diff --git a/.gitignore b/.gitignore index 2dbad75022..dbf8f0f70e 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,4 @@ example/flash/flash.mk example/flash/main.c example/flash/README.md settings.json +build/cmd/win32/Python27/Lib/encodings/*.pyc \ No newline at end of file diff --git a/app/usyscall/syscall_fapi.h b/app/usyscall/syscall_fapi.h index 1304d10e89..2eac36ca3c 100644 --- a/app/usyscall/syscall_fapi.h +++ b/app/usyscall/syscall_fapi.h @@ -7,6 +7,7 @@ #ifdef WITH_LWIP #include #endif +#include "aos/uData.h" #include diff --git a/board/.DS_Store b/board/.DS_Store new file mode 100644 index 0000000000..395ce82309 Binary files /dev/null and b/board/.DS_Store differ diff --git a/board/b_l475e/atcmd_config_platform.h b/board/b_l475e/atcmd_config_platform.h index 7aa9da6253..8346ecfc00 100644 --- a/board/b_l475e/atcmd_config_platform.h +++ b/board/b_l475e/atcmd_config_platform.h @@ -2,41 +2,10 @@ * Copyright (C) 2015-2017 Alibaba Group Holding Limited */ -#ifndef _ATCMD_DEFINES_MK3060_H_ -#define _ATCMD_DEFINES_MK3060_H_ - -#include - -/** - * AT related platform-dependent things are here, including: - * 1. AT command; - * 2. AT response code; - * 3. AT delimiter; - * 4. AT event; - * 5. Uart port used by AT; - * 6. ... - */ - -// AT command -#define AT_CMD_ENET_SEND "AT+ENETRAWSEND" -#define AT_CMD_ENTER_ENET_MODE "AT+ENETRAWMODE=ON" -#define AT_CMD_EHCO_OFF "AT+UARTE=OFF" -#define AT_CMD_TEST "AT" - -// Delimiter -#define AT_RECV_DELIMITER "\r\n" -#define AT_SEND_DELIMITER "\r" - -// AT event -#define AT_EVENT_ENET_DATA "+ENETEVENT:" +#ifndef _ATCMD_CONFIG_PLATFORM_H_ +#define _ATCMD_CONFIG_PLATFORM_H_ // AT uart #define AT_UART_PORT 1 -#define AT_UART_BAUDRATE 921600 -#define AT_UART_DATA_WIDTH DATA_WIDTH_8BIT -#define AT_UART_PARITY NO_PARITY -#define AT_UART_STOP_BITS STOP_BITS_1 -#define AT_UART_FLOW_CONTROL FLOW_CONTROL_DISABLED -#define AT_UART_LINUX_DEV "/dev/ttyUSB1" // required by linuxhost #endif diff --git a/board/b_l475e/b_l475e.mk b/board/b_l475e/b_l475e.mk index 6a7a279a66..ca11a28891 100644 --- a/board/b_l475e/b_l475e.mk +++ b/board/b_l475e/b_l475e.mk @@ -11,13 +11,18 @@ SUPPORT_BINS := no $(NAME)_SOURCES := board.c osa_flash.c GLOBAL_INCLUDES += . -GLOBAL_DEFINES += STDIO_UART=0 CONFIG_NO_TCPIP -GLOBAL_DEFINES += RHINO_CONFIG_TICK_TASK=0 RHINO_CONFIG_WORKQUEUE=0 - -ifeq ($(sal),1) -GLOBAL_DEFINES += RHINO_CONFIG_WORKQUEUE=1 +GLOBAL_DEFINES += STDIO_UART=0 +GLOBAL_DEFINES += RHINO_CONFIG_TICK_TASK=0 + +sal ?= 1 +ifeq (1,$(sal)) +$(NAME)_COMPONENTS += sal +$(NAME)_COMPONENTS += sal.wifi.mk3060 +else +GLOBAL_DEFINES += CONFIG_NO_TCPIP endif + CONFIG_SYSINFO_PRODUCT_MODEL := ALI_AOS_B-L475E CONFIG_SYSINFO_DEVICE_NAME := B-L475E @@ -25,7 +30,11 @@ GLOBAL_CFLAGS += -DSYSINFO_OS_VERSION=\"$(CONFIG_SYSINFO_OS_VERSION)\" GLOBAL_CFLAGS += -DSYSINFO_PRODUCT_MODEL=\"$(CONFIG_SYSINFO_PRODUCT_MODEL)\" GLOBAL_CFLAGS += -DSYSINFO_DEVICE_NAME=\"$(CONFIG_SYSINFO_DEVICE_NAME)\" +ifeq ($(COMPILER),armcc) +else ifeq ($(COMPILER),iar) +else GLOBAL_LDFLAGS += -L $(SOURCE_ROOT)/board/b_l475e +endif # Global defines # HSE_VALUE = STM32 crystal frequency = 26MHz (needed to make UART work correctly) @@ -43,4 +52,6 @@ EXTRA_TARGET_MAKEFILES += $(MAKEFILES_PATH)/aos_standard_targets.mk ifeq (, $(findstring yts, $(BUILD_STRING))) GLOBAL_DEFINES += RHINO_CONFIG_WORKQUEUE=1 TEST_COMPONENTS += basic api wifi_hal rhino vcall kv yloop alicrypto cjson digest_algorithm hashtable +else +GLOBAL_DEFINES += RHINO_CONFIG_WORKQUEUE=0 endif diff --git a/board/esp32devkitc/esp32devkitc.mk b/board/esp32devkitc/esp32devkitc.mk index 31d89d3576..bb8e5d8597 100644 --- a/board/esp32devkitc/esp32devkitc.mk +++ b/board/esp32devkitc/esp32devkitc.mk @@ -8,7 +8,6 @@ SUPPORT_BINS := no # todo: remove these after rhino/lwip ready vcall ?= rhino -CURRENT_TIME = $(shell /bin/date +%Y%m%d.%H%M) define get-os-version "AOS-R"-$(CURRENT_TIME) endef diff --git a/board/hobbit1_evb/hobbit1_evb.mk b/board/hobbit1_evb/hobbit1_evb.mk index 14a30f82c3..6b33016d13 100644 --- a/board/hobbit1_evb/hobbit1_evb.mk +++ b/board/hobbit1_evb/hobbit1_evb.mk @@ -12,7 +12,6 @@ $(NAME)_SOURCES := board_init.c GLOBAL_INCLUDES += . GLOBAL_DEFINES += STDIO_UART=1 -CURRENT_TIME = $(shell /bin/date +%Y%m%d.%H%M) define get-os-version "AOS-R"-$(CURRENT_TIME) endef diff --git a/board/linuxhost/atcmd_config_platform.h b/board/linuxhost/atcmd_config_platform.h index 7aa9da6253..9a9c331bb2 100644 --- a/board/linuxhost/atcmd_config_platform.h +++ b/board/linuxhost/atcmd_config_platform.h @@ -2,41 +2,10 @@ * Copyright (C) 2015-2017 Alibaba Group Holding Limited */ -#ifndef _ATCMD_DEFINES_MK3060_H_ -#define _ATCMD_DEFINES_MK3060_H_ +#ifndef _ATCMD_PLATFORM_CONFIG_H_ +#define _ATCMD_PLATFORM_CONFIG_H_ -#include - -/** - * AT related platform-dependent things are here, including: - * 1. AT command; - * 2. AT response code; - * 3. AT delimiter; - * 4. AT event; - * 5. Uart port used by AT; - * 6. ... - */ - -// AT command -#define AT_CMD_ENET_SEND "AT+ENETRAWSEND" -#define AT_CMD_ENTER_ENET_MODE "AT+ENETRAWMODE=ON" -#define AT_CMD_EHCO_OFF "AT+UARTE=OFF" -#define AT_CMD_TEST "AT" - -// Delimiter -#define AT_RECV_DELIMITER "\r\n" -#define AT_SEND_DELIMITER "\r" - -// AT event -#define AT_EVENT_ENET_DATA "+ENETEVENT:" - -// AT uart #define AT_UART_PORT 1 -#define AT_UART_BAUDRATE 921600 -#define AT_UART_DATA_WIDTH DATA_WIDTH_8BIT -#define AT_UART_PARITY NO_PARITY -#define AT_UART_STOP_BITS STOP_BITS_1 -#define AT_UART_FLOW_CONTROL FLOW_CONTROL_DISABLED #define AT_UART_LINUX_DEV "/dev/ttyUSB1" // required by linuxhost #endif diff --git a/board/lpcxpresso54102/board.c b/board/lpcxpresso54102/board.c new file mode 100644 index 0000000000..6ec79ab5d5 --- /dev/null +++ b/board/lpcxpresso54102/board.c @@ -0,0 +1,55 @@ +/* + * Copyright 2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "fsl_common.h" +#include "clock_config.h" +#include "board.h" +#include "fsl_debug_console.h" + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Clock rate on the CLKIN pin */ +const uint32_t ExtClockIn = BOARD_EXTCLKINRATE; + +/******************************************************************************* + * Code + ******************************************************************************/ +/* Initialize debug console. */ +status_t BOARD_InitDebugConsole(void) +{ + status_t result; + RESET_PeripheralReset(BOARD_DEBUG_UART_RST); + result = DbgConsole_Init(BOARD_DEBUG_UART_BASEADDR, BOARD_DEBUG_UART_BAUDRATE, DEBUG_CONSOLE_DEVICE_TYPE_VUSART, + BOARD_DEBUG_UART_CLK_FREQ); + assert(kStatus_Success == result); + return result; +} diff --git a/board/lpcxpresso54102/board.h b/board/lpcxpresso54102/board.h new file mode 100644 index 0000000000..5d84dfb948 --- /dev/null +++ b/board/lpcxpresso54102/board.h @@ -0,0 +1,139 @@ +/* + * Copyright 2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _BOARD_H_ +#define _BOARD_H_ + +#include "clock_config.h" +#include "fsl_common.h" +#include "fsl_gpio.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/*! @brief The board name */ +#define BOARD_NAME "LPCXPRESSO54102" + +#define BOARD_EXTCLKINRATE (0) + +/*! @brief The UART to use for debug messages. */ +#define BOARD_DEBUG_UART_TYPE DEBUG_CONSOLE_DEVICE_TYPE_FLEXCOMM +#define BOARD_DEBUG_UART_BASEADDR (uint32_t) USART0 +#define BOARD_DEBUG_UART_CLK_FREQ CLOCK_GetFreq(kCLOCK_Usart) +#define BOARD_DEBUG_UART_CLK_ATTACH kIRC12M_to_USART +#define BOARD_DEBUG_UART_RST kUSART0_RST_SHIFT_RSTn + +#define BOARD_DEBUG_SPI_CLK_FREQ 12000000 + +#ifndef BOARD_DEBUG_UART_BAUDRATE +#define BOARD_DEBUG_UART_BAUDRATE 115200 +#endif /* BOARD_DEBUG_UART_BAUDRATE */ + +#define BOARD_LED_RED_GPIO GPIO +#define BOARD_LED_RED_GPIO_PORT 0U +#define BOARD_LED_RED_GPIO_PIN 29U +#define BOARD_LED_GREEN_GPIO GPIO +#define BOARD_LED_GREEN_GPIO_PORT 0U +#define BOARD_LED_GREEN_GPIO_PIN 30U +#define BOARD_LED_BLUE_GPIO GPIO +#define BOARD_LED_BLUE_GPIO_PORT 0U +#define BOARD_LED_BLUE_GPIO_PIN 31U + +#define BOARD_SW1_GPIO GPIO +#define BOARD_SW1_GPIO_PORT 0U +#define BOARD_SW1_GPIO_PIN 24U +#define BOARD_SW1_NAME "SW1" +#define BOARD_SW1_IRQ PIN_INT0_IRQn +#define BOARD_SW1_IRQ_HANDLER PIN_INT0_IRQHandler + +#define BOARD_SW2_GPIO GPIO +#define BOARD_SW2_GPIO_PORT 0U +#define BOARD_SW2_GPIO_PIN 31U +#define BOARD_SW2_NAME "SW2" +#define BOARD_SW2_IRQ PIN_INT0_IRQn +#define BOARD_SW2_IRQ_HANDLER PIN_INT0_IRQHandler + +/* Board led color mapping */ +#define LOGIC_LED_ON 0U +#define LOGIC_LED_OFF 1U + +#define LED_RED_INIT(output) \ + GPIO_PinInit(BOARD_LED_RED_GPIO, BOARD_LED_RED_GPIO_PORT, BOARD_LED_RED_GPIO_PIN, \ + &(gpio_pin_config_t){kGPIO_DigitalOutput, (output)}) /*!< Enable target LED_RED */ +#define LED_RED_ON() \ + GPIO_ClearPinsOutput(BOARD_LED_RED_GPIO, BOARD_LED_RED_GPIO_PORT, \ + 1U << BOARD_LED_RED_GPIO_PIN) /*!< Turn on target LED_RED */ +#define LED_RED_OFF() \ + GPIO_SetPinsOutput(BOARD_LED_RED_GPIO, BOARD_LED_RED_GPIO_PORT, \ + 1U << BOARD_LED_RED_GPIO_PIN) /*!< Turn off target LED_RED */ +#define LED_RED_TOGGLE() \ + GPIO_TogglePinsOutput(BOARD_LED_RED_GPIO, BOARD_LED_RED_GPIO_PORT, \ + 1U << BOARD_LED_RED_GPIO_PIN) /*!< Toggle on target LED_RED */ + +#define LED_GREEN_INIT(output) \ + GPIO_PinInit(BOARD_LED_GREEN_GPIO, BOARD_LED_GREEN_GPIO_PORT, BOARD_LED_GREEN_GPIO_PIN, \ + &(gpio_pin_config_t){kGPIO_DigitalOutput, (output)}) /*!< Enable target LED_GREEN */ +#define LED_GREEN_ON() \ + GPIO_ClearPinsOutput(BOARD_LED_GREEN_GPIO, BOARD_LED_GREEN_GPIO_PORT, \ + 1U << BOARD_LED_GREEN_GPIO_PIN) /*!< Turn on target LED_GREEN */ +#define LED_GREEN_OFF() \ + GPIO_SetPinsOutput(BOARD_LED_GREEN_GPIO, BOARD_LED_GREEN_GPIO_PORT, \ + 1U << BOARD_LED_GREEN_GPIO_PIN) /*!< Turn off target LED_GREEN */ +#define LED_GREEN_TOGGLE() \ + GPIO_TogglePinsOutput(BOARD_LED_GREEN_GPIO, BOARD_LED_GREEN_GPIO_PORT, \ + 1U << BOARD_LED_GREEN_GPIO_PIN) /*!< Toggle on target LED_GREEN */ + +#define LED_BLUE_INIT(output) \ + GPIO_PinInit(BOARD_LED_BLUE_GPIO, BOARD_LED_BLUE_GPIO_PORT, BOARD_LED_BLUE_GPIO_PIN, \ + &(gpio_pin_config_t){kGPIO_DigitalOutput, (output)}) /*!< Enable target LED_BLUE */ +#define LED_BLUE_ON() \ + GPIO_ClearPinsOutput(BOARD_LED_BLUE_GPIO, BOARD_LED_BLUE_GPIO_PORT, \ + 1U << BOARD_LED_BLUE_GPIO_PIN) /*!< Turn on target LED_BLUE */ +#define LED_BLUE_OFF() \ + GPIO_SetPinsOutput(BOARD_LED_BLUE_GPIO, BOARD_LED_BLUE_GPIO_PORT, \ + 1U << BOARD_LED_BLUE_GPIO_PIN) /*!< Turn off target LED_BLUE */ +#define LED_BLUE_TOGGLE() \ + GPIO_TogglePinsOutput(BOARD_LED_BLUE_GPIO, BOARD_LED_BLUE_GPIO_PORT, \ + 1U << BOARD_LED_BLUE_GPIO_PIN) /*!< Toggle on target LED_BLUE */ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + +/******************************************************************************* + * API + ******************************************************************************/ + +status_t BOARD_InitDebugConsole(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + +#endif /* _BOARD_H_ */ diff --git a/board/lpcxpresso54102/clock_config.c b/board/lpcxpresso54102/clock_config.c new file mode 100644 index 0000000000..69950abb64 --- /dev/null +++ b/board/lpcxpresso54102/clock_config.c @@ -0,0 +1,309 @@ +/* + * Copyright 2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * How to set up clock using clock driver functions: + * + * 1. Setup clock sources. + * + * 2. Setup voltage for the fastest of the clock outputs + * + * 3. Set up wait states of the flash. + * + * 4. Set up all dividers. + * + * 5. Set up all selectors to provide selected clocks. + */ + +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Clocks v3.0 +processor: LPC54102J512 +package_id: LPC54102J512BD64 +mcu_data: ksdk2_0 +processor_version: 0.0.0 +board: LPCXpresso54102 + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ + +#include "fsl_power.h" +#include "fsl_clock.h" +#include "clock_config.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ +/* System clock frequency. */ +extern uint32_t SystemCoreClock; + +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ +void BOARD_InitBootClocks(void) +{ + BOARD_BootClockPLL96M(); +} + +/******************************************************************************* + ******************** Configuration BOARD_BootClockIRC12M ********************** + ******************************************************************************/ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockIRC12M +outputs: +- {id: ASYNCAPB_clock.outFreq, value: 12 MHz} +- {id: System_clock.outFreq, value: 12 MHz} +- {id: TRACE_clock.outFreq, value: 12 MHz} +sources: +- {id: SYSCON.clk_in.outFreq, value: 4 MHz} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ + +/******************************************************************************* + * Variables for BOARD_BootClockIRC12M configuration + ******************************************************************************/ +/******************************************************************************* + * Code for BOARD_BootClockIRC12M configuration + ******************************************************************************/ +void BOARD_BootClockIRC12M(void) +{ + /*!< Set up the clock sources */ + /*!< Set up IRC */ + POWER_DisablePD(kPDRUNCFG_PD_IRC_OSC); /*!< Ensure IRC OSC is on */ + POWER_DisablePD(kPDRUNCFG_PD_IRC); /*!< Ensure IRC is on */ + CLOCK_AttachClk(kIRC12M_to_MAIN_CLK); /*!< Switch to IRC 12MHz first to ensure we can change voltage without accidentally + being below the voltage for current speed */ + POWER_SetVoltageForFreq(12000000U); /*!< Set voltage for the one of the fastest clock outputs: System clock output */ + CLOCK_SetFLASHAccessCyclesForFreq(12000000U); /*!< Set FLASH wait states for core */ + + /*!< PLL is in power_down mode */ + + /*!< Set up dividers */ + CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U, false); /*!< Set AHBCLKDIV divider to value 1 */ + + /*!< Set up clock selectors - Attach clocks to the peripheries */ + CLOCK_AttachClk(kIRC12M_to_MAIN_CLK); /*!< Switch MAIN_CLK to IRC12M */ + + /*< Set SystemCoreClock variable. */ + SystemCoreClock = BOARD_BOOTCLOCKIRC12M_CORE_CLOCK; +} + +/******************************************************************************* + ******************** Configuration BOARD_BootClockPLL48M ********************** + ******************************************************************************/ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockPLL48M +outputs: +- {id: ASYNCAPB_clock.outFreq, value: 48 MHz} +- {id: System_clock.outFreq, value: 48 MHz} +- {id: TRACE_clock.outFreq, value: 48 MHz} +settings: +- {id: PLL_Mode, value: Fractional} +- {id: SYSCON.MAINCLKSELB.sel, value: SYSCON.PLL_BYPASS} +- {id: SYSCON.M_MULT.scale, value: '49152', locked: true} +- {id: SYSCON.N_DIV.scale, value: '3', locked: true} +- {id: SYSCON.PDEC.scale, value: '2', locked: true} +- {id: SYSCON.PLL_BYPASS.sel, value: SYSCON.DIRECTO} +- {id: 'SYSCON::SYSPLLSSCTRL0[MDEC].bitField', value: '3'} +- {id: SYSCON_SYSPLLCTRL_BYPASSCCODIV2_CFG, value: Enabled} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ + +/******************************************************************************* + * Variables for BOARD_BootClockPLL48M configuration + ******************************************************************************/ +/******************************************************************************* + * Code for BOARD_BootClockPLL48M configuration + ******************************************************************************/ +void BOARD_BootClockPLL48M(void) +{ + /*!< Set up the clock sources */ + /*!< Set up IRC */ + POWER_DisablePD(kPDRUNCFG_PD_IRC_OSC); /*!< Ensure IRC OSC is on */ + POWER_DisablePD(kPDRUNCFG_PD_IRC); /*!< Ensure IRC is on */ + CLOCK_AttachClk(kIRC12M_to_MAIN_CLK); /*!< Switch to IRC 12MHz first to ensure we can change voltage without accidentally + being below the voltage for current speed */ + POWER_SetVoltageForFreq(48000000U); /*!< Set voltage for the one of the fastest clock outputs: System clock output */ + CLOCK_SetFLASHAccessCyclesForFreq(48000000U); /*!< Set FLASH wait states for core */ + + /*!< Set up PLL */ + POWER_DisablePD(kPDRUNCFG_PD_SYS_PLL); /*!< Ensure PLL is on */ + const pll_setup_t pllSetup = { + .syspllctrl = SYSCON_SYSPLLCTRL_UPLIMOFF_MASK | SYSCON_SYSPLLCTRL_BYPASSCCODIV2_MASK, + .syspllndec = SYSCON_SYSPLLNDEC_NDEC(1U), + .syspllpdec = SYSCON_SYSPLLPDEC_PDEC(98U), + .syspllssctrl = {0x0U,(SYSCON_SYSPLLSSCTRL1_MD(49152U) | (uint32_t)(kSS_MF_512) | (uint32_t)(kSS_MR_K0) | (uint32_t)(kSS_MC_NOC))}, + .pllRate = 48000000U, + .flags = PLL_SETUPFLAG_POWERUP + }; + CLOCK_SetPLLFreq(&pllSetup); /*!< Configure PLL to the desired values */ + + /* PLL in Fractional/Spread spectrum mode */ + /* SYSTICK is used for waiting for PLL stabilization */ + + /*!< Set up dividers */ + CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U, false); /*!< Set AHBCLKDIV divider to value 1 */ + + /*!< Set up clock selectors - Attach clocks to the peripheries */ + CLOCK_AttachClk(kSYS_PLL_OUT_to_MAIN_CLK); /*!< Switch MAIN_CLK to SYS_PLL_OUT */ + + /*< Set SystemCoreClock variable. */ + SystemCoreClock = BOARD_BOOTCLOCKPLL48M_CORE_CLOCK; +} + +/******************************************************************************* + ******************** Configuration BOARD_BootClockPLL96M ********************** + ******************************************************************************/ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockPLL96M +called_from_default_init: true +outputs: +- {id: ASYNCAPB_clock.outFreq, value: 96 MHz} +- {id: System_clock.outFreq, value: 96 MHz} +- {id: TRACE_clock.outFreq, value: 96 MHz} +settings: +- {id: PLL_Mode, value: Fractional} +- {id: SYSCON.DIRECTO.sel, value: SYSCON.PLL} +- {id: SYSCON.MAINCLKSELB.sel, value: SYSCON.PLL_BYPASS} +- {id: SYSCON.M_MULT.scale, value: '49152', locked: true} +- {id: SYSCON.N_DIV.scale, value: '3', locked: true} +- {id: SYSCON.PDEC.scale, value: '2', locked: true} +- {id: SYSCON.PLL_BYPASS.sel, value: SYSCON.DIRECTO} +- {id: 'SYSCON::SYSPLLSSCTRL0[MDEC].bitField', value: '3'} +- {id: SYSCON_SYSPLLCTRL_BYPASSCCODIV2_CFG, value: Enabled} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ + +/******************************************************************************* + * Variables for BOARD_BootClockPLL96M configuration + ******************************************************************************/ +/******************************************************************************* + * Code for BOARD_BootClockPLL96M configuration + ******************************************************************************/ +void BOARD_BootClockPLL96M(void) +{ + /*!< Set up the clock sources */ + /*!< Set up IRC */ + POWER_DisablePD(kPDRUNCFG_PD_IRC_OSC); /*!< Ensure IRC OSC is on */ + POWER_DisablePD(kPDRUNCFG_PD_IRC); /*!< Ensure IRC is on */ + CLOCK_AttachClk(kIRC12M_to_MAIN_CLK); /*!< Switch to IRC 12MHz first to ensure we can change voltage without accidentally + being below the voltage for current speed */ + POWER_SetVoltageForFreq(96000000U); /*!< Set voltage for the one of the fastest clock outputs: System clock output */ + CLOCK_SetFLASHAccessCyclesForFreq(96000000U); /*!< Set FLASH wait states for core */ + + /*!< Set up PLL */ + POWER_DisablePD(kPDRUNCFG_PD_SYS_PLL); /*!< Ensure PLL is on */ + const pll_setup_t pllSetup = { + .syspllctrl = SYSCON_SYSPLLCTRL_UPLIMOFF_MASK | SYSCON_SYSPLLCTRL_BYPASSCCODIV2_MASK | SYSCON_SYSPLLCTRL_DIRECTO_MASK, + .syspllndec = SYSCON_SYSPLLNDEC_NDEC(1U), + .syspllpdec = SYSCON_SYSPLLPDEC_PDEC(98U), + .syspllssctrl = {0x0U,(SYSCON_SYSPLLSSCTRL1_MD(49152U) | (uint32_t)(kSS_MF_512) | (uint32_t)(kSS_MR_K0) | (uint32_t)(kSS_MC_NOC))}, + .pllRate = 96000000U, + .flags = PLL_SETUPFLAG_POWERUP + }; + CLOCK_SetPLLFreq(&pllSetup); /*!< Configure PLL to the desired values */ + + /* PLL in Fractional/Spread spectrum mode */ + /* SYSTICK is used for waiting for PLL stabilization */ + + /*!< Set up dividers */ + CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U, false); /*!< Set AHBCLKDIV divider to value 1 */ + + /*!< Set up clock selectors - Attach clocks to the peripheries */ + CLOCK_AttachClk(kSYS_PLL_OUT_to_MAIN_CLK); /*!< Switch MAIN_CLK to SYS_PLL_OUT */ + + /*< Set SystemCoreClock variable. */ + SystemCoreClock = BOARD_BOOTCLOCKPLL96M_CORE_CLOCK; +} + +/******************************************************************************* + ******************** Configuration BOARD_BootClockPLL100M ********************* + ******************************************************************************/ +/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!Configuration +name: BOARD_BootClockPLL100M +outputs: +- {id: ASYNCAPB_clock.outFreq, value: 100 MHz} +- {id: System_clock.outFreq, value: 100 MHz} +- {id: TRACE_clock.outFreq, value: 100 MHz} +settings: +- {id: PLL_Mode, value: Fractional} +- {id: SYSCON.DIRECTO.sel, value: SYSCON.PLL} +- {id: SYSCON.MAINCLKSELB.sel, value: SYSCON.PLL_BYPASS} +- {id: SYSCON.M_MULT.scale, value: '102400', locked: true} +- {id: SYSCON.N_DIV.scale, value: '6', locked: true} +- {id: SYSCON.PDEC.scale, value: '2', locked: true} +- {id: SYSCON.PLL_BYPASS.sel, value: SYSCON.DIRECTO} +- {id: 'SYSCON::SYSPLLSSCTRL0[MDEC].bitField', value: '32597'} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ + +/******************************************************************************* + * Variables for BOARD_BootClockPLL100M configuration + ******************************************************************************/ +/******************************************************************************* + * Code for BOARD_BootClockPLL100M configuration + ******************************************************************************/ +void BOARD_BootClockPLL100M(void) +{ + /*!< Set up the clock sources */ + /*!< Set up IRC */ + POWER_DisablePD(kPDRUNCFG_PD_IRC_OSC); /*!< Ensure IRC OSC is on */ + POWER_DisablePD(kPDRUNCFG_PD_IRC); /*!< Ensure IRC is on */ + CLOCK_AttachClk(kIRC12M_to_MAIN_CLK); /*!< Switch to IRC 12MHz first to ensure we can change voltage without accidentally + being below the voltage for current speed */ + POWER_SetVoltageForFreq(100000000U); /*!< Set voltage for the one of the fastest clock outputs: System clock output */ + CLOCK_SetFLASHAccessCyclesForFreq(100000000U); /*!< Set FLASH wait states for core */ + + /*!< Set up PLL */ + POWER_DisablePD(kPDRUNCFG_PD_SYS_PLL); /*!< Ensure PLL is on */ + const pll_setup_t pllSetup = { + .syspllctrl = SYSCON_SYSPLLCTRL_UPLIMOFF_MASK | SYSCON_SYSPLLCTRL_DIRECTO_MASK, + .syspllndec = SYSCON_SYSPLLNDEC_NDEC(11U), + .syspllpdec = SYSCON_SYSPLLPDEC_PDEC(98U), + .syspllssctrl = {0x0U,(SYSCON_SYSPLLSSCTRL1_MD(51200U) | (uint32_t)(kSS_MF_512) | (uint32_t)(kSS_MR_K0) | (uint32_t)(kSS_MC_NOC))}, + .pllRate = 100000000U, + .flags = PLL_SETUPFLAG_POWERUP + }; + CLOCK_SetPLLFreq(&pllSetup); /*!< Configure PLL to the desired values */ + + /* PLL in Fractional/Spread spectrum mode */ + /* SYSTICK is used for waiting for PLL stabilization */ + + /*!< Set up dividers */ + CLOCK_SetClkDiv(kCLOCK_DivAhbClk, 1U, false); /*!< Set AHBCLKDIV divider to value 1 */ + + /*!< Set up clock selectors - Attach clocks to the peripheries */ + CLOCK_AttachClk(kSYS_PLL_OUT_to_MAIN_CLK); /*!< Switch MAIN_CLK to SYS_PLL_OUT */ + + /*< Set SystemCoreClock variable. */ + SystemCoreClock = BOARD_BOOTCLOCKPLL100M_CORE_CLOCK; +} + diff --git a/board/lpcxpresso54102/clock_config.h b/board/lpcxpresso54102/clock_config.h new file mode 100644 index 0000000000..7326d68bad --- /dev/null +++ b/board/lpcxpresso54102/clock_config.h @@ -0,0 +1,164 @@ +/* + * Copyright 2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _CLOCK_CONFIG_H_ +#define _CLOCK_CONFIG_H_ + +#include "fsl_common.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define BOARD_XTAL0_CLK_HZ 12000000U /*!< Board xtal0 frequency in Hz */ +#define BOARD_XTAL32K_CLK_HZ 32768U /*!< Board xtal32K frequency in Hz */ + +/******************************************************************************* + ************************ BOARD_InitBootClocks function ************************ + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes default configuration of clocks. + * + */ +void BOARD_InitBootClocks(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ******************** Configuration BOARD_BootClockIRC12M ********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockIRC12M configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKIRC12M_CORE_CLOCK 12000000U /*!< Core clock frequency: 12000000Hz */ + + +/******************************************************************************* + * API for BOARD_BootClockIRC12M configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockIRC12M(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ******************** Configuration BOARD_BootClockPLL48M ********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockPLL48M configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKPLL48M_CORE_CLOCK 48000000U /*!< Core clock frequency: 48000000Hz */ + + +/******************************************************************************* + * API for BOARD_BootClockPLL48M configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockPLL48M(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ******************** Configuration BOARD_BootClockPLL96M ********************** + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockPLL96M configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKPLL96M_CORE_CLOCK 96000000U /*!< Core clock frequency: 96000000Hz */ + + +/******************************************************************************* + * API for BOARD_BootClockPLL96M configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockPLL96M(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/******************************************************************************* + ******************** Configuration BOARD_BootClockPLL100M ********************* + ******************************************************************************/ +/******************************************************************************* + * Definitions for BOARD_BootClockPLL100M configuration + ******************************************************************************/ +#define BOARD_BOOTCLOCKPLL100M_CORE_CLOCK 100000000U /*!< Core clock frequency: 100000000Hz */ + + +/******************************************************************************* + * API for BOARD_BootClockPLL100M configuration + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief This function executes configuration of clocks. + * + */ +void BOARD_BootClockPLL100M(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +#endif /* _CLOCK_CONFIG_H_ */ + diff --git a/board/lpcxpresso54102/k_config.h b/board/lpcxpresso54102/k_config.h new file mode 100644 index 0000000000..b959991f71 --- /dev/null +++ b/board/lpcxpresso54102/k_config.h @@ -0,0 +1,208 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#ifndef K_CONFIG_H +#define K_CONFIG_H + +/* chip level conf */ +#ifndef RHINO_CONFIG_LITTLE_ENDIAN +#define RHINO_CONFIG_LITTLE_ENDIAN 1 +#endif +#ifndef RHINO_CONFIG_CPU_STACK_DOWN +#define RHINO_CONFIG_CPU_STACK_DOWN 1 +#endif + +/* kernel feature conf */ +#ifndef RHINO_CONFIG_SEM +#define RHINO_CONFIG_SEM 1 +#endif +#ifndef RHINO_CONFIG_QUEUE +#define RHINO_CONFIG_QUEUE 1 +#endif +#ifndef RHINO_CONFIG_TASK_SEM +#define RHINO_CONFIG_TASK_SEM 1 +#endif +#ifndef RHINO_CONFIG_EVENT_FLAG +#define RHINO_CONFIG_EVENT_FLAG 1 +#endif +#ifndef RHINO_CONFIG_TIMER +#define RHINO_CONFIG_TIMER 1 +#endif +#ifndef RHINO_CONFIG_BUF_QUEUE +#define RHINO_CONFIG_BUF_QUEUE 1 +#endif +#ifndef RHINO_CONFIG_MM_BLK +#define RHINO_CONFIG_MM_BLK 1 +#endif +#ifndef RHINO_CONFIG_MM_DEBUG +#define RHINO_CONFIG_MM_DEBUG 1 +#endif +#ifndef RHINO_CONFIG_MM_TLF +#define RHINO_CONFIG_MM_TLF 1 +#endif +#ifndef RHINO_CONFIG_MM_MAXMSIZEBIT +#define RHINO_CONFIG_MM_MAXMSIZEBIT 24 +#endif +#ifndef RHINO_CONFIG_GCC_RETADDR +#define RHINO_CONFIG_GCC_RETADDR 1 +#endif +#ifndef RHINO_CONFIG_MM_LEAKCHECK +#define RHINO_CONFIG_MM_LEAKCHECK 0 +#endif +#define K_MM_STATISTIC 1 +#ifndef RHINO_CONFIG_KOBJ_SET +#define RHINO_CONFIG_KOBJ_SET 1 +#endif +#ifndef RHINO_CONFIG_RINGBUF_VENDOR +#define RHINO_CONFIG_RINGBUF_VENDOR 1 +#endif + +/* kernel task conf */ +#ifndef RHINO_CONFIG_TASK_SUSPEND +#define RHINO_CONFIG_TASK_SUSPEND 1 +#endif +#ifndef RHINO_CONFIG_TASK_INFO +#define RHINO_CONFIG_TASK_INFO 10 +#endif +#ifndef RHINO_CONFIG_TASK_DEL +#define RHINO_CONFIG_TASK_DEL 1 +#endif +#ifndef RHINO_CONFIG_TASK_WAIT_ABORT +#define RHINO_CONFIG_TASK_WAIT_ABORT 1 +#endif +#ifndef RHINO_CONFIG_TASK_STACK_OVF_CHECK +#define RHINO_CONFIG_TASK_STACK_OVF_CHECK 1 +#endif +#ifndef RHINO_CONFIG_SCHED_RR +#define RHINO_CONFIG_SCHED_RR 1 +#endif +#ifndef RHINO_CONFIG_TIME_SLICE_DEFAULT +#define RHINO_CONFIG_TIME_SLICE_DEFAULT 10 +#endif +#ifndef RHINO_CONFIG_PRI_MAX +#define RHINO_CONFIG_PRI_MAX 62 +#endif +#ifndef RHINO_CONFIG_USER_PRI_MAX +#define RHINO_CONFIG_USER_PRI_MAX (RHINO_CONFIG_PRI_MAX - 2) +#endif + +/* kernel workqueue conf */ +#ifndef RHINO_CONFIG_WORKQUEUE +#define RHINO_CONFIG_WORKQUEUE 1 +#endif + +/* kernel mm_region conf */ +#ifndef RHINO_CONFIG_MM_REGION_MUTEX +#define RHINO_CONFIG_MM_REGION_MUTEX 0 +#endif + +/* kernel timer&tick conf */ +#ifndef RHINO_CONFIG_HW_COUNT +#define RHINO_CONFIG_HW_COUNT 0 +#endif +#ifndef RHINO_CONFIG_TICK_TASK +#define RHINO_CONFIG_TICK_TASK 0 +#endif +#if (RHINO_CONFIG_TICK_TASK > 0) +#ifndef RHINO_CONFIG_TICK_TASK_STACK_SIZE +#define RHINO_CONFIG_TICK_TASK_STACK_SIZE 256 +#endif +#ifndef RHINO_CONFIG_TICK_TASK_PRI +#define RHINO_CONFIG_TICK_TASK_PRI 1 +#endif +#endif +#ifndef RHINO_CONFIG_TICKLESS +#define RHINO_CONFIG_TICKLESS 0 +#endif +#ifndef RHINO_CONFIG_TICKS_PER_SECOND +#define RHINO_CONFIG_TICKS_PER_SECOND 100 +#endif +/* must be 2^n size!, such as 1, 2, 4, 8, 16,32, etc....... */ +#ifndef RHINO_CONFIG_TICK_HEAD_ARRAY +#define RHINO_CONFIG_TICK_HEAD_ARRAY 8 +#endif +#ifndef RHINO_CONFIG_TIMER_TASK_STACK_SIZE +#define RHINO_CONFIG_TIMER_TASK_STACK_SIZE 200 +#endif +#ifndef RHINO_CONFIG_TIMER_RATE +#define RHINO_CONFIG_TIMER_RATE 1 +#endif +#ifndef RHINO_CONFIG_TIMER_TASK_PRI +#define RHINO_CONFIG_TIMER_TASK_PRI 5 +#endif + +/* kernel intrpt conf */ +#ifndef RHINO_CONFIG_INTRPT_STACK_REMAIN_GET +#define RHINO_CONFIG_INTRPT_STACK_REMAIN_GET 0 +#endif +#ifndef RHINO_CONFIG_INTRPT_STACK_OVF_CHECK +#define RHINO_CONFIG_INTRPT_STACK_OVF_CHECK 0 +#endif +#ifndef RHINO_CONFIG_INTRPT_MAX_NESTED_LEVEL +#define RHINO_CONFIG_INTRPT_MAX_NESTED_LEVEL 8u +#endif +#ifndef RHINO_CONFIG_INTRPT_GUARD +#define RHINO_CONFIG_INTRPT_GUARD 0 +#endif + +/* kernel dyn alloc conf */ +#ifndef RHINO_CONFIG_KOBJ_DYN_ALLOC +#define RHINO_CONFIG_KOBJ_DYN_ALLOC 1 +#endif +#if (RHINO_CONFIG_KOBJ_DYN_ALLOC > 0) +#ifndef RHINO_CONFIG_K_DYN_QUEUE_MSG +#define RHINO_CONFIG_K_DYN_QUEUE_MSG 30 +#endif +#ifndef RHINO_CONFIG_K_DYN_TASK_STACK +#define RHINO_CONFIG_K_DYN_TASK_STACK 256 +#endif +#ifndef RHINO_CONFIG_K_DYN_MEM_TASK_PRI +#define RHINO_CONFIG_K_DYN_MEM_TASK_PRI 5 +#endif +#endif + +/* kernel idle conf */ +#ifndef RHINO_CONFIG_IDLE_TASK_STACK_SIZE +#define RHINO_CONFIG_IDLE_TASK_STACK_SIZE 200 +#endif + +/* kernel hook conf */ +#ifndef RHINO_CONFIG_USER_HOOK +#define RHINO_CONFIG_USER_HOOK 0 +#endif + +/* kernel stats conf */ +#ifndef RHINO_CONFIG_SYSTEM_STATS +#define RHINO_CONFIG_SYSTEM_STATS 1 +#endif +#ifndef RHINO_CONFIG_DISABLE_SCHED_STATS +#define RHINO_CONFIG_DISABLE_SCHED_STATS 0 +#endif +#ifndef RHINO_CONFIG_DISABLE_INTRPT_STATS +#define RHINO_CONFIG_DISABLE_INTRPT_STATS 0 +#endif +#ifndef RHINO_CONFIG_CPU_USAGE_STATS +#define RHINO_CONFIG_CPU_USAGE_STATS 0 +#endif +#ifndef RHINO_CONFIG_CPU_USAGE_TASK_PRI +#define RHINO_CONFIG_CPU_USAGE_TASK_PRI (RHINO_CONFIG_PRI_MAX - 2) +#endif +#ifndef RHINO_CONFIG_TASK_SCHED_STATS +#define RHINO_CONFIG_TASK_SCHED_STATS 0 +#endif +#ifndef RHINO_CONFIG_CPU_USAGE_TASK_STACK +#define RHINO_CONFIG_CPU_USAGE_TASK_STACK 256 +#endif + +/* kernel trace conf */ +#ifndef RHINO_CONFIG_TRACE +#define RHINO_CONFIG_TRACE 0 +#endif + +#ifndef RHINO_CONFIG_CPU_NUM +#define RHINO_CONFIG_CPU_NUM 1 +#endif + +#endif /* K_CONFIG_H */ + diff --git a/board/lpcxpresso54102/lpcxpresso54102.mk b/board/lpcxpresso54102/lpcxpresso54102.mk new file mode 100644 index 0000000000..15983c253c --- /dev/null +++ b/board/lpcxpresso54102/lpcxpresso54102.mk @@ -0,0 +1,37 @@ + +NAME := board_lpcxpresso54102 + +MODULE := 1062 +HOST_ARCH := Cortex-M4 +HOST_MCU_FAMILY := lpc54102 + +CONFIG_SYSINFO_PRODUCT_MODEL := ALI_AOS_LPC54102 +CONFIG_SYSINFO_DEVICE_NAME := LPC54102 +GLOBAL_CFLAGS += -DSYSINFO_PRODUCT_MODEL=\"$(CONFIG_SYSINFO_PRODUCT_MODEL)\" +GLOBAL_CFLAGS += -DSYSINFO_DEVICE_NAME=\"$(CONFIG_SYSINFO_DEVICE_NAME)\" +#-DCONFIG_NO_TCPIP +GLOBAL_CFLAGS += -DCPU_LPC54102J512BD64_cm4 +GLOBAL_CFLAGS += -D__USE_CMSIS -D__MULTICORE_MASTER +GLOBAL_CFLAGS += -D__NEWLIB__ + + + +GLOBAL_LDFLAGS += + +GLOBAL_INCLUDES += . +GLOBAL_INCLUDES += ../../platform/mcu/lpc54102/ +GLOBAL_INCLUDES += ../../platform/mcu/lpc54102/CMSIS/Include +GLOBAL_INCLUDES += ../../platform/mcu/lpc54102/drivers +GLOBAL_INCLUDES += ../../platform/mcu/lpc54102/mcuxpresso +GLOBAL_INCLUDES += ../../platform/mcu/lpc54102/utilities +GLOBAL_INCLUDES += ../../platform/mcu/lpc54102/utilities/str +GLOBAL_INCLUDES += ../../platform/mcu/lpc54102/utilities/log +GLOBAL_INCLUDES += ../../platform/mcu/lpc54102/utilities/io + + + +$(NAME)_SOURCES := +$(NAME)_SOURCES += ./board.c +$(NAME)_SOURCES += ./clock_config.c +$(NAME)_SOURCES += ./pin_mux.c + diff --git a/board/lpcxpresso54102/pin_mux.c b/board/lpcxpresso54102/pin_mux.c new file mode 100644 index 0000000000..256bb96cde --- /dev/null +++ b/board/lpcxpresso54102/pin_mux.c @@ -0,0 +1,193 @@ +/* + * Copyright 2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Pins v3.0 +processor: LPC54102J512 +package_id: LPC54102J512BD64 +mcu_data: ksdk2_0 +processor_version: 1.0.0 + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +#include "fsl_common.h" +#include "fsl_iocon.h" +#include "pin_mux.h" + +/*FUNCTION********************************************************************** + * + * Function Name : BOARD_InitBootPins + * Description : Calls initialization functions. + * + *END**************************************************************************/ +void BOARD_InitBootPins(void) { + BOARD_InitPins(); +} + +#define IOCON_PIO_DIGITAL_EN 0x80u /*!< Enables digital function */ +#define IOCON_PIO_FUNC0 0x00u /*!< Selects pin function 0 */ +#define IOCON_PIO_FUNC1 0x01u /*!< Selects pin function 1 */ +#define IOCON_PIO_I2CDRIVE_LOW 0x00u /*!< Low drive: 4 mA */ +#define IOCON_PIO_I2CFILTER_EN 0x00u /*!< I2C 50 ns glitch filter enabled */ +#define IOCON_PIO_I2CSLEW_GPIO 0x20u /*!< GPIO mode */ +#define IOCON_PIO_INPFILT_OFF 0x0100u /*!< Input filter disabled */ +#define IOCON_PIO_INV_DI 0x00u /*!< Input function is not inverted */ +#define IOCON_PIO_MODE_INACT 0x00u /*!< No addition pin function */ +#define IOCON_PIO_MODE_PULLUP 0x10u /*!< Selects pull-up function */ +#define IOCON_PIO_OPENDRAIN_DI 0x00u /*!< Open drain is disabled */ +#define IOCON_PIO_SLEW_STANDARD 0x00u /*!< Standard mode, output slew rate control is enabled */ +#define PIN0_IDX 0u /*!< Pin number for pin 0 in a port 0 */ +#define PIN1_IDX 1u /*!< Pin number for pin 1 in a port 0 */ +#define PIN4_IDX 4u /*!< Pin number for pin 4 in a port 0 */ +#define PIN9_IDX 9u /*!< Pin number for pin 9 in a port 1 */ +#define PIN10_IDX 10u /*!< Pin number for pin 10 in a port 1 */ +#define PIN24_IDX 24u /*!< Pin number for pin 24 in a port 0 */ +#define PIN29_IDX 29u /*!< Pin number for pin 29 in a port 0 */ +#define PIN31_IDX 31u /*!< Pin number for pin 31 in a port 0 */ +#define PORT0_IDX 0u /*!< Port index */ +#define PORT1_IDX 1u /*!< Port index */ + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +BOARD_InitPins: +- options: {callFromInitBoot: 'true', coreID: cm4, enableClock: 'true'} +- pin_list: + - {pin_num: '31', peripheral: USART0, signal: RXD, pin_signal: PIO0_0/U0_RXD/SPI0_SSELSN0/CT32B0_CAP0/SCT0_OUT3, mode: inactive, invert: disabled, glitch_filter: disabled, + slew_rate: standard, open_drain: disabled} + - {pin_num: '32', peripheral: USART0, signal: TXD, pin_signal: PIO0_1/U0_TXD/SPI0_SSELSN1/CT32B0_CAP1/SCT0_OUT1, mode: inactive, invert: disabled, glitch_filter: disabled, + slew_rate: standard, open_drain: disabled} + - {pin_num: '2', peripheral: GPIO, signal: 'PIO0, 24', pin_signal: PIO0_24/I2C0_SDA/CT32B0_CAP1/CT32B0_MAT0, invert: disabled, glitch_filter: disabled, i2c_slew: gpio, + i2c_drive: low, i2c_filter: enabled} + - {pin_num: '11', peripheral: GPIO, signal: 'PIO0, 29', pin_signal: PIO0_29/SCT0_OUT2/CT32B0_MAT3/CT32B0_CAP1/CT32B0_MAT1, mode: pullUp, invert: disabled, glitch_filter: disabled, + open_drain: disabled} + - {pin_num: '13', peripheral: GPIO, signal: 'PIO0, 31', pin_signal: PIO0_31/U2_CTS/CT32B2_CAP2/CT32B0_CAP3/CT32B0_MAT3, mode: pullUp, invert: disabled, glitch_filter: disabled, + open_drain: disabled} + - {pin_num: '38', peripheral: GPIO, signal: 'PIO0, 4', pin_signal: PIO0_4/U0_SCLK/SPI0_SSELSN2/CT32B0_CAP2, mode: pullUp, invert: disabled, glitch_filter: disabled, + slew_rate: standard, open_drain: disabled} + - {pin_num: '30', peripheral: GPIO, signal: 'PIO1, 10', pin_signal: PIO1_10/U1_TXD/SCT0_OUT4, mode: pullUp, invert: disabled, glitch_filter: disabled, slew_rate: standard, + open_drain: disabled} + - {pin_num: '29', peripheral: GPIO, signal: 'PIO1, 9', pin_signal: PIO1_9/SPI0_MOSI/CT32B0_CAP2, mode: pullUp, invert: disabled, glitch_filter: disabled, slew_rate: standard, + open_drain: disabled} + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +/*FUNCTION********************************************************************** + * + * Function Name : BOARD_InitPins + * Description : Configures pin routing and optionally pin electrical features. + * + *END**************************************************************************/ +void BOARD_InitPins(void) { /* Function assigned for the Cortex-M0P */ + CLOCK_EnableClock(kCLOCK_Iocon); /* Enables the clock for the IOCON block. 0 = Disable; 1 = Enable.: 0x01u */ + + const uint32_t port0_pin0_config = ( + IOCON_PIO_FUNC1 | /* Pin is configured as U0_RXD */ + IOCON_PIO_MODE_INACT | /* No addition pin function */ + IOCON_PIO_INV_DI | /* Input function is not inverted */ + IOCON_PIO_DIGITAL_EN | /* Enables digital function */ + IOCON_PIO_INPFILT_OFF | /* Input filter disabled */ + IOCON_PIO_SLEW_STANDARD | /* Standard mode, output slew rate control is enabled */ + IOCON_PIO_OPENDRAIN_DI /* Open drain is disabled */ + ); + IOCON_PinMuxSet(IOCON, PORT0_IDX, PIN0_IDX, port0_pin0_config); /* PORT0 PIN0 (coords: 31) is configured as U0_RXD */ + const uint32_t port0_pin1_config = ( + IOCON_PIO_FUNC1 | /* Pin is configured as U0_TXD */ + IOCON_PIO_MODE_INACT | /* No addition pin function */ + IOCON_PIO_INV_DI | /* Input function is not inverted */ + IOCON_PIO_DIGITAL_EN | /* Enables digital function */ + IOCON_PIO_INPFILT_OFF | /* Input filter disabled */ + IOCON_PIO_SLEW_STANDARD | /* Standard mode, output slew rate control is enabled */ + IOCON_PIO_OPENDRAIN_DI /* Open drain is disabled */ + ); + IOCON_PinMuxSet(IOCON, PORT0_IDX, PIN1_IDX, port0_pin1_config); /* PORT0 PIN1 (coords: 32) is configured as U0_TXD */ + const uint32_t port0_pin24_config = ( + IOCON_PIO_FUNC0 | /* Pin is configured as PIO0_24 */ + IOCON_PIO_I2CSLEW_GPIO | /* GPIO mode */ + IOCON_PIO_INV_DI | /* Input function is not inverted */ + IOCON_PIO_DIGITAL_EN | /* Enables digital function */ + IOCON_PIO_INPFILT_OFF | /* Input filter disabled */ + IOCON_PIO_I2CDRIVE_LOW | /* Low drive: 4 mA */ + IOCON_PIO_I2CFILTER_EN /* I2C 50 ns glitch filter enabled */ + ); + IOCON_PinMuxSet(IOCON, PORT0_IDX, PIN24_IDX, port0_pin24_config); /* PORT0 PIN24 (coords: 2) is configured as PIO0_24 */ + const uint32_t port0_pin29_config = ( + IOCON_PIO_FUNC0 | /* Pin is configured as PIO0_29 */ + IOCON_PIO_MODE_PULLUP | /* Selects pull-up function */ + IOCON_PIO_INV_DI | /* Input function is not inverted */ + IOCON_PIO_DIGITAL_EN | /* Enables digital function */ + IOCON_PIO_INPFILT_OFF | /* Input filter disabled */ + IOCON_PIO_OPENDRAIN_DI /* Open drain is disabled */ + ); + IOCON_PinMuxSet(IOCON, PORT0_IDX, PIN29_IDX, port0_pin29_config); /* PORT0 PIN29 (coords: 11) is configured as PIO0_29 */ + const uint32_t port0_pin31_config = ( + IOCON_PIO_FUNC0 | /* Pin is configured as PIO0_31 */ + IOCON_PIO_MODE_PULLUP | /* Selects pull-up function */ + IOCON_PIO_INV_DI | /* Input function is not inverted */ + IOCON_PIO_DIGITAL_EN | /* Enables digital function */ + IOCON_PIO_INPFILT_OFF | /* Input filter disabled */ + IOCON_PIO_OPENDRAIN_DI /* Open drain is disabled */ + ); + IOCON_PinMuxSet(IOCON, PORT0_IDX, PIN31_IDX, port0_pin31_config); /* PORT0 PIN31 (coords: 13) is configured as PIO0_31 */ + const uint32_t port0_pin4_config = ( + IOCON_PIO_FUNC0 | /* Pin is configured as PIO0_4 */ + IOCON_PIO_MODE_PULLUP | /* Selects pull-up function */ + IOCON_PIO_INV_DI | /* Input function is not inverted */ + IOCON_PIO_DIGITAL_EN | /* Enables digital function */ + IOCON_PIO_INPFILT_OFF | /* Input filter disabled */ + IOCON_PIO_SLEW_STANDARD | /* Standard mode, output slew rate control is enabled */ + IOCON_PIO_OPENDRAIN_DI /* Open drain is disabled */ + ); + IOCON_PinMuxSet(IOCON, PORT0_IDX, PIN4_IDX, port0_pin4_config); /* PORT0 PIN4 (coords: 38) is configured as PIO0_4 */ + const uint32_t port1_pin10_config = ( + IOCON_PIO_FUNC0 | /* Pin is configured as PIO1_10 */ + IOCON_PIO_MODE_PULLUP | /* Selects pull-up function */ + IOCON_PIO_INV_DI | /* Input function is not inverted */ + IOCON_PIO_DIGITAL_EN | /* Enables digital function */ + IOCON_PIO_INPFILT_OFF | /* Input filter disabled */ + IOCON_PIO_SLEW_STANDARD | /* Standard mode, output slew rate control is enabled */ + IOCON_PIO_OPENDRAIN_DI /* Open drain is disabled */ + ); + IOCON_PinMuxSet(IOCON, PORT1_IDX, PIN10_IDX, port1_pin10_config); /* PORT1 PIN10 (coords: 30) is configured as PIO1_10 */ + const uint32_t port1_pin9_config = ( + IOCON_PIO_FUNC0 | /* Pin is configured as PIO1_9 */ + IOCON_PIO_MODE_PULLUP | /* Selects pull-up function */ + IOCON_PIO_INV_DI | /* Input function is not inverted */ + IOCON_PIO_DIGITAL_EN | /* Enables digital function */ + IOCON_PIO_INPFILT_OFF | /* Input filter disabled */ + IOCON_PIO_SLEW_STANDARD | /* Standard mode, output slew rate control is enabled */ + IOCON_PIO_OPENDRAIN_DI /* Open drain is disabled */ + ); + IOCON_PinMuxSet(IOCON, PORT1_IDX, PIN9_IDX, port1_pin9_config); /* PORT1 PIN9 (coords: 29) is configured as PIO1_9 */ +} + +/******************************************************************************* + * EOF + ******************************************************************************/ diff --git a/board/lpcxpresso54102/pin_mux.h b/board/lpcxpresso54102/pin_mux.h new file mode 100644 index 0000000000..e1363e4a70 --- /dev/null +++ b/board/lpcxpresso54102/pin_mux.h @@ -0,0 +1,111 @@ +/* + * The Clear BSD License + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted (subject to the limitations in the disclaimer below) provided + * that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 + * 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 _PIN_MUX_H_ +#define _PIN_MUX_H_ + + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief Direction type */ +typedef enum _pin_mux_direction +{ + kPIN_MUX_DirectionInput = 0U, /* Input direction */ + kPIN_MUX_DirectionOutput = 1U, /* Output direction */ + kPIN_MUX_DirectionInputOrOutput = 2U /* Input or output direction */ +} pin_mux_direction_t; + + + +/*! @name PIO4_7 (coord A14), PWRON + @{ */ +#define BOARD_INITGT202SHIELD_PWRON_GPIO GPIO /*!<@brief GPIO device name: GPIO */ +#define BOARD_INITGT202SHIELD_PWRON_GPIO_PIN 4U /*!<@brief PIO4 pin index: 7 */ +#define BOARD_INITGT202SHIELD_PWRON_PORT 0U /*!<@brief PORT device name: 4U */ +#define BOARD_INITGT202SHIELD_PWRON_DIRECTION kPIN_MUX_DirectionOutput /*!<@brief Direction */ + /* @} */ + +/*! @name PIO1_22 (coord P11), IRQ + @{ */ +#define BOARD_INITGT202SHIELD_IRQ_GPIO GPIO /*!<@brief GPIO device name: GPIO */ +#define BOARD_INITGT202SHIELD_IRQ_GPIO_PIN 6U /*!<@brief PIO1 pin index: 22 */ +#define BOARD_INITGT202SHIELD_IRQ_PORT 0U /*!<@brief PORT device name: 1U */ +#define BOARD_INITGT202SHIELD_IRQ_DIRECTION kPIN_MUX_DirectionInput /*!<@brief Direction */ + /* @} */ + +/*! + * @addtogroup pin_mux + * @{ + */ + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitGT202Shield(void); /* Function assigned for the Cortex-M4F */ + +/*! + * @brief Calls initialization functions. + * + */ +void BOARD_InitBootPins(void); + +/*! + * @brief Configures pin routing and optionally pin electrical features. + * + */ +void BOARD_InitPins(void); /* Function assigned for the Cortex-M4 */ + +#if defined(__cplusplus) +} +#endif + +/*! + * @} + */ +#endif /* _PIN_MUX_H_ */ + +/******************************************************************************* + * EOF + ******************************************************************************/ diff --git a/board/mk108/mk108.mk b/board/mk108/mk108.mk deleted file mode 100644 index 91c50fe09c..0000000000 --- a/board/mk108/mk108.mk +++ /dev/null @@ -1,32 +0,0 @@ -NAME := board_mk108 - -JTAG := jlink - -MODULE := MOC108 -HOST_ARCH := ARM968E-S -HOST_MCU_FAMILY := moc108 -SUPPORT_BINS := no - -$(NAME)_SOURCES := board.c - -GLOBAL_INCLUDES += . -GLOBAL_DEFINES += STDIO_UART=1 - -CURRENT_TIME = $(shell /bin/date +%Y%m%d.%H%M) -define get-os-version -"AOS-R"-$(CURRENT_TIME) -endef - -CONFIG_SYSINFO_OS_VERSION := $(call get-os-version) -CONFIG_SYSINFO_PRODUCT_MODEL := ALI_AOS_MK108 -CONFIG_SYSINFO_DEVICE_NAME := MK108 - -GLOBAL_CFLAGS += -DSYSINFO_OS_VERSION=\"$(CONFIG_SYSINFO_OS_VERSION)\" -GLOBAL_CFLAGS += -DSYSINFO_PRODUCT_MODEL=\"$(CONFIG_SYSINFO_PRODUCT_MODEL)\" -GLOBAL_CFLAGS += -DSYSINFO_DEVICE_NAME=\"$(CONFIG_SYSINFO_DEVICE_NAME)\" - -GLOBAL_LDFLAGS += -L $(SOURCE_ROOT)/board/mk108 - -# Extra build target in mico_standard_targets.mk, include bootloader, and copy output file to eclipse debug file (copy_output_for_eclipse) -EXTRA_TARGET_MAKEFILES += $(MAKEFILES_PATH)/aos_standard_targets.mk -EXTRA_TARGET_MAKEFILES += $(SOURCE_ROOT)/platform/mcu/$(HOST_MCU_FAMILY)/gen_crc_bin.mk diff --git a/board/mk1101/board.c b/board/mk1101/board.c new file mode 100755 index 0000000000..c162e08819 --- /dev/null +++ b/board/mk1101/board.c @@ -0,0 +1,9 @@ +#include "hal/soc/soc.h" +#include + +/* Logic partition on flash devices */ +hal_logic_partition_t hal_partitions[HAL_PARTITION_MAX]; + +void board_init(void) +{ +} diff --git a/board/mk1101/board.h b/board/mk1101/board.h new file mode 100644 index 0000000000..4f2a8ccfa2 --- /dev/null +++ b/board/mk1101/board.h @@ -0,0 +1,10 @@ +#define HARDWARE_REVISION "V1.0" +#define MODEL "EML3047" + +#ifdef BOOTLOADER +#define STDIO_UART 0 +#define STDIO_UART_BUADRATE 115200 +#else +#define STDIO_UART 0 +#define STDIO_UART_BUADRATE 115200 +#endif diff --git a/board/mk1101/k_config.h b/board/mk1101/k_config.h new file mode 100644 index 0000000000..e8a943c049 --- /dev/null +++ b/board/mk1101/k_config.h @@ -0,0 +1,225 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#ifndef CONFIG_H +#define CONFIG_H + +/* chip level conf */ +#ifndef RHINO_CONFIG_LITTLE_ENDIAN +#define RHINO_CONFIG_LITTLE_ENDIAN 1 +#endif +#ifndef RHINO_CONFIG_CPU_STACK_DOWN +#define RHINO_CONFIG_CPU_STACK_DOWN 1 +#endif + +/* kernel feature conf */ +#ifndef RHINO_CONFIG_SEM +#define RHINO_CONFIG_SEM 1 +#endif +#ifndef RHINO_CONFIG_QUEUE +#define RHINO_CONFIG_QUEUE 1 +#endif +#ifndef RHINO_CONFIG_TASK_SEM +#define RHINO_CONFIG_TASK_SEM 1 +#endif +#ifndef RHINO_CONFIG_EVENT_FLAG +#define RHINO_CONFIG_EVENT_FLAG 1 +#endif +#ifndef RHINO_CONFIG_TIMER +#define RHINO_CONFIG_TIMER 1 +#endif +#ifndef RHINO_CONFIG_BUF_QUEUE +#define RHINO_CONFIG_BUF_QUEUE 1 +#endif +#ifndef RHINO_CONFIG_MM_BLK +#define RHINO_CONFIG_MM_BLK 1 +#endif +#ifndef RHINO_CONFIG_MM_DEBUG +#define RHINO_CONFIG_MM_DEBUG 1 +#endif +#ifndef RHINO_CONFIG_MM_TLF +#define RHINO_CONFIG_MM_TLF 1 +#endif +#ifndef RHINO_CONFIG_MM_TLF_BLK_SIZE +#define RHINO_CONFIG_MM_TLF_BLK_SIZE 1024 +#endif +#define K_MM_STATISTIC 1 +#ifndef RHINO_CONFIG_MM_MAXMSIZEBIT +#define RHINO_CONFIG_MM_MAXMSIZEBIT 19 +#endif +#ifndef RHINO_CONFIG_GCC_RETADDR +#define RHINO_CONFIG_GCC_RETADDR 1 +#endif +#ifndef RHINO_CONFIG_MM_LEAKCHECK +#define RHINO_CONFIG_MM_LEAKCHECK 0 +#endif +#ifndef RHINO_CONFIG_RINGBUF_VENDOR +#define RHINO_CONFIG_RINGBUF_VENDOR 0 +#endif + +#ifndef RHINO_CONFIG_KOBJ_SET +#define RHINO_CONFIG_KOBJ_SET 1 +#endif + +/* kernel task conf */ +#ifndef RHINO_CONFIG_TASK_SUSPEND +#define RHINO_CONFIG_TASK_SUSPEND 1 +#endif +#ifndef RHINO_CONFIG_TASK_INFO +#define RHINO_CONFIG_TASK_INFO 1 +#endif +#ifndef RHINO_CONFIG_TASK_DEL +#define RHINO_CONFIG_TASK_DEL 1 +#endif + +#ifndef RHINO_CONFIG_TASK_STACK_CUR_CHECK +#define RHINO_CONFIG_TASK_STACK_CUR_CHECK 1 +#endif + +#ifndef RHINO_CONFIG_TASK_WAIT_ABORT +#define RHINO_CONFIG_TASK_WAIT_ABORT 1 +#endif +#ifndef RHINO_CONFIG_TASK_STACK_OVF_CHECK +#define RHINO_CONFIG_TASK_STACK_OVF_CHECK 1 +#endif +#ifndef RHINO_CONFIG_SCHED_RR +#define RHINO_CONFIG_SCHED_RR 1 +#endif +#ifndef RHINO_CONFIG_TIME_SLICE_DEFAULT +#define RHINO_CONFIG_TIME_SLICE_DEFAULT 50 +#endif +#ifndef RHINO_CONFIG_PRI_MAX +#define RHINO_CONFIG_PRI_MAX 62 +#endif +#ifndef RHINO_CONFIG_USER_PRI_MAX +#define RHINO_CONFIG_USER_PRI_MAX (RHINO_CONFIG_PRI_MAX - 2) +#endif + +/* kernel workqueue conf */ +#ifndef RHINO_CONFIG_WORKQUEUE +#define RHINO_CONFIG_WORKQUEUE 1 +#endif +#ifndef RHINO_CONFIG_WORKQUEUE_STACK_SIZE +#define RHINO_CONFIG_WORKQUEUE_STACK_SIZE 768 +#endif + +/* kernel mm_region conf */ +#ifndef RHINO_CONFIG_MM_REGION_MUTEX +#define RHINO_CONFIG_MM_REGION_MUTEX 0 +#endif + +/* kernel timer&tick conf */ +#ifndef RHINO_CONFIG_HW_COUNT +#define RHINO_CONFIG_HW_COUNT 0 +#endif +#ifndef RHINO_CONFIG_TICK_TASK +#define RHINO_CONFIG_TICK_TASK 0 +#endif + +#if (RHINO_CONFIG_TICK_TASK > 0) +#ifndef RHINO_CONFIG_TICK_TASK_STACK_SIZE +#define RHINO_CONFIG_TICK_TASK_STACK_SIZE 256 +#endif +#ifndef RHINO_CONFIG_TICK_TASK_PRI +#define RHINO_CONFIG_TICK_TASK_PRI 1 +#endif +#endif + +#ifndef RHINO_CONFIG_TICKLESS +#define RHINO_CONFIG_TICKLESS 0 +#endif +#ifndef RHINO_CONFIG_TICKS_PER_SECOND +#define RHINO_CONFIG_TICKS_PER_SECOND 100 +#endif +/* must be 2^n size!, such as 1, 2, 4, 8, 16,32, etc....... */ +#ifndef RHINO_CONFIG_TICK_HEAD_ARRAY +#define RHINO_CONFIG_TICK_HEAD_ARRAY 8 +#endif + +/*must reserve enough stack size for timer cb will consume*/ +#ifndef RHINO_CONFIG_TIMER_TASK_STACK_SIZE +#define RHINO_CONFIG_TIMER_TASK_STACK_SIZE 300 +#endif +#ifndef RHINO_CONFIG_TIMER_RATE +#define RHINO_CONFIG_TIMER_RATE 1 +#endif +#ifndef RHINO_CONFIG_TIMER_TASK_PRI +#define RHINO_CONFIG_TIMER_TASK_PRI 5 +#endif + +/* kernel intrpt conf */ +#ifndef RHINO_CONFIG_INTRPT_STACK_REMAIN_GET +#define RHINO_CONFIG_INTRPT_STACK_REMAIN_GET 0 +#endif +#ifndef RHINO_CONFIG_INTRPT_STACK_OVF_CHECK +#define RHINO_CONFIG_INTRPT_STACK_OVF_CHECK 0 +#endif +#ifndef RHINO_CONFIG_INTRPT_MAX_NESTED_LEVEL +#define RHINO_CONFIG_INTRPT_MAX_NESTED_LEVEL 188u +#endif +#ifndef RHINO_CONFIG_INTRPT_GUARD +#define RHINO_CONFIG_INTRPT_GUARD 0 +#endif + +/* kernel dyn alloc conf */ +#ifndef RHINO_CONFIG_KOBJ_DYN_ALLOC +#define RHINO_CONFIG_KOBJ_DYN_ALLOC 1 +#endif + +#if (RHINO_CONFIG_KOBJ_DYN_ALLOC > 0) +#ifndef RHINO_CONFIG_K_DYN_QUEUE_MSG +#define RHINO_CONFIG_K_DYN_QUEUE_MSG 30 +#endif +#ifndef RHINO_CONFIG_K_DYN_TASK_STACK +#define RHINO_CONFIG_K_DYN_TASK_STACK 256 +#endif +#ifndef RHINO_CONFIG_K_DYN_MEM_TASK_PRI +#define RHINO_CONFIG_K_DYN_MEM_TASK_PRI 6 +#endif +#endif + +/* kernel idle conf */ +#ifndef RHINO_CONFIG_IDLE_TASK_STACK_SIZE +#define RHINO_CONFIG_IDLE_TASK_STACK_SIZE 200 +#endif + +/* kernel hook conf */ +#ifndef RHINO_CONFIG_USER_HOOK +#define RHINO_CONFIG_USER_HOOK 0 +#endif + +/* kernel stats conf */ +#ifndef RHINO_CONFIG_SYSTEM_STATS +#define RHINO_CONFIG_SYSTEM_STATS 1 +#endif +#ifndef RHINO_CONFIG_DISABLE_SCHED_STATS +#define RHINO_CONFIG_DISABLE_SCHED_STATS 0 +#endif +#ifndef RHINO_CONFIG_DISABLE_INTRPT_STATS +#define RHINO_CONFIG_DISABLE_INTRPT_STATS 0 +#endif +#ifndef RHINO_CONFIG_CPU_USAGE_STATS +#define RHINO_CONFIG_CPU_USAGE_STATS 0 +#endif +#ifndef RHINO_CONFIG_CPU_USAGE_TASK_PRI +#define RHINO_CONFIG_CPU_USAGE_TASK_PRI (RHINO_CONFIG_PRI_MAX - 2) +#endif +#ifndef RHINO_CONFIG_TASK_SCHED_STATS +#define RHINO_CONFIG_TASK_SCHED_STATS 0 +#endif +#ifndef RHINO_CONFIG_CPU_USAGE_TASK_STACK +#define RHINO_CONFIG_CPU_USAGE_TASK_STACK 256 +#endif + +#ifndef RHINO_CONFIG_CPU_NUM +#define RHINO_CONFIG_CPU_NUM 1 +#endif + +/* kernel trace conf */ +#ifndef RHINO_CONFIG_TRACE +#define RHINO_CONFIG_TRACE 0 +#endif + +#endif /* CONFIG_H */ + diff --git a/board/mk1101/mk1101.mk b/board/mk1101/mk1101.mk new file mode 100644 index 0000000000..c85d184090 --- /dev/null +++ b/board/mk1101/mk1101.mk @@ -0,0 +1,35 @@ +NAME := board_mk1101 + +JTAG := jlink_swd + +$(NAME)_TYPE := kernel +MODULE := 1062 +HOST_ARCH := Cortex-M3 +HOST_MCU_FAMILY := mx1101 + +$(NAME)_SOURCES := board.c + +GLOBAL_INCLUDES += . +GLOBAL_DEFINES += STDIO_UART=0 CONFIG_NO_TCPIP +GLOBAL_DEFINES += RHINO_CONFIG_TICK_TASK=0 RHINO_CONFIG_WORKQUEUE=0 + +CONFIG_SYSINFO_PRODUCT_MODEL := ALI_AOS_MX1101 +CONFIG_SYSINFO_DEVICE_NAME := MX1101 + +GLOBAL_CFLAGS += -DSYSINFO_OS_VERSION=\"$(CONFIG_SYSINFO_OS_VERSION)\" +GLOBAL_CFLAGS += -DSYSINFO_PRODUCT_MODEL=\"$(CONFIG_SYSINFO_PRODUCT_MODEL)\" +GLOBAL_CFLAGS += -DSYSINFO_DEVICE_NAME=\"$(CONFIG_SYSINFO_DEVICE_NAME)\" + +GLOBAL_LDFLAGS += -L $(SOURCE_ROOT)/board/mx1101 + +# Global defines +# HSE_VALUE = STM32 crystal frequency = 26MHz (needed to make UART work correctly) +GLOBAL_DEFINES += $$(if $$(NO_CRLF_STDIO_REPLACEMENT),,CRLF_STDIO_REPLACEMENT) +GLOBAL_CFLAGS += -mcpu=cortex-m3 -mthumb -mfloat-abi=soft + +WIFI_FIRMWARE_SECTOR_START := 2 #0x2000 +FILESYSTEM_IMAGE_SECTOR_START := 256 #0x100000 + +# Extra build target in mico_standard_targets.mk, include bootloader, and copy output file to eclipse debug file (copy_output_for_eclipse) +EXTRA_TARGET_MAKEFILES += $(MAKEFILES_PATH)/aos_standard_targets.mk +#EXTRA_TARGET_MAKEFILES += $(SOURCE_ROOT)/platform/mcu/$(HOST_MCU_FAMILY)/gen_crc_bin.mk diff --git a/board/mk3166/memory.ld b/board/mk3166/memory.ld index a1ffa1b8f7..9c80ccf753 100644 --- a/board/mk3166/memory.ld +++ b/board/mk3166/memory.ld @@ -1,27 +1,3 @@ -/** -****************************************************************************** -* -* The MIT License -* Copyright (c) 2016 MXCHIP Inc. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is furnished -* to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -* IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -****************************************************************************** -*/ MEMORY { @@ -29,4 +5,4 @@ MEMORY APP_FLASH (rx) : ORIGIN = 0x08008000, LENGTH = 1000K RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 256K ERAM (rwx) : ORIGIN = 0, LENGTH = 0 -} \ No newline at end of file +} diff --git a/board/mk3239/board.c b/board/mk3239/board.c new file mode 100644 index 0000000000..85335725b4 --- /dev/null +++ b/board/mk3239/board.c @@ -0,0 +1,492 @@ +#include "hal/soc/soc.h" +#include +#include "platform_bluetooth.h" + +/* Logic partition on flash devices */ +hal_logic_partition_t hal_partitions[HAL_PARTITION_MAX]; + +void board_init(void) +{ + + hal_partitions[HAL_PARTITION_BOOTLOADER].partition_owner = HAL_FLASH_EMBEDDED; + hal_partitions[HAL_PARTITION_BOOTLOADER].partition_description = "Bootloader"; + hal_partitions[HAL_PARTITION_BOOTLOADER].partition_start_addr = 0x08000000; + hal_partitions[HAL_PARTITION_BOOTLOADER].partition_length = 0x8000; //500k bytes + hal_partitions[HAL_PARTITION_BOOTLOADER].partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_DIS; + + hal_partitions[HAL_PARTITION_APPLICATION].partition_owner = HAL_FLASH_EMBEDDED; + hal_partitions[HAL_PARTITION_APPLICATION].partition_description = "Application"; + hal_partitions[HAL_PARTITION_APPLICATION].partition_start_addr = 0x08008000; + hal_partitions[HAL_PARTITION_APPLICATION].partition_length = 0xF8000, //992k bytes + hal_partitions[HAL_PARTITION_APPLICATION].partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_EN; + + hal_partitions[HAL_PARTITION_RF_FIRMWARE].partition_owner = HAL_FLASH_QSPI; + hal_partitions[HAL_PARTITION_RF_FIRMWARE].partition_description = "RF Firmware"; + hal_partitions[HAL_PARTITION_RF_FIRMWARE].partition_start_addr = 0x2000; + hal_partitions[HAL_PARTITION_RF_FIRMWARE].partition_length = 0x6E000; ///440k bytes + hal_partitions[HAL_PARTITION_RF_FIRMWARE].partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_EN; + + hal_partitions[HAL_PARTITION_PARAMETER_1].partition_owner = HAL_FLASH_QSPI; + hal_partitions[HAL_PARTITION_PARAMETER_1].partition_description = "PARAMETER1"; + hal_partitions[HAL_PARTITION_PARAMETER_1].partition_start_addr = 0x1F8000; + hal_partitions[HAL_PARTITION_PARAMETER_1].partition_length = 0x1000; // 4k bytes + hal_partitions[HAL_PARTITION_PARAMETER_1].partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_EN; + + hal_partitions[HAL_PARTITION_PARAMETER_2].partition_owner = HAL_FLASH_QSPI; + hal_partitions[HAL_PARTITION_PARAMETER_2].partition_description = "PARAMETER2"; + hal_partitions[HAL_PARTITION_PARAMETER_2].partition_start_addr = 0x1F9000; + hal_partitions[HAL_PARTITION_PARAMETER_2].partition_length = 0x4000; //16k bytes + hal_partitions[HAL_PARTITION_PARAMETER_2].partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_EN; + + hal_partitions[HAL_PARTITION_OTA_TEMP].partition_owner = HAL_FLASH_EMBEDDED; + hal_partitions[HAL_PARTITION_OTA_TEMP].partition_description = "OTA Storage"; + hal_partitions[HAL_PARTITION_OTA_TEMP].partition_start_addr = 0x70000; + hal_partitions[HAL_PARTITION_OTA_TEMP].partition_length = 0xF8000, //608k bytes + hal_partitions[HAL_PARTITION_OTA_TEMP].partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_EN; + + hal_partitions[HAL_PARTITION_PARAMETER_3].partition_owner = HAL_FLASH_QSPI; + hal_partitions[HAL_PARTITION_PARAMETER_3].partition_description = "PARAMETER3"; + hal_partitions[HAL_PARTITION_PARAMETER_3].partition_start_addr = 0x1FD000; + hal_partitions[HAL_PARTITION_PARAMETER_3].partition_length = 0x1000; //4k bytes + hal_partitions[HAL_PARTITION_PARAMETER_3].partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_EN; + + hal_partitions[HAL_PARTITION_PARAMETER_4].partition_owner = HAL_FLASH_QSPI; + hal_partitions[HAL_PARTITION_PARAMETER_4].partition_description = "PARAMETER4"; + hal_partitions[HAL_PARTITION_PARAMETER_4].partition_start_addr = 0x1FE000; + hal_partitions[HAL_PARTITION_PARAMETER_4].partition_length = 0x1000; //4k bytes + hal_partitions[HAL_PARTITION_PARAMETER_4].partition_options = PAR_OPT_READ_EN | PAR_OPT_WRITE_EN; +} + + + +#include "platform_config.h" +#include "platform_peripheral.h" +#include "platform_config.h" +#include "platform_logging.h" +#include "wlan_platform_common.h" + +/****************************************************** +* Function Declarations +******************************************************/ +extern WEAK void PlatformEasyLinkButtonClickedCallback(void); +extern WEAK void PlatformEasyLinkButtonLongPressedCallback(void); +extern WEAK void bootloader_start(void); + +/****************************************************** +* Variables Definitions +******************************************************/ + +const platform_gpio_t platform_gpio_pins[] = +{ + /* Common GPIOs for internal use */ + [FLASH_PIN_QSPI_CS ] = { GPIOC, 11 }, + [FLASH_PIN_QSPI_CLK] = { GPIOB, 1 }, + [FLASH_PIN_QSPI_D0] = { GPIOA, 6 }, + [FLASH_PIN_QSPI_D1] = { GPIOA, 7 }, + [FLASH_PIN_QSPI_D2] = { GPIOC, 4 }, + [FLASH_PIN_QSPI_D3] = { GPIOC, 5 }, + + /* GPIOs for external use */ + [MICO_GPIO_2] = { GPIOB, 2 }, + [MICO_GPIO_4] = { GPIOB, 15 }, + [MICO_GPIO_5] = { GPIOB, 12 }, + [MICO_GPIO_6] = { GPIOB, 13 }, + [MICO_GPIO_7] = { GPIOB, 14 }, + [MICO_GPIO_8] = { GPIOC, 6 }, + [MICO_GPIO_9] = { GPIOA, 15 }, + [MICO_GPIO_12] = { GPIOC, 7 }, + [MICO_GPIO_14] = { GPIOC, 0 }, + [MICO_GPIO_16] = { GPIOC, 13 }, + [MICO_GPIO_17] = { GPIOB, 8 }, + [MICO_GPIO_18] = { GPIOB, 9 }, + [MICO_GPIO_19] = { GPIOB, 10 }, + [MICO_GPIO_27] = { GPIOB, 3 }, + [MICO_GPIO_29] = { GPIOB, 7 }, + [MICO_GPIO_30] = { GPIOB, 6 }, + [MICO_GPIO_31] = { GPIOB, 4 }, + [MICO_GPIO_33] = { GPIOA, 10 }, + [MICO_GPIO_34] = { GPIOA, 5 }, + [MICO_GPIO_35] = { GPIOA, 11 }, + [MICO_GPIO_36] = { GPIOA, 12 }, + [MICO_GPIO_37] = { GPIOB, 0 }, + [MICO_GPIO_38] = { GPIOA, 4 }, +}; + +const platform_pwm_t *platform_pwm_peripherals = NULL; + +const platform_i2c_t platform_i2c_peripherals[] = +{ + [MICO_I2C_1] = + { + .port = I2C1, + .pin_scl = &platform_gpio_pins[MICO_GPIO_17], + .pin_sda = &platform_gpio_pins[MICO_GPIO_18], + .peripheral_clock_reg = RCC_APB1Periph_I2C1, + .tx_dma = DMA1, + .tx_dma_peripheral_clock = RCC_AHB1Periph_DMA1, + .tx_dma_stream = DMA1_Stream1, + .rx_dma_stream = DMA1_Stream0, + .tx_dma_stream_id = 1, + .rx_dma_stream_id = 0, + .tx_dma_channel = DMA_Channel_1, + .rx_dma_channel = DMA_Channel_1, + .gpio_af_scl = GPIO_AF_I2C1, + .gpio_af_sda = GPIO_AF_I2C1 + }, +}; + +platform_i2c_driver_t platform_i2c_drivers[MICO_I2C_MAX]; + +const platform_uart_t platform_uart_peripherals[] = +{ + [MICO_UART_1] = + { + .port = USART6, + .pin_tx = &platform_gpio_pins[MICO_GPIO_8], + .pin_rx = &platform_gpio_pins[MICO_GPIO_12], + .pin_cts = NULL, + .pin_rts = NULL, + .tx_dma_config = + { + .controller = DMA2, + .stream = DMA2_Stream6, + .channel = DMA_Channel_5, + .irq_vector = DMA2_Stream6_IRQn, + .complete_flags = DMA_HISR_TCIF6, + .error_flags = ( DMA_HISR_TEIF6 | DMA_HISR_FEIF6 ), + }, + .rx_dma_config = + { + .controller = DMA2, + .stream = DMA2_Stream1, + .channel = DMA_Channel_5, + .irq_vector = DMA2_Stream1_IRQn, + .complete_flags = DMA_LISR_TCIF1, + .error_flags = ( DMA_LISR_TEIF1 | DMA_LISR_FEIF1 | DMA_LISR_DMEIF1 ), + }, + }, + [MICO_UART_2] = + { + .port = USART1, + .pin_tx = &platform_gpio_pins[MICO_GPIO_30], + .pin_rx = &platform_gpio_pins[MICO_GPIO_29], + .pin_cts = NULL, + .pin_rts = NULL, + .tx_dma_config = + { + .controller = DMA2, + .stream = DMA2_Stream7, + .channel = DMA_Channel_4, + .irq_vector = DMA2_Stream7_IRQn, + .complete_flags = DMA_HISR_TCIF7, + .error_flags = ( DMA_HISR_TEIF7 | DMA_HISR_FEIF7 ), + }, + .rx_dma_config = + { + .controller = DMA2, + .stream = DMA2_Stream2, + .channel = DMA_Channel_4, + .irq_vector = DMA2_Stream2_IRQn, + .complete_flags = DMA_LISR_TCIF2, + .error_flags = ( DMA_LISR_TEIF2 | DMA_LISR_FEIF2 | DMA_LISR_DMEIF2 ), + }, + }, +}; +platform_uart_driver_t platform_uart_drivers[MICO_UART_MAX]; + +const platform_spi_t platform_spi_peripherals[] = +{ + [MICO_SPI_1] = + { + .port = SPI2, + .gpio_af = GPIO_AF_SPI2, + .peripheral_clock_reg = RCC_APB1Periph_SPI2, + .peripheral_clock_func = RCC_APB1PeriphClockCmd, + .pin_mosi = &platform_gpio_pins[MICO_GPIO_4], + .pin_miso = &platform_gpio_pins[MICO_GPIO_7], + .pin_clock = &platform_gpio_pins[MICO_GPIO_6], + .tx_dma = + { + .controller = DMA1, + .stream = DMA1_Stream4, + .channel = DMA_Channel_0, + .irq_vector = DMA1_Stream4_IRQn, + .complete_flags = DMA_HISR_TCIF4, + .error_flags = ( DMA_HISR_TEIF4 | DMA_HISR_FEIF4 ), + }, + .rx_dma = + { + .controller = DMA1, + .stream = DMA1_Stream3, + .channel = DMA_Channel_0, + .irq_vector = DMA1_Stream3_IRQn, + .complete_flags = DMA_LISR_TCIF3, + .error_flags = ( DMA_LISR_TEIF3 | DMA_LISR_FEIF3 | DMA_LISR_DMEIF3 ), + }, + } +}; + +platform_spi_driver_t platform_spi_drivers[MICO_SPI_MAX]; + + +const platform_qspi_t platform_qspi_peripherals[] = +{ + [MICO_QSPI_1] = + { + .port = QUADSPI, + .FSelect = QSPI_FSelect_2, + .peripheral_clock_reg = RCC_AHB3Periph_QSPI, + .peripheral_clock_func = RCC_AHB3PeriphClockCmd, + .pin_d0 = &platform_gpio_pins[FLASH_PIN_QSPI_D0], + .pin_d1 = &platform_gpio_pins[FLASH_PIN_QSPI_D1], + .pin_d2 = &platform_gpio_pins[FLASH_PIN_QSPI_D2], + .pin_d3 = &platform_gpio_pins[FLASH_PIN_QSPI_D3], + .pin_clock = &platform_gpio_pins[FLASH_PIN_QSPI_CLK], + .pin_cs = &platform_gpio_pins[FLASH_PIN_QSPI_CS], +#ifdef USE_QUAD_SPI_DMA + .dma = + { + .controller = DMA2, + .stream = DMA2_Stream7, + .channel = DMA_Channel_3, + .complete_flags = DMA_FLAG_TCIF7, + }, +#endif + .gpio_af_d0 = GPIO_AF10_QUADSPI, + .gpio_af_d1 = GPIO_AF10_QUADSPI, + .gpio_af_d2 = GPIO_AF10_QUADSPI, + .gpio_af_d3 = GPIO_AF10_QUADSPI, + .gpio_af_clk = GPIO_AF9_QUADSPI, + .gpio_af_cs = GPIO_AF9_QUADSPI, + } +}; + +//platform_qspi_driver_t platform_qspi_drivers[MICO_QSPI_MAX]; + +/* Flash memory devices */ +const platform_flash_t platform_flash_peripherals[] = +{ + [HAL_FLASH_EMBEDDED] = + { + .flash_type = FLASH_TYPE_EMBEDDED, + .flash_start_addr = 0x08000000, + .flash_length = 0x100000, + }, + [HAL_FLASH_QSPI] = + { + .flash_type = FLASH_TYPE_QSPI, + .flash_start_addr = 0x000000, + .flash_length = 0x200000, + }, +}; + +platform_flash_driver_t platform_flash_drivers[HAL_FLASH_MAX]; + + +#if defined ( USE_MICO_SPI_FLASH ) +const mico_spi_device_t mico_spi_flash = +{ + .port = MICO_SPI_1, + .chip_select = FLASH_PIN_SPI_CS, + .speed = 40000000, + .mode = (SPI_CLOCK_RISING_EDGE | SPI_CLOCK_IDLE_HIGH | SPI_USE_DMA | SPI_MSB_FIRST ), + .bits = 8 +}; +#endif + +const platform_adc_t platform_adc_peripherals[] = +{ + [MICO_ADC_1] = { ADC1, ADC_Channel_4, RCC_APB2Periph_ADC1, 1, (platform_gpio_t*)&platform_gpio_pins[MICO_GPIO_38] }, + [MICO_ADC_2] = { ADC1, ADC_Channel_5, RCC_APB2Periph_ADC1, 1, (platform_gpio_t*)&platform_gpio_pins[MICO_GPIO_34] }, +}; + +/* Wi-Fi control pins. Used by platform/MCU/wlan_platform_common.c +* SDIO: EMW1062_PIN_BOOTSTRAP[1:0] = b'00 +* gSPI: EMW1062_PIN_BOOTSTRAP[1:0] = b'01 +*/ +const platform_gpio_t wifi_control_pins[] = +{ + [WIFI_PIN_POWER ] = { GPIOA, 9 }, + [WIFI_PIN_BOOTSTRAP_1] = { GPIOC, 10 }, + [WIFI_PIN_RESET] = { GPIOA, 9 }, + [WIFI_PIN_32K_CLK] = { GPIOA, 8 }, +}; + +/* Wi-Fi SDIO bus pins. Used by platform/MCU/STM32F2xx/EMW1062_driver/wlan_SDIO.c */ +const platform_gpio_t wifi_sdio_pins[] = +{ + [WIFI_PIN_SDIO_OOB_IRQ] = { GPIOC, 0 }, + [WIFI_PIN_SDIO_CLK ] = { GPIOC, 12 }, + [WIFI_PIN_SDIO_CMD ] = { GPIOD, 2 }, + [WIFI_PIN_SDIO_D0 ] = { GPIOC, 8 }, + [WIFI_PIN_SDIO_D1 ] = { GPIOC, 9 }, + [WIFI_PIN_SDIO_D2 ] = { GPIOC, 10 }, + [WIFI_PIN_SDIO_D3 ] = { GPIOB, 5 }, +}; + + +/* Bluetooth control pins.*/ +static const platform_gpio_t internal_bt_control_pins[] = +{ + /* Reset pin unavailable */ + [MICO_BT_PIN_POWER ] = { GPIOC, 3 }, + [MICO_BT_PIN_HOST_WAKE ] = { GPIOC, 2 }, + [MICO_BT_PIN_DEVICE_WAKE] = { GPIOC, 1 } +}; + +const platform_gpio_t* mico_bt_control_pins[] = +{ + /* Reset pin unavailable */ + [MICO_BT_PIN_POWER ] = &internal_bt_control_pins[MICO_BT_PIN_POWER ], + [MICO_BT_PIN_HOST_WAKE ] = &internal_bt_control_pins[MICO_BT_PIN_HOST_WAKE ], + [MICO_BT_PIN_DEVICE_WAKE] = &internal_bt_control_pins[MICO_BT_PIN_DEVICE_WAKE], + [MICO_BT_PIN_RESET ] = NULL, +}; + +/* Bluetooth UART pins.*/ +static const platform_gpio_t internal_bt_uart_pins[] = +{ + [MICO_BT_PIN_UART_TX ] = { GPIOA, 2 }, + [MICO_BT_PIN_UART_RX ] = { GPIOA, 3 }, + [MICO_BT_PIN_UART_CTS] = { GPIOA, 0 }, + [MICO_BT_PIN_UART_RTS] = { GPIOA, 1 }, +}; + +const platform_gpio_t* mico_bt_uart_pins[] = +{ + [MICO_BT_PIN_UART_TX ] = &internal_bt_uart_pins[MICO_BT_PIN_UART_TX ], + [MICO_BT_PIN_UART_RX ] = &internal_bt_uart_pins[MICO_BT_PIN_UART_RX ], + [MICO_BT_PIN_UART_CTS] = &internal_bt_uart_pins[MICO_BT_PIN_UART_CTS], + [MICO_BT_PIN_UART_RTS] = &internal_bt_uart_pins[MICO_BT_PIN_UART_RTS], +}; + +static const platform_uart_t internal_bt_uart_peripheral = +{ + .port = USART2, + .pin_tx = &internal_bt_uart_pins[MICO_BT_PIN_UART_TX ], + .pin_rx = &internal_bt_uart_pins[MICO_BT_PIN_UART_RX ], + .pin_cts = &internal_bt_uart_pins[MICO_BT_PIN_UART_CTS ], + .pin_rts = &internal_bt_uart_pins[MICO_BT_PIN_UART_RTS ], + .tx_dma_config = + { + .controller = DMA1, + .stream = DMA1_Stream6, + .channel = DMA_Channel_4, + .irq_vector = DMA1_Stream6_IRQn, + .complete_flags = DMA_HISR_TCIF6, + .error_flags = ( DMA_HISR_TEIF6 | DMA_HISR_FEIF6 ), + }, + .rx_dma_config = + { + .controller = DMA1, + .stream = DMA1_Stream5, + .channel = DMA_Channel_4, + .irq_vector = DMA1_Stream5_IRQn, + .complete_flags = DMA_HISR_TCIF5, + .error_flags = ( DMA_HISR_TEIF5 | DMA_HISR_FEIF5 | DMA_HISR_DMEIF5 ), + }, +}; + +static platform_uart_driver_t internal_bt_uart_driver; +const platform_uart_t* mico_bt_uart_peripheral = &internal_bt_uart_peripheral; +platform_uart_driver_t* mico_bt_uart_driver = &internal_bt_uart_driver; + + +/* Bluetooth UART configuration. Used by libraries/bluetooth/internal/bus/UART/bt_bus.c */ +const platform_uart_config_t mico_bt_uart_config = +{ + .baud_rate = 115200, + .data_width = DATA_WIDTH_8BIT, + .parity = NO_PARITY, + .stop_bits = STOP_BITS_1, + .flow_control = FLOW_CONTROL_CTS_RTS, //FLOW_CONTROL_DISABLED, +}; + +/*BT chip specific configuration information*/ +const platform_bluetooth_config_t mico_bt_config = +{ + .patchram_download_mode = PATCHRAM_DOWNLOAD_MODE_MINIDRV_CMD, + .patchram_download_baud_rate = 115200, + .featured_baud_rate = 3000000 +}; + +/****************************************************** +* Interrupt Handler Definitions +******************************************************/ + +MICO_RTOS_DEFINE_ISR( USART1_IRQHandler ) +{ + platform_uart_irq( &platform_uart_drivers[MICO_UART_2] ); +} + +MICO_RTOS_DEFINE_ISR( USART6_IRQHandler ) +{ + platform_uart_irq( &platform_uart_drivers[MICO_UART_1] ); +} + +MICO_RTOS_DEFINE_ISR( USART2_IRQHandler ) +{ + platform_uart_irq( mico_bt_uart_driver ); +} + +MICO_RTOS_DEFINE_ISR( DMA2_Stream6_IRQHandler ) +{ + platform_uart_tx_dma_irq( &platform_uart_drivers[MICO_UART_1] ); +} + +MICO_RTOS_DEFINE_ISR( DMA2_Stream7_IRQHandler ) +{ + platform_uart_tx_dma_irq( &platform_uart_drivers[MICO_UART_2] ); +} + +MICO_RTOS_DEFINE_ISR( DMA2_Stream1_IRQHandler ) +{ + platform_uart_rx_dma_irq( &platform_uart_drivers[MICO_UART_1] ); +} + +MICO_RTOS_DEFINE_ISR( DMA2_Stream2_IRQHandler ) +{ + platform_uart_rx_dma_irq( &platform_uart_drivers[MICO_UART_2] ); +} + +MICO_RTOS_DEFINE_ISR( DMA1_Stream6_IRQHandler ) +{ + platform_uart_tx_dma_irq( mico_bt_uart_driver ); +} + +MICO_RTOS_DEFINE_ISR( DMA1_Stream5_IRQHandler ) +{ + platform_uart_rx_dma_irq( mico_bt_uart_driver ); +} + + +/****************************************************** +* Function Definitions +******************************************************/ + +void platform_init_peripheral_irq_priorities( void ) +{ + /* Interrupt priority setup. Called by MiCO/platform/MCU/STM32F4xx/platform_init.c */ + NVIC_SetPriority( RTC_WKUP_IRQn , 1 ); /* RTC Wake-up event */ + NVIC_SetPriority( SDIO_IRQn , 2 ); /* WLAN SDIO */ + NVIC_SetPriority( DMA2_Stream3_IRQn, 3 ); /* WLAN SDIO DMA */ + NVIC_SetPriority( USART6_IRQn , 6 ); /* MICO_UART_1 */ + NVIC_SetPriority( DMA2_Stream6_IRQn, 7 ); /* MICO_UART_1 TX DMA */ + NVIC_SetPriority( DMA2_Stream1_IRQn, 7 ); /* MICO_UART_1 RX DMA */ + NVIC_SetPriority( USART2_IRQn , 6 ); /* BT UART */ + NVIC_SetPriority( DMA1_Stream5_IRQn, 7 ); /* BT UART RX DMA */ + NVIC_SetPriority( DMA1_Stream6_IRQn, 7 ); /* BT UART TX DMA */ + NVIC_SetPriority( EXTI0_IRQn , 14 ); /* GPIO */ + NVIC_SetPriority( EXTI1_IRQn , 14 ); /* GPIO */ + NVIC_SetPriority( EXTI2_IRQn , 14 ); /* GPIO */ + NVIC_SetPriority( EXTI3_IRQn , 14 ); /* GPIO */ + NVIC_SetPriority( EXTI4_IRQn , 14 ); /* GPIO */ + NVIC_SetPriority( EXTI9_5_IRQn , 14 ); /* GPIO */ + NVIC_SetPriority( EXTI15_10_IRQn , 14 ); /* GPIO */ +} + +void init_platform( void ) +{ + +} + diff --git a/board/mk3239/board.h b/board/mk3239/board.h new file mode 100644 index 0000000000..6f6926a6d4 --- /dev/null +++ b/board/mk3239/board.h @@ -0,0 +1,365 @@ +#pragma once + +#define MANUFACTURER "MXCHIP Inc." +#define HARDWARE_REVISION "V1.0" +#define MODEL "STM32F412" +#define DEFAULT_NAME "MiCOKit 3166" + +#ifdef BOOTLOADER +#define STDIO_UART_BUADRATE 115200 +#else +#define STDIO_UART_BUADRATE 115200 +#endif + +#define HSE_SOURCE RCC_HSE_ON /* Use external crystal */ +#define AHB_CLOCK_DIVIDER RCC_SYSCLK_Div1 /* AHB clock = System clock */ +#define APB1_CLOCK_DIVIDER RCC_HCLK_Div2 /* APB1 clock = AHB clock / 2 */ +#define APB2_CLOCK_DIVIDER RCC_HCLK_Div1 /* APB2 clock = AHB clock / 1 */ +#define PLL_SOURCE RCC_PLLSource_HSE /* PLL source = external crystal */ +#define PLL_M_CONSTANT 13 /* PLLM = 16 */ +#define PLL_N_CONSTANT 192 /* PLLN = 400 */ +#define PLL_P_CONSTANT 4 /* PLLP = 4 */ +#define PPL_Q_CONSTANT 8 /* PLLQ = 8 */ +#define PPL_R_CONSTANT 2 /* PLLR = 2 */ +#define SYSTEM_CLOCK_SOURCE RCC_SYSCLKSource_PLLCLK /* System clock source = PLL clock */ +#define SYSTICK_CLOCK_SOURCE SysTick_CLKSource_HCLK /* SysTick clock source = AHB clock */ +#define INT_FLASH_WAIT_STATE FLASH_Latency_3 /* Internal flash wait state = 3 cycles */ +#define PWR_WakeUp_Pin PWR_WakeUp_Pin2 /* PWR_Wake_Up_Pin */ + +/* Wi-Fi chip module */ +#define EMW1062 + +/* GPIO pins are used to bootstrap Wi-Fi to SDIO or gSPI mode */ +//#define MICO_WIFI_USE_GPIO_FOR_BOOTSTRAP_0 +//#define MICO_WIFI_USE_GPIO_FOR_BOOTSTRAP_1 + +/* Wi-Fi GPIO0 pin is used for out-of-band interrupt */ +#define MICO_WIFI_OOB_IRQ_GPIO_PIN ( 0 ) + +/* Wi-Fi power pin is present */ +#define MICO_USE_WIFI_POWER_PIN + +/* Wi-Fi reset pin is present */ +//#define MICO_USE_WIFI_RESET_PIN + +/* Wi-Fi 32K pin is present */ +#define MICO_USE_WIFI_32K_PIN + +/* Wi-Fi power pin is active high */ +#define MICO_USE_WIFI_POWER_PIN_ACTIVE_HIGH + +#define MICO_WIFI_USE_GPIO_FOR_BOOTSTRAP_1 +#define MICO_WIFI_USE_GPIO_FOR_BOOTSTRAP_1_HIGH_FOR_SDIO + +/* +EMW3166 on EMB-3166-A platform pin definitions ... ++-------------------------------------------------------------------------+ +| Enum ID |Pin | STM32| Peripheral | Board | Peripheral | +| | # | Port | Available | Connection | Alias | +|---------------+----+------+-------------+--------------+----------------| +| | 1 | NC | | | | +|---------------+----+------+-------------+--------------+----------------| +| MICO_GPIO_2 | 2 | B 2 | GPIO | | | +|---------------+----+------+-------------+--------------+----------------| +| | 3 | NC | | | | +|---------------+----+------+-------------+--------------+----------------| +| MICO_GPIO_4 | 4 | B 15 | TIM1_CH3N | | | +| | | | TIM8_CH3N | | | +| | | | SPI2_MOSI | | | +| | | | SDIO_CK | | | +|---------------+----+------+-------------+--------------+----------------| +| MICO_GPIO_5 | 5 | B 12 | SPI2_NSS | | | +| | | | SPI4_NSS | | | +|---------------+----+------+-------------+--------------+----------------| +| MICO_GPIO_6 | 6 | B 13 | TIM1_CH1N | | | +| | | | GPIO | | | +| | | | SPI2_SCK | | | +|---------------+----+------+-------------+--------------+----------------| +| MICO_GPIO_7 | 7 | B 14 | GPIO | | | +| | | | SDIO_D6 | | | +| | | | TIM1_CH2N | | | +| | | | SPI2_MISO | | | +|---------------+----+------+-------------+--------------+----------------| +| MICO_GPIO_8 | 8 | C 6 | TIM3_CH1 | STDIO_UART_TX| MICO_UART_1_TX | +| | | | TIM8_CH1 | | | +| | | | USART6_TX | | | +| | | | GPIO | | | +|---------------+----+------+-------------+--------------+----------------| +| MICO_GPIO_9 | 9 | A 15 | TIM2_CH1 |EasyLink_BUTTON| | +| | | | JTDI | | | +| | | | USART1_TX | | | +| | | | GPIO | | | +|---------------+----+------+-------------+--------------+----------------| +| | 10 | VBAT | | +|---------------+----+------+-------------+--------------+----------------| +| | 11 | NC | | | | +|---------------+----+------+-------------+--------------+----------------| +| MICO_GPIO_12 | 12 | C 7 | TIM3_CH2 | STDIO_UART_RX| MICO_UART_1_RX | +| | | | TIM8_CH2 | | | +| | | | SPI2_SCK | | | +| | | | SDIO_D7 | | | +| | | | USART6_RX | | | +| | | | GPIO | | | +|---------------+----+------+-------------+--------------+----------------| +| | 13 | NRST | | | MICRO_RST_N | +|---------------+----+------+-------------+--------------+----------------| +| MICO_GPIO_14 | 14 | C 0 | WAKE_UP | | | +|---------------+----+------+-------------+--------------+----------------| +| | 15 | NC | | | | +|---------------+----+------+-------------+--------------+----------------| +| MICO_GPIO_16 | 16 | C 13 | - | | | +|---------------+----+------+-------------+--------------+----------------| +| MICO_SYS_LED | 17 | B 8 | TIM4_CH3 | | | +| | | | I2C2_SCL | | | +| | | | GPIO | | | +|---------------+----+------+-------------+--------------+----------------| +| MICO_GPIO_18 | 18 | B 9 | TIM4_CH3 | | | +| | | | TIM10_CH1 | | | +| | | | I2C1_SCL | | | +| | | | SDIO_D4 | | | +| | | | GPIO | | | ++---------------+----+--------------------+--------------+----------------+ +| MICO_GPIO_19 | 19 | B 10 | GPIO | | | ++---------------+----+--------------------+--------------+----------------+ +| | 20 | GND | | | | ++---------------+----+--------------------+--------------+----------------+ +| | 21 | GND | | | | ++---------------+----+--------------------+--------------+----------------+ +| MICO_GPIO_22 | 22 | B 3 | | | | ++---------------+----+--------------------+--------------+----------------+ +| MICO_GPIO_23 | 23 | A 15 | GPIO | | JTAG_TDI | +| | | | USART1_TX | | SPI1_SSN | +| | | | TIM2_CH1 | | | +| | | | TIM2_ETR | | | ++---------------+----+--------------------+--------------+----------------+ +| MICO_GPIO_24 | 24 | B 4 | | | | ++---------------+----+--------------------+--------------+----------------+ +| MICO_GPIO_25 | 25 | A 14 | JTCK-SWCLK | SWCLK | | +| | | | GPIO | | | ++---------------+----+--------------------+--------------+----------------+ +|MICO_GPIO_26 | 26 | A 13 | JTMS-SWDIO | SWDIO | | +| | | | GPIO | | | ++---------------+----+--------------------+--------------+----------------+ +|MICO_GPIO_27 | 27 | B 3 | TIM1_ETR | | | +| | | | USART1_RX | | | +| | | | GPIO | | | ++---------------+----+--------------------+--------------+----------------+ +| | 28 | NC | | | | ++---------------+----+--------------------+--------------+----------------+ +| MICO_GPIO_29 | 29 | B 7 | GPIO | | MICO_UART_2_RX | +| | | | TIM4_CH2 | | | +| | | | USART1_RX | | | +| | | | I2C1_SDA | | | ++---------------+----+--------------------+--------------+----------------+ +| MICO_GPIO_30 | 30 | B 6 | GPIO | | MICO_UART_2_TX | +| | | | TIM4_CH1 | | | +| | | | USART1_TX | | | +| | | | I2C1_SCL | | | ++---------------+----+--------------------+--------------+----------------+ +| MICO_GPIO_31 | 31 | B 4 | GPIO | MICO_RF_LED | | +| | | | TIM3_CH1 | | | +| | | | SDIO_D0 | | | ++---------------+----+--------------------+--------------+----------------+ +| | 32 | NC | | | | ++---------------+----+--------------------+--------------+----------------+ +| MICO_GPIO_33 | 33 | A 10 | TIM1_CH3 | MICO_SYS_LED | | +| | | | SPI5_MOSI | | | +| | | | USB_FS_ID | | | +| | | | GPIO | | | ++---------------+----+--------------------+--------------+----------------+ +| MICO_GPIO_34 | 34 | A 12 | TIM1_ETR | | | +| | | | USART1_RTS | | | +| | | | USB_FS_DP | | | +| | | | GPIO | | | ++---------------+----+--------------------+--------------+----------------+ +| MICO_GPIO_35 | 35 | A 11 | TIM1_CH4 | | | +| | | | SPI4_MISO | | | +| | | | USART1_CTS | | | +| | | | USART6_TX | | | +| | | | USB_FS_DM | | | +| | | | GPIO | | | ++---------------+----+--------------------+--------------+----------------+ +| MICO_GPIO_36 | 36 | A 5 | TIM2_CH1 | BOOT_SEL | | +| | | | TIM2_ETR | | | +| | | | TIM8_CH1N | | | +| | | | SPI1_SCK | | | +| | | | GPIO | | | ++---------------+----+--------------------+--------------+----------------+ +| MICO_GPIO_37 | 37 | B 0 | TIM1_CH2N | MFG_SEL | | +| | | | TIM3_CH3 | | | +| | | | TIM8_CH2N | | | +| | | | GPIO | | | ++---------------+----+--------------------+--------------+----------------+ +| MICO_GPIO_38 | 38 | A 4 | USART2_CK | | | +| | | | GPIO | | | ++---------------+----+--------------------+--------------+----------------+ +| | 39 | VDD | | | | ++---------------+----+--------------------+--------------+----------------+ +| | 40 | VDD | | | | ++---------------+----+--------------------+--------------+----------------+ +| | 41 | ANT | | | | ++---------------+----+--------------------+--------------+----------------+ +*/ + +typedef enum +{ + FLASH_PIN_QSPI_CS, + FLASH_PIN_QSPI_CLK, + FLASH_PIN_QSPI_D0, + FLASH_PIN_QSPI_D1, + FLASH_PIN_QSPI_D2, + FLASH_PIN_QSPI_D3, + + MICO_GPIO_2, + MICO_GPIO_4, + MICO_GPIO_5, + MICO_GPIO_6, + MICO_GPIO_7, + MICO_GPIO_8, + MICO_GPIO_9, + MICO_GPIO_12, + MICO_GPIO_14, + MICO_GPIO_16, + MICO_GPIO_17, + MICO_GPIO_18, + MICO_GPIO_19, + MICO_GPIO_27, + MICO_GPIO_29, + MICO_GPIO_30, + MICO_GPIO_31, + MICO_GPIO_33, + MICO_GPIO_34, + MICO_GPIO_35, + MICO_GPIO_36, + MICO_GPIO_37, + MICO_GPIO_38, + MICO_GPIO_MAX, /* Denotes the total number of GPIO port aliases. Not a valid GPIO alias */ + MICO_GPIO_NONE, +} mico_gpio_t; + +typedef enum +{ + MICO_SPI_1, + MICO_SPI_MAX, /* Denotes the total number of SPI port aliases. Not a valid SPI alias */ + MICO_SPI_NONE, +} mico_spi_t; + +typedef enum +{ + MICO_QSPI_1, + MICO_QSPI_MAX,/* Denotes the total number of QSPI port aliases. Not a valid QSPI alias */ + MICO_QSPI_NONE, +}mico_qspi_t; + +typedef enum +{ + MICO_I2C_1, + MICO_I2C_MAX, /* Denotes the total number of I2C port aliases. Not a valid I2C alias */ + MICO_I2C_NONE, +} mico_i2c_t; + +typedef enum +{ + MICO_IIS_MAX, /* Denotes the total number of IIS port aliases. Not a valid IIS alias */ + MICO_IIS_NONE, +} mico_iis_t; + +typedef enum +{ + MICO_PWM_MAX, /* Denotes the total number of PWM port aliases. Not a valid PWM alias */ + MICO_PWM_NONE, +} mico_pwm_t; + +typedef enum +{ + MICO_ADC_1, + MICO_ADC_2, + MICO_ADC_MAX, /* Denotes the total number of ADC port aliases. Not a valid ADC alias */ + MICO_ADC_NONE, +} mico_adc_t; + +typedef enum +{ + MICO_UART_1, + MICO_UART_2, + MICO_UART_MAX, /* Denotes the total number of UART port aliases. Not a valid UART alias */ + MICO_UART_NONE, +} mico_uart_t; + +typedef hal_flash_t mico_flash_t; + +typedef enum +{ + MICO_PARTITION_FILESYS, + MICO_PARTITION_USER_MAX +} mico_user_partition_t; + +#ifdef BOOTLOADER +#define STDIO_UART (MICO_UART_2) +#define STDIO_UART_BAUDRATE (921600) +#else +#define STDIO_UART (MICO_UART_1) +#define STDIO_UART_BAUDRATE (115200) +#endif + +#define UART_FOR_APP (MICO_UART_2) +#define MFG_TEST (MICO_UART_2) +#define CLI_UART (MICO_UART_1) + +/* Components connected to external I/Os*/ +//#define USE_MICO_SPI_FLASH +//#define SFLASH_SUPPORT_MACRONIX_PARTS +//#define SFLASH_SUPPORT_SST_PARTS +//#define SFLASH_SUPPORT_WINBOND_PARTS + +#define USE_QUAD_SPI_FLASH +//#define USE_QUAD_SPI_DMA + +#define BOOT_SEL (MICO_GPIO_36) +#define MFG_SEL (MICO_GPIO_37) +#define EasyLink_BUTTON (MICO_GPIO_9) +#define MICO_SYS_LED (MICO_GPIO_33) +#define MICO_RF_LED (MICO_GPIO_31) + +/* Arduino extention connector */ +#define Arduino_RXD (MICO_GPIO_29) +#define Arduino_TXD (MICO_GPIO_30) +#define Arduino_D2 (MICO_GPIO_NONE) +#define Arduino_D3 (MICO_GPIO_NONE) +#define Arduino_D4 (MICO_GPIO_19) +#define Arduino_D5 (MICO_GPIO_16) +#define Arduino_D6 (MICO_GPIO_14) +#define Arduino_D7 (MICO_GPIO_NONE) + + +#define Arduino_D8 (MICO_GPIO_2) +#define Arduino_D9 (MICO_GPIO_27) +#define Arduino_CS (MICO_GPIO_5) +#define Arduino_SI (MICO_GPIO_4) +#define Arduino_SO (MICO_GPIO_7) +#define Arduino_SCK (MICO_GPIO_6) +#define Arduino_SDA (MICO_GPIO_18) +#define Arduino_SCL (MICO_GPIO_17) + +#define Arduino_A0 (MICO_ADC_NONE) +#define Arduino_A1 (MICO_ADC_NONE) +#define Arduino_A2 (MICO_ADC_1) +#define Arduino_A3 (MICO_ADC_2) +#define Arduino_A4 (MICO_ADC_NONE) +#define Arduino_A5 (MICO_ADC_NONE) + +#define Arduino_I2C (MICO_I2C_1) +#define Arduino_SPI (MICO_SPI_1) +#define Arduino_UART (MICO_UART_2) + +#ifdef USE_MiCOKit_EXT +#define MICO_I2C_CP (Arduino_I2C) +#include "micokit_ext_def.h" +#else +#define MICO_I2C_CP (MICO_I2C_NONE) +#endif //USE_MiCOKit_EXT + +#define MICO_BLUETOOTH_ENABLE + + + diff --git a/board/mk3239/flash_prog.elf b/board/mk3239/flash_prog.elf new file mode 100644 index 0000000000..0155ee1fd0 Binary files /dev/null and b/board/mk3239/flash_prog.elf differ diff --git a/board/mk3239/k_config.h b/board/mk3239/k_config.h new file mode 100644 index 0000000000..f1c8cc977f --- /dev/null +++ b/board/mk3239/k_config.h @@ -0,0 +1,225 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#ifndef CONFIG_H +#define CONFIG_H + +/* chip level conf */ +#ifndef RHINO_CONFIG_LITTLE_ENDIAN +#define RHINO_CONFIG_LITTLE_ENDIAN 1 +#endif +#ifndef RHINO_CONFIG_CPU_STACK_DOWN +#define RHINO_CONFIG_CPU_STACK_DOWN 1 +#endif + +/* kernel feature conf */ +#ifndef RHINO_CONFIG_SEM +#define RHINO_CONFIG_SEM 1 +#endif +#ifndef RHINO_CONFIG_QUEUE +#define RHINO_CONFIG_QUEUE 1 +#endif +#ifndef RHINO_CONFIG_TASK_SEM +#define RHINO_CONFIG_TASK_SEM 1 +#endif +#ifndef RHINO_CONFIG_EVENT_FLAG +#define RHINO_CONFIG_EVENT_FLAG 1 +#endif +#ifndef RHINO_CONFIG_TIMER +#define RHINO_CONFIG_TIMER 1 +#endif +#ifndef RHINO_CONFIG_BUF_QUEUE +#define RHINO_CONFIG_BUF_QUEUE 1 +#endif +#ifndef RHINO_CONFIG_MM_BLK +#define RHINO_CONFIG_MM_BLK 1 +#endif +#ifndef RHINO_CONFIG_MM_DEBUG +#define RHINO_CONFIG_MM_DEBUG 1 +#endif +#ifndef RHINO_CONFIG_MM_TLF +#define RHINO_CONFIG_MM_TLF 1 +#endif +#ifndef RHINO_CONFIG_MM_TLF_BLK_SIZE +#define RHINO_CONFIG_MM_TLF_BLK_SIZE 8192 +#endif +#define K_MM_STATISTIC 1 +#ifndef RHINO_CONFIG_MM_MAXMSIZEBIT +#define RHINO_CONFIG_MM_MAXMSIZEBIT 19 +#endif +#ifndef RHINO_CONFIG_GCC_RETADDR +#define RHINO_CONFIG_GCC_RETADDR 1 +#endif +#ifndef RHINO_CONFIG_MM_LEAKCHECK +#define RHINO_CONFIG_MM_LEAKCHECK 1 +#endif +#ifndef RHINO_CONFIG_RINGBUF_VENDOR +#define RHINO_CONFIG_RINGBUF_VENDOR 0 +#endif + +#ifndef RHINO_CONFIG_KOBJ_SET +#define RHINO_CONFIG_KOBJ_SET 1 +#endif + +/* kernel task conf */ +#ifndef RHINO_CONFIG_TASK_SUSPEND +#define RHINO_CONFIG_TASK_SUSPEND 1 +#endif +#ifndef RHINO_CONFIG_TASK_INFO +#define RHINO_CONFIG_TASK_INFO 1 +#endif +#ifndef RHINO_CONFIG_TASK_DEL +#define RHINO_CONFIG_TASK_DEL 1 +#endif + +#ifndef RHINO_CONFIG_TASK_STACK_CUR_CHECK +#define RHINO_CONFIG_TASK_STACK_CUR_CHECK 1 +#endif + +#ifndef RHINO_CONFIG_TASK_WAIT_ABORT +#define RHINO_CONFIG_TASK_WAIT_ABORT 1 +#endif +#ifndef RHINO_CONFIG_TASK_STACK_OVF_CHECK +#define RHINO_CONFIG_TASK_STACK_OVF_CHECK 1 +#endif +#ifndef RHINO_CONFIG_SCHED_RR +#define RHINO_CONFIG_SCHED_RR 1 +#endif +#ifndef RHINO_CONFIG_TIME_SLICE_DEFAULT +#define RHINO_CONFIG_TIME_SLICE_DEFAULT 50 +#endif +#ifndef RHINO_CONFIG_PRI_MAX +#define RHINO_CONFIG_PRI_MAX 62 +#endif +#ifndef RHINO_CONFIG_USER_PRI_MAX +#define RHINO_CONFIG_USER_PRI_MAX (RHINO_CONFIG_PRI_MAX - 2) +#endif + +/* kernel workqueue conf */ +//#ifndef RHINO_CONFIG_WORKQUEUE +#define RHINO_CONFIG_WORKQUEUE 1 +//#endif +#ifndef RHINO_CONFIG_WORKQUEUE_STACK_SIZE +#define RHINO_CONFIG_WORKQUEUE_STACK_SIZE 768 +#endif + +/* kernel mm_region conf */ +#ifndef RHINO_CONFIG_MM_REGION_MUTEX +#define RHINO_CONFIG_MM_REGION_MUTEX 0 +#endif + +/* kernel timer&tick conf */ +#ifndef RHINO_CONFIG_HW_COUNT +#define RHINO_CONFIG_HW_COUNT 0 +#endif +#ifndef RHINO_CONFIG_TICK_TASK +#define RHINO_CONFIG_TICK_TASK 0 +#endif + +#if (RHINO_CONFIG_TICK_TASK > 0) +#ifndef RHINO_CONFIG_TICK_TASK_STACK_SIZE +#define RHINO_CONFIG_TICK_TASK_STACK_SIZE 256 +#endif +#ifndef RHINO_CONFIG_TICK_TASK_PRI +#define RHINO_CONFIG_TICK_TASK_PRI 1 +#endif +#endif + +#ifndef RHINO_CONFIG_TICKLESS +#define RHINO_CONFIG_TICKLESS 0 +#endif +#ifndef RHINO_CONFIG_TICKS_PER_SECOND +#define RHINO_CONFIG_TICKS_PER_SECOND 100 +#endif +/* must be 2^n size!, such as 1, 2, 4, 8, 16,32, etc....... */ +#ifndef RHINO_CONFIG_TICK_HEAD_ARRAY +#define RHINO_CONFIG_TICK_HEAD_ARRAY 8 +#endif + +/*must reserve enough stack size for timer cb will consume*/ +#ifndef RHINO_CONFIG_TIMER_TASK_STACK_SIZE +#define RHINO_CONFIG_TIMER_TASK_STACK_SIZE 300 +#endif +#ifndef RHINO_CONFIG_TIMER_RATE +#define RHINO_CONFIG_TIMER_RATE 1 +#endif +#ifndef RHINO_CONFIG_TIMER_TASK_PRI +#define RHINO_CONFIG_TIMER_TASK_PRI 5 +#endif + +/* kernel intrpt conf */ +#ifndef RHINO_CONFIG_INTRPT_STACK_REMAIN_GET +#define RHINO_CONFIG_INTRPT_STACK_REMAIN_GET 0 +#endif +#ifndef RHINO_CONFIG_INTRPT_STACK_OVF_CHECK +#define RHINO_CONFIG_INTRPT_STACK_OVF_CHECK 0 +#endif +#ifndef RHINO_CONFIG_INTRPT_MAX_NESTED_LEVEL +#define RHINO_CONFIG_INTRPT_MAX_NESTED_LEVEL 188u +#endif +#ifndef RHINO_CONFIG_INTRPT_GUARD +#define RHINO_CONFIG_INTRPT_GUARD 0 +#endif + +/* kernel dyn alloc conf */ +#ifndef RHINO_CONFIG_KOBJ_DYN_ALLOC +#define RHINO_CONFIG_KOBJ_DYN_ALLOC 1 +#endif + +#if (RHINO_CONFIG_KOBJ_DYN_ALLOC > 0) +#ifndef RHINO_CONFIG_K_DYN_QUEUE_MSG +#define RHINO_CONFIG_K_DYN_QUEUE_MSG 30 +#endif +#ifndef RHINO_CONFIG_K_DYN_TASK_STACK +#define RHINO_CONFIG_K_DYN_TASK_STACK 256 +#endif +#ifndef RHINO_CONFIG_K_DYN_MEM_TASK_PRI +#define RHINO_CONFIG_K_DYN_MEM_TASK_PRI 6 +#endif +#endif + +/* kernel idle conf */ +#ifndef RHINO_CONFIG_IDLE_TASK_STACK_SIZE +#define RHINO_CONFIG_IDLE_TASK_STACK_SIZE 200 +#endif + +/* kernel hook conf */ +#ifndef RHINO_CONFIG_USER_HOOK +#define RHINO_CONFIG_USER_HOOK 0 +#endif + +/* kernel stats conf */ +#ifndef RHINO_CONFIG_SYSTEM_STATS +#define RHINO_CONFIG_SYSTEM_STATS 1 +#endif +#ifndef RHINO_CONFIG_DISABLE_SCHED_STATS +#define RHINO_CONFIG_DISABLE_SCHED_STATS 0 +#endif +#ifndef RHINO_CONFIG_DISABLE_INTRPT_STATS +#define RHINO_CONFIG_DISABLE_INTRPT_STATS 0 +#endif +#ifndef RHINO_CONFIG_CPU_USAGE_STATS +#define RHINO_CONFIG_CPU_USAGE_STATS 0 +#endif +#ifndef RHINO_CONFIG_CPU_USAGE_TASK_PRI +#define RHINO_CONFIG_CPU_USAGE_TASK_PRI (RHINO_CONFIG_PRI_MAX - 2) +#endif +#ifndef RHINO_CONFIG_TASK_SCHED_STATS +#define RHINO_CONFIG_TASK_SCHED_STATS 0 +#endif +#ifndef RHINO_CONFIG_CPU_USAGE_TASK_STACK +#define RHINO_CONFIG_CPU_USAGE_TASK_STACK 256 +#endif + +#ifndef RHINO_CONFIG_CPU_NUM +#define RHINO_CONFIG_CPU_NUM 1 +#endif + +/* kernel trace conf */ +#ifndef RHINO_CONFIG_TRACE +#define RHINO_CONFIG_TRACE 0 +#endif + +#endif /* CONFIG_H */ + diff --git a/board/mk3239/memory.ld b/board/mk3239/memory.ld new file mode 100644 index 0000000000..9c80ccf753 --- /dev/null +++ b/board/mk3239/memory.ld @@ -0,0 +1,8 @@ + +MEMORY +{ + BL_FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 32K + APP_FLASH (rx) : ORIGIN = 0x08008000, LENGTH = 1000K + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 256K + ERAM (rwx) : ORIGIN = 0, LENGTH = 0 +} diff --git a/board/mk3239/mk3239.mk b/board/mk3239/mk3239.mk new file mode 100644 index 0000000000..b5adb3ec35 --- /dev/null +++ b/board/mk3239/mk3239.mk @@ -0,0 +1,50 @@ +NAME := board_mk3239 + +JTAG := jlink_swd + +$(NAME)_TYPE := kernel +MODULE := 3239 +HOST_ARCH := Cortex-M4 +HOST_MCU_FAMILY := stm32f4xx +HOST_MCU_VARIANT := STM32F412 +SUPPORT_BINS := no + +WLAN_CHIP := 43438 +WLAN_CHIP_REVISION := A1 +WLAN_CHIP_FAMILY := 4343x +WLAN_CHIP_FIRMWARE_VER := 7.45.98.38 + +BT_CHIP := 43438 +BT_CHIP_REVISION := A1 +BT_CHIP_XTAL_FREQUENCY := 26MHz + +BUS := SDIO + +$(NAME)_SOURCES := board.c wifi_nvram.c + +GLOBAL_INCLUDES += ./ +GLOBAL_DEFINES += HSE_VALUE=26000000 + +GLOBAL_DEFINES += STDIO_UART=0 CONFIG_NO_TCPIP +GLOBAL_DEFINES += RHINO_CONFIG_TICK_TASK=0 RHINO_CONFIG_WORKQUEUE=0 + +CONFIG_SYSINFO_PRODUCT_MODEL := ALI_AOS_MK3239 +CONFIG_SYSINFO_DEVICE_NAME := MK3239 + +GLOBAL_CFLAGS += -DSYSINFO_OS_VERSION=\"$(CONFIG_SYSINFO_OS_VERSION)\" +GLOBAL_CFLAGS += -DSYSINFO_PRODUCT_MODEL=\"$(CONFIG_SYSINFO_PRODUCT_MODEL)\" +GLOBAL_CFLAGS += -DSYSINFO_DEVICE_NAME=\"$(CONFIG_SYSINFO_DEVICE_NAME)\" + +GLOBAL_LDFLAGS += -L $(SOURCE_ROOT)/board/mk3239 + +# Global defines +# HSE_VALUE = STM32 crystal frequency = 26MHz (needed to make UART work correctly) +GLOBAL_DEFINES += $$(if $$(NO_CRLF_STDIO_REPLACEMENT),,CRLF_STDIO_REPLACEMENT) +GLOBAL_CFLAGS += -DSTM32F412 -mcpu=cortex-m4 -mthumb -mfloat-abi=soft + +WIFI_FIRMWARE_SECTOR_START := 2 #0x2000 +BT_PATCH_SECTOR_START := 256 #0x100000 + +# Extra build target in mico_standard_targets.mk, include bootloader, and copy output file to eclipse debug file (copy_output_for_eclipse) +EXTRA_TARGET_MAKEFILES += $(MAKEFILES_PATH)/aos_standard_targets.mk +#EXTRA_TARGET_MAKEFILES += $(SOURCE_ROOT)/platform/mcu/$(HOST_MCU_FAMILY)/gen_crc_bin.mk diff --git a/board/mk3239/osa_flash.c b/board/mk3239/osa_flash.c new file mode 100644 index 0000000000..9278c54f37 --- /dev/null +++ b/board/mk3239/osa_flash.c @@ -0,0 +1,493 @@ +#include +#include +#include +#include + +#include "stm32l4xx_hal.h" +#include "stm32l4xx_hal_flash.h" + +#define EN_DBG 0 + +#define KM_FLASH_ADDR_START 0x080FF000 +#define KM_FLASH_ADDR_SIZE 0x1000 +#define FLASH_BLOCK_LEN FLASH_PAGE_SIZE + +/** + * @brief Gets the page of a given address + * @param Addr: Address of the FLASH Memory + * @retval The page of a given address + */ +static uint32_t GetPage(uint32_t Addr) +{ + uint32_t page = 0; + + if (Addr < (FLASH_BASE + FLASH_BANK_SIZE)) + { + /* Bank 1 */ + page = (Addr - FLASH_BASE) / FLASH_PAGE_SIZE; + } + else + { + /* Bank 2 */ + page = (Addr - (FLASH_BASE + FLASH_BANK_SIZE)) / FLASH_PAGE_SIZE; + } + + return page; +} + +/** + * @brief Gets the bank of a given address + * @param Addr: Address of the FLASH Memory + * @retval The bank of a given address + */ +static uint32_t GetBank(uint32_t Addr) +{ + uint32_t bank = 0; + + if (READ_BIT(SYSCFG->MEMRMP, SYSCFG_MEMRMP_FB_MODE) == 0) + { + /* No Bank swap */ + if (Addr < (FLASH_BASE + FLASH_BANK_SIZE)) + { + bank = FLASH_BANK_1; + } + else + { + bank = FLASH_BANK_2; + } + } + else + { + /* Bank swap */ + if (Addr < (FLASH_BASE + FLASH_BANK_SIZE)) + { + bank = FLASH_BANK_2; + } + else + { + bank = FLASH_BANK_1; + } + } + + return bank; +} + +int32_t osa_flash_read(void *addr, void *out, size_t size) +{ +#if EN_DBG + printf("flash read addr 0x%08x size 0x%08x\n", (uint32_t)addr, size); +#endif + memcpy(out, addr ,size); + +#if EN_DBG + printf("data 0x%02x 0x%02x 0x%02x 0x%02x\n", + *((uint8_t *)out + 0), *((uint8_t *)out + 1), + *((uint8_t *)out + 2), *((uint8_t *)out + 3)); +#endif + return 0; +} + +int32_t osa_flash_write(void *addr, void *buf, size_t size) +{ + uint64_t *p = (uint64_t *)buf; + uint32_t a = (uint32_t)addr; + HAL_StatusTypeDef ret = HAL_OK; + + if (0 != ((uint32_t)addr % 8) || 0 != (size % 8)) { + printf("bad param addr 0x%08x size 0x%08x\n", + (unsigned int)addr , (unsigned int)size); + return -1; + } +#if EN_DBG + printf("flash write addr 0x%08x size 0x%08x\n", + (uint32_t)addr , (uint32_t)size); +#endif + + HAL_FLASH_Unlock(); + while ((size >= 8) && (ret == HAL_OK)) { + ret = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, (uint32_t)a, (uint64_t)(*p)); + if (0 != ret) { + printf("write flash fail addr %08x data %llx ret 0x%08x\n", + (unsigned int)a, (uint64_t)(*p), (unsigned int)ret); + return -1; + } +#if EN_DBG + uint8_t tmp_buf[8]; + int i; + + osa_flash_read((void *)a , tmp_buf, 8); + if (0 != memcmp(tmp_buf, p, 8)) { + printf("write than read not match \n"); + + for (i = 0; i < 8; ++i) { + printf("write buf 0x%02x read data 0x%02x\n", *((uint8_t *)p + i), tmp_buf[i]); + } + return -1; + } + #if 0 + for (i = 0; i < 8; ++i) { + printf("write buf 0x%02x read data 0x%02x\n", *((uint8_t *)p + i), tmp_buf[i]); + } + #endif +#endif + p = (uint64_t *)((uint32_t)p + 8); + a += 8; + size -= 8; + } + HAL_FLASH_Lock(); + + return 0; +} + +int32_t osa_flash_erase(void *addr, size_t size) +{ + uint32_t PageError = 0; + FLASH_EraseInitTypeDef pEraseInit; + uint32_t cur_addr = (uint32_t)addr; + size_t cur_size = size; + + HAL_FLASH_Unlock(); + if (0 != (size % FLASH_BLOCK_LEN) || 0 != (cur_addr % FLASH_BLOCK_LEN)) { + printf("bad param addr 0x%08x size 0x%08x\n", + (unsigned int)addr, (unsigned int)size); + return -1; + } + + if (0 == size) { + return 0; + } + while (cur_size > 0) { + /* Fill EraseInit structure*/ + pEraseInit.TypeErase = FLASH_TYPEERASE_PAGES; + pEraseInit.Banks = GetBank(cur_addr); + pEraseInit.Page = GetPage(cur_addr); + pEraseInit.NbPages = 1; +#if EN_DBG + printf("flash erase page %d bank %d\n", GetPage(cur_addr), GetBank(cur_addr)); +#endif + if (HAL_FLASHEx_Erase(&pEraseInit, &PageError) != HAL_OK) + { + printf("flash erase fail\n"); + return -1; + } + cur_size -= FLASH_BLOCK_LEN; + cur_addr -= FLASH_BLOCK_LEN; + } + HAL_FLASH_Lock(); + + return 0; +} + +int32_t getRDPLevel(uint32_t *RDPLevel) +{ + FLASH_OBProgramInitTypeDef sFlashOptionBytes; + int32_t eRetStatus = 0; + + if (NULL == RDPLevel) { + return -1; + } + /* Unlock the Flash to enable the flash control register access +*************/ + HAL_FLASH_Unlock(); + + /* Clear OPTVERR bit set on virgin samples */ + __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR); + + /* Unlock the Options Bytes +*************************************************/ + HAL_FLASH_OB_Unlock(); + + /* Get Option Bytes status for FLASH_BANK_1: WRP AREA_A and PCRoP +**********/ + HAL_FLASHEx_OBGetConfig(&sFlashOptionBytes); + + *RDPLevel = sFlashOptionBytes.RDPLevel; + + /* Lock the Options Bytes +***************************************************/ + HAL_FLASH_OB_Lock(); + HAL_FLASH_Lock(); + + return eRetStatus; +} + +int32_t ConfigWRP (bool enable, bool reboot) +{ + int32_t eRetStatus = 0; + uint32_t RDPlevel; + uint32_t StartPage = 0, EndPage = 0, StartBank = 0, EndBank = 0; + FLASH_OBProgramInitTypeDef psFlashOptionBytes, psFlashOptionBytes2; + + eRetStatus = getRDPLevel(&RDPlevel); + if (0 != eRetStatus) { + return -1; + } + + if (OB_RDP_LEVEL_2 == RDPlevel) { + return -1; + } + + /* Get the number of the start and end pages */ + StartPage = GetPage(KM_FLASH_ADDR_START); + EndPage = GetPage(KM_FLASH_ADDR_START + KM_FLASH_ADDR_SIZE - 1); + + /* Get the bank of the start and end pages */ + StartBank = GetBank(KM_FLASH_ADDR_START); + EndBank = GetBank(KM_FLASH_ADDR_START + KM_FLASH_ADDR_SIZE - 1); + + if (StartBank != EndBank) { + /* cross bank not support now */ + return -1; + } + + /* WRP area is only on one bank */ + if (StartBank == FLASH_BANK_1) + { + psFlashOptionBytes.WRPArea = OB_WRPAREA_BANK1_AREAA; + psFlashOptionBytes2.WRPArea = OB_WRPAREA_BANK1_AREAB; + } + else + { + psFlashOptionBytes.WRPArea = OB_WRPAREA_BANK2_AREAA; + psFlashOptionBytes2.WRPArea = OB_WRPAREA_BANK2_AREAB; + } + + HAL_FLASH_Unlock(); + __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR); + HAL_FLASH_OB_Unlock(); + + HAL_FLASHEx_OBGetConfig(&psFlashOptionBytes); + HAL_FLASHEx_OBGetConfig(&psFlashOptionBytes2); + if (true == enable) { + /* Check if desired pages are not yet write protected ***********************/ + if ((psFlashOptionBytes.WRPStartOffset <= StartPage) && (psFlashOptionBytes.WRPEndOffset >= (StartPage - 1))) + { + /* Current area is adjacent to pages to be write protected */ + if (psFlashOptionBytes.WRPEndOffset < EndPage) + { + /* Current area will be extended to include the pages to be write protected */ + psFlashOptionBytes.OptionType = OPTIONBYTE_WRP; + psFlashOptionBytes.WRPEndOffset = EndPage; + } + } + else if ((psFlashOptionBytes.WRPStartOffset <= (EndPage + 1)) && (psFlashOptionBytes.WRPEndOffset >= EndPage)) + { + /* Current area is adjacent to pages to be write protected */ + if (psFlashOptionBytes.WRPStartOffset > StartPage) + { + /* Current area will be extended to include the pages to be write protected */ + psFlashOptionBytes.OptionType = OPTIONBYTE_WRP; + psFlashOptionBytes.WRPStartOffset = StartPage; + } + } + else if ((psFlashOptionBytes.WRPStartOffset > StartPage) && (psFlashOptionBytes.WRPEndOffset < EndPage)) + { + /* Current area is included in pages to be write protected */ + psFlashOptionBytes.OptionType = OPTIONBYTE_WRP; + psFlashOptionBytes.WRPStartOffset = StartPage; + psFlashOptionBytes.WRPEndOffset = EndPage; + } + else if ((psFlashOptionBytes2.WRPStartOffset <= StartPage) && (psFlashOptionBytes2.WRPEndOffset >= (StartPage - 1))) + { + /* Current area is adjacent to pages to be write protected */ + if (psFlashOptionBytes2.WRPEndOffset < EndPage) + { + /* Current area will be extended to include the pages to be write protected */ + psFlashOptionBytes2.OptionType = OPTIONBYTE_WRP; + psFlashOptionBytes2.WRPEndOffset = EndPage; + } + } + else if ((psFlashOptionBytes2.WRPStartOffset <= (EndPage + 1)) && (psFlashOptionBytes2.WRPEndOffset >= EndPage)) + { + /* Current area is adjacent to pages to be write protected */ + if (psFlashOptionBytes2.WRPStartOffset > StartPage) + { + /* Current area will be extended to include the pages to be write protected */ + psFlashOptionBytes2.OptionType = OPTIONBYTE_WRP; + psFlashOptionBytes2.WRPStartOffset = StartPage; + } + } + else if ((psFlashOptionBytes2.WRPStartOffset > StartPage) && (psFlashOptionBytes2.WRPEndOffset < EndPage)) + { + /* Current area is included in pages to be write protected */ + psFlashOptionBytes2.OptionType = OPTIONBYTE_WRP; + psFlashOptionBytes2.WRPStartOffset = StartPage; + psFlashOptionBytes2.WRPEndOffset = EndPage; + } + else if (psFlashOptionBytes.WRPStartOffset > psFlashOptionBytes.WRPEndOffset) + { + /* Current area is not used => it will be configured to protect the pages */ + psFlashOptionBytes.OptionType = OPTIONBYTE_WRP; + psFlashOptionBytes.WRPStartOffset = StartPage; + psFlashOptionBytes.WRPEndOffset = EndPage; + } + else if (psFlashOptionBytes2.WRPStartOffset > psFlashOptionBytes2.WRPEndOffset) + { + /* Current area is not used => it will be configured to protect the pages */ + psFlashOptionBytes2.OptionType = OPTIONBYTE_WRP; + psFlashOptionBytes2.WRPStartOffset = StartPage; + psFlashOptionBytes2.WRPEndOffset = EndPage; + } + else + { + /* No more area available to protect the pages */ + /* => Error : not possible to activate the pages indicated */ + HAL_FLASH_OB_Lock(); + HAL_FLASH_Lock(); + eRetStatus = -1; + } + } else { + /* disable */ + /* Check if desired pages are already write protected ***********************/ + if ((psFlashOptionBytes.WRPStartOffset == StartPage) && (psFlashOptionBytes.WRPEndOffset == EndPage)) + { + /* Current area correspond to the area to disable */ + psFlashOptionBytes.OptionType = OPTIONBYTE_WRP; + psFlashOptionBytes.WRPStartOffset = 0xFF; + psFlashOptionBytes.WRPEndOffset = 0; + } + else if ((psFlashOptionBytes.WRPStartOffset == StartPage) && (psFlashOptionBytes.WRPEndOffset > EndPage)) + { + /* Current area is bigger than the area to disable : */ + /* - End of area is bigger than the last page to un-protect */ + psFlashOptionBytes.OptionType = OPTIONBYTE_WRP; + psFlashOptionBytes.WRPStartOffset = EndPage + 1; + } + else if ((psFlashOptionBytes.WRPStartOffset < StartPage) && (psFlashOptionBytes.WRPEndOffset == EndPage)) + { + /* Current area is bigger than the area to disable : */ + /* - Start of area is lower than the first page to un-protect */ + psFlashOptionBytes.OptionType = OPTIONBYTE_WRP; + psFlashOptionBytes.WRPEndOffset = StartPage - 1; + } + else if ((psFlashOptionBytes.WRPStartOffset < StartPage) && (psFlashOptionBytes.WRPEndOffset > EndPage)) + { + /* Current area is bigger than the area to disable */ + /* - Start of area is lower than the first page to un-protect */ + /* - End of area is bigger than the last page to un-protect */ + if (psFlashOptionBytes2.WRPStartOffset > psFlashOptionBytes2.WRPEndOffset) + { + /* Second area of the bank can be used */ + psFlashOptionBytes2.OptionType = OPTIONBYTE_WRP; + psFlashOptionBytes2.WRPStartOffset = EndPage + 1; + psFlashOptionBytes2.WRPEndOffset = psFlashOptionBytes.WRPEndOffset; + + psFlashOptionBytes.OptionType = OPTIONBYTE_WRP; + psFlashOptionBytes.WRPEndOffset = StartPage - 1; + } + else + { + /* Second area of the bank already used for WRP */ + /* => Error : not possible to deactivate only the pages indicated */ + HAL_FLASH_OB_Lock(); + HAL_FLASH_Lock(); + eRetStatus = -1; + } + } + else if ((psFlashOptionBytes2.WRPStartOffset == StartPage) && (psFlashOptionBytes2.WRPEndOffset == EndPage)) + { + /* Current area correspond to the area to disable */ + psFlashOptionBytes2.OptionType = OPTIONBYTE_WRP; + psFlashOptionBytes2.WRPStartOffset = 0xFF; + psFlashOptionBytes2.WRPEndOffset = 0; + } + else if ((psFlashOptionBytes2.WRPStartOffset == StartPage) && (psFlashOptionBytes2.WRPEndOffset > EndPage)) + { + /* Current area is bigger than the area to disable : */ + /* - End of area is bigger than the last page to un-protect */ + psFlashOptionBytes2.OptionType = OPTIONBYTE_WRP; + psFlashOptionBytes2.WRPStartOffset = EndPage + 1; + } + else if ((psFlashOptionBytes2.WRPStartOffset < StartPage) && (psFlashOptionBytes2.WRPEndOffset == EndPage)) + { + /* Current area is bigger than the area to disable : */ + /* - Start of area is lower than the first page to un-protect */ + psFlashOptionBytes2.OptionType = OPTIONBYTE_WRP; + psFlashOptionBytes2.WRPEndOffset = StartPage - 1; + } + else if ((psFlashOptionBytes2.WRPStartOffset < StartPage) && (psFlashOptionBytes2.WRPEndOffset > EndPage)) + { + /* Current area is bigger than the area to disable */ + /* - Start of area is lower than the first page to un-protect */ + /* - End of area is bigger than the last page to un-protect */ + if (psFlashOptionBytes.WRPStartOffset > psFlashOptionBytes.WRPEndOffset) + { + /* Second area of the bank can be used */ + psFlashOptionBytes.OptionType = OPTIONBYTE_WRP; + psFlashOptionBytes.WRPStartOffset = EndPage + 1; + psFlashOptionBytes.WRPEndOffset = psFlashOptionBytes2.WRPEndOffset; + + psFlashOptionBytes2.OptionType = OPTIONBYTE_WRP; + psFlashOptionBytes2.WRPEndOffset = StartPage - 1; + } + else + { + /* Second area of the bank already used for WRP */ + /* => Error : not possible to deactivate only the pages indicated */ + HAL_FLASH_OB_Lock(); + HAL_FLASH_Lock(); + eRetStatus = -1; + } + } + } + + /* Configure write protected pages */ + if (psFlashOptionBytes.OptionType == OPTIONBYTE_WRP) + { + if(HAL_FLASHEx_OBProgram(&psFlashOptionBytes) != HAL_OK) + { + /* Error occurred while options bytes programming. **********************/ + HAL_FLASH_OB_Lock(); + HAL_FLASH_Lock(); + eRetStatus = -1; + } + } + + if (psFlashOptionBytes2.OptionType == OPTIONBYTE_WRP) + { + if(HAL_FLASHEx_OBProgram(&psFlashOptionBytes2) != HAL_OK) + { + /* Error occurred while options bytes programming. **********************/ + HAL_FLASH_OB_Lock(); + HAL_FLASH_Lock(); + eRetStatus = -1; + } + } + + /* Generate System Reset to load the new option byte values ***************/ + if (((psFlashOptionBytes.OptionType == OPTIONBYTE_WRP) || (psFlashOptionBytes2.OptionType == OPTIONBYTE_WRP)) && reboot) + { + HAL_FLASH_OB_Launch(); + } + + HAL_FLASH_OB_Lock(); + HAL_FLASH_Lock(); + return eRetStatus; +} + +int32_t CleanProtectionWRP (void) +{ + int32_t eRetStatus = 0; + uint32_t RDPlevel; + FLASH_OBProgramInitTypeDef psFlashOptionBytes; + + eRetStatus = getRDPLevel(&RDPlevel); + if (0 != eRetStatus) { + return -1; + } + + if (OB_RDP_LEVEL_2 == RDPlevel) { + return -1; + } + + psFlashOptionBytes.OptionType = OPTIONBYTE_WRP; + psFlashOptionBytes.WRPArea = 0;//SFU_HAL_IF_PROTECT_WRP_AREA_1; + psFlashOptionBytes.WRPStartOffset = 0; + psFlashOptionBytes.WRPEndOffset = 0; + + if (HAL_FLASHEx_OBProgram(&psFlashOptionBytes) != HAL_OK) { + eRetStatus = -1; + } + + return eRetStatus; +} diff --git a/board/mk3239/wifi_nvram.c b/board/mk3239/wifi_nvram.c new file mode 100644 index 0000000000..7a47748b82 --- /dev/null +++ b/board/mk3239/wifi_nvram.c @@ -0,0 +1,13 @@ + +#include +#include + +uint32_t host_platform_memory_wifi_nvram_size( void ) +{ + return sizeof(wifi_nvram_image); +} + +uint8_t* host_platform_read_wifi_nvram_image( int offset ) +{ + return (uint8_t*) &wifi_nvram_image[offset]; +} diff --git a/board/mk3239/wifi_nvram_image.h b/board/mk3239/wifi_nvram_image.h new file mode 100644 index 0000000000..f2f3c52697 --- /dev/null +++ b/board/mk3239/wifi_nvram_image.h @@ -0,0 +1,99 @@ + +/** @file + * NVRAM variables which define BCM43438A1 Parameters for the + * MXCHIP EMW3239 module. + * + */ + +#ifndef INCLUDED_NVRAM_IMAGE_H_ +#define INCLUDED_NVRAM_IMAGE_H_ + +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +#define NVRAM_GENERATED_MAC_ADDRESS "macaddr=C8:93:46:00:00:01" +/** + * Character array of NVRAM image + */ + + static const char wifi_nvram_image[] = + // # The following parameter values are just placeholders, need to be updated. + "manfid=0x2d0" "\x00" + "prodid=0x0726" "\x00" + "vendid=0x14e4" "\x00" + "devid=0x43e2" "\x00" + "boardtype=0x0726" "\x00" + "boardrev=0x1101" "\x00" + "boardnum=22" "\x00" + "xtalfreq=26000" "\x00" + "sromrev=11" "\x00" + "boardflags=0x00404201" "\x00" + "boardflags3=0x04000000" "\x00" //0x08000000 /* Force external lpo */ + NVRAM_GENERATED_MAC_ADDRESS "\x00" + "nocrc=1" "\x00" + "ag0=255" "\x00" + "aa2g=1" "\x00" + "ccode=ALL" "\x00" + //#Antenna diversity + "swdiv_en=1" "\x00" + "swdiv_gpio=2" "\x00" + + "pa0itssit=0x20" "\x00" + "extpagain2g=0" "\x00" + //#PA parameters for 2.4GHz, measured at CHIP OUTPUT + "pa2ga0=-194,5941,-695" "\x00" + "AvVmid_c0=0x0,0xc8" "\x00" + "cckpwroffset0=5" "\x00" + //# PPR params + "maxp2ga0=74" "\x00" + "txpwrbckof=6" "\x00" + "cckbw202gpo=0" "\x00" //0x1111 + "legofdmbw202gpo=0x44444444" "\x00" //0x66666666 + "mcsbw202gpo=0x88888888" "\x00" //0x88888888 + "propbw202gpo=0xdd" "\x00" + //# OFDM IIR : + "ofdmdigfilttype=18" "\x00" + "ofdmdigfilttypebe=18" "\x00" + //# PAPD mode: + "papdmode=1" "\x00" + "papdvalidtest=1" "\x00" + "pacalidx2g=32" "\x00" + "papdepsoffset=-36" "\x00" + "papdendidx=61" "\x00" + //# LTECX flags + // "ltecxmux=1" "\x00" + //"ltecxpadnum=0x02030401" "\x00" + // "ltecxfnsel=0x3003" "\x00" + // "ltecxgcigpio=0x3012" "\x00" + //#il0macaddr=00:90:4c:c5:12:38 + "wl0id=0x431b" "\x00" + "deadman_to=0xffffffff" "\x00" + //#OOB parameters + "hostwake=0x40" "\x00" + "hostrdy=0x41" "\x00" + //# muxenab: 0x1 for UART enable, 0x2 for GPIOs, 0x8 for JTAG, 0x10 for HW OOB + "muxenab=0x11" "\x00" + //# CLDO PWM voltage settings - 0x4 - 1.1 volt + //#cldo_pwm=0x4 "\x00" + //#VCO freq 326.4MHz + "spurconfig=0x3" "\x00" + //#CE 1.8.1 + //"edonthd=-70" "\x00" + //"edoffthd=-76" "\x00" + "\x00\x00"; + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#else /* ifndef INCLUDED_NVRAM_IMAGE_H_ */ + +#error Wi-Fi NVRAM image included twice + +#endif /* ifndef INCLUDED_NVRAM_IMAGE_H_ */ diff --git a/build/Makefile b/build/Makefile index 080bd10158..aed2f8eaeb 100644 --- a/build/Makefile +++ b/build/Makefile @@ -196,6 +196,7 @@ $(BUILD_STRING): main_app $(if $(SUB_BUILD),,.gdbinit .gdbinit$(BINSTYPE_LOWER)) main_app: $(OUTPUT_DIR)/config.mk $(YOS_SDK_PRE_APP_BUILDS) $(MAKEFILES_PATH)/aos_target_build.mk $(if $(BINS_ERROR), $(call BINS_EXIT)) $(QUIET)$(ECHO) Build AOS Now + $(QUIET)$(ECHO) TOOLCHAIN_PATH=$(TOOLCHAIN_PATH) $(QUIET)$(call MKDIR, $(OUTPUT_DIR)/binary) $(QUIET)$(call MKDIR, $(OUTPUT_DIR)/modules) $(QUIET)$(call MKDIR, $(OUTPUT_DIR)/libraries) @@ -207,7 +208,8 @@ main_app: $(OUTPUT_DIR)/config.mk $(YOS_SDK_PRE_APP_BUILDS) $(MAKEFILES_PATH)/ao ifeq ($(SUB_BUILD),) .gdbinit: $(OUTPUT_DIR)/config.mk $(MAKEFILES_PATH)/aos_host_cmd.mk main_app $(QUIET)$(ECHO) Making $@ - $(QUIET)$(ECHO) set remotetimeout 20 > $@ + $(QUIET)$(ECHO) '#GDB_PATH=$(GDB_COMMAND)' > $@ + $(QUIET)$(ECHO) set remotetimeout 20 >> $@ $(QUIET)$(ECHO) $(GDB_KILL_OPENOCD) >> $@ $(QUIET)$(ECHO) $(GDBINIT_STRING) >> $@ diff --git a/build/aos_firmware_update.py b/build/aos_firmware_update.py index 75f931eccf..e039a48d29 100755 --- a/build/aos_firmware_update.py +++ b/build/aos_firmware_update.py @@ -616,7 +616,7 @@ def print_usage(): port.write("a\r\n") #abort potential ongoing YMODEM transfer port.flushInput() port.write("help\r\n") - if assert_response(["bootloader", "read: usage: read [address] [size]"], 1) == False: + if assert_response(["bootloader", "read [address] [size]"], 1) == False: if application_baudrate != bootloader_baudrate: port.baudrate = application_baudrate port.flushInput() @@ -628,9 +628,13 @@ def print_usage(): sys.exit(1) if application_baudrate != bootloader_baudrate: port.baudrate = bootloader_baudrate - time.sleep(0.12) - port.write(" \r\n"); - if assert_response(["ootloader"], 1) == False: + time.sleep(0.11); port.write(" ") #0.11s + time.sleep(0.03); port.write(" ") #0.14s + time.sleep(0.03); port.write(" ") #0.17s + time.sleep(0.03); port.write(" ") #0.20s + time.sleep(0.03); port.write(" ") #0.23s + time.sleep(0.03); port.write(" \r\n") #0.26s + if assert_response(["ootloader", "BOOTLODER"], 1) == False: sys.stderr.write("error: failed to enter bootloader\n") sys.exit(1) else: diff --git a/build/aos_host_cmd.mk b/build/aos_host_cmd.mk index f2f5f9c066..38e93385f3 100644 --- a/build/aos_host_cmd.mk +++ b/build/aos_host_cmd.mk @@ -8,6 +8,8 @@ JTAG ?= jlink_swd BUILD_DIR ?= out +DATE := date + ifeq ($(HOST_OS),Win32) ################ # Windows settings @@ -16,6 +18,7 @@ COMMON_TOOLS_PATH := $(TOOLS_ROOT)/cmd/win32/ export SHELL = cmd.exe EXECUTABLE_SUFFIX := .exe OPENOCD_FULL_NAME := $(OPENOCD_PATH)Win32/openocd.exe +DATE := $(COMMON_TOOLS_PATH)$(DATE) # Python ifneq ($(wildcard C:\Python34\python.exe),) @@ -210,6 +213,7 @@ RM := "$(COMMON_TOOLS_PATH)rm$(EXECUTABLE_SUFFIX)" -f CP := "$(COMMON_TOOLS_PATH)cp$(EXECUTABLE_SUFFIX)" -f MAKE := "$(COMMON_TOOLS_PATH)make$(EXECUTABLE_SUFFIX)" BIN2C := "$(COMMON_TOOLS_PATH)bin2c$(EXECUTABLE_SUFFIX)" +CURRENT_TIME = $(shell $(DATE) +%Y%m%d.%H%M) SHOULD_I_WAIT_FOR_DOWNLOAD := $(filter download, $(MAKECMDGOALS)) diff --git a/build/aos_library_build.mk b/build/aos_library_build.mk index cfe7ca8f9f..7c32d68123 100644 --- a/build/aos_library_build.mk +++ b/build/aos_library_build.mk @@ -31,6 +31,8 @@ include $(SOURCE_ROOT)build/aos_host_cmd.mk ifeq ($(COMPILER),armcc) include $(SOURCE_ROOT)build/aos_toolchain_armcc.mk +else ifeq ($(COMPILER),iar) +include $(SOURCE_ROOT)build/aos_toolchain_iar.mk else include $(SOURCE_ROOT)build/aos_toolchain_gcc.mk endif diff --git a/build/aos_library_config.mk b/build/aos_library_config.mk index aa99bc94e9..5063680b49 100644 --- a/build/aos_library_config.mk +++ b/build/aos_library_config.mk @@ -9,6 +9,8 @@ include $(SOURCE_ROOT)/build/aos_host_cmd.mk ifeq ($(COMPILER),armcc) include $(SOURCE_ROOT)/build/aos_toolchain_armcc.mk +else ifeq ($(COMPILER),iar) +include $(SOURCE_ROOT)build/aos_toolchain_iar.mk else include $(SOURCE_ROOT)/build/aos_toolchain_gcc.mk endif diff --git a/build/aos_library_makefile.mk b/build/aos_library_makefile.mk index 96eaae2edf..89b7213de4 100644 --- a/build/aos_library_makefile.mk +++ b/build/aos_library_makefile.mk @@ -14,6 +14,6 @@ endef POSSIBLE_BOARD_LIST := $(notdir $(wildcard $(SOURCE_ROOT)/board/*)) $(foreach b, $(POSSIBLE_BOARD_LIST), \ -$(if $(SOURCE_ROOT)/board/$(b)/$(b).mk, \ +$(if $(wildcard $(SOURCE_ROOT)/board/$(b)/$(b).mk), \ $(eval $(call TRY_TO_BUILD_LIBRARY, $(b))))) diff --git a/build/aos_target_build.mk b/build/aos_target_build.mk index ba13bb5c39..0d4aaba11b 100644 --- a/build/aos_target_build.mk +++ b/build/aos_target_build.mk @@ -12,6 +12,8 @@ else ifeq ($(COMPILER),gcc) include $(MAKEFILES_PATH)/aos_toolchain_gcc.mk else ifeq ($(COMPILER),armcc) include $(MAKEFILES_PATH)/aos_toolchain_armcc.mk +else ifeq ($(COMPILER),iar) +include $(MAKEFILES_PATH)/aos_toolchain_iar.mk endif .PHONY: display_map_summary build_done @@ -108,9 +110,9 @@ endef # Creates a target for building Assembly language files (*.s & *.S) # $(1) is component name, $(2) is the source file define BUILD_S_RULE -$(OUTPUT_DIR)/Modules/$(call GET_BARE_LOCATION,$(1))$(strip $(patsubst %.S,%.o, $(2:.s=.o) )): $(strip $($(1)_LOCATION))$(2) $($(1)_PRE_BUILD_TARGETS) $(CONFIG_FILE) $$(dir $(OUTPUT_DIR)/Modules/$(call GET_BARE_LOCATION,$(1))$(strip $(patsubst %.S, %.o, $(2)))).d $(RESOURCES_DEPENDENCY) $(LIBS_DIR)/$(1).c_opts $(PROCESS_PRECOMPILED_FILES) | $(EXTRA_PRE_BUILD_TARGETS) +$(OUTPUT_DIR)/Modules/$(call GET_BARE_LOCATION,$(1))$(strip $(patsubst %.S,%.o, $(2:.s=.o) )): $(strip $($(1)_LOCATION))$(2) $($(1)_PRE_BUILD_TARGETS) $(CONFIG_FILE) $$(dir $(OUTPUT_DIR)/Modules/$(call GET_BARE_LOCATION,$(1))$(strip $(patsubst %.S, %.o, $(2)))).d $(RESOURCES_DEPENDENCY) $(LIBS_DIR)/$(1).as_opts $(PROCESS_PRECOMPILED_FILES) | $(EXTRA_PRE_BUILD_TARGETS) $$(if $($(1)_START_PRINT),,$(eval $(1)_START_PRINT:=1) $(ECHO) Compiling $(1)) - $(QUIET)$(CC) $(OPTIONS_IN_FILE_OPTION_PREFIX)$(OPTIONS_IN_FILE_OPTION)$(LIBS_DIR)/$(1).c_opts$(OPTIONS_IN_FILE_OPTION_SUFFIX) -o $$@ $$< $(COMPILER_SPECIFIC_STDOUT_REDIRECT) + $(QUIET)$(AS) $(OPTIONS_IN_FILE_OPTION_PREFIX)$(OPTIONS_IN_FILE_OPTION)$(LIBS_DIR)/$(1).as_opts$(OPTIONS_IN_FILE_OPTION_SUFFIX) -o $$@ $$< $(COMPILER_SPECIFIC_STDOUT_REDIRECT) endef ############################################################################### @@ -138,8 +140,8 @@ $(LIBS_DIR)/$(1).c_opts: $($(1)_PRE_BUILD_TARGETS) $(CONFIG_FILE) | $(LIBS_DIR) $(LIBS_DIR)/$(1).cpp_opts: $($(1)_PRE_BUILD_TARGETS) $(CONFIG_FILE) | $(LIBS_DIR) $(QUIET)$$(call WRITE_FILE_CREATE, $$@ ,$(COMPILER_SPECIFIC_COMP_ONLY_FLAG) $(COMPILER_SPECIFIC_DEPS_FLAG) $($(1)_CXXFLAGS) $($(1)_INCLUDES) $($(1)_DEFINES) $(AOS_SDK_INCLUDES) $(AOS_SDK_DEFINES)) -#$(LIBS_DIR)/$(1).as_opts: $(CONFIG_FILE) | $(LIBS_DIR) -# $(QUIET)$$(call WRITE_FILE_CREATE, $$@ ,$($(1)_ASMFLAGS)) +$(LIBS_DIR)/$(1).as_opts: $(CONFIG_FILE) | $(LIBS_DIR) + $(QUIET)$$(call WRITE_FILE_CREATE, $$@ ,$(CPU_ASMFLAGS) $(COMPILER_SPECIFIC_COMP_ONLY_FLAG) $($(1)_ASMFLAGS) $($(1)_INCLUDES) $(AOS_SDK_INCLUDES)) $(LIBS_DIR)/$(1).ar_opts: $(CONFIG_FILE) | $(LIBS_DIR) $(QUIET)$$(call WRITE_FILE_CREATE, $$@ ,$($(1)_LIB_OBJS)) @@ -252,33 +254,46 @@ $(LDS_FILE_DIR): %/.i: $(QUIET)$(call MKDIR, $(dir $@)) - +# FIXME GCC Whole archive not ready in all platform $(LINK_OPTS_FILE): $(OUTPUT_DIR)/config.mk $(LDS_FILES) -#$(COMPILER_SPECIFIC_LINK_MAP) $(MAP_OUTPUT_FILE) $(LINK_OPTS_FILE) +ifeq ($(COMPILER),armcc) + $(QUIET)$(call WRITE_FILE_CREATE, $@ ,$(AOS_SDK_LINK_SCRIPT_CMD) $(call COMPILER_SPECIFIC_LINK_MAP,$(MAP_OUTPUT_FILE)) $(AOS_SDK_LDFLAGS) $(call COMPILER_SPECIFIC_LINK_FILES, $(AOS_SDK_LINK_FILES) $(filter %.a,$^) $(LINK_LIBS))) +else $(QUIET)$(call WRITE_FILE_CREATE, $@ ,$(AOS_SDK_LINK_SCRIPT_CMD) $(call COMPILER_SPECIFIC_LINK_MAP,$(MAP_OUTPUT_FILE)) $(call COMPILER_SPECIFIC_LINK_FILES, $(AOS_SDK_LINK_FILES) $(filter %.a,$^) $(LINK_LIBS)) $(AOS_SDK_LDFLAGS) ) +endif $(LINT_OPTS_FILE): $(LINK_LIBS) $(QUIET)$(call WRITE_FILE_CREATE, $@ , ) $(QUIET)$(foreach opt,$(sort $(subst \",",$(LINT_FLAGS))) $(sort $(LINT_FILES)),$(call WRITE_FILE_APPEND, $@ ,$(opt))) - + +define LINK_OUTPUT_FILE_OPTIONS_MACRO +LINK_OUTPUT_FILE_OPTIONS = $(OPTIONS_IN_FILE_OPTION_PREFIX)$(OPTIONS_IN_FILE_OPTION)$1$(OPTIONS_IN_FILE_OPTION_SUFFIX) +endef + $(LINK_OUTPUT_FILE): $(LINK_LIBS) $(AOS_SDK_LINK_SCRIPT) $(LINK_OPTS_FILE) $(LINT_DEPENDENCY) | $(EXTRA_PRE_LINK_TARGETS) $(QUIET)$(ECHO) Making $(notdir $@) - $(QUIET)$(LINKER) $(OPTIONS_IN_FILE_OPTION_PREFIX)$(OPTIONS_IN_FILE_OPTION)$(LINK_OPTS_FILE)$(OPTIONS_IN_FILE_OPTION_SUFFIX) $(COMPILER_SPECIFIC_STDOUT_REDIRECT) -o $@ + $(eval $(call LINK_OUTPUT_FILE_OPTIONS_MACRO,$(LINK_OPTS_FILE))) + $(QUIET)$(LINKER) $(LINK_OUTPUT_FILE_OPTIONS) $(COMPILER_SPECIFIC_STDOUT_REDIRECT) -o $@ $(QUIET)$(ECHO_BLANK_LINE) $(QUIET)$(call COMPILER_SPECIFIC_MAPFILE_TO_CSV,$(MAP_OUTPUT_FILE),$(MAP_CSV_OUTPUT_FILE)) - + # Stripped elf file target - Strips the full elf file and outputs to a new .stripped.elf file $(STRIPPED_LINK_OUTPUT_FILE): $(LINK_OUTPUT_FILE) - $(QUIET)$(STRIP) -o $@ $(STRIPFLAGS) $< +ifeq ($(COMPILER),iar) + $(QUIET)$(STRIP) $(STRIPFLAGS) $< $(STRIP_OUTPUT_PREFIX)$@ +else + $(QUIET)$(STRIP) $(STRIP_OUTPUT_PREFIX)$@ $(STRIPFLAGS) $< +endif # Bin file target - uses objcopy to convert the stripped elf into a binary file $(BIN_OUTPUT_FILE): $(STRIPPED_LINK_OUTPUT_FILE) $(QUIET)$(ECHO) Making $(notdir $@) - $(QUIET)$(OBJCOPY) -O binary -R .eh_frame -R .init -R .fini -R .comment -R .ARM.attributes $< $@ + $(QUIET)$(OBJCOPY) $(OBJCOPY_BIN_FLAGS) $< $(OBJCOPY_OUTPUT_PREFIX)$@ $(HEX_OUTPUT_FILE): $(STRIPPED_LINK_OUTPUT_FILE) $(QUIET)$(ECHO) Making $(notdir $@) - $(QUIET)$(OBJCOPY) -O ihex -R .eh_frame -R .init -R .fini -R .comment -R .ARM.attributes $< $@ + $(QUIET)$(OBJCOPY) $(OBJCOPY_HEX_FLAGS) $< $(OBJCOPY_OUTPUT_PREFIX)$@ + # Linker output target - This links all component & resource libraries and objects into an output executable # CXX is used for compatibility with C++ #$(AOS_SDK_CONVERTER_OUTPUT_FILE): $(LINK_OUTPUT_FILE) diff --git a/build/aos_target_config.mk b/build/aos_target_config.mk index 469171f5cb..679458f52a 100644 --- a/build/aos_target_config.mk +++ b/build/aos_target_config.mk @@ -43,18 +43,16 @@ $(eval TEST_COMPONENTS := $(addprefix %., $(addsuffix _test, $(TEST_COMPONENTS)) $(eval COMPONENTS += $(filter $(TEST_COMPONENTS), $(subst /,.,$(strip $(TEST_COMPONENT_LIST))))))) endef - ##################################################################################### -# Macro PROCESS_COMPONENT +# Macro FIND_COMPONENT use breadth traversal to search component # $(1) is the list of components left to process. $(COMP) is set as the first element in the list -define PROCESS_COMPONENT +define FIND_COMPONENT $(eval COMP := $(word 1,$(1))) $(eval COMP_LOCATION := $(subst .,/,$(COMP))) $(eval COMP_MAKEFILE_NAME := $(notdir $(COMP_LOCATION))) # Find the component makefile in directory list -$(eval TEMP_MAKEFILE := $(strip $(wildcard $(foreach dir, $(if $(filter-out out, $(BUILD_DIR)),$(OUTPUT_DIR),) $(if $(APPDIR),$(APPDIR)/$(comp),) $(addprefix $(SOURCE_ROOT),$(COMPONENT_DIRECTORIES)), $(dir)/$(COMP_LOCATION)/$(COMP_MAKEFILE_NAME).mk)))) - +$(eval TEMP_MAKEFILE := $(strip $(wildcard $(foreach dir, $(if $(filter-out out, $(BUILD_DIR)),$(OUTPUT_DIR) $(OUTPUT_DIR)/syscall,) $(if $(APPDIR),$(APPDIR)/$(comp),) $(addprefix $(SOURCE_ROOT),$(COMPONENT_DIRECTORIES)), $(dir)/$(COMP_LOCATION)/$(COMP_MAKEFILE_NAME).mk)))) # Check if component makefile was found - if not try downloading it and re-doing the makefile search $(if $(TEMP_MAKEFILE),,\ $(info Unknown component: $(COMP) - directory or makefile for component not found. Ensure the $(COMP_LOCATION) directory contains $(COMP_MAKEFILE_NAME).mk) \ @@ -66,6 +64,29 @@ $(if $(TEMP_MAKEFILE),,\ $(error Unknown component: $(COMP) - directory or makefile for component not found. Ensure the $(COMP_LOCATION) directory contains $(COMP_MAKEFILE_NAME).mk)) $(if $(filter 1,$(words $(TEMP_MAKEFILE))),,$(error More than one component with the name "$(COMP)". See $(TEMP_MAKEFILE))) +$(eval include $(TEMP_MAKEFILE)) +$(eval COMPONENTS += $($(NAME)_COMPONENTS)) +$(call PREPROCESS_TEST_COMPONENT, $(COMPONENTS), $(TEST_COMPONENTS)) + +$(eval PROCESSED_COMPONENTS_LOCS += $(COMP)) + +DEPENDENCY += '$(NAME)': '$($(NAME)_COMPONENTS)', + +$(if $(strip $(filter-out $(PROCESSED_COMPONENTS_LOCS),$(COMPONENTS))),\ + $(call FIND_COMPONENT,$(filter-out $(PROCESSED_COMPONENTS_LOCS),$(COMPONENTS))),\ +) +endef + +##################################################################################### +# Macro PROCESS_ONE_COMPONENT +# $(1) is one component +define PROCESS_ONE_COMPONENT +$(eval COMP := $(1)) +$(eval COMP_LOCATION := $(subst .,/,$(COMP))) +$(eval COMP_MAKEFILE_NAME := $(notdir $(COMP_LOCATION))) +# Find the component makefile in directory list +$(eval TEMP_MAKEFILE := $(strip $(wildcard $(foreach dir, $(if $(filter-out out, $(BUILD_DIR)),$(OUTPUT_DIR) $(OUTPUT_DIR)/syscall,) $(if $(APPDIR),$(APPDIR)/$(comp),) $(addprefix $(SOURCE_ROOT),$(COMPONENT_DIRECTORIES)), $(dir)/$(COMP_LOCATION)/$(COMP_MAKEFILE_NAME).mk)))) + # Clear all the temporary variables $(eval GLOBAL_INCLUDES:=) $(eval GLOBAL_LINK_SCRIPT:=) @@ -112,7 +133,7 @@ $(eval $(NAME)_RESOURCES_EXPANDED := $(foreach res,$($(NAME)_RESOURCES),$(word 1 $(eval CURDIR := $(OLD_CURDIR)) -$(eval $(NAME)_LOCATION ?= $(dir $(TEMP_MAKEFILE))) +$(eval $(NAME)_LOCATION := $(dir $(TEMP_MAKEFILE))) $(eval $(NAME)_MAKEFILE := $(TEMP_MAKEFILE)) AOS_SDK_MAKEFILES += $($(NAME)_MAKEFILE) @@ -143,14 +164,17 @@ AOS_SDK_CONVERTER_OUTPUT_FILE += $(CONVERTER_OUTPUT_FILE) AOS_SDK_FINAL_OUTPUT_FILE += $(BIN_OUTPUT_FILE) $(eval PROCESSED_COMPONENTS += $(NAME)) -$(eval PROCESSED_COMPONENTS_LOCS += $(COMP)) -$(eval COMPONENTS += $($(NAME)_COMPONENTS)) -$(call PREPROCESS_TEST_COMPONENT, $(COMPONENTS), $(TEST_COMPONENTS)) +$(eval $(NAME)_SOURCES := $(sort $($(NAME)_SOURCES)) ) -DEPENDENCY += '$(NAME)': '$($(NAME)_COMPONENTS)', +endef -$(if $(strip $(filter-out $(PROCESSED_COMPONENTS_LOCS),$(COMPONENTS))),$(eval $(call PROCESS_COMPONENT,$(filter-out $(PROCESSED_COMPONENTS_LOCS),$(COMPONENTS)))),) + +##################################################################################### +# Macro PROCESS_COMPONENT +# $(1) is the list of components left to process. $(COMP) is set as the first element in the list +define PROCESS_COMPONENT +$(foreach TMP_COMP, $(COMPONENTS),$(call PROCESS_ONE_COMPONENT, $(TMP_COMP))) endef ################################## @@ -184,6 +208,7 @@ else AOS_SDK_LDFLAGS += $(COMPILER_SPECIFIC_DEBUG_LDFLAGS) endif + # Check if there are any unknown components; output error if so. $(foreach comp, $(COMPONENTS), $(if $(wildcard $(APPDIR)/$(comp) $(foreach dir, $(addprefix $(SOURCE_ROOT),$(COMPONENT_DIRECTORIES)), $(dir)/$(subst .,/,$(comp)) ) ),,$(error Unknown component: $(comp)))) @@ -204,6 +229,7 @@ EXTRA_CFLAGS := -DAOS_SDK_VERSION_MAJOR=$(AOS_SDK_VERSION_MAJOR) \ # Load platform makefile to make variables like WLAN_CHIP, HOST_OPENOCD & HOST_ARCH available to all makefiles $(eval CURDIR := $(SOURCE_ROOT)board/$(PLATFORM_DIRECTORY)/) + include $(SOURCE_ROOT)board/$(PLATFORM_DIRECTORY)/$(notdir $(PLATFORM_DIRECTORY)).mk PLATFORM_MCU_BOARD :=$(subst .,/,$(HOST_MCU_FAMILY)) @@ -219,6 +245,8 @@ CC := ifeq ($(COMPILER),armcc) include $(MAKEFILES_PATH)/aos_toolchain_armcc.mk +else ifeq ($(COMPILER),iar) +include $(MAKEFILES_PATH)/aos_toolchain_iar.mk else include $(MAKEFILES_PATH)/aos_toolchain_gcc.mk endif @@ -227,6 +255,8 @@ ifndef CC $(error No matching toolchain found for architecture $(HOST_ARCH)) endif + + # Process all the components + AOS COMPONENTS += platform/mcu/$(PLATFORM_MCU_BOARD) vcall init @@ -253,9 +283,16 @@ else ifeq (,$(BINS)) AOS_SDK_DEFINES += BUILD_BIN endif -$(info processing components: $(COMPONENTS)) - CURDIR := +ifneq ($(DEFAULT_ALL_COMPONENTS), ) +$(info default all components.) +$(eval COMPONENTS := $(subst @, ,$(DEFAULT_ALL_COMPONENTS))) +else +$(info processing components: $(COMPONENTS)) +$(eval $(call FIND_COMPONENT, $(COMPONENTS))) +endif +# remove repeat component +$(eval COMPONENTS := $(sort $(COMPONENTS)) ) $(eval $(call PROCESS_COMPONENT, $(COMPONENTS))) PLATFORM :=$(notdir $(PLATFORM_FULL)) diff --git a/build/aos_toolchain_arm-none-eabi.mk b/build/aos_toolchain_arm-none-eabi.mk index 909b8352aa..7f2f16f3b7 100644 --- a/build/aos_toolchain_arm-none-eabi.mk +++ b/build/aos_toolchain_arm-none-eabi.mk @@ -15,9 +15,14 @@ else HOST_INSTRUCTION_SET := THUMB endif +TOOLCHAIN_PATH ?= TOOLCHAIN_PREFIX := arm-none-eabi- TOOLCHAIN_VERSION := 5_4-2016q3-20160926 +ifneq (,$(wildcard $(TOOLS_ROOT)/compiler/arm-none-eabi-$(TOOLCHAIN_VERSION)/$(HOST_OS)/bin)) +TOOLCHAIN_PATH := $(TOOLS_ROOT)/compiler/arm-none-eabi-$(TOOLCHAIN_VERSION)/$(HOST_OS)/bin/ +endif + BINS ?= ifeq ($(HOST_OS),Win32) @@ -25,12 +30,15 @@ ifeq ($(HOST_OS),Win32) # Windows settings ################ -$(eval GCC_VER := $(shell arm-none-eabi-gcc --version | findstr "Copyright")) -ifeq ($(TOOLCHAIN_PATH),) -ifeq ($(GCC_VER),) -TOOLCHAIN_PATH := $(TOOLS_ROOT)/compiler/arm-none-eabi-$(TOOLCHAIN_VERSION)/Win32/bin/ +ifeq (,$(TOOLCHAIN_PATH)) +SYSTEM_GCC_PATH = $(shell where $(TOOLCHAIN_PREFIX)gcc.exe) +ifneq (,$(findstring $(TOOLCHAIN_PREFIX)gcc.exe,$(SYSTEM_GCC_PATH))) +SYSTEM_TOOLCHAIN_PATH = $(subst $(TOOLCHAIN_PREFIX)gcc.exe,,$(SYSTEM_GCC_PATH)) +TOOLCHAIN_PATH := $(SYSTEM_TOOLCHAIN_PATH) else -TOOLCHAIN_PATH := +DOWNLOAD_URL = "https://launchpad.net/gcc-arm-embedded/+download" +TOOLCHIAN_FILE = "gcc-arm-none-eabi-5_4-2016q3-20160926-win32.zip" +$(error can not find compiler toolchain, please download $(TOOLCHIAN_FILE) from $(DOWNLOAD_URL) and unzip to $(TOOLS_ROOT)/compiler/arm-none-eabi-$(TOOLCHAIN_VERSION)/$(HOST_OS) folder) endif endif @@ -44,8 +52,18 @@ ifneq (,$(filter $(HOST_OS),Linux32 Linux64)) # Linux 32/64-bit settings ################ -export PATH := $(TOOLS_ROOT)/compiler/arm-none-eabi-$(TOOLCHAIN_VERSION)/$(HOST_OS)/bin:$(PATH) -TOOLCHAIN_PATH ?= +ifeq (,$(TOOLCHAIN_PATH)) +SYSTEM_GCC_PATH = $(shell which $(TOOLCHAIN_PREFIX)gcc) +ifneq (,$(findstring $(TOOLCHAIN_PREFIX)gcc,$(SYSTEM_GCC_PATH))) +SYSTEM_TOOLCHAIN_PATH = $(subst $(TOOLCHAIN_PREFIX)gcc,,$(SYSTEM_GCC_PATH)) +TOOLCHAIN_PATH := $(SYSTEM_TOOLCHAIN_PATH) +else +DOWNLOAD_URL = "https://launchpad.net/gcc-arm-embedded/+download" +TOOLCHIAN_FILE = "gcc-arm-none-eabi-5_4-2016q3-20160926-linux.tar.bz2" +$(error can not find compiler toolchain, please download $(TOOLCHIAN_FILE) from $(DOWNLOAD_URL) and unzip to $(TOOLS_ROOT)/compiler/arm-none-eabi-$(TOOLCHAIN_VERSION)/$(HOST_OS) folder) +endif +endif + GDB_KILL_OPENOCD = 'shell killall openocd' GDBINIT_STRING = 'shell $(COMMON_TOOLS_PATH)dash -c "trap \\"\\" 2;$(OPENOCD_FULL_NAME) -f $(OPENOCD_CFG_PATH)interface/$(JTAG).cfg -f $(OPENOCD_CFG_PATH)$(HOST_OPENOCD)/$(HOST_OPENOCD).cfg -f $(OPENOCD_CFG_PATH)$(HOST_OPENOCD)/$(HOST_OPENOCD)_gdb_jtag.cfg -l $(OPENOCD_LOG_FILE) &"' GDB_COMMAND = "$(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)gdb" @@ -56,19 +74,28 @@ ifeq ($(HOST_OS),OSX) # OSX settings ################ -export PATH := $(TOOLS_ROOT)/compiler/arm-none-eabi-$(TOOLCHAIN_VERSION)/$(HOST_OS)/bin:$(PATH) -TOOLCHAIN_PATH ?= +ifeq (,$(TOOLCHAIN_PATH)) +SYSTEM_GCC_PATH = $(shell which $(TOOLCHAIN_PREFIX)gcc) +ifneq (,$(findstring $(TOOLCHAIN_PREFIX)gcc,$(SYSTEM_GCC_PATH))) +SYSTEM_TOOLCHAIN_PATH = $(subst $(TOOLCHAIN_PREFIX)gcc,,$(SYSTEM_GCC_PATH)) +TOOLCHAIN_PATH := $(SYSTEM_TOOLCHAIN_PATH) +else +DOWNLOAD_URL = "https://launchpad.net/gcc-arm-embedded/+download" +TOOLCHIAN_FILE = "gcc-arm-none-eabi-5_4-2016q3-20160926-mac.tar.bz2" +$(error can not find compiler toolchain, please download $(TOOLCHIAN_FILE) from $(DOWNLOAD_URL) and unzip to $(TOOLS_ROOT)/compiler/arm-none-eabi-$(TOOLCHAIN_VERSION)/$(HOST_OS) folder) +endif +endif + GDB_KILL_OPENOCD = 'shell killall openocd_run' GDBINIT_STRING = 'shell $(COMMON_TOOLS_PATH)dash -c "trap \\"\\" 2;$(OPENOCD_FULL_NAME) -f $(OPENOCD_CFG_PATH)interface/$(JTAG).cfg -f $(OPENOCD_CFG_PATH)$(HOST_OPENOCD)/$(HOST_OPENOCD).cfg -f $(OPENOCD_CFG_PATH)$(HOST_OPENOCD)/$(HOST_OPENOCD)_gdb_jtag.cfg -l $(OPENOCD_LOG_FILE) &"' GDB_COMMAND = "$(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)gdb" else # OSX -$(error incorrect 'make' used ($(MAKE)) - please use: (Windows) .\make.exe (OS X, Linux) ./make ) +$(error unsupport OS $(HOST_OS)) endif # OSX endif # Linux32 Linux64 OSX endif # Win32 - # Notes on C++ options: # The next two CXXFLAGS reduce the size of C++ code by removing unneeded # features. For example, these flags reduced the size of a console app build @@ -89,7 +116,7 @@ endif # Win32 CC := "$(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)gcc$(EXECUTABLE_SUFFIX)" CXX := "$(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)g++$(EXECUTABLE_SUFFIX)" -AS := "$(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)as$(EXECUTABLE_SUFFIX)" +AS := $(CC) AR := "$(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)ar$(EXECUTABLE_SUFFIX)" LD := "$(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)ld$(EXECUTABLE_SUFFIX)" CPP := "$(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)cpp$(EXECUTABLE_SUFFIX)" @@ -112,7 +139,7 @@ COMPILER_SPECIFIC_ARFLAGS_VERBOSE := -v #debug: no optimize and log enable COMPILER_SPECIFIC_DEBUG_CFLAGS := -DDEBUG -ggdb $(COMPILER_SPECIFIC_UNOPTIMIZED_CFLAGS) COMPILER_SPECIFIC_DEBUG_CXXFLAGS := -DDEBUG -ggdb $(COMPILER_SPECIFIC_UNOPTIMIZED_CFLAGS) -COMPILER_SPECIFIC_DEBUG_ASFLAGS := --defsym DEBUG=1 -ggdb +COMPILER_SPECIFIC_DEBUG_ASFLAGS := -DDEBUG=1 -ggdb COMPILER_SPECIFIC_DEBUG_LDFLAGS := -Wl,--gc-sections -Wl,--cref #release_log: optimize but log enable @@ -158,7 +185,7 @@ endif ifeq ($(HOST_ARCH),Cortex-M4F) CPU_CFLAGS := -mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard CPU_CXXFLAGS := -mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -CPU_ASMFLAGS := -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard +CPU_ASMFLAGS := $(CPU_CFLAGS) CPU_LDFLAGS := -mthumb -mcpu=cortex-m4 -Wl,-A,thumb CLIB_LDFLAGS_NANO += -mfpu=fpv4-sp-d16 -mfloat-abi=hard CLIB_LDFLAGS_NANO_FLOAT += -mfpu=fpv4-sp-d16 -mfloat-abi=hard @@ -167,21 +194,21 @@ endif ifeq ($(HOST_ARCH),Cortex-M4) CPU_CFLAGS := -mthumb -mcpu=cortex-m4 CPU_CXXFLAGS := -mthumb -mcpu=cortex-m4 -CPU_ASMFLAGS := -mcpu=cortex-m4 -mfpu=softvfp +CPU_ASMFLAGS := $(CPU_CFLAGS) CPU_LDFLAGS := -mthumb -mcpu=cortex-m4 -Wl,-A,thumb endif ifeq ($(HOST_ARCH),Cortex-M3) CPU_CFLAGS := -mthumb -mcpu=cortex-m3 CPU_CXXFLAGS := -mthumb -mcpu=cortex-m3 -CPU_ASMFLAGS := -mcpu=cortex-m3 -mfpu=softvfp +CPU_ASMFLAGS := $(CPU_CFLAGS) CPU_LDFLAGS := -mthumb -mcpu=cortex-m3 -Wl,-A,thumb endif ifeq ($(HOST_ARCH),Cortex-M0) CPU_CFLAGS := -mthumb -mcpu=cortex-m0 CPU_CXXFLAGS := -mthumb -mcpu=cortex-m0 -CPU_ASMFLAGS := -mcpu=cortex-m0 -mthumb +CPU_ASMFLAGS := $(CPU_CFLAGS) CPU_LDFLAGS := -mthumb -mcpu=cortex-m0 -Wl,-A,thumb endif @@ -240,6 +267,10 @@ else BINS_DOWNLOAD_ADDR = 0x13200 endif # BINS +STRIP_OUTPUT_PREFIX := -o +OBJCOPY_BIN_FLAGS := -O binary -R .eh_frame -R .init -R .fini -R .comment -R .ARM.attributes +OBJCOPY_HEX_FLAGS := -O ihex -R .eh_frame -R .init -R .fini -R .comment -R .ARM.attributes + LINK_OUTPUT_SUFFIX :=.elf BIN_OUTPUT_SUFFIX :=.bin HEX_OUTPUT_SUFFIX :=.hex diff --git a/build/aos_toolchain_armcc.mk b/build/aos_toolchain_armcc.mk index 4f4e31f4b3..73e8cbe21c 100644 --- a/build/aos_toolchain_armcc.mk +++ b/build/aos_toolchain_armcc.mk @@ -2,14 +2,14 @@ TOOLCHAIN_PATH ?= TOOLCHAIN_PREFIX := arm CC := $(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)cc CXX := $(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)cc -AS := $(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)asm +AS := $(CC) AR := $(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)ar LD := $(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)link CPP := $(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)cc -OPTIONS_IN_FILE_OPTION_PREFIX = $$( -OPTIONS_IN_FILE_OPTION = file < -OPTIONS_IN_FILE_OPTION_SUFFIX = ) +OPTIONS_IN_FILE_OPTION_PREFIX = $$ +OPTIONS_IN_FILE_OPTION = (file < +OPTIONS_IN_FILE_OPTION_SUFFIX = ) OBJCOPYFLAGS := --bin --output= ADD_COMPILER_SPECIFIC_STANDARD_CFLAGS = @@ -42,7 +42,7 @@ COMPILER_SPECIFIC_RELEASE_LDFLAGS := COMPILER_SPECIFIC_DEPS_FLAG := --md COMPILER_SPECIFIC_COMP_ONLY_FLAG := -c -COMPILER_SPECIFIC_LINK_MAP = -L--map -L --list=$(1) +COMPILER_SPECIFIC_LINK_MAP = -L --map -L --list=$(1) COMPILER_SPECIFIC_LINK_FILES = $(1) COMPILER_SPECIFIC_LINK_SCRIPT_DEFINE_OPTION = COMPILER_SPECIFIC_LINK_SCRIPT = @@ -71,14 +71,21 @@ CPU_LDFLAGS := #MAPFILE_PARSER :=$(MAKEFILES_PATH)/scripts/map_parse_armcc.py # $(1) is map file, $(2) is CSV output file -COMPILER_SPECIFIC_MAPFILE_DISPLAY_SUMMARY = $(PYTHON) $(MAPFILE_PARSER) $(1) +#COMPILER_SPECIFIC_MAPFILE_DISPLAY_SUMMARY = $(PYTHON) $(MAPFILE_PARSER) $(1) +#TODO treat mapfile -OBJDUMP := "$(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)fromelf$(EXECUTABLE_SUFFIX)" -OBJCOPY := "$(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)fromelf$(EXECUTABLE_SUFFIX)" +OBJDUMP := "$(TOOLCHAIN_PATH)fromelf$(EXECUTABLE_SUFFIX)" +OBJCOPY := "$(TOOLCHAIN_PATH)fromelf$(EXECUTABLE_SUFFIX)" #no need to strip in arm fromelf -#STRIP := "$(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)fromelf$(EXECUTABLE_SUFFIX)" +STRIP := "$(TOOLCHAIN_PATH)fromelf$(EXECUTABLE_SUFFIX)" + +STRIP_OUTPUT_PREFIX := --output= +STRIPFLAGS := --strip=debug,symbols --elf +OBJCOPY_BIN_FLAGS := --bin +OBJCOPY_OUTPUT_PREFIX := --output= +OBJCOPY_HEX_FLAGS := --i32 LINK_OUTPUT_SUFFIX :=.axf BIN_OUTPUT_SUFFIX :=.bin -HEX_OUTPUT_SUFFIX :=.hex \ No newline at end of file +HEX_OUTPUT_SUFFIX :=.hex diff --git a/build/aos_toolchain_armhflinux.mk b/build/aos_toolchain_armhflinux.mk index 29e8f6856d..d2dec1005c 100644 --- a/build/aos_toolchain_armhflinux.mk +++ b/build/aos_toolchain_armhflinux.mk @@ -1,16 +1,33 @@ ifneq ($(filter $(HOST_ARCH), armhflinux),) -PATH := $(PATH):/bin:/usr/bin:/usr/local/bin -TOOLCHAIN_PATH := +TOOLCHAIN_PATH ?= TOOLCHAIN_PREFIX := arm-linux-gnueabihf- + +SYSTEM_TOOLCHAIN_PATH := +ifneq (,$(filter $(HOST_OS),Linux32 Linux64 OSX)) +SYSTEM_GCC_PATH = $(shell which $(TOOLCHAIN_PREFIX)gcc) +ifneq (,$(findstring $(TOOLCHAIN_PREFIX)gcc,$(SYSTEM_GCC_PATH))) +SYSTEM_TOOLCHAIN_PATH := $(subst $(TOOLCHAIN_PREFIX)gcc,,$(SYSTEM_GCC_PATH)) +endif +else #Linux32 Linux64 OSX +$(error unsupport OS $(HOST_OS)) +endif #Linux32 Linux64 OSX + +ifeq (,$(TOOLCHAIN_PATH)) +ifneq (,$(SYSTEM_TOOLCHAIN_PATH)) +TOOLCHAIN_PATH := $(SYSTEM_TOOLCHAIN_PATH) +else +$(error can not find compiler toolchain, please install gcc-arm-linux-gnueabihf toolchain first) +endif #SYSTEM_TOOLCHAIN_PATH +endif #TOOLCHAIN_PATH + CC := $(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)gcc CXX := $(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)g++ -AS := $(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)as +AS := $(CC) AR := $(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)ar LD := $(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)ld OPTIONS_IN_FILE_OPTION := @ -export PATH ADD_COMPILER_SPECIFIC_STANDARD_CFLAGS = $(1) $(if $(filter yes,$(MXCHIP_INTERNAL) $(TESTER)),-Werror) ADD_COMPILER_SPECIFIC_STANDARD_CXXFLAGS = $(1) $(if $(filter yes,$(MXCHIP_INTERNAL) $(TESTER)),-Werror) ADD_COMPILER_SPECIFIC_STANDARD_ADMFLAGS = $(1) @@ -24,7 +41,7 @@ COMPILER_SPECIFIC_ARFLAGS_VERBOSE := -v #debug: no optimize and log enable COMPILER_SPECIFIC_DEBUG_CFLAGS := -DDEBUG -ggdb $(COMPILER_SPECIFIC_UNOPTIMIZED_CFLAGS) COMPILER_SPECIFIC_DEBUG_CXXFLAGS := -DDEBUG -ggdb $(COMPILER_SPECIFIC_UNOPTIMIZED_CFLAGS) -COMPILER_SPECIFIC_DEBUG_ASFLAGS := --defsym DEBUG=1 +COMPILER_SPECIFIC_DEBUG_ASFLAGS := -DDEBUG=1 COMPILER_SPECIFIC_DEBUG_LDFLAGS := -Wl,--gc-sections -Wl,--cref #release_log: optimize but log enable @@ -82,8 +99,12 @@ OBJCOPY := "$(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)objcopy$(EXECUTABLE_SUFFIX)" STRIP := "$(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)strip$(EXECUTABLE_SUFFIX)" NM := "$(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)nm$(EXECUTABLE_SUFFIX)" +STRIP_OUTPUT_PREFIX := -o +OBJCOPY_BIN_FLAGS := -O binary -R .eh_frame -R .init -R .fini -R .comment -R .ARM.attributes +OBJCOPY_HEX_FLAGS := -O ihex -R .eh_frame -R .init -R .fini -R .comment -R .ARM.attributes + LINK_OUTPUT_SUFFIX :=.elf -BIN_OUTPUT_SUFFIX :=.bin -HEX_OUTPUT_SUFFIX :=.hex +BIN_OUTPUT_SUFFIX :=.bin +HEX_OUTPUT_SUFFIX :=.hex endif diff --git a/build/aos_toolchain_csky.mk b/build/aos_toolchain_csky.mk index 7905c65161..e785d1020f 100644 --- a/build/aos_toolchain_csky.mk +++ b/build/aos_toolchain_csky.mk @@ -1,17 +1,45 @@ ifneq ($(filter $(HOST_ARCH), ck802),) -TOOL_PATH := $(shell pwd) -TOOLCHAIN_PATH = $(TOOL_PATH)/build/compiler/csky-abiv2-elf-tools-x86_64-minilibc-20160704/bin/ -PATH := $(PATH):/bin:/usr/bin:/usr/local/bin -CC := $(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)csky-abiv2-elf-gcc -AS := $(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)csky-abiv2-elf-as -AR := $(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)csky-abiv2-elf-ar -LD := $(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)csky-abiv2-elf-ld -DUMP := $(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)csky-abiv2-elf-objdump -OBJCOPY := $(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)csky-abiv2-elf-objcopy +TOOLCHAIN_PATH ?= +TOOLCHAIN_PREFIX := csky-abiv2-elf- + +ifneq (,$(wildcard $(TOOLS_ROOT)/build/compiler/csky-abiv2-elf-tools-x86_64-minilibc-20160704/bin)) +TOOLCHAIN_PATH := $(TOOLS_ROOT)/build/compiler/csky-abiv2-elf-tools-x86_64-minilibc-20160704/bin/ +endif + +SYSTEM_TOOLCHAIN_PATH := +ifeq ($(HOST_OS),Win32) +SYSTEM_GCC_PATH = $(shell where $(TOOLCHAIN_PREFIX)gcc.exe) +ifneq (,$(findstring $(TOOLCHAIN_PREFIX)gcc.exe,$(SYSTEM_GCC_PATH))) +SYSTEM_TOOLCHAIN_PATH := $(subst $(TOOLCHAIN_PREFIX)gcc.exe,,$(SYSTEM_GCC_PATH)) +endif +else #WIN32 +ifneq (,$(filter $(HOST_OS),Linux32 Linux64 OSX)) +SYSTEM_GCC_PATH = $(shell which $(TOOLCHAIN_PREFIX)gcc) +ifneq (,$(findstring $(TOOLCHAIN_PREFIX)gcc,$(SYSTEM_GCC_PATH))) +SYSTEM_TOOLCHAIN_PATH := $(subst $(TOOLCHAIN_PREFIX)gcc,,$(SYSTEM_GCC_PATH)) +endif +else #Linux32 Linux64 OSX +$(error unsupport OS $(HOST_OS)) +endif #Linux32 Linux64 OSX +endif #WIN32 + +ifeq (,$(TOOLCHAIN_PATH)) +ifneq (,$(SYSTEM_TOOLCHAIN_PATH)) +TOOLCHAIN_PATH := $(SYSTEM_TOOLCHAIN_PATH) +else +$(error can not find compiler toolchain, please install gcc-csky-abiv3-elf toolchain to $(TOOLS_ROOT)/build/compiler/csky-abiv2-elf-tools-x86_64-minilibc-20160704 folder) +endif #SYSTEM_TOOLCHAIN_PATH +endif #TOOLCHAIN_PATH + +CC := $(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)gcc +AS := $(CC) +AR := $(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)ar +LD := $(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)ld +DUMP := $(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)objdump +OBJCOPY := $(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)objcopy OPTIONS_IN_FILE_OPTION := @ -export PATH ADD_COMPILER_SPECIFIC_STANDARD_CFLAGS = $(1) $(if $(filter yes,$(MXCHIP_INTERNAL) $(TESTER)),-Wl) ADD_COMPILER_SPECIFIC_STANDARD_CXXFLAGS = $(1) $(if $(filter yes,$(MXCHIP_INTERNAL) $(TESTER)),-Wl) ADD_COMPILER_SPECIFIC_STANDARD_ADMFLAGS = $(1) @@ -25,7 +53,7 @@ COMPILER_SPECIFIC_ARFLAGS_VERBOSE := -v #debug: no optimize and log enable COMPILER_SPECIFIC_DEBUG_CFLAGS := -DDEBUG -ggdb $(COMPILER_SPECIFIC_UNOPTIMIZED_CFLAGS) COMPILER_SPECIFIC_DEBUG_CXXFLAGS := -DDEBUG -ggdb $(COMPILER_SPECIFIC_UNOPTIMIZED_CFLAGS) -COMPILER_SPECIFIC_DEBUG_ASFLAGS := --defsym DEBUG=1 +COMPILER_SPECIFIC_DEBUG_ASFLAGS := -DDEBUG=1 COMPILER_SPECIFIC_DEBUG_LDFLAGS := -Wl,--gc-sections -Wl,--cref #release_log: optimize but log enable @@ -82,8 +110,12 @@ OBJCOPY := "$(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)csky-abiv2-elf-objcopy$(EXECUTAB STRIP := "$(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)csky-abiv2-elf-strip$(EXECUTABLE_SUFFIX)" NM := "$(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)csky-abiv2-elf-nm$(EXECUTABLE_SUFFIX)" +STRIP_OUTPUT_PREFIX := -o +OBJCOPY_BIN_FLAGS := -O binary -R .eh_frame -R .init -R .fini -R .comment -R .ARM.attributes +OBJCOPY_HEX_FLAGS := -O ihex -R .eh_frame -R .init -R .fini -R .comment -R .ARM.attributes + LINK_OUTPUT_SUFFIX :=.elf -BIN_OUTPUT_SUFFIX :=.bin -HEX_OUTPUT_SUFFIX :=.hex +BIN_OUTPUT_SUFFIX :=.bin +HEX_OUTPUT_SUFFIX :=.hex endif diff --git a/build/aos_toolchain_iar.mk b/build/aos_toolchain_iar.mk new file mode 100644 index 0000000000..049163c2f9 --- /dev/null +++ b/build/aos_toolchain_iar.mk @@ -0,0 +1,92 @@ +TOOLCHAIN_PATH ?= +TOOLCHAIN_PREFIX := +CC := $(TOOLCHAIN_PATH)iccarm +CXX := $(TOOLCHAIN_PATH)iccarm +AS := $(TOOLCHAIN_PATH)iasmarm +AR := $(TOOLCHAIN_PATH)iarchive +LD := $(TOOLCHAIN_PATH)ilinkarm +CPP := $(TOOLCHAIN_PATH)iccarm + +OPTIONS_IN_FILE_OPTION_PREFIX_DIRECT = $ +OPTIONS_IN_FILE_OPTION_PREFIX = $$ +OPTIONS_IN_FILE_OPTION = (file < +OPTIONS_IN_FILE_OPTION_SUFFIX = ) +OBJCOPYFLAGS := --bin --output= + +ADD_COMPILER_SPECIFIC_STANDARD_CFLAGS = +ADD_COMPILER_SPECIFIC_STANDARD_CXXFLAGS = +ADD_COMPILER_SPECIFIC_STANDARD_ADMFLAGS = $(1) +COMPILER_SPECIFIC_OPTIMIZED_CFLAGS := -Os +COMPILER_SPECIFIC_UNOPTIMIZED_CFLAGS := -O0 +COMPILER_SPECIFIC_PEDANTIC_CFLAGS := $(COMPILER_SPECIFIC_STANDARD_CFLAGS) +COMPILER_SPECIFIC_ARFLAGS_CREATE := --create +COMPILER_SPECIFIC_ARFLAGS_ADD := --create +COMPILER_SPECIFIC_ARFLAGS_VERBOSE := -V + +#debug: no optimize and log enable +COMPILER_SPECIFIC_DEBUG_CFLAGS := -DDEBUG -Dgdb $(COMPILER_SPECIFIC_UNOPTIMIZED_CFLAGS) +COMPILER_SPECIFIC_DEBUG_CXXFLAGS := -DDEBUG -Dgdb $(COMPILER_SPECIFIC_UNOPTIMIZED_CFLAGS) +COMPILER_SPECIFIC_DEBUG_ASFLAGS := +COMPILER_SPECIFIC_DEBUG_LDFLAGS := + +#release_log: optimize but log enable +COMPILER_SPECIFIC_RELEASE_LOG_CFLAGS := -Dgdb $(COMPILER_SPECIFIC_OPTIMIZED_CFLAGS) +COMPILER_SPECIFIC_RELEASE_LOG_CXXFLAGS := -Dgdb $(COMPILER_SPECIFIC_OPTIMIZED_CFLAGS) +COMPILER_SPECIFIC_RELEASE_LOG_ASFLAGS := +COMPILER_SPECIFIC_RELEASE_LOG_LDFLAGS := + +#release: optimize and log disable +COMPILER_SPECIFIC_RELEASE_CFLAGS := -DNDEBUG $(COMPILER_SPECIFIC_OPTIMIZED_CFLAGS) +COMPILER_SPECIFIC_RELEASE_CXXFLAGS := -DNDEBUG $(COMPILER_SPECIFIC_OPTIMIZED_CFLAGS) +COMPILER_SPECIFIC_RELEASE_ASFLAGS := +COMPILER_SPECIFIC_RELEASE_LDFLAGS := + +# -MD -> --dependencies xx.d +COMPILER_SPECIFIC_DEPS_FLAG := -e --dlib_config=full -D_TIMESPEC_DEFINED --silent --only_stdout --no_warnings --diag_warning=Pe167,Pe144,Pe513 +COMPILER_SPECIFIC_COMP_ONLY_FLAG := +COMPILER_SPECIFIC_LINK_MAP = --map $(1) +COMPILER_SPECIFIC_LINK_FILES = --whole_archive $(1) +COMPILER_SPECIFIC_LINK_SCRIPT_DEFINE_OPTION = +COMPILER_SPECIFIC_LINK_SCRIPT = + +LINKER := $(LD) +LINK_SCRIPT_SUFFIX := .icf +TOOLCHAIN_NAME := iar + +ENDIAN_CFLAGS_LITTLE := --littleend +ENDIAN_CXXFLAGS_LITTLE := --littleend +ENDIAN_ASMFLAGS_LITTLE := +ENDIAN_LDFLAGS_LITTLE := --littleend +CLIB_LDFLAGS_NANO := +CLIB_LDFLAGS_NANO_FLOAT:= + +# Chip specific flags for compiler +CPU_CFLAGS := +CPU_CXXFLAGS := +CPU_ASMFLAGS := +CPU_LDFLAGS := + +# $(1) is map file, $(2) is CSV output file +#COMPILER_SPECIFIC_MAPFILE_TO_CSV = $(PYTHON) $(MAPFILE_PARSER) $(1) > $(2) + +#TODO +#MAPFILE_PARSER :=$(MAKEFILES_PATH)/scripts/map_parse_armcc.py + +# $(1) is map file, $(2) is CSV output file +# iar map file format is different +#COMPILER_SPECIFIC_MAPFILE_DISPLAY_SUMMARY = $(PYTHON) $(MAPFILE_PARSER) $(1) + +OBJDUMP := "$(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)ielfdumparm$(EXECUTABLE_SUFFIX)" +OBJCOPY := "$(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)ielftool$(EXECUTABLE_SUFFIX)" +# -R .eh_frame -R .init -R .fini -R .comment -R .ARM.attributes -> iobjmanip --remvoe_secton +OBJCOPY_BIN_FLAGS := --bin --silent +OBJCOPY_HEX_FLAGS := --ihex --silent + +#no need to strip in arm fromelf +STRIP := "$(TOOLCHAIN_PATH)ielftool" +STRIPFLAGS := --strip --silent + +LINK_OUTPUT_SUFFIX :=.iarElf +BIN_OUTPUT_SUFFIX :=.bin +HEX_OUTPUT_SUFFIX :=.hex + diff --git a/build/aos_toolchain_linux.mk b/build/aos_toolchain_linux.mk index 41ca3a8648..7b6d858768 100644 --- a/build/aos_toolchain_linux.mk +++ b/build/aos_toolchain_linux.mk @@ -5,7 +5,7 @@ TOOLCHAIN_PATH := PATH := $(PATH):/bin:/usr/bin:/usr/local/bin CC := $(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)gcc CXX := $(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)g++ -AS := $(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)as +AS := $(CC) AR := $(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)ar LD := $(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)ld OPTIONS_IN_FILE_OPTION := @ @@ -24,7 +24,7 @@ COMPILER_SPECIFIC_ARFLAGS_VERBOSE := -v #debug: no optimize and log enable COMPILER_SPECIFIC_DEBUG_CFLAGS := -DDEBUG -ggdb $(COMPILER_SPECIFIC_UNOPTIMIZED_CFLAGS) COMPILER_SPECIFIC_DEBUG_CXXFLAGS := -DDEBUG -ggdb $(COMPILER_SPECIFIC_UNOPTIMIZED_CFLAGS) -COMPILER_SPECIFIC_DEBUG_ASFLAGS := --defsym DEBUG=1 +COMPILER_SPECIFIC_DEBUG_ASFLAGS := -DDEBUG=1 COMPILER_SPECIFIC_DEBUG_LDFLAGS := -Wl,--gc-sections -Wl,--cref #release_log: optimize but log enable @@ -82,8 +82,12 @@ OBJCOPY := "$(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)objcopy$(EXECUTABLE_SUFFIX)" STRIP := "$(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)strip$(EXECUTABLE_SUFFIX)" NM := "$(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)nm$(EXECUTABLE_SUFFIX)" +STRIP_OUTPUT_PREFIX := -o +OBJCOPY_BIN_FLAGS := -O binary -R .eh_frame -R .init -R .fini -R .comment -R .ARM.attributes +OBJCOPY_HEX_FLAGS := -O ihex -R .eh_frame -R .init -R .fini -R .comment -R .ARM.attributes + LINK_OUTPUT_SUFFIX :=.elf -BIN_OUTPUT_SUFFIX :=.bin -HEX_OUTPUT_SUFFIX :=.hex +BIN_OUTPUT_SUFFIX :=.bin +HEX_OUTPUT_SUFFIX :=.hex endif diff --git a/build/aos_toolchain_xtensa.mk b/build/aos_toolchain_xtensa.mk index 1076addbc1..911ceaa5ef 100644 --- a/build/aos_toolchain_xtensa.mk +++ b/build/aos_toolchain_xtensa.mk @@ -3,19 +3,51 @@ ifneq ($(filter $(HOST_ARCH), xtensa),) TOOLCHAIN_PATH ?= ifneq ($(filter $(HOST_MCU_FAMILY), esp8266), ) TOOLCHAIN_PREFIX := xtensa-lx106-elf- +TOOLCHAIN_DEFAULT_FOLDER := gcc-xtensa-lx106 endif ifneq ($(filter $(HOST_MCU_FAMILY), esp32), ) TOOLCHAIN_PREFIX := xtensa-esp32-elf- +TOOLCHAIN_DEFAULT_FOLDER := gcc-xtensa-esp32 endif + +ifneq (,$(wildcard $(TOOLS_ROOT)/compiler/$(TOOCHAIN_DEFAULT_FOLDER)/$(HOST_OS)/bin)) +TOOLCHAIN_PATH := $(TOOLS_ROOT)/compiler/$(TOOCHAIN_DEFAULT_FOLDER)/$(HOST_OS)/bin/ +endif + +SYSTEM_TOOLCHAIN_PATH := +ifeq ($(HOST_OS),Win32) +SYSTEM_GCC_PATH = $(shell where $(TOOLCHAIN_PREFIX)gcc.exe) +ifneq (,$(findstring $(TOOLCHAIN_PREFIX)gcc.exe,$(SYSTEM_GCC_PATH))) +SYSTEM_TOOLCHAIN_PATH := $(subst $(TOOLCHAIN_PREFIX)gcc.exe,,$(SYSTEM_GCC_PATH)) +endif +else #WIN32 +ifneq (,$(filter $(HOST_OS),Linux32 Linux64 OSX)) +SYSTEM_GCC_PATH = $(shell which $(TOOLCHAIN_PREFIX)gcc) +ifneq (,$(findstring $(TOOLCHAIN_PREFIX)gcc,$(SYSTEM_GCC_PATH))) +SYSTEM_TOOLCHAIN_PATH := $(subst $(TOOLCHAIN_PREFIX)gcc,,$(SYSTEM_GCC_PATH)) +endif +else #Linux32 Linux64 OSX +$(error unsupport OS $(HOST_OS)) +endif #Linux32 Linux64 OSX +endif #WIN32 + +ifeq (,$(TOOLCHAIN_PATH)) +ifneq (,$(SYSTEM_TOOLCHAIN_PATH)) +TOOLCHAIN_PATH := $(SYSTEM_TOOLCHAIN_PATH) +else +DOWNLOAD_URL = "https://esp-idf.readthedocs.io/en/latest/get-started/index.html\#setup-toolchain" +$(error can not find compiler toolchain, please setup toolchain as $(DOWNLOAD_URL) instructed) +endif #SYSTEM_TOOLCHAIN_PATH +endif #TOOLCHAIN_PATH + CC := $(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)gcc CXX := $(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)g++ -AS := $(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)as +AS := $(CC) AR := $(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)ar LD := $(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)ld CPP := $(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)cpp OPTIONS_IN_FILE_OPTION := @ -export PATH := $(TOOLS_ROOT)/compiler/gcc-xtensa-esp32/$(HOST_OS)/bin:$(PATH) ADD_COMPILER_SPECIFIC_STANDARD_CFLAGS = $(1) $(if $(filter yes,$(MXCHIP_INTERNAL) $(TESTER)),-Werror) ADD_COMPILER_SPECIFIC_STANDARD_CXXFLAGS = $(1) $(if $(filter yes,$(MXCHIP_INTERNAL) $(TESTER)),-Werror) ADD_COMPILER_SPECIFIC_STANDARD_ADMFLAGS = $(1) @@ -29,7 +61,7 @@ COMPILER_SPECIFIC_ARFLAGS_VERBOSE := -v #debug: no optimize and log enable COMPILER_SPECIFIC_DEBUG_CFLAGS := -DDEBUG -ggdb $(COMPILER_SPECIFIC_UNOPTIMIZED_CFLAGS) COMPILER_SPECIFIC_DEBUG_CXXFLAGS := -DDEBUG -ggdb $(COMPILER_SPECIFIC_UNOPTIMIZED_CFLAGS) -COMPILER_SPECIFIC_DEBUG_ASFLAGS := --defsym DEBUG=1 +COMPILER_SPECIFIC_DEBUG_ASFLAGS := -DDEBUG=1 COMPILER_SPECIFIC_DEBUG_LDFLAGS := -Wl,--gc-sections -Wl,--cref #release_log: optimize but log enable @@ -87,6 +119,10 @@ OBJCOPY := "$(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)objcopy$(EXECUTABLE_SUFFIX)" STRIP := "$(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)strip$(EXECUTABLE_SUFFIX)" NM := "$(TOOLCHAIN_PATH)$(TOOLCHAIN_PREFIX)nm$(EXECUTABLE_SUFFIX)" +STRIP_OUTPUT_PREFIX := -o +OBJCOPY_BIN_FLAGS := -O binary -R .eh_frame -R .init -R .fini -R .comment -R .ARM.attributes +OBJCOPY_HEX_FLAGS := -O ihex -R .eh_frame -R .init -R .fini -R .comment -R .ARM.attributes + LINK_OUTPUT_SUFFIX :=.elf BIN_OUTPUT_SUFFIX :=.bin HEX_OUTPUT_SUFFIX :=.hex diff --git a/build/autobuild.sh b/build/autobuild.sh index 63c52da7b6..a464d9533a 100755 --- a/build/autobuild.sh +++ b/build/autobuild.sh @@ -4,9 +4,9 @@ workdir=autobuild linux_posix_targets="alinkapp" linux_targets="alinkapp helloworld linuxapp yts" linux_platforms="linuxhost linuxhost@debug linuxhost@release" -mk3060_targets="alinkapp helloworld linuxapp meshapp" +mk3060_targets="alinkapp helloworld linuxapp meshapp uDataapp" mk3060_platforms="mk3060 mk3060@release" -b_l475e_targets="mqttapp helloworld" +b_l475e_targets="mqttapp helloworld uDataapp" b_l475e_platforms="b_l475e" esp32_targets="alinkapp helloworld meshapp" esp32_platforms="esp32devkitc" @@ -18,6 +18,7 @@ if [ $? -ne 0 ]; then exit 1 fi +JNUM=`cat /proc/cpuinfo | grep processor | wc -l` if [ -f ~/.bashrc ]; then . ~/.bashrc fi @@ -29,7 +30,7 @@ cd $(git rev-parse --show-toplevel) aos make clean > /dev/null 2>&1 for target in ${linux_posix_targets}; do for platform in ${linux_platforms}; do - vcall=posix aos make ${target}@${platform} > ${target}@${platform}@${branch}.log 2>&1 + vcall=posix aos make ${target}@${platform} JOBS=${JNUM} > ${target}@${platform}@${branch}.log 2>&1 if [ $? -eq 0 ]; then echo "build vcall=posix ${target}@${platform} at ${branch} branch succeed" rm -rf ${target}@${platform}@${branch}.log @@ -47,7 +48,7 @@ done aos make clean > /dev/null 2>&1 for target in ${linux_targets}; do for platform in ${linux_platforms}; do - aos make ${target}@${platform} > ${target}@${platform}@${branch}.log 2>&1 + aos make ${target}@${platform} JOBS=${JNUM} > ${target}@${platform}@${branch}.log 2>&1 if [ $? -eq 0 ]; then echo "build ${target}@${platform} at ${branch} branch succeed" rm -rf ${target}@${platform}@${branch}.log @@ -65,7 +66,7 @@ done aos make clean > /dev/null 2>&1 for target in ${mk3060_targets}; do for platform in ${mk3060_platforms}; do - aos make ${target}@${platform} > ${target}@${platform}@${branch}.log 2>&1 + aos make ${target}@${platform} JOBS=${JNUM} > ${target}@${platform}@${branch}.log 2>&1 if [ $? -eq 0 ]; then rm -rf ${target}@${platform}@${branch}.log echo "build ${target}@${platform} at ${branch} branch succeed" @@ -85,10 +86,10 @@ aos make clean > /dev/null 2>&1 for target in ${mk3060_targets}; do for platform in ${mk3060_platforms}; do for bins in ${bins_type}; do - if [ "${target}" = "tls" ] || [ "${target}" = "meshapp" ]; then + if [ "${target}" = "tls" ] || [ "${target}" = "meshapp" ] || [ "${target}" = "uDataapp" ]; then continue fi - aos make ${target}@${platform} BINS=${bins} > ${target}@${platform}@${bins}@${branch}.log 2>&1 + aos make ${target}@${platform} BINS=${bins} JOBS=${JNUM} > ${target}@${platform}@${bins}@${branch}.log 2>&1 if [ $? -eq 0 ]; then rm -rf ${target}@${platform}@${bins}@${branch}.log echo "build ${target}@${platform} BINS=${bins} as multiple BINs at ${branch} branch succeed" @@ -108,7 +109,7 @@ done aos make clean > /dev/null 2>&1 for target in ${b_l475e_targets}; do for platform in ${b_l475e_platforms}; do - aos make ${target}@${platform} > ${target}@${platform}@${branch}.log 2>&1 + aos make ${target}@${platform} JOBS=${JNUM} > ${target}@${platform}@${branch}.log 2>&1 if [ $? -eq 0 ]; then rm -rf ${target}@${platform}@${branch}.log echo "build ${target}@${platform} at ${branch} branch succeed" @@ -127,7 +128,7 @@ done aos make clean > /dev/null 2>&1 for target in ${esp32_targets}; do for platform in ${esp32_platforms}; do - aos make ${target}@${platform} wifi=1 > ${target}@${platform}@${branch}.log 2>&1 + aos make ${target}@${platform} wifi=1 JOBS=${JNUM} > ${target}@${platform}@${branch}.log 2>&1 if [ $? -eq 0 ]; then rm -rf ${target}@${platform}@${branch}.log echo "build ${target}@${platform} at ${branch} branch succeed" diff --git a/build/cmd/win32/date.exe b/build/cmd/win32/date.exe new file mode 100644 index 0000000000..676ba7d02f Binary files /dev/null and b/build/cmd/win32/date.exe differ diff --git a/build/cmd/win32/make.exe b/build/cmd/win32/make.exe old mode 100755 new mode 100644 index b950ba887e..39c969239e Binary files a/build/cmd/win32/make.exe and b/build/cmd/win32/make.exe differ diff --git a/build/fileformat.py b/build/fileformat.py new file mode 100755 index 0000000000..c4ef1b2b4f --- /dev/null +++ b/build/fileformat.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python + +import os, sys, re, platform + +def list_files(dir_path): + file_list = []; + + for root, dirs, files in os.walk(dir_path): + for f in files: + if (os.path.splitext(f)[1] == ".h" or os.path.splitext(f)[1] == ".c" or os.path.splitext(f)[1] == ".mk"): + file_list.append(os.path.join(root, f)) + return file_list + +def main(): + + if len(sys.argv) != 2: + print "Dir args is empty, Enter the path to be processed!" + os._exit(0) + + filedir = sys.argv[1] + print filedir.strip() + + sys_version = platform.version() + if "Ubuntu" in sys_version: + os.environ['syscmd'] = str("fromdos") + elif "CentOS" in sys_version: + os.environ['syscmd'] = str("dos2unix") + else: + print "Not find the system version!" + os._exit(0) + + file_list = list_files(filedir) + for f in file_list: + os.environ['file'] = str(f) + os.system('$syscmd $file') + +if __name__ == '__main__': + main() + diff --git a/build/scripts/syscall_data b/build/scripts/syscall_data index ed8e07d1a4..5e873a35dc 100644 --- a/build/scripts/syscall_data +++ b/build/scripts/syscall_data @@ -188,3 +188,7 @@ 1 187 aos_vprintf "int" " char *, va_list" 1 188 tcp_init "void" " void" 1 189 udp_init "void" " void" +1 190 hal_wifi_get_channel "int" " hal_wifi_module_t *" +1 191 hal_wifi_get_channel_list "int" " hal_wifi_module_t *, const uint8_t **" +1 192 uData_report_publish "int" " void *" +1 193 uData_subscribe "int" " udata_type_e" diff --git a/device/bluetooth/mk3239/BTE_platform/data_types.h b/device/bluetooth/mk3239/BTE_platform/data_types.h index 964e4e6168..57b52dcd8c 100644 --- a/device/bluetooth/mk3239/BTE_platform/data_types.h +++ b/device/bluetooth/mk3239/BTE_platform/data_types.h @@ -1,7 +1,3 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - #ifndef DATA_TYPES_H #define DATA_TYPES_H diff --git a/device/bluetooth/mk3239/BTE_platform/include/gki.h b/device/bluetooth/mk3239/BTE_platform/include/gki.h index b65bf1cea6..fea9132076 100644 --- a/device/bluetooth/mk3239/BTE_platform/include/gki.h +++ b/device/bluetooth/mk3239/BTE_platform/include/gki.h @@ -1,7 +1,3 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - /**************************************************************************** ** ** Name gki.h diff --git a/device/bluetooth/mk3239/BTE_platform/include/ucodec.h b/device/bluetooth/mk3239/BTE_platform/include/ucodec.h index 1c33af927b..d6b198fe1b 100644 --- a/device/bluetooth/mk3239/BTE_platform/include/ucodec.h +++ b/device/bluetooth/mk3239/BTE_platform/include/ucodec.h @@ -1,7 +1,3 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - /******************************************************************************* ** Name: ucodec.h ** diff --git a/device/bluetooth/mk3239/BTE_platform/include/udac.h b/device/bluetooth/mk3239/BTE_platform/include/udac.h index b8d6b826bc..1ae3b49480 100644 --- a/device/bluetooth/mk3239/BTE_platform/include/udac.h +++ b/device/bluetooth/mk3239/BTE_platform/include/udac.h @@ -1,13 +1,3 @@ -/** - * UNPUBLISHED PROPRIETARY SOURCE CODE - * Copyright (c) 2016 MXCHIP Inc. - * - * The contents of this file may not be disclosed to third parties, copied or - * duplicated in any form, in whole or in part, without the prior written - * permission of MXCHIP Corporation. - * - */ - /***************************************************************************** ** ** Name udac.h diff --git a/device/bluetooth/mk3239/BTE_platform/include/uipc.h b/device/bluetooth/mk3239/BTE_platform/include/uipc.h index 0911c8f538..2bbdb9ace9 100644 --- a/device/bluetooth/mk3239/BTE_platform/include/uipc.h +++ b/device/bluetooth/mk3239/BTE_platform/include/uipc.h @@ -1,7 +1,3 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - /******************************************************************************** ** * ** Name uipc.h * diff --git a/device/bluetooth/mk3239/BTE_platform/include/unv.h b/device/bluetooth/mk3239/BTE_platform/include/unv.h index d5c1b3aa75..7027492740 100644 --- a/device/bluetooth/mk3239/BTE_platform/include/unv.h +++ b/device/bluetooth/mk3239/BTE_platform/include/unv.h @@ -1,6 +1,3 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ /******************************************************************************* ** Name: unv.h diff --git a/device/bluetooth/mk3239/BTE_platform/include/upio.h b/device/bluetooth/mk3239/BTE_platform/include/upio.h index 3d889e28a9..284061cafc 100644 --- a/device/bluetooth/mk3239/BTE_platform/include/upio.h +++ b/device/bluetooth/mk3239/BTE_platform/include/upio.h @@ -1,13 +1,3 @@ -/** - * UNPUBLISHED PROPRIETARY SOURCE CODE - * Copyright (c) 2016 MXCHIP Inc. - * - * The contents of this file may not be disclosed to third parties, copied or - * duplicated in any form, in whole or in part, without the prior written - * permission of MXCHIP Corporation. - * - */ - /***************************************************************************** ** ** Name upio.h diff --git a/device/bluetooth/mk3239/BTE_platform/include/usb.h b/device/bluetooth/mk3239/BTE_platform/include/usb.h index 66645d61f0..a38e810542 100644 --- a/device/bluetooth/mk3239/BTE_platform/include/usb.h +++ b/device/bluetooth/mk3239/BTE_platform/include/usb.h @@ -1,7 +1,3 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - /******************************************************************************* ** Name: usb.h ** diff --git a/device/bluetooth/mk3239/BTE_platform/include/userial.h b/device/bluetooth/mk3239/BTE_platform/include/userial.h index e8c3363c50..f1cade1611 100644 --- a/device/bluetooth/mk3239/BTE_platform/include/userial.h +++ b/device/bluetooth/mk3239/BTE_platform/include/userial.h @@ -1,7 +1,3 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - /******************************************************************************* ** Name: userial.h ** diff --git a/device/bluetooth/mk3239/BTE_platform/include/utimer.h b/device/bluetooth/mk3239/BTE_platform/include/utimer.h index 26262777fe..34e2b57512 100644 --- a/device/bluetooth/mk3239/BTE_platform/include/utimer.h +++ b/device/bluetooth/mk3239/BTE_platform/include/utimer.h @@ -1,7 +1,3 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - /******************************************************************************* ** Name: utimer.h ** diff --git a/device/bluetooth/mk3239/BTE_platform/include/uusb.h b/device/bluetooth/mk3239/BTE_platform/include/uusb.h index d0e19da063..7f8559529e 100644 --- a/device/bluetooth/mk3239/BTE_platform/include/uusb.h +++ b/device/bluetooth/mk3239/BTE_platform/include/uusb.h @@ -1,7 +1,3 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - /******************************************************************************* ** Name: uusb.h ** diff --git a/device/bluetooth/mk3239/BTE_platform/mico_bt_bus.c b/device/bluetooth/mk3239/BTE_platform/mico_bt_bus.c index c208da7bac..8b2a901ab1 100644 --- a/device/bluetooth/mk3239/BTE_platform/mico_bt_bus.c +++ b/device/bluetooth/mk3239/BTE_platform/mico_bt_bus.c @@ -1,7 +1,3 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - /******************************************************************************* ** Name: userial_bby.c ** @@ -13,7 +9,7 @@ #include "mico.h" -#include "aos_bt_types.h" +#include "mico_bt_types.h" #include "platform_bluetooth.h" #include "platform_config.h" diff --git a/device/bluetooth/mk3239/BTE_platform/mico_bt_hcd.c b/device/bluetooth/mk3239/BTE_platform/mico_bt_hcd.c index 763d657a30..85332c4340 100644 --- a/device/bluetooth/mk3239/BTE_platform/mico_bt_hcd.c +++ b/device/bluetooth/mk3239/BTE_platform/mico_bt_hcd.c @@ -1,7 +1,3 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - #include "mico.h" #include "platform.h" #include "platform_config.h" diff --git a/device/bluetooth/mk3239/BTE_platform/mico_bt_logmsg.c b/device/bluetooth/mk3239/BTE_platform/mico_bt_logmsg.c index 087298548d..01df393c5d 100644 --- a/device/bluetooth/mk3239/BTE_platform/mico_bt_logmsg.c +++ b/device/bluetooth/mk3239/BTE_platform/mico_bt_logmsg.c @@ -1,7 +1,3 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - /***************************************************************************** ** ** Name: mico_bt_logmsg.c diff --git a/device/bluetooth/mk3239/BTE_platform/mico_bt_nvram_access.c b/device/bluetooth/mk3239/BTE_platform/mico_bt_nvram_access.c index b6f9c1e899..00046c99e9 100644 --- a/device/bluetooth/mk3239/BTE_platform/mico_bt_nvram_access.c +++ b/device/bluetooth/mk3239/BTE_platform/mico_bt_nvram_access.c @@ -1,7 +1,3 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - /***************************************************************************** ** ** Name: mico_bt_nvram_access.c @@ -21,14 +17,14 @@ #include "bt_types.h" /* This must be defined AFTER buildcfg.h */ #include "bt_trace.h" -#include "aos_bt_dev.h" +#include "mico_bt_dev.h" -#include "aos_bt_nvram_access.h" +#include "mico_bt_nvram_access.h" /** NVRAM entry for bonded device */ #pragma pack(1) typedef struct { - aos_bt_device_address_t bd_addr; /**< Device address */ + mico_bt_device_address_t bd_addr; /**< Device address */ uint8_t addr_type; /**< BLE_ADDR_PUBLIC or BLE_ADDR_RANDOM */ uint8_t device_type; /**< BT_DEVICE_TYPE_BREDR or BT_DEVICE_TYPE_BLE */ uint16_t length; /**< Length of key_blobs (link key information) */ @@ -62,22 +58,22 @@ void mico_bt_nvram_access_init() * @param[in] paired_device_list : array for getting bd address of bonded devices * @param[in/out] p_num_devices : list size of paired_device_list/total number of bonded devices stored * - * @return AOS_BT_SUCCESS or ERROR + * @return MICO_BT_SUCCESS or ERROR */ -aos_bt_result_t mico_bt_nvram_access_get_bonded_devices(aos_bt_dev_bonded_device_info_t bonded_device_list[], - uint16_t *p_num_devices) +mico_bt_result_t mico_bt_nvram_access_get_bonded_devices(mico_bt_dev_bonded_device_info_t bonded_device_list[], + uint16_t *p_num_devices) { int index, list_size = 0; mico_bt_nvram_access_entry_t *p_entry; char key[32]; - int buflen = sizeof(mico_bt_nvram_access_entry_t) + AOS_BT_DCT_MAX_KEYBLOBS; + int buflen = sizeof(mico_bt_nvram_access_entry_t) + MICO_BT_DCT_MAX_KEYBLOBS; *p_num_devices = 0; p_entry = (mico_bt_nvram_access_entry_t *)malloc(buflen); if (p_entry == NULL) { return -1; } - for (index = 0 ; index < AOS_BT_DCT_MAX_DEVICES ; index++) { + for (index = 0 ; index < MICO_BT_DCT_MAX_DEVICES ; index++) { sprintf(key, "bt_bounded_dev%d", index); if (aos_kv_get(key, p_entry, buflen) != 0) { continue; @@ -93,13 +89,13 @@ aos_bt_result_t mico_bt_nvram_access_get_bonded_devices(aos_bt_dev_bonded_device APPL_TRACE_DEBUG2("%s num bonded devices : %d", __FUNCTION__, *p_num_devices ); free(p_entry); - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } /** - * Function eico_bt_nvram_access_save_bonded_device_key + * Function mico_bt_nvram_access_save_bonded_device_key * * save link key information of bonded device * @@ -107,30 +103,30 @@ aos_bt_result_t mico_bt_nvram_access_get_bonded_devices(aos_bt_dev_bonded_device * @param[in] p_keyblobs : key blobs including key header, link keys and key length * @param[in] key_len : total length of p_keyblobs * - * @return AOS_BT_SUCCESS or ERROR + * @return MICO_BT_SUCCESS or ERROR */ -aos_bt_result_t mico_bt_nvram_access_save_bonded_device_key(aos_bt_device_address_t bd_addr, - aos_bt_ble_address_type_t addr_type, uint8_t device_type, uint8_t *p_keyblobs, uint16_t key_len) +mico_bt_result_t mico_bt_nvram_access_save_bonded_device_key(mico_bt_device_address_t bd_addr, + mico_bt_ble_address_type_t addr_type, uint8_t device_type, uint8_t *p_keyblobs, uint16_t key_len) { - int index, list_size = 0, idle_index = -1, ret = AOS_BT_SUCCESS; + int index, list_size = 0, idle_index = -1, ret = MICO_BT_SUCCESS; mico_bt_nvram_access_entry_t *p_entry; char key[32]; - int buflen = sizeof(mico_bt_nvram_access_entry_t) + AOS_BT_DCT_MAX_KEYBLOBS; + int buflen = sizeof(mico_bt_nvram_access_entry_t) + MICO_BT_DCT_MAX_KEYBLOBS; p_entry = (mico_bt_nvram_access_entry_t *)malloc(buflen); if (p_entry == NULL) { return -1; } - for (index = 0 ; index < AOS_BT_DCT_MAX_DEVICES ; index++) { + for (index = 0 ; index < MICO_BT_DCT_MAX_DEVICES ; index++) { sprintf(key, "bt_bounded_dev%d", index); if (aos_kv_get(key, p_entry, buflen) != 0) { idle_index = index; continue; } - if ( !memcmp(p_entry->bd_addr, bd_addr, sizeof(aos_bt_device_address_t) )) { // found + if ( !memcmp(p_entry->bd_addr, bd_addr, sizeof(mico_bt_device_address_t) )) { // found if ( (key_len == p_entry->length) && (memcmp( p_entry->key_blobs, p_keyblobs, key_len ) == 0)) { // same key APPL_TRACE_DEBUG0( "Same key, write ignore..." ); } else { @@ -146,7 +142,7 @@ aos_bt_result_t mico_bt_nvram_access_save_bonded_device_key(aos_bt_device_addres if (idle_index > 0) { sprintf(key, "bt_bounded_dev%d", idle_index); - memcpy(p_entry->bd_addr, bd_addr, AOS_BT_DCT_ADDR_FIELD); + memcpy(p_entry->bd_addr, bd_addr, MICO_BT_DCT_ADDR_FIELD); p_entry->addr_type = addr_type; p_entry->device_type = device_type; p_entry->length = key_len; @@ -173,36 +169,36 @@ aos_bt_result_t mico_bt_nvram_access_save_bonded_device_key(aos_bt_device_addres * @param[in] bd_addr : bd_addr of bonded device * @param[out] p_key_entry : key information stored * - * @return AOS_BT_SUCCESS or ERROR + * @return MICO_BT_SUCCESS or ERROR */ -aos_bt_result_t mico_bt_nvram_access_load_bonded_device_keys(aos_bt_device_address_t bd_addr, - mico_bt_nvram_access_entry_t *p_key_entry, uint8_t entry_max_length) +mico_bt_result_t mico_bt_nvram_access_load_bonded_device_keys(mico_bt_device_address_t bd_addr, + mico_bt_nvram_access_entry_t *p_key_entry, uint8_t entry_max_length) { - int index, ret = AOS_BT_NO_RESOURCES; + int index, ret = MICO_BT_NO_RESOURCES; mico_bt_nvram_access_entry_t *p_entry; char key[32]; - int buflen = sizeof(mico_bt_nvram_access_entry_t) + AOS_BT_DCT_MAX_KEYBLOBS; + int buflen = sizeof(mico_bt_nvram_access_entry_t) + MICO_BT_DCT_MAX_KEYBLOBS; p_entry = (mico_bt_nvram_access_entry_t *)malloc(buflen); if (p_entry == NULL) { return -1; } - for (index = 0 ; index < AOS_BT_DCT_MAX_DEVICES ; index++) { + for (index = 0 ; index < MICO_BT_DCT_MAX_DEVICES ; index++) { sprintf(key, "bt_bounded_dev%d", index); if (aos_kv_get(key, p_entry, buflen) != 0) { continue; } - if ( !memcmp(p_entry->bd_addr, bd_addr, sizeof(aos_bt_device_address_t) )) { // found + if ( !memcmp(p_entry->bd_addr, bd_addr, sizeof(mico_bt_device_address_t) )) { // found if (entry_max_length < p_entry->length) { - ret = AOS_BT_ILLEGAL_VALUE; + ret = MICO_BT_ILLEGAL_VALUE; } else { p_key_entry->addr_type = p_entry->addr_type; p_key_entry->device_type = p_entry->device_type; p_key_entry->length = p_entry->length; memcpy(p_key_entry->key_blobs, p_entry->key_blobs, p_entry->length); - ret = AOS_BT_SUCCESS; + ret = MICO_BT_SUCCESS; } } } @@ -221,29 +217,29 @@ aos_bt_result_t mico_bt_nvram_access_load_bonded_device_keys(aos_bt_device_addre * * @param[in] bd_addr : bd_addr of bonded device to be removed - * @return AOS_BT_SUCCESS or ERROR + * @return MICO_BT_SUCCESS or ERROR */ -aos_bt_result_t mico_bt_nvram_access_delete_bonded_device(aos_bt_device_address_t bd_addr) +mico_bt_result_t mico_bt_nvram_access_delete_bonded_device(mico_bt_device_address_t bd_addr) { - int index, ret = AOS_BT_NO_RESOURCES; + int index, ret = MICO_BT_NO_RESOURCES; mico_bt_nvram_access_entry_t *p_entry; char key[32]; - int buflen = sizeof(mico_bt_nvram_access_entry_t) + AOS_BT_DCT_MAX_KEYBLOBS; + int buflen = sizeof(mico_bt_nvram_access_entry_t) + MICO_BT_DCT_MAX_KEYBLOBS; p_entry = (mico_bt_nvram_access_entry_t *)malloc(buflen); if (p_entry == NULL) { return -1; } - for (index = 0 ; index < AOS_BT_DCT_MAX_DEVICES ; index++) { + for (index = 0 ; index < MICO_BT_DCT_MAX_DEVICES ; index++) { sprintf(key, "bt_bounded_dev%d", index); if (aos_kv_get(key, p_entry, buflen) != 0) { continue; } - if ( !memcmp(p_entry->bd_addr, bd_addr, sizeof(aos_bt_device_address_t) )) { // found + if ( !memcmp(p_entry->bd_addr, bd_addr, sizeof(mico_bt_device_address_t) )) { // found aos_kv_del(key); - ret = AOS_BT_SUCCESS; + ret = MICO_BT_SUCCESS; goto EXIT; } } @@ -263,18 +259,18 @@ aos_bt_result_t mico_bt_nvram_access_delete_bonded_device(aos_bt_device_address_ * * @param[out] p_lkeys: local identity key information * - * @return AOS_BT_SUCCESS or ERROR + * @return MICO_BT_SUCCESS or ERROR */ -aos_bt_result_t mico_bt_nvram_access_load_local_identity_keys(aos_bt_local_identity_keys_t *p_lkeys) +mico_bt_result_t mico_bt_nvram_access_load_local_identity_keys(mico_bt_local_identity_keys_t *p_lkeys) { int ret; - ret = aos_kv_get("bt_local_key", p_lkeys, sizeof(aos_bt_local_identity_keys_t)); + ret = aos_kv_get("bt_local_key", p_lkeys, sizeof(mico_bt_local_identity_keys_t)); if (ret != 0) { - return AOS_BT_NO_RESOURCES; + return MICO_BT_NO_RESOURCES; } else { - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } } @@ -286,18 +282,18 @@ aos_bt_result_t mico_bt_nvram_access_load_local_identity_keys(aos_bt_local_ident * * @param[in] p_lkeys : local identity key information * - * @return AOS_BT_SUCCESS or ERROR + * @return MICO_BT_SUCCESS or ERROR */ -aos_bt_result_t mico_bt_nvram_access_save_local_identity_keys(aos_bt_local_identity_keys_t *p_lkeys) +mico_bt_result_t mico_bt_nvram_access_save_local_identity_keys(mico_bt_local_identity_keys_t *p_lkeys) { int ret; - ret = aos_kv_set("bt_local_key", p_lkeys, sizeof(aos_bt_local_identity_keys_t), 1); + ret = aos_kv_set("bt_local_key", p_lkeys, sizeof(mico_bt_local_identity_keys_t), 1); if (ret != 0) { - return AOS_BT_NO_RESOURCES; + return MICO_BT_NO_RESOURCES; } else { - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } } @@ -313,18 +309,18 @@ aos_bt_result_t mico_bt_nvram_access_save_local_identity_keys(aos_bt_local_ident * * @return TRUE if there is available space or FALSE */ -BOOLEAN mico_bt_nvram_access_key_storage_available(aos_bt_device_address_t bd_addr, int req_size) +BOOLEAN mico_bt_nvram_access_key_storage_available(mico_bt_device_address_t bd_addr, int req_size) { int index, found = 0; mico_bt_nvram_access_entry_t *p_entry; char key[32]; - int buflen = sizeof(mico_bt_nvram_access_entry_t) + AOS_BT_DCT_MAX_KEYBLOBS; + int buflen = sizeof(mico_bt_nvram_access_entry_t) + MICO_BT_DCT_MAX_KEYBLOBS; p_entry = (mico_bt_nvram_access_entry_t *)malloc(buflen); if (p_entry == NULL) { return -1; } - for (index = 0 ; index < AOS_BT_DCT_MAX_DEVICES ; index++) { + for (index = 0 ; index < MICO_BT_DCT_MAX_DEVICES ; index++) { sprintf(key, "bt_bounded_dev%d", index); if (aos_kv_get(key, p_entry, buflen) != 0) { found = 1; @@ -349,10 +345,10 @@ BOOLEAN mico_bt_nvram_access_key_storage_available(aos_bt_device_address_t bd_ad * @param[out] p_index : index of stored key * @param[out] p_key_entry : key information stored * - * @return AOS_BT_SUCCESS or ERROR + * @return MICO_BT_SUCCESS or ERROR */ -aos_bt_result_t mico_bt_nvram_access_enum_bonded_device_keys(int8_t *p_index, mico_bt_nvram_access_entry_t *p_key_entry, - uint8_t entry_max_length) +mico_bt_result_t mico_bt_nvram_access_enum_bonded_device_keys(int8_t *p_index, + mico_bt_nvram_access_entry_t *p_key_entry, uint8_t entry_max_length) { static int8_t enum_index = 0; char key[32]; @@ -361,14 +357,14 @@ aos_bt_result_t mico_bt_nvram_access_enum_bonded_device_keys(int8_t *p_index, mi sprintf(key, "bt_bounded_dev%d", enum_index); enum_index++; - if (enum_index == AOS_BT_DCT_MAX_KEYBLOBS) { + if (enum_index == MICO_BT_DCT_MAX_KEYBLOBS) { enum_index = 0; } if (aos_kv_get(key, p_key_entry, entry_max_length + sizeof(*p_key_entry)) != 0) { return -1; } - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } /** @@ -381,25 +377,25 @@ aos_bt_result_t mico_bt_nvram_access_enum_bonded_device_keys(int8_t *p_index, mi * * @return TRUE if found or FALSE */ -mico_bool_t mico_bt_nvram_access_find_device( aos_bt_device_address_t key_bdaddr ) +mico_bool_t mico_bt_nvram_access_find_device( mico_bt_device_address_t key_bdaddr ) { int index, list_size = 0; mico_bt_nvram_access_entry_t *p_entry; char key[32]; - int buflen = sizeof(mico_bt_nvram_access_entry_t) + AOS_BT_DCT_MAX_KEYBLOBS; + int buflen = sizeof(mico_bt_nvram_access_entry_t) + MICO_BT_DCT_MAX_KEYBLOBS; mico_bool_t found_keyblobs = FALSE; p_entry = (mico_bt_nvram_access_entry_t *)malloc(buflen); if (p_entry == NULL) { return -1; } - for (index = 0 ; index < AOS_BT_DCT_MAX_DEVICES ; index++) { + for (index = 0 ; index < MICO_BT_DCT_MAX_DEVICES ; index++) { sprintf(key, "bt_bounded_dev%d", index); if (aos_kv_get(key, p_entry, buflen) != 0) { continue; } - if ( !memcmp(p_entry->bd_addr, key_bdaddr, sizeof(aos_bt_device_address_t) )) { // found + if ( !memcmp(p_entry->bd_addr, key_bdaddr, sizeof(mico_bt_device_address_t) )) { // found found_keyblobs = TRUE; break; } diff --git a/device/bluetooth/mk3239/BTE_platform/mico_upio.c b/device/bluetooth/mk3239/BTE_platform/mico_upio.c index cbd6adc6b4..874c468ca6 100644 --- a/device/bluetooth/mk3239/BTE_platform/mico_upio.c +++ b/device/bluetooth/mk3239/BTE_platform/mico_upio.c @@ -1,7 +1,3 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - /***************************************************************************** ** ** Name upio_bby.c @@ -12,7 +8,7 @@ ** *****************************************************************************/ #include "buildcfg.h" -#include "aos_bt_dev.h" +#include "mico_bt_dev.h" #include "include/upio.h" #include "platform_bluetooth.h" diff --git a/device/bluetooth/mk3239/aosbt_shim_layer/aosbt_shim_layer.c b/device/bluetooth/mk3239/aosbt_shim_layer/aosbt_shim_layer.c deleted file mode 100644 index 2ef58b1e7f..0000000000 --- a/device/bluetooth/mk3239/aosbt_shim_layer/aosbt_shim_layer.c +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#include "aos_bt_ble.h" -#include "aos_bt_dev.h" -#include "aos_bt_gatt.h" -//#include "aos_bt_int.h" -//include "aos_bt_l2c.h" -//#include "aos_bt_rfcomm.h" -#include "aos_bt_sco.h" -#include "aos_bt_sdp.h" -#include "aos_bt_stack.h" -#include "aos_bt_nvram_access.h" - -void aos_bt_dev_read_local_addr (aos_bt_device_address_t bd_addr) -{ - mico_bt_dev_read_local_addr(bd_addr); -} - -void aos_bt_ble_security_grant(aos_bt_device_address_t bd_addr, uint8_t res) -{ - mico_bt_ble_security_grant(bd_addr, res); -} - -void aos_bt_dev_pass_key_req_reply(aos_bt_result_t res, aos_bt_device_address_t bd_addr, uint32_t passkey) -{ - mico_bt_dev_pass_key_req_reply(res, bd_addr, passkey); -} - -void aos_bt_dev_confirm_req_reply(aos_bt_result_t res, aos_bt_device_address_t bd_addr) -{ - mico_bt_dev_confirm_req_reply(res, bd_addr); -} - -aos_bt_result_t aos_bt_stack_init(aos_bt_management_cback_t *p_bt_management_cback, - const aos_bt_cfg_settings_t *p_bt_cfg_settings, - const aos_bt_cfg_buf_pool_t aos_bt_cfg_buf_pools[AOS_BT_CFG_NUM_BUF_POOLS]) -{ - return mico_bt_stack_init(p_bt_management_cback, p_bt_cfg_settings, aos_bt_cfg_buf_pools); -} - -aos_bt_gatt_status_t aos_bt_gatt_send_indication_confirm (uint16_t conn_id, uint16_t handle) -{ - return mico_bt_gatt_send_indication_confirm(conn_id, handle); -} - -aos_bt_gatt_status_t aos_bt_gatt_register (aos_bt_gatt_app_interface_t gatt_if, aos_bt_gatt_cback_t *p_gatt_cback) -{ - return mico_bt_gatt_register(gatt_if, p_gatt_cback); -} - -aos_bt_ble_scan_type_t aos_bt_ble_get_current_scan_state(void) -{ - return mico_bt_ble_get_current_scan_state(); -} - -aos_bt_result_t aos_bt_ble_scan (aos_bt_ble_scan_type_t scan_type, aos_bool_t duplicate_filter_enable, - aos_bt_ble_scan_result_cback_t *p_scan_result_cback) -{ - return mico_bt_ble_scan(scan_type, duplicate_filter_enable, p_scan_result_cback); -} - -aos_bt_gatt_status_t aos_bt_gatt_disconnect (uint16_t conn_id) -{ - return mico_bt_gatt_disconnect(conn_id); -} - -aos_bt_gatt_status_t aos_bt_gatt_db_init (const uint8_t *p_gatt_db, uint16_t gatt_db_size) -{ - return mico_bt_gatt_db_init(p_gatt_db, gatt_db_size); -} - -aos_bt_result_t aos_bt_ble_set_advertisement_data(aos_bt_ble_advert_mask_t data_mask, - aos_bt_ble_advert_data_t *p_data) -{ - return mico_bt_ble_set_advertisement_data(data_mask, p_data); -} - -aos_bt_dev_status_t aos_bt_ble_set_scan_response_data(aos_bt_ble_advert_mask_t data_mask, - aos_bt_ble_advert_data_t *p_data) -{ - return mico_bt_ble_set_scan_response_data(data_mask, p_data); -} - -aos_bt_result_t aos_bt_dev_sec_bond (aos_bt_device_address_t bd_addr, aos_bt_ble_address_type_t bd_addr_type, - aos_bt_transport_t transport, uint8_t pin_len, uint8_t *p_pin) -{ - return mico_bt_dev_sec_bond(bd_addr, bd_addr_type, transport, pin_len, p_pin); -} - -aos_bt_result_t aos_bt_dev_set_encryption (aos_bt_device_address_t bd_addr, aos_bt_transport_t transport, - void *p_ref_data) -{ - return mico_bt_dev_set_encryption(bd_addr, transport, p_ref_data); -} - -aos_bool_t aos_bt_dev_find_bonded_device( aos_bt_device_address_t bd_addr) -{ - return mico_bt_dev_find_bonded_device(bd_addr); -} - -aos_bt_result_t aos_bt_start_advertisements(aos_bt_ble_advert_mode_t advert_mode, - aos_bt_ble_address_type_t directed_advertisement_bdaddr_type, - aos_bt_device_address_ptr_t directed_advertisement_bdaddr_ptr) -{ - return mico_bt_start_advertisements(advert_mode, directed_advertisement_bdaddr_type, directed_advertisement_bdaddr_ptr); -} - -aos_bool_t aos_bt_ble_update_advertising_white_list(aos_bool_t add, const aos_bt_device_address_t remote_bda) -{ - return mico_bt_ble_update_advertising_white_list(add, remote_bda); -} - -aos_bt_result_t aos_bt_dev_sec_bond_cancel (aos_bt_device_address_t bd_addr) -{ - return mico_bt_dev_sec_bond_cancel(bd_addr); -} - -aos_bt_result_t aos_bt_dev_delete_bonded_device(aos_bt_device_address_t bd_addr) -{ - return mico_bt_dev_delete_bonded_device(bd_addr); -} - -aos_bt_gatt_status_t aos_bt_gatt_send_discover (uint16_t conn_id, - aos_bt_gatt_discovery_type_t discovery_type, - aos_bt_gatt_discovery_param_t *p_discovery_param ) -{ - return mico_bt_gatt_send_discover(conn_id, discovery_type, p_discovery_param); -} - -aos_bt_gatt_status_t aos_bt_gatt_send_read (uint16_t conn_id, aos_bt_gatt_read_type_t type, - aos_bt_gatt_read_param_t *p_read) -{ - return mico_bt_gatt_send_read(conn_id, type, p_read); -} - -aos_bt_gatt_status_t aos_bt_gatt_send_write (uint16_t conn_id, aos_bt_gatt_write_type_t type, - aos_bt_gatt_value_t *p_write) -{ - return mico_bt_gatt_send_write(conn_id, type, p_write); -} - -aos_bool_t aos_bt_ble_update_background_connection_device(aos_bool_t add_remove, aos_bt_device_address_t remote_bda) -{ - return mico_bt_ble_update_background_connection_device(add_remove, remote_bda); -} - -aos_bool_t aos_bt_gatt_cancel_connect (aos_bt_device_address_t bd_addr, aos_bool_t is_direct) -{ - return mico_bt_gatt_cancel_connect(bd_addr, is_direct); -} - -aos_bool_t aos_bt_gatt_le_connect (aos_bt_device_address_t bd_addr, - aos_bt_ble_address_type_t bd_addr_type, - aos_bt_ble_conn_mode_t conn_mode, - aos_bool_t is_direct) -{ - return mico_bt_gatt_le_connect(bd_addr, bd_addr_type, conn_mode, is_direct); -} - -aos_bt_result_t aos_bt_dev_read_tx_power (aos_bt_device_address_t remote_bda, aos_bt_transport_t transport, - aos_bt_dev_cmpl_cback_t *p_cback) -{ - return mico_bt_dev_read_tx_power(remote_bda, transport, p_cback); -} - -aos_bt_result_t aos_bt_dev_read_rssi (aos_bt_device_address_t remote_bda, aos_bt_transport_t transport, - aos_bt_dev_cmpl_cback_t *p_cback) -{ - return mico_bt_dev_read_rssi(remote_bda, transport, p_cback); -} - -aos_bt_gatt_status_t aos_bt_gatt_send_indication (uint16_t conn_id, uint16_t attr_handle, uint16_t *val_len, - uint8_t *p_val ) -{ - return mico_bt_gatt_send_indication(conn_id, attr_handle, val_len, p_val); -} - -aos_bt_result_t aos_bt_dev_get_bonded_devices(aos_bt_dev_bonded_device_info_t *p_paired_device_list, - uint16_t *p_num_devices) -{ - return mico_bt_dev_get_bonded_devices(p_paired_device_list, p_num_devices); -} - -aos_bt_result_t aos_bt_dev_get_key_by_keytype(aos_bt_device_address_t bd_addr, aos_bt_dev_le_key_type_t key_type, - aos_bt_security_key_value_t *p_sec_keys) -{ - return mico_bt_dev_get_key_by_keytype(bd_addr, key_type, p_sec_keys); -} - -aos_bool_t aos_bt_ble_get_background_connection_device_size(uint8_t *size) -{ - return mico_bt_ble_get_background_connection_device_size(size); -} - -uint8_t *aos_bt_ble_check_advertising_data( uint8_t *p_adv, aos_bt_ble_advert_type_t type, uint8_t *p_length) -{ - return mico_bt_ble_check_advertising_data(p_adv, type, p_length); -} diff --git a/device/bluetooth/mk3239/aosbt_shim_layer/aosbt_shim_layer.mk b/device/bluetooth/mk3239/aosbt_shim_layer/aosbt_shim_layer.mk deleted file mode 100644 index 0566766e64..0000000000 --- a/device/bluetooth/mk3239/aosbt_shim_layer/aosbt_shim_layer.mk +++ /dev/null @@ -1,3 +0,0 @@ -NAME := aosbt_shim_layer - -$(NAME)_SOURCES += aosbt_shim_layer.c diff --git a/device/bluetooth/mk3239/ble_access/ble_access.mk b/device/bluetooth/mk3239/ble_access/ble_access.mk index a0f449d0cf..da87c64aec 100644 --- a/device/bluetooth/mk3239/ble_access/ble_access.mk +++ b/device/bluetooth/mk3239/ble_access/ble_access.mk @@ -1,9 +1,9 @@ -NAME := ble_access_core +NAME := Lib_Ble_Access_Core_Framework GLOBAL_INCLUDES += . $(NAME)_SOURCES := ble_access_core.c \ - ble_access_core_i.c + ble_access_core_i.c -$(NAME)_COMPONENTS := bluetooth.smartbt \ - bluetooth.mk3239.low_energy +$(NAME)_COMPONENTS := framework/bluetooth/bt_smart \ + framework/bluetooth/low_energy diff --git a/device/bluetooth/mk3239/ble_access/ble_access_core.c b/device/bluetooth/mk3239/ble_access/ble_access_core.c index 4e5815dbc4..b14b943019 100644 --- a/device/bluetooth/mk3239/ble_access/ble_access_core.c +++ b/device/bluetooth/mk3239/ble_access/ble_access_core.c @@ -1,16 +1,13 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - #include #include -#include "smartbt.h" -#include "smartbt_cfg.h" -#include "smartbt_smart_attribute.h" -#include "smartbt_smart_interface.h" -#include "smartbt_smartbridge.h" -#include "smartbt_smartbridge_gatt.h" +#include "mico.h" +#include "mico_bt.h" +#include "mico_bt_cfg.h" +#include "mico_bt_smart_attribute.h" +#include "mico_bt_smart_interface.h" +#include "mico_bt_smartbridge.h" +#include "mico_bt_smartbridge_gatt.h" #include "sdpdefs.h" #include "gattdefs.h" @@ -20,10 +17,6 @@ #include "ble_access_core.h" #include "ble_access_core_i.h" -#ifndef MIN -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#endif - /* *------------------------------------------------------------------------------------------------- * @@ -70,18 +63,18 @@ /* Local function prototype */ static OSStatus ble_access_connection_handler (void *arg); -static OSStatus ble_access_disconnection_handler (aos_bt_smartbridge_socket_t *socket); -static OSStatus ble_access_notification_handler (aos_bt_smartbridge_socket_t *socket, uint16_t attribute_handle); +static OSStatus ble_access_disconnection_handler (mico_bt_smartbridge_socket_t *socket); +static OSStatus ble_access_notification_handler (mico_bt_smartbridge_socket_t *socket, uint16_t attribute_handle); static OSStatus ble_access_scan_complete_handler (void *arg); -static OSStatus ble_access_scan_result_handler (const aos_bt_smart_advertising_report_t *result); +static OSStatus ble_access_scan_result_handler (const mico_bt_smart_advertising_report_t *result); -static OSStatus ble_access_auto_conn_parms_handler (const aos_bt_device_address_t device_address, +static OSStatus ble_access_auto_conn_parms_handler (const mico_bt_device_address_t device_address, const char *name, const uint8_t *p_adv_data, const uint8_t length, - aos_bt_smartbridge_auto_conn_cback_parms_t *parm); + mico_bt_smartbridge_auto_conn_cback_parms_t *parm); -static OSStatus ble_access_auto_connection_handler (aos_bt_smartbridge_socket_t *socket); +static OSStatus ble_access_auto_connection_handler (mico_bt_smartbridge_socket_t *socket); static OSStatus ble_access_timer_event_handle (void *arg); static OSStatus ble_access_send_bt_event (uint8_t evt_code, const ble_access_evt_parms_t *parms ); @@ -100,7 +93,7 @@ static OSStatus ble_access_send_command (const ble_access_device_t * */ /* SmartBridge security settings */ -const aos_bt_smart_security_settings_t ble_access_security_settings = { +const mico_bt_smart_security_settings_t ble_access_security_settings = { .timeout_second = 15, .io_capabilities = BT_SMART_IO_DISPLAY_ONLY,//BT_SMART_IO_NO_INPUT_NO_OUTPUT, .authentication_requirements = AUTHENTICATION_REQUIREMENTS, @@ -111,13 +104,13 @@ const aos_bt_smart_security_settings_t ble_access_security_settings = { }; /* SmartBridge connection settings */ -static const aos_bt_smart_connection_settings_t ble_access_connection_settings = { +static const mico_bt_smart_connection_settings_t ble_access_connection_settings = { .timeout_second = 10, .filter_policy = FILTER_POLICY_WHITE_LIST, - .interval_min = 32,//AOS_BT_CFG_DEFAULT_CONN_MIN_INTERVAL, - .interval_max = 64,//AOS_BT_CFG_DEFAULT_CONN_MAX_INTERVAL, - .latency = AOS_BT_CFG_DEFAULT_CONN_LATENCY, - .supervision_timeout = AOS_BT_CFG_DEFAULT_CONN_SUPERVISION_TIMEOUT, + .interval_min = 32,//MICO_BT_CFG_DEFAULT_CONN_MIN_INTERVAL, + .interval_max = 64,//MICO_BT_CFG_DEFAULT_CONN_MAX_INTERVAL, + .latency = MICO_BT_CFG_DEFAULT_CONN_LATENCY, + .supervision_timeout = MICO_BT_CFG_DEFAULT_CONN_SUPERVISION_TIMEOUT, .ce_length_min = 0, .ce_length_max = 0, .attribute_protocol_timeout_ms = 10000, @@ -135,7 +128,7 @@ static const aos_bt_smart_connection_settings_t ble_access_connection_settings = // #define BLE_BATTERY_LEVEL_CHAR_UUID_IDX 3 /* All services UUID */ -const aos_bt_uuid_t ble_access_cache_services_uuid[] = { +const mico_bt_uuid_t ble_access_cache_services_uuid[] = { // [BLE_ACCESS_SERV_UUID_IDX] = { // .len = LEN_UUID_128, // .uu.uuid128 = { UUID_MXCHIP_ALERT_NOTIFICATION_SERVICE }, @@ -151,7 +144,7 @@ const aos_bt_uuid_t ble_access_cache_services_uuid[] = { }; /* All characteristic UUID */ -const aos_bt_uuid_t ble_access_cache_chars_uuid[] = { +const mico_bt_uuid_t ble_access_cache_chars_uuid[] = { // [BLE_ACCESS_CHAR_UUID_IDX] = { // .len = LEN_UUID_128, // .uu.uuid128 = { UUID_MXCHIP_ALERT_NOTIFICATION_CHAR }, @@ -194,7 +187,7 @@ const aos_bt_uuid_t ble_access_cache_chars_uuid[] = { static ble_access_event_callback_t ble_access_callback; static uint8_t ble_access_app_state; -static aos_bt_device_address_t ble_access_local_address; +static mico_bt_device_address_t ble_access_local_address; /* @@ -210,24 +203,24 @@ OSStatus ble_access_bluetooth_init(void) OSStatus err = kNoErr; ble_access_device_t *dev = NULL; - aos_bt_dev_bonded_device_info_t paired_device_list[MAX_CONCURRENT_CONNECTIONS]; + mico_bt_dev_bonded_device_info_t paired_device_list[MAX_CONCURRENT_CONNECTIONS]; uint16_t paired_device_num = MAX_CONCURRENT_CONNECTIONS, idx = 0; - /* Initialize AOS Bluetooth Framework */ - err = aos_bt_init(AOS_BT_HCI_MODE, "BLE Access Center", MAX_CONCURRENT_CONNECTIONS, 0); - require_noerr_string(err, exit, "Initializing AOS bluetooth Framework failed"); + /* Initialize MiCO Bluetooth Framework */ + err = mico_bt_init(MICO_BT_HCI_MODE, "BLE Access Center", MAX_CONCURRENT_CONNECTIONS, 0); + require_noerr_string(err, exit, "Initializing MiCO bluetooth Framework failed"); - /* Initialize AOS BT Smart Bridge Framework */ - err = aos_bt_smartbridge_init(MAX_CONCURRENT_CONNECTIONS); - require_noerr_string(err, exit, "Initializing AOS BT Smart Bridge Framework failed"); + /* Initialize MiCO BT Smart Bridge Framework */ + err = mico_bt_smartbridge_init(MAX_CONCURRENT_CONNECTIONS); + require_noerr_string(err, exit, "Initializing MiCO BT Smart Bridge Framework failed"); /* Get Local device address */ - aos_bt_device_get_address(&ble_access_local_address); + mico_bt_device_get_address(&ble_access_local_address); - printf("Initialize BLE Access Core Successfully"); + ble_access_log("Initialize BLE Access Core Successfully"); /* Enable Attribute Cache and set maximum number of caches */ - err = aos_bt_smartbridge_enable_attribute_cache(MAX_CONCURRENT_CONNECTIONS, NULL, 0); + err = mico_bt_smartbridge_enable_attribute_cache(MAX_CONCURRENT_CONNECTIONS, NULL, 0); require_noerr_string(err, exit, "Enable Attribute Cache failed"); /* Create a worker thread for making a connection */ @@ -246,14 +239,14 @@ OSStatus ble_access_bluetooth_init(void) ble_access_initialize_devices(); /* Update BLE Controller White List */ - aos_bt_dev_get_bonded_devices(paired_device_list, &paired_device_num); + mico_bt_dev_get_bonded_devices(paired_device_list, &paired_device_num); for (idx = 0; idx < paired_device_num; idx++) { #if defined(BLE_ACCESS_DEBUG) && BLE_ACCESS_DEBUG == 1 - printf("WL: [%02x:%02x:%02x:%02x:%02x:%02x, %lu]", - paired_device_list[idx].bd_addr[0], paired_device_list[idx].bd_addr[1], paired_device_list[idx].bd_addr[2], - paired_device_list[idx].bd_addr[3], paired_device_list[idx].bd_addr[4], paired_device_list[idx].bd_addr[5], - ble_access_calculate_device_id(paired_device_list[idx].bd_addr)); + ble_access_log("WL: [%02x:%02x:%02x:%02x:%02x:%02x, %lu]", + paired_device_list[idx].bd_addr[0], paired_device_list[idx].bd_addr[1], paired_device_list[idx].bd_addr[2], + paired_device_list[idx].bd_addr[3], paired_device_list[idx].bd_addr[4], paired_device_list[idx].bd_addr[5], + ble_access_calculate_device_id(paired_device_list[idx].bd_addr)); #endif dev = ble_access_get_free_device(); @@ -264,7 +257,7 @@ OSStatus ble_access_bluetooth_init(void) dev->auth_state = BLE_ACCESS_AUTH_STATE_SUCC; /* Update BLE Controller White List */ - aos_bt_ble_update_background_connection_device(AOS_TRUE, paired_device_list[idx].bd_addr); + mico_bt_ble_update_background_connection_device(MICO_TRUE, paired_device_list[idx].bd_addr); } exit: @@ -311,10 +304,10 @@ OSStatus ble_access_bluetooth_request(uint8_t request, const ble_access_cmd_parm uint8_t timeout[4]; uint8_t *p_timeout = 0; - aos_bt_smartbridge_socket_status_t status; - aos_bt_smart_scan_settings_t scan_settings; - aos_bt_smart_device_t *device = NULL; - aos_bt_device_address_t device_address; + mico_bt_smartbridge_socket_status_t status; + mico_bt_smart_scan_settings_t scan_settings; + mico_bt_smart_device_t *device = NULL; + mico_bt_device_address_t device_address; ble_access_device_t *dev = NULL; @@ -322,10 +315,10 @@ OSStatus ble_access_bluetooth_request(uint8_t request, const ble_access_cmd_parm uint8_t size = 0; #endif - printf("User Request - %s[%#x] to %s device.", - print_request_str(request), - request, - parms == NULL ? "all" : "specificed"); + ble_access_log("User Request - %s[%#x] to %s device.", + print_request_str(request), + request, + parms == NULL ? "all" : "specificed"); if (request == BLE_ACCESS_REQ_DEV_ADD || request == BLE_ACCESS_REQ_DEV_DISC @@ -333,7 +326,7 @@ OSStatus ble_access_bluetooth_request(uint8_t request, const ble_access_cmd_parm /* Check Parameters */ if (parms == NULL) { - printf("Invalid Parameters"); + ble_access_log("Invalid Parameters"); return kParamErr; } @@ -342,9 +335,9 @@ OSStatus ble_access_bluetooth_request(uint8_t request, const ble_access_cmd_parm require_noerr_string(err, exit, "Invalid device ID"); #if defined(BLE_ACCESS_DEBUG) && BLE_ACCESS_DEBUG == 1 char *device_address_str = NULL; - printf("Generate device address: device_id = %lu", parms->device_id); + ble_access_log("Generate device address: device_id = %lu", parms->device_id); device_address_str = DataToHexStringWithColons(device_address, 6); - printf("device_address: %s", device_address_str); + ble_access_log("device_address: %s", device_address_str); free(device_address_str); #endif } @@ -359,7 +352,7 @@ OSStatus ble_access_bluetooth_request(uint8_t request, const ble_access_cmd_parm /* Stop scanning procedure. */ if (!parms->p.start) { - aos_bt_smartbridge_stop_scan(); + mico_bt_smartbridge_stop_scan(); break; } @@ -369,10 +362,10 @@ OSStatus ble_access_bluetooth_request(uint8_t request, const ble_access_cmd_parm } /* start to scanning */ - ble_access_set_scan_cfg(&scan_settings, AOS_FALSE); - aos_bt_smartbridge_start_scan(&scan_settings, - ble_access_scan_complete_handler, - ble_access_scan_result_handler); + ble_access_set_scan_cfg(&scan_settings, MICO_FALSE); + mico_bt_smartbridge_start_scan(&scan_settings, + ble_access_scan_complete_handler, + ble_access_scan_result_handler); ble_access_app_state = BLE_ACCESS_APP_STATE_ADD; break; case BLE_ACCESS_REQ_DEV_ADD: @@ -398,7 +391,7 @@ OSStatus ble_access_bluetooth_request(uint8_t request, const ble_access_cmd_parm UINT32_TO_STREAM(p_timeout, parms->p.timeout); err = ble_access_send_command(dev, BLE_ACCESS_CODE_DISC, sizeof(uint32_t), (uint8_t *)timeout); if (err != kNoErr) { - printf("Send a command failed, ret = %d", err); + ble_access_log("Send a command failed, ret = %d", err); goto exit; } break; @@ -413,36 +406,36 @@ OSStatus ble_access_bluetooth_request(uint8_t request, const ble_access_cmd_parm require_action_string(dev != NULL, exit, err = kConnectionErr, "Not a connection"); /* Delete it from the White List. */ - aos_bt_smartbridge_get_socket_status(&dev->socket, &status); + mico_bt_smartbridge_get_socket_status(&dev->socket, &status); require_string(status == SMARTBRIDGE_SOCKET_CONNECTED || status == SMARTBRIDGE_SOCKET_DISCONNECTED, exit, "This socket is busy!!"); if (status == SMARTBRIDGE_SOCKET_CONNECTED) { - aos_bt_smartbridge_disconnect(&dev->socket, AOS_TRUE); + mico_bt_smartbridge_disconnect(&dev->socket, MICO_TRUE); } else { - aos_bt_ble_update_background_connection_device(AOS_FALSE, device_address); + mico_bt_ble_update_background_connection_device(MICO_FALSE, device_address); } - aos_bt_dev_delete_bonded_device(device_address); - ble_access_release_device(AOS_TRUE, dev); + mico_bt_dev_delete_bonded_device(device_address); + ble_access_release_device(MICO_TRUE, dev); break; case BLE_ACCESS_REQ_DEV_START_AUTO: /* Change state */ ble_access_app_state = BLE_ACCESS_APP_STATE_AUTO_CONN; - aos_bt_smartbridge_stop_scan(); + mico_bt_smartbridge_stop_scan(); /* Start auto connection action. */ #if defined(BLE_ACCESS_DEBUG) && BLE_ACCESS_DEBUG == 1 - err = aos_bt_smartbridge_get_background_connection_devices_size(&size); + err = mico_bt_smartbridge_get_background_connection_devices_size(&size); require_noerr_string(err, exit, "Get white list size unsuccessfully!!"); - printf("white list size: %d", size); + ble_access_log("white list size: %d", size); #endif /* Set auto connection */ - ble_access_set_scan_cfg(&scan_settings, AOS_TRUE); - err = aos_bt_smartbridge_set_auto_connection_action(TRUE, &scan_settings, - ble_access_auto_conn_parms_handler); + ble_access_set_scan_cfg(&scan_settings, MICO_TRUE); + err = mico_bt_smartbridge_set_auto_connection_action(TRUE, &scan_settings, + ble_access_auto_conn_parms_handler); require_noerr_string(err, exit, "Start auto connection type unsuccessfully!!"); - printf("Start to establish background connection..."); + ble_access_log("Start to establish background connection..."); break; case BLE_ACCESS_REQ_DEV_STOP_AUTO: /* Change state */ @@ -454,17 +447,17 @@ OSStatus ble_access_bluetooth_request(uint8_t request, const ble_access_cmd_parm /* Stop */ #if defined(BLE_ACCESS_DEBUG) && BLE_ACCESS_DEBUG == 1 - err = aos_bt_smartbridge_get_background_connection_devices_size(&size); + err = mico_bt_smartbridge_get_background_connection_devices_size(&size); require_noerr_string(err, exit, "Get white list size unsuccessfully!!"); - printf("white list size: %d\n", size); + ble_access_log("white list size: %d\n", size); #endif - err = aos_bt_smartbridge_set_auto_connection_action(FALSE, NULL, NULL); + err = mico_bt_smartbridge_set_auto_connection_action(FALSE, NULL, NULL); require_noerr_string(err, exit, "Stop auto connection type unsuccessfully!!"); - printf("Stop to establish background connection..."); + ble_access_log("Stop to establish background connection..."); break; default: - printf("Unsupported Request!"); + ble_access_log("Unsupported Request!"); break; } @@ -472,11 +465,11 @@ OSStatus ble_access_bluetooth_request(uint8_t request, const ble_access_cmd_parm return err; } -static void ble_access_attribute_copy_from_smart(const aos_bt_smart_attribute_t *from, ble_access_attribute_t *to) +static void ble_access_attribute_copy_from_smart(const mico_bt_smart_attribute_t *from, ble_access_attribute_t *to) { if (from != NULL && to != NULL) { to->handle = from->handle; - memcpy(&to->type, &from->type, sizeof(aos_bt_uuid_t)); + memcpy(&to->type, &from->type, sizeof(mico_bt_uuid_t)); to->permission = from->permission; to->value_length = from->value_length; to->value_struct_size = from->value_struct_size; @@ -491,9 +484,9 @@ OSStatus ble_access_get_characteritic_by_uuid(uint32_t dev_id, ble_access_attribute_t *attr) { uint8_t buf[ATTR_CHARACTERISTIC_VALUE_SIZE(BLE_ACCESS_MAX_ATTR_VALUE_LENGTH)] = {0}; - aos_bt_smart_attribute_t *attribute = (aos_bt_smart_attribute_t *)buf; + mico_bt_smart_attribute_t *attribute = (mico_bt_smart_attribute_t *)buf; - aos_bt_device_address_t device_address; + mico_bt_device_address_t device_address; ble_access_device_t *dev = NULL; OSStatus err = kNoErr; @@ -511,12 +504,12 @@ OSStatus ble_access_get_characteritic_by_uuid(uint32_t dev_id, require_action_string(dev != NULL, exit, err = kConnectionErr, "Not a connection"); attribute->value_struct_size = BLE_ACCESS_MAX_ATTR_VALUE_LENGTH; - err = aos_bt_smartbridge_get_characteritics_from_attribute_cache_by_uuid( + err = mico_bt_smartbridge_get_characteritics_from_attribute_cache_by_uuid( &dev->socket, - (aos_bt_uuid_t *)uuid, + (mico_bt_uuid_t *)uuid, serv->start_handle, serv->end_handle, - (aos_bt_smart_attribute_t *)attribute, + (mico_bt_smart_attribute_t *)attribute, ATTR_CHARACTERISTIC_VALUE_SIZE(BLE_ACCESS_MAX_ATTR_VALUE_LENGTH)); if (err == kNoErr) { ble_access_attribute_copy_from_smart(attribute, attr); @@ -533,15 +526,15 @@ static OSStatus ble_access_characteristic_aync_event(void *arg) uint32_t dev_id; ble_access_serv_t serv; OSStatus err = kNoErr; - aos_bt_device_address_t device_address; + mico_bt_device_address_t device_address; uint8_t buf[ATTR_CHARACTERISTIC_VALUE_SIZE(BLE_ACCESS_MAX_ATTR_VALUE_LENGTH)] = {0}; - aos_bt_smart_attribute_t *attribute = (aos_bt_smart_attribute_t *)buf; + mico_bt_smart_attribute_t *attribute = (mico_bt_smart_attribute_t *)buf; ble_access_attribute_t attr; uint16_t start_handle, end_handle; - aos_bt_uuid_t characteristic_uuid = { + mico_bt_uuid_t characteristic_uuid = { .len = LEN_UUID_16, .uu.uuid16 = GATT_UUID_CHAR_DECLARE }; @@ -561,7 +554,7 @@ static OSStatus ble_access_characteristic_aync_event(void *arg) if (!dev) { err = kConnectionErr; parms.status = BLE_ACCESS_STATUS_NO_CONNECTION; - printf("Not a connection"); + ble_access_log("Not a connection"); goto exit; } @@ -572,14 +565,14 @@ static OSStatus ble_access_characteristic_aync_event(void *arg) /* Find service */ attribute->value_struct_size = BLE_ACCESS_MAX_ATTR_VALUE_LENGTH; - while ((err = aos_bt_smartbridge_get_attribute_cache_by_uuid( + while ((err = mico_bt_smartbridge_get_attribute_cache_by_uuid( &dev->socket, &characteristic_uuid, start_handle, end_handle, attribute, ATTR_CHARACTERISTIC_VALUE_SIZE(BLE_ACCESS_MAX_ATTR_VALUE_LENGTH))) - == AOS_BT_SUCCESS) { + == MICO_BT_SUCCESS) { /* Notify */ ble_access_attribute_copy_from_smart(attribute, &attr); @@ -610,7 +603,7 @@ OSStatus ble_access_get_characteristics(uint32_t dev_id, const ble_access_serv_t p = (uint8_t *)malloc(sizeof(ble_access_serv_t) + sizeof(uint32_t)); if (!p) { - printf("Malloc failed"); + ble_access_log("Malloc failed"); return kUnknownErr; } memcpy(p, &dev_id, sizeof(uint32_t)); @@ -629,9 +622,9 @@ OSStatus ble_access_get_attribute_by_handle(uint32_t dev_id, ble_access_attribute_t *attr) { uint8_t buf[ATTR_CHARACTERISTIC_VALUE_SIZE(BLE_ACCESS_MAX_ATTR_VALUE_LENGTH)] = {0}; - aos_bt_smart_attribute_t *attribute = (aos_bt_smart_attribute_t *)buf; + mico_bt_smart_attribute_t *attribute = (mico_bt_smart_attribute_t *)buf; - aos_bt_device_address_t device_address; + mico_bt_device_address_t device_address; ble_access_device_t *dev = NULL; OSStatus err = kNoErr; @@ -649,14 +642,14 @@ OSStatus ble_access_get_attribute_by_handle(uint32_t dev_id, require_action_string(dev != NULL, exit, err = kConnectionErr, "Not a connection"); /* refresh the attribute and read it. */ - err = aos_bt_smartbridge_refresh_attribute_cache_characteristic_value(&dev->socket, handle); + err = mico_bt_smartbridge_refresh_attribute_cache_characteristic_value(&dev->socket, handle); require_noerr_string(err, exit, "Refresh attribute cache failed"); attribute->value_struct_size = BLE_ACCESS_MAX_ATTR_VALUE_LENGTH; - err = aos_bt_smartbridge_get_attribute_cache_by_handle( + err = mico_bt_smartbridge_get_attribute_cache_by_handle( &dev->socket, handle, - (aos_bt_smart_attribute_t *)attribute, + (mico_bt_smart_attribute_t *)attribute, ATTR_CHARACTERISTIC_VALUE_SIZE(BLE_ACCESS_MAX_ATTR_VALUE_LENGTH)); require_noerr_string(err, exit, "Get attribute cache failed"); @@ -670,8 +663,8 @@ OSStatus ble_access_get_attribute_by_handle(uint32_t dev_id, OSStatus ble_access_update_characteristic_value(uint32_t dev_id, uint16_t handle, uint8_t length, uint8_t *data) { uint8_t buf[ATTR_CHARACTERISTIC_VALUE_SIZE(BLE_ACCESS_MAX_CHAR_VALUE_LENGTH)] = {0}; - aos_bt_smart_attribute_t *char_value = NULL; - aos_bt_device_address_t device_address; + mico_bt_smart_attribute_t *char_value = NULL; + mico_bt_device_address_t device_address; ble_access_device_t *dev = NULL; OSStatus err = kNoErr; @@ -691,32 +684,32 @@ OSStatus ble_access_update_characteristic_value(uint32_t dev_id, uint16_t handle dev = ble_access_find_device_by_address(device_address); require_action_string(dev != NULL, exit, err = kConnectionErr, "Not a connection"); - char_value = (aos_bt_smart_attribute_t *)buf; + char_value = (mico_bt_smart_attribute_t *)buf; char_value->value_struct_size = length; - err = aos_bt_smartbridge_get_attribute_cache_by_handle(&dev->socket, - handle, - char_value, - ATTR_CHARACTERISTIC_VALUE_SIZE(length)); + err = mico_bt_smartbridge_get_attribute_cache_by_handle(&dev->socket, + handle, + char_value, + ATTR_CHARACTERISTIC_VALUE_SIZE(length)); require_noerr_string(err, exit, "Get Attribute failed"); char_value->value_length = length; memcpy(&char_value->value.value[0], data, length); - err = aos_bt_smartbridge_write_attribute_cache_characteristic_value(&dev->socket, - (aos_bt_smart_attribute_t *)char_value); + err = mico_bt_smartbridge_write_attribute_cache_characteristic_value(&dev->socket, + (mico_bt_smart_attribute_t *)char_value); exit: return err; } /* Enable Characteristic Client Configuration Indication or Notification */ -OSStatus ble_access_enable_notification(uint32_t dev_id, const ble_access_attribute_t *attr, aos_bool_t notify) +OSStatus ble_access_enable_notification(uint32_t dev_id, const ble_access_attribute_t *attr, mico_bool_t notify) { - aos_bt_device_address_t device_address; + mico_bt_device_address_t device_address; ble_access_device_t *dev = NULL; OSStatus err = kNoErr; /* Generate device address */ - printf("Generate device address: device_id = %lu", dev_id); + ble_access_log("Generate device address: device_id = %lu", dev_id); ble_access_generate_device_address(device_address, dev_id); /* Check the socket is connected. */ @@ -724,7 +717,7 @@ OSStatus ble_access_enable_notification(uint32_t dev_id, const ble_access_attrib require_action_string(dev != NULL, exit, err = kConnectionErr, "Not a connection"); /* Enable Attribute Cache notification */ - err = aos_bt_smartbridge_enable_attribute_cache_notification(&dev->socket, notify); + err = mico_bt_smartbridge_enable_attribute_cache_notification(&dev->socket, notify); require_noerr_string(err, exit, "Enable Attribute notification failed"); exit: @@ -732,13 +725,13 @@ OSStatus ble_access_enable_notification(uint32_t dev_id, const ble_access_attrib } /* Scan complete handler. Scan complete event reported via this callback. - * It runs on the AOS_BT_EVT_WORKER_THREAD context. + * It runs on the MICO_BT_EVT_WORKER_THREAD context. */ static OSStatus ble_access_scan_complete_handler(void *arg) { UNUSED_PARAMETER(arg); /* Scan complete, start a new scan. Do not use a infinit scan, it may store every result in RAM. */ - printf("scanning stop"); + ble_access_log("scanning stop"); ble_access_send_bt_event(BLE_ACCESS_EVENT_DEV_NEW_CMPL, NULL); @@ -746,21 +739,21 @@ static OSStatus ble_access_scan_complete_handler(void *arg) } /* Handler of Scanning result */ -static OSStatus ble_access_scan_result_handler(const aos_bt_smart_advertising_report_t *scan_result) +static OSStatus ble_access_scan_result_handler(const mico_bt_smart_advertising_report_t *scan_result) { OSStatus err = kNoErr; - aos_bool_t is_reported = AOS_FALSE; + mico_bool_t is_reported = MICO_FALSE; - aos_bt_smart_device_t *device = NULL; + mico_bt_smart_device_t *device = NULL; ble_access_manufactor_data_t manufactor_data; ble_access_evt_parms_t parms; #if defined(BLE_ACCESS_DEBUG) && BLE_ACCESS_DEBUG == 1 char *device_address_str = DataToHexStringWithColons(scan_result->remote_device.address, 6); - printf("A device is scanned: %s[%s]", - scan_result->remote_device.name != NULL ? scan_result->remote_device.name : "Unknown Device", - device_address_str); + ble_access_log("A device is scanned: %s[%s]", + scan_result->remote_device.name != NULL ? scan_result->remote_device.name : "Unknown Device", + device_address_str); free(device_address_str); #endif @@ -771,7 +764,7 @@ static OSStatus ble_access_scan_result_handler(const aos_bt_smart_advertising_re scan_result->remote_device.address)) { if (!is_reported) { /* Update reported */ - ble_access_connect_list_set_report(device, AOS_TRUE); + ble_access_connect_list_set_report(device, MICO_TRUE); /* Update device name */ if (strlen(scan_result->remote_device.name) > 0) { @@ -807,24 +800,24 @@ static OSStatus ble_access_scan_result_handler(const aos_bt_smart_advertising_re &manufactor_data); if (err != kNoErr) { if (err != kParamErr) { - printf("Advertising data failed"); + ble_access_log("Advertising data failed"); } goto exit; } /* Add device to the list */ - require_noerr_string(ble_access_connect_list_add(&scan_result->remote_device, AOS_FALSE), + require_noerr_string(ble_access_connect_list_add(&scan_result->remote_device, MICO_FALSE), exit, "The device is existed!"); #if defined(BLE_ACCESS_DEBUG) && BLE_ACCESS_DEBUG == 1 - printf("ADV Data: "); - printf("RSSI - %d", scan_result->signal_strength); - printf("ADV type - %d", manufactor_data.adv_type); - printf("alert state - %d", manufactor_data.alert_state); + ble_access_log("ADV Data: "); + ble_access_log("RSSI - %d", scan_result->signal_strength); + ble_access_log("ADV type - %d", manufactor_data.adv_type); + ble_access_log("alert state - %d", manufactor_data.alert_state); device_address_str = DataToHexStringWithColons(manufactor_data.direct_addr, 6); - printf("addr - %s", device_address_str); - printf("\n\n"); + ble_access_log("addr - %s", device_address_str); + ble_access_log("\n\n"); free(device_address_str); #endif @@ -841,20 +834,20 @@ static OSStatus ble_access_connection_handler(void *arg) OSStatus err = kNoErr; ble_access_evt_parms_t parms; - aos_bt_smart_device_t *remote_device = (aos_bt_smart_device_t *)arg; + mico_bt_smart_device_t *remote_device = (mico_bt_smart_device_t *)arg; ble_access_device_t *dev = NULL; /* Iterate all sockets and look for the first available socket */ dev = ble_access_find_device_by_address(remote_device->address); if (dev) { - aos_bt_smartbridge_socket_status_t status; - aos_bt_smartbridge_get_socket_status(&dev->socket, &status); + mico_bt_smartbridge_socket_status_t status; + mico_bt_smartbridge_get_socket_status(&dev->socket, &status); if (status != SMARTBRIDGE_SOCKET_DISCONNECTED) { - printf("This device is busy!!!"); + ble_access_log("This device is busy!!!"); return kInProgressErr; } } else { - printf("Not a bonded device, allocate!!"); + ble_access_log("Not a bonded device, allocate!!"); dev = ble_access_get_free_device(); require_action_string(dev != 0, exit, err = kNoResourcesErr, "No resource for a new connection"); } @@ -863,48 +856,48 @@ static OSStatus ble_access_connection_handler(void *arg) #if defined(BLE_ACCESS_DEBUG) && BLE_ACCESS_DEBUG == 1 char *bt_addr_str = NULL; bt_addr_str = DataToHexStringWithColons((uint8_t *)remote_device->address, 6); - printf("Opening GATT Connection to [%s] (addr type =%s)...", - bt_addr_str, - (remote_device->address_type == BT_SMART_ADDR_TYPE_PUBLIC) ? "Public" : "Random"); + ble_access_log("Opening GATT Connection to [%s] (addr type =%s)...", + bt_addr_str, + (remote_device->address_type == BT_SMART_ADDR_TYPE_PUBLIC) ? "Public" : "Random"); free(bt_addr_str); #endif /* If there is a previously sotred device, then connect to it */ if (ble_access_security_settings.authentication_requirements != BT_SMART_AUTH_REQ_NONE) { - if (aos_bt_dev_find_bonded_device((uint8_t *)remote_device->address) == AOS_FALSE) { - printf("Bond info isn't found, Initiate pairing request."); - aos_bt_smartbridge_enable_pairing(&dev->socket, &ble_access_security_settings, NULL); + if (mico_bt_dev_find_bonded_device((uint8_t *)remote_device->address) == MICO_FALSE) { + ble_access_log("Bond info isn't found, Initiate pairing request."); + mico_bt_smartbridge_enable_pairing(&dev->socket, &ble_access_security_settings, NULL); } else { - printf("Bond info is found. Encrypt use bond info"); - aos_bt_smartbridge_set_bond_info(&dev->socket, &ble_access_security_settings, NULL); + ble_access_log("Bond info is found. Encrypt use bond info"); + mico_bt_smartbridge_set_bond_info(&dev->socket, &ble_access_security_settings, NULL); } } parms.device_id = ble_access_calculate_device_id(remote_device->address); /* connect */ - err = aos_bt_smartbridge_connect(&dev->socket, remote_device, &ble_access_connection_settings, - ble_access_disconnection_handler, - ble_access_notification_handler); + err = mico_bt_smartbridge_connect(&dev->socket, remote_device, &ble_access_connection_settings, + ble_access_disconnection_handler, + ble_access_notification_handler); require_noerr_string(err, exit, "The Peer Device connect failed"); /* Cache all services */ err = ble_access_cache_control_service(dev); require_noerr_action_string(err, exit, - aos_bt_smartbridge_disconnect(&dev->socket, TRUE), + mico_bt_smartbridge_disconnect(&dev->socket, TRUE), "Cache Control Point service failed"); /* Start a timer to wait for device authentication procedure */ err = ble_access_start_timer(dev, ble_access_timer_event_handle, (void *)dev); - require_noerr_action(err, exit, aos_bt_smartbridge_disconnect(&dev->socket, TRUE)); + require_noerr_action(err, exit, mico_bt_smartbridge_disconnect(&dev->socket, TRUE)); dev->auth_state = BLE_ACCESS_AUTH_STATE_START; - printf("Start a timer to wait device authentication."); + ble_access_log("Start a timer to wait device authentication."); /* Enable Attribute Cache notification */ - err = aos_bt_smartbridge_enable_attribute_cache_notification(&dev->socket, AOS_FALSE); + err = mico_bt_smartbridge_enable_attribute_cache_notification(&dev->socket, MICO_FALSE); require_noerr_action_string(err, exit, - aos_bt_smartbridge_disconnect(&dev->socket, TRUE), + mico_bt_smartbridge_disconnect(&dev->socket, TRUE), "Enable Attribute notification failed"); exit: @@ -912,7 +905,7 @@ static OSStatus ble_access_connection_handler(void *arg) dev->device_id = parms.device_id; ble_access_connect_list_remove(remote_device); } else { - ble_access_release_device(AOS_TRUE, dev); + ble_access_release_device(MICO_TRUE, dev); parms.p.state = BLE_ACCESS_STATUS_ADD_FAILED; ble_access_send_bt_event(BLE_ACCESS_EVENT_DEV_ADD, &parms); } @@ -920,15 +913,15 @@ static OSStatus ble_access_connection_handler(void *arg) } /* Disconnection handler. Disconnection by remote device is reported via this callback. - * It runs on the AOS_BT_EVT_WORKER_THREAD context. + * It runs on the MICO_BT_EVT_WORKER_THREAD context. */ -static OSStatus ble_access_disconnection_handler(aos_bt_smartbridge_socket_t *socket) +static OSStatus ble_access_disconnection_handler(mico_bt_smartbridge_socket_t *socket) { ble_access_evt_parms_t parms; /* Insert list and allow to add */ - ble_access_connect_list_add(&socket->remote_device, AOS_FALSE); - ble_access_release_device(AOS_FALSE, + ble_access_connect_list_add(&socket->remote_device, MICO_FALSE); + ble_access_release_device(MICO_FALSE, ble_access_find_device_by_address(socket->remote_device.address)); /* Send event */ @@ -939,39 +932,39 @@ static OSStatus ble_access_disconnection_handler(aos_bt_smartbridge_socket_t *so return kNoErr; } -static aos_bool_t ble_access_compare_uuid(const aos_bt_uuid_t *uuid1, const aos_bt_uuid_t *uuid2) +static mico_bool_t ble_access_compare_uuid(const mico_bt_uuid_t *uuid1, const mico_bt_uuid_t *uuid2) { - if ((uuid1->len == uuid2->len) && (memcmp(uuid1, uuid2, sizeof(aos_bt_uuid_t)) == 0)) { - return AOS_TRUE; + if ((uuid1->len == uuid2->len) && (memcmp(uuid1, uuid2, sizeof(mico_bt_uuid_t)) == 0)) { + return MICO_TRUE; } else { - return AOS_FALSE; + return MICO_FALSE; } } -static OSStatus ble_access_cache_all_services(aos_bt_smartbridge_socket_t *socket, ble_access_evt_parms_t *parms, +static OSStatus ble_access_cache_all_services(mico_bt_smartbridge_socket_t *socket, ble_access_evt_parms_t *parms, uint8_t max_servs) { uint8_t buf[ATTR_CHARACTERISTIC_VALUE_SIZE(BLE_ACCESS_MAX_ATTR_VALUE_LENGTH)] = {0}; - aos_bt_smart_attribute_t *attribute = (aos_bt_smart_attribute_t *)buf; + mico_bt_smart_attribute_t *attribute = (mico_bt_smart_attribute_t *)buf; ble_access_serv_t *servs = parms->p.add.serv; uint16_t start_handle = 0; uint16_t end_handle = 0xff; - aos_bt_uuid_t service_uuid = { .len = LEN_UUID_16, .uu.uuid16 = GATT_UUID_PRI_SERVICE }; - aos_bt_uuid_t gap_uuid = { .len = LEN_UUID_16, .uu.uuid16 = 0x1800 }; - aos_bt_uuid_t gatt_uuid = { .len = LEN_UUID_16, .uu.uuid16 = 0x1801 }; + mico_bt_uuid_t service_uuid = { .len = LEN_UUID_16, .uu.uuid16 = GATT_UUID_PRI_SERVICE }; + mico_bt_uuid_t gap_uuid = { .len = LEN_UUID_16, .uu.uuid16 = 0x1800 }; + mico_bt_uuid_t gatt_uuid = { .len = LEN_UUID_16, .uu.uuid16 = 0x1801 }; /* Find service */ attribute->value_struct_size = BLE_ACCESS_MAX_ATTR_VALUE_LENGTH; - while (aos_bt_smartbridge_get_attribute_cache_by_uuid( + while (mico_bt_smartbridge_get_attribute_cache_by_uuid( socket, &service_uuid, start_handle, end_handle, attribute, ATTR_CHARACTERISTIC_VALUE_SIZE(BLE_ACCESS_MAX_ATTR_VALUE_LENGTH)) - == AOS_BT_SUCCESS) { + == MICO_BT_SUCCESS) { /* Not GAP, GATT or MXCHIP */ if (!ble_access_compare_uuid(&attribute->value.service.uuid, &gap_uuid) @@ -997,9 +990,9 @@ static OSStatus ble_access_cache_all_services(aos_bt_smartbridge_socket_t *socke } /* Notification handler. GATT notification by remote device is reported via this callback. - * It runs on the AOS_BT_EVT_WORKER_THREAD context. + * It runs on the MICO_BT_EVT_WORKER_THREAD context. */ -static OSStatus ble_access_notification_handler(aos_bt_smartbridge_socket_t *socket, uint16_t attribute_handle) +static OSStatus ble_access_notification_handler(mico_bt_smartbridge_socket_t *socket, uint16_t attribute_handle) { /* GATT value notification event. attribute_handle is the handle * which value of the attribute is updated by the remote device. @@ -1007,7 +1000,7 @@ static OSStatus ble_access_notification_handler(aos_bt_smartbridge_socket_t *soc OSStatus err = kNoErr; uint8_t buf[ATTR_CHARACTERISTIC_VALUE_SIZE(BLE_ACCESS_MAX_CHAR_VALUE_LENGTH)] = {0}; - aos_bt_smart_attribute_t *characteristic_value = NULL; + mico_bt_smart_attribute_t *characteristic_value = NULL; ble_access_device_t *dev = NULL; ble_access_attribute_t attr; @@ -1015,12 +1008,12 @@ static OSStatus ble_access_notification_handler(aos_bt_smartbridge_socket_t *soc ble_access_evt_parms_t parms; /* Read cached data */ - characteristic_value = (aos_bt_smart_attribute_t *)buf; + characteristic_value = (mico_bt_smart_attribute_t *)buf; characteristic_value->value_struct_size = BLE_ACCESS_MAX_CHAR_VALUE_LENGTH; - err = aos_bt_smartbridge_refresh_attribute_cache_characteristic_value(socket, attribute_handle); + err = mico_bt_smartbridge_refresh_attribute_cache_characteristic_value(socket, attribute_handle); require_noerr_string(err, exit, "Refresh an Attribute failed"); - err = aos_bt_smartbridge_get_attribute_cache_by_handle( + err = mico_bt_smartbridge_get_attribute_cache_by_handle( socket, attribute_handle, characteristic_value, @@ -1029,7 +1022,7 @@ static OSStatus ble_access_notification_handler(aos_bt_smartbridge_socket_t *soc /* Check socket */ dev = ble_access_find_device_by_address(socket->remote_device.address); - require_action_string(dev != NULL, exit, aos_bt_smartbridge_disconnect(socket, TRUE), "Not a valid socket"); + require_action_string(dev != NULL, exit, mico_bt_smartbridge_disconnect(socket, TRUE), "Not a valid socket"); /* Calculate Device ID */ parms.device_id = ble_access_calculate_device_id(socket->remote_device.address); @@ -1051,43 +1044,43 @@ static OSStatus ble_access_notification_handler(aos_bt_smartbridge_socket_t *soc memset(servs, 0, sizeof(servs) / sizeof(servs[0])); ble_access_cache_all_services(&dev->socket, &parms, sizeof(servs) / sizeof(servs[0])); - printf("Authentication Device Successfully"); + ble_access_log("Authentication Device Successfully"); } else { err = kGeneralErr; parms.status = BLE_ACCESS_STATUS_SLAVE_REJECT; dev->auth_state = BLE_ACCESS_AUTH_STATE_FAIL; - printf("Authenticate Device Failed"); + ble_access_log("Authenticate Device Failed"); /* Disconnect */ - aos_bt_smartbridge_disconnect(&dev->socket, AOS_TRUE); + mico_bt_smartbridge_disconnect(&dev->socket, MICO_TRUE); /* Delete its bond information */ - aos_bt_dev_delete_bonded_device(dev->socket.remote_device.address); + mico_bt_dev_delete_bonded_device(dev->socket.remote_device.address); /* Release BLE Access Device to Pool */ - ble_access_release_device(AOS_TRUE, dev); + ble_access_release_device(MICO_TRUE, dev); } ble_access_send_bt_event(BLE_ACCESS_EVENT_DEV_ADD, &parms); } else { - printf("Authentication: unknown Command[0x%02x]", characteristic_value->value.value[0]); + ble_access_log("Authentication: unknown Command[0x%02x]", characteristic_value->value.value[0]); } } else if (dev->auth_state == BLE_ACCESS_AUTH_STATE_SUCC) { if (characteristic_value->value.value[0] == BLE_ACCESS_RES_DISC) { - printf("Commiunity: DISC Command, status[0x%02x]", characteristic_value->value.value[4]); + ble_access_log("Commiunity: DISC Command, status[0x%02x]", characteristic_value->value.value[4]); if (characteristic_value->value.value[4] == BLE_ACCESS_ERR_NO_ERR) { /* Accept */ parms.status = BLE_ACCESS_STATUS_SUCCESS; - aos_bt_smartbridge_disconnect(&dev->socket, FALSE); - ble_access_release_device(AOS_FALSE, dev); + mico_bt_smartbridge_disconnect(&dev->socket, FALSE); + ble_access_release_device(MICO_FALSE, dev); } else if (characteristic_value->value.value[4] == BLE_ACCESS_ERR_REJECT) { parms.status = BLE_ACCESS_STATUS_SLAVE_REJECT; } ble_access_send_bt_event(BLE_ACCESS_EVENT_DEV_DISC, &parms); } else { - printf("Commiunity: unknown Command[0x%02x]", characteristic_value->value.value[0]); + ble_access_log("Commiunity: unknown Command[0x%02x]", characteristic_value->value.value[0]); } } else { - printf("Authentication or DISC_REQ sequence, substate: 0x%02x", dev->auth_state); + ble_access_log("Authentication or DISC_REQ sequence, substate: 0x%02x", dev->auth_state); } } else { if (dev->auth_state == BLE_ACCESS_AUTH_STATE_SUCC) { @@ -1101,38 +1094,38 @@ static OSStatus ble_access_notification_handler(aos_bt_smartbridge_socket_t *soc return err; } -static OSStatus ble_access_auto_connection_handler(aos_bt_smartbridge_socket_t *socket) +static OSStatus ble_access_auto_connection_handler(mico_bt_smartbridge_socket_t *socket) { OSStatus err = kNoErr; ble_access_device_t *dev = NULL; ble_access_serv_t servs[BLE_ACCESS_REMOTE_SERVS_NUM]; ble_access_evt_parms_t parms; - aos_bt_smartbridge_socket_status_t status; + mico_bt_smartbridge_socket_status_t status; dev = ble_access_find_device_by_address(socket->remote_device.address); require_action_string(dev != NULL, exit, err = kGeneralErr, "Unknown a socket which isn't in the pool"); /* Check current socket status */ - aos_bt_smartbridge_get_socket_status(socket, &status); + mico_bt_smartbridge_get_socket_status(socket, &status); if (status != SMARTBRIDGE_SOCKET_CONNECTED) { - printf("An auto connection status: %u", status); - ble_access_release_device(AOS_FALSE, dev); + ble_access_log("An auto connection status: %u", status); + ble_access_release_device(MICO_FALSE, dev); return kConnectionErr; } - printf("An auto connection is established"); + ble_access_log("An auto connection is established"); /* Cache all services */ err = ble_access_cache_control_service(dev); require_noerr_action_string(err, exit, - aos_bt_smartbridge_disconnect(&dev->socket, TRUE), + mico_bt_smartbridge_disconnect(&dev->socket, TRUE), "Cache Control Point service failed"); /* Enable all service indication. */ - err = aos_bt_smartbridge_enable_attribute_cache_notification(socket, AOS_FALSE); + err = mico_bt_smartbridge_enable_attribute_cache_notification(socket, MICO_FALSE); require_noerr_string(err, exit, "Enable attribute indication failed"); /* Notify user layer application */ @@ -1149,24 +1142,24 @@ static OSStatus ble_access_auto_connection_handler(aos_bt_smartbridge_socket_t * } /* Get Auto Connection Parameters. */ -OSStatus ble_access_auto_conn_parms_handler(const aos_bt_device_address_t device_address, +OSStatus ble_access_auto_conn_parms_handler(const mico_bt_device_address_t device_address, const char *name, const uint8_t *p_adv_data, const uint8_t length, - aos_bt_smartbridge_auto_conn_cback_parms_t *parm) + mico_bt_smartbridge_auto_conn_cback_parms_t *parm) { OSStatus err = kNoErr; ble_access_manufactor_data_t manufactor_data; ble_access_device_t *dev = NULL; - printf("Auto connection: %s[%02x:%02x:%02x:%02x:%02x:%02x]", - name, - device_address[0], - device_address[1], - device_address[2], - device_address[3], - device_address[4], - device_address[5]); + ble_access_log("Auto connection: %s[%02x:%02x:%02x:%02x:%02x:%02x]", + name, + device_address[0], + device_address[1], + device_address[2], + device_address[3], + device_address[4], + device_address[5]); /* Allow to be connected. */ dev = ble_access_find_device_by_address(device_address); @@ -1182,14 +1175,14 @@ OSStatus ble_access_auto_conn_parms_handler(const aos_bt_device_address_t device /* Check target device */ if (memcmp(manufactor_data.direct_addr, ble_access_local_address, 6) != 0) { - printf("The target device is not myself"); + ble_access_log("The target device is not myself"); return kUnknownErr; } parm->socket = &dev->socket; memcpy((void *)parm->socket->remote_device.address, (void *)device_address, - sizeof(aos_bt_device_address_t)); + sizeof(mico_bt_device_address_t)); memcpy((void *)parm->socket->remote_device.name, (void *)name, MIN(sizeof(parm->socket->remote_device.name), @@ -1200,10 +1193,10 @@ OSStatus ble_access_auto_conn_parms_handler(const aos_bt_device_address_t device parm->notification_callback = ble_access_notification_handler; memcpy((void *)&parm->conn_settings, (void *)&ble_access_connection_settings, - sizeof(aos_bt_smart_connection_settings_t)); + sizeof(mico_bt_smart_connection_settings_t)); memcpy((void *)&parm->security_settings, (void *)&ble_access_security_settings, - sizeof(aos_bt_smart_security_settings_t)); + sizeof(mico_bt_smart_security_settings_t)); exit: return err; @@ -1214,19 +1207,19 @@ static OSStatus ble_access_timer_event_handle(void *arg) ble_access_device_t *dev = (ble_access_device_t *)arg; ble_access_evt_parms_t parms; - printf("Authentication Device Timeout"); + ble_access_log("Authentication Device Timeout"); ble_access_stop_timer(dev); dev->auth_state = BLE_ACCESS_AUTH_STATE_FAIL; /* Timeout for add device */ - ble_access_connect_list_add(&dev->socket.remote_device, AOS_FALSE); + ble_access_connect_list_add(&dev->socket.remote_device, MICO_FALSE); /* Disconnect this device */ - aos_bt_smartbridge_disconnect(&dev->socket, TRUE); - ble_access_release_device(AOS_TRUE, dev); + mico_bt_smartbridge_disconnect(&dev->socket, TRUE); + ble_access_release_device(MICO_TRUE, dev); /* Delete its bond information */ - aos_bt_dev_delete_bonded_device(dev->socket.remote_device.address); + mico_bt_dev_delete_bonded_device(dev->socket.remote_device.address); /* Notify user */ parms.device_id = ble_access_calculate_device_id(dev->socket.remote_device.address); @@ -1284,7 +1277,7 @@ static OSStatus ble_access_send_command(const ble_access_device_t *dev, uint8_t { OSStatus err = kNoErr; uint8_t buf[ATTR_CHARACTERISTIC_VALUE_SIZE(BLE_ACCESS_MAX_CHAR_VALUE_LENGTH)] = {0}; - aos_bt_smart_attribute_t *characteristic_value = NULL; + mico_bt_smart_attribute_t *characteristic_value = NULL; if (length == 0 || p_data == NULL) { @@ -1292,11 +1285,11 @@ static OSStatus ble_access_send_command(const ble_access_device_t *dev, uint8_t } /* Prepare for writing */ - characteristic_value = (aos_bt_smart_attribute_t *)buf; + characteristic_value = (mico_bt_smart_attribute_t *)buf; characteristic_value->value_struct_size = BLE_ACCESS_MAX_CHAR_VALUE_LENGTH; - err = aos_bt_smartbridge_get_attribute_cache_by_handle( - (aos_bt_smartbridge_socket_t *)&dev->socket, + err = mico_bt_smartbridge_get_attribute_cache_by_handle( + (mico_bt_smartbridge_socket_t *)&dev->socket, dev->service.ctrl_evt_char_value_handle, characteristic_value, ATTR_CHARACTERISTIC_VALUE_SIZE(BLE_ACCESS_MAX_CHAR_VALUE_LENGTH)); @@ -1311,8 +1304,8 @@ static OSStatus ble_access_send_command(const ble_access_device_t *dev, uint8_t memcpy(&characteristic_value->value.value[4], p_data, length); /* Write */ - err = aos_bt_smartbridge_write_attribute_cache_characteristic_value((aos_bt_smartbridge_socket_t *)&dev->socket, - characteristic_value); + err = mico_bt_smartbridge_write_attribute_cache_characteristic_value((mico_bt_smartbridge_socket_t *)&dev->socket, + characteristic_value); exit: return err; } @@ -1322,15 +1315,15 @@ static OSStatus ble_access_cache_control_service(ble_access_device_t *dev) OSStatus err = kNoErr; uint8_t buf[ATTR_CHARACTERISTIC_VALUE_SIZE(BLE_ACCESS_MAX_ATTR_VALUE_LENGTH)] = {0}; - aos_bt_smart_attribute_t *attribute = (aos_bt_smart_attribute_t *)buf; + mico_bt_smart_attribute_t *attribute = (mico_bt_smart_attribute_t *)buf; if (!dev) { return kParamErr; } /* Find service */ - err = aos_bt_smartbridge_get_service_from_attribute_cache_by_uuid( - (aos_bt_smartbridge_socket_t *)&dev->socket, + err = mico_bt_smartbridge_get_service_from_attribute_cache_by_uuid( + (mico_bt_smartbridge_socket_t *)&dev->socket, &ble_access_cache_services_uuid[BLE_CONTROL_SERV_UUID_IDX], 0x00, 0xff, @@ -1339,16 +1332,16 @@ static OSStatus ble_access_cache_control_service(ble_access_device_t *dev) require_noerr_string(err, exit, "Cache Control Service failed"); /* Find Control Point Event characteristic, and save characteristic value handle */ - err = aos_bt_smartbridge_get_characteritics_from_attribute_cache_by_uuid( - (aos_bt_smartbridge_socket_t *)&dev->socket, + err = mico_bt_smartbridge_get_characteritics_from_attribute_cache_by_uuid( + (mico_bt_smartbridge_socket_t *)&dev->socket, &ble_access_cache_chars_uuid[BLE_CONTROL_EVT_CHAR_UUID_IDX], attribute->value.service.start_handle, attribute->value.service.end_handle, - (aos_bt_smart_attribute_t *)attribute, + (mico_bt_smart_attribute_t *)attribute, ATTR_CHARACTERISTIC_VALUE_SIZE(BLE_ACCESS_MAX_ATTR_VALUE_LENGTH)); require_noerr_action_string(err, exit, - aos_bt_smartbridge_remove_attribute_cache((aos_bt_smartbridge_socket_t *)&dev->socket), + mico_bt_smartbridge_remove_attribute_cache((mico_bt_smartbridge_socket_t *)&dev->socket), "Cache Control Service Response Characteristic Failed"); dev->service.ctrl_evt_char_value_handle = attribute->value.characteristic.value_handle; diff --git a/device/bluetooth/mk3239/ble_access/ble_access_core.h b/device/bluetooth/mk3239/ble_access/ble_access_core.h index 5e4bd6ab94..31071772fc 100644 --- a/device/bluetooth/mk3239/ble_access/ble_access_core.h +++ b/device/bluetooth/mk3239/ble_access/ble_access_core.h @@ -1,7 +1,3 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - #ifndef __BLE_ACCESS_CORE_H__ #define __BLE_ACCESS_CORE_H__ @@ -92,7 +88,7 @@ typedef struct { uint32_t device_id; union { /* used by BLE_ACCESS_REQ_DEV_SCAN */ - aos_bool_t start; + mico_bool_t start; /* used by BLE_ACCESS_REQ_DEV_DISC */ uint32_t timeout; } p; @@ -409,7 +405,7 @@ extern OSStatus ble_access_update_characteristic_value(uint32_t dev_id, uint16_t */ extern OSStatus ble_access_enable_notification(uint32_t dev_id, const ble_access_attribute_t *attr, - aos_bool_t notify); + mico_bool_t notify); /* * Compare two UUID type. @@ -419,7 +415,7 @@ extern OSStatus ble_access_enable_notification(uint32_t dev_id, * * @return 0 if they are equal, otherwise non-zero. */ -extern aos_bool_t ble_access_uuid_compare(const ble_access_uuid_t *uuid1, const ble_access_uuid_t *uuid2); +extern mico_bool_t ble_access_uuid_compare(const ble_access_uuid_t *uuid1, const ble_access_uuid_t *uuid2); /* * Calculate device ID by Device Address @@ -428,7 +424,7 @@ extern aos_bool_t ble_access_uuid_compare(const ble_access_uuid_t *uuid1, const * * @return device ID or zero */ -extern uint32_t ble_access_calculate_device_id(const aos_bt_device_address_t addr); +extern uint32_t ble_access_calculate_device_id(const mico_bt_device_address_t addr); /* * Generate a device address by device ID @@ -438,7 +434,7 @@ extern uint32_t ble_access_calculate_device_id(const aos_bt_device_address_t add * * @return kNoErr if successful. */ -extern OSStatus ble_access_generate_device_address(aos_bt_device_address_t addr, uint32_t device_id); +extern OSStatus ble_access_generate_device_address(mico_bt_device_address_t addr, uint32_t device_id); #ifdef __cplusplus } diff --git a/device/bluetooth/mk3239/ble_access/ble_access_core_i.c b/device/bluetooth/mk3239/ble_access/ble_access_core_i.c index 811ca40fef..f081d0ab10 100644 --- a/device/bluetooth/mk3239/ble_access/ble_access_core_i.c +++ b/device/bluetooth/mk3239/ble_access/ble_access_core_i.c @@ -1,15 +1,12 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - #include #include -#include "smartbt.h" -#include "smartbt_cfg.h" -#include "smartbt_smart_interface.h" -#include "smartbt_smartbridge.h" -#include "smartbt_smartbridge_gatt.h" +#include "mico.h" +#include "mico_bt.h" +#include "mico_bt_cfg.h" +#include "mico_bt_smart_interface.h" +#include "mico_bt_smartbridge.h" +#include "mico_bt_smartbridge_gatt.h" #include "sdpdefs.h" #include "gattdefs.h" @@ -52,12 +49,12 @@ */ static ble_access_device_t ble_access_devices[MAX_CONCURRENT_CONNECTIONS]; -static aos_mutex_t ble_access_dev_mutex; +static mico_mutex_t ble_access_dev_mutex; static linked_list_t ble_access_connecting_device_list; -static aos_mutex_t ble_access_conn_dev_list_mutex; +static mico_mutex_t ble_access_conn_dev_list_mutex; -static aos_worker_thread_t ble_access_worker_thread; +static mico_worker_thread_t ble_access_worker_thread; static event_handler_t ble_access_timer_evt; /* Prefix Address for valid device MAC Address */ @@ -84,15 +81,15 @@ static uint8_t prefix_addr[][BLE_ACCESS_PREFIX_LEN] = { OSStatus ble_access_create_worker_thread(void) { - return aos_rtos_create_worker_thread(&ble_access_worker_thread, - AOS_DEFAULT_WORKER_PRIORITY, - 2048, - 20); + return mico_rtos_create_worker_thread(&ble_access_worker_thread, + MICO_DEFAULT_WORKER_PRIORITY, + 2048, + 20); } OSStatus ble_access_send_aync_event(event_handler_t event_handle, void *arg) { - return aos_rtos_send_asynchronous_event(&ble_access_worker_thread, event_handle, arg); + return mico_rtos_send_asynchronous_event(&ble_access_worker_thread, event_handle, arg); } /* @@ -112,11 +109,11 @@ OSStatus ble_access_start_timer(ble_access_device_t *dev, event_handler_t timer_ require_action(dev != NULL && timer_event_handle != NULL, exit, err = kParamErr); - err = aos_rtos_init_timer(&dev->timer, 10000, ble_access_timer_callback, arg); + err = mico_rtos_init_timer(&dev->timer, 10000, ble_access_timer_callback, arg); require_noerr_string(err, exit, "Initialize a timer failed"); - err = aos_rtos_start_timer(&dev->timer); - require_noerr_action_string(err, exit, aos_rtos_deinit_timer(&dev->timer), "Start a timer failed"); + err = mico_rtos_start_timer(&dev->timer); + require_noerr_action_string(err, exit, mico_rtos_deinit_timer(&dev->timer), "Start a timer failed"); ble_access_timer_evt = timer_event_handle; @@ -130,10 +127,10 @@ OSStatus ble_access_stop_timer(ble_access_device_t *dev) require_action(dev != NULL, exit, err = kParamErr); - if (aos_rtos_is_timer_running(&dev->timer)) { - aos_rtos_stop_timer(&dev->timer); + if (mico_rtos_is_timer_running(&dev->timer)) { + mico_rtos_stop_timer(&dev->timer); } - err = aos_rtos_deinit_timer(&dev->timer); + err = mico_rtos_deinit_timer(&dev->timer); exit: return err; @@ -152,10 +149,10 @@ void ble_access_initialize_devices(void) for (idx = 0; idx < ble_access_array_size(ble_access_devices); idx++) { ble_access_devices[idx].used = FALSE; ble_access_devices[idx].device_id = 0; - err = aos_bt_smartbridge_create_socket(&ble_access_devices[idx].socket); + err = mico_bt_smartbridge_create_socket(&ble_access_devices[idx].socket); require_noerr_string(err, exit, "Create Sockets failed"); } - aos_rtos_init_mutex(&ble_access_dev_mutex); + mico_rtos_init_mutex(&ble_access_dev_mutex); exit: return; @@ -167,18 +164,18 @@ void ble_access_deinit_devices(void) uint8_t idx = 0; for (idx = 0; idx < ble_access_array_size(ble_access_devices); idx++) { - aos_bt_smartbridge_delete_socket(&ble_access_devices[idx].socket); + mico_bt_smartbridge_delete_socket(&ble_access_devices[idx].socket); } - aos_rtos_deinit_mutex(&ble_access_dev_mutex); + mico_rtos_deinit_mutex(&ble_access_dev_mutex); } -ble_access_device_t *ble_access_find_device_by_address(const aos_bt_device_address_t address) +ble_access_device_t *ble_access_find_device_by_address(const mico_bt_device_address_t address) { uint8_t idx = 0; ble_access_device_t *dev = NULL; uint32_t device_id = ble_access_calculate_device_id(address); - aos_rtos_lock_mutex(&ble_access_dev_mutex); + mico_rtos_lock_mutex(&ble_access_dev_mutex); for (idx = 0; idx < ble_access_array_size(ble_access_devices); idx++) { if (ble_access_devices[idx].used && device_id == ble_access_devices[idx].device_id) { break; @@ -187,7 +184,7 @@ ble_access_device_t *ble_access_find_device_by_address(const aos_bt_device_addre if (idx < ble_access_array_size(ble_access_devices)) { dev = &ble_access_devices[idx]; } - aos_rtos_unlock_mutex(&ble_access_dev_mutex); + mico_rtos_unlock_mutex(&ble_access_dev_mutex); return dev; } @@ -197,24 +194,24 @@ ble_access_device_t *ble_access_get_free_device(void) { uint8_t idx = 0; - aos_rtos_lock_mutex(&ble_access_dev_mutex); + mico_rtos_lock_mutex(&ble_access_dev_mutex); for (idx = 0; idx < ble_access_array_size(ble_access_devices); idx++) { if (!ble_access_devices[idx].used) { ble_access_devices[idx].used = TRUE; - aos_rtos_unlock_mutex(&ble_access_dev_mutex); + mico_rtos_unlock_mutex(&ble_access_dev_mutex); return &ble_access_devices[idx]; } } - aos_rtos_unlock_mutex(&ble_access_dev_mutex); + mico_rtos_unlock_mutex(&ble_access_dev_mutex); return NULL; } -void ble_access_release_device(aos_bool_t free, const ble_access_device_t *device) +void ble_access_release_device(mico_bool_t free, const ble_access_device_t *device) { uint8_t idx = 0; - aos_rtos_lock_mutex(&ble_access_dev_mutex); + mico_rtos_lock_mutex(&ble_access_dev_mutex); if (device != NULL) { for (idx = 0; idx < ble_access_array_size(ble_access_devices) && device != &ble_access_devices[idx]; @@ -224,7 +221,7 @@ void ble_access_release_device(aos_bool_t free, const ble_access_device_t *devic ble_access_devices[idx].used = FALSE; } } - aos_rtos_unlock_mutex(&ble_access_dev_mutex); + mico_rtos_unlock_mutex(&ble_access_dev_mutex); } /* @@ -244,7 +241,7 @@ void ble_access_release_device(aos_bool_t free, const ble_access_device_t *devic * ----> * addr = { 0x20, 0x73, 0x6a, 0x11, 0x22, 0x33 } */ -OSStatus ble_access_generate_device_address(aos_bt_device_address_t addr, uint32_t device_id) +OSStatus ble_access_generate_device_address(mico_bt_device_address_t addr, uint32_t device_id) { uint8_t idx_addr_type = 0; @@ -278,7 +275,7 @@ OSStatus ble_access_generate_device_address(aos_bt_device_address_t addr, uint32 * addr = { 0x20, 0x73, 0x6a, 0x11, 0x22, 0x33 }; * so, device_id = 0x112233. */ -uint32_t ble_access_calculate_device_id(const aos_bt_device_address_t addr) +uint32_t ble_access_calculate_device_id(const mico_bt_device_address_t addr) { uint32_t id = 0x00000000; uint8_t idx; @@ -351,12 +348,12 @@ OSStatus ble_access_check_adv_type(const uint8_t *adv_data, if (adv_data == NULL || length == 0 || (adv_type != BLE_ACCESS_ADV_TYPE_INIT && adv_type != BLE_ACCESS_ADV_TYPE_RECONN)) { - return AOS_FALSE; + return MICO_FALSE; } - packet = aos_bt_ble_check_advertising_data((uint8_t *)adv_data, - BTM_BLE_ADVERT_TYPE_MANUFACTURER, - &data_length); + packet = mico_bt_ble_check_advertising_data((uint8_t *)adv_data, + BTM_BLE_ADVERT_TYPE_MANUFACTURER, + &data_length); if (packet == NULL || data_length == 0) { err = kUnknownErr; goto exit; @@ -384,7 +381,7 @@ OSStatus ble_access_check_adv_type(const uint8_t *adv_data, return err; } -void ble_access_set_scan_cfg(aos_bt_smart_scan_settings_t *scan_cfg, aos_bool_t is_auto_scanning) +void ble_access_set_scan_cfg(mico_bt_smart_scan_settings_t *scan_cfg, mico_bool_t is_auto_scanning) { require_string(scan_cfg != NULL, exit, "invalid parameters"); @@ -408,31 +405,31 @@ void ble_access_set_scan_cfg(aos_bt_smart_scan_settings_t *scan_cfg, aos_bool_t return; } -aos_bool_t ble_access_uuid_compare(const ble_access_uuid_t *uuid1, const ble_access_uuid_t *uuid2) +mico_bool_t ble_access_uuid_compare(const ble_access_uuid_t *uuid1, const ble_access_uuid_t *uuid2) { if (!uuid1 || !uuid2) { - return AOS_FALSE; + return MICO_FALSE; } if (uuid1->len == uuid2->len && memcmp(&uuid1->uu, &uuid2->uu, uuid1->len) == 0) { - return AOS_TRUE; + return MICO_TRUE; } - return AOS_FALSE; + return MICO_FALSE; } OSStatus ble_access_connect_list_init( void ) { - aos_rtos_init_mutex(&ble_access_conn_dev_list_mutex); + mico_rtos_init_mutex(&ble_access_conn_dev_list_mutex); return linked_list_init(&ble_access_connecting_device_list); } OSStatus ble_access_connect_list_deinit(void) { OSStatus err = kNoErr; - aos_bt_smart_device_t *dev = NULL; + mico_bt_smart_device_t *dev = NULL; for (; ;) { err = ble_access_connect_list_get(&dev, NULL); @@ -443,13 +440,13 @@ OSStatus ble_access_connect_list_deinit(void) } } - return aos_rtos_deinit_mutex(&ble_access_conn_dev_list_mutex); + return mico_rtos_deinit_mutex(&ble_access_conn_dev_list_mutex); } -aos_bool_t compare_device_by_address(linked_list_node_t *node_to_compare, void *user_data) +mico_bool_t compare_device_by_address(linked_list_node_t *node_to_compare, void *user_data) { ble_access_connecting_device_t *device = (ble_access_connecting_device_t * )node_to_compare; - aos_bt_device_address_t *device_address = (aos_bt_device_address_t *)user_data; + mico_bt_device_address_t *device_address = (mico_bt_device_address_t *)user_data; if (memcmp(device->device.address, device_address, BD_ADDR_LEN) == 0) { return TRUE; @@ -458,19 +455,19 @@ aos_bool_t compare_device_by_address(linked_list_node_t *node_to_compare, void * } } -OSStatus ble_access_connect_list_add(const aos_bt_smart_device_t *remote_device, aos_bool_t is_reported) +OSStatus ble_access_connect_list_add(const mico_bt_smart_device_t *remote_device, mico_bool_t is_reported) { OSStatus err = kNoErr; ble_access_connecting_device_t *device_found, *new_device; require_action(remote_device != NULL, exit, err = kParamErr); - aos_rtos_lock_mutex(&ble_access_conn_dev_list_mutex); + mico_rtos_lock_mutex(&ble_access_conn_dev_list_mutex); err = linked_list_find_node(&ble_access_connecting_device_list, (linked_list_compare_callback_t)compare_device_by_address, (void *)remote_device->address, (linked_list_node_t **)&device_found); - aos_rtos_unlock_mutex(&ble_access_conn_dev_list_mutex); + mico_rtos_unlock_mutex(&ble_access_conn_dev_list_mutex); if (err != kNotFoundErr) { err = kAlreadyInUseErr; @@ -484,24 +481,24 @@ OSStatus ble_access_connect_list_add(const aos_bt_smart_device_t *remote_device, } new_device->reported = is_reported; - memcpy(&new_device->device, remote_device, sizeof(aos_bt_smart_device_t)); + memcpy(&new_device->device, remote_device, sizeof(mico_bt_smart_device_t)); - aos_rtos_lock_mutex(&ble_access_conn_dev_list_mutex); + mico_rtos_lock_mutex(&ble_access_conn_dev_list_mutex); err = linked_list_insert_node_at_rear(&ble_access_connecting_device_list, &new_device->this_node); - aos_rtos_unlock_mutex(&ble_access_conn_dev_list_mutex); + mico_rtos_unlock_mutex(&ble_access_conn_dev_list_mutex); exit: return err; } -OSStatus ble_access_connect_list_set_report(const aos_bt_smart_device_t *device, aos_bool_t is_reported) +OSStatus ble_access_connect_list_set_report(const mico_bt_smart_device_t *device, mico_bool_t is_reported) { OSStatus err = kNoErr; ble_access_connecting_device_t *device_found; require_action(device != NULL, exit, err = kParamErr); - aos_rtos_lock_mutex(&ble_access_conn_dev_list_mutex); + mico_rtos_lock_mutex(&ble_access_conn_dev_list_mutex); err = linked_list_find_node(&ble_access_connecting_device_list, (linked_list_compare_callback_t)compare_device_by_address, (void *)device->address, @@ -509,22 +506,22 @@ OSStatus ble_access_connect_list_set_report(const aos_bt_smart_device_t *device, if (err == kNoErr) { device_found->reported = is_reported; } - aos_rtos_unlock_mutex(&ble_access_conn_dev_list_mutex); + mico_rtos_unlock_mutex(&ble_access_conn_dev_list_mutex); exit: return err; } -OSStatus ble_access_connect_list_get(aos_bt_smart_device_t **device, aos_bool_t *reported) +OSStatus ble_access_connect_list_get(mico_bt_smart_device_t **device, mico_bool_t *reported) { OSStatus err = kNoErr; ble_access_connecting_device_t *current_device; require_action(device != NULL, exit, err = kParamErr); - aos_rtos_lock_mutex(&ble_access_conn_dev_list_mutex); + mico_rtos_lock_mutex(&ble_access_conn_dev_list_mutex); err = linked_list_get_front_node(&ble_access_connecting_device_list, (linked_list_node_t **)¤t_device); - aos_rtos_unlock_mutex(&ble_access_conn_dev_list_mutex); + mico_rtos_unlock_mutex(&ble_access_conn_dev_list_mutex); if (err != kNoErr) { goto exit; @@ -539,20 +536,20 @@ OSStatus ble_access_connect_list_get(aos_bt_smart_device_t **device, aos_bool_t return err; } -OSStatus ble_access_connect_list_get_by_address(aos_bt_smart_device_t **device, aos_bool_t *reported, - const aos_bt_device_address_t address) +OSStatus ble_access_connect_list_get_by_address(mico_bt_smart_device_t **device, mico_bool_t *reported, + const mico_bt_device_address_t address) { OSStatus err = kNoErr; ble_access_connecting_device_t *current_device; require_action(device != NULL && address != NULL, exit, err = kParamErr); - aos_rtos_lock_mutex(&ble_access_conn_dev_list_mutex); + mico_rtos_lock_mutex(&ble_access_conn_dev_list_mutex); err = linked_list_find_node(&ble_access_connecting_device_list, (linked_list_compare_callback_t)compare_device_by_address, (void *)address, (linked_list_node_t **)¤t_device); - aos_rtos_unlock_mutex(&ble_access_conn_dev_list_mutex); + mico_rtos_unlock_mutex(&ble_access_conn_dev_list_mutex); if (err != kNoErr) { goto exit; @@ -567,26 +564,26 @@ OSStatus ble_access_connect_list_get_by_address(aos_bt_smart_device_t **device, return err; } -OSStatus ble_access_connect_list_find_by_address(const aos_bt_device_address_t address) +OSStatus ble_access_connect_list_find_by_address(const mico_bt_device_address_t address) { OSStatus err = kNoErr; ble_access_connecting_device_t *current_device; - aos_rtos_lock_mutex(&ble_access_conn_dev_list_mutex); + mico_rtos_lock_mutex(&ble_access_conn_dev_list_mutex); err = linked_list_find_node(&ble_access_connecting_device_list, (linked_list_compare_callback_t)compare_device_by_address, (void *)address, (linked_list_node_t **)¤t_device); - aos_rtos_unlock_mutex(&ble_access_conn_dev_list_mutex); + mico_rtos_unlock_mutex(&ble_access_conn_dev_list_mutex); return err; } -OSStatus ble_access_connect_list_remove(aos_bt_smart_device_t *device) +OSStatus ble_access_connect_list_remove(mico_bt_smart_device_t *device) { OSStatus err = kNoErr; ble_access_connecting_device_t *current_device; - aos_rtos_lock_mutex(&ble_access_conn_dev_list_mutex); + mico_rtos_lock_mutex(&ble_access_conn_dev_list_mutex); err = linked_list_find_node(&ble_access_connecting_device_list, (linked_list_compare_callback_t)compare_device_by_address, device->address, @@ -602,7 +599,7 @@ OSStatus ble_access_connect_list_remove(aos_bt_smart_device_t *device) free(current_device); exit: - aos_rtos_unlock_mutex(&ble_access_conn_dev_list_mutex); + mico_rtos_unlock_mutex(&ble_access_conn_dev_list_mutex); return err; } diff --git a/device/bluetooth/mk3239/ble_access/ble_access_core_i.h b/device/bluetooth/mk3239/ble_access/ble_access_core_i.h index 2ec1f404fd..54c4b2c079 100644 --- a/device/bluetooth/mk3239/ble_access/ble_access_core_i.h +++ b/device/bluetooth/mk3239/ble_access/ble_access_core_i.h @@ -1,11 +1,8 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - #ifndef __BLE_ACCESS_CORE_I_H__ #define __BLE_ACCESS_CORE_I_H__ -#include "smartbt.h" +#include "mico.h" +#include "mico_bt.h" /* *------------------------------------------------------------------------------------------------- @@ -100,8 +97,8 @@ /* Device info ready to connect */ typedef struct { linked_list_node_t this_node; /* Linked-list node of this device */ - aos_bt_smart_device_t device; /* Remote BT device */ - aos_bool_t reported; /* Is reported? */ + mico_bt_smart_device_t device; /* Remote BT device */ + mico_bool_t reported; /* Is reported? */ } ble_access_connecting_device_t; /* The Peer device Advertisement data */ @@ -109,7 +106,7 @@ typedef struct { uint8_t mxchip[6]; uint8_t adv_type; uint8_t alert_state; - aos_bt_device_address_t direct_addr; + mico_bt_device_address_t direct_addr; } ble_access_manufactor_data_t; /* @@ -119,13 +116,13 @@ typedef struct { // Device ID uint32_t device_id; // BT Socket for Every BLE Connection - aos_bt_smartbridge_socket_t socket; + mico_bt_smartbridge_socket_t socket; // A timer for Authentication Process - aos_timer_t timer; + mico_timer_t timer; // Authentication State uint8_t auth_state; // Is used ? - aos_bool_t used; + mico_bool_t used; // Some handles for a service of a BLE Connection. struct { // Notify Characteristic Value handle in MXCHIP Service @@ -155,14 +152,14 @@ typedef struct { extern OSStatus ble_access_connect_list_init (void); extern OSStatus ble_access_connect_list_deinit (void); -extern OSStatus ble_access_connect_list_add (const aos_bt_smart_device_t *remote_device, - aos_bool_t is_reported); -extern OSStatus ble_access_connect_list_get (aos_bt_smart_device_t **address, aos_bool_t *reported); -extern OSStatus ble_access_connect_list_get_by_address (aos_bt_smart_device_t **device, aos_bool_t *reported, - const aos_bt_device_address_t address); -extern OSStatus ble_access_connect_list_find_by_address(const aos_bt_device_address_t address); -extern OSStatus ble_access_connect_list_remove (aos_bt_smart_device_t *device); -extern OSStatus ble_access_connect_list_set_report (const aos_bt_smart_device_t *device, aos_bool_t is_reported); +extern OSStatus ble_access_connect_list_add (const mico_bt_smart_device_t *remote_device, + mico_bool_t is_reported); +extern OSStatus ble_access_connect_list_get (mico_bt_smart_device_t **address, mico_bool_t *reported); +extern OSStatus ble_access_connect_list_get_by_address (mico_bt_smart_device_t **device, mico_bool_t *reported, + const mico_bt_device_address_t address); +extern OSStatus ble_access_connect_list_find_by_address(const mico_bt_device_address_t address); +extern OSStatus ble_access_connect_list_remove (mico_bt_smart_device_t *device); +extern OSStatus ble_access_connect_list_set_report (const mico_bt_smart_device_t *device, mico_bool_t is_reported); /* * Utils function @@ -179,8 +176,8 @@ extern OSStatus ble_access_check_adv_type (const uint8_t *adv_data, uint8_t adv_type, ble_access_manufactor_data_t *manu_data); -extern void ble_access_set_scan_cfg (aos_bt_smart_scan_settings_t *scan_cfg, - aos_bool_t is_auto_scanning); +extern void ble_access_set_scan_cfg (mico_bt_smart_scan_settings_t *scan_cfg, + mico_bool_t is_auto_scanning); extern OSStatus ble_access_start_timer (ble_access_device_t *dev, event_handler_t timer_event_handle, void *arg); @@ -192,9 +189,9 @@ extern OSStatus ble_access_stop_timer (ble_access_device_t *dev); extern void ble_access_initialize_devices (void); extern void ble_access_deinit_devices (void); extern ble_access_device_t *ble_access_get_free_device (void); -extern void ble_access_release_device (aos_bool_t free, const ble_access_device_t *device); -//extern ble_access_device_t *ble_access_find_device_by_socket (const aos_bt_smartbridge_socket_t *socket); -extern ble_access_device_t *ble_access_find_device_by_address (const aos_bt_device_address_t address); +extern void ble_access_release_device (mico_bool_t free, const ble_access_device_t *device); +//extern ble_access_device_t *ble_access_find_device_by_socket (const mico_bt_smartbridge_socket_t *socket); +extern ble_access_device_t *ble_access_find_device_by_address (const mico_bt_device_address_t address); extern OSStatus ble_access_create_worker_thread(void); extern OSStatus ble_access_send_aync_event(event_handler_t event_handle, void *arg); diff --git a/device/bluetooth/mk3239/ble_app_framework_impl/adv_helper.c b/device/bluetooth/mk3239/ble_app_framework_impl/adv_helper.c new file mode 100644 index 0000000000..dde582150e --- /dev/null +++ b/device/bluetooth/mk3239/ble_app_framework_impl/adv_helper.c @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#include "internal/ble_helper_internal.h" + +/* Peripheral auto advertising settings */ +static mico_bt_smart_advertising_settings_t advertising_settings = { + .type = BT_SMART_UNDIRECTED_ADVERTISING, /**< Advertising type */ + .use_high_duty = MICO_TRUE, /**< Using high duty to start advertising */ + .high_duty_interval = MICO_BT_CFG_DEFAULT_HIGH_DUTY_ADV_MIN_INTERVAL, /**< High duty advertising interval */ + .high_duty_duration = 5, /**< High duty advertising duration in seconds (0 for infinite) */ + .low_duty_interval = MICO_BT_CFG_DEFAULT_LOW_DUTY_ADV_MIN_INTERVAL, /**< Low duty advertising interval */ + .low_duty_duration = 60, /**< Low duty advertising duration in seconds (0 for infinite) */ + + /* Used Directed Advertisement */ + .directed_advertisement_addr_type = BT_SMART_ADDR_TYPE_PUBLIC, + .directed_advertisement_addr = { 11, 22, 33, 44, 55, 66 }, +}; + +/* Set advertisement data and scanning response data */ +static OSStatus set_advertisement_data(const char *manufacture) +{ + OSStatus err = kNoErr; + + uint16_t uuid[1] = { UUID_SERVCLASS_DEVICE_INFO }; + mico_bt_ble_advert_data_t adv_data; + + mico_bt_ble_service_t advert_services_16 = { + .num_service = 1, + .list_cmpl = true, + .p_uuid = uuid, + }; + + mico_bt_ble_manu_t advert_manufacture = { + .len = strlen(manufacture), + .p_val = (uint8_t *)manufacture, + }; + + adv_data.flag = BTM_BLE_GENERAL_DISCOVERABLE_FLAG | BTM_BLE_BREDR_NOT_SUPPORTED; + adv_data.p_services = &advert_services_16; + adv_data.p_manu = &advert_manufacture; + + mico_bt_ble_set_advertisement_data( + BTM_BLE_ADVERT_BIT_DEV_NAME | BTM_BLE_ADVERT_BIT_SERVICE | BTM_BLE_ADVERT_BIT_FLAGS, + &adv_data ); + mico_bt_ble_set_scan_response_data( BTM_BLE_ADVERT_BIT_MANUFACTURER, &adv_data ); + + return err; +} + +/* Display Advertisement Arguments */ +static void start_advertisements(peripheral_hdl_t hdl, + mico_bt_smart_advertising_complete_callback_t advertisement_complete_handle) +{ + mico_bt_dev_status_t status; + mico_bt_peripheral_socket_status_t socket_status = PERIPHERAL_SOCKET_CONNECTED; + peripheral_socket_t *p = g_skt_head; + + printf("%d, hdl (%d) to operate\r\n", __LINE__, hdl); + + for (; p; p = p->next) { + printf("%d iterate on hdl (%d)\r\n", __LINE__, p->hdl); + if (p->hdl == hdl) { + break; + } + } + + if (!p) { + printf("%s %d no hdl found\r\n", __func__, __LINE__); + return; + } + + /* Check current connection state. */ + mico_bt_peripheral_get_socket_status(&p->skt, &socket_status ); + if ( socket_status != PERIPHERAL_SOCKET_DISCONNECTED ) { + printf( "Advertisements Started unsuccessfully! Existed connection" ); + printf( "" ); + return; + } + + /* Start advertisements */ + status = mico_bt_peripheral_start_advertisements( &advertising_settings, + advertisement_complete_handle ); + + /* LOG */ + printf(""); + if ( status == MICO_BT_SUCCESS ) { + printf( "Advertisements Started successfully! Arguments: " ); + } else if ( status == MICO_BT_ILLEGAL_VALUE ) { + printf( "Advertisements Started unsuccessfully! Illegal value: " ); + } else { + printf( "Advertisements Started unsuccessfully! Unknown error: " ); + } + printf( "" ); + //printf( "\t\t type : %s", pBT_AdvertStr( advertising_settings.type ) ); + printf( "\t\t duty : %s", + advertising_settings.use_high_duty == MICO_TRUE ? "High duty" : "Low duty" ); + printf( "\t\t high_duty_interval: %-4d (slots, 0.625ms)", + advertising_settings.high_duty_interval ); + printf( "\t\t high_duty_duration: %-4d (seconds)", + advertising_settings.high_duty_duration ); + printf( "\t\t low_duty_interval : %-4d (slots, 0.625ms)", + advertising_settings.low_duty_interval ); + printf( "\t\t low_duty_duration : %-4d (seconds)", + advertising_settings.low_duty_duration ); + printf( "" ); +} + +void ble_adv_start(mico_bt_smart_advertising_complete_callback_t adv_handler, + const char *manufacture, peripheral_hdl_t hdl) +{ + /* Set the advertising parameters and make the device discoverable */ + set_advertisement_data(manufacture); + + /* Start advertising */ + start_advertisements(hdl, adv_handler); +} + +void ble_adv_stop() +{ + +} diff --git a/device/bluetooth/mk3239/ble_app_framework_impl/ble_app_framework_impl.mk b/device/bluetooth/mk3239/ble_app_framework_impl/ble_app_framework_impl.mk new file mode 100644 index 0000000000..78bffe3b79 --- /dev/null +++ b/device/bluetooth/mk3239/ble_app_framework_impl/ble_app_framework_impl.mk @@ -0,0 +1,5 @@ +NAME := ble_app_helper_impl + +$(NAME)_SOURCES := adv_helper.c init_helper.c gatt_attr_helper.c + +$(NAME)_COMPONENTS := bluetooth.mk3239.bt_smart bluetooth.ble_app_framework bluetooth.mk3239.low_energy diff --git a/device/bluetooth/mk3239/ble_app_framework_impl/gatt_attr_helper.c b/device/bluetooth/mk3239/ble_app_framework_impl/gatt_attr_helper.c new file mode 100644 index 0000000000..f9988a2ab9 --- /dev/null +++ b/device/bluetooth/mk3239/ble_app_framework_impl/gatt_attr_helper.c @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#include "internal/ble_helper_internal.h" + +ble_gatt_attr_t *ble_attr_add(uint16_t hdl, uint16_t val_len, const uint8_t *val) +{ + return mico_bt_peripheral_ext_attribute_add(hdl, val_len, val, NULL); +} + +void ble_attr_indicate(ble_gatt_attr_t *attr, peripheral_hdl_t hdl, + uint16_t len, const uint8_t *data) +{ + peripheral_socket_t *p = g_skt_head; + + for (; p; p = p->next) + if (p->hdl == hdl) { + break; + } + + if (!p) { + return; + } + + mico_bt_peripheral_ext_attribute_value_write(attr, len, 0, data); + mico_bt_peripheral_gatt_indicate_attribute_value(&p->skt, attr); +} + +void ble_attr_notify(ble_gatt_attr_t *attr, peripheral_hdl_t hdl, + uint16_t len, const uint8_t *data) +{ + peripheral_socket_t *p = g_skt_head; + + for (; p; p = p->next) + if (p->hdl == hdl) { + break; + } + + if (!p) { + return; + } + + mico_bt_peripheral_ext_attribute_value_write(attr, len, 0, data); + mico_bt_peripheral_gatt_notify_attribute_value(&p->skt, attr); +} diff --git a/device/bluetooth/mk3239/ble_app_framework_impl/init_helper.c b/device/bluetooth/mk3239/ble_app_framework_impl/init_helper.c new file mode 100644 index 0000000000..097e2d6871 --- /dev/null +++ b/device/bluetooth/mk3239/ble_app_framework_impl/init_helper.c @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#include "internal/ble_helper_internal.h" + +/* Peripheral security settings */ +static const mico_bt_smart_security_settings_t security_settings = { + .timeout_second = 15, + .io_capabilities = BT_SMART_IO_DISPLAY_ONLY, + .authentication_requirements = BT_SMART_AUTH_REQ_BONDING, + .oob_authentication = BT_SMART_OOB_AUTH_NONE, + .max_encryption_key_size = 16, + .master_key_distribution = BT_SMART_DISTRIBUTE_ALL_KEYS, + .slave_key_distribution = BT_SMART_DISTRIBUTE_ALL_KEYS, +}; + +peripheral_socket_t *g_skt_head = NULL; + +static uint32_t g_ble_hdl = 0; +peripheral_hdl_t ble_peripheral_init(peripheral_init_t *p, + ble_peripheral_conn_cb_t c, + ble_peripheral_disconn_cb_t disc, + const uint8_t *db, int db_len) +{ + peripheral_socket_t *s = (peripheral_socket_t *)aos_malloc((sizeof(peripheral_socket_t))); + + // mutex? + s->hdl = g_ble_hdl++; + s->next = g_skt_head; + g_skt_head = s; + + printf("%d, hdl (%d) inserted\r\n", __LINE__, s->hdl); + + /* Initialize MICO bluetooth Framework */ + mico_bt_init(MICO_BT_HCI_MODE, p->dev_name, p->client_links, p->server_links); + + /* Initialize MICO bluetooth peripheral */ + mico_bt_peripheral_init(&s->skt, &security_settings, c, disc, NULL); + + /* Build BT Stack layer GATT database */ + mico_bt_gatt_db_init(db, db_len); + + return s->hdl; +} + +// Mutex? +void ble_peripheral_deinit(peripheral_hdl_t hdl) +{ + peripheral_socket_t *p, *q; + + for (p = g_skt_head; p; q = p, p = p->next) + if (p->hdl == hdl) { + break; + } + + if (!p) { + printf("%s %d no hdl found\r\n", __func__, __LINE__); + return; + } + + if (p == g_skt_head) { + g_skt_head = p->next; + mico_free(p); + } else { + q->next = p->next; + mico_free(p); + } + + mico_bt_peripheral_deinit(); + mico_bt_deinit(); +} diff --git a/device/bluetooth/mk3239/ble_app_framework_impl/internal/ble_helper_internal.h b/device/bluetooth/mk3239/ble_app_framework_impl/internal/ble_helper_internal.h new file mode 100644 index 0000000000..0c9569d94f --- /dev/null +++ b/device/bluetooth/mk3239/ble_app_framework_impl/internal/ble_helper_internal.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#ifndef _BLE_HELPER_INTERNAL_H_ +#define _BLE_HELPER_INTERNAL_H_ + +#include "ble_app_framework.h" +#include +#include "sdpdefs.h" +#include "mico_bt_cfg.h" +#include "mico_bt.h" +#include "mico_bt_peripheral.h" + +typedef struct peripheral_socket_s { + peripheral_hdl_t hdl; + mico_bt_peripheral_socket_t skt; + struct peripheral_socket_s *next; +} peripheral_socket_t; + +extern peripheral_socket_t *g_skt_head; + +#endif diff --git a/framework/bluetooth/smartbt/LinkListUtils.c b/device/bluetooth/mk3239/bt_smart/LinkListUtils.c similarity index 89% rename from framework/bluetooth/smartbt/LinkListUtils.c rename to device/bluetooth/mk3239/bt_smart/LinkListUtils.c index 374f58d18a..39ca5bf82b 100644 --- a/framework/bluetooth/smartbt/LinkListUtils.c +++ b/device/bluetooth/mk3239/bt_smart/LinkListUtils.c @@ -2,27 +2,6 @@ * Copyright (C) 2015-2017 Alibaba Group Holding Limited */ -/** -****************************************************************************** -* @file LinkListUtils.c -* @author William Xu -* @version V1.0.0 -* @date 12-Jan-2015 -* @brief This file contains function called by link list operation -****************************************************************************** -* @attention -* -* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS -* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE -* TIME. AS A RESULT, MXCHIP Inc. SHALL NOT BE HELD LIABLE FOR ANY -* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING -* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE -* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. -* -*

© COPYRIGHT 2015 MXCHIP Inc.

-****************************************************************************** -*/ - #include "LinkListUtils.h" #include "debug.h" diff --git a/framework/bluetooth/smartbt/StringUtils.c b/device/bluetooth/mk3239/bt_smart/StringUtils.c similarity index 96% rename from framework/bluetooth/smartbt/StringUtils.c rename to device/bluetooth/mk3239/bt_smart/StringUtils.c index d8a80bd259..95c1f88bab 100644 --- a/framework/bluetooth/smartbt/StringUtils.c +++ b/device/bluetooth/mk3239/bt_smart/StringUtils.c @@ -1,35 +1,3 @@ -/** - ****************************************************************************** - * @file StringUtils.c - * @author William Xu - * @version V1.0.0 - * @date 05-May-2014 - * @brief This file contains function for manipulating strings.. - ****************************************************************************** - * - * The MIT License - * Copyright (c) 2014 MXCHIP Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR - * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ****************************************************************************** - */ - - #include "StringUtils.h" #include "debug.h" #include diff --git a/framework/bluetooth/smartbt/smartbt.mk b/device/bluetooth/mk3239/bt_smart/bt_smart.mk similarity index 52% rename from framework/bluetooth/smartbt/smartbt.mk rename to device/bluetooth/mk3239/bt_smart/bt_smart.mk index 01ba1e91f6..303077d7c7 100644 --- a/framework/bluetooth/smartbt/smartbt.mk +++ b/device/bluetooth/mk3239/bt_smart/bt_smart.mk @@ -1,21 +1,18 @@ -NAME := smartbt +NAME := bt_smart GLOBAL_INCLUDES += include $(NAME)_INCLUDES += internal -$(NAME)_COMPONENTS := protocols.bluetooth - -$(NAME)_SOURCES := bt_management.c \ - bt_peripheral.c \ - bt_smartbridge_gatt.c \ - bt_smartbridge.c \ - bt_smartbridge_cfg.c \ +$(NAME)_SOURCES := mico_bt_management.c \ + mico_bt_peripheral.c \ + mico_bt_smartbridge_gatt.c \ + mico_bt_smartbridge.c \ + mico_bt_smartbridge_cfg.c \ internal/bt_peripheral_stack_interface.c \ internal/bt_smart_attribute.c \ internal/bt_smartbridge_att_cache_manager.c \ internal/bt_smartbridge_socket_manager.c \ internal/bt_smartbridge_helper.c \ internal/bt_smartbridge_stack_interface.c \ - LinkListUtils.c StringUtils.c \ - internal/os_wrapper.c + LinkListUtils.c StringUtils.c diff --git a/framework/bluetooth/smartbt/include/LinkListUtils.h b/device/bluetooth/mk3239/bt_smart/include/LinkListUtils.h similarity index 92% rename from framework/bluetooth/smartbt/include/LinkListUtils.h rename to device/bluetooth/mk3239/bt_smart/include/LinkListUtils.h index 95e82c3bd4..308938fd39 100644 --- a/framework/bluetooth/smartbt/include/LinkListUtils.h +++ b/device/bluetooth/mk3239/bt_smart/include/LinkListUtils.h @@ -1,18 +1,11 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ +#pragma once -#ifndef _LINK_LIST_UTIL_H_ -#define _LINK_LIST_UTIL_H_ +#include "common.h" #ifdef __cplusplus extern "C" { #endif -#include -#include -#include "../internal/os_wrapper.h" - /****************************************************** * Type Definitions ******************************************************/ @@ -78,8 +71,10 @@ OSStatus linked_list_remove_node_from_front( linked_list_t *list, linked_list_no OSStatus linked_list_remove_node_from_rear( linked_list_t *list, linked_list_node_t **removed_node ); + + #ifdef __cplusplus } /* extern "C" */ #endif -#endif + diff --git a/framework/bluetooth/smartbt/include/StringUtils.h b/device/bluetooth/mk3239/bt_smart/include/StringUtils.h similarity index 94% rename from framework/bluetooth/smartbt/include/StringUtils.h rename to device/bluetooth/mk3239/bt_smart/include/StringUtils.h index 8a17d9d170..902a68d478 100644 --- a/framework/bluetooth/smartbt/include/StringUtils.h +++ b/device/bluetooth/mk3239/bt_smart/include/StringUtils.h @@ -1,13 +1,19 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ #ifndef __StringUtils_h__ #define __StringUtils_h__ #include -#include -#include +#include "common.h" + + +/** @addtogroup MICO_Middleware_Interface + * @{ + */ + +/** @defgroup MICO_String_Utils MiCO String Utils + * @brief Provide String operations APIs. + * @{ + */ // ==== STRING SIZE UTILS ==== //--------------------------------------------------------------------------------------------------------------------------- @@ -38,7 +44,7 @@ void formatMACAddr(char *destAddr, char *srcAddr); */ unsigned int str2hex(unsigned char *ibuf, unsigned char *obuf, unsigned int olen); -/* +/** * @brief Convert an Integer to a string * * @param str: The string @@ -48,7 +54,8 @@ unsigned int str2hex(unsigned char *ibuf, unsigned char *obuf, unsigned int olen */ void Int2Str(uint8_t *str, int32_t intnum); -/* + +/** * @brief Convert a string to an integer * * @param inputstr: The string to be converted @@ -60,7 +67,7 @@ void Int2Str(uint8_t *str, int32_t intnum); uint32_t Str2Int(uint8_t *inputstr, int32_t *intnum); -/* +/** * @brief Allocate a memory to store the string * * @param src: ? @@ -71,7 +78,7 @@ char *__strdup(const char *src); -/* +/** * @brief Allocate a memory to store the string, and transfer '.' to '\.' * * @param src: ? @@ -84,7 +91,7 @@ char *__strdup_trans_dot(char *src); #define TextToMACAddress( TEXT, SIZE, ADDR ) TextToHardwareAddress( TEXT, SIZE, 6, ADDR ) -/* +/** * @brief ? * * @param inText : ? @@ -101,7 +108,7 @@ unsigned int str2hex(unsigned char *ibuf, unsigned char *obuf, unsigned int olen // ==== BYTE BUFFER TO STRING CONVERSION UTILS ==== -/* +/** * @brief * * @param inBuf :? @@ -112,7 +119,7 @@ unsigned int str2hex(unsigned char *ibuf, unsigned char *obuf, unsigned int olen char *DataToCString( const uint8_t *inBuf, size_t inBufLen ); -/* +/** * @brief ? * * @param inBuf :? @@ -123,7 +130,7 @@ char *DataToCString( const uint8_t *inBuf, size_t inBufLen ); char *DataToHexString( const uint8_t *inBuf, size_t inBufLen ); -/* +/** * @brief ? * * @param inBuf :? @@ -134,7 +141,7 @@ char *DataToHexString( const uint8_t *inBuf, size_t inBufLen ); char *DataToHexStringWithSpaces( const uint8_t *inBuf, size_t inBufLen ); -/* +/** * @brief ? * * @param inBuf :? @@ -145,7 +152,7 @@ char *DataToHexStringWithSpaces( const uint8_t *inBuf, size_t inBufLen ); char *DataToHexStringWithColons( const uint8_t *inBuf, size_t inBufLen ); // ==== STRING COMPARE UTILS ==== -/* +/** * @brief ? * * @param inStr :? @@ -158,7 +165,7 @@ int strnicmp_suffix( const void *inStr, size_t inMaxLen, const char *inSuffix ); -/* +/** * @brief ? * * @param inS1 :? @@ -170,7 +177,7 @@ int strnicmp_suffix( const void *inStr, size_t inMaxLen, const char *inSuffix ); int strnicmp( const char *inS1, const char *inS2, size_t inMax ); -/* +/** * @brief ? * * @param inS1 :? @@ -182,7 +189,7 @@ int strnicmp( const char *inS1, const char *inS2, size_t inMax ); int strnicmpx( const void *inS1, size_t inN, const char *inS2 ); -/* +/** * @brief ? * * @param inStr :? @@ -194,7 +201,7 @@ int strnicmpx( const void *inS1, size_t inN, const char *inS2 ); char *strnstr_suffix( const char *inStr, size_t inMaxLen, const char *inSuffix); -/* +/** * @brief ? * * @param inStr : ? @@ -205,7 +212,7 @@ char *strnstr_suffix( const char *inStr, size_t inMaxLen, const char *inSuffix); */ int VSNScanF( const void *inString, size_t inSize, const char *inFormat, va_list inArgs ); -/* +/** * @brief ? * * @param value : ? @@ -217,7 +224,7 @@ int VSNScanF( const void *inString, size_t inSize, const char *inFormat, va_list */ uint8_t unsigned_to_hex_string( uint32_t value, char *output, uint8_t min_length, uint8_t max_length ); -/* +/** * @brief ? * * @param string : ? @@ -230,7 +237,7 @@ uint8_t unsigned_to_hex_string( uint32_t value, char *output, uint8_t min_length uint8_t string_to_unsigned( const char *string, uint8_t str_length, uint32_t *value_out, uint8_t is_hex ); -/* +/** * @brief ? * * @param start :? @@ -247,7 +254,7 @@ uint8_t unsigned_to_decimal_string( uint32_t value, char *output, uint8_t min_le #if defined (__CC_ARM) #define strdup __strdup -/* +/** * @brief ? * * @param s : @@ -258,5 +265,14 @@ uint8_t unsigned_to_decimal_string( uint32_t value, char *output, uint8_t min_le size_t strnlen(const char *s, size_t count); #endif +/** + * @} + */ + +/** + * @} + */ + + #endif // __StringUtils_h__ diff --git a/framework/bluetooth/smartbt/include/smartbt.h b/device/bluetooth/mk3239/bt_smart/include/mico_bt.h similarity index 56% rename from framework/bluetooth/smartbt/include/smartbt.h rename to device/bluetooth/mk3239/bt_smart/include/mico_bt.h index b6c7a5f7bd..3079e3e156 100644 --- a/framework/bluetooth/smartbt/include/smartbt.h +++ b/device/bluetooth/mk3239/bt_smart/include/mico_bt.h @@ -1,14 +1,13 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited +/** @file + * Defines functions for using the MICO Bluetooth Framework */ -#ifndef _SMART_BT_H_ -#define _SMART_BT_H_ +#pragma once -#include "../internal/os_wrapper.h" -#include "aos_bt_types.h" -#include "aos_bt_dev.h" -#include "smartbt_smart_interface.h" +#include "mico.h" +#include "mico_bt_types.h" +#include "mico_bt_dev.h" +#include "mico_bt_smart_interface.h" #ifdef __cplusplus extern "C" { @@ -26,22 +25,22 @@ extern "C" { * Enumerations ******************************************************/ -/** AOS Bluetooth Framework mode of operation +/** MICO Bluetooth Framework mode of operation */ typedef enum { - AOS_BT_MPAF_MODE, /* The framework uses Multi-Profile Application Framework (MPAF). The entire Bluetooth stack runs on the controller. The host controls the controller using remote procedure calls (RPC) */ - AOS_BT_HCI_MODE, /* The framework uses standard Host Controller Interface (HCI). The upper stack runs on the host and the lower stack runs on the controller */ -} aos_bt_mode_t; + MICO_BT_MPAF_MODE, /**< The framework uses Multi-Profile Application Framework (MPAF). The entire Bluetooth stack runs on the controller. The host controls the controller using remote procedure calls (RPC) */ + MICO_BT_HCI_MODE, /**< The framework uses standard Host Controller Interface (HCI). The upper stack runs on the host and the lower stack runs on the controller */ +} mico_bt_mode_t; /****************************************************** * Type Definitions ******************************************************/ -/** AOS Bluetooth packet. +/** MICO Bluetooth packet. * An opaque data type representing a generic, zero-copy packet used for transporting data to/from the Bluetooth controller. */ -typedef struct bt_packet aos_bt_packet_t; -//typedef platform_uart_config_t aos_uart_config_t; +typedef struct bt_packet mico_bt_packet_t; +typedef platform_uart_config_t mico_uart_config_t; /****************************************************** * Structures @@ -51,26 +50,26 @@ typedef struct bt_packet aos_bt_packet_t; * Global Variables ******************************************************/ -extern aos_worker_thread_t aos_bt_worker_thread; -extern aos_worker_thread_t aos_bt_evt_worker_thread; +extern mico_worker_thread_t mico_bt_worker_thread; +extern mico_worker_thread_t mico_bt_evt_worker_thread; -#define AOS_BT_WORKER_THREAD ((aos_worker_thread_t *)&aos_bt_worker_thread) -#define AOS_BT_EVT_WORKER_THREAD ((aos_worker_thread_t *)&aos_bt_evt_worker_thread) +#define MICO_BT_WORKER_THREAD ((mico_worker_thread_t *)&mico_bt_worker_thread) +#define MICO_BT_EVT_WORKER_THREAD ((mico_worker_thread_t *)&mico_bt_evt_worker_thread) /****************************************************** * Function Declarations ******************************************************/ /*****************************************************************************/ -/** @defgroup aosbt Bluetooth +/** @defgroup micobt Bluetooth * - * AOS Bluetooth Framework Functions + * MICO Bluetooth Framework Functions */ /*****************************************************************************/ /*****************************************************************************/ /** @addtogroup btfwmgmt Framework - * @ingroup aosbt + * @ingroup micobt * * Bluetooth Framework Management Functions * @@ -79,71 +78,71 @@ extern aos_worker_thread_t aos_bt_evt_worker_thread; */ /*****************************************************************************/ -/** Initialise the AOS Bluetooth Framework +/** Initialise the MICO Bluetooth Framework * * This function initialises the local Bluetooth device and the framework core * components to operate in the mode specified. Upon return, the device is * powered. * - * @note To switch mode, invoke @ref aos_bt_deinit to tear down the current + * @note To switch mode, invoke @ref mico_bt_deinit to tear down the current * operating mode, and call this function with the desired mode. * - * @param mode : The framework mode of operation, only AOS_BT_HCI_MODE is + * @param mode : The framework mode of operation, only MICO_BT_HCI_MODE is * supported now * @param device_name : A user-friendly name of the local Bluetooth device. A * name longer than 21 characters will be truncated. * @param client_links : Max cocurrent connections as a BLE client * @param server_links : * - * @return AOS_SUCCESS : on success; - * AOS_ERROR : if an error occurred + * @return MICO_SUCCESS : on success; + * MICO_ERROR : if an error occurred */ -OSStatus aos_bt_init( aos_bt_mode_t mode, const char *device_name, uint8_t client_links, uint8_t server_links ); +OSStatus mico_bt_init( mico_bt_mode_t mode, const char *device_name, uint8_t client_links, uint8_t server_links ); -/** Deinitialise the AOS Bluetooth Framework +/** Deinitialise the MICO Bluetooth Framework * * This function tears down all active framework components. Depending on the * hardware platform used, it may also power down the Bluetooth device. * - * @return AOS_SUCCESS : on success; - * AOS_ERROR : if an error occurred + * @return MICO_SUCCESS : on success; + * MICO_ERROR : if an error occurred */ -OSStatus aos_bt_deinit( void ); +OSStatus mico_bt_deinit( void ); /** Initialise the device address of the local Bluetooth device * * This function provides users with a option to overwrite the default address of - * the local Bluetooth device with the address provided. Once called, @ref aos_bt_init() + * the local Bluetooth device with the address provided. Once called, @ref mico_bt_init() * overwrites the default address with the address provided. Users can selectively * overwrite bits of the default address by setting the correspondping bits in the * 'mask' argument to 1. * - * @warning When used, this function *MUST* be called before aos_bt_init() + * @warning When used, this function *MUST* be called before mico_bt_init() * * @param[in] address : new address * @param[in] mask : masking bits * - * @return AOS_SUCCESS : on success; - * AOS_ERROR : if an error occurred + * @return MICO_SUCCESS : on success; + * MICO_ERROR : if an error occurred */ -OSStatus aos_bt_init_address( const aos_bt_device_address_t *address, const aos_bt_device_address_t *mask ); +OSStatus mico_bt_init_address( const mico_bt_device_address_t *address, const mico_bt_device_address_t *mask ); /** Start manufacturing test mode * * @param[in] config : Configuration of the UART peripheral that connects to the host PC * - * @return AOS_SUCCESS : on success; - * AOS_ERROR : if an error occurred + * @return MICO_SUCCESS : on success; + * MICO_ERROR : if an error occurred */ -//OSStatus aos_bt_start_mfgtest_mode( const aos_uart_config_t* config ); +OSStatus mico_bt_start_mfgtest_mode( const mico_uart_config_t *config ); /** @} */ /*****************************************************************************/ /** @addtogroup btdevmgmt Device - * @ingroup aosbt + * @ingroup micobt * * Bluetooth Device Management Functions * @@ -156,44 +155,44 @@ OSStatus aos_bt_init_address( const aos_bt_device_address_t *address, const aos_ * * @param[out] address : device address * - * @return AOS_TRUE : is device address successfully retrieved; - * AOS_FALSE : if not or if an error occurred + * @return MICO_TRUE : is device address successfully retrieved; + * MICO_FALSE : if not or if an error occurred */ -OSStatus aos_bt_device_get_address( aos_bt_device_address_t *address ); +OSStatus mico_bt_device_get_address( mico_bt_device_address_t *address ); /** Retrieve the user-friendly name of the local Bluetooth device * * @return pointer to the device name string */ -const char *aos_bt_device_get_name( void ); +const char *mico_bt_device_get_name( void ); /** Check if the local Bluetooth device is powered * - * @return AOS_TRUE : if powered on; - * AOS_FALSE : if not powered or if an error occurred + * @return MICO_TRUE : if powered on; + * MICO_FALSE : if not powered or if an error occurred */ -aos_bool_t aos_bt_device_is_on( void ); +mico_bool_t mico_bt_device_is_on( void ); /** Check if the local Bluetooth device is connectable state * - * @return AOS_TRUE : is in connectable state; - * AOS_FALSE : if not or if an error occurred + * @return MICO_TRUE : is in connectable state; + * MICO_FALSE : if not or if an error occurred */ -aos_bool_t aos_bt_device_is_connectable( void ); +mico_bool_t mico_bt_device_is_connectable( void ); /** Check if the local Bluetooth device is discoverable state * - * @return AOS_TRUE : is in discoverable state; - * AOS_FALSE : if not or if an error occurred + * @return MICO_TRUE : is in discoverable state; + * MICO_FALSE : if not or if an error occurred */ -aos_bool_t aos_bt_device_is_discoverable( void ); +mico_bool_t mico_bt_device_is_discoverable( void ); /** @} */ /*****************************************************************************/ /** @addtogroup btdevmgmt Device - * @ingroup aosbt + * @ingroup micobt * * Bluetooth Pairing Management Functions * @@ -202,45 +201,45 @@ aos_bool_t aos_bt_device_is_discoverable( void ); */ /*****************************************************************************/ -/** Start a AOS bluetooth LE pairing procedure +/** Start a MiCO bluetooth LE pairing procedure * * * @param address : The remote device address * @param type : The remote device address type * @param settings : Security settings used in pairing procedure * - * @return AOS_BT_PENDING if successfully initiated, - * AOS_BT_SUCCESS if already paired to the device, else + * @return MICO_BT_PENDING if successfully initiated, + * MICO_BT_SUCCESS if already paired to the device, else * error code */ -OSStatus aos_bt_start_pairing( aos_bt_device_address_t address, aos_bt_smart_address_type_t type, - const aos_bt_smart_security_settings_t *settings ); +OSStatus mico_bt_start_pairing( mico_bt_device_address_t address, mico_bt_smart_address_type_t type, + const mico_bt_smart_security_settings_t *settings ); -/** Stop a AOS bluetooth LE pairing procedure +/** Stop a MiCO bluetooth LE pairing procedure * * @param address : The remote device address * - * @return AOS_BT_PENDING if cancel initiated, - * AOS_BT_SUCCESS if cancel has completed already, else error code. + * @return MICO_BT_PENDING if cancel initiated, + * MICO_BT_SUCCESS if cancel has completed already, else error code. */ -OSStatus aos_bt_stop_pairing( aos_bt_device_address_t address ); +OSStatus mico_bt_stop_pairing( mico_bt_device_address_t address ); -/** Satrt a AOS bluetooth LE encryption procedure +/** Satrt a MiCO bluetooth LE encryption procedure * * @param address : The remote device address * - * @return AOS_BT_SUCCESS : already encrypted - * AOS_BT_PENDING : command will be returned in the callback - * AOS_BT_WRONG_MODE : connection not up. - * AOS_BT_BUSY : security procedures are currently active + * @return MICO_BT_SUCCESS : already encrypted + * MICO_BT_PENDING : command will be returned in the callback + * MICO_BT_WRONG_MODE : connection not up. + * MICO_BT_BUSY : security procedures are currently active */ -OSStatus aos_bt_start_encryption( aos_bt_device_address_t *address ); +OSStatus mico_bt_start_encryption( mico_bt_device_address_t *address ); /** @} */ /*****************************************************************************/ /** @addtogroup btpktmgmt Packet - * @ingroup aosbt + * @ingroup micobt * * Bluetooth Packet Management Functions * @@ -249,18 +248,18 @@ OSStatus aos_bt_start_encryption( aos_bt_device_address_t *address ); */ /*****************************************************************************/ -/** Delete a AOS Bluetooth packet +/** Delete a MICO Bluetooth packet * * This function returns the packet's memory space back to the source, allowing * for reuse. * * @param packet : The pointer to the packet to delete - * @return AOS_SUCCESS : on success; - * AOS_BADARG : if bad argument(s) are inserted; - * AOS_ERROR : if an error occurred. + * @return MICO_SUCCESS : on success; + * MICO_BADARG : if bad argument(s) are inserted; + * MICO_ERROR : if an error occurred. */ -OSStatus aos_bt_packet_delete( aos_bt_packet_t *packet ); +OSStatus mico_bt_packet_delete( mico_bt_packet_t *packet ); /** Get a pointer to the packet data * @@ -276,12 +275,12 @@ OSStatus aos_bt_packet_delete( aos_bt_packet_t *packet ); * @param available_space : A pointer that will receive the available data * space in the packet in bytes * - * @return AOS_SUCCESS : on success; - * AOS_BADARG : if bad argument(s) are inserted; - * AOS_ERROR : if an error occurred. + * @return MICO_SUCCESS : on success; + * MICO_BADARG : if bad argument(s) are inserted; + * MICO_ERROR : if an error occurred. */ -OSStatus aos_bt_packet_get_data( const aos_bt_packet_t *packet, uint8_t **data, uint32_t *current_data_size, - uint32_t *available_space ); +OSStatus mico_bt_packet_get_data( const mico_bt_packet_t *packet, uint8_t **data, uint32_t *current_data_size, + uint32_t *available_space ); /** Set the end of the packet data * @@ -291,11 +290,11 @@ OSStatus aos_bt_packet_get_data( const aos_bt_packet_t *packet, uint8_t **data, * @param packet : The pointer to the packet * @param data_end : The pointer to the end of the data section in the packet - * @return AOS_SUCCESS : on success; - * AOS_BADARG : if bad argument(s) are inserted; - * AOS_ERROR : if an error occurred + * @return MICO_SUCCESS : on success; + * MICO_BADARG : if bad argument(s) are inserted; + * MICO_ERROR : if an error occurred */ -OSStatus aos_bt_packet_set_data_end( aos_bt_packet_t *packet, const uint8_t *data_end ); +OSStatus mico_bt_packet_set_data_end( mico_bt_packet_t *packet, const uint8_t *data_end ); /** @} */ @@ -322,7 +321,7 @@ OSStatus aos_bt_packet_set_data_end( aos_bt_packet_t *packet, const uint8_t *dat * * @return @ref OSStatus */ -OSStatus aos_bt_get_whitelist_capability( uint8_t *size ); +OSStatus mico_bt_get_whitelist_capability( uint8_t *size ); /** Clear the whitelist @@ -333,12 +332,10 @@ OSStatus aos_bt_get_whitelist_capability( uint8_t *size ); * * @return @ref OSStatus */ -OSStatus aos_bt_clear_whitelist( void ); +OSStatus mico_bt_clear_whitelist( void ); /** @} */ #ifdef __cplusplus } /* extern "C" */ #endif - -#endif diff --git a/device/bluetooth/mk3239/bt_smart/include/mico_bt_peripheral.h b/device/bluetooth/mk3239/bt_smart/include/mico_bt_peripheral.h new file mode 100644 index 0000000000..11607b9e3d --- /dev/null +++ b/device/bluetooth/mk3239/bt_smart/include/mico_bt_peripheral.h @@ -0,0 +1,399 @@ +#pragma once + +#include "mico_bt_smart_interface.h" +#include "LinkListUtils.h" +#include "mico_bt_gatt.h" +/** @file + * Defines functions for bridging Bluetooth Smart with Wi-Fi + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************** + * Macros + ******************************************************/ + +/****************************************************** + * Enumerations + ******************************************************/ + +/** + * BT smart peripheral socket status + */ +typedef enum { + PERIPHERAL_SOCKET_DISCONNECTED, /**< Socket is disconnected */ + PERIPHERAL_SOCKET_CONNECTING, /**< Socket is in connecting state */ + PERIPHERAL_SOCKET_CONNECTED, /**< Socket is connected with a remote device */ +} mico_bt_peripheral_socket_status_t; + +/** + * Advertising filter policy + */ +typedef enum { + PERIPHERAL_ADVERT_FILTER_ALL_CONNECTION_REQ_ALL_SCAN_REQ = 0x00, /**< Process scan and connection requests from all devices (i.e., the White List is not in use) (default) */ + PERIPHERAL_ADVERT_FILTER_ALL_CONNECTION_REQ_WHITELIST_SCAN_REQ = 0x01, /**< Process connection requests from all devices and only scan requests from devices that are in the White List. */ + PERIPHERAL_ADVERT_FILTER_WHITELIST_CONNECTION_REQ_ALL_SCAN_REQ = 0x02, /**< Process scan requests from all devices and only connection requests from devices that are in the White List */ + PERIPHERAL_ADVERT_FILTER_WHITELIST_CONNECTION_REQ_WHITELIST_SCAN_REQ = 0x03, /**< Process scan and connection requests only from devices in the White List. */ + PERIPHERAL_ADVERT_FILTER_MAX +} mico_bt_peripheral_adv_filter_policy_t; + + +/****************************************************** + * Type Definitions + ******************************************************/ + +typedef struct _bt_ext_attribute_value_t mico_bt_ext_attribute_value_t; + +/** + * Socket to create a BT smart peripheral connection + */ +typedef struct mico_bt_peripheral_socket mico_bt_peripheral_socket_t; + +/** + * Socket connection callback + */ +typedef OSStatus (* mico_bt_peripheral_connection_callback_t) ( mico_bt_peripheral_socket_t *socket ); + +/** + * Socket disconnection callback + */ +typedef OSStatus (* mico_bt_peripheral_disconnection_callback_t) ( mico_bt_peripheral_socket_t *socket ); + +/** + * Attrubute request callback + */ +typedef mico_bt_gatt_status_t (* mico_bt_peripheral_attribute_handler)( mico_bt_ext_attribute_value_t *attribute, + mico_bt_gatt_request_type_t op ); + + +/****************************************************** + * Structures + ******************************************************/ + + +#define BT_SMART_S_NONE ( 0x0 ) +#define BT_SMART_S_INDICATE ( 0x1 << 0 ) +#define BT_SMART_S_NOTIFICATION ( 0x1 << 1 ) + +typedef uint8_t bt_smart_server_send_type_t; + +struct _bt_ext_attribute_value_t { + linked_list_node_t this_node; /* Linked-list node of this characteristic */ + uint16_t handle; /* Attribute handle */ + uint16_t value_length; /* Attribute value length */ + uint16_t value_buffer_length; /* Attribute value buffer length */ + uint8_t *p_value; /* Pointer to characteristic value */ + mico_bt_peripheral_attribute_handler attribute_handler; +}; + + +/** + * Socket to create a Smart Peripheral connection + * @warning The content of the socket structure is for INTERNAL USE only. Modifying + * the content of this structure is prohibited. Please use the Bluetooth SmartBridge + * API to retrieve socket information. + */ +struct mico_bt_peripheral_socket { + mico_bt_smart_device_t + remote_device; /**< Remote Bluetooth device MiCO is connected with (BLE server) */ + uint16_t + connection_handle; /**< Connection handle */ + uint8_t + state; /**< Internal state */ + uint8_t + actions; /**< Internal socket actions */ + mico_bt_peripheral_connection_callback_t + connection_callback; /**< Callback for handling connection event by remote device */ + mico_bt_peripheral_disconnection_callback_t + disconnection_callback; /**< Callback for handling disconnection event by remote device */ + mico_bt_smart_bonding_callback_t + bonding_callback; /**< Callback for handling bonding evnet by remote device */ + mico_bt_smart_security_settings_t + security_settings; /**< Security settings */ + mico_bt_smart_bond_request_t + bond_req; /**< Bond Request Structure */ + mico_semaphore_t + semaphore; /**< Semaphore */ + linked_list_t + attribute_database; /**< Attribute database */ + uint16_t mtu; +}; + +/****************************************************** + * Function declarations + ******************************************************/ + +/*****************************************************************************/ +/** @addtogroup smartbridge SmartBridge + * @ingroup micobt + * + * Bluetooth SmartBridge Functions + * + * + * @{ + */ +/*****************************************************************************/ + +/*****************************************************************************/ +/** @addtogroup sbmgmt SmartBridge Management + * @ingroup smartbridge + * + * SmartBridge Management Functions + * + * + * @{ + */ +/*****************************************************************************/ + + +/** Initialise the MiCO BT peripheral + * + * @note + * This function initialises: + * \li Generic Attribute Profile (GATT) Server + * \li Generic Access Profile (GAP) Peripheral Role + * \li Security settings used when conneted by BT client + * \li Initialises the socket internals to make it ready to connect to + * a Bluetooth Smart Central + * + * + * @return MICO_BT_SUCCESS: success , else @ref OSStatus + */ +OSStatus mico_bt_peripheral_init( mico_bt_peripheral_socket_t *socket, + const mico_bt_smart_security_settings_t *settings, + mico_bt_peripheral_connection_callback_t connection_callback, + mico_bt_peripheral_disconnection_callback_t disconnection_callback, + mico_bt_smart_bonding_callback_t bonding_callback ); + + +/** Deinitialise the MiCO BT peripheral + * + * @note + * This function deinitialises: + * \li Generic Attribute Profile (GATT) Server + * \li Generic Access Profile (GAP) Peripheral Role + * \li Create BT peripheral Socket ready to be connected + * + * @return MICO_BT_SUCCESS: success + */ +OSStatus mico_bt_peripheral_deinit( void ); + + +/** @} */ + + +/*****************************************************************************/ +/** @addtogroup sbsock BT peripheral Socket and Connection Management + * @ingroup SmartPeripheral + * + * BT peripheral Socket and Connection Functions + * + * + * @{ + */ +/*****************************************************************************/ + + +/** Get BT peripheral socket status + * + * @param[in] socket : pointer to the socket to get the status + * @param[out] status : socket status + * + * @return MICO_BT_SUCCESS: success + * MICO_BT_SMART_APPL_UNINITIALISED: Smart peripheral framework is uninitialized + */ +OSStatus mico_bt_peripheral_get_socket_status( mico_bt_peripheral_socket_t *socket, + mico_bt_peripheral_socket_status_t *status ); + +/** Disconnect BT peripheral connection + * + * @note + * This function disconnects a connection with remote client. + * + * @return MICO_BT_SUCCESS: success + * MICO_BT_SMART_APPL_UNINITIALISED: Smart peripheral framework is uninitialized + */ +OSStatus mico_bt_peripheral_disconnect( void ); + + +/** @} */ + +/*****************************************************************************/ +/** @addtogroup sbscan Smart Peripheral Advert + * @ingroup SmartPeripheral + * + * Smart Peripheral Advertising Functions + * + * + * @{ + */ +/*****************************************************************************/ + +/** Start advertising local Bluetooth Smart devices + * + * @note + * This function instructs the Bluetooth controller to start advertising. Advertising data + * sould be set first use mico_bt_ble_set_advertisement_data(). + * + * @warning + * \li complete_callback is an intermediate report callback. + * + * @param[in] settings : advertising settings + * @param[in] complete_callback : callback function which is called when advertising is + * complete,running under MICO_BT_EVT_WORKER_THREAD + * + * @return MICO_BG_SUCCESS, else @ref OSStatus + */ +OSStatus mico_bt_peripheral_start_advertisements( mico_bt_smart_advertising_settings_t *settings, + mico_bt_smart_advertising_complete_callback_t complete_callback); + +/** Stop the ongoing advertising process + * + * This function instructs the Bluetooth controller to advertising local + * Bluetooth Smart devices. + * + * @return MICO_BG_SUCCESS, else @ref OSStatus + */ +OSStatus mico_bt_peripheral_stop_advertisements( void ); + +/** @} */ + +/*****************************************************************************/ +/** @addtogroup sbwhitelist SmartBridge Whitelist Filter + * @ingroup smartbridge + * + * SmartBridge Whitelist Filter Functions + * + * + * @{ + */ +/*****************************************************************************/ + +/** Update the devices in white list. + * + * @param[in] add : Add or remove this device specified by device_address. + * @param[in] device_address : Bluetooth address of the device to add to the whitelist + * + * @return @ref OSStatus + */ +OSStatus mico_bt_peripheral_update_advertisements_white_list( mico_bool_t add, + mico_bt_device_address_t device_address ); + +/** Get the number of devices in white list + * + * @param[out] size : The number of devices in white list. + * + * @return @ref OSStatus + */ +OSStatus mico_bt_peripheral_get_advertisements_white_list_size( uint8_t *size ); + +/** Set Advertisements Filter Policy + * + * @param[in] policy : Advertisements filter policy + * + * @return @ref OSStatus + */ +OSStatus mico_bt_peripheral_set_advertisements_filter_policy( mico_bt_peripheral_adv_filter_policy_t policy ); + +/** @} */ + +/*****************************************************************************/ +/** @addtogroup sbattr Smart peripheral Attribute Value database + * @ingroup SmartPeripheral + * + * Smart Peripheral External Attribute Value Database Functions + * + * + * @{ + */ +/*****************************************************************************/ + +/** Add an external attribute vale to BT peripheral + * + * @param handle[in] : Handle of an attribution + * @param length[in] : Attribute value length (0, if value is not existed) + * @param value[in] : Point to the Attribute value (NULL, if value is not existed) + * @param handler[in] : Attribute request handler is synchronized triggerd + * after an attribute write by remote GATT write operation + * or before anattribute read by remote GATT read operation + * + * @return The address of the external attrbute value object, NULL if failed + */ +mico_bt_ext_attribute_value_t *mico_bt_peripheral_ext_attribute_add( uint16_t handle, uint16_t length, + const uint8_t *value, mico_bt_peripheral_attribute_handler handler ); + + +/** Remove an external attribute vale from BT peripheral + * + * @param attribute[in] : The address of the external attrbute value object + * + * @return @ref OSStatus + */ +OSStatus mico_bt_peripheral_ext_attribute_remove( mico_bt_ext_attribute_value_t *attribute ); + +/** Find an external attribute value from BT peripheral using handle + * + * @param handle[in] : Handle of an attribute + * @param attribute_found[in,out] : Pointer to the external attribute address find by handle + * + * @return @ref OSStatus + */ +OSStatus mico_bt_peripheral_ext_attribute_find_by_handle( uint16_t handle, + mico_bt_ext_attribute_value_t **attribute_found ); + + +/** Write or update data to the external attribute value object + * + * @note + * The value will copy to attrubute object, free after write + * + * @param handle[in] : Handle of an attribute + * @param length[in] : Data length + * @param length[in] : Attrubute value offset where data is written to + * @param value[in] : Point to the data + * + * @return @ref OSStatus + */ +OSStatus mico_bt_peripheral_ext_attribute_value_write( mico_bt_ext_attribute_value_t *attribute, uint16_t length, + uint16_t value_offset, const uint8_t *value ); + + +/** Remove all external attribute vale from BT peripheral + * + * @return @ref OSStatus + */ +OSStatus mico_bt_peripheral_ext_attribute_remove_all( void ); + + +/** Send external attribute value to BT client using indicate + * + * + * @param socket[in] : Pointer to the socket to send attribute value + * @param attribute[in] : Pointer to the external attribute that hold the value to be sent + * + * @return @ref OSStatus + */ +OSStatus mico_bt_peripheral_gatt_indicate_attribute_value ( mico_bt_peripheral_socket_t *socket, + const mico_bt_ext_attribute_value_t *attribute ); + + +/** Send external attribute value to BT client using notify + * + * + * @param socket[in] : Pointer to the socket to send attribute value + * @param attribute[in] : Pointer to the external attribute that hold the value to be sent + * + * @return @ref OSStatus + */ +OSStatus mico_bt_peripheral_gatt_notify_attribute_value( mico_bt_peripheral_socket_t *socket, + const mico_bt_ext_attribute_value_t *attribute ); + + +/** @} */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + diff --git a/device/bluetooth/mk3239/bt_smart/include/mico_bt_smart_attribute.h b/device/bluetooth/mk3239/bt_smart/include/mico_bt_smart_attribute.h new file mode 100644 index 0000000000..7c6be6195e --- /dev/null +++ b/device/bluetooth/mk3239/bt_smart/include/mico_bt_smart_attribute.h @@ -0,0 +1,416 @@ +/** @file + * Defines structures and functions for Bluetooth Smart Attribute abstraction + */ + +#pragma once + +#include "mico.h" +#include "mico_bt_smartbridge_constants.h" +#include "mico_bt_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************** + * Macros + ******************************************************/ + +/****************************************************** + * Constants + ******************************************************/ + +/** @cond !ADDTHIS*/ +/* Attribute structure fixed length */ +#define ATTR_COMMON_FIELDS_SIZE ( sizeof(mico_bt_smart_attribute_t*) + sizeof(uint16_t) + sizeof(mico_bt_uuid_t) + sizeof(uint8_t) + sizeof(uint32_t) + + sizeof(uint32_t)) + +#define ATTR_NO_VALUE_SIZE ( ATTR_COMMON_FIELDS_SIZE + sizeof(uint8_t) ) +#define ATTR_LONG_VALUE_SIZE ( ATTR_COMMON_FIELDS_SIZE + sizeof(uint8_t) * MAX_CHARACTERISTIC_VALUE_LENGTH ) +#define ATTR_SERVICE_SIZE ( ATTR_COMMON_FIELDS_SIZE + sizeof(attr_val_service_t) ) +#define ATTR_INCLUDE_SIZE ( ATTR_COMMON_FIELDS_SIZE + sizeof(attr_val_include_t) ) +#define ATTR_CHARACTERISTIC_SIZE ( ATTR_COMMON_FIELDS_SIZE + sizeof(attr_val_characteristic_t) ) +#define ATTR_CHARACTERISTIC_VALUE_SIZE( value_length ) ( ATTR_COMMON_FIELDS_SIZE + (sizeof(uint8_t) * value_length) ) +#define ATTR_EXTENDED_PROPERTIES_SIZE ( ATTR_COMMON_FIELDS_SIZE + sizeof(attr_val_extended_properties_t) ) +#define ATTR_USER_DESCRIPTION_SIZE( string_length ) ( ATTR_COMMON_FIELDS_SIZE + (sizeof(char) * string_length) ) +#define ATTR_CLIENT_CONFIG_SIZE ( ATTR_COMMON_FIELDS_SIZE + sizeof(attr_val_client_config_t) ) +#define ATTR_SERVER_CONFIG_SIZE ( ATTR_COMMON_FIELDS_SIZE + sizeof(attr_val_server_config_t) ) +#define ATTR_PRESENTATION_FORMAT_SIZE ( ATTR_COMMON_FIELDS_SIZE + sizeof(attr_val_presentation_format_t) ) +#define ATTR_AGGREGATE_FORMAT_SIZE( handle_count ) ( ATTR_COMMON_FIELDS_SIZE + (sizeof(uint16_t) * handle_count) ) + +/* Maximum characteristic value length */ +#define MAX_CHARACTERISTIC_VALUE_LENGTH 512 +/** @endcond */ + +/****************************************************** + * Enumerations + ******************************************************/ + +/** + * Bluetooth Smart Attribute type + */ +typedef enum { + MICO_ATTRIBUTE_TYPE_NO_VALUE, /**< Attribute with no value */ + MICO_ATTRIBUTE_TYPE_LONG_VALUE, /**< Attribute with long value */ + MICO_ATTRIBUTE_TYPE_PRIMARY_SERVICE, /**< Primary service */ + MICO_ATTRIBUTE_TYPE_INCLUDE, /**< Included Service */ + MICO_ATTRIBUTE_TYPE_CHARACTERISTIC, /**< Characteristic */ + MICO_ATTRIBUTE_TYPE_CHARACTERISTIC_VALUE, /**< Characteristic Value */ + MICO_ATTRIBUTE_TYPE_CHARACTERISTIC_DESCRIPTOR_EXTENDED_PROPERTIES, /**< Characteristic Descriptor: Extended Properties */ + MICO_ATTRIBUTE_TYPE_CHARACTERISTIC_DESCRIPTOR_USER_DESCRIPTION, /**< Characteristic Descriptor: User Description */ + MICO_ATTRIBUTE_TYPE_CHARACTERISTIC_DESCRIPTOR_CLIENT_CONFIGURATION, /**< Characteristic Descriptor: Client Configuration */ + MICO_ATTRIBUTE_TYPE_CHARACTERISTIC_DESCRIPTOR_SERVER_CONFIGURATION, /**< Characteristic Descriptor: Server Configuration */ + MICO_ATTRIBUTE_TYPE_CHARACTERISTIC_DESCRIPTOR_PRESENTATION_FORMAT, /**< Characteristic Descriptor: Presentation Format */ + MICO_ATTRIBUTE_TYPE_CHARACTERISTIC_DESCRIPTOR_AGGREGATE_FORMAT /**< Characteristic Descriptor: Aggregate Format */ +} mico_bt_smart_attribute_type_t; + +/****************************************************** + * Type Definitions + ******************************************************/ + +/****************************************************** + * Structures + ******************************************************/ + +#pragma pack(1) +/* @note: The following Attribute Values follow the Bluetooth Core Spec v4.0 + * Volume 3 Part G Section 3 closely. This allows for direct memcpy from + * the ATT response PDU to the Attribute Value structure. Also note that + * any additional fields follow the fields in the specification. + */ + +/** + * 3.1 Attribute Value of Service Definition + */ +typedef struct { + uint16_t start_handle; /**< Starting handle */ + uint16_t end_handle; /**< Ending handle */ + mico_bt_uuid_t uuid; /**< UUID */ +} attr_val_service_t; + +/** + * 3.2 Attribute Value of Include Definition + */ +typedef struct { + uint16_t included_service_handle; /**< Included service handle */ + uint16_t end_group_handle; /**< End group handle */ + mico_bt_uuid_t uuid; /**< UUID */ +} attr_val_include_t; + +/** + * 3.3.1 Attribute Value of Characteristic Declaration + */ +typedef struct { + uint8_t properties; /**< Properties */ + uint16_t value_handle; /**< Value handle */ + mico_bt_uuid_t uuid; /**< UUID */ + + uint16_t descriptor_start_handle; /**< Descriptor start handle. Additional field. Not in spec */ + uint16_t descriptor_end_handle; /**< Descriptor end handle. Additional field. Not in spec */ +} attr_val_characteristic_t; + +/** + * 3.3.2 Attribute Value of Characteristic Value Declaration + */ +typedef struct { + uint8_t value[1]; /**< Start of value */ +} attr_val_characteristic_value_t; + +/** + * 3.3.3.1 Attribute Value of Characteristic Extended Properties + */ +typedef struct { + uint8_t properties; /**< Properties */ +} attr_val_extended_properties_t; + +/** + * 3.3.3.2 Attribute Value of Characteristic User Description + */ +typedef struct { + char string[1]; /**< User description string */ +} attr_val_user_description_t; + +/** + * 3.3.3.3 Attribute Value of Client Characteristic Configuration + */ +typedef struct { + uint16_t config_bits; /**< Configuration bits */ +} attr_val_client_config_t; + +/** + * 3.3.3.4 Attribute Value of Server Characteristic Configuration + */ +typedef struct { + uint16_t config_bits; /**< Configuration bits */ +} attr_val_server_config_t; + +/** + * 3.3.3.5 Attribute Value of Characteristic Presentation Format + */ +typedef struct { + uint8_t format; /**< Format */ + uint8_t exponent; /**< Exponent */ + uint16_t unit; /**< Unit */ + uint8_t name_space; /**< Namespace */ + uint16_t description; /**< Description */ +} attr_val_presentation_format_t; + +/** + * 3.3.3.6 Attribute Value of Characteristic Aggregate Format + */ +typedef struct { + uint16_t handle_list[1]; /**< Handle list */ +} attr_val_aggregate_format_t; + +/** + * Vol 3 Part C 12.1 Attribute Value of Device Name Characteristic + */ +typedef struct { + char device_name[1]; /**< Maximum length is 248 bytes */ +} attr_val_device_name_t; + +/** + * Vol 3 Part C 12.2 Attribute Value of Appearance Characteristic + */ +typedef struct { + uint16_t appearance; /**< Enumerated value defined in "Assigned Numbers" */ +} attr_val_appearance_t; + +/** + * Vol 3 Part C 12.3 Attribute Value of Peripheral Privacy Flag Characteristic + */ +typedef struct { + uint8_t periph_privacy_flag; /**< Peripheral privacy flag: 0 if disabled; 1 if enabled */ +} attr_val_periph_privacy_flag_t; + +/** + * Vol 3 Part C 12.4 Attribute Value of Reconnection Address Characteristic + */ +typedef struct { + uint8_t reconn_address[6]; /**< Network-order reconnection address */ +} attr_val_reconnection_address_t; + +/** + * Vol 3 Part C 12.5 Attribute Value of Peripheral Preferred Connection Parameters Characteristic + */ +typedef struct { + uint16_t min_conn_interval; /**< Minimum connection interval */ + uint16_t max_conn_interval; /**< Maximum connection interval */ + uint16_t slave_latency; /**< Slave latency */ + uint16_t conn_supervision_timeout_multiplier; /**< Connection supervision timeout multiplier */ +} attr_val_periph_preferred_conn_params_t; + +/** + * Attribute Structure + */ +typedef struct mico_bt_attribute { + struct mico_bt_attribute + *next; /**< Pointer to the next attribute in the list. NULL if not a list */ + uint16_t + handle; /**< Attribute Handle */ + mico_bt_uuid_t + type; /**< Attribute Type (UUID) */ + uint8_t + permission; /**< Attribute Permission(s). Unused in GATT client */ + uint32_t + value_length; /**< Length of the Attribute Value. If no value, this equals 0 */ + uint32_t + value_struct_size; /**< Size of the value structure */ + + /* Union of Attribute Values. Use the right format based on Attribute Type */ + union { + uint8_t + value[MAX_CHARACTERISTIC_VALUE_LENGTH]; /**< Long Value */ + attr_val_service_t + service; /**< Attribute Value for Service */ + attr_val_include_t + include; /**< Attribute Value for Include */ + attr_val_characteristic_t + characteristic; /**< Attribute Value for Characteristic */ + attr_val_characteristic_value_t + characteristic_value; /**< Attribute Value for Characteristic Value */ + attr_val_extended_properties_t + extended_properties; /**< Attribute Value for Descriptor: Characteristic Extended Properties */ + attr_val_user_description_t + user_description; /**< Attribute Value for Descriptor: Characteristic User_Description */ + attr_val_client_config_t + client_config; /**< Attribute Value for Descriptor: Client Characteristic Configuration */ + attr_val_server_config_t + server_config; /**< Attribute Value for Descriptor: Server Characteristic Configuration */ + attr_val_presentation_format_t + presentation_format; /**< Attribute Value for Descriptor: Characteristic Presentation Format */ + attr_val_aggregate_format_t + aggregate_format; /**< Attribute Value for Descriptor: Characteristic Aggregate Format */ + attr_val_device_name_t + device_name; /**< Attribute Value for Characteristic Type: Device Name */ + attr_val_appearance_t + appearance; /**< Attribute Value for Characteristic Type: Appearance */ + attr_val_periph_privacy_flag_t + periph_privacy_flag; /**< Attribute Value for Characteristic Type: Peripheral Privacy Flag */ + attr_val_reconnection_address_t + reconn_address; /**< Attribute Value for Characteristic Type: Reconnection Address */ + attr_val_periph_preferred_conn_params_t + periph_preferred_conn_params; /**< Attribute Value for Characteristic Type: Peripheral Preferred Connection Parameters */ + } value; /**< Union of Attribute Values. Use the right format based on Attribute Type */ + +} mico_bt_smart_attribute_t; + +/** + * Attribute List Structure + */ +typedef struct { + uint32_t count; /**< Attribute count */ + mico_bt_smart_attribute_t *list; /**< Pointer to attribute linked-list */ +} mico_bt_smart_attribute_list_t; + +#pragma pack() + +/****************************************************** + * Global Variables + ******************************************************/ + +/****************************************************** + * Function Declarations + ******************************************************/ + +/*****************************************************************************/ +/** @addtogroup btattr Attribute + * @ingroup micobt + * + * Bluetooth Smart Attribute Abstraction + * + * + * @{ + */ +/*****************************************************************************/ + +/** Create a Bluetooth Smart Attribute structure + * + * @param[out] attribute : pointer that will receive the attribute structure + * @param[in] type : attribute type + * @param[in] variable_length : length of the variable part of the attribute. + * For some attribute types, this argument is not + * used. + * + * @return MICO_BT_SUCCESS:success,MICO_BT_BADARG:input argument error + */ +OSStatus mico_bt_smart_attribute_create( mico_bt_smart_attribute_t **attribute, mico_bt_smart_attribute_type_t type, + uint16_t variable_length ); + +/** Delete a Bluetooth Smart Attribute structure + * + * @param[in,out] attribute : attribute structure to delete + * + * @return MICO_BT_SUCCESS:success,MICO_BT_BADARG:input argument error + */ +OSStatus mico_bt_smart_attribute_delete( mico_bt_smart_attribute_t *attribute ); + +/** Initialise a list of Bluetooth Smart Attributes + * + * @param[out] list : list to initialise + * + * @return MICO_BT_SUCCESS:success,MICO_BT_BADARG:input argument error + */ +OSStatus mico_bt_smart_attribute_create_list( mico_bt_smart_attribute_list_t *list ); + +/** Deinitialise a list of Bluetooth Smart Attributes + * + * @param[out] list : list to deinitialise + * + * @return @ref OSStatus + */ +OSStatus mico_bt_smart_attribute_delete_list( mico_bt_smart_attribute_list_t *list ); + +/** Add a Bluetooth Smart Attribute to a list + * + * @param[in,out] list : list to add attribute to + * @param[in] attribute : attribute to add to the list + * + * @return @ref OSStatus + */ +OSStatus mico_bt_smart_attribute_add_to_list( mico_bt_smart_attribute_list_t *list, + mico_bt_smart_attribute_t *attribute ); + +/** Remove a Bluetooth Smart Attribute with the given handle from a list + * + * @param[in,out] list : list to remote attribute from + * @param[in] handle : handle of the attribute to remove + * + * @return @ref OSStatus + */ +OSStatus mico_bt_smart_attribute_remove_from_list( mico_bt_smart_attribute_list_t *list, uint16_t handle ); + +/** Find a Bluetooth Smart Attribute with the given handle from a list + * + * @param[in,out] list : list to find attribute in + * @param[in] handle : handle of the attribute to find + * @param[out] attribute : pointer that will receive the attribute + * + * @return @ref OSStatus + */ +OSStatus mico_bt_smart_attribute_search_list_by_handle( const mico_bt_smart_attribute_list_t *list, uint16_t handle, + mico_bt_smart_attribute_t **attribute ); + +/** Find a Bluetooth Smart Attribute with the given handle from a list + * + * @param[in,out] list : list to find attribute in + * @param[in] uuid : UUID of the attribute to find + * @param[in] starting_handle : handle to start the search + * @param[in] ending_handle : handle to end the search + * @param[out] attribute : pointer that will receive the attribute + * + * @return @ref OSStatus + */ +OSStatus mico_bt_smart_attribute_search_list_by_uuid( const mico_bt_smart_attribute_list_t *list, + const mico_bt_uuid_t *uuid, uint16_t starting_handle, uint16_t ending_handle, mico_bt_smart_attribute_t **attribute ); + +/** Merge two Bluetooth Smart Attribute lists + * + * @param[in,out] trunk_list : list that will receive all of the attributes from the branch list + * @param[in,out] branch_list : list whose attributes will be removed and inserted into the trunk list + * + * @return @ref OSStatus + */ +OSStatus mico_bt_smart_attribute_merge_lists( mico_bt_smart_attribute_list_t *trunk_list, + mico_bt_smart_attribute_list_t *branch_list ); + +/** Print attribute contents + * + * @param[in] attribute : attribute to print + * + * @return @ref OSStatus + */ +OSStatus mico_bt_smart_attribute_print( const mico_bt_smart_attribute_t *attribute ); + +/** Print the contents of all attributes in a list + * + * @param[in] list : list whose attributes to print + * + * @return @ref OSStatus + */ +OSStatus mico_bt_smart_attribute_print_list( const mico_bt_smart_attribute_list_t *list ); + +/** Get attribute list head + * + * @param[in] list : attribute list + * @param[out] head : pointer that will receive the list head + * + * @return @ref OSStatus + */ +OSStatus mico_bt_smart_attribute_get_list_head( const mico_bt_smart_attribute_list_t *list, + mico_bt_smart_attribute_t **head ); + + +/** Get attribute list count + * + * @param[in] list : attribute list + * @param[out] count : variable that will receive the count + * + * @return @ref OSStatus + */ +OSStatus mico_bt_smart_attribute_get_list_count( const mico_bt_smart_attribute_list_t *list, uint32_t *count ); + +/** @} */ + +#ifdef __cplusplus +} /* extern "C" */ +#endif diff --git a/device/bluetooth/mk3239/bt_smart/include/mico_bt_smart_interface.h b/device/bluetooth/mk3239/bt_smart/include/mico_bt_smart_interface.h new file mode 100644 index 0000000000..64d425badd --- /dev/null +++ b/device/bluetooth/mk3239/bt_smart/include/mico_bt_smart_interface.h @@ -0,0 +1,427 @@ + +/** @file + * Defines common constants and types for MiCO support for Bluetooth Smart + */ + +#pragma once + +#include "mico_bt_smartbridge_constants.h" +#include "mico_bt_smart_attribute.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************** + * Macros + ******************************************************/ + +/****************************************************** + * Constants + ******************************************************/ + +/** @cond !ADDTHIS*/ +/* Limits and Default Value for Scan Interval */ +#define DEFAULT_SCAN_INTERVAL 0x0010 +#define MIN_SCAN_INTERVAL 0x0004 +#define MAX_SCAN_INTERVAL 0x4000 + +/* Limits and Default Value for Scan Window */ +#define DEFAULT_SCAN_WINDOW 0x0010 +#define MIN_SCAN_WINDOW 0x0004 +#define MAX_SCAN_WINDOW 0x4000 + +#define BONDING_DISABLED 0x00 +#define BONDING_ENABLED 0x01 +#define PASSKEY_ENTRY_ENABLED 0x04 +#define SECURE_CONNECTION_ENABLE 0x08 + +#define DISTRIBUTE_ENCRYPTION_KEY 0x01 +#define DISTRIBUTE_ID_KEY 0x02 +#define DISTRIBUTE_SIGN_KEY 0x04 +/** @endcond */ + +/****************************************************** + * Enumerations + ******************************************************/ + +/** + * Bluetooth Smart filter policy + */ +typedef enum { + FILTER_POLICY_NONE = 0x00, /**< No filter policy */ + FILTER_POLICY_WHITE_LIST = 0x01, /**< White list filter policy */ +} mico_bt_smart_filter_policy_t; + +/** + * Bluetooth Smart scan duplicates filter + */ +typedef enum { + DUPLICATES_FILTER_DISABLED = 0x00, /**< Duplicates filter is disabled */ + DUPLICATES_FILTER_ENABLED = 0x01, /**< Duplicates filter is enabled */ +} mico_bt_smart_filter_duplicated_t; + +/** + * Bluetooth Smart address type + */ +typedef enum { + BT_SMART_ADDR_TYPE_PUBLIC = 0x00, /**< Public address */ + BT_SMART_ADDR_TYPE_RANDOM = 0x01 /**< Random address */ +} mico_bt_smart_address_type_t; + +/** + * Bluetooth Smart link role + */ +typedef enum { + BT_SMART_LINK_ROLE_MASTER = 0x00, /**< Public address */ + BT_SMART_LINK_ROLE_SLAVE = 0x01 /**< Random address */ +} mico_bt_smart_link_role_t; + +/** + * Bluetooth Smart scan type + */ +typedef enum { + BT_SMART_PASSIVE_SCAN = 0x00, /**< Passive scan. Controller does not send SCAN_REQ and listens for Advertising from remote devices */ + BT_SMART_ACTIVE_SCAN = 0x01, /**< Active scan. Controller sends SCAN_REQ. Controller listens for Advertising from remote devices and may receive SCAN_RSP from remote devices */ +} mico_bt_smart_scan_type_t; + +/** + * Bluetooth Smart advertising event + */ +typedef enum { + BT_SMART_CONNECTABLE_UNDIRECTED_ADVERTISING_EVENT = 0x00, /**< ADV_IND : Connectable undirected advertising event */ + BT_SMART_CONNECTABLE_DIRECTED_ADVERTISING_EVENT = 0x01, /**< ADV_DIRECT_IND : Connectable directed advertising event */ + BT_SMART_SCANNABLE_UNDIRECTED_ADVERTISING_EVENT = 0x02, /**< ADV_SCAN_IND : Scannable undirected advertising event */ + BT_SMART_NON_CONNECTABLE_UNDIRECTED_ADVERTISING_EVENT = 0x03, /**< ADV_NONCONN_IND : Non-connectable undirected advertising event */ + BT_SMART_SCAN_RESPONSE_EVENT = 0x04, /**< SCAN_RSP : Scan response event */ +} mico_bt_smart_advertising_event_t; + +/** + * Bluetooth Smart advertising event + */ +typedef enum { + BT_SMART_UNDIRECTED_ADVERTISING = 0x00, /**< General undirected advertising */ + BT_SMART_DISCOVERABLE_ADVERTISING = 0x01, /**< Discoverable advertising */ + BT_SMART_DIRECTED_ADVERTISING = 0x02, /**< Directed advertising */ + BT_SMART_NON_CONNECTABLE_UNDIRECTED_ADVERTISING = 0x03, /**< Non-connectable undirected advertising */ +} mico_bt_smart_advertising_type_t; + +/** + * Bluetooth Smart device input/output (IO) capabilities + */ +typedef enum { + BT_SMART_IO_DISPLAY_ONLY = 0x00, + BT_SMART_IO_DISPLAY_YES_NO_BUTTONS = 0x01, + BT_SMART_IO_KEYBOARD_ONLY = 0x02, + BT_SMART_IO_NO_INPUT_NO_OUTPUT = 0x03, + BT_SMART_IO_KEYBOARD_DISPLAY = 0x04, +} mico_bt_io_capabilities_t; + +/** + * Bluetooth Smart device Authentication Requirements (AuthReq) + */ +typedef enum { + BT_SMART_AUTH_REQ_NONE = 0, + BT_SMART_AUTH_REQ_BONDING = ( BONDING_ENABLED ), + BT_SMART_AUTH_REQ_PASSKEY_ENTRY = ( PASSKEY_ENTRY_ENABLED ), + BT_SMART_AUTH_REQ_BONDING_AND_PASSKEY_ENTRY = ( BONDING_ENABLED | PASSKEY_ENTRY_ENABLED ), +} mico_bt_smart_auth_req_t; + +/** + * Bluetooth Smart device bonding request type + */ +typedef enum { + /* Bonding event -- user should reply it with #mico_bt_smart_bond_reply() */ + MICO_BT_SMART_BOND_PASS_KEY_REQ = 0x01, + /* Bonding event -- user should reply it with #mico_bt_smart_bond_reply() */ + MICO_BT_SMART_BOND_USR_CONFIRM_REQ = 0x02, + /* Bonding event -- user should reply it with #mico_bt_smart_bond_reply() */ + MICO_BT_SMART_BOND_OOB_DATA_REQ = 0x03, + /* Bonding event -- user should not reply it */ + MICO_BT_SMART_BOND_PASS_KEY_NOTIFY = 0x04, +} mico_bt_smart_bond_request_type_t; + +/** + * Bluetooth Smart device key distribution types + */ +typedef enum { + BT_SMART_DISTRIBUTE_NONE = 0, + BT_SMART_DISTRIBUTE_ENCRYPTION_KEY = ( DISTRIBUTE_ENCRYPTION_KEY ), + BT_SMART_DISTRIBUTE_ID_KEY = ( DISTRIBUTE_ID_KEY ), + BT_SMART_DISTRIBUTE_ENCRYPTION_AND_ID_KEYS = ( DISTRIBUTE_ID_KEY | DISTRIBUTE_ENCRYPTION_KEY ), + BT_SMART_DISTRIBUTE_SIGN_KEY = ( DISTRIBUTE_SIGN_KEY ), + BT_SMART_DISTRIBUTE_ENCRYPTION_AND_SIGN_KEYS = ( DISTRIBUTE_SIGN_KEY | DISTRIBUTE_ENCRYPTION_KEY ), + BT_SMART_DISTRIBUTE_ID_AND_SIGN_KEYS = ( DISTRIBUTE_SIGN_KEY | DISTRIBUTE_ID_KEY ), + BT_SMART_DISTRIBUTE_ALL_KEYS = ( DISTRIBUTE_SIGN_KEY | DISTRIBUTE_ID_KEY | DISTRIBUTE_ENCRYPTION_KEY ), +} mico_bt_smart_key_distribution_t; + +/** + * Bluetooth Smart Out-of-Band (OOB) authentication data + */ +typedef enum { + BT_SMART_OOB_AUTH_NONE, /**< OOB authentication data is not available */ + BT_SMART_OOB_AUTH_AVAILABLE, /**< OOB authentication data is available */ +} mico_bt_smart_oob_auth_t; + +/****************************************************** + * Structures + ******************************************************/ + +#pragma pack(1) + +/** + * Bluetooth Smart device + */ +typedef struct { + mico_bt_device_address_t address; /**< Bluetooth device address */ + mico_bt_smart_address_type_t address_type; /**< Address Type */ + char name[31]; /**< User-friendly name */ +} mico_bt_smart_device_t; + +/** + * Bluetooth Smart scan settings + */ +typedef struct { + mico_bt_smart_scan_type_t + type; /**< Scan type */ + mico_bt_smart_filter_policy_t + filter_policy; /**< Scan filter policy */ + mico_bt_smart_filter_duplicated_t + filter_duplicates; /**< Scan duplicates filter */ + uint16_t + interval; /**< Interval between scans. Unit: 0.625ms. Range: 0x0004 - 0x4000 (2.5ms - 10.24s) */ + uint16_t + window; /**< Scan window. Must be <= scan interval. Unit: 0.625ms. Range: 0x0004 - 0x4000 (2.5ms - 10.24s) */ + uint16_t + duration_second; /**< Scan duration in seconds */ +} mico_bt_smart_scan_settings_t; + +/** + * Bluetooth Smart advertising report + */ +typedef struct { + mico_bt_smart_device_t remote_device; /**< Remote device */ + int8_t signal_strength; /**< RSSI in dBm */ + mico_bt_smart_advertising_event_t event; /**< Advertising event received */ + uint8_t eir_data_length; /**< Length of EIR data received with advertising event */ + uint8_t eir_data[31]; /**< EIR data of advertising event */ +} mico_bt_smart_advertising_report_t; + +/** + * Bluetooth Smart scan result + */ +typedef struct mico_bt_smart_scan_result { + mico_bt_smart_device_t remote_device; /**< Remote device */ + int8_t signal_strength; /**< RSSI in dBm */ + mico_bt_smart_advertising_report_t last_scan_response_received; /**< Last scan response event received */ + mico_bt_smart_advertising_report_t last_advertising_event_received; /**< Last advertising event received */ + struct mico_bt_smart_scan_result *next; /**< Pointer to the next scan result */ + + /* Additional flag to help application filter scan results */ + mico_bool_t filter_display; /**< Set to MICO_TRUE if filter display */ + +} mico_bt_smart_scan_result_t; + +/** + * Bluetooth Smart advertise settings + */ +typedef struct { + mico_bt_smart_advertising_type_t + type; /**< Advertising type */ + mico_bool_t + use_high_duty; /**< Start advertising use high duty cycle interval */ + uint16_t + high_duty_interval; /**< High duty advertising interval */ + uint16_t + high_duty_duration; /**< High duty advertising duration in seconds (0 for infinite) */ + uint16_t + low_duty_interval; /**< Low duty advertising interval */ + uint16_t + low_duty_duration; /**< Low duty advertising duration in seconds (0 for infinite) */ + mico_bt_smart_address_type_t + directed_advertisement_addr_type; /**< Target device address type for directed advertising */ + mico_bt_device_address_t + directed_advertisement_addr; /**< Target device address for directed advertising */ +} mico_bt_smart_advertising_settings_t; + +/** + * Bluetooth Smart connection settings + */ +typedef struct { + uint16_t + timeout_second; /**< Connection timeout in seconds */ + mico_bt_smart_filter_policy_t + filter_policy; /**< Connection initiator filter policy: No filter or using white list */ + uint16_t + interval_min; /**< Connection Interval Min. Unit: 1.25ms. Range: 0x000A - 0x0C80 (7.5ms - 4s) */ + uint16_t + interval_max; /**< Connection Interval Max. Unit: 1.25ms. Range: 0x000A - 0x0C80 (7.5ms - 4s) */ + uint16_t + latency; /**< Connection Latency. Unit: Connection Events. Range: 0x0000 - 0x01F4 */ + uint16_t + supervision_timeout; /**< Supervision Timeout. Unit: 10ms. Range: 0x000A - 0x0C80 (100ms - 32s)*/ + uint16_t + ce_length_min; /**< Connection Event Length Min. Unit: Connection Events. Range: 0x0000 - 0xFFFF */ + uint16_t + ce_length_max; /**< Connection Event Length Max. Unit: Connection Events. Range: 0x0000 - 0xFFFF */ + uint32_t + attribute_protocol_timeout_ms; /**< Attribute protocol timeout in milliseconds */ +} mico_bt_smart_connection_settings_t; + +/** + * Bluetooth Smart Extended Inquiry Response (EIR) data structure + */ +typedef struct { + uint8_t length; /**< Length */ + uint8_t type; /**< Type */ + uint8_t data[1]; /**< Start of data */ +} mico_bt_smart_eir_data_structure_t; + +/** + * Bluetooth Smart security settings + */ +typedef struct { + uint16_t timeout_second; /**< Timeout in second. Default is 30 seconds */ + mico_bt_io_capabilities_t io_capabilities; /**< Device I/O capability */ + mico_bt_smart_auth_req_t authentication_requirements; /**< Authentication requirements */ + mico_bt_smart_oob_auth_t oob_authentication; /**< OOB authentication data */ + uint8_t max_encryption_key_size; /**< Encryption key size (7 to 16 bytes) */ + mico_bt_smart_key_distribution_t master_key_distribution; /**< Bit mask of master/initiator key distribution */ + mico_bt_smart_key_distribution_t slave_key_distribution; /**< Bit mask of slave/responder key distribution */ +} mico_bt_smart_security_settings_t; + +/** + * Bluetooth Smart Peer Device Bond Info + */ +typedef struct { + mico_bt_device_address_t + peer_address; /**< Bonded peer device address */ + mico_bt_smart_address_type_t + address_type; /**< Peer device's address type */ + uint8_t + irk [16]; /**< Peer device's Identity Resolving Key (IRK). Used for random address generation and resolution */ + uint8_t + csrk[16]; /**< Peer device's Connection Signature Resolving Key (CSRK). Used for signing data and verifying messages */ + uint8_t + ltk [16]; /**< Peer device's Long Term Key (LTK). Used for encryption */ + uint8_t + rand[8]; /**< Peer device's Random Number (Rand). Used for identifying LTK */ + uint16_t + ediv; /**< Peer device's Encrypted Diversifier (EDIV). Used for identifying LTK */ +} mico_bt_smart_bond_info_t; + +/** + * Bluetooth Smart Device Bond Request Event Parameters. + */ +typedef struct { + /* Type of the request */ + mico_bt_smart_bond_request_type_t type; + + union { + /* MICO_BT_SMART_BOND_PASS_KEY_REQ */ + struct { + mico_bt_device_address_t addr; + } passkey; + + /* MICO_BT_SMART_BOND_USR_CONFIRM_REQ */ + struct { + mico_bt_device_address_t addr; + /* An up to six-digit number (from 0 to 999999) to display or + * request remote entry + */ + uint32_t passkey; + } confirm; + + /* MICO_BT_SMART_BOND_OOB_DATA_REQ */ + struct { + mico_bt_device_address_t addr; + } oob_data; + + /* MICO_BT_SMART_BOND_PASS_KEY_NOTIFY */ + struct { + mico_bt_device_address_t addr; + uint32_t passkey; + } notify; + } u; +} mico_bt_smart_bond_request_t; + +/* + * Bluetooth Smart Device Bond Replay information. + */ +typedef struct { + /* Type of the request */ + mico_bt_smart_bond_request_type_t type; + + /* reply status */ + mico_bt_result_t res; + + /* reply data -- only valid when 'res' is MICO_BT_SUCCESS */ + union { + /* Used for MICO_BT_SMART_BOND_USER_CONFIRM */ + struct { + mico_bt_device_address_t addr; + } confirm; + + /* Used for MICO_BT_SMART_BOND_PASS_KEY_REQ */ + struct { + mico_bt_device_address_t addr; + uint32_t passkey; + } passkey; + + /* Used for MICO_BT_SMART_BOND_OOB_DATA_REQ */ + struct { + mico_bt_device_address_t addr; + uint8_t *data; + uint8_t len; + } oob_data; + } u; +} mico_bt_smart_bond_reply_t; + +#pragma pack() + +/****************************************************** + * Type Definitions + ******************************************************/ + +/** + * Bluetooth Smart scan complete callback + */ +typedef event_handler_t mico_bt_smart_scan_complete_callback_t; + +/** + * Bluetooth Smart advertising report callback + */ +typedef OSStatus (*mico_bt_smart_advertising_report_callback_t) ( const mico_bt_smart_advertising_report_t *result ); + +/** + * Bluetooth Smart Device Bond Callback. + */ +typedef OSStatus (*mico_bt_smart_bonding_callback_t)(const mico_bt_smart_bond_request_t *request); + +/** + * Bluetooth Smart advertising complete callback + */ +typedef event_handler_t mico_bt_smart_advertising_complete_callback_t; + +/****************************************************** + * Global Variables + ******************************************************/ + +/****************************************************** + * Function Declarations + ******************************************************/ + +/** mico_bt_smart_bond_reply + * + * This function is called to reply BLE Bond Event posted by #mico_bt_smart_bonding_callback_t. + * You should fill a strcutre #mico_bt_smart_bond_reply_t to complete this bonding procedure. + * + * @param[in] response the response to current bonding event. + * + * @return OSStatus + */ +extern OSStatus mico_bt_smart_bond_reply(const mico_bt_smart_bond_reply_t *response); + +#ifdef __cplusplus +} /* extern "C" */ +#endif diff --git a/framework/bluetooth/smartbt/include/smartbt_smartbridge.h b/device/bluetooth/mk3239/bt_smart/include/mico_bt_smartbridge.h similarity index 54% rename from framework/bluetooth/smartbt/include/smartbt_smartbridge.h rename to device/bluetooth/mk3239/bt_smart/include/mico_bt_smartbridge.h index d8ed15d653..05cad757db 100644 --- a/framework/bluetooth/smartbt/include/smartbt_smartbridge.h +++ b/device/bluetooth/mk3239/bt_smart/include/mico_bt_smartbridge.h @@ -1,15 +1,10 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ -#ifndef _SMART_BT_SMART_BRIDGE_H_ -#define _SMART_BT_SMART_BRIDGE_H_ +#pragma once -#include "../internal/os_wrapper.h" -#include "smartbt_smart_interface.h" +#include "mico_bt_smart_interface.h" #include "LinkListUtils.h" -/* @file +/** @file * Defines functions for bridging Bluetooth Smart with Wi-Fi */ @@ -17,139 +12,139 @@ extern "C" { #endif -/***************************************************** +/****************************************************** * Macros ******************************************************/ -/***************************************************** +/****************************************************** * Enumerations ******************************************************/ -/* +/** * SmartBridge socket status */ typedef enum { - SMARTBRIDGE_SOCKET_DISCONNECTED, /* Socket is disconnected */ - SMARTBRIDGE_SOCKET_CONNECTING, /* Socket is in connecting state */ - SMARTBRIDGE_SOCKET_CONNECTED, /* Socket is connected with a remote device */ -} aos_bt_smartbridge_socket_status_t; + SMARTBRIDGE_SOCKET_DISCONNECTED, /**< Socket is disconnected */ + SMARTBRIDGE_SOCKET_CONNECTING, /**< Socket is in connecting state */ + SMARTBRIDGE_SOCKET_CONNECTED, /**< Socket is connected with a remote device */ +} mico_bt_smartbridge_socket_status_t; -/***************************************************** +/****************************************************** * Type Definitions ******************************************************/ -/* +/** * Socket to create a SmartBridge connection */ -typedef struct aos_bt_smartbridge_socket aos_bt_smartbridge_socket_t; +typedef struct mico_bt_smartbridge_socket mico_bt_smartbridge_socket_t; -/* +/** * Auto connection callback parameters */ -typedef struct aos_bt_smartbridge_auto_conn_cback_parm aos_bt_smartbridge_auto_conn_cback_parms_t; +typedef struct mico_bt_smartbridge_auto_conn_cback_parm mico_bt_smartbridge_auto_conn_cback_parms_t; -/* +/** * Socket disconnection callback */ -typedef OSStatus (*aos_bt_smartbridge_disconnection_callback_t) ( aos_bt_smartbridge_socket_t *socket ); +typedef OSStatus (*mico_bt_smartbridge_disconnection_callback_t) ( mico_bt_smartbridge_socket_t *socket ); -/* +/** * Socket GATT notification callback */ -typedef OSStatus (*aos_bt_smartbridge_notification_callback_t) ( aos_bt_smartbridge_socket_t *socket, - uint16_t attribute_handle ); +typedef OSStatus (*mico_bt_smartbridge_notification_callback_t) ( mico_bt_smartbridge_socket_t *socket, + uint16_t attribute_handle ); -/* +/** * BLE Auto connection callback */ -typedef OSStatus (*aos_bt_smartbridge_auto_connection_callback_t) ( aos_bt_smartbridge_socket_t *socket ); +typedef OSStatus (*mico_bt_smartbridge_auto_connection_callback_t) ( mico_bt_smartbridge_socket_t *socket ); -/* +/** * BLE Auto connection parameters callback -- auto connection procedure callback */ -typedef OSStatus (*aos_bt_smartbridge_auto_connection_parms_cback_t) ( const aos_bt_device_address_t random_bda, - const char *name, const uint8_t *p_data, uint8_t len, aos_bt_smartbridge_auto_conn_cback_parms_t *parm ); +typedef OSStatus (*mico_bt_smartbridge_auto_connection_parms_cback_t) ( const mico_bt_device_address_t random_bda, + const char *name, const uint8_t *p_data, uint8_t len, mico_bt_smartbridge_auto_conn_cback_parms_t *parm ); -/***************************************************** +/****************************************************** * Structures ******************************************************/ -/* +/** * Socket to create a SmartBridge connection * @warning The content of the socket structure is for INTERNAL USE only. Modifying * the content of this structure is prohibited. Please use the Bluetooth SmartBridge * API to retrieve socket information. */ -struct aos_bt_smartbridge_socket { +struct mico_bt_smartbridge_socket { linked_list_node_t - node; /* Socket list node */ - aos_bt_smart_device_t - remote_device; /* Remote Bluetooth device AOS is connected with (bridging) */ + node; /**< Socket list node */ + mico_bt_smart_device_t + remote_device; /**< Remote Bluetooth device MICO is connected with (bridging) */ uint16_t - connection_handle; /* Connection handle */ + connection_handle; /**< Connection handle */ uint16_t - last_notified_attribute_handle; /* Last notified attribute handle */ + last_notified_attribute_handle; /**< Last notified attribute handle */ uint8_t - state; /* Internal state */ + state; /**< Internal state */ uint8_t - actions; /* Internal socket actions */ - - aos_bt_smartbridge_auto_connection_callback_t - auto_connection_callback; /* Callback for handing connection event by Auto Connection */ - aos_bt_smartbridge_disconnection_callback_t - disconnection_callback; /* Callback for handling disconnection event by remote device */ - aos_bt_smart_bonding_callback_t - bonding_callback; /* Callback for handling pairing/bonding successful event */ - aos_bt_smartbridge_notification_callback_t - notification_callback; /* Callback for handling GATT notification from remote device */ - aos_bt_smart_connection_settings_t - connection_settings; /* Connection settings */ - aos_bt_smart_security_settings_t - security_settings; /* Security settings */ - aos_bt_smart_bond_info_t - bond_info; /* Bond Info */ - aos_bt_smart_bond_request_t - bond_req; /* Bond Request Structure */ + actions; /**< Internal socket actions */ + + mico_bt_smartbridge_auto_connection_callback_t + auto_connection_callback; /**< Callback for handing connection event by Auto Connection */ + mico_bt_smartbridge_disconnection_callback_t + disconnection_callback; /**< Callback for handling disconnection event by remote device */ + mico_bt_smart_bonding_callback_t + bonding_callback; /**< Callback for handling pairing/bonding successful event */ + mico_bt_smartbridge_notification_callback_t + notification_callback; /**< Callback for handling GATT notification from remote device */ + mico_bt_smart_connection_settings_t + connection_settings; /**< Connection settings */ + mico_bt_smart_security_settings_t + security_settings; /**< Security settings */ + mico_bt_smart_bond_info_t + bond_info; /**< Bond Info */ + mico_bt_smart_bond_request_t + bond_req; /**< Bond Request Structure */ void - *att_cache; /* Pointer to Attribute Cache */ - aos_semaphore_t - semaphore; /* Semaphore */ + *att_cache; /**< Pointer to Attribute Cache */ + mico_semaphore_t + semaphore; /**< Semaphore */ }; -struct aos_bt_smartbridge_auto_conn_cback_parm { - aos_bt_smartbridge_socket_t - *socket; /* A socket associated with the auto connection */ - aos_bt_smart_connection_settings_t - conn_settings; /* The connection settings associated with a socket */ - aos_bt_smart_security_settings_t - security_settings; /* Security settings */ - - aos_bt_smartbridge_auto_connection_callback_t - auto_connection_callback; /* Callback for handing connection event by Auto connection */ - aos_bt_smartbridge_disconnection_callback_t - auto_disconn_callback; /* Callback for handing disconnection event */ - aos_bt_smartbridge_notification_callback_t - notification_callback; /* Callback for handing GATT notification from a remote device */ +struct mico_bt_smartbridge_auto_conn_cback_parm { + mico_bt_smartbridge_socket_t + *socket; /**< A socket associated with the auto connection */ + mico_bt_smart_connection_settings_t + conn_settings; /**< The connection settings associated with a socket */ + mico_bt_smart_security_settings_t + security_settings; /**< Security settings */ + + mico_bt_smartbridge_auto_connection_callback_t + auto_connection_callback; /**< Callback for handing connection event by Auto connection */ + mico_bt_smartbridge_disconnection_callback_t + auto_disconn_callback; /**< Callback for handing disconnection event */ + mico_bt_smartbridge_notification_callback_t + notification_callback; /**< Callback for handing GATT notification from a remote device */ }; -/***************************************************** +/****************************************************** * Function declarations ******************************************************/ -/****************************************************************************/ -/* @addtogroup smartbridge SmartBridge - * @ingroup aosbt +/*****************************************************************************/ +/** @addtogroup smartbridge SmartBridge + * @ingroup micobt * * Bluetooth SmartBridge Functions * * * @{ */ -/****************************************************************************/ +/*****************************************************************************/ -/****************************************************************************/ -/* @addtogroup sbmgmt SmartBridge Management +/*****************************************************************************/ +/** @addtogroup sbmgmt SmartBridge Management * @ingroup smartbridge * * SmartBridge Management Functions @@ -157,10 +152,10 @@ struct aos_bt_smartbridge_auto_conn_cback_parm { * * @{ */ -/****************************************************************************/ +/*****************************************************************************/ -/* Initialise the AOS SmartBridge +/** Initialise the MICO SmartBridge * * @note * This function initialises: @@ -169,15 +164,15 @@ struct aos_bt_smartbridge_auto_conn_cback_parm { * \li SmartBridge Socket Manager * \li Set the number of concurrent connections * - * After calling @ref aos_bt_smartbridge_init, you may call: - * \li @ref aos_bt_smartbridge_enable_attribute_cache() to enable Attribute Cache + * After calling @ref mico_bt_smartbridge_init, you may call: + * \li @ref mico_bt_smartbridge_enable_attribute_cache() to enable Attribute Cache * * @return @ref OSStatus */ -OSStatus aos_bt_smartbridge_init( uint8_t count ); +OSStatus mico_bt_smartbridge_init( uint8_t count ); -/* Deinitialise the AOS SmartBridge +/** Deinitialise the MICO SmartBridge * * @note * This function deinitialises: @@ -188,51 +183,51 @@ OSStatus aos_bt_smartbridge_init( uint8_t count ); * * @return @ref OSStatus */ -OSStatus aos_bt_smartbridge_deinit( void ); +OSStatus mico_bt_smartbridge_deinit( void ); -/* Enable Attribute Cache +/** Enable Attribute Cache * * @note * This function enables the attribute caching feature as specified in the Bluetooth * Specification version 4.0 Volume 3 Part G Section 2.5.2. Attribute Cache allows * SmartBridge to discover server's Attribute information once and use cached information * across reconnections without rediscovery, thus saving time and reducing the amount - * of packet exhange required between AOS SmartBridge and the server. + * of packet exhange required between MICO SmartBridge and the server. * * On a reconnection, SmartBridge searches for matching Attribute information in * the cache. If not found, SmartBridge discovers server's Attribute * information and adds the information to the cache when completed. If SmartBridge * runs out of cache space, the first non-active cache in the list is replaced. * - * Specified services can be used in ATT cache generation, it makes AOS SmartBridge + * Specified services can be used in ATT cache generation, it makes MICO SmartBridge * only cache the services that application can support and operate. * - * @param[in] cache_count : the number of caches that will be supported by AOS SmartBridge + * @param[in] cache_count : the number of caches that will be supported by MICO SmartBridge * @param[in] cache_services : define service list to generate caches * @param[in] service_count : the number of services to generate caches, pass 0 to generate * all primary services * * @return @ref OSStatus */ -OSStatus aos_bt_smartbridge_enable_attribute_cache( uint32_t cache_count, aos_bt_uuid_t cache_services[], - uint32_t service_count ); +OSStatus mico_bt_smartbridge_enable_attribute_cache( uint32_t cache_count, mico_bt_uuid_t cache_services[], + uint32_t service_count ); -/* Disable Attribute Cache +/** Disable Attribute Cache * * @note * This function disables the attribute caching feature * * @return @ref OSStatus */ -OSStatus aos_bt_smartbridge_disable_attribute_cache( void ); +OSStatus mico_bt_smartbridge_disable_attribute_cache( void ); -/* @} */ +/** @} */ -/****************************************************************************/ -/* @addtogroup sbscan SmartBridge Scan +/*****************************************************************************/ +/** @addtogroup sbscan SmartBridge Scan * @ingroup smartbridge * * SmartBridge Scan Functions @@ -240,21 +235,21 @@ OSStatus aos_bt_smartbridge_disable_attribute_cache( void ); * * @{ */ -/****************************************************************************/ +/*****************************************************************************/ -/* Check if the AOS SmartBridge is currently scanning for Bluetooth Smart devices +/** Check if the MICO SmartBridge is currently scanning for Bluetooth Smart devices * * @note * This function checks if the Bluetooth Controller is currently scanning for Bluetooth * Smart devices * - * @return @ref aos_bool_t + * @return @ref mico_bool_t */ -aos_bool_t aos_bt_smartbridge_is_scanning( void ); +mico_bool_t mico_bt_smartbridge_is_scanning( void ); -/* Start scanning for remote Bluetooth Smart devices +/** Start scanning for remote Bluetooth Smart devices * * @note * This function instructs the Bluetooth controller to start scanning for remote @@ -263,13 +258,13 @@ aos_bool_t aos_bt_smartbridge_is_scanning( void ); * * @warning * \li result_callback is an intermediate report callback. The complete scan results - * are retrieved using @ref aos_bt_smartbridge_get_scan_result_list once scan + * are retrieved using @ref mico_bt_smartbridge_get_scan_result_list once scan * is complete * \li advertising_report_callback runs on the context of Bluetooth transport thread. Please refrain * from executing a long task in the callback - * \li complete_callback runs on the context of AOS_BT_EVT_WORKER_THREAD + * \li complete_callback runs on the context of MICO_BT_EVT_WORKER_THREAD * \li If the whitelist filter is enabled in the scan settings, only devices - * in the whitelist appear in the scan results. Call @ref aos_bt_smartbridge_add_device_to_whitelist() + * in the whitelist appear in the scan results. Call @ref mico_bt_smartbridge_add_device_to_whitelist() * to add a device to the whitelist * * @param[in] settings : scan settings @@ -280,22 +275,22 @@ aos_bool_t aos_bt_smartbridge_is_scanning( void ); * * @return @ref OSStatus */ -OSStatus aos_bt_smartbridge_start_scan( const aos_bt_smart_scan_settings_t *settings, - aos_bt_smart_scan_complete_callback_t complete_callback, - aos_bt_smart_advertising_report_callback_t advertising_report_callback ); +OSStatus mico_bt_smartbridge_start_scan( const mico_bt_smart_scan_settings_t *settings, + mico_bt_smart_scan_complete_callback_t complete_callback, + mico_bt_smart_advertising_report_callback_t advertising_report_callback ); -/* Stop the ongoing scan process +/** Stop the ongoing scan process * * This function instructs the Bluetooth controller to stop scanning for remote * Bluetooth Smart devices. * * @return @ref OSStatus */ -OSStatus aos_bt_smartbridge_stop_scan( void ); +OSStatus mico_bt_smartbridge_stop_scan( void ); -/* Retrieve the most recent scan results +/** Retrieve the most recent scan results * * @note * This function returns a linked-list of the most recent scan results @@ -308,13 +303,13 @@ OSStatus aos_bt_smartbridge_stop_scan( void ); * * @return @ref OSStatus */ -OSStatus aos_bt_smartbridge_get_scan_result_list( aos_bt_smart_scan_result_t **result_list, uint32_t *count ); +OSStatus mico_bt_smartbridge_get_scan_result_list( mico_bt_smart_scan_result_t **result_list, uint32_t *count ); -/* @} */ +/** @} */ -/****************************************************************************/ -/* @addtogroup sbwhitelist SmartBridge Whitelist Filter +/*****************************************************************************/ +/** @addtogroup sbwhitelist SmartBridge Whitelist Filter * @ingroup smartbridge * * SmartBridge Whitelist Filter Functions @@ -322,9 +317,9 @@ OSStatus aos_bt_smartbridge_get_scan_result_list( aos_bt_smart_scan_result_t **r * * @{ */ -/****************************************************************************/ +/*****************************************************************************/ -/* Get the number of devices specified by type in the whitelist +/** Get the number of devices specified by type in the whitelist * * @note * This function retrieves the number of Bluetooth Smart devices which can @@ -334,9 +329,9 @@ OSStatus aos_bt_smartbridge_get_scan_result_list( aos_bt_smart_scan_result_t **r * * @return @ref OSStatus */ -OSStatus aos_bt_smartbridge_get_background_connection_devices_size( uint8_t *size ); +OSStatus mico_bt_smartbridge_get_background_connection_devices_size( uint8_t *size ); -/* Set auto connection action - start or stop. +/** Set auto connection action - start or stop. * * @param[in] start_stop : Start or stop auto connection establishment procedure by * the White List. @@ -354,15 +349,16 @@ OSStatus aos_bt_smartbridge_get_background_connection_devices_size( uint8_t *siz * * @return @ref OSStatus */ -OSStatus aos_bt_smartbridge_set_auto_connection_action( aos_bool_t start_stop, - const aos_bt_smart_scan_settings_t *scan_settings, aos_bt_smartbridge_auto_connection_parms_cback_t p_auto_conn_cback ); +OSStatus mico_bt_smartbridge_set_auto_connection_action( mico_bool_t start_stop, + const mico_bt_smart_scan_settings_t *scan_settings, + mico_bt_smartbridge_auto_connection_parms_cback_t p_auto_conn_cback ); -/* @} */ +/** @} */ -/****************************************************************************/ -/* @addtogroup sbsock SmartBridge Socket and Connection Management +/*****************************************************************************/ +/** @addtogroup sbsock SmartBridge Socket and Connection Management * @ingroup smartbridge * * SmartBridge Socket and Connection Functions @@ -370,32 +366,32 @@ OSStatus aos_bt_smartbridge_set_auto_connection_action( aos_bool_t start_stop, * * @{ */ -/****************************************************************************/ +/*****************************************************************************/ -/* Check if the Bluetooth SmartBridge is ready to connect +/** Check if the Bluetooth SmartBridge is ready to connect * * @note * This function checks if the Bluetooth SmartBridge is ready to make a connection * to a Bluetooth Smart device. The Bluetooth Controller does not support concurrent * connection requests. * - * @return @ref aos_bool_t + * @return @ref mico_bool_t */ -aos_bool_t aos_bt_smartbridge_is_ready_to_connect( void ); +mico_bool_t mico_bt_smartbridge_is_ready_to_connect( void ); -/* Get SmartBridge socket status +/** Get SmartBridge socket status * * @param[in] socket : pointer to the socket to get the status * @param[out] status : socket status * * @return @ref OSStatus */ -OSStatus aos_bt_smartbridge_get_socket_status( aos_bt_smartbridge_socket_t *socket, - aos_bt_smartbridge_socket_status_t *status ); +OSStatus mico_bt_smartbridge_get_socket_status( mico_bt_smartbridge_socket_t *socket, + mico_bt_smartbridge_socket_status_t *status ); -/* Create a SmartBridge socket +/** Create a SmartBridge socket * * @note * \li This function initialises the socket internals to make it ready to connect to @@ -406,10 +402,10 @@ OSStatus aos_bt_smartbridge_get_socket_status( aos_bt_smartbridge_socket_t *sock * * @return @ref OSStatus */ -OSStatus aos_bt_smartbridge_create_socket( aos_bt_smartbridge_socket_t *socket ); +OSStatus mico_bt_smartbridge_create_socket( mico_bt_smartbridge_socket_t *socket ); -/* Delete a SmartBridge socket +/** Delete a SmartBridge socket * * @note * This function deinitialises the socket internals. @@ -418,26 +414,26 @@ OSStatus aos_bt_smartbridge_create_socket( aos_bt_smartbridge_socket_t *socket ) * * @return @ref OSStatus */ -OSStatus aos_bt_smartbridge_delete_socket( aos_bt_smartbridge_socket_t *socket ); +OSStatus mico_bt_smartbridge_delete_socket( mico_bt_smartbridge_socket_t *socket ); -/* Initiate a SmartBridge connection with a remote Bluetooth Smart device +/** Initiate a SmartBridge connection with a remote Bluetooth Smart device * * @note * This function creates a connection with the specified remote device. * * \li If Bond Information is loaded, the socket uses the Long-Term Key (LTK), Random * Number (RAND), and Encryption Diversifier (EDIV) of the Bond Information to - * encrypt the connection. Call @ref aos_bt_smartbridge_set_bond_info() before + * encrypt the connection. Call @ref mico_bt_smartbridge_set_bond_info() before * connecting to load Bond information. * \li If Pairing is enforced, the socket initiates Pairing Request and a new Bond - * is created. Call @ref aos_bt_smartbridge_enable_pairing() before connecting + * is created. Call @ref mico_bt_smartbridge_enable_pairing() before connecting * to initiate Pairing Request. * \li If Attribute Cache is enabled, the socket starts a discovery of the server's * Attribute information. * * @warning - * \li Callback functions run on the context of AOS_BT_EVT_WORKER_THREAD. + * \li Callback functions run on the context of MICO_BT_EVT_WORKER_THREAD. * \li If Pairing and Attribute Cache are enabled, this function may block for a * few seconds. * @@ -456,14 +452,14 @@ OSStatus aos_bt_smartbridge_delete_socket( aos_bt_smartbridge_socket_t *socket ) * * @return @ref OSStatus */ -OSStatus aos_bt_smartbridge_connect( aos_bt_smartbridge_socket_t *socket, - const aos_bt_smart_device_t *remote_device, - const aos_bt_smart_connection_settings_t *settings, - aos_bt_smartbridge_disconnection_callback_t disconnection_callback, - aos_bt_smartbridge_notification_callback_t notification_callback ); +OSStatus mico_bt_smartbridge_connect( mico_bt_smartbridge_socket_t *socket, + const mico_bt_smart_device_t *remote_device, + const mico_bt_smart_connection_settings_t *settings, + mico_bt_smartbridge_disconnection_callback_t disconnection_callback, + mico_bt_smartbridge_notification_callback_t notification_callback ); -/* Disconnect a SmartBridge connection +/** Disconnect a SmartBridge connection * * @note * This function disconnects a connection with a remote device. @@ -473,10 +469,10 @@ OSStatus aos_bt_smartbridge_connect( aos_bt_smartbridge_socket_t * * @return @ref OSStatus */ -OSStatus aos_bt_smartbridge_disconnect( aos_bt_smartbridge_socket_t *socket, aos_bool_t remove_it_from_whitelist ); +OSStatus mico_bt_smartbridge_disconnect( mico_bt_smartbridge_socket_t *socket, mico_bool_t remove_it_from_whitelist ); -/* Set transmit power during connection +/** Set transmit power during connection * * @note * This function set the transmit power of the connection @@ -486,12 +482,12 @@ OSStatus aos_bt_smartbridge_disconnect( aos_bt_smartbridge_socket_t *socket, aos * * @return @ref OSStatus */ -OSStatus aos_bt_smartbridge_set_transmit_power( aos_bt_smartbridge_socket_t *socket, int8_t transmit_power_dbm ); +OSStatus mico_bt_smartbridge_set_transmit_power( mico_bt_smartbridge_socket_t *socket, int8_t transmit_power_dbm ); -/* @} */ +/** @} */ -/****************************************************************************/ -/* @addtogroup sbsec SmartBridge Security +/*****************************************************************************/ +/** @addtogroup sbsec SmartBridge Security * @ingroup smartbridge * * SmartBridge Security Functions @@ -499,10 +495,10 @@ OSStatus aos_bt_smartbridge_set_transmit_power( aos_bt_smartbridge_socket_t *soc * * @{ */ -/****************************************************************************/ +/*****************************************************************************/ -/* Set a peer device's bond information +/** Set a peer device's bond information * * @note * This function loads Bond (security) information to the socket which will be used @@ -510,7 +506,7 @@ OSStatus aos_bt_smartbridge_set_transmit_power( aos_bt_smartbridge_socket_t *soc * the complete handshake procedure (pairing) * * @warning - * This function must be called before calling @ref aos_bt_smartbridge_connect + * This function must be called before calling @ref mico_bt_smartbridge_connect * * @param[in,out] socket : socket to load the Bond information into * @param[in] settings : security settings @@ -518,24 +514,24 @@ OSStatus aos_bt_smartbridge_set_transmit_power( aos_bt_smartbridge_socket_t *soc * * @return @ref OSStatus */ -OSStatus aos_bt_smartbridge_set_bond_info( aos_bt_smartbridge_socket_t *socket, - const aos_bt_smart_security_settings_t *settings, - const aos_bt_smart_bond_info_t *bond_info ); +OSStatus mico_bt_smartbridge_set_bond_info( mico_bt_smartbridge_socket_t *socket, + const mico_bt_smart_security_settings_t *settings, + const mico_bt_smart_bond_info_t *bond_info ); -/* Reset the bond information stored in the socket +/** Reset the bond information stored in the socket * * @warning - * This function must be called before calling @ref aos_bt_smartbridge_connect + * This function must be called before calling @ref mico_bt_smartbridge_connect * * @param[in,out] socket : pointer to the socket of the connection to disconnect * * @return @ref OSStatus */ -OSStatus aos_bt_smartbridge_clear_bond_info( aos_bt_smartbridge_socket_t *socket ); +OSStatus mico_bt_smartbridge_clear_bond_info( mico_bt_smartbridge_socket_t *socket ); -/* Force a SmartBridge socket to initiate Pairing Request with a Bluetooth Smart device +/** Force a SmartBridge socket to initiate Pairing Request with a Bluetooth Smart device * * @note * This function prepares the socket to initiate Pairing Request with the device. @@ -543,8 +539,8 @@ OSStatus aos_bt_smartbridge_clear_bond_info( aos_bt_smartbridge_socket_t *socket * if the pairing process succeeds. * * @warning - * \li This function must be called before calling @ref aos_bt_smartbridge_connect - * \li Callback functions run on the context of AOS_BT_EVT_WORKER_THREAD + * \li This function must be called before calling @ref mico_bt_smartbridge_connect + * \li Callback functions run on the context of MICO_BT_EVT_WORKER_THREAD * * @param[in,out] socket : pointer to the socket to enable pairing * @param[in] settings : security settings @@ -555,26 +551,26 @@ OSStatus aos_bt_smartbridge_clear_bond_info( aos_bt_smartbridge_socket_t *socket * * @return @ref OSStatus */ -OSStatus aos_bt_smartbridge_enable_pairing( aos_bt_smartbridge_socket_t *socket, - const aos_bt_smart_security_settings_t *settings, - aos_bt_smart_bonding_callback_t bonding_callback ); +OSStatus mico_bt_smartbridge_enable_pairing( mico_bt_smartbridge_socket_t *socket, + const mico_bt_smart_security_settings_t *settings, + mico_bt_smart_bonding_callback_t bonding_callback ); -/* Set a SmartBridge socket to disable pairing with a remote device +/** Set a SmartBridge socket to disable pairing with a remote device * * @warning - * This function must be called before calling @ref aos_bt_smartbridge_connect + * This function must be called before calling @ref mico_bt_smartbridge_connect * * @param[in,out] socket : pointer to the socket to disable pairing * * @return @ref OSStatus */ -OSStatus aos_bt_smartbridge_disable_pairing( aos_bt_smartbridge_socket_t *socket ); +OSStatus mico_bt_smartbridge_disable_pairing( mico_bt_smartbridge_socket_t *socket ); -/* @} */ +/** @} */ -/****************************************************************************/ -/* @addtogroup sbattr SmartBridge Attribute Cache +/*****************************************************************************/ +/** @addtogroup sbattr SmartBridge Attribute Cache * @ingroup smartbridge * * SmartBridge Attribute Cache Functions @@ -582,10 +578,10 @@ OSStatus aos_bt_smartbridge_disable_pairing( aos_bt_smartbridge_socket_t *socket * * @{ */ -/****************************************************************************/ +/*****************************************************************************/ -/* Enable all GATT notifications supported by the server +/** Enable all GATT notifications supported by the server * * @note * This function searches for client configuration Attribute in the cache and enables @@ -598,11 +594,11 @@ OSStatus aos_bt_smartbridge_disable_pairing( aos_bt_smartbridge_socket_t *socket * * @return @ref OSStatus */ -OSStatus aos_bt_smartbridge_enable_attribute_cache_notification( aos_bt_smartbridge_socket_t *socket, - aos_bool_t is_notification_or_indication ); +OSStatus mico_bt_smartbridge_enable_attribute_cache_notification( mico_bt_smartbridge_socket_t *socket, + mico_bool_t is_notification_or_indication ); -/* Disable all GATT notifications supported by the server +/** Disable all GATT notifications supported by the server * * @note * This function searches for client configuration Attribute in the cache and disables @@ -614,9 +610,9 @@ OSStatus aos_bt_smartbridge_enable_attribute_cache_notification( aos_bt_smartbri * * @return @ref OSStatus */ -OSStatus aos_bt_smartbridge_disable_attribute_cache_notification( aos_bt_smartbridge_socket_t *socket ); +OSStatus mico_bt_smartbridge_disable_attribute_cache_notification( mico_bt_smartbridge_socket_t *socket ); -/* Release attribute cache data +/** Release attribute cache data * * @note * This function release all data in the cache and put attribute cache to free list. @@ -627,9 +623,9 @@ OSStatus aos_bt_smartbridge_disable_attribute_cache_notification( aos_bt_smartbr * * @return @ref OSStatus */ -OSStatus aos_bt_smartbridge_remove_attribute_cache( aos_bt_smartbridge_socket_t *socket ); +OSStatus mico_bt_smartbridge_remove_attribute_cache( mico_bt_smartbridge_socket_t *socket ); -/* Retrieve the list of cached Attributes +/** Retrieve the list of cached Attributes * * @note * This function retrieves the list of cached Attributes of the socket @@ -641,11 +637,11 @@ OSStatus aos_bt_smartbridge_remove_attribute_cache( aos_bt_smartbridge_socket_t * * @return @ref OSStatus */ -OSStatus aos_bt_smartbridge_get_attribute_cache_list( aos_bt_smartbridge_socket_t *socket, - aos_bt_smart_attribute_list_t **att_cache_list ); +OSStatus mico_bt_smartbridge_get_attribute_cache_list( mico_bt_smartbridge_socket_t *socket, + mico_bt_smart_attribute_list_t **att_cache_list ); -/* Find and read attribute with the handle provided from the Attribute Cache +/** Find and read attribute with the handle provided from the Attribute Cache * * @note * This function searches for an attribute with the given handle in the cache and @@ -660,11 +656,11 @@ OSStatus aos_bt_smartbridge_get_attribute_cache_list( aos_bt_smartbridge_socket_ * * @return @ref OSStatus */ -OSStatus aos_bt_smartbridge_get_attribute_cache_by_handle( aos_bt_smartbridge_socket_t *socket, uint16_t handle, - aos_bt_smart_attribute_t *attribute, uint16_t size ); +OSStatus mico_bt_smartbridge_get_attribute_cache_by_handle( mico_bt_smartbridge_socket_t *socket, uint16_t handle, + mico_bt_smart_attribute_t *attribute, uint16_t size ); -/* Find and read attribute with the UUID provided from the local attribute database +/** Find and read attribute with the UUID provided from the local attribute database * * @note * This function searches for an attribute with the given UUID in the local @@ -681,17 +677,18 @@ OSStatus aos_bt_smartbridge_get_attribute_cache_by_handle( aos_bt_smartbridge_so * * @return @ref OSStatus */ -OSStatus aos_bt_smartbridge_get_attribute_cache_by_uuid( aos_bt_smartbridge_socket_t *socket, const aos_bt_uuid_t *uuid, - uint16_t starting_handle, uint16_t ending_handle, aos_bt_smart_attribute_t *attribute, uint32_t size ); -OSStatus aos_bt_smartbridge_get_service_from_attribute_cache_by_uuid( aos_bt_smartbridge_socket_t *socket, - const aos_bt_uuid_t *uuid, uint16_t starting_handle, uint16_t ending_handle, aos_bt_smart_attribute_t *attribute, - uint32_t size ); -OSStatus aos_bt_smartbridge_get_characteritics_from_attribute_cache_by_uuid( aos_bt_smartbridge_socket_t *socket, - const aos_bt_uuid_t *uuid, uint16_t starting_handle, uint16_t ending_handle, aos_bt_smart_attribute_t *attribute, - uint32_t size ); +OSStatus mico_bt_smartbridge_get_attribute_cache_by_uuid( mico_bt_smartbridge_socket_t *socket, + const mico_bt_uuid_t *uuid, uint16_t starting_handle, uint16_t ending_handle, mico_bt_smart_attribute_t *attribute, + uint32_t size ); +OSStatus mico_bt_smartbridge_get_service_from_attribute_cache_by_uuid( mico_bt_smartbridge_socket_t *socket, + const mico_bt_uuid_t *uuid, uint16_t starting_handle, uint16_t ending_handle, mico_bt_smart_attribute_t *attribute, + uint32_t size ); +OSStatus mico_bt_smartbridge_get_characteritics_from_attribute_cache_by_uuid( mico_bt_smartbridge_socket_t *socket, + const mico_bt_uuid_t *uuid, uint16_t starting_handle, uint16_t ending_handle, mico_bt_smart_attribute_t *attribute, + uint32_t size ); -/* Find and refresh Characteristic Value with the given handle in the Attribute Cache +/** Find and refresh Characteristic Value with the given handle in the Attribute Cache * * @note * This function reads the Characteristic Value from the server and updates the @@ -704,11 +701,11 @@ OSStatus aos_bt_smartbridge_get_characteritics_from_attribute_cache_by_uuid( aos * * @return OSStatus */ -OSStatus aos_bt_smartbridge_refresh_attribute_cache_characteristic_value( aos_bt_smartbridge_socket_t *socket, - uint16_t handle ); +OSStatus mico_bt_smartbridge_refresh_attribute_cache_characteristic_value( mico_bt_smartbridge_socket_t *socket, + uint16_t handle ); -/* Write Characteristic Value in the Attribute Cache to the server +/** Write Characteristic Value in the Attribute Cache to the server * * @note * This function writes the given Characteristic Value to the server and updates the @@ -721,15 +718,14 @@ OSStatus aos_bt_smartbridge_refresh_attribute_cache_characteristic_value( aos_bt * * @return OSStatus */ -OSStatus aos_bt_smartbridge_write_attribute_cache_characteristic_value( aos_bt_smartbridge_socket_t *socket, - const aos_bt_smart_attribute_t *characteristic_value ); +OSStatus mico_bt_smartbridge_write_attribute_cache_characteristic_value( mico_bt_smartbridge_socket_t *socket, + const mico_bt_smart_attribute_t *characteristic_value ); -/* @} */ +/** @} */ -/* @} */ +/** @} */ #ifdef __cplusplus } /* extern "C" */ #endif -#endif diff --git a/device/bluetooth/mk3239/bt_smart/include/mico_bt_smartbridge_constants.h b/device/bluetooth/mk3239/bt_smart/include/mico_bt_smartbridge_constants.h new file mode 100644 index 0000000000..ffb89421d4 --- /dev/null +++ b/device/bluetooth/mk3239/bt_smart/include/mico_bt_smartbridge_constants.h @@ -0,0 +1,84 @@ + +/** @file + * Defines common constants and types for the MICO Bluetooth Framework + */ + +#pragma once + +#include "mico_bt_constants.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************** + * Macros + ******************************************************/ + + +/****************************************************** + * Constants + ******************************************************/ + +/** @cond !ADDTHIS*/ +#define MICO_BT_ADDRESS_BYTE_SIZE 6 +/** @endcond */ + +/****************************************************** + * Enumerations + ******************************************************/ + +/** + * UUID size + */ +typedef enum { + UUID_16BIT = 0x02, /**< 16-bit */ + UUID_32BIT = 0x04, /**< 32-bit */ + UUID_128BIT = 0x10 /**< 128-bit */ +} mico_bt_uuid_size_t; + + +/****************************************************** + * Type Definitions + ******************************************************/ + +/****************************************************** + * Structures + ******************************************************/ + +#if 0 +/** + * Bluetooth Device Address (BD_ADDR) + * A 48-bit address that uniquely identifies a Bluetooth device + */ +typedef struct { + uint8_t address[MICO_BT_ADDRESS_BYTE_SIZE]; /**< Address. 48-bit Bluetooth device address in a little-endian format */ +} mico_bt_device_address_t; + + +/** + * Universally Unique Identifier (UUID) + * A standardised format of string ID that uniquely identifies a Bluetooth service + */ +typedef struct { + union { + uint16_t value_16_bit; /**< 16-bit UUID value. */ + uint16_t value_128_bit[UUID_128BIT / 2]; /**< 128-bit UUID value. */ + } value; /**< A union of UUID values */ + + mico_bt_uuid_size_t size; /**< UUID size */ + +} mico_bt_uuid_t; +#endif + +/****************************************************** + * Global Variables + ******************************************************/ + +/****************************************************** + * Function Declarations + ******************************************************/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif diff --git a/framework/bluetooth/smartbt/include/smartbt_smartbridge_gatt.h b/device/bluetooth/mk3239/bt_smart/include/mico_bt_smartbridge_gatt.h similarity index 63% rename from framework/bluetooth/smartbt/include/smartbt_smartbridge_gatt.h rename to device/bluetooth/mk3239/bt_smart/include/mico_bt_smartbridge_gatt.h index eadbab2141..79922ea62f 100644 --- a/framework/bluetooth/smartbt/include/smartbt_smartbridge_gatt.h +++ b/device/bluetooth/mk3239/bt_smart/include/mico_bt_smartbridge_gatt.h @@ -1,51 +1,47 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ -#ifndef _SMART_BT_SMART_BRIDGE_GATT_H_ -#define _SMART_BT_SMART_BRIDGE_GATT_H_ +#pragma once -/* @file +/** @file * Defines SmartBridge Generic Attribute Profile (GATT) Functions */ -#include "smartbt_smartbridge.h" -#include "smartbt_smart_interface.h" +#include "mico_bt_smartbridge.h" +#include "mico_bt_smart_interface.h" #ifdef __cplusplus extern "C" { #endif -/***************************************************** +/****************************************************** * Macros ******************************************************/ -/***************************************************** +/****************************************************** * Constants ******************************************************/ -/***************************************************** +/****************************************************** * Enumerations ******************************************************/ -/***************************************************** +/****************************************************** * Type Definitions ******************************************************/ -/***************************************************** +/****************************************************** * Structures ******************************************************/ -/***************************************************** +/****************************************************** * Global Variables ******************************************************/ -/***************************************************** +/****************************************************** * Function Declarations ******************************************************/ -/****************************************************************************/ -/* @addtogroup sbgatt SmartBridge GATT Procedures +/*****************************************************************************/ +/** @addtogroup sbgatt SmartBridge GATT Procedures * @ingroup smartbridge * * SmartBridge Raw GATT Functions @@ -53,10 +49,10 @@ extern "C" { * * @{ */ -/****************************************************************************/ +/*****************************************************************************/ -/* Discover All Primary Services +/** Discover All Primary Services * * @param[in] socket : socket that is connected to the server to discover * Primary Services from @@ -64,11 +60,11 @@ extern "C" { * * @return @ref OSStatus */ -OSStatus aos_bt_smartbridge_gatt_discover_all_primary_services( const aos_bt_smartbridge_socket_t *socket, - aos_bt_smart_attribute_list_t *service_list ); +OSStatus mico_bt_smartbridge_gatt_discover_all_primary_services( const mico_bt_smartbridge_socket_t *socket, + mico_bt_smart_attribute_list_t *service_list ); -/* Discover Primary Services by the given UUID +/** Discover Primary Services by the given UUID * * @param[in] socket : socket that is connected to the server to discover * Primary Services from @@ -77,11 +73,11 @@ OSStatus aos_bt_smartbridge_gatt_discover_all_primary_services( const aos_bt_sma * * @return @ref OSStatus */ -OSStatus aos_bt_smartbridge_gatt_discover_primary_services_by_uuid( const aos_bt_smartbridge_socket_t *socket, - const aos_bt_uuid_t *uuid, aos_bt_smart_attribute_list_t *service_list ); +OSStatus mico_bt_smartbridge_gatt_discover_primary_services_by_uuid( const mico_bt_smartbridge_socket_t *socket, + const mico_bt_uuid_t *uuid, mico_bt_smart_attribute_list_t *service_list ); -/* Find Included Services +/** Find Included Services * * @param[in] socket : socket that is connected to the server to discover * Included Services from @@ -93,11 +89,11 @@ OSStatus aos_bt_smartbridge_gatt_discover_primary_services_by_uuid( const aos_bt * * @return @ref OSStatus */ -OSStatus aos_bt_smartbridge_gatt_find_included_services( const aos_bt_smartbridge_socket_t *socket, - uint16_t start_handle, uint16_t end_handle, aos_bt_smart_attribute_list_t *include_list ); +OSStatus mico_bt_smartbridge_gatt_find_included_services( const mico_bt_smartbridge_socket_t *socket, + uint16_t start_handle, uint16_t end_handle, mico_bt_smart_attribute_list_t *include_list ); -/* Discover All Characterisitics in a Service +/** Discover All Characterisitics in a Service * * @param[in] socket : socket that is connected to the server to discover * Characteristics from @@ -109,11 +105,11 @@ OSStatus aos_bt_smartbridge_gatt_find_included_services( const aos_bt_smartbridg * * @return @ref OSStatus */ -OSStatus aos_bt_smartbridge_gatt_discover_all_characteristics_in_a_service( const aos_bt_smartbridge_socket_t *socket, - uint16_t start_handle, uint16_t end_handle, aos_bt_smart_attribute_list_t *characteristic_list ); +OSStatus mico_bt_smartbridge_gatt_discover_all_characteristics_in_a_service( const mico_bt_smartbridge_socket_t *socket, + uint16_t start_handle, uint16_t end_handle, mico_bt_smart_attribute_list_t *characteristic_list ); -/* Discover Characterisitics by the given UUID +/** Discover Characterisitics by the given UUID * * @param[in] socket : socket that is connected to the server to discover * Characteristics from @@ -126,16 +122,16 @@ OSStatus aos_bt_smartbridge_gatt_discover_all_characteristics_in_a_service( cons * * @return @ref OSStatus */ -OSStatus aos_bt_smartbridge_gatt_discover_characteristic_by_uuid( const aos_bt_smartbridge_socket_t *socket, - const aos_bt_uuid_t *uuid, uint16_t start_handle, uint16_t end_handle, - aos_bt_smart_attribute_list_t *characteristic_list ); +OSStatus mico_bt_smartbridge_gatt_discover_characteristic_by_uuid( const mico_bt_smartbridge_socket_t *socket, + const mico_bt_uuid_t *uuid, uint16_t start_handle, uint16_t end_handle, + mico_bt_smart_attribute_list_t *characteristic_list ); -/* Discover Attribute Handle and Type of all Characteristic Descriptors +/** Discover Attribute Handle and Type of all Characteristic Descriptors * * @note - * Additional information of the Descriptors can be read using @ref aos_bt_smartbridge_gatt_read_characteristic_descriptor() - * and @ref aos_bt_smartbridge_gatt_read_long_characteristic_descriptor() + * Additional information of the Descriptors can be read using @ref mico_bt_smartbridge_gatt_read_characteristic_descriptor() + * and @ref mico_bt_smartbridge_gatt_read_long_characteristic_descriptor() * * @param[in] socket : socket that is connected to the server to discover * Characteristic Descriptors from @@ -147,12 +143,12 @@ OSStatus aos_bt_smartbridge_gatt_discover_characteristic_by_uuid( const aos_bt_s * * @return @ref OSStatus */ -OSStatus aos_bt_smartbridge_gatt_discover_handle_and_type_of_all_characteristic_descriptors( - const aos_bt_smartbridge_socket_t *socket, uint16_t start_handle, uint16_t end_handle, - aos_bt_smart_attribute_list_t *descriptor_list ); +OSStatus mico_bt_smartbridge_gatt_discover_handle_and_type_of_all_characteristic_descriptors( + const mico_bt_smartbridge_socket_t *socket, uint16_t start_handle, uint16_t end_handle, + mico_bt_smart_attribute_list_t *descriptor_list ); -/* Read Characteristic Descriptor +/** Read Characteristic Descriptor * * @param[in] socket : socket that is connected to the server to read * Characteristic Descriptor from @@ -162,11 +158,11 @@ OSStatus aos_bt_smartbridge_gatt_discover_handle_and_type_of_all_characteristic_ * * @return @ref OSStatus */ -OSStatus aos_bt_smartbridge_gatt_read_characteristic_descriptor( const aos_bt_smartbridge_socket_t *socket, - uint16_t handle, const aos_bt_uuid_t *uuid, aos_bt_smart_attribute_t **descriptor ); +OSStatus mico_bt_smartbridge_gatt_read_characteristic_descriptor( const mico_bt_smartbridge_socket_t *socket, + uint16_t handle, const mico_bt_uuid_t *uuid, mico_bt_smart_attribute_t **descriptor ); -/* Read Long Characteristic Descriptor +/** Read Long Characteristic Descriptor * * @param[in] socket : socket that is connected to the server to read * Characteristic Descriptor from @@ -176,11 +172,11 @@ OSStatus aos_bt_smartbridge_gatt_read_characteristic_descriptor( const aos_bt_sm * * @return @ref OSStatus */ -OSStatus aos_bt_smartbridge_gatt_read_long_characteristic_descriptor( const aos_bt_smartbridge_socket_t *socket, - uint16_t handle, const aos_bt_uuid_t *uuid, aos_bt_smart_attribute_t **descriptor ); +OSStatus mico_bt_smartbridge_gatt_read_long_characteristic_descriptor( const mico_bt_smartbridge_socket_t *socket, + uint16_t handle, const mico_bt_uuid_t *uuid, mico_bt_smart_attribute_t **descriptor ); -/* Write Characteristic Descriptor +/** Write Characteristic Descriptor * * @param[in] socket : socket that is connected to the server to write * Characteristic Descriptor to @@ -188,11 +184,11 @@ OSStatus aos_bt_smartbridge_gatt_read_long_characteristic_descriptor( const aos_ * * @return @ref OSStatus */ -OSStatus aos_bt_smartbridge_gatt_write_characteristic_descriptor( const aos_bt_smartbridge_socket_t *socket, - const aos_bt_smart_attribute_t *descriptor ); +OSStatus mico_bt_smartbridge_gatt_write_characteristic_descriptor( const mico_bt_smartbridge_socket_t *socket, + const mico_bt_smart_attribute_t *descriptor ); -/* Write Long Characteristic Descriptor +/** Write Long Characteristic Descriptor * * @param[in] socket : socket that is connected to the server to write * Characteristic Descriptor to @@ -200,11 +196,11 @@ OSStatus aos_bt_smartbridge_gatt_write_characteristic_descriptor( const aos_bt_s * * @return @ref OSStatus */ -OSStatus aos_bt_smartbridge_gatt_write_long_characteristic_descriptor( const aos_bt_smartbridge_socket_t *socket, - const aos_bt_smart_attribute_t *descriptor ); +OSStatus mico_bt_smartbridge_gatt_write_long_characteristic_descriptor( const mico_bt_smartbridge_socket_t *socket, + const mico_bt_smart_attribute_t *descriptor ); -/* Read Characteristic Value +/** Read Characteristic Value * * @param[in] socket : socket that is connected to the server to read * Characteristic Value from @@ -214,11 +210,11 @@ OSStatus aos_bt_smartbridge_gatt_write_long_characteristic_descriptor( const aos * * @return @ref OSStatus */ -OSStatus aos_bt_smartbridge_gatt_read_characteristic_value( const aos_bt_smartbridge_socket_t *socket, uint16_t handle, - const aos_bt_uuid_t *uuid, aos_bt_smart_attribute_t **characteristic_value ); +OSStatus mico_bt_smartbridge_gatt_read_characteristic_value( const mico_bt_smartbridge_socket_t *socket, + uint16_t handle, const mico_bt_uuid_t *uuid, mico_bt_smart_attribute_t **characteristic_value ); -/* Read Characteristic Value +/** Read Characteristic Value * * @param[in] socket : socket that is connected to the server to read * Characteristic Value from @@ -227,11 +223,11 @@ OSStatus aos_bt_smartbridge_gatt_read_characteristic_value( const aos_bt_smartbr * * @return @ref OSStatus */ -OSStatus aos_bt_smartbridge_gatt_read_characteristic_values_using_uuid( const aos_bt_smartbridge_socket_t *socket, - const aos_bt_uuid_t *uuid, aos_bt_smart_attribute_list_t *characteristic_value_list ); +OSStatus mico_bt_smartbridge_gatt_read_characteristic_values_using_uuid( const mico_bt_smartbridge_socket_t *socket, + const mico_bt_uuid_t *uuid, mico_bt_smart_attribute_list_t *characteristic_value_list ); -/* Read Long Characteristic Value +/** Read Long Characteristic Value * * @param[in] socket : socket that is connected to the server to read * Characteristic Value from @@ -241,11 +237,11 @@ OSStatus aos_bt_smartbridge_gatt_read_characteristic_values_using_uuid( const ao * * @return @ref OSStatus */ -OSStatus aos_bt_smartbridge_gatt_read_long_characteristic_value( const aos_bt_smartbridge_socket_t *socket, - uint16_t handle, const aos_bt_uuid_t *uuid, aos_bt_smart_attribute_t **characteristic_value ); +OSStatus mico_bt_smartbridge_gatt_read_long_characteristic_value( const mico_bt_smartbridge_socket_t *socket, + uint16_t handle, const mico_bt_uuid_t *uuid, mico_bt_smart_attribute_t **characteristic_value ); -/* Write Characteristic Value +/** Write Characteristic Value * * @param[in] socket : socket that is connected to the server to write * Characteristic Value to @@ -253,11 +249,11 @@ OSStatus aos_bt_smartbridge_gatt_read_long_characteristic_value( const aos_bt_sm * * @return @ref OSStatus */ -OSStatus aos_bt_smartbridge_gatt_write_characteristic_value( const aos_bt_smartbridge_socket_t *socket, - const aos_bt_smart_attribute_t *characteristic_value ); +OSStatus mico_bt_smartbridge_gatt_write_characteristic_value( const mico_bt_smartbridge_socket_t *socket, + const mico_bt_smart_attribute_t *characteristic_value ); -/* Write Long Characteristic Value +/** Write Long Characteristic Value * * @param[in] socket : socket that is connected to the server to write * Characteristic Value to @@ -265,14 +261,12 @@ OSStatus aos_bt_smartbridge_gatt_write_characteristic_value( const aos_bt_smartb * * @return @ref OSStatus */ -OSStatus aos_bt_smartbridge_gatt_write_long_characteristic_value( const aos_bt_smartbridge_socket_t *socket, - const aos_bt_smart_attribute_t *characteristic_value ); +OSStatus mico_bt_smartbridge_gatt_write_long_characteristic_value( const mico_bt_smartbridge_socket_t *socket, + const mico_bt_smart_attribute_t *characteristic_value ); -/* @} */ +/** @} */ #ifdef __cplusplus } /* extern "C" */ #endif - -#endif diff --git a/framework/bluetooth/smartbt/internal/bt_peripheral_stack_interface.c b/device/bluetooth/mk3239/bt_smart/internal/bt_peripheral_stack_interface.c similarity index 50% rename from framework/bluetooth/smartbt/internal/bt_peripheral_stack_interface.c rename to device/bluetooth/mk3239/bt_smart/internal/bt_peripheral_stack_interface.c index 6c6c79a3db..57f14a7266 100644 --- a/framework/bluetooth/smartbt/internal/bt_peripheral_stack_interface.c +++ b/device/bluetooth/mk3239/bt_smart/internal/bt_peripheral_stack_interface.c @@ -1,16 +1,13 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - /** @file * */ -#include "smartbt_smartbridge.h" +#include "mico.h" +#include "mico_bt_smartbridge.h" -#include "smartbt.h" -#include "aos_bt_gatt.h" -#include "aos_bt_ble.h" -#include "smartbt_cfg.h" +#include "mico_bt.h" +#include "mico_bt_gatt.h" +#include "mico_bt_ble.h" +#include "mico_bt_cfg.h" #include "bt_smartbridge_socket_manager.h" #include "bt_smartbridge_att_cache_manager.h" @@ -51,13 +48,13 @@ gatt_subprocedure_t peripheral_subprocedure; -extern aos_bt_cfg_settings_t aos_bt_cfg_settings; -extern aos_bt_dev_ble_io_caps_req_t default_io_caps_ble; +extern mico_bt_cfg_settings_t mico_bt_cfg_settings; +extern mico_bt_dev_ble_io_caps_req_t default_io_caps_ble; -extern aos_bt_gatt_status_t bt_peripheral_gatt_callback( aos_bt_gatt_evt_t event, - aos_bt_gatt_event_data_t *p_event_data ); +extern mico_bt_gatt_status_t bt_peripheral_gatt_callback( mico_bt_gatt_evt_t event, + mico_bt_gatt_event_data_t *p_event_data ); -aos_bt_smart_advertising_complete_callback_t app_advertising_complete_callback; +mico_bt_smart_advertising_complete_callback_t app_advertising_complete_callback; /****************************************************** * Function Definitions @@ -69,22 +66,22 @@ OSStatus peripheral_bt_interface_initialize( void ) bt_peripheral_log( "Initializing Bluetooth Interface..." ); - result = aos_rtos_init_mutex( &peripheral_subprocedure.mutex ); - if ( result != AOS_BT_SUCCESS ) { + result = mico_rtos_init_mutex( &peripheral_subprocedure.mutex ); + if ( result != MICO_BT_SUCCESS ) { bt_peripheral_log( "Error creating mutex" ); return result; } - result = aos_rtos_init_semaphore( &peripheral_subprocedure.done_semaphore, 1 ); - if ( result != AOS_BT_SUCCESS ) { + result = mico_rtos_init_semaphore( &peripheral_subprocedure.done_semaphore, 1 ); + if ( result != MICO_BT_SUCCESS ) { bt_peripheral_log( "Error creating semaphore" ); return result; } subprocedure_reset( &peripheral_subprocedure ); - aos_bt_gatt_register( GATT_IF_FIXED_DB_APP, bt_peripheral_gatt_callback ); + mico_bt_gatt_register( GATT_IF_FIXED_DB_APP, bt_peripheral_gatt_callback ); - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } OSStatus peripheral_bt_interface_deinitialize( void ) @@ -92,23 +89,23 @@ OSStatus peripheral_bt_interface_deinitialize( void ) bt_peripheral_log( "Deinitializing Bluetooth Interface..." ); subprocedure_reset( &peripheral_subprocedure ); - aos_rtos_deinit_mutex( &peripheral_subprocedure.mutex ); - aos_rtos_deinit_semaphore( &peripheral_subprocedure.done_semaphore ); + mico_rtos_deinit_mutex( &peripheral_subprocedure.mutex ); + mico_rtos_deinit_semaphore( &peripheral_subprocedure.done_semaphore ); - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } -OSStatus peripheral_bt_interface_cancel_last_connect( aos_bt_device_address_t address ) +OSStatus peripheral_bt_interface_cancel_last_connect( mico_bt_device_address_t address ) { - return aos_bt_gatt_cancel_connect( address, AOS_TRUE ); + return mico_bt_gatt_cancel_connect( address, MICO_TRUE ); } OSStatus peripheral_bt_interface_disconnect( uint16_t connection_handle ) { - return aos_bt_gatt_disconnect( connection_handle ); + return mico_bt_gatt_disconnect( connection_handle ); } -OSStatus peripheral_bt_interface_set_security_settings( const aos_bt_smart_security_settings_t *settings ) +OSStatus peripheral_bt_interface_set_security_settings( const mico_bt_smart_security_settings_t *settings ) { /* update the security settings as per passed by the application */ default_io_caps_ble.local_io_cap = settings->io_capabilities; @@ -118,43 +115,43 @@ OSStatus peripheral_bt_interface_set_security_settings( const aos_bt_smart_secur default_io_caps_ble.init_keys = settings->master_key_distribution; default_io_caps_ble.resp_keys = settings->slave_key_distribution; - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } -OSStatus peripheral_bt_interface_start_advertisements( aos_bt_smart_advertising_settings_t *settings, - aos_bt_smart_advertising_complete_callback_t complete_callback ) +OSStatus peripheral_bt_interface_start_advertisements( mico_bt_smart_advertising_settings_t *settings, + mico_bt_smart_advertising_complete_callback_t complete_callback ) { - aos_bt_smart_advertising_type_t advertising_type = settings->type; - aos_bool_t high_duty = settings->use_high_duty; - aos_bt_ble_advert_mode_t mode; + mico_bt_smart_advertising_type_t advertising_type = settings->type; + mico_bool_t high_duty = settings->use_high_duty; + mico_bt_ble_advert_mode_t mode; app_advertising_complete_callback = complete_callback; switch ( advertising_type ) { case BT_SMART_UNDIRECTED_ADVERTISING: { - aos_bt_cfg_settings.ble_advert_cfg.high_duty_min_interval = settings->high_duty_interval; - aos_bt_cfg_settings.ble_advert_cfg.high_duty_max_interval = settings->high_duty_interval; - aos_bt_cfg_settings.ble_advert_cfg.high_duty_duration = settings->high_duty_duration; + mico_bt_cfg_settings.ble_advert_cfg.high_duty_min_interval = settings->high_duty_interval; + mico_bt_cfg_settings.ble_advert_cfg.high_duty_max_interval = settings->high_duty_interval; + mico_bt_cfg_settings.ble_advert_cfg.high_duty_duration = settings->high_duty_duration; - aos_bt_cfg_settings.ble_advert_cfg.low_duty_min_interval = settings->low_duty_interval; - aos_bt_cfg_settings.ble_advert_cfg.low_duty_max_interval = settings->low_duty_interval; - aos_bt_cfg_settings.ble_advert_cfg.low_duty_duration = settings->low_duty_duration; + mico_bt_cfg_settings.ble_advert_cfg.low_duty_min_interval = settings->low_duty_interval; + mico_bt_cfg_settings.ble_advert_cfg.low_duty_max_interval = settings->low_duty_interval; + mico_bt_cfg_settings.ble_advert_cfg.low_duty_duration = settings->low_duty_duration; mode = high_duty ? BTM_BLE_ADVERT_UNDIRECTED_HIGH : BTM_BLE_ADVERT_UNDIRECTED_LOW; - return aos_bt_start_advertisements( mode, 0, NULL ); + return mico_bt_start_advertisements( mode, 0, NULL ); } case BT_SMART_NON_CONNECTABLE_UNDIRECTED_ADVERTISING: case BT_SMART_DISCOVERABLE_ADVERTISING: { - aos_bt_cfg_settings.ble_advert_cfg.high_duty_nonconn_min_interval = settings->high_duty_interval; - aos_bt_cfg_settings.ble_advert_cfg.high_duty_nonconn_max_interval = settings->high_duty_interval; - aos_bt_cfg_settings.ble_advert_cfg.high_duty_nonconn_duration = settings->high_duty_duration; + mico_bt_cfg_settings.ble_advert_cfg.high_duty_nonconn_min_interval = settings->high_duty_interval; + mico_bt_cfg_settings.ble_advert_cfg.high_duty_nonconn_max_interval = settings->high_duty_interval; + mico_bt_cfg_settings.ble_advert_cfg.high_duty_nonconn_duration = settings->high_duty_duration; - aos_bt_cfg_settings.ble_advert_cfg.low_duty_nonconn_min_interval = settings->low_duty_interval; - aos_bt_cfg_settings.ble_advert_cfg.low_duty_nonconn_max_interval = settings->low_duty_interval; - aos_bt_cfg_settings.ble_advert_cfg.low_duty_nonconn_duration = settings->low_duty_duration; + mico_bt_cfg_settings.ble_advert_cfg.low_duty_nonconn_min_interval = settings->low_duty_interval; + mico_bt_cfg_settings.ble_advert_cfg.low_duty_nonconn_max_interval = settings->low_duty_interval; + mico_bt_cfg_settings.ble_advert_cfg.low_duty_nonconn_duration = settings->low_duty_duration; if ( advertising_type == BT_SMART_NON_CONNECTABLE_UNDIRECTED_ADVERTISING ) { mode = high_duty ? BTM_BLE_ADVERT_NONCONN_HIGH : BTM_BLE_ADVERT_NONCONN_LOW; @@ -162,43 +159,43 @@ OSStatus peripheral_bt_interface_start_advertisements( aos_bt_smart_advertising_ mode = high_duty ? BTM_BLE_ADVERT_DISCOVERABLE_HIGH : BTM_BLE_ADVERT_DISCOVERABLE_LOW; } - return aos_bt_start_advertisements( mode, 0, NULL ); + return mico_bt_start_advertisements( mode, 0, NULL ); } case BT_SMART_DIRECTED_ADVERTISING: { - aos_bt_cfg_settings.ble_advert_cfg.low_duty_directed_min_interval = settings->low_duty_interval; - aos_bt_cfg_settings.ble_advert_cfg.low_duty_directed_max_interval = settings->low_duty_interval; - aos_bt_cfg_settings.ble_advert_cfg.low_duty_directed_duration = settings->low_duty_duration; + mico_bt_cfg_settings.ble_advert_cfg.low_duty_directed_min_interval = settings->low_duty_interval; + mico_bt_cfg_settings.ble_advert_cfg.low_duty_directed_max_interval = settings->low_duty_interval; + mico_bt_cfg_settings.ble_advert_cfg.low_duty_directed_duration = settings->low_duty_duration; - aos_bt_cfg_settings.ble_advert_cfg.high_duty_directed_min_interval = settings->high_duty_interval; - aos_bt_cfg_settings.ble_advert_cfg.high_duty_directed_max_interval = settings->high_duty_interval; + mico_bt_cfg_settings.ble_advert_cfg.high_duty_directed_min_interval = settings->high_duty_interval; + mico_bt_cfg_settings.ble_advert_cfg.high_duty_directed_max_interval = settings->high_duty_interval; mode = high_duty ? BTM_BLE_ADVERT_DIRECTED_HIGH : BTM_BLE_ADVERT_DIRECTED_LOW; - return aos_bt_start_advertisements( BTM_BLE_ADVERT_DIRECTED_HIGH, settings->directed_advertisement_addr_type, - settings->directed_advertisement_addr ); + return mico_bt_start_advertisements( BTM_BLE_ADVERT_DIRECTED_HIGH, settings->directed_advertisement_addr_type, + settings->directed_advertisement_addr ); } default: - return oUnknownErr; + return kUnknownErr; } } OSStatus peripheral_bt_interface_stop_advertisements( void ) { app_advertising_complete_callback = NULL; - return aos_bt_start_advertisements( BTM_BLE_ADVERT_OFF, 0, NULL ); + return mico_bt_start_advertisements( BTM_BLE_ADVERT_OFF, 0, NULL ); } -void peripheral_bt_interface_advertisements_state_change_callback( aos_bt_ble_advert_mode_t state ) +void peripheral_bt_interface_advertisements_state_change_callback( mico_bt_ble_advert_mode_t state ) { if ( state == BTM_BLE_ADVERT_OFF && app_advertising_complete_callback != NULL ) { - aos_rtos_send_asynchronous_event( AOS_BT_EVT_WORKER_THREAD, app_advertising_complete_callback, NULL ); + mico_rtos_send_asynchronous_event( MICO_BT_EVT_WORKER_THREAD, app_advertising_complete_callback, NULL ); } } OSStatus peripheral_bt_interface_indicate_attribute_value ( uint16_t connection_handle, - const aos_bt_ext_attribute_value_t *attribute ) + const mico_bt_ext_attribute_value_t *attribute ) { uint16_t val_len = 0; uint16_t offset = 0; @@ -209,11 +206,11 @@ OSStatus peripheral_bt_interface_indicate_attribute_value ( uint16_t connection_ val_len = attribute->value_length; - while ( aos_bt_gatt_send_indication( connection_handle, attribute->handle, &val_len, - attribute->p_value + offset ) == AOS_BT_GATT_SUCCESS ) { + while ( mico_bt_gatt_send_indication( connection_handle, attribute->handle, &val_len, + attribute->p_value + offset ) == MICO_BT_GATT_SUCCESS ) { subprocedure_wait_for_completion( &peripheral_subprocedure ); - if ( peripheral_subprocedure.result != AOS_BT_SUCCESS ) { + if ( peripheral_subprocedure.result != MICO_BT_SUCCESS ) { break; } @@ -231,7 +228,7 @@ OSStatus peripheral_bt_interface_indicate_attribute_value ( uint16_t connection_ } OSStatus peripheral_bt_interface_notify_attribute_value( uint16_t connection_handle, - const aos_bt_ext_attribute_value_t *attribute ) + const mico_bt_ext_attribute_value_t *attribute ) { uint16_t val_len = 0; uint16_t offset = 0; @@ -242,8 +239,8 @@ OSStatus peripheral_bt_interface_notify_attribute_value( uint16_t connection_han val_len = attribute->value_length; - while ( aos_bt_gatt_send_notification( connection_handle, attribute->handle, &val_len, - attribute->p_value + offset ) == AOS_BT_GATT_SUCCESS ) { + while ( mico_bt_gatt_send_notification( connection_handle, attribute->handle, &val_len, + attribute->p_value + offset ) == MICO_BT_GATT_SUCCESS ) { offset += val_len; val_len = attribute->value_length - offset; @@ -254,31 +251,31 @@ OSStatus peripheral_bt_interface_notify_attribute_value( uint16_t connection_han subprocedure_unlock( &peripheral_subprocedure ); - return oNoErr; + return kNoErr; } #if 0 -OSStatus smartbridge_bt_interface_start_advertise( const aos_bt_smart_advertise_settings_t *settings, - aos_bt_smart_advertise_mode_changed_callback_t advertise_mode_changed_callback ) +OSStatus smartbridge_bt_interface_start_advertise( const mico_bt_smart_advertise_settings_t *settings, + mico_bt_smart_advertise_mode_changed_callback_t advertise_mode_changed_callback ) { - aos_bool_t duplicate_filter_enabled = AOS_FALSE; + mico_bool_t duplicate_filter_enabled = MICO_FALSE; /* fill with the settings provided by the smartserver-application */ - aos_bt_cfg_settings.ble_advert_cfg. + mico_bt_cfg_settings.ble_advert_cfg. - aos_bt_cfg_settings.ble_scan_cfg.scan_mode = settings->type; - aos_bt_cfg_settings.ble_scan_cfg.high_duty_scan_window = settings->window; - aos_bt_cfg_settings.ble_scan_cfg.high_duty_scan_duration = settings->duration_second; - aos_bt_cfg_settings.ble_scan_cfg.high_duty_scan_interval = settings->interval; + mico_bt_cfg_settings.ble_scan_cfg.scan_mode = settings->type; + mico_bt_cfg_settings.ble_scan_cfg.high_duty_scan_window = settings->window; + mico_bt_cfg_settings.ble_scan_cfg.high_duty_scan_duration = settings->duration_second; + mico_bt_cfg_settings.ble_scan_cfg.high_duty_scan_interval = settings->interval; duplicate_filter_enabled = settings->filter_duplicates; app_scan_complete_callback = complete_callback; app_scan_report_callback = advertising_report_callback; - return aos_bt_start_advertisements( BTM_BLE_ADVERT_UNDIRECTED_LOW, 0, NULL ); - return aos_bt_ble_scan( BTM_BLE_SCAN_TYPE_HIGH_DUTY, duplicate_filter_enabled, smartbridge_scan_result_callback ); + return mico_bt_start_advertisements( BTM_BLE_ADVERT_UNDIRECTED_LOW, 0, NULL ); + return mico_bt_ble_scan( BTM_BLE_SCAN_TYPE_HIGH_DUTY, duplicate_filter_enabled, smartbridge_scan_result_callback ); } @@ -287,62 +284,62 @@ OSStatus smartbridge_bt_interface_stop_scan( ) app_scan_complete_callback = NULL; app_scan_report_callback = NULL; - return aos_bt_ble_scan( BTM_BLE_SCAN_TYPE_NONE, AOS_TRUE, smartbridge_scan_result_callback ); + return mico_bt_ble_scan( BTM_BLE_SCAN_TYPE_NONE, MICO_TRUE, smartbridge_scan_result_callback ); } -OSStatus smartbridge_bt_interface_start_scan( const aos_bt_smart_scan_settings_t *settings, - aos_bt_smart_scan_complete_callback_t complete_callback, - aos_bt_smart_advertising_report_callback_t advertising_report_callback ) +OSStatus smartbridge_bt_interface_start_scan( const mico_bt_smart_scan_settings_t *settings, + mico_bt_smart_scan_complete_callback_t complete_callback, + mico_bt_smart_advertising_report_callback_t advertising_report_callback ) { - aos_bool_t duplicate_filter_enabled = AOS_FALSE; + mico_bool_t duplicate_filter_enabled = MICO_FALSE; /* First delete the previous scan result list */ smartbridge_helper_delete_scan_result_list(); /* fill with the settings provided by the smartbridge-application */ - aos_bt_cfg_settings.ble_scan_cfg.scan_mode = settings->type; - aos_bt_cfg_settings.ble_scan_cfg.high_duty_scan_window = settings->window; - aos_bt_cfg_settings.ble_scan_cfg.high_duty_scan_duration = settings->duration_second; - aos_bt_cfg_settings.ble_scan_cfg.high_duty_scan_interval = settings->interval; + mico_bt_cfg_settings.ble_scan_cfg.scan_mode = settings->type; + mico_bt_cfg_settings.ble_scan_cfg.high_duty_scan_window = settings->window; + mico_bt_cfg_settings.ble_scan_cfg.high_duty_scan_duration = settings->duration_second; + mico_bt_cfg_settings.ble_scan_cfg.high_duty_scan_interval = settings->interval; duplicate_filter_enabled = settings->filter_duplicates; app_scan_complete_callback = complete_callback; app_scan_report_callback = advertising_report_callback; - return aos_bt_ble_scan( BTM_BLE_SCAN_TYPE_HIGH_DUTY, duplicate_filter_enabled, smartbridge_scan_result_callback ); + return mico_bt_ble_scan( BTM_BLE_SCAN_TYPE_HIGH_DUTY, duplicate_filter_enabled, smartbridge_scan_result_callback ); } #endif -OSStatus peripheral_bt_interface_update_advertisements_white_list( aos_bool_t add, - aos_bt_device_address_t device_address ) +OSStatus peripheral_bt_interface_update_advertisements_white_list( mico_bool_t add, + mico_bt_device_address_t device_address ) { if ( device_address == 0 ) { - return oParamErr; + return kParamErr; } if ( add ) { - if ( TRUE != aos_bt_ble_update_advertising_white_list( AOS_TRUE, device_address ) ) { - return oGeneralErr; + if ( TRUE != mico_bt_ble_update_advertising_white_list( MICO_TRUE, device_address ) ) { + return kGeneralErr; } } else { - if ( TRUE != aos_bt_ble_update_advertising_white_list( AOS_FALSE, device_address ) ) { - return oGeneralErr; + if ( TRUE != mico_bt_ble_update_advertising_white_list( MICO_FALSE, device_address ) ) { + return kGeneralErr; } } - return oNoErr; + return kNoErr; } OSStatus peripheral_bt_interface_get_advertisements_white_list_size( uint8_t *size ) { - if ( TRUE != aos_bt_ble_get_advertisement_white_list_size(size) ) { - return oGeneralErr; + if ( TRUE != mico_bt_ble_get_advertisement_white_list_size(size) ) { + return kGeneralErr; } - return oNoErr; + return kNoErr; } -OSStatus peripheral_bt_interface_set_advertisements_filter_policy(aos_bt_peripheral_adv_filter_policy_t type) +OSStatus peripheral_bt_interface_set_advertisements_filter_policy(mico_bt_peripheral_adv_filter_policy_t type) { - OSStatus status = oNoErr; - aos_bt_ble_advert_filter_policy_t policy; + OSStatus status = kNoErr; + mico_bt_ble_advert_filter_policy_t policy; switch (type) { case PERIPHERAL_ADVERT_FILTER_ALL_CONNECTION_REQ_ALL_SCAN_REQ: @@ -358,11 +355,11 @@ OSStatus peripheral_bt_interface_set_advertisements_filter_policy(aos_bt_periphe policy = BTM_BLE_ADVERT_FILTER_WHITELIST_CONNECTION_REQ_WHITELIST_SCAN_REQ; break; default: - return oParamErr; + return kParamErr; } - if (!aos_bt_ble_update_advertisement_filter_policy(policy)) { - status = oUnknownErr; + if (!mico_bt_ble_update_advertisement_filter_policy(policy)) { + status = kUnknownErr; } return status; } diff --git a/framework/bluetooth/smartbt/internal/bt_peripheral_stack_interface.h b/device/bluetooth/mk3239/bt_smart/internal/bt_peripheral_stack_interface.h similarity index 69% rename from framework/bluetooth/smartbt/internal/bt_peripheral_stack_interface.h rename to device/bluetooth/mk3239/bt_smart/internal/bt_peripheral_stack_interface.h index 6f703d4a03..fdfe7f4b63 100644 --- a/framework/bluetooth/smartbt/internal/bt_peripheral_stack_interface.h +++ b/device/bluetooth/mk3239/bt_smart/internal/bt_peripheral_stack_interface.h @@ -1,18 +1,12 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#ifndef _BT_PERIPHERAL_STACK_INTERFACE_H_ -#define _BT_PERIPHERAL_STACK_INTERFACE_H_ - #pragma once /** @file * Peripheral's Interface Header with Bluetooth Stack */ -#include "smartbt_peripheral.h" -#include "smartbt_smart_interface.h" +//#include "mico_utilities.h" +#include "mico_bt_peripheral.h" +#include "mico_bt_smart_interface.h" #ifdef __cplusplus extern "C" { @@ -54,32 +48,30 @@ OSStatus peripheral_bt_interface_initialize( void ); OSStatus peripheral_bt_interface_deinitialize( void ); -OSStatus peripheral_bt_interface_cancel_last_connect( aos_bt_device_address_t address ); +OSStatus peripheral_bt_interface_cancel_last_connect( mico_bt_device_address_t address ); OSStatus peripheral_bt_interface_disconnect( uint16_t connection_handle ); -OSStatus peripheral_bt_interface_set_security_settings( const aos_bt_smart_security_settings_t *settings ); +OSStatus peripheral_bt_interface_set_security_settings( const mico_bt_smart_security_settings_t *settings ); -OSStatus peripheral_bt_interface_start_advertisements( aos_bt_smart_advertising_settings_t *settings, - aos_bt_smart_advertising_complete_callback_t complete_callback ); +OSStatus peripheral_bt_interface_start_advertisements( mico_bt_smart_advertising_settings_t *settings, + mico_bt_smart_advertising_complete_callback_t complete_callback ); OSStatus peripheral_bt_interface_stop_advertisements( void ); OSStatus peripheral_bt_interface_indicate_attribute_value ( uint16_t connection_handle, - const aos_bt_ext_attribute_value_t *attribute ); + const mico_bt_ext_attribute_value_t *attribute ); OSStatus peripheral_bt_interface_notify_attribute_value( uint16_t connection_handle, - const aos_bt_ext_attribute_value_t *attribute ); + const mico_bt_ext_attribute_value_t *attribute ); -OSStatus peripheral_bt_interface_update_advertisements_white_list( aos_bool_t add, - aos_bt_device_address_t device_address ); +OSStatus peripheral_bt_interface_update_advertisements_white_list( mico_bool_t add, + mico_bt_device_address_t device_address ); OSStatus peripheral_bt_interface_get_advertisements_white_list_size( uint8_t *size ); -OSStatus peripheral_bt_interface_set_advertisements_filter_policy(aos_bt_peripheral_adv_filter_policy_t type); +OSStatus peripheral_bt_interface_set_advertisements_filter_policy(mico_bt_peripheral_adv_filter_policy_t type); #ifdef __cplusplus } /* extern "C" */ #endif - -#endif diff --git a/framework/bluetooth/smartbt/internal/bt_smart_attribute.c b/device/bluetooth/mk3239/bt_smart/internal/bt_smart_attribute.c similarity index 74% rename from framework/bluetooth/smartbt/internal/bt_smart_attribute.c rename to device/bluetooth/mk3239/bt_smart/internal/bt_smart_attribute.c index 552add2d3e..76f948bfcd 100644 --- a/framework/bluetooth/smartbt/internal/bt_smart_attribute.c +++ b/device/bluetooth/mk3239/bt_smart/internal/bt_smart_attribute.c @@ -1,20 +1,9 @@ -/** - * UNPUBLISHED PROPRIETARY SOURCE CODE - * Copyright (c) 2016 MXCHIP Inc. - * - * The contents of this file may not be disclosed to third parties, copied or - * duplicated in any form, in whole or in part, without the prior written - * permission of MXCHIP Corporation. - * - */ - /** @file * */ -//#include "aosbt.h" -#include "os_wrapper.h" -#include "aos_bt_constants.h" +#include "mico_rtos.h" +#include "mico_bt_constants.h" #include "string.h" #include "bt_smartbridge_helper.h" #include "bt_smartbridge_stack_interface.h" @@ -50,18 +39,18 @@ ******************************************************/ static const uint16_t fixed_attribute_size_list[] = { - [AOS_ATTRIBUTE_TYPE_NO_VALUE ] = ATTR_NO_VALUE_SIZE, - [AOS_ATTRIBUTE_TYPE_LONG_VALUE ] = ATTR_LONG_VALUE_SIZE, - [AOS_ATTRIBUTE_TYPE_PRIMARY_SERVICE ] = ATTR_SERVICE_SIZE, - [AOS_ATTRIBUTE_TYPE_INCLUDE ] = ATTR_INCLUDE_SIZE, - [AOS_ATTRIBUTE_TYPE_CHARACTERISTIC ] = ATTR_CHARACTERISTIC_SIZE, - [AOS_ATTRIBUTE_TYPE_CHARACTERISTIC_VALUE ] = 0, // Variable length - [AOS_ATTRIBUTE_TYPE_CHARACTERISTIC_DESCRIPTOR_EXTENDED_PROPERTIES ] = ATTR_EXTENDED_PROPERTIES_SIZE, - [AOS_ATTRIBUTE_TYPE_CHARACTERISTIC_DESCRIPTOR_USER_DESCRIPTION ] = 0, // Variable length - [AOS_ATTRIBUTE_TYPE_CHARACTERISTIC_DESCRIPTOR_CLIENT_CONFIGURATION] = ATTR_CLIENT_CONFIG_SIZE, - [AOS_ATTRIBUTE_TYPE_CHARACTERISTIC_DESCRIPTOR_SERVER_CONFIGURATION] = ATTR_SERVER_CONFIG_SIZE, - [AOS_ATTRIBUTE_TYPE_CHARACTERISTIC_DESCRIPTOR_PRESENTATION_FORMAT ] = ATTR_PRESENTATION_FORMAT_SIZE, - [AOS_ATTRIBUTE_TYPE_CHARACTERISTIC_DESCRIPTOR_AGGREGATE_FORMAT ] = 0, // Variable length + [MICO_ATTRIBUTE_TYPE_NO_VALUE ] = ATTR_NO_VALUE_SIZE, + [MICO_ATTRIBUTE_TYPE_LONG_VALUE ] = ATTR_LONG_VALUE_SIZE, + [MICO_ATTRIBUTE_TYPE_PRIMARY_SERVICE ] = ATTR_SERVICE_SIZE, + [MICO_ATTRIBUTE_TYPE_INCLUDE ] = ATTR_INCLUDE_SIZE, + [MICO_ATTRIBUTE_TYPE_CHARACTERISTIC ] = ATTR_CHARACTERISTIC_SIZE, + [MICO_ATTRIBUTE_TYPE_CHARACTERISTIC_VALUE ] = 0, // Variable length + [MICO_ATTRIBUTE_TYPE_CHARACTERISTIC_DESCRIPTOR_EXTENDED_PROPERTIES ] = ATTR_EXTENDED_PROPERTIES_SIZE, + [MICO_ATTRIBUTE_TYPE_CHARACTERISTIC_DESCRIPTOR_USER_DESCRIPTION ] = 0, // Variable length + [MICO_ATTRIBUTE_TYPE_CHARACTERISTIC_DESCRIPTOR_CLIENT_CONFIGURATION] = ATTR_CLIENT_CONFIG_SIZE, + [MICO_ATTRIBUTE_TYPE_CHARACTERISTIC_DESCRIPTOR_SERVER_CONFIGURATION] = ATTR_SERVER_CONFIG_SIZE, + [MICO_ATTRIBUTE_TYPE_CHARACTERISTIC_DESCRIPTOR_PRESENTATION_FORMAT ] = ATTR_PRESENTATION_FORMAT_SIZE, + [MICO_ATTRIBUTE_TYPE_CHARACTERISTIC_DESCRIPTOR_AGGREGATE_FORMAT ] = 0, // Variable length }; static uint32_t attributes_created = 0; @@ -87,8 +76,8 @@ static uint32_t attributes_deleted = 0; * Static Function Declarations ******************************************************/ -static OSStatus print_uuid( const aos_bt_uuid_t *uuid ); -static OSStatus print_type( const aos_bt_uuid_t *uuid ); +static OSStatus print_uuid( const mico_bt_uuid_t *uuid ); +static OSStatus print_type( const mico_bt_uuid_t *uuid ); /****************************************************** * Variable Definitions @@ -98,25 +87,25 @@ static OSStatus print_type( const aos_bt_uuid_t *uuid ); * Function Definitions ******************************************************/ -OSStatus aos_bt_smart_attribute_create( aos_bt_smart_attribute_t **attribute, aos_bt_smart_attribute_type_t type, - uint16_t variable_length ) +OSStatus mico_bt_smart_attribute_create( mico_bt_smart_attribute_t **attribute, mico_bt_smart_attribute_type_t type, + uint16_t variable_length ) { uint16_t size; if ( attribute == NULL ) { - return AOS_BT_BADARG; + return MICO_BT_BADARG; } switch ( type ) { - case AOS_ATTRIBUTE_TYPE_CHARACTERISTIC_VALUE: { + case MICO_ATTRIBUTE_TYPE_CHARACTERISTIC_VALUE: { size = ATTR_CHARACTERISTIC_VALUE_SIZE( variable_length ); break; } - case AOS_ATTRIBUTE_TYPE_CHARACTERISTIC_DESCRIPTOR_USER_DESCRIPTION: { + case MICO_ATTRIBUTE_TYPE_CHARACTERISTIC_DESCRIPTOR_USER_DESCRIPTION: { size = ATTR_USER_DESCRIPTION_SIZE( variable_length ); break; } - case AOS_ATTRIBUTE_TYPE_CHARACTERISTIC_DESCRIPTOR_AGGREGATE_FORMAT: { + case MICO_ATTRIBUTE_TYPE_CHARACTERISTIC_DESCRIPTOR_AGGREGATE_FORMAT: { size = ATTR_AGGREGATE_FORMAT_SIZE( variable_length ); break; } @@ -126,23 +115,23 @@ OSStatus aos_bt_smart_attribute_create( aos_bt_smart_attribute_t **attribute, ao } } - *attribute = (aos_bt_smart_attribute_t *)malloc_named("attribute", size ); + *attribute = (mico_bt_smart_attribute_t *)malloc_named("attribute", size ); if ( *attribute == NULL ) { - return AOS_BT_OUT_OF_HEAP_SPACE; + return MICO_BT_OUT_OF_HEAP_SPACE; } memset( *attribute, 0, size ); (*attribute)->value_struct_size = size - ATTR_COMMON_FIELDS_SIZE; attributes_created++; - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } -OSStatus aos_bt_smart_attribute_delete( aos_bt_smart_attribute_t *attribute ) +OSStatus mico_bt_smart_attribute_delete( mico_bt_smart_attribute_t *attribute ) { if ( attribute == NULL ) { - return AOS_BT_BADARG; + return MICO_BT_BADARG; } /* Set to NULL to make sure this doesn't point to any used attribute */ @@ -154,23 +143,24 @@ OSStatus aos_bt_smart_attribute_delete( aos_bt_smart_attribute_t *attribute ) attributes_deleted++; - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } -OSStatus aos_bt_smart_attribute_create_list( aos_bt_smart_attribute_list_t *list ) +OSStatus mico_bt_smart_attribute_create_list( mico_bt_smart_attribute_list_t *list ) { if ( list == NULL ) { - return AOS_BT_BADARG; + return MICO_BT_BADARG; } memset( list, 0, sizeof( *list ) ); - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } -OSStatus aos_bt_smart_attribute_add_to_list( aos_bt_smart_attribute_list_t *list, aos_bt_smart_attribute_t *attribute ) +OSStatus mico_bt_smart_attribute_add_to_list( mico_bt_smart_attribute_list_t *list, + mico_bt_smart_attribute_t *attribute ) { if ( list == NULL || attribute == NULL ) { - return AOS_BT_BADARG; + return MICO_BT_BADARG; } if ( list->count == 0 ) { @@ -178,8 +168,8 @@ OSStatus aos_bt_smart_attribute_add_to_list( aos_bt_smart_attribute_list_t *list attribute->next = NULL; list->list = attribute; } else { - aos_bt_smart_attribute_t *curr = list->list; - aos_bt_smart_attribute_t *prev = NULL; + mico_bt_smart_attribute_t *curr = list->list; + mico_bt_smart_attribute_t *prev = NULL; /* Traverse the list and compare handle */ while ( curr != NULL ) { @@ -210,20 +200,20 @@ OSStatus aos_bt_smart_attribute_add_to_list( aos_bt_smart_attribute_list_t *list /* Increment count */ list->count++; - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } -OSStatus aos_bt_smart_attribute_remove_from_list( aos_bt_smart_attribute_list_t *list, uint16_t handle ) +OSStatus mico_bt_smart_attribute_remove_from_list( mico_bt_smart_attribute_list_t *list, uint16_t handle ) { if ( list == NULL ) { - return AOS_BT_BADARG; + return MICO_BT_BADARG; } if ( list->count == 0 ) { - return AOS_BT_LIST_EMPTY; + return MICO_BT_LIST_EMPTY; } else { - aos_bt_smart_attribute_t *curr = list->list; - aos_bt_smart_attribute_t *prev = NULL; + mico_bt_smart_attribute_t *curr = list->list; + mico_bt_smart_attribute_t *prev = NULL; /* Traverse the list and compare handle */ while ( curr != NULL ) { @@ -236,11 +226,11 @@ OSStatus aos_bt_smart_attribute_remove_from_list( aos_bt_smart_attribute_list_t prev->next = curr->next; } - aos_bt_smart_attribute_delete( curr ); + mico_bt_smart_attribute_delete( curr ); /* Decrement count */ list->count--; - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } /* Update previous and current attribute pointers */ @@ -249,15 +239,15 @@ OSStatus aos_bt_smart_attribute_remove_from_list( aos_bt_smart_attribute_list_t } } - return AOS_BT_ITEM_NOT_IN_LIST; + return MICO_BT_ITEM_NOT_IN_LIST; } -OSStatus aos_bt_smart_attribute_delete_list( aos_bt_smart_attribute_list_t *list ) +OSStatus mico_bt_smart_attribute_delete_list( mico_bt_smart_attribute_list_t *list ) { - aos_bt_smart_attribute_t *curr; + mico_bt_smart_attribute_t *curr; if ( list == NULL ) { - return AOS_BT_BADARG; + return MICO_BT_BADARG; } curr = list->list; @@ -265,35 +255,35 @@ OSStatus aos_bt_smart_attribute_delete_list( aos_bt_smart_attribute_list_t *list /* Traverse through the list and delete all attributes */ while ( curr != NULL ) { /* Store pointer to next because curr is about to be deleted */ - aos_bt_smart_attribute_t *next = curr->next; + mico_bt_smart_attribute_t *next = curr->next; - aos_bt_smart_attribute_delete( curr ); + mico_bt_smart_attribute_delete( curr ); /* Update curr */ curr = next; } memset( list, 0, sizeof( *list ) ); - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } -OSStatus aos_bt_smart_attribute_search_list_by_handle( const aos_bt_smart_attribute_list_t *list, uint16_t handle, - aos_bt_smart_attribute_t **attribute ) +OSStatus mico_bt_smart_attribute_search_list_by_handle( const mico_bt_smart_attribute_list_t *list, uint16_t handle, + mico_bt_smart_attribute_t **attribute ) { if ( list == NULL || attribute == NULL ) { - return AOS_BT_BADARG; + return MICO_BT_BADARG; } if ( list->count == 0 ) { - return AOS_BT_LIST_EMPTY; + return MICO_BT_LIST_EMPTY; } else { - aos_bt_smart_attribute_t *curr = list->list; + mico_bt_smart_attribute_t *curr = list->list; /* Traverse the list and compare handle */ while ( curr != NULL ) { if ( curr->handle == handle ) { *attribute = curr; - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } /* Update current attribute pointers */ @@ -301,20 +291,20 @@ OSStatus aos_bt_smart_attribute_search_list_by_handle( const aos_bt_smart_attrib } } - return AOS_BT_ITEM_NOT_IN_LIST; + return MICO_BT_ITEM_NOT_IN_LIST; } -OSStatus aos_bt_smart_attribute_search_list_by_uuid( const aos_bt_smart_attribute_list_t *list, - const aos_bt_uuid_t *uuid, uint16_t starting_handle, uint16_t ending_handle, aos_bt_smart_attribute_t **attribute ) +OSStatus mico_bt_smart_attribute_search_list_by_uuid( const mico_bt_smart_attribute_list_t *list, + const mico_bt_uuid_t *uuid, uint16_t starting_handle, uint16_t ending_handle, mico_bt_smart_attribute_t **attribute ) { if ( list == NULL || uuid == NULL || attribute == NULL ) { - return AOS_BT_BADARG; + return MICO_BT_BADARG; } if ( list->count == 0 ) { - return AOS_BT_LIST_EMPTY; + return MICO_BT_LIST_EMPTY; } else { - aos_bt_smart_attribute_t *curr = list->list; + mico_bt_smart_attribute_t *curr = list->list; /* Traverse the list until it's larger or equal the starting handle provided */ while ( curr != NULL && curr->handle <= ending_handle ) { @@ -327,7 +317,7 @@ OSStatus aos_bt_smart_attribute_search_list_by_uuid( const aos_bt_smart_attribut /* Return if reaches the end of the list */ if ( curr == NULL || curr->handle > ending_handle ) { - return AOS_BT_ITEM_NOT_IN_LIST; + return MICO_BT_ITEM_NOT_IN_LIST; } /* Traverse the list and compare handle */ @@ -335,7 +325,7 @@ OSStatus aos_bt_smart_attribute_search_list_by_uuid( const aos_bt_smart_attribut /* Check if UUID is found */ if ( memcmp( (void *)&curr->type.uu, &uuid->uu, uuid->len ) == 0 ) { *attribute = curr; - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } /* Update current attribute pointers */ @@ -343,43 +333,43 @@ OSStatus aos_bt_smart_attribute_search_list_by_uuid( const aos_bt_smart_attribut } } - return AOS_BT_ITEM_NOT_IN_LIST; + return MICO_BT_ITEM_NOT_IN_LIST; } -OSStatus aos_bt_smart_attribute_merge_lists( aos_bt_smart_attribute_list_t *trunk_list, - aos_bt_smart_attribute_list_t *branch_list ) +OSStatus mico_bt_smart_attribute_merge_lists( mico_bt_smart_attribute_list_t *trunk_list, + mico_bt_smart_attribute_list_t *branch_list ) { - aos_bt_smart_attribute_t *curr; + mico_bt_smart_attribute_t *curr; if ( trunk_list == NULL || branch_list == NULL ) { - return AOS_BT_BADARG; + return MICO_BT_BADARG; } curr = branch_list->list; /* Traverse through the branch list */ while ( curr != NULL ) { - aos_bt_smart_attribute_t *prev = curr; + mico_bt_smart_attribute_t *prev = curr; /* Increment curr and take prev of the branch list */ curr = curr->next; prev->next = NULL; /* Add prev to the trunk list */ - aos_bt_smart_attribute_add_to_list( trunk_list, prev ); + mico_bt_smart_attribute_add_to_list( trunk_list, prev ); } memset( branch_list, 0, sizeof( *branch_list ) ); - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } -OSStatus aos_bt_smart_attribute_print( const aos_bt_smart_attribute_t *attribute ) +OSStatus mico_bt_smart_attribute_print( const mico_bt_smart_attribute_t *attribute ) { - aos_bt_smart_attribute_t *curr_attr = (aos_bt_smart_attribute_t *)attribute; + mico_bt_smart_attribute_t *curr_attr = (mico_bt_smart_attribute_t *)attribute; if ( attribute == NULL ) { - return AOS_BT_BADARG; + return MICO_BT_BADARG; } WPRINT_LIB_INFO( ( "----------------------------------------------------\n" ) ); @@ -496,22 +486,22 @@ OSStatus aos_bt_smart_attribute_print( const aos_bt_smart_attribute_t *attribute } WPRINT_LIB_INFO( ( "----------------------------------------------------\n" ) ); - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } -OSStatus aos_bt_smart_attribute_print_list( const aos_bt_smart_attribute_list_t *list ) +OSStatus mico_bt_smart_attribute_print_list( const mico_bt_smart_attribute_list_t *list ) { - aos_bt_smart_attribute_t *curr_attr = (aos_bt_smart_attribute_t *)list->list; + mico_bt_smart_attribute_t *curr_attr = (mico_bt_smart_attribute_t *)list->list; while ( curr_attr != NULL ) { - aos_bt_smart_attribute_print( curr_attr ); + mico_bt_smart_attribute_print( curr_attr ); curr_attr = curr_attr->next; } - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } -static OSStatus print_uuid( const aos_bt_uuid_t *uuid ) +static OSStatus print_uuid( const mico_bt_uuid_t *uuid ) { if ( uuid->len == UUID_16BIT ) { WPRINT_LIB_INFO( ( "%04x\n", (int)uuid->uu.uuid16 ) ); @@ -527,14 +517,14 @@ static OSStatus print_uuid( const aos_bt_uuid_t *uuid ) (int)uuid->uu.uuid128[7] ) ); } - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } -static OSStatus print_type( const aos_bt_uuid_t *uuid ) +static OSStatus print_type( const mico_bt_uuid_t *uuid ) { if ( uuid->len != UUID_16BIT ) { WPRINT_LIB_INFO( ( "Unknown Type" ) ); - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } switch ( uuid->uu.uuid16 ) { @@ -608,26 +598,26 @@ static OSStatus print_type( const aos_bt_uuid_t *uuid ) } } - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } -OSStatus aos_bt_smart_attribute_get_list_head( const aos_bt_smart_attribute_list_t *list, - aos_bt_smart_attribute_t **head ) +OSStatus mico_bt_smart_attribute_get_list_head( const mico_bt_smart_attribute_list_t *list, + mico_bt_smart_attribute_t **head ) { if ( list == NULL ) { - return AOS_BT_BADARG; + return MICO_BT_BADARG; } *head = list->list; - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } -OSStatus aos_bt_smart_attribute_get_list_count( const aos_bt_smart_attribute_list_t *list, uint32_t *count ) +OSStatus mico_bt_smart_attribute_get_list_count( const mico_bt_smart_attribute_list_t *list, uint32_t *count ) { if ( list == NULL ) { - return AOS_BT_BADARG; + return MICO_BT_BADARG; } *count = list->count; - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } diff --git a/framework/bluetooth/smartbt/internal/bt_smartbridge_att_cache_manager.c b/device/bluetooth/mk3239/bt_smart/internal/bt_smartbridge_att_cache_manager.c similarity index 67% rename from framework/bluetooth/smartbt/internal/bt_smartbridge_att_cache_manager.c rename to device/bluetooth/mk3239/bt_smart/internal/bt_smartbridge_att_cache_manager.c index cc2780d572..70ad629618 100644 --- a/framework/bluetooth/smartbt/internal/bt_smartbridge_att_cache_manager.c +++ b/device/bluetooth/mk3239/bt_smart/internal/bt_smartbridge_att_cache_manager.c @@ -1,14 +1,12 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ /** @file * */ +#include "mico.h" #include "LinkListUtils.h" -#include "smartbt_smartbridge.h" -#include "smartbt_smart_interface.h" +#include "mico_bt_smartbridge.h" +#include "mico_bt_smart_interface.h" #include "bt_smartbridge_stack_interface.h" #include "bt_smartbridge_helper.h" #include "bt_smartbridge_att_cache_manager.h" @@ -52,21 +50,21 @@ sizeof( bt_smartbridge_att_cache_t ) * ( cache_count - 1 ) typedef struct bt_smartbridge_att_cache { linked_list_node_t node; - aos_bool_t is_active; - aos_bool_t is_discovering; - aos_bt_smart_device_t remote_device; + mico_bool_t is_active; + mico_bool_t is_discovering; + mico_bt_smart_device_t remote_device; uint16_t connection_handle; - aos_bt_smart_attribute_list_t attribute_list; - aos_mutex_t mutex; + mico_bt_smart_attribute_list_t attribute_list; + mico_mutex_t mutex; } bt_smartbridge_att_cache_t; typedef struct { uint32_t count; - aos_bt_uuid_t *att_cache_services; + mico_bt_uuid_t *att_cache_services; uint32_t att_cache_services_count; linked_list_t free_list; linked_list_t used_list; - aos_mutex_t mutex; + mico_mutex_t mutex; bt_smartbridge_att_cache_t pool[1]; } bt_smartbridge_att_cache_manager_t; @@ -94,27 +92,28 @@ static bt_smartbridge_att_cache_manager_t *att_cache_manager = NULL; * Function Definitions ******************************************************/ -OSStatus bt_smartbridge_att_cache_enable( uint32_t cache_count, aos_bt_uuid_t cache_services[], uint32_t service_count ) +OSStatus bt_smartbridge_att_cache_enable( uint32_t cache_count, mico_bt_uuid_t cache_services[], + uint32_t service_count ) { uint32_t a; OSStatus result; bt_smartbridge_att_cache_manager_t *manager; - aos_bt_uuid_t *services = NULL; + mico_bt_uuid_t *services = NULL; if ( att_cache_manager != NULL ) { - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } manager = (bt_smartbridge_att_cache_manager_t *)malloc_named( "att_cache", CALCULATE_ATT_CACHE_MANAGER_SIZE( cache_count ) ); if ( manager == NULL ) { - return AOS_BT_OUT_OF_HEAP_SPACE; + return MICO_BT_OUT_OF_HEAP_SPACE; } if ( service_count != 0 ) { - services = (aos_bt_uuid_t *)malloc_named( "cache_services", service_count * sizeof(aos_bt_uuid_t) ); + services = (mico_bt_uuid_t *)malloc_named( "cache_services", service_count * sizeof(mico_bt_uuid_t) ); if ( services == NULL ) { - return AOS_BT_OUT_OF_HEAP_SPACE; + return MICO_BT_OUT_OF_HEAP_SPACE; } } @@ -126,32 +125,32 @@ OSStatus bt_smartbridge_att_cache_enable( uint32_t cache_count, aos_bt_uuid_t ca manager->att_cache_services_count = service_count; if ( service_count != 0 ) { manager->att_cache_services = services; - memcpy( manager->att_cache_services, cache_services, service_count * sizeof(aos_bt_uuid_t) ); + memcpy( manager->att_cache_services, cache_services, service_count * sizeof(mico_bt_uuid_t) ); } result = linked_list_init( &manager->free_list ); - if ( result != AOS_BT_SUCCESS ) { + if ( result != MICO_BT_SUCCESS ) { bt_smartbridge_log( "Error creating linked list\n" ); goto error; } result = linked_list_init( &manager->used_list ); - if ( result != AOS_BT_SUCCESS ) { + if ( result != MICO_BT_SUCCESS ) { bt_smartbridge_log( "Error creating linked list\n" ); goto error; } - result = aos_rtos_init_mutex( &manager->mutex ); - if ( result != AOS_BT_SUCCESS ) { + result = mico_rtos_init_mutex( &manager->mutex ); + if ( result != MICO_BT_SUCCESS ) { bt_smartbridge_log( "Error creating mutex\n" ); goto error; } /* Initialise mutexes for protecting access to cached attributes */ for ( a = 0; a < manager->count; a++ ) { - result = aos_rtos_init_mutex( &manager->pool[a].mutex ); - if ( result != AOS_BT_SUCCESS ) { + result = mico_rtos_init_mutex( &manager->pool[a].mutex ); + if ( result != MICO_BT_SUCCESS ) { goto error; } @@ -160,12 +159,12 @@ OSStatus bt_smartbridge_att_cache_enable( uint32_t cache_count, aos_bt_uuid_t ca /* Insert cached attribute instance into free list */ result = linked_list_insert_node_at_rear( &manager->free_list, &manager->pool[a].node ); - if ( result != AOS_BT_SUCCESS ) { + if ( result != MICO_BT_SUCCESS ) { goto error; } } - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; error: bt_smartbridge_att_cache_disable(); @@ -179,32 +178,32 @@ OSStatus bt_smartbridge_att_cache_disable( void ) bt_smartbridge_att_cache_manager_t *manager = att_cache_manager; if ( att_cache_manager == NULL ) { - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } /* Set status at the beginning to prevent cached attributes being used even when deinitialisation failed */ att_cache_manager = NULL; - while ( linked_list_remove_node_from_front( &manager->free_list, &node ) == AOS_BT_SUCCESS ) { + while ( linked_list_remove_node_from_front( &manager->free_list, &node ) == MICO_BT_SUCCESS ) { bt_smartbridge_att_cache_t *cache = (bt_smartbridge_att_cache_t *)node->data; - aos_bt_smart_attribute_delete_list( &cache->attribute_list ); + mico_bt_smart_attribute_delete_list( &cache->attribute_list ); } linked_list_deinit( &manager->free_list ); - while ( linked_list_remove_node_from_front( &manager->used_list, &node ) == AOS_BT_SUCCESS ) { + while ( linked_list_remove_node_from_front( &manager->used_list, &node ) == MICO_BT_SUCCESS ) { bt_smartbridge_att_cache_t *cache = (bt_smartbridge_att_cache_t *)node->data; - aos_bt_smart_attribute_delete_list( &cache->attribute_list ); + mico_bt_smart_attribute_delete_list( &cache->attribute_list ); } linked_list_deinit( &manager->used_list ); - aos_rtos_deinit_mutex( &manager->mutex ); + mico_rtos_deinit_mutex( &manager->mutex ); /* Deinitialise mutexes for protecting access to cached attributes */ for ( a = 0; a < manager->count; a++ ) { - aos_rtos_deinit_mutex( &manager->pool[a].mutex ); + mico_rtos_deinit_mutex( &manager->pool[a].mutex ); } if ( manager->att_cache_services_count != 0 ) { @@ -214,153 +213,154 @@ OSStatus bt_smartbridge_att_cache_disable( void ) memset( manager, 0, CALCULATE_ATT_CACHE_MANAGER_SIZE( manager->count ) ); free( manager ); - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } -OSStatus bt_smartbridge_att_cache_get_list( bt_smartbridge_att_cache_t *cache, aos_bt_smart_attribute_list_t **list ) +OSStatus bt_smartbridge_att_cache_get_list( bt_smartbridge_att_cache_t *cache, mico_bt_smart_attribute_list_t **list ) { if ( cache == NULL || list == NULL ) { - return AOS_BT_BADARG; + return MICO_BT_BADARG; } if ( att_cache_manager == NULL ) { - return AOS_BT_ATT_CACHE_UNINITIALISED; + return MICO_BT_ATT_CACHE_UNINITIALISED; } *list = &cache->attribute_list; - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } -aos_bool_t bt_smartbridge_att_cache_is_enabled( void ) +mico_bool_t bt_smartbridge_att_cache_is_enabled( void ) { - return ( att_cache_manager == NULL ) ? AOS_FALSE : AOS_TRUE; + return ( att_cache_manager == NULL ) ? MICO_FALSE : MICO_TRUE; } -aos_bool_t bt_smartbridge_att_cache_is_discovering( const bt_smartbridge_att_cache_t *cache ) +mico_bool_t bt_smartbridge_att_cache_is_discovering( const bt_smartbridge_att_cache_t *cache ) { if ( cache == NULL || att_cache_manager == NULL ) { - return AOS_FALSE; + return MICO_FALSE; } return cache->is_discovering; } -aos_bool_t bt_smartbridge_att_cache_get_active_state( const bt_smartbridge_att_cache_t *cache ) +mico_bool_t bt_smartbridge_att_cache_get_active_state( const bt_smartbridge_att_cache_t *cache ) { if ( cache == NULL || att_cache_manager == NULL ) { - return AOS_FALSE; + return MICO_FALSE; } return cache->is_active; } -OSStatus bt_smartbridge_att_cache_set_active_state( bt_smartbridge_att_cache_t *cache, aos_bool_t is_active ) +OSStatus bt_smartbridge_att_cache_set_active_state( bt_smartbridge_att_cache_t *cache, mico_bool_t is_active ) { if ( cache == NULL ) { - return AOS_BT_BADARG; + return MICO_BT_BADARG; } if ( att_cache_manager == NULL ) { - return AOS_BT_ATT_CACHE_UNINITIALISED; + return MICO_BT_ATT_CACHE_UNINITIALISED; } cache->is_active = is_active; - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } OSStatus bt_smartbridge_att_cache_lock( bt_smartbridge_att_cache_t *cache ) { if ( cache == NULL ) { - return AOS_BT_BADARG; + return MICO_BT_BADARG; } if ( att_cache_manager == NULL ) { - return AOS_BT_ATT_CACHE_UNINITIALISED; + return MICO_BT_ATT_CACHE_UNINITIALISED; } - return aos_rtos_lock_mutex( &cache->mutex ); + return mico_rtos_lock_mutex( &cache->mutex ); } OSStatus bt_smartbridge_att_cache_unlock( bt_smartbridge_att_cache_t *cache ) { if ( cache == NULL ) { - return AOS_BT_BADARG; + return MICO_BT_BADARG; } if ( att_cache_manager == NULL ) { - return AOS_BT_ATT_CACHE_UNINITIALISED; + return MICO_BT_ATT_CACHE_UNINITIALISED; } - return aos_rtos_unlock_mutex( &cache->mutex ); + return mico_rtos_unlock_mutex( &cache->mutex ); } -OSStatus bt_smartbridge_att_cache_find( const aos_bt_smart_device_t *remote_device, bt_smartbridge_att_cache_t **cache ) +OSStatus bt_smartbridge_att_cache_find( const mico_bt_smart_device_t *remote_device, + bt_smartbridge_att_cache_t **cache ) { OSStatus result; linked_list_node_t *node_found; if ( remote_device == NULL || cache == NULL ) { - return AOS_BT_BADARG; + return MICO_BT_BADARG; } if ( att_cache_manager == NULL ) { - return AOS_BT_ATT_CACHE_UNINITIALISED; + return MICO_BT_ATT_CACHE_UNINITIALISED; } /* Lock protection */ - result = aos_rtos_lock_mutex( &att_cache_manager->mutex ); - if ( result != AOS_BT_SUCCESS ) { + result = mico_rtos_lock_mutex( &att_cache_manager->mutex ); + if ( result != MICO_BT_SUCCESS ) { return result; } result = linked_list_find_node( &att_cache_manager->used_list, smartbridge_att_cache_find_by_device_callback, (void *)remote_device, &node_found ); - if ( result == AOS_BT_SUCCESS ) { + if ( result == MICO_BT_SUCCESS ) { *cache = (bt_smartbridge_att_cache_t *)node_found->data; } /* Unlock protection */ - aos_rtos_unlock_mutex( &att_cache_manager->mutex ); + mico_rtos_unlock_mutex( &att_cache_manager->mutex ); return result; } -OSStatus bt_smartbridge_att_cache_generate( const aos_bt_smart_device_t *remote_device, uint16_t connection_handle, +OSStatus bt_smartbridge_att_cache_generate( const mico_bt_smart_device_t *remote_device, uint16_t connection_handle, bt_smartbridge_att_cache_t **cache ) { bt_smartbridge_att_cache_t *new_cache = NULL; OSStatus result; if ( cache == NULL ) { - return AOS_BT_BADARG; + return MICO_BT_BADARG; } if ( att_cache_manager == NULL ) { - return AOS_BT_ATT_CACHE_UNINITIALISED; + return MICO_BT_ATT_CACHE_UNINITIALISED; } /* Cached attributes not found. Get a free instance and discover services */ result = smartbridge_att_cache_get_free_cache( &new_cache ); - if ( result != AOS_BT_SUCCESS ) { + if ( result != MICO_BT_SUCCESS ) { return result; } /* Copy remote device to cache */ - aos_rtos_lock_mutex( &new_cache->mutex ); + mico_rtos_lock_mutex( &new_cache->mutex ); memcpy( &new_cache->remote_device, remote_device, sizeof( new_cache->remote_device ) ); new_cache->connection_handle = connection_handle; - new_cache->is_discovering = AOS_TRUE; - aos_rtos_unlock_mutex( &new_cache->mutex ); + new_cache->is_discovering = MICO_TRUE; + mico_rtos_unlock_mutex( &new_cache->mutex ); /* Rediscover services */ result = smartbridge_att_cache_discover_all( new_cache, new_cache->connection_handle ); - aos_rtos_lock_mutex( &new_cache->mutex ); - new_cache->is_discovering = AOS_FALSE; - aos_rtos_unlock_mutex( &new_cache->mutex ); + mico_rtos_lock_mutex( &new_cache->mutex ); + new_cache->is_discovering = MICO_FALSE; + mico_rtos_unlock_mutex( &new_cache->mutex ); - if ( result == AOS_BT_SUCCESS ) { + if ( result == MICO_BT_SUCCESS ) { result = smartbridge_att_cache_insert_to_used_list( new_cache ); - if ( result == AOS_BT_SUCCESS ) { + if ( result == MICO_BT_SUCCESS ) { *cache = new_cache; } } else { @@ -376,25 +376,25 @@ OSStatus bt_smartbridge_att_cache_release( bt_smartbridge_att_cache_t *cache ) OSStatus result; if ( att_cache_manager == NULL ) { - return AOS_BT_ATT_CACHE_UNINITIALISED; + return MICO_BT_ATT_CACHE_UNINITIALISED; } /* Lock protection */ - result = aos_rtos_lock_mutex( &att_cache_manager->mutex ); - if ( result != AOS_BT_SUCCESS ) { + result = mico_rtos_lock_mutex( &att_cache_manager->mutex ); + if ( result != MICO_BT_SUCCESS ) { return result; } result = linked_list_remove_node( &att_cache_manager->used_list, &cache->node ); - if ( result == AOS_BT_SUCCESS ) { + if ( result == MICO_BT_SUCCESS ) { /* Delete list and set data to NULL */ - aos_bt_smart_attribute_delete_list( &cache->attribute_list ); + mico_bt_smart_attribute_delete_list( &cache->attribute_list ); } smartbridge_att_cache_return_to_free_list( cache ); /* Unlock protection */ - aos_rtos_unlock_mutex( &att_cache_manager->mutex ); + mico_rtos_unlock_mutex( &att_cache_manager->mutex ); return result; } @@ -406,12 +406,12 @@ static OSStatus smartbridge_att_cache_get_free_cache( bt_smartbridge_att_cache_t linked_list_node_t *node; if ( att_cache_manager == NULL ) { - return AOS_BT_ATT_CACHE_UNINITIALISED; + return MICO_BT_ATT_CACHE_UNINITIALISED; } /* Lock protection */ - result = aos_rtos_lock_mutex( &att_cache_manager->mutex ); - if ( result != oNoErr ) { + result = mico_rtos_lock_mutex( &att_cache_manager->mutex ); + if ( result != kNoErr ) { return result; } @@ -419,25 +419,25 @@ static OSStatus smartbridge_att_cache_get_free_cache( bt_smartbridge_att_cache_t result = linked_list_remove_node_from_front( &att_cache_manager->free_list, &node ); /* Free list is empty. Remove the oldest one from used list */ - if ( result != AOS_BT_SUCCESS ) { + if ( result != MICO_BT_SUCCESS ) { result = linked_list_find_node( &att_cache_manager->used_list, smartbridge_att_cache_get_free_callback, NULL, &node ); - if ( result == AOS_BT_SUCCESS ) { + if ( result == MICO_BT_SUCCESS ) { result = linked_list_remove_node( &att_cache_manager->used_list, node ); - if ( result == AOS_BT_SUCCESS ) { - aos_bt_smart_attribute_list_t *list = (aos_bt_smart_attribute_list_t *)node->data; + if ( result == MICO_BT_SUCCESS ) { + mico_bt_smart_attribute_list_t *list = (mico_bt_smart_attribute_list_t *)node->data; /* Delete list and set data to NULL */ - aos_bt_smart_attribute_delete_list( list ); + mico_bt_smart_attribute_delete_list( list ); } } } - if ( result == AOS_BT_SUCCESS ) { + if ( result == MICO_BT_SUCCESS ) { *free_cache = (bt_smartbridge_att_cache_t *)node->data; } /* Unlock protection */ - aos_rtos_unlock_mutex( &att_cache_manager->mutex ); + mico_rtos_unlock_mutex( &att_cache_manager->mutex ); return result; } @@ -447,19 +447,19 @@ static OSStatus smartbridge_att_cache_insert_to_used_list( bt_smartbridge_att_ca OSStatus result; if ( att_cache_manager == NULL ) { - return AOS_BT_ATT_CACHE_UNINITIALISED; + return MICO_BT_ATT_CACHE_UNINITIALISED; } /* Lock protection */ - result = aos_rtos_lock_mutex( &att_cache_manager->mutex ); - if ( result != AOS_BT_SUCCESS ) { + result = mico_rtos_lock_mutex( &att_cache_manager->mutex ); + if ( result != MICO_BT_SUCCESS ) { return result; } result = linked_list_insert_node_at_rear( &att_cache_manager->used_list, &cache->node ); /* Unlock protection */ - aos_rtos_unlock_mutex( &att_cache_manager->mutex ); + mico_rtos_unlock_mutex( &att_cache_manager->mutex ); return result; } @@ -469,19 +469,19 @@ static OSStatus smartbridge_att_cache_return_to_free_list( bt_smartbridge_att_ca OSStatus result; if ( att_cache_manager == NULL ) { - return AOS_BT_ATT_CACHE_UNINITIALISED; + return MICO_BT_ATT_CACHE_UNINITIALISED; } /* Lock protection */ - result = aos_rtos_lock_mutex( &att_cache_manager->mutex ); - if ( result != AOS_BT_SUCCESS ) { + result = mico_rtos_lock_mutex( &att_cache_manager->mutex ); + if ( result != MICO_BT_SUCCESS ) { return result; } result = linked_list_insert_node_at_rear( &att_cache_manager->free_list, &cache->node ); /* Unlock protection */ - aos_rtos_unlock_mutex( &att_cache_manager->mutex ); + mico_rtos_unlock_mutex( &att_cache_manager->mutex ); return result; } @@ -496,29 +496,29 @@ static OSStatus smartbridge_att_cache_discover_all( bt_smartbridge_att_cache_t * * 5. Characteristic Descriptor Discovery for every Characteristic */ - aos_bt_smart_attribute_t **primary_service_array = NULL; - aos_bt_smart_attribute_t **characteristic_array = NULL; - aos_bt_smart_attribute_t *characteristic_value = NULL; - aos_bt_smart_attribute_t *descriptor_with_no_value = NULL; - aos_bt_smart_attribute_t *descriptor_with_value = NULL; - aos_bt_smart_attribute_t *iterator = NULL; - OSStatus result = AOS_BT_SUCCESS; - OSStatus error_code_var = AOS_BT_ERROR; + mico_bt_smart_attribute_t **primary_service_array = NULL; + mico_bt_smart_attribute_t **characteristic_array = NULL; + mico_bt_smart_attribute_t *characteristic_value = NULL; + mico_bt_smart_attribute_t *descriptor_with_no_value = NULL; + mico_bt_smart_attribute_t *descriptor_with_value = NULL; + mico_bt_smart_attribute_t *iterator = NULL; + OSStatus result = MICO_BT_SUCCESS; + OSStatus error_code_var = MICO_BT_ERROR; uint32_t i = 0; uint32_t j = 0; uint32_t primary_service_count = 0; uint32_t characteristic_count = 0; - aos_bt_smart_attribute_list_t primary_service_list; - aos_bt_smart_attribute_list_t branch_primary_service_list; - aos_bt_smart_attribute_list_t included_service_list; - aos_bt_smart_attribute_list_t characteristic_list; - aos_bt_smart_attribute_list_t descriptor_list; + mico_bt_smart_attribute_list_t primary_service_list; + mico_bt_smart_attribute_list_t branch_primary_service_list; + mico_bt_smart_attribute_list_t included_service_list; + mico_bt_smart_attribute_list_t characteristic_list; + mico_bt_smart_attribute_list_t descriptor_list; - aos_bool_t characteristic_list_merged = AOS_FALSE; - aos_bool_t included_service_list_merged = AOS_FALSE; + mico_bool_t characteristic_list_merged = MICO_FALSE; + mico_bool_t included_service_list_merged = MICO_FALSE; if ( att_cache_manager == NULL ) { - return AOS_BT_ATT_CACHE_UNINITIALISED; + return MICO_BT_ATT_CACHE_UNINITIALISED; } /* Initialise local variables */ @@ -528,39 +528,39 @@ static OSStatus smartbridge_att_cache_discover_all( bt_smartbridge_att_cache_t * memset( &characteristic_list, 0, sizeof( characteristic_list ) ); memset( &descriptor_list, 0, sizeof( descriptor_list ) ); - aos_rtos_lock_mutex( &cache->mutex ); + mico_rtos_lock_mutex( &cache->mutex ); - result = aos_bt_smart_attribute_create_list( &primary_service_list ); + result = mico_bt_smart_attribute_create_list( &primary_service_list ); - aos_rtos_unlock_mutex( &cache->mutex ); + mico_rtos_unlock_mutex( &cache->mutex ); - CHECK_FOR_ERROR( result != AOS_BT_SUCCESS, result ); + CHECK_FOR_ERROR( result != MICO_BT_SUCCESS, result ); /************************************************************************** * Primary Services Discovery **************************************************************************/ if ( att_cache_manager->att_cache_services_count == 0 ) { result = smartbridge_bt_interface_discover_all_primary_services( connection_handle, &primary_service_list ); - CHECK_FOR_ERROR( result != AOS_BT_SUCCESS, result ); + CHECK_FOR_ERROR( result != MICO_BT_SUCCESS, result ); } else { for ( i = 0; i < att_cache_manager->att_cache_services_count; i++ ) { result = smartbridge_bt_interface_discover_primary_services_by_uuid( connection_handle, &att_cache_manager->att_cache_services[i], &branch_primary_service_list ); - CHECK_FOR_ERROR( result != AOS_BT_SUCCESS, result ); - result = aos_bt_smart_attribute_merge_lists( &primary_service_list, &branch_primary_service_list ); - CHECK_FOR_ERROR( result != AOS_BT_SUCCESS, result ); + CHECK_FOR_ERROR( result != MICO_BT_SUCCESS, result ); + result = mico_bt_smart_attribute_merge_lists( &primary_service_list, &branch_primary_service_list ); + CHECK_FOR_ERROR( result != MICO_BT_SUCCESS, result ); } } - aos_bt_smart_attribute_get_list_count( &primary_service_list, &primary_service_count ); + mico_bt_smart_attribute_get_list_count( &primary_service_list, &primary_service_count ); - primary_service_array = (aos_bt_smart_attribute_t **)malloc_named( "svc_array", - primary_service_count * sizeof(aos_bt_smart_attribute_t)); + primary_service_array = (mico_bt_smart_attribute_t **)malloc_named( "svc_array", + primary_service_count * sizeof(mico_bt_smart_attribute_t)); - CHECK_FOR_ERROR( primary_service_array == NULL, AOS_BT_OUT_OF_HEAP_SPACE ); + CHECK_FOR_ERROR( primary_service_array == NULL, MICO_BT_OUT_OF_HEAP_SPACE ); /* Keep the original pointers to the primary service list before the list gets merged */ - aos_bt_smart_attribute_get_list_head( &primary_service_list, &iterator ); + mico_bt_smart_attribute_get_list_head( &primary_service_list, &iterator ); for ( i = 0; i < primary_service_count; i++ ) { primary_service_array[i] = iterator; @@ -581,20 +581,20 @@ static OSStatus smartbridge_att_cache_discover_all( bt_smartbridge_att_cache_t * **********************************************************************/ /*result = bt_smart_gatt_find_included_services( connection_handle, primary_service_array[i]->value.service.start_handle, primary_service_array[i]->value.service.start_handle, &included_service_list ); - CHECK_FOR_ERROR( result == AOS_BT_GATT_TIMEOUT, result ); + CHECK_FOR_ERROR( result == MICO_BT_GATT_TIMEOUT, result ); - aos_rtos_lock_mutex( &cache->mutex ); + mico_rtos_lock_mutex( &cache->mutex ); - result = aos_bt_smart_attribute_merge_lists( &primary_service_list, &included_service_list ); + result = mico_bt_smart_attribute_merge_lists( &primary_service_list, &included_service_list ); - if( result == AOS_BT_SUCCES ) + if( result == MICO_BT_SUCCES ) { - included_service_list_merged = AOS_TRUE; + included_service_list_merged = MICO_TRUE; } - aos_rtos_unlock_mutex( &cache->mutex ); + mico_rtos_unlock_mutex( &cache->mutex ); - CHECK_FOR_ERROR( result != AOS_BT_SUCCESS, result ); + CHECK_FOR_ERROR( result != MICO_BT_SUCCESS, result ); */ /********************************************************************** @@ -604,18 +604,18 @@ static OSStatus smartbridge_att_cache_discover_all( bt_smartbridge_att_cache_t * primary_service_array[i]->value.service.start_handle, primary_service_array[i]->value.service.end_handle, &characteristic_list ); - CHECK_FOR_ERROR( result == AOS_BT_GATT_TIMEOUT || result == AOS_BT_TIMEOUT, result ); + CHECK_FOR_ERROR( result == MICO_BT_GATT_TIMEOUT || result == MICO_BT_TIMEOUT, result ); - aos_bt_smart_attribute_get_list_count( &characteristic_list, &characteristic_count ); + mico_bt_smart_attribute_get_list_count( &characteristic_list, &characteristic_count ); - characteristic_array = (aos_bt_smart_attribute_t **)malloc_named( "char_array", - characteristic_count * sizeof(characteristic_list)); + characteristic_array = (mico_bt_smart_attribute_t **)malloc_named( "char_array", + characteristic_count * sizeof(characteristic_list)); - CHECK_FOR_ERROR( characteristic_array == NULL, AOS_BT_OUT_OF_HEAP_SPACE ); + CHECK_FOR_ERROR( characteristic_array == NULL, MICO_BT_OUT_OF_HEAP_SPACE ); /* Keep the original pointers to the characteristic list before the list gets merged. */ - aos_bt_smart_attribute_get_list_head( &characteristic_list, &iterator ); + mico_bt_smart_attribute_get_list_head( &characteristic_list, &iterator ); for ( j = 0; j < characteristic_count; j++ ) { characteristic_array[j] = iterator; @@ -638,35 +638,35 @@ static OSStatus smartbridge_att_cache_discover_all( bt_smartbridge_att_cache_t * characteristic_array[j]->value.characteristic.value_handle, &characteristic_array[j]->value.characteristic.uuid, &characteristic_value ); - CHECK_FOR_ERROR( result == AOS_BT_GATT_TIMEOUT || result == AOS_BT_TIMEOUT, result ); + CHECK_FOR_ERROR( result == MICO_BT_GATT_TIMEOUT || result == MICO_BT_TIMEOUT, result ); } else { bt_smartbridge_log( "[Cache] Characteristic Read-Properties is NOT set" ); /* Failed to read. Let's enter a control-point attribute (dummy) here so when notification come, UUID is known. */ - result = aos_bt_smart_attribute_create( &characteristic_value, AOS_ATTRIBUTE_TYPE_NO_VALUE, 0 ); + result = mico_bt_smart_attribute_create( &characteristic_value, MICO_ATTRIBUTE_TYPE_NO_VALUE, 0 ); - if ( result == AOS_BT_SUCCESS ) { + if ( result == MICO_BT_SUCCESS ) { characteristic_value->handle = characteristic_array[j]->value.characteristic.value_handle; characteristic_value->type = characteristic_array[j]->value.characteristic.uuid; } - CHECK_FOR_ERROR( result != AOS_BT_SUCCESS, result ); + CHECK_FOR_ERROR( result != MICO_BT_SUCCESS, result ); } if ( characteristic_value != NULL ) { /* Add Characteristic Value to main list */ - aos_rtos_lock_mutex( &cache->mutex ); + mico_rtos_lock_mutex( &cache->mutex ); /* Add characteristic_value to main list */ - result = aos_bt_smart_attribute_add_to_list( &primary_service_list, characteristic_value ); + result = mico_bt_smart_attribute_add_to_list( &primary_service_list, characteristic_value ); /* Merge success, it will be deleted by primary_service_list when error */ - if ( result == AOS_BT_SUCCESS ) { + if ( result == MICO_BT_SUCCESS ) { characteristic_value = NULL; } - aos_rtos_unlock_mutex( &cache->mutex ); + mico_rtos_unlock_mutex( &cache->mutex ); - CHECK_FOR_ERROR( result != AOS_BT_SUCCESS, result ); + CHECK_FOR_ERROR( result != MICO_BT_SUCCESS, result ); } /****************************************************************** * Characteristic Descriptor Discovery @@ -695,9 +695,9 @@ static OSStatus smartbridge_att_cache_discover_all( bt_smartbridge_att_cache_t * characteristic_array[j]->value.characteristic.descriptor_start_handle, characteristic_array[j]->value.characteristic.descriptor_end_handle, &descriptor_list ); - CHECK_FOR_ERROR( result == AOS_BT_GATT_TIMEOUT || result == AOS_BT_TIMEOUT, result ); + CHECK_FOR_ERROR( result == MICO_BT_GATT_TIMEOUT || result == MICO_BT_TIMEOUT, result ); - aos_bt_smart_attribute_get_list_head( &descriptor_list, &descriptor_with_no_value ); + mico_bt_smart_attribute_get_list_head( &descriptor_list, &descriptor_with_no_value ); /* Traverse through all descriptors */ while ( descriptor_with_no_value != NULL ) { @@ -707,40 +707,40 @@ static OSStatus smartbridge_att_cache_discover_all( bt_smartbridge_att_cache_t * result = smartbridge_bt_interface_read_characteristic_descriptor( connection_handle, descriptor_with_no_value->handle, &descriptor_with_no_value->type, &descriptor_with_value ); - CHECK_FOR_ERROR( result == AOS_BT_GATT_TIMEOUT || result == AOS_BT_TIMEOUT, result ); + CHECK_FOR_ERROR( result == MICO_BT_GATT_TIMEOUT || result == MICO_BT_TIMEOUT, result ); /* Add Descriptor with Value to main list */ - result = aos_bt_smart_attribute_add_to_list( &primary_service_list, descriptor_with_value ); + result = mico_bt_smart_attribute_add_to_list( &primary_service_list, descriptor_with_value ); /* Merge success, it will be deleted by primary_service_list when error */ - if ( result == AOS_BT_SUCCESS ) { + if ( result == MICO_BT_SUCCESS ) { descriptor_with_value = NULL; } - CHECK_FOR_ERROR( result != AOS_BT_SUCCESS, result ); + CHECK_FOR_ERROR( result != MICO_BT_SUCCESS, result ); descriptor_with_no_value = descriptor_with_no_value->next; } /* Delete the empty descriptor list */ - result = aos_bt_smart_attribute_delete_list( &descriptor_list ); + result = mico_bt_smart_attribute_delete_list( &descriptor_list ); - CHECK_FOR_ERROR( result != AOS_BT_SUCCESS, result ); + CHECK_FOR_ERROR( result != MICO_BT_SUCCESS, result ); } } /* Merge Characteristics to main list */ - aos_rtos_lock_mutex( &cache->mutex ); + mico_rtos_lock_mutex( &cache->mutex ); - result = aos_bt_smart_attribute_merge_lists( &primary_service_list, &characteristic_list ); + result = mico_bt_smart_attribute_merge_lists( &primary_service_list, &characteristic_list ); - if ( result == AOS_BT_SUCCESS ) { - characteristic_list_merged = AOS_TRUE; + if ( result == MICO_BT_SUCCESS ) { + characteristic_list_merged = MICO_TRUE; } - aos_rtos_unlock_mutex( &cache->mutex ); + mico_rtos_unlock_mutex( &cache->mutex ); - CHECK_FOR_ERROR( result != AOS_BT_SUCCESS, result ); + CHECK_FOR_ERROR( result != MICO_BT_SUCCESS, result ); /* Free primary service array */ free( characteristic_array ); @@ -752,9 +752,9 @@ static OSStatus smartbridge_att_cache_discover_all( bt_smartbridge_att_cache_t * /* Successful. Now copy the primary service list to the cached attributes list */ memcpy( &cache->attribute_list, &primary_service_list, sizeof( cache->attribute_list ) ); - //aos_bt_smart_attribute_print_list( &(cache->attribute_list) ); + //mico_bt_smart_attribute_print_list( &(cache->attribute_list) ); - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; error: @@ -762,11 +762,11 @@ static OSStatus smartbridge_att_cache_discover_all( bt_smartbridge_att_cache_t * /* Delete all local attributes */ if ( descriptor_with_value != NULL ) { - aos_bt_smart_attribute_delete( descriptor_with_value ); + mico_bt_smart_attribute_delete( descriptor_with_value ); } if ( characteristic_value != NULL ) { - aos_bt_smart_attribute_delete( characteristic_value ); + mico_bt_smart_attribute_delete( characteristic_value ); } if ( characteristic_array != NULL ) { @@ -777,16 +777,16 @@ static OSStatus smartbridge_att_cache_discover_all( bt_smartbridge_att_cache_t * free( primary_service_array ); } - if ( characteristic_list_merged == AOS_FALSE ) { - aos_bt_smart_attribute_delete_list( &characteristic_list ); + if ( characteristic_list_merged == MICO_FALSE ) { + mico_bt_smart_attribute_delete_list( &characteristic_list ); } - if ( included_service_list_merged == AOS_FALSE ) { - aos_bt_smart_attribute_delete_list( &included_service_list ); + if ( included_service_list_merged == MICO_FALSE ) { + mico_bt_smart_attribute_delete_list( &included_service_list ); } - aos_bt_smart_attribute_delete_list( &descriptor_list ); - aos_bt_smart_attribute_delete_list( &primary_service_list ); + mico_bt_smart_attribute_delete_list( &descriptor_list ); + mico_bt_smart_attribute_delete_list( &primary_service_list ); /* Return the error code to the caller */ return error_code_var; @@ -795,7 +795,7 @@ static OSStatus smartbridge_att_cache_discover_all( bt_smartbridge_att_cache_t * static bool smartbridge_att_cache_find_by_device_callback( linked_list_node_t *node_to_compare, void *user_data ) { bt_smartbridge_att_cache_t *cached_attributes = (bt_smartbridge_att_cache_t *)node_to_compare->data; - aos_bt_smart_device_t *remote_device = (aos_bt_smart_device_t *)user_data; + mico_bt_smart_device_t *remote_device = (mico_bt_smart_device_t *)user_data; return ( ( memcmp( cached_attributes->remote_device.address, remote_device->address, sizeof( remote_device->address ) ) == 0 ) && @@ -806,5 +806,5 @@ static bool smartbridge_att_cache_get_free_callback( linked_list_node_t *node_ { bt_smartbridge_att_cache_t *cache = (bt_smartbridge_att_cache_t *)node_to_compare->data; - return ( cache->is_active == AOS_FALSE ) ? true : false; + return ( cache->is_active == MICO_FALSE ) ? true : false; } diff --git a/framework/bluetooth/smartbt/internal/bt_smartbridge_att_cache_manager.h b/device/bluetooth/mk3239/bt_smart/internal/bt_smartbridge_att_cache_manager.h similarity index 72% rename from framework/bluetooth/smartbt/internal/bt_smartbridge_att_cache_manager.h rename to device/bluetooth/mk3239/bt_smart/internal/bt_smartbridge_att_cache_manager.h index 56a5d9097c..7ec7f85813 100644 --- a/framework/bluetooth/smartbt/internal/bt_smartbridge_att_cache_manager.h +++ b/device/bluetooth/mk3239/bt_smart/internal/bt_smartbridge_att_cache_manager.h @@ -1,13 +1,7 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#ifndef _BT_SMART_BRIDGE_ATT_MANAGER_H_ -#define _BT_SMART_BRIDGE_ATT_MANAGER_H_ - #pragma once -#include "smartbt_smart_interface.h" +//#include "mico_utilities.h" +#include "mico_bt_smart_interface.h" #include "bt_smartbridge_att_cache_manager.h" #ifdef __cplusplus @@ -46,28 +40,28 @@ typedef struct bt_smartbridge_att_cache bt_smartbridge_att_cache_t; * Function Declarations ******************************************************/ -OSStatus bt_smartbridge_att_cache_enable( uint32_t cache_count, aos_bt_uuid_t cache_services[], +OSStatus bt_smartbridge_att_cache_enable( uint32_t cache_count, mico_bt_uuid_t cache_services[], uint32_t service_count ); OSStatus bt_smartbridge_att_cache_disable( void ); -aos_bool_t bt_smartbridge_att_cache_is_enabled( void ); +mico_bool_t bt_smartbridge_att_cache_is_enabled( void ); -aos_bool_t bt_smartbridge_att_cache_is_discovering( const bt_smartbridge_att_cache_t *cache ); +mico_bool_t bt_smartbridge_att_cache_is_discovering( const bt_smartbridge_att_cache_t *cache ); -aos_bool_t bt_smartbridge_att_cache_get_active_state( const bt_smartbridge_att_cache_t *cache ); +mico_bool_t bt_smartbridge_att_cache_get_active_state( const bt_smartbridge_att_cache_t *cache ); -OSStatus bt_smartbridge_att_cache_set_active_state( bt_smartbridge_att_cache_t *cache, aos_bool_t is_active ); +OSStatus bt_smartbridge_att_cache_set_active_state( bt_smartbridge_att_cache_t *cache, mico_bool_t is_active ); -OSStatus bt_smartbridge_att_cache_find( const aos_bt_smart_device_t *remote_device, +OSStatus bt_smartbridge_att_cache_find( const mico_bt_smart_device_t *remote_device, bt_smartbridge_att_cache_t **cache ); -OSStatus bt_smartbridge_att_cache_generate( const aos_bt_smart_device_t *remote_device, uint16_t connection_handle, +OSStatus bt_smartbridge_att_cache_generate( const mico_bt_smart_device_t *remote_device, uint16_t connection_handle, bt_smartbridge_att_cache_t **cache ); OSStatus bt_smartbridge_att_cache_release( bt_smartbridge_att_cache_t *cache ); -OSStatus bt_smartbridge_att_cache_get_list( bt_smartbridge_att_cache_t *cache, aos_bt_smart_attribute_list_t **list ); +OSStatus bt_smartbridge_att_cache_get_list( bt_smartbridge_att_cache_t *cache, mico_bt_smart_attribute_list_t **list ); OSStatus bt_smartbridge_att_cache_lock( bt_smartbridge_att_cache_t *cache ); @@ -76,5 +70,3 @@ OSStatus bt_smartbridge_att_cache_unlock( bt_smartbridge_att_cache_t *cache ); #ifdef __cplusplus } /* extern "C" */ #endif - -#endif diff --git a/framework/bluetooth/smartbt/internal/bt_smartbridge_helper.c b/device/bluetooth/mk3239/bt_smart/internal/bt_smartbridge_helper.c similarity index 59% rename from framework/bluetooth/smartbt/internal/bt_smartbridge_helper.c rename to device/bluetooth/mk3239/bt_smart/internal/bt_smartbridge_helper.c index ff8adc4657..ac7859c76d 100644 --- a/framework/bluetooth/smartbt/internal/bt_smartbridge_helper.c +++ b/device/bluetooth/mk3239/bt_smart/internal/bt_smartbridge_helper.c @@ -1,16 +1,14 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ /** @file * */ -#include "smartbt_smartbridge.h" -#include "smartbt_peripheral.h" +#include "mico.h" +#include "mico_bt_smartbridge.h" +#include "mico_bt_peripheral.h" -#include "aos_bt_gatt.h" -#include "aos_bt_ble.h" -#include "smartbt_cfg.h" +#include "mico_bt_gatt.h" +#include "mico_bt_ble.h" +#include "mico_bt_cfg.h" #include "bt_smartbridge_socket_manager.h" #include "bt_smartbridge_att_cache_manager.h" @@ -47,32 +45,32 @@ * Variable Definitions ******************************************************/ -static aos_bt_smart_scan_result_t *scan_result_head = NULL; -static aos_bt_smart_scan_result_t *scan_result_tail = NULL; +static mico_bt_smart_scan_result_t *scan_result_head = NULL; +static mico_bt_smart_scan_result_t *scan_result_tail = NULL; static uint32_t scan_result_count = 0; /****************************************************** * Function Definitions ******************************************************/ -OSStatus smartbridge_helper_get_scan_results( aos_bt_smart_scan_result_t **result_list, uint32_t *count ) +OSStatus smartbridge_helper_get_scan_results( mico_bt_smart_scan_result_t **result_list, uint32_t *count ) { - if ( smartbridge_bt_interface_is_scanning() == AOS_TRUE ) { + if ( smartbridge_bt_interface_is_scanning() == MICO_TRUE ) { bt_smartbridge_log("Can't Fetch Scan-Results [ Scan in-progress ? ]"); - return AOS_BT_SCAN_IN_PROGRESS; + return MICO_BT_SCAN_IN_PROGRESS; } *result_list = scan_result_head; *count = scan_result_count; - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } OSStatus smartbridge_helper_delete_scan_result_list( void ) { - aos_bt_smart_scan_result_t *curr; + mico_bt_smart_scan_result_t *curr; if ( scan_result_count == 0 ) { - return AOS_BT_LIST_EMPTY; + return MICO_BT_LIST_EMPTY; } curr = scan_result_head; @@ -80,7 +78,7 @@ OSStatus smartbridge_helper_delete_scan_result_list( void ) /* Traverse through the list and delete all attributes */ while ( curr != NULL ) { /* Store pointer to next because curr is about to be deleted */ - aos_bt_smart_scan_result_t *next = curr->next; + mico_bt_smart_scan_result_t *next = curr->next; /* Detach result from the list and free memory */ curr->next = NULL; @@ -93,10 +91,10 @@ OSStatus smartbridge_helper_delete_scan_result_list( void ) scan_result_count = 0; scan_result_head = NULL; scan_result_tail = NULL; - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } -OSStatus smartbridge_helper_add_scan_result_to_list( aos_bt_smart_scan_result_t *result ) +OSStatus smartbridge_helper_add_scan_result_to_list( mico_bt_smart_scan_result_t *result ) { if ( scan_result_count == 0 ) { scan_result_head = result; @@ -110,67 +108,68 @@ OSStatus smartbridge_helper_add_scan_result_to_list( aos_bt_smart_scan_result_t //bt_smartbridge_log("New scan-result-count:%d", (int)scan_result_count); result->next = NULL; - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } -OSStatus smartbridge_helper_find_device_in_scan_result_list( aos_bt_device_address_t *address, - aos_bt_smart_address_type_t type, aos_bt_smart_scan_result_t **result ) +OSStatus smartbridge_helper_find_device_in_scan_result_list( mico_bt_device_address_t *address, + mico_bt_smart_address_type_t type, mico_bt_smart_scan_result_t **result ) { - aos_bt_smart_scan_result_t *iterator = scan_result_head; + mico_bt_smart_scan_result_t *iterator = scan_result_head; while ( iterator != NULL ) { if ( ( memcmp( &iterator->remote_device.address, address, sizeof( *address ) ) == 0 ) && ( iterator->remote_device.address_type == type ) ) { *result = iterator; - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } iterator = iterator->next; } - return AOS_BT_ITEM_NOT_IN_LIST; + return MICO_BT_ITEM_NOT_IN_LIST; } /****************************************************** * Socket Action Helper Functions ******************************************************/ -aos_bool_t smartbridge_helper_socket_check_actions_enabled( aos_bt_smartbridge_socket_t *socket, uint8_t action_bits ) +mico_bool_t smartbridge_helper_socket_check_actions_enabled( mico_bt_smartbridge_socket_t *socket, uint8_t action_bits ) { - return ( ( socket->actions & action_bits ) == action_bits ) ? AOS_TRUE : AOS_FALSE; + return ( ( socket->actions & action_bits ) == action_bits ) ? MICO_TRUE : MICO_FALSE; } -aos_bool_t smartbridge_helper_socket_check_actions_disabled( aos_bt_smartbridge_socket_t *socket, uint8_t action_bits ) +mico_bool_t smartbridge_helper_socket_check_actions_disabled( mico_bt_smartbridge_socket_t *socket, + uint8_t action_bits ) { - return ( ( socket->actions | ~action_bits ) == ~action_bits ) ? AOS_TRUE : AOS_FALSE; + return ( ( socket->actions | ~action_bits ) == ~action_bits ) ? MICO_TRUE : MICO_FALSE; } -void smartbridge_helper_socket_set_actions( aos_bt_smartbridge_socket_t *socket, uint8_t action_bits ) +void smartbridge_helper_socket_set_actions( mico_bt_smartbridge_socket_t *socket, uint8_t action_bits ) { socket->actions |= action_bits; } -void smartbridge_helper_socket_clear_actions( aos_bt_smartbridge_socket_t *socket, uint8_t action_bits ) +void smartbridge_helper_socket_clear_actions( mico_bt_smartbridge_socket_t *socket, uint8_t action_bits ) { socket->actions &= ~action_bits; } -aos_bool_t peripheral_helper_socket_check_actions_enabled( aos_bt_peripheral_socket_t *socket, uint8_t action_bits ) +mico_bool_t peripheral_helper_socket_check_actions_enabled( mico_bt_peripheral_socket_t *socket, uint8_t action_bits ) { - return ( ( socket->actions & action_bits ) == action_bits ) ? AOS_TRUE : AOS_FALSE; + return ( ( socket->actions & action_bits ) == action_bits ) ? MICO_TRUE : MICO_FALSE; } -aos_bool_t peripheral_helper_socket_check_actions_disabled( aos_bt_peripheral_socket_t *socket, uint8_t action_bits ) +mico_bool_t peripheral_helper_socket_check_actions_disabled( mico_bt_peripheral_socket_t *socket, uint8_t action_bits ) { - return ( ( socket->actions | ~action_bits ) == ~action_bits ) ? AOS_TRUE : AOS_FALSE; + return ( ( socket->actions | ~action_bits ) == ~action_bits ) ? MICO_TRUE : MICO_FALSE; } -void peripheral_helper_socket_set_actions( aos_bt_peripheral_socket_t *socket, uint8_t action_bits ) +void peripheral_helper_socket_set_actions( mico_bt_peripheral_socket_t *socket, uint8_t action_bits ) { socket->actions |= action_bits; } -void peripheral_helper_socket_clear_actions( aos_bt_peripheral_socket_t *socket, uint8_t action_bits ) +void peripheral_helper_socket_clear_actions( mico_bt_peripheral_socket_t *socket, uint8_t action_bits ) { socket->actions &= ~action_bits; } @@ -183,12 +182,12 @@ void peripheral_helper_socket_clear_actions( aos_bt_peripheral_socket_t *socket, OSStatus subprocedure_lock( gatt_subprocedure_t *subprocedure ) { - return aos_rtos_lock_mutex( &subprocedure->mutex ); + return mico_rtos_lock_mutex( &subprocedure->mutex ); } OSStatus subprocedure_unlock( gatt_subprocedure_t *subprocedure ) { - return aos_rtos_unlock_mutex( &subprocedure->mutex ); + return mico_rtos_unlock_mutex( &subprocedure->mutex ); } OSStatus subprocedure_reset( gatt_subprocedure_t *subprocedure ) @@ -197,7 +196,7 @@ OSStatus subprocedure_reset( gatt_subprocedure_t *subprocedure ) subprocedure->attr_head = NULL; subprocedure->attr_tail = NULL; subprocedure->attr_count = 0; - subprocedure->result = AOS_BT_SUCCESS; + subprocedure->result = MICO_BT_SUCCESS; subprocedure->start_handle = 0; subprocedure->end_handle = 0; //subprocedure.pdu = 0; @@ -206,27 +205,27 @@ OSStatus subprocedure_reset( gatt_subprocedure_t *subprocedure ) subprocedure->connection_handle = 0; memset( &subprocedure->uuid, 0, sizeof( subprocedure->uuid ) ); subprocedure_wait_clear_semaphore( subprocedure ); - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } OSStatus subprocedure_wait_for_completion( gatt_subprocedure_t *subprocedure ) { - if ( oNoErr != aos_rtos_get_semaphore( &subprocedure->done_semaphore, GATT_MAX_PROCEDURE_TIMEOUT ) ) { - subprocedure->result = AOS_BT_TIMEOUT; + if ( kNoErr != mico_rtos_get_semaphore( &subprocedure->done_semaphore, GATT_MAX_PROCEDURE_TIMEOUT ) ) { + subprocedure->result = MICO_BT_TIMEOUT; } return subprocedure->result; } OSStatus subprocedure_wait_clear_semaphore( gatt_subprocedure_t *subprocedure ) { - while ( aos_rtos_get_semaphore( &subprocedure->done_semaphore, AOS_NO_WAIT ) == oNoErr ) { + while ( mico_rtos_get_semaphore( &subprocedure->done_semaphore, MICO_NO_WAIT ) == kNoErr ) { } - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } OSStatus subprocedure_notify_complete( gatt_subprocedure_t *subprocedure ) { - return aos_rtos_set_semaphore( &subprocedure->done_semaphore ); + return mico_rtos_set_semaphore( &subprocedure->done_semaphore ); } /****************************************************** @@ -246,62 +245,62 @@ static void smartbridge_helper_timer_handler(void *arg) /* Reload if not one-shot timer. */ if (timer->is_started && !timer->one_shot) { bt_smartbridge_log("smartbridge timer reload"); - aos_rtos_reload_timer(&timer->timer); + mico_rtos_reload_timer(&timer->timer); } } /* This function is used to stop a active timer. - * return AOS_TRUE if successful, otherwise, return AOS_FALSE. + * return MICO_TRUE if successful, otherwise, return MICO_FALSE. */ -aos_bool_t smartbridge_helper_timer_stop(smartbridge_helper_timer_t *timer) +mico_bool_t smartbridge_helper_timer_stop(smartbridge_helper_timer_t *timer) { if (timer == (void *)0) { - return AOS_FALSE; + return MICO_FALSE; } if (!timer->is_started) { - return AOS_FALSE; + return MICO_FALSE; } - if (aos_rtos_is_timer_running(&timer->timer)) { - aos_rtos_stop_timer(&timer->timer); + if (mico_rtos_is_timer_running(&timer->timer)) { + mico_rtos_stop_timer(&timer->timer); } - aos_rtos_deinit_timer(&timer->timer); + mico_rtos_deinit_timer(&timer->timer); - timer->is_started = AOS_FALSE; - timer->one_shot = AOS_FALSE; + timer->is_started = MICO_FALSE; + timer->one_shot = MICO_FALSE; - return AOS_TRUE; + return MICO_TRUE; } /* This function is used to start or restart a timer. * The 'timer' will be restarted if it is active. */ -aos_bool_t smartbridge_helper_timer_start(smartbridge_helper_timer_t *timer, aos_bool_t one_shot, uint32_t ms, - timer_handler_t handler, void *arg) +mico_bool_t smartbridge_helper_timer_start(smartbridge_helper_timer_t *timer, mico_bool_t one_shot, uint32_t ms, + timer_handler_t handler, void *arg) { if (timer == (void *)0) { - return AOS_FALSE; + return MICO_FALSE; } if (timer->is_started) { smartbridge_helper_timer_stop(timer); } - if (aos_rtos_init_timer(&timer->timer, ms, smartbridge_helper_timer_handler, (void *)timer) != oNoErr) { - return AOS_FALSE; + if (mico_rtos_init_timer(&timer->timer, ms, smartbridge_helper_timer_handler, (void *)timer) != kNoErr) { + return MICO_FALSE; } - if (aos_rtos_start_timer(&timer->timer) != oNoErr) { - aos_rtos_deinit_timer(&timer->timer); - return AOS_FALSE; + if (mico_rtos_start_timer(&timer->timer) != kNoErr) { + mico_rtos_deinit_timer(&timer->timer); + return MICO_FALSE; } - timer->is_started = AOS_TRUE; + timer->is_started = MICO_TRUE; timer->one_shot = one_shot; timer->handler = handler; timer->context = arg; - return AOS_TRUE; + return MICO_TRUE; } diff --git a/framework/bluetooth/smartbt/internal/bt_smartbridge_helper.h b/device/bluetooth/mk3239/bt_smart/internal/bt_smartbridge_helper.h similarity index 80% rename from framework/bluetooth/smartbt/internal/bt_smartbridge_helper.h rename to device/bluetooth/mk3239/bt_smart/internal/bt_smartbridge_helper.h index 98ad0b68cb..7dc08bdcdd 100644 --- a/framework/bluetooth/smartbt/internal/bt_smartbridge_helper.h +++ b/device/bluetooth/mk3239/bt_smart/internal/bt_smartbridge_helper.h @@ -1,20 +1,14 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#ifndef _BT_SMART_BRIDGE_HELPER_H_ -#define _BT_SMART_BRIDGE_HELPER_H_ - #pragma once /** @file * Smartbridge's Helper Function Headers */ -#include "smartbt_smartbridge.h" -#include "smartbt_smart_interface.h" +//#include "mico_utilities.h" +#include "mico_bt_smartbridge.h" +#include "mico_bt_smart_interface.h" -#include "smartbt_peripheral.h" +#include "mico_bt_peripheral.h" #ifdef __cplusplus extern "C" { @@ -88,12 +82,12 @@ typedef enum { typedef struct { bt_smart_gatt_subprocedure_t subprocedure; - aos_mutex_t mutex; - aos_semaphore_t done_semaphore; + mico_mutex_t mutex; + mico_semaphore_t done_semaphore; OSStatus result; - aos_bt_uuid_t uuid; - aos_bt_smart_attribute_t *attr_head; - aos_bt_smart_attribute_t *attr_tail; + mico_bt_uuid_t uuid; + mico_bt_smart_attribute_t *attr_head; + mico_bt_smart_attribute_t *attr_tail; uint32_t attr_count; uint16_t server_mtu; uint16_t start_handle; @@ -105,9 +99,9 @@ typedef struct { } gatt_subprocedure_t; typedef struct { - aos_bt_timer_t timer; // AOS timer object - aos_bool_t is_started; // is it started? - aos_bool_t one_shot; // one-shot? + mico_timer_t timer; // MiCO timer object + mico_bool_t is_started; // is it started? + mico_bool_t one_shot; // one-shot? timer_handler_t handler; // timer expired handler void *context; // user context } smartbridge_helper_timer_t; @@ -120,30 +114,30 @@ typedef struct { ******************************************************/ OSStatus smartbridge_helper_delete_scan_result_list ( void ); -OSStatus smartbridge_helper_add_scan_result_to_list ( aos_bt_smart_scan_result_t *result ); -OSStatus smartbridge_helper_find_device_in_scan_result_list ( aos_bt_device_address_t *address, - aos_bt_smart_address_type_t type, aos_bt_smart_scan_result_t **result ); -OSStatus smartbridge_helper_get_scan_results ( aos_bt_smart_scan_result_t **result_list, +OSStatus smartbridge_helper_add_scan_result_to_list ( mico_bt_smart_scan_result_t *result ); +OSStatus smartbridge_helper_find_device_in_scan_result_list ( mico_bt_device_address_t *address, + mico_bt_smart_address_type_t type, mico_bt_smart_scan_result_t **result ); +OSStatus smartbridge_helper_get_scan_results ( mico_bt_smart_scan_result_t **result_list, uint32_t *count ); -aos_bool_t smartbridge_helper_socket_check_actions_enabled ( aos_bt_smartbridge_socket_t *socket, - uint8_t action_bits ); -aos_bool_t smartbridge_helper_socket_check_actions_disabled ( aos_bt_smartbridge_socket_t *socket, - uint8_t action_bits ); -void smartbridge_helper_socket_set_actions ( aos_bt_smartbridge_socket_t *socket, +mico_bool_t smartbridge_helper_socket_check_actions_enabled ( mico_bt_smartbridge_socket_t *socket, + uint8_t action_bits ); +mico_bool_t smartbridge_helper_socket_check_actions_disabled ( mico_bt_smartbridge_socket_t *socket, + uint8_t action_bits ); +void smartbridge_helper_socket_set_actions ( mico_bt_smartbridge_socket_t *socket, uint8_t action_bits ); -void smartbridge_helper_socket_clear_actions ( aos_bt_smartbridge_socket_t *socket, +void smartbridge_helper_socket_clear_actions ( mico_bt_smartbridge_socket_t *socket, uint8_t action_bits ); -aos_bool_t peripheral_helper_socket_check_actions_enabled ( aos_bt_peripheral_socket_t *socket, - uint8_t action_bits ); -aos_bool_t peripheral_helper_socket_check_actions_disabled ( aos_bt_peripheral_socket_t *socket, - uint8_t action_bits ); -void peripheral_helper_socket_set_actions ( aos_bt_peripheral_socket_t *socket, +mico_bool_t peripheral_helper_socket_check_actions_enabled ( mico_bt_peripheral_socket_t *socket, uint8_t action_bits ); -void peripheral_helper_socket_clear_actions ( aos_bt_peripheral_socket_t *socket, +mico_bool_t peripheral_helper_socket_check_actions_disabled ( mico_bt_peripheral_socket_t *socket, + uint8_t action_bits ); +void peripheral_helper_socket_set_actions ( mico_bt_peripheral_socket_t *socket, + uint8_t action_bits ); +void peripheral_helper_socket_clear_actions ( mico_bt_peripheral_socket_t *socket, uint8_t action_bits ); OSStatus subprocedure_notify_complete ( gatt_subprocedure_t *subprocedure ); @@ -154,18 +148,16 @@ OSStatus subprocedure_wait_for_completion ( gatt_subprocedure_t *subp OSStatus subprocedure_wait_clear_semaphore ( gatt_subprocedure_t *subprocedure ); /* This function is used to stop a active timer. - * return AOS_TRUE if successful, otherwise, return AOS_FALSE + * return MICO_TRUE if successful, otherwise, return MICO_FALSE */ -aos_bool_t smartbridge_helper_timer_stop(smartbridge_helper_timer_t *timer); +mico_bool_t smartbridge_helper_timer_stop(smartbridge_helper_timer_t *timer); /* This function is used to start or restart a timer. * The 'timer' will be restarted if it is active. */ -aos_bool_t smartbridge_helper_timer_start(smartbridge_helper_timer_t *timer, aos_bool_t one_shot, uint32_t ms, - timer_handler_t handler, void *arg); +mico_bool_t smartbridge_helper_timer_start(smartbridge_helper_timer_t *timer, mico_bool_t one_shot, uint32_t ms, + timer_handler_t handler, void *arg); #ifdef __cplusplus } /* extern "C" */ #endif - -#endif diff --git a/framework/bluetooth/smartbt/internal/bt_smartbridge_socket_manager.c b/device/bluetooth/mk3239/bt_smart/internal/bt_smartbridge_socket_manager.c similarity index 69% rename from framework/bluetooth/smartbt/internal/bt_smartbridge_socket_manager.c rename to device/bluetooth/mk3239/bt_smart/internal/bt_smartbridge_socket_manager.c index b2b7d516ad..43e47913c9 100644 --- a/framework/bluetooth/smartbt/internal/bt_smartbridge_socket_manager.c +++ b/device/bluetooth/mk3239/bt_smart/internal/bt_smartbridge_socket_manager.c @@ -1,12 +1,9 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ /** @file * */ -#include +#include "mico.h" #include "LinkListUtils.h" #include "bt_smartbridge_socket_manager.h" @@ -45,7 +42,7 @@ static bool smartbridge_socket_manager_find_socket_by_address_callback ( linked_ /* Socket Management Globals */ static linked_list_t connected_socket_list; -static aos_mutex_t connected_socket_list_mutex; +static mico_mutex_t connected_socket_list_mutex; static uint8_t max_number_of_connections = 0; /****************************************************** @@ -57,46 +54,46 @@ OSStatus bt_smartbridge_socket_manager_init( void ) OSStatus result; result = linked_list_init( &connected_socket_list ); - if ( result != oNoErr ) { - printf( ( "Error creating linked list\n" ) ); + if ( result != kNoErr ) { + WPRINT_LIB_INFO( ( "Error creating linked list\n" ) ); return result; } - result = aos_rtos_init_mutex( &connected_socket_list_mutex ); - if ( result != oNoErr ) { - printf( ( "Error creating mutex\n" ) ); + result = mico_rtos_init_mutex( &connected_socket_list_mutex ); + if ( result != kNoErr ) { + WPRINT_LIB_INFO( ( "Error creating mutex\n" ) ); return result; } max_number_of_connections = 1; - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } OSStatus bt_smartbridge_socket_manager_deinit( void ) { - aos_rtos_deinit_mutex( &connected_socket_list_mutex ); + mico_rtos_deinit_mutex( &connected_socket_list_mutex ); linked_list_deinit( &connected_socket_list ); max_number_of_connections = 0; - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } OSStatus bt_smartbridge_socket_manager_set_max_concurrent_connections( uint8_t count ) { max_number_of_connections = count; - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } -aos_bool_t bt_smartbridge_socket_manager_is_full( void ) +mico_bool_t bt_smartbridge_socket_manager_is_full( void ) { uint32_t active_connection_count; linked_list_get_count( &connected_socket_list, &active_connection_count ); - return ( active_connection_count == max_number_of_connections ) ? AOS_TRUE : AOS_FALSE; + return ( active_connection_count == max_number_of_connections ) ? MICO_TRUE : MICO_FALSE; } -OSStatus bt_smartbridge_socket_manager_insert_socket( aos_bt_smartbridge_socket_t *socket ) +OSStatus bt_smartbridge_socket_manager_insert_socket( mico_bt_smartbridge_socket_t *socket ) { OSStatus result; uint32_t count; @@ -104,21 +101,22 @@ OSStatus bt_smartbridge_socket_manager_insert_socket( aos_bt_smartbridge_socket_ linked_list_get_count( &connected_socket_list, &count ); if ( count == max_number_of_connections ) { - return AOS_BT_MAX_CONNECTIONS_REACHED; + return MICO_BT_MAX_CONNECTIONS_REACHED; } /* Lock protection */ - aos_rtos_lock_mutex( &connected_socket_list_mutex ); + mico_rtos_lock_mutex( &connected_socket_list_mutex ); result = linked_list_insert_node_at_rear( &connected_socket_list, &socket->node ); /* Unlock protection */ - aos_rtos_unlock_mutex( &connected_socket_list_mutex ); + mico_rtos_unlock_mutex( &connected_socket_list_mutex ); return result; } -OSStatus bt_smartbridge_socket_manager_remove_socket( uint16_t connection_handle, aos_bt_smartbridge_socket_t **socket ) +OSStatus bt_smartbridge_socket_manager_remove_socket( uint16_t connection_handle, + mico_bt_smartbridge_socket_t **socket ) { OSStatus result; uint32_t count; @@ -128,30 +126,30 @@ OSStatus bt_smartbridge_socket_manager_remove_socket( uint16_t connection_handle linked_list_get_count( &connected_socket_list, &count ); if ( count == 0 ) { - return AOS_BT_SOCKET_NOT_CONNECTED; + return MICO_BT_SOCKET_NOT_CONNECTED; } /* Lock protection */ - aos_rtos_lock_mutex( &connected_socket_list_mutex ); + mico_rtos_lock_mutex( &connected_socket_list_mutex ); result = linked_list_find_node( &connected_socket_list, smartbridge_socket_manager_find_socket_by_handle_callback, (void *)user_data, &node_found ); - if ( result == AOS_BT_SUCCESS ) { + if ( result == MICO_BT_SUCCESS ) { result = linked_list_remove_node( &connected_socket_list, node_found ); - if ( result == AOS_BT_SUCCESS ) { - *socket = (aos_bt_smartbridge_socket_t *)node_found->data; + if ( result == MICO_BT_SUCCESS ) { + *socket = (mico_bt_smartbridge_socket_t *)node_found->data; } } /* Unlock protection */ - aos_rtos_unlock_mutex( &connected_socket_list_mutex ); + mico_rtos_unlock_mutex( &connected_socket_list_mutex ); return result; } OSStatus bt_smartbridge_socket_manager_find_socket_by_handle( uint16_t connection_handle, - aos_bt_smartbridge_socket_t **socket ) + mico_bt_smartbridge_socket_t **socket ) { OSStatus result; uint32_t count; @@ -161,27 +159,27 @@ OSStatus bt_smartbridge_socket_manager_find_socket_by_handle( uint16_t connectio linked_list_get_count( &connected_socket_list, &count ); if ( count == 0 ) { - return AOS_BT_SOCKET_NOT_CONNECTED; + return MICO_BT_SOCKET_NOT_CONNECTED; } /* Lock protection */ - aos_rtos_lock_mutex( &connected_socket_list_mutex ); + mico_rtos_lock_mutex( &connected_socket_list_mutex ); result = linked_list_find_node( &connected_socket_list, smartbridge_socket_manager_find_socket_by_handle_callback, (void *)user_data, &node_found ); - if ( result == AOS_BT_SUCCESS ) { - *socket = (aos_bt_smartbridge_socket_t *)node_found->data; + if ( result == MICO_BT_SUCCESS ) { + *socket = (mico_bt_smartbridge_socket_t *)node_found->data; } /* Unlock protection */ - aos_rtos_unlock_mutex( &connected_socket_list_mutex ); + mico_rtos_unlock_mutex( &connected_socket_list_mutex ); return result; } -OSStatus bt_smartbridge_socket_manager_find_socket_by_address( const aos_bt_device_address_t *address, - aos_bt_smartbridge_socket_t **socket ) +OSStatus bt_smartbridge_socket_manager_find_socket_by_address( const mico_bt_device_address_t *address, + mico_bt_smartbridge_socket_t **socket ) { OSStatus result; uint32_t count; @@ -190,21 +188,21 @@ OSStatus bt_smartbridge_socket_manager_find_socket_by_address( const aos_bt_devi linked_list_get_count( &connected_socket_list, &count ); if ( count == 0 ) { - return AOS_BT_SOCKET_NOT_CONNECTED; + return MICO_BT_SOCKET_NOT_CONNECTED; } /* Lock protection */ - aos_rtos_lock_mutex( &connected_socket_list_mutex ); + mico_rtos_lock_mutex( &connected_socket_list_mutex ); result = linked_list_find_node( &connected_socket_list, smartbridge_socket_manager_find_socket_by_address_callback, (void *)address, &node_found ); - if ( result == AOS_BT_SUCCESS ) { - *socket = (aos_bt_smartbridge_socket_t *)node_found->data; + if ( result == MICO_BT_SUCCESS ) { + *socket = (mico_bt_smartbridge_socket_t *)node_found->data; } /* Unlock protection */ - aos_rtos_unlock_mutex( &connected_socket_list_mutex ); + mico_rtos_unlock_mutex( &connected_socket_list_mutex ); return result; } @@ -212,7 +210,7 @@ OSStatus bt_smartbridge_socket_manager_find_socket_by_address( const aos_bt_devi static bool smartbridge_socket_manager_find_socket_by_handle_callback( linked_list_node_t *node_to_compare, void *user_data ) { - aos_bt_smartbridge_socket_t *socket = (aos_bt_smartbridge_socket_t *)node_to_compare->data; + mico_bt_smartbridge_socket_t *socket = (mico_bt_smartbridge_socket_t *)node_to_compare->data; uint32_t connection_handle = (uint32_t)user_data; return ( socket->connection_handle == connection_handle ) ? true : false; @@ -221,8 +219,8 @@ static bool smartbridge_socket_manager_find_socket_by_handle_callback( linked_li static bool smartbridge_socket_manager_find_socket_by_address_callback( linked_list_node_t *node_to_compare, void *user_data ) { - aos_bt_smartbridge_socket_t *socket = (aos_bt_smartbridge_socket_t *)node_to_compare->data; - aos_bt_device_address_t *address = (aos_bt_device_address_t *)user_data; + mico_bt_smartbridge_socket_t *socket = (mico_bt_smartbridge_socket_t *)node_to_compare->data; + mico_bt_device_address_t *address = (mico_bt_device_address_t *)user_data; return ( memcmp( socket->remote_device.address, address, sizeof( *address ) ) == 0 ) ? true : false; } diff --git a/framework/bluetooth/smartbt/internal/bt_smartbridge_socket_manager.h b/device/bluetooth/mk3239/bt_smart/internal/bt_smartbridge_socket_manager.h similarity index 70% rename from framework/bluetooth/smartbt/internal/bt_smartbridge_socket_manager.h rename to device/bluetooth/mk3239/bt_smart/internal/bt_smartbridge_socket_manager.h index dba800e71e..2fdba043c3 100644 --- a/framework/bluetooth/smartbt/internal/bt_smartbridge_socket_manager.h +++ b/device/bluetooth/mk3239/bt_smart/internal/bt_smartbridge_socket_manager.h @@ -1,13 +1,7 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#ifndef _BT_SMART_BRIDGE_SOCKET_MANAGER_H_ -#define _BT_SMART_BRIDGE_SOCKET_MANAGER_H_ - #pragma once -#include "smartbt_smartbridge.h" +//#include "mico_utilities.h" +#include "mico_bt_smartbridge.h" #include "LinkListUtils.h" #ifdef __cplusplus @@ -48,21 +42,19 @@ OSStatus bt_smartbridge_socket_manager_deinit( void ); OSStatus bt_smartbridge_socket_manager_set_max_concurrent_connections( uint8_t count ); -aos_bool_t bt_smartbridge_socket_manager_is_full( void ); +mico_bool_t bt_smartbridge_socket_manager_is_full( void ); -OSStatus bt_smartbridge_socket_manager_insert_socket( aos_bt_smartbridge_socket_t *socket ); +OSStatus bt_smartbridge_socket_manager_insert_socket( mico_bt_smartbridge_socket_t *socket ); OSStatus bt_smartbridge_socket_manager_remove_socket( uint16_t connection_handle, - aos_bt_smartbridge_socket_t **socket ); + mico_bt_smartbridge_socket_t **socket ); OSStatus bt_smartbridge_socket_manager_find_socket_by_handle( uint16_t connection_handle, - aos_bt_smartbridge_socket_t **socket ); + mico_bt_smartbridge_socket_t **socket ); -OSStatus bt_smartbridge_socket_manager_find_socket_by_address( const aos_bt_device_address_t *address, - aos_bt_smartbridge_socket_t **socket ); +OSStatus bt_smartbridge_socket_manager_find_socket_by_address( const mico_bt_device_address_t *address, + mico_bt_smartbridge_socket_t **socket ); #ifdef __cplusplus } /* extern "C" */ #endif - -#endif diff --git a/framework/bluetooth/smartbt/internal/bt_smartbridge_stack_interface.c b/device/bluetooth/mk3239/bt_smart/internal/bt_smartbridge_stack_interface.c similarity index 69% rename from framework/bluetooth/smartbt/internal/bt_smartbridge_stack_interface.c rename to device/bluetooth/mk3239/bt_smart/internal/bt_smartbridge_stack_interface.c index 5ad977fd47..ce57d2e16f 100644 --- a/framework/bluetooth/smartbt/internal/bt_smartbridge_stack_interface.c +++ b/device/bluetooth/mk3239/bt_smart/internal/bt_smartbridge_stack_interface.c @@ -1,16 +1,14 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ /** @file * */ -#include "smartbt_smartbridge.h" +#include "mico.h" +#include "mico_bt_smartbridge.h" -#include "smartbt.h" -#include "aos_bt_gatt.h" -#include "aos_bt_ble.h" -#include "smartbt_cfg.h" +#include "mico_bt.h" +#include "mico_bt_gatt.h" +#include "mico_bt_ble.h" +#include "mico_bt_cfg.h" #include "bt_smartbridge_socket_manager.h" #include "bt_smartbridge_att_cache_manager.h" @@ -49,11 +47,11 @@ gatt_subprocedure_t smartbridge_subprocedure; -extern aos_bt_cfg_settings_t aos_bt_cfg_settings; -aos_bt_smart_scan_complete_callback_t app_scan_complete_callback; -aos_bt_smart_advertising_report_callback_t app_scan_report_callback; +extern mico_bt_cfg_settings_t mico_bt_cfg_settings; +mico_bt_smart_scan_complete_callback_t app_scan_complete_callback; +mico_bt_smart_advertising_report_callback_t app_scan_report_callback; -aos_bt_dev_ble_io_caps_req_t default_io_caps_ble = { +mico_bt_dev_ble_io_caps_req_t default_io_caps_ble = { .bd_addr = { 0 }, .local_io_cap = BTM_IO_CAPABILITIES_NONE, .oob_data = 0, @@ -63,8 +61,8 @@ aos_bt_dev_ble_io_caps_req_t default_io_caps_ble = { .resp_keys = (BTM_LE_KEY_PENC | BTM_LE_KEY_PID | BTM_LE_KEY_PCSRK | BTM_LE_KEY_PLK) // resp_keys - Keys to be distributed, bit mask }; -extern aos_bt_gatt_status_t smartbridge_gatt_callback ( aos_bt_gatt_evt_t event, - aos_bt_gatt_event_data_t *p_event_data ); +extern mico_bt_gatt_status_t smartbridge_gatt_callback ( mico_bt_gatt_evt_t event, + mico_bt_gatt_event_data_t *p_event_data ); /****************************************************** * Function Definitions @@ -76,21 +74,21 @@ OSStatus smartbridge_bt_interface_initialize( void ) bt_smartbridge_log( "Initializing Bluetooth Interface..." ); - result = aos_rtos_init_mutex( &smartbridge_subprocedure.mutex ); - if ( result != AOS_BT_SUCCESS ) { + result = mico_rtos_init_mutex( &smartbridge_subprocedure.mutex ); + if ( result != MICO_BT_SUCCESS ) { bt_smartbridge_log( "Error creating mutex" ); return result; } - result = aos_rtos_init_semaphore( &smartbridge_subprocedure.done_semaphore, 1 ); - if ( result != AOS_BT_SUCCESS ) { + result = mico_rtos_init_semaphore( &smartbridge_subprocedure.done_semaphore, 1 ); + if ( result != MICO_BT_SUCCESS ) { bt_smartbridge_log( "Error creating semaphore" ); return result; } subprocedure_reset( &smartbridge_subprocedure ); - aos_bt_gatt_register( GATT_IF_CLIENT, smartbridge_gatt_callback ); - return AOS_BT_SUCCESS; + mico_bt_gatt_register( GATT_IF_CLIENT, smartbridge_gatt_callback ); + return MICO_BT_SUCCESS; } OSStatus smartbridge_bt_interface_deinitialize( void ) @@ -98,16 +96,16 @@ OSStatus smartbridge_bt_interface_deinitialize( void ) bt_smartbridge_log( "Deinitializing Bluetooth Interface..." ); subprocedure_reset( &smartbridge_subprocedure ); - aos_rtos_deinit_mutex( &smartbridge_subprocedure.mutex ); - aos_rtos_deinit_semaphore( &smartbridge_subprocedure.done_semaphore ); + mico_rtos_deinit_mutex( &smartbridge_subprocedure.mutex ); + mico_rtos_deinit_semaphore( &smartbridge_subprocedure.done_semaphore ); - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } OSStatus smartbridge_bt_interface_discover_all_primary_services( uint16_t connection_handle, - aos_bt_smart_attribute_list_t *service_list ) + mico_bt_smart_attribute_list_t *service_list ) { - aos_bt_gatt_discovery_param_t parameter; + mico_bt_gatt_discovery_param_t parameter; bt_smartbridge_log( "Discover all Primary Services" ); subprocedure_lock( &smartbridge_subprocedure ); @@ -123,21 +121,21 @@ OSStatus smartbridge_bt_interface_discover_all_primary_services( uint16_t connec smartbridge_subprocedure.end_handle = 0xffff; smartbridge_subprocedure.start_handle = 1; - aos_bt_gatt_send_discover( connection_handle, GATT_DISCOVER_SERVICES_ALL, ¶meter ); + mico_bt_gatt_send_discover( connection_handle, GATT_DISCOVER_SERVICES_ALL, ¶meter ); subprocedure_wait_for_completion( &smartbridge_subprocedure ); - if ( smartbridge_subprocedure.result == AOS_BT_SUCCESS ) { + if ( smartbridge_subprocedure.result == MICO_BT_SUCCESS ) { service_list->count = smartbridge_subprocedure.attr_count; service_list->list = smartbridge_subprocedure.attr_head; } else { /* Clean up */ - aos_bt_smart_attribute_list_t list; + mico_bt_smart_attribute_list_t list; list.count = smartbridge_subprocedure.attr_count; list.list = smartbridge_subprocedure.attr_head; - aos_bt_smart_attribute_delete_list( &list ); + mico_bt_smart_attribute_delete_list( &list ); } subprocedure_unlock( &smartbridge_subprocedure ); @@ -146,9 +144,9 @@ OSStatus smartbridge_bt_interface_discover_all_primary_services( uint16_t connec } OSStatus smartbridge_bt_interface_discover_primary_services_by_uuid( uint16_t connection_handle, - const aos_bt_uuid_t *uuid, aos_bt_smart_attribute_list_t *service_list ) + const mico_bt_uuid_t *uuid, mico_bt_smart_attribute_list_t *service_list ) { - aos_bt_gatt_discovery_param_t parameter; + mico_bt_gatt_discovery_param_t parameter; bt_smartbridge_log( "Discover all Primary Services(By-UUID)" ); subprocedure_lock( &smartbridge_subprocedure ); @@ -162,21 +160,21 @@ OSStatus smartbridge_bt_interface_discover_primary_services_by_uuid( uint16_t co parameter.s_handle = smartbridge_subprocedure.end_handle = 0x0001; parameter.e_handle = smartbridge_subprocedure.start_handle = 0xffff; - aos_bt_gatt_send_discover( connection_handle, GATT_DISCOVER_SERVICES_BY_UUID, ¶meter ); + mico_bt_gatt_send_discover( connection_handle, GATT_DISCOVER_SERVICES_BY_UUID, ¶meter ); subprocedure_wait_for_completion( &smartbridge_subprocedure ); - if ( smartbridge_subprocedure.result == AOS_BT_SUCCESS ) { + if ( smartbridge_subprocedure.result == MICO_BT_SUCCESS ) { service_list->count = smartbridge_subprocedure.attr_count; service_list->list = smartbridge_subprocedure.attr_head; } else { /* Clean up */ - aos_bt_smart_attribute_list_t list; + mico_bt_smart_attribute_list_t list; list.count = smartbridge_subprocedure.attr_count; list.list = smartbridge_subprocedure.attr_head; - aos_bt_smart_attribute_delete_list( &list ); + mico_bt_smart_attribute_delete_list( &list ); } subprocedure_unlock( &smartbridge_subprocedure ); @@ -185,10 +183,10 @@ OSStatus smartbridge_bt_interface_discover_primary_services_by_uuid( uint16_t co } OSStatus smartbridge_bt_interface_find_included_services( uint16_t connection_handle, uint16_t start_handle, - uint16_t end_handle, aos_bt_smart_attribute_list_t *include_list ) + uint16_t end_handle, mico_bt_smart_attribute_list_t *include_list ) { - aos_bt_gatt_discovery_param_t parameter; + mico_bt_gatt_discovery_param_t parameter; bt_smartbridge_log( "Discover all Included Services" ); subprocedure_lock( &smartbridge_subprocedure ); @@ -202,21 +200,21 @@ OSStatus smartbridge_bt_interface_find_included_services( uint16_t connection_ha parameter.s_handle = smartbridge_subprocedure.end_handle = start_handle; parameter.e_handle = smartbridge_subprocedure.start_handle = end_handle; - aos_bt_gatt_send_discover( connection_handle, GATT_DISCOVER_INCLUDED_SERVICES, ¶meter ); + mico_bt_gatt_send_discover( connection_handle, GATT_DISCOVER_INCLUDED_SERVICES, ¶meter ); subprocedure_wait_for_completion( &smartbridge_subprocedure ); - if ( smartbridge_subprocedure.result == AOS_BT_SUCCESS ) { + if ( smartbridge_subprocedure.result == MICO_BT_SUCCESS ) { include_list->count = smartbridge_subprocedure.attr_count; include_list->list = smartbridge_subprocedure.attr_head; } else { /* Clean up */ - aos_bt_smart_attribute_list_t list; + mico_bt_smart_attribute_list_t list; list.count = smartbridge_subprocedure.attr_count; list.list = smartbridge_subprocedure.attr_head; - aos_bt_smart_attribute_delete_list( &list ); + mico_bt_smart_attribute_delete_list( &list ); } subprocedure_unlock( &smartbridge_subprocedure ); @@ -225,9 +223,9 @@ OSStatus smartbridge_bt_interface_find_included_services( uint16_t connection_ha } OSStatus smartbridge_bt_interface_discover_all_characteristics_in_a_service( uint16_t connection_handle, - uint16_t start_handle, uint16_t end_handle, aos_bt_smart_attribute_list_t *characteristic_list ) + uint16_t start_handle, uint16_t end_handle, mico_bt_smart_attribute_list_t *characteristic_list ) { - aos_bt_gatt_discovery_param_t parameter; + mico_bt_gatt_discovery_param_t parameter; subprocedure_lock( &smartbridge_subprocedure ); bt_smartbridge_log( "Discover Characteristics by Service[%x %x]", start_handle, end_handle ); @@ -242,22 +240,22 @@ OSStatus smartbridge_bt_interface_discover_all_characteristics_in_a_service( uin smartbridge_subprocedure.end_handle = end_handle; smartbridge_subprocedure.start_handle = start_handle; - aos_bt_gatt_send_discover( connection_handle, GATT_DISCOVER_CHARACTERISTICS, ¶meter ); + mico_bt_gatt_send_discover( connection_handle, GATT_DISCOVER_CHARACTERISTICS, ¶meter ); subprocedure_wait_for_completion( &smartbridge_subprocedure ); - if ( smartbridge_subprocedure.result == AOS_BT_SUCCESS ) { + if ( smartbridge_subprocedure.result == MICO_BT_SUCCESS ) { characteristic_list->count = smartbridge_subprocedure.attr_count; characteristic_list->list = smartbridge_subprocedure.attr_head; } else { /* Clean up */ - aos_bt_smart_attribute_list_t list; + mico_bt_smart_attribute_list_t list; list.count = smartbridge_subprocedure.attr_count; list.list = smartbridge_subprocedure.attr_head; - aos_bt_smart_attribute_delete_list( &list ); + mico_bt_smart_attribute_delete_list( &list ); } subprocedure_unlock( &smartbridge_subprocedure ); @@ -266,11 +264,11 @@ OSStatus smartbridge_bt_interface_discover_all_characteristics_in_a_service( uin } OSStatus smartbridge_bt_interface_discover_characteristic_by_uuid( uint16_t connection_handle, - const aos_bt_uuid_t *uuid, uint16_t start_handle, uint16_t end_handle, - aos_bt_smart_attribute_list_t *characteristic_list ) + const mico_bt_uuid_t *uuid, uint16_t start_handle, uint16_t end_handle, + mico_bt_smart_attribute_list_t *characteristic_list ) { UNUSED_PARAMETER(characteristic_list); - aos_bt_gatt_discovery_param_t parameter; + mico_bt_gatt_discovery_param_t parameter; subprocedure_lock( &smartbridge_subprocedure ); bt_smartbridge_log( "Discover Characteristics by UUID [%x %x]", start_handle, end_handle ); @@ -283,22 +281,22 @@ OSStatus smartbridge_bt_interface_discover_characteristic_by_uuid( uint16_t conn parameter.s_handle = smartbridge_subprocedure.start_handle = start_handle; parameter.e_handle = smartbridge_subprocedure.end_handle = end_handle; - aos_bt_gatt_send_discover( connection_handle, GATT_DISCOVER_CHARACTERISTICS, ¶meter ); + mico_bt_gatt_send_discover( connection_handle, GATT_DISCOVER_CHARACTERISTICS, ¶meter ); subprocedure_wait_for_completion( &smartbridge_subprocedure ); - if ( smartbridge_subprocedure.result == AOS_BT_SUCCESS ) { + if ( smartbridge_subprocedure.result == MICO_BT_SUCCESS ) { characteristic_list->count = smartbridge_subprocedure.attr_count; characteristic_list->list = smartbridge_subprocedure.attr_head; } else { /* Clean up */ - aos_bt_smart_attribute_list_t list; + mico_bt_smart_attribute_list_t list; list.count = smartbridge_subprocedure.attr_count; list.list = smartbridge_subprocedure.attr_head; - aos_bt_smart_attribute_delete_list( &list ); + mico_bt_smart_attribute_delete_list( &list ); } subprocedure_unlock( &smartbridge_subprocedure ); @@ -307,10 +305,10 @@ OSStatus smartbridge_bt_interface_discover_characteristic_by_uuid( uint16_t conn } OSStatus smartbridge_bt_interface_discover_all_characteristic_descriptors( uint16_t connection_handle, - uint16_t start_handle, uint16_t end_handle, aos_bt_smart_attribute_list_t *no_value_descriptor_list ) + uint16_t start_handle, uint16_t end_handle, mico_bt_smart_attribute_list_t *no_value_descriptor_list ) { - aos_bt_gatt_discovery_param_t parameter; + mico_bt_gatt_discovery_param_t parameter; bt_smartbridge_log( "Discover all Characteristic Descriptors[%x %x]", start_handle, end_handle ); subprocedure_lock( &smartbridge_subprocedure ); subprocedure_reset( &smartbridge_subprocedure ); @@ -325,22 +323,22 @@ OSStatus smartbridge_bt_interface_discover_all_characteristic_descriptors( uint1 smartbridge_subprocedure.end_handle = end_handle; smartbridge_subprocedure.connection_handle = connection_handle; - aos_bt_gatt_send_discover( connection_handle, GATT_DISCOVER_CHARACTERISTIC_DESCRIPTORS, ¶meter ); + mico_bt_gatt_send_discover( connection_handle, GATT_DISCOVER_CHARACTERISTIC_DESCRIPTORS, ¶meter ); subprocedure_wait_for_completion( &smartbridge_subprocedure); bt_smartbridge_log( "Discover complete: %d", smartbridge_subprocedure.result ); - if ( smartbridge_subprocedure.result == AOS_BT_SUCCESS ) { + if ( smartbridge_subprocedure.result == MICO_BT_SUCCESS ) { no_value_descriptor_list->count = smartbridge_subprocedure.attr_count; no_value_descriptor_list->list = smartbridge_subprocedure.attr_head; } else { /* Clean up */ - aos_bt_smart_attribute_list_t list; + mico_bt_smart_attribute_list_t list; list.count = smartbridge_subprocedure.attr_count; list.list = smartbridge_subprocedure.attr_head; - aos_bt_smart_attribute_delete_list( &list ); + mico_bt_smart_attribute_delete_list( &list ); } subprocedure_unlock( &smartbridge_subprocedure ); @@ -349,9 +347,9 @@ OSStatus smartbridge_bt_interface_discover_all_characteristic_descriptors( uint1 } OSStatus smartbridge_bt_interface_read_characteristic_descriptor( uint16_t connection_handle, uint16_t handle, - const aos_bt_uuid_t *uuid, aos_bt_smart_attribute_t **descriptor ) + const mico_bt_uuid_t *uuid, mico_bt_smart_attribute_t **descriptor ) { - aos_bt_gatt_read_param_t parameter; + mico_bt_gatt_read_param_t parameter; bt_smartbridge_log( "Read Characteristic Descriptor" ); subprocedure_lock( &smartbridge_subprocedure ); @@ -375,15 +373,15 @@ OSStatus smartbridge_bt_interface_read_characteristic_descriptor( uint16_t conne memcpy( smartbridge_subprocedure.uuid.uu.uuid128, uuid->uu.uuid128, UUID_128BIT ); } - aos_bt_gatt_send_read( connection_handle, GATT_READ_BY_HANDLE, ¶meter ); + mico_bt_gatt_send_read( connection_handle, GATT_READ_BY_HANDLE, ¶meter ); subprocedure_wait_for_completion( &smartbridge_subprocedure ); - if ( smartbridge_subprocedure.result == AOS_BT_SUCCESS ) { + if ( smartbridge_subprocedure.result == MICO_BT_SUCCESS ) { *descriptor = smartbridge_subprocedure.attr_head; } else { /* Clean up */ - aos_bt_smart_attribute_delete( smartbridge_subprocedure.attr_head ); + mico_bt_smart_attribute_delete( smartbridge_subprocedure.attr_head ); } subprocedure_unlock( &smartbridge_subprocedure ); @@ -391,9 +389,9 @@ OSStatus smartbridge_bt_interface_read_characteristic_descriptor( uint16_t conne } OSStatus smartbridge_bt_interface_read_characteristic_value( uint16_t connection_handle, uint16_t handle, - const aos_bt_uuid_t *type, aos_bt_smart_attribute_t **characteristic_value ) + const mico_bt_uuid_t *type, mico_bt_smart_attribute_t **characteristic_value ) { - aos_bt_gatt_read_param_t parameter; + mico_bt_gatt_read_param_t parameter; bt_smartbridge_log( "Read Characteristic Value" ); subprocedure_lock( &smartbridge_subprocedure ); @@ -414,15 +412,15 @@ OSStatus smartbridge_bt_interface_read_characteristic_value( uint16_t connection memcpy( (uint8_t *)smartbridge_subprocedure.uuid.uu.uuid128, (uint8_t *)type->uu.uuid128, UUID_128BIT ); } - aos_bt_gatt_send_read( connection_handle, GATT_READ_BY_HANDLE, ¶meter ); + mico_bt_gatt_send_read( connection_handle, GATT_READ_BY_HANDLE, ¶meter ); subprocedure_wait_for_completion( &smartbridge_subprocedure ); - if ( smartbridge_subprocedure.result == AOS_BT_SUCCESS ) { + if ( smartbridge_subprocedure.result == MICO_BT_SUCCESS ) { *characteristic_value = smartbridge_subprocedure.attr_head; } else { /* Clean up */ - aos_bt_smart_attribute_delete( smartbridge_subprocedure.attr_head ); + mico_bt_smart_attribute_delete( smartbridge_subprocedure.attr_head ); } subprocedure_unlock( &smartbridge_subprocedure ); @@ -431,9 +429,9 @@ OSStatus smartbridge_bt_interface_read_characteristic_value( uint16_t connection } OSStatus smartbridge_bt_interface_read_characteristic_values_using_uuid( uint16_t connection_handle, - const aos_bt_uuid_t *uuid, aos_bt_smart_attribute_list_t *characteristic_value_list ) + const mico_bt_uuid_t *uuid, mico_bt_smart_attribute_list_t *characteristic_value_list ) { - aos_bt_gatt_read_param_t parameter; + mico_bt_gatt_read_param_t parameter; bt_smartbridge_log( "Read Characteristic Value" ); subprocedure_lock( &smartbridge_subprocedure ); @@ -443,7 +441,7 @@ OSStatus smartbridge_bt_interface_read_characteristic_values_using_uuid( uint16_ parameter.char_type.s_handle = smartbridge_subprocedure.start_handle = 0x0001; parameter.char_type.e_handle = smartbridge_subprocedure.end_handle = 0xffff; - memcpy( ¶meter.char_type.uuid, uuid, sizeof(aos_bt_uuid_t) ); + memcpy( ¶meter.char_type.uuid, uuid, sizeof(mico_bt_uuid_t) ); smartbridge_subprocedure.subprocedure = GATT_READ_USING_CHARACTERISTIC_UUID; smartbridge_subprocedure.attr_count = 0; @@ -456,16 +454,16 @@ OSStatus smartbridge_bt_interface_read_characteristic_values_using_uuid( uint16_ memcpy( smartbridge_subprocedure.uuid.uu.uuid128, uuid->uu.uuid128, UUID_128BIT ); } - aos_bt_gatt_send_read( connection_handle, GATT_READ_CHAR_VALUE, ¶meter ); + mico_bt_gatt_send_read( connection_handle, GATT_READ_CHAR_VALUE, ¶meter ); subprocedure_wait_for_completion( &smartbridge_subprocedure ); - if ( smartbridge_subprocedure.result == AOS_BT_SUCCESS ) { + if ( smartbridge_subprocedure.result == MICO_BT_SUCCESS ) { characteristic_value_list->count = smartbridge_subprocedure.attr_count; characteristic_value_list->list = smartbridge_subprocedure.attr_head; } else { /* Clean up */ - aos_bt_smart_attribute_delete( smartbridge_subprocedure.attr_head ); + mico_bt_smart_attribute_delete( smartbridge_subprocedure.attr_head ); } subprocedure_unlock( &smartbridge_subprocedure ); @@ -476,9 +474,9 @@ OSStatus smartbridge_bt_interface_read_characteristic_values_using_uuid( uint16_ } OSStatus smartbridge_bt_interface_read_long_characteristic_value( uint16_t connection_handle, uint16_t handle, - const aos_bt_uuid_t *type, aos_bt_smart_attribute_t **characteristic_value ) + const mico_bt_uuid_t *type, mico_bt_smart_attribute_t **characteristic_value ) { - aos_bt_gatt_read_param_t parameter; + mico_bt_gatt_read_param_t parameter; bt_smartbridge_log( "Read Long Characteristic Value" ); subprocedure_lock( &smartbridge_subprocedure ); @@ -500,15 +498,15 @@ OSStatus smartbridge_bt_interface_read_long_characteristic_value( uint16_t conne memcpy( smartbridge_subprocedure.uuid.uu.uuid128, type->uu.uuid128, UUID_128BIT ); } - aos_bt_gatt_send_read( connection_handle, GATT_READ_PARTIAL, ¶meter ); + mico_bt_gatt_send_read( connection_handle, GATT_READ_PARTIAL, ¶meter ); subprocedure_wait_for_completion( &smartbridge_subprocedure ); - if ( smartbridge_subprocedure.result == AOS_BT_SUCCESS ) { + if ( smartbridge_subprocedure.result == MICO_BT_SUCCESS ) { *characteristic_value = smartbridge_subprocedure.attr_head; } else { /* Clean up */ - aos_bt_smart_attribute_delete( smartbridge_subprocedure.attr_head ); + mico_bt_smart_attribute_delete( smartbridge_subprocedure.attr_head ); } subprocedure_unlock( &smartbridge_subprocedure ); @@ -517,27 +515,27 @@ OSStatus smartbridge_bt_interface_read_long_characteristic_value( uint16_t conne } OSStatus smartbridge_bt_interface_read_long_characteristic_descriptor( uint16_t connection_handle, uint16_t handle, - const aos_bt_uuid_t *uuid, aos_bt_smart_attribute_t **descriptor ) + const mico_bt_uuid_t *uuid, mico_bt_smart_attribute_t **descriptor ) { UNUSED_PARAMETER(connection_handle); UNUSED_PARAMETER(handle); UNUSED_PARAMETER(uuid); UNUSED_PARAMETER(descriptor); - return AOS_BT_UNSUPPORTED; + return MICO_BT_UNSUPPORTED; } OSStatus smartbridge_bt_interface_write_characteristic_descriptor( uint16_t connection_handle, - aos_bt_smart_attribute_t *attribute ) + mico_bt_smart_attribute_t *attribute ) { uint8_t buffer[100] = { 0 }; - aos_bt_gatt_value_t *write_value = (aos_bt_gatt_value_t *)buffer; + mico_bt_gatt_value_t *write_value = (mico_bt_gatt_value_t *)buffer; bt_smartbridge_log( "Write Characteristic Descriptor" ); #if 0 if ( attribute->value_length > LEATT_ATT_MTU - sizeof(LEATT_PDU_WRITE_HDR) ) { BT_DEBUG_PRINT( ( "[GATT] Write Characteristic Value: value too long\n" ) ); - return AOS_BT_ATTRIBUTE_VALUE_TOO_LONG; + return MICO_BT_ATTRIBUTE_VALUE_TOO_LONG; } #endif subprocedure_lock( &smartbridge_subprocedure ); @@ -553,7 +551,7 @@ OSStatus smartbridge_bt_interface_write_characteristic_descriptor( uint16_t con memcpy( write_value->value, attribute->value.value, attribute->value_length ); - aos_bt_gatt_send_write( connection_handle, GATT_WRITE, write_value ); + mico_bt_gatt_send_write( connection_handle, GATT_WRITE, write_value ); subprocedure_wait_for_completion( &smartbridge_subprocedure ); @@ -562,11 +560,11 @@ OSStatus smartbridge_bt_interface_write_characteristic_descriptor( uint16_t con } OSStatus smartbridge_bt_interface_write_characteristic_value( uint16_t connection_handle, - aos_bt_smart_attribute_t *attribute ) + mico_bt_smart_attribute_t *attribute ) { - OSStatus err = oNoErr; + OSStatus err = kNoErr; uint8_t buffer[100] = { 0 }; - aos_bt_gatt_value_t *write_value = (aos_bt_gatt_value_t *)buffer; + mico_bt_gatt_value_t *write_value = (mico_bt_gatt_value_t *)buffer; bt_smartbridge_log( "Write Characteristic value" ); @@ -581,7 +579,7 @@ OSStatus smartbridge_bt_interface_write_characteristic_value( uint16_t connectio memcpy( write_value->value, attribute->value.value, attribute->value_length ); - err = aos_bt_gatt_send_write( connection_handle, GATT_WRITE, write_value ); + err = mico_bt_gatt_send_write( connection_handle, GATT_WRITE, write_value ); require_noerr(err, exit); subprocedure_wait_for_completion( &smartbridge_subprocedure ); @@ -594,35 +592,35 @@ OSStatus smartbridge_bt_interface_write_characteristic_value( uint16_t connectio } OSStatus smartbridge_bt_interface_write_long_characteristic_value( uint16_t connection_handle, - aos_bt_smart_attribute_t *attribute ) + mico_bt_smart_attribute_t *attribute ) { UNUSED_PARAMETER(connection_handle); UNUSED_PARAMETER(attribute); - return AOS_BT_UNSUPPORTED; + return MICO_BT_UNSUPPORTED; } OSStatus smartbridge_bt_interface_write_long_characteristic_descriptor( uint16_t connection_handle, - const aos_bt_smart_attribute_t *descriptor ) + const mico_bt_smart_attribute_t *descriptor ) { UNUSED_PARAMETER( connection_handle ); UNUSED_PARAMETER( descriptor ); - return AOS_BT_UNSUPPORTED; + return MICO_BT_UNSUPPORTED; } -static void smartbridge_scan_result_callback( aos_bt_ble_scan_results_t *p_scan_result, uint8_t *p_adv_data ) +static void smartbridge_scan_result_callback( mico_bt_ble_scan_results_t *p_scan_result, uint8_t *p_adv_data ) { if ( p_scan_result ) { - aos_bt_smart_advertising_report_t advertising_report; - aos_bt_smart_scan_result_t *current_scan_result = NULL; + mico_bt_smart_advertising_report_t advertising_report; + mico_bt_smart_scan_result_t *current_scan_result = NULL; uint8_t adv_data_length; uint8_t *p = p_adv_data; uint8_t adv_type; uint8_t i; - memset( &advertising_report, 0x0, sizeof(aos_bt_smart_advertising_report_t) ); + memset( &advertising_report, 0x0, sizeof(mico_bt_smart_advertising_report_t) ); advertising_report.remote_device.address[0] = p_scan_result->remote_bd_addr[0]; advertising_report.remote_device.address[1] = p_scan_result->remote_bd_addr[1]; advertising_report.remote_device.address[2] = p_scan_result->remote_bd_addr[2]; @@ -631,9 +629,9 @@ static void smartbridge_scan_result_callback( aos_bt_ble_scan_results_t *p_scan_ advertising_report.remote_device.address[5] = p_scan_result->remote_bd_addr[5]; - advertising_report.remote_device.address_type = (aos_bt_smart_address_type_t)p_scan_result->ble_addr_type; + advertising_report.remote_device.address_type = (mico_bt_smart_address_type_t)p_scan_result->ble_addr_type; advertising_report.signal_strength = p_scan_result->rssi; - advertising_report.event = (aos_bt_smart_advertising_event_t)p_scan_result->ble_evt_type; + advertising_report.event = (mico_bt_smart_advertising_event_t)p_scan_result->ble_evt_type; advertising_report.eir_data_length = 0; bt_smartbridge_log( "address:%x %x %x %x %x %x rssi:%d bdaddrtype:%d event_type:%x length:%u", @@ -646,9 +644,9 @@ static void smartbridge_scan_result_callback( aos_bt_ble_scan_results_t *p_scan_ } if ( smartbridge_helper_find_device_in_scan_result_list( &advertising_report.remote_device.address, - advertising_report.remote_device.address_type, ¤t_scan_result ) == AOS_BT_ITEM_NOT_IN_LIST ) { + advertising_report.remote_device.address_type, ¤t_scan_result ) == MICO_BT_ITEM_NOT_IN_LIST ) { /* This is a new result. Create new result object and add to the list */ - current_scan_result = (aos_bt_smart_scan_result_t *)malloc_named( "scanres", sizeof( *current_scan_result ) ); + current_scan_result = (mico_bt_smart_scan_result_t *)malloc_named( "scanres", sizeof( *current_scan_result ) ); if ( !current_scan_result ) { bt_smartbridge_log( "Failed to alloc memory for scan-list" ); return; @@ -663,7 +661,7 @@ static void smartbridge_scan_result_callback( aos_bt_ble_scan_results_t *p_scan_ current_scan_result->remote_device.address[4] = p_scan_result->remote_bd_addr[4]; current_scan_result->remote_device.address[5] = p_scan_result->remote_bd_addr[5]; - current_scan_result->remote_device.address_type = (aos_bt_smart_address_type_t)p_scan_result->ble_addr_type; + current_scan_result->remote_device.address_type = (mico_bt_smart_address_type_t)p_scan_result->ble_addr_type; smartbridge_helper_add_scan_result_to_list( current_scan_result ); } @@ -696,23 +694,23 @@ static void smartbridge_scan_result_callback( aos_bt_ble_scan_results_t *p_scan_ if ( p_scan_result->ble_evt_type == BT_SMART_SCAN_RESPONSE_EVENT ) { bt_smartbridge_log( "Received SCAN_RSP\r\n" ); memcpy( ¤t_scan_result->last_scan_response_received, &advertising_report, - sizeof(aos_bt_smart_advertising_report_t) ); + sizeof(mico_bt_smart_advertising_report_t) ); if ( app_scan_report_callback != NULL ) { bt_smartbridge_log( "advertising callback reported" ); - aos_rtos_send_asynchronous_event( AOS_BT_EVT_WORKER_THREAD, - (event_handler_t)app_scan_report_callback, - ¤t_scan_result->last_scan_response_received ); + mico_rtos_send_asynchronous_event( MICO_BT_EVT_WORKER_THREAD, + (event_handler_t)app_scan_report_callback, + ¤t_scan_result->last_scan_response_received ); } } else { bt_smartbridge_log( "Received ADV[%lu], %d\r\n", (uint32_t)p_scan_result->ble_evt_type, advertising_report.eir_data_length ); memcpy( ¤t_scan_result->last_advertising_event_received, &advertising_report, - sizeof(aos_bt_smart_advertising_report_t) ); + sizeof(mico_bt_smart_advertising_report_t) ); if ( app_scan_report_callback != NULL ) { bt_smartbridge_log( "advertising callback reported" ); - aos_rtos_send_asynchronous_event( AOS_BT_EVT_WORKER_THREAD, - (event_handler_t)app_scan_report_callback, - ¤t_scan_result->last_advertising_event_received ); + mico_rtos_send_asynchronous_event( MICO_BT_EVT_WORKER_THREAD, + (event_handler_t)app_scan_report_callback, + ¤t_scan_result->last_advertising_event_received ); } } } @@ -720,7 +718,7 @@ static void smartbridge_scan_result_callback( aos_bt_ble_scan_results_t *p_scan_ else { bt_smartbridge_log( "LE scan completed." ); if ( app_scan_complete_callback != NULL ) { - aos_rtos_send_asynchronous_event( AOS_BT_EVT_WORKER_THREAD, app_scan_complete_callback, NULL ); + mico_rtos_send_asynchronous_event( MICO_BT_EVT_WORKER_THREAD, app_scan_complete_callback, NULL ); } } } @@ -728,41 +726,41 @@ static void smartbridge_scan_result_callback( aos_bt_ble_scan_results_t *p_scan_ OSStatus smartbridge_bt_interface_set_attribute_timeout( uint32_t timeout_seconds ) { UNUSED_PARAMETER(timeout_seconds); - return AOS_BT_UNSUPPORTED; + return MICO_BT_UNSUPPORTED; } -OSStatus smartbridge_bt_interface_update_background_connection_device( aos_bool_t add, - aos_bt_device_address_t device_address ) +OSStatus smartbridge_bt_interface_update_background_connection_device( mico_bool_t add, + mico_bt_device_address_t device_address ) { if ( device_address == 0 ) { - return oParamErr; + return kParamErr; } if ( add ) { - if ( aos_bt_ble_update_background_connection_device( AOS_TRUE, device_address ) != TRUE ) { - return oGeneralErr; + if ( mico_bt_ble_update_background_connection_device( MICO_TRUE, device_address ) != TRUE ) { + return kGeneralErr; } } else { - if ( aos_bt_ble_update_background_connection_device( AOS_FALSE, device_address ) != TRUE ) { - return oGeneralErr; + if ( mico_bt_ble_update_background_connection_device( MICO_FALSE, device_address ) != TRUE ) { + return kGeneralErr; } } - return oNoErr; + return kNoErr; } OSStatus smartbridge_bt_interface_get_background_connection_device_size( uint8_t *size ) { - OSStatus status = oNoErr; - if (TRUE != aos_bt_ble_get_background_connection_device_size(size)) { - status = oGeneralErr; + OSStatus status = kNoErr; + if (TRUE != mico_bt_ble_get_background_connection_device_size(size)) { + status = kGeneralErr; } return status; } -OSStatus smartbridge_bt_interface_set_background_connection_type(aos_bt_smartbridge_auto_connection_type_t type, - const aos_bt_smart_scan_settings_t *settings, aos_bt_smartbridge_auto_connection_parms_cback_t p_select_cback) +OSStatus smartbridge_bt_interface_set_background_connection_type(mico_bt_smartbridge_auto_connection_type_t type, + const mico_bt_smart_scan_settings_t *settings, mico_bt_smartbridge_auto_connection_parms_cback_t p_select_cback) { - OSStatus status = oNoErr; - aos_bt_ble_conn_type_t conn_type; + OSStatus status = kNoErr; + mico_bt_ble_conn_type_t conn_type; switch (type) { case SMARTBRIDGE_CONN_AUTO: @@ -775,53 +773,53 @@ OSStatus smartbridge_bt_interface_set_background_connection_type(aos_bt_smartbri conn_type = BTM_BLE_CONN_NONE; break; default: - return oParamErr; + return kParamErr; } /* fill with the settings provided by the smartbridge-application */ if (settings != NULL) { - aos_bt_cfg_settings.ble_scan_cfg.scan_mode = settings->type; - aos_bt_cfg_settings.ble_scan_cfg.high_duty_scan_window = settings->window; - aos_bt_cfg_settings.ble_scan_cfg.high_duty_scan_interval = settings->interval; + mico_bt_cfg_settings.ble_scan_cfg.scan_mode = settings->type; + mico_bt_cfg_settings.ble_scan_cfg.high_duty_scan_window = settings->window; + mico_bt_cfg_settings.ble_scan_cfg.high_duty_scan_interval = settings->interval; } else { /* Used the default. */ } - if (!aos_bt_ble_set_background_connection_type(conn_type, *(aos_bt_ble_selective_conn_cback_t *)p_select_cback)) { - status = oGeneralErr; + if (!mico_bt_ble_set_background_connection_type(conn_type, *(mico_bt_ble_selective_conn_cback_t *)p_select_cback)) { + status = kGeneralErr; } return status; } -OSStatus smartbridge_bt_interface_cancel_last_connect( aos_bt_device_address_t address ) +OSStatus smartbridge_bt_interface_cancel_last_connect( mico_bt_device_address_t address ) { - return aos_bt_gatt_cancel_connect( address, AOS_TRUE ); + return mico_bt_gatt_cancel_connect( address, MICO_TRUE ); } OSStatus smartbridge_bt_interface_set_connection_tx_power( uint16_t connection_handle, int8_t transmit_power_dbm ) { - return AOS_BT_UNSUPPORTED; + return MICO_BT_UNSUPPORTED; } -aos_bool_t smartbridge_bt_interface_is_scanning( void ) +mico_bool_t smartbridge_bt_interface_is_scanning( void ) { - aos_bt_ble_scan_type_t scan_type; + mico_bt_ble_scan_type_t scan_type; - scan_type = aos_bt_ble_get_current_scan_state(); + scan_type = mico_bt_ble_get_current_scan_state(); if ( scan_type != BTM_BLE_SCAN_TYPE_NONE ) { - return AOS_TRUE; + return MICO_TRUE; } - return AOS_FALSE; + return MICO_FALSE; } OSStatus smartbridge_bt_interface_set_max_concurrent_connections( uint8_t count ) { /* Just update the Stack's configuration settings */ - aos_bt_cfg_settings.max_simultaneous_links = count; - aos_bt_cfg_settings.gatt_cfg.client_max_links = count; - return AOS_BT_SUCCESS; + mico_bt_cfg_settings.max_simultaneous_links = count; + mico_bt_cfg_settings.gatt_cfg.client_max_links = count; + return MICO_BT_SUCCESS; } OSStatus smartbridge_bt_interface_stop_scan( ) @@ -829,50 +827,51 @@ OSStatus smartbridge_bt_interface_stop_scan( ) app_scan_complete_callback = NULL; app_scan_report_callback = NULL; - return aos_bt_ble_scan( BTM_BLE_SCAN_TYPE_NONE, AOS_TRUE, smartbridge_scan_result_callback ); + return mico_bt_ble_scan( BTM_BLE_SCAN_TYPE_NONE, MICO_TRUE, smartbridge_scan_result_callback ); } -OSStatus smartbridge_bt_interface_start_scan( const aos_bt_smart_scan_settings_t *settings, - aos_bt_smart_scan_complete_callback_t complete_callback, - aos_bt_smart_advertising_report_callback_t advertising_report_callback ) +OSStatus smartbridge_bt_interface_start_scan( const mico_bt_smart_scan_settings_t *settings, + mico_bt_smart_scan_complete_callback_t complete_callback, + mico_bt_smart_advertising_report_callback_t advertising_report_callback ) { - aos_bool_t duplicate_filter_enabled = AOS_FALSE; + mico_bool_t duplicate_filter_enabled = MICO_FALSE; /* First delete the previous scan result list */ smartbridge_helper_delete_scan_result_list(); /* fill with the settings provided by the smartbridge-application */ - aos_bt_cfg_settings.ble_scan_cfg.scan_mode = settings->type; - aos_bt_cfg_settings.ble_scan_cfg.high_duty_scan_window = settings->window; - aos_bt_cfg_settings.ble_scan_cfg.high_duty_scan_duration = settings->duration_second; - aos_bt_cfg_settings.ble_scan_cfg.high_duty_scan_interval = settings->interval; - aos_bt_cfg_settings.ble_scan_cfg.scan_filter_policy = settings->filter_policy; + mico_bt_cfg_settings.ble_scan_cfg.scan_mode = settings->type; + mico_bt_cfg_settings.ble_scan_cfg.high_duty_scan_window = settings->window; + mico_bt_cfg_settings.ble_scan_cfg.high_duty_scan_duration = settings->duration_second; + mico_bt_cfg_settings.ble_scan_cfg.high_duty_scan_interval = settings->interval; + mico_bt_cfg_settings.ble_scan_cfg.scan_filter_policy = settings->filter_policy; duplicate_filter_enabled = settings->filter_duplicates; app_scan_complete_callback = complete_callback; app_scan_report_callback = advertising_report_callback; - return aos_bt_ble_scan( BTM_BLE_SCAN_TYPE_HIGH_DUTY, duplicate_filter_enabled, smartbridge_scan_result_callback ); + return mico_bt_ble_scan( BTM_BLE_SCAN_TYPE_HIGH_DUTY, duplicate_filter_enabled, smartbridge_scan_result_callback ); } -OSStatus smartbridge_bt_interface_connect( const aos_bt_smart_device_t *remote_device, - const aos_bt_smart_connection_settings_t *settings, aos_bt_smartbridge_disconnection_callback_t disconnection_callback, - aos_bt_smartbridge_notification_callback_t notification_callback ) +OSStatus smartbridge_bt_interface_connect( const mico_bt_smart_device_t *remote_device, + const mico_bt_smart_connection_settings_t *settings, + mico_bt_smartbridge_disconnection_callback_t disconnection_callback, + mico_bt_smartbridge_notification_callback_t notification_callback ) { - aos_bool_t gatt_connect_result; + mico_bool_t gatt_connect_result; UNUSED_PARAMETER(disconnection_callback); UNUSED_PARAMETER(notification_callback); /* Update the Stack's configuration */ - aos_bt_cfg_settings.ble_scan_cfg.conn_min_interval = settings->interval_min; - aos_bt_cfg_settings.ble_scan_cfg.conn_max_interval = settings->interval_max; - aos_bt_cfg_settings.ble_scan_cfg.conn_latency = settings->latency; - aos_bt_cfg_settings.ble_scan_cfg.conn_supervision_timeout = settings->supervision_timeout; + mico_bt_cfg_settings.ble_scan_cfg.conn_min_interval = settings->interval_min; + mico_bt_cfg_settings.ble_scan_cfg.conn_max_interval = settings->interval_max; + mico_bt_cfg_settings.ble_scan_cfg.conn_latency = settings->latency; + mico_bt_cfg_settings.ble_scan_cfg.conn_supervision_timeout = settings->supervision_timeout; /* Send connection request */ - gatt_connect_result = aos_bt_gatt_le_connect( (uint8_t *)remote_device->address, remote_device->address_type, - BLE_CONN_MODE_HIGH_DUTY, AOS_TRUE); + gatt_connect_result = mico_bt_gatt_le_connect( (uint8_t *)remote_device->address, remote_device->address_type, + BLE_CONN_MODE_HIGH_DUTY, MICO_TRUE); bt_smartbridge_log( "LE-connect, result:%d", gatt_connect_result ); @@ -884,6 +883,6 @@ OSStatus smartbridge_bt_interface_disconnect( uint16_t connection_handle ) /* First delete the previous scan result list */ smartbridge_helper_delete_scan_result_list(); - return aos_bt_gatt_disconnect( connection_handle ); + return mico_bt_gatt_disconnect( connection_handle ); } diff --git a/framework/bluetooth/smartbt/internal/bt_smartbridge_stack_interface.h b/device/bluetooth/mk3239/bt_smart/internal/bt_smartbridge_stack_interface.h similarity index 66% rename from framework/bluetooth/smartbt/internal/bt_smartbridge_stack_interface.h rename to device/bluetooth/mk3239/bt_smart/internal/bt_smartbridge_stack_interface.h index 46bb160758..3fc4b38e82 100644 --- a/framework/bluetooth/smartbt/internal/bt_smartbridge_stack_interface.h +++ b/device/bluetooth/mk3239/bt_smart/internal/bt_smartbridge_stack_interface.h @@ -1,18 +1,12 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#ifndef _BT_SMART_BRIDGE_STACK_INTERFACE_H_ -#define _BT_SMART_BRIDGE_STACK_INTERFACE_H_ - #pragma once /** @file * Smartbridge's Interface Header with Bluetooth Stack */ -#include "smartbt_smartbridge.h" -#include "smartbt_smart_interface.h" +//#include "mico_utilities.h" +#include "mico_bt_smartbridge.h" +#include "mico_bt_smart_interface.h" #ifdef __cplusplus extern "C" { @@ -45,7 +39,7 @@ typedef enum { SMARTBRIDGE_CONN_NONE, /**< No background connection */ SMARTBRIDGE_CONN_AUTO, /**< Auto connection */ SMARTBRIDGE_CONN_SELECTIVE /**< Selective connection */ -} aos_bt_smartbridge_auto_connection_type_t; +} mico_bt_smartbridge_auto_connection_type_t; /****************************************************** @@ -65,26 +59,27 @@ OSStatus smartbridge_bt_interface_deinitialize( void ); OSStatus smartbridge_bt_interface_stop_scan( void ); -OSStatus smartbridge_bt_interface_start_scan( const aos_bt_smart_scan_settings_t *setting, - aos_bt_smart_scan_complete_callback_t complete_callback, - aos_bt_smart_advertising_report_callback_t advertising_report_callback ); -aos_bool_t smartbridge_bt_interface_is_scanning( void ); +OSStatus smartbridge_bt_interface_start_scan( const mico_bt_smart_scan_settings_t *setting, + mico_bt_smart_scan_complete_callback_t complete_callback, + mico_bt_smart_advertising_report_callback_t advertising_report_callback ); +mico_bool_t smartbridge_bt_interface_is_scanning( void ); -OSStatus smartbridge_bt_interface_connect( const aos_bt_smart_device_t *remote_device, - const aos_bt_smart_connection_settings_t *settings, aos_bt_smartbridge_disconnection_callback_t disconnection_callback, - aos_bt_smartbridge_notification_callback_t notification_callback ); +OSStatus smartbridge_bt_interface_connect( const mico_bt_smart_device_t *remote_device, + const mico_bt_smart_connection_settings_t *settings, + mico_bt_smartbridge_disconnection_callback_t disconnection_callback, + mico_bt_smartbridge_notification_callback_t notification_callback ); -OSStatus smartbridge_bt_interface_cancel_last_connect( aos_bt_device_address_t address ); +OSStatus smartbridge_bt_interface_cancel_last_connect( mico_bt_device_address_t address ); OSStatus smartbridge_bt_interface_disconnect( uint16_t connection_handle ); -OSStatus smartbridge_bt_interface_update_background_connection_device( aos_bool_t add, - aos_bt_device_address_t device_address ); +OSStatus smartbridge_bt_interface_update_background_connection_device( mico_bool_t add, + mico_bt_device_address_t device_address ); OSStatus smartbridge_bt_interface_get_background_connection_device_size( uint8_t *size ); -OSStatus smartbridge_bt_interface_set_background_connection_type(aos_bt_smartbridge_auto_connection_type_t type, - const aos_bt_smart_scan_settings_t *settings, aos_bt_smartbridge_auto_connection_parms_cback_t ); +OSStatus smartbridge_bt_interface_set_background_connection_type(mico_bt_smartbridge_auto_connection_type_t type, + const mico_bt_smart_scan_settings_t *settings, mico_bt_smartbridge_auto_connection_parms_cback_t ); OSStatus smartbridge_bt_interface_set_attribute_timeout( uint32_t timeout_seconds ); @@ -94,41 +89,39 @@ OSStatus smartbridge_bt_interface_set_max_concurrent_connections( uint8_t count OSStatus smartbridge_bt_interface_discover_all_primary_services( uint16_t connection_handle, - aos_bt_smart_attribute_list_t *service_list ); + mico_bt_smart_attribute_list_t *service_list ); OSStatus smartbridge_bt_interface_discover_all_characteristics_in_a_service( uint16_t connection_handle, - uint16_t start_handle, uint16_t end_handle, aos_bt_smart_attribute_list_t *characteristic_list ); + uint16_t start_handle, uint16_t end_handle, mico_bt_smart_attribute_list_t *characteristic_list ); OSStatus smartbridge_bt_interface_discover_all_characteristic_descriptors( uint16_t connection_handle, - uint16_t start_handle, uint16_t end_handle, aos_bt_smart_attribute_list_t *no_value_descriptor_list ); + uint16_t start_handle, uint16_t end_handle, mico_bt_smart_attribute_list_t *no_value_descriptor_list ); OSStatus smartbridge_bt_interface_discover_primary_services_by_uuid( uint16_t connection_handle, - const aos_bt_uuid_t *uuid, aos_bt_smart_attribute_list_t *service_list ); + const mico_bt_uuid_t *uuid, mico_bt_smart_attribute_list_t *service_list ); OSStatus smartbridge_bt_interface_find_included_services( uint16_t connection_handle, uint16_t start_handle, - uint16_t end_handle, aos_bt_smart_attribute_list_t *include_list ); + uint16_t end_handle, mico_bt_smart_attribute_list_t *include_list ); OSStatus smartbridge_bt_interface_discover_characteristic_by_uuid( uint16_t connection_handle, - const aos_bt_uuid_t *uuid, uint16_t start_handle, uint16_t end_handle, - aos_bt_smart_attribute_list_t *characteristic_list ); + const mico_bt_uuid_t *uuid, uint16_t start_handle, uint16_t end_handle, + mico_bt_smart_attribute_list_t *characteristic_list ); OSStatus smartbridge_bt_interface_read_characteristic_value( uint16_t connection_handle, uint16_t handle, - const aos_bt_uuid_t *type, aos_bt_smart_attribute_t **characteristic_value ); + const mico_bt_uuid_t *type, mico_bt_smart_attribute_t **characteristic_value ); OSStatus smartbridge_bt_interface_read_long_characteristic_value( uint16_t connection_handle, uint16_t handle, - const aos_bt_uuid_t *type, aos_bt_smart_attribute_t **characteristic_value ); + const mico_bt_uuid_t *type, mico_bt_smart_attribute_t **characteristic_value ); OSStatus smartbridge_bt_interface_read_characteristic_descriptor( uint16_t connection_handle, uint16_t handle, - const aos_bt_uuid_t *uuid, aos_bt_smart_attribute_t **descriptor ); + const mico_bt_uuid_t *uuid, mico_bt_smart_attribute_t **descriptor ); OSStatus smartbridge_bt_interface_read_long_characteristic_descriptor( uint16_t connection_handle, uint16_t handle, - const aos_bt_uuid_t *uuid, aos_bt_smart_attribute_t **descriptor ); + const mico_bt_uuid_t *uuid, mico_bt_smart_attribute_t **descriptor ); OSStatus smartbridge_bt_interface_read_characteristic_values_using_uuid( uint16_t connection_handle, - const aos_bt_uuid_t *uuid, aos_bt_smart_attribute_list_t *characteristic_value_list ); + const mico_bt_uuid_t *uuid, mico_bt_smart_attribute_list_t *characteristic_value_list ); OSStatus smartbridge_bt_interface_write_characteristic_value( uint16_t connection_handle, - aos_bt_smart_attribute_t *attribute ); + mico_bt_smart_attribute_t *attribute ); OSStatus smartbridge_bt_interface_write_long_characteristic_value( uint16_t connection_handle, - aos_bt_smart_attribute_t *attribute ); + mico_bt_smart_attribute_t *attribute ); OSStatus smartbridge_bt_interface_write_long_characteristic_descriptor( uint16_t connection_handle, - const aos_bt_smart_attribute_t *descriptor ); + const mico_bt_smart_attribute_t *descriptor ); OSStatus smartbridge_bt_interface_write_characteristic_descriptor( uint16_t connection_handle, - aos_bt_smart_attribute_t *attribute ); + mico_bt_smart_attribute_t *attribute ); #ifdef __cplusplus } /* extern "C" */ #endif - -#endif diff --git a/framework/bluetooth/smartbt/bt_management.c b/device/bluetooth/mk3239/bt_smart/mico_bt_management.c similarity index 61% rename from framework/bluetooth/smartbt/bt_management.c rename to device/bluetooth/mk3239/bt_smart/mico_bt_management.c index 8105aeaa85..d4827f67b0 100644 --- a/framework/bluetooth/smartbt/bt_management.c +++ b/device/bluetooth/mk3239/bt_smart/mico_bt_management.c @@ -1,20 +1,20 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited + +/** @file + * */ -#include "smartbt.h" -#include "smartbt_smartbridge_constants.h" -#include "smartbt_smartbridge.h" -#include "aos_bt_types.h" -#include "aos_bt_stack.h" +#include "mico.h" +#include "mico_bt.h" +#include "mico_bt_smartbridge_constants.h" +#include "mico_bt_smartbridge.h" +#include "mico_bt_types.h" +#include "mico_bt_stack.h" #ifdef BT_MFGTEST_MODE #include "bt_mfgtest.h" #endif #include "bt_smartbridge_helper.h" #include "bt_smartbridge_stack_interface.h" #include "bt_smartbridge_socket_manager.h" -//#include "aosbt.h" -#include "os_wrapper.h" /****************************************************** * Macros @@ -25,11 +25,11 @@ ******************************************************/ /* Stack size and Queue size for BT Worker Thread */ -#define AOS_BT_WORKER_THREAD_STACK_SIZE (3 * 1024) -#define AOS_BT_WORKER_THREAD_QUEUE_SIZE 15 +#define MICO_BT_WORKER_THREAD_STACK_SIZE (3 * 1024) +#define MICO_BT_WORKER_THREAD_QUEUE_SIZE 15 /* Stack size and Queue size for BT Event Worker thread */ -#define AOS_BT_EVT_WORKER_THREAD_STACK_SIZE (3 * 1024) -#define AOS_BT_EVT_WORKER_THREAD_QUEUE_SIZE 15 +#define MICO_BT_EVT_WORKER_THREAD_STACK_SIZE (3 * 1024) +#define MICO_BT_EVT_WORKER_THREAD_QUEUE_SIZE 15 #define BT_DEVICE_NAME_MAX_LENGTH 21 @@ -52,192 +52,190 @@ * Static Function Declarations ******************************************************/ -static aos_bt_dev_status_t smartbridge_bt_stack_management_callback ( aos_bt_management_evt_t event, - aos_bt_management_evt_data_t *p_event_data ); +static mico_bt_dev_status_t smartbridge_bt_stack_management_callback ( mico_bt_management_evt_t event, + mico_bt_management_evt_data_t *p_event_data ); /****************************************************** * Variable Definitions ******************************************************/ -aos_worker_thread_t aos_bt_worker_thread; -aos_worker_thread_t aos_bt_evt_worker_thread; - -aos_bt_local_identity_keys_t local_identity_keys; -aos_bt_device_sec_keys_t device_link_keys; -aos_bool_t device_link_key_updated = AOS_FALSE; -extern aos_bt_cfg_settings_t aos_bt_cfg_settings; -extern aos_bt_dev_ble_io_caps_req_t default_io_caps_ble; -extern aos_bt_smartbridge_socket_t *connecting_socket; -extern aos_bt_peripheral_socket_t *connecting_peripheral_socket; -extern const aos_bt_cfg_buf_pool_t aos_bt_cfg_buf_pools[]; +mico_worker_thread_t mico_bt_worker_thread; +mico_worker_thread_t mico_bt_evt_worker_thread; + +mico_bt_local_identity_keys_t local_identity_keys; +mico_bt_device_sec_keys_t device_link_keys; +mico_bool_t device_link_key_updated = MICO_FALSE; +extern mico_bt_cfg_settings_t mico_bt_cfg_settings; +extern mico_bt_dev_ble_io_caps_req_t default_io_caps_ble; +extern mico_bt_smartbridge_socket_t *connecting_socket; +extern mico_bt_peripheral_socket_t *connecting_peripheral_socket; +extern const mico_bt_cfg_buf_pool_t mico_bt_cfg_buf_pools[]; static char bt_device_name[BT_DEVICE_NAME_MAX_LENGTH + 1] = { 0 }; -aos_bool_t bt_initialised = AOS_FALSE; -static aos_semaphore_t wait_bt_initialised_sem = NULL; -static aos_bt_device_address_t bt_address = { 0 }; +mico_bool_t bt_initialised = MICO_FALSE; +static mico_semaphore_t wait_bt_initialised_sem = NULL; +static mico_bt_device_address_t bt_address = { 0 }; -extern void peripheral_bt_interface_advertisements_state_change_callback( aos_bt_ble_advert_mode_t state ); -extern void smartbridge_auto_connection_encryption_check(const aos_bt_dev_pairing_cplt_t *p_event_data); +extern void peripheral_bt_interface_advertisements_state_change_callback( mico_bt_ble_advert_mode_t state ); +extern void smartbridge_auto_connection_encryption_check(const mico_bt_dev_pairing_cplt_t *p_event_data); /****************************************************** * Function Definitions ******************************************************/ -OSStatus aos_bt_init( aos_bt_mode_t mode, const char *device_name, uint8_t client_links, uint8_t server_links ) +OSStatus mico_bt_init( mico_bt_mode_t mode, const char *device_name, uint8_t client_links, uint8_t server_links ) { - OSStatus result = AOS_BT_SUCCESS; + OSStatus result = MICO_BT_SUCCESS; - if ( bt_initialised == AOS_TRUE ) { - return AOS_BT_SUCCESS; + if ( bt_initialised == MICO_TRUE ) { + return MICO_BT_SUCCESS; } bt_manager_log( "Initializing Bluetooth" ); - if ( mode == AOS_BT_MPAF_MODE ) { + if ( mode == MICO_BT_MPAF_MODE ) { bt_manager_log( "Error. MPAF-mode is not supported" ); - return AOS_BT_UNSUPPORTED; + return MICO_BT_UNSUPPORTED; } /* Create the BT Woker thread */ - result = aos_rtos_create_worker_thread(AOS_BT_WORKER_THREAD, - AOS_APPLICATION_PRIORITY, - AOS_BT_WORKER_THREAD_STACK_SIZE, - AOS_BT_WORKER_THREAD_QUEUE_SIZE); - if (result != oNoErr) { + result = mico_rtos_create_worker_thread(MICO_BT_WORKER_THREAD, + MICO_APPLICATION_PRIORITY, + MICO_BT_WORKER_THREAD_STACK_SIZE, + MICO_BT_WORKER_THREAD_QUEUE_SIZE); + if (result != kNoErr) { bt_smartbridge_log("Error creating BT WORKER THREAD"); goto exit; } /* Create the BT Event Woker thread */ - result = aos_rtos_create_worker_thread(AOS_BT_EVT_WORKER_THREAD, - AOS_APPLICATION_PRIORITY, - AOS_BT_EVT_WORKER_THREAD_STACK_SIZE, - AOS_BT_EVT_WORKER_THREAD_QUEUE_SIZE); - if (result != oNoErr) { + result = mico_rtos_create_worker_thread(MICO_BT_EVT_WORKER_THREAD, + MICO_APPLICATION_PRIORITY, + MICO_BT_EVT_WORKER_THREAD_STACK_SIZE, + MICO_BT_EVT_WORKER_THREAD_QUEUE_SIZE); + if (result != kNoErr) { bt_smartbridge_log("Error create BT EVT WORKER THREAD"); goto err1; } /* Initialise Bluetooth Stack */ wait_bt_initialised_sem = NULL; - aos_rtos_init_semaphore( &wait_bt_initialised_sem, 1 ); + mico_rtos_init_semaphore( &wait_bt_initialised_sem, 1 ); - aos_bt_cfg_settings.device_name = (uint8_t *)device_name; - aos_bt_cfg_settings.max_simultaneous_links = client_links + server_links; - aos_bt_cfg_settings.gatt_cfg.client_max_links = client_links; - aos_bt_cfg_settings.gatt_cfg.server_max_links = server_links; + mico_bt_cfg_settings.device_name = (uint8_t *)device_name; + mico_bt_cfg_settings.max_simultaneous_links = client_links + server_links; + mico_bt_cfg_settings.gatt_cfg.client_max_links = client_links; + mico_bt_cfg_settings.gatt_cfg.server_max_links = server_links; - result = aos_bt_stack_init( smartbridge_bt_stack_management_callback, &aos_bt_cfg_settings, aos_bt_cfg_buf_pools ); - if ( result != AOS_BT_SUCCESS ) { + result = mico_bt_stack_init( smartbridge_bt_stack_management_callback, &mico_bt_cfg_settings, mico_bt_cfg_buf_pools ); + if ( result != MICO_BT_SUCCESS ) { bt_smartbridge_log( "Error initialising Bluetooth stack" ); goto err2; } - aos_rtos_get_semaphore( &wait_bt_initialised_sem, AOS_NEVER_TIMEOUT ); - aos_rtos_deinit_semaphore( &wait_bt_initialised_sem ); + mico_rtos_get_semaphore( &wait_bt_initialised_sem, MICO_NEVER_TIMEOUT ); + mico_rtos_deinit_semaphore( &wait_bt_initialised_sem ); - aos_bt_dev_read_local_addr( bt_address ); + mico_bt_dev_read_local_addr( bt_address ); memset( bt_device_name, 0, sizeof( bt_device_name ) ); memcpy( bt_device_name, device_name, strnlen( device_name, BT_DEVICE_NAME_MAX_LENGTH ) ); - aos_rtos_delay_milliseconds(10); + mico_rtos_delay_milliseconds(10); - result = AOS_BT_SUCCESS; + result = MICO_BT_SUCCESS; goto exit; err2: - aos_rtos_deinit_semaphore( &wait_bt_initialised_sem ); - aos_rtos_delete_worker_thread(AOS_BT_EVT_WORKER_THREAD); + mico_rtos_deinit_semaphore( &wait_bt_initialised_sem ); + mico_rtos_delete_worker_thread(MICO_BT_EVT_WORKER_THREAD); err1: - aos_rtos_delete_worker_thread(AOS_BT_WORKER_THREAD); + mico_rtos_delete_worker_thread(MICO_BT_WORKER_THREAD); exit: return result; } -OSStatus aos_bt_deinit( void ) +OSStatus mico_bt_deinit( void ) { OSStatus result; - if ( bt_initialised == AOS_FALSE ) { - return AOS_BT_SUCCESS; + if ( bt_initialised == MICO_FALSE ) { + return MICO_BT_SUCCESS; } - result = aos_bt_stack_deinit( ); - if ( result != AOS_BT_SUCCESS ) { + result = mico_bt_stack_deinit( ); + if ( result != MICO_BT_SUCCESS ) { bt_manager_log( "Error de-initialising Bluetooth stack" ); return result; } - aos_rtos_delete_worker_thread(AOS_BT_WORKER_THREAD); - aos_rtos_delete_worker_thread(AOS_BT_EVT_WORKER_THREAD); + mico_rtos_delete_worker_thread(MICO_BT_WORKER_THREAD); + mico_rtos_delete_worker_thread(MICO_BT_EVT_WORKER_THREAD); memset( bt_device_name, 0, sizeof( bt_device_name ) ); - bt_initialised = AOS_FALSE; - return AOS_BT_SUCCESS; + bt_initialised = MICO_FALSE; + return MICO_BT_SUCCESS; } -OSStatus aos_bt_init_address( const aos_bt_device_address_t *address, const aos_bt_device_address_t *mask ) +OSStatus mico_bt_init_address( const mico_bt_device_address_t *address, const mico_bt_device_address_t *mask ) { UNUSED_PARAMETER(address); UNUSED_PARAMETER(mask); - return AOS_BT_UNSUPPORTED; + return MICO_BT_UNSUPPORTED; } -#if 0 -OSStatus aos_bt_start_mfgtest_mode( const aos_uart_config_t *config ) +OSStatus mico_bt_start_mfgtest_mode( const mico_uart_config_t *config ) { #ifdef BT_MFGTEST_MODE OSStatus result = bt_bus_init(); - if ( result != AOS_BT_SUCCESS ) { + if ( result != MICO_BT_SUCCESS ) { bt_manager_log( "Error initialising Bluetooth transport bus" ); return result; } return bt_mfgtest_start( config ); #else - return AOS_BT_UNSUPPORTED; + return MICO_BT_UNSUPPORTED; #endif } -#endif -OSStatus aos_bt_device_get_address( aos_bt_device_address_t *address ) +OSStatus mico_bt_device_get_address( mico_bt_device_address_t *address ) { - if ( bt_initialised == AOS_FALSE ) { - return AOS_BT_ERROR; + if ( bt_initialised == MICO_FALSE ) { + return MICO_BT_ERROR; } memcpy( address, &bt_address, sizeof( *address ) ); - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } -const char *aos_bt_device_get_name( void ) +const char *mico_bt_device_get_name( void ) { /* TODO: bt_device_name is not provided to Stack/Controller. Once it is provided to the Stack * correctly, we should rather read the name of the device from the Stack */ return (const char *)bt_device_name; } -aos_bool_t aos_bt_device_is_on( void ) +mico_bool_t mico_bt_device_is_on( void ) { /* TODO: Need to be implemented again as per the new Stack */ - return AOS_FALSE; + return MICO_FALSE; } -aos_bool_t aos_bt_device_is_connectable( void ) +mico_bool_t mico_bt_device_is_connectable( void ) { /* TODO : Need to be implemented for the new-stack */ - return AOS_FALSE; + return MICO_FALSE; } -aos_bool_t aos_bt_device_is_discoverable( void ) +mico_bool_t mico_bt_device_is_discoverable( void ) { /* TODO : Need to be implemented for the new-stack */ - return AOS_FALSE; + return MICO_FALSE; } -OSStatus aos_bt_start_pairing( aos_bt_device_address_t address, aos_bt_smart_address_type_t type, - const aos_bt_smart_security_settings_t *settings ) +OSStatus mico_bt_start_pairing( mico_bt_device_address_t address, mico_bt_smart_address_type_t type, + const mico_bt_smart_security_settings_t *settings ) { - OSStatus err = oNoErr; + OSStatus err = kNoErr; uint8_t integer_passkey[4] = { 0 }; /* update the security settings as per passed by the application */ @@ -248,66 +246,66 @@ OSStatus aos_bt_start_pairing( aos_bt_device_address_t address, aos_bt_smart_add default_io_caps_ble.init_keys = settings->master_key_distribution; default_io_caps_ble.resp_keys = settings->slave_key_distribution; - err = aos_bt_dev_sec_bond( address, type, BT_TRANSPORT_LE, 4, integer_passkey ); - bt_manager_log( "aos_bt_start_pairing, ret = %d", err ); + err = mico_bt_dev_sec_bond( address, type, BT_TRANSPORT_LE, 4, integer_passkey ); + bt_manager_log( "mico_bt_start_pairing, ret = %d", err ); return err; } -OSStatus aos_bt_stop_pairing( aos_bt_device_address_t address ) +OSStatus mico_bt_stop_pairing( mico_bt_device_address_t address ) { - OSStatus err = oNoErr; + OSStatus err = kNoErr; - err = aos_bt_dev_sec_bond_cancel( address ); - bt_manager_log( "aos_bt_stop_pairing, ret = %d", err ); + err = mico_bt_dev_sec_bond_cancel( address ); + bt_manager_log( "mico_bt_stop_pairing, ret = %d", err ); return err; } -OSStatus aos_bt_start_encryption( aos_bt_device_address_t *address ) +OSStatus mico_bt_start_encryption( mico_bt_device_address_t *address ) { - OSStatus err = oNoErr; + OSStatus err = kNoErr; uint32_t security_level = INTERNAL_SECURITY_LEVEL; - err = aos_bt_dev_set_encryption( *address, BT_TRANSPORT_LE, &security_level ); - bt_manager_log( "aos_bt_start_encryption, ret = %d", err ); + err = mico_bt_dev_set_encryption( *address, BT_TRANSPORT_LE, &security_level ); + bt_manager_log( "mico_bt_start_encryption, ret = %d", err ); return err; } -OSStatus aos_bt_clear_whitelist( void ) +OSStatus mico_bt_clear_whitelist( void ) { - if ( TRUE != aos_bt_ble_clear_white_list( ) ) { - return oGeneralErr; + if ( TRUE != mico_bt_ble_clear_white_list( ) ) { + return kGeneralErr; } - return oNoErr; + return kNoErr; } -OSStatus aos_bt_get_whitelist_capability( uint8_t *size ) +OSStatus mico_bt_get_whitelist_capability( uint8_t *size ) { if ( size == (uint8_t *)0 ) { - return oGeneralErr; + return kGeneralErr; } - if ( TRUE != aos_bt_ble_get_white_list_capability( size ) ) { - return oGeneralErr; + if ( TRUE != mico_bt_ble_get_white_list_capability( size ) ) { + return kGeneralErr; } - return oNoErr; + return kNoErr; } -static aos_bt_dev_status_t smartbridge_bt_stack_management_callback( aos_bt_management_evt_t event, - aos_bt_management_evt_data_t *p_event_data ) +static mico_bt_dev_status_t smartbridge_bt_stack_management_callback( mico_bt_management_evt_t event, + mico_bt_management_evt_data_t *p_event_data ) { - aos_bt_dev_status_t status = AOS_BT_SUCCESS; + mico_bt_dev_status_t status = MICO_BT_SUCCESS; BD_ADDR address; switch (event) { case BTM_ENABLED_EVT: { /* Initialize GATT REST API Server once Bluetooth controller and host stack is enabled */ - if ( ( status = p_event_data->enabled.status ) == AOS_BT_SUCCESS ) { - aos_bt_dev_read_local_addr(address); + if ( ( status = p_event_data->enabled.status ) == MICO_BT_SUCCESS ) { + mico_bt_dev_read_local_addr(address); bt_manager_log( "Local Bluetooth Address: [%02X:%02X:%02X:%02X:%02X:%02X]", address[0], address[1], address[2], address[3], address[4], address[5] ); /* Register for GATT event notifications */ - bt_initialised = AOS_TRUE; + bt_initialised = MICO_TRUE; if ( wait_bt_initialised_sem ) { - aos_rtos_set_semaphore( &wait_bt_initialised_sem ); + mico_rtos_set_semaphore( &wait_bt_initialised_sem ); } } break; @@ -315,36 +313,36 @@ static aos_bt_dev_status_t smartbridge_bt_stack_management_callback( aos_bt_mana case BTM_SECURITY_REQUEST_EVT: { bt_manager_log( "Security grant request" ); - aos_bt_ble_security_grant( p_event_data->security_request.bd_addr, AOS_BT_SUCCESS ); + mico_bt_ble_security_grant( p_event_data->security_request.bd_addr, MICO_BT_SUCCESS ); break; } case BTM_LOCAL_IDENTITY_KEYS_UPDATE_EVT: { - memcpy(&local_identity_keys, &p_event_data->local_identity_keys_update, sizeof( aos_bt_local_identity_keys_t ) ); + memcpy(&local_identity_keys, &p_event_data->local_identity_keys_update, sizeof( mico_bt_local_identity_keys_t ) ); bt_manager_log( "Local Identity Keys Update type:%u", local_identity_keys.local_key_data[0] ); break; } case BTM_LOCAL_IDENTITY_KEYS_REQUEST_EVT: { - memcpy( &p_event_data->local_identity_keys_request , &local_identity_keys, sizeof(aos_bt_local_identity_keys_t) ); + memcpy( &p_event_data->local_identity_keys_request , &local_identity_keys, sizeof(mico_bt_local_identity_keys_t) ); bt_manager_log( "Local Identity Keys Request Event" ); break; } case BTM_PAIRED_DEVICE_LINK_KEYS_UPDATE_EVT: { bt_manager_log( "Paired Device Link Keys Update Event" ); - memcpy(&device_link_keys, &p_event_data->paired_device_link_keys_request.key_data, sizeof(aos_bt_device_sec_keys_t)); - device_link_key_updated = AOS_TRUE; + memcpy(&device_link_keys, &p_event_data->paired_device_link_keys_request.key_data, sizeof(mico_bt_device_sec_keys_t)); + device_link_key_updated = MICO_TRUE; break; } case BTM_PAIRED_DEVICE_LINK_KEYS_REQUEST_EVT: { bt_manager_log( "Paired Device Link Keys Request Event" ); - if ( device_link_key_updated == AOS_TRUE ) { - memcpy( &p_event_data->paired_device_link_keys_request.key_data, &device_link_keys, sizeof(aos_bt_device_sec_keys_t)); - return AOS_BT_SUCCESS; + if ( device_link_key_updated == MICO_TRUE ) { + memcpy( &p_event_data->paired_device_link_keys_request.key_data, &device_link_keys, sizeof(mico_bt_device_sec_keys_t)); + return MICO_BT_SUCCESS; } - status = AOS_BT_ERROR; + status = MICO_BT_ERROR; break; } @@ -366,15 +364,15 @@ static aos_bt_dev_status_t smartbridge_bt_stack_management_callback( aos_bt_mana bt_manager_log( "Pairing complete status=%i, reason=0x%x.", p_event_data->pairing_complete.pairing_complete_info.ble.status, p_event_data->pairing_complete.pairing_complete_info.ble.reason ); - if ( p_event_data->pairing_complete.pairing_complete_info.ble.status == AOS_BT_SUCCESS ) { + if ( p_event_data->pairing_complete.pairing_complete_info.ble.status == MICO_BT_SUCCESS ) { } /* Notify app thread that pairing is complete, regardless of */ if ( connecting_socket && memcmp( p_event_data->pairing_complete.bd_addr, connecting_socket->remote_device.address, BD_ADDR_LEN ) == 0 ) { if ( smartbridge_helper_socket_check_actions_enabled( connecting_socket, - SOCKET_ACTION_INITIATE_PAIRING ) == AOS_TRUE ) { + SOCKET_ACTION_INITIATE_PAIRING ) == MICO_TRUE ) { if ( connecting_socket->semaphore ) { - aos_rtos_set_semaphore( &connecting_socket->semaphore ); + mico_rtos_set_semaphore( &connecting_socket->semaphore ); } } } @@ -383,9 +381,9 @@ static aos_bt_dev_status_t smartbridge_bt_stack_management_callback( aos_bt_mana memcmp( p_event_data->pairing_complete.bd_addr, connecting_peripheral_socket->remote_device.address, BD_ADDR_LEN ) == 0 ) { if ( peripheral_helper_socket_check_actions_enabled( connecting_peripheral_socket, - SOCKET_ACTION_INITIATE_PAIRING ) == AOS_TRUE ) { + SOCKET_ACTION_INITIATE_PAIRING ) == MICO_TRUE ) { if ( connecting_peripheral_socket->semaphore ) { - aos_rtos_set_semaphore( &connecting_peripheral_socket->semaphore ); + mico_rtos_set_semaphore( &connecting_peripheral_socket->semaphore ); } } } @@ -396,7 +394,7 @@ static aos_bt_dev_status_t smartbridge_bt_stack_management_callback( aos_bt_mana case BTM_ENCRYPTION_STATUS_EVT: { bt_manager_log( "encryption status = %i", p_event_data->encryption_status.result ); - if ( p_event_data->encryption_status.result == AOS_BT_SUCCESS ) { + if ( p_event_data->encryption_status.result == MICO_BT_SUCCESS ) { /* Update state of the socket to encrypted */ if ( connecting_socket ) { connecting_socket->state = SOCKET_STATE_LINK_ENCRYPTED; @@ -409,11 +407,12 @@ static aos_bt_dev_status_t smartbridge_bt_stack_management_callback( aos_bt_mana /* Notify app thread that pairing is complete, regardless of */ if ( connecting_socket && memcmp( p_event_data->pairing_complete.bd_addr, connecting_socket->remote_device.address, BD_ADDR_LEN ) == 0 ) { - if ( smartbridge_helper_socket_check_actions_enabled( connecting_socket, SOCKET_ACTION_INITIATE_PAIRING ) == AOS_TRUE || + if ( smartbridge_helper_socket_check_actions_enabled( connecting_socket, + SOCKET_ACTION_INITIATE_PAIRING ) == MICO_TRUE || smartbridge_helper_socket_check_actions_enabled( connecting_socket, - SOCKET_ACTION_ENCRYPT_USING_BOND_INFO ) == AOS_TRUE ) { + SOCKET_ACTION_ENCRYPT_USING_BOND_INFO ) == MICO_TRUE ) { if ( connecting_socket->semaphore ) { - aos_rtos_set_semaphore( &connecting_socket->semaphore ); + mico_rtos_set_semaphore( &connecting_socket->semaphore ); } } } @@ -422,11 +421,11 @@ static aos_bt_dev_status_t smartbridge_bt_stack_management_callback( aos_bt_mana memcmp( p_event_data->pairing_complete.bd_addr, connecting_peripheral_socket->remote_device.address, BD_ADDR_LEN ) == 0 ) { if ( peripheral_helper_socket_check_actions_enabled( connecting_peripheral_socket, - SOCKET_ACTION_INITIATE_PAIRING ) == AOS_TRUE || + SOCKET_ACTION_INITIATE_PAIRING ) == MICO_TRUE || peripheral_helper_socket_check_actions_enabled( connecting_peripheral_socket, - SOCKET_ACTION_ENCRYPT_USING_BOND_INFO ) == AOS_TRUE ) { + SOCKET_ACTION_ENCRYPT_USING_BOND_INFO ) == MICO_TRUE ) { if ( connecting_peripheral_socket->semaphore ) { - aos_rtos_set_semaphore( &connecting_peripheral_socket->semaphore ); + mico_rtos_set_semaphore( &connecting_peripheral_socket->semaphore ); } } break; @@ -459,13 +458,13 @@ static aos_bt_dev_status_t smartbridge_bt_stack_management_callback( aos_bt_mana BD_ADDR_LEN) == 0) { if (connecting_socket->bonding_callback && smartbridge_helper_socket_check_actions_enabled(connecting_socket, SOCKET_ACTION_INITIATE_PAIRING)) { - connecting_socket->bond_req.type = AOS_BT_SMART_BOND_PASS_KEY_NOTIFY; + connecting_socket->bond_req.type = MICO_BT_SMART_BOND_PASS_KEY_NOTIFY; connecting_socket->bond_req.u.notify.passkey = p_event_data->user_passkey_notification.passkey; memcpy(connecting_socket->bond_req.u.notify.addr, p_event_data->user_passkey_notification.bd_addr, 6); - aos_rtos_send_asynchronous_event(AOS_BT_EVT_WORKER_THREAD, - (event_handler_t)connecting_socket->bonding_callback, - (void *)&connecting_socket->bond_req); + mico_rtos_send_asynchronous_event(MICO_BT_EVT_WORKER_THREAD, + (event_handler_t)connecting_socket->bonding_callback, + (void *)&connecting_socket->bond_req); } } @@ -476,13 +475,13 @@ static aos_bt_dev_status_t smartbridge_bt_stack_management_callback( aos_bt_mana BD_ADDR_LEN) == 0) { if (connecting_peripheral_socket->bonding_callback && peripheral_helper_socket_check_actions_enabled(connecting_peripheral_socket, SOCKET_ACTION_INITIATE_PAIRING)) { - connecting_peripheral_socket->bond_req.type = AOS_BT_SMART_BOND_PASS_KEY_NOTIFY; + connecting_peripheral_socket->bond_req.type = MICO_BT_SMART_BOND_PASS_KEY_NOTIFY; connecting_peripheral_socket->bond_req.u.notify.passkey = p_event_data->user_passkey_notification.passkey; memcpy(connecting_peripheral_socket->bond_req.u.notify.addr, p_event_data->user_passkey_notification.bd_addr, 6); - aos_rtos_send_asynchronous_event(AOS_BT_EVT_WORKER_THREAD, - (event_handler_t)connecting_peripheral_socket->bonding_callback, - (void *)&connecting_peripheral_socket->bond_req); + mico_rtos_send_asynchronous_event(MICO_BT_EVT_WORKER_THREAD, + (event_handler_t)connecting_peripheral_socket->bonding_callback, + (void *)&connecting_peripheral_socket->bond_req); } } break; @@ -503,13 +502,13 @@ static aos_bt_dev_status_t smartbridge_bt_stack_management_callback( aos_bt_mana BD_ADDR_LEN) == 0) { if (connecting_socket->bonding_callback && smartbridge_helper_socket_check_actions_enabled(connecting_socket, SOCKET_ACTION_INITIATE_PAIRING)) { - connecting_socket->bond_req.type = AOS_BT_SMART_BOND_PASS_KEY_REQ; + connecting_socket->bond_req.type = MICO_BT_SMART_BOND_PASS_KEY_REQ; memcpy(connecting_socket->bond_req.u.passkey.addr, p_event_data->user_passkey_request.bd_addr, 6); - aos_rtos_send_asynchronous_event(AOS_BT_EVT_WORKER_THREAD, - (event_handler_t)connecting_socket->bonding_callback, - (void *)&connecting_socket->bond_req); + mico_rtos_send_asynchronous_event(MICO_BT_EVT_WORKER_THREAD, + (event_handler_t)connecting_socket->bonding_callback, + (void *)&connecting_socket->bond_req); } else { - aos_bt_dev_pass_key_req_reply(AOS_BT_ERROR, p_event_data->user_passkey_request.bd_addr, 0); + mico_bt_dev_pass_key_req_reply(MICO_BT_ERROR, p_event_data->user_passkey_request.bd_addr, 0); } } @@ -519,13 +518,13 @@ static aos_bt_dev_status_t smartbridge_bt_stack_management_callback( aos_bt_mana BD_ADDR_LEN) == 0) { if (connecting_peripheral_socket->bonding_callback && peripheral_helper_socket_check_actions_enabled(connecting_peripheral_socket, SOCKET_ACTION_INITIATE_PAIRING)) { - connecting_peripheral_socket->bond_req.type = AOS_BT_SMART_BOND_PASS_KEY_REQ; + connecting_peripheral_socket->bond_req.type = MICO_BT_SMART_BOND_PASS_KEY_REQ; memcpy(connecting_peripheral_socket->bond_req.u.passkey.addr, p_event_data->user_passkey_request.bd_addr, 6); - aos_rtos_send_asynchronous_event(AOS_BT_EVT_WORKER_THREAD, - (event_handler_t)connecting_peripheral_socket->bonding_callback, - (void *)&connecting_peripheral_socket->bond_req); + mico_rtos_send_asynchronous_event(MICO_BT_EVT_WORKER_THREAD, + (event_handler_t)connecting_peripheral_socket->bonding_callback, + (void *)&connecting_peripheral_socket->bond_req); } else { - aos_bt_dev_pass_key_req_reply(AOS_BT_ERROR, p_event_data->user_passkey_request.bd_addr, 0); + mico_bt_dev_pass_key_req_reply(MICO_BT_ERROR, p_event_data->user_passkey_request.bd_addr, 0); } } break; @@ -548,14 +547,14 @@ static aos_bt_dev_status_t smartbridge_bt_stack_management_callback( aos_bt_mana BD_ADDR_LEN) == 0) { if (connecting_socket->bonding_callback && smartbridge_helper_socket_check_actions_enabled(connecting_socket, SOCKET_ACTION_INITIATE_PAIRING)) { - connecting_socket->bond_req.type = AOS_BT_SMART_BOND_USR_CONFIRM_REQ; + connecting_socket->bond_req.type = MICO_BT_SMART_BOND_USR_CONFIRM_REQ; connecting_socket->bond_req.u.confirm.passkey = p_event_data->user_confirmation_request.numeric_value; memcpy(connecting_socket->bond_req.u.confirm.addr, p_event_data->user_confirmation_request.bd_addr, 6); - aos_rtos_send_asynchronous_event(AOS_BT_EVT_WORKER_THREAD, - (event_handler_t)connecting_socket->bonding_callback, - (void *)&connecting_socket->bond_req); + mico_rtos_send_asynchronous_event(MICO_BT_EVT_WORKER_THREAD, + (event_handler_t)connecting_socket->bonding_callback, + (void *)&connecting_socket->bond_req); } else { - aos_bt_dev_confirm_req_reply(AOS_BT_ERROR, p_event_data->user_confirmation_request.bd_addr); + mico_bt_dev_confirm_req_reply(MICO_BT_ERROR, p_event_data->user_confirmation_request.bd_addr); } } @@ -565,14 +564,14 @@ static aos_bt_dev_status_t smartbridge_bt_stack_management_callback( aos_bt_mana BD_ADDR_LEN) == 0) { if (connecting_peripheral_socket->bonding_callback && peripheral_helper_socket_check_actions_enabled(connecting_peripheral_socket, SOCKET_ACTION_INITIATE_PAIRING)) { - connecting_peripheral_socket->bond_req.type = AOS_BT_SMART_BOND_USR_CONFIRM_REQ; + connecting_peripheral_socket->bond_req.type = MICO_BT_SMART_BOND_USR_CONFIRM_REQ; connecting_peripheral_socket->bond_req.u.confirm.passkey = p_event_data->user_confirmation_request.numeric_value; memcpy(connecting_peripheral_socket->bond_req.u.confirm.addr, p_event_data->user_confirmation_request.bd_addr, 6); - aos_rtos_send_asynchronous_event(AOS_BT_EVT_WORKER_THREAD, - (event_handler_t)connecting_peripheral_socket->bonding_callback, - (void *)&connecting_peripheral_socket->bond_req); + mico_rtos_send_asynchronous_event(MICO_BT_EVT_WORKER_THREAD, + (event_handler_t)connecting_peripheral_socket->bonding_callback, + (void *)&connecting_peripheral_socket->bond_req); } else { - aos_bt_dev_confirm_req_reply(AOS_BT_ERROR, p_event_data->user_confirmation_request.bd_addr); + mico_bt_dev_confirm_req_reply(MICO_BT_ERROR, p_event_data->user_confirmation_request.bd_addr); } } break; @@ -594,13 +593,13 @@ static aos_bt_dev_status_t smartbridge_bt_stack_management_callback( aos_bt_mana BD_ADDR_LEN) == 0) { if (connecting_socket->bonding_callback && smartbridge_helper_socket_check_actions_enabled(connecting_socket, SOCKET_ACTION_INITIATE_PAIRING)) { - connecting_socket->bond_req.type = AOS_BT_SMART_BOND_OOB_DATA_REQ; + connecting_socket->bond_req.type = MICO_BT_SMART_BOND_OOB_DATA_REQ; memcpy(connecting_socket->bond_req.u.oob_data.addr, p_event_data->smp_remote_oob_data_request.bd_addr, 6); - aos_rtos_send_asynchronous_event(AOS_BT_EVT_WORKER_THREAD, - (event_handler_t)connecting_socket->bonding_callback, - (void *)&connecting_socket->bond_req); + mico_rtos_send_asynchronous_event(MICO_BT_EVT_WORKER_THREAD, + (event_handler_t)connecting_socket->bonding_callback, + (void *)&connecting_socket->bond_req); } else { - aos_bt_smp_oob_data_reply(p_event_data->smp_remote_oob_data_request.bd_addr, AOS_BT_ERROR, 0, NULL); + mico_bt_smp_oob_data_reply(p_event_data->smp_remote_oob_data_request.bd_addr, MICO_BT_ERROR, 0, NULL); } } @@ -610,13 +609,13 @@ static aos_bt_dev_status_t smartbridge_bt_stack_management_callback( aos_bt_mana BD_ADDR_LEN) == 0) { if (connecting_peripheral_socket->bonding_callback && peripheral_helper_socket_check_actions_enabled(connecting_peripheral_socket, SOCKET_ACTION_INITIATE_PAIRING)) { - connecting_peripheral_socket->bond_req.type = AOS_BT_SMART_BOND_OOB_DATA_REQ; + connecting_peripheral_socket->bond_req.type = MICO_BT_SMART_BOND_OOB_DATA_REQ; memcpy(connecting_peripheral_socket->bond_req.u.oob_data.addr, p_event_data->smp_remote_oob_data_request.bd_addr, 6); - aos_rtos_send_asynchronous_event(AOS_BT_EVT_WORKER_THREAD, - (event_handler_t)connecting_peripheral_socket->bonding_callback, - (void *)&connecting_peripheral_socket->bond_req); + mico_rtos_send_asynchronous_event(MICO_BT_EVT_WORKER_THREAD, + (event_handler_t)connecting_peripheral_socket->bonding_callback, + (void *)&connecting_peripheral_socket->bond_req); } else { - aos_bt_smp_oob_data_reply(p_event_data->smp_remote_oob_data_request.bd_addr, AOS_BT_ERROR, 0, NULL); + mico_bt_smp_oob_data_reply(p_event_data->smp_remote_oob_data_request.bd_addr, MICO_BT_ERROR, 0, NULL); } } break; @@ -633,42 +632,42 @@ static aos_bt_dev_status_t smartbridge_bt_stack_management_callback( aos_bt_mana return status; } -/** aos_bt_smart_bond_reply +/** mico_bt_smart_bond_reply * - * This function is called to reply BLE Bond Event posted by #aos_bt_smart_bonding_callback_t. - * You should fill a strcutre #aos_bt_smart_bond_reply_t to complete this bonding procedure. + * This function is called to reply BLE Bond Event posted by #mico_bt_smart_bonding_callback_t. + * You should fill a strcutre #mico_bt_smart_bond_reply_t to complete this bonding procedure. * * @param[in] response the response to current bonding event. * * @return OSStatus */ -OSStatus aos_bt_smart_bond_reply(const aos_bt_smart_bond_reply_t *response) +OSStatus mico_bt_smart_bond_reply(const mico_bt_smart_bond_reply_t *response) { - OSStatus err = oNoErr; + OSStatus err = kNoErr; if (!response) { - return oParamErr; + return kParamErr; } switch (response->type) { - case AOS_BT_SMART_BOND_PASS_KEY_REQ: - aos_bt_dev_pass_key_req_reply(response->res, - (uint8_t *)response->u.passkey.addr, - response->u.passkey.passkey); + case MICO_BT_SMART_BOND_PASS_KEY_REQ: + mico_bt_dev_pass_key_req_reply(response->res, + (uint8_t *)response->u.passkey.addr, + response->u.passkey.passkey); break; - case AOS_BT_SMART_BOND_USR_CONFIRM_REQ: - aos_bt_dev_confirm_req_reply(response->res, (uint8_t *)response->u.confirm.addr); + case MICO_BT_SMART_BOND_USR_CONFIRM_REQ: + mico_bt_dev_confirm_req_reply(response->res, (uint8_t *)response->u.confirm.addr); break; #if (BTM_OOB_INCLUDED == TRUE) - case AOS_BT_SMART_BOND_OOB_DATA_REQ: - aos_bt_smp_oob_data_reply((uint8_t *)response->u.oob_data.addr, - response->res, - response->u.oob_data.len, - response->u.oob_data.data); + case MICO_BT_SMART_BOND_OOB_DATA_REQ: + mico_bt_smp_oob_data_reply((uint8_t *)response->u.oob_data.addr, + response->res, + response->u.oob_data.len, + response->u.oob_data.data); break; #endif default: - err = oParamErr; + err = kParamErr; break; } diff --git a/framework/bluetooth/smartbt/bt_peripheral.c b/device/bluetooth/mk3239/bt_smart/mico_bt_peripheral.c similarity index 64% rename from framework/bluetooth/smartbt/bt_peripheral.c rename to device/bluetooth/mk3239/bt_smart/mico_bt_peripheral.c index 1c107c7d4d..dd356d7a76 100644 --- a/framework/bluetooth/smartbt/bt_peripheral.c +++ b/device/bluetooth/mk3239/bt_smart/mico_bt_peripheral.c @@ -1,20 +1,19 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited +/** @file + * */ - -//#include "aosbt.h" -#include "os_wrapper.h" +#include "mico.h" #include "StringUtils.h" -#include "smartbt_peripheral.h" +#include "mico_bt_peripheral.h" -#include "aos_bt_gatt.h" -#include "aos_bt_ble.h" -#include "smartbt_cfg.h" +#include "mico_bt_gatt.h" +#include "mico_bt_ble.h" +#include "mico_bt_cfg.h" -#include "smartbt.h" +#include "mico_bt.h" #include "bt_smartbridge_socket_manager.h" #include "bt_smartbridge_helper.h" #include "bt_peripheral_stack_interface.h" +#include "mico_bt_cfg.h" /****************************************************** * Macros @@ -53,12 +52,12 @@ static OSStatus peripheral_app_disconnection_handler ( void *arg ); extern gatt_subprocedure_t peripheral_subprocedure; -aos_bt_peripheral_socket_t *peripheral_socket = NULL; -static aos_bool_t initialised = AOS_FALSE; -extern aos_bool_t bt_initialised; -extern aos_bt_dev_ble_io_caps_req_t local_io_caps_ble; +mico_bt_peripheral_socket_t *peripheral_socket = NULL; +static mico_bool_t initialised = MICO_FALSE; +extern mico_bool_t bt_initialised; +extern mico_bt_dev_ble_io_caps_req_t local_io_caps_ble; -aos_bt_peripheral_socket_t *connecting_peripheral_socket = NULL; +mico_bt_peripheral_socket_t *connecting_peripheral_socket = NULL; /****************************************************** * Function Definitions @@ -68,7 +67,8 @@ static void peripheral_gatt_connection_handler( uint16_t connection_handle ) { bt_peripheral_log( "GATT connection was SUCCESS" ); - aos_rtos_send_asynchronous_event( AOS_BT_WORKER_THREAD, peripheral_app_connection_handler, (void *)peripheral_socket ); + mico_rtos_send_asynchronous_event( MICO_BT_WORKER_THREAD, peripheral_app_connection_handler, + (void *)peripheral_socket ); } static void peripheral_gatt_disconnection_handler( uint16_t connection_handle ) @@ -84,43 +84,40 @@ static void peripheral_gatt_disconnection_handler( uint16_t connection_handle ) peripheral_socket->state = SOCKET_STATE_DISCONNECTED; /* Check if disconnection is from host or remote device */ - if ( peripheral_helper_socket_check_actions_enabled( peripheral_socket, SOCKET_ACTION_HOST_DISCONNECT ) == AOS_TRUE ) { + if ( peripheral_helper_socket_check_actions_enabled( peripheral_socket, SOCKET_ACTION_HOST_DISCONNECT ) == MICO_TRUE ) { /* Disconnection is originated from the host. Notify app thread that disconnection is complete */ - aos_rtos_set_semaphore( &peripheral_socket->semaphore ); + mico_rtos_set_semaphore( &peripheral_socket->semaphore ); } else { /* Notify app that connection is disconnected by the remote device */ if ( peripheral_socket->disconnection_callback != NULL ) { - aos_rtos_send_asynchronous_event( AOS_BT_EVT_WORKER_THREAD, peripheral_app_disconnection_handler, - (void *)peripheral_socket ); + mico_rtos_send_asynchronous_event( MICO_BT_EVT_WORKER_THREAD, peripheral_app_disconnection_handler, + (void *)peripheral_socket ); } /* If disconnection happens when connection is still being established. Notify app */ if ( connecting_peripheral_socket == peripheral_socket ) { - aos_rtos_set_semaphore( &connecting_peripheral_socket->semaphore ); + mico_rtos_set_semaphore( &connecting_peripheral_socket->semaphore ); } } } else { /* If disconnection happens when connection is still being established. Notify app */ if ( connecting_peripheral_socket != NULL ) { - aos_rtos_set_semaphore( &connecting_peripheral_socket->semaphore ); + mico_rtos_set_semaphore( &connecting_peripheral_socket->semaphore ); } } } -#ifndef MIN -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#endif -static aos_bt_gatt_status_t peripheral_gatt_read_request_handler( aos_bt_gatt_read_t *request_data ) +static mico_bt_gatt_status_t peripheral_gatt_read_request_handler( mico_bt_gatt_read_t *request_data ) { - aos_bt_ext_attribute_value_t *attribute; - aos_bt_gatt_status_t status = AOS_BT_GATT_SUCCESS; + mico_bt_ext_attribute_value_t *attribute; + mico_bt_gatt_status_t status = MICO_BT_GATT_SUCCESS; // Find characteristic value - if ( aos_bt_peripheral_ext_attribute_find_by_handle( request_data->handle, &attribute ) == oNoErr ) { + if ( mico_bt_peripheral_ext_attribute_find_by_handle( request_data->handle, &attribute ) == kNoErr ) { /* Invoke attribute_handler before real read request, prepare attribute data if needed */ if ( attribute->attribute_handler != NULL ) { /* Invock callback only once per attribute read */ - if ( request_data->offset == 0 ) { //|| request_data->is_long == AOS_FALSE ) + if ( request_data->offset == 0 ) { //|| request_data->is_long == MICO_FALSE ) status = ( attribute->attribute_handler )( attribute, GATTS_REQ_TYPE_READ ); } } @@ -134,26 +131,26 @@ static aos_bt_gatt_status_t peripheral_gatt_read_request_handler( aos_bt_gatt_re *(request_data->p_val_len) ); } } else { - status = AOS_BT_GATT_READ_NOT_PERMIT; + status = MICO_BT_GATT_READ_NOT_PERMIT; } return status; } -aos_bt_gatt_status_t bt_peripheral_gatt_callback( aos_bt_gatt_evt_t event, aos_bt_gatt_event_data_t *p_event_data ) +mico_bt_gatt_status_t bt_peripheral_gatt_callback( mico_bt_gatt_evt_t event, mico_bt_gatt_event_data_t *p_event_data ) { - aos_bt_ext_attribute_value_t *attribute; + mico_bt_ext_attribute_value_t *attribute; - aos_bt_gatt_status_t status = AOS_BT_GATT_SUCCESS; + mico_bt_gatt_status_t status = MICO_BT_GATT_SUCCESS; switch (event) { case GATT_CONNECTION_STATUS_EVT: { if ( p_event_data->connection_status.link_role == BT_SMART_LINK_ROLE_SLAVE ) { /* Connection */ - if ( p_event_data->connection_status.connected == AOS_TRUE ) { + if ( p_event_data->connection_status.connected == MICO_TRUE ) { /* Store remote device information */ connecting_peripheral_socket = peripheral_socket; memcpy( &peripheral_socket->remote_device.address, p_event_data->connection_status.bd_addr, BD_ADDR_LEN ); - peripheral_socket->remote_device.address_type = (aos_bt_smart_address_type_t)p_event_data->connection_status.addr_type; + peripheral_socket->remote_device.address_type = (mico_bt_smart_address_type_t)p_event_data->connection_status.addr_type; peripheral_socket->connection_handle = p_event_data->connection_status.conn_id; peripheral_socket->state = SOCKET_STATE_LINK_CONNECTED; peripheral_gatt_connection_handler( p_event_data->connection_status.conn_id ); @@ -167,21 +164,21 @@ aos_bt_gatt_status_t bt_peripheral_gatt_callback( aos_bt_gatt_evt_t event, aos_b case GATT_ATTRIBUTE_REQUEST_EVT: { /* GATT attribute read/write request */ if ( p_event_data->attribute_request.request_type == GATTS_REQ_TYPE_WRITE ) { - if ( p_event_data->attribute_request.data.write_req.is_prep == AOS_TRUE ) { + if ( p_event_data->attribute_request.data.write_req.is_prep == MICO_TRUE ) { bt_peripheral_log("Not implement"); break; } - if ( aos_bt_peripheral_ext_attribute_find_by_handle( p_event_data->attribute_request.data.handle, - &attribute ) == oNoErr ) { - aos_bt_peripheral_ext_attribute_value_write( attribute, p_event_data->attribute_request.data.write_req.val_len, - p_event_data->attribute_request.data.write_req.offset, p_event_data->attribute_request.data.write_req.p_val ); + if ( mico_bt_peripheral_ext_attribute_find_by_handle( p_event_data->attribute_request.data.handle, + &attribute ) == kNoErr ) { + mico_bt_peripheral_ext_attribute_value_write( attribute, p_event_data->attribute_request.data.write_req.val_len, + p_event_data->attribute_request.data.write_req.offset, p_event_data->attribute_request.data.write_req.p_val ); if ( attribute->attribute_handler != NULL ) { status = (attribute->attribute_handler)( attribute, GATTS_REQ_TYPE_WRITE ); } } else { - status = AOS_BT_GATT_WRITE_NOT_PERMIT; + status = MICO_BT_GATT_WRITE_NOT_PERMIT; } break; @@ -210,26 +207,26 @@ aos_bt_gatt_status_t bt_peripheral_gatt_callback( aos_bt_gatt_evt_t event, aos_b return status; } -OSStatus aos_bt_peripheral_init( aos_bt_peripheral_socket_t *socket, - const aos_bt_smart_security_settings_t *settings, - aos_bt_peripheral_connection_callback_t connection_callback, - aos_bt_peripheral_disconnection_callback_t disconnection_callback, - aos_bt_smart_bonding_callback_t bonding_callback ) +OSStatus mico_bt_peripheral_init( mico_bt_peripheral_socket_t *socket, + const mico_bt_smart_security_settings_t *settings, + mico_bt_peripheral_connection_callback_t connection_callback, + mico_bt_peripheral_disconnection_callback_t disconnection_callback, + mico_bt_smart_bonding_callback_t bonding_callback ) { OSStatus result; - if ( initialised == AOS_TRUE ) { - return AOS_BT_SUCCESS; + if ( initialised == MICO_TRUE ) { + return MICO_BT_SUCCESS; } - bt_peripheral_log( "Initialising AOS Smart preipheral ..." ); + bt_peripheral_log( "Initialising MICO Smart preipheral ..." ); /* Reset socket fields */ memset( socket, 0, sizeof( *socket ) ); socket->connection_handle = SOCKET_INVALID_CONNECTION_HANDLE; /* Initialise socket semaphore */ - result = aos_rtos_init_semaphore( &socket->semaphore, 1 ); + result = mico_rtos_init_semaphore( &socket->semaphore, 1 ); require_noerr(result, exit); /* Initialise callbacks */ @@ -265,15 +262,15 @@ OSStatus aos_bt_peripheral_init( aos_bt_peripheral_socket_t //TODO use a different interface!!! peripheral_bt_interface_initialize(); - initialised = AOS_TRUE; + initialised = MICO_TRUE; exit: return result; } -OSStatus aos_bt_peripheral_deinit( void ) +OSStatus mico_bt_peripheral_deinit( void ) { - if ( initialised == AOS_FALSE ) { - return AOS_BT_SUCCESS; + if ( initialised == MICO_FALSE ) { + return MICO_BT_SUCCESS; } peripheral_socket = NULL; @@ -282,46 +279,46 @@ OSStatus aos_bt_peripheral_deinit( void ) //TODO use a different interface!!! peripheral_bt_interface_deinitialize(); - initialised = AOS_FALSE; + initialised = MICO_FALSE; - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } -OSStatus aos_bt_peripheral_delete_socket( aos_bt_peripheral_socket_t *socket ) +OSStatus mico_bt_peripheral_delete_socket( mico_bt_peripheral_socket_t *socket ) { OSStatus result; - if ( initialised == AOS_FALSE ) { - return AOS_BT_SMART_APPL_UNINITIALISED; + if ( initialised == MICO_FALSE ) { + return MICO_BT_SMART_APPL_UNINITIALISED; } - result = aos_rtos_deinit_semaphore( &socket->semaphore ); - if ( result != AOS_BT_SUCCESS ) { + result = mico_rtos_deinit_semaphore( &socket->semaphore ); + if ( result != MICO_BT_SUCCESS ) { return result; } memset( socket, 0, sizeof( *socket ) ); socket->connection_handle = SOCKET_INVALID_CONNECTION_HANDLE; - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } -OSStatus aos_bt_peripheral_disconnect( void ) +OSStatus mico_bt_peripheral_disconnect( void ) { - if ( initialised == AOS_FALSE ) { - return AOS_BT_SMART_APPL_UNINITIALISED; + if ( initialised == MICO_FALSE ) { + return MICO_BT_SMART_APPL_UNINITIALISED; } /* Mark disconnection flag that it's coming from the host */ peripheral_helper_socket_set_actions( peripheral_socket, SOCKET_ACTION_HOST_DISCONNECT ); /* Clean-up accidentally set semaphores */ - while ( aos_rtos_get_semaphore( &peripheral_socket->semaphore, AOS_NO_WAIT ) == AOS_BT_SUCCESS ) { + while ( mico_rtos_get_semaphore( &peripheral_socket->semaphore, MICO_NO_WAIT ) == MICO_BT_SUCCESS ) { } /* Check if either link is encrypted or connected */ if ( peripheral_socket->state >= SOCKET_STATE_LINK_CONNECTED ) { peripheral_bt_interface_disconnect( peripheral_socket->connection_handle ); /* Wait for disconnection */ - aos_rtos_get_semaphore( &peripheral_socket->semaphore, 5 * 1000 ); + mico_rtos_get_semaphore( &peripheral_socket->semaphore, 5 * 1000 ); } else { /* Link is not yet connected. Cancel last */ peripheral_bt_interface_cancel_last_connect( peripheral_socket->remote_device.address ); @@ -339,47 +336,47 @@ OSStatus aos_bt_peripheral_disconnect( void ) peripheral_socket->state = SOCKET_STATE_DISCONNECTED; } - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } -OSStatus aos_bt_peripheral_gatt_indicate_attribute_value ( aos_bt_peripheral_socket_t *socket, - const aos_bt_ext_attribute_value_t *attribute ) +OSStatus mico_bt_peripheral_gatt_indicate_attribute_value ( mico_bt_peripheral_socket_t *socket, + const mico_bt_ext_attribute_value_t *attribute ) { - aos_bt_peripheral_socket_status_t status; + mico_bt_peripheral_socket_status_t status; - if ( initialised == AOS_FALSE ) { - return AOS_BT_SMART_APPL_UNINITIALISED; + if ( initialised == MICO_FALSE ) { + return MICO_BT_SMART_APPL_UNINITIALISED; } if ( socket == NULL || attribute == NULL ) { - return AOS_BT_BADARG; + return MICO_BT_BADARG; } - aos_bt_peripheral_get_socket_status( socket, &status ); + mico_bt_peripheral_get_socket_status( socket, &status ); if ( status != PERIPHERAL_SOCKET_CONNECTED ) { - return AOS_BT_SOCKET_NOT_CONNECTED; + return MICO_BT_SOCKET_NOT_CONNECTED; } return peripheral_bt_interface_indicate_attribute_value( socket->connection_handle, attribute ); } -OSStatus aos_bt_peripheral_gatt_notify_attribute_value ( aos_bt_peripheral_socket_t *socket, - const aos_bt_ext_attribute_value_t *attribute ) +OSStatus mico_bt_peripheral_gatt_notify_attribute_value ( mico_bt_peripheral_socket_t *socket, + const mico_bt_ext_attribute_value_t *attribute ) { - aos_bt_peripheral_socket_status_t status; + mico_bt_peripheral_socket_status_t status; - if ( initialised == AOS_FALSE ) { - return AOS_BT_SMART_APPL_UNINITIALISED; + if ( initialised == MICO_FALSE ) { + return MICO_BT_SMART_APPL_UNINITIALISED; } if ( socket == NULL || attribute == NULL ) { - return AOS_BT_BADARG; + return MICO_BT_BADARG; } - aos_bt_peripheral_get_socket_status( socket, &status ); + mico_bt_peripheral_get_socket_status( socket, &status ); if ( status != PERIPHERAL_SOCKET_CONNECTED ) { - return AOS_BT_SOCKET_NOT_CONNECTED; + return MICO_BT_SOCKET_NOT_CONNECTED; } return peripheral_bt_interface_notify_attribute_value( socket->connection_handle, attribute ); @@ -389,56 +386,56 @@ OSStatus aos_bt_peripheral_gatt_notify_attribute_value ( aos_bt_peripheral_socke -OSStatus aos_bt_peripheral_start_advertisements( aos_bt_smart_advertising_settings_t *settings, - aos_bt_smart_advertising_complete_callback_t complete_callback) +OSStatus mico_bt_peripheral_start_advertisements( mico_bt_smart_advertising_settings_t *settings, + mico_bt_smart_advertising_complete_callback_t complete_callback) { return peripheral_bt_interface_start_advertisements( settings, complete_callback ); } -OSStatus aos_bt_peripheral_stop_advertisements( void ) +OSStatus mico_bt_peripheral_stop_advertisements( void ) { return peripheral_bt_interface_stop_advertisements(); } -OSStatus aos_bt_peripheral_update_advertisements_white_list( aos_bool_t add, aos_bt_device_address_t device_address ) +OSStatus mico_bt_peripheral_update_advertisements_white_list( mico_bool_t add, mico_bt_device_address_t device_address ) { - if ( initialised == AOS_FALSE ) { - return oNotInitializedErr; + if ( initialised == MICO_FALSE ) { + return kNotInitializedErr; } return peripheral_bt_interface_update_advertisements_white_list( add, device_address ); } -OSStatus aos_bt_peripheral_get_advertisements_white_list_size( uint8_t *size ) +OSStatus mico_bt_peripheral_get_advertisements_white_list_size( uint8_t *size ) { - if ( initialised == AOS_FALSE ) { - return oNotInitializedErr; + if ( initialised == MICO_FALSE ) { + return kNotInitializedErr; } if ( size == (uint8_t *)0 ) { - return oParamErr; + return kParamErr; } return peripheral_bt_interface_get_advertisements_white_list_size( size ); } -OSStatus aos_bt_peripheral_set_advertisements_filter_policy( aos_bt_peripheral_adv_filter_policy_t policy ) +OSStatus mico_bt_peripheral_set_advertisements_filter_policy( mico_bt_peripheral_adv_filter_policy_t policy ) { - if ( initialised == AOS_FALSE ) { - return oNotInitializedErr; + if ( initialised == MICO_FALSE ) { + return kNotInitializedErr; } return peripheral_bt_interface_set_advertisements_filter_policy( policy ); } -OSStatus aos_bt_peripheral_get_socket_status( aos_bt_peripheral_socket_t *socket, - aos_bt_peripheral_socket_status_t *status ) +OSStatus mico_bt_peripheral_get_socket_status( mico_bt_peripheral_socket_t *socket, + mico_bt_peripheral_socket_status_t *status ) { - if ( initialised == AOS_FALSE ) { - return AOS_BT_SMART_APPL_UNINITIALISED; + if ( initialised == MICO_FALSE ) { + return MICO_BT_SMART_APPL_UNINITIALISED; } if ( socket->state == SOCKET_STATE_LINK_ENCRYPTED ) { *status = PERIPHERAL_SOCKET_CONNECTED; } else if ( socket->state == SOCKET_STATE_LINK_CONNECTED ) { /* Status is connected if socket does not have loaded bond info and does not initiate pairing */ - // if ( smartbridge_helper_socket_check_actions_disabled( server_socket, SOCKET_ACTION_ENCRYPT_USING_BOND_INFO | SOCKET_ACTION_INITIATE_PAIRING ) == AOS_TRUE ) + // if ( smartbridge_helper_socket_check_actions_disabled( server_socket, SOCKET_ACTION_ENCRYPT_USING_BOND_INFO | SOCKET_ACTION_INITIATE_PAIRING ) == MICO_TRUE ) // { *status = PERIPHERAL_SOCKET_CONNECTED; // } @@ -450,51 +447,51 @@ OSStatus aos_bt_peripheral_get_socket_status( aos_bt_peripheral_socket_t *socket *status = PERIPHERAL_SOCKET_DISCONNECTED; } - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } static OSStatus bt_peripheral_get_buffer( void **buffer, uint32_t size ) { - OSStatus err = oNoErr; - require_action( buffer != NULL, exit, err = oParamErr ); + OSStatus err = kNoErr; + require_action( buffer != NULL, exit, err = kParamErr ); /* Allocate buffer object */ *buffer = malloc( size ); - require_action( *buffer != NULL, exit, err = oNoMemoryErr); + require_action( *buffer != NULL, exit, err = kNoMemoryErr); exit: return err; } static OSStatus bt_peripheral_resize_buffer( void **buffer, uint32_t size ) { - OSStatus err = oNoErr; - require_action( buffer != NULL, exit, err = oParamErr ); + OSStatus err = kNoErr; + require_action( buffer != NULL, exit, err = kParamErr ); /* Allocate buffer object */ *buffer = realloc( *buffer, size ); - require_action( *buffer != NULL, exit, err = oNoMemoryErr); + require_action( *buffer != NULL, exit, err = kNoMemoryErr); exit: return err; } static OSStatus bt_peripheral_release_buffer( void *buffer ) { - OSStatus err = oNoErr; - require_action( buffer != NULL, exit, err = oParamErr ); + OSStatus err = kNoErr; + require_action( buffer != NULL, exit, err = kParamErr ); free( buffer ); exit: return err; } -aos_bt_ext_attribute_value_t *aos_bt_peripheral_ext_attribute_add( uint16_t handle, uint16_t value_length, - const uint8_t *value, aos_bt_peripheral_attribute_handler handler ) +mico_bt_ext_attribute_value_t *mico_bt_peripheral_ext_attribute_add( uint16_t handle, uint16_t value_length, + const uint8_t *value, mico_bt_peripheral_attribute_handler handler ) { - aos_bt_ext_attribute_value_t *new_attribite = NULL; - OSStatus err = oNoErr; + mico_bt_ext_attribute_value_t *new_attribite = NULL; + OSStatus err = kNoErr; void *value_buffer; - require_action( initialised == AOS_TRUE, exit, err = oNotInitializedErr ); + require_action( initialised == MICO_TRUE, exit, err = kNotInitializedErr ); /* Get buffer */ - err = bt_peripheral_get_buffer( (void **)&new_attribite, sizeof( aos_bt_ext_attribute_value_t ) ); + err = bt_peripheral_get_buffer( (void **)&new_attribite, sizeof( mico_bt_ext_attribute_value_t ) ); require_noerr(err, exit); /* Copy content to buffer */ @@ -521,21 +518,21 @@ aos_bt_ext_attribute_value_t *aos_bt_peripheral_ext_attribute_add( uint16_t hand /* Add to socket */ err = linked_list_insert_node_at_rear( &peripheral_socket->attribute_database, &new_attribite->this_node ); - require_noerr_action(err, exit, bt_peripheral_release_buffer( (void *)new_attribite )); + require_noerr_action(err, exit, bt_peripheral_release_buffer( (void *)new_attribite );); exit: - if ( err != oNoErr && new_attribite ) { - aos_bt_peripheral_ext_attribute_remove( new_attribite ); + if ( err != kNoErr && new_attribite ) { + mico_bt_peripheral_ext_attribute_remove( new_attribite ); new_attribite = NULL; } return new_attribite; } -OSStatus aos_bt_peripheral_ext_attribute_remove( aos_bt_ext_attribute_value_t *attribute ) +OSStatus mico_bt_peripheral_ext_attribute_remove( mico_bt_ext_attribute_value_t *attribute ) { - OSStatus err = oNoErr; + OSStatus err = kNoErr; - require_action( initialised == AOS_TRUE, exit, err = oNotInitializedErr ); + require_action( initialised == MICO_TRUE, exit, err = kNotInitializedErr ); /* Remove characteristic from service */ err = linked_list_remove_node( &peripheral_socket->attribute_database, &attribute->this_node ); @@ -555,12 +552,12 @@ OSStatus aos_bt_peripheral_ext_attribute_remove( aos_bt_ext_attribute_value_t *a return err; } -OSStatus aos_bt_peripheral_ext_attribute_value_write( aos_bt_ext_attribute_value_t *attribute, uint16_t length, - uint16_t offset, const uint8_t *value ) +OSStatus mico_bt_peripheral_ext_attribute_value_write( mico_bt_ext_attribute_value_t *attribute, uint16_t length, + uint16_t offset, const uint8_t *value ) { - OSStatus err = oNoErr; + OSStatus err = kNoErr; - require_action( initialised == AOS_TRUE, exit, err = oNotInitializedErr ); + require_action( initialised == MICO_TRUE, exit, err = kNotInitializedErr ); if ( attribute->p_value == NULL ) { /* Allocate buffer for value */ @@ -584,7 +581,7 @@ OSStatus aos_bt_peripheral_ext_attribute_value_write( aos_bt_ext_attribute_value static bool compare_attribute_by_handle( linked_list_node_t *node_to_compare, void *user_data ) { - aos_bt_ext_attribute_value_t *current_attribute = (aos_bt_ext_attribute_value_t *)node_to_compare; + mico_bt_ext_attribute_value_t *current_attribute = (mico_bt_ext_attribute_value_t *)node_to_compare; uint16_t attribute_handle = (uint16_t)( (uint32_t)user_data & 0xffff ); if ( current_attribute->handle == attribute_handle ) { @@ -594,12 +591,12 @@ static bool compare_attribute_by_handle( linked_list_node_t *node_to_compare, vo } } -OSStatus aos_bt_peripheral_ext_attribute_find_by_handle( uint16_t handle, - aos_bt_ext_attribute_value_t **attribute_found ) +OSStatus mico_bt_peripheral_ext_attribute_find_by_handle( uint16_t handle, + mico_bt_ext_attribute_value_t **attribute_found ) { - OSStatus err = oNoErr; + OSStatus err = kNoErr; - require_action( ( initialised == AOS_TRUE ) && ( attribute_found != NULL ), exit, err = oParamErr ); + require_action( ( initialised == MICO_TRUE ) && ( attribute_found != NULL ), exit, err = kParamErr ); err = linked_list_find_node( &peripheral_socket->attribute_database, compare_attribute_by_handle, (void *)( handle & 0xffffffff ), (linked_list_node_t **)attribute_found ); @@ -614,42 +611,42 @@ OSStatus aos_bt_peripheral_ext_attribute_find_by_handle( uint16_t handle, static OSStatus peripheral_app_connection_handler( void *arg ) { - aos_bt_peripheral_socket_t *socket = (aos_bt_peripheral_socket_t *)arg; + mico_bt_peripheral_socket_t *socket = (mico_bt_peripheral_socket_t *)arg; /* Performing PAIRING & ENCRYPTION Procedure */ if (peripheral_helper_socket_check_actions_enabled(socket, SOCKET_ACTION_INITIATE_PAIRING)) { - if (aos_bt_dev_find_bonded_device(socket->remote_device.address)) { - aos_bt_start_encryption(&socket->remote_device.address); + if (mico_bt_dev_find_bonded_device(socket->remote_device.address)) { + mico_bt_start_encryption(&socket->remote_device.address); } else { - aos_bt_start_pairing(socket->remote_device.address, socket->remote_device.address_type, &socket->security_settings); - aos_rtos_get_semaphore(&socket->semaphore, AOS_NEVER_TIMEOUT); - aos_bt_start_encryption(&socket->remote_device.address); + mico_bt_start_pairing(socket->remote_device.address, socket->remote_device.address_type, &socket->security_settings); + mico_rtos_get_semaphore(&socket->semaphore, MICO_NEVER_TIMEOUT); + mico_bt_start_encryption(&socket->remote_device.address); } - aos_rtos_get_semaphore(&socket->semaphore, AOS_NEVER_TIMEOUT); + mico_rtos_get_semaphore(&socket->semaphore, MICO_NEVER_TIMEOUT); } /* Finished */ connecting_peripheral_socket = NULL; if ( socket != NULL && socket->connection_callback != NULL ) { - return aos_rtos_send_asynchronous_event( AOS_BT_EVT_WORKER_THREAD, - (event_handler_t)socket->connection_callback, - (void *)socket ); + return mico_rtos_send_asynchronous_event( MICO_BT_EVT_WORKER_THREAD, + (event_handler_t)socket->connection_callback, + (void *)socket ); } - return AOS_BT_ERROR; + return MICO_BT_ERROR; } static OSStatus peripheral_app_disconnection_handler( void *arg ) { - aos_bt_peripheral_socket_t *socket = (aos_bt_peripheral_socket_t *)arg; + mico_bt_peripheral_socket_t *socket = (mico_bt_peripheral_socket_t *)arg; if ( socket != NULL && socket->disconnection_callback != NULL ) { socket->disconnection_callback( socket ); - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } - return AOS_BT_ERROR; + return MICO_BT_ERROR; } diff --git a/framework/bluetooth/smartbt/bt_smartbridge.c b/device/bluetooth/mk3239/bt_smart/mico_bt_smartbridge.c similarity index 68% rename from framework/bluetooth/smartbt/bt_smartbridge.c rename to device/bluetooth/mk3239/bt_smart/mico_bt_smartbridge.c index 5b16806569..2025fc3c0a 100644 --- a/framework/bluetooth/smartbt/bt_smartbridge.c +++ b/device/bluetooth/mk3239/bt_smart/mico_bt_smartbridge.c @@ -1,25 +1,20 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited +/** @file + * */ - +#include "mico.h" #include "StringUtils.h" -#include "smartbt_smartbridge.h" +#include "mico_bt_smartbridge.h" -#include "aos_bt_gatt.h" -#include "aos_bt_ble.h" -#include "smartbt_cfg.h" +#include "mico_bt_gatt.h" +#include "mico_bt_ble.h" +#include "mico_bt_cfg.h" -#include "smartbt.h" +#include "mico_bt.h" #include "bt_smartbridge_socket_manager.h" #include "bt_smartbridge_att_cache_manager.h" #include "bt_smartbridge_helper.h" #include "bt_smartbridge_stack_interface.h" -#ifndef MIN -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#endif - - /****************************************************** * Macros ******************************************************/ @@ -70,9 +65,9 @@ typedef struct { /* Local auto connection settings */ typedef struct { - aos_bt_smartbridge_socket_t + mico_bt_smartbridge_socket_t *socket; /**< A socket associated with the auto connection */ - aos_bt_smart_connection_settings_t + mico_bt_smart_connection_settings_t conn_settings; /**< The connection settings associated with a socket */ smartbridge_auto_conn_dev_info_t device_info; /**< The scanned device information */ } smartbridge_auto_conn_entity_t; @@ -80,14 +75,14 @@ typedef struct { /* Device info ready to connect */ typedef struct { linked_list_node_t this_node; /* Linked-list node of this device */ - aos_bt_smart_advertising_report_t report; /* Remote BT device */ + mico_bt_smart_advertising_report_t report; /* Remote BT device */ smartbridge_auto_conn_state_t state; /* Auto-connection state */ } smartbridge_auto_conn_report_t; /* Device info ready to connect */ typedef struct { linked_list_t list; - aos_mutex_t mutex; + mico_mutex_t mutex; } smartbridge_auto_conn_list_t; /****************************************************** @@ -101,46 +96,46 @@ typedef struct { static OSStatus smartbridge_app_notification_handler ( void *arg ); static OSStatus smartbridge_app_disconnection_handler ( void *arg ); -static void smartbridge_gatt_auto_conn_handler ( aos_bt_device_address_t bdaddr, +static void smartbridge_gatt_auto_conn_handler ( mico_bt_device_address_t bdaddr, uint16_t connection_handle ); -static aos_bool_t smartbridge_gap_auto_conn_user_cfg ( const aos_bt_device_address_t device_address, - const uint8_t *device_name, const uint8_t *p_data, uint8_t length ); +static mico_bool_t smartbridge_gap_auto_conn_user_cfg ( const mico_bt_device_address_t device_address, + const uint8_t *device_name, const uint8_t *p_data, uint8_t length ); static OSStatus smartbridge_gap_auto_conn_asyn_event_handler ( void *arg ); -static OSStatus smartbridge_gap_auto_conn_scan_report_handler ( const aos_bt_smart_advertising_report_t *report ); +static OSStatus smartbridge_gap_auto_conn_scan_report_handler ( const mico_bt_smart_advertising_report_t *report ); static OSStatus smartbridge_gap_auto_conn_scan_cmpl_handler ( void *arg ); static OSStatus smartbridge_gap_auto_conn_cryption ( void *arg ); static OSStatus smartbridge_auto_conn_user_parms ( void *arg ); static int8_t smartbridge_auto_conn_dev_alloc ( void ); -static int8_t smartbridge_auto_conn_find_dev_by_addr ( const aos_bt_device_address_t device_address ); +static int8_t smartbridge_auto_conn_find_dev_by_addr ( const mico_bt_device_address_t device_address ); static OSStatus smartbridge_auto_conn_list_init ( void ); static OSStatus smartbridge_auto_conn_list_deinit ( void ); -static OSStatus smartbridge_auto_conn_list_add ( const aos_bt_smart_advertising_report_t *report ); -static OSStatus smartbridge_auto_conn_list_remove ( aos_bt_device_address_t bdaddr ); +static OSStatus smartbridge_auto_conn_list_add ( const mico_bt_smart_advertising_report_t *report ); +static OSStatus smartbridge_auto_conn_list_remove ( mico_bt_device_address_t bdaddr ); static OSStatus smartbridge_auto_conn_list_clear ( void ); static OSStatus smartbridge_auto_conn_list_remove_by_state ( smartbridge_auto_conn_state_t state ); -static OSStatus smartbridge_auto_conn_list_set_state ( const aos_bt_device_address_t bdaddr, +static OSStatus smartbridge_auto_conn_list_set_state ( const mico_bt_device_address_t bdaddr, smartbridge_auto_conn_state_t state ); -static OSStatus smartbridge_auto_conn_list_get_by_state ( aos_bt_smart_advertising_report_t **report, +static OSStatus smartbridge_auto_conn_list_get_by_state ( mico_bt_smart_advertising_report_t **report, smartbridge_auto_conn_state_t state ); /****************************************************** * Variable Definitions ******************************************************/ -aos_bt_smartbridge_socket_t *connecting_socket = NULL; -static aos_bool_t initialised = AOS_FALSE; -extern aos_bool_t bt_initialised; -extern aos_bt_dev_ble_io_caps_req_t local_io_caps_ble; +mico_bt_smartbridge_socket_t *connecting_socket = NULL; +static mico_bool_t initialised = MICO_FALSE; +extern mico_bool_t bt_initialised; +extern mico_bt_dev_ble_io_caps_req_t local_io_caps_ble; extern gatt_subprocedure_t smartbridge_subprocedure; -aos_bt_gatt_char_declaration_t current_characteristic; +mico_bt_gatt_char_declaration_t current_characteristic; /** Auto Connection Establishment Procedure */ -static aos_semaphore_t g_auto_conn_sem = NULL; +static mico_semaphore_t g_auto_conn_sem = NULL; static smartbridge_auto_conn_entity_t g_auto_conn_dev_table[BTM_BLE_MAX_BG_CONN_DEV_NUM]; -static aos_bt_smartbridge_auto_connection_parms_cback_t g_auto_conn_cback = NULL; -static aos_bt_smart_scan_settings_t g_auto_conn_scan_cfg; +static mico_bt_smartbridge_auto_connection_parms_cback_t g_auto_conn_cback = NULL; +static mico_bt_smart_scan_settings_t g_auto_conn_scan_cfg; static uint16_t g_auto_conn_scan_duration = 0; static smartbridge_auto_conn_list_t g_auto_conn_list; @@ -160,13 +155,13 @@ static void smartbridge_gatt_connection_handler( uint16_t connection_handle ) bt_smartbridge_socket_manager_insert_socket( connecting_socket ); /* Notify app thread that link is connected */ - aos_sem_signal( &connecting_socket->semaphore ); + mico_rtos_set_semaphore( &connecting_socket->semaphore ); } -static void smartbridge_gatt_auto_conn_handler( aos_bt_device_address_t bdaddr, uint16_t connection_handle ) +static void smartbridge_gatt_auto_conn_handler( mico_bt_device_address_t bdaddr, uint16_t connection_handle ) { int8_t idx = 0; - aos_bt_smartbridge_socket_t *p_socket; + mico_bt_smartbridge_socket_t *p_socket; bt_smartbridge_log("Auto connection [%02x:%02x:%02x:%02x:%02x:%02x] established.", bdaddr[0], bdaddr[1], bdaddr[2], bdaddr[3], bdaddr[4], bdaddr[5]); @@ -195,17 +190,17 @@ static void smartbridge_gatt_auto_conn_handler( aos_bt_device_address_t bdaddr, bt_smartbridge_socket_manager_insert_socket(p_socket); /* Tell smartbridge_gap_auto_conn_asyn_event_handler a connection is ready. */ - aos_sem_signal(&g_auto_conn_sem); + mico_rtos_set_semaphore(&g_auto_conn_sem); } static void smartbridge_gatt_disconnection_handler( uint16_t connection_handle ) { bt_smartbridge_log( "GATT disconnection" ); - aos_bt_smartbridge_socket_t *removed_socket = NULL; + mico_bt_smartbridge_socket_t *removed_socket = NULL; /* Remove socket from the connected list */ - if ( bt_smartbridge_socket_manager_remove_socket( connection_handle, &removed_socket ) == AOS_BT_SUCCESS ) { + if ( bt_smartbridge_socket_manager_remove_socket( connection_handle, &removed_socket ) == MICO_BT_SUCCESS ) { /* Reset connection handle to invalid value */ removed_socket->connection_handle = SOCKET_INVALID_CONNECTION_HANDLE; @@ -213,39 +208,39 @@ static void smartbridge_gatt_disconnection_handler( uint16_t connection_handle ) removed_socket->state = SOCKET_STATE_DISCONNECTED; /* Mark att cache as inactive and reset reference to cache */ - bt_smartbridge_att_cache_set_active_state( (bt_smartbridge_att_cache_t *)removed_socket->att_cache, AOS_FALSE ); + bt_smartbridge_att_cache_set_active_state( (bt_smartbridge_att_cache_t *)removed_socket->att_cache, MICO_FALSE ); removed_socket->att_cache = NULL; /* Check if disconnection is from host or remote device */ - if ( smartbridge_helper_socket_check_actions_enabled( removed_socket, SOCKET_ACTION_HOST_DISCONNECT ) == AOS_TRUE ) { + if ( smartbridge_helper_socket_check_actions_enabled( removed_socket, SOCKET_ACTION_HOST_DISCONNECT ) == MICO_TRUE ) { /* Disconnection is originated from the host. Notify app thread that disconnection is complete */ - aos_sem_signal( &removed_socket->semaphore ); + mico_rtos_set_semaphore( &removed_socket->semaphore ); } else { /* Notify app that connection is disconnected by the remote device */ if ( removed_socket->disconnection_callback != NULL ) { - aos_rtos_send_asynchronous_event( AOS_BT_EVT_WORKER_THREAD, smartbridge_app_disconnection_handler, - (void *)removed_socket ); + mico_rtos_send_asynchronous_event( MICO_BT_EVT_WORKER_THREAD, smartbridge_app_disconnection_handler, + (void *)removed_socket ); } /* If disconnection happens when connection is still being established. Notify app */ if ( connecting_socket == removed_socket ) { - aos_sem_signal( &connecting_socket->semaphore ); + mico_rtos_set_semaphore( &connecting_socket->semaphore ); } } } else { /* If disconnection happens when connection is still being established. Notify app */ if ( connecting_socket != NULL ) { - aos_sem_signal( &connecting_socket->semaphore ); + mico_rtos_set_semaphore( &connecting_socket->semaphore ); } } } -static void smartbridge_gatt_read_operation_complete_handler( aos_bt_gatt_data_t *response_data ) +static void smartbridge_gatt_read_operation_complete_handler( mico_bt_gatt_data_t *response_data ) { - aos_bt_smart_attribute_t *attr; + mico_bt_smart_attribute_t *attr; uint8_t *data = NULL; /* Create a new attribute */ - aos_bt_smart_attribute_create( &attr, AOS_ATTRIBUTE_TYPE_CHARACTERISTIC_VALUE, response_data->len ); + mico_bt_smart_attribute_create( &attr, MICO_ATTRIBUTE_TYPE_CHARACTERISTIC_VALUE, response_data->len ); if ( attr != NULL ) { attr->next = NULL; @@ -266,13 +261,13 @@ static void smartbridge_gatt_read_operation_complete_handler( aos_bt_gatt_data_t memcpy( &attr->value, data, attr->value_length ); } - //memcpy( &attr->type, &subprocedure.uuid, sizeof(aos_bt_uuid_t)); + //memcpy( &attr->type, &subprocedure.uuid, sizeof(mico_bt_uuid_t)); /* Update temporary variables */ if ( smartbridge_subprocedure.attr_head == NULL ) { smartbridge_subprocedure.attr_head = attr; } - smartbridge_subprocedure.result = AOS_BT_SUCCESS; + smartbridge_subprocedure.result = MICO_BT_SUCCESS; char *debug_str = NULL; @@ -286,14 +281,15 @@ static void smartbridge_gatt_read_operation_complete_handler( aos_bt_gatt_data_t free( debug_str ); } } else { - smartbridge_subprocedure.result = AOS_BT_OUT_OF_HEAP_SPACE; + smartbridge_subprocedure.result = MICO_BT_OUT_OF_HEAP_SPACE; } } -static OSStatus smartbridge_gatt_notification_indication_handler( aos_bt_gatt_operation_complete_t *operation_complete ) +static OSStatus smartbridge_gatt_notification_indication_handler( mico_bt_gatt_operation_complete_t + *operation_complete ) { - aos_bt_smartbridge_socket_t *socket; + mico_bt_smartbridge_socket_t *socket; uint16_t connection_handle = operation_complete->conn_id; uint16_t attribute_handle = operation_complete->response_data.att_value.handle; uint8_t *data = operation_complete->response_data.att_value.p_data; @@ -306,18 +302,18 @@ static OSStatus smartbridge_gatt_notification_indication_handler( aos_bt_gatt_op /* Send Indication ACK to peer device. */ if ( operation_complete->op == GATTC_OPTYPE_INDICATION ) { bt_smartbridge_log("Confirm peer device's INDICATION"); - if ( aos_bt_gatt_send_indication_confirm( connection_handle, attribute_handle ) != 0 ) { + if ( mico_bt_gatt_send_indication_confirm( connection_handle, attribute_handle ) != 0 ) { bt_smartbridge_log("Send INDICATION confirm failed!!!"); } } /* Search for socket with indicated connection handle in the connected list */ - if ( bt_smartbridge_socket_manager_find_socket_by_handle( connection_handle, &socket ) == AOS_BT_SUCCESS ) { - if ( bt_smartbridge_att_cache_is_enabled() == AOS_TRUE && socket->att_cache != NULL ) { + if ( bt_smartbridge_socket_manager_find_socket_by_handle( connection_handle, &socket ) == MICO_BT_SUCCESS ) { + if ( bt_smartbridge_att_cache_is_enabled() == MICO_TRUE && socket->att_cache != NULL ) { bt_smartbridge_att_cache_t *cache = (bt_smartbridge_att_cache_t *)socket->att_cache; - aos_bt_smart_attribute_list_t *att_cache_list = NULL; - aos_bt_smart_attribute_t *att = NULL; + mico_bt_smart_attribute_list_t *att_cache_list = NULL; + mico_bt_smart_attribute_t *att = NULL; bt_smartbridge_att_cache_get_list( cache, &att_cache_list ); @@ -325,19 +321,19 @@ static OSStatus smartbridge_gatt_notification_indication_handler( aos_bt_gatt_op bt_smartbridge_att_cache_lock( cache ); /* Search for att in the socket's att list */ - if ( aos_bt_smart_attribute_search_list_by_handle( att_cache_list, attribute_handle, &att ) == AOS_BT_SUCCESS ) { - aos_bt_uuid_t uuid = att->type; - aos_bool_t is_new_att = AOS_FALSE; + if ( mico_bt_smart_attribute_search_list_by_handle( att_cache_list, attribute_handle, &att ) == MICO_BT_SUCCESS ) { + mico_bt_uuid_t uuid = att->type; + mico_bool_t is_new_att = MICO_FALSE; /* Check if existing att memory length is sufficient */ if ( length > att->value_length ) { /* length isn't sufficient. Remove existing from the list */ - aos_bt_smart_attribute_remove_from_list( att_cache_list, attribute_handle ); + mico_bt_smart_attribute_remove_from_list( att_cache_list, attribute_handle ); att = NULL; /* Create a new one and marked as new */ - aos_bt_smart_attribute_create( &att, AOS_ATTRIBUTE_TYPE_CHARACTERISTIC_VALUE, length ); - is_new_att = AOS_TRUE; + mico_bt_smart_attribute_create( &att, MICO_ATTRIBUTE_TYPE_CHARACTERISTIC_VALUE, length ); + is_new_att = MICO_TRUE; } /* Copy new value to the att */ @@ -346,9 +342,9 @@ static OSStatus smartbridge_gatt_notification_indication_handler( aos_bt_gatt_op att->value_length = length; memcpy( att->value.value, data, length ); - if ( is_new_att == AOS_TRUE ) { + if ( is_new_att == MICO_TRUE ) { /* Add newly created att to the list */ - aos_bt_smart_attribute_add_to_list( att_cache_list, att ); + mico_bt_smart_attribute_add_to_list( att_cache_list, att ); } } @@ -360,27 +356,27 @@ static OSStatus smartbridge_gatt_notification_indication_handler( aos_bt_gatt_op /* Notification callback is called regardless of att cache is enabled or not */ if ( socket->notification_callback != NULL ) { - if ( oNoErr != aos_rtos_send_asynchronous_event( AOS_BT_EVT_WORKER_THREAD, smartbridge_app_notification_handler, - (void *)socket ) ) { + if ( kNoErr != mico_rtos_send_asynchronous_event( MICO_BT_EVT_WORKER_THREAD, smartbridge_app_notification_handler, + (void *)socket ) ) { bt_smartbridge_log("Send asynchronous event for INDICATION/NOTIFICATION handler failed!!!"); - return AOS_BT_ERROR; + return MICO_BT_ERROR; } } - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } else { bt_smartbridge_log("Unknown connection handle: 0x%04x", connection_handle); } - return AOS_BT_ERROR; + return MICO_BT_ERROR; } -static void smartbridge_gatt_discover_characteristic_descriptor_result( aos_bt_gatt_event_data_t *p_event_data ) +static void smartbridge_gatt_discover_characteristic_descriptor_result( mico_bt_gatt_event_data_t *p_event_data ) { /* Create attribute(s) based on information included in the response PDU */ - aos_bt_smart_attribute_t *attr; + mico_bt_smart_attribute_t *attr; - aos_bt_smart_attribute_create( &attr, AOS_ATTRIBUTE_TYPE_NO_VALUE, 0 ); + mico_bt_smart_attribute_create( &attr, MICO_ATTRIBUTE_TYPE_NO_VALUE, 0 ); if ( attr != NULL ) { attr->next = NULL; @@ -412,12 +408,12 @@ static void smartbridge_gatt_discover_characteristic_descriptor_result( aos_bt_g } } -static void smartbridge_gatt_discover_services_result( aos_bt_gatt_event_data_t *p_event_data ) +static void smartbridge_gatt_discover_services_result( mico_bt_gatt_event_data_t *p_event_data ) { /* Create attribute(s) based on information included in the response PDU */ - aos_bt_smart_attribute_t *attr; + mico_bt_smart_attribute_t *attr; - aos_bt_smart_attribute_create( &attr, AOS_ATTRIBUTE_TYPE_PRIMARY_SERVICE, 0 ); + mico_bt_smart_attribute_create( &attr, MICO_ATTRIBUTE_TYPE_PRIMARY_SERVICE, 0 ); if ( attr != NULL ) { attr->next = NULL; @@ -429,7 +425,7 @@ static void smartbridge_gatt_discover_services_result( aos_bt_gatt_event_data_t attr->value.service.end_handle = p_event_data->discovery_result.discovery_data.group_value.e_handle; memcpy( &attr->value.service.uuid, &p_event_data->discovery_result.discovery_data.group_value.service_type, - sizeof(aos_bt_uuid_t) ); + sizeof(mico_bt_uuid_t) ); if ( smartbridge_subprocedure.attr_head == NULL ) { smartbridge_subprocedure.attr_head = attr; @@ -449,13 +445,13 @@ static void smartbridge_gatt_discover_services_result( aos_bt_gatt_event_data_t } } -static void smartbridge_gatt_discover_included_services_result( aos_bt_gatt_event_data_t *p_event_data ) +static void smartbridge_gatt_discover_included_services_result( mico_bt_gatt_event_data_t *p_event_data ) { /* Create attribute(s) based on information included in the response PDU */ - aos_bt_smart_attribute_t *attr; + mico_bt_smart_attribute_t *attr; //uint16_t start_handle = 0x0; - aos_bt_smart_attribute_create( &attr, AOS_ATTRIBUTE_TYPE_INCLUDE, 0 ); + mico_bt_smart_attribute_create( &attr, MICO_ATTRIBUTE_TYPE_INCLUDE, 0 ); if ( attr != NULL ) { attr->next = NULL; @@ -469,7 +465,7 @@ static void smartbridge_gatt_discover_included_services_result( aos_bt_gatt_even //start_handle = p_event_data->discovery_result.discovery_data.included_service.s_handle; memcpy( &attr->value.include.uuid, &p_event_data->discovery_result.discovery_data.included_service.service_type, - sizeof(aos_bt_uuid_t) ); + sizeof(mico_bt_uuid_t) ); if ( smartbridge_subprocedure.attr_head == NULL ) { smartbridge_subprocedure.attr_head = attr; @@ -486,12 +482,12 @@ static void smartbridge_gatt_discover_included_services_result( aos_bt_gatt_even } } -static void smartbridge_gatt_discover_characteristic_result( aos_bt_gatt_event_data_t *p_event_data ) +static void smartbridge_gatt_discover_characteristic_result( mico_bt_gatt_event_data_t *p_event_data ) { /* Create attribute(s) based on information included in the response PDU */ - aos_bt_smart_attribute_t *attr; + mico_bt_smart_attribute_t *attr; - aos_bt_smart_attribute_create( &attr, AOS_ATTRIBUTE_TYPE_CHARACTERISTIC, 0 ); + mico_bt_smart_attribute_create( &attr, MICO_ATTRIBUTE_TYPE_CHARACTERISTIC, 0 ); memcpy( ¤t_characteristic, &p_event_data->discovery_result.discovery_data.characteristic_declaration, sizeof( current_characteristic ) ); @@ -509,7 +505,7 @@ static void smartbridge_gatt_discover_characteristic_result( aos_bt_gatt_event_ /* FIXME: descriptor_end_handle need to be calculated correclty */ attr->value.characteristic.descriptor_end_handle = attr->value.characteristic.descriptor_start_handle; - memcpy( &attr->value.characteristic.uuid, ¤t_characteristic.char_uuid, sizeof(aos_bt_uuid_t) ); + memcpy( &attr->value.characteristic.uuid, ¤t_characteristic.char_uuid, sizeof(mico_bt_uuid_t) ); if ( smartbridge_subprocedure.attr_head == NULL ) { smartbridge_subprocedure.attr_head = attr; @@ -527,7 +523,7 @@ static void smartbridge_gatt_discover_characteristic_result( aos_bt_gatt_event_ } } -static void smartbridge_gatt_discovery_complete_handler( aos_bt_gatt_event_data_t *p_event_data ) +static void smartbridge_gatt_discovery_complete_handler( mico_bt_gatt_event_data_t *p_event_data ) { uint16_t discovery_complete_type = p_event_data->discovery_complete.disc_type; @@ -538,9 +534,9 @@ static void smartbridge_gatt_discovery_complete_handler( aos_bt_gatt_event_data_ case GATT_DISCOVER_CHARACTERISTICS: case GATT_DISCOVER_CHARACTERISTIC_DESCRIPTORS: if ( smartbridge_subprocedure.attr_count != 0 ) { - smartbridge_subprocedure.result = AOS_BT_SUCCESS; + smartbridge_subprocedure.result = MICO_BT_SUCCESS; } else { - smartbridge_subprocedure.result = AOS_BT_ITEM_NOT_IN_LIST; + smartbridge_subprocedure.result = MICO_BT_ITEM_NOT_IN_LIST; } bt_smartbridge_log( "Discovery Completed ( result:%d type:%d )\r\n", smartbridge_subprocedure.result, @@ -555,16 +551,16 @@ static void smartbridge_gatt_discovery_complete_handler( aos_bt_gatt_event_data_ } } -aos_bt_gatt_status_t smartbridge_gatt_callback( aos_bt_gatt_evt_t event, aos_bt_gatt_event_data_t *p_event_data ) +mico_bt_gatt_status_t smartbridge_gatt_callback( mico_bt_gatt_evt_t event, mico_bt_gatt_event_data_t *p_event_data ) { - aos_bt_gatt_status_t status = AOS_BT_GATT_SUCCESS; + mico_bt_gatt_status_t status = MICO_BT_GATT_SUCCESS; switch (event) { case GATT_CONNECTION_STATUS_EVT: { if ( p_event_data->connection_status.link_role == BT_SMART_LINK_ROLE_MASTER) { /* Connection */ - if ( p_event_data->connection_status.connected == AOS_TRUE ) { + if ( p_event_data->connection_status.connected == MICO_TRUE ) { if ( connecting_socket && memcmp(connecting_socket->remote_device.address, p_event_data->connection_status.bd_addr, BD_ADDR_LEN) == 0) { smartbridge_gatt_connection_handler( p_event_data->connection_status.conn_id ); @@ -644,29 +640,29 @@ aos_bt_gatt_status_t smartbridge_gatt_callback( aos_bt_gatt_evt_t event, aos_bt_ return status; } -OSStatus aos_bt_smartbridge_init( uint8_t count ) +OSStatus mico_bt_smartbridge_init( uint8_t count ) { OSStatus result; - if ( initialised == AOS_TRUE ) { - return AOS_BT_SUCCESS; + if ( initialised == MICO_TRUE ) { + return MICO_BT_SUCCESS; } - bt_smartbridge_log( "Initialising AOS SmartBridge ..." ); + bt_smartbridge_log( "Initialising MICO SmartBridge ..." ); /* Initialise internal settings for Auto Connection. */ memset((void *)g_auto_conn_dev_table, 0, sizeof(g_auto_conn_dev_table)); smartbridge_auto_conn_list_init(); - result = aos_rtos_init_semaphore(&g_auto_conn_sem, 1); - if (result != oNoErr) { + result = mico_rtos_init_semaphore(&g_auto_conn_sem, 1); + if (result != kNoErr) { bt_smartbridge_log( "Error initialising a semaphore used to Auto connection" ); return result; } /* Initialise SmartBridge Socket Manager */ result = bt_smartbridge_socket_manager_init(); - if ( result != AOS_BT_SUCCESS ) { + if ( result != MICO_BT_SUCCESS ) { bt_smartbridge_log( "Error initialising SmartBridge Socket Manager" ); return result; } @@ -677,14 +673,14 @@ OSStatus aos_bt_smartbridge_init( uint8_t count ) /* Initialise bt stack operation interface */ smartbridge_bt_interface_initialize(); - initialised = AOS_TRUE; - return AOS_BT_SUCCESS; + initialised = MICO_TRUE; + return MICO_BT_SUCCESS; } -OSStatus aos_bt_smartbridge_deinit( void ) +OSStatus mico_bt_smartbridge_deinit( void ) { - if ( initialised == AOS_FALSE ) { - return AOS_BT_SUCCESS; + if ( initialised == MICO_FALSE ) { + return MICO_BT_SUCCESS; } /* Disable Attribute Cache (The function checks if it's enabled) */ @@ -696,83 +692,84 @@ OSStatus aos_bt_smartbridge_deinit( void ) smartbridge_bt_interface_deinitialize(); /* Delete semaphore */ - aos_rtos_deinit_semaphore(&g_auto_conn_sem); + mico_rtos_deinit_semaphore(&g_auto_conn_sem); g_auto_conn_sem = NULL; /* Delete Auto-connection list. */ smartbridge_auto_conn_list_deinit(); - initialised = AOS_FALSE; + initialised = MICO_FALSE; - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } -aos_bool_t aos_bt_smartbridge_is_scanning( void ) +mico_bool_t mico_bt_smartbridge_is_scanning( void ) { - return ( initialised == AOS_TRUE ) ? smartbridge_bt_interface_is_scanning( ) : AOS_FALSE; + return ( initialised == MICO_TRUE ) ? smartbridge_bt_interface_is_scanning( ) : MICO_FALSE; } -aos_bool_t aos_bt_smartbridge_is_ready_to_connect( void ) +mico_bool_t mico_bt_smartbridge_is_ready_to_connect( void ) { - return ( initialised == AOS_FALSE || connecting_socket != NULL ) ? AOS_FALSE : AOS_TRUE; + return ( initialised == MICO_FALSE || connecting_socket != NULL ) ? MICO_FALSE : MICO_TRUE; } -OSStatus aos_bt_smartbridge_start_scan( const aos_bt_smart_scan_settings_t *settings, - aos_bt_smart_scan_complete_callback_t complete_callback, - aos_bt_smart_advertising_report_callback_t advertising_report_callback ) +OSStatus mico_bt_smartbridge_start_scan( const mico_bt_smart_scan_settings_t *settings, + mico_bt_smart_scan_complete_callback_t complete_callback, + mico_bt_smart_advertising_report_callback_t advertising_report_callback ) { - if ( initialised == AOS_FALSE ) { - return AOS_BT_SMART_APPL_UNINITIALISED; + if ( initialised == MICO_FALSE ) { + return MICO_BT_SMART_APPL_UNINITIALISED; } return smartbridge_bt_interface_start_scan( settings, complete_callback, advertising_report_callback ); } -OSStatus aos_bt_smartbridge_stop_scan( void ) +OSStatus mico_bt_smartbridge_stop_scan( void ) { - if ( initialised == AOS_FALSE ) { - return AOS_BT_SMART_APPL_UNINITIALISED; + if ( initialised == MICO_FALSE ) { + return MICO_BT_SMART_APPL_UNINITIALISED; } return smartbridge_bt_interface_stop_scan(); } -OSStatus aos_bt_smartbridge_get_scan_result_list( aos_bt_smart_scan_result_t **result_list, uint32_t *count ) +OSStatus mico_bt_smartbridge_get_scan_result_list( mico_bt_smart_scan_result_t **result_list, uint32_t *count ) { - if ( initialised == AOS_FALSE ) { - return AOS_BT_SMART_APPL_UNINITIALISED; + if ( initialised == MICO_FALSE ) { + return MICO_BT_SMART_APPL_UNINITIALISED; } return smartbridge_helper_get_scan_results( result_list, count ); } -OSStatus aos_bt_smartbridge_get_background_connection_devices_size( uint8_t *size ) +OSStatus mico_bt_smartbridge_get_background_connection_devices_size( uint8_t *size ) { - if ( initialised == AOS_FALSE ) { - return oNotInitializedErr; + if ( initialised == MICO_FALSE ) { + return kNotInitializedErr; } if ( size == (uint8_t *)0 ) { - return oGeneralErr; + return kGeneralErr; } return smartbridge_bt_interface_get_background_connection_device_size( size ); } -OSStatus aos_bt_smartbridge_set_auto_connection_action( aos_bool_t start_stop, - const aos_bt_smart_scan_settings_t *scan_settings, aos_bt_smartbridge_auto_connection_parms_cback_t p_auto_conn_cback ) +OSStatus mico_bt_smartbridge_set_auto_connection_action( mico_bool_t start_stop, + const mico_bt_smart_scan_settings_t *scan_settings, + mico_bt_smartbridge_auto_connection_parms_cback_t p_auto_conn_cback ) { - OSStatus err = oNoErr; + OSStatus err = kNoErr; uint32_t duration; if (start_stop && !scan_settings) { - return oParamErr; + return kParamErr; } - if (initialised == AOS_FALSE) { - return oNotInitializedErr; + if (initialised == MICO_FALSE) { + return kNotInitializedErr; } if (connecting_socket != NULL) { - return oInProgressErr; + return kInProgressErr; } if (start_stop && g_auto_conn_cback) { - return oInProgressErr; + return kInProgressErr; } /* Clear connection list */ @@ -781,16 +778,16 @@ OSStatus aos_bt_smartbridge_set_auto_connection_action( aos_bool_t start_stop, if (start_stop) { /* Start a scanning procedure */ duration = scan_settings->duration_second; - memcpy(&g_auto_conn_scan_cfg, scan_settings, sizeof(aos_bt_smart_scan_settings_t)); + memcpy(&g_auto_conn_scan_cfg, scan_settings, sizeof(mico_bt_smart_scan_settings_t)); g_auto_conn_scan_cfg.filter_duplicates = DUPLICATES_FILTER_DISABLED; g_auto_conn_scan_cfg.filter_policy = FILTER_POLICY_WHITE_LIST; g_auto_conn_scan_cfg.duration_second = MIN(SMARTBRIDGE_AUTO_CONN_SCAN_INTERVAL, duration); - err = aos_bt_smartbridge_start_scan(&g_auto_conn_scan_cfg, - smartbridge_gap_auto_conn_scan_cmpl_handler, - smartbridge_gap_auto_conn_scan_report_handler); + err = mico_bt_smartbridge_start_scan(&g_auto_conn_scan_cfg, + smartbridge_gap_auto_conn_scan_cmpl_handler, + smartbridge_gap_auto_conn_scan_report_handler); - if (err == AOS_BT_PENDING) { + if (err == MICO_BT_PENDING) { if (scan_settings->duration_second < (uint16_t)(-1)) { /* An limited timeout */ g_auto_conn_scan_duration = duration - MIN(SMARTBRIDGE_AUTO_CONN_SCAN_INTERVAL, duration); @@ -803,22 +800,22 @@ OSStatus aos_bt_smartbridge_set_auto_connection_action( aos_bool_t start_stop, if (p_auto_conn_cback) { g_auto_conn_cback = p_auto_conn_cback; } - err = oNoErr; + err = kNoErr; } else { bt_smartbridge_log("%s: start scanning failed", __FUNCTION__); } } else { g_auto_conn_cback = NULL; - memset(&g_auto_conn_scan_cfg, 0, sizeof(aos_bt_smart_scan_settings_t)); - err = aos_bt_smartbridge_stop_scan(); + memset(&g_auto_conn_scan_cfg, 0, sizeof(mico_bt_smart_scan_settings_t)); + err = mico_bt_smartbridge_stop_scan(); } return err; } -OSStatus aos_bt_smartbridge_create_socket( aos_bt_smartbridge_socket_t *socket ) +OSStatus mico_bt_smartbridge_create_socket( mico_bt_smartbridge_socket_t *socket ) { - if ( initialised == AOS_FALSE ) { - return AOS_BT_SMART_APPL_UNINITIALISED; + if ( initialised == MICO_FALSE ) { + return MICO_BT_SMART_APPL_UNINITIALISED; } /* Reset socket fields */ @@ -829,31 +826,31 @@ OSStatus aos_bt_smartbridge_create_socket( aos_bt_smartbridge_socket_t *socket ) socket->node.data = (void *)socket; /* Initialise socket semaphore */ - return aos_rtos_init_semaphore( &socket->semaphore, 1 ); + return mico_rtos_init_semaphore( &socket->semaphore, 1 ); } -OSStatus aos_bt_smartbridge_delete_socket( aos_bt_smartbridge_socket_t *socket ) +OSStatus mico_bt_smartbridge_delete_socket( mico_bt_smartbridge_socket_t *socket ) { OSStatus result; - if ( initialised == AOS_FALSE ) { - return AOS_BT_SMART_APPL_UNINITIALISED; + if ( initialised == MICO_FALSE ) { + return MICO_BT_SMART_APPL_UNINITIALISED; } - result = aos_rtos_deinit_semaphore( &socket->semaphore ); - if ( result != AOS_BT_SUCCESS ) { + result = mico_rtos_deinit_semaphore( &socket->semaphore ); + if ( result != MICO_BT_SUCCESS ) { return result; } memset( socket, 0, sizeof( *socket ) ); socket->connection_handle = SOCKET_INVALID_CONNECTION_HANDLE; - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } -OSStatus aos_bt_smartbridge_get_socket_status( aos_bt_smartbridge_socket_t *socket, - aos_bt_smartbridge_socket_status_t *status ) +OSStatus mico_bt_smartbridge_get_socket_status( mico_bt_smartbridge_socket_t *socket, + mico_bt_smartbridge_socket_status_t *status ) { - if ( initialised == AOS_FALSE ) { - return AOS_BT_SMART_APPL_UNINITIALISED; + if ( initialised == MICO_FALSE ) { + return MICO_BT_SMART_APPL_UNINITIALISED; } if ( socket->state == SOCKET_STATE_LINK_ENCRYPTED ) { @@ -861,7 +858,7 @@ OSStatus aos_bt_smartbridge_get_socket_status( aos_bt_smartbridge_socket_t *sock } else if ( socket->state == SOCKET_STATE_LINK_CONNECTED ) { /* Status is connected if socket does not have loaded bond info and does not initiate pairing */ if ( smartbridge_helper_socket_check_actions_disabled( socket, - SOCKET_ACTION_ENCRYPT_USING_BOND_INFO | SOCKET_ACTION_INITIATE_PAIRING ) == AOS_TRUE ) { + SOCKET_ACTION_ENCRYPT_USING_BOND_INFO | SOCKET_ACTION_INITIATE_PAIRING ) == MICO_TRUE ) { *status = SMARTBRIDGE_SOCKET_CONNECTED; } else { *status = SMARTBRIDGE_SOCKET_CONNECTING; @@ -872,39 +869,40 @@ OSStatus aos_bt_smartbridge_get_socket_status( aos_bt_smartbridge_socket_t *sock *status = SMARTBRIDGE_SOCKET_DISCONNECTED; } - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } -OSStatus aos_bt_smartbridge_connect( aos_bt_smartbridge_socket_t *socket, const aos_bt_smart_device_t *remote_device, - const aos_bt_smart_connection_settings_t *settings, aos_bt_smartbridge_disconnection_callback_t disconnection_callback, - aos_bt_smartbridge_notification_callback_t notification_callback ) +OSStatus mico_bt_smartbridge_connect( mico_bt_smartbridge_socket_t *socket, const mico_bt_smart_device_t *remote_device, + const mico_bt_smart_connection_settings_t *settings, + mico_bt_smartbridge_disconnection_callback_t disconnection_callback, + mico_bt_smartbridge_notification_callback_t notification_callback ) { - aos_bt_smartbridge_socket_t *found_socket; - OSStatus result = AOS_BT_SUCCESS; + mico_bt_smartbridge_socket_t *found_socket; + OSStatus result = MICO_BT_SUCCESS; - if ( initialised == AOS_FALSE ) { - return AOS_BT_SMART_APPL_UNINITIALISED; + if ( initialised == MICO_FALSE ) { + return MICO_BT_SMART_APPL_UNINITIALISED; } if ( connecting_socket != NULL ) { /* Only 1 connecting socket is allowed */ - return AOS_BT_CONNECT_IN_PROGRESS; + return MICO_BT_CONNECT_IN_PROGRESS; } - if ( bt_smartbridge_socket_manager_is_full() == AOS_TRUE ) { - return AOS_BT_MAX_CONNECTIONS_REACHED; + if ( bt_smartbridge_socket_manager_is_full() == MICO_TRUE ) { + return MICO_BT_MAX_CONNECTIONS_REACHED; } if ( bt_smartbridge_socket_manager_find_socket_by_address( &remote_device->address, - &found_socket ) == AOS_BT_SUCCESS ) { + &found_socket ) == MICO_BT_SUCCESS ) { /* device is already connected */ - return AOS_BT_SOCKET_IN_USE; + return MICO_BT_SOCKET_IN_USE; } bt_smartbridge_log( "connect()...socket things are okay" ); /* Clean-up accidentally set semaphores */ - while ( aos_rtos_get_semaphore( &socket->semaphore, AOS_NO_WAIT ) == AOS_BT_SUCCESS ) { + while ( mico_rtos_get_semaphore( &socket->semaphore, MICO_NO_WAIT ) == MICO_BT_SUCCESS ) { } /* Store socket pointer in a temporary global variable so it can be referenced in smartbridge_gap_connection_handler */ @@ -933,67 +931,67 @@ OSStatus aos_bt_smartbridge_connect( aos_bt_smartbridge_socket_t *socket, const /* Set attribute protocol timeout */ smartbridge_bt_interface_set_attribute_timeout( settings->attribute_protocol_timeout_ms ); - if ( smartbridge_helper_socket_check_actions_enabled( socket, SOCKET_ACTION_INITIATE_PAIRING ) == AOS_TRUE ) { + if ( smartbridge_helper_socket_check_actions_enabled( socket, SOCKET_ACTION_INITIATE_PAIRING ) == MICO_TRUE ) { /* Tell GAP to initiate pairing on the next connection attempt */ - aos_bt_start_pairing( socket->remote_device.address, socket->remote_device.address_type, &socket->security_settings ); + mico_bt_start_pairing( socket->remote_device.address, socket->remote_device.address_type, &socket->security_settings ); } else { /* Tell GAP to not send pairing request on the next connection attempt */ - aos_bt_stop_pairing( socket->remote_device.address ); + mico_bt_stop_pairing( socket->remote_device.address ); } smartbridge_bt_interface_connect( remote_device, settings, disconnection_callback, notification_callback ); /* Wait for connection */ - aos_rtos_get_semaphore( &socket->semaphore, socket->connection_settings.timeout_second * 1000 ); + mico_rtos_get_semaphore( &socket->semaphore, socket->connection_settings.timeout_second * 1000 ); /* Check if link is connected. Otherwise, return error */ if ( socket->state == SOCKET_STATE_LINK_CONNECTED ) { - if ( smartbridge_helper_socket_check_actions_enabled( socket, SOCKET_ACTION_INITIATE_PAIRING ) == AOS_TRUE ) { + if ( smartbridge_helper_socket_check_actions_enabled( socket, SOCKET_ACTION_INITIATE_PAIRING ) == MICO_TRUE ) { /* Wait until pairing is complete */ - aos_rtos_get_semaphore( &socket->semaphore, AOS_NEVER_TIMEOUT ); + mico_rtos_get_semaphore( &socket->semaphore, MICO_NEVER_TIMEOUT ); } /* Check if encryption is required */ - if ( smartbridge_helper_socket_check_actions_enabled( socket, SOCKET_ACTION_INITIATE_PAIRING ) == AOS_TRUE || - smartbridge_helper_socket_check_actions_enabled( socket, SOCKET_ACTION_ENCRYPT_USING_BOND_INFO ) == AOS_TRUE ) { - aos_bt_start_encryption( &socket->remote_device.address ); + if ( smartbridge_helper_socket_check_actions_enabled( socket, SOCKET_ACTION_INITIATE_PAIRING ) == MICO_TRUE || + smartbridge_helper_socket_check_actions_enabled( socket, SOCKET_ACTION_ENCRYPT_USING_BOND_INFO ) == MICO_TRUE ) { + mico_bt_start_encryption( &socket->remote_device.address ); /* Wait until link is encrypted */ - aos_rtos_get_semaphore( &socket->semaphore, AOS_NEVER_TIMEOUT ); + mico_rtos_get_semaphore( &socket->semaphore, MICO_NEVER_TIMEOUT ); if ( socket->state != SOCKET_STATE_LINK_ENCRYPTED ) { - result = AOS_BT_ENCRYPTION_FAILED; - aos_bt_dev_delete_bonded_device( (uint8_t *)remote_device->address ); + result = MICO_BT_ENCRYPTION_FAILED; + mico_bt_dev_delete_bonded_device( (uint8_t *)remote_device->address ); goto error; } } } else { - result = AOS_BT_SOCKET_NOT_CONNECTED; + result = MICO_BT_SOCKET_NOT_CONNECTED; goto error; } /* Successful */ - if ( bt_smartbridge_att_cache_is_enabled() == AOS_TRUE ) { + if ( bt_smartbridge_att_cache_is_enabled() == MICO_TRUE ) { bt_smartbridge_att_cache_t *cache = NULL; result = bt_smartbridge_att_cache_find( remote_device, &cache ); - if ( result == AOS_BT_SUCCESS ) { + if ( result == MICO_BT_SUCCESS ) { bt_smartbridge_log( "USING ATT CACHE ..." ); } else { bt_smartbridge_log( "GENERATING ATT CACHE ..." ); result = bt_smartbridge_att_cache_generate( remote_device, socket->connection_handle, &cache ); - if ( result != AOS_BT_SUCCESS ) { + if ( result != MICO_BT_SUCCESS ) { bt_smartbridge_log( "Error Generating Cache result:%d", result ); goto error; } } /* Successful. Mark cache as active and store reference in socket */ - bt_smartbridge_att_cache_set_active_state( cache, AOS_TRUE ); + bt_smartbridge_att_cache_set_active_state( cache, MICO_TRUE ); socket->att_cache = (void *)cache; } @@ -1001,7 +999,7 @@ OSStatus aos_bt_smartbridge_connect( aos_bt_smartbridge_socket_t *socket, const if (connecting_socket->connection_settings.filter_policy == FILTER_POLICY_WHITE_LIST) { if (connecting_socket->remote_device.address_type == BT_SMART_ADDR_TYPE_PUBLIC) { result = smartbridge_bt_interface_update_background_connection_device(TRUE, connecting_socket->remote_device.address); - if (result != oNoErr) { + if (result != kNoErr) { bt_smartbridge_log("Add device to white list unsuccessfully, status: %d", result); } } else { @@ -1023,9 +1021,9 @@ OSStatus aos_bt_smartbridge_connect( aos_bt_smartbridge_socket_t *socket, const /* Link is not connected nor encrypted. Issue disconnection attempt to clean-up */ smartbridge_helper_socket_clear_actions( socket, SOCKET_ACTION_INITIATE_PAIRING | SOCKET_ACTION_ENCRYPT_USING_BOND_INFO ); - aos_rtos_delay_milliseconds( + mico_rtos_delay_milliseconds( 200); //A quick disconnection from an established connection may cause a duplicated gatt connected callback, by william - aos_bt_smartbridge_disconnect( socket, TRUE ); + mico_bt_smartbridge_disconnect( socket, TRUE ); /* Clear connect action as it's no longer needed */ smartbridge_helper_socket_clear_actions( socket, SOCKET_ACTION_HOST_CONNECT ); @@ -1038,24 +1036,24 @@ OSStatus aos_bt_smartbridge_connect( aos_bt_smartbridge_socket_t *socket, const #endif } -OSStatus aos_bt_smartbridge_disconnect( aos_bt_smartbridge_socket_t *socket, aos_bool_t remove_it_from_whitelist ) +OSStatus mico_bt_smartbridge_disconnect( mico_bt_smartbridge_socket_t *socket, mico_bool_t remove_it_from_whitelist ) { - if ( initialised == AOS_FALSE ) { - return AOS_BT_SMART_APPL_UNINITIALISED; + if ( initialised == MICO_FALSE ) { + return MICO_BT_SMART_APPL_UNINITIALISED; } /* Mark disconnection flag that it's coming from the host */ smartbridge_helper_socket_set_actions( socket, SOCKET_ACTION_HOST_DISCONNECT ); /* Clean-up accidentally set semaphores */ - while ( aos_rtos_get_semaphore( &socket->semaphore, AOS_NO_WAIT ) == AOS_BT_SUCCESS ) { + while ( mico_rtos_get_semaphore( &socket->semaphore, MICO_NO_WAIT ) == MICO_BT_SUCCESS ) { } /* Check if either link is encrypted or connected */ if ( socket->state >= SOCKET_STATE_LINK_CONNECTED ) { smartbridge_bt_interface_disconnect( socket->connection_handle ); /* Wait for disconnection */ - aos_rtos_get_semaphore( &socket->semaphore, socket->connection_settings.timeout_second * 1000 ); + mico_rtos_get_semaphore( &socket->semaphore, socket->connection_settings.timeout_second * 1000 ); } else { /* Link is not yet connected. Cancel last */ smartbridge_bt_interface_cancel_last_connect( socket->remote_device.address ); @@ -1066,7 +1064,7 @@ OSStatus aos_bt_smartbridge_disconnect( aos_bt_smartbridge_socket_t *socket, aos /* Proper clean-up if socket isn't properly disconnected */ if ( socket->state != SOCKET_STATE_DISCONNECTED ) { - aos_bt_smartbridge_socket_t *removed_socket; + mico_bt_smartbridge_socket_t *removed_socket; bt_smartbridge_socket_manager_remove_socket( socket->connection_handle, &removed_socket ); @@ -1077,7 +1075,7 @@ OSStatus aos_bt_smartbridge_disconnect( aos_bt_smartbridge_socket_t *socket, aos socket->state = SOCKET_STATE_DISCONNECTED; /* Mark att cache as inactive and reset reference to cache */ - bt_smartbridge_att_cache_set_active_state( (bt_smartbridge_att_cache_t *)socket->att_cache, AOS_FALSE ); + bt_smartbridge_att_cache_set_active_state( (bt_smartbridge_att_cache_t *)socket->att_cache, MICO_FALSE ); socket->att_cache = NULL; } @@ -1086,23 +1084,23 @@ OSStatus aos_bt_smartbridge_disconnect( aos_bt_smartbridge_socket_t *socket, aos smartbridge_bt_interface_update_background_connection_device(FALSE, socket->remote_device.address); } - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } -OSStatus aos_bt_smartbridge_set_transmit_power( aos_bt_smartbridge_socket_t *socket, int8_t transmit_power_dbm ) +OSStatus mico_bt_smartbridge_set_transmit_power( mico_bt_smartbridge_socket_t *socket, int8_t transmit_power_dbm ) { - if ( initialised == AOS_FALSE || socket->state == SOCKET_STATE_DISCONNECTED ) { - return AOS_BT_SMART_APPL_UNINITIALISED; + if ( initialised == MICO_FALSE || socket->state == SOCKET_STATE_DISCONNECTED ) { + return MICO_BT_SMART_APPL_UNINITIALISED; } return smartbridge_bt_interface_set_connection_tx_power( socket->connection_handle, transmit_power_dbm ); } -OSStatus aos_bt_smartbridge_set_bond_info( aos_bt_smartbridge_socket_t *socket, - const aos_bt_smart_security_settings_t *settings, const aos_bt_smart_bond_info_t *bond_info ) +OSStatus mico_bt_smartbridge_set_bond_info( mico_bt_smartbridge_socket_t *socket, + const mico_bt_smart_security_settings_t *settings, const mico_bt_smart_bond_info_t *bond_info ) { - if ( initialised == AOS_FALSE ) { - return AOS_BT_SMART_APPL_UNINITIALISED; + if ( initialised == MICO_FALSE ) { + return MICO_BT_SMART_APPL_UNINITIALISED; } /* Set local copies of security settings and bond info */ @@ -1115,13 +1113,13 @@ OSStatus aos_bt_smartbridge_set_bond_info( aos_bt_smartbridge_socket_t *socket, /* Set socket action to encrypt using loaded bond info */ smartbridge_helper_socket_set_actions( socket, SOCKET_ACTION_ENCRYPT_USING_BOND_INFO ); - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } -OSStatus aos_bt_smartbridge_clear_bond_info( aos_bt_smartbridge_socket_t *socket ) +OSStatus mico_bt_smartbridge_clear_bond_info( mico_bt_smartbridge_socket_t *socket ) { - if ( initialised == AOS_FALSE ) { - return AOS_BT_SMART_APPL_UNINITIALISED; + if ( initialised == MICO_FALSE ) { + return MICO_BT_SMART_APPL_UNINITIALISED; } /* Reset bond info */ @@ -1130,14 +1128,14 @@ OSStatus aos_bt_smartbridge_clear_bond_info( aos_bt_smartbridge_socket_t *socket /* Clear socket action to encrypt using loaded bond info */ smartbridge_helper_socket_clear_actions( socket, SOCKET_ACTION_ENCRYPT_USING_BOND_INFO ); - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } -OSStatus aos_bt_smartbridge_enable_pairing( aos_bt_smartbridge_socket_t *socket, - const aos_bt_smart_security_settings_t *settings, aos_bt_smart_bonding_callback_t bonding_callback ) +OSStatus mico_bt_smartbridge_enable_pairing( mico_bt_smartbridge_socket_t *socket, + const mico_bt_smart_security_settings_t *settings, mico_bt_smart_bonding_callback_t bonding_callback ) { - if ( initialised == AOS_FALSE ) { - return AOS_BT_SMART_APPL_UNINITIALISED; + if ( initialised == MICO_FALSE ) { + return MICO_BT_SMART_APPL_UNINITIALISED; } /* Store security settings in local copy */ @@ -1155,85 +1153,85 @@ OSStatus aos_bt_smartbridge_enable_pairing( aos_bt_smartbridge_socket_t *socket, /* Set socket action to iniatiate pairing request */ smartbridge_helper_socket_set_actions( socket, SOCKET_ACTION_INITIATE_PAIRING ); - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } -OSStatus aos_bt_smartbridge_disable_pairing( aos_bt_smartbridge_socket_t *socket ) +OSStatus mico_bt_smartbridge_disable_pairing( mico_bt_smartbridge_socket_t *socket ) { - if ( initialised == AOS_FALSE ) { - return AOS_BT_SMART_APPL_UNINITIALISED; + if ( initialised == MICO_FALSE ) { + return MICO_BT_SMART_APPL_UNINITIALISED; } /* Clear socket action to iniatiate pairing request */ smartbridge_helper_socket_clear_actions( socket, SOCKET_ACTION_INITIATE_PAIRING ); - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } -OSStatus aos_bt_smartbridge_enable_attribute_cache( uint32_t cache_count, aos_bt_uuid_t cache_services[], - uint32_t service_count ) +OSStatus mico_bt_smartbridge_enable_attribute_cache( uint32_t cache_count, mico_bt_uuid_t cache_services[], + uint32_t service_count ) { - if ( initialised == AOS_FALSE ) { - return AOS_BT_SMART_APPL_UNINITIALISED; + if ( initialised == MICO_FALSE ) { + return MICO_BT_SMART_APPL_UNINITIALISED; } /* Call internal function */ return bt_smartbridge_att_cache_enable( cache_count, cache_services, service_count ); } -OSStatus aos_bt_smartbridge_disable_attribute_cache( void ) +OSStatus mico_bt_smartbridge_disable_attribute_cache( void ) { - if ( initialised == AOS_FALSE ) { - return AOS_BT_SMART_APPL_UNINITIALISED; + if ( initialised == MICO_FALSE ) { + return MICO_BT_SMART_APPL_UNINITIALISED; } /* Call internal function */ return bt_smartbridge_att_cache_disable(); } -OSStatus aos_bt_smartbridge_remove_attribute_cache( aos_bt_smartbridge_socket_t *socket ) +OSStatus mico_bt_smartbridge_remove_attribute_cache( mico_bt_smartbridge_socket_t *socket ) { - if ( initialised == AOS_FALSE ) { - return AOS_BT_SMART_APPL_UNINITIALISED; + if ( initialised == MICO_FALSE ) { + return MICO_BT_SMART_APPL_UNINITIALISED; } /* Call internal function */ return bt_smartbridge_att_cache_release( socket->att_cache ); } -OSStatus aos_bt_smartbridge_enable_attribute_cache_notification( aos_bt_smartbridge_socket_t *socket, - aos_bool_t is_notification_or_indication ) +OSStatus mico_bt_smartbridge_enable_attribute_cache_notification( mico_bt_smartbridge_socket_t *socket, + mico_bool_t is_notification_or_indication ) { - aos_bt_smart_attribute_list_t *list; - aos_bt_smart_attribute_t *iterator; + mico_bt_smart_attribute_list_t *list; + mico_bt_smart_attribute_t *iterator; bt_smartbridge_att_cache_t *cache; OSStatus result; - if ( initialised == AOS_FALSE ) { - return AOS_BT_SMART_APPL_UNINITIALISED; + if ( initialised == MICO_FALSE ) { + return MICO_BT_SMART_APPL_UNINITIALISED; } - if ( bt_smartbridge_att_cache_is_enabled( ) == AOS_FALSE ) { - return AOS_BT_ATT_CACHE_UNINITIALISED; + if ( bt_smartbridge_att_cache_is_enabled( ) == MICO_FALSE ) { + return MICO_BT_ATT_CACHE_UNINITIALISED; } if ( socket == NULL || socket->att_cache == NULL ) { - return AOS_BT_BADARG; + return MICO_BT_BADARG; } cache = (bt_smartbridge_att_cache_t *)socket->att_cache; - if ( bt_smartbridge_att_cache_is_discovering( cache ) == AOS_TRUE ) { - return AOS_BT_DISCOVER_IN_PROGRESS; + if ( bt_smartbridge_att_cache_is_discovering( cache ) == MICO_TRUE ) { + return MICO_BT_DISCOVER_IN_PROGRESS; } result = bt_smartbridge_att_cache_get_list( cache, &list ); - if ( result != AOS_BT_SUCCESS ) { + if ( result != MICO_BT_SUCCESS ) { return result; } - result = aos_bt_smart_attribute_get_list_head( list, &iterator ); - if ( result != AOS_BT_SUCCESS ) { + result = mico_bt_smart_attribute_get_list_head( list, &iterator ); + if ( result != MICO_BT_SUCCESS ) { return result; } @@ -1258,38 +1256,38 @@ OSStatus aos_bt_smartbridge_enable_attribute_cache_notification( aos_bt_smartbri return result; } -OSStatus aos_bt_smartbridge_disable_attribute_cache_notification( aos_bt_smartbridge_socket_t *socket ) +OSStatus mico_bt_smartbridge_disable_attribute_cache_notification( mico_bt_smartbridge_socket_t *socket ) { - aos_bt_smart_attribute_list_t *list; - aos_bt_smart_attribute_t *iterator; + mico_bt_smart_attribute_list_t *list; + mico_bt_smart_attribute_t *iterator; bt_smartbridge_att_cache_t *cache; OSStatus result; - if ( initialised == AOS_FALSE ) { - return AOS_BT_SMART_APPL_UNINITIALISED; + if ( initialised == MICO_FALSE ) { + return MICO_BT_SMART_APPL_UNINITIALISED; } - if ( bt_smartbridge_att_cache_is_enabled( ) == AOS_FALSE ) { - return AOS_BT_ATT_CACHE_UNINITIALISED; + if ( bt_smartbridge_att_cache_is_enabled( ) == MICO_FALSE ) { + return MICO_BT_ATT_CACHE_UNINITIALISED; } if ( socket == NULL || socket->att_cache == NULL ) { - return AOS_BT_BADARG; + return MICO_BT_BADARG; } cache = (bt_smartbridge_att_cache_t *)socket->att_cache; - if ( bt_smartbridge_att_cache_is_discovering( cache ) == AOS_TRUE ) { - return AOS_BT_DISCOVER_IN_PROGRESS; + if ( bt_smartbridge_att_cache_is_discovering( cache ) == MICO_TRUE ) { + return MICO_BT_DISCOVER_IN_PROGRESS; } result = bt_smartbridge_att_cache_get_list( cache, &list ); - if ( result != AOS_BT_SUCCESS ) { + if ( result != MICO_BT_SUCCESS ) { return result; } - result = aos_bt_smart_attribute_get_list_head( list, &iterator ); - if ( result != AOS_BT_SUCCESS ) { + result = mico_bt_smart_attribute_get_list_head( list, &iterator ); + if ( result != MICO_BT_SUCCESS ) { return result; } @@ -1311,64 +1309,64 @@ OSStatus aos_bt_smartbridge_disable_attribute_cache_notification( aos_bt_smartbr return result; } -OSStatus aos_bt_smartbridge_get_attribute_cache_list( aos_bt_smartbridge_socket_t *socket, - aos_bt_smart_attribute_list_t **att_cache_list ) +OSStatus mico_bt_smartbridge_get_attribute_cache_list( mico_bt_smartbridge_socket_t *socket, + mico_bt_smart_attribute_list_t **att_cache_list ) { - if ( initialised == AOS_FALSE ) { - return AOS_BT_SMART_APPL_UNINITIALISED; + if ( initialised == MICO_FALSE ) { + return MICO_BT_SMART_APPL_UNINITIALISED; } - if ( bt_smartbridge_att_cache_is_enabled( ) == AOS_FALSE ) { - return AOS_BT_ATT_CACHE_UNINITIALISED; + if ( bt_smartbridge_att_cache_is_enabled( ) == MICO_FALSE ) { + return MICO_BT_ATT_CACHE_UNINITIALISED; } if ( socket == NULL || socket->att_cache == NULL || att_cache_list == NULL ) { - return AOS_BT_BADARG; + return MICO_BT_BADARG; } - if ( bt_smartbridge_att_cache_is_discovering( (bt_smartbridge_att_cache_t *)socket->att_cache ) == AOS_TRUE ) { - return AOS_BT_DISCOVER_IN_PROGRESS; + if ( bt_smartbridge_att_cache_is_discovering( (bt_smartbridge_att_cache_t *)socket->att_cache ) == MICO_TRUE ) { + return MICO_BT_DISCOVER_IN_PROGRESS; } /* Call internal function */ return bt_smartbridge_att_cache_get_list( (bt_smartbridge_att_cache_t *)socket->att_cache, att_cache_list ); } -OSStatus aos_bt_smartbridge_get_attribute_cache_by_handle( aos_bt_smartbridge_socket_t *socket, uint16_t handle, - aos_bt_smart_attribute_t *attribute, uint16_t size ) +OSStatus mico_bt_smartbridge_get_attribute_cache_by_handle( mico_bt_smartbridge_socket_t *socket, uint16_t handle, + mico_bt_smart_attribute_t *attribute, uint16_t size ) { bt_smartbridge_att_cache_t *cache = NULL; - aos_bt_smart_attribute_list_t *att_cache_list = NULL; - aos_bt_smart_attribute_t *att = NULL; + mico_bt_smart_attribute_list_t *att_cache_list = NULL; + mico_bt_smart_attribute_t *att = NULL; OSStatus result; - if ( initialised == AOS_FALSE ) { - return AOS_BT_SMART_APPL_UNINITIALISED; + if ( initialised == MICO_FALSE ) { + return MICO_BT_SMART_APPL_UNINITIALISED; } - if ( bt_smartbridge_att_cache_is_enabled( ) == AOS_FALSE ) { - return AOS_BT_ATT_CACHE_UNINITIALISED; + if ( bt_smartbridge_att_cache_is_enabled( ) == MICO_FALSE ) { + return MICO_BT_ATT_CACHE_UNINITIALISED; } if ( socket == NULL || socket->att_cache == NULL || attribute == NULL ) { - return AOS_BT_BADARG; + return MICO_BT_BADARG; } cache = (bt_smartbridge_att_cache_t *)socket->att_cache; - if ( bt_smartbridge_att_cache_is_discovering( cache ) == AOS_TRUE ) { - return AOS_BT_DISCOVER_IN_PROGRESS; + if ( bt_smartbridge_att_cache_is_discovering( cache ) == MICO_TRUE ) { + return MICO_BT_DISCOVER_IN_PROGRESS; } bt_smartbridge_att_cache_get_list( cache, &att_cache_list ); bt_smartbridge_att_cache_lock( cache ); - result = aos_bt_smart_attribute_search_list_by_handle( att_cache_list, handle, &att ); + result = mico_bt_smart_attribute_search_list_by_handle( att_cache_list, handle, &att ); - if ( result == AOS_BT_SUCCESS ) { + if ( result == MICO_BT_SUCCESS ) { if ( att->value_struct_size + ATTR_COMMON_FIELDS_SIZE > size ) { - result = AOS_BT_ATTRIBUTE_VALUE_TOO_LONG; + result = MICO_BT_ATTRIBUTE_VALUE_TOO_LONG; } else { memcpy( attribute, att, att->value_struct_size + ATTR_COMMON_FIELDS_SIZE ); } @@ -1378,40 +1376,41 @@ OSStatus aos_bt_smartbridge_get_attribute_cache_by_handle( aos_bt_smartbridge_so return result; } -OSStatus aos_bt_smartbridge_get_attribute_cache_by_uuid( aos_bt_smartbridge_socket_t *socket, const aos_bt_uuid_t *uuid, - uint16_t starting_handle, uint16_t ending_handle, aos_bt_smart_attribute_t *attribute, uint32_t size ) +OSStatus mico_bt_smartbridge_get_attribute_cache_by_uuid( mico_bt_smartbridge_socket_t *socket, + const mico_bt_uuid_t *uuid, uint16_t starting_handle, uint16_t ending_handle, mico_bt_smart_attribute_t *attribute, + uint32_t size ) { bt_smartbridge_att_cache_t *cache = NULL; - aos_bt_smart_attribute_list_t *att_cache_list = NULL; - aos_bt_smart_attribute_t *att = NULL; + mico_bt_smart_attribute_list_t *att_cache_list = NULL; + mico_bt_smart_attribute_t *att = NULL; OSStatus result; - if ( initialised == AOS_FALSE ) { - return AOS_BT_SMART_APPL_UNINITIALISED; + if ( initialised == MICO_FALSE ) { + return MICO_BT_SMART_APPL_UNINITIALISED; } - if ( bt_smartbridge_att_cache_is_enabled( ) == AOS_FALSE ) { - return AOS_BT_ATT_CACHE_UNINITIALISED; + if ( bt_smartbridge_att_cache_is_enabled( ) == MICO_FALSE ) { + return MICO_BT_ATT_CACHE_UNINITIALISED; } if ( socket == NULL || socket->att_cache == NULL || uuid == NULL || attribute == NULL ) { - return AOS_BT_BADARG; + return MICO_BT_BADARG; } cache = (bt_smartbridge_att_cache_t *)socket->att_cache; - if ( bt_smartbridge_att_cache_is_discovering( cache ) == AOS_TRUE ) { - return AOS_BT_DISCOVER_IN_PROGRESS; + if ( bt_smartbridge_att_cache_is_discovering( cache ) == MICO_TRUE ) { + return MICO_BT_DISCOVER_IN_PROGRESS; } bt_smartbridge_att_cache_get_list( cache, &att_cache_list ); bt_smartbridge_att_cache_lock( cache ); - result = aos_bt_smart_attribute_search_list_by_uuid( att_cache_list, uuid, starting_handle, ending_handle, &att ); - if ( result == AOS_BT_SUCCESS ) { + result = mico_bt_smart_attribute_search_list_by_uuid( att_cache_list, uuid, starting_handle, ending_handle, &att ); + if ( result == MICO_BT_SUCCESS ) { if ( att->value_struct_size + ATTR_COMMON_FIELDS_SIZE > size ) { - result = AOS_BT_ATTRIBUTE_VALUE_TOO_LONG; + result = MICO_BT_ATTRIBUTE_VALUE_TOO_LONG; } else { memcpy( attribute, att, att->value_struct_size + ATTR_COMMON_FIELDS_SIZE ); } @@ -1421,20 +1420,20 @@ OSStatus aos_bt_smartbridge_get_attribute_cache_by_uuid( aos_bt_smartbridge_sock return result; } -OSStatus aos_bt_smartbridge_get_service_from_attribute_cache_by_uuid( aos_bt_smartbridge_socket_t *socket, - const aos_bt_uuid_t *uuid, uint16_t starting_handle, uint16_t ending_handle, aos_bt_smart_attribute_t *attribute, - uint32_t size ) +OSStatus mico_bt_smartbridge_get_service_from_attribute_cache_by_uuid( mico_bt_smartbridge_socket_t *socket, + const mico_bt_uuid_t *uuid, uint16_t starting_handle, uint16_t ending_handle, mico_bt_smart_attribute_t *attribute, + uint32_t size ) { OSStatus result; uint16_t _starting_handle = starting_handle; uint16_t _ending_handle = ending_handle; - aos_bt_uuid_t service_uuid = { .len = LEN_UUID_16, .uu.uuid16 = GATT_UUID_PRI_SERVICE }; + mico_bt_uuid_t service_uuid = { .len = LEN_UUID_16, .uu.uuid16 = GATT_UUID_PRI_SERVICE }; /* Find service */ - while ( ( result = aos_bt_smartbridge_get_attribute_cache_by_uuid( socket, &service_uuid, _starting_handle, - _ending_handle, attribute, size ) ) == AOS_BT_SUCCESS ) { + while ( ( result = mico_bt_smartbridge_get_attribute_cache_by_uuid( socket, &service_uuid, _starting_handle, + _ending_handle, attribute, size ) ) == MICO_BT_SUCCESS ) { if ( memcmp( (void *)&attribute->value.service.uuid.uu, &uuid->uu, uuid->len ) == 0 ) { - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } /* Fixed a bug for a service without characteristics. */ @@ -1447,20 +1446,20 @@ OSStatus aos_bt_smartbridge_get_service_from_attribute_cache_by_uuid( aos_bt_sma return result; } -OSStatus aos_bt_smartbridge_get_characteritics_from_attribute_cache_by_uuid( aos_bt_smartbridge_socket_t *socket, - const aos_bt_uuid_t *uuid, uint16_t starting_handle, uint16_t ending_handle, aos_bt_smart_attribute_t *attribute, - uint32_t size ) +OSStatus mico_bt_smartbridge_get_characteritics_from_attribute_cache_by_uuid( mico_bt_smartbridge_socket_t *socket, + const mico_bt_uuid_t *uuid, uint16_t starting_handle, uint16_t ending_handle, mico_bt_smart_attribute_t *attribute, + uint32_t size ) { OSStatus result; uint16_t _starting_handle = starting_handle; uint16_t _ending_handle = ending_handle; - aos_bt_uuid_t characteristic_uuid = { .len = LEN_UUID_16, .uu.uuid16 = GATT_UUID_CHAR_DECLARE }; + mico_bt_uuid_t characteristic_uuid = { .len = LEN_UUID_16, .uu.uuid16 = GATT_UUID_CHAR_DECLARE }; /* Find service */ - while ( ( result = aos_bt_smartbridge_get_attribute_cache_by_uuid( socket, &characteristic_uuid, _starting_handle, - _ending_handle, attribute, size ) ) == AOS_BT_SUCCESS ) { + while ( ( result = mico_bt_smartbridge_get_attribute_cache_by_uuid( socket, &characteristic_uuid, _starting_handle, + _ending_handle, attribute, size ) ) == MICO_BT_SUCCESS ) { if ( memcmp( (void *)&attribute->value.characteristic.uuid.uu, &uuid->uu, uuid->len ) == 0 ) { - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } _starting_handle = attribute->handle + 1; } @@ -1469,39 +1468,39 @@ OSStatus aos_bt_smartbridge_get_characteritics_from_attribute_cache_by_uuid( aos -OSStatus aos_bt_smartbridge_refresh_attribute_cache_characteristic_value( aos_bt_smartbridge_socket_t *socket, - uint16_t handle ) +OSStatus mico_bt_smartbridge_refresh_attribute_cache_characteristic_value( mico_bt_smartbridge_socket_t *socket, + uint16_t handle ) { bt_smartbridge_att_cache_t *cache = NULL; - aos_bt_smart_attribute_list_t *att_cache_list = NULL; - aos_bt_smart_attribute_t *current_att = NULL; - aos_bt_smart_attribute_t *refreshed_att = NULL; + mico_bt_smart_attribute_list_t *att_cache_list = NULL; + mico_bt_smart_attribute_t *current_att = NULL; + mico_bt_smart_attribute_t *refreshed_att = NULL; OSStatus result; - if ( initialised == AOS_FALSE ) { - return AOS_BT_SMART_APPL_UNINITIALISED; + if ( initialised == MICO_FALSE ) { + return MICO_BT_SMART_APPL_UNINITIALISED; } - if ( bt_smartbridge_att_cache_is_enabled( ) == AOS_FALSE ) { - return AOS_BT_ATT_CACHE_UNINITIALISED; + if ( bt_smartbridge_att_cache_is_enabled( ) == MICO_FALSE ) { + return MICO_BT_ATT_CACHE_UNINITIALISED; } if ( socket == NULL || socket->att_cache == NULL ) { - return AOS_BT_BADARG; + return MICO_BT_BADARG; } cache = (bt_smartbridge_att_cache_t *)socket->att_cache; - if ( bt_smartbridge_att_cache_is_discovering( cache ) == AOS_TRUE ) { - return AOS_BT_DISCOVER_IN_PROGRESS; + if ( bt_smartbridge_att_cache_is_discovering( cache ) == MICO_TRUE ) { + return MICO_BT_DISCOVER_IN_PROGRESS; } bt_smartbridge_att_cache_get_list( cache, &att_cache_list ); bt_smartbridge_att_cache_lock( cache ); - result = aos_bt_smart_attribute_search_list_by_handle( att_cache_list, handle, ¤t_att ); - if ( result == AOS_BT_SUCCESS ) { + result = mico_bt_smart_attribute_search_list_by_handle( att_cache_list, handle, ¤t_att ); + if ( result == MICO_BT_SUCCESS ) { /* Check if length is longer than what read characteristic value can handle * If longer, use read long characteristic value */ @@ -1515,11 +1514,11 @@ OSStatus aos_bt_smartbridge_refresh_attribute_cache_characteristic_value( aos_bt /* If read is successful, replace attribute with the refreshed one */ - if ( result == AOS_BT_SUCCESS ) { + if ( result == MICO_BT_SUCCESS ) { /* This function removes and also deletes the attribute with handle specified */ - result = aos_bt_smart_attribute_remove_from_list( att_cache_list, current_att->handle ); - if ( result == AOS_BT_SUCCESS ) { - result = aos_bt_smart_attribute_add_to_list( att_cache_list, refreshed_att ); + result = mico_bt_smart_attribute_remove_from_list( att_cache_list, current_att->handle ); + if ( result == MICO_BT_SUCCESS ) { + result = mico_bt_smart_attribute_add_to_list( att_cache_list, refreshed_att ); } } } @@ -1528,30 +1527,30 @@ OSStatus aos_bt_smartbridge_refresh_attribute_cache_characteristic_value( aos_bt return result; } -OSStatus aos_bt_smartbridge_write_attribute_cache_characteristic_value( aos_bt_smartbridge_socket_t *socket, - const aos_bt_smart_attribute_t *char_value ) +OSStatus mico_bt_smartbridge_write_attribute_cache_characteristic_value( mico_bt_smartbridge_socket_t *socket, + const mico_bt_smart_attribute_t *char_value ) { bt_smartbridge_att_cache_t *cache = NULL; - aos_bt_smart_attribute_list_t *att_cache_list = NULL; - aos_bt_smart_attribute_t *att = NULL; + mico_bt_smart_attribute_list_t *att_cache_list = NULL; + mico_bt_smart_attribute_t *att = NULL; OSStatus result; - if ( initialised == AOS_FALSE ) { - return AOS_BT_SMART_APPL_UNINITIALISED; + if ( initialised == MICO_FALSE ) { + return MICO_BT_SMART_APPL_UNINITIALISED; } - if ( bt_smartbridge_att_cache_is_enabled( ) == AOS_FALSE ) { - return AOS_BT_ATT_CACHE_UNINITIALISED; + if ( bt_smartbridge_att_cache_is_enabled( ) == MICO_FALSE ) { + return MICO_BT_ATT_CACHE_UNINITIALISED; } if ( socket == NULL || socket->att_cache == NULL || char_value == NULL ) { - return AOS_BT_BADARG; + return MICO_BT_BADARG; } cache = (bt_smartbridge_att_cache_t *)socket->att_cache; - if ( bt_smartbridge_att_cache_is_discovering( cache ) == AOS_TRUE ) { - return AOS_BT_DISCOVER_IN_PROGRESS; + if ( bt_smartbridge_att_cache_is_discovering( cache ) == MICO_TRUE ) { + return MICO_BT_DISCOVER_IN_PROGRESS; } bt_smartbridge_att_cache_get_list( cache, &att_cache_list ); @@ -1559,13 +1558,13 @@ OSStatus aos_bt_smartbridge_write_attribute_cache_characteristic_value( aos_bt_s if ( char_value->value_length <= ATT_STANDARD_VALUE_LENGTH ) { result = smartbridge_bt_interface_write_characteristic_value( socket->connection_handle, - (aos_bt_smart_attribute_t *)char_value ); + (mico_bt_smart_attribute_t *)char_value ); } else { result = smartbridge_bt_interface_write_long_characteristic_value( socket->connection_handle, - (aos_bt_smart_attribute_t *)char_value ); + (mico_bt_smart_attribute_t *)char_value ); } - if ( result != AOS_BT_SUCCESS ) { + if ( result != MICO_BT_SUCCESS ) { return result; } @@ -1573,29 +1572,29 @@ OSStatus aos_bt_smartbridge_write_attribute_cache_characteristic_value( aos_bt_s /* Find characteristic value in local attribute list. Add to the list if not found */ - result = aos_bt_smart_attribute_search_list_by_handle( att_cache_list, char_value->handle, &att ); + result = mico_bt_smart_attribute_search_list_by_handle( att_cache_list, char_value->handle, &att ); - if ( result == AOS_BT_SUCCESS ) { + if ( result == MICO_BT_SUCCESS ) { /* Found. Compare lengths first. * If new length is not equal old length, replace old attribute with new one. * If equal, copy content directly. */ if ( char_value->value_length != att->value_length ) { - result = aos_bt_smart_attribute_remove_from_list( att_cache_list, att->handle ); + result = mico_bt_smart_attribute_remove_from_list( att_cache_list, att->handle ); - if ( result != AOS_BT_SUCCESS ) { + if ( result != MICO_BT_SUCCESS ) { goto exit; } att = NULL; /* Reuse attribute pointer */ - if ( result != AOS_BT_SUCCESS ) { + if ( result != MICO_BT_SUCCESS ) { goto exit; } - result = aos_bt_smart_attribute_create( &att, AOS_ATTRIBUTE_TYPE_CHARACTERISTIC_VALUE, char_value->value_length ); + result = mico_bt_smart_attribute_create( &att, MICO_ATTRIBUTE_TYPE_CHARACTERISTIC_VALUE, char_value->value_length ); - if ( result != AOS_BT_SUCCESS ) { + if ( result != MICO_BT_SUCCESS ) { goto exit; } @@ -1606,15 +1605,15 @@ OSStatus aos_bt_smartbridge_write_attribute_cache_characteristic_value( aos_bt_s memcpy( att->value.value, char_value->value.value, char_value->value_length ); - result = aos_bt_smart_attribute_add_to_list( att_cache_list, att ); + result = mico_bt_smart_attribute_add_to_list( att_cache_list, att ); } else { memcpy( att->value.value, char_value->value.value, char_value->value_length ); } - } else if ( result == AOS_BT_ITEM_NOT_IN_LIST ) { + } else if ( result == MICO_BT_ITEM_NOT_IN_LIST ) { /* Not found. Create new one and add attribute to the list */ - result = aos_bt_smart_attribute_create( &att, AOS_ATTRIBUTE_TYPE_CHARACTERISTIC_VALUE, char_value->value_length ); + result = mico_bt_smart_attribute_create( &att, MICO_ATTRIBUTE_TYPE_CHARACTERISTIC_VALUE, char_value->value_length ); - if ( result != AOS_BT_SUCCESS ) { + if ( result != MICO_BT_SUCCESS ) { goto exit; } @@ -1625,7 +1624,7 @@ OSStatus aos_bt_smartbridge_write_attribute_cache_characteristic_value( aos_bt_s memcpy( att->value.value, char_value->value.value, char_value->value_length ); - result = aos_bt_smart_attribute_add_to_list( att_cache_list, att ); + result = mico_bt_smart_attribute_add_to_list( att_cache_list, att ); } exit: @@ -1639,55 +1638,55 @@ OSStatus aos_bt_smartbridge_write_attribute_cache_characteristic_value( aos_bt_s static OSStatus smartbridge_app_notification_handler( void *arg ) { - aos_bt_smartbridge_socket_t *socket = (aos_bt_smartbridge_socket_t *)arg; + mico_bt_smartbridge_socket_t *socket = (mico_bt_smartbridge_socket_t *)arg; if ( socket != NULL && socket->notification_callback != NULL ) { socket->notification_callback( socket, socket->last_notified_attribute_handle ); - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } - return AOS_BT_ERROR; + return MICO_BT_ERROR; } static OSStatus smartbridge_app_disconnection_handler( void *arg ) { - aos_bt_smartbridge_socket_t *socket = (aos_bt_smartbridge_socket_t *)arg; + mico_bt_smartbridge_socket_t *socket = (mico_bt_smartbridge_socket_t *)arg; if ( socket != NULL && socket->disconnection_callback != NULL ) { socket->disconnection_callback( socket ); - return AOS_BT_SUCCESS; + return MICO_BT_SUCCESS; } - return AOS_BT_ERROR; + return MICO_BT_ERROR; } -// OSStatus aos_bt_smartbridge_bond_info_update( aos_bt_device_link_keys_t paired_device_keys ) +// OSStatus mico_bt_smartbridge_bond_info_update( mico_bt_device_link_keys_t paired_device_keys ) // { -// aos_bt_smart_bond_info_t bond_info; -// aos_bt_ble_keys_t *le_security_keys; -// aos_bt_device_sec_keys_t *security_keys; +// mico_bt_smart_bond_info_t bond_info; +// mico_bt_ble_keys_t *le_security_keys; +// mico_bt_device_sec_keys_t *security_keys; -// OSStatus result = AOS_BT_ERROR; +// OSStatus result = MICO_BT_ERROR; // memcpy(bond_info.peer_address, paired_device_keys.bd_addr, BD_ADDR_LEN ); -// security_keys = (aos_bt_device_sec_keys_t*)&paired_device_keys.key_data; +// security_keys = (mico_bt_device_sec_keys_t*)&paired_device_keys.key_data; // if( security_keys == NULL ) // { // WPRINT_LIB_ERROR( ("[SmartBridge] Security Keys is NULL\n")); -// return AOS_BT_ERROR; +// return MICO_BT_ERROR; // } -// le_security_keys = ( aos_bt_ble_keys_t* )&security_keys->le_keys; +// le_security_keys = ( mico_bt_ble_keys_t* )&security_keys->le_keys; // if ( le_security_keys == NULL ) // { // WPRINT_LIB_ERROR( ("[SmartBridge] Security LE-Keys is NULL\n")); -// return AOS_BT_ERROR; +// return MICO_BT_ERROR; // } -// bond_info.address_type = (aos_bt_smart_address_type_t)security_keys->ble_addr_type; +// bond_info.address_type = (mico_bt_smart_address_type_t)security_keys->ble_addr_type; // bond_info.ediv = le_security_keys->ediv; @@ -1704,49 +1703,49 @@ static OSStatus smartbridge_app_disconnection_handler( void *arg ) // return result; // } -// static OSStatus smartbridge_gap_bonding_handler( uint16_t connection_handle, const aos_bt_smart_bond_info_t* bond_info ) +// static OSStatus smartbridge_gap_bonding_handler( uint16_t connection_handle, const mico_bt_smart_bond_info_t* bond_info ) // { -// aos_bt_smartbridge_socket_t* socket; +// mico_bt_smartbridge_socket_t* socket; -// if ( bt_smartbridge_socket_manager_find_socket_by_handle( connection_handle, &socket ) == AOS_BT_SUCCESS ) +// if ( bt_smartbridge_socket_manager_find_socket_by_handle( connection_handle, &socket ) == MICO_BT_SUCCESS ) // { -// /* Bonding successful. Update socket's bond info and post callback to AOS_BT_EVT_WORKER_THREAD */ +// /* Bonding successful. Update socket's bond info and post callback to MICO_BT_EVT_WORKER_THREAD */ // memcpy( &socket->bond_info, bond_info, sizeof( *bond_info ) ); // if ( socket != NULL && socket->bonding_callback != NULL ) // { -// aos_rtos_send_asynchronous_event( AOS_BT_EVT_WORKER_THREAD, smartbridge_app_pairing_handler, (void*)socket ); +// mico_rtos_send_asynchronous_event( MICO_BT_EVT_WORKER_THREAD, smartbridge_app_pairing_handler, (void*)socket ); // } -// return AOS_BT_SUCCESS; +// return MICO_BT_SUCCESS; // } -// return AOS_BT_ERROR; +// return MICO_BT_ERROR; // } // static OSStatus smartbridge_app_pairing_handler( void* arg ) // { -// aos_bt_smartbridge_socket_t* socket = (aos_bt_smartbridge_socket_t*)arg; +// mico_bt_smartbridge_socket_t* socket = (mico_bt_smartbridge_socket_t*)arg; // if ( socket != NULL && socket->bonding_callback != NULL ) // { // socket->bonding_callback( socket, &socket->bond_info ); -// return AOS_BT_SUCCESS; +// return MICO_BT_SUCCESS; // } -// return AOS_BT_ERROR; +// return MICO_BT_ERROR; // } /* Auto-Connection Connecting Event Handler */ static OSStatus smartbridge_gap_auto_conn_asyn_event_handler(void *arg) { - OSStatus err = oNoErr; - aos_bt_gatt_status_t gatt_status; - aos_bt_smart_advertising_report_t *report = NULL; + OSStatus err = kNoErr; + mico_bt_gatt_status_t gatt_status; + mico_bt_smart_advertising_report_t *report = NULL; /* Find a scanned device to create a connection. */ err = smartbridge_auto_conn_list_get_by_state(&report, SMARTBRIDGE_AUTO_CONN_STATE_SCANED); - if (err == oNoErr) { + if (err == kNoErr) { /* Update current state */ smartbridge_auto_conn_list_set_state(report->remote_device.address, SMARTBRIDGE_AUTO_CONN_STATE_REPORTED); @@ -1758,10 +1757,10 @@ static OSStatus smartbridge_gap_auto_conn_asyn_event_handler(void *arg) report->eir_data_length)) { /* Get socket */ int8_t idx = smartbridge_auto_conn_find_dev_by_addr(report->remote_device.address); - aos_bt_smartbridge_socket_t *p_socket = g_auto_conn_dev_table[idx].socket; + mico_bt_smartbridge_socket_t *p_socket = g_auto_conn_dev_table[idx].socket; /* Clear semaphore */ - while (aos_rtos_get_semaphore(&g_auto_conn_sem, AOS_NO_WAIT) == oNoErr); + while (mico_rtos_get_semaphore(&g_auto_conn_sem, MICO_NO_WAIT) == kNoErr); /* Update current state */ smartbridge_auto_conn_list_set_state(report->remote_device.address, @@ -1773,29 +1772,29 @@ static OSStatus smartbridge_gap_auto_conn_asyn_event_handler(void *arg) smartbridge_helper_socket_clear_actions(p_socket, SOCKET_ACTION_HOST_CONNECT); /* Start to create a connection */ - gatt_status = aos_bt_gatt_le_connect((uint8_t *)report->remote_device.address, - report->remote_device.address_type, - BLE_CONN_MODE_HIGH_DUTY, - AOS_TRUE); + gatt_status = mico_bt_gatt_le_connect((uint8_t *)report->remote_device.address, + report->remote_device.address_type, + BLE_CONN_MODE_HIGH_DUTY, + MICO_TRUE); if (!gatt_status) { bt_smartbridge_log("%s: Create LE Connection failed", __FUNCTION__); - err = oConnectionErr; + err = kConnectionErr; goto err_exit; } /* Wait for completion */ - err = aos_rtos_get_semaphore(&g_auto_conn_sem, 5000); - if (err != oNoErr) { + err = mico_rtos_get_semaphore(&g_auto_conn_sem, 5000); + if (err != kNoErr) { bt_smartbridge_log("%s: Create LE Connection failed: %s", __FUNCTION__, - err == oTimeoutErr ? "Timeout" : "Unknown Error"); + err == kTimeoutErr ? "Timeout" : "Unknown Error"); err_exit: p_socket->state = SOCKET_STATE_DISCONNECTED; smartbridge_auto_conn_list_set_state(report->remote_device.address, SMARTBRIDGE_AUTO_CONN_STATE_FREE); - aos_rtos_send_asynchronous_event(AOS_BT_EVT_WORKER_THREAD, - (event_handler_t)p_socket->auto_connection_callback, - (void *)p_socket); + mico_rtos_send_asynchronous_event(MICO_BT_EVT_WORKER_THREAD, + (event_handler_t)p_socket->auto_connection_callback, + (void *)p_socket); } else { bt_smartbridge_log("%s: Craete LE Connection succesfully", __FUNCTION__); @@ -1806,14 +1805,14 @@ static OSStatus smartbridge_gap_auto_conn_asyn_event_handler(void *arg) smartbridge_auto_conn_list_remove(report->remote_device.address); /* Notify user */ - aos_rtos_send_asynchronous_event(AOS_BT_EVT_WORKER_THREAD, - (event_handler_t)p_socket->auto_connection_callback, - (void *)p_socket); + mico_rtos_send_asynchronous_event(MICO_BT_EVT_WORKER_THREAD, + (event_handler_t)p_socket->auto_connection_callback, + (void *)p_socket); } /* Next Connection */ - aos_rtos_send_asynchronous_event(AOS_BT_WORKER_THREAD, - smartbridge_gap_auto_conn_asyn_event_handler, - NULL); + mico_rtos_send_asynchronous_event(MICO_BT_WORKER_THREAD, + smartbridge_gap_auto_conn_asyn_event_handler, + NULL); } else { /* Update current state */ smartbridge_auto_conn_list_set_state(report->remote_device.address, @@ -1824,10 +1823,10 @@ static OSStatus smartbridge_gap_auto_conn_asyn_event_handler(void *arg) } /* Auto-Connection Scanning Procedure Report Handler */ -static OSStatus smartbridge_gap_auto_conn_scan_report_handler(const aos_bt_smart_advertising_report_t *report) +static OSStatus smartbridge_gap_auto_conn_scan_report_handler(const mico_bt_smart_advertising_report_t *report) { - OSStatus err = oNoErr; - aos_bt_smart_advertising_report_t *match_report = NULL; + OSStatus err = kNoErr; + mico_bt_smart_advertising_report_t *match_report = NULL; bt_smartbridge_log("%s: scan result: %s[%02x:%02x:%02x:%02x:%02x:%02x]", __FUNCTION__, @@ -1841,7 +1840,7 @@ static OSStatus smartbridge_gap_auto_conn_scan_report_handler(const aos_bt_smart /* Add it to the list. */ err = smartbridge_auto_conn_list_add(report); - if (err != oNoErr) { + if (err != kNoErr) { //bt_smartbridge_log("%s: add list failed", __FUNCTION__); goto exit; } @@ -1851,14 +1850,14 @@ static OSStatus smartbridge_gap_auto_conn_scan_report_handler(const aos_bt_smart /* Check current state. */ err = smartbridge_auto_conn_list_get_by_state(&match_report, SMARTBRIDGE_AUTO_CONN_STATE_CONNING); - if (err == oNoErr) { + if (err == kNoErr) { bt_smartbridge_log("%s: A connection is busy!", __FUNCTION__); /* It is busy for Auto-Connection Procedure and we should wait. */ } else { /* Create connection */ - aos_rtos_send_asynchronous_event(AOS_BT_WORKER_THREAD, - smartbridge_gap_auto_conn_asyn_event_handler, - NULL); + mico_rtos_send_asynchronous_event(MICO_BT_WORKER_THREAD, + smartbridge_gap_auto_conn_asyn_event_handler, + NULL); } exit: @@ -1868,7 +1867,7 @@ static OSStatus smartbridge_gap_auto_conn_scan_report_handler(const aos_bt_smart /* Auto-Connection Scanning Procedure Completion Handler */ static OSStatus smartbridge_gap_auto_conn_scan_cmpl_handler(void *arg) { - OSStatus err = oNoErr; + OSStatus err = kNoErr; UNUSED_PARAMETER(arg); @@ -1879,12 +1878,12 @@ static OSStatus smartbridge_gap_auto_conn_scan_cmpl_handler(void *arg) if (g_auto_conn_scan_duration > 0) { bt_smartbridge_log("restart scanning for auto-connection"); g_auto_conn_scan_cfg.duration_second = MIN(SMARTBRIDGE_AUTO_CONN_SCAN_INTERVAL, g_auto_conn_scan_duration); - err = aos_bt_smartbridge_start_scan(&g_auto_conn_scan_cfg, - smartbridge_gap_auto_conn_scan_cmpl_handler, - smartbridge_gap_auto_conn_scan_report_handler); + err = mico_bt_smartbridge_start_scan(&g_auto_conn_scan_cfg, + smartbridge_gap_auto_conn_scan_cmpl_handler, + smartbridge_gap_auto_conn_scan_report_handler); /* Update remain duration */ - if (err == AOS_BT_PENDING && g_auto_conn_scan_duration < (uint16_t)(-1)) { + if (err == MICO_BT_PENDING && g_auto_conn_scan_duration < (uint16_t)(-1)) { g_auto_conn_scan_duration -= MIN(SMARTBRIDGE_AUTO_CONN_SCAN_INTERVAL, g_auto_conn_scan_duration); } } else { @@ -1896,41 +1895,41 @@ static OSStatus smartbridge_gap_auto_conn_scan_cmpl_handler(void *arg) static OSStatus smartbridge_gap_auto_conn_cryption( void *arg ) { - OSStatus result = oNoErr; - aos_bt_smartbridge_socket_t *socket = (aos_bt_smartbridge_socket_t *)arg; + OSStatus result = kNoErr; + mico_bt_smartbridge_socket_t *socket = (mico_bt_smartbridge_socket_t *)arg; if (socket != NULL && socket->auto_connection_callback != NULL) { if (socket->security_settings.authentication_requirements != BT_SMART_AUTH_REQ_NONE) { /* Encryption */ bt_smartbridge_log("Encryption started."); - aos_bt_start_encryption( &socket->remote_device.address ); - aos_rtos_get_semaphore(&g_auto_conn_sem, AOS_NEVER_TIMEOUT); + mico_bt_start_encryption( &socket->remote_device.address ); + mico_rtos_get_semaphore(&g_auto_conn_sem, MICO_NEVER_TIMEOUT); socket->state = SOCKET_STATE_LINK_ENCRYPTED; bt_smartbridge_log("Encryption completed."); } /* Cache if enabled. */ - if (bt_smartbridge_att_cache_is_enabled() == AOS_TRUE) { + if (bt_smartbridge_att_cache_is_enabled() == MICO_TRUE) { bt_smartbridge_log("ATT Cache for an auto connection."); bt_smartbridge_att_cache_t *cache = NULL; result = bt_smartbridge_att_cache_find(&socket->remote_device, &cache); - if (result == AOS_BT_SUCCESS) { + if (result == MICO_BT_SUCCESS) { bt_smartbridge_log("USING ATT CACHE ..."); } else { bt_smartbridge_log("GENERATING ATT CACHE ..."); result = bt_smartbridge_att_cache_generate(&socket->remote_device, socket->connection_handle, &cache); - if (result != AOS_BT_SUCCESS) { + if (result != MICO_BT_SUCCESS) { bt_smartbridge_log("Error Generating Cache result:%d", result ); goto error; } } /* Successful. Mark cache as active and store reference in socket */ - bt_smartbridge_att_cache_set_active_state(cache, AOS_TRUE); + bt_smartbridge_att_cache_set_active_state(cache, MICO_TRUE); socket->att_cache = (void *)cache; } @@ -1939,13 +1938,13 @@ static OSStatus smartbridge_gap_auto_conn_cryption( void *arg ) } error: - return AOS_BT_ERROR; + return MICO_BT_ERROR; } -static aos_bool_t smartbridge_gap_auto_conn_user_cfg( const aos_bt_device_address_t device_address, - const uint8_t *device_name, const uint8_t *p_data, uint8_t length ) +static mico_bool_t smartbridge_gap_auto_conn_user_cfg( const mico_bt_device_address_t device_address, + const uint8_t *device_name, const uint8_t *p_data, uint8_t length ) { - extern aos_bt_cfg_settings_t aos_bt_cfg_settings; + extern mico_bt_cfg_settings_t mico_bt_cfg_settings; int8_t idx; smartbridge_auto_conn_dev_info_t *device_info = NULL; @@ -1971,21 +1970,21 @@ static aos_bool_t smartbridge_gap_auto_conn_user_cfg( const aos_bt_device_addres /* Assign connection configuration parameters for auto connection procedure. */ require_string(g_auto_conn_dev_table[idx].socket != NULL, exit, "User not allow this auto connection"); - aos_bt_cfg_settings.ble_scan_cfg.conn_min_interval = g_auto_conn_dev_table[idx].conn_settings.interval_min; - aos_bt_cfg_settings.ble_scan_cfg.conn_max_interval = g_auto_conn_dev_table[idx].conn_settings.interval_max; - aos_bt_cfg_settings.ble_scan_cfg.conn_latency = g_auto_conn_dev_table[idx].conn_settings.latency; - aos_bt_cfg_settings.ble_scan_cfg.conn_supervision_timeout = + mico_bt_cfg_settings.ble_scan_cfg.conn_min_interval = g_auto_conn_dev_table[idx].conn_settings.interval_min; + mico_bt_cfg_settings.ble_scan_cfg.conn_max_interval = g_auto_conn_dev_table[idx].conn_settings.interval_max; + mico_bt_cfg_settings.ble_scan_cfg.conn_latency = g_auto_conn_dev_table[idx].conn_settings.latency; + mico_bt_cfg_settings.ble_scan_cfg.conn_supervision_timeout = g_auto_conn_dev_table[idx].conn_settings.supervision_timeout; - return AOS_TRUE; + return MICO_TRUE; exit: - return AOS_FALSE; + return MICO_FALSE; } static OSStatus smartbridge_auto_conn_user_parms( void *arg ) { - OSStatus err = oNoErr; - aos_bt_smartbridge_auto_conn_cback_parms_t parm; + OSStatus err = kNoErr; + mico_bt_smartbridge_auto_conn_cback_parms_t parm; smartbridge_auto_conn_dev_info_t *p_dev_info = (smartbridge_auto_conn_dev_info_t *) arg; smartbridge_auto_conn_entity_t *p_entity; @@ -2004,10 +2003,10 @@ static OSStatus smartbridge_auto_conn_user_parms( void *arg ) p_dev_info->adv_data, p_dev_info->length, &parm) - ) != oNoErr ) { + ) != kNoErr ) { /* Clear */ p_entity->socket = (void *) 0; - memset( (void *) &p_entity->conn_settings, 0, sizeof(aos_bt_smart_connection_settings_t) ); + memset( (void *) &p_entity->conn_settings, 0, sizeof(mico_bt_smart_connection_settings_t) ); bt_smartbridge_log(" Not allow this auto connection"); } else { /* Socket */ @@ -2019,27 +2018,27 @@ static OSStatus smartbridge_auto_conn_user_parms( void *arg ) /* Connection settings */ memcpy( (void *) &p_entity->conn_settings, (void *) &parm.conn_settings, - sizeof(aos_bt_smart_connection_settings_t) ); + sizeof(mico_bt_smart_connection_settings_t) ); /* Security settings */ memcpy( (void *) &p_entity->socket->security_settings, (void *) &parm.security_settings, - sizeof(aos_bt_smart_security_settings_t) ); + sizeof(mico_bt_smart_security_settings_t) ); } return err; } /* Find a valid auto connection entity by address. */ -static int8_t smartbridge_auto_conn_find_dev_by_addr(const aos_bt_device_address_t device_address) +static int8_t smartbridge_auto_conn_find_dev_by_addr(const mico_bt_device_address_t device_address) { int8_t idx = 0; - aos_bt_smartbridge_socket_t *temp_socket; + mico_bt_smartbridge_socket_t *temp_socket; for (idx = 0; idx < sizeof(g_auto_conn_dev_table) / sizeof(g_auto_conn_dev_table[0]); idx++) { temp_socket = g_auto_conn_dev_table[idx].socket; if ((temp_socket != (void *)0) && (memcmp((void *)temp_socket->remote_device.address, (void *)device_address, - sizeof(aos_bt_device_address_t)) == 0)) { + sizeof(mico_bt_device_address_t)) == 0)) { return idx; } } @@ -2055,14 +2054,14 @@ static int8_t smartbridge_auto_conn_dev_alloc(void) if (g_auto_conn_dev_table[idx].socket == (void *)0) { memset((void *)&g_auto_conn_dev_table[idx].conn_settings, 0, - sizeof(aos_bt_smart_connection_settings_t)); + sizeof(mico_bt_smart_connection_settings_t)); return idx; } } return -1; } -void smartbridge_auto_connection_encryption_check(const aos_bt_dev_pairing_cplt_t *p_pairing_cplt) +void smartbridge_auto_connection_encryption_check(const mico_bt_dev_pairing_cplt_t *p_pairing_cplt) { if (p_pairing_cplt == NULL) { bt_smartbridge_log("Check auto connection encryption: invalid parameters"); @@ -2073,7 +2072,7 @@ void smartbridge_auto_connection_encryption_check(const aos_bt_dev_pairing_cplt_ if (idx >= 0) { if (g_auto_conn_dev_table[idx].socket->security_settings.authentication_requirements != BT_SMART_AUTH_REQ_NONE) { - aos_sem_signal(&g_auto_conn_sem); + mico_rtos_set_semaphore(&g_auto_conn_sem); } } } @@ -2081,18 +2080,18 @@ void smartbridge_auto_connection_encryption_check(const aos_bt_dev_pairing_cplt_ static OSStatus smartbridge_auto_conn_list_init(void) { linked_list_init(&g_auto_conn_list.list); - return aos_rtos_init_mutex(&g_auto_conn_list.mutex); + return mico_rtos_init_mutex(&g_auto_conn_list.mutex); } static OSStatus smartbridge_auto_conn_list_deinit(void) { - return aos_rtos_deinit_mutex(&g_auto_conn_list.mutex); + return mico_rtos_deinit_mutex(&g_auto_conn_list.mutex); } -static aos_bool_t smartbridge_auto_conn_compare_bdaddr(linked_list_node_t *node_to_compare, void *user_data) +static mico_bool_t smartbridge_auto_conn_compare_bdaddr(linked_list_node_t *node_to_compare, void *user_data) { smartbridge_auto_conn_report_t *report = (smartbridge_auto_conn_report_t *)node_to_compare; - aos_bt_device_address_t *device_address = (aos_bt_device_address_t *)user_data; + mico_bt_device_address_t *device_address = (mico_bt_device_address_t *)user_data; if (memcmp(report->report.remote_device.address, device_address, BD_ADDR_LEN) == 0) { return TRUE; @@ -2101,7 +2100,7 @@ static aos_bool_t smartbridge_auto_conn_compare_bdaddr(linked_list_node_t *node_ } } -static aos_bool_t smartbridge_auto_conn_compare_state(linked_list_node_t *node_to_compare, void *user_data) +static mico_bool_t smartbridge_auto_conn_compare_state(linked_list_node_t *node_to_compare, void *user_data) { smartbridge_auto_conn_report_t *report = (smartbridge_auto_conn_report_t *)node_to_compare; smartbridge_auto_conn_state_t state = *(smartbridge_auto_conn_state_t *)user_data; @@ -2113,25 +2112,25 @@ static aos_bool_t smartbridge_auto_conn_compare_state(linked_list_node_t *node_t } } -static OSStatus smartbridge_auto_conn_list_add(const aos_bt_smart_advertising_report_t *report) +static OSStatus smartbridge_auto_conn_list_add(const mico_bt_smart_advertising_report_t *report) { - OSStatus err = oNoErr; + OSStatus err = kNoErr; smartbridge_auto_conn_report_t *report_found = NULL, *new_report = NULL; uint32_t count = 0; smartbridge_auto_conn_state_t state = SMARTBRIDGE_AUTO_CONN_STATE_FREE; - require_action(report != NULL, exit, err = oParamErr); + require_action(report != NULL, exit, err = kParamErr); /* Check if this report is existed. */ - aos_rtos_lock_mutex(&g_auto_conn_list.mutex); + mico_rtos_lock_mutex(&g_auto_conn_list.mutex); err = linked_list_find_node(&g_auto_conn_list.list, (linked_list_compare_callback_t)smartbridge_auto_conn_compare_bdaddr, (void *)report->remote_device.address, (linked_list_node_t **)&report_found); /* If already existed, we should update its EIR Data. */ - if (err == oNoErr) { + if (err == kNoErr) { bt_smartbridge_log("%s: already existed, state[%d], event[%d]", __FUNCTION__, report_found->state, report_found->report.event); @@ -2153,9 +2152,9 @@ static OSStatus smartbridge_auto_conn_list_add(const aos_bt_smart_advertising_re /* Already existed and we may release it after next scaning procedure * in smartbridge_auto_conn_scan_cmpl_handler. */ - err = oAlreadyInUseErr; + err = kAlreadyInUseErr; } - aos_rtos_unlock_mutex(&g_auto_conn_list.mutex); + mico_rtos_unlock_mutex(&g_auto_conn_list.mutex); return err; } else { linked_list_get_count(&g_auto_conn_list.list, &count); @@ -2167,138 +2166,138 @@ static OSStatus smartbridge_auto_conn_list_add(const aos_bt_smart_advertising_re (linked_list_compare_callback_t)smartbridge_auto_conn_compare_state, (void *)&state, (linked_list_node_t **)&report_found); - if (err == oNoErr) { + if (err == kNoErr) { /* Yeah, we should reuse it. */ linked_list_remove_node(&g_auto_conn_list.list, &report_found->this_node); new_report = report_found; } } } - aos_rtos_unlock_mutex(&g_auto_conn_list.mutex); + mico_rtos_unlock_mutex(&g_auto_conn_list.mutex); /* Not existed. */ if (new_report == NULL) { new_report = malloc(sizeof(smartbridge_auto_conn_report_t)); if (!new_report) { bt_smartbridge_log("%s: malloc failed", __FUNCTION__); - return oNoMemoryErr; + return kNoMemoryErr; } } memset(new_report, 0, sizeof(smartbridge_auto_conn_report_t)); new_report->state = SMARTBRIDGE_AUTO_CONN_STATE_SCANED; new_report->this_node.data = new_report; - memcpy(&new_report->report, report, sizeof(aos_bt_smart_advertising_report_t)); + memcpy(&new_report->report, report, sizeof(mico_bt_smart_advertising_report_t)); - aos_rtos_lock_mutex(&g_auto_conn_list.mutex); + mico_rtos_lock_mutex(&g_auto_conn_list.mutex); err = linked_list_insert_node_at_rear(&g_auto_conn_list.list, &new_report->this_node); - aos_rtos_unlock_mutex(&g_auto_conn_list.mutex); + mico_rtos_unlock_mutex(&g_auto_conn_list.mutex); exit: return err; } -static OSStatus smartbridge_auto_conn_list_get_by_state(aos_bt_smart_advertising_report_t **report, +static OSStatus smartbridge_auto_conn_list_get_by_state(mico_bt_smart_advertising_report_t **report, smartbridge_auto_conn_state_t state) { - OSStatus err = oNoErr; + OSStatus err = kNoErr; smartbridge_auto_conn_report_t *current_report; - require_action(report != NULL, exit, err = oParamErr); + require_action(report != NULL, exit, err = kParamErr); - aos_rtos_lock_mutex(&g_auto_conn_list.mutex); + mico_rtos_lock_mutex(&g_auto_conn_list.mutex); err = linked_list_find_node(&g_auto_conn_list.list, (linked_list_compare_callback_t)smartbridge_auto_conn_compare_state, (void *)&state, (linked_list_node_t **)¤t_report); *report = ¤t_report->report; - aos_rtos_unlock_mutex(&g_auto_conn_list.mutex); + mico_rtos_unlock_mutex(&g_auto_conn_list.mutex); exit: return err; } -static OSStatus smartbridge_auto_conn_list_set_state(const aos_bt_device_address_t bdaddr, +static OSStatus smartbridge_auto_conn_list_set_state(const mico_bt_device_address_t bdaddr, smartbridge_auto_conn_state_t state) { - OSStatus err = oNoErr; + OSStatus err = kNoErr; smartbridge_auto_conn_report_t *report_found; - require_action(bdaddr != NULL, exit, err = oParamErr); + require_action(bdaddr != NULL, exit, err = kParamErr); - aos_rtos_lock_mutex(&g_auto_conn_list.mutex); + mico_rtos_lock_mutex(&g_auto_conn_list.mutex); err = linked_list_find_node(&g_auto_conn_list.list, (linked_list_compare_callback_t)smartbridge_auto_conn_compare_bdaddr, (void *)bdaddr, (linked_list_node_t **)&report_found); - if (err == oNoErr) { + if (err == kNoErr) { report_found->state = state; } - aos_rtos_unlock_mutex(&g_auto_conn_list.mutex); + mico_rtos_unlock_mutex(&g_auto_conn_list.mutex); exit: return err; } -static OSStatus smartbridge_auto_conn_list_remove(aos_bt_device_address_t bdaddr) +static OSStatus smartbridge_auto_conn_list_remove(mico_bt_device_address_t bdaddr) { - OSStatus err = oNoErr; + OSStatus err = kNoErr; smartbridge_auto_conn_report_t *current_report; - aos_rtos_lock_mutex(&g_auto_conn_list.mutex); + mico_rtos_lock_mutex(&g_auto_conn_list.mutex); err = linked_list_find_node(&g_auto_conn_list.list, (linked_list_compare_callback_t)smartbridge_auto_conn_compare_bdaddr, bdaddr, (linked_list_node_t **)¤t_report); - if (err != oNoErr) { + if (err != kNoErr) { goto exit; } current_report->state = SMARTBRIDGE_AUTO_CONN_STATE_FREE; exit: - aos_rtos_unlock_mutex(&g_auto_conn_list.mutex); + mico_rtos_unlock_mutex(&g_auto_conn_list.mutex); return err; } static OSStatus smartbridge_auto_conn_list_remove_by_state(smartbridge_auto_conn_state_t state) { - OSStatus err = oNoErr; + OSStatus err = kNoErr; smartbridge_auto_conn_report_t *current_report; - aos_rtos_lock_mutex(&g_auto_conn_list.mutex); + mico_rtos_lock_mutex(&g_auto_conn_list.mutex); do { err = linked_list_find_node(&g_auto_conn_list.list, (linked_list_compare_callback_t)smartbridge_auto_conn_compare_state, &state, (linked_list_node_t **)¤t_report); - if (err != oNoErr) { + if (err != kNoErr) { break; } current_report->state = SMARTBRIDGE_AUTO_CONN_STATE_FREE; } while (1); - aos_rtos_unlock_mutex(&g_auto_conn_list.mutex); + mico_rtos_unlock_mutex(&g_auto_conn_list.mutex); - return oNoErr; + return kNoErr; } static OSStatus smartbridge_auto_conn_list_clear(void) { - OSStatus err = oNoErr; + OSStatus err = kNoErr; smartbridge_auto_conn_report_t *current_report = NULL; - aos_rtos_lock_mutex(&g_auto_conn_list.mutex); + mico_rtos_lock_mutex(&g_auto_conn_list.mutex); do { err = linked_list_get_front_node(&g_auto_conn_list.list, (linked_list_node_t **)¤t_report); - if (err != oNoErr) { + if (err != kNoErr) { break; } linked_list_remove_node(&g_auto_conn_list.list, ¤t_report->this_node); free(current_report); } while (1); - aos_rtos_unlock_mutex(&g_auto_conn_list.mutex); + mico_rtos_unlock_mutex(&g_auto_conn_list.mutex); - return oNoErr; + return kNoErr; } diff --git a/framework/bluetooth/smartbt/bt_smartbridge_cfg.c b/device/bluetooth/mk3239/bt_smart/mico_bt_smartbridge_cfg.c similarity index 50% rename from framework/bluetooth/smartbt/bt_smartbridge_cfg.c rename to device/bluetooth/mk3239/bt_smart/mico_bt_smartbridge_cfg.c index 66321cc350..5537113a95 100644 --- a/framework/bluetooth/smartbt/bt_smartbridge_cfg.c +++ b/device/bluetooth/mk3239/bt_smart/mico_bt_smartbridge_cfg.c @@ -1,73 +1,69 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - /** @file * * Runtime Bluetooth stack configuration parameters * */ -#include "smartbt_cfg.h" +#include "mico_bt_cfg.h" /***************************************************************************** * BTE stack configuration ****************************************************************************/ -aos_bt_cfg_settings_t aos_bt_cfg_settings = { - .device_name = (uint8_t *)"AOS BT Gateway", /**< Local device name (NULL terminated) */ +mico_bt_cfg_settings_t mico_bt_cfg_settings = { + .device_name = (uint8_t *)"MiCO BT Gateway", /**< Local device name (NULL terminated) */ .device_class = { 0x00, 0x00, 0x00 }, /**< Local device class */ - .security_requirement_mask = BTM_SEC_NONE, /**< Security requirements mask (BTM_SEC_NONE, or combination of BTM_SEC_IN_AUTHENTICATE, BTM_SEC_OUT_AUTHENTICATE, BTM_SEC_ENCRYPT (see #aos_bt_sec_level_e)) */ + .security_requirement_mask = BTM_SEC_NONE, /**< Security requirements mask (BTM_SEC_NONE, or combination of BTM_SEC_IN_AUTHENTICATE, BTM_SEC_OUT_AUTHENTICATE, BTM_SEC_ENCRYPT (see #mico_bt_sec_level_e)) */ .max_simultaneous_links = 3, /**< Maximum number simultaneous links to different devices */ /* Scan and advertisement configuration */ .br_edr_scan_cfg = /**< BR/EDR scan settings */ { .inquiry_scan_type = BTM_SCAN_TYPE_STANDARD, /**< Inquiry scan type (BTM_SCAN_TYPE_STANDARD or BTM_SCAN_TYPE_INTERLACED) */ - .inquiry_scan_interval = AOS_BT_CFG_DEFAULT_INQUIRY_SCAN_INTERVAL, /**< Inquiry scan interval (default: AOS_BT_CFG_DEFAULT_INQUIRY_SCAN_INTERVAL) */ - .inquiry_scan_window = AOS_BT_CFG_DEFAULT_INQUIRY_SCAN_WINDOW, /**< Inquiry scan window (default: AOS_BT_CFG_DEFAULT_INQUIRY_SCAN_WINDOW) */ + .inquiry_scan_interval = MICO_BT_CFG_DEFAULT_INQUIRY_SCAN_INTERVAL, /**< Inquiry scan interval (default: MICO_BT_CFG_DEFAULT_INQUIRY_SCAN_INTERVAL) */ + .inquiry_scan_window = MICO_BT_CFG_DEFAULT_INQUIRY_SCAN_WINDOW, /**< Inquiry scan window (default: MICO_BT_CFG_DEFAULT_INQUIRY_SCAN_WINDOW) */ .page_scan_type = BTM_SCAN_TYPE_STANDARD, /**< Page scan type (BTM_SCAN_TYPE_STANDARD or BTM_SCAN_TYPE_INTERLACED) */ - .page_scan_interval = AOS_BT_CFG_DEFAULT_PAGE_SCAN_INTERVAL, /**< Page scan interval (default: AOS_BT_CFG_DEFAULT_PAGE_SCAN_INTERVAL) */ - .page_scan_window = AOS_BT_CFG_DEFAULT_PAGE_SCAN_WINDOW, /**< Page scan window (default: AOS_BT_CFG_DEFAULT_PAGE_SCAN_WINDOW) */ + .page_scan_interval = MICO_BT_CFG_DEFAULT_PAGE_SCAN_INTERVAL, /**< Page scan interval (default: MICO_BT_CFG_DEFAULT_PAGE_SCAN_INTERVAL) */ + .page_scan_window = MICO_BT_CFG_DEFAULT_PAGE_SCAN_WINDOW, /**< Page scan window (default: MICO_BT_CFG_DEFAULT_PAGE_SCAN_WINDOW) */ }, .ble_scan_cfg = /**< BLE scan settings */ { .scan_mode = BTM_BLE_SCAN_MODE_PASSIVE, /**< BLE scan mode (BTM_BLE_SCAN_MODE_PASSIVE, BTM_BLE_SCAN_MODE_ACTIVE) */ .scan_filter_policy = BTM_BLE_SCAN_FILTER_POLICY_NONE, - .high_duty_scan_interval = AOS_BT_CFG_DEFAULT_HIGH_DUTY_SCAN_INTERVAL, /**< High duty scan interval (default: AOS_BT_CFG_DEFAULT_HIGH_DUTY_SCAN_INTERVAL) */ - .high_duty_scan_window = AOS_BT_CFG_DEFAULT_HIGH_DUTY_SCAN_WINDOW, /**< High duty scan window (default: AOS_BT_CFG_DEFAULT_HIGH_DUTY_SCAN_WINDOW) */ + .high_duty_scan_interval = MICO_BT_CFG_DEFAULT_HIGH_DUTY_SCAN_INTERVAL, /**< High duty scan interval (default: MICO_BT_CFG_DEFAULT_HIGH_DUTY_SCAN_INTERVAL) */ + .high_duty_scan_window = MICO_BT_CFG_DEFAULT_HIGH_DUTY_SCAN_WINDOW, /**< High duty scan window (default: MICO_BT_CFG_DEFAULT_HIGH_DUTY_SCAN_WINDOW) */ .high_duty_scan_duration = 3, /**< High duty scan duration in seconds (0 for infinite) */ - .low_duty_scan_interval = AOS_BT_CFG_DEFAULT_LOW_DUTY_SCAN_INTERVAL, /**< Low duty scan interval (default: AOS_BT_CFG_DEFAULT_LOW_DUTY_SCAN_INTERVAL) */ - .low_duty_scan_window = AOS_BT_CFG_DEFAULT_LOW_DUTY_SCAN_WINDOW, /**< Low duty scan window (default: AOS_BT_CFG_DEFAULT_LOW_DUTY_SCAN_WINDOW) */ + .low_duty_scan_interval = MICO_BT_CFG_DEFAULT_LOW_DUTY_SCAN_INTERVAL, /**< Low duty scan interval (default: MICO_BT_CFG_DEFAULT_LOW_DUTY_SCAN_INTERVAL) */ + .low_duty_scan_window = MICO_BT_CFG_DEFAULT_LOW_DUTY_SCAN_WINDOW, /**< Low duty scan window (default: MICO_BT_CFG_DEFAULT_LOW_DUTY_SCAN_WINDOW) */ .low_duty_scan_duration = 3, /**< Low duty scan duration in seconds (0 for infinite) */ - .high_duty_conn_scan_interval = AOS_BT_CFG_DEFAULT_HIGH_DUTY_CONN_SCAN_INTERVAL, /**< High duty cycle connection scan interval (default: AOS_BT_CFG_DEFAULT_HIGH_DUTY_CONN_SCAN_INTERVAL) */ - .high_duty_conn_scan_window = AOS_BT_CFG_DEFAULT_HIGH_DUTY_CONN_SCAN_WINDOW, /**< High duty cycle connection scan window (default: AOS_BT_CFG_DEFAULT_HIGH_DUTY_CONN_SCAN_WINDOW) */ + .high_duty_conn_scan_interval = MICO_BT_CFG_DEFAULT_HIGH_DUTY_CONN_SCAN_INTERVAL, /**< High duty cycle connection scan interval (default: MICO_BT_CFG_DEFAULT_HIGH_DUTY_CONN_SCAN_INTERVAL) */ + .high_duty_conn_scan_window = MICO_BT_CFG_DEFAULT_HIGH_DUTY_CONN_SCAN_WINDOW, /**< High duty cycle connection scan window (default: MICO_BT_CFG_DEFAULT_HIGH_DUTY_CONN_SCAN_WINDOW) */ .high_duty_conn_duration = 0, /**< High duty cycle connection duration in seconds (0 for infinite) */ - .low_duty_conn_scan_interval = AOS_BT_CFG_DEFAULT_LOW_DUTY_CONN_SCAN_INTERVAL, /**< Low duty cycle connection scan interval (default: AOS_BT_CFG_DEFAULT_LOW_DUTY_CONN_SCAN_INTERVAL) */ - .low_duty_conn_scan_window = AOS_BT_CFG_DEFAULT_LOW_DUTY_CONN_SCAN_WINDOW, /**< Low duty cycle connection scan window (default: AOS_BT_CFG_DEFAULT_LOW_DUTY_CONN_SCAN_WINDOW) */ + .low_duty_conn_scan_interval = MICO_BT_CFG_DEFAULT_LOW_DUTY_CONN_SCAN_INTERVAL, /**< Low duty cycle connection scan interval (default: MICO_BT_CFG_DEFAULT_LOW_DUTY_CONN_SCAN_INTERVAL) */ + .low_duty_conn_scan_window = MICO_BT_CFG_DEFAULT_LOW_DUTY_CONN_SCAN_WINDOW, /**< Low duty cycle connection scan window (default: MICO_BT_CFG_DEFAULT_LOW_DUTY_CONN_SCAN_WINDOW) */ .low_duty_conn_duration = 0, /**< Low duty cycle connection duration in seconds (0 for infinite) */ - .conn_min_interval = AOS_BT_CFG_DEFAULT_CONN_MIN_INTERVAL, /**< Minimum connection interval (default: AOS_BT_CFG_DEFAULT_CONN_MIN_INTERVAL) */ - .conn_max_interval = AOS_BT_CFG_DEFAULT_CONN_MAX_INTERVAL, /**< Maximum connection interval (default: AOS_BT_CFG_DEFAULT_CONN_MAX_INTERVAL) */ - .conn_latency = AOS_BT_CFG_DEFAULT_CONN_LATENCY, /**< Connection latency (default: AOS_BT_CFG_DEFAULT_CONN_LATENCY) */ - .conn_supervision_timeout = AOS_BT_CFG_DEFAULT_CONN_SUPERVISION_TIMEOUT, /**< Connection link supervision timeout (default: AOS_BT_CFG_DEFAULT_ CONN_SUPERVISION_TIMEOUT) */ + .conn_min_interval = MICO_BT_CFG_DEFAULT_CONN_MIN_INTERVAL, /**< Minimum connection interval (default: MICO_BT_CFG_DEFAULT_CONN_MIN_INTERVAL) */ + .conn_max_interval = MICO_BT_CFG_DEFAULT_CONN_MAX_INTERVAL, /**< Maximum connection interval (default: MICO_BT_CFG_DEFAULT_CONN_MAX_INTERVAL) */ + .conn_latency = MICO_BT_CFG_DEFAULT_CONN_LATENCY, /**< Connection latency (default: MICO_BT_CFG_DEFAULT_CONN_LATENCY) */ + .conn_supervision_timeout = MICO_BT_CFG_DEFAULT_CONN_SUPERVISION_TIMEOUT, /**< Connection link supervision timeout (default: MICO_BT_CFG_DEFAULT_ CONN_SUPERVISION_TIMEOUT) */ }, .ble_advert_cfg = /**< BLE advertisement settings */ { .channel_map = ( BTM_BLE_ADVERT_CHNL_37 | BTM_BLE_ADVERT_CHNL_38 | BTM_BLE_ADVERT_CHNL_39 ), /**< Advertising channel map (mask of BTM_BLE_ADVERT_CHNL_37, BTM_BLE_ADVERT_CHNL_38, BTM_BLE_ADVERT_CHNL_39) */ - .high_duty_min_interval = AOS_BT_CFG_DEFAULT_HIGH_DUTY_ADV_MIN_INTERVAL, /**< High duty undirected connectable advert minimum advertising interval (default: AOS_BT_CFG_DEFAULT_HIGH_DUTY_ADV_MIN_INTERVAL) */ - .high_duty_max_interval = AOS_BT_CFG_DEFAULT_HIGH_DUTY_ADV_MAX_INTERVAL, /**< High duty undirected connectable advert maximum advertising interval (default: AOS_BT_CFG_DEFAULT_HIGH_DUTY_ADV_MAX_INTERVAL) */ + .high_duty_min_interval = MICO_BT_CFG_DEFAULT_HIGH_DUTY_ADV_MIN_INTERVAL, /**< High duty undirected connectable advert minimum advertising interval (default: MICO_BT_CFG_DEFAULT_HIGH_DUTY_ADV_MIN_INTERVAL) */ + .high_duty_max_interval = MICO_BT_CFG_DEFAULT_HIGH_DUTY_ADV_MAX_INTERVAL, /**< High duty undirected connectable advert maximum advertising interval (default: MICO_BT_CFG_DEFAULT_HIGH_DUTY_ADV_MAX_INTERVAL) */ .high_duty_duration = 30, /**< High duty advertising duration in seconds (0 for infinite) */ - .low_duty_min_interval = AOS_BT_CFG_DEFAULT_LOW_DUTY_ADV_MIN_INTERVAL, /**< Low duty undirected connectable advert minimum advertising interval (default: AOS_BT_CFG_DEFAULT_LOW_DUTY_ADV_MIN_INTERVAL) */ - .low_duty_max_interval = AOS_BT_CFG_DEFAULT_LOW_DUTY_ADV_MAX_INTERVAL, /**< Low duty undirected connectable advert maximum advertising interval (default: AOS_BT_CFG_DEFAULT_LOW_DUTY_ADV_MAX_INTERVAL) */ + .low_duty_min_interval = MICO_BT_CFG_DEFAULT_LOW_DUTY_ADV_MIN_INTERVAL, /**< Low duty undirected connectable advert minimum advertising interval (default: MICO_BT_CFG_DEFAULT_LOW_DUTY_ADV_MIN_INTERVAL) */ + .low_duty_max_interval = MICO_BT_CFG_DEFAULT_LOW_DUTY_ADV_MAX_INTERVAL, /**< Low duty undirected connectable advert maximum advertising interval (default: MICO_BT_CFG_DEFAULT_LOW_DUTY_ADV_MAX_INTERVAL) */ .low_duty_duration = 30, /**< Low duty advertising duration in seconds (0 for infinite) */ - .high_duty_directed_min_interval = AOS_BT_CFG_DEFAULT_HIGH_DUTY_DIRECTED_ADV_MIN_INTERVAL, /**< high duty directed adv minimum advertising interval (default: AOS_BT_CFG_DEFAULT_HIGH_DUTY_DIRECTED_ADV_MIN_INTERVAL) */ - .high_duty_directed_max_interval = AOS_BT_CFG_DEFAULT_HIGH_DUTY_DIRECTED_ADV_MAX_INTERVAL, /**< high duty directed adv maximum advertising interval (default: AOS_BT_CFG_DEFAULT_HIGH_DUTY_DIRECTED_ADV_MAX_INTERVAL) */ - .low_duty_directed_min_interval = AOS_BT_CFG_DEFAULT_LOW_DUTY_DIRECTED_ADV_MIN_INTERVAL, /**< Low duty directed adv minimum advertising interval (default: AOS_BT_CFG_DEFAULT_LOW_DUTY_DIRECTED_ADV_MIN_INTERVAL) */ - .low_duty_directed_max_interval = AOS_BT_CFG_DEFAULT_LOW_DUTY_DIRECTED_ADV_MAX_INTERVAL, /**< Low duty directed adv maximum advertising interval (default: AOS_BT_CFG_DEFAULT_LOW_DUTY_DIRECTED_ADV_MAX_INTERVAL) */ + .high_duty_directed_min_interval = MICO_BT_CFG_DEFAULT_HIGH_DUTY_DIRECTED_ADV_MIN_INTERVAL, /**< high duty directed adv minimum advertising interval (default: MICO_BT_CFG_DEFAULT_HIGH_DUTY_DIRECTED_ADV_MIN_INTERVAL) */ + .high_duty_directed_max_interval = MICO_BT_CFG_DEFAULT_HIGH_DUTY_DIRECTED_ADV_MAX_INTERVAL, /**< high duty directed adv maximum advertising interval (default: MICO_BT_CFG_DEFAULT_HIGH_DUTY_DIRECTED_ADV_MAX_INTERVAL) */ + .low_duty_directed_min_interval = MICO_BT_CFG_DEFAULT_LOW_DUTY_DIRECTED_ADV_MIN_INTERVAL, /**< Low duty directed adv minimum advertising interval (default: MICO_BT_CFG_DEFAULT_LOW_DUTY_DIRECTED_ADV_MIN_INTERVAL) */ + .low_duty_directed_max_interval = MICO_BT_CFG_DEFAULT_LOW_DUTY_DIRECTED_ADV_MAX_INTERVAL, /**< Low duty directed adv maximum advertising interval (default: MICO_BT_CFG_DEFAULT_LOW_DUTY_DIRECTED_ADV_MAX_INTERVAL) */ .low_duty_directed_duration = 30, /**< Low duty directed advertising duration in seconds (0 for infinite) */ - .high_duty_nonconn_min_interval = AOS_BT_CFG_DEFAULT_HIGH_DUTY_NONCONN_ADV_MIN_INTERVAL, /**< High duty non-connectable adv minimum advertising interval (default: AOS_BT_CFG_DEFAULT_HIGH_DUTY_NONCONN_ADV_MIN_INTERVAL) */ - .high_duty_nonconn_max_interval = AOS_BT_CFG_DEFAULT_HIGH_DUTY_NONCONN_ADV_MAX_INTERVAL, /**< High duty non-connectable adv maximum advertising interval (default: AOS_BT_CFG_DEFAULT_HIGH_DUTY_NONCONN_ADV_MAX_INTERVAL) */ + .high_duty_nonconn_min_interval = MICO_BT_CFG_DEFAULT_HIGH_DUTY_NONCONN_ADV_MIN_INTERVAL, /**< High duty non-connectable adv minimum advertising interval (default: MICO_BT_CFG_DEFAULT_HIGH_DUTY_NONCONN_ADV_MIN_INTERVAL) */ + .high_duty_nonconn_max_interval = MICO_BT_CFG_DEFAULT_HIGH_DUTY_NONCONN_ADV_MAX_INTERVAL, /**< High duty non-connectable adv maximum advertising interval (default: MICO_BT_CFG_DEFAULT_HIGH_DUTY_NONCONN_ADV_MAX_INTERVAL) */ .high_duty_nonconn_duration = 30, /**< High duty non-connectable advertising duration in seconds (0 for infinite) */ - .low_duty_nonconn_min_interval = AOS_BT_CFG_DEFAULT_LOW_DUTY_NONCONN_ADV_MIN_INTERVAL, /**< Low duty non-connectable adv minimum advertising interval (default: AOS_BT_CFG_DEFAULT_LOW_DUTY_NONCONN_ADV_MIN_INTERVAL) */ - .low_duty_nonconn_max_interval = AOS_BT_CFG_DEFAULT_LOW_DUTY_NONCONN_ADV_MAX_INTERVAL, /**< Low duty non-connectable adv maximum advertising interval (default: AOS_BT_CFG_DEFAULT_LOW_DUTY_NONCONN_ADV_MAX_INTERVAL) */ + .low_duty_nonconn_min_interval = MICO_BT_CFG_DEFAULT_LOW_DUTY_NONCONN_ADV_MIN_INTERVAL, /**< Low duty non-connectable adv minimum advertising interval (default: MICO_BT_CFG_DEFAULT_LOW_DUTY_NONCONN_ADV_MIN_INTERVAL) */ + .low_duty_nonconn_max_interval = MICO_BT_CFG_DEFAULT_LOW_DUTY_NONCONN_ADV_MAX_INTERVAL, /**< Low duty non-connectable adv maximum advertising interval (default: MICO_BT_CFG_DEFAULT_LOW_DUTY_NONCONN_ADV_MAX_INTERVAL) */ .low_duty_nonconn_duration = 30, /**< Low duty non-connectable advertising duration in seconds (0 for infinite) */ }, @@ -114,14 +110,14 @@ aos_bt_cfg_settings_t aos_bt_cfg_settings = { /***************************************************************************** - * aos_bt_stack buffer pool configuration + * mico_bt_stack buffer pool configuration * * Configure buffer pools used by the stack * * Pools must be ordered in increasing buf_size. * If a pool runs out of buffers, the next pool will be used *****************************************************************************/ -const aos_bt_cfg_buf_pool_t aos_bt_cfg_buf_pools[AOS_BT_CFG_NUM_BUF_POOLS] = { +const mico_bt_cfg_buf_pool_t mico_bt_cfg_buf_pools[MICO_BT_CFG_NUM_BUF_POOLS] = { /* { buf_size, buf_count } */ { 64, 4 }, /* Small Buffer Pool */ { 360, 4 }, /* Medium Buffer Pool (used for HCI & RFCOMM control messages, min recommended size is 360) */ diff --git a/device/bluetooth/mk3239/bt_smart/mico_bt_smartbridge_gatt.c b/device/bluetooth/mk3239/bt_smart/mico_bt_smartbridge_gatt.c new file mode 100644 index 0000000000..5594c83a92 --- /dev/null +++ b/device/bluetooth/mk3239/bt_smart/mico_bt_smartbridge_gatt.c @@ -0,0 +1,333 @@ +/** @file + * + */ + +#include "mico.h" +#include "mico_bt_smartbridge.h" +#include "mico_bt_smartbridge_gatt.h" +#include "bt_smartbridge_stack_interface.h" +#include "bt_smartbridge_helper.h" + +/****************************************************** + * Macros + ******************************************************/ + +/****************************************************** + * Constants + ******************************************************/ + +/****************************************************** + * Enumerations + ******************************************************/ + +/****************************************************** + * Type Definitions + ******************************************************/ + +/****************************************************** + * Structures + ******************************************************/ + +/****************************************************** + * Static Function Declarations + ******************************************************/ + +/****************************************************** + * Variable Definitions + ******************************************************/ + +/****************************************************** + * Function Definitions + ******************************************************/ + +OSStatus mico_bt_smartbridge_gatt_discover_all_primary_services( const mico_bt_smartbridge_socket_t *socket, + mico_bt_smart_attribute_list_t *service_list ) +{ + mico_bt_smartbridge_socket_status_t status; + + if ( socket == NULL || service_list == NULL ) { + return MICO_BT_BADARG; + } + + mico_bt_smartbridge_get_socket_status( (mico_bt_smartbridge_socket_t *)socket, &status ); + + if ( status != SMARTBRIDGE_SOCKET_CONNECTED ) { + return MICO_BT_SOCKET_NOT_CONNECTED; + } + + return smartbridge_bt_interface_discover_all_primary_services( socket->connection_handle, service_list ); +} + +OSStatus mico_bt_smartbridge_gatt_discover_primary_services_by_uuid( const mico_bt_smartbridge_socket_t *socket, + const mico_bt_uuid_t *uuid, mico_bt_smart_attribute_list_t *service_list ) +{ + mico_bt_smartbridge_socket_status_t status; + + if ( socket == NULL || uuid == NULL || service_list == NULL ) { + return MICO_BT_BADARG; + } + + mico_bt_smartbridge_get_socket_status( (mico_bt_smartbridge_socket_t *)socket, &status ); + if ( status != SMARTBRIDGE_SOCKET_CONNECTED ) { + return MICO_BT_SOCKET_NOT_CONNECTED; + } + + return smartbridge_bt_interface_discover_primary_services_by_uuid( socket->connection_handle, uuid, service_list ); +} + +OSStatus mico_bt_smartbridge_gatt_find_included_services( const mico_bt_smartbridge_socket_t *socket, + uint16_t start_handle, uint16_t end_handle, mico_bt_smart_attribute_list_t *include_list ) +{ + mico_bt_smartbridge_socket_status_t status; + + if ( socket == NULL || include_list == NULL ) { + return MICO_BT_BADARG; + } + + mico_bt_smartbridge_get_socket_status( (mico_bt_smartbridge_socket_t *)socket, &status ); + if ( status != SMARTBRIDGE_SOCKET_CONNECTED ) { + return MICO_BT_SOCKET_NOT_CONNECTED; + } + + return smartbridge_bt_interface_find_included_services( socket->connection_handle, start_handle, end_handle, + include_list ); +} + +OSStatus mico_bt_smartbridge_gatt_discover_all_characteristics_in_a_service( const mico_bt_smartbridge_socket_t *socket, + uint16_t start_handle, uint16_t end_handle, mico_bt_smart_attribute_list_t *characteristic_list ) +{ + mico_bt_smartbridge_socket_status_t status; + + if ( socket == NULL || characteristic_list == NULL ) { + return MICO_BT_BADARG; + } + + mico_bt_smartbridge_get_socket_status( (mico_bt_smartbridge_socket_t *)socket, &status ); + if ( status != SMARTBRIDGE_SOCKET_CONNECTED ) { + return MICO_BT_SOCKET_NOT_CONNECTED; + } + return smartbridge_bt_interface_discover_all_characteristics_in_a_service( socket->connection_handle, start_handle, + end_handle, characteristic_list ); +} + +OSStatus mico_bt_smartbridge_gatt_discover_characteristic_by_uuid( const mico_bt_smartbridge_socket_t *socket, + const mico_bt_uuid_t *uuid, uint16_t start_handle, uint16_t end_handle, + mico_bt_smart_attribute_list_t *characteristic_list ) +{ + mico_bt_smartbridge_socket_status_t status; + + if ( socket == NULL || uuid == NULL || characteristic_list == NULL ) { + return MICO_BT_BADARG; + } + + mico_bt_smartbridge_get_socket_status( (mico_bt_smartbridge_socket_t *)socket, &status ); + if ( status != SMARTBRIDGE_SOCKET_CONNECTED ) { + return MICO_BT_SOCKET_NOT_CONNECTED; + } + + return smartbridge_bt_interface_discover_characteristic_by_uuid( socket->connection_handle, uuid, start_handle, + end_handle, characteristic_list ); +} + +OSStatus mico_bt_smartbridge_gatt_discover_handle_and_type_of_all_characteristic_descriptors( + const mico_bt_smartbridge_socket_t *socket, uint16_t start_handle, uint16_t end_handle, + mico_bt_smart_attribute_list_t *descriptor_list ) +{ + mico_bt_smartbridge_socket_status_t status; + + if ( socket == NULL || descriptor_list == NULL ) { + return MICO_BT_BADARG; + } + + mico_bt_smartbridge_get_socket_status( (mico_bt_smartbridge_socket_t *)socket, &status ); + if ( status != SMARTBRIDGE_SOCKET_CONNECTED ) { + return MICO_BT_SOCKET_NOT_CONNECTED; + } + + return smartbridge_bt_interface_discover_all_characteristic_descriptors( socket->connection_handle, start_handle, + end_handle, descriptor_list ); +} + +OSStatus mico_bt_smartbridge_gatt_read_characteristic_descriptor( const mico_bt_smartbridge_socket_t *socket, + uint16_t handle, const mico_bt_uuid_t *uuid, mico_bt_smart_attribute_t **descriptor ) +{ + mico_bt_smartbridge_socket_status_t status; + + if ( socket == NULL || uuid == NULL || descriptor == NULL ) { + return MICO_BT_BADARG; + } + + mico_bt_smartbridge_get_socket_status( (mico_bt_smartbridge_socket_t *)socket, &status ); + if ( status != SMARTBRIDGE_SOCKET_CONNECTED ) { + return MICO_BT_SOCKET_NOT_CONNECTED; + } + + return smartbridge_bt_interface_read_characteristic_descriptor( socket->connection_handle, handle, uuid, descriptor ); +} + +OSStatus mico_bt_smartbridge_gatt_read_long_characteristic_descriptor( const mico_bt_smartbridge_socket_t *socket, + uint16_t handle, const mico_bt_uuid_t *uuid, mico_bt_smart_attribute_t **descriptor ) +{ + mico_bt_smartbridge_socket_status_t status; + + if ( socket == NULL || uuid == NULL || descriptor == NULL ) { + return MICO_BT_BADARG; + } + + mico_bt_smartbridge_get_socket_status( (mico_bt_smartbridge_socket_t *)socket, &status ); + if ( status != SMARTBRIDGE_SOCKET_CONNECTED ) { + return MICO_BT_SOCKET_NOT_CONNECTED; + } + + return smartbridge_bt_interface_read_long_characteristic_descriptor( socket->connection_handle, handle, uuid, + descriptor ); +} + +OSStatus mico_bt_smartbridge_gatt_write_characteristic_descriptor( const mico_bt_smartbridge_socket_t *socket, + const mico_bt_smart_attribute_t *descriptor ) +{ + mico_bt_smartbridge_socket_status_t status; + + if ( socket == NULL || descriptor == NULL ) { + return MICO_BT_BADARG; + } + + mico_bt_smartbridge_get_socket_status( (mico_bt_smartbridge_socket_t *)socket, &status ); + if ( status != SMARTBRIDGE_SOCKET_CONNECTED ) { + return MICO_BT_SOCKET_NOT_CONNECTED; + } + + return smartbridge_bt_interface_write_characteristic_descriptor( socket->connection_handle, + (mico_bt_smart_attribute_t *)descriptor ); +} + +OSStatus mico_bt_smartbridge_gatt_write_long_characteristic_descriptor( const mico_bt_smartbridge_socket_t *socket, + const mico_bt_smart_attribute_t *descriptor ) +{ + mico_bt_smartbridge_socket_status_t status; + + if ( socket == NULL || descriptor == NULL ) { + return MICO_BT_BADARG; + } + + mico_bt_smartbridge_get_socket_status( (mico_bt_smartbridge_socket_t *)socket, &status ); + if ( status != SMARTBRIDGE_SOCKET_CONNECTED ) { + return MICO_BT_SOCKET_NOT_CONNECTED; + } + + return smartbridge_bt_interface_write_long_characteristic_descriptor( socket->connection_handle, + (mico_bt_smart_attribute_t *)descriptor ); +} + +OSStatus mico_bt_smartbridge_gatt_read_characteristic_value( const mico_bt_smartbridge_socket_t *socket, + uint16_t handle, const mico_bt_uuid_t *uuid, mico_bt_smart_attribute_t **characteristic_value ) +{ + mico_bt_smartbridge_socket_status_t status; + + if ( socket == NULL || uuid == NULL || characteristic_value == NULL ) { + return MICO_BT_BADARG; + } + + mico_bt_smartbridge_get_socket_status( (mico_bt_smartbridge_socket_t *)socket, &status ); + if ( status != SMARTBRIDGE_SOCKET_CONNECTED ) { + return MICO_BT_SOCKET_NOT_CONNECTED; + } + + return smartbridge_bt_interface_read_characteristic_value( socket->connection_handle, handle, uuid, + characteristic_value ); +} + +OSStatus mico_bt_smartbridge_gatt_read_characteristic_values_using_uuid( const mico_bt_smartbridge_socket_t *socket, + const mico_bt_uuid_t *uuid, mico_bt_smart_attribute_list_t *characteristic_value_list ) +{ + mico_bt_smartbridge_socket_status_t status; + + if ( socket == NULL || uuid == NULL || characteristic_value_list == NULL ) { + return MICO_BT_BADARG; + } + + mico_bt_smartbridge_get_socket_status( (mico_bt_smartbridge_socket_t *)socket, &status ); + if ( status != SMARTBRIDGE_SOCKET_CONNECTED ) { + return MICO_BT_SOCKET_NOT_CONNECTED; + } + + return smartbridge_bt_interface_read_characteristic_values_using_uuid( socket->connection_handle, uuid, + characteristic_value_list ); +} + +OSStatus mico_bt_smartbridge_gatt_read_long_characteristic_value( const mico_bt_smartbridge_socket_t *socket, + uint16_t handle, const mico_bt_uuid_t *uuid, mico_bt_smart_attribute_t **characteristic_value ) +{ + mico_bt_smartbridge_socket_status_t status; + + if ( socket == NULL || uuid == NULL || characteristic_value == NULL ) { + return MICO_BT_BADARG; + } + + mico_bt_smartbridge_get_socket_status( (mico_bt_smartbridge_socket_t *)socket, &status ); + if ( status != SMARTBRIDGE_SOCKET_CONNECTED ) { + return MICO_BT_SOCKET_NOT_CONNECTED; + } + + return smartbridge_bt_interface_read_long_characteristic_value( socket->connection_handle, handle, uuid, + characteristic_value ); +} + +OSStatus mico_bt_smartbridge_gatt_write_characteristic_value_without_response( const mico_bt_smartbridge_socket_t + *socket, const mico_bt_smart_attribute_t *characteristic_value ) +{ + UNUSED_PARAMETER( socket ); + UNUSED_PARAMETER( characteristic_value ); + return MICO_BT_UNSUPPORTED; +} + +OSStatus mico_bt_smartbridge_gatt_signed_write_characteristic_value_without_response( + const mico_bt_smartbridge_socket_t *socket, const mico_bt_smart_attribute_t *characteristic_value ) +{ + UNUSED_PARAMETER( socket ); + UNUSED_PARAMETER( characteristic_value ); + return MICO_BT_UNSUPPORTED; +} + +OSStatus mico_bt_smartbridge_gatt_write_characteristic_value( const mico_bt_smartbridge_socket_t *socket, + const mico_bt_smart_attribute_t *characteristic_value ) +{ + mico_bt_smartbridge_socket_status_t status; + + if ( socket == NULL || characteristic_value == NULL ) { + return MICO_BT_BADARG; + } + + mico_bt_smartbridge_get_socket_status( (mico_bt_smartbridge_socket_t *)socket, &status ); + if ( status != SMARTBRIDGE_SOCKET_CONNECTED ) { + return MICO_BT_SOCKET_NOT_CONNECTED; + } + return smartbridge_bt_interface_write_characteristic_value( socket->connection_handle, + (mico_bt_smart_attribute_t *)characteristic_value ); +} + +OSStatus mico_bt_smartbridge_gatt_write_long_characteristic_value( const mico_bt_smartbridge_socket_t *socket, + const mico_bt_smart_attribute_t *characteristic_value ) +{ + mico_bt_smartbridge_socket_status_t status; + + if ( socket == NULL || characteristic_value == NULL ) { + return MICO_BT_BADARG; + } + + mico_bt_smartbridge_get_socket_status( (mico_bt_smartbridge_socket_t *)socket, &status ); + if ( status != SMARTBRIDGE_SOCKET_CONNECTED ) { + return MICO_BT_SOCKET_NOT_CONNECTED; + } + + return smartbridge_bt_interface_write_long_characteristic_value( socket->connection_handle, + (mico_bt_smart_attribute_t *)characteristic_value ); +} + +OSStatus mico_bt_smartbridge_gatt_reliable_write_characteristic_value( const mico_bt_smartbridge_socket_t *socket, + const mico_bt_smart_attribute_t *characteristic_value ) +{ + UNUSED_PARAMETER( socket ); + UNUSED_PARAMETER( characteristic_value ); + return MICO_BT_UNSUPPORTED; +} diff --git a/device/bluetooth/mk3239/dual_mode/buildcfg.h b/device/bluetooth/mk3239/dual_mode/buildcfg.h index bfdb2da231..046d52595d 100644 --- a/device/bluetooth/mk3239/dual_mode/buildcfg.h +++ b/device/bluetooth/mk3239/dual_mode/buildcfg.h @@ -1,6 +1,3 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ #pragma once diff --git a/device/bluetooth/mk3239/dual_mode/dual_mode.mk b/device/bluetooth/mk3239/dual_mode/dual_mode.mk index b94d9b806e..99d25eba75 100644 --- a/device/bluetooth/mk3239/dual_mode/dual_mode.mk +++ b/device/bluetooth/mk3239/dual_mode/dual_mode.mk @@ -1,4 +1,4 @@ -NAME := Lib_Bluetooth_Embedded_Dual_mode_Stack_for_$(BT_CHIP)$(BT_CHIP_REVISION) +NAME := lib_ble_dual_mode BTE_PLATFORM_DIR := ../BTE_platform @@ -19,7 +19,7 @@ endif # Include appropriate firmware as component -$(NAME)_COMPONENTS += bluetooth/firmware +$(NAME)_COMPONENTS += bluetooth/mk3239/firmware $(NAME)_SOURCES += $(BTE_PLATFORM_DIR)/mico_bt_bus.c \ $(BTE_PLATFORM_DIR)/mico_bt_hcd.c \ @@ -28,4 +28,3 @@ $(NAME)_SOURCES += $(BTE_PLATFORM_DIR)/mico_bt_bus.c \ $(BTE_PLATFORM_DIR)/mico_upio.c VALID_PLATFORMS := MK3238 MK3239 - diff --git a/device/bluetooth/mk3239/firmware/20702B0/bt_firmware_image.c b/device/bluetooth/mk3239/firmware/20702B0/bt_firmware_image.c index 98e23e993b..9fff78bff7 100644 --- a/device/bluetooth/mk3239/firmware/20702B0/bt_firmware_image.c +++ b/device/bluetooth/mk3239/firmware/20702B0/bt_firmware_image.c @@ -6,6 +6,7 @@ ** * ** Copyright (c) 2015, Broadcom Corp., All Rights Reserved. * ******************************************************************************/ + #include const char brcm_patch_version[] = "BCM20702B0_002.001.014.0487.0000_Generic_UART_Class1_20MHz.hcd"; diff --git a/device/bluetooth/mk3239/firmware/20703A1/bt_firmware_image.c b/device/bluetooth/mk3239/firmware/20703A1/bt_firmware_image.c index 6548b609e3..86cf9bc47b 100644 --- a/device/bluetooth/mk3239/firmware/20703A1/bt_firmware_image.c +++ b/device/bluetooth/mk3239/firmware/20703A1/bt_firmware_image.c @@ -6,6 +6,7 @@ ** * ** Copyright (c) 2015, Broadcom Corp., All Rights Reserved. * ******************************************************************************/ + #include /* FILE-CSTYLED */ diff --git a/device/bluetooth/mk3239/firmware/20707A1/40MHz/bt_firmware_image.c b/device/bluetooth/mk3239/firmware/20707A1/40MHz/bt_firmware_image.c index 1e4f625832..70faf32734 100644 --- a/device/bluetooth/mk3239/firmware/20707A1/40MHz/bt_firmware_image.c +++ b/device/bluetooth/mk3239/firmware/20707A1/40MHz/bt_firmware_image.c @@ -1,6 +1,11 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ +/***************************************************************************** +** * +** Name: bt_firmware_image.c * +** * +** Description: Bluetooth Controller Firmware patch * +** * +** Copyright (c) 2015, Broadcom Corp., All Rights Reserved. * +******************************************************************************/ #include const char brcm_patch_version[] = "BCM20703A1_001.001.005.0276.0000_Generic_UART_40MHz_flood_mesh_fcbga_BU.hcd"; diff --git a/device/bluetooth/mk3239/firmware/20707A1/bt_firmware_image.c b/device/bluetooth/mk3239/firmware/20707A1/bt_firmware_image.c index 84aff5f0fc..9baaf870e6 100644 --- a/device/bluetooth/mk3239/firmware/20707A1/bt_firmware_image.c +++ b/device/bluetooth/mk3239/firmware/20707A1/bt_firmware_image.c @@ -1,6 +1,11 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ +/***************************************************************************** +** * +** Name: bt_firmware_image.c * +** * +** Description: Bluetooth Controller Firmware patch * +** * +** Copyright (c) 2015, Broadcom Corp., All Rights Reserved. * +******************************************************************************/ #include const char brcm_patch_version[] = "BCM20703A1_001.001.005.0276.0000_Generic_UART_20MHz_flood_mesh_fcbga_BU.hcd"; diff --git a/device/bluetooth/mk3239/firmware/43438A0/bt_firmware_image.c b/device/bluetooth/mk3239/firmware/43438A0/bt_firmware_image.c index a5047ed4dc..b7f8cdd278 100644 --- a/device/bluetooth/mk3239/firmware/43438A0/bt_firmware_image.c +++ b/device/bluetooth/mk3239/firmware/43438A0/bt_firmware_image.c @@ -6,6 +6,7 @@ ** * ** Copyright (c) 2015, Broadcom Corp., All Rights Reserved. * ******************************************************************************/ + #include const char brcm_patch_version[] = "BCM4343A0_37.4MHz_WSDB-751GNB_TEST_ONLY.hcd"; diff --git a/device/bluetooth/mk3239/firmware/43438A1/26MHz/bt_firmware_image.c b/device/bluetooth/mk3239/firmware/43438A1/26MHz/bt_firmware_image.c index aa9f40971d..3cd48f1097 100644 --- a/device/bluetooth/mk3239/firmware/43438A1/26MHz/bt_firmware_image.c +++ b/device/bluetooth/mk3239/firmware/43438A1/26MHz/bt_firmware_image.c @@ -1,11 +1,12 @@ /***************************************************************************** ** * -** Name: brcm_patch.c * +** Name: bt_firmware_image.c * ** * ** Description: Bluetooth Controller Firmware patch * ** * -** Copyright (c) 2013, Broadcom Corp., All Rights Reserved. * +** Copyright (c) 2015, Broadcom Corp., All Rights Reserved. * ******************************************************************************/ + #include const char brcm_patch_version[] = "BCM4343A1_001_002_009_0038_0000_Generic_UART_26MHz_wlbga_ref_otp_hcd"; diff --git a/device/bluetooth/mk3239/firmware/43438A1/37_4MHz/bt_firmware_image.c b/device/bluetooth/mk3239/firmware/43438A1/37_4MHz/bt_firmware_image.c index f5c64e4006..dd94663696 100644 --- a/device/bluetooth/mk3239/firmware/43438A1/37_4MHz/bt_firmware_image.c +++ b/device/bluetooth/mk3239/firmware/43438A1/37_4MHz/bt_firmware_image.c @@ -1,11 +1,12 @@ /***************************************************************************** ** * -** Name: brcm_patch.c * +** Name: bt_firmware_image.c * ** * ** Description: Bluetooth Controller Firmware patch * ** * -** Copyright (c) 2013, Broadcom Corp., All Rights Reserved. * +** Copyright (c) 2015, Broadcom Corp., All Rights Reserved. * ******************************************************************************/ + #include const char brcm_patch_version[] = "BCM4343A1_001_002_009_0038_0000_Generic_UART_37_4MHz_wlbga_ref_otp_37_4"; diff --git a/device/bluetooth/mk3239/firmware/firmware.mk b/device/bluetooth/mk3239/firmware/firmware.mk index bdc2353295..4305685df6 100644 --- a/device/bluetooth/mk3239/firmware/firmware.mk +++ b/device/bluetooth/mk3239/firmware/firmware.mk @@ -1,6 +1,4 @@ -NAME := Lib_MICO_Bluetooth_Firmware_for_$(BT_CHIP)$(BT_CHIP_REVISION) - -$(NAME)_COMPONENTS := bluetooth.mk3239.aosbt_shim_layer +NAME := lib_mico_ble_firmware # Use Firmware images which are already present ifeq ($(BT_CHIP_XTAL_FREQUENCY),) diff --git a/kernel/protocols/bluetooth/include/bt_trace.h b/device/bluetooth/mk3239/include/bt_trace.h similarity index 99% rename from kernel/protocols/bluetooth/include/bt_trace.h rename to device/bluetooth/mk3239/include/bt_trace.h index a600f08a60..545f3dab55 100644 --- a/kernel/protocols/bluetooth/include/bt_trace.h +++ b/device/bluetooth/mk3239/include/bt_trace.h @@ -1,9 +1,6 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ -#ifndef _BT_TRACE_H_ -#define _BT_TRACE_H_ +#ifndef BT_TRACE_H +#define BT_TRACE_H #include "data_types.h" @@ -4211,4 +4208,7 @@ EXPORT_API extern void BTTRC_StackTrace6(tBTTRC_LAYER_ID layer_id, #define DRV_TRACE_DEBUG5(m,p1,p2,p3,p4,p5) APPL_TRACE_DEBUG5(m,p1,p2,p3,p4,p5) #define DRV_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) APPL_TRACE_DEBUG6(m,p1,p2,p3,p4,p5,p6) + #endif /* BT_TRACE_H */ + + diff --git a/kernel/protocols/bluetooth/include/bt_types.h b/device/bluetooth/mk3239/include/bt_types.h similarity index 99% rename from kernel/protocols/bluetooth/include/bt_types.h rename to device/bluetooth/mk3239/include/bt_types.h index a08f04728c..859713186f 100644 --- a/kernel/protocols/bluetooth/include/bt_types.h +++ b/device/bluetooth/mk3239/include/bt_types.h @@ -1,12 +1,15 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ -#ifndef _BT_TYPES_H_ -#define _BT_TYPES_H_ +#ifndef BT_TYPES_H +#define BT_TYPES_H #include "data_types.h" +#ifdef _WIN32 +#ifdef BLUESTACK_TESTER +#include "bte_stack_entry.h" +#endif +#endif + /* READ WELL !! ** ** This section defines global events. These are events that cross layers. @@ -653,3 +656,4 @@ typedef UINT8 tBT_DEVICE_TYPE; typedef void (BT_LOG_FUNC) (int trace_type, const char *fmt_str, ...); #endif + diff --git a/kernel/protocols/bluetooth/include/data_types.h b/device/bluetooth/mk3239/include/data_types.h similarity index 88% rename from kernel/protocols/bluetooth/include/data_types.h rename to device/bluetooth/mk3239/include/data_types.h index e471af86ac..11d327c2b7 100644 --- a/kernel/protocols/bluetooth/include/data_types.h +++ b/device/bluetooth/mk3239/include/data_types.h @@ -1,9 +1,6 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ -#ifndef _DATA_TYPES_H_ -#define _DATA_TYPES_H_ +#ifndef DATA_TYPES_H +#define DATA_TYPES_H #ifndef NULL #define NULL 0 @@ -58,14 +55,14 @@ typedef unsigned char UBYTE; #define BT_MEMSET(a,b,c) memset( (a), (b), (c) ) #define BT_STRLEN(a) strlen( (a) ) #define BT_MEMCMP(a,b,c) memcmp( (a), (b), (c) ) -#define BT_MEMCMP_OK 0 /* memcmp success */ +#define BT_MEMCMP_OK 0 // memcmp success -/* - * Timer list entry callback type - */ +/* Timer list entry callback type +*/ typedef void (TIMER_CBACK)(void *p_tle); #ifndef TIMER_PARAM_TYPE #define TIMER_PARAM_TYPE UINT32 #endif #endif + diff --git a/kernel/protocols/bluetooth/include/gattdefs.h b/device/bluetooth/mk3239/include/gattdefs.h similarity index 91% rename from kernel/protocols/bluetooth/include/gattdefs.h rename to device/bluetooth/mk3239/include/gattdefs.h index 590ff5d755..6ca3d02701 100644 --- a/kernel/protocols/bluetooth/include/gattdefs.h +++ b/device/bluetooth/mk3239/include/gattdefs.h @@ -2,14 +2,20 @@ * Copyright (C) 2015-2017 Alibaba Group Holding Limited */ -#ifndef _GATTDEFS_H_ -#define _GATTDEFS_H_ +/****************************************************************************/ +/* */ +/* Name: gattdefs.h */ +/* */ +/* Function this file contains internally used ATT definitions */ +/*****************************************************************************/ + +#ifndef _GATTDEFS_H +#define _GATTDEFS_H #define GATT_ILLEGAL_UUID 0 -/* - * GATT attribute types - */ +/* GATT attribute types +*/ #define GATT_UUID_PRI_SERVICE 0x2800 #define GATT_UUID_SEC_SERVICE 0x2801 #define GATT_UUID_INCLUDE_SERVICE 0x2802 @@ -21,14 +27,13 @@ #define GATT_UUID_CHAR_SRVR_CONFIG 0x2903 /* Server Characteristic Configuration */ #define GATT_UUID_CHAR_PRESENT_FORMAT 0x2904 /* Characteristic Presentation Format*/ #define GATT_UUID_CHAR_AGG_FORMAT 0x2905 /* Characteristic Aggregate Format*/ -#define GATT_UUID_CHAR_VALID_RANGE 0x2906 /* Characteristic Valid Range */ +#define GATT_UUID_CHAR_VALID_RANGE 0x2906 /* Characteristic Valid Range */ #define GATT_UUID_EXT_RPT_REF_DESCR 0x2907 #define GATT_UUID_RPT_REF_DESCR 0x2908 -/* - *GAP Profile Attributes - */ +/* GAP Profile Attributes +*/ #define GATT_UUID_GAP_DEVICE_NAME 0x2A00 #define GATT_UUID_GAP_ICON 0x2A01 #define GATT_UUID_GAP_PREF_CONN_PARAM 0x2A04 @@ -167,4 +172,5 @@ enum gatt_appearance_e { APPEARANCE_CYCLING_SPEED_AND_CADENCE_SENSOR = 1157, }; + #endif diff --git a/kernel/protocols/bluetooth/include/hcidefs.h b/device/bluetooth/mk3239/include/hcidefs.h similarity index 99% rename from kernel/protocols/bluetooth/include/hcidefs.h rename to device/bluetooth/mk3239/include/hcidefs.h index 2f50cd737e..87a3a49dcc 100644 --- a/kernel/protocols/bluetooth/include/hcidefs.h +++ b/device/bluetooth/mk3239/include/hcidefs.h @@ -2,8 +2,17 @@ * Copyright (C) 2015-2017 Alibaba Group Holding Limited */ -#ifndef _HCIDEFS_H_ -#define _HCIDEFS_H_ +/***************************************************************************** +** +** Name hcidefs.h +** +** Function this file contains Host Controller Interface definitions +** +** +******************************************************************************/ + +#ifndef HCIDEFS_H +#define HCIDEFS_H #define HCI_PROTO_VERSION 0x01 /* Version for BT spec 1.1 */ #define HCI_PROTO_VERSION_1_2 0x02 /* Version for BT spec 1.2 */ @@ -12,8 +21,8 @@ #define HCI_PROTO_VERSION_3_0 0x05 /* Version for BT spec 3.0 */ #define HCI_PROTO_REVISION 0x000C /* Current implementation version */ /* - * Definitions for HCI groups - */ +** Definitions for HCI groups +*/ #define HCI_GRP_LINK_CONTROL_CMDS (0x01 << 10) /* 0x0400 */ #define HCI_GRP_LINK_POLICY_CMDS (0x02 << 10) /* 0x0800 */ #define HCI_GRP_HOST_CONT_BASEBAND_CMDS (0x03 << 10) /* 0x0C00 */ @@ -28,9 +37,8 @@ #define HCI_OCF(p) ( 0x3FF & (p)) /* - * Definitions for Link Control Commands - */ - +** Definitions for Link Control Commands +*/ /* Following opcode is used only in command complete event for flow control */ #define HCI_COMMAND_NONE 0x0000 @@ -2986,3 +2994,4 @@ Commands of HCI_GRP_VENDOR_SPECIFIC group for WIDCOMM SW LM Simulator #endif #endif + diff --git a/kernel/protocols/bluetooth/include/l2cdefs.h b/device/bluetooth/mk3239/include/l2cdefs.h similarity index 92% rename from kernel/protocols/bluetooth/include/l2cdefs.h rename to device/bluetooth/mk3239/include/l2cdefs.h index 0d44670114..e34d54c7be 100644 --- a/kernel/protocols/bluetooth/include/l2cdefs.h +++ b/device/bluetooth/mk3239/include/l2cdefs.h @@ -2,12 +2,20 @@ * Copyright (C) 2015-2017 Alibaba Group Holding Limited */ -#ifndef _L2CDEFS_H_ -#define _L2CDEFS_H_ - -/* - * L2CAP command codes - */ +/**************************************************************************** +** +** Name: l2cdefs.h +** +** Function: This file contains L2CAP protocol definitions +** +** +*****************************************************************************/ + +#ifndef L2CDEFS_H +#define L2CDEFS_H + +/* L2CAP command codes +*/ #define L2CAP_CMD_REJECT 0x01 #define L2CAP_CMD_CONN_REQ 0x02 #define L2CAP_CMD_CONN_RSP 0x03 @@ -32,9 +40,8 @@ #define L2CAP_CMD_BLE_CREDIT 0x16 -/* - * Define some packet and header lengths - */ +/* Define some packet and header lengths +*/ #define L2CAP_PKT_OVERHEAD 4 /* Length and CID */ #define L2CAP_CMD_OVERHEAD 4 /* Cmd code, Id and length */ #define L2CAP_CMD_REJECT_LEN 2 /* Reason (data is optional) */ @@ -65,9 +72,8 @@ #define L2CAP_BLE_CONN_CRED_LEN 4 /* Local CID, connection credits to add */ -/* - * Define the packet boundary flags - */ +/* Define the packet boundary flags +*/ #if (L2CAP_NON_FLUSHABLE_PB_INCLUDED == TRUE) #define L2CAP_PKT_START_FLUSHABLE 2 #define L2CAP_PKT_START_NON_FLUSHABLE 0 @@ -85,9 +91,8 @@ #define L2CAP_BLE_CONN_SDU_LEN_FIELD_SIZE 2 -/* - * Define the L2CAP connection result codes - */ +/* Define the L2CAP connection result codes +*/ #define L2CAP_CONN_OK 0 #define L2CAP_CONN_PENDING 1 #define L2CAP_CONN_NO_PSM 2 @@ -106,9 +111,8 @@ #define L2CAP_CONN_CANCEL 256 /* L2CAP connection cancelled */ -/* - * Define L2CAP Move Channel Response result codes - */ +/* Define L2CAP Move Channel Response result codes +*/ #define L2CAP_MOVE_OK 0 #define L2CAP_MOVE_PENDING 1 #define L2CAP_MOVE_CTRL_ID_NOT_SUPPORT 2 @@ -118,24 +122,21 @@ #define L2CAP_MOVE_NOT_ALLOWED 6 -/* - * Define L2CAP Move Channel Confirmation result codes - */ +/* Define L2CAP Move Channel Confirmation result codes +*/ #define L2CAP_MOVE_CFM_OK 0 #define L2CAP_MOVE_CFM_REFUSED 1 -/* - * Define the L2CAP command reject reason codes - */ +/* Define the L2CAP command reject reason codes +*/ #define L2CAP_CMD_REJ_NOT_UNDERSTOOD 0 #define L2CAP_CMD_REJ_MTU_EXCEEDED 1 #define L2CAP_CMD_REJ_INVALID_CID 2 -/* - * L2CAP Predefined CIDs - */ +/* L2CAP Predefined CIDs +*/ #define L2CAP_SIGNALLING_CID 1 #define L2CAP_CONNECTIONLESS_CID 2 #define L2CAP_AMP_CID 3 @@ -147,9 +148,8 @@ #define L2CAP_BASE_APPL_CID 0x0040 #define L2CAP_BLE_CONN_MAX_CID 0x007F -/* - * Fixed Channels mask bits - */ +/* Fixed Channels mask bits +*/ #define L2CAP_FIXED_CHNL_SIG_BIT (1 << L2CAP_SIGNALLING_CID) /* Signal Channel Supported (Mandatory) */ #define L2CAP_FIXED_CHNL_CNCTLESS_BIT (1 << L2CAP_CONNECTIONLESS_CID) /* Connectionless Reception */ #define L2CAP_FIXED_CHNL_AMP_BIT (1 << L2CAP_AMP_CID) /* AMP Manager Supported */ @@ -160,9 +160,8 @@ -/* - * Define the L2CAP configuration result codes - */ +/* Define the L2CAP configuration result codes +*/ #define L2CAP_CFG_OK 0 #define L2CAP_CFG_UNACCEPTABLE_PARAMS 1 #define L2CAP_CFG_FAILED_NO_REASON 2 @@ -171,9 +170,8 @@ #define L2CAP_CFG_FLOW_SPEC_REJECTED 5 -/* - * Define the L2CAP configuration option types - */ +/* Define the L2CAP configuration option types +*/ #define L2CAP_CFG_TYPE_MTU 0x01 #define L2CAP_CFG_TYPE_FLUSH_TOUT 0x02 #define L2CAP_CFG_TYPE_QOS 0x03 @@ -191,20 +189,17 @@ #define L2CAP_CFG_EXT_WIN_SIZE_LEN 2 /* Ext window size length */ #define L2CAP_CFG_OPTION_OVERHEAD 2 /* Type and length */ -/* - * Configuration Cmd/Rsp Flags mask - */ +/* Configuration Cmd/Rsp Flags mask +*/ #define L2CAP_CFG_FLAGS_MASK_CONT 0x0001 /* Flags mask: Continuation */ -/* - * FCS Check Option values - */ +/* FCS Check Option values +*/ #define L2CAP_CFG_FCS_BYPASS 0 /* Bypass the FCS in streaming or ERTM modes */ #define L2CAP_CFG_FCS_USE 1 /* Use the FCS in streaming or ERTM modes [default] */ -/* - * Default values for configuration - */ +/* Default values for configuration +*/ #define L2CAP_NO_AUTOMATIC_FLUSH 0xFFFF #define L2CAP_NO_RETRANSMISSION 0x0001 @@ -219,21 +214,18 @@ #define L2CAP_DEFAULT_FCS L2CAP_CFG_FCS_USE -/* - * Define the L2CAP disconnect result codes - */ +/* Define the L2CAP disconnect result codes +*/ #define L2CAP_DISC_OK 0 #define L2CAP_DISC_TIMEOUT 0xEEEE -/* - * Define the L2CAP info resp result codes - */ +/* Define the L2CAP info resp result codes +*/ #define L2CAP_INFO_RESP_RESULT_SUCCESS 0 #define L2CAP_INFO_RESP_RESULT_NOT_SUPPORTED 1 -/* - * Define the info-type fields of information request & response - */ +/* Define the info-type fields of information request & response +*/ #define L2CAP_CONNLESS_MTU_INFO_TYPE 0x0001 #define L2CAP_EXTENDED_FEATURES_INFO_TYPE 0x0002 /* Used in Information Req/Response */ #define L2CAP_FIXED_CHANNELS_INFO_TYPE 0x0003 /* Used in AMP */ @@ -242,9 +234,8 @@ #define L2CAP_EXTENDED_FEATURES_ARRAY_SIZE 4 /* Extended features array size */ #define L2CAP_FIXED_CHNL_ARRAY_SIZE 8 /* Fixed channel array size */ -/* - * Extended features mask bits - */ +/* Extended features mask bits +*/ #define L2CAP_EXTFEA_RTRANS 0x00000001 /* Retransmission Mode (Not Supported) */ #define L2CAP_EXTFEA_FC 0x00000002 /* Flow Control Mode (Not Supported) */ #define L2CAP_EXTFEA_QOS 0x00000004 @@ -282,17 +273,15 @@ */ #define L2CAP_OFFSET_WO_L2HDR (L2CAP_MIN_OFFSET-(L2CAP_PKT_OVERHEAD+L2CAP_FCR_OVERHEAD)) -/* - * SAR bits in the control word - */ +/* SAR bits in the control word +*/ #define L2CAP_FCR_UNSEG_SDU 0x0000 /* Control word to begin with for unsegmented PDU*/ #define L2CAP_FCR_START_SDU 0x4000 /* ...for Starting PDU of a semented SDU */ #define L2CAP_FCR_END_SDU 0x8000 /* ...for ending PDU of a segmented SDU */ #define L2CAP_FCR_CONT_SDU 0xc000 /* ...for continuation PDU of a segmented SDU */ -/* - * Supervisory frame types - */ +/* Supervisory frame types +*/ #define L2CAP_FCR_SUP_RR 0x0000 /* Supervisory frame - RR */ #define L2CAP_FCR_SUP_REJ 0x0001 /* Supervisory frame - REJ */ #define L2CAP_FCR_SUP_RNR 0x0002 /* Supervisory frame - RNR */ diff --git a/device/bluetooth/mk3239/include/mico_bt_ble.h b/device/bluetooth/mk3239/include/mico_bt_ble.h new file mode 100644 index 0000000000..da8aa7a423 --- /dev/null +++ b/device/bluetooth/mk3239/include/mico_bt_ble.h @@ -0,0 +1,670 @@ + +/** @file + * + * MiCO Bluetooth Low Energy (BLE) Functions + * + */ +#pragma once + +#include "mico_bt_dev.h" + +#define CHNL_MAP_LEN 5 +typedef uint8_t mico_bt_ble_chnl_map_t[CHNL_MAP_LEN]; + +/** Scan modes */ +enum mico_bt_ble_scan_mode_e { + BTM_BLE_SCAN_MODE_PASSIVE = 0, /**< Passive scan mode */ + BTM_BLE_SCAN_MODE_ACTIVE = 1, /**< Active scan mode */ + BTM_BLE_SCAN_MODE_NONE = 0xff /**< None */ +}; +typedef uint8_t mico_bt_ble_scan_mode_t; /**< scan mode (see #mico_bt_ble_scan_mode_e) */ + +/** Scan filter policy */ +enum mico_bt_ble_scan_filter_policy_e { + BTM_BLE_SCAN_FILTER_POLICY_NONE = 0, /**< Not use White List for Scanning Procedure. */ + BTM_BLE_SCAN_FILTER_POLICY_WHITE_LIST = 1, /**< Use White List for Scanning Procedure. */ +}; +typedef uint8_t mico_bt_ble_scan_filter_policy_t; /**< scan filter policy (see #mico_bt_ble_scan_filter_policy_e) */ + +/** advertising channel map */ +enum mico_bt_ble_advert_chnl_map_e { + BTM_BLE_ADVERT_CHNL_37 = (0x01 << 0), /**< ADV channel */ + BTM_BLE_ADVERT_CHNL_38 = (0x01 << 1), /**< ADV channel */ + BTM_BLE_ADVERT_CHNL_39 = (0x01 << 2) /**< ADV channel */ +}; +typedef uint8_t +mico_bt_ble_advert_chnl_map_t; /**< BLE advertisement channel map (see #mico_bt_ble_advert_chnl_map_e) */ + +/* default advertising channel map */ +#ifndef BTM_BLE_DEFAULT_ADVERT_CHNL_MAP +#define BTM_BLE_DEFAULT_ADVERT_CHNL_MAP (BTM_BLE_ADVERT_CHNL_37| BTM_BLE_ADVERT_CHNL_38| BTM_BLE_ADVERT_CHNL_39) +#endif + +/** Advertising filter policy */ +enum mico_bt_ble_advert_filter_policy_e { + BTM_BLE_ADVERT_FILTER_ALL_CONNECTION_REQ_ALL_SCAN_REQ = 0x00, /**< Process scan and connection requests from all devices (i.e., the White List is not in use) (default) */ + BTM_BLE_ADVERT_FILTER_ALL_CONNECTION_REQ_WHITELIST_SCAN_REQ = 0x01, /**< Process connection requests from all devices and only scan requests from devices that are in the White List. */ + BTM_BLE_ADVERT_FILTER_WHITELIST_CONNECTION_REQ_ALL_SCAN_REQ = 0x02, /**< Process scan requests from all devices and only connection requests from devices that are in the White List */ + BTM_BLE_ADVERT_FILTER_WHITELIST_CONNECTION_REQ_WHITELIST_SCAN_REQ = 0x03, /**< Process scan and connection requests only from devices in the White List. */ + BTM_BLE_ADVERT_FILTER_MAX +}; +typedef uint8_t +mico_bt_ble_advert_filter_policy_t; /**< Advertising filter policy (see #mico_bt_ble_advert_filter_policy_e) */ + +/* default advertising filter policy */ +#define BTM_BLE_ADVERT_FILTER_DEFAULT BTM_BLE_ADVERT_FILTER_ALL_CONNECTION_REQ_ALL_SCAN_REQ + +/* adv parameter boundary values */ +#define BTM_BLE_ADVERT_INTERVAL_MIN 0x0020 +#define BTM_BLE_ADVERT_INTERVAL_MAX 0x4000 + +/* connection parameter boundary values */ +#define BTM_BLE_SCAN_INTERVAL_MIN 0x0004 +#define BTM_BLE_SCAN_INTERVAL_MAX 0x4000 +#define BTM_BLE_SCAN_WINDOW_MIN 0x0004 +#define BTM_BLE_SCAN_WINDOW_MAX 0x4000 +#define BTM_BLE_CONN_INTERVAL_MIN 0x0006 +#define BTM_BLE_CONN_INTERVAL_MAX 0x0C80 +#define BTM_BLE_CONN_LATENCY_MAX 500 +#define BTM_BLE_CONN_SUP_TOUT_MIN 0x000A +#define BTM_BLE_CONN_SUP_TOUT_MAX 0x0C80 +#define BTM_BLE_CONN_PARAM_UNDEF 0xffff /* use this value when a specific value not to be overwritten */ +#define BTM_BLE_CONN_SUP_TOUT_DEF 700 + +/* default connection parameters if not configured, use GAP recommend value for auto/selective connection */ +/* default scan interval */ +#define BTM_BLE_SCAN_FAST_INTERVAL 96 /* 30 ~ 60 ms (use 60) = 96 *0.625 */ + +/* default scan window for background connection, applicable for auto connection or selective conenction */ +#define BTM_BLE_SCAN_FAST_WINDOW 48 /* 30 ms = 48 *0.625 */ + +/* default scan paramter used in reduced power cycle (background scanning) */ +#define BTM_BLE_SCAN_SLOW_INTERVAL_1 2048 /* 1.28 s = 2048 *0.625 */ + +#define BTM_BLE_SCAN_SLOW_WINDOW_1 18 /* 11.25 ms = 18 *0.625 */ + +/* default scan paramter used in reduced power cycle (background scanning) */ +#define BTM_BLE_SCAN_SLOW_INTERVAL_2 4096 /* 2.56 s = 4096 *0.625 */ + +#define BTM_BLE_SCAN_SLOW_WINDOW_2 36 /* 22.5 ms = 36 *0.625 */ + +/* default connection interval min */ +#define BTM_BLE_CONN_INTERVAL_MIN_DEF 24 /* recommended min: 30ms = 24 * 1.25 */ + +/* default connectino interval max */ +#define BTM_BLE_CONN_INTERVAL_MAX_DEF 40 /* recommended max: 50 ms = 56 * 1.25 */ + +/* default slave latency */ +#define BTM_BLE_CONN_SLAVE_LATENCY_DEF 0 /* 0 */ + +/* default supervision timeout */ +#define BTM_BLE_CONN_TIMEOUT_DEF 2000 + +#define BTM_BLE_DIR_CONN_FALLBACK_UNDIR 1 +#define BTM_BLE_DIR_CONN_FALLBACK_NO_ADV 2 + +#define BTM_BLE_DIR_CONN_FALLBACK BTM_BLE_DIR_CONN_FALLBACK_UNDIR + +/** BLE Signature */ +#define BTM_BLE_AUTH_SIGNATURE_SIZE 12 /**< BLE data signature length 8 Bytes + 4 bytes counter*/ +typedef uint8_t +mico_dev_ble_signature_t[BTM_BLE_AUTH_SIGNATURE_SIZE]; /**< Device address (see #BTM_BLE_AUTH_SIGNATURE_SIZE) */ + +#define BTM_BLE_POLICY_BLACK_ALL 0x00 /* relevant to both */ +#define BTM_BLE_POLICY_ALLOW_SCAN 0x01 /* relevant to advertiser */ +#define BTM_BLE_POLICY_ALLOW_CONN 0x02 /* relevant to advertiser */ +#define BTM_BLE_POLICY_WHITE_ALL 0x03 /* relevant to both */ + +/* ADV data flag bit definition used for BTM_BLE_ADVERT_TYPE_FLAG */ +#define BTM_BLE_LIMITED_DISCOVERABLE_FLAG (0x01 << 0) +#define BTM_BLE_GENERAL_DISCOVERABLE_FLAG (0x01 << 1) +#define BTM_BLE_BREDR_NOT_SUPPORTED (0x01 << 2) +/* 4.1 spec adv flag for simultaneous BR/EDR+LE connection support (see) */ +#define BTM_BLE_SIMULTANEOUS_DUAL_MODE_TO_SAME_DEVICE_CONTROLLER_SUPPORTED (0x01 << 3) /**< Simultaneous LE and BR/EDR to Same Device Capable (Controller). */ +#define BTM_BLE_SIMULTANEOUS_DUAL_MODE_TO_SAME_DEVICE_HOST_SUPPORTED (0x01 << 4) /**< Simultaneous LE and BR/EDR to Same Device Capable (Host). */ +#define BTM_BLE_NON_LIMITED_DISCOVERABLE_FLAG (0x00 ) /* lowest bit unset */ +#define BTM_BLE_ADVERT_FLAG_MASK (BTM_BLE_LIMITED_DISCOVERABLE_FLAG | BTM_BLE_BREDR_NOT_SUPPORTED | BTM_BLE_GENERAL_DISCOVERABLE_FLAG) +#define BTM_BLE_LIMITED_DISCOVERABLE_MASK (BTM_BLE_LIMITED_DISCOVERABLE_FLAG ) + +/** Advertisement Data bit masks */ +enum mico_bt_ble_advert_mask_e { + BTM_BLE_ADVERT_BIT_DEV_NAME = (0x00000001 << 0), /**< Device Name */ + BTM_BLE_ADVERT_BIT_FLAGS = (0x00000001 << 1), /**< Flags */ + BTM_BLE_ADVERT_BIT_MANUFACTURER = (0x00000001 << 2), /**< Manufacturer Specific Data */ + BTM_BLE_ADVERT_BIT_TX_POWER = (0x00000001 << 3), /**< Transmit Power Level */ + BTM_BLE_ADVERT_BIT_INTERVAL_RANGE = (0x00000001 << 5), /**< Slave preferred connection interval range */ + BTM_BLE_ADVERT_BIT_SERVICE = (0x00000001 << 6), /**< Service UUID (16-bit) */ + BTM_BLE_ADVERT_BIT_SERVICE_SOLICITATION = (0x00000001 << 7), /**< Service Solicitation (16-bit) */ + BTM_BLE_ADVERT_BIT_SERVICE_DATA = (0x00000001 << 8), /**< Service Data */ + BTM_BLE_ADVERT_BIT_SIGN_DATA = (0x00000001 << 9), /**< Signed data */ + BTM_BLE_ADVERT_BIT_SERVICE_128SOLICITATION = (0x00000001 << 10), /**< Service Solicitation (128-bit) */ + BTM_BLE_ADVERT_BIT_APPEARANCE = (0x00000001 << 11), /**< Appearance */ + BTM_BLE_ADVERT_BIT_PUBLIC_ADDR = (0x00000001 << 12), /**< Public Target Address */ + BTM_BLE_ADVERT_BIT_RANDOM_ADDR = (0x00000001 << 13), /**< Random Target Address */ + BTM_BLE_ADVERT_BIT_SERVICE_32 = (0x00000001 << 4), /**< Service UUIDs (32-bit) */ + BTM_BLE_ADVERT_BIT_SERVICE_32SOLICITATION = (0x00000001 << 14), /**< Service Solicitation (32-bit) */ + BTM_BLE_ADVERT_BIT_PROPRIETARY = (0x00000001 << 15), /**< Priorpietary */ + BTM_BLE_ADVERT_BIT_SERVICE_128 = (0x00000001 << 16) /**< Service UUIDs (128-bit) */ +}; +typedef uint32_t mico_bt_ble_advert_mask_t; /**< BLE advertisement mask (see #mico_bt_ble_advert_mask_e) */ + + +/** Advertisement data types */ +enum mico_bt_ble_advert_type_e { + BTM_BLE_ADVERT_TYPE_FLAG = 0x01, /**< Advertisement flags */ + BTM_BLE_ADVERT_TYPE_16SRV_PARTIAL = 0x02, /**< List of supported services - 16 bit UUIDs (partial) */ + BTM_BLE_ADVERT_TYPE_16SRV_COMPLETE = 0x03, /**< List of supported services - 16 bit UUIDs (complete) */ + BTM_BLE_ADVERT_TYPE_32SRV_PARTIAL = 0x04, /**< List of supported services - 32 bit UUIDs (partial) */ + BTM_BLE_ADVERT_TYPE_32SRV_COMPLETE = 0x05, /**< List of supported services - 32 bit UUIDs (complete) */ + BTM_BLE_ADVERT_TYPE_128SRV_PARTIAL = 0x06, /**< List of supported services - 128 bit UUIDs (partial) */ + BTM_BLE_ADVERT_TYPE_128SRV_COMPLETE = 0x07, /**< List of supported services - 128 bit UUIDs (complete) */ + BTM_BLE_ADVERT_TYPE_NAME_SHORT = 0x08, /**< Short name */ + BTM_BLE_ADVERT_TYPE_NAME_COMPLETE = 0x09, /**< Complete name */ + BTM_BLE_ADVERT_TYPE_TX_POWER = 0x0A, /**< TX Power level */ + BTM_BLE_ADVERT_TYPE_DEV_CLASS = 0x0D, /**< Device Class */ + BTM_BLE_ADVERT_TYPE_SM_TK = 0x10, /**< Security manager TK value */ + BTM_BLE_ADVERT_TYPE_SM_OOB_FLAG = 0x11, /**< Security manager Out-of-Band data */ + BTM_BLE_ADVERT_TYPE_INTERVAL_RANGE = 0x12, /**< Slave connection interval range */ + BTM_BLE_ADVERT_TYPE_SOLICITATION_SRV_UUID = 0x14, /**< List of solicitated services - 16 bit UUIDs */ + BTM_BLE_ADVERT_TYPE_128SOLICITATION_SRV_UUID = 0x15, /**< List of solicitated services - 128 bit UUIDs */ + BTM_BLE_ADVERT_TYPE_SERVICE_DATA = 0x16, /**< Service data - 16 bit UUID */ + BTM_BLE_ADVERT_TYPE_PUBLIC_TARGET = 0x17, /**< Public target address */ + BTM_BLE_ADVERT_TYPE_RANDOM_TARGET = 0x18, /**< Random target address */ + BTM_BLE_ADVERT_TYPE_APPEARANCE = 0x19, /**< Appearance */ + BTM_BLE_ADVERT_TYPE_ADVERT_INTERVAL = 0x1a, /**< Advertising interval */ + BTM_BLE_ADVERT_TYPE_32SOLICITATION_SRV_UUID = 0x1b, /**< List of solicitated services - 32 bit UUIDs */ + BTM_BLE_ADVERT_TYPE_32SERVICE_DATA = 0x1c, /**< Service data - 32 bit UUID */ + BTM_BLE_ADVERT_TYPE_128SERVICE_DATA = 0x1d, /**< Service data - 128 bit UUID */ + BTM_BLE_ADVERT_TYPE_MANUFACTURER = 0xFF /**< Manufacturer data */ +}; +typedef uint8_t mico_bt_ble_advert_type_t; /**< BLE advertisement data type (see #mico_bt_ble_advert_type_e) */ + +/** security settings used with L2CAP LE COC */ +enum mico_bt_ble_sec_flags_e { + BTM_SEC_LE_LINK_ENCRYPTED = 0x01, /**< Link encrypted */ + BTM_SEC_LE_LINK_PAIRED_WITHOUT_MITM = 0x02, /**< Paired without man-in-the-middle protection */ + BTM_SEC_LE_LINK_PAIRED_WITH_MITM = 0x04 /**< Link with man-in-the-middle protection */ +}; + +/** Slave preferred connection interval range */ +typedef struct { + uint16_t low; /**< Preferred low connection interval */ + uint16_t hi; /**< Preferred high connection interval */ +} mico_bt_ble_int_range_t; + +/** Service tag supported in the device */ +typedef struct { + uint8_t num_service; /**< Number of services */ + mico_bool_t list_cmpl; /**< Complete list or not */ + uint16_t *p_uuid; /**< 16-bit UUID data */ +} mico_bt_ble_service_t; + +/** 32 bits Service supported in the device */ +typedef struct { + uint8_t num_service; /**< Number of services */ + mico_bool_t list_cmpl; /**< Complete list or not */ + uint32_t *p_uuid; /**< 32-bit UUID data */ +} mico_bt_ble_32service_t; + +/** 128 bits Service supported in the device */ +typedef struct { + mico_bool_t list_cmpl; /**< Complete list or not */ + uint8_t uuid128[MAX_UUID_SIZE]; /**< 128-bit UUID data */ +} mico_bt_ble_128service_t; + +/** Manufacturer data supported in the device */ +typedef struct { + uint8_t len; /**< Length of manufacturer data */ + uint8_t *p_val; /**< Manufacturer data */ +} mico_bt_ble_manu_t; + +/** Service data supported in the device */ +typedef struct { + mico_bt_uuid_t service_uuid; /**< Service UUID data */ + uint8_t len; /**< Service UUID length */ + uint8_t *p_val; /**< Service data value */ +} mico_bt_ble_service_data_t; + +/** Proprietary data element supported in the device */ +typedef struct { + uint8_t advert_type; /**< Advertisement type */ + uint8_t len; /**< Advertisement length */ + uint8_t *p_val; /**< Element data */ +} mico_bt_ble_prop_elem_t; + +/** Proprietary data elements structure supported in the device */ +typedef struct { + uint8_t num_elem; /**< Number of elements */ + mico_bt_ble_prop_elem_t *p_elem; /**< Proprietary elements */ +} mico_bt_ble_proprietary_t; + +/** Advertising data */ +typedef struct { + mico_bt_ble_int_range_t + int_range; /**< slave preferred connection interval range (BTM_BLE_ADVERT_BIT_INTERVAL_RANGE) */ + mico_bt_ble_manu_t *p_manu; /**< manufacturer data (BTM_BLE_ADVERT_BIT_MANUFACTURER) */ + mico_bt_ble_service_t + *p_services; /**< list of supported services - 16 bit UUIDs (BTM_BLE_ADVERT_BIT_SERVICE) */ + mico_bt_ble_128service_t + *p_services_128b; /**< list of supported services - 128 bit UUIDs (BTM_BLE_ADVERT_BIT_SERVICE_128) */ + mico_bt_ble_32service_t + *p_service_32b; /**< list of supported services - 32 bit UUIDs (BTM_BLE_ADVERT_BIT_SERVICE_32) */ + mico_bt_ble_service_t + *p_sol_services; /**< list of solicited services - 16 bit UUIDs (BTM_BLE_ADVERT_BIT_SERVICE_SOLICITATION) */ + mico_bt_ble_32service_t + *p_sol_service_32b; /**< list of solicited services - 32 bit UUIDs (BTM_BLE_ADVERT_BIT_SERVICE_32SOLICITATION) */ + mico_bt_ble_128service_t + *p_sol_service_128b; /**< list of solicited services - 128 bit UUIDs (BTM_BLE_ADVERT_BIT_SERVICE_128SOLICITATION) */ + mico_bt_ble_proprietary_t + *p_proprietary; /**< list of proprietary data elements (BTM_BLE_ADVERT_BIT_PROPRIETARY) */ + mico_bt_ble_service_data_t *p_service_data; /**< service data (BTM_BLE_ADVERT_BIT_SERVICE_DATA) */ + uint16_t appearance; /**< appearance (BTM_BLE_ADVERT_BIT_APPEARANCE) */ + uint8_t flag; /**< flag (BTM_BLE_ADVERT_BIT_FLAGS) */ + uint8_t tx_power; /**< transmit power (BTM_BLE_ADVERT_BIT_TX_POWER) */ +} mico_bt_ble_advert_data_t; + +/** Scan result event type */ +enum mico_bt_dev_ble_evt_type_e { + BTM_BLE_EVT_CONNECTABLE_ADVERTISEMENT = 0x00, /**< Connectable advertisement */ + BTM_BLE_EVT_CONNECTABLE_DIRECTED_ADVERTISEMENT = 0x01, /**< Connectable Directed advertisement */ + BTM_BLE_EVT_SCANNABLE_ADVERTISEMENT = 0x02, /**< Scannable advertisement */ + BTM_BLE_EVT_NON_CONNECTABLE_ADVERTISEMENT = 0x03, /**< Non connectable advertisement */ + BTM_BLE_EVT_SCAN_RSP = 0x04 /**< Scan response */ +}; +typedef uint8_t mico_bt_dev_ble_evt_type_t; /**< Scan result event value (see #mico_bt_dev_ble_evt_type_e) */ + +/** Background connection type */ +enum mico_bt_ble_conn_type_e { + BTM_BLE_CONN_NONE, /**< No background connection */ + BTM_BLE_CONN_AUTO, /**< Auto connection */ + BTM_BLE_CONN_SELECTIVE /**< Selective connection */ +}; +typedef uint8_t mico_bt_ble_conn_type_t; /**< Connection type (see #mico_bt_ble_conn_type_e) */ + +/** LE inquiry result type */ +typedef struct { + mico_bt_device_address_t remote_bd_addr; /**< Device address */ + uint8_t ble_addr_type; /**< LE Address type */ + mico_bt_dev_ble_evt_type_t ble_evt_type; /**< Scan result event type */ + int8_t + rssi; /**< Set to #BTM_INQ_RES_IGNORE_RSSI, if not valid */ + uint8_t flag; + uint8_t length; +} mico_bt_ble_scan_results_t; + +/** + * Callback mico_bt_ble_selective_conn_cback_t + * + * Selective connection callback (registered with #mico_bt_ble_set_background_connection_type) + * + * @param remote_bda : remote device + * @param p_remote_name : remote device name + * + * @return + */ +typedef bool (mico_bt_ble_selective_conn_cback_t)(mico_bt_device_address_t remote_bda, uint8_t *p_remote_name, + const uint8_t *p_data, uint8_t length); + + +/** + * Callback mico_bt_ble_scan_result_cback_t + * + * Scan result callback (from calling #mico_bt_ble_scan) + * + * @param p_scan_result : scan result data (NULL indicates end of scanning) + * @param p_adv_data : Advertisement data (parse using #mico_bt_ble_check_advertising_data) + * + * @return Nothing + */ +typedef void (mico_bt_ble_scan_result_cback_t) (mico_bt_ble_scan_results_t *p_scan_result, uint8_t *p_adv_data); + +/****************************************************** + * Function Declarations + * + ******************************************************/ +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @addtogroup btm_ble_api_functions BLE (Bluetooth Low Energy) + * @ingroup micobt_DeviceManagement + * + * BLE (Bluetooth Low Energy) Functions. + * + * @{ + */ + +/** + * + * Function mico_bt_start_advertisements + * + * Start advertising. + * + * Use #mico_bt_ble_set_advertisement_data to configure advertising data + * prior to starting avertisements. + * + * The advert_mode parameter determines what advertising parameters and durations + * to use (as specified by the application configuration). + * + * @param[in] advert_mode : advertisement mode + * @param[in] directed_advertisement_bdaddr_type : BLE_ADDR_PUBLIC or BLE_ADDR_RANDOM (if using directed advertisement mode) + * @param[in] directed_advertisement_bdaddr_ptr : Directed advertisement address (NULL if not using directed advertisement) + * + * @return status + * + */ +mico_bt_result_t mico_bt_start_advertisements(mico_bt_ble_advert_mode_t advert_mode, + mico_bt_ble_address_type_t directed_advertisement_bdaddr_type, + mico_bt_device_address_ptr_t directed_advertisement_bdaddr_ptr); + +/** + * + * Function mico_bt_ble_get_current_advert_mode + * + * Get current advertising mode + * + * @return Current advertising mode + * + */ +mico_bt_ble_advert_mode_t mico_bt_ble_get_current_advert_mode(void); + + +/** + * + * Function mico_bt_ble_set_advertisement_data + * + * Set advertisement data. + * + * @param[in] data_mask : mask of data types to include in the advertisement data + * @param[in] p_data : advertisement data + * + * @return void + * + */ +mico_bt_result_t mico_bt_ble_set_advertisement_data(mico_bt_ble_advert_mask_t data_mask, + mico_bt_ble_advert_data_t *p_data); + +/** + * + * Function mico_bt_ble_set_scan_response_data + * + * Set scan response data + * + * @param[in] data_mask : mask of data types to include in the scan response data + * @param[in] p_data : scan response data + * + * @return status of the operation + * + */ +mico_bt_dev_status_t mico_bt_ble_set_scan_response_data(mico_bt_ble_advert_mask_t data_mask, + mico_bt_ble_advert_data_t *p_data); + +/** + * Function mico_bt_ble_scan + * + * Start LE scanning + * + * The scan_type parameter determines what scanning parameters and durations + * to use (as specified by the application configuration). + * + * Scan results are notified using p_scan_result_cback + * + * @param[in] scan_type : BTM_BLE_SCAN_TYPE_NONE, BTM_BLE_SCAN_TYPE_HIGH_DUTY, BTM_BLE_SCAN_TYPE_LOW_DUTY + * @param[in] duplicate_filter_enable : TRUE or FALSE to enable or disable duplicate filtering + * + * @param[in] p_scan_result_cback : scan result callback + * + * @return mico_bt_result_t + * + * MICO_BT_PENDING if successfully initiated + * MICO_BT_BUSY if already in progress + * MICO_BT_ILLEGAL_VALUE if parameter(s) are out of range + * MICO_BT_NO_RESOURCES if could not allocate resources to start the command + * MICO_BT_WRONG_MODE if the device is not up. + */ +mico_bt_result_t mico_bt_ble_scan (mico_bt_ble_scan_type_t scan_type, mico_bool_t duplicate_filter_enable, + mico_bt_ble_scan_result_cback_t *p_scan_result_cback); + +/** + * + * Function mico_bt_ble_get_current_scan_state + * + * Get current scan state + * + * @return mico_bt_ble_scan_type_t + * + * BTM_BLE_SCAN_TYPE_NONE Not scanning + * BTM_BLE_SCAN_TYPE_HIGH_DUTY High duty cycle scan + * BTM_BLE_SCAN_TYPE_LOW_DUTY Low duty cycle scan + */ +mico_bt_ble_scan_type_t mico_bt_ble_get_current_scan_state(void); + + +/** + * + * Function mico_bt_ble_security_grant + * + * Grant or deny access. Used in response to an BTM_SECURITY_REQUEST_EVT event. + * + * @param[in] bd_addr : peer device bd address. + * @param[in] res : BTM_SUCCESS to grant access; BTM_REPEATED_ATTEMPTS otherwise + * + * @return None + * + */ +void mico_bt_ble_security_grant(mico_bt_device_address_t bd_addr, uint8_t res); + +/** + * + * Function mico_bt_ble_data_signature + * + * Sign the data using AES128 CMAC algorith. + * + * @param[in] bd_addr: target device the data to be signed for. + * @param[in] p_text: signing data + * @param[in] len: length of the signing data + * @param[in] signature: output parameter where data signature is going to be stored + * + * @return TRUE if signing successful, otherwise FALSE. + * + */ +mico_bool_t mico_bt_ble_data_signature (mico_bt_device_address_t bd_addr, uint8_t *p_text, uint16_t len, + mico_dev_ble_signature_t signature); + +/** + * + * Function mico_bt_ble_verify_signature + * + * Verify the data signature + * + * @param[in] bd_addr: target device the data to be signed for. + * @param[in] p_orig: original data before signature. + * @param[in] len: length of the signing data + * @param[in] counter: counter used when doing data signing + * @param[in] p_comp: signature to be compared against. + * + * @return TRUE if signature verified correctly; otherwise FALSE. + * + */ +mico_bool_t mico_bt_ble_verify_signature (mico_bt_device_address_t bd_addr, uint8_t *p_orig, + uint16_t len, uint32_t counter, + uint8_t *p_comp); + +/** + * + * Function mico_bt_ble_set_background_connection_type + * + * Set BLE background connection procedure type. + * + * @param[in] conn_type: BTM_BLE_CONN_NONE, BTM_BLE_CONN_AUTO, or BTM_BLE_CONN_SELECTIVE + * @param[in] p_select_cback: callback for BTM_BLE_CONN_SELECTIVE + * + * @return TRUE if background connection set + * + */ +mico_bool_t mico_bt_ble_set_background_connection_type (mico_bt_ble_conn_type_t conn_type, + mico_bt_ble_selective_conn_cback_t *p_select_cback); + +/** + * + * Function mico_bt_ble_update_background_connection_device + * + * This function is called to add or remove a device into/from + * background connection procedure. The background connection +* procedure is decided by the background connection type, it can be +* auto connection, or selective connection. + * + * @param[in] add_remove: TRUE to add; FALSE to remove. + * @param[in] remote_bda: device address to add/remove. + * + * @return TRUE if successful + * + */ +mico_bool_t mico_bt_ble_update_background_connection_device(mico_bool_t add_remove, + mico_bt_device_address_t remote_bda); + + +/** + * + * Function mico_bt_ble_get_background_connection_device_size + * + * Get a size of white list for the AUTO or SELECTIVE Connection Procedure. + * + * @param[out] size: white list size + * + * @return MICO_TRUE or MICO_FALSE + */ +mico_bool_t mico_bt_ble_get_background_connection_device_size(uint8_t *size); + + +/** + * + * Function mico_bt_ble_check_advertising_data + * + * Parse advertising data (returned from scan results callback #mico_bt_ble_scan_result_cback_t). + * Look for specified advertisement data type. + * + * @param[in] p_adv : pointer to advertisement data + * @param[in] type : advertisement data type to look for + * @param[out] p_length : length of advertisement data (if found) + * + * @return pointer to start of requested advertisement data (if found). NULL if requested data type not found. + * + */ +uint8_t *mico_bt_ble_check_advertising_data( uint8_t *p_adv, mico_bt_ble_advert_type_t type, uint8_t *p_length); + +/** + * + * Function mico_bt_ble_enable_privacy + * + * This function is called to enable or disable the privacy in + * the local device. + * + * @param[in] enable: TRUE to enable it; FALSE to disable it. + * + * @return void + * + */ +void mico_bt_ble_enable_privacy (mico_bool_t enable); + +/** + * + * Function mico_bt_ble_enable_mixed_privacy_mode + * + * This function is called to enabled Mixed mode if privacy 1.2 + * is applicable in controller. + * + * @param[in] mixed_on: mixed mode to be used or not. + * + * @return void + * + */ +void mico_bt_ble_enable_mixed_privacy_mode(mico_bool_t mixed_on); + + +/** + * + * Function mico_bt_ble_get_security_state + * + * Get security mode 1 flags and encryption key size for LE peer. + * + * @param[in] bd_addr : peer address + * @param[out] p_le_sec_flags : security flags (see #mico_bt_ble_sec_flags_e) + * @param[out] p_le_key_size : encryption key size + * + * @return TRUE if successful + * + */ +mico_bool_t mico_bt_ble_get_security_state (mico_bt_device_address_t bd_addr, uint8_t *p_le_sec_flags, + uint8_t *p_le_key_size); + +/** + * + * Function mico_bt_ble_update_advertising_white_list + * + * Add or remove device from advertising white list + * + * @param[in] add: TRUE to add; FALSE to remove + * @param[in] remote_bda: remote device address. + * + * @return void + * + */ +mico_bool_t mico_bt_ble_update_advertising_white_list(mico_bool_t add, const mico_bt_device_address_t remote_bda); + +/** + * + * Function mico_bt_ble_update_advertisement_filter_policy + * + * Update the filter policy of advertiser. + * + * @param[in] advertising_policy: advertising filter policy + * + * @return void + */ +mico_bool_t mico_bt_ble_update_advertisement_filter_policy(mico_bt_ble_advert_filter_policy_t advertising_policy); + + +/** + * + * Function mico_bt_ble_get_advertisement_white_list_size + * + * Get advertisement white list size. + * + * @param[out] size: white list size + * + * @return MICO_TRUE or MICO_FALSE + */ +mico_bool_t mico_bt_ble_get_advertisement_white_list_size(uint8_t *size); + + +/** + * + * Function mico_bt_ble_get_white_list_capability + * + * Get All white list size. + * + * @param[out] size: white list size + * + * @return MICO_TRUE or MICO_FALSE + */ +mico_bool_t mico_bt_ble_get_white_list_capability(uint8_t *size); + +/** + * + * Function mico_bt_ble_clear_white_list + * + * Clear white list (Advertisement & background connection). + * + * @param none + * + * @return MICO_TRUE or MICO_FALSE + */ +mico_bool_t mico_bt_ble_clear_white_list(void); + +/**@} btm_ble_api_functions */ + +#ifdef __cplusplus +} +#endif diff --git a/device/bluetooth/mk3239/include/mico_bt_cfg.h b/device/bluetooth/mk3239/include/mico_bt_cfg.h new file mode 100644 index 0000000000..4a4d2926ee --- /dev/null +++ b/device/bluetooth/mk3239/include/mico_bt_cfg.h @@ -0,0 +1,297 @@ + +/** @file + * + * Runtime Bluetooth configuration parameters + * + */ +#pragma once +#include "data_types.h" +#include "mico_bt_types.h" +#include "mico_bt_dev.h" +#include "mico_bt_ble.h" +#include "mico_bt_gatt.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/***************************************************************************** + * Default configuration values + ****************************************************************************/ +#define MICO_BT_CFG_DEFAULT_INQUIRY_SCAN_INTERVAL 0x0800 /**< Inquiry scan interval */ +#define MICO_BT_CFG_DEFAULT_INQUIRY_SCAN_WINDOW 0x0012 /**< Inquiry scan window */ +#define MICO_BT_CFG_DEFAULT_PAGE_SCAN_INTERVAL 0x0800 /**< Page scan interval */ +#define MICO_BT_CFG_DEFAULT_PAGE_SCAN_WINDOW 0x0012 /**< Page scan window */ +#define MICO_BT_CFG_DEFAULT_HIGH_DUTY_SCAN_INTERVAL 96 /**< High duty scan interval */ +#define MICO_BT_CFG_DEFAULT_HIGH_DUTY_SCAN_WINDOW 48 /**< High duty scan window */ +#define MICO_BT_CFG_DEFAULT_LOW_DUTY_SCAN_INTERVAL 2048 /**< Low duty scan interval */ +#define MICO_BT_CFG_DEFAULT_LOW_DUTY_SCAN_WINDOW 18 /**< Low duty scan window */ +#define MICO_BT_CFG_DEFAULT_HIGH_DUTY_CONN_SCAN_INTERVAL 96 /**< High duty cycle connection scan interval BTM_BLE_SCAN_FAST_INT*/ +#define MICO_BT_CFG_DEFAULT_HIGH_DUTY_CONN_SCAN_WINDOW 48 /**< High duty cycle connection scan window BTM_BLE_SCAN_FAST_WIN */ +#define MICO_BT_CFG_DEFAULT_LOW_DUTY_CONN_SCAN_INTERVAL 2048 /**< Low duty cycle connection scan interval BTM_BLE_SCAN_SLOW_INT_1 */ +#define MICO_BT_CFG_DEFAULT_LOW_DUTY_CONN_SCAN_WINDOW 18 /**< Low duty cycle connection scan window BTM_BLE_SCAN_SLOW_WIN_1 */ +#define MICO_BT_CFG_DEFAULT_CONN_MIN_INTERVAL 24 /**< Minimum connection event interval */ +#define MICO_BT_CFG_DEFAULT_CONN_MAX_INTERVAL 40 /**< Maximum connection event interval */ +#define MICO_BT_CFG_DEFAULT_CONN_LATENCY 0 /**< Connection latency */ +#define MICO_BT_CFG_DEFAULT_CONN_SUPERVISION_TIMEOUT 700 /**< Connection link supervsion timeout */ + +/* undirected connectable advertisement high/low duty cycle interval default */ +#define MICO_BT_CFG_DEFAULT_HIGH_DUTY_ADV_MIN_INTERVAL 48 /**< Tgap(adv_fast_interval1) = 30(used) ~ 60 ms = 48 *0.625 */ +#define MICO_BT_CFG_DEFAULT_HIGH_DUTY_ADV_MAX_INTERVAL 48 /**< Tgap(adv_fast_interval1) = 30(used) ~ 60 ms = 48 *0.625 */ +#define MICO_BT_CFG_DEFAULT_LOW_DUTY_ADV_MIN_INTERVAL 2048 /**< Tgap(adv_slow_interval) = 1.28 s= 512 * 0.625 ms */ +#define MICO_BT_CFG_DEFAULT_LOW_DUTY_ADV_MAX_INTERVAL 2048 /**< Tgap(adv_slow_interval) = 1.28 s= 512 * 0.625 ms */ + +/* non-connectable advertisement high/low duty cycle advertisement interval default */ +#define MICO_BT_CFG_DEFAULT_HIGH_DUTY_NONCONN_ADV_MIN_INTERVAL 160 /**< Tgap(adv_fast_interval2) = 100(used) ~ 150 ms = 160 * 0.625 ms */ +#define MICO_BT_CFG_DEFAULT_HIGH_DUTY_NONCONN_ADV_MAX_INTERVAL 160 /**< Tgap(adv_fast_interval2) = 100(used) ~ 150 ms = 160 * 0.625 ms */ +#define MICO_BT_CFG_DEFAULT_LOW_DUTY_NONCONN_ADV_MIN_INTERVAL 2048 /**< Tgap(adv_slow_interval) = 1.28 s= 512 * 0.625 ms */ +#define MICO_BT_CFG_DEFAULT_LOW_DUTY_NONCONN_ADV_MAX_INTERVAL 2048 /**< Tgap(adv_slow_interval) = 1.28 s= 512 * 0.625 ms */ + +/* directed connectable advertisement high/low duty cycle interval default */ +#define MICO_BT_CFG_DEFAULT_HIGH_DUTY_DIRECTED_ADV_MIN_INTERVAL 400 /**< Tgap(dir_conn_adv_int_max) = 250 ms = 400 * 0.625 ms */ +#define MICO_BT_CFG_DEFAULT_HIGH_DUTY_DIRECTED_ADV_MAX_INTERVAL 800 /**< Tgap(dir_conn_adv_int_min) = 500 ms = 800 * 0.625 ms */ +#define MICO_BT_CFG_DEFAULT_LOW_DUTY_DIRECTED_ADV_MIN_INTERVAL 48 /**< Tgap(adv_fast_interval1) = 30(used) ~ 60 ms = 48 *0.625 */ +#define MICO_BT_CFG_DEFAULT_LOW_DUTY_DIRECTED_ADV_MAX_INTERVAL 48 /**< Tgap(adv_fast_interval1) = 30(used) ~ 60 ms = 48 *0.625 */ + +/***************************************************************************** + * mico_bt core stack configuration + ****************************************************************************/ + +/** BR/EDR scan settings */ +typedef struct { + uint16_t + inquiry_scan_type; /**< Inquiry scan type (BTM_SCAN_TYPE_STANDARD or BTM_SCAN_TYPE_INTERLACED) */ + uint16_t + inquiry_scan_interval; /**< Inquiry scan interval (default: MICO_BT_CFG_DEFAULT_INQUIRY_SCAN_INTERVAL) */ + uint16_t + inquiry_scan_window; /**< Inquiry scan window (default: MICO_BT_CFG_DEFAULT_INQUIRY_SCAN_WINDOW) */ + + uint16_t + page_scan_type; /**< Page scan type (BTM_SCAN_TYPE_STANDARD or BTM_SCAN_TYPE_INTERLACED) */ + uint16_t + page_scan_interval; /**< Page scan interval (default: MICO_BT_CFG_DEFAULT_PAGE_SCAN_INTERVAL) */ + uint16_t + page_scan_window; /**< Page scan window (default: MICO_BT_CFG_DEFAULT_PAGE_SCAN_WINDOW) */ +} mico_bt_cfg_br_edr_scan_settings_t; +extern const mico_bt_cfg_br_edr_scan_settings_t +*mico_bt_cfg_br_edr_scan_settings; /**< BR/EDR Scan settings (NULL to use defaults) */ + +/** LE Scan settings */ +typedef struct { + mico_bt_ble_scan_mode_t + scan_mode; /**< BLE scan mode (BTM_BLE_SCAN_MODE_PASSIVE, BTM_BLE_SCAN_MODE_ACTIVE) */ + mico_bt_ble_scan_filter_policy_t + scan_filter_policy; /**< BLE scan filter policy (FILTER_POLICY_NONE or FILTER_POLICY_WHITE_LIST) */ + + /* Advertisement scan configuration */ + uint16_t + high_duty_scan_interval; /**< High duty scan interval (default: MICO_BT_CFG_DEFAULT_HIGH_DUTY_SCAN_INTERVAL) */ + uint16_t + high_duty_scan_window; /**< High duty scan window (default: MICO_BT_CFG_DEFAULT_HIGH_DUTY_SCAN_WINDOW) */ + uint16_t + high_duty_scan_duration; /**< High duty scan duration in seconds (0 for infinite) */ + + uint16_t + low_duty_scan_interval; /**< Low duty scan interval (default: MICO_BT_CFG_DEFAULT_LOW_DUTY_SCAN_INTERVAL) */ + uint16_t + low_duty_scan_window; /**< Low duty scan window (default: MICO_BT_CFG_DEFAULT_LOW_DUTY_SCAN_WINDOW) */ + uint16_t + low_duty_scan_duration; /**< Low duty scan duration in seconds (0 for infinite) */ + + /* Connection scan configuration */ + uint16_t + high_duty_conn_scan_interval; /**< High duty cycle connection scan interval (default: MICO_BT_CFG_DEFAULT_HIGH_DUTY_CONN_SCAN_INTERVAL) */ + uint16_t + high_duty_conn_scan_window; /**< High duty cycle connection scan window (default: MICO_BT_CFG_DEFAULT_HIGH_DUTY_CONN_SCAN_WINDOW) */ + uint16_t + high_duty_conn_duration; /**< High duty cycle connection duration in seconds (0 for infinite) */ + + uint16_t + low_duty_conn_scan_interval; /**< Low duty cycle connection scan interval (default: MICO_BT_CFG_DEFAULT_LOW_DUTY_CONN_SCAN_INTERVAL) */ + uint16_t + low_duty_conn_scan_window; /**< Low duty cycle connection scan window (default: MICO_BT_CFG_DEFAULT_LOW_DUTY_CONN_SCAN_WINDOW) */ + uint16_t + low_duty_conn_duration; /**< Low duty cycle connection duration in seconds (0 for infinite) */ + + /* Connection configuration */ + uint16_t + conn_min_interval; /**< Minimum connection interval (default: MICO_BT_CFG_DEFAULT_CONN_MIN_INTERVAL) */ + uint16_t + conn_max_interval; /**< Maximum connection interval (default: MICO_BT_CFG_DEFAULT_CONN_MAX_INTERVAL) */ + uint16_t + conn_latency; /**< Connection latency (default: MICO_BT_CFG_DEFAULT_CONN_LATENCY) */ + uint16_t + conn_supervision_timeout; /**< Connection link supervision timeout (default: MICO_BT_CFG_DEFAULT_ CONN_SUPERVISION_TIMEOUT) */ +} mico_bt_cfg_ble_scan_settings_t; + +/** Advertising settings */ +typedef struct { + mico_bt_ble_advert_chnl_map_t + channel_map; /**< Advertising channel map (mask of BTM_BLE_ADVERT_CHNL_37, BTM_BLE_ADVERT_CHNL_38, BTM_BLE_ADVERT_CHNL_39) */ + + uint16_t + high_duty_min_interval; /**< High duty undirected connectable advert minimum advertising interval (default: MICO_BT_CFG_DEFAULT_HIGH_DUTY_ADV_MIN_INTERVAL) */ + uint16_t + high_duty_max_interval; /**< High duty undirected connectable advert maximum advertising interval (default: MICO_BT_CFG_DEFAULT_HIGH_DUTY_ADV_MAX_INTERVAL) */ + uint16_t + high_duty_duration; /**< High duty advertising duration in seconds (0 for infinite) */ + + uint16_t + low_duty_min_interval; /**< Low duty undirected connectable advert minimum advertising interval (default: MICO_BT_CFG_DEFAULT_LOW_DUTY_ADV_MIN_INTERVAL) */ + uint16_t + low_duty_max_interval; /**< Low duty undirected connectable advert maximum advertising interval (default: MICO_BT_CFG_DEFAULT_LOW_DUTY_ADV_MAX_INTERVAL) */ + uint16_t + low_duty_duration; /**< Low duty advertising duration in seconds (0 for infinite) */ + + uint16_t + high_duty_directed_min_interval; /**< high duty directed adv minimum advertising interval (default: MICO_BT_CFG_DEFAULT_HIGH_DUTY_DIRECTED_ADV_MIN_INTERVAL) */ + uint16_t + high_duty_directed_max_interval; /**< high duty directed adv maximum advertising interval (default: MICO_BT_CFG_DEFAULT_HIGH_DUTY_DIRECTED_ADV_MAX_INTERVAL) */ + + uint16_t + low_duty_directed_min_interval; /**< Low duty directed adv minimum advertising interval (default: MICO_BT_CFG_DEFAULT_LOW_DUTY_DIRECTED_ADV_MIN_INTERVAL) */ + uint16_t + low_duty_directed_max_interval; /**< Low duty directed adv maximum advertising interval (default: MICO_BT_CFG_DEFAULT_LOW_DUTY_DIRECTED_ADV_MAX_INTERVAL) */ + uint16_t + low_duty_directed_duration; /**< Low duty directed advertising duration in seconds (0 for infinite) */ + + uint16_t + high_duty_nonconn_min_interval; /**< High duty non-connectable adv minimum advertising interval (default: MICO_BT_CFG_DEFAULT_HIGH_DUTY_NONCONN_ADV_MIN_INTERVAL) */ + uint16_t + high_duty_nonconn_max_interval; /**< High duty non-connectable adv maximum advertising interval (default: MICO_BT_CFG_DEFAULT_HIGH_DUTY_NONCONN_ADV_MAX_INTERVAL) */ + uint16_t + high_duty_nonconn_duration; /**< High duty non-connectable advertising duration in seconds (0 for infinite) */ + + uint16_t + low_duty_nonconn_min_interval; /**< Low duty non-connectable adv minimum advertising interval (default: MICO_BT_CFG_DEFAULT_LOW_DUTY_NONCONN_ADV_MIN_INTERVAL) */ + uint16_t + low_duty_nonconn_max_interval; /**< Low duty non-connectable adv maximum advertising interval (default: MICO_BT_CFG_DEFAULT_LOW_DUTY_NONCONN_ADV_MAX_INTERVAL) */ + uint16_t + low_duty_nonconn_duration; /**< Low duty non-connectable advertising duration in seconds (0 for infinite) */ + +} mico_bt_cfg_ble_advert_settings_t; + +/** GATT settings */ +typedef struct { + mico_bt_gatt_appearance_t appearance; /**< GATT appearance (see #gatt_appearance_e) */ + uint8_t + client_max_links; /**< Client config: maximum number of servers that local client can connect to */ + uint8_t + server_max_links; /**< Server config: maximum number of remote clients connections allowed by the local */ + uint16_t + max_attr_len; /**< Maximum attribute length; gki_cfg must have a corresponding buffer pool that can hold this length */ +} mico_bt_cfg_gatt_settings_t; + +/** Settings for application managed L2CAP protocols (optional) */ +typedef struct { + uint8_t + max_links; /**< Maximum number of application-managed l2cap links (BR/EDR and LE) */ + + /* BR EDR l2cap configuration */ + uint8_t + max_psm; /**< Maximum number of application-managed BR/EDR PSMs */ + uint8_t + max_channels; /**< Maximum number of application-managed BR/EDR channels */ + + /* LE L2cap connection-oriented channels configuration */ + uint8_t + max_le_psm; /**< Maximum number of application-managed LE PSMs */ + uint8_t + max_le_channels; /**< Maximum number of application-managed LE channels */ + +} mico_bt_cfg_l2cap_application_t; + +/** Audio/Video Distribution configuration */ +typedef struct { + uint8_t max_links; /**< Maximum simultaneous audio/video links */ +} mico_bt_cfg_avdt_t; + +/** Audio/Video Remote Control configuration */ +typedef struct { + uint8_t + roles; /**< Mask of local roles supported (AVRC_CONN_INITIATOR|AVRC_CONN_ACCEPTOR) */ + uint8_t max_links; /**< Maximum simultaneous remote control links */ +} mico_bt_cfg_avrc_t; + + +/* RFCOMM configuration */ +typedef struct { + uint8_t + max_links; /**< Maximum number of simultaneous connected remote devices*/ + uint8_t max_ports; /**< Maximum number of simultaneous RFCOMM ports */ +} mico_bt_cfg_rfcomm_t; + + +/** Bluetooth stack configuration */ +typedef struct { + uint8_t *device_name; /**< Local device name (NULL terminated) */ + mico_bt_dev_class_t device_class; /**< Local device class */ + uint8_t + security_requirement_mask; /**< Security requirements mask (BTM_SEC_NONE, or combination of BTM_SEC_IN_AUTHENTICATE, BTM_SEC_OUT_AUTHENTICATE, BTM_SEC_ENCRYPT (see #mico_bt_sec_level_e)) */ + uint8_t + max_simultaneous_links; /**< Maximum number simultaneous links to different devices */ + + /* Scan and advertisement configuration */ + mico_bt_cfg_br_edr_scan_settings_t br_edr_scan_cfg; /**< BR/EDR scan settings */ + mico_bt_cfg_ble_scan_settings_t ble_scan_cfg; /**< BLE scan settings */ + mico_bt_cfg_ble_advert_settings_t ble_advert_cfg; /**< BLE advertisement settings */ + + /* GATT configuration */ + mico_bt_cfg_gatt_settings_t gatt_cfg; /**< GATT settings */ + + /* RFCOMM configuration */ + mico_bt_cfg_rfcomm_t rfcomm_cfg; /**< RFCOMM settings */ + + /* Application managed l2cap protocol configuration */ + mico_bt_cfg_l2cap_application_t + l2cap_application; /**< Application managed l2cap protocol configuration */ + + /* Audio/Video Distribution configuration */ + mico_bt_cfg_avdt_t avdt_cfg; /**< Audio/Video Distribution configuration */ + + /* Audio/Video Remote Control configuration */ + mico_bt_cfg_avrc_t avrc_cfg; /**< Audio/Video Remote Control configuration */ + + /* LE Address Resolution DB size */ + uint8_t + addr_resolution_db_size; /**< LE Address Resolution DB settings - effective only for pre 4.2 controller*/ + +} mico_bt_cfg_settings_t; + +/***************************************************************************** + * Buffer pool configuration + * + * Pools must be ordered in increasing buf_size. + * If a pool runs out of buffers, the next pool will be used + * + * Pool usage (4 pools): + * Pool 0: Small Buffer Pool - miscellaneous use (small HCI messages) + * Pool 1: Medium Buffer Pool - HCI & RFCOMM control messages, min recommended buf_size is 360 + * Pool 2: Large Buffer Pool - HCI ACL data messages + * Pool 3: Extra Large Buffer Pool - Used for avdt media packets and miscellaneous (if not needed, set buf_count to 0) + * + ****************************************************************************/ +#define MICO_BT_CFG_NUM_BUF_POOLS (4) /**< mico_bt stack uses 4 pools */ +typedef struct { + uint16_t buf_size; /**< size of buffers in the pool */ + uint16_t buf_count; /**< number of buffers in the pool */ +} mico_bt_cfg_buf_pool_t; + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#define DEMO_APP_BLE_REPORTER 1 +#define DEMO_APP_BLE_MONITOR 2 +#define DEMO_APP_RFCOMM_CLT 3 +#define DEMO_APP_RFCOMM_SVR 4 +#define DEMO_APP_SCAN 5 +#define DEMO_APP_FLOOD_BRIDGE 6 + +//#define DEMO_APP_TYPE DEMO_APP_BLE_REPORTER +//#define DEMO_APP_TYPE DEMO_APP_RFCOMM_SVR +//#define DEMO_APP_TYPE DEMO_APP_RFCOMM_CLT +//#define DEMO_APP_TYPE DEMO_APP_BLE_MONITOR +//#define DEMO_APP_TYPE DEMO_APP_SCAN +#define DEMO_APP_TYPE DEMO_APP_FLOOD_BRIDGE + diff --git a/device/bluetooth/mk3239/include/mico_bt_constants.h b/device/bluetooth/mk3239/include/mico_bt_constants.h new file mode 100644 index 0000000000..43df285c9d --- /dev/null +++ b/device/bluetooth/mk3239/include/mico_bt_constants.h @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + + +/** @file + * Defines common constants and types for the MBLE Bluetooth Framework + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************** + * Macros + ******************************************************/ + +#ifndef RESULT_ENUM +#define RESULT_ENUM( prefix, name, value ) prefix ## name = (value) +#endif /* ifndef RESULT_ENUM */ + +#define BT_RESULT_LIST( prefix ) \ + RESULT_ENUM( prefix, SUCCESS, 0 ), /**< Success */ \ + RESULT_ENUM( prefix, PARTIAL_RESULTS, 3 ), /**< Partial results */ \ + RESULT_ENUM( prefix, BADARG, 5 ), /**< Bad Arguments */ \ + RESULT_ENUM( prefix, BADOPTION, 6 ), /**< Mode not supported */ \ + RESULT_ENUM( prefix, OUT_OF_HEAP_SPACE, 8 ), /**< Dynamic memory space exhausted */ \ + RESULT_ENUM( prefix, UNKNOWN_EVENT, 8029 ), /**< Unknown event is received */ \ + RESULT_ENUM( prefix, LIST_EMPTY, 8010 ), /**< List is empty */ \ + RESULT_ENUM( prefix, ITEM_NOT_IN_LIST, 8011 ), /**< Item not found in the list */ \ + RESULT_ENUM( prefix, PACKET_DATA_OVERFLOW, 8012 ), /**< Data overflow beyond the packet end */ \ + RESULT_ENUM( prefix, PACKET_POOL_EXHAUSTED, 8013 ), /**< All packets in the pool is in use */ \ + RESULT_ENUM( prefix, PACKET_POOL_FATAL_ERROR, 8014 ), /**< Packet pool fatal error such as permanent packet leak */ \ + RESULT_ENUM( prefix, UNKNOWN_PACKET, 8015 ), /**< Unknown packet */ \ + RESULT_ENUM( prefix, PACKET_WRONG_OWNER, 8016 ), /**< Packet is owned by another entity */ \ + RESULT_ENUM( prefix, BUS_UNINITIALISED, 8017 ), /**< Bluetooth bus isn't initialised */ \ + RESULT_ENUM( prefix, MPAF_UNINITIALISED, 8018 ), /**< MPAF framework isn't initialised */ \ + RESULT_ENUM( prefix, RFCOMM_UNINITIALISED, 8019 ), /**< RFCOMM protocol isn't initialised */ \ + RESULT_ENUM( prefix, STACK_UNINITIALISED, 8020 ), /**< SmartBridge isn't initialised */ \ + RESULT_ENUM( prefix, SMART_APPL_UNINITIALISED, 8021 ), /**< Bluetooth stack isn't initialised */ \ + RESULT_ENUM( prefix, ATT_CACHE_UNINITIALISED, 8022 ), /**< Attribute cache isn't initialised */ \ + RESULT_ENUM( prefix, MAX_CONNECTIONS_REACHED, 8023 ), /**< Maximum number of connections is reached */ \ + RESULT_ENUM( prefix, SOCKET_IN_USE, 8024 ), /**< Socket specified is in use */ \ + RESULT_ENUM( prefix, SOCKET_NOT_CONNECTED, 8025 ), /**< Socket is not connected or connection failed */ \ + RESULT_ENUM( prefix, ENCRYPTION_FAILED, 8026 ), /**< Encryption failed */ \ + RESULT_ENUM( prefix, SCAN_IN_PROGRESS, 8027 ), /**< Scan is in progress */ \ + RESULT_ENUM( prefix, CONNECT_IN_PROGRESS, 8028 ), /**< Connect is in progress */ \ + RESULT_ENUM( prefix, DISCONNECT_IN_PROGRESS, 8029 ), /**< Disconnect is in progress */ \ + RESULT_ENUM( prefix, DISCOVER_IN_PROGRESS, 8030 ), /**< Discovery is in progress */ \ + RESULT_ENUM( prefix, GATT_TIMEOUT, 8031 ), /**< GATT timeout occured*/ \ + RESULT_ENUM( prefix, ATTRIBUTE_VALUE_TOO_LONG, 8032 ), /**< Attribute value too long */ \ + RESULT_ENUM( prefix, PENDING, 8100 ), /**< Pending */ \ + RESULT_ENUM( prefix, BUSY, 8101 ), /**< Device busy with another command */ \ + RESULT_ENUM( prefix, NO_RESOURCES, 8102 ), /**< No resources to issue command */ \ + RESULT_ENUM( prefix, UNSUPPORTED, 8103 ), /**< Unsupported function */ \ + RESULT_ENUM( prefix, ILLEGAL_VALUE, 8104 ), /**< Illegal parameter value */ \ + RESULT_ENUM( prefix, WRONG_MODE, 8105 ), /**< Device in wrong mode for request */ \ + RESULT_ENUM( prefix, UNKNOWN_ADDR, 8106 ), /**< Unknown remote BD address */ \ + RESULT_ENUM( prefix, TIMEOUT, 8107 ), /**< Timeout */ \ + RESULT_ENUM( prefix, BAD_VALUE_RET, 8108 ), /**< A bad value was received from HCI */ \ + RESULT_ENUM( prefix, ERROR, 8109 ), /**< Error */ \ + RESULT_ENUM( prefix, NOT_AUTHORIZED, 8110 ), /**< Authorization failed */ \ + RESULT_ENUM( prefix, DEV_RESET, 8111 ), /**< Device has been reset */ \ + RESULT_ENUM( prefix, CMD_STORED, 8112 ), /**< request is stored in control block */ \ + RESULT_ENUM( prefix, ILLEGAL_ACTION, 8113 ), /**< state machine gets illegal command */ \ + RESULT_ENUM( prefix, DELAY_CHECK, 8114 ), /**< delay the check on encryption */ \ + RESULT_ENUM( prefix, SCO_BAD_LENGTH, 8115 ), /**< Bad SCO over HCI data length */ \ + RESULT_ENUM( prefix, SUCCESS_NO_SECURITY, 8116 ), /**< security passed, no security set */ \ + RESULT_ENUM( prefix, FAILED_ON_SECURITY, 8117 ), /**< security failed */ \ + RESULT_ENUM( prefix, REPEATED_ATTEMPTS, 8118 ), /**< repeated attempts for LE security requests */ \ + RESULT_ENUM( prefix, MODE4_LEVEL4_NOT_SUPPORTED,8119 ), /**< Connections Only Mode can't be supported */ \ + RESULT_ENUM( prefix, USE_DEFAULT_SECURITY, 8120 ), /**< Use default security*/ + + +/****************************************************** + * Constants + ******************************************************/ + +/** @cond !ADDTHIS*/ +#define MBLE_ADDRESS_BYTE_SIZE 6 +/** @endcond */ + +/****************************************************** + * Enumerations + ******************************************************/ + +/** + * MiCO Result Type + */ +typedef enum { + BT_RESULT_LIST ( MICO_BT_ ) +} mico_bt_result_t; + +/****************************************************** + * Type Definitions + ******************************************************/ + +/****************************************************** + * Structures + ******************************************************/ + + +/****************************************************** + * Global Variables + ******************************************************/ + +/****************************************************** + * Function Declarations + ******************************************************/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif diff --git a/device/bluetooth/mk3239/include/mico_bt_dev.h b/device/bluetooth/mk3239/include/mico_bt_dev.h new file mode 100644 index 0000000000..187c6fd6dd --- /dev/null +++ b/device/bluetooth/mk3239/include/mico_bt_dev.h @@ -0,0 +1,1671 @@ + +/** @file + * + * Bluetooth Management (BTM) Application Programming Interface + * + * The BTM consists of several management entities: + * 1. Device Control - controls the local device + * 2. Device Discovery - manages inquiries, discover database + * 3. ACL Channels - manages ACL connections (BR/EDR and LE) + * 4. SCO Channels - manages SCO connections + * 5. Security - manages all security functionality + * 6. Power Management - manages park, sniff, hold, etc. + * + * @defgroup micobt Bluetooth + * + * MiCO Bluetooth Framework Functions + */ + +#pragma once + +#include "buildcfg.h" +#include "mico_bt_types.h" +#include "mico_bt_constants.h" +#include "hcidefs.h" +#include "bt_types.h" + +/** Result/Status for mico_bt_dev */ +typedef mico_bt_result_t mico_bt_dev_status_t; /**< Result/Status for mico_bt_dev */ + +/** Structure returned with Vendor Specific Command complete callback */ +typedef struct { + uint16_t opcode; /**< Vendor specific command opcode */ + uint16_t param_len; /**< Return parameter length */ + uint8_t *p_param_buf; /**< Return parameter buffer */ +} mico_bt_dev_vendor_specific_command_complete_params_t; + + +/***************************************************************************** + * DEVICE DISCOVERY - Inquiry, Remote Name, Discovery, Class of Device + *****************************************************************************/ +/* BR/EDR Discoverable modes */ +#ifndef BTM_DISCOVERABILITY_MODE +#define BTM_DISCOVERABILITY_MODE +enum mico_bt_discoverability_mode_e { + BTM_NON_DISCOVERABLE = 0, /**< Non discoverable */ + BTM_LIMITED_DISCOVERABLE = 1, /**< Limited BR/EDR discoverable */ + BTM_GENERAL_DISCOVERABLE = 2 /**< General BR/EDR discoverable */ +}; +#define BTM_DISCOVERABLE_MASK (BTM_LIMITED_DISCOVERABLE|BTM_GENERAL_DISCOVERABLE) +#define BTM_MAX_DISCOVERABLE BTM_GENERAL_DISCOVERABLE +#endif /* BTM_DISCOVERABILITY_MODE */ + +/* BR/EDR Connectable modes */ +#ifndef BTM_CONNECTABILITY_MODE +#define BTM_CONNECTABILITY_MODE +enum mico_bt_connectability_mode_e { + BTM_NON_CONNECTABLE = 0, /**< Not connectable */ + BTM_CONNECTABLE = 1 /**< BR/EDR connectable */ +}; +#define BTM_CONNECTABLE_MASK (BTM_NON_CONNECTABLE | BTM_CONNECTABLE) +#endif /* BTM_CONNECTABILITY_MODE */ + +/* Inquiry modes + * Note: These modes are associated with the inquiry active values (BTM_*ACTIVE) + */ +#ifndef BTM_INQUIRY_MODE /* To avoid redefintions when including mico_bt_dev.h */ +#define BTM_INQUIRY_MODE +enum mico_bt_inquiry_mode_e { + BTM_INQUIRY_NONE = 0, /**< Stop inquiry */ + BTM_GENERAL_INQUIRY = 0x01, /**< General inquiry */ + BTM_LIMITED_INQUIRY = 0x02, /**< Limited inquiry */ + BTM_BR_INQUIRY_MASK = (BTM_GENERAL_INQUIRY | BTM_LIMITED_INQUIRY) +}; +#endif /* BTM_INQUIRY_MODE */ + +/* Define scan types */ +#define BTM_SCAN_TYPE_STANDARD 0 +#define BTM_SCAN_TYPE_INTERLACED 1 + +/* Inquiry results mode */ +#define BTM_INQ_RESULT 0 +#define BTM_INQ_RESULT_WITH_RSSI 1 +#define BTM_INQ_RESULT_EXTENDED 2 + +#define BTM_INQ_RES_IGNORE_RSSI 0x7f /**< RSSI value not supplied (ignore it) */ +#define BTM_SCAN_PARAM_IGNORE 0 /* Passed to BTM_SetScanConfig() to ignore */ + +/* Inquiry Filter Condition types (see mico_bt_dev_inq_parms_t) */ +#ifndef BTM_INQUIRY_FILTER +#define BTM_INQUIRY_FILTER +enum mico_bt_dev_filter_cond_e { + BTM_CLR_INQUIRY_FILTER = 0, /**< No inquiry filter */ + BTM_FILTER_COND_DEVICE_CLASS = HCI_FILTER_COND_DEVICE_CLASS, /**< Filter on device class */ + BTM_FILTER_COND_BD_ADDR = HCI_FILTER_COND_BD_ADDR, /**< Filter on device addr */ +}; +#endif /* BTM_INQUIRY_FILTER */ + +/* State of the remote name retrieval during inquiry operations. + * Used in the mico_bt_dev_inq_info_t structure, and returned in the + * BTM_InqDbRead, BTM_InqDbFirst, and BTM_InqDbNext functions. + * The name field is valid when the state returned is + * BTM_INQ_RMT_NAME_DONE */ +#define BTM_INQ_RMT_NAME_EMPTY 0 +#define BTM_INQ_RMT_NAME_PENDING 1 +#define BTM_INQ_RMT_NAME_DONE 2 +#define BTM_INQ_RMT_NAME_FAILED 3 + + +/** BTM service definitions (used for storing EIR data to bit mask */ +#ifndef BTM_EIR_UUID_ENUM +#define BTM_EIR_UUID_ENUM +enum { + BTM_EIR_UUID_SERVCLASS_SERVICE_DISCOVERY_SERVER, + BTM_EIR_UUID_SERVCLASS_SERIAL_PORT, + BTM_EIR_UUID_SERVCLASS_LAN_ACCESS_USING_PPP, + BTM_EIR_UUID_SERVCLASS_DIALUP_NETWORKING, + BTM_EIR_UUID_SERVCLASS_IRMC_SYNC, + BTM_EIR_UUID_SERVCLASS_OBEX_OBJECT_PUSH, + BTM_EIR_UUID_SERVCLASS_OBEX_FILE_TRANSFER, + BTM_EIR_UUID_SERVCLASS_IRMC_SYNC_COMMAND, + BTM_EIR_UUID_SERVCLASS_HEADSET, + BTM_EIR_UUID_SERVCLASS_CORDLESS_TELEPHONY, + BTM_EIR_UUID_SERVCLASS_AUDIO_SOURCE, + BTM_EIR_UUID_SERVCLASS_AUDIO_SINK, + BTM_EIR_UUID_SERVCLASS_AV_REM_CTRL_TARGET, + BTM_EIR_UUID_SERVCLASS_AV_REMOTE_CONTROL, + BTM_EIR_UUID_SERVCLASS_INTERCOM, + BTM_EIR_UUID_SERVCLASS_FAX, + BTM_EIR_UUID_SERVCLASS_HEADSET_AUDIO_GATEWAY, + BTM_EIR_UUID_SERVCLASS_PANU, + BTM_EIR_UUID_SERVCLASS_NAP, + BTM_EIR_UUID_SERVCLASS_GN, + BTM_EIR_UUID_SERVCLASS_DIRECT_PRINTING, + BTM_EIR_UUID_SERVCLASS_IMAGING, + BTM_EIR_UUID_SERVCLASS_IMAGING_RESPONDER, + BTM_EIR_UUID_SERVCLASS_IMAGING_AUTO_ARCHIVE, + BTM_EIR_UUID_SERVCLASS_IMAGING_REF_OBJECTS, + BTM_EIR_UUID_SERVCLASS_HF_HANDSFREE, + BTM_EIR_UUID_SERVCLASS_AG_HANDSFREE, + BTM_EIR_UUID_SERVCLASS_DIR_PRT_REF_OBJ_SERVICE, + BTM_EIR_UUID_SERVCLASS_BASIC_PRINTING, + BTM_EIR_UUID_SERVCLASS_PRINTING_STATUS, + BTM_EIR_UUID_SERVCLASS_HUMAN_INTERFACE, + BTM_EIR_UUID_SERVCLASS_CABLE_REPLACEMENT, + BTM_EIR_UUID_SERVCLASS_HCRP_PRINT, + BTM_EIR_UUID_SERVCLASS_HCRP_SCAN, + BTM_EIR_UUID_SERVCLASS_SAP, + BTM_EIR_UUID_SERVCLASS_PBAP_PCE, + BTM_EIR_UUID_SERVCLASS_PBAP_PSE, + BTM_EIR_UUID_SERVCLASS_PHONE_ACCESS, + BTM_EIR_UUID_SERVCLASS_HEADSET_HS, + BTM_EIR_UUID_SERVCLASS_PNP_INFORMATION, + BTM_EIR_UUID_SERVCLASS_VIDEO_SOURCE, + BTM_EIR_UUID_SERVCLASS_VIDEO_SINK, + BTM_EIR_UUID_SERVCLASS_MESSAGE_ACCESS, + BTM_EIR_UUID_SERVCLASS_MESSAGE_NOTIFICATION, + BTM_EIR_UUID_SERVCLASS_HDP_SOURCE, + BTM_EIR_UUID_SERVCLASS_HDP_SINK, + BTM_EIR_MAX_SERVICES +}; +#endif /* BTM_EIR_UUID_ENUM */ + + +/************************************************************************************************ + * BTM Services MACROS handle array of uint32_t bits for more than 32 services + ************************************************************************************************/ +/* Determine the number of uint32_t's necessary for services */ +#define BTM_EIR_ARRAY_BITS 32 /* Number of bits in each array element */ +#ifndef BTM_EIR_SERVICE_ARRAY_SIZE +#define BTM_EIR_SERVICE_ARRAY_SIZE (((uint32_t)BTM_EIR_MAX_SERVICES / BTM_EIR_ARRAY_BITS) + \ + (((uint32_t)BTM_EIR_MAX_SERVICES % BTM_EIR_ARRAY_BITS) ? 1 : 0)) +#endif + +/*************************** + * Device Discovery Types + ****************************/ +/** Class of Device inquiry filter */ +typedef struct { + mico_bt_dev_class_t dev_class; /**< class of device */ + mico_bt_dev_class_t dev_class_mask; /**< class of device filter mask */ +} mico_bt_dev_cod_cond_t; + +/** Inquiry filter */ +typedef union { + mico_bt_device_address_t bdaddr_cond; /**< bluetooth address filter */ + mico_bt_dev_cod_cond_t cod_cond; /**< class of device filter */ +} mico_bt_dev_inq_filt_cond_t; + +/** Inquiry Parameters */ +typedef struct { + uint8_t mode; /**< Inquiry mode (see #mico_bt_inquiry_mode_e) */ + uint8_t duration; /**< Inquiry duration (1.28 sec increments) */ + uint8_t filter_cond_type; /**< Inquiry filter type (see #mico_bt_dev_filter_cond_e) */ + mico_bt_dev_inq_filt_cond_t filter_cond; /**< Inquiry filter */ +} mico_bt_dev_inq_parms_t; + +/** Inquiry Results */ +typedef struct { + uint16_t clock_offset; /**< Clock offset */ + mico_bt_device_address_t remote_bd_addr; /**< Device address */ + mico_bt_dev_class_t dev_class; /**< Class of device */ + uint8_t page_scan_rep_mode; /**< Page scan repetition mode */ + uint8_t page_scan_per_mode; /**< Page scan per mode */ + uint8_t page_scan_mode; /**< Page scan mode */ + int8_t + rssi; /**< Receive signal strength index (#BTM_INQ_RES_IGNORE_RSSI, if not available) */ + uint32_t eir_uuid[BTM_EIR_SERVICE_ARRAY_SIZE]; /**< Array or EIR UUIDs */ + mico_bool_t eir_complete_list; /**< TRUE if EIR array is complete */ +} mico_bt_dev_inquiry_scan_result_t; + +/** RSSI Result (in response to #mico_bt_dev_read_rssi) */ +typedef struct { + mico_bt_result_t status; /**< Status of the operation */ + uint8_t hci_status; /**< Status from controller */ + int8_t rssi; /**< RSSI */ + mico_bt_device_address_t rem_bda; /**< Remote BD address */ +} mico_bt_dev_rssi_result_t; + +/** TX Power Result (in response to #mico_bt_dev_read_tx_power) */ +typedef struct { + mico_bt_result_t status; /**< Status of the operation */ + uint8_t hci_status; /**< Status from controller */ + int8_t tx_power; /**< TX power */ + mico_bt_device_address_t rem_bda; /**< Remote BD address */ +} mico_bt_tx_power_result_t; + +/***************************************************************************** + * SECURITY MANAGEMENT + *****************************************************************************/ + +/** Security Service Levels [bit mask]. Encryption should not be used without authentication. */ +#ifndef BTM_SEC_LEVEL +#define BTM_SEC_LEVEL +enum mico_bt_sec_level_e { + BTM_SEC_NONE = 0x0000, /**< Nothing required */ + BTM_SEC_IN_AUTHENTICATE = 0x0002, /**< Inbound call requires authentication */ + BTM_SEC_OUT_AUTHENTICATE = 0x0010, /**< Outbound call requires authentication */ + BTM_SEC_ENCRYPT = 0x0024, /**< Requires encryption (inbound and outbound) */ + BTM_SEC_SECURE_CONNECTION = 0x0040 /**< Secure Connections Mode (P-256 based Secure Simple Pairing and Authentication) */ +}; +#endif /* BTM_SEC_LEVEL */ + +/** PIN types */ +#define BTM_PIN_TYPE_VARIABLE HCI_PIN_TYPE_VARIABLE +#define BTM_PIN_TYPE_FIXED HCI_PIN_TYPE_FIXED + +/** Size of security keys */ +#ifndef BTM_SECURITY_KEY_DATA_LEN +#define BTM_SECURITY_KEY_DATA_LEN 132 /**< Security key data length (used by mico_bt_device_link_keys_t structure) */ +#endif + +#ifndef BTM_SECURITY_LOCAL_KEY_DATA_LEN +#define BTM_SECURITY_LOCAL_KEY_DATA_LEN 65 /**< Local security key data length (used by mico_bt_local_identity_keys_t structure) */ +#endif + +/** Pairing IO Capabilities */ +enum mico_bt_dev_io_cap_e { + BTM_IO_CAPABILITIES_DISPLAY_ONLY, /**< Display Only */ + BTM_IO_CAPABILITIES_DISPLAY_AND_KEYBOARD, /**< Display Yes/No */ + BTM_IO_CAPABILITIES_KEYBOARD_ONLY, /**< Keyboard Only */ + BTM_IO_CAPABILITIES_NONE, /**< No Input, No Output */ + BTM_IO_CAPABILITIES_KEYBOARD_DISPLAY, /**< Keyboard display */ + BTM_IO_CAPABILITIES_MAX +}; +typedef uint8_t mico_bt_dev_io_cap_t; /**< IO capabilities (see #mico_bt_dev_io_cap_e) */ + +/** BR/EDR Authentication requirement */ +enum mico_bt_dev_auth_req_e { + BTM_AUTH_SINGLE_PROFILE_NO = 0, /**< MITM Protection Not Required - Single Profile/non-bonding. Numeric comparison with automatic accept allowed */ + BTM_AUTH_SINGLE_PROFILE_YES = 1, /**< MITM Protection Required - Single Profile/non-bonding. Use IO Capabilities to determine authentication procedure */ + BTM_AUTH_ALL_PROFILES_NO = 2, /**< MITM Protection Not Required - All Profiles/dedicated bonding. Numeric comparison with automatic accept allowed */ + BTM_AUTH_ALL_PROFILES_YES = 3, /**< MITM Protection Required - All Profiles/dedicated bonding. Use IO Capabilities to determine authentication procedure */ + BTM_AUTH_SINGLE_PROFILE_GENERAL_BONDING_NO = 4, /**< MITM Protection Not Required - Single Profiles/general bonding. Numeric comparison with automatic accept allowed */ + BTM_AUTH_SINGLE_PROFILE_GENERAL_BONDING_YES = 5, /**< MITM Protection Required - Single Profiles/general bonding. Use IO Capabilities to determine authentication procedure */ +}; +typedef uint8_t +mico_bt_dev_auth_req_t; /**< BR/EDR authentication requirement (see #mico_bt_dev_auth_req_e) */ + +/** Device Security Mode */ +enum mico_bt_security_mode_e { + BTM_SEC_MODE_UNDEFINED = 0, + BTM_SEC_MODE_NONE = 1, + BTM_SEC_MODE_SERVICE = 2, + BTM_SEC_MODE_LINK = 3, + BTM_SEC_MODE_SP = 4, + BTM_SEC_MODE_SP_DEBUG = 5, + BTM_SEC_MODE_SC = 6, +}; +typedef uint8_t mico_bt_security_mode_t; + +/** LE Authentication requirement */ +enum mico_bt_dev_le_auth_req_e { + BTM_LE_AUTH_REQ_NO_BOND = 0x00, /**< Not required - No Bond */ + BTM_LE_AUTH_REQ_BOND = 0x01, /**< Required - General Bond */ + BTM_LE_AUTH_REQ_MITM = 0x04, /**< MITM required - Auth Y/N*/ + BTM_LE_AUTH_REQ_SC_ONLY = 0x08, /**< LE Secure Connection, no MITM, no Bonding */ + BTM_LE_AUTH_REQ_SC_BOND = (BTM_LE_AUTH_REQ_SC_ONLY | BTM_LE_AUTH_REQ_BOND), /**< LE Secure Connection, no MITM, Bonding */ + BTM_LE_AUTH_REQ_SC_MITM = (BTM_LE_AUTH_REQ_SC_ONLY | BTM_LE_AUTH_REQ_MITM), /**< LE Secure Connection, MITM, no Bonding */ + BTM_LE_AUTH_REQ_SC_MITM_BOND = (BTM_LE_AUTH_REQ_SC_ONLY | BTM_LE_AUTH_REQ_MITM | BTM_LE_AUTH_REQ_BOND), /**< LE Secure Connection, MITM, Bonding */ + BTM_LE_AUTH_REQ_MASK = 0x1D +}; +typedef uint8_t +mico_bt_dev_le_auth_req_t; /**< BLE authentication requirement (see #mico_bt_dev_le_auth_req_e) */ + +/** OOB Data status */ +#ifndef BTM_OOB_STATE +#define BTM_OOB_STATE +enum mico_bt_dev_oob_data_e { + BTM_OOB_NONE, /**< No OOB data */ + BTM_OOB_PRESENT_192, /**< OOB data present (from the P-192 public key) */ + BTM_OOB_PRESENT_256, /**< OOB data present (from the P-256 public key) */ + BTM_OOB_PRESENT_192_256, /**< OOB data present (from the P-192 and P-256 public keys) */ + BTM_OOB_UNKNOWN /**< OOB data unknown */ +}; +#endif +typedef uint8_t mico_bt_dev_oob_data_t; /**< OOB data (see #mico_bt_dev_oob_data_e) */ + +/** Data type for IO capabalities response (BTM_PAIRING_IO_CAPABILITIES_BR_EDR_RESPONSE_EVT) */ +typedef struct { + mico_bt_device_address_t bd_addr; /**< Peer address */ + mico_bt_dev_io_cap_t io_cap; /**< Peer IO capabilities */ + mico_bt_dev_oob_data_t oob_data; /**< OOB data present at peer device for the local device */ + mico_bt_dev_auth_req_t auth_req; /**< Authentication required for peer device */ +} mico_bt_dev_bredr_io_caps_rsp_t; + +/** Data for pairing confirmation request (BTM_USER_CONFIRMATION_REQUEST_EVT event data type) */ +typedef struct { + mico_bt_device_address_t bd_addr; /**< peer address */ + uint32_t + numeric_value; /**< numeric value for comparison (if "just_works", do not show this number to UI) */ + mico_bool_t just_works; /**< TRUE, if using "just works" association model */ + mico_bt_dev_auth_req_t local_authentication_requirements; /**< Authentication requirement for local device */ + mico_bt_dev_auth_req_t remote_authentication_requirements; /**< Authentication requirement for peer device */ +} mico_bt_dev_user_cfm_req_t; + +/** Pairing user passkey request (BTM_USER_PASSKEY_REQUEST_EVT event data type) */ +typedef struct { + mico_bt_device_address_t bd_addr; /**< peer address */ +} mico_bt_dev_user_key_req_t; + +/** Data for pairing passkey notification (BTM_USER_PASSKEY_NOTIFICATION_EVT event data type) */ +typedef struct { + mico_bt_device_address_t bd_addr; /**< peer address */ + uint32_t passkey; /**< passkey */ +} mico_bt_dev_user_key_notif_t; + + +/** Pairing keypress types */ +enum mico_bt_dev_passkey_entry_type_e { + BTM_PASSKEY_ENTRY_STARTED, /**< passkey entry started */ + BTM_PASSKEY_DIGIT_ENTERED, /**< passkey digit entered */ + BTM_PASSKEY_DIGIT_ERASED, /**< passkey digit erased */ + BTM_PASSKEY_DIGIT_CLEARED, /**< passkey cleared */ + BTM_PASSKEY_ENTRY_COMPLETED /**< passkey entry completed */ +}; +typedef uint8_t +mico_bt_dev_passkey_entry_type_t; /**< Bluetooth pairing keypress value (see #mico_bt_dev_passkey_entry_type_e) */ + +/** Pairing keypress notification (BTM_USER_KEYPRESS_NOTIFICATION_EVT event data type) */ +typedef struct { + mico_bt_device_address_t bd_addr; /**< peer address */ + mico_bt_dev_passkey_entry_type_t keypress_type; /**< type of keypress */ +} mico_bt_dev_user_keypress_t; + +/** BR/EDR pairing complete infomation */ +typedef struct { + uint8_t + status; /**< status of the simple pairing process (see defintions for HCI status codes) */ +} mico_bt_dev_br_edr_pairing_info_t; + +/** BLE pairing complete infomation */ +typedef struct { + mico_bt_result_t status; /**< status of the simple pairing process */ + uint8_t reason; /**< failure reason (see #mico_bt_smp_status_t) */ + uint8_t sec_level; /**< 0 - None, 1- Unauthenticated Key, 4-Authenticated Key */ + mico_bool_t privacy_supported; /**< True if privacy supported, False if not */ + mico_bool_t is_pair_cancel; /**< True if cancelled, else False */ + mico_bt_device_address_t + resolved_bd_addr; /**< Resolved address (if remote device using private address) */ + mico_bt_ble_address_type_t resolved_bd_addr_type; /**< Resolved addr type of bonded device */ +} mico_bt_dev_ble_pairing_info_t; + +/** Transport dependent pairing complete infomation */ +typedef union { + mico_bt_dev_br_edr_pairing_info_t br_edr; /**< BR/EDR pairing complete infomation */ + mico_bt_dev_ble_pairing_info_t ble; /**< BLE pairing complete infomation */ +} mico_bt_dev_pairing_info_t; + +/** Pairing complete notification (BTM_PAIRING_COMPLETE_EVT event data type) */ +typedef struct { + uint8_t *bd_addr; /**< peer address */ + mico_bt_transport_t transport; /**< BT_TRANSPORT_BR_EDR or BT_TRANSPORT_LE */ + mico_bt_dev_pairing_info_t pairing_complete_info; /**< Transport dependent pairing complete infomation */ + mico_bt_result_t + bonding_status; /**< current status of bonding process to notify app of completion status of storing keys */ +} mico_bt_dev_pairing_cplt_t; + +/** Check if application wishes to upgrade security (BTM_SECURITY_UPGRADE_EVT event data type) */ +typedef struct { + mico_bt_device_address_t bd_addr; /**< [in] Peer address */ + mico_bool_t upgrade; /**< [out] Set to TRUE to request security upgrade */ +} mico_bt_dev_security_upgrade_t; + +/** Security request (BTM_SECURITY_REQUEST_EVT event data type) */ +typedef struct { + mico_bt_device_address_t bd_addr; /**< peer address */ +} mico_bt_dev_security_request_t; + +/** LE Key type */ +#ifndef BTM_LE_KEY_TYPES +#define BTM_LE_KEY_TYPES +enum mico_bt_dev_le_key_type_e { + BTM_LE_KEY_PENC = (1 << 0), /**< encryption information of peer device */ + BTM_LE_KEY_PID = (1 << 1), /**< identity key of the peer device */ + BTM_LE_KEY_PCSRK = (1 << 2), /**< peer SRK */ +#if SMP_LE_SC_INCLUDED == TRUE + BTM_LE_KEY_PLK = (1 << 3), + BTM_LE_KEY_LENC = (1 << 4), /**< master role security information:div */ + BTM_LE_KEY_LID = (1 << 5), /**< master device ID key */ + BTM_LE_KEY_LCSRK = (1 << 6), /**< local CSRK has been deliver to peer */ + BTM_LE_KEY_LLK = (1 << 7), +#else + BTM_LE_KEY_LENC = (1 << 3), /**< master role security information:div */ + BTM_LE_KEY_LID = (1 << 4), /**< master device ID key */ + BTM_LE_KEY_LCSRK = (1 << 5), /**< local CSRK has been deliver to peer */ +#endif + BTM_BR_EDR_LKEY = 0xFF +}; +#endif /* BTM_LE_KEY_TYPES */ +typedef uint8_t mico_bt_dev_le_key_type_t; /**< LE key type (see #mico_bt_dev_le_key_type_e) */ + + +enum mico_bt_dev_link_key_type_e { + BTM_LKEY_TYPE_COMBINATION, + BTM_LKEY_TYPE_LOCAL_UNIT, + BTM_LKEY_TYPE_REMOTE_UNIT, + BTM_LKEY_TYPE_DEBUG_COMB, + BTM_LKEY_TYPE_UNAUTH_COMB, + BTM_LKEY_TYPE_AUTH_COMB, + BTM_LKEY_TYPE_CHANGED_COMB, + BTM_LKEY_TYPE_UNAUTH_COMB_P_256, + BTM_LKEY_TYPE_AUTH_COMB_P_256, +}; +typedef uint8_t LINK_KEY_TYPE; + +/* LE security level */ +#define BTM_LE_SEC_NONE 0 +#define BTM_LE_SEC_UNAUTHENTICATE 1 +#define BTM_LE_SEC_AUTHENTICATED 4 +typedef uint8_t mico_bt_security_level; + + +/* BLE encryption keys */ +typedef struct { + BT_OCTET16 ltk; + BT_OCTET8 rand; + UINT16 ediv; + mico_bt_security_level sec_level; + UINT8 key_size; +} tBTM_LE_PENC_KEYS; + +/* BLE CSRK keys */ +typedef struct { + UINT32 counter; + BT_OCTET16 csrk; + mico_bt_security_level sec_level; +} tBTM_LE_PCSRK_KEYS; + +/* BLE Encryption reproduction keys */ +typedef struct { +#if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE && SMP_LE_SC_INCLUDED == TRUE + BT_OCTET16 ltk; +#endif + UINT16 div; + UINT8 key_size; + mico_bt_security_level sec_level; +} tBTM_LE_LENC_KEYS; + +/* BLE SRK keys */ +typedef struct { + UINT32 counter; + UINT16 div; + mico_bt_security_level sec_level; +#if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE && SMP_LE_SC_INCLUDED == TRUE + BT_OCTET16 csrk; +#endif +} tBTM_LE_LCSRK_KEYS; + +typedef struct { + BT_OCTET16 irk; + mico_bt_ble_address_type_t addr_type; + mico_bt_device_address_t static_addr; +} tBTM_LE_PID_KEYS; + +typedef union { + tBTM_LE_PENC_KEYS penc_key; /* received peer encryption key */ + tBTM_LE_PCSRK_KEYS pcsrk_key; /* received peer device SRK */ + tBTM_LE_PID_KEYS pid_key; /* peer device ID key */ + tBTM_LE_LENC_KEYS lenc_key; /* local encryption reproduction keys LTK = = d1(ER,DIV,0)*/ + tBTM_LE_LCSRK_KEYS lcsrk_key; /* local device CSRK = d1(ER,DIV,1)*/ +} tBTM_LE_KEY_VALUE; + +typedef struct { + /* BR/EDR key */ + LINK_KEY_TYPE br_edr_key_type; /* BR/EDR Link Key type */ + LINK_KEY br_edr_key; /* BR/EDR Link Key */ +} tBTM_BR_EDR_KEY; + + +typedef union { + tBTM_LE_KEY_VALUE le_keys; + tBTM_BR_EDR_KEY br_edr_key; +} mico_bt_security_key_value_t; + + +/** Scan duty cycle (used for BTM_BLE_SCAN_STATE_CHANGED_EVT and mico_bt_dev_create_connection) */ +#ifndef BTM_BLE_SCAN_TYPE +#define BTM_BLE_SCAN_TYPE +enum mico_bt_ble_scan_type_e { + BTM_BLE_SCAN_TYPE_NONE, /**< Stop scanning */ + BTM_BLE_SCAN_TYPE_HIGH_DUTY, /**< High duty cycle scan */ + BTM_BLE_SCAN_TYPE_LOW_DUTY /**< Low duty cycle scan */ +}; +#endif +typedef uint8_t mico_bt_ble_scan_type_t; /**< scan type (see #mico_bt_ble_scan_type_e) */ + + +/** bonding device information from mico_bt_dev_get_bonded_devices */ +typedef struct { + mico_bt_device_address_t bd_addr; /**< peer address */ + mico_bt_ble_address_type_t addr_type; /**< peer address type : BLE_ADDR_PUBLIC/BLE_ADDR_RANDOM */ + mico_bt_device_type_t + device_type; /**< peer device type : BT_DEVICE_TYPE_BREDR/BT_DEVICE_TYPE_BLE/BT_DEVICE_TYPE_BREDR_BLE */ +} mico_bt_dev_bonded_device_info_t; + +/* LE Secure connection event data */ +/** Type of OOB data required */ +#ifndef BTM_OOB_REQ_TYPE +#define BTM_OOB_REQ_TYPE +enum mico_bt_dev_oob_data_req_type_e { + BTM_OOB_INVALID_TYPE, + BTM_OOB_PEER, /**< Peer OOB data requested */ + BTM_OOB_LOCAL, /**< Local OOB data requested */ + BTM_OOB_BOTH /**< Both local and peer OOB data requested */ +}; +#endif +typedef UINT8 +mico_bt_dev_oob_data_req_type_t; /**< OOB data type requested (see #mico_bt_dev_oob_data_req_type_t) */ + +/** SMP Pairing status codes */ +enum mico_bt_smp_status_e { + SMP_SUCCESS = 0, /**< Success */ + SMP_PASSKEY_ENTRY_FAIL = 0x01, /**< Passkey entry failed */ + SMP_OOB_FAIL = 0x02, /**< OOB failed */ + SMP_PAIR_AUTH_FAIL = 0x03, /**< Authentication failed */ + SMP_CONFIRM_VALUE_ERR = 0x04, /**< Value confirmation failed */ + SMP_PAIR_NOT_SUPPORT = 0x05, /**< Not supported */ + SMP_ENC_KEY_SIZE = 0x06, /**< Encryption key size failure */ + SMP_INVALID_CMD = 0x07, /**< Invalid command */ + SMP_PAIR_FAIL_UNKNOWN = 0x08, /**< Unknown failure */ + SMP_REPEATED_ATTEMPTS = 0x09, /**< Repeated attempts */ + SMP_INVALID_PARAMETERS = 0x0A, /**< Invalid parameters */ + SMP_DHKEY_CHK_FAIL = 0x0B, /**< DH Key check failed */ + SMP_NUMERIC_COMPAR_FAIL = 0x0C, /**< Numeric comparison failed */ + SMP_BR_PAIRING_IN_PROGR = 0x0D, /**< BR paIring in progress */ + SMP_XTRANS_DERIVE_NOT_ALLOW = 0x0E, /**< Cross transport key derivation not allowed */ + SMP_MAX_FAIL_RSN_PER_SPEC = SMP_XTRANS_DERIVE_NOT_ALLOW, + + /* bte smp status codes */ + SMP_PAIR_INTERNAL_ERR = (SMP_MAX_FAIL_RSN_PER_SPEC + 0x01), /**< Internal error */ + SMP_UNKNOWN_IO_CAP = (SMP_MAX_FAIL_RSN_PER_SPEC + 0x02), /**< unknown IO capability, unable to decide associatino model */ + SMP_INIT_FAIL = (SMP_MAX_FAIL_RSN_PER_SPEC + 0x03), /**< Initialization failed */ + SMP_CONFIRM_FAIL = (SMP_MAX_FAIL_RSN_PER_SPEC + 0x04), /**< Confirmation failed */ + SMP_BUSY = (SMP_MAX_FAIL_RSN_PER_SPEC + 0x05), /**< Busy */ + SMP_ENC_FAIL = (SMP_MAX_FAIL_RSN_PER_SPEC + 0x06), /**< Encryption failed */ + SMP_STARTED = (SMP_MAX_FAIL_RSN_PER_SPEC + 0x07), /**< Started */ + SMP_RSP_TIMEOUT = (SMP_MAX_FAIL_RSN_PER_SPEC + 0x08), /**< Response timeout */ + SMP_FAIL = (SMP_MAX_FAIL_RSN_PER_SPEC + 0x09), /**< Generic failure */ + SMP_CONN_TOUT = (SMP_MAX_FAIL_RSN_PER_SPEC + 0x0A), /**< Connection timeout */ +}; +typedef uint8_t mico_bt_smp_status_t; /**< SMP Pairing status (see #mico_bt_smp_status_e) */ + +/** data type for BTM_SMP_REMOTE_OOB_DATA_REQUEST_EVT */ +typedef struct { + mico_bt_device_address_t bd_addr; /* peer address */ +} mico_bt_smp_remote_oob_req_t; + +/** data type for BTM_SMP_SC_REMOTE_OOB_DATA_REQUEST_EVT */ +typedef struct { + mico_bt_device_address_t bd_addr; /* peer address */ + mico_bt_dev_oob_data_req_type_t + oob_type; /* requested oob data types (BTM_OOB_PEER, BTM_OOB_LOCAL, or BTM_OOB_BOTH) */ +} mico_bt_smp_sc_remote_oob_req_t; + +/** Public key */ +typedef struct { + BT_OCTET32 x; + BT_OCTET32 y; +} mico_bt_public_key_t; + +/**< Data for BTM_SMP_SC_LOCAL_OOB_DATA_NOTIFICATION_EVT */ +typedef struct { + mico_bool_t present; /**< TRUE if local oob is present */ + BT_OCTET16 randomizer; /**< randomizer */ + BT_OCTET16 commitment; /**< commitment */ + + mico_bt_ble_address_t addr_sent_to; /**< peer address sent to */ + BT_OCTET32 private_key_used; /**< private key */ + mico_bt_public_key_t public_key_used; /**< public key */ +} mico_bt_smp_sc_local_oob_t; + + +/** SCO link type */ +#define BTM_LINK_TYPE_SCO HCI_LINK_TYPE_SCO /**< Link type SCO */ +#define BTM_LINK_TYPE_ESCO HCI_LINK_TYPE_ESCO /**< Link type eSCO */ +typedef uint8_t mico_bt_sco_type_t; + + +/** LE identity key for local device (used by BTM_LE_LOCAL_IDENTITY_KEYS_UPDATE_EVT and BTM_LE_LOCAL_KEYS_REQUEST_EVT notification) */ +typedef struct { + uint8_t local_key_data[BTM_SECURITY_LOCAL_KEY_DATA_LEN]; /**< [in/out] Local security key */ +} mico_bt_local_identity_keys_t; + +/** SCO connected event related data */ +typedef struct { + uint16_t sco_index; /**< SCO index */ +} mico_bt_sco_connected_t; + +/** SCO disconnected event related data */ +typedef struct { + uint16_t sco_index; /**< SCO index */ +} mico_bt_sco_disconnected_t; + +/** SCO connect request event related data */ +typedef struct { + uint16_t sco_index; /**< SCO index */ + mico_bt_device_address_t bd_addr; /**< Peer bd address */ + mico_bt_dev_class_t dev_class; /**< Peer device class */ + mico_bt_sco_type_t link_type; /**< SCO link type */ +} mico_bt_sco_connection_request_t; + +/** SCO connection change event related data */ +typedef struct { + uint16_t sco_index; /**< SCO index */ + uint16_t rx_pkt_len; /**< RX packet length */ + uint16_t tx_pkt_len; /**< TX packet length */ + mico_bt_device_address_t bd_addr; /**< Peer bd address */ + uint8_t hci_status; /**< HCI status */ + uint8_t tx_interval; /**< TX interval */ + uint8_t retrans_windows; /**< Retransmission windows */ +} mico_bt_sco_connection_change_t; + + +/** Power Management status codes */ +#ifndef BTM_PM_STATUS_CODES +#define BTM_PM_STATUS_CODES +enum mico_bt_dev_power_mgmt_status_e { + BTM_PM_STS_ACTIVE = HCI_MODE_ACTIVE, /**< Active */ + BTM_PM_STS_HOLD = HCI_MODE_HOLD, /**< Hold */ + BTM_PM_STS_SNIFF = HCI_MODE_SNIFF, /**< Sniff */ + BTM_PM_STS_PARK = HCI_MODE_PARK, /**< Park */ + BTM_PM_STS_SSR, /**< Sniff subrating notification */ + BTM_PM_STS_PENDING, /**< Pending (waiting for status from controller) */ + BTM_PM_STS_ERROR /**< Error (controller returned error) */ +}; +#endif +typedef uint8_t +mico_bt_dev_power_mgmt_status_t; /**< Power management status (see #mico_bt_dev_power_mgmt_status_e) */ + +/* Bluetooth application tracing macro */ +#ifndef WPRINT_BT_APP_INFO +//extern mico_mutex_t global_trace_mutex; +/* +#define WPRINT_BT_APP_INFO(info) { \ + mico_rtos_lock_mutex(&global_trace_mutex); \ + WPRINT_APP_INFO(info); \ + mico_rtos_unlock_mutex(&global_trace_mutex); \ + } +*/ +#endif + + +#ifndef BTM_MANAGEMENT_EVT +#define BTM_MANAGEMENT_EVT +/** Bluetooth Management events */ +enum mico_bt_management_evt_e { + /* Bluetooth status events */ + BTM_ENABLED_EVT, /**< Bluetooth controller and host stack enabled. Event data: mico_bt_dev_enabled_t */ + BTM_DISABLED_EVT, /**< Bluetooth controller and host stack disabled. Event data: NULL */ + BTM_POWER_MANAGEMENT_STATUS_EVT, /**< Power management status change. Event data: mico_bt_power_mgmt_notification_t */ + + /* Security events */ + BTM_PIN_REQUEST_EVT, /**< PIN request (used only with legacy devices). Event data: #mico_bt_dev_name_and_class_t */ + BTM_USER_CONFIRMATION_REQUEST_EVT, /**< received USER_CONFIRMATION_REQUEST event (respond using #mico_bt_dev_confirm_req_reply). Event data: #mico_bt_dev_user_cfm_req_t */ + BTM_PASSKEY_NOTIFICATION_EVT, /**< received USER_PASSKEY_NOTIFY event. Event data: #mico_bt_dev_user_key_notif_t */ + BTM_PASSKEY_REQUEST_EVT, /**< received USER_PASSKEY_REQUEST event (respond using #mico_bt_dev_pass_key_req_reply). Event data: #mico_bt_dev_user_key_req_t */ + BTM_KEYPRESS_NOTIFICATION_EVT, /**< received KEYPRESS_NOTIFY event. Event data: #mico_bt_dev_user_keypress_t */ + BTM_PAIRING_IO_CAPABILITIES_BR_EDR_REQUEST_EVT, /**< Requesting IO capabilities for BR/EDR pairing. Event data: #mico_bt_dev_bredr_io_caps_req_t */ + BTM_PAIRING_IO_CAPABILITIES_BR_EDR_RESPONSE_EVT,/**< Received IO capabilities response for BR/EDR pairing. Event data: #mico_bt_dev_bredr_io_caps_rsp_t */ + BTM_PAIRING_IO_CAPABILITIES_BLE_REQUEST_EVT, /**< Requesting IO capabilities for BLE pairing. Event data: #mico_bt_dev_ble_io_caps_req_t */ + BTM_PAIRING_COMPLETE_EVT, /**< received SIMPLE_PAIRING_COMPLETE event. Event data: #mico_bt_dev_pairing_cplt_t */ + BTM_ENCRYPTION_STATUS_EVT, /**< Encryption status change. Event data: #mico_bt_dev_encryption_status_t */ + BTM_SECURITY_REQUEST_EVT, /**< Security request (respond using #mico_bt_ble_security_grant). Event data: #mico_bt_dev_security_request_t */ + BTM_SECURITY_UPGRADE_EVT, /**< Check if the application wants to upgrade the link key. Event data: #mico_bt_dev_security_upgrade_t */ + BTM_SECURITY_ABORTED_EVT, /**< Security procedure aborted locally, or unexpected link drop. Event data: #mico_bt_dev_name_and_class_t */ + + BTM_READ_LOCAL_OOB_DATA_COMPLETE_EVT, /**< Result of reading local OOB data (mico_bt_dev_read_local_oob_data). Event data: #mico_bt_dev_local_oob_t */ + BTM_REMOTE_OOB_DATA_REQUEST_EVT, /**< OOB data from remote device (respond using #mico_bt_dev_remote_oob_data_reply). Event data: #mico_bt_dev_remote_oob_t */ + + BTM_PAIRED_DEVICE_LINK_KEYS_UPDATE_EVT, /**< Updated remote device link keys (store device_link_keys to NV memory). Event data: #mico_bt_device_link_keys_t */ + BTM_PAIRED_DEVICE_LINK_KEYS_REQUEST_EVT, /**< Request for stored remote device link keys (restore device_link_keys from NV memory). If successful, return MICO_BT_SUCCESS. Event data: #mico_bt_device_link_keys_t */ + + BTM_LOCAL_IDENTITY_KEYS_UPDATE_EVT, /**< Update local identity key (stored local_identity_keys NV memory). Event data: #mico_bt_local_identity_keys_t */ + BTM_LOCAL_IDENTITY_KEYS_REQUEST_EVT, /**< Request local identity key (get local_identity_keys from NV memory). If successful, return MICO_BT_SUCCESS. Event data: #mico_bt_local_identity_keys_t */ + + BTM_BLE_SCAN_STATE_CHANGED_EVT, /**< BLE scan state change. Event data: #mico_bt_ble_scan_type_t */ + BTM_BLE_ADVERT_STATE_CHANGED_EVT, /**< BLE advertisement state change. Event data: #mico_bt_ble_advert_mode_t */ + + /* BLE Secure Connection events */ + BTM_SMP_REMOTE_OOB_DATA_REQUEST_EVT, /**< SMP remote oob data request. Reply using mico_bt_smp_oob_data_reply. Event data: mico_bt_smp_remote_oob_req_t */ + BTM_SMP_SC_REMOTE_OOB_DATA_REQUEST_EVT, /**< LE secure connection remote oob data request. Reply using mico_bt_smp_sc_oob_reply. Event data: #mico_bt_smp_sc_remote_oob_req_t */ + BTM_SMP_SC_LOCAL_OOB_DATA_NOTIFICATION_EVT, /**< LE secure connection local OOB data (mico_bt_smp_create_local_sc_oob_data). Event data: #mico_bt_smp_sc_local_oob_t*/ + + BTM_SCO_CONNECTED_EVT, /**< SCO connected event. Event data: #mico_bt_sco_connected_t */ + BTM_SCO_DISCONNECTED_EVT, /**< SCO disconnected event. Event data: #mico_bt_sco_disconnected_t */ + BTM_SCO_CONNECTION_REQUEST_EVT, /**< SCO connection request event. Event data: #mico_bt_sco_connection_request_t */ + BTM_SCO_CONNECTION_CHANGE_EVT /**< SCO connection change event. Event data: #mico_bt_sco_connection_change_t */ +}; +#endif +typedef uint8_t mico_bt_management_evt_t; /**< Bluetooth management events (see #mico_bt_management_evt_e) */ + +/** Device enabled (used by BTM_ENABLED_EVT) */ +typedef struct { + mico_bt_result_t status; /**< Status */ +} mico_bt_dev_enabled_t; + +/** Remote device information (used by BTM_PIN_REQUEST_EVT, BTM_SECURITY_ABORTED_EVT) */ +typedef struct { + mico_bt_device_address_t *bd_addr; /**< BD Address of remote */ + mico_bt_dev_class_t *dev_class; /**< peer class of device */ + uint8_t *bd_name; /**< BD Name of remote */ +} mico_bt_dev_name_and_class_t; + +/** Change in power management status (used by BTM_POWER_MANAGEMENT_STATUS_EVT notication) */ +typedef struct { + mico_bt_device_address_t bd_addr; /**< BD Address of remote */ + mico_bt_dev_power_mgmt_status_t status; /**< PM status */ + uint16_t value; /**< Additional mode data */ + uint8_t hci_status; /**< HCI status */ +} mico_bt_power_mgmt_notification_t; + +/** Encryption status change (used by BTM_ENCRYPTION_STATUS_EVT) */ +typedef struct { + uint8_t *bd_addr; /**< BD Address of remote */ + mico_bt_transport_t transport; /**< BT_TRANSPORT_BR_EDR or BT_TRANSPORT_LE */ + void *p_ref_data; /**< Optional data passed in by mico_bt_dev_set_encryption */ + mico_bt_result_t result; /**< Result of the operation */ +} mico_bt_dev_encryption_status_t; + +/** Local OOB data BTM_READ_LOCAL_OOB_DATA_COMPLETE_EVT */ +typedef struct { + mico_bt_result_t status; /**< Status */ + mico_bool_t is_extended_oob_data; /**< TRUE if extended OOB data */ + + BT_OCTET16 c_192; /**< Simple Pairing Hash C derived from the P-192 public key */ + BT_OCTET16 + r_192; /**< Simple Pairing Randomnizer R associated with the P-192 public key */ + BT_OCTET16 + c_256; /**< Simple Pairing Hash C derived from the P-256 public key (valid only if is_extended_oob_data=TRUE) */ + BT_OCTET16 + r_256; /**< Simple Pairing Randomnizer R associated with the P-256 public key (valid only if is_extended_oob_data=TRUE) */ +} mico_bt_dev_local_oob_t; + +/** BTM_REMOTE_OOB_DATA_REQUEST_EVT */ +typedef struct { + mico_bt_device_address_t bd_addr; /**< BD Address of remote */ + mico_bool_t extended_oob_data; /**< TRUE if requesting extended OOB (P-256) */ +} mico_bt_dev_remote_oob_t; + +/** BR/EDR Pairing IO Capabilities (to be filled by application callback on BTM_PAIRING_IO_CAPABILITIES_REQUEST_EVT) */ +typedef struct { + mico_bt_device_address_t bd_addr; /**< [in] BD Address of remote */ + mico_bt_dev_io_cap_t local_io_cap; /**< local IO capabilities (to be filled by application callback) */ + mico_bt_dev_oob_data_t oob_data; /**< OOB data present at peer device for the local device */ + mico_bt_dev_auth_req_t auth_req; /**< Authentication required for peer device */ + mico_bool_t is_orig; /**< TRUE, if local device initiated the pairing process */ +} mico_bt_dev_bredr_io_caps_req_t; + +/** BLE Pairing IO Capabilities (to be filled by application callback on BTM_PAIRING_IO_CAPABILITIES_REQUEST_EVT) */ +typedef struct { + mico_bt_device_address_t bd_addr; /**< [in] BD Address of remote */ + mico_bt_dev_io_cap_t local_io_cap; /**< local IO capabilities (to be filled by application callback) */ + uint8_t + oob_data; /**< OOB data present (locally) for the peer device */ + mico_bt_dev_le_auth_req_t + auth_req; /**< Authentication request (for local device) contain bonding and MITM info */ + uint8_t + max_key_size; /**< Max encryption key size */ + mico_bt_dev_le_key_type_t + init_keys; /**< Keys to be distributed, bit mask */ + mico_bt_dev_le_key_type_t + resp_keys; /**< keys to be distributed, bit mask */ +} mico_bt_dev_ble_io_caps_req_t; + + +typedef struct { + BT_OCTET16 irk; /**< peer diverified identity root */ +#if SMP_INCLUDED == TRUE && SMP_LE_SC_INCLUDED == TRUE + BT_OCTET16 pltk; /**< peer long term key */ + BT_OCTET16 pcsrk; /**< peer SRK peer device used to secured sign local data */ + + BT_OCTET16 lltk; /**< local long term key */ + BT_OCTET16 lcsrk; /**< local SRK peer device used to secured sign local data */ +#else + BT_OCTET16 ltk; /**< peer long term key */ + BT_OCTET16 csrk; /**< peer SRK peer device used to secured sign local data */ +#endif + + BT_OCTET8 rand; /**< random vector for LTK generation */ + UINT16 ediv; /**< LTK diversifier of this slave device */ + UINT16 div; /**< local DIV to generate local LTK=d1(ER,DIV,0) and CSRK=d1(ER,DIV,1) */ + uint8_t sec_level; /**< local pairing security level */ + uint8_t key_size; /**< key size of the LTK delivered to peer device */ + uint8_t srk_sec_level; /**< security property of peer SRK for this device */ + uint8_t local_csrk_sec_level; /**< security property of local CSRK for this device */ + + UINT32 counter; /**< peer sign counter for verifying rcv signed cmd */ + UINT32 local_counter; /**< local sign counter for sending signed write cmd*/ +} mico_bt_ble_keys_t; + + +typedef struct { + /* BR/EDR key */ + uint8_t br_edr_key_type; /**< BR/EDR Link Key type */ + mico_bt_link_key_t br_edr_key; /**< BR/EDR Link Key */ + + /* LE Keys */ + mico_bt_dev_le_key_type_t le_keys_available_mask; /**< Mask of available BLE keys */ + mico_bt_ble_address_type_t ble_addr_type; /**< LE device type: public or random address */ + mico_bt_ble_address_type_t static_addr_type; /**< static address type */ + mico_bt_device_address_t static_addr; /**< static address */ + mico_bt_ble_keys_t le_keys; /**< LE keys */ +} mico_bt_device_sec_keys_t; + +/** Paired device link key notification (used by BTM_PAIRED_DEVICE_LINK_KEYS_UPDATE_EVT notication) */ +typedef struct { + mico_bt_device_address_t bd_addr; /**< [in] BD Address of remote */ + mico_bt_device_sec_keys_t key_data; /**< [in/out] Key data */ +} mico_bt_device_link_keys_t; + +/** advertisement type (used when calling mico_bt_start_advertisements) */ +#ifndef BTM_BLE_ADVERT_MODE +#define BTM_BLE_ADVERT_MODE +enum mico_bt_ble_advert_mode_e { + BTM_BLE_ADVERT_OFF, /**< Stop advertising */ + BTM_BLE_ADVERT_DIRECTED_HIGH, /**< Directed advertisement (high duty cycle) */ + BTM_BLE_ADVERT_DIRECTED_LOW, /**< Directed advertisement (low duty cycle) */ + BTM_BLE_ADVERT_UNDIRECTED_HIGH, /**< Undirected advertisement (high duty cycle) */ + BTM_BLE_ADVERT_UNDIRECTED_LOW, /**< Undirected advertisement (low duty cycle) */ + BTM_BLE_ADVERT_NONCONN_HIGH, /**< Non-connectable advertisement (high duty cycle) */ + BTM_BLE_ADVERT_NONCONN_LOW, /**< Non-connectable advertisement (low duty cycle) */ + BTM_BLE_ADVERT_DISCOVERABLE_HIGH, /**< discoverable advertisement (high duty cycle) */ + BTM_BLE_ADVERT_DISCOVERABLE_LOW /**< discoverable advertisement (low duty cycle) */ +}; +#endif +typedef uint8_t mico_bt_ble_advert_mode_t; /**< Advertisement type (see #mico_bt_ble_advert_mode_e) */ + +/** scan mode used in initiating */ +#ifndef BTM_BLE_CONN_MODE +#define BTM_BLE_CONN_MODE +enum mico_bt_ble_conn_mode_e { + BLE_CONN_MODE_OFF, /**< Stop initiating */ + BLE_CONN_MODE_LOW_DUTY, /**< slow connection scan parameter */ + BLE_CONN_MODE_HIGH_DUTY /**< fast connection scan parameter */ +}; +#endif +typedef uint8_t mico_bt_ble_conn_mode_t; /**< Conn mode (see #mico_bt_ble_conn_mode_e) */ + +/** Structure definitions for Bluetooth Management (mico_bt_management_cback_t) event notifications */ +typedef union { + /* Bluetooth status event data types*/ + mico_bt_dev_enabled_t enabled; /**< Data for BTM_ENABLED_EVT */ + mico_bt_power_mgmt_notification_t power_mgmt_notification; /**< Data for BTM_POWER_MANAGEMENT_STATUS_EVT */ + + /* Security event data types */ + mico_bt_dev_name_and_class_t pin_request; /**< Data for BTM_PIN_REQUEST_EVT */ + mico_bt_dev_user_cfm_req_t + user_confirmation_request; /**< Data for BTM_USER_CONFIRMATION_REQUEST_EVT */ + mico_bt_dev_user_key_notif_t + user_passkey_notification; /**< Data for BTM_USER_PASSKEY_NOTIFICATION_EVT */ + mico_bt_dev_user_key_req_t user_passkey_request; /**< Data for BTM_USER_PASSKEY_REQUEST_EVT */ + mico_bt_dev_user_keypress_t + user_keypress_notification; /**< Data for BTM_USER_KEYPRESS_NOTIFICATION_EVT - See #mico_bt_dev_user_keypress_t */ + mico_bt_dev_bredr_io_caps_req_t + pairing_io_capabilities_br_edr_request; /**< Data for BTM_PAIRING_IO_CAPABILITIES_BR_EDR_REQUEST_EVT */ + mico_bt_dev_bredr_io_caps_rsp_t + pairing_io_capabilities_br_edr_response;/**< Data for BTM_PAIRING_IO_CAPABILITIES_BR_EDR_RESPONSE_EVT */ + mico_bt_dev_ble_io_caps_req_t + pairing_io_capabilities_ble_request; /**< Data for BTM_PAIRING_IO_CAPABILITIES_BLE_REQUEST_EVT */ + mico_bt_dev_pairing_cplt_t pairing_complete; /**< Data for BTM_PAIRING_COMPLETE_EVT */ + mico_bt_dev_encryption_status_t encryption_status; /**< Data for BTM_ENCRYPTION_STATUS_EVT */ + mico_bt_dev_security_request_t security_request; /**< Data for BTM_SECURITY_REQUEST_EVT */ + mico_bt_dev_security_upgrade_t + security_upgrade; /**< Data for BTM_SECURITY_UPGRADE_EVT See #mico_bt_dev_security_upgrade_t */ + mico_bt_dev_name_and_class_t security_aborted; /**< Data for BTM_SECURITY_ABORTED_EVT */ + + mico_bt_dev_local_oob_t + read_local_oob_data_complete; /**< Data for BTM_READ_LOCAL_OOB_DATA_COMPLETE_EVT */ + mico_bt_dev_remote_oob_t remote_oob_data_request; /**< Data for BTM_REMOTE_OOB_DATA_REQUEST_EVT */ + + mico_bt_device_link_keys_t + paired_device_link_keys_update; /**< Data for BTM_PAIRED_DEVICE_LINK_KEYS_UPDATE_EVT */ + mico_bt_device_link_keys_t + paired_device_link_keys_request; /**< Data for BTM_PAIRED_DEVICE_LINK_KEYS_REQUEST_EVT */ + mico_bt_local_identity_keys_t + local_identity_keys_update; /**< Data for BTM_LOCAL_IDENTITY_KEYS_UPDATE_EVT */ + mico_bt_local_identity_keys_t + local_identity_keys_request; /**< Data for BTM_LOCAL_IDENTITY_KEYS_REQUEST_EVT */ + + mico_bt_ble_scan_type_t ble_scan_state_changed; /**< Data for BTM_BLE_SCAN_STATE_CHANGED_EVT */ + mico_bt_ble_advert_mode_t ble_advert_state_changed; /**< Data for BTM_BLE_ADVERT_STATE_CHANGED_EVT */ + + mico_bt_smp_remote_oob_req_t + smp_remote_oob_data_request; /**< Data for BTM_SMP_REMOTE_OOB_DATA_REQUEST_EVT */ + mico_bt_smp_sc_remote_oob_req_t + smp_sc_remote_oob_data_request; /**< Data for BTM_SMP_SC_REMOTE_OOB_DATA_REQUEST_EVT */ + mico_bt_smp_sc_local_oob_t + *p_smp_sc_local_oob_data; /**< Data for BTM_SMP_SC_LOCAL_OOB_DATA_NOTIFICATION_EVT */ + + mico_bt_sco_connected_t sco_connected; /**< Data for BTM_SCO_CONNECTED_EVT */ + mico_bt_sco_disconnected_t sco_disconnected; /**< Data for BTM_SCO_DISCONNECTED_EVT */ + mico_bt_sco_connection_request_t sco_connection_request; /**< Data for BTM_SCO_CONNECTION_REQUEST_EVT */ + mico_bt_sco_connection_change_t sco_connection_change; /**< Data for BTM_SCO_CONNECTION_CHANGE_EVT */ + +} mico_bt_management_evt_data_t; + +/** + * Bluetooth Management callback + * + * Callback for Bluetooth Management event notifications. + * Registered using mico_bt_stack_init() + * + * @param event : Event ID + * @param p_event_data : Event data + * + * @return Status of event handling + */ +typedef mico_bt_result_t (mico_bt_management_cback_t) (mico_bt_management_evt_t event, + mico_bt_management_evt_data_t *p_event_data); + +/** + * Connection status change callback + * + * Callback for Bluetooth Management event notifications. + * Registered using mico_bt_register_connection_status_change() + * + * @param[in] bd_addr : BD Address of remote + * @param[in] p_features + * @param[in] is_connected : TRUE if connected + * @param[in] handle : Connection handle + * @param[in] transport : BT_TRANSPORT_BR_EDR or BT_TRANSPORT_LE + * + * @return void + */ +typedef void (mico_bt_connection_status_change_cback_t) (mico_bt_device_address_t bd_addr, uint8_t *p_features, + mico_bool_t is_connected, uint16_t handle, mico_bt_transport_t transport); /**< connection status change callback */ + + +/** + * Inquiry result callback. + * + * @param p_inquiry_result : Inquiry result data (NULL if inquiry is complete) + * @param p_eir_data : Extended inquiry response data + * + * @return Nothing + */ +typedef void (mico_bt_inquiry_result_cback_t) (mico_bt_dev_inquiry_scan_result_t *p_inquiry_result, + uint8_t *p_eir_data); /**< inquiry result callback */ + +/** + * Synchronous BTM operation is complete. + * + * @param p_data : Operation dependent data + * + * @return Nothing + */ +typedef void (mico_bt_dev_cmpl_cback_t) (void *p_data); + +/** + * Vendor specific command complete + * + * @param p_command_complete_params : Command complete parameters + * + * @return Nothing + */ +typedef void (mico_bt_dev_vendor_specific_command_complete_cback_t) ( + mico_bt_dev_vendor_specific_command_complete_params_t *p_command_complete_params); + +/****************************************************** + * Function Declarations + ******************************************************/ +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************************************/ +/** + * Device Management Functions + * + * @addtogroup micobt_DeviceManagement Device Management + * @ingroup micobt + * + * @{ + */ +/****************************************************************************/ + + +/****************************************************************************/ +/** + * Bluetooth Basic Rate / Enhanced Data Rate Functions + * + * @addtogroup micobt_bredr BR/EDR (Bluetooth Basic Rate / Enhanced Data Rate) + * @ingroup micobt_DeviceManagement + * + * @{ + */ +/****************************************************************************/ + +/** + * Function mico_bt_start_inquiry + * + * Begin BR/EDR inquiry for peer devices. + * + * @param[in] p_inqparms : inquiry parameters + * @param[in] p_inquiry_result_cback : inquiry results callback + * + * @return mico_bt_result_t + * + * MICO_BT_PENDING if successfully initiated + * MICO_BT_BUSY if already in progress + * MICO_BT_ILLEGAL_VALUE if parameter(s) are out of range + * MICO_BT_NO_RESOURCES if could not allocate resources to start the command + * MICO_BT_WRONG_MODE if the device is not up. + */ +mico_bt_result_t mico_bt_start_inquiry (mico_bt_dev_inq_parms_t *p_inqparms, + mico_bt_inquiry_result_cback_t *p_inquiry_result_cback); + +/** + * Function mico_bt_cancel_inquiry + * + * Cancel inquiry + * + * @return + * + * MICO_BT_SUCCESS if successful + * MICO_BT_NO_RESOURCES if could not allocate a message buffer + * MICO_BT_WRONG_MODE if the device is not up. + */ +mico_bt_result_t mico_bt_cancel_inquiry(void); + +/** + * Function mico_bt_dev_read_local_addr + * + * Read the local device address + * + * @param[out] bd_addr : Local bd address + * + * @return void + * + */ +void mico_bt_dev_read_local_addr (mico_bt_device_address_t bd_addr); + + +/** + * Function mico_bt_dev_set_advanced_connection_params + * + * Set advanced connection parameters for subsequent BR/EDR connections + * (remote clock offset, page scan mode, and other information obtained during inquiry) + * + * If not called, then default connection parameters will be used. + * + * @param[in] p_inquiry_scan_result : Inquiry scan result (from #mico_bt_inquiry_result_cback_t) + * + * @return mico_bt_result_t + * + * MICO_BT_SUCCESS : on success; + * MICO_BT_FAILED : if an error occurred + */ +mico_bt_result_t mico_bt_dev_set_advanced_connection_params (mico_bt_dev_inquiry_scan_result_t *p_inquiry_scan_result); + + +/** + * Function mico_bt_dev_set_local_device_address + * + * + * Set local Bluetooth Device Address. + * + * @param[in] bdaddr : Bluetooth Device Address + * @param[in] p_cback : Callback for command complete + * + * @return + * + * MICO_BT_SUCCESS : Command sent. Does not expect command complete event. (command complete callback param is NULL) + * MICO_BT_NO_RESOURCES: Failure and no resources. + * + */ +mico_bt_result_t mico_bt_dev_set_local_device_address(mico_bt_device_address_t bdaddr, + mico_bt_dev_cmpl_cback_t *p_cback); + +/** + * Function mico_bt_dev_vendor_specific_command + * + * Send a vendor specific HCI command to the controller. + * + * @param[in] opcode : Opcode of vendor specific command + * @param[in] param_len : Length of parameter buffer + * @param[in] p_param_buf : Parameters + * @param[in] p_cback : Callback for command complete + * + * @return + * + * MICO_BT_SUCCESS : Command sent. Does not expect command complete event. (command complete callback param is NULL) + * MICO_BT_PENDING : Command sent. Waiting for command complete event. + * MICO_BT_BUSY : Command not sent. Waiting for command complete event for prior command. + * + */ +mico_bt_result_t mico_bt_dev_vendor_specific_command (uint16_t opcode, uint8_t param_len, uint8_t *p_param_buf, + mico_bt_dev_vendor_specific_command_complete_cback_t *p_cback); + +/** + * Function mico_bt_dev_set_discoverability + * + * Set discoverability + * + * @note The duration must be less than or equal to the interval. + * + * @param[in] inq_mode : Discoverability mode (see #mico_bt_discoverability_mode_e) + * @param[in] duration : Duration (in 0.625 msec intervals). BTM_DEFAULT_DISC_WINDOW, or range: 0x0012 ~ 0x1000 (11.25 ~ 2560 msecs) + * @param[in] interval : Interval (in 0.625 msec intervals). BTM_DEFAULT_DISC_INTERVAL, or range: 0x0012 ~ 0x1000 (11.25 ~ 2560 msecs) + * + * @return + * + * MICO_BT_SUCCESS: If successful + * MICO_BT_BUSY: If a setting of the filter is already in progress + * MICO_BT_NO_RESOURCES: If couldn't get a memory pool buffer + * MICO_BT_ILLEGAL_VALUE: If a bad parameter was detected + * MICO_BT_WRONG_MODE: If the device is not up + */ +mico_bt_result_t mico_bt_dev_set_discoverability (uint8_t inq_mode, uint16_t duration, + uint16_t interval); + +/** + * Function mico_bt_dev_set_connectability + * + * Set connectablilty + * + * @note The duration (window parameter) must be less than or equal to the interval. + * + * @param[in] page_mode : Connectability mode (see #mico_bt_connectability_mode_e) + * @param[in] window : Duration (in 0.625 msec intervals). BTM_DEFAULT_CONN_WINDOW, or range: 0x0012 ~ 0x1000 (11.25 ~ 2560 msecs) + * @param[in] interval : Interval (in 0.625 msec intervals). BTM_DEFAULT_CONN_INTERVAL, or range: 0x0012 ~ 0x1000 (11.25 ~ 2560 msecs) + * + * @return + * + * MICO_BT_SUCCESS: If successful + * MICO_BT_ILLEGAL_VALUE: If a bad parameter is detected + * MICO_BT_NO_RESOURCES: If could not allocate a message buffer + * MICO_BT_WRONG_MODE: If the device is not up + */ +mico_bt_result_t mico_bt_dev_set_connectability (uint8_t page_mode, uint16_t window, + uint16_t interval); +/** + * Function mico_bt_dev_register_connection_status_change + * + * Register callback for connection status change + * + * + * @param[in] p_mico_bt_connection_status_change_cback - Callback for connection status change + * + * @return mico_bt_result_t + * + * MICO_BT_SUCCESS : on success; + * MICO_BT_FAILED : if an error occurred + */ +mico_bt_result_t mico_bt_dev_register_connection_status_change(mico_bt_connection_status_change_cback_t + *p_mico_bt_connection_status_change_cback); + +/** + * Function mico_bt_dev_set_sniff_mode + * + * Set a connection into sniff mode. + * + * @param[in] remote_bda : Link for which to put into sniff mode + * @param[in] min_period : Minimum sniff period + * @param[in] max_period : Maximum sniff period + * @param[in] attempt : Number of attempts for switching to sniff mode + * @param[in] timeout : Timeout for attempting to switch to sniff mode + * + * @return MICO_BT_PENDING if successfully initiated, otherwise error + */ +mico_bt_result_t mico_bt_dev_set_sniff_mode (mico_bt_device_address_t remote_bda, uint16_t min_period, + uint16_t max_period, uint16_t attempt, + uint16_t timeout); + + +/** + * Function mico_bt_dev_cancel_sniff_mode + * + * Take a connection out of sniff mode. + * A check is made if the connection is already in sniff mode, + * and if not, the cancel sniff mode is ignored. + * + * @return MICO_BT_PENDING if successfully initiated, otherwise error + * + */ +mico_bt_result_t mico_bt_dev_cancel_sniff_mode (mico_bt_device_address_t remote_bda); + + +/** + * + * Function mico_bt_dev_set_sniff_subrating + * + * Set sniff subrating parameters for an active connection + * + * @param[in] remote_bda : device address of desired ACL connection + * @param[in] max_latency : maximum latency (in 0.625ms units) (range: 0x0002-0xFFFE) + * @param[in] min_remote_timeout : minimum remote timeout + * @param[in] min_local_timeout : minimum local timeout + * + * @return + * + * MICO_BT_SUCCESS : on success; + * MICO_BT_ILLEGAL_ACTION : if an error occurred + */ +mico_bt_result_t mico_bt_dev_set_sniff_subrating (mico_bt_device_address_t remote_bda, uint16_t max_latency, + uint16_t min_remote_timeout, uint16_t min_local_timeout); + +/** + * Function mico_bt_dev_read_rssi + * + * Get Receive Signal Strenth Index (RSSI) for the requested link + * + * @param[in] remote_bda : BD address of connection to read rssi + * @param[in] transport : Transport type + * @param[in] p_cback : Result callback (mico_bt_dev_rssi_result_t will be passed to the callback) + * + * @return + * + * MICO_BT_PENDING if command issued to controller. + * MICO_BT_NO_RESOURCES if couldn't allocate memory to issue command + * MICO_BT_UNKNOWN_ADDR if no active link with bd addr specified + * MICO_BT_BUSY if command is already in progress + * + */ +mico_bt_result_t mico_bt_dev_read_rssi (mico_bt_device_address_t remote_bda, mico_bt_transport_t transport, + mico_bt_dev_cmpl_cback_t *p_cback); + +/** + * Function mico_bt_dev_read_tx_power + * + * Read the transmit power for the requested link + * + * @param[in] remote_bda : BD address of connection to read tx power + * @param[in] transport : Transport type + * @param[in] p_cback : Result callback (mico_bt_tx_power_result_t will be passed to the callback) + * + * @return + * + * MICO_BT_PENDING if command issued to controller. + * MICO_BT_NO_RESOURCES if couldn't allocate memory to issue command + * MICO_BT_UNKNOWN_ADDR if no active link with bd addr specified + * MICO_BT_BUSY if command is already in progress + * + */ +mico_bt_result_t mico_bt_dev_read_tx_power (mico_bt_device_address_t remote_bda, mico_bt_transport_t transport, + mico_bt_dev_cmpl_cback_t *p_cback); + + +/** + * + * Function mico_bt_dev_write_eir + * + * Write EIR data to controller. + * + * @param[in] p_buff : EIR data + * @param[in] len : Length of EIR data + * + * @return MICO_BT_SUCCESS if successful + * MICO_BT_NO_RESOURCES if couldn't allocate memory to issue command + * MICO_BT_UNSUPPORTED if local device cannot support request + * + */ +mico_bt_result_t mico_bt_dev_write_eir (uint8_t *p_buff, uint16_t len); + +/**@} micobt_bredr */ + +/***************************************************************************** + * SECURITY MANAGEMENT FUNCTIONS + ****************************************************************************/ +/****************************************************************************/ +/** + * Bluetooth Security Functions + * + * @addtogroup btm_sec_api_functions Security + * @ingroup micobt_DeviceManagement + * + * @{ + */ + + +/** + * Function mico_bt_dev_set_pin_code_only + * + * Set the latency pairing mode. + * + * @param[in] enable : Pin Code Only Mode is enable or not. + * + * @return mico_bt_result_t + */ +mico_bt_result_t mico_bt_dev_set_pin_code_only(mico_bool_t enable); + +/** + * Function mico_bt_dev_set_security_mode + * + * Set PIN type for the device. + * + * @param[in] fixed_pin : fixed pin if TRUE or variable pin. + * @param[in] pin_code : this arguement must be set if pin type is fixed. + * @param[in] pin_code_len: length of pin code. + * + */ +void mico_bt_dev_set_pin_type(mico_bool_t fixed_pin, uint8_t *pin_code, uint8_t pin_code_len); + + +/** + * Function mico_bt_dev_pin_code_reply + * + * PIN code reply (use in response to BTM_PIN_REQUEST_EVT in #mico_bt_management_cback_t) + * + * @param[in] bd_addr : Address of the device for which PIN was requested + * @param[in] res : result of the operation MICO_BT_SUCCESS if success + * @param[in] pin_len : length in bytes of the PIN Code + * @param[in] p_pin : pointer to array with the PIN Code + * + * @return void + */ +void mico_bt_dev_pin_code_reply (mico_bt_device_address_t bd_addr, mico_bt_result_t res, uint8_t pin_len, + uint8_t *p_pin); + +/** + * Function mico_bt_dev_sec_bond + * + * Bond with peer device. If the connection is already up, but not secure, pairing is attempted. + * + * @note PIN parameters are only needed when bonding with legacy devices (pre-2.1 Core Spec) + * + * @param[in] bd_addr : Peer device bd address to pair with. + * @param[in] bd_addr_type : BLE_ADDR_PUBLIC or BLE_ADDR_RANDOM (applies to LE devices only) + * @param[in] transport : BT_TRANSPORT_BR_EDR or BT_TRANSPORT_LE + * @param[in] pin_len : Length of input parameter p_pin (0 if not used). + * @param[in] p_pin : Pointer to Pin Code to use (NULL if not used). + * + * @return + * + * MICO_BT_PENDING if successfully initiated, + * MICO_BT_SUCCESS if already paired to the device, else + * error code + */ +mico_bt_result_t mico_bt_dev_sec_bond (mico_bt_device_address_t bd_addr, mico_bt_ble_address_type_t bd_addr_type, + mico_bt_transport_t transport, uint8_t pin_len, uint8_t *p_pin); + + +/** + * Function mico_bt_dev_sec_bond_cancel + * + * Cancel an ongoing bonding process with peer device. + * + * @param[in] bd_addr : Peer device bd address to pair with. + * + * @return + * + * MICO_BT_PENDING if cancel initiated, + * MICO_BT_SUCCESS if cancel has completed already, else error code. + */ +mico_bt_result_t mico_bt_dev_sec_bond_cancel (mico_bt_device_address_t bd_addr); + + +/** + * Function mico_bt_dev_set_encryption + * + * Encrypt the specified connection. + * Status is notified using BTM_ENCRYPTION_STATUS_EVT of #mico_bt_management_cback_t. + * + * @param[in] bd_addr : Address of peer device + * @param[in] transport : BT_TRANSPORT_BR_EDR or BT_TRANSPORT_LE + * @param[in] p_ref_data : pointer to reference data to be passed upon completion (NULL if no data) + * + * @return + * + * MICO_BT_SUCCESS : already encrypted + * MICO_BT_PENDING : command will be returned in the callback + * MICO_BT_WRONG_MODE : connection not up. + * MICO_BT_BUSY : security procedures are currently active + */ +mico_bt_result_t mico_bt_dev_set_encryption (mico_bt_device_address_t bd_addr, mico_bt_transport_t transport, + void *p_ref_data); + + +/** + * Function mico_bt_dev_confirm_req_reply + * + * Confirm the numeric value for pairing (in response to BTM_USER_CONFIRMATION_REQUEST_EVT of #mico_bt_management_cback_t) + * + * @param[in] res : result of the operation MICO_BT_SUCCESS if success + * @param[in] bd_addr : Address of the peer device + * + * @return void + */ +void mico_bt_dev_confirm_req_reply(mico_bt_result_t res, mico_bt_device_address_t bd_addr); + +/** + * Function mico_bt_dev_pass_key_req_reply + * + * Provide the pairing passkey (in response to BTM_PASSKEY_REQUEST_EVT of #mico_bt_management_cback_t) + * + * @param[in] res : result of the operation MICO_BT_SUCCESS if success + * @param[in] bd_addr : Address of the peer device + * @param[in] passkey : numeric value in the range of 0 - 999999(0xF423F). + * + * @return void + */ +void mico_bt_dev_pass_key_req_reply(mico_bt_result_t res, mico_bt_device_address_t bd_addr, uint32_t passkey); + +/** + * Function mico_bt_dev_send_key_press_notif + * + * Inform remote device of keypress during pairing. + * + * Used during the passkey entry by a device with KeyboardOnly IO capabilities + * (typically a HID keyboard device). + * + * @param[in] bd_addr : Address of the peer device + * @param[in] type : notification type + * + */ +void mico_bt_dev_send_key_press_notif(mico_bt_device_address_t bd_addr, mico_bt_dev_passkey_entry_type_t type); + +/** + * + * Function mico_bt_dev_read_local_oob_data + * + * Read the local OOB data from controller (for sending + * to peer device over oob message). When + * operation is completed, local OOB data will be + * provided via BTM_READ_LOCAL_OOB_DATA_COMPLETE_EVT. + * + */ +mico_bt_result_t mico_bt_dev_read_local_oob_data(void); + +/** + * Function mico_bt_dev_remote_oob_data_reply + * + * Provide the remote OOB extended data for Simple Pairing + * in response to BTM_REMOTE_OOB_DATA_REQUEST_EVT + * + * @param[in] bd_addr : Address of the peer device + * @param[in] is_extended_oob_data : TRUE if extended OOB data (set according to BTM_REMOTE_OOB_DATA_REQUEST_EVT request) + * @param[in] c_192 : simple pairing Hash C derived from the P-192 public key. + * @param[in] r_192 : simple pairing Randomizer R associated with the P-192 public key. + * @param[in] c_256 : simple pairing Hash C derived from the P-256 public key (if is_extended_oob_data=TRUE) + * @param[in] r_256 : simple pairing Randomizer R associated with the P-256 public key (if is_extended_oob_data=TRUE) + * + */ +void mico_bt_dev_remote_oob_data_reply (mico_bt_result_t res, mico_bt_device_address_t bd_addr, + mico_bool_t is_extended_oob_data, + BT_OCTET16 c_192, BT_OCTET16 r_192, + BT_OCTET16 c_256, BT_OCTET16 r_256); + +/* + * + * Function mico_bt_dev_build_oob_data + * + * Build the OOB data block to be used to send OOB extended + * data over OOB (non-Bluetooth) link. + * + * @param[out] p_data : OOB data block location + * @param[in] max_len : OOB data block size + * @param[in] is_extended_oob_data : TRUE if extended OOB data (for Secure Connections) + * @param[in] c_192 : simple pairing Hash C derived from the P-192 public key. + * @param[in] r_192 : simple pairing Randomizer R associated with the P-192 public key. + * @param[in] c_256 : simple pairing Hash C derived from the P-256 public key (if is_extended_oob_data=TRUE) + * @param[in] r_256 : simple pairing Randomizer R associated with the P-256 public key (if is_extended_oob_data=TRUE) + * + * @return Number of bytes put into OOB data block. + * + */ +uint16_t mico_bt_dev_build_oob_data(uint8_t *p_data, uint16_t max_len, + mico_bool_t is_extended_oob_data, + BT_OCTET16 c_192, BT_OCTET16 r_192, + BT_OCTET16 c_256, BT_OCTET16 r_256); + +/* + * + * Function mico_bt_smp_oob_data_reply + * + * This function is called to provide the OOB data for + * SMP in response to BTM_SMP_REMOTE_OOB_DATA_REQUEST_EVT + * + * @param[in] bd_addr - Address of the peer device + * @param[in] res - result of the operation MICO_BT_SUCCESS if success + * @param[in] len - oob data length + * @param[in] p_data - oob data + * + */ +void mico_bt_smp_oob_data_reply(mico_bt_device_address_t bd_addr, mico_bt_result_t res, uint8_t len, uint8_t *p_data); + +/** + * Function mico_bt_smp_create_local_sc_oob_data + * + * Create local BLE SC (secure connection) OOB data. When + * operation is completed, local OOB data will be + * provided via BTM_SMP_SC_LOCAL_OOB_DATA_NOTIFICATION_EVT. + * + * @param[in] bd_addr : intended remote address for the OOB data + * @param[in] bd_addr_type : BLE_ADDR_PUBLIC or BLE_ADDR_PUBLIC + * + * @return TRUE: creation of local SC OOB data set started. + * + */ +mico_bool_t mico_bt_smp_create_local_sc_oob_data (mico_bt_device_address_t bd_addr, + mico_bt_ble_address_type_t bd_addr_type); + +/** + * + * Function mico_bt_smp_sc_oob_reply + * + * Description Provide the SC OOB data for SMP in response to + * BTM_SMP_SC_REMOTE_OOB_DATA_REQUEST_EVT + * + * @param[in] p_oob_data : oob data + * + */ +void mico_bt_smp_sc_oob_reply (uint8_t *p_oob_data); + +/**@} btm_sec_api_functions */ + + +/**@} micobt_DeviceManagement */ + + +/** HCI trace types */ +typedef enum { + HCI_TRACE_EVENT, /**< HCI event data from controller to the host */ + HCI_TRACE_COMMAND, /**< HCI command data from host to controller */ + HCI_TRACE_INCOMING_ACL_DATA,/**< HCI incoming acl data */ + HCI_TRACE_OUTGOING_ACL_DATA/**< HCI outgoing acl data */ +} mico_bt_hci_trace_type_t; + +/** + * HCI trace callback + * + * Callback for HCI traces + * Registered using mico_bt_dev_register_hci_trace() + * + * @param[in] type : Trace type + * @param[in] length : Length of the trace data + * @param[in] p_data : Pointer to the data + * + * @return void + */ +typedef void ( mico_bt_hci_trace_cback_t )( mico_bt_hci_trace_type_t type, uint16_t length, uint8_t *p_data ); + +/** + * Function mico_bt_dev_register_hci_trace + * + * Register to get the hci traces + * + * @param[in] p_cback : Callback for hci traces + * + * @return void + * + */ +void mico_bt_dev_register_hci_trace( mico_bt_hci_trace_cback_t *p_cback ); + + +/** + * Function mico_bt_dev_get_bonded_devices + * + * get bonded device list + * + * @param[out] p_paired_device_list : array for getting bd address of bonded devices + * @param[in/out] p_num_devices : list size of p_pared_device_list total number of bonded devices stored + * + * @return mico_bt_result_t + * + */ +mico_bt_result_t mico_bt_dev_get_bonded_devices(mico_bt_dev_bonded_device_info_t *p_paired_device_list, + uint16_t *p_num_devices); + +/** + * Function mico_bt_dev_find_bonded_device + * + * check a device is bonded or not + * + * @param[in] bd_addr : Address of the peer device + * + * @return mico_bool_t + * + */ +mico_bool_t mico_bt_dev_find_bonded_device( mico_bt_device_address_t bd_addr); + +/** + * Function mico_bt_dev_get_key_by_keytype + * + * get security key from a bonded device + * + * @param[in] bd_addr : Address of the peer device + * @param[in] key_type : The achieved key type + * @param[out] p_sec_keys : The memory to hold the achieved key value + * + * @return mico_bt_result_t + * + */ +mico_bt_result_t mico_bt_dev_get_key_by_keytype(mico_bt_device_address_t bd_addr, mico_bt_dev_le_key_type_t key_type, + mico_bt_security_key_value_t *p_sec_keys); + + + +/** + * Function mico_bt_dev_delete_bonded_device + * + * remove bonding with remote device with assigned bd_addr + * + * @param[in] bd_addr : bd_addr of remote device to be removed from bonding list + * + * @return mico_bt_result_t + * + */ +mico_bt_result_t mico_bt_dev_delete_bonded_device(mico_bt_device_address_t bd_addr); + + +/** + * Function mico_bt_dev_add_device_to_address_resolution_db + * + * add link key information to internal address resolution db + * + * @param[in] p_link_keys : link keys information stored in application side + * + * @return mico_bt_result_t + * + */ +mico_bt_result_t mico_bt_dev_add_device_to_address_resolution_db(mico_bt_device_link_keys_t *p_link_keys); + + +/** + * Function mico_bt_dev_remove_device_from_address_resolution_db + * + * remove link key information from internal address resolution db + * + * @param[in] p_link_keys : link keys information stored in application side + * + * @return mico_bt_result_t + * + */ +mico_bt_result_t mico_bt_dev_remove_device_from_address_resolution_db(mico_bt_device_link_keys_t *p_link_keys); + + + +#ifdef __cplusplus +} +#endif diff --git a/device/bluetooth/mk3239/include/mico_bt_gatt.h b/device/bluetooth/mk3239/include/mico_bt_gatt.h new file mode 100644 index 0000000000..63b4e5c7ee --- /dev/null +++ b/device/bluetooth/mk3239/include/mico_bt_gatt.h @@ -0,0 +1,973 @@ + +/** @file + * + * MiCO Generic Attribute (GATT) Application Programming Interface + */ + + + + + + +#pragma once + +#include "mico.h" +#include "gattdefs.h" +#include "mico_bt_dev.h" +#include "l2cdefs.h" +#include "mico_bt_types.h" + +/** GATT Status Codes*/ +enum mico_bt_gatt_status_e { + MICO_BT_GATT_SUCCESS = 0x00, /**< Success */ + MICO_BT_GATT_INVALID_HANDLE = 0x01, /**< Invalid Handle */ + MICO_BT_GATT_READ_NOT_PERMIT = 0x02, /**< Read Not Permitted */ + MICO_BT_GATT_WRITE_NOT_PERMIT = 0x03, /**< Write Not permitted */ + MICO_BT_GATT_INVALID_PDU = 0x04, /**< Invalid PDU */ + MICO_BT_GATT_INSUF_AUTHENTICATION = 0x05, /**< Insufficient Authentication */ + MICO_BT_GATT_REQ_NOT_SUPPORTED = 0x06, /**< Request Not Supported */ + MICO_BT_GATT_INVALID_OFFSET = 0x07, /**< Invalid Offset */ + MICO_BT_GATT_INSUF_AUTHORIZATION = 0x08, /**< Insufficient Authorization */ + MICO_BT_GATT_PREPARE_Q_FULL = 0x09, /**< Prepare Queue Full */ + MICO_BT_GATT_NOT_FOUND = 0x0a, /**< Not Found */ + MICO_BT_GATT_NOT_LONG = 0x0b, /**< Not Long Size */ + MICO_BT_GATT_INSUF_KEY_SIZE = 0x0c, /**< Insufficient Key Size */ + MICO_BT_GATT_INVALID_ATTR_LEN = 0x0d, /**< Invalid Attribute Length */ + MICO_BT_GATT_ERR_UNLIKELY = 0x0e, /**< Error Unlikely */ + MICO_BT_GATT_INSUF_ENCRYPTION = 0x0f, /**< Insufficient Encryption */ + MICO_BT_GATT_UNSUPPORT_GRP_TYPE = 0x10, /**< Unsupported Group Type */ + MICO_BT_GATT_INSUF_RESOURCE = 0x11, /**< Insufficient Resource */ + + MICO_BT_GATT_ILLEGAL_PARAMETER = 0x87, /**< Illegal Parameter */ + MICO_BT_GATT_NO_RESOURCES = 0x80, /**< No Resources */ + MICO_BT_GATT_INTERNAL_ERROR = 0x81, /**< Internal Error */ + MICO_BT_GATT_WRONG_STATE = 0x82, /**< Wrong State */ + MICO_BT_GATT_DB_FULL = 0x83, /**< DB Full */ + MICO_BT_GATT_BUSY = 0x84, /**< Busy */ + MICO_BT_GATT_ERROR = 0x85, /**< Error */ + MICO_BT_GATT_CMD_STARTED = 0x86, /**< Command Started */ + MICO_BT_GATT_PENDING = 0x88, /**< Pending */ + MICO_BT_GATT_AUTH_FAIL = 0x89, /**< Authentication Fail */ + MICO_BT_GATT_MORE = 0x8a, /**< More */ + MICO_BT_GATT_INVALID_CFG = 0x8b, /**< Invalid Configuration */ + MICO_BT_GATT_SERVICE_STARTED = 0x8c, /**< Service Started */ + MICO_BT_GATT_ENCRYPED_MITM = MICO_BT_GATT_SUCCESS, /**< Encrypted MITM */ + MICO_BT_GATT_ENCRYPED_NO_MITM = 0x8d, /**< Encrypted No MITM */ + MICO_BT_GATT_NOT_ENCRYPTED = 0x8e, /**< Not Encrypted */ + MICO_BT_GATT_CONGESTED = 0x8f, /**< Congested */ + + /* 0xE0 ~ 0xFC reserved for future use */ + MICO_BT_GATT_CCC_CFG_ERR = 0xFD, /**< Improper Client Char Configuration */ + MICO_BT_GATT_PRC_IN_PROGRESS = 0xFE, /**< Procedure Already in Progress */ + MICO_BT_GATT_OUT_OF_RANGE = 0xFF, /**< Value Out of Range */ +}; +typedef uint8_t mico_bt_gatt_status_t; /**< GATT status (see #mico_bt_gatt_status_e) */ + + +/** GATT Status Codes*/ +enum mico_bt_gatt_app_interface_e { + GATT_IF_FIXED_DB_GAP = 0x01, + GATT_IF_FIXED_DB_APP = 0x02, + GATT_IF_CLIENT = 0x03, +}; +typedef uint8_t mico_bt_gatt_app_interface_t; /**< GATT status (see #mico_bt_gatt_status_e) */ + + +/** GATT Operation Codes */ +#define GATT_RSP_ERROR 0x01 /**< Error Response */ +#define GATT_REQ_MTU 0x02 /**< Exchange MTU Request */ +#define GATT_RSP_MTU 0x03 /**< Exchange MTU Response */ +#define GATT_REQ_FIND_INFO 0x04 /**< Find Information Request */ +#define GATT_RSP_FIND_INFO 0x05 /**< Find Information Response */ +#define GATT_REQ_FIND_TYPE_VALUE 0x06 /**< Find By Type Value Request */ +#define GATT_RSP_FIND_TYPE_VALUE 0x07 /**< Find By Type Value Response */ +#define GATT_REQ_READ_BY_TYPE 0x08 /**< Read By Type Request */ +#define GATT_RSP_READ_BY_TYPE 0x09 /**< Read By Type Response */ +#define GATT_REQ_READ 0x0A /**< Read Request */ +#define GATT_RSP_READ 0x0B /**< Read Response */ +#define GATT_REQ_READ_BLOB 0x0C /**< Read Blob Request */ +#define GATT_RSP_READ_BLOB 0x0D /**< Read Blob Response */ +#define GATT_REQ_READ_MULTI 0x0E /**< Read Multiple Request */ +#define GATT_RSP_READ_MULTI 0x0F /**< Read Multiple Response */ +#define GATT_REQ_READ_BY_GRP_TYPE 0x10 /**< Read By Group Type Request */ +#define GATT_RSP_READ_BY_GRP_TYPE 0x11 /**< Read By Group Type Response */ +#define GATT_REQ_WRITE 0x12 /**< Write Request */ +#define GATT_RSP_WRITE 0x13 /**< Write Request */ +#define GATT_CMD_WRITE 0x52 /**< Write Command */ +#define GATT_REQ_PREPARE_WRITE 0x16 /**< Prepare Write Request */ +#define GATT_RSP_PREPARE_WRITE 0x17 /**< Prepare Write Response */ +#define GATT_REQ_EXEC_WRITE 0x18 /**< Execute Write Request */ +#define GATT_RSP_EXEC_WRITE 0x19 /**< Execute Write Response */ +#define GATT_HANDLE_VALUE_NOTIF 0x1B /**< Handle Value Notification */ +#define GATT_HANDLE_VALUE_IND 0x1D /**< Handle Value Indication */ +#define GATT_HANDLE_VALUE_CONF 0x1E /**< Handle Value Confirmation */ +#define GATT_OP_CODE_MAX (GATT_HANDLE_VALUE_CONF + 1) /**< Maximum opcode value */ +#define GATT_SIGN_CMD_WRITE 0xD2 /**< changed in V4.0 1101-0010 (signed write) see write cmd above*/ + +/** GATT Disconnection reason */ +enum mico_bt_gatt_disconn_reason_e { + GATT_CONN_UNKNOWN = 0, /**< Unknown reason */ + GATT_CONN_L2C_FAILURE = 1, /**< General L2cap failure */ + GATT_CONN_TIMEOUT = HCI_ERR_CONNECTION_TOUT, /**< Connection timeout */ + GATT_CONN_TERMINATE_PEER_USER = HCI_ERR_PEER_USER, /**< Connection terminated by peer user */ + GATT_CONN_TERMINATE_LOCAL_HOST = HCI_ERR_CONN_CAUSE_LOCAL_HOST, /**< Connection terminated by local host */ + GATT_CONN_FAIL_ESTABLISH = HCI_ERR_CONN_FAILED_ESTABLISHMENT, /**< Connection fail to establish */ + GATT_CONN_LMP_TIMEOUT = HCI_ERR_LMP_RESPONSE_TIMEOUT, /**< Connection fail due to LMP response tout */ + GATT_CONN_CANCEL = L2CAP_CONN_CANCEL /**< L2CAP connection cancelled */ +}; +typedef uint16_t +mico_bt_gatt_disconn_reason_t; /**< GATT disconnection reason (see #mico_bt_gatt_disconn_reason_e) */ + +/* default GATT MTU size over LE link +*/ +#define GATT_DEF_BLE_MTU_SIZE 23 + +/* invalid connection ID +*/ +#define GATT_INVALID_CONN_ID 0xFFFF + + +/** characteristic descriptor: client configuration value */ +enum mico_bt_gatt_client_char_config_e { + GATT_CLIENT_CONFIG_NONE = 0x0000, /**< Does not allow both notifications and indications */ + GATT_CLIENT_CONFIG_NOTIFICATION = 0x0001, /**< Allows notifications */ + GATT_CLIENT_CONFIG_INDICATION = 0x0002 /**< Allows indications */ +}; +typedef uint16_t +mico_bt_gatt_client_char_config_t; /**< GATT client config (see #mico_bt_gatt_client_char_config_e) */ + +/** characteristic descriptor: server configuration value */ +#define GATT_SERVER_CONFIG_NONE 0x0000 /**< No broadcast */ +#define GATT_SERVER_CONFIG_BROADCAST 0x0001 /**< Broadcast */ +typedef uint16_t +mico_bt_gatt_server_char_config_t; /**< GATT server config (see #mico_bt_gatt_server_char_config_e) */ + + +/** GATT Characteristic Properties Mask */ +enum mico_bt_gatt_char_properties_e { + GATT_CHAR_PROPERTIES_BIT_BROADCAST = (1 << 0), /**< bit 0: Broadcast */ + GATT_CHAR_PROPERTIES_BIT_READ = (1 << 1), /**< bit 1: Read */ + GATT_CHAR_PROPERTIES_BIT_WRITE_NR = (1 << 2), /**< bit 2: Write (No Response) */ + GATT_CHAR_PROPERTIES_BIT_WRITE = (1 << 3), /**< bit 3: Write */ + GATT_CHAR_PROPERTIES_BIT_NOTIFY = (1 << 4), /**< bit 4: Notify */ + GATT_CHAR_PROPERTIES_BIT_INDICATE = (1 << 5), /**< bit 5: Indicate */ + GATT_CHAR_PROPERTIES_BIT_AUTH = (1 << 6), /**< bit 6: Authenticate */ + GATT_CHAR_PROPERTIES_BIT_EXT_PROP = (1 << 7) /**< bit 7: Extended Properties */ +}; +typedef uint8_t +mico_bt_gatt_char_properties_t; /**< GATT characteristic properties mask (see #mico_bt_gatt_char_properties_e) */ + +/************************************************************************* + * Macros for parsing results GATT discovery results + * (while handling GATT_DISCOVERY_RESULT_EVT) + ****************************************************************************/ +/* Discovery type: GATT_DISCOVER_SERVICES_ALL or GATT_DISCOVER_SERVICES_BY_UUID */ +#define GATT_DISCOVERY_RESULT_SERVICE_START_HANDLE(p_event_data) (p_event_data->discovery_result.discovery_data.group_value.s_handle) +#define GATT_DISCOVERY_RESULT_SERVICE_END_HANDLE(p_event_data) (p_event_data->discovery_result.discovery_data.group_value.e_handle) +#define GATT_DISCOVERY_RESULT_SERVICE_UUID_LEN(p_event_data) (p_event_data->discovery_result.discovery_data.group_value.service_type.len) +#define GATT_DISCOVERY_RESULT_SERVICE_UUID16(p_event_data) (p_event_data->discovery_result.discovery_data.group_value.service_type.uu.uuid16) +#define GATT_DISCOVERY_RESULT_SERVICE_UUID32(p_event_data) (p_event_data->discovery_result.discovery_data.group_value.service_type.uu.uuid32) +#define GATT_DISCOVERY_RESULT_SERVICE_UUID128(p_event_data) (p_event_data->discovery_result.discovery_data.group_value.service_type.uu.uuid128) + +/* Discovery type: GATT_DISCOVER_CHARACTERISTIC_DESCRIPTORS */ +#define GATT_DISCOVERY_RESULT_CHARACTERISTIC_DESCRIPTOR_UUID_LEN(p_event_data) (p_event_data->discovery_result.discovery_data.char_descr_info.type.len) +#define GATT_DISCOVERY_RESULT_CHARACTERISTIC_DESCRIPTOR_UUID16(p_event_data) (p_event_data->discovery_result.discovery_data.char_descr_info.type.uu.uuid16) +#define GATT_DISCOVERY_RESULT_CHARACTERISTIC_DESCRIPTOR_UUID32(p_event_data) (p_event_data->discovery_result.discovery_data.char_descr_info.type.uu.uuid32) +#define GATT_DISCOVERY_RESULT_CHARACTERISTIC_DESCRIPTOR_UUID128(p_event_data) (p_event_data->discovery_result.discovery_data.char_descr_info.type.uu.uuid128) +#define GATT_DISCOVERY_RESULT_CHARACTERISTIC_DESCRIPTOR_VALUE_HANDLE(p_event_data) (p_event_data->discovery_result.discovery_data.char_descr_info.handle) + +/* Discovery type: GATT_DISCOVER_CHARACTERISTICS */ +#define GATT_DISCOVERY_RESULT_CHARACTERISTIC_VALUE_HANDLE(p_event_data) (p_event_data->discovery_result.discovery_data.characteristic_declaration.val_handle) +#define GATT_DISCOVERY_RESULT_CHARACTERISTIC_UUID_LEN(p_event_data) (p_event_data->discovery_result.discovery_data.characteristic_declaration.char_uuid.len) +#define GATT_DISCOVERY_RESULT_CHARACTERISTIC_UUID16(p_event_data) (p_event_data->discovery_result.discovery_data.characteristic_declaration.char_uuid.uu.uuid16) +#define GATT_DISCOVERY_RESULT_CHARACTERISTIC_UUID32(p_event_data) (p_event_data->discovery_result.discovery_data.characteristic_declaration.char_uuid.uu.uuid32) +#define GATT_DISCOVERY_RESULT_CHARACTERISTIC_UUID128(p_event_data) (p_event_data->discovery_result.discovery_data.characteristic_declaration.char_uuid.uu.uuid128) + +/** Authentication requirement */ +enum mico_bt_gatt_auth_req_e { + GATT_AUTH_REQ_NONE = 0, /**< No Authentication Required */ + GATT_AUTH_REQ_NO_MITM = 1, /**< Unauthenticated encryption (No MITM) */ + GATT_AUTH_REQ_MITM = 2, /**< Authenticated encryption (MITM) */ + GATT_AUTH_REQ_SIGNED_NO_MITM = 3, /**< Signed Data (No MITM) */ + GATT_AUTH_REQ_SIGNED_MITM = 4 /**< Signed Data (MITM) */ +}; +typedef uint8_t mico_bt_gatt_auth_req_t; /**< GATT authentication requirement (see #mico_bt_gatt_auth_req_e)*/ + +/** Attribute value, used for GATT write operations, and read response callbacks */ +typedef struct { + uint16_t handle; /**< Attribute handle */ + uint16_t + offset; /**< Attribute value offset, ignored if not needed for a command */ + uint16_t len; /**< Length of attribute value */ + mico_bt_gatt_auth_req_t + auth_req; /**< Authentication requirement (see @link mico_bt_gatt_auth_req_e mico_bt_gatt_auth_req_t @endlink) */ + uint8_t + value[1]; /**< The attribute value (actual length is specified by 'len') */ +} mico_bt_gatt_value_t; + +/** GATT Write Execute request flags */ +enum mico_bt_gatt_exec_flag_e { + GATT_PREP_WRITE_CANCEL = 0x00, /**< GATT_PREP_WRITE_CANCEL */ + GATT_PREP_WRITE_EXEC = 0x01 /**< GATT_PREP_WRITE_EXEC */ +}; +typedef uint8_t mico_bt_gatt_exec_flag_t; /**< GATT execute flag (see #mico_bt_gatt_exec_flag_e) */ + +/** Attribute read request */ +typedef struct { + uint16_t handle; /**< Handle of attribute to read */ + uint16_t offset; /**< Offset to read */ + mico_bool_t is_long; /**< TRUE if long read */ + uint16_t *p_val_len; /**< input and output parameter for value length */ + uint8_t *p_val; /**< Value pointer */ +} mico_bt_gatt_read_t; + +/** Attribute write request */ +typedef struct { + uint16_t handle; /**< Handle of attribute to read */ + mico_bool_t is_prep; /**< TRUE if this is a prepare write request */ + uint16_t offset; /**< Offset to write */ + uint16_t val_len; /**< Value length */ + uint8_t *p_val; /**< Value pointer */ +} mico_bt_gatt_write_t; + +/** Attribute information for GATT attribute requests */ +typedef union { + mico_bt_gatt_read_t read_req; /**< Parameters for GATTS_REQ_TYPE_READ */ + mico_bt_gatt_write_t write_req; /**< Parameters for GATTS_REQ_TYPE_WRITE */ + uint16_t handle; /**< Parameters for GATTS_REQ_TYPE_CONF */ + uint16_t mtu; /**< Parameters for GATTS_REQ_TYPE_MTU */ + mico_bt_gatt_exec_flag_t exec_write; /**< Parameters for GATTS_REQ_TYPE_WRITE_EXEC */ +} mico_bt_gatt_request_data_t; + +/** GATT Attribute Request Type */ +enum mico_bt_gatt_request_type_e { + GATTS_REQ_TYPE_READ = 1, /**< Attribute read notification (attribute value internally read from GATT database) */ + GATTS_REQ_TYPE_WRITE, /**< Attribute write notification (attribute value internally written to GATT database) */ + GATTS_REQ_TYPE_PREP_WRITE, /**< Attribute Prepare Write Notification (Suspending write request before triggering actual execute write ) */ + GATTS_REQ_TYPE_WRITE_EXEC, /**< Execute write request */ + GATTS_REQ_TYPE_MTU, /**< MTU exchange information */ + GATTS_REQ_TYPE_CONF, /**< Value confirmation */ +}; +typedef uint8_t mico_bt_gatt_request_type_t; /**< GATT Attribute Request Type (see #mico_bt_gatt_request_type_e) */ + +/** Discovery types */ +enum mico_bt_gatt_discovery_type_e { + GATT_DISCOVER_SERVICES_ALL = 1, /**< discover all services */ + GATT_DISCOVER_SERVICES_BY_UUID, /**< discover service by UUID */ + GATT_DISCOVER_INCLUDED_SERVICES, /**< discover an included service within a service */ + GATT_DISCOVER_CHARACTERISTICS, /**< discover characteristics of a service with/without type requirement */ + GATT_DISCOVER_CHARACTERISTIC_DESCRIPTORS, /**< discover characteristic descriptors of a character */ + GATT_DISCOVER_MAX /* maximum discovery types */ +}; +typedef uint8_t mico_bt_gatt_discovery_type_t; /**< GATT Discovery type (see #mico_bt_gatt_discovery_type_e) */ + +/** Parameters used in a GATT Discovery */ +typedef struct { + mico_bt_uuid_t uuid; /**< Service or Characteristic UUID */ + uint16_t s_handle; /**< Start handle for range to search */ + uint16_t e_handle; /**< End handle for range to search */ +} mico_bt_gatt_discovery_param_t; + +/** GATT Read Types */ +enum mico_bt_gatt_read_type_e { + GATT_READ_BY_TYPE = 1, /**< Read by Type (service or characteristic UUIDs) */ + GATT_READ_BY_HANDLE, /**< Read by Handle */ + GATT_READ_MULTIPLE, /**< Read Multiple (array of handles) */ + GATT_READ_CHAR_VALUE, /**< Read Characteristic Value */ + GATT_READ_PARTIAL, /**< Read Partial */ + GATT_READ_MAX +}; +typedef uint8_t mico_bt_gatt_read_type_t; /**< GATT read type (see #mico_bt_gatt_read_type_e) */ + +/** Parameters for GATT_READ_BY_TYPE and GATT_READ_CHAR_VALUE */ +typedef struct { + mico_bt_gatt_auth_req_t + auth_req; /**< Authentication requirement (see @link mico_bt_gatt_auth_req_e mico_bt_gatt_auth_req_t @endlink) */ + uint16_t s_handle; /**< Starting handle */ + uint16_t e_handle; /**< Ending handle */ + mico_bt_uuid_t uuid; /**< uuid */ +} mico_bt_gatt_read_by_type_t; + +#define GATT_MAX_READ_MULTI_HANDLES 10 /**< Max attributes allowed in one GATT_READ_MULTIPLE request */ +/** Parameters for GATT_READ_MULTIPLE */ +typedef struct { + mico_bt_gatt_auth_req_t + auth_req; /**< authentication requirement (see @link mico_bt_gatt_auth_req_e mico_bt_gatt_auth_req_t @endlink) */ + uint16_t num_handles; /**< number of handles to read */ + uint16_t handles[GATT_MAX_READ_MULTI_HANDLES]; /**< handles list to be read */ +} mico_bt_gatt_read_multi_t; + +/** Parameters for GATT_READ_BY_HANDLE */ +typedef struct { + mico_bt_gatt_auth_req_t + auth_req; /**< authentication requirement (see @link mico_bt_gatt_auth_req_e mico_bt_gatt_auth_req_t @endlink) */ + uint16_t handle; /**< handle */ +} mico_bt_gatt_read_by_handle_t; + +/** Parameters for GATT_READ_PARTIAL */ +typedef struct { + mico_bt_gatt_auth_req_t + auth_req; /**< authentication requirement (see @link mico_bt_gatt_auth_req_e mico_bt_gatt_auth_req_t @endlink) */ + uint16_t handle; /**< handle */ + uint16_t offset; /**< offset */ +} mico_bt_gatt_read_partial_t; + +/** Read request parameters - used when calling #mico_bt_gatt_send_read */ +typedef union { + mico_bt_gatt_read_by_type_t service; /**< Parameters for GATT_READ_BY_TYPE */ + mico_bt_gatt_read_by_type_t char_type; /**< Parameters for GATT_READ_CHAR_VALUE */ + mico_bt_gatt_read_multi_t read_multiple; /**< Parameters for GATT_READ_MULTIPLE */ + mico_bt_gatt_read_by_handle_t by_handle; /**< Parameters for GATT_READ_BY_HANDLE */ + mico_bt_gatt_read_partial_t partial; /**< Parameters for GATT_READ_PARTIAL */ +} mico_bt_gatt_read_param_t; + +/** Write request types - used when calling #mico_bt_gatt_send_write */ +enum mico_bt_gatt_write_type_e { + GATT_WRITE_NO_RSP = 1, /**< Write without response */ + GATT_WRITE, /**< Write with response */ + GATT_WRITE_PREPARE /**< Prepare to write (call #mico_bt_gatt_send_execute_write to execute the write) */ +}; +typedef uint8_t mico_bt_gatt_write_type_t; /**< GATT write type (see #mico_bt_gatt_write_type_e) */ + +/** Response data for read operations */ +typedef struct { + uint16_t handle; /**< handle */ + uint16_t len; /**< length of response data */ + uint16_t offset; /**< offset */ + uint8_t *p_data; /**< attribute data */ +} mico_bt_gatt_data_t; + +/** Client Operation Complete response data (dependent on operation completed) */ +typedef union { + mico_bt_gatt_data_t + att_value; /**< Response data for read operations (initiated using #mico_bt_gatt_send_read) */ + uint16_t mtu; /**< Response data for configuration operations */ + uint16_t + handle; /**< Response data for write operations (initiated using #mico_bt_gatt_send_write) */ +} mico_bt_gatt_operation_complete_rsp_t; /**< GATT operation complete response type */ + +/** GATT client operation type, used in client callback function +*/ +enum mico_bt_gatt_optype_e { + GATTC_OPTYPE_NONE = 0, /**< None */ + GATTC_OPTYPE_DISCOVERY = 1, /**< Discovery */ + GATTC_OPTYPE_READ = 2, /**< Read */ + GATTC_OPTYPE_WRITE = 3, /**< Write */ + GATTC_OPTYPE_EXE_WRITE = 4, /**< Execute Write */ + GATTC_OPTYPE_CONFIG = 5, /**< Configure */ + GATTC_OPTYPE_NOTIFICATION = 6, /**< Notification */ + GATTC_OPTYPE_INDICATION = 7 /**< Indication */ +}; + +/* GATT Client Operation Codes */ +typedef uint8_t mico_bt_gatt_optype_t; /**< GATT operation type (see #mico_bt_gatt_optype_e) */ + +/** characteristic declaration */ +typedef struct { + mico_bt_gatt_char_properties_t + characteristic_properties; /**< characteristic properties (see @link mico_bt_gatt_char_properties_e mico_bt_gatt_char_properties_t @endlink) */ + uint16_t val_handle; /**< characteristic value attribute handle */ + uint16_t handle; /**< characteristic declaration handle */ + mico_bt_uuid_t char_uuid; /**< characteristic UUID type */ +} mico_bt_gatt_char_declaration_t; + +/** GATT group value */ +typedef struct { + mico_bt_uuid_t service_type; /**< group type */ + uint16_t s_handle; /**< starting handle of the group */ + uint16_t e_handle; /**< ending handle of the group */ +} mico_bt_gatt_group_value_t; + + +/** included service attribute value */ +typedef struct { + mico_bt_uuid_t service_type; /**< included service UUID */ + uint16_t handle; /**< included service handle */ + uint16_t s_handle; /**< starting handle */ + uint16_t e_handle; /**< ending handle */ +} mico_bt_gatt_included_service_t; + +/** characteristic descriptor information */ +typedef struct { + mico_bt_uuid_t type; /**< descriptor UUID type */ + uint16_t handle; /**< descriptor attribute handle */ +} mico_bt_gatt_char_descr_info_t; + + +/** + * Discovery result data + * Use GATT_DISCOVERY_RESULT_SERVICE_* or GATT_DISCOVERY_RESULT_CHARACTERISTIC_* macros to parse discovery data) + */ +typedef union { + mico_bt_gatt_included_service_t included_service; /**< Result for GATT_DISCOVER_INCLUDED_SERVICES */ + mico_bt_gatt_group_value_t + group_value; /**< Result for GATT_DISCOVER_SERVICES_ALL or GATT_DISCOVER_SERVICES_BY_UUID */ + mico_bt_gatt_char_declaration_t characteristic_declaration; /**< Result for GATT_DISCOVER_CHARACTERISTICS */ + mico_bt_gatt_char_descr_info_t + char_descr_info; /**< Result for GATT_DISCOVER_CHARACTERISTIC_DESCRIPTORS */ +} mico_bt_gatt_discovery_data_t; + +#define GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP 0 /* start a idle timer for this duration when no application need to use the link */ +#define GATT_LINK_NO_IDLE_TIMEOUT 0xFFFF +#define GATT_INVALID_ACL_HANDLE 0xFFFF +#define GATT_HANDLE_IS_VALID(x) ((x) != 0) + +typedef uint16_t mico_bt_gatt_appearance_t; /**< GATT appearance (see #gatt_appearance_e) */ + +/***************************************************************************** + * GATT Database Defintions + *****************************************************************************/ +/* The permission bits (see Vol 3, Part F, 3.3.1.1) */ +#define LEGATTDB_PERM_NONE (0x00) +#define LEGATTDB_PERM_VARIABLE_LENGTH (0x1 << 0) +#define LEGATTDB_PERM_READABLE (0x1 << 1) +#define LEGATTDB_PERM_WRITE_CMD (0x1 << 2) +#define LEGATTDB_PERM_WRITE_REQ (0x1 << 3) +#define LEGATTDB_PERM_AUTH_READABLE (0x1 << 4) +#define LEGATTDB_PERM_RELIABLE_WRITE (0x1 << 5) +#define LEGATTDB_PERM_AUTH_WRITABLE (0x1 << 6) + +#define LEGATTDB_PERM_WRITABLE (LEGATTDB_PERM_WRITE_CMD | LEGATTDB_PERM_WRITE_REQ| LEGATTDB_PERM_AUTH_WRITABLE) +#define LEGATTDB_PERM_MASK (0x7f) /* All the permission bits. */ +#define LEGATTDB_PERM_SERVICE_UUID_128 (0x1 << 7) + + +/* GATT Characteristic Properties */ +#define LEGATTDB_CHAR_PROP_BROADCAST (0x1 << 0) +#define LEGATTDB_CHAR_PROP_READ (0x1 << 1) +#define LEGATTDB_CHAR_PROP_WRITE_NO_RESPONSE (0x1 << 2) +#define LEGATTDB_CHAR_PROP_WRITE (0x1 << 3) +#define LEGATTDB_CHAR_PROP_NOTIFY (0x1 << 4) +#define LEGATTDB_CHAR_PROP_INDICATE (0x1 << 5) +#define LEGATTDB_CHAR_PROP_AUTHD_WRITES (0x1 << 6) +#define LEGATTDB_CHAR_PROP_EXTENDED (0x1 << 7) + +/* Conversion macros */ +#define BIT16_TO_8( val ) \ + (uint8_t)( (val) & 0xff),/* LSB */ \ + (uint8_t)(( (val) >> 8 ) & 0xff) /* MSB */ + +/* UUID lengths */ +#define LEGATTDB_UUID16_SIZE 2 +#define LEGATTDB_UUID128_SIZE 16 + + +/* Service and Characteristic macros */ +#define ATTRIBUTE16( handle, permission, datalen, uuid ) \ + BIT16_TO_8(handle), \ + (uint8_t)(permission), \ + (uint8_t)(datalen + 2), \ + BIT16_TO_8(uuid) + +#define PRIMARY_SERVICE_UUID16(handle, service) \ + BIT16_TO_8((uint16_t)(handle)), \ + LEGATTDB_PERM_READABLE, \ + 4, \ + BIT16_TO_8((GATT_UUID_PRI_SERVICE)), \ + BIT16_TO_8((service)) + +#define PRIMARY_SERVICE_UUID128(handle, service) \ + BIT16_TO_8((uint16_t)(handle)), \ + LEGATTDB_PERM_READABLE, \ + 18, \ + BIT16_TO_8(GATT_UUID_PRI_SERVICE), \ + service + +#define SECONDARY_SERVICE_UUID16(handle, service) \ + BIT16_TO_8((uint16_t)(handle)), \ + LEGATTDB_PERM_READABLE, \ + 4, \ + BIT16_TO_8((GATT_UUID_SEC_SERVICE)), \ + BIT16_TO_8((service)) + +#define SECONDARY_SERVICE_UUID128(handle, service) \ + BIT16_TO_8((uint16_t)(handle)), \ + LEGATTDB_PERM_READABLE, \ + 18, \ + BIT16_TO_8(GATT_UUID_SEC_SERVICE), \ + service + +#define INCLUDE_SERVICE_UUID16(handle, service_handle, end_group_handle, service) \ + BIT16_TO_8((uint16_t)(handle)), \ + LEGATTDB_PERM_READABLE, \ + 8, \ + BIT16_TO_8(GATT_UUID_INCLUDE_SERVICE), \ + BIT16_TO_8(service_handle), \ + BIT16_TO_8(end_group_handle), \ + BIT16_TO_8(service) + + +#define INCLUDE_SERVICE_UUID128(handle, service_handle, end_group_handle)\ + BIT16_TO_8((uint16_t)(handle)), \ + LEGATTDB_PERM_READABLE, \ + 6, \ + BIT16_TO_8(GATT_UUID_INCLUDE_SERVICE), \ + BIT16_TO_8(service_handle), \ + BIT16_TO_8(end_group_handle) + + +#define CHARACTERISTIC_UUID16(handle, handle_value, uuid, properties, permission) \ + BIT16_TO_8((uint16_t)(handle)), \ + LEGATTDB_PERM_READABLE, \ + 0x07, \ + BIT16_TO_8(GATT_UUID_CHAR_DECLARE), \ + (uint8_t)(properties), \ + BIT16_TO_8((uint16_t)(handle_value)), \ + BIT16_TO_8(uuid), \ + BIT16_TO_8((uint16_t)(handle_value)), \ + (uint8_t)(permission), \ + (uint8_t)(LEGATTDB_UUID16_SIZE), \ + BIT16_TO_8(uuid) + +#define CHARACTERISTIC_UUID128(handle, handle_value, uuid, properties, permission) \ + BIT16_TO_8((uint16_t)(handle)), \ + LEGATTDB_PERM_READABLE, \ + 21, \ + BIT16_TO_8(GATT_UUID_CHAR_DECLARE), \ + (uint8_t)(properties), \ + BIT16_TO_8((uint16_t)(handle_value)), \ + uuid, \ + BIT16_TO_8((uint16_t)(handle_value)), \ + (uint8_t)(permission | LEGATTDB_PERM_SERVICE_UUID_128), \ + (uint8_t)(LEGATTDB_UUID128_SIZE), \ + uuid + +#define CHARACTERISTIC_UUID16_WRITABLE(handle, handle_value, uuid, properties, permission) \ + BIT16_TO_8((uint16_t)(handle)), \ + LEGATTDB_PERM_READABLE, \ + 0x07, \ + BIT16_TO_8(GATT_UUID_CHAR_DECLARE), \ + (uint8_t)(properties), \ + BIT16_TO_8((uint16_t)(handle_value)), \ + BIT16_TO_8(uuid), \ + BIT16_TO_8((uint16_t)(handle_value)), \ + (uint8_t)(permission), \ + (uint8_t)(LEGATTDB_UUID16_SIZE), \ + (uint8_t)(0), \ + BIT16_TO_8(uuid) + +#define CHARACTERISTIC_UUID128_WRITABLE(handle, handle_value, uuid, properties, permission) \ + BIT16_TO_8((uint16_t)(handle)), \ + LEGATTDB_PERM_READABLE, \ + 21, \ + BIT16_TO_8(GATT_UUID_CHAR_DECLARE), \ + (uint8_t)(properties), \ + BIT16_TO_8((uint16_t)(handle_value)), \ + uuid, \ + BIT16_TO_8((uint16_t)(handle_value)), \ + (uint8_t)(permission | LEGATTDB_PERM_SERVICE_UUID_128), \ + (uint8_t)(LEGATTDB_UUID128_SIZE), \ + (uint8_t)(0), \ + uuid + +#define CHAR_DESCRIPTOR_UUID16_WRITABLE(handle, uuid, permission) \ + BIT16_TO_8((uint16_t)(handle)), \ + (uint8_t)(permission), \ + (uint8_t)(LEGATTDB_UUID16_SIZE), \ + (uint8_t)(0), \ + BIT16_TO_8(uuid) + +#define CHAR_DESCRIPTOR_UUID16(handle, uuid, permission) \ + BIT16_TO_8((uint16_t)(handle)), \ + (uint8_t)(permission), \ + (uint8_t)(LEGATTDB_UUID16_SIZE), \ + BIT16_TO_8(uuid) + +/** GATT events */ +typedef enum { + GATT_CONNECTION_STATUS_EVT, /**< GATT connection status change. Event data: #mico_bt_gatt_connection_status_t */ + GATT_OPERATION_CPLT_EVT, /**< GATT operation complete. Event data: #mico_bt_gatt_event_data_t */ + GATT_DISCOVERY_RESULT_EVT, /**< GATT attribute discovery result. Event data: #mico_bt_gatt_discovery_result_t */ + GATT_DISCOVERY_CPLT_EVT, /**< GATT attribute discovery complete. Event data: #mico_bt_gatt_event_data_t */ + GATT_ATTRIBUTE_REQUEST_EVT /**< GATT attribute request (from remote client). Event data: #mico_bt_gatt_attribute_request_t */ +} mico_bt_gatt_evt_t; + +/** Discovery result (used by GATT_DISCOVERY_RESULT_EVT notification) */ +typedef struct { + uint16_t conn_id; /**< ID of the connection */ + mico_bt_gatt_discovery_type_t + discovery_type; /**< Discovery type (see @link mico_bt_gatt_discovery_type_e mico_bt_gatt_discovery_type_t @endlink) */ + mico_bt_gatt_discovery_data_t discovery_data; /**< Discovery data */ +} mico_bt_gatt_discovery_result_t; + +/** Discovery Complete (used by GATT_DISCOVERY_CPLT_EVT notification) */ +typedef struct { + uint16_t conn_id; /**< ID of the connection */ + mico_bt_gatt_discovery_type_t + disc_type; /**< Discovery type (see @link mico_bt_gatt_discovery_type_e mico_bt_gatt_discovery_type_t @endlink) */ + mico_bt_gatt_status_t status; /**< Status of operation */ +} mico_bt_gatt_discovery_complete_t; + +/** Response to read/write/disc/config operations (used by GATT_OPERATION_CPLT_EVT notification) */ +typedef struct { + uint16_t conn_id; /**< ID of the connection */ + mico_bt_gatt_optype_t + op; /**< Type of operation completed (see @link mico_bt_gatt_optype_e mico_bt_gatt_optype_t @endlink) */ + mico_bt_gatt_status_t status; /**< Status of operation */ + mico_bt_gatt_operation_complete_rsp_t response_data; /**< Response data (dependent on optype) */ +} mico_bt_gatt_operation_complete_t; + +/** GATT connection status (used by GATT_CONNECTION_STATUS_EVT notification) */ +typedef struct { + uint8_t *bd_addr; /**< Remote device address */ + mico_bt_ble_address_type_t addr_type; /**< Remmote device address type */ + uint16_t conn_id; /**< ID of the connection */ + mico_bool_t connected; /**< TRUE if connected, FALSE if disconnected */ + mico_bt_gatt_disconn_reason_t + reason; /**< Reason code (see @link mico_bt_gatt_disconn_reason_e mico_bt_gatt_disconn_reason_t @endlink) */ + mico_bt_transport_t transport; /**< Transport type of the connection */ + uint8_t link_role; /**< Link role on this connection */ +} mico_bt_gatt_connection_status_t; + +/** GATT attribute request (used by GATT_ATTRIBUTE_REQUEST_EVT notification) */ +typedef struct { + uint16_t conn_id; /**< ID of the connection */ + mico_bt_gatt_request_type_t + request_type; /**< Request type (see @link mico_bt_gatt_request_type_e mico_bt_gatt_request_type_t) */ + mico_bt_gatt_request_data_t + data; /**< Information about attribute being request (dependent on request type) */ +} mico_bt_gatt_attribute_request_t; + +/** Stuctures for GATT event notifications */ +typedef union { + mico_bt_gatt_discovery_result_t discovery_result; /**< Data for GATT_DISCOVERY_RESULT_EVT */ + mico_bt_gatt_discovery_complete_t discovery_complete; /**< Data for GATT_DISCOVERY_CPLT_EVT */ + mico_bt_gatt_operation_complete_t operation_complete; /**< Data for GATT_OPERATION_CPLT_EVT */ + mico_bt_gatt_connection_status_t connection_status; /**< Data for GATT_CONNECTION_STATUS_EVT */ + mico_bt_gatt_attribute_request_t attribute_request; /**< Data for GATT_ATTRIBUTE_REQUEST_EVT */ +} mico_bt_gatt_event_data_t; + +/** + * GATT event notification callback + * + * Callback for GATT event notifications + * Registered using mico_bt_gatt_register() + * + * @param event : Event ID + * @param p_event_data : Event data + * + * @return Status of event handling +*/ +typedef mico_bt_gatt_status_t mico_bt_gatt_cback_t(mico_bt_gatt_evt_t event, mico_bt_gatt_event_data_t *p_event_data); + +/***************************************************************************** + * External Function Declarations + ****************************************************************************/ +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @addtogroup micobt_gatt Generic Attribute (GATT) + * @ingroup micobt + * + * Generic Attribute (GATT) Functions. + * + * @{ + */ +/****************************************************************************/ +/** + * GATT Profile Server Functions + * + * @addtogroup server_api_functions Server + * @ingroup micobt_gatt + * + * Server API Functions sub module for @b GATT. + * + * @{ + */ +/****************************************************************************/ + +/** + * Function mico_bt_gatt_db_init + * + * Initialize the GATT database + * + * @param[in] p_gatt_db : First element in GATT database array + * @param[in] gatt_db_size : Size (in bytes) of GATT database + * + * @return @link mico_bt_gatt_status_e mico_bt_gatt_status_t @endlink + * + */ +mico_bt_gatt_status_t mico_bt_gatt_db_init (const uint8_t *p_gatt_db, uint16_t gatt_db_size); + +/** + * + * Function mico_bt_gatt_send_indication + * + * Send a handle value indication to a client + * + * @param[in] conn_id : connection identifier. + * @param[in] attr_handle : Attribute handle of this handle value indication. + * @param[in] val_len : Length of notification value passed, and return the length actually. + * @param[in] p_val : Notification Value. + * + * @return @link mico_bt_gatt_status_e mico_bt_gatt_status_t @endlink + * + */ +mico_bt_gatt_status_t mico_bt_gatt_send_indication (uint16_t conn_id, uint16_t attr_handle, uint16_t *val_len, + uint8_t *p_val ); + +/** + * Function mico_bt_gatt_send_notification + * + * Send a handle value notification to a client. + * + * @param[in] conn_id : connection identifier. + * @param[in] attr_handle : Attribute handle of this handle value indication. + * @param[in] val_len : Length of notification value passed, and return the length actually. + * @param[in] p_val : Notification Value. + * + * @return @link mico_bt_gatt_status_e mico_bt_gatt_status_t @endlink + * + */ +mico_bt_gatt_status_t mico_bt_gatt_send_notification (uint16_t conn_id, uint16_t attr_handle, uint16_t *val_len, + uint8_t *p_val ); + +/** +* Function mico_bt_gatt_send_response +* +* When application receives a Read Request, Write Request or Indication from the +* peer it can reply synchronously or return a MICO_BT_GATT_PENDING result code +* indicating to the stack that the message is not processed yet. In that case +* application should call this function to send data or just a confirmation to +* the peer. +* +* @param[in] status : Status of the operation to be send to the peer +* @param[in] conn_id : Connection handle +* @param[in] attr_handle : Attribute handle +* @param[in] attr_len : Length of the attribute to send +* @param[in] offset : Attribute value offset +* @param[in] p_attr : Attribute Value +* +* @return @link mico_bt_gatt_status_e mico_bt_gatt_status_t @endlink +*/ +mico_bt_gatt_status_t mico_bt_gatt_send_response(mico_bt_gatt_status_t status, uint16_t conn_id, + uint16_t attr_handle, uint16_t attr_len, uint16_t offset, uint8_t *p_attr); + +/**@} server_api_functions */ + +/*****************************************************************************/ +/** + * GATT Profile Client Functions + * + * @addtogroup client_api_functions Client + * @ingroup micobt_gatt + * + * @{ + */ +/*****************************************************************************/ + +/** + * Function mico_bt_gatt_configure_mtu + * + * Configure the ATT MTU size for a connection on an LE + * transport. + * + * @param[in] conn_id : GATT connection handle + * @param[in] mtu : New MTU size + * + * @return @link mico_bt_gatt_status_e mico_bt_gatt_status_t @endlink +*/ +mico_bt_gatt_status_t mico_bt_gatt_configure_mtu (uint16_t conn_id, uint16_t mtu); + +/** + * Function mico_bt_gatt_send_discover + * + * Start an attribute discovery on an ATT server. + * Discovery results are notified using GATT_DISCOVERY_RESULT_EVT ; + * completion is notified using GATT_DISCOVERY_CPLT_EVT of #mico_bt_gatt_cback_t. + * + * @param[in] conn_id : GATT connection handle + * @param[in] discovery_type : Discover type + * @param[in] p_discovery_param : Discover parameter + * + * @return @link mico_bt_gatt_status_e mico_bt_gatt_status_t @endlink +*/ +mico_bt_gatt_status_t mico_bt_gatt_send_discover (uint16_t conn_id, + mico_bt_gatt_discovery_type_t discovery_type, + mico_bt_gatt_discovery_param_t *p_discovery_param ); + +/** + * Function mico_bt_gatt_send_read + * + * Read from remote ATT server. + * Result is notified using GATT_OPERATION_CPLT_EVT of #mico_bt_gatt_cback_t. + * + * @param[in] conn_id : Connection handle + * @param[in] type : Type of the read + * @param[in] p_read : Pointer to the read request parameters + * + * @return @link mico_bt_gatt_status_e mico_bt_gatt_status_t @endlink + * + */ +mico_bt_gatt_status_t mico_bt_gatt_send_read (uint16_t conn_id, mico_bt_gatt_read_type_t type, + mico_bt_gatt_read_param_t *p_read); + +/** + * Function mico_bt_gatt_send_write + * + * Write to remote ATT server. + * Result is notified using GATT_OPERATION_CPLT_EVT of #mico_bt_gatt_cback_t. + * + * @param[in] conn_id : Connection handle + * @param[in] type : Type of write + * @param[in] p_write : Pointer to the write parameters + * + * @return @link mico_bt_gatt_status_e mico_bt_gatt_status_t @endlink + */ +mico_bt_gatt_status_t mico_bt_gatt_send_write (uint16_t conn_id, mico_bt_gatt_write_type_t type, + mico_bt_gatt_value_t *p_write); + +/** + * Function mico_bt_gatt_send_execute_write + * + * Send Execute Write request to remote ATT server. + * + * @param[in] conn_id : Connection handle + * @param[in] is_execute : MICO_BT_TRUE to execute, MICO_BT_FALSE to cancel + * + * @return @link mico_bt_gatt_status_e mico_bt_gatt_status_t @endlink + * + */ +mico_bt_gatt_status_t mico_bt_gatt_send_execute_write (uint16_t conn_id, mico_bool_t is_execute); + +/** + * Function mico_bt_gatt_send_indication_confirm + * + * Send a handle value confirmation to remote ATT server. + * (in response to GATTC_OPTYPE_INDICATION of #mico_bt_gatt_cback_t) + * + * @param[in] conn_id : Connection handle + * @param[in] handle : Attribute handle + * + * @return @link mico_bt_gatt_status_e mico_bt_gatt_status_t @endlink +*/ +mico_bt_gatt_status_t mico_bt_gatt_send_indication_confirm (uint16_t conn_id, uint16_t handle); + +/**@} client_api_functions */ + +/*****************************************************************************/ +/** + * GATT Profile Common Functions + * + * @addtogroup common_api_functions Common + * @ingroup micobt_gatt + * + * @{ + */ +/*****************************************************************************/ + +/** + * Function mico_bt_gatt_register + * + * Register an application callback for GATT. + * + * @param[in] gatt_if : The GATT application interface + * @param[in] p_gatt_cback : The GATT notification callback + * + * @return @link mico_bt_gatt_status_e mico_bt_gatt_status_t @endlink + * + */ +mico_bt_gatt_status_t mico_bt_gatt_register (mico_bt_gatt_app_interface_t gatt_if, mico_bt_gatt_cback_t *p_gatt_cback); + +/** + * Function mico_bt_gatt_deregister + * + * Deregister an application callback for GATT. + * + * @param[in] gatt_if : The GATT application interface + * + * @return @link mico_bt_gatt_status_e mico_bt_gatt_status_t @endlink + * + */ +mico_bt_gatt_status_t mico_bt_gatt_deregister (mico_bt_gatt_app_interface_t gatt_if); + + +/** + * Function mico_bt_gatt_le_connect + * + * Open GATT over LE connection to a remote device + * Result is notified using GATT_CONNECTION_STATUS_EVT of #mico_bt_gatt_cback_t. + * + * @param[in] bd_addr : Remote device address + * @param[in] bd_addr_type: Public or random address + * @param[in] conn_mode : connection scan mode + * @param[in] is_direct : Is direct connection or not + * + * @return TRUE : If connection started + * FALSE : If connection start failure + * + */ +mico_bool_t mico_bt_gatt_le_connect (mico_bt_device_address_t bd_addr, + mico_bt_ble_address_type_t bd_addr_type, + mico_bt_ble_conn_mode_t conn_mode, + mico_bool_t is_direct); + +/** + * Function mico_bt_gatt_bredr_connect + * + * Open GATT over BR/EDR connection to a remote device + * Result is notified using GATT_CONNECTION_STATUS_EVT of #mico_bt_gatt_cback_t. + * + * @param[in] bd_addr : Remote device address + * + * @return TRUE : If connection started + * FALSE : If connection start failure + * + */ +mico_bool_t mico_bt_gatt_bredr_connect (mico_bt_device_address_t bd_addr); + +/** + * Function mico_bt_gatt_cancel_connect + * + * Cancel initiating GATT connecton + * + * @param[in] bd_addr : Remote device addresss + * @param[in] is_direct : Is direct connection or not + * + * @return TRUE : If connection started + * FALSE : If connection start failure + * + */ +mico_bool_t mico_bt_gatt_cancel_connect (mico_bt_device_address_t bd_addr, mico_bool_t is_direct); + +/** + * Function mico_bt_gatt_disconnect + * + * Close the specified GATT connection. + * Result is notified using GATT_CONNECTION_STATUS_EVT of #mico_bt_gatt_cback_t. + * + * @param[in] conn_id : GATT connection ID + * + * @return @link mico_bt_gatt_status_e mico_bt_gatt_status_t @endlink + * + */ +mico_bt_gatt_status_t mico_bt_gatt_disconnect (uint16_t conn_id); + + +/** + * Function mico_bt_gatt_listen + * + * Start or stop LE advertisement and listen for connection. + * + * @param[in] start : TRUE to add device to whitelist / FALSE to remove + * @param[in] bd_addr : Device to add/remove from whitelist + * + * @return TRUE : Success + * FALSE : Failure + * + */ +mico_bool_t mico_bt_gatt_listen (mico_bool_t start, mico_bt_device_address_t bd_addr); + +/**@} common_api_functions*/ + +#ifdef __cplusplus +} +#endif + +/**@} micobt_gatt */ + + + diff --git a/device/bluetooth/mk3239/include/mico_bt_hidd_ble.h b/device/bluetooth/mk3239/include/mico_bt_hidd_ble.h new file mode 100644 index 0000000000..c5f13d22fc --- /dev/null +++ b/device/bluetooth/mk3239/include/mico_bt_hidd_ble.h @@ -0,0 +1,306 @@ + +/** @file + * + * Human Interface Device Profile (HID) Device over BLE + * + */ +#pragma once + +#include "mico.h" +#include "mico_bt_dev.h" +#include "hiddefs.h" + + +/****************************************************** + * Constants + ******************************************************/ + +/* HID-LE-Device Callback Events */ +enum mico_bt_hidd_ble_cback_event_e { + MICO_BT_HIDD_BLE_DEV_EVT_OPEN, /**< Connected to host with Interrupt and Control Data = 1 if Virtual Cable + Channels in OPEN state. pdata = Host BD-Addr.*/ + + MICO_BT_HIDD_BLE_DEV_EVT_CLOSE, /**< Connection with host is closed. Data=Reason Code. */ + MICO_BT_HIDD_BLE_DEV_EVT_GET_REPORT, /**< Host sent GET_REPORT Data=Length pdata=structure + having details of get-report. */ + MICO_BT_HIDD_BLE_DEV_EVT_SET_REPORT, /**< Host sent SET_REPORT Data=Length pdata=details. */ + MICO_BT_HIDD_BLE_DEV_EVT_GET_PROTO, /**< Host sent GET_PROTOCOL Data=NA */ + MICO_BT_HIDD_BLE_DEV_EVT_SET_PROTO, /**< Host sent SET_PROTOCOL Data=1 for Report, 0 for Boot */ + MICO_BT_HIDD_BLE_DEV_EVT_DATA /**< General event data */ +}; +typedef uint8_t mico_bt_hidd_ble_cback_event_t; /**< HIDD BLE callback events */ + +/* GATT application error code for HID profile */ +#define HIDD_LE_RPT_NOT_SUPT 0x8F /**< Report not supported */ + +/* HIDD type */ +#define HIDD_LE_KB_TYPE 0x01 /**< bit 0 */ +#define HIDD_LE_MICE_TYPE 0x02 /**< bit 1 */ +#define HIDD_LE_OTHER_TYPE 0x80 /**< bit 7 */ +typedef uint8_t mico_bt_hidd_ble_dev_t; /**< HIDD BLE device types */ + +#define HIDD_LE_PROTO_MODE_RPT 0x00 /**< Report protocol */ +#define HIDD_LE_PROTO_MODE_BOOT 0x01 /**< Boot protocol */ +typedef uint8_t mico_bt_hidd_ble_proto_t; /**< HIDD BLE protocol types */ + +/* LE HIDD report type */ +#define HID_LE_RPT_TYPE_INPUT 0x01 /**< Input reports */ +#define HID_LE_RPT_TYPE_OUTPUT 0x02 /**< Output reports */ +#define HID_LE_RPT_TYPE_FEATURE 0x03 /**< Feature reports */ +#define HID_LE_RPT_TYPE_KB_INPUT 0x04 /**< Keyboard input */ +#define HID_LE_RPT_TYPE_KB_OUTPUT 0x05 /**< Keyboard output */ +#define HID_LE_RPT_TYPE_MI_INPUT 0x06 /**< Mouse input */ +typedef uint8_t mico_bt_hidd_ble_rpt_t; /**< HIDD BLE report types */ + +#define HID_LE_RPT_TYPE_MAX HID_LE_RPT_TYPE_FEATURE /**< Maximun report type */ + +/****************************************************** + * Type Definitions + ******************************************************/ +enum mico_bt_hidd_ble_status { + MICO_BT_HIDD_BLE_SUCCESS, /**< Success */ + MICO_BT_HIDD_BLE_ERR_NOT_REGISTERED, /**< Not registered */ + MICO_BT_HIDD_BLE_ERR_ALREADY_REGISTERED, /**< Alreadu registered */ + MICO_BT_HIDD_BLE_ERR_NO_RESOURCES, /**< No resources */ + MICO_BT_HIDD_BLE_ERR_NO_CONNECTION, /**< Not connection */ + MICO_BT_HIDD_BLE_ERR_INVALID_PARAM, /**< Invalid parameter */ + MICO_BT_HIDD_BLE_ERR_UNSUPPORTED, /**< Not supported */ + MICO_BT_HIDD_BLE_ERR_UNKNOWN_COMMAND, /**< Unknown command */ + MICO_BT_HIDD_BLE_ERR_CONGESTED, /**< Congested */ + MICO_BT_HIDD_BLE_ERR_CONN_IN_PROCESS, /**< Connection in process */ + MICO_BT_HIDD_BLE_ERR_ALREADY_CONN, /**< Already connected */ + MICO_BT_HIDD_BLE_ERR_DISCONNECTING, /**< Disconnecting is process */ + MICO_BT_HIDD_BLE_ERR_SET_CONNABLE_FAIL, /**< Set connectable failiure */ + /* Device specific error codes */ + MICO_BT_HIDD_BLE_ERR_HOST_UNKNOWN, /**< Host unknown */ + MICO_BT_HIDD_BLE_ERR_L2CAP_FAILED, /**< L2CAP failed */ + MICO_BT_HIDD_BLE_ERR_AUTH_FAILED, /**< Authentication failed */ + MICO_BT_HIDD_BLE_ERR_SDP_BUSY, /**< SDP busy */ + MICO_BT_HIDD_BLE_ERR_GATT, /**< GATT */ + + MICO_BT_HIDD_BLE_ERR_INVALID = 0xFF /**< Invalid */ +}; +typedef uint8_t mico_bt_hidd_ble_status_t; /**< HIDD BLE status codes */ + +/* report reference descriptor value */ +typedef struct { + uint8_t rpt_id; /**< Report ID */ + mico_bt_hidd_ble_rpt_t rpt_type; /**< Report type */ +} mico_bt_hidd_ble_rpt_ref_t; /**< HIDD BLE report reference */ + +/* LE HIDD registration information */ +typedef struct { + mico_bt_hidd_ble_dev_t dev_type; /**< Device type */ + uint8_t num_rpt; /**< Number of reports */ + uint16_t battery_handle; /**< Battery handle */ + mico_bt_hidd_ble_rpt_ref_t *p_rpt_lst; /**< Pointer to the report reference */ + mico_bt_hidd_ble_proto_t proto_cap; /**< Protocol capability */ + +} mico_bt_hidd_ble_dev_info_t; /**< HIDD BLE device info */ + +#define HIDD_LE_REMOTE_WAKE 0x01 /**< Remote wake */ +#define HIDD_LE_NORMAL_CONN 0x02 /**< Normally connectable */ + +typedef struct { + uint16_t dl_len; /**< Description length */ + uint8_t *dsc_list; /**< Pointer to the description */ +} mico_bt_hidd_ble_dscp_info_t; /**< HIDD BLE description info */ + +/* LE HIDD report map info */ +typedef struct { + uint16_t bcdHID; /**< HID info in BCD format */ + uint8_t contry_code; /**< Country code */ + uint8_t flags; /**< HID info in BCD format */ + mico_bt_hidd_ble_dscp_info_t rpt_map; /**< Report map */ +} mico_bt_hidd_ble_rpt_map_info_t; /**< HIDD BLE report map info */ + +#define HIDD_REPT_ID_BOOT_KB 1 +#define HIDD_REPT_ID_BOOT_MOUSE 2 + +typedef struct { + uint16_t event; /**< event */ + uint16_t len; /**< length */ + uint16_t offset; /**< offset */ + uint16_t layer_specific; /**< lay_specific */ +} mico_bt_hidd_bt_hdr_t; /**< General data in BT_HDR type */ + +/* LE HIDD report data */ +typedef struct { + mico_bt_hidd_bt_hdr_t hdr; /**< report data, assuming the first byte of data is report ID */ + uint8_t rpt_id; /**< report ID */ +} mico_bt_hidd_ble_rpt_data_t; /**< HIDD BLE report data */ + +/* LE HIDD get report data */ +typedef struct { + uint8_t rep_type; /**< HIDD BLE report type */ + uint8_t rep_id; /**< HIDD BLE report ID */ +} mico_bt_hidd_ble_get_rpt_data_t; /**< HIDD BLE get report data */ + +/* LE HIDD cback data */ +typedef union { + mico_bt_device_address_t host_bdaddr; /**< Host BD-ADDR */ + mico_bt_hidd_ble_get_rpt_data_t get_rpt; /**< Get report */ + mico_bt_hidd_ble_rpt_data_t *p_buffer; /**< General report data */ +} mico_bt_hidd_ble_cback_data_t; /**< HIDD BLE callback data */ + +/** + * HIDD LE callback + * + * Callback for Human Interface Device Profile Device (HIDD) + * + * @param[in] event : Callback event + * @param[in] data : Integer data corresponding to the event + * @param[in] p_data : Callback data + * + * @return void + */ +typedef void (mico_bt_hidd_ble_cback_t) (uint8_t event, + uint32_t data, + mico_bt_hidd_ble_cback_data_t *p_data ); +/* HIDD LE registration info */ +typedef struct { + mico_bt_device_address_t host_addr; /**< Host BD-ADDR */ + mico_bt_hidd_ble_dev_info_t dev_info; /**< Device info */ + mico_bt_hidd_ble_cback_t *app_cback; /**< Callback function */ +} mico_bt_hidd_ble_reg_info_t; /**< HIDD BLE registration info */ + + +/** + * @addtogroup hidd_le_api_functions HIDD over BLE + * @ingroup micobt + * + * HIDD LE Functions + * + * @{ + */ + +/****************************************************** + * Function Declarations + ******************************************************/ +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * Function mico_bt_hidd_ble_init + * + * Initialize HIDD LE control block and trace variable. + * + * @param[in] None + * @param[out] None + * + * @return None + */ +void mico_bt_hidd_ble_init (void); + +/** + * Function mico_bt_hidd_ble_register + * + * This function must be called at startup to register info related + * to HIDD over LE. + * + * + * @param[in] p_reg_info : SCO index to remove + * @param[out] None + * + * @return status code (see #mico_bt_hidd_ble_status_t) + */ +mico_bt_hidd_ble_status_t mico_bt_hidd_ble_register(mico_bt_hidd_ble_reg_info_t *p_reg_info); + +/** + * Function mico_bt_hidd_ble_deregister + * + * Disable HIDD service. + * + * @param[in] None + * @param[out] None + * + * @return status code (see #mico_bt_hidd_ble_status_t) + */ +mico_bt_hidd_ble_status_t mico_bt_hidd_ble_deregister(void); + +/** + * Function mico_bt_hidd_ble_connect + * + * Initiates a connection to the host. + * + * @param[in] None + * @param[out] None + * + * @return status code (see #mico_bt_hidd_ble_status_t) + */ +mico_bt_hidd_ble_status_t mico_bt_hidd_ble_connect(void); + +/** + * Function mico_bt_hidd_ble_disconnect + * + * Disconnects from the host. + * + * @param[in] None + * @param[out] None + * + * @return status code (see #mico_bt_hidd_ble_status_t) + */ +mico_bt_hidd_ble_status_t mico_bt_hidd_ble_disconnect(void); + +/** + * Function mico_bt_hidd_ble_send_report + * + * Sends report data to the host. + * + * @param[in] rep_type : Report type + * @param[in] rep_id : Report ID + * @param[in] len : Length of the data + * @param[in] offset : Offset of the data + * @param[in] p_rpt : Pointer to the report data + * @param[out] None + * + * @return status code (see #mico_bt_hidd_ble_status_t) + */ +mico_bt_hidd_ble_status_t mico_bt_hidd_ble_send_report(uint8_t rep_type, uint8_t rpt_id, + uint16_t len, uint16_t offset, uint8_t *p_rpt); + +/** + * Function mico_bt_hidd_ble_hand_shake + * + * Acks a set report request + * + * @param[in] status code (see #mico_bt_hidd_ble_status_t) + * @param[out] None + * + * @return status code (see #mico_bt_hidd_ble_status_t) + */ +mico_bt_hidd_ble_status_t mico_bt_hidd_ble_hand_shake(mico_bt_hidd_ble_status_t status); + +/** + * Function mico_bt_hidd_ble_rsp_get_protocol + * + * Responds to a get protocol mode request + * + * @param[in] cur_mode : Current protocol + * @param[out] None + * + * @return status code (see #mico_bt_hidd_ble_status_t) + */ +mico_bt_hidd_ble_status_t mico_bt_hidd_ble_rsp_get_protocol(mico_bt_hidd_ble_proto_t cur_mode); + +/** + * Function mico_bt_hidd_ble_set_rsp_map_info + * + * This function shall be called at startup to configure the + * device HID information and report map + * + * + * @param[in] p_dev_info : Device map info + * @param[out] None + * + * @return status code (see #mico_bt_hidd_ble_status_t) + */ +mico_bt_hidd_ble_status_t mico_bt_hidd_ble_set_rsp_map_info(mico_bt_hidd_ble_rpt_map_info_t *p_dev_info); + +#ifdef __cplusplus +} +#endif + +/** @} micobt_hidd_ble */ diff --git a/device/bluetooth/mk3239/include/mico_bt_int.h b/device/bluetooth/mk3239/include/mico_bt_int.h new file mode 100644 index 0000000000..d8d37f2f13 --- /dev/null +++ b/device/bluetooth/mk3239/include/mico_bt_int.h @@ -0,0 +1,75 @@ + +#pragma once + +/* MiCO -> BTE Conversion */ +#define int8_t INT8 +#define int16_t INT16 +#define int32_t INT32 +#define uint8_t UINT8 +#define uint16_t UINT16 +#define uint32_t UINT32 +#define mico_bool_t BOOLEAN + +#define mico_bt_dev_status_t tBTM_STATUS +#define mico_bt_management_evt_t tBTM_EVENT +#define mico_bt_dev_class_t DEV_CLASS +#define mico_bt_device_address_t BD_ADDR +#define mico_bt_device_address_ptr_t BD_ADDR_PTR +#define mico_bt_dev_io_cap_t tBTM_IO_CAP +#define mico_bt_dev_oob_data_t tBTM_OOB_DATA +#define mico_bt_dev_le_auth_req_t tBTM_LE_AUTH_REQ +#define mico_bt_dev_le_key_type_t tBTM_LE_KEY_TYPE +#define mico_bt_dev_auth_req_t tBTM_AUTH_REQ +#define mico_bt_device_type_t tBT_DEVICE_TYPE +#define mico_bt_dev_bonded_device_info_t tBT_BONDED_DEVICE_INFO_TYPE +#define mico_bt_security_key_value_t tBTM_SEC_KEY_VALUE +#define mico_bt_transport_t tBT_TRANSPORT +#define mico_bt_ble_address_t tBLE_BD_ADDR +#define mico_bt_ble_address_type_t tBLE_ADDR_TYPE +#define mico_bt_ble_conn_mode_t tBLE_CONN_MODE +#define mico_bt_dev_passkey_entry_type_t tBTM_SP_KEY_TYPE +#define mico_bt_connection_status_change_cback_t tBTM_ACL_DB_CHANGE_CB /* modified from bte */ +#define mico_bt_dev_inq_parms_t tBTM_INQ_PARMS /* modified from bte */ +#define mico_bt_dev_inquiry_scan_result_t tBTM_INQ_RESULTS /* modified from bte */ +#define mico_bt_inquiry_result_cback_t tBTM_INQ_RESULTS_CB +#define mico_bt_dev_vendor_specific_command_complete_cback_t tBTM_VSC_CMPL_CB +#ifndef mico_bt_dev_vendor_specific_command_complete_params_t +#define mico_bt_dev_vendor_specific_command_complete_params_t tBTM_VSC_CMPL +#endif +#define mico_bt_ble_advert_mask_t tBTM_BLE_AD_MASK +#define mico_bt_ble_advert_data_t tBTM_BLE_ADV_DATA +#define mico_bt_ble_conn_type_t tBTM_BLE_CONN_TYPE +#define mico_bt_ble_selective_conn_cback_t tBTM_BLE_SEL_CBACK +#define mico_bt_ble_scan_type_t tBTM_BLE_SCAN_TYPE /* new */ +#define mico_bt_ble_advert_mode_t tBTM_BLE_AVERT_MODE /* new */ +#define mico_bt_ble_scan_result_cback_t tBTM_BLE_SCAN_RESULT_CBACK /* new */ +#define mico_bt_ble_scan_results_t tBTM_BLE_SCAN_RESULT /* new */ +#define mico_bt_ble_scan_mode_t tBTM_BLE_SCAN_MODE +#define mico_bt_ble_advert_chnl_map_t tBTM_BLE_ADV_CHNL_MAP +#define mico_dev_ble_signature_t BLE_SIGNATURE +#define mico_bt_ble_advert_filter_policy_t tBTM_BLE_AFP +#define mico_bt_device_link_keys_t tBTM_PAIRED_DEVICE_LINK_KEYS +#define mico_bt_local_identity_keys_t tBTM_LOCAL_IDENTITY_KEYS + +/* l2cap mico-to-bte translation */ +#define mico_bt_l2c_appl_info_t tL2CAP_APPL_INFO +#define mico_bt_l2c_fixed_chnl_reg_t tL2CAP_FIXED_CHNL_REG +#define mico_bt_l2cap_le_appl_information_t tL2CAP_LE_APPL_INFO +#define mico_bt_l2c_cfg_info_t tL2CAP_CFG_INFO +#define mico_bt_l2c_ch_cfg_bits_t tL2CAP_CH_CFG_BITS +#define mico_bt_l2cap_ertm_information_t tL2CAP_ERTM_INFO +#define mico_bt_l2cap_chnl_priority_t tL2CAP_CHNL_PRIORITY +#define mico_bt_l2cap_nocp_cback_t tL2CA_NOCP_CB +#define mico_bt_l2cap_chnl_data_rate_t tL2CAP_CHNL_DATA_RATE + +#define mico_bt_gatt_appearance_t tGATT_APPEARANCE +#define mico_bt_gatt_status_t tGATT_STATUS +#define mico_bt_gatt_write_t tGATT_WRITE_REQ +#define mico_bt_gatt_read_t tGATT_READ_REQ +#define mico_bt_gatt_exec_flag_t tGATT_EXEC_FLAG + +#define mico_bt_hidd_status_t tHID_STATUS +#define mico_bt_hidd_reg_info_t tHID_DEV_REG_INFO +#define mico_bt_hidd_callback_t tHID_DEV_CBACK_DATA + +#define mico_bt_sco_enh_esco_params_t tBTM_ENH_ESCO_PARAMS diff --git a/kernel/protocols/bluetooth/include/aos_bt_l2c.h b/device/bluetooth/mk3239/include/mico_bt_l2c.h similarity index 60% rename from kernel/protocols/bluetooth/include/aos_bt_l2c.h rename to device/bluetooth/mk3239/include/mico_bt_l2c.h index e747c0c1be..2866858d5e 100644 --- a/kernel/protocols/bluetooth/include/aos_bt_l2c.h +++ b/device/bluetooth/mk3239/include/mico_bt_l2c.h @@ -1,8 +1,5 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ -/* @file +/** @file * * Bluetooth L2CAP Application Programming Interface * @@ -14,17 +11,16 @@ * @defgroup l2cap Logical Link Control and Adaptaion Protocol (L2CAP) * */ - -#ifndef _AOS_BT_L2C_H_ -#define _AOS_BT_L2C_H_ +#pragma once #include "bt_target.h" #include "l2cdefs.h" #include "hcidefs.h" -#include "aos_bt_types.h" -#include "aos_bt_ble.h" +#include "mico_bt_types.h" +#include "mico_bt_ble.h" -/* + +/** * @addtogroup l2cap_data_types Data Types * @ingroup l2cap * @@ -32,7 +28,7 @@ * * @{ */ -/**************************************************************************** +/***************************************************************************** * Constants ****************************************************************************/ @@ -40,56 +36,56 @@ * HCI type(1), len(2), handle(2), L2CAP len(2) and CID(2) => 9 */ -#define L2CAP_MINIMUM_OFFSET 13 /* plus control(2), SDU length(2) */ +#define L2CAP_MINIMUM_OFFSET 13 /**< plus control(2), SDU length(2) */ -#define L2CAP_BLE_CONN_MIN_OFFSET 9 /* HCI type(1), len(2), handle(2), L2CAP len(2) and CID(2) */ -#define L2CAP_DEFAULT_BLE_CB_POOL_ID 0xFF /* Use the default HCI ACL buffer pool */ -#define L2CAP_BLE_COC_SDU_OFFSET 4 /* to provide upper layer some minimal offset possibly required +#define L2CAP_BLE_CONN_MIN_OFFSET 9 /**< HCI type(1), len(2), handle(2), L2CAP len(2) and CID(2) */ +#define L2CAP_DEFAULT_BLE_CB_POOL_ID 0xFF /**< Use the default HCI ACL buffer pool */ +#define L2CAP_BLE_COC_SDU_OFFSET 4 /**< to provide upper layer some minimal offset possibly required ** to process incoming packets */ #define L2CAP_BLE_TX_CONG_START_THRESH 3 #define L2CAP_BLE_TX_CONG_STOP_THRESH 1 -/* Minimum offset for broadcast needs another two bytes for the PSM */ +/** Minimum offset for broadcast needs another two bytes for the PSM */ #define L2CAP_BROADCAST_MIN_OFFSET 11 -/* Ping result codes */ -#define L2CAP_PING_RESULT_OK 0 /* Ping reply received OK */ -#define L2CAP_PING_RESULT_NO_LINK 1 /* Link could not be setup */ -#define L2CAP_PING_RESULT_NO_RESPONSE 2 /* Remote L2CAP did not reply */ +/** Ping result codes */ +#define L2CAP_PING_RESULT_OK 0 /**< Ping reply received OK */ +#define L2CAP_PING_RESULT_NO_LINK 1 /**< Link could not be setup */ +#define L2CAP_PING_RESULT_NO_RESPONSE 2 /**< Remote L2CAP did not reply */ -/* Result codes for aos_bt_l2cap_data_write() */ +/** Result codes for mico_bt_l2cap_data_write() */ #define L2CAP_DATAWRITE_FAILED FALSE #define L2CAP_DATAWRITE_SUCCESS TRUE #define L2CAP_DATAWRITE_CONGESTED 2 -/* Values for priority parameter to aos_bt_l2cap_set_acl_priority */ +/** Values for priority parameter to mico_bt_l2cap_set_acl_priority */ #define L2CAP_PRIORITY_NORMAL 0 #define L2CAP_PRIORITY_HIGH 1 -/* Values for direction parameter to aos_bt_l2cap_set_acl_priority */ -#define L2CAP_DIRECTION_IGNORE 0 /* Set ACL priority direction as ignore */ -#define L2CAP_DIRECTION_DATA_SOURCE 1 /* Set ACL priority direction as source */ -#define L2CAP_DIRECTION_DATA_SINK 2 /* Set ACL priority direction as sink */ +/** Values for direction parameter to mico_bt_l2cap_set_acl_priority */ +#define L2CAP_DIRECTION_IGNORE 0 /**< Set ACL priority direction as ignore */ +#define L2CAP_DIRECTION_DATA_SOURCE 1 /**< Set ACL priority direction as source */ +#define L2CAP_DIRECTION_DATA_SINK 2 /**< Set ACL priority direction as sink */ -/* Values for priority parameter to aos_bt_l2cap_set_tx_priority */ +/** Values for priority parameter to mico_bt_l2cap_set_tx_priority */ #define L2CAP_CHNL_PRIORITY_HIGH 0 #define L2CAP_CHNL_PRIORITY_MEDIUM 1 #define L2CAP_CHNL_PRIORITY_LOW 2 -typedef uint8_t aos_bt_l2cap_chnl_priority_t; +typedef uint8_t mico_bt_l2cap_chnl_priority_t; -/* Values for Tx/Rx data rate parameter to aos_bt_l2cap_set_chnl_data_rate */ +/** Values for Tx/Rx data rate parameter to mico_bt_l2cap_set_chnl_data_rate */ #define L2CAP_CHNL_DATA_RATE_HIGH 3 #define L2CAP_CHNL_DATA_RATE_MEDIUM 2 #define L2CAP_CHNL_DATA_RATE_LOW 1 #define L2CAP_CHNL_DATA_RATE_NO_TRAFFIC 0 -typedef uint8_t aos_bt_l2cap_chnl_data_rate_t; +typedef uint8_t mico_bt_l2cap_chnl_data_rate_t; -/* Data Packet Flags (bits 2-15 are reserved) +/** Data Packet Flags (bits 2-15 are reserved) * layer specific 14-15 bits are used for FCR SAR. - * Used in call to aos_bt_l2cap_data_write() + * Used in call to mico_bt_l2cap_data_write() */ #define L2CAP_FLUSHABLE_MASK 0x0003 #define L2CAP_FLUSHABLE_CH_BASED 0x0000 @@ -97,33 +93,33 @@ typedef uint8_t aos_bt_l2cap_chnl_data_rate_t; #define L2CAP_NON_FLUSHABLE_PACKET 0x0002 -/* Used in aos_bt_l2cap_flush_channel num_to_flush definitions */ +/** Used in mico_bt_l2cap_flush_channel num_to_flush definitions */ #define L2CAP_FLUSH_CHANNELS_ALL 0xffff #define L2CAP_FLUSH_CHANNELS_GET 0x0000 -/* Definition used for aos_bt_l2cap_set_desire_role */ +/** Definition used for mico_bt_l2cap_set_desire_role */ #define L2CAP_ROLE_SLAVE HCI_ROLE_SLAVE #define L2CAP_ROLE_MASTER HCI_ROLE_MASTER -#define L2CAP_ROLE_ALLOW_SWITCH 0x80 /* set this bit to allow switch at create conn */ -#define L2CAP_ROLE_DISALLOW_SWITCH 0x40 /* set this bit to disallow switch at create conn */ +#define L2CAP_ROLE_ALLOW_SWITCH 0x80 /**< set this bit to allow switch at create conn */ +#define L2CAP_ROLE_DISALLOW_SWITCH 0x40 /**< set this bit to disallow switch at create conn */ #define L2CAP_ROLE_CHECK_SWITCH 0xC0 -/* Values for 'allowed_modes' field passed in structure aos_bt_l2cap_ertm_information_t */ +/** Values for 'allowed_modes' field passed in structure mico_bt_l2cap_ertm_information_t */ #define L2CAP_FCR_CHAN_OPT_BASIC (1 << L2CAP_FCR_BASIC_MODE) #define L2CAP_FCR_CHAN_OPT_ERTM (1 << L2CAP_FCR_ERTM_MODE) #define L2CAP_FCR_CHAN_OPT_STREAM (1 << L2CAP_FCR_STREAM_MODE) #define L2CAP_FCR_CHAN_OPT_ALL_MASK (L2CAP_FCR_CHAN_OPT_BASIC | L2CAP_FCR_CHAN_OPT_ERTM | L2CAP_FCR_CHAN_OPT_STREAM) -/* Validity check for PSM. PSM values must be odd. Also, all PSM values must +/** Validity check for PSM. PSM values must be odd. Also, all PSM values must * be assigned such that the least significant bit of the most sigificant * octet equals zero. */ #define L2C_INVALID_PSM(psm) (((psm) & 0x0101) != 0x0001) #define L2C_IS_VALID_PSM(psm) (((psm) & 0x0101) == 0x0001) -/* Validity check for LE_PSM. +/** Validity check for LE_PSM. * Fixed LE_PSMs are in the range 0x0001 - 0x007F. * Dynamic LE_PSM are in the range 0x0080 - 0x00FF. * The values 0x0000 and 0x0100 - 0xFFFF are reserved. @@ -134,44 +130,44 @@ typedef uint8_t aos_bt_l2cap_chnl_data_rate_t; #define L2C_BLE_IS_VALID_PSM(le_psm) (((le_psm) != 0) && ((le_psm) <= MAX_LE_PSM)) -/**************************************************************************** +/***************************************************************************** * Type Definitions ****************************************************************************/ -/* Structure for Enhanced Retransmission Mode Options +/** Structure for Enhanced Retransmission Mode Options * Refer to Volume 3, Part A, section 5.4 of BT Core specification for details */ typedef struct { #define L2CAP_FCR_BASIC_MODE 0x00 #define L2CAP_FCR_ERTM_MODE 0x03 #define L2CAP_FCR_STREAM_MODE 0x04 - uint8_t mode; /* Requested mode of link */ - uint8_t tx_window_size; /* Maximum transmit window size (1..63) */ - uint8_t max_transmit; /* Maximum number of trasmission attempts */ - uint16_t rtrans_timeout; /* Retransmission timeout (msecs) */ - uint16_t monitor_timeout; /* Monitor timeout (msecs) */ - uint16_t max_pdu_size; /* Maximum PDU payload size */ -} aos_bt_l2cap_fcr_options_t; + uint8_t mode; /**< Requested mode of link */ + uint8_t tx_window_size; /**< Maximum transmit window size (1..63) */ + uint8_t max_transmit; /**< Maximum number of trasmission attempts */ + uint16_t rtrans_timeout; /**< Retransmission timeout (msecs) */ + uint16_t monitor_timeout; /**< Monitor timeout (msecs) */ + uint16_t max_pdu_size; /**< Maximum PDU payload size */ +} mico_bt_l2cap_fcr_options_t; -/* Define a structure to hold the configuration parameters. Since the +/** Define a structure to hold the configuration parameters. Since the * parameters are optional, for each parameter there is a boolean to * use to signify its presence or absence. * Refer to Volume 3, Part A, section 5.4 of BT Core specification for details */ typedef struct { - uint16_t result; /* Only used in confirm messages */ - aos_bool_t mtu_present; /* TRUE if MTU option present */ - uint16_t mtu; /* Maximum transmission unit size */ - aos_bool_t qos_present; /* QoS configuration present */ - aos_bt_flow_spec_t qos; /* QoS configuration */ - aos_bool_t flush_timeout_present; /* TRUE if flush option present */ - uint16_t flush_timeout; /* Flush timeout value (1 msec increments) */ - aos_bool_t fcr_present; /* TRUE if Enhanced retransmission & flow control option present */ - aos_bt_l2cap_fcr_options_t fcr; /* Enhanced flow control and retransmission parameters */ - aos_bool_t fcs_present; /* TRUE if Frame check sequence option present */ - uint8_t fcs; /* '0' if desire is to bypass FCS, otherwise '1' */ - uint16_t flags; /* bit 0: 0-no continuation, 1-continuation */ -} aos_bt_l2cap_cfg_information_t; + uint16_t result; /**< Only used in confirm messages */ + mico_bool_t mtu_present; /**< TRUE if MTU option present */ + uint16_t mtu; /**< Maximum transmission unit size */ + mico_bool_t qos_present; /**< QoS configuration present */ + mico_bt_flow_spec_t qos; /**< QoS configuration */ + mico_bool_t flush_timeout_present; /**< TRUE if flush option present */ + uint16_t flush_timeout; /**< Flush timeout value (1 msec increments) */ + mico_bool_t fcr_present; /**< TRUE if Enhanced retransmission & flow control option present */ + mico_bt_l2cap_fcr_options_t fcr; /**< Enhanced flow control and retransmission parameters */ + mico_bool_t fcs_present; /**< TRUE if Frame check sequence option present */ + uint8_t fcs; /**< '0' if desire is to bypass FCS, otherwise '1' */ + uint16_t flags; /**< bit 0: 0-no continuation, 1-continuation */ +} mico_bt_l2cap_cfg_information_t; /* L2CAP channel configured field bitmap */ #define L2CAP_CH_CFG_MASK_MTU 0x0001 @@ -181,90 +177,90 @@ typedef struct { #define L2CAP_CH_CFG_MASK_FCS 0x0010 #define L2CAP_CH_CFG_MASK_EXT_FLOW_SPEC 0x0020 -typedef uint16_t aos_bt_l2cap_ch_cfg_bits_t; +typedef uint16_t mico_bt_l2cap_ch_cfg_bits_t; -/* Structure that applications use to create or accept +/** Structure that applications use to create or accept * connections with enhanced retransmission mode. */ typedef struct { - uint8_t preferred_mode; /* Preferred mode: ERTM, Streaming, or Basic */ - uint8_t allowed_modes; /* Bitmask for allowed modes */ - uint8_t user_rx_pool_id; /* TODO */ - uint8_t user_tx_pool_id; /* TODO */ - uint8_t fcr_rx_pool_id; /* TODO */ - uint8_t fcr_tx_pool_id; /* TODO */ + uint8_t preferred_mode; /**< Preferred mode: ERTM, Streaming, or Basic */ + uint8_t allowed_modes; /**< Bitmask for allowed modes */ + uint8_t user_rx_pool_id; /**< TODO */ + uint8_t user_tx_pool_id; /**< TODO */ + uint8_t fcr_rx_pool_id; /**< TODO */ + uint8_t fcr_tx_pool_id; /**< TODO */ -} aos_bt_l2cap_ertm_information_t; +} mico_bt_l2cap_ertm_information_t; -/*@} Data Types */ +/**@} Data Types */ -/******************************** +/********************************* * Callback Functions Prototypes *********************************/ -/* +/** * Connection established callback prototype. * - * @param context : Caller context provided with aos_bt_l2cap_register() + * @param context : Caller context provided with mico_bt_l2cap_register() * @param bd_addr : BD Address of remote * @param local_cid : Local CID assigned to the connection * @param peer_mtu : Peer MTU * * @return void */ -typedef void (aos_bt_l2cap_connected_cback_t) (void *context, aos_bt_device_address_t bd_addr, uint16_t local_cid, - uint16_t peer_mtu); +typedef void (mico_bt_l2cap_connected_cback_t) (void *context, mico_bt_device_address_t bd_addr, uint16_t local_cid, + uint16_t peer_mtu); -/* +/** * Disconnect indication callback prototype. * - * @param context : Caller context provided with aos_bt_l2cap_register() + * @param context : Caller context provided with mico_bt_l2cap_register() * @param local_cid : Local CID * @param ack : Boolean whether upper layer should ack this * * @return void */ -typedef void (aos_bt_l2cap_disconnect_indication_cback_t) (void *context, uint16_t local_cid, aos_bool_t ack); +typedef void (mico_bt_l2cap_disconnect_indication_cback_t) (void *context, uint16_t local_cid, mico_bool_t ack); -/* +/** * Disconnect confirm callback prototype. * - * @param context : Caller context provided with aos_bt_l2cap_register() + * @param context : Caller context provided with mico_bt_l2cap_register() * @param local_cid : Local CID * @param result : Result * * @return void */ -typedef void (aos_bt_l2cap_disconnect_confirm_cback_t) (void *context, uint16_t local_cid, uint16_t result); +typedef void (mico_bt_l2cap_disconnect_confirm_cback_t) (void *context, uint16_t local_cid, uint16_t result); -/* +/** * Data received indication callback prototype. * - * @param context : Caller context provided with aos_bt_l2cap_register() + * @param context : Caller context provided with mico_bt_l2cap_register() * @param local_cid : Local CID * @param p_addr_buff : Address of buffer * * @return void */ -typedef void (aos_bt_l2cap_data_indication_cback_t) (void *context, uint16_t local_cid, uint8_t *p_buff, - uint16_t buf_len); +typedef void (mico_bt_l2cap_data_indication_cback_t) (void *context, uint16_t local_cid, uint8_t *p_buff, + uint16_t buf_len); -/* +/** * Congestion status callback protype. This callback is optional. If * an application tries to send data when the transmit queue is full, * the data will anyways be dropped. * - * @param context : Caller context provided with aos_bt_l2cap_register() + * @param context : Caller context provided with mico_bt_l2cap_register() * @param local_cid : Local CID * @param congested : TRUE if congested, FALSE if uncongested * * @return void */ -typedef void (aos_bt_l2cap_congestion_status_cback_t) (void *context, uint16_t local_cid, aos_bool_t congested); +typedef void (mico_bt_l2cap_congestion_status_cback_t) (void *context, uint16_t local_cid, mico_bool_t congested); -/* +/** * Callback prototype for number of packets completed events. * This callback notifies the application when Number of Completed Packets (nocp) * event has been received. @@ -274,23 +270,23 @@ typedef void (aos_bt_l2cap_congestion_status_cback_t) (void *context, uint16_t l * * @return void */ -typedef void (aos_bt_l2cap_nocp_cback_t) (aos_bt_device_address_t bd_addr); +typedef void (mico_bt_l2cap_nocp_cback_t) (mico_bt_device_address_t bd_addr); -/* +/** * Transmit complete callback protype. This callback is optional. If * set, L2CAP will call it when packets are sent or flushed. If the * count is 0xFFFF, it means all packets are sent for that CID (eRTM * mode only). * - * @param context : Caller context provided with aos_bt_l2cap_register() + * @param context : Caller context provided with mico_bt_l2cap_register() * @param local_cid : Local CID * @param num_sdu : Number of SDUs sent or dropped * * @return void */ -typedef void (aos_bt_l2cap_tx_complete_cback_t) (void *context, uint16_t local_cid, uint16_t num_sdu); +typedef void (mico_bt_l2cap_tx_complete_cback_t) (void *context, uint16_t local_cid, uint16_t num_sdu); -/* +/** * Define the structure that applications use to register with * L2CAP. This structure includes callback functions. All functions * MUST be provided, with the exception of the "connect pending" @@ -299,24 +295,24 @@ typedef void (aos_bt_l2cap_tx_complete_cback_t) (void *context, uint16_t local_c * be NULL since dynamic PSMs use this as a flag for "virtual PSM". */ typedef struct { - aos_bt_l2cap_connected_cback_t *connected_cback; /* BR/EDR connected event */ - aos_bt_l2cap_disconnect_indication_cback_t *disconnect_indication_cback; /* BR/EDR disconnect indication event */ - aos_bt_l2cap_disconnect_confirm_cback_t *disconnect_confirm_cback; /* BR/EDR disconnect confirmation event */ - aos_bt_l2cap_data_indication_cback_t *data_indication_cback; /* BR/EDR data received indication */ - aos_bt_l2cap_congestion_status_cback_t *congestion_status_cback; /* Connection (un)congested event */ - aos_bt_l2cap_tx_complete_cback_t *tx_complete_cback; /* BR/EDR transmit complete event */ + mico_bt_l2cap_connected_cback_t *connected_cback; /**< BR/EDR connected event */ + mico_bt_l2cap_disconnect_indication_cback_t *disconnect_indication_cback; /**< BR/EDR disconnect indication event */ + mico_bt_l2cap_disconnect_confirm_cback_t *disconnect_confirm_cback; /**< BR/EDR disconnect confirmation event */ + mico_bt_l2cap_data_indication_cback_t *data_indication_cback; /**< BR/EDR data received indication */ + mico_bt_l2cap_congestion_status_cback_t *congestion_status_cback; /**< Connection (un)congested event */ + mico_bt_l2cap_tx_complete_cback_t *tx_complete_cback; /**< BR/EDR transmit complete event */ uint16_t mtu; - aos_bool_t qos_present; - aos_bt_flow_spec_t qos; - aos_bool_t flush_timeout_present; + mico_bool_t qos_present; + mico_bt_flow_spec_t qos; + mico_bool_t flush_timeout_present; uint16_t flush_timeout; - aos_bool_t fcr_present; - aos_bt_l2cap_fcr_options_t fcr; - aos_bool_t fcs_present; - uint8_t fcs; /* '0' if desire is to bypass FCS, otherwise '1' */ - aos_bool_t is_ob_only; /* Set to TRUE if registration is for outbound only to a dynamic PSM */ -} aos_bt_l2cap_appl_information_t; + mico_bool_t fcr_present; + mico_bt_l2cap_fcr_options_t fcr; + mico_bool_t fcs_present; + uint8_t fcs; /**< '0' if desire is to bypass FCS, otherwise '1' */ + mico_bool_t is_ob_only; /**< Set to TRUE if registration is for outbound only to a dynamic PSM */ +} mico_bt_l2cap_appl_information_t; /* * @@ -324,7 +320,7 @@ typedef struct { * */ -/* +/** * Fixed channel connected and disconnected. * * @param bd_addr : BD Address of remote @@ -334,10 +330,10 @@ typedef struct { * * @return void */ -typedef void (aos_bt_l2cap_fixed_chnl_cback_t) (aos_bt_device_address_t bd_addr, aos_bool_t connected, - uint16_t reason, tBT_TRANSPORT transport); +typedef void (mico_bt_l2cap_fixed_chnl_cback_t) (mico_bt_device_address_t bd_addr, mico_bool_t connected, + uint16_t reason, tBT_TRANSPORT transport); -/* +/** * Signalling data received. * * @param bd_addr : BD Address of remote @@ -345,35 +341,35 @@ typedef void (aos_bt_l2cap_fixed_chnl_cback_t) (aos_bt_device_address_t bd_addr, * * @return void */ -typedef void (aos_bt_l2cap_fixed_data_cback_t) (aos_bt_device_address_t bd_addr, uint8_t *p_buff, uint16_t buf_len); +typedef void (mico_bt_l2cap_fixed_data_cback_t) (mico_bt_device_address_t bd_addr, uint8_t *p_buff, uint16_t buf_len); -/* +/** * Congestion status callback protype. This callback is optional. If * an application tries to send data when the transmit queue is full, * the data will anyways be dropped. * - * @param bd_addr : remote aos_bt_device_address_t + * @param bd_addr : remote mico_bt_device_address_t * @param congested : TRUE if congested, FALSE if uncongested * * @return void */ -typedef void (aos_bt_l2cap_fixed_congestion_status_cback_t) (aos_bt_device_address_t bd_addr, aos_bool_t congested); +typedef void (mico_bt_l2cap_fixed_congestion_status_cback_t) (mico_bt_device_address_t bd_addr, mico_bool_t congested); -/* +/** * Fixed channel registration info (the callback addresses and channel config) */ typedef struct { - aos_bt_l2cap_fixed_chnl_cback_t *fixed_conn_cback; /* TODO */ - aos_bt_l2cap_fixed_data_cback_t *fixed_data_cback; /* TODO */ - aos_bt_l2cap_fixed_congestion_status_cback_t *fixed_cong_cback; /* TODO */ + mico_bt_l2cap_fixed_chnl_cback_t *fixed_conn_cback; /**< TODO */ + mico_bt_l2cap_fixed_data_cback_t *fixed_data_cback; /**< TODO */ + mico_bt_l2cap_fixed_congestion_status_cback_t *fixed_cong_cback; /**< TODO */ - uint16_t default_idle_timeout; /* TODO */ -} aos_bt_l2cap_fixed_chnl_reg_t; + uint16_t default_idle_timeout; /**< TODO */ +} mico_bt_l2cap_fixed_chnl_reg_t; -/* +/** * LE Connection indication callback prototype. * - * @param context : Caller context provided with aos_bt_l2cap_le_register() + * @param context : Caller context provided with mico_bt_l2cap_le_register() * @param bd_addr : BD Address of remote * @param local_cid : Local CID assigned to the connection * @param psm : PSM that the remote wants to connect to @@ -382,35 +378,35 @@ typedef struct { * * @return void */ -typedef void (aos_bt_l2cap_le_connect_indication_cback_t) (void *context, aos_bt_device_address_t bd_addr, - uint16_t local_cid, uint16_t psm, uint8_t id, uint16_t mtu_peer); +typedef void (mico_bt_l2cap_le_connect_indication_cback_t) (void *context, mico_bt_device_address_t bd_addr, + uint16_t local_cid, uint16_t psm, uint8_t id, uint16_t mtu_peer); -/* +/** * LE Connection confirmation callback prototype. * - * @param context : Caller context provided with aos_bt_l2cap_le_register() + * @param context : Caller context provided with mico_bt_l2cap_le_register() * @param local_cid : Local CID * @param result : Result - 0 = connected, non-zero means failure reason * @param mtu_peer : MTU of the peer * * @return void */ -typedef void (aos_bt_l2cap_le_connect_confirm_cback_t) (void *context, uint16_t local_cid, - uint16_t result, uint16_t mtu_peer); +typedef void (mico_bt_l2cap_le_connect_confirm_cback_t) (void *context, uint16_t local_cid, + uint16_t result, uint16_t mtu_peer); #if (L2CAP_LE_COC_CONFORMANCE_TESTING == TRUE) -/* +/** * * * @return void */ -typedef void (aos_bt_l2cap_le_conformance_test_cback_t) (uint16_t); +typedef void (mico_bt_l2cap_le_conformance_test_cback_t) (uint16_t); #endif -/* +/** * Define the structure that applications use to register with * LE L2CAP. This structure includes callback functions. All functions * MUST be provided, with the exception of the "connect pending" @@ -419,21 +415,21 @@ typedef void (aos_bt_l2cap_le_conformance_test_cback_t) (uint16_t); * be NULL since dynamic PSMs use this as a flag for "virtual PSM". */ typedef struct { - aos_bt_l2cap_le_connect_indication_cback_t *le_connect_indication_cback; /* LE connect indication event */ - aos_bt_l2cap_le_connect_confirm_cback_t *le_connect_confirm_cback; /* LE connect confirm event */ - aos_bt_l2cap_disconnect_indication_cback_t *disconnect_indication_cback; /* LE disconnect indication event */ - aos_bt_l2cap_disconnect_confirm_cback_t *disconnect_confirm_cback; /* LE disconnect confirm event */ - aos_bt_l2cap_data_indication_cback_t *data_indication_cback; /* LE data received indication */ - aos_bt_l2cap_congestion_status_cback_t *congestion_status_cback; /* TODO */ + mico_bt_l2cap_le_connect_indication_cback_t *le_connect_indication_cback; /**< LE connect indication event */ + mico_bt_l2cap_le_connect_confirm_cback_t *le_connect_confirm_cback; /**< LE connect confirm event */ + mico_bt_l2cap_disconnect_indication_cback_t *disconnect_indication_cback; /**< LE disconnect indication event */ + mico_bt_l2cap_disconnect_confirm_cback_t *disconnect_confirm_cback; /**< LE disconnect confirm event */ + mico_bt_l2cap_data_indication_cback_t *data_indication_cback; /**< LE data received indication */ + mico_bt_l2cap_congestion_status_cback_t *congestion_status_cback; /**< TODO */ #if (L2CAP_LE_COC_CONFORMANCE_TESTING == TRUE) - aos_bt_l2cap_le_conformance_test_cback_t *conformance_test_cback; /* TODO */ + mico_bt_l2cap_le_conformance_test_cback_t *conformance_test_cback; /**< TODO */ #endif -} aos_bt_l2cap_le_appl_information_t; +} mico_bt_l2cap_le_appl_information_t; -/*@} Callback Functions */ +/**@} Callback Functions */ -/**************************************************************************** +/***************************************************************************** * External Function Declarations ****************************************************************************/ #ifdef __cplusplus @@ -441,7 +437,7 @@ extern "C" { #endif -/* +/** * @addtogroup l2cap_api_functions API Functions * @ingroup l2cap * @@ -451,9 +447,9 @@ extern "C" */ #if (L2CAP_NUM_FIXED_CHNLS > 0) -/* +/** * - * Function aos_bt_l2cap_register_fixed_channel + * Function mico_bt_l2cap_register_fixed_channel * * Register a fixed channel. * @@ -463,12 +459,12 @@ extern "C" * @return: TRUE if registered OK * */ -aos_bool_t aos_bt_l2cap_register_fixed_channel (uint16_t fixed_cid, aos_bt_l2cap_fixed_chnl_reg_t *p_freg); +mico_bool_t mico_bt_l2cap_register_fixed_channel (uint16_t fixed_cid, mico_bt_l2cap_fixed_chnl_reg_t *p_freg); -/* +/** * - * Function aos_bt_l2cap_connect_fixed_chnl + * Function mico_bt_l2cap_connect_fixed_chnl * * Connect an fixed signalling channel to a remote device. * @@ -478,12 +474,12 @@ aos_bool_t aos_bt_l2cap_register_fixed_channel (uint16_t fixed_cid, aos_bt_l2ca * @return: TRUE if connection started * */ -aos_bool_t aos_bt_l2cap_connect_fixed_chnl (uint16_t fixed_cid, aos_bt_device_address_t bd_addr); +mico_bool_t mico_bt_l2cap_connect_fixed_chnl (uint16_t fixed_cid, mico_bt_device_address_t bd_addr); -/* +/** * - * Function aos_bt_l2cap_send_fixed_chnl_data + * Function mico_bt_l2cap_send_fixed_chnl_data * * Write data on a fixed signalling channel. * @@ -495,14 +491,14 @@ aos_bool_t aos_bt_l2cap_connect_fixed_chnl (uint16_t fixed_cid, aos_bt_device_ad * L2CAP_DATAWRITE_FAILED, if error * */ -uint16_t aos_bt_l2cap_send_fixed_chnl_data (uint16_t fixed_cid, aos_bt_device_address_t rem_bda, - uint8_t *p_buf, uint16_t buf_len); +uint16_t mico_bt_l2cap_send_fixed_chnl_data (uint16_t fixed_cid, mico_bt_device_address_t rem_bda, + uint8_t *p_buf, uint16_t buf_len); -/* +/** * - * Function aos_bt_l2cap_remove_fixed_chnl + * Function mico_bt_l2cap_remove_fixed_chnl * * Remove a fixed channel to a remote device. * @@ -513,12 +509,12 @@ uint16_t aos_bt_l2cap_send_fixed_chnl_data (uint16_t fixed_cid, aos_bt_device_ad * @return: TRUE if channel removed * */ -aos_bool_t aos_bt_l2cap_remove_fixed_chnl (uint16_t fixed_cid, aos_bt_device_address_t rem_bda); +mico_bool_t mico_bt_l2cap_remove_fixed_chnl (uint16_t fixed_cid, mico_bt_device_address_t rem_bda); -/* +/** * - * Function aos_bt_l2cap_set_fixed_channel_timeout + * Function mico_bt_l2cap_set_fixed_channel_timeout * * Higher layers call this function to set the idle timeout for * a fixed channel. The "idle timeout" is the amount of time that @@ -537,15 +533,15 @@ aos_bool_t aos_bt_l2cap_remove_fixed_chnl (uint16_t fixed_cid, aos_bt_device_add * @return TRUE if command succeeded, FALSE if failed * */ -aos_bool_t aos_bt_l2cap_set_fixed_channel_timeout (aos_bt_device_address_t rem_bda, uint16_t fixed_cid, - uint16_t idle_timeout); +mico_bool_t mico_bt_l2cap_set_fixed_channel_timeout (mico_bt_device_address_t rem_bda, uint16_t fixed_cid, + uint16_t idle_timeout); #endif /* (L2CAP_NUM_FIXED_CHNLS > 0) */ -/* +/** * - * Function aos_bt_l2cap_get_current_config + * Function mico_bt_l2cap_get_current_config * * This function returns configurations of L2CAP channel * @@ -558,14 +554,14 @@ aos_bool_t aos_bt_l2cap_set_fixed_channel_timeout (aos_bt_device_address_t rem_b * @return TRUE if successful * */ -aos_bool_t aos_bt_l2cap_get_current_config (uint16_t lcid, - aos_bt_l2cap_cfg_information_t **pp_our_cfg, aos_bt_l2cap_ch_cfg_bits_t *p_our_cfg_bits, - aos_bt_l2cap_cfg_information_t **pp_peer_cfg, aos_bt_l2cap_ch_cfg_bits_t *p_peer_cfg_bits); +mico_bool_t mico_bt_l2cap_get_current_config (uint16_t lcid, + mico_bt_l2cap_cfg_information_t **pp_our_cfg, mico_bt_l2cap_ch_cfg_bits_t *p_our_cfg_bits, + mico_bt_l2cap_cfg_information_t **pp_peer_cfg, mico_bt_l2cap_ch_cfg_bits_t *p_peer_cfg_bits); -/* +/** * - * Function aos_bt_l2cap_register + * Function mico_bt_l2cap_register * * Other layers call this function to register for L2CAP * services. @@ -577,16 +573,16 @@ aos_bool_t aos_bt_l2cap_get_current_config (uint16_t lcid, * @return PSM to use or zero if error. Typically, the PSM returned * is the same as was passed in, but for an outgoing-only * connection to a dynamic PSM, a "virtual" PSM is returned - * and should be used in the calls to aos_bt_l2cap_connect_req() + * and should be used in the calls to mico_bt_l2cap_connect_req() * and BTM_SetSecurityLevel(). * */ -uint16_t aos_bt_l2cap_register (uint16_t psm, aos_bt_l2cap_appl_information_t *p_cb_information, void *context); +uint16_t mico_bt_l2cap_register (uint16_t psm, mico_bt_l2cap_appl_information_t *p_cb_information, void *context); -/* +/** * - * Function aos_bt_l2cap_deregister + * Function mico_bt_l2cap_deregister * * Other layers call this function to deregister for L2CAP * services. @@ -596,12 +592,12 @@ uint16_t aos_bt_l2cap_register (uint16_t psm, aos_bt_l2cap_appl_information_t *p * @return void * */ -void aos_bt_l2cap_deregister (uint16_t psm); +void mico_bt_l2cap_deregister (uint16_t psm); -/* +/** * - * Function aos_bt_l2cap_allocate_psm + * Function mico_bt_l2cap_allocate_psm * * Other layers call this function to find an unused PSM for * L2CAP services. @@ -609,12 +605,12 @@ void aos_bt_l2cap_deregister (uint16_t psm); * @return PSM to use. * */ -uint16_t aos_bt_l2cap_allocate_psm (void); +uint16_t mico_bt_l2cap_allocate_psm (void); -/* +/** * - * Function aos_bt_l2cap_connect_req + * Function mico_bt_l2cap_connect_req * * Higher layers call this function to create an L2CAP connection. * Note that the connection is not established at this time, but @@ -628,13 +624,13 @@ uint16_t aos_bt_l2cap_allocate_psm (void); * @return the CID of the connection, or 0 if it failed to start * */ -uint16_t aos_bt_l2cap_connect_req (uint16_t psm, aos_bt_device_address_t p_bd_addr, - aos_bt_l2cap_ertm_information_t *p_ertm_information); +uint16_t mico_bt_l2cap_connect_req (uint16_t psm, mico_bt_device_address_t p_bd_addr, + mico_bt_l2cap_ertm_information_t *p_ertm_information); -/* +/** * - * Function aos_bt_l2cap_ertm_enable + * Function mico_bt_l2cap_ertm_enable * * Description Enable ERTM. * @@ -646,12 +642,12 @@ uint16_t aos_bt_l2cap_connect_req (uint16_t psm, aos_bt_device_address_t p_bd_ad * @return void * */ -void aos_bt_l2cap_ertm_enable (void); +void mico_bt_l2cap_ertm_enable (void); -/* +/** * - * Function aos_bt_l2cap_ertm_connect_req + * Function mico_bt_l2cap_ertm_connect_req * * Higher layers call this function to create an L2CAP connection * that needs to use Enhanced Retransmission Mode. @@ -666,13 +662,13 @@ void aos_bt_l2cap_ertm_enable (void); * @return the CID of the connection, or 0 if it failed to start * */ -uint16_t aos_bt_l2cap_ertm_connect_req (uint16_t psm, aos_bt_device_address_t p_bd_addr, - aos_bt_l2cap_ertm_information_t *p_ertm_information); +uint16_t mico_bt_l2cap_ertm_connect_req (uint16_t psm, mico_bt_device_address_t p_bd_addr, + mico_bt_l2cap_ertm_information_t *p_ertm_information); -/* +/** * - * Function aos_bt_l2cap_disconnect_req + * Function mico_bt_l2cap_disconnect_req * * Higher layers call this function to disconnect a channel. * @@ -681,12 +677,12 @@ uint16_t aos_bt_l2cap_ertm_connect_req (uint16_t psm, aos_bt_device_address_t p_ * @return TRUE if disconnect sent, else FALSE * */ -aos_bool_t aos_bt_l2cap_disconnect_req (uint16_t cid); +mico_bool_t mico_bt_l2cap_disconnect_req (uint16_t cid); -/* +/** * - * Function aos_bt_l2cap_disconnect_rsp + * Function mico_bt_l2cap_disconnect_rsp * * Higher layers call this function to acknowledge the * disconnection of a channel. @@ -696,12 +692,12 @@ aos_bool_t aos_bt_l2cap_disconnect_req (uint16_t cid); * @return void * */ -aos_bool_t aos_bt_l2cap_disconnect_rsp (uint16_t cid); +mico_bool_t mico_bt_l2cap_disconnect_rsp (uint16_t cid); -/* +/** * - * Function aos_bt_l2cap_data_write + * Function mico_bt_l2cap_data_write * * Higher layers call this function to write data with extended * @@ -716,11 +712,11 @@ aos_bool_t aos_bt_l2cap_disconnect_rsp (uint16_t cid); * L2CAP_DATAWRITE_FAILED, if error * */ -uint8_t aos_bt_l2cap_data_write (uint16_t cid, uint8_t *p_buf, uint16_t buf_len, uint16_t flags); +uint8_t mico_bt_l2cap_data_write (uint16_t cid, uint8_t *p_buf, uint16_t buf_len, uint16_t flags); -/* +/** * - * Function aos_bt_l2cap_set_idle_timeout + * Function mico_bt_l2cap_set_idle_timeout * * Higher layers call this function to set the idle timeout for * a connection, or for all future connections. The "idle timeout" @@ -737,13 +733,13 @@ uint8_t aos_bt_l2cap_data_write (uint16_t cid, uint8_t *p_buf, uint16_t buf_len, * @return TRUE if command succeeded, FALSE if failed * */ -aos_bool_t aos_bt_l2cap_set_idle_timeout (uint16_t cid, uint16_t timeout, - aos_bool_t is_global); +mico_bool_t mico_bt_l2cap_set_idle_timeout (uint16_t cid, uint16_t timeout, + mico_bool_t is_global); -/* +/** * - * Function aos_bt_l2cap_set_idle_timeout_by_bd_addr + * Function mico_bt_l2cap_set_idle_timeout_by_bd_addr * * Higher layers call this function to set the idle timeout for * a connection. The "idle timeout" is the amount of time that @@ -763,12 +759,12 @@ aos_bool_t aos_bt_l2cap_set_idle_timeout (uint16_t cid, uint16_t timeout, * NOTE This timeout applies to all logical channels active on the * ACL link. */ -aos_bool_t aos_bt_l2cap_set_idle_timeout_by_bd_addr (aos_bt_device_address_t bd_addr, uint16_t timeout, - tBT_TRANSPORT transport); +mico_bool_t mico_bt_l2cap_set_idle_timeout_by_bd_addr (mico_bt_device_address_t bd_addr, uint16_t timeout, + tBT_TRANSPORT transport); -/* +/** * - * Function aos_bt_l2cap_set_trace_level + * Function mico_bt_l2cap_set_trace_level * * This function sets the trace level for L2CAP. If called with * a value of 0xFF, it simply reads the current trace level. @@ -778,12 +774,12 @@ aos_bool_t aos_bt_l2cap_set_idle_timeout_by_bd_addr (aos_bt_device_address_t bd_ * @return the new (current) trace level * */ -uint8_t aos_bt_l2cap_set_trace_level (uint8_t trace_level); +uint8_t mico_bt_l2cap_set_trace_level (uint8_t trace_level); -/* +/** * - * Function aos_bt_l2cap_set_desire_role + * Function mico_bt_l2cap_set_desire_role * * This function sets the desire role for L2CAP. * If the new role is L2CAP_ROLE_ALLOW_SWITCH, allow switch on @@ -799,12 +795,12 @@ uint8_t aos_bt_l2cap_set_trace_level (uint8_t trace_level); * @return the new (current) role * */ -uint8_t aos_bt_l2cap_set_desire_role (uint8_t new_role); +uint8_t mico_bt_l2cap_set_desire_role (uint8_t new_role); -/* +/** * - * Function aos_bt_l2cap_flush_channel + * Function mico_bt_l2cap_flush_channel * * This function flushes none, some or all buffers queued up * for xmission for a particular CID. If called with @@ -819,12 +815,12 @@ uint8_t aos_bt_l2cap_set_desire_role (uint8_t new_role); * @return Number of buffers left queued for that CID * */ -uint16_t aos_bt_l2cap_flush_channel (uint16_t lcid, uint16_t num_to_flush); +uint16_t mico_bt_l2cap_flush_channel (uint16_t lcid, uint16_t num_to_flush); -/* +/** * - * Function aos_bt_l2cap_set_acl_priority + * Function mico_bt_l2cap_set_acl_priority * * Sets the priority for an ACL channel * @@ -834,11 +830,11 @@ uint16_t aos_bt_l2cap_flush_channel (uint16_t lcid, uint16_t num_to_flush); * @return TRUE if a valid channel, else FALSE * */ -aos_bool_t aos_bt_l2cap_set_acl_priority (aos_bt_device_address_t bd_addr, uint8_t priority); +mico_bool_t mico_bt_l2cap_set_acl_priority (mico_bt_device_address_t bd_addr, uint8_t priority); -/* +/** * - * Function aos_bt_l2cap_set_acl_priority_ext + * Function mico_bt_l2cap_set_acl_priority_ext * * Sets the priority for an ACL channel * with extended parameters. @@ -850,12 +846,12 @@ aos_bool_t aos_bt_l2cap_set_acl_priority (aos_bt_device_address_t bd_addr, uint8 * @return TRUE if a valid channel, else FALSE * */ -aos_bool_t aos_bt_l2cap_set_acl_priority_ext (aos_bt_device_address_t bd_addr, uint8_t priority, uint8_t direction); +mico_bool_t mico_bt_l2cap_set_acl_priority_ext (mico_bt_device_address_t bd_addr, uint8_t priority, uint8_t direction); -/* +/** * - * Function aos_bt_l2cap_flow_control + * Function mico_bt_l2cap_flow_control * * Higher layers call this function to flow control a channel. * @@ -867,12 +863,12 @@ aos_bool_t aos_bt_l2cap_set_acl_priority_ext (aos_bt_device_address_t bd_addr, u * @return TRUE if valid channel, else FALSE * */ -aos_bool_t aos_bt_l2cap_flow_control (uint16_t cid, aos_bool_t data_enabled); +mico_bool_t mico_bt_l2cap_flow_control (uint16_t cid, mico_bool_t data_enabled); -/* +/** * - * Function aos_bt_l2cap_set_tx_priority + * Function mico_bt_l2cap_set_tx_priority * * Sets the transmission priority for a channel. (FCR Mode) * @@ -883,12 +879,12 @@ aos_bool_t aos_bt_l2cap_flow_control (uint16_t cid, aos_bool_t data_enabled); * @return TRUE if a valid channel, else FALSE * */ -aos_bool_t aos_bt_l2cap_set_tx_priority (uint16_t cid, aos_bt_l2cap_chnl_priority_t priority); +mico_bool_t mico_bt_l2cap_set_tx_priority (uint16_t cid, mico_bt_l2cap_chnl_priority_t priority); -/* +/** * - * Function aos_bt_l2cap_register_for_nocp_evt + * Function mico_bt_l2cap_register_for_nocp_evt * * Register callback for Number of Completed Packets (NOCP) event. * @@ -898,11 +894,11 @@ aos_bool_t aos_bt_l2cap_set_tx_priority (uint16_t cid, aos_bt_l2cap_chnl_priorit * @return TRUE successful * */ -aos_bool_t aos_bt_l2cap_register_for_nocp_evt (aos_bt_l2cap_nocp_cback_t *p_cb, aos_bt_device_address_t p_bda); +mico_bool_t mico_bt_l2cap_register_for_nocp_evt (mico_bt_l2cap_nocp_cback_t *p_cb, mico_bt_device_address_t p_bda); -/* +/** * - * Function aos_bt_l2cap_set_flush_timeout + * Function mico_bt_l2cap_set_flush_timeout * * This function set the automatic flush time out in Baseband * for ACL-U packets. @@ -922,14 +918,14 @@ aos_bool_t aos_bt_l2cap_register_for_nocp_evt (aos_bt_l2cap_nocp_cback_t *p_cb, * NOTE This flush timeout applies to all logical channels active on the * ACL link. */ -aos_bool_t aos_bt_l2cap_set_flush_timeout (aos_bt_device_address_t bd_addr, uint16_t flush_timeout); +mico_bool_t mico_bt_l2cap_set_flush_timeout (mico_bt_device_address_t bd_addr, uint16_t flush_timeout); -/* +/** * - * Function aos_bt_l2cap_set_chnl_flushability + * Function mico_bt_l2cap_set_chnl_flushability * * Higher layers call this function to set a channels * flushability flags @@ -940,12 +936,12 @@ aos_bool_t aos_bt_l2cap_set_flush_timeout (aos_bt_device_address_t bd_addr, uint * @return TRUE if CID found, else FALSE * */ -aos_bool_t aos_bt_l2cap_set_chnl_flushability (uint16_t cid, aos_bool_t is_flushable); +mico_bool_t mico_bt_l2cap_set_chnl_flushability (uint16_t cid, mico_bool_t is_flushable); -/* +/** * - * Function aos_bt_l2cap_get_peer_features + * Function mico_bt_l2cap_get_peer_features * * Get a peers features and fixed channel map * @@ -956,12 +952,13 @@ aos_bool_t aos_bt_l2cap_set_chnl_flushability (uint16_t cid, aos_bool_t is_flush * @return: TRUE if peer is connected * */ -aos_bool_t aos_bt_l2cap_get_peer_features (aos_bt_device_address_t bd_addr, uint32_t *p_ext_feat, uint8_t *p_chnl_mask); +mico_bool_t mico_bt_l2cap_get_peer_features (mico_bt_device_address_t bd_addr, uint32_t *p_ext_feat, + uint8_t *p_chnl_mask); -/* +/** * - * Function aos_bt_l2cap_get_bdaddrby_handle + * Function mico_bt_l2cap_get_bdaddrby_handle * * Get BD address for the given HCI handle * @@ -971,12 +968,12 @@ aos_bool_t aos_bt_l2cap_get_peer_features (aos_bt_device_address_t bd_addr, uint * @return: TRUE if found lcb for the given handle, FALSE otherwise * */ -aos_bool_t aos_bt_l2cap_get_bdaddrby_handle (uint16_t handle, aos_bt_device_address_t bd_addr); +mico_bool_t mico_bt_l2cap_get_bdaddrby_handle (uint16_t handle, mico_bt_device_address_t bd_addr); -/* +/** * - * Function aos_bt_l2cap_get_chnl_fcr_mode + * Function mico_bt_l2cap_get_chnl_fcr_mode * * Get the channel FCR mode * @@ -985,12 +982,12 @@ aos_bool_t aos_bt_l2cap_get_bdaddrby_handle (uint16_t handle, aos_bt_device_addr * @return: Channel mode * */ -uint8_t aos_bt_l2cap_get_chnl_fcr_mode (uint16_t lcid); +uint8_t mico_bt_l2cap_get_chnl_fcr_mode (uint16_t lcid); -/* +/** * - * Function aos_bt_l2cap_cancel_ble_connect_req + * Function mico_bt_l2cap_cancel_ble_connect_req * * Cancel a pending connection attempt to a BLE device. * @@ -999,12 +996,12 @@ uint8_t aos_bt_l2cap_get_chnl_fcr_mode (uint16_t lcid); * @return: TRUE if connection was cancelled * */ -aos_bool_t aos_bt_l2cap_cancel_ble_connect_req (aos_bt_device_address_t rem_bda); +mico_bool_t mico_bt_l2cap_cancel_ble_connect_req (mico_bt_device_address_t rem_bda); -/* +/** * - * Function aos_bt_l2cap_update_ble_conn_params + * Function mico_bt_l2cap_update_ble_conn_params * * Update BLE connection parameters. * @@ -1017,13 +1014,13 @@ aos_bool_t aos_bt_l2cap_cancel_ble_connect_req (aos_bt_device_address_t rem_bda) * @return: TRUE if update started * */ -aos_bool_t aos_bt_l2cap_update_ble_conn_params (aos_bt_device_address_t rem_bdRa, uint16_t min_int, uint16_t max_int, - uint16_t latency, uint16_t timeout); +mico_bool_t mico_bt_l2cap_update_ble_conn_params (mico_bt_device_address_t rem_bdRa, uint16_t min_int, uint16_t max_int, + uint16_t latency, uint16_t timeout); -/* +/** * - * Function aos_bt_l2cap_enable_update_ble_conn_params + * Function mico_bt_l2cap_enable_update_ble_conn_params * * Update BLE connection parameters. * @@ -1033,12 +1030,12 @@ aos_bool_t aos_bt_l2cap_update_ble_conn_params (aos_bt_device_address_t rem_bdRa * @return: TRUE if update started * */ -aos_bool_t aos_bt_l2cap_enable_update_ble_conn_params (aos_bt_device_address_t rem_bda, aos_bool_t enable); +mico_bool_t mico_bt_l2cap_enable_update_ble_conn_params (mico_bt_device_address_t rem_bda, mico_bool_t enable); -/* +/** * - * Function aos_bt_l2cap_get_ble_conn_role + * Function mico_bt_l2cap_get_ble_conn_role * * This function returns the connection role. * @@ -1047,12 +1044,12 @@ aos_bool_t aos_bt_l2cap_enable_update_ble_conn_params (aos_bt_device_address_t r * @return link role. * */ -uint8_t aos_bt_l2cap_get_ble_conn_role (aos_bt_device_address_t bd_addr); +uint8_t mico_bt_l2cap_get_ble_conn_role (mico_bt_device_address_t bd_addr); -/* +/** * - * Function aos_bt_l2cap_get_disconnect_reason + * Function mico_bt_l2cap_get_disconnect_reason * * This function returns the disconnect reason code. * @@ -1062,12 +1059,12 @@ uint8_t aos_bt_l2cap_get_ble_conn_role (aos_bt_device_address_t bd_addr); * @return disconnect reason * */ -uint16_t aos_bt_l2cap_get_disconnect_reason (aos_bt_device_address_t remote_bda, tBT_TRANSPORT transport); +uint16_t mico_bt_l2cap_get_disconnect_reason (mico_bt_device_address_t remote_bda, tBT_TRANSPORT transport); -/* +/** * - * Function aos_bt_l2cap_le_register + * Function mico_bt_l2cap_le_register * * Other layers call this function to register L2CAP services * for LE_PSM. @@ -1079,16 +1076,16 @@ uint16_t aos_bt_l2cap_get_disconnect_reason (aos_bt_device_address_t remote_bda, * @return LE_PSM to use or zero if error. Typically the LE_PSM returned * is the same as was passed in, but for an outgoing-only * connection a "virtual" LE_PSM is returned and should be used - * in the calls to aos_bt_l2cap_le_connect_req() and aos_bt_l2cap_le_deregister(). + * in the calls to mico_bt_l2cap_le_connect_req() and mico_bt_l2cap_le_deregister(). * */ -uint16_t aos_bt_l2cap_le_register (uint16_t le_psm, aos_bt_l2cap_le_appl_information_t *p_cb_information, - void *context); +uint16_t mico_bt_l2cap_le_register (uint16_t le_psm, mico_bt_l2cap_le_appl_information_t *p_cb_information, + void *context); -/* +/** * - * Function aos_bt_l2cap_le_deregister + * Function mico_bt_l2cap_le_deregister * * Other layers call this function to deregister L2CAP services * for LE_PSM. @@ -1098,12 +1095,12 @@ uint16_t aos_bt_l2cap_le_register (uint16_t le_psm, aos_bt_l2cap_le_appl_informa * @return void * */ -aos_bool_t aos_bt_l2cap_le_deregister (uint16_t le_psm); +mico_bool_t mico_bt_l2cap_le_deregister (uint16_t le_psm); -/* +/** * - * Function aos_bt_l2cap_le_connect_req + * Function mico_bt_l2cap_le_connect_req * * Higher layers call this function to create an L2CAP connection * for LE_PSM. @@ -1123,16 +1120,16 @@ aos_bool_t aos_bt_l2cap_le_deregister (uint16_t le_psm); * @return the CID of the connection, or 0 if it failed to start * */ -uint16_t aos_bt_l2cap_le_connect_req (uint16_t le_psm, aos_bt_device_address_t p_bd_addr, - aos_bt_ble_address_type_t bd_addr_type, - aos_bt_ble_conn_mode_t conn_mode, - uint16_t rx_mtu, uint8_t rx_sdu_pool_id, - uint8_t req_security, uint8_t req_encr_key_size); +uint16_t mico_bt_l2cap_le_connect_req (uint16_t le_psm, mico_bt_device_address_t p_bd_addr, + mico_bt_ble_address_type_t bd_addr_type, + mico_bt_ble_conn_mode_t conn_mode, + uint16_t rx_mtu, uint8_t rx_sdu_pool_id, + uint8_t req_security, uint8_t req_encr_key_size); -/* +/** * - * Function aos_bt_l2cap_le_connect_rsp + * Function mico_bt_l2cap_le_connect_rsp * * Higher layers call this function to accept an incoming * LE L2CAP connection, for which they had gotten an connect @@ -1148,13 +1145,13 @@ uint16_t aos_bt_l2cap_le_connect_req (uint16_t le_psm, aos_bt_device_address_t p * @return TRUE for success, FALSE for failure * */ -aos_bool_t aos_bt_l2cap_le_connect_rsp (aos_bt_device_address_t p_bd_addr, uint8_t id, uint16_t lcid, - uint16_t result, uint16_t rx_mtu, uint8_t rx_sdu_pool_id); +mico_bool_t mico_bt_l2cap_le_connect_rsp (mico_bt_device_address_t p_bd_addr, uint8_t id, uint16_t lcid, + uint16_t result, uint16_t rx_mtu, uint8_t rx_sdu_pool_id); -/* +/** * - * Function aos_bt_l2cap_le_disconnect_req + * Function mico_bt_l2cap_le_disconnect_req * * Higher layers call this function to disconnect a LE COC * channel. @@ -1164,12 +1161,12 @@ aos_bool_t aos_bt_l2cap_le_connect_rsp (aos_bt_device_address_t p_bd_addr, uint * @return TRUE if disconnect sent, else FALSE * */ -aos_bool_t aos_bt_l2cap_le_disconnect_req (uint16_t lcid); +mico_bool_t mico_bt_l2cap_le_disconnect_req (uint16_t lcid); -/* +/** * - * Function aos_bt_l2cap_le_disconnect_rsp + * Function mico_bt_l2cap_le_disconnect_rsp * * Higher layers call this function to acknowledge the * disconnection of a LE COC channel. @@ -1179,12 +1176,12 @@ aos_bool_t aos_bt_l2cap_le_disconnect_req (uint16_t lcid); * @return void * */ -aos_bool_t aos_bt_l2cap_le_disconnect_rsp (uint16_t lcid); +mico_bool_t mico_bt_l2cap_le_disconnect_rsp (uint16_t lcid); -/* +/** * - * Function aos_bt_l2cap_le_data_write + * Function mico_bt_l2cap_le_data_write * * Higher layers call this function to write data. * @@ -1197,12 +1194,12 @@ aos_bool_t aos_bt_l2cap_le_disconnect_rsp (uint16_t lcid); * L2CAP_DATAWRITE_FAILED, if error * */ -uint8_t aos_bt_l2cap_le_data_write (uint16_t cid, uint8_t *p_data, uint16_t buf_len, uint16_t flags); +uint8_t mico_bt_l2cap_le_data_write (uint16_t cid, uint8_t *p_data, uint16_t buf_len, uint16_t flags); -/* +/** * - * Function aos_bt_l2cap_le_set_user_congestion + * Function mico_bt_l2cap_le_set_user_congestion * * Higher layers call this function to tell if the connection * is congested or not @@ -1213,12 +1210,12 @@ uint8_t aos_bt_l2cap_le_data_write (uint16_t cid, uint8_t *p_data, uint16_t buf_ * @return TRUE if command processed OK * */ -aos_bool_t aos_bt_l2cap_le_set_user_congestion (uint16_t lcid, aos_bool_t is_congested); +mico_bool_t mico_bt_l2cap_le_set_user_congestion (uint16_t lcid, mico_bool_t is_congested); -/* +/** * - * Function aos_bt_l2cap_le_get_peer_mtu + * Function mico_bt_l2cap_le_get_peer_mtu * * Higher layers call this function to get peer MTU. * @@ -1227,12 +1224,12 @@ aos_bool_t aos_bt_l2cap_le_set_user_congestion (uint16_t lcid, aos_bool_t is_co * @return Peer MTU or 0. * */ -uint16_t aos_bt_l2cap_le_get_peer_mtu (uint16_t lcid); +uint16_t mico_bt_l2cap_le_get_peer_mtu (uint16_t lcid); -/* +/** * - * Function aos_bt_l2cap_le_determ_secur_rsp + * Function mico_bt_l2cap_le_determ_secur_rsp * * Higher layers call this function to check if the current * device security settings are sufficient to continue with @@ -1249,14 +1246,12 @@ uint16_t aos_bt_l2cap_le_get_peer_mtu (uint16_t lcid); * L2CAP_CONN_NO_RESOURCES. * */ -uint16_t aos_bt_l2cap_le_determ_secur_rsp (aos_bt_device_address_t bd_addr, uint8_t req_secur, - uint8_t req_encr_key_size); +uint16_t mico_bt_l2cap_le_determ_secur_rsp (mico_bt_device_address_t bd_addr, uint8_t req_secur, + uint8_t req_encr_key_size); -/*@} l2cap_api_functions */ +/**@} l2cap_api_functions */ #ifdef __cplusplus } #endif - -#endif diff --git a/device/bluetooth/mk3239/include/mico_bt_nvram_access.h b/device/bluetooth/mk3239/include/mico_bt_nvram_access.h new file mode 100644 index 0000000000..427db9b558 --- /dev/null +++ b/device/bluetooth/mk3239/include/mico_bt_nvram_access.h @@ -0,0 +1,41 @@ + +/** @file + * + * MiCO Bluetooth Low Energy (BLE) Functions + * + */ +#pragma once + +#ifndef OFFSETOF +#define OFFSETOF( type, member ) ( (uintptr_t)&((type *)0)->member ) +#endif /* OFFSETOF */ + +#define MICO_BT_PARA_LOCAL_KEY_DATA 65 /* BTM_SECURITY_LOCAL_KEY_DATA_LEN */ + +#define MICO_BT_DCT_NAME 249 +#define MICO_BT_DCT_MAX_KEYBLOBS 146 /* Maximum size of key blobs to be stored := size of BR-EDR link keys + size of BLE keys*/ +#define MICO_BT_DCT_ADDR_FIELD 6 +#define MICO_BT_DCT_LENGTH_FIELD 2 +#ifndef MICO_BT_DCT_MAX_DEVICES +#define MICO_BT_DCT_MAX_DEVICES 10 /* Maximum number of device records stored in nvram */ +#endif +#define MICO_BT_DCT_ADDR_TYPE 1 +#define MICO_BT_DCT_DEVICE_TYPE 1 + +/* Length of BD_ADDR + 2bytes length field */ +#define MICO_BT_DCT_ENTRY_HDR_LENGTH (MICO_BT_DCT_ADDR_FIELD + MICO_BT_DCT_LENGTH_FIELD + MICO_BT_DCT_ADDR_TYPE + MICO_BT_DCT_DEVICE_TYPE) + +#define MICO_BT_DCT_LOCAL_KEY_OFFSET OFFSETOF( mico_bt_config_t, bluetooth_local_key ) +#define MICO_BT_DCT_REMOTE_KEY_OFFSET OFFSETOF( mico_bt_config_t, bluetooth_remote_key ) + + + +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif diff --git a/device/bluetooth/mk3239/include/mico_bt_rfcomm.h b/device/bluetooth/mk3239/include/mico_bt_rfcomm.h new file mode 100644 index 0000000000..56a70c30d1 --- /dev/null +++ b/device/bluetooth/mk3239/include/mico_bt_rfcomm.h @@ -0,0 +1,317 @@ + + +/** @file + * + * Bluetooth RFCOMM Application Programming Interface + * + */ +#pragma once + +#include "mico.h" +//#include "mico_bt_dev.h" + +/****************************************************** + * Constants and Type definitions + ******************************************************/ + +/** RFCOMM Port Event Masks */ +typedef enum mico_bt_rfcomm_port_event_e { + MICO_BT_RFCOMM_EV_RXCHAR = 0x00000001, /**< Any Character received */ + MICO_BT_RFCOMM_EV_RXFLAG = 0x00000002, /**< Received certain character */ + MICO_BT_RFCOMM_EV_TXEMPTY = 0x00000004, /**< Transmitt Queue Empty */ + MICO_BT_RFCOMM_EV_CTS = 0x00000008, /**< CTS changed state */ + MICO_BT_RFCOMM_EV_DSR = 0x00000010, /**< DSR changed state */ + MICO_BT_RFCOMM_EV_RLSD = 0x00000020, /**< RLSD changed state */ + MICO_BT_RFCOMM_EV_BREAK = 0x00000040, /**< BREAK received */ + MICO_BT_RFCOMM_EV_ERR = 0x00000080, /**< Line status error occurred */ + MICO_BT_RFCOMM_EV_RING = 0x00000100, /**< Ring signal detected */ + MICO_BT_RFCOMM_EV_CTSS = 0x00000400, /**< CTS state */ + MICO_BT_RFCOMM_EV_DSRS = 0x00000800, /**< DSR state */ + MICO_BT_RFCOMM_EV_RLSDS = 0x00001000, /**< RLSD state */ + MICO_BT_RFCOMM_EV_OVERRUN = 0x00002000, /**< receiver buffer overrun */ + MICO_BT_RFCOMM_EV_TXCHAR = 0x00004000, /**< Any character transmitted */ + MICO_BT_RFCOMM_EV_CONNECTED = 0x00000200, /**< RFCOMM connection established */ + MICO_BT_RFCOMM_EV_CONNECT_ERR = 0x00008000, /**< Was not able to establish connection or disconnected */ + MICO_BT_RFCOMM_EV_FC = 0x00010000, /**< data flow enabled flag changed by remote */ + MICO_BT_RFCOMM_EV_FCS = 0x00020000, /**< data flow enable status true = enabled */ +} mico_bt_rfcomm_port_event_t; + +#define MICO_BT_RFCOMM_MASK_ALL (MICO_BT_RFCOMM_EV_RXCHAR | MICO_BT_RFCOMM_EV_TXEMPTY | MICO_BT_RFCOMM_EV_CTS | \ + MICO_BT_RFCOMM_EV_DSR | MICO_BT_RFCOMM_EV_RLSD | MICO_BT_RFCOMM_EV_BREAK | \ + MICO_BT_RFCOMM_EV_ERR | MICO_BT_RFCOMM_EV_RING | MICO_BT_RFCOMM_EV_CONNECT_ERR | \ + MICO_BT_RFCOMM_EV_DSRS | MICO_BT_RFCOMM_EV_CTSS | MICO_BT_RFCOMM_EV_RLSDS | \ + MICO_BT_RFCOMM_EV_RXFLAG | MICO_BT_RFCOMM_EV_TXCHAR | MICO_BT_RFCOMM_EV_OVERRUN | \ + MICO_BT_RFCOMM_EV_FC | MICO_BT_RFCOMM_EV_FCS | MICO_BT_RFCOMM_EV_CONNECTED) + + + +/** RFCOMM Result Codes */ +enum mico_bt_rfcomm_result_e { + MICO_BT_RFCOMM_SUCCESS, /**< Success */ + MICO_BT_RFCOMM_ERROR, /**< Error */ + MICO_BT_RFCOMM_ALREADY_OPENED, /**< Already Opened */ + MICO_BT_RFCOMM_CMD_PENDING, /**< Command Pending */ + MICO_BT_RFCOMM_APP_NOT_REGISTERED, /**< App Not Registered */ + MICO_BT_RFCOMM_NO_MEM, /**< No Memory */ + MICO_BT_RFCOMM_NO_RESOURCES, /**< No Resources */ + MICO_BT_RFCOMM_BAD_BD_ADDR, /**< Bad BD Address */ + MICO_BT_RFCOMM_RESULT_RESERVED0, + MICO_BT_RFCOMM_BAD_HANDLE, /**< Bad Handle */ + MICO_BT_RFCOMM_NOT_OPENED, /**< Not Opened */ + MICO_BT_RFCOMM_LINE_ERR, /**< Line Error */ + MICO_BT_RFCOMM_START_FAILED, /**< Start Failed */ + MICO_BT_RFCOMM_PAR_NEG_FAILED, + MICO_BT_RFCOMM_RFCOMM_NEG_FAILED, + MICO_BT_RFCOMM_SEC_FAILED, + MICO_BT_RFCOMM_PEER_CONNECTION_FAILED, /**< Peer Connection Failed */ + MICO_BT_RFCOMM_PEER_FAILED, /**< Peer Failed */ + MICO_BT_RFCOMM_PEER_TIMEOUT, /**< Peer Timeout */ + MICO_BT_RFCOMM_CLOSED, /**< Closed */ + MICO_BT_RFCOMM_TX_FULL, + MICO_BT_RFCOMM_LOCAL_CLOSED, /**< Local Closed */ + MICO_BT_RFCOMM_LOCAL_TIMEOUT, /**< Local Timeout */ + MICO_BT_RFCOMM_TX_QUEUE_DISABLED, + MICO_BT_RFCOMM_PAGE_TIMEOUT, /**< Page Timeout */ + MICO_BT_RFCOMM_INVALID_SCN /**< Invalid SCN */ +}; +typedef int mico_bt_rfcomm_result_t; /**< RFCOMM result code (see #mico_bt_rfcomm_result_e) */ + +/** RFCOMM Signals */ +enum mico_bt_rfcomm_signal_e { + MICO_BT_RFCOMM_SET_DTRDSR = 0x01, /** DTRDSR set */ + MICO_BT_RFCOMM_CLR_DTRDSR, /** DTRDSR clear */ + MICO_BT_RFCOMM_SET_CTSRTS, /** CTSRTS set */ + MICO_BT_RFCOMM_CLR_CTSRTS, /** CTSRTS clear */ + MICO_BT_RFCOMM_SET_RI, /** RI set (DCE only) */ + MICO_BT_RFCOMM_CLR_RI, /** RI clear (DCE only) */ + MICO_BT_RFCOMM_SET_DCD, /** DCD set (DCE only) */ + MICO_BT_RFCOMM_CLR_DCD, /** DCD clear (DCE only) */ + MICO_BT_RFCOMM_BREAK, /** BRK */ +}; +typedef uint8_t mico_bt_rfcomm_signal_t; /**< RFCOMM Signals (see #mico_bt_rfcomm_signal_e) */ + +/** + * Define the callback function prototypes for mico_bt_rfcomm_data_cback_t + * + * @param port_handle : A 16-bit unsigned integer returned by @link mico_bt_rfcomm_create_connection mico_bt_rfcomm_create_connection @endlink. + * @param *p_data : A pointer to the array of bytes received from the peer device. + * @param len : The length of the data received. + */ +typedef int (mico_bt_rfcomm_data_cback_t) (uint16_t port_handle, void *p_data, uint16_t len); + +/** + * Port management callback + * + * @param code : Result code + * @param port_handle : Port handle from @link mico_bt_rfcomm_create_connection mico_bt_rfcomm_create_connection @endlink. + */ +typedef void (mico_bt_port_mgmt_cback_t) (mico_bt_rfcomm_result_t code, uint16_t port_handle); + +/** + * Port event callback + * + * @param event : A 32-bit event code that contains a bit-mask of one or more events the caller would like to register. + * @param port_handle : Port handle from @link mico_bt_rfcomm_create_connection mico_bt_rfcomm_create_connection @endlink. + */ +typedef void (mico_bt_port_event_cback_t) (mico_bt_rfcomm_port_event_t event, uint16_t port_handle); + +/** + * @addtogroup rfcomm_api_functions RFCOMM + * @ingroup micobt + * + * RFCOMM Functions + * + * @{ + */ +/****************************************************** + * Function Declarations + ******************************************************/ +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * Establish serial port connection to the peer device, or allow + * RFCOMM to accept a connection from peer devices. + * + * @note + * Server can call this function with the same scn parameter multiple times if + * it is ready to accept multiple simulteneous connections. + * + * DLCI for the connection is (scn * 2 + 1) if client originates connection on + * existing none initiator multiplexer channel. Otherwise it is (scn * 2). + * For the server DLCI can be changed later if client will be calling it using + * (scn * 2 + 1) dlci. + * + * @param[in] uuid : The Universal Unique Identifier (UUID) of the + * Class ID of the service being opened + * @param[in] scn : The Service Channel Number(SCN) as registered + * with the SDP (server) or obtained using SDP from + * the peer device (client) + * @param[in] is_server : TRUE if requesting application is a server + * @param[in] mtu : The maximum number of bytes transferred per frame + * If 0, a default size of L2CAP_MTU_SIZE minus + * 5 bytes is used + * @param[in] bd_addr : BD_ADDR of the peer (if client), NULL if server + * @param[in] p_mgmt_cb : Pointer to callback function to receive connection + * up/down events + * @param[out] p_handle : A pointer to the handle set by RFCOMM to be used in + * consecutive calls for this connection + * + * @return MICO_BT_RFCOMM_SUCCESS : If successful + * MICO_BT_RFCOMM_ALREADY_OPENED : If the client tries to establish a connection to the same BD_ADDR + * MICO_BT_RFCOMM_NO_RESOURCES : If there is not enough memory to allocate a control block structure + * MICO_BT_RFCOMM_INVALID_SCN : If Server Channel Number(SCN) is out of in range 1...30 + */ +mico_bt_rfcomm_result_t mico_bt_rfcomm_create_connection (uint16_t uuid, uint8_t scn, + mico_bool_t is_server, uint16_t mtu, + mico_bt_device_address_t bd_addr, + uint16_t *p_handle, + mico_bt_port_mgmt_cback_t *p_mgmt_cb); + +/** + * Close the specified connection. + * + * @param[in] handle : The connection handle returned by + * @link mico_bt_rfcomm_create_connection mico_bt_rfcomm_create_connection @endlink. + * @param[in] remove_server : (for server only) If TRUE, then also remove server; otherwise server remains enabled + * after connection is closed. + * + * @return MICO_BT_RFCOMM_SUCCESS : If successful + * MICO_BT_RFCOMM_BAD_HANDLE : If the handle is out of range + * MICO_BT_RFCOMM_NOT_OPENED : If the connection is not opened + */ +mico_bt_rfcomm_result_t mico_bt_rfcomm_remove_connection (uint16_t handle, mico_bool_t remove_server); + + +/** + * Set event callback the specified connection. + * + * @param[in] port_handle : A 16-bit unsigned integer returned by + * @link mico_bt_rfcomm_create_connection mico_bt_rfcomm_create_connection @endlink + * @param[in] p_port_cb : Address of the callback function which should + * be called from the RFCOMM when an event + * specified in the mask occurs + * + * @return MICO_BT_RFCOMM_SUCCESS : If successful + * MICO_BT_RFCOMM_BAD_HANDLE : If the handle is out of range + * MICO_BT_RFCOMM_NOT_OPENED : If the connection is not opened + */ +mico_bt_rfcomm_result_t mico_bt_rfcomm_set_event_callback (uint16_t port_handle, mico_bt_port_event_cback_t *p_port_cb); + +/** + * Set event data callback the specified connection. + * + * @param[in] port_handle : A 16-bit unsigned integer returned by + * @link mico_bt_rfcomm_create_connection mico_bt_rfcomm_create_connection @endlink + * @param[in] p_cb : Address of the callback function which should + * be called from the RFCOMM when a data + * packet is received + * + * @return MICO_BT_RFCOMM_SUCCESS : If successful + * MICO_BT_RFCOMM_BAD_HANDLE : If the handle is out of range + * MICO_BT_RFCOMM_NOT_OPENED : If the connection is not opened + */ +mico_bt_rfcomm_result_t mico_bt_rfcomm_set_data_callback (uint16_t port_handle, mico_bt_rfcomm_data_cback_t *p_cb); + + +/** + * Set events for which to be notified + * + * @param[in] port_handle : A 16-bit unsigned integer returned by + * @link mico_bt_rfcomm_create_connection mico_bt_rfcomm_create_connection @endlink + * @param[in] mask : Event mask + * + * @return MICO_BT_RFCOMM_SUCCESS : If successful + * MICO_BT_RFCOMM_BAD_HANDLE : If the handle is out of range + * MICO_BT_RFCOMM_NOT_OPENED : If the connection is not opened + */ +mico_bt_rfcomm_result_t mico_bt_rfcomm_set_event_mask (uint16_t port_handle, mico_bt_rfcomm_port_event_t mask); + +/** + * Send control signal to the peer device. + * + * @param[in] handle : The connection handle returned by + * @link mico_bt_rfcomm_create_connection mico_bt_rfcomm_create_connection @endlink + * @param[in] signal : Signal to send (see #mico_bt_rfcomm_signal_e) + * + * @return MICO_BT_RFCOMM_SUCCESS : If successful + * MICO_BT_RFCOMM_BAD_HANDLE : If the handle is out of range + * MICO_BT_RFCOMM_NOT_OPENED : If the connection is not opened + */ +mico_bt_rfcomm_result_t mico_bt_rfcomm_control (uint16_t handle, mico_bt_rfcomm_signal_t signal); + +/** + * This function directs a specified connection to pass flow control message to the peer device. + * Enable flag passed shows if port can accept more data. + * + * @param[in] handle : The connection handle returned by + * @link mico_bt_rfcomm_create_connection mico_bt_rfcomm_create_connection @endlink + * @param[in] enable : Flow control setting + * TRUE Enable data flow + * FALSE Disable data flow + * + * @return MICO_BT_RFCOMM_SUCCESS : If successful + * MICO_BT_RFCOMM_BAD_HANDLE : If the handle is out of range + * MICO_BT_RFCOMM_NOT_OPENED : If the connection is not opened + */ +mico_bt_rfcomm_result_t mico_bt_rfcomm_flow_control (uint16_t handle, mico_bool_t enable); + +/** + * This function directs a specified connection to pass flow control message to the peer device. + * Enable flag passed shows if port can accept more data. + * + * @param[in] handle : The connection handle returned by + * @link mico_bt_rfcomm_create_connection mico_bt_rfcomm_create_connection @endlink + * @param[in] p_data : Data to write + * @param[in] max_len : Byte count to write + * @param[out] p_len : Bytes written + * + * @return MICO_BT_RFCOMM_SUCCESS : If successful + * MICO_BT_RFCOMM_BAD_HANDLE : If the handle is out of range + * MICO_BT_RFCOMM_NOT_OPENED : If the connection is not opened + */ +mico_bt_rfcomm_result_t mico_bt_rfcomm_write_data (uint16_t handle, char *p_data, uint16_t max_len, uint16_t *p_len); + +/** + * This function checks connection referenced by handle is up and running. + * + * @param[in] handle : The connection handle returned by + * @link mico_bt_rfcomm_create_connection mico_bt_rfcomm_create_connection @endlink + * @param[out] bd_addr : Peer BD Address + * @param[out] p_lcid : L2CAP's LCID + * + * @return MICO_BT_RFCOMM_SUCCESS : If successful + * MICO_BT_RFCOMM_LINE_ERR : If connection is not up and running + */ +//mico_bt_rfcomm_result_t mico_bt_rfcomm_check_connection (UINT16 handle, BD_ADDR bd_addr, UINT16 *p_lcid); + +#ifdef MPAF_CUSTOM_STACK +/** + * This function allocates private pool to be used by RFCOMM. + * + * @param[in] buffer_size : size of buffer + * @param[out] buffer_cnt : buffers + * + * @return MICO_BT_RFCOMM_SUCCESS : If successful + * MICO_BT_RFCOMM_ERROR : If pool allocation fails + */ +mico_bt_rfcomm_result_t mico_bt_rfcomm_init(uint32_t buffer_size, uint32_t buffer_cnt); + +/** + * This function enables flow control based on ACL buffer availability + * + * @param[in] peer_addr : Peer BD Address + * + * @return MICO_TRUE : If successful + * MICO_FALSE : If fails + */ +mico_bool_t mico_bt_rfcomm_control_data_flow(BD_ADDR peer_bda); +#endif + +#ifdef __cplusplus +} +#endif + +/**@} */ diff --git a/kernel/protocols/bluetooth/include/aos_bt_sco.h b/device/bluetooth/mk3239/include/mico_bt_sco.h similarity index 50% rename from kernel/protocols/bluetooth/include/aos_bt_sco.h rename to device/bluetooth/mk3239/include/mico_bt_sco.h index 45084ec7ac..838f8469fe 100644 --- a/kernel/protocols/bluetooth/include/aos_bt_sco.h +++ b/device/bluetooth/mk3239/include/mico_bt_sco.h @@ -1,47 +1,43 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -/* @file +/** @file * * Bluetooth Synchronous Connection Oriented Channel Application Programming Interface * */ -#ifndef _AOS_BT_SCO_H_ -#define _AOS_BT_SCO_H_ +#ifdef SCO_ENABLE //oscar for mindray + -#ifdef SCO_ENABLE //oscar for mindray +#pragma once -#include "aos.h" -#include "aos_bt_dev.h" -/***************************************************** +#include "mico.h" +#include "mico_bt_dev.h" +/****************************************************** * Constants ******************************************************/ -/***************************************************** +/****************************************************** * Type Definitions ******************************************************/ /* Subset for the enhanced setup/accept synchronous connection paramters * See BT 4.1 or later HCI spec for details */ typedef struct { - uint16_t max_latency; /* Maximum latency (0x4-0xFFFE in msecs) */ - uint16_t packet_types; /* Packet Types */ - uint8_t retrans_effort; /* 0x00-0x02, 0xFF don't care */ - aos_bool_t use_wbs; /* True to use wide band, False to use narrow band */ + uint16_t max_latency; /**< Maximum latency (0x4-0xFFFE in msecs) */ + uint16_t packet_types; /**< Packet Types */ + uint8_t retrans_effort; /**< 0x00-0x02, 0xFF don't care */ + mico_bool_t use_wbs; /**< True to use wide band, False to use narrow band */ -} aos_bt_sco_params_t; +} mico_bt_sco_params_t; -/* +/** * @addtogroup sco_api_functions Synchronous Connection Oriented (SCO) Channel - * @ingroup aosbt + * @ingroup micobt * * SCO Functions * * @{ */ -/***************************************************** +/****************************************************** * Function Declarations ******************************************************/ #ifdef __cplusplus @@ -49,8 +45,8 @@ extern "C" { #endif -/* - * Function aos_bt_sco_create_as_initiator +/** + * Function mico_bt_sco_create_as_initiator * * Creates a synchronous connection oriented connection as initiator. * @@ -58,56 +54,56 @@ extern "C" * @param[in] p_params : Pointer to the SCO parameter structure * @param[out] p_sco_index : SCO index returned * - * @return AOS_BT_UNKNOWN_ADDR : Create connection failed, ACL connection is not up - * AOS_BT_BUSY : Create connection failed, another SCO is being + * @return MICO_BT_UNKNOWN_ADDR : Create connection failed, ACL connection is not up + * MICO_BT_BUSY : Create connection failed, another SCO is being * conncted to the same BD address - * AOS_BT_WRONG_MODE : Create connection failed, wrong mode - * AOS_BT_NO_RESOURCES : Create connection failed, max SCO limit has been + * MICO_BT_WRONG_MODE : Create connection failed, wrong mode + * MICO_BT_NO_RESOURCES : Create connection failed, max SCO limit has been * reached * BTM_CMD_STARTED : Create connection successfully, "p_sco_index" is returned */ -aos_bt_dev_status_t aos_bt_sco_create_as_initiator (aos_bt_device_address_t bd_addr, - uint16_t *p_sco_index, - aos_bt_sco_params_t *p_params); +mico_bt_dev_status_t mico_bt_sco_create_as_initiator (mico_bt_device_address_t bd_addr, + uint16_t *p_sco_index, + mico_bt_sco_params_t *p_params); -/* - * Function aos_bt_sco_create_as_acceptor +/** + * Function mico_bt_sco_create_as_acceptor * * Creates a synchronous connection oriented connection as acceptor. * * @param[out] p_sco_index : SCO index returned * - * @return AOS_BT_UNKNOWN_ADDR : Create connection failed, ACL connection is not up or + * @return MICO_BT_UNKNOWN_ADDR : Create connection failed, ACL connection is not up or * address is invalid - * AOS_BT_BUSY : Create connection failed, a SCO connection is already + * MICO_BT_BUSY : Create connection failed, a SCO connection is already * conncted to the same BD address - * AOS_BT_WRONG_MODE : Create connection failed, link in park mode or + * MICO_BT_WRONG_MODE : Create connection failed, link in park mode or * automatic un-park is not supported - * AOS_BT_NO_RESOURCES : Create connection failed, max SCO limit has been + * MICO_BT_NO_RESOURCES : Create connection failed, max SCO limit has been * reached * BTM_CMD_STARTED : Create connection successfully, "p_sco_index" is returned */ -aos_bt_dev_status_t aos_bt_sco_create_as_acceptor (uint16_t *p_sco_index); +mico_bt_dev_status_t mico_bt_sco_create_as_acceptor (uint16_t *p_sco_index); -/* - * Function aos_bt_sco_remove +/** + * Function mico_bt_sco_remove * * Removes a specific synchronous connection oriented connection. * * @param[in] sco_index : SCO index to remove * - * @return AOS_BT_UNKNOWN_ADDR : Remove connection failed, invalid SCO index - * AOS_BT_NO_RESOURCES : Remove connection failed, no resource - * AOS_BT_SUCCESS : Remove connection successfully, device is still + * @return MICO_BT_UNKNOWN_ADDR : Remove connection failed, invalid SCO index + * MICO_BT_NO_RESOURCES : Remove connection failed, no resource + * MICO_BT_SUCCESS : Remove connection successfully, device is still * listening for incoming connection * BTM_CMD_STARTED : Remove connection successfully */ -aos_bt_dev_status_t aos_bt_sco_remove (uint16_t sco_index); +mico_bt_dev_status_t mico_bt_sco_remove (uint16_t sco_index); -/* - * Function aos_bt_sco_accept_connection +/** + * Function mico_bt_sco_accept_connection * - * Called to handle (e)SCO connection request event (aos_bt_sco_connect_request_event). + * Called to handle (e)SCO connection request event (mico_bt_sco_connect_request_event). * * * @param[in] sco_index : SCO index to remove @@ -119,14 +115,12 @@ aos_bt_dev_status_t aos_bt_sco_remove (uint16_t sco_index); * @param[in] p_params : Pointer to the SCO parameter structure * */ -void aos_bt_sco_accept_connection (uint16_t sco_index, uint8_t hci_status, - aos_bt_sco_params_t *p_params); +void mico_bt_sco_accept_connection (uint16_t sco_index, uint8_t hci_status, + mico_bt_sco_params_t *p_params); #ifdef __cplusplus } #endif -/* @} aosbt_sco */ - -#endif +/** @} micobt_sco */ #endif diff --git a/kernel/protocols/bluetooth/include/aos_bt_sdp.h b/device/bluetooth/mk3239/include/mico_bt_sdp.h similarity index 63% rename from kernel/protocols/bluetooth/include/aos_bt_sdp.h rename to device/bluetooth/mk3239/include/mico_bt_sdp.h index 183265a2e5..99dd7e75fa 100644 --- a/kernel/protocols/bluetooth/include/aos_bt_sdp.h +++ b/device/bluetooth/mk3239/include/mico_bt_sdp.h @@ -1,129 +1,124 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ -/* @file +/** @file * * Bluetooth SDP Application Programming Interface * */ +#pragma once -#ifndef _AOS_BT_SDP_H_ -#define _AOS_BT_SDP_H_ - -#include "aos_bt_dev.h" +#include "mico_bt_dev.h" #include "sdpdefs.h" -/**************************************************************************** +/***************************************************************************** * Constants ****************************************************************************/ -/* SDP result - Success code and error codes */ -enum aos_bt_sdp_result_t { - AOS_BT_SDP_SUCCESS = AOS_BT_SUCCESS, /* SDP - Result: Success */ - AOS_BT_SDP_INVALID_VERSION = 0x0001, /* SDP - invalid version */ - AOS_BT_SDP_INVALID_SERV_REC_HDL = 0x0002, /* SDP - invalid service record */ - AOS_BT_SDP_INVALID_REQ_SYNTAX = 0x0003, /* SDP - invalid request syntax */ - AOS_BT_SDP_INVALID_PDU_SIZE = 0x0004, /* SDP - invalid PDU size */ - AOS_BT_SDP_INVALID_CONT_STATE = 0x0005, /* SDP - invalid controller state */ - AOS_BT_SDP_NO_RESOURCES = 0x0006, /* SDP - no resources */ - AOS_BT_SDP_DI_REG_FAILED = 0x0007, /* SDP - registration failed */ - AOS_BT_SDP_DI_DISC_FAILED = 0x0008, /* SDP - discovery failed */ - AOS_BT_SDP_NO_DI_RECORD_FOUND = 0x0009, /* SDP - no record found */ - AOS_BT_SDP_ERR_ATTR_NOT_PRESENT = 0x000A, /* SDP - no attribute present */ - AOS_BT_SDP_ILLEGAL_PARAMETER = 0x000B, /* SDP - Illegal parameter */ - - AOS_BT_SDP_NO_RECS_MATCH = 0xFFF0, /* SDP - No records match */ - AOS_BT_SDP_CONN_FAILED = 0xFFF1, /* SDP - Connection failed */ - AOS_BT_SDP_CFG_FAILED = 0xFFF2, /* SDP - Configuration failed */ - AOS_BT_SDP_GENERIC_ERROR = 0xFFF3, /* SDP - Generic error */ - AOS_BT_SDP_DB_FULL = 0xFFF4, /* SDP - DB full */ - AOS_BT_SDP_INVALID_PDU = 0xFFF5, /* SDP - Invalid PDU */ - AOS_BT_SDP_SECURITY_ERR = 0xFFF6, /* SDP - Security Error */ - AOS_BT_SDP_CONN_REJECTED = 0xFFF7, /* SDP - Connection rejected */ - AOS_BT_SDP_CANCEL = 0xFFF8 /* SDP - cancel */ +/** SDP result - Success code and error codes */ +enum mico_bt_sdp_result_t { + MICO_BT_SDP_SUCCESS = MICO_BT_SUCCESS, /**< SDP - Result: Success */ + MICO_BT_SDP_INVALID_VERSION = 0x0001, /**< SDP - invalid version */ + MICO_BT_SDP_INVALID_SERV_REC_HDL = 0x0002, /**< SDP - invalid service record */ + MICO_BT_SDP_INVALID_REQ_SYNTAX = 0x0003, /**< SDP - invalid request syntax */ + MICO_BT_SDP_INVALID_PDU_SIZE = 0x0004, /**< SDP - invalid PDU size */ + MICO_BT_SDP_INVALID_CONT_STATE = 0x0005, /**< SDP - invalid controller state */ + MICO_BT_SDP_NO_RESOURCES = 0x0006, /**< SDP - no resources */ + MICO_BT_SDP_DI_REG_FAILED = 0x0007, /**< SDP - registration failed */ + MICO_BT_SDP_DI_DISC_FAILED = 0x0008, /**< SDP - discovery failed */ + MICO_BT_SDP_NO_DI_RECORD_FOUND = 0x0009, /**< SDP - no record found */ + MICO_BT_SDP_ERR_ATTR_NOT_PRESENT = 0x000A, /**< SDP - no attribute present */ + MICO_BT_SDP_ILLEGAL_PARAMETER = 0x000B, /**< SDP - Illegal parameter */ + + MICO_BT_SDP_NO_RECS_MATCH = 0xFFF0, /**< SDP - No records match */ + MICO_BT_SDP_CONN_FAILED = 0xFFF1, /**< SDP - Connection failed */ + MICO_BT_SDP_CFG_FAILED = 0xFFF2, /**< SDP - Configuration failed */ + MICO_BT_SDP_GENERIC_ERROR = 0xFFF3, /**< SDP - Generic error */ + MICO_BT_SDP_DB_FULL = 0xFFF4, /**< SDP - DB full */ + MICO_BT_SDP_INVALID_PDU = 0xFFF5, /**< SDP - Invalid PDU */ + MICO_BT_SDP_SECURITY_ERR = 0xFFF6, /**< SDP - Security Error */ + MICO_BT_SDP_CONN_REJECTED = 0xFFF7, /**< SDP - Connection rejected */ + MICO_BT_SDP_CANCEL = 0xFFF8 /**< SDP - cancel */ }; /* Define the PSM that SDP uses */ #define SDP_PSM 0x0001 -/* Masks for attr_value field of aos_bt_sdp_discovery_attribute_t */ +/* Masks for attr_value field of mico_bt_sdp_discovery_attribute_t */ #define SDP_DISC_ATTR_LEN_MASK 0x0FFF #define SDP_DISC_ATTR_TYPE(len_type) (len_type >> 12) #define SDP_DISC_ATTR_LEN(len_type) (len_type & SDP_DISC_ATTR_LEN_MASK) -/* Maximum number of protocol list items (list_elem in aos_bt_sdp_protocol_elem_t) */ +/* Maximum number of protocol list items (list_elem in mico_bt_sdp_protocol_elem_t) */ #define SDP_MAX_LIST_ELEMS 3 -/**************************************************************************** +/***************************************************************************** * Type Definitions ****************************************************************************/ -/* - * Function aos_bt_sdp_discovery_complete_cback_t +/** + * Function mico_bt_sdp_discovery_complete_cback_t * * Service discovery complete callback. * - * If discovery was successful, the discovery results database (provided when #aos_bt_sdp_service_search_request - * or #aos_bt_sdp_service_search_attribute_request was called) will be filled. + * If discovery was successful, the discovery results database (provided when #mico_bt_sdp_service_search_request + * or #mico_bt_sdp_service_search_attribute_request was called) will be filled. * - * Use the aos_bt_sdp_find_* utility functions to parse the results. + * Use the mico_bt_sdp_find_* utility functions to parse the results. * - * @param[in] sdp_result : SDP result code (see #aos_bt_sdp_result_t) + * @param[in] sdp_result : SDP result code (see #mico_bt_sdp_result_t) * * @return Nothing * */ -typedef void (aos_bt_sdp_discovery_complete_cback_t) (uint16_t sdp_result); +typedef void (mico_bt_sdp_discovery_complete_cback_t) (uint16_t sdp_result); -/* Attribute value */ +/** Attribute value */ typedef struct { union { - uint8_t u8; /* 8-bit integer */ - uint16_t u16; /* 16-bit integer */ - uint32_t u32; /* 32-bit integer */ - uint8_t array[4]; /* Variable length field */ - struct t_sdp_discovery_attr *p_sub_attr; /* Addr of first sub-attr (list)*/ + uint8_t u8; /**< 8-bit integer */ + uint16_t u16; /**< 16-bit integer */ + uint32_t u32; /**< 32-bit integer */ + uint8_t array[4]; /**< Variable length field */ + struct t_sdp_discovery_attr *p_sub_attr; /**< Addr of first sub-attr (list)*/ } v; -} aos_bt_sdp_discovery_attribute_value_t; +} mico_bt_sdp_discovery_attribute_value_t; -/* SDP Attribute */ +/** SDP Attribute */ typedef struct t_sdp_discovery_attr { - struct t_sdp_disc_attr *p_next_attr; /* Addr of next linked attr */ - uint16_t attr_id; /* Attribute ID */ - uint16_t attr_len_type; /* Length and type fields */ - aos_bt_sdp_discovery_attribute_value_t attr_value; /* Variable length entry data */ -} aos_bt_sdp_discovery_attribute_t; + struct t_sdp_disc_attr *p_next_attr; /**< Addr of next linked attr */ + uint16_t attr_id; /**< Attribute ID */ + uint16_t attr_len_type; /**< Length and type fields */ + mico_bt_sdp_discovery_attribute_value_t attr_value; /**< Variable length entry data */ +} mico_bt_sdp_discovery_attribute_t; -/* Discovery record from SDP search result */ +/** Discovery record from SDP search result */ typedef struct sdp_discovery_record_t { - aos_bt_sdp_discovery_attribute_t *p_first_attr; /* First attribute of record */ - struct sdp_discovery_record_t *p_next_rec; /* Addr of next linked record */ - uint32_t time_read; /* The time the record was read */ - aos_bt_device_address_t remote_bd_addr; /* Remote BD address */ -} aos_bt_sdp_discovery_record_t; + mico_bt_sdp_discovery_attribute_t *p_first_attr; /**< First attribute of record */ + struct sdp_discovery_record_t *p_next_rec; /**< Addr of next linked record */ + uint32_t time_read; /**< The time the record was read */ + mico_bt_device_address_t remote_bd_addr; /**< Remote BD address */ +} mico_bt_sdp_discovery_record_t; -/* Discovery database (used for performing service searches and holding search results) */ +/** Discovery database (used for performing service searches and holding search results) */ typedef struct { - uint32_t mem_size; /* Memory size of the DB */ - uint32_t mem_free; /* Memory still available */ - aos_bt_sdp_discovery_record_t *p_first_rec; /* Addr of first record in DB */ - uint16_t num_uuid_filters; /* Number of UUIds to filter */ - aos_bt_uuid_t uid_filters[SDP_MAX_UUID_FILTERS]; /* UUIDs to filter */ - uint16_t num_attr_filters; /* Number of attribute filters */ - uint16_t attr_filters[SDP_MAX_ATTR_FILTERS]; /* Attributes to filter */ - uint8_t *p_free_mem; /* Pointer to free memory */ -} aos_bt_sdp_discovery_db_t; - -/* This structure is used to add protocol lists and find protocol elements */ + uint32_t mem_size; /**< Memory size of the DB */ + uint32_t mem_free; /**< Memory still available */ + mico_bt_sdp_discovery_record_t *p_first_rec; /**< Addr of first record in DB */ + uint16_t num_uuid_filters; /**< Number of UUIds to filter */ + mico_bt_uuid_t uid_filters[SDP_MAX_UUID_FILTERS]; /**< UUIDs to filter */ + uint16_t num_attr_filters; /**< Number of attribute filters */ + uint16_t attr_filters[SDP_MAX_ATTR_FILTERS]; /**< Attributes to filter */ + uint8_t *p_free_mem; /**< Pointer to free memory */ +} mico_bt_sdp_discovery_db_t; + +/** This structure is used to add protocol lists and find protocol elements */ typedef struct { - uint16_t protocol_uuid; /* The protocol uuid */ - uint16_t num_params; /* Number of parameters */ - uint16_t params[SDP_MAX_PROTOCOL_PARAMS]; /* Contents of protocol parameters */ -} aos_bt_sdp_protocol_elem_t; + uint16_t protocol_uuid; /**< The protocol uuid */ + uint16_t num_params; /**< Number of parameters */ + uint16_t params[SDP_MAX_PROTOCOL_PARAMS]; /**< Contents of protocol parameters */ +} mico_bt_sdp_protocol_elem_t; -/**************************************************************************** +/***************************************************************************** * SDP Server Database Macros ****************************************************************************/ #define SDP_UINT1(value) (value) @@ -266,16 +261,16 @@ typedef struct { #define SDP_ATTR_SERVICE_DATABASE_STATE(state) \ SDP_ATTR_UINT4(ATTR_ID_VENDOR_ID, state) -/************************************************************************//* +/*************************************************************************//** * @addtogroup sdp_api_functions Service Discovery (SDP) - * @ingroup aosbt + * @ingroup micobt * * Service Discovery (SDP) Functions. * * @{ ****************************************************************************/ -/***************************************************** +/****************************************************** * Function Declarations ******************************************************/ #ifdef __cplusplus @@ -285,12 +280,12 @@ extern "C" /* SDP Server APIs */ -/* +/** * - * Function aos_bt_sdp_db_init + * Function mico_bt_sdp_db_init * * Initialize local SDP server database (database generated using - * AOS Smart/SmartReady Designer) + * MiCO Smart/SmartReady Designer) * * @param[in] p_sdp_db: First element in database array * @param[in] size: size (in bytes) of SDP database @@ -298,17 +293,17 @@ extern "C" * @return TRUE if successful, FALSE otherwise * **/ -aos_bool_t aos_bt_sdp_db_init (uint8_t *p_sdp_db, uint16_t size); +mico_bool_t mico_bt_sdp_db_init (uint8_t *p_sdp_db, uint16_t size); /* SDP Client APIs */ -/* +/** * - * Function aos_bt_sdp_init_discovery_db + * Function mico_bt_sdp_init_discovery_db * * Initialize discovery database prior to performing service - * discovery (using #aos_bt_sdp_service_search_request or - * #aos_bt_sdp_service_search_request). + * discovery (using #mico_bt_sdp_service_search_request or + * #mico_bt_sdp_service_search_request). * * Provides a list of UUIDs and/or attribute IDs to search for. * @@ -322,15 +317,15 @@ aos_bool_t aos_bt_sdp_db_init (uint8_t *p_sdp_db, uint16_t size); * @return TRUE if successful, FALSE if one or more parameters are bad * **/ -aos_bool_t aos_bt_sdp_init_discovery_db (aos_bt_sdp_discovery_db_t *p_db, uint32_t len, - uint16_t num_uuid, - aos_bt_uuid_t *p_uuid_list, - uint16_t num_attr, - uint16_t *p_attr_list); +mico_bool_t mico_bt_sdp_init_discovery_db (mico_bt_sdp_discovery_db_t *p_db, uint32_t len, + uint16_t num_uuid, + mico_bt_uuid_t *p_uuid_list, + uint16_t num_attr, + uint16_t *p_attr_list); -/* +/** * - * Function aos_bt_sdp_cancel_service_search + * Function mico_bt_sdp_cancel_service_search * * Cancel service search request * @@ -339,50 +334,50 @@ aos_bool_t aos_bt_sdp_init_discovery_db (aos_bt_sdp_discovery_db_t *p_db, uint32 * @return TRUE if discovery cancelled, FALSE if a matching activity is not found. * **/ -aos_bool_t aos_bt_sdp_cancel_service_search (aos_bt_sdp_discovery_db_t *p_db); +mico_bool_t mico_bt_sdp_cancel_service_search (mico_bt_sdp_discovery_db_t *p_db); -/* +/** * - * Function aos_bt_sdp_service_search_request + * Function mico_bt_sdp_service_search_request * * Initiate service search on remote device * * @param[in] p_bd_addr : Remote device address - * @param[in] p_db : Discovery database of UUIDs and attribute IDs to search for (intialized using #aos_bt_sdp_init_discovery_db) + * @param[in] p_db : Discovery database of UUIDs and attribute IDs to search for (intialized using #mico_bt_sdp_init_discovery_db) * @param[in] p_cb : Callback for discovery results * * @return TRUE if discovery started, FALSE if failed. * **/ -aos_bool_t aos_bt_sdp_service_search_request (uint8_t *p_bd_addr, - aos_bt_sdp_discovery_db_t *p_db, - aos_bt_sdp_discovery_complete_cback_t *p_cb); +mico_bool_t mico_bt_sdp_service_search_request (uint8_t *p_bd_addr, + mico_bt_sdp_discovery_db_t *p_db, + mico_bt_sdp_discovery_complete_cback_t *p_cb); -/* +/** * - * Function aos_bt_sdp_service_search_attribute_request + * Function mico_bt_sdp_service_search_attribute_request * * Initiate combined service search and attribute request on remote device * * @param[in] p_bd_addr : Remote device address - * @param[in] p_db : Discovery database of UUIDs and attribute IDs to search for (intialized using #aos_bt_sdp_init_discovery_db) + * @param[in] p_db : Discovery database of UUIDs and attribute IDs to search for (intialized using #mico_bt_sdp_init_discovery_db) * @param[in] p_cb : Callback for discovery results * * @return TRUE if discovery started, FALSE if failed. * **/ -aos_bool_t aos_bt_sdp_service_search_attribute_request (uint8_t *p_bd_addr, - aos_bt_sdp_discovery_db_t *p_db, - aos_bt_sdp_discovery_complete_cback_t *p_cb); +mico_bool_t mico_bt_sdp_service_search_attribute_request (uint8_t *p_bd_addr, + mico_bt_sdp_discovery_db_t *p_db, + mico_bt_sdp_discovery_complete_cback_t *p_cb); /* API of utilities to find data in the local discovery database */ -/* +/** * - * Function aos_bt_sdp_find_attribute_in_db + * Function mico_bt_sdp_find_attribute_in_db * * Parse results from service search. Look next record in discovery database * containing attribute ID. @@ -394,14 +389,14 @@ aos_bool_t aos_bt_sdp_service_search_attribute_request (uint8_t *p_bd_addr, * @return Pointer to matching record, or NULL * **/ -aos_bt_sdp_discovery_record_t *aos_bt_sdp_find_attribute_in_db (aos_bt_sdp_discovery_db_t *p_db, - uint16_t attr_id, - aos_bt_sdp_discovery_record_t *p_start_rec); +mico_bt_sdp_discovery_record_t *mico_bt_sdp_find_attribute_in_db (mico_bt_sdp_discovery_db_t *p_db, + uint16_t attr_id, + mico_bt_sdp_discovery_record_t *p_start_rec); -/* +/** * - * Function aos_bt_sdp_find_attribute_in_rec + * Function mico_bt_sdp_find_attribute_in_rec * * Parse SDP record. Look for requested attribute in the service record. * @@ -411,13 +406,13 @@ aos_bt_sdp_discovery_record_t *aos_bt_sdp_find_attribute_in_db (aos_bt_sdp_disco * @return Pointer to matching attribute entry, or NULL * **/ -aos_bt_sdp_discovery_attribute_t *aos_bt_sdp_find_attribute_in_rec (aos_bt_sdp_discovery_record_t *p_rec, - uint16_t attr_id); +mico_bt_sdp_discovery_attribute_t *mico_bt_sdp_find_attribute_in_rec (mico_bt_sdp_discovery_record_t *p_rec, + uint16_t attr_id); -/* +/** * - * Function aos_bt_sdp_find_service_in_db + * Function mico_bt_sdp_find_service_in_db * * Parse results from service search. Look next record in discovery database * containing requested service UUID (specified using uint16_t) @@ -429,17 +424,17 @@ aos_bt_sdp_discovery_attribute_t *aos_bt_sdp_find_attribute_in_rec (aos_bt_sdp_d * @return Pointer to matching record, or NULL * **/ -aos_bt_sdp_discovery_record_t *aos_bt_sdp_find_service_in_db (aos_bt_sdp_discovery_db_t *p_db, - uint16_t service_uuid, - aos_bt_sdp_discovery_record_t *p_start_rec); +mico_bt_sdp_discovery_record_t *mico_bt_sdp_find_service_in_db (mico_bt_sdp_discovery_db_t *p_db, + uint16_t service_uuid, + mico_bt_sdp_discovery_record_t *p_start_rec); -/* +/** * - * Function aos_bt_sdp_find_service_uuid_in_db + * Function mico_bt_sdp_find_service_uuid_in_db * * Parse results from service search. Look next record in discovery database - * containing requested service UUID (specified using aos_bt_uuid_t structure) + * containing requested service UUID (specified using mico_bt_uuid_t structure) * * @param[in] p_db : Discovery results database * @param[in] p_uuid : Service to find @@ -448,14 +443,14 @@ aos_bt_sdp_discovery_record_t *aos_bt_sdp_find_service_in_db (aos_bt_sdp_discove * @return Pointer to matching record, or NULL * **/ -aos_bt_sdp_discovery_record_t *aos_bt_sdp_find_service_uuid_in_db (aos_bt_sdp_discovery_db_t *p_db, - aos_bt_uuid_t *p_uuid, - aos_bt_sdp_discovery_record_t *p_start_rec); +mico_bt_sdp_discovery_record_t *mico_bt_sdp_find_service_uuid_in_db (mico_bt_sdp_discovery_db_t *p_db, + mico_bt_uuid_t *p_uuid, + mico_bt_sdp_discovery_record_t *p_start_rec); -/* +/** * - * Function aos_bt_sdp_find_protocol_list_elem_in_rec + * Function mico_bt_sdp_find_protocol_list_elem_in_rec * * Parse SDP record. Look for requested protocol list element in the service record. * @@ -466,13 +461,13 @@ aos_bt_sdp_discovery_record_t *aos_bt_sdp_find_service_uuid_in_db (aos_bt_sdp_di * @return TRUE if found, else FALSE * **/ -aos_bool_t aos_bt_sdp_find_protocol_list_elem_in_rec (aos_bt_sdp_discovery_record_t *p_rec, - uint16_t layer_uuid, - aos_bt_sdp_protocol_elem_t *p_elem); +mico_bool_t mico_bt_sdp_find_protocol_list_elem_in_rec (mico_bt_sdp_discovery_record_t *p_rec, + uint16_t layer_uuid, + mico_bt_sdp_protocol_elem_t *p_elem); -/* +/** * - * Function aos_bt_sdp_find_protocol_lists_elem_in_rec + * Function mico_bt_sdp_find_protocol_lists_elem_in_rec * * Parse SDP record. Look for requested protocol lists element in the service record. * @@ -483,13 +478,13 @@ aos_bool_t aos_bt_sdp_find_protocol_list_elem_in_rec (aos_bt_sdp_discovery_recor * @return TRUE if found, else FALSE * **/ -aos_bool_t aos_bt_sdp_find_protocol_lists_elem_in_rec (aos_bt_sdp_discovery_record_t *p_rec, - uint16_t layer_uuid, - aos_bt_sdp_protocol_elem_t *p_elem); +mico_bool_t mico_bt_sdp_find_protocol_lists_elem_in_rec (mico_bt_sdp_discovery_record_t *p_rec, + uint16_t layer_uuid, + mico_bt_sdp_protocol_elem_t *p_elem); -/* +/** * - * Function aos_bt_sdp_find_profile_version_in_rec + * Function mico_bt_sdp_find_profile_version_in_rec * * Parse SDP record. Look for version of requested profile. * @@ -500,13 +495,13 @@ aos_bool_t aos_bt_sdp_find_protocol_lists_elem_in_rec (aos_bt_sdp_discovery_reco * @return TRUE if found, FALSE if not * **/ -aos_bool_t aos_bt_sdp_find_profile_version_in_rec (aos_bt_sdp_discovery_record_t *p_rec, - uint16_t profile_uuid, - uint16_t *p_version); +mico_bool_t mico_bt_sdp_find_profile_version_in_rec (mico_bt_sdp_discovery_record_t *p_rec, + uint16_t profile_uuid, + uint16_t *p_version); -/* +/** * - * Function aos_bt_sdp_find_service_uuid_in_rec + * Function mico_bt_sdp_find_service_uuid_in_rec * * Parse SDP record. Look for service UUID * @@ -516,12 +511,10 @@ aos_bool_t aos_bt_sdp_find_profile_version_in_rec (aos_bt_sdp_discovery_record_t * @return TRUE if found, FALSE if not * **/ -aos_bool_t aos_bt_sdp_find_service_uuid_in_rec(aos_bt_sdp_discovery_record_t *p_rec, aos_bt_uuid_t *p_uuid); +mico_bool_t mico_bt_sdp_find_service_uuid_in_rec(mico_bt_sdp_discovery_record_t *p_rec, mico_bt_uuid_t *p_uuid); #ifdef __cplusplus } #endif -#endif - -/*@} sdp_api_functions */ +/**@} sdp_api_functions */ diff --git a/device/bluetooth/mk3239/include/mico_bt_stack.h b/device/bluetooth/mk3239/include/mico_bt_stack.h new file mode 100644 index 0000000000..fed5e4b303 --- /dev/null +++ b/device/bluetooth/mk3239/include/mico_bt_stack.h @@ -0,0 +1,79 @@ + +/** @file + * + * Bluetooth Management (BTM) Application Programming Interface + * + * The BTM consists of several management entities: + * 1. Device Control - controls the local device + * 2. Device Discovery - manages inquiries, discover database + * 3. ACL Channels - manages ACL connections (BR/EDR and LE) + * 4. SCO Channels - manages SCO connections + * 5. Security - manages all security functionality + * 6. Power Management - manages park, sniff, hold, etc. + * + * @defgroup micobt Bluetooth + * + * MiCO Bluetooth Framework Functions + */ + +#pragma once + +#include "mico_bt_dev.h" +#include "mico_bt_cfg.h" + +/****************************************************** + * Function Declarations + ******************************************************/ +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************************************/ +/** + * Framework Management Functions + * + * @addtogroup micobt_Framework Framework + * @ingroup micobt + * + * @{ + */ +/****************************************************************************/ + +/** + * Function mico_bt_stack_init + * + * Initialize the Bluetooth controller and stack; register + * callback for Bluetooth event notification. + * + * @param[in] p_bt_management_cback : Callback for receiving Bluetooth management events + * @param[in] p_bt_cfg_settings : Bluetooth stack configuration + * @param[in] mico_bt_cfg_buf_pools : Buffer pool configuration + * + * @return MICO_BT_SUCCESS : on success; + * MICO_BT_FAILED : if an error occurred + */ +mico_bt_result_t mico_bt_stack_init(mico_bt_management_cback_t *p_bt_management_cback, + const mico_bt_cfg_settings_t *p_bt_cfg_settings, + const mico_bt_cfg_buf_pool_t mico_bt_cfg_buf_pools[MICO_BT_CFG_NUM_BUF_POOLS]); + + + +/** + * Function mico_bt_stack_deinit + * + * De-initialize the Bluetooth controller and stack. + * + * @return MICO_BT_SUCCESS : on success; + * MICO_BT_ERROR : if an error occurred + */ +OSStatus mico_bt_stack_deinit(void); + + +/**@} micobt_Framework */ + + +#ifdef __cplusplus +} +#endif + + diff --git a/device/bluetooth/mk3239/include/mico_bt_types.h b/device/bluetooth/mk3239/include/mico_bt_types.h new file mode 100644 index 0000000000..3a37056a96 --- /dev/null +++ b/device/bluetooth/mk3239/include/mico_bt_types.h @@ -0,0 +1,114 @@ + +/** @file + * + * Generic types + * + */ +#pragma once +#include "common.h" +#include "data_types.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +#define BD_ADDR_LEN 6 +typedef uint8_t mico_bt_device_address_t[BD_ADDR_LEN]; /**< Device address length */ + +typedef uint8_t *mico_bt_device_address_ptr_t; /**< Device address Pointer */ + +#define DEV_CLASS_LEN 3 +typedef uint8_t mico_bt_dev_class_t[DEV_CLASS_LEN]; /**< Device class */ + +#define MAX_UUID_SIZE 16 /**< Maximum UUID size - 16 bytes, and structure to hold any type of UUID. */ + +/** UUID Type */ +typedef struct { +#define LEN_UUID_16 2 +#define LEN_UUID_32 4 +#define LEN_UUID_128 16 + + uint16_t len; /**< UUID length */ + + union { + uint16_t uuid16; /**< 16-bit UUID */ + uint32_t uuid32; /**< 32-bit UUID */ + uint8_t uuid128[MAX_UUID_SIZE]; /**< 128-bit UUID */ + } uu; + +} mico_bt_uuid_t; + +#define BT_OCTET16_LEN 16 /**< length: 16 */ +typedef uint8_t BT_OCTET16[BT_OCTET16_LEN]; /**< octet array: size 16 */ + +#define BT_OCTET32_LEN 32 +typedef uint8_t BT_OCTET32[BT_OCTET32_LEN]; /* octet array: size 32 */ + +/** Bluetooth QoS defintions */ +typedef struct { + uint8_t qos_flags; /**< TBD */ + uint8_t service_type; /**< service type (NO_TRAFFIC, BEST_EFFORT, or GUARANTEED) */ + uint32_t token_rate; /**< token rate (bytes/second) */ + uint32_t token_bucket_size; /**< token bucket size (bytes) */ + uint32_t peak_bandwidth; /**< peak bandwidth (bytes/second) */ + uint32_t latency; /**< latency (microseconds) */ + uint32_t delay_variation; /**< delay variation (microseconds) */ +} mico_bt_flow_spec_t; + +/* Values for smico_bt_flow_spec_t service_type */ +#define NO_TRAFFIC 0 +#define BEST_EFFORT 1 +#define GUARANTEED 2 + +/** + * @anchor MICO_BT_TRANSPORT_TYPE + * @name Transport types + * @{ + */ +#define BT_TRANSPORT_BR_EDR 1 /**< BR/EDR transport */ +#define BT_TRANSPORT_LE 2 /**< BLE transport */ +typedef uint8_t mico_bt_transport_t; /**< Transport type (see @ref MICO_BT_TRANSPORT_TYPE "BT Transport Types") */ + +/** + * @anchor MICO_BT_DEVICE_TYPE + * @name Device Types + * @{ + */ +#define BT_DEVICE_TYPE_BREDR 0x01 /**< BR/EDR device */ +#define BT_DEVICE_TYPE_BLE 0x02 /**< LE device */ +#define BT_DEVICE_TYPE_BREDR_BLE 0x03 /**< Dual Mode device */ +typedef uint8_t +mico_bt_device_type_t; /**< Bluetooth device type (see @ref MICO_BT_DEVICE_TYPE "BT Device Types") */ +/** @} MICO_BT_DEVICE_TYPE */ + +/** + * @anchor MICO_BT_ADDR_TYPE + * @name Address Types + * @{ + */ +#define BLE_ADDR_PUBLIC 0x00 /**< Public address */ +#define BLE_ADDR_RANDOM 0x01 /**< Random address */ +#define BLE_ADDR_PUBLIC_ID 0x02 /**< Public ID */ +#define BLE_ADDR_RANDOM_ID 0x03 /**< Random ID */ +typedef uint8_t +mico_bt_ble_address_type_t; /**< BLE device address type (see @ref MICO_BT_ADDR_TYPE "BT Address Types")*/ +#define BLE_ADDR_TYPE_MASK (BLE_ADDR_RANDOM | BLE_ADDR_PUBLIC) +/** @} MICO_BT_ADDR_TYPE */ + +typedef struct { + mico_bt_ble_address_type_t type; + mico_bt_device_address_t bda; +} mico_bt_ble_address_t; + +#define LINK_KEY_LEN 16 +typedef uint8_t mico_bt_link_key_t[LINK_KEY_LEN]; + +#define BT_ROLE_MASTER 0x00 +#define BT_ROLE_SLAVE 0x01 +typedef uint8_t mico_bt_ble_link_role_t; + + +#ifdef __cplusplus +} +#endif diff --git a/kernel/protocols/bluetooth/include/sdpdefs.h b/device/bluetooth/mk3239/include/sdpdefs.h similarity index 96% rename from kernel/protocols/bluetooth/include/sdpdefs.h rename to device/bluetooth/mk3239/include/sdpdefs.h index 386708b528..edad09724d 100644 --- a/kernel/protocols/bluetooth/include/sdpdefs.h +++ b/device/bluetooth/mk3239/include/sdpdefs.h @@ -2,12 +2,18 @@ * Copyright (C) 2015-2017 Alibaba Group Holding Limited */ -#ifndef _SDP_DEFS_H_ -#define _SDP_DEFS_H_ +/**************************************************************************** +** +** Name: sdp_defs.h +** +** Function this file contains the definitions for the SDP API +** +******************************************************************************/ +#ifndef SDP_DEFS_H +#define SDP_DEFS_H -/* - * Define the service attribute IDs. - */ +/* Define the service attribute IDs. +*/ #define ATTR_ID_SERVICE_RECORD_HDL 0x0000 #define ATTR_ID_SERVICE_CLASS_ID_LIST 0x0001 #define ATTR_ID_SERVICE_RECORD_STATE 0x0002 @@ -28,9 +34,8 @@ #define ATTR_ID_SERVICE_DESCRIPTION LANGUAGE_BASE_ID + 0x0001 #define ATTR_ID_PROVIDER_NAME LANGUAGE_BASE_ID + 0x0002 -/* - * Device Identification (DI) - */ +/* Device Identification (DI) +*/ #define ATTR_ID_SPECIFICATION_ID 0x0200 #define ATTR_ID_VENDOR_ID 0x0201 #define ATTR_ID_PRODUCT_ID 0x0202 @@ -75,10 +80,9 @@ #define ATTR_ID_INSTANCE_ID 0x0315 /* MAP, CTN profile */ #define ATTR_ID_SUPPORTED_MSG_TYPE 0x0316 /* MAP profile */ -/* - * MAP 1.2 uses this, but PBAP 1.2 and GPP, and - * other profiles can also use this generic 32-bit mask - */ +/* MAP 1.2 uses this, but PBAP 1.2 and GPP, and +** other profiles can also use this generic 32-bit mask +*/ #define ATTR_ID_SUPPORTED_FEATURES_32 0x0317 /* 32-bit supported features */ @@ -145,9 +149,8 @@ #define BTA_MPS_UUID_MPMD_SCENARIOS ((UINT16) 0x201) #define BTA_MPS_UUID_PPD_SUPPORTED ((UINT16) 0x202) -/* - * Define common 16-bit protocol UUIDs - */ +/* Define common 16-bit protocol UUIDs +*/ #define UUID_PROTOCOL_SDP 0x0001 #define UUID_PROTOCOL_UDP 0x0002 #define UUID_PROTOCOL_RFCOMM 0x0003 @@ -174,9 +177,8 @@ #define UUID_PROTOCOL_L2CAP 0x0100 #define UUID_PROTOCOL_ATT 0x0007 -/* - * Define common 16-bit service class UUIDs - */ +/* Define common 16-bit service class UUIDs +*/ #define UUID_SERVCLASS_SERVICE_DISCOVERY_SERVER 0X1000 #define UUID_SERVCLASS_BROWSE_GROUP_DESCRIPTOR 0X1001 #define UUID_SERVCLASS_PUBLIC_BROWSE_GROUP 0X1002 @@ -293,9 +295,8 @@ #define UUID_HF_IND_EDS 0x0001 /* HF indicator for enhanced driver safety */ -/* - * Define all the 'Descriptor Type' values. - */ +/* Define all the 'Descriptor Type' values. +*/ #define NULL_DESC_TYPE 0 #define UINT_DESC_TYPE 1 #define TWO_COMP_INT_DESC_TYPE 2 @@ -306,9 +307,8 @@ #define DATA_ELE_ALT_DESC_TYPE 7 #define URL_DESC_TYPE 8 -/* - * Define all the "Descriptor Size" values. - */ +/* Define all the "Descriptor Size" values. +*/ #define SIZE_ONE_BYTE 0 #define SIZE_TWO_BYTES 1 #define SIZE_FOUR_BYTES 2 @@ -337,3 +337,5 @@ #define ATTR_ID_NETADDRESS_OR_DEVLOCATION 0x0306 #endif + + diff --git a/device/bluetooth/mk3239/low_energy/buildcfg.h b/device/bluetooth/mk3239/low_energy/buildcfg.h index 0c8f9c3c76..587cabfd52 100644 --- a/device/bluetooth/mk3239/low_energy/buildcfg.h +++ b/device/bluetooth/mk3239/low_energy/buildcfg.h @@ -1,6 +1,3 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ #pragma once diff --git a/device/bluetooth/mk3239/low_energy/low_energy.mk b/device/bluetooth/mk3239/low_energy/low_energy.mk index d03c32711f..2111a4f804 100644 --- a/device/bluetooth/mk3239/low_energy/low_energy.mk +++ b/device/bluetooth/mk3239/low_energy/low_energy.mk @@ -1,4 +1,4 @@ -NAME := Lib_Bluetooth_Embedded_Low_energy_Stack_for_$(BT_CHIP)$(BT_CHIP_REVISION) +NAME := lib_ble_low_energy BTE_PLATFORM_DIR := ../BTE_platform @@ -10,16 +10,16 @@ GLOBAL_INCLUDES += . \ BLUETOOTH_LIB_TYPE := low_energy -ifneq ($(wildcard $(CURDIR)BTE_$(BLUETOOTH_LIB_TYPE).$(HOST_ARCH).$(TOOLCHAIN_NAME).release.a),) +#ifneq ($(wildcard $(CURDIR)BTE_$(BLUETOOTH_LIB_TYPE).$(HOST_ARCH).$(TOOLCHAIN_NAME).release.a),) $(NAME)_PREBUILT_LIBRARY := BTE_$(BLUETOOTH_LIB_TYPE).$(HOST_ARCH).$(TOOLCHAIN_NAME).release.a -else +#else # Build from source (MXCHIP internal) -include $(CURDIR)$(BLUETOOTH_LIB_TYPE)_src.mk -endif +#include $(CURDIR)$(BLUETOOTH_LIB_TYPE)_src.mk +#endif # Include appropriate firmware as component -$(NAME)_COMPONENTS += bluetooth.mk3239.firmware +$(NAME)_COMPONENTS += device/bluetooth/mk3239/firmware $(NAME)_SOURCES += $(BTE_PLATFORM_DIR)/mico_bt_bus.c \ $(BTE_PLATFORM_DIR)/mico_bt_hcd.c \ @@ -28,4 +28,3 @@ $(NAME)_SOURCES += $(BTE_PLATFORM_DIR)/mico_bt_bus.c \ $(BTE_PLATFORM_DIR)/mico_upio.c VALID_PLATFORMS := MK3238 MK3239 - diff --git a/device/sal/include/sal.h b/device/sal/include/sal.h index efaee4d0af..92b5e300d6 100644 --- a/device/sal/include/sal.h +++ b/device/sal/include/sal.h @@ -41,7 +41,7 @@ typedef enum netconn_evt { NETCONN_EVT_ERROR } netconn_evt_t; -typedef int (*netconn_data_input_cb_t)(int fd, void *data, size_t len, ip_addr_t *addr, u16_t port); +typedef int (*netconn_data_input_cb_t)(int fd, void *data, size_t len, char remote_ip[16], uint16_t remote_port); typedef struct sal_op_s { char *version; /* Reserved for furture use. */ diff --git a/device/sal/sal.mk b/device/sal/sal.mk index 91a0056109..9c8ba3b59b 100644 --- a/device/sal/sal.mk +++ b/device/sal/sal.mk @@ -1,5 +1,8 @@ NAME := sal -GLOBAL_DEFINES += WITH_SAL # for sal general use + $(NAME)_TYPE := kernel +ifneq (1,$(at_adapter)) +GLOBAL_DEFINES += WITH_SAL # for sal general use $(NAME)_SOURCES := sal_sockets.c sal_err.c sal_arch.c ip4_addr.c sal.c sal_device.c GLOBAL_INCLUDES += ./include +endif diff --git a/device/sal/sal_sockets.c b/device/sal/sal_sockets.c index 39225d0246..20aaf7d880 100644 --- a/device/sal/sal_sockets.c +++ b/device/sal/sal_sockets.c @@ -1276,12 +1276,12 @@ int sal_sendto(int s, const void *data, size_t size, int flags, return ERR_ARG; } - LOCK_SAL_CORE; + /* TODO have no consider tcp server send to client*/ if (NETCONNTYPE_GROUP(pstsalsock->conn->type) == NETCONN_TCP) { if (pstsalsock->conn->state == NETCONN_NONE) { SAL_ERROR("sal_sendto socket %d connect state is %d\n", s, pstsalsock->conn->state); - UNLOCK_SAL_CORE; + return ERR_VAL; } } @@ -1295,7 +1295,7 @@ int sal_sendto(int s, const void *data, size_t size, int flags, err = salnetconn_connect(pstsalsock->conn, ip_str, remote_port); if (ERR_OK != err) { SAL_ERROR("sal_sendto fail to connect socket %d\n", s); - UNLOCK_SAL_CORE; + return err; } } @@ -1303,15 +1303,13 @@ int sal_sendto(int s, const void *data, size_t size, int flags, if (pstsalsock->conn->state == NETCONN_NONE) { SAL_ERROR("sal_sendto socket %d is not connected and " "input addr is null, cannot send packet\n", s); - UNLOCK_SAL_CORE; return ERR_ARG; } } } err = sal_module_send(s, (uint8_t *)data, size, NULL, -1); - UNLOCK_SAL_CORE; - + if (err != ERR_OK){ return -1; } @@ -1324,11 +1322,6 @@ int sal_send(int s, const void *data, size_t size, int flags) SAL_DEBUG("sal_send(%d, flags=0x%x)\n", s, flags); return sal_sendto(s, data, size, flags, NULL, 0); - /*TODO: 1ã€å…ˆè®¤ä¸ºremote adrrå’Œportå¯ä»¥é€šè¿‡conn中获å–, 具体的remote ip - å’Œportä¿¡æ¯çš„填写需è¦å†åˆ†æž - 2ã€å…ˆä¸è€ƒè™‘ipv6 - 3ã€å‘包控制的pcb暂时没有,所以目å‰å‘åŒ…æœ€å¤§é•¿åº¦å…ˆå†™æ­»ä¸€ä¸ªå® - */ } int sal_write(int s, const void *data, size_t size) @@ -1353,7 +1346,7 @@ int sal_write(int s, const void *data, size_t size) return sal_send(s, data, size, 0); } -static int salnetconn_packet_input(sal_netconn_t *conn, void *data, size_t len, ip_addr_t *addr, u16_t port) +static int salnetconn_packet_input(sal_netconn_t *conn, void *data, size_t len, char remote_ip[16], uint16_t remote_port) { sal_netbuf_t *buf; @@ -1378,11 +1371,14 @@ static int salnetconn_packet_input(sal_netconn_t *conn, void *data, size_t len, } memcpy(buf->payload, data, len); buf->len = len; + #if 0 if (NULL != addr){ ip_addr_set(&buf->addr, addr); } - buf->port = port; - + #endif + buf->port = remote_port; + + if(sal_mbox_trypost(&conn->recvmbox, buf) != ERR_OK){ aos_free(buf->payload); aos_free(buf); @@ -1393,7 +1389,7 @@ static int salnetconn_packet_input(sal_netconn_t *conn, void *data, size_t len, return 0; } -int sal_packet_input(int s, void *data, size_t len, ip_addr_t *addr, u16_t port) +int sal_packet_input(int s, void *data, size_t len, char remote_ip[16], uint16_t remote_port) { struct sal_sock *sock = NULL; int ret = 0; @@ -1413,12 +1409,12 @@ int sal_packet_input(int s, void *data, size_t len, ip_addr_t *addr, u16_t port) SAL_ERROR("socket %d invalid for haven't creat connnet yet\n"); return -1; } - - //LOCK_SAL_CORE; - ret = salnetconn_packet_input(sock->conn, data, len, addr, port); - //UNLOCK_SAL_CORE; + + ret = salnetconn_packet_input(sock->conn, data, len, remote_ip, remote_port); + if (ret){ SAL_ERROR("sal packet input fail\n"); + return -1; } sal_deal_event(s, NETCONN_EVT_RCVPLUS); @@ -2002,8 +1998,8 @@ int sal_fcntl(int s, int cmd, int val) int sal_shutdown(int s, int how) { - SAL_ERROR("%s call sal_close for now\n", __func__); - return sal_close(s); + SAL_ERROR("%s call stub for now\n", __func__); + return 0; } int sal_getaddrinfo(const char *nodename, const char *servname, @@ -2133,15 +2129,3 @@ void sal_freeaddrinfo(struct addrinfo *ai) } } -const void *ur_adapter_get_default_ipaddr(void) -{ - SAL_ERROR("Error: Calling %s stub !\n", __FUNCTION__); - return NULL; -} - -const void *ur_adapter_get_mcast_ipaddr(void) -{ - SAL_ERROR("Error: Calling %s stub !\n", __FUNCTION__); - return NULL; -} - diff --git a/device/sal/wifi/mk3060/atcmd_config_module.h b/device/sal/wifi/mk3060/atcmd_config_module.h new file mode 100755 index 0000000000..f21679c4bd --- /dev/null +++ b/device/sal/wifi/mk3060/atcmd_config_module.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#ifndef _ATCMD_CONFIG_MODULE +#define _ATCMD_CONFIG_MODULE + +#include + +/** + * AT related platform-dependent things are here, including: + * 1. AT command; + * 2. AT response code; + * 3. AT delimiter; + * 4. AT event; + * 5. Uart port used by AT; + * 6. ... + */ + +// AT command +#define AT_CMD_ENET_SEND "AT+ENETRAWSEND" +#define AT_CMD_ENTER_ENET_MODE "AT+ENETRAWMODE=ON" +#define AT_CMD_EHCO_OFF "AT+UARTE=OFF" +#define AT_CMD_TEST "AT" + +// Delimiter +#define AT_RECV_DELIMITER "\r\n" +#define AT_SEND_DELIMITER "\r" + +// AT event +#define AT_EVENT_ENET_DATA "+ENETEVENT:" + +// uart config +#define AT_UART_BAUDRATE 460800 +#define AT_UART_DATA_WIDTH DATA_WIDTH_8BIT +#define AT_UART_PARITY NO_PARITY +#define AT_UART_STOP_BITS STOP_BITS_1 +#define AT_UART_FLOW_CONTROL FLOW_CONTROL_DISABLED + +#endif diff --git a/device/sal/wifi/mk3060/mk3060.c b/device/sal/wifi/mk3060/mk3060.c index 25bb5ab6fd..5d193c131d 100644 --- a/device/sal/wifi/mk3060/mk3060.c +++ b/device/sal/wifi/mk3060/mk3060.c @@ -20,6 +20,9 @@ #define DATA_LEN_MAX 10 #define LINK_ID_MAX 5 +#define STOP_CMD "AT+CIPSTOP" +#define STOP_CMD_LEN (sizeof(STOP_CMD)+1+1+5+1) + /* Change to include data slink for each link id respectively. */ typedef struct link_s { int fd; @@ -209,7 +212,9 @@ static uint8_t inited = 0; static int sal_wifi_init(void) { int link; - + char cmd[STOP_CMD_LEN] = {0}; + char out[64] = {0}; + if (inited) { LOGW(TAG, "sal component is already initialized"); return 0; @@ -223,10 +228,21 @@ static int sal_wifi_init(void) memset(g_link, 0, sizeof(g_link)); for (link = 0; link < LINK_ID_MAX; link++) { g_link[link].fd = -1; + /*close all link */ + snprintf(cmd, STOP_CMD_LEN - 1, "%s=%d", STOP_CMD, link); + LOGD(TAG, "%s %d - AT cmd to run: %s", __func__, __LINE__, cmd); + + at.send_raw(cmd, out, sizeof(out)); + LOGD(TAG, "The AT response is: %s", out); + if (strstr(out, CMD_FAIL_RSP) != NULL) { + LOGE(TAG, "%s %d failed", __func__, __LINE__); + //return -1; + } } - + at.oob(NET_OOB_PREFIX, net_event_handler, NULL); - + inited = 1; + return 0; } @@ -446,9 +462,7 @@ static int sal_wifi_domain_to_ip(char *domain, return -1; } -/* close should clean the socket data buffer realted to the link id. */ -#define STOP_CMD "AT+CIPSTOP" -#define STOP_CMD_LEN (sizeof(STOP_CMD)+1+1+5+1) + static int sal_wifi_close(int fd, int32_t remote_port) { diff --git a/device/sal/wifi/mk3060/mk3060.mk b/device/sal/wifi/mk3060/mk3060.mk index b9bccae311..280b0886ae 100644 --- a/device/sal/wifi/mk3060/mk3060.mk +++ b/device/sal/wifi/mk3060/mk3060.mk @@ -1,7 +1,11 @@ NAME := device_sal_mk3060 +$(NAME)_SOURCES += wifi_atcmd.c +GLOBAL_DEFINES += DEV_SAL_MK3060 + +ifneq (1, $(at_adapter)) $(NAME)_COMPONENTS += sal atparser $(NAME)_SOURCES += mk3060.c - -GLOBAL_DEFINES += DEV_SAL_MK3060 +endif +GLOBAL_INCLUDES += ./ diff --git a/platform/mcu/linux/main/wifi_atcmd.c b/device/sal/wifi/mk3060/wifi_atcmd.c similarity index 86% rename from platform/mcu/linux/main/wifi_atcmd.c rename to device/sal/wifi/mk3060/wifi_atcmd.c index 571ead7b21..0d0ff4b490 100644 --- a/platform/mcu/linux/main/wifi_atcmd.c +++ b/device/sal/wifi/mk3060/wifi_atcmd.c @@ -19,7 +19,6 @@ static int get_ip_stat_helper(hal_wifi_ip_stat_t *result); static void fetch_ip_stat(void *arg) { - char out[128]; hal_wifi_ip_stat_t ip_stat = {0}; hal_wifi_module_t *m; @@ -53,12 +52,13 @@ static void at_wevent_handler(void *arg) } // !!!Do not call at_send_raw here since it will block at_worker - aos_task_new("fetch_ip_stat", fetch_ip_stat, arg, 1024); + //aos_task_new("fetch_ip_stat", fetch_ip_stat, arg, 1024); + aos_loop_schedule_work(0, fetch_ip_stat, arg, NULL, NULL); } static int wifi_init(hal_wifi_module_t *m) { - LOGD(TAG, "wifi init success!!\n"); + LOGI(TAG, "wifi init success!!\n"); return 0; }; @@ -96,7 +96,7 @@ static void wifi_get_mac_addr(hal_wifi_module_t *m, uint8_t *mac) get_mac_helper(mac_str); mac_str_to_hex(mac_str, mac); - LOGD(TAG, "mac in hex: %02x%02x%02x%02x%02x%02x", + LOGI(TAG, "mac in hex: %02x%02x%02x%02x%02x%02x", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); }; @@ -109,7 +109,6 @@ static int wifi_start(hal_wifi_module_t *m, hal_wifi_init_type_t *init_para) (void)init_para; - hal_wifi_ip_stat_t ip_stat; if (strcmp(init_para->wifi_key, "open") == 0) { snprintf(in, sizeof(in), AT_CMD_CONNECT_AP"=%s", @@ -119,14 +118,14 @@ static int wifi_start(hal_wifi_module_t *m, hal_wifi_init_type_t *init_para) init_para->wifi_ssid, init_para->wifi_key); } - LOGD(TAG, "Will connect via at cmd: %s\r\n", in); + LOGI(TAG, "Will connect via at cmd: %s\r\n", in); at.oob(AT_EVENT_GOT_IP, at_wevent_handler, (void *)m); if (at.send_raw(in, out, sizeof(out)) == 0) - LOGD(TAG, "AT command succeed, rsp: %s\r\n", out); + LOGI(TAG, "AT command %s succeed, rsp: %s\r\n", in, out); else - LOGE(TAG, "AT command failed\r\n"); + LOGE(TAG, "AT command %s failed\r\n", in); if (strstr(out, AT_RSP_FAIL)) { LOGE(TAG, "Connect wifi failed\r\n"); @@ -152,19 +151,19 @@ static int get_mac_helper(char *mac) if (!mac) return -1; if (at.send_raw(AT_CMD_OBTAIN_MAC, out, sizeof(out)) == 0) { - LOGD(TAG, "AT command succeed, rsp: %s", out); + LOGI(TAG, "AT command %s succeed, rsp: %s", AT_CMD_OBTAIN_MAC, out); } else { - LOGE(TAG, "AT command failed\r\n"); + LOGE(TAG, "AT command %s failed\r\n", AT_CMD_OBTAIN_MAC); return -1; } if (strstr(out, AT_RSP_FAIL)) { - LOGE(TAG, "Command executed with ERROR."); + LOGE(TAG, "Command %s executed with ERROR.", AT_CMD_OBTAIN_MAC); return -1; } sscanf(out, "%*[^:]:%[^\r]", mac); - LOGD(TAG, "mac result: %s\r\n", mac); + LOGI(TAG, "mac result: %s\r\n", mac); return 0; } @@ -178,14 +177,14 @@ static int get_ip_stat_helper(hal_wifi_ip_stat_t *result) if (!result) return -1; if (at.send_raw(AT_CMD_OBTAIN_IP, out, sizeof(out)) == 0) { - LOGD(TAG, "AT command succeed, rsp: %s", out); + LOGI(TAG, "AT command %s succeed, rsp: %s", AT_CMD_OBTAIN_IP, out); } else { - LOGE(TAG, "AT command failed\r\n"); + LOGE(TAG, "AT command %s failed\r\n", AT_CMD_OBTAIN_IP); return -1; } if (strstr(out, AT_RSP_FAIL)) { - LOGE(TAG, "Command executed with ERROR"); + LOGE(TAG, "Command %s executed with ERROR", AT_CMD_OBTAIN_IP); return -1; } @@ -202,8 +201,6 @@ static int get_ip_stat_helper(hal_wifi_ip_stat_t *result) static int get_ip_stat(hal_wifi_module_t *m, hal_wifi_ip_stat_t *out_net_para, hal_wifi_type_t wifi_type) { - char out[128] = {0}; - (void)wifi_type; (void)m; @@ -282,8 +279,8 @@ static int wlan_send_80211_raw_frame(hal_wifi_module_t *m, uint8_t *buf, int len return 0; } -hal_wifi_module_t sim_aos_wifi_linux = { - .base.name = "sim_aos_wifi_linux", +hal_wifi_module_t aos_wifi_module_mk3060 = { + .base.name = "aos_wifi_module_mk3060", .init = wifi_init, .get_mac_addr = wifi_get_mac_addr, .start = wifi_start, diff --git a/device/sensor/drv/drv_acc_bosch_bma253.c b/device/sensor/drv/drv_acc_bosch_bma253.c new file mode 100644 index 0000000000..a025539ac3 --- /dev/null +++ b/device/sensor/drv/drv_acc_bosch_bma253.c @@ -0,0 +1,539 @@ +/* +* Copyright (C) 2015-2017 Alibaba Group Holding Limited +* +* +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "hal/sensor.h" + + +#define BMA253_I2C_ADDR1 (0x18) +#define BMA253_I2C_ADDR2 (0x19) +#define BMA253_I2C_ADDR3 (0x10) +#define BMA253_I2C_ADDR4 (0x11) + + +#define BMA253_INIT_VALUE (0) +#define BMA253_GEN_READ_WRITE_LENGTH (1) +#define BMA253_INTERFACE_IDLE_TIME_DELAY (1) +#define BMA253_LSB_MSB_READ_LENGTH (2) +#define BMA253_SHIFT_TWO_BITS (2) +#define BMA253_SHIFT_FOUR_BITS (4) +#define BMA253_SHIFT_FIVE_BITS (5) +#define BMA253_SHIFT_SIX_BITS (6) +#define BMA253_SHIFT_EIGHT_BITS (8) +#define BMA253_12_BIT_SHIFT (0xF0) + +#define BMA253_FIFO_MODE_STATUS_RANGE (2) +#define BMA253_FIFO_DATA_SELECT_RANGE (4) +#define BMA253_FIFO_MODE_RANGE (4) +#define BMA253_FIFO_WML_RANGE (32) +#define BMA253_FIFO_XYZ_DATA_ENABLED (0x00) +#define BMA253_FIFO_X_DATA_ENABLED (0x01) +#define BMA253_FIFO_Y_DATA_ENABLED (0x02) +#define BMA253_FIFO_Z_DATA_ENABLED (0x03) +#define BMA253_FIFO_DATA_ENABLED_MASK (0x03) +#define BMA253_FIFO_XYZ_AXES_FRAME_SIZE (6) +#define BMA253_FIFO_SINGLE_AXIS_FRAME_SIZE (2) +#define BMA253_ACCEL_BW_MIN_RANGE (7) +#define BMA253_ACCEL_BW_1000HZ_RANGE (15) +#define BMA253_ACCEL_BW_MAX_RANGE (16) +#define BMA253_SLEEP_DURN_MIN_RANGE (4) +#define BMA253_SLEEP_TIMER_MODE_RANGE (2) +#define BMA253_SLEEP_DURN_MAX_RANGE (16) +#define BMA253_POWER_MODE_RANGE (6) +#define BMA253_SELF_TEST_AXIS_RANGE (4) +#define BMA253_SELF_TEST_SIGN_RANGE (2) + +#define BMA253_EEP_OFFSET (0x16) +#define BMA253_IMAGE_BASE (0x38) +#define BMA253_IMAGE_LEN (22) +#define BMA253_CHIP_ID_ADDR (0x00) +#define BMA253_CHIP_ID_VALUE (0xFA) +#define BMA253_X_AXIS_LSB_ADDR (0x02) +#define BMA253_X_AXIS_MSB_ADDR (0x03) +#define BMA253_Y_AXIS_LSB_ADDR (0x04) +#define BMA253_Y_AXIS_MSB_ADDR (0x05) +#define BMA253_Z_AXIS_LSB_ADDR (0x06) +#define BMA253_Z_AXIS_MSB_ADDR (0x07) +#define BMA253_TEMP_ADDR (0x08) +#define BMA253_STAT1_ADDR (0x09) +#define BMA253_STAT2_ADDR (0x0A) +#define BMA253_STAT_TAP_SLOPE_ADDR (0x0B) +#define BMA253_STAT_ORIENT_HIGH_ADDR (0x0C) +#define BMA253_STAT_FIFO_ADDR (0x0E) +#define BMA253_RANGE_SELECT_ADDR (0x0F) +#define BMA253_BW_SELECT_ADDR (0x10) +#define BMA253_MODE_CTRL_ADDR (0x11) +#define BMA253_LOW_NOISE_CTRL_ADDR (0x12) +#define BMA253_DATA_CTRL_ADDR (0x13) +#define BMA253_RST_ADDR (0x14) +#define BMA253_INTR_ENABLE1_ADDR (0x16) +#define BMA253_INTR_ENABLE2_ADDR (0x17) +#define BMA253_INTR_SLOW_NO_MOTION_ADDR (0x18) +#define BMA253_INTR1_PAD_SELECT_ADDR (0x19) +#define BMA253_INTR_DATA_SELECT_ADDR (0x1A) +#define BMA253_INTR2_PAD_SELECT_ADDR (0x1B) +#define BMA253_INTR_SOURCE_ADDR (0x1E) +#define BMA253_INTR_SET_ADDR (0x20) +#define BMA253_INTR_CTRL_ADDR (0x21) +#define BMA253_LOW_DURN_ADDR (0x22) +#define BMA253_LOW_THRES_ADDR (0x23) +#define BMA253_LOW_HIGH_HYST_ADDR (0x24) +#define BMA253_HIGH_DURN_ADDR (0x25) +#define BMA253_HIGH_THRES_ADDR (0x26) +#define BMA253_SLOPE_DURN_ADDR (0x27) +#define BMA253_SLOPE_THRES_ADDR (0x28) +#define BMA253_SLOW_NO_MOTION_THRES_ADDR (0x29) +#define BMA253_TAP_PARAM_ADDR (0x2A) +#define BMA253_TAP_THRES_ADDR (0x2B) +#define BMA253_ORIENT_PARAM_ADDR (0x2C) +#define BMA253_THETA_BLOCK_ADDR (0x2D) +#define BMA253_THETA_FLAT_ADDR (0x2E) +#define BMA253_FLAT_HOLD_TIME_ADDR (0x2F) +#define BMA253_SELFTEST_ADDR (0x32) +#define BMA253_EEPROM_CTRL_ADDR (0x33) +#define BMA253_SERIAL_CTRL_ADDR (0x34) +#define BMA253_OFFSET_CTRL_ADDR (0x36) +#define BMA253_OFFSET_PARAMS_ADDR (0x37) +#define BMA253_OFFSET_X_AXIS_ADDR (0x38) +#define BMA253_OFFSET_Y_AXIS_ADDR (0x39) +#define BMA253_OFFSET_Z_AXIS_ADDR (0x3A) +#define BMA253_GP0_ADDR (0x3B) +#define BMA253_GP1_ADDR (0x3C) +#define BMA253_FIFO_MODE_ADDR (0x3E) +#define BMA253_FIFO_DATA_OUTPUT_ADDR (0x3F) +#define BMA253_FIFO_WML_TRIG (0x30) + +#define BMA253_12_RESOLUTION (0) +#define BMA253_10_RESOLUTION (1) +#define BMA253_14_RESOLUTION (2) + +#define BMA253_ENABLE_SOFT_RESET_VALUE (0xB6) +#define BMA253_RANGE_SELECT_POS (0) +#define BMA253_RANGE_SELECT_LEN (4) +#define BMA253_RANGE_SELECT_MSK (0x0F) +#define BMA253_RANGE_SELECT_REG BMA253_RANGE_SELECT_ADDR + +#define BMA253_RANGE_2G (3) +#define BMA253_RANGE_4G (5) +#define BMA253_RANGE_8G (8) +#define BMA253_RANGE_16G (12) + +#define BMA253_BW_15_63 (15) +#define BMA253_BW_31_25 (31) +#define BMA253_BW_62_5 (62) +#define BMA253_BW_125 (125) +#define BMA253_BW_250 (250) +#define BMA253_BW_500 (500) +#define BMA253_BW_1000 (1000) + +#define BMA253_BW_7_81HZ (0x08) +#define BMA253_BW_15_63HZ (0x09) +#define BMA253_BW_31_25HZ (0x0A) +#define BMA253_BW_62_50HZ (0x0B) +#define BMA253_BW_125HZ (0x0C) +#define BMA253_BW_250HZ (0x0D) +#define BMA253_BW_500HZ (0x0E) +#define BMA253_BW_1000HZ (0x0F) +#define BMA253_BW_BIT_MASK (0x0F) + +#define BMA253_SLEEP_DURN_0_5MS (0x05) +#define BMA253_SLEEP_DURN_1MS (0x06) +#define BMA253_SLEEP_DURN_2MS (0x07) +#define BMA253_SLEEP_DURN_4MS (0x08) +#define BMA253_SLEEP_DURN_6MS (0x09) +#define BMA253_SLEEP_DURN_10MS (0x0A) +#define BMA253_SLEEP_DURN_25MS (0x0B) +#define BMA253_SLEEP_DURN_50MS (0x0C) +#define BMA253_SLEEP_DURN_100MS (0x0D) +#define BMA253_SLEEP_DURN_500MS (0x0E) +#define BMA253_SLEEP_DURN_1S (0x0F) +#define BMA253_SLEEP_DURN_POS (1) +#define BMA253_SLEEP_DURN_LEN (4) +#define BMA253_SLEEP_DURN_MSK (0x1E) +#define BMA253_SLEEP_DURN_REG BMA253_MODE_CTRL_ADDR +#define BME253_SLEEP_MODE (0x40) +#define BME253_DEEP_SUSPEND_MODE (0x20) +#define BME253_SUSPEND_MODE (0x80) +#define BME253_NORMAL_MODE (0x40) +#define BMA253_MODE_CTRL_POS (5) +#define BMA253_MODE_CTRL_LEN (3) +#define BMA253_MODE_CTRL_MSK (0xE0) +#define BMA253_MODE_CTRL_REG BMA253_MODE_CTRL_ADDR +#define BMA253_LOW_POWER_MODE_POS (6) +#define BMA253_LOW_POWER_MODE_LEN (1) +#define BMA253_LOW_POWER_MODE_MSK (0x40) +#define BMA253_LOW_POWER_MODE_REG BMA253_LOW_NOISE_CTRL_ADDR + +#define BMA253_DEFAULT_ODR_100HZ (100) + +//bma253 sensitivity factor table, the unit is LSB/g +static uint32_t bma253_factor[4] = { 128, 256, 512, 1024 }; +static uint32_t current_factor = 0; + +#define BMA253_GET_BITSLICE(regvar, bitname)\ +((regvar & bitname##_MSK) >> bitname##_POS) + +#define BMA253_SET_BITSLICE(regvar, bitname, val)\ +((regvar & ~bitname##_MSK) | ((val<= BMA253_BW_1000){ + value &= BMA253_BW_BIT_MASK; + value |= BMA253_BW_1000HZ; + } + else if(bw >= BMA253_BW_500){ + value &= BMA253_BW_BIT_MASK; + value |= BMA253_BW_500HZ; + } + else if(bw >= BMA253_BW_250){ + value &= BMA253_BW_BIT_MASK; + value |= BMA253_BW_250HZ; + } + else if(bw >= BMA253_BW_125){ + value &= BMA253_BW_BIT_MASK; + value |= BMA253_BW_125HZ; + } + else if(bw >= BMA253_BW_62_5){ + value &= BMA253_BW_BIT_MASK; + value |= BMA253_BW_62_50HZ; + } + else if(bw >= BMA253_BW_31_25){ + value &= BMA253_BW_BIT_MASK; + value |= BMA253_BW_31_25HZ; + } + else{ + value &= BMA253_BW_BIT_MASK; + value |= BMA253_BW_15_63HZ; + } + + ret = sensor_i2c_write(drv, BMA253_BW_SELECT_ADDR, &value, I2C_DATA_LEN, I2C_OP_RETRIES); + if(unlikely(ret)){ + return ret; + } + return 0; +} + +static int drv_acc_bosch_bma253_set_range(i2c_dev_t* drv, uint32_t range) +{ + int ret = 0; + uint8_t value = 0x00; + + ret = sensor_i2c_read(drv, BMA253_RANGE_SELECT_REG, &value, I2C_DATA_LEN, I2C_OP_RETRIES); + if(unlikely(ret)){ + return ret; + } + + switch (range){ + case ACC_RANGE_2G:{ + value = BMA253_SET_BITSLICE(value,BMA253_RANGE_SELECT,BMA253_RANGE_2G); + }break; + + case ACC_RANGE_4G:{ + value = BMA253_SET_BITSLICE(value,BMA253_RANGE_SELECT,BMA253_RANGE_4G); + }break; + + case ACC_RANGE_8G:{ + value = BMA253_SET_BITSLICE(value,BMA253_RANGE_SELECT,BMA253_RANGE_8G); + }break; + + case ACC_RANGE_16G:{ + value = BMA253_SET_BITSLICE(value,BMA253_RANGE_SELECT,BMA253_RANGE_16G); + }break; + + default:break; + } + + /* Write the range register 0x0F*/ + ret = sensor_i2c_write(drv, BMA253_RANGE_SELECT_REG, &value, I2C_DATA_LEN, I2C_OP_RETRIES); + if(unlikely(ret)){ + return ret; + } + + if((range >= ACC_RANGE_2G)&&(range <= ACC_RANGE_16G)){ + current_factor = bma253_factor[range]; + } + + return 0; +} + + +static void drv_acc_bosch_bma253_irq_handle(void) +{ + /* no handle so far */ +} + +static int drv_acc_bosch_bma253_open(void) +{ + int ret = 0; + ret = drv_acc_bosch_bma253_set_power_mode(&bma253_ctx, DEV_POWER_ON); + if(unlikely(ret)){ + return -1; + } + return 0; + +} + +static int drv_acc_bosch_bma253_close(void) +{ + int ret = 0; + ret = drv_acc_bosch_bma253_set_power_mode(&bma253_ctx, DEV_POWER_OFF); + if(unlikely(ret)){ + return -1; + } + return 0; +} + +static int drv_acc_bosch_bma253_read(void *buf, size_t len) +{ + int ret = 0; + uint8_t reg[6]; + accel_data_t *accel = buf; + if(buf == NULL){ + return -1; + } + + ret = sensor_i2c_read(&bma253_ctx, BMA253_X_AXIS_LSB_ADDR, ®[0], I2C_REG_LEN, I2C_OP_RETRIES); + ret |= sensor_i2c_read(&bma253_ctx, BMA253_X_AXIS_MSB_ADDR, ®[1], I2C_REG_LEN, I2C_OP_RETRIES); + ret |= sensor_i2c_read(&bma253_ctx, BMA253_Y_AXIS_LSB_ADDR, ®[2], I2C_REG_LEN, I2C_OP_RETRIES); + ret |= sensor_i2c_read(&bma253_ctx, BMA253_Y_AXIS_MSB_ADDR, ®[3], I2C_REG_LEN, I2C_OP_RETRIES); + ret |= sensor_i2c_read(&bma253_ctx, BMA253_Z_AXIS_LSB_ADDR, ®[4], I2C_REG_LEN, I2C_OP_RETRIES); + ret |= sensor_i2c_read(&bma253_ctx, BMA253_Z_AXIS_MSB_ADDR, ®[5], I2C_REG_LEN, I2C_OP_RETRIES); + if(unlikely(ret)){ + return ret; + } + + accel->data[DATA_AXIS_X] = (int16_t)((((int32_t)((int8_t)reg[1]))<< BMA253_SHIFT_EIGHT_BITS)|(reg[0] &BMA253_12_BIT_SHIFT)); + accel->data[DATA_AXIS_X] = accel->data[DATA_AXIS_X] >> BMA253_SHIFT_FOUR_BITS; + + accel->data[DATA_AXIS_Y] = (int16_t)((((int32_t)((int8_t)reg[3]))<< BMA253_SHIFT_EIGHT_BITS)|(reg[2] &BMA253_12_BIT_SHIFT)); + accel->data[DATA_AXIS_Y] = accel->data[DATA_AXIS_Y] >> BMA253_SHIFT_FOUR_BITS; + + accel->data[DATA_AXIS_Z] = (int16_t)((((int32_t)((int8_t)reg[5]))<< BMA253_SHIFT_EIGHT_BITS)|(reg[4]&BMA253_12_BIT_SHIFT)); + accel->data[DATA_AXIS_Z] = accel->data[DATA_AXIS_Z] >> BMA253_SHIFT_FOUR_BITS; + + if(current_factor != 0){ + // the unit of acc is mg, 1000 mg = 1 g. + accel->data[DATA_AXIS_X] = accel->data[DATA_AXIS_X] * ACCELEROMETER_UNIT_FACTOR / current_factor; + accel->data[DATA_AXIS_Y] = accel->data[DATA_AXIS_Y] * ACCELEROMETER_UNIT_FACTOR / current_factor; + accel->data[DATA_AXIS_Z] = accel->data[DATA_AXIS_Z] * ACCELEROMETER_UNIT_FACTOR / current_factor; + } + accel->timestamp = aos_now_ms(); + len = sizeof(accel_data_t); + return 0; +} + +static int drv_acc_bosch_bma253_ioctl(int cmd, unsigned long arg) +{ + int ret = 0; + + switch(cmd){ + case SENSOR_IOCTL_ODR_SET:{ + ret = drv_acc_bosch_bma253_set_odr(&bma253_ctx, arg); + if(unlikely(ret)){ + return -1; + } + }break; + case SENSOR_IOCTL_RANGE_SET:{ + ret = drv_acc_bosch_bma253_set_range(&bma253_ctx, arg); + if(unlikely(ret)){ + return -1; + } + }break; + case SENSOR_IOCTL_SET_POWER:{ + ret = drv_acc_bosch_bma253_set_power_mode(&bma253_ctx, arg); + if(unlikely(ret)){ + return -1; + } + }break; + case SENSOR_IOCTL_GET_INFO:{ + /* fill the dev info here */ + dev_sensor_info_t *info =arg; + *(info->model) = "BMA253"; + info->range_max = 16; + info->range_min = 2; + info->unit = mg; + }break; + + default:break; + } + + return 0; +} + +int drv_acc_bosch_bma253_init(void){ + int ret = 0; + sensor_obj_t sensor; + + /* fill the sensor obj parameters here */ + sensor.io_port = I2C_PORT; + sensor.tag = TAG_DEV_ACC; + sensor.path = dev_acc_path; + sensor.open = drv_acc_bosch_bma253_open; + sensor.close = drv_acc_bosch_bma253_close; + sensor.read = drv_acc_bosch_bma253_read; + sensor.write = NULL; + sensor.ioctl = drv_acc_bosch_bma253_ioctl; + sensor.irq_handle = drv_acc_bosch_bma253_irq_handle; + sensor.bus = &bma253_ctx; + + ret = sensor_create_obj(&sensor); + if(unlikely(ret)){ + return -1; + } + + ret = drv_acc_bosch_bma253_validate_id(&bma253_ctx, BMA253_CHIP_ID_ADDR, BMA253_CHIP_ID_VALUE); + if(unlikely(ret)){ + return -1; + } + + ret = drv_acc_bosch_bma253_soft_reset(&bma253_ctx); + if(unlikely(ret)){ + return -1; + } + + ret = drv_acc_bosch_bma253_set_range(&bma253_ctx, ACC_RANGE_8G); + if(unlikely(ret)){ + return -1; + } + + //set odr is 100hz, and will update + ret = drv_acc_bosch_bma253_set_odr(&bma253_ctx, BMA253_DEFAULT_ODR_100HZ); + if(unlikely(ret)){ + return -1; + } + + ret = drv_acc_bosch_bma253_set_power_mode(&bma253_ctx, DEV_POWER_OFF); + if(unlikely(ret)){ + return -1; + } + + /* update the phy sensor info to sensor hal */ + LOG("%s %s successfully \n", SENSOR_STR, __func__); + return 0; +} + diff --git a/device/sensor/drv/drv_baro_bosch_bmp280.c b/device/sensor/drv/drv_baro_bosch_bmp280.c new file mode 100644 index 0000000000..12a76db7ea --- /dev/null +++ b/device/sensor/drv/drv_baro_bosch_bmp280.c @@ -0,0 +1,844 @@ +/* +* Copyright (C) 2015-2017 Alibaba Group Holding Limited +* +* +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "hal/sensor.h" + + +#define BMP280_TEMPERATURE_CALIB_DIG_T1_LSB_REG (0x88) +#define BMP280_TEMPERATURE_CALIB_DIG_T1_MSB_REG (0x89) +#define BMP280_TEMPERATURE_CALIB_DIG_T2_LSB_REG (0x8A) +#define BMP280_TEMPERATURE_CALIB_DIG_T2_MSB_REG (0x8B) +#define BMP280_TEMPERATURE_CALIB_DIG_T3_LSB_REG (0x8C) +#define BMP280_TEMPERATURE_CALIB_DIG_T3_MSB_REG (0x8D) +#define BMP280_PRESSURE_CALIB_DIG_P1_LSB_REG (0x8E) +#define BMP280_PRESSURE_CALIB_DIG_P1_MSB_REG (0x8F) +#define BMP280_PRESSURE_CALIB_DIG_P2_LSB_REG (0x90) +#define BMP280_PRESSURE_CALIB_DIG_P2_MSB_REG (0x91) +#define BMP280_PRESSURE_CALIB_DIG_P3_LSB_REG (0x92) +#define BMP280_PRESSURE_CALIB_DIG_P3_MSB_REG (0x93) +#define BMP280_PRESSURE_CALIB_DIG_P4_LSB_REG (0x94) +#define BMP280_PRESSURE_CALIB_DIG_P4_MSB_REG (0x95) +#define BMP280_PRESSURE_CALIB_DIG_P5_LSB_REG (0x96) +#define BMP280_PRESSURE_CALIB_DIG_P5_MSB_REG (0x97) +#define BMP280_PRESSURE_CALIB_DIG_P6_LSB_REG (0x98) +#define BMP280_PRESSURE_CALIB_DIG_P6_MSB_REG (0x99) +#define BMP280_PRESSURE_CALIB_DIG_P7_LSB_REG (0x9A) +#define BMP280_PRESSURE_CALIB_DIG_P7_MSB_REG (0x9B) +#define BMP280_PRESSURE_CALIB_DIG_P8_LSB_REG (0x9C) +#define BMP280_PRESSURE_CALIB_DIG_P8_MSB_REG (0x9D) +#define BMP280_PRESSURE_CALIB_DIG_P9_LSB_REG (0x9E) +#define BMP280_PRESSURE_CALIB_DIG_P9_MSB_REG (0x9F) + + +#define BMP280_CHIP_ID_REG (0xD0) +#define BMP280_RST_REG (0xE0) +#define BMP280_STAT_REG (0xF3) +#define BMP280_CTRL_MEAS_REG (0xF4) +#define BMP280_CONFIG_REG (0xF5) +#define BMP280_PRESSURE_MSB_REG (0xF7) +#define BMP280_PRESSURE_LSB_REG (0xF8) +#define BMP280_PRESSURE_XLSB_REG (0xF9) +#define BMP280_TEMPERATURE_MSB_REG (0xFA) +#define BMP280_TEMPERATURE_LSB_REG (0xFB) +#define BMP280_TEMPERATURE_XLSB_REG (0xFC) + + +#define BMP280_SHIFT_BY_01_BIT (1) +#define BMP280_SHIFT_BY_02_BITS (2) +#define BMP280_SHIFT_BY_03_BITS (3) +#define BMP280_SHIFT_BY_04_BITS (4) +#define BMP280_SHIFT_BY_05_BITS (5) +#define BMP280_SHIFT_BY_08_BITS (8) +#define BMP280_SHIFT_BY_11_BITS (11) +#define BMP280_SHIFT_BY_12_BITS (12) +#define BMP280_SHIFT_BY_13_BITS (13) +#define BMP280_SHIFT_BY_14_BITS (14) +#define BMP280_SHIFT_BY_15_BITS (15) +#define BMP280_SHIFT_BY_16_BITS (16) +#define BMP280_SHIFT_BY_17_BITS (17) +#define BMP280_SHIFT_BY_18_BITS (18) +#define BMP280_SHIFT_BY_19_BITS (19) +#define BMP280_SHIFT_BY_25_BITS (25) +#define BMP280_SHIFT_BY_31_BITS (31) +#define BMP280_SHIFT_BY_33_BITS (33) +#define BMP280_SHIFT_BY_35_BITS (35) +#define BMP280_SHIFT_BY_47_BITS (47) + + +#define BMP280_PRESSURE_TEMPERATURE_CALIB_DATA_LENGTH (24) +#define BMP280_GEN_READ_WRITE_DATA_LENGTH (1) +#define BMP280_REGISTER_READ_DELAY (1) +#define BMP280_TEMPERATURE_DATA_LENGTH (3) +#define BMP280_PRESSURE_DATA_LENGTH (3) +#define BMP280_ALL_DATA_FRAME_LENGTH (6) +#define BMP280_INIT_VALUE (0) +#define BMP280_CHIP_ID_READ_COUNT (5) +#define BMP280_CHIP_ID_READ_SUCCESS (0) +#define BMP280_CHIP_ID_READ_FAIL ((int8_t)-1) +#define BMP280_INVALID_DATA (0) + + + + +#define BMP280_TEMPERATURE_DATA_SIZE (3) +#define BMP280_PRESSURE_DATA_SIZE (3) +#define BMP280_DATA_FRAME_SIZE (6) +#define BMP280_CALIB_DATA_SIZE (24) + +#define BMP280_TEMPERATURE_MSB_DATA (0) +#define BMP280_TEMPERATURE_LSB_DATA (1) +#define BMP280_TEMPERATURE_XLSB_DATA (2) + + + +#define BMP280_I2C_ADDRESS1 (0x76) +#define BMP280_I2C_ADDRESS2 (0x77) + + +#define BMP280_SLEEP_MODE (0x00) +#define BMP280_FORCED_MODE (0x01) +#define BMP280_NORMAL_MODE (0x03) +#define BMP280_SOFT_RESET_CODE (0xB6) + + + +#define BMP280_STANDBY_TIME_1_MS (0x00) +#define BMP280_STANDBY_TIME_63_MS (0x01) +#define BMP280_STANDBY_TIME_125_MS (0x02) +#define BMP280_STANDBY_TIME_250_MS (0x03) +#define BMP280_STANDBY_TIME_500_MS (0x04) +#define BMP280_STANDBY_TIME_1000_MS (0x05) +#define BMP280_STANDBY_TIME_2000_MS (0x06) +#define BMP280_STANDBY_TIME_4000_MS (0x07) + + +#define BMP280_OVERSAMP_SKIPPED (0x00) +#define BMP280_OVERSAMP_1X (0x01) +#define BMP280_OVERSAMP_2X (0x02) +#define BMP280_OVERSAMP_4X (0x03) +#define BMP280_OVERSAMP_8X (0x04) +#define BMP280_OVERSAMP_16X (0x05) + +#define BMP280_FILTER_COEFF_OFF (0x00) +#define BMP280_FILTER_COEFF_2 (0x01) +#define BMP280_FILTER_COEFF_4 (0x02) +#define BMP280_FILTER_COEFF_8 (0x03) +#define BMP280_FILTER_COEFF_16 (0x04) + + +#define BMP280_ULTRA_LOW_POWER_MODE (0x00) +#define BMP280_LOW_POWER_MODE (0x01) +#define BMP280_STANDARD_RESOLUTION_MODE (0x02) +#define BMP280_HIGH_RESOLUTION_MODE (0x03) +#define BMP280_ULTRA_HIGH_RESOLUTION_MODE (0x04) + +#define BMP280_ULTRALOWPOWER_OVERSAMP_PRESSURE BMP280_OVERSAMP_1X +#define BMP280_ULTRALOWPOWER_OVERSAMP_TEMPERATURE BMP280_OVERSAMP_1X + +#define BMP280_LOWPOWER_OVERSAMP_PRESSURE BMP280_OVERSAMP_2X +#define BMP280_LOWPOWER_OVERSAMP_TEMPERATURE BMP280_OVERSAMP_1X + +#define BMP280_STANDARDRESOLUTION_OVERSAMP_PRESSURE BMP280_OVERSAMP_4X +#define BMP280_STANDARDRESOLUTION_OVERSAMP_TEMPERATURE BMP280_OVERSAMP_1X + +#define BMP280_HIGHRESOLUTION_OVERSAMP_PRESSURE BMP280_OVERSAMP_8X +#define BMP280_HIGHRESOLUTION_OVERSAMP_TEMPERATURE BMP280_OVERSAMP_1X + +#define BMP280_ULTRAHIGHRESOLUTION_OVERSAMP_PRESSURE BMP280_OVERSAMP_16X +#define BMP280_ULTRAHIGHRESOLUTION_OVERSAMP_TEMPERATURE BMP280_OVERSAMP_2X + + +#define BMP280_STATUS_REG_MEASURING__POS (3) +#define BMP280_STATUS_REG_MEASURING__MSK (0x08) +#define BMP280_STATUS_REG_MEASURING__LEN (1) +#define BMP280_STATUS_REG_MEASURING__REG (BMP280_STAT_REG) + +#define BMP280_STATUS_REG_IM_UPDATE__POS (0) +#define BMP280_STATUS_REG_IM_UPDATE__MSK (0x01) +#define BMP280_STATUS_REG_IM_UPDATE__LEN (1) +#define BMP280_STATUS_REG_IM_UPDATE__REG (BMP280_STAT_REG) + + +#define BMP280_CTRL_MEAS_REG_OVERSAMP_TEMPERATURE__POS (5) +#define BMP280_CTRL_MEAS_REG_OVERSAMP_TEMPERATURE__MSK (0xE0) +#define BMP280_CTRL_MEAS_REG_OVERSAMP_TEMPERATURE__LEN (3) +#define BMP280_CTRL_MEAS_REG_OVERSAMP_TEMPERATURE__REG (BMP280_CTRL_MEAS_REG) + + +#define BMP280_CTRL_MEAS_REG_OVERSAMP_PRESSURE__POS (2) +#define BMP280_CTRL_MEAS_REG_OVERSAMP_PRESSURE__MSK (0x1C) +#define BMP280_CTRL_MEAS_REG_OVERSAMP_PRESSURE__LEN (3) +#define BMP280_CTRL_MEAS_REG_OVERSAMP_PRESSURE__REG (BMP280_CTRL_MEAS_REG) + +#define BMP280_CTRL_MEAS_REG_POWER_MODE__POS (0) +#define BMP280_CTRL_MEAS_REG_POWER_MODE__MSK (0x03) +#define BMP280_CTRL_MEAS_REG_POWER_MODE__LEN (2) +#define BMP280_CTRL_MEAS_REG_POWER_MODE__REG (BMP280_CTRL_MEAS_REG) + + +#define BMP280_CONFIG_REG_STANDBY_DURN__POS (5) +#define BMP280_CONFIG_REG_STANDBY_DURN__MSK (0xE0) +#define BMP280_CONFIG_REG_STANDBY_DURN__LEN (3) +#define BMP280_CONFIG_REG_STANDBY_DURN__REG (BMP280_CONFIG_REG) + +#define BMP280_CONFIG_REG_FILTER__POS (2) +#define BMP280_CONFIG_REG_FILTER__MSK (0x1C) +#define BMP280_CONFIG_REG_FILTER__LEN (3) +#define BMP280_CONFIG_REG_FILTER__REG (BMP280_CONFIG_REG) + + +#define BMP280_CONFIG_REG_SPI3_ENABLE__POS (0) +#define BMP280_CONFIG_REG_SPI3_ENABLE__MSK (0x01) +#define BMP280_CONFIG_REG_SPI3_ENABLE__LEN (1) +#define BMP280_CONFIG_REG_SPI3_ENABLE__REG (BMP280_CONFIG_REG) + + +#define BMP280_PRESSURE_XLSB_REG_DATA__POS (4) +#define BMP280_PRESSURE_XLSB_REG_DATA__MSK (0xF0) +#define BMP280_PRESSURE_XLSB_REG_DATA__LEN (4) +#define BMP280_PRESSURE_XLSB_REG_DATA__REG (BMP280_PRESSURE_XLSB_REG) + +#define BMP280_TEMPERATURE_XLSB_REG_DATA__POS (4) +#define BMP280_TEMPERATURE_XLSB_REG_DATA__MSK (0xF0) +#define BMP280_TEMPERATURE_XLSB_REG_DATA__LEN (4) +#define BMP280_TEMPERATURE_XLSB_REG_DATA__REG (BMP280_TEMPERATURE_XLSB_REG) + +#define BMP280_TEMPERATURE_MSB_DATA (0) +#define BMP280_TEMPERATURE_LSB_DATA (1) +#define BMP280_TEMPERATURE_XLSB_DATA (2) + +#define BMP280_PRESSURE_MSB_DATA (0) +#define BMP280_PRESSURE_LSB_DATA (1) +#define BMP280_PRESSURE_XLSB_DATA (2) + +#define BMP280_DATA_FRAME_PRESSURE_MSB_BYTE (0) +#define BMP280_DATA_FRAME_PRESSURE_LSB_BYTE (1) +#define BMP280_DATA_FRAME_PRESSURE_XLSB_BYTE (2) +#define BMP280_DATA_FRAME_TEMPERATURE_MSB_BYTE (3) +#define BMP280_DATA_FRAME_TEMPERATURE_LSB_BYTE (4) +#define BMP280_DATA_FRAME_TEMPERATURE_XLSB_BYTE (5) + +#define BMP280_TEMPERATURE_CALIB_DIG_T1_LSB (0) +#define BMP280_TEMPERATURE_CALIB_DIG_T1_MSB (1) +#define BMP280_TEMPERATURE_CALIB_DIG_T2_LSB (2) +#define BMP280_TEMPERATURE_CALIB_DIG_T2_MSB (3) +#define BMP280_TEMPERATURE_CALIB_DIG_T3_LSB (4) +#define BMP280_TEMPERATURE_CALIB_DIG_T3_MSB (5) +#define BMP280_PRESSURE_CALIB_DIG_P1_LSB (6) +#define BMP280_PRESSURE_CALIB_DIG_P1_MSB (7) +#define BMP280_PRESSURE_CALIB_DIG_P2_LSB (8) +#define BMP280_PRESSURE_CALIB_DIG_P2_MSB (9) +#define BMP280_PRESSURE_CALIB_DIG_P3_LSB (10) +#define BMP280_PRESSURE_CALIB_DIG_P3_MSB (11) +#define BMP280_PRESSURE_CALIB_DIG_P4_LSB (12) +#define BMP280_PRESSURE_CALIB_DIG_P4_MSB (13) +#define BMP280_PRESSURE_CALIB_DIG_P5_LSB (14) +#define BMP280_PRESSURE_CALIB_DIG_P5_MSB (15) +#define BMP280_PRESSURE_CALIB_DIG_P6_LSB (16) +#define BMP280_PRESSURE_CALIB_DIG_P6_MSB (17) +#define BMP280_PRESSURE_CALIB_DIG_P7_LSB (18) +#define BMP280_PRESSURE_CALIB_DIG_P7_MSB (19) +#define BMP280_PRESSURE_CALIB_DIG_P8_LSB (20) +#define BMP280_PRESSURE_CALIB_DIG_P8_MSB (21) +#define BMP280_PRESSURE_CALIB_DIG_P9_LSB (22) +#define BMP280_PRESSURE_CALIB_DIG_P9_MSB (23) + +#define BMP280_SOFT_RESRT_VALUE (0XB6) + +#define BMP280_I2C_SLAVE_ADDR_LOW (0X76) +#define BMP280_I2C_SLAVE_ADDR_HIGN (0X77) + +#define BMP280_DEFAULT_ODR_1HZ (1) + +#define BMP280_BIT(x) ((uint8_t)(x)) +#define BMP280_CHIP_ID_VAL BMP280_BIT(0X58) +#define BMP280_I2C_ADDR_TRANS(n) ((n)<<1) +#define BMP280_I2C_ADDR BMP280_I2C_ADDR_TRANS(BMP280_I2C_SLAVE_ADDR_LOW) + + +#define BMP280_GET_BITSLICE(regvar, bitname) ((regvar & bitname##__MSK) >> bitname##__POS) +#define BMP280_SET_BITSLICE(regvar, bitname, val) ((regvar & ~bitname##__MSK) | ((val< 80) + return BMP280_STANDBY_TIME_1_MS; + else if(hz > 13) + return BMP280_STANDBY_TIME_63_MS; + else if(hz > 7) + return BMP280_STANDBY_TIME_125_MS; + else if(hz > 3) + return BMP280_STANDBY_TIME_250_MS; + else + return BMP280_STANDBY_TIME_500_MS; +} + + +static int drv_baro_bosch_bmp280_set_odr(i2c_dev_t* drv, uint8_t odr) +{ + int ret = 0; + uint8_t v_data_u8 = 0; + + ret = sensor_i2c_read(drv,BMP280_CONFIG_REG_STANDBY_DURN__REG, + &v_data_u8,I2C_DATA_LEN,I2C_OP_RETRIES); + if(unlikely(ret)){ + return ret; + } + + v_data_u8 = BMP280_SET_BITSLICE(v_data_u8,BMP280_CONFIG_REG_STANDBY_DURN,odr); + ret = sensor_i2c_write(drv,BMP280_CONFIG_REG_STANDBY_DURN__REG, + &v_data_u8,I2C_DATA_LEN,I2C_OP_RETRIES); + if(unlikely(ret)){ + return ret; + } + + return ret; +} + + +static int drv_baro_bosch_bmp280_soft_reset(i2c_dev_t* drv) +{ + int ret = 0; + uint8_t v_data_u8 = BMP280_SOFT_RESRT_VALUE; + + ret = sensor_i2c_write(drv,BMP280_RST_REG, + &v_data_u8,I2C_DATA_LEN,I2C_OP_RETRIES); + if(unlikely(ret)){ + return ret; + } + + return ret; +} + +static int drv_baro_bosch_bmp280_set_default_config(i2c_dev_t* drv) +{ + int ret = 0; + + ret = drv_baro_bosch_bmp280_set_power_mode(drv, DEV_SLEEP); + if(unlikely(ret)){ + return ret; + } + + ret = drv_baro_bosch_bmp280_set_odr(drv, BMP280_DEFAULT_ODR_1HZ); + if(unlikely(ret)){ + return ret; + } + + return 0; +} + + +static int drv_baro_bosch_bmp280_read_uncomp_baro(i2c_dev_t* drv, barometer_data_t* pdata) +{ + int ret = 0; + uint8_t data[BMP280_PRESSURE_DATA_SIZE] = {0}; + + ret = sensor_i2c_read(drv, BMP280_PRESSURE_MSB_REG, data, BMP280_PRESSURE_DATA_SIZE, I2C_OP_RETRIES); + if(unlikely(ret)){ + return ret; + } + + pdata->p = (int)((((uint32_t)(data[BMP280_PRESSURE_MSB_DATA]))<< BMP280_SHIFT_BY_12_BITS) + | (((uint32_t)(data[BMP280_PRESSURE_LSB_DATA]))<< BMP280_SHIFT_BY_04_BITS) + | ((uint32_t)data[BMP280_PRESSURE_XLSB_DATA]>> BMP280_SHIFT_BY_04_BITS)); + return ret; +} + + +static int drv_baro_bosch_bmp280_compensate_baro( barometer_data_t* pdata) +{ + int v_x1_u32r = 0; + int v_x2_u32r = 0; + uint32_t comp_baro = 0; + + v_x1_u32r = (((int)g_bmp280_calib_table.t_fine) + >>BMP280_SHIFT_BY_01_BIT) - (int)64000; + + v_x2_u32r = (((v_x1_u32r >> BMP280_SHIFT_BY_02_BITS) + * (v_x1_u32r >> BMP280_SHIFT_BY_02_BITS)) + >> BMP280_SHIFT_BY_11_BITS) + * ((int)g_bmp280_calib_table.dig_P6); + v_x2_u32r = v_x2_u32r + ((v_x1_u32r * + ((int)g_bmp280_calib_table.dig_P5)) + << BMP280_SHIFT_BY_01_BIT); + v_x2_u32r = (v_x2_u32r >> BMP280_SHIFT_BY_02_BITS) + + (((int)g_bmp280_calib_table.dig_P4) + << BMP280_SHIFT_BY_16_BITS); + + v_x1_u32r = (((g_bmp280_calib_table.dig_P3 + * (((v_x1_u32r + >> BMP280_SHIFT_BY_02_BITS) * (v_x1_u32r + >> BMP280_SHIFT_BY_02_BITS)) + >> BMP280_SHIFT_BY_13_BITS)) + >> BMP280_SHIFT_BY_03_BITS) + + ((((int)g_bmp280_calib_table.dig_P2) + * v_x1_u32r) + >> BMP280_SHIFT_BY_01_BIT)) + >> BMP280_SHIFT_BY_18_BITS; + v_x1_u32r = ((((32768 + v_x1_u32r)) + * ((int)g_bmp280_calib_table.dig_P1)) + >> BMP280_SHIFT_BY_15_BITS); + + comp_baro = (((uint32_t)(((int)1048576) - pdata->p) + - (v_x2_u32r >> BMP280_SHIFT_BY_12_BITS))) + * 3125; + + if (comp_baro < 0x80000000){ + if (v_x1_u32r != 0){ + comp_baro = (comp_baro + << BMP280_SHIFT_BY_01_BIT) + / ((uint32_t)v_x1_u32r); + } + else{ + return -1; + } + } + else if (v_x1_u32r != 0){ + comp_baro = (comp_baro / (uint32_t)v_x1_u32r) * 2; + } + else{ + return -1; + } + v_x1_u32r = (((int)g_bmp280_calib_table.dig_P9) * ((int)( + ((comp_baro >> BMP280_SHIFT_BY_03_BITS) + * (comp_baro >> BMP280_SHIFT_BY_03_BITS)) + >> BMP280_SHIFT_BY_13_BITS))) + >> BMP280_SHIFT_BY_12_BITS; + + v_x2_u32r = (((int)(comp_baro >> + BMP280_SHIFT_BY_02_BITS)) + * ((int)g_bmp280_calib_table.dig_P8)) + >> BMP280_SHIFT_BY_13_BITS; + + comp_baro = (uint32_t)((int)comp_baro + ((v_x1_u32r + v_x2_u32r + + g_bmp280_calib_table.dig_P7) + >> BMP280_SHIFT_BY_04_BITS)); + + pdata->p = comp_baro; + return 0; +} + + + +static int drv_baro_bosch_bmp280_read_baro(i2c_dev_t* drv, barometer_data_t* pdata) +{ + int ret = 0; + + ret = drv_baro_bosch_bmp280_read_uncomp_baro(drv, pdata); + if(unlikely(ret)){ + return ret; + } + ret = drv_baro_bosch_bmp280_compensate_baro(pdata); + if(unlikely(ret)){ + return ret; + } + + return 0; +} + +static int drv_baro_bosch_bmp280_comp_temp(temperature_data_t* pdata) +{ + int v_x1_u32r = 0; + int v_x2_u32r = 0; + v_x1_u32r = ((((pdata->t >> BMP280_SHIFT_BY_03_BITS) + - ((int)g_bmp280_calib_table.dig_T1 + << BMP280_SHIFT_BY_01_BIT))) + * ((int)g_bmp280_calib_table.dig_T2)) + >> BMP280_SHIFT_BY_11_BITS; + + v_x2_u32r = (((((pdata->t >> BMP280_SHIFT_BY_04_BITS) + - ((int)g_bmp280_calib_table.dig_T1)) + * ((pdata->t >> BMP280_SHIFT_BY_04_BITS) + - ((int)g_bmp280_calib_table.dig_T1))) + >> BMP280_SHIFT_BY_12_BITS) + * ((int)g_bmp280_calib_table.dig_T3)) + >> BMP280_SHIFT_BY_14_BITS; + + g_bmp280_calib_table.t_fine = v_x1_u32r + v_x2_u32r; + + pdata->t = (g_bmp280_calib_table.t_fine * 5 + 128) >> BMP280_SHIFT_BY_08_BITS; + return 0; +} + + + +static int drv_baro_bosch_bmp280_cali_temp(i2c_dev_t* drv) +{ + int ret = 0; + uint8_t data[BMP280_TEMPERATURE_DATA_SIZE] = {0}; + temperature_data_t temp; + + ret = sensor_i2c_read(drv, BMP280_TEMPERATURE_MSB_REG, data, BMP280_TEMPERATURE_DATA_SIZE, I2C_OP_RETRIES); + if(unlikely(ret)){ + return ret; + } + + temp.t = (int)((((uint32_t)(data[BMP280_TEMPERATURE_MSB_DATA]))<< BMP280_SHIFT_BY_12_BITS) + | (((uint32_t)(data[BMP280_TEMPERATURE_LSB_DATA]))<< BMP280_SHIFT_BY_04_BITS) + | ((uint32_t)data[BMP280_TEMPERATURE_XLSB_DATA]>> BMP280_SHIFT_BY_04_BITS)); + + + ret = drv_baro_bosch_bmp280_comp_temp(&temp); + if(unlikely(ret)){ + return ret; + } + + return 0; +} + + + +static void drv_baro_bosch_bmp280_irq_handle(void) +{ + /* no handle so far */ +} + +static int drv_baro_bosch_bmp280_open(void) +{ + int ret = 0; + + /* set the default config for the sensor here */ + ret = drv_baro_bosch_bmp280_set_work_mode(&bmp280_ctx,BMP280_ULTRA_LOW_POWER_MODE); + if(unlikely(ret)){ + return -1; + } + + ret = drv_baro_bosch_bmp280_set_power_mode(&bmp280_ctx, DEV_POWER_ON); + if(unlikely(ret)){ + return -1; + } + + LOG("%s %s successfully \n", SENSOR_STR, __func__); + return 0; + +} + +static int drv_baro_bosch_bmp280_close(void) +{ + int ret = 0; + ret = drv_baro_bosch_bmp280_set_power_mode(&bmp280_ctx, DEV_POWER_OFF); + if(unlikely(ret)){ + return -1; + } + LOG("%s %s successfully \n", SENSOR_STR, __func__); + return 0; +} + +static int drv_baro_bosch_bmp280_read(void *buf, size_t len) +{ + int ret = 0; + barometer_data_t* pdata = (barometer_data_t*)buf; + + if(buf == NULL){ + return -1; + } + + ret = drv_baro_bosch_bmp280_cali_temp(&bmp280_ctx); + if(unlikely(ret)){ + return ret; + } + + ret = drv_baro_bosch_bmp280_read_baro(&bmp280_ctx, pdata); + if(unlikely(ret)){ + return ret; + } + + pdata->timestamp = aos_now_ms(); + len = sizeof(barometer_data_t); + + return 0; +} + +static int drv_baro_bosch_bmp280_write(const void *buf, size_t len) +{ + (void)buf; + (void)len; + return 0; +} + +static int drv_baro_bosch_bmp280_ioctl(int cmd, unsigned long arg) +{ + int ret = 0; + + switch(cmd){ + case SENSOR_IOCTL_ODR_SET:{ + uint8_t odr = drv_baro_bosch_bmp280_hz2odr(arg); + ret = drv_baro_bosch_bmp280_set_odr(&bmp280_ctx, odr); + if(unlikely(ret)){ + return -1; + } + }break; + case SENSOR_IOCTL_SET_POWER:{ + ret = drv_baro_bosch_bmp280_set_power_mode(&bmp280_ctx, arg); + if(unlikely(ret)){ + return -1; + } + }break; + case SENSOR_IOCTL_GET_INFO:{ + /* fill the dev info here */ + dev_sensor_info_t *info =arg; + *(info->model) = "BMP280"; + info->range_max = 16; + info->range_min = 4; + info->unit = pa; + + }break; + + default:break; + } + + LOG("%s %s successfully \n", SENSOR_STR, __func__); + return 0; +} + +int drv_baro_bosch_bmp280_init(void) +{ + int ret = 0; + sensor_obj_t sensor; + + /* fill the sensor obj parameters here */ + sensor.tag = TAG_DEV_BARO; + sensor.path = dev_baro_path; + sensor.io_port = I2C_PORT; + sensor.open = drv_baro_bosch_bmp280_open; + sensor.close = drv_baro_bosch_bmp280_close; + sensor.read = drv_baro_bosch_bmp280_read; + sensor.write = drv_baro_bosch_bmp280_write; + sensor.ioctl = drv_baro_bosch_bmp280_ioctl; + sensor.irq_handle = drv_baro_bosch_bmp280_irq_handle; + sensor.bus = &bmp280_ctx; + + ret = sensor_create_obj(&sensor); + if(unlikely(ret)){ + return -1; + } + + ret = drv_baro_bosch_bmp280_validate_id(&bmp280_ctx, BMP280_CHIP_ID_VAL); + if(unlikely(ret)){ + return -1; + } + + ret = drv_baro_bosch_bmp280_soft_reset(&bmp280_ctx); + if(unlikely(ret)){ + return -1; + } + + ret = drv_baro_bosch_bmp280_set_default_config(&bmp280_ctx); + if(unlikely(ret)){ + return -1; + } + + ret = drv_baro_bosch_bmp280_get_calib_param(&bmp280_ctx); + if(unlikely(ret)){ + return -1; + } + + LOG("%s %s successfully \n", SENSOR_STR, __func__); + return 0; +} + diff --git a/device/sensor/drv/drv_humi_bosch_bme280.c b/device/sensor/drv/drv_humi_bosch_bme280.c new file mode 100644 index 0000000000..3fd732867e --- /dev/null +++ b/device/sensor/drv/drv_humi_bosch_bme280.c @@ -0,0 +1,743 @@ +/* +* Copyright (C) 2015-2017 Alibaba Group Holding Limited +* +* +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "hal/sensor.h" + + +#define BME280_I2C_ADDR_PRIM (0x76) +#define BME280_I2C_ADDR_SEC (0x77) +#define BME280_CHIP_ID (0x60) +#define BME280_SOFT_RESET (0xB6) + +#define BME280_CHIP_ID_ADDR (0xD0) +#define BME280_RESET_ADDR (0xE0) +#define BME280_TEMP_PRESS_CALIB_DATA_ADDR (0x88) +#define BME280_HUMIDITY_CALIB_DATA_ADDR (0xE1) +#define BME280_PWR_CTRL_ADDR (0xF4) +#define BME280_CTRL_HUM_ADDR (0xF2) +#define BME280_CTRL_MEAS_ADDR (0xF4) +#define BME280_CONFIG_ADDR (0xF5) +#define BME280_TEMP_DATA_ADDR (0xFA) +#define BME280_HUMI_DATA_ADDR (0xFD) + +#define BME280_TEMP_PRESS_CALIB_DATA_LEN (26) +#define BME280_HUMIDITY_CALIB_DATA_LEN (7) +#define BME280_HUMI_DATA_LEN (2) +#define BME280_TEMP_DATA_LEN (3) + + +#define BME280_SLEEP_MODE (0x00) +#define BME280_FORCED_MODE (0x01) +#define BME280_NORMAL_MODE (0x03) +#define BME280_POWER_BIT_MASK (0x03) + +#define BME280_PRESS (1) +#define BME280_TEMP (1 << 1) +#define BME280_HUM (1 << 2) +#define BME280_ALL (0x07) + +#define BME280_OSR_PRESS_SEL (1) +#define BME280_OSR_TEMP_SEL (1 << 1) +#define BME280_OSR_HUM_SEL (1 << 2) +#define BME280_FILTER_SEL (1 << 3) +#define BME280_STANDBY_SEL (1 << 4) +#define BME280_ALL_SETTINGS_SEL (0x1F) + +#define BME280_NO_OVERSAMPLING (0x00) +#define BME280_OVERSAMPLING_1X (0x01) +#define BME280_OVERSAMPLING_2X (0x02) +#define BME280_OVERSAMPLING_4X (0x03) +#define BME280_OVERSAMPLING_8X (0x04) +#define BME280_OVERSAMPLING_16X (0x05) + +#define BME280_STANDBY_TIME_1_MS (0x00) +#define BME280_STANDBY_TIME_62_5_MS (0x01) +#define BME280_STANDBY_TIME_125_MS (0x02) +#define BME280_STANDBY_TIME_250_MS (0x03) +#define BME280_STANDBY_TIME_500_MS (0x04) +#define BME280_STANDBY_TIME_1000_MS (0x05) +#define BME280_STANDBY_TIME_10_MS (0x06) +#define BME280_STANDBY_TIME_20_MS (0x07) + +#define BME280_FILTER_COEFF_OFF (0x00) +#define BME280_FILTER_COEFF_2 (0x01) +#define BME280_FILTER_COEFF_4 (0x02) +#define BME280_FILTER_COEFF_8 (0x03) +#define BME280_FILTER_COEFF_16 (0x04) + + + +#define BME280_ULTRA_LOW_POWER_MODE (0x00) +#define BME280_LOW_POWER_MODE (0x01) +#define BME280_STANDARD_RESOLUTION_MODE (0x02) +#define BME280_HIGH_RESOLUTION_MODE (0x03) +#define BME280_ULTRA_HIGH_RESOLUTION_MODE (0x04) + + +#define BME280_OVERSAMP_SKIPPED (0x00) +#define BME280_OVERSAMP_1X (0x01) +#define BME280_OVERSAMP_2X (0x02) +#define BME280_OVERSAMP_4X (0x03) +#define BME280_OVERSAMP_8X (0x04) +#define BME280_OVERSAMP_16X (0x05) + + +#define BME280_SENSOR_MODE_MSK (0x03) +#define BME280_SENSOR_MODE_POS (0x00) + +#define BME280_CTRL_HUM_MSK (0x07) +#define BME280_CTRL_HUM_POS (0x00) + +#define BME280_CTRL_PRESS_MSK (0x1C) +#define BME280_CTRL_PRESS_POS (0x02) + +#define BME280_CTRL_TEMP_MSK (0xE0) +#define BME280_CTRL_TEMP_POS (0x05) + +#define BME280_FILTER_MSK (0x1C) +#define BME280_FILTER_POS (0x02) + +#define BME280_STANDBY_MSK (0xE0) +#define BME280_STANDBY_POS (0x05) + +#define BME280_SHIFT_BY_01_BITS (1) +#define BME280_SHIFT_BY_02_BITS (2) +#define BME280_SHIFT_BY_03_BITS (3) +#define BME280_SHIFT_BY_04_BITS (4) +#define BME280_SHIFT_BY_05_BITS (5) +#define BME280_SHIFT_BY_08_BITS (8) +#define BME280_SHIFT_BY_11_BITS (11) +#define BME280_SHIFT_BY_12_BITS (12) +#define BME280_SHIFT_BY_13_BITS (13) +#define BME280_SHIFT_BY_14_BITS (14) +#define BME280_SHIFT_BY_15_BITS (15) +#define BME280_SHIFT_BY_16_BITS (16) +#define BME280_SHIFT_BY_17_BITS (17) +#define BME280_SHIFT_BY_18_BITS (18) +#define BME280_SHIFT_BY_19_BITS (19) +#define BME280_SHIFT_BY_25_BITS (25) +#define BME280_SHIFT_BY_31_BITS (31) + +#define BME280_I2C_SLAVE_ADDR_LOW (0X76) +#define BME280_I2C_SLAVE_ADDR_HIGN (0X77) + +#define BME280_DEFAULT_ODR_1HZ (1) + +#define BME280_I2C_ADDR_TRANS(n) ((n)<<1) +#define BME280_I2C_ADDR BME280_I2C_ADDR_TRANS(BME280_I2C_SLAVE_ADDR_LOW) +#define BME280_CONCAT_BYTES(msb, lsb) (((uint16_t)msb << 8) | (uint16_t)lsb) + +#define BME280_SET_BITS(reg_data, bitname, data) ((reg_data & ~(bitname##_MSK)) | ((data << bitname##_POS) & bitname##_MSK)) +#define BME280_SET_BITS_POS_0(reg_data, bitname, data) ((reg_data & ~(bitname##_MSK)) | (data & bitname##_MSK)) + +#define BME280_GET_BITS(reg_data, bitname) ((reg_data & (bitname##_MSK)) >> (bitname##_POS)) +#define BME280_GET_BITS_POS_0(reg_data, bitname) (reg_data & (bitname##_MSK)) + + +typedef struct _bme280_cali_table_t { + uint16_t dig_T1; + int16_t dig_T2; + int16_t dig_T3; + uint16_t dig_P1; + int16_t dig_P2; + int16_t dig_P3; + int16_t dig_P4; + int16_t dig_P5; + int16_t dig_P6; + int16_t dig_P7; + int16_t dig_P8; + int16_t dig_P9; + uint8_t dig_H1; + int16_t dig_H2; + uint8_t dig_H3; + int16_t dig_H4; + int16_t dig_H5; + int8_t dig_H6; + int32_t t_fine; +}bme280_cali_table_t; + +typedef struct _bme280_config_t { + uint8_t osr_p; + uint8_t osr_t; + uint8_t osr_h; + uint8_t filter; + uint8_t standby_time; +}bme280_config_t; + +static bme280_cali_table_t g_cali_table; +static bme280_config_t g_bme280_config; + +i2c_dev_t bme280_ctx = { + .port = 1, + .config.address_width = 7, + .config.freq = 400000, + .config.dev_addr = BME280_I2C_ADDR, +}; + +static int drv_humi_bosch_bme280_get_cali_temp(i2c_dev_t* drv) +{ + int ret; + uint8_t calib_data[BME280_TEMP_PRESS_CALIB_DATA_LEN] = {0}; + + ret = sensor_i2c_read(drv, BME280_TEMP_PRESS_CALIB_DATA_ADDR, calib_data, BME280_TEMP_PRESS_CALIB_DATA_LEN, I2C_OP_RETRIES); + if(unlikely(ret)){ + return ret; + } + + g_cali_table.dig_T1 = BME280_CONCAT_BYTES(calib_data[1], calib_data[0]); + g_cali_table.dig_T2 = (int16_t)BME280_CONCAT_BYTES(calib_data[3], calib_data[2]); + g_cali_table.dig_T3 = (int16_t)BME280_CONCAT_BYTES(calib_data[5], calib_data[4]); + g_cali_table.dig_P1 = BME280_CONCAT_BYTES(calib_data[7], calib_data[6]); + g_cali_table.dig_P2 = (int16_t)BME280_CONCAT_BYTES(calib_data[9], calib_data[8]); + g_cali_table.dig_P3 = (int16_t)BME280_CONCAT_BYTES(calib_data[11], calib_data[10]); + g_cali_table.dig_P4 = (int16_t)BME280_CONCAT_BYTES(calib_data[13], calib_data[12]); + g_cali_table.dig_P5 = (int16_t)BME280_CONCAT_BYTES(calib_data[15], calib_data[14]); + g_cali_table.dig_P6 = (int16_t)BME280_CONCAT_BYTES(calib_data[17], calib_data[16]); + g_cali_table.dig_P7 = (int16_t)BME280_CONCAT_BYTES(calib_data[19], calib_data[18]); + g_cali_table.dig_P8 = (int16_t)BME280_CONCAT_BYTES(calib_data[21], calib_data[20]); + g_cali_table.dig_P9 = (int16_t)BME280_CONCAT_BYTES(calib_data[23], calib_data[22]); + g_cali_table.dig_H1 = calib_data[25]; + + return 0; +} + +static int drv_humi_bosch_bme280_get_cali_humi(i2c_dev_t* drv) +{ + int ret = 0; + int16_t dig_H4_lsb; + int16_t dig_H4_msb; + int16_t dig_H5_lsb; + int16_t dig_H5_msb; + + uint8_t table[BME280_HUMIDITY_CALIB_DATA_LEN] = {0}; + ret = sensor_i2c_read(drv, BME280_HUMIDITY_CALIB_DATA_ADDR, table, BME280_HUMIDITY_CALIB_DATA_LEN, I2C_OP_RETRIES); + if(unlikely(ret)){ + return -1; + } + + g_cali_table.dig_H2 = (int16_t)BME280_CONCAT_BYTES(table[1], table[0]); + g_cali_table.dig_H3 = table[2]; + + dig_H4_msb = (int16_t)(int8_t)table[3] * 16; + dig_H4_lsb = (int16_t)(table[4] & 0x0F); + g_cali_table.dig_H4 = dig_H4_msb | dig_H4_lsb; + + dig_H5_msb = (int16_t)(int8_t)table[5] * 16; + dig_H5_lsb = (int16_t)(table[4] >> 4); + g_cali_table.dig_H5 = dig_H5_msb | dig_H5_lsb; + g_cali_table.dig_H6 = (int8_t)table[6]; + + return 0; +} + +static int drv_humi_bosch_bme280_get_cali_parm(i2c_dev_t* drv) +{ + int ret = 0; + uint8_t table[BME280_HUMIDITY_CALIB_DATA_LEN] = {0}; + + ret = drv_humi_bosch_bme280_get_cali_temp(drv); + if(unlikely(ret)){ + return -1; + } + + ret = drv_humi_bosch_bme280_get_cali_humi(drv); + if(unlikely(ret)){ + return -1; + } + + return 0; +} + + +static int drv_humi_bosch_bme280_soft_reset(i2c_dev_t* drv) +{ + int ret = 0; + ret = sensor_i2c_write(drv, BME280_RESET_ADDR, BME280_SOFT_RESET, I2C_DATA_LEN, I2C_OP_RETRIES); + if(unlikely(ret)){ + return -1; + } + return 0; +} + +static int drv_humi_bosch_bme280_validate_id(i2c_dev_t* drv, uint8_t id_addr, uint8_t id_value) +{ + uint8_t value = 0x00; + int ret = 0; + + if(drv == NULL){ + return -1; + } + + ret = sensor_i2c_read(drv, id_addr, &value, I2C_DATA_LEN, I2C_OP_RETRIES); + if(unlikely(ret)){ + return ret; + } + + if (id_value != value){ + return -1; + } + + return 0; +} + +static int drv_humi_bosch_bme280_enter_sleep_mode(i2c_dev_t* drv) +{ + int ret = 0; + uint8_t ctrl_hum; + uint8_t ctrl_meas; + uint8_t data[4]; + uint8_t reg_addr = BME280_CTRL_HUM_ADDR; + if(drv == NULL){ + return -1; + } + + ret = sensor_i2c_read(drv, BME280_CTRL_HUM_ADDR, data, 4, I2C_OP_RETRIES); + if(unlikely(ret)){ + return ret; + } + + g_bme280_config.osr_h = BME280_GET_BITS_POS_0(data[0], BME280_CTRL_HUM); + g_bme280_config.osr_p = BME280_GET_BITS(data[2], BME280_CTRL_PRESS); + g_bme280_config.osr_t = BME280_GET_BITS(data[2], BME280_CTRL_TEMP); + g_bme280_config.filter = BME280_GET_BITS(data[3], BME280_FILTER); + g_bme280_config.standby_time = BME280_GET_BITS(data[3], BME280_STANDBY); + + ret = drv_humi_bosch_bme280_soft_reset(&bme280_ctx); + if(unlikely(ret)){ + return ret; + } + + return 0; +} + + +static int drv_humi_bosch_bme280_set_work_mode(i2c_dev_t* drv,uint8_t mode) +{ + uint8_t ret = 0; + uint8_t value = 0; + uint8_t temp = 0; + uint8_t baro = 0; + uint8_t humi = 0; + + switch (mode) { + case BME280_ULTRA_LOW_POWER_MODE: + temp = BME280_OVERSAMP_1X; + baro = BME280_OVERSAMP_1X; + humi = BME280_OVERSAMP_1X; + break; + + case BME280_LOW_POWER_MODE: + temp = BME280_OVERSAMP_2X; + baro = BME280_OVERSAMP_2X; + humi = BME280_OVERSAMP_2X; + break; + + case BME280_STANDARD_RESOLUTION_MODE: + temp = BME280_OVERSAMP_4X; + baro = BME280_OVERSAMP_4X; + humi = BME280_OVERSAMP_4X; + break; + + case BME280_HIGH_RESOLUTION_MODE: + temp = BME280_OVERSAMP_8X; + baro = BME280_OVERSAMP_8X; + humi = BME280_OVERSAMP_8X; + break; + + case BME280_ULTRA_HIGH_RESOLUTION_MODE: + temp = BME280_OVERSAMP_16X; + baro = BME280_OVERSAMP_16X; + humi = BME280_OVERSAMP_16X; + break; + + default: + return -1; + + } + + ret = sensor_i2c_read(drv, BME280_CTRL_HUM_ADDR, &value, I2C_DATA_LEN, I2C_OP_RETRIES); + if(unlikely(ret)){ + return ret; + } + + value = BME280_SET_BITS(value,BME280_CTRL_HUM,humi); + + ret = sensor_i2c_write(drv, BME280_CTRL_HUM_ADDR, &value, I2C_DATA_LEN, I2C_OP_RETRIES); + if(unlikely(ret)){ + return ret; + } + + value = 0; + ret = sensor_i2c_read(drv, BME280_PWR_CTRL_ADDR, &value, I2C_DATA_LEN, I2C_OP_RETRIES); + if(unlikely(ret)){ + return ret; + } + + value = BME280_SET_BITS(value,BME280_CTRL_PRESS,baro); + value = BME280_SET_BITS(value,BME280_CTRL_TEMP,temp); + + ret = sensor_i2c_write(drv, BME280_PWR_CTRL_ADDR, &value, I2C_DATA_LEN, I2C_OP_RETRIES); + if(unlikely(ret)){ + return ret; + } + + return ret; +} + + +static int drv_humi_bosch_bme280_set_power_mode(i2c_dev_t* drv, dev_power_mode_e mode) +{ + uint8_t value = 0x00; + int ret = 0; + uint8_t buf[4]; + + ret = sensor_i2c_read(drv, BME280_PWR_CTRL_ADDR, &value, I2C_DATA_LEN, I2C_OP_RETRIES); + if(unlikely(ret)){ + return ret; + } + + switch(mode){ + case DEV_POWER_ON:{ + if((value & BME280_POWER_BIT_MASK) == BME280_NORMAL_MODE){ + return 0; + } + value |= BME280_NORMAL_MODE; + ret = sensor_i2c_write(drv, BME280_PWR_CTRL_ADDR, &value, I2C_DATA_LEN, I2C_OP_RETRIES); + if(unlikely(ret)){ + return ret; + } + }break; + + case DEV_POWER_OFF: + case DEV_SLEEP:{ + if((value & BME280_POWER_BIT_MASK) == BME280_SLEEP_MODE){ + return 0; + } + + value &= (~BME280_POWER_BIT_MASK); + ret = sensor_i2c_write(drv, BME280_PWR_CTRL_ADDR, &value, I2C_DATA_LEN, I2C_OP_RETRIES); + if(unlikely(ret)){ + return ret; + } + + }break; + + default:break; + } + return 0; +} + +static uint8_t drv_humi_bosch_bme280_hz2odr(int hz) +{ + if(hz > 80) + return BME280_STANDBY_TIME_1_MS; + else if(hz > 13) + return BME280_STANDBY_TIME_62_5_MS; + else if(hz > 7) + return BME280_STANDBY_TIME_125_MS; + else if(hz > 3) + return BME280_STANDBY_TIME_250_MS; + else + return BME280_STANDBY_TIME_500_MS; + +} + +static int drv_humi_bosch_bme280_set_odr(i2c_dev_t* drv, uint8_t odr) +{ + int ret = 0; + uint8_t v_data_u8 = 0; + + ret = sensor_i2c_read(drv,BME280_CONFIG_ADDR,&v_data_u8,I2C_DATA_LEN,I2C_OP_RETRIES); + if(unlikely(ret)){ + return ret; + } + + v_data_u8 = BME280_SET_BITS(v_data_u8,BME280_STANDBY,odr); + ret = sensor_i2c_write(drv,BME280_CONFIG_ADDR, + &v_data_u8,I2C_DATA_LEN,I2C_OP_RETRIES); + if(unlikely(ret)){ + return ret; + } + + return ret; +} + + +static int drv_humi_bosch_bme280_set_default_config(i2c_dev_t* drv) +{ + int ret = 0; + + ret = drv_humi_bosch_bme280_set_power_mode(drv, DEV_SLEEP); + if(unlikely(ret)){ + return ret; + } + + ret = drv_humi_bosch_bme280_set_odr(drv, BME280_DEFAULT_ODR_1HZ); + if(unlikely(ret)){ + return ret; + } + + return 0; +} + + +static int drv_humi_bosch_bme280_comp_temp(temperature_data_t *uncomp_data) +{ + int32_t var1; + int32_t var2; + int32_t temperature; + int32_t temperature_min = -4000; + int32_t temperature_max = 8500; + + var1 = (int32_t)((uncomp_data->t / 8) - ((int32_t)g_cali_table.dig_T1 * 2)); + var1 = (var1 * ((int32_t)g_cali_table.dig_T2)) / 2048; + var2 = (int32_t)((uncomp_data->t / 16) - ((int32_t)g_cali_table.dig_T1)); + var2 = (((var2 * var2) / 4096) * ((int32_t)g_cali_table.dig_T3)) / 16384; + g_cali_table.t_fine = var1 + var2; + temperature = (g_cali_table.t_fine * 5 + 128) / 256; + + if (temperature < temperature_min) + temperature = temperature_min; + else if (temperature > temperature_max) + temperature = temperature_max; + + uncomp_data->t = temperature; + + return 0; +} + + +static int drv_humi_bosch_bme280_comp_humi(humidity_data_t* pdata) +{ + int32_t var1 = 0; + int32_t var2 = 0; + int32_t var3 = 0; + int32_t var4 = 0; + int32_t var5 = 0; + uint32_t humidity = 0; + uint32_t humidity_max = 100000; + + var1 = g_cali_table.t_fine - ((int32_t)76800); + var2 = (int32_t)((pdata->h) * 16384); + var3 = (int32_t)(((int32_t)g_cali_table.dig_H4) * 1048576); + var4 = ((int32_t)g_cali_table.dig_H5) * var1; + var5 = (((var2 - var3) - var4) + (int32_t)16384) / 32768; + var2 = (var1 * ((int32_t)g_cali_table.dig_H6)) / 1024; + var3 = (var1 * ((int32_t)g_cali_table.dig_H3)) / 2048; + var4 = ((var2 * (var3 + (int32_t)32768)) / 1024) + (int32_t)2097152; + var2 = ((var4 * ((int32_t)g_cali_table.dig_H2)) + 8192) / 16384; + var3 = var5 * var2; + var4 = ((var3 / 32768) * (var3 / 32768)) / 128; + var5 = var3 - ((var4 * ((int32_t)g_cali_table.dig_H1)) / 16); + var5 = (var5 < 0 ? 0 : var5); + var5 = (var5 > 419430400 ? 419430400 : var5); + humidity = (uint32_t)(var5 / 4096); + + if (humidity > humidity_max){ + humidity = humidity_max; + } + pdata->h = humidity; + return 0; +} + + +static int drv_humi_bosch_bme280_cali_temp(void) +{ + int ret = 0; + uint8_t data[BME280_TEMP_DATA_LEN] = {0}; + temperature_data_t temp; + + ret = sensor_i2c_read(&bme280_ctx, BME280_TEMP_DATA_ADDR, data, BME280_TEMP_DATA_LEN, I2C_OP_RETRIES); + if(unlikely(ret)){ + return ret; + } + + temp.t = (int32_t)((uint32_t)data[0]<>BME280_SHIFT_BY_04_BITS); + + ret = drv_humi_bosch_bme280_comp_temp(&temp); + if(unlikely(ret)){ + return ret; + } + + return 0; +} + + +static int drv_humi_bosch_bme280_read_humi(humidity_data_t* pdata) +{ + int ret = 0; + uint8_t data[BME280_HUMI_DATA_LEN] = {0}; + uint32_t data_lsb; + uint32_t data_msb; + + ret = sensor_i2c_read(&bme280_ctx, BME280_HUMI_DATA_ADDR, data, BME280_HUMI_DATA_LEN, I2C_OP_RETRIES); + if(unlikely(ret)){ + return ret; + } + + data_lsb = (uint32_t)data[0] << 8; + data_msb = (uint32_t)data[1]; + pdata->h = data_msb | data_lsb; + + ret = drv_humi_bosch_bme280_comp_humi(pdata); + if(unlikely(ret)){ + return ret; + } + return 0; +} + + +static void drv_humi_bosch_bme280_irq_handle(void) +{ + /* no handle so far */ +} + +static int drv_humi_bosch_bme280_open(void) +{ + int ret = 0; + + ret = drv_humi_bosch_bme280_set_work_mode(&bme280_ctx, BME280_STANDARD_RESOLUTION_MODE); + if(unlikely(ret)){ + return -1; + } + + ret = drv_humi_bosch_bme280_set_power_mode(&bme280_ctx, DEV_POWER_ON); + if(unlikely(ret)){ + return -1; + } + return 0; +} + +static int drv_humi_bosch_bme280_close(void) +{ + int ret = 0; + ret = drv_humi_bosch_bme280_set_power_mode(&bme280_ctx, DEV_POWER_OFF); + if(unlikely(ret)){ + return -1; + } + return 0; +} + +static int drv_humi_bosch_bme280_read(void *buf, size_t len) +{ + int ret = 0; + uint8_t data[BME280_TEMP_DATA_LEN] = {0}; + uint32_t data_lsb; + uint32_t data_msb; + + humidity_data_t* pdata = (humidity_data_t*)buf; + if(buf == NULL){ + return -1; + } + + if(len < sizeof(humidity_data_t)){ + return -1; + } + + ret = drv_humi_bosch_bme280_cali_temp(); + if(unlikely(ret)){ + return ret; + } + + ret = drv_humi_bosch_bme280_read_humi(pdata); + if(unlikely(ret)){ + return ret; + } + + pdata->timestamp = aos_now_ms(); + + return 0; +} + +static int drv_humi_bosch_bme280_ioctl(int cmd, unsigned long arg) +{ + int ret = 0; + + switch(cmd){ + case SENSOR_IOCTL_ODR_SET:{ + uint8_t odr = drv_humi_bosch_bme280_hz2odr(arg); + ret = drv_humi_bosch_bme280_set_odr(&bme280_ctx, arg); + if(unlikely(ret)){ + return -1; + } + }break; + case SENSOR_IOCTL_SET_POWER:{ + ret = drv_humi_bosch_bme280_set_power_mode(&bme280_ctx, arg); + if(unlikely(ret)){ + return -1; + } + }break; + case SENSOR_IOCTL_GET_INFO:{ + /* fill the dev info here */ + dev_sensor_info_t *info =arg; + *(info->model) = "BME280"; + info->range_max = 16; + info->range_min = 4; + info->unit = pecent; + }break; + + default:break; + } + + return 0; +} + +int drv_humi_bosch_bme280_init(void){ + int ret = 0; + sensor_obj_t sensor; + + /* fill the sensor obj parameters here */ + sensor.io_port = I2C_PORT; + sensor.tag = TAG_DEV_HUMI; + sensor.path = dev_humi_path; + sensor.open = drv_humi_bosch_bme280_open; + sensor.close = drv_humi_bosch_bme280_close; + sensor.read = drv_humi_bosch_bme280_read; + sensor.write = NULL; + sensor.ioctl = drv_humi_bosch_bme280_ioctl; + sensor.irq_handle = drv_humi_bosch_bme280_irq_handle; + sensor.bus = &bme280_ctx; + + ret = sensor_create_obj(&sensor); + if(unlikely(ret)){ + return -1; + } + + ret = drv_humi_bosch_bme280_validate_id(&bme280_ctx, BME280_CHIP_ID_ADDR, BME280_CHIP_ID); + if(unlikely(ret)){ + return -1; + } + + ret = drv_humi_bosch_bme280_soft_reset(&bme280_ctx); + if(unlikely(ret)){ + return -1; + } + + + ret = drv_humi_bosch_bme280_set_default_config(&bme280_ctx); + if(unlikely(ret)){ + return -1; + } + + ret = drv_humi_bosch_bme280_get_cali_parm(&bme280_ctx); + if(unlikely(ret)){ + return -1; + } + + /* update the phy sensor info to sensor hal */ + LOG("%s %s successfully \n", SENSOR_STR, __func__); + return 0; +} + diff --git a/device/sensor/hal/sensor_drv_api.c b/device/sensor/hal/sensor_drv_api.c new file mode 100644 index 0000000000..ed7d42db3c --- /dev/null +++ b/device/sensor/hal/sensor_drv_api.c @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#include +#include "hal/soc/soc.h" +#include "hal/soc/i2c.h" +#include "hal/sensor.h" + +int32_t sensor_i2c_read(i2c_dev_t *i2c, uint16_t reg, uint8_t *data, uint16_t size, uint32_t timeout) +{ + int32_t ret = 0; + if(i2c == NULL){ + return -1; + } + hal_i2c_mem_read(i2c, i2c->config.dev_addr, reg, I2C_REG_LEN, data, size, AOS_WAIT_FOREVER); + return ret; +} + +int32_t sensor_i2c_write(i2c_dev_t *i2c, uint16_t reg, uint8_t *data, uint16_t size, uint32_t timeout) +{ + int32_t ret = 0; + if(i2c == NULL){ + return -1; + } + hal_i2c_mem_write(i2c, i2c->config.dev_addr, reg, I2C_REG_LEN, data, size, AOS_WAIT_FOREVER); + return ret; +} + + diff --git a/device/sensor/hal/sensor_hal.c b/device/sensor/hal/sensor_hal.c new file mode 100644 index 0000000000..458512cadf --- /dev/null +++ b/device/sensor/hal/sensor_hal.c @@ -0,0 +1,316 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#include +#include +#include +#include +#include +#include "common.h" +#include "hal/sensor.h" + +static int sensor_open(inode_t *node, file_t *file); +static int sensor_close(file_t *file); +static ssize_t sensor_read(file_t *f, void *buf, size_t len); +static ssize_t sensor_write(file_t *f, const void *buf, size_t len); +static int sensor_ioctl(file_t *f, int cmd, unsigned long arg); +static int sensor_poll(file_t *f, bool setup, poll_notify_t notify, struct pollfd *fd, void *opa); + +file_ops_t sensor_fops = { + .open = sensor_open, + .close = sensor_close, + .read = sensor_read, + .write = sensor_write, + .ioctl = sensor_ioctl, +}; + +i2c_dev_t i2c = { + .port = 1, + .config.address_width = 7, + .config.freq = 400000, + .config.dev_addr = 0x00, /* the dev addr will be update in the sensor driver */ +}; + + +static sensor_obj_t *g_sensor_obj[TAG_DEV_SENSOR_NUM_MAX]; +static uint32_t g_sensor_cnt = 0; + +static void sensor_set_power_mode(dev_power_mode_e power, int index) +{ + g_sensor_obj[index]->power = power; + +} + +static void sensor_irq_handle(void *arg) +{ + // will implement later + return 0; +} + +static int sensor_register_irq(int index ) +{ + // will implement later + return 0; +} + +static int find_selected_sensor(char* path ) +{ + int i = 0; + + if(path == NULL){ + return -1; + } + + for(i = 0; i < g_sensor_cnt; i++){ + if(strncmp(g_sensor_obj[i]->path, path, strlen(path)) == 0){ + return i; + } + } + return -1; +} +static int load_sensor_config(int index ) +{ + int ret = 0; + g_sensor_obj[index] = (sensor_obj_t*)aos_malloc(sizeof(sensor_obj_t)); + if(g_sensor_obj[index] == NULL){ + return -1; + } + return 0; +} + +static int sensor_io_bus_init(i2c_dev_t *i2c) +{ + int ret = 0; + /* plan to add the other bus register here like spi */ + ret = hal_i2c_init(i2c); + if (ret != 0) { + return -1; + } + return 0; +} + +static int sensor_obj_register(int index ) +{ + int ret = 0; + + if((g_sensor_obj[index]->mode == DEV_INT)||(g_sensor_obj[index]->mode == DEV_DATA_READY)){ + ret = sensor_register_irq(index); + if (ret != 0) { + return -1; + } + } + + ret = aos_register_driver(g_sensor_obj[index]->path, &sensor_fops, NULL); + if (ret != 0) { + return -1; + } + return 0; +} + +int sensor_create_obj(sensor_obj_t* sensor) +{ + int ret = 0; + + g_sensor_obj[g_sensor_cnt] = (sensor_obj_t*)aos_malloc(sizeof(sensor_obj_t)); + if(g_sensor_obj[g_sensor_cnt] == NULL){ + return -1; + } + memset(g_sensor_obj[g_sensor_cnt], 0, sizeof(sensor_obj_t)); + + /* install the phy sensor info into the sensor object datebase here */ + g_sensor_obj[g_sensor_cnt]->io_port = sensor->io_port; + g_sensor_obj[g_sensor_cnt]->path = sensor->path; + g_sensor_obj[g_sensor_cnt]->tag = sensor->tag; + g_sensor_obj[g_sensor_cnt]->open = sensor->open; + g_sensor_obj[g_sensor_cnt]->close = sensor->close; + g_sensor_obj[g_sensor_cnt]->ioctl = sensor->ioctl; + g_sensor_obj[g_sensor_cnt]->read = sensor->read; + g_sensor_obj[g_sensor_cnt]->write = sensor->write; + g_sensor_obj[g_sensor_cnt]->irq_handle = sensor->irq_handle; + g_sensor_obj[g_sensor_cnt]->mode = sensor->mode; + g_sensor_obj[g_sensor_cnt]->bus->config.address_width = sensor->bus->config.address_width; + g_sensor_obj[g_sensor_cnt]->bus->config.freq = sensor->bus->config.freq; + g_sensor_obj[g_sensor_cnt]->bus->port = sensor->bus->port; + g_sensor_obj[g_sensor_cnt]->power = DEV_POWER_OFF; // will update the status later + + /* register the sensor object into the irq list and vfs */ + ret = sensor_obj_register(g_sensor_cnt); + if (ret != 0) { + goto error; + } + //ret = sensor_io_bus_init((sensor->bus)); + //if (ret != 0) { + // goto error; + //} + g_sensor_cnt++; + LOG("%s %s successfully \n", SENSOR_STR, __func__); + return 0; + +error: + free(g_sensor_obj[g_sensor_cnt]); + return -1; +} + +static int sensor_hal_get_dev_list(void* buf) +{ + sensor_list_t* list = buf; + if(buf == NULL) + return -1; + + /* load the sensor count and tag list here */ + list->cnt = g_sensor_cnt; + for(int index = 0; index < g_sensor_cnt; index++){ + list->list[index] = g_sensor_obj[index]->tag; + } + + return 0; +} + +static int sensor_open(inode_t *node, file_t *file) +{ + int index = 0; + + if((node == NULL)||(file == NULL)){ + return -1; + } + + + /* just open the /dev/sensor node here */ + if(strncmp(sensor_node_path, node->i_name, strlen(node->i_name)) == 0){ + return 0; + } + + index = find_selected_sensor(node->i_name); + if(( g_sensor_obj[index]->open == NULL)||(index < 0)){ + return -1; + } + + g_sensor_obj[index]->open(); + + LOG("%s %s successfully\n", SENSOR_STR, __func__); + return 0; +} + +static int sensor_close(file_t *file) +{ + int index = 0; + + /* just close the /dev/sensor node here */ + if(strncmp(sensor_node_path, (file->node->i_name), strlen(file->node->i_name)) == 0){ + return 0; + } + + index = find_selected_sensor(file->node->i_name); + if(( g_sensor_obj[index]->close == NULL)||(index < 0)){ + return -1; + } + g_sensor_obj[index]->close(); + + return 0; +} + +static ssize_t sensor_read(file_t *f, void *buf, size_t len) +{ + int index = 0; + int ret = 0; + + if(f == NULL){ + return -1; + } + + index = find_selected_sensor(f->node->i_name); + if(( g_sensor_obj[index]->read == NULL)||(index < 0)){ + goto error; + } + + if(buf == NULL){ + goto error; + } + + ret = g_sensor_obj[index]->read(buf, len); + if(ret != 0){ + goto error; + } + + LOG("%s %s successfully\n", SENSOR_STR, __func__); + return len; + +error: + return -1; +} + +static ssize_t sensor_write(file_t *f, const void *buf, size_t len) +{ + /* no need this functionality recently */ + return 0; +} + +static int sensor_ioctl(file_t *f, int cmd, unsigned long arg) +{ + int ret = 0; + int index = 0; + + if(f == NULL){ + return -1; + } + + if(cmd == SENSOR_IOCTL_GET_SENSOR_LIST){ + ret = sensor_hal_get_dev_list(arg); + if(ret != 0){ + return -1; + } + return 0; + } + + index = find_selected_sensor(f->node->i_name); + if(( g_sensor_obj[index]->ioctl == NULL)||(index < 0)){ + return -1; + } + + ret = g_sensor_obj[index]->ioctl(cmd, arg); + if(ret != 0){ + return -1; + } + LOG("%s %s successfully\n", SENSOR_STR, __func__); + return 0; +} + +static int sensor_hal_register(void) +{ + int ret = 0; + ret = aos_register_driver(sensor_node_path, &sensor_fops, NULL); + if (ret != 0) { + return -1; + } + return 0; +} + +int sensor_init(void){ + int ret = 0; + int index = 0; + g_sensor_cnt = 0 ; + + sensor_io_bus_init(&i2c); + +#ifdef AOS_SENSOR_HUMI_BOSCH_BME280 + drv_humi_bosch_bme280_init(); +#endif /* AOS_SENSOR_HUMI_BOSCH_BME280 */ + +#ifdef AOS_SENSOR_ACC_BOSCH_BMA253 + drv_acc_bosch_bma253_init(); +#endif /* AOS_SENSOR_ACC_BOSCH_BMA253 */ + +#ifdef AOS_SENSOR_BARO_BOSCH_BMP280 + drv_baro_bosch_bmp280_init(); +#endif /* AOS_SENSOR_BARO_BOSCH_BMP280 */ + + ret = sensor_hal_register(); + if(ret != 0){ + return -1; + } + + LOG("%s %s successfully\n", SENSOR_STR, __func__); + return 0; +} + diff --git a/device/sensor/hal/sensor_hal.h b/device/sensor/hal/sensor_hal.h new file mode 100644 index 0000000000..84fe6ec7d6 --- /dev/null +++ b/device/sensor/hal/sensor_hal.h @@ -0,0 +1,11 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#ifndef SENSOR_HAL_H +#define SENSOR_HAL_H + +extern int sensor_hal_init(void); + +#endif /* SENSOR_HAL_H */ + diff --git a/device/sensor/sensor.mk b/device/sensor/sensor.mk new file mode 100644 index 0000000000..b0a7df652b --- /dev/null +++ b/device/sensor/sensor.mk @@ -0,0 +1,19 @@ +NAME := sensor + +$(NAME)_TYPE := kernel + +$(NAME)_SOURCES += \ + hal/sensor_hal.c \ + hal/sensor_drv_api.c \ + drv/drv_humi_bosch_bme280.c \ + drv/drv_acc_bosch_bma253.c \ + drv/drv_baro_bosch_bmp280.c + +$(NAME)_CFLAGS += -Wall -Werror + +GLOBAL_INCLUDES += . +GLOBAL_DEFINES += AOS_SENSOR + +#GLOBAL_DEFINES += AOS_SENSOR_HUMI_BOSCH_BME280 +#GLOBAL_DEFINES += AOS_SENSOR_ACC_BOSCH_BMA253 +#GLOBAL_DEFINES += AOS_SENSOR_BARO_BOSCH_BMP280 diff --git a/example/GUI/STemWin/Config/GUIConf.c b/example/GUI/STemWin/Config/GUIConf.c new file mode 100755 index 0000000000..f78f5b8573 --- /dev/null +++ b/example/GUI/STemWin/Config/GUIConf.c @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GUIConf.c +Purpose : Display controller initialization +---------------------------END-OF-HEADER------------------------------ +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +#include "GUI.h" + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ +// +// Define the available number of bytes available for the GUI +// +#define GUI_NUMBYTES 1024*32 + +/********************************************************************* +* +* Public code +* +********************************************************************** +*/ + +// +// 32 bit aligned memory area +// +static U32 aMemory[GUI_NUMBYTES / 4]; + +/********************************************************************* +* +* GUI_X_Config +* +* Purpose: +* Called during the initialization process in order to set up the +* available memory for the GUI. +*/ +void GUI_X_Config(void) { + // + // Assign memory to emWin + // + GUI_ALLOC_AssignMemory(aMemory, GUI_NUMBYTES); + // + // Set default font + // + GUI_SetDefaultFont(GUI_FONT_6X8); +} + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/Config/GUIConf.h b/example/GUI/STemWin/Config/GUIConf.h new file mode 100755 index 0000000000..17b4f089d8 --- /dev/null +++ b/example/GUI/STemWin/Config/GUIConf.h @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GUIConf.h +Purpose : Configures emWins abilities, fonts etc. +---------------------------------------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef GUICONF_H +#define GUICONF_H + +/********************************************************************* +* +* Multi layer/display support +*/ +#define GUI_NUM_LAYERS 2 // Maximum number of available layers + +/********************************************************************* +* +* Multi tasking support +*/ +#define OS_SUPPORT + +#ifdef OS_SUPPORT + #define GUI_OS (1) // Compile with multitasking support +#else + #define GUI_OS (0) +#endif + +/********************************************************************* +* +* Configuration of touch support +*/ +#ifndef GUI_SUPPORT_TOUCH + #define GUI_SUPPORT_TOUCH (0) // Support touchscreen +#endif + +/********************************************************************* +* +* Default font +*/ +#define GUI_DEFAULT_FONT &GUI_Font6x8 + +/********************************************************************* +* +* Configuration of available packages +*/ +#define GUI_SUPPORT_MOUSE (0) /* Support a mouse */ +#define GUI_WINSUPPORT (1) /* Use window manager */ +#define GUI_SUPPORT_MEMDEV (1) /* Memory device package available */ +#define GUI_SUPPORT_DEVICES (1) /* Enable use of device pointers */ + +#endif /* Avoid multiple inclusion */ diff --git a/example/GUI/STemWin/Config/LCDConf_FlexColor_Template.c b/example/GUI/STemWin/Config/LCDConf_FlexColor_Template.c new file mode 100755 index 0000000000..4e5e25907b --- /dev/null +++ b/example/GUI/STemWin/Config/LCDConf_FlexColor_Template.c @@ -0,0 +1,285 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : LCDConf_FlexColor_Template.c +Purpose : Display controller configuration (single layer) +---------------------------END-OF-HEADER------------------------------ +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +#include "GUI.h" +#include "GUIDRV_FlexColor.h" +#include "stm32l4xx_ll_bus.h" +#include "stm32l4xx_ll_dma.h" +#include "stm32l4xx_ll_dma2d.h" +//#include "st7789h2.h" +//#include "stm32l496g_discovery.h" +//#include "stm32l496g_discovery_lcd.h" +//#include "stm32l496g_discovery_ts.h" +/********************************************************************* +* +* Layer configuration (to be modified) +* +********************************************************************** +*/ + +/* Physical display size */ +#define XSIZE_PHYS 240 +#define YSIZE_PHYS 240 + +/********************************************************************* +* +* Configuration checking +* +********************************************************************** +*/ +#ifndef VXSIZE_PHYS + #define VXSIZE_PHYS XSIZE_PHYS +#endif +#ifndef VYSIZE_PHYS + #define VYSIZE_PHYS YSIZE_PHYS +#endif +#ifndef XSIZE_PHYS + #error Physical X size of display is not defined! +#endif +#ifndef YSIZE_PHYS + #error Physical Y size of display is not defined! +#endif +#ifndef GUICC_M565 + #error Color conversion not defined! +#endif +#ifndef GUIDRV_FLEXCOLOR + #error No display driver defined! +#endif + +/********************************************************************* +* +* Local functions +* +********************************************************************** +*/ + +/******************************************************************** +* +* LcdWriteReg +* +* Function description: +* Sets display register +*/ +static void LcdWriteReg(U16 Data) +{ +// LCD_IO_WriteReg(Data); +} + +/******************************************************************** +* +* LcdWriteData +* +* Function description: +* Writes a value to a display register +*/ +static void LcdWriteData(U16 Data) +{ +// LCD_IO_WriteData(Data); +} + +/******************************************************************** +* +* LcdWriteDataMultiple +* +* Function description: +* Writes multiple values to a display register. +*/ +static void LcdWriteDataMultiple(U16 * pData, int NumItems) +{ + /* Set input memory address */ +// LL_DMA2D_FGND_SetMemAddr(DMA2D, (uint32_t)pData); + + /* Set number of lines */ +// LL_DMA2D_SetNbrOfLines(DMA2D, NumItems); + + /* Start DMA2D transfer */ +// LL_DMA2D_Start(DMA2D); + +/* Wait for transfer end */ +// while (LL_DMA2D_IsTransferOngoing(DMA2D)); +} + +/******************************************************************** +* +* LcdReadDataMultiple +* +* Function description: +* Reads multiple values from a display register. +*/ +static void LcdReadDataMultiple(U16 * pData, int NumItems) +{ + __IO uint16_t tmp; + +// LCD_IO_WriteReg(ST7789H2_READ_RAM); + + /* Dummy read */ +// tmp = LCD_IO_ReadData(); + + while (NumItems--) + { +// *pData++ = LCD_IO_ReadData(); + } +} + +/********************************************************************* +* +* Public functions +* +********************************************************************** +*/ + +/** + * @brief Initializes the LCD. + * @param None + * @retval LCD state + */ +void LCD_LL_Init(void) +{ + /* LCD Init */ +// BSP_LCD_Init(); + +// LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA2D); + + /* Configure the DMA2D Color Mode */ +// LL_DMA2D_SetOutputColorMode(DMA2D, LL_DMA2D_OUTPUT_MODE_RGB565); + + /* Foreground Configuration: */ + /* Set Alpha value to full opaque */ +// LL_DMA2D_FGND_SetAlpha(DMA2D, 0xFF); + + /* Foreground layer format is RGB565 (16 bpp) */ +// LL_DMA2D_FGND_SetColorMode(DMA2D, LL_DMA2D_INPUT_MODE_RGB565); + + /* Set output address (remains constant throughout the application) */ +// LL_DMA2D_SetOutputMemAddr(DMA2D, (uint32_t)(&(LCD_ADDR->REG))); + + /* Set number of pixels per line (remains constant throughout the application) */ +// LL_DMA2D_SetNbrOfPixelsPerLines(DMA2D, 0x01); +} + +/********************************************************************* +* +* LCD_X_Config +* +* Function description: +* Called during the initialization process in order to set up the +* display driver configuration. +* +*/ +void LCD_X_Config(void) +{ + GUI_DEVICE * pDevice; + CONFIG_FLEXCOLOR Config = {0}; + GUI_PORT_API PortAPI = {0}; + + /* Set display driver and color conversion */ + pDevice = GUI_DEVICE_CreateAndLink(GUIDRV_FLEXCOLOR, GUICC_M565, 0, 0); + + /* Display driver configuration, required for Lin-driver */ + LCD_SetSizeEx (0, XSIZE_PHYS , YSIZE_PHYS); + LCD_SetVSizeEx(0, VXSIZE_PHYS, VYSIZE_PHYS); + + Config.Orientation = GUI_SWAP_XY | GUI_MIRROR_X; + GUIDRV_FlexColor_Config(pDevice, &Config); + + /* Set controller and operation mode */ + PortAPI.pfWrite16_A0 = LcdWriteReg; + PortAPI.pfWrite16_A1 = LcdWriteData; + PortAPI.pfWriteM16_A1 = LcdWriteDataMultiple; + PortAPI.pfReadM16_A1 = LcdReadDataMultiple; + GUIDRV_FlexColor_SetFunc(pDevice, &PortAPI, GUIDRV_FLEXCOLOR_F66709, GUIDRV_FLEXCOLOR_M16C0B16); +} + +/********************************************************************* +* +* LCD_X_DisplayDriver +* +* Function description: +* This function is called by the display driver for several purposes. +* To support the according task the routine needs to be adapted to +* the display controller. Please note that the commands marked with +* 'optional' are not cogently required and should only be adapted if +* the display controller supports these features. +* +* Parameter: +* LayerIndex - Index of layer to be configured +* Cmd - Please refer to the details in the switch statement below +* pData - Pointer to a LCD_X_DATA structure +* +* Return Value: +* < -1 - Error +* -1 - Command not handled +* 0 - Ok +*/ +int LCD_X_DisplayDriver(unsigned LayerIndex, unsigned Cmd, void * pData) { + int r; + (void) LayerIndex; + (void) pData; + + switch (Cmd) { + case LCD_X_INITCONTROLLER: { + + LCD_LL_Init(); + + return 0; + } + default: + r = -1; + } + return r; +} + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/Config/LCDConf_FlexColor_Template.h b/example/GUI/STemWin/Config/LCDConf_FlexColor_Template.h new file mode 100755 index 0000000000..855f9e93d8 --- /dev/null +++ b/example/GUI/STemWin/Config/LCDConf_FlexColor_Template.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : LCDConf_FlexColor_Template.h +Purpose : Display driver configuration file +---------------------------END-OF-HEADER------------------------------ +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef LCDCONF_H +#define LCDCONF_H + +#endif /* LCDCONF_H */ + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/Lib/MCD-ST Image SW License Agreement V2.pdf b/example/GUI/STemWin/Lib/MCD-ST Image SW License Agreement V2.pdf new file mode 100755 index 0000000000..7ad54a2cd7 Binary files /dev/null and b/example/GUI/STemWin/Lib/MCD-ST Image SW License Agreement V2.pdf differ diff --git a/example/GUI/STemWin/Lib/STemWin540_CM4_OS_GCC.a b/example/GUI/STemWin/Lib/STemWin540_CM4_OS_GCC.a new file mode 100755 index 0000000000..0fcba0075a Binary files /dev/null and b/example/GUI/STemWin/Lib/STemWin540_CM4_OS_GCC.a differ diff --git a/example/GUI/STemWin/Lib/STemWin540_CM4_OS_GCC_ARGB.a b/example/GUI/STemWin/Lib/STemWin540_CM4_OS_GCC_ARGB.a new file mode 100755 index 0000000000..7497248d6d Binary files /dev/null and b/example/GUI/STemWin/Lib/STemWin540_CM4_OS_GCC_ARGB.a differ diff --git a/example/GUI/STemWin/Lib/STemWin540_CM4_OS_GCC_ot.a b/example/GUI/STemWin/Lib/STemWin540_CM4_OS_GCC_ot.a new file mode 100755 index 0000000000..07fdf2ec0f Binary files /dev/null and b/example/GUI/STemWin/Lib/STemWin540_CM4_OS_GCC_ot.a differ diff --git a/example/GUI/STemWin/Lib/STemWin540_CM4_OS_GCC_ot_ARGB.a b/example/GUI/STemWin/Lib/STemWin540_CM4_OS_GCC_ot_ARGB.a new file mode 100755 index 0000000000..7e0d2d54bc Binary files /dev/null and b/example/GUI/STemWin/Lib/STemWin540_CM4_OS_GCC_ot_ARGB.a differ diff --git a/example/GUI/STemWin/Lib/STemWin540_CM4_OS_IAR.a b/example/GUI/STemWin/Lib/STemWin540_CM4_OS_IAR.a new file mode 100755 index 0000000000..10babe7d91 Binary files /dev/null and b/example/GUI/STemWin/Lib/STemWin540_CM4_OS_IAR.a differ diff --git a/example/GUI/STemWin/Lib/STemWin540_CM4_OS_IAR_ARGB.a b/example/GUI/STemWin/Lib/STemWin540_CM4_OS_IAR_ARGB.a new file mode 100755 index 0000000000..9ecbb30669 Binary files /dev/null and b/example/GUI/STemWin/Lib/STemWin540_CM4_OS_IAR_ARGB.a differ diff --git a/example/GUI/STemWin/Lib/STemWin540_CM4_OS_IAR_ot.a b/example/GUI/STemWin/Lib/STemWin540_CM4_OS_IAR_ot.a new file mode 100755 index 0000000000..a0acb82588 Binary files /dev/null and b/example/GUI/STemWin/Lib/STemWin540_CM4_OS_IAR_ot.a differ diff --git a/example/GUI/STemWin/Lib/STemWin540_CM4_OS_IAR_ot_ARGB.a b/example/GUI/STemWin/Lib/STemWin540_CM4_OS_IAR_ot_ARGB.a new file mode 100755 index 0000000000..110ad2725f Binary files /dev/null and b/example/GUI/STemWin/Lib/STemWin540_CM4_OS_IAR_ot_ARGB.a differ diff --git a/example/GUI/STemWin/Lib/STemWin540_CM4_OS_Keil.lib b/example/GUI/STemWin/Lib/STemWin540_CM4_OS_Keil.lib new file mode 100755 index 0000000000..dd3b2088e5 Binary files /dev/null and b/example/GUI/STemWin/Lib/STemWin540_CM4_OS_Keil.lib differ diff --git a/example/GUI/STemWin/Lib/STemWin540_CM4_OS_Keil_ARGB.lib b/example/GUI/STemWin/Lib/STemWin540_CM4_OS_Keil_ARGB.lib new file mode 100755 index 0000000000..f7a60f0008 Binary files /dev/null and b/example/GUI/STemWin/Lib/STemWin540_CM4_OS_Keil_ARGB.lib differ diff --git a/example/GUI/STemWin/Lib/STemWin540_CM4_OS_Keil_ot.lib b/example/GUI/STemWin/Lib/STemWin540_CM4_OS_Keil_ot.lib new file mode 100755 index 0000000000..49b8ed0943 Binary files /dev/null and b/example/GUI/STemWin/Lib/STemWin540_CM4_OS_Keil_ot.lib differ diff --git a/example/GUI/STemWin/Lib/STemWin540_CM4_OS_Keil_ot_ARGB.lib b/example/GUI/STemWin/Lib/STemWin540_CM4_OS_Keil_ot_ARGB.lib new file mode 100755 index 0000000000..d63663be00 Binary files /dev/null and b/example/GUI/STemWin/Lib/STemWin540_CM4_OS_Keil_ot_ARGB.lib differ diff --git a/example/GUI/STemWin/OS/GUI_X_rhino.c b/example/GUI/STemWin/OS/GUI_X_rhino.c new file mode 100755 index 0000000000..87bad128a8 --- /dev/null +++ b/example/GUI/STemWin/OS/GUI_X_rhino.c @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#include +#include "GUI_Private.H" +#include "stdio.H" + +static kmutex_t disp_mutex; +static ksem_t event_sem; + +static ksem_t key_sem; +static int key_pressed; +static char key_is_inited; + +GUI_TIMER_TIME GUI_X_GetTime (void) +{ + return ((GUI_TIMER_TIME)krhino_sys_time_get()); +} + + +void GUI_X_Delay (int period) +{ + krhino_task_sleep(krhino_ms_to_ticks(period)); +} + +void GUI_X_ExecIdle (void) +{ + GUI_X_Delay(1); +} + +void GUI_X_InitOS (void) +{ + krhino_mutex_create(&disp_mutex, "mutex"); + krhino_sem_create(&event_sem, "sem", 0); +} + +void GUI_X_Lock (void) +{ + krhino_mutex_lock(&disp_mutex, RHINO_WAIT_FOREVER); +} + +void GUI_X_Unlock (void) +{ + krhino_mutex_unlock(&disp_mutex); +} + + +U32 GUI_X_GetTaskId (void) +{ + return ((U32)krhino_cur_task_get()); +} + +void GUI_X_WaitEvent (void) +{ + krhino_sem_take(&event_sem, RHINO_WAIT_FOREVER); +} + +void GUI_X_SignalEvent (void) +{ + krhino_sem_give(&event_sem); +} + +static void CheckInit (void) +{ + if (key_is_inited == 0) { + key_is_inited = 1; + GUI_X_Init(); + } +} + + +void GUI_X_Init (void) +{ + krhino_sem_create(&key_sem, "sem", 0); +} + + +int GUI_X_GetKey (void) +{ + int r; + + r = key_pressed; + CheckInit(); + key_pressed = 0; + return (r); +} + +int GUI_X_WaitKey (void) +{ + int r; + + CheckInit(); + if (key_pressed == 0) { + krhino_sem_take(&key_sem, RHINO_WAIT_FOREVER); + } + r = key_pressed; + key_pressed = 0; + return (r); +} + +void GUI_X_StoreKey (int k) +{ + key_pressed = k; + krhino_sem_give(&key_sem); +} + diff --git a/example/GUI/STemWin/Simulation/GUISim.lib b/example/GUI/STemWin/Simulation/GUISim.lib new file mode 100755 index 0000000000..2c6506c2cd Binary files /dev/null and b/example/GUI/STemWin/Simulation/GUISim.lib differ diff --git a/example/GUI/STemWin/Simulation/SimulationMinGW.res b/example/GUI/STemWin/Simulation/SimulationMinGW.res new file mode 100755 index 0000000000..30df30447f Binary files /dev/null and b/example/GUI/STemWin/Simulation/SimulationMinGW.res differ diff --git a/example/GUI/STemWin/Simulation/WinMain.c b/example/GUI/STemWin/Simulation/WinMain.c new file mode 100755 index 0000000000..a429bf2aab --- /dev/null +++ b/example/GUI/STemWin/Simulation/WinMain.c @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +---------------------------------------------------------------------- +File : WinMain.c +---------------------------END-OF-HEADER------------------------------ +*/ +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ +#include + +#include "GUI_SIM_Win32.h" + +/********************************************************************* +* +* Public data +* +********************************************************************** +*/ + +/********************************************************************* +* +* Public code +* +********************************************************************** +*/ +/********************************************************************* +* +* WinMain +*/ +int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { + return SIM_GUI_App(hInstance, hPrevInstance, lpCmdLine, nCmdShow); +} + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/Software/Bin2C.exe b/example/GUI/STemWin/Software/Bin2C.exe new file mode 100755 index 0000000000..f1d3d60c23 Binary files /dev/null and b/example/GUI/STemWin/Software/Bin2C.exe differ diff --git a/example/GUI/STemWin/Software/BmpCvtST.exe b/example/GUI/STemWin/Software/BmpCvtST.exe new file mode 100755 index 0000000000..24ef0b9184 Binary files /dev/null and b/example/GUI/STemWin/Software/BmpCvtST.exe differ diff --git a/example/GUI/STemWin/Software/FontCvtST.exe b/example/GUI/STemWin/Software/FontCvtST.exe new file mode 100755 index 0000000000..59278cde08 Binary files /dev/null and b/example/GUI/STemWin/Software/FontCvtST.exe differ diff --git a/example/GUI/STemWin/Software/GUIBuilder.exe b/example/GUI/STemWin/Software/GUIBuilder.exe new file mode 100755 index 0000000000..8e6589aa6a Binary files /dev/null and b/example/GUI/STemWin/Software/GUIBuilder.exe differ diff --git a/example/GUI/STemWin/Software/JPEG2Movie.exe b/example/GUI/STemWin/Software/JPEG2Movie.exe new file mode 100755 index 0000000000..bdef620f36 Binary files /dev/null and b/example/GUI/STemWin/Software/JPEG2Movie.exe differ diff --git a/example/GUI/STemWin/Software/JPEG2MovieScripts/120x68.bat b/example/GUI/STemWin/Software/JPEG2MovieScripts/120x68.bat new file mode 100755 index 0000000000..22e81ceabe --- /dev/null +++ b/example/GUI/STemWin/Software/JPEG2MovieScripts/120x68.bat @@ -0,0 +1,21 @@ +@ECHO OFF +GOTO START + +****************************************************************************** +* +* File: x.bat +* +* Purpose: This file simply calls MakeMovie.bat with its own file name +* as parameter %2 which defines the resolution used by FFmpeg +* to create the JPEG files. +* By copying and renaming this file further resolutions can +* be simply achieved. +* +* Note: The file name of this file needs to match the size +* specification parameter '-s' for FFmpeg.exe. +* +****************************************************************************** + +:START + +@%~dp0MakeMovie.bat %1 %~n0 \ No newline at end of file diff --git a/example/GUI/STemWin/Software/JPEG2MovieScripts/160x120.bat b/example/GUI/STemWin/Software/JPEG2MovieScripts/160x120.bat new file mode 100755 index 0000000000..22e81ceabe --- /dev/null +++ b/example/GUI/STemWin/Software/JPEG2MovieScripts/160x120.bat @@ -0,0 +1,21 @@ +@ECHO OFF +GOTO START + +****************************************************************************** +* +* File: x.bat +* +* Purpose: This file simply calls MakeMovie.bat with its own file name +* as parameter %2 which defines the resolution used by FFmpeg +* to create the JPEG files. +* By copying and renaming this file further resolutions can +* be simply achieved. +* +* Note: The file name of this file needs to match the size +* specification parameter '-s' for FFmpeg.exe. +* +****************************************************************************** + +:START + +@%~dp0MakeMovie.bat %1 %~n0 \ No newline at end of file diff --git a/example/GUI/STemWin/Software/JPEG2MovieScripts/160x90.bat b/example/GUI/STemWin/Software/JPEG2MovieScripts/160x90.bat new file mode 100755 index 0000000000..22e81ceabe --- /dev/null +++ b/example/GUI/STemWin/Software/JPEG2MovieScripts/160x90.bat @@ -0,0 +1,21 @@ +@ECHO OFF +GOTO START + +****************************************************************************** +* +* File: x.bat +* +* Purpose: This file simply calls MakeMovie.bat with its own file name +* as parameter %2 which defines the resolution used by FFmpeg +* to create the JPEG files. +* By copying and renaming this file further resolutions can +* be simply achieved. +* +* Note: The file name of this file needs to match the size +* specification parameter '-s' for FFmpeg.exe. +* +****************************************************************************** + +:START + +@%~dp0MakeMovie.bat %1 %~n0 \ No newline at end of file diff --git a/example/GUI/STemWin/Software/JPEG2MovieScripts/200x150.bat b/example/GUI/STemWin/Software/JPEG2MovieScripts/200x150.bat new file mode 100755 index 0000000000..22e81ceabe --- /dev/null +++ b/example/GUI/STemWin/Software/JPEG2MovieScripts/200x150.bat @@ -0,0 +1,21 @@ +@ECHO OFF +GOTO START + +****************************************************************************** +* +* File: x.bat +* +* Purpose: This file simply calls MakeMovie.bat with its own file name +* as parameter %2 which defines the resolution used by FFmpeg +* to create the JPEG files. +* By copying and renaming this file further resolutions can +* be simply achieved. +* +* Note: The file name of this file needs to match the size +* specification parameter '-s' for FFmpeg.exe. +* +****************************************************************************** + +:START + +@%~dp0MakeMovie.bat %1 %~n0 \ No newline at end of file diff --git a/example/GUI/STemWin/Software/JPEG2MovieScripts/240x136.bat b/example/GUI/STemWin/Software/JPEG2MovieScripts/240x136.bat new file mode 100755 index 0000000000..22e81ceabe --- /dev/null +++ b/example/GUI/STemWin/Software/JPEG2MovieScripts/240x136.bat @@ -0,0 +1,21 @@ +@ECHO OFF +GOTO START + +****************************************************************************** +* +* File: x.bat +* +* Purpose: This file simply calls MakeMovie.bat with its own file name +* as parameter %2 which defines the resolution used by FFmpeg +* to create the JPEG files. +* By copying and renaming this file further resolutions can +* be simply achieved. +* +* Note: The file name of this file needs to match the size +* specification parameter '-s' for FFmpeg.exe. +* +****************************************************************************** + +:START + +@%~dp0MakeMovie.bat %1 %~n0 \ No newline at end of file diff --git a/example/GUI/STemWin/Software/JPEG2MovieScripts/240x180.bat b/example/GUI/STemWin/Software/JPEG2MovieScripts/240x180.bat new file mode 100755 index 0000000000..22e81ceabe --- /dev/null +++ b/example/GUI/STemWin/Software/JPEG2MovieScripts/240x180.bat @@ -0,0 +1,21 @@ +@ECHO OFF +GOTO START + +****************************************************************************** +* +* File: x.bat +* +* Purpose: This file simply calls MakeMovie.bat with its own file name +* as parameter %2 which defines the resolution used by FFmpeg +* to create the JPEG files. +* By copying and renaming this file further resolutions can +* be simply achieved. +* +* Note: The file name of this file needs to match the size +* specification parameter '-s' for FFmpeg.exe. +* +****************************************************************************** + +:START + +@%~dp0MakeMovie.bat %1 %~n0 \ No newline at end of file diff --git a/example/GUI/STemWin/Software/JPEG2MovieScripts/320x180.bat b/example/GUI/STemWin/Software/JPEG2MovieScripts/320x180.bat new file mode 100755 index 0000000000..22e81ceabe --- /dev/null +++ b/example/GUI/STemWin/Software/JPEG2MovieScripts/320x180.bat @@ -0,0 +1,21 @@ +@ECHO OFF +GOTO START + +****************************************************************************** +* +* File: x.bat +* +* Purpose: This file simply calls MakeMovie.bat with its own file name +* as parameter %2 which defines the resolution used by FFmpeg +* to create the JPEG files. +* By copying and renaming this file further resolutions can +* be simply achieved. +* +* Note: The file name of this file needs to match the size +* specification parameter '-s' for FFmpeg.exe. +* +****************************************************************************** + +:START + +@%~dp0MakeMovie.bat %1 %~n0 \ No newline at end of file diff --git a/example/GUI/STemWin/Software/JPEG2MovieScripts/320x240.bat b/example/GUI/STemWin/Software/JPEG2MovieScripts/320x240.bat new file mode 100755 index 0000000000..22e81ceabe --- /dev/null +++ b/example/GUI/STemWin/Software/JPEG2MovieScripts/320x240.bat @@ -0,0 +1,21 @@ +@ECHO OFF +GOTO START + +****************************************************************************** +* +* File: x.bat +* +* Purpose: This file simply calls MakeMovie.bat with its own file name +* as parameter %2 which defines the resolution used by FFmpeg +* to create the JPEG files. +* By copying and renaming this file further resolutions can +* be simply achieved. +* +* Note: The file name of this file needs to match the size +* specification parameter '-s' for FFmpeg.exe. +* +****************************************************************************** + +:START + +@%~dp0MakeMovie.bat %1 %~n0 \ No newline at end of file diff --git a/example/GUI/STemWin/Software/JPEG2MovieScripts/480x272.bat b/example/GUI/STemWin/Software/JPEG2MovieScripts/480x272.bat new file mode 100755 index 0000000000..22e81ceabe --- /dev/null +++ b/example/GUI/STemWin/Software/JPEG2MovieScripts/480x272.bat @@ -0,0 +1,21 @@ +@ECHO OFF +GOTO START + +****************************************************************************** +* +* File: x.bat +* +* Purpose: This file simply calls MakeMovie.bat with its own file name +* as parameter %2 which defines the resolution used by FFmpeg +* to create the JPEG files. +* By copying and renaming this file further resolutions can +* be simply achieved. +* +* Note: The file name of this file needs to match the size +* specification parameter '-s' for FFmpeg.exe. +* +****************************************************************************** + +:START + +@%~dp0MakeMovie.bat %1 %~n0 \ No newline at end of file diff --git a/example/GUI/STemWin/Software/JPEG2MovieScripts/80x45.bat b/example/GUI/STemWin/Software/JPEG2MovieScripts/80x45.bat new file mode 100755 index 0000000000..22e81ceabe --- /dev/null +++ b/example/GUI/STemWin/Software/JPEG2MovieScripts/80x45.bat @@ -0,0 +1,21 @@ +@ECHO OFF +GOTO START + +****************************************************************************** +* +* File: x.bat +* +* Purpose: This file simply calls MakeMovie.bat with its own file name +* as parameter %2 which defines the resolution used by FFmpeg +* to create the JPEG files. +* By copying and renaming this file further resolutions can +* be simply achieved. +* +* Note: The file name of this file needs to match the size +* specification parameter '-s' for FFmpeg.exe. +* +****************************************************************************** + +:START + +@%~dp0MakeMovie.bat %1 %~n0 \ No newline at end of file diff --git a/example/GUI/STemWin/Software/JPEG2MovieScripts/80x60.bat b/example/GUI/STemWin/Software/JPEG2MovieScripts/80x60.bat new file mode 100755 index 0000000000..22e81ceabe --- /dev/null +++ b/example/GUI/STemWin/Software/JPEG2MovieScripts/80x60.bat @@ -0,0 +1,21 @@ +@ECHO OFF +GOTO START + +****************************************************************************** +* +* File: x.bat +* +* Purpose: This file simply calls MakeMovie.bat with its own file name +* as parameter %2 which defines the resolution used by FFmpeg +* to create the JPEG files. +* By copying and renaming this file further resolutions can +* be simply achieved. +* +* Note: The file name of this file needs to match the size +* specification parameter '-s' for FFmpeg.exe. +* +****************************************************************************** + +:START + +@%~dp0MakeMovie.bat %1 %~n0 \ No newline at end of file diff --git a/example/GUI/STemWin/Software/JPEG2MovieScripts/MakeMovie.bat b/example/GUI/STemWin/Software/JPEG2MovieScripts/MakeMovie.bat new file mode 100755 index 0000000000..084eb2512e --- /dev/null +++ b/example/GUI/STemWin/Software/JPEG2MovieScripts/MakeMovie.bat @@ -0,0 +1,83 @@ +@ECHO OFF +GOTO START + +****************************************************************************** +* +* File: MakeMovie.bat +* +* Parameters: 4 (3 optional) +* %1: Movie file to be converted +* %2: Size +* %3: Quality +* %4: Framerate +* +* Requirement: The free available tool FFmpeg is required for the conversion +* operation. FFmpeg is available under the following link: +* +* http://www.ffmpeg.org/ +* +* Please note that Prep.bat needs to be adapted before using +* MakeMovie.bat. +* +* This file (MakeMovie.bat) normally do not need to be modified. +* +* Purpose: This batch file converts a video file to an (E)mWin (M)ovie (F)ile. +* It first uses FFmpeg for converting the given movie into single +* JPEG files. After that the emWin tool JPEG2Movie is used to +* convert these images into an emWin movie file. +* +* For details about all supported file types and the parameters +* resolution, quality and frame rate please refer to the FFmpeg +* documentation. +* +* Output: A copy of the converted file will be copied into the folder of +* the source file. The file name will be the same as the source file +* with a size postfix and the extension '.emf' (emWin movie file). +* +****************************************************************************** + +:START + +CALL %~dp0PREP.BAT + +IF "%2" == "" GOTO CONT2 +SET SIZE=%2 +GOTO NEXT2 +:CONT2 +SET SIZE=%DEFAULT_SIZE% +:NEXT2 + +IF "%3" == "" GOTO CONT3 +SET QUALITY=%3 +GOTO NEXT3 +:CONT3 +SET QUALITY=%DEFAULT_QUALITY% +:NEXT3 + +IF "%4" == "" GOTO CONT4 +SET FRAMERATE=%4 +GOTO NEXT4 +:CONT4 +SET FRAMERATE=%DEFAULT_FRAMERATE% +:NEXT4 + +DEL /Q "%OUTPUT%*.*" + +"%FFMPEG%" -y -i %1 -r %FRAMERATE% -q %QUALITY% -s %SIZE% -f image2 -pix_fmt yuvj420p "%OUTPUT%img-%%05d.jpeg" + +"%JPEG2MOVIE%" "%OUTPUT%" +IF ERRORLEVEL 1 GOTO ERROR +GOTO NOERROR +:ERROR +ECHO Error using JPEG2Movie! +PAUSE +:NOERROR + +COPY /B %OUTPUT%*.emf %~dp1%~n1_%SIZE%.emf + +SET SIZE= +SET QUALITY= +SET FRAMERATE= +SET FOLDER= +SET FFMPEG= +SET JPEG2MOVIE= \ No newline at end of file diff --git a/example/GUI/STemWin/Software/JPEG2MovieScripts/Prep.bat b/example/GUI/STemWin/Software/JPEG2MovieScripts/Prep.bat new file mode 100755 index 0000000000..f4c046c867 --- /dev/null +++ b/example/GUI/STemWin/Software/JPEG2MovieScripts/Prep.bat @@ -0,0 +1,50 @@ +@ECHO OFF +GOTO START + +****************************************************************************** +* +* File: Prep.bat +* +* Parameters: none +* +* Purpose: This batch file is called by MakeMovie.bat and sets the default +* values for working folder, FFmpeg and JPEG2MOVIE path. It needs +* to be adapted before MakeMovie.bat can be used. +* +****************************************************************************** + +:START + +REM ************************************************************************** +REM +REM Configuration: Default values for size, quality and framerate +REM +REM ************************************************************************** + +SET DEFAULT_SIZE=320x240 +SET DEFAULT_QUALITY=5 +SET DEFAULT_FRAMERATE=25 + +REM ************************************************************************** +REM +REM Configuration: Working folder +REM +REM ************************************************************************** + +SET OUTPUT=C:\Movie\Output\ + +REM ************************************************************************** +REM +REM Configuration: FFmpeg +REM +REM ************************************************************************** + +SET FFMPEG=C:\FFmpeg\ffmpeg.exe + +REM ************************************************************************** +REM +REM Configuration: JPEG2Movie +REM +REM ************************************************************************** + +SET JPEG2MOVIE=C:\Movie\JPEG2Movie.exe diff --git a/example/GUI/STemWin/Software/U2C.exe b/example/GUI/STemWin/Software/U2C.exe new file mode 100755 index 0000000000..273b2ad603 Binary files /dev/null and b/example/GUI/STemWin/Software/U2C.exe differ diff --git a/example/GUI/STemWin/Software/emVNC.exe b/example/GUI/STemWin/Software/emVNC.exe new file mode 100755 index 0000000000..921ab7e0ee Binary files /dev/null and b/example/GUI/STemWin/Software/emVNC.exe differ diff --git a/example/GUI/STemWin/Software/emWinPlayer.exe b/example/GUI/STemWin/Software/emWinPlayer.exe new file mode 100755 index 0000000000..f7f5d109da Binary files /dev/null and b/example/GUI/STemWin/Software/emWinPlayer.exe differ diff --git a/example/GUI/STemWin/inc/BUTTON.h b/example/GUI/STemWin/inc/BUTTON.h new file mode 100755 index 0000000000..05ba24a2fd --- /dev/null +++ b/example/GUI/STemWin/inc/BUTTON.h @@ -0,0 +1,231 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : BUTTON.h +Purpose : BUTTON public header file (API) +--------------------END-OF-HEADER------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef BUTTON_H +#define BUTTON_H + +#include "WM.h" +#include "DIALOG_Intern.h" /* Req. for Create indirect data structure */ +#include "WIDGET.h" + +#if GUI_WINSUPPORT + +#if defined(__cplusplus) + extern "C" { /* Make sure we have C-declarations in C++ programs */ +#endif + +/********************************************************************* +* +* Create flags +*/ +/* For compatibility only ! */ +#define BUTTON_CF_HIDE WM_CF_HIDE +#define BUTTON_CF_SHOW WM_CF_SHOW +#define BUTTON_CF_MEMDEV WM_CF_MEMDEV + +/********************************************************************* +* +* Color indices +*/ +#define BUTTON_CI_UNPRESSED 0 +#define BUTTON_CI_PRESSED 1 +#define BUTTON_CI_DISABLED 2 + +/********************************************************************* +* +* Bitmap indices +*/ +#define BUTTON_BI_UNPRESSED 0 +#define BUTTON_BI_PRESSED 1 +#define BUTTON_BI_DISABLED 2 + +/********************************************************************* +* +* States +*/ +#define BUTTON_STATE_FOCUS WIDGET_STATE_FOCUS +#define BUTTON_STATE_PRESSED WIDGET_STATE_USER0 + +/********************************************************************* +* +* Skinning property indices +*/ +#define BUTTON_SKINFLEX_PI_PRESSED 0 +#define BUTTON_SKINFLEX_PI_FOCUSED 1 +#define BUTTON_SKINFLEX_PI_ENABLED 2 +#define BUTTON_SKINFLEX_PI_DISABLED 3 + +#define BUTTON_SKINFLEX_PI_FOCUSSED BUTTON_SKINFLEX_PI_FOCUSED + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ +typedef WM_HMEM BUTTON_Handle; + +typedef struct { + GUI_COLOR aColorFrame[3]; + GUI_COLOR aColorUpper[2]; + GUI_COLOR aColorLower[2]; + int Radius; +} BUTTON_SKINFLEX_PROPS; + +/********************************************************************* +* +* Create function(s) + + Note: the parameters to a create function may vary. + Some widgets may have multiple create functions +*/ + +BUTTON_Handle BUTTON_Create (int x0, int y0, int xSize, int ySize, int ID, int Flags); +BUTTON_Handle BUTTON_CreateAsChild (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int Id, int Flags); +BUTTON_Handle BUTTON_CreateEx (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int WinFlags, int ExFlags, int Id); +BUTTON_Handle BUTTON_CreateUser (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int WinFlags, int ExFlags, int Id, int NumExtraBytes); +BUTTON_Handle BUTTON_CreateIndirect(const GUI_WIDGET_CREATE_INFO * pCreateInfo, WM_HWIN hWinParent, int x0, int y0, WM_CALLBACK * cb); + +/********************************************************************* +* +* Managing default values +* +********************************************************************** +*/ +GUI_COLOR BUTTON_GetDefaultBkColor (unsigned Index); +const GUI_FONT * BUTTON_GetDefaultFont (void); +int BUTTON_GetDefaultTextAlign (void); +GUI_COLOR BUTTON_GetDefaultTextColor (unsigned Index); +void BUTTON_SetDefaultBkColor (GUI_COLOR Color, unsigned Index); +GUI_COLOR BUTTON_SetDefaultFocusColor(GUI_COLOR Color); +void BUTTON_SetDefaultFont (const GUI_FONT * pFont); +void BUTTON_SetDefaultTextAlign (int Align); +void BUTTON_SetDefaultTextColor (GUI_COLOR Color, unsigned Index); + +/********************************************************************* +* +* The callback ... +* +* Do not call it directly ! It is only to be used from within an +* overwritten callback. +*/ +void BUTTON_Callback(WM_MESSAGE *pMsg); + +/********************************************************************* +* +* Member functions +* +********************************************************************** +*/ +GUI_COLOR BUTTON_GetBkColor (BUTTON_Handle hObj, unsigned int Index); +const GUI_BITMAP * BUTTON_GetBitmap(BUTTON_Handle hObj,unsigned int Index); +const GUI_FONT * BUTTON_GetFont (BUTTON_Handle hObj); +GUI_COLOR BUTTON_GetFrameColor (BUTTON_Handle hObj); +WIDGET * BUTTON_GetpWidget (BUTTON_Handle hObj); +void BUTTON_GetText (BUTTON_Handle hObj, char * pBuffer, int MaxLen); +GUI_COLOR BUTTON_GetTextColor (BUTTON_Handle hObj, unsigned int Index); +int BUTTON_GetTextAlign (BUTTON_Handle hObj); +int BUTTON_GetUserData (BUTTON_Handle hObj, void * pDest, int NumBytes); +unsigned BUTTON_IsPressed (BUTTON_Handle hObj); +void BUTTON_SetBitmap (BUTTON_Handle hObj, unsigned int Index, const GUI_BITMAP * pBitmap); +void BUTTON_SetBitmapEx (BUTTON_Handle hObj, unsigned int Index, const GUI_BITMAP * pBitmap, int x, int y); +void BUTTON_SetBkColor (BUTTON_Handle hObj, unsigned int Index, GUI_COLOR Color); +void BUTTON_SetBMP (BUTTON_Handle hObj, unsigned int Index, const void * pBitmap); +void BUTTON_SetBMPEx (BUTTON_Handle hObj, unsigned int Index, const void * pBitmap, int x, int y); +void BUTTON_SetFont (BUTTON_Handle hObj, const GUI_FONT * pfont); +void BUTTON_SetFrameColor (BUTTON_Handle hObj, GUI_COLOR Color); +void BUTTON_SetState (BUTTON_Handle hObj, int State); /* Not to be doc. */ +void BUTTON_SetPressed (BUTTON_Handle hObj, int State); +GUI_COLOR BUTTON_SetFocusColor (BUTTON_Handle hObj, GUI_COLOR Color); +void BUTTON_SetStreamedBitmap (BUTTON_Handle hObj, unsigned int Index, const GUI_BITMAP_STREAM * pBitmap); +void BUTTON_SetStreamedBitmapEx(BUTTON_Handle hObj, unsigned int Index, const GUI_BITMAP_STREAM * pBitmap, int x, int y); +int BUTTON_SetText (BUTTON_Handle hObj, const char* s); +void BUTTON_SetTextAlign (BUTTON_Handle hObj, int Align); +void BUTTON_SetTextColor (BUTTON_Handle hObj, unsigned int Index, GUI_COLOR Color); +void BUTTON_SetTextOffset (BUTTON_Handle hObj, int xPos, int yPos); +void BUTTON_SetSelfDrawEx (BUTTON_Handle hObj, unsigned int Index, GUI_DRAW_SELF_CB * pDraw, int x, int y); /* Not to be doc. */ +void BUTTON_SetSelfDraw (BUTTON_Handle hObj, unsigned int Index, GUI_DRAW_SELF_CB * pDraw); /* Not to be doc. */ +void BUTTON_SetReactOnLevel (void); +void BUTTON_SetReactOnTouch (void); +int BUTTON_SetUserData (BUTTON_Handle hObj, const void * pSrc, int NumBytes); + +#define BUTTON_SetFocussable BUTTON_SetFocusable +#define BUTTON_SetFocusable WIDGET_SetFocusable + +/********************************************************************* +* +* Member functions: Skinning +* +********************************************************************** +*/ +void BUTTON_GetSkinFlexProps (BUTTON_SKINFLEX_PROPS * pProps, int Index); +void BUTTON_SetSkinClassic (BUTTON_Handle hObj); +void BUTTON_SetSkin (BUTTON_Handle hObj, WIDGET_DRAW_ITEM_FUNC * pfDrawSkin); +int BUTTON_DrawSkinFlex (const WIDGET_ITEM_DRAW_INFO * pDrawItemInfo); +void BUTTON_SetSkinFlexProps (const BUTTON_SKINFLEX_PROPS * pProps, int Index); +void BUTTON_SetDefaultSkinClassic(void); +WIDGET_DRAW_ITEM_FUNC * BUTTON_SetDefaultSkin(WIDGET_DRAW_ITEM_FUNC * pfDrawSkin); + +#define BUTTON_SKIN_FLEX BUTTON_DrawSkinFlex + +#if defined(__cplusplus) + } +#endif + +#endif // GUI_WINSUPPORT +#endif // BUTTON_H + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/BUTTON_Private.h b/example/GUI/STemWin/inc/BUTTON_Private.h new file mode 100755 index 0000000000..422955d9d6 --- /dev/null +++ b/example/GUI/STemWin/inc/BUTTON_Private.h @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : BUTTON_Private.h +Purpose : BUTTON private header file +--------------------END-OF-HEADER------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef BUTTON_PRIVATE_H +#define BUTTON_PRIVATE_H + +#include "WM.h" +#include "BUTTON.h" + +#if GUI_WINSUPPORT + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ +#ifndef BUTTON_3D_MOVE_X + #define BUTTON_3D_MOVE_X 1 +#endif +#ifndef BUTTON_3D_MOVE_Y + #define BUTTON_3D_MOVE_Y 1 +#endif + +/********************************************************************* +* +* Object definition +* +********************************************************************** +*/ +typedef struct { + WIDGET_DRAW_ITEM_FUNC * pfDrawSkin; +} BUTTON_SKIN_PRIVATE; + +typedef struct { + GUI_COLOR aBkColor[3]; + GUI_COLOR aTextColor[3]; + GUI_COLOR FocusColor; + GUI_COLOR FrameColor; + const GUI_FONT * pFont; + BUTTON_SKIN_PRIVATE SkinPrivate; + I16 Align; + I16 xPosText, yPosText; +} BUTTON_PROPS; + +typedef struct { + WIDGET Widget; + BUTTON_PROPS Props; + WIDGET_SKIN const * pWidgetSkin; + WM_HMEM hpText; + WM_HMEM ahDrawObj[3]; +} BUTTON_Obj; + +/********************************************************************* +* +* Macros for internal use +* +********************************************************************** +*/ +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL + #define BUTTON_INIT_ID(p) (p->Widget.DebugId = BUTTON_ID) +#else + #define BUTTON_INIT_ID(p) +#endif + +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL + BUTTON_Obj * BUTTON_LockH(BUTTON_Handle h); + #define BUTTON_LOCK_H(h) BUTTON_LockH(h) +#else + #define BUTTON_LOCK_H(h) (BUTTON_Obj *)GUI_LOCK_H(h) +#endif + +/********************************************************************* +* +* Public data (internal defaults) +* +********************************************************************** +*/ +extern BUTTON_PROPS BUTTON__DefaultProps; + +extern const WIDGET_SKIN BUTTON__SkinClassic; +extern WIDGET_SKIN BUTTON__Skin; + +extern WIDGET_SKIN const * BUTTON__pSkinDefault; + +/********************************************************************* +* +* Private functions +* +********************************************************************** +*/ +void BUTTON__SetDrawObj(BUTTON_Handle hObj, int Index, GUI_DRAW_HANDLE hDrawObj); + + +#endif /* GUI_WINSUPPORT */ +#endif /* BUTTON_H */ + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/CALENDAR.h b/example/GUI/STemWin/inc/CALENDAR.h new file mode 100755 index 0000000000..13609779bb --- /dev/null +++ b/example/GUI/STemWin/inc/CALENDAR.h @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : CALENDAR.h +Purpose : Message box interface +--------------------END-OF-HEADER------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef CALENDAR_H +#define CALENDAR_H + +#include "WM.h" + +#if GUI_WINSUPPORT + +#if defined(__cplusplus) + extern "C" { /* Make sure we have C-declarations in C++ programs */ +#endif + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ +#define CALENDAR_CI_WEEKEND 0 +#define CALENDAR_CI_WEEKDAY 1 +#define CALENDAR_CI_SEL 2 + +#define CALENDAR_CI_HEADER 3 +#define CALENDAR_CI_MONTH 4 +#define CALENDAR_CI_LABEL 5 +#define CALENDAR_CI_FRAME 6 + +#define CALENDAR_FI_CONTENT 0 +#define CALENDAR_FI_HEADER 1 + +#define CALENDAR_SI_HEADER 0 +#define CALENDAR_SI_CELL_X 1 +#define CALENDAR_SI_CELL_Y 2 + +/********************************************************************* +* +* Notification codes +* +* The following is the list of notification codes specific to this widget, +* Send with the WM_NOTIFY_PARENT message +*/ +#define CALENDAR_NOTIFICATION_MONTH_CLICKED (WM_NOTIFICATION_WIDGET + 0) +#define CALENDAR_NOTIFICATION_MONTH_RELEASED (WM_NOTIFICATION_WIDGET + 1) + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ +/********************************************************************* +* +* CALENDAR_DATE +*/ +typedef struct { + int Year; + int Month; + int Day; +} CALENDAR_DATE; + +/********************************************************************* +* +* CALENDAR_SKINFLEX_PROPS +*/ +typedef struct { + GUI_COLOR aColorFrame[3]; // Frame colors of buttons + GUI_COLOR aColorUpper[2]; // Upper gradient colors of buttons + GUI_COLOR aColorLower[2]; // Lower gradient colors of buttons + GUI_COLOR ColorArrow; // Arrow colors +} CALENDAR_SKINFLEX_PROPS; + +/********************************************************************* +* +* Public code +* +********************************************************************** +*/ +WM_HWIN CALENDAR_Create (WM_HWIN hParent, int xPos, int yPos, unsigned Year, unsigned Month, unsigned Day, unsigned FirstDayOfWeek, int Id, int Flags); +void CALENDAR_GetDate (WM_HWIN hWin, CALENDAR_DATE * pDate); +void CALENDAR_GetSel (WM_HWIN hWin, CALENDAR_DATE * pDate); +void CALENDAR_SetDate (WM_HWIN hWin, CALENDAR_DATE * pDate); +void CALENDAR_SetSel (WM_HWIN hWin, CALENDAR_DATE * pDate); +void CALENDAR_ShowDate (WM_HWIN hWin, CALENDAR_DATE * pDate); + +/********************************************************************* +* +* Default related +*/ +void CALENDAR_SetDefaultBkColor(unsigned Index, GUI_COLOR Color); +void CALENDAR_SetDefaultColor (unsigned Index, GUI_COLOR Color); +void CALENDAR_SetDefaultDays (const char ** apDays); +void CALENDAR_SetDefaultFont (unsigned Index, const GUI_FONT * pFont); +void CALENDAR_SetDefaultMonths (const char ** apMonths); +void CALENDAR_SetDefaultSize (unsigned Index, unsigned Size); + +/********************************************************************* +* +* Skinning related +*/ +void CALENDAR_GetSkinFlexProps (CALENDAR_SKINFLEX_PROPS * pProps, int Index); +void CALENDAR_SetSkinFlexProps (const CALENDAR_SKINFLEX_PROPS * pProps, int Index); + +/********************************************************************* +* +* The callback ... +* +* Do not call it directly ! It is only to be used from within an +* overwritten callback. +*/ +void CALENDAR_Callback(WM_MESSAGE * pMsg); + +#if defined(__cplusplus) + } +#endif + +#endif // GUI_WINSUPPORT +#endif // CALENDAR_H + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/CHECKBOX.h b/example/GUI/STemWin/inc/CHECKBOX.h new file mode 100755 index 0000000000..d34e0d7346 --- /dev/null +++ b/example/GUI/STemWin/inc/CHECKBOX.h @@ -0,0 +1,221 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : CHECKBOX.h +Purpose : CHECKBOX include +--------------------END-OF-HEADER------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef CHECKBOX_H +#define CHECKBOX_H + +#include "WM.h" +#include "DIALOG_Intern.h" /* Req. for Create indirect data structure */ +#include "WIDGET.h" + +#if GUI_WINSUPPORT + +#if defined(__cplusplus) + extern "C" { /* Make sure we have C-declarations in C++ programs */ +#endif + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ + +/********************************************************************* +* +* Color indices +*/ +#define CHECKBOX_CI_DISABLED 0 +#define CHECKBOX_CI_ENABLED 1 + +/********************************************************************* +* +* Bitmap indices +*/ +#define CHECKBOX_BI_INACTIV_UNCHECKED 0 +#define CHECKBOX_BI_ACTIV_UNCHECKED 1 +#define CHECKBOX_BI_INACTIV_CHECKED 2 +#define CHECKBOX_BI_ACTIV_CHECKED 3 +#define CHECKBOX_BI_INACTIV_3STATE 4 +#define CHECKBOX_BI_ACTIV_3STATE 5 + +/********************************************************************* +* +* Skinning property indices +*/ +#define CHECKBOX_SKINFLEX_PI_ENABLED 0 +#define CHECKBOX_SKINFLEX_PI_DISABLED 1 + +/********************************************************************* +* +* Public Types +* +********************************************************************** +*/ +typedef WM_HMEM CHECKBOX_Handle; + +typedef struct { + GUI_COLOR aColorFrame[3]; + GUI_COLOR aColorInner[2]; + GUI_COLOR ColorCheck; + int ButtonSize; +} CHECKBOX_SKINFLEX_PROPS; + +/********************************************************************* +* +* Create functions +* +********************************************************************** +*/ +CHECKBOX_Handle CHECKBOX_Create (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int Id, int Flags); +CHECKBOX_Handle CHECKBOX_CreateEx (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int WinFlags, int ExFlags, int Id); +CHECKBOX_Handle CHECKBOX_CreateUser (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int WinFlags, int ExFlags, int Id, int NumExtraBytes); +CHECKBOX_Handle CHECKBOX_CreateIndirect(const GUI_WIDGET_CREATE_INFO * pCreateInfo, WM_HWIN hWinParent, int x0, int y0, WM_CALLBACK * cb); + +/********************************************************************* +* +* The callback ... +* +* Do not call it directly ! It is only to be used from within an +* overwritten callback. +*/ +void CHECKBOX_Callback(WM_MESSAGE * pMsg); + +/********************************************************************* +* +* Managing default values +* +********************************************************************** +*/ + +int CHECKBOX_GetDefaultAlign (void); +GUI_COLOR CHECKBOX_GetDefaultBkColor (void); +const GUI_FONT * CHECKBOX_GetDefaultFont (void); +int CHECKBOX_GetDefaultSpacing (void); +int CHECKBOX_GetDefaultTextAlign (void); +GUI_COLOR CHECKBOX_GetDefaultTextColor (void); +int CHECKBOX_GetUserData (CHECKBOX_Handle hObj, void * pDest, int NumBytes); +void CHECKBOX_SetDefaultAlign (int Align); +void CHECKBOX_SetDefaultBkColor (GUI_COLOR Color); +GUI_COLOR CHECKBOX_SetDefaultFocusColor(GUI_COLOR Color); +void CHECKBOX_SetDefaultFont (const GUI_FONT * pFont); +void CHECKBOX_SetDefaultImage (const GUI_BITMAP * pBitmap, unsigned int Index); +void CHECKBOX_SetDefaultSpacing (int Spacing); +void CHECKBOX_SetDefaultTextAlign (int Align); +void CHECKBOX_SetDefaultTextColor (GUI_COLOR Color); + +/********************************************************************* +* +* Member functions +* +********************************************************************** +*/ + +int CHECKBOX_GetState (CHECKBOX_Handle hObj); +int CHECKBOX_GetText (CHECKBOX_Handle hObj, char * pBuffer, int MaxLen); +int CHECKBOX_IsChecked (CHECKBOX_Handle hObj); +void CHECKBOX_SetBkColor (CHECKBOX_Handle hObj, GUI_COLOR Color); +GUI_COLOR CHECKBOX_SetBoxBkColor(CHECKBOX_Handle hObj, GUI_COLOR Color, int Index); +GUI_COLOR CHECKBOX_SetFocusColor(CHECKBOX_Handle hObj, GUI_COLOR Color); +void CHECKBOX_SetFont (CHECKBOX_Handle hObj, const GUI_FONT * pFont); +void CHECKBOX_SetImage (CHECKBOX_Handle hObj, const GUI_BITMAP * pBitmap, unsigned int Index); +void CHECKBOX_SetNumStates (CHECKBOX_Handle hObj, unsigned NumStates); +void CHECKBOX_SetSpacing (CHECKBOX_Handle hObj, unsigned Spacing); +void CHECKBOX_SetState (CHECKBOX_Handle hObj, unsigned State); +void CHECKBOX_SetText (CHECKBOX_Handle hObj, const char * pText); +void CHECKBOX_SetTextAlign (CHECKBOX_Handle hObj, int Align); +void CHECKBOX_SetTextColor (CHECKBOX_Handle hObj, GUI_COLOR Color); +int CHECKBOX_SetUserData (CHECKBOX_Handle hObj, const void * pSrc, int NumBytes); + +/********************************************************************* +* +* Member functions: Skinning +* +********************************************************************** +*/ +void CHECKBOX_GetSkinFlexProps (CHECKBOX_SKINFLEX_PROPS * pProps, int Index); +void CHECKBOX_SetSkinClassic (CHECKBOX_Handle hObj); +void CHECKBOX_SetSkin (CHECKBOX_Handle hObj, WIDGET_DRAW_ITEM_FUNC * pfDrawSkin); +int CHECKBOX_DrawSkinFlex (const WIDGET_ITEM_DRAW_INFO * pDrawItemInfo); +void CHECKBOX_SetSkinFlexProps (const CHECKBOX_SKINFLEX_PROPS * pProps, int Index); +void CHECKBOX_SetDefaultSkinClassic (void); +int CHECKBOX_GetSkinFlexButtonSize (CHECKBOX_Handle hObj); +void CHECKBOX_SetSkinFlexButtonSize (CHECKBOX_Handle hObj, int ButtonSize); +WIDGET_DRAW_ITEM_FUNC * CHECKBOX_SetDefaultSkin(WIDGET_DRAW_ITEM_FUNC * pfDrawSkin); + +#define CHECKBOX_SKIN_FLEX CHECKBOX_DrawSkinFlex + +/********************************************************************* +* +* Macros for compatibility +* +********************************************************************** +*/ + +#define CHECKBOX_Check(hObj) CHECKBOX_SetState(hObj, 1) +#define CHECKBOX_Uncheck(hObj) CHECKBOX_SetState(hObj, 0) + +#define CHECKBOX_BI_INACTIV CHECKBOX_BI_INACTIV_CHECKED +#define CHECKBOX_BI_ACTIV CHECKBOX_BI_ACTIV_CHECKED + +#if defined(__cplusplus) + } +#endif + +#endif // GUI_WINSUPPORT +#endif // CHECKBOX_H + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/CHECKBOX_Private.h b/example/GUI/STemWin/inc/CHECKBOX_Private.h new file mode 100755 index 0000000000..a056b9bece --- /dev/null +++ b/example/GUI/STemWin/inc/CHECKBOX_Private.h @@ -0,0 +1,176 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : CHECKBOX_Private.h +Purpose : CHECKBOX private header file +--------------------END-OF-HEADER------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef CHECKBOX_PRIVATE_H +#define CHECKBOX_PRIVATE_H + +#include "WM.h" +#include "WIDGET.h" +#include "CHECKBOX.h" + +#if GUI_WINSUPPORT + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ +#ifndef CHECKBOX_BKCOLOR0_DEFAULT + #define CHECKBOX_BKCOLOR0_DEFAULT 0x808080 /* Inactive color */ +#endif + +#ifndef CHECKBOX_BKCOLOR1_DEFAULT + #define CHECKBOX_BKCOLOR1_DEFAULT GUI_WHITE /* Active color */ +#endif + +#ifndef CHECKBOX_FGCOLOR0_DEFAULT + #define CHECKBOX_FGCOLOR0_DEFAULT 0x101010 +#endif + +#ifndef CHECKBOX_FGCOLOR1_DEFAULT + #define CHECKBOX_FGCOLOR1_DEFAULT GUI_BLACK +#endif + +#ifndef CHECKBOX_DEFAULT_SIZE + #define CHECKBOX_DEFAULT_SIZE 15 +#endif + +/********************************************************************* +* +* Object definition +* +********************************************************************** +*/ +typedef struct { + unsigned (* pfGetButtonSize)(void); + WIDGET_DRAW_ITEM_FUNC * pfDrawSkin; +} CHECKBOX_SKIN_PRIVATE; + +typedef struct { + const GUI_FONT * pFont; + GUI_COLOR aBkColorBox[2]; /* Colors used to draw the box background */ + GUI_COLOR BkColor; /* Widget background color */ + GUI_COLOR TextColor; + GUI_COLOR FocusColor; + CHECKBOX_SKIN_PRIVATE SkinPrivate; + I16 Align; + U8 Spacing; + const GUI_BITMAP * apBm[6]; +} CHECKBOX_PROPS; + +typedef struct { + WIDGET Widget; + CHECKBOX_PROPS Props; + WIDGET_SKIN const * pWidgetSkin; + U8 NumStates; + U8 CurrentState; + WM_HMEM hpText; + U32 ButtonSize; +} CHECKBOX_Obj; + +/********************************************************************* +* +* Macros for internal use +* +********************************************************************** +*/ +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL + #define CHECKBOX_INIT_ID(p) (p->Widget.DebugId = CHECKBOX_ID) +#else + #define CHECKBOX_INIT_ID(p) +#endif + +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL + CHECKBOX_Obj * CHECKBOX_LockH(CHECKBOX_Handle h); + #define CHECKBOX_LOCK_H(h) CHECKBOX_LockH(h) +#else + #define CHECKBOX_LOCK_H(h) (CHECKBOX_Obj *)GUI_LOCK_H(h) +#endif + +/********************************************************************* +* +* Private functions +* +********************************************************************** +*/ +unsigned CHECKBOX__GetButtonSize(void); + +/********************************************************************* +* +* Public data (internal defaults) +* +********************************************************************** +*/ +extern CHECKBOX_PROPS CHECKBOX__DefaultProps; + +extern const WIDGET_SKIN CHECKBOX__SkinClassic; +extern WIDGET_SKIN CHECKBOX__Skin; + +extern WIDGET_SKIN const * CHECKBOX__pSkinDefault; + +/********************************************************************* +* +* Extern data +* +********************************************************************** +*/ +extern const GUI_BITMAP CHECKBOX__abmCheck[2]; + +#endif /* GUI_WINSUPPORT */ +#endif /* CHECKBOX_PRIVATE_H */ + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/CHOOSECOLOR.h b/example/GUI/STemWin/inc/CHOOSECOLOR.h new file mode 100755 index 0000000000..7953e2d835 --- /dev/null +++ b/example/GUI/STemWin/inc/CHOOSECOLOR.h @@ -0,0 +1,154 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : CHOOSECOLOR.h +Purpose : Message box interface +--------------------END-OF-HEADER------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef CHOOSECOLOR_H +#define CHOOSECOLOR_H + +#include "WM.h" + +#if GUI_WINSUPPORT + +#if defined(__cplusplus) +extern "C" { /* Make sure we have C-declarations in C++ programs */ +#endif + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ +#define CHOOSECOLOR_CF_MOVEABLE FRAMEWIN_CF_MOVEABLE + +#define CHOOSECOLOR_CI_FRAME 0 +#define CHOOSECOLOR_CI_FOCUS 1 + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ +/********************************************************************* +* +* CHOOSECOLOR_PROPS +*/ +typedef struct { + unsigned aBorder[2]; + unsigned aSpace[2]; + unsigned aButtonSize[2]; + GUI_COLOR aColor[2]; +} CHOOSECOLOR_PROPS; + +/********************************************************************* +* +* CHOOSECOLOR_CONTEXT +*/ +typedef struct { + U32 LastColor; + const GUI_COLOR * pColor; + unsigned NumColors; + unsigned NumColorsPerLine; + int SelOld; + int Sel; + WM_HWIN hParent; + CHOOSECOLOR_PROPS Props; +} CHOOSECOLOR_CONTEXT; + +/********************************************************************* +* +* Public code +* +********************************************************************** +*/ +WM_HWIN CHOOSECOLOR_Create(WM_HWIN hParent, + int xPos, + int yPos, + int xSize, + int ySize, + const GUI_COLOR * pColor, + unsigned NumColors, + unsigned NumColorsPerLine, + int Sel, + const char * sCaption, + int Flags); + +int CHOOSECOLOR_GetSel(WM_HWIN hObj); +void CHOOSECOLOR_SetSel(WM_HWIN hObj, int Sel); + +void CHOOSECOLOR_SetDefaultColor (unsigned Index, GUI_COLOR Color); +void CHOOSECOLOR_SetDefaultSpace (unsigned Index, unsigned Space); +void CHOOSECOLOR_SetDefaultBorder (unsigned Index, unsigned Border); +void CHOOSECOLOR_SetDefaultButtonSize(unsigned Index, unsigned ButtonSize); + +/********************************************************************* +* +* The callback ... +* +* Do not call it directly ! It is only to be used from within an +* overwritten callback. +*/ +void CHOOSECOLOR_Callback(WM_MESSAGE * pMsg); + +#if defined(__cplusplus) + } +#endif + +#endif /* GUI_WINSUPPORT */ + +#endif /* CHOOSECOLOR_H */ + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/CHOOSEFILE.h b/example/GUI/STemWin/inc/CHOOSEFILE.h new file mode 100755 index 0000000000..a780b40ab7 --- /dev/null +++ b/example/GUI/STemWin/inc/CHOOSEFILE.h @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : CHOOSEFILE.h +Purpose : File dialog interface +--------------------END-OF-HEADER------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef CHOOSEFILE_H +#define CHOOSEFILE_H + +#include "WM.h" + +#if GUI_WINSUPPORT + +#if defined(__cplusplus) +extern "C" { /* Make sure we have C-declarations in C++ programs */ +#endif + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ +#define CHOOSEFILE_FINDFIRST 0 +#define CHOOSEFILE_FINDNEXT 1 + +#define CHOOSEFILE_FLAG_DIRECTORY (1 << 0) + +#ifndef CHOOSEFILE_MAXLEN + #define CHOOSEFILE_MAXLEN 256 +#endif + +#define CHOOSEFILE_BI_CANCEL 0 +#define CHOOSEFILE_BI_OK 1 +#define CHOOSEFILE_BI_UP 2 + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ +/********************************************************************* +* +* CHOOSEFILE_INFO +*/ +typedef struct CHOOSEFILE_INFO CHOOSEFILE_INFO; + +struct CHOOSEFILE_INFO { + int Cmd; // Command for GetData() function + int Id; // Id of pressed button (for internal use only) + const char * pMask; // Mask to be used for searching files + char * pName; // (for internal use only) + char * pExt; // (for internal use only) + char * pAttrib; // (for internal use only) + WM_TOOLTIP_HANDLE hToolTip; // (for internal use only) + U32 SizeL; // FileSize low word + U32 SizeH; // FileSize high word + U32 Flags; // File flags + char pRoot[CHOOSEFILE_MAXLEN]; // Buffer used internally and for passing result + int (* pfGetData)(CHOOSEFILE_INFO * pInfo); // Pointer to GetData() function +}; + +/********************************************************************* +* +* Functions +* +********************************************************************** +*/ +WM_HWIN CHOOSEFILE_Create(WM_HWIN hParent, // Parent window + int xPos, // xPosition in window coordinates + int yPos, // yPosition in window coordinates + int xSize, // xSize in pixels + int ySize, // ySize in pixels + const char * apRoot[], // Pointers to root strings + int NumRoot, // Number of roots + int SelRoot, // Root to be selected at first + const char * sCaption, // Shown in title bar + int Flags, // Flags for FRAMEWINDOW + CHOOSEFILE_INFO * pInfo // Pointer to CHOOSEFILE_INFO structure + ); + +void CHOOSEFILE_Callback (WM_MESSAGE * pMsg); +void CHOOSEFILE_EnableToolTips (void); +void CHOOSEFILE_SetButtonText (WM_HWIN hWin, unsigned ButtonIndex, const char * pText); +void CHOOSEFILE_SetDefaultButtonText(unsigned ButtonIndex, const char * pText); +void CHOOSEFILE_SetDelim (char Delim); +void CHOOSEFILE_SetToolTips (const TOOLTIP_INFO * pInfo, int NumItems); +void CHOOSEFILE_SetTopMode (unsigned OnOff); + +#if defined(__cplusplus) + } +#endif + +#endif /* GUI_WINSUPPORT */ + +#endif /* CHOOSEFILE_H */ + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/DIALOG.h b/example/GUI/STemWin/inc/DIALOG.h new file mode 100755 index 0000000000..a8f1a8686e --- /dev/null +++ b/example/GUI/STemWin/inc/DIALOG.h @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : Dialog.h +Purpose : Dialog box include +--------------------END-OF-HEADER------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef DIALOG_H +#define DIALOG_H + +#include "WM.h" +#include "BUTTON.h" +#include "CALENDAR.h" +#include "CHECKBOX.h" +#include "CHOOSECOLOR.h" +#include "CHOOSEFILE.h" +#include "DROPDOWN.h" +#include "EDIT.h" +#include "FRAMEWIN.h" +#include "GRAPH.h" +#include "HEADER.h" +#include "ICONVIEW.h" +#include "IMAGE.h" +#include "LISTBOX.h" +#include "LISTVIEW.h" +#include "LISTWHEEL.h" +#include "MENU.h" +#include "MULTIEDIT.h" +#include "MULTIPAGE.h" +#include "PROGBAR.h" +#include "RADIO.h" +#include "SCROLLBAR.h" +#include "SLIDER.h" +#include "SPINBOX.h" +#include "SWIPELIST.h" +#include "TEXT.h" +#include "TREEVIEW.h" +#include "KNOB.h" + +#if GUI_WINSUPPORT + +#if defined(__cplusplus) + extern "C" { /* Make sure we have C-declarations in C++ programs */ +#endif + +/********************************************************************* +* +* WINDOW API +*/ +WM_HWIN WINDOW_CreateEx (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int WinFlags, int ExFlags, int Id, WM_CALLBACK * cb); +WM_HWIN WINDOW_CreateUser (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int WinFlags, int ExFlags, int Id, WM_CALLBACK * cb, int NumExtraBytes); +WM_HWIN WINDOW_CreateIndirect (const GUI_WIDGET_CREATE_INFO * pCreateInfo, WM_HWIN hWinParent, int x0, int y0, WM_CALLBACK * cb); +GUI_COLOR WINDOW_GetDefaultBkColor(void); +int WINDOW_GetUserData (WM_HWIN hObj, void * pDest, int NumBytes); +void WINDOW_SetBkColor (WM_HWIN hObj, GUI_COLOR Color); +void WINDOW_SetDefaultBkColor(GUI_COLOR Color); +int WINDOW_SetUserData (WM_HWIN hObj, const void * pSrc, int NumBytes); + +void WINDOW_Callback(WM_MESSAGE * pMsg); + +#if defined(__cplusplus) + } +#endif + +#endif // GUI_WINSUPPORT +#endif // DIALOG_H + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/DIALOG_Intern.h b/example/GUI/STemWin/inc/DIALOG_Intern.h new file mode 100755 index 0000000000..373bc75388 --- /dev/null +++ b/example/GUI/STemWin/inc/DIALOG_Intern.h @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : Dialog.h +Purpose : Dialog box include +--------------------END-OF-HEADER------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef DIALOG_INTERN_H +#define DIALOG_INTERN_H + +#include "WM.h" + +#if GUI_WINSUPPORT + +#if defined(__cplusplus) + extern "C" { // Make sure we have C-declarations in C++ programs +#endif + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ +typedef struct GUI_WIDGET_CREATE_INFO_struct GUI_WIDGET_CREATE_INFO; +typedef WM_HWIN GUI_WIDGET_CREATE_FUNC (const GUI_WIDGET_CREATE_INFO * pCreate, WM_HWIN hWin, int x0, int y0, WM_CALLBACK * cb); + +/********************************************************************* +* +* Structures +* +********************************************************************** +*/ +struct GUI_WIDGET_CREATE_INFO_struct { + GUI_WIDGET_CREATE_FUNC * pfCreateIndirect; + const char * pName; // Text ... Not used on all widgets + I16 Id; // ID ... should be unique in a dialog + I16 x0; // x position + I16 y0; // y position + I16 xSize; // x size + I16 ySize; // y size + U16 Flags; // Widget specific create flags (opt.) + I32 Para; // Widget specific parameter (opt.) + U32 NumExtraBytes; // Number of extra bytes usable with _SetUserData & _GetUserData +}; + +/********************************************************************* +* +* Public API functions +* +********************************************************************** +*/ +WM_HWIN GUI_CreateDialogBox (const GUI_WIDGET_CREATE_INFO * paWidget, int NumWidgets, WM_CALLBACK * cb, WM_HWIN hParent, int x0, int y0); +void GUI_EndDialog (WM_HWIN hWin, int r); +int GUI_ExecDialogBox (const GUI_WIDGET_CREATE_INFO * paWidget, int NumWidgets, WM_CALLBACK * cb, WM_HWIN hParent, int x0, int y0); +int GUI_ExecCreatedDialog (WM_HWIN hDialog); +WM_DIALOG_STATUS * GUI_GetDialogStatusPtr(WM_HWIN hDialog); // Not to be documented +void GUI_SetDialogStatusPtr(WM_HWIN hDialog, WM_DIALOG_STATUS * pDialogStatus); // Not to be documented + +/********************************************************************* +* +* Obsolete +*/ +LCD_COLOR DIALOG_GetBkColor(void); +LCD_COLOR DIALOG_SetBkColor(LCD_COLOR BkColor); + +#if defined(__cplusplus) + } +#endif + +#endif // GUI_WINSUPPORT +#endif // DIALOG_INTERN_H + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/DROPDOWN.h b/example/GUI/STemWin/inc/DROPDOWN.h new file mode 100755 index 0000000000..c8a0dd6f3a --- /dev/null +++ b/example/GUI/STemWin/inc/DROPDOWN.h @@ -0,0 +1,214 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : DROPDOWN.h +Purpose : Multiple choice object include +--------------------END-OF-HEADER------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef DROPDOWN_H +#define DROPDOWN_H + +#include "WM.h" +#include "DIALOG_Intern.h" /* Req. for Create indirect data structure */ +#include "LISTBOX.h" + +#if GUI_WINSUPPORT + +#if defined(__cplusplus) + extern "C" { /* Make sure we have C-declarations in C++ programs */ +#endif + +/************************************************************ +* +* Create flags +*/ +#define DROPDOWN_CF_AUTOSCROLLBAR (1 << 0) +#define DROPDOWN_CF_UP (1 << 1) + +/********************************************************************* +* +* Color indices +*/ +#define DROPDOWN_CI_UNSEL 0 +#define DROPDOWN_CI_SEL 1 +#define DROPDOWN_CI_SELFOCUS 2 + +#define DROPDOWN_CI_ARROW 0 +#define DROPDOWN_CI_BUTTON 1 + +/********************************************************************* +* +* Skinning property indices +*/ +#define DROPDOWN_SKINFLEX_PI_EXPANDED 0 +#define DROPDOWN_SKINFLEX_PI_FOCUSED 1 +#define DROPDOWN_SKINFLEX_PI_ENABLED 2 +#define DROPDOWN_SKINFLEX_PI_DISABLED 3 + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ +typedef WM_HMEM DROPDOWN_Handle; + +typedef struct { + GUI_COLOR aColorFrame[3]; + GUI_COLOR aColorUpper[2]; + GUI_COLOR aColorLower[2]; + GUI_COLOR ColorArrow; + GUI_COLOR ColorText; + GUI_COLOR ColorSep; + int Radius; +} DROPDOWN_SKINFLEX_PROPS; + +/********************************************************************* +* +* Create functions +* +********************************************************************** +*/ +DROPDOWN_Handle DROPDOWN_Create (WM_HWIN hWinParent, int x0, int y0, int xSize, int ySize, int Flags); +DROPDOWN_Handle DROPDOWN_CreateEx (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int WinFlags, int ExFlags, int Id); +DROPDOWN_Handle DROPDOWN_CreateUser (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int WinFlags, int ExFlags, int Id, int NumExtraBytes); +DROPDOWN_Handle DROPDOWN_CreateIndirect(const GUI_WIDGET_CREATE_INFO* pCreateInfo, WM_HWIN hWinParent, int x0, int y0, WM_CALLBACK* cb); + +/********************************************************************* +* +* The callback ... +* +* Do not call it directly ! It is only to be used from within an +* overwritten callback. +*/ +void DROPDOWN_Callback(WM_MESSAGE * pMsg); + +/********************************************************************* +* +* Member functions +* +********************************************************************** +*/ +void DROPDOWN_AddKey (DROPDOWN_Handle hObj, int Key); +void DROPDOWN_AddString (DROPDOWN_Handle hObj, const char* s); +void DROPDOWN_Collapse (DROPDOWN_Handle hObj); +void DROPDOWN_DecSel (DROPDOWN_Handle hObj); +void DROPDOWN_DecSelExp (DROPDOWN_Handle hObj); +void DROPDOWN_DeleteItem (DROPDOWN_Handle hObj, unsigned int Index); +void DROPDOWN_Expand (DROPDOWN_Handle hObj); +unsigned DROPDOWN_GetItemDisabled (DROPDOWN_Handle hObj, unsigned Index); +unsigned DROPDOWN_GetItemSpacing (DROPDOWN_Handle hObj); +int DROPDOWN_GetItemText (DROPDOWN_Handle hObj, unsigned Index, char * pBuffer, int MaxSize); +LISTBOX_Handle DROPDOWN_GetListbox (DROPDOWN_Handle hObj); +int DROPDOWN_GetNumItems (DROPDOWN_Handle hObj); +int DROPDOWN_GetSel (DROPDOWN_Handle hObj); +int DROPDOWN_GetSelExp (DROPDOWN_Handle hObj); +int DROPDOWN_GetUserData (DROPDOWN_Handle hObj, void * pDest, int NumBytes); +void DROPDOWN_IncSel (DROPDOWN_Handle hObj); +void DROPDOWN_IncSelExp (DROPDOWN_Handle hObj); +void DROPDOWN_InsertString (DROPDOWN_Handle hObj, const char* s, unsigned int Index); +void DROPDOWN_SetAutoScroll (DROPDOWN_Handle hObj, int OnOff); +void DROPDOWN_SetBkColor (DROPDOWN_Handle hObj, unsigned int Index, GUI_COLOR color); +void DROPDOWN_SetColor (DROPDOWN_Handle hObj, unsigned int Index, GUI_COLOR Color); +void DROPDOWN_SetFont (DROPDOWN_Handle hObj, const GUI_FONT * pfont); +void DROPDOWN_SetItemDisabled (DROPDOWN_Handle hObj, unsigned Index, int OnOff); +void DROPDOWN_SetItemSpacing (DROPDOWN_Handle hObj, unsigned Value); +int DROPDOWN_SetListHeight (DROPDOWN_Handle hObj, unsigned Height); +void DROPDOWN_SetScrollbarColor(DROPDOWN_Handle hObj, unsigned Index, GUI_COLOR Color); +void DROPDOWN_SetScrollbarWidth(DROPDOWN_Handle hObj, unsigned Width); +void DROPDOWN_SetSel (DROPDOWN_Handle hObj, int Sel); +void DROPDOWN_SetSelExp (DROPDOWN_Handle hObj, int Sel); +void DROPDOWN_SetTextAlign (DROPDOWN_Handle hObj, int Align); +void DROPDOWN_SetTextColor (DROPDOWN_Handle hObj, unsigned int index, GUI_COLOR color); +void DROPDOWN_SetTextHeight (DROPDOWN_Handle hObj, unsigned TextHeight); +int DROPDOWN_SetUpMode (DROPDOWN_Handle hObj, int OnOff); +int DROPDOWN_SetUserData (DROPDOWN_Handle hObj, const void * pSrc, int NumBytes); + +/********************************************************************* +* +* Member functions: Skinning +* +********************************************************************** +*/ +void DROPDOWN_GetSkinFlexProps (DROPDOWN_SKINFLEX_PROPS * pProps, int Index); +void DROPDOWN_SetSkinClassic (DROPDOWN_Handle hObj); +void DROPDOWN_SetSkin (DROPDOWN_Handle hObj, WIDGET_DRAW_ITEM_FUNC * pfDrawSkin); +int DROPDOWN_DrawSkinFlex (const WIDGET_ITEM_DRAW_INFO * pDrawItemInfo); +void DROPDOWN_SetSkinFlexProps (const DROPDOWN_SKINFLEX_PROPS * pProps, int Index); +void DROPDOWN_SetDefaultSkinClassic(void); +WIDGET_DRAW_ITEM_FUNC * DROPDOWN_SetDefaultSkin(WIDGET_DRAW_ITEM_FUNC * pfDrawSkin); + +#define DROPDOWN_SKIN_FLEX DROPDOWN_DrawSkinFlex + +/********************************************************************* +* +* Managing default values +* +********************************************************************** +*/ +GUI_COLOR DROPDOWN_GetDefaultBkColor (int Index); +GUI_COLOR DROPDOWN_GetDefaultColor (int Index); +const GUI_FONT * DROPDOWN_GetDefaultFont (void); +GUI_COLOR DROPDOWN_GetDefaultScrollbarColor(int Index); +void DROPDOWN_SetDefaultFont (const GUI_FONT * pFont); +GUI_COLOR DROPDOWN_SetDefaultBkColor (int Index, GUI_COLOR Color); +GUI_COLOR DROPDOWN_SetDefaultColor (int Index, GUI_COLOR Color); +GUI_COLOR DROPDOWN_SetDefaultScrollbarColor(int Index, GUI_COLOR Color); + +#if defined(__cplusplus) + } +#endif + +#endif // GUI_WINSUPPORT +#endif // DROPDOWN_H + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/DROPDOWN_Private.h b/example/GUI/STemWin/inc/DROPDOWN_Private.h new file mode 100755 index 0000000000..898df17dea --- /dev/null +++ b/example/GUI/STemWin/inc/DROPDOWN_Private.h @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : DROPDOWN_Private.h +Purpose : DROPDOWN private header file +--------------------END-OF-HEADER------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef DROPDOWN_PRIVATE_H +#define DROPDOWN_PRIVATE_H + +#include "DROPDOWN.h" +#include "WIDGET.h" +#include "GUI_ARRAY.h" + +#if GUI_WINSUPPORT + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ +#define DROPDOWN_SF_AUTOSCROLLBAR DROPDOWN_CF_AUTOSCROLLBAR + +/********************************************************************* +* +* Object definition +* +********************************************************************** +*/ +typedef struct { + WIDGET_DRAW_ITEM_FUNC * pfDrawSkin; +} DROPDOWN_SKIN_PRIVATE; + +typedef struct { + const GUI_FONT * pFont; + GUI_COLOR aBackColor[3]; + GUI_COLOR aTextColor[3]; + GUI_COLOR aColor[2]; + GUI_COLOR aScrollbarColor[3]; + DROPDOWN_SKIN_PRIVATE SkinPrivate; + I16 TextBorderSize; + I16 Align; +} DROPDOWN_PROPS; + +typedef struct { + WIDGET Widget; + I16 Sel; // Current selection + I16 ySizeLB; // ySize of assigned LISTBOX in expanded state + I16 TextHeight; + GUI_ARRAY Handles; + WM_SCROLL_STATE ScrollState; + DROPDOWN_PROPS Props; + WIDGET_SKIN const * pWidgetSkin; + WM_HWIN hListWin; + U8 Flags; + U16 ItemSpacing; + U8 ScrollbarWidth; + char IsPressed; + WM_HMEM hDisabled; +} DROPDOWN_Obj; + +/********************************************************************* +* +* Macros for internal use +* +********************************************************************** +*/ +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL + #define DROPDOWN_INIT_ID(p) (p->Widget.DebugId = DROPDOWN_ID) +#else + #define DROPDOWN_INIT_ID(p) +#endif + +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL + DROPDOWN_Obj * DROPDOWN_LockH(DROPDOWN_Handle h); + #define DROPDOWN_LOCK_H(h) DROPDOWN_LockH(h) +#else + #define DROPDOWN_LOCK_H(h) (DROPDOWN_Obj *)GUI_LOCK_H(h) +#endif + +/********************************************************************* +* +* Private (module internal) data +* +********************************************************************** +*/ + +extern DROPDOWN_PROPS DROPDOWN__DefaultProps; + +extern const WIDGET_SKIN DROPDOWN__SkinClassic; +extern WIDGET_SKIN DROPDOWN__Skin; + +extern WIDGET_SKIN const * DROPDOWN__pSkinDefault; + +/********************************************************************* +* +* Private functions +* +********************************************************************** +*/ + +void DROPDOWN__AdjustHeight(DROPDOWN_Handle hObj); +int DROPDOWN__GetNumItems (DROPDOWN_Obj * pObj); +const char * DROPDOWN__GetpItemLocked(DROPDOWN_Handle hObj, int Index); + +#endif // GUI_WINSUPPORT +#endif // DROPDOWN_PRIVATE_H + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/EDIT.h b/example/GUI/STemWin/inc/EDIT.h new file mode 100755 index 0000000000..86a983b53c --- /dev/null +++ b/example/GUI/STemWin/inc/EDIT.h @@ -0,0 +1,241 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : EDIT.h +Purpose : EDIT include +--------------------END-OF-HEADER------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef EDIT_H +#define EDIT_H + +#include "WM.h" +#include "DIALOG_Intern.h" // Required for Create indirect data structure + +#if GUI_WINSUPPORT + +#if defined(__cplusplus) + extern "C" { // Make sure we have C-declarations in C++ programs +#endif + +/********************************************************************* +* +* Defaults for configuration switches +* +* The following are defaults for config switches which affect the +* interface specified in this module +* +********************************************************************** +*/ +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ +// +// Create / Status flags +// +#define EDIT_CF_LEFT GUI_TA_LEFT +#define EDIT_CF_RIGHT GUI_TA_RIGHT +#define EDIT_CF_HCENTER GUI_TA_HCENTER +#define EDIT_CF_VCENTER GUI_TA_VCENTER +#define EDIT_CF_TOP GUI_TA_TOP +#define EDIT_CF_BOTTOM GUI_TA_BOTTOM + +// +// Color indices +// +#define EDIT_CI_DISABLED 0 +#define EDIT_CI_ENABLED 1 +#define EDIT_CI_CURSOR 2 + +// +// Signed or normal mode +// +#define GUI_EDIT_NORMAL (0 << 0) +#define GUI_EDIT_SIGNED (1 << 0) +#define GUI_EDIT_SUPPRESS_LEADING_ZEROES (1 << 1) + +// +// Cursor coloring +// +#define GUI_EDIT_SHOWCURSOR (1 << 2) +#define GUI_EDIT_CUSTCOLORMODE (1 << 3) + +// +// Edit modes +// +#define GUI_EDIT_MODE_INSERT 0 +#define GUI_EDIT_MODE_OVERWRITE 1 + +// +// Compatibility macros +// +#define EDIT_CI_DISABELD EDIT_CI_DISABLED +#define EDIT_CI_ENABELD EDIT_CI_ENABLED + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ +typedef WM_HMEM EDIT_Handle; +typedef void tEDIT_AddKeyEx (EDIT_Handle hObj, int Key); +typedef void tEDIT_UpdateBuffer(EDIT_Handle hObj); + +/********************************************************************* +* +* Create functions +*/ +EDIT_Handle EDIT_Create (int x0, int y0, int xSize, int ySize, int Id, int MaxLen, int Flags); +EDIT_Handle EDIT_CreateAsChild (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int Id, int Flags, int MaxLen); +EDIT_Handle EDIT_CreateEx (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int WinFlags, int ExFlags, int Id, int MaxLen); +EDIT_Handle EDIT_CreateUser (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int WinFlags, int ExFlags, int Id, int MaxLen, int NumExtraBytes); +EDIT_Handle EDIT_CreateIndirect(const GUI_WIDGET_CREATE_INFO * pCreateInfo, WM_HWIN hWinParent, int x0, int y0, WM_CALLBACK * cb); + +/********************************************************************* +* +* The callback ... +* +* Do not call it directly ! It is only to be used from within an +* overwritten callback. +*/ +void EDIT_Callback(WM_MESSAGE * pMsg); + +/********************************************************************* +* +* Managing default values +* +********************************************************************** +*/ +void EDIT_SetDefaultBkColor (unsigned int Index, GUI_COLOR Color); +void EDIT_SetDefaultFont (const GUI_FONT * pFont); +void EDIT_SetDefaultTextAlign(int Align); +void EDIT_SetDefaultTextColor(unsigned int Index, GUI_COLOR Color); + +/********************************************************************* +* +* Individual member functions +*/ +// +// Query preferences +// +GUI_COLOR EDIT_GetDefaultBkColor(unsigned int Index); +const GUI_FONT * EDIT_GetDefaultFont(void); +int EDIT_GetDefaultTextAlign(void); +GUI_COLOR EDIT_GetDefaultTextColor(unsigned int Index); +// +// Methods changing properties +// +void EDIT_AddKey (EDIT_Handle hObj, int Key); +void EDIT_EnableBlink (EDIT_Handle hObj, int Period, int OnOff); +GUI_COLOR EDIT_GetBkColor (EDIT_Handle hObj, unsigned int Index); +void EDIT_SetBkColor (EDIT_Handle hObj, unsigned int Index, GUI_COLOR color); +void EDIT_SetCursorAtChar (EDIT_Handle hObj, int Pos); +void EDIT_SetCursorAtPixel (EDIT_Handle hObj, int xPos); +void EDIT_SetFont (EDIT_Handle hObj, const GUI_FONT * pFont); +int EDIT_SetInsertMode (EDIT_Handle hObj, int OnOff); +void EDIT_SetMaxLen (EDIT_Handle hObj, int MaxLen); +void EDIT_SetpfAddKeyEx (EDIT_Handle hObj, tEDIT_AddKeyEx * pfAddKeyEx); +void EDIT_SetpfUpdateBuffer(EDIT_Handle hObj, tEDIT_UpdateBuffer * pfUpdateBuffer); +void EDIT_SetText (EDIT_Handle hObj, const char * s); +void EDIT_SetTextAlign (EDIT_Handle hObj, int Align); +GUI_COLOR EDIT_GetTextColor(EDIT_Handle hObj, unsigned int Index); +void EDIT_SetTextColor (EDIT_Handle hObj, unsigned int Index, GUI_COLOR Color); +void EDIT_SetSel (EDIT_Handle hObj, int FirstChar, int LastChar); +int EDIT_SetUserData (EDIT_Handle hObj, const void * pSrc, int NumBytes); +int EDIT_EnableInversion (EDIT_Handle hObj, int OnOff); +// +// Get/Set user input +// +int EDIT_GetCursorCharPos (EDIT_Handle hObj); +void EDIT_GetCursorPixelPos (EDIT_Handle hObj, int * pxPos, int * pyPos); +float EDIT_GetFloatValue (EDIT_Handle hObj); +const GUI_FONT * EDIT_GetFont(EDIT_Handle hObj); +int EDIT_GetNumChars (EDIT_Handle hObj); +void EDIT_GetText (EDIT_Handle hObj, char * sDest, int MaxLen); +I32 EDIT_GetValue (EDIT_Handle hObj); +void EDIT_SetFloatValue (EDIT_Handle hObj, float Value); +int EDIT_GetUserData (EDIT_Handle hObj, void * pDest, int NumBytes); +void EDIT_SetValue (EDIT_Handle hObj, I32 Value); + +#define EDIT_SetFocussable EDIT_SetFocusable +#define EDIT_SetFocusable WIDGET_SetFocusable + +/********************************************************************* +* +* Routines for editing values +* +********************************************************************** +*/ +void EDIT_SetHexMode (EDIT_Handle hEdit, U32 Value, U32 Min, U32 Max); +void EDIT_SetBinMode (EDIT_Handle hEdit, U32 Value, U32 Min, U32 Max); +void EDIT_SetDecMode (EDIT_Handle hEdit, I32 Value, I32 Min, I32 Max, int Shift, U8 Flags); +void EDIT_SetFloatMode(EDIT_Handle hEdit, float Value, float Min, float Max, int Shift, U8 Flags); +void EDIT_SetTextMode (EDIT_Handle hEdit); +void EDIT_SetUlongMode(EDIT_Handle hEdit, U32 Value, U32 Min, U32 Max); + +U32 GUI_EditHex (U32 Value, U32 Min, U32 Max, int Len, int xSize); +U32 GUI_EditBin (U32 Value, U32 Min, U32 Max, int Len, int xSize); +I32 GUI_EditDec (I32 Value, I32 Min, I32 Max, int Len, int xSize, int Shift, U8 Flags); +float GUI_EditFloat (float Value, float Min, float Max, int Len, int xSize, int Shift, U8 Flags); +void GUI_EditString (char * pString, int Len, int xSize); + +#if defined(__cplusplus) + } +#endif + +#endif // GUI_WINSUPPORT +#endif // EDIT_H + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/EDIT_Private.h b/example/GUI/STemWin/inc/EDIT_Private.h new file mode 100755 index 0000000000..d2d89c5f4b --- /dev/null +++ b/example/GUI/STemWin/inc/EDIT_Private.h @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : EDIT_Private.h +Purpose : Internal header file +---------------------------END-OF-HEADER------------------------------ +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef EDIT_PRIVATE_H +#define EDIT_PRIVATE_H + +#include "EDIT.h" + +#if GUI_WINSUPPORT + +#include "WIDGET.h" + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ +#define EDIT_REALLOC_SIZE 16 + +#ifndef EDIT_XOFF + #define EDIT_XOFF 1 +#endif + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ +typedef struct EDIT_Obj_struct EDIT_Obj; + +typedef struct { + int Align; + int Border; + const GUI_FONT * pFont; + GUI_COLOR aTextColor[3]; + GUI_COLOR aBkColor[3]; +} EDIT_PROPS; + +struct EDIT_Obj_struct { + WIDGET Widget; + WM_HMEM hpText; + I16 MaxLen; + U16 BufferSize; + I32 Min, Max; // Min max values as normalized floats (integers) + U8 NumDecs; // Number of decimals + I32 CurrentValue; // Current value + int CursorPos; // Cursor position. 0 means left most + unsigned SelSize; // Number of selected characters + U8 EditMode; // Insert or overwrite mode + U8 XSizeCursor; // Size of cursor when working in insert mode + U8 Flags; + tEDIT_AddKeyEx * pfAddKeyEx; // Handle key input + tEDIT_UpdateBuffer * pfUpdateBuffer; // Update textbuffer + EDIT_PROPS Props; + WM_HTIMER hTimer; + U8 MinMaxMode; +}; + +/********************************************************************* +* +* Macros for internal use +* +********************************************************************** +*/ +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL + #define EDIT_INIT_ID(p) (p->Widget.DebugId = EDIT_ID) +#else + #define EDIT_INIT_ID(p) +#endif + +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL + EDIT_Obj * EDIT_LockH(EDIT_Handle h); + #define EDIT_LOCK_H(h) EDIT_LockH(h) +#else + #define EDIT_LOCK_H(h) (EDIT_Obj *)GUI_LOCK_H(h) +#endif + +/********************************************************************* +* +* Public data (internal defaults) +* +********************************************************************** +*/ +extern EDIT_PROPS EDIT__DefaultProps; + +/********************************************************************* +* +* Public functions (internal) +* +********************************************************************** +*/ +U16 EDIT__GetCurrentChar (EDIT_Obj * pObj); +void EDIT__SetCursorPos (EDIT_Handle hObj, int CursorPos); +void EDIT__SetValueUnsigned(EDIT_Handle hObj, I32 Value); + +#endif // GUI_WINSUPPORT + +#endif // EDIT_PRIVATE_H + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/FRAMEWIN.h b/example/GUI/STemWin/inc/FRAMEWIN.h new file mode 100755 index 0000000000..6d8b758908 --- /dev/null +++ b/example/GUI/STemWin/inc/FRAMEWIN.h @@ -0,0 +1,277 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : FRAMEWIN.h +Purpose : Frame window include +--------------------END-OF-HEADER------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef FRAMEWIN_H +#define FRAMEWIN_H + +#include "WM.h" +#include "WIDGET.h" /* Req. for WIDGET_DRAW_ITEM_FUNC */ +#if GUI_WINSUPPORT +#include "DIALOG_Intern.h" /* Req. for Create indirect data structure */ + +#if defined(__cplusplus) + extern "C" { /* Make sure we have C-declarations in C++ programs */ +#endif + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ +/********************************************************************* +* +* Configuration +*/ +#ifndef FRAMEWIN_ALLOW_DRAG_ON_FRAME + #define FRAMEWIN_ALLOW_DRAG_ON_FRAME 1 +#endif + +/********************************************************************* +* +* Color indices +*/ +#define FRAMEWIN_CI_INACTIVE 0 +#define FRAMEWIN_CI_ACTIVE 1 + +/********************************************************************* +* +* Create / Status flags +*/ +#define FRAMEWIN_CF_ACTIVE (1<<3) +#define FRAMEWIN_CF_MOVEABLE (1<<4) +#define FRAMEWIN_CF_TITLEVIS (1<<5) +#define FRAMEWIN_CF_MINIMIZED (1<<6) +#define FRAMEWIN_CF_MAXIMIZED (1<<7) +#define FRAMEWIN_CF_DRAGGING (1<<8) + +#define FRAMEWIN_SF_ACTIVE FRAMEWIN_CF_ACTIVE +#define FRAMEWIN_SF_MOVEABLE FRAMEWIN_CF_MOVEABLE +#define FRAMEWIN_SF_TITLEVIS FRAMEWIN_CF_TITLEVIS +#define FRAMEWIN_SF_MINIMIZED FRAMEWIN_CF_MINIMIZED +#define FRAMEWIN_SF_MAXIMIZED FRAMEWIN_CF_MAXIMIZED +#define FRAMEWIN_SF_DRAGGING FRAMEWIN_CF_DRAGGING + +/********************************************************************* +* +* BUTTON Flags +*/ +#define FRAMEWIN_BUTTON_RIGHT (1<<0) +#define FRAMEWIN_BUTTON_LEFT (1<<1) + +/********************************************************************* +* +* Skinning property indices +*/ +#define FRAMEWIN_SKINFLEX_PI_ACTIVE 0 +#define FRAMEWIN_SKINFLEX_PI_INACTIVE 1 + +/********************************************************************* +* +* Getting border size +*/ +#define FRAMEWIN_BORDERSIZE_T 0 +#define FRAMEWIN_BORDERSIZE_L 1 +#define FRAMEWIN_BORDERSIZE_B 2 +#define FRAMEWIN_BORDERSIZE_R 3 + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ +typedef WM_HMEM FRAMEWIN_Handle; + +typedef struct { + GUI_COLOR aColorFrame[3]; + GUI_COLOR aColorTitle[2]; + int Radius; + int SpaceX; + int BorderSizeL; + int BorderSizeR; + int BorderSizeT; + int BorderSizeB; +} FRAMEWIN_SKINFLEX_PROPS; + +/********************************************************************* +* +* Create functions +* +********************************************************************** +*/ +FRAMEWIN_Handle FRAMEWIN_Create (const char * pTitle, WM_CALLBACK * cb, int Flags, int x0, int y0, int xSize, int ySize); +FRAMEWIN_Handle FRAMEWIN_CreateAsChild (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, const char * pText, WM_CALLBACK * cb, int Flags); +FRAMEWIN_Handle FRAMEWIN_CreateEx (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int WinFlags, int ExFlags, int Id, const char * pTitle, WM_CALLBACK * cb); +FRAMEWIN_Handle FRAMEWIN_CreateUser (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int WinFlags, int ExFlags, int Id, const char * pTitle, WM_CALLBACK * cb, int NumExtraBytes); +FRAMEWIN_Handle FRAMEWIN_CreateIndirect(const GUI_WIDGET_CREATE_INFO * pCreateInfo, WM_HWIN hWinParent, int x0, int y0, WM_CALLBACK * cb); + +/********************************************************************* +* +* The callback ... +* +* Do not call it directly ! It is only to be used from within an +* overwritten callback. +*/ +void FRAMEWIN_Callback(WM_MESSAGE * pMsg); + +/********************************************************************* +* +* Member functions: Set Properties +* +********************************************************************** +*/ +WM_HWIN FRAMEWIN_AddButton (FRAMEWIN_Handle hObj, int Flags, int Off, int Id); +WM_HWIN FRAMEWIN_AddCloseButton(FRAMEWIN_Handle hObj, int Flags, int Off); +WM_HWIN FRAMEWIN_AddMaxButton (FRAMEWIN_Handle hObj, int Flags, int Off); +void FRAMEWIN_AddMenu (FRAMEWIN_Handle hObj, WM_HWIN hMenu); +WM_HWIN FRAMEWIN_AddMinButton (FRAMEWIN_Handle hObj, int Flags, int Off); +void FRAMEWIN_Minimize (FRAMEWIN_Handle hObj); +void FRAMEWIN_Maximize (FRAMEWIN_Handle hObj); +void FRAMEWIN_Restore (FRAMEWIN_Handle hObj); +void FRAMEWIN_SetActive (FRAMEWIN_Handle hObj, int State); +void FRAMEWIN_SetBarColor (FRAMEWIN_Handle hObj, unsigned Index, GUI_COLOR Color); +void FRAMEWIN_SetBorderSize (FRAMEWIN_Handle hObj, unsigned Size); +void FRAMEWIN_SetClientColor(FRAMEWIN_Handle hObj, GUI_COLOR Color); +void FRAMEWIN_SetFont (FRAMEWIN_Handle hObj, const GUI_FONT * pFont); +void FRAMEWIN_SetMoveable (FRAMEWIN_Handle hObj, int State); +void FRAMEWIN_SetOwnerDraw (FRAMEWIN_Handle hObj, WIDGET_DRAW_ITEM_FUNC * pfDrawItem); +void FRAMEWIN_SetResizeable (FRAMEWIN_Handle hObj, int State); +void FRAMEWIN_SetText (FRAMEWIN_Handle hObj, const char* s); +void FRAMEWIN_SetTextAlign (FRAMEWIN_Handle hObj, int Align); +void FRAMEWIN_SetTextColor (FRAMEWIN_Handle hObj, GUI_COLOR Color); +void FRAMEWIN_SetTextColorEx(FRAMEWIN_Handle hObj, unsigned Index, GUI_COLOR Color); +void FRAMEWIN_SetTitleVis (FRAMEWIN_Handle hObj, int Show); +int FRAMEWIN_SetTitleHeight(FRAMEWIN_Handle hObj, int Height); +int FRAMEWIN_SetUserData (FRAMEWIN_Handle hObj, const void * pSrc, int NumBytes); + +/********************************************************************* +* +* Member functions: Skinning +* +********************************************************************** +*/ +void FRAMEWIN_GetSkinFlexProps (FRAMEWIN_SKINFLEX_PROPS * pProps, int Index); +void FRAMEWIN_SetSkinClassic (FRAMEWIN_Handle hObj); +void FRAMEWIN_SetSkin (FRAMEWIN_Handle hObj, WIDGET_DRAW_ITEM_FUNC * pfDrawSkin); +int FRAMEWIN_DrawSkinFlex (const WIDGET_ITEM_DRAW_INFO * pDrawItemInfo); +void FRAMEWIN_SetSkinFlexProps (const FRAMEWIN_SKINFLEX_PROPS * pProps, int Index); +void FRAMEWIN_SetDefaultSkinClassic(void); +WIDGET_DRAW_ITEM_FUNC * FRAMEWIN_SetDefaultSkin(WIDGET_DRAW_ITEM_FUNC * pfDrawSkin); + +#define FRAMEWIN_SKIN_FLEX FRAMEWIN_DrawSkinFlex + +/********************************************************************* +* +* Member functions: Get Properties +* +********************************************************************** +*/ +const GUI_FONT * FRAMEWIN_GetFont(FRAMEWIN_Handle hObj); + +int FRAMEWIN_GetActive (FRAMEWIN_Handle hObj); +int FRAMEWIN_GetTitleHeight (FRAMEWIN_Handle hObj); +GUI_COLOR FRAMEWIN_GetBarColor (FRAMEWIN_Handle hObj, unsigned Index); +int FRAMEWIN_GetBorderSize (FRAMEWIN_Handle hObj); +int FRAMEWIN_GetBorderSizeEx(FRAMEWIN_Handle hObj, unsigned Edge); +void FRAMEWIN_GetText (FRAMEWIN_Handle hObj, char * pBuffer, int MaxLen); +int FRAMEWIN_GetTextAlign (FRAMEWIN_Handle hObj); +int FRAMEWIN_GetUserData (FRAMEWIN_Handle hObj, void * pDest, int NumBytes); +int FRAMEWIN_IsMinimized (FRAMEWIN_Handle hObj); +int FRAMEWIN_IsMaximized (FRAMEWIN_Handle hObj); + +/********************************************************************* +* +* Managing default values +* +********************************************************************** +*/ +GUI_COLOR FRAMEWIN_GetDefaultBarColor (unsigned Index); +int FRAMEWIN_GetDefaultBorderSize (void); +int FRAMEWIN_GetDefaultTitleHeight(void); +GUI_COLOR FRAMEWIN_GetDefaultClientColor(void); +const GUI_FONT * FRAMEWIN_GetDefaultFont (void); +GUI_COLOR FRAMEWIN_GetDefaultTextColor (unsigned Index); +int FRAMEWIN_OwnerDraw (const WIDGET_ITEM_DRAW_INFO * pDrawItemInfo); +void FRAMEWIN_SetDefaultBarColor (unsigned Index, GUI_COLOR Color); +void FRAMEWIN_SetDefaultBorderSize (int DefaultBorderSize); +void FRAMEWIN_SetDefaultTitleHeight(int DefaultTitleHeight); +void FRAMEWIN_SetDefaultClientColor(GUI_COLOR Color); +void FRAMEWIN_SetDefaultFont (const GUI_FONT * pFont); +int FRAMEWIN_SetDefaultTextAlign (int TextAlign); +void FRAMEWIN_SetDefaultTextColor (unsigned Index, GUI_COLOR Color); + +/********************************************************************* +* +* Macros for compatibility +* +********************************************************************** +*/ +#define FRAMEWIN_SetDefaultCaptionSize(Height) FRAMEWIN_SetDefaultTitleHeight(Height) +#define FRAMEWIN_GetDefaultCaptionSize() FRAMEWIN_GetDefaultTitleHeight() +#define FRAMEWIN_CreateButton(hObj, Flags, Off, Id) FRAMEWIN_AddButton(hObj, Flags, Off, Id) +#define FRAMEWIN_CreateCloseButton(hObj, Flags, Off) FRAMEWIN_AddCloseButton(hObj, Flags, Off) +#define FRAMEWIN_CreateMaxButton(hObj, Flags, Off) FRAMEWIN_AddMaxButton(hObj, Flags, Off) +#define FRAMEWIN_CreateMinButton(hObj, Flags, Off) FRAMEWIN_AddMinButton(hObj, Flags, Off) + +#if defined(__cplusplus) + } +#endif + +#endif // GUI_WINSUPPORT +#endif // FRAMEWIN_H + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/FRAMEWIN_Private.h b/example/GUI/STemWin/inc/FRAMEWIN_Private.h new file mode 100755 index 0000000000..3a23995400 --- /dev/null +++ b/example/GUI/STemWin/inc/FRAMEWIN_Private.h @@ -0,0 +1,272 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : FRAMEWIN_Private.h +Purpose : FRAMEWIN private header file +--------------------END-OF-HEADER------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef FRAMEWIN_PRIVATE_H +#define FRAMEWIN_PRIVATE_H + +#include "WM.h" +#include "FRAMEWIN.h" +#include "WIDGET.h" +#include "GUI_HOOK.h" + +#if GUI_WINSUPPORT + +/****************************************************************** +* +* Config defaults +* +******************************************************************* +*/ +// +//Support for 3D effects +// +#ifndef FRAMEWIN_CLIENTCOLOR_DEFAULT + #if WIDGET_USE_FLEX_SKIN + #define FRAMEWIN_CLIENTCOLOR_DEFAULT GUI_WHITE + #else + #define FRAMEWIN_CLIENTCOLOR_DEFAULT GUI_GRAY_C0 + #endif +#endif + +// +// Default for top frame size +// +#ifndef FRAMEWIN_TITLEHEIGHT_DEFAULT + #define FRAMEWIN_TITLEHEIGHT_DEFAULT 0 +#endif + +// +// Default for left/right/top/bottom frame size +// +#ifndef FRAMEWIN_BORDER_DEFAULT + #define FRAMEWIN_BORDER_DEFAULT 3 +#endif + +// +// Default for inner frame size +// +#ifndef FRAMEWIN_IBORDER_DEFAULT + #define FRAMEWIN_IBORDER_DEFAULT 1 +#endif + +// +// Default font +// +#ifndef FRAMEWIN_DEFAULT_FONT + #if WIDGET_USE_FLEX_SKIN + #if WIDGET_USE_SCHEME_SMALL + #define FRAMEWIN_DEFAULT_FONT &GUI_Font13_1 + #elif WIDGET_USE_SCHEME_MEDIUM + #define FRAMEWIN_DEFAULT_FONT &GUI_Font16_1 + #elif WIDGET_USE_SCHEME_LARGE + #define FRAMEWIN_DEFAULT_FONT &GUI_Font24_1 + #endif + #else + #if WIDGET_USE_SCHEME_SMALL + #define FRAMEWIN_DEFAULT_FONT &GUI_Font8_1 + #elif WIDGET_USE_SCHEME_MEDIUM + #define FRAMEWIN_DEFAULT_FONT &GUI_Font13_1 + #elif WIDGET_USE_SCHEME_LARGE + #define FRAMEWIN_DEFAULT_FONT &GUI_Font16_1 + #endif + #endif +#endif + +// +// Default bar color when framewin is active +// +#ifndef FRAMEWIN_BARCOLOR_ACTIVE_DEFAULT + #define FRAMEWIN_BARCOLOR_ACTIVE_DEFAULT GUI_BLUE +#endif + +// +// Default bar color when framewin is inactive +// +#ifndef FRAMEWIN_BARCOLOR_INACTIVE_DEFAULT + #define FRAMEWIN_BARCOLOR_INACTIVE_DEFAULT GUI_DARKGRAY +#endif + +// +// Default frame color +// +#ifndef FRAMEWIN_FRAMECOLOR_DEFAULT + #define FRAMEWIN_FRAMECOLOR_DEFAULT GUI_GRAY_AA +#endif + +// +// Default text color when framewin is active +// +#ifndef FRAMEWIN_TEXTCOLOR_INACTIVE_DEFAULT + #if WIDGET_USE_FLEX_SKIN + #define FRAMEWIN_TEXTCOLOR_INACTIVE_DEFAULT GUI_BLACK + #else + #define FRAMEWIN_TEXTCOLOR_INACTIVE_DEFAULT GUI_WHITE + #endif +#endif + +// +// Default text color when framewin is inactive +// +#ifndef FRAMEWIN_TEXTCOLOR_ACTIVE_DEFAULT + #if WIDGET_USE_FLEX_SKIN + #define FRAMEWIN_TEXTCOLOR_ACTIVE_DEFAULT GUI_BLACK + #else + #define FRAMEWIN_TEXTCOLOR_ACTIVE_DEFAULT GUI_WHITE + #endif +#endif + +// +// Default text alignment +// +#ifndef FRAMEWIN_TEXTALIGN_DEFAULT + #define FRAMEWIN_TEXTALIGN_DEFAULT GUI_TA_LEFT +#endif + +/********************************************************************* +* +* Object definition +* +********************************************************************** +*/ +typedef struct { + unsigned (* pfGetBordersize)(FRAMEWIN_Handle hObj, unsigned Index); + WIDGET_DRAW_ITEM_FUNC * pfDrawSkin; +} FRAMEWIN_SKIN_PRIVATE; + +typedef struct { + const GUI_FONT * pFont; + GUI_COLOR aBarColor[2]; + GUI_COLOR aTextColor[2]; + GUI_COLOR ClientColor; + FRAMEWIN_SKIN_PRIVATE SkinPrivate; + I16 TitleHeight; + I16 BorderSize; + I16 IBorderSize; + I16 TextAlign; +} FRAMEWIN_PROPS; + +typedef struct { + WIDGET Widget; + FRAMEWIN_PROPS Props; + WIDGET_SKIN const * pWidgetSkin; + WIDGET_DRAW_ITEM_FUNC * pfDrawItem; // Only for drawing the title bar... + WM_CALLBACK * cb; + WM_HWIN hClient; + WM_HWIN hMenu; + WM_HWIN hText; + GUI_RECT rRestore; + U16 Flags; + WM_HWIN hFocusedChild; // Handle to focused child .. default none (0) + WM_DIALOG_STATUS * pDialogStatus; + GUI_HOOK * pFirstHook; +} FRAMEWIN_Obj; + +typedef struct { + I16 TitleHeight; + I16 MenuHeight; + GUI_RECT rClient; + GUI_RECT rTitleText; +} FRAMEWIN_POSITIONS; + +/********************************************************************* +* +* Macros for internal use +* +********************************************************************** +*/ +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL + #define FRAMEWIN_INIT_ID(p) (p->Widget.DebugId = FRAMEWIN_ID) +#else + #define FRAMEWIN_INIT_ID(p) +#endif + +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL + FRAMEWIN_Obj * FRAMEWIN_LockH(FRAMEWIN_Handle h); + #define FRAMEWIN_LOCK_H(h) FRAMEWIN_LockH(h) +#else + #define FRAMEWIN_LOCK_H(h) (FRAMEWIN_Obj *)GUI_LOCK_H(h) +#endif + +/********************************************************************* +* +* Public data (internal defaults) +* +********************************************************************** +*/ +extern FRAMEWIN_PROPS FRAMEWIN__DefaultProps; + +extern const WIDGET_SKIN FRAMEWIN__SkinClassic; +extern WIDGET_SKIN FRAMEWIN__Skin; + +extern const WIDGET_SKIN * FRAMEWIN__pSkinDefault; + +/********************************************************************* +* +* Private functions +* +********************************************************************** +*/ +void FRAMEWIN__CalcPositions (FRAMEWIN_Handle hObj, FRAMEWIN_POSITIONS * pPos); +int FRAMEWIN__CalcTitleHeight(FRAMEWIN_Obj * pObj); +void FRAMEWIN__UpdatePositions(FRAMEWIN_Handle hObj); +void FRAMEWIN__UpdateButtons (FRAMEWIN_Handle hObj, int OldHeight, int OldBorderSizeL, int OldBorderSizeR, int OldBorderSizeT); +void FRAMEWIN__GetTitleLimits (FRAMEWIN_Handle hObj, int * pxMin, int * pxMax); +unsigned FRAMEWIN__GetBorderSize (FRAMEWIN_Handle hObj, unsigned Index); + +#endif // GUI_WINSUPPORT +#endif // FRAMEWIN_PRIVATE_H + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/GRAPH.h b/example/GUI/STemWin/inc/GRAPH.h new file mode 100755 index 0000000000..49afdeb32a --- /dev/null +++ b/example/GUI/STemWin/inc/GRAPH.h @@ -0,0 +1,210 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GRAPH.h +Purpose : GRAPH include +--------------------END-OF-HEADER------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef GRAPH_H +#define GRAPH_H + +#include "WM.h" +#include "DIALOG_Intern.h" /* Req. for Create indirect data structure */ +#include "WIDGET.h" + +#if GUI_WINSUPPORT + +#if defined(__cplusplus) + extern "C" { /* Make sure we have C-declarations in C++ programs */ +#endif + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ +#define GRAPH_CI_BK 0 +#define GRAPH_CI_BORDER 1 +#define GRAPH_CI_FRAME 2 +#define GRAPH_CI_GRID 3 + +#define GRAPH_SCALE_CF_HORIZONTAL (0 << 0) +#define GRAPH_SCALE_CF_VERTICAL (1 << 0) + +#define GRAPH_SCALE_SF_HORIZONTAL GRAPH_SCALE_CF_HORIZONTAL +#define GRAPH_SCALE_SF_VERTICAL GRAPH_SCALE_CF_VERTICAL + +#define GRAPH_DRAW_FIRST 0 +#define GRAPH_DRAW_AFTER_BORDER 1 +#define GRAPH_DRAW_LAST 2 + +#define GRAPH_ALIGN_RIGHT (0 << 0) +#define GRAPH_ALIGN_LEFT (1 << 0) + +// +// Creation flags (ExFlags) +// +#define GRAPH_CF_GRID_FIXED_X (1 << 0) +#define GRAPH_CF_AVOID_SCROLLBAR_H (1 << 1) +#define GRAPH_CF_AVOID_SCROLLBAR_V (1 << 2) + +// +// Status flags +// +#define GRAPH_SF_AVOID_SCROLLBAR_H GRAPH_CF_AVOID_SCROLLBAR_H +#define GRAPH_SF_AVOID_SCROLLBAR_V GRAPH_CF_AVOID_SCROLLBAR_V + +/********************************************************************* +* +* Public Types +* +********************************************************************** +*/ +typedef WM_HMEM GRAPH_Handle; +typedef WM_HMEM GRAPH_DATA_Handle; +typedef WM_HMEM GRAPH_SCALE_Handle; + +/********************************************************************* +* +* Create functions +* +********************************************************************** +*/ + +GRAPH_Handle GRAPH_CreateEx (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int WinFlags, int ExFlags, int Id); +GRAPH_Handle GRAPH_CreateUser (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int WinFlags, int ExFlags, int Id, int NumExtraBytes); +GRAPH_Handle GRAPH_CreateIndirect(const GUI_WIDGET_CREATE_INFO * pCreateInfo, WM_HWIN hWinParent, int x0, int y0, WM_CALLBACK * cb); + +GRAPH_DATA_Handle GRAPH_DATA_XY_Create(GUI_COLOR Color, unsigned MaxNumItems, const GUI_POINT * pData, unsigned NumItems); +GRAPH_DATA_Handle GRAPH_DATA_YT_Create(GUI_COLOR Color, unsigned MaxNumItems, const I16 * pData, unsigned NumItems); +GRAPH_SCALE_Handle GRAPH_SCALE_Create (int Pos, int TextAlign, unsigned Flags, unsigned TickDist); + +/********************************************************************* +* +* The callback ... +* +* Do not call it directly ! It is only to be used from within an +* overwritten callback. +*/ +void GRAPH_Callback(WM_MESSAGE * pMsg); + +/********************************************************************* +* +* Member functions +* +********************************************************************** +*/ +void GRAPH_AttachData (GRAPH_Handle hObj, GRAPH_DATA_Handle hData); +void GRAPH_AttachScale (GRAPH_Handle hObj, GRAPH_SCALE_Handle hScale); +void GRAPH_DetachData (GRAPH_Handle hObj, GRAPH_DATA_Handle hData); +void GRAPH_DetachScale (GRAPH_Handle hObj, GRAPH_SCALE_Handle hScale); +I32 GRAPH_GetScrollValue (GRAPH_Handle hObj, U8 Coord); +int GRAPH_GetUserData (GRAPH_Handle hObj, void * pDest, int NumBytes); +void GRAPH_SetAutoScrollbar (GRAPH_Handle hObj, U8 Coord, U8 OnOff); +void GRAPH_SetBorder (GRAPH_Handle hObj, unsigned BorderL, unsigned BorderT, unsigned BorderR, unsigned BorderB); +GUI_COLOR GRAPH_SetColor (GRAPH_Handle hObj, GUI_COLOR Color, unsigned Index); +unsigned GRAPH_SetGridFixedX (GRAPH_Handle hObj, unsigned OnOff); +unsigned GRAPH_SetGridOffY (GRAPH_Handle hObj, unsigned Value); +unsigned GRAPH_SetGridVis (GRAPH_Handle hObj, unsigned OnOff); +unsigned GRAPH_SetGridDistX (GRAPH_Handle hObj, unsigned Value); +unsigned GRAPH_SetGridDistY (GRAPH_Handle hObj, unsigned Value); +U8 GRAPH_SetLineStyleH (GRAPH_Handle hObj, U8 Value); +U8 GRAPH_SetLineStyleV (GRAPH_Handle hObj, U8 Value); +void GRAPH_SetLineStyle (GRAPH_Handle hObj, U8 Value); +void GRAPH_SetScrollValue (GRAPH_Handle hObj, U8 Coord, U32 Value); +unsigned GRAPH_SetVSizeX (GRAPH_Handle hObj, unsigned Value); +unsigned GRAPH_SetVSizeY (GRAPH_Handle hObj, unsigned Value); +int GRAPH_SetUserData (GRAPH_Handle hObj, const void * pSrc, int NumBytes); +void GRAPH_SetUserDraw (GRAPH_Handle hObj, void (* pOwnerDraw)(WM_HWIN, int)); + +void GRAPH_DATA_YT_AddValue (GRAPH_DATA_Handle hDataObj, I16 Value); +void GRAPH_DATA_YT_Clear (GRAPH_DATA_Handle hDataObj); +void GRAPH_DATA_YT_Delete (GRAPH_DATA_Handle hDataObj); +int GRAPH_DATA_YT_GetValue (GRAPH_DATA_Handle hDataObj, I16 * pValue, U32 Index); + +void GRAPH_DATA_YT_SetAlign (GRAPH_DATA_Handle hDataObj, int Align); +void GRAPH_DATA_YT_SetOffY (GRAPH_DATA_Handle hDataObj, int Off); +void GRAPH_DATA_YT_MirrorX (GRAPH_DATA_Handle hDataObj, int OnOff); + +void GRAPH_DATA_XY_AddPoint (GRAPH_DATA_Handle hDataObj, GUI_POINT * pPoint); +void GRAPH_DATA_XY_Clear (GRAPH_DATA_Handle hDataObj); +void GRAPH_DATA_XY_Delete (GRAPH_DATA_Handle hDataObj); +unsigned GRAPH_DATA_XY_GetLineVis (GRAPH_DATA_Handle hDataObj); +int GRAPH_DATA_XY_GetPoint (GRAPH_DATA_Handle hDataObj, GUI_POINT * pPoint, U32 Index); +unsigned GRAPH_DATA_XY_GetPointVis (GRAPH_DATA_Handle hDataObj); +void GRAPH_DATA_XY_SetLineStyle (GRAPH_DATA_Handle hDataObj, U8 LineStyle); +unsigned GRAPH_DATA_XY_SetLineVis (GRAPH_DATA_Handle hDataObj, unsigned OnOff); +void GRAPH_DATA_XY_SetOffX (GRAPH_DATA_Handle hDataObj, int Off); +void GRAPH_DATA_XY_SetOffY (GRAPH_DATA_Handle hDataObj, int Off); +void GRAPH_DATA_XY_SetPenSize (GRAPH_DATA_Handle hDataObj, U8 PenSize); +void GRAPH_DATA_XY_SetPointSize (GRAPH_DATA_Handle hDataObj, unsigned PointSize); +unsigned GRAPH_DATA_XY_SetPointVis (GRAPH_DATA_Handle hDataObj, unsigned OnOff); +void GRAPH_DATA_XY_SetOwnerDraw (GRAPH_DATA_Handle hDataObj, WIDGET_DRAW_ITEM_FUNC * pOwnerDraw); + +void GRAPH_SCALE_Delete (GRAPH_SCALE_Handle hScaleObj); +float GRAPH_SCALE_SetFactor (GRAPH_SCALE_Handle hScaleObj, float Factor); +const GUI_FONT * GRAPH_SCALE_SetFont (GRAPH_SCALE_Handle hScaleObj, const GUI_FONT * pFont); +int GRAPH_SCALE_SetNumDecs (GRAPH_SCALE_Handle hScaleObj, int NumDecs); +int GRAPH_SCALE_SetOff (GRAPH_SCALE_Handle hScaleObj, int Off); +int GRAPH_SCALE_SetPos (GRAPH_SCALE_Handle hScaleObj, int Pos); +GUI_COLOR GRAPH_SCALE_SetTextColor(GRAPH_SCALE_Handle hScaleObj, GUI_COLOR Color); +unsigned GRAPH_SCALE_SetTickDist (GRAPH_SCALE_Handle hScaleObj, unsigned Value); + +#if defined(__cplusplus) + } +#endif + +#endif // GUI_WINSUPPORT +#endif // GRAPH_H + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/GRAPH_Private.h b/example/GUI/STemWin/inc/GRAPH_Private.h new file mode 100755 index 0000000000..7c61a431e9 --- /dev/null +++ b/example/GUI/STemWin/inc/GRAPH_Private.h @@ -0,0 +1,176 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GRAPH_Private.h +Purpose : GRAPH private header file +--------------------END-OF-HEADER------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef GRAPH_PRIVATE_H +#define GRAPH_PRIVATE_H + +#include "GRAPH.h" +#include "GUI_ARRAY.h" +#include "WIDGET.h" + +#if GUI_WINSUPPORT + +/********************************************************************* +* +* Object definition +* +********************************************************************** +*/ +typedef struct GRAPH_OBJ GRAPH_OBJ; +typedef struct GRAPH_DATA_OBJ GRAPH_DATA_OBJ; +typedef struct GRAPH_SCALE_OBJ GRAPH_SCALE_OBJ; +typedef struct GRAPH_PAINT_OBJ GRAPH_PAINT_OBJ; + +struct GRAPH_PAINT_OBJ { + void (* pfOnPaint) (WM_HMEM hObj, GUI_RECT * pRectInvalid); /* Pointer to paint function */ + void (* pfOnDelete) (WM_HMEM hObj); /* Pointer to delete function */ + WM_HWIN hGraph; /* Handle of graph widget */ +}; + +typedef struct { + GUI_COLOR TextColor; + const GUI_FONT * pFont; +} GRAPH_SCALE_PROPS; + +struct GRAPH_SCALE_OBJ { + GRAPH_PAINT_OBJ PaintObj; + GRAPH_SCALE_PROPS Props; + int Pos; + int TextAlign; + unsigned TickDist; + int Off; + U16 Flags; + float Factor; + int NumDecs; +}; + +struct GRAPH_DATA_OBJ { + GRAPH_PAINT_OBJ PaintObj; + void (* pfInvalidateNewItem)(GRAPH_DATA_OBJ * pDataObj); /* Pointer to a function which can be used for invalidating the required area */ + unsigned NumItems; + unsigned MaxNumItems; + GUI_COLOR Color; + int OffX, OffY; +}; + +typedef struct { + GUI_COLOR aColor[4]; + unsigned GridSpacingX; + unsigned GridSpacingY; + unsigned GridOffX; + unsigned GridOffY; + unsigned BorderL; + unsigned BorderT; + unsigned BorderR; + unsigned BorderB; +} GRAPH_PROPS; + +struct GRAPH_OBJ { + WIDGET Widget; + GRAPH_PROPS Props; + GUI_ARRAY GraphArray; + GUI_ARRAY ScaleArray; + U8 ShowGrid; + unsigned RangeX, RangeY; + U16 Flags; + U8 LineStyleV; + U8 LineStyleH; + WM_SCROLL_STATE ScrollStateV; + WM_SCROLL_STATE ScrollStateH; + void (* pUserDraw)(WM_HWIN hObj, int Stage); +}; + +/********************************************************************* +* +* Macros for internal use +* +********************************************************************** +*/ +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL + #define GRAPH_INIT_ID(p) (p->Widget.DebugId = GRAPH_ID) +#else + #define GRAPH_INIT_ID(p) +#endif + +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL + GRAPH_OBJ * GRAPH_LockH(GRAPH_Handle h); + #define GRAPH_LOCK_H(h) GRAPH_LockH(h) +#else + #define GRAPH_LOCK_H(h) (GRAPH_OBJ *)GUI_LOCK_H(h) +#endif + +/********************************************************************* +* +* Public data (internal defaults) +* +********************************************************************** +*/ +extern GRAPH_PROPS GRAPH__DefaultProps; + +/********************************************************************* +* +* Private functions +* +********************************************************************** +*/ +void GRAPH__AddValue (GRAPH_DATA_OBJ * pDataObj, void * pData, void * pValue, int Size); +int GRAPH__GetValue (GRAPH_DATA_OBJ * pDataObj, void * pData, void * pValue, int Size, U32 Index); +void GRAPH__InvalidateGraph(GRAPH_Handle hObj); + +#endif /* GUI_WINSUPPORT */ +#endif /* GRAPH_PRIVATE_H */ + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/GUI.h b/example/GUI/STemWin/inc/GUI.h new file mode 100755 index 0000000000..072a4d0910 --- /dev/null +++ b/example/GUI/STemWin/inc/GUI.h @@ -0,0 +1,2506 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GUI.h +Purpose : GUI API include file +---------------------------END-OF-HEADER------------------------------ +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef GUI_H +#define GUI_H + +#include "GUI_ConfDefaults.h" +#include "GUI_Type.h" +#include "GUI_Version.h" + +#if defined(__cplusplus) +extern "C" { /* Make sure we have C-declarations in C++ programs */ +#endif + +/********************************************************************* +* +* Disable string function warning with newer MSVC versions +*/ +#if defined (_MSC_VER) + #if (_MSC_VER > 1200) + #pragma warning( disable : 4996) + #endif +#endif + +/********************************************************************* +* +* Macros, function replacement +*/ +#define GUI_COUNTOF(a) (sizeof(a) / sizeof(a[0])) +#define GUI_MIN(a,b) (((a) < (b)) ? (a) : (b)) +#define GUI_MAX(a,b) (((a) > (b)) ? (a) : (b)) +#define GUI_ZEROFILL(p, Size) (memset(p, 0, Size)) /**/ + +/********************************************************************* +* +* Support for multitasking systems (locking) +*/ +typedef struct GUI_CONTEXT GUI_CONTEXT; + +#if !GUI_OS + #define GUI_LOCK() + #define GUI_UNLOCK() + #define GUITASK_INIT() + #define GUITASK_COPY_CONTEXT() +#else + void GUI_Lock(void); + void GUI_Unlock(void); + void GUITASK_Init(void); + void GUITASK_CopyContext(void); + void GUITASK_SetMaxTask(int MaxTask); + int GUITASK_GetMaxTask(void); + GUI_CONTEXT * GUITASK_GetpContext(int Index); + #define GUI_LOCK() GUI_Lock() + #define GUI_UNLOCK() GUI_Unlock() + #define GUITASK_INIT() GUITASK_Init() + #define GUITASK_COPY_CONTEXT() GUITASK_CopyContext() +#endif + +/********************************************************************* +* +* API table of a display driver +*/ +struct GUI_DEVICE_API { + // + // Data + // + int DeviceClassIndex; + // + // Drawing functions + // + void (* pfDrawBitmap )(GUI_DEVICE * pDevice, int x0, int y0, int xsize, int ysize, int BitsPerPixel, int BytesPerLine, const U8 * pData, int Diff, const LCD_PIXELINDEX * pTrans); + void (* pfDrawHLine )(GUI_DEVICE * pDevice, int x0, int y0, int x1); + void (* pfDrawVLine )(GUI_DEVICE * pDevice, int x , int y0, int y1); + void (* pfFillRect )(GUI_DEVICE * pDevice, int x0, int y0, int x1, int y1); + LCD_PIXELINDEX (* pfGetPixelIndex)(GUI_DEVICE * pDevice, int x, int y); + void (* pfSetPixelIndex)(GUI_DEVICE * pDevice, int x, int y, LCD_PIXELINDEX ColorIndex); + void (* pfXorPixel )(GUI_DEVICE * pDevice, int x, int y); + // + // Set origin + // + void (* pfSetOrg )(GUI_DEVICE * pDevice, int x, int y); + // + // Request information + // + void (*(* pfGetDevFunc) (GUI_DEVICE ** ppDevice, int Index))(void); + I32 (* pfGetDevProp )(GUI_DEVICE * pDevice, int Index); + void *(* pfGetDevData )(GUI_DEVICE * pDevice, int Index); + void (* pfGetRect )(GUI_DEVICE * pDevice, LCD_RECT * pRect); +}; + +/********************************************************************* +* +* Device classes +*/ +typedef enum { + DEVICE_CLASS_DRIVER = 0, + DEVICE_CLASS_DRIVER_MODIFIER, // Zoom or delta-pixel modifier + DEVICE_CLASS_VNC, + DEVICE_CLASS_SPRITE, + DEVICE_CLASS_MEMDEV, + DEVICE_CLASS_ALPHA, + DEVICE_CLASS_AUTOALPHA, + DEVICE_CLASS_MEASDEV +} DEVICE_CLASS; + +#define GUI_DEVICE_STAYONTOP 1 + +/********************************************************************* +* +* Display drivers +*/ +// +// Addresses +// +extern const GUI_DEVICE_API GUIDRV_Win_API; +extern const GUI_DEVICE_API GUIDRV_Template_API; + +// +// Macros to be used in configuration files +// +#define GUIDRV_WIN32 &GUIDRV_Win_API + +#if defined(WIN32) && !defined(LCD_SIMCONTROLLER) + #define GUIDRV_TEMPLATE &GUIDRV_Win_API +#else + #define GUIDRV_TEMPLATE &GUIDRV_Template_API +#endif + +/********************************************************************* +* +* Definition of GUI_DEVICE structure +*/ +struct GUI_DEVICE { + // + // Linking + // + GUI_DEVICE * pNext; + GUI_DEVICE * pPrev; + // + // Data + // + union { + GUI_HMEM hContext; // Handle of payload data like sprite- or memory device context + void * pContext; // Pointer for context data in a fixed block + } u; + // + // API pointers + // + const GUI_DEVICE_API * pDeviceAPI; + const LCD_API_COLOR_CONV * pColorConvAPI; + U16 Flags; + int LayerIndex; +}; + +extern const GUI_DEVICE_API GUI_MEMDEV_DEVICE_1; +extern const GUI_DEVICE_API GUI_MEMDEV_DEVICE_8; +extern const GUI_DEVICE_API GUI_MEMDEV_DEVICE_16; +extern const GUI_DEVICE_API GUI_MEMDEV_DEVICE_32; + +/********************************************************************* +* +* GUI_CONTEXT +* +* This structure is public for one reason only: +* To allow the application to save and restore the context. +*/ +typedef union { + U8 aColorIndex8[2]; + U16 aColorIndex16[2]; + U32 aColorIndex32[2]; +} LCD_COLORINDEX_UNION; + +struct GUI_CONTEXT { + // + // Variables in LCD module + // + LCD_COLORINDEX_UNION uLCD; + LCD_RECT ClipRect; + U8 DrawMode; + U8 SelLayer; + U8 TextStyle; + // + // Variables in GL module + // + GUI_RECT * pClipRect_HL; // High level clip rectangle ... Speed optimization so drawing routines can optimize + U8 PenSize; + U8 PenShape; + U8 LineStyle; + // + // Variables in GUICHAR module + // + const GUI_FONT * pAFont; + I16P LBorder; + I16P DispPosX, DispPosY; + I16P DrawPosX, DrawPosY; + I16P TextMode, TextAlign; + GUI_COLOR Color, BkColor; // Required only when changing devices and for speed opt (caching) + // + // Pointer to color indices + // + LCD_PIXELINDEX * LCD_pBkColorIndex; + LCD_PIXELINDEX * LCD_pColorIndex; + LCD_PIXELINDEX * LCD_pAColorIndex; + // + // Variables in WM module + // + #if GUI_WINSUPPORT + const GUI_RECT * WM__pUserClipRect; + GUI_HWIN hAWin; + int xOff, yOff; + U8 WM_IsActive; + #endif + // + // Array of pointers to device chains + // + GUI_DEVICE * apDriver[GUI_NUM_LAYERS]; + // + // Variables in MEMDEV module (with memory devices only) + // + GUI_HMEM hDevData; + // + // Variables in Anitaliasing module + // + const tLCD_HL_APIList * pLCD_HL; // Required to reroute drawing (HLine & Pixel) to the AA module + U8 AA_Factor; + U8 AA_HiResEnable; + void (* AA_pfSetPixelAA)(int x, int y, U8 Intens); // Function to be used for drawing a single pixel +}; + +/* Rename GUI_SaveContext in order to avoid crashes if wrong GUIConf is used */ +#if (GUI_WINSUPPORT == 1) + #define GUI_SaveContext GUI_SaveContext_W +#else + #define GUI_SaveContext GUI_SaveContext_ +#endif + +/********************************************************************* +* +* Device management +*/ +GUI_DEVICE * GUI_DEVICE_Create (const GUI_DEVICE_API * pDeviceAPI, const LCD_API_COLOR_CONV * pColorConvAPI, U16 Flags, int LayerIndex); +GUI_DEVICE * GUI_DEVICE_CreateAndLink(const GUI_DEVICE_API * pDeviceAPI, const LCD_API_COLOR_CONV * pColorConvAPI, U16 Flags, int LayerIndex); +void GUI_DEVICE_Delete (GUI_DEVICE * pDevice); +int GUI_DEVICE_Link (GUI_DEVICE * pDevice); +void GUI_DEVICE_Unlink (GUI_DEVICE * pDevice); +GUI_DEVICE * GUI_DEVICE__GetpDriver (int LayerIndex); +GUI_DEVICE * GUI_DEVICE__GetpDevice (int LayerIndex, int DeviceClass); + +GUI_DEVICE * GUI_DEVICE_UnlinkTaskDevices(void); +void GUI_DEVICE_LinkDevices (GUI_DEVICE * pDevice); + +/********************************************************************* +* +* GUI_DIRTYDEVICE +*/ +typedef struct { + void * pData; // Pointer to first pixel + int x0, y0; // Coordinates of the upper left pixel + int xSize, ySize; // Size of dirty rectangle + int LineOff; // Virtual xSize in pixels + int BytesPerPixel; // Number of bytes required per pixel + int IsDirty; // Indicates if dirty pixels exist +} GUI_DIRTYDEVICE_INFO; + +int GUI_DIRTYDEVICE_Create (void); +int GUI_DIRTYDEVICE_CreateEx (int LayerIndex); +int GUI_DIRTYDEVICE_CreateExInfo(GUI_DIRTYDEVICE_INFO * pInfo, int LayerIndex); +int GUI_DIRTYDEVICE_Delete (void); +int GUI_DIRTYDEVICE_DeleteEx (int LayerIndex); +int GUI_DIRTYDEVICE_Fetch (GUI_DIRTYDEVICE_INFO * pInfo); +int GUI_DIRTYDEVICE_FetchEx (GUI_DIRTYDEVICE_INFO * pInfo, int LayerIndex); + +/********************************************************************* +* +* GUI_GCACHE +*/ +int GUI_GCACHE_4_Create(const LCD_API_COLOR_CONV * pColorConvAPI); +int GUI_GCACHE_4_CreateEx(int LayerIndex, const LCD_API_COLOR_CONV * pColorConvAPI); + +/********************************************************************* +* +* GUI_DCACHE +*/ +void GUI_DCACHE_SetClearCacheHook(void (* pFunc)(U32 LayerMask)); +void GUI_DCACHE_Clear (U32 LayerMask); + +extern void (* GUI_DCACHE__pfClearCacheHook)(U32 LayerMask); + +/********************************************************************* +* +* GUI_SOFTLAYER +*/ +typedef struct { + int xPos; + int yPos; + int xSize; + int ySize; + int Visible; +} GUI_SOFTLAYER_CONFIG; + +int GUI_SOFTLAYER_Enable (GUI_SOFTLAYER_CONFIG * pConfig, int NumLayers, GUI_COLOR CompositeColor); +int GUI_SOFTLAYER_Refresh (void); +void GUI_SOFTLAYER_SetCompositeColor(U32 Color); +int GUI_SOFTLAYER_MULTIBUF_Enable (int OnOff); + +/********************************************************************* +* +* General routines +*/ +void GUI_Exit (void); +GUI_COLOR GUI_GetDefaultBkColor(void); +GUI_COLOR GUI_GetDefaultColor (void); +const GUI_FONT * GUI_GetDefaultFont (void); +int GUI_GetScreenSizeX (void); +int GUI_GetScreenSizeY (void); +const char * GUI_GetVersionString (void); +int GUI_Init (void); +int GUI_IsInitialized (void); +void GUI_SetAfterInitHook (void (* pFunc)(void)); +void GUI_RestoreContext (const GUI_CONTEXT * pContext); +void GUI_SaveContext (GUI_CONTEXT * pContext); +const GUI_RECT * GUI_SetClipRect (const GUI_RECT * pRect); +void GUI_SetControlHook (void (* pFunc)(int LayerIndex, int Cmd)); +void GUI_SetDefault (void); +void GUI_SetDefaultBkColor(GUI_COLOR Color); +void GUI_SetDefaultColor (GUI_COLOR Color); +void GUI_SetDefaultFont (const GUI_FONT * pFont); +GUI_DRAWMODE GUI_SetDrawMode (GUI_DRAWMODE dm); +void GUI_SetScreenSizeX (int xSize); +void GUI_SetScreenSizeY (int ySize); +void GUI_SetRefreshHook (void (* pFunc)(void)); +void MainTask (void); + +#define GUI_PID_SetInitFunc(x) GUI_SetAfterInitHook(x) // Compatibility + +/********************************************************************* +* +* Function replacement +*/ +void GUI_SetpfMemset(void * (* pFunc)(void * pDest, int c, unsigned Cnt)); +void GUI_SetpfMemcpy(void * (* pFunc)(void * pDest, const void * pSrc, unsigned Cnt)); + +/********************************************************************* +* +* Rectangle helper functions +*/ +int GUI_RectsIntersect(const GUI_RECT * pr0, const GUI_RECT * pr1); +void GUI_MoveRect (GUI_RECT * pRect, int x, int y); +void GUI_MergeRect (GUI_RECT * pDest, const GUI_RECT * pr0, const GUI_RECT * pr1); +int GUI__IntersectRects(GUI_RECT * pDest, const GUI_RECT * pr0, const GUI_RECT * pr1); +void GUI__IntersectRect (GUI_RECT * pDest, const GUI_RECT * pr0); +void GUI__ReduceRect (GUI_RECT * pDest, const GUI_RECT * pRect, int Dist); + +/********************************************************************* +* +* Misc helper functions +*/ +I32 GUI__ATan2(I32 x, I32 y, I32 * ph); +I32 GUI__ASinHQ(I32 SinHQ); +int GUI__CompactPixelIndices (LCD_PIXELINDEX * pBuffer, int NumPixels, int BitsPerPixel); +int GUI__CompactPixelIndicesEx(LCD_PIXELINDEX * pBuffer, int NumPixels, int BitsPerPixel, const LCD_API_COLOR_CONV * pColorConvAPI); +int GUI__ConvertColor2Index (LCD_PIXELINDEX * pBuffer, int NumPixels, int BitsPerPixel, const LCD_API_COLOR_CONV * pColorConvAPI, void * pResult); +void GUI__Config(void); +I32 GUI__CosHQ(I32 Ang1000); +int GUI__DivideRound (int a, int b); +I32 GUI__DivideRound32 (I32 a, I32 b); +void GUI__ExpandPixelIndices (void * pBuffer, int NumPixels, int BitsPerPixel); +void GUI__ExpandPixelIndicesEx (void * pBuffer, int NumPixels, int BitsPerPixel, const LCD_API_COLOR_CONV * pColorConvAPI); +int GUI__SetText(GUI_HMEM * phText, const char * s); +I32 GUI__SinHQ(I32 Ang1000); +I32 GUI__sqrt32(I32 Square); +void GUI__DrawTwinArc2(int xl, int xr, int y0, int r, GUI_COLOR ColorR0, GUI_COLOR ColorR1, GUI_COLOR ColorFill); +void GUI__DrawTwinArc4(int x0, int y0, int x1, int y1, int r, GUI_COLOR ColorR0, GUI_COLOR ColorR1, GUI_COLOR ColorFill); +void GUI__FillTrippleArc(int x0, int y0, int Size, GUI_COLOR ColorR0, GUI_COLOR ColorR1, GUI_COLOR ColorR2, GUI_COLOR ColorFill); +void GUI__RegisterExit(GUI_REGISTER_EXIT * pRegisterExit); + +/********************************************************************* +* +* Optional function replacement +*/ +void * GUI__memcpy(void * pDest, const void * pSrc, unsigned NumBytes); +void * GUI__memset(void * pDest, int c, unsigned Cnt); + +/********************************************************************* +* +* Get / Set Attributes +*/ +GUI_COLOR GUI_GetBkColor (void); +int GUI_GetBkColorIndex(void); +GUI_COLOR GUI_GetColor (void); +int GUI_GetColorIndex (void); +U8 GUI_GetLineStyle (void); +U8 GUI_GetPenSize (void); +U8 GUI_GetPenShape (void); +unsigned GUI_GetPixelIndex (int x, int y); + +void GUI_SetBkColor (GUI_COLOR); +void GUI_SetColor (GUI_COLOR); +void GUI_SetBkColorIndex(int Index); +void GUI_SetColorIndex(int Index); + +U8 GUI_SetPenSize (U8 Size); +U8 GUI_SetPenShape (U8 Shape); +U8 GUI_SetLineStyle (U8 Style); + +/* Get/Set Character used as decimal point (usually '.' or ',') */ +char GUI_GetDecChar(void); +char GUI_SetDecChar(char c); + +/********************************************************************* +* +* Color / Index related functions +*/ +int GUI_Color2Index(GUI_COLOR color); +GUI_COLOR GUI_Color2VisColor(GUI_COLOR color); +char GUI_ColorIsAvailable(GUI_COLOR color); +GUI_COLOR GUI_Index2Color(int Index); +U32 GUI_CalcColorDist (GUI_COLOR Color0, GUI_COLOR Color1); +U32 GUI_CalcVisColorError(GUI_COLOR color); + +/********************************************************************* +* +* Error handler +*/ +void GUI_SetOnErrorFunc(void (* pFunc)(const char * s)); + +/********************************************************************* +* +* Logging (for debugging primarily) +*/ +void GUI_Log (const char * s); +void GUI_Log1 (const char * s, I32 p0); +void GUI_Log2 (const char * s, I32 p0, I32 p1); +void GUI_Log3 (const char * s, I32 p0, I32 p1, I32 p2); +void GUI_Log4 (const char * s, I32 p0, I32 p1, I32 p2,I32 p3); +void GUI_Warn (const char * s); +void GUI_Warn1 (const char * s, I32 p0); +void GUI_Warn2 (const char * s, I32 p0, I32 p1); +void GUI_Warn3 (const char * s, I32 p0, I32 p1, I32 p2); +void GUI_Warn4 (const char * s, I32 p0, I32 p1, I32 p2, I32 p3); +void GUI_ErrorOut (const char * s); +void GUI_ErrorOut1(const char * s, I32 p0); +void GUI_ErrorOut2(const char * s, I32 p0, I32 p1); +void GUI_ErrorOut3(const char * s, I32 p0, I32 p1, I32 p2); +void GUI_ErrorOut4(const char * s, I32 p0, I32 p1, I32 p2, I32 p3); + +/********************************************************************* +* +* 2d - GL +*/ +void GUI_Clear (void); +void GUI_ClearRect (int x0, int y0, int x1, int y1); +void GUI_ClearRectEx (const GUI_RECT * pRect); +void GUI_CopyRect (int x0, int y0, int x1, int y1, int dx, int dy); +void GUI_DrawArc (int x0, int y0, int rx, int ry, int a0, int a1); +void GUI_DrawBitmap (const GUI_BITMAP * pBM, int x0, int y0); +void GUI_DrawBitmapMag (const GUI_BITMAP * pBM, int x0, int y0, int XMul, int YMul); +void GUI_DrawBitmapEx (const GUI_BITMAP * pBM, int x0, int y0, int xCenter, int yCenter, int xMag, int yMag); +void GUI_DrawBitmapExp (int x0, int y0, int XSize, int YSize, int XMul, int YMul, int BitsPerPixel, int BytesPerLine, const U8 * pData, const GUI_LOGPALETTE * pPal); +void GUI_DrawBitmapHWAlpha(const GUI_BITMAP * pBM, int x0, int y0); +void GUI_DrawCircle (int x0, int y0, int r); +void GUI_DrawEllipse (int x0, int y0, int rx, int ry); +void GUI_DrawGradientH (int x0, int y0, int x1, int y1, GUI_COLOR Color0, GUI_COLOR Color1); +void GUI_DrawGradientV (int x0, int y0, int x1, int y1, GUI_COLOR Color0, GUI_COLOR Color1); +void GUI_DrawGradientRoundedH(int x0, int y0, int x1, int y1, int rd, GUI_COLOR Color0, GUI_COLOR Color1); +void GUI_DrawGradientRoundedV(int x0, int y0, int x1, int y1, int rd, GUI_COLOR Color0, GUI_COLOR Color1); +void GUI_DrawGraph (I16 * pay, int NumPoints, int x0, int y0); +void GUI_DrawGraphEx (I16 * pay, int NumPoints, int x0, int y0, int Numerator, int Denominator, int MirrorX); +void GUI_DrawHLine (int y0, int x0, int x1); +void GUI_DrawLine (int x0, int y0, int x1, int y1); +void GUI_DrawLineRel (int dx, int dy); +void GUI_DrawLineTo (int x, int y); +void GUI_DrawPie (int x0, int y0, int r, int a0, int a1, int Type); +void GUI_DrawPixel (int x, int y); +void GUI_DrawPoint (int x, int y); +void GUI_DrawPolygon (const GUI_POINT * pPoints, int NumPoints, int x0, int y0); +void GUI_DrawPolyLine (const GUI_POINT * pPoints, int NumPoints, int x0, int y0); +void GUI_DrawFocusRect (const GUI_RECT * pRect, int Dist); +void GUI_DrawRect (int x0, int y0, int x1, int y1); +void GUI_DrawRectEx (const GUI_RECT * pRect); +void GUI_DrawRoundedFrame (int x0, int y0, int x1, int y1, int r, int w); +void GUI_DrawRoundedRect (int x0, int y0, int x1, int y1, int r); +void GUI_DrawVLine (int x0, int y0, int y1); +void GUI_FillCircle (int x0, int y0, int r); +void GUI_FillEllipse (int x0, int y0, int rx, int ry); +void GUI_FillPolygon (const GUI_POINT * pPoints, int NumPoints, int x0, int y0); +void GUI_FillRect (int x0, int y0, int x1, int y1); +void GUI_FillRectEx (const GUI_RECT * pRect); +void GUI_FillRoundedFrame (int x0, int y0, int x1, int y1, int r, int w); +void GUI_FillRoundedRect (int x0, int y0, int x1, int y1, int r); +void GUI_FillRoundedRectB (int x0, int y0, int x1, int y1, int r); +void GUI_FillRoundedRectT (int x0, int y0, int x1, int y1, int r); +void GUI_GetClientRect (GUI_RECT * pRect); +void GUI_InvertRect (int x0, int y0, int x1, int y1); +void GUI_MoveRel (int dx, int dy); +void GUI_MoveTo (int x, int y); +void GUI_SetAlphaMask8888 (U32 OrMask, U32 AndMask); + +/********************************************************************* +* +* IMAGE file support +*/ +typedef int GUI_GET_DATA_FUNC(void * p, const U8 ** ppData, unsigned NumBytes, U32 Off); + +/********************************************************************* +* +* GIF file support +*/ +int GUI_GIF_Draw (const void * pGIF, U32 NumBytes, int x0, int y0); +int GUI_GIF_DrawEx (GUI_GET_DATA_FUNC * pfGetData, void * p, int x0, int y0); +int GUI_GIF_DrawSub (const void * pGIF, U32 NumBytes, int x0, int y0, int Index); +int GUI_GIF_DrawSubEx (GUI_GET_DATA_FUNC * pfGetData, void * p, int x0, int y0, int Index); +int GUI_GIF_DrawSubScaled (const void * pGIF, U32 NumBytes, int x0, int y0, int Index, int Num, int Denom); +int GUI_GIF_DrawSubScaledEx(GUI_GET_DATA_FUNC * pfGetData, void * p, int x0, int y0, int Index, int Num, int Denom); +int GUI_GIF_GetComment (const void * pGIF, U32 NumBytes, U8 * pBuffer, int MaxSize, int Index); +int GUI_GIF_GetCommentEx (GUI_GET_DATA_FUNC * pfGetData, void * p, U8 * pBuffer, int MaxSize, int Index); +int GUI_GIF_GetImageInfo (const void * pGIF, U32 NumBytes, GUI_GIF_IMAGE_INFO * pInfo, int Index); +int GUI_GIF_GetImageInfoEx (GUI_GET_DATA_FUNC * pfGetData, void * p, GUI_GIF_IMAGE_INFO * pInfo, int Index); +int GUI_GIF_GetInfo (const void * pGIF, U32 NumBytes, GUI_GIF_INFO * pInfo); +int GUI_GIF_GetInfoEx (GUI_GET_DATA_FUNC * pfGetData, void * p, GUI_GIF_INFO * pInfo); +int GUI_GIF_GetXSize (const void * pGIF); +int GUI_GIF_GetXSizeEx (GUI_GET_DATA_FUNC * pfGetData, void * p); +int GUI_GIF_GetYSize (const void * pGIF); +int GUI_GIF_GetYSizeEx (GUI_GET_DATA_FUNC * pfGetData, void * p); +int GUI_GIF_SetFillTrans (int OnOff); + +/********************************************************************* +* +* BMP file support +*/ +int GUI_BMP_Draw (const void * pFileData, int x0, int y0); +int GUI_BMP_DrawEx (GUI_GET_DATA_FUNC * pfGetData, void * p, int x0, int y0); +int GUI_BMP_DrawScaled (const void * pFileData, int x0, int y0, int Num, int Denom); +int GUI_BMP_DrawScaledEx(GUI_GET_DATA_FUNC * pfGetData, void * p, int x0, int y0, int Num, int Denom); +int GUI_BMP_GetXSize (const void * pFileData); +int GUI_BMP_GetXSizeEx (GUI_GET_DATA_FUNC * pfGetData, void * p); +int GUI_BMP_GetYSize (const void * pFileData); +int GUI_BMP_GetYSizeEx (GUI_GET_DATA_FUNC * pfGetData, void * p); +void GUI_BMP_EnableAlpha (void); +void GUI_BMP_DisableAlpha(void); + +/********************************************************************* +* +* PNG file support +*/ +int GUI_PNG_Draw (const void * pFileData, int DataSize, int x0, int y0); +int GUI_PNG_DrawEx (GUI_GET_DATA_FUNC * pfGetData, void * p, int x0, int y0); +int GUI_PNG_GetXSize (const void * pFileData, int FileSize); +int GUI_PNG_GetXSizeEx(GUI_GET_DATA_FUNC * pfGetData, void * p); +int GUI_PNG_GetYSize (const void * pFileData, int FileSize); +int GUI_PNG_GetYSizeEx(GUI_GET_DATA_FUNC * pfGetData, void * p); + +/********************************************************************* +* +* JPEG file support +*/ +typedef struct { + int XSize; + int YSize; +} GUI_JPEG_INFO; + +int GUI_JPEG_Draw (const void * pFileData, int DataSize, int x0, int y0); +int GUI_JPEG_DrawEx (GUI_GET_DATA_FUNC * pfGetData, void * p, int x0, int y0); +int GUI_JPEG_DrawScaled (const void * pFileData, int DataSize, int x0, int y0, int Num, int Denom); +int GUI_JPEG_DrawScaledEx(GUI_GET_DATA_FUNC * pfGetData, void * p, int x0, int y0, int Num, int Denom); +int GUI_JPEG_GetInfo (const void * pFileData, int DataSize, GUI_JPEG_INFO * pInfo); +int GUI_JPEG_GetInfoEx (GUI_GET_DATA_FUNC * pfGetData, void * p, GUI_JPEG_INFO * pInfo); + +/********************************************************************* +* +* MOVIE file support +*/ +#define GUI_MOVIE_NOTIFICATION_PREDRAW 0 // Immediately before frame is drawn +#define GUI_MOVIE_NOTIFICATION_POSTDRAW 1 // Immediately after a frame is drawn +#define GUI_MOVIE_NOTIFICATION_START 2 // Send when start playing a movie +#define GUI_MOVIE_NOTIFICATION_STOP 3 // Movie has stopped +#define GUI_MOVIE_NOTIFICATION_DELETE 4 // Movie has been deleted + +typedef GUI_HMEM GUI_MOVIE_HANDLE; + +typedef void GUI_MOVIE_FUNC(GUI_MOVIE_HANDLE hMovie, int Notification, U32 CurrentFrame); + +typedef struct { + int xSize; // X-size of images + int ySize; // Y-size of images + int msPerFrame; // Default duration of 1 frame + U32 NumFrames; // Number of frames +} GUI_MOVIE_INFO; + +GUI_MOVIE_HANDLE GUI_MOVIE_Create (const void * pFileData, U32 FileSize, GUI_MOVIE_FUNC * pfNotify); +GUI_MOVIE_HANDLE GUI_MOVIE_CreateEx (GUI_GET_DATA_FUNC * pfGetData, void * pParam, GUI_MOVIE_FUNC * pfNotify); +int GUI_MOVIE_Delete (GUI_MOVIE_HANDLE hMovie); +void GUI_MOVIE_DrawFrame (GUI_MOVIE_HANDLE hMovie, int Index, int x, int y); +U32 GUI_MOVIE_GetFrameIndex(GUI_MOVIE_HANDLE hMovie); +int GUI_MOVIE_GetInfo (const void * pFileData, U32 FileSize, GUI_MOVIE_INFO * pInfo); +int GUI_MOVIE_GetInfoEx (GUI_GET_DATA_FUNC * pfGetData, void * pParam, GUI_MOVIE_INFO * pInfo); +int GUI_MOVIE_GetPos (GUI_MOVIE_HANDLE hMovie, int * pxPos, int * pyPos, int * pxSize, int * pySize); +int GUI_MOVIE_GotoFrame (GUI_MOVIE_HANDLE hMovie, U32 Frame); +int GUI_MOVIE_Pause (GUI_MOVIE_HANDLE hMovie); +int GUI_MOVIE_Play (GUI_MOVIE_HANDLE hMovie); +int GUI_MOVIE_SetPeriod (GUI_MOVIE_HANDLE hMovie, unsigned Period); +int GUI_MOVIE_SetPos (GUI_MOVIE_HANDLE hMovie, int xPos, int yPos); +int GUI_MOVIE_Show (GUI_MOVIE_HANDLE hMovie, int xPos, int yPos, int DoLoop); +int GUI_MOVIE_ShowScaled (GUI_MOVIE_HANDLE hMovie, int xPos, int yPos, int num, int denom, int DoLoop); +/********************************************************************* +* +* Cursor routines +*/ +#define GUI_CURSOR_SHOW 0 +#define GUI_CURSOR_HIDE 1 + +typedef struct { + const GUI_BITMAP * pBitmap; + int xHot; + int yHot; +} GUI_CURSOR; + +typedef struct { + const GUI_BITMAP ** ppBm; + int xHot; + int yHot; + unsigned Period; + const unsigned * pPeriod; + int NumItems; +} GUI_CURSOR_ANIM; + +#if GUI_SUPPORT_CURSOR + int GUI_CURSOR_GetState (void); + int GUI_CURSOR_GetStateEx (int Layer); + void GUI_CURSOR_Hide (void); + void GUI_CURSOR_HideEx (int Layer); + const GUI_CURSOR * GUI_CURSOR_Select (const GUI_CURSOR * pCursor); + const GUI_CURSOR * GUI_CURSOR_SelectEx (const GUI_CURSOR * pCursor, int Layer); + int GUI_CURSOR_SelectAnim (const GUI_CURSOR_ANIM * pCursorAnim); + int GUI_CURSOR_SelectAnimEx (const GUI_CURSOR_ANIM * pCursorAnim, int LayerIndex); + int GUI_CURSOR_SetBitmap (const GUI_BITMAP * pBM); + int GUI_CURSOR_SetBitmapEx (const GUI_BITMAP * pBM, int Layer); + void GUI_CURSOR_SetPosition (int x, int y); + void GUI_CURSOR_SetPositionEx(int xNewPos, int yNewPos, int Layer); + void GUI_CURSOR_Show (void); + void GUI_CURSOR_ShowEx (int Layer); + GUI_HSPRITE GUI_CURSOR__GetSpriteEx (int LayerIndex, int * pxPos, int * pyPos); + void GUI_CURSOR__SetSpriteEx (GUI_HSPRITE hSprite, const GUI_CURSOR * pCursor, int LayerIndex); +#else + #define GUI_CURSOR_Show(); + #define GUI_CURSOR_Clear(); +#endif + +/********************************************************************* +* +* Sprite support +*/ +#define GUI_SPRITE_CF_STAYONTOP (1 << 0) +#define GUI_SPRITE_CF_SHOW (1 << 1) + +#define GUI_SPRITE_SHOW 0 +#define GUI_SPRITE_HIDE 1 + +GUI_HSPRITE GUI_SPRITE__CreateEx (const GUI_BITMAP * pBM, int x, int y, int Layer, U16 Flags); /* Not to be documented, only used by cursor modul */ +void GUI_SPRITE__SetCallback (GUI_HSPRITE hSprite, GUI_HMEM hContext, void (* pCB)(GUI_HSPRITE, int)); +GUI_HSPRITE GUI_SPRITE_Create (const GUI_BITMAP * pBM, int x, int y); +GUI_HSPRITE GUI_SPRITE_CreateAnim (const GUI_BITMAP ** ppBm, int x, int y, unsigned Period, const unsigned * pPeriod, int NumItems); +GUI_HSPRITE GUI_SPRITE_CreateEx (const GUI_BITMAP * pBM, int x, int y, int Layer); +GUI_HSPRITE GUI_SPRITE_CreateExAnim (const GUI_BITMAP ** ppBm, int x, int y, unsigned Period, const unsigned * pPeriod, int NumItems, int LayerIndex); +GUI_HSPRITE GUI_SPRITE_CreateHidden (const GUI_BITMAP * pBM, int x, int y); +GUI_HSPRITE GUI_SPRITE_CreateHiddenEx (const GUI_BITMAP * pBM, int x, int y, int Layer); +void GUI_SPRITE_Delete (GUI_HSPRITE hSprite); +int GUI_SPRITE_GetState (GUI_HSPRITE hSprite); +void GUI_SPRITE_Hide (GUI_HSPRITE hSprite); +int GUI_SPRITE_SetBitmap (GUI_HSPRITE hSprite, const GUI_BITMAP * pBM); +int GUI_SPRITE_SetBitmapAndPosition(GUI_HSPRITE hSprite, const GUI_BITMAP * pBM, int x, int y); +int GUI_SPRITE_SetLoop (GUI_HSPRITE hSprite, int OnOff); +void GUI_SPRITE_SetPosition (GUI_HSPRITE hSprite, int x, int y); +int GUI_SPRITE_StartAnim (GUI_HSPRITE hSprite); +int GUI_SPRITE_StopAnim (GUI_HSPRITE hSprite); +void GUI_SPRITE_Show (GUI_HSPRITE hSprite); + +/********************************************************************* +* +* Cursors and their bitmaps +*/ +extern GUI_CONST_STORAGE GUI_CURSOR GUI_CursorArrowS, GUI_CursorArrowSI; +extern GUI_CONST_STORAGE GUI_CURSOR GUI_CursorArrowM, GUI_CursorArrowMI; +extern GUI_CONST_STORAGE GUI_CURSOR GUI_CursorArrowL, GUI_CursorArrowLI; +extern GUI_CONST_STORAGE GUI_CURSOR GUI_CursorCrossS, GUI_CursorCrossSI; +extern GUI_CONST_STORAGE GUI_CURSOR GUI_CursorCrossM, GUI_CursorCrossMI; +extern GUI_CONST_STORAGE GUI_CURSOR GUI_CursorCrossL, GUI_CursorCrossLI; +extern GUI_CONST_STORAGE GUI_CURSOR GUI_CursorHeaderM, GUI_CursorHeaderMI; +extern GUI_CONST_STORAGE GUI_CURSOR_ANIM GUI_CursorAnimHourglassM; + +/********************************************************************* +* +* Wrap modes +*/ +typedef enum { GUI_WRAPMODE_NONE, GUI_WRAPMODE_WORD, GUI_WRAPMODE_CHAR } GUI_WRAPMODE; + +/********************************************************************* +* +* Text related routines +*/ +void GUI_DispCEOL (void); +void GUI_DispChar (U16 c); +void GUI_DispCharAt (U16 c, I16P x, I16P y); +void GUI_DispChars (U16 c, int Cnt); +void GUI_DispNextLine (void); +void GUI_DispString (const char * s); +void GUI_DispStringAt (const char * s, int x, int y); +void GUI_DispStringAtCEOL (const char * s, int x, int y); +void GUI_DispStringHCenterAt (const char * s, int x, int y); +void GUI__DispStringInRect (const char * s, GUI_RECT * pRect, int TextAlign, int MaxNumChars); +void GUI_DispStringInRect (const char * s, GUI_RECT * pRect, int TextAlign); +#if GUI_SUPPORT_ROTATION + void GUI_DispStringInRectEx (const char * s, GUI_RECT * pRect, int TextAlign, int MaxLen, const GUI_ROTATION * pLCD_Api); +#endif +void GUI_DispStringInRectMax (const char * s, GUI_RECT * pRect, int TextAlign, int MaxLen); /* Not to be doc. */ +void GUI_DispStringInRectWrap (const char * s, GUI_RECT * pRect, int TextAlign, GUI_WRAPMODE WrapMode); /* Not to be doc. */ +void GUI_DispStringLen (const char * s, int Len); +void GUI_GetTextExtend (GUI_RECT* pRect, const char * s, int Len); +int GUI_GetYAdjust (void); +int GUI_GetDispPosX (void); +int GUI_GetDispPosY (void); +const GUI_FONT * GUI_GetFont(void); +int GUI_GetCharDistX (U16 c); +int GUI_GetCharDistXEx (U16 c, int * pSizeX); +int GUI_GetStringDistX (const char * s); +GUI_DRAWMODE GUI_GetDrawMode (void); +int GUI_GetFontDistY (void); +int GUI_GetFontSizeY (void); +void GUI_GetFontInfo (const GUI_FONT * pFont, GUI_FONTINFO * pfi); +void GUI_GetOrg (int * px, int * py); +int GUI_GetYSizeOfFont (const GUI_FONT * pFont); +int GUI_GetYDistOfFont (const GUI_FONT * pFont); +int GUI_GetTextAlign (void); +int GUI_GetTextMode (void); +char GUI_IsInFont (const GUI_FONT * pFont, U16 c); +int GUI_SetTextAlign (int Align); +int GUI_SetTextMode (int Mode); +char GUI_SetTextStyle (char Style); +int GUI_SetLBorder (int x); +const GUI_FONT * GUI_SetFont(const GUI_FONT * pNewFont); +char GUI_GotoXY (int x, int y); +char GUI_GotoX (int x); +char GUI_GotoY (int y); +int GUI_WrapGetNumLines (const char * pText, int xSize, GUI_WRAPMODE WrapMode); +int GUI_WrapGetPositions (const char * pText, int xSize, GUI_WRAPMODE WrapMode, int * aPos, int NumItems); +void GUI_WrapSetSeparators (const U16 * pSep, int NumSeps); + +int GUI_GetLeadingBlankCols (U16 c); +int GUI_GetTrailingBlankCols(U16 c); + + +/********************************************************************* +* +* System independent fonts (SIF) +*/ +void GUI_SIF_CreateFont(const void * pFontData, GUI_FONT * pFont, const GUI_SIF_TYPE * pFontType); +void GUI_SIF_DeleteFont(GUI_FONT * pFont); + +/********************************************************************* +* +* External binary fonts (XBF) +*/ +int GUI_XBF_CreateFont(GUI_FONT * pFont, GUI_XBF_DATA * pXBF, const GUI_XBF_TYPE * pFontType, GUI_XBF_GET_DATA_FUNC * pfGetData, void * pVoid); +void GUI_XBF_DeleteFont(GUI_FONT * pFont); + +/********************************************************************* +* +* TrueType support (TTF) +*/ +int GUI_TTF_CreateFont (GUI_FONT * pFont, GUI_TTF_CS * pCS); +int GUI_TTF_CreateFontAA (GUI_FONT * pFont, GUI_TTF_CS * pCS); +void GUI_TTF_DestroyCache (void); +void GUI_TTF_Done (void); +int GUI_TTF_GetFamilyName(GUI_FONT * pFont, char * pBuffer, int NumBytes); +int GUI_TTF_GetStyleName (GUI_FONT * pFont, char * pBuffer, int NumBytes); +void GUI_TTF_SetCacheSize (unsigned MaxFaces, unsigned MaxSizes, U32 MaxBytes); + +/********************************************************************* +* +* Resource file support +*/ +int GUI_LANG_GetLang (void); +int GUI_LANG_GetNumItems (int IndexLang); +const char * GUI_LANG_GetText (int IndexText); +int GUI_LANG_GetTextBuffered (int IndexText, char * pBuffer, int SizeOfBuffer); +int GUI_LANG_GetTextBufferedEx(int IndexText, int IndexLang, char * pBuffer, int SizeOfBuffer); +const char * GUI_LANG_GetTextEx (int IndexText, int IndexLang); +int GUI_LANG_LoadCSV (U8 * pFileData, U32 FileSize); +int GUI_LANG_LoadCSVEx (GUI_GET_DATA_FUNC * pfGetData, void * p); +int GUI_LANG_LoadText (U8 * pFileData, U32 FileSize, int IndexLang); +int GUI_LANG_LoadTextEx (GUI_GET_DATA_FUNC * pfGetData, void * p, int IndexLang); +int GUI_LANG_SetLang (int IndexLang); +unsigned GUI_LANG_SetMaxNumLang (unsigned MaxNumLang); +U16 GUI_LANG_SetSep (U16 Sep); + +/********************************************************************* +* +* Unicode support +*/ +int GUI_UC_ConvertUC2UTF8(const U16 * s, int Len, char * pBuffer, int BufferSize); +int GUI_UC_ConvertUTF82UC(const char * s, int Len, U16 * pBuffer, int BufferSize); +int GUI_UC_EnableBIDI (int OnOff); +int GUI_UC_Encode (char * s, U16 Char); +int GUI_UC_GetCharSize (const char * s); +U16 GUI_UC_GetCharCode (const char * s); +void GUI_UC_SetEncodeNone (void); +void GUI_UC_SetEncodeUTF8 (void); +void GUI_UC_SetBaseDir (int Dir); // Only available with new version of BIDI algorithm +int GUI_UC_GetBaseDir (void); // Only available with new version of BIDI algorithm + +void GUI_UC_DispString(const U16 * s); +void GUI_UC2DB (U16 Code, U8 * pOut); +U16 GUI_DB2UC (U8 Byte0, U8 Byte1); + +/********************************************************************* +* +* Bidi support +*/ +#define GUI_BIDI_BASEDIR_LTR 0 +#define GUI_BIDI_BASEDIR_RTL 1 +#define GUI_BIDI_BASEDIR_AUTO 2 + +/********************************************************************* +* +* Drawing of binary, decimal and hexadecimal values +*/ +void GUI_DispBin (U32 v, U8 Len); +void GUI_DispBinAt(U32 v, I16P x, I16P y, U8 Len); +void GUI_DispDec (I32 v, U8 Len); +void GUI_DispDecAt (I32 v, I16P x, I16P y, U8 Len); +void GUI_DispDecMin(I32 v); +void GUI_DispDecShift(I32 v, U8 Len, U8 Shift); +void GUI_DispDecSpace(I32 v, U8 MaxDigits); +void GUI_DispHex (U32 v, U8 Len); +void GUI_DispHexAt(U32 v, I16P x, I16P y, U8 Len); +void GUI_DispSDec(I32 v, U8 Len); +void GUI_DispSDecShift(I32 v, U8 Len, U8 Shift); + +/********************************************************************* +* +* Drawing of floating point values +*/ +void GUI_DispFloat (float v, char Len); +void GUI_DispFloatFix (float v, char Len, char Fract); +void GUI_DispFloatMin (float v, char Fract); +void GUI_DispSFloatFix(float v, char Len, char Fract); +void GUI_DispSFloatMin(float v, char Fract); + +/********************************************************************* +* +* Dynamic memory management +*/ +typedef struct { + U32 TotalBytes; + U32 FreeBytes; + U32 UsedBytes; + U32 AllocSize; + U32 NumFixedBytes; + U32 MaxUsedBytes; +} GUI_ALLOC_INFO; + +GUI_ALLOC_DATATYPE GUI_ALLOC_GetNumFreeBlocks(void); +GUI_ALLOC_DATATYPE GUI_ALLOC_GetNumFreeBytes (void); +GUI_ALLOC_DATATYPE GUI_ALLOC_GetNumUsedBlocks(void); +GUI_ALLOC_DATATYPE GUI_ALLOC_GetNumUsedBytes (void); +GUI_ALLOC_DATATYPE GUI_ALLOC_GetMaxUsedBytes (void); + +void GUI_ALLOC_GetMemInfo (GUI_ALLOC_INFO * pInfo); +void GUI_ALLOC_SuppressPeak(int OnOff); + +GUI_HMEM GUI_ALLOC_AllocInit (const void * pInitData, GUI_ALLOC_DATATYPE Size); +GUI_HMEM GUI_ALLOC_AllocNoInit (GUI_ALLOC_DATATYPE size); +GUI_HMEM GUI_ALLOC_AllocZero (GUI_ALLOC_DATATYPE size); +void GUI_ALLOC_AssignMemory (void * p, U32 NumBytes); +void GUI_ALLOC_Free (GUI_HMEM hMem); +void GUI_ALLOC_FreeFixedBlock (void * p); +void GUI_ALLOC_FreePtrArray (GUI_HMEM * pArray, int NumElems); +void GUI_ALLOC_FreePtr (GUI_HMEM * phMem); +void * GUI_ALLOC_GetFixedBlock (GUI_ALLOC_DATATYPE Size); +GUI_ALLOC_DATATYPE GUI_ALLOC_GetMaxSize (void); +GUI_ALLOC_DATATYPE GUI_ALLOC_GetSize (GUI_HMEM hMem); +void * GUI_ALLOC_h2p (GUI_HMEM hMem); +GUI_HMEM GUI_ALLOC_p2h (void * p); +void GUI_ALLOC_Init (void); +void GUI_ALLOC_Lock (void); +void * GUI_ALLOC_LockH (GUI_HMEM hMem); +GUI_HMEM GUI_ALLOC_Realloc (GUI_HMEM hOld, int NewSize); +GUI_ALLOC_DATATYPE GUI_ALLOC_RequestSize (void); +void GUI_ALLOC_SetAvBlockSize (U32 BlockSize); +void GUI_ALLOC_Unlock (void); +void * GUI_ALLOC_UnlockH (void ** pp); +int GUI_ALLOC_SetMaxPercentage(int MaxPercentage); +void GUI_ALLOC_Exit (void); + +/********************************************************************* +* +* Memory devices: GUI_MEMDEV +*/ +#define GUI_MEMDEV_HASTRANS 0 +#define GUI_MEMDEV_NOTRANS (1 << 0) + +typedef GUI_HMEM GUI_MEMDEV_Handle; +typedef void GUI_CALLBACK_VOID_P (void * p); +typedef int GUI_ANIMATION_CALLBACK_FUNC(int TimeRem, void * pVoid); +typedef void GUI_DRAWMEMDEV_16BPP_FUNC (void * pDst, const void * pSrc, int xSize, int ySize, int BytesPerLineDst, int BytesPerLineSrc); + +#define GUI_DRAWMEMDEV_FUNC GUI_DRAWMEMDEV_16BPP_FUNC + +typedef void GUI_DRAWBITMAP_FUNC (int LayerIndex, int x, int y, const void * p, int xSize, int ySize, int BytesPerLine); + +int GUI_SetFuncDrawAlpha(GUI_DRAWMEMDEV_FUNC * pfDrawMemdevFunc, GUI_DRAWBITMAP_FUNC * pfDrawBitmapFunc); +int GUI_SetFuncDrawM565 (GUI_DRAWMEMDEV_FUNC * pfDrawMemdevFunc, GUI_DRAWBITMAP_FUNC * pfDrawBitmapFunc); + +extern GUI_ANIMATION_CALLBACK_FUNC * GUI_MEMDEV__pCbAnimation; +extern void * GUI_MEMDEV__pVoid; + +extern void (* GUI_MEMDEV__pfMEMDEV_Write) (GUI_MEMDEV_Handle hMem); +extern void (* GUI_MEMDEV__pfMEMDEV_CopyToLCD)(GUI_MEMDEV_Handle hMem); + +typedef struct { + GUI_RECT rView, rPrev; + char FirstCall; +} GUI_AUTODEV; + +typedef struct { + char DrawFixed; + char IsMeasurement; +} GUI_AUTODEV_INFO; + +int GUI_MEMDEV_CreateAuto(GUI_AUTODEV * pAutoDev); +void GUI_MEMDEV_DeleteAuto(GUI_AUTODEV * pAutoDev); +int GUI_MEMDEV_DrawAuto (GUI_AUTODEV * pAutoDev, GUI_AUTODEV_INFO * pAutoDevInfo, GUI_CALLBACK_VOID_P * pfDraw, void * pData); + +/* Create a memory device which is compatible to the selected LCD */ +GUI_MEMDEV_Handle GUI_MEMDEV_Create (int x0, int y0, int xSize, int ySize); +GUI_MEMDEV_Handle GUI_MEMDEV_CreateEx (int x0, int y0, int xSize, int ySize, int Flags); +GUI_MEMDEV_Handle GUI_MEMDEV_CreateFixed (int x0, int y0, int xSize, int ySize, int Flags, + const GUI_DEVICE_API * pDeviceAPI, + const LCD_API_COLOR_CONV * pColorConvAPI); +GUI_MEMDEV_Handle GUI_MEMDEV_CreateFixed32(int x0, int y0, int xSize, int ySize); + +void GUI_MEMDEV_Clear (GUI_MEMDEV_Handle hMem); +int GUI_MEMDEV_ClearAlpha (GUI_MEMDEV_Handle hMemData, GUI_MEMDEV_Handle hMemMask); +void GUI_MEMDEV_CopyFromLCD (GUI_MEMDEV_Handle hMem); +void GUI_MEMDEV_CopyFromLCDAA (GUI_MEMDEV_Handle hMem); +void GUI_MEMDEV_CopyToLCD (GUI_MEMDEV_Handle hMem); +void GUI_MEMDEV_CopyToLCDAA (GUI_MEMDEV_Handle hMem); +void GUI_MEMDEV_CopyToLCDAt (GUI_MEMDEV_Handle hMem, int x, int y); +int GUI_MEMDEV_CompareWithLCD (GUI_MEMDEV_Handle hMem, int * px, int * py, int * pExp, int * pAct); +void GUI_MEMDEV_Delete (GUI_MEMDEV_Handle MemDev); +void GUI_MEMDEV_DrawPerspectiveX (GUI_MEMDEV_Handle hMem, int x, int y, int h0, int h1, int dx, int dy); +int GUI_MEMDEV_GetXPos (GUI_MEMDEV_Handle hMem); +int GUI_MEMDEV_GetXSize (GUI_MEMDEV_Handle hMem); +int GUI_MEMDEV_GetYPos (GUI_MEMDEV_Handle hMem); +int GUI_MEMDEV_GetYSize (GUI_MEMDEV_Handle hMem); +void GUI_MEMDEV_MarkDirty (GUI_MEMDEV_Handle hMem, int x0, int y0, int x1, int y1); +void GUI_MEMDEV_ReduceYSize (GUI_MEMDEV_Handle hMem, int YSize); +void GUI_MEMDEV_Rotate (GUI_MEMDEV_Handle hSrc, GUI_MEMDEV_Handle hDst, int dx, int dy, int a, int Mag); +void GUI_MEMDEV_RotateAlpha (GUI_MEMDEV_Handle hSrc, GUI_MEMDEV_Handle hDst, int dx, int dy, int a, int Mag, U8 Alpha); +void GUI_MEMDEV_RotateHR (GUI_MEMDEV_Handle hSrc, GUI_MEMDEV_Handle hDst, I32 dx, I32 dy, int a, int Mag); +void GUI_MEMDEV__Rotate (GUI_MEMDEV_Handle hSrc, GUI_MEMDEV_Handle hDst, int dx, int dy, int a, int Mag, U32 Mask); +void GUI_MEMDEV__RotateHR (GUI_MEMDEV_Handle hSrc, GUI_MEMDEV_Handle hDst, I32 dx, I32 dy, int a, int Mag, U32 Mask); +void GUI_MEMDEV_RotateHQ (GUI_MEMDEV_Handle hSrc, GUI_MEMDEV_Handle hDst, int dx, int dy, int a, int Mag); +void GUI_MEMDEV_RotateHQAlpha (GUI_MEMDEV_Handle hSrc, GUI_MEMDEV_Handle hDst, int dx, int dy, int a, int Mag, U8 Alpha); +void GUI_MEMDEV_RotateHQHR (GUI_MEMDEV_Handle hSrc, GUI_MEMDEV_Handle hDst, I32 dx, I32 dy, int a, int Mag); +void GUI_MEMDEV_RotateHQT (GUI_MEMDEV_Handle hSrc, GUI_MEMDEV_Handle hDst, int dx, int dy, int a, int Mag); +void GUI_MEMDEV_RotateHQTI (GUI_MEMDEV_Handle hSrc, GUI_MEMDEV_Handle hDst, int dx, int dy, int a, int Mag); +GUI_MEMDEV_Handle GUI_MEMDEV_Select (GUI_MEMDEV_Handle hMem); /* Select (activate) a particular memory device. */ +void GUI_MEMDEV_SetOrg (GUI_MEMDEV_Handle hMem, int x0, int y0); +void GUI_MEMDEV_WriteAt (GUI_MEMDEV_Handle hMem, int x, int y); +void GUI_MEMDEV_Write (GUI_MEMDEV_Handle hMem); +void GUI_MEMDEV_WriteAlphaAt (GUI_MEMDEV_Handle hMem, int Alpha, int x, int y); +void GUI_MEMDEV_WriteAlpha (GUI_MEMDEV_Handle hMem, int Alpha); +void GUI_MEMDEV_WriteExAt (GUI_MEMDEV_Handle hMem, int x, int y, int xMag, int yMag, int Alpha); +void GUI_MEMDEV_WriteEx (GUI_MEMDEV_Handle hMem, int xMag, int yMag, int Alpha); +void GUI_MEMDEV_WriteOpaque (GUI_MEMDEV_Handle hMem); +void GUI_MEMDEV_WriteOpaqueAt (GUI_MEMDEV_Handle hMem, int x, int y); +int GUI_MEMDEV_Draw (GUI_RECT * pRect, GUI_CALLBACK_VOID_P * pfDraw, void * pData, int NumLines, int Flags); +void* GUI_MEMDEV_GetDataPtr (GUI_MEMDEV_Handle hMem); +void GUI_MEMDEV_SetColorConv (GUI_MEMDEV_Handle hMem, const LCD_API_COLOR_CONV * pColorConvAPI); +const LCD_API_COLOR_CONV * GUI_MEMDEV_GetColorConv(GUI_MEMDEV_Handle hMemDev); +int GUI_MEMDEV_GetBitsPerPixel (GUI_MEMDEV_Handle hMemDev); +int GUI_MEMDEV_FadeInDevices (GUI_MEMDEV_Handle hMem0, GUI_MEMDEV_Handle hMem1, int Period); +int GUI_MEMDEV_FadeOutDevices (GUI_MEMDEV_Handle hMem0, GUI_MEMDEV_Handle hMem1, int Period); +void GUI_MEMDEV_SerializeBMP (GUI_MEMDEV_Handle hDev, GUI_CALLBACK_VOID_U8_P * pfSerialize, void * p); +void GUI_MEMDEV_SetAnimationCallback(GUI_ANIMATION_CALLBACK_FUNC * pCbAnimation, void * pVoid); +void GUI_MEMDEV__FadeDevice (GUI_MEMDEV_Handle hMemWin, GUI_MEMDEV_Handle hMemBk, GUI_MEMDEV_Handle hMemDst, U8 Intens); +void GUI_MEMDEV__FadeDeviceEx (GUI_MEMDEV_Handle hMemWin, GUI_MEMDEV_Handle hMemBk, GUI_MEMDEV_Handle hMemDst, U8 Intens, int xPosWin, int yPosWin); +int GUI_MEMDEV_PunchOutDevice (GUI_MEMDEV_Handle hMemData, GUI_MEMDEV_Handle hMemMask); +void GUI_MEMDEV_SetTimePerFrame (unsigned TimePerFrame); +int GUI_MEMDEV_MULTIBUF_Enable (int OnOff); + +void GUI_SelectLCD(void); + +/* Blurring, dithering and blending */ +GUI_MEMDEV_Handle GUI_MEMDEV_CreateBlurredDevice32 (GUI_MEMDEV_Handle hMem, U8 Depth); +GUI_MEMDEV_Handle GUI_MEMDEV_CreateBlurredDevice32HQ(GUI_MEMDEV_Handle hMem, U8 Depth); +GUI_MEMDEV_Handle GUI_MEMDEV_CreateBlurredDevice32LQ(GUI_MEMDEV_Handle hMem, U8 Depth); +void GUI_MEMDEV_SetBlurHQ (void); +void GUI_MEMDEV_SetBlurLQ (void); +int GUI_MEMDEV_BlendColor32 (GUI_MEMDEV_Handle hMem, U32 BlendColor, U8 BlendIntens); +int GUI_MEMDEV_Dither32 (GUI_MEMDEV_Handle hMem, const LCD_API_COLOR_CONV * pColorConvAPI); + +/* Optional custom drawing of 16bpp memory devices */ +void GUI_MEMDEV_SetDrawMemdev16bppFunc(GUI_DRAWMEMDEV_16BPP_FUNC * pfDrawMemdev16bppFunc); + +/********************************************************************* +* +* Alpha blending +*/ +typedef struct { + U32 UserAlpha; +} GUI_ALPHA_STATE; + +#define GUI_MAKE_ALPHA(Alpha, Color) ((U32)(((U32)Alpha << 24) | (Color & 0xFFFFFF))) + +unsigned GUI_EnableAlpha (unsigned OnOff); +U32 GUI_RestoreUserAlpha (GUI_ALPHA_STATE * pAlphaState); +unsigned GUI_SetAlpha (U8 Alpha); +U32 GUI_SetUserAlpha (GUI_ALPHA_STATE * pAlphaState, U32 UserAlpha); +void (* GUI_SetFuncAlphaBlending(void (* pfAlphaBlending)(LCD_COLOR *, LCD_COLOR *, LCD_COLOR *, U32))) + (LCD_COLOR *, LCD_COLOR *, LCD_COLOR *, U32); +LCD_COLOR (* GUI_SetFuncMixColors (LCD_COLOR (* pFunc)(LCD_COLOR Color, LCD_COLOR BkColor, U8 Intens))) + (LCD_COLOR Color, LCD_COLOR BkColor, U8 Intens); +void (* GUI_SetFuncMixColorsBulk(void (* pFunc)(U32 * pFG, U32 * pBG, U32 * pDst, unsigned OffFG, unsigned OffBG, unsigned OffDest, unsigned xSize, unsigned ySize, U8 Intens))) + (U32 * pFG, U32 * pBG, U32 * pDst, unsigned OffFG, unsigned OffBG, unsigned OffDest, unsigned xSize, unsigned ySize, U8 Intens); +unsigned GUI_PreserveTrans (unsigned OnOff); + +/********************************************************************* +* +* Multi layer support +*/ +unsigned GUI_SelectLayer(unsigned Index); +unsigned GUI_GetSelLayer(void); + +int GUI_SetLayerPosEx (unsigned Index, int xPos, int yPos); +int GUI_SetLayerSizeEx (unsigned Index, int xSize, int ySize); +int GUI_SetLayerVisEx (unsigned Index, int OnOff); +int GUI_SetLayerAlphaEx(unsigned Index, int Alpha); +int GUI_GetLayerPosEx (unsigned Index, int * pxPos, int * pyPos); + +void GUI_AssignCursorLayer(unsigned Index, unsigned CursorLayer); +unsigned GUI_GetCursorLayer (unsigned Index); + +/********************************************************************* +* +* Multiple buffers and display origin +*/ +void GUI_SetOrg(int x, int y); + +void GUI_MULTIBUF_Begin (void); +void GUI_MULTIBUF_BeginEx (int LayerIndex); +void GUI_MULTIBUF_End (void); +void GUI_MULTIBUF_EndEx (int LayerIndex); +void GUI_MULTIBUF_Config (int NumBuffers); +void GUI_MULTIBUF_ConfigEx (int LayerIndex, int NumBuffers); +void GUI_MULTIBUF_Confirm (int Index); +void GUI_MULTIBUF_ConfirmEx (int LayerIndex, int BufferIndex); +int GUI_MULTIBUF_GetNumBuffers (void); +int GUI_MULTIBUF_GetNumBuffersEx(int LayerIndex); +void GUI_MULTIBUF_SetLayerMask (U32 LayerMask); +void GUI_MULTIBUF_UseSingleBuffer(void); + +/********************************************************************* +* +* emWinSPY +*/ +int GUI_SPY_Process (GUI_tSend pfSend, GUI_tRecv pfRecv, void * pConnectInfo); +void GUI_SPY_SetMemHandler(GUI_tMalloc pMalloc, GUI_tFree pFree); +int GUI_SPY_StartServer (void); +int GUI_SPY_X_StartServer(void); + +/********************************************************************* +* +* QR-Codes +*/ +#define GUI_QR_ECLEVEL_L 0 +#define GUI_QR_ECLEVEL_M 1 +#define GUI_QR_ECLEVEL_Q 2 +#define GUI_QR_ECLEVEL_H 3 + +typedef struct { + int Version; // Version according to QR code documentation + int Width; // Number of 'Modules' + int Size; // Size of bitmap in pixels +} GUI_QR_INFO; + +GUI_HMEM GUI_QR_Create (const char * pText, int PixelSize, int EccLevel, int Version); +void GUI_QR_Draw (GUI_HMEM hQR, int xPos, int yPos); +void GUI_QR_GetInfo(GUI_HMEM hQR, GUI_QR_INFO * pInfo); +void GUI_QR_Delete (GUI_HMEM hQR); + +/********************************************************************* +* +* Basics for animations +*/ +#define ANIM_LINEAR GUI_ANIM__Linear +#define ANIM_ACCEL GUI_ANIM__Accel +#define ANIM_DECEL GUI_ANIM__Decel +#define ANIM_ACCELDECEL GUI_ANIM__AccelDecel + +#define GUI_ANIM_START 0 +#define GUI_ANIM_RUNNING 1 +#define GUI_ANIM_END 2 + +#ifndef GUI_ANIM_RANGE + #define GUI_ANIM_RANGE 32767L +#endif + +typedef GUI_HMEM GUI_ANIM_HANDLE; + +typedef I32 (* GUI_ANIM_GETPOS_FUNC)(GUI_TIMER_TIME ts, GUI_TIMER_TIME te, GUI_TIMER_TIME tNow); + +typedef struct { + int Pos; + int State; + GUI_ANIM_HANDLE hAnim; + GUI_TIMER_TIME Period; +} GUI_ANIM_INFO; + +typedef void GUI_ANIMATION_FUNC(GUI_ANIM_INFO * pInfo, void * pVoid); + +I32 GUI_ANIM__Linear (GUI_TIMER_TIME ts, GUI_TIMER_TIME te, GUI_TIMER_TIME tNow); +I32 GUI_ANIM__Decel (GUI_TIMER_TIME ts, GUI_TIMER_TIME te, GUI_TIMER_TIME tNow); +I32 GUI_ANIM__Accel (GUI_TIMER_TIME ts, GUI_TIMER_TIME te, GUI_TIMER_TIME tNow); +I32 GUI_ANIM__AccelDecel(GUI_TIMER_TIME ts, GUI_TIMER_TIME te, GUI_TIMER_TIME tNow); + +int GUI_ANIM_AddItem(GUI_ANIM_HANDLE hAnim, GUI_TIMER_TIME ts, GUI_TIMER_TIME te, GUI_ANIM_GETPOS_FUNC pfGetPos, void * pVoid, GUI_ANIMATION_FUNC * pfAnim); +GUI_ANIM_HANDLE GUI_ANIM_Create (GUI_TIMER_TIME Period, unsigned MinTimePerFrame, void * pVoid, void (* pfSliceInfo)(int State, void * pVoid)); +void GUI_ANIM_Delete (GUI_ANIM_HANDLE hAnim); +int GUI_ANIM_Exec (GUI_ANIM_HANDLE hAnim); +void GUI_ANIM_Start (GUI_ANIM_HANDLE hAnim); +void GUI_ANIM_StartEx(GUI_ANIM_HANDLE hAnim, int NumLoops, void (* pfOnDelete)(void * pVoid)); +void GUI_ANIM_Stop (GUI_ANIM_HANDLE hAnim); + +/********************************************************************* +* +* Display orientation +*/ +/********************************************************************* +* +* GUI_ORIENTATION_API +*/ +typedef struct { + void (* pfDrawBitmap )(GUI_DEVICE * pDevice, int x0, int y0, int xsize, int ysize, int BitsPerPixel, int BytesPerLine, const U8 * pData, int Diff, const LCD_PIXELINDEX * pTrans); + void (* pfDrawHLine )(GUI_DEVICE * pDevice, int x0, int y0, int x1); + void (* pfDrawVLine )(GUI_DEVICE * pDevice, int x , int y0, int y1); + void (* pfFillRect )(GUI_DEVICE * pDevice, int x0, int y0, int x1, int y1); + LCD_PIXELINDEX (* pfGetPixelIndex)(GUI_DEVICE * pDevice, int x, int y); + void (* pfSetPixelIndex)(GUI_DEVICE * pDevice, int x, int y, LCD_PIXELINDEX ColorIndex); + void (* pfXorPixel )(GUI_DEVICE * pDevice, int x, int y); + int BytesPerPixel; +} GUI_ORIENTATION_API; + +extern const GUI_ORIENTATION_API GUI_OrientationAPI_C0; +extern const GUI_ORIENTATION_API GUI_OrientationAPI_C8; +extern const GUI_ORIENTATION_API GUI_OrientationAPI_C16; +extern const GUI_ORIENTATION_API GUI_OrientationAPI_C32; + +#define GUI_ORIENTATION_C0 &GUI_OrientationAPI_C0 +#define GUI_ORIENTATION_C8 &GUI_OrientationAPI_C8 +#define GUI_ORIENTATION_C16 &GUI_OrientationAPI_C16 +#define GUI_ORIENTATION_C32 &GUI_OrientationAPI_C32 + +int GUI_SetOrientation (int Orientation); +int GUI_SetOrientationEx (int Orientation, int LayerIndex); +int GUI_SetOrientationExCached(int Orientation, int LayerIndex, const GUI_ORIENTATION_API * pAPI); + +/********************************************************************* +* +* Measure device: GUI_MEASDEV +*/ +typedef GUI_HMEM GUI_MEASDEV_Handle; + +GUI_MEASDEV_Handle GUI_MEASDEV_Create (void); +void GUI_MEASDEV_Delete (GUI_MEASDEV_Handle hMemDev); +void GUI_MEASDEV_Select (GUI_MEASDEV_Handle hMem); +void GUI_MEASDEV_GetRect(GUI_MEASDEV_Handle hMem, GUI_RECT * pRect); +void GUI_MEASDEV_ClearRect(GUI_MEASDEV_Handle hMem); + +/********************************************************************* +* +* Polygon helpers +*/ +void GUI_RotatePolygon (GUI_POINT * pDest, const GUI_POINT * pSrc, int NumPoints, float Angle); +void GUI_MagnifyPolygon(GUI_POINT * pDest, const GUI_POINT * pSrc, int NumPoints, int Mag); +void GUI_EnlargePolygon(GUI_POINT * pDest, const GUI_POINT * pSrc, int NumPoints, int Len); + +/********************************************************************* +* +* Streamed bitmaps +*/ +#define GUI_BITMAPSTREAM_GET_BUFFER 1 +#define GUI_BITMAPSTREAM_RELEASE_BUFFER 2 +#define GUI_BITMAPSTREAM_MODIFY_PALETTE 3 + +#define DECLARE_CREATE_FROM_STREAM(ID) int GUI_CreateBitmapFromStream##ID(GUI_BITMAP * pBMP, GUI_LOGPALETTE * pPAL, const void * p); + +DECLARE_CREATE_FROM_STREAM(IDX) +DECLARE_CREATE_FROM_STREAM(RLE4) +DECLARE_CREATE_FROM_STREAM(RLE8) +DECLARE_CREATE_FROM_STREAM(565) +DECLARE_CREATE_FROM_STREAM(M565) +DECLARE_CREATE_FROM_STREAM(555) +DECLARE_CREATE_FROM_STREAM(M555) +DECLARE_CREATE_FROM_STREAM(A565) +DECLARE_CREATE_FROM_STREAM(AM565) +DECLARE_CREATE_FROM_STREAM(A555) +DECLARE_CREATE_FROM_STREAM(AM555) +DECLARE_CREATE_FROM_STREAM(RLE16) +DECLARE_CREATE_FROM_STREAM(RLEM16) +DECLARE_CREATE_FROM_STREAM(24) +DECLARE_CREATE_FROM_STREAM(Alpha) +DECLARE_CREATE_FROM_STREAM(M8888I) +DECLARE_CREATE_FROM_STREAM(RLEAlpha) +DECLARE_CREATE_FROM_STREAM(RLE32) +DECLARE_CREATE_FROM_STREAM(444_12) +DECLARE_CREATE_FROM_STREAM(M444_12) +DECLARE_CREATE_FROM_STREAM(444_12_1) +DECLARE_CREATE_FROM_STREAM(M444_12_1) +DECLARE_CREATE_FROM_STREAM(444_16) +DECLARE_CREATE_FROM_STREAM(M444_16) + +int GUI_CreateBitmapFromStream (GUI_BITMAP * pBMP, GUI_LOGPALETTE * pPAL, const void * p); +void GUI_DrawStreamedBitmap (const void * p, int x, int y); +void GUI_DrawStreamedBitmapAuto (const void * p, int x, int y); +int GUI_DrawStreamedBitmapEx (GUI_GET_DATA_FUNC * pfGetData, const void * p, int x, int y); +int GUI_DrawStreamedBitmapExAuto (GUI_GET_DATA_FUNC * pfGetData, const void * p, int x, int y); +int GUI_DrawStreamedBitmap555Ex (GUI_GET_DATA_FUNC * pfGetData, const void * p, int x, int y); +int GUI_DrawStreamedBitmapM555Ex (GUI_GET_DATA_FUNC * pfGetData, const void * p, int x, int y); +int GUI_DrawStreamedBitmap565Ex (GUI_GET_DATA_FUNC * pfGetData, const void * p, int x, int y); +int GUI_DrawStreamedBitmapM565Ex (GUI_GET_DATA_FUNC * pfGetData, const void * p, int x, int y); +int GUI_DrawStreamedBitmapA555Ex (GUI_GET_DATA_FUNC * pfGetData, const void * p, int x, int y); +int GUI_DrawStreamedBitmapAM555Ex(GUI_GET_DATA_FUNC * pfGetData, const void * p, int x, int y); +int GUI_DrawStreamedBitmapA565Ex (GUI_GET_DATA_FUNC * pfGetData, const void * p, int x, int y); +int GUI_DrawStreamedBitmapAM565Ex(GUI_GET_DATA_FUNC * pfGetData, const void * p, int x, int y); +int GUI_DrawStreamedBitmap24Ex (GUI_GET_DATA_FUNC * pfGetData, const void * p, int x, int y); +void GUI_GetStreamedBitmapInfo (const void * p, GUI_BITMAPSTREAM_INFO * pInfo); +int GUI_GetStreamedBitmapInfoEx (GUI_GET_DATA_FUNC * pfGetData, const void * p, GUI_BITMAPSTREAM_INFO * pInfo); +void GUI_SetStreamedBitmapHook (GUI_BITMAPSTREAM_CALLBACK pfStreamedBitmapHook); + +void LCD__RLE4_SetFunc (GUI_GET_DATA_FUNC * pfGetData, void * pVoid, U32 Off, const LCD_LOGPALETTE * pLogPal); +void LCD__RLE8_SetFunc (GUI_GET_DATA_FUNC * pfGetData, void * pVoid, U32 Off, const LCD_LOGPALETTE * pLogPal); +void LCD__RLE16_SetFunc(GUI_GET_DATA_FUNC * pfGetData, void * pVoid, U32 Off); +void LCD__RLE32_SetFunc(GUI_GET_DATA_FUNC * pfGetData, void * pVoid, U32 Off); + +/********************************************************************* +* +* BMP-export +*/ +void GUI_BMP_Serialize (GUI_CALLBACK_VOID_U8_P * pfSerialize, void * p); +void GUI_BMP_SerializeEx (GUI_CALLBACK_VOID_U8_P * pfSerialize, int x0, int y0, int xSize, int ySize, void * p); +void GUI_BMP_SerializeExBpp(GUI_CALLBACK_VOID_U8_P * pfSerialize, int x0, int y0, int xSize, int ySize, void * p, int BitsPerPixel); + +void GUI_BMP__WriteBitmapHeader(GUI_CALLBACK_VOID_U8_P * pfSerialize, int xSize, int ySize, void * p, int BitsPerPixel, int BytesPerLine, int BytesPerPixel, int NumColors, int Padding); + +/********************************************************************* +* +* Time / execution related routines +*/ +void GUI_Delay (int Period); +GUI_TIMER_TIME GUI_GetTime (void); +int GUI_GetTimeSlice(void); +int GUI_Exec (void); /* Execute all jobs ... Return 0 if nothing was done. */ +int GUI_Exec1 (void); /* Execute one job ... Return 0 if nothing was done. */ +void GUI_SetTimeSlice(int TimeSlice); + +/********************************************************************* +* +* MessageBox +*/ +int GUI_MessageBox (const char * sMessage, const char * sCaption, int Flags); +#define GUI_MESSAGEBOX_CF_MOVEABLE (1 << 0) +#define GUI_MESSAGEBOX_CF_MODAL (1 << 1) + +#define GUI_MB_OK 20 +#define GUI_MB_WARNING 21 + +/********************************************************************* +* +* GUI_TIMER module +*/ +#define GUI_TIMER_CF_WINDOW (1 << 0) +#define GUI_TIMER_CF_CURSOR (1 << 1) + +typedef GUI_HMEM GUI_TIMER_HANDLE; + +typedef struct { + GUI_TIMER_TIME Time; + U32 Context; + GUI_TIMER_HANDLE hTimer; +} GUI_TIMER_MESSAGE; + +typedef void GUI_TIMER_CALLBACK(/*const*/ GUI_TIMER_MESSAGE* pTM); + +GUI_TIMER_HANDLE GUI_TIMER_Create (GUI_TIMER_CALLBACK * cb, GUI_TIMER_TIME Time, U32 Context, U16 Flags); +void GUI_TIMER_Delete (GUI_TIMER_HANDLE hObj); + +/* Methods changing properties */ +GUI_TIMER_TIME GUI_TIMER_GetPeriod(GUI_TIMER_HANDLE hObj); +void GUI_TIMER_SetPeriod(GUI_TIMER_HANDLE hObj, GUI_TIMER_TIME Period); +void GUI_TIMER_SetTime (GUI_TIMER_HANDLE hObj, GUI_TIMER_TIME Period); +void GUI_TIMER_SetDelay (GUI_TIMER_HANDLE hObj, GUI_TIMER_TIME Delay); +void GUI_TIMER_Restart (GUI_TIMER_HANDLE hObj); +int GUI_TIMER_GetFlag (GUI_TIMER_HANDLE hObj, int Flag); /* Not to be documented */ +int GUI_TIMER_Exec (void); + +/********************************************************************* +* +* Anti Aliasing +*/ +#define GUI_AA_TRANS 0 // Foreground color mixed up with current content of framebuffer +#define GUI_AA_NOTRANS 1 // Foreground color mixed up with current background color + +void GUI_AA_DisableHiRes (void); +void GUI_AA_EnableHiRes (void); +int GUI_AA_GetFactor (void); +void GUI_AA_SetFactor (int Factor); +void GUI_AA_DrawArc (int x0, int y0, int rx, int ry, int a0, int a1); +void GUI_AA_DrawLine (int x0, int y0, int x1, int y1); +void GUI_AA_DrawPolyOutline (const GUI_POINT * pSrc, int NumPoints, int Thickness, int x, int y); +void GUI_AA_DrawPolyOutlineEx(const GUI_POINT * pSrc, int NumPoints, int Thickness, int x, int y, GUI_POINT * pBuffer); +void GUI_AA_DrawRoundedRect (int x0, int y0, int x1, int y1, int r); +void GUI_AA_DrawRoundedRectEx(GUI_RECT * pRect, int r); +void GUI_AA_FillCircle (int x0, int y0, int r); +void GUI_AA_FillEllipse (int x0, int y0, int rx, int ry); +void GUI_AA_FillPolygon (const GUI_POINT * pPoints, int NumPoints, int x0, int y0); +void GUI_AA_FillRoundedRect (int x0, int y0, int x1, int y1, int r); +void GUI_AA_FillRoundedRectEx(GUI_RECT * pRect, int r); +int GUI_AA_SetDrawMode (int Mode); +void GUI_AA_SetpfDrawCharAA4 (int (* pfDrawChar)(int LayerIndex, int x, int y, U8 const * p, int xSize, int ySize, int BytesPerLine)); +void GUI_AA_SetGammaAA4 (U8 * pGamma); +void GUI_AA_GetGammaAA4 (U8 * pGamma); +void GUI_AA_EnableGammaAA4 (int OnOff); + +#define GUI_AA_PreserveTrans(OnOff) GUI_PreserveTrans(OnOff) // For compatibility only + +/********************************************************************* +* +* Keyboard +*/ +/* Message layer */ +void GUI_StoreKeyMsg(int Key, int Pressed); +void GUI_SendKeyMsg (int Key, int Pressed); +int GUI_PollKeyMsg (void); +void GUI_GetKeyState(GUI_KEY_STATE * pState); + +void GUI_KEY__SetHook(void (* pfHook)(const GUI_KEY_STATE *)); + +/* Application layer */ +int GUI_GetKey(void); +int GUI_WaitKey(void); +void GUI_StoreKey(int c); +void GUI_ClearKeyBuffer(void); + +/********************************************************************* +* +* Task synchronization +*/ +void GUI_WaitEvent (void); +void GUI_SignalEvent (void); +void GUI_SetSignalEventFunc (GUI_SIGNAL_EVENT_FUNC pfSignalEvent); +void GUI_SetWaitEventFunc (GUI_WAIT_EVENT_FUNC pfWaitEvent); +void GUI_SetWaitEventTimedFunc(GUI_WAIT_EVENT_TIMED_FUNC pfWaitEventTimed); + +/********************************************************************* +* +* Joystick, generic +*/ +void GUI_JOYSTICK_StoreState(const GUI_PID_STATE * pState); + +/********************************************************************* +* +* PID (Pointer input device ... mouse/touch) +*/ +void GUI_PID_StoreState (const GUI_PID_STATE * pState); +int GUI_PID_GetState ( GUI_PID_STATE * pState); +void GUI_PID_GetCurrentState( GUI_PID_STATE * pState); +int GUI_PID_IsEmpty (void); +int GUI_PID_IsPressed (void); +void GUI_PID_SetHook (void (* pfHook)( GUI_PID_STATE *)); // Public +void GUI_PID__SetHook (void (* pfHook)(const GUI_PID_STATE *)); // Private + +/********************************************************************* +* +* Mouse, generic +*/ +int GUI_MOUSE_GetState ( GUI_PID_STATE * pState); +void GUI_MOUSE_StoreState(const GUI_PID_STATE * pState); + +/********************************************************************* +* +* TOUCH screen, generic +*/ +int GUI_TOUCH_GetLayer (void); +int GUI_TOUCH_GetState (GUI_PID_STATE * pState); +void GUI_TOUCH_GetUnstable (int * px, int * py); /* for diagnostics only */ +void GUI_TOUCH_SetLayer (int Layer); +void GUI_TOUCH_StoreState (int x, int y); +void GUI_TOUCH_StoreStateEx (const GUI_PID_STATE * pState); +void GUI_TOUCH_StoreUnstable(int x, int y); + +/********************************************************************* +* +* Mouse, PS2 driver +*/ +void GUI_MOUSE_DRIVER_PS2_Init(void); /* optional */ +void GUI_MOUSE_DRIVER_PS2_OnRx(unsigned char Data); + +/********************************************************************* +* +* TOUCH screen, analog driver +*/ +int GUI_TOUCH_CalcCoefficients (int NumPoints, int * pxRef, int * pyRef, int * pxSample, int * pySample, int xSize, int ySize); +int GUI_TOUCH_Calibrate (int Coord, int Log0, int Log1, int Phys0, int Phys1); +int GUI_TOUCH_CalibratePoint (int * px, int * py); +void GUI_TOUCH_EnableCalibration(int OnOff); +void GUI_TOUCH_Exec (void); +int GUI_TOUCH_GetxPhys (void); /* for diagnostics only */ +int GUI_TOUCH_GetyPhys (void); /* for diagnostics only */ +void GUI_TOUCH_SetCalibration (int (* pFunc)(int *, int *)); /* Not to be documented */ +void GUI_TOUCH_SetOrientation (unsigned Orientation); +int GUI_TOUCH_TransformPoint (int * px, int * py); /* Not to be documented */ + +/********************************************************************* +* +* TOUCH: imports +* +* Please note: The following functions are required by the module. +* They need to be part of your application software (or rather, part +* of the hardware-layer of your software). +*/ +void GUI_TOUCH_X_ActivateX(void); +void GUI_TOUCH_X_ActivateY(void); +void GUI_TOUCH_X_Disable (void); +int GUI_TOUCH_X_MeasureX (void); +int GUI_TOUCH_X_MeasureY (void); + +/********************************************************************* +* +* GUI_X_ +* +* Externals, to be defined by application +* +* The externals defined below should be defined by the +* application. They are per default contained in the module +* GUI_X.c. +* Note that a lot if not all of these are not required in most target +* systems. +* For this module, samples are available for configurations +* with or without operating system. +*/ +// +// Configuration +// +void GUI_X_Config(void); +void GUI_X_Init (void); + +// +// Timing routines +// +GUI_TIMER_TIME GUI_X_GetTime(void); +void GUI_X_Delay (int Period); + +// +// Multitask routines - required only if multitasking is used (#define GUI_OS 1) +// +void GUI_X_Unlock (void); +void GUI_X_Lock (void); +U32 GUI_X_GetTaskId(void); +void GUI_X_InitOS (void); + +// +// Event driving (optional with multitasking) +// +void GUI_X_ExecIdle (void); +void GUI_X_WaitEvent (void); +void GUI_X_WaitEventTimed(int Period); +void GUI_X_SignalEvent (void); + +// +// Recording (logs/warnings and errors) - required only for higher levels +// +void GUI_X_Log (const char * s); +void GUI_X_Warn (const char * s); +void GUI_X_ErrorOut(const char * s); + +/********************************************************************* +* +* Constants for fonts and bitmaps +*/ +extern const GUI_BITMAP_METHODS GUI_BitmapMethodsRLE4; +extern const GUI_BITMAP_METHODS GUI_BitmapMethodsRLE4Ex; +extern const GUI_BITMAP_METHODS GUI_BitmapMethodsRLE8; +extern const GUI_BITMAP_METHODS GUI_BitmapMethodsRLE8Ex; +extern const GUI_BITMAP_METHODS GUI_BitmapMethodsRLE16; +extern const GUI_BITMAP_METHODS GUI_BitmapMethodsRLE16Ex; +extern const GUI_BITMAP_METHODS GUI_BitmapMethodsRLEM16; +extern const GUI_BITMAP_METHODS GUI_BitmapMethodsRLEM16Ex; +extern const GUI_BITMAP_METHODS GUI_BitmapMethodsRLE32; +extern const GUI_BITMAP_METHODS GUI_BitmapMethodsRLE32Ex; +extern const GUI_BITMAP_METHODS GUI_BitmapMethodsRLEAlpha; + +extern const GUI_BITMAP_METHODS GUI_BitmapMethods444_12; +extern const GUI_BITMAP_METHODS GUI_BitmapMethodsM444_12; +extern const GUI_BITMAP_METHODS GUI_BitmapMethods444_12_1; +extern const GUI_BITMAP_METHODS GUI_BitmapMethodsM444_12_1; +extern const GUI_BITMAP_METHODS GUI_BitmapMethods444_16; +extern const GUI_BITMAP_METHODS GUI_BitmapMethodsM444_16; +extern const GUI_BITMAP_METHODS GUI_BitmapMethods555; +extern const GUI_BITMAP_METHODS GUI_BitmapMethodsM555; +extern const GUI_BITMAP_METHODS GUI_BitmapMethods565; +extern const GUI_BITMAP_METHODS GUI_BitmapMethodsM565; +extern const GUI_BITMAP_METHODS GUI_BitmapMethods24; +extern const GUI_BITMAP_METHODS GUI_BitmapMethods888; +extern const GUI_BITMAP_METHODS GUI_BitmapMethodsM888; +extern const GUI_BITMAP_METHODS GUI_BitmapMethods8888; +extern const GUI_BITMAP_METHODS GUI_BitmapMethodsM8888I; +extern const GUI_BITMAP_METHODS GUI_BitmapMethodsA565; +extern const GUI_BITMAP_METHODS GUI_BitmapMethodsAM565; +extern const GUI_BITMAP_METHODS GUI_BitmapMethodsA555; +extern const GUI_BITMAP_METHODS GUI_BitmapMethodsAM555; + +#define GUI_COMPRESS_RLE4 0 +#define GUI_COMPRESS_RLE8 0 + +#define GUI_DRAW_RLE4 &GUI_BitmapMethodsRLE4 /* Method table ! */ +#define GUI_DRAW_RLE8 &GUI_BitmapMethodsRLE8 /* Method table ! */ +#define GUI_DRAW_RLE16 &GUI_BitmapMethodsRLE16 /* Method table ! */ +#define GUI_DRAW_RLEM16 &GUI_BitmapMethodsRLEM16 /* Method table ! */ +#define GUI_DRAW_RLE32 &GUI_BitmapMethodsRLE32 /* Method table ! */ +#define GUI_DRAW_RLEALPHA &GUI_BitmapMethodsRLEAlpha /* Method table ! */ + +#define GUI_DRAW_BMP444_12 &GUI_BitmapMethods444_12 /* Method table ! */ +#define GUI_DRAW_BMPM444_12 &GUI_BitmapMethodsM444_12 /* Method table ! */ +#define GUI_DRAW_BMP444_12_1 &GUI_BitmapMethods444_12_1 /* Method table ! */ +#define GUI_DRAW_BMPM444_12_1 &GUI_BitmapMethodsM444_12_1 /* Method table ! */ +#define GUI_DRAW_BMP444_16 &GUI_BitmapMethods444_16 /* Method table ! */ +#define GUI_DRAW_BMPM444_16 &GUI_BitmapMethodsM444_16 /* Method table ! */ +#define GUI_DRAW_BMP555 &GUI_BitmapMethods555 /* Method table ! */ +#define GUI_DRAW_BMPM555 &GUI_BitmapMethodsM555 /* Method table ! */ +#define GUI_DRAW_BMP565 &GUI_BitmapMethods565 /* Method table ! */ +#define GUI_DRAW_BMPM565 &GUI_BitmapMethodsM565 /* Method table ! */ +#define GUI_DRAW_BMP24 &GUI_BitmapMethods24 /* Method table ! */ +#define GUI_DRAW_BMP888 &GUI_BitmapMethods888 /* Method table ! */ +#define GUI_DRAW_BMPM888 &GUI_BitmapMethodsM888 /* Method table ! */ +#define GUI_DRAW_BMP8888 &GUI_BitmapMethods8888 /* Method table ! */ +#define GUI_DRAW_BMPM8888I &GUI_BitmapMethodsM8888I /* Method table ! */ +#define GUI_DRAW_BMPA555 &GUI_BitmapMethodsA555 /* Method table ! */ +#define GUI_DRAW_BMPAM555 &GUI_BitmapMethodsAM555 /* Method table ! */ +#define GUI_DRAW_BMPA565 &GUI_BitmapMethodsA565 /* Method table ! */ +#define GUI_DRAW_BMPAM565 &GUI_BitmapMethodsAM565 /* Method table ! */ + +extern const tGUI_SIF_APIList GUI_SIF_APIList_Prop; +extern const tGUI_SIF_APIList GUI_SIF_APIList_Prop_Ext; +extern const tGUI_SIF_APIList GUI_SIF_APIList_Prop_Frm; +extern const tGUI_SIF_APIList GUI_SIF_APIList_Prop_AA2; +extern const tGUI_SIF_APIList GUI_SIF_APIList_Prop_AA4; +extern const tGUI_SIF_APIList GUI_SIF_APIList_Prop_AA2_EXT; +extern const tGUI_SIF_APIList GUI_SIF_APIList_Prop_AA4_EXT; + +extern const tGUI_XBF_APIList GUI_XBF_APIList_Prop; +extern const tGUI_XBF_APIList GUI_XBF_APIList_Prop_Ext; +extern const tGUI_XBF_APIList GUI_XBF_APIList_Prop_Frm; +extern const tGUI_XBF_APIList GUI_XBF_APIList_Prop_AA2_Ext; +extern const tGUI_XBF_APIList GUI_XBF_APIList_Prop_AA4_Ext; + +/********************************************************************* +* +* GUI_KEY_... +* +* These ID values are basically meant to be used with widgets +* Note that we have chosen the values to be close to existing +* "standards", so do not change them unless forced to. +* +*/ +#define GUI_KEY_BACKSPACE 8 /* ASCII: BACKSPACE Crtl-H */ +#define GUI_KEY_TAB 9 /* ASCII: TAB Crtl-I */ +#define GUI_KEY_BACKTAB 10 +#define GUI_KEY_ENTER 13 /* ASCII: ENTER Crtl-M */ +#define GUI_KEY_LEFT 16 +#define GUI_KEY_UP 17 +#define GUI_KEY_RIGHT 18 +#define GUI_KEY_DOWN 19 +#define GUI_KEY_HOME 23 +#define GUI_KEY_END 24 +#define GUI_KEY_SHIFT 25 +#define GUI_KEY_CONTROL 26 +#define GUI_KEY_ESCAPE 27 /* ASCII: ESCAPE 0x1b */ +#define GUI_KEY_INSERT 29 +#define GUI_KEY_DELETE 30 +#define GUI_KEY_SPACE 32 +#define GUI_KEY_PGUP 33 +#define GUI_KEY_PGDOWN 34 + +#define GUI_KEY_F1 40 +#define GUI_KEY_F2 41 + +/********************************************************************* +* +* Dialog item IDs +* +* The IDs below are arbitrary values. They just have to be unique +* within the dialog. +* +* If you use your own Ids, we recommend to use values above GUI_ID_USER. +*/ +#define GUI_ID_OK 1 +#define GUI_ID_CANCEL 2 +#define GUI_ID_YES 3 +#define GUI_ID_NO 4 +#define GUI_ID_CLOSE 5 +#define GUI_ID_HELP 6 +#define GUI_ID_MAXIMIZE 7 +#define GUI_ID_MINIMIZE 8 + +#define GUI_ID_VSCROLL 0xFE +#define GUI_ID_HSCROLL 0xFF + +#define GUI_ID_EDIT0 0x100 +#define GUI_ID_EDIT1 0x101 +#define GUI_ID_EDIT2 0x102 +#define GUI_ID_EDIT3 0x103 +#define GUI_ID_EDIT4 0x104 +#define GUI_ID_EDIT5 0x105 +#define GUI_ID_EDIT6 0x106 +#define GUI_ID_EDIT7 0x107 +#define GUI_ID_EDIT8 0x108 +#define GUI_ID_EDIT9 0x109 + +#define GUI_ID_LISTBOX0 0x110 +#define GUI_ID_LISTBOX1 0x111 +#define GUI_ID_LISTBOX2 0x112 +#define GUI_ID_LISTBOX3 0x113 +#define GUI_ID_LISTBOX4 0x114 +#define GUI_ID_LISTBOX5 0x115 +#define GUI_ID_LISTBOX6 0x116 +#define GUI_ID_LISTBOX7 0x117 +#define GUI_ID_LISTBOX8 0x118 +#define GUI_ID_LISTBOX9 0x119 + +#define GUI_ID_CHECK0 0x120 +#define GUI_ID_CHECK1 0x121 +#define GUI_ID_CHECK2 0x122 +#define GUI_ID_CHECK3 0x123 +#define GUI_ID_CHECK4 0x124 +#define GUI_ID_CHECK5 0x125 +#define GUI_ID_CHECK6 0x126 +#define GUI_ID_CHECK7 0x127 +#define GUI_ID_CHECK8 0x128 +#define GUI_ID_CHECK9 0x129 + +#define GUI_ID_SLIDER0 0x130 +#define GUI_ID_SLIDER1 0x131 +#define GUI_ID_SLIDER2 0x132 +#define GUI_ID_SLIDER3 0x133 +#define GUI_ID_SLIDER4 0x134 +#define GUI_ID_SLIDER5 0x135 +#define GUI_ID_SLIDER6 0x136 +#define GUI_ID_SLIDER7 0x137 +#define GUI_ID_SLIDER8 0x138 +#define GUI_ID_SLIDER9 0x139 + +#define GUI_ID_SCROLLBAR0 0x140 +#define GUI_ID_SCROLLBAR1 0x141 +#define GUI_ID_SCROLLBAR2 0x142 +#define GUI_ID_SCROLLBAR3 0x143 + +#define GUI_ID_RADIO0 0x150 +#define GUI_ID_RADIO1 0x151 +#define GUI_ID_RADIO2 0x152 +#define GUI_ID_RADIO3 0x153 +#define GUI_ID_RADIO4 0x154 +#define GUI_ID_RADIO5 0x155 +#define GUI_ID_RADIO6 0x156 +#define GUI_ID_RADIO7 0x157 + +#define GUI_ID_TEXT0 0x160 +#define GUI_ID_TEXT1 0x161 +#define GUI_ID_TEXT2 0x162 +#define GUI_ID_TEXT3 0x163 +#define GUI_ID_TEXT4 0x164 +#define GUI_ID_TEXT5 0x165 +#define GUI_ID_TEXT6 0x166 +#define GUI_ID_TEXT7 0x167 +#define GUI_ID_TEXT8 0x168 +#define GUI_ID_TEXT9 0x169 + +#define GUI_ID_BUTTON0 0x170 +#define GUI_ID_BUTTON1 0x171 +#define GUI_ID_BUTTON2 0x172 +#define GUI_ID_BUTTON3 0x173 +#define GUI_ID_BUTTON4 0x174 +#define GUI_ID_BUTTON5 0x175 +#define GUI_ID_BUTTON6 0x176 +#define GUI_ID_BUTTON7 0x177 +#define GUI_ID_BUTTON8 0x178 +#define GUI_ID_BUTTON9 0x179 + +#define GUI_ID_DROPDOWN0 0x180 +#define GUI_ID_DROPDOWN1 0x181 +#define GUI_ID_DROPDOWN2 0x182 +#define GUI_ID_DROPDOWN3 0x183 + +#define GUI_ID_MULTIEDIT0 0x190 +#define GUI_ID_MULTIEDIT1 0x191 +#define GUI_ID_MULTIEDIT2 0x192 +#define GUI_ID_MULTIEDIT3 0x193 + +#define GUI_ID_LISTVIEW0 0x200 +#define GUI_ID_LISTVIEW1 0x201 +#define GUI_ID_LISTVIEW2 0x202 +#define GUI_ID_LISTVIEW3 0x203 + +#define GUI_ID_PROGBAR0 0x210 +#define GUI_ID_PROGBAR1 0x211 +#define GUI_ID_PROGBAR2 0x212 +#define GUI_ID_PROGBAR3 0x213 + +#define GUI_ID_GRAPH0 0x220 +#define GUI_ID_GRAPH1 0x221 +#define GUI_ID_GRAPH2 0x222 +#define GUI_ID_GRAPH3 0x223 + +#define GUI_ID_MULTIPAGE0 0x230 +#define GUI_ID_MULTIPAGE1 0x231 +#define GUI_ID_MULTIPAGE2 0x232 +#define GUI_ID_MULTIPAGE3 0x233 + +#define GUI_ID_TREEVIEW0 0x240 +#define GUI_ID_TREEVIEW1 0x241 +#define GUI_ID_TREEVIEW2 0x242 +#define GUI_ID_TREEVIEW3 0x243 + +#define GUI_ID_ICONVIEW0 0x250 +#define GUI_ID_ICONVIEW1 0x251 +#define GUI_ID_ICONVIEW2 0x252 +#define GUI_ID_ICONVIEW3 0x253 + +#define GUI_ID_LISTWHEEL0 0x260 +#define GUI_ID_LISTWHEEL1 0x261 +#define GUI_ID_LISTWHEEL2 0x262 +#define GUI_ID_LISTWHEEL3 0x263 + +#define GUI_ID_IMAGE0 0x270 +#define GUI_ID_IMAGE1 0x271 +#define GUI_ID_IMAGE2 0x272 +#define GUI_ID_IMAGE3 0x273 +#define GUI_ID_IMAGE4 0x274 +#define GUI_ID_IMAGE5 0x275 +#define GUI_ID_IMAGE6 0x276 +#define GUI_ID_IMAGE7 0x277 +#define GUI_ID_IMAGE8 0x278 +#define GUI_ID_IMAGE9 0x279 + +#define GUI_ID_SPINBOX0 0x280 +#define GUI_ID_SPINBOX1 0x281 +#define GUI_ID_SPINBOX2 0x282 +#define GUI_ID_SPINBOX3 0x283 +#define GUI_ID_SPINBOX4 0x284 +#define GUI_ID_SPINBOX5 0x285 +#define GUI_ID_SPINBOX6 0x286 +#define GUI_ID_SPINBOX7 0x287 +#define GUI_ID_SPINBOX8 0x288 +#define GUI_ID_SPINBOX9 0x289 + +#define GUI_ID_CALENDAR0 0x290 + +#define GUI_ID_KNOB0 0x300 +#define GUI_ID_KNOB1 0x301 +#define GUI_ID_KNOB2 0x302 +#define GUI_ID_KNOB3 0x303 +#define GUI_ID_KNOB4 0x304 +#define GUI_ID_KNOB5 0x305 +#define GUI_ID_KNOB6 0x306 +#define GUI_ID_KNOB7 0x307 +#define GUI_ID_KNOB8 0x308 +#define GUI_ID_KNOB9 0x309 + +#define GUI_ID_SWIPELIST0 0x320 +#define GUI_ID_SWIPELIST1 0x321 +#define GUI_ID_SWIPELIST2 0x322 + +#define GUI_ID_USER 0x800 + +/********************************************************************* +* +* Mouse buttons +*/ +#define GUI_LBUTTON (1 << 0) /* Left button */ +#define GUI_RBUTTON (1 << 1) /* Right button */ +#define GUI_MBUTTON (1 << 2) /* Middle button */ +#define GUI_DBUTTON (1 << 7) /* Double-click button */ + +/********************************************************************* +* +* Text styles +*/ +#define GUI_TS_NORMAL (0) +#define GUI_TS_UNDERLINE (1 << 0) +#define GUI_TS_STRIKETHRU (1 << 1) +#define GUI_TS_OVERLINE (1 << 2) + +/********************************************************************* +* +* Line styles +*/ +#define GUI_LS_SOLID (0) +#define GUI_LS_DASH (1) +#define GUI_LS_DOT (2) +#define GUI_LS_DASHDOT (3) +#define GUI_LS_DASHDOTDOT (4) + +/********************************************************************* +* +* Pen shapes +*/ +#define GUI_PS_ROUND (0) +#define GUI_PS_FLAT (1) +#define GUI_PS_SQUARE (2) + +/********************************************************************* +* +* Standard colors +*/ +#if (GUI_USE_ARGB) + #define GUI_BLUE 0xFF0000FF + #define GUI_GREEN 0xFF00FF00 + #define GUI_RED 0xFFFF0000 + #define GUI_CYAN 0xFF00FFFF + #define GUI_MAGENTA 0xFFFF00FF + #define GUI_YELLOW 0xFFFFFF00 + #define GUI_LIGHTBLUE 0xFF8080FF + #define GUI_LIGHTGREEN 0xFF80FF80 + #define GUI_LIGHTRED 0xFFFF8080 + #define GUI_LIGHTCYAN 0xFF80FFFF + #define GUI_LIGHTMAGENTA 0xFFFF80FF + #define GUI_LIGHTYELLOW 0xFFFFFF80 + #define GUI_DARKBLUE 0xFF000080 + #define GUI_DARKGREEN 0xFF008000 + #define GUI_DARKRED 0xFF800000 + #define GUI_DARKCYAN 0xFF008080 + #define GUI_DARKMAGENTA 0xFF800080 + #define GUI_DARKYELLOW 0xFF808000 + #define GUI_WHITE 0xFFFFFFFF + #define GUI_LIGHTGRAY 0xFFD3D3D3 + #define GUI_GRAY 0xFF808080 + #define GUI_DARKGRAY 0xFF404040 + #define GUI_BLACK 0xFF000000 + #define GUI_BROWN 0xFFA52A2A + #define GUI_ORANGE 0xFFFFA500 + #define GUI_TRANSPARENT 0x00000000 + + #define GUI_GRAY_3F 0xFF3F3F3F + #define GUI_GRAY_50 0xFF505050 + #define GUI_GRAY_55 0xFF555555 + #define GUI_GRAY_60 0xFF606060 + #define GUI_GRAY_7C 0xFF7C7C7C + #define GUI_GRAY_9A 0xFF9A9A9A + #define GUI_GRAY_AA 0xFFAAAAAA + #define GUI_GRAY_C0 0xFFC0C0C0 + #define GUI_GRAY_C8 0xFFC8C8C8 + #define GUI_GRAY_D0 0xFFD0D0D0 + #define GUI_GRAY_E7 0xFFE7E7E7 + #define GUI_BLUE_98 0xFF000098 +#else + #define GUI_BLUE 0x00FF0000 + #define GUI_GREEN 0x0000FF00 + #define GUI_RED 0x000000FF + #define GUI_CYAN 0x00FFFF00 + #define GUI_MAGENTA 0x00FF00FF + #define GUI_YELLOW 0x0000FFFF + #define GUI_LIGHTBLUE 0x00FF8080 + #define GUI_LIGHTGREEN 0x0080FF80 + #define GUI_LIGHTRED 0x008080FF + #define GUI_LIGHTCYAN 0x00FFFF80 + #define GUI_LIGHTMAGENTA 0x00FF80FF + #define GUI_LIGHTYELLOW 0x0080FFFF + #define GUI_DARKBLUE 0x00800000 + #define GUI_DARKGREEN 0x00008000 + #define GUI_DARKRED 0x00000080 + #define GUI_DARKCYAN 0x00808000 + #define GUI_DARKMAGENTA 0x00800080 + #define GUI_DARKYELLOW 0x00008080 + #define GUI_WHITE 0x00FFFFFF + #define GUI_LIGHTGRAY 0x00D3D3D3 + #define GUI_GRAY 0x00808080 + #define GUI_DARKGRAY 0x00404040 + #define GUI_BLACK 0x00000000 + #define GUI_BROWN 0x002A2AA5 + #define GUI_ORANGE 0x0000A5FF + #define GUI_TRANSPARENT 0xFF000000 + + #define GUI_GRAY_3F 0x003F3F3F + #define GUI_GRAY_50 0x00505050 + #define GUI_GRAY_55 0x00555555 + #define GUI_GRAY_60 0x00606060 + #define GUI_GRAY_7C 0x007C7C7C + #define GUI_GRAY_9A 0x009A9A9A + #define GUI_GRAY_AA 0x00AAAAAA + #define GUI_GRAY_C0 0x00C0C0C0 + #define GUI_GRAY_C8 0x00C8C8C8 + #define GUI_GRAY_D0 0x00D0D0D0 + #define GUI_GRAY_E7 0x00E7E7E7 + #define GUI_BLUE_98 0x00980000 +#endif + +#define GUI_INVALID_COLOR 0xFFFFFFF /* Invalid color - more than 24 bits */ + +#if (GUI_USE_ARGB) + #define GUI_MAKE_COLOR(ABGR) (((((U32)ABGR) & 0xFF000000ul) ^ 0xFF000000ul) | ((((U32)ABGR) & 0x00FF0000ul) >> 16) | (((U32)ABGR) & 0x0000FF00ul) | ((((U32)ABGR) & 0x000000FFul) << 16)) + #define GUI_MAKE_TRANS(Alpha) (255 - (Alpha)) +#else + #define GUI_MAKE_COLOR(ABGR) (ABGR) + #define GUI_MAKE_TRANS(Alpha) (Alpha) +#endif + +#if (GUI_USE_ARGB) + #define GUI_TRANS_BYTE 0x00 +#else + #define GUI_TRANS_BYTE 0xFF +#endif + + +/********************************************************************* +* +* MultiTouch-Support +*/ +// +// Defines +// +#define GUI_MTOUCH_FLAG_DOWN (1 << 0) +#define GUI_MTOUCH_FLAG_MOVE (1 << 1) +#define GUI_MTOUCH_FLAG_UP (1 << 2) + +// +// Variables +// +extern T_GUI_MTOUCH_STOREEVENT GUI_MTOUCH__pStoreEvent; + +// +// Interface +// +void GUI_MTOUCH_Enable (int OnOff); +int GUI_MTOUCH_GetEvent (GUI_MTOUCH_EVENT * pEvent); +int GUI_MTOUCH_GetTouchInput (GUI_MTOUCH_EVENT * pEvent, GUI_MTOUCH_INPUT * pBuffer, unsigned Index); +int GUI_MTOUCH_IsEmpty (void); +void GUI_MTOUCH_SetOrientation (int Orientation); +void GUI_MTOUCH_SetOrientationEx(int Orientation, int LayerIndex); +void GUI_MTOUCH_StoreEvent (GUI_MTOUCH_EVENT * pEvent, GUI_MTOUCH_INPUT * pInput); + +/********************************************************************* +* +* Coordinates used in touch driver +*/ +#define GUI_COORD_X 0 +#define GUI_COORD_Y 1 + +/********************************************************************* +* +* Addresses of standard fonts +*/ +// +// Proportional fonts +// +extern GUI_CONST_STORAGE GUI_FONT GUI_Font8_ASCII, GUI_Font8_1; +extern GUI_CONST_STORAGE GUI_FONT GUI_Font10S_ASCII, GUI_Font10S_1; +extern GUI_CONST_STORAGE GUI_FONT GUI_Font10_ASCII, GUI_Font10_1; +extern GUI_CONST_STORAGE GUI_FONT GUI_Font13_ASCII, GUI_Font13_1; +extern GUI_CONST_STORAGE GUI_FONT GUI_Font13B_ASCII, GUI_Font13B_1; +extern GUI_CONST_STORAGE GUI_FONT GUI_Font13H_ASCII, GUI_Font13H_1; +extern GUI_CONST_STORAGE GUI_FONT GUI_Font13HB_ASCII, GUI_Font13HB_1; +extern GUI_CONST_STORAGE GUI_FONT GUI_Font16_ASCII, GUI_Font16_1, GUI_Font16_HK, GUI_Font16_1HK; +extern GUI_CONST_STORAGE GUI_FONT GUI_Font16B_ASCII, GUI_Font16B_1; +extern GUI_CONST_STORAGE GUI_FONT GUI_Font20_ASCII, GUI_Font20_1; +extern GUI_CONST_STORAGE GUI_FONT GUI_Font20B_ASCII, GUI_Font20B_1; +extern GUI_CONST_STORAGE GUI_FONT GUI_Font24_ASCII, GUI_Font24_1; +extern GUI_CONST_STORAGE GUI_FONT GUI_Font24B_ASCII, GUI_Font24B_1; +extern GUI_CONST_STORAGE GUI_FONT GUI_Font32_ASCII, GUI_Font32_1; +extern GUI_CONST_STORAGE GUI_FONT GUI_Font32B_ASCII, GUI_Font32B_1; + +// +// Proportional fonts, framed +// +extern GUI_CONST_STORAGE GUI_FONT GUI_Font20F_ASCII; + +// +// Monospaced +// +extern GUI_CONST_STORAGE GUI_FONT GUI_Font4x6; +extern GUI_CONST_STORAGE GUI_FONT GUI_Font6x8, GUI_Font6x9; +extern GUI_CONST_STORAGE GUI_FONT GUI_Font6x8_ASCII, GUI_Font6x8_1; +extern GUI_CONST_STORAGE GUI_FONT GUI_Font8x8, GUI_Font8x9; +extern GUI_CONST_STORAGE GUI_FONT GUI_Font8x8_ASCII, GUI_Font8x8_1; +extern GUI_CONST_STORAGE GUI_FONT GUI_Font8x10_ASCII; +extern GUI_CONST_STORAGE GUI_FONT GUI_Font8x12_ASCII; +extern GUI_CONST_STORAGE GUI_FONT GUI_Font8x13_ASCII, GUI_Font8x13_1; +extern GUI_CONST_STORAGE GUI_FONT GUI_Font8x15B_ASCII, GUI_Font8x15B_1; +extern GUI_CONST_STORAGE GUI_FONT GUI_Font8x16, GUI_Font8x17, GUI_Font8x18; +extern GUI_CONST_STORAGE GUI_FONT GUI_Font8x16x1x2, GUI_Font8x16x2x2, GUI_Font8x16x3x3; +extern GUI_CONST_STORAGE GUI_FONT GUI_Font8x16_ASCII, GUI_Font8x16_1; + +// +// Digits +// +extern GUI_CONST_STORAGE GUI_FONT GUI_FontD24x32; +extern GUI_CONST_STORAGE GUI_FONT GUI_FontD32; +extern GUI_CONST_STORAGE GUI_FONT GUI_FontD36x48; +extern GUI_CONST_STORAGE GUI_FONT GUI_FontD48; +extern GUI_CONST_STORAGE GUI_FONT GUI_FontD48x64; +extern GUI_CONST_STORAGE GUI_FONT GUI_FontD64; +extern GUI_CONST_STORAGE GUI_FONT GUI_FontD60x80; +extern GUI_CONST_STORAGE GUI_FONT GUI_FontD80; + +// +// Comic fonts +// +extern GUI_CONST_STORAGE GUI_FONT GUI_FontComic18B_ASCII, GUI_FontComic18B_1; +extern GUI_CONST_STORAGE GUI_FONT GUI_FontComic24B_ASCII, GUI_FontComic24B_1; + +/********************************************************************* +* +* Macros to be used +*/ +// +// Proportional fonts +// +#define GUI_FONT_8_ASCII &GUI_Font8_ASCII +#define GUI_FONT_8_1 &GUI_Font8_1 +#define GUI_FONT_10S_ASCII &GUI_Font10S_ASCII +#define GUI_FONT_10S_1 &GUI_Font10S_1 +#define GUI_FONT_10_ASCII &GUI_Font10_ASCII +#define GUI_FONT_10_1 &GUI_Font10_1 +#define GUI_FONT_13_ASCII &GUI_Font13_ASCII +#define GUI_FONT_13_1 &GUI_Font13_1 +#define GUI_FONT_13B_ASCII &GUI_Font13B_ASCII +#define GUI_FONT_13B_1 &GUI_Font13B_1 +#define GUI_FONT_13H_ASCII &GUI_Font13H_ASCII +#define GUI_FONT_13H_1 &GUI_Font13H_1 +#define GUI_FONT_13HB_ASCII &GUI_Font13HB_ASCII +#define GUI_FONT_13HB_1 &GUI_Font13HB_1 +#define GUI_FONT_16_ASCII &GUI_Font16_ASCII +#define GUI_FONT_16_1 &GUI_Font16_1 +#define GUI_FONT_16_HK &GUI_Font16_HK +#define GUI_FONT_16_1HK &GUI_Font16_1HK +#define GUI_FONT_16B_ASCII &GUI_Font16B_ASCII +#define GUI_FONT_16B_1 &GUI_Font16B_1 +#define GUI_FONT_20_ASCII &GUI_Font20_ASCII +#define GUI_FONT_20_1 &GUI_Font20_1 +#define GUI_FONT_20B_ASCII &GUI_Font20B_ASCII +#define GUI_FONT_20B_1 &GUI_Font20B_1 +#define GUI_FONT_24_ASCII &GUI_Font24_ASCII +#define GUI_FONT_24_1 &GUI_Font24_1 +#define GUI_FONT_24B_ASCII &GUI_Font24B_ASCII +#define GUI_FONT_24B_1 &GUI_Font24B_1 +#define GUI_FONT_32_ASCII &GUI_Font32_ASCII +#define GUI_FONT_32_1 &GUI_Font32_1 +#define GUI_FONT_32B_ASCII &GUI_Font32B_ASCII +#define GUI_FONT_32B_1 &GUI_Font32B_1 + +// +// Proportional fonts, framed +// +#define GUI_FONT_20F_ASCII &GUI_Font20F_ASCII + +// +// Monospaced +// +#define GUI_FONT_4X6 &GUI_Font4x6 +#define GUI_FONT_6X8 &GUI_Font6x8 +#define GUI_FONT_6X8_ASCII &GUI_Font6x8_ASCII +#define GUI_FONT_6X8_1 &GUI_Font6x8_1 +#define GUI_FONT_6X9 &GUI_Font6x9 +#define GUI_FONT_8X8 &GUI_Font8x8 +#define GUI_FONT_8X8_ASCII &GUI_Font8x8_ASCII +#define GUI_FONT_8X8_1 &GUI_Font8x8_1 +#define GUI_FONT_8X9 &GUI_Font8x9 +#define GUI_FONT_8X10_ASCII &GUI_Font8x10_ASCII +#define GUI_FONT_8X12_ASCII &GUI_Font8x12_ASCII +#define GUI_FONT_8X13_ASCII &GUI_Font8x13_ASCII +#define GUI_FONT_8X13_1 &GUI_Font8x13_1 +#define GUI_FONT_8X15B_ASCII &GUI_Font8x15B_ASCII +#define GUI_FONT_8X15B_1 &GUI_Font8x15B_1 +#define GUI_FONT_8X16 &GUI_Font8x16 +#define GUI_FONT_8X17 &GUI_Font8x17 +#define GUI_FONT_8X18 &GUI_Font8x18 +#define GUI_FONT_8X16X1X2 &GUI_Font8x16x1x2 +#define GUI_FONT_8X16X2X2 &GUI_Font8x16x2x2 +#define GUI_FONT_8X16X3X3 &GUI_Font8x16x3x3 +#define GUI_FONT_8X16_ASCII &GUI_Font8x16_ASCII +#define GUI_FONT_8X16_1 &GUI_Font8x16_1 + +// +// Digits +// +#define GUI_FONT_D24X32 &GUI_FontD24x32 +#define GUI_FONT_D32 &GUI_FontD32 +#define GUI_FONT_D36X48 &GUI_FontD36x48 +#define GUI_FONT_D48 &GUI_FontD48 +#define GUI_FONT_D48X64 &GUI_FontD48x64 +#define GUI_FONT_D64 &GUI_FontD64 +#define GUI_FONT_D60X80 &GUI_FontD60x80 +#define GUI_FONT_D80 &GUI_FontD80 + +// +// Comic fonts +// +#define GUI_FONT_COMIC18B_ASCII &GUI_FontComic18B_ASCII +#define GUI_FONT_COMIC18B_1 &GUI_FontComic18B_1 +#define GUI_FONT_COMIC24B_ASCII &GUI_FontComic24B_ASCII +#define GUI_FONT_COMIC24B_1 &GUI_FontComic24B_1 + +/********************************************************************* +* +* Text and drawing modes +* +* These defines come in two flavors: the long version (.._DRAWMODE_..) +* and the short ones (.._DM_..). They are identical, feel free to use +* which ever one you like best. +*/ +#define GUI_DRAWMODE_NORMAL LCD_DRAWMODE_NORMAL +#define GUI_DRAWMODE_XOR LCD_DRAWMODE_XOR +#define GUI_DRAWMODE_TRANS LCD_DRAWMODE_TRANS +#define GUI_DRAWMODE_REV LCD_DRAWMODE_REV +#define GUI_DM_NORMAL LCD_DRAWMODE_NORMAL +#define GUI_DM_XOR LCD_DRAWMODE_XOR +#define GUI_DM_TRANS LCD_DRAWMODE_TRANS +#define GUI_DM_REV LCD_DRAWMODE_REV + +#define GUI_TEXTMODE_NORMAL LCD_DRAWMODE_NORMAL +#define GUI_TEXTMODE_XOR LCD_DRAWMODE_XOR +#define GUI_TEXTMODE_TRANS LCD_DRAWMODE_TRANS +#define GUI_TEXTMODE_REV LCD_DRAWMODE_REV +#define GUI_TM_NORMAL LCD_DRAWMODE_NORMAL +#define GUI_TM_XOR LCD_DRAWMODE_XOR +#define GUI_TM_TRANS LCD_DRAWMODE_TRANS +#define GUI_TM_REV LCD_DRAWMODE_REV + +/* Text alignment flags, horizontal */ +#define GUI_TA_LEFT (0) +#define GUI_TA_HORIZONTAL (3<<0) +#define GUI_TA_RIGHT (1<<0) +#define GUI_TA_CENTER (2<<0) +#define GUI_TA_HCENTER GUI_TA_CENTER /* easier to remember :-) */ + +/* Text alignment flags, vertical */ +#define GUI_TA_TOP (0) +#define GUI_TA_VERTICAL (3<<2) +#define GUI_TA_BOTTOM (1<<2) +#define GUI_TA_BASELINE (2<<2) +#define GUI_TA_VCENTER (3<<2) + +/* General orientation flags */ +#define GUI_MIRROR_X (1 << 0) +#define GUI_MIRROR_Y (1 << 1) +#define GUI_SWAP_XY (1 << 2) + +#define GUI_ROTATION_0 (0) +#define GUI_ROTATION_CW (GUI_MIRROR_X | GUI_SWAP_XY) +#define GUI_ROTATION_180 (GUI_MIRROR_X | GUI_MIRROR_Y) +#define GUI_ROTATION_CCW (GUI_MIRROR_Y | GUI_SWAP_XY) + +/********************************************************************* +* +* Min/Max coordinates +* +* Define minimum and maximum coordinates in x and y +*/ +#define GUI_XMIN -16383 +#define GUI_XMAX 16383 +#define GUI_YMIN -16383 +#define GUI_YMAX 16383 + +/********************************************************************* +* +* Defines for constants +*/ +#define ________ 0x0 +#define _______X 0x1 +#define ______X_ 0x2 +#define ______XX 0x3 +#define _____X__ 0x4 +#define _____X_X 0x5 +#define _____XX_ 0x6 +#define _____XXX 0x7 +#define ____X___ 0x8 +#define ____X__X 0x9 +#define ____X_X_ 0xa +#define ____X_XX 0xb +#define ____XX__ 0xc +#define ____XX_X 0xd +#define ____XXX_ 0xe +#define ____XXXX 0xf +#define ___X____ 0x10 +#define ___X___X 0x11 +#define ___X__X_ 0x12 +#define ___X__XX 0x13 +#define ___X_X__ 0x14 +#define ___X_X_X 0x15 +#define ___X_XX_ 0x16 +#define ___X_XXX 0x17 +#define ___XX___ 0x18 +#define ___XX__X 0x19 +#define ___XX_X_ 0x1a +#define ___XX_XX 0x1b +#define ___XXX__ 0x1c +#define ___XXX_X 0x1d +#define ___XXXX_ 0x1e +#define ___XXXXX 0x1f +#define __X_____ 0x20 +#define __X____X 0x21 +#define __X___X_ 0x22 +#define __X___XX 0x23 +#define __X__X__ 0x24 +#define __X__X_X 0x25 +#define __X__XX_ 0x26 +#define __X__XXX 0x27 +#define __X_X___ 0x28 +#define __X_X__X 0x29 +#define __X_X_X_ 0x2a +#define __X_X_XX 0x2b +#define __X_XX__ 0x2c +#define __X_XX_X 0x2d +#define __X_XXX_ 0x2e +#define __X_XXXX 0x2f +#define __XX____ 0x30 +#define __XX___X 0x31 +#define __XX__X_ 0x32 +#define __XX__XX 0x33 +#define __XX_X__ 0x34 +#define __XX_X_X 0x35 +#define __XX_XX_ 0x36 +#define __XX_XXX 0x37 +#define __XXX___ 0x38 +#define __XXX__X 0x39 +#define __XXX_X_ 0x3a +#define __XXX_XX 0x3b +#define __XXXX__ 0x3c +#define __XXXX_X 0x3d +#define __XXXXX_ 0x3e +#define __XXXXXX 0x3f +#define _X______ 0x40 +#define _X_____X 0x41 +#define _X____X_ 0x42 +#define _X____XX 0x43 +#define _X___X__ 0x44 +#define _X___X_X 0x45 +#define _X___XX_ 0x46 +#define _X___XXX 0x47 +#define _X__X___ 0x48 +#define _X__X__X 0x49 +#define _X__X_X_ 0x4a +#define _X__X_XX 0x4b +#define _X__XX__ 0x4c +#define _X__XX_X 0x4d +#define _X__XXX_ 0x4e +#define _X__XXXX 0x4f +#define _X_X____ 0x50 +#define _X_X___X 0x51 +#define _X_X__X_ 0x52 +#define _X_X__XX 0x53 +#define _X_X_X__ 0x54 +#define _X_X_X_X 0x55 +#define _X_X_XX_ 0x56 +#define _X_X_XXX 0x57 +#define _X_XX___ 0x58 +#define _X_XX__X 0x59 +#define _X_XX_X_ 0x5a +#define _X_XX_XX 0x5b +#define _X_XXX__ 0x5c +#define _X_XXX_X 0x5d +#define _X_XXXX_ 0x5e +#define _X_XXXXX 0x5f +#define _XX_____ 0x60 +#define _XX____X 0x61 +#define _XX___X_ 0x62 +#define _XX___XX 0x63 +#define _XX__X__ 0x64 +#define _XX__X_X 0x65 +#define _XX__XX_ 0x66 +#define _XX__XXX 0x67 +#define _XX_X___ 0x68 +#define _XX_X__X 0x69 +#define _XX_X_X_ 0x6a +#define _XX_X_XX 0x6b +#define _XX_XX__ 0x6c +#define _XX_XX_X 0x6d +#define _XX_XXX_ 0x6e +#define _XX_XXXX 0x6f +#define _XXX____ 0x70 +#define _XXX___X 0x71 +#define _XXX__X_ 0x72 +#define _XXX__XX 0x73 +#define _XXX_X__ 0x74 +#define _XXX_X_X 0x75 +#define _XXX_XX_ 0x76 +#define _XXX_XXX 0x77 +#define _XXXX___ 0x78 +#define _XXXX__X 0x79 +#define _XXXX_X_ 0x7a +#define _XXXX_XX 0x7b +#define _XXXXX__ 0x7c +#define _XXXXX_X 0x7d +#define _XXXXXX_ 0x7e +#define _XXXXXXX 0x7f +#define X_______ 0x80 +#define X______X 0x81 +#define X_____X_ 0x82 +#define X_____XX 0x83 +#define X____X__ 0x84 +#define X____X_X 0x85 +#define X____XX_ 0x86 +#define X____XXX 0x87 +#define X___X___ 0x88 +#define X___X__X 0x89 +#define X___X_X_ 0x8a +#define X___X_XX 0x8b +#define X___XX__ 0x8c +#define X___XX_X 0x8d +#define X___XXX_ 0x8e +#define X___XXXX 0x8f +#define X__X____ 0x90 +#define X__X___X 0x91 +#define X__X__X_ 0x92 +#define X__X__XX 0x93 +#define X__X_X__ 0x94 +#define X__X_X_X 0x95 +#define X__X_XX_ 0x96 +#define X__X_XXX 0x97 +#define X__XX___ 0x98 +#define X__XX__X 0x99 +#define X__XX_X_ 0x9a +#define X__XX_XX 0x9b +#define X__XXX__ 0x9c +#define X__XXX_X 0x9d +#define X__XXXX_ 0x9e +#define X__XXXXX 0x9f +#define X_X_____ 0xa0 +#define X_X____X 0xa1 +#define X_X___X_ 0xa2 +#define X_X___XX 0xa3 +#define X_X__X__ 0xa4 +#define X_X__X_X 0xa5 +#define X_X__XX_ 0xa6 +#define X_X__XXX 0xa7 +#define X_X_X___ 0xa8 +#define X_X_X__X 0xa9 +#define X_X_X_X_ 0xaa +#define X_X_X_XX 0xab +#define X_X_XX__ 0xac +#define X_X_XX_X 0xad +#define X_X_XXX_ 0xae +#define X_X_XXXX 0xaf +#define X_XX____ 0xb0 +#define X_XX___X 0xb1 +#define X_XX__X_ 0xb2 +#define X_XX__XX 0xb3 +#define X_XX_X__ 0xb4 +#define X_XX_X_X 0xb5 +#define X_XX_XX_ 0xb6 +#define X_XX_XXX 0xb7 +#define X_XXX___ 0xb8 +#define X_XXX__X 0xb9 +#define X_XXX_X_ 0xba +#define X_XXX_XX 0xbb +#define X_XXXX__ 0xbc +#define X_XXXX_X 0xbd +#define X_XXXXX_ 0xbe +#define X_XXXXXX 0xbf +#define XX______ 0xc0 +#define XX_____X 0xc1 +#define XX____X_ 0xc2 +#define XX____XX 0xc3 +#define XX___X__ 0xc4 +#define XX___X_X 0xc5 +#define XX___XX_ 0xc6 +#define XX___XXX 0xc7 +#define XX__X___ 0xc8 +#define XX__X__X 0xc9 +#define XX__X_X_ 0xca +#define XX__X_XX 0xcb +#define XX__XX__ 0xcc +#define XX__XX_X 0xcd +#define XX__XXX_ 0xce +#define XX__XXXX 0xcf +#define XX_X____ 0xd0 +#define XX_X___X 0xd1 +#define XX_X__X_ 0xd2 +#define XX_X__XX 0xd3 +#define XX_X_X__ 0xd4 +#define XX_X_X_X 0xd5 +#define XX_X_XX_ 0xd6 +#define XX_X_XXX 0xd7 +#define XX_XX___ 0xd8 +#define XX_XX__X 0xd9 +#define XX_XX_X_ 0xda +#define XX_XX_XX 0xdb +#define XX_XXX__ 0xdc +#define XX_XXX_X 0xdd +#define XX_XXXX_ 0xde +#define XX_XXXXX 0xdf +#define XXX_____ 0xe0 +#define XXX____X 0xe1 +#define XXX___X_ 0xe2 +#define XXX___XX 0xe3 +#define XXX__X__ 0xe4 +#define XXX__X_X 0xe5 +#define XXX__XX_ 0xe6 +#define XXX__XXX 0xe7 +#define XXX_X___ 0xe8 +#define XXX_X__X 0xe9 +#define XXX_X_X_ 0xea +#define XXX_X_XX 0xeb +#define XXX_XX__ 0xec +#define XXX_XX_X 0xed +#define XXX_XXX_ 0xee +#define XXX_XXXX 0xef +#define XXXX____ 0xf0 +#define XXXX___X 0xf1 +#define XXXX__X_ 0xf2 +#define XXXX__XX 0xf3 +#define XXXX_X__ 0xf4 +#define XXXX_X_X 0xf5 +#define XXXX_XX_ 0xf6 +#define XXXX_XXX 0xf7 +#define XXXXX___ 0xf8 +#define XXXXX__X 0xf9 +#define XXXXX_X_ 0xfa +#define XXXXX_XX 0xfb +#define XXXXXX__ 0xfc +#define XXXXXX_X 0xfd +#define XXXXXXX_ 0xfe +#define XXXXXXXX 0xff + +/********************************************************************* +* +* Compatibility with older versions +*/ +#define GUI_DispString_UC GUI_UC_DispString +#define TOUCH_X_ActivateX GUI_TOUCH_X_ActivateX +#define TOUCH_X_ActivateY GUI_TOUCH_X_ActivateY +#define TOUCH_X_Disable GUI_TOUCH_X_Disable +#define TOUCH_X_MeasureX GUI_TOUCH_X_MeasureX +#define TOUCH_X_MeasureY GUI_TOUCH_X_MeasureY +#define GUI_SelLayer GUI_SelectLayer +#define GUI_MEMDEV_FadeDevices GUI_MEMDEV_FadeInDevices +#if defined(__cplusplus) +} +#endif + +#endif /* ifdef GUI_H */ + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/GUIDRV_DCache.h b/example/GUI/STemWin/inc/GUIDRV_DCache.h new file mode 100755 index 0000000000..f21c3352df --- /dev/null +++ b/example/GUI/STemWin/inc/GUIDRV_DCache.h @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GUIDRV_DCache.h +Purpose : Interface definition for GUIDRV_DCache driver +---------------------------END-OF-HEADER------------------------------ +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef GUIDRV_DCACHE_H +#define GUIDRV_DCACHE_H + +#if defined(__cplusplus) +extern "C" { /* Make sure we have C-declarations in C++ programs */ +#endif + +/********************************************************************* +* +* Display driver +*/ +// +// Address +// +extern const GUI_DEVICE_API GUIDRV_DCache_API; + +// +// Macros to be used in configuration files +// +#if defined(WIN32) && !defined(LCD_SIMCONTROLLER) + + #define GUIDRV_DCACHE &GUIDRV_Win_API + +#else + + #define GUIDRV_DCACHE &GUIDRV_DCache_API + +#endif + +/********************************************************************* +* +* Public routines +*/ +#if defined(WIN32) && !defined(LCD_SIMCONTROLLER) + + #define GUIDRV_DCache_AddDriver(pDevice, pDriver) + #define GUIDRV_DCache_SetMode1bpp(pDevice) + +#else + + void GUIDRV_DCache_AddDriver (GUI_DEVICE * pDevice, GUI_DEVICE * pDriver); + void GUIDRV_DCache_SetMode1bpp(GUI_DEVICE * pDevice); + +#endif + +#if defined(__cplusplus) +} +#endif + +#endif /* GUIDRV_DCACHE_H */ + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/GUIDRV_DCache_Private.h b/example/GUI/STemWin/inc/GUIDRV_DCache_Private.h new file mode 100755 index 0000000000..6fd76fc0e7 --- /dev/null +++ b/example/GUI/STemWin/inc/GUIDRV_DCache_Private.h @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GUIDRV_DCache_Private.h +Purpose : Private declarations for GUIDRV_DCache driver +---------------------------END-OF-HEADER------------------------------ +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef GUIDRV_DCACHE_PRIVATE_H +#define GUIDRV_DCACHE_PRIVATE_H + +#include "GUIDRV_DCache.h" + +#if defined(__cplusplus) +extern "C" { /* Make sure we have C-declarations in C++ programs */ +#endif + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ +// +// Use unique context identified +// +#define DRIVER_CONTEXT DRIVER_CONTEXT_DCACHE + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ +/********************************************************************* +* +* DRIVER_CONTEXT +*/ +typedef struct { + // + // Data + // + int xSize, ySize; // Display size + int vxSize, vySize; // Virtual display size + int BitsPerPixelDriver; + int BitsPerPixel; + int NumColors; + LCD_PIXELINDEX IndexMask; + U32 MemSize; + GUI_RECT rDirty; + const GUI_DEVICE_API * pMemdev_API; + // + // Cache mamagement + // + void (* pfFlush )(GUI_DEVICE * pDevice); + void (* pfSendCacheRect)(GUI_DEVICE * pDevice, int x0, int y0, int x1, int y1); + // + // Setting the rectangle to be filled up within the real driver + // + void (* pfSetRect )(GUI_DEVICE * pDevice, int x0, int y0, int x1, int y1, int OnOff); + // + // Mode dependent drawing functions + // + void (* pfDrawBitmap )(GUI_DEVICE * pDevice, int x0, int y0, int xsize, int ysize, int _BitsPerPixel, int BytesPerLine, const U8 * pData, int Diff, const LCD_PIXELINDEX * pTrans); + void (* pfFillRect )(GUI_DEVICE * pDevice, int x0, int y0, int x1, int y1); + LCD_PIXELINDEX (* pfGetPixelIndex)(GUI_DEVICE * pDevice, int x, int y); + void (* pfSetPixelIndex)(GUI_DEVICE * pDevice, int x, int y, LCD_PIXELINDEX ColorIndex); + // + // Request information + // + I32 (* pfGetDevProp )(GUI_DEVICE * pDevice, int Index); + // + // Initialization + // + void (* pfInit) (GUI_DEVICE * pDevice); + // + // Conversion array from cache to real display driver + // + LCD_PIXELINDEX * pConvert; + LCD_PIXELINDEX * pIndex; + // + // Cache + // + U8 * pVRAM; + U8 * pVRAM_Lock; + int CacheLocked; + int CacheStat; + int CacheDirty; + // + // The driver which is used for the actual drawing operations + // + GUI_DEVICE * pDriver; +} DRIVER_CONTEXT; + +/********************************************************************* +* +* Private interface +* +********************************************************************** +*/ +void GUIDRV_DCache__AddDirtyRect (DRIVER_CONTEXT * pContext, int x0, int y0, int x1, int y1); +void GUIDRV_DCache__ClearDirtyRect(DRIVER_CONTEXT * pContext); +void GUIDRV_DCache__InitOnce (GUI_DEVICE * pDevice); + +#if defined(__cplusplus) +} +#endif + +#endif /* GUIDRV_DCACHE_PRIVATE_H */ + +/*************************** End of file ****************************/ + diff --git a/example/GUI/STemWin/inc/GUIDRV_Dist.h b/example/GUI/STemWin/inc/GUIDRV_Dist.h new file mode 100755 index 0000000000..7cf8d25f69 --- /dev/null +++ b/example/GUI/STemWin/inc/GUIDRV_Dist.h @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GUIDRV_Dist.h +Purpose : Interface definition for GUIDRV_Dist driver +---------------------------END-OF-HEADER------------------------------ +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef GUIDRV_DIST_H +#define GUIDRV_DIST_H + +#if defined(__cplusplus) +extern "C" { /* Make sure we have C-declarations in C++ programs */ +#endif + +/********************************************************************* +* +* Display driver +*/ +// +// Address +// +extern const GUI_DEVICE_API GUIDRV_Dist_API; + +// +// Macros to be used in configuration files +// +#if defined(WIN32) && !defined(LCD_SIMCONTROLLER) + + #define GUIDRV_DIST &GUIDRV_Win_API + +#else + + #define GUIDRV_DIST &GUIDRV_Dist_API + +#endif + +/********************************************************************* +* +* Public routines +*/ +#if defined(WIN32) && !defined(LCD_SIMCONTROLLER) + + #define GUIDRV_Dist_AddDriver(pDevice, pDriver, pRect) + +#else + + void GUIDRV_Dist_AddDriver(GUI_DEVICE * pDevice, GUI_DEVICE * pDriver, GUI_RECT * pRect); + +#endif + +#if defined(__cplusplus) +} +#endif + +#endif /* GUIDRV_DIST_H */ + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/GUIDRV_FlexColor.h b/example/GUI/STemWin/inc/GUIDRV_FlexColor.h new file mode 100755 index 0000000000..5e27036a2e --- /dev/null +++ b/example/GUI/STemWin/inc/GUIDRV_FlexColor.h @@ -0,0 +1,299 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GUIDRV_FlexColor.h +Purpose : Interface definition for GUIDRV_FlexColor driver +---------------------------END-OF-HEADER------------------------------ +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef GUIDRV_FLEXCOLOR_H +#define GUIDRV_FLEXCOLOR_H + +#include "GUI.h" + +#if defined(__cplusplus) +extern "C" { /* Make sure we have C-declarations in C++ programs */ +#endif + +/********************************************************************* +* +* Configuration macros +*/ +// +// Operation modes (16bpp) +// +#define GUIDRV_FLEXCOLOR_M16C0B8 GUIDRV_FlexColor_SetMode16bppC0B8 +#define GUIDRV_FLEXCOLOR_M16C1B8 GUIDRV_FlexColor_SetMode16bppC1B8 +#define GUIDRV_FLEXCOLOR_M16C0B16 GUIDRV_FlexColor_SetMode16bppC0B16 +#define GUIDRV_FLEXCOLOR_M16C1B16 GUIDRV_FlexColor_SetMode16bppC1B16 + +// +// Operation modes (18bpp) +// +#define GUIDRV_FLEXCOLOR_M18C0B9 GUIDRV_FlexColor_SetMode18bppC0B9 +#define GUIDRV_FLEXCOLOR_M18C1B9 GUIDRV_FlexColor_SetMode18bppC1B9 +#define GUIDRV_FLEXCOLOR_M18C0B18 GUIDRV_FlexColor_SetMode18bppC0B18 +#define GUIDRV_FLEXCOLOR_M18C1B18 GUIDRV_FlexColor_SetMode18bppC1B18 + +// +// Operation mode (24bpp) +// +#define GUIDRV_FLEXCOLOR_M24C0B8 GUIDRV_FlexColor_SetMode24bppC0B8 + +// +// Controller selection +// +#define GUIDRV_FLEXCOLOR_F66702 GUIDRV_FlexColor_SetFunc66702 +#define GUIDRV_FLEXCOLOR_F66708 GUIDRV_FlexColor_SetFunc66708 +#define GUIDRV_FLEXCOLOR_F66709 GUIDRV_FlexColor_SetFunc66709 +#define GUIDRV_FLEXCOLOR_F66712 GUIDRV_FlexColor_SetFunc66712 +#define GUIDRV_FLEXCOLOR_F66714 GUIDRV_FlexColor_SetFunc66714 +#define GUIDRV_FLEXCOLOR_F66715 GUIDRV_FlexColor_SetFunc66715 +#define GUIDRV_FLEXCOLOR_F66718 GUIDRV_FlexColor_SetFunc66718 +#define GUIDRV_FLEXCOLOR_F66719 GUIDRV_FlexColor_SetFunc66719 +#define GUIDRV_FLEXCOLOR_F66720 GUIDRV_FlexColor_SetFunc66720 +#define GUIDRV_FLEXCOLOR_F66721 GUIDRV_FlexColor_SetFunc66721 +#define GUIDRV_FLEXCOLOR_F66722 GUIDRV_FlexColor_SetFunc66722 +#define GUIDRV_FLEXCOLOR_F66723 GUIDRV_FlexColor_SetFunc66723 +#define GUIDRV_FLEXCOLOR_F66772 GUIDRV_FlexColor_SetFunc66772 + +// +// Hardware interfaces +// +#define GUIDRV_FLEXCOLOR_IF_TYPE_I 0 +#define GUIDRV_FLEXCOLOR_IF_TYPE_II 1 + +// +// Reading interface +// +#define GUIDRV_FLEXCOLOR_READ_FUNC_I 0 +#define GUIDRV_FLEXCOLOR_READ_FUNC_II 1 +#define GUIDRV_FLEXCOLOR_READ_FUNC_III 2 + +/********************************************************************* +* +* Configuration structure +*/ +typedef struct { + // + // Driver specific configuration items + // + int FirstSEG; + int FirstCOM; + int Orientation; + U16 RegEntryMode; + int NumDummyReads; +} CONFIG_FLEXCOLOR; + +/********************************************************************* +* +* Display drivers +*/ +// +// Addresses +// +extern const GUI_DEVICE_API GUIDRV_Win_API; + +extern const GUI_DEVICE_API GUIDRV_FlexColor_API; + +// +// Macros to be used in configuration files +// +#if defined(WIN32) && !defined(LCD_SIMCONTROLLER) + + #define GUIDRV_FLEXCOLOR &GUIDRV_Win_API + +#else + + #define GUIDRV_FLEXCOLOR &GUIDRV_FlexColor_API + +#endif + +/********************************************************************* +* +* Configuration interface +*/ +#if !defined(WIN32) || defined(LCD_SIMCONTROLLER) + + // + // Display controller configuration + // + void GUIDRV_FlexColor_SetFunc66702 (GUI_DEVICE * pDevice); + void GUIDRV_FlexColor_SetFunc66708 (GUI_DEVICE * pDevice); + void GUIDRV_FlexColor_SetFunc66709 (GUI_DEVICE * pDevice); + void GUIDRV_FlexColor_SetFunc66712 (GUI_DEVICE * pDevice); + void GUIDRV_FlexColor_SetFunc66714 (GUI_DEVICE * pDevice); + void GUIDRV_FlexColor_SetFunc66715 (GUI_DEVICE * pDevice); + void GUIDRV_FlexColor_SetFunc66718 (GUI_DEVICE * pDevice); + void GUIDRV_FlexColor_SetFunc66719 (GUI_DEVICE * pDevice); + void GUIDRV_FlexColor_SetFunc66720 (GUI_DEVICE * pDevice); + void GUIDRV_FlexColor_SetFunc66721 (GUI_DEVICE * pDevice); + void GUIDRV_FlexColor_SetFunc66722 (GUI_DEVICE * pDevice); + void GUIDRV_FlexColor_SetFunc66723 (GUI_DEVICE * pDevice); + void GUIDRV_FlexColor_SetFunc66772 (GUI_DEVICE * pDevice); + + // + // Operation mode configuration (16bpp) + // + void GUIDRV_FlexColor_SetMode16bppC0B8 (GUI_DEVICE * pDevice); + void GUIDRV_FlexColor_SetMode16bppC1B8 (GUI_DEVICE * pDevice); + void GUIDRV_FlexColor_SetMode16bppC0B16(GUI_DEVICE * pDevice); + void GUIDRV_FlexColor_SetMode16bppC1B16(GUI_DEVICE * pDevice); + + // + // Drawing mode configuration (18bpp) + // + void GUIDRV_FlexColor_SetMode18bppC0B9 (GUI_DEVICE * pDevice); + void GUIDRV_FlexColor_SetMode18bppC1B9 (GUI_DEVICE * pDevice); + void GUIDRV_FlexColor_SetMode18bppC0B18(GUI_DEVICE * pDevice); + void GUIDRV_FlexColor_SetMode18bppC1B18(GUI_DEVICE * pDevice); + + // + // Drawing mode configuration (24bpp) + // + void GUIDRV_FlexColor_SetMode24bppC0B8 (GUI_DEVICE * pDevice); + + // + // User interface + // + void GUIDRV_FlexColor_SetFunc(GUI_DEVICE * pDevice, GUI_PORT_API * pHW_API, void (* pfFunc)(GUI_DEVICE *), void (* pfMode)(GUI_DEVICE *)); + void GUIDRV_FlexColor_Config (GUI_DEVICE * pDevice, CONFIG_FLEXCOLOR * pConfig); + + // + // Setting up hardware interface to be used + // + void GUIDRV_FlexColor_SetInterface66712_B9 (GUI_DEVICE * pDevice, int Type); + void GUIDRV_FlexColor_SetInterface66712_B18(GUI_DEVICE * pDevice, int Type); + #define GUIDRV_FlexColor_SetInterface66715_B9(pDevice, Type) GUIDRV_FlexColor_SetInterface66712_B9(pDevice, Type) + #define GUIDRV_FlexColor_SetInterface66715_B18(pDevice, Type) GUIDRV_FlexColor_SetInterface66712_B18(pDevice, Type) + + // + // Setting up interface for reading back data + // + void GUIDRV_FlexColor_SetReadFunc66709_B16(GUI_DEVICE * pDevice, int Func); + void GUIDRV_FlexColor_SetReadFunc66712_B9 (GUI_DEVICE * pDevice, int Func); + void GUIDRV_FlexColor_SetReadFunc66712_B16(GUI_DEVICE * pDevice, int Func); + #define GUIDRV_FlexColor_SetReadFunc66715_B9(pDevice, Func) GUIDRV_FlexColor_SetReadFunc66712_B9(pDevice, Func) + #define GUIDRV_FlexColor_SetReadFunc66715_B16(pDevice, Func) GUIDRV_FlexColor_SetReadFunc66712_B16(pDevice, Func) + void GUIDRV_FlexColor_SetReadFunc66720_B16(GUI_DEVICE * pDevice, int Func); + void GUIDRV_FlexColor_SetReadFunc66772_B8 (GUI_DEVICE * pDevice, int Func); + void GUIDRV_FlexColor_SetReadFunc66772_B16(GUI_DEVICE * pDevice, int Func); + +#else + + // + // Display controller configuration + // + #define GUIDRV_FlexColor_SetFunc66708(pDevice) + #define GUIDRV_FlexColor_SetFunc66709(pDevice) + #define GUIDRV_FlexColor_SetFunc66712(pDevice) + #define GUIDRV_FlexColor_SetFunc66714(pDevice) + #define GUIDRV_FlexColor_SetFunc66715(pDevice) + #define GUIDRV_FlexColor_SetFunc66718(pDevice) + #define GUIDRV_FlexColor_SetFunc66719(pDevice) + #define GUIDRV_FlexColor_SetFunc66720(pDevice) + #define GUIDRV_FlexColor_SetFunc66721(pDevice) + #define GUIDRV_FlexColor_SetFunc66722(pDevice) + #define GUIDRV_FlexColor_SetFunc66723(pDevice) + #define GUIDRV_FlexColor_SetFunc66772(pDevice) + + // + // Operation mode configuration (16bpp) + // + #define GUIDRV_FlexColor_SetMode16bppC0B8(pDevice) + #define GUIDRV_FlexColor_SetMode16bppC1B8(pDevice) + #define GUIDRV_FlexColor_SetMode16bppC0B16(pDevice) + #define GUIDRV_FlexColor_SetMode16bppC1B16(pDevice) + + // + // Drawing mode configuration (18bpp) + // + #define GUIDRV_FlexColor_SetMode18bppC0B9(pDevice) + #define GUIDRV_FlexColor_SetMode18bppC1B9(pDevice) + #define GUIDRV_FlexColor_SetMode18bppC0B18(pDevice) + #define GUIDRV_FlexColor_SetMode18bppC1B18(pDevice) + + // + // User interface + // + #define GUIDRV_FlexColor_SetFunc(pDevice, pHW_API, pfFunc, pfMode) + #define GUIDRV_FlexColor_Config(pDevice, pConfig) + + // + // Setting up hardware interface to be used + // + #define GUIDRV_FlexColor_SetInterface66712_B9(pDevice, Type) + #define GUIDRV_FlexColor_SetInterface66712_B18(pDevice, Type) + #define GUIDRV_FlexColor_SetInterface66720_B18(pDevice, Type) + #define GUIDRV_FlexColor_SetInterface66715_B9(pDevice, Type) + #define GUIDRV_FlexColor_SetInterface66715_B18(pDevice, Type) + + // + // Setting up interface for reading back data + // + #define GUIDRV_FlexColor_SetReadFunc66709_B16(pDevice, Func) + #define GUIDRV_FlexColor_SetReadFunc66712_B9(pDevice, Func) + #define GUIDRV_FlexColor_SetReadFunc66712_B16(pDevice, Func) + #define GUIDRV_FlexColor_SetReadFunc66715_B9(pDevice, Func) + #define GUIDRV_FlexColor_SetReadFunc66715_B16(pDevice, Func) + #define GUIDRV_FlexColor_SetReadFunc66720_B16(pDevice, Func) + #define GUIDRV_FlexColor_SetReadFunc66772_B8(pDevice, Func) + #define GUIDRV_FlexColor_SetReadFunc66772_B16(pDevice, Func) + +#endif + +#if defined(__cplusplus) +} +#endif + +#endif /* GUIDRV_FLEXCOLOR_H */ + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/GUIDRV_FlexColor_Private.h b/example/GUI/STemWin/inc/GUIDRV_FlexColor_Private.h new file mode 100755 index 0000000000..f1f2e14ab0 --- /dev/null +++ b/example/GUI/STemWin/inc/GUIDRV_FlexColor_Private.h @@ -0,0 +1,268 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GUIDRV_FlexColor_Private.h +Purpose : Private declarations for GUIDRV_FlexColor driver +---------------------------END-OF-HEADER------------------------------ +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +#include "GUIDRV_FlexColor.h" + +#ifndef GUIDRV_FLEXCOLOR_PRIVATE_H +#define GUIDRV_FLEXCOLOR_PRIVATE_H + +#if defined(__cplusplus) +extern "C" { /* Make sure we have C-declarations in C++ programs */ +#endif + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ +#define LCD_WRITE_BUFFER_SIZE 500 + +#define FLEXCOLOR_CF_MANAGE_ORIENTATION (1 << 0) +#define FLEXCOLOR_CF_RAM_ADDR_SET (1 << 1) +#define FLEXCOLOR_CF_SET_CURSOR (1 << 2) + +#define FLEXCOLOR_CF_DEFAULT FLEXCOLOR_CF_RAM_ADDR_SET + +#define FLEXCOLOR_MAX_NUM_DUMMY_READS 5 +#define FLEXCOLOR_NUM_DUMMY_READS 1 + +#define PUSH_RECT 0 +#define POP_RECT 1 + +// +// Use unique context identified +// +#define DRIVER_CONTEXT DRIVER_CONTEXT_FLEXCOLOR + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ + +typedef struct DRIVER_CONTEXT DRIVER_CONTEXT; + +/********************************************************************* +* +* DRIVER_CONTEXT +*/ +struct DRIVER_CONTEXT { + // + // Data + // + int xSize, ySize; // Display size + int vxSize, vySize; // Virtual display size + int x0, y0, x1, y1; // Current rectangle + int NumDummyReads; // Number of required dummy reads + U16 RegEntryMode; // Can be used for storing additional configuration bits for 'EntryMode' register which is modified by the driver + U16 Flags; + LCD_PIXELINDEX IndexMask; + int FirstSEG, FirstCOM; + int Orientation; + int BitsPerPixel; + int Shift; + GUI_DEVICE * pDevice; + const GUI_DEVICE_API * pMemdev_API; + // + // Cache + // + void * pVRAM; + int CacheLocked; + int CacheStat; + int xPos, yPos; + U32 Addr; + GUI_RECT CacheRect; + // + // Buffers + // + void * pWriteBuffer; + void * pLineBuffer; + U8 aPair_8 [3 + FLEXCOLOR_MAX_NUM_DUMMY_READS]; + U16 aPair_16[3 + FLEXCOLOR_MAX_NUM_DUMMY_READS]; + // + // Functions for writing single items (data, cmd) regardless of the interface and getting the status + // + U16 (* pfReadReg) (DRIVER_CONTEXT * _pContext); + void (* pfSetReg) (DRIVER_CONTEXT * _pContext, U16 _Data); + void (* pfWritePara) (DRIVER_CONTEXT * _pContext, U16 _Data); + void (* pfSetInterface)(DRIVER_CONTEXT * _pContext, int _BusWidth); + // + // Setting read mode, required for RA8870 + // + void (* pfSetReadMode)(DRIVER_CONTEXT * _pContext, int OnOff, int SetCursor); + // + // Cache related function pointers + // + void (* pfSendCacheRect)(DRIVER_CONTEXT * _pContext, int _x0, int _y0, int _x1, int _y1); + U32 (* pfReadData) (DRIVER_CONTEXT * _pContext); + void (* pfWriteData) (DRIVER_CONTEXT * _pContext, U32 _PixelIndex); + // + // Controller specific routines + // + void (* pfSetRect) (DRIVER_CONTEXT * _pContext, int _x0, int _y0, int _x1, int _y1); + void (* pfSetPhysRAMAddr) (DRIVER_CONTEXT * _pContext, int _x, int _y); + void (* pfSetOrientation) (DRIVER_CONTEXT * _pContext); + U16 (* pfReadPixel_16bpp_B16)(DRIVER_CONTEXT * _pContext); + U16 (* pfReadPixel_16bpp_B8) (DRIVER_CONTEXT * _pContext); + U32 (* pfReadPixel_18bpp_B9) (DRIVER_CONTEXT * _pContext); + U32 (* pfReadPixel_18bpp_B18)(DRIVER_CONTEXT * _pContext); + U32 (* pfReadPixel_32bpp_B8) (DRIVER_CONTEXT * _pContext); + void (* pfReadRect_16bpp_B16) (GUI_DEVICE * _pDevice, int _x0, int _y0, int _x1, int _y1, U16 * _pBuffer); + void (* pfReadRect_16bpp_B8) (GUI_DEVICE * _pDevice, int _x0, int _y0, int _x1, int _y1, U16 * _pBuffer); + void (* pfReadRect_18bpp_B9) (GUI_DEVICE * _pDevice, int _x0, int _y0, int _x1, int _y1, U32 * _pBuffer); + void (* pfReadRect_18bpp_B18) (GUI_DEVICE * _pDevice, int _x0, int _y0, int _x1, int _y1, U32 * _pBuffer); + void (* pfReadRect_32bpp_B8) (GUI_DEVICE * _pDevice, int _x0, int _y0, int _x1, int _y1, U32 * _pBuffer); + // + // Custom read functions + // + U16 (* pfReadPixelCust_16bpp) (int LayerIndex); + U32 (* pfReadPixelCust_18bpp) (int LayerIndex); + void(* pfReadMPixelCust_16bpp)(int LayerIndex, U16 * pBuffer, U32 NumPixels); + void(* pfReadMPixelCust_18bpp)(int LayerIndex, U32 * pBuffer, U32 NumPixels); + // + // Mode dependent drawing functions + // + void (* pfDrawBitmap )(GUI_DEVICE * _pDevice, int _x0, int _y0, int _xsize, int _ysize, int _BitsPerPixel, int _BytesPerLine, const U8 * _pData, int _Diff, const LCD_PIXELINDEX * _pTrans); + void (* pfFillRect )(GUI_DEVICE * _pDevice, int _x0, int _y0, int _x1, int _y1); + LCD_PIXELINDEX(* pfGetPixelIndex)(GUI_DEVICE * _pDevice, int _x, int _y); + void (* pfSetPixelIndex)(GUI_DEVICE * _pDevice, int _x, int _y, LCD_PIXELINDEX _ColorIndex); + int (* pfControlCache )(GUI_DEVICE * _pDevice, int _Cmd); + void (* pfRefresh )(GUI_DEVICE * _pDevice); + // + // Controller dependent function pointers + // + void (* pfReadRect)(void); + // + // Orientation + // + int (* pfLog2PhysX)(DRIVER_CONTEXT * _pContext, int _x, int _y); + int (* pfLog2PhysY)(DRIVER_CONTEXT * _pContext, int _x, int _y); + // + // Function pointer for setting up pfLog2Phys + // + void (* pfSetLog2Phys)(DRIVER_CONTEXT * _pContext); + // + // Hardware routines + // + GUI_PORT_API HW_API; +}; + +/********************************************************************* +* +* Private functions +* +********************************************************************** +*/ +void GUIDRV_FlexColor__InitOnce (GUI_DEVICE * pDevice); +int GUIDRV_FlexColor__ControlCache (GUI_DEVICE * pDevice, int Cmd); +void GUIDRV_FlexColor__Refresh (GUI_DEVICE * pDevice); + +void GUIDRV_FlexColor__AddCacheRect (DRIVER_CONTEXT * pContext); +void GUIDRV_FlexColor__ManageRect (DRIVER_CONTEXT * pContext, int Cmd); +void GUIDRV_FlexColor__SetCacheAddr (DRIVER_CONTEXT * pContext, int x, int y); +void GUIDRV_FlexColor__SetCacheRect (DRIVER_CONTEXT * pContext, int x0, int y0, int x1, int y1); +void GUIDRV_FlexColor__SetLog2Phys (DRIVER_CONTEXT * pContext); +void GUIDRV_FlexColor__SetSubRect (DRIVER_CONTEXT * pContext, int x0, int y0, int x1, int y1); +void GUIDRV_FlexColor__ClearCacheRect (DRIVER_CONTEXT * pContext); + +LCD_PIXELINDEX GUIDRV_FlexColor__GetPixelIndexCache (GUI_DEVICE * pDevice, int x, int y); +void GUIDRV_FlexColor__SetPixelIndexCache (GUI_DEVICE * pDevice, int x, int y, LCD_PIXELINDEX PixelIndex); +LCD_PIXELINDEX GUIDRV_FlexColor__GetPixelIndexNoCache(GUI_DEVICE * pDevice, int x, int y); +void GUIDRV_FlexColor__SetPixelIndexNoCache(GUI_DEVICE * pDevice, int x, int y, LCD_PIXELINDEX PixelIndex); + +void GUIDRV_FlexColor__SetFunc66712(GUI_DEVICE * pDevice, U16 AndMask_SetAddrRAM); + +/********************************************************************* +* +* Simulation (Segger internal use only) +* +********************************************************************** +*/ +#if defined(WIN32) && defined(LCD_SIMCONTROLLER) + + extern GUI_PORT_API SIM_FlexColor_HW_API; + + void SIM_FlexColor_Config (GUI_DEVICE * pDevice, int Orientation, int xSize, int ySize, int FirstSEG, int FirstCOM, int BitsPerPixel, int NumDummyReads); + void SIM_FlexColor_SetBus8 (GUI_DEVICE * pDevice); + void SIM_FlexColor_SetBus9 (GUI_DEVICE * pDevice); + void SIM_FlexColor_SetBus16 (GUI_DEVICE * pDevice); + void SIM_FlexColor_SetBus32 (GUI_DEVICE * pDevice, int Shift); + void SIM_FlexColor_SetBus8_24 (GUI_DEVICE * pDevice); + void SIM_FlexColor_SetFunc66702(GUI_DEVICE * pDevice); + void SIM_FlexColor_SetFunc66708(GUI_DEVICE * pDevice); + void SIM_FlexColor_SetFunc66709(GUI_DEVICE * pDevice); + void SIM_FlexColor_SetFunc66712(GUI_DEVICE * pDevice); + void SIM_FlexColor_SetFunc66714(GUI_DEVICE * pDevice); + void SIM_FlexColor_SetFunc66715(GUI_DEVICE * pDevice); + void SIM_FlexColor_SetFunc66718(GUI_DEVICE * pDevice); + void SIM_FlexColor_SetFunc66719(GUI_DEVICE * pDevice); + void SIM_FlexColor_SetFunc66720(GUI_DEVICE * pDevice); + void SIM_FlexColor_SetFunc66721(GUI_DEVICE * pDevice); + void SIM_FlexColor_SetFunc66722(GUI_DEVICE * pDevice); + void SIM_FlexColor_SetFunc66723(GUI_DEVICE * pDevice); + void SIM_FlexColor_SetFunc66772(GUI_DEVICE * pDevice); + +#endif + +#if defined(__cplusplus) +} +#endif + +#endif /* GUIDRV_FLEXCOLOR_PRIVATE_H */ + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/GUIDRV_Lin.h b/example/GUI/STemWin/inc/GUIDRV_Lin.h new file mode 100755 index 0000000000..2220cbd5cf --- /dev/null +++ b/example/GUI/STemWin/inc/GUIDRV_Lin.h @@ -0,0 +1,277 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GUIDRV_Lin.h +Purpose : Interface definition for GUIDRV_Lin driver +---------------------------END-OF-HEADER------------------------------ +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef GUIDRV_LIN_H +#define GUIDRV_LIN_H + +#if defined(__cplusplus) +extern "C" { /* Make sure we have C-declarations in C++ programs */ +#endif + +/********************************************************************* +* +* Display drivers +*/ +// +// Addresses +// +extern const GUI_DEVICE_API GUIDRV_Win_API; + +extern const GUI_DEVICE_API GUIDRV_Lin_1_API; +extern const GUI_DEVICE_API GUIDRV_Lin_OY_1_API; +extern const GUI_DEVICE_API GUIDRV_Lin_OX_1_API; +extern const GUI_DEVICE_API GUIDRV_Lin_OXY_1_API; +extern const GUI_DEVICE_API GUIDRV_Lin_OS_1_API; +extern const GUI_DEVICE_API GUIDRV_Lin_OSY_1_API; +extern const GUI_DEVICE_API GUIDRV_Lin_OSX_1_API; +extern const GUI_DEVICE_API GUIDRV_Lin_OSXY_1_API; + +extern const GUI_DEVICE_API GUIDRV_Lin_2_API; +extern const GUI_DEVICE_API GUIDRV_Lin_OY_2_API; +extern const GUI_DEVICE_API GUIDRV_Lin_OX_2_API; +extern const GUI_DEVICE_API GUIDRV_Lin_OXY_2_API; +extern const GUI_DEVICE_API GUIDRV_Lin_OS_2_API; +extern const GUI_DEVICE_API GUIDRV_Lin_OSY_2_API; +extern const GUI_DEVICE_API GUIDRV_Lin_OSX_2_API; +extern const GUI_DEVICE_API GUIDRV_Lin_OSXY_2_API; + +extern const GUI_DEVICE_API GUIDRV_Lin_4_API; +extern const GUI_DEVICE_API GUIDRV_Lin_OY_4_API; +extern const GUI_DEVICE_API GUIDRV_Lin_OX_4_API; +extern const GUI_DEVICE_API GUIDRV_Lin_OXY_4_API; +extern const GUI_DEVICE_API GUIDRV_Lin_OS_4_API; +extern const GUI_DEVICE_API GUIDRV_Lin_OSY_4_API; +extern const GUI_DEVICE_API GUIDRV_Lin_OSX_4_API; +extern const GUI_DEVICE_API GUIDRV_Lin_OSXY_4_API; + +extern const GUI_DEVICE_API GUIDRV_Lin_8_API; +extern const GUI_DEVICE_API GUIDRV_Lin_OY_8_API; +extern const GUI_DEVICE_API GUIDRV_Lin_OX_8_API; +extern const GUI_DEVICE_API GUIDRV_Lin_OXY_8_API; +extern const GUI_DEVICE_API GUIDRV_Lin_OS_8_API; +extern const GUI_DEVICE_API GUIDRV_Lin_OSY_8_API; +extern const GUI_DEVICE_API GUIDRV_Lin_OSX_8_API; +extern const GUI_DEVICE_API GUIDRV_Lin_OSXY_8_API; + +extern const GUI_DEVICE_API GUIDRV_Lin_16_API; +extern const GUI_DEVICE_API GUIDRV_Lin_OY_16_API; +extern const GUI_DEVICE_API GUIDRV_Lin_OX_16_API; +extern const GUI_DEVICE_API GUIDRV_Lin_OXY_16_API; +extern const GUI_DEVICE_API GUIDRV_Lin_OS_16_API; +extern const GUI_DEVICE_API GUIDRV_Lin_OSY_16_API; +extern const GUI_DEVICE_API GUIDRV_Lin_OSX_16_API; +extern const GUI_DEVICE_API GUIDRV_Lin_OSXY_16_API; + +extern const GUI_DEVICE_API GUIDRV_Lin_24_API; +extern const GUI_DEVICE_API GUIDRV_Lin_OY_24_API; +extern const GUI_DEVICE_API GUIDRV_Lin_OX_24_API; +extern const GUI_DEVICE_API GUIDRV_Lin_OXY_24_API; +extern const GUI_DEVICE_API GUIDRV_Lin_OS_24_API; +extern const GUI_DEVICE_API GUIDRV_Lin_OSY_24_API; +extern const GUI_DEVICE_API GUIDRV_Lin_OSX_24_API; +extern const GUI_DEVICE_API GUIDRV_Lin_OSXY_24_API; + +extern const GUI_DEVICE_API GUIDRV_Lin_32_API; +extern const GUI_DEVICE_API GUIDRV_Lin_OY_32_API; +extern const GUI_DEVICE_API GUIDRV_Lin_OX_32_API; +extern const GUI_DEVICE_API GUIDRV_Lin_OXY_32_API; +extern const GUI_DEVICE_API GUIDRV_Lin_OS_32_API; +extern const GUI_DEVICE_API GUIDRV_Lin_OSY_32_API; +extern const GUI_DEVICE_API GUIDRV_Lin_OSX_32_API; +extern const GUI_DEVICE_API GUIDRV_Lin_OSXY_32_API; + +// +// Macros to be used in configuration files +// +#if defined(WIN32) && !defined(LCD_SIMCONTROLLER) + + #define GUIDRV_LIN_1 &GUIDRV_Win_API + #define GUIDRV_LIN_OY_1 &GUIDRV_Win_API + #define GUIDRV_LIN_OX_1 &GUIDRV_Win_API + #define GUIDRV_LIN_OXY_1 &GUIDRV_Win_API + #define GUIDRV_LIN_OS_1 &GUIDRV_Win_API + #define GUIDRV_LIN_OSY_1 &GUIDRV_Win_API + #define GUIDRV_LIN_OSX_1 &GUIDRV_Win_API + #define GUIDRV_LIN_OSXY_1 &GUIDRV_Win_API + + #define GUIDRV_LIN_2 &GUIDRV_Win_API + #define GUIDRV_LIN_OY_2 &GUIDRV_Win_API + #define GUIDRV_LIN_OX_2 &GUIDRV_Win_API + #define GUIDRV_LIN_OXY_2 &GUIDRV_Win_API + #define GUIDRV_LIN_OS_2 &GUIDRV_Win_API + #define GUIDRV_LIN_OSY_2 &GUIDRV_Win_API + #define GUIDRV_LIN_OSX_2 &GUIDRV_Win_API + #define GUIDRV_LIN_OSXY_2 &GUIDRV_Win_API + + #define GUIDRV_LIN_4 &GUIDRV_Win_API + #define GUIDRV_LIN_OY_4 &GUIDRV_Win_API + #define GUIDRV_LIN_OX_4 &GUIDRV_Win_API + #define GUIDRV_LIN_OXY_4 &GUIDRV_Win_API + #define GUIDRV_LIN_OS_4 &GUIDRV_Win_API + #define GUIDRV_LIN_OSY_4 &GUIDRV_Win_API + #define GUIDRV_LIN_OSX_4 &GUIDRV_Win_API + #define GUIDRV_LIN_OSXY_4 &GUIDRV_Win_API + + #define GUIDRV_LIN_8 &GUIDRV_Win_API + #define GUIDRV_LIN_OY_8 &GUIDRV_Win_API + #define GUIDRV_LIN_OX_8 &GUIDRV_Win_API + #define GUIDRV_LIN_OXY_8 &GUIDRV_Win_API + #define GUIDRV_LIN_OS_8 &GUIDRV_Win_API + #define GUIDRV_LIN_OSY_8 &GUIDRV_Win_API + #define GUIDRV_LIN_OSX_8 &GUIDRV_Win_API + #define GUIDRV_LIN_OSXY_8 &GUIDRV_Win_API + + #define GUIDRV_LIN_16 &GUIDRV_Win_API + #define GUIDRV_LIN_OY_16 &GUIDRV_Win_API + #define GUIDRV_LIN_OX_16 &GUIDRV_Win_API + #define GUIDRV_LIN_OXY_16 &GUIDRV_Win_API + #define GUIDRV_LIN_OS_16 &GUIDRV_Win_API + #define GUIDRV_LIN_OSY_16 &GUIDRV_Win_API + #define GUIDRV_LIN_OSX_16 &GUIDRV_Win_API + #define GUIDRV_LIN_OSXY_16 &GUIDRV_Win_API + + #define GUIDRV_LIN_24 &GUIDRV_Win_API + #define GUIDRV_LIN_OY_24 &GUIDRV_Win_API + #define GUIDRV_LIN_OX_24 &GUIDRV_Win_API + #define GUIDRV_LIN_OXY_24 &GUIDRV_Win_API + #define GUIDRV_LIN_OS_24 &GUIDRV_Win_API + #define GUIDRV_LIN_OSY_24 &GUIDRV_Win_API + #define GUIDRV_LIN_OSX_24 &GUIDRV_Win_API + #define GUIDRV_LIN_OSXY_24 &GUIDRV_Win_API + + #define GUIDRV_LIN_32 &GUIDRV_Win_API + #define GUIDRV_LIN_OY_32 &GUIDRV_Win_API + #define GUIDRV_LIN_OX_32 &GUIDRV_Win_API + #define GUIDRV_LIN_OXY_32 &GUIDRV_Win_API + #define GUIDRV_LIN_OS_32 &GUIDRV_Win_API + #define GUIDRV_LIN_OSY_32 &GUIDRV_Win_API + #define GUIDRV_LIN_OSX_32 &GUIDRV_Win_API + #define GUIDRV_LIN_OSXY_32 &GUIDRV_Win_API + +#else + + #define GUIDRV_LIN_1 &GUIDRV_Lin_1_API + #define GUIDRV_LIN_OY_1 &GUIDRV_Lin_OY_1_API + #define GUIDRV_LIN_OX_1 &GUIDRV_Lin_OX_1_API + #define GUIDRV_LIN_OXY_1 &GUIDRV_Lin_OXY_1_API + #define GUIDRV_LIN_OS_1 &GUIDRV_Lin_OS_1_API + #define GUIDRV_LIN_OSY_1 &GUIDRV_Lin_OSY_1_API + #define GUIDRV_LIN_OSX_1 &GUIDRV_Lin_OSX_1_API + #define GUIDRV_LIN_OSXY_1 &GUIDRV_Lin_OSXY_1_API + + #define GUIDRV_LIN_2 &GUIDRV_Lin_2_API + #define GUIDRV_LIN_OY_2 &GUIDRV_Lin_OY_2_API + #define GUIDRV_LIN_OX_2 &GUIDRV_Lin_OX_2_API + #define GUIDRV_LIN_OXY_2 &GUIDRV_Lin_OXY_2_API + #define GUIDRV_LIN_OS_2 &GUIDRV_Lin_OS_2_API + #define GUIDRV_LIN_OSY_2 &GUIDRV_Lin_OSY_2_API + #define GUIDRV_LIN_OSX_2 &GUIDRV_Lin_OSX_2_API + #define GUIDRV_LIN_OSXY_2 &GUIDRV_Lin_OSXY_2_API + + #define GUIDRV_LIN_4 &GUIDRV_Lin_4_API + #define GUIDRV_LIN_OY_4 &GUIDRV_Lin_OY_4_API + #define GUIDRV_LIN_OX_4 &GUIDRV_Lin_OX_4_API + #define GUIDRV_LIN_OXY_4 &GUIDRV_Lin_OXY_4_API + #define GUIDRV_LIN_OS_4 &GUIDRV_Lin_OS_4_API + #define GUIDRV_LIN_OSY_4 &GUIDRV_Lin_OSY_4_API + #define GUIDRV_LIN_OSX_4 &GUIDRV_Lin_OSX_4_API + #define GUIDRV_LIN_OSXY_4 &GUIDRV_Lin_OSXY_4_API + + #define GUIDRV_LIN_8 &GUIDRV_Lin_8_API + #define GUIDRV_LIN_OY_8 &GUIDRV_Lin_OY_8_API + #define GUIDRV_LIN_OX_8 &GUIDRV_Lin_OX_8_API + #define GUIDRV_LIN_OXY_8 &GUIDRV_Lin_OXY_8_API + #define GUIDRV_LIN_OS_8 &GUIDRV_Lin_OS_8_API + #define GUIDRV_LIN_OSY_8 &GUIDRV_Lin_OSY_8_API + #define GUIDRV_LIN_OSX_8 &GUIDRV_Lin_OSX_8_API + #define GUIDRV_LIN_OSXY_8 &GUIDRV_Lin_OSXY_8_API + + #define GUIDRV_LIN_16 &GUIDRV_Lin_16_API + #define GUIDRV_LIN_OY_16 &GUIDRV_Lin_OY_16_API + #define GUIDRV_LIN_OX_16 &GUIDRV_Lin_OX_16_API + #define GUIDRV_LIN_OXY_16 &GUIDRV_Lin_OXY_16_API + #define GUIDRV_LIN_OS_16 &GUIDRV_Lin_OS_16_API + #define GUIDRV_LIN_OSY_16 &GUIDRV_Lin_OSY_16_API + #define GUIDRV_LIN_OSX_16 &GUIDRV_Lin_OSX_16_API + #define GUIDRV_LIN_OSXY_16 &GUIDRV_Lin_OSXY_16_API + + #define GUIDRV_LIN_24 &GUIDRV_Lin_24_API + #define GUIDRV_LIN_OY_24 &GUIDRV_Lin_OY_24_API + #define GUIDRV_LIN_OX_24 &GUIDRV_Lin_OX_24_API + #define GUIDRV_LIN_OXY_24 &GUIDRV_Lin_OXY_24_API + #define GUIDRV_LIN_OS_24 &GUIDRV_Lin_OS_24_API + #define GUIDRV_LIN_OSY_24 &GUIDRV_Lin_OSY_24_API + #define GUIDRV_LIN_OSX_24 &GUIDRV_Lin_OSX_24_API + #define GUIDRV_LIN_OSXY_24 &GUIDRV_Lin_OSXY_24_API + + #define GUIDRV_LIN_32 &GUIDRV_Lin_32_API + #define GUIDRV_LIN_OY_32 &GUIDRV_Lin_OY_32_API + #define GUIDRV_LIN_OX_32 &GUIDRV_Lin_OX_32_API + #define GUIDRV_LIN_OXY_32 &GUIDRV_Lin_OXY_32_API + #define GUIDRV_LIN_OS_32 &GUIDRV_Lin_OS_32_API + #define GUIDRV_LIN_OSY_32 &GUIDRV_Lin_OSY_32_API + #define GUIDRV_LIN_OSX_32 &GUIDRV_Lin_OSX_32_API + #define GUIDRV_LIN_OSXY_32 &GUIDRV_Lin_OSXY_32_API + +#endif + +#if defined(__cplusplus) +} +#endif + +#endif + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/GUIDRV_Lin_Opt_16.h b/example/GUI/STemWin/inc/GUIDRV_Lin_Opt_16.h new file mode 100755 index 0000000000..06a94026d3 --- /dev/null +++ b/example/GUI/STemWin/inc/GUIDRV_Lin_Opt_16.h @@ -0,0 +1,219 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GUIDRV_Lin_Opt_16.h +Purpose : Optimized routines, included by GUIDRV_Lin_..._16.c +---------------------------END-OF-HEADER------------------------------ +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +/********************************************************************* +* +* Static functions +* +********************************************************************** +*/ +/********************************************************************* +* +* _FillRectOpt16 +* +* Purpose: +* Optimized filling routine for 16 bpp +*/ +static void _FillRectOpt16(GUI_DEVICE * pDevice, int x0, int y0, int x1, int y1) { + DRIVER_CONTEXT * pContext; + U32 * pDest; + U32 * pDest0; + U32 Off, OffLine; + int RemPixels, NumLines, RemLines, RemItems; + U32 Data, ColorMask; + LCD_PIXELINDEX ColorIndex; + + pContext = (DRIVER_CONTEXT *)pDevice->u.pContext; + ColorIndex = LCD__GetColorIndex(); + Off = XY2OFF32(pContext->vxSizePhys, x0, y0); + pDest0 = OFF2PTR32(pContext->VRAMAddr, Off); + RemPixels = x1 - x0 + 1; + NumLines = y1 - y0 + 1; + OffLine = pContext->vxSizePhys >> 1; + pDest = NULL; + if (GUI_pContext->DrawMode & LCD_DRAWMODE_XOR) { + // + // First DWORD + // + if (x0 & 1) { + for (RemLines = NumLines, pDest = pDest0; RemLines; RemLines--) { + Data = READ_MEM32P(pDest); + #if (LCD_ENDIAN_BIG == 0) + Data ^= 0xFFFF0000; + #else + Data ^= 0xFFFF; + #endif + WRITE_MEM32P(pDest, Data); + pDest += OffLine; + } + pDest0++; + RemPixels--; + } + // + // Complete DWORDS + // + if (RemPixels >= 2) { + for (RemLines = NumLines; RemLines; RemLines--) { + RemItems = RemPixels; + pDest = pDest0 + OffLine * (RemLines - 1); + do { + Data = READ_MEM32P(pDest); + Data ^= 0xFFFFFFFF; + WRITE_MEM32P(pDest, Data); + pDest++; + RemItems -= 2; + } while (RemItems >= 2); + } + pDest0 = pDest; + RemPixels -= (RemPixels >> 1) << 1; + } + // + // Last DWORD + // + if (RemPixels > 0) { + for (RemLines = NumLines, pDest = pDest0; RemLines; RemLines--) { + Data = READ_MEM32P(pDest); + #if (LCD_ENDIAN_BIG == 0) + Data ^= 0xFFFF; + #else + Data ^= 0xFFFF0000; + #endif + WRITE_MEM32P(pDest, Data); + pDest += OffLine; + } + } + } else { + // + // First DWORD + // + if (x0 & 1) { + for (RemLines = NumLines, pDest = pDest0; RemLines; RemLines--) { + Data = READ_MEM32P(pDest); + #if (LCD_ENDIAN_BIG == 0) + Data &= 0xFFFF; + Data |= (((U32)ColorIndex) << 16); + #else + Data &= 0xFFFF0000; + Data |= ColorIndex; + #endif + WRITE_MEM32P(pDest, Data); + pDest += OffLine; + } + pDest0++; + RemPixels--; + } + // + // Complete DWORDS + // + ColorMask = ColorIndex * 0x00010001; + if (RemPixels >= 16) { + RemPixels -= 16; + + for (RemLines = NumLines; RemLines; RemLines--) { + RemItems = RemPixels; + pDest = pDest0 + OffLine * (RemLines - 1); + do { + WRITE_MEM32P(pDest, ColorMask); + WRITE_MEM32P(pDest + 1, ColorMask); + WRITE_MEM32P(pDest + 2, ColorMask); + WRITE_MEM32P(pDest + 3, ColorMask); + WRITE_MEM32P(pDest + 4, ColorMask); + WRITE_MEM32P(pDest + 5, ColorMask); + WRITE_MEM32P(pDest + 6, ColorMask); + WRITE_MEM32P(pDest + 7, ColorMask); + pDest += 8; + RemItems -= 16; + } while (RemItems >= 0); + } + pDest0 = pDest; + + RemPixels += 16; + RemPixels -= (RemPixels >> 4) << 4; + } + if (RemPixels >= 2) { + for (RemLines = NumLines; RemLines; RemLines--) { + RemItems = RemPixels; + pDest = pDest0 + OffLine * (RemLines - 1); + do { + WRITE_MEM32P(pDest, ColorMask); + pDest++; + RemItems -= 2; + } while (RemItems >= 2); + } + pDest0 = pDest; + RemPixels -= (RemPixels >> 1) << 1; + } + // + // Last DWORD + // + if (RemPixels > 0) { + for (RemLines = NumLines, pDest = pDest0; RemLines; RemLines--) { + Data = READ_MEM32P(pDest); + #if (LCD_ENDIAN_BIG == 0) + Data &= 0xFFFF0000; + Data |= ColorIndex; + #else + Data &= 0xFFFF; + Data |= (((U32)ColorIndex) << 16); + #endif + WRITE_MEM32P(pDest, Data); + pDest += OffLine; + } + } + } +} + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/GUIDRV_Lin_Opt_24.h b/example/GUI/STemWin/inc/GUIDRV_Lin_Opt_24.h new file mode 100755 index 0000000000..d1752ee8c4 --- /dev/null +++ b/example/GUI/STemWin/inc/GUIDRV_Lin_Opt_24.h @@ -0,0 +1,522 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GUIDRV_Lin_Opt_24.h +Purpose : Optimized routines, included by GUIDRV_Lin_..._24.c +---------------------------END-OF-HEADER------------------------------ +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +/********************************************************************* +* +* Static functions +* +********************************************************************** +*/ +/********************************************************************* +* +* _FillRectOpt24 +* +* Purpose: +* Optimized filling routine for 24 bpp +*/ +static void _FillRectOpt24(GUI_DEVICE * pDevice, int x0, int y0, int x1, int y1) { + DRIVER_CONTEXT * pContext; + U32 Off, Off0, OffLine; + int RemPixels, NumLines, RemLines, RemItems, Odd; + U32 Data, Data0, Data1, Data2; + LCD_PIXELINDEX ColorIndex; + + pContext = (DRIVER_CONTEXT *)pDevice->u.pContext; + Off0 = XY2OFF32(pContext->vxSizePhys, x0, y0); + RemPixels = x1 - x0 + 1; + Odd = x0 & 3; + NumLines = y1 - y0 + 1; + OffLine = (pContext->vxSizePhys + pContext->vxSizePhys +pContext->vxSizePhys) >> 2; + RemItems = 0; + Off = 0; +#if (LCD_ENDIAN_BIG == 0) + if (GUI_pContext->DrawMode & LCD_DRAWMODE_XOR) { + // + // First triple DWORD + // + if (Odd) { + for (RemLines = NumLines; RemLines; RemLines--) { + RemItems = RemPixels; + Off = Off0 + OffLine * (RemLines - 1); + Data = READ_MEM32(pContext->VRAMAddr, Off); + switch (Odd) { + case 1: + Data ^= 0xFF000000; + WRITE_MEM32(pContext->VRAMAddr, Off, Data); + Off++; + Data = READ_MEM32(pContext->VRAMAddr, Off); + Data ^= 0x0000FFFF; + RemItems--; + if (!RemItems) { + WRITE_MEM32(pContext->VRAMAddr, Off, Data); + break; + } + // + // no break at this position required... + // + case 2: + Data ^= 0xFFFF0000; + WRITE_MEM32(pContext->VRAMAddr, Off, Data); + Off++; + Data = READ_MEM32(pContext->VRAMAddr, Off); + Data ^= 0x000000FF; + RemItems--; + if (!RemItems) { + WRITE_MEM32(pContext->VRAMAddr, Off, Data); + break; + } + // + // no break at this position required... + // + case 3: + Data ^= 0xFFFFFF00; + RemItems--; + WRITE_MEM32(pContext->VRAMAddr, Off, Data); + Off++; + } + } + Off0 = Off; + RemPixels -= (RemPixels - RemItems); + } + // + // Complete triple DWORDS + // + if (RemPixels >= 4) { + for (RemLines = NumLines; RemLines; RemLines--) { + RemItems = RemPixels; + Off = Off0 + OffLine * (RemLines - 1); + do { + Data = READ_MEM32(pContext->VRAMAddr, Off + 0); + Data ^= 0xFFFFFFFF; + WRITE_MEM32(pContext->VRAMAddr, Off + 0, Data); + Data = READ_MEM32(pContext->VRAMAddr, Off + 1); + Data ^= 0xFFFFFFFF; + WRITE_MEM32(pContext->VRAMAddr, Off + 1, Data); + Data = READ_MEM32(pContext->VRAMAddr, Off + 2); + Data ^= 0xFFFFFFFF; + WRITE_MEM32(pContext->VRAMAddr, Off + 2, Data); + Off += 3; + } while ((RemItems -= 4) >= 4); + } + Off0 = Off; + RemPixels -= (RemPixels >> 2) << 2; + } + // + // Last triple DWORD + // + if (RemPixels) { + for (RemLines = NumLines; RemLines; RemLines--) { + RemItems = RemPixels; + Off = Off0 + OffLine * (RemLines - 1); + Data = READ_MEM32(pContext->VRAMAddr, Off); + Data ^= 0x00FFFFFF; + RemItems--; + if (!RemItems) { + WRITE_MEM32(pContext->VRAMAddr, Off, Data); + continue; + } + Data ^= 0xFF000000; + WRITE_MEM32(pContext->VRAMAddr, Off, Data); + Off++; + Data = READ_MEM32(pContext->VRAMAddr, Off); + Data ^= 0x0000FFFF; + RemItems--; + if (!RemItems) { + WRITE_MEM32(pContext->VRAMAddr, Off, Data); + continue; + } + Data ^= 0xFFFF0000; + WRITE_MEM32(pContext->VRAMAddr, Off, Data); + Off++; + Data = READ_MEM32(pContext->VRAMAddr, Off); + Data ^= 0x000000FF; + WRITE_MEM32(pContext->VRAMAddr, Off, Data); + } + } + } else { + ColorIndex = LCD__GetColorIndex() & 0xFFFFFF; + // + // First triple DWORD + // + if (Odd) { + for (RemLines = NumLines; RemLines; RemLines--) { + RemItems = RemPixels; + Off = Off0 + OffLine * (RemLines - 1); + Data = READ_MEM32(pContext->VRAMAddr, Off); + switch (Odd) { + case 1: + Data &= 0x00FFFFFF; + Data |= ColorIndex << 24; + WRITE_MEM32(pContext->VRAMAddr, Off, Data); + Off++; + Data = READ_MEM32(pContext->VRAMAddr, Off); + Data &= 0xFFFF0000; + Data |= ColorIndex >> 8; + RemItems--; + if (!RemItems) { + WRITE_MEM32(pContext->VRAMAddr, Off, Data); + break; + } + // + // no break at this position required... + // + case 2: + Data &= 0x0000FFFF; + Data |= ColorIndex << 16; + WRITE_MEM32(pContext->VRAMAddr, Off, Data); + Off++; + Data = READ_MEM32(pContext->VRAMAddr, Off); + Data &= 0xFFFFFF00; + Data |= ColorIndex >> 16; + RemItems--; + if (!RemItems) { + WRITE_MEM32(pContext->VRAMAddr, Off, Data); + break; + } + // + // no break at this position required... + // + case 3: + Data &= 0x000000FF; + Data |= ColorIndex << 8; + RemItems--; + WRITE_MEM32(pContext->VRAMAddr, Off, Data); + Off++; + } + } + Off0 = Off; + RemPixels -= (RemPixels - RemItems); + } + // + // Complete triple DWORDS + // + if (RemPixels >= 4) { + for (RemLines = NumLines; RemLines; RemLines--) { + RemItems = RemPixels; + Off = Off0 + OffLine * (RemLines - 1); + Data0 = (ColorIndex ) | (ColorIndex << 24); + Data1 = (ColorIndex >> 8) | (ColorIndex << 16); + Data2 = (ColorIndex >> 16) | (ColorIndex << 8); + do { + WRITE_MEM32(pContext->VRAMAddr, Off + 0, Data0); + WRITE_MEM32(pContext->VRAMAddr, Off + 1, Data1); + WRITE_MEM32(pContext->VRAMAddr, Off + 2, Data2); + Off += 3; + } while ((RemItems -= 4) >= 4); + } + Off0 = Off; + RemPixels -= (RemPixels >> 2) << 2; + } + // + // Last triple DWORD + // + if (RemPixels) { + for (RemLines = NumLines; RemLines; RemLines--) { + RemItems = RemPixels; + Off = Off0 + OffLine * (RemLines - 1); + Data = READ_MEM32(pContext->VRAMAddr, Off); + Data &= 0xFF000000; + Data |= ColorIndex; + RemItems--; + if (!RemItems) { + WRITE_MEM32(pContext->VRAMAddr, Off, Data); + continue; + } + Data &= 0x00FFFFFF; + Data |= ColorIndex << 24; + WRITE_MEM32(pContext->VRAMAddr, Off, Data); + Off++; + Data = READ_MEM32(pContext->VRAMAddr, Off); + Data &= 0xFFFF0000; + Data |= ColorIndex >> 8; + RemItems--; + if (!RemItems) { + WRITE_MEM32(pContext->VRAMAddr, Off, Data); + continue; + } + Data &= 0x0000FFFF; + Data |= ColorIndex << 16; + WRITE_MEM32(pContext->VRAMAddr, Off, Data); + Off++; + Data = READ_MEM32(pContext->VRAMAddr, Off); + Data &= 0xFFFFFF00; + Data |= ColorIndex >> 16; + WRITE_MEM32(pContext->VRAMAddr, Off, Data); + } + } + } +#else + if (GUI_pContext->DrawMode & LCD_DRAWMODE_XOR) { + // + // First triple DWORD + // + if (Odd) { + for (RemLines = NumLines; RemLines; RemLines--) { + RemItems = RemPixels; + Off = Off0 + OffLine * (RemLines - 1); + Data = READ_MEM32(pContext->VRAMAddr, Off); + switch (Odd) { + case 1: + Data ^= 0x000000FF; + WRITE_MEM32(pContext->VRAMAddr, Off, Data); + Off++; + Data = READ_MEM32(pContext->VRAMAddr, Off); + Data ^= 0xFFFF0000; + RemItems--; + if (!RemItems) { + WRITE_MEM32(pContext->VRAMAddr, Off, Data); + break; + } + // + // no break at this position required... + // + case 2: + Data ^= 0x0000FFFF; + WRITE_MEM32(pContext->VRAMAddr, Off, Data); + Off++; + Data = READ_MEM32(pContext->VRAMAddr, Off); + Data ^= 0xFF000000; + RemItems--; + if (!RemItems) { + WRITE_MEM32(pContext->VRAMAddr, Off, Data); + break; + } + // + // no break at this position required... + // + case 3: + Data ^= 0x00FFFFFF; + RemItems--; + WRITE_MEM32(pContext->VRAMAddr, Off, Data); + Off++; + } + } + Off0 = Off; + RemPixels -= (RemPixels - RemItems); + } + // + // Complete triple DWORDS + // + if (RemPixels >= 4) { + for (RemLines = NumLines; RemLines; RemLines--) { + RemItems = RemPixels; + Off = Off0 + OffLine * (RemLines - 1); + do { + Data = READ_MEM32(pContext->VRAMAddr, Off + 0); + Data ^= 0xFFFFFFFF; + WRITE_MEM32(pContext->VRAMAddr, Off + 0, Data); + Data = READ_MEM32(pContext->VRAMAddr, Off + 1); + Data ^= 0xFFFFFFFF; + WRITE_MEM32(pContext->VRAMAddr, Off + 1, Data); + Data = READ_MEM32(pContext->VRAMAddr, Off + 2); + Data ^= 0xFFFFFFFF; + WRITE_MEM32(pContext->VRAMAddr, Off + 2, Data); + Off += 3; + } while ((RemItems -= 4) >= 4); + } + Off0 = Off; + RemPixels -= (RemPixels >> 2) << 2; + } + // + // Last triple DWORD + // + if (RemPixels) { + for (RemLines = NumLines; RemLines; RemLines--) { + RemItems = RemPixels; + Off = Off0 + OffLine * (RemLines - 1); + + Data = READ_MEM32(pContext->VRAMAddr, Off); + Data ^= 0xFFFFFF00; + RemItems--; + if (!RemItems) { + WRITE_MEM32(pContext->VRAMAddr, Off, Data); + continue; + } + Data ^= 0x000000FF; + WRITE_MEM32(pContext->VRAMAddr, Off, Data); + Off++; + Data = READ_MEM32(pContext->VRAMAddr, Off); + Data ^= 0xFFFF0000; + RemItems--; + if (!RemItems) { + WRITE_MEM32(pContext->VRAMAddr, Off, Data); + continue; + } + Data ^= 0x0000FFFF; + WRITE_MEM32(pContext->VRAMAddr, Off, Data); + Off++; + Data = READ_MEM32(pContext->VRAMAddr, Off); + Data ^= 0xFF000000; + WRITE_MEM32(pContext->VRAMAddr, Off, Data); + } + } + } else { + ColorIndex = LCD__GetColorIndex(); + // + // First triple DWORD + // + if (Odd) { + for (RemLines = NumLines; RemLines; RemLines--) { + RemItems = RemPixels; + Off = Off0 + OffLine * (RemLines - 1); + Data = READ_MEM32(pContext->VRAMAddr, Off); + switch (Odd) { + case 1: + Data &= 0xFFFFFF00; + Data |= ColorIndex >> 16; + WRITE_MEM32(pContext->VRAMAddr, Off, Data); + Off++; + Data = READ_MEM32(pContext->VRAMAddr, Off); + Data &= 0x0000FFFF; + Data |= ColorIndex << 16; + RemItems--; + if (!RemItems) { + WRITE_MEM32(pContext->VRAMAddr, Off, Data); + break; + } + // + // no break at this position required... + // + case 2: + Data &= 0xFFFF0000; + Data |= ColorIndex >> 8; + WRITE_MEM32(pContext->VRAMAddr, Off, Data); + Off++; + Data = READ_MEM32(pContext->VRAMAddr, Off); + Data &= 0x00FFFFFF; + Data |= ColorIndex << 24; + RemItems--; + if (!RemItems) { + WRITE_MEM32(pContext->VRAMAddr, Off, Data); + break; + } + // + // no break at this position required... + // + case 3: + Data &= 0xFF000000; + Data |= ColorIndex; + RemItems--; + WRITE_MEM32(pContext->VRAMAddr, Off, Data); + Off++; + } + } + Off0 = Off; + RemPixels -= (RemPixels - RemItems); + } + // + // Complete triple DWORDS + // + if (RemPixels >= 4) { + for (RemLines = NumLines; RemLines; RemLines--) { + RemItems = RemPixels; + Off = Off0 + OffLine * (RemLines - 1); + Data0 = (ColorIndex << 8) | (ColorIndex >> 16); + Data1 = (ColorIndex << 16) | (ColorIndex >> 8); + Data2 = (ColorIndex << 24) | (ColorIndex ); + do { + WRITE_MEM32(pContext->VRAMAddr, Off + 0, Data0); + WRITE_MEM32(pContext->VRAMAddr, Off + 1, Data1); + WRITE_MEM32(pContext->VRAMAddr, Off + 2, Data2); + Off += 3; + } while ((RemItems -= 4) >= 4); + } + Off0 = Off; + RemPixels -= (RemPixels >> 2) << 2; + } + // + // Last triple DWORD + // + if (RemPixels) { + for (RemLines = NumLines; RemLines; RemLines--) { + RemItems = RemPixels; + Off = Off0 + OffLine * (RemLines - 1); + + Data = READ_MEM32(pContext->VRAMAddr, Off); + Data &= 0x000000FF; + Data |= (ColorIndex << 8); + RemItems--; + if (!RemItems) { + WRITE_MEM32(pContext->VRAMAddr, Off, Data); + continue; + } + Data &= 0xFFFFFF00; + Data |= ColorIndex >> 16; + WRITE_MEM32(pContext->VRAMAddr, Off, Data); + Off++; + Data = READ_MEM32(pContext->VRAMAddr, Off); + Data &= 0x0000FFFF; + Data |= ColorIndex << 16; + RemItems--; + if (!RemItems) { + WRITE_MEM32(pContext->VRAMAddr, Off, Data); + continue; + } + Data &= 0xFFFF0000; + Data |= ColorIndex >> 8; + WRITE_MEM32(pContext->VRAMAddr, Off, Data); + Off++; + Data = READ_MEM32(pContext->VRAMAddr, Off); + Data &= 0x00FFFFFF; + Data |= ColorIndex << 24; + WRITE_MEM32(pContext->VRAMAddr, Off, Data); + } + } + } +#endif +} + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/GUIDRV_Lin_Opt_32.h b/example/GUI/STemWin/inc/GUIDRV_Lin_Opt_32.h new file mode 100755 index 0000000000..d2310000f0 --- /dev/null +++ b/example/GUI/STemWin/inc/GUIDRV_Lin_Opt_32.h @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GUIDRV_Lin_Opt_32.h +Purpose : Optimized routines, included by GUIDRV_Lin_..._32.c +---------------------------END-OF-HEADER------------------------------ +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +/********************************************************************* +* +* Static functions +* +********************************************************************** +*/ +/********************************************************************* +* +* _FillRectOpt32 +* +* Purpose: +* Optimized filling routine for 32 bpp +*/ +static void _FillRectOpt32(GUI_DEVICE * pDevice, int x0, int y0, int x1, int y1) { + DRIVER_CONTEXT * pContext; + register LCD_PIXELINDEX ColorIndex; + U32 * pDest; + U32 * pDest0; + U32 Off, Off0, RemPixels, NumLines, RemLines, OffLine, RemItems; + LCD_PIXELINDEX IndexMask; + + pContext = (DRIVER_CONTEXT *)pDevice->u.pContext; + RemPixels = x1 - x0 + 1; + NumLines = y1 - y0 + 1; + OffLine = pContext->vxSizePhys; + pDest = NULL; + if (GUI_pContext->DrawMode & LCD_DRAWMODE_XOR) { + IndexMask = pDevice->pColorConvAPI->pfGetIndexMask(); + Off0 = XY2OFF32(pContext->vxSizePhys, x0, y0); + if (RemPixels) { + for (RemLines = NumLines; RemLines; RemLines--) { + RemItems = RemPixels; + Off = Off0 + OffLine * (RemLines - 1); + do { + ColorIndex = READ_MEM32(pContext->VRAMAddr, Off); + ColorIndex ^= IndexMask; + WRITE_MEM32(pContext->VRAMAddr, Off, ColorIndex); + Off++; + } while (--RemItems); + } + } + } else { + Off = XY2OFF32(pContext->vxSizePhys, x0, y0); + pDest0 = OFF2PTR32(pContext->VRAMAddr, Off); + ColorIndex = LCD__GetColorIndex(); + if (RemPixels >= 16) { + for (RemLines = NumLines; RemLines; RemLines--) { + RemItems = RemPixels; + pDest = pDest0 + OffLine * (RemLines - 1); + do { + WRITE_MEM32P(pDest , ColorIndex); + WRITE_MEM32P(pDest + 1, ColorIndex); + WRITE_MEM32P(pDest + 2, ColorIndex); + WRITE_MEM32P(pDest + 3, ColorIndex); + WRITE_MEM32P(pDest + 4, ColorIndex); + WRITE_MEM32P(pDest + 5, ColorIndex); + WRITE_MEM32P(pDest + 6, ColorIndex); + WRITE_MEM32P(pDest + 7, ColorIndex); + WRITE_MEM32P(pDest + 8, ColorIndex); + WRITE_MEM32P(pDest + 9, ColorIndex); + WRITE_MEM32P(pDest + 10, ColorIndex); + WRITE_MEM32P(pDest + 11, ColorIndex); + WRITE_MEM32P(pDest + 12, ColorIndex); + WRITE_MEM32P(pDest + 13, ColorIndex); + WRITE_MEM32P(pDest + 14, ColorIndex); + WRITE_MEM32P(pDest + 15, ColorIndex); + pDest += 16; + RemItems -= 16; + } while (RemItems >= 16); + } + pDest0 = pDest; + RemPixels -= (RemPixels >> 4) << 4; + } + if (RemPixels) { + for (RemLines = NumLines; RemLines; RemLines--) { + RemItems = RemPixels; + pDest = pDest0 + OffLine * (RemLines - 1); + do { + WRITE_MEM32P(pDest, ColorIndex); + pDest++; + } while (--RemItems); + } + } + } +} + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/GUIDRV_Lin_Opt_8.h b/example/GUI/STemWin/inc/GUIDRV_Lin_Opt_8.h new file mode 100755 index 0000000000..e73da660f1 --- /dev/null +++ b/example/GUI/STemWin/inc/GUIDRV_Lin_Opt_8.h @@ -0,0 +1,213 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GUIDRV_Lin_Opt_8.h +Purpose : Optimized routines, included by GUIDRV_Lin_..._8.c +---------------------------END-OF-HEADER------------------------------ +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +/********************************************************************* +* +* Static functions +* +********************************************************************** +*/ +/********************************************************************* +* +* _FillRectOpt8 +* +* Purpose: +* Optimized filling routine for 8 bpp +*/ +static void _FillRectOpt8(GUI_DEVICE * pDevice, int x0, int y0, int x1, int y1) { + DRIVER_CONTEXT * pContext; + U32 Data, ColorMask, AndMask, Off0, OffLine; + int NumPixel_0, NumPixel_1, RemPixels, NumLines, RemLines, RemItems; + LCD_PIXELINDEX ColorIndex; + U32 * pDest; + + pContext = (DRIVER_CONTEXT *)pDevice->u.pContext; + ColorIndex = LCD__GetColorIndex(); + Off0 = XY2OFF32(pContext->vxSizePhys, x0, y0); + RemPixels = x1 - x0 + 1; + NumLines = y1 - y0 + 1; + OffLine = pContext->vxSizePhys >> 2; + NumPixel_0 = x0 & 3; + NumPixel_1 = x1 & 3; + if (GUI_pContext->DrawMode & LCD_DRAWMODE_XOR) { + // + // First DWORD + // + if (NumPixel_0) { + for (RemLines = NumLines; RemLines; RemLines--) { + pDest = ((U32 *)pContext->VRAMAddr) + Off0 + OffLine * (RemLines - 1); + AndMask = ~(0xFFFFFFFF << (8 * NumPixel_0)); + if ((RemPixels < 3) && (NumPixel_1)) { + AndMask |= ~(0xFFFFFFFF >> (8 * (3 - NumPixel_1))); + } + #if (LCD_ENDIAN_BIG == 1) + MIRROR(AndMask); + #endif + Data = READ_MEM32P(pDest); + Data ^= ~AndMask; + WRITE_MEM32P(pDest, Data); + } + Off0++; + RemPixels -= (4 - NumPixel_0); + } + // + // Complete DWORDS + // + if (RemPixels >= 4) { + for (RemLines = NumLines; RemLines; RemLines--) { + RemItems = RemPixels; + pDest = ((U32 *)pContext->VRAMAddr) + Off0 + OffLine * (RemLines - 1); + while (RemItems >= 4) { + Data = READ_MEM32P(pDest); + Data ^= 0xFFFFFFFF; + WRITE_MEM32P(pDest, Data); + pDest++; + RemItems -= 4; + } + } + Off0 += (RemPixels >> 2); + RemPixels -= (RemPixels >> 2) << 2; + } + // + // Last DWORD + // + if (RemPixels > 0) { + for (RemLines = NumLines; RemLines; RemLines--) { + pDest = ((U32 *)pContext->VRAMAddr) + Off0 + OffLine * (RemLines - 1); + AndMask = 0xFFFFFF00 << (8 * NumPixel_1); + #if (LCD_ENDIAN_BIG == 1) + MIRROR(AndMask); + #endif + Data = READ_MEM32P(pDest); + Data ^= ~AndMask; + WRITE_MEM32P(pDest, Data); + } + } + } else { + // + // First DWORD + // + if (NumPixel_0) { + for (RemLines = NumLines; RemLines; RemLines--) { + pDest = ((U32 *)pContext->VRAMAddr) + Off0 + OffLine * (RemLines - 1); + AndMask = ~(0xFFFFFFFF << (8 * NumPixel_0)); + if ((RemPixels < 3) && (NumPixel_1)) { + AndMask |= ~(0xFFFFFFFF >> (8 * (3 - NumPixel_1))); + } + ColorMask = (ColorIndex * 0x01010101) & ~AndMask; + #if (LCD_ENDIAN_BIG == 1) + MIRROR(AndMask); + MIRROR(ColorMask); + #endif + Data = READ_MEM32P(pDest); + Data &= AndMask; + Data |= ColorMask; + WRITE_MEM32P(pDest, Data); + } + Off0++; + RemPixels -= (4 - NumPixel_0); + } + // + // Complete DWORDS + // + if (RemPixels >= 4) { + ColorMask = ColorIndex * 0x01010101; + for (RemLines = NumLines; RemLines; RemLines--) { + RemItems = RemPixels; + pDest = ((U32 *)pContext->VRAMAddr) + Off0 + OffLine * (RemLines - 1); + while (RemItems >= 32) { + WRITE_MEM32P(pDest , ColorMask); + WRITE_MEM32P(pDest + 1, ColorMask); + WRITE_MEM32P(pDest + 2, ColorMask); + WRITE_MEM32P(pDest + 3, ColorMask); + WRITE_MEM32P(pDest + 4, ColorMask); + WRITE_MEM32P(pDest + 5, ColorMask); + WRITE_MEM32P(pDest + 6, ColorMask); + WRITE_MEM32P(pDest + 7, ColorMask); + pDest += 8; + RemItems -= 32; + } + while (RemItems >= 4) { + WRITE_MEM32P(pDest, ColorMask); + pDest++; + RemItems -= 4; + } + } + Off0 += (RemPixels >> 2); + RemPixels -= (RemPixels >> 2) << 2; + } + // + // Last DWORD + // + if (RemPixels > 0) { + for (RemLines = NumLines; RemLines; RemLines--) { + pDest = ((U32 *)pContext->VRAMAddr) + Off0 + OffLine * (RemLines - 1); + AndMask = 0xFFFFFF00 << (8 * NumPixel_1); + ColorMask = (ColorIndex * 0x01010101) & ~AndMask; + #if (LCD_ENDIAN_BIG == 1) + MIRROR(AndMask); + MIRROR(ColorMask); + #endif + Data = READ_MEM32P(pDest); + Data &= AndMask; + Data |= ColorMask; + WRITE_MEM32P(pDest, Data); + } + } + } +} + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/GUIDRV_Lin_Private.h b/example/GUI/STemWin/inc/GUIDRV_Lin_Private.h new file mode 100755 index 0000000000..e28cdaa18e --- /dev/null +++ b/example/GUI/STemWin/inc/GUIDRV_Lin_Private.h @@ -0,0 +1,804 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GUIDRV_Lin_Private.h +Purpose : Common definitions and common code for all LIN-drivers +---------------------------END-OF-HEADER------------------------------ +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef GUIDRV_LIN_PRIVATE_H +#define GUIDRV_LIN_PRIVATE_H + +#include + +#if defined(__cplusplus) +extern "C" { /* Make sure we have C-declarations in C++ programs */ +#endif + +/********************************************************************* +* +* Common definitions for all variants of the LIN driver +* +********************************************************************** +*/ +#if defined(WIN32) + // + // Simulation prototypes + // + U16 SIM_Lin_ReadMem16 (unsigned int Off); + U32 SIM_Lin_ReadMem32 (unsigned int Off); + U8 SIM_Lin_ReadMem08p (U8 * p); + U32 SIM_Lin_ReadMem32p (U32 * p); + void SIM_Lin_WriteMem16 (unsigned int Off, U16 Data); + void SIM_Lin_WriteMem32 (unsigned int Off, U32 Data); + void SIM_Lin_WriteMem08p(U8 * p, U8 Data); + void SIM_Lin_WriteMem16p(U16 * p, U16 Data); + void SIM_Lin_WriteMem32p(U32 * p, U32 Data); + void SIM_Lin_memcpy (void * pDst, const void * pSrc, int Len); + void SIM_Lin_memset (void * pDst, U8 Value, U32 Len); + void SIM_Lin_SetVRAMAddr(int LayerIndex, void * pVRAM); + void SIM_Lin_SetVRAMSize(int LayerIndex, int vxSize, int vySize, int xSize, int ySize); + void SIM_Lin_CopyBuffer (int IndexSrc, int IndexDst); + void SIM_Lin_ShowBuffer (int Index); + // + // Access macro definition for internal simulation + // + #define LCD_READ_MEM16(VRAMAddr, Off) SIM_Lin_ReadMem16(Off) + #define LCD_READ_MEM32(VRAMAddr, Off) SIM_Lin_ReadMem32(Off) + #define LCD_READ_MEM08P(p) SIM_Lin_ReadMem08p(p) + #define LCD_READ_MEM32P(p) SIM_Lin_ReadMem32p(p) + #define LCD_WRITE_MEM16(VRAMAddr, Off, Data) SIM_Lin_WriteMem16(Off, Data) + #define LCD_WRITE_MEM32(VRAMAddr, Off, Data) SIM_Lin_WriteMem32(Off, Data) + #define LCD_WRITE_MEM08P(p, Data) SIM_Lin_WriteMem08p(p, Data) + #define LCD_WRITE_MEM16P(p, Data) SIM_Lin_WriteMem16p(p, Data) + #define LCD_WRITE_MEM32P(p, Data) SIM_Lin_WriteMem32p(p, Data) + #undef GUI__MEMCPY + #define GUI__MEMCPY(pDst, pSrc, Len) SIM_Lin_memcpy(pDst, pSrc, Len) + #undef GUI__MEMSET + #define GUI__MEMSET(pDst, Value, Len) SIM_Lin_memset(pDst, Value, Len) +#else + // + // Access macro definition for hardware + // + #define LCD_READ_MEM16(VRAMAddr, Off) (*((U16 *)VRAMAddr + (U32)Off)) + #define LCD_READ_MEM32(VRAMAddr, Off) (*((U32 *)VRAMAddr + (U32)Off)) + #define LCD_READ_MEM08P(p) (*((U8 *)p)) + #define LCD_READ_MEM32P(p) (*((U32 *)p)) + #define LCD_WRITE_MEM16(VRAMAddr, Off, Data) *((U16 *)VRAMAddr + (U32)Off) = (U16)(Data) + #define LCD_WRITE_MEM32(VRAMAddr, Off, Data) *((U32 *)VRAMAddr + (U32)Off) = Data + #define LCD_WRITE_MEM08P(p, Data) *((U8 *)p) = (U8)(Data) + #define LCD_WRITE_MEM16P(p, Data) *((U16 *)p) = (U16)(Data) + #define LCD_WRITE_MEM32P(p, Data) *((U32 *)p) = Data +#endif + +#ifndef WRITE_MEM16 + #define WRITE_MEM16(VRAMAddr, Off, Data) LCD_WRITE_MEM16(VRAMAddr, Off, Data) +#endif +#ifndef WRITE_MEM32 + #define WRITE_MEM32(VRAMAddr, Off, Data) LCD_WRITE_MEM32(VRAMAddr, Off, Data) +#endif +#ifndef READ_MEM08P + #define READ_MEM08P(p) LCD_READ_MEM08P(p) +#endif +#ifndef READ_MEM16 + #define READ_MEM16(VRAMAddr, Off) LCD_READ_MEM16(VRAMAddr, Off) +#endif +#ifndef READ_MEM32 + #define READ_MEM32(VRAMAddr, Off) LCD_READ_MEM32(VRAMAddr, Off) +#endif +#ifndef READ_MEM32P + #define READ_MEM32P(p) LCD_READ_MEM32P(p) +#endif +#ifndef WRITE_MEM08P + #define WRITE_MEM08P(p, Data) LCD_WRITE_MEM08P(p, Data) +#endif +#ifndef WRITE_MEM16P + #define WRITE_MEM16P(p, Data) LCD_WRITE_MEM16P(p, Data) +#endif +#ifndef WRITE_MEM32P + #define WRITE_MEM32P(p, Data) LCD_WRITE_MEM32P(p, Data) +#endif + +#define OFF2PTR08(VRAMAddr, Off) (U8 *)((U8 *)VRAMAddr + (Off )) +#define OFF2PTR16(VRAMAddr, Off) (U16 *)((U8 *)VRAMAddr + (Off << 1)) +#define OFF2PTR32(VRAMAddr, Off) (U32 *)((U8 *)VRAMAddr + (Off << 2)) + +// +// Use unique context identified +// +#define DRIVER_CONTEXT DRIVER_CONTEXT_LIN + +// +// Definition of default members for DRIVER_CONTEXT structure +// +#define DEFAULT_CONTEXT_MEMBERS \ + U32 VRAMAddr; \ + U32 BaseAddr; \ + int BufferIndex; \ + int xSize, ySize; \ + int vxSize, vySize; \ + int vxSizePhys; \ + int xPos, yPos; \ + int Alpha; \ + int IsVisible; \ + void (* pfFillRect) (int /* LayerIndex */, \ + int /* x0 */, \ + int /* y0 */, \ + int /* x1 */, \ + int /* y1 */, \ + U32 /* PixelIndex */); \ + void (* pfCopyBuffer)(int /* LayerIndex */, \ + int /* IndexSrc */, \ + int /* IndexDst */); \ + void (* pfDrawBMP1) (int /* LayerIndex */, \ + int /* x */, \ + int /* y */, \ + U8 const * /* p */, \ + int /* Diff */, \ + int /* xSize */, \ + int /* ySize */, \ + int /* BytesPerLine */, \ + const LCD_PIXELINDEX * /* pTrans */); \ + void (* pfDrawBMP8) (int /* LayerIndex */, \ + int /* x */, \ + int /* y */, \ + U8 const * /* p */, \ + int /* xSize */, \ + int /* ySize */, \ + int /* BytesPerLine */, \ + const LCD_PIXELINDEX * /* pTrans */); \ + void (* pfCopyRect) (int /* LayerIndex */, \ + int /* x0 */, \ + int /* y0 */, \ + int /* x1 */, \ + int /* y1 */, \ + int /* xSize */, \ + int /* ySize */); \ + void (* pfSetPos) (int /* LayerIndex */, \ + int /* xPos */, \ + int /* yPos */); + +#ifndef PRIVATE_CONTEXT_MEMBERS + #define PRIVATE_CONTEXT_MEMBERS +#endif + +// +// Definition of default function management for _GetDevFunc() +// +#define DEFAULT_MANAGEMENT_GETDEVFUNC() \ + case LCD_DEVFUNC_SET_VRAM_ADDR: \ + return (void (*)(void))_SetVRAMAddr; \ + case LCD_DEVFUNC_SET_VSIZE: \ + return (void (*)(void))_SetVSize; \ + case LCD_DEVFUNC_SET_SIZE: \ + return (void (*)(void))_SetSize; \ + case LCD_DEVFUNC_SETPOS: \ + return (void (*)(void))_SetPos; \ + case LCD_DEVFUNC_GETPOS: \ + return (void (*)(void))_GetPos; \ + case LCD_DEVFUNC_SETALPHA: \ + return (void (*)(void))_SetAlpha; \ + case LCD_DEVFUNC_SETVIS: \ + return (void (*)(void))_SetVis; \ + case LCD_DEVFUNC_INIT: \ + return (void (*)(void))_Init; \ + case LCD_DEVFUNC_ON: \ + return (void (*)(void))_On; \ + case LCD_DEVFUNC_OFF: \ + return (void (*)(void))_Off; \ + case LCD_DEVFUNC_ALPHAMODE: \ + return (void (*)(void))_SetAlphaMode; \ + case LCD_DEVFUNC_CHROMAMODE: \ + return (void (*)(void))_SetChromaMode; \ + case LCD_DEVFUNC_CHROMA: \ + return (void (*)(void))_SetChroma; \ + case LCD_DEVFUNC_COPYBUFFER: \ + return (void (*)(void))_CopyBuffer; \ + case LCD_DEVFUNC_SHOWBUFFER: \ + return (void (*)(void))_ShowBuffer; \ + case LCD_DEVFUNC_SETFUNC: \ + return (void (*)(void))_SetDevFunc; \ + case LCD_DEVFUNC_FILLRECT: \ + return (void (*)(void))((DRIVER_CONTEXT *)(*ppDevice)->u.pContext)->pfFillRect; \ + case LCD_DEVFUNC_DRAWBMP_1BPP: \ + return (void (*)(void))((DRIVER_CONTEXT *)(*ppDevice)->u.pContext)->pfDrawBMP1; \ + case LCD_DEVFUNC_DRAWBMP_8BPP: \ + return (void (*)(void))((DRIVER_CONTEXT *)(*ppDevice)->u.pContext)->pfDrawBMP8; \ + case LCD_DEVFUNC_COPYRECT: \ + return (void (*)(void))((DRIVER_CONTEXT *)(*ppDevice)->u.pContext)->pfCopyRect; + +// +// Definition of private function management for _GetDevFunc() +// +#ifndef PRIVATE_MANAGEMENT_GETDEVFUNC + #define PRIVATE_MANAGEMENT_GETDEVFUNC() +#endif + +// +// Definition of default function management for _SetDevFunc() +// +#define DEFAULT_MANAGEMENT_SETDEVFUNC() \ + case LCD_DEVFUNC_FILLRECT: \ + pContext->pfFillRect = (void (*)(int LayerIndex, int x0, int y0, int x1, int y1, U32 PixelIndex))pFunc; \ + break; \ + case LCD_DEVFUNC_COPYBUFFER: \ + pContext->pfCopyBuffer = (void (*)(int LayerIndex, int IndexSrc, int IndexDst))pFunc; \ + break; \ + case LCD_DEVFUNC_DRAWBMP_1BPP: \ + pContext->pfDrawBMP1 = (void (*)(int LayerIndex, int x, int y, U8 const * p, int Diff, int xSize, int ySize, int BytesPerLine, const LCD_PIXELINDEX * pTrans))pFunc; \ + break; \ + case LCD_DEVFUNC_DRAWBMP_8BPP: \ + pContext->pfDrawBMP8 = (void (*)(int LayerIndex, int x, int y, U8 const * p, int xSize, int ySize, int BytesPerLine, const LCD_PIXELINDEX * pTrans))pFunc; \ + break; \ + case LCD_DEVFUNC_COPYRECT: \ + pContext->pfCopyRect = (void (*)(int LayerIndex, int x0, int y0, int x1, int y1, int xSize, int ySize))pFunc; \ + break; \ + case LCD_DEVFUNC_SETPOS: \ + pContext->pfSetPos = (void (*)(int LayerIndex, int xPos, int yPos))pFunc; \ + break; + +// +// Definition of private function management for _GetDevFunc() +// +#ifndef PRIVATE_MANAGEMENT_SETDEVFUNC + #define PRIVATE_MANAGEMENT_SETDEVFUNC() +#endif + +// +// Endian related definitions +// +#ifndef LCD_MIRROR + #define LCD_MIRROR 0 +#endif + +#if (LCD_MIRROR == 2) +#define MIRROR(x) x = ((x & 0x000000ffUL) << 8) \ + | ((x & 0x0000ff00UL) >> 8) \ + | ((x & 0x00ff0000UL) << 8) \ + | ((x & 0xff000000UL) >> 8) +#else +#define MIRROR(x) x = ((x & 0x000000ffUL) << 24) \ + | ((x & 0x0000ff00UL) << 8) \ + | ((x & 0x00ff0000UL) >> 8) \ + | ((x & 0xff000000UL) >> 24) +#endif + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ +// +// DRIVER_CONTEXT structure consisting of default and private members +// +typedef struct { + DEFAULT_CONTEXT_MEMBERS + PRIVATE_CONTEXT_MEMBERS +} DRIVER_CONTEXT; + +/********************************************************************* +* +* Static code (common for all) +* +********************************************************************** +*/ +/********************************************************************* +* +* _InitOnce +* +* Purpose: +* Allocates a fixed block for the context of the driver +* +* Return value: +* 0 on success, 1 on error +*/ +static int _InitOnce(GUI_DEVICE * pDevice) { + if (pDevice->u.pContext == NULL) { + pDevice->u.pContext = GUI_ALLOC_GetFixedBlock(sizeof(DRIVER_CONTEXT)); + GUI__memset((U8 *)pDevice->u.pContext, 0, sizeof(DRIVER_CONTEXT)); + } + return pDevice->u.pContext ? 0 : 1; +} + +/********************************************************************* +* +* _GetRect +* +* Purpose: +* Returns the display size. +*/ +static void _GetRect(GUI_DEVICE * pDevice, LCD_RECT * pRect) { + DRIVER_CONTEXT * pContext; + + pContext = (DRIVER_CONTEXT *)pDevice->u.pContext; + pRect->x0 = 0; + pRect->y0 = 0; + pRect->x1 = pContext->vxSize - 1; + pRect->y1 = pContext->vySize - 1; +} + +/********************************************************************* +* +* _SetVis +* +* Purpose: +* Sets the visibility of the given layer by sending a LCD_X_SETVIS command to LCD_X_DisplayDriver() +* (Requires special hardware support.) +*/ +static void _SetVis(GUI_DEVICE * pDevice, int OnOff) { + DRIVER_CONTEXT * pContext; + LCD_X_SETVIS_INFO Data = {0}; + + _InitOnce(pDevice); + if (pDevice->u.pContext) { + pContext = (DRIVER_CONTEXT *)pDevice->u.pContext; + pContext->IsVisible = OnOff; + Data.OnOff = OnOff; + LCD_X_DisplayDriver(pDevice->LayerIndex, LCD_X_SETVIS, (void *)&Data); + } +} + +/********************************************************************* +* +* _SetPos +* +* Purpose: +* Sets the position of the given layer by sending a LCD_X_SETPOS command to LCD_X_DisplayDriver() +* (Requires special hardware support.) +*/ +static void _SetPos(GUI_DEVICE * pDevice, int xPos, int yPos) { + DRIVER_CONTEXT * pContext; + int xSizeDisplay, ySizeDisplay, xSizeLayer, ySizeLayer, BitsPerPixel; + LCD_X_SETPOS_INFO PosInfo = {0}; + + _InitOnce(pDevice); + if (pDevice->u.pContext) { + pContext = (DRIVER_CONTEXT *)pDevice->u.pContext; + if (pContext->pfSetPos) { + // + // Use custom callback to setlayer position + // + pContext->pfSetPos(pDevice->LayerIndex, xPos, yPos); + } else { + // + // Calculate xPos/yPos and new layer size + // + pContext->xPos = xPos; + pContext->yPos = yPos; + + xSizeDisplay = LCD_GetXSizeDisplay(); + ySizeDisplay = LCD_GetYSizeDisplay(); + xSizeLayer = pContext->xSize; + ySizeLayer = pContext->ySize; + BitsPerPixel = pDevice->pDeviceAPI->pfGetDevProp(pDevice, LCD_DEVCAP_BITSPERPIXEL); + PosInfo.BytesPerPixel = (BitsPerPixel + 7) / 8; + if (xPos < 0) { + PosInfo.Off -= xPos * PosInfo.BytesPerPixel; + PosInfo.xPos = 0; + PosInfo.xLen = xSizeLayer + xPos; + } else { + PosInfo.xPos = xPos; + PosInfo.xLen = xSizeLayer; + if ((PosInfo.xPos + PosInfo.xLen) > xSizeDisplay) { + PosInfo.xLen = xSizeDisplay - xPos; + } + } + if (yPos < 0) { + PosInfo.Off -= yPos * PosInfo.BytesPerPixel * xSizeLayer; + PosInfo.yPos = 0; + PosInfo.yLen = ySizeLayer + yPos; + } else { + PosInfo.yPos = yPos; + PosInfo.yLen = ySizeLayer; + if ((PosInfo.yPos + PosInfo.yLen) > ySizeDisplay) { + PosInfo.yLen = ySizeDisplay - yPos; + } + } + if ((PosInfo.xLen <= 0) || (PosInfo.yLen <= 0) || (PosInfo.xPos >= xSizeDisplay) || (PosInfo.yPos >= ySizeDisplay)) { + if (pContext->IsVisible == 1) { + _SetVis(pDevice, 0); + } + return; + } + if (pContext->IsVisible == 0) { + _SetVis(pDevice, 1); + } + LCD_X_DisplayDriver(pDevice->LayerIndex, LCD_X_SETPOS, (void *)&PosInfo); + } + } +} + +/********************************************************************* +* +* _GetPos +* +* Purpose: +* Returns the position of the given layer. +*/ +static void _GetPos(GUI_DEVICE * pDevice, int * pxPos, int * pyPos) { + DRIVER_CONTEXT * pContext; + + _InitOnce(pDevice); + if (pDevice->u.pContext) { + pContext = (DRIVER_CONTEXT *)pDevice->u.pContext; + *pxPos = pContext->xPos; + *pyPos = pContext->yPos; + } +} + +/********************************************************************* +* +* _SetAlpha +* +* Purpose: +* Sets the alpha value of the given layer by sending a LCD_X_SETALPHA command to LCD_X_DisplayDriver() +* (Requires special hardware support.) +*/ +static void _SetAlpha(GUI_DEVICE * pDevice, int Alpha) { + DRIVER_CONTEXT * pContext; + LCD_X_SETALPHA_INFO Data = {0}; + + _InitOnce(pDevice); + if (pDevice->u.pContext) { + pContext = (DRIVER_CONTEXT *)pDevice->u.pContext; + pContext->Alpha = Alpha; + Data.Alpha = Alpha; + LCD_X_DisplayDriver(pDevice->LayerIndex, LCD_X_SETALPHA, (void *)&Data); + } +} + +/********************************************************************* +* +* _Init +* +* Purpose: +* Called during the initialization process of emWin. +*/ +static int _Init(GUI_DEVICE * pDevice) { + int r; + + r = _InitOnce(pDevice); + r |= LCD_X_DisplayDriver(pDevice->LayerIndex, LCD_X_INITCONTROLLER, NULL); + return r; +} + +/********************************************************************* +* +* _On +* +* Purpose: +* Sends a LCD_X_ON command to LCD_X_DisplayDriver(). +*/ +static void _On (GUI_DEVICE * pDevice) { + LCD_X_DisplayDriver(pDevice->LayerIndex, LCD_X_ON, NULL); +} + +/********************************************************************* +* +* _Off +* +* Purpose: +* Sends a LCD_X_OFF command to LCD_X_DisplayDriver(). +*/ +static void _Off (GUI_DEVICE * pDevice) { + LCD_X_DisplayDriver(pDevice->LayerIndex, LCD_X_OFF, NULL); +} + +/********************************************************************* +* +* _SetAlphaMode +* +* Purpose: +* Sets the alpha mode of the given layer by sending a LCD_X_SETALPHAMODE command to LCD_X_DisplayDriver() +* (Requires special hardware support.) +*/ +static void _SetAlphaMode(GUI_DEVICE * pDevice, int AlphaMode) { + LCD_X_SETALPHAMODE_INFO Data = {0}; + + Data.AlphaMode = AlphaMode; + LCD_X_DisplayDriver(pDevice->LayerIndex, LCD_X_SETALPHAMODE, (void *)&Data); +} + +/********************************************************************* +* +* _SetChromaMode +* +* Purpose: +* Sets the chroma mode of the given layer by sending a LCD_X_SETCHROMAMODE command to LCD_X_DisplayDriver() +* (Requires special hardware support.) +*/ +static void _SetChromaMode(GUI_DEVICE * pDevice, int ChromaMode) { + LCD_X_SETCHROMAMODE_INFO Data = {0}; + + Data.ChromaMode = ChromaMode; + LCD_X_DisplayDriver(pDevice->LayerIndex, LCD_X_SETCHROMAMODE, (void *)&Data); +} + +/********************************************************************* +* +* _SetChroma +* +* Purpose: +* Sets the chroma values of the given layer by sending a LCD_X_SETCHROMA command to LCD_X_DisplayDriver() +* (Requires special hardware support.) +*/ +static void _SetChroma(GUI_DEVICE * pDevice, LCD_COLOR ChromaMin, LCD_COLOR ChromaMax) { + LCD_X_SETCHROMA_INFO Data = {0}; + + Data.ChromaMin = ChromaMin; + Data.ChromaMax = ChromaMax; + LCD_X_DisplayDriver(pDevice->LayerIndex, LCD_X_SETCHROMA, (void *)&Data); +} + +/********************************************************************* +* +* _CopyBuffer +* +* Purpose: +* Copies the source buffer to the destination buffer and routes +* further drawing operations to the destination buffer. +* +* (Required for using multiple buffers) +*/ +static void _CopyBuffer(GUI_DEVICE * pDevice, int IndexSrc, int IndexDst) { + DRIVER_CONTEXT * pContext; + #if (!defined(WIN32)) + U32 AddrSrc, AddrDst; + I32 BufferSize; + int BitsPerPixel; + #endif + + _InitOnce(pDevice); + if (pDevice->u.pContext) { + pContext = (DRIVER_CONTEXT *)pDevice->u.pContext; + if (IndexSrc != IndexDst) { + #if defined(WIN32) + SIM_Lin_CopyBuffer(IndexSrc, IndexDst); + #else + BitsPerPixel = pDevice->pDeviceAPI->pfGetDevProp(pDevice, LCD_DEVCAP_BITSPERPIXEL); + BufferSize = (((U32)pContext->vxSize * pContext->ySize * BitsPerPixel) >> 3); + AddrSrc = pContext->BaseAddr + BufferSize * IndexSrc; + AddrDst = pContext->BaseAddr + BufferSize * IndexDst; + if (pContext->pfCopyBuffer) { + // + // Use custom callback function for copy operation + // + pContext->pfCopyBuffer(pDevice->LayerIndex, IndexSrc, IndexDst); + } else { + // + // Calculate pointers for copy operation + // + GUI__MEMCPY((void *)AddrDst, (void *)AddrSrc, BufferSize); + } + // + // Set destination buffer as target for further drawing operations + // + pContext->VRAMAddr = AddrDst; + #endif + } + } +} + +/********************************************************************* +* +* _ShowBuffer +* +* Purpose: +* Sends a LCD_X_SHOWBUFFER command to LCD_X_DisplayDriver() to make the given buffer visible. +* +* (Required for using multiple buffers) +*/ +static void _ShowBuffer(GUI_DEVICE * pDevice, int Index) { + LCD_X_SHOWBUFFER_INFO Data = {0}; + + _InitOnce(pDevice); + if (pDevice->u.pContext) { + #if defined(WIN32) + SIM_Lin_ShowBuffer(Index); + #else + Data.Index = Index; + LCD_X_DisplayDriver(pDevice->LayerIndex, LCD_X_SHOWBUFFER, (void *)&Data); + #endif + } +} + +/********************************************************************* +* +* _SetOrg +* +* Purpose: +* Calls the driver callback function with the display origin to be set +*/ +static void _SetOrg(GUI_DEVICE * pDevice, int x, int y) { + #if (!defined(WIN32)) + DRIVER_CONTEXT * pContext; + int Orientation; + #endif + LCD_X_SETORG_INFO Data = {0}; + + #if defined(WIN32) + LCDSIM_SetOrg(x, y, pDevice->LayerIndex); + #else + pContext = (DRIVER_CONTEXT *)pDevice->u.pContext; + Orientation = LCD_GetMirrorXEx(pDevice->LayerIndex) * GUI_MIRROR_X; + Orientation |= LCD_GetMirrorYEx(pDevice->LayerIndex) * GUI_MIRROR_Y; + Orientation |= LCD_GetSwapXYEx (pDevice->LayerIndex) * GUI_SWAP_XY; + switch (Orientation) { + case 0: + Data.xPos = x; + Data.yPos = y; + break; + case GUI_MIRROR_X: + Data.xPos = pContext->vxSize - pContext->xSize - x; + Data.yPos = y; + break; + case GUI_MIRROR_Y: + Data.xPos = x; + Data.yPos = pContext->vySize - pContext->ySize - y; + break; + case GUI_MIRROR_X | GUI_MIRROR_Y: + Data.xPos = pContext->vxSize - pContext->xSize - x; + Data.yPos = pContext->vySize - pContext->ySize - y; + break; + case GUI_SWAP_XY: + Data.xPos = y; + Data.yPos = x; + break; + case GUI_SWAP_XY | GUI_MIRROR_X: + Data.xPos = pContext->vySize - pContext->ySize - y; + Data.yPos = x; + break; + case GUI_SWAP_XY | GUI_MIRROR_Y: + Data.xPos = y; + Data.yPos = pContext->vxSize - pContext->xSize - x; + break; + case GUI_SWAP_XY | GUI_MIRROR_X | GUI_MIRROR_Y: + Data.xPos = pContext->vySize - pContext->ySize - y; + Data.yPos = pContext->vxSize - pContext->xSize - x; + break; + } + LCD_X_DisplayDriver(pDevice->LayerIndex, LCD_X_SETORG, (void *)&Data); + #endif +} + +/********************************************************************* +* +* _SetVRAMAddr +*/ +static void _SetVRAMAddr(GUI_DEVICE * pDevice, void * pVRAM) { + DRIVER_CONTEXT * pContext; + LCD_X_SETVRAMADDR_INFO Data = {0}; + + _InitOnce(pDevice); + if (pDevice->u.pContext) { + pContext = (DRIVER_CONTEXT *)pDevice->u.pContext; + pContext->VRAMAddr = pContext->BaseAddr = (U32)pVRAM; + Data.pVRAM = pVRAM; + LCD_X_DisplayDriver(pDevice->LayerIndex, LCD_X_SETVRAMADDR, (void *)&Data); + } + #if defined(WIN32) + SIM_Lin_SetVRAMAddr(pDevice->LayerIndex, pVRAM); + #endif +} + +/********************************************************************* +* +* _SetVSize +*/ +static void _SetVSize(GUI_DEVICE * pDevice, int xSize, int ySize) { + DRIVER_CONTEXT * pContext; + #if defined(WIN32) + int NumBuffers; + #endif + + _InitOnce(pDevice); + if (pDevice->u.pContext) { + #if defined(WIN32) + NumBuffers = GUI_MULTIBUF_GetNumBuffers(); + #endif + pContext = (DRIVER_CONTEXT *)pDevice->u.pContext; + if (LCD_GetSwapXYEx(pDevice->LayerIndex)) { + #if defined(WIN32) + pContext->vxSize = xSize * NumBuffers; + #else + pContext->vxSize = xSize; + #endif + pContext->vySize = ySize; + pContext->vxSizePhys = ySize; + } else { + pContext->vxSize = xSize; + #if defined(WIN32) + pContext->vySize = ySize * NumBuffers; + #else + pContext->vySize = ySize; + #endif + pContext->vxSizePhys = xSize; + } + } + #if defined(WIN32) + SIM_Lin_SetVRAMSize(pDevice->LayerIndex, pContext->vxSize, pContext->vySize, pContext->xSize, pContext->ySize); + #endif +} + +/********************************************************************* +* +* _SetSize +*/ +static void _SetSize(GUI_DEVICE * pDevice, int xSize, int ySize) { + DRIVER_CONTEXT * pContext; + LCD_X_SETSIZE_INFO Data = {0}; + + _InitOnce(pDevice); + if (pDevice->u.pContext) { + pContext = (DRIVER_CONTEXT *)pDevice->u.pContext; + if (pContext->vxSizePhys == 0) { + if (LCD_GetSwapXYEx(pDevice->LayerIndex)) { + pContext->vxSizePhys = ySize; + } else { + pContext->vxSizePhys = xSize; + } + } + pContext->xSize = xSize; + pContext->ySize = ySize; + Data.xSize = xSize; + Data.ySize = ySize; + LCD_X_DisplayDriver(pDevice->LayerIndex, LCD_X_SETSIZE, (void *)&Data); + } +} + +#if defined(__cplusplus) +} +#endif + +#endif /* GUIDRV_LIN_PRIVATE_H */ + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/GUIDRV_NoOpt_1_8.h b/example/GUI/STemWin/inc/GUIDRV_NoOpt_1_8.h new file mode 100755 index 0000000000..8441a9779e --- /dev/null +++ b/example/GUI/STemWin/inc/GUIDRV_NoOpt_1_8.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GUIDRV_NoOpt_1_8.h +Purpose : Interface definition for non optimized drawing functions +---------------------------END-OF-HEADER------------------------------ +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +#include "GUI_Private.h" + +#ifndef GUIDRV_NOOPT_1_8_H +#define GUIDRV_NOOPT_1_8_H + +void GUIDRV__NoOpt_XorPixel (GUI_DEVICE * pDevice, int x, int y); +void GUIDRV__NoOpt_DrawHLine (GUI_DEVICE * pDevice, int x0, int y, int x1); +void GUIDRV__NoOpt_DrawVLine (GUI_DEVICE * pDevice, int x, int y0, int y1); +void GUIDRV__NoOpt_FillRect (GUI_DEVICE * pDevice, int x0, int y0, int x1, int y1); +void GUIDRV__NoOpt_DrawBitmap(GUI_DEVICE * pDevice, int x0, int y0, int xSize, int ySize, int BitsPerPixel, int BytesPerLine, const U8 * pData, int Diff, const LCD_PIXELINDEX * pTrans); + +#endif + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/GUIDRV_Template.h b/example/GUI/STemWin/inc/GUIDRV_Template.h new file mode 100755 index 0000000000..daa4f03930 --- /dev/null +++ b/example/GUI/STemWin/inc/GUIDRV_Template.h @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GUIDRV_Template.h +Purpose : Interface definition for GUIDRV_Template driver +---------------------------END-OF-HEADER------------------------------ +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef GUIDRV_TEMPLATE_H +#define GUIDRV_TEMPLATE_H + +/********************************************************************* +* +* Display drivers +*/ +// +// Addresses +// +extern const GUI_DEVICE_API GUIDRV_Win_API; + +extern const GUI_DEVICE_API GUIDRV_Template_API; + +// +// Macros to be used in configuration files +// +#if defined(WIN32) && !defined(LCD_SIMCONTROLLER) + + #define GUIDRV_TEMPLATE &GUIDRV_Win_API + +#else + + #define GUIDRV_TEMPLATE &GUIDRV_Template_API + +#endif + +#endif + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/GUIDRV_TemplateI.h b/example/GUI/STemWin/inc/GUIDRV_TemplateI.h new file mode 100755 index 0000000000..ca80ad0ab7 --- /dev/null +++ b/example/GUI/STemWin/inc/GUIDRV_TemplateI.h @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GUIDRV_TemplateI.h +Purpose : Interface definition for GUIDRV_TemplateI driver +---------------------------END-OF-HEADER------------------------------ +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef GUIDRV_TEMPLATE_I_H +#define GUIDRV_TEMPLATE_I_H + +#if defined(__cplusplus) +extern "C" { /* Make sure we have C-declarations in C++ programs */ +#endif + +/********************************************************************* +* +* Configuration structure +*/ +typedef struct { + // + // Driver specific configuration items + // + int Dummy; +} CONFIG_TEMPLATE_I; + +/********************************************************************* +* +* Display drivers +*/ +// +// Addresses +// +extern const GUI_DEVICE_API GUIDRV_TEMPLATE_I_16_API; +extern const GUI_DEVICE_API GUIDRV_TEMPLATE_I_OY_16_API; +extern const GUI_DEVICE_API GUIDRV_TEMPLATE_I_OX_16_API; +extern const GUI_DEVICE_API GUIDRV_TEMPLATE_I_OXY_16_API; +extern const GUI_DEVICE_API GUIDRV_TEMPLATE_I_OS_16_API; +extern const GUI_DEVICE_API GUIDRV_TEMPLATE_I_OSY_16_API; +extern const GUI_DEVICE_API GUIDRV_TEMPLATE_I_OSX_16_API; +extern const GUI_DEVICE_API GUIDRV_TEMPLATE_I_OSXY_16_API; + +// +// Macros to be used in configuration files +// +#if defined(WIN32) && !defined(LCD_SIMCONTROLLER) + + #define GUIDRV_TEMPLATE_I_16 &GUIDRV_Win_API + #define GUIDRV_TEMPLATE_I_OY_16 &GUIDRV_Win_API + #define GUIDRV_TEMPLATE_I_OX_16 &GUIDRV_Win_API + #define GUIDRV_TEMPLATE_I_OXY_16 &GUIDRV_Win_API + #define GUIDRV_TEMPLATE_I_OS_16 &GUIDRV_Win_API + #define GUIDRV_TEMPLATE_I_OSY_16 &GUIDRV_Win_API + #define GUIDRV_TEMPLATE_I_OSX_16 &GUIDRV_Win_API + #define GUIDRV_TEMPLATE_I_OSXY_16 &GUIDRV_Win_API + +#else + + #define GUIDRV_TEMPLATE_I_16 &GUIDRV_TEMPLATE_I_16_API + #define GUIDRV_TEMPLATE_I_OY_16 &GUIDRV_TEMPLATE_I_OY_16_API + #define GUIDRV_TEMPLATE_I_OX_16 &GUIDRV_TEMPLATE_I_OX_16_API + #define GUIDRV_TEMPLATE_I_OXY_16 &GUIDRV_TEMPLATE_I_OXY_16_API + #define GUIDRV_TEMPLATE_I_OS_16 &GUIDRV_TEMPLATE_I_OS_16_API + #define GUIDRV_TEMPLATE_I_OSY_16 &GUIDRV_TEMPLATE_I_OSY_16_API + #define GUIDRV_TEMPLATE_I_OSX_16 &GUIDRV_TEMPLATE_I_OSX_16_API + #define GUIDRV_TEMPLATE_I_OSXY_16 &GUIDRV_TEMPLATE_I_OSXY_16_API + +#endif + +/********************************************************************* +* +* Public routines +*/ +void GUIDRV_TemplateI_Config (GUI_DEVICE * pDevice, CONFIG_TEMPLATE_I * pConfig); +void GUIDRV_TemplateI_SetBus_XXX(GUI_DEVICE * pDevice, GUI_PORT_API * pHW_API); +void GUIDRV_TemplateI_SetFuncXXX(GUI_DEVICE * pDevice); + +#if defined(__cplusplus) +} +#endif + +#endif + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/GUIDRV_TemplateI_Private.h b/example/GUI/STemWin/inc/GUIDRV_TemplateI_Private.h new file mode 100755 index 0000000000..4fac468850 --- /dev/null +++ b/example/GUI/STemWin/inc/GUIDRV_TemplateI_Private.h @@ -0,0 +1,219 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GUIDRV_TemplateI_Private.h +Purpose : Interface definition for GUIDRV_TemplateI driver +---------------------------END-OF-HEADER------------------------------ +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +#include "GUIDRV_TemplateI.h" +#include "GUIDRV_NoOpt_1_8.h" + +#ifndef GUIDRV_TEMPLATE_I_PRIVATE_H +#define GUIDRV_TEMPLATE_I_PRIVATE_H + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ +#define PRIVATE_DEVFUNC_ONINITHOOK 0x1000 + +// +// Use unique context identified +// +#define DRIVER_CONTEXT DRIVER_CONTEXT_TEMPLATE_I + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ +typedef struct DRIVER_CONTEXT DRIVER_CONTEXT; + +typedef void (* T_ONINITHOOK)(DRIVER_CONTEXT * pContext); + +/********************************************************************* +* +* MANAGE_VMEM_API +*/ +typedef struct { + // + // TBD: Add private function pointers... + // + int Dummy; +} MANAGE_VMEM_API; + +/********************************************************************* +* +* DRIVER_CONTEXT +*/ +struct DRIVER_CONTEXT { + // + // Common data + // + int xSize, ySize; + int vxSize, vySize; + // + // Driver specific data + // + // + // Accelerators for calculation + // + int BytesPerLine; + int BitsPerPixel; + // + // VRAM + // + U8 * pVMEM; + // + // Pointer to driver internal initialization routine + // + void (* pfInit) (GUI_DEVICE * pDevice); + void (* pfCheck)(GUI_DEVICE * pDevice); + // + // API-Tables + // + MANAGE_VMEM_API ManageVMEM_API; // Memory management + GUI_PORT_API HW_API; // Hardware routines +}; + +/********************************************************************* +* +* LOG2PHYS_xxx +*/ +#define LOG2PHYS_X ( x ) +#define LOG2PHYS_X_OX (pContext->xSize - x - 1) +#define LOG2PHYS_X_OY ( x ) +#define LOG2PHYS_X_OXY (pContext->xSize - x - 1) +#define LOG2PHYS_X_OS ( y ) +#define LOG2PHYS_X_OSX (pContext->ySize - y - 1) +#define LOG2PHYS_X_OSY ( y ) +#define LOG2PHYS_X_OSXY (pContext->ySize - y - 1) + +#define LOG2PHYS_Y ( y ) +#define LOG2PHYS_Y_OX ( y ) +#define LOG2PHYS_Y_OY (pContext->ySize - y - 1) +#define LOG2PHYS_Y_OXY (pContext->ySize - y - 1) +#define LOG2PHYS_Y_OS ( x ) +#define LOG2PHYS_Y_OSX ( x ) +#define LOG2PHYS_Y_OSY (pContext->xSize - x - 1) +#define LOG2PHYS_Y_OSXY (pContext->xSize - x - 1) + +/********************************************************************* +* +* _SetPixelIndex_##EXT +*/ +#define DEFINE_SETPIXELINDEX(EXT, X_PHYS, Y_PHYS) \ +static void _SetPixelIndex_##EXT(GUI_DEVICE * pDevice, int x, int y, LCD_PIXELINDEX PixelIndex) { \ + DRIVER_CONTEXT * pContext; \ + \ + pContext = (DRIVER_CONTEXT *)pDevice->u.pContext; \ + pContext->xSize = pContext->xSize; /* Keep compiler happy */ \ + _SetPixelIndex(pDevice, X_PHYS, Y_PHYS, PixelIndex); \ +} + +/********************************************************************* +* +* _GetPixelIndex_##EXT +*/ +#define DEFINE_GETPIXELINDEX(EXT, X_PHYS, Y_PHYS) \ +static LCD_PIXELINDEX _GetPixelIndex_##EXT(GUI_DEVICE * pDevice, int x, int y) { \ + LCD_PIXELINDEX PixelIndex; \ + DRIVER_CONTEXT * pContext; \ + \ + pContext = (DRIVER_CONTEXT *)pDevice->u.pContext; \ + pContext->xSize = pContext->xSize; /* Keep compiler happy */ \ + PixelIndex = _GetPixelIndex(pDevice, X_PHYS, Y_PHYS); \ + return PixelIndex; \ +} + +/********************************************************************* +* +* _GetDevProp_##EXT +*/ +#define DEFINE_GETDEVPROP(EXT, MX, MY, SWAP) \ +static I32 _GetDevProp_##EXT(GUI_DEVICE * pDevice, int Index) { \ + switch (Index) { \ + case LCD_DEVCAP_MIRROR_X: return MX; \ + case LCD_DEVCAP_MIRROR_Y: return MY; \ + case LCD_DEVCAP_SWAP_XY: return SWAP; \ + } \ + return _GetDevProp(pDevice, Index); \ +} + +/********************************************************************* +* +* DEFINE_FUNCTIONS +*/ +#define DEFINE_FUNCTIONS(EXT, X_PHYS, Y_PHYS, MX, MY, SWAP) \ + DEFINE_SETPIXELINDEX(EXT, X_PHYS, Y_PHYS) \ + DEFINE_GETPIXELINDEX(EXT, X_PHYS, Y_PHYS) \ + DEFINE_GETDEVPROP(EXT, MX, MY, SWAP) \ + DEFINE_GUI_DEVICE_API(EXT) + + +/********************************************************************* +* +* Private functions +* +********************************************************************** +*/ +void (*GUIDRV__TemplateI_GetDevFunc(GUI_DEVICE ** ppDevice, int Index))(void); +void GUIDRV__TemplateI_SetOrg (GUI_DEVICE * pDevice, int x, int y); +I32 GUIDRV__TemplateI_GetDevProp(GUI_DEVICE * pDevice, int Index); +void GUIDRV__TemplateI_GetRect (GUI_DEVICE * pDevice, LCD_RECT * pRect); + +#endif + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/GUIMTDRV_TangoC32.h b/example/GUI/STemWin/inc/GUIMTDRV_TangoC32.h new file mode 100755 index 0000000000..d192155582 --- /dev/null +++ b/example/GUI/STemWin/inc/GUIMTDRV_TangoC32.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GUIMTDRV_TangoC32.h +Purpose : Interface definition for GUIMTDRV_TangoC32 driver +---------------------------END-OF-HEADER------------------------------ +*/ + +#ifndef GUIMTDRV_TANGOC32_H +#define GUIMTDRV_TANGOC32_H + +#include "GUI_Type.h" + +#if defined(__cplusplus) +//extern "C" { /* Make sure we have C-declarations in C++ programs */ +#endif + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ +typedef struct { + int LayerIndex; + // + // Initialization + // + void (* pf_I2C_Init)(unsigned char SlaveAddr); + // + // Read- and write access + // + int (* pf_I2C_Read )(unsigned char * pData, int Start, int Stop); + int (* pf_I2C_ReadM )(unsigned char * pData, int NumItems, int Start, int Stop); + int (* pf_I2C_Write )(unsigned char Data, int Start, int Stop); + int (* pf_I2C_WriteM)(unsigned char * pData, int NumItems, int Start, int Stop); + // + // 7-bit address to be used to address the I2C slave + // + U8 SlaveAddr; +} GUIMTDRV_TANGOC32_CONFIG; + +/********************************************************************* +* +* Interface +* +********************************************************************** +*/ +int GUIMTDRV_TangoC32_Init(GUIMTDRV_TANGOC32_CONFIG * pConfig); +int GUIMTDRV_TangoC32_Exec(void); + +#endif /* GUIMTDRV_TANGOC32_H */ + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/GUITDRV_ADS7846.h b/example/GUI/STemWin/inc/GUITDRV_ADS7846.h new file mode 100755 index 0000000000..9b2710cca3 --- /dev/null +++ b/example/GUI/STemWin/inc/GUITDRV_ADS7846.h @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GUITDRV_ADS7846.h +Purpose : Touch screen driver include +---------------------------------------------------------------------- + +Notes +===== +(1) The driver needs some function pointer to be filled correctly to be able + to communicate with the external peripheral correctly. The correct assignment + of these function pointers is checked during driver configuration. + +(2) The driver needs some configuration variables filled in to be able to calculate + the logical screen coordinates from the physical AD values. + A description of the typical paramaters that have to be known by the driver is + listed below: + - Orientation: Orientation of the touch screen if not the same as the physical orientation. + A or-combination of the defines GUI_SWAP_XY, GUI_MIRROR_X and GUI_MIRROR_Y + can be used. + - xLog0 : Logical pixel value of horizontal reference point 0. Typically 0. + - xLog1 : Logical pixel value of horizontal reference point 1. Typically horizontal screen resolution -1. + - xPhys0 : Physical AD value of horizontal reference point 0. + - xPhys1 : Physical AD value of horizontal reference point 1. + - yLog0 : Logical pixel value of vertical reference point 0. Typically 0. + - yLog1 : Logical pixel value of vertical reference point 1. Typically vertical screen resolution -1. + - yPhys0 : Physical AD value of vertical reference point 0. + - yPhys1 : Physical AD value of vertical reference point 1. + +(3) If the PENIRQ line of the touch controller is connected to a port of the target hardware + a touch event can be detected by the driver. Upon polling the driver's exec routine the + driver can check if a touch event is ready to be sampled by checking the PENIRQ line. + Without PENIRQ line the driver will always try to sample a touch event even if no touch + happened which will consume time even if not necessary. + Without PENIRQ it is the responsibility of the user's pfGetResult() routine to return + 0xFFFF if the measured AD value is out of bounds. + If both, the PENIRQ and the touch pressure recognition are enabled first the PENIRQ will + signal that there is a touch event. Afterwards the touch pressure measurement is used to + confirm that this was a valid touch and the touch had enough pressure to deliver good + measurements. + +(4) The touch pressure measurement is activated by setting a value for PressureMin and + PressureMax . + To calculate the correct touch pressure the resistance of the X-plate has to be known. + This can be set via PlateResistanceX [Ohm]. + A touch event that we have measured with a pressure within these thresholds is confirmed + as valid touch event with good measurment samples. + If both, the PENIRQ and the touch pressure recognition are enabled first the PENIRQ will + signal that there is a touch event. Afterwards the touch pressure measurement is used to + confirm that this was a valid touch and the touch had enough pressure to deliver good + measurements. + If no PENIRQ line is connected this measurement takes place everytime the touch event is + polled regardless if there is a touch event or not as the driver will only know for sure + after calculating the touch pressure. + Setting the value for PlateResistanceX to 0 is invalid. The driver will internally use a + value of 1 instead. +*/ + +#ifndef GUITDRV_ADS7846_H /* Make sure we only include it once */ +#define GUITDRV_ADS7846_H + +#include "GUI_Type.h" + +#if defined(__cplusplus) +extern "C" { /* Make sure we have C-declarations in C++ programs */ +#endif + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ + +typedef struct { + // + // Function pointer (1) + // + void (* pfSendCmd) (U8 Data); // Sends a 8-bit command to the peripheral + U16 (* pfGetResult) (void); // Retrieves the result of the AD conversion. 4 dummy bytes have to be shifted out to the left. + char (* pfGetBusy) (void); // Retrieves the status of the busy line. 0: Not busy; 1: Busy + void (* pfSetCS) (char OnOff); // Set chip select line. OnOff == 1 means peripheral selected + // + // Configuration (2) + // + unsigned Orientation; + int xLog0; + int xLog1; + int xPhys0; + int xPhys1; + int yLog0; + int yLog1; + int yPhys0; + int yPhys1; + // + // Optional, touch recognition via PENIRQ line (3) + // + char (* pfGetPENIRQ) (void); // Retrieves the status of the PENIRQ line to detect a touch event. + // + // Optional, touch recognition via touch pressure measurement (4) + // + int PressureMin; // Minimum pressure threshold. A measured pressure below this value means we do not have a valid touch event. + int PressureMax; // Maximum pressure threshold. A measured pressure above this value means we do not have a valid touch event. + int PlateResistanceX; // Resistance of the X-plate of the touch screen. This value is needed for calculation of the touch pressure. +} GUITDRV_ADS7846_CONFIG; + +typedef struct { + int xPhys; // Last measured x value + int yPhys; // Last measured y value + int z1Phys; // Last measured z1 value + int z2Phys; // Last measured z2 value + int PENIRQ; // Last sampled PENIRQ state if PENIRQ callback has been set + int Pressure; // Last measured touch pressure if touch pressure measurement is enabled +} GUITDRV_ADS7846_LAST_VAL; + +/********************************************************************* +* +* Prototypes +* +********************************************************************** +*/ + +void GUITDRV_ADS7846_Config (GUITDRV_ADS7846_CONFIG * pConfig); +char GUITDRV_ADS7846_Exec (void); +void GUITDRV_ADS7846_GetLastVal(GUITDRV_ADS7846_LAST_VAL * p); + +#if defined(__cplusplus) +} /* Make sure we have C-declarations in C++ programs */ +#endif + + +#endif /* GUITDRV_ADS7846_H */ + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/GUI_ARRAY.h b/example/GUI/STemWin/inc/GUI_ARRAY.h new file mode 100755 index 0000000000..70f7823a09 --- /dev/null +++ b/example/GUI/STemWin/inc/GUI_ARRAY.h @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GUI_ARRAY.h +Purpose : Array handling routines +---------------------------END-OF-HEADER------------------------------ +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef GUI_ARRAY_H +#define GUI_ARRAY_H + +#include "WM_Intern.h" + +#if GUI_WINSUPPORT + +/********************************************************************* +* +* Public types +* +********************************************************************** +*/ +typedef WM_HMEM GUI_ARRAY; + +/********************************************************************* +* +* Public functions +* +********************************************************************** +*/ +GUI_ARRAY GUI_ARRAY_Create (void); +int GUI_ARRAY_AddItem (GUI_ARRAY hArray, const void * pNew, int Len); +void GUI_ARRAY_Delete (GUI_ARRAY hArray); +WM_HMEM GUI_ARRAY_GethItem (GUI_ARRAY hArray, unsigned int Index); +unsigned GUI_ARRAY_GetNumItems (GUI_ARRAY hArray); +void * GUI_ARRAY_GetpItemLocked (GUI_ARRAY hArray, unsigned int Index); +int GUI_ARRAY_SethItem (GUI_ARRAY hArray, unsigned int Index, WM_HMEM hItem); +WM_HMEM GUI_ARRAY_SetItem (GUI_ARRAY hArray, unsigned int Index, const void * pData, int Len); +void GUI_ARRAY_DeleteItem (GUI_ARRAY hArray, unsigned int Index); +char GUI_ARRAY_InsertBlankItem (GUI_ARRAY hArray, unsigned int Index); +WM_HMEM GUI_ARRAY_InsertItem (GUI_ARRAY hArray, unsigned int Index, int Len); +void * GUI_ARRAY_ResizeItemLocked(GUI_ARRAY hArray, unsigned int Index, int Len); + +#endif /* GUI_WINSUPPORT */ + +#endif /* GUI_ARRAY_H */ + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/GUI_ARRAY_Private.h b/example/GUI/STemWin/inc/GUI_ARRAY_Private.h new file mode 100755 index 0000000000..1b491ee833 --- /dev/null +++ b/example/GUI/STemWin/inc/GUI_ARRAY_Private.h @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GUI_ARRAY_Private.h +Purpose : Private array handling routines, should be used only + from within GUI_ARRAY... routines! +---------------------------END-OF-HEADER------------------------------ +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef GUI_ARRAY_PRIVATE_H +#define GUI_ARRAY_PRIVATE_H + +#include "GUI_ARRAY.h" + +#if GUI_WINSUPPORT + +/********************************************************************* +* +* Private types +* +********************************************************************** +*/ +typedef struct { + U16 NumItems; + WM_HMEM haHandle; /* Handle to buffer holding handles */ +} GUI_ARRAY_OBJ; + +/********************************************************************* +* +* Private functions +* +********************************************************************** +*/ +WM_HMEM GUI_ARRAY__GethItem (const GUI_ARRAY_OBJ * pThis, unsigned int Index); +void * GUI_ARRAY__GetpItem (const GUI_ARRAY_OBJ * pThis, unsigned int Index); +void * GUI_ARRAY__GetpItemLocked(const GUI_ARRAY_OBJ * pThis, unsigned int Index); +int GUI_ARRAY__SethItem ( GUI_ARRAY_OBJ * pThis, unsigned int Index, WM_HMEM hItem); + +#endif /* GUI_WINSUPPORT */ + +#endif /* GUI_ARRAY_PRIVATE_H */ + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/GUI_BMP_Private.h b/example/GUI/STemWin/inc/GUI_BMP_Private.h new file mode 100755 index 0000000000..1cbab20a20 --- /dev/null +++ b/example/GUI/STemWin/inc/GUI_BMP_Private.h @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GUI_BMP_Private.h +Purpose : Private header file for GUI_BMP... functions +---------------------------END-OF-HEADER------------------------------ +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef GUI_BMP_PRIVATE_H +#define GUI_BMP_PRIVATE_H + +#include "GUI_Private.h" + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ +#define BI_RGB 0 +#define BI_RLE8 1 +#define BI_RLE4 2 +#define BI_BITFIELDS 3 + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ +// +// Default parameter structure for reading data from memory +// +typedef struct { + const U8 * pFileData; +} GUI_BMP_PARAM; + +// +// Context structure for getting stdio input +// +typedef struct { + GUI_GET_DATA_FUNC * pfGetData; // Function pointer + U32 Off; // Data pointer + void * pParam; // Parameter pointer passed to function +} GUI_BMP_CONTEXT; + +// +// Parameter structure for passing several required variables to the +// functions _DrawLine_RGB() and _DrawLine_ARGB() (in GUI_BMP_EnableAlpha.c). +// +typedef struct { + const U8 * pSrc; // Pointer to data + I32 xSrc; // Used to read data + int ySrc; // Used to read data + I32 xSize; + U32 BytesPerPixel; + tLCDDEV_Color2Index * pfColor2Index; + tLCDDEV_Index2Color * pfIndex2Color; // Used to manage bitfield conversion + LCD_API_NEXT_PIXEL * pNextPixel_API; + int x0; // Used to draw data + int y0; // Used to draw data + int x1; // Used to draw data + int y1; // Used to draw data +} GUI_DRAWLINE_INFO; + +/********************************************************************* +* +* Interface +* +********************************************************************** +*/ +int GUI_BMP__GetData (void * p, const U8 ** ppData, unsigned NumBytesReq, U32 Off); +int GUI_BMP__Init (GUI_BMP_CONTEXT * pContext, I32 * pWidth, I32 * pHeight, U16 * pBitCount, int * pNumColors, int * pCompression); +int GUI_BMP__ReadData (GUI_BMP_CONTEXT * pContext, int NumBytes, const U8 ** ppData, unsigned StartOfFile); +int GUI_BMP__ReadPalette(GUI_BMP_CONTEXT * pContext, int NumColors); + +#endif /* GUI_BMP_PRIVATE_H */ + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/GUI_ConfDefaults.h b/example/GUI/STemWin/inc/GUI_ConfDefaults.h new file mode 100755 index 0000000000..f0b3d8e5bc --- /dev/null +++ b/example/GUI/STemWin/inc/GUI_ConfDefaults.h @@ -0,0 +1,212 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GUI_ConfDefaults.h +Purpose : Defaults for GUI config switches. +---------------------------END-OF-HEADER------------------------------ + +Attention : Do not modify this file ! If you do, you will not + be able do update to a later GUI version ! + +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef GUI_CONFDEFAULTS_H +#define GUI_CONFDEFAULTS_H + +#include "GUIConf.h" + +#ifndef GUI_USE_MIXCOLORS + #define GUI_USE_MIXCOLORS 1 +#endif + +#ifndef GUI_USE_BIDI2 + #define GUI_USE_BIDI2 1 +#endif + +#ifndef LCD_MAX_LOG_COLORS + #define LCD_MAX_LOG_COLORS 256 +#else + #if (LCD_MAX_LOG_COLORS > 256) + #error The value of LCD_MAX_LOG_COLORS must be <= 256! + #endif +#endif + +#define LCD_PIXELINDEX U32 + +#ifndef LCD_YMAG + #define LCD_YMAG 1 +#endif +#ifndef LCD_XMAG + #define LCD_XMAG 1 +#endif + +/********************************************************************** +* +* Defaults for config switches +* +*********************************************************************** +*/ + +/* ATTENTION: This define swaps the meaning of a logical color from + ABGR to ARGB. + + It further swaps the meaning of a transparent pixel: + ABGR: 0x00 means opaque, 0xFF means transparent (default) + ARGB: 0x00 means transparent, 0xFF means opaque +*/ +#ifndef GUI_USE_ARGB + #define GUI_USE_ARGB 1 +#endif + +/* Define "universal pointer". Normally, this is not needed (define will expand to nothing) + However, on some systems (AVR - IAR compiler) it can be necessary ( -> __generic), + since a default pointer can access RAM only, not the built-in Flash +*/ +#ifndef GUI_UNI_PTR + #define GUI_UNI_PTR /* Remains only for compatibility purpose, no longer used in emWin */ +#endif + +/* Define const storage. Normally, this is not needed (define will expand to const) + However, on some systems (AVR - IAR compiler) it can be necessary ( -> __flash const), + since otherwise constants are copied into RAM +*/ +#ifndef GUI_CONST_STORAGE + #define GUI_CONST_STORAGE const +#endif + +#ifndef GUI_USE_MEMDEV_1BPP_FOR_SCREEN + #define GUI_USE_MEMDEV_1BPP_FOR_SCREEN 1 +#endif + +#ifndef GUI_BIDI_MAX_CHARS_PER_LINE + #if GUI_USE_BIDI2 + #define GUI_BIDI_MAX_CHARS_PER_LINE 200 + #else + #define GUI_BIDI_MAX_CHARS_PER_LINE 80 + #endif +#endif + +#ifndef GUI_SUPPORT_TOUCH + #define GUI_SUPPORT_TOUCH 0 +#endif + +#ifndef GUI_SUPPORT_MOUSE + #define GUI_SUPPORT_MOUSE 0 +#endif + +#ifndef GUI_SUPPORT_MEMDEV + #define GUI_SUPPORT_MEMDEV 0 +#endif + +#ifndef GUI_OS + #define GUI_OS 0 +#endif + +#ifndef GUI_NUM_LAYERS + #define GUI_NUM_LAYERS 1 +#endif + +#ifndef GUI_SUPPORT_CURSOR + #define GUI_SUPPORT_CURSOR (GUI_SUPPORT_MOUSE | GUI_SUPPORT_TOUCH) +#endif + +#ifndef GUI_CURSOR_LAYER + #define GUI_CURSOR_LAYER 0 +#endif + +#ifndef GUI_SUPPORT_ROTATION + #define GUI_SUPPORT_ROTATION 1 +#endif + +/* In order to avoid warnings for undefined parameters */ +#ifndef GUI_USE_PARA + #if defined (__BORLANDC__) || defined(NC30) || defined(NC308) + #define GUI_USE_PARA(para) + #else + #define GUI_USE_PARA(para) (void)para + #endif +#endif + +/* Default for types */ +#ifndef GUI_TIMER_TIME + #define GUI_TIMER_TIME int /* default is to use 16 bits for 16 bit CPUs, + 32 bits on 32 bit CPUs for timing */ +#endif + +/* Types used for memory allocation */ +#define GUI_ALLOC_DATATYPE I32 +#define GUI_ALLOC_DATATYPE_U U32 + +#ifndef GUI_MAX_XBF_BYTES + #define GUI_MAX_XBF_BYTES 200 +#endif + +#ifndef GUI_MEMSET + #define GUI_MEMSET memset +#endif + +#ifndef GUI_MEMCPY + #define GUI_MEMCPY memcpy +#endif + +/* Optional custom drawing of memory devices */ +#ifndef GUI_MEMDEV_SUPPORT_CUSTOMDRAW + #define GUI_MEMDEV_SUPPORT_CUSTOMDRAW 1 +#endif + +/* Clip static memory devices to parent borders */ +#ifndef GUI_MEMDEV_CLIP_AT_PARENT + #define GUI_MEMDEV_CLIP_AT_PARENT 0 +#endif + +#endif /* ifdef GUI_CONFDEFAULTS_H */ + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/GUI_Debug.h b/example/GUI/STemWin/inc/GUI_Debug.h new file mode 100755 index 0000000000..e46f376b00 --- /dev/null +++ b/example/GUI/STemWin/inc/GUI_Debug.h @@ -0,0 +1,213 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GUI_Debug.h +Purpose : Debug macros +---------------------------------------------------------------------- + Debug macros for logging + + In the GUI Simulation, all output is transferred into the log window. +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef GUI_DEBUG_H +#define GUI_DEBUG_H + +#include + +#include "GUI.h" + +#define GUI_DEBUG_LEVEL_NOCHECK 0 /* No run time checks are performed */ +#define GUI_DEBUG_LEVEL_CHECK_PARA 1 /* Parameter checks are performed to avoid crashes */ +#define GUI_DEBUG_LEVEL_CHECK_ALL 2 /* Parameter checks and consistency checks are performed */ +#define GUI_DEBUG_LEVEL_LOG_ERRORS 3 /* Errors are recorded */ +#define GUI_DEBUG_LEVEL_LOG_WARNINGS 4 /* Errors & Warnings are recorded */ +#define GUI_DEBUG_LEVEL_LOG_ALL 5 /* Errors, Warnings and Messages are recorded. */ + +#ifndef GUI_DEBUG_LEVEL + #ifdef WIN32 + #define GUI_DEBUG_LEVEL GUI_DEBUG_LEVEL_LOG_WARNINGS /* Simulation should log all warnings */ + #else + #define GUI_DEBUG_LEVEL GUI_DEBUG_LEVEL_NOCHECK /* For most targets, min. size is important */ + #endif +#endif + +#define GUI_LOCK_H(hMem) GUI_ALLOC_LockH(hMem) +#define GUI_UNLOCK_H(pMem) GUI_ALLOC_UnlockH((void **)&pMem) + +/******************************************************************* +* +* Commandline +* +******************************************************************** +*/ + +#ifdef WIN32 + #define GUI_DEBUG_GETCMDLINE() SIM_GetCmdLine() +#else + #define GUI_DEBUG_GETCMDLINE() 0 +#endif + +/******************************************************************* +* +* Error macros +* +******************************************************************** +*/ + +/* Make sure the macros are actually defined */ + +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_LOG_ERRORS + #define GUI_DEBUG_ERROROUT(s) GUI_ErrorOut(s) + #define GUI_DEBUG_ERROROUT1(s,p0) GUI_ErrorOut1(s,p0) + #define GUI_DEBUG_ERROROUT2(s,p0,p1) GUI_ErrorOut2(s,p0,p1) + #define GUI_DEBUG_ERROROUT3(s,p0,p1,p2) GUI_ErrorOut3(s,p0,p1,p2) + #define GUI_DEBUG_ERROROUT4(s,p0,p1,p2,p3) GUI_ErrorOut4(s,p0,p1,p2,p3) + #define GUI_DEBUG_ERROROUT_IF(exp,s) { if (exp) GUI_DEBUG_ERROROUT(s); } + #define GUI_DEBUG_ERROROUT1_IF(exp,s,p0) { if (exp) GUI_DEBUG_ERROROUT1(s,p0); } + #define GUI_DEBUG_ERROROUT2_IF(exp,s,p0,p1) { if (exp) GUI_DEBUG_ERROROUT2(s,p0,p1); } + #define GUI_DEBUG_ERROROUT3_IF(exp,s,p0,p1,p2) { if (exp) GUI_DEBUG_ERROROUT3(s,p0,p1,p2); } + #define GUI_DEBUG_ERROROUT4_IF(exp,s,p0,p1,p2,p3) { if (exp) GUI_DEBUG_ERROROUT4(s,p0,p1,p2,p3); } +#else + #define GUI_DEBUG_ERROROUT(s) + #define GUI_DEBUG_ERROROUT1(s,p0) + #define GUI_DEBUG_ERROROUT2(s,p0,p1) + #define GUI_DEBUG_ERROROUT3(s,p0,p1,p2) + #define GUI_DEBUG_ERROROUT4(s,p0,p1,p2,p3) + #define GUI_DEBUG_ERROROUT_IF(exp,s) + #define GUI_DEBUG_ERROROUT1_IF(exp,s,p0) + #define GUI_DEBUG_ERROROUT2_IF(exp,s,p0,p1) + #define GUI_DEBUG_ERROROUT3_IF(exp,s,p0,p1,p2) + #define GUI_DEBUG_ERROROUT4_IF(exp,s,p0,p1,p2,p3) +#endif + +/******************************************************************* +* +* Warning macros +* +******************************************************************** +*/ + +/* Make sure the macros are actually defined */ + +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_LOG_WARNINGS + #define GUI_DEBUG_WARN(s) GUI_Warn(s) + #define GUI_DEBUG_WARN1(s,p0) GUI_Warn1(s,p0) + #define GUI_DEBUG_WARN2(s,p0,p1) GUI_Warn2(s,p0,p1) + #define GUI_DEBUG_WARN3(s,p0,p1,p2) GUI_Warn3(s,p0,p1,p2) + #define GUI_DEBUG_WARN4(s,p0,p1,p2,p3) GUI_Warn4(s,p0,p1,p2,p3) + #define GUI_DEBUG_WARN_IF(exp,s) { if (exp) GUI_DEBUG_WARN(s); } + #define GUI_DEBUG_WARN1_IF(exp,s,p0) { if (exp) GUI_DEBUG_WARN1(s,p0); } + #define GUI_DEBUG_WARN2_IF(exp,s,p0,p1) { if (exp) GUI_DEBUG_WARN2(s,p0,p1); } + #define GUI_DEBUG_WARN3_IF(exp,s,p0,p1,p2) { if (exp) GUI_DEBUG_WARN3(s,p0,p1,p2); } + #define GUI_DEBUG_WARN4_IF(exp,s,p0,p1,p2,p3) { if (exp) GUI_DEBUG_WARN4(s,p0,p1,p2,p3); } +#else + #define GUI_DEBUG_WARN(s) + #define GUI_DEBUG_WARN1(s,p0) + #define GUI_DEBUG_WARN2(s,p0,p1) + #define GUI_DEBUG_WARN3(s,p0,p1,p2) + #define GUI_DEBUG_WARN4(s,p0,p1,p2,p3) + #define GUI_DEBUG_WARN_IF(exp,s) + #define GUI_DEBUG_WARN1_IF(exp,s,p0) + #define GUI_DEBUG_WARN2_IF(exp,s,p0,p1) + #define GUI_DEBUG_WARN3_IF(exp,s,p0,p1,p2) + #define GUI_DEBUG_WARN4_IF(exp,s,p0,p1,p2,p3) +#endif + +/******************************************************************* +* +* Logging macros +* +******************************************************************** +*/ +/* Make sure the macros are actually defined */ + +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_LOG_ALL + #define GUI_DEBUG_LOG(s) GUI_Log(s) + #define GUI_DEBUG_LOG1(s,p0) GUI_Log1(s,p0) + #define GUI_DEBUG_LOG2(s,p0,p1) GUI_Log2(s,p0,p1) + #define GUI_DEBUG_LOG3(s,p0,p1,p2) GUI_Log3(s,p0,p1,p2) + #define GUI_DEBUG_LOG4(s,p0,p1,p2,p3) GUI_Log4(s,p0,p1,p2,p3) + #define GUI_DEBUG_LOG_IF(exp,s) { if (exp) GUI_DEBUG_LOG(s); } + #define GUI_DEBUG_LOG1_IF(exp,s,p0) { if (exp) GUI_DEBUG_LOG1(s,p0); } + #define GUI_DEBUG_LOG2_IF(exp,s,p0,p1) { if (exp) GUI_DEBUG_LOG2(s,p0,p1); } + #define GUI_DEBUG_LOG3_IF(exp,s,p0,p1,p2) { if (exp) GUI_DEBUG_LOG3(s,p0,p1,p2); } + #define GUI_DEBUG_LOG4_IF(exp,s,p0,p1,p2,p3) { if (exp) GUI_DEBUG_LOG4(s,p0,p1,p2,p3); } +#else + #define GUI_DEBUG_LOG(s) + #define GUI_DEBUG_LOG1(s,p0) + #define GUI_DEBUG_LOG2(s,p0,p1) + #define GUI_DEBUG_LOG3(s,p0,p1,p2) + #define GUI_DEBUG_LOG4(s,p0,p1,p2,p3) + #define GUI_DEBUG_LOG_IF(exp,s) + #define GUI_DEBUG_LOG1_IF(exp,s,p0) + #define GUI_DEBUG_LOG2_IF(exp,s,p0,p1) + #define GUI_DEBUG_LOG3_IF(exp,s,p0,p1,p2) + #define GUI_DEBUG_LOG4_IF(exp,s,p0,p1,p2,p3) +#endif + +/******************************************************************* +* +* Asserts +* +******************************************************************** +*/ +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_LOG_ERRORS + #define GUI_DEBUG_ASSERT(exp) { if (!exp) GUI_DEBUG_ERROROUT(#exp); } +#else + #define GUI_DEBUG_ASSERT(exp) +#endif + +#endif /* LCD_H */ + + + + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/GUI_FontIntern.h b/example/GUI/STemWin/inc/GUI_FontIntern.h new file mode 100755 index 0000000000..541b330422 --- /dev/null +++ b/example/GUI/STemWin/inc/GUI_FontIntern.h @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GUI_FontIntern.h +Purpose : Internal decalrations used in font files +---------------------------END-OF-HEADER------------------------------ + +Attention : Do not modify this file ! If you do, you will not + be able do update to a later GUI version ! + +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef GUI_FONTINTERN_H /* Guard against multiple inclusion */ +#define GUI_FONTINTERN_H + +#include "GUI.h" + +#if defined(__cplusplus) +extern "C" { /* Make sure we have C-declarations in C++ programs */ +#endif + +extern GUI_CONST_STORAGE GUI_FONT_PROP GUI_Font8ASCII_Prop; +extern GUI_CONST_STORAGE GUI_FONT_PROP GUI_FontF8x13_ASCII_Prop1; +extern GUI_CONST_STORAGE GUI_FONT_PROP GUI_FontF8x15B_ASCII_Prop1; +extern GUI_CONST_STORAGE GUI_FONT_PROP GUI_Font10S_ASCII_FontProp1; +extern GUI_CONST_STORAGE GUI_FONT_PROP GUI_Font10ASCIIProp1; +extern GUI_CONST_STORAGE GUI_FONT_PROP GUI_Font13ASCII_Prop1; +extern GUI_CONST_STORAGE GUI_FONT_PROP GUI_Font13B_ASCII_Prop1; +extern GUI_CONST_STORAGE GUI_FONT_PROP GUI_Font13H_ASCII_Prop1; +extern GUI_CONST_STORAGE GUI_FONT_PROP GUI_Font13HB_ASCII_Prop1; +extern GUI_CONST_STORAGE GUI_FONT_PROP GUI_Font16_1_FontProp1; +extern GUI_CONST_STORAGE GUI_FONT_PROP GUI_Font16ASCIIProp1; +extern GUI_CONST_STORAGE GUI_FONT_PROP GUI_Font16B_ASCII_Prop1; +extern GUI_CONST_STORAGE GUI_FONT_PROP GUI_Font20_ASCII_Prop1; +extern GUI_CONST_STORAGE GUI_FONT_PROP GUI_Font20B_ASCII_Prop1; +extern GUI_CONST_STORAGE GUI_FONT_PROP GUI_Font24_ASCII_Prop1; +extern GUI_CONST_STORAGE GUI_FONT_PROP GUI_Font24B_ASCII_Prop1; +extern GUI_CONST_STORAGE GUI_FONT_PROP GUI_Font32_ASCII_Prop1; +extern GUI_CONST_STORAGE GUI_FONT_PROP GUI_Font32B_ASCII_Prop1; +extern GUI_CONST_STORAGE GUI_FONT_PROP GUI_FontComic18B_ASCII_Prop1; +extern GUI_CONST_STORAGE GUI_FONT_PROP GUI_FontComic24B_ASCII_Prop1; + +extern GUI_CONST_STORAGE GUI_FONT_PROP GUI_Font6x8ASCII_Prop0; +extern GUI_CONST_STORAGE GUI_FONT_PROP GUI_Font8x16ASCII_Prop0; +extern GUI_CONST_STORAGE GUI_FONT_PROP GUI_Font8x8ASCII_Prop0; + +extern GUI_CONST_STORAGE GUI_CHARINFO GUI_Font16_HK_CharInfo[169]; + +#if defined(__cplusplus) + } +#endif + + +#endif /* Guard against multiple inclusion */ + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/GUI_GCache_Private.h b/example/GUI/STemWin/inc/GUI_GCache_Private.h new file mode 100755 index 0000000000..2f2f78b074 --- /dev/null +++ b/example/GUI/STemWin/inc/GUI_GCache_Private.h @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +Licensing information +Licensor: SEGGER Software GmbH +Licensed to: STMicroelectronics International NV, 39, Chemin du Champ-des Filles, 1228 Plan Les Ouates, Geneva, SWITZERLAND +Licensed SEGGER software: emWin +License number: GUI-00429 +License model: Buyout SRC [Buyout Source Code License, signed November 29th 2012] +Licensed product: - +Licensed platform: STMs ARM Cortex-M based 32 BIT CPUs +Licensed number of seats: - +---------------------------------------------------------------------- +Support and Update Agreement (SUA) +SUA period: 2012-12-07 - 2017-12-31 +Contact to extend SUA: sales@segger.com +---------------------------------------------------------------------- +File : GUI_GCache_Private.h +Purpose : Private header +---------------------------END-OF-HEADER------------------------------ +*/ + +#ifndef GUI_GCACHE_PRIVATE_H +#define GUI_GCACHE_PRIVATE_H + +#include "GUI_Private.h" + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ +#define DRIVER_CONTEXT DRIVER_CONTEXT_GCACHE + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ +/********************************************************************* +* +* DRIVER_CONTEXT +*/ +typedef struct { + int x0, y0, x1, y1, IsDirty; + int xSize, ySize; + int CacheLocked; + int MemSize; + int BitsPerPixel; + int BytesPerLine; + // + // Line buffer for reading operation + // + LCD_PIXELINDEX * pLineBuffer; + // + // Palette for drawing 'cache bitmap' + // + LCD_PIXELINDEX * pPalette; + // + // Cache management + // + void (* pfReadRect) (GUI_DEVICE * pDevice, int x0, int y0, int x1, int y1, LCD_PIXELINDEX * pBuffer); + void (* pfSendCacheRect)(GUI_DEVICE * pDevice); + U32 * pVMEM; + // + // Drawing functions + // + void (* pfDrawBitmap )(GUI_DEVICE * pDevice, int x0, int y0, int xsize, int ysize, int BitsPerPixel, int BytesPerLine, const U8 * pData, int Diff, const LCD_PIXELINDEX * pTrans); + void (* pfDrawHLine )(GUI_DEVICE * pDevice, int x0, int y0, int x1); + void (* pfDrawVLine )(GUI_DEVICE * pDevice, int x , int y0, int y1); + void (* pfFillRect )(GUI_DEVICE * pDevice, int x0, int y0, int x1, int y1); + LCD_PIXELINDEX (* pfGetPixelIndex)(GUI_DEVICE * pDevice, int x, int y); + void (* pfSetPixelIndex)(GUI_DEVICE * pDevice, int x, int y, LCD_PIXELINDEX ColorIndex); + void (* pfXorPixel )(GUI_DEVICE * pDevice, int x, int y); + // + // GetData function + // + void *(* pfGetDevData )(GUI_DEVICE * pDevice, int Index); +} DRIVER_CONTEXT; + +/********************************************************************* +* +* Interface +* +********************************************************************** +*/ +GUI_DEVICE * GUI_GCACHE__CreateEx(int LayerIndex, const LCD_API_COLOR_CONV * pColorConvAPI, int BitsPerPixel); + +#endif + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/GUI_GIF_Private.h b/example/GUI/STemWin/inc/GUI_GIF_Private.h new file mode 100755 index 0000000000..e2c0056df6 --- /dev/null +++ b/example/GUI/STemWin/inc/GUI_GIF_Private.h @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GUI_GIF_Private.h +Purpose : Private header file for GUI_GIF... functions +---------------------------END-OF-HEADER------------------------------ +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef GUI_GIF_PRIVATE_H +#define GUI_GIF_PRIVATE_H + +#include "GUI_Private.h" + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ +#define MAX_NUM_LWZ_BITS 12 + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ +/* Context structure */ +typedef struct { + /* Required for getting input */ + unsigned NumBytesInBuffer; /* Remaining bytes in buffer */ + const U8 * pBuffer; /* Pointer into buffer for reading data */ + GUI_GET_DATA_FUNC * pfGetData; /* Function pointer */ + void * pParam; /* Parameter pointer passed to function */ + U32 Off; /* Data pointer */ + /* Decompression data */ + U8 aBuffer[258]; /* Input buffer for data block */ + short aCode [(1 << MAX_NUM_LWZ_BITS)]; /* This array stores the LZW codes for the compressed strings */ + U8 aPrefix[(1 << MAX_NUM_LWZ_BITS)]; /* Prefix character of the LZW code. */ + U8 aDecompBuffer[3000]; /* Decompression buffer. The higher the compression, the more bytes are needed in the buffer. */ + U8 * sp; /* Pointer into the decompression buffer */ + int CurBit; + int LastBit; + int GetDone; + int LastByte; + int ReturnClear; + int CodeSize; + int SetCodeSize; + int MaxCode; + int MaxCodeSize; + int ClearCode; + int EndCode; + int FirstCode; + int OldCode; + /* Palette buffer */ + GUI_COLOR aColorTable[256]; +} GUI_GIF_CONTEXT; + +typedef struct { + int XPos; + int YPos; + int XSize; + int YSize; + int Flags; + int NumColors; +} IMAGE_DESCRIPTOR; + +/* Default parameter structure for reading data from memory */ +typedef struct { + const U8 * pFileData; + U32 FileSize; +} GUI_GIF_PARAM; + +typedef int DRAW_FROM_DATABLOCK(GUI_GIF_CONTEXT * pContext, IMAGE_DESCRIPTOR * pDescriptor, int x0, int y0, int Transparency, int Disposal, int Num, int Denom); +typedef void CLEAR_UNUSED_PIXELS(int x0, int y0, IMAGE_DESCRIPTOR * pDescriptor, GUI_GIF_IMAGE_INFO * pInfo, int Num, int Denom); + +/********************************************************************* +* +* Private data +* +********************************************************************** +*/ +extern const int GUI_GIF__aInterlaceOffset[4]; +extern const int GUI_GIF__aInterlaceYPos[4]; + +/********************************************************************* +* +* Interface +* +********************************************************************** +*/ +int GUI_GIF__ReadData(GUI_GIF_CONTEXT * pContext, unsigned NumBytes, const U8 ** ppData, unsigned StartOfFile); +int GUI_GIF__GetData(void * p, const U8 ** ppData, unsigned NumBytesReq, U32 Off); +int GUI_GIF__DrawFromFilePointer(GUI_GIF_CONTEXT * pContext, int x0, int y0, int Index, int Num, int Denom, DRAW_FROM_DATABLOCK pfDrawFromDataBlock, CLEAR_UNUSED_PIXELS pfClearUnusedPixels); +void GUI_GIF__InitLZW(GUI_GIF_CONTEXT * pContext, int InputCodeSize); +int GUI_GIF__GetNextByte(GUI_GIF_CONTEXT * pContext); + +#endif /* GUI_GIF_PRIVATE_H */ diff --git a/example/GUI/STemWin/inc/GUI_HOOK.h b/example/GUI/STemWin/inc/GUI_HOOK.h new file mode 100755 index 0000000000..973f8c86f3 --- /dev/null +++ b/example/GUI/STemWin/inc/GUI_HOOK.h @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GUI_HOOK.h +Purpose : Hook handling routines +--------------------END-OF-HEADER------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef GUI_HOOK_H +#define GUI_HOOK_H + +#include "WM_Intern.h" + +#if GUI_WINSUPPORT + +#if defined(__cplusplus) +extern "C" { /* Make sure we have C-declarations in C++ programs */ +#endif + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ + +typedef int GUI_HOOK_FUNC(WM_MESSAGE* pMsg); + +typedef struct GUI_HOOK { + struct GUI_HOOK* pNext; + GUI_HOOK_FUNC* pHookFunc; +} GUI_HOOK; + +/********************************************************************* +* +* Functions +* +********************************************************************** +*/ + +void GUI_HOOK_Add (GUI_HOOK** ppFirstHook, GUI_HOOK* pNewHook, GUI_HOOK_FUNC* pHookFunc); +void GUI_HOOK_Remove(GUI_HOOK** ppFirstHook, GUI_HOOK* pHook); + +#if defined(__cplusplus) + } +#endif + +#endif /* GUI_WINSUPPORT */ +#endif /* GUI_HOOK_H */ + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/GUI_JPEG_Private.h b/example/GUI/STemWin/inc/GUI_JPEG_Private.h new file mode 100755 index 0000000000..4ac8e8576a --- /dev/null +++ b/example/GUI/STemWin/inc/GUI_JPEG_Private.h @@ -0,0 +1,302 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GUI_JPEG_Private.h +Purpose : Private header +---------------------------------------------------------------------- + +Explanation of terms: + + Component - Color channel, e.g., Red or Luminance. + Sample - Single component value (i.e., one number in the image data). + Coefficient - Frequency coefficient (a DCT transform output number). + Block - 8x8 group of samples or coefficients. + MCU - (Minimum Coded Unit) is an interleaved set of blocks of size + determined by the sampling factors, or a single block in a + noninterleaved scan. + +---------------------------END-OF-HEADER------------------------------ +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef GUI_JPEG_PRIVATE_H +#define GUI_JPEG_PRIVATE_H + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ +#define JPEG_LOCK_H(h) (GUI_JPEG_DCONTEXT *)GUI_LOCK_H(h) + +/********************************************************************* +* +* Scan types +*/ +#define GRAYSCALE 0 +#define YH1V1 1 +#define YH2V1 2 +#define YH1V2 3 +#define YH2V2 4 + +/********************************************************************* +* +* Maximum number of... +*/ +#define MAX_COMPONENTS 4 +#define MAX_HUFFTABLES 8 +#define MAX_QUANTTABLES 4 +#define MAX_COMPSINSCAN 4 +#define MAX_BLOCKSPERMCU 10 + +/********************************************************************* +* +* Marker definitions +*/ +#define M_SOF0 0xc0 /* Start Of Frame */ +#define M_SOF1 0xc1 +#define M_SOF2 0xc2 +#define M_SOF3 0xc3 + +#define M_SOF5 0xc5 +#define M_SOF6 0xc6 +#define M_SOF7 0xc7 + +#define M_JPG 0xc8 +#define M_SOF9 0xc9 +#define M_SOF10 0xca +#define M_SOF11 0xcb + +#define M_SOF13 0xcd +#define M_SOF14 0xce +#define M_SOF15 0xcf + +#define M_DHT 0xc4 /* Define Huffman Table */ + +#define M_DAC 0xcc /* Define Arithmetic Coding Table */ + +#define M_RST0 0xd0 +#define M_RST1 0xd1 +#define M_RST2 0xd2 +#define M_RST3 0xd3 +#define M_RST4 0xd4 +#define M_RST5 0xd5 +#define M_RST6 0xd6 +#define M_RST7 0xd7 + +#define M_SOI 0xd8 /* Start Of Image */ +#define M_EOI 0xd9 +#define M_SOS 0xda /* Start Of Scan */ +#define M_DQT 0xdb /* Define Quantisation Table */ +#define M_DRI 0xdd /* Define Restart Interval */ + +#define M_APP0 0xe0 /* Application Usage */ +#define M_APP14 0xee /* Adobe marker */ + +#define M_TEM 0x01 + +#define ADOBE_TRANSFORM_RGB 0 +#define ADOBE_TRANSFORM_YCBCR 1 + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ +/* Default parameter structure for reading data from memory */ +typedef struct { + const U8 * pFileData; + I32 FileSize; +} GUI_JPEG_PARAM; + +/* Huffman table definition */ +typedef struct { + unsigned aLookUp[256]; + U8 aCodeSize[256]; + unsigned aTree[512]; +} HUFF_TABLE; + +/* Coefficient buffer used for progressive JPEGs */ +typedef struct { + int NumBlocksX; + int NumBlocksY; + unsigned BlockSize; + GUI_HMEM hData; +} COEFF_BUFFER; + +typedef struct GUI_JPEG_DCONTEXT GUI_JPEG_DCONTEXT; + +struct GUI_JPEG_DCONTEXT { + /* Function pointer for reading one byte */ + int (* pfGetU8)(GUI_JPEG_DCONTEXT * pContext, U8 * pByte); + + GUI_GET_DATA_FUNC * pfGetData; /* 'GetData' Function pointer */ + void * pParam; /* Pointer passed to 'GetData' function */ + U32 Off; /* Data pointer */ + /* Image size */ + U16 xSize; + U16 ySize; + /* Input buffer */ + const U8 * pBuffer; + unsigned NumBytesInBuffer; + U8 StartOfFile; + U8 aStuff[4]; /* Stuff back buffer */ + U8 NumBytesStuffed; /* Number of stuffed bytes */ + /* Bit buffer */ + U32 BitBuffer; + int NumBitsLeft; + /* Huffman tables */ + U8 aHuffNumTableAvail[MAX_HUFFTABLES]; + U8 aaHuffNum[MAX_HUFFTABLES][17]; /* Pointer to number of Huffman codes per bit size */ + U8 aaHuffVal[MAX_HUFFTABLES][256]; /* Pointer to Huffman codes */ + HUFF_TABLE aHuffTable[MAX_HUFFTABLES]; + HUFF_TABLE * apDC_Huff[MAX_BLOCKSPERMCU]; + HUFF_TABLE * apAC_Huff[MAX_BLOCKSPERMCU]; + /* Quantization tables */ + U16 aaQuantTbl[MAX_QUANTTABLES][64]; + U16 * apQuantTbl[MAX_QUANTTABLES]; + // + // Component information + // + U8 NumCompsPerFrame; // Number of components per frame + U8 aCompHSamp[MAX_COMPONENTS]; // Component's horizontal sampling factor + U8 aCompVSamp[MAX_COMPONENTS]; // Component's vertical sampling factor + U8 aCompQuant[MAX_COMPONENTS]; // Component's quantization table selector + U8 aCompId [MAX_COMPONENTS]; // Component's ID + U8 NumCompsPerScan; // Number of components per scan + U8 aCompList[MAX_COMPSINSCAN]; // Components in this scan + U8 aCompDC_Tab[MAX_COMPONENTS]; // Component's DC Huffman coding table selector + U8 aCompAC_Tab[MAX_COMPONENTS]; // Component's AC Huffman coding table selector + unsigned * apComponent[MAX_BLOCKSPERMCU]; // Points into the table aLastDC_Val[] + unsigned aLastDC_Val[MAX_COMPONENTS]; // Table of last DC values + // + // Data used for progressive scans + // + U8 SpectralStart; // Spectral selection start + U8 SpectralEnd; // Spectral selection end + U8 SuccessiveLow; // Successive approximation low + U8 SuccessiveHigh; // Successive approximation high + COEFF_BUFFER aDC_Coeffs[MAX_COMPONENTS]; // DC coefficient buffer for progressive scan + COEFF_BUFFER aAC_Coeffs[MAX_COMPONENTS]; // AC coefficient buffer for progressive scan + int aBlockY_MCU[MAX_COMPONENTS]; // + // + // Common + // + U8 TransformationRequired; + U8 IsProgressive; /* Flag is set to 1 if JPEG is progressive */ + U8 ScanType; /* Gray, Yh1v1, Yh1v2, Yh2v1, Yh2v2 */ + int MaxMCUsPerRow; /* Maximum number of MCUs per row */ + int MaxMCUsPerCol; /* Maximum number of MCUs per column */ + int MaxBlocksPerMCU; /* Maximum number of blocks per MCU */ + int MaxBlocksPerRow; /* Maximum number of blocks per row */ + int MaxMCU_xSize; /* MCU's max. X size in pixels */ + int MaxMCU_ySize; /* MCU's max. Y size in pixels */ + int DestBytesPerPixel; /* 4 (RGB) or 1 (Y) */ + int DestBytesPerScanline; /* Rounded up */ + int RealDestBytesPerScanline; /* Actual bytes */ + int EOB_Run; /* 'End Of Band' run */ + int RestartInterval; + int RestartsLeft; + int NextRestartNum; + int MCUsPerRow; + int MCUsPerCol; + int NumBlocksPerMCU; + int aMCU_Org[MAX_BLOCKSPERMCU]; + /* Block buffer */ + GUI_HMEM hBlocks; + GUI_HMEM hBlockMaxZagSet; + /* Sample buffer */ + GUI_HMEM hSampleBuf; + U8 * pSampleBuf; + /* Status */ + int TotalLinesLeft; /* Total number of lines left in image */ + int MCULinesLeft; /* Total number of lines left in current MCU */ + /* Output buffer(s) */ + GUI_HMEM hScanLine0; /* Buffer 0 */ + GUI_HMEM hScanLine1; /* Buffer 1, only used for V2 sampling factors */ + U8 BufferIndex; + /* Arrays used for converting YCbCr to RGB */ + int aCRR[256]; + int aCBB[256]; + I32 aCRG[256]; + I32 aCBG[256]; + /* Banding */ + U8 BandingRequired; /* Flag if banding is required */ + unsigned NumBands; /* Number of required bands for drawing the complete frame */ + int NumBlocksPerBand; /* Number of vertical blocks per band */ + int FirstBlockOfBand; + int aFirstBlockOfBand[MAX_COMPONENTS]; + int bpp; +}; + +/********************************************************************* +* +* Private interface +* +********************************************************************** +*/ +int GUI_JPEG__AllocBandingCoeffBuffer (GUI_HMEM hContext); +int GUI_JPEG__DecodeLine (GUI_JPEG_DCONTEXT * pContext); +int GUI_JPEG__DecodeProgressiveBanding(GUI_JPEG_DCONTEXT * pContext); +void GUI_JPEG__Free (GUI_JPEG_DCONTEXT * pContext); +GUI_COLOR GUI_JPEG__GetColorGray (const U8 ** ppData, unsigned SkipCnt); +GUI_COLOR GUI_JPEG__GetColorRGB (const U8 ** ppData, unsigned SkipCnt); +int GUI_JPEG__GetData (void * p, const U8 ** ppData, unsigned NumBytesReq, U32 Off); +int GUI_JPEG__InitDraw (GUI_HMEM hContext); +int GUI_JPEG__ReadUntilSOF (GUI_HMEM hContext); +void GUI_JPEG__SetNextBand (GUI_JPEG_DCONTEXT * pContext); +int GUI_JPEG__SkipLine (GUI_JPEG_DCONTEXT * pContext); +int GUI_JPEG__GetInfoEx (GUI_HMEM hContext, GUI_JPEG_INFO * pInfo); + +#endif + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/GUI_Private.h b/example/GUI/STemWin/inc/GUI_Private.h new file mode 100755 index 0000000000..0e77e8b24d --- /dev/null +++ b/example/GUI/STemWin/inc/GUI_Private.h @@ -0,0 +1,746 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GUI_Private.h +Purpose : GUI internal declarations +---------------------------END-OF-HEADER------------------------------ +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef GUI_PRIVATE_H +#define GUI_PRIVATE_H + +#include "GUI.h" +#include "LCD_Protected.h" +#include "GUI_Debug.h" +#if GUI_WINSUPPORT + #include "WM_GUI.h" +#endif + +#if defined(__cplusplus) +extern "C" { /* Make sure we have C-declarations in C++ programs */ +#endif + +/********************************************************************* +* +* Defaults for config switches +* +********************************************************************** + + The config switches below do not affect the interface in GUI.h and + are therefor not required to be in GUI.h. +*/ + +/* Short address area. + For most compilers, this is "near" or "__near" + We do not use this except for some CPUs which we know to always have some + near memory, because the GUI_Context and some other data will be declared + to be in this short address (near) memory area as it has a major effect + on performance. + Please define in GUIConf.h (if you want to use it) +*/ +#ifndef GUI_SADDR + #define GUI_SADDR +#endif + +#ifndef GUI_DEFAULT_FONT + #define GUI_DEFAULT_FONT &GUI_Font6x8 +#endif + +#ifndef GUI_DEFAULT_CURSOR + #define GUI_DEFAULT_CURSOR &GUI_CursorArrowM +#endif + +#ifndef GUI_DEFAULT_BKCOLOR + #define GUI_DEFAULT_BKCOLOR GUI_BLACK +#endif + +#ifndef GUI_DEFAULT_COLOR + #define GUI_DEFAULT_COLOR GUI_WHITE +#endif + +/********************************************************************* +* +* Angles +* +********************************************************************** +*/ +#define GUI_45DEG 512 +#define GUI_90DEG (2 * GUI_45DEG) +#define GUI_180DEG (4 * GUI_45DEG) +#define GUI_360DEG (8 * GUI_45DEG) + +/********************************************************************* +* +* Locking checks +* +********************************************************************** +*/ +#if defined (WIN32) && defined (_DEBUG) && GUI_OS + #define GUI_ASSERT_LOCK() GUITASK_AssertLock() + #define GUI_ASSERT_NO_LOCK() GUITASK_AssertNoLock() + void GUITASK_AssertLock(void); + void GUITASK_AssertNoLock(void); +#else + #define GUI_ASSERT_LOCK() + #define GUI_ASSERT_NO_LOCK() +#endif + +/********************************************************************* +* +* Division tables +* +********************************************************************** +*/ +extern const U8 GUI__aConvert_15_255[(1 << 4)]; +extern const U8 GUI__aConvert_31_255[(1 << 5)]; +extern const U8 GUI__aConvert_63_255[(1 << 6)]; +extern const U8 GUI__aConvert_255_15[(1 << 8)]; +extern const U8 GUI__aConvert_255_31[(1 << 8)]; +extern const U8 GUI__aConvert_255_63[(1 << 8)]; + +/********************************************************************* +* +* Usage internals +* +********************************************************************** +*/ +typedef GUI_HMEM GUI_USAGE_Handle; +typedef struct tsUSAGE_APIList tUSAGE_APIList; +typedef struct GUI_Usage GUI_USAGE; +#define GUI_USAGE_h GUI_USAGE_Handle + +typedef GUI_USAGE_h tUSAGE_CreateCompatible(GUI_USAGE * p); +typedef void tUSAGE_AddPixel (GUI_USAGE * p, int x, int y); +typedef void tUSAGE_AddHLine (GUI_USAGE * p, int x0, int y0, int len); +typedef void tUSAGE_Clear (GUI_USAGE * p); +typedef void tUSAGE_Delete (GUI_USAGE_h h); +typedef int tUSAGE_GetNextDirty (GUI_USAGE * p, int * pxOff, int yOff); +#define GUI_USAGE_LOCK_H(h) ((GUI_USAGE *)GUI_LOCK_H(h)) + +void GUI_USAGE_DecUseCnt(GUI_USAGE_Handle hUsage); + +GUI_USAGE_Handle GUI_USAGE_BM_Create(int x0, int y0, int xsize, int ysize, int Flags); +void GUI_USAGE_Select(GUI_USAGE_Handle hUsage); +void GUI_USAGE_AddRect(GUI_USAGE * pUsage, int x0, int y0, int xSize, int ySize); +#define GUI_USAGE_AddPixel(p, x,y) p->pAPI->pfAddPixel(p,x,y) +#define GUI_USAGE_AddHLine(p,x,y,len) p->pAPI->pfAddHLine(p,x,y,len) +#define GUI_USAGE_Clear(p) p->pAPI->pfClear(p) +#define GUI_USAGE_Delete(p) p->pAPI->pfDelete(p) +#define GUI_USAGE_GetNextDirty(p,pxOff, yOff) p->pAPI->pfGetNextDirty(p,pxOff, yOff) + +struct tsUSAGE_APIList { + tUSAGE_AddPixel * pfAddPixel; + tUSAGE_AddHLine * pfAddHLine; + tUSAGE_Clear * pfClear; + tUSAGE_CreateCompatible * pfCreateCompatible; + tUSAGE_Delete * pfDelete; + tUSAGE_GetNextDirty * pfGetNextDirty; +} ; + +struct GUI_Usage { + I16P x0, y0, XSize, YSize; + const tUSAGE_APIList * pAPI; + I16 UseCnt; +}; + +/********************************************************************* +* +* GUI_MEMDEV +* +********************************************************************** +*/ +#if GUI_SUPPORT_MEMDEV + +typedef struct { + GUI_DEVICE * pDevice; + I16P x0, y0, XSize, YSize; + unsigned BytesPerLine; + unsigned BitsPerPixel; + GUI_HMEM hUsage; +} GUI_MEMDEV; + +#define GUI_MEMDEV_LOCK_H(h) ((GUI_MEMDEV *)GUI_LOCK_H(h)) + +void GUI_MEMDEV__CopyFromLCD (GUI_MEMDEV_Handle hMem); +void GUI_MEMDEV__GetRect (GUI_RECT * pRect); +unsigned GUI_MEMDEV__Color2Index (LCD_COLOR Color); +LCD_COLOR GUI_MEMDEV__Index2Color (int Index); +unsigned int GUI_MEMDEV__GetIndexMask(void); +void GUI_MEMDEV__SetAlphaCallback(unsigned(* pcbSetAlpha)(U8)); + +GUI_MEMDEV_Handle GUI_MEMDEV__CreateFixed(int x0, int y0, int xSize, int ySize, int Flags, + const GUI_DEVICE_API * pDeviceAPI, + const LCD_API_COLOR_CONV * pColorConvAPI); + +void GUI_MEMDEV__DrawSizedAt (GUI_MEMDEV_Handle hMem, int xPos, int yPos, int xSize, int ySize); +GUI_MEMDEV_Handle GUI_MEMDEV__GetEmptyCopy32 (GUI_MEMDEV_Handle hMem, int * pxSize, int * pySize, int * pxPos, int * pyPos); +void GUI_MEMDEV__ReadLine (int x0, int y, int x1, LCD_PIXELINDEX * pBuffer); +void GUI_MEMDEV__WriteToActiveAlpha (GUI_MEMDEV_Handle hMem,int x, int y); +void GUI_MEMDEV__WriteToActiveAt (GUI_MEMDEV_Handle hMem,int x, int y); +void GUI_MEMDEV__WriteToActiveOpaque(GUI_MEMDEV_Handle hMem,int x, int y); +void * GUI_MEMDEV__XY2PTR (int x,int y); +void * GUI_MEMDEV__XY2PTREx (GUI_MEMDEV * pDev, int x,int y); +void GUI_MEMDEV__BlendColor32 (GUI_MEMDEV_Handle hMem, U32 BlendColor, U8 BlendIntens); + +unsigned GUI__AlphaPreserveTrans(int OnOff); + +extern unsigned GUI_MEMDEV__TimePerFrame; + +#define GUI_TIME_PER_FRAME (GUI_TIMER_TIME)GUI_MEMDEV__TimePerFrame + +#define GUI_POS_AUTO -4095 /* Position value for auto-pos */ + +#endif + +/********************************************************************* +* +* LCD_HL_ level defines +* +********************************************************************** +*/ +#define LCD_HL_DrawHLine GUI_pContext->pLCD_HL->pfDrawHLine +#define LCD_HL_DrawPixel GUI_pContext->pLCD_HL->pfDrawPixel + +/********************************************************************* +* +* Helper functions +* +********************************************************************** +*/ +#define GUI_ZEROINIT(Obj) GUI__MEMSET(Obj, 0, sizeof(Obj)) +int GUI_cos(int angle); +int GUI_sin(int angle); +extern const U32 GUI_Pow10[10]; + +/* Multi-touch */ +void GUI_MTOUCH__ManagePID(int OnOff); + +/* Anti-aliased drawing */ +int GUI_AA_Init (int x0, int x1); +int GUI_AA_Init_HiRes (int x0, int x1); +void GUI_AA_Exit (void); +I16 GUI_AA_HiRes2Pixel(int HiRes); + +void GL_FillCircleAA_HiRes (int x0, int y0, int r); +void GL_FillEllipseAA_HiRes(int x0, int y0, int rx, int ry); + +void GUI_AA__DrawCharAA2(int x0, int y0, int XSize, int YSize, int BytesPerLine, const U8 * pData); +void GUI_AA__DrawCharAA4(int x0, int y0, int XSize, int YSize, int BytesPerLine, const U8 * pData); +void GUI_AA__DrawCharAA8(int x0, int y0, int XSize, int YSize, int BytesPerLine, const U8 * pData); + +/* Alpha blending helper functions */ +#define GUI_ALPHABLENDING_DONE (1 << 0) + +int GUI__GetAlphaBuffer (U32 ** ppCurrent, U32 ** ppConvert, U32 ** ppData, int * pVXSizeMax); +int GUI__AllocAlphaBuffer (int AllocDataBuffer); +U32 * GUI__DoAlphaBlending (int x, int y, U32 * pData, int xSize, tLCDDEV_Index2Color * pfIndex2Color_DEV, int * pDone); +unsigned GUI__SetAlphaBufferSize(int xSize); + +/* System independent font routines */ +int GUI_SIF__GetCharDistX (U16P c, int * pSizeX); +void GUI_SIF__GetFontInfo (const GUI_FONT * pFont, GUI_FONTINFO * pfi); +char GUI_SIF__IsInFont (const GUI_FONT * pFont, U16 c); +const U8 * GUI_SIF__GetpCharInfo (const GUI_FONT * pFont, U16P c, unsigned SizeOfCharInfo); +int GUI_SIF__GetNumCharAreas (const GUI_FONT * pFont); +int GUI_SIF__GetCharDistX_ExtFrm(U16P c, int * pSizeX); +void GUI_SIF__GetFontInfo_ExtFrm (const GUI_FONT * pFont, GUI_FONTINFO * pfi); +char GUI_SIF__IsInFont_ExtFrm (const GUI_FONT * pFont, U16 c); +int GUI_SIF__GetCharInfo_ExtFrm (U16P c, GUI_CHARINFO_EXT * pInfo); +void GUI_SIF__ClearLine_ExtFrm (const char * s, int Len); + +/* External binary font routines */ +int GUI_XBF__GetOff (const GUI_XBF_DATA * pXBF_Data, unsigned c, U32 * pOff); +int GUI_XBF__GetOffAndSize(const GUI_XBF_DATA * pXBF_Data, unsigned c, U32 * pOff, U16 * pSize); +int GUI_XBF__GetCharDistX (U16P c, int * pSizeX); +void GUI_XBF__GetFontInfo (const GUI_FONT * pFont, GUI_FONTINFO * pInfo); +char GUI_XBF__IsInFont (const GUI_FONT * pFont, U16 c); +int GUI_XBF__GetCharInfo (U16P c, GUI_CHARINFO_EXT * pInfo); +void GUI_XBF__ClearLine (const char * s, int Len); + +/* Conversion routines */ +void GUI_AddHex (U32 v, U8 Len, char ** ps); +void GUI_AddBin (U32 v, U8 Len, char ** ps); +void GUI_AddDecMin (I32 v, char ** ps); +void GUI_AddDecShift(I32 v, U8 Len, U8 Shift, char ** ps); +long GUI_AddSign (long v, char ** ps); +int GUI_Long2Len (I32 v); + +#define GUI_UC__GetCharSize(sText) GUI_pUC_API->pfGetCharSize(sText) +#define GUI_UC__GetCharCode(sText) GUI_pUC_API->pfGetCharCode(sText) + +int GUI_UC__CalcSizeOfChar (U16 Char); +U16 GUI_UC__GetCharCodeInc (const char ** ps); +int GUI_UC__NumChars2NumBytes(const char * s, int NumChars); +int GUI_UC__NumBytes2NumChars(const char * s, int NumBytes); + +int GUI__GetLineNumChars (const char * s, int MaxNumChars); +int GUI__GetNumChars (const char * s); +int GUI__GetOverlap (U16 Char); +int GUI__GetLineDistX (const char * s, int Len); +int GUI__GetFontSizeY (void); +int GUI__HandleEOLine (const char ** ps); +void GUI__InvertRectColors (int x0, int y0, int x1, int y1); +void GUI__DispLine (const char * s, int Len, const GUI_RECT * pr); +void GUI__AddSpaceHex (U32 v, U8 Len, char ** ps); +void GUI__CalcTextRect (const char * pText, const GUI_RECT * pTextRectIn, GUI_RECT * pTextRectOut, int TextAlign); + +void GUI__ClearTextBackground(int xDist, int yDist); + +int GUI__WrapGetNumCharsDisp (const char * pText, int xSize, GUI_WRAPMODE WrapMode); +int GUI__WrapGetNumCharsToNextLine (const char * pText, int xSize, GUI_WRAPMODE WrapMode); +int GUI__WrapGetNumBytesToNextLine (const char * pText, int xSize, GUI_WRAPMODE WrapMode); +//void GUI__memset (U8 * p, U8 Fill, int NumBytes); +void GUI__memset16 (U16 * p, U16 Fill, int NumWords); +int GUI__strlen (const char * s); +int GUI__strcmp (const char * s0, const char * s1); +int GUI__strcmp_hp (GUI_HMEM hs0, const char * s1); + +/* Get cursor position */ +int GUI__GetCursorPosX (const char * s, int Index, int MaxNumChars); +int GUI__GetCursorPosChar (const char * s, int x, int NumCharsToNextLine); +U16 GUI__GetCursorCharacter(const char * s, int Index, int MaxNumChars, int * pIsRTL); + +/* Arabic support (tbd) */ +U16 GUI__GetPresentationForm (U16 Char, U16 Next, U16 Prev, int * pIgnoreNext, const char * s); +int GUI__IsArabicCharacter (U16 c); + +/* BiDi support */ +int GUI__BIDI_Log2Vis (const char * s, int NumChars, char * pBuffer, int BufferSize); +int GUI__BIDI_GetCursorPosX (const char * s, int NumChars, int Index); +int GUI__BIDI_GetCursorPosChar (const char * s, int NumChars, int x); +U16 GUI__BIDI_GetLogChar (const char * s, int NumChars, int Index); +int GUI__BIDI_GetCharDir (const char * s, int NumChars, int Index); +int GUI__BIDI_IsNSM (U16 Char); +U16 GUI__BIDI_GetCursorCharacter(const char * s, int Index, int MaxNumChars, int * pIsRTL); +int GUI__BIDI_GetWordWrap (const char * s, int xSize, int * pxDist); +int GUI__BIDI_GetCharWrap (const char * s, int xSize); + +#if (GUI_USE_BIDI2) + +#define GUI__BIDI_Log2Vis GUI__BIDI2_Log2Vis +#define GUI__BIDI_GetCursorPosX GUI__BIDI2_GetCursorPosX +#define GUI__BIDI_GetCursorPosChar GUI__BIDI2_GetCursorPosChar +#define GUI__BIDI_GetLogChar GUI__BIDI2_GetLogChar +#define GUI__BIDI_GetCharDir GUI__BIDI2_GetCharDir +#define GUI__BIDI_IsNSM GUI__BIDI2_IsNSM +#define GUI__BIDI_GetCursorCharacter GUI__BIDI2_GetCursorCharacter +#define GUI__BIDI_GetWordWrap GUI__BIDI2_GetWordWrap +#define GUI__BIDI_GetCharWrap GUI__BIDI2_GetCharWrap +#define GUI__BIDI_SetBaseDir GUI__BIDI2_SetBaseDir +#define GUI__BIDI_GetBaseDir GUI__BIDI2_GetBaseDir + +int GUI__BIDI_Log2Vis (const char * s, int NumChars, char * pBuffer, int BufferSize); +int GUI__BIDI_GetCursorPosX (const char * s, int NumChars, int Index); +int GUI__BIDI_GetCursorPosChar (const char * s, int NumChars, int x); +U16 GUI__BIDI_GetLogChar (const char * s, int NumChars, int Index); +int GUI__BIDI_GetCharDir (const char * s, int NumChars, int Index); +int GUI__BIDI_IsNSM (U16 Char); +U16 GUI__BIDI_GetCursorCharacter(const char * s, int Index, int MaxNumChars, int * pIsRTL); +int GUI__BIDI_GetWordWrap (const char * s, int xSize, int * pxDist); +int GUI__BIDI_GetCharWrap (const char * s, int xSize); +void GUI__BIDI_SetBaseDir (int Dir); +int GUI__BIDI_GetBaseDir (void); + +#else + +#define GUI__BIDI_SetBaseDir +#define GUI__BIDI_GetBaseDir + +#endif + +const char * GUI__BIDI_Log2VisBuffered(const char * s, int * pMaxNumChars); + +extern int GUI__BIDI_Enabled; + +extern int (* _pfGUI__BIDI_Log2Vis )(const char * s, int NumChars, char * pBuffer, int BufferSize); +extern int (* _pfGUI__BIDI_GetCursorPosX )(const char * s, int NumChars, int Index); +extern int (* _pfGUI__BIDI_GetCursorPosChar)(const char * s, int NumChars, int x); +extern U16 (* _pfGUI__BIDI_GetLogChar )(const char * s, int NumChars, int Index); +extern int (* _pfGUI__BIDI_GetCharDir )(const char * s, int NumChars, int Index); +extern int (* _pfGUI__BIDI_IsNSM )(U16 Char); + +/* BiDi-related function pointers */ +extern const char * (* GUI_CharLine_pfLog2Vis)(const char * s, int * pMaxNumChars); + +extern int (* GUI__GetCursorPos_pfGetPosX) (const char * s, int MaxNumChars, int Index); +extern int (* GUI__GetCursorPos_pfGetPosChar) (const char * s, int MaxNumChars, int x); +extern U16 (* GUI__GetCursorPos_pfGetCharacter)(const char * s, int MaxNumChars, int Index, int * pIsRTL); + +extern int (* GUI__Wrap_pfGetWordWrap)(const char * s, int xSize, int * pxDist); +extern int (* GUI__Wrap_pfGetCharWrap)(const char * s, int xSize); + +/* Proportional font support */ +const GUI_FONT_PROP * GUIPROP__FindChar(const GUI_FONT_PROP * pProp, U16P c); + +/* Extended proportional font support */ +const GUI_FONT_PROP_EXT * GUIPROP_EXT__FindChar(const GUI_FONT_PROP_EXT * pPropExt, U16P c); +void GUIPROP_EXT__DispLine (const char * s, int Len); +void GUIPROP_EXT__ClearLine (const char * s, int Len); +void GUIPROP_EXT__SetfpClearLine(void (* fpClearLine)(const char * s, int Len)); + +/* Reading data routines */ +U16 GUI__Read16(const U8 ** ppData); +U32 GUI__Read32(const U8 ** ppData); + +/* Virtual screen support */ +void GUI__GetOrg(int * px, int * py); +void GUI__SetOrgHook(void(* pfHook)(int x, int y)); + +/* Timer support */ +int GUI_TIMER__IsActive (void); +GUI_TIMER_TIME GUI_TIMER__GetPeriod (void); +GUI_TIMER_HANDLE GUI_TIMER__GetNextTimer (GUI_TIMER_HANDLE hTimer, U32 * pContext); +GUI_TIMER_HANDLE GUI_TIMER__GetFirstTimer (U32 * pContext); +GUI_TIMER_HANDLE GUI_TIMER__GetNextTimerLin(GUI_TIMER_HANDLE hTimer, U32 * pContext); + +/* Get function pointers for color conversion */ +tLCDDEV_Index2Color * GUI_GetpfIndex2ColorEx(int LayerIndex); +tLCDDEV_Color2Index * GUI_GetpfColor2IndexEx(int LayerIndex); + +int GUI_GetBitsPerPixelEx(int LayerIndex); + +LCD_PIXELINDEX * LCD_GetpPalConvTable (const LCD_LOGPALETTE * pLogPal); +LCD_PIXELINDEX * LCD_GetpPalConvTableUncached(const LCD_LOGPALETTE * pLogPal); +LCD_PIXELINDEX * LCD_GetpPalConvTableBM (const LCD_LOGPALETTE * pLogPal, const GUI_BITMAP * pBitmap, int LayerIndex); + +/* Setting a function for converting a color palette to an array of index values */ +void GUI_SetFuncGetpPalConvTable(LCD_PIXELINDEX * (* pFunc)(const LCD_LOGPALETTE * pLogPal, const GUI_BITMAP * pBitmap, int LayerIndex)); + +/********************************************************************* +* +* Format definitions used by streamed bitmaps +* +* IMPORTANT: DO NOT CHANGE THESE VALUES! +* THEY HAVE TO CORRESPOND TO THE DEFINITIONS WITHIN THE CODE OF THE BITMAPCONVERTER! +*/ +#define GUI_STREAM_FORMAT_INDEXED 100 /* DO NOT CHANGE */ +#define GUI_STREAM_FORMAT_RLE4 6 /* DO NOT CHANGE */ +#define GUI_STREAM_FORMAT_RLE8 7 /* DO NOT CHANGE */ +#define GUI_STREAM_FORMAT_565 8 /* DO NOT CHANGE */ +#define GUI_STREAM_FORMAT_M565 9 /* DO NOT CHANGE */ +#define GUI_STREAM_FORMAT_555 10 /* DO NOT CHANGE */ +#define GUI_STREAM_FORMAT_M555 11 /* DO NOT CHANGE */ +#define GUI_STREAM_FORMAT_RLE16 12 /* DO NOT CHANGE */ +#define GUI_STREAM_FORMAT_RLEM16 13 /* DO NOT CHANGE */ +#define GUI_STREAM_FORMAT_8888 16 /* DO NOT CHANGE */ +#define GUI_STREAM_FORMAT_RLE32 15 /* DO NOT CHANGE */ +#define GUI_STREAM_FORMAT_24 17 /* DO NOT CHANGE */ +#define GUI_STREAM_FORMAT_RLEALPHA 18 /* DO NOT CHANGE */ +#define GUI_STREAM_FORMAT_444_12 19 /* DO NOT CHANGE */ +#define GUI_STREAM_FORMAT_M444_12 20 /* DO NOT CHANGE */ +#define GUI_STREAM_FORMAT_444_12_1 21 /* DO NOT CHANGE */ +#define GUI_STREAM_FORMAT_M444_12_1 22 /* DO NOT CHANGE */ +#define GUI_STREAM_FORMAT_444_16 23 /* DO NOT CHANGE */ +#define GUI_STREAM_FORMAT_M444_16 24 /* DO NOT CHANGE */ +#define GUI_STREAM_FORMAT_A555 25 /* DO NOT CHANGE */ +#define GUI_STREAM_FORMAT_AM555 26 /* DO NOT CHANGE */ +#define GUI_STREAM_FORMAT_A565 27 /* DO NOT CHANGE */ +#define GUI_STREAM_FORMAT_AM565 28 /* DO NOT CHANGE */ +#define GUI_STREAM_FORMAT_M8888I 29 /* DO NOT CHANGE */ + +void GUI__ReadHeaderFromStream (GUI_BITMAP_STREAM * pBitmapHeader, const U8 * pData); +void GUI__CreateBitmapFromStream(const GUI_BITMAP_STREAM * pBitmapHeader, const void * pData, GUI_BITMAP * pBMP, GUI_LOGPALETTE * pPAL, const GUI_BITMAP_METHODS * pMethods); + +/* Cache management */ +int GUI__ManageCache (int Cmd); +int GUI__ManageCacheEx(int LayerIndex, int Cmd); + +/********************************************************************* +* +* 2d - GL +* +********************************************************************** +*/ +void GL_DispChar (U16 c); +void GL_DrawArc (int x0, int y0, int rx, int ry, int a0, int a1); +void GL_DrawBitmap (const GUI_BITMAP * pBM, int x0, int y0); +void GL_DrawCircle (int x0, int y0, int r); +void GL_DrawEllipse (int x0, int y0, int rx, int ry, int w); +void GL_DrawHLine (int y0, int x0, int x1); +void GL_DrawPolygon (const GUI_POINT * pPoints, int NumPoints, int x0, int y0); +void GL_DrawPoint (int x, int y); +void GL_DrawLine1 (int x0, int y0, int x1, int y1); +void GL_DrawLine1Ex (int x0, int y0, int x1, int y1, unsigned * pPixelCnt); +void GL_DrawLineRel (int dx, int dy); +void GL_DrawLineTo (int x, int y); +void GL_DrawLineToEx (int x, int y, unsigned * pPixelCnt); +void GL_DrawLine (int x0, int y0, int x1, int y1); +void GL_DrawLineEx (int x0, int y0, int x1, int y1, unsigned * pPixelCnt); +void GL_MoveTo (int x, int y); +void GL_FillCircle (int x0, int y0, int r); +void GL_FillCircleAA (int x0, int y0, int r); +void GL_FillEllipse (int x0, int y0, int rx, int ry); +void GL_FillPolygon (const GUI_POINT * pPoints, int NumPoints, int x0, int y0); +void GL_SetDefault (void); + +/********************************************************************* +* +* Replacement of memcpy() and memset() +* +********************************************************************** +*/ +// +// Configurable function pointers +// +extern void * (* GUI__pfMemset)(void * pDest, int Fill, unsigned Cnt); +extern void * (* GUI__pfMemcpy)(void * pDest, const void * pSrc, unsigned Cnt); +// +// Macros for typesave use of function pointers +// +#define GUI__MEMSET(pDest, Fill, Cnt) GUI__pfMemset((void *)(pDest), (int)(Fill), (unsigned)(Cnt)) +#define GUI__MEMCPY(pDest, pSrc, Cnt) GUI__pfMemcpy((void *)(pDest), (const void *)(pSrc), (unsigned)(Cnt)) + +/********************************************************************* +* +* Callback pointers for dynamic linkage +* +********************************************************************** +Dynamic linkage pointers reduces configuration hassles. +*/ +typedef int GUI_tfTimer(void); +typedef int WM_tfHandlePID(void); + +/********************************************************************* +* +* Text rotation +* +********************************************************************** +*/ +extern GUI_RECT GUI_RectDispString; /* Used by LCD_Rotate...() and GUI_DispStringInRect() */ + +/********************************************************************* +* +* Flag for setting transparency for 'EXT' fonts +* +********************************************************************** +*/ +extern U8 GUI__CharHasTrans; + +/********************************************************************* +* +* Multitasking support +* +********************************************************************** +*/ +extern int GUITASK__EntranceCnt; + +/********************************************************************* +* +* Bitmap related functions +* +********************************************************************** +*/ + +int GUI_GetBitmapPixelIndex(const GUI_BITMAP * pBMP, unsigned x, unsigned y); +GUI_COLOR GUI_GetBitmapPixelColor(const GUI_BITMAP * pBMP, unsigned x, unsigned y); +int GUI_GetBitmapPixelIndexEx(int BitsPerPixel, int BytesPerLine, const U8 * pData, unsigned x, unsigned y); + +void GUI__DrawBitmap16bpp (int x0, int y0, int xsize, int ysize, const U8 * pPixel, const LCD_LOGPALETTE * pLogPal, int xMag, int yMag, tLCDDEV_Index2Color * pfIndex2Color, const LCD_API_COLOR_CONV * pColorConvAPI); +void GUI__DrawBitmapA16bpp(int x0, int y0, int xSize, int ySize, const U8 * pPixel, const LCD_LOGPALETTE * pLogPal, int xMag, int yMag, tLCDDEV_Index2Color * pfIndex2Color); +void GUI__SetPixelAlpha (int x, int y, U8 Alpha, LCD_COLOR Color); +LCD_COLOR GUI__MixColors (LCD_COLOR Color, LCD_COLOR BkColor, U8 Intens); +void GUI__MixColorsBulk (U32 * pFG, U32 * pBG, U32 * pDst, unsigned OffFG, unsigned OffBG, unsigned OffDest, unsigned xSize, unsigned ySize, U8 Intens); + +extern const GUI_UC_ENC_APILIST GUI_UC_None; + +/********************************************************************* +* +* LCDDEV_L0_xxx +* +********************************************************************** +*/ +#define LCDDEV_L0_Color2Index GUI__apDevice[GUI_pContext->SelLayer]->pColorConvAPI->pfColor2Index +#define LCDDEV_L0_Index2Color GUI__apDevice[GUI_pContext->SelLayer]->pColorConvAPI->pfIndex2Color + +#define LCDDEV_L0_DrawBitmap GUI__apDevice[GUI_pContext->SelLayer]->pDeviceAPI->pfDrawBitmap +#define LCDDEV_L0_DrawHLine GUI__apDevice[GUI_pContext->SelLayer]->pDeviceAPI->pfDrawHLine +#define LCDDEV_L0_DrawVLine GUI__apDevice[GUI_pContext->SelLayer]->pDeviceAPI->pfDrawVLine +#define LCDDEV_L0_DrawPixel GUI__apDevice[GUI_pContext->SelLayer]->pDeviceAPI->pfDrawPixel +#define LCDDEV_L0_FillRect GUI__apDevice[GUI_pContext->SelLayer]->pDeviceAPI->pfFillRect +#define LCDDEV_L0_GetPixel GUI__apDevice[GUI_pContext->SelLayer]->pDeviceAPI->pfGetPixel +#define LCDDEV_L0_GetRect GUI__apDevice[GUI_pContext->SelLayer]->pDeviceAPI->pfGetRect +#define LCDDEV_L0_GetPixelIndex GUI__apDevice[GUI_pContext->SelLayer]->pDeviceAPI->pfGetPixelIndex +#define LCDDEV_L0_SetPixelIndex GUI__apDevice[GUI_pContext->SelLayer]->pDeviceAPI->pfSetPixelIndex +#define LCDDEV_L0_XorPixel GUI__apDevice[GUI_pContext->SelLayer]->pDeviceAPI->pfXorPixel +#define LCDDEV_L0_GetDevFunc GUI__apDevice[GUI_pContext->SelLayer]->pDeviceAPI->pfGetDevFunc + +void LCD_ReadRect (int x0, int y0, int x1, int y1, LCD_PIXELINDEX * pBuffer, GUI_DEVICE * pDevice); +void GUI_ReadRect (int x0, int y0, int x1, int y1, LCD_PIXELINDEX * pBuffer, GUI_DEVICE * pDevice); +void GUI_ReadRectEx(int x0, int y0, int x1, int y1, LCD_PIXELINDEX * pBuffer, GUI_DEVICE * pDevice); + +void LCD_ReadRectNoClip(int x0, int y0, int x1, int y1, LCD_PIXELINDEX * pBuffer, GUI_DEVICE * pDevice); + +/********************************************************************* +* +* Internal color management +* +********************************************************************** +*/ +typedef struct { + void (* pfSetColor) (LCD_COLOR Index); + void (* pfSetBkColor) (LCD_COLOR Index); + LCD_DRAWMODE (* pfSetDrawMode)(LCD_DRAWMODE dm); +} LCD_SET_COLOR_API; + +extern const LCD_SET_COLOR_API * LCD__pSetColorAPI; + +#define LCD__SetBkColorIndex(Index) (*GUI_pContext->LCD_pBkColorIndex = Index) +#define LCD__SetColorIndex(Index) (*GUI_pContext->LCD_pColorIndex = Index) +#define LCD__GetBkColorIndex() (*GUI_pContext->LCD_pBkColorIndex) +#define LCD__GetColorIndex() (*GUI_pContext->LCD_pColorIndex) + +/* The following 2 defines are only required for compatibility to older versions of the TTF library */ +#define LCD_BKCOLORINDEX (*GUI_pContext->LCD_pBkColorIndex) +#define LCD_COLORINDEX (*GUI_pContext->LCD_pColorIndex) + +/********************************************************************* +* +* EXTERNs for GL_CORE +* +********************************************************************** +*/ +extern const GUI_FONT * GUI__pFontDefault; +extern GUI_COLOR GUI__ColorDefault; +extern GUI_COLOR GUI__BkColorDefault; + +extern GUI_SADDR GUI_CONTEXT * GUI_pContext; + +extern GUI_DEVICE * GUI__apDevice[GUI_NUM_LAYERS]; + +// +// Function pointer for converting a palette containing a color array into an index array +// +extern LCD_PIXELINDEX * (* GUI_pfGetpPalConvTable)(const LCD_LOGPALETTE * pLogPal, const GUI_BITMAP * pBitmap, int LayerIndex); + +// +// Function pointer for mixing up 2 colors +// +extern LCD_COLOR (* GUI__pfMixColors)(LCD_COLOR Color, LCD_COLOR BkColor, U8 Intens); + +// +// Function pointer for mixing up arrays of colors +// +extern void (* GUI__pfMixColorsBulk)(U32 * pFG, U32 * pBG, U32 * pDst, unsigned OffFG, unsigned OffBG, unsigned OffDest, unsigned xSize, unsigned ySize, U8 Intens); + +// +// Function pointer for mixing color and gamma values +// +extern LCD_COLOR (* LCD_AA_pfMixColors16)(LCD_COLOR Color, LCD_COLOR BkColor, U8 Intens); + +// +// Function pointer for drawing alpha memory devices +// +extern GUI_DRAWMEMDEV_FUNC * GUI__pfDrawAlphaMemdevFunc; +extern GUI_DRAWMEMDEV_FUNC * GUI__pfDrawM565MemdevFunc; + +// +// Function pointer for drawing alpha bitmaps +// +extern GUI_DRAWBITMAP_FUNC * GUI__pfDrawAlphaBitmapFunc; +extern GUI_DRAWBITMAP_FUNC * GUI__pfDrawM565BitmapFunc; + +// +// API list to be used for MultiBuffering +// +extern const GUI_MULTIBUF_API GUI_MULTIBUF_APIList; +extern const GUI_MULTIBUF_API GUI_MULTIBUF_APIListMasked; +extern const GUI_MULTIBUF_API_EX GUI_MULTIBUF_APIListEx; + +#ifdef GL_CORE_C + #define GUI_EXTERN +#else + #define GUI_EXTERN extern +#endif + +GUI_EXTERN void (* GUI_pfExecAnimations)(void); +GUI_EXTERN int (* GUI_pfUpdateSoftLayer)(void); + +GUI_EXTERN void (* GUI_pfAfterInitHook)(void); + +#ifdef WIN32 + GUI_EXTERN void (* GUI_pfSoftlayerGetPixel)(int x, int y, void * p); +#endif + +GUI_EXTERN void (* GUI_pfHookMTOUCH)(const GUI_MTOUCH_STATE * pState); + +GUI_EXTERN const GUI_UC_ENC_APILIST * GUI_pUC_API; /* Unicode encoding API */ + +GUI_EXTERN GUI_SADDR char GUI_DecChar; +GUI_EXTERN GUI_tfTimer * GUI_pfTimerExec; +GUI_EXTERN WM_tfHandlePID * WM_pfHandlePID; +GUI_EXTERN void (* GUI_pfDispCharStyle)(U16 Char); +GUI_EXTERN void (* GUI_pfDispCharLine)(int x0); + +GUI_EXTERN int GUI__BufferSize; // Required buffer size in pixels for alpha blending and/or antialiasing +GUI_EXTERN int GUI_AA__ClipX0; // x0-clipping value for AA module + +GUI_EXTERN I8 GUI__aNumBuffers[GUI_NUM_LAYERS]; // Number of buffers used per layer +GUI_EXTERN U8 GUI__PreserveTrans; +GUI_EXTERN U8 GUI__IsInitialized; + +GUI_EXTERN U8 GUI__NumLayersInUse; +GUI_EXTERN U32 GUI__LayerMask; + +#if GUI_SUPPORT_ROTATION + GUI_EXTERN const tLCD_APIList * GUI_pLCD_APIList; /* Used for rotating text */ +#endif + +GUI_EXTERN I16 GUI_OrgX, GUI_OrgY; + +#undef GUI_EXTERN + +#if defined(__cplusplus) +} +#endif + +#endif /* GUI_PRIVATE_H */ + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/GUI_SIM_Win32.h b/example/GUI/STemWin/inc/GUI_SIM_Win32.h new file mode 100755 index 0000000000..476d50ca3d --- /dev/null +++ b/example/GUI/STemWin/inc/GUI_SIM_Win32.h @@ -0,0 +1,116 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GUI_SIM_Win32.h +Purpose : Declares public functions of Simulation +---------------------------------------------------------------------- +*/ + +#ifndef SIM_GUI_H +#define SIM_GUI_H + +#include + +#if defined(__cplusplus) +extern "C" { /* Make sure we have C-declarations in C++ programs */ +#endif + +/******************************************************************** +* +* Data +* +********************************************************************* +*/ +extern HINSTANCE SIM_GUI_hInst; +extern HWND SIM_GUI_hWndMain; + +/******************************************************************** +* +* Types +* +********************************************************************* +*/ +typedef struct { + HWND hWndMain; + HWND ahWndLCD[16]; + HWND ahWndColor[16]; +} SIM_GUI_INFO; + +typedef int SIM_GUI_tfHook (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, int * pResult); +typedef void SIM_GUI_tfDelayHandler (int ms); +typedef void SIM_GUI_tfExecIdleHandler(void); + +/******************************************************************** +* +* Interface +* +********************************************************************* +*/ +void SIM_GUI_ShowDevice (int OnOff); +void SIM_GUI_SetCallback (int (* pfCallback)(SIM_GUI_INFO * pInfo)); +void SIM_GUI_HandleKeyEvents (unsigned Msg, WPARAM wParam); +HWND SIM_GUI_CreateCompositeWindow(HWND hParent, int x, int y, int xSize, int ySize, int DisplayIndex); +HWND SIM_GUI_CreateLCDWindow (HWND hParent, int x, int y, int xSize, int ySize, int LayerIndex); +HWND SIM_GUI_CreateLOGWindow (HWND hParent, int x, int y, int xSize, int ySize); +HWND SIM_GUI_CreateLCDInfoWindow (HWND hParent, int x, int y, int xSize, int ySize, int LayerIndex); +void SIM_GUI_Enable (void); +int SIM_GUI_Init (HINSTANCE hInst, HWND hWndMain, char * pCmdLine, const char * sAppName); +void SIM_GUI_CopyToClipboard (int LayerIndex); +void SIM_GUI_SetLCDWindowHook (SIM_GUI_tfHook * pfHook); +void SIM_GUI_SetDelayHandler (SIM_GUI_tfDelayHandler * pfHandler); +void SIM_GUI_SetExecIdleHandler (SIM_GUI_tfExecIdleHandler * pfHandler); +void SIM_GUI_GetCompositeSize (int * pxSize, int * pySize); +int SIM_GUI_GetTransColor (void); +void SIM_GUI_GetLCDPos (int * px, int * py); +void SIM_GUI_Exit (void); +void SIM_GUI_SetMessageBoxOnError (int OnOff); +int SIM_GUI_App (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow); +void SIM_GUI_SetPixel (int x, int y, unsigned Color); + +void SIM_GUI_LOG_Time (void); +void __cdecl SIM_GUI_LOG_Add (const char *format ,... ); +void SIM_GUI_LOG_AddRed(void); +void SIM_GUI_LOG_Clear (void); + +void LCDSIM_CalcCompositePixels(int * pxSize, int * pySize); +const unsigned char * LCDSIM_GetPixelComposite(void); + +void LCDSIM_Paint (HWND hWnd); +void LCDSIM_PaintComposite(HWND hWnd); +void LCDSIM_SetTransMode (int LayerIndex, int TransMode); +void LCDSIM_SetChroma (int LayerIndex, unsigned long ChromaMin, unsigned long ChromaMax); + +#if defined(__cplusplus) +} +#endif + +#endif /* SIM_GUI_H */ diff --git a/example/GUI/STemWin/inc/GUI_SPRITE_Private.h b/example/GUI/STemWin/inc/GUI_SPRITE_Private.h new file mode 100755 index 0000000000..4ed6773fa8 --- /dev/null +++ b/example/GUI/STemWin/inc/GUI_SPRITE_Private.h @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GUI_SPRITE_Private.h +Purpose : Private header file for sprites +---------------------------END-OF-HEADER------------------------------ +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef GUI_SPRITE_PRIVATE_H +#define GUI_SPRITE_PRIVATE_H + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ +#define SPRITE_LOCK_H(h) (GUI_SPRITE_OBJ *)GUI_LOCK_H(h) + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ +// +// The sprite object +// +typedef struct { + GUI_DEVICE * pDevice; + GUI_RECT Rect; + GUI_HMEM hColors; + U16 Flags; + const GUI_BITMAP * pBM; + void (* pCB)(GUI_HSPRITE hSprite, int Cmd); // Callback routine for animated sprites + GUI_HMEM hContext; +} GUI_SPRITE_OBJ; + + +#endif // GUI_SPRITE_PRIVATE_H + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/GUI_SetOrientation.h b/example/GUI/STemWin/inc/GUI_SetOrientation.h new file mode 100755 index 0000000000..fc6ae14261 --- /dev/null +++ b/example/GUI/STemWin/inc/GUI_SetOrientation.h @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GUI_SetOrientation.h +Purpose : Private include file for GUI_SetOrientation_xxx +---------------------------END-OF-HEADER------------------------------ +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef GUI_SETORIENTATION_H +#define GUI_SETORIENTATION_H + +#include "GUI_Private.h" + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ +// +// Use unique context identified +// +#define DRIVER_CONTEXT DRIVER_CONTEXT_ORIENTATION + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ +/********************************************************************* +* +* DRIVER_CONTEXT +*/ +typedef struct DRIVER_CONTEXT DRIVER_CONTEXT; + +struct DRIVER_CONTEXT { + void (* pfLog2Phys)(DRIVER_CONTEXT * pContext, int x, int y, int * px_phys, int * py_phys); + U8 * pData; + int BytesPerPixel; + int BytesPerLine; + int Orientation; + int xSize, ySize; + int vxSize, vySize; + int PixelOffset; + const GUI_ORIENTATION_API * pDrawingAPI; +}; + +/********************************************************************* +* +* Private interface +* +********************************************************************** +*/ +void GUI__Sort(int * p0, int * p1); + +#endif /* GUI_SETORIENTATION_H */ + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/GUI_SetOrientationCX.h b/example/GUI/STemWin/inc/GUI_SetOrientationCX.h new file mode 100755 index 0000000000..1d075e976e --- /dev/null +++ b/example/GUI/STemWin/inc/GUI_SetOrientationCX.h @@ -0,0 +1,626 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GUI_SetOrientationC0.c +Purpose : Runtime display orientation without cache +---------------------------END-OF-HEADER------------------------------ +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +#include "GUI_SetOrientation.h" + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ +#define XY2PTR(x, y) (PIXEL *)(pContext->pData + y * pContext->BytesPerLine + x * pContext->pDrawingAPI->BytesPerPixel) + +/********************************************************************* +* +* Static code +* +********************************************************************** +*/ +/********************************************************************* +* +* Static code +* +********************************************************************** +*/ +/********************************************************************* +* +* _Sort +* +* Purpose: +* Sorts the values pointed by the given pointers. Please note that +* the same static function is also in GUI_SetOrientationC0.h +* to enable better compiler optimization. +*/ +static void _Sort(int * p0, int * p1) { + int temp; + + if (*p0 > *p1) { + temp = *p0; + *p0 = *p1; + *p1 = temp; + } +} + +/********************************************************************* +* +* Static code: Bitmap drawing routines +* +********************************************************************** +*/ +/********************************************************************* +* +* Draw Bitmap 1 BPP +*/ +static void _DrawBitLine1BPP(GUI_DEVICE * pDevice, unsigned x, unsigned y, U8 const * p, int Diff, int xsize, const LCD_PIXELINDEX * pTrans) { + LCD_PIXELINDEX IndexMask, Index0, Index1, Pixel; + LCD_PIXELINDEX (* pfGetPixelIndex)(GUI_DEVICE *, int, int); + PIXEL * pData; + int x_phys, y_phys; + DRIVER_CONTEXT * pContext; + + pContext = (DRIVER_CONTEXT *)pDevice->u.pContext; + Index0 = *(pTrans + 0); + Index1 = *(pTrans + 1); + x += Diff; + pContext->pfLog2Phys(pContext, x, y, &x_phys, &y_phys); + pData = XY2PTR(x_phys, y_phys); + switch (GUI_pContext->DrawMode & (LCD_DRAWMODE_TRANS | LCD_DRAWMODE_XOR)) { + case 0: + do { + *pData = (PIXEL)((*p & (0x80 >> Diff)) ? Index1 : Index0); + pData += pContext->PixelOffset; + if (++Diff == 8) { + Diff = 0; + p++; + } + } while (--xsize); + break; + case LCD_DRAWMODE_TRANS: + do { + if (*p & (0x80 >> Diff)) { + *pData = (PIXEL)Index1; + } + pData += pContext->PixelOffset; + if (++Diff == 8) { + Diff = 0; + p++; + } + } while (--xsize); + break; + case LCD_DRAWMODE_XOR | LCD_DRAWMODE_TRANS: + case LCD_DRAWMODE_XOR: + pfGetPixelIndex = pDevice->pDeviceAPI->pfGetPixelIndex; + IndexMask = pDevice->pColorConvAPI->pfGetIndexMask(); + do { + if (*p & (0x80 >> Diff)) { + Pixel = pfGetPixelIndex(pDevice, x, y); + Pixel ^= IndexMask; + *pData = (PIXEL)Pixel; + } + pData += pContext->PixelOffset; + x++; + if (++Diff == 8) { + Diff = 0; + p++; + } + } while (--xsize); + break; + } +} + +/********************************************************************* +* +* Draw Bitmap 2 BPP +*/ +static void _DrawBitLine2BPP(GUI_DEVICE * pDevice, int x, int y, U8 const * p, int Diff, int xsize, const LCD_PIXELINDEX * pTrans) { + LCD_PIXELINDEX Pixels, PixelIndex; + int CurrentPixel, Shift, Index; + PIXEL * pData; + int x_phys, y_phys; + DRIVER_CONTEXT * pContext; + + pContext = (DRIVER_CONTEXT *)pDevice->u.pContext; + Pixels = *p; + CurrentPixel = Diff; + x += Diff; + pContext->pfLog2Phys(pContext, x, y, &x_phys, &y_phys); + pData = XY2PTR(x_phys, y_phys); + switch (GUI_pContext->DrawMode & (LCD_DRAWMODE_TRANS | LCD_DRAWMODE_XOR)) { + case 0: + if (pTrans) { + do { + Shift = (3 - CurrentPixel) << 1; + Index = (Pixels & (0xC0 >> (6 - Shift))) >> Shift; + PixelIndex = *(pTrans + Index); + *pData = (PIXEL)PixelIndex; + pData += pContext->PixelOffset; + if (++CurrentPixel == 4) { + CurrentPixel = 0; + Pixels = *(++p); + } + } while (--xsize); + } else { + do { + Shift = (3 - CurrentPixel) << 1; + Index = (Pixels & (0xC0 >> (6 - Shift))) >> Shift; + *pData = (PIXEL)Index; + pData += pContext->PixelOffset; + if (++CurrentPixel == 4) { + CurrentPixel = 0; + Pixels = *(++p); + } + } while (--xsize); + } + break; + case LCD_DRAWMODE_TRANS: + if (pTrans) { + do { + Shift = (3 - CurrentPixel) << 1; + Index = (Pixels & (0xC0 >> (6 - Shift))) >> Shift; + if (Index) { + PixelIndex = *(pTrans + Index); + *pData = (PIXEL)PixelIndex; + } + pData += pContext->PixelOffset; + if (++CurrentPixel == 4) { + CurrentPixel = 0; + Pixels = *(++p); + } + } while (--xsize); + } else { + do { + Shift = (3 - CurrentPixel) << 1; + Index = (Pixels & (0xC0 >> (6 - Shift))) >> Shift; + if (Index) { + *pData = (PIXEL)Index; + } + pData += pContext->PixelOffset; + if (++CurrentPixel == 4) { + CurrentPixel = 0; + Pixels = *(++p); + } + } while (--xsize); + } + break; + } +} + +/********************************************************************* +* +* Draw Bitmap 4 BPP +*/ +static void _DrawBitLine4BPP(GUI_DEVICE * pDevice, int x, int y, U8 const * p, int Diff, int xsize, const LCD_PIXELINDEX * pTrans) { + LCD_PIXELINDEX Pixels, PixelIndex; + int CurrentPixel, Shift, Index; + PIXEL * pData; + int x_phys, y_phys; + DRIVER_CONTEXT * pContext; + + pContext = (DRIVER_CONTEXT *)pDevice->u.pContext; + Pixels = *p; + CurrentPixel = Diff; + x += Diff; + pContext->pfLog2Phys(pContext, x, y, &x_phys, &y_phys); + pData = XY2PTR(x_phys, y_phys); + switch (GUI_pContext->DrawMode & (LCD_DRAWMODE_TRANS | LCD_DRAWMODE_XOR)) { + case 0: + if (pTrans) { + do { + Shift = (1 - CurrentPixel) << 2; + Index = (Pixels & (0xF0 >> (4 - Shift))) >> Shift; + PixelIndex = *(pTrans + Index); + *pData = (PIXEL)PixelIndex; + pData += pContext->PixelOffset; + if (++CurrentPixel == 2) { + CurrentPixel = 0; + Pixels = *(++p); + } + } while (--xsize); + } else { + do { + Shift = (1 - CurrentPixel) << 2; + Index = (Pixels & (0xF0 >> (4 - Shift))) >> Shift; + *pData = (PIXEL)Index; + pData += pContext->PixelOffset; + if (++CurrentPixel == 2) { + CurrentPixel = 0; + Pixels = *(++p); + } + } while (--xsize); + } + break; + case LCD_DRAWMODE_TRANS: + if (pTrans) { + do { + Shift = (1 - CurrentPixel) << 2; + Index = (Pixels & (0xF0 >> (4 - Shift))) >> Shift; + if (Index) { + PixelIndex = *(pTrans + Index); + *pData = (PIXEL)PixelIndex; + } + pData += pContext->PixelOffset; + if (++CurrentPixel == 2) { + CurrentPixel = 0; + Pixels = *(++p); + } + } while (--xsize); + } else { + do { + Shift = (1 - CurrentPixel) << 2; + Index = (Pixels & (0xF0 >> (4 - Shift))) >> Shift; + if (Index) { + *pData = (PIXEL)Index; + } + pData += pContext->PixelOffset; + if (++CurrentPixel == 2) { + CurrentPixel = 0; + Pixels = *(++p); + } + } while (--xsize); + } + break; + } +} + +/********************************************************************* +* +* Draw Bitmap 8 BPP +*/ +static void _DrawBitLine8BPP(GUI_DEVICE * pDevice, int x, int y, U8 const * p, int xsize, const LCD_PIXELINDEX * pTrans) { + LCD_PIXELINDEX Pixel; + PIXEL * pData; + int x_phys, y_phys; + DRIVER_CONTEXT * pContext; + + pContext = (DRIVER_CONTEXT *)pDevice->u.pContext; + pContext->pfLog2Phys(pContext, x, y, &x_phys, &y_phys); + pData = XY2PTR(x_phys, y_phys); + switch (GUI_pContext->DrawMode & (LCD_DRAWMODE_TRANS | LCD_DRAWMODE_XOR)) { + case 0: + if (pTrans) { + do { + Pixel = *p++; + *pData = (PIXEL)*(pTrans + Pixel); + pData += pContext->PixelOffset; + } while (--xsize); + } else { + do { + *pData = (PIXEL)*p++; + pData += pContext->PixelOffset; + } while (--xsize); + } + break; + case LCD_DRAWMODE_TRANS: + if (pTrans) { + do { + Pixel = *p++; + if (Pixel) { + *pData = (PIXEL)*(pTrans + Pixel); + } + pData += pContext->PixelOffset; + } while (--xsize); + } else { + do { + Pixel = *p++; + if (Pixel) { + *pData = (PIXEL)Pixel; + } + pData += pContext->PixelOffset; + } while (--xsize); + } + break; + } +} + +/********************************************************************* +* +* Draw Bitmap 16 BPP +*/ +static void _DrawBitLine16BPP(GUI_DEVICE * pDevice, int x, int y, U16 const * p, int xsize) { + PIXEL * pData; + int x_phys, y_phys, PixelOffset; + DRIVER_CONTEXT * pContext; + + pContext = (DRIVER_CONTEXT *)pDevice->u.pContext; + pContext->pfLog2Phys(pContext, x, y, &x_phys, &y_phys); + pData = XY2PTR(x_phys, y_phys); + PixelOffset = pContext->PixelOffset; + do { + *pData = (PIXEL)*p++; + pData += PixelOffset; + } while (--xsize); +} + +/********************************************************************* +* +* Draw Bitmap 32 BPP +*/ +static void _DrawBitLine32BPP(GUI_DEVICE * pDevice, int x, int y, U32 const * p, int xsize) { + PIXEL * pData; + int x_phys, y_phys, PixelOffset; + DRIVER_CONTEXT * pContext; + + pContext = (DRIVER_CONTEXT *)pDevice->u.pContext; + pContext->pfLog2Phys(pContext, x, y, &x_phys, &y_phys); + pData = XY2PTR(x_phys, y_phys); + PixelOffset = pContext->PixelOffset; + do { + *pData = (PIXEL)*p++; + pData += PixelOffset; + } while (--xsize); +} + +/********************************************************************* +* +* Static code: API functions for drawing operations, no cache +* +********************************************************************** +*/ +/********************************************************************* +* +* _DrawBitmap_CX +*/ +static void _DrawBitmap_CX(GUI_DEVICE * pDevice, int x0, int y0, + int xSize, int ySize, + int BitsPerPixel, + int BytesPerLine, + const U8 * pData, int Diff, + const LCD_PIXELINDEX * pTrans) { + int x0_phys, y0_phys, x1_phys, y1_phys; + int i; + PIXEL * pDataBM; + DRIVER_CONTEXT * pContext; + + pContext = (DRIVER_CONTEXT *)pDevice->u.pContext; + switch (BitsPerPixel) { + case 1: + for (i = 0; i < ySize; i++) { + _DrawBitLine1BPP(pDevice, x0, i + y0, pData, Diff, xSize, pTrans); + pData += BytesPerLine; + } + break; + case 2: + for (i = 0; i < ySize; i++) { + _DrawBitLine2BPP(pDevice, x0, i + y0, pData, Diff, xSize, pTrans); + pData += BytesPerLine; + } + break; + case 4: + for (i = 0; i < ySize; i++) { + _DrawBitLine4BPP(pDevice, x0, i + y0, pData, Diff, xSize, pTrans); + pData += BytesPerLine; + } + break; + case 8: + for (i = 0; i < ySize; i++) { + _DrawBitLine8BPP(pDevice, x0, i + y0, pData, xSize, pTrans); + pData += BytesPerLine; + } + break; + case 16: + for (i = 0; i < ySize; i++) { + _DrawBitLine16BPP(pDevice, x0, i + y0, (U16 *)pData, xSize); + pData += BytesPerLine; + } + break; + case 32: + for (i = 0; i < ySize; i++) { + _DrawBitLine32BPP(pDevice, x0, i + y0, (U32 *)pData, xSize); + pData += BytesPerLine; + } + break; + } + + pContext->pfLog2Phys(pContext, x0 + Diff, y0, &x0_phys, &y0_phys); + pContext->pfLog2Phys(pContext, x0 + Diff + xSize - 1, y0 + ySize - 1, &x1_phys, &y1_phys); + _Sort(&x0_phys, &x1_phys); + _Sort(&y0_phys, &y1_phys); + pDataBM = XY2PTR(x0_phys, y0_phys); + pDevice = pDevice->pNext; + pDevice->pDeviceAPI->pfDrawBitmap(pDevice, + x0_phys, y0_phys, + x1_phys - x0_phys + 1, + y1_phys - y0_phys + 1, + pContext->pDrawingAPI->BytesPerPixel << 3, + pContext->pDrawingAPI->BytesPerPixel * pContext->vxSize, + (U8 *)pDataBM, 0, NULL); +} + +/********************************************************************* +* +* _GetPixelIndex_CX +*/ +static LCD_PIXELINDEX _GetPixelIndex_CX(GUI_DEVICE * pDevice, int x, int y) { + PIXEL * pData; + PIXEL Pixel; + int x_phys, y_phys; + DRIVER_CONTEXT * pContext; + + pContext = (DRIVER_CONTEXT *)pDevice->u.pContext; + pContext->pfLog2Phys(pContext, x, y, &x_phys, &y_phys); + pData = XY2PTR(x_phys, y_phys); + Pixel = *pData; + return Pixel; +} + +/********************************************************************* +* +* _SetPixelIndex_CX +*/ +static void _SetPixelIndex_CX(GUI_DEVICE * pDevice, int x, int y, LCD_PIXELINDEX PixelIndex) { + PIXEL * pData; + int x_phys, y_phys; + DRIVER_CONTEXT * pContext; + + pContext = (DRIVER_CONTEXT *)pDevice->u.pContext; + pContext->pfLog2Phys(pContext, x, y, &x_phys, &y_phys); + pData = XY2PTR(x_phys, y_phys); + *pData = (PIXEL)PixelIndex; + pDevice = pDevice->pNext; + pDevice->pDeviceAPI->pfSetPixelIndex(pDevice, x_phys, y_phys, PixelIndex); +} + +/********************************************************************* +* +* _XorPixel_CX +*/ +static void _XorPixel_CX(GUI_DEVICE * pDevice, int x, int y) { + PIXEL Pixel, IndexMask; + + IndexMask = (PIXEL)pDevice->pColorConvAPI->pfGetIndexMask(); + Pixel = (PIXEL)pDevice->pDeviceAPI->pfGetPixelIndex(pDevice, x, y); + Pixel ^= IndexMask; + pDevice->pDeviceAPI->pfSetPixelIndex(pDevice, x, y, Pixel); +} + +/********************************************************************* +* +* _DrawHLine_CX +*/ +static void _DrawHLine_CX(GUI_DEVICE * pDevice, int x0, int y, int x1) { + pDevice->pDeviceAPI->pfFillRect(pDevice, x0, y, x1, y); +} + +/********************************************************************* +* +* _DrawVLine_CX +*/ +static void _DrawVLine_CX(GUI_DEVICE * pDevice, int x, int y0, int y1) { + pDevice->pDeviceAPI->pfFillRect(pDevice, x, y0, x, y1); +} + +/********************************************************************* +* +* _FillRect_CX +*/ +static void _FillRect_CX(GUI_DEVICE * pDevice, int x0, int y0, int x1, int y1) { + PIXEL * pData; + PIXEL * pLine; + PIXEL * pPixel; + PIXEL Pixel, IndexMask; + int x0_phys, y0_phys, x1_phys, y1_phys; + int NumPixels, NumLines; + DRIVER_CONTEXT * pContext; + + pContext = (DRIVER_CONTEXT *)pDevice->u.pContext; + pContext->pfLog2Phys(pContext, x0, y0, &x0_phys, &y0_phys); + pContext->pfLog2Phys(pContext, x1, y1, &x1_phys, &y1_phys); + _Sort(&x0_phys, &x1_phys); + _Sort(&y0_phys, &y1_phys); + pData = pLine = XY2PTR(x0_phys, y0_phys); + NumLines = y1_phys - y0_phys + 1; + if (GUI_pContext->DrawMode & LCD_DRAWMODE_XOR) { + IndexMask = (PIXEL)pDevice->pColorConvAPI->pfGetIndexMask(); + do { + pPixel = pLine; + NumPixels = x1_phys - x0_phys + 1; + do { + *pPixel++ ^= IndexMask; + } while (--NumPixels); + pLine += pContext->vxSize; + } while (--NumLines); + } else { + Pixel = (PIXEL)LCD__GetColorIndex(); + if (sizeof(Pixel) == 1) { + NumPixels = x1_phys - x0_phys + 1; + do { + GUI__MEMSET((U8 *)pLine, (U8)Pixel, NumPixels); + pLine += pContext->vxSize; + } while (--NumLines); + } else { + do { + pPixel = pLine; + NumPixels = x1_phys - x0_phys + 1; + do { + *pPixel++ = Pixel; + } while (--NumPixels); + pLine += pContext->vxSize; + } while (--NumLines); + } + } + pDevice = pDevice->pNext; + pDevice->pDeviceAPI->pfDrawBitmap(pDevice, + x0_phys, y0_phys, + x1_phys - x0_phys + 1, + y1_phys - y0_phys + 1, + pContext->pDrawingAPI->BytesPerPixel << 3, + pContext->pDrawingAPI->BytesPerPixel * pContext->vxSize, + (U8 *)pData, 0, NULL); +} + +/********************************************************************* +* +* Static data: Drawing API(s) +* +********************************************************************** +*/ +/********************************************************************* +* +* GUI_OrientationAPI_CX +*/ +const GUI_ORIENTATION_API API_NAME = { + _DrawBitmap_CX, + _DrawHLine_CX, + _DrawVLine_CX, + _FillRect_CX, + _GetPixelIndex_CX, + _SetPixelIndex_CX, + _XorPixel_CX, + BYTES_PER_PIXEL +}; + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/GUI_Type.h b/example/GUI/STemWin/inc/GUI_Type.h new file mode 100755 index 0000000000..dec73e2117 --- /dev/null +++ b/example/GUI/STemWin/inc/GUI_Type.h @@ -0,0 +1,694 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GUI_Type.h +Purpose : Include file define the types used for GUI +---------------------------END-OF-HEADER------------------------------ + +Attention : Do not modify this file ! If you do, you will not + be able do update to a later GUI version ! + +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef GUITYPE_H_INCLUDED +#define GUITYPE_H_INCLUDED + +#include "LCD.h" +#include "GUIConf.h" + +/********************************************************************* +* +* Common types +*/ +typedef const char * GUI_ConstString; + +typedef LCD_COLOR GUI_COLOR; +typedef LCD_LOGPALETTE GUI_LOGPALETTE; +typedef LCD_DRAWMODE GUI_DRAWMODE; +typedef LCD_RECT GUI_RECT; + +typedef struct { + void (* pfDraw) (int x0, + int y0, + int xsize, + int ysize, + const U8 * pPixel, + const LCD_LOGPALETTE * pLogPal, + int xMag, + int yMag); + GUI_COLOR (* pfIndex2Color)(LCD_PIXELINDEX Index); + void (* pfDrawHW)(int x0, + int y0, + int xsize, + int ysize, + const U8 * pPixel, + const LCD_LOGPALETTE * pLogPal, + int xMag, + int yMag); + const LCD_API_COLOR_CONV * pColorConvAPI; +} GUI_BITMAP_METHODS; + +typedef struct { + U16P XSize; + U16P YSize; + U16P BytesPerLine; + U16P BitsPerPixel; + const U8 * pData; + const GUI_LOGPALETTE * pPal; + const GUI_BITMAP_METHODS * pMethods; +} GUI_BITMAP; + +/* This structure may not be changed because the data that it + expects is read in binary form (via any kind of interface, + at runtime). + This structure should therefor not be changed. +*/ +typedef struct { + U16 ID; + U16 Format; + U16 XSize; + U16 YSize; + U16 BytesPerLine; + U16 BitsPerPixel; + U16 NumColors; + U16 HasTrans; +} GUI_BITMAP_STREAM; + +typedef struct { + int Cmd; + U32 v; + void * p; +} GUI_BITMAPSTREAM_PARAM; + +typedef struct { + int XSize; + int YSize; + int BitsPerPixel; + int NumColors; + int HasTrans; +} GUI_BITMAPSTREAM_INFO; + +typedef void * (* GUI_BITMAPSTREAM_CALLBACK)(GUI_BITMAPSTREAM_PARAM * pParam); + +typedef struct { + int x,y; + U8 Pressed; + U8 Layer; +} GUI_PID_STATE; + +typedef struct { + int Key; + int Pressed; +} GUI_KEY_STATE; + +typedef struct { + int xPos; + int yPos; + int xSize; + int ySize; + int Delay; +} GUI_GIF_IMAGE_INFO; + +typedef struct { + int xSize; + int ySize; + int NumImages; +} GUI_GIF_INFO; + +typedef struct GUI_REGISTER_EXIT GUI_REGISTER_EXIT; + +struct GUI_REGISTER_EXIT { + void (* pfVoid)(void); + GUI_REGISTER_EXIT * pNext; +}; + +typedef struct { + void (* cbBegin)(void); + void (* cbEnd) (void); +} GUI_MULTIBUF_API; + +typedef struct { + void (* cbBeginEx)(int LayerIndex); + void (* cbEndEx) (int LayerIndex); +} GUI_MULTIBUF_API_EX; + +/********************************************************************* +* +* FONT structures +*/ + +/* Translation list. Translates a character code into up to 2 + indices of images to display on top of each other; + 'á' -> index('a'), index('´') */ +typedef struct { + I16P c0; + I16P c1; +} GUI_FONT_TRANSLIST; + +typedef struct { + U16P FirstChar; + U16P LastChar; + const GUI_FONT_TRANSLIST * pList; +} GUI_FONT_TRANSINFO; + +typedef struct { + U8 XSize; + U8 XDist; + U8 BytesPerLine; + const unsigned char * pData; +} GUI_CHARINFO; + +typedef struct { + U8 XSize; + U8 YSize; + I8 XPos; + I8 YPos; + U8 XDist; + const unsigned char * pData; +} GUI_CHARINFO_EXT; + +typedef struct GUI_FONT_PROP { + U16P First; /* First character */ + U16P Last; /* Last character */ + const GUI_CHARINFO * paCharInfo; /* Address of first character */ + const struct GUI_FONT_PROP * pNext; /* Pointer to next */ +} GUI_FONT_PROP; + +typedef struct GUI_FONT_PROP_EXT { + U16P First; /* First character */ + U16P Last; /* Last character */ + const GUI_CHARINFO_EXT * paCharInfo; /* Address of first character */ + const struct GUI_FONT_PROP_EXT * pNext; /* Pointer to next */ +} GUI_FONT_PROP_EXT; + +typedef struct { + const unsigned char * pData; + const U8 * pTransData; + const GUI_FONT_TRANSINFO * pTrans; + U16P FirstChar; + U16P LastChar; + U8 XSize; + U8 XDist; + U8 BytesPerLine; +} GUI_FONT_MONO; + +/********************************************************************* +* +* FONT structures +* +* This structure is used when retrieving information about a font. +* It is designed for future expansion without incompatibilities. +*/ +typedef struct { + U16 Flags; + U8 Baseline; + U8 LHeight; /* height of a small lower case character (a,x) */ + U8 CHeight; /* height of a small upper case character (A,X) */ +} GUI_FONTINFO; + +#define GUI_FONTINFO_FLAG_PROP (1 << 0) /* Is proportional */ +#define GUI_FONTINFO_FLAG_MONO (1 << 1) /* Is monospaced */ +#define GUI_FONTINFO_FLAG_AA (1 << 2) /* Is an antialiased font */ +#define GUI_FONTINFO_FLAG_AA2 (1 << 3) /* Is an antialiased font, 2bpp */ +#define GUI_FONTINFO_FLAG_AA4 (1 << 4) /* Is an antialiased font, 4bpp */ +#define GUI_FONTINFO_FLAG_PROPFRM (1 << 5) /* Is proportional, framed */ + +/********************************************************************* +* +* UNICODE Encoding +*/ +typedef U16 tGUI_GetCharCode (const char * s); +typedef int tGUI_GetCharSize (const char * s); +typedef int tGUI_CalcSizeOfChar(U16 Char); +typedef int tGUI_Encode (char * s, U16 Char); + +typedef struct { + tGUI_GetCharCode * pfGetCharCode; + tGUI_GetCharSize * pfGetCharSize; + tGUI_CalcSizeOfChar * pfCalcSizeOfChar; + tGUI_Encode * pfEncode; +} GUI_UC_ENC_APILIST; + +/********************************************************************* +* +* FONT Encoding +*/ +typedef int tGUI_GetLineDistX(const char * s, int Len); +typedef int tGUI_GetLineLen (const char * s, int MaxLen); +typedef void tGL_DispLine (const char * s, int Len); + +typedef struct { + tGUI_GetLineDistX * pfGetLineDistX; + tGUI_GetLineLen * pfGetLineLen; + tGL_DispLine * pfDispLine; +} tGUI_ENC_APIList; + +extern const tGUI_ENC_APIList GUI_ENC_APIList_SJIS; +extern const tGUI_ENC_APIList GUI_ENC_APIList_EXT; + +/********************************************************************* +* +* FONT methods +*/ +typedef struct GUI_FONT GUI_FONT; + +typedef void GUI_DISPCHAR (U16 c); +typedef int GUI_GETCHARDISTX(U16P c, int * pSizeX); +typedef void GUI_GETFONTINFO (const GUI_FONT * pFont, GUI_FONTINFO * pfi); +typedef char GUI_ISINFONT (const GUI_FONT * pFont, U16 c); +typedef int GUI_GETCHARINFO (U16P c, GUI_CHARINFO_EXT * pInfo); + +#define DECLARE_FONT(Type) \ +void GUI##Type##_DispChar (U16P c); \ +int GUI##Type##_GetCharDistX(U16P c, int * pSizeX); \ +void GUI##Type##_GetFontInfo (const GUI_FONT * pFont, GUI_FONTINFO * pfi); \ +char GUI##Type##_IsInFont (const GUI_FONT * pFont, U16 c); \ +int GUI##Type##_GetCharInfo (U16P c, GUI_CHARINFO_EXT * pInfo) + +#if defined(__cplusplus) +extern "C" { /* Make sure we have C-declarations in C++ programs */ +#endif + +DECLARE_FONT(MONO); +DECLARE_FONT(PROP); +DECLARE_FONT(PROP_EXT); +DECLARE_FONT(PROP_FRM); +DECLARE_FONT(PROPAA); +DECLARE_FONT(PROP_AA2); +DECLARE_FONT(PROP_AA2_EXT); +DECLARE_FONT(PROP_AA4); +DECLARE_FONT(PROP_AA4_EXT); + +/* MONO: Monospaced fonts */ +#define GUI_FONTTYPE_MONO \ + GUIMONO_DispChar, \ + GUIMONO_GetCharDistX, \ + GUIMONO_GetFontInfo, \ + GUIMONO_IsInFont, \ + (GUI_GETCHARINFO *)0, \ + (tGUI_ENC_APIList*)0 + +/* PROP: Proportional fonts */ +#define GUI_FONTTYPE_PROP \ + GUIPROP_DispChar, \ + GUIPROP_GetCharDistX, \ + GUIPROP_GetFontInfo, \ + GUIPROP_IsInFont, \ + (GUI_GETCHARINFO *)0, \ + (tGUI_ENC_APIList*)0 + +/* PROP_EXT: Extended proportional fonts */ +#define GUI_FONTTYPE_PROP_EXT \ + GUIPROP_EXT_DispChar, \ + GUIPROP_EXT_GetCharDistX, \ + GUIPROP_EXT_GetFontInfo, \ + GUIPROP_EXT_IsInFont, \ + GUIPROP_EXT_GetCharInfo, \ + &GUI_ENC_APIList_EXT + +/* PROP_FRM: Extended proportional fonts, framed */ +#define GUI_FONTTYPE_PROP_FRM \ + GUIPROP_FRM_DispChar, \ + GUIPROP_FRM_GetCharDistX, \ + GUIPROP_FRM_GetFontInfo, \ + GUIPROP_FRM_IsInFont, \ + (GUI_GETCHARINFO *)0, \ + (tGUI_ENC_APIList*)0 + +/* PROP: Proportional fonts SJIS */ +#define GUI_FONTTYPE_PROP_SJIS \ + GUIPROP_DispChar, \ + GUIPROP_GetCharDistX, \ + GUIPROP_GetFontInfo, \ + GUIPROP_IsInFont, \ + (GUI_GETCHARINFO *)0, \ + &GUI_ENC_APIList_SJIS + +/* PROPAA: Proportional, antialiased fonts */ +#define GUI_FONTTYPE_PROPAA \ + GUIPROPAA_DispChar, \ + GUIPROPAA_GetCharDistX, \ + GUIPROPAA_GetFontInfo, \ + GUIPROPAA_IsInFont, \ + (GUI_GETCHARINFO *)0, \ + (tGUI_ENC_APIList*)0 + +/* PROP_AA2: Proportional, antialiased fonts, 2bpp */ +#define GUI_FONTTYPE_PROP_AA2 \ + GUIPROP_AA2_DispChar, \ + GUIPROP_AA2_GetCharDistX, \ + GUIPROP_AA2_GetFontInfo, \ + GUIPROP_AA2_IsInFont, \ + (GUI_GETCHARINFO *)0, \ + (tGUI_ENC_APIList*)0 + +/* PROP_AA2_EXT: Proportional, antialiased fonts, 2bpp, extended font information */ +#define GUI_FONTTYPE_PROP_AA2_EXT \ + GUIPROP_AA2_EXT_DispChar, \ + GUIPROP_EXT_GetCharDistX, \ + GUIPROP_EXT_GetFontInfo, \ + GUIPROP_EXT_IsInFont, \ + GUIPROP_EXT_GetCharInfo, \ + &GUI_ENC_APIList_EXT + +/* PROP_AA2: Proportional, antialiased fonts, 2bpp, SJIS encoding */ +#define GUI_FONTTYPE_PROP_AA2_SJIS \ + GUIPROP_AA2_DispChar, \ + GUIPROP_AA2_GetCharDistX, \ + GUIPROP_AA2_GetFontInfo, \ + GUIPROP_AA2_IsInFont, \ + (GUI_GETCHARINFO *)0, \ + &GUI_ENC_APIList_SJIS + +/* PROP_AA4: Proportional, antialiased fonts, 4bpp */ +#define GUI_FONTTYPE_PROP_AA4 \ + GUIPROP_AA4_DispChar, \ + GUIPROP_AA4_GetCharDistX, \ + GUIPROP_AA4_GetFontInfo, \ + GUIPROP_AA4_IsInFont, \ + (GUI_GETCHARINFO *)0, \ + (tGUI_ENC_APIList*)0 + +/* PROP_AA4_EXT: Proportional, antialiased fonts, 4bpp, extended font information */ +#define GUI_FONTTYPE_PROP_AA4_EXT \ + GUIPROP_AA4_EXT_DispChar, \ + GUIPROP_EXT_GetCharDistX, \ + GUIPROP_EXT_GetFontInfo, \ + GUIPROP_EXT_IsInFont, \ + GUIPROP_EXT_GetCharInfo, \ + &GUI_ENC_APIList_EXT + +/* PROP_AA4: Proportional, antialiased fonts, 4bpp, SJIS encoding */ +#define GUI_FONTTYPE_PROP_AA4_SJIS \ + GUIPROP_AA4_DispChar, \ + GUIPROP_AA4_GetCharDistX, \ + GUIPROP_AA4_GetFontInfo, \ + GUIPROP_AA4_IsInFont, \ + (GUI_GETCHARINFO *)0, \ + &GUI_ENC_APIList_SJIS + +#if defined(__cplusplus) + } +#endif + +struct GUI_FONT { + GUI_DISPCHAR * pfDispChar; + GUI_GETCHARDISTX * pfGetCharDistX; + GUI_GETFONTINFO * pfGetFontInfo; + GUI_ISINFONT * pfIsInFont; + GUI_GETCHARINFO * pfGetCharInfo; + const tGUI_ENC_APIList* pafEncode; + U8 YSize; + U8 YDist; + U8 XMag; + U8 YMag; + union { + const void * pFontData; + const GUI_FONT_MONO * pMono; + const GUI_FONT_PROP * pProp; + const GUI_FONT_PROP_EXT * pPropExt; + } p; + U8 Baseline; + U8 LHeight; /* Height of a small lower case character (a,x) */ + U8 CHeight; /* Height of a small upper case character (A,X) */ +}; + +/********************************************************************* +* +* Bitmap serialization (BMP) +*/ +typedef void GUI_CALLBACK_VOID_U8_P(U8 Data, void * p); + +/********************************************************************* +* +* System independent font structures (SIF) +*/ +typedef struct { + U32 ID; /* Font file ID */ + U16 YSize; /* Height of font */ + U16 YDist; /* Space of font Y */ + U16 Baseline; /* Index of baseline */ + U16 LHeight; /* Height of a small lower case character (a) */ + U16 CHeight; /* Height of a upper case character (A) */ + U16 NumAreas; /* Number of character areas */ +} GUI_SI_FONT; + +typedef struct { + U16 First; /* Index of first character */ + U16 Last; /* Index of last character */ +} GUI_SIF_CHAR_AREA; + +typedef struct { + U16 XSize; /* Size of bitmap data in X */ + U16 XDist; /* Number of pixels for increment cursor in X */ + U16 BytesPerLine; /* Number of bytes per line */ + U16 Dummy; + U32 OffData; /* Offset of pixel data */ +} GUI_SIF_CHARINFO; + +typedef struct { + U16 XSize; /* Size of bitmap data in X */ + U16 YSize; /* Size of bitmap data in X */ + I16 XOff; /* Display offset of bitmap data in X */ + I16 YOff; /* Display offset of bitmap data in Y */ + U16 XDist; /* Number of pixels for increment cursor in X */ + U16 Dummy; + U32 OffData; /* Offset of pixel data */ +} GUI_SIF_CHARINFO_EXT; + +typedef struct tGUI_SIF_APIList_struct { + GUI_DISPCHAR * pfDispChar; + GUI_GETCHARDISTX * pfGetCharDistX; + GUI_GETFONTINFO * pfGetFontInfo; + GUI_ISINFONT * pfIsInFont; + GUI_GETCHARINFO * pfGetCharInfo; + const tGUI_ENC_APIList* pafEncode; +} tGUI_SIF_APIList; + +#define GUI_SIF_TYPE tGUI_SIF_APIList +#define GUI_SIF_TYPE_PROP &GUI_SIF_APIList_Prop +#define GUI_SIF_TYPE_PROP_EXT &GUI_SIF_APIList_Prop_Ext +#define GUI_SIF_TYPE_PROP_FRM &GUI_SIF_APIList_Prop_Frm +#define GUI_SIF_TYPE_PROP_AA2 &GUI_SIF_APIList_Prop_AA2 +#define GUI_SIF_TYPE_PROP_AA4 &GUI_SIF_APIList_Prop_AA4 +#define GUI_SIF_TYPE_PROP_AA2_EXT &GUI_SIF_APIList_Prop_AA2_EXT +#define GUI_SIF_TYPE_PROP_AA4_EXT &GUI_SIF_APIList_Prop_AA4_EXT + +/********************************************************************* +* +* External binary font structures (XBF) +*/ +typedef int GUI_XBF_GET_DATA_FUNC(U32 Off, U16 NumBytes, void * pVoid, void * pBuffer); + +typedef struct { + U16 First; /* First character of font */ + U16 Last; /* Last character of font */ + void * pVoid; /* Void pointer passed to GetData-function */ + GUI_XBF_GET_DATA_FUNC * pfGetData; /* Pointer to callback function */ +} GUI_XBF_DATA; + +typedef struct tGUI_XBF_APIList_struct { + GUI_DISPCHAR * pfDispChar; + GUI_GETCHARDISTX * pfGetCharDistX; + GUI_GETFONTINFO * pfGetFontInfo; + GUI_ISINFONT * pfIsInFont; + GUI_GETCHARINFO * pfGetCharInfo; + const tGUI_ENC_APIList* pafEncode; +} tGUI_XBF_APIList; + +#define GUI_XBF_TYPE tGUI_XBF_APIList +#define GUI_XBF_TYPE_PROP &GUI_XBF_APIList_Prop +#define GUI_XBF_TYPE_PROP_EXT &GUI_XBF_APIList_Prop_Ext +#define GUI_XBF_TYPE_PROP_FRM &GUI_XBF_APIList_Prop_Frm +#define GUI_XBF_TYPE_PROP_AA2_EXT &GUI_XBF_APIList_Prop_AA2_Ext +#define GUI_XBF_TYPE_PROP_AA4_EXT &GUI_XBF_APIList_Prop_AA4_Ext + +/********************************************************************* +* +* TrueType support (TTF) +*/ +typedef struct { + const void * pData; /* Pointer to TTF font file in addressable memory area */ + U32 NumBytes; /* Size of file in bytes */ +} GUI_TTF_DATA; + +typedef struct { + GUI_TTF_DATA * pTTF; /* Pointer to GUI_TTF_DATA structure which contains location and size of font file */ + U32 aImageTypeBuffer[4]; /* Buffer for image type structure */ + int PixelHeight; /* Pixel height of new font. It means the height of the surrounding rectangle + * between the glyphs 'g' anf 'f'. Please notice that it is not the distance + * between two lines of text. With other words the value returned byGUI_GetFontSizeY() + * is not identically with this value. */ + int FaceIndex; /* Some font files can contain more than one font face. In case of more than one face + * this index specifies the zero based face index to be used to create the font. + * Usually 0. */ +} GUI_TTF_CS; + +/********************************************************************* +* +* Task synchronization +*/ +typedef void (* GUI_SIGNAL_EVENT_FUNC) (void); +typedef void (* GUI_WAIT_EVENT_FUNC) (void); +typedef void (* GUI_WAIT_EVENT_TIMED_FUNC)(int Period); + +/********************************************************************* +* +* Memory management +*/ +#ifndef GUI_HMEM + #define GUI_HMEM I32 +#endif +#define GUI_HMEM_NULL (0) +typedef GUI_HMEM GUI_HWIN; +typedef GUI_HMEM GUI_HSPRITE; + +/********************************************************************* +* +* Multi touch input +*/ +#ifndef GUI_MTOUCH_MAX_NUM_POINTS + #define GUI_MTOUCH_MAX_NUM_POINTS 10 +#endif + +typedef struct { + I32 x; + I32 y; + U32 Id; + U16 Flags; +} GUI_MTOUCH_INPUT; + +typedef struct { + int LayerIndex; + unsigned NumPoints; + GUI_TIMER_TIME TimeStamp; + GUI_HMEM hInput; +} GUI_MTOUCH_EVENT; + +// +// Used for emWinSPY with reduced data types and array sizes +// +typedef struct { + U8 Layer; + U8 NumPoints; + I16 ax[5]; + I16 ay[5]; + U16 aId[5]; + U8 aFlags[5]; +} GUI_MTOUCH_STATE; + +typedef void (* T_GUI_MTOUCH_STOREEVENT)(GUI_MTOUCH_EVENT *, GUI_MTOUCH_INPUT * pInput); + +/********************************************************************* +* +* Hardware routines +*/ +typedef struct { + // + // 8 Bit access + // + void (* pfWrite8_A0) (U8 Data); + void (* pfWrite8_A1) (U8 Data); + void (* pfWriteM8_A0) (U8 * pData, int NumItems); + void (* pfWriteM8_A1) (U8 * pData, int NumItems); + U8 (* pfRead8_A0) (void); + U8 (* pfRead8_A1) (void); + void (* pfReadM8_A0) (U8 * pData, int NumItems); + void (* pfReadM8_A1) (U8 * pData, int NumItems); + // + // 16 Bit access + // + void (* pfWrite16_A0) (U16 Data); + void (* pfWrite16_A1) (U16 Data); + void (* pfWriteM16_A0)(U16 * pData, int NumItems); + void (* pfWriteM16_A1)(U16 * pData, int NumItems); + U16 (* pfRead16_A0) (void); + U16 (* pfRead16_A1) (void); + void (* pfReadM16_A0) (U16 * pData, int NumItems); + void (* pfReadM16_A1) (U16 * pData, int NumItems); + // + // 32 Bit access + // + void (* pfWrite32_A0) (U32 Data); + void (* pfWrite32_A1) (U32 Data); + void (* pfWriteM32_A0)(U32 * pData, int NumItems); + void (* pfWriteM32_A1)(U32 * pData, int NumItems); + U32 (* pfRead32_A0) (void); + U32 (* pfRead32_A1) (void); + void (* pfReadM32_A0) (U32 * pData, int NumItems); + void (* pfReadM32_A1) (U32 * pData, int NumItems); + // + // SPI access + // + void (* pfSetCS) (U8 NotActive); + // + // Common routines + // + void (* pfFlushBuffer)(void); +} GUI_PORT_API; + +/********************************************************************* +* +* Send/Receive function for VNC and/or emWinSPY +*/ +typedef int (* GUI_tSend) (const U8 * pData, int len, void * p); +typedef int (* GUI_tRecv) ( U8 * pData, int len, void * p); + +/********************************************************************* +* +* Memory allocation replacement for emWinSPY +*/ +typedef void * (* GUI_tMalloc)(unsigned int); +typedef void (* GUI_tFree) (void *); + +#endif /* GUITYPE_H_INCLUDED */ + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/GUI_VNC.h b/example/GUI/STemWin/inc/GUI_VNC.h new file mode 100755 index 0000000000..64bfb07655 --- /dev/null +++ b/example/GUI/STemWin/inc/GUI_VNC.h @@ -0,0 +1,223 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GUI_VNC.h +Purpose : Publics for the VNC server +---------------------------END-OF-HEADER------------------------------ + +Attention : Do not modify this file ! If you do, you will not + be able do update to a later GUI version ! + +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef GUI_VNC_H +#define GUI_VNC_H + +#include "GUI_Private.h" +#include "GUI_Type.h" +#include "IP_FS.h" + +#if defined(__cplusplus) +extern "C" { /* Make sure we have C-declarations in C++ programs */ +#endif + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ +#define GUI_VNC_NO_ERROR 0 +#define GUI_VNC_ERROR_MISC 1 +#define GUI_VNC_ERROR_WRONGFORMAT 2 + +#define GUI_DES_ENCRYPT 0 +#define GUI_DES_DECRYPT 1 + +// +// File transfer +// +#define GUI_VNC_SUPPORT_FILETRANSFER 0x10 + +// +// Extension message (used for file transfer) +// +#define RFB_EXTENSION 0xFCul + +// +// File transfer protocol +// +#define RFBX_FILE_LIST_REQUEST (0x000102ul | (RFB_EXTENSION << 24)) +#define RFBX_FILE_LIST_REPLY (0x000103ul | (RFB_EXTENSION << 24)) +#define RFBX_UPLOAD_START_REQUEST (0x000106ul | (RFB_EXTENSION << 24)) +#define RFBX_UPLOAD_START_REPLY (0x000107ul | (RFB_EXTENSION << 24)) +#define RFBX_UPLOAD_DATA_REQUEST (0x000108ul | (RFB_EXTENSION << 24)) +#define RFBX_UPLOAD_DATA_REPLY (0x000109ul | (RFB_EXTENSION << 24)) +#define RFBX_UPLOAD_END_REQUEST (0x00010Aul | (RFB_EXTENSION << 24)) +#define RFBX_UPLOAD_END_REPLY (0x00010Bul | (RFB_EXTENSION << 24)) + +#define RFBX_DOWNLOAD_START_REQUEST (0x00010Cul | (RFB_EXTENSION << 24)) +#define RFBX_DOWNLOAD_START_REPLY (0x00010Dul | (RFB_EXTENSION << 24)) +#define RFBX_DOWNLOAD_DATA_REQUEST (0x00010Eul | (RFB_EXTENSION << 24)) +#define RFBX_DOWNLOAD_DATA_REPLY (0x00010Ful | (RFB_EXTENSION << 24)) +#define RFBX_DOWNLOAD_END_REPLY (0x000110ul | (RFB_EXTENSION << 24)) +#define RFBX_MKDIR_REQUEST (0x000111ul | (RFB_EXTENSION << 24)) +#define RFBX_MKDIR_REPLY (0x000112ul | (RFB_EXTENSION << 24)) +#define RFBX_REMOVE_REQUEST (0x000113ul | (RFB_EXTENSION << 24)) +#define RFBX_REMOVE_REPLY (0x000114ul | (RFB_EXTENSION << 24)) +#define RFBX_RENAME_REQUEST (0x000115ul | (RFB_EXTENSION << 24)) +#define RFBX_RENAME_REPLY (0x000116ul | (RFB_EXTENSION << 24)) + + /********************************************************************* +* +* Types +* +********************************************************************** +*/ +typedef struct { + U8 * pBuffer; + int BufferSize; + int NumBytesInBuffer; +} BUFFER_CB; + +typedef struct GUI_VNC_CONTEXT { + GUI_DEVICE * pDevice; + struct GUI_VNC_CONTEXT * pNext; + int LayerIndex; + int BytesPerPixel; + int BitsPerPixel; // Note, that from within the VNC server the function LCD_GetBitsBerPixel() can not be used because the VNC server runs in a separate thread and the device chain can change during the function call + // + // Connection related data + // + GUI_tSend pfSend; + GUI_tRecv pfReceive; + void * pConnectInfo; + U16 ServerIndex; + // + // Display related info + // + int x0Dirty, y0Dirty, x1Dirty, y1Dirty; + int xSize, ySize; + int xOrg, yOrg, xOrgNew, yOrgNew; + // + // Status + // + char ClientSupportsHextile; + char IsBigEndian; + char OrgLock; + char BkFlag; + // + // Pointer to buffer + // + U8 * pBuffer; + unsigned SizeOfBuffer; + int (* pfStoreU8) (struct GUI_VNC_CONTEXT * pContext, BUFFER_CB * pBCB, U8 Data); + int (* pfStoreU16) (struct GUI_VNC_CONTEXT * pContext, BUFFER_CB * pBCB, U16 Data); + int (* pfStoreU32) (struct GUI_VNC_CONTEXT * pContext, BUFFER_CB * pBCB, U32 Data); + int (* pfStoreData)(struct GUI_VNC_CONTEXT * pContext, BUFFER_CB * pBCB, const U8 * pData, int NumBytes); + int (* pfFlush) (struct GUI_VNC_CONTEXT * pContext, BUFFER_CB * pBCB); + int (* pfRead) (struct GUI_VNC_CONTEXT * pContext, U8 * pBuffer, int Len); +} GUI_VNC_CONTEXT; + +typedef struct { + void (* pfGetChallenge)(U8 * pChallenge); + void (* pfGetResponse )(U8 * pResponse ); +} GUI_VNC_AUTHENTICATION; + +/********************************************************************* +* +* Private Functions +* +********************************************************************** +*/ +void GUI_VNC_SetDESKey(U8 * pKey, int Mode); +void GUI_VNC_DoDES (U8 * pInblock, U8 * pOutblock); + +/********************************************************************* +* +* Public Functions +* +********************************************************************** +*/ +void GUI_VNC_AttachToLayer (GUI_VNC_CONTEXT * pContext, int LayerIndex); +void GUI_VNC_EnableKeyboardInput(int OnOff); +void GUI_VNC_EnableMouseInput (int OnOff); +void GUI_VNC_EnableFileTransfer (unsigned OnOff); +int GUI_VNC_GetNumConnections (void); +int GUI_VNC_Process (GUI_VNC_CONTEXT * pContext, GUI_tSend pfSend, GUI_tRecv pfReceive, void * pConnectInfo); +void GUI_VNC_RingBell (void); +void GUI_VNC_SetAuthentication (GUI_VNC_AUTHENTICATION * pAuthentication); +void GUI_VNC_SetPassword (U8 * sPassword); +void GUI_VNC_SetProgName (const char * sProgName); +void GUI_VNC_SetSize (unsigned xSize, unsigned ySize); +void GUI_VNC_SetLockFrame (unsigned OnOff); +void GUI_VNC_SetRetryCount (unsigned Cnt); +void GUI_VNC_SetFS_API (const IP_FS_API * pFS_API); + +// +// Private function for setting file transfer handler +// +void GUI_VNC__SetRFBExtensionHandler(int (* pFunc)(U32, GUI_VNC_CONTEXT *, BUFFER_CB *)); + +// +// External routine to link the server to the system ... USER defined ! +// +int GUI_VNC_X_StartServer (int LayerIndex, int ServerIndex); +int GUI_VNC_X_StartServerFT(int LayerIndex, int ServerIndex); +void GUI_VNC_X_getpeername (U32 * Addr); + +#if defined(__cplusplus) + } +#endif + +#endif /* Avoid multiple inclusion */ + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/GUI_Version.h b/example/GUI/STemWin/inc/GUI_Version.h new file mode 100755 index 0000000000..ef784d8c13 --- /dev/null +++ b/example/GUI/STemWin/inc/GUI_Version.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GUI_Version.h +Purpose : Include file defining current GUI version +---------------------------END-OF-HEADER------------------------------ +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef GUI_VERSION_H +#define GUI_VERSION_H + +#define GUI_VERSION 54002 + +#endif /* Avoid multiple inclusion */ + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/GUI__BiDi2_Brackets_800.h b/example/GUI/STemWin/inc/GUI__BiDi2_Brackets_800.h new file mode 100755 index 0000000000..e85bec797e --- /dev/null +++ b/example/GUI/STemWin/inc/GUI__BiDi2_Brackets_800.h @@ -0,0 +1,181 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +Licensing information +Licensor: SEGGER Software GmbH +Licensed to: STMicroelectronics International NV, 39, Chemin du Champ-des Filles, 1228 Plan Les Ouates, Geneva, SWITZERLAND +Licensed SEGGER software: emWin +License number: GUI-00429 +License model: Buyout SRC [Buyout Source Code License, signed November 29th 2012] +Licensed product: - +Licensed platform: STMs ARM Cortex-M based 32 BIT CPUs +Licensed number of seats: - +---------------------------------------------------------------------- +Support and Update Agreement (SUA) +SUA period: 2012-12-07 - 2017-12-31 +Contact to extend SUA: sales@segger.com +---------------------------------------------------------------------- +File : GUI__BiDi2_Brackets_800.h +Purpose : Bracket pairs according to Unicode V8.0.0 +---------------------------END-OF-HEADER------------------------------ +*/ + +#ifdef GUI__BIDI2 +// CodePoint +// | Paired bracket +// | | Bracket type +// | | | +// V V V + { 0x0028, 0x0029, BPT_O }, // LEFT PARENTHESIS + { 0x0029, 0x0028, BPT_C }, // RIGHT PARENTHESIS + { 0x005B, 0x005D, BPT_O }, // LEFT SQUARE BRACKET + { 0x005D, 0x005B, BPT_C }, // RIGHT SQUARE BRACKET + { 0x007B, 0x007D, BPT_O }, // LEFT CURLY BRACKET + { 0x007D, 0x007B, BPT_C }, // RIGHT CURLY BRACKET + { 0x0F3A, 0x0F3B, BPT_O }, // TIBETAN MARK GUG RTAGS GYON + { 0x0F3B, 0x0F3A, BPT_C }, // TIBETAN MARK GUG RTAGS GYAS + { 0x0F3C, 0x0F3D, BPT_O }, // TIBETAN MARK ANG KHANG GYON + { 0x0F3D, 0x0F3C, BPT_C }, // TIBETAN MARK ANG KHANG GYAS + { 0x169B, 0x169C, BPT_O }, // OGHAM FEATHER MARK + { 0x169C, 0x169B, BPT_C }, // OGHAM REVERSED FEATHER MARK + { 0x2045, 0x2046, BPT_O }, // LEFT SQUARE BRACKET WITH QUILL + { 0x2046, 0x2045, BPT_C }, // RIGHT SQUARE BRACKET WITH QUILL + { 0x207D, 0x207E, BPT_O }, // SUPERSCRIPT LEFT PARENTHESIS + { 0x207E, 0x207D, BPT_C }, // SUPERSCRIPT RIGHT PARENTHESIS + { 0x208D, 0x208E, BPT_O }, // SUBSCRIPT LEFT PARENTHESIS + { 0x208E, 0x208D, BPT_C }, // SUBSCRIPT RIGHT PARENTHESIS + { 0x2308, 0x2309, BPT_O }, // LEFT CEILING + { 0x2309, 0x2308, BPT_C }, // RIGHT CEILING + { 0x230A, 0x230B, BPT_O }, // LEFT FLOOR + { 0x230B, 0x230A, BPT_C }, // RIGHT FLOOR + { 0x2329, 0x232A, BPT_O }, // LEFT-POINTING ANGLE BRACKET + { 0x232A, 0x2329, BPT_C }, // RIGHT-POINTING ANGLE BRACKET + { 0x2768, 0x2769, BPT_O }, // MEDIUM LEFT PARENTHESIS ORNAMENT + { 0x2769, 0x2768, BPT_C }, // MEDIUM RIGHT PARENTHESIS ORNAMENT + { 0x276A, 0x276B, BPT_O }, // MEDIUM FLATTENED LEFT PARENTHESIS ORNAMENT + { 0x276B, 0x276A, BPT_C }, // MEDIUM FLATTENED RIGHT PARENTHESIS ORNAMENT + { 0x276C, 0x276D, BPT_O }, // MEDIUM LEFT-POINTING ANGLE BRACKET ORNAMENT + { 0x276D, 0x276C, BPT_C }, // MEDIUM RIGHT-POINTING ANGLE BRACKET ORNAMENT + { 0x276E, 0x276F, BPT_O }, // HEAVY LEFT-POINTING ANGLE QUOTATION MARK ORNAMENT + { 0x276F, 0x276E, BPT_C }, // HEAVY RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT + { 0x2770, 0x2771, BPT_O }, // HEAVY LEFT-POINTING ANGLE BRACKET ORNAMENT + { 0x2771, 0x2770, BPT_C }, // HEAVY RIGHT-POINTING ANGLE BRACKET ORNAMENT + { 0x2772, 0x2773, BPT_O }, // LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT + { 0x2773, 0x2772, BPT_C }, // LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT + { 0x2774, 0x2775, BPT_O }, // MEDIUM LEFT CURLY BRACKET ORNAMENT + { 0x2775, 0x2774, BPT_C }, // MEDIUM RIGHT CURLY BRACKET ORNAMENT + { 0x27C5, 0x27C6, BPT_O }, // LEFT S-SHAPED BAG DELIMITER + { 0x27C6, 0x27C5, BPT_C }, // RIGHT S-SHAPED BAG DELIMITER + { 0x27E6, 0x27E7, BPT_O }, // MATHEMATICAL LEFT WHITE SQUARE BRACKET + { 0x27E7, 0x27E6, BPT_C }, // MATHEMATICAL RIGHT WHITE SQUARE BRACKET + { 0x27E8, 0x27E9, BPT_O }, // MATHEMATICAL LEFT ANGLE BRACKET + { 0x27E9, 0x27E8, BPT_C }, // MATHEMATICAL RIGHT ANGLE BRACKET + { 0x27EA, 0x27EB, BPT_O }, // MATHEMATICAL LEFT DOUBLE ANGLE BRACKET + { 0x27EB, 0x27EA, BPT_C }, // MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET + { 0x27EC, 0x27ED, BPT_O }, // MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET + { 0x27ED, 0x27EC, BPT_C }, // MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET + { 0x27EE, 0x27EF, BPT_O }, // MATHEMATICAL LEFT FLATTENED PARENTHESIS + { 0x27EF, 0x27EE, BPT_C }, // MATHEMATICAL RIGHT FLATTENED PARENTHESIS + { 0x2983, 0x2984, BPT_O }, // LEFT WHITE CURLY BRACKET + { 0x2984, 0x2983, BPT_C }, // RIGHT WHITE CURLY BRACKET + { 0x2985, 0x2986, BPT_O }, // LEFT WHITE PARENTHESIS + { 0x2986, 0x2985, BPT_C }, // RIGHT WHITE PARENTHESIS + { 0x2987, 0x2988, BPT_O }, // Z NOTATION LEFT IMAGE BRACKET + { 0x2988, 0x2987, BPT_C }, // Z NOTATION RIGHT IMAGE BRACKET + { 0x2989, 0x298A, BPT_O }, // Z NOTATION LEFT BINDING BRACKET + { 0x298A, 0x2989, BPT_C }, // Z NOTATION RIGHT BINDING BRACKET + { 0x298B, 0x298C, BPT_O }, // LEFT SQUARE BRACKET WITH UNDERBAR + { 0x298C, 0x298B, BPT_C }, // RIGHT SQUARE BRACKET WITH UNDERBAR + { 0x298D, 0x2990, BPT_O }, // LEFT SQUARE BRACKET WITH TICK IN TOP CORNER + { 0x298E, 0x298F, BPT_C }, // RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER + { 0x298F, 0x298E, BPT_O }, // LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER + { 0x2990, 0x298D, BPT_C }, // RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER + { 0x2991, 0x2992, BPT_O }, // LEFT ANGLE BRACKET WITH DOT + { 0x2992, 0x2991, BPT_C }, // RIGHT ANGLE BRACKET WITH DOT + { 0x2993, 0x2994, BPT_O }, // LEFT ARC LESS-THAN BRACKET + { 0x2994, 0x2993, BPT_C }, // RIGHT ARC GREATER-THAN BRACKET + { 0x2995, 0x2996, BPT_O }, // DOUBLE LEFT ARC GREATER-THAN BRACKET + { 0x2996, 0x2995, BPT_C }, // DOUBLE RIGHT ARC LESS-THAN BRACKET + { 0x2997, 0x2998, BPT_O }, // LEFT BLACK TORTOISE SHELL BRACKET + { 0x2998, 0x2997, BPT_C }, // RIGHT BLACK TORTOISE SHELL BRACKET + { 0x29D8, 0x29D9, BPT_O }, // LEFT WIGGLY FENCE + { 0x29D9, 0x29D8, BPT_C }, // RIGHT WIGGLY FENCE + { 0x29DA, 0x29DB, BPT_O }, // LEFT DOUBLE WIGGLY FENCE + { 0x29DB, 0x29DA, BPT_C }, // RIGHT DOUBLE WIGGLY FENCE + { 0x29FC, 0x29FD, BPT_O }, // LEFT-POINTING CURVED ANGLE BRACKET + { 0x29FD, 0x29FC, BPT_C }, // RIGHT-POINTING CURVED ANGLE BRACKET + { 0x2E22, 0x2E23, BPT_O }, // TOP LEFT HALF BRACKET + { 0x2E23, 0x2E22, BPT_C }, // TOP RIGHT HALF BRACKET + { 0x2E24, 0x2E25, BPT_O }, // BOTTOM LEFT HALF BRACKET + { 0x2E25, 0x2E24, BPT_C }, // BOTTOM RIGHT HALF BRACKET + { 0x2E26, 0x2E27, BPT_O }, // LEFT SIDEWAYS U BRACKET + { 0x2E27, 0x2E26, BPT_C }, // RIGHT SIDEWAYS U BRACKET + { 0x2E28, 0x2E29, BPT_O }, // LEFT DOUBLE PARENTHESIS + { 0x2E29, 0x2E28, BPT_C }, // RIGHT DOUBLE PARENTHESIS + { 0x3008, 0x3009, BPT_O }, // LEFT ANGLE BRACKET + { 0x3009, 0x3008, BPT_C }, // RIGHT ANGLE BRACKET + { 0x300A, 0x300B, BPT_O }, // LEFT DOUBLE ANGLE BRACKET + { 0x300B, 0x300A, BPT_C }, // RIGHT DOUBLE ANGLE BRACKET + { 0x300C, 0x300D, BPT_O }, // LEFT CORNER BRACKET + { 0x300D, 0x300C, BPT_C }, // RIGHT CORNER BRACKET + { 0x300E, 0x300F, BPT_O }, // LEFT WHITE CORNER BRACKET + { 0x300F, 0x300E, BPT_C }, // RIGHT WHITE CORNER BRACKET + { 0x3010, 0x3011, BPT_O }, // LEFT BLACK LENTICULAR BRACKET + { 0x3011, 0x3010, BPT_C }, // RIGHT BLACK LENTICULAR BRACKET + { 0x3014, 0x3015, BPT_O }, // LEFT TORTOISE SHELL BRACKET + { 0x3015, 0x3014, BPT_C }, // RIGHT TORTOISE SHELL BRACKET + { 0x3016, 0x3017, BPT_O }, // LEFT WHITE LENTICULAR BRACKET + { 0x3017, 0x3016, BPT_C }, // RIGHT WHITE LENTICULAR BRACKET + { 0x3018, 0x3019, BPT_O }, // LEFT WHITE TORTOISE SHELL BRACKET + { 0x3019, 0x3018, BPT_C }, // RIGHT WHITE TORTOISE SHELL BRACKET + { 0x301A, 0x301B, BPT_O }, // LEFT WHITE SQUARE BRACKET + { 0x301B, 0x301A, BPT_C }, // RIGHT WHITE SQUARE BRACKET + { 0xFE59, 0xFE5A, BPT_O }, // SMALL LEFT PARENTHESIS + { 0xFE5A, 0xFE59, BPT_C }, // SMALL RIGHT PARENTHESIS + { 0xFE5B, 0xFE5C, BPT_O }, // SMALL LEFT CURLY BRACKET + { 0xFE5C, 0xFE5B, BPT_C }, // SMALL RIGHT CURLY BRACKET + { 0xFE5D, 0xFE5E, BPT_O }, // SMALL LEFT TORTOISE SHELL BRACKET + { 0xFE5E, 0xFE5D, BPT_C }, // SMALL RIGHT TORTOISE SHELL BRACKET + { 0xFF08, 0xFF09, BPT_O }, // FULLWIDTH LEFT PARENTHESIS + { 0xFF09, 0xFF08, BPT_C }, // FULLWIDTH RIGHT PARENTHESIS + { 0xFF3B, 0xFF3D, BPT_O }, // FULLWIDTH LEFT SQUARE BRACKET + { 0xFF3D, 0xFF3B, BPT_C }, // FULLWIDTH RIGHT SQUARE BRACKET + { 0xFF5B, 0xFF5D, BPT_O }, // FULLWIDTH LEFT CURLY BRACKET + { 0xFF5D, 0xFF5B, BPT_C }, // FULLWIDTH RIGHT CURLY BRACKET + { 0xFF5F, 0xFF60, BPT_O }, // FULLWIDTH LEFT WHITE PARENTHESIS + { 0xFF60, 0xFF5F, BPT_C }, // FULLWIDTH RIGHT WHITE PARENTHESIS + { 0xFF62, 0xFF63, BPT_O }, // HALFWIDTH LEFT CORNER BRACKET + { 0xFF63, 0xFF62, BPT_C }, // HALFWIDTH RIGHT CORNER BRACKET +#endif + +/*************************** End of file ****************************/ + diff --git a/example/GUI/STemWin/inc/GUI__BiDi2_Types_800.h b/example/GUI/STemWin/inc/GUI__BiDi2_Types_800.h new file mode 100755 index 0000000000..dbe176c361 --- /dev/null +++ b/example/GUI/STemWin/inc/GUI__BiDi2_Types_800.h @@ -0,0 +1,16614 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +Licensing information +Licensor: SEGGER Software GmbH +Licensed to: STMicroelectronics International NV, 39, Chemin du Champ-des Filles, 1228 Plan Les Ouates, Geneva, SWITZERLAND +Licensed SEGGER software: emWin +License number: GUI-00429 +License model: Buyout SRC [Buyout Source Code License, signed November 29th 2012] +Licensed product: - +Licensed platform: STMs ARM Cortex-M based 32 BIT CPUs +Licensed number of seats: - +---------------------------------------------------------------------- +Support and Update Agreement (SUA) +SUA period: 2012-12-07 - 2017-12-31 +Contact to extend SUA: sales@segger.com +---------------------------------------------------------------------- +File : GUI__BiDi2_Types_800.h +Purpose : Bidi types according to Unicode V8.0.0 + + ( !!! Basic Multilingual Plane Only !!! ) + +---------------------------END-OF-HEADER------------------------------ +*/ + +#ifdef GUI__BIDI2 + +#ifndef GUI_BIDI_SUPPORT_RANGE_0 + #define GUI_BIDI_SUPPORT_RANGE_0 1 +#endif +#ifndef GUI_BIDI_SUPPORT_RANGE_1 + #define GUI_BIDI_SUPPORT_RANGE_1 1 +#endif +#ifndef GUI_BIDI_SUPPORT_RANGE_2 + #define GUI_BIDI_SUPPORT_RANGE_2 1 +#endif +#ifndef GUI_BIDI_SUPPORT_RANGE_3 + #define GUI_BIDI_SUPPORT_RANGE_3 1 +#endif +#ifndef GUI_BIDI_SUPPORT_RANGE_4 + #define GUI_BIDI_SUPPORT_RANGE_4 1 +#endif +#ifndef GUI_BIDI_SUPPORT_RANGE_A + #define GUI_BIDI_SUPPORT_RANGE_A 1 +#endif +#ifndef GUI_BIDI_SUPPORT_RANGE_D + #define GUI_BIDI_SUPPORT_RANGE_D 1 +#endif +#ifndef GUI_BIDI_SUPPORT_RANGE_F + #define GUI_BIDI_SUPPORT_RANGE_F 1 +#endif + +#if (GUI_BIDI_SUPPORT_RANGE_0 == 1) + +// CodePoint +// | BiDi category +// | | Unicode name +// | | | +// V V V + { 0x0000, BIDI_BN }, // + { 0x0001, BIDI_BN }, // + { 0x0002, BIDI_BN }, // + { 0x0003, BIDI_BN }, // + { 0x0004, BIDI_BN }, // + { 0x0005, BIDI_BN }, // + { 0x0006, BIDI_BN }, // + { 0x0007, BIDI_BN }, // + { 0x0008, BIDI_BN }, // + { 0x0009, BIDI_S }, // + { 0x000A, BIDI_B }, // + { 0x000B, BIDI_S }, // + { 0x000C, BIDI_WS }, // + { 0x000D, BIDI_B }, // + { 0x000E, BIDI_BN }, // + { 0x000F, BIDI_BN }, // + { 0x0010, BIDI_BN }, // + { 0x0011, BIDI_BN }, // + { 0x0012, BIDI_BN }, // + { 0x0013, BIDI_BN }, // + { 0x0014, BIDI_BN }, // + { 0x0015, BIDI_BN }, // + { 0x0016, BIDI_BN }, // + { 0x0017, BIDI_BN }, // + { 0x0018, BIDI_BN }, // + { 0x0019, BIDI_BN }, // + { 0x001A, BIDI_BN }, // + { 0x001B, BIDI_BN }, // + { 0x001C, BIDI_B }, // + { 0x001D, BIDI_B }, // + { 0x001E, BIDI_B }, // + { 0x001F, BIDI_S }, // + { 0x0020, BIDI_WS }, // SPACE + { 0x0021, BIDI_ON }, // EXCLAMATION MARK + { 0x0022, BIDI_ON }, // QUOTATION MARK + { 0x0023, BIDI_ET }, // NUMBER SIGN + { 0x0024, BIDI_ET }, // DOLLAR SIGN + { 0x0025, BIDI_ET }, // PERCENT SIGN + { 0x0026, BIDI_ON }, // AMPERSAND + { 0x0027, BIDI_ON }, // APOSTROPHE + { 0x0028, BIDI_ON }, // LEFT PARENTHESIS + { 0x0029, BIDI_ON }, // RIGHT PARENTHESIS + { 0x002A, BIDI_ON }, // ASTERISK + { 0x002B, BIDI_ES }, // PLUS SIGN + { 0x002C, BIDI_CS }, // COMMA + { 0x002D, BIDI_ES }, // HYPHEN-MINUS + { 0x002E, BIDI_CS }, // FULL STOP + { 0x002F, BIDI_CS }, // SOLIDUS + { 0x0030, BIDI_EN }, // DIGIT ZERO + { 0x0031, BIDI_EN }, // DIGIT ONE + { 0x0032, BIDI_EN }, // DIGIT TWO + { 0x0033, BIDI_EN }, // DIGIT THREE + { 0x0034, BIDI_EN }, // DIGIT FOUR + { 0x0035, BIDI_EN }, // DIGIT FIVE + { 0x0036, BIDI_EN }, // DIGIT SIX + { 0x0037, BIDI_EN }, // DIGIT SEVEN + { 0x0038, BIDI_EN }, // DIGIT EIGHT + { 0x0039, BIDI_EN }, // DIGIT NINE + { 0x003A, BIDI_CS }, // COLON + { 0x003B, BIDI_ON }, // SEMICOLON + { 0x003C, BIDI_ON }, // LESS-THAN SIGN + { 0x003D, BIDI_ON }, // EQUALS SIGN + { 0x003E, BIDI_ON }, // GREATER-THAN SIGN + { 0x003F, BIDI_ON }, // QUESTION MARK + { 0x0040, BIDI_ON }, // COMMERCIAL AT + { 0x0041, BIDI_L }, // LATIN CAPITAL LETTER A + { 0x0042, BIDI_L }, // LATIN CAPITAL LETTER B + { 0x0043, BIDI_L }, // LATIN CAPITAL LETTER C + { 0x0044, BIDI_L }, // LATIN CAPITAL LETTER D + { 0x0045, BIDI_L }, // LATIN CAPITAL LETTER E + { 0x0046, BIDI_L }, // LATIN CAPITAL LETTER F + { 0x0047, BIDI_L }, // LATIN CAPITAL LETTER G + { 0x0048, BIDI_L }, // LATIN CAPITAL LETTER H + { 0x0049, BIDI_L }, // LATIN CAPITAL LETTER I + { 0x004A, BIDI_L }, // LATIN CAPITAL LETTER J + { 0x004B, BIDI_L }, // LATIN CAPITAL LETTER K + { 0x004C, BIDI_L }, // LATIN CAPITAL LETTER L + { 0x004D, BIDI_L }, // LATIN CAPITAL LETTER M + { 0x004E, BIDI_L }, // LATIN CAPITAL LETTER N + { 0x004F, BIDI_L }, // LATIN CAPITAL LETTER O + { 0x0050, BIDI_L }, // LATIN CAPITAL LETTER P + { 0x0051, BIDI_L }, // LATIN CAPITAL LETTER Q + { 0x0052, BIDI_L }, // LATIN CAPITAL LETTER R + { 0x0053, BIDI_L }, // LATIN CAPITAL LETTER S + { 0x0054, BIDI_L }, // LATIN CAPITAL LETTER T + { 0x0055, BIDI_L }, // LATIN CAPITAL LETTER U + { 0x0056, BIDI_L }, // LATIN CAPITAL LETTER V + { 0x0057, BIDI_L }, // LATIN CAPITAL LETTER W + { 0x0058, BIDI_L }, // LATIN CAPITAL LETTER X + { 0x0059, BIDI_L }, // LATIN CAPITAL LETTER Y + { 0x005A, BIDI_L }, // LATIN CAPITAL LETTER Z + { 0x005B, BIDI_ON }, // LEFT SQUARE BRACKET + { 0x005C, BIDI_ON }, // REVERSE SOLIDUS + { 0x005D, BIDI_ON }, // RIGHT SQUARE BRACKET + { 0x005E, BIDI_ON }, // CIRCUMFLEX ACCENT + { 0x005F, BIDI_ON }, // LOW LINE + { 0x0060, BIDI_ON }, // GRAVE ACCENT + { 0x0061, BIDI_L }, // LATIN SMALL LETTER A + { 0x0062, BIDI_L }, // LATIN SMALL LETTER B + { 0x0063, BIDI_L }, // LATIN SMALL LETTER C + { 0x0064, BIDI_L }, // LATIN SMALL LETTER D + { 0x0065, BIDI_L }, // LATIN SMALL LETTER E + { 0x0066, BIDI_L }, // LATIN SMALL LETTER F + { 0x0067, BIDI_L }, // LATIN SMALL LETTER G + { 0x0068, BIDI_L }, // LATIN SMALL LETTER H + { 0x0069, BIDI_L }, // LATIN SMALL LETTER I + { 0x006A, BIDI_L }, // LATIN SMALL LETTER J + { 0x006B, BIDI_L }, // LATIN SMALL LETTER K + { 0x006C, BIDI_L }, // LATIN SMALL LETTER L + { 0x006D, BIDI_L }, // LATIN SMALL LETTER M + { 0x006E, BIDI_L }, // LATIN SMALL LETTER N + { 0x006F, BIDI_L }, // LATIN SMALL LETTER O + { 0x0070, BIDI_L }, // LATIN SMALL LETTER P + { 0x0071, BIDI_L }, // LATIN SMALL LETTER Q + { 0x0072, BIDI_L }, // LATIN SMALL LETTER R + { 0x0073, BIDI_L }, // LATIN SMALL LETTER S + { 0x0074, BIDI_L }, // LATIN SMALL LETTER T + { 0x0075, BIDI_L }, // LATIN SMALL LETTER U + { 0x0076, BIDI_L }, // LATIN SMALL LETTER V + { 0x0077, BIDI_L }, // LATIN SMALL LETTER W + { 0x0078, BIDI_L }, // LATIN SMALL LETTER X + { 0x0079, BIDI_L }, // LATIN SMALL LETTER Y + { 0x007A, BIDI_L }, // LATIN SMALL LETTER Z + { 0x007B, BIDI_ON }, // LEFT CURLY BRACKET + { 0x007C, BIDI_ON }, // VERTICAL LINE + { 0x007D, BIDI_ON }, // RIGHT CURLY BRACKET + { 0x007E, BIDI_ON }, // TILDE + { 0x007F, BIDI_BN }, // + { 0x0080, BIDI_BN }, // + { 0x0081, BIDI_BN }, // + { 0x0082, BIDI_BN }, // + { 0x0083, BIDI_BN }, // + { 0x0084, BIDI_BN }, // + { 0x0085, BIDI_B }, // + { 0x0086, BIDI_BN }, // + { 0x0087, BIDI_BN }, // + { 0x0088, BIDI_BN }, // + { 0x0089, BIDI_BN }, // + { 0x008A, BIDI_BN }, // + { 0x008B, BIDI_BN }, // + { 0x008C, BIDI_BN }, // + { 0x008D, BIDI_BN }, // + { 0x008E, BIDI_BN }, // + { 0x008F, BIDI_BN }, // + { 0x0090, BIDI_BN }, // + { 0x0091, BIDI_BN }, // + { 0x0092, BIDI_BN }, // + { 0x0093, BIDI_BN }, // + { 0x0094, BIDI_BN }, // + { 0x0095, BIDI_BN }, // + { 0x0096, BIDI_BN }, // + { 0x0097, BIDI_BN }, // + { 0x0098, BIDI_BN }, // + { 0x0099, BIDI_BN }, // + { 0x009A, BIDI_BN }, // + { 0x009B, BIDI_BN }, // + { 0x009C, BIDI_BN }, // + { 0x009D, BIDI_BN }, // + { 0x009E, BIDI_BN }, // + { 0x009F, BIDI_BN }, // + { 0x00A0, BIDI_CS }, // NO-BREAK SPACE + { 0x00A1, BIDI_ON }, // INVERTED EXCLAMATION MARK + { 0x00A2, BIDI_ET }, // CENT SIGN + { 0x00A3, BIDI_ET }, // POUND SIGN + { 0x00A4, BIDI_ET }, // CURRENCY SIGN + { 0x00A5, BIDI_ET }, // YEN SIGN + { 0x00A6, BIDI_ON }, // BROKEN BAR + { 0x00A7, BIDI_ON }, // SECTION SIGN + { 0x00A8, BIDI_ON }, // DIAERESIS + { 0x00A9, BIDI_ON }, // COPYRIGHT SIGN + { 0x00AA, BIDI_L }, // FEMININE ORDINAL INDICATOR + { 0x00AB, BIDI_ON }, // LEFT-POINTING DOUBLE ANGLE QUOTATION MARK + { 0x00AC, BIDI_ON }, // NOT SIGN + { 0x00AD, BIDI_BN }, // SOFT HYPHEN + { 0x00AE, BIDI_ON }, // REGISTERED SIGN + { 0x00AF, BIDI_ON }, // MACRON + { 0x00B0, BIDI_ET }, // DEGREE SIGN + { 0x00B1, BIDI_ET }, // PLUS-MINUS SIGN + { 0x00B2, BIDI_EN }, // SUPERSCRIPT TWO + { 0x00B3, BIDI_EN }, // SUPERSCRIPT THREE + { 0x00B4, BIDI_ON }, // ACUTE ACCENT + { 0x00B5, BIDI_L }, // MICRO SIGN + { 0x00B6, BIDI_ON }, // PILCROW SIGN + { 0x00B7, BIDI_ON }, // MIDDLE DOT + { 0x00B8, BIDI_ON }, // CEDILLA + { 0x00B9, BIDI_EN }, // SUPERSCRIPT ONE + { 0x00BA, BIDI_L }, // MASCULINE ORDINAL INDICATOR + { 0x00BB, BIDI_ON }, // RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK + { 0x00BC, BIDI_ON }, // VULGAR FRACTION ONE QUARTER + { 0x00BD, BIDI_ON }, // VULGAR FRACTION ONE HALF + { 0x00BE, BIDI_ON }, // VULGAR FRACTION THREE QUARTERS + { 0x00BF, BIDI_ON }, // INVERTED QUESTION MARK + { 0x00C0, BIDI_L }, // LATIN CAPITAL LETTER A WITH GRAVE + { 0x00C1, BIDI_L }, // LATIN CAPITAL LETTER A WITH ACUTE + { 0x00C2, BIDI_L }, // LATIN CAPITAL LETTER A WITH CIRCUMFLEX + { 0x00C3, BIDI_L }, // LATIN CAPITAL LETTER A WITH TILDE + { 0x00C4, BIDI_L }, // LATIN CAPITAL LETTER A WITH DIAERESIS + { 0x00C5, BIDI_L }, // LATIN CAPITAL LETTER A WITH RING ABOVE + { 0x00C6, BIDI_L }, // LATIN CAPITAL LETTER AE + { 0x00C7, BIDI_L }, // LATIN CAPITAL LETTER C WITH CEDILLA + { 0x00C8, BIDI_L }, // LATIN CAPITAL LETTER E WITH GRAVE + { 0x00C9, BIDI_L }, // LATIN CAPITAL LETTER E WITH ACUTE + { 0x00CA, BIDI_L }, // LATIN CAPITAL LETTER E WITH CIRCUMFLEX + { 0x00CB, BIDI_L }, // LATIN CAPITAL LETTER E WITH DIAERESIS + { 0x00CC, BIDI_L }, // LATIN CAPITAL LETTER I WITH GRAVE + { 0x00CD, BIDI_L }, // LATIN CAPITAL LETTER I WITH ACUTE + { 0x00CE, BIDI_L }, // LATIN CAPITAL LETTER I WITH CIRCUMFLEX + { 0x00CF, BIDI_L }, // LATIN CAPITAL LETTER I WITH DIAERESIS + { 0x00D0, BIDI_L }, // LATIN CAPITAL LETTER ETH + { 0x00D1, BIDI_L }, // LATIN CAPITAL LETTER N WITH TILDE + { 0x00D2, BIDI_L }, // LATIN CAPITAL LETTER O WITH GRAVE + { 0x00D3, BIDI_L }, // LATIN CAPITAL LETTER O WITH ACUTE + { 0x00D4, BIDI_L }, // LATIN CAPITAL LETTER O WITH CIRCUMFLEX + { 0x00D5, BIDI_L }, // LATIN CAPITAL LETTER O WITH TILDE + { 0x00D6, BIDI_L }, // LATIN CAPITAL LETTER O WITH DIAERESIS + { 0x00D7, BIDI_ON }, // MULTIPLICATION SIGN + { 0x00D8, BIDI_L }, // LATIN CAPITAL LETTER O WITH STROKE + { 0x00D9, BIDI_L }, // LATIN CAPITAL LETTER U WITH GRAVE + { 0x00DA, BIDI_L }, // LATIN CAPITAL LETTER U WITH ACUTE + { 0x00DB, BIDI_L }, // LATIN CAPITAL LETTER U WITH CIRCUMFLEX + { 0x00DC, BIDI_L }, // LATIN CAPITAL LETTER U WITH DIAERESIS + { 0x00DD, BIDI_L }, // LATIN CAPITAL LETTER Y WITH ACUTE + { 0x00DE, BIDI_L }, // LATIN CAPITAL LETTER THORN + { 0x00DF, BIDI_L }, // LATIN SMALL LETTER SHARP S + { 0x00E0, BIDI_L }, // LATIN SMALL LETTER A WITH GRAVE + { 0x00E1, BIDI_L }, // LATIN SMALL LETTER A WITH ACUTE + { 0x00E2, BIDI_L }, // LATIN SMALL LETTER A WITH CIRCUMFLEX + { 0x00E3, BIDI_L }, // LATIN SMALL LETTER A WITH TILDE + { 0x00E4, BIDI_L }, // LATIN SMALL LETTER A WITH DIAERESIS + { 0x00E5, BIDI_L }, // LATIN SMALL LETTER A WITH RING ABOVE + { 0x00E6, BIDI_L }, // LATIN SMALL LETTER AE + { 0x00E7, BIDI_L }, // LATIN SMALL LETTER C WITH CEDILLA + { 0x00E8, BIDI_L }, // LATIN SMALL LETTER E WITH GRAVE + { 0x00E9, BIDI_L }, // LATIN SMALL LETTER E WITH ACUTE + { 0x00EA, BIDI_L }, // LATIN SMALL LETTER E WITH CIRCUMFLEX + { 0x00EB, BIDI_L }, // LATIN SMALL LETTER E WITH DIAERESIS + { 0x00EC, BIDI_L }, // LATIN SMALL LETTER I WITH GRAVE + { 0x00ED, BIDI_L }, // LATIN SMALL LETTER I WITH ACUTE + { 0x00EE, BIDI_L }, // LATIN SMALL LETTER I WITH CIRCUMFLEX + { 0x00EF, BIDI_L }, // LATIN SMALL LETTER I WITH DIAERESIS + { 0x00F0, BIDI_L }, // LATIN SMALL LETTER ETH + { 0x00F1, BIDI_L }, // LATIN SMALL LETTER N WITH TILDE + { 0x00F2, BIDI_L }, // LATIN SMALL LETTER O WITH GRAVE + { 0x00F3, BIDI_L }, // LATIN SMALL LETTER O WITH ACUTE + { 0x00F4, BIDI_L }, // LATIN SMALL LETTER O WITH CIRCUMFLEX + { 0x00F5, BIDI_L }, // LATIN SMALL LETTER O WITH TILDE + { 0x00F6, BIDI_L }, // LATIN SMALL LETTER O WITH DIAERESIS + { 0x00F7, BIDI_ON }, // DIVISION SIGN + { 0x00F8, BIDI_L }, // LATIN SMALL LETTER O WITH STROKE + { 0x00F9, BIDI_L }, // LATIN SMALL LETTER U WITH GRAVE + { 0x00FA, BIDI_L }, // LATIN SMALL LETTER U WITH ACUTE + { 0x00FB, BIDI_L }, // LATIN SMALL LETTER U WITH CIRCUMFLEX + { 0x00FC, BIDI_L }, // LATIN SMALL LETTER U WITH DIAERESIS + { 0x00FD, BIDI_L }, // LATIN SMALL LETTER Y WITH ACUTE + { 0x00FE, BIDI_L }, // LATIN SMALL LETTER THORN + { 0x00FF, BIDI_L }, // LATIN SMALL LETTER Y WITH DIAERESIS + { 0x0100, BIDI_L }, // LATIN CAPITAL LETTER A WITH MACRON + { 0x0101, BIDI_L }, // LATIN SMALL LETTER A WITH MACRON + { 0x0102, BIDI_L }, // LATIN CAPITAL LETTER A WITH BREVE + { 0x0103, BIDI_L }, // LATIN SMALL LETTER A WITH BREVE + { 0x0104, BIDI_L }, // LATIN CAPITAL LETTER A WITH OGONEK + { 0x0105, BIDI_L }, // LATIN SMALL LETTER A WITH OGONEK + { 0x0106, BIDI_L }, // LATIN CAPITAL LETTER C WITH ACUTE + { 0x0107, BIDI_L }, // LATIN SMALL LETTER C WITH ACUTE + { 0x0108, BIDI_L }, // LATIN CAPITAL LETTER C WITH CIRCUMFLEX + { 0x0109, BIDI_L }, // LATIN SMALL LETTER C WITH CIRCUMFLEX + { 0x010A, BIDI_L }, // LATIN CAPITAL LETTER C WITH DOT ABOVE + { 0x010B, BIDI_L }, // LATIN SMALL LETTER C WITH DOT ABOVE + { 0x010C, BIDI_L }, // LATIN CAPITAL LETTER C WITH CARON + { 0x010D, BIDI_L }, // LATIN SMALL LETTER C WITH CARON + { 0x010E, BIDI_L }, // LATIN CAPITAL LETTER D WITH CARON + { 0x010F, BIDI_L }, // LATIN SMALL LETTER D WITH CARON + { 0x0110, BIDI_L }, // LATIN CAPITAL LETTER D WITH STROKE + { 0x0111, BIDI_L }, // LATIN SMALL LETTER D WITH STROKE + { 0x0112, BIDI_L }, // LATIN CAPITAL LETTER E WITH MACRON + { 0x0113, BIDI_L }, // LATIN SMALL LETTER E WITH MACRON + { 0x0114, BIDI_L }, // LATIN CAPITAL LETTER E WITH BREVE + { 0x0115, BIDI_L }, // LATIN SMALL LETTER E WITH BREVE + { 0x0116, BIDI_L }, // LATIN CAPITAL LETTER E WITH DOT ABOVE + { 0x0117, BIDI_L }, // LATIN SMALL LETTER E WITH DOT ABOVE + { 0x0118, BIDI_L }, // LATIN CAPITAL LETTER E WITH OGONEK + { 0x0119, BIDI_L }, // LATIN SMALL LETTER E WITH OGONEK + { 0x011A, BIDI_L }, // LATIN CAPITAL LETTER E WITH CARON + { 0x011B, BIDI_L }, // LATIN SMALL LETTER E WITH CARON + { 0x011C, BIDI_L }, // LATIN CAPITAL LETTER G WITH CIRCUMFLEX + { 0x011D, BIDI_L }, // LATIN SMALL LETTER G WITH CIRCUMFLEX + { 0x011E, BIDI_L }, // LATIN CAPITAL LETTER G WITH BREVE + { 0x011F, BIDI_L }, // LATIN SMALL LETTER G WITH BREVE + { 0x0120, BIDI_L }, // LATIN CAPITAL LETTER G WITH DOT ABOVE + { 0x0121, BIDI_L }, // LATIN SMALL LETTER G WITH DOT ABOVE + { 0x0122, BIDI_L }, // LATIN CAPITAL LETTER G WITH CEDILLA + { 0x0123, BIDI_L }, // LATIN SMALL LETTER G WITH CEDILLA + { 0x0124, BIDI_L }, // LATIN CAPITAL LETTER H WITH CIRCUMFLEX + { 0x0125, BIDI_L }, // LATIN SMALL LETTER H WITH CIRCUMFLEX + { 0x0126, BIDI_L }, // LATIN CAPITAL LETTER H WITH STROKE + { 0x0127, BIDI_L }, // LATIN SMALL LETTER H WITH STROKE + { 0x0128, BIDI_L }, // LATIN CAPITAL LETTER I WITH TILDE + { 0x0129, BIDI_L }, // LATIN SMALL LETTER I WITH TILDE + { 0x012A, BIDI_L }, // LATIN CAPITAL LETTER I WITH MACRON + { 0x012B, BIDI_L }, // LATIN SMALL LETTER I WITH MACRON + { 0x012C, BIDI_L }, // LATIN CAPITAL LETTER I WITH BREVE + { 0x012D, BIDI_L }, // LATIN SMALL LETTER I WITH BREVE + { 0x012E, BIDI_L }, // LATIN CAPITAL LETTER I WITH OGONEK + { 0x012F, BIDI_L }, // LATIN SMALL LETTER I WITH OGONEK + { 0x0130, BIDI_L }, // LATIN CAPITAL LETTER I WITH DOT ABOVE + { 0x0131, BIDI_L }, // LATIN SMALL LETTER DOTLESS I + { 0x0132, BIDI_L }, // LATIN CAPITAL LIGATURE IJ + { 0x0133, BIDI_L }, // LATIN SMALL LIGATURE IJ + { 0x0134, BIDI_L }, // LATIN CAPITAL LETTER J WITH CIRCUMFLEX + { 0x0135, BIDI_L }, // LATIN SMALL LETTER J WITH CIRCUMFLEX + { 0x0136, BIDI_L }, // LATIN CAPITAL LETTER K WITH CEDILLA + { 0x0137, BIDI_L }, // LATIN SMALL LETTER K WITH CEDILLA + { 0x0138, BIDI_L }, // LATIN SMALL LETTER KRA + { 0x0139, BIDI_L }, // LATIN CAPITAL LETTER L WITH ACUTE + { 0x013A, BIDI_L }, // LATIN SMALL LETTER L WITH ACUTE + { 0x013B, BIDI_L }, // LATIN CAPITAL LETTER L WITH CEDILLA + { 0x013C, BIDI_L }, // LATIN SMALL LETTER L WITH CEDILLA + { 0x013D, BIDI_L }, // LATIN CAPITAL LETTER L WITH CARON + { 0x013E, BIDI_L }, // LATIN SMALL LETTER L WITH CARON + { 0x013F, BIDI_L }, // LATIN CAPITAL LETTER L WITH MIDDLE DOT + { 0x0140, BIDI_L }, // LATIN SMALL LETTER L WITH MIDDLE DOT + { 0x0141, BIDI_L }, // LATIN CAPITAL LETTER L WITH STROKE + { 0x0142, BIDI_L }, // LATIN SMALL LETTER L WITH STROKE + { 0x0143, BIDI_L }, // LATIN CAPITAL LETTER N WITH ACUTE + { 0x0144, BIDI_L }, // LATIN SMALL LETTER N WITH ACUTE + { 0x0145, BIDI_L }, // LATIN CAPITAL LETTER N WITH CEDILLA + { 0x0146, BIDI_L }, // LATIN SMALL LETTER N WITH CEDILLA + { 0x0147, BIDI_L }, // LATIN CAPITAL LETTER N WITH CARON + { 0x0148, BIDI_L }, // LATIN SMALL LETTER N WITH CARON + { 0x0149, BIDI_L }, // LATIN SMALL LETTER N PRECEDED BY APOSTROPHE + { 0x014A, BIDI_L }, // LATIN CAPITAL LETTER ENG + { 0x014B, BIDI_L }, // LATIN SMALL LETTER ENG + { 0x014C, BIDI_L }, // LATIN CAPITAL LETTER O WITH MACRON + { 0x014D, BIDI_L }, // LATIN SMALL LETTER O WITH MACRON + { 0x014E, BIDI_L }, // LATIN CAPITAL LETTER O WITH BREVE + { 0x014F, BIDI_L }, // LATIN SMALL LETTER O WITH BREVE + { 0x0150, BIDI_L }, // LATIN CAPITAL LETTER O WITH DOUBLE ACUTE + { 0x0151, BIDI_L }, // LATIN SMALL LETTER O WITH DOUBLE ACUTE + { 0x0152, BIDI_L }, // LATIN CAPITAL LIGATURE OE + { 0x0153, BIDI_L }, // LATIN SMALL LIGATURE OE + { 0x0154, BIDI_L }, // LATIN CAPITAL LETTER R WITH ACUTE + { 0x0155, BIDI_L }, // LATIN SMALL LETTER R WITH ACUTE + { 0x0156, BIDI_L }, // LATIN CAPITAL LETTER R WITH CEDILLA + { 0x0157, BIDI_L }, // LATIN SMALL LETTER R WITH CEDILLA + { 0x0158, BIDI_L }, // LATIN CAPITAL LETTER R WITH CARON + { 0x0159, BIDI_L }, // LATIN SMALL LETTER R WITH CARON + { 0x015A, BIDI_L }, // LATIN CAPITAL LETTER S WITH ACUTE + { 0x015B, BIDI_L }, // LATIN SMALL LETTER S WITH ACUTE + { 0x015C, BIDI_L }, // LATIN CAPITAL LETTER S WITH CIRCUMFLEX + { 0x015D, BIDI_L }, // LATIN SMALL LETTER S WITH CIRCUMFLEX + { 0x015E, BIDI_L }, // LATIN CAPITAL LETTER S WITH CEDILLA + { 0x015F, BIDI_L }, // LATIN SMALL LETTER S WITH CEDILLA + { 0x0160, BIDI_L }, // LATIN CAPITAL LETTER S WITH CARON + { 0x0161, BIDI_L }, // LATIN SMALL LETTER S WITH CARON + { 0x0162, BIDI_L }, // LATIN CAPITAL LETTER T WITH CEDILLA + { 0x0163, BIDI_L }, // LATIN SMALL LETTER T WITH CEDILLA + { 0x0164, BIDI_L }, // LATIN CAPITAL LETTER T WITH CARON + { 0x0165, BIDI_L }, // LATIN SMALL LETTER T WITH CARON + { 0x0166, BIDI_L }, // LATIN CAPITAL LETTER T WITH STROKE + { 0x0167, BIDI_L }, // LATIN SMALL LETTER T WITH STROKE + { 0x0168, BIDI_L }, // LATIN CAPITAL LETTER U WITH TILDE + { 0x0169, BIDI_L }, // LATIN SMALL LETTER U WITH TILDE + { 0x016A, BIDI_L }, // LATIN CAPITAL LETTER U WITH MACRON + { 0x016B, BIDI_L }, // LATIN SMALL LETTER U WITH MACRON + { 0x016C, BIDI_L }, // LATIN CAPITAL LETTER U WITH BREVE + { 0x016D, BIDI_L }, // LATIN SMALL LETTER U WITH BREVE + { 0x016E, BIDI_L }, // LATIN CAPITAL LETTER U WITH RING ABOVE + { 0x016F, BIDI_L }, // LATIN SMALL LETTER U WITH RING ABOVE + { 0x0170, BIDI_L }, // LATIN CAPITAL LETTER U WITH DOUBLE ACUTE + { 0x0171, BIDI_L }, // LATIN SMALL LETTER U WITH DOUBLE ACUTE + { 0x0172, BIDI_L }, // LATIN CAPITAL LETTER U WITH OGONEK + { 0x0173, BIDI_L }, // LATIN SMALL LETTER U WITH OGONEK + { 0x0174, BIDI_L }, // LATIN CAPITAL LETTER W WITH CIRCUMFLEX + { 0x0175, BIDI_L }, // LATIN SMALL LETTER W WITH CIRCUMFLEX + { 0x0176, BIDI_L }, // LATIN CAPITAL LETTER Y WITH CIRCUMFLEX + { 0x0177, BIDI_L }, // LATIN SMALL LETTER Y WITH CIRCUMFLEX + { 0x0178, BIDI_L }, // LATIN CAPITAL LETTER Y WITH DIAERESIS + { 0x0179, BIDI_L }, // LATIN CAPITAL LETTER Z WITH ACUTE + { 0x017A, BIDI_L }, // LATIN SMALL LETTER Z WITH ACUTE + { 0x017B, BIDI_L }, // LATIN CAPITAL LETTER Z WITH DOT ABOVE + { 0x017C, BIDI_L }, // LATIN SMALL LETTER Z WITH DOT ABOVE + { 0x017D, BIDI_L }, // LATIN CAPITAL LETTER Z WITH CARON + { 0x017E, BIDI_L }, // LATIN SMALL LETTER Z WITH CARON + { 0x017F, BIDI_L }, // LATIN SMALL LETTER LONG S + { 0x0180, BIDI_L }, // LATIN SMALL LETTER B WITH STROKE + { 0x0181, BIDI_L }, // LATIN CAPITAL LETTER B WITH HOOK + { 0x0182, BIDI_L }, // LATIN CAPITAL LETTER B WITH TOPBAR + { 0x0183, BIDI_L }, // LATIN SMALL LETTER B WITH TOPBAR + { 0x0184, BIDI_L }, // LATIN CAPITAL LETTER TONE SIX + { 0x0185, BIDI_L }, // LATIN SMALL LETTER TONE SIX + { 0x0186, BIDI_L }, // LATIN CAPITAL LETTER OPEN O + { 0x0187, BIDI_L }, // LATIN CAPITAL LETTER C WITH HOOK + { 0x0188, BIDI_L }, // LATIN SMALL LETTER C WITH HOOK + { 0x0189, BIDI_L }, // LATIN CAPITAL LETTER AFRICAN D + { 0x018A, BIDI_L }, // LATIN CAPITAL LETTER D WITH HOOK + { 0x018B, BIDI_L }, // LATIN CAPITAL LETTER D WITH TOPBAR + { 0x018C, BIDI_L }, // LATIN SMALL LETTER D WITH TOPBAR + { 0x018D, BIDI_L }, // LATIN SMALL LETTER TURNED DELTA + { 0x018E, BIDI_L }, // LATIN CAPITAL LETTER REVERSED E + { 0x018F, BIDI_L }, // LATIN CAPITAL LETTER SCHWA + { 0x0190, BIDI_L }, // LATIN CAPITAL LETTER OPEN E + { 0x0191, BIDI_L }, // LATIN CAPITAL LETTER F WITH HOOK + { 0x0192, BIDI_L }, // LATIN SMALL LETTER F WITH HOOK + { 0x0193, BIDI_L }, // LATIN CAPITAL LETTER G WITH HOOK + { 0x0194, BIDI_L }, // LATIN CAPITAL LETTER GAMMA + { 0x0195, BIDI_L }, // LATIN SMALL LETTER HV + { 0x0196, BIDI_L }, // LATIN CAPITAL LETTER IOTA + { 0x0197, BIDI_L }, // LATIN CAPITAL LETTER I WITH STROKE + { 0x0198, BIDI_L }, // LATIN CAPITAL LETTER K WITH HOOK + { 0x0199, BIDI_L }, // LATIN SMALL LETTER K WITH HOOK + { 0x019A, BIDI_L }, // LATIN SMALL LETTER L WITH BAR + { 0x019B, BIDI_L }, // LATIN SMALL LETTER LAMBDA WITH STROKE + { 0x019C, BIDI_L }, // LATIN CAPITAL LETTER TURNED M + { 0x019D, BIDI_L }, // LATIN CAPITAL LETTER N WITH LEFT HOOK + { 0x019E, BIDI_L }, // LATIN SMALL LETTER N WITH LONG RIGHT LEG + { 0x019F, BIDI_L }, // LATIN CAPITAL LETTER O WITH MIDDLE TILDE + { 0x01A0, BIDI_L }, // LATIN CAPITAL LETTER O WITH HORN + { 0x01A1, BIDI_L }, // LATIN SMALL LETTER O WITH HORN + { 0x01A2, BIDI_L }, // LATIN CAPITAL LETTER OI + { 0x01A3, BIDI_L }, // LATIN SMALL LETTER OI + { 0x01A4, BIDI_L }, // LATIN CAPITAL LETTER P WITH HOOK + { 0x01A5, BIDI_L }, // LATIN SMALL LETTER P WITH HOOK + { 0x01A6, BIDI_L }, // LATIN LETTER YR + { 0x01A7, BIDI_L }, // LATIN CAPITAL LETTER TONE TWO + { 0x01A8, BIDI_L }, // LATIN SMALL LETTER TONE TWO + { 0x01A9, BIDI_L }, // LATIN CAPITAL LETTER ESH + { 0x01AA, BIDI_L }, // LATIN LETTER REVERSED ESH LOOP + { 0x01AB, BIDI_L }, // LATIN SMALL LETTER T WITH PALATAL HOOK + { 0x01AC, BIDI_L }, // LATIN CAPITAL LETTER T WITH HOOK + { 0x01AD, BIDI_L }, // LATIN SMALL LETTER T WITH HOOK + { 0x01AE, BIDI_L }, // LATIN CAPITAL LETTER T WITH RETROFLEX HOOK + { 0x01AF, BIDI_L }, // LATIN CAPITAL LETTER U WITH HORN + { 0x01B0, BIDI_L }, // LATIN SMALL LETTER U WITH HORN + { 0x01B1, BIDI_L }, // LATIN CAPITAL LETTER UPSILON + { 0x01B2, BIDI_L }, // LATIN CAPITAL LETTER V WITH HOOK + { 0x01B3, BIDI_L }, // LATIN CAPITAL LETTER Y WITH HOOK + { 0x01B4, BIDI_L }, // LATIN SMALL LETTER Y WITH HOOK + { 0x01B5, BIDI_L }, // LATIN CAPITAL LETTER Z WITH STROKE + { 0x01B6, BIDI_L }, // LATIN SMALL LETTER Z WITH STROKE + { 0x01B7, BIDI_L }, // LATIN CAPITAL LETTER EZH + { 0x01B8, BIDI_L }, // LATIN CAPITAL LETTER EZH REVERSED + { 0x01B9, BIDI_L }, // LATIN SMALL LETTER EZH REVERSED + { 0x01BA, BIDI_L }, // LATIN SMALL LETTER EZH WITH TAIL + { 0x01BB, BIDI_L }, // LATIN LETTER TWO WITH STROKE + { 0x01BC, BIDI_L }, // LATIN CAPITAL LETTER TONE FIVE + { 0x01BD, BIDI_L }, // LATIN SMALL LETTER TONE FIVE + { 0x01BE, BIDI_L }, // LATIN LETTER INVERTED GLOTTAL STOP WITH STROKE + { 0x01BF, BIDI_L }, // LATIN LETTER WYNN + { 0x01C0, BIDI_L }, // LATIN LETTER DENTAL CLICK + { 0x01C1, BIDI_L }, // LATIN LETTER LATERAL CLICK + { 0x01C2, BIDI_L }, // LATIN LETTER ALVEOLAR CLICK + { 0x01C3, BIDI_L }, // LATIN LETTER RETROFLEX CLICK + { 0x01C4, BIDI_L }, // LATIN CAPITAL LETTER DZ WITH CARON + { 0x01C5, BIDI_L }, // LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON + { 0x01C6, BIDI_L }, // LATIN SMALL LETTER DZ WITH CARON + { 0x01C7, BIDI_L }, // LATIN CAPITAL LETTER LJ + { 0x01C8, BIDI_L }, // LATIN CAPITAL LETTER L WITH SMALL LETTER J + { 0x01C9, BIDI_L }, // LATIN SMALL LETTER LJ + { 0x01CA, BIDI_L }, // LATIN CAPITAL LETTER NJ + { 0x01CB, BIDI_L }, // LATIN CAPITAL LETTER N WITH SMALL LETTER J + { 0x01CC, BIDI_L }, // LATIN SMALL LETTER NJ + { 0x01CD, BIDI_L }, // LATIN CAPITAL LETTER A WITH CARON + { 0x01CE, BIDI_L }, // LATIN SMALL LETTER A WITH CARON + { 0x01CF, BIDI_L }, // LATIN CAPITAL LETTER I WITH CARON + { 0x01D0, BIDI_L }, // LATIN SMALL LETTER I WITH CARON + { 0x01D1, BIDI_L }, // LATIN CAPITAL LETTER O WITH CARON + { 0x01D2, BIDI_L }, // LATIN SMALL LETTER O WITH CARON + { 0x01D3, BIDI_L }, // LATIN CAPITAL LETTER U WITH CARON + { 0x01D4, BIDI_L }, // LATIN SMALL LETTER U WITH CARON + { 0x01D5, BIDI_L }, // LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON + { 0x01D6, BIDI_L }, // LATIN SMALL LETTER U WITH DIAERESIS AND MACRON + { 0x01D7, BIDI_L }, // LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE + { 0x01D8, BIDI_L }, // LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE + { 0x01D9, BIDI_L }, // LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON + { 0x01DA, BIDI_L }, // LATIN SMALL LETTER U WITH DIAERESIS AND CARON + { 0x01DB, BIDI_L }, // LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE + { 0x01DC, BIDI_L }, // LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE + { 0x01DD, BIDI_L }, // LATIN SMALL LETTER TURNED E + { 0x01DE, BIDI_L }, // LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON + { 0x01DF, BIDI_L }, // LATIN SMALL LETTER A WITH DIAERESIS AND MACRON + { 0x01E0, BIDI_L }, // LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON + { 0x01E1, BIDI_L }, // LATIN SMALL LETTER A WITH DOT ABOVE AND MACRON + { 0x01E2, BIDI_L }, // LATIN CAPITAL LETTER AE WITH MACRON + { 0x01E3, BIDI_L }, // LATIN SMALL LETTER AE WITH MACRON + { 0x01E4, BIDI_L }, // LATIN CAPITAL LETTER G WITH STROKE + { 0x01E5, BIDI_L }, // LATIN SMALL LETTER G WITH STROKE + { 0x01E6, BIDI_L }, // LATIN CAPITAL LETTER G WITH CARON + { 0x01E7, BIDI_L }, // LATIN SMALL LETTER G WITH CARON + { 0x01E8, BIDI_L }, // LATIN CAPITAL LETTER K WITH CARON + { 0x01E9, BIDI_L }, // LATIN SMALL LETTER K WITH CARON + { 0x01EA, BIDI_L }, // LATIN CAPITAL LETTER O WITH OGONEK + { 0x01EB, BIDI_L }, // LATIN SMALL LETTER O WITH OGONEK + { 0x01EC, BIDI_L }, // LATIN CAPITAL LETTER O WITH OGONEK AND MACRON + { 0x01ED, BIDI_L }, // LATIN SMALL LETTER O WITH OGONEK AND MACRON + { 0x01EE, BIDI_L }, // LATIN CAPITAL LETTER EZH WITH CARON + { 0x01EF, BIDI_L }, // LATIN SMALL LETTER EZH WITH CARON + { 0x01F0, BIDI_L }, // LATIN SMALL LETTER J WITH CARON + { 0x01F1, BIDI_L }, // LATIN CAPITAL LETTER DZ + { 0x01F2, BIDI_L }, // LATIN CAPITAL LETTER D WITH SMALL LETTER Z + { 0x01F3, BIDI_L }, // LATIN SMALL LETTER DZ + { 0x01F4, BIDI_L }, // LATIN CAPITAL LETTER G WITH ACUTE + { 0x01F5, BIDI_L }, // LATIN SMALL LETTER G WITH ACUTE + { 0x01F6, BIDI_L }, // LATIN CAPITAL LETTER HWAIR + { 0x01F7, BIDI_L }, // LATIN CAPITAL LETTER WYNN + { 0x01F8, BIDI_L }, // LATIN CAPITAL LETTER N WITH GRAVE + { 0x01F9, BIDI_L }, // LATIN SMALL LETTER N WITH GRAVE + { 0x01FA, BIDI_L }, // LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE + { 0x01FB, BIDI_L }, // LATIN SMALL LETTER A WITH RING ABOVE AND ACUTE + { 0x01FC, BIDI_L }, // LATIN CAPITAL LETTER AE WITH ACUTE + { 0x01FD, BIDI_L }, // LATIN SMALL LETTER AE WITH ACUTE + { 0x01FE, BIDI_L }, // LATIN CAPITAL LETTER O WITH STROKE AND ACUTE + { 0x01FF, BIDI_L }, // LATIN SMALL LETTER O WITH STROKE AND ACUTE + { 0x0200, BIDI_L }, // LATIN CAPITAL LETTER A WITH DOUBLE GRAVE + { 0x0201, BIDI_L }, // LATIN SMALL LETTER A WITH DOUBLE GRAVE + { 0x0202, BIDI_L }, // LATIN CAPITAL LETTER A WITH INVERTED BREVE + { 0x0203, BIDI_L }, // LATIN SMALL LETTER A WITH INVERTED BREVE + { 0x0204, BIDI_L }, // LATIN CAPITAL LETTER E WITH DOUBLE GRAVE + { 0x0205, BIDI_L }, // LATIN SMALL LETTER E WITH DOUBLE GRAVE + { 0x0206, BIDI_L }, // LATIN CAPITAL LETTER E WITH INVERTED BREVE + { 0x0207, BIDI_L }, // LATIN SMALL LETTER E WITH INVERTED BREVE + { 0x0208, BIDI_L }, // LATIN CAPITAL LETTER I WITH DOUBLE GRAVE + { 0x0209, BIDI_L }, // LATIN SMALL LETTER I WITH DOUBLE GRAVE + { 0x020A, BIDI_L }, // LATIN CAPITAL LETTER I WITH INVERTED BREVE + { 0x020B, BIDI_L }, // LATIN SMALL LETTER I WITH INVERTED BREVE + { 0x020C, BIDI_L }, // LATIN CAPITAL LETTER O WITH DOUBLE GRAVE + { 0x020D, BIDI_L }, // LATIN SMALL LETTER O WITH DOUBLE GRAVE + { 0x020E, BIDI_L }, // LATIN CAPITAL LETTER O WITH INVERTED BREVE + { 0x020F, BIDI_L }, // LATIN SMALL LETTER O WITH INVERTED BREVE + { 0x0210, BIDI_L }, // LATIN CAPITAL LETTER R WITH DOUBLE GRAVE + { 0x0211, BIDI_L }, // LATIN SMALL LETTER R WITH DOUBLE GRAVE + { 0x0212, BIDI_L }, // LATIN CAPITAL LETTER R WITH INVERTED BREVE + { 0x0213, BIDI_L }, // LATIN SMALL LETTER R WITH INVERTED BREVE + { 0x0214, BIDI_L }, // LATIN CAPITAL LETTER U WITH DOUBLE GRAVE + { 0x0215, BIDI_L }, // LATIN SMALL LETTER U WITH DOUBLE GRAVE + { 0x0216, BIDI_L }, // LATIN CAPITAL LETTER U WITH INVERTED BREVE + { 0x0217, BIDI_L }, // LATIN SMALL LETTER U WITH INVERTED BREVE + { 0x0218, BIDI_L }, // LATIN CAPITAL LETTER S WITH COMMA BELOW + { 0x0219, BIDI_L }, // LATIN SMALL LETTER S WITH COMMA BELOW + { 0x021A, BIDI_L }, // LATIN CAPITAL LETTER T WITH COMMA BELOW + { 0x021B, BIDI_L }, // LATIN SMALL LETTER T WITH COMMA BELOW + { 0x021C, BIDI_L }, // LATIN CAPITAL LETTER YOGH + { 0x021D, BIDI_L }, // LATIN SMALL LETTER YOGH + { 0x021E, BIDI_L }, // LATIN CAPITAL LETTER H WITH CARON + { 0x021F, BIDI_L }, // LATIN SMALL LETTER H WITH CARON + { 0x0220, BIDI_L }, // LATIN CAPITAL LETTER N WITH LONG RIGHT LEG + { 0x0221, BIDI_L }, // LATIN SMALL LETTER D WITH CURL + { 0x0222, BIDI_L }, // LATIN CAPITAL LETTER OU + { 0x0223, BIDI_L }, // LATIN SMALL LETTER OU + { 0x0224, BIDI_L }, // LATIN CAPITAL LETTER Z WITH HOOK + { 0x0225, BIDI_L }, // LATIN SMALL LETTER Z WITH HOOK + { 0x0226, BIDI_L }, // LATIN CAPITAL LETTER A WITH DOT ABOVE + { 0x0227, BIDI_L }, // LATIN SMALL LETTER A WITH DOT ABOVE + { 0x0228, BIDI_L }, // LATIN CAPITAL LETTER E WITH CEDILLA + { 0x0229, BIDI_L }, // LATIN SMALL LETTER E WITH CEDILLA + { 0x022A, BIDI_L }, // LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON + { 0x022B, BIDI_L }, // LATIN SMALL LETTER O WITH DIAERESIS AND MACRON + { 0x022C, BIDI_L }, // LATIN CAPITAL LETTER O WITH TILDE AND MACRON + { 0x022D, BIDI_L }, // LATIN SMALL LETTER O WITH TILDE AND MACRON + { 0x022E, BIDI_L }, // LATIN CAPITAL LETTER O WITH DOT ABOVE + { 0x022F, BIDI_L }, // LATIN SMALL LETTER O WITH DOT ABOVE + { 0x0230, BIDI_L }, // LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON + { 0x0231, BIDI_L }, // LATIN SMALL LETTER O WITH DOT ABOVE AND MACRON + { 0x0232, BIDI_L }, // LATIN CAPITAL LETTER Y WITH MACRON + { 0x0233, BIDI_L }, // LATIN SMALL LETTER Y WITH MACRON + { 0x0234, BIDI_L }, // LATIN SMALL LETTER L WITH CURL + { 0x0235, BIDI_L }, // LATIN SMALL LETTER N WITH CURL + { 0x0236, BIDI_L }, // LATIN SMALL LETTER T WITH CURL + { 0x0237, BIDI_L }, // LATIN SMALL LETTER DOTLESS J + { 0x0238, BIDI_L }, // LATIN SMALL LETTER DB DIGRAPH + { 0x0239, BIDI_L }, // LATIN SMALL LETTER QP DIGRAPH + { 0x023A, BIDI_L }, // LATIN CAPITAL LETTER A WITH STROKE + { 0x023B, BIDI_L }, // LATIN CAPITAL LETTER C WITH STROKE + { 0x023C, BIDI_L }, // LATIN SMALL LETTER C WITH STROKE + { 0x023D, BIDI_L }, // LATIN CAPITAL LETTER L WITH BAR + { 0x023E, BIDI_L }, // LATIN CAPITAL LETTER T WITH DIAGONAL STROKE + { 0x023F, BIDI_L }, // LATIN SMALL LETTER S WITH SWASH TAIL + { 0x0240, BIDI_L }, // LATIN SMALL LETTER Z WITH SWASH TAIL + { 0x0241, BIDI_L }, // LATIN CAPITAL LETTER GLOTTAL STOP + { 0x0242, BIDI_L }, // LATIN SMALL LETTER GLOTTAL STOP + { 0x0243, BIDI_L }, // LATIN CAPITAL LETTER B WITH STROKE + { 0x0244, BIDI_L }, // LATIN CAPITAL LETTER U BAR + { 0x0245, BIDI_L }, // LATIN CAPITAL LETTER TURNED V + { 0x0246, BIDI_L }, // LATIN CAPITAL LETTER E WITH STROKE + { 0x0247, BIDI_L }, // LATIN SMALL LETTER E WITH STROKE + { 0x0248, BIDI_L }, // LATIN CAPITAL LETTER J WITH STROKE + { 0x0249, BIDI_L }, // LATIN SMALL LETTER J WITH STROKE + { 0x024A, BIDI_L }, // LATIN CAPITAL LETTER SMALL Q WITH HOOK TAIL + { 0x024B, BIDI_L }, // LATIN SMALL LETTER Q WITH HOOK TAIL + { 0x024C, BIDI_L }, // LATIN CAPITAL LETTER R WITH STROKE + { 0x024D, BIDI_L }, // LATIN SMALL LETTER R WITH STROKE + { 0x024E, BIDI_L }, // LATIN CAPITAL LETTER Y WITH STROKE + { 0x024F, BIDI_L }, // LATIN SMALL LETTER Y WITH STROKE + { 0x0250, BIDI_L }, // LATIN SMALL LETTER TURNED A + { 0x0251, BIDI_L }, // LATIN SMALL LETTER ALPHA + { 0x0252, BIDI_L }, // LATIN SMALL LETTER TURNED ALPHA + { 0x0253, BIDI_L }, // LATIN SMALL LETTER B WITH HOOK + { 0x0254, BIDI_L }, // LATIN SMALL LETTER OPEN O + { 0x0255, BIDI_L }, // LATIN SMALL LETTER C WITH CURL + { 0x0256, BIDI_L }, // LATIN SMALL LETTER D WITH TAIL + { 0x0257, BIDI_L }, // LATIN SMALL LETTER D WITH HOOK + { 0x0258, BIDI_L }, // LATIN SMALL LETTER REVERSED E + { 0x0259, BIDI_L }, // LATIN SMALL LETTER SCHWA + { 0x025A, BIDI_L }, // LATIN SMALL LETTER SCHWA WITH HOOK + { 0x025B, BIDI_L }, // LATIN SMALL LETTER OPEN E + { 0x025C, BIDI_L }, // LATIN SMALL LETTER REVERSED OPEN E + { 0x025D, BIDI_L }, // LATIN SMALL LETTER REVERSED OPEN E WITH HOOK + { 0x025E, BIDI_L }, // LATIN SMALL LETTER CLOSED REVERSED OPEN E + { 0x025F, BIDI_L }, // LATIN SMALL LETTER DOTLESS J WITH STROKE + { 0x0260, BIDI_L }, // LATIN SMALL LETTER G WITH HOOK + { 0x0261, BIDI_L }, // LATIN SMALL LETTER SCRIPT G + { 0x0262, BIDI_L }, // LATIN LETTER SMALL CAPITAL G + { 0x0263, BIDI_L }, // LATIN SMALL LETTER GAMMA + { 0x0264, BIDI_L }, // LATIN SMALL LETTER RAMS HORN + { 0x0265, BIDI_L }, // LATIN SMALL LETTER TURNED H + { 0x0266, BIDI_L }, // LATIN SMALL LETTER H WITH HOOK + { 0x0267, BIDI_L }, // LATIN SMALL LETTER HENG WITH HOOK + { 0x0268, BIDI_L }, // LATIN SMALL LETTER I WITH STROKE + { 0x0269, BIDI_L }, // LATIN SMALL LETTER IOTA + { 0x026A, BIDI_L }, // LATIN LETTER SMALL CAPITAL I + { 0x026B, BIDI_L }, // LATIN SMALL LETTER L WITH MIDDLE TILDE + { 0x026C, BIDI_L }, // LATIN SMALL LETTER L WITH BELT + { 0x026D, BIDI_L }, // LATIN SMALL LETTER L WITH RETROFLEX HOOK + { 0x026E, BIDI_L }, // LATIN SMALL LETTER LEZH + { 0x026F, BIDI_L }, // LATIN SMALL LETTER TURNED M + { 0x0270, BIDI_L }, // LATIN SMALL LETTER TURNED M WITH LONG LEG + { 0x0271, BIDI_L }, // LATIN SMALL LETTER M WITH HOOK + { 0x0272, BIDI_L }, // LATIN SMALL LETTER N WITH LEFT HOOK + { 0x0273, BIDI_L }, // LATIN SMALL LETTER N WITH RETROFLEX HOOK + { 0x0274, BIDI_L }, // LATIN LETTER SMALL CAPITAL N + { 0x0275, BIDI_L }, // LATIN SMALL LETTER BARRED O + { 0x0276, BIDI_L }, // LATIN LETTER SMALL CAPITAL OE + { 0x0277, BIDI_L }, // LATIN SMALL LETTER CLOSED OMEGA + { 0x0278, BIDI_L }, // LATIN SMALL LETTER PHI + { 0x0279, BIDI_L }, // LATIN SMALL LETTER TURNED R + { 0x027A, BIDI_L }, // LATIN SMALL LETTER TURNED R WITH LONG LEG + { 0x027B, BIDI_L }, // LATIN SMALL LETTER TURNED R WITH HOOK + { 0x027C, BIDI_L }, // LATIN SMALL LETTER R WITH LONG LEG + { 0x027D, BIDI_L }, // LATIN SMALL LETTER R WITH TAIL + { 0x027E, BIDI_L }, // LATIN SMALL LETTER R WITH FISHHOOK + { 0x027F, BIDI_L }, // LATIN SMALL LETTER REVERSED R WITH FISHHOOK + { 0x0280, BIDI_L }, // LATIN LETTER SMALL CAPITAL R + { 0x0281, BIDI_L }, // LATIN LETTER SMALL CAPITAL INVERTED R + { 0x0282, BIDI_L }, // LATIN SMALL LETTER S WITH HOOK + { 0x0283, BIDI_L }, // LATIN SMALL LETTER ESH + { 0x0284, BIDI_L }, // LATIN SMALL LETTER DOTLESS J WITH STROKE AND HOOK + { 0x0285, BIDI_L }, // LATIN SMALL LETTER SQUAT REVERSED ESH + { 0x0286, BIDI_L }, // LATIN SMALL LETTER ESH WITH CURL + { 0x0287, BIDI_L }, // LATIN SMALL LETTER TURNED T + { 0x0288, BIDI_L }, // LATIN SMALL LETTER T WITH RETROFLEX HOOK + { 0x0289, BIDI_L }, // LATIN SMALL LETTER U BAR + { 0x028A, BIDI_L }, // LATIN SMALL LETTER UPSILON + { 0x028B, BIDI_L }, // LATIN SMALL LETTER V WITH HOOK + { 0x028C, BIDI_L }, // LATIN SMALL LETTER TURNED V + { 0x028D, BIDI_L }, // LATIN SMALL LETTER TURNED W + { 0x028E, BIDI_L }, // LATIN SMALL LETTER TURNED Y + { 0x028F, BIDI_L }, // LATIN LETTER SMALL CAPITAL Y + { 0x0290, BIDI_L }, // LATIN SMALL LETTER Z WITH RETROFLEX HOOK + { 0x0291, BIDI_L }, // LATIN SMALL LETTER Z WITH CURL + { 0x0292, BIDI_L }, // LATIN SMALL LETTER EZH + { 0x0293, BIDI_L }, // LATIN SMALL LETTER EZH WITH CURL + { 0x0294, BIDI_L }, // LATIN LETTER GLOTTAL STOP + { 0x0295, BIDI_L }, // LATIN LETTER PHARYNGEAL VOICED FRICATIVE + { 0x0296, BIDI_L }, // LATIN LETTER INVERTED GLOTTAL STOP + { 0x0297, BIDI_L }, // LATIN LETTER STRETCHED C + { 0x0298, BIDI_L }, // LATIN LETTER BILABIAL CLICK + { 0x0299, BIDI_L }, // LATIN LETTER SMALL CAPITAL B + { 0x029A, BIDI_L }, // LATIN SMALL LETTER CLOSED OPEN E + { 0x029B, BIDI_L }, // LATIN LETTER SMALL CAPITAL G WITH HOOK + { 0x029C, BIDI_L }, // LATIN LETTER SMALL CAPITAL H + { 0x029D, BIDI_L }, // LATIN SMALL LETTER J WITH CROSSED-TAIL + { 0x029E, BIDI_L }, // LATIN SMALL LETTER TURNED K + { 0x029F, BIDI_L }, // LATIN LETTER SMALL CAPITAL L + { 0x02A0, BIDI_L }, // LATIN SMALL LETTER Q WITH HOOK + { 0x02A1, BIDI_L }, // LATIN LETTER GLOTTAL STOP WITH STROKE + { 0x02A2, BIDI_L }, // LATIN LETTER REVERSED GLOTTAL STOP WITH STROKE + { 0x02A3, BIDI_L }, // LATIN SMALL LETTER DZ DIGRAPH + { 0x02A4, BIDI_L }, // LATIN SMALL LETTER DEZH DIGRAPH + { 0x02A5, BIDI_L }, // LATIN SMALL LETTER DZ DIGRAPH WITH CURL + { 0x02A6, BIDI_L }, // LATIN SMALL LETTER TS DIGRAPH + { 0x02A7, BIDI_L }, // LATIN SMALL LETTER TESH DIGRAPH + { 0x02A8, BIDI_L }, // LATIN SMALL LETTER TC DIGRAPH WITH CURL + { 0x02A9, BIDI_L }, // LATIN SMALL LETTER FENG DIGRAPH + { 0x02AA, BIDI_L }, // LATIN SMALL LETTER LS DIGRAPH + { 0x02AB, BIDI_L }, // LATIN SMALL LETTER LZ DIGRAPH + { 0x02AC, BIDI_L }, // LATIN LETTER BILABIAL PERCUSSIVE + { 0x02AD, BIDI_L }, // LATIN LETTER BIDENTAL PERCUSSIVE + { 0x02AE, BIDI_L }, // LATIN SMALL LETTER TURNED H WITH FISHHOOK + { 0x02AF, BIDI_L }, // LATIN SMALL LETTER TURNED H WITH FISHHOOK AND TAIL + { 0x02B0, BIDI_L }, // MODIFIER LETTER SMALL H + { 0x02B1, BIDI_L }, // MODIFIER LETTER SMALL H WITH HOOK + { 0x02B2, BIDI_L }, // MODIFIER LETTER SMALL J + { 0x02B3, BIDI_L }, // MODIFIER LETTER SMALL R + { 0x02B4, BIDI_L }, // MODIFIER LETTER SMALL TURNED R + { 0x02B5, BIDI_L }, // MODIFIER LETTER SMALL TURNED R WITH HOOK + { 0x02B6, BIDI_L }, // MODIFIER LETTER SMALL CAPITAL INVERTED R + { 0x02B7, BIDI_L }, // MODIFIER LETTER SMALL W + { 0x02B8, BIDI_L }, // MODIFIER LETTER SMALL Y + { 0x02B9, BIDI_ON }, // MODIFIER LETTER PRIME + { 0x02BA, BIDI_ON }, // MODIFIER LETTER DOUBLE PRIME + { 0x02BB, BIDI_L }, // MODIFIER LETTER TURNED COMMA + { 0x02BC, BIDI_L }, // MODIFIER LETTER APOSTROPHE + { 0x02BD, BIDI_L }, // MODIFIER LETTER REVERSED COMMA + { 0x02BE, BIDI_L }, // MODIFIER LETTER RIGHT HALF RING + { 0x02BF, BIDI_L }, // MODIFIER LETTER LEFT HALF RING + { 0x02C0, BIDI_L }, // MODIFIER LETTER GLOTTAL STOP + { 0x02C1, BIDI_L }, // MODIFIER LETTER REVERSED GLOTTAL STOP + { 0x02C2, BIDI_ON }, // MODIFIER LETTER LEFT ARROWHEAD + { 0x02C3, BIDI_ON }, // MODIFIER LETTER RIGHT ARROWHEAD + { 0x02C4, BIDI_ON }, // MODIFIER LETTER UP ARROWHEAD + { 0x02C5, BIDI_ON }, // MODIFIER LETTER DOWN ARROWHEAD + { 0x02C6, BIDI_ON }, // MODIFIER LETTER CIRCUMFLEX ACCENT + { 0x02C7, BIDI_ON }, // CARON + { 0x02C8, BIDI_ON }, // MODIFIER LETTER VERTICAL LINE + { 0x02C9, BIDI_ON }, // MODIFIER LETTER MACRON + { 0x02CA, BIDI_ON }, // MODIFIER LETTER ACUTE ACCENT + { 0x02CB, BIDI_ON }, // MODIFIER LETTER GRAVE ACCENT + { 0x02CC, BIDI_ON }, // MODIFIER LETTER LOW VERTICAL LINE + { 0x02CD, BIDI_ON }, // MODIFIER LETTER LOW MACRON + { 0x02CE, BIDI_ON }, // MODIFIER LETTER LOW GRAVE ACCENT + { 0x02CF, BIDI_ON }, // MODIFIER LETTER LOW ACUTE ACCENT + { 0x02D0, BIDI_L }, // MODIFIER LETTER TRIANGULAR COLON + { 0x02D1, BIDI_L }, // MODIFIER LETTER HALF TRIANGULAR COLON + { 0x02D2, BIDI_ON }, // MODIFIER LETTER CENTRED RIGHT HALF RING + { 0x02D3, BIDI_ON }, // MODIFIER LETTER CENTRED LEFT HALF RING + { 0x02D4, BIDI_ON }, // MODIFIER LETTER UP TACK + { 0x02D5, BIDI_ON }, // MODIFIER LETTER DOWN TACK + { 0x02D6, BIDI_ON }, // MODIFIER LETTER PLUS SIGN + { 0x02D7, BIDI_ON }, // MODIFIER LETTER MINUS SIGN + { 0x02D8, BIDI_ON }, // BREVE + { 0x02D9, BIDI_ON }, // DOT ABOVE + { 0x02DA, BIDI_ON }, // RING ABOVE + { 0x02DB, BIDI_ON }, // OGONEK + { 0x02DC, BIDI_ON }, // SMALL TILDE + { 0x02DD, BIDI_ON }, // DOUBLE ACUTE ACCENT + { 0x02DE, BIDI_ON }, // MODIFIER LETTER RHOTIC HOOK + { 0x02DF, BIDI_ON }, // MODIFIER LETTER CROSS ACCENT + { 0x02E0, BIDI_L }, // MODIFIER LETTER SMALL GAMMA + { 0x02E1, BIDI_L }, // MODIFIER LETTER SMALL L + { 0x02E2, BIDI_L }, // MODIFIER LETTER SMALL S + { 0x02E3, BIDI_L }, // MODIFIER LETTER SMALL X + { 0x02E4, BIDI_L }, // MODIFIER LETTER SMALL REVERSED GLOTTAL STOP + { 0x02E5, BIDI_ON }, // MODIFIER LETTER EXTRA-HIGH TONE BAR + { 0x02E6, BIDI_ON }, // MODIFIER LETTER HIGH TONE BAR + { 0x02E7, BIDI_ON }, // MODIFIER LETTER MID TONE BAR + { 0x02E8, BIDI_ON }, // MODIFIER LETTER LOW TONE BAR + { 0x02E9, BIDI_ON }, // MODIFIER LETTER EXTRA-LOW TONE BAR + { 0x02EA, BIDI_ON }, // MODIFIER LETTER YIN DEPARTING TONE MARK + { 0x02EB, BIDI_ON }, // MODIFIER LETTER YANG DEPARTING TONE MARK + { 0x02EC, BIDI_ON }, // MODIFIER LETTER VOICING + { 0x02ED, BIDI_ON }, // MODIFIER LETTER UNASPIRATED + { 0x02EE, BIDI_L }, // MODIFIER LETTER DOUBLE APOSTROPHE + { 0x02EF, BIDI_ON }, // MODIFIER LETTER LOW DOWN ARROWHEAD + { 0x02F0, BIDI_ON }, // MODIFIER LETTER LOW UP ARROWHEAD + { 0x02F1, BIDI_ON }, // MODIFIER LETTER LOW LEFT ARROWHEAD + { 0x02F2, BIDI_ON }, // MODIFIER LETTER LOW RIGHT ARROWHEAD + { 0x02F3, BIDI_ON }, // MODIFIER LETTER LOW RING + { 0x02F4, BIDI_ON }, // MODIFIER LETTER MIDDLE GRAVE ACCENT + { 0x02F5, BIDI_ON }, // MODIFIER LETTER MIDDLE DOUBLE GRAVE ACCENT + { 0x02F6, BIDI_ON }, // MODIFIER LETTER MIDDLE DOUBLE ACUTE ACCENT + { 0x02F7, BIDI_ON }, // MODIFIER LETTER LOW TILDE + { 0x02F8, BIDI_ON }, // MODIFIER LETTER RAISED COLON + { 0x02F9, BIDI_ON }, // MODIFIER LETTER BEGIN HIGH TONE + { 0x02FA, BIDI_ON }, // MODIFIER LETTER END HIGH TONE + { 0x02FB, BIDI_ON }, // MODIFIER LETTER BEGIN LOW TONE + { 0x02FC, BIDI_ON }, // MODIFIER LETTER END LOW TONE + { 0x02FD, BIDI_ON }, // MODIFIER LETTER SHELF + { 0x02FE, BIDI_ON }, // MODIFIER LETTER OPEN SHELF + { 0x02FF, BIDI_ON }, // MODIFIER LETTER LOW LEFT ARROW + { 0x0300, BIDI_NSM }, // COMBINING GRAVE ACCENT + { 0x0301, BIDI_NSM }, // COMBINING ACUTE ACCENT + { 0x0302, BIDI_NSM }, // COMBINING CIRCUMFLEX ACCENT + { 0x0303, BIDI_NSM }, // COMBINING TILDE + { 0x0304, BIDI_NSM }, // COMBINING MACRON + { 0x0305, BIDI_NSM }, // COMBINING OVERLINE + { 0x0306, BIDI_NSM }, // COMBINING BREVE + { 0x0307, BIDI_NSM }, // COMBINING DOT ABOVE + { 0x0308, BIDI_NSM }, // COMBINING DIAERESIS + { 0x0309, BIDI_NSM }, // COMBINING HOOK ABOVE + { 0x030A, BIDI_NSM }, // COMBINING RING ABOVE + { 0x030B, BIDI_NSM }, // COMBINING DOUBLE ACUTE ACCENT + { 0x030C, BIDI_NSM }, // COMBINING CARON + { 0x030D, BIDI_NSM }, // COMBINING VERTICAL LINE ABOVE + { 0x030E, BIDI_NSM }, // COMBINING DOUBLE VERTICAL LINE ABOVE + { 0x030F, BIDI_NSM }, // COMBINING DOUBLE GRAVE ACCENT + { 0x0310, BIDI_NSM }, // COMBINING CANDRABINDU + { 0x0311, BIDI_NSM }, // COMBINING INVERTED BREVE + { 0x0312, BIDI_NSM }, // COMBINING TURNED COMMA ABOVE + { 0x0313, BIDI_NSM }, // COMBINING COMMA ABOVE + { 0x0314, BIDI_NSM }, // COMBINING REVERSED COMMA ABOVE + { 0x0315, BIDI_NSM }, // COMBINING COMMA ABOVE RIGHT + { 0x0316, BIDI_NSM }, // COMBINING GRAVE ACCENT BELOW + { 0x0317, BIDI_NSM }, // COMBINING ACUTE ACCENT BELOW + { 0x0318, BIDI_NSM }, // COMBINING LEFT TACK BELOW + { 0x0319, BIDI_NSM }, // COMBINING RIGHT TACK BELOW + { 0x031A, BIDI_NSM }, // COMBINING LEFT ANGLE ABOVE + { 0x031B, BIDI_NSM }, // COMBINING HORN + { 0x031C, BIDI_NSM }, // COMBINING LEFT HALF RING BELOW + { 0x031D, BIDI_NSM }, // COMBINING UP TACK BELOW + { 0x031E, BIDI_NSM }, // COMBINING DOWN TACK BELOW + { 0x031F, BIDI_NSM }, // COMBINING PLUS SIGN BELOW + { 0x0320, BIDI_NSM }, // COMBINING MINUS SIGN BELOW + { 0x0321, BIDI_NSM }, // COMBINING PALATALIZED HOOK BELOW + { 0x0322, BIDI_NSM }, // COMBINING RETROFLEX HOOK BELOW + { 0x0323, BIDI_NSM }, // COMBINING DOT BELOW + { 0x0324, BIDI_NSM }, // COMBINING DIAERESIS BELOW + { 0x0325, BIDI_NSM }, // COMBINING RING BELOW + { 0x0326, BIDI_NSM }, // COMBINING COMMA BELOW + { 0x0327, BIDI_NSM }, // COMBINING CEDILLA + { 0x0328, BIDI_NSM }, // COMBINING OGONEK + { 0x0329, BIDI_NSM }, // COMBINING VERTICAL LINE BELOW + { 0x032A, BIDI_NSM }, // COMBINING BRIDGE BELOW + { 0x032B, BIDI_NSM }, // COMBINING INVERTED DOUBLE ARCH BELOW + { 0x032C, BIDI_NSM }, // COMBINING CARON BELOW + { 0x032D, BIDI_NSM }, // COMBINING CIRCUMFLEX ACCENT BELOW + { 0x032E, BIDI_NSM }, // COMBINING BREVE BELOW + { 0x032F, BIDI_NSM }, // COMBINING INVERTED BREVE BELOW + { 0x0330, BIDI_NSM }, // COMBINING TILDE BELOW + { 0x0331, BIDI_NSM }, // COMBINING MACRON BELOW + { 0x0332, BIDI_NSM }, // COMBINING LOW LINE + { 0x0333, BIDI_NSM }, // COMBINING DOUBLE LOW LINE + { 0x0334, BIDI_NSM }, // COMBINING TILDE OVERLAY + { 0x0335, BIDI_NSM }, // COMBINING SHORT STROKE OVERLAY + { 0x0336, BIDI_NSM }, // COMBINING LONG STROKE OVERLAY + { 0x0337, BIDI_NSM }, // COMBINING SHORT SOLIDUS OVERLAY + { 0x0338, BIDI_NSM }, // COMBINING LONG SOLIDUS OVERLAY + { 0x0339, BIDI_NSM }, // COMBINING RIGHT HALF RING BELOW + { 0x033A, BIDI_NSM }, // COMBINING INVERTED BRIDGE BELOW + { 0x033B, BIDI_NSM }, // COMBINING SQUARE BELOW + { 0x033C, BIDI_NSM }, // COMBINING SEAGULL BELOW + { 0x033D, BIDI_NSM }, // COMBINING X ABOVE + { 0x033E, BIDI_NSM }, // COMBINING VERTICAL TILDE + { 0x033F, BIDI_NSM }, // COMBINING DOUBLE OVERLINE + { 0x0340, BIDI_NSM }, // COMBINING GRAVE TONE MARK + { 0x0341, BIDI_NSM }, // COMBINING ACUTE TONE MARK + { 0x0342, BIDI_NSM }, // COMBINING GREEK PERISPOMENI + { 0x0343, BIDI_NSM }, // COMBINING GREEK KORONIS + { 0x0344, BIDI_NSM }, // COMBINING GREEK DIALYTIKA TONOS + { 0x0345, BIDI_NSM }, // COMBINING GREEK YPOGEGRAMMENI + { 0x0346, BIDI_NSM }, // COMBINING BRIDGE ABOVE + { 0x0347, BIDI_NSM }, // COMBINING EQUALS SIGN BELOW + { 0x0348, BIDI_NSM }, // COMBINING DOUBLE VERTICAL LINE BELOW + { 0x0349, BIDI_NSM }, // COMBINING LEFT ANGLE BELOW + { 0x034A, BIDI_NSM }, // COMBINING NOT TILDE ABOVE + { 0x034B, BIDI_NSM }, // COMBINING HOMOTHETIC ABOVE + { 0x034C, BIDI_NSM }, // COMBINING ALMOST EQUAL TO ABOVE + { 0x034D, BIDI_NSM }, // COMBINING LEFT RIGHT ARROW BELOW + { 0x034E, BIDI_NSM }, // COMBINING UPWARDS ARROW BELOW + { 0x034F, BIDI_NSM }, // COMBINING GRAPHEME JOINER + { 0x0350, BIDI_NSM }, // COMBINING RIGHT ARROWHEAD ABOVE + { 0x0351, BIDI_NSM }, // COMBINING LEFT HALF RING ABOVE + { 0x0352, BIDI_NSM }, // COMBINING FERMATA + { 0x0353, BIDI_NSM }, // COMBINING X BELOW + { 0x0354, BIDI_NSM }, // COMBINING LEFT ARROWHEAD BELOW + { 0x0355, BIDI_NSM }, // COMBINING RIGHT ARROWHEAD BELOW + { 0x0356, BIDI_NSM }, // COMBINING RIGHT ARROWHEAD AND UP ARROWHEAD BELOW + { 0x0357, BIDI_NSM }, // COMBINING RIGHT HALF RING ABOVE + { 0x0358, BIDI_NSM }, // COMBINING DOT ABOVE RIGHT + { 0x0359, BIDI_NSM }, // COMBINING ASTERISK BELOW + { 0x035A, BIDI_NSM }, // COMBINING DOUBLE RING BELOW + { 0x035B, BIDI_NSM }, // COMBINING ZIGZAG ABOVE + { 0x035C, BIDI_NSM }, // COMBINING DOUBLE BREVE BELOW + { 0x035D, BIDI_NSM }, // COMBINING DOUBLE BREVE + { 0x035E, BIDI_NSM }, // COMBINING DOUBLE MACRON + { 0x035F, BIDI_NSM }, // COMBINING DOUBLE MACRON BELOW + { 0x0360, BIDI_NSM }, // COMBINING DOUBLE TILDE + { 0x0361, BIDI_NSM }, // COMBINING DOUBLE INVERTED BREVE + { 0x0362, BIDI_NSM }, // COMBINING DOUBLE RIGHTWARDS ARROW BELOW + { 0x0363, BIDI_NSM }, // COMBINING LATIN SMALL LETTER A + { 0x0364, BIDI_NSM }, // COMBINING LATIN SMALL LETTER E + { 0x0365, BIDI_NSM }, // COMBINING LATIN SMALL LETTER I + { 0x0366, BIDI_NSM }, // COMBINING LATIN SMALL LETTER O + { 0x0367, BIDI_NSM }, // COMBINING LATIN SMALL LETTER U + { 0x0368, BIDI_NSM }, // COMBINING LATIN SMALL LETTER C + { 0x0369, BIDI_NSM }, // COMBINING LATIN SMALL LETTER D + { 0x036A, BIDI_NSM }, // COMBINING LATIN SMALL LETTER H + { 0x036B, BIDI_NSM }, // COMBINING LATIN SMALL LETTER M + { 0x036C, BIDI_NSM }, // COMBINING LATIN SMALL LETTER R + { 0x036D, BIDI_NSM }, // COMBINING LATIN SMALL LETTER T + { 0x036E, BIDI_NSM }, // COMBINING LATIN SMALL LETTER V + { 0x036F, BIDI_NSM }, // COMBINING LATIN SMALL LETTER X + { 0x0370, BIDI_L }, // GREEK CAPITAL LETTER HETA + { 0x0371, BIDI_L }, // GREEK SMALL LETTER HETA + { 0x0372, BIDI_L }, // GREEK CAPITAL LETTER ARCHAIC SAMPI + { 0x0373, BIDI_L }, // GREEK SMALL LETTER ARCHAIC SAMPI + { 0x0374, BIDI_ON }, // GREEK NUMERAL SIGN + { 0x0375, BIDI_ON }, // GREEK LOWER NUMERAL SIGN + { 0x0376, BIDI_L }, // GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA + { 0x0377, BIDI_L }, // GREEK SMALL LETTER PAMPHYLIAN DIGAMMA + { 0x037A, BIDI_L }, // GREEK YPOGEGRAMMENI + { 0x037B, BIDI_L }, // GREEK SMALL REVERSED LUNATE SIGMA SYMBOL + { 0x037C, BIDI_L }, // GREEK SMALL DOTTED LUNATE SIGMA SYMBOL + { 0x037D, BIDI_L }, // GREEK SMALL REVERSED DOTTED LUNATE SIGMA SYMBOL + { 0x037E, BIDI_ON }, // GREEK QUESTION MARK + { 0x037F, BIDI_L }, // GREEK CAPITAL LETTER YOT + { 0x0384, BIDI_ON }, // GREEK TONOS + { 0x0385, BIDI_ON }, // GREEK DIALYTIKA TONOS + { 0x0386, BIDI_L }, // GREEK CAPITAL LETTER ALPHA WITH TONOS + { 0x0387, BIDI_ON }, // GREEK ANO TELEIA + { 0x0388, BIDI_L }, // GREEK CAPITAL LETTER EPSILON WITH TONOS + { 0x0389, BIDI_L }, // GREEK CAPITAL LETTER ETA WITH TONOS + { 0x038A, BIDI_L }, // GREEK CAPITAL LETTER IOTA WITH TONOS + { 0x038C, BIDI_L }, // GREEK CAPITAL LETTER OMICRON WITH TONOS + { 0x038E, BIDI_L }, // GREEK CAPITAL LETTER UPSILON WITH TONOS + { 0x038F, BIDI_L }, // GREEK CAPITAL LETTER OMEGA WITH TONOS + { 0x0390, BIDI_L }, // GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS + { 0x0391, BIDI_L }, // GREEK CAPITAL LETTER ALPHA + { 0x0392, BIDI_L }, // GREEK CAPITAL LETTER BETA + { 0x0393, BIDI_L }, // GREEK CAPITAL LETTER GAMMA + { 0x0394, BIDI_L }, // GREEK CAPITAL LETTER DELTA + { 0x0395, BIDI_L }, // GREEK CAPITAL LETTER EPSILON + { 0x0396, BIDI_L }, // GREEK CAPITAL LETTER ZETA + { 0x0397, BIDI_L }, // GREEK CAPITAL LETTER ETA + { 0x0398, BIDI_L }, // GREEK CAPITAL LETTER THETA + { 0x0399, BIDI_L }, // GREEK CAPITAL LETTER IOTA + { 0x039A, BIDI_L }, // GREEK CAPITAL LETTER KAPPA + { 0x039B, BIDI_L }, // GREEK CAPITAL LETTER LAMDA + { 0x039C, BIDI_L }, // GREEK CAPITAL LETTER MU + { 0x039D, BIDI_L }, // GREEK CAPITAL LETTER NU + { 0x039E, BIDI_L }, // GREEK CAPITAL LETTER XI + { 0x039F, BIDI_L }, // GREEK CAPITAL LETTER OMICRON + { 0x03A0, BIDI_L }, // GREEK CAPITAL LETTER PI + { 0x03A1, BIDI_L }, // GREEK CAPITAL LETTER RHO + { 0x03A3, BIDI_L }, // GREEK CAPITAL LETTER SIGMA + { 0x03A4, BIDI_L }, // GREEK CAPITAL LETTER TAU + { 0x03A5, BIDI_L }, // GREEK CAPITAL LETTER UPSILON + { 0x03A6, BIDI_L }, // GREEK CAPITAL LETTER PHI + { 0x03A7, BIDI_L }, // GREEK CAPITAL LETTER CHI + { 0x03A8, BIDI_L }, // GREEK CAPITAL LETTER PSI + { 0x03A9, BIDI_L }, // GREEK CAPITAL LETTER OMEGA + { 0x03AA, BIDI_L }, // GREEK CAPITAL LETTER IOTA WITH DIALYTIKA + { 0x03AB, BIDI_L }, // GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA + { 0x03AC, BIDI_L }, // GREEK SMALL LETTER ALPHA WITH TONOS + { 0x03AD, BIDI_L }, // GREEK SMALL LETTER EPSILON WITH TONOS + { 0x03AE, BIDI_L }, // GREEK SMALL LETTER ETA WITH TONOS + { 0x03AF, BIDI_L }, // GREEK SMALL LETTER IOTA WITH TONOS + { 0x03B0, BIDI_L }, // GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS + { 0x03B1, BIDI_L }, // GREEK SMALL LETTER ALPHA + { 0x03B2, BIDI_L }, // GREEK SMALL LETTER BETA + { 0x03B3, BIDI_L }, // GREEK SMALL LETTER GAMMA + { 0x03B4, BIDI_L }, // GREEK SMALL LETTER DELTA + { 0x03B5, BIDI_L }, // GREEK SMALL LETTER EPSILON + { 0x03B6, BIDI_L }, // GREEK SMALL LETTER ZETA + { 0x03B7, BIDI_L }, // GREEK SMALL LETTER ETA + { 0x03B8, BIDI_L }, // GREEK SMALL LETTER THETA + { 0x03B9, BIDI_L }, // GREEK SMALL LETTER IOTA + { 0x03BA, BIDI_L }, // GREEK SMALL LETTER KAPPA + { 0x03BB, BIDI_L }, // GREEK SMALL LETTER LAMDA + { 0x03BC, BIDI_L }, // GREEK SMALL LETTER MU + { 0x03BD, BIDI_L }, // GREEK SMALL LETTER NU + { 0x03BE, BIDI_L }, // GREEK SMALL LETTER XI + { 0x03BF, BIDI_L }, // GREEK SMALL LETTER OMICRON + { 0x03C0, BIDI_L }, // GREEK SMALL LETTER PI + { 0x03C1, BIDI_L }, // GREEK SMALL LETTER RHO + { 0x03C2, BIDI_L }, // GREEK SMALL LETTER FINAL SIGMA + { 0x03C3, BIDI_L }, // GREEK SMALL LETTER SIGMA + { 0x03C4, BIDI_L }, // GREEK SMALL LETTER TAU + { 0x03C5, BIDI_L }, // GREEK SMALL LETTER UPSILON + { 0x03C6, BIDI_L }, // GREEK SMALL LETTER PHI + { 0x03C7, BIDI_L }, // GREEK SMALL LETTER CHI + { 0x03C8, BIDI_L }, // GREEK SMALL LETTER PSI + { 0x03C9, BIDI_L }, // GREEK SMALL LETTER OMEGA + { 0x03CA, BIDI_L }, // GREEK SMALL LETTER IOTA WITH DIALYTIKA + { 0x03CB, BIDI_L }, // GREEK SMALL LETTER UPSILON WITH DIALYTIKA + { 0x03CC, BIDI_L }, // GREEK SMALL LETTER OMICRON WITH TONOS + { 0x03CD, BIDI_L }, // GREEK SMALL LETTER UPSILON WITH TONOS + { 0x03CE, BIDI_L }, // GREEK SMALL LETTER OMEGA WITH TONOS + { 0x03CF, BIDI_L }, // GREEK CAPITAL KAI SYMBOL + { 0x03D0, BIDI_L }, // GREEK BETA SYMBOL + { 0x03D1, BIDI_L }, // GREEK THETA SYMBOL + { 0x03D2, BIDI_L }, // GREEK UPSILON WITH HOOK SYMBOL + { 0x03D3, BIDI_L }, // GREEK UPSILON WITH ACUTE AND HOOK SYMBOL + { 0x03D4, BIDI_L }, // GREEK UPSILON WITH DIAERESIS AND HOOK SYMBOL + { 0x03D5, BIDI_L }, // GREEK PHI SYMBOL + { 0x03D6, BIDI_L }, // GREEK PI SYMBOL + { 0x03D7, BIDI_L }, // GREEK KAI SYMBOL + { 0x03D8, BIDI_L }, // GREEK LETTER ARCHAIC KOPPA + { 0x03D9, BIDI_L }, // GREEK SMALL LETTER ARCHAIC KOPPA + { 0x03DA, BIDI_L }, // GREEK LETTER STIGMA + { 0x03DB, BIDI_L }, // GREEK SMALL LETTER STIGMA + { 0x03DC, BIDI_L }, // GREEK LETTER DIGAMMA + { 0x03DD, BIDI_L }, // GREEK SMALL LETTER DIGAMMA + { 0x03DE, BIDI_L }, // GREEK LETTER KOPPA + { 0x03DF, BIDI_L }, // GREEK SMALL LETTER KOPPA + { 0x03E0, BIDI_L }, // GREEK LETTER SAMPI + { 0x03E1, BIDI_L }, // GREEK SMALL LETTER SAMPI + { 0x03E2, BIDI_L }, // COPTIC CAPITAL LETTER SHEI + { 0x03E3, BIDI_L }, // COPTIC SMALL LETTER SHEI + { 0x03E4, BIDI_L }, // COPTIC CAPITAL LETTER FEI + { 0x03E5, BIDI_L }, // COPTIC SMALL LETTER FEI + { 0x03E6, BIDI_L }, // COPTIC CAPITAL LETTER KHEI + { 0x03E7, BIDI_L }, // COPTIC SMALL LETTER KHEI + { 0x03E8, BIDI_L }, // COPTIC CAPITAL LETTER HORI + { 0x03E9, BIDI_L }, // COPTIC SMALL LETTER HORI + { 0x03EA, BIDI_L }, // COPTIC CAPITAL LETTER GANGIA + { 0x03EB, BIDI_L }, // COPTIC SMALL LETTER GANGIA + { 0x03EC, BIDI_L }, // COPTIC CAPITAL LETTER SHIMA + { 0x03ED, BIDI_L }, // COPTIC SMALL LETTER SHIMA + { 0x03EE, BIDI_L }, // COPTIC CAPITAL LETTER DEI + { 0x03EF, BIDI_L }, // COPTIC SMALL LETTER DEI + { 0x03F0, BIDI_L }, // GREEK KAPPA SYMBOL + { 0x03F1, BIDI_L }, // GREEK RHO SYMBOL + { 0x03F2, BIDI_L }, // GREEK LUNATE SIGMA SYMBOL + { 0x03F3, BIDI_L }, // GREEK LETTER YOT + { 0x03F4, BIDI_L }, // GREEK CAPITAL THETA SYMBOL + { 0x03F5, BIDI_L }, // GREEK LUNATE EPSILON SYMBOL + { 0x03F6, BIDI_ON }, // GREEK REVERSED LUNATE EPSILON SYMBOL + { 0x03F7, BIDI_L }, // GREEK CAPITAL LETTER SHO + { 0x03F8, BIDI_L }, // GREEK SMALL LETTER SHO + { 0x03F9, BIDI_L }, // GREEK CAPITAL LUNATE SIGMA SYMBOL + { 0x03FA, BIDI_L }, // GREEK CAPITAL LETTER SAN + { 0x03FB, BIDI_L }, // GREEK SMALL LETTER SAN + { 0x03FC, BIDI_L }, // GREEK RHO WITH STROKE SYMBOL + { 0x03FD, BIDI_L }, // GREEK CAPITAL REVERSED LUNATE SIGMA SYMBOL + { 0x03FE, BIDI_L }, // GREEK CAPITAL DOTTED LUNATE SIGMA SYMBOL + { 0x03FF, BIDI_L }, // GREEK CAPITAL REVERSED DOTTED LUNATE SIGMA SYMBOL + { 0x0400, BIDI_L }, // CYRILLIC CAPITAL LETTER IE WITH GRAVE + { 0x0401, BIDI_L }, // CYRILLIC CAPITAL LETTER IO + { 0x0402, BIDI_L }, // CYRILLIC CAPITAL LETTER DJE + { 0x0403, BIDI_L }, // CYRILLIC CAPITAL LETTER GJE + { 0x0404, BIDI_L }, // CYRILLIC CAPITAL LETTER UKRAINIAN IE + { 0x0405, BIDI_L }, // CYRILLIC CAPITAL LETTER DZE + { 0x0406, BIDI_L }, // CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I + { 0x0407, BIDI_L }, // CYRILLIC CAPITAL LETTER YI + { 0x0408, BIDI_L }, // CYRILLIC CAPITAL LETTER JE + { 0x0409, BIDI_L }, // CYRILLIC CAPITAL LETTER LJE + { 0x040A, BIDI_L }, // CYRILLIC CAPITAL LETTER NJE + { 0x040B, BIDI_L }, // CYRILLIC CAPITAL LETTER TSHE + { 0x040C, BIDI_L }, // CYRILLIC CAPITAL LETTER KJE + { 0x040D, BIDI_L }, // CYRILLIC CAPITAL LETTER I WITH GRAVE + { 0x040E, BIDI_L }, // CYRILLIC CAPITAL LETTER SHORT U + { 0x040F, BIDI_L }, // CYRILLIC CAPITAL LETTER DZHE + { 0x0410, BIDI_L }, // CYRILLIC CAPITAL LETTER A + { 0x0411, BIDI_L }, // CYRILLIC CAPITAL LETTER BE + { 0x0412, BIDI_L }, // CYRILLIC CAPITAL LETTER VE + { 0x0413, BIDI_L }, // CYRILLIC CAPITAL LETTER GHE + { 0x0414, BIDI_L }, // CYRILLIC CAPITAL LETTER DE + { 0x0415, BIDI_L }, // CYRILLIC CAPITAL LETTER IE + { 0x0416, BIDI_L }, // CYRILLIC CAPITAL LETTER ZHE + { 0x0417, BIDI_L }, // CYRILLIC CAPITAL LETTER ZE + { 0x0418, BIDI_L }, // CYRILLIC CAPITAL LETTER I + { 0x0419, BIDI_L }, // CYRILLIC CAPITAL LETTER SHORT I + { 0x041A, BIDI_L }, // CYRILLIC CAPITAL LETTER KA + { 0x041B, BIDI_L }, // CYRILLIC CAPITAL LETTER EL + { 0x041C, BIDI_L }, // CYRILLIC CAPITAL LETTER EM + { 0x041D, BIDI_L }, // CYRILLIC CAPITAL LETTER EN + { 0x041E, BIDI_L }, // CYRILLIC CAPITAL LETTER O + { 0x041F, BIDI_L }, // CYRILLIC CAPITAL LETTER PE + { 0x0420, BIDI_L }, // CYRILLIC CAPITAL LETTER ER + { 0x0421, BIDI_L }, // CYRILLIC CAPITAL LETTER ES + { 0x0422, BIDI_L }, // CYRILLIC CAPITAL LETTER TE + { 0x0423, BIDI_L }, // CYRILLIC CAPITAL LETTER U + { 0x0424, BIDI_L }, // CYRILLIC CAPITAL LETTER EF + { 0x0425, BIDI_L }, // CYRILLIC CAPITAL LETTER HA + { 0x0426, BIDI_L }, // CYRILLIC CAPITAL LETTER TSE + { 0x0427, BIDI_L }, // CYRILLIC CAPITAL LETTER CHE + { 0x0428, BIDI_L }, // CYRILLIC CAPITAL LETTER SHA + { 0x0429, BIDI_L }, // CYRILLIC CAPITAL LETTER SHCHA + { 0x042A, BIDI_L }, // CYRILLIC CAPITAL LETTER HARD SIGN + { 0x042B, BIDI_L }, // CYRILLIC CAPITAL LETTER YERU + { 0x042C, BIDI_L }, // CYRILLIC CAPITAL LETTER SOFT SIGN + { 0x042D, BIDI_L }, // CYRILLIC CAPITAL LETTER E + { 0x042E, BIDI_L }, // CYRILLIC CAPITAL LETTER YU + { 0x042F, BIDI_L }, // CYRILLIC CAPITAL LETTER YA + { 0x0430, BIDI_L }, // CYRILLIC SMALL LETTER A + { 0x0431, BIDI_L }, // CYRILLIC SMALL LETTER BE + { 0x0432, BIDI_L }, // CYRILLIC SMALL LETTER VE + { 0x0433, BIDI_L }, // CYRILLIC SMALL LETTER GHE + { 0x0434, BIDI_L }, // CYRILLIC SMALL LETTER DE + { 0x0435, BIDI_L }, // CYRILLIC SMALL LETTER IE + { 0x0436, BIDI_L }, // CYRILLIC SMALL LETTER ZHE + { 0x0437, BIDI_L }, // CYRILLIC SMALL LETTER ZE + { 0x0438, BIDI_L }, // CYRILLIC SMALL LETTER I + { 0x0439, BIDI_L }, // CYRILLIC SMALL LETTER SHORT I + { 0x043A, BIDI_L }, // CYRILLIC SMALL LETTER KA + { 0x043B, BIDI_L }, // CYRILLIC SMALL LETTER EL + { 0x043C, BIDI_L }, // CYRILLIC SMALL LETTER EM + { 0x043D, BIDI_L }, // CYRILLIC SMALL LETTER EN + { 0x043E, BIDI_L }, // CYRILLIC SMALL LETTER O + { 0x043F, BIDI_L }, // CYRILLIC SMALL LETTER PE + { 0x0440, BIDI_L }, // CYRILLIC SMALL LETTER ER + { 0x0441, BIDI_L }, // CYRILLIC SMALL LETTER ES + { 0x0442, BIDI_L }, // CYRILLIC SMALL LETTER TE + { 0x0443, BIDI_L }, // CYRILLIC SMALL LETTER U + { 0x0444, BIDI_L }, // CYRILLIC SMALL LETTER EF + { 0x0445, BIDI_L }, // CYRILLIC SMALL LETTER HA + { 0x0446, BIDI_L }, // CYRILLIC SMALL LETTER TSE + { 0x0447, BIDI_L }, // CYRILLIC SMALL LETTER CHE + { 0x0448, BIDI_L }, // CYRILLIC SMALL LETTER SHA + { 0x0449, BIDI_L }, // CYRILLIC SMALL LETTER SHCHA + { 0x044A, BIDI_L }, // CYRILLIC SMALL LETTER HARD SIGN + { 0x044B, BIDI_L }, // CYRILLIC SMALL LETTER YERU + { 0x044C, BIDI_L }, // CYRILLIC SMALL LETTER SOFT SIGN + { 0x044D, BIDI_L }, // CYRILLIC SMALL LETTER E + { 0x044E, BIDI_L }, // CYRILLIC SMALL LETTER YU + { 0x044F, BIDI_L }, // CYRILLIC SMALL LETTER YA + { 0x0450, BIDI_L }, // CYRILLIC SMALL LETTER IE WITH GRAVE + { 0x0451, BIDI_L }, // CYRILLIC SMALL LETTER IO + { 0x0452, BIDI_L }, // CYRILLIC SMALL LETTER DJE + { 0x0453, BIDI_L }, // CYRILLIC SMALL LETTER GJE + { 0x0454, BIDI_L }, // CYRILLIC SMALL LETTER UKRAINIAN IE + { 0x0455, BIDI_L }, // CYRILLIC SMALL LETTER DZE + { 0x0456, BIDI_L }, // CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I + { 0x0457, BIDI_L }, // CYRILLIC SMALL LETTER YI + { 0x0458, BIDI_L }, // CYRILLIC SMALL LETTER JE + { 0x0459, BIDI_L }, // CYRILLIC SMALL LETTER LJE + { 0x045A, BIDI_L }, // CYRILLIC SMALL LETTER NJE + { 0x045B, BIDI_L }, // CYRILLIC SMALL LETTER TSHE + { 0x045C, BIDI_L }, // CYRILLIC SMALL LETTER KJE + { 0x045D, BIDI_L }, // CYRILLIC SMALL LETTER I WITH GRAVE + { 0x045E, BIDI_L }, // CYRILLIC SMALL LETTER SHORT U + { 0x045F, BIDI_L }, // CYRILLIC SMALL LETTER DZHE + { 0x0460, BIDI_L }, // CYRILLIC CAPITAL LETTER OMEGA + { 0x0461, BIDI_L }, // CYRILLIC SMALL LETTER OMEGA + { 0x0462, BIDI_L }, // CYRILLIC CAPITAL LETTER YAT + { 0x0463, BIDI_L }, // CYRILLIC SMALL LETTER YAT + { 0x0464, BIDI_L }, // CYRILLIC CAPITAL LETTER IOTIFIED E + { 0x0465, BIDI_L }, // CYRILLIC SMALL LETTER IOTIFIED E + { 0x0466, BIDI_L }, // CYRILLIC CAPITAL LETTER LITTLE YUS + { 0x0467, BIDI_L }, // CYRILLIC SMALL LETTER LITTLE YUS + { 0x0468, BIDI_L }, // CYRILLIC CAPITAL LETTER IOTIFIED LITTLE YUS + { 0x0469, BIDI_L }, // CYRILLIC SMALL LETTER IOTIFIED LITTLE YUS + { 0x046A, BIDI_L }, // CYRILLIC CAPITAL LETTER BIG YUS + { 0x046B, BIDI_L }, // CYRILLIC SMALL LETTER BIG YUS + { 0x046C, BIDI_L }, // CYRILLIC CAPITAL LETTER IOTIFIED BIG YUS + { 0x046D, BIDI_L }, // CYRILLIC SMALL LETTER IOTIFIED BIG YUS + { 0x046E, BIDI_L }, // CYRILLIC CAPITAL LETTER KSI + { 0x046F, BIDI_L }, // CYRILLIC SMALL LETTER KSI + { 0x0470, BIDI_L }, // CYRILLIC CAPITAL LETTER PSI + { 0x0471, BIDI_L }, // CYRILLIC SMALL LETTER PSI + { 0x0472, BIDI_L }, // CYRILLIC CAPITAL LETTER FITA + { 0x0473, BIDI_L }, // CYRILLIC SMALL LETTER FITA + { 0x0474, BIDI_L }, // CYRILLIC CAPITAL LETTER IZHITSA + { 0x0475, BIDI_L }, // CYRILLIC SMALL LETTER IZHITSA + { 0x0476, BIDI_L }, // CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT + { 0x0477, BIDI_L }, // CYRILLIC SMALL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT + { 0x0478, BIDI_L }, // CYRILLIC CAPITAL LETTER UK + { 0x0479, BIDI_L }, // CYRILLIC SMALL LETTER UK + { 0x047A, BIDI_L }, // CYRILLIC CAPITAL LETTER ROUND OMEGA + { 0x047B, BIDI_L }, // CYRILLIC SMALL LETTER ROUND OMEGA + { 0x047C, BIDI_L }, // CYRILLIC CAPITAL LETTER OMEGA WITH TITLO + { 0x047D, BIDI_L }, // CYRILLIC SMALL LETTER OMEGA WITH TITLO + { 0x047E, BIDI_L }, // CYRILLIC CAPITAL LETTER OT + { 0x047F, BIDI_L }, // CYRILLIC SMALL LETTER OT + { 0x0480, BIDI_L }, // CYRILLIC CAPITAL LETTER KOPPA + { 0x0481, BIDI_L }, // CYRILLIC SMALL LETTER KOPPA + { 0x0482, BIDI_L }, // CYRILLIC THOUSANDS SIGN + { 0x0483, BIDI_NSM }, // COMBINING CYRILLIC TITLO + { 0x0484, BIDI_NSM }, // COMBINING CYRILLIC PALATALIZATION + { 0x0485, BIDI_NSM }, // COMBINING CYRILLIC DASIA PNEUMATA + { 0x0486, BIDI_NSM }, // COMBINING CYRILLIC PSILI PNEUMATA + { 0x0487, BIDI_NSM }, // COMBINING CYRILLIC POKRYTIE + { 0x0488, BIDI_NSM }, // COMBINING CYRILLIC HUNDRED THOUSANDS SIGN + { 0x0489, BIDI_NSM }, // COMBINING CYRILLIC MILLIONS SIGN + { 0x048A, BIDI_L }, // CYRILLIC CAPITAL LETTER SHORT I WITH TAIL + { 0x048B, BIDI_L }, // CYRILLIC SMALL LETTER SHORT I WITH TAIL + { 0x048C, BIDI_L }, // CYRILLIC CAPITAL LETTER SEMISOFT SIGN + { 0x048D, BIDI_L }, // CYRILLIC SMALL LETTER SEMISOFT SIGN + { 0x048E, BIDI_L }, // CYRILLIC CAPITAL LETTER ER WITH TICK + { 0x048F, BIDI_L }, // CYRILLIC SMALL LETTER ER WITH TICK + { 0x0490, BIDI_L }, // CYRILLIC CAPITAL LETTER GHE WITH UPTURN + { 0x0491, BIDI_L }, // CYRILLIC SMALL LETTER GHE WITH UPTURN + { 0x0492, BIDI_L }, // CYRILLIC CAPITAL LETTER GHE WITH STROKE + { 0x0493, BIDI_L }, // CYRILLIC SMALL LETTER GHE WITH STROKE + { 0x0494, BIDI_L }, // CYRILLIC CAPITAL LETTER GHE WITH MIDDLE HOOK + { 0x0495, BIDI_L }, // CYRILLIC SMALL LETTER GHE WITH MIDDLE HOOK + { 0x0496, BIDI_L }, // CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER + { 0x0497, BIDI_L }, // CYRILLIC SMALL LETTER ZHE WITH DESCENDER + { 0x0498, BIDI_L }, // CYRILLIC CAPITAL LETTER ZE WITH DESCENDER + { 0x0499, BIDI_L }, // CYRILLIC SMALL LETTER ZE WITH DESCENDER + { 0x049A, BIDI_L }, // CYRILLIC CAPITAL LETTER KA WITH DESCENDER + { 0x049B, BIDI_L }, // CYRILLIC SMALL LETTER KA WITH DESCENDER + { 0x049C, BIDI_L }, // CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE + { 0x049D, BIDI_L }, // CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE + { 0x049E, BIDI_L }, // CYRILLIC CAPITAL LETTER KA WITH STROKE + { 0x049F, BIDI_L }, // CYRILLIC SMALL LETTER KA WITH STROKE + { 0x04A0, BIDI_L }, // CYRILLIC CAPITAL LETTER BASHKIR KA + { 0x04A1, BIDI_L }, // CYRILLIC SMALL LETTER BASHKIR KA + { 0x04A2, BIDI_L }, // CYRILLIC CAPITAL LETTER EN WITH DESCENDER + { 0x04A3, BIDI_L }, // CYRILLIC SMALL LETTER EN WITH DESCENDER + { 0x04A4, BIDI_L }, // CYRILLIC CAPITAL LIGATURE EN GHE + { 0x04A5, BIDI_L }, // CYRILLIC SMALL LIGATURE EN GHE + { 0x04A6, BIDI_L }, // CYRILLIC CAPITAL LETTER PE WITH MIDDLE HOOK + { 0x04A7, BIDI_L }, // CYRILLIC SMALL LETTER PE WITH MIDDLE HOOK + { 0x04A8, BIDI_L }, // CYRILLIC CAPITAL LETTER ABKHASIAN HA + { 0x04A9, BIDI_L }, // CYRILLIC SMALL LETTER ABKHASIAN HA + { 0x04AA, BIDI_L }, // CYRILLIC CAPITAL LETTER ES WITH DESCENDER + { 0x04AB, BIDI_L }, // CYRILLIC SMALL LETTER ES WITH DESCENDER + { 0x04AC, BIDI_L }, // CYRILLIC CAPITAL LETTER TE WITH DESCENDER + { 0x04AD, BIDI_L }, // CYRILLIC SMALL LETTER TE WITH DESCENDER + { 0x04AE, BIDI_L }, // CYRILLIC CAPITAL LETTER STRAIGHT U + { 0x04AF, BIDI_L }, // CYRILLIC SMALL LETTER STRAIGHT U + { 0x04B0, BIDI_L }, // CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE + { 0x04B1, BIDI_L }, // CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE + { 0x04B2, BIDI_L }, // CYRILLIC CAPITAL LETTER HA WITH DESCENDER + { 0x04B3, BIDI_L }, // CYRILLIC SMALL LETTER HA WITH DESCENDER + { 0x04B4, BIDI_L }, // CYRILLIC CAPITAL LIGATURE TE TSE + { 0x04B5, BIDI_L }, // CYRILLIC SMALL LIGATURE TE TSE + { 0x04B6, BIDI_L }, // CYRILLIC CAPITAL LETTER CHE WITH DESCENDER + { 0x04B7, BIDI_L }, // CYRILLIC SMALL LETTER CHE WITH DESCENDER + { 0x04B8, BIDI_L }, // CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE + { 0x04B9, BIDI_L }, // CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE + { 0x04BA, BIDI_L }, // CYRILLIC CAPITAL LETTER SHHA + { 0x04BB, BIDI_L }, // CYRILLIC SMALL LETTER SHHA + { 0x04BC, BIDI_L }, // CYRILLIC CAPITAL LETTER ABKHASIAN CHE + { 0x04BD, BIDI_L }, // CYRILLIC SMALL LETTER ABKHASIAN CHE + { 0x04BE, BIDI_L }, // CYRILLIC CAPITAL LETTER ABKHASIAN CHE WITH DESCENDER + { 0x04BF, BIDI_L }, // CYRILLIC SMALL LETTER ABKHASIAN CHE WITH DESCENDER + { 0x04C0, BIDI_L }, // CYRILLIC LETTER PALOCHKA + { 0x04C1, BIDI_L }, // CYRILLIC CAPITAL LETTER ZHE WITH BREVE + { 0x04C2, BIDI_L }, // CYRILLIC SMALL LETTER ZHE WITH BREVE + { 0x04C3, BIDI_L }, // CYRILLIC CAPITAL LETTER KA WITH HOOK + { 0x04C4, BIDI_L }, // CYRILLIC SMALL LETTER KA WITH HOOK + { 0x04C5, BIDI_L }, // CYRILLIC CAPITAL LETTER EL WITH TAIL + { 0x04C6, BIDI_L }, // CYRILLIC SMALL LETTER EL WITH TAIL + { 0x04C7, BIDI_L }, // CYRILLIC CAPITAL LETTER EN WITH HOOK + { 0x04C8, BIDI_L }, // CYRILLIC SMALL LETTER EN WITH HOOK + { 0x04C9, BIDI_L }, // CYRILLIC CAPITAL LETTER EN WITH TAIL + { 0x04CA, BIDI_L }, // CYRILLIC SMALL LETTER EN WITH TAIL + { 0x04CB, BIDI_L }, // CYRILLIC CAPITAL LETTER KHAKASSIAN CHE + { 0x04CC, BIDI_L }, // CYRILLIC SMALL LETTER KHAKASSIAN CHE + { 0x04CD, BIDI_L }, // CYRILLIC CAPITAL LETTER EM WITH TAIL + { 0x04CE, BIDI_L }, // CYRILLIC SMALL LETTER EM WITH TAIL + { 0x04CF, BIDI_L }, // CYRILLIC SMALL LETTER PALOCHKA + { 0x04D0, BIDI_L }, // CYRILLIC CAPITAL LETTER A WITH BREVE + { 0x04D1, BIDI_L }, // CYRILLIC SMALL LETTER A WITH BREVE + { 0x04D2, BIDI_L }, // CYRILLIC CAPITAL LETTER A WITH DIAERESIS + { 0x04D3, BIDI_L }, // CYRILLIC SMALL LETTER A WITH DIAERESIS + { 0x04D4, BIDI_L }, // CYRILLIC CAPITAL LIGATURE A IE + { 0x04D5, BIDI_L }, // CYRILLIC SMALL LIGATURE A IE + { 0x04D6, BIDI_L }, // CYRILLIC CAPITAL LETTER IE WITH BREVE + { 0x04D7, BIDI_L }, // CYRILLIC SMALL LETTER IE WITH BREVE + { 0x04D8, BIDI_L }, // CYRILLIC CAPITAL LETTER SCHWA + { 0x04D9, BIDI_L }, // CYRILLIC SMALL LETTER SCHWA + { 0x04DA, BIDI_L }, // CYRILLIC CAPITAL LETTER SCHWA WITH DIAERESIS + { 0x04DB, BIDI_L }, // CYRILLIC SMALL LETTER SCHWA WITH DIAERESIS + { 0x04DC, BIDI_L }, // CYRILLIC CAPITAL LETTER ZHE WITH DIAERESIS + { 0x04DD, BIDI_L }, // CYRILLIC SMALL LETTER ZHE WITH DIAERESIS + { 0x04DE, BIDI_L }, // CYRILLIC CAPITAL LETTER ZE WITH DIAERESIS + { 0x04DF, BIDI_L }, // CYRILLIC SMALL LETTER ZE WITH DIAERESIS + { 0x04E0, BIDI_L }, // CYRILLIC CAPITAL LETTER ABKHASIAN DZE + { 0x04E1, BIDI_L }, // CYRILLIC SMALL LETTER ABKHASIAN DZE + { 0x04E2, BIDI_L }, // CYRILLIC CAPITAL LETTER I WITH MACRON + { 0x04E3, BIDI_L }, // CYRILLIC SMALL LETTER I WITH MACRON + { 0x04E4, BIDI_L }, // CYRILLIC CAPITAL LETTER I WITH DIAERESIS + { 0x04E5, BIDI_L }, // CYRILLIC SMALL LETTER I WITH DIAERESIS + { 0x04E6, BIDI_L }, // CYRILLIC CAPITAL LETTER O WITH DIAERESIS + { 0x04E7, BIDI_L }, // CYRILLIC SMALL LETTER O WITH DIAERESIS + { 0x04E8, BIDI_L }, // CYRILLIC CAPITAL LETTER BARRED O + { 0x04E9, BIDI_L }, // CYRILLIC SMALL LETTER BARRED O + { 0x04EA, BIDI_L }, // CYRILLIC CAPITAL LETTER BARRED O WITH DIAERESIS + { 0x04EB, BIDI_L }, // CYRILLIC SMALL LETTER BARRED O WITH DIAERESIS + { 0x04EC, BIDI_L }, // CYRILLIC CAPITAL LETTER E WITH DIAERESIS + { 0x04ED, BIDI_L }, // CYRILLIC SMALL LETTER E WITH DIAERESIS + { 0x04EE, BIDI_L }, // CYRILLIC CAPITAL LETTER U WITH MACRON + { 0x04EF, BIDI_L }, // CYRILLIC SMALL LETTER U WITH MACRON + { 0x04F0, BIDI_L }, // CYRILLIC CAPITAL LETTER U WITH DIAERESIS + { 0x04F1, BIDI_L }, // CYRILLIC SMALL LETTER U WITH DIAERESIS + { 0x04F2, BIDI_L }, // CYRILLIC CAPITAL LETTER U WITH DOUBLE ACUTE + { 0x04F3, BIDI_L }, // CYRILLIC SMALL LETTER U WITH DOUBLE ACUTE + { 0x04F4, BIDI_L }, // CYRILLIC CAPITAL LETTER CHE WITH DIAERESIS + { 0x04F5, BIDI_L }, // CYRILLIC SMALL LETTER CHE WITH DIAERESIS + { 0x04F6, BIDI_L }, // CYRILLIC CAPITAL LETTER GHE WITH DESCENDER + { 0x04F7, BIDI_L }, // CYRILLIC SMALL LETTER GHE WITH DESCENDER + { 0x04F8, BIDI_L }, // CYRILLIC CAPITAL LETTER YERU WITH DIAERESIS + { 0x04F9, BIDI_L }, // CYRILLIC SMALL LETTER YERU WITH DIAERESIS + { 0x04FA, BIDI_L }, // CYRILLIC CAPITAL LETTER GHE WITH STROKE AND HOOK + { 0x04FB, BIDI_L }, // CYRILLIC SMALL LETTER GHE WITH STROKE AND HOOK + { 0x04FC, BIDI_L }, // CYRILLIC CAPITAL LETTER HA WITH HOOK + { 0x04FD, BIDI_L }, // CYRILLIC SMALL LETTER HA WITH HOOK + { 0x04FE, BIDI_L }, // CYRILLIC CAPITAL LETTER HA WITH STROKE + { 0x04FF, BIDI_L }, // CYRILLIC SMALL LETTER HA WITH STROKE + { 0x0500, BIDI_L }, // CYRILLIC CAPITAL LETTER KOMI DE + { 0x0501, BIDI_L }, // CYRILLIC SMALL LETTER KOMI DE + { 0x0502, BIDI_L }, // CYRILLIC CAPITAL LETTER KOMI DJE + { 0x0503, BIDI_L }, // CYRILLIC SMALL LETTER KOMI DJE + { 0x0504, BIDI_L }, // CYRILLIC CAPITAL LETTER KOMI ZJE + { 0x0505, BIDI_L }, // CYRILLIC SMALL LETTER KOMI ZJE + { 0x0506, BIDI_L }, // CYRILLIC CAPITAL LETTER KOMI DZJE + { 0x0507, BIDI_L }, // CYRILLIC SMALL LETTER KOMI DZJE + { 0x0508, BIDI_L }, // CYRILLIC CAPITAL LETTER KOMI LJE + { 0x0509, BIDI_L }, // CYRILLIC SMALL LETTER KOMI LJE + { 0x050A, BIDI_L }, // CYRILLIC CAPITAL LETTER KOMI NJE + { 0x050B, BIDI_L }, // CYRILLIC SMALL LETTER KOMI NJE + { 0x050C, BIDI_L }, // CYRILLIC CAPITAL LETTER KOMI SJE + { 0x050D, BIDI_L }, // CYRILLIC SMALL LETTER KOMI SJE + { 0x050E, BIDI_L }, // CYRILLIC CAPITAL LETTER KOMI TJE + { 0x050F, BIDI_L }, // CYRILLIC SMALL LETTER KOMI TJE + { 0x0510, BIDI_L }, // CYRILLIC CAPITAL LETTER REVERSED ZE + { 0x0511, BIDI_L }, // CYRILLIC SMALL LETTER REVERSED ZE + { 0x0512, BIDI_L }, // CYRILLIC CAPITAL LETTER EL WITH HOOK + { 0x0513, BIDI_L }, // CYRILLIC SMALL LETTER EL WITH HOOK + { 0x0514, BIDI_L }, // CYRILLIC CAPITAL LETTER LHA + { 0x0515, BIDI_L }, // CYRILLIC SMALL LETTER LHA + { 0x0516, BIDI_L }, // CYRILLIC CAPITAL LETTER RHA + { 0x0517, BIDI_L }, // CYRILLIC SMALL LETTER RHA + { 0x0518, BIDI_L }, // CYRILLIC CAPITAL LETTER YAE + { 0x0519, BIDI_L }, // CYRILLIC SMALL LETTER YAE + { 0x051A, BIDI_L }, // CYRILLIC CAPITAL LETTER QA + { 0x051B, BIDI_L }, // CYRILLIC SMALL LETTER QA + { 0x051C, BIDI_L }, // CYRILLIC CAPITAL LETTER WE + { 0x051D, BIDI_L }, // CYRILLIC SMALL LETTER WE + { 0x051E, BIDI_L }, // CYRILLIC CAPITAL LETTER ALEUT KA + { 0x051F, BIDI_L }, // CYRILLIC SMALL LETTER ALEUT KA + { 0x0520, BIDI_L }, // CYRILLIC CAPITAL LETTER EL WITH MIDDLE HOOK + { 0x0521, BIDI_L }, // CYRILLIC SMALL LETTER EL WITH MIDDLE HOOK + { 0x0522, BIDI_L }, // CYRILLIC CAPITAL LETTER EN WITH MIDDLE HOOK + { 0x0523, BIDI_L }, // CYRILLIC SMALL LETTER EN WITH MIDDLE HOOK + { 0x0524, BIDI_L }, // CYRILLIC CAPITAL LETTER PE WITH DESCENDER + { 0x0525, BIDI_L }, // CYRILLIC SMALL LETTER PE WITH DESCENDER + { 0x0526, BIDI_L }, // CYRILLIC CAPITAL LETTER SHHA WITH DESCENDER + { 0x0527, BIDI_L }, // CYRILLIC SMALL LETTER SHHA WITH DESCENDER + { 0x0528, BIDI_L }, // CYRILLIC CAPITAL LETTER EN WITH LEFT HOOK + { 0x0529, BIDI_L }, // CYRILLIC SMALL LETTER EN WITH LEFT HOOK + { 0x052A, BIDI_L }, // CYRILLIC CAPITAL LETTER DZZHE + { 0x052B, BIDI_L }, // CYRILLIC SMALL LETTER DZZHE + { 0x052C, BIDI_L }, // CYRILLIC CAPITAL LETTER DCHE + { 0x052D, BIDI_L }, // CYRILLIC SMALL LETTER DCHE + { 0x052E, BIDI_L }, // CYRILLIC CAPITAL LETTER EL WITH DESCENDER + { 0x052F, BIDI_L }, // CYRILLIC SMALL LETTER EL WITH DESCENDER + { 0x0531, BIDI_L }, // ARMENIAN CAPITAL LETTER AYB + { 0x0532, BIDI_L }, // ARMENIAN CAPITAL LETTER BEN + { 0x0533, BIDI_L }, // ARMENIAN CAPITAL LETTER GIM + { 0x0534, BIDI_L }, // ARMENIAN CAPITAL LETTER DA + { 0x0535, BIDI_L }, // ARMENIAN CAPITAL LETTER ECH + { 0x0536, BIDI_L }, // ARMENIAN CAPITAL LETTER ZA + { 0x0537, BIDI_L }, // ARMENIAN CAPITAL LETTER EH + { 0x0538, BIDI_L }, // ARMENIAN CAPITAL LETTER ET + { 0x0539, BIDI_L }, // ARMENIAN CAPITAL LETTER TO + { 0x053A, BIDI_L }, // ARMENIAN CAPITAL LETTER ZHE + { 0x053B, BIDI_L }, // ARMENIAN CAPITAL LETTER INI + { 0x053C, BIDI_L }, // ARMENIAN CAPITAL LETTER LIWN + { 0x053D, BIDI_L }, // ARMENIAN CAPITAL LETTER XEH + { 0x053E, BIDI_L }, // ARMENIAN CAPITAL LETTER CA + { 0x053F, BIDI_L }, // ARMENIAN CAPITAL LETTER KEN + { 0x0540, BIDI_L }, // ARMENIAN CAPITAL LETTER HO + { 0x0541, BIDI_L }, // ARMENIAN CAPITAL LETTER JA + { 0x0542, BIDI_L }, // ARMENIAN CAPITAL LETTER GHAD + { 0x0543, BIDI_L }, // ARMENIAN CAPITAL LETTER CHEH + { 0x0544, BIDI_L }, // ARMENIAN CAPITAL LETTER MEN + { 0x0545, BIDI_L }, // ARMENIAN CAPITAL LETTER YI + { 0x0546, BIDI_L }, // ARMENIAN CAPITAL LETTER NOW + { 0x0547, BIDI_L }, // ARMENIAN CAPITAL LETTER SHA + { 0x0548, BIDI_L }, // ARMENIAN CAPITAL LETTER VO + { 0x0549, BIDI_L }, // ARMENIAN CAPITAL LETTER CHA + { 0x054A, BIDI_L }, // ARMENIAN CAPITAL LETTER PEH + { 0x054B, BIDI_L }, // ARMENIAN CAPITAL LETTER JHEH + { 0x054C, BIDI_L }, // ARMENIAN CAPITAL LETTER RA + { 0x054D, BIDI_L }, // ARMENIAN CAPITAL LETTER SEH + { 0x054E, BIDI_L }, // ARMENIAN CAPITAL LETTER VEW + { 0x054F, BIDI_L }, // ARMENIAN CAPITAL LETTER TIWN + { 0x0550, BIDI_L }, // ARMENIAN CAPITAL LETTER REH + { 0x0551, BIDI_L }, // ARMENIAN CAPITAL LETTER CO + { 0x0552, BIDI_L }, // ARMENIAN CAPITAL LETTER YIWN + { 0x0553, BIDI_L }, // ARMENIAN CAPITAL LETTER PIWR + { 0x0554, BIDI_L }, // ARMENIAN CAPITAL LETTER KEH + { 0x0555, BIDI_L }, // ARMENIAN CAPITAL LETTER OH + { 0x0556, BIDI_L }, // ARMENIAN CAPITAL LETTER FEH + { 0x0559, BIDI_L }, // ARMENIAN MODIFIER LETTER LEFT HALF RING + { 0x055A, BIDI_L }, // ARMENIAN APOSTROPHE + { 0x055B, BIDI_L }, // ARMENIAN EMPHASIS MARK + { 0x055C, BIDI_L }, // ARMENIAN EXCLAMATION MARK + { 0x055D, BIDI_L }, // ARMENIAN COMMA + { 0x055E, BIDI_L }, // ARMENIAN QUESTION MARK + { 0x055F, BIDI_L }, // ARMENIAN ABBREVIATION MARK + { 0x0561, BIDI_L }, // ARMENIAN SMALL LETTER AYB + { 0x0562, BIDI_L }, // ARMENIAN SMALL LETTER BEN + { 0x0563, BIDI_L }, // ARMENIAN SMALL LETTER GIM + { 0x0564, BIDI_L }, // ARMENIAN SMALL LETTER DA + { 0x0565, BIDI_L }, // ARMENIAN SMALL LETTER ECH + { 0x0566, BIDI_L }, // ARMENIAN SMALL LETTER ZA + { 0x0567, BIDI_L }, // ARMENIAN SMALL LETTER EH + { 0x0568, BIDI_L }, // ARMENIAN SMALL LETTER ET + { 0x0569, BIDI_L }, // ARMENIAN SMALL LETTER TO + { 0x056A, BIDI_L }, // ARMENIAN SMALL LETTER ZHE + { 0x056B, BIDI_L }, // ARMENIAN SMALL LETTER INI + { 0x056C, BIDI_L }, // ARMENIAN SMALL LETTER LIWN + { 0x056D, BIDI_L }, // ARMENIAN SMALL LETTER XEH + { 0x056E, BIDI_L }, // ARMENIAN SMALL LETTER CA + { 0x056F, BIDI_L }, // ARMENIAN SMALL LETTER KEN + { 0x0570, BIDI_L }, // ARMENIAN SMALL LETTER HO + { 0x0571, BIDI_L }, // ARMENIAN SMALL LETTER JA + { 0x0572, BIDI_L }, // ARMENIAN SMALL LETTER GHAD + { 0x0573, BIDI_L }, // ARMENIAN SMALL LETTER CHEH + { 0x0574, BIDI_L }, // ARMENIAN SMALL LETTER MEN + { 0x0575, BIDI_L }, // ARMENIAN SMALL LETTER YI + { 0x0576, BIDI_L }, // ARMENIAN SMALL LETTER NOW + { 0x0577, BIDI_L }, // ARMENIAN SMALL LETTER SHA + { 0x0578, BIDI_L }, // ARMENIAN SMALL LETTER VO + { 0x0579, BIDI_L }, // ARMENIAN SMALL LETTER CHA + { 0x057A, BIDI_L }, // ARMENIAN SMALL LETTER PEH + { 0x057B, BIDI_L }, // ARMENIAN SMALL LETTER JHEH + { 0x057C, BIDI_L }, // ARMENIAN SMALL LETTER RA + { 0x057D, BIDI_L }, // ARMENIAN SMALL LETTER SEH + { 0x057E, BIDI_L }, // ARMENIAN SMALL LETTER VEW + { 0x057F, BIDI_L }, // ARMENIAN SMALL LETTER TIWN + { 0x0580, BIDI_L }, // ARMENIAN SMALL LETTER REH + { 0x0581, BIDI_L }, // ARMENIAN SMALL LETTER CO + { 0x0582, BIDI_L }, // ARMENIAN SMALL LETTER YIWN + { 0x0583, BIDI_L }, // ARMENIAN SMALL LETTER PIWR + { 0x0584, BIDI_L }, // ARMENIAN SMALL LETTER KEH + { 0x0585, BIDI_L }, // ARMENIAN SMALL LETTER OH + { 0x0586, BIDI_L }, // ARMENIAN SMALL LETTER FEH + { 0x0587, BIDI_L }, // ARMENIAN SMALL LIGATURE ECH YIWN + { 0x0589, BIDI_L }, // ARMENIAN FULL STOP + { 0x058A, BIDI_ON }, // ARMENIAN HYPHEN + { 0x058D, BIDI_ON }, // RIGHT-FACING ARMENIAN ETERNITY SIGN + { 0x058E, BIDI_ON }, // LEFT-FACING ARMENIAN ETERNITY SIGN + { 0x058F, BIDI_ET }, // ARMENIAN DRAM SIGN + { 0x0591, BIDI_NSM }, // HEBREW ACCENT ETNAHTA + { 0x0592, BIDI_NSM }, // HEBREW ACCENT SEGOL + { 0x0593, BIDI_NSM }, // HEBREW ACCENT SHALSHELET + { 0x0594, BIDI_NSM }, // HEBREW ACCENT ZAQEF QATAN + { 0x0595, BIDI_NSM }, // HEBREW ACCENT ZAQEF GADOL + { 0x0596, BIDI_NSM }, // HEBREW ACCENT TIPEHA + { 0x0597, BIDI_NSM }, // HEBREW ACCENT REVIA + { 0x0598, BIDI_NSM }, // HEBREW ACCENT ZARQA + { 0x0599, BIDI_NSM }, // HEBREW ACCENT PASHTA + { 0x059A, BIDI_NSM }, // HEBREW ACCENT YETIV + { 0x059B, BIDI_NSM }, // HEBREW ACCENT TEVIR + { 0x059C, BIDI_NSM }, // HEBREW ACCENT GERESH + { 0x059D, BIDI_NSM }, // HEBREW ACCENT GERESH MUQDAM + { 0x059E, BIDI_NSM }, // HEBREW ACCENT GERSHAYIM + { 0x059F, BIDI_NSM }, // HEBREW ACCENT QARNEY PARA + { 0x05A0, BIDI_NSM }, // HEBREW ACCENT TELISHA GEDOLA + { 0x05A1, BIDI_NSM }, // HEBREW ACCENT PAZER + { 0x05A2, BIDI_NSM }, // HEBREW ACCENT ATNAH HAFUKH + { 0x05A3, BIDI_NSM }, // HEBREW ACCENT MUNAH + { 0x05A4, BIDI_NSM }, // HEBREW ACCENT MAHAPAKH + { 0x05A5, BIDI_NSM }, // HEBREW ACCENT MERKHA + { 0x05A6, BIDI_NSM }, // HEBREW ACCENT MERKHA KEFULA + { 0x05A7, BIDI_NSM }, // HEBREW ACCENT DARGA + { 0x05A8, BIDI_NSM }, // HEBREW ACCENT QADMA + { 0x05A9, BIDI_NSM }, // HEBREW ACCENT TELISHA QETANA + { 0x05AA, BIDI_NSM }, // HEBREW ACCENT YERAH BEN YOMO + { 0x05AB, BIDI_NSM }, // HEBREW ACCENT OLE + { 0x05AC, BIDI_NSM }, // HEBREW ACCENT ILUY + { 0x05AD, BIDI_NSM }, // HEBREW ACCENT DEHI + { 0x05AE, BIDI_NSM }, // HEBREW ACCENT ZINOR + { 0x05AF, BIDI_NSM }, // HEBREW MARK MASORA CIRCLE + { 0x05B0, BIDI_NSM }, // HEBREW POINT SHEVA + { 0x05B1, BIDI_NSM }, // HEBREW POINT HATAF SEGOL + { 0x05B2, BIDI_NSM }, // HEBREW POINT HATAF PATAH + { 0x05B3, BIDI_NSM }, // HEBREW POINT HATAF QAMATS + { 0x05B4, BIDI_NSM }, // HEBREW POINT HIRIQ + { 0x05B5, BIDI_NSM }, // HEBREW POINT TSERE + { 0x05B6, BIDI_NSM }, // HEBREW POINT SEGOL + { 0x05B7, BIDI_NSM }, // HEBREW POINT PATAH + { 0x05B8, BIDI_NSM }, // HEBREW POINT QAMATS + { 0x05B9, BIDI_NSM }, // HEBREW POINT HOLAM + { 0x05BA, BIDI_NSM }, // HEBREW POINT HOLAM HASER FOR VAV + { 0x05BB, BIDI_NSM }, // HEBREW POINT QUBUTS + { 0x05BC, BIDI_NSM }, // HEBREW POINT DAGESH OR MAPIQ + { 0x05BD, BIDI_NSM }, // HEBREW POINT METEG + { 0x05BE, BIDI_R }, // HEBREW PUNCTUATION MAQAF + { 0x05BF, BIDI_NSM }, // HEBREW POINT RAFE + { 0x05C0, BIDI_R }, // HEBREW PUNCTUATION PASEQ + { 0x05C1, BIDI_NSM }, // HEBREW POINT SHIN DOT + { 0x05C2, BIDI_NSM }, // HEBREW POINT SIN DOT + { 0x05C3, BIDI_R }, // HEBREW PUNCTUATION SOF PASUQ + { 0x05C4, BIDI_NSM }, // HEBREW MARK UPPER DOT + { 0x05C5, BIDI_NSM }, // HEBREW MARK LOWER DOT + { 0x05C6, BIDI_R }, // HEBREW PUNCTUATION NUN HAFUKHA + { 0x05C7, BIDI_NSM }, // HEBREW POINT QAMATS QATAN + { 0x05D0, BIDI_R }, // HEBREW LETTER ALEF + { 0x05D1, BIDI_R }, // HEBREW LETTER BET + { 0x05D2, BIDI_R }, // HEBREW LETTER GIMEL + { 0x05D3, BIDI_R }, // HEBREW LETTER DALET + { 0x05D4, BIDI_R }, // HEBREW LETTER HE + { 0x05D5, BIDI_R }, // HEBREW LETTER VAV + { 0x05D6, BIDI_R }, // HEBREW LETTER ZAYIN + { 0x05D7, BIDI_R }, // HEBREW LETTER HET + { 0x05D8, BIDI_R }, // HEBREW LETTER TET + { 0x05D9, BIDI_R }, // HEBREW LETTER YOD + { 0x05DA, BIDI_R }, // HEBREW LETTER FINAL KAF + { 0x05DB, BIDI_R }, // HEBREW LETTER KAF + { 0x05DC, BIDI_R }, // HEBREW LETTER LAMED + { 0x05DD, BIDI_R }, // HEBREW LETTER FINAL MEM + { 0x05DE, BIDI_R }, // HEBREW LETTER MEM + { 0x05DF, BIDI_R }, // HEBREW LETTER FINAL NUN + { 0x05E0, BIDI_R }, // HEBREW LETTER NUN + { 0x05E1, BIDI_R }, // HEBREW LETTER SAMEKH + { 0x05E2, BIDI_R }, // HEBREW LETTER AYIN + { 0x05E3, BIDI_R }, // HEBREW LETTER FINAL PE + { 0x05E4, BIDI_R }, // HEBREW LETTER PE + { 0x05E5, BIDI_R }, // HEBREW LETTER FINAL TSADI + { 0x05E6, BIDI_R }, // HEBREW LETTER TSADI + { 0x05E7, BIDI_R }, // HEBREW LETTER QOF + { 0x05E8, BIDI_R }, // HEBREW LETTER RESH + { 0x05E9, BIDI_R }, // HEBREW LETTER SHIN + { 0x05EA, BIDI_R }, // HEBREW LETTER TAV + { 0x05F0, BIDI_R }, // HEBREW LIGATURE YIDDISH DOUBLE VAV + { 0x05F1, BIDI_R }, // HEBREW LIGATURE YIDDISH VAV YOD + { 0x05F2, BIDI_R }, // HEBREW LIGATURE YIDDISH DOUBLE YOD + { 0x05F3, BIDI_R }, // HEBREW PUNCTUATION GERESH + { 0x05F4, BIDI_R }, // HEBREW PUNCTUATION GERSHAYIM + { 0x0600, BIDI_AN }, // ARABIC NUMBER SIGN + { 0x0601, BIDI_AN }, // ARABIC SIGN SANAH + { 0x0602, BIDI_AN }, // ARABIC FOOTNOTE MARKER + { 0x0603, BIDI_AN }, // ARABIC SIGN SAFHA + { 0x0604, BIDI_AN }, // ARABIC SIGN SAMVAT + { 0x0605, BIDI_AN }, // ARABIC NUMBER MARK ABOVE + { 0x0606, BIDI_ON }, // ARABIC-INDIC CUBE ROOT + { 0x0607, BIDI_ON }, // ARABIC-INDIC FOURTH ROOT + { 0x0608, BIDI_AL }, // ARABIC RAY + { 0x0609, BIDI_ET }, // ARABIC-INDIC PER MILLE SIGN + { 0x060A, BIDI_ET }, // ARABIC-INDIC PER TEN THOUSAND SIGN + { 0x060B, BIDI_AL }, // AFGHANI SIGN + { 0x060C, BIDI_CS }, // ARABIC COMMA + { 0x060D, BIDI_AL }, // ARABIC DATE SEPARATOR + { 0x060E, BIDI_ON }, // ARABIC POETIC VERSE SIGN + { 0x060F, BIDI_ON }, // ARABIC SIGN MISRA + { 0x0610, BIDI_NSM }, // ARABIC SIGN SALLALLAHOU ALAYHE WASSALLAM + { 0x0611, BIDI_NSM }, // ARABIC SIGN ALAYHE ASSALLAM + { 0x0612, BIDI_NSM }, // ARABIC SIGN RAHMATULLAH ALAYHE + { 0x0613, BIDI_NSM }, // ARABIC SIGN RADI ALLAHOU ANHU + { 0x0614, BIDI_NSM }, // ARABIC SIGN TAKHALLUS + { 0x0615, BIDI_NSM }, // ARABIC SMALL HIGH TAH + { 0x0616, BIDI_NSM }, // ARABIC SMALL HIGH LIGATURE ALEF WITH LAM WITH YEH + { 0x0617, BIDI_NSM }, // ARABIC SMALL HIGH ZAIN + { 0x0618, BIDI_NSM }, // ARABIC SMALL FATHA + { 0x0619, BIDI_NSM }, // ARABIC SMALL DAMMA + { 0x061A, BIDI_NSM }, // ARABIC SMALL KASRA + { 0x061B, BIDI_AL }, // ARABIC SEMICOLON + { 0x061C, BIDI_AL }, // ARABIC LETTER MARK + { 0x061E, BIDI_AL }, // ARABIC TRIPLE DOT PUNCTUATION MARK + { 0x061F, BIDI_AL }, // ARABIC QUESTION MARK + { 0x0620, BIDI_AL }, // ARABIC LETTER KASHMIRI YEH + { 0x0621, BIDI_AL }, // ARABIC LETTER HAMZA + { 0x0622, BIDI_AL }, // ARABIC LETTER ALEF WITH MADDA ABOVE + { 0x0623, BIDI_AL }, // ARABIC LETTER ALEF WITH HAMZA ABOVE + { 0x0624, BIDI_AL }, // ARABIC LETTER WAW WITH HAMZA ABOVE + { 0x0625, BIDI_AL }, // ARABIC LETTER ALEF WITH HAMZA BELOW + { 0x0626, BIDI_AL }, // ARABIC LETTER YEH WITH HAMZA ABOVE + { 0x0627, BIDI_AL }, // ARABIC LETTER ALEF + { 0x0628, BIDI_AL }, // ARABIC LETTER BEH + { 0x0629, BIDI_AL }, // ARABIC LETTER TEH MARBUTA + { 0x062A, BIDI_AL }, // ARABIC LETTER TEH + { 0x062B, BIDI_AL }, // ARABIC LETTER THEH + { 0x062C, BIDI_AL }, // ARABIC LETTER JEEM + { 0x062D, BIDI_AL }, // ARABIC LETTER HAH + { 0x062E, BIDI_AL }, // ARABIC LETTER KHAH + { 0x062F, BIDI_AL }, // ARABIC LETTER DAL + { 0x0630, BIDI_AL }, // ARABIC LETTER THAL + { 0x0631, BIDI_AL }, // ARABIC LETTER REH + { 0x0632, BIDI_AL }, // ARABIC LETTER ZAIN + { 0x0633, BIDI_AL }, // ARABIC LETTER SEEN + { 0x0634, BIDI_AL }, // ARABIC LETTER SHEEN + { 0x0635, BIDI_AL }, // ARABIC LETTER SAD + { 0x0636, BIDI_AL }, // ARABIC LETTER DAD + { 0x0637, BIDI_AL }, // ARABIC LETTER TAH + { 0x0638, BIDI_AL }, // ARABIC LETTER ZAH + { 0x0639, BIDI_AL }, // ARABIC LETTER AIN + { 0x063A, BIDI_AL }, // ARABIC LETTER GHAIN + { 0x063B, BIDI_AL }, // ARABIC LETTER KEHEH WITH TWO DOTS ABOVE + { 0x063C, BIDI_AL }, // ARABIC LETTER KEHEH WITH THREE DOTS BELOW + { 0x063D, BIDI_AL }, // ARABIC LETTER FARSI YEH WITH INVERTED V + { 0x063E, BIDI_AL }, // ARABIC LETTER FARSI YEH WITH TWO DOTS ABOVE + { 0x063F, BIDI_AL }, // ARABIC LETTER FARSI YEH WITH THREE DOTS ABOVE + { 0x0640, BIDI_AL }, // ARABIC TATWEEL + { 0x0641, BIDI_AL }, // ARABIC LETTER FEH + { 0x0642, BIDI_AL }, // ARABIC LETTER QAF + { 0x0643, BIDI_AL }, // ARABIC LETTER KAF + { 0x0644, BIDI_AL }, // ARABIC LETTER LAM + { 0x0645, BIDI_AL }, // ARABIC LETTER MEEM + { 0x0646, BIDI_AL }, // ARABIC LETTER NOON + { 0x0647, BIDI_AL }, // ARABIC LETTER HEH + { 0x0648, BIDI_AL }, // ARABIC LETTER WAW + { 0x0649, BIDI_AL }, // ARABIC LETTER ALEF MAKSURA + { 0x064A, BIDI_AL }, // ARABIC LETTER YEH + { 0x064B, BIDI_NSM }, // ARABIC FATHATAN + { 0x064C, BIDI_NSM }, // ARABIC DAMMATAN + { 0x064D, BIDI_NSM }, // ARABIC KASRATAN + { 0x064E, BIDI_NSM }, // ARABIC FATHA + { 0x064F, BIDI_NSM }, // ARABIC DAMMA + { 0x0650, BIDI_NSM }, // ARABIC KASRA + { 0x0651, BIDI_NSM }, // ARABIC SHADDA + { 0x0652, BIDI_NSM }, // ARABIC SUKUN + { 0x0653, BIDI_NSM }, // ARABIC MADDAH ABOVE + { 0x0654, BIDI_NSM }, // ARABIC HAMZA ABOVE + { 0x0655, BIDI_NSM }, // ARABIC HAMZA BELOW + { 0x0656, BIDI_NSM }, // ARABIC SUBSCRIPT ALEF + { 0x0657, BIDI_NSM }, // ARABIC INVERTED DAMMA + { 0x0658, BIDI_NSM }, // ARABIC MARK NOON GHUNNA + { 0x0659, BIDI_NSM }, // ARABIC ZWARAKAY + { 0x065A, BIDI_NSM }, // ARABIC VOWEL SIGN SMALL V ABOVE + { 0x065B, BIDI_NSM }, // ARABIC VOWEL SIGN INVERTED SMALL V ABOVE + { 0x065C, BIDI_NSM }, // ARABIC VOWEL SIGN DOT BELOW + { 0x065D, BIDI_NSM }, // ARABIC REVERSED DAMMA + { 0x065E, BIDI_NSM }, // ARABIC FATHA WITH TWO DOTS + { 0x065F, BIDI_NSM }, // ARABIC WAVY HAMZA BELOW + { 0x0660, BIDI_AN }, // ARABIC-INDIC DIGIT ZERO + { 0x0661, BIDI_AN }, // ARABIC-INDIC DIGIT ONE + { 0x0662, BIDI_AN }, // ARABIC-INDIC DIGIT TWO + { 0x0663, BIDI_AN }, // ARABIC-INDIC DIGIT THREE + { 0x0664, BIDI_AN }, // ARABIC-INDIC DIGIT FOUR + { 0x0665, BIDI_AN }, // ARABIC-INDIC DIGIT FIVE + { 0x0666, BIDI_AN }, // ARABIC-INDIC DIGIT SIX + { 0x0667, BIDI_AN }, // ARABIC-INDIC DIGIT SEVEN + { 0x0668, BIDI_AN }, // ARABIC-INDIC DIGIT EIGHT + { 0x0669, BIDI_AN }, // ARABIC-INDIC DIGIT NINE + { 0x066A, BIDI_ET }, // ARABIC PERCENT SIGN + { 0x066B, BIDI_AN }, // ARABIC DECIMAL SEPARATOR + { 0x066C, BIDI_AN }, // ARABIC THOUSANDS SEPARATOR + { 0x066D, BIDI_AL }, // ARABIC FIVE POINTED STAR + { 0x066E, BIDI_AL }, // ARABIC LETTER DOTLESS BEH + { 0x066F, BIDI_AL }, // ARABIC LETTER DOTLESS QAF + { 0x0670, BIDI_NSM }, // ARABIC LETTER SUPERSCRIPT ALEF + { 0x0671, BIDI_AL }, // ARABIC LETTER ALEF WASLA + { 0x0672, BIDI_AL }, // ARABIC LETTER ALEF WITH WAVY HAMZA ABOVE + { 0x0673, BIDI_AL }, // ARABIC LETTER ALEF WITH WAVY HAMZA BELOW + { 0x0674, BIDI_AL }, // ARABIC LETTER HIGH HAMZA + { 0x0675, BIDI_AL }, // ARABIC LETTER HIGH HAMZA ALEF + { 0x0676, BIDI_AL }, // ARABIC LETTER HIGH HAMZA WAW + { 0x0677, BIDI_AL }, // ARABIC LETTER U WITH HAMZA ABOVE + { 0x0678, BIDI_AL }, // ARABIC LETTER HIGH HAMZA YEH + { 0x0679, BIDI_AL }, // ARABIC LETTER TTEH + { 0x067A, BIDI_AL }, // ARABIC LETTER TTEHEH + { 0x067B, BIDI_AL }, // ARABIC LETTER BEEH + { 0x067C, BIDI_AL }, // ARABIC LETTER TEH WITH RING + { 0x067D, BIDI_AL }, // ARABIC LETTER TEH WITH THREE DOTS ABOVE DOWNWARDS + { 0x067E, BIDI_AL }, // ARABIC LETTER PEH + { 0x067F, BIDI_AL }, // ARABIC LETTER TEHEH + { 0x0680, BIDI_AL }, // ARABIC LETTER BEHEH + { 0x0681, BIDI_AL }, // ARABIC LETTER HAH WITH HAMZA ABOVE + { 0x0682, BIDI_AL }, // ARABIC LETTER HAH WITH TWO DOTS VERTICAL ABOVE + { 0x0683, BIDI_AL }, // ARABIC LETTER NYEH + { 0x0684, BIDI_AL }, // ARABIC LETTER DYEH + { 0x0685, BIDI_AL }, // ARABIC LETTER HAH WITH THREE DOTS ABOVE + { 0x0686, BIDI_AL }, // ARABIC LETTER TCHEH + { 0x0687, BIDI_AL }, // ARABIC LETTER TCHEHEH + { 0x0688, BIDI_AL }, // ARABIC LETTER DDAL + { 0x0689, BIDI_AL }, // ARABIC LETTER DAL WITH RING + { 0x068A, BIDI_AL }, // ARABIC LETTER DAL WITH DOT BELOW + { 0x068B, BIDI_AL }, // ARABIC LETTER DAL WITH DOT BELOW AND SMALL TAH + { 0x068C, BIDI_AL }, // ARABIC LETTER DAHAL + { 0x068D, BIDI_AL }, // ARABIC LETTER DDAHAL + { 0x068E, BIDI_AL }, // ARABIC LETTER DUL + { 0x068F, BIDI_AL }, // ARABIC LETTER DAL WITH THREE DOTS ABOVE DOWNWARDS + { 0x0690, BIDI_AL }, // ARABIC LETTER DAL WITH FOUR DOTS ABOVE + { 0x0691, BIDI_AL }, // ARABIC LETTER RREH + { 0x0692, BIDI_AL }, // ARABIC LETTER REH WITH SMALL V + { 0x0693, BIDI_AL }, // ARABIC LETTER REH WITH RING + { 0x0694, BIDI_AL }, // ARABIC LETTER REH WITH DOT BELOW + { 0x0695, BIDI_AL }, // ARABIC LETTER REH WITH SMALL V BELOW + { 0x0696, BIDI_AL }, // ARABIC LETTER REH WITH DOT BELOW AND DOT ABOVE + { 0x0697, BIDI_AL }, // ARABIC LETTER REH WITH TWO DOTS ABOVE + { 0x0698, BIDI_AL }, // ARABIC LETTER JEH + { 0x0699, BIDI_AL }, // ARABIC LETTER REH WITH FOUR DOTS ABOVE + { 0x069A, BIDI_AL }, // ARABIC LETTER SEEN WITH DOT BELOW AND DOT ABOVE + { 0x069B, BIDI_AL }, // ARABIC LETTER SEEN WITH THREE DOTS BELOW + { 0x069C, BIDI_AL }, // ARABIC LETTER SEEN WITH THREE DOTS BELOW AND THREE DOTS ABOVE + { 0x069D, BIDI_AL }, // ARABIC LETTER SAD WITH TWO DOTS BELOW + { 0x069E, BIDI_AL }, // ARABIC LETTER SAD WITH THREE DOTS ABOVE + { 0x069F, BIDI_AL }, // ARABIC LETTER TAH WITH THREE DOTS ABOVE + { 0x06A0, BIDI_AL }, // ARABIC LETTER AIN WITH THREE DOTS ABOVE + { 0x06A1, BIDI_AL }, // ARABIC LETTER DOTLESS FEH + { 0x06A2, BIDI_AL }, // ARABIC LETTER FEH WITH DOT MOVED BELOW + { 0x06A3, BIDI_AL }, // ARABIC LETTER FEH WITH DOT BELOW + { 0x06A4, BIDI_AL }, // ARABIC LETTER VEH + { 0x06A5, BIDI_AL }, // ARABIC LETTER FEH WITH THREE DOTS BELOW + { 0x06A6, BIDI_AL }, // ARABIC LETTER PEHEH + { 0x06A7, BIDI_AL }, // ARABIC LETTER QAF WITH DOT ABOVE + { 0x06A8, BIDI_AL }, // ARABIC LETTER QAF WITH THREE DOTS ABOVE + { 0x06A9, BIDI_AL }, // ARABIC LETTER KEHEH + { 0x06AA, BIDI_AL }, // ARABIC LETTER SWASH KAF + { 0x06AB, BIDI_AL }, // ARABIC LETTER KAF WITH RING + { 0x06AC, BIDI_AL }, // ARABIC LETTER KAF WITH DOT ABOVE + { 0x06AD, BIDI_AL }, // ARABIC LETTER NG + { 0x06AE, BIDI_AL }, // ARABIC LETTER KAF WITH THREE DOTS BELOW + { 0x06AF, BIDI_AL }, // ARABIC LETTER GAF + { 0x06B0, BIDI_AL }, // ARABIC LETTER GAF WITH RING + { 0x06B1, BIDI_AL }, // ARABIC LETTER NGOEH + { 0x06B2, BIDI_AL }, // ARABIC LETTER GAF WITH TWO DOTS BELOW + { 0x06B3, BIDI_AL }, // ARABIC LETTER GUEH + { 0x06B4, BIDI_AL }, // ARABIC LETTER GAF WITH THREE DOTS ABOVE + { 0x06B5, BIDI_AL }, // ARABIC LETTER LAM WITH SMALL V + { 0x06B6, BIDI_AL }, // ARABIC LETTER LAM WITH DOT ABOVE + { 0x06B7, BIDI_AL }, // ARABIC LETTER LAM WITH THREE DOTS ABOVE + { 0x06B8, BIDI_AL }, // ARABIC LETTER LAM WITH THREE DOTS BELOW + { 0x06B9, BIDI_AL }, // ARABIC LETTER NOON WITH DOT BELOW + { 0x06BA, BIDI_AL }, // ARABIC LETTER NOON GHUNNA + { 0x06BB, BIDI_AL }, // ARABIC LETTER RNOON + { 0x06BC, BIDI_AL }, // ARABIC LETTER NOON WITH RING + { 0x06BD, BIDI_AL }, // ARABIC LETTER NOON WITH THREE DOTS ABOVE + { 0x06BE, BIDI_AL }, // ARABIC LETTER HEH DOACHASHMEE + { 0x06BF, BIDI_AL }, // ARABIC LETTER TCHEH WITH DOT ABOVE + { 0x06C0, BIDI_AL }, // ARABIC LETTER HEH WITH YEH ABOVE + { 0x06C1, BIDI_AL }, // ARABIC LETTER HEH GOAL + { 0x06C2, BIDI_AL }, // ARABIC LETTER HEH GOAL WITH HAMZA ABOVE + { 0x06C3, BIDI_AL }, // ARABIC LETTER TEH MARBUTA GOAL + { 0x06C4, BIDI_AL }, // ARABIC LETTER WAW WITH RING + { 0x06C5, BIDI_AL }, // ARABIC LETTER KIRGHIZ OE + { 0x06C6, BIDI_AL }, // ARABIC LETTER OE + { 0x06C7, BIDI_AL }, // ARABIC LETTER U + { 0x06C8, BIDI_AL }, // ARABIC LETTER YU + { 0x06C9, BIDI_AL }, // ARABIC LETTER KIRGHIZ YU + { 0x06CA, BIDI_AL }, // ARABIC LETTER WAW WITH TWO DOTS ABOVE + { 0x06CB, BIDI_AL }, // ARABIC LETTER VE + { 0x06CC, BIDI_AL }, // ARABIC LETTER FARSI YEH + { 0x06CD, BIDI_AL }, // ARABIC LETTER YEH WITH TAIL + { 0x06CE, BIDI_AL }, // ARABIC LETTER YEH WITH SMALL V + { 0x06CF, BIDI_AL }, // ARABIC LETTER WAW WITH DOT ABOVE + { 0x06D0, BIDI_AL }, // ARABIC LETTER E + { 0x06D1, BIDI_AL }, // ARABIC LETTER YEH WITH THREE DOTS BELOW + { 0x06D2, BIDI_AL }, // ARABIC LETTER YEH BARREE + { 0x06D3, BIDI_AL }, // ARABIC LETTER YEH BARREE WITH HAMZA ABOVE + { 0x06D4, BIDI_AL }, // ARABIC FULL STOP + { 0x06D5, BIDI_AL }, // ARABIC LETTER AE + { 0x06D6, BIDI_NSM }, // ARABIC SMALL HIGH LIGATURE SAD WITH LAM WITH ALEF MAKSURA + { 0x06D7, BIDI_NSM }, // ARABIC SMALL HIGH LIGATURE QAF WITH LAM WITH ALEF MAKSURA + { 0x06D8, BIDI_NSM }, // ARABIC SMALL HIGH MEEM INITIAL FORM + { 0x06D9, BIDI_NSM }, // ARABIC SMALL HIGH LAM ALEF + { 0x06DA, BIDI_NSM }, // ARABIC SMALL HIGH JEEM + { 0x06DB, BIDI_NSM }, // ARABIC SMALL HIGH THREE DOTS + { 0x06DC, BIDI_NSM }, // ARABIC SMALL HIGH SEEN + { 0x06DD, BIDI_AN }, // ARABIC END OF AYAH + { 0x06DE, BIDI_ON }, // ARABIC START OF RUB EL HIZB + { 0x06DF, BIDI_NSM }, // ARABIC SMALL HIGH ROUNDED ZERO + { 0x06E0, BIDI_NSM }, // ARABIC SMALL HIGH UPRIGHT RECTANGULAR ZERO + { 0x06E1, BIDI_NSM }, // ARABIC SMALL HIGH DOTLESS HEAD OF KHAH + { 0x06E2, BIDI_NSM }, // ARABIC SMALL HIGH MEEM ISOLATED FORM + { 0x06E3, BIDI_NSM }, // ARABIC SMALL LOW SEEN + { 0x06E4, BIDI_NSM }, // ARABIC SMALL HIGH MADDA + { 0x06E5, BIDI_AL }, // ARABIC SMALL WAW + { 0x06E6, BIDI_AL }, // ARABIC SMALL YEH + { 0x06E7, BIDI_NSM }, // ARABIC SMALL HIGH YEH + { 0x06E8, BIDI_NSM }, // ARABIC SMALL HIGH NOON + { 0x06E9, BIDI_ON }, // ARABIC PLACE OF SAJDAH + { 0x06EA, BIDI_NSM }, // ARABIC EMPTY CENTRE LOW STOP + { 0x06EB, BIDI_NSM }, // ARABIC EMPTY CENTRE HIGH STOP + { 0x06EC, BIDI_NSM }, // ARABIC ROUNDED HIGH STOP WITH FILLED CENTRE + { 0x06ED, BIDI_NSM }, // ARABIC SMALL LOW MEEM + { 0x06EE, BIDI_AL }, // ARABIC LETTER DAL WITH INVERTED V + { 0x06EF, BIDI_AL }, // ARABIC LETTER REH WITH INVERTED V + { 0x06F0, BIDI_EN }, // EXTENDED ARABIC-INDIC DIGIT ZERO + { 0x06F1, BIDI_EN }, // EXTENDED ARABIC-INDIC DIGIT ONE + { 0x06F2, BIDI_EN }, // EXTENDED ARABIC-INDIC DIGIT TWO + { 0x06F3, BIDI_EN }, // EXTENDED ARABIC-INDIC DIGIT THREE + { 0x06F4, BIDI_EN }, // EXTENDED ARABIC-INDIC DIGIT FOUR + { 0x06F5, BIDI_EN }, // EXTENDED ARABIC-INDIC DIGIT FIVE + { 0x06F6, BIDI_EN }, // EXTENDED ARABIC-INDIC DIGIT SIX + { 0x06F7, BIDI_EN }, // EXTENDED ARABIC-INDIC DIGIT SEVEN + { 0x06F8, BIDI_EN }, // EXTENDED ARABIC-INDIC DIGIT EIGHT + { 0x06F9, BIDI_EN }, // EXTENDED ARABIC-INDIC DIGIT NINE + { 0x06FA, BIDI_AL }, // ARABIC LETTER SHEEN WITH DOT BELOW + { 0x06FB, BIDI_AL }, // ARABIC LETTER DAD WITH DOT BELOW + { 0x06FC, BIDI_AL }, // ARABIC LETTER GHAIN WITH DOT BELOW + { 0x06FD, BIDI_AL }, // ARABIC SIGN SINDHI AMPERSAND + { 0x06FE, BIDI_AL }, // ARABIC SIGN SINDHI POSTPOSITION MEN + { 0x06FF, BIDI_AL }, // ARABIC LETTER HEH WITH INVERTED V + { 0x0700, BIDI_AL }, // SYRIAC END OF PARAGRAPH + { 0x0701, BIDI_AL }, // SYRIAC SUPRALINEAR FULL STOP + { 0x0702, BIDI_AL }, // SYRIAC SUBLINEAR FULL STOP + { 0x0703, BIDI_AL }, // SYRIAC SUPRALINEAR COLON + { 0x0704, BIDI_AL }, // SYRIAC SUBLINEAR COLON + { 0x0705, BIDI_AL }, // SYRIAC HORIZONTAL COLON + { 0x0706, BIDI_AL }, // SYRIAC COLON SKEWED LEFT + { 0x0707, BIDI_AL }, // SYRIAC COLON SKEWED RIGHT + { 0x0708, BIDI_AL }, // SYRIAC SUPRALINEAR COLON SKEWED LEFT + { 0x0709, BIDI_AL }, // SYRIAC SUBLINEAR COLON SKEWED RIGHT + { 0x070A, BIDI_AL }, // SYRIAC CONTRACTION + { 0x070B, BIDI_AL }, // SYRIAC HARKLEAN OBELUS + { 0x070C, BIDI_AL }, // SYRIAC HARKLEAN METOBELUS + { 0x070D, BIDI_AL }, // SYRIAC HARKLEAN ASTERISCUS + { 0x070F, BIDI_AL }, // SYRIAC ABBREVIATION MARK + { 0x0710, BIDI_AL }, // SYRIAC LETTER ALAPH + { 0x0711, BIDI_NSM }, // SYRIAC LETTER SUPERSCRIPT ALAPH + { 0x0712, BIDI_AL }, // SYRIAC LETTER BETH + { 0x0713, BIDI_AL }, // SYRIAC LETTER GAMAL + { 0x0714, BIDI_AL }, // SYRIAC LETTER GAMAL GARSHUNI + { 0x0715, BIDI_AL }, // SYRIAC LETTER DALATH + { 0x0716, BIDI_AL }, // SYRIAC LETTER DOTLESS DALATH RISH + { 0x0717, BIDI_AL }, // SYRIAC LETTER HE + { 0x0718, BIDI_AL }, // SYRIAC LETTER WAW + { 0x0719, BIDI_AL }, // SYRIAC LETTER ZAIN + { 0x071A, BIDI_AL }, // SYRIAC LETTER HETH + { 0x071B, BIDI_AL }, // SYRIAC LETTER TETH + { 0x071C, BIDI_AL }, // SYRIAC LETTER TETH GARSHUNI + { 0x071D, BIDI_AL }, // SYRIAC LETTER YUDH + { 0x071E, BIDI_AL }, // SYRIAC LETTER YUDH HE + { 0x071F, BIDI_AL }, // SYRIAC LETTER KAPH + { 0x0720, BIDI_AL }, // SYRIAC LETTER LAMADH + { 0x0721, BIDI_AL }, // SYRIAC LETTER MIM + { 0x0722, BIDI_AL }, // SYRIAC LETTER NUN + { 0x0723, BIDI_AL }, // SYRIAC LETTER SEMKATH + { 0x0724, BIDI_AL }, // SYRIAC LETTER FINAL SEMKATH + { 0x0725, BIDI_AL }, // SYRIAC LETTER E + { 0x0726, BIDI_AL }, // SYRIAC LETTER PE + { 0x0727, BIDI_AL }, // SYRIAC LETTER REVERSED PE + { 0x0728, BIDI_AL }, // SYRIAC LETTER SADHE + { 0x0729, BIDI_AL }, // SYRIAC LETTER QAPH + { 0x072A, BIDI_AL }, // SYRIAC LETTER RISH + { 0x072B, BIDI_AL }, // SYRIAC LETTER SHIN + { 0x072C, BIDI_AL }, // SYRIAC LETTER TAW + { 0x072D, BIDI_AL }, // SYRIAC LETTER PERSIAN BHETH + { 0x072E, BIDI_AL }, // SYRIAC LETTER PERSIAN GHAMAL + { 0x072F, BIDI_AL }, // SYRIAC LETTER PERSIAN DHALATH + { 0x0730, BIDI_NSM }, // SYRIAC PTHAHA ABOVE + { 0x0731, BIDI_NSM }, // SYRIAC PTHAHA BELOW + { 0x0732, BIDI_NSM }, // SYRIAC PTHAHA DOTTED + { 0x0733, BIDI_NSM }, // SYRIAC ZQAPHA ABOVE + { 0x0734, BIDI_NSM }, // SYRIAC ZQAPHA BELOW + { 0x0735, BIDI_NSM }, // SYRIAC ZQAPHA DOTTED + { 0x0736, BIDI_NSM }, // SYRIAC RBASA ABOVE + { 0x0737, BIDI_NSM }, // SYRIAC RBASA BELOW + { 0x0738, BIDI_NSM }, // SYRIAC DOTTED ZLAMA HORIZONTAL + { 0x0739, BIDI_NSM }, // SYRIAC DOTTED ZLAMA ANGULAR + { 0x073A, BIDI_NSM }, // SYRIAC HBASA ABOVE + { 0x073B, BIDI_NSM }, // SYRIAC HBASA BELOW + { 0x073C, BIDI_NSM }, // SYRIAC HBASA-ESASA DOTTED + { 0x073D, BIDI_NSM }, // SYRIAC ESASA ABOVE + { 0x073E, BIDI_NSM }, // SYRIAC ESASA BELOW + { 0x073F, BIDI_NSM }, // SYRIAC RWAHA + { 0x0740, BIDI_NSM }, // SYRIAC FEMININE DOT + { 0x0741, BIDI_NSM }, // SYRIAC QUSHSHAYA + { 0x0742, BIDI_NSM }, // SYRIAC RUKKAKHA + { 0x0743, BIDI_NSM }, // SYRIAC TWO VERTICAL DOTS ABOVE + { 0x0744, BIDI_NSM }, // SYRIAC TWO VERTICAL DOTS BELOW + { 0x0745, BIDI_NSM }, // SYRIAC THREE DOTS ABOVE + { 0x0746, BIDI_NSM }, // SYRIAC THREE DOTS BELOW + { 0x0747, BIDI_NSM }, // SYRIAC OBLIQUE LINE ABOVE + { 0x0748, BIDI_NSM }, // SYRIAC OBLIQUE LINE BELOW + { 0x0749, BIDI_NSM }, // SYRIAC MUSIC + { 0x074A, BIDI_NSM }, // SYRIAC BARREKH + { 0x074D, BIDI_AL }, // SYRIAC LETTER SOGDIAN ZHAIN + { 0x074E, BIDI_AL }, // SYRIAC LETTER SOGDIAN KHAPH + { 0x074F, BIDI_AL }, // SYRIAC LETTER SOGDIAN FE + { 0x0750, BIDI_AL }, // ARABIC LETTER BEH WITH THREE DOTS HORIZONTALLY BELOW + { 0x0751, BIDI_AL }, // ARABIC LETTER BEH WITH DOT BELOW AND THREE DOTS ABOVE + { 0x0752, BIDI_AL }, // ARABIC LETTER BEH WITH THREE DOTS POINTING UPWARDS BELOW + { 0x0753, BIDI_AL }, // ARABIC LETTER BEH WITH THREE DOTS POINTING UPWARDS BELOW AND TWO DOTS ABOVE + { 0x0754, BIDI_AL }, // ARABIC LETTER BEH WITH TWO DOTS BELOW AND DOT ABOVE + { 0x0755, BIDI_AL }, // ARABIC LETTER BEH WITH INVERTED SMALL V BELOW + { 0x0756, BIDI_AL }, // ARABIC LETTER BEH WITH SMALL V + { 0x0757, BIDI_AL }, // ARABIC LETTER HAH WITH TWO DOTS ABOVE + { 0x0758, BIDI_AL }, // ARABIC LETTER HAH WITH THREE DOTS POINTING UPWARDS BELOW + { 0x0759, BIDI_AL }, // ARABIC LETTER DAL WITH TWO DOTS VERTICALLY BELOW AND SMALL TAH + { 0x075A, BIDI_AL }, // ARABIC LETTER DAL WITH INVERTED SMALL V BELOW + { 0x075B, BIDI_AL }, // ARABIC LETTER REH WITH STROKE + { 0x075C, BIDI_AL }, // ARABIC LETTER SEEN WITH FOUR DOTS ABOVE + { 0x075D, BIDI_AL }, // ARABIC LETTER AIN WITH TWO DOTS ABOVE + { 0x075E, BIDI_AL }, // ARABIC LETTER AIN WITH THREE DOTS POINTING DOWNWARDS ABOVE + { 0x075F, BIDI_AL }, // ARABIC LETTER AIN WITH TWO DOTS VERTICALLY ABOVE + { 0x0760, BIDI_AL }, // ARABIC LETTER FEH WITH TWO DOTS BELOW + { 0x0761, BIDI_AL }, // ARABIC LETTER FEH WITH THREE DOTS POINTING UPWARDS BELOW + { 0x0762, BIDI_AL }, // ARABIC LETTER KEHEH WITH DOT ABOVE + { 0x0763, BIDI_AL }, // ARABIC LETTER KEHEH WITH THREE DOTS ABOVE + { 0x0764, BIDI_AL }, // ARABIC LETTER KEHEH WITH THREE DOTS POINTING UPWARDS BELOW + { 0x0765, BIDI_AL }, // ARABIC LETTER MEEM WITH DOT ABOVE + { 0x0766, BIDI_AL }, // ARABIC LETTER MEEM WITH DOT BELOW + { 0x0767, BIDI_AL }, // ARABIC LETTER NOON WITH TWO DOTS BELOW + { 0x0768, BIDI_AL }, // ARABIC LETTER NOON WITH SMALL TAH + { 0x0769, BIDI_AL }, // ARABIC LETTER NOON WITH SMALL V + { 0x076A, BIDI_AL }, // ARABIC LETTER LAM WITH BAR + { 0x076B, BIDI_AL }, // ARABIC LETTER REH WITH TWO DOTS VERTICALLY ABOVE + { 0x076C, BIDI_AL }, // ARABIC LETTER REH WITH HAMZA ABOVE + { 0x076D, BIDI_AL }, // ARABIC LETTER SEEN WITH TWO DOTS VERTICALLY ABOVE + { 0x076E, BIDI_AL }, // ARABIC LETTER HAH WITH SMALL ARABIC LETTER TAH BELOW + { 0x076F, BIDI_AL }, // ARABIC LETTER HAH WITH SMALL ARABIC LETTER TAH AND TWO DOTS + { 0x0770, BIDI_AL }, // ARABIC LETTER SEEN WITH SMALL ARABIC LETTER TAH AND TWO DOTS + { 0x0771, BIDI_AL }, // ARABIC LETTER REH WITH SMALL ARABIC LETTER TAH AND TWO DOTS + { 0x0772, BIDI_AL }, // ARABIC LETTER HAH WITH SMALL ARABIC LETTER TAH ABOVE + { 0x0773, BIDI_AL }, // ARABIC LETTER ALEF WITH EXTENDED ARABIC-INDIC DIGIT TWO ABOVE + { 0x0774, BIDI_AL }, // ARABIC LETTER ALEF WITH EXTENDED ARABIC-INDIC DIGIT THREE ABOVE + { 0x0775, BIDI_AL }, // ARABIC LETTER FARSI YEH WITH EXTENDED ARABIC-INDIC DIGIT TWO ABOVE + { 0x0776, BIDI_AL }, // ARABIC LETTER FARSI YEH WITH EXTENDED ARABIC-INDIC DIGIT THREE ABOVE + { 0x0777, BIDI_AL }, // ARABIC LETTER FARSI YEH WITH EXTENDED ARABIC-INDIC DIGIT FOUR BELOW + { 0x0778, BIDI_AL }, // ARABIC LETTER WAW WITH EXTENDED ARABIC-INDIC DIGIT TWO ABOVE + { 0x0779, BIDI_AL }, // ARABIC LETTER WAW WITH EXTENDED ARABIC-INDIC DIGIT THREE ABOVE + { 0x077A, BIDI_AL }, // ARABIC LETTER YEH BARREE WITH EXTENDED ARABIC-INDIC DIGIT TWO ABOVE + { 0x077B, BIDI_AL }, // ARABIC LETTER YEH BARREE WITH EXTENDED ARABIC-INDIC DIGIT THREE ABOVE + { 0x077C, BIDI_AL }, // ARABIC LETTER HAH WITH EXTENDED ARABIC-INDIC DIGIT FOUR BELOW + { 0x077D, BIDI_AL }, // ARABIC LETTER SEEN WITH EXTENDED ARABIC-INDIC DIGIT FOUR ABOVE + { 0x077E, BIDI_AL }, // ARABIC LETTER SEEN WITH INVERTED V + { 0x077F, BIDI_AL }, // ARABIC LETTER KAF WITH TWO DOTS ABOVE + { 0x0780, BIDI_AL }, // THAANA LETTER HAA + { 0x0781, BIDI_AL }, // THAANA LETTER SHAVIYANI + { 0x0782, BIDI_AL }, // THAANA LETTER NOONU + { 0x0783, BIDI_AL }, // THAANA LETTER RAA + { 0x0784, BIDI_AL }, // THAANA LETTER BAA + { 0x0785, BIDI_AL }, // THAANA LETTER LHAVIYANI + { 0x0786, BIDI_AL }, // THAANA LETTER KAAFU + { 0x0787, BIDI_AL }, // THAANA LETTER ALIFU + { 0x0788, BIDI_AL }, // THAANA LETTER VAAVU + { 0x0789, BIDI_AL }, // THAANA LETTER MEEMU + { 0x078A, BIDI_AL }, // THAANA LETTER FAAFU + { 0x078B, BIDI_AL }, // THAANA LETTER DHAALU + { 0x078C, BIDI_AL }, // THAANA LETTER THAA + { 0x078D, BIDI_AL }, // THAANA LETTER LAAMU + { 0x078E, BIDI_AL }, // THAANA LETTER GAAFU + { 0x078F, BIDI_AL }, // THAANA LETTER GNAVIYANI + { 0x0790, BIDI_AL }, // THAANA LETTER SEENU + { 0x0791, BIDI_AL }, // THAANA LETTER DAVIYANI + { 0x0792, BIDI_AL }, // THAANA LETTER ZAVIYANI + { 0x0793, BIDI_AL }, // THAANA LETTER TAVIYANI + { 0x0794, BIDI_AL }, // THAANA LETTER YAA + { 0x0795, BIDI_AL }, // THAANA LETTER PAVIYANI + { 0x0796, BIDI_AL }, // THAANA LETTER JAVIYANI + { 0x0797, BIDI_AL }, // THAANA LETTER CHAVIYANI + { 0x0798, BIDI_AL }, // THAANA LETTER TTAA + { 0x0799, BIDI_AL }, // THAANA LETTER HHAA + { 0x079A, BIDI_AL }, // THAANA LETTER KHAA + { 0x079B, BIDI_AL }, // THAANA LETTER THAALU + { 0x079C, BIDI_AL }, // THAANA LETTER ZAA + { 0x079D, BIDI_AL }, // THAANA LETTER SHEENU + { 0x079E, BIDI_AL }, // THAANA LETTER SAADHU + { 0x079F, BIDI_AL }, // THAANA LETTER DAADHU + { 0x07A0, BIDI_AL }, // THAANA LETTER TO + { 0x07A1, BIDI_AL }, // THAANA LETTER ZO + { 0x07A2, BIDI_AL }, // THAANA LETTER AINU + { 0x07A3, BIDI_AL }, // THAANA LETTER GHAINU + { 0x07A4, BIDI_AL }, // THAANA LETTER QAAFU + { 0x07A5, BIDI_AL }, // THAANA LETTER WAAVU + { 0x07A6, BIDI_NSM }, // THAANA ABAFILI + { 0x07A7, BIDI_NSM }, // THAANA AABAAFILI + { 0x07A8, BIDI_NSM }, // THAANA IBIFILI + { 0x07A9, BIDI_NSM }, // THAANA EEBEEFILI + { 0x07AA, BIDI_NSM }, // THAANA UBUFILI + { 0x07AB, BIDI_NSM }, // THAANA OOBOOFILI + { 0x07AC, BIDI_NSM }, // THAANA EBEFILI + { 0x07AD, BIDI_NSM }, // THAANA EYBEYFILI + { 0x07AE, BIDI_NSM }, // THAANA OBOFILI + { 0x07AF, BIDI_NSM }, // THAANA OABOAFILI + { 0x07B0, BIDI_NSM }, // THAANA SUKUN + { 0x07B1, BIDI_AL }, // THAANA LETTER NAA + { 0x07C0, BIDI_R }, // NKO DIGIT ZERO + { 0x07C1, BIDI_R }, // NKO DIGIT ONE + { 0x07C2, BIDI_R }, // NKO DIGIT TWO + { 0x07C3, BIDI_R }, // NKO DIGIT THREE + { 0x07C4, BIDI_R }, // NKO DIGIT FOUR + { 0x07C5, BIDI_R }, // NKO DIGIT FIVE + { 0x07C6, BIDI_R }, // NKO DIGIT SIX + { 0x07C7, BIDI_R }, // NKO DIGIT SEVEN + { 0x07C8, BIDI_R }, // NKO DIGIT EIGHT + { 0x07C9, BIDI_R }, // NKO DIGIT NINE + { 0x07CA, BIDI_R }, // NKO LETTER A + { 0x07CB, BIDI_R }, // NKO LETTER EE + { 0x07CC, BIDI_R }, // NKO LETTER I + { 0x07CD, BIDI_R }, // NKO LETTER E + { 0x07CE, BIDI_R }, // NKO LETTER U + { 0x07CF, BIDI_R }, // NKO LETTER OO + { 0x07D0, BIDI_R }, // NKO LETTER O + { 0x07D1, BIDI_R }, // NKO LETTER DAGBASINNA + { 0x07D2, BIDI_R }, // NKO LETTER N + { 0x07D3, BIDI_R }, // NKO LETTER BA + { 0x07D4, BIDI_R }, // NKO LETTER PA + { 0x07D5, BIDI_R }, // NKO LETTER TA + { 0x07D6, BIDI_R }, // NKO LETTER JA + { 0x07D7, BIDI_R }, // NKO LETTER CHA + { 0x07D8, BIDI_R }, // NKO LETTER DA + { 0x07D9, BIDI_R }, // NKO LETTER RA + { 0x07DA, BIDI_R }, // NKO LETTER RRA + { 0x07DB, BIDI_R }, // NKO LETTER SA + { 0x07DC, BIDI_R }, // NKO LETTER GBA + { 0x07DD, BIDI_R }, // NKO LETTER FA + { 0x07DE, BIDI_R }, // NKO LETTER KA + { 0x07DF, BIDI_R }, // NKO LETTER LA + { 0x07E0, BIDI_R }, // NKO LETTER NA WOLOSO + { 0x07E1, BIDI_R }, // NKO LETTER MA + { 0x07E2, BIDI_R }, // NKO LETTER NYA + { 0x07E3, BIDI_R }, // NKO LETTER NA + { 0x07E4, BIDI_R }, // NKO LETTER HA + { 0x07E5, BIDI_R }, // NKO LETTER WA + { 0x07E6, BIDI_R }, // NKO LETTER YA + { 0x07E7, BIDI_R }, // NKO LETTER NYA WOLOSO + { 0x07E8, BIDI_R }, // NKO LETTER JONA JA + { 0x07E9, BIDI_R }, // NKO LETTER JONA CHA + { 0x07EA, BIDI_R }, // NKO LETTER JONA RA + { 0x07EB, BIDI_NSM }, // NKO COMBINING SHORT HIGH TONE + { 0x07EC, BIDI_NSM }, // NKO COMBINING SHORT LOW TONE + { 0x07ED, BIDI_NSM }, // NKO COMBINING SHORT RISING TONE + { 0x07EE, BIDI_NSM }, // NKO COMBINING LONG DESCENDING TONE + { 0x07EF, BIDI_NSM }, // NKO COMBINING LONG HIGH TONE + { 0x07F0, BIDI_NSM }, // NKO COMBINING LONG LOW TONE + { 0x07F1, BIDI_NSM }, // NKO COMBINING LONG RISING TONE + { 0x07F2, BIDI_NSM }, // NKO COMBINING NASALIZATION MARK + { 0x07F3, BIDI_NSM }, // NKO COMBINING DOUBLE DOT ABOVE + { 0x07F4, BIDI_R }, // NKO HIGH TONE APOSTROPHE + { 0x07F5, BIDI_R }, // NKO LOW TONE APOSTROPHE + { 0x07F6, BIDI_ON }, // NKO SYMBOL OO DENNEN + { 0x07F7, BIDI_ON }, // NKO SYMBOL GBAKURUNEN + { 0x07F8, BIDI_ON }, // NKO COMMA + { 0x07F9, BIDI_ON }, // NKO EXCLAMATION MARK + { 0x07FA, BIDI_R }, // NKO LAJANYALAN + { 0x0800, BIDI_R }, // SAMARITAN LETTER ALAF + { 0x0801, BIDI_R }, // SAMARITAN LETTER BIT + { 0x0802, BIDI_R }, // SAMARITAN LETTER GAMAN + { 0x0803, BIDI_R }, // SAMARITAN LETTER DALAT + { 0x0804, BIDI_R }, // SAMARITAN LETTER IY + { 0x0805, BIDI_R }, // SAMARITAN LETTER BAA + { 0x0806, BIDI_R }, // SAMARITAN LETTER ZEN + { 0x0807, BIDI_R }, // SAMARITAN LETTER IT + { 0x0808, BIDI_R }, // SAMARITAN LETTER TIT + { 0x0809, BIDI_R }, // SAMARITAN LETTER YUT + { 0x080A, BIDI_R }, // SAMARITAN LETTER KAAF + { 0x080B, BIDI_R }, // SAMARITAN LETTER LABAT + { 0x080C, BIDI_R }, // SAMARITAN LETTER MIM + { 0x080D, BIDI_R }, // SAMARITAN LETTER NUN + { 0x080E, BIDI_R }, // SAMARITAN LETTER SINGAAT + { 0x080F, BIDI_R }, // SAMARITAN LETTER IN + { 0x0810, BIDI_R }, // SAMARITAN LETTER FI + { 0x0811, BIDI_R }, // SAMARITAN LETTER TSAADIY + { 0x0812, BIDI_R }, // SAMARITAN LETTER QUF + { 0x0813, BIDI_R }, // SAMARITAN LETTER RISH + { 0x0814, BIDI_R }, // SAMARITAN LETTER SHAN + { 0x0815, BIDI_R }, // SAMARITAN LETTER TAAF + { 0x0816, BIDI_NSM }, // SAMARITAN MARK IN + { 0x0817, BIDI_NSM }, // SAMARITAN MARK IN-ALAF + { 0x0818, BIDI_NSM }, // SAMARITAN MARK OCCLUSION + { 0x0819, BIDI_NSM }, // SAMARITAN MARK DAGESH + { 0x081A, BIDI_R }, // SAMARITAN MODIFIER LETTER EPENTHETIC YUT + { 0x081B, BIDI_NSM }, // SAMARITAN MARK EPENTHETIC YUT + { 0x081C, BIDI_NSM }, // SAMARITAN VOWEL SIGN LONG E + { 0x081D, BIDI_NSM }, // SAMARITAN VOWEL SIGN E + { 0x081E, BIDI_NSM }, // SAMARITAN VOWEL SIGN OVERLONG AA + { 0x081F, BIDI_NSM }, // SAMARITAN VOWEL SIGN LONG AA + { 0x0820, BIDI_NSM }, // SAMARITAN VOWEL SIGN AA + { 0x0821, BIDI_NSM }, // SAMARITAN VOWEL SIGN OVERLONG A + { 0x0822, BIDI_NSM }, // SAMARITAN VOWEL SIGN LONG A + { 0x0823, BIDI_NSM }, // SAMARITAN VOWEL SIGN A + { 0x0824, BIDI_R }, // SAMARITAN MODIFIER LETTER SHORT A + { 0x0825, BIDI_NSM }, // SAMARITAN VOWEL SIGN SHORT A + { 0x0826, BIDI_NSM }, // SAMARITAN VOWEL SIGN LONG U + { 0x0827, BIDI_NSM }, // SAMARITAN VOWEL SIGN U + { 0x0828, BIDI_R }, // SAMARITAN MODIFIER LETTER I + { 0x0829, BIDI_NSM }, // SAMARITAN VOWEL SIGN LONG I + { 0x082A, BIDI_NSM }, // SAMARITAN VOWEL SIGN I + { 0x082B, BIDI_NSM }, // SAMARITAN VOWEL SIGN O + { 0x082C, BIDI_NSM }, // SAMARITAN VOWEL SIGN SUKUN + { 0x082D, BIDI_NSM }, // SAMARITAN MARK NEQUDAA + { 0x0830, BIDI_R }, // SAMARITAN PUNCTUATION NEQUDAA + { 0x0831, BIDI_R }, // SAMARITAN PUNCTUATION AFSAAQ + { 0x0832, BIDI_R }, // SAMARITAN PUNCTUATION ANGED + { 0x0833, BIDI_R }, // SAMARITAN PUNCTUATION BAU + { 0x0834, BIDI_R }, // SAMARITAN PUNCTUATION ATMAAU + { 0x0835, BIDI_R }, // SAMARITAN PUNCTUATION SHIYYAALAA + { 0x0836, BIDI_R }, // SAMARITAN ABBREVIATION MARK + { 0x0837, BIDI_R }, // SAMARITAN PUNCTUATION MELODIC QITSA + { 0x0838, BIDI_R }, // SAMARITAN PUNCTUATION ZIQAA + { 0x0839, BIDI_R }, // SAMARITAN PUNCTUATION QITSA + { 0x083A, BIDI_R }, // SAMARITAN PUNCTUATION ZAEF + { 0x083B, BIDI_R }, // SAMARITAN PUNCTUATION TURU + { 0x083C, BIDI_R }, // SAMARITAN PUNCTUATION ARKAANU + { 0x083D, BIDI_R }, // SAMARITAN PUNCTUATION SOF MASHFAAT + { 0x083E, BIDI_R }, // SAMARITAN PUNCTUATION ANNAAU + { 0x0840, BIDI_R }, // MANDAIC LETTER HALQA + { 0x0841, BIDI_R }, // MANDAIC LETTER AB + { 0x0842, BIDI_R }, // MANDAIC LETTER AG + { 0x0843, BIDI_R }, // MANDAIC LETTER AD + { 0x0844, BIDI_R }, // MANDAIC LETTER AH + { 0x0845, BIDI_R }, // MANDAIC LETTER USHENNA + { 0x0846, BIDI_R }, // MANDAIC LETTER AZ + { 0x0847, BIDI_R }, // MANDAIC LETTER IT + { 0x0848, BIDI_R }, // MANDAIC LETTER ATT + { 0x0849, BIDI_R }, // MANDAIC LETTER AKSA + { 0x084A, BIDI_R }, // MANDAIC LETTER AK + { 0x084B, BIDI_R }, // MANDAIC LETTER AL + { 0x084C, BIDI_R }, // MANDAIC LETTER AM + { 0x084D, BIDI_R }, // MANDAIC LETTER AN + { 0x084E, BIDI_R }, // MANDAIC LETTER AS + { 0x084F, BIDI_R }, // MANDAIC LETTER IN + { 0x0850, BIDI_R }, // MANDAIC LETTER AP + { 0x0851, BIDI_R }, // MANDAIC LETTER ASZ + { 0x0852, BIDI_R }, // MANDAIC LETTER AQ + { 0x0853, BIDI_R }, // MANDAIC LETTER AR + { 0x0854, BIDI_R }, // MANDAIC LETTER ASH + { 0x0855, BIDI_R }, // MANDAIC LETTER AT + { 0x0856, BIDI_R }, // MANDAIC LETTER DUSHENNA + { 0x0857, BIDI_R }, // MANDAIC LETTER KAD + { 0x0858, BIDI_R }, // MANDAIC LETTER AIN + { 0x0859, BIDI_NSM }, // MANDAIC AFFRICATION MARK + { 0x085A, BIDI_NSM }, // MANDAIC VOCALIZATION MARK + { 0x085B, BIDI_NSM }, // MANDAIC GEMINATION MARK + { 0x085E, BIDI_R }, // MANDAIC PUNCTUATION + { 0x08A0, BIDI_AL }, // ARABIC LETTER BEH WITH SMALL V BELOW + { 0x08A1, BIDI_AL }, // ARABIC LETTER BEH WITH HAMZA ABOVE + { 0x08A2, BIDI_AL }, // ARABIC LETTER JEEM WITH TWO DOTS ABOVE + { 0x08A3, BIDI_AL }, // ARABIC LETTER TAH WITH TWO DOTS ABOVE + { 0x08A4, BIDI_AL }, // ARABIC LETTER FEH WITH DOT BELOW AND THREE DOTS ABOVE + { 0x08A5, BIDI_AL }, // ARABIC LETTER QAF WITH DOT BELOW + { 0x08A6, BIDI_AL }, // ARABIC LETTER LAM WITH DOUBLE BAR + { 0x08A7, BIDI_AL }, // ARABIC LETTER MEEM WITH THREE DOTS ABOVE + { 0x08A8, BIDI_AL }, // ARABIC LETTER YEH WITH TWO DOTS BELOW AND HAMZA ABOVE + { 0x08A9, BIDI_AL }, // ARABIC LETTER YEH WITH TWO DOTS BELOW AND DOT ABOVE + { 0x08AA, BIDI_AL }, // ARABIC LETTER REH WITH LOOP + { 0x08AB, BIDI_AL }, // ARABIC LETTER WAW WITH DOT WITHIN + { 0x08AC, BIDI_AL }, // ARABIC LETTER ROHINGYA YEH + { 0x08AD, BIDI_AL }, // ARABIC LETTER LOW ALEF + { 0x08AE, BIDI_AL }, // ARABIC LETTER DAL WITH THREE DOTS BELOW + { 0x08AF, BIDI_AL }, // ARABIC LETTER SAD WITH THREE DOTS BELOW + { 0x08B0, BIDI_AL }, // ARABIC LETTER GAF WITH INVERTED STROKE + { 0x08B1, BIDI_AL }, // ARABIC LETTER STRAIGHT WAW + { 0x08B2, BIDI_AL }, // ARABIC LETTER ZAIN WITH INVERTED V ABOVE + { 0x08B3, BIDI_AL }, // ARABIC LETTER AIN WITH THREE DOTS BELOW + { 0x08B4, BIDI_AL }, // ARABIC LETTER KAF WITH DOT BELOW + { 0x08E3, BIDI_NSM }, // ARABIC TURNED DAMMA BELOW + { 0x08E4, BIDI_NSM }, // ARABIC CURLY FATHA + { 0x08E5, BIDI_NSM }, // ARABIC CURLY DAMMA + { 0x08E6, BIDI_NSM }, // ARABIC CURLY KASRA + { 0x08E7, BIDI_NSM }, // ARABIC CURLY FATHATAN + { 0x08E8, BIDI_NSM }, // ARABIC CURLY DAMMATAN + { 0x08E9, BIDI_NSM }, // ARABIC CURLY KASRATAN + { 0x08EA, BIDI_NSM }, // ARABIC TONE ONE DOT ABOVE + { 0x08EB, BIDI_NSM }, // ARABIC TONE TWO DOTS ABOVE + { 0x08EC, BIDI_NSM }, // ARABIC TONE LOOP ABOVE + { 0x08ED, BIDI_NSM }, // ARABIC TONE ONE DOT BELOW + { 0x08EE, BIDI_NSM }, // ARABIC TONE TWO DOTS BELOW + { 0x08EF, BIDI_NSM }, // ARABIC TONE LOOP BELOW + { 0x08F0, BIDI_NSM }, // ARABIC OPEN FATHATAN + { 0x08F1, BIDI_NSM }, // ARABIC OPEN DAMMATAN + { 0x08F2, BIDI_NSM }, // ARABIC OPEN KASRATAN + { 0x08F3, BIDI_NSM }, // ARABIC SMALL HIGH WAW + { 0x08F4, BIDI_NSM }, // ARABIC FATHA WITH RING + { 0x08F5, BIDI_NSM }, // ARABIC FATHA WITH DOT ABOVE + { 0x08F6, BIDI_NSM }, // ARABIC KASRA WITH DOT BELOW + { 0x08F7, BIDI_NSM }, // ARABIC LEFT ARROWHEAD ABOVE + { 0x08F8, BIDI_NSM }, // ARABIC RIGHT ARROWHEAD ABOVE + { 0x08F9, BIDI_NSM }, // ARABIC LEFT ARROWHEAD BELOW + { 0x08FA, BIDI_NSM }, // ARABIC RIGHT ARROWHEAD BELOW + { 0x08FB, BIDI_NSM }, // ARABIC DOUBLE RIGHT ARROWHEAD ABOVE + { 0x08FC, BIDI_NSM }, // ARABIC DOUBLE RIGHT ARROWHEAD ABOVE WITH DOT + { 0x08FD, BIDI_NSM }, // ARABIC RIGHT ARROWHEAD ABOVE WITH DOT + { 0x08FE, BIDI_NSM }, // ARABIC DAMMA WITH DOT + { 0x08FF, BIDI_NSM }, // ARABIC MARK SIDEWAYS NOON GHUNNA + { 0x0900, BIDI_NSM }, // DEVANAGARI SIGN INVERTED CANDRABINDU + { 0x0901, BIDI_NSM }, // DEVANAGARI SIGN CANDRABINDU + { 0x0902, BIDI_NSM }, // DEVANAGARI SIGN ANUSVARA + { 0x0903, BIDI_L }, // DEVANAGARI SIGN VISARGA + { 0x0904, BIDI_L }, // DEVANAGARI LETTER SHORT A + { 0x0905, BIDI_L }, // DEVANAGARI LETTER A + { 0x0906, BIDI_L }, // DEVANAGARI LETTER AA + { 0x0907, BIDI_L }, // DEVANAGARI LETTER I + { 0x0908, BIDI_L }, // DEVANAGARI LETTER II + { 0x0909, BIDI_L }, // DEVANAGARI LETTER U + { 0x090A, BIDI_L }, // DEVANAGARI LETTER UU + { 0x090B, BIDI_L }, // DEVANAGARI LETTER VOCALIC R + { 0x090C, BIDI_L }, // DEVANAGARI LETTER VOCALIC L + { 0x090D, BIDI_L }, // DEVANAGARI LETTER CANDRA E + { 0x090E, BIDI_L }, // DEVANAGARI LETTER SHORT E + { 0x090F, BIDI_L }, // DEVANAGARI LETTER E + { 0x0910, BIDI_L }, // DEVANAGARI LETTER AI + { 0x0911, BIDI_L }, // DEVANAGARI LETTER CANDRA O + { 0x0912, BIDI_L }, // DEVANAGARI LETTER SHORT O + { 0x0913, BIDI_L }, // DEVANAGARI LETTER O + { 0x0914, BIDI_L }, // DEVANAGARI LETTER AU + { 0x0915, BIDI_L }, // DEVANAGARI LETTER KA + { 0x0916, BIDI_L }, // DEVANAGARI LETTER KHA + { 0x0917, BIDI_L }, // DEVANAGARI LETTER GA + { 0x0918, BIDI_L }, // DEVANAGARI LETTER GHA + { 0x0919, BIDI_L }, // DEVANAGARI LETTER NGA + { 0x091A, BIDI_L }, // DEVANAGARI LETTER CA + { 0x091B, BIDI_L }, // DEVANAGARI LETTER CHA + { 0x091C, BIDI_L }, // DEVANAGARI LETTER JA + { 0x091D, BIDI_L }, // DEVANAGARI LETTER JHA + { 0x091E, BIDI_L }, // DEVANAGARI LETTER NYA + { 0x091F, BIDI_L }, // DEVANAGARI LETTER TTA + { 0x0920, BIDI_L }, // DEVANAGARI LETTER TTHA + { 0x0921, BIDI_L }, // DEVANAGARI LETTER DDA + { 0x0922, BIDI_L }, // DEVANAGARI LETTER DDHA + { 0x0923, BIDI_L }, // DEVANAGARI LETTER NNA + { 0x0924, BIDI_L }, // DEVANAGARI LETTER TA + { 0x0925, BIDI_L }, // DEVANAGARI LETTER THA + { 0x0926, BIDI_L }, // DEVANAGARI LETTER DA + { 0x0927, BIDI_L }, // DEVANAGARI LETTER DHA + { 0x0928, BIDI_L }, // DEVANAGARI LETTER NA + { 0x0929, BIDI_L }, // DEVANAGARI LETTER NNNA + { 0x092A, BIDI_L }, // DEVANAGARI LETTER PA + { 0x092B, BIDI_L }, // DEVANAGARI LETTER PHA + { 0x092C, BIDI_L }, // DEVANAGARI LETTER BA + { 0x092D, BIDI_L }, // DEVANAGARI LETTER BHA + { 0x092E, BIDI_L }, // DEVANAGARI LETTER MA + { 0x092F, BIDI_L }, // DEVANAGARI LETTER YA + { 0x0930, BIDI_L }, // DEVANAGARI LETTER RA + { 0x0931, BIDI_L }, // DEVANAGARI LETTER RRA + { 0x0932, BIDI_L }, // DEVANAGARI LETTER LA + { 0x0933, BIDI_L }, // DEVANAGARI LETTER LLA + { 0x0934, BIDI_L }, // DEVANAGARI LETTER LLLA + { 0x0935, BIDI_L }, // DEVANAGARI LETTER VA + { 0x0936, BIDI_L }, // DEVANAGARI LETTER SHA + { 0x0937, BIDI_L }, // DEVANAGARI LETTER SSA + { 0x0938, BIDI_L }, // DEVANAGARI LETTER SA + { 0x0939, BIDI_L }, // DEVANAGARI LETTER HA + { 0x093A, BIDI_NSM }, // DEVANAGARI VOWEL SIGN OE + { 0x093B, BIDI_L }, // DEVANAGARI VOWEL SIGN OOE + { 0x093C, BIDI_NSM }, // DEVANAGARI SIGN NUKTA + { 0x093D, BIDI_L }, // DEVANAGARI SIGN AVAGRAHA + { 0x093E, BIDI_L }, // DEVANAGARI VOWEL SIGN AA + { 0x093F, BIDI_L }, // DEVANAGARI VOWEL SIGN I + { 0x0940, BIDI_L }, // DEVANAGARI VOWEL SIGN II + { 0x0941, BIDI_NSM }, // DEVANAGARI VOWEL SIGN U + { 0x0942, BIDI_NSM }, // DEVANAGARI VOWEL SIGN UU + { 0x0943, BIDI_NSM }, // DEVANAGARI VOWEL SIGN VOCALIC R + { 0x0944, BIDI_NSM }, // DEVANAGARI VOWEL SIGN VOCALIC RR + { 0x0945, BIDI_NSM }, // DEVANAGARI VOWEL SIGN CANDRA E + { 0x0946, BIDI_NSM }, // DEVANAGARI VOWEL SIGN SHORT E + { 0x0947, BIDI_NSM }, // DEVANAGARI VOWEL SIGN E + { 0x0948, BIDI_NSM }, // DEVANAGARI VOWEL SIGN AI + { 0x0949, BIDI_L }, // DEVANAGARI VOWEL SIGN CANDRA O + { 0x094A, BIDI_L }, // DEVANAGARI VOWEL SIGN SHORT O + { 0x094B, BIDI_L }, // DEVANAGARI VOWEL SIGN O + { 0x094C, BIDI_L }, // DEVANAGARI VOWEL SIGN AU + { 0x094D, BIDI_NSM }, // DEVANAGARI SIGN VIRAMA + { 0x094E, BIDI_L }, // DEVANAGARI VOWEL SIGN PRISHTHAMATRA E + { 0x094F, BIDI_L }, // DEVANAGARI VOWEL SIGN AW + { 0x0950, BIDI_L }, // DEVANAGARI OM + { 0x0951, BIDI_NSM }, // DEVANAGARI STRESS SIGN UDATTA + { 0x0952, BIDI_NSM }, // DEVANAGARI STRESS SIGN ANUDATTA + { 0x0953, BIDI_NSM }, // DEVANAGARI GRAVE ACCENT + { 0x0954, BIDI_NSM }, // DEVANAGARI ACUTE ACCENT + { 0x0955, BIDI_NSM }, // DEVANAGARI VOWEL SIGN CANDRA LONG E + { 0x0956, BIDI_NSM }, // DEVANAGARI VOWEL SIGN UE + { 0x0957, BIDI_NSM }, // DEVANAGARI VOWEL SIGN UUE + { 0x0958, BIDI_L }, // DEVANAGARI LETTER QA + { 0x0959, BIDI_L }, // DEVANAGARI LETTER KHHA + { 0x095A, BIDI_L }, // DEVANAGARI LETTER GHHA + { 0x095B, BIDI_L }, // DEVANAGARI LETTER ZA + { 0x095C, BIDI_L }, // DEVANAGARI LETTER DDDHA + { 0x095D, BIDI_L }, // DEVANAGARI LETTER RHA + { 0x095E, BIDI_L }, // DEVANAGARI LETTER FA + { 0x095F, BIDI_L }, // DEVANAGARI LETTER YYA + { 0x0960, BIDI_L }, // DEVANAGARI LETTER VOCALIC RR + { 0x0961, BIDI_L }, // DEVANAGARI LETTER VOCALIC LL + { 0x0962, BIDI_NSM }, // DEVANAGARI VOWEL SIGN VOCALIC L + { 0x0963, BIDI_NSM }, // DEVANAGARI VOWEL SIGN VOCALIC LL + { 0x0964, BIDI_L }, // DEVANAGARI DANDA + { 0x0965, BIDI_L }, // DEVANAGARI DOUBLE DANDA + { 0x0966, BIDI_L }, // DEVANAGARI DIGIT ZERO + { 0x0967, BIDI_L }, // DEVANAGARI DIGIT ONE + { 0x0968, BIDI_L }, // DEVANAGARI DIGIT TWO + { 0x0969, BIDI_L }, // DEVANAGARI DIGIT THREE + { 0x096A, BIDI_L }, // DEVANAGARI DIGIT FOUR + { 0x096B, BIDI_L }, // DEVANAGARI DIGIT FIVE + { 0x096C, BIDI_L }, // DEVANAGARI DIGIT SIX + { 0x096D, BIDI_L }, // DEVANAGARI DIGIT SEVEN + { 0x096E, BIDI_L }, // DEVANAGARI DIGIT EIGHT + { 0x096F, BIDI_L }, // DEVANAGARI DIGIT NINE + { 0x0970, BIDI_L }, // DEVANAGARI ABBREVIATION SIGN + { 0x0971, BIDI_L }, // DEVANAGARI SIGN HIGH SPACING DOT + { 0x0972, BIDI_L }, // DEVANAGARI LETTER CANDRA A + { 0x0973, BIDI_L }, // DEVANAGARI LETTER OE + { 0x0974, BIDI_L }, // DEVANAGARI LETTER OOE + { 0x0975, BIDI_L }, // DEVANAGARI LETTER AW + { 0x0976, BIDI_L }, // DEVANAGARI LETTER UE + { 0x0977, BIDI_L }, // DEVANAGARI LETTER UUE + { 0x0978, BIDI_L }, // DEVANAGARI LETTER MARWARI DDA + { 0x0979, BIDI_L }, // DEVANAGARI LETTER ZHA + { 0x097A, BIDI_L }, // DEVANAGARI LETTER HEAVY YA + { 0x097B, BIDI_L }, // DEVANAGARI LETTER GGA + { 0x097C, BIDI_L }, // DEVANAGARI LETTER JJA + { 0x097D, BIDI_L }, // DEVANAGARI LETTER GLOTTAL STOP + { 0x097E, BIDI_L }, // DEVANAGARI LETTER DDDA + { 0x097F, BIDI_L }, // DEVANAGARI LETTER BBA + { 0x0980, BIDI_L }, // BENGALI ANJI + { 0x0981, BIDI_NSM }, // BENGALI SIGN CANDRABINDU + { 0x0982, BIDI_L }, // BENGALI SIGN ANUSVARA + { 0x0983, BIDI_L }, // BENGALI SIGN VISARGA + { 0x0985, BIDI_L }, // BENGALI LETTER A + { 0x0986, BIDI_L }, // BENGALI LETTER AA + { 0x0987, BIDI_L }, // BENGALI LETTER I + { 0x0988, BIDI_L }, // BENGALI LETTER II + { 0x0989, BIDI_L }, // BENGALI LETTER U + { 0x098A, BIDI_L }, // BENGALI LETTER UU + { 0x098B, BIDI_L }, // BENGALI LETTER VOCALIC R + { 0x098C, BIDI_L }, // BENGALI LETTER VOCALIC L + { 0x098F, BIDI_L }, // BENGALI LETTER E + { 0x0990, BIDI_L }, // BENGALI LETTER AI + { 0x0993, BIDI_L }, // BENGALI LETTER O + { 0x0994, BIDI_L }, // BENGALI LETTER AU + { 0x0995, BIDI_L }, // BENGALI LETTER KA + { 0x0996, BIDI_L }, // BENGALI LETTER KHA + { 0x0997, BIDI_L }, // BENGALI LETTER GA + { 0x0998, BIDI_L }, // BENGALI LETTER GHA + { 0x0999, BIDI_L }, // BENGALI LETTER NGA + { 0x099A, BIDI_L }, // BENGALI LETTER CA + { 0x099B, BIDI_L }, // BENGALI LETTER CHA + { 0x099C, BIDI_L }, // BENGALI LETTER JA + { 0x099D, BIDI_L }, // BENGALI LETTER JHA + { 0x099E, BIDI_L }, // BENGALI LETTER NYA + { 0x099F, BIDI_L }, // BENGALI LETTER TTA + { 0x09A0, BIDI_L }, // BENGALI LETTER TTHA + { 0x09A1, BIDI_L }, // BENGALI LETTER DDA + { 0x09A2, BIDI_L }, // BENGALI LETTER DDHA + { 0x09A3, BIDI_L }, // BENGALI LETTER NNA + { 0x09A4, BIDI_L }, // BENGALI LETTER TA + { 0x09A5, BIDI_L }, // BENGALI LETTER THA + { 0x09A6, BIDI_L }, // BENGALI LETTER DA + { 0x09A7, BIDI_L }, // BENGALI LETTER DHA + { 0x09A8, BIDI_L }, // BENGALI LETTER NA + { 0x09AA, BIDI_L }, // BENGALI LETTER PA + { 0x09AB, BIDI_L }, // BENGALI LETTER PHA + { 0x09AC, BIDI_L }, // BENGALI LETTER BA + { 0x09AD, BIDI_L }, // BENGALI LETTER BHA + { 0x09AE, BIDI_L }, // BENGALI LETTER MA + { 0x09AF, BIDI_L }, // BENGALI LETTER YA + { 0x09B0, BIDI_L }, // BENGALI LETTER RA + { 0x09B2, BIDI_L }, // BENGALI LETTER LA + { 0x09B6, BIDI_L }, // BENGALI LETTER SHA + { 0x09B7, BIDI_L }, // BENGALI LETTER SSA + { 0x09B8, BIDI_L }, // BENGALI LETTER SA + { 0x09B9, BIDI_L }, // BENGALI LETTER HA + { 0x09BC, BIDI_NSM }, // BENGALI SIGN NUKTA + { 0x09BD, BIDI_L }, // BENGALI SIGN AVAGRAHA + { 0x09BE, BIDI_L }, // BENGALI VOWEL SIGN AA + { 0x09BF, BIDI_L }, // BENGALI VOWEL SIGN I + { 0x09C0, BIDI_L }, // BENGALI VOWEL SIGN II + { 0x09C1, BIDI_NSM }, // BENGALI VOWEL SIGN U + { 0x09C2, BIDI_NSM }, // BENGALI VOWEL SIGN UU + { 0x09C3, BIDI_NSM }, // BENGALI VOWEL SIGN VOCALIC R + { 0x09C4, BIDI_NSM }, // BENGALI VOWEL SIGN VOCALIC RR + { 0x09C7, BIDI_L }, // BENGALI VOWEL SIGN E + { 0x09C8, BIDI_L }, // BENGALI VOWEL SIGN AI + { 0x09CB, BIDI_L }, // BENGALI VOWEL SIGN O + { 0x09CC, BIDI_L }, // BENGALI VOWEL SIGN AU + { 0x09CD, BIDI_NSM }, // BENGALI SIGN VIRAMA + { 0x09CE, BIDI_L }, // BENGALI LETTER KHANDA TA + { 0x09D7, BIDI_L }, // BENGALI AU LENGTH MARK + { 0x09DC, BIDI_L }, // BENGALI LETTER RRA + { 0x09DD, BIDI_L }, // BENGALI LETTER RHA + { 0x09DF, BIDI_L }, // BENGALI LETTER YYA + { 0x09E0, BIDI_L }, // BENGALI LETTER VOCALIC RR + { 0x09E1, BIDI_L }, // BENGALI LETTER VOCALIC LL + { 0x09E2, BIDI_NSM }, // BENGALI VOWEL SIGN VOCALIC L + { 0x09E3, BIDI_NSM }, // BENGALI VOWEL SIGN VOCALIC LL + { 0x09E6, BIDI_L }, // BENGALI DIGIT ZERO + { 0x09E7, BIDI_L }, // BENGALI DIGIT ONE + { 0x09E8, BIDI_L }, // BENGALI DIGIT TWO + { 0x09E9, BIDI_L }, // BENGALI DIGIT THREE + { 0x09EA, BIDI_L }, // BENGALI DIGIT FOUR + { 0x09EB, BIDI_L }, // BENGALI DIGIT FIVE + { 0x09EC, BIDI_L }, // BENGALI DIGIT SIX + { 0x09ED, BIDI_L }, // BENGALI DIGIT SEVEN + { 0x09EE, BIDI_L }, // BENGALI DIGIT EIGHT + { 0x09EF, BIDI_L }, // BENGALI DIGIT NINE + { 0x09F0, BIDI_L }, // BENGALI LETTER RA WITH MIDDLE DIAGONAL + { 0x09F1, BIDI_L }, // BENGALI LETTER RA WITH LOWER DIAGONAL + { 0x09F2, BIDI_ET }, // BENGALI RUPEE MARK + { 0x09F3, BIDI_ET }, // BENGALI RUPEE SIGN + { 0x09F4, BIDI_L }, // BENGALI CURRENCY NUMERATOR ONE + { 0x09F5, BIDI_L }, // BENGALI CURRENCY NUMERATOR TWO + { 0x09F6, BIDI_L }, // BENGALI CURRENCY NUMERATOR THREE + { 0x09F7, BIDI_L }, // BENGALI CURRENCY NUMERATOR FOUR + { 0x09F8, BIDI_L }, // BENGALI CURRENCY NUMERATOR ONE LESS THAN THE DENOMINATOR + { 0x09F9, BIDI_L }, // BENGALI CURRENCY DENOMINATOR SIXTEEN + { 0x09FA, BIDI_L }, // BENGALI ISSHAR + { 0x09FB, BIDI_ET }, // BENGALI GANDA MARK + { 0x0A01, BIDI_NSM }, // GURMUKHI SIGN ADAK BINDI + { 0x0A02, BIDI_NSM }, // GURMUKHI SIGN BINDI + { 0x0A03, BIDI_L }, // GURMUKHI SIGN VISARGA + { 0x0A05, BIDI_L }, // GURMUKHI LETTER A + { 0x0A06, BIDI_L }, // GURMUKHI LETTER AA + { 0x0A07, BIDI_L }, // GURMUKHI LETTER I + { 0x0A08, BIDI_L }, // GURMUKHI LETTER II + { 0x0A09, BIDI_L }, // GURMUKHI LETTER U + { 0x0A0A, BIDI_L }, // GURMUKHI LETTER UU + { 0x0A0F, BIDI_L }, // GURMUKHI LETTER EE + { 0x0A10, BIDI_L }, // GURMUKHI LETTER AI + { 0x0A13, BIDI_L }, // GURMUKHI LETTER OO + { 0x0A14, BIDI_L }, // GURMUKHI LETTER AU + { 0x0A15, BIDI_L }, // GURMUKHI LETTER KA + { 0x0A16, BIDI_L }, // GURMUKHI LETTER KHA + { 0x0A17, BIDI_L }, // GURMUKHI LETTER GA + { 0x0A18, BIDI_L }, // GURMUKHI LETTER GHA + { 0x0A19, BIDI_L }, // GURMUKHI LETTER NGA + { 0x0A1A, BIDI_L }, // GURMUKHI LETTER CA + { 0x0A1B, BIDI_L }, // GURMUKHI LETTER CHA + { 0x0A1C, BIDI_L }, // GURMUKHI LETTER JA + { 0x0A1D, BIDI_L }, // GURMUKHI LETTER JHA + { 0x0A1E, BIDI_L }, // GURMUKHI LETTER NYA + { 0x0A1F, BIDI_L }, // GURMUKHI LETTER TTA + { 0x0A20, BIDI_L }, // GURMUKHI LETTER TTHA + { 0x0A21, BIDI_L }, // GURMUKHI LETTER DDA + { 0x0A22, BIDI_L }, // GURMUKHI LETTER DDHA + { 0x0A23, BIDI_L }, // GURMUKHI LETTER NNA + { 0x0A24, BIDI_L }, // GURMUKHI LETTER TA + { 0x0A25, BIDI_L }, // GURMUKHI LETTER THA + { 0x0A26, BIDI_L }, // GURMUKHI LETTER DA + { 0x0A27, BIDI_L }, // GURMUKHI LETTER DHA + { 0x0A28, BIDI_L }, // GURMUKHI LETTER NA + { 0x0A2A, BIDI_L }, // GURMUKHI LETTER PA + { 0x0A2B, BIDI_L }, // GURMUKHI LETTER PHA + { 0x0A2C, BIDI_L }, // GURMUKHI LETTER BA + { 0x0A2D, BIDI_L }, // GURMUKHI LETTER BHA + { 0x0A2E, BIDI_L }, // GURMUKHI LETTER MA + { 0x0A2F, BIDI_L }, // GURMUKHI LETTER YA + { 0x0A30, BIDI_L }, // GURMUKHI LETTER RA + { 0x0A32, BIDI_L }, // GURMUKHI LETTER LA + { 0x0A33, BIDI_L }, // GURMUKHI LETTER LLA + { 0x0A35, BIDI_L }, // GURMUKHI LETTER VA + { 0x0A36, BIDI_L }, // GURMUKHI LETTER SHA + { 0x0A38, BIDI_L }, // GURMUKHI LETTER SA + { 0x0A39, BIDI_L }, // GURMUKHI LETTER HA + { 0x0A3C, BIDI_NSM }, // GURMUKHI SIGN NUKTA + { 0x0A3E, BIDI_L }, // GURMUKHI VOWEL SIGN AA + { 0x0A3F, BIDI_L }, // GURMUKHI VOWEL SIGN I + { 0x0A40, BIDI_L }, // GURMUKHI VOWEL SIGN II + { 0x0A41, BIDI_NSM }, // GURMUKHI VOWEL SIGN U + { 0x0A42, BIDI_NSM }, // GURMUKHI VOWEL SIGN UU + { 0x0A47, BIDI_NSM }, // GURMUKHI VOWEL SIGN EE + { 0x0A48, BIDI_NSM }, // GURMUKHI VOWEL SIGN AI + { 0x0A4B, BIDI_NSM }, // GURMUKHI VOWEL SIGN OO + { 0x0A4C, BIDI_NSM }, // GURMUKHI VOWEL SIGN AU + { 0x0A4D, BIDI_NSM }, // GURMUKHI SIGN VIRAMA + { 0x0A51, BIDI_NSM }, // GURMUKHI SIGN UDAAT + { 0x0A59, BIDI_L }, // GURMUKHI LETTER KHHA + { 0x0A5A, BIDI_L }, // GURMUKHI LETTER GHHA + { 0x0A5B, BIDI_L }, // GURMUKHI LETTER ZA + { 0x0A5C, BIDI_L }, // GURMUKHI LETTER RRA + { 0x0A5E, BIDI_L }, // GURMUKHI LETTER FA + { 0x0A66, BIDI_L }, // GURMUKHI DIGIT ZERO + { 0x0A67, BIDI_L }, // GURMUKHI DIGIT ONE + { 0x0A68, BIDI_L }, // GURMUKHI DIGIT TWO + { 0x0A69, BIDI_L }, // GURMUKHI DIGIT THREE + { 0x0A6A, BIDI_L }, // GURMUKHI DIGIT FOUR + { 0x0A6B, BIDI_L }, // GURMUKHI DIGIT FIVE + { 0x0A6C, BIDI_L }, // GURMUKHI DIGIT SIX + { 0x0A6D, BIDI_L }, // GURMUKHI DIGIT SEVEN + { 0x0A6E, BIDI_L }, // GURMUKHI DIGIT EIGHT + { 0x0A6F, BIDI_L }, // GURMUKHI DIGIT NINE + { 0x0A70, BIDI_NSM }, // GURMUKHI TIPPI + { 0x0A71, BIDI_NSM }, // GURMUKHI ADDAK + { 0x0A72, BIDI_L }, // GURMUKHI IRI + { 0x0A73, BIDI_L }, // GURMUKHI URA + { 0x0A74, BIDI_L }, // GURMUKHI EK ONKAR + { 0x0A75, BIDI_NSM }, // GURMUKHI SIGN YAKASH + { 0x0A81, BIDI_NSM }, // GUJARATI SIGN CANDRABINDU + { 0x0A82, BIDI_NSM }, // GUJARATI SIGN ANUSVARA + { 0x0A83, BIDI_L }, // GUJARATI SIGN VISARGA + { 0x0A85, BIDI_L }, // GUJARATI LETTER A + { 0x0A86, BIDI_L }, // GUJARATI LETTER AA + { 0x0A87, BIDI_L }, // GUJARATI LETTER I + { 0x0A88, BIDI_L }, // GUJARATI LETTER II + { 0x0A89, BIDI_L }, // GUJARATI LETTER U + { 0x0A8A, BIDI_L }, // GUJARATI LETTER UU + { 0x0A8B, BIDI_L }, // GUJARATI LETTER VOCALIC R + { 0x0A8C, BIDI_L }, // GUJARATI LETTER VOCALIC L + { 0x0A8D, BIDI_L }, // GUJARATI VOWEL CANDRA E + { 0x0A8F, BIDI_L }, // GUJARATI LETTER E + { 0x0A90, BIDI_L }, // GUJARATI LETTER AI + { 0x0A91, BIDI_L }, // GUJARATI VOWEL CANDRA O + { 0x0A93, BIDI_L }, // GUJARATI LETTER O + { 0x0A94, BIDI_L }, // GUJARATI LETTER AU + { 0x0A95, BIDI_L }, // GUJARATI LETTER KA + { 0x0A96, BIDI_L }, // GUJARATI LETTER KHA + { 0x0A97, BIDI_L }, // GUJARATI LETTER GA + { 0x0A98, BIDI_L }, // GUJARATI LETTER GHA + { 0x0A99, BIDI_L }, // GUJARATI LETTER NGA + { 0x0A9A, BIDI_L }, // GUJARATI LETTER CA + { 0x0A9B, BIDI_L }, // GUJARATI LETTER CHA + { 0x0A9C, BIDI_L }, // GUJARATI LETTER JA + { 0x0A9D, BIDI_L }, // GUJARATI LETTER JHA + { 0x0A9E, BIDI_L }, // GUJARATI LETTER NYA + { 0x0A9F, BIDI_L }, // GUJARATI LETTER TTA + { 0x0AA0, BIDI_L }, // GUJARATI LETTER TTHA + { 0x0AA1, BIDI_L }, // GUJARATI LETTER DDA + { 0x0AA2, BIDI_L }, // GUJARATI LETTER DDHA + { 0x0AA3, BIDI_L }, // GUJARATI LETTER NNA + { 0x0AA4, BIDI_L }, // GUJARATI LETTER TA + { 0x0AA5, BIDI_L }, // GUJARATI LETTER THA + { 0x0AA6, BIDI_L }, // GUJARATI LETTER DA + { 0x0AA7, BIDI_L }, // GUJARATI LETTER DHA + { 0x0AA8, BIDI_L }, // GUJARATI LETTER NA + { 0x0AAA, BIDI_L }, // GUJARATI LETTER PA + { 0x0AAB, BIDI_L }, // GUJARATI LETTER PHA + { 0x0AAC, BIDI_L }, // GUJARATI LETTER BA + { 0x0AAD, BIDI_L }, // GUJARATI LETTER BHA + { 0x0AAE, BIDI_L }, // GUJARATI LETTER MA + { 0x0AAF, BIDI_L }, // GUJARATI LETTER YA + { 0x0AB0, BIDI_L }, // GUJARATI LETTER RA + { 0x0AB2, BIDI_L }, // GUJARATI LETTER LA + { 0x0AB3, BIDI_L }, // GUJARATI LETTER LLA + { 0x0AB5, BIDI_L }, // GUJARATI LETTER VA + { 0x0AB6, BIDI_L }, // GUJARATI LETTER SHA + { 0x0AB7, BIDI_L }, // GUJARATI LETTER SSA + { 0x0AB8, BIDI_L }, // GUJARATI LETTER SA + { 0x0AB9, BIDI_L }, // GUJARATI LETTER HA + { 0x0ABC, BIDI_NSM }, // GUJARATI SIGN NUKTA + { 0x0ABD, BIDI_L }, // GUJARATI SIGN AVAGRAHA + { 0x0ABE, BIDI_L }, // GUJARATI VOWEL SIGN AA + { 0x0ABF, BIDI_L }, // GUJARATI VOWEL SIGN I + { 0x0AC0, BIDI_L }, // GUJARATI VOWEL SIGN II + { 0x0AC1, BIDI_NSM }, // GUJARATI VOWEL SIGN U + { 0x0AC2, BIDI_NSM }, // GUJARATI VOWEL SIGN UU + { 0x0AC3, BIDI_NSM }, // GUJARATI VOWEL SIGN VOCALIC R + { 0x0AC4, BIDI_NSM }, // GUJARATI VOWEL SIGN VOCALIC RR + { 0x0AC5, BIDI_NSM }, // GUJARATI VOWEL SIGN CANDRA E + { 0x0AC7, BIDI_NSM }, // GUJARATI VOWEL SIGN E + { 0x0AC8, BIDI_NSM }, // GUJARATI VOWEL SIGN AI + { 0x0AC9, BIDI_L }, // GUJARATI VOWEL SIGN CANDRA O + { 0x0ACB, BIDI_L }, // GUJARATI VOWEL SIGN O + { 0x0ACC, BIDI_L }, // GUJARATI VOWEL SIGN AU + { 0x0ACD, BIDI_NSM }, // GUJARATI SIGN VIRAMA + { 0x0AD0, BIDI_L }, // GUJARATI OM + { 0x0AE0, BIDI_L }, // GUJARATI LETTER VOCALIC RR + { 0x0AE1, BIDI_L }, // GUJARATI LETTER VOCALIC LL + { 0x0AE2, BIDI_NSM }, // GUJARATI VOWEL SIGN VOCALIC L + { 0x0AE3, BIDI_NSM }, // GUJARATI VOWEL SIGN VOCALIC LL + { 0x0AE6, BIDI_L }, // GUJARATI DIGIT ZERO + { 0x0AE7, BIDI_L }, // GUJARATI DIGIT ONE + { 0x0AE8, BIDI_L }, // GUJARATI DIGIT TWO + { 0x0AE9, BIDI_L }, // GUJARATI DIGIT THREE + { 0x0AEA, BIDI_L }, // GUJARATI DIGIT FOUR + { 0x0AEB, BIDI_L }, // GUJARATI DIGIT FIVE + { 0x0AEC, BIDI_L }, // GUJARATI DIGIT SIX + { 0x0AED, BIDI_L }, // GUJARATI DIGIT SEVEN + { 0x0AEE, BIDI_L }, // GUJARATI DIGIT EIGHT + { 0x0AEF, BIDI_L }, // GUJARATI DIGIT NINE + { 0x0AF0, BIDI_L }, // GUJARATI ABBREVIATION SIGN + { 0x0AF1, BIDI_ET }, // GUJARATI RUPEE SIGN + { 0x0AF9, BIDI_L }, // GUJARATI LETTER ZHA + { 0x0B01, BIDI_NSM }, // ORIYA SIGN CANDRABINDU + { 0x0B02, BIDI_L }, // ORIYA SIGN ANUSVARA + { 0x0B03, BIDI_L }, // ORIYA SIGN VISARGA + { 0x0B05, BIDI_L }, // ORIYA LETTER A + { 0x0B06, BIDI_L }, // ORIYA LETTER AA + { 0x0B07, BIDI_L }, // ORIYA LETTER I + { 0x0B08, BIDI_L }, // ORIYA LETTER II + { 0x0B09, BIDI_L }, // ORIYA LETTER U + { 0x0B0A, BIDI_L }, // ORIYA LETTER UU + { 0x0B0B, BIDI_L }, // ORIYA LETTER VOCALIC R + { 0x0B0C, BIDI_L }, // ORIYA LETTER VOCALIC L + { 0x0B0F, BIDI_L }, // ORIYA LETTER E + { 0x0B10, BIDI_L }, // ORIYA LETTER AI + { 0x0B13, BIDI_L }, // ORIYA LETTER O + { 0x0B14, BIDI_L }, // ORIYA LETTER AU + { 0x0B15, BIDI_L }, // ORIYA LETTER KA + { 0x0B16, BIDI_L }, // ORIYA LETTER KHA + { 0x0B17, BIDI_L }, // ORIYA LETTER GA + { 0x0B18, BIDI_L }, // ORIYA LETTER GHA + { 0x0B19, BIDI_L }, // ORIYA LETTER NGA + { 0x0B1A, BIDI_L }, // ORIYA LETTER CA + { 0x0B1B, BIDI_L }, // ORIYA LETTER CHA + { 0x0B1C, BIDI_L }, // ORIYA LETTER JA + { 0x0B1D, BIDI_L }, // ORIYA LETTER JHA + { 0x0B1E, BIDI_L }, // ORIYA LETTER NYA + { 0x0B1F, BIDI_L }, // ORIYA LETTER TTA + { 0x0B20, BIDI_L }, // ORIYA LETTER TTHA + { 0x0B21, BIDI_L }, // ORIYA LETTER DDA + { 0x0B22, BIDI_L }, // ORIYA LETTER DDHA + { 0x0B23, BIDI_L }, // ORIYA LETTER NNA + { 0x0B24, BIDI_L }, // ORIYA LETTER TA + { 0x0B25, BIDI_L }, // ORIYA LETTER THA + { 0x0B26, BIDI_L }, // ORIYA LETTER DA + { 0x0B27, BIDI_L }, // ORIYA LETTER DHA + { 0x0B28, BIDI_L }, // ORIYA LETTER NA + { 0x0B2A, BIDI_L }, // ORIYA LETTER PA + { 0x0B2B, BIDI_L }, // ORIYA LETTER PHA + { 0x0B2C, BIDI_L }, // ORIYA LETTER BA + { 0x0B2D, BIDI_L }, // ORIYA LETTER BHA + { 0x0B2E, BIDI_L }, // ORIYA LETTER MA + { 0x0B2F, BIDI_L }, // ORIYA LETTER YA + { 0x0B30, BIDI_L }, // ORIYA LETTER RA + { 0x0B32, BIDI_L }, // ORIYA LETTER LA + { 0x0B33, BIDI_L }, // ORIYA LETTER LLA + { 0x0B35, BIDI_L }, // ORIYA LETTER VA + { 0x0B36, BIDI_L }, // ORIYA LETTER SHA + { 0x0B37, BIDI_L }, // ORIYA LETTER SSA + { 0x0B38, BIDI_L }, // ORIYA LETTER SA + { 0x0B39, BIDI_L }, // ORIYA LETTER HA + { 0x0B3C, BIDI_NSM }, // ORIYA SIGN NUKTA + { 0x0B3D, BIDI_L }, // ORIYA SIGN AVAGRAHA + { 0x0B3E, BIDI_L }, // ORIYA VOWEL SIGN AA + { 0x0B3F, BIDI_NSM }, // ORIYA VOWEL SIGN I + { 0x0B40, BIDI_L }, // ORIYA VOWEL SIGN II + { 0x0B41, BIDI_NSM }, // ORIYA VOWEL SIGN U + { 0x0B42, BIDI_NSM }, // ORIYA VOWEL SIGN UU + { 0x0B43, BIDI_NSM }, // ORIYA VOWEL SIGN VOCALIC R + { 0x0B44, BIDI_NSM }, // ORIYA VOWEL SIGN VOCALIC RR + { 0x0B47, BIDI_L }, // ORIYA VOWEL SIGN E + { 0x0B48, BIDI_L }, // ORIYA VOWEL SIGN AI + { 0x0B4B, BIDI_L }, // ORIYA VOWEL SIGN O + { 0x0B4C, BIDI_L }, // ORIYA VOWEL SIGN AU + { 0x0B4D, BIDI_NSM }, // ORIYA SIGN VIRAMA + { 0x0B56, BIDI_NSM }, // ORIYA AI LENGTH MARK + { 0x0B57, BIDI_L }, // ORIYA AU LENGTH MARK + { 0x0B5C, BIDI_L }, // ORIYA LETTER RRA + { 0x0B5D, BIDI_L }, // ORIYA LETTER RHA + { 0x0B5F, BIDI_L }, // ORIYA LETTER YYA + { 0x0B60, BIDI_L }, // ORIYA LETTER VOCALIC RR + { 0x0B61, BIDI_L }, // ORIYA LETTER VOCALIC LL + { 0x0B62, BIDI_NSM }, // ORIYA VOWEL SIGN VOCALIC L + { 0x0B63, BIDI_NSM }, // ORIYA VOWEL SIGN VOCALIC LL + { 0x0B66, BIDI_L }, // ORIYA DIGIT ZERO + { 0x0B67, BIDI_L }, // ORIYA DIGIT ONE + { 0x0B68, BIDI_L }, // ORIYA DIGIT TWO + { 0x0B69, BIDI_L }, // ORIYA DIGIT THREE + { 0x0B6A, BIDI_L }, // ORIYA DIGIT FOUR + { 0x0B6B, BIDI_L }, // ORIYA DIGIT FIVE + { 0x0B6C, BIDI_L }, // ORIYA DIGIT SIX + { 0x0B6D, BIDI_L }, // ORIYA DIGIT SEVEN + { 0x0B6E, BIDI_L }, // ORIYA DIGIT EIGHT + { 0x0B6F, BIDI_L }, // ORIYA DIGIT NINE + { 0x0B70, BIDI_L }, // ORIYA ISSHAR + { 0x0B71, BIDI_L }, // ORIYA LETTER WA + { 0x0B72, BIDI_L }, // ORIYA FRACTION ONE QUARTER + { 0x0B73, BIDI_L }, // ORIYA FRACTION ONE HALF + { 0x0B74, BIDI_L }, // ORIYA FRACTION THREE QUARTERS + { 0x0B75, BIDI_L }, // ORIYA FRACTION ONE SIXTEENTH + { 0x0B76, BIDI_L }, // ORIYA FRACTION ONE EIGHTH + { 0x0B77, BIDI_L }, // ORIYA FRACTION THREE SIXTEENTHS + { 0x0B82, BIDI_NSM }, // TAMIL SIGN ANUSVARA + { 0x0B83, BIDI_L }, // TAMIL SIGN VISARGA + { 0x0B85, BIDI_L }, // TAMIL LETTER A + { 0x0B86, BIDI_L }, // TAMIL LETTER AA + { 0x0B87, BIDI_L }, // TAMIL LETTER I + { 0x0B88, BIDI_L }, // TAMIL LETTER II + { 0x0B89, BIDI_L }, // TAMIL LETTER U + { 0x0B8A, BIDI_L }, // TAMIL LETTER UU + { 0x0B8E, BIDI_L }, // TAMIL LETTER E + { 0x0B8F, BIDI_L }, // TAMIL LETTER EE + { 0x0B90, BIDI_L }, // TAMIL LETTER AI + { 0x0B92, BIDI_L }, // TAMIL LETTER O + { 0x0B93, BIDI_L }, // TAMIL LETTER OO + { 0x0B94, BIDI_L }, // TAMIL LETTER AU + { 0x0B95, BIDI_L }, // TAMIL LETTER KA + { 0x0B99, BIDI_L }, // TAMIL LETTER NGA + { 0x0B9A, BIDI_L }, // TAMIL LETTER CA + { 0x0B9C, BIDI_L }, // TAMIL LETTER JA + { 0x0B9E, BIDI_L }, // TAMIL LETTER NYA + { 0x0B9F, BIDI_L }, // TAMIL LETTER TTA + { 0x0BA3, BIDI_L }, // TAMIL LETTER NNA + { 0x0BA4, BIDI_L }, // TAMIL LETTER TA + { 0x0BA8, BIDI_L }, // TAMIL LETTER NA + { 0x0BA9, BIDI_L }, // TAMIL LETTER NNNA + { 0x0BAA, BIDI_L }, // TAMIL LETTER PA + { 0x0BAE, BIDI_L }, // TAMIL LETTER MA + { 0x0BAF, BIDI_L }, // TAMIL LETTER YA + { 0x0BB0, BIDI_L }, // TAMIL LETTER RA + { 0x0BB1, BIDI_L }, // TAMIL LETTER RRA + { 0x0BB2, BIDI_L }, // TAMIL LETTER LA + { 0x0BB3, BIDI_L }, // TAMIL LETTER LLA + { 0x0BB4, BIDI_L }, // TAMIL LETTER LLLA + { 0x0BB5, BIDI_L }, // TAMIL LETTER VA + { 0x0BB6, BIDI_L }, // TAMIL LETTER SHA + { 0x0BB7, BIDI_L }, // TAMIL LETTER SSA + { 0x0BB8, BIDI_L }, // TAMIL LETTER SA + { 0x0BB9, BIDI_L }, // TAMIL LETTER HA + { 0x0BBE, BIDI_L }, // TAMIL VOWEL SIGN AA + { 0x0BBF, BIDI_L }, // TAMIL VOWEL SIGN I + { 0x0BC0, BIDI_NSM }, // TAMIL VOWEL SIGN II + { 0x0BC1, BIDI_L }, // TAMIL VOWEL SIGN U + { 0x0BC2, BIDI_L }, // TAMIL VOWEL SIGN UU + { 0x0BC6, BIDI_L }, // TAMIL VOWEL SIGN E + { 0x0BC7, BIDI_L }, // TAMIL VOWEL SIGN EE + { 0x0BC8, BIDI_L }, // TAMIL VOWEL SIGN AI + { 0x0BCA, BIDI_L }, // TAMIL VOWEL SIGN O + { 0x0BCB, BIDI_L }, // TAMIL VOWEL SIGN OO + { 0x0BCC, BIDI_L }, // TAMIL VOWEL SIGN AU + { 0x0BCD, BIDI_NSM }, // TAMIL SIGN VIRAMA + { 0x0BD0, BIDI_L }, // TAMIL OM + { 0x0BD7, BIDI_L }, // TAMIL AU LENGTH MARK + { 0x0BE6, BIDI_L }, // TAMIL DIGIT ZERO + { 0x0BE7, BIDI_L }, // TAMIL DIGIT ONE + { 0x0BE8, BIDI_L }, // TAMIL DIGIT TWO + { 0x0BE9, BIDI_L }, // TAMIL DIGIT THREE + { 0x0BEA, BIDI_L }, // TAMIL DIGIT FOUR + { 0x0BEB, BIDI_L }, // TAMIL DIGIT FIVE + { 0x0BEC, BIDI_L }, // TAMIL DIGIT SIX + { 0x0BED, BIDI_L }, // TAMIL DIGIT SEVEN + { 0x0BEE, BIDI_L }, // TAMIL DIGIT EIGHT + { 0x0BEF, BIDI_L }, // TAMIL DIGIT NINE + { 0x0BF0, BIDI_L }, // TAMIL NUMBER TEN + { 0x0BF1, BIDI_L }, // TAMIL NUMBER ONE HUNDRED + { 0x0BF2, BIDI_L }, // TAMIL NUMBER ONE THOUSAND + { 0x0BF3, BIDI_ON }, // TAMIL DAY SIGN + { 0x0BF4, BIDI_ON }, // TAMIL MONTH SIGN + { 0x0BF5, BIDI_ON }, // TAMIL YEAR SIGN + { 0x0BF6, BIDI_ON }, // TAMIL DEBIT SIGN + { 0x0BF7, BIDI_ON }, // TAMIL CREDIT SIGN + { 0x0BF8, BIDI_ON }, // TAMIL AS ABOVE SIGN + { 0x0BF9, BIDI_ET }, // TAMIL RUPEE SIGN + { 0x0BFA, BIDI_ON }, // TAMIL NUMBER SIGN + { 0x0C00, BIDI_NSM }, // TELUGU SIGN COMBINING CANDRABINDU ABOVE + { 0x0C01, BIDI_L }, // TELUGU SIGN CANDRABINDU + { 0x0C02, BIDI_L }, // TELUGU SIGN ANUSVARA + { 0x0C03, BIDI_L }, // TELUGU SIGN VISARGA + { 0x0C05, BIDI_L }, // TELUGU LETTER A + { 0x0C06, BIDI_L }, // TELUGU LETTER AA + { 0x0C07, BIDI_L }, // TELUGU LETTER I + { 0x0C08, BIDI_L }, // TELUGU LETTER II + { 0x0C09, BIDI_L }, // TELUGU LETTER U + { 0x0C0A, BIDI_L }, // TELUGU LETTER UU + { 0x0C0B, BIDI_L }, // TELUGU LETTER VOCALIC R + { 0x0C0C, BIDI_L }, // TELUGU LETTER VOCALIC L + { 0x0C0E, BIDI_L }, // TELUGU LETTER E + { 0x0C0F, BIDI_L }, // TELUGU LETTER EE + { 0x0C10, BIDI_L }, // TELUGU LETTER AI + { 0x0C12, BIDI_L }, // TELUGU LETTER O + { 0x0C13, BIDI_L }, // TELUGU LETTER OO + { 0x0C14, BIDI_L }, // TELUGU LETTER AU + { 0x0C15, BIDI_L }, // TELUGU LETTER KA + { 0x0C16, BIDI_L }, // TELUGU LETTER KHA + { 0x0C17, BIDI_L }, // TELUGU LETTER GA + { 0x0C18, BIDI_L }, // TELUGU LETTER GHA + { 0x0C19, BIDI_L }, // TELUGU LETTER NGA + { 0x0C1A, BIDI_L }, // TELUGU LETTER CA + { 0x0C1B, BIDI_L }, // TELUGU LETTER CHA + { 0x0C1C, BIDI_L }, // TELUGU LETTER JA + { 0x0C1D, BIDI_L }, // TELUGU LETTER JHA + { 0x0C1E, BIDI_L }, // TELUGU LETTER NYA + { 0x0C1F, BIDI_L }, // TELUGU LETTER TTA + { 0x0C20, BIDI_L }, // TELUGU LETTER TTHA + { 0x0C21, BIDI_L }, // TELUGU LETTER DDA + { 0x0C22, BIDI_L }, // TELUGU LETTER DDHA + { 0x0C23, BIDI_L }, // TELUGU LETTER NNA + { 0x0C24, BIDI_L }, // TELUGU LETTER TA + { 0x0C25, BIDI_L }, // TELUGU LETTER THA + { 0x0C26, BIDI_L }, // TELUGU LETTER DA + { 0x0C27, BIDI_L }, // TELUGU LETTER DHA + { 0x0C28, BIDI_L }, // TELUGU LETTER NA + { 0x0C2A, BIDI_L }, // TELUGU LETTER PA + { 0x0C2B, BIDI_L }, // TELUGU LETTER PHA + { 0x0C2C, BIDI_L }, // TELUGU LETTER BA + { 0x0C2D, BIDI_L }, // TELUGU LETTER BHA + { 0x0C2E, BIDI_L }, // TELUGU LETTER MA + { 0x0C2F, BIDI_L }, // TELUGU LETTER YA + { 0x0C30, BIDI_L }, // TELUGU LETTER RA + { 0x0C31, BIDI_L }, // TELUGU LETTER RRA + { 0x0C32, BIDI_L }, // TELUGU LETTER LA + { 0x0C33, BIDI_L }, // TELUGU LETTER LLA + { 0x0C34, BIDI_L }, // TELUGU LETTER LLLA + { 0x0C35, BIDI_L }, // TELUGU LETTER VA + { 0x0C36, BIDI_L }, // TELUGU LETTER SHA + { 0x0C37, BIDI_L }, // TELUGU LETTER SSA + { 0x0C38, BIDI_L }, // TELUGU LETTER SA + { 0x0C39, BIDI_L }, // TELUGU LETTER HA + { 0x0C3D, BIDI_L }, // TELUGU SIGN AVAGRAHA + { 0x0C3E, BIDI_NSM }, // TELUGU VOWEL SIGN AA + { 0x0C3F, BIDI_NSM }, // TELUGU VOWEL SIGN I + { 0x0C40, BIDI_NSM }, // TELUGU VOWEL SIGN II + { 0x0C41, BIDI_L }, // TELUGU VOWEL SIGN U + { 0x0C42, BIDI_L }, // TELUGU VOWEL SIGN UU + { 0x0C43, BIDI_L }, // TELUGU VOWEL SIGN VOCALIC R + { 0x0C44, BIDI_L }, // TELUGU VOWEL SIGN VOCALIC RR + { 0x0C46, BIDI_NSM }, // TELUGU VOWEL SIGN E + { 0x0C47, BIDI_NSM }, // TELUGU VOWEL SIGN EE + { 0x0C48, BIDI_NSM }, // TELUGU VOWEL SIGN AI + { 0x0C4A, BIDI_NSM }, // TELUGU VOWEL SIGN O + { 0x0C4B, BIDI_NSM }, // TELUGU VOWEL SIGN OO + { 0x0C4C, BIDI_NSM }, // TELUGU VOWEL SIGN AU + { 0x0C4D, BIDI_NSM }, // TELUGU SIGN VIRAMA + { 0x0C55, BIDI_NSM }, // TELUGU LENGTH MARK + { 0x0C56, BIDI_NSM }, // TELUGU AI LENGTH MARK + { 0x0C58, BIDI_L }, // TELUGU LETTER TSA + { 0x0C59, BIDI_L }, // TELUGU LETTER DZA + { 0x0C5A, BIDI_L }, // TELUGU LETTER RRRA + { 0x0C60, BIDI_L }, // TELUGU LETTER VOCALIC RR + { 0x0C61, BIDI_L }, // TELUGU LETTER VOCALIC LL + { 0x0C62, BIDI_NSM }, // TELUGU VOWEL SIGN VOCALIC L + { 0x0C63, BIDI_NSM }, // TELUGU VOWEL SIGN VOCALIC LL + { 0x0C66, BIDI_L }, // TELUGU DIGIT ZERO + { 0x0C67, BIDI_L }, // TELUGU DIGIT ONE + { 0x0C68, BIDI_L }, // TELUGU DIGIT TWO + { 0x0C69, BIDI_L }, // TELUGU DIGIT THREE + { 0x0C6A, BIDI_L }, // TELUGU DIGIT FOUR + { 0x0C6B, BIDI_L }, // TELUGU DIGIT FIVE + { 0x0C6C, BIDI_L }, // TELUGU DIGIT SIX + { 0x0C6D, BIDI_L }, // TELUGU DIGIT SEVEN + { 0x0C6E, BIDI_L }, // TELUGU DIGIT EIGHT + { 0x0C6F, BIDI_L }, // TELUGU DIGIT NINE + { 0x0C78, BIDI_ON }, // TELUGU FRACTION DIGIT ZERO FOR ODD POWERS OF FOUR + { 0x0C79, BIDI_ON }, // TELUGU FRACTION DIGIT ONE FOR ODD POWERS OF FOUR + { 0x0C7A, BIDI_ON }, // TELUGU FRACTION DIGIT TWO FOR ODD POWERS OF FOUR + { 0x0C7B, BIDI_ON }, // TELUGU FRACTION DIGIT THREE FOR ODD POWERS OF FOUR + { 0x0C7C, BIDI_ON }, // TELUGU FRACTION DIGIT ONE FOR EVEN POWERS OF FOUR + { 0x0C7D, BIDI_ON }, // TELUGU FRACTION DIGIT TWO FOR EVEN POWERS OF FOUR + { 0x0C7E, BIDI_ON }, // TELUGU FRACTION DIGIT THREE FOR EVEN POWERS OF FOUR + { 0x0C7F, BIDI_L }, // TELUGU SIGN TUUMU + { 0x0C81, BIDI_NSM }, // KANNADA SIGN CANDRABINDU + { 0x0C82, BIDI_L }, // KANNADA SIGN ANUSVARA + { 0x0C83, BIDI_L }, // KANNADA SIGN VISARGA + { 0x0C85, BIDI_L }, // KANNADA LETTER A + { 0x0C86, BIDI_L }, // KANNADA LETTER AA + { 0x0C87, BIDI_L }, // KANNADA LETTER I + { 0x0C88, BIDI_L }, // KANNADA LETTER II + { 0x0C89, BIDI_L }, // KANNADA LETTER U + { 0x0C8A, BIDI_L }, // KANNADA LETTER UU + { 0x0C8B, BIDI_L }, // KANNADA LETTER VOCALIC R + { 0x0C8C, BIDI_L }, // KANNADA LETTER VOCALIC L + { 0x0C8E, BIDI_L }, // KANNADA LETTER E + { 0x0C8F, BIDI_L }, // KANNADA LETTER EE + { 0x0C90, BIDI_L }, // KANNADA LETTER AI + { 0x0C92, BIDI_L }, // KANNADA LETTER O + { 0x0C93, BIDI_L }, // KANNADA LETTER OO + { 0x0C94, BIDI_L }, // KANNADA LETTER AU + { 0x0C95, BIDI_L }, // KANNADA LETTER KA + { 0x0C96, BIDI_L }, // KANNADA LETTER KHA + { 0x0C97, BIDI_L }, // KANNADA LETTER GA + { 0x0C98, BIDI_L }, // KANNADA LETTER GHA + { 0x0C99, BIDI_L }, // KANNADA LETTER NGA + { 0x0C9A, BIDI_L }, // KANNADA LETTER CA + { 0x0C9B, BIDI_L }, // KANNADA LETTER CHA + { 0x0C9C, BIDI_L }, // KANNADA LETTER JA + { 0x0C9D, BIDI_L }, // KANNADA LETTER JHA + { 0x0C9E, BIDI_L }, // KANNADA LETTER NYA + { 0x0C9F, BIDI_L }, // KANNADA LETTER TTA + { 0x0CA0, BIDI_L }, // KANNADA LETTER TTHA + { 0x0CA1, BIDI_L }, // KANNADA LETTER DDA + { 0x0CA2, BIDI_L }, // KANNADA LETTER DDHA + { 0x0CA3, BIDI_L }, // KANNADA LETTER NNA + { 0x0CA4, BIDI_L }, // KANNADA LETTER TA + { 0x0CA5, BIDI_L }, // KANNADA LETTER THA + { 0x0CA6, BIDI_L }, // KANNADA LETTER DA + { 0x0CA7, BIDI_L }, // KANNADA LETTER DHA + { 0x0CA8, BIDI_L }, // KANNADA LETTER NA + { 0x0CAA, BIDI_L }, // KANNADA LETTER PA + { 0x0CAB, BIDI_L }, // KANNADA LETTER PHA + { 0x0CAC, BIDI_L }, // KANNADA LETTER BA + { 0x0CAD, BIDI_L }, // KANNADA LETTER BHA + { 0x0CAE, BIDI_L }, // KANNADA LETTER MA + { 0x0CAF, BIDI_L }, // KANNADA LETTER YA + { 0x0CB0, BIDI_L }, // KANNADA LETTER RA + { 0x0CB1, BIDI_L }, // KANNADA LETTER RRA + { 0x0CB2, BIDI_L }, // KANNADA LETTER LA + { 0x0CB3, BIDI_L }, // KANNADA LETTER LLA + { 0x0CB5, BIDI_L }, // KANNADA LETTER VA + { 0x0CB6, BIDI_L }, // KANNADA LETTER SHA + { 0x0CB7, BIDI_L }, // KANNADA LETTER SSA + { 0x0CB8, BIDI_L }, // KANNADA LETTER SA + { 0x0CB9, BIDI_L }, // KANNADA LETTER HA + { 0x0CBC, BIDI_NSM }, // KANNADA SIGN NUKTA + { 0x0CBD, BIDI_L }, // KANNADA SIGN AVAGRAHA + { 0x0CBE, BIDI_L }, // KANNADA VOWEL SIGN AA + { 0x0CBF, BIDI_L }, // KANNADA VOWEL SIGN I + { 0x0CC0, BIDI_L }, // KANNADA VOWEL SIGN II + { 0x0CC1, BIDI_L }, // KANNADA VOWEL SIGN U + { 0x0CC2, BIDI_L }, // KANNADA VOWEL SIGN UU + { 0x0CC3, BIDI_L }, // KANNADA VOWEL SIGN VOCALIC R + { 0x0CC4, BIDI_L }, // KANNADA VOWEL SIGN VOCALIC RR + { 0x0CC6, BIDI_L }, // KANNADA VOWEL SIGN E + { 0x0CC7, BIDI_L }, // KANNADA VOWEL SIGN EE + { 0x0CC8, BIDI_L }, // KANNADA VOWEL SIGN AI + { 0x0CCA, BIDI_L }, // KANNADA VOWEL SIGN O + { 0x0CCB, BIDI_L }, // KANNADA VOWEL SIGN OO + { 0x0CCC, BIDI_NSM }, // KANNADA VOWEL SIGN AU + { 0x0CCD, BIDI_NSM }, // KANNADA SIGN VIRAMA + { 0x0CD5, BIDI_L }, // KANNADA LENGTH MARK + { 0x0CD6, BIDI_L }, // KANNADA AI LENGTH MARK + { 0x0CDE, BIDI_L }, // KANNADA LETTER FA + { 0x0CE0, BIDI_L }, // KANNADA LETTER VOCALIC RR + { 0x0CE1, BIDI_L }, // KANNADA LETTER VOCALIC LL + { 0x0CE2, BIDI_NSM }, // KANNADA VOWEL SIGN VOCALIC L + { 0x0CE3, BIDI_NSM }, // KANNADA VOWEL SIGN VOCALIC LL + { 0x0CE6, BIDI_L }, // KANNADA DIGIT ZERO + { 0x0CE7, BIDI_L }, // KANNADA DIGIT ONE + { 0x0CE8, BIDI_L }, // KANNADA DIGIT TWO + { 0x0CE9, BIDI_L }, // KANNADA DIGIT THREE + { 0x0CEA, BIDI_L }, // KANNADA DIGIT FOUR + { 0x0CEB, BIDI_L }, // KANNADA DIGIT FIVE + { 0x0CEC, BIDI_L }, // KANNADA DIGIT SIX + { 0x0CED, BIDI_L }, // KANNADA DIGIT SEVEN + { 0x0CEE, BIDI_L }, // KANNADA DIGIT EIGHT + { 0x0CEF, BIDI_L }, // KANNADA DIGIT NINE + { 0x0CF1, BIDI_L }, // KANNADA SIGN JIHVAMULIYA + { 0x0CF2, BIDI_L }, // KANNADA SIGN UPADHMANIYA + { 0x0D01, BIDI_NSM }, // MALAYALAM SIGN CANDRABINDU + { 0x0D02, BIDI_L }, // MALAYALAM SIGN ANUSVARA + { 0x0D03, BIDI_L }, // MALAYALAM SIGN VISARGA + { 0x0D05, BIDI_L }, // MALAYALAM LETTER A + { 0x0D06, BIDI_L }, // MALAYALAM LETTER AA + { 0x0D07, BIDI_L }, // MALAYALAM LETTER I + { 0x0D08, BIDI_L }, // MALAYALAM LETTER II + { 0x0D09, BIDI_L }, // MALAYALAM LETTER U + { 0x0D0A, BIDI_L }, // MALAYALAM LETTER UU + { 0x0D0B, BIDI_L }, // MALAYALAM LETTER VOCALIC R + { 0x0D0C, BIDI_L }, // MALAYALAM LETTER VOCALIC L + { 0x0D0E, BIDI_L }, // MALAYALAM LETTER E + { 0x0D0F, BIDI_L }, // MALAYALAM LETTER EE + { 0x0D10, BIDI_L }, // MALAYALAM LETTER AI + { 0x0D12, BIDI_L }, // MALAYALAM LETTER O + { 0x0D13, BIDI_L }, // MALAYALAM LETTER OO + { 0x0D14, BIDI_L }, // MALAYALAM LETTER AU + { 0x0D15, BIDI_L }, // MALAYALAM LETTER KA + { 0x0D16, BIDI_L }, // MALAYALAM LETTER KHA + { 0x0D17, BIDI_L }, // MALAYALAM LETTER GA + { 0x0D18, BIDI_L }, // MALAYALAM LETTER GHA + { 0x0D19, BIDI_L }, // MALAYALAM LETTER NGA + { 0x0D1A, BIDI_L }, // MALAYALAM LETTER CA + { 0x0D1B, BIDI_L }, // MALAYALAM LETTER CHA + { 0x0D1C, BIDI_L }, // MALAYALAM LETTER JA + { 0x0D1D, BIDI_L }, // MALAYALAM LETTER JHA + { 0x0D1E, BIDI_L }, // MALAYALAM LETTER NYA + { 0x0D1F, BIDI_L }, // MALAYALAM LETTER TTA + { 0x0D20, BIDI_L }, // MALAYALAM LETTER TTHA + { 0x0D21, BIDI_L }, // MALAYALAM LETTER DDA + { 0x0D22, BIDI_L }, // MALAYALAM LETTER DDHA + { 0x0D23, BIDI_L }, // MALAYALAM LETTER NNA + { 0x0D24, BIDI_L }, // MALAYALAM LETTER TA + { 0x0D25, BIDI_L }, // MALAYALAM LETTER THA + { 0x0D26, BIDI_L }, // MALAYALAM LETTER DA + { 0x0D27, BIDI_L }, // MALAYALAM LETTER DHA + { 0x0D28, BIDI_L }, // MALAYALAM LETTER NA + { 0x0D29, BIDI_L }, // MALAYALAM LETTER NNNA + { 0x0D2A, BIDI_L }, // MALAYALAM LETTER PA + { 0x0D2B, BIDI_L }, // MALAYALAM LETTER PHA + { 0x0D2C, BIDI_L }, // MALAYALAM LETTER BA + { 0x0D2D, BIDI_L }, // MALAYALAM LETTER BHA + { 0x0D2E, BIDI_L }, // MALAYALAM LETTER MA + { 0x0D2F, BIDI_L }, // MALAYALAM LETTER YA + { 0x0D30, BIDI_L }, // MALAYALAM LETTER RA + { 0x0D31, BIDI_L }, // MALAYALAM LETTER RRA + { 0x0D32, BIDI_L }, // MALAYALAM LETTER LA + { 0x0D33, BIDI_L }, // MALAYALAM LETTER LLA + { 0x0D34, BIDI_L }, // MALAYALAM LETTER LLLA + { 0x0D35, BIDI_L }, // MALAYALAM LETTER VA + { 0x0D36, BIDI_L }, // MALAYALAM LETTER SHA + { 0x0D37, BIDI_L }, // MALAYALAM LETTER SSA + { 0x0D38, BIDI_L }, // MALAYALAM LETTER SA + { 0x0D39, BIDI_L }, // MALAYALAM LETTER HA + { 0x0D3A, BIDI_L }, // MALAYALAM LETTER TTTA + { 0x0D3D, BIDI_L }, // MALAYALAM SIGN AVAGRAHA + { 0x0D3E, BIDI_L }, // MALAYALAM VOWEL SIGN AA + { 0x0D3F, BIDI_L }, // MALAYALAM VOWEL SIGN I + { 0x0D40, BIDI_L }, // MALAYALAM VOWEL SIGN II + { 0x0D41, BIDI_NSM }, // MALAYALAM VOWEL SIGN U + { 0x0D42, BIDI_NSM }, // MALAYALAM VOWEL SIGN UU + { 0x0D43, BIDI_NSM }, // MALAYALAM VOWEL SIGN VOCALIC R + { 0x0D44, BIDI_NSM }, // MALAYALAM VOWEL SIGN VOCALIC RR + { 0x0D46, BIDI_L }, // MALAYALAM VOWEL SIGN E + { 0x0D47, BIDI_L }, // MALAYALAM VOWEL SIGN EE + { 0x0D48, BIDI_L }, // MALAYALAM VOWEL SIGN AI + { 0x0D4A, BIDI_L }, // MALAYALAM VOWEL SIGN O + { 0x0D4B, BIDI_L }, // MALAYALAM VOWEL SIGN OO + { 0x0D4C, BIDI_L }, // MALAYALAM VOWEL SIGN AU + { 0x0D4D, BIDI_NSM }, // MALAYALAM SIGN VIRAMA + { 0x0D4E, BIDI_L }, // MALAYALAM LETTER DOT REPH + { 0x0D57, BIDI_L }, // MALAYALAM AU LENGTH MARK + { 0x0D5F, BIDI_L }, // MALAYALAM LETTER ARCHAIC II + { 0x0D60, BIDI_L }, // MALAYALAM LETTER VOCALIC RR + { 0x0D61, BIDI_L }, // MALAYALAM LETTER VOCALIC LL + { 0x0D62, BIDI_NSM }, // MALAYALAM VOWEL SIGN VOCALIC L + { 0x0D63, BIDI_NSM }, // MALAYALAM VOWEL SIGN VOCALIC LL + { 0x0D66, BIDI_L }, // MALAYALAM DIGIT ZERO + { 0x0D67, BIDI_L }, // MALAYALAM DIGIT ONE + { 0x0D68, BIDI_L }, // MALAYALAM DIGIT TWO + { 0x0D69, BIDI_L }, // MALAYALAM DIGIT THREE + { 0x0D6A, BIDI_L }, // MALAYALAM DIGIT FOUR + { 0x0D6B, BIDI_L }, // MALAYALAM DIGIT FIVE + { 0x0D6C, BIDI_L }, // MALAYALAM DIGIT SIX + { 0x0D6D, BIDI_L }, // MALAYALAM DIGIT SEVEN + { 0x0D6E, BIDI_L }, // MALAYALAM DIGIT EIGHT + { 0x0D6F, BIDI_L }, // MALAYALAM DIGIT NINE + { 0x0D70, BIDI_L }, // MALAYALAM NUMBER TEN + { 0x0D71, BIDI_L }, // MALAYALAM NUMBER ONE HUNDRED + { 0x0D72, BIDI_L }, // MALAYALAM NUMBER ONE THOUSAND + { 0x0D73, BIDI_L }, // MALAYALAM FRACTION ONE QUARTER + { 0x0D74, BIDI_L }, // MALAYALAM FRACTION ONE HALF + { 0x0D75, BIDI_L }, // MALAYALAM FRACTION THREE QUARTERS + { 0x0D79, BIDI_L }, // MALAYALAM DATE MARK + { 0x0D7A, BIDI_L }, // MALAYALAM LETTER CHILLU NN + { 0x0D7B, BIDI_L }, // MALAYALAM LETTER CHILLU N + { 0x0D7C, BIDI_L }, // MALAYALAM LETTER CHILLU RR + { 0x0D7D, BIDI_L }, // MALAYALAM LETTER CHILLU L + { 0x0D7E, BIDI_L }, // MALAYALAM LETTER CHILLU LL + { 0x0D7F, BIDI_L }, // MALAYALAM LETTER CHILLU K + { 0x0D82, BIDI_L }, // SINHALA SIGN ANUSVARAYA + { 0x0D83, BIDI_L }, // SINHALA SIGN VISARGAYA + { 0x0D85, BIDI_L }, // SINHALA LETTER AYANNA + { 0x0D86, BIDI_L }, // SINHALA LETTER AAYANNA + { 0x0D87, BIDI_L }, // SINHALA LETTER AEYANNA + { 0x0D88, BIDI_L }, // SINHALA LETTER AEEYANNA + { 0x0D89, BIDI_L }, // SINHALA LETTER IYANNA + { 0x0D8A, BIDI_L }, // SINHALA LETTER IIYANNA + { 0x0D8B, BIDI_L }, // SINHALA LETTER UYANNA + { 0x0D8C, BIDI_L }, // SINHALA LETTER UUYANNA + { 0x0D8D, BIDI_L }, // SINHALA LETTER IRUYANNA + { 0x0D8E, BIDI_L }, // SINHALA LETTER IRUUYANNA + { 0x0D8F, BIDI_L }, // SINHALA LETTER ILUYANNA + { 0x0D90, BIDI_L }, // SINHALA LETTER ILUUYANNA + { 0x0D91, BIDI_L }, // SINHALA LETTER EYANNA + { 0x0D92, BIDI_L }, // SINHALA LETTER EEYANNA + { 0x0D93, BIDI_L }, // SINHALA LETTER AIYANNA + { 0x0D94, BIDI_L }, // SINHALA LETTER OYANNA + { 0x0D95, BIDI_L }, // SINHALA LETTER OOYANNA + { 0x0D96, BIDI_L }, // SINHALA LETTER AUYANNA + { 0x0D9A, BIDI_L }, // SINHALA LETTER ALPAPRAANA KAYANNA + { 0x0D9B, BIDI_L }, // SINHALA LETTER MAHAAPRAANA KAYANNA + { 0x0D9C, BIDI_L }, // SINHALA LETTER ALPAPRAANA GAYANNA + { 0x0D9D, BIDI_L }, // SINHALA LETTER MAHAAPRAANA GAYANNA + { 0x0D9E, BIDI_L }, // SINHALA LETTER KANTAJA NAASIKYAYA + { 0x0D9F, BIDI_L }, // SINHALA LETTER SANYAKA GAYANNA + { 0x0DA0, BIDI_L }, // SINHALA LETTER ALPAPRAANA CAYANNA + { 0x0DA1, BIDI_L }, // SINHALA LETTER MAHAAPRAANA CAYANNA + { 0x0DA2, BIDI_L }, // SINHALA LETTER ALPAPRAANA JAYANNA + { 0x0DA3, BIDI_L }, // SINHALA LETTER MAHAAPRAANA JAYANNA + { 0x0DA4, BIDI_L }, // SINHALA LETTER TAALUJA NAASIKYAYA + { 0x0DA5, BIDI_L }, // SINHALA LETTER TAALUJA SANYOOGA NAAKSIKYAYA + { 0x0DA6, BIDI_L }, // SINHALA LETTER SANYAKA JAYANNA + { 0x0DA7, BIDI_L }, // SINHALA LETTER ALPAPRAANA TTAYANNA + { 0x0DA8, BIDI_L }, // SINHALA LETTER MAHAAPRAANA TTAYANNA + { 0x0DA9, BIDI_L }, // SINHALA LETTER ALPAPRAANA DDAYANNA + { 0x0DAA, BIDI_L }, // SINHALA LETTER MAHAAPRAANA DDAYANNA + { 0x0DAB, BIDI_L }, // SINHALA LETTER MUURDHAJA NAYANNA + { 0x0DAC, BIDI_L }, // SINHALA LETTER SANYAKA DDAYANNA + { 0x0DAD, BIDI_L }, // SINHALA LETTER ALPAPRAANA TAYANNA + { 0x0DAE, BIDI_L }, // SINHALA LETTER MAHAAPRAANA TAYANNA + { 0x0DAF, BIDI_L }, // SINHALA LETTER ALPAPRAANA DAYANNA + { 0x0DB0, BIDI_L }, // SINHALA LETTER MAHAAPRAANA DAYANNA + { 0x0DB1, BIDI_L }, // SINHALA LETTER DANTAJA NAYANNA + { 0x0DB3, BIDI_L }, // SINHALA LETTER SANYAKA DAYANNA + { 0x0DB4, BIDI_L }, // SINHALA LETTER ALPAPRAANA PAYANNA + { 0x0DB5, BIDI_L }, // SINHALA LETTER MAHAAPRAANA PAYANNA + { 0x0DB6, BIDI_L }, // SINHALA LETTER ALPAPRAANA BAYANNA + { 0x0DB7, BIDI_L }, // SINHALA LETTER MAHAAPRAANA BAYANNA + { 0x0DB8, BIDI_L }, // SINHALA LETTER MAYANNA + { 0x0DB9, BIDI_L }, // SINHALA LETTER AMBA BAYANNA + { 0x0DBA, BIDI_L }, // SINHALA LETTER YAYANNA + { 0x0DBB, BIDI_L }, // SINHALA LETTER RAYANNA + { 0x0DBD, BIDI_L }, // SINHALA LETTER DANTAJA LAYANNA + { 0x0DC0, BIDI_L }, // SINHALA LETTER VAYANNA + { 0x0DC1, BIDI_L }, // SINHALA LETTER TAALUJA SAYANNA + { 0x0DC2, BIDI_L }, // SINHALA LETTER MUURDHAJA SAYANNA + { 0x0DC3, BIDI_L }, // SINHALA LETTER DANTAJA SAYANNA + { 0x0DC4, BIDI_L }, // SINHALA LETTER HAYANNA + { 0x0DC5, BIDI_L }, // SINHALA LETTER MUURDHAJA LAYANNA + { 0x0DC6, BIDI_L }, // SINHALA LETTER FAYANNA + { 0x0DCA, BIDI_NSM }, // SINHALA SIGN AL-LAKUNA + { 0x0DCF, BIDI_L }, // SINHALA VOWEL SIGN AELA-PILLA + { 0x0DD0, BIDI_L }, // SINHALA VOWEL SIGN KETTI AEDA-PILLA + { 0x0DD1, BIDI_L }, // SINHALA VOWEL SIGN DIGA AEDA-PILLA + { 0x0DD2, BIDI_NSM }, // SINHALA VOWEL SIGN KETTI IS-PILLA + { 0x0DD3, BIDI_NSM }, // SINHALA VOWEL SIGN DIGA IS-PILLA + { 0x0DD4, BIDI_NSM }, // SINHALA VOWEL SIGN KETTI PAA-PILLA + { 0x0DD6, BIDI_NSM }, // SINHALA VOWEL SIGN DIGA PAA-PILLA + { 0x0DD8, BIDI_L }, // SINHALA VOWEL SIGN GAETTA-PILLA + { 0x0DD9, BIDI_L }, // SINHALA VOWEL SIGN KOMBUVA + { 0x0DDA, BIDI_L }, // SINHALA VOWEL SIGN DIGA KOMBUVA + { 0x0DDB, BIDI_L }, // SINHALA VOWEL SIGN KOMBU DEKA + { 0x0DDC, BIDI_L }, // SINHALA VOWEL SIGN KOMBUVA HAA AELA-PILLA + { 0x0DDD, BIDI_L }, // SINHALA VOWEL SIGN KOMBUVA HAA DIGA AELA-PILLA + { 0x0DDE, BIDI_L }, // SINHALA VOWEL SIGN KOMBUVA HAA GAYANUKITTA + { 0x0DDF, BIDI_L }, // SINHALA VOWEL SIGN GAYANUKITTA + { 0x0DE6, BIDI_L }, // SINHALA LITH DIGIT ZERO + { 0x0DE7, BIDI_L }, // SINHALA LITH DIGIT ONE + { 0x0DE8, BIDI_L }, // SINHALA LITH DIGIT TWO + { 0x0DE9, BIDI_L }, // SINHALA LITH DIGIT THREE + { 0x0DEA, BIDI_L }, // SINHALA LITH DIGIT FOUR + { 0x0DEB, BIDI_L }, // SINHALA LITH DIGIT FIVE + { 0x0DEC, BIDI_L }, // SINHALA LITH DIGIT SIX + { 0x0DED, BIDI_L }, // SINHALA LITH DIGIT SEVEN + { 0x0DEE, BIDI_L }, // SINHALA LITH DIGIT EIGHT + { 0x0DEF, BIDI_L }, // SINHALA LITH DIGIT NINE + { 0x0DF2, BIDI_L }, // SINHALA VOWEL SIGN DIGA GAETTA-PILLA + { 0x0DF3, BIDI_L }, // SINHALA VOWEL SIGN DIGA GAYANUKITTA + { 0x0DF4, BIDI_L }, // SINHALA PUNCTUATION KUNDDALIYA + { 0x0E01, BIDI_L }, // THAI CHARACTER KO KAI + { 0x0E02, BIDI_L }, // THAI CHARACTER KHO KHAI + { 0x0E03, BIDI_L }, // THAI CHARACTER KHO KHUAT + { 0x0E04, BIDI_L }, // THAI CHARACTER KHO KHWAI + { 0x0E05, BIDI_L }, // THAI CHARACTER KHO KHON + { 0x0E06, BIDI_L }, // THAI CHARACTER KHO RAKHANG + { 0x0E07, BIDI_L }, // THAI CHARACTER NGO NGU + { 0x0E08, BIDI_L }, // THAI CHARACTER CHO CHAN + { 0x0E09, BIDI_L }, // THAI CHARACTER CHO CHING + { 0x0E0A, BIDI_L }, // THAI CHARACTER CHO CHANG + { 0x0E0B, BIDI_L }, // THAI CHARACTER SO SO + { 0x0E0C, BIDI_L }, // THAI CHARACTER CHO CHOE + { 0x0E0D, BIDI_L }, // THAI CHARACTER YO YING + { 0x0E0E, BIDI_L }, // THAI CHARACTER DO CHADA + { 0x0E0F, BIDI_L }, // THAI CHARACTER TO PATAK + { 0x0E10, BIDI_L }, // THAI CHARACTER THO THAN + { 0x0E11, BIDI_L }, // THAI CHARACTER THO NANGMONTHO + { 0x0E12, BIDI_L }, // THAI CHARACTER THO PHUTHAO + { 0x0E13, BIDI_L }, // THAI CHARACTER NO NEN + { 0x0E14, BIDI_L }, // THAI CHARACTER DO DEK + { 0x0E15, BIDI_L }, // THAI CHARACTER TO TAO + { 0x0E16, BIDI_L }, // THAI CHARACTER THO THUNG + { 0x0E17, BIDI_L }, // THAI CHARACTER THO THAHAN + { 0x0E18, BIDI_L }, // THAI CHARACTER THO THONG + { 0x0E19, BIDI_L }, // THAI CHARACTER NO NU + { 0x0E1A, BIDI_L }, // THAI CHARACTER BO BAIMAI + { 0x0E1B, BIDI_L }, // THAI CHARACTER PO PLA + { 0x0E1C, BIDI_L }, // THAI CHARACTER PHO PHUNG + { 0x0E1D, BIDI_L }, // THAI CHARACTER FO FA + { 0x0E1E, BIDI_L }, // THAI CHARACTER PHO PHAN + { 0x0E1F, BIDI_L }, // THAI CHARACTER FO FAN + { 0x0E20, BIDI_L }, // THAI CHARACTER PHO SAMPHAO + { 0x0E21, BIDI_L }, // THAI CHARACTER MO MA + { 0x0E22, BIDI_L }, // THAI CHARACTER YO YAK + { 0x0E23, BIDI_L }, // THAI CHARACTER RO RUA + { 0x0E24, BIDI_L }, // THAI CHARACTER RU + { 0x0E25, BIDI_L }, // THAI CHARACTER LO LING + { 0x0E26, BIDI_L }, // THAI CHARACTER LU + { 0x0E27, BIDI_L }, // THAI CHARACTER WO WAEN + { 0x0E28, BIDI_L }, // THAI CHARACTER SO SALA + { 0x0E29, BIDI_L }, // THAI CHARACTER SO RUSI + { 0x0E2A, BIDI_L }, // THAI CHARACTER SO SUA + { 0x0E2B, BIDI_L }, // THAI CHARACTER HO HIP + { 0x0E2C, BIDI_L }, // THAI CHARACTER LO CHULA + { 0x0E2D, BIDI_L }, // THAI CHARACTER O ANG + { 0x0E2E, BIDI_L }, // THAI CHARACTER HO NOKHUK + { 0x0E2F, BIDI_L }, // THAI CHARACTER PAIYANNOI + { 0x0E30, BIDI_L }, // THAI CHARACTER SARA A + { 0x0E31, BIDI_NSM }, // THAI CHARACTER MAI HAN-AKAT + { 0x0E32, BIDI_L }, // THAI CHARACTER SARA AA + { 0x0E33, BIDI_L }, // THAI CHARACTER SARA AM + { 0x0E34, BIDI_NSM }, // THAI CHARACTER SARA I + { 0x0E35, BIDI_NSM }, // THAI CHARACTER SARA II + { 0x0E36, BIDI_NSM }, // THAI CHARACTER SARA UE + { 0x0E37, BIDI_NSM }, // THAI CHARACTER SARA UEE + { 0x0E38, BIDI_NSM }, // THAI CHARACTER SARA U + { 0x0E39, BIDI_NSM }, // THAI CHARACTER SARA UU + { 0x0E3A, BIDI_NSM }, // THAI CHARACTER PHINTHU + { 0x0E3F, BIDI_ET }, // THAI CURRENCY SYMBOL BAHT + { 0x0E40, BIDI_L }, // THAI CHARACTER SARA E + { 0x0E41, BIDI_L }, // THAI CHARACTER SARA AE + { 0x0E42, BIDI_L }, // THAI CHARACTER SARA O + { 0x0E43, BIDI_L }, // THAI CHARACTER SARA AI MAIMUAN + { 0x0E44, BIDI_L }, // THAI CHARACTER SARA AI MAIMALAI + { 0x0E45, BIDI_L }, // THAI CHARACTER LAKKHANGYAO + { 0x0E46, BIDI_L }, // THAI CHARACTER MAIYAMOK + { 0x0E47, BIDI_NSM }, // THAI CHARACTER MAITAIKHU + { 0x0E48, BIDI_NSM }, // THAI CHARACTER MAI EK + { 0x0E49, BIDI_NSM }, // THAI CHARACTER MAI THO + { 0x0E4A, BIDI_NSM }, // THAI CHARACTER MAI TRI + { 0x0E4B, BIDI_NSM }, // THAI CHARACTER MAI CHATTAWA + { 0x0E4C, BIDI_NSM }, // THAI CHARACTER THANTHAKHAT + { 0x0E4D, BIDI_NSM }, // THAI CHARACTER NIKHAHIT + { 0x0E4E, BIDI_NSM }, // THAI CHARACTER YAMAKKAN + { 0x0E4F, BIDI_L }, // THAI CHARACTER FONGMAN + { 0x0E50, BIDI_L }, // THAI DIGIT ZERO + { 0x0E51, BIDI_L }, // THAI DIGIT ONE + { 0x0E52, BIDI_L }, // THAI DIGIT TWO + { 0x0E53, BIDI_L }, // THAI DIGIT THREE + { 0x0E54, BIDI_L }, // THAI DIGIT FOUR + { 0x0E55, BIDI_L }, // THAI DIGIT FIVE + { 0x0E56, BIDI_L }, // THAI DIGIT SIX + { 0x0E57, BIDI_L }, // THAI DIGIT SEVEN + { 0x0E58, BIDI_L }, // THAI DIGIT EIGHT + { 0x0E59, BIDI_L }, // THAI DIGIT NINE + { 0x0E5A, BIDI_L }, // THAI CHARACTER ANGKHANKHU + { 0x0E5B, BIDI_L }, // THAI CHARACTER KHOMUT + { 0x0E81, BIDI_L }, // LAO LETTER KO + { 0x0E82, BIDI_L }, // LAO LETTER KHO SUNG + { 0x0E84, BIDI_L }, // LAO LETTER KHO TAM + { 0x0E87, BIDI_L }, // LAO LETTER NGO + { 0x0E88, BIDI_L }, // LAO LETTER CO + { 0x0E8A, BIDI_L }, // LAO LETTER SO TAM + { 0x0E8D, BIDI_L }, // LAO LETTER NYO + { 0x0E94, BIDI_L }, // LAO LETTER DO + { 0x0E95, BIDI_L }, // LAO LETTER TO + { 0x0E96, BIDI_L }, // LAO LETTER THO SUNG + { 0x0E97, BIDI_L }, // LAO LETTER THO TAM + { 0x0E99, BIDI_L }, // LAO LETTER NO + { 0x0E9A, BIDI_L }, // LAO LETTER BO + { 0x0E9B, BIDI_L }, // LAO LETTER PO + { 0x0E9C, BIDI_L }, // LAO LETTER PHO SUNG + { 0x0E9D, BIDI_L }, // LAO LETTER FO TAM + { 0x0E9E, BIDI_L }, // LAO LETTER PHO TAM + { 0x0E9F, BIDI_L }, // LAO LETTER FO SUNG + { 0x0EA1, BIDI_L }, // LAO LETTER MO + { 0x0EA2, BIDI_L }, // LAO LETTER YO + { 0x0EA3, BIDI_L }, // LAO LETTER LO LING + { 0x0EA5, BIDI_L }, // LAO LETTER LO LOOT + { 0x0EA7, BIDI_L }, // LAO LETTER WO + { 0x0EAA, BIDI_L }, // LAO LETTER SO SUNG + { 0x0EAB, BIDI_L }, // LAO LETTER HO SUNG + { 0x0EAD, BIDI_L }, // LAO LETTER O + { 0x0EAE, BIDI_L }, // LAO LETTER HO TAM + { 0x0EAF, BIDI_L }, // LAO ELLIPSIS + { 0x0EB0, BIDI_L }, // LAO VOWEL SIGN A + { 0x0EB1, BIDI_NSM }, // LAO VOWEL SIGN MAI KAN + { 0x0EB2, BIDI_L }, // LAO VOWEL SIGN AA + { 0x0EB3, BIDI_L }, // LAO VOWEL SIGN AM + { 0x0EB4, BIDI_NSM }, // LAO VOWEL SIGN I + { 0x0EB5, BIDI_NSM }, // LAO VOWEL SIGN II + { 0x0EB6, BIDI_NSM }, // LAO VOWEL SIGN Y + { 0x0EB7, BIDI_NSM }, // LAO VOWEL SIGN YY + { 0x0EB8, BIDI_NSM }, // LAO VOWEL SIGN U + { 0x0EB9, BIDI_NSM }, // LAO VOWEL SIGN UU + { 0x0EBB, BIDI_NSM }, // LAO VOWEL SIGN MAI KON + { 0x0EBC, BIDI_NSM }, // LAO SEMIVOWEL SIGN LO + { 0x0EBD, BIDI_L }, // LAO SEMIVOWEL SIGN NYO + { 0x0EC0, BIDI_L }, // LAO VOWEL SIGN E + { 0x0EC1, BIDI_L }, // LAO VOWEL SIGN EI + { 0x0EC2, BIDI_L }, // LAO VOWEL SIGN O + { 0x0EC3, BIDI_L }, // LAO VOWEL SIGN AY + { 0x0EC4, BIDI_L }, // LAO VOWEL SIGN AI + { 0x0EC6, BIDI_L }, // LAO KO LA + { 0x0EC8, BIDI_NSM }, // LAO TONE MAI EK + { 0x0EC9, BIDI_NSM }, // LAO TONE MAI THO + { 0x0ECA, BIDI_NSM }, // LAO TONE MAI TI + { 0x0ECB, BIDI_NSM }, // LAO TONE MAI CATAWA + { 0x0ECC, BIDI_NSM }, // LAO CANCELLATION MARK + { 0x0ECD, BIDI_NSM }, // LAO NIGGAHITA + { 0x0ED0, BIDI_L }, // LAO DIGIT ZERO + { 0x0ED1, BIDI_L }, // LAO DIGIT ONE + { 0x0ED2, BIDI_L }, // LAO DIGIT TWO + { 0x0ED3, BIDI_L }, // LAO DIGIT THREE + { 0x0ED4, BIDI_L }, // LAO DIGIT FOUR + { 0x0ED5, BIDI_L }, // LAO DIGIT FIVE + { 0x0ED6, BIDI_L }, // LAO DIGIT SIX + { 0x0ED7, BIDI_L }, // LAO DIGIT SEVEN + { 0x0ED8, BIDI_L }, // LAO DIGIT EIGHT + { 0x0ED9, BIDI_L }, // LAO DIGIT NINE + { 0x0EDC, BIDI_L }, // LAO HO NO + { 0x0EDD, BIDI_L }, // LAO HO MO + { 0x0EDE, BIDI_L }, // LAO LETTER KHMU GO + { 0x0EDF, BIDI_L }, // LAO LETTER KHMU NYO + { 0x0F00, BIDI_L }, // TIBETAN SYLLABLE OM + { 0x0F01, BIDI_L }, // TIBETAN MARK GTER YIG MGO TRUNCATED A + { 0x0F02, BIDI_L }, // TIBETAN MARK GTER YIG MGO -UM RNAM BCAD MA + { 0x0F03, BIDI_L }, // TIBETAN MARK GTER YIG MGO -UM GTER TSHEG MA + { 0x0F04, BIDI_L }, // TIBETAN MARK INITIAL YIG MGO MDUN MA + { 0x0F05, BIDI_L }, // TIBETAN MARK CLOSING YIG MGO SGAB MA + { 0x0F06, BIDI_L }, // TIBETAN MARK CARET YIG MGO PHUR SHAD MA + { 0x0F07, BIDI_L }, // TIBETAN MARK YIG MGO TSHEG SHAD MA + { 0x0F08, BIDI_L }, // TIBETAN MARK SBRUL SHAD + { 0x0F09, BIDI_L }, // TIBETAN MARK BSKUR YIG MGO + { 0x0F0A, BIDI_L }, // TIBETAN MARK BKA- SHOG YIG MGO + { 0x0F0B, BIDI_L }, // TIBETAN MARK INTERSYLLABIC TSHEG + { 0x0F0C, BIDI_L }, // TIBETAN MARK DELIMITER TSHEG BSTAR + { 0x0F0D, BIDI_L }, // TIBETAN MARK SHAD + { 0x0F0E, BIDI_L }, // TIBETAN MARK NYIS SHAD + { 0x0F0F, BIDI_L }, // TIBETAN MARK TSHEG SHAD + { 0x0F10, BIDI_L }, // TIBETAN MARK NYIS TSHEG SHAD + { 0x0F11, BIDI_L }, // TIBETAN MARK RIN CHEN SPUNGS SHAD + { 0x0F12, BIDI_L }, // TIBETAN MARK RGYA GRAM SHAD + { 0x0F13, BIDI_L }, // TIBETAN MARK CARET -DZUD RTAGS ME LONG CAN + { 0x0F14, BIDI_L }, // TIBETAN MARK GTER TSHEG + { 0x0F15, BIDI_L }, // TIBETAN LOGOTYPE SIGN CHAD RTAGS + { 0x0F16, BIDI_L }, // TIBETAN LOGOTYPE SIGN LHAG RTAGS + { 0x0F17, BIDI_L }, // TIBETAN ASTROLOGICAL SIGN SGRA GCAN -CHAR RTAGS + { 0x0F18, BIDI_NSM }, // TIBETAN ASTROLOGICAL SIGN -KHYUD PA + { 0x0F19, BIDI_NSM }, // TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS + { 0x0F1A, BIDI_L }, // TIBETAN SIGN RDEL DKAR GCIG + { 0x0F1B, BIDI_L }, // TIBETAN SIGN RDEL DKAR GNYIS + { 0x0F1C, BIDI_L }, // TIBETAN SIGN RDEL DKAR GSUM + { 0x0F1D, BIDI_L }, // TIBETAN SIGN RDEL NAG GCIG + { 0x0F1E, BIDI_L }, // TIBETAN SIGN RDEL NAG GNYIS + { 0x0F1F, BIDI_L }, // TIBETAN SIGN RDEL DKAR RDEL NAG + { 0x0F20, BIDI_L }, // TIBETAN DIGIT ZERO + { 0x0F21, BIDI_L }, // TIBETAN DIGIT ONE + { 0x0F22, BIDI_L }, // TIBETAN DIGIT TWO + { 0x0F23, BIDI_L }, // TIBETAN DIGIT THREE + { 0x0F24, BIDI_L }, // TIBETAN DIGIT FOUR + { 0x0F25, BIDI_L }, // TIBETAN DIGIT FIVE + { 0x0F26, BIDI_L }, // TIBETAN DIGIT SIX + { 0x0F27, BIDI_L }, // TIBETAN DIGIT SEVEN + { 0x0F28, BIDI_L }, // TIBETAN DIGIT EIGHT + { 0x0F29, BIDI_L }, // TIBETAN DIGIT NINE + { 0x0F2A, BIDI_L }, // TIBETAN DIGIT HALF ONE + { 0x0F2B, BIDI_L }, // TIBETAN DIGIT HALF TWO + { 0x0F2C, BIDI_L }, // TIBETAN DIGIT HALF THREE + { 0x0F2D, BIDI_L }, // TIBETAN DIGIT HALF FOUR + { 0x0F2E, BIDI_L }, // TIBETAN DIGIT HALF FIVE + { 0x0F2F, BIDI_L }, // TIBETAN DIGIT HALF SIX + { 0x0F30, BIDI_L }, // TIBETAN DIGIT HALF SEVEN + { 0x0F31, BIDI_L }, // TIBETAN DIGIT HALF EIGHT + { 0x0F32, BIDI_L }, // TIBETAN DIGIT HALF NINE + { 0x0F33, BIDI_L }, // TIBETAN DIGIT HALF ZERO + { 0x0F34, BIDI_L }, // TIBETAN MARK BSDUS RTAGS + { 0x0F35, BIDI_NSM }, // TIBETAN MARK NGAS BZUNG NYI ZLA + { 0x0F36, BIDI_L }, // TIBETAN MARK CARET -DZUD RTAGS BZHI MIG CAN + { 0x0F37, BIDI_NSM }, // TIBETAN MARK NGAS BZUNG SGOR RTAGS + { 0x0F38, BIDI_L }, // TIBETAN MARK CHE MGO + { 0x0F39, BIDI_NSM }, // TIBETAN MARK TSA -PHRU + { 0x0F3A, BIDI_ON }, // TIBETAN MARK GUG RTAGS GYON + { 0x0F3B, BIDI_ON }, // TIBETAN MARK GUG RTAGS GYAS + { 0x0F3C, BIDI_ON }, // TIBETAN MARK ANG KHANG GYON + { 0x0F3D, BIDI_ON }, // TIBETAN MARK ANG KHANG GYAS + { 0x0F3E, BIDI_L }, // TIBETAN SIGN YAR TSHES + { 0x0F3F, BIDI_L }, // TIBETAN SIGN MAR TSHES + { 0x0F40, BIDI_L }, // TIBETAN LETTER KA + { 0x0F41, BIDI_L }, // TIBETAN LETTER KHA + { 0x0F42, BIDI_L }, // TIBETAN LETTER GA + { 0x0F43, BIDI_L }, // TIBETAN LETTER GHA + { 0x0F44, BIDI_L }, // TIBETAN LETTER NGA + { 0x0F45, BIDI_L }, // TIBETAN LETTER CA + { 0x0F46, BIDI_L }, // TIBETAN LETTER CHA + { 0x0F47, BIDI_L }, // TIBETAN LETTER JA + { 0x0F49, BIDI_L }, // TIBETAN LETTER NYA + { 0x0F4A, BIDI_L }, // TIBETAN LETTER TTA + { 0x0F4B, BIDI_L }, // TIBETAN LETTER TTHA + { 0x0F4C, BIDI_L }, // TIBETAN LETTER DDA + { 0x0F4D, BIDI_L }, // TIBETAN LETTER DDHA + { 0x0F4E, BIDI_L }, // TIBETAN LETTER NNA + { 0x0F4F, BIDI_L }, // TIBETAN LETTER TA + { 0x0F50, BIDI_L }, // TIBETAN LETTER THA + { 0x0F51, BIDI_L }, // TIBETAN LETTER DA + { 0x0F52, BIDI_L }, // TIBETAN LETTER DHA + { 0x0F53, BIDI_L }, // TIBETAN LETTER NA + { 0x0F54, BIDI_L }, // TIBETAN LETTER PA + { 0x0F55, BIDI_L }, // TIBETAN LETTER PHA + { 0x0F56, BIDI_L }, // TIBETAN LETTER BA + { 0x0F57, BIDI_L }, // TIBETAN LETTER BHA + { 0x0F58, BIDI_L }, // TIBETAN LETTER MA + { 0x0F59, BIDI_L }, // TIBETAN LETTER TSA + { 0x0F5A, BIDI_L }, // TIBETAN LETTER TSHA + { 0x0F5B, BIDI_L }, // TIBETAN LETTER DZA + { 0x0F5C, BIDI_L }, // TIBETAN LETTER DZHA + { 0x0F5D, BIDI_L }, // TIBETAN LETTER WA + { 0x0F5E, BIDI_L }, // TIBETAN LETTER ZHA + { 0x0F5F, BIDI_L }, // TIBETAN LETTER ZA + { 0x0F60, BIDI_L }, // TIBETAN LETTER -A + { 0x0F61, BIDI_L }, // TIBETAN LETTER YA + { 0x0F62, BIDI_L }, // TIBETAN LETTER RA + { 0x0F63, BIDI_L }, // TIBETAN LETTER LA + { 0x0F64, BIDI_L }, // TIBETAN LETTER SHA + { 0x0F65, BIDI_L }, // TIBETAN LETTER SSA + { 0x0F66, BIDI_L }, // TIBETAN LETTER SA + { 0x0F67, BIDI_L }, // TIBETAN LETTER HA + { 0x0F68, BIDI_L }, // TIBETAN LETTER A + { 0x0F69, BIDI_L }, // TIBETAN LETTER KSSA + { 0x0F6A, BIDI_L }, // TIBETAN LETTER FIXED-FORM RA + { 0x0F6B, BIDI_L }, // TIBETAN LETTER KKA + { 0x0F6C, BIDI_L }, // TIBETAN LETTER RRA + { 0x0F71, BIDI_NSM }, // TIBETAN VOWEL SIGN AA + { 0x0F72, BIDI_NSM }, // TIBETAN VOWEL SIGN I + { 0x0F73, BIDI_NSM }, // TIBETAN VOWEL SIGN II + { 0x0F74, BIDI_NSM }, // TIBETAN VOWEL SIGN U + { 0x0F75, BIDI_NSM }, // TIBETAN VOWEL SIGN UU + { 0x0F76, BIDI_NSM }, // TIBETAN VOWEL SIGN VOCALIC R + { 0x0F77, BIDI_NSM }, // TIBETAN VOWEL SIGN VOCALIC RR + { 0x0F78, BIDI_NSM }, // TIBETAN VOWEL SIGN VOCALIC L + { 0x0F79, BIDI_NSM }, // TIBETAN VOWEL SIGN VOCALIC LL + { 0x0F7A, BIDI_NSM }, // TIBETAN VOWEL SIGN E + { 0x0F7B, BIDI_NSM }, // TIBETAN VOWEL SIGN EE + { 0x0F7C, BIDI_NSM }, // TIBETAN VOWEL SIGN O + { 0x0F7D, BIDI_NSM }, // TIBETAN VOWEL SIGN OO + { 0x0F7E, BIDI_NSM }, // TIBETAN SIGN RJES SU NGA RO + { 0x0F7F, BIDI_L }, // TIBETAN SIGN RNAM BCAD + { 0x0F80, BIDI_NSM }, // TIBETAN VOWEL SIGN REVERSED I + { 0x0F81, BIDI_NSM }, // TIBETAN VOWEL SIGN REVERSED II + { 0x0F82, BIDI_NSM }, // TIBETAN SIGN NYI ZLA NAA DA + { 0x0F83, BIDI_NSM }, // TIBETAN SIGN SNA LDAN + { 0x0F84, BIDI_NSM }, // TIBETAN MARK HALANTA + { 0x0F85, BIDI_L }, // TIBETAN MARK PALUTA + { 0x0F86, BIDI_NSM }, // TIBETAN SIGN LCI RTAGS + { 0x0F87, BIDI_NSM }, // TIBETAN SIGN YANG RTAGS + { 0x0F88, BIDI_L }, // TIBETAN SIGN LCE TSA CAN + { 0x0F89, BIDI_L }, // TIBETAN SIGN MCHU CAN + { 0x0F8A, BIDI_L }, // TIBETAN SIGN GRU CAN RGYINGS + { 0x0F8B, BIDI_L }, // TIBETAN SIGN GRU MED RGYINGS + { 0x0F8C, BIDI_L }, // TIBETAN SIGN INVERTED MCHU CAN + { 0x0F8D, BIDI_NSM }, // TIBETAN SUBJOINED SIGN LCE TSA CAN + { 0x0F8E, BIDI_NSM }, // TIBETAN SUBJOINED SIGN MCHU CAN + { 0x0F8F, BIDI_NSM }, // TIBETAN SUBJOINED SIGN INVERTED MCHU CAN + { 0x0F90, BIDI_NSM }, // TIBETAN SUBJOINED LETTER KA + { 0x0F91, BIDI_NSM }, // TIBETAN SUBJOINED LETTER KHA + { 0x0F92, BIDI_NSM }, // TIBETAN SUBJOINED LETTER GA + { 0x0F93, BIDI_NSM }, // TIBETAN SUBJOINED LETTER GHA + { 0x0F94, BIDI_NSM }, // TIBETAN SUBJOINED LETTER NGA + { 0x0F95, BIDI_NSM }, // TIBETAN SUBJOINED LETTER CA + { 0x0F96, BIDI_NSM }, // TIBETAN SUBJOINED LETTER CHA + { 0x0F97, BIDI_NSM }, // TIBETAN SUBJOINED LETTER JA + { 0x0F99, BIDI_NSM }, // TIBETAN SUBJOINED LETTER NYA + { 0x0F9A, BIDI_NSM }, // TIBETAN SUBJOINED LETTER TTA + { 0x0F9B, BIDI_NSM }, // TIBETAN SUBJOINED LETTER TTHA + { 0x0F9C, BIDI_NSM }, // TIBETAN SUBJOINED LETTER DDA + { 0x0F9D, BIDI_NSM }, // TIBETAN SUBJOINED LETTER DDHA + { 0x0F9E, BIDI_NSM }, // TIBETAN SUBJOINED LETTER NNA + { 0x0F9F, BIDI_NSM }, // TIBETAN SUBJOINED LETTER TA + { 0x0FA0, BIDI_NSM }, // TIBETAN SUBJOINED LETTER THA + { 0x0FA1, BIDI_NSM }, // TIBETAN SUBJOINED LETTER DA + { 0x0FA2, BIDI_NSM }, // TIBETAN SUBJOINED LETTER DHA + { 0x0FA3, BIDI_NSM }, // TIBETAN SUBJOINED LETTER NA + { 0x0FA4, BIDI_NSM }, // TIBETAN SUBJOINED LETTER PA + { 0x0FA5, BIDI_NSM }, // TIBETAN SUBJOINED LETTER PHA + { 0x0FA6, BIDI_NSM }, // TIBETAN SUBJOINED LETTER BA + { 0x0FA7, BIDI_NSM }, // TIBETAN SUBJOINED LETTER BHA + { 0x0FA8, BIDI_NSM }, // TIBETAN SUBJOINED LETTER MA + { 0x0FA9, BIDI_NSM }, // TIBETAN SUBJOINED LETTER TSA + { 0x0FAA, BIDI_NSM }, // TIBETAN SUBJOINED LETTER TSHA + { 0x0FAB, BIDI_NSM }, // TIBETAN SUBJOINED LETTER DZA + { 0x0FAC, BIDI_NSM }, // TIBETAN SUBJOINED LETTER DZHA + { 0x0FAD, BIDI_NSM }, // TIBETAN SUBJOINED LETTER WA + { 0x0FAE, BIDI_NSM }, // TIBETAN SUBJOINED LETTER ZHA + { 0x0FAF, BIDI_NSM }, // TIBETAN SUBJOINED LETTER ZA + { 0x0FB0, BIDI_NSM }, // TIBETAN SUBJOINED LETTER -A + { 0x0FB1, BIDI_NSM }, // TIBETAN SUBJOINED LETTER YA + { 0x0FB2, BIDI_NSM }, // TIBETAN SUBJOINED LETTER RA + { 0x0FB3, BIDI_NSM }, // TIBETAN SUBJOINED LETTER LA + { 0x0FB4, BIDI_NSM }, // TIBETAN SUBJOINED LETTER SHA + { 0x0FB5, BIDI_NSM }, // TIBETAN SUBJOINED LETTER SSA + { 0x0FB6, BIDI_NSM }, // TIBETAN SUBJOINED LETTER SA + { 0x0FB7, BIDI_NSM }, // TIBETAN SUBJOINED LETTER HA + { 0x0FB8, BIDI_NSM }, // TIBETAN SUBJOINED LETTER A + { 0x0FB9, BIDI_NSM }, // TIBETAN SUBJOINED LETTER KSSA + { 0x0FBA, BIDI_NSM }, // TIBETAN SUBJOINED LETTER FIXED-FORM WA + { 0x0FBB, BIDI_NSM }, // TIBETAN SUBJOINED LETTER FIXED-FORM YA + { 0x0FBC, BIDI_NSM }, // TIBETAN SUBJOINED LETTER FIXED-FORM RA + { 0x0FBE, BIDI_L }, // TIBETAN KU RU KHA + { 0x0FBF, BIDI_L }, // TIBETAN KU RU KHA BZHI MIG CAN + { 0x0FC0, BIDI_L }, // TIBETAN CANTILLATION SIGN HEAVY BEAT + { 0x0FC1, BIDI_L }, // TIBETAN CANTILLATION SIGN LIGHT BEAT + { 0x0FC2, BIDI_L }, // TIBETAN CANTILLATION SIGN CANG TE-U + { 0x0FC3, BIDI_L }, // TIBETAN CANTILLATION SIGN SBUB -CHAL + { 0x0FC4, BIDI_L }, // TIBETAN SYMBOL DRIL BU + { 0x0FC5, BIDI_L }, // TIBETAN SYMBOL RDO RJE + { 0x0FC6, BIDI_NSM }, // TIBETAN SYMBOL PADMA GDAN + { 0x0FC7, BIDI_L }, // TIBETAN SYMBOL RDO RJE RGYA GRAM + { 0x0FC8, BIDI_L }, // TIBETAN SYMBOL PHUR PA + { 0x0FC9, BIDI_L }, // TIBETAN SYMBOL NOR BU + { 0x0FCA, BIDI_L }, // TIBETAN SYMBOL NOR BU NYIS -KHYIL + { 0x0FCB, BIDI_L }, // TIBETAN SYMBOL NOR BU GSUM -KHYIL + { 0x0FCC, BIDI_L }, // TIBETAN SYMBOL NOR BU BZHI -KHYIL + { 0x0FCE, BIDI_L }, // TIBETAN SIGN RDEL NAG RDEL DKAR + { 0x0FCF, BIDI_L }, // TIBETAN SIGN RDEL NAG GSUM + { 0x0FD0, BIDI_L }, // TIBETAN MARK BSKA- SHOG GI MGO RGYAN + { 0x0FD1, BIDI_L }, // TIBETAN MARK MNYAM YIG GI MGO RGYAN + { 0x0FD2, BIDI_L }, // TIBETAN MARK NYIS TSHEG + { 0x0FD3, BIDI_L }, // TIBETAN MARK INITIAL BRDA RNYING YIG MGO MDUN MA + { 0x0FD4, BIDI_L }, // TIBETAN MARK CLOSING BRDA RNYING YIG MGO SGAB MA + { 0x0FD5, BIDI_L }, // RIGHT-FACING SVASTI SIGN + { 0x0FD6, BIDI_L }, // LEFT-FACING SVASTI SIGN + { 0x0FD7, BIDI_L }, // RIGHT-FACING SVASTI SIGN WITH DOTS + { 0x0FD8, BIDI_L }, // LEFT-FACING SVASTI SIGN WITH DOTS + { 0x0FD9, BIDI_L }, // TIBETAN MARK LEADING MCHAN RTAGS + { 0x0FDA, BIDI_L }, // TIBETAN MARK TRAILING MCHAN RTAGS + +#endif +#if (GUI_BIDI_SUPPORT_RANGE_1 == 1) + + { 0x1000, BIDI_L }, // MYANMAR LETTER KA + { 0x1001, BIDI_L }, // MYANMAR LETTER KHA + { 0x1002, BIDI_L }, // MYANMAR LETTER GA + { 0x1003, BIDI_L }, // MYANMAR LETTER GHA + { 0x1004, BIDI_L }, // MYANMAR LETTER NGA + { 0x1005, BIDI_L }, // MYANMAR LETTER CA + { 0x1006, BIDI_L }, // MYANMAR LETTER CHA + { 0x1007, BIDI_L }, // MYANMAR LETTER JA + { 0x1008, BIDI_L }, // MYANMAR LETTER JHA + { 0x1009, BIDI_L }, // MYANMAR LETTER NYA + { 0x100A, BIDI_L }, // MYANMAR LETTER NNYA + { 0x100B, BIDI_L }, // MYANMAR LETTER TTA + { 0x100C, BIDI_L }, // MYANMAR LETTER TTHA + { 0x100D, BIDI_L }, // MYANMAR LETTER DDA + { 0x100E, BIDI_L }, // MYANMAR LETTER DDHA + { 0x100F, BIDI_L }, // MYANMAR LETTER NNA + { 0x1010, BIDI_L }, // MYANMAR LETTER TA + { 0x1011, BIDI_L }, // MYANMAR LETTER THA + { 0x1012, BIDI_L }, // MYANMAR LETTER DA + { 0x1013, BIDI_L }, // MYANMAR LETTER DHA + { 0x1014, BIDI_L }, // MYANMAR LETTER NA + { 0x1015, BIDI_L }, // MYANMAR LETTER PA + { 0x1016, BIDI_L }, // MYANMAR LETTER PHA + { 0x1017, BIDI_L }, // MYANMAR LETTER BA + { 0x1018, BIDI_L }, // MYANMAR LETTER BHA + { 0x1019, BIDI_L }, // MYANMAR LETTER MA + { 0x101A, BIDI_L }, // MYANMAR LETTER YA + { 0x101B, BIDI_L }, // MYANMAR LETTER RA + { 0x101C, BIDI_L }, // MYANMAR LETTER LA + { 0x101D, BIDI_L }, // MYANMAR LETTER WA + { 0x101E, BIDI_L }, // MYANMAR LETTER SA + { 0x101F, BIDI_L }, // MYANMAR LETTER HA + { 0x1020, BIDI_L }, // MYANMAR LETTER LLA + { 0x1021, BIDI_L }, // MYANMAR LETTER A + { 0x1022, BIDI_L }, // MYANMAR LETTER SHAN A + { 0x1023, BIDI_L }, // MYANMAR LETTER I + { 0x1024, BIDI_L }, // MYANMAR LETTER II + { 0x1025, BIDI_L }, // MYANMAR LETTER U + { 0x1026, BIDI_L }, // MYANMAR LETTER UU + { 0x1027, BIDI_L }, // MYANMAR LETTER E + { 0x1028, BIDI_L }, // MYANMAR LETTER MON E + { 0x1029, BIDI_L }, // MYANMAR LETTER O + { 0x102A, BIDI_L }, // MYANMAR LETTER AU + { 0x102B, BIDI_L }, // MYANMAR VOWEL SIGN TALL AA + { 0x102C, BIDI_L }, // MYANMAR VOWEL SIGN AA + { 0x102D, BIDI_NSM }, // MYANMAR VOWEL SIGN I + { 0x102E, BIDI_NSM }, // MYANMAR VOWEL SIGN II + { 0x102F, BIDI_NSM }, // MYANMAR VOWEL SIGN U + { 0x1030, BIDI_NSM }, // MYANMAR VOWEL SIGN UU + { 0x1031, BIDI_L }, // MYANMAR VOWEL SIGN E + { 0x1032, BIDI_NSM }, // MYANMAR VOWEL SIGN AI + { 0x1033, BIDI_NSM }, // MYANMAR VOWEL SIGN MON II + { 0x1034, BIDI_NSM }, // MYANMAR VOWEL SIGN MON O + { 0x1035, BIDI_NSM }, // MYANMAR VOWEL SIGN E ABOVE + { 0x1036, BIDI_NSM }, // MYANMAR SIGN ANUSVARA + { 0x1037, BIDI_NSM }, // MYANMAR SIGN DOT BELOW + { 0x1038, BIDI_L }, // MYANMAR SIGN VISARGA + { 0x1039, BIDI_NSM }, // MYANMAR SIGN VIRAMA + { 0x103A, BIDI_NSM }, // MYANMAR SIGN ASAT + { 0x103B, BIDI_L }, // MYANMAR CONSONANT SIGN MEDIAL YA + { 0x103C, BIDI_L }, // MYANMAR CONSONANT SIGN MEDIAL RA + { 0x103D, BIDI_NSM }, // MYANMAR CONSONANT SIGN MEDIAL WA + { 0x103E, BIDI_NSM }, // MYANMAR CONSONANT SIGN MEDIAL HA + { 0x103F, BIDI_L }, // MYANMAR LETTER GREAT SA + { 0x1040, BIDI_L }, // MYANMAR DIGIT ZERO + { 0x1041, BIDI_L }, // MYANMAR DIGIT ONE + { 0x1042, BIDI_L }, // MYANMAR DIGIT TWO + { 0x1043, BIDI_L }, // MYANMAR DIGIT THREE + { 0x1044, BIDI_L }, // MYANMAR DIGIT FOUR + { 0x1045, BIDI_L }, // MYANMAR DIGIT FIVE + { 0x1046, BIDI_L }, // MYANMAR DIGIT SIX + { 0x1047, BIDI_L }, // MYANMAR DIGIT SEVEN + { 0x1048, BIDI_L }, // MYANMAR DIGIT EIGHT + { 0x1049, BIDI_L }, // MYANMAR DIGIT NINE + { 0x104A, BIDI_L }, // MYANMAR SIGN LITTLE SECTION + { 0x104B, BIDI_L }, // MYANMAR SIGN SECTION + { 0x104C, BIDI_L }, // MYANMAR SYMBOL LOCATIVE + { 0x104D, BIDI_L }, // MYANMAR SYMBOL COMPLETED + { 0x104E, BIDI_L }, // MYANMAR SYMBOL AFOREMENTIONED + { 0x104F, BIDI_L }, // MYANMAR SYMBOL GENITIVE + { 0x1050, BIDI_L }, // MYANMAR LETTER SHA + { 0x1051, BIDI_L }, // MYANMAR LETTER SSA + { 0x1052, BIDI_L }, // MYANMAR LETTER VOCALIC R + { 0x1053, BIDI_L }, // MYANMAR LETTER VOCALIC RR + { 0x1054, BIDI_L }, // MYANMAR LETTER VOCALIC L + { 0x1055, BIDI_L }, // MYANMAR LETTER VOCALIC LL + { 0x1056, BIDI_L }, // MYANMAR VOWEL SIGN VOCALIC R + { 0x1057, BIDI_L }, // MYANMAR VOWEL SIGN VOCALIC RR + { 0x1058, BIDI_NSM }, // MYANMAR VOWEL SIGN VOCALIC L + { 0x1059, BIDI_NSM }, // MYANMAR VOWEL SIGN VOCALIC LL + { 0x105A, BIDI_L }, // MYANMAR LETTER MON NGA + { 0x105B, BIDI_L }, // MYANMAR LETTER MON JHA + { 0x105C, BIDI_L }, // MYANMAR LETTER MON BBA + { 0x105D, BIDI_L }, // MYANMAR LETTER MON BBE + { 0x105E, BIDI_NSM }, // MYANMAR CONSONANT SIGN MON MEDIAL NA + { 0x105F, BIDI_NSM }, // MYANMAR CONSONANT SIGN MON MEDIAL MA + { 0x1060, BIDI_NSM }, // MYANMAR CONSONANT SIGN MON MEDIAL LA + { 0x1061, BIDI_L }, // MYANMAR LETTER SGAW KAREN SHA + { 0x1062, BIDI_L }, // MYANMAR VOWEL SIGN SGAW KAREN EU + { 0x1063, BIDI_L }, // MYANMAR TONE MARK SGAW KAREN HATHI + { 0x1064, BIDI_L }, // MYANMAR TONE MARK SGAW KAREN KE PHO + { 0x1065, BIDI_L }, // MYANMAR LETTER WESTERN PWO KAREN THA + { 0x1066, BIDI_L }, // MYANMAR LETTER WESTERN PWO KAREN PWA + { 0x1067, BIDI_L }, // MYANMAR VOWEL SIGN WESTERN PWO KAREN EU + { 0x1068, BIDI_L }, // MYANMAR VOWEL SIGN WESTERN PWO KAREN UE + { 0x1069, BIDI_L }, // MYANMAR SIGN WESTERN PWO KAREN TONE-1 + { 0x106A, BIDI_L }, // MYANMAR SIGN WESTERN PWO KAREN TONE-2 + { 0x106B, BIDI_L }, // MYANMAR SIGN WESTERN PWO KAREN TONE-3 + { 0x106C, BIDI_L }, // MYANMAR SIGN WESTERN PWO KAREN TONE-4 + { 0x106D, BIDI_L }, // MYANMAR SIGN WESTERN PWO KAREN TONE-5 + { 0x106E, BIDI_L }, // MYANMAR LETTER EASTERN PWO KAREN NNA + { 0x106F, BIDI_L }, // MYANMAR LETTER EASTERN PWO KAREN YWA + { 0x1070, BIDI_L }, // MYANMAR LETTER EASTERN PWO KAREN GHWA + { 0x1071, BIDI_NSM }, // MYANMAR VOWEL SIGN GEBA KAREN I + { 0x1072, BIDI_NSM }, // MYANMAR VOWEL SIGN KAYAH OE + { 0x1073, BIDI_NSM }, // MYANMAR VOWEL SIGN KAYAH U + { 0x1074, BIDI_NSM }, // MYANMAR VOWEL SIGN KAYAH EE + { 0x1075, BIDI_L }, // MYANMAR LETTER SHAN KA + { 0x1076, BIDI_L }, // MYANMAR LETTER SHAN KHA + { 0x1077, BIDI_L }, // MYANMAR LETTER SHAN GA + { 0x1078, BIDI_L }, // MYANMAR LETTER SHAN CA + { 0x1079, BIDI_L }, // MYANMAR LETTER SHAN ZA + { 0x107A, BIDI_L }, // MYANMAR LETTER SHAN NYA + { 0x107B, BIDI_L }, // MYANMAR LETTER SHAN DA + { 0x107C, BIDI_L }, // MYANMAR LETTER SHAN NA + { 0x107D, BIDI_L }, // MYANMAR LETTER SHAN PHA + { 0x107E, BIDI_L }, // MYANMAR LETTER SHAN FA + { 0x107F, BIDI_L }, // MYANMAR LETTER SHAN BA + { 0x1080, BIDI_L }, // MYANMAR LETTER SHAN THA + { 0x1081, BIDI_L }, // MYANMAR LETTER SHAN HA + { 0x1082, BIDI_NSM }, // MYANMAR CONSONANT SIGN SHAN MEDIAL WA + { 0x1083, BIDI_L }, // MYANMAR VOWEL SIGN SHAN AA + { 0x1084, BIDI_L }, // MYANMAR VOWEL SIGN SHAN E + { 0x1085, BIDI_NSM }, // MYANMAR VOWEL SIGN SHAN E ABOVE + { 0x1086, BIDI_NSM }, // MYANMAR VOWEL SIGN SHAN FINAL Y + { 0x1087, BIDI_L }, // MYANMAR SIGN SHAN TONE-2 + { 0x1088, BIDI_L }, // MYANMAR SIGN SHAN TONE-3 + { 0x1089, BIDI_L }, // MYANMAR SIGN SHAN TONE-5 + { 0x108A, BIDI_L }, // MYANMAR SIGN SHAN TONE-6 + { 0x108B, BIDI_L }, // MYANMAR SIGN SHAN COUNCIL TONE-2 + { 0x108C, BIDI_L }, // MYANMAR SIGN SHAN COUNCIL TONE-3 + { 0x108D, BIDI_NSM }, // MYANMAR SIGN SHAN COUNCIL EMPHATIC TONE + { 0x108E, BIDI_L }, // MYANMAR LETTER RUMAI PALAUNG FA + { 0x108F, BIDI_L }, // MYANMAR SIGN RUMAI PALAUNG TONE-5 + { 0x1090, BIDI_L }, // MYANMAR SHAN DIGIT ZERO + { 0x1091, BIDI_L }, // MYANMAR SHAN DIGIT ONE + { 0x1092, BIDI_L }, // MYANMAR SHAN DIGIT TWO + { 0x1093, BIDI_L }, // MYANMAR SHAN DIGIT THREE + { 0x1094, BIDI_L }, // MYANMAR SHAN DIGIT FOUR + { 0x1095, BIDI_L }, // MYANMAR SHAN DIGIT FIVE + { 0x1096, BIDI_L }, // MYANMAR SHAN DIGIT SIX + { 0x1097, BIDI_L }, // MYANMAR SHAN DIGIT SEVEN + { 0x1098, BIDI_L }, // MYANMAR SHAN DIGIT EIGHT + { 0x1099, BIDI_L }, // MYANMAR SHAN DIGIT NINE + { 0x109A, BIDI_L }, // MYANMAR SIGN KHAMTI TONE-1 + { 0x109B, BIDI_L }, // MYANMAR SIGN KHAMTI TONE-3 + { 0x109C, BIDI_L }, // MYANMAR VOWEL SIGN AITON A + { 0x109D, BIDI_NSM }, // MYANMAR VOWEL SIGN AITON AI + { 0x109E, BIDI_L }, // MYANMAR SYMBOL SHAN ONE + { 0x109F, BIDI_L }, // MYANMAR SYMBOL SHAN EXCLAMATION + { 0x10A0, BIDI_L }, // GEORGIAN CAPITAL LETTER AN + { 0x10A1, BIDI_L }, // GEORGIAN CAPITAL LETTER BAN + { 0x10A2, BIDI_L }, // GEORGIAN CAPITAL LETTER GAN + { 0x10A3, BIDI_L }, // GEORGIAN CAPITAL LETTER DON + { 0x10A4, BIDI_L }, // GEORGIAN CAPITAL LETTER EN + { 0x10A5, BIDI_L }, // GEORGIAN CAPITAL LETTER VIN + { 0x10A6, BIDI_L }, // GEORGIAN CAPITAL LETTER ZEN + { 0x10A7, BIDI_L }, // GEORGIAN CAPITAL LETTER TAN + { 0x10A8, BIDI_L }, // GEORGIAN CAPITAL LETTER IN + { 0x10A9, BIDI_L }, // GEORGIAN CAPITAL LETTER KAN + { 0x10AA, BIDI_L }, // GEORGIAN CAPITAL LETTER LAS + { 0x10AB, BIDI_L }, // GEORGIAN CAPITAL LETTER MAN + { 0x10AC, BIDI_L }, // GEORGIAN CAPITAL LETTER NAR + { 0x10AD, BIDI_L }, // GEORGIAN CAPITAL LETTER ON + { 0x10AE, BIDI_L }, // GEORGIAN CAPITAL LETTER PAR + { 0x10AF, BIDI_L }, // GEORGIAN CAPITAL LETTER ZHAR + { 0x10B0, BIDI_L }, // GEORGIAN CAPITAL LETTER RAE + { 0x10B1, BIDI_L }, // GEORGIAN CAPITAL LETTER SAN + { 0x10B2, BIDI_L }, // GEORGIAN CAPITAL LETTER TAR + { 0x10B3, BIDI_L }, // GEORGIAN CAPITAL LETTER UN + { 0x10B4, BIDI_L }, // GEORGIAN CAPITAL LETTER PHAR + { 0x10B5, BIDI_L }, // GEORGIAN CAPITAL LETTER KHAR + { 0x10B6, BIDI_L }, // GEORGIAN CAPITAL LETTER GHAN + { 0x10B7, BIDI_L }, // GEORGIAN CAPITAL LETTER QAR + { 0x10B8, BIDI_L }, // GEORGIAN CAPITAL LETTER SHIN + { 0x10B9, BIDI_L }, // GEORGIAN CAPITAL LETTER CHIN + { 0x10BA, BIDI_L }, // GEORGIAN CAPITAL LETTER CAN + { 0x10BB, BIDI_L }, // GEORGIAN CAPITAL LETTER JIL + { 0x10BC, BIDI_L }, // GEORGIAN CAPITAL LETTER CIL + { 0x10BD, BIDI_L }, // GEORGIAN CAPITAL LETTER CHAR + { 0x10BE, BIDI_L }, // GEORGIAN CAPITAL LETTER XAN + { 0x10BF, BIDI_L }, // GEORGIAN CAPITAL LETTER JHAN + { 0x10C0, BIDI_L }, // GEORGIAN CAPITAL LETTER HAE + { 0x10C1, BIDI_L }, // GEORGIAN CAPITAL LETTER HE + { 0x10C2, BIDI_L }, // GEORGIAN CAPITAL LETTER HIE + { 0x10C3, BIDI_L }, // GEORGIAN CAPITAL LETTER WE + { 0x10C4, BIDI_L }, // GEORGIAN CAPITAL LETTER HAR + { 0x10C5, BIDI_L }, // GEORGIAN CAPITAL LETTER HOE + { 0x10C7, BIDI_L }, // GEORGIAN CAPITAL LETTER YN + { 0x10CD, BIDI_L }, // GEORGIAN CAPITAL LETTER AEN + { 0x10D0, BIDI_L }, // GEORGIAN LETTER AN + { 0x10D1, BIDI_L }, // GEORGIAN LETTER BAN + { 0x10D2, BIDI_L }, // GEORGIAN LETTER GAN + { 0x10D3, BIDI_L }, // GEORGIAN LETTER DON + { 0x10D4, BIDI_L }, // GEORGIAN LETTER EN + { 0x10D5, BIDI_L }, // GEORGIAN LETTER VIN + { 0x10D6, BIDI_L }, // GEORGIAN LETTER ZEN + { 0x10D7, BIDI_L }, // GEORGIAN LETTER TAN + { 0x10D8, BIDI_L }, // GEORGIAN LETTER IN + { 0x10D9, BIDI_L }, // GEORGIAN LETTER KAN + { 0x10DA, BIDI_L }, // GEORGIAN LETTER LAS + { 0x10DB, BIDI_L }, // GEORGIAN LETTER MAN + { 0x10DC, BIDI_L }, // GEORGIAN LETTER NAR + { 0x10DD, BIDI_L }, // GEORGIAN LETTER ON + { 0x10DE, BIDI_L }, // GEORGIAN LETTER PAR + { 0x10DF, BIDI_L }, // GEORGIAN LETTER ZHAR + { 0x10E0, BIDI_L }, // GEORGIAN LETTER RAE + { 0x10E1, BIDI_L }, // GEORGIAN LETTER SAN + { 0x10E2, BIDI_L }, // GEORGIAN LETTER TAR + { 0x10E3, BIDI_L }, // GEORGIAN LETTER UN + { 0x10E4, BIDI_L }, // GEORGIAN LETTER PHAR + { 0x10E5, BIDI_L }, // GEORGIAN LETTER KHAR + { 0x10E6, BIDI_L }, // GEORGIAN LETTER GHAN + { 0x10E7, BIDI_L }, // GEORGIAN LETTER QAR + { 0x10E8, BIDI_L }, // GEORGIAN LETTER SHIN + { 0x10E9, BIDI_L }, // GEORGIAN LETTER CHIN + { 0x10EA, BIDI_L }, // GEORGIAN LETTER CAN + { 0x10EB, BIDI_L }, // GEORGIAN LETTER JIL + { 0x10EC, BIDI_L }, // GEORGIAN LETTER CIL + { 0x10ED, BIDI_L }, // GEORGIAN LETTER CHAR + { 0x10EE, BIDI_L }, // GEORGIAN LETTER XAN + { 0x10EF, BIDI_L }, // GEORGIAN LETTER JHAN + { 0x10F0, BIDI_L }, // GEORGIAN LETTER HAE + { 0x10F1, BIDI_L }, // GEORGIAN LETTER HE + { 0x10F2, BIDI_L }, // GEORGIAN LETTER HIE + { 0x10F3, BIDI_L }, // GEORGIAN LETTER WE + { 0x10F4, BIDI_L }, // GEORGIAN LETTER HAR + { 0x10F5, BIDI_L }, // GEORGIAN LETTER HOE + { 0x10F6, BIDI_L }, // GEORGIAN LETTER FI + { 0x10F7, BIDI_L }, // GEORGIAN LETTER YN + { 0x10F8, BIDI_L }, // GEORGIAN LETTER ELIFI + { 0x10F9, BIDI_L }, // GEORGIAN LETTER TURNED GAN + { 0x10FA, BIDI_L }, // GEORGIAN LETTER AIN + { 0x10FB, BIDI_L }, // GEORGIAN PARAGRAPH SEPARATOR + { 0x10FC, BIDI_L }, // MODIFIER LETTER GEORGIAN NAR + { 0x10FD, BIDI_L }, // GEORGIAN LETTER AEN + { 0x10FE, BIDI_L }, // GEORGIAN LETTER HARD SIGN + { 0x10FF, BIDI_L }, // GEORGIAN LETTER LABIAL SIGN + { 0x1100, BIDI_L }, // HANGUL CHOSEONG KIYEOK + { 0x1101, BIDI_L }, // HANGUL CHOSEONG SSANGKIYEOK + { 0x1102, BIDI_L }, // HANGUL CHOSEONG NIEUN + { 0x1103, BIDI_L }, // HANGUL CHOSEONG TIKEUT + { 0x1104, BIDI_L }, // HANGUL CHOSEONG SSANGTIKEUT + { 0x1105, BIDI_L }, // HANGUL CHOSEONG RIEUL + { 0x1106, BIDI_L }, // HANGUL CHOSEONG MIEUM + { 0x1107, BIDI_L }, // HANGUL CHOSEONG PIEUP + { 0x1108, BIDI_L }, // HANGUL CHOSEONG SSANGPIEUP + { 0x1109, BIDI_L }, // HANGUL CHOSEONG SIOS + { 0x110A, BIDI_L }, // HANGUL CHOSEONG SSANGSIOS + { 0x110B, BIDI_L }, // HANGUL CHOSEONG IEUNG + { 0x110C, BIDI_L }, // HANGUL CHOSEONG CIEUC + { 0x110D, BIDI_L }, // HANGUL CHOSEONG SSANGCIEUC + { 0x110E, BIDI_L }, // HANGUL CHOSEONG CHIEUCH + { 0x110F, BIDI_L }, // HANGUL CHOSEONG KHIEUKH + { 0x1110, BIDI_L }, // HANGUL CHOSEONG THIEUTH + { 0x1111, BIDI_L }, // HANGUL CHOSEONG PHIEUPH + { 0x1112, BIDI_L }, // HANGUL CHOSEONG HIEUH + { 0x1113, BIDI_L }, // HANGUL CHOSEONG NIEUN-KIYEOK + { 0x1114, BIDI_L }, // HANGUL CHOSEONG SSANGNIEUN + { 0x1115, BIDI_L }, // HANGUL CHOSEONG NIEUN-TIKEUT + { 0x1116, BIDI_L }, // HANGUL CHOSEONG NIEUN-PIEUP + { 0x1117, BIDI_L }, // HANGUL CHOSEONG TIKEUT-KIYEOK + { 0x1118, BIDI_L }, // HANGUL CHOSEONG RIEUL-NIEUN + { 0x1119, BIDI_L }, // HANGUL CHOSEONG SSANGRIEUL + { 0x111A, BIDI_L }, // HANGUL CHOSEONG RIEUL-HIEUH + { 0x111B, BIDI_L }, // HANGUL CHOSEONG KAPYEOUNRIEUL + { 0x111C, BIDI_L }, // HANGUL CHOSEONG MIEUM-PIEUP + { 0x111D, BIDI_L }, // HANGUL CHOSEONG KAPYEOUNMIEUM + { 0x111E, BIDI_L }, // HANGUL CHOSEONG PIEUP-KIYEOK + { 0x111F, BIDI_L }, // HANGUL CHOSEONG PIEUP-NIEUN + { 0x1120, BIDI_L }, // HANGUL CHOSEONG PIEUP-TIKEUT + { 0x1121, BIDI_L }, // HANGUL CHOSEONG PIEUP-SIOS + { 0x1122, BIDI_L }, // HANGUL CHOSEONG PIEUP-SIOS-KIYEOK + { 0x1123, BIDI_L }, // HANGUL CHOSEONG PIEUP-SIOS-TIKEUT + { 0x1124, BIDI_L }, // HANGUL CHOSEONG PIEUP-SIOS-PIEUP + { 0x1125, BIDI_L }, // HANGUL CHOSEONG PIEUP-SSANGSIOS + { 0x1126, BIDI_L }, // HANGUL CHOSEONG PIEUP-SIOS-CIEUC + { 0x1127, BIDI_L }, // HANGUL CHOSEONG PIEUP-CIEUC + { 0x1128, BIDI_L }, // HANGUL CHOSEONG PIEUP-CHIEUCH + { 0x1129, BIDI_L }, // HANGUL CHOSEONG PIEUP-THIEUTH + { 0x112A, BIDI_L }, // HANGUL CHOSEONG PIEUP-PHIEUPH + { 0x112B, BIDI_L }, // HANGUL CHOSEONG KAPYEOUNPIEUP + { 0x112C, BIDI_L }, // HANGUL CHOSEONG KAPYEOUNSSANGPIEUP + { 0x112D, BIDI_L }, // HANGUL CHOSEONG SIOS-KIYEOK + { 0x112E, BIDI_L }, // HANGUL CHOSEONG SIOS-NIEUN + { 0x112F, BIDI_L }, // HANGUL CHOSEONG SIOS-TIKEUT + { 0x1130, BIDI_L }, // HANGUL CHOSEONG SIOS-RIEUL + { 0x1131, BIDI_L }, // HANGUL CHOSEONG SIOS-MIEUM + { 0x1132, BIDI_L }, // HANGUL CHOSEONG SIOS-PIEUP + { 0x1133, BIDI_L }, // HANGUL CHOSEONG SIOS-PIEUP-KIYEOK + { 0x1134, BIDI_L }, // HANGUL CHOSEONG SIOS-SSANGSIOS + { 0x1135, BIDI_L }, // HANGUL CHOSEONG SIOS-IEUNG + { 0x1136, BIDI_L }, // HANGUL CHOSEONG SIOS-CIEUC + { 0x1137, BIDI_L }, // HANGUL CHOSEONG SIOS-CHIEUCH + { 0x1138, BIDI_L }, // HANGUL CHOSEONG SIOS-KHIEUKH + { 0x1139, BIDI_L }, // HANGUL CHOSEONG SIOS-THIEUTH + { 0x113A, BIDI_L }, // HANGUL CHOSEONG SIOS-PHIEUPH + { 0x113B, BIDI_L }, // HANGUL CHOSEONG SIOS-HIEUH + { 0x113C, BIDI_L }, // HANGUL CHOSEONG CHITUEUMSIOS + { 0x113D, BIDI_L }, // HANGUL CHOSEONG CHITUEUMSSANGSIOS + { 0x113E, BIDI_L }, // HANGUL CHOSEONG CEONGCHIEUMSIOS + { 0x113F, BIDI_L }, // HANGUL CHOSEONG CEONGCHIEUMSSANGSIOS + { 0x1140, BIDI_L }, // HANGUL CHOSEONG PANSIOS + { 0x1141, BIDI_L }, // HANGUL CHOSEONG IEUNG-KIYEOK + { 0x1142, BIDI_L }, // HANGUL CHOSEONG IEUNG-TIKEUT + { 0x1143, BIDI_L }, // HANGUL CHOSEONG IEUNG-MIEUM + { 0x1144, BIDI_L }, // HANGUL CHOSEONG IEUNG-PIEUP + { 0x1145, BIDI_L }, // HANGUL CHOSEONG IEUNG-SIOS + { 0x1146, BIDI_L }, // HANGUL CHOSEONG IEUNG-PANSIOS + { 0x1147, BIDI_L }, // HANGUL CHOSEONG SSANGIEUNG + { 0x1148, BIDI_L }, // HANGUL CHOSEONG IEUNG-CIEUC + { 0x1149, BIDI_L }, // HANGUL CHOSEONG IEUNG-CHIEUCH + { 0x114A, BIDI_L }, // HANGUL CHOSEONG IEUNG-THIEUTH + { 0x114B, BIDI_L }, // HANGUL CHOSEONG IEUNG-PHIEUPH + { 0x114C, BIDI_L }, // HANGUL CHOSEONG YESIEUNG + { 0x114D, BIDI_L }, // HANGUL CHOSEONG CIEUC-IEUNG + { 0x114E, BIDI_L }, // HANGUL CHOSEONG CHITUEUMCIEUC + { 0x114F, BIDI_L }, // HANGUL CHOSEONG CHITUEUMSSANGCIEUC + { 0x1150, BIDI_L }, // HANGUL CHOSEONG CEONGCHIEUMCIEUC + { 0x1151, BIDI_L }, // HANGUL CHOSEONG CEONGCHIEUMSSANGCIEUC + { 0x1152, BIDI_L }, // HANGUL CHOSEONG CHIEUCH-KHIEUKH + { 0x1153, BIDI_L }, // HANGUL CHOSEONG CHIEUCH-HIEUH + { 0x1154, BIDI_L }, // HANGUL CHOSEONG CHITUEUMCHIEUCH + { 0x1155, BIDI_L }, // HANGUL CHOSEONG CEONGCHIEUMCHIEUCH + { 0x1156, BIDI_L }, // HANGUL CHOSEONG PHIEUPH-PIEUP + { 0x1157, BIDI_L }, // HANGUL CHOSEONG KAPYEOUNPHIEUPH + { 0x1158, BIDI_L }, // HANGUL CHOSEONG SSANGHIEUH + { 0x1159, BIDI_L }, // HANGUL CHOSEONG YEORINHIEUH + { 0x115A, BIDI_L }, // HANGUL CHOSEONG KIYEOK-TIKEUT + { 0x115B, BIDI_L }, // HANGUL CHOSEONG NIEUN-SIOS + { 0x115C, BIDI_L }, // HANGUL CHOSEONG NIEUN-CIEUC + { 0x115D, BIDI_L }, // HANGUL CHOSEONG NIEUN-HIEUH + { 0x115E, BIDI_L }, // HANGUL CHOSEONG TIKEUT-RIEUL + { 0x115F, BIDI_L }, // HANGUL CHOSEONG FILLER + { 0x1160, BIDI_L }, // HANGUL JUNGSEONG FILLER + { 0x1161, BIDI_L }, // HANGUL JUNGSEONG A + { 0x1162, BIDI_L }, // HANGUL JUNGSEONG AE + { 0x1163, BIDI_L }, // HANGUL JUNGSEONG YA + { 0x1164, BIDI_L }, // HANGUL JUNGSEONG YAE + { 0x1165, BIDI_L }, // HANGUL JUNGSEONG EO + { 0x1166, BIDI_L }, // HANGUL JUNGSEONG E + { 0x1167, BIDI_L }, // HANGUL JUNGSEONG YEO + { 0x1168, BIDI_L }, // HANGUL JUNGSEONG YE + { 0x1169, BIDI_L }, // HANGUL JUNGSEONG O + { 0x116A, BIDI_L }, // HANGUL JUNGSEONG WA + { 0x116B, BIDI_L }, // HANGUL JUNGSEONG WAE + { 0x116C, BIDI_L }, // HANGUL JUNGSEONG OE + { 0x116D, BIDI_L }, // HANGUL JUNGSEONG YO + { 0x116E, BIDI_L }, // HANGUL JUNGSEONG U + { 0x116F, BIDI_L }, // HANGUL JUNGSEONG WEO + { 0x1170, BIDI_L }, // HANGUL JUNGSEONG WE + { 0x1171, BIDI_L }, // HANGUL JUNGSEONG WI + { 0x1172, BIDI_L }, // HANGUL JUNGSEONG YU + { 0x1173, BIDI_L }, // HANGUL JUNGSEONG EU + { 0x1174, BIDI_L }, // HANGUL JUNGSEONG YI + { 0x1175, BIDI_L }, // HANGUL JUNGSEONG I + { 0x1176, BIDI_L }, // HANGUL JUNGSEONG A-O + { 0x1177, BIDI_L }, // HANGUL JUNGSEONG A-U + { 0x1178, BIDI_L }, // HANGUL JUNGSEONG YA-O + { 0x1179, BIDI_L }, // HANGUL JUNGSEONG YA-YO + { 0x117A, BIDI_L }, // HANGUL JUNGSEONG EO-O + { 0x117B, BIDI_L }, // HANGUL JUNGSEONG EO-U + { 0x117C, BIDI_L }, // HANGUL JUNGSEONG EO-EU + { 0x117D, BIDI_L }, // HANGUL JUNGSEONG YEO-O + { 0x117E, BIDI_L }, // HANGUL JUNGSEONG YEO-U + { 0x117F, BIDI_L }, // HANGUL JUNGSEONG O-EO + { 0x1180, BIDI_L }, // HANGUL JUNGSEONG O-E + { 0x1181, BIDI_L }, // HANGUL JUNGSEONG O-YE + { 0x1182, BIDI_L }, // HANGUL JUNGSEONG O-O + { 0x1183, BIDI_L }, // HANGUL JUNGSEONG O-U + { 0x1184, BIDI_L }, // HANGUL JUNGSEONG YO-YA + { 0x1185, BIDI_L }, // HANGUL JUNGSEONG YO-YAE + { 0x1186, BIDI_L }, // HANGUL JUNGSEONG YO-YEO + { 0x1187, BIDI_L }, // HANGUL JUNGSEONG YO-O + { 0x1188, BIDI_L }, // HANGUL JUNGSEONG YO-I + { 0x1189, BIDI_L }, // HANGUL JUNGSEONG U-A + { 0x118A, BIDI_L }, // HANGUL JUNGSEONG U-AE + { 0x118B, BIDI_L }, // HANGUL JUNGSEONG U-EO-EU + { 0x118C, BIDI_L }, // HANGUL JUNGSEONG U-YE + { 0x118D, BIDI_L }, // HANGUL JUNGSEONG U-U + { 0x118E, BIDI_L }, // HANGUL JUNGSEONG YU-A + { 0x118F, BIDI_L }, // HANGUL JUNGSEONG YU-EO + { 0x1190, BIDI_L }, // HANGUL JUNGSEONG YU-E + { 0x1191, BIDI_L }, // HANGUL JUNGSEONG YU-YEO + { 0x1192, BIDI_L }, // HANGUL JUNGSEONG YU-YE + { 0x1193, BIDI_L }, // HANGUL JUNGSEONG YU-U + { 0x1194, BIDI_L }, // HANGUL JUNGSEONG YU-I + { 0x1195, BIDI_L }, // HANGUL JUNGSEONG EU-U + { 0x1196, BIDI_L }, // HANGUL JUNGSEONG EU-EU + { 0x1197, BIDI_L }, // HANGUL JUNGSEONG YI-U + { 0x1198, BIDI_L }, // HANGUL JUNGSEONG I-A + { 0x1199, BIDI_L }, // HANGUL JUNGSEONG I-YA + { 0x119A, BIDI_L }, // HANGUL JUNGSEONG I-O + { 0x119B, BIDI_L }, // HANGUL JUNGSEONG I-U + { 0x119C, BIDI_L }, // HANGUL JUNGSEONG I-EU + { 0x119D, BIDI_L }, // HANGUL JUNGSEONG I-ARAEA + { 0x119E, BIDI_L }, // HANGUL JUNGSEONG ARAEA + { 0x119F, BIDI_L }, // HANGUL JUNGSEONG ARAEA-EO + { 0x11A0, BIDI_L }, // HANGUL JUNGSEONG ARAEA-U + { 0x11A1, BIDI_L }, // HANGUL JUNGSEONG ARAEA-I + { 0x11A2, BIDI_L }, // HANGUL JUNGSEONG SSANGARAEA + { 0x11A3, BIDI_L }, // HANGUL JUNGSEONG A-EU + { 0x11A4, BIDI_L }, // HANGUL JUNGSEONG YA-U + { 0x11A5, BIDI_L }, // HANGUL JUNGSEONG YEO-YA + { 0x11A6, BIDI_L }, // HANGUL JUNGSEONG O-YA + { 0x11A7, BIDI_L }, // HANGUL JUNGSEONG O-YAE + { 0x11A8, BIDI_L }, // HANGUL JONGSEONG KIYEOK + { 0x11A9, BIDI_L }, // HANGUL JONGSEONG SSANGKIYEOK + { 0x11AA, BIDI_L }, // HANGUL JONGSEONG KIYEOK-SIOS + { 0x11AB, BIDI_L }, // HANGUL JONGSEONG NIEUN + { 0x11AC, BIDI_L }, // HANGUL JONGSEONG NIEUN-CIEUC + { 0x11AD, BIDI_L }, // HANGUL JONGSEONG NIEUN-HIEUH + { 0x11AE, BIDI_L }, // HANGUL JONGSEONG TIKEUT + { 0x11AF, BIDI_L }, // HANGUL JONGSEONG RIEUL + { 0x11B0, BIDI_L }, // HANGUL JONGSEONG RIEUL-KIYEOK + { 0x11B1, BIDI_L }, // HANGUL JONGSEONG RIEUL-MIEUM + { 0x11B2, BIDI_L }, // HANGUL JONGSEONG RIEUL-PIEUP + { 0x11B3, BIDI_L }, // HANGUL JONGSEONG RIEUL-SIOS + { 0x11B4, BIDI_L }, // HANGUL JONGSEONG RIEUL-THIEUTH + { 0x11B5, BIDI_L }, // HANGUL JONGSEONG RIEUL-PHIEUPH + { 0x11B6, BIDI_L }, // HANGUL JONGSEONG RIEUL-HIEUH + { 0x11B7, BIDI_L }, // HANGUL JONGSEONG MIEUM + { 0x11B8, BIDI_L }, // HANGUL JONGSEONG PIEUP + { 0x11B9, BIDI_L }, // HANGUL JONGSEONG PIEUP-SIOS + { 0x11BA, BIDI_L }, // HANGUL JONGSEONG SIOS + { 0x11BB, BIDI_L }, // HANGUL JONGSEONG SSANGSIOS + { 0x11BC, BIDI_L }, // HANGUL JONGSEONG IEUNG + { 0x11BD, BIDI_L }, // HANGUL JONGSEONG CIEUC + { 0x11BE, BIDI_L }, // HANGUL JONGSEONG CHIEUCH + { 0x11BF, BIDI_L }, // HANGUL JONGSEONG KHIEUKH + { 0x11C0, BIDI_L }, // HANGUL JONGSEONG THIEUTH + { 0x11C1, BIDI_L }, // HANGUL JONGSEONG PHIEUPH + { 0x11C2, BIDI_L }, // HANGUL JONGSEONG HIEUH + { 0x11C3, BIDI_L }, // HANGUL JONGSEONG KIYEOK-RIEUL + { 0x11C4, BIDI_L }, // HANGUL JONGSEONG KIYEOK-SIOS-KIYEOK + { 0x11C5, BIDI_L }, // HANGUL JONGSEONG NIEUN-KIYEOK + { 0x11C6, BIDI_L }, // HANGUL JONGSEONG NIEUN-TIKEUT + { 0x11C7, BIDI_L }, // HANGUL JONGSEONG NIEUN-SIOS + { 0x11C8, BIDI_L }, // HANGUL JONGSEONG NIEUN-PANSIOS + { 0x11C9, BIDI_L }, // HANGUL JONGSEONG NIEUN-THIEUTH + { 0x11CA, BIDI_L }, // HANGUL JONGSEONG TIKEUT-KIYEOK + { 0x11CB, BIDI_L }, // HANGUL JONGSEONG TIKEUT-RIEUL + { 0x11CC, BIDI_L }, // HANGUL JONGSEONG RIEUL-KIYEOK-SIOS + { 0x11CD, BIDI_L }, // HANGUL JONGSEONG RIEUL-NIEUN + { 0x11CE, BIDI_L }, // HANGUL JONGSEONG RIEUL-TIKEUT + { 0x11CF, BIDI_L }, // HANGUL JONGSEONG RIEUL-TIKEUT-HIEUH + { 0x11D0, BIDI_L }, // HANGUL JONGSEONG SSANGRIEUL + { 0x11D1, BIDI_L }, // HANGUL JONGSEONG RIEUL-MIEUM-KIYEOK + { 0x11D2, BIDI_L }, // HANGUL JONGSEONG RIEUL-MIEUM-SIOS + { 0x11D3, BIDI_L }, // HANGUL JONGSEONG RIEUL-PIEUP-SIOS + { 0x11D4, BIDI_L }, // HANGUL JONGSEONG RIEUL-PIEUP-HIEUH + { 0x11D5, BIDI_L }, // HANGUL JONGSEONG RIEUL-KAPYEOUNPIEUP + { 0x11D6, BIDI_L }, // HANGUL JONGSEONG RIEUL-SSANGSIOS + { 0x11D7, BIDI_L }, // HANGUL JONGSEONG RIEUL-PANSIOS + { 0x11D8, BIDI_L }, // HANGUL JONGSEONG RIEUL-KHIEUKH + { 0x11D9, BIDI_L }, // HANGUL JONGSEONG RIEUL-YEORINHIEUH + { 0x11DA, BIDI_L }, // HANGUL JONGSEONG MIEUM-KIYEOK + { 0x11DB, BIDI_L }, // HANGUL JONGSEONG MIEUM-RIEUL + { 0x11DC, BIDI_L }, // HANGUL JONGSEONG MIEUM-PIEUP + { 0x11DD, BIDI_L }, // HANGUL JONGSEONG MIEUM-SIOS + { 0x11DE, BIDI_L }, // HANGUL JONGSEONG MIEUM-SSANGSIOS + { 0x11DF, BIDI_L }, // HANGUL JONGSEONG MIEUM-PANSIOS + { 0x11E0, BIDI_L }, // HANGUL JONGSEONG MIEUM-CHIEUCH + { 0x11E1, BIDI_L }, // HANGUL JONGSEONG MIEUM-HIEUH + { 0x11E2, BIDI_L }, // HANGUL JONGSEONG KAPYEOUNMIEUM + { 0x11E3, BIDI_L }, // HANGUL JONGSEONG PIEUP-RIEUL + { 0x11E4, BIDI_L }, // HANGUL JONGSEONG PIEUP-PHIEUPH + { 0x11E5, BIDI_L }, // HANGUL JONGSEONG PIEUP-HIEUH + { 0x11E6, BIDI_L }, // HANGUL JONGSEONG KAPYEOUNPIEUP + { 0x11E7, BIDI_L }, // HANGUL JONGSEONG SIOS-KIYEOK + { 0x11E8, BIDI_L }, // HANGUL JONGSEONG SIOS-TIKEUT + { 0x11E9, BIDI_L }, // HANGUL JONGSEONG SIOS-RIEUL + { 0x11EA, BIDI_L }, // HANGUL JONGSEONG SIOS-PIEUP + { 0x11EB, BIDI_L }, // HANGUL JONGSEONG PANSIOS + { 0x11EC, BIDI_L }, // HANGUL JONGSEONG IEUNG-KIYEOK + { 0x11ED, BIDI_L }, // HANGUL JONGSEONG IEUNG-SSANGKIYEOK + { 0x11EE, BIDI_L }, // HANGUL JONGSEONG SSANGIEUNG + { 0x11EF, BIDI_L }, // HANGUL JONGSEONG IEUNG-KHIEUKH + { 0x11F0, BIDI_L }, // HANGUL JONGSEONG YESIEUNG + { 0x11F1, BIDI_L }, // HANGUL JONGSEONG YESIEUNG-SIOS + { 0x11F2, BIDI_L }, // HANGUL JONGSEONG YESIEUNG-PANSIOS + { 0x11F3, BIDI_L }, // HANGUL JONGSEONG PHIEUPH-PIEUP + { 0x11F4, BIDI_L }, // HANGUL JONGSEONG KAPYEOUNPHIEUPH + { 0x11F5, BIDI_L }, // HANGUL JONGSEONG HIEUH-NIEUN + { 0x11F6, BIDI_L }, // HANGUL JONGSEONG HIEUH-RIEUL + { 0x11F7, BIDI_L }, // HANGUL JONGSEONG HIEUH-MIEUM + { 0x11F8, BIDI_L }, // HANGUL JONGSEONG HIEUH-PIEUP + { 0x11F9, BIDI_L }, // HANGUL JONGSEONG YEORINHIEUH + { 0x11FA, BIDI_L }, // HANGUL JONGSEONG KIYEOK-NIEUN + { 0x11FB, BIDI_L }, // HANGUL JONGSEONG KIYEOK-PIEUP + { 0x11FC, BIDI_L }, // HANGUL JONGSEONG KIYEOK-CHIEUCH + { 0x11FD, BIDI_L }, // HANGUL JONGSEONG KIYEOK-KHIEUKH + { 0x11FE, BIDI_L }, // HANGUL JONGSEONG KIYEOK-HIEUH + { 0x11FF, BIDI_L }, // HANGUL JONGSEONG SSANGNIEUN + { 0x1200, BIDI_L }, // ETHIOPIC SYLLABLE HA + { 0x1201, BIDI_L }, // ETHIOPIC SYLLABLE HU + { 0x1202, BIDI_L }, // ETHIOPIC SYLLABLE HI + { 0x1203, BIDI_L }, // ETHIOPIC SYLLABLE HAA + { 0x1204, BIDI_L }, // ETHIOPIC SYLLABLE HEE + { 0x1205, BIDI_L }, // ETHIOPIC SYLLABLE HE + { 0x1206, BIDI_L }, // ETHIOPIC SYLLABLE HO + { 0x1207, BIDI_L }, // ETHIOPIC SYLLABLE HOA + { 0x1208, BIDI_L }, // ETHIOPIC SYLLABLE LA + { 0x1209, BIDI_L }, // ETHIOPIC SYLLABLE LU + { 0x120A, BIDI_L }, // ETHIOPIC SYLLABLE LI + { 0x120B, BIDI_L }, // ETHIOPIC SYLLABLE LAA + { 0x120C, BIDI_L }, // ETHIOPIC SYLLABLE LEE + { 0x120D, BIDI_L }, // ETHIOPIC SYLLABLE LE + { 0x120E, BIDI_L }, // ETHIOPIC SYLLABLE LO + { 0x120F, BIDI_L }, // ETHIOPIC SYLLABLE LWA + { 0x1210, BIDI_L }, // ETHIOPIC SYLLABLE HHA + { 0x1211, BIDI_L }, // ETHIOPIC SYLLABLE HHU + { 0x1212, BIDI_L }, // ETHIOPIC SYLLABLE HHI + { 0x1213, BIDI_L }, // ETHIOPIC SYLLABLE HHAA + { 0x1214, BIDI_L }, // ETHIOPIC SYLLABLE HHEE + { 0x1215, BIDI_L }, // ETHIOPIC SYLLABLE HHE + { 0x1216, BIDI_L }, // ETHIOPIC SYLLABLE HHO + { 0x1217, BIDI_L }, // ETHIOPIC SYLLABLE HHWA + { 0x1218, BIDI_L }, // ETHIOPIC SYLLABLE MA + { 0x1219, BIDI_L }, // ETHIOPIC SYLLABLE MU + { 0x121A, BIDI_L }, // ETHIOPIC SYLLABLE MI + { 0x121B, BIDI_L }, // ETHIOPIC SYLLABLE MAA + { 0x121C, BIDI_L }, // ETHIOPIC SYLLABLE MEE + { 0x121D, BIDI_L }, // ETHIOPIC SYLLABLE ME + { 0x121E, BIDI_L }, // ETHIOPIC SYLLABLE MO + { 0x121F, BIDI_L }, // ETHIOPIC SYLLABLE MWA + { 0x1220, BIDI_L }, // ETHIOPIC SYLLABLE SZA + { 0x1221, BIDI_L }, // ETHIOPIC SYLLABLE SZU + { 0x1222, BIDI_L }, // ETHIOPIC SYLLABLE SZI + { 0x1223, BIDI_L }, // ETHIOPIC SYLLABLE SZAA + { 0x1224, BIDI_L }, // ETHIOPIC SYLLABLE SZEE + { 0x1225, BIDI_L }, // ETHIOPIC SYLLABLE SZE + { 0x1226, BIDI_L }, // ETHIOPIC SYLLABLE SZO + { 0x1227, BIDI_L }, // ETHIOPIC SYLLABLE SZWA + { 0x1228, BIDI_L }, // ETHIOPIC SYLLABLE RA + { 0x1229, BIDI_L }, // ETHIOPIC SYLLABLE RU + { 0x122A, BIDI_L }, // ETHIOPIC SYLLABLE RI + { 0x122B, BIDI_L }, // ETHIOPIC SYLLABLE RAA + { 0x122C, BIDI_L }, // ETHIOPIC SYLLABLE REE + { 0x122D, BIDI_L }, // ETHIOPIC SYLLABLE RE + { 0x122E, BIDI_L }, // ETHIOPIC SYLLABLE RO + { 0x122F, BIDI_L }, // ETHIOPIC SYLLABLE RWA + { 0x1230, BIDI_L }, // ETHIOPIC SYLLABLE SA + { 0x1231, BIDI_L }, // ETHIOPIC SYLLABLE SU + { 0x1232, BIDI_L }, // ETHIOPIC SYLLABLE SI + { 0x1233, BIDI_L }, // ETHIOPIC SYLLABLE SAA + { 0x1234, BIDI_L }, // ETHIOPIC SYLLABLE SEE + { 0x1235, BIDI_L }, // ETHIOPIC SYLLABLE SE + { 0x1236, BIDI_L }, // ETHIOPIC SYLLABLE SO + { 0x1237, BIDI_L }, // ETHIOPIC SYLLABLE SWA + { 0x1238, BIDI_L }, // ETHIOPIC SYLLABLE SHA + { 0x1239, BIDI_L }, // ETHIOPIC SYLLABLE SHU + { 0x123A, BIDI_L }, // ETHIOPIC SYLLABLE SHI + { 0x123B, BIDI_L }, // ETHIOPIC SYLLABLE SHAA + { 0x123C, BIDI_L }, // ETHIOPIC SYLLABLE SHEE + { 0x123D, BIDI_L }, // ETHIOPIC SYLLABLE SHE + { 0x123E, BIDI_L }, // ETHIOPIC SYLLABLE SHO + { 0x123F, BIDI_L }, // ETHIOPIC SYLLABLE SHWA + { 0x1240, BIDI_L }, // ETHIOPIC SYLLABLE QA + { 0x1241, BIDI_L }, // ETHIOPIC SYLLABLE QU + { 0x1242, BIDI_L }, // ETHIOPIC SYLLABLE QI + { 0x1243, BIDI_L }, // ETHIOPIC SYLLABLE QAA + { 0x1244, BIDI_L }, // ETHIOPIC SYLLABLE QEE + { 0x1245, BIDI_L }, // ETHIOPIC SYLLABLE QE + { 0x1246, BIDI_L }, // ETHIOPIC SYLLABLE QO + { 0x1247, BIDI_L }, // ETHIOPIC SYLLABLE QOA + { 0x1248, BIDI_L }, // ETHIOPIC SYLLABLE QWA + { 0x124A, BIDI_L }, // ETHIOPIC SYLLABLE QWI + { 0x124B, BIDI_L }, // ETHIOPIC SYLLABLE QWAA + { 0x124C, BIDI_L }, // ETHIOPIC SYLLABLE QWEE + { 0x124D, BIDI_L }, // ETHIOPIC SYLLABLE QWE + { 0x1250, BIDI_L }, // ETHIOPIC SYLLABLE QHA + { 0x1251, BIDI_L }, // ETHIOPIC SYLLABLE QHU + { 0x1252, BIDI_L }, // ETHIOPIC SYLLABLE QHI + { 0x1253, BIDI_L }, // ETHIOPIC SYLLABLE QHAA + { 0x1254, BIDI_L }, // ETHIOPIC SYLLABLE QHEE + { 0x1255, BIDI_L }, // ETHIOPIC SYLLABLE QHE + { 0x1256, BIDI_L }, // ETHIOPIC SYLLABLE QHO + { 0x1258, BIDI_L }, // ETHIOPIC SYLLABLE QHWA + { 0x125A, BIDI_L }, // ETHIOPIC SYLLABLE QHWI + { 0x125B, BIDI_L }, // ETHIOPIC SYLLABLE QHWAA + { 0x125C, BIDI_L }, // ETHIOPIC SYLLABLE QHWEE + { 0x125D, BIDI_L }, // ETHIOPIC SYLLABLE QHWE + { 0x1260, BIDI_L }, // ETHIOPIC SYLLABLE BA + { 0x1261, BIDI_L }, // ETHIOPIC SYLLABLE BU + { 0x1262, BIDI_L }, // ETHIOPIC SYLLABLE BI + { 0x1263, BIDI_L }, // ETHIOPIC SYLLABLE BAA + { 0x1264, BIDI_L }, // ETHIOPIC SYLLABLE BEE + { 0x1265, BIDI_L }, // ETHIOPIC SYLLABLE BE + { 0x1266, BIDI_L }, // ETHIOPIC SYLLABLE BO + { 0x1267, BIDI_L }, // ETHIOPIC SYLLABLE BWA + { 0x1268, BIDI_L }, // ETHIOPIC SYLLABLE VA + { 0x1269, BIDI_L }, // ETHIOPIC SYLLABLE VU + { 0x126A, BIDI_L }, // ETHIOPIC SYLLABLE VI + { 0x126B, BIDI_L }, // ETHIOPIC SYLLABLE VAA + { 0x126C, BIDI_L }, // ETHIOPIC SYLLABLE VEE + { 0x126D, BIDI_L }, // ETHIOPIC SYLLABLE VE + { 0x126E, BIDI_L }, // ETHIOPIC SYLLABLE VO + { 0x126F, BIDI_L }, // ETHIOPIC SYLLABLE VWA + { 0x1270, BIDI_L }, // ETHIOPIC SYLLABLE TA + { 0x1271, BIDI_L }, // ETHIOPIC SYLLABLE TU + { 0x1272, BIDI_L }, // ETHIOPIC SYLLABLE TI + { 0x1273, BIDI_L }, // ETHIOPIC SYLLABLE TAA + { 0x1274, BIDI_L }, // ETHIOPIC SYLLABLE TEE + { 0x1275, BIDI_L }, // ETHIOPIC SYLLABLE TE + { 0x1276, BIDI_L }, // ETHIOPIC SYLLABLE TO + { 0x1277, BIDI_L }, // ETHIOPIC SYLLABLE TWA + { 0x1278, BIDI_L }, // ETHIOPIC SYLLABLE CA + { 0x1279, BIDI_L }, // ETHIOPIC SYLLABLE CU + { 0x127A, BIDI_L }, // ETHIOPIC SYLLABLE CI + { 0x127B, BIDI_L }, // ETHIOPIC SYLLABLE CAA + { 0x127C, BIDI_L }, // ETHIOPIC SYLLABLE CEE + { 0x127D, BIDI_L }, // ETHIOPIC SYLLABLE CE + { 0x127E, BIDI_L }, // ETHIOPIC SYLLABLE CO + { 0x127F, BIDI_L }, // ETHIOPIC SYLLABLE CWA + { 0x1280, BIDI_L }, // ETHIOPIC SYLLABLE XA + { 0x1281, BIDI_L }, // ETHIOPIC SYLLABLE XU + { 0x1282, BIDI_L }, // ETHIOPIC SYLLABLE XI + { 0x1283, BIDI_L }, // ETHIOPIC SYLLABLE XAA + { 0x1284, BIDI_L }, // ETHIOPIC SYLLABLE XEE + { 0x1285, BIDI_L }, // ETHIOPIC SYLLABLE XE + { 0x1286, BIDI_L }, // ETHIOPIC SYLLABLE XO + { 0x1287, BIDI_L }, // ETHIOPIC SYLLABLE XOA + { 0x1288, BIDI_L }, // ETHIOPIC SYLLABLE XWA + { 0x128A, BIDI_L }, // ETHIOPIC SYLLABLE XWI + { 0x128B, BIDI_L }, // ETHIOPIC SYLLABLE XWAA + { 0x128C, BIDI_L }, // ETHIOPIC SYLLABLE XWEE + { 0x128D, BIDI_L }, // ETHIOPIC SYLLABLE XWE + { 0x1290, BIDI_L }, // ETHIOPIC SYLLABLE NA + { 0x1291, BIDI_L }, // ETHIOPIC SYLLABLE NU + { 0x1292, BIDI_L }, // ETHIOPIC SYLLABLE NI + { 0x1293, BIDI_L }, // ETHIOPIC SYLLABLE NAA + { 0x1294, BIDI_L }, // ETHIOPIC SYLLABLE NEE + { 0x1295, BIDI_L }, // ETHIOPIC SYLLABLE NE + { 0x1296, BIDI_L }, // ETHIOPIC SYLLABLE NO + { 0x1297, BIDI_L }, // ETHIOPIC SYLLABLE NWA + { 0x1298, BIDI_L }, // ETHIOPIC SYLLABLE NYA + { 0x1299, BIDI_L }, // ETHIOPIC SYLLABLE NYU + { 0x129A, BIDI_L }, // ETHIOPIC SYLLABLE NYI + { 0x129B, BIDI_L }, // ETHIOPIC SYLLABLE NYAA + { 0x129C, BIDI_L }, // ETHIOPIC SYLLABLE NYEE + { 0x129D, BIDI_L }, // ETHIOPIC SYLLABLE NYE + { 0x129E, BIDI_L }, // ETHIOPIC SYLLABLE NYO + { 0x129F, BIDI_L }, // ETHIOPIC SYLLABLE NYWA + { 0x12A0, BIDI_L }, // ETHIOPIC SYLLABLE GLOTTAL A + { 0x12A1, BIDI_L }, // ETHIOPIC SYLLABLE GLOTTAL U + { 0x12A2, BIDI_L }, // ETHIOPIC SYLLABLE GLOTTAL I + { 0x12A3, BIDI_L }, // ETHIOPIC SYLLABLE GLOTTAL AA + { 0x12A4, BIDI_L }, // ETHIOPIC SYLLABLE GLOTTAL EE + { 0x12A5, BIDI_L }, // ETHIOPIC SYLLABLE GLOTTAL E + { 0x12A6, BIDI_L }, // ETHIOPIC SYLLABLE GLOTTAL O + { 0x12A7, BIDI_L }, // ETHIOPIC SYLLABLE GLOTTAL WA + { 0x12A8, BIDI_L }, // ETHIOPIC SYLLABLE KA + { 0x12A9, BIDI_L }, // ETHIOPIC SYLLABLE KU + { 0x12AA, BIDI_L }, // ETHIOPIC SYLLABLE KI + { 0x12AB, BIDI_L }, // ETHIOPIC SYLLABLE KAA + { 0x12AC, BIDI_L }, // ETHIOPIC SYLLABLE KEE + { 0x12AD, BIDI_L }, // ETHIOPIC SYLLABLE KE + { 0x12AE, BIDI_L }, // ETHIOPIC SYLLABLE KO + { 0x12AF, BIDI_L }, // ETHIOPIC SYLLABLE KOA + { 0x12B0, BIDI_L }, // ETHIOPIC SYLLABLE KWA + { 0x12B2, BIDI_L }, // ETHIOPIC SYLLABLE KWI + { 0x12B3, BIDI_L }, // ETHIOPIC SYLLABLE KWAA + { 0x12B4, BIDI_L }, // ETHIOPIC SYLLABLE KWEE + { 0x12B5, BIDI_L }, // ETHIOPIC SYLLABLE KWE + { 0x12B8, BIDI_L }, // ETHIOPIC SYLLABLE KXA + { 0x12B9, BIDI_L }, // ETHIOPIC SYLLABLE KXU + { 0x12BA, BIDI_L }, // ETHIOPIC SYLLABLE KXI + { 0x12BB, BIDI_L }, // ETHIOPIC SYLLABLE KXAA + { 0x12BC, BIDI_L }, // ETHIOPIC SYLLABLE KXEE + { 0x12BD, BIDI_L }, // ETHIOPIC SYLLABLE KXE + { 0x12BE, BIDI_L }, // ETHIOPIC SYLLABLE KXO + { 0x12C0, BIDI_L }, // ETHIOPIC SYLLABLE KXWA + { 0x12C2, BIDI_L }, // ETHIOPIC SYLLABLE KXWI + { 0x12C3, BIDI_L }, // ETHIOPIC SYLLABLE KXWAA + { 0x12C4, BIDI_L }, // ETHIOPIC SYLLABLE KXWEE + { 0x12C5, BIDI_L }, // ETHIOPIC SYLLABLE KXWE + { 0x12C8, BIDI_L }, // ETHIOPIC SYLLABLE WA + { 0x12C9, BIDI_L }, // ETHIOPIC SYLLABLE WU + { 0x12CA, BIDI_L }, // ETHIOPIC SYLLABLE WI + { 0x12CB, BIDI_L }, // ETHIOPIC SYLLABLE WAA + { 0x12CC, BIDI_L }, // ETHIOPIC SYLLABLE WEE + { 0x12CD, BIDI_L }, // ETHIOPIC SYLLABLE WE + { 0x12CE, BIDI_L }, // ETHIOPIC SYLLABLE WO + { 0x12CF, BIDI_L }, // ETHIOPIC SYLLABLE WOA + { 0x12D0, BIDI_L }, // ETHIOPIC SYLLABLE PHARYNGEAL A + { 0x12D1, BIDI_L }, // ETHIOPIC SYLLABLE PHARYNGEAL U + { 0x12D2, BIDI_L }, // ETHIOPIC SYLLABLE PHARYNGEAL I + { 0x12D3, BIDI_L }, // ETHIOPIC SYLLABLE PHARYNGEAL AA + { 0x12D4, BIDI_L }, // ETHIOPIC SYLLABLE PHARYNGEAL EE + { 0x12D5, BIDI_L }, // ETHIOPIC SYLLABLE PHARYNGEAL E + { 0x12D6, BIDI_L }, // ETHIOPIC SYLLABLE PHARYNGEAL O + { 0x12D8, BIDI_L }, // ETHIOPIC SYLLABLE ZA + { 0x12D9, BIDI_L }, // ETHIOPIC SYLLABLE ZU + { 0x12DA, BIDI_L }, // ETHIOPIC SYLLABLE ZI + { 0x12DB, BIDI_L }, // ETHIOPIC SYLLABLE ZAA + { 0x12DC, BIDI_L }, // ETHIOPIC SYLLABLE ZEE + { 0x12DD, BIDI_L }, // ETHIOPIC SYLLABLE ZE + { 0x12DE, BIDI_L }, // ETHIOPIC SYLLABLE ZO + { 0x12DF, BIDI_L }, // ETHIOPIC SYLLABLE ZWA + { 0x12E0, BIDI_L }, // ETHIOPIC SYLLABLE ZHA + { 0x12E1, BIDI_L }, // ETHIOPIC SYLLABLE ZHU + { 0x12E2, BIDI_L }, // ETHIOPIC SYLLABLE ZHI + { 0x12E3, BIDI_L }, // ETHIOPIC SYLLABLE ZHAA + { 0x12E4, BIDI_L }, // ETHIOPIC SYLLABLE ZHEE + { 0x12E5, BIDI_L }, // ETHIOPIC SYLLABLE ZHE + { 0x12E6, BIDI_L }, // ETHIOPIC SYLLABLE ZHO + { 0x12E7, BIDI_L }, // ETHIOPIC SYLLABLE ZHWA + { 0x12E8, BIDI_L }, // ETHIOPIC SYLLABLE YA + { 0x12E9, BIDI_L }, // ETHIOPIC SYLLABLE YU + { 0x12EA, BIDI_L }, // ETHIOPIC SYLLABLE YI + { 0x12EB, BIDI_L }, // ETHIOPIC SYLLABLE YAA + { 0x12EC, BIDI_L }, // ETHIOPIC SYLLABLE YEE + { 0x12ED, BIDI_L }, // ETHIOPIC SYLLABLE YE + { 0x12EE, BIDI_L }, // ETHIOPIC SYLLABLE YO + { 0x12EF, BIDI_L }, // ETHIOPIC SYLLABLE YOA + { 0x12F0, BIDI_L }, // ETHIOPIC SYLLABLE DA + { 0x12F1, BIDI_L }, // ETHIOPIC SYLLABLE DU + { 0x12F2, BIDI_L }, // ETHIOPIC SYLLABLE DI + { 0x12F3, BIDI_L }, // ETHIOPIC SYLLABLE DAA + { 0x12F4, BIDI_L }, // ETHIOPIC SYLLABLE DEE + { 0x12F5, BIDI_L }, // ETHIOPIC SYLLABLE DE + { 0x12F6, BIDI_L }, // ETHIOPIC SYLLABLE DO + { 0x12F7, BIDI_L }, // ETHIOPIC SYLLABLE DWA + { 0x12F8, BIDI_L }, // ETHIOPIC SYLLABLE DDA + { 0x12F9, BIDI_L }, // ETHIOPIC SYLLABLE DDU + { 0x12FA, BIDI_L }, // ETHIOPIC SYLLABLE DDI + { 0x12FB, BIDI_L }, // ETHIOPIC SYLLABLE DDAA + { 0x12FC, BIDI_L }, // ETHIOPIC SYLLABLE DDEE + { 0x12FD, BIDI_L }, // ETHIOPIC SYLLABLE DDE + { 0x12FE, BIDI_L }, // ETHIOPIC SYLLABLE DDO + { 0x12FF, BIDI_L }, // ETHIOPIC SYLLABLE DDWA + { 0x1300, BIDI_L }, // ETHIOPIC SYLLABLE JA + { 0x1301, BIDI_L }, // ETHIOPIC SYLLABLE JU + { 0x1302, BIDI_L }, // ETHIOPIC SYLLABLE JI + { 0x1303, BIDI_L }, // ETHIOPIC SYLLABLE JAA + { 0x1304, BIDI_L }, // ETHIOPIC SYLLABLE JEE + { 0x1305, BIDI_L }, // ETHIOPIC SYLLABLE JE + { 0x1306, BIDI_L }, // ETHIOPIC SYLLABLE JO + { 0x1307, BIDI_L }, // ETHIOPIC SYLLABLE JWA + { 0x1308, BIDI_L }, // ETHIOPIC SYLLABLE GA + { 0x1309, BIDI_L }, // ETHIOPIC SYLLABLE GU + { 0x130A, BIDI_L }, // ETHIOPIC SYLLABLE GI + { 0x130B, BIDI_L }, // ETHIOPIC SYLLABLE GAA + { 0x130C, BIDI_L }, // ETHIOPIC SYLLABLE GEE + { 0x130D, BIDI_L }, // ETHIOPIC SYLLABLE GE + { 0x130E, BIDI_L }, // ETHIOPIC SYLLABLE GO + { 0x130F, BIDI_L }, // ETHIOPIC SYLLABLE GOA + { 0x1310, BIDI_L }, // ETHIOPIC SYLLABLE GWA + { 0x1312, BIDI_L }, // ETHIOPIC SYLLABLE GWI + { 0x1313, BIDI_L }, // ETHIOPIC SYLLABLE GWAA + { 0x1314, BIDI_L }, // ETHIOPIC SYLLABLE GWEE + { 0x1315, BIDI_L }, // ETHIOPIC SYLLABLE GWE + { 0x1318, BIDI_L }, // ETHIOPIC SYLLABLE GGA + { 0x1319, BIDI_L }, // ETHIOPIC SYLLABLE GGU + { 0x131A, BIDI_L }, // ETHIOPIC SYLLABLE GGI + { 0x131B, BIDI_L }, // ETHIOPIC SYLLABLE GGAA + { 0x131C, BIDI_L }, // ETHIOPIC SYLLABLE GGEE + { 0x131D, BIDI_L }, // ETHIOPIC SYLLABLE GGE + { 0x131E, BIDI_L }, // ETHIOPIC SYLLABLE GGO + { 0x131F, BIDI_L }, // ETHIOPIC SYLLABLE GGWAA + { 0x1320, BIDI_L }, // ETHIOPIC SYLLABLE THA + { 0x1321, BIDI_L }, // ETHIOPIC SYLLABLE THU + { 0x1322, BIDI_L }, // ETHIOPIC SYLLABLE THI + { 0x1323, BIDI_L }, // ETHIOPIC SYLLABLE THAA + { 0x1324, BIDI_L }, // ETHIOPIC SYLLABLE THEE + { 0x1325, BIDI_L }, // ETHIOPIC SYLLABLE THE + { 0x1326, BIDI_L }, // ETHIOPIC SYLLABLE THO + { 0x1327, BIDI_L }, // ETHIOPIC SYLLABLE THWA + { 0x1328, BIDI_L }, // ETHIOPIC SYLLABLE CHA + { 0x1329, BIDI_L }, // ETHIOPIC SYLLABLE CHU + { 0x132A, BIDI_L }, // ETHIOPIC SYLLABLE CHI + { 0x132B, BIDI_L }, // ETHIOPIC SYLLABLE CHAA + { 0x132C, BIDI_L }, // ETHIOPIC SYLLABLE CHEE + { 0x132D, BIDI_L }, // ETHIOPIC SYLLABLE CHE + { 0x132E, BIDI_L }, // ETHIOPIC SYLLABLE CHO + { 0x132F, BIDI_L }, // ETHIOPIC SYLLABLE CHWA + { 0x1330, BIDI_L }, // ETHIOPIC SYLLABLE PHA + { 0x1331, BIDI_L }, // ETHIOPIC SYLLABLE PHU + { 0x1332, BIDI_L }, // ETHIOPIC SYLLABLE PHI + { 0x1333, BIDI_L }, // ETHIOPIC SYLLABLE PHAA + { 0x1334, BIDI_L }, // ETHIOPIC SYLLABLE PHEE + { 0x1335, BIDI_L }, // ETHIOPIC SYLLABLE PHE + { 0x1336, BIDI_L }, // ETHIOPIC SYLLABLE PHO + { 0x1337, BIDI_L }, // ETHIOPIC SYLLABLE PHWA + { 0x1338, BIDI_L }, // ETHIOPIC SYLLABLE TSA + { 0x1339, BIDI_L }, // ETHIOPIC SYLLABLE TSU + { 0x133A, BIDI_L }, // ETHIOPIC SYLLABLE TSI + { 0x133B, BIDI_L }, // ETHIOPIC SYLLABLE TSAA + { 0x133C, BIDI_L }, // ETHIOPIC SYLLABLE TSEE + { 0x133D, BIDI_L }, // ETHIOPIC SYLLABLE TSE + { 0x133E, BIDI_L }, // ETHIOPIC SYLLABLE TSO + { 0x133F, BIDI_L }, // ETHIOPIC SYLLABLE TSWA + { 0x1340, BIDI_L }, // ETHIOPIC SYLLABLE TZA + { 0x1341, BIDI_L }, // ETHIOPIC SYLLABLE TZU + { 0x1342, BIDI_L }, // ETHIOPIC SYLLABLE TZI + { 0x1343, BIDI_L }, // ETHIOPIC SYLLABLE TZAA + { 0x1344, BIDI_L }, // ETHIOPIC SYLLABLE TZEE + { 0x1345, BIDI_L }, // ETHIOPIC SYLLABLE TZE + { 0x1346, BIDI_L }, // ETHIOPIC SYLLABLE TZO + { 0x1347, BIDI_L }, // ETHIOPIC SYLLABLE TZOA + { 0x1348, BIDI_L }, // ETHIOPIC SYLLABLE FA + { 0x1349, BIDI_L }, // ETHIOPIC SYLLABLE FU + { 0x134A, BIDI_L }, // ETHIOPIC SYLLABLE FI + { 0x134B, BIDI_L }, // ETHIOPIC SYLLABLE FAA + { 0x134C, BIDI_L }, // ETHIOPIC SYLLABLE FEE + { 0x134D, BIDI_L }, // ETHIOPIC SYLLABLE FE + { 0x134E, BIDI_L }, // ETHIOPIC SYLLABLE FO + { 0x134F, BIDI_L }, // ETHIOPIC SYLLABLE FWA + { 0x1350, BIDI_L }, // ETHIOPIC SYLLABLE PA + { 0x1351, BIDI_L }, // ETHIOPIC SYLLABLE PU + { 0x1352, BIDI_L }, // ETHIOPIC SYLLABLE PI + { 0x1353, BIDI_L }, // ETHIOPIC SYLLABLE PAA + { 0x1354, BIDI_L }, // ETHIOPIC SYLLABLE PEE + { 0x1355, BIDI_L }, // ETHIOPIC SYLLABLE PE + { 0x1356, BIDI_L }, // ETHIOPIC SYLLABLE PO + { 0x1357, BIDI_L }, // ETHIOPIC SYLLABLE PWA + { 0x1358, BIDI_L }, // ETHIOPIC SYLLABLE RYA + { 0x1359, BIDI_L }, // ETHIOPIC SYLLABLE MYA + { 0x135A, BIDI_L }, // ETHIOPIC SYLLABLE FYA + { 0x135D, BIDI_NSM }, // ETHIOPIC COMBINING GEMINATION AND VOWEL LENGTH MARK + { 0x135E, BIDI_NSM }, // ETHIOPIC COMBINING VOWEL LENGTH MARK + { 0x135F, BIDI_NSM }, // ETHIOPIC COMBINING GEMINATION MARK + { 0x1360, BIDI_L }, // ETHIOPIC SECTION MARK + { 0x1361, BIDI_L }, // ETHIOPIC WORDSPACE + { 0x1362, BIDI_L }, // ETHIOPIC FULL STOP + { 0x1363, BIDI_L }, // ETHIOPIC COMMA + { 0x1364, BIDI_L }, // ETHIOPIC SEMICOLON + { 0x1365, BIDI_L }, // ETHIOPIC COLON + { 0x1366, BIDI_L }, // ETHIOPIC PREFACE COLON + { 0x1367, BIDI_L }, // ETHIOPIC QUESTION MARK + { 0x1368, BIDI_L }, // ETHIOPIC PARAGRAPH SEPARATOR + { 0x1369, BIDI_L }, // ETHIOPIC DIGIT ONE + { 0x136A, BIDI_L }, // ETHIOPIC DIGIT TWO + { 0x136B, BIDI_L }, // ETHIOPIC DIGIT THREE + { 0x136C, BIDI_L }, // ETHIOPIC DIGIT FOUR + { 0x136D, BIDI_L }, // ETHIOPIC DIGIT FIVE + { 0x136E, BIDI_L }, // ETHIOPIC DIGIT SIX + { 0x136F, BIDI_L }, // ETHIOPIC DIGIT SEVEN + { 0x1370, BIDI_L }, // ETHIOPIC DIGIT EIGHT + { 0x1371, BIDI_L }, // ETHIOPIC DIGIT NINE + { 0x1372, BIDI_L }, // ETHIOPIC NUMBER TEN + { 0x1373, BIDI_L }, // ETHIOPIC NUMBER TWENTY + { 0x1374, BIDI_L }, // ETHIOPIC NUMBER THIRTY + { 0x1375, BIDI_L }, // ETHIOPIC NUMBER FORTY + { 0x1376, BIDI_L }, // ETHIOPIC NUMBER FIFTY + { 0x1377, BIDI_L }, // ETHIOPIC NUMBER SIXTY + { 0x1378, BIDI_L }, // ETHIOPIC NUMBER SEVENTY + { 0x1379, BIDI_L }, // ETHIOPIC NUMBER EIGHTY + { 0x137A, BIDI_L }, // ETHIOPIC NUMBER NINETY + { 0x137B, BIDI_L }, // ETHIOPIC NUMBER HUNDRED + { 0x137C, BIDI_L }, // ETHIOPIC NUMBER TEN THOUSAND + { 0x1380, BIDI_L }, // ETHIOPIC SYLLABLE SEBATBEIT MWA + { 0x1381, BIDI_L }, // ETHIOPIC SYLLABLE MWI + { 0x1382, BIDI_L }, // ETHIOPIC SYLLABLE MWEE + { 0x1383, BIDI_L }, // ETHIOPIC SYLLABLE MWE + { 0x1384, BIDI_L }, // ETHIOPIC SYLLABLE SEBATBEIT BWA + { 0x1385, BIDI_L }, // ETHIOPIC SYLLABLE BWI + { 0x1386, BIDI_L }, // ETHIOPIC SYLLABLE BWEE + { 0x1387, BIDI_L }, // ETHIOPIC SYLLABLE BWE + { 0x1388, BIDI_L }, // ETHIOPIC SYLLABLE SEBATBEIT FWA + { 0x1389, BIDI_L }, // ETHIOPIC SYLLABLE FWI + { 0x138A, BIDI_L }, // ETHIOPIC SYLLABLE FWEE + { 0x138B, BIDI_L }, // ETHIOPIC SYLLABLE FWE + { 0x138C, BIDI_L }, // ETHIOPIC SYLLABLE SEBATBEIT PWA + { 0x138D, BIDI_L }, // ETHIOPIC SYLLABLE PWI + { 0x138E, BIDI_L }, // ETHIOPIC SYLLABLE PWEE + { 0x138F, BIDI_L }, // ETHIOPIC SYLLABLE PWE + { 0x1390, BIDI_ON }, // ETHIOPIC TONAL MARK YIZET + { 0x1391, BIDI_ON }, // ETHIOPIC TONAL MARK DERET + { 0x1392, BIDI_ON }, // ETHIOPIC TONAL MARK RIKRIK + { 0x1393, BIDI_ON }, // ETHIOPIC TONAL MARK SHORT RIKRIK + { 0x1394, BIDI_ON }, // ETHIOPIC TONAL MARK DIFAT + { 0x1395, BIDI_ON }, // ETHIOPIC TONAL MARK KENAT + { 0x1396, BIDI_ON }, // ETHIOPIC TONAL MARK CHIRET + { 0x1397, BIDI_ON }, // ETHIOPIC TONAL MARK HIDET + { 0x1398, BIDI_ON }, // ETHIOPIC TONAL MARK DERET-HIDET + { 0x1399, BIDI_ON }, // ETHIOPIC TONAL MARK KURT + { 0x13A0, BIDI_L }, // CHEROKEE LETTER A + { 0x13A1, BIDI_L }, // CHEROKEE LETTER E + { 0x13A2, BIDI_L }, // CHEROKEE LETTER I + { 0x13A3, BIDI_L }, // CHEROKEE LETTER O + { 0x13A4, BIDI_L }, // CHEROKEE LETTER U + { 0x13A5, BIDI_L }, // CHEROKEE LETTER V + { 0x13A6, BIDI_L }, // CHEROKEE LETTER GA + { 0x13A7, BIDI_L }, // CHEROKEE LETTER KA + { 0x13A8, BIDI_L }, // CHEROKEE LETTER GE + { 0x13A9, BIDI_L }, // CHEROKEE LETTER GI + { 0x13AA, BIDI_L }, // CHEROKEE LETTER GO + { 0x13AB, BIDI_L }, // CHEROKEE LETTER GU + { 0x13AC, BIDI_L }, // CHEROKEE LETTER GV + { 0x13AD, BIDI_L }, // CHEROKEE LETTER HA + { 0x13AE, BIDI_L }, // CHEROKEE LETTER HE + { 0x13AF, BIDI_L }, // CHEROKEE LETTER HI + { 0x13B0, BIDI_L }, // CHEROKEE LETTER HO + { 0x13B1, BIDI_L }, // CHEROKEE LETTER HU + { 0x13B2, BIDI_L }, // CHEROKEE LETTER HV + { 0x13B3, BIDI_L }, // CHEROKEE LETTER LA + { 0x13B4, BIDI_L }, // CHEROKEE LETTER LE + { 0x13B5, BIDI_L }, // CHEROKEE LETTER LI + { 0x13B6, BIDI_L }, // CHEROKEE LETTER LO + { 0x13B7, BIDI_L }, // CHEROKEE LETTER LU + { 0x13B8, BIDI_L }, // CHEROKEE LETTER LV + { 0x13B9, BIDI_L }, // CHEROKEE LETTER MA + { 0x13BA, BIDI_L }, // CHEROKEE LETTER ME + { 0x13BB, BIDI_L }, // CHEROKEE LETTER MI + { 0x13BC, BIDI_L }, // CHEROKEE LETTER MO + { 0x13BD, BIDI_L }, // CHEROKEE LETTER MU + { 0x13BE, BIDI_L }, // CHEROKEE LETTER NA + { 0x13BF, BIDI_L }, // CHEROKEE LETTER HNA + { 0x13C0, BIDI_L }, // CHEROKEE LETTER NAH + { 0x13C1, BIDI_L }, // CHEROKEE LETTER NE + { 0x13C2, BIDI_L }, // CHEROKEE LETTER NI + { 0x13C3, BIDI_L }, // CHEROKEE LETTER NO + { 0x13C4, BIDI_L }, // CHEROKEE LETTER NU + { 0x13C5, BIDI_L }, // CHEROKEE LETTER NV + { 0x13C6, BIDI_L }, // CHEROKEE LETTER QUA + { 0x13C7, BIDI_L }, // CHEROKEE LETTER QUE + { 0x13C8, BIDI_L }, // CHEROKEE LETTER QUI + { 0x13C9, BIDI_L }, // CHEROKEE LETTER QUO + { 0x13CA, BIDI_L }, // CHEROKEE LETTER QUU + { 0x13CB, BIDI_L }, // CHEROKEE LETTER QUV + { 0x13CC, BIDI_L }, // CHEROKEE LETTER SA + { 0x13CD, BIDI_L }, // CHEROKEE LETTER S + { 0x13CE, BIDI_L }, // CHEROKEE LETTER SE + { 0x13CF, BIDI_L }, // CHEROKEE LETTER SI + { 0x13D0, BIDI_L }, // CHEROKEE LETTER SO + { 0x13D1, BIDI_L }, // CHEROKEE LETTER SU + { 0x13D2, BIDI_L }, // CHEROKEE LETTER SV + { 0x13D3, BIDI_L }, // CHEROKEE LETTER DA + { 0x13D4, BIDI_L }, // CHEROKEE LETTER TA + { 0x13D5, BIDI_L }, // CHEROKEE LETTER DE + { 0x13D6, BIDI_L }, // CHEROKEE LETTER TE + { 0x13D7, BIDI_L }, // CHEROKEE LETTER DI + { 0x13D8, BIDI_L }, // CHEROKEE LETTER TI + { 0x13D9, BIDI_L }, // CHEROKEE LETTER DO + { 0x13DA, BIDI_L }, // CHEROKEE LETTER DU + { 0x13DB, BIDI_L }, // CHEROKEE LETTER DV + { 0x13DC, BIDI_L }, // CHEROKEE LETTER DLA + { 0x13DD, BIDI_L }, // CHEROKEE LETTER TLA + { 0x13DE, BIDI_L }, // CHEROKEE LETTER TLE + { 0x13DF, BIDI_L }, // CHEROKEE LETTER TLI + { 0x13E0, BIDI_L }, // CHEROKEE LETTER TLO + { 0x13E1, BIDI_L }, // CHEROKEE LETTER TLU + { 0x13E2, BIDI_L }, // CHEROKEE LETTER TLV + { 0x13E3, BIDI_L }, // CHEROKEE LETTER TSA + { 0x13E4, BIDI_L }, // CHEROKEE LETTER TSE + { 0x13E5, BIDI_L }, // CHEROKEE LETTER TSI + { 0x13E6, BIDI_L }, // CHEROKEE LETTER TSO + { 0x13E7, BIDI_L }, // CHEROKEE LETTER TSU + { 0x13E8, BIDI_L }, // CHEROKEE LETTER TSV + { 0x13E9, BIDI_L }, // CHEROKEE LETTER WA + { 0x13EA, BIDI_L }, // CHEROKEE LETTER WE + { 0x13EB, BIDI_L }, // CHEROKEE LETTER WI + { 0x13EC, BIDI_L }, // CHEROKEE LETTER WO + { 0x13ED, BIDI_L }, // CHEROKEE LETTER WU + { 0x13EE, BIDI_L }, // CHEROKEE LETTER WV + { 0x13EF, BIDI_L }, // CHEROKEE LETTER YA + { 0x13F0, BIDI_L }, // CHEROKEE LETTER YE + { 0x13F1, BIDI_L }, // CHEROKEE LETTER YI + { 0x13F2, BIDI_L }, // CHEROKEE LETTER YO + { 0x13F3, BIDI_L }, // CHEROKEE LETTER YU + { 0x13F4, BIDI_L }, // CHEROKEE LETTER YV + { 0x13F5, BIDI_L }, // CHEROKEE LETTER MV + { 0x13F8, BIDI_L }, // CHEROKEE SMALL LETTER YE + { 0x13F9, BIDI_L }, // CHEROKEE SMALL LETTER YI + { 0x13FA, BIDI_L }, // CHEROKEE SMALL LETTER YO + { 0x13FB, BIDI_L }, // CHEROKEE SMALL LETTER YU + { 0x13FC, BIDI_L }, // CHEROKEE SMALL LETTER YV + { 0x13FD, BIDI_L }, // CHEROKEE SMALL LETTER MV + { 0x1400, BIDI_ON }, // CANADIAN SYLLABICS HYPHEN + { 0x1401, BIDI_L }, // CANADIAN SYLLABICS E + { 0x1402, BIDI_L }, // CANADIAN SYLLABICS AAI + { 0x1403, BIDI_L }, // CANADIAN SYLLABICS I + { 0x1404, BIDI_L }, // CANADIAN SYLLABICS II + { 0x1405, BIDI_L }, // CANADIAN SYLLABICS O + { 0x1406, BIDI_L }, // CANADIAN SYLLABICS OO + { 0x1407, BIDI_L }, // CANADIAN SYLLABICS Y-CREE OO + { 0x1408, BIDI_L }, // CANADIAN SYLLABICS CARRIER EE + { 0x1409, BIDI_L }, // CANADIAN SYLLABICS CARRIER I + { 0x140A, BIDI_L }, // CANADIAN SYLLABICS A + { 0x140B, BIDI_L }, // CANADIAN SYLLABICS AA + { 0x140C, BIDI_L }, // CANADIAN SYLLABICS WE + { 0x140D, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE WE + { 0x140E, BIDI_L }, // CANADIAN SYLLABICS WI + { 0x140F, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE WI + { 0x1410, BIDI_L }, // CANADIAN SYLLABICS WII + { 0x1411, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE WII + { 0x1412, BIDI_L }, // CANADIAN SYLLABICS WO + { 0x1413, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE WO + { 0x1414, BIDI_L }, // CANADIAN SYLLABICS WOO + { 0x1415, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE WOO + { 0x1416, BIDI_L }, // CANADIAN SYLLABICS NASKAPI WOO + { 0x1417, BIDI_L }, // CANADIAN SYLLABICS WA + { 0x1418, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE WA + { 0x1419, BIDI_L }, // CANADIAN SYLLABICS WAA + { 0x141A, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE WAA + { 0x141B, BIDI_L }, // CANADIAN SYLLABICS NASKAPI WAA + { 0x141C, BIDI_L }, // CANADIAN SYLLABICS AI + { 0x141D, BIDI_L }, // CANADIAN SYLLABICS Y-CREE W + { 0x141E, BIDI_L }, // CANADIAN SYLLABICS GLOTTAL STOP + { 0x141F, BIDI_L }, // CANADIAN SYLLABICS FINAL ACUTE + { 0x1420, BIDI_L }, // CANADIAN SYLLABICS FINAL GRAVE + { 0x1421, BIDI_L }, // CANADIAN SYLLABICS FINAL BOTTOM HALF RING + { 0x1422, BIDI_L }, // CANADIAN SYLLABICS FINAL TOP HALF RING + { 0x1423, BIDI_L }, // CANADIAN SYLLABICS FINAL RIGHT HALF RING + { 0x1424, BIDI_L }, // CANADIAN SYLLABICS FINAL RING + { 0x1425, BIDI_L }, // CANADIAN SYLLABICS FINAL DOUBLE ACUTE + { 0x1426, BIDI_L }, // CANADIAN SYLLABICS FINAL DOUBLE SHORT VERTICAL STROKES + { 0x1427, BIDI_L }, // CANADIAN SYLLABICS FINAL MIDDLE DOT + { 0x1428, BIDI_L }, // CANADIAN SYLLABICS FINAL SHORT HORIZONTAL STROKE + { 0x1429, BIDI_L }, // CANADIAN SYLLABICS FINAL PLUS + { 0x142A, BIDI_L }, // CANADIAN SYLLABICS FINAL DOWN TACK + { 0x142B, BIDI_L }, // CANADIAN SYLLABICS EN + { 0x142C, BIDI_L }, // CANADIAN SYLLABICS IN + { 0x142D, BIDI_L }, // CANADIAN SYLLABICS ON + { 0x142E, BIDI_L }, // CANADIAN SYLLABICS AN + { 0x142F, BIDI_L }, // CANADIAN SYLLABICS PE + { 0x1430, BIDI_L }, // CANADIAN SYLLABICS PAAI + { 0x1431, BIDI_L }, // CANADIAN SYLLABICS PI + { 0x1432, BIDI_L }, // CANADIAN SYLLABICS PII + { 0x1433, BIDI_L }, // CANADIAN SYLLABICS PO + { 0x1434, BIDI_L }, // CANADIAN SYLLABICS POO + { 0x1435, BIDI_L }, // CANADIAN SYLLABICS Y-CREE POO + { 0x1436, BIDI_L }, // CANADIAN SYLLABICS CARRIER HEE + { 0x1437, BIDI_L }, // CANADIAN SYLLABICS CARRIER HI + { 0x1438, BIDI_L }, // CANADIAN SYLLABICS PA + { 0x1439, BIDI_L }, // CANADIAN SYLLABICS PAA + { 0x143A, BIDI_L }, // CANADIAN SYLLABICS PWE + { 0x143B, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE PWE + { 0x143C, BIDI_L }, // CANADIAN SYLLABICS PWI + { 0x143D, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE PWI + { 0x143E, BIDI_L }, // CANADIAN SYLLABICS PWII + { 0x143F, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE PWII + { 0x1440, BIDI_L }, // CANADIAN SYLLABICS PWO + { 0x1441, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE PWO + { 0x1442, BIDI_L }, // CANADIAN SYLLABICS PWOO + { 0x1443, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE PWOO + { 0x1444, BIDI_L }, // CANADIAN SYLLABICS PWA + { 0x1445, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE PWA + { 0x1446, BIDI_L }, // CANADIAN SYLLABICS PWAA + { 0x1447, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE PWAA + { 0x1448, BIDI_L }, // CANADIAN SYLLABICS Y-CREE PWAA + { 0x1449, BIDI_L }, // CANADIAN SYLLABICS P + { 0x144A, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE P + { 0x144B, BIDI_L }, // CANADIAN SYLLABICS CARRIER H + { 0x144C, BIDI_L }, // CANADIAN SYLLABICS TE + { 0x144D, BIDI_L }, // CANADIAN SYLLABICS TAAI + { 0x144E, BIDI_L }, // CANADIAN SYLLABICS TI + { 0x144F, BIDI_L }, // CANADIAN SYLLABICS TII + { 0x1450, BIDI_L }, // CANADIAN SYLLABICS TO + { 0x1451, BIDI_L }, // CANADIAN SYLLABICS TOO + { 0x1452, BIDI_L }, // CANADIAN SYLLABICS Y-CREE TOO + { 0x1453, BIDI_L }, // CANADIAN SYLLABICS CARRIER DEE + { 0x1454, BIDI_L }, // CANADIAN SYLLABICS CARRIER DI + { 0x1455, BIDI_L }, // CANADIAN SYLLABICS TA + { 0x1456, BIDI_L }, // CANADIAN SYLLABICS TAA + { 0x1457, BIDI_L }, // CANADIAN SYLLABICS TWE + { 0x1458, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE TWE + { 0x1459, BIDI_L }, // CANADIAN SYLLABICS TWI + { 0x145A, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE TWI + { 0x145B, BIDI_L }, // CANADIAN SYLLABICS TWII + { 0x145C, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE TWII + { 0x145D, BIDI_L }, // CANADIAN SYLLABICS TWO + { 0x145E, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE TWO + { 0x145F, BIDI_L }, // CANADIAN SYLLABICS TWOO + { 0x1460, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE TWOO + { 0x1461, BIDI_L }, // CANADIAN SYLLABICS TWA + { 0x1462, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE TWA + { 0x1463, BIDI_L }, // CANADIAN SYLLABICS TWAA + { 0x1464, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE TWAA + { 0x1465, BIDI_L }, // CANADIAN SYLLABICS NASKAPI TWAA + { 0x1466, BIDI_L }, // CANADIAN SYLLABICS T + { 0x1467, BIDI_L }, // CANADIAN SYLLABICS TTE + { 0x1468, BIDI_L }, // CANADIAN SYLLABICS TTI + { 0x1469, BIDI_L }, // CANADIAN SYLLABICS TTO + { 0x146A, BIDI_L }, // CANADIAN SYLLABICS TTA + { 0x146B, BIDI_L }, // CANADIAN SYLLABICS KE + { 0x146C, BIDI_L }, // CANADIAN SYLLABICS KAAI + { 0x146D, BIDI_L }, // CANADIAN SYLLABICS KI + { 0x146E, BIDI_L }, // CANADIAN SYLLABICS KII + { 0x146F, BIDI_L }, // CANADIAN SYLLABICS KO + { 0x1470, BIDI_L }, // CANADIAN SYLLABICS KOO + { 0x1471, BIDI_L }, // CANADIAN SYLLABICS Y-CREE KOO + { 0x1472, BIDI_L }, // CANADIAN SYLLABICS KA + { 0x1473, BIDI_L }, // CANADIAN SYLLABICS KAA + { 0x1474, BIDI_L }, // CANADIAN SYLLABICS KWE + { 0x1475, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE KWE + { 0x1476, BIDI_L }, // CANADIAN SYLLABICS KWI + { 0x1477, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE KWI + { 0x1478, BIDI_L }, // CANADIAN SYLLABICS KWII + { 0x1479, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE KWII + { 0x147A, BIDI_L }, // CANADIAN SYLLABICS KWO + { 0x147B, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE KWO + { 0x147C, BIDI_L }, // CANADIAN SYLLABICS KWOO + { 0x147D, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE KWOO + { 0x147E, BIDI_L }, // CANADIAN SYLLABICS KWA + { 0x147F, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE KWA + { 0x1480, BIDI_L }, // CANADIAN SYLLABICS KWAA + { 0x1481, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE KWAA + { 0x1482, BIDI_L }, // CANADIAN SYLLABICS NASKAPI KWAA + { 0x1483, BIDI_L }, // CANADIAN SYLLABICS K + { 0x1484, BIDI_L }, // CANADIAN SYLLABICS KW + { 0x1485, BIDI_L }, // CANADIAN SYLLABICS SOUTH-SLAVEY KEH + { 0x1486, BIDI_L }, // CANADIAN SYLLABICS SOUTH-SLAVEY KIH + { 0x1487, BIDI_L }, // CANADIAN SYLLABICS SOUTH-SLAVEY KOH + { 0x1488, BIDI_L }, // CANADIAN SYLLABICS SOUTH-SLAVEY KAH + { 0x1489, BIDI_L }, // CANADIAN SYLLABICS CE + { 0x148A, BIDI_L }, // CANADIAN SYLLABICS CAAI + { 0x148B, BIDI_L }, // CANADIAN SYLLABICS CI + { 0x148C, BIDI_L }, // CANADIAN SYLLABICS CII + { 0x148D, BIDI_L }, // CANADIAN SYLLABICS CO + { 0x148E, BIDI_L }, // CANADIAN SYLLABICS COO + { 0x148F, BIDI_L }, // CANADIAN SYLLABICS Y-CREE COO + { 0x1490, BIDI_L }, // CANADIAN SYLLABICS CA + { 0x1491, BIDI_L }, // CANADIAN SYLLABICS CAA + { 0x1492, BIDI_L }, // CANADIAN SYLLABICS CWE + { 0x1493, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE CWE + { 0x1494, BIDI_L }, // CANADIAN SYLLABICS CWI + { 0x1495, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE CWI + { 0x1496, BIDI_L }, // CANADIAN SYLLABICS CWII + { 0x1497, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE CWII + { 0x1498, BIDI_L }, // CANADIAN SYLLABICS CWO + { 0x1499, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE CWO + { 0x149A, BIDI_L }, // CANADIAN SYLLABICS CWOO + { 0x149B, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE CWOO + { 0x149C, BIDI_L }, // CANADIAN SYLLABICS CWA + { 0x149D, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE CWA + { 0x149E, BIDI_L }, // CANADIAN SYLLABICS CWAA + { 0x149F, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE CWAA + { 0x14A0, BIDI_L }, // CANADIAN SYLLABICS NASKAPI CWAA + { 0x14A1, BIDI_L }, // CANADIAN SYLLABICS C + { 0x14A2, BIDI_L }, // CANADIAN SYLLABICS SAYISI TH + { 0x14A3, BIDI_L }, // CANADIAN SYLLABICS ME + { 0x14A4, BIDI_L }, // CANADIAN SYLLABICS MAAI + { 0x14A5, BIDI_L }, // CANADIAN SYLLABICS MI + { 0x14A6, BIDI_L }, // CANADIAN SYLLABICS MII + { 0x14A7, BIDI_L }, // CANADIAN SYLLABICS MO + { 0x14A8, BIDI_L }, // CANADIAN SYLLABICS MOO + { 0x14A9, BIDI_L }, // CANADIAN SYLLABICS Y-CREE MOO + { 0x14AA, BIDI_L }, // CANADIAN SYLLABICS MA + { 0x14AB, BIDI_L }, // CANADIAN SYLLABICS MAA + { 0x14AC, BIDI_L }, // CANADIAN SYLLABICS MWE + { 0x14AD, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE MWE + { 0x14AE, BIDI_L }, // CANADIAN SYLLABICS MWI + { 0x14AF, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE MWI + { 0x14B0, BIDI_L }, // CANADIAN SYLLABICS MWII + { 0x14B1, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE MWII + { 0x14B2, BIDI_L }, // CANADIAN SYLLABICS MWO + { 0x14B3, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE MWO + { 0x14B4, BIDI_L }, // CANADIAN SYLLABICS MWOO + { 0x14B5, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE MWOO + { 0x14B6, BIDI_L }, // CANADIAN SYLLABICS MWA + { 0x14B7, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE MWA + { 0x14B8, BIDI_L }, // CANADIAN SYLLABICS MWAA + { 0x14B9, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE MWAA + { 0x14BA, BIDI_L }, // CANADIAN SYLLABICS NASKAPI MWAA + { 0x14BB, BIDI_L }, // CANADIAN SYLLABICS M + { 0x14BC, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE M + { 0x14BD, BIDI_L }, // CANADIAN SYLLABICS MH + { 0x14BE, BIDI_L }, // CANADIAN SYLLABICS ATHAPASCAN M + { 0x14BF, BIDI_L }, // CANADIAN SYLLABICS SAYISI M + { 0x14C0, BIDI_L }, // CANADIAN SYLLABICS NE + { 0x14C1, BIDI_L }, // CANADIAN SYLLABICS NAAI + { 0x14C2, BIDI_L }, // CANADIAN SYLLABICS NI + { 0x14C3, BIDI_L }, // CANADIAN SYLLABICS NII + { 0x14C4, BIDI_L }, // CANADIAN SYLLABICS NO + { 0x14C5, BIDI_L }, // CANADIAN SYLLABICS NOO + { 0x14C6, BIDI_L }, // CANADIAN SYLLABICS Y-CREE NOO + { 0x14C7, BIDI_L }, // CANADIAN SYLLABICS NA + { 0x14C8, BIDI_L }, // CANADIAN SYLLABICS NAA + { 0x14C9, BIDI_L }, // CANADIAN SYLLABICS NWE + { 0x14CA, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE NWE + { 0x14CB, BIDI_L }, // CANADIAN SYLLABICS NWA + { 0x14CC, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE NWA + { 0x14CD, BIDI_L }, // CANADIAN SYLLABICS NWAA + { 0x14CE, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE NWAA + { 0x14CF, BIDI_L }, // CANADIAN SYLLABICS NASKAPI NWAA + { 0x14D0, BIDI_L }, // CANADIAN SYLLABICS N + { 0x14D1, BIDI_L }, // CANADIAN SYLLABICS CARRIER NG + { 0x14D2, BIDI_L }, // CANADIAN SYLLABICS NH + { 0x14D3, BIDI_L }, // CANADIAN SYLLABICS LE + { 0x14D4, BIDI_L }, // CANADIAN SYLLABICS LAAI + { 0x14D5, BIDI_L }, // CANADIAN SYLLABICS LI + { 0x14D6, BIDI_L }, // CANADIAN SYLLABICS LII + { 0x14D7, BIDI_L }, // CANADIAN SYLLABICS LO + { 0x14D8, BIDI_L }, // CANADIAN SYLLABICS LOO + { 0x14D9, BIDI_L }, // CANADIAN SYLLABICS Y-CREE LOO + { 0x14DA, BIDI_L }, // CANADIAN SYLLABICS LA + { 0x14DB, BIDI_L }, // CANADIAN SYLLABICS LAA + { 0x14DC, BIDI_L }, // CANADIAN SYLLABICS LWE + { 0x14DD, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE LWE + { 0x14DE, BIDI_L }, // CANADIAN SYLLABICS LWI + { 0x14DF, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE LWI + { 0x14E0, BIDI_L }, // CANADIAN SYLLABICS LWII + { 0x14E1, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE LWII + { 0x14E2, BIDI_L }, // CANADIAN SYLLABICS LWO + { 0x14E3, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE LWO + { 0x14E4, BIDI_L }, // CANADIAN SYLLABICS LWOO + { 0x14E5, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE LWOO + { 0x14E6, BIDI_L }, // CANADIAN SYLLABICS LWA + { 0x14E7, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE LWA + { 0x14E8, BIDI_L }, // CANADIAN SYLLABICS LWAA + { 0x14E9, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE LWAA + { 0x14EA, BIDI_L }, // CANADIAN SYLLABICS L + { 0x14EB, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE L + { 0x14EC, BIDI_L }, // CANADIAN SYLLABICS MEDIAL L + { 0x14ED, BIDI_L }, // CANADIAN SYLLABICS SE + { 0x14EE, BIDI_L }, // CANADIAN SYLLABICS SAAI + { 0x14EF, BIDI_L }, // CANADIAN SYLLABICS SI + { 0x14F0, BIDI_L }, // CANADIAN SYLLABICS SII + { 0x14F1, BIDI_L }, // CANADIAN SYLLABICS SO + { 0x14F2, BIDI_L }, // CANADIAN SYLLABICS SOO + { 0x14F3, BIDI_L }, // CANADIAN SYLLABICS Y-CREE SOO + { 0x14F4, BIDI_L }, // CANADIAN SYLLABICS SA + { 0x14F5, BIDI_L }, // CANADIAN SYLLABICS SAA + { 0x14F6, BIDI_L }, // CANADIAN SYLLABICS SWE + { 0x14F7, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE SWE + { 0x14F8, BIDI_L }, // CANADIAN SYLLABICS SWI + { 0x14F9, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE SWI + { 0x14FA, BIDI_L }, // CANADIAN SYLLABICS SWII + { 0x14FB, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE SWII + { 0x14FC, BIDI_L }, // CANADIAN SYLLABICS SWO + { 0x14FD, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE SWO + { 0x14FE, BIDI_L }, // CANADIAN SYLLABICS SWOO + { 0x14FF, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE SWOO + { 0x1500, BIDI_L }, // CANADIAN SYLLABICS SWA + { 0x1501, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE SWA + { 0x1502, BIDI_L }, // CANADIAN SYLLABICS SWAA + { 0x1503, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE SWAA + { 0x1504, BIDI_L }, // CANADIAN SYLLABICS NASKAPI SWAA + { 0x1505, BIDI_L }, // CANADIAN SYLLABICS S + { 0x1506, BIDI_L }, // CANADIAN SYLLABICS ATHAPASCAN S + { 0x1507, BIDI_L }, // CANADIAN SYLLABICS SW + { 0x1508, BIDI_L }, // CANADIAN SYLLABICS BLACKFOOT S + { 0x1509, BIDI_L }, // CANADIAN SYLLABICS MOOSE-CREE SK + { 0x150A, BIDI_L }, // CANADIAN SYLLABICS NASKAPI SKW + { 0x150B, BIDI_L }, // CANADIAN SYLLABICS NASKAPI S-W + { 0x150C, BIDI_L }, // CANADIAN SYLLABICS NASKAPI SPWA + { 0x150D, BIDI_L }, // CANADIAN SYLLABICS NASKAPI STWA + { 0x150E, BIDI_L }, // CANADIAN SYLLABICS NASKAPI SKWA + { 0x150F, BIDI_L }, // CANADIAN SYLLABICS NASKAPI SCWA + { 0x1510, BIDI_L }, // CANADIAN SYLLABICS SHE + { 0x1511, BIDI_L }, // CANADIAN SYLLABICS SHI + { 0x1512, BIDI_L }, // CANADIAN SYLLABICS SHII + { 0x1513, BIDI_L }, // CANADIAN SYLLABICS SHO + { 0x1514, BIDI_L }, // CANADIAN SYLLABICS SHOO + { 0x1515, BIDI_L }, // CANADIAN SYLLABICS SHA + { 0x1516, BIDI_L }, // CANADIAN SYLLABICS SHAA + { 0x1517, BIDI_L }, // CANADIAN SYLLABICS SHWE + { 0x1518, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE SHWE + { 0x1519, BIDI_L }, // CANADIAN SYLLABICS SHWI + { 0x151A, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE SHWI + { 0x151B, BIDI_L }, // CANADIAN SYLLABICS SHWII + { 0x151C, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE SHWII + { 0x151D, BIDI_L }, // CANADIAN SYLLABICS SHWO + { 0x151E, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE SHWO + { 0x151F, BIDI_L }, // CANADIAN SYLLABICS SHWOO + { 0x1520, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE SHWOO + { 0x1521, BIDI_L }, // CANADIAN SYLLABICS SHWA + { 0x1522, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE SHWA + { 0x1523, BIDI_L }, // CANADIAN SYLLABICS SHWAA + { 0x1524, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE SHWAA + { 0x1525, BIDI_L }, // CANADIAN SYLLABICS SH + { 0x1526, BIDI_L }, // CANADIAN SYLLABICS YE + { 0x1527, BIDI_L }, // CANADIAN SYLLABICS YAAI + { 0x1528, BIDI_L }, // CANADIAN SYLLABICS YI + { 0x1529, BIDI_L }, // CANADIAN SYLLABICS YII + { 0x152A, BIDI_L }, // CANADIAN SYLLABICS YO + { 0x152B, BIDI_L }, // CANADIAN SYLLABICS YOO + { 0x152C, BIDI_L }, // CANADIAN SYLLABICS Y-CREE YOO + { 0x152D, BIDI_L }, // CANADIAN SYLLABICS YA + { 0x152E, BIDI_L }, // CANADIAN SYLLABICS YAA + { 0x152F, BIDI_L }, // CANADIAN SYLLABICS YWE + { 0x1530, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE YWE + { 0x1531, BIDI_L }, // CANADIAN SYLLABICS YWI + { 0x1532, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE YWI + { 0x1533, BIDI_L }, // CANADIAN SYLLABICS YWII + { 0x1534, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE YWII + { 0x1535, BIDI_L }, // CANADIAN SYLLABICS YWO + { 0x1536, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE YWO + { 0x1537, BIDI_L }, // CANADIAN SYLLABICS YWOO + { 0x1538, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE YWOO + { 0x1539, BIDI_L }, // CANADIAN SYLLABICS YWA + { 0x153A, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE YWA + { 0x153B, BIDI_L }, // CANADIAN SYLLABICS YWAA + { 0x153C, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE YWAA + { 0x153D, BIDI_L }, // CANADIAN SYLLABICS NASKAPI YWAA + { 0x153E, BIDI_L }, // CANADIAN SYLLABICS Y + { 0x153F, BIDI_L }, // CANADIAN SYLLABICS BIBLE-CREE Y + { 0x1540, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE Y + { 0x1541, BIDI_L }, // CANADIAN SYLLABICS SAYISI YI + { 0x1542, BIDI_L }, // CANADIAN SYLLABICS RE + { 0x1543, BIDI_L }, // CANADIAN SYLLABICS R-CREE RE + { 0x1544, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE LE + { 0x1545, BIDI_L }, // CANADIAN SYLLABICS RAAI + { 0x1546, BIDI_L }, // CANADIAN SYLLABICS RI + { 0x1547, BIDI_L }, // CANADIAN SYLLABICS RII + { 0x1548, BIDI_L }, // CANADIAN SYLLABICS RO + { 0x1549, BIDI_L }, // CANADIAN SYLLABICS ROO + { 0x154A, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE LO + { 0x154B, BIDI_L }, // CANADIAN SYLLABICS RA + { 0x154C, BIDI_L }, // CANADIAN SYLLABICS RAA + { 0x154D, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE LA + { 0x154E, BIDI_L }, // CANADIAN SYLLABICS RWAA + { 0x154F, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE RWAA + { 0x1550, BIDI_L }, // CANADIAN SYLLABICS R + { 0x1551, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE R + { 0x1552, BIDI_L }, // CANADIAN SYLLABICS MEDIAL R + { 0x1553, BIDI_L }, // CANADIAN SYLLABICS FE + { 0x1554, BIDI_L }, // CANADIAN SYLLABICS FAAI + { 0x1555, BIDI_L }, // CANADIAN SYLLABICS FI + { 0x1556, BIDI_L }, // CANADIAN SYLLABICS FII + { 0x1557, BIDI_L }, // CANADIAN SYLLABICS FO + { 0x1558, BIDI_L }, // CANADIAN SYLLABICS FOO + { 0x1559, BIDI_L }, // CANADIAN SYLLABICS FA + { 0x155A, BIDI_L }, // CANADIAN SYLLABICS FAA + { 0x155B, BIDI_L }, // CANADIAN SYLLABICS FWAA + { 0x155C, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE FWAA + { 0x155D, BIDI_L }, // CANADIAN SYLLABICS F + { 0x155E, BIDI_L }, // CANADIAN SYLLABICS THE + { 0x155F, BIDI_L }, // CANADIAN SYLLABICS N-CREE THE + { 0x1560, BIDI_L }, // CANADIAN SYLLABICS THI + { 0x1561, BIDI_L }, // CANADIAN SYLLABICS N-CREE THI + { 0x1562, BIDI_L }, // CANADIAN SYLLABICS THII + { 0x1563, BIDI_L }, // CANADIAN SYLLABICS N-CREE THII + { 0x1564, BIDI_L }, // CANADIAN SYLLABICS THO + { 0x1565, BIDI_L }, // CANADIAN SYLLABICS THOO + { 0x1566, BIDI_L }, // CANADIAN SYLLABICS THA + { 0x1567, BIDI_L }, // CANADIAN SYLLABICS THAA + { 0x1568, BIDI_L }, // CANADIAN SYLLABICS THWAA + { 0x1569, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE THWAA + { 0x156A, BIDI_L }, // CANADIAN SYLLABICS TH + { 0x156B, BIDI_L }, // CANADIAN SYLLABICS TTHE + { 0x156C, BIDI_L }, // CANADIAN SYLLABICS TTHI + { 0x156D, BIDI_L }, // CANADIAN SYLLABICS TTHO + { 0x156E, BIDI_L }, // CANADIAN SYLLABICS TTHA + { 0x156F, BIDI_L }, // CANADIAN SYLLABICS TTH + { 0x1570, BIDI_L }, // CANADIAN SYLLABICS TYE + { 0x1571, BIDI_L }, // CANADIAN SYLLABICS TYI + { 0x1572, BIDI_L }, // CANADIAN SYLLABICS TYO + { 0x1573, BIDI_L }, // CANADIAN SYLLABICS TYA + { 0x1574, BIDI_L }, // CANADIAN SYLLABICS NUNAVIK HE + { 0x1575, BIDI_L }, // CANADIAN SYLLABICS NUNAVIK HI + { 0x1576, BIDI_L }, // CANADIAN SYLLABICS NUNAVIK HII + { 0x1577, BIDI_L }, // CANADIAN SYLLABICS NUNAVIK HO + { 0x1578, BIDI_L }, // CANADIAN SYLLABICS NUNAVIK HOO + { 0x1579, BIDI_L }, // CANADIAN SYLLABICS NUNAVIK HA + { 0x157A, BIDI_L }, // CANADIAN SYLLABICS NUNAVIK HAA + { 0x157B, BIDI_L }, // CANADIAN SYLLABICS NUNAVIK H + { 0x157C, BIDI_L }, // CANADIAN SYLLABICS NUNAVUT H + { 0x157D, BIDI_L }, // CANADIAN SYLLABICS HK + { 0x157E, BIDI_L }, // CANADIAN SYLLABICS QAAI + { 0x157F, BIDI_L }, // CANADIAN SYLLABICS QI + { 0x1580, BIDI_L }, // CANADIAN SYLLABICS QII + { 0x1581, BIDI_L }, // CANADIAN SYLLABICS QO + { 0x1582, BIDI_L }, // CANADIAN SYLLABICS QOO + { 0x1583, BIDI_L }, // CANADIAN SYLLABICS QA + { 0x1584, BIDI_L }, // CANADIAN SYLLABICS QAA + { 0x1585, BIDI_L }, // CANADIAN SYLLABICS Q + { 0x1586, BIDI_L }, // CANADIAN SYLLABICS TLHE + { 0x1587, BIDI_L }, // CANADIAN SYLLABICS TLHI + { 0x1588, BIDI_L }, // CANADIAN SYLLABICS TLHO + { 0x1589, BIDI_L }, // CANADIAN SYLLABICS TLHA + { 0x158A, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE RE + { 0x158B, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE RI + { 0x158C, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE RO + { 0x158D, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE RA + { 0x158E, BIDI_L }, // CANADIAN SYLLABICS NGAAI + { 0x158F, BIDI_L }, // CANADIAN SYLLABICS NGI + { 0x1590, BIDI_L }, // CANADIAN SYLLABICS NGII + { 0x1591, BIDI_L }, // CANADIAN SYLLABICS NGO + { 0x1592, BIDI_L }, // CANADIAN SYLLABICS NGOO + { 0x1593, BIDI_L }, // CANADIAN SYLLABICS NGA + { 0x1594, BIDI_L }, // CANADIAN SYLLABICS NGAA + { 0x1595, BIDI_L }, // CANADIAN SYLLABICS NG + { 0x1596, BIDI_L }, // CANADIAN SYLLABICS NNG + { 0x1597, BIDI_L }, // CANADIAN SYLLABICS SAYISI SHE + { 0x1598, BIDI_L }, // CANADIAN SYLLABICS SAYISI SHI + { 0x1599, BIDI_L }, // CANADIAN SYLLABICS SAYISI SHO + { 0x159A, BIDI_L }, // CANADIAN SYLLABICS SAYISI SHA + { 0x159B, BIDI_L }, // CANADIAN SYLLABICS WOODS-CREE THE + { 0x159C, BIDI_L }, // CANADIAN SYLLABICS WOODS-CREE THI + { 0x159D, BIDI_L }, // CANADIAN SYLLABICS WOODS-CREE THO + { 0x159E, BIDI_L }, // CANADIAN SYLLABICS WOODS-CREE THA + { 0x159F, BIDI_L }, // CANADIAN SYLLABICS WOODS-CREE TH + { 0x15A0, BIDI_L }, // CANADIAN SYLLABICS LHI + { 0x15A1, BIDI_L }, // CANADIAN SYLLABICS LHII + { 0x15A2, BIDI_L }, // CANADIAN SYLLABICS LHO + { 0x15A3, BIDI_L }, // CANADIAN SYLLABICS LHOO + { 0x15A4, BIDI_L }, // CANADIAN SYLLABICS LHA + { 0x15A5, BIDI_L }, // CANADIAN SYLLABICS LHAA + { 0x15A6, BIDI_L }, // CANADIAN SYLLABICS LH + { 0x15A7, BIDI_L }, // CANADIAN SYLLABICS TH-CREE THE + { 0x15A8, BIDI_L }, // CANADIAN SYLLABICS TH-CREE THI + { 0x15A9, BIDI_L }, // CANADIAN SYLLABICS TH-CREE THII + { 0x15AA, BIDI_L }, // CANADIAN SYLLABICS TH-CREE THO + { 0x15AB, BIDI_L }, // CANADIAN SYLLABICS TH-CREE THOO + { 0x15AC, BIDI_L }, // CANADIAN SYLLABICS TH-CREE THA + { 0x15AD, BIDI_L }, // CANADIAN SYLLABICS TH-CREE THAA + { 0x15AE, BIDI_L }, // CANADIAN SYLLABICS TH-CREE TH + { 0x15AF, BIDI_L }, // CANADIAN SYLLABICS AIVILIK B + { 0x15B0, BIDI_L }, // CANADIAN SYLLABICS BLACKFOOT E + { 0x15B1, BIDI_L }, // CANADIAN SYLLABICS BLACKFOOT I + { 0x15B2, BIDI_L }, // CANADIAN SYLLABICS BLACKFOOT O + { 0x15B3, BIDI_L }, // CANADIAN SYLLABICS BLACKFOOT A + { 0x15B4, BIDI_L }, // CANADIAN SYLLABICS BLACKFOOT WE + { 0x15B5, BIDI_L }, // CANADIAN SYLLABICS BLACKFOOT WI + { 0x15B6, BIDI_L }, // CANADIAN SYLLABICS BLACKFOOT WO + { 0x15B7, BIDI_L }, // CANADIAN SYLLABICS BLACKFOOT WA + { 0x15B8, BIDI_L }, // CANADIAN SYLLABICS BLACKFOOT NE + { 0x15B9, BIDI_L }, // CANADIAN SYLLABICS BLACKFOOT NI + { 0x15BA, BIDI_L }, // CANADIAN SYLLABICS BLACKFOOT NO + { 0x15BB, BIDI_L }, // CANADIAN SYLLABICS BLACKFOOT NA + { 0x15BC, BIDI_L }, // CANADIAN SYLLABICS BLACKFOOT KE + { 0x15BD, BIDI_L }, // CANADIAN SYLLABICS BLACKFOOT KI + { 0x15BE, BIDI_L }, // CANADIAN SYLLABICS BLACKFOOT KO + { 0x15BF, BIDI_L }, // CANADIAN SYLLABICS BLACKFOOT KA + { 0x15C0, BIDI_L }, // CANADIAN SYLLABICS SAYISI HE + { 0x15C1, BIDI_L }, // CANADIAN SYLLABICS SAYISI HI + { 0x15C2, BIDI_L }, // CANADIAN SYLLABICS SAYISI HO + { 0x15C3, BIDI_L }, // CANADIAN SYLLABICS SAYISI HA + { 0x15C4, BIDI_L }, // CANADIAN SYLLABICS CARRIER GHU + { 0x15C5, BIDI_L }, // CANADIAN SYLLABICS CARRIER GHO + { 0x15C6, BIDI_L }, // CANADIAN SYLLABICS CARRIER GHE + { 0x15C7, BIDI_L }, // CANADIAN SYLLABICS CARRIER GHEE + { 0x15C8, BIDI_L }, // CANADIAN SYLLABICS CARRIER GHI + { 0x15C9, BIDI_L }, // CANADIAN SYLLABICS CARRIER GHA + { 0x15CA, BIDI_L }, // CANADIAN SYLLABICS CARRIER RU + { 0x15CB, BIDI_L }, // CANADIAN SYLLABICS CARRIER RO + { 0x15CC, BIDI_L }, // CANADIAN SYLLABICS CARRIER RE + { 0x15CD, BIDI_L }, // CANADIAN SYLLABICS CARRIER REE + { 0x15CE, BIDI_L }, // CANADIAN SYLLABICS CARRIER RI + { 0x15CF, BIDI_L }, // CANADIAN SYLLABICS CARRIER RA + { 0x15D0, BIDI_L }, // CANADIAN SYLLABICS CARRIER WU + { 0x15D1, BIDI_L }, // CANADIAN SYLLABICS CARRIER WO + { 0x15D2, BIDI_L }, // CANADIAN SYLLABICS CARRIER WE + { 0x15D3, BIDI_L }, // CANADIAN SYLLABICS CARRIER WEE + { 0x15D4, BIDI_L }, // CANADIAN SYLLABICS CARRIER WI + { 0x15D5, BIDI_L }, // CANADIAN SYLLABICS CARRIER WA + { 0x15D6, BIDI_L }, // CANADIAN SYLLABICS CARRIER HWU + { 0x15D7, BIDI_L }, // CANADIAN SYLLABICS CARRIER HWO + { 0x15D8, BIDI_L }, // CANADIAN SYLLABICS CARRIER HWE + { 0x15D9, BIDI_L }, // CANADIAN SYLLABICS CARRIER HWEE + { 0x15DA, BIDI_L }, // CANADIAN SYLLABICS CARRIER HWI + { 0x15DB, BIDI_L }, // CANADIAN SYLLABICS CARRIER HWA + { 0x15DC, BIDI_L }, // CANADIAN SYLLABICS CARRIER THU + { 0x15DD, BIDI_L }, // CANADIAN SYLLABICS CARRIER THO + { 0x15DE, BIDI_L }, // CANADIAN SYLLABICS CARRIER THE + { 0x15DF, BIDI_L }, // CANADIAN SYLLABICS CARRIER THEE + { 0x15E0, BIDI_L }, // CANADIAN SYLLABICS CARRIER THI + { 0x15E1, BIDI_L }, // CANADIAN SYLLABICS CARRIER THA + { 0x15E2, BIDI_L }, // CANADIAN SYLLABICS CARRIER TTU + { 0x15E3, BIDI_L }, // CANADIAN SYLLABICS CARRIER TTO + { 0x15E4, BIDI_L }, // CANADIAN SYLLABICS CARRIER TTE + { 0x15E5, BIDI_L }, // CANADIAN SYLLABICS CARRIER TTEE + { 0x15E6, BIDI_L }, // CANADIAN SYLLABICS CARRIER TTI + { 0x15E7, BIDI_L }, // CANADIAN SYLLABICS CARRIER TTA + { 0x15E8, BIDI_L }, // CANADIAN SYLLABICS CARRIER PU + { 0x15E9, BIDI_L }, // CANADIAN SYLLABICS CARRIER PO + { 0x15EA, BIDI_L }, // CANADIAN SYLLABICS CARRIER PE + { 0x15EB, BIDI_L }, // CANADIAN SYLLABICS CARRIER PEE + { 0x15EC, BIDI_L }, // CANADIAN SYLLABICS CARRIER PI + { 0x15ED, BIDI_L }, // CANADIAN SYLLABICS CARRIER PA + { 0x15EE, BIDI_L }, // CANADIAN SYLLABICS CARRIER P + { 0x15EF, BIDI_L }, // CANADIAN SYLLABICS CARRIER GU + { 0x15F0, BIDI_L }, // CANADIAN SYLLABICS CARRIER GO + { 0x15F1, BIDI_L }, // CANADIAN SYLLABICS CARRIER GE + { 0x15F2, BIDI_L }, // CANADIAN SYLLABICS CARRIER GEE + { 0x15F3, BIDI_L }, // CANADIAN SYLLABICS CARRIER GI + { 0x15F4, BIDI_L }, // CANADIAN SYLLABICS CARRIER GA + { 0x15F5, BIDI_L }, // CANADIAN SYLLABICS CARRIER KHU + { 0x15F6, BIDI_L }, // CANADIAN SYLLABICS CARRIER KHO + { 0x15F7, BIDI_L }, // CANADIAN SYLLABICS CARRIER KHE + { 0x15F8, BIDI_L }, // CANADIAN SYLLABICS CARRIER KHEE + { 0x15F9, BIDI_L }, // CANADIAN SYLLABICS CARRIER KHI + { 0x15FA, BIDI_L }, // CANADIAN SYLLABICS CARRIER KHA + { 0x15FB, BIDI_L }, // CANADIAN SYLLABICS CARRIER KKU + { 0x15FC, BIDI_L }, // CANADIAN SYLLABICS CARRIER KKO + { 0x15FD, BIDI_L }, // CANADIAN SYLLABICS CARRIER KKE + { 0x15FE, BIDI_L }, // CANADIAN SYLLABICS CARRIER KKEE + { 0x15FF, BIDI_L }, // CANADIAN SYLLABICS CARRIER KKI + { 0x1600, BIDI_L }, // CANADIAN SYLLABICS CARRIER KKA + { 0x1601, BIDI_L }, // CANADIAN SYLLABICS CARRIER KK + { 0x1602, BIDI_L }, // CANADIAN SYLLABICS CARRIER NU + { 0x1603, BIDI_L }, // CANADIAN SYLLABICS CARRIER NO + { 0x1604, BIDI_L }, // CANADIAN SYLLABICS CARRIER NE + { 0x1605, BIDI_L }, // CANADIAN SYLLABICS CARRIER NEE + { 0x1606, BIDI_L }, // CANADIAN SYLLABICS CARRIER NI + { 0x1607, BIDI_L }, // CANADIAN SYLLABICS CARRIER NA + { 0x1608, BIDI_L }, // CANADIAN SYLLABICS CARRIER MU + { 0x1609, BIDI_L }, // CANADIAN SYLLABICS CARRIER MO + { 0x160A, BIDI_L }, // CANADIAN SYLLABICS CARRIER ME + { 0x160B, BIDI_L }, // CANADIAN SYLLABICS CARRIER MEE + { 0x160C, BIDI_L }, // CANADIAN SYLLABICS CARRIER MI + { 0x160D, BIDI_L }, // CANADIAN SYLLABICS CARRIER MA + { 0x160E, BIDI_L }, // CANADIAN SYLLABICS CARRIER YU + { 0x160F, BIDI_L }, // CANADIAN SYLLABICS CARRIER YO + { 0x1610, BIDI_L }, // CANADIAN SYLLABICS CARRIER YE + { 0x1611, BIDI_L }, // CANADIAN SYLLABICS CARRIER YEE + { 0x1612, BIDI_L }, // CANADIAN SYLLABICS CARRIER YI + { 0x1613, BIDI_L }, // CANADIAN SYLLABICS CARRIER YA + { 0x1614, BIDI_L }, // CANADIAN SYLLABICS CARRIER JU + { 0x1615, BIDI_L }, // CANADIAN SYLLABICS SAYISI JU + { 0x1616, BIDI_L }, // CANADIAN SYLLABICS CARRIER JO + { 0x1617, BIDI_L }, // CANADIAN SYLLABICS CARRIER JE + { 0x1618, BIDI_L }, // CANADIAN SYLLABICS CARRIER JEE + { 0x1619, BIDI_L }, // CANADIAN SYLLABICS CARRIER JI + { 0x161A, BIDI_L }, // CANADIAN SYLLABICS SAYISI JI + { 0x161B, BIDI_L }, // CANADIAN SYLLABICS CARRIER JA + { 0x161C, BIDI_L }, // CANADIAN SYLLABICS CARRIER JJU + { 0x161D, BIDI_L }, // CANADIAN SYLLABICS CARRIER JJO + { 0x161E, BIDI_L }, // CANADIAN SYLLABICS CARRIER JJE + { 0x161F, BIDI_L }, // CANADIAN SYLLABICS CARRIER JJEE + { 0x1620, BIDI_L }, // CANADIAN SYLLABICS CARRIER JJI + { 0x1621, BIDI_L }, // CANADIAN SYLLABICS CARRIER JJA + { 0x1622, BIDI_L }, // CANADIAN SYLLABICS CARRIER LU + { 0x1623, BIDI_L }, // CANADIAN SYLLABICS CARRIER LO + { 0x1624, BIDI_L }, // CANADIAN SYLLABICS CARRIER LE + { 0x1625, BIDI_L }, // CANADIAN SYLLABICS CARRIER LEE + { 0x1626, BIDI_L }, // CANADIAN SYLLABICS CARRIER LI + { 0x1627, BIDI_L }, // CANADIAN SYLLABICS CARRIER LA + { 0x1628, BIDI_L }, // CANADIAN SYLLABICS CARRIER DLU + { 0x1629, BIDI_L }, // CANADIAN SYLLABICS CARRIER DLO + { 0x162A, BIDI_L }, // CANADIAN SYLLABICS CARRIER DLE + { 0x162B, BIDI_L }, // CANADIAN SYLLABICS CARRIER DLEE + { 0x162C, BIDI_L }, // CANADIAN SYLLABICS CARRIER DLI + { 0x162D, BIDI_L }, // CANADIAN SYLLABICS CARRIER DLA + { 0x162E, BIDI_L }, // CANADIAN SYLLABICS CARRIER LHU + { 0x162F, BIDI_L }, // CANADIAN SYLLABICS CARRIER LHO + { 0x1630, BIDI_L }, // CANADIAN SYLLABICS CARRIER LHE + { 0x1631, BIDI_L }, // CANADIAN SYLLABICS CARRIER LHEE + { 0x1632, BIDI_L }, // CANADIAN SYLLABICS CARRIER LHI + { 0x1633, BIDI_L }, // CANADIAN SYLLABICS CARRIER LHA + { 0x1634, BIDI_L }, // CANADIAN SYLLABICS CARRIER TLHU + { 0x1635, BIDI_L }, // CANADIAN SYLLABICS CARRIER TLHO + { 0x1636, BIDI_L }, // CANADIAN SYLLABICS CARRIER TLHE + { 0x1637, BIDI_L }, // CANADIAN SYLLABICS CARRIER TLHEE + { 0x1638, BIDI_L }, // CANADIAN SYLLABICS CARRIER TLHI + { 0x1639, BIDI_L }, // CANADIAN SYLLABICS CARRIER TLHA + { 0x163A, BIDI_L }, // CANADIAN SYLLABICS CARRIER TLU + { 0x163B, BIDI_L }, // CANADIAN SYLLABICS CARRIER TLO + { 0x163C, BIDI_L }, // CANADIAN SYLLABICS CARRIER TLE + { 0x163D, BIDI_L }, // CANADIAN SYLLABICS CARRIER TLEE + { 0x163E, BIDI_L }, // CANADIAN SYLLABICS CARRIER TLI + { 0x163F, BIDI_L }, // CANADIAN SYLLABICS CARRIER TLA + { 0x1640, BIDI_L }, // CANADIAN SYLLABICS CARRIER ZU + { 0x1641, BIDI_L }, // CANADIAN SYLLABICS CARRIER ZO + { 0x1642, BIDI_L }, // CANADIAN SYLLABICS CARRIER ZE + { 0x1643, BIDI_L }, // CANADIAN SYLLABICS CARRIER ZEE + { 0x1644, BIDI_L }, // CANADIAN SYLLABICS CARRIER ZI + { 0x1645, BIDI_L }, // CANADIAN SYLLABICS CARRIER ZA + { 0x1646, BIDI_L }, // CANADIAN SYLLABICS CARRIER Z + { 0x1647, BIDI_L }, // CANADIAN SYLLABICS CARRIER INITIAL Z + { 0x1648, BIDI_L }, // CANADIAN SYLLABICS CARRIER DZU + { 0x1649, BIDI_L }, // CANADIAN SYLLABICS CARRIER DZO + { 0x164A, BIDI_L }, // CANADIAN SYLLABICS CARRIER DZE + { 0x164B, BIDI_L }, // CANADIAN SYLLABICS CARRIER DZEE + { 0x164C, BIDI_L }, // CANADIAN SYLLABICS CARRIER DZI + { 0x164D, BIDI_L }, // CANADIAN SYLLABICS CARRIER DZA + { 0x164E, BIDI_L }, // CANADIAN SYLLABICS CARRIER SU + { 0x164F, BIDI_L }, // CANADIAN SYLLABICS CARRIER SO + { 0x1650, BIDI_L }, // CANADIAN SYLLABICS CARRIER SE + { 0x1651, BIDI_L }, // CANADIAN SYLLABICS CARRIER SEE + { 0x1652, BIDI_L }, // CANADIAN SYLLABICS CARRIER SI + { 0x1653, BIDI_L }, // CANADIAN SYLLABICS CARRIER SA + { 0x1654, BIDI_L }, // CANADIAN SYLLABICS CARRIER SHU + { 0x1655, BIDI_L }, // CANADIAN SYLLABICS CARRIER SHO + { 0x1656, BIDI_L }, // CANADIAN SYLLABICS CARRIER SHE + { 0x1657, BIDI_L }, // CANADIAN SYLLABICS CARRIER SHEE + { 0x1658, BIDI_L }, // CANADIAN SYLLABICS CARRIER SHI + { 0x1659, BIDI_L }, // CANADIAN SYLLABICS CARRIER SHA + { 0x165A, BIDI_L }, // CANADIAN SYLLABICS CARRIER SH + { 0x165B, BIDI_L }, // CANADIAN SYLLABICS CARRIER TSU + { 0x165C, BIDI_L }, // CANADIAN SYLLABICS CARRIER TSO + { 0x165D, BIDI_L }, // CANADIAN SYLLABICS CARRIER TSE + { 0x165E, BIDI_L }, // CANADIAN SYLLABICS CARRIER TSEE + { 0x165F, BIDI_L }, // CANADIAN SYLLABICS CARRIER TSI + { 0x1660, BIDI_L }, // CANADIAN SYLLABICS CARRIER TSA + { 0x1661, BIDI_L }, // CANADIAN SYLLABICS CARRIER CHU + { 0x1662, BIDI_L }, // CANADIAN SYLLABICS CARRIER CHO + { 0x1663, BIDI_L }, // CANADIAN SYLLABICS CARRIER CHE + { 0x1664, BIDI_L }, // CANADIAN SYLLABICS CARRIER CHEE + { 0x1665, BIDI_L }, // CANADIAN SYLLABICS CARRIER CHI + { 0x1666, BIDI_L }, // CANADIAN SYLLABICS CARRIER CHA + { 0x1667, BIDI_L }, // CANADIAN SYLLABICS CARRIER TTSU + { 0x1668, BIDI_L }, // CANADIAN SYLLABICS CARRIER TTSO + { 0x1669, BIDI_L }, // CANADIAN SYLLABICS CARRIER TTSE + { 0x166A, BIDI_L }, // CANADIAN SYLLABICS CARRIER TTSEE + { 0x166B, BIDI_L }, // CANADIAN SYLLABICS CARRIER TTSI + { 0x166C, BIDI_L }, // CANADIAN SYLLABICS CARRIER TTSA + { 0x166D, BIDI_L }, // CANADIAN SYLLABICS CHI SIGN + { 0x166E, BIDI_L }, // CANADIAN SYLLABICS FULL STOP + { 0x166F, BIDI_L }, // CANADIAN SYLLABICS QAI + { 0x1670, BIDI_L }, // CANADIAN SYLLABICS NGAI + { 0x1671, BIDI_L }, // CANADIAN SYLLABICS NNGI + { 0x1672, BIDI_L }, // CANADIAN SYLLABICS NNGII + { 0x1673, BIDI_L }, // CANADIAN SYLLABICS NNGO + { 0x1674, BIDI_L }, // CANADIAN SYLLABICS NNGOO + { 0x1675, BIDI_L }, // CANADIAN SYLLABICS NNGA + { 0x1676, BIDI_L }, // CANADIAN SYLLABICS NNGAA + { 0x1677, BIDI_L }, // CANADIAN SYLLABICS WOODS-CREE THWEE + { 0x1678, BIDI_L }, // CANADIAN SYLLABICS WOODS-CREE THWI + { 0x1679, BIDI_L }, // CANADIAN SYLLABICS WOODS-CREE THWII + { 0x167A, BIDI_L }, // CANADIAN SYLLABICS WOODS-CREE THWO + { 0x167B, BIDI_L }, // CANADIAN SYLLABICS WOODS-CREE THWOO + { 0x167C, BIDI_L }, // CANADIAN SYLLABICS WOODS-CREE THWA + { 0x167D, BIDI_L }, // CANADIAN SYLLABICS WOODS-CREE THWAA + { 0x167E, BIDI_L }, // CANADIAN SYLLABICS WOODS-CREE FINAL TH + { 0x167F, BIDI_L }, // CANADIAN SYLLABICS BLACKFOOT W + { 0x1680, BIDI_WS }, // OGHAM SPACE MARK + { 0x1681, BIDI_L }, // OGHAM LETTER BEITH + { 0x1682, BIDI_L }, // OGHAM LETTER LUIS + { 0x1683, BIDI_L }, // OGHAM LETTER FEARN + { 0x1684, BIDI_L }, // OGHAM LETTER SAIL + { 0x1685, BIDI_L }, // OGHAM LETTER NION + { 0x1686, BIDI_L }, // OGHAM LETTER UATH + { 0x1687, BIDI_L }, // OGHAM LETTER DAIR + { 0x1688, BIDI_L }, // OGHAM LETTER TINNE + { 0x1689, BIDI_L }, // OGHAM LETTER COLL + { 0x168A, BIDI_L }, // OGHAM LETTER CEIRT + { 0x168B, BIDI_L }, // OGHAM LETTER MUIN + { 0x168C, BIDI_L }, // OGHAM LETTER GORT + { 0x168D, BIDI_L }, // OGHAM LETTER NGEADAL + { 0x168E, BIDI_L }, // OGHAM LETTER STRAIF + { 0x168F, BIDI_L }, // OGHAM LETTER RUIS + { 0x1690, BIDI_L }, // OGHAM LETTER AILM + { 0x1691, BIDI_L }, // OGHAM LETTER ONN + { 0x1692, BIDI_L }, // OGHAM LETTER UR + { 0x1693, BIDI_L }, // OGHAM LETTER EADHADH + { 0x1694, BIDI_L }, // OGHAM LETTER IODHADH + { 0x1695, BIDI_L }, // OGHAM LETTER EABHADH + { 0x1696, BIDI_L }, // OGHAM LETTER OR + { 0x1697, BIDI_L }, // OGHAM LETTER UILLEANN + { 0x1698, BIDI_L }, // OGHAM LETTER IFIN + { 0x1699, BIDI_L }, // OGHAM LETTER EAMHANCHOLL + { 0x169A, BIDI_L }, // OGHAM LETTER PEITH + { 0x169B, BIDI_ON }, // OGHAM FEATHER MARK + { 0x169C, BIDI_ON }, // OGHAM REVERSED FEATHER MARK + { 0x16A0, BIDI_L }, // RUNIC LETTER FEHU FEOH FE F + { 0x16A1, BIDI_L }, // RUNIC LETTER V + { 0x16A2, BIDI_L }, // RUNIC LETTER URUZ UR U + { 0x16A3, BIDI_L }, // RUNIC LETTER YR + { 0x16A4, BIDI_L }, // RUNIC LETTER Y + { 0x16A5, BIDI_L }, // RUNIC LETTER W + { 0x16A6, BIDI_L }, // RUNIC LETTER THURISAZ THURS THORN + { 0x16A7, BIDI_L }, // RUNIC LETTER ETH + { 0x16A8, BIDI_L }, // RUNIC LETTER ANSUZ A + { 0x16A9, BIDI_L }, // RUNIC LETTER OS O + { 0x16AA, BIDI_L }, // RUNIC LETTER AC A + { 0x16AB, BIDI_L }, // RUNIC LETTER AESC + { 0x16AC, BIDI_L }, // RUNIC LETTER LONG-BRANCH-OSS O + { 0x16AD, BIDI_L }, // RUNIC LETTER SHORT-TWIG-OSS O + { 0x16AE, BIDI_L }, // RUNIC LETTER O + { 0x16AF, BIDI_L }, // RUNIC LETTER OE + { 0x16B0, BIDI_L }, // RUNIC LETTER ON + { 0x16B1, BIDI_L }, // RUNIC LETTER RAIDO RAD REID R + { 0x16B2, BIDI_L }, // RUNIC LETTER KAUNA + { 0x16B3, BIDI_L }, // RUNIC LETTER CEN + { 0x16B4, BIDI_L }, // RUNIC LETTER KAUN K + { 0x16B5, BIDI_L }, // RUNIC LETTER G + { 0x16B6, BIDI_L }, // RUNIC LETTER ENG + { 0x16B7, BIDI_L }, // RUNIC LETTER GEBO GYFU G + { 0x16B8, BIDI_L }, // RUNIC LETTER GAR + { 0x16B9, BIDI_L }, // RUNIC LETTER WUNJO WYNN W + { 0x16BA, BIDI_L }, // RUNIC LETTER HAGLAZ H + { 0x16BB, BIDI_L }, // RUNIC LETTER HAEGL H + { 0x16BC, BIDI_L }, // RUNIC LETTER LONG-BRANCH-HAGALL H + { 0x16BD, BIDI_L }, // RUNIC LETTER SHORT-TWIG-HAGALL H + { 0x16BE, BIDI_L }, // RUNIC LETTER NAUDIZ NYD NAUD N + { 0x16BF, BIDI_L }, // RUNIC LETTER SHORT-TWIG-NAUD N + { 0x16C0, BIDI_L }, // RUNIC LETTER DOTTED-N + { 0x16C1, BIDI_L }, // RUNIC LETTER ISAZ IS ISS I + { 0x16C2, BIDI_L }, // RUNIC LETTER E + { 0x16C3, BIDI_L }, // RUNIC LETTER JERAN J + { 0x16C4, BIDI_L }, // RUNIC LETTER GER + { 0x16C5, BIDI_L }, // RUNIC LETTER LONG-BRANCH-AR AE + { 0x16C6, BIDI_L }, // RUNIC LETTER SHORT-TWIG-AR A + { 0x16C7, BIDI_L }, // RUNIC LETTER IWAZ EOH + { 0x16C8, BIDI_L }, // RUNIC LETTER PERTHO PEORTH P + { 0x16C9, BIDI_L }, // RUNIC LETTER ALGIZ EOLHX + { 0x16CA, BIDI_L }, // RUNIC LETTER SOWILO S + { 0x16CB, BIDI_L }, // RUNIC LETTER SIGEL LONG-BRANCH-SOL S + { 0x16CC, BIDI_L }, // RUNIC LETTER SHORT-TWIG-SOL S + { 0x16CD, BIDI_L }, // RUNIC LETTER C + { 0x16CE, BIDI_L }, // RUNIC LETTER Z + { 0x16CF, BIDI_L }, // RUNIC LETTER TIWAZ TIR TYR T + { 0x16D0, BIDI_L }, // RUNIC LETTER SHORT-TWIG-TYR T + { 0x16D1, BIDI_L }, // RUNIC LETTER D + { 0x16D2, BIDI_L }, // RUNIC LETTER BERKANAN BEORC BJARKAN B + { 0x16D3, BIDI_L }, // RUNIC LETTER SHORT-TWIG-BJARKAN B + { 0x16D4, BIDI_L }, // RUNIC LETTER DOTTED-P + { 0x16D5, BIDI_L }, // RUNIC LETTER OPEN-P + { 0x16D6, BIDI_L }, // RUNIC LETTER EHWAZ EH E + { 0x16D7, BIDI_L }, // RUNIC LETTER MANNAZ MAN M + { 0x16D8, BIDI_L }, // RUNIC LETTER LONG-BRANCH-MADR M + { 0x16D9, BIDI_L }, // RUNIC LETTER SHORT-TWIG-MADR M + { 0x16DA, BIDI_L }, // RUNIC LETTER LAUKAZ LAGU LOGR L + { 0x16DB, BIDI_L }, // RUNIC LETTER DOTTED-L + { 0x16DC, BIDI_L }, // RUNIC LETTER INGWAZ + { 0x16DD, BIDI_L }, // RUNIC LETTER ING + { 0x16DE, BIDI_L }, // RUNIC LETTER DAGAZ DAEG D + { 0x16DF, BIDI_L }, // RUNIC LETTER OTHALAN ETHEL O + { 0x16E0, BIDI_L }, // RUNIC LETTER EAR + { 0x16E1, BIDI_L }, // RUNIC LETTER IOR + { 0x16E2, BIDI_L }, // RUNIC LETTER CWEORTH + { 0x16E3, BIDI_L }, // RUNIC LETTER CALC + { 0x16E4, BIDI_L }, // RUNIC LETTER CEALC + { 0x16E5, BIDI_L }, // RUNIC LETTER STAN + { 0x16E6, BIDI_L }, // RUNIC LETTER LONG-BRANCH-YR + { 0x16E7, BIDI_L }, // RUNIC LETTER SHORT-TWIG-YR + { 0x16E8, BIDI_L }, // RUNIC LETTER ICELANDIC-YR + { 0x16E9, BIDI_L }, // RUNIC LETTER Q + { 0x16EA, BIDI_L }, // RUNIC LETTER X + { 0x16EB, BIDI_L }, // RUNIC SINGLE PUNCTUATION + { 0x16EC, BIDI_L }, // RUNIC MULTIPLE PUNCTUATION + { 0x16ED, BIDI_L }, // RUNIC CROSS PUNCTUATION + { 0x16EE, BIDI_L }, // RUNIC ARLAUG SYMBOL + { 0x16EF, BIDI_L }, // RUNIC TVIMADUR SYMBOL + { 0x16F0, BIDI_L }, // RUNIC BELGTHOR SYMBOL + { 0x16F1, BIDI_L }, // RUNIC LETTER K + { 0x16F2, BIDI_L }, // RUNIC LETTER SH + { 0x16F3, BIDI_L }, // RUNIC LETTER OO + { 0x16F4, BIDI_L }, // RUNIC LETTER FRANKS CASKET OS + { 0x16F5, BIDI_L }, // RUNIC LETTER FRANKS CASKET IS + { 0x16F6, BIDI_L }, // RUNIC LETTER FRANKS CASKET EH + { 0x16F7, BIDI_L }, // RUNIC LETTER FRANKS CASKET AC + { 0x16F8, BIDI_L }, // RUNIC LETTER FRANKS CASKET AESC + { 0x1700, BIDI_L }, // TAGALOG LETTER A + { 0x1701, BIDI_L }, // TAGALOG LETTER I + { 0x1702, BIDI_L }, // TAGALOG LETTER U + { 0x1703, BIDI_L }, // TAGALOG LETTER KA + { 0x1704, BIDI_L }, // TAGALOG LETTER GA + { 0x1705, BIDI_L }, // TAGALOG LETTER NGA + { 0x1706, BIDI_L }, // TAGALOG LETTER TA + { 0x1707, BIDI_L }, // TAGALOG LETTER DA + { 0x1708, BIDI_L }, // TAGALOG LETTER NA + { 0x1709, BIDI_L }, // TAGALOG LETTER PA + { 0x170A, BIDI_L }, // TAGALOG LETTER BA + { 0x170B, BIDI_L }, // TAGALOG LETTER MA + { 0x170C, BIDI_L }, // TAGALOG LETTER YA + { 0x170E, BIDI_L }, // TAGALOG LETTER LA + { 0x170F, BIDI_L }, // TAGALOG LETTER WA + { 0x1710, BIDI_L }, // TAGALOG LETTER SA + { 0x1711, BIDI_L }, // TAGALOG LETTER HA + { 0x1712, BIDI_NSM }, // TAGALOG VOWEL SIGN I + { 0x1713, BIDI_NSM }, // TAGALOG VOWEL SIGN U + { 0x1714, BIDI_NSM }, // TAGALOG SIGN VIRAMA + { 0x1720, BIDI_L }, // HANUNOO LETTER A + { 0x1721, BIDI_L }, // HANUNOO LETTER I + { 0x1722, BIDI_L }, // HANUNOO LETTER U + { 0x1723, BIDI_L }, // HANUNOO LETTER KA + { 0x1724, BIDI_L }, // HANUNOO LETTER GA + { 0x1725, BIDI_L }, // HANUNOO LETTER NGA + { 0x1726, BIDI_L }, // HANUNOO LETTER TA + { 0x1727, BIDI_L }, // HANUNOO LETTER DA + { 0x1728, BIDI_L }, // HANUNOO LETTER NA + { 0x1729, BIDI_L }, // HANUNOO LETTER PA + { 0x172A, BIDI_L }, // HANUNOO LETTER BA + { 0x172B, BIDI_L }, // HANUNOO LETTER MA + { 0x172C, BIDI_L }, // HANUNOO LETTER YA + { 0x172D, BIDI_L }, // HANUNOO LETTER RA + { 0x172E, BIDI_L }, // HANUNOO LETTER LA + { 0x172F, BIDI_L }, // HANUNOO LETTER WA + { 0x1730, BIDI_L }, // HANUNOO LETTER SA + { 0x1731, BIDI_L }, // HANUNOO LETTER HA + { 0x1732, BIDI_NSM }, // HANUNOO VOWEL SIGN I + { 0x1733, BIDI_NSM }, // HANUNOO VOWEL SIGN U + { 0x1734, BIDI_NSM }, // HANUNOO SIGN PAMUDPOD + { 0x1735, BIDI_L }, // PHILIPPINE SINGLE PUNCTUATION + { 0x1736, BIDI_L }, // PHILIPPINE DOUBLE PUNCTUATION + { 0x1740, BIDI_L }, // BUHID LETTER A + { 0x1741, BIDI_L }, // BUHID LETTER I + { 0x1742, BIDI_L }, // BUHID LETTER U + { 0x1743, BIDI_L }, // BUHID LETTER KA + { 0x1744, BIDI_L }, // BUHID LETTER GA + { 0x1745, BIDI_L }, // BUHID LETTER NGA + { 0x1746, BIDI_L }, // BUHID LETTER TA + { 0x1747, BIDI_L }, // BUHID LETTER DA + { 0x1748, BIDI_L }, // BUHID LETTER NA + { 0x1749, BIDI_L }, // BUHID LETTER PA + { 0x174A, BIDI_L }, // BUHID LETTER BA + { 0x174B, BIDI_L }, // BUHID LETTER MA + { 0x174C, BIDI_L }, // BUHID LETTER YA + { 0x174D, BIDI_L }, // BUHID LETTER RA + { 0x174E, BIDI_L }, // BUHID LETTER LA + { 0x174F, BIDI_L }, // BUHID LETTER WA + { 0x1750, BIDI_L }, // BUHID LETTER SA + { 0x1751, BIDI_L }, // BUHID LETTER HA + { 0x1752, BIDI_NSM }, // BUHID VOWEL SIGN I + { 0x1753, BIDI_NSM }, // BUHID VOWEL SIGN U + { 0x1760, BIDI_L }, // TAGBANWA LETTER A + { 0x1761, BIDI_L }, // TAGBANWA LETTER I + { 0x1762, BIDI_L }, // TAGBANWA LETTER U + { 0x1763, BIDI_L }, // TAGBANWA LETTER KA + { 0x1764, BIDI_L }, // TAGBANWA LETTER GA + { 0x1765, BIDI_L }, // TAGBANWA LETTER NGA + { 0x1766, BIDI_L }, // TAGBANWA LETTER TA + { 0x1767, BIDI_L }, // TAGBANWA LETTER DA + { 0x1768, BIDI_L }, // TAGBANWA LETTER NA + { 0x1769, BIDI_L }, // TAGBANWA LETTER PA + { 0x176A, BIDI_L }, // TAGBANWA LETTER BA + { 0x176B, BIDI_L }, // TAGBANWA LETTER MA + { 0x176C, BIDI_L }, // TAGBANWA LETTER YA + { 0x176E, BIDI_L }, // TAGBANWA LETTER LA + { 0x176F, BIDI_L }, // TAGBANWA LETTER WA + { 0x1770, BIDI_L }, // TAGBANWA LETTER SA + { 0x1772, BIDI_NSM }, // TAGBANWA VOWEL SIGN I + { 0x1773, BIDI_NSM }, // TAGBANWA VOWEL SIGN U + { 0x1780, BIDI_L }, // KHMER LETTER KA + { 0x1781, BIDI_L }, // KHMER LETTER KHA + { 0x1782, BIDI_L }, // KHMER LETTER KO + { 0x1783, BIDI_L }, // KHMER LETTER KHO + { 0x1784, BIDI_L }, // KHMER LETTER NGO + { 0x1785, BIDI_L }, // KHMER LETTER CA + { 0x1786, BIDI_L }, // KHMER LETTER CHA + { 0x1787, BIDI_L }, // KHMER LETTER CO + { 0x1788, BIDI_L }, // KHMER LETTER CHO + { 0x1789, BIDI_L }, // KHMER LETTER NYO + { 0x178A, BIDI_L }, // KHMER LETTER DA + { 0x178B, BIDI_L }, // KHMER LETTER TTHA + { 0x178C, BIDI_L }, // KHMER LETTER DO + { 0x178D, BIDI_L }, // KHMER LETTER TTHO + { 0x178E, BIDI_L }, // KHMER LETTER NNO + { 0x178F, BIDI_L }, // KHMER LETTER TA + { 0x1790, BIDI_L }, // KHMER LETTER THA + { 0x1791, BIDI_L }, // KHMER LETTER TO + { 0x1792, BIDI_L }, // KHMER LETTER THO + { 0x1793, BIDI_L }, // KHMER LETTER NO + { 0x1794, BIDI_L }, // KHMER LETTER BA + { 0x1795, BIDI_L }, // KHMER LETTER PHA + { 0x1796, BIDI_L }, // KHMER LETTER PO + { 0x1797, BIDI_L }, // KHMER LETTER PHO + { 0x1798, BIDI_L }, // KHMER LETTER MO + { 0x1799, BIDI_L }, // KHMER LETTER YO + { 0x179A, BIDI_L }, // KHMER LETTER RO + { 0x179B, BIDI_L }, // KHMER LETTER LO + { 0x179C, BIDI_L }, // KHMER LETTER VO + { 0x179D, BIDI_L }, // KHMER LETTER SHA + { 0x179E, BIDI_L }, // KHMER LETTER SSO + { 0x179F, BIDI_L }, // KHMER LETTER SA + { 0x17A0, BIDI_L }, // KHMER LETTER HA + { 0x17A1, BIDI_L }, // KHMER LETTER LA + { 0x17A2, BIDI_L }, // KHMER LETTER QA + { 0x17A3, BIDI_L }, // KHMER INDEPENDENT VOWEL QAQ + { 0x17A4, BIDI_L }, // KHMER INDEPENDENT VOWEL QAA + { 0x17A5, BIDI_L }, // KHMER INDEPENDENT VOWEL QI + { 0x17A6, BIDI_L }, // KHMER INDEPENDENT VOWEL QII + { 0x17A7, BIDI_L }, // KHMER INDEPENDENT VOWEL QU + { 0x17A8, BIDI_L }, // KHMER INDEPENDENT VOWEL QUK + { 0x17A9, BIDI_L }, // KHMER INDEPENDENT VOWEL QUU + { 0x17AA, BIDI_L }, // KHMER INDEPENDENT VOWEL QUUV + { 0x17AB, BIDI_L }, // KHMER INDEPENDENT VOWEL RY + { 0x17AC, BIDI_L }, // KHMER INDEPENDENT VOWEL RYY + { 0x17AD, BIDI_L }, // KHMER INDEPENDENT VOWEL LY + { 0x17AE, BIDI_L }, // KHMER INDEPENDENT VOWEL LYY + { 0x17AF, BIDI_L }, // KHMER INDEPENDENT VOWEL QE + { 0x17B0, BIDI_L }, // KHMER INDEPENDENT VOWEL QAI + { 0x17B1, BIDI_L }, // KHMER INDEPENDENT VOWEL QOO TYPE ONE + { 0x17B2, BIDI_L }, // KHMER INDEPENDENT VOWEL QOO TYPE TWO + { 0x17B3, BIDI_L }, // KHMER INDEPENDENT VOWEL QAU + { 0x17B4, BIDI_NSM }, // KHMER VOWEL INHERENT AQ + { 0x17B5, BIDI_NSM }, // KHMER VOWEL INHERENT AA + { 0x17B6, BIDI_L }, // KHMER VOWEL SIGN AA + { 0x17B7, BIDI_NSM }, // KHMER VOWEL SIGN I + { 0x17B8, BIDI_NSM }, // KHMER VOWEL SIGN II + { 0x17B9, BIDI_NSM }, // KHMER VOWEL SIGN Y + { 0x17BA, BIDI_NSM }, // KHMER VOWEL SIGN YY + { 0x17BB, BIDI_NSM }, // KHMER VOWEL SIGN U + { 0x17BC, BIDI_NSM }, // KHMER VOWEL SIGN UU + { 0x17BD, BIDI_NSM }, // KHMER VOWEL SIGN UA + { 0x17BE, BIDI_L }, // KHMER VOWEL SIGN OE + { 0x17BF, BIDI_L }, // KHMER VOWEL SIGN YA + { 0x17C0, BIDI_L }, // KHMER VOWEL SIGN IE + { 0x17C1, BIDI_L }, // KHMER VOWEL SIGN E + { 0x17C2, BIDI_L }, // KHMER VOWEL SIGN AE + { 0x17C3, BIDI_L }, // KHMER VOWEL SIGN AI + { 0x17C4, BIDI_L }, // KHMER VOWEL SIGN OO + { 0x17C5, BIDI_L }, // KHMER VOWEL SIGN AU + { 0x17C6, BIDI_NSM }, // KHMER SIGN NIKAHIT + { 0x17C7, BIDI_L }, // KHMER SIGN REAHMUK + { 0x17C8, BIDI_L }, // KHMER SIGN YUUKALEAPINTU + { 0x17C9, BIDI_NSM }, // KHMER SIGN MUUSIKATOAN + { 0x17CA, BIDI_NSM }, // KHMER SIGN TRIISAP + { 0x17CB, BIDI_NSM }, // KHMER SIGN BANTOC + { 0x17CC, BIDI_NSM }, // KHMER SIGN ROBAT + { 0x17CD, BIDI_NSM }, // KHMER SIGN TOANDAKHIAT + { 0x17CE, BIDI_NSM }, // KHMER SIGN KAKABAT + { 0x17CF, BIDI_NSM }, // KHMER SIGN AHSDA + { 0x17D0, BIDI_NSM }, // KHMER SIGN SAMYOK SANNYA + { 0x17D1, BIDI_NSM }, // KHMER SIGN VIRIAM + { 0x17D2, BIDI_NSM }, // KHMER SIGN COENG + { 0x17D3, BIDI_NSM }, // KHMER SIGN BATHAMASAT + { 0x17D4, BIDI_L }, // KHMER SIGN KHAN + { 0x17D5, BIDI_L }, // KHMER SIGN BARIYOOSAN + { 0x17D6, BIDI_L }, // KHMER SIGN CAMNUC PII KUUH + { 0x17D7, BIDI_L }, // KHMER SIGN LEK TOO + { 0x17D8, BIDI_L }, // KHMER SIGN BEYYAL + { 0x17D9, BIDI_L }, // KHMER SIGN PHNAEK MUAN + { 0x17DA, BIDI_L }, // KHMER SIGN KOOMUUT + { 0x17DB, BIDI_ET }, // KHMER CURRENCY SYMBOL RIEL + { 0x17DC, BIDI_L }, // KHMER SIGN AVAKRAHASANYA + { 0x17DD, BIDI_NSM }, // KHMER SIGN ATTHACAN + { 0x17E0, BIDI_L }, // KHMER DIGIT ZERO + { 0x17E1, BIDI_L }, // KHMER DIGIT ONE + { 0x17E2, BIDI_L }, // KHMER DIGIT TWO + { 0x17E3, BIDI_L }, // KHMER DIGIT THREE + { 0x17E4, BIDI_L }, // KHMER DIGIT FOUR + { 0x17E5, BIDI_L }, // KHMER DIGIT FIVE + { 0x17E6, BIDI_L }, // KHMER DIGIT SIX + { 0x17E7, BIDI_L }, // KHMER DIGIT SEVEN + { 0x17E8, BIDI_L }, // KHMER DIGIT EIGHT + { 0x17E9, BIDI_L }, // KHMER DIGIT NINE + { 0x17F0, BIDI_ON }, // KHMER SYMBOL LEK ATTAK SON + { 0x17F1, BIDI_ON }, // KHMER SYMBOL LEK ATTAK MUOY + { 0x17F2, BIDI_ON }, // KHMER SYMBOL LEK ATTAK PII + { 0x17F3, BIDI_ON }, // KHMER SYMBOL LEK ATTAK BEI + { 0x17F4, BIDI_ON }, // KHMER SYMBOL LEK ATTAK BUON + { 0x17F5, BIDI_ON }, // KHMER SYMBOL LEK ATTAK PRAM + { 0x17F6, BIDI_ON }, // KHMER SYMBOL LEK ATTAK PRAM-MUOY + { 0x17F7, BIDI_ON }, // KHMER SYMBOL LEK ATTAK PRAM-PII + { 0x17F8, BIDI_ON }, // KHMER SYMBOL LEK ATTAK PRAM-BEI + { 0x17F9, BIDI_ON }, // KHMER SYMBOL LEK ATTAK PRAM-BUON + { 0x1800, BIDI_ON }, // MONGOLIAN BIRGA + { 0x1801, BIDI_ON }, // MONGOLIAN ELLIPSIS + { 0x1802, BIDI_ON }, // MONGOLIAN COMMA + { 0x1803, BIDI_ON }, // MONGOLIAN FULL STOP + { 0x1804, BIDI_ON }, // MONGOLIAN COLON + { 0x1805, BIDI_ON }, // MONGOLIAN FOUR DOTS + { 0x1806, BIDI_ON }, // MONGOLIAN TODO SOFT HYPHEN + { 0x1807, BIDI_ON }, // MONGOLIAN SIBE SYLLABLE BOUNDARY MARKER + { 0x1808, BIDI_ON }, // MONGOLIAN MANCHU COMMA + { 0x1809, BIDI_ON }, // MONGOLIAN MANCHU FULL STOP + { 0x180A, BIDI_ON }, // MONGOLIAN NIRUGU + { 0x180B, BIDI_NSM }, // MONGOLIAN FREE VARIATION SELECTOR ONE + { 0x180C, BIDI_NSM }, // MONGOLIAN FREE VARIATION SELECTOR TWO + { 0x180D, BIDI_NSM }, // MONGOLIAN FREE VARIATION SELECTOR THREE + { 0x180E, BIDI_BN }, // MONGOLIAN VOWEL SEPARATOR + { 0x1810, BIDI_L }, // MONGOLIAN DIGIT ZERO + { 0x1811, BIDI_L }, // MONGOLIAN DIGIT ONE + { 0x1812, BIDI_L }, // MONGOLIAN DIGIT TWO + { 0x1813, BIDI_L }, // MONGOLIAN DIGIT THREE + { 0x1814, BIDI_L }, // MONGOLIAN DIGIT FOUR + { 0x1815, BIDI_L }, // MONGOLIAN DIGIT FIVE + { 0x1816, BIDI_L }, // MONGOLIAN DIGIT SIX + { 0x1817, BIDI_L }, // MONGOLIAN DIGIT SEVEN + { 0x1818, BIDI_L }, // MONGOLIAN DIGIT EIGHT + { 0x1819, BIDI_L }, // MONGOLIAN DIGIT NINE + { 0x1820, BIDI_L }, // MONGOLIAN LETTER A + { 0x1821, BIDI_L }, // MONGOLIAN LETTER E + { 0x1822, BIDI_L }, // MONGOLIAN LETTER I + { 0x1823, BIDI_L }, // MONGOLIAN LETTER O + { 0x1824, BIDI_L }, // MONGOLIAN LETTER U + { 0x1825, BIDI_L }, // MONGOLIAN LETTER OE + { 0x1826, BIDI_L }, // MONGOLIAN LETTER UE + { 0x1827, BIDI_L }, // MONGOLIAN LETTER EE + { 0x1828, BIDI_L }, // MONGOLIAN LETTER NA + { 0x1829, BIDI_L }, // MONGOLIAN LETTER ANG + { 0x182A, BIDI_L }, // MONGOLIAN LETTER BA + { 0x182B, BIDI_L }, // MONGOLIAN LETTER PA + { 0x182C, BIDI_L }, // MONGOLIAN LETTER QA + { 0x182D, BIDI_L }, // MONGOLIAN LETTER GA + { 0x182E, BIDI_L }, // MONGOLIAN LETTER MA + { 0x182F, BIDI_L }, // MONGOLIAN LETTER LA + { 0x1830, BIDI_L }, // MONGOLIAN LETTER SA + { 0x1831, BIDI_L }, // MONGOLIAN LETTER SHA + { 0x1832, BIDI_L }, // MONGOLIAN LETTER TA + { 0x1833, BIDI_L }, // MONGOLIAN LETTER DA + { 0x1834, BIDI_L }, // MONGOLIAN LETTER CHA + { 0x1835, BIDI_L }, // MONGOLIAN LETTER JA + { 0x1836, BIDI_L }, // MONGOLIAN LETTER YA + { 0x1837, BIDI_L }, // MONGOLIAN LETTER RA + { 0x1838, BIDI_L }, // MONGOLIAN LETTER WA + { 0x1839, BIDI_L }, // MONGOLIAN LETTER FA + { 0x183A, BIDI_L }, // MONGOLIAN LETTER KA + { 0x183B, BIDI_L }, // MONGOLIAN LETTER KHA + { 0x183C, BIDI_L }, // MONGOLIAN LETTER TSA + { 0x183D, BIDI_L }, // MONGOLIAN LETTER ZA + { 0x183E, BIDI_L }, // MONGOLIAN LETTER HAA + { 0x183F, BIDI_L }, // MONGOLIAN LETTER ZRA + { 0x1840, BIDI_L }, // MONGOLIAN LETTER LHA + { 0x1841, BIDI_L }, // MONGOLIAN LETTER ZHI + { 0x1842, BIDI_L }, // MONGOLIAN LETTER CHI + { 0x1843, BIDI_L }, // MONGOLIAN LETTER TODO LONG VOWEL SIGN + { 0x1844, BIDI_L }, // MONGOLIAN LETTER TODO E + { 0x1845, BIDI_L }, // MONGOLIAN LETTER TODO I + { 0x1846, BIDI_L }, // MONGOLIAN LETTER TODO O + { 0x1847, BIDI_L }, // MONGOLIAN LETTER TODO U + { 0x1848, BIDI_L }, // MONGOLIAN LETTER TODO OE + { 0x1849, BIDI_L }, // MONGOLIAN LETTER TODO UE + { 0x184A, BIDI_L }, // MONGOLIAN LETTER TODO ANG + { 0x184B, BIDI_L }, // MONGOLIAN LETTER TODO BA + { 0x184C, BIDI_L }, // MONGOLIAN LETTER TODO PA + { 0x184D, BIDI_L }, // MONGOLIAN LETTER TODO QA + { 0x184E, BIDI_L }, // MONGOLIAN LETTER TODO GA + { 0x184F, BIDI_L }, // MONGOLIAN LETTER TODO MA + { 0x1850, BIDI_L }, // MONGOLIAN LETTER TODO TA + { 0x1851, BIDI_L }, // MONGOLIAN LETTER TODO DA + { 0x1852, BIDI_L }, // MONGOLIAN LETTER TODO CHA + { 0x1853, BIDI_L }, // MONGOLIAN LETTER TODO JA + { 0x1854, BIDI_L }, // MONGOLIAN LETTER TODO TSA + { 0x1855, BIDI_L }, // MONGOLIAN LETTER TODO YA + { 0x1856, BIDI_L }, // MONGOLIAN LETTER TODO WA + { 0x1857, BIDI_L }, // MONGOLIAN LETTER TODO KA + { 0x1858, BIDI_L }, // MONGOLIAN LETTER TODO GAA + { 0x1859, BIDI_L }, // MONGOLIAN LETTER TODO HAA + { 0x185A, BIDI_L }, // MONGOLIAN LETTER TODO JIA + { 0x185B, BIDI_L }, // MONGOLIAN LETTER TODO NIA + { 0x185C, BIDI_L }, // MONGOLIAN LETTER TODO DZA + { 0x185D, BIDI_L }, // MONGOLIAN LETTER SIBE E + { 0x185E, BIDI_L }, // MONGOLIAN LETTER SIBE I + { 0x185F, BIDI_L }, // MONGOLIAN LETTER SIBE IY + { 0x1860, BIDI_L }, // MONGOLIAN LETTER SIBE UE + { 0x1861, BIDI_L }, // MONGOLIAN LETTER SIBE U + { 0x1862, BIDI_L }, // MONGOLIAN LETTER SIBE ANG + { 0x1863, BIDI_L }, // MONGOLIAN LETTER SIBE KA + { 0x1864, BIDI_L }, // MONGOLIAN LETTER SIBE GA + { 0x1865, BIDI_L }, // MONGOLIAN LETTER SIBE HA + { 0x1866, BIDI_L }, // MONGOLIAN LETTER SIBE PA + { 0x1867, BIDI_L }, // MONGOLIAN LETTER SIBE SHA + { 0x1868, BIDI_L }, // MONGOLIAN LETTER SIBE TA + { 0x1869, BIDI_L }, // MONGOLIAN LETTER SIBE DA + { 0x186A, BIDI_L }, // MONGOLIAN LETTER SIBE JA + { 0x186B, BIDI_L }, // MONGOLIAN LETTER SIBE FA + { 0x186C, BIDI_L }, // MONGOLIAN LETTER SIBE GAA + { 0x186D, BIDI_L }, // MONGOLIAN LETTER SIBE HAA + { 0x186E, BIDI_L }, // MONGOLIAN LETTER SIBE TSA + { 0x186F, BIDI_L }, // MONGOLIAN LETTER SIBE ZA + { 0x1870, BIDI_L }, // MONGOLIAN LETTER SIBE RAA + { 0x1871, BIDI_L }, // MONGOLIAN LETTER SIBE CHA + { 0x1872, BIDI_L }, // MONGOLIAN LETTER SIBE ZHA + { 0x1873, BIDI_L }, // MONGOLIAN LETTER MANCHU I + { 0x1874, BIDI_L }, // MONGOLIAN LETTER MANCHU KA + { 0x1875, BIDI_L }, // MONGOLIAN LETTER MANCHU RA + { 0x1876, BIDI_L }, // MONGOLIAN LETTER MANCHU FA + { 0x1877, BIDI_L }, // MONGOLIAN LETTER MANCHU ZHA + { 0x1880, BIDI_L }, // MONGOLIAN LETTER ALI GALI ANUSVARA ONE + { 0x1881, BIDI_L }, // MONGOLIAN LETTER ALI GALI VISARGA ONE + { 0x1882, BIDI_L }, // MONGOLIAN LETTER ALI GALI DAMARU + { 0x1883, BIDI_L }, // MONGOLIAN LETTER ALI GALI UBADAMA + { 0x1884, BIDI_L }, // MONGOLIAN LETTER ALI GALI INVERTED UBADAMA + { 0x1885, BIDI_L }, // MONGOLIAN LETTER ALI GALI BALUDA + { 0x1886, BIDI_L }, // MONGOLIAN LETTER ALI GALI THREE BALUDA + { 0x1887, BIDI_L }, // MONGOLIAN LETTER ALI GALI A + { 0x1888, BIDI_L }, // MONGOLIAN LETTER ALI GALI I + { 0x1889, BIDI_L }, // MONGOLIAN LETTER ALI GALI KA + { 0x188A, BIDI_L }, // MONGOLIAN LETTER ALI GALI NGA + { 0x188B, BIDI_L }, // MONGOLIAN LETTER ALI GALI CA + { 0x188C, BIDI_L }, // MONGOLIAN LETTER ALI GALI TTA + { 0x188D, BIDI_L }, // MONGOLIAN LETTER ALI GALI TTHA + { 0x188E, BIDI_L }, // MONGOLIAN LETTER ALI GALI DDA + { 0x188F, BIDI_L }, // MONGOLIAN LETTER ALI GALI NNA + { 0x1890, BIDI_L }, // MONGOLIAN LETTER ALI GALI TA + { 0x1891, BIDI_L }, // MONGOLIAN LETTER ALI GALI DA + { 0x1892, BIDI_L }, // MONGOLIAN LETTER ALI GALI PA + { 0x1893, BIDI_L }, // MONGOLIAN LETTER ALI GALI PHA + { 0x1894, BIDI_L }, // MONGOLIAN LETTER ALI GALI SSA + { 0x1895, BIDI_L }, // MONGOLIAN LETTER ALI GALI ZHA + { 0x1896, BIDI_L }, // MONGOLIAN LETTER ALI GALI ZA + { 0x1897, BIDI_L }, // MONGOLIAN LETTER ALI GALI AH + { 0x1898, BIDI_L }, // MONGOLIAN LETTER TODO ALI GALI TA + { 0x1899, BIDI_L }, // MONGOLIAN LETTER TODO ALI GALI ZHA + { 0x189A, BIDI_L }, // MONGOLIAN LETTER MANCHU ALI GALI GHA + { 0x189B, BIDI_L }, // MONGOLIAN LETTER MANCHU ALI GALI NGA + { 0x189C, BIDI_L }, // MONGOLIAN LETTER MANCHU ALI GALI CA + { 0x189D, BIDI_L }, // MONGOLIAN LETTER MANCHU ALI GALI JHA + { 0x189E, BIDI_L }, // MONGOLIAN LETTER MANCHU ALI GALI TTA + { 0x189F, BIDI_L }, // MONGOLIAN LETTER MANCHU ALI GALI DDHA + { 0x18A0, BIDI_L }, // MONGOLIAN LETTER MANCHU ALI GALI TA + { 0x18A1, BIDI_L }, // MONGOLIAN LETTER MANCHU ALI GALI DHA + { 0x18A2, BIDI_L }, // MONGOLIAN LETTER MANCHU ALI GALI SSA + { 0x18A3, BIDI_L }, // MONGOLIAN LETTER MANCHU ALI GALI CYA + { 0x18A4, BIDI_L }, // MONGOLIAN LETTER MANCHU ALI GALI ZHA + { 0x18A5, BIDI_L }, // MONGOLIAN LETTER MANCHU ALI GALI ZA + { 0x18A6, BIDI_L }, // MONGOLIAN LETTER ALI GALI HALF U + { 0x18A7, BIDI_L }, // MONGOLIAN LETTER ALI GALI HALF YA + { 0x18A8, BIDI_L }, // MONGOLIAN LETTER MANCHU ALI GALI BHA + { 0x18A9, BIDI_NSM }, // MONGOLIAN LETTER ALI GALI DAGALGA + { 0x18AA, BIDI_L }, // MONGOLIAN LETTER MANCHU ALI GALI LHA + { 0x18B0, BIDI_L }, // CANADIAN SYLLABICS OY + { 0x18B1, BIDI_L }, // CANADIAN SYLLABICS AY + { 0x18B2, BIDI_L }, // CANADIAN SYLLABICS AAY + { 0x18B3, BIDI_L }, // CANADIAN SYLLABICS WAY + { 0x18B4, BIDI_L }, // CANADIAN SYLLABICS POY + { 0x18B5, BIDI_L }, // CANADIAN SYLLABICS PAY + { 0x18B6, BIDI_L }, // CANADIAN SYLLABICS PWOY + { 0x18B7, BIDI_L }, // CANADIAN SYLLABICS TAY + { 0x18B8, BIDI_L }, // CANADIAN SYLLABICS KAY + { 0x18B9, BIDI_L }, // CANADIAN SYLLABICS KWAY + { 0x18BA, BIDI_L }, // CANADIAN SYLLABICS MAY + { 0x18BB, BIDI_L }, // CANADIAN SYLLABICS NOY + { 0x18BC, BIDI_L }, // CANADIAN SYLLABICS NAY + { 0x18BD, BIDI_L }, // CANADIAN SYLLABICS LAY + { 0x18BE, BIDI_L }, // CANADIAN SYLLABICS SOY + { 0x18BF, BIDI_L }, // CANADIAN SYLLABICS SAY + { 0x18C0, BIDI_L }, // CANADIAN SYLLABICS SHOY + { 0x18C1, BIDI_L }, // CANADIAN SYLLABICS SHAY + { 0x18C2, BIDI_L }, // CANADIAN SYLLABICS SHWOY + { 0x18C3, BIDI_L }, // CANADIAN SYLLABICS YOY + { 0x18C4, BIDI_L }, // CANADIAN SYLLABICS YAY + { 0x18C5, BIDI_L }, // CANADIAN SYLLABICS RAY + { 0x18C6, BIDI_L }, // CANADIAN SYLLABICS NWI + { 0x18C7, BIDI_L }, // CANADIAN SYLLABICS OJIBWAY NWI + { 0x18C8, BIDI_L }, // CANADIAN SYLLABICS NWII + { 0x18C9, BIDI_L }, // CANADIAN SYLLABICS OJIBWAY NWII + { 0x18CA, BIDI_L }, // CANADIAN SYLLABICS NWO + { 0x18CB, BIDI_L }, // CANADIAN SYLLABICS OJIBWAY NWO + { 0x18CC, BIDI_L }, // CANADIAN SYLLABICS NWOO + { 0x18CD, BIDI_L }, // CANADIAN SYLLABICS OJIBWAY NWOO + { 0x18CE, BIDI_L }, // CANADIAN SYLLABICS RWEE + { 0x18CF, BIDI_L }, // CANADIAN SYLLABICS RWI + { 0x18D0, BIDI_L }, // CANADIAN SYLLABICS RWII + { 0x18D1, BIDI_L }, // CANADIAN SYLLABICS RWO + { 0x18D2, BIDI_L }, // CANADIAN SYLLABICS RWOO + { 0x18D3, BIDI_L }, // CANADIAN SYLLABICS RWA + { 0x18D4, BIDI_L }, // CANADIAN SYLLABICS OJIBWAY P + { 0x18D5, BIDI_L }, // CANADIAN SYLLABICS OJIBWAY T + { 0x18D6, BIDI_L }, // CANADIAN SYLLABICS OJIBWAY K + { 0x18D7, BIDI_L }, // CANADIAN SYLLABICS OJIBWAY C + { 0x18D8, BIDI_L }, // CANADIAN SYLLABICS OJIBWAY M + { 0x18D9, BIDI_L }, // CANADIAN SYLLABICS OJIBWAY N + { 0x18DA, BIDI_L }, // CANADIAN SYLLABICS OJIBWAY S + { 0x18DB, BIDI_L }, // CANADIAN SYLLABICS OJIBWAY SH + { 0x18DC, BIDI_L }, // CANADIAN SYLLABICS EASTERN W + { 0x18DD, BIDI_L }, // CANADIAN SYLLABICS WESTERN W + { 0x18DE, BIDI_L }, // CANADIAN SYLLABICS FINAL SMALL RING + { 0x18DF, BIDI_L }, // CANADIAN SYLLABICS FINAL RAISED DOT + { 0x18E0, BIDI_L }, // CANADIAN SYLLABICS R-CREE RWE + { 0x18E1, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE LOO + { 0x18E2, BIDI_L }, // CANADIAN SYLLABICS WEST-CREE LAA + { 0x18E3, BIDI_L }, // CANADIAN SYLLABICS THWE + { 0x18E4, BIDI_L }, // CANADIAN SYLLABICS THWA + { 0x18E5, BIDI_L }, // CANADIAN SYLLABICS TTHWE + { 0x18E6, BIDI_L }, // CANADIAN SYLLABICS TTHOO + { 0x18E7, BIDI_L }, // CANADIAN SYLLABICS TTHAA + { 0x18E8, BIDI_L }, // CANADIAN SYLLABICS TLHWE + { 0x18E9, BIDI_L }, // CANADIAN SYLLABICS TLHOO + { 0x18EA, BIDI_L }, // CANADIAN SYLLABICS SAYISI SHWE + { 0x18EB, BIDI_L }, // CANADIAN SYLLABICS SAYISI SHOO + { 0x18EC, BIDI_L }, // CANADIAN SYLLABICS SAYISI HOO + { 0x18ED, BIDI_L }, // CANADIAN SYLLABICS CARRIER GWU + { 0x18EE, BIDI_L }, // CANADIAN SYLLABICS CARRIER DENE GEE + { 0x18EF, BIDI_L }, // CANADIAN SYLLABICS CARRIER GAA + { 0x18F0, BIDI_L }, // CANADIAN SYLLABICS CARRIER GWA + { 0x18F1, BIDI_L }, // CANADIAN SYLLABICS SAYISI JUU + { 0x18F2, BIDI_L }, // CANADIAN SYLLABICS CARRIER JWA + { 0x18F3, BIDI_L }, // CANADIAN SYLLABICS BEAVER DENE L + { 0x18F4, BIDI_L }, // CANADIAN SYLLABICS BEAVER DENE R + { 0x18F5, BIDI_L }, // CANADIAN SYLLABICS CARRIER DENTAL S + { 0x1900, BIDI_L }, // LIMBU VOWEL-CARRIER LETTER + { 0x1901, BIDI_L }, // LIMBU LETTER KA + { 0x1902, BIDI_L }, // LIMBU LETTER KHA + { 0x1903, BIDI_L }, // LIMBU LETTER GA + { 0x1904, BIDI_L }, // LIMBU LETTER GHA + { 0x1905, BIDI_L }, // LIMBU LETTER NGA + { 0x1906, BIDI_L }, // LIMBU LETTER CA + { 0x1907, BIDI_L }, // LIMBU LETTER CHA + { 0x1908, BIDI_L }, // LIMBU LETTER JA + { 0x1909, BIDI_L }, // LIMBU LETTER JHA + { 0x190A, BIDI_L }, // LIMBU LETTER YAN + { 0x190B, BIDI_L }, // LIMBU LETTER TA + { 0x190C, BIDI_L }, // LIMBU LETTER THA + { 0x190D, BIDI_L }, // LIMBU LETTER DA + { 0x190E, BIDI_L }, // LIMBU LETTER DHA + { 0x190F, BIDI_L }, // LIMBU LETTER NA + { 0x1910, BIDI_L }, // LIMBU LETTER PA + { 0x1911, BIDI_L }, // LIMBU LETTER PHA + { 0x1912, BIDI_L }, // LIMBU LETTER BA + { 0x1913, BIDI_L }, // LIMBU LETTER BHA + { 0x1914, BIDI_L }, // LIMBU LETTER MA + { 0x1915, BIDI_L }, // LIMBU LETTER YA + { 0x1916, BIDI_L }, // LIMBU LETTER RA + { 0x1917, BIDI_L }, // LIMBU LETTER LA + { 0x1918, BIDI_L }, // LIMBU LETTER WA + { 0x1919, BIDI_L }, // LIMBU LETTER SHA + { 0x191A, BIDI_L }, // LIMBU LETTER SSA + { 0x191B, BIDI_L }, // LIMBU LETTER SA + { 0x191C, BIDI_L }, // LIMBU LETTER HA + { 0x191D, BIDI_L }, // LIMBU LETTER GYAN + { 0x191E, BIDI_L }, // LIMBU LETTER TRA + { 0x1920, BIDI_NSM }, // LIMBU VOWEL SIGN A + { 0x1921, BIDI_NSM }, // LIMBU VOWEL SIGN I + { 0x1922, BIDI_NSM }, // LIMBU VOWEL SIGN U + { 0x1923, BIDI_L }, // LIMBU VOWEL SIGN EE + { 0x1924, BIDI_L }, // LIMBU VOWEL SIGN AI + { 0x1925, BIDI_L }, // LIMBU VOWEL SIGN OO + { 0x1926, BIDI_L }, // LIMBU VOWEL SIGN AU + { 0x1927, BIDI_NSM }, // LIMBU VOWEL SIGN E + { 0x1928, BIDI_NSM }, // LIMBU VOWEL SIGN O + { 0x1929, BIDI_L }, // LIMBU SUBJOINED LETTER YA + { 0x192A, BIDI_L }, // LIMBU SUBJOINED LETTER RA + { 0x192B, BIDI_L }, // LIMBU SUBJOINED LETTER WA + { 0x1930, BIDI_L }, // LIMBU SMALL LETTER KA + { 0x1931, BIDI_L }, // LIMBU SMALL LETTER NGA + { 0x1932, BIDI_NSM }, // LIMBU SMALL LETTER ANUSVARA + { 0x1933, BIDI_L }, // LIMBU SMALL LETTER TA + { 0x1934, BIDI_L }, // LIMBU SMALL LETTER NA + { 0x1935, BIDI_L }, // LIMBU SMALL LETTER PA + { 0x1936, BIDI_L }, // LIMBU SMALL LETTER MA + { 0x1937, BIDI_L }, // LIMBU SMALL LETTER RA + { 0x1938, BIDI_L }, // LIMBU SMALL LETTER LA + { 0x1939, BIDI_NSM }, // LIMBU SIGN MUKPHRENG + { 0x193A, BIDI_NSM }, // LIMBU SIGN KEMPHRENG + { 0x193B, BIDI_NSM }, // LIMBU SIGN SA-I + { 0x1940, BIDI_ON }, // LIMBU SIGN LOO + { 0x1944, BIDI_ON }, // LIMBU EXCLAMATION MARK + { 0x1945, BIDI_ON }, // LIMBU QUESTION MARK + { 0x1946, BIDI_L }, // LIMBU DIGIT ZERO + { 0x1947, BIDI_L }, // LIMBU DIGIT ONE + { 0x1948, BIDI_L }, // LIMBU DIGIT TWO + { 0x1949, BIDI_L }, // LIMBU DIGIT THREE + { 0x194A, BIDI_L }, // LIMBU DIGIT FOUR + { 0x194B, BIDI_L }, // LIMBU DIGIT FIVE + { 0x194C, BIDI_L }, // LIMBU DIGIT SIX + { 0x194D, BIDI_L }, // LIMBU DIGIT SEVEN + { 0x194E, BIDI_L }, // LIMBU DIGIT EIGHT + { 0x194F, BIDI_L }, // LIMBU DIGIT NINE + { 0x1950, BIDI_L }, // TAI LE LETTER KA + { 0x1951, BIDI_L }, // TAI LE LETTER XA + { 0x1952, BIDI_L }, // TAI LE LETTER NGA + { 0x1953, BIDI_L }, // TAI LE LETTER TSA + { 0x1954, BIDI_L }, // TAI LE LETTER SA + { 0x1955, BIDI_L }, // TAI LE LETTER YA + { 0x1956, BIDI_L }, // TAI LE LETTER TA + { 0x1957, BIDI_L }, // TAI LE LETTER THA + { 0x1958, BIDI_L }, // TAI LE LETTER LA + { 0x1959, BIDI_L }, // TAI LE LETTER PA + { 0x195A, BIDI_L }, // TAI LE LETTER PHA + { 0x195B, BIDI_L }, // TAI LE LETTER MA + { 0x195C, BIDI_L }, // TAI LE LETTER FA + { 0x195D, BIDI_L }, // TAI LE LETTER VA + { 0x195E, BIDI_L }, // TAI LE LETTER HA + { 0x195F, BIDI_L }, // TAI LE LETTER QA + { 0x1960, BIDI_L }, // TAI LE LETTER KHA + { 0x1961, BIDI_L }, // TAI LE LETTER TSHA + { 0x1962, BIDI_L }, // TAI LE LETTER NA + { 0x1963, BIDI_L }, // TAI LE LETTER A + { 0x1964, BIDI_L }, // TAI LE LETTER I + { 0x1965, BIDI_L }, // TAI LE LETTER EE + { 0x1966, BIDI_L }, // TAI LE LETTER EH + { 0x1967, BIDI_L }, // TAI LE LETTER U + { 0x1968, BIDI_L }, // TAI LE LETTER OO + { 0x1969, BIDI_L }, // TAI LE LETTER O + { 0x196A, BIDI_L }, // TAI LE LETTER UE + { 0x196B, BIDI_L }, // TAI LE LETTER E + { 0x196C, BIDI_L }, // TAI LE LETTER AUE + { 0x196D, BIDI_L }, // TAI LE LETTER AI + { 0x1970, BIDI_L }, // TAI LE LETTER TONE-2 + { 0x1971, BIDI_L }, // TAI LE LETTER TONE-3 + { 0x1972, BIDI_L }, // TAI LE LETTER TONE-4 + { 0x1973, BIDI_L }, // TAI LE LETTER TONE-5 + { 0x1974, BIDI_L }, // TAI LE LETTER TONE-6 + { 0x1980, BIDI_L }, // NEW TAI LUE LETTER HIGH QA + { 0x1981, BIDI_L }, // NEW TAI LUE LETTER LOW QA + { 0x1982, BIDI_L }, // NEW TAI LUE LETTER HIGH KA + { 0x1983, BIDI_L }, // NEW TAI LUE LETTER HIGH XA + { 0x1984, BIDI_L }, // NEW TAI LUE LETTER HIGH NGA + { 0x1985, BIDI_L }, // NEW TAI LUE LETTER LOW KA + { 0x1986, BIDI_L }, // NEW TAI LUE LETTER LOW XA + { 0x1987, BIDI_L }, // NEW TAI LUE LETTER LOW NGA + { 0x1988, BIDI_L }, // NEW TAI LUE LETTER HIGH TSA + { 0x1989, BIDI_L }, // NEW TAI LUE LETTER HIGH SA + { 0x198A, BIDI_L }, // NEW TAI LUE LETTER HIGH YA + { 0x198B, BIDI_L }, // NEW TAI LUE LETTER LOW TSA + { 0x198C, BIDI_L }, // NEW TAI LUE LETTER LOW SA + { 0x198D, BIDI_L }, // NEW TAI LUE LETTER LOW YA + { 0x198E, BIDI_L }, // NEW TAI LUE LETTER HIGH TA + { 0x198F, BIDI_L }, // NEW TAI LUE LETTER HIGH THA + { 0x1990, BIDI_L }, // NEW TAI LUE LETTER HIGH NA + { 0x1991, BIDI_L }, // NEW TAI LUE LETTER LOW TA + { 0x1992, BIDI_L }, // NEW TAI LUE LETTER LOW THA + { 0x1993, BIDI_L }, // NEW TAI LUE LETTER LOW NA + { 0x1994, BIDI_L }, // NEW TAI LUE LETTER HIGH PA + { 0x1995, BIDI_L }, // NEW TAI LUE LETTER HIGH PHA + { 0x1996, BIDI_L }, // NEW TAI LUE LETTER HIGH MA + { 0x1997, BIDI_L }, // NEW TAI LUE LETTER LOW PA + { 0x1998, BIDI_L }, // NEW TAI LUE LETTER LOW PHA + { 0x1999, BIDI_L }, // NEW TAI LUE LETTER LOW MA + { 0x199A, BIDI_L }, // NEW TAI LUE LETTER HIGH FA + { 0x199B, BIDI_L }, // NEW TAI LUE LETTER HIGH VA + { 0x199C, BIDI_L }, // NEW TAI LUE LETTER HIGH LA + { 0x199D, BIDI_L }, // NEW TAI LUE LETTER LOW FA + { 0x199E, BIDI_L }, // NEW TAI LUE LETTER LOW VA + { 0x199F, BIDI_L }, // NEW TAI LUE LETTER LOW LA + { 0x19A0, BIDI_L }, // NEW TAI LUE LETTER HIGH HA + { 0x19A1, BIDI_L }, // NEW TAI LUE LETTER HIGH DA + { 0x19A2, BIDI_L }, // NEW TAI LUE LETTER HIGH BA + { 0x19A3, BIDI_L }, // NEW TAI LUE LETTER LOW HA + { 0x19A4, BIDI_L }, // NEW TAI LUE LETTER LOW DA + { 0x19A5, BIDI_L }, // NEW TAI LUE LETTER LOW BA + { 0x19A6, BIDI_L }, // NEW TAI LUE LETTER HIGH KVA + { 0x19A7, BIDI_L }, // NEW TAI LUE LETTER HIGH XVA + { 0x19A8, BIDI_L }, // NEW TAI LUE LETTER LOW KVA + { 0x19A9, BIDI_L }, // NEW TAI LUE LETTER LOW XVA + { 0x19AA, BIDI_L }, // NEW TAI LUE LETTER HIGH SUA + { 0x19AB, BIDI_L }, // NEW TAI LUE LETTER LOW SUA + { 0x19B0, BIDI_L }, // NEW TAI LUE VOWEL SIGN VOWEL SHORTENER + { 0x19B1, BIDI_L }, // NEW TAI LUE VOWEL SIGN AA + { 0x19B2, BIDI_L }, // NEW TAI LUE VOWEL SIGN II + { 0x19B3, BIDI_L }, // NEW TAI LUE VOWEL SIGN U + { 0x19B4, BIDI_L }, // NEW TAI LUE VOWEL SIGN UU + { 0x19B5, BIDI_L }, // NEW TAI LUE VOWEL SIGN E + { 0x19B6, BIDI_L }, // NEW TAI LUE VOWEL SIGN AE + { 0x19B7, BIDI_L }, // NEW TAI LUE VOWEL SIGN O + { 0x19B8, BIDI_L }, // NEW TAI LUE VOWEL SIGN OA + { 0x19B9, BIDI_L }, // NEW TAI LUE VOWEL SIGN UE + { 0x19BA, BIDI_L }, // NEW TAI LUE VOWEL SIGN AY + { 0x19BB, BIDI_L }, // NEW TAI LUE VOWEL SIGN AAY + { 0x19BC, BIDI_L }, // NEW TAI LUE VOWEL SIGN UY + { 0x19BD, BIDI_L }, // NEW TAI LUE VOWEL SIGN OY + { 0x19BE, BIDI_L }, // NEW TAI LUE VOWEL SIGN OAY + { 0x19BF, BIDI_L }, // NEW TAI LUE VOWEL SIGN UEY + { 0x19C0, BIDI_L }, // NEW TAI LUE VOWEL SIGN IY + { 0x19C1, BIDI_L }, // NEW TAI LUE LETTER FINAL V + { 0x19C2, BIDI_L }, // NEW TAI LUE LETTER FINAL NG + { 0x19C3, BIDI_L }, // NEW TAI LUE LETTER FINAL N + { 0x19C4, BIDI_L }, // NEW TAI LUE LETTER FINAL M + { 0x19C5, BIDI_L }, // NEW TAI LUE LETTER FINAL K + { 0x19C6, BIDI_L }, // NEW TAI LUE LETTER FINAL D + { 0x19C7, BIDI_L }, // NEW TAI LUE LETTER FINAL B + { 0x19C8, BIDI_L }, // NEW TAI LUE TONE MARK-1 + { 0x19C9, BIDI_L }, // NEW TAI LUE TONE MARK-2 + { 0x19D0, BIDI_L }, // NEW TAI LUE DIGIT ZERO + { 0x19D1, BIDI_L }, // NEW TAI LUE DIGIT ONE + { 0x19D2, BIDI_L }, // NEW TAI LUE DIGIT TWO + { 0x19D3, BIDI_L }, // NEW TAI LUE DIGIT THREE + { 0x19D4, BIDI_L }, // NEW TAI LUE DIGIT FOUR + { 0x19D5, BIDI_L }, // NEW TAI LUE DIGIT FIVE + { 0x19D6, BIDI_L }, // NEW TAI LUE DIGIT SIX + { 0x19D7, BIDI_L }, // NEW TAI LUE DIGIT SEVEN + { 0x19D8, BIDI_L }, // NEW TAI LUE DIGIT EIGHT + { 0x19D9, BIDI_L }, // NEW TAI LUE DIGIT NINE + { 0x19DA, BIDI_L }, // NEW TAI LUE THAM DIGIT ONE + { 0x19DE, BIDI_ON }, // NEW TAI LUE SIGN LAE + { 0x19DF, BIDI_ON }, // NEW TAI LUE SIGN LAEV + { 0x19E0, BIDI_ON }, // KHMER SYMBOL PATHAMASAT + { 0x19E1, BIDI_ON }, // KHMER SYMBOL MUOY KOET + { 0x19E2, BIDI_ON }, // KHMER SYMBOL PII KOET + { 0x19E3, BIDI_ON }, // KHMER SYMBOL BEI KOET + { 0x19E4, BIDI_ON }, // KHMER SYMBOL BUON KOET + { 0x19E5, BIDI_ON }, // KHMER SYMBOL PRAM KOET + { 0x19E6, BIDI_ON }, // KHMER SYMBOL PRAM-MUOY KOET + { 0x19E7, BIDI_ON }, // KHMER SYMBOL PRAM-PII KOET + { 0x19E8, BIDI_ON }, // KHMER SYMBOL PRAM-BEI KOET + { 0x19E9, BIDI_ON }, // KHMER SYMBOL PRAM-BUON KOET + { 0x19EA, BIDI_ON }, // KHMER SYMBOL DAP KOET + { 0x19EB, BIDI_ON }, // KHMER SYMBOL DAP-MUOY KOET + { 0x19EC, BIDI_ON }, // KHMER SYMBOL DAP-PII KOET + { 0x19ED, BIDI_ON }, // KHMER SYMBOL DAP-BEI KOET + { 0x19EE, BIDI_ON }, // KHMER SYMBOL DAP-BUON KOET + { 0x19EF, BIDI_ON }, // KHMER SYMBOL DAP-PRAM KOET + { 0x19F0, BIDI_ON }, // KHMER SYMBOL TUTEYASAT + { 0x19F1, BIDI_ON }, // KHMER SYMBOL MUOY ROC + { 0x19F2, BIDI_ON }, // KHMER SYMBOL PII ROC + { 0x19F3, BIDI_ON }, // KHMER SYMBOL BEI ROC + { 0x19F4, BIDI_ON }, // KHMER SYMBOL BUON ROC + { 0x19F5, BIDI_ON }, // KHMER SYMBOL PRAM ROC + { 0x19F6, BIDI_ON }, // KHMER SYMBOL PRAM-MUOY ROC + { 0x19F7, BIDI_ON }, // KHMER SYMBOL PRAM-PII ROC + { 0x19F8, BIDI_ON }, // KHMER SYMBOL PRAM-BEI ROC + { 0x19F9, BIDI_ON }, // KHMER SYMBOL PRAM-BUON ROC + { 0x19FA, BIDI_ON }, // KHMER SYMBOL DAP ROC + { 0x19FB, BIDI_ON }, // KHMER SYMBOL DAP-MUOY ROC + { 0x19FC, BIDI_ON }, // KHMER SYMBOL DAP-PII ROC + { 0x19FD, BIDI_ON }, // KHMER SYMBOL DAP-BEI ROC + { 0x19FE, BIDI_ON }, // KHMER SYMBOL DAP-BUON ROC + { 0x19FF, BIDI_ON }, // KHMER SYMBOL DAP-PRAM ROC + { 0x1A00, BIDI_L }, // BUGINESE LETTER KA + { 0x1A01, BIDI_L }, // BUGINESE LETTER GA + { 0x1A02, BIDI_L }, // BUGINESE LETTER NGA + { 0x1A03, BIDI_L }, // BUGINESE LETTER NGKA + { 0x1A04, BIDI_L }, // BUGINESE LETTER PA + { 0x1A05, BIDI_L }, // BUGINESE LETTER BA + { 0x1A06, BIDI_L }, // BUGINESE LETTER MA + { 0x1A07, BIDI_L }, // BUGINESE LETTER MPA + { 0x1A08, BIDI_L }, // BUGINESE LETTER TA + { 0x1A09, BIDI_L }, // BUGINESE LETTER DA + { 0x1A0A, BIDI_L }, // BUGINESE LETTER NA + { 0x1A0B, BIDI_L }, // BUGINESE LETTER NRA + { 0x1A0C, BIDI_L }, // BUGINESE LETTER CA + { 0x1A0D, BIDI_L }, // BUGINESE LETTER JA + { 0x1A0E, BIDI_L }, // BUGINESE LETTER NYA + { 0x1A0F, BIDI_L }, // BUGINESE LETTER NYCA + { 0x1A10, BIDI_L }, // BUGINESE LETTER YA + { 0x1A11, BIDI_L }, // BUGINESE LETTER RA + { 0x1A12, BIDI_L }, // BUGINESE LETTER LA + { 0x1A13, BIDI_L }, // BUGINESE LETTER VA + { 0x1A14, BIDI_L }, // BUGINESE LETTER SA + { 0x1A15, BIDI_L }, // BUGINESE LETTER A + { 0x1A16, BIDI_L }, // BUGINESE LETTER HA + { 0x1A17, BIDI_NSM }, // BUGINESE VOWEL SIGN I + { 0x1A18, BIDI_NSM }, // BUGINESE VOWEL SIGN U + { 0x1A19, BIDI_L }, // BUGINESE VOWEL SIGN E + { 0x1A1A, BIDI_L }, // BUGINESE VOWEL SIGN O + { 0x1A1B, BIDI_NSM }, // BUGINESE VOWEL SIGN AE + { 0x1A1E, BIDI_L }, // BUGINESE PALLAWA + { 0x1A1F, BIDI_L }, // BUGINESE END OF SECTION + { 0x1A20, BIDI_L }, // TAI THAM LETTER HIGH KA + { 0x1A21, BIDI_L }, // TAI THAM LETTER HIGH KHA + { 0x1A22, BIDI_L }, // TAI THAM LETTER HIGH KXA + { 0x1A23, BIDI_L }, // TAI THAM LETTER LOW KA + { 0x1A24, BIDI_L }, // TAI THAM LETTER LOW KXA + { 0x1A25, BIDI_L }, // TAI THAM LETTER LOW KHA + { 0x1A26, BIDI_L }, // TAI THAM LETTER NGA + { 0x1A27, BIDI_L }, // TAI THAM LETTER HIGH CA + { 0x1A28, BIDI_L }, // TAI THAM LETTER HIGH CHA + { 0x1A29, BIDI_L }, // TAI THAM LETTER LOW CA + { 0x1A2A, BIDI_L }, // TAI THAM LETTER LOW SA + { 0x1A2B, BIDI_L }, // TAI THAM LETTER LOW CHA + { 0x1A2C, BIDI_L }, // TAI THAM LETTER NYA + { 0x1A2D, BIDI_L }, // TAI THAM LETTER RATA + { 0x1A2E, BIDI_L }, // TAI THAM LETTER HIGH RATHA + { 0x1A2F, BIDI_L }, // TAI THAM LETTER DA + { 0x1A30, BIDI_L }, // TAI THAM LETTER LOW RATHA + { 0x1A31, BIDI_L }, // TAI THAM LETTER RANA + { 0x1A32, BIDI_L }, // TAI THAM LETTER HIGH TA + { 0x1A33, BIDI_L }, // TAI THAM LETTER HIGH THA + { 0x1A34, BIDI_L }, // TAI THAM LETTER LOW TA + { 0x1A35, BIDI_L }, // TAI THAM LETTER LOW THA + { 0x1A36, BIDI_L }, // TAI THAM LETTER NA + { 0x1A37, BIDI_L }, // TAI THAM LETTER BA + { 0x1A38, BIDI_L }, // TAI THAM LETTER HIGH PA + { 0x1A39, BIDI_L }, // TAI THAM LETTER HIGH PHA + { 0x1A3A, BIDI_L }, // TAI THAM LETTER HIGH FA + { 0x1A3B, BIDI_L }, // TAI THAM LETTER LOW PA + { 0x1A3C, BIDI_L }, // TAI THAM LETTER LOW FA + { 0x1A3D, BIDI_L }, // TAI THAM LETTER LOW PHA + { 0x1A3E, BIDI_L }, // TAI THAM LETTER MA + { 0x1A3F, BIDI_L }, // TAI THAM LETTER LOW YA + { 0x1A40, BIDI_L }, // TAI THAM LETTER HIGH YA + { 0x1A41, BIDI_L }, // TAI THAM LETTER RA + { 0x1A42, BIDI_L }, // TAI THAM LETTER RUE + { 0x1A43, BIDI_L }, // TAI THAM LETTER LA + { 0x1A44, BIDI_L }, // TAI THAM LETTER LUE + { 0x1A45, BIDI_L }, // TAI THAM LETTER WA + { 0x1A46, BIDI_L }, // TAI THAM LETTER HIGH SHA + { 0x1A47, BIDI_L }, // TAI THAM LETTER HIGH SSA + { 0x1A48, BIDI_L }, // TAI THAM LETTER HIGH SA + { 0x1A49, BIDI_L }, // TAI THAM LETTER HIGH HA + { 0x1A4A, BIDI_L }, // TAI THAM LETTER LLA + { 0x1A4B, BIDI_L }, // TAI THAM LETTER A + { 0x1A4C, BIDI_L }, // TAI THAM LETTER LOW HA + { 0x1A4D, BIDI_L }, // TAI THAM LETTER I + { 0x1A4E, BIDI_L }, // TAI THAM LETTER II + { 0x1A4F, BIDI_L }, // TAI THAM LETTER U + { 0x1A50, BIDI_L }, // TAI THAM LETTER UU + { 0x1A51, BIDI_L }, // TAI THAM LETTER EE + { 0x1A52, BIDI_L }, // TAI THAM LETTER OO + { 0x1A53, BIDI_L }, // TAI THAM LETTER LAE + { 0x1A54, BIDI_L }, // TAI THAM LETTER GREAT SA + { 0x1A55, BIDI_L }, // TAI THAM CONSONANT SIGN MEDIAL RA + { 0x1A56, BIDI_NSM }, // TAI THAM CONSONANT SIGN MEDIAL LA + { 0x1A57, BIDI_L }, // TAI THAM CONSONANT SIGN LA TANG LAI + { 0x1A58, BIDI_NSM }, // TAI THAM SIGN MAI KANG LAI + { 0x1A59, BIDI_NSM }, // TAI THAM CONSONANT SIGN FINAL NGA + { 0x1A5A, BIDI_NSM }, // TAI THAM CONSONANT SIGN LOW PA + { 0x1A5B, BIDI_NSM }, // TAI THAM CONSONANT SIGN HIGH RATHA OR LOW PA + { 0x1A5C, BIDI_NSM }, // TAI THAM CONSONANT SIGN MA + { 0x1A5D, BIDI_NSM }, // TAI THAM CONSONANT SIGN BA + { 0x1A5E, BIDI_NSM }, // TAI THAM CONSONANT SIGN SA + { 0x1A60, BIDI_NSM }, // TAI THAM SIGN SAKOT + { 0x1A61, BIDI_L }, // TAI THAM VOWEL SIGN A + { 0x1A62, BIDI_NSM }, // TAI THAM VOWEL SIGN MAI SAT + { 0x1A63, BIDI_L }, // TAI THAM VOWEL SIGN AA + { 0x1A64, BIDI_L }, // TAI THAM VOWEL SIGN TALL AA + { 0x1A65, BIDI_NSM }, // TAI THAM VOWEL SIGN I + { 0x1A66, BIDI_NSM }, // TAI THAM VOWEL SIGN II + { 0x1A67, BIDI_NSM }, // TAI THAM VOWEL SIGN UE + { 0x1A68, BIDI_NSM }, // TAI THAM VOWEL SIGN UUE + { 0x1A69, BIDI_NSM }, // TAI THAM VOWEL SIGN U + { 0x1A6A, BIDI_NSM }, // TAI THAM VOWEL SIGN UU + { 0x1A6B, BIDI_NSM }, // TAI THAM VOWEL SIGN O + { 0x1A6C, BIDI_NSM }, // TAI THAM VOWEL SIGN OA BELOW + { 0x1A6D, BIDI_L }, // TAI THAM VOWEL SIGN OY + { 0x1A6E, BIDI_L }, // TAI THAM VOWEL SIGN E + { 0x1A6F, BIDI_L }, // TAI THAM VOWEL SIGN AE + { 0x1A70, BIDI_L }, // TAI THAM VOWEL SIGN OO + { 0x1A71, BIDI_L }, // TAI THAM VOWEL SIGN AI + { 0x1A72, BIDI_L }, // TAI THAM VOWEL SIGN THAM AI + { 0x1A73, BIDI_NSM }, // TAI THAM VOWEL SIGN OA ABOVE + { 0x1A74, BIDI_NSM }, // TAI THAM SIGN MAI KANG + { 0x1A75, BIDI_NSM }, // TAI THAM SIGN TONE-1 + { 0x1A76, BIDI_NSM }, // TAI THAM SIGN TONE-2 + { 0x1A77, BIDI_NSM }, // TAI THAM SIGN KHUEN TONE-3 + { 0x1A78, BIDI_NSM }, // TAI THAM SIGN KHUEN TONE-4 + { 0x1A79, BIDI_NSM }, // TAI THAM SIGN KHUEN TONE-5 + { 0x1A7A, BIDI_NSM }, // TAI THAM SIGN RA HAAM + { 0x1A7B, BIDI_NSM }, // TAI THAM SIGN MAI SAM + { 0x1A7C, BIDI_NSM }, // TAI THAM SIGN KHUEN-LUE KARAN + { 0x1A7F, BIDI_NSM }, // TAI THAM COMBINING CRYPTOGRAMMIC DOT + { 0x1A80, BIDI_L }, // TAI THAM HORA DIGIT ZERO + { 0x1A81, BIDI_L }, // TAI THAM HORA DIGIT ONE + { 0x1A82, BIDI_L }, // TAI THAM HORA DIGIT TWO + { 0x1A83, BIDI_L }, // TAI THAM HORA DIGIT THREE + { 0x1A84, BIDI_L }, // TAI THAM HORA DIGIT FOUR + { 0x1A85, BIDI_L }, // TAI THAM HORA DIGIT FIVE + { 0x1A86, BIDI_L }, // TAI THAM HORA DIGIT SIX + { 0x1A87, BIDI_L }, // TAI THAM HORA DIGIT SEVEN + { 0x1A88, BIDI_L }, // TAI THAM HORA DIGIT EIGHT + { 0x1A89, BIDI_L }, // TAI THAM HORA DIGIT NINE + { 0x1A90, BIDI_L }, // TAI THAM THAM DIGIT ZERO + { 0x1A91, BIDI_L }, // TAI THAM THAM DIGIT ONE + { 0x1A92, BIDI_L }, // TAI THAM THAM DIGIT TWO + { 0x1A93, BIDI_L }, // TAI THAM THAM DIGIT THREE + { 0x1A94, BIDI_L }, // TAI THAM THAM DIGIT FOUR + { 0x1A95, BIDI_L }, // TAI THAM THAM DIGIT FIVE + { 0x1A96, BIDI_L }, // TAI THAM THAM DIGIT SIX + { 0x1A97, BIDI_L }, // TAI THAM THAM DIGIT SEVEN + { 0x1A98, BIDI_L }, // TAI THAM THAM DIGIT EIGHT + { 0x1A99, BIDI_L }, // TAI THAM THAM DIGIT NINE + { 0x1AA0, BIDI_L }, // TAI THAM SIGN WIANG + { 0x1AA1, BIDI_L }, // TAI THAM SIGN WIANGWAAK + { 0x1AA2, BIDI_L }, // TAI THAM SIGN SAWAN + { 0x1AA3, BIDI_L }, // TAI THAM SIGN KEOW + { 0x1AA4, BIDI_L }, // TAI THAM SIGN HOY + { 0x1AA5, BIDI_L }, // TAI THAM SIGN DOKMAI + { 0x1AA6, BIDI_L }, // TAI THAM SIGN REVERSED ROTATED RANA + { 0x1AA7, BIDI_L }, // TAI THAM SIGN MAI YAMOK + { 0x1AA8, BIDI_L }, // TAI THAM SIGN KAAN + { 0x1AA9, BIDI_L }, // TAI THAM SIGN KAANKUU + { 0x1AAA, BIDI_L }, // TAI THAM SIGN SATKAAN + { 0x1AAB, BIDI_L }, // TAI THAM SIGN SATKAANKUU + { 0x1AAC, BIDI_L }, // TAI THAM SIGN HANG + { 0x1AAD, BIDI_L }, // TAI THAM SIGN CAANG + { 0x1AB0, BIDI_NSM }, // COMBINING DOUBLED CIRCUMFLEX ACCENT + { 0x1AB1, BIDI_NSM }, // COMBINING DIAERESIS-RING + { 0x1AB2, BIDI_NSM }, // COMBINING INFINITY + { 0x1AB3, BIDI_NSM }, // COMBINING DOWNWARDS ARROW + { 0x1AB4, BIDI_NSM }, // COMBINING TRIPLE DOT + { 0x1AB5, BIDI_NSM }, // COMBINING X-X BELOW + { 0x1AB6, BIDI_NSM }, // COMBINING WIGGLY LINE BELOW + { 0x1AB7, BIDI_NSM }, // COMBINING OPEN MARK BELOW + { 0x1AB8, BIDI_NSM }, // COMBINING DOUBLE OPEN MARK BELOW + { 0x1AB9, BIDI_NSM }, // COMBINING LIGHT CENTRALIZATION STROKE BELOW + { 0x1ABA, BIDI_NSM }, // COMBINING STRONG CENTRALIZATION STROKE BELOW + { 0x1ABB, BIDI_NSM }, // COMBINING PARENTHESES ABOVE + { 0x1ABC, BIDI_NSM }, // COMBINING DOUBLE PARENTHESES ABOVE + { 0x1ABD, BIDI_NSM }, // COMBINING PARENTHESES BELOW + { 0x1ABE, BIDI_NSM }, // COMBINING PARENTHESES OVERLAY + { 0x1B00, BIDI_NSM }, // BALINESE SIGN ULU RICEM + { 0x1B01, BIDI_NSM }, // BALINESE SIGN ULU CANDRA + { 0x1B02, BIDI_NSM }, // BALINESE SIGN CECEK + { 0x1B03, BIDI_NSM }, // BALINESE SIGN SURANG + { 0x1B04, BIDI_L }, // BALINESE SIGN BISAH + { 0x1B05, BIDI_L }, // BALINESE LETTER AKARA + { 0x1B06, BIDI_L }, // BALINESE LETTER AKARA TEDUNG + { 0x1B07, BIDI_L }, // BALINESE LETTER IKARA + { 0x1B08, BIDI_L }, // BALINESE LETTER IKARA TEDUNG + { 0x1B09, BIDI_L }, // BALINESE LETTER UKARA + { 0x1B0A, BIDI_L }, // BALINESE LETTER UKARA TEDUNG + { 0x1B0B, BIDI_L }, // BALINESE LETTER RA REPA + { 0x1B0C, BIDI_L }, // BALINESE LETTER RA REPA TEDUNG + { 0x1B0D, BIDI_L }, // BALINESE LETTER LA LENGA + { 0x1B0E, BIDI_L }, // BALINESE LETTER LA LENGA TEDUNG + { 0x1B0F, BIDI_L }, // BALINESE LETTER EKARA + { 0x1B10, BIDI_L }, // BALINESE LETTER AIKARA + { 0x1B11, BIDI_L }, // BALINESE LETTER OKARA + { 0x1B12, BIDI_L }, // BALINESE LETTER OKARA TEDUNG + { 0x1B13, BIDI_L }, // BALINESE LETTER KA + { 0x1B14, BIDI_L }, // BALINESE LETTER KA MAHAPRANA + { 0x1B15, BIDI_L }, // BALINESE LETTER GA + { 0x1B16, BIDI_L }, // BALINESE LETTER GA GORA + { 0x1B17, BIDI_L }, // BALINESE LETTER NGA + { 0x1B18, BIDI_L }, // BALINESE LETTER CA + { 0x1B19, BIDI_L }, // BALINESE LETTER CA LACA + { 0x1B1A, BIDI_L }, // BALINESE LETTER JA + { 0x1B1B, BIDI_L }, // BALINESE LETTER JA JERA + { 0x1B1C, BIDI_L }, // BALINESE LETTER NYA + { 0x1B1D, BIDI_L }, // BALINESE LETTER TA LATIK + { 0x1B1E, BIDI_L }, // BALINESE LETTER TA MURDA MAHAPRANA + { 0x1B1F, BIDI_L }, // BALINESE LETTER DA MURDA ALPAPRANA + { 0x1B20, BIDI_L }, // BALINESE LETTER DA MURDA MAHAPRANA + { 0x1B21, BIDI_L }, // BALINESE LETTER NA RAMBAT + { 0x1B22, BIDI_L }, // BALINESE LETTER TA + { 0x1B23, BIDI_L }, // BALINESE LETTER TA TAWA + { 0x1B24, BIDI_L }, // BALINESE LETTER DA + { 0x1B25, BIDI_L }, // BALINESE LETTER DA MADU + { 0x1B26, BIDI_L }, // BALINESE LETTER NA + { 0x1B27, BIDI_L }, // BALINESE LETTER PA + { 0x1B28, BIDI_L }, // BALINESE LETTER PA KAPAL + { 0x1B29, BIDI_L }, // BALINESE LETTER BA + { 0x1B2A, BIDI_L }, // BALINESE LETTER BA KEMBANG + { 0x1B2B, BIDI_L }, // BALINESE LETTER MA + { 0x1B2C, BIDI_L }, // BALINESE LETTER YA + { 0x1B2D, BIDI_L }, // BALINESE LETTER RA + { 0x1B2E, BIDI_L }, // BALINESE LETTER LA + { 0x1B2F, BIDI_L }, // BALINESE LETTER WA + { 0x1B30, BIDI_L }, // BALINESE LETTER SA SAGA + { 0x1B31, BIDI_L }, // BALINESE LETTER SA SAPA + { 0x1B32, BIDI_L }, // BALINESE LETTER SA + { 0x1B33, BIDI_L }, // BALINESE LETTER HA + { 0x1B34, BIDI_NSM }, // BALINESE SIGN REREKAN + { 0x1B35, BIDI_L }, // BALINESE VOWEL SIGN TEDUNG + { 0x1B36, BIDI_NSM }, // BALINESE VOWEL SIGN ULU + { 0x1B37, BIDI_NSM }, // BALINESE VOWEL SIGN ULU SARI + { 0x1B38, BIDI_NSM }, // BALINESE VOWEL SIGN SUKU + { 0x1B39, BIDI_NSM }, // BALINESE VOWEL SIGN SUKU ILUT + { 0x1B3A, BIDI_NSM }, // BALINESE VOWEL SIGN RA REPA + { 0x1B3B, BIDI_L }, // BALINESE VOWEL SIGN RA REPA TEDUNG + { 0x1B3C, BIDI_NSM }, // BALINESE VOWEL SIGN LA LENGA + { 0x1B3D, BIDI_L }, // BALINESE VOWEL SIGN LA LENGA TEDUNG + { 0x1B3E, BIDI_L }, // BALINESE VOWEL SIGN TALING + { 0x1B3F, BIDI_L }, // BALINESE VOWEL SIGN TALING REPA + { 0x1B40, BIDI_L }, // BALINESE VOWEL SIGN TALING TEDUNG + { 0x1B41, BIDI_L }, // BALINESE VOWEL SIGN TALING REPA TEDUNG + { 0x1B42, BIDI_NSM }, // BALINESE VOWEL SIGN PEPET + { 0x1B43, BIDI_L }, // BALINESE VOWEL SIGN PEPET TEDUNG + { 0x1B44, BIDI_L }, // BALINESE ADEG ADEG + { 0x1B45, BIDI_L }, // BALINESE LETTER KAF SASAK + { 0x1B46, BIDI_L }, // BALINESE LETTER KHOT SASAK + { 0x1B47, BIDI_L }, // BALINESE LETTER TZIR SASAK + { 0x1B48, BIDI_L }, // BALINESE LETTER EF SASAK + { 0x1B49, BIDI_L }, // BALINESE LETTER VE SASAK + { 0x1B4A, BIDI_L }, // BALINESE LETTER ZAL SASAK + { 0x1B4B, BIDI_L }, // BALINESE LETTER ASYURA SASAK + { 0x1B50, BIDI_L }, // BALINESE DIGIT ZERO + { 0x1B51, BIDI_L }, // BALINESE DIGIT ONE + { 0x1B52, BIDI_L }, // BALINESE DIGIT TWO + { 0x1B53, BIDI_L }, // BALINESE DIGIT THREE + { 0x1B54, BIDI_L }, // BALINESE DIGIT FOUR + { 0x1B55, BIDI_L }, // BALINESE DIGIT FIVE + { 0x1B56, BIDI_L }, // BALINESE DIGIT SIX + { 0x1B57, BIDI_L }, // BALINESE DIGIT SEVEN + { 0x1B58, BIDI_L }, // BALINESE DIGIT EIGHT + { 0x1B59, BIDI_L }, // BALINESE DIGIT NINE + { 0x1B5A, BIDI_L }, // BALINESE PANTI + { 0x1B5B, BIDI_L }, // BALINESE PAMADA + { 0x1B5C, BIDI_L }, // BALINESE WINDU + { 0x1B5D, BIDI_L }, // BALINESE CARIK PAMUNGKAH + { 0x1B5E, BIDI_L }, // BALINESE CARIK SIKI + { 0x1B5F, BIDI_L }, // BALINESE CARIK PAREREN + { 0x1B60, BIDI_L }, // BALINESE PAMENENG + { 0x1B61, BIDI_L }, // BALINESE MUSICAL SYMBOL DONG + { 0x1B62, BIDI_L }, // BALINESE MUSICAL SYMBOL DENG + { 0x1B63, BIDI_L }, // BALINESE MUSICAL SYMBOL DUNG + { 0x1B64, BIDI_L }, // BALINESE MUSICAL SYMBOL DANG + { 0x1B65, BIDI_L }, // BALINESE MUSICAL SYMBOL DANG SURANG + { 0x1B66, BIDI_L }, // BALINESE MUSICAL SYMBOL DING + { 0x1B67, BIDI_L }, // BALINESE MUSICAL SYMBOL DAENG + { 0x1B68, BIDI_L }, // BALINESE MUSICAL SYMBOL DEUNG + { 0x1B69, BIDI_L }, // BALINESE MUSICAL SYMBOL DAING + { 0x1B6A, BIDI_L }, // BALINESE MUSICAL SYMBOL DANG GEDE + { 0x1B6B, BIDI_NSM }, // BALINESE MUSICAL SYMBOL COMBINING TEGEH + { 0x1B6C, BIDI_NSM }, // BALINESE MUSICAL SYMBOL COMBINING ENDEP + { 0x1B6D, BIDI_NSM }, // BALINESE MUSICAL SYMBOL COMBINING KEMPUL + { 0x1B6E, BIDI_NSM }, // BALINESE MUSICAL SYMBOL COMBINING KEMPLI + { 0x1B6F, BIDI_NSM }, // BALINESE MUSICAL SYMBOL COMBINING JEGOGAN + { 0x1B70, BIDI_NSM }, // BALINESE MUSICAL SYMBOL COMBINING KEMPUL WITH JEGOGAN + { 0x1B71, BIDI_NSM }, // BALINESE MUSICAL SYMBOL COMBINING KEMPLI WITH JEGOGAN + { 0x1B72, BIDI_NSM }, // BALINESE MUSICAL SYMBOL COMBINING BENDE + { 0x1B73, BIDI_NSM }, // BALINESE MUSICAL SYMBOL COMBINING GONG + { 0x1B74, BIDI_L }, // BALINESE MUSICAL SYMBOL RIGHT-HAND OPEN DUG + { 0x1B75, BIDI_L }, // BALINESE MUSICAL SYMBOL RIGHT-HAND OPEN DAG + { 0x1B76, BIDI_L }, // BALINESE MUSICAL SYMBOL RIGHT-HAND CLOSED TUK + { 0x1B77, BIDI_L }, // BALINESE MUSICAL SYMBOL RIGHT-HAND CLOSED TAK + { 0x1B78, BIDI_L }, // BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PANG + { 0x1B79, BIDI_L }, // BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PUNG + { 0x1B7A, BIDI_L }, // BALINESE MUSICAL SYMBOL LEFT-HAND CLOSED PLAK + { 0x1B7B, BIDI_L }, // BALINESE MUSICAL SYMBOL LEFT-HAND CLOSED PLUK + { 0x1B7C, BIDI_L }, // BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PING + { 0x1B80, BIDI_NSM }, // SUNDANESE SIGN PANYECEK + { 0x1B81, BIDI_NSM }, // SUNDANESE SIGN PANGLAYAR + { 0x1B82, BIDI_L }, // SUNDANESE SIGN PANGWISAD + { 0x1B83, BIDI_L }, // SUNDANESE LETTER A + { 0x1B84, BIDI_L }, // SUNDANESE LETTER I + { 0x1B85, BIDI_L }, // SUNDANESE LETTER U + { 0x1B86, BIDI_L }, // SUNDANESE LETTER AE + { 0x1B87, BIDI_L }, // SUNDANESE LETTER O + { 0x1B88, BIDI_L }, // SUNDANESE LETTER E + { 0x1B89, BIDI_L }, // SUNDANESE LETTER EU + { 0x1B8A, BIDI_L }, // SUNDANESE LETTER KA + { 0x1B8B, BIDI_L }, // SUNDANESE LETTER QA + { 0x1B8C, BIDI_L }, // SUNDANESE LETTER GA + { 0x1B8D, BIDI_L }, // SUNDANESE LETTER NGA + { 0x1B8E, BIDI_L }, // SUNDANESE LETTER CA + { 0x1B8F, BIDI_L }, // SUNDANESE LETTER JA + { 0x1B90, BIDI_L }, // SUNDANESE LETTER ZA + { 0x1B91, BIDI_L }, // SUNDANESE LETTER NYA + { 0x1B92, BIDI_L }, // SUNDANESE LETTER TA + { 0x1B93, BIDI_L }, // SUNDANESE LETTER DA + { 0x1B94, BIDI_L }, // SUNDANESE LETTER NA + { 0x1B95, BIDI_L }, // SUNDANESE LETTER PA + { 0x1B96, BIDI_L }, // SUNDANESE LETTER FA + { 0x1B97, BIDI_L }, // SUNDANESE LETTER VA + { 0x1B98, BIDI_L }, // SUNDANESE LETTER BA + { 0x1B99, BIDI_L }, // SUNDANESE LETTER MA + { 0x1B9A, BIDI_L }, // SUNDANESE LETTER YA + { 0x1B9B, BIDI_L }, // SUNDANESE LETTER RA + { 0x1B9C, BIDI_L }, // SUNDANESE LETTER LA + { 0x1B9D, BIDI_L }, // SUNDANESE LETTER WA + { 0x1B9E, BIDI_L }, // SUNDANESE LETTER SA + { 0x1B9F, BIDI_L }, // SUNDANESE LETTER XA + { 0x1BA0, BIDI_L }, // SUNDANESE LETTER HA + { 0x1BA1, BIDI_L }, // SUNDANESE CONSONANT SIGN PAMINGKAL + { 0x1BA2, BIDI_NSM }, // SUNDANESE CONSONANT SIGN PANYAKRA + { 0x1BA3, BIDI_NSM }, // SUNDANESE CONSONANT SIGN PANYIKU + { 0x1BA4, BIDI_NSM }, // SUNDANESE VOWEL SIGN PANGHULU + { 0x1BA5, BIDI_NSM }, // SUNDANESE VOWEL SIGN PANYUKU + { 0x1BA6, BIDI_L }, // SUNDANESE VOWEL SIGN PANAELAENG + { 0x1BA7, BIDI_L }, // SUNDANESE VOWEL SIGN PANOLONG + { 0x1BA8, BIDI_NSM }, // SUNDANESE VOWEL SIGN PAMEPET + { 0x1BA9, BIDI_NSM }, // SUNDANESE VOWEL SIGN PANEULEUNG + { 0x1BAA, BIDI_L }, // SUNDANESE SIGN PAMAAEH + { 0x1BAB, BIDI_NSM }, // SUNDANESE SIGN VIRAMA + { 0x1BAC, BIDI_NSM }, // SUNDANESE CONSONANT SIGN PASANGAN MA + { 0x1BAD, BIDI_NSM }, // SUNDANESE CONSONANT SIGN PASANGAN WA + { 0x1BAE, BIDI_L }, // SUNDANESE LETTER KHA + { 0x1BAF, BIDI_L }, // SUNDANESE LETTER SYA + { 0x1BB0, BIDI_L }, // SUNDANESE DIGIT ZERO + { 0x1BB1, BIDI_L }, // SUNDANESE DIGIT ONE + { 0x1BB2, BIDI_L }, // SUNDANESE DIGIT TWO + { 0x1BB3, BIDI_L }, // SUNDANESE DIGIT THREE + { 0x1BB4, BIDI_L }, // SUNDANESE DIGIT FOUR + { 0x1BB5, BIDI_L }, // SUNDANESE DIGIT FIVE + { 0x1BB6, BIDI_L }, // SUNDANESE DIGIT SIX + { 0x1BB7, BIDI_L }, // SUNDANESE DIGIT SEVEN + { 0x1BB8, BIDI_L }, // SUNDANESE DIGIT EIGHT + { 0x1BB9, BIDI_L }, // SUNDANESE DIGIT NINE + { 0x1BBA, BIDI_L }, // SUNDANESE AVAGRAHA + { 0x1BBB, BIDI_L }, // SUNDANESE LETTER REU + { 0x1BBC, BIDI_L }, // SUNDANESE LETTER LEU + { 0x1BBD, BIDI_L }, // SUNDANESE LETTER BHA + { 0x1BBE, BIDI_L }, // SUNDANESE LETTER FINAL K + { 0x1BBF, BIDI_L }, // SUNDANESE LETTER FINAL M + { 0x1BC0, BIDI_L }, // BATAK LETTER A + { 0x1BC1, BIDI_L }, // BATAK LETTER SIMALUNGUN A + { 0x1BC2, BIDI_L }, // BATAK LETTER HA + { 0x1BC3, BIDI_L }, // BATAK LETTER SIMALUNGUN HA + { 0x1BC4, BIDI_L }, // BATAK LETTER MANDAILING HA + { 0x1BC5, BIDI_L }, // BATAK LETTER BA + { 0x1BC6, BIDI_L }, // BATAK LETTER KARO BA + { 0x1BC7, BIDI_L }, // BATAK LETTER PA + { 0x1BC8, BIDI_L }, // BATAK LETTER SIMALUNGUN PA + { 0x1BC9, BIDI_L }, // BATAK LETTER NA + { 0x1BCA, BIDI_L }, // BATAK LETTER MANDAILING NA + { 0x1BCB, BIDI_L }, // BATAK LETTER WA + { 0x1BCC, BIDI_L }, // BATAK LETTER SIMALUNGUN WA + { 0x1BCD, BIDI_L }, // BATAK LETTER PAKPAK WA + { 0x1BCE, BIDI_L }, // BATAK LETTER GA + { 0x1BCF, BIDI_L }, // BATAK LETTER SIMALUNGUN GA + { 0x1BD0, BIDI_L }, // BATAK LETTER JA + { 0x1BD1, BIDI_L }, // BATAK LETTER DA + { 0x1BD2, BIDI_L }, // BATAK LETTER RA + { 0x1BD3, BIDI_L }, // BATAK LETTER SIMALUNGUN RA + { 0x1BD4, BIDI_L }, // BATAK LETTER MA + { 0x1BD5, BIDI_L }, // BATAK LETTER SIMALUNGUN MA + { 0x1BD6, BIDI_L }, // BATAK LETTER SOUTHERN TA + { 0x1BD7, BIDI_L }, // BATAK LETTER NORTHERN TA + { 0x1BD8, BIDI_L }, // BATAK LETTER SA + { 0x1BD9, BIDI_L }, // BATAK LETTER SIMALUNGUN SA + { 0x1BDA, BIDI_L }, // BATAK LETTER MANDAILING SA + { 0x1BDB, BIDI_L }, // BATAK LETTER YA + { 0x1BDC, BIDI_L }, // BATAK LETTER SIMALUNGUN YA + { 0x1BDD, BIDI_L }, // BATAK LETTER NGA + { 0x1BDE, BIDI_L }, // BATAK LETTER LA + { 0x1BDF, BIDI_L }, // BATAK LETTER SIMALUNGUN LA + { 0x1BE0, BIDI_L }, // BATAK LETTER NYA + { 0x1BE1, BIDI_L }, // BATAK LETTER CA + { 0x1BE2, BIDI_L }, // BATAK LETTER NDA + { 0x1BE3, BIDI_L }, // BATAK LETTER MBA + { 0x1BE4, BIDI_L }, // BATAK LETTER I + { 0x1BE5, BIDI_L }, // BATAK LETTER U + { 0x1BE6, BIDI_NSM }, // BATAK SIGN TOMPI + { 0x1BE7, BIDI_L }, // BATAK VOWEL SIGN E + { 0x1BE8, BIDI_NSM }, // BATAK VOWEL SIGN PAKPAK E + { 0x1BE9, BIDI_NSM }, // BATAK VOWEL SIGN EE + { 0x1BEA, BIDI_L }, // BATAK VOWEL SIGN I + { 0x1BEB, BIDI_L }, // BATAK VOWEL SIGN KARO I + { 0x1BEC, BIDI_L }, // BATAK VOWEL SIGN O + { 0x1BED, BIDI_NSM }, // BATAK VOWEL SIGN KARO O + { 0x1BEE, BIDI_L }, // BATAK VOWEL SIGN U + { 0x1BEF, BIDI_NSM }, // BATAK VOWEL SIGN U FOR SIMALUNGUN SA + { 0x1BF0, BIDI_NSM }, // BATAK CONSONANT SIGN NG + { 0x1BF1, BIDI_NSM }, // BATAK CONSONANT SIGN H + { 0x1BF2, BIDI_L }, // BATAK PANGOLAT + { 0x1BF3, BIDI_L }, // BATAK PANONGONAN + { 0x1BFC, BIDI_L }, // BATAK SYMBOL BINDU NA METEK + { 0x1BFD, BIDI_L }, // BATAK SYMBOL BINDU PINARBORAS + { 0x1BFE, BIDI_L }, // BATAK SYMBOL BINDU JUDUL + { 0x1BFF, BIDI_L }, // BATAK SYMBOL BINDU PANGOLAT + { 0x1C00, BIDI_L }, // LEPCHA LETTER KA + { 0x1C01, BIDI_L }, // LEPCHA LETTER KLA + { 0x1C02, BIDI_L }, // LEPCHA LETTER KHA + { 0x1C03, BIDI_L }, // LEPCHA LETTER GA + { 0x1C04, BIDI_L }, // LEPCHA LETTER GLA + { 0x1C05, BIDI_L }, // LEPCHA LETTER NGA + { 0x1C06, BIDI_L }, // LEPCHA LETTER CA + { 0x1C07, BIDI_L }, // LEPCHA LETTER CHA + { 0x1C08, BIDI_L }, // LEPCHA LETTER JA + { 0x1C09, BIDI_L }, // LEPCHA LETTER NYA + { 0x1C0A, BIDI_L }, // LEPCHA LETTER TA + { 0x1C0B, BIDI_L }, // LEPCHA LETTER THA + { 0x1C0C, BIDI_L }, // LEPCHA LETTER DA + { 0x1C0D, BIDI_L }, // LEPCHA LETTER NA + { 0x1C0E, BIDI_L }, // LEPCHA LETTER PA + { 0x1C0F, BIDI_L }, // LEPCHA LETTER PLA + { 0x1C10, BIDI_L }, // LEPCHA LETTER PHA + { 0x1C11, BIDI_L }, // LEPCHA LETTER FA + { 0x1C12, BIDI_L }, // LEPCHA LETTER FLA + { 0x1C13, BIDI_L }, // LEPCHA LETTER BA + { 0x1C14, BIDI_L }, // LEPCHA LETTER BLA + { 0x1C15, BIDI_L }, // LEPCHA LETTER MA + { 0x1C16, BIDI_L }, // LEPCHA LETTER MLA + { 0x1C17, BIDI_L }, // LEPCHA LETTER TSA + { 0x1C18, BIDI_L }, // LEPCHA LETTER TSHA + { 0x1C19, BIDI_L }, // LEPCHA LETTER DZA + { 0x1C1A, BIDI_L }, // LEPCHA LETTER YA + { 0x1C1B, BIDI_L }, // LEPCHA LETTER RA + { 0x1C1C, BIDI_L }, // LEPCHA LETTER LA + { 0x1C1D, BIDI_L }, // LEPCHA LETTER HA + { 0x1C1E, BIDI_L }, // LEPCHA LETTER HLA + { 0x1C1F, BIDI_L }, // LEPCHA LETTER VA + { 0x1C20, BIDI_L }, // LEPCHA LETTER SA + { 0x1C21, BIDI_L }, // LEPCHA LETTER SHA + { 0x1C22, BIDI_L }, // LEPCHA LETTER WA + { 0x1C23, BIDI_L }, // LEPCHA LETTER A + { 0x1C24, BIDI_L }, // LEPCHA SUBJOINED LETTER YA + { 0x1C25, BIDI_L }, // LEPCHA SUBJOINED LETTER RA + { 0x1C26, BIDI_L }, // LEPCHA VOWEL SIGN AA + { 0x1C27, BIDI_L }, // LEPCHA VOWEL SIGN I + { 0x1C28, BIDI_L }, // LEPCHA VOWEL SIGN O + { 0x1C29, BIDI_L }, // LEPCHA VOWEL SIGN OO + { 0x1C2A, BIDI_L }, // LEPCHA VOWEL SIGN U + { 0x1C2B, BIDI_L }, // LEPCHA VOWEL SIGN UU + { 0x1C2C, BIDI_NSM }, // LEPCHA VOWEL SIGN E + { 0x1C2D, BIDI_NSM }, // LEPCHA CONSONANT SIGN K + { 0x1C2E, BIDI_NSM }, // LEPCHA CONSONANT SIGN M + { 0x1C2F, BIDI_NSM }, // LEPCHA CONSONANT SIGN L + { 0x1C30, BIDI_NSM }, // LEPCHA CONSONANT SIGN N + { 0x1C31, BIDI_NSM }, // LEPCHA CONSONANT SIGN P + { 0x1C32, BIDI_NSM }, // LEPCHA CONSONANT SIGN R + { 0x1C33, BIDI_NSM }, // LEPCHA CONSONANT SIGN T + { 0x1C34, BIDI_L }, // LEPCHA CONSONANT SIGN NYIN-DO + { 0x1C35, BIDI_L }, // LEPCHA CONSONANT SIGN KANG + { 0x1C36, BIDI_NSM }, // LEPCHA SIGN RAN + { 0x1C37, BIDI_NSM }, // LEPCHA SIGN NUKTA + { 0x1C3B, BIDI_L }, // LEPCHA PUNCTUATION TA-ROL + { 0x1C3C, BIDI_L }, // LEPCHA PUNCTUATION NYET THYOOM TA-ROL + { 0x1C3D, BIDI_L }, // LEPCHA PUNCTUATION CER-WA + { 0x1C3E, BIDI_L }, // LEPCHA PUNCTUATION TSHOOK CER-WA + { 0x1C3F, BIDI_L }, // LEPCHA PUNCTUATION TSHOOK + { 0x1C40, BIDI_L }, // LEPCHA DIGIT ZERO + { 0x1C41, BIDI_L }, // LEPCHA DIGIT ONE + { 0x1C42, BIDI_L }, // LEPCHA DIGIT TWO + { 0x1C43, BIDI_L }, // LEPCHA DIGIT THREE + { 0x1C44, BIDI_L }, // LEPCHA DIGIT FOUR + { 0x1C45, BIDI_L }, // LEPCHA DIGIT FIVE + { 0x1C46, BIDI_L }, // LEPCHA DIGIT SIX + { 0x1C47, BIDI_L }, // LEPCHA DIGIT SEVEN + { 0x1C48, BIDI_L }, // LEPCHA DIGIT EIGHT + { 0x1C49, BIDI_L }, // LEPCHA DIGIT NINE + { 0x1C4D, BIDI_L }, // LEPCHA LETTER TTA + { 0x1C4E, BIDI_L }, // LEPCHA LETTER TTHA + { 0x1C4F, BIDI_L }, // LEPCHA LETTER DDA + { 0x1C50, BIDI_L }, // OL CHIKI DIGIT ZERO + { 0x1C51, BIDI_L }, // OL CHIKI DIGIT ONE + { 0x1C52, BIDI_L }, // OL CHIKI DIGIT TWO + { 0x1C53, BIDI_L }, // OL CHIKI DIGIT THREE + { 0x1C54, BIDI_L }, // OL CHIKI DIGIT FOUR + { 0x1C55, BIDI_L }, // OL CHIKI DIGIT FIVE + { 0x1C56, BIDI_L }, // OL CHIKI DIGIT SIX + { 0x1C57, BIDI_L }, // OL CHIKI DIGIT SEVEN + { 0x1C58, BIDI_L }, // OL CHIKI DIGIT EIGHT + { 0x1C59, BIDI_L }, // OL CHIKI DIGIT NINE + { 0x1C5A, BIDI_L }, // OL CHIKI LETTER LA + { 0x1C5B, BIDI_L }, // OL CHIKI LETTER AT + { 0x1C5C, BIDI_L }, // OL CHIKI LETTER AG + { 0x1C5D, BIDI_L }, // OL CHIKI LETTER ANG + { 0x1C5E, BIDI_L }, // OL CHIKI LETTER AL + { 0x1C5F, BIDI_L }, // OL CHIKI LETTER LAA + { 0x1C60, BIDI_L }, // OL CHIKI LETTER AAK + { 0x1C61, BIDI_L }, // OL CHIKI LETTER AAJ + { 0x1C62, BIDI_L }, // OL CHIKI LETTER AAM + { 0x1C63, BIDI_L }, // OL CHIKI LETTER AAW + { 0x1C64, BIDI_L }, // OL CHIKI LETTER LI + { 0x1C65, BIDI_L }, // OL CHIKI LETTER IS + { 0x1C66, BIDI_L }, // OL CHIKI LETTER IH + { 0x1C67, BIDI_L }, // OL CHIKI LETTER INY + { 0x1C68, BIDI_L }, // OL CHIKI LETTER IR + { 0x1C69, BIDI_L }, // OL CHIKI LETTER LU + { 0x1C6A, BIDI_L }, // OL CHIKI LETTER UC + { 0x1C6B, BIDI_L }, // OL CHIKI LETTER UD + { 0x1C6C, BIDI_L }, // OL CHIKI LETTER UNN + { 0x1C6D, BIDI_L }, // OL CHIKI LETTER UY + { 0x1C6E, BIDI_L }, // OL CHIKI LETTER LE + { 0x1C6F, BIDI_L }, // OL CHIKI LETTER EP + { 0x1C70, BIDI_L }, // OL CHIKI LETTER EDD + { 0x1C71, BIDI_L }, // OL CHIKI LETTER EN + { 0x1C72, BIDI_L }, // OL CHIKI LETTER ERR + { 0x1C73, BIDI_L }, // OL CHIKI LETTER LO + { 0x1C74, BIDI_L }, // OL CHIKI LETTER OTT + { 0x1C75, BIDI_L }, // OL CHIKI LETTER OB + { 0x1C76, BIDI_L }, // OL CHIKI LETTER OV + { 0x1C77, BIDI_L }, // OL CHIKI LETTER OH + { 0x1C78, BIDI_L }, // OL CHIKI MU TTUDDAG + { 0x1C79, BIDI_L }, // OL CHIKI GAAHLAA TTUDDAAG + { 0x1C7A, BIDI_L }, // OL CHIKI MU-GAAHLAA TTUDDAAG + { 0x1C7B, BIDI_L }, // OL CHIKI RELAA + { 0x1C7C, BIDI_L }, // OL CHIKI PHAARKAA + { 0x1C7D, BIDI_L }, // OL CHIKI AHAD + { 0x1C7E, BIDI_L }, // OL CHIKI PUNCTUATION MUCAAD + { 0x1C7F, BIDI_L }, // OL CHIKI PUNCTUATION DOUBLE MUCAAD + { 0x1CC0, BIDI_L }, // SUNDANESE PUNCTUATION BINDU SURYA + { 0x1CC1, BIDI_L }, // SUNDANESE PUNCTUATION BINDU PANGLONG + { 0x1CC2, BIDI_L }, // SUNDANESE PUNCTUATION BINDU PURNAMA + { 0x1CC3, BIDI_L }, // SUNDANESE PUNCTUATION BINDU CAKRA + { 0x1CC4, BIDI_L }, // SUNDANESE PUNCTUATION BINDU LEU SATANGA + { 0x1CC5, BIDI_L }, // SUNDANESE PUNCTUATION BINDU KA SATANGA + { 0x1CC6, BIDI_L }, // SUNDANESE PUNCTUATION BINDU DA SATANGA + { 0x1CC7, BIDI_L }, // SUNDANESE PUNCTUATION BINDU BA SATANGA + { 0x1CD0, BIDI_NSM }, // VEDIC TONE KARSHANA + { 0x1CD1, BIDI_NSM }, // VEDIC TONE SHARA + { 0x1CD2, BIDI_NSM }, // VEDIC TONE PRENKHA + { 0x1CD3, BIDI_L }, // VEDIC SIGN NIHSHVASA + { 0x1CD4, BIDI_NSM }, // VEDIC SIGN YAJURVEDIC MIDLINE SVARITA + { 0x1CD5, BIDI_NSM }, // VEDIC TONE YAJURVEDIC AGGRAVATED INDEPENDENT SVARITA + { 0x1CD6, BIDI_NSM }, // VEDIC TONE YAJURVEDIC INDEPENDENT SVARITA + { 0x1CD7, BIDI_NSM }, // VEDIC TONE YAJURVEDIC KATHAKA INDEPENDENT SVARITA + { 0x1CD8, BIDI_NSM }, // VEDIC TONE CANDRA BELOW + { 0x1CD9, BIDI_NSM }, // VEDIC TONE YAJURVEDIC KATHAKA INDEPENDENT SVARITA SCHROEDER + { 0x1CDA, BIDI_NSM }, // VEDIC TONE DOUBLE SVARITA + { 0x1CDB, BIDI_NSM }, // VEDIC TONE TRIPLE SVARITA + { 0x1CDC, BIDI_NSM }, // VEDIC TONE KATHAKA ANUDATTA + { 0x1CDD, BIDI_NSM }, // VEDIC TONE DOT BELOW + { 0x1CDE, BIDI_NSM }, // VEDIC TONE TWO DOTS BELOW + { 0x1CDF, BIDI_NSM }, // VEDIC TONE THREE DOTS BELOW + { 0x1CE0, BIDI_NSM }, // VEDIC TONE RIGVEDIC KASHMIRI INDEPENDENT SVARITA + { 0x1CE1, BIDI_L }, // VEDIC TONE ATHARVAVEDIC INDEPENDENT SVARITA + { 0x1CE2, BIDI_NSM }, // VEDIC SIGN VISARGA SVARITA + { 0x1CE3, BIDI_NSM }, // VEDIC SIGN VISARGA UDATTA + { 0x1CE4, BIDI_NSM }, // VEDIC SIGN REVERSED VISARGA UDATTA + { 0x1CE5, BIDI_NSM }, // VEDIC SIGN VISARGA ANUDATTA + { 0x1CE6, BIDI_NSM }, // VEDIC SIGN REVERSED VISARGA ANUDATTA + { 0x1CE7, BIDI_NSM }, // VEDIC SIGN VISARGA UDATTA WITH TAIL + { 0x1CE8, BIDI_NSM }, // VEDIC SIGN VISARGA ANUDATTA WITH TAIL + { 0x1CE9, BIDI_L }, // VEDIC SIGN ANUSVARA ANTARGOMUKHA + { 0x1CEA, BIDI_L }, // VEDIC SIGN ANUSVARA BAHIRGOMUKHA + { 0x1CEB, BIDI_L }, // VEDIC SIGN ANUSVARA VAMAGOMUKHA + { 0x1CEC, BIDI_L }, // VEDIC SIGN ANUSVARA VAMAGOMUKHA WITH TAIL + { 0x1CED, BIDI_NSM }, // VEDIC SIGN TIRYAK + { 0x1CEE, BIDI_L }, // VEDIC SIGN HEXIFORM LONG ANUSVARA + { 0x1CEF, BIDI_L }, // VEDIC SIGN LONG ANUSVARA + { 0x1CF0, BIDI_L }, // VEDIC SIGN RTHANG LONG ANUSVARA + { 0x1CF1, BIDI_L }, // VEDIC SIGN ANUSVARA UBHAYATO MUKHA + { 0x1CF2, BIDI_L }, // VEDIC SIGN ARDHAVISARGA + { 0x1CF3, BIDI_L }, // VEDIC SIGN ROTATED ARDHAVISARGA + { 0x1CF4, BIDI_NSM }, // VEDIC TONE CANDRA ABOVE + { 0x1CF5, BIDI_L }, // VEDIC SIGN JIHVAMULIYA + { 0x1CF6, BIDI_L }, // VEDIC SIGN UPADHMANIYA + { 0x1CF8, BIDI_NSM }, // VEDIC TONE RING ABOVE + { 0x1CF9, BIDI_NSM }, // VEDIC TONE DOUBLE RING ABOVE + { 0x1D00, BIDI_L }, // LATIN LETTER SMALL CAPITAL A + { 0x1D01, BIDI_L }, // LATIN LETTER SMALL CAPITAL AE + { 0x1D02, BIDI_L }, // LATIN SMALL LETTER TURNED AE + { 0x1D03, BIDI_L }, // LATIN LETTER SMALL CAPITAL BARRED B + { 0x1D04, BIDI_L }, // LATIN LETTER SMALL CAPITAL C + { 0x1D05, BIDI_L }, // LATIN LETTER SMALL CAPITAL D + { 0x1D06, BIDI_L }, // LATIN LETTER SMALL CAPITAL ETH + { 0x1D07, BIDI_L }, // LATIN LETTER SMALL CAPITAL E + { 0x1D08, BIDI_L }, // LATIN SMALL LETTER TURNED OPEN E + { 0x1D09, BIDI_L }, // LATIN SMALL LETTER TURNED I + { 0x1D0A, BIDI_L }, // LATIN LETTER SMALL CAPITAL J + { 0x1D0B, BIDI_L }, // LATIN LETTER SMALL CAPITAL K + { 0x1D0C, BIDI_L }, // LATIN LETTER SMALL CAPITAL L WITH STROKE + { 0x1D0D, BIDI_L }, // LATIN LETTER SMALL CAPITAL M + { 0x1D0E, BIDI_L }, // LATIN LETTER SMALL CAPITAL REVERSED N + { 0x1D0F, BIDI_L }, // LATIN LETTER SMALL CAPITAL O + { 0x1D10, BIDI_L }, // LATIN LETTER SMALL CAPITAL OPEN O + { 0x1D11, BIDI_L }, // LATIN SMALL LETTER SIDEWAYS O + { 0x1D12, BIDI_L }, // LATIN SMALL LETTER SIDEWAYS OPEN O + { 0x1D13, BIDI_L }, // LATIN SMALL LETTER SIDEWAYS O WITH STROKE + { 0x1D14, BIDI_L }, // LATIN SMALL LETTER TURNED OE + { 0x1D15, BIDI_L }, // LATIN LETTER SMALL CAPITAL OU + { 0x1D16, BIDI_L }, // LATIN SMALL LETTER TOP HALF O + { 0x1D17, BIDI_L }, // LATIN SMALL LETTER BOTTOM HALF O + { 0x1D18, BIDI_L }, // LATIN LETTER SMALL CAPITAL P + { 0x1D19, BIDI_L }, // LATIN LETTER SMALL CAPITAL REVERSED R + { 0x1D1A, BIDI_L }, // LATIN LETTER SMALL CAPITAL TURNED R + { 0x1D1B, BIDI_L }, // LATIN LETTER SMALL CAPITAL T + { 0x1D1C, BIDI_L }, // LATIN LETTER SMALL CAPITAL U + { 0x1D1D, BIDI_L }, // LATIN SMALL LETTER SIDEWAYS U + { 0x1D1E, BIDI_L }, // LATIN SMALL LETTER SIDEWAYS DIAERESIZED U + { 0x1D1F, BIDI_L }, // LATIN SMALL LETTER SIDEWAYS TURNED M + { 0x1D20, BIDI_L }, // LATIN LETTER SMALL CAPITAL V + { 0x1D21, BIDI_L }, // LATIN LETTER SMALL CAPITAL W + { 0x1D22, BIDI_L }, // LATIN LETTER SMALL CAPITAL Z + { 0x1D23, BIDI_L }, // LATIN LETTER SMALL CAPITAL EZH + { 0x1D24, BIDI_L }, // LATIN LETTER VOICED LARYNGEAL SPIRANT + { 0x1D25, BIDI_L }, // LATIN LETTER AIN + { 0x1D26, BIDI_L }, // GREEK LETTER SMALL CAPITAL GAMMA + { 0x1D27, BIDI_L }, // GREEK LETTER SMALL CAPITAL LAMDA + { 0x1D28, BIDI_L }, // GREEK LETTER SMALL CAPITAL PI + { 0x1D29, BIDI_L }, // GREEK LETTER SMALL CAPITAL RHO + { 0x1D2A, BIDI_L }, // GREEK LETTER SMALL CAPITAL PSI + { 0x1D2B, BIDI_L }, // CYRILLIC LETTER SMALL CAPITAL EL + { 0x1D2C, BIDI_L }, // MODIFIER LETTER CAPITAL A + { 0x1D2D, BIDI_L }, // MODIFIER LETTER CAPITAL AE + { 0x1D2E, BIDI_L }, // MODIFIER LETTER CAPITAL B + { 0x1D2F, BIDI_L }, // MODIFIER LETTER CAPITAL BARRED B + { 0x1D30, BIDI_L }, // MODIFIER LETTER CAPITAL D + { 0x1D31, BIDI_L }, // MODIFIER LETTER CAPITAL E + { 0x1D32, BIDI_L }, // MODIFIER LETTER CAPITAL REVERSED E + { 0x1D33, BIDI_L }, // MODIFIER LETTER CAPITAL G + { 0x1D34, BIDI_L }, // MODIFIER LETTER CAPITAL H + { 0x1D35, BIDI_L }, // MODIFIER LETTER CAPITAL I + { 0x1D36, BIDI_L }, // MODIFIER LETTER CAPITAL J + { 0x1D37, BIDI_L }, // MODIFIER LETTER CAPITAL K + { 0x1D38, BIDI_L }, // MODIFIER LETTER CAPITAL L + { 0x1D39, BIDI_L }, // MODIFIER LETTER CAPITAL M + { 0x1D3A, BIDI_L }, // MODIFIER LETTER CAPITAL N + { 0x1D3B, BIDI_L }, // MODIFIER LETTER CAPITAL REVERSED N + { 0x1D3C, BIDI_L }, // MODIFIER LETTER CAPITAL O + { 0x1D3D, BIDI_L }, // MODIFIER LETTER CAPITAL OU + { 0x1D3E, BIDI_L }, // MODIFIER LETTER CAPITAL P + { 0x1D3F, BIDI_L }, // MODIFIER LETTER CAPITAL R + { 0x1D40, BIDI_L }, // MODIFIER LETTER CAPITAL T + { 0x1D41, BIDI_L }, // MODIFIER LETTER CAPITAL U + { 0x1D42, BIDI_L }, // MODIFIER LETTER CAPITAL W + { 0x1D43, BIDI_L }, // MODIFIER LETTER SMALL A + { 0x1D44, BIDI_L }, // MODIFIER LETTER SMALL TURNED A + { 0x1D45, BIDI_L }, // MODIFIER LETTER SMALL ALPHA + { 0x1D46, BIDI_L }, // MODIFIER LETTER SMALL TURNED AE + { 0x1D47, BIDI_L }, // MODIFIER LETTER SMALL B + { 0x1D48, BIDI_L }, // MODIFIER LETTER SMALL D + { 0x1D49, BIDI_L }, // MODIFIER LETTER SMALL E + { 0x1D4A, BIDI_L }, // MODIFIER LETTER SMALL SCHWA + { 0x1D4B, BIDI_L }, // MODIFIER LETTER SMALL OPEN E + { 0x1D4C, BIDI_L }, // MODIFIER LETTER SMALL TURNED OPEN E + { 0x1D4D, BIDI_L }, // MODIFIER LETTER SMALL G + { 0x1D4E, BIDI_L }, // MODIFIER LETTER SMALL TURNED I + { 0x1D4F, BIDI_L }, // MODIFIER LETTER SMALL K + { 0x1D50, BIDI_L }, // MODIFIER LETTER SMALL M + { 0x1D51, BIDI_L }, // MODIFIER LETTER SMALL ENG + { 0x1D52, BIDI_L }, // MODIFIER LETTER SMALL O + { 0x1D53, BIDI_L }, // MODIFIER LETTER SMALL OPEN O + { 0x1D54, BIDI_L }, // MODIFIER LETTER SMALL TOP HALF O + { 0x1D55, BIDI_L }, // MODIFIER LETTER SMALL BOTTOM HALF O + { 0x1D56, BIDI_L }, // MODIFIER LETTER SMALL P + { 0x1D57, BIDI_L }, // MODIFIER LETTER SMALL T + { 0x1D58, BIDI_L }, // MODIFIER LETTER SMALL U + { 0x1D59, BIDI_L }, // MODIFIER LETTER SMALL SIDEWAYS U + { 0x1D5A, BIDI_L }, // MODIFIER LETTER SMALL TURNED M + { 0x1D5B, BIDI_L }, // MODIFIER LETTER SMALL V + { 0x1D5C, BIDI_L }, // MODIFIER LETTER SMALL AIN + { 0x1D5D, BIDI_L }, // MODIFIER LETTER SMALL BETA + { 0x1D5E, BIDI_L }, // MODIFIER LETTER SMALL GREEK GAMMA + { 0x1D5F, BIDI_L }, // MODIFIER LETTER SMALL DELTA + { 0x1D60, BIDI_L }, // MODIFIER LETTER SMALL GREEK PHI + { 0x1D61, BIDI_L }, // MODIFIER LETTER SMALL CHI + { 0x1D62, BIDI_L }, // LATIN SUBSCRIPT SMALL LETTER I + { 0x1D63, BIDI_L }, // LATIN SUBSCRIPT SMALL LETTER R + { 0x1D64, BIDI_L }, // LATIN SUBSCRIPT SMALL LETTER U + { 0x1D65, BIDI_L }, // LATIN SUBSCRIPT SMALL LETTER V + { 0x1D66, BIDI_L }, // GREEK SUBSCRIPT SMALL LETTER BETA + { 0x1D67, BIDI_L }, // GREEK SUBSCRIPT SMALL LETTER GAMMA + { 0x1D68, BIDI_L }, // GREEK SUBSCRIPT SMALL LETTER RHO + { 0x1D69, BIDI_L }, // GREEK SUBSCRIPT SMALL LETTER PHI + { 0x1D6A, BIDI_L }, // GREEK SUBSCRIPT SMALL LETTER CHI + { 0x1D6B, BIDI_L }, // LATIN SMALL LETTER UE + { 0x1D6C, BIDI_L }, // LATIN SMALL LETTER B WITH MIDDLE TILDE + { 0x1D6D, BIDI_L }, // LATIN SMALL LETTER D WITH MIDDLE TILDE + { 0x1D6E, BIDI_L }, // LATIN SMALL LETTER F WITH MIDDLE TILDE + { 0x1D6F, BIDI_L }, // LATIN SMALL LETTER M WITH MIDDLE TILDE + { 0x1D70, BIDI_L }, // LATIN SMALL LETTER N WITH MIDDLE TILDE + { 0x1D71, BIDI_L }, // LATIN SMALL LETTER P WITH MIDDLE TILDE + { 0x1D72, BIDI_L }, // LATIN SMALL LETTER R WITH MIDDLE TILDE + { 0x1D73, BIDI_L }, // LATIN SMALL LETTER R WITH FISHHOOK AND MIDDLE TILDE + { 0x1D74, BIDI_L }, // LATIN SMALL LETTER S WITH MIDDLE TILDE + { 0x1D75, BIDI_L }, // LATIN SMALL LETTER T WITH MIDDLE TILDE + { 0x1D76, BIDI_L }, // LATIN SMALL LETTER Z WITH MIDDLE TILDE + { 0x1D77, BIDI_L }, // LATIN SMALL LETTER TURNED G + { 0x1D78, BIDI_L }, // MODIFIER LETTER CYRILLIC EN + { 0x1D79, BIDI_L }, // LATIN SMALL LETTER INSULAR G + { 0x1D7A, BIDI_L }, // LATIN SMALL LETTER TH WITH STRIKETHROUGH + { 0x1D7B, BIDI_L }, // LATIN SMALL CAPITAL LETTER I WITH STROKE + { 0x1D7C, BIDI_L }, // LATIN SMALL LETTER IOTA WITH STROKE + { 0x1D7D, BIDI_L }, // LATIN SMALL LETTER P WITH STROKE + { 0x1D7E, BIDI_L }, // LATIN SMALL CAPITAL LETTER U WITH STROKE + { 0x1D7F, BIDI_L }, // LATIN SMALL LETTER UPSILON WITH STROKE + { 0x1D80, BIDI_L }, // LATIN SMALL LETTER B WITH PALATAL HOOK + { 0x1D81, BIDI_L }, // LATIN SMALL LETTER D WITH PALATAL HOOK + { 0x1D82, BIDI_L }, // LATIN SMALL LETTER F WITH PALATAL HOOK + { 0x1D83, BIDI_L }, // LATIN SMALL LETTER G WITH PALATAL HOOK + { 0x1D84, BIDI_L }, // LATIN SMALL LETTER K WITH PALATAL HOOK + { 0x1D85, BIDI_L }, // LATIN SMALL LETTER L WITH PALATAL HOOK + { 0x1D86, BIDI_L }, // LATIN SMALL LETTER M WITH PALATAL HOOK + { 0x1D87, BIDI_L }, // LATIN SMALL LETTER N WITH PALATAL HOOK + { 0x1D88, BIDI_L }, // LATIN SMALL LETTER P WITH PALATAL HOOK + { 0x1D89, BIDI_L }, // LATIN SMALL LETTER R WITH PALATAL HOOK + { 0x1D8A, BIDI_L }, // LATIN SMALL LETTER S WITH PALATAL HOOK + { 0x1D8B, BIDI_L }, // LATIN SMALL LETTER ESH WITH PALATAL HOOK + { 0x1D8C, BIDI_L }, // LATIN SMALL LETTER V WITH PALATAL HOOK + { 0x1D8D, BIDI_L }, // LATIN SMALL LETTER X WITH PALATAL HOOK + { 0x1D8E, BIDI_L }, // LATIN SMALL LETTER Z WITH PALATAL HOOK + { 0x1D8F, BIDI_L }, // LATIN SMALL LETTER A WITH RETROFLEX HOOK + { 0x1D90, BIDI_L }, // LATIN SMALL LETTER ALPHA WITH RETROFLEX HOOK + { 0x1D91, BIDI_L }, // LATIN SMALL LETTER D WITH HOOK AND TAIL + { 0x1D92, BIDI_L }, // LATIN SMALL LETTER E WITH RETROFLEX HOOK + { 0x1D93, BIDI_L }, // LATIN SMALL LETTER OPEN E WITH RETROFLEX HOOK + { 0x1D94, BIDI_L }, // LATIN SMALL LETTER REVERSED OPEN E WITH RETROFLEX HOOK + { 0x1D95, BIDI_L }, // LATIN SMALL LETTER SCHWA WITH RETROFLEX HOOK + { 0x1D96, BIDI_L }, // LATIN SMALL LETTER I WITH RETROFLEX HOOK + { 0x1D97, BIDI_L }, // LATIN SMALL LETTER OPEN O WITH RETROFLEX HOOK + { 0x1D98, BIDI_L }, // LATIN SMALL LETTER ESH WITH RETROFLEX HOOK + { 0x1D99, BIDI_L }, // LATIN SMALL LETTER U WITH RETROFLEX HOOK + { 0x1D9A, BIDI_L }, // LATIN SMALL LETTER EZH WITH RETROFLEX HOOK + { 0x1D9B, BIDI_L }, // MODIFIER LETTER SMALL TURNED ALPHA + { 0x1D9C, BIDI_L }, // MODIFIER LETTER SMALL C + { 0x1D9D, BIDI_L }, // MODIFIER LETTER SMALL C WITH CURL + { 0x1D9E, BIDI_L }, // MODIFIER LETTER SMALL ETH + { 0x1D9F, BIDI_L }, // MODIFIER LETTER SMALL REVERSED OPEN E + { 0x1DA0, BIDI_L }, // MODIFIER LETTER SMALL F + { 0x1DA1, BIDI_L }, // MODIFIER LETTER SMALL DOTLESS J WITH STROKE + { 0x1DA2, BIDI_L }, // MODIFIER LETTER SMALL SCRIPT G + { 0x1DA3, BIDI_L }, // MODIFIER LETTER SMALL TURNED H + { 0x1DA4, BIDI_L }, // MODIFIER LETTER SMALL I WITH STROKE + { 0x1DA5, BIDI_L }, // MODIFIER LETTER SMALL IOTA + { 0x1DA6, BIDI_L }, // MODIFIER LETTER SMALL CAPITAL I + { 0x1DA7, BIDI_L }, // MODIFIER LETTER SMALL CAPITAL I WITH STROKE + { 0x1DA8, BIDI_L }, // MODIFIER LETTER SMALL J WITH CROSSED-TAIL + { 0x1DA9, BIDI_L }, // MODIFIER LETTER SMALL L WITH RETROFLEX HOOK + { 0x1DAA, BIDI_L }, // MODIFIER LETTER SMALL L WITH PALATAL HOOK + { 0x1DAB, BIDI_L }, // MODIFIER LETTER SMALL CAPITAL L + { 0x1DAC, BIDI_L }, // MODIFIER LETTER SMALL M WITH HOOK + { 0x1DAD, BIDI_L }, // MODIFIER LETTER SMALL TURNED M WITH LONG LEG + { 0x1DAE, BIDI_L }, // MODIFIER LETTER SMALL N WITH LEFT HOOK + { 0x1DAF, BIDI_L }, // MODIFIER LETTER SMALL N WITH RETROFLEX HOOK + { 0x1DB0, BIDI_L }, // MODIFIER LETTER SMALL CAPITAL N + { 0x1DB1, BIDI_L }, // MODIFIER LETTER SMALL BARRED O + { 0x1DB2, BIDI_L }, // MODIFIER LETTER SMALL PHI + { 0x1DB3, BIDI_L }, // MODIFIER LETTER SMALL S WITH HOOK + { 0x1DB4, BIDI_L }, // MODIFIER LETTER SMALL ESH + { 0x1DB5, BIDI_L }, // MODIFIER LETTER SMALL T WITH PALATAL HOOK + { 0x1DB6, BIDI_L }, // MODIFIER LETTER SMALL U BAR + { 0x1DB7, BIDI_L }, // MODIFIER LETTER SMALL UPSILON + { 0x1DB8, BIDI_L }, // MODIFIER LETTER SMALL CAPITAL U + { 0x1DB9, BIDI_L }, // MODIFIER LETTER SMALL V WITH HOOK + { 0x1DBA, BIDI_L }, // MODIFIER LETTER SMALL TURNED V + { 0x1DBB, BIDI_L }, // MODIFIER LETTER SMALL Z + { 0x1DBC, BIDI_L }, // MODIFIER LETTER SMALL Z WITH RETROFLEX HOOK + { 0x1DBD, BIDI_L }, // MODIFIER LETTER SMALL Z WITH CURL + { 0x1DBE, BIDI_L }, // MODIFIER LETTER SMALL EZH + { 0x1DBF, BIDI_L }, // MODIFIER LETTER SMALL THETA + { 0x1DC0, BIDI_NSM }, // COMBINING DOTTED GRAVE ACCENT + { 0x1DC1, BIDI_NSM }, // COMBINING DOTTED ACUTE ACCENT + { 0x1DC2, BIDI_NSM }, // COMBINING SNAKE BELOW + { 0x1DC3, BIDI_NSM }, // COMBINING SUSPENSION MARK + { 0x1DC4, BIDI_NSM }, // COMBINING MACRON-ACUTE + { 0x1DC5, BIDI_NSM }, // COMBINING GRAVE-MACRON + { 0x1DC6, BIDI_NSM }, // COMBINING MACRON-GRAVE + { 0x1DC7, BIDI_NSM }, // COMBINING ACUTE-MACRON + { 0x1DC8, BIDI_NSM }, // COMBINING GRAVE-ACUTE-GRAVE + { 0x1DC9, BIDI_NSM }, // COMBINING ACUTE-GRAVE-ACUTE + { 0x1DCA, BIDI_NSM }, // COMBINING LATIN SMALL LETTER R BELOW + { 0x1DCB, BIDI_NSM }, // COMBINING BREVE-MACRON + { 0x1DCC, BIDI_NSM }, // COMBINING MACRON-BREVE + { 0x1DCD, BIDI_NSM }, // COMBINING DOUBLE CIRCUMFLEX ABOVE + { 0x1DCE, BIDI_NSM }, // COMBINING OGONEK ABOVE + { 0x1DCF, BIDI_NSM }, // COMBINING ZIGZAG BELOW + { 0x1DD0, BIDI_NSM }, // COMBINING IS BELOW + { 0x1DD1, BIDI_NSM }, // COMBINING UR ABOVE + { 0x1DD2, BIDI_NSM }, // COMBINING US ABOVE + { 0x1DD3, BIDI_NSM }, // COMBINING LATIN SMALL LETTER FLATTENED OPEN A ABOVE + { 0x1DD4, BIDI_NSM }, // COMBINING LATIN SMALL LETTER AE + { 0x1DD5, BIDI_NSM }, // COMBINING LATIN SMALL LETTER AO + { 0x1DD6, BIDI_NSM }, // COMBINING LATIN SMALL LETTER AV + { 0x1DD7, BIDI_NSM }, // COMBINING LATIN SMALL LETTER C CEDILLA + { 0x1DD8, BIDI_NSM }, // COMBINING LATIN SMALL LETTER INSULAR D + { 0x1DD9, BIDI_NSM }, // COMBINING LATIN SMALL LETTER ETH + { 0x1DDA, BIDI_NSM }, // COMBINING LATIN SMALL LETTER G + { 0x1DDB, BIDI_NSM }, // COMBINING LATIN LETTER SMALL CAPITAL G + { 0x1DDC, BIDI_NSM }, // COMBINING LATIN SMALL LETTER K + { 0x1DDD, BIDI_NSM }, // COMBINING LATIN SMALL LETTER L + { 0x1DDE, BIDI_NSM }, // COMBINING LATIN LETTER SMALL CAPITAL L + { 0x1DDF, BIDI_NSM }, // COMBINING LATIN LETTER SMALL CAPITAL M + { 0x1DE0, BIDI_NSM }, // COMBINING LATIN SMALL LETTER N + { 0x1DE1, BIDI_NSM }, // COMBINING LATIN LETTER SMALL CAPITAL N + { 0x1DE2, BIDI_NSM }, // COMBINING LATIN LETTER SMALL CAPITAL R + { 0x1DE3, BIDI_NSM }, // COMBINING LATIN SMALL LETTER R ROTUNDA + { 0x1DE4, BIDI_NSM }, // COMBINING LATIN SMALL LETTER S + { 0x1DE5, BIDI_NSM }, // COMBINING LATIN SMALL LETTER LONG S + { 0x1DE6, BIDI_NSM }, // COMBINING LATIN SMALL LETTER Z + { 0x1DE7, BIDI_NSM }, // COMBINING LATIN SMALL LETTER ALPHA + { 0x1DE8, BIDI_NSM }, // COMBINING LATIN SMALL LETTER B + { 0x1DE9, BIDI_NSM }, // COMBINING LATIN SMALL LETTER BETA + { 0x1DEA, BIDI_NSM }, // COMBINING LATIN SMALL LETTER SCHWA + { 0x1DEB, BIDI_NSM }, // COMBINING LATIN SMALL LETTER F + { 0x1DEC, BIDI_NSM }, // COMBINING LATIN SMALL LETTER L WITH DOUBLE MIDDLE TILDE + { 0x1DED, BIDI_NSM }, // COMBINING LATIN SMALL LETTER O WITH LIGHT CENTRALIZATION STROKE + { 0x1DEE, BIDI_NSM }, // COMBINING LATIN SMALL LETTER P + { 0x1DEF, BIDI_NSM }, // COMBINING LATIN SMALL LETTER ESH + { 0x1DF0, BIDI_NSM }, // COMBINING LATIN SMALL LETTER U WITH LIGHT CENTRALIZATION STROKE + { 0x1DF1, BIDI_NSM }, // COMBINING LATIN SMALL LETTER W + { 0x1DF2, BIDI_NSM }, // COMBINING LATIN SMALL LETTER A WITH DIAERESIS + { 0x1DF3, BIDI_NSM }, // COMBINING LATIN SMALL LETTER O WITH DIAERESIS + { 0x1DF4, BIDI_NSM }, // COMBINING LATIN SMALL LETTER U WITH DIAERESIS + { 0x1DF5, BIDI_NSM }, // COMBINING UP TACK ABOVE + { 0x1DFC, BIDI_NSM }, // COMBINING DOUBLE INVERTED BREVE BELOW + { 0x1DFD, BIDI_NSM }, // COMBINING ALMOST EQUAL TO BELOW + { 0x1DFE, BIDI_NSM }, // COMBINING LEFT ARROWHEAD ABOVE + { 0x1DFF, BIDI_NSM }, // COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW + { 0x1E00, BIDI_L }, // LATIN CAPITAL LETTER A WITH RING BELOW + { 0x1E01, BIDI_L }, // LATIN SMALL LETTER A WITH RING BELOW + { 0x1E02, BIDI_L }, // LATIN CAPITAL LETTER B WITH DOT ABOVE + { 0x1E03, BIDI_L }, // LATIN SMALL LETTER B WITH DOT ABOVE + { 0x1E04, BIDI_L }, // LATIN CAPITAL LETTER B WITH DOT BELOW + { 0x1E05, BIDI_L }, // LATIN SMALL LETTER B WITH DOT BELOW + { 0x1E06, BIDI_L }, // LATIN CAPITAL LETTER B WITH LINE BELOW + { 0x1E07, BIDI_L }, // LATIN SMALL LETTER B WITH LINE BELOW + { 0x1E08, BIDI_L }, // LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE + { 0x1E09, BIDI_L }, // LATIN SMALL LETTER C WITH CEDILLA AND ACUTE + { 0x1E0A, BIDI_L }, // LATIN CAPITAL LETTER D WITH DOT ABOVE + { 0x1E0B, BIDI_L }, // LATIN SMALL LETTER D WITH DOT ABOVE + { 0x1E0C, BIDI_L }, // LATIN CAPITAL LETTER D WITH DOT BELOW + { 0x1E0D, BIDI_L }, // LATIN SMALL LETTER D WITH DOT BELOW + { 0x1E0E, BIDI_L }, // LATIN CAPITAL LETTER D WITH LINE BELOW + { 0x1E0F, BIDI_L }, // LATIN SMALL LETTER D WITH LINE BELOW + { 0x1E10, BIDI_L }, // LATIN CAPITAL LETTER D WITH CEDILLA + { 0x1E11, BIDI_L }, // LATIN SMALL LETTER D WITH CEDILLA + { 0x1E12, BIDI_L }, // LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW + { 0x1E13, BIDI_L }, // LATIN SMALL LETTER D WITH CIRCUMFLEX BELOW + { 0x1E14, BIDI_L }, // LATIN CAPITAL LETTER E WITH MACRON AND GRAVE + { 0x1E15, BIDI_L }, // LATIN SMALL LETTER E WITH MACRON AND GRAVE + { 0x1E16, BIDI_L }, // LATIN CAPITAL LETTER E WITH MACRON AND ACUTE + { 0x1E17, BIDI_L }, // LATIN SMALL LETTER E WITH MACRON AND ACUTE + { 0x1E18, BIDI_L }, // LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW + { 0x1E19, BIDI_L }, // LATIN SMALL LETTER E WITH CIRCUMFLEX BELOW + { 0x1E1A, BIDI_L }, // LATIN CAPITAL LETTER E WITH TILDE BELOW + { 0x1E1B, BIDI_L }, // LATIN SMALL LETTER E WITH TILDE BELOW + { 0x1E1C, BIDI_L }, // LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE + { 0x1E1D, BIDI_L }, // LATIN SMALL LETTER E WITH CEDILLA AND BREVE + { 0x1E1E, BIDI_L }, // LATIN CAPITAL LETTER F WITH DOT ABOVE + { 0x1E1F, BIDI_L }, // LATIN SMALL LETTER F WITH DOT ABOVE + { 0x1E20, BIDI_L }, // LATIN CAPITAL LETTER G WITH MACRON + { 0x1E21, BIDI_L }, // LATIN SMALL LETTER G WITH MACRON + { 0x1E22, BIDI_L }, // LATIN CAPITAL LETTER H WITH DOT ABOVE + { 0x1E23, BIDI_L }, // LATIN SMALL LETTER H WITH DOT ABOVE + { 0x1E24, BIDI_L }, // LATIN CAPITAL LETTER H WITH DOT BELOW + { 0x1E25, BIDI_L }, // LATIN SMALL LETTER H WITH DOT BELOW + { 0x1E26, BIDI_L }, // LATIN CAPITAL LETTER H WITH DIAERESIS + { 0x1E27, BIDI_L }, // LATIN SMALL LETTER H WITH DIAERESIS + { 0x1E28, BIDI_L }, // LATIN CAPITAL LETTER H WITH CEDILLA + { 0x1E29, BIDI_L }, // LATIN SMALL LETTER H WITH CEDILLA + { 0x1E2A, BIDI_L }, // LATIN CAPITAL LETTER H WITH BREVE BELOW + { 0x1E2B, BIDI_L }, // LATIN SMALL LETTER H WITH BREVE BELOW + { 0x1E2C, BIDI_L }, // LATIN CAPITAL LETTER I WITH TILDE BELOW + { 0x1E2D, BIDI_L }, // LATIN SMALL LETTER I WITH TILDE BELOW + { 0x1E2E, BIDI_L }, // LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE + { 0x1E2F, BIDI_L }, // LATIN SMALL LETTER I WITH DIAERESIS AND ACUTE + { 0x1E30, BIDI_L }, // LATIN CAPITAL LETTER K WITH ACUTE + { 0x1E31, BIDI_L }, // LATIN SMALL LETTER K WITH ACUTE + { 0x1E32, BIDI_L }, // LATIN CAPITAL LETTER K WITH DOT BELOW + { 0x1E33, BIDI_L }, // LATIN SMALL LETTER K WITH DOT BELOW + { 0x1E34, BIDI_L }, // LATIN CAPITAL LETTER K WITH LINE BELOW + { 0x1E35, BIDI_L }, // LATIN SMALL LETTER K WITH LINE BELOW + { 0x1E36, BIDI_L }, // LATIN CAPITAL LETTER L WITH DOT BELOW + { 0x1E37, BIDI_L }, // LATIN SMALL LETTER L WITH DOT BELOW + { 0x1E38, BIDI_L }, // LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON + { 0x1E39, BIDI_L }, // LATIN SMALL LETTER L WITH DOT BELOW AND MACRON + { 0x1E3A, BIDI_L }, // LATIN CAPITAL LETTER L WITH LINE BELOW + { 0x1E3B, BIDI_L }, // LATIN SMALL LETTER L WITH LINE BELOW + { 0x1E3C, BIDI_L }, // LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW + { 0x1E3D, BIDI_L }, // LATIN SMALL LETTER L WITH CIRCUMFLEX BELOW + { 0x1E3E, BIDI_L }, // LATIN CAPITAL LETTER M WITH ACUTE + { 0x1E3F, BIDI_L }, // LATIN SMALL LETTER M WITH ACUTE + { 0x1E40, BIDI_L }, // LATIN CAPITAL LETTER M WITH DOT ABOVE + { 0x1E41, BIDI_L }, // LATIN SMALL LETTER M WITH DOT ABOVE + { 0x1E42, BIDI_L }, // LATIN CAPITAL LETTER M WITH DOT BELOW + { 0x1E43, BIDI_L }, // LATIN SMALL LETTER M WITH DOT BELOW + { 0x1E44, BIDI_L }, // LATIN CAPITAL LETTER N WITH DOT ABOVE + { 0x1E45, BIDI_L }, // LATIN SMALL LETTER N WITH DOT ABOVE + { 0x1E46, BIDI_L }, // LATIN CAPITAL LETTER N WITH DOT BELOW + { 0x1E47, BIDI_L }, // LATIN SMALL LETTER N WITH DOT BELOW + { 0x1E48, BIDI_L }, // LATIN CAPITAL LETTER N WITH LINE BELOW + { 0x1E49, BIDI_L }, // LATIN SMALL LETTER N WITH LINE BELOW + { 0x1E4A, BIDI_L }, // LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW + { 0x1E4B, BIDI_L }, // LATIN SMALL LETTER N WITH CIRCUMFLEX BELOW + { 0x1E4C, BIDI_L }, // LATIN CAPITAL LETTER O WITH TILDE AND ACUTE + { 0x1E4D, BIDI_L }, // LATIN SMALL LETTER O WITH TILDE AND ACUTE + { 0x1E4E, BIDI_L }, // LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS + { 0x1E4F, BIDI_L }, // LATIN SMALL LETTER O WITH TILDE AND DIAERESIS + { 0x1E50, BIDI_L }, // LATIN CAPITAL LETTER O WITH MACRON AND GRAVE + { 0x1E51, BIDI_L }, // LATIN SMALL LETTER O WITH MACRON AND GRAVE + { 0x1E52, BIDI_L }, // LATIN CAPITAL LETTER O WITH MACRON AND ACUTE + { 0x1E53, BIDI_L }, // LATIN SMALL LETTER O WITH MACRON AND ACUTE + { 0x1E54, BIDI_L }, // LATIN CAPITAL LETTER P WITH ACUTE + { 0x1E55, BIDI_L }, // LATIN SMALL LETTER P WITH ACUTE + { 0x1E56, BIDI_L }, // LATIN CAPITAL LETTER P WITH DOT ABOVE + { 0x1E57, BIDI_L }, // LATIN SMALL LETTER P WITH DOT ABOVE + { 0x1E58, BIDI_L }, // LATIN CAPITAL LETTER R WITH DOT ABOVE + { 0x1E59, BIDI_L }, // LATIN SMALL LETTER R WITH DOT ABOVE + { 0x1E5A, BIDI_L }, // LATIN CAPITAL LETTER R WITH DOT BELOW + { 0x1E5B, BIDI_L }, // LATIN SMALL LETTER R WITH DOT BELOW + { 0x1E5C, BIDI_L }, // LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON + { 0x1E5D, BIDI_L }, // LATIN SMALL LETTER R WITH DOT BELOW AND MACRON + { 0x1E5E, BIDI_L }, // LATIN CAPITAL LETTER R WITH LINE BELOW + { 0x1E5F, BIDI_L }, // LATIN SMALL LETTER R WITH LINE BELOW + { 0x1E60, BIDI_L }, // LATIN CAPITAL LETTER S WITH DOT ABOVE + { 0x1E61, BIDI_L }, // LATIN SMALL LETTER S WITH DOT ABOVE + { 0x1E62, BIDI_L }, // LATIN CAPITAL LETTER S WITH DOT BELOW + { 0x1E63, BIDI_L }, // LATIN SMALL LETTER S WITH DOT BELOW + { 0x1E64, BIDI_L }, // LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE + { 0x1E65, BIDI_L }, // LATIN SMALL LETTER S WITH ACUTE AND DOT ABOVE + { 0x1E66, BIDI_L }, // LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE + { 0x1E67, BIDI_L }, // LATIN SMALL LETTER S WITH CARON AND DOT ABOVE + { 0x1E68, BIDI_L }, // LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE + { 0x1E69, BIDI_L }, // LATIN SMALL LETTER S WITH DOT BELOW AND DOT ABOVE + { 0x1E6A, BIDI_L }, // LATIN CAPITAL LETTER T WITH DOT ABOVE + { 0x1E6B, BIDI_L }, // LATIN SMALL LETTER T WITH DOT ABOVE + { 0x1E6C, BIDI_L }, // LATIN CAPITAL LETTER T WITH DOT BELOW + { 0x1E6D, BIDI_L }, // LATIN SMALL LETTER T WITH DOT BELOW + { 0x1E6E, BIDI_L }, // LATIN CAPITAL LETTER T WITH LINE BELOW + { 0x1E6F, BIDI_L }, // LATIN SMALL LETTER T WITH LINE BELOW + { 0x1E70, BIDI_L }, // LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW + { 0x1E71, BIDI_L }, // LATIN SMALL LETTER T WITH CIRCUMFLEX BELOW + { 0x1E72, BIDI_L }, // LATIN CAPITAL LETTER U WITH DIAERESIS BELOW + { 0x1E73, BIDI_L }, // LATIN SMALL LETTER U WITH DIAERESIS BELOW + { 0x1E74, BIDI_L }, // LATIN CAPITAL LETTER U WITH TILDE BELOW + { 0x1E75, BIDI_L }, // LATIN SMALL LETTER U WITH TILDE BELOW + { 0x1E76, BIDI_L }, // LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW + { 0x1E77, BIDI_L }, // LATIN SMALL LETTER U WITH CIRCUMFLEX BELOW + { 0x1E78, BIDI_L }, // LATIN CAPITAL LETTER U WITH TILDE AND ACUTE + { 0x1E79, BIDI_L }, // LATIN SMALL LETTER U WITH TILDE AND ACUTE + { 0x1E7A, BIDI_L }, // LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS + { 0x1E7B, BIDI_L }, // LATIN SMALL LETTER U WITH MACRON AND DIAERESIS + { 0x1E7C, BIDI_L }, // LATIN CAPITAL LETTER V WITH TILDE + { 0x1E7D, BIDI_L }, // LATIN SMALL LETTER V WITH TILDE + { 0x1E7E, BIDI_L }, // LATIN CAPITAL LETTER V WITH DOT BELOW + { 0x1E7F, BIDI_L }, // LATIN SMALL LETTER V WITH DOT BELOW + { 0x1E80, BIDI_L }, // LATIN CAPITAL LETTER W WITH GRAVE + { 0x1E81, BIDI_L }, // LATIN SMALL LETTER W WITH GRAVE + { 0x1E82, BIDI_L }, // LATIN CAPITAL LETTER W WITH ACUTE + { 0x1E83, BIDI_L }, // LATIN SMALL LETTER W WITH ACUTE + { 0x1E84, BIDI_L }, // LATIN CAPITAL LETTER W WITH DIAERESIS + { 0x1E85, BIDI_L }, // LATIN SMALL LETTER W WITH DIAERESIS + { 0x1E86, BIDI_L }, // LATIN CAPITAL LETTER W WITH DOT ABOVE + { 0x1E87, BIDI_L }, // LATIN SMALL LETTER W WITH DOT ABOVE + { 0x1E88, BIDI_L }, // LATIN CAPITAL LETTER W WITH DOT BELOW + { 0x1E89, BIDI_L }, // LATIN SMALL LETTER W WITH DOT BELOW + { 0x1E8A, BIDI_L }, // LATIN CAPITAL LETTER X WITH DOT ABOVE + { 0x1E8B, BIDI_L }, // LATIN SMALL LETTER X WITH DOT ABOVE + { 0x1E8C, BIDI_L }, // LATIN CAPITAL LETTER X WITH DIAERESIS + { 0x1E8D, BIDI_L }, // LATIN SMALL LETTER X WITH DIAERESIS + { 0x1E8E, BIDI_L }, // LATIN CAPITAL LETTER Y WITH DOT ABOVE + { 0x1E8F, BIDI_L }, // LATIN SMALL LETTER Y WITH DOT ABOVE + { 0x1E90, BIDI_L }, // LATIN CAPITAL LETTER Z WITH CIRCUMFLEX + { 0x1E91, BIDI_L }, // LATIN SMALL LETTER Z WITH CIRCUMFLEX + { 0x1E92, BIDI_L }, // LATIN CAPITAL LETTER Z WITH DOT BELOW + { 0x1E93, BIDI_L }, // LATIN SMALL LETTER Z WITH DOT BELOW + { 0x1E94, BIDI_L }, // LATIN CAPITAL LETTER Z WITH LINE BELOW + { 0x1E95, BIDI_L }, // LATIN SMALL LETTER Z WITH LINE BELOW + { 0x1E96, BIDI_L }, // LATIN SMALL LETTER H WITH LINE BELOW + { 0x1E97, BIDI_L }, // LATIN SMALL LETTER T WITH DIAERESIS + { 0x1E98, BIDI_L }, // LATIN SMALL LETTER W WITH RING ABOVE + { 0x1E99, BIDI_L }, // LATIN SMALL LETTER Y WITH RING ABOVE + { 0x1E9A, BIDI_L }, // LATIN SMALL LETTER A WITH RIGHT HALF RING + { 0x1E9B, BIDI_L }, // LATIN SMALL LETTER LONG S WITH DOT ABOVE + { 0x1E9C, BIDI_L }, // LATIN SMALL LETTER LONG S WITH DIAGONAL STROKE + { 0x1E9D, BIDI_L }, // LATIN SMALL LETTER LONG S WITH HIGH STROKE + { 0x1E9E, BIDI_L }, // LATIN CAPITAL LETTER SHARP S + { 0x1E9F, BIDI_L }, // LATIN SMALL LETTER DELTA + { 0x1EA0, BIDI_L }, // LATIN CAPITAL LETTER A WITH DOT BELOW + { 0x1EA1, BIDI_L }, // LATIN SMALL LETTER A WITH DOT BELOW + { 0x1EA2, BIDI_L }, // LATIN CAPITAL LETTER A WITH HOOK ABOVE + { 0x1EA3, BIDI_L }, // LATIN SMALL LETTER A WITH HOOK ABOVE + { 0x1EA4, BIDI_L }, // LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE + { 0x1EA5, BIDI_L }, // LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE + { 0x1EA6, BIDI_L }, // LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE + { 0x1EA7, BIDI_L }, // LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE + { 0x1EA8, BIDI_L }, // LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE + { 0x1EA9, BIDI_L }, // LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE + { 0x1EAA, BIDI_L }, // LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE + { 0x1EAB, BIDI_L }, // LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE + { 0x1EAC, BIDI_L }, // LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW + { 0x1EAD, BIDI_L }, // LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW + { 0x1EAE, BIDI_L }, // LATIN CAPITAL LETTER A WITH BREVE AND ACUTE + { 0x1EAF, BIDI_L }, // LATIN SMALL LETTER A WITH BREVE AND ACUTE + { 0x1EB0, BIDI_L }, // LATIN CAPITAL LETTER A WITH BREVE AND GRAVE + { 0x1EB1, BIDI_L }, // LATIN SMALL LETTER A WITH BREVE AND GRAVE + { 0x1EB2, BIDI_L }, // LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE + { 0x1EB3, BIDI_L }, // LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE + { 0x1EB4, BIDI_L }, // LATIN CAPITAL LETTER A WITH BREVE AND TILDE + { 0x1EB5, BIDI_L }, // LATIN SMALL LETTER A WITH BREVE AND TILDE + { 0x1EB6, BIDI_L }, // LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW + { 0x1EB7, BIDI_L }, // LATIN SMALL LETTER A WITH BREVE AND DOT BELOW + { 0x1EB8, BIDI_L }, // LATIN CAPITAL LETTER E WITH DOT BELOW + { 0x1EB9, BIDI_L }, // LATIN SMALL LETTER E WITH DOT BELOW + { 0x1EBA, BIDI_L }, // LATIN CAPITAL LETTER E WITH HOOK ABOVE + { 0x1EBB, BIDI_L }, // LATIN SMALL LETTER E WITH HOOK ABOVE + { 0x1EBC, BIDI_L }, // LATIN CAPITAL LETTER E WITH TILDE + { 0x1EBD, BIDI_L }, // LATIN SMALL LETTER E WITH TILDE + { 0x1EBE, BIDI_L }, // LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE + { 0x1EBF, BIDI_L }, // LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE + { 0x1EC0, BIDI_L }, // LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE + { 0x1EC1, BIDI_L }, // LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE + { 0x1EC2, BIDI_L }, // LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE + { 0x1EC3, BIDI_L }, // LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE + { 0x1EC4, BIDI_L }, // LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE + { 0x1EC5, BIDI_L }, // LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE + { 0x1EC6, BIDI_L }, // LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW + { 0x1EC7, BIDI_L }, // LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW + { 0x1EC8, BIDI_L }, // LATIN CAPITAL LETTER I WITH HOOK ABOVE + { 0x1EC9, BIDI_L }, // LATIN SMALL LETTER I WITH HOOK ABOVE + { 0x1ECA, BIDI_L }, // LATIN CAPITAL LETTER I WITH DOT BELOW + { 0x1ECB, BIDI_L }, // LATIN SMALL LETTER I WITH DOT BELOW + { 0x1ECC, BIDI_L }, // LATIN CAPITAL LETTER O WITH DOT BELOW + { 0x1ECD, BIDI_L }, // LATIN SMALL LETTER O WITH DOT BELOW + { 0x1ECE, BIDI_L }, // LATIN CAPITAL LETTER O WITH HOOK ABOVE + { 0x1ECF, BIDI_L }, // LATIN SMALL LETTER O WITH HOOK ABOVE + { 0x1ED0, BIDI_L }, // LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE + { 0x1ED1, BIDI_L }, // LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE + { 0x1ED2, BIDI_L }, // LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE + { 0x1ED3, BIDI_L }, // LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE + { 0x1ED4, BIDI_L }, // LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE + { 0x1ED5, BIDI_L }, // LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE + { 0x1ED6, BIDI_L }, // LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE + { 0x1ED7, BIDI_L }, // LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE + { 0x1ED8, BIDI_L }, // LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW + { 0x1ED9, BIDI_L }, // LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW + { 0x1EDA, BIDI_L }, // LATIN CAPITAL LETTER O WITH HORN AND ACUTE + { 0x1EDB, BIDI_L }, // LATIN SMALL LETTER O WITH HORN AND ACUTE + { 0x1EDC, BIDI_L }, // LATIN CAPITAL LETTER O WITH HORN AND GRAVE + { 0x1EDD, BIDI_L }, // LATIN SMALL LETTER O WITH HORN AND GRAVE + { 0x1EDE, BIDI_L }, // LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE + { 0x1EDF, BIDI_L }, // LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE + { 0x1EE0, BIDI_L }, // LATIN CAPITAL LETTER O WITH HORN AND TILDE + { 0x1EE1, BIDI_L }, // LATIN SMALL LETTER O WITH HORN AND TILDE + { 0x1EE2, BIDI_L }, // LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW + { 0x1EE3, BIDI_L }, // LATIN SMALL LETTER O WITH HORN AND DOT BELOW + { 0x1EE4, BIDI_L }, // LATIN CAPITAL LETTER U WITH DOT BELOW + { 0x1EE5, BIDI_L }, // LATIN SMALL LETTER U WITH DOT BELOW + { 0x1EE6, BIDI_L }, // LATIN CAPITAL LETTER U WITH HOOK ABOVE + { 0x1EE7, BIDI_L }, // LATIN SMALL LETTER U WITH HOOK ABOVE + { 0x1EE8, BIDI_L }, // LATIN CAPITAL LETTER U WITH HORN AND ACUTE + { 0x1EE9, BIDI_L }, // LATIN SMALL LETTER U WITH HORN AND ACUTE + { 0x1EEA, BIDI_L }, // LATIN CAPITAL LETTER U WITH HORN AND GRAVE + { 0x1EEB, BIDI_L }, // LATIN SMALL LETTER U WITH HORN AND GRAVE + { 0x1EEC, BIDI_L }, // LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE + { 0x1EED, BIDI_L }, // LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE + { 0x1EEE, BIDI_L }, // LATIN CAPITAL LETTER U WITH HORN AND TILDE + { 0x1EEF, BIDI_L }, // LATIN SMALL LETTER U WITH HORN AND TILDE + { 0x1EF0, BIDI_L }, // LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW + { 0x1EF1, BIDI_L }, // LATIN SMALL LETTER U WITH HORN AND DOT BELOW + { 0x1EF2, BIDI_L }, // LATIN CAPITAL LETTER Y WITH GRAVE + { 0x1EF3, BIDI_L }, // LATIN SMALL LETTER Y WITH GRAVE + { 0x1EF4, BIDI_L }, // LATIN CAPITAL LETTER Y WITH DOT BELOW + { 0x1EF5, BIDI_L }, // LATIN SMALL LETTER Y WITH DOT BELOW + { 0x1EF6, BIDI_L }, // LATIN CAPITAL LETTER Y WITH HOOK ABOVE + { 0x1EF7, BIDI_L }, // LATIN SMALL LETTER Y WITH HOOK ABOVE + { 0x1EF8, BIDI_L }, // LATIN CAPITAL LETTER Y WITH TILDE + { 0x1EF9, BIDI_L }, // LATIN SMALL LETTER Y WITH TILDE + { 0x1EFA, BIDI_L }, // LATIN CAPITAL LETTER MIDDLE-WELSH LL + { 0x1EFB, BIDI_L }, // LATIN SMALL LETTER MIDDLE-WELSH LL + { 0x1EFC, BIDI_L }, // LATIN CAPITAL LETTER MIDDLE-WELSH V + { 0x1EFD, BIDI_L }, // LATIN SMALL LETTER MIDDLE-WELSH V + { 0x1EFE, BIDI_L }, // LATIN CAPITAL LETTER Y WITH LOOP + { 0x1EFF, BIDI_L }, // LATIN SMALL LETTER Y WITH LOOP + { 0x1F00, BIDI_L }, // GREEK SMALL LETTER ALPHA WITH PSILI + { 0x1F01, BIDI_L }, // GREEK SMALL LETTER ALPHA WITH DASIA + { 0x1F02, BIDI_L }, // GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA + { 0x1F03, BIDI_L }, // GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA + { 0x1F04, BIDI_L }, // GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA + { 0x1F05, BIDI_L }, // GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA + { 0x1F06, BIDI_L }, // GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI + { 0x1F07, BIDI_L }, // GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI + { 0x1F08, BIDI_L }, // GREEK CAPITAL LETTER ALPHA WITH PSILI + { 0x1F09, BIDI_L }, // GREEK CAPITAL LETTER ALPHA WITH DASIA + { 0x1F0A, BIDI_L }, // GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA + { 0x1F0B, BIDI_L }, // GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA + { 0x1F0C, BIDI_L }, // GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA + { 0x1F0D, BIDI_L }, // GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA + { 0x1F0E, BIDI_L }, // GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI + { 0x1F0F, BIDI_L }, // GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI + { 0x1F10, BIDI_L }, // GREEK SMALL LETTER EPSILON WITH PSILI + { 0x1F11, BIDI_L }, // GREEK SMALL LETTER EPSILON WITH DASIA + { 0x1F12, BIDI_L }, // GREEK SMALL LETTER EPSILON WITH PSILI AND VARIA + { 0x1F13, BIDI_L }, // GREEK SMALL LETTER EPSILON WITH DASIA AND VARIA + { 0x1F14, BIDI_L }, // GREEK SMALL LETTER EPSILON WITH PSILI AND OXIA + { 0x1F15, BIDI_L }, // GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA + { 0x1F18, BIDI_L }, // GREEK CAPITAL LETTER EPSILON WITH PSILI + { 0x1F19, BIDI_L }, // GREEK CAPITAL LETTER EPSILON WITH DASIA + { 0x1F1A, BIDI_L }, // GREEK CAPITAL LETTER EPSILON WITH PSILI AND VARIA + { 0x1F1B, BIDI_L }, // GREEK CAPITAL LETTER EPSILON WITH DASIA AND VARIA + { 0x1F1C, BIDI_L }, // GREEK CAPITAL LETTER EPSILON WITH PSILI AND OXIA + { 0x1F1D, BIDI_L }, // GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA + { 0x1F20, BIDI_L }, // GREEK SMALL LETTER ETA WITH PSILI + { 0x1F21, BIDI_L }, // GREEK SMALL LETTER ETA WITH DASIA + { 0x1F22, BIDI_L }, // GREEK SMALL LETTER ETA WITH PSILI AND VARIA + { 0x1F23, BIDI_L }, // GREEK SMALL LETTER ETA WITH DASIA AND VARIA + { 0x1F24, BIDI_L }, // GREEK SMALL LETTER ETA WITH PSILI AND OXIA + { 0x1F25, BIDI_L }, // GREEK SMALL LETTER ETA WITH DASIA AND OXIA + { 0x1F26, BIDI_L }, // GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI + { 0x1F27, BIDI_L }, // GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI + { 0x1F28, BIDI_L }, // GREEK CAPITAL LETTER ETA WITH PSILI + { 0x1F29, BIDI_L }, // GREEK CAPITAL LETTER ETA WITH DASIA + { 0x1F2A, BIDI_L }, // GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA + { 0x1F2B, BIDI_L }, // GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA + { 0x1F2C, BIDI_L }, // GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA + { 0x1F2D, BIDI_L }, // GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA + { 0x1F2E, BIDI_L }, // GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI + { 0x1F2F, BIDI_L }, // GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI + { 0x1F30, BIDI_L }, // GREEK SMALL LETTER IOTA WITH PSILI + { 0x1F31, BIDI_L }, // GREEK SMALL LETTER IOTA WITH DASIA + { 0x1F32, BIDI_L }, // GREEK SMALL LETTER IOTA WITH PSILI AND VARIA + { 0x1F33, BIDI_L }, // GREEK SMALL LETTER IOTA WITH DASIA AND VARIA + { 0x1F34, BIDI_L }, // GREEK SMALL LETTER IOTA WITH PSILI AND OXIA + { 0x1F35, BIDI_L }, // GREEK SMALL LETTER IOTA WITH DASIA AND OXIA + { 0x1F36, BIDI_L }, // GREEK SMALL LETTER IOTA WITH PSILI AND PERISPOMENI + { 0x1F37, BIDI_L }, // GREEK SMALL LETTER IOTA WITH DASIA AND PERISPOMENI + { 0x1F38, BIDI_L }, // GREEK CAPITAL LETTER IOTA WITH PSILI + { 0x1F39, BIDI_L }, // GREEK CAPITAL LETTER IOTA WITH DASIA + { 0x1F3A, BIDI_L }, // GREEK CAPITAL LETTER IOTA WITH PSILI AND VARIA + { 0x1F3B, BIDI_L }, // GREEK CAPITAL LETTER IOTA WITH DASIA AND VARIA + { 0x1F3C, BIDI_L }, // GREEK CAPITAL LETTER IOTA WITH PSILI AND OXIA + { 0x1F3D, BIDI_L }, // GREEK CAPITAL LETTER IOTA WITH DASIA AND OXIA + { 0x1F3E, BIDI_L }, // GREEK CAPITAL LETTER IOTA WITH PSILI AND PERISPOMENI + { 0x1F3F, BIDI_L }, // GREEK CAPITAL LETTER IOTA WITH DASIA AND PERISPOMENI + { 0x1F40, BIDI_L }, // GREEK SMALL LETTER OMICRON WITH PSILI + { 0x1F41, BIDI_L }, // GREEK SMALL LETTER OMICRON WITH DASIA + { 0x1F42, BIDI_L }, // GREEK SMALL LETTER OMICRON WITH PSILI AND VARIA + { 0x1F43, BIDI_L }, // GREEK SMALL LETTER OMICRON WITH DASIA AND VARIA + { 0x1F44, BIDI_L }, // GREEK SMALL LETTER OMICRON WITH PSILI AND OXIA + { 0x1F45, BIDI_L }, // GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA + { 0x1F48, BIDI_L }, // GREEK CAPITAL LETTER OMICRON WITH PSILI + { 0x1F49, BIDI_L }, // GREEK CAPITAL LETTER OMICRON WITH DASIA + { 0x1F4A, BIDI_L }, // GREEK CAPITAL LETTER OMICRON WITH PSILI AND VARIA + { 0x1F4B, BIDI_L }, // GREEK CAPITAL LETTER OMICRON WITH DASIA AND VARIA + { 0x1F4C, BIDI_L }, // GREEK CAPITAL LETTER OMICRON WITH PSILI AND OXIA + { 0x1F4D, BIDI_L }, // GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA + { 0x1F50, BIDI_L }, // GREEK SMALL LETTER UPSILON WITH PSILI + { 0x1F51, BIDI_L }, // GREEK SMALL LETTER UPSILON WITH DASIA + { 0x1F52, BIDI_L }, // GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA + { 0x1F53, BIDI_L }, // GREEK SMALL LETTER UPSILON WITH DASIA AND VARIA + { 0x1F54, BIDI_L }, // GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA + { 0x1F55, BIDI_L }, // GREEK SMALL LETTER UPSILON WITH DASIA AND OXIA + { 0x1F56, BIDI_L }, // GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI + { 0x1F57, BIDI_L }, // GREEK SMALL LETTER UPSILON WITH DASIA AND PERISPOMENI + { 0x1F59, BIDI_L }, // GREEK CAPITAL LETTER UPSILON WITH DASIA + { 0x1F5B, BIDI_L }, // GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA + { 0x1F5D, BIDI_L }, // GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA + { 0x1F5F, BIDI_L }, // GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI + { 0x1F60, BIDI_L }, // GREEK SMALL LETTER OMEGA WITH PSILI + { 0x1F61, BIDI_L }, // GREEK SMALL LETTER OMEGA WITH DASIA + { 0x1F62, BIDI_L }, // GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA + { 0x1F63, BIDI_L }, // GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA + { 0x1F64, BIDI_L }, // GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA + { 0x1F65, BIDI_L }, // GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA + { 0x1F66, BIDI_L }, // GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI + { 0x1F67, BIDI_L }, // GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI + { 0x1F68, BIDI_L }, // GREEK CAPITAL LETTER OMEGA WITH PSILI + { 0x1F69, BIDI_L }, // GREEK CAPITAL LETTER OMEGA WITH DASIA + { 0x1F6A, BIDI_L }, // GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA + { 0x1F6B, BIDI_L }, // GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA + { 0x1F6C, BIDI_L }, // GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA + { 0x1F6D, BIDI_L }, // GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA + { 0x1F6E, BIDI_L }, // GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI + { 0x1F6F, BIDI_L }, // GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI + { 0x1F70, BIDI_L }, // GREEK SMALL LETTER ALPHA WITH VARIA + { 0x1F71, BIDI_L }, // GREEK SMALL LETTER ALPHA WITH OXIA + { 0x1F72, BIDI_L }, // GREEK SMALL LETTER EPSILON WITH VARIA + { 0x1F73, BIDI_L }, // GREEK SMALL LETTER EPSILON WITH OXIA + { 0x1F74, BIDI_L }, // GREEK SMALL LETTER ETA WITH VARIA + { 0x1F75, BIDI_L }, // GREEK SMALL LETTER ETA WITH OXIA + { 0x1F76, BIDI_L }, // GREEK SMALL LETTER IOTA WITH VARIA + { 0x1F77, BIDI_L }, // GREEK SMALL LETTER IOTA WITH OXIA + { 0x1F78, BIDI_L }, // GREEK SMALL LETTER OMICRON WITH VARIA + { 0x1F79, BIDI_L }, // GREEK SMALL LETTER OMICRON WITH OXIA + { 0x1F7A, BIDI_L }, // GREEK SMALL LETTER UPSILON WITH VARIA + { 0x1F7B, BIDI_L }, // GREEK SMALL LETTER UPSILON WITH OXIA + { 0x1F7C, BIDI_L }, // GREEK SMALL LETTER OMEGA WITH VARIA + { 0x1F7D, BIDI_L }, // GREEK SMALL LETTER OMEGA WITH OXIA + { 0x1F80, BIDI_L }, // GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI + { 0x1F81, BIDI_L }, // GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI + { 0x1F82, BIDI_L }, // GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI + { 0x1F83, BIDI_L }, // GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI + { 0x1F84, BIDI_L }, // GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI + { 0x1F85, BIDI_L }, // GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI + { 0x1F86, BIDI_L }, // GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI + { 0x1F87, BIDI_L }, // GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI + { 0x1F88, BIDI_L }, // GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI + { 0x1F89, BIDI_L }, // GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI + { 0x1F8A, BIDI_L }, // GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI + { 0x1F8B, BIDI_L }, // GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI + { 0x1F8C, BIDI_L }, // GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI + { 0x1F8D, BIDI_L }, // GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI + { 0x1F8E, BIDI_L }, // GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI + { 0x1F8F, BIDI_L }, // GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI + { 0x1F90, BIDI_L }, // GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI + { 0x1F91, BIDI_L }, // GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI + { 0x1F92, BIDI_L }, // GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI + { 0x1F93, BIDI_L }, // GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI + { 0x1F94, BIDI_L }, // GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI + { 0x1F95, BIDI_L }, // GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI + { 0x1F96, BIDI_L }, // GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI + { 0x1F97, BIDI_L }, // GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI + { 0x1F98, BIDI_L }, // GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI + { 0x1F99, BIDI_L }, // GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI + { 0x1F9A, BIDI_L }, // GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI + { 0x1F9B, BIDI_L }, // GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI + { 0x1F9C, BIDI_L }, // GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI + { 0x1F9D, BIDI_L }, // GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI + { 0x1F9E, BIDI_L }, // GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI + { 0x1F9F, BIDI_L }, // GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI + { 0x1FA0, BIDI_L }, // GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI + { 0x1FA1, BIDI_L }, // GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI + { 0x1FA2, BIDI_L }, // GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI + { 0x1FA3, BIDI_L }, // GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI + { 0x1FA4, BIDI_L }, // GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI + { 0x1FA5, BIDI_L }, // GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI + { 0x1FA6, BIDI_L }, // GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI + { 0x1FA7, BIDI_L }, // GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI + { 0x1FA8, BIDI_L }, // GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI + { 0x1FA9, BIDI_L }, // GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI + { 0x1FAA, BIDI_L }, // GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI + { 0x1FAB, BIDI_L }, // GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI + { 0x1FAC, BIDI_L }, // GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI + { 0x1FAD, BIDI_L }, // GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI + { 0x1FAE, BIDI_L }, // GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI + { 0x1FAF, BIDI_L }, // GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI + { 0x1FB0, BIDI_L }, // GREEK SMALL LETTER ALPHA WITH VRACHY + { 0x1FB1, BIDI_L }, // GREEK SMALL LETTER ALPHA WITH MACRON + { 0x1FB2, BIDI_L }, // GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI + { 0x1FB3, BIDI_L }, // GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI + { 0x1FB4, BIDI_L }, // GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI + { 0x1FB6, BIDI_L }, // GREEK SMALL LETTER ALPHA WITH PERISPOMENI + { 0x1FB7, BIDI_L }, // GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI + { 0x1FB8, BIDI_L }, // GREEK CAPITAL LETTER ALPHA WITH VRACHY + { 0x1FB9, BIDI_L }, // GREEK CAPITAL LETTER ALPHA WITH MACRON + { 0x1FBA, BIDI_L }, // GREEK CAPITAL LETTER ALPHA WITH VARIA + { 0x1FBB, BIDI_L }, // GREEK CAPITAL LETTER ALPHA WITH OXIA + { 0x1FBC, BIDI_L }, // GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI + { 0x1FBD, BIDI_ON }, // GREEK KORONIS + { 0x1FBE, BIDI_L }, // GREEK PROSGEGRAMMENI + { 0x1FBF, BIDI_ON }, // GREEK PSILI + { 0x1FC0, BIDI_ON }, // GREEK PERISPOMENI + { 0x1FC1, BIDI_ON }, // GREEK DIALYTIKA AND PERISPOMENI + { 0x1FC2, BIDI_L }, // GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI + { 0x1FC3, BIDI_L }, // GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI + { 0x1FC4, BIDI_L }, // GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI + { 0x1FC6, BIDI_L }, // GREEK SMALL LETTER ETA WITH PERISPOMENI + { 0x1FC7, BIDI_L }, // GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI + { 0x1FC8, BIDI_L }, // GREEK CAPITAL LETTER EPSILON WITH VARIA + { 0x1FC9, BIDI_L }, // GREEK CAPITAL LETTER EPSILON WITH OXIA + { 0x1FCA, BIDI_L }, // GREEK CAPITAL LETTER ETA WITH VARIA + { 0x1FCB, BIDI_L }, // GREEK CAPITAL LETTER ETA WITH OXIA + { 0x1FCC, BIDI_L }, // GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI + { 0x1FCD, BIDI_ON }, // GREEK PSILI AND VARIA + { 0x1FCE, BIDI_ON }, // GREEK PSILI AND OXIA + { 0x1FCF, BIDI_ON }, // GREEK PSILI AND PERISPOMENI + { 0x1FD0, BIDI_L }, // GREEK SMALL LETTER IOTA WITH VRACHY + { 0x1FD1, BIDI_L }, // GREEK SMALL LETTER IOTA WITH MACRON + { 0x1FD2, BIDI_L }, // GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA + { 0x1FD3, BIDI_L }, // GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA + { 0x1FD6, BIDI_L }, // GREEK SMALL LETTER IOTA WITH PERISPOMENI + { 0x1FD7, BIDI_L }, // GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI + { 0x1FD8, BIDI_L }, // GREEK CAPITAL LETTER IOTA WITH VRACHY + { 0x1FD9, BIDI_L }, // GREEK CAPITAL LETTER IOTA WITH MACRON + { 0x1FDA, BIDI_L }, // GREEK CAPITAL LETTER IOTA WITH VARIA + { 0x1FDB, BIDI_L }, // GREEK CAPITAL LETTER IOTA WITH OXIA + { 0x1FDD, BIDI_ON }, // GREEK DASIA AND VARIA + { 0x1FDE, BIDI_ON }, // GREEK DASIA AND OXIA + { 0x1FDF, BIDI_ON }, // GREEK DASIA AND PERISPOMENI + { 0x1FE0, BIDI_L }, // GREEK SMALL LETTER UPSILON WITH VRACHY + { 0x1FE1, BIDI_L }, // GREEK SMALL LETTER UPSILON WITH MACRON + { 0x1FE2, BIDI_L }, // GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA + { 0x1FE3, BIDI_L }, // GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA + { 0x1FE4, BIDI_L }, // GREEK SMALL LETTER RHO WITH PSILI + { 0x1FE5, BIDI_L }, // GREEK SMALL LETTER RHO WITH DASIA + { 0x1FE6, BIDI_L }, // GREEK SMALL LETTER UPSILON WITH PERISPOMENI + { 0x1FE7, BIDI_L }, // GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI + { 0x1FE8, BIDI_L }, // GREEK CAPITAL LETTER UPSILON WITH VRACHY + { 0x1FE9, BIDI_L }, // GREEK CAPITAL LETTER UPSILON WITH MACRON + { 0x1FEA, BIDI_L }, // GREEK CAPITAL LETTER UPSILON WITH VARIA + { 0x1FEB, BIDI_L }, // GREEK CAPITAL LETTER UPSILON WITH OXIA + { 0x1FEC, BIDI_L }, // GREEK CAPITAL LETTER RHO WITH DASIA + { 0x1FED, BIDI_ON }, // GREEK DIALYTIKA AND VARIA + { 0x1FEE, BIDI_ON }, // GREEK DIALYTIKA AND OXIA + { 0x1FEF, BIDI_ON }, // GREEK VARIA + { 0x1FF2, BIDI_L }, // GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI + { 0x1FF3, BIDI_L }, // GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI + { 0x1FF4, BIDI_L }, // GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI + { 0x1FF6, BIDI_L }, // GREEK SMALL LETTER OMEGA WITH PERISPOMENI + { 0x1FF7, BIDI_L }, // GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI + { 0x1FF8, BIDI_L }, // GREEK CAPITAL LETTER OMICRON WITH VARIA + { 0x1FF9, BIDI_L }, // GREEK CAPITAL LETTER OMICRON WITH OXIA + { 0x1FFA, BIDI_L }, // GREEK CAPITAL LETTER OMEGA WITH VARIA + { 0x1FFB, BIDI_L }, // GREEK CAPITAL LETTER OMEGA WITH OXIA + { 0x1FFC, BIDI_L }, // GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI + { 0x1FFD, BIDI_ON }, // GREEK OXIA + { 0x1FFE, BIDI_ON }, // GREEK DASIA + +#endif +#if (GUI_BIDI_SUPPORT_RANGE_2 == 1) + + { 0x2000, BIDI_WS }, // EN QUAD + { 0x2001, BIDI_WS }, // EM QUAD + { 0x2002, BIDI_WS }, // EN SPACE + { 0x2003, BIDI_WS }, // EM SPACE + { 0x2004, BIDI_WS }, // THREE-PER-EM SPACE + { 0x2005, BIDI_WS }, // FOUR-PER-EM SPACE + { 0x2006, BIDI_WS }, // SIX-PER-EM SPACE + { 0x2007, BIDI_WS }, // FIGURE SPACE + { 0x2008, BIDI_WS }, // PUNCTUATION SPACE + { 0x2009, BIDI_WS }, // THIN SPACE + { 0x200A, BIDI_WS }, // HAIR SPACE + { 0x200B, BIDI_BN }, // ZERO WIDTH SPACE + { 0x200C, BIDI_BN }, // ZERO WIDTH NON-JOINER + { 0x200D, BIDI_BN }, // ZERO WIDTH JOINER + { 0x200E, BIDI_L }, // LEFT-TO-RIGHT MARK + { 0x200F, BIDI_R }, // RIGHT-TO-LEFT MARK + { 0x2010, BIDI_ON }, // HYPHEN + { 0x2011, BIDI_ON }, // NON-BREAKING HYPHEN + { 0x2012, BIDI_ON }, // FIGURE DASH + { 0x2013, BIDI_ON }, // EN DASH + { 0x2014, BIDI_ON }, // EM DASH + { 0x2015, BIDI_ON }, // HORIZONTAL BAR + { 0x2016, BIDI_ON }, // DOUBLE VERTICAL LINE + { 0x2017, BIDI_ON }, // DOUBLE LOW LINE + { 0x2018, BIDI_ON }, // LEFT SINGLE QUOTATION MARK + { 0x2019, BIDI_ON }, // RIGHT SINGLE QUOTATION MARK + { 0x201A, BIDI_ON }, // SINGLE LOW-9 QUOTATION MARK + { 0x201B, BIDI_ON }, // SINGLE HIGH-REVERSED-9 QUOTATION MARK + { 0x201C, BIDI_ON }, // LEFT DOUBLE QUOTATION MARK + { 0x201D, BIDI_ON }, // RIGHT DOUBLE QUOTATION MARK + { 0x201E, BIDI_ON }, // DOUBLE LOW-9 QUOTATION MARK + { 0x201F, BIDI_ON }, // DOUBLE HIGH-REVERSED-9 QUOTATION MARK + { 0x2020, BIDI_ON }, // DAGGER + { 0x2021, BIDI_ON }, // DOUBLE DAGGER + { 0x2022, BIDI_ON }, // BULLET + { 0x2023, BIDI_ON }, // TRIANGULAR BULLET + { 0x2024, BIDI_ON }, // ONE DOT LEADER + { 0x2025, BIDI_ON }, // TWO DOT LEADER + { 0x2026, BIDI_ON }, // HORIZONTAL ELLIPSIS + { 0x2027, BIDI_ON }, // HYPHENATION POINT + { 0x2028, BIDI_WS }, // LINE SEPARATOR + { 0x2029, BIDI_B }, // PARAGRAPH SEPARATOR + { 0x202A, BIDI_LRE }, // LEFT-TO-RIGHT EMBEDDING + { 0x202B, BIDI_RLE }, // RIGHT-TO-LEFT EMBEDDING + { 0x202C, BIDI_PDF }, // POP DIRECTIONAL FORMATTING + { 0x202D, BIDI_LRO }, // LEFT-TO-RIGHT OVERRIDE + { 0x202E, BIDI_RLO }, // RIGHT-TO-LEFT OVERRIDE + { 0x202F, BIDI_CS }, // NARROW NO-BREAK SPACE + { 0x2030, BIDI_ET }, // PER MILLE SIGN + { 0x2031, BIDI_ET }, // PER TEN THOUSAND SIGN + { 0x2032, BIDI_ET }, // PRIME + { 0x2033, BIDI_ET }, // DOUBLE PRIME + { 0x2034, BIDI_ET }, // TRIPLE PRIME + { 0x2035, BIDI_ON }, // REVERSED PRIME + { 0x2036, BIDI_ON }, // REVERSED DOUBLE PRIME + { 0x2037, BIDI_ON }, // REVERSED TRIPLE PRIME + { 0x2038, BIDI_ON }, // CARET + { 0x2039, BIDI_ON }, // SINGLE LEFT-POINTING ANGLE QUOTATION MARK + { 0x203A, BIDI_ON }, // SINGLE RIGHT-POINTING ANGLE QUOTATION MARK + { 0x203B, BIDI_ON }, // REFERENCE MARK + { 0x203C, BIDI_ON }, // DOUBLE EXCLAMATION MARK + { 0x203D, BIDI_ON }, // INTERROBANG + { 0x203E, BIDI_ON }, // OVERLINE + { 0x203F, BIDI_ON }, // UNDERTIE + { 0x2040, BIDI_ON }, // CHARACTER TIE + { 0x2041, BIDI_ON }, // CARET INSERTION POINT + { 0x2042, BIDI_ON }, // ASTERISM + { 0x2043, BIDI_ON }, // HYPHEN BULLET + { 0x2044, BIDI_CS }, // FRACTION SLASH + { 0x2045, BIDI_ON }, // LEFT SQUARE BRACKET WITH QUILL + { 0x2046, BIDI_ON }, // RIGHT SQUARE BRACKET WITH QUILL + { 0x2047, BIDI_ON }, // DOUBLE QUESTION MARK + { 0x2048, BIDI_ON }, // QUESTION EXCLAMATION MARK + { 0x2049, BIDI_ON }, // EXCLAMATION QUESTION MARK + { 0x204A, BIDI_ON }, // TIRONIAN SIGN ET + { 0x204B, BIDI_ON }, // REVERSED PILCROW SIGN + { 0x204C, BIDI_ON }, // BLACK LEFTWARDS BULLET + { 0x204D, BIDI_ON }, // BLACK RIGHTWARDS BULLET + { 0x204E, BIDI_ON }, // LOW ASTERISK + { 0x204F, BIDI_ON }, // REVERSED SEMICOLON + { 0x2050, BIDI_ON }, // CLOSE UP + { 0x2051, BIDI_ON }, // TWO ASTERISKS ALIGNED VERTICALLY + { 0x2052, BIDI_ON }, // COMMERCIAL MINUS SIGN + { 0x2053, BIDI_ON }, // SWUNG DASH + { 0x2054, BIDI_ON }, // INVERTED UNDERTIE + { 0x2055, BIDI_ON }, // FLOWER PUNCTUATION MARK + { 0x2056, BIDI_ON }, // THREE DOT PUNCTUATION + { 0x2057, BIDI_ON }, // QUADRUPLE PRIME + { 0x2058, BIDI_ON }, // FOUR DOT PUNCTUATION + { 0x2059, BIDI_ON }, // FIVE DOT PUNCTUATION + { 0x205A, BIDI_ON }, // TWO DOT PUNCTUATION + { 0x205B, BIDI_ON }, // FOUR DOT MARK + { 0x205C, BIDI_ON }, // DOTTED CROSS + { 0x205D, BIDI_ON }, // TRICOLON + { 0x205E, BIDI_ON }, // VERTICAL FOUR DOTS + { 0x205F, BIDI_WS }, // MEDIUM MATHEMATICAL SPACE + { 0x2060, BIDI_BN }, // WORD JOINER + { 0x2061, BIDI_BN }, // FUNCTION APPLICATION + { 0x2062, BIDI_BN }, // INVISIBLE TIMES + { 0x2063, BIDI_BN }, // INVISIBLE SEPARATOR + { 0x2064, BIDI_BN }, // INVISIBLE PLUS + { 0x2066, BIDI_LRI }, // LEFT-TO-RIGHT ISOLATE + { 0x2067, BIDI_RLI }, // RIGHT-TO-LEFT ISOLATE + { 0x2068, BIDI_FSI }, // FIRST STRONG ISOLATE + { 0x2069, BIDI_PDI }, // POP DIRECTIONAL ISOLATE + { 0x206A, BIDI_BN }, // INHIBIT SYMMETRIC SWAPPING + { 0x206B, BIDI_BN }, // ACTIVATE SYMMETRIC SWAPPING + { 0x206C, BIDI_BN }, // INHIBIT ARABIC FORM SHAPING + { 0x206D, BIDI_BN }, // ACTIVATE ARABIC FORM SHAPING + { 0x206E, BIDI_BN }, // NATIONAL DIGIT SHAPES + { 0x206F, BIDI_BN }, // NOMINAL DIGIT SHAPES + { 0x2070, BIDI_EN }, // SUPERSCRIPT ZERO + { 0x2071, BIDI_L }, // SUPERSCRIPT LATIN SMALL LETTER I + { 0x2074, BIDI_EN }, // SUPERSCRIPT FOUR + { 0x2075, BIDI_EN }, // SUPERSCRIPT FIVE + { 0x2076, BIDI_EN }, // SUPERSCRIPT SIX + { 0x2077, BIDI_EN }, // SUPERSCRIPT SEVEN + { 0x2078, BIDI_EN }, // SUPERSCRIPT EIGHT + { 0x2079, BIDI_EN }, // SUPERSCRIPT NINE + { 0x207A, BIDI_ES }, // SUPERSCRIPT PLUS SIGN + { 0x207B, BIDI_ES }, // SUPERSCRIPT MINUS + { 0x207C, BIDI_ON }, // SUPERSCRIPT EQUALS SIGN + { 0x207D, BIDI_ON }, // SUPERSCRIPT LEFT PARENTHESIS + { 0x207E, BIDI_ON }, // SUPERSCRIPT RIGHT PARENTHESIS + { 0x207F, BIDI_L }, // SUPERSCRIPT LATIN SMALL LETTER N + { 0x2080, BIDI_EN }, // SUBSCRIPT ZERO + { 0x2081, BIDI_EN }, // SUBSCRIPT ONE + { 0x2082, BIDI_EN }, // SUBSCRIPT TWO + { 0x2083, BIDI_EN }, // SUBSCRIPT THREE + { 0x2084, BIDI_EN }, // SUBSCRIPT FOUR + { 0x2085, BIDI_EN }, // SUBSCRIPT FIVE + { 0x2086, BIDI_EN }, // SUBSCRIPT SIX + { 0x2087, BIDI_EN }, // SUBSCRIPT SEVEN + { 0x2088, BIDI_EN }, // SUBSCRIPT EIGHT + { 0x2089, BIDI_EN }, // SUBSCRIPT NINE + { 0x208A, BIDI_ES }, // SUBSCRIPT PLUS SIGN + { 0x208B, BIDI_ES }, // SUBSCRIPT MINUS + { 0x208C, BIDI_ON }, // SUBSCRIPT EQUALS SIGN + { 0x208D, BIDI_ON }, // SUBSCRIPT LEFT PARENTHESIS + { 0x208E, BIDI_ON }, // SUBSCRIPT RIGHT PARENTHESIS + { 0x2090, BIDI_L }, // LATIN SUBSCRIPT SMALL LETTER A + { 0x2091, BIDI_L }, // LATIN SUBSCRIPT SMALL LETTER E + { 0x2092, BIDI_L }, // LATIN SUBSCRIPT SMALL LETTER O + { 0x2093, BIDI_L }, // LATIN SUBSCRIPT SMALL LETTER X + { 0x2094, BIDI_L }, // LATIN SUBSCRIPT SMALL LETTER SCHWA + { 0x2095, BIDI_L }, // LATIN SUBSCRIPT SMALL LETTER H + { 0x2096, BIDI_L }, // LATIN SUBSCRIPT SMALL LETTER K + { 0x2097, BIDI_L }, // LATIN SUBSCRIPT SMALL LETTER L + { 0x2098, BIDI_L }, // LATIN SUBSCRIPT SMALL LETTER M + { 0x2099, BIDI_L }, // LATIN SUBSCRIPT SMALL LETTER N + { 0x209A, BIDI_L }, // LATIN SUBSCRIPT SMALL LETTER P + { 0x209B, BIDI_L }, // LATIN SUBSCRIPT SMALL LETTER S + { 0x209C, BIDI_L }, // LATIN SUBSCRIPT SMALL LETTER T + { 0x20A0, BIDI_ET }, // EURO-CURRENCY SIGN + { 0x20A1, BIDI_ET }, // COLON SIGN + { 0x20A2, BIDI_ET }, // CRUZEIRO SIGN + { 0x20A3, BIDI_ET }, // FRENCH FRANC SIGN + { 0x20A4, BIDI_ET }, // LIRA SIGN + { 0x20A5, BIDI_ET }, // MILL SIGN + { 0x20A6, BIDI_ET }, // NAIRA SIGN + { 0x20A7, BIDI_ET }, // PESETA SIGN + { 0x20A8, BIDI_ET }, // RUPEE SIGN + { 0x20A9, BIDI_ET }, // WON SIGN + { 0x20AA, BIDI_ET }, // NEW SHEQEL SIGN + { 0x20AB, BIDI_ET }, // DONG SIGN + { 0x20AC, BIDI_ET }, // EURO SIGN + { 0x20AD, BIDI_ET }, // KIP SIGN + { 0x20AE, BIDI_ET }, // TUGRIK SIGN + { 0x20AF, BIDI_ET }, // DRACHMA SIGN + { 0x20B0, BIDI_ET }, // GERMAN PENNY SIGN + { 0x20B1, BIDI_ET }, // PESO SIGN + { 0x20B2, BIDI_ET }, // GUARANI SIGN + { 0x20B3, BIDI_ET }, // AUSTRAL SIGN + { 0x20B4, BIDI_ET }, // HRYVNIA SIGN + { 0x20B5, BIDI_ET }, // CEDI SIGN + { 0x20B6, BIDI_ET }, // LIVRE TOURNOIS SIGN + { 0x20B7, BIDI_ET }, // SPESMILO SIGN + { 0x20B8, BIDI_ET }, // TENGE SIGN + { 0x20B9, BIDI_ET }, // INDIAN RUPEE SIGN + { 0x20BA, BIDI_ET }, // TURKISH LIRA SIGN + { 0x20BB, BIDI_ET }, // NORDIC MARK SIGN + { 0x20BC, BIDI_ET }, // MANAT SIGN + { 0x20BD, BIDI_ET }, // RUBLE SIGN + { 0x20BE, BIDI_ET }, // LARI SIGN + { 0x20D0, BIDI_NSM }, // COMBINING LEFT HARPOON ABOVE + { 0x20D1, BIDI_NSM }, // COMBINING RIGHT HARPOON ABOVE + { 0x20D2, BIDI_NSM }, // COMBINING LONG VERTICAL LINE OVERLAY + { 0x20D3, BIDI_NSM }, // COMBINING SHORT VERTICAL LINE OVERLAY + { 0x20D4, BIDI_NSM }, // COMBINING ANTICLOCKWISE ARROW ABOVE + { 0x20D5, BIDI_NSM }, // COMBINING CLOCKWISE ARROW ABOVE + { 0x20D6, BIDI_NSM }, // COMBINING LEFT ARROW ABOVE + { 0x20D7, BIDI_NSM }, // COMBINING RIGHT ARROW ABOVE + { 0x20D8, BIDI_NSM }, // COMBINING RING OVERLAY + { 0x20D9, BIDI_NSM }, // COMBINING CLOCKWISE RING OVERLAY + { 0x20DA, BIDI_NSM }, // COMBINING ANTICLOCKWISE RING OVERLAY + { 0x20DB, BIDI_NSM }, // COMBINING THREE DOTS ABOVE + { 0x20DC, BIDI_NSM }, // COMBINING FOUR DOTS ABOVE + { 0x20DD, BIDI_NSM }, // COMBINING ENCLOSING CIRCLE + { 0x20DE, BIDI_NSM }, // COMBINING ENCLOSING SQUARE + { 0x20DF, BIDI_NSM }, // COMBINING ENCLOSING DIAMOND + { 0x20E0, BIDI_NSM }, // COMBINING ENCLOSING CIRCLE BACKSLASH + { 0x20E1, BIDI_NSM }, // COMBINING LEFT RIGHT ARROW ABOVE + { 0x20E2, BIDI_NSM }, // COMBINING ENCLOSING SCREEN + { 0x20E3, BIDI_NSM }, // COMBINING ENCLOSING KEYCAP + { 0x20E4, BIDI_NSM }, // COMBINING ENCLOSING UPWARD POINTING TRIANGLE + { 0x20E5, BIDI_NSM }, // COMBINING REVERSE SOLIDUS OVERLAY + { 0x20E6, BIDI_NSM }, // COMBINING DOUBLE VERTICAL STROKE OVERLAY + { 0x20E7, BIDI_NSM }, // COMBINING ANNUITY SYMBOL + { 0x20E8, BIDI_NSM }, // COMBINING TRIPLE UNDERDOT + { 0x20E9, BIDI_NSM }, // COMBINING WIDE BRIDGE ABOVE + { 0x20EA, BIDI_NSM }, // COMBINING LEFTWARDS ARROW OVERLAY + { 0x20EB, BIDI_NSM }, // COMBINING LONG DOUBLE SOLIDUS OVERLAY + { 0x20EC, BIDI_NSM }, // COMBINING RIGHTWARDS HARPOON WITH BARB DOWNWARDS + { 0x20ED, BIDI_NSM }, // COMBINING LEFTWARDS HARPOON WITH BARB DOWNWARDS + { 0x20EE, BIDI_NSM }, // COMBINING LEFT ARROW BELOW + { 0x20EF, BIDI_NSM }, // COMBINING RIGHT ARROW BELOW + { 0x20F0, BIDI_NSM }, // COMBINING ASTERISK ABOVE + { 0x2100, BIDI_ON }, // ACCOUNT OF + { 0x2101, BIDI_ON }, // ADDRESSED TO THE SUBJECT + { 0x2102, BIDI_L }, // DOUBLE-STRUCK CAPITAL C + { 0x2103, BIDI_ON }, // DEGREE CELSIUS + { 0x2104, BIDI_ON }, // CENTRE LINE SYMBOL + { 0x2105, BIDI_ON }, // CARE OF + { 0x2106, BIDI_ON }, // CADA UNA + { 0x2107, BIDI_L }, // EULER CONSTANT + { 0x2108, BIDI_ON }, // SCRUPLE + { 0x2109, BIDI_ON }, // DEGREE FAHRENHEIT + { 0x210A, BIDI_L }, // SCRIPT SMALL G + { 0x210B, BIDI_L }, // SCRIPT CAPITAL H + { 0x210C, BIDI_L }, // BLACK-LETTER CAPITAL H + { 0x210D, BIDI_L }, // DOUBLE-STRUCK CAPITAL H + { 0x210E, BIDI_L }, // PLANCK CONSTANT + { 0x210F, BIDI_L }, // PLANCK CONSTANT OVER TWO PI + { 0x2110, BIDI_L }, // SCRIPT CAPITAL I + { 0x2111, BIDI_L }, // BLACK-LETTER CAPITAL I + { 0x2112, BIDI_L }, // SCRIPT CAPITAL L + { 0x2113, BIDI_L }, // SCRIPT SMALL L + { 0x2114, BIDI_ON }, // L B BAR SYMBOL + { 0x2115, BIDI_L }, // DOUBLE-STRUCK CAPITAL N + { 0x2116, BIDI_ON }, // NUMERO SIGN + { 0x2117, BIDI_ON }, // SOUND RECORDING COPYRIGHT + { 0x2118, BIDI_ON }, // SCRIPT CAPITAL P + { 0x2119, BIDI_L }, // DOUBLE-STRUCK CAPITAL P + { 0x211A, BIDI_L }, // DOUBLE-STRUCK CAPITAL Q + { 0x211B, BIDI_L }, // SCRIPT CAPITAL R + { 0x211C, BIDI_L }, // BLACK-LETTER CAPITAL R + { 0x211D, BIDI_L }, // DOUBLE-STRUCK CAPITAL R + { 0x211E, BIDI_ON }, // PRESCRIPTION TAKE + { 0x211F, BIDI_ON }, // RESPONSE + { 0x2120, BIDI_ON }, // SERVICE MARK + { 0x2121, BIDI_ON }, // TELEPHONE SIGN + { 0x2122, BIDI_ON }, // TRADE MARK SIGN + { 0x2123, BIDI_ON }, // VERSICLE + { 0x2124, BIDI_L }, // DOUBLE-STRUCK CAPITAL Z + { 0x2125, BIDI_ON }, // OUNCE SIGN + { 0x2126, BIDI_L }, // OHM SIGN + { 0x2127, BIDI_ON }, // INVERTED OHM SIGN + { 0x2128, BIDI_L }, // BLACK-LETTER CAPITAL Z + { 0x2129, BIDI_ON }, // TURNED GREEK SMALL LETTER IOTA + { 0x212A, BIDI_L }, // KELVIN SIGN + { 0x212B, BIDI_L }, // ANGSTROM SIGN + { 0x212C, BIDI_L }, // SCRIPT CAPITAL B + { 0x212D, BIDI_L }, // BLACK-LETTER CAPITAL C + { 0x212E, BIDI_ET }, // ESTIMATED SYMBOL + { 0x212F, BIDI_L }, // SCRIPT SMALL E + { 0x2130, BIDI_L }, // SCRIPT CAPITAL E + { 0x2131, BIDI_L }, // SCRIPT CAPITAL F + { 0x2132, BIDI_L }, // TURNED CAPITAL F + { 0x2133, BIDI_L }, // SCRIPT CAPITAL M + { 0x2134, BIDI_L }, // SCRIPT SMALL O + { 0x2135, BIDI_L }, // ALEF SYMBOL + { 0x2136, BIDI_L }, // BET SYMBOL + { 0x2137, BIDI_L }, // GIMEL SYMBOL + { 0x2138, BIDI_L }, // DALET SYMBOL + { 0x2139, BIDI_L }, // INFORMATION SOURCE + { 0x213A, BIDI_ON }, // ROTATED CAPITAL Q + { 0x213B, BIDI_ON }, // FACSIMILE SIGN + { 0x213C, BIDI_L }, // DOUBLE-STRUCK SMALL PI + { 0x213D, BIDI_L }, // DOUBLE-STRUCK SMALL GAMMA + { 0x213E, BIDI_L }, // DOUBLE-STRUCK CAPITAL GAMMA + { 0x213F, BIDI_L }, // DOUBLE-STRUCK CAPITAL PI + { 0x2140, BIDI_ON }, // DOUBLE-STRUCK N-ARY SUMMATION + { 0x2141, BIDI_ON }, // TURNED SANS-SERIF CAPITAL G + { 0x2142, BIDI_ON }, // TURNED SANS-SERIF CAPITAL L + { 0x2143, BIDI_ON }, // REVERSED SANS-SERIF CAPITAL L + { 0x2144, BIDI_ON }, // TURNED SANS-SERIF CAPITAL Y + { 0x2145, BIDI_L }, // DOUBLE-STRUCK ITALIC CAPITAL D + { 0x2146, BIDI_L }, // DOUBLE-STRUCK ITALIC SMALL D + { 0x2147, BIDI_L }, // DOUBLE-STRUCK ITALIC SMALL E + { 0x2148, BIDI_L }, // DOUBLE-STRUCK ITALIC SMALL I + { 0x2149, BIDI_L }, // DOUBLE-STRUCK ITALIC SMALL J + { 0x214A, BIDI_ON }, // PROPERTY LINE + { 0x214B, BIDI_ON }, // TURNED AMPERSAND + { 0x214C, BIDI_ON }, // PER SIGN + { 0x214D, BIDI_ON }, // AKTIESELSKAB + { 0x214E, BIDI_L }, // TURNED SMALL F + { 0x214F, BIDI_L }, // SYMBOL FOR SAMARITAN SOURCE + { 0x2150, BIDI_ON }, // VULGAR FRACTION ONE SEVENTH + { 0x2151, BIDI_ON }, // VULGAR FRACTION ONE NINTH + { 0x2152, BIDI_ON }, // VULGAR FRACTION ONE TENTH + { 0x2153, BIDI_ON }, // VULGAR FRACTION ONE THIRD + { 0x2154, BIDI_ON }, // VULGAR FRACTION TWO THIRDS + { 0x2155, BIDI_ON }, // VULGAR FRACTION ONE FIFTH + { 0x2156, BIDI_ON }, // VULGAR FRACTION TWO FIFTHS + { 0x2157, BIDI_ON }, // VULGAR FRACTION THREE FIFTHS + { 0x2158, BIDI_ON }, // VULGAR FRACTION FOUR FIFTHS + { 0x2159, BIDI_ON }, // VULGAR FRACTION ONE SIXTH + { 0x215A, BIDI_ON }, // VULGAR FRACTION FIVE SIXTHS + { 0x215B, BIDI_ON }, // VULGAR FRACTION ONE EIGHTH + { 0x215C, BIDI_ON }, // VULGAR FRACTION THREE EIGHTHS + { 0x215D, BIDI_ON }, // VULGAR FRACTION FIVE EIGHTHS + { 0x215E, BIDI_ON }, // VULGAR FRACTION SEVEN EIGHTHS + { 0x215F, BIDI_ON }, // FRACTION NUMERATOR ONE + { 0x2160, BIDI_L }, // ROMAN NUMERAL ONE + { 0x2161, BIDI_L }, // ROMAN NUMERAL TWO + { 0x2162, BIDI_L }, // ROMAN NUMERAL THREE + { 0x2163, BIDI_L }, // ROMAN NUMERAL FOUR + { 0x2164, BIDI_L }, // ROMAN NUMERAL FIVE + { 0x2165, BIDI_L }, // ROMAN NUMERAL SIX + { 0x2166, BIDI_L }, // ROMAN NUMERAL SEVEN + { 0x2167, BIDI_L }, // ROMAN NUMERAL EIGHT + { 0x2168, BIDI_L }, // ROMAN NUMERAL NINE + { 0x2169, BIDI_L }, // ROMAN NUMERAL TEN + { 0x216A, BIDI_L }, // ROMAN NUMERAL ELEVEN + { 0x216B, BIDI_L }, // ROMAN NUMERAL TWELVE + { 0x216C, BIDI_L }, // ROMAN NUMERAL FIFTY + { 0x216D, BIDI_L }, // ROMAN NUMERAL ONE HUNDRED + { 0x216E, BIDI_L }, // ROMAN NUMERAL FIVE HUNDRED + { 0x216F, BIDI_L }, // ROMAN NUMERAL ONE THOUSAND + { 0x2170, BIDI_L }, // SMALL ROMAN NUMERAL ONE + { 0x2171, BIDI_L }, // SMALL ROMAN NUMERAL TWO + { 0x2172, BIDI_L }, // SMALL ROMAN NUMERAL THREE + { 0x2173, BIDI_L }, // SMALL ROMAN NUMERAL FOUR + { 0x2174, BIDI_L }, // SMALL ROMAN NUMERAL FIVE + { 0x2175, BIDI_L }, // SMALL ROMAN NUMERAL SIX + { 0x2176, BIDI_L }, // SMALL ROMAN NUMERAL SEVEN + { 0x2177, BIDI_L }, // SMALL ROMAN NUMERAL EIGHT + { 0x2178, BIDI_L }, // SMALL ROMAN NUMERAL NINE + { 0x2179, BIDI_L }, // SMALL ROMAN NUMERAL TEN + { 0x217A, BIDI_L }, // SMALL ROMAN NUMERAL ELEVEN + { 0x217B, BIDI_L }, // SMALL ROMAN NUMERAL TWELVE + { 0x217C, BIDI_L }, // SMALL ROMAN NUMERAL FIFTY + { 0x217D, BIDI_L }, // SMALL ROMAN NUMERAL ONE HUNDRED + { 0x217E, BIDI_L }, // SMALL ROMAN NUMERAL FIVE HUNDRED + { 0x217F, BIDI_L }, // SMALL ROMAN NUMERAL ONE THOUSAND + { 0x2180, BIDI_L }, // ROMAN NUMERAL ONE THOUSAND C D + { 0x2181, BIDI_L }, // ROMAN NUMERAL FIVE THOUSAND + { 0x2182, BIDI_L }, // ROMAN NUMERAL TEN THOUSAND + { 0x2183, BIDI_L }, // ROMAN NUMERAL REVERSED ONE HUNDRED + { 0x2184, BIDI_L }, // LATIN SMALL LETTER REVERSED C + { 0x2185, BIDI_L }, // ROMAN NUMERAL SIX LATE FORM + { 0x2186, BIDI_L }, // ROMAN NUMERAL FIFTY EARLY FORM + { 0x2187, BIDI_L }, // ROMAN NUMERAL FIFTY THOUSAND + { 0x2188, BIDI_L }, // ROMAN NUMERAL ONE HUNDRED THOUSAND + { 0x2189, BIDI_ON }, // VULGAR FRACTION ZERO THIRDS + { 0x218A, BIDI_ON }, // TURNED DIGIT TWO + { 0x218B, BIDI_ON }, // TURNED DIGIT THREE + { 0x2190, BIDI_ON }, // LEFTWARDS ARROW + { 0x2191, BIDI_ON }, // UPWARDS ARROW + { 0x2192, BIDI_ON }, // RIGHTWARDS ARROW + { 0x2193, BIDI_ON }, // DOWNWARDS ARROW + { 0x2194, BIDI_ON }, // LEFT RIGHT ARROW + { 0x2195, BIDI_ON }, // UP DOWN ARROW + { 0x2196, BIDI_ON }, // NORTH WEST ARROW + { 0x2197, BIDI_ON }, // NORTH EAST ARROW + { 0x2198, BIDI_ON }, // SOUTH EAST ARROW + { 0x2199, BIDI_ON }, // SOUTH WEST ARROW + { 0x219A, BIDI_ON }, // LEFTWARDS ARROW WITH STROKE + { 0x219B, BIDI_ON }, // RIGHTWARDS ARROW WITH STROKE + { 0x219C, BIDI_ON }, // LEFTWARDS WAVE ARROW + { 0x219D, BIDI_ON }, // RIGHTWARDS WAVE ARROW + { 0x219E, BIDI_ON }, // LEFTWARDS TWO HEADED ARROW + { 0x219F, BIDI_ON }, // UPWARDS TWO HEADED ARROW + { 0x21A0, BIDI_ON }, // RIGHTWARDS TWO HEADED ARROW + { 0x21A1, BIDI_ON }, // DOWNWARDS TWO HEADED ARROW + { 0x21A2, BIDI_ON }, // LEFTWARDS ARROW WITH TAIL + { 0x21A3, BIDI_ON }, // RIGHTWARDS ARROW WITH TAIL + { 0x21A4, BIDI_ON }, // LEFTWARDS ARROW FROM BAR + { 0x21A5, BIDI_ON }, // UPWARDS ARROW FROM BAR + { 0x21A6, BIDI_ON }, // RIGHTWARDS ARROW FROM BAR + { 0x21A7, BIDI_ON }, // DOWNWARDS ARROW FROM BAR + { 0x21A8, BIDI_ON }, // UP DOWN ARROW WITH BASE + { 0x21A9, BIDI_ON }, // LEFTWARDS ARROW WITH HOOK + { 0x21AA, BIDI_ON }, // RIGHTWARDS ARROW WITH HOOK + { 0x21AB, BIDI_ON }, // LEFTWARDS ARROW WITH LOOP + { 0x21AC, BIDI_ON }, // RIGHTWARDS ARROW WITH LOOP + { 0x21AD, BIDI_ON }, // LEFT RIGHT WAVE ARROW + { 0x21AE, BIDI_ON }, // LEFT RIGHT ARROW WITH STROKE + { 0x21AF, BIDI_ON }, // DOWNWARDS ZIGZAG ARROW + { 0x21B0, BIDI_ON }, // UPWARDS ARROW WITH TIP LEFTWARDS + { 0x21B1, BIDI_ON }, // UPWARDS ARROW WITH TIP RIGHTWARDS + { 0x21B2, BIDI_ON }, // DOWNWARDS ARROW WITH TIP LEFTWARDS + { 0x21B3, BIDI_ON }, // DOWNWARDS ARROW WITH TIP RIGHTWARDS + { 0x21B4, BIDI_ON }, // RIGHTWARDS ARROW WITH CORNER DOWNWARDS + { 0x21B5, BIDI_ON }, // DOWNWARDS ARROW WITH CORNER LEFTWARDS + { 0x21B6, BIDI_ON }, // ANTICLOCKWISE TOP SEMICIRCLE ARROW + { 0x21B7, BIDI_ON }, // CLOCKWISE TOP SEMICIRCLE ARROW + { 0x21B8, BIDI_ON }, // NORTH WEST ARROW TO LONG BAR + { 0x21B9, BIDI_ON }, // LEFTWARDS ARROW TO BAR OVER RIGHTWARDS ARROW TO BAR + { 0x21BA, BIDI_ON }, // ANTICLOCKWISE OPEN CIRCLE ARROW + { 0x21BB, BIDI_ON }, // CLOCKWISE OPEN CIRCLE ARROW + { 0x21BC, BIDI_ON }, // LEFTWARDS HARPOON WITH BARB UPWARDS + { 0x21BD, BIDI_ON }, // LEFTWARDS HARPOON WITH BARB DOWNWARDS + { 0x21BE, BIDI_ON }, // UPWARDS HARPOON WITH BARB RIGHTWARDS + { 0x21BF, BIDI_ON }, // UPWARDS HARPOON WITH BARB LEFTWARDS + { 0x21C0, BIDI_ON }, // RIGHTWARDS HARPOON WITH BARB UPWARDS + { 0x21C1, BIDI_ON }, // RIGHTWARDS HARPOON WITH BARB DOWNWARDS + { 0x21C2, BIDI_ON }, // DOWNWARDS HARPOON WITH BARB RIGHTWARDS + { 0x21C3, BIDI_ON }, // DOWNWARDS HARPOON WITH BARB LEFTWARDS + { 0x21C4, BIDI_ON }, // RIGHTWARDS ARROW OVER LEFTWARDS ARROW + { 0x21C5, BIDI_ON }, // UPWARDS ARROW LEFTWARDS OF DOWNWARDS ARROW + { 0x21C6, BIDI_ON }, // LEFTWARDS ARROW OVER RIGHTWARDS ARROW + { 0x21C7, BIDI_ON }, // LEFTWARDS PAIRED ARROWS + { 0x21C8, BIDI_ON }, // UPWARDS PAIRED ARROWS + { 0x21C9, BIDI_ON }, // RIGHTWARDS PAIRED ARROWS + { 0x21CA, BIDI_ON }, // DOWNWARDS PAIRED ARROWS + { 0x21CB, BIDI_ON }, // LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON + { 0x21CC, BIDI_ON }, // RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON + { 0x21CD, BIDI_ON }, // LEFTWARDS DOUBLE ARROW WITH STROKE + { 0x21CE, BIDI_ON }, // LEFT RIGHT DOUBLE ARROW WITH STROKE + { 0x21CF, BIDI_ON }, // RIGHTWARDS DOUBLE ARROW WITH STROKE + { 0x21D0, BIDI_ON }, // LEFTWARDS DOUBLE ARROW + { 0x21D1, BIDI_ON }, // UPWARDS DOUBLE ARROW + { 0x21D2, BIDI_ON }, // RIGHTWARDS DOUBLE ARROW + { 0x21D3, BIDI_ON }, // DOWNWARDS DOUBLE ARROW + { 0x21D4, BIDI_ON }, // LEFT RIGHT DOUBLE ARROW + { 0x21D5, BIDI_ON }, // UP DOWN DOUBLE ARROW + { 0x21D6, BIDI_ON }, // NORTH WEST DOUBLE ARROW + { 0x21D7, BIDI_ON }, // NORTH EAST DOUBLE ARROW + { 0x21D8, BIDI_ON }, // SOUTH EAST DOUBLE ARROW + { 0x21D9, BIDI_ON }, // SOUTH WEST DOUBLE ARROW + { 0x21DA, BIDI_ON }, // LEFTWARDS TRIPLE ARROW + { 0x21DB, BIDI_ON }, // RIGHTWARDS TRIPLE ARROW + { 0x21DC, BIDI_ON }, // LEFTWARDS SQUIGGLE ARROW + { 0x21DD, BIDI_ON }, // RIGHTWARDS SQUIGGLE ARROW + { 0x21DE, BIDI_ON }, // UPWARDS ARROW WITH DOUBLE STROKE + { 0x21DF, BIDI_ON }, // DOWNWARDS ARROW WITH DOUBLE STROKE + { 0x21E0, BIDI_ON }, // LEFTWARDS DASHED ARROW + { 0x21E1, BIDI_ON }, // UPWARDS DASHED ARROW + { 0x21E2, BIDI_ON }, // RIGHTWARDS DASHED ARROW + { 0x21E3, BIDI_ON }, // DOWNWARDS DASHED ARROW + { 0x21E4, BIDI_ON }, // LEFTWARDS ARROW TO BAR + { 0x21E5, BIDI_ON }, // RIGHTWARDS ARROW TO BAR + { 0x21E6, BIDI_ON }, // LEFTWARDS WHITE ARROW + { 0x21E7, BIDI_ON }, // UPWARDS WHITE ARROW + { 0x21E8, BIDI_ON }, // RIGHTWARDS WHITE ARROW + { 0x21E9, BIDI_ON }, // DOWNWARDS WHITE ARROW + { 0x21EA, BIDI_ON }, // UPWARDS WHITE ARROW FROM BAR + { 0x21EB, BIDI_ON }, // UPWARDS WHITE ARROW ON PEDESTAL + { 0x21EC, BIDI_ON }, // UPWARDS WHITE ARROW ON PEDESTAL WITH HORIZONTAL BAR + { 0x21ED, BIDI_ON }, // UPWARDS WHITE ARROW ON PEDESTAL WITH VERTICAL BAR + { 0x21EE, BIDI_ON }, // UPWARDS WHITE DOUBLE ARROW + { 0x21EF, BIDI_ON }, // UPWARDS WHITE DOUBLE ARROW ON PEDESTAL + { 0x21F0, BIDI_ON }, // RIGHTWARDS WHITE ARROW FROM WALL + { 0x21F1, BIDI_ON }, // NORTH WEST ARROW TO CORNER + { 0x21F2, BIDI_ON }, // SOUTH EAST ARROW TO CORNER + { 0x21F3, BIDI_ON }, // UP DOWN WHITE ARROW + { 0x21F4, BIDI_ON }, // RIGHT ARROW WITH SMALL CIRCLE + { 0x21F5, BIDI_ON }, // DOWNWARDS ARROW LEFTWARDS OF UPWARDS ARROW + { 0x21F6, BIDI_ON }, // THREE RIGHTWARDS ARROWS + { 0x21F7, BIDI_ON }, // LEFTWARDS ARROW WITH VERTICAL STROKE + { 0x21F8, BIDI_ON }, // RIGHTWARDS ARROW WITH VERTICAL STROKE + { 0x21F9, BIDI_ON }, // LEFT RIGHT ARROW WITH VERTICAL STROKE + { 0x21FA, BIDI_ON }, // LEFTWARDS ARROW WITH DOUBLE VERTICAL STROKE + { 0x21FB, BIDI_ON }, // RIGHTWARDS ARROW WITH DOUBLE VERTICAL STROKE + { 0x21FC, BIDI_ON }, // LEFT RIGHT ARROW WITH DOUBLE VERTICAL STROKE + { 0x21FD, BIDI_ON }, // LEFTWARDS OPEN-HEADED ARROW + { 0x21FE, BIDI_ON }, // RIGHTWARDS OPEN-HEADED ARROW + { 0x21FF, BIDI_ON }, // LEFT RIGHT OPEN-HEADED ARROW + { 0x2200, BIDI_ON }, // FOR ALL + { 0x2201, BIDI_ON }, // COMPLEMENT + { 0x2202, BIDI_ON }, // PARTIAL DIFFERENTIAL + { 0x2203, BIDI_ON }, // THERE EXISTS + { 0x2204, BIDI_ON }, // THERE DOES NOT EXIST + { 0x2205, BIDI_ON }, // EMPTY SET + { 0x2206, BIDI_ON }, // INCREMENT + { 0x2207, BIDI_ON }, // NABLA + { 0x2208, BIDI_ON }, // ELEMENT OF + { 0x2209, BIDI_ON }, // NOT AN ELEMENT OF + { 0x220A, BIDI_ON }, // SMALL ELEMENT OF + { 0x220B, BIDI_ON }, // CONTAINS AS MEMBER + { 0x220C, BIDI_ON }, // DOES NOT CONTAIN AS MEMBER + { 0x220D, BIDI_ON }, // SMALL CONTAINS AS MEMBER + { 0x220E, BIDI_ON }, // END OF PROOF + { 0x220F, BIDI_ON }, // N-ARY PRODUCT + { 0x2210, BIDI_ON }, // N-ARY COPRODUCT + { 0x2211, BIDI_ON }, // N-ARY SUMMATION + { 0x2212, BIDI_ES }, // MINUS SIGN + { 0x2213, BIDI_ET }, // MINUS-OR-PLUS SIGN + { 0x2214, BIDI_ON }, // DOT PLUS + { 0x2215, BIDI_ON }, // DIVISION SLASH + { 0x2216, BIDI_ON }, // SET MINUS + { 0x2217, BIDI_ON }, // ASTERISK OPERATOR + { 0x2218, BIDI_ON }, // RING OPERATOR + { 0x2219, BIDI_ON }, // BULLET OPERATOR + { 0x221A, BIDI_ON }, // SQUARE ROOT + { 0x221B, BIDI_ON }, // CUBE ROOT + { 0x221C, BIDI_ON }, // FOURTH ROOT + { 0x221D, BIDI_ON }, // PROPORTIONAL TO + { 0x221E, BIDI_ON }, // INFINITY + { 0x221F, BIDI_ON }, // RIGHT ANGLE + { 0x2220, BIDI_ON }, // ANGLE + { 0x2221, BIDI_ON }, // MEASURED ANGLE + { 0x2222, BIDI_ON }, // SPHERICAL ANGLE + { 0x2223, BIDI_ON }, // DIVIDES + { 0x2224, BIDI_ON }, // DOES NOT DIVIDE + { 0x2225, BIDI_ON }, // PARALLEL TO + { 0x2226, BIDI_ON }, // NOT PARALLEL TO + { 0x2227, BIDI_ON }, // LOGICAL AND + { 0x2228, BIDI_ON }, // LOGICAL OR + { 0x2229, BIDI_ON }, // INTERSECTION + { 0x222A, BIDI_ON }, // UNION + { 0x222B, BIDI_ON }, // INTEGRAL + { 0x222C, BIDI_ON }, // DOUBLE INTEGRAL + { 0x222D, BIDI_ON }, // TRIPLE INTEGRAL + { 0x222E, BIDI_ON }, // CONTOUR INTEGRAL + { 0x222F, BIDI_ON }, // SURFACE INTEGRAL + { 0x2230, BIDI_ON }, // VOLUME INTEGRAL + { 0x2231, BIDI_ON }, // CLOCKWISE INTEGRAL + { 0x2232, BIDI_ON }, // CLOCKWISE CONTOUR INTEGRAL + { 0x2233, BIDI_ON }, // ANTICLOCKWISE CONTOUR INTEGRAL + { 0x2234, BIDI_ON }, // THEREFORE + { 0x2235, BIDI_ON }, // BECAUSE + { 0x2236, BIDI_ON }, // RATIO + { 0x2237, BIDI_ON }, // PROPORTION + { 0x2238, BIDI_ON }, // DOT MINUS + { 0x2239, BIDI_ON }, // EXCESS + { 0x223A, BIDI_ON }, // GEOMETRIC PROPORTION + { 0x223B, BIDI_ON }, // HOMOTHETIC + { 0x223C, BIDI_ON }, // TILDE OPERATOR + { 0x223D, BIDI_ON }, // REVERSED TILDE + { 0x223E, BIDI_ON }, // INVERTED LAZY S + { 0x223F, BIDI_ON }, // SINE WAVE + { 0x2240, BIDI_ON }, // WREATH PRODUCT + { 0x2241, BIDI_ON }, // NOT TILDE + { 0x2242, BIDI_ON }, // MINUS TILDE + { 0x2243, BIDI_ON }, // ASYMPTOTICALLY EQUAL TO + { 0x2244, BIDI_ON }, // NOT ASYMPTOTICALLY EQUAL TO + { 0x2245, BIDI_ON }, // APPROXIMATELY EQUAL TO + { 0x2246, BIDI_ON }, // APPROXIMATELY BUT NOT ACTUALLY EQUAL TO + { 0x2247, BIDI_ON }, // NEITHER APPROXIMATELY NOR ACTUALLY EQUAL TO + { 0x2248, BIDI_ON }, // ALMOST EQUAL TO + { 0x2249, BIDI_ON }, // NOT ALMOST EQUAL TO + { 0x224A, BIDI_ON }, // ALMOST EQUAL OR EQUAL TO + { 0x224B, BIDI_ON }, // TRIPLE TILDE + { 0x224C, BIDI_ON }, // ALL EQUAL TO + { 0x224D, BIDI_ON }, // EQUIVALENT TO + { 0x224E, BIDI_ON }, // GEOMETRICALLY EQUIVALENT TO + { 0x224F, BIDI_ON }, // DIFFERENCE BETWEEN + { 0x2250, BIDI_ON }, // APPROACHES THE LIMIT + { 0x2251, BIDI_ON }, // GEOMETRICALLY EQUAL TO + { 0x2252, BIDI_ON }, // APPROXIMATELY EQUAL TO OR THE IMAGE OF + { 0x2253, BIDI_ON }, // IMAGE OF OR APPROXIMATELY EQUAL TO + { 0x2254, BIDI_ON }, // COLON EQUALS + { 0x2255, BIDI_ON }, // EQUALS COLON + { 0x2256, BIDI_ON }, // RING IN EQUAL TO + { 0x2257, BIDI_ON }, // RING EQUAL TO + { 0x2258, BIDI_ON }, // CORRESPONDS TO + { 0x2259, BIDI_ON }, // ESTIMATES + { 0x225A, BIDI_ON }, // EQUIANGULAR TO + { 0x225B, BIDI_ON }, // STAR EQUALS + { 0x225C, BIDI_ON }, // DELTA EQUAL TO + { 0x225D, BIDI_ON }, // EQUAL TO BY DEFINITION + { 0x225E, BIDI_ON }, // MEASURED BY + { 0x225F, BIDI_ON }, // QUESTIONED EQUAL TO + { 0x2260, BIDI_ON }, // NOT EQUAL TO + { 0x2261, BIDI_ON }, // IDENTICAL TO + { 0x2262, BIDI_ON }, // NOT IDENTICAL TO + { 0x2263, BIDI_ON }, // STRICTLY EQUIVALENT TO + { 0x2264, BIDI_ON }, // LESS-THAN OR EQUAL TO + { 0x2265, BIDI_ON }, // GREATER-THAN OR EQUAL TO + { 0x2266, BIDI_ON }, // LESS-THAN OVER EQUAL TO + { 0x2267, BIDI_ON }, // GREATER-THAN OVER EQUAL TO + { 0x2268, BIDI_ON }, // LESS-THAN BUT NOT EQUAL TO + { 0x2269, BIDI_ON }, // GREATER-THAN BUT NOT EQUAL TO + { 0x226A, BIDI_ON }, // MUCH LESS-THAN + { 0x226B, BIDI_ON }, // MUCH GREATER-THAN + { 0x226C, BIDI_ON }, // BETWEEN + { 0x226D, BIDI_ON }, // NOT EQUIVALENT TO + { 0x226E, BIDI_ON }, // NOT LESS-THAN + { 0x226F, BIDI_ON }, // NOT GREATER-THAN + { 0x2270, BIDI_ON }, // NEITHER LESS-THAN NOR EQUAL TO + { 0x2271, BIDI_ON }, // NEITHER GREATER-THAN NOR EQUAL TO + { 0x2272, BIDI_ON }, // LESS-THAN OR EQUIVALENT TO + { 0x2273, BIDI_ON }, // GREATER-THAN OR EQUIVALENT TO + { 0x2274, BIDI_ON }, // NEITHER LESS-THAN NOR EQUIVALENT TO + { 0x2275, BIDI_ON }, // NEITHER GREATER-THAN NOR EQUIVALENT TO + { 0x2276, BIDI_ON }, // LESS-THAN OR GREATER-THAN + { 0x2277, BIDI_ON }, // GREATER-THAN OR LESS-THAN + { 0x2278, BIDI_ON }, // NEITHER LESS-THAN NOR GREATER-THAN + { 0x2279, BIDI_ON }, // NEITHER GREATER-THAN NOR LESS-THAN + { 0x227A, BIDI_ON }, // PRECEDES + { 0x227B, BIDI_ON }, // SUCCEEDS + { 0x227C, BIDI_ON }, // PRECEDES OR EQUAL TO + { 0x227D, BIDI_ON }, // SUCCEEDS OR EQUAL TO + { 0x227E, BIDI_ON }, // PRECEDES OR EQUIVALENT TO + { 0x227F, BIDI_ON }, // SUCCEEDS OR EQUIVALENT TO + { 0x2280, BIDI_ON }, // DOES NOT PRECEDE + { 0x2281, BIDI_ON }, // DOES NOT SUCCEED + { 0x2282, BIDI_ON }, // SUBSET OF + { 0x2283, BIDI_ON }, // SUPERSET OF + { 0x2284, BIDI_ON }, // NOT A SUBSET OF + { 0x2285, BIDI_ON }, // NOT A SUPERSET OF + { 0x2286, BIDI_ON }, // SUBSET OF OR EQUAL TO + { 0x2287, BIDI_ON }, // SUPERSET OF OR EQUAL TO + { 0x2288, BIDI_ON }, // NEITHER A SUBSET OF NOR EQUAL TO + { 0x2289, BIDI_ON }, // NEITHER A SUPERSET OF NOR EQUAL TO + { 0x228A, BIDI_ON }, // SUBSET OF WITH NOT EQUAL TO + { 0x228B, BIDI_ON }, // SUPERSET OF WITH NOT EQUAL TO + { 0x228C, BIDI_ON }, // MULTISET + { 0x228D, BIDI_ON }, // MULTISET MULTIPLICATION + { 0x228E, BIDI_ON }, // MULTISET UNION + { 0x228F, BIDI_ON }, // SQUARE IMAGE OF + { 0x2290, BIDI_ON }, // SQUARE ORIGINAL OF + { 0x2291, BIDI_ON }, // SQUARE IMAGE OF OR EQUAL TO + { 0x2292, BIDI_ON }, // SQUARE ORIGINAL OF OR EQUAL TO + { 0x2293, BIDI_ON }, // SQUARE CAP + { 0x2294, BIDI_ON }, // SQUARE CUP + { 0x2295, BIDI_ON }, // CIRCLED PLUS + { 0x2296, BIDI_ON }, // CIRCLED MINUS + { 0x2297, BIDI_ON }, // CIRCLED TIMES + { 0x2298, BIDI_ON }, // CIRCLED DIVISION SLASH + { 0x2299, BIDI_ON }, // CIRCLED DOT OPERATOR + { 0x229A, BIDI_ON }, // CIRCLED RING OPERATOR + { 0x229B, BIDI_ON }, // CIRCLED ASTERISK OPERATOR + { 0x229C, BIDI_ON }, // CIRCLED EQUALS + { 0x229D, BIDI_ON }, // CIRCLED DASH + { 0x229E, BIDI_ON }, // SQUARED PLUS + { 0x229F, BIDI_ON }, // SQUARED MINUS + { 0x22A0, BIDI_ON }, // SQUARED TIMES + { 0x22A1, BIDI_ON }, // SQUARED DOT OPERATOR + { 0x22A2, BIDI_ON }, // RIGHT TACK + { 0x22A3, BIDI_ON }, // LEFT TACK + { 0x22A4, BIDI_ON }, // DOWN TACK + { 0x22A5, BIDI_ON }, // UP TACK + { 0x22A6, BIDI_ON }, // ASSERTION + { 0x22A7, BIDI_ON }, // MODELS + { 0x22A8, BIDI_ON }, // TRUE + { 0x22A9, BIDI_ON }, // FORCES + { 0x22AA, BIDI_ON }, // TRIPLE VERTICAL BAR RIGHT TURNSTILE + { 0x22AB, BIDI_ON }, // DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE + { 0x22AC, BIDI_ON }, // DOES NOT PROVE + { 0x22AD, BIDI_ON }, // NOT TRUE + { 0x22AE, BIDI_ON }, // DOES NOT FORCE + { 0x22AF, BIDI_ON }, // NEGATED DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE + { 0x22B0, BIDI_ON }, // PRECEDES UNDER RELATION + { 0x22B1, BIDI_ON }, // SUCCEEDS UNDER RELATION + { 0x22B2, BIDI_ON }, // NORMAL SUBGROUP OF + { 0x22B3, BIDI_ON }, // CONTAINS AS NORMAL SUBGROUP + { 0x22B4, BIDI_ON }, // NORMAL SUBGROUP OF OR EQUAL TO + { 0x22B5, BIDI_ON }, // CONTAINS AS NORMAL SUBGROUP OR EQUAL TO + { 0x22B6, BIDI_ON }, // ORIGINAL OF + { 0x22B7, BIDI_ON }, // IMAGE OF + { 0x22B8, BIDI_ON }, // MULTIMAP + { 0x22B9, BIDI_ON }, // HERMITIAN CONJUGATE MATRIX + { 0x22BA, BIDI_ON }, // INTERCALATE + { 0x22BB, BIDI_ON }, // XOR + { 0x22BC, BIDI_ON }, // NAND + { 0x22BD, BIDI_ON }, // NOR + { 0x22BE, BIDI_ON }, // RIGHT ANGLE WITH ARC + { 0x22BF, BIDI_ON }, // RIGHT TRIANGLE + { 0x22C0, BIDI_ON }, // N-ARY LOGICAL AND + { 0x22C1, BIDI_ON }, // N-ARY LOGICAL OR + { 0x22C2, BIDI_ON }, // N-ARY INTERSECTION + { 0x22C3, BIDI_ON }, // N-ARY UNION + { 0x22C4, BIDI_ON }, // DIAMOND OPERATOR + { 0x22C5, BIDI_ON }, // DOT OPERATOR + { 0x22C6, BIDI_ON }, // STAR OPERATOR + { 0x22C7, BIDI_ON }, // DIVISION TIMES + { 0x22C8, BIDI_ON }, // BOWTIE + { 0x22C9, BIDI_ON }, // LEFT NORMAL FACTOR SEMIDIRECT PRODUCT + { 0x22CA, BIDI_ON }, // RIGHT NORMAL FACTOR SEMIDIRECT PRODUCT + { 0x22CB, BIDI_ON }, // LEFT SEMIDIRECT PRODUCT + { 0x22CC, BIDI_ON }, // RIGHT SEMIDIRECT PRODUCT + { 0x22CD, BIDI_ON }, // REVERSED TILDE EQUALS + { 0x22CE, BIDI_ON }, // CURLY LOGICAL OR + { 0x22CF, BIDI_ON }, // CURLY LOGICAL AND + { 0x22D0, BIDI_ON }, // DOUBLE SUBSET + { 0x22D1, BIDI_ON }, // DOUBLE SUPERSET + { 0x22D2, BIDI_ON }, // DOUBLE INTERSECTION + { 0x22D3, BIDI_ON }, // DOUBLE UNION + { 0x22D4, BIDI_ON }, // PITCHFORK + { 0x22D5, BIDI_ON }, // EQUAL AND PARALLEL TO + { 0x22D6, BIDI_ON }, // LESS-THAN WITH DOT + { 0x22D7, BIDI_ON }, // GREATER-THAN WITH DOT + { 0x22D8, BIDI_ON }, // VERY MUCH LESS-THAN + { 0x22D9, BIDI_ON }, // VERY MUCH GREATER-THAN + { 0x22DA, BIDI_ON }, // LESS-THAN EQUAL TO OR GREATER-THAN + { 0x22DB, BIDI_ON }, // GREATER-THAN EQUAL TO OR LESS-THAN + { 0x22DC, BIDI_ON }, // EQUAL TO OR LESS-THAN + { 0x22DD, BIDI_ON }, // EQUAL TO OR GREATER-THAN + { 0x22DE, BIDI_ON }, // EQUAL TO OR PRECEDES + { 0x22DF, BIDI_ON }, // EQUAL TO OR SUCCEEDS + { 0x22E0, BIDI_ON }, // DOES NOT PRECEDE OR EQUAL + { 0x22E1, BIDI_ON }, // DOES NOT SUCCEED OR EQUAL + { 0x22E2, BIDI_ON }, // NOT SQUARE IMAGE OF OR EQUAL TO + { 0x22E3, BIDI_ON }, // NOT SQUARE ORIGINAL OF OR EQUAL TO + { 0x22E4, BIDI_ON }, // SQUARE IMAGE OF OR NOT EQUAL TO + { 0x22E5, BIDI_ON }, // SQUARE ORIGINAL OF OR NOT EQUAL TO + { 0x22E6, BIDI_ON }, // LESS-THAN BUT NOT EQUIVALENT TO + { 0x22E7, BIDI_ON }, // GREATER-THAN BUT NOT EQUIVALENT TO + { 0x22E8, BIDI_ON }, // PRECEDES BUT NOT EQUIVALENT TO + { 0x22E9, BIDI_ON }, // SUCCEEDS BUT NOT EQUIVALENT TO + { 0x22EA, BIDI_ON }, // NOT NORMAL SUBGROUP OF + { 0x22EB, BIDI_ON }, // DOES NOT CONTAIN AS NORMAL SUBGROUP + { 0x22EC, BIDI_ON }, // NOT NORMAL SUBGROUP OF OR EQUAL TO + { 0x22ED, BIDI_ON }, // DOES NOT CONTAIN AS NORMAL SUBGROUP OR EQUAL + { 0x22EE, BIDI_ON }, // VERTICAL ELLIPSIS + { 0x22EF, BIDI_ON }, // MIDLINE HORIZONTAL ELLIPSIS + { 0x22F0, BIDI_ON }, // UP RIGHT DIAGONAL ELLIPSIS + { 0x22F1, BIDI_ON }, // DOWN RIGHT DIAGONAL ELLIPSIS + { 0x22F2, BIDI_ON }, // ELEMENT OF WITH LONG HORIZONTAL STROKE + { 0x22F3, BIDI_ON }, // ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE + { 0x22F4, BIDI_ON }, // SMALL ELEMENT OF WITH VERTICAL BAR AT END OF HORIZONTAL STROKE + { 0x22F5, BIDI_ON }, // ELEMENT OF WITH DOT ABOVE + { 0x22F6, BIDI_ON }, // ELEMENT OF WITH OVERBAR + { 0x22F7, BIDI_ON }, // SMALL ELEMENT OF WITH OVERBAR + { 0x22F8, BIDI_ON }, // ELEMENT OF WITH UNDERBAR + { 0x22F9, BIDI_ON }, // ELEMENT OF WITH TWO HORIZONTAL STROKES + { 0x22FA, BIDI_ON }, // CONTAINS WITH LONG HORIZONTAL STROKE + { 0x22FB, BIDI_ON }, // CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE + { 0x22FC, BIDI_ON }, // SMALL CONTAINS WITH VERTICAL BAR AT END OF HORIZONTAL STROKE + { 0x22FD, BIDI_ON }, // CONTAINS WITH OVERBAR + { 0x22FE, BIDI_ON }, // SMALL CONTAINS WITH OVERBAR + { 0x22FF, BIDI_ON }, // Z NOTATION BAG MEMBERSHIP + { 0x2300, BIDI_ON }, // DIAMETER SIGN + { 0x2301, BIDI_ON }, // ELECTRIC ARROW + { 0x2302, BIDI_ON }, // HOUSE + { 0x2303, BIDI_ON }, // UP ARROWHEAD + { 0x2304, BIDI_ON }, // DOWN ARROWHEAD + { 0x2305, BIDI_ON }, // PROJECTIVE + { 0x2306, BIDI_ON }, // PERSPECTIVE + { 0x2307, BIDI_ON }, // WAVY LINE + { 0x2308, BIDI_ON }, // LEFT CEILING + { 0x2309, BIDI_ON }, // RIGHT CEILING + { 0x230A, BIDI_ON }, // LEFT FLOOR + { 0x230B, BIDI_ON }, // RIGHT FLOOR + { 0x230C, BIDI_ON }, // BOTTOM RIGHT CROP + { 0x230D, BIDI_ON }, // BOTTOM LEFT CROP + { 0x230E, BIDI_ON }, // TOP RIGHT CROP + { 0x230F, BIDI_ON }, // TOP LEFT CROP + { 0x2310, BIDI_ON }, // REVERSED NOT SIGN + { 0x2311, BIDI_ON }, // SQUARE LOZENGE + { 0x2312, BIDI_ON }, // ARC + { 0x2313, BIDI_ON }, // SEGMENT + { 0x2314, BIDI_ON }, // SECTOR + { 0x2315, BIDI_ON }, // TELEPHONE RECORDER + { 0x2316, BIDI_ON }, // POSITION INDICATOR + { 0x2317, BIDI_ON }, // VIEWDATA SQUARE + { 0x2318, BIDI_ON }, // PLACE OF INTEREST SIGN + { 0x2319, BIDI_ON }, // TURNED NOT SIGN + { 0x231A, BIDI_ON }, // WATCH + { 0x231B, BIDI_ON }, // HOURGLASS + { 0x231C, BIDI_ON }, // TOP LEFT CORNER + { 0x231D, BIDI_ON }, // TOP RIGHT CORNER + { 0x231E, BIDI_ON }, // BOTTOM LEFT CORNER + { 0x231F, BIDI_ON }, // BOTTOM RIGHT CORNER + { 0x2320, BIDI_ON }, // TOP HALF INTEGRAL + { 0x2321, BIDI_ON }, // BOTTOM HALF INTEGRAL + { 0x2322, BIDI_ON }, // FROWN + { 0x2323, BIDI_ON }, // SMILE + { 0x2324, BIDI_ON }, // UP ARROWHEAD BETWEEN TWO HORIZONTAL BARS + { 0x2325, BIDI_ON }, // OPTION KEY + { 0x2326, BIDI_ON }, // ERASE TO THE RIGHT + { 0x2327, BIDI_ON }, // X IN A RECTANGLE BOX + { 0x2328, BIDI_ON }, // KEYBOARD + { 0x2329, BIDI_ON }, // LEFT-POINTING ANGLE BRACKET + { 0x232A, BIDI_ON }, // RIGHT-POINTING ANGLE BRACKET + { 0x232B, BIDI_ON }, // ERASE TO THE LEFT + { 0x232C, BIDI_ON }, // BENZENE RING + { 0x232D, BIDI_ON }, // CYLINDRICITY + { 0x232E, BIDI_ON }, // ALL AROUND-PROFILE + { 0x232F, BIDI_ON }, // SYMMETRY + { 0x2330, BIDI_ON }, // TOTAL RUNOUT + { 0x2331, BIDI_ON }, // DIMENSION ORIGIN + { 0x2332, BIDI_ON }, // CONICAL TAPER + { 0x2333, BIDI_ON }, // SLOPE + { 0x2334, BIDI_ON }, // COUNTERBORE + { 0x2335, BIDI_ON }, // COUNTERSINK + { 0x2336, BIDI_L }, // APL FUNCTIONAL SYMBOL I-BEAM + { 0x2337, BIDI_L }, // APL FUNCTIONAL SYMBOL SQUISH QUAD + { 0x2338, BIDI_L }, // APL FUNCTIONAL SYMBOL QUAD EQUAL + { 0x2339, BIDI_L }, // APL FUNCTIONAL SYMBOL QUAD DIVIDE + { 0x233A, BIDI_L }, // APL FUNCTIONAL SYMBOL QUAD DIAMOND + { 0x233B, BIDI_L }, // APL FUNCTIONAL SYMBOL QUAD JOT + { 0x233C, BIDI_L }, // APL FUNCTIONAL SYMBOL QUAD CIRCLE + { 0x233D, BIDI_L }, // APL FUNCTIONAL SYMBOL CIRCLE STILE + { 0x233E, BIDI_L }, // APL FUNCTIONAL SYMBOL CIRCLE JOT + { 0x233F, BIDI_L }, // APL FUNCTIONAL SYMBOL SLASH BAR + { 0x2340, BIDI_L }, // APL FUNCTIONAL SYMBOL BACKSLASH BAR + { 0x2341, BIDI_L }, // APL FUNCTIONAL SYMBOL QUAD SLASH + { 0x2342, BIDI_L }, // APL FUNCTIONAL SYMBOL QUAD BACKSLASH + { 0x2343, BIDI_L }, // APL FUNCTIONAL SYMBOL QUAD LESS-THAN + { 0x2344, BIDI_L }, // APL FUNCTIONAL SYMBOL QUAD GREATER-THAN + { 0x2345, BIDI_L }, // APL FUNCTIONAL SYMBOL LEFTWARDS VANE + { 0x2346, BIDI_L }, // APL FUNCTIONAL SYMBOL RIGHTWARDS VANE + { 0x2347, BIDI_L }, // APL FUNCTIONAL SYMBOL QUAD LEFTWARDS ARROW + { 0x2348, BIDI_L }, // APL FUNCTIONAL SYMBOL QUAD RIGHTWARDS ARROW + { 0x2349, BIDI_L }, // APL FUNCTIONAL SYMBOL CIRCLE BACKSLASH + { 0x234A, BIDI_L }, // APL FUNCTIONAL SYMBOL DOWN TACK UNDERBAR + { 0x234B, BIDI_L }, // APL FUNCTIONAL SYMBOL DELTA STILE + { 0x234C, BIDI_L }, // APL FUNCTIONAL SYMBOL QUAD DOWN CARET + { 0x234D, BIDI_L }, // APL FUNCTIONAL SYMBOL QUAD DELTA + { 0x234E, BIDI_L }, // APL FUNCTIONAL SYMBOL DOWN TACK JOT + { 0x234F, BIDI_L }, // APL FUNCTIONAL SYMBOL UPWARDS VANE + { 0x2350, BIDI_L }, // APL FUNCTIONAL SYMBOL QUAD UPWARDS ARROW + { 0x2351, BIDI_L }, // APL FUNCTIONAL SYMBOL UP TACK OVERBAR + { 0x2352, BIDI_L }, // APL FUNCTIONAL SYMBOL DEL STILE + { 0x2353, BIDI_L }, // APL FUNCTIONAL SYMBOL QUAD UP CARET + { 0x2354, BIDI_L }, // APL FUNCTIONAL SYMBOL QUAD DEL + { 0x2355, BIDI_L }, // APL FUNCTIONAL SYMBOL UP TACK JOT + { 0x2356, BIDI_L }, // APL FUNCTIONAL SYMBOL DOWNWARDS VANE + { 0x2357, BIDI_L }, // APL FUNCTIONAL SYMBOL QUAD DOWNWARDS ARROW + { 0x2358, BIDI_L }, // APL FUNCTIONAL SYMBOL QUOTE UNDERBAR + { 0x2359, BIDI_L }, // APL FUNCTIONAL SYMBOL DELTA UNDERBAR + { 0x235A, BIDI_L }, // APL FUNCTIONAL SYMBOL DIAMOND UNDERBAR + { 0x235B, BIDI_L }, // APL FUNCTIONAL SYMBOL JOT UNDERBAR + { 0x235C, BIDI_L }, // APL FUNCTIONAL SYMBOL CIRCLE UNDERBAR + { 0x235D, BIDI_L }, // APL FUNCTIONAL SYMBOL UP SHOE JOT + { 0x235E, BIDI_L }, // APL FUNCTIONAL SYMBOL QUOTE QUAD + { 0x235F, BIDI_L }, // APL FUNCTIONAL SYMBOL CIRCLE STAR + { 0x2360, BIDI_L }, // APL FUNCTIONAL SYMBOL QUAD COLON + { 0x2361, BIDI_L }, // APL FUNCTIONAL SYMBOL UP TACK DIAERESIS + { 0x2362, BIDI_L }, // APL FUNCTIONAL SYMBOL DEL DIAERESIS + { 0x2363, BIDI_L }, // APL FUNCTIONAL SYMBOL STAR DIAERESIS + { 0x2364, BIDI_L }, // APL FUNCTIONAL SYMBOL JOT DIAERESIS + { 0x2365, BIDI_L }, // APL FUNCTIONAL SYMBOL CIRCLE DIAERESIS + { 0x2366, BIDI_L }, // APL FUNCTIONAL SYMBOL DOWN SHOE STILE + { 0x2367, BIDI_L }, // APL FUNCTIONAL SYMBOL LEFT SHOE STILE + { 0x2368, BIDI_L }, // APL FUNCTIONAL SYMBOL TILDE DIAERESIS + { 0x2369, BIDI_L }, // APL FUNCTIONAL SYMBOL GREATER-THAN DIAERESIS + { 0x236A, BIDI_L }, // APL FUNCTIONAL SYMBOL COMMA BAR + { 0x236B, BIDI_L }, // APL FUNCTIONAL SYMBOL DEL TILDE + { 0x236C, BIDI_L }, // APL FUNCTIONAL SYMBOL ZILDE + { 0x236D, BIDI_L }, // APL FUNCTIONAL SYMBOL STILE TILDE + { 0x236E, BIDI_L }, // APL FUNCTIONAL SYMBOL SEMICOLON UNDERBAR + { 0x236F, BIDI_L }, // APL FUNCTIONAL SYMBOL QUAD NOT EQUAL + { 0x2370, BIDI_L }, // APL FUNCTIONAL SYMBOL QUAD QUESTION + { 0x2371, BIDI_L }, // APL FUNCTIONAL SYMBOL DOWN CARET TILDE + { 0x2372, BIDI_L }, // APL FUNCTIONAL SYMBOL UP CARET TILDE + { 0x2373, BIDI_L }, // APL FUNCTIONAL SYMBOL IOTA + { 0x2374, BIDI_L }, // APL FUNCTIONAL SYMBOL RHO + { 0x2375, BIDI_L }, // APL FUNCTIONAL SYMBOL OMEGA + { 0x2376, BIDI_L }, // APL FUNCTIONAL SYMBOL ALPHA UNDERBAR + { 0x2377, BIDI_L }, // APL FUNCTIONAL SYMBOL EPSILON UNDERBAR + { 0x2378, BIDI_L }, // APL FUNCTIONAL SYMBOL IOTA UNDERBAR + { 0x2379, BIDI_L }, // APL FUNCTIONAL SYMBOL OMEGA UNDERBAR + { 0x237A, BIDI_L }, // APL FUNCTIONAL SYMBOL ALPHA + { 0x237B, BIDI_ON }, // NOT CHECK MARK + { 0x237C, BIDI_ON }, // RIGHT ANGLE WITH DOWNWARDS ZIGZAG ARROW + { 0x237D, BIDI_ON }, // SHOULDERED OPEN BOX + { 0x237E, BIDI_ON }, // BELL SYMBOL + { 0x237F, BIDI_ON }, // VERTICAL LINE WITH MIDDLE DOT + { 0x2380, BIDI_ON }, // INSERTION SYMBOL + { 0x2381, BIDI_ON }, // CONTINUOUS UNDERLINE SYMBOL + { 0x2382, BIDI_ON }, // DISCONTINUOUS UNDERLINE SYMBOL + { 0x2383, BIDI_ON }, // EMPHASIS SYMBOL + { 0x2384, BIDI_ON }, // COMPOSITION SYMBOL + { 0x2385, BIDI_ON }, // WHITE SQUARE WITH CENTRE VERTICAL LINE + { 0x2386, BIDI_ON }, // ENTER SYMBOL + { 0x2387, BIDI_ON }, // ALTERNATIVE KEY SYMBOL + { 0x2388, BIDI_ON }, // HELM SYMBOL + { 0x2389, BIDI_ON }, // CIRCLED HORIZONTAL BAR WITH NOTCH + { 0x238A, BIDI_ON }, // CIRCLED TRIANGLE DOWN + { 0x238B, BIDI_ON }, // BROKEN CIRCLE WITH NORTHWEST ARROW + { 0x238C, BIDI_ON }, // UNDO SYMBOL + { 0x238D, BIDI_ON }, // MONOSTABLE SYMBOL + { 0x238E, BIDI_ON }, // HYSTERESIS SYMBOL + { 0x238F, BIDI_ON }, // OPEN-CIRCUIT-OUTPUT H-TYPE SYMBOL + { 0x2390, BIDI_ON }, // OPEN-CIRCUIT-OUTPUT L-TYPE SYMBOL + { 0x2391, BIDI_ON }, // PASSIVE-PULL-DOWN-OUTPUT SYMBOL + { 0x2392, BIDI_ON }, // PASSIVE-PULL-UP-OUTPUT SYMBOL + { 0x2393, BIDI_ON }, // DIRECT CURRENT SYMBOL FORM TWO + { 0x2394, BIDI_ON }, // SOFTWARE-FUNCTION SYMBOL + { 0x2395, BIDI_L }, // APL FUNCTIONAL SYMBOL QUAD + { 0x2396, BIDI_ON }, // DECIMAL SEPARATOR KEY SYMBOL + { 0x2397, BIDI_ON }, // PREVIOUS PAGE + { 0x2398, BIDI_ON }, // NEXT PAGE + { 0x2399, BIDI_ON }, // PRINT SCREEN SYMBOL + { 0x239A, BIDI_ON }, // CLEAR SCREEN SYMBOL + { 0x239B, BIDI_ON }, // LEFT PARENTHESIS UPPER HOOK + { 0x239C, BIDI_ON }, // LEFT PARENTHESIS EXTENSION + { 0x239D, BIDI_ON }, // LEFT PARENTHESIS LOWER HOOK + { 0x239E, BIDI_ON }, // RIGHT PARENTHESIS UPPER HOOK + { 0x239F, BIDI_ON }, // RIGHT PARENTHESIS EXTENSION + { 0x23A0, BIDI_ON }, // RIGHT PARENTHESIS LOWER HOOK + { 0x23A1, BIDI_ON }, // LEFT SQUARE BRACKET UPPER CORNER + { 0x23A2, BIDI_ON }, // LEFT SQUARE BRACKET EXTENSION + { 0x23A3, BIDI_ON }, // LEFT SQUARE BRACKET LOWER CORNER + { 0x23A4, BIDI_ON }, // RIGHT SQUARE BRACKET UPPER CORNER + { 0x23A5, BIDI_ON }, // RIGHT SQUARE BRACKET EXTENSION + { 0x23A6, BIDI_ON }, // RIGHT SQUARE BRACKET LOWER CORNER + { 0x23A7, BIDI_ON }, // LEFT CURLY BRACKET UPPER HOOK + { 0x23A8, BIDI_ON }, // LEFT CURLY BRACKET MIDDLE PIECE + { 0x23A9, BIDI_ON }, // LEFT CURLY BRACKET LOWER HOOK + { 0x23AA, BIDI_ON }, // CURLY BRACKET EXTENSION + { 0x23AB, BIDI_ON }, // RIGHT CURLY BRACKET UPPER HOOK + { 0x23AC, BIDI_ON }, // RIGHT CURLY BRACKET MIDDLE PIECE + { 0x23AD, BIDI_ON }, // RIGHT CURLY BRACKET LOWER HOOK + { 0x23AE, BIDI_ON }, // INTEGRAL EXTENSION + { 0x23AF, BIDI_ON }, // HORIZONTAL LINE EXTENSION + { 0x23B0, BIDI_ON }, // UPPER LEFT OR LOWER RIGHT CURLY BRACKET SECTION + { 0x23B1, BIDI_ON }, // UPPER RIGHT OR LOWER LEFT CURLY BRACKET SECTION + { 0x23B2, BIDI_ON }, // SUMMATION TOP + { 0x23B3, BIDI_ON }, // SUMMATION BOTTOM + { 0x23B4, BIDI_ON }, // TOP SQUARE BRACKET + { 0x23B5, BIDI_ON }, // BOTTOM SQUARE BRACKET + { 0x23B6, BIDI_ON }, // BOTTOM SQUARE BRACKET OVER TOP SQUARE BRACKET + { 0x23B7, BIDI_ON }, // RADICAL SYMBOL BOTTOM + { 0x23B8, BIDI_ON }, // LEFT VERTICAL BOX LINE + { 0x23B9, BIDI_ON }, // RIGHT VERTICAL BOX LINE + { 0x23BA, BIDI_ON }, // HORIZONTAL SCAN LINE-1 + { 0x23BB, BIDI_ON }, // HORIZONTAL SCAN LINE-3 + { 0x23BC, BIDI_ON }, // HORIZONTAL SCAN LINE-7 + { 0x23BD, BIDI_ON }, // HORIZONTAL SCAN LINE-9 + { 0x23BE, BIDI_ON }, // DENTISTRY SYMBOL LIGHT VERTICAL AND TOP RIGHT + { 0x23BF, BIDI_ON }, // DENTISTRY SYMBOL LIGHT VERTICAL AND BOTTOM RIGHT + { 0x23C0, BIDI_ON }, // DENTISTRY SYMBOL LIGHT VERTICAL WITH CIRCLE + { 0x23C1, BIDI_ON }, // DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL WITH CIRCLE + { 0x23C2, BIDI_ON }, // DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL WITH CIRCLE + { 0x23C3, BIDI_ON }, // DENTISTRY SYMBOL LIGHT VERTICAL WITH TRIANGLE + { 0x23C4, BIDI_ON }, // DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL WITH TRIANGLE + { 0x23C5, BIDI_ON }, // DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL WITH TRIANGLE + { 0x23C6, BIDI_ON }, // DENTISTRY SYMBOL LIGHT VERTICAL AND WAVE + { 0x23C7, BIDI_ON }, // DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL WITH WAVE + { 0x23C8, BIDI_ON }, // DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL WITH WAVE + { 0x23C9, BIDI_ON }, // DENTISTRY SYMBOL LIGHT DOWN AND HORIZONTAL + { 0x23CA, BIDI_ON }, // DENTISTRY SYMBOL LIGHT UP AND HORIZONTAL + { 0x23CB, BIDI_ON }, // DENTISTRY SYMBOL LIGHT VERTICAL AND TOP LEFT + { 0x23CC, BIDI_ON }, // DENTISTRY SYMBOL LIGHT VERTICAL AND BOTTOM LEFT + { 0x23CD, BIDI_ON }, // SQUARE FOOT + { 0x23CE, BIDI_ON }, // RETURN SYMBOL + { 0x23CF, BIDI_ON }, // EJECT SYMBOL + { 0x23D0, BIDI_ON }, // VERTICAL LINE EXTENSION + { 0x23D1, BIDI_ON }, // METRICAL BREVE + { 0x23D2, BIDI_ON }, // METRICAL LONG OVER SHORT + { 0x23D3, BIDI_ON }, // METRICAL SHORT OVER LONG + { 0x23D4, BIDI_ON }, // METRICAL LONG OVER TWO SHORTS + { 0x23D5, BIDI_ON }, // METRICAL TWO SHORTS OVER LONG + { 0x23D6, BIDI_ON }, // METRICAL TWO SHORTS JOINED + { 0x23D7, BIDI_ON }, // METRICAL TRISEME + { 0x23D8, BIDI_ON }, // METRICAL TETRASEME + { 0x23D9, BIDI_ON }, // METRICAL PENTASEME + { 0x23DA, BIDI_ON }, // EARTH GROUND + { 0x23DB, BIDI_ON }, // FUSE + { 0x23DC, BIDI_ON }, // TOP PARENTHESIS + { 0x23DD, BIDI_ON }, // BOTTOM PARENTHESIS + { 0x23DE, BIDI_ON }, // TOP CURLY BRACKET + { 0x23DF, BIDI_ON }, // BOTTOM CURLY BRACKET + { 0x23E0, BIDI_ON }, // TOP TORTOISE SHELL BRACKET + { 0x23E1, BIDI_ON }, // BOTTOM TORTOISE SHELL BRACKET + { 0x23E2, BIDI_ON }, // WHITE TRAPEZIUM + { 0x23E3, BIDI_ON }, // BENZENE RING WITH CIRCLE + { 0x23E4, BIDI_ON }, // STRAIGHTNESS + { 0x23E5, BIDI_ON }, // FLATNESS + { 0x23E6, BIDI_ON }, // AC CURRENT + { 0x23E7, BIDI_ON }, // ELECTRICAL INTERSECTION + { 0x23E8, BIDI_ON }, // DECIMAL EXPONENT SYMBOL + { 0x23E9, BIDI_ON }, // BLACK RIGHT-POINTING DOUBLE TRIANGLE + { 0x23EA, BIDI_ON }, // BLACK LEFT-POINTING DOUBLE TRIANGLE + { 0x23EB, BIDI_ON }, // BLACK UP-POINTING DOUBLE TRIANGLE + { 0x23EC, BIDI_ON }, // BLACK DOWN-POINTING DOUBLE TRIANGLE + { 0x23ED, BIDI_ON }, // BLACK RIGHT-POINTING DOUBLE TRIANGLE WITH VERTICAL BAR + { 0x23EE, BIDI_ON }, // BLACK LEFT-POINTING DOUBLE TRIANGLE WITH VERTICAL BAR + { 0x23EF, BIDI_ON }, // BLACK RIGHT-POINTING TRIANGLE WITH DOUBLE VERTICAL BAR + { 0x23F0, BIDI_ON }, // ALARM CLOCK + { 0x23F1, BIDI_ON }, // STOPWATCH + { 0x23F2, BIDI_ON }, // TIMER CLOCK + { 0x23F3, BIDI_ON }, // HOURGLASS WITH FLOWING SAND + { 0x23F4, BIDI_ON }, // BLACK MEDIUM LEFT-POINTING TRIANGLE + { 0x23F5, BIDI_ON }, // BLACK MEDIUM RIGHT-POINTING TRIANGLE + { 0x23F6, BIDI_ON }, // BLACK MEDIUM UP-POINTING TRIANGLE + { 0x23F7, BIDI_ON }, // BLACK MEDIUM DOWN-POINTING TRIANGLE + { 0x23F8, BIDI_ON }, // DOUBLE VERTICAL BAR + { 0x23F9, BIDI_ON }, // BLACK SQUARE FOR STOP + { 0x23FA, BIDI_ON }, // BLACK CIRCLE FOR RECORD + { 0x2400, BIDI_ON }, // SYMBOL FOR NULL + { 0x2401, BIDI_ON }, // SYMBOL FOR START OF HEADING + { 0x2402, BIDI_ON }, // SYMBOL FOR START OF TEXT + { 0x2403, BIDI_ON }, // SYMBOL FOR END OF TEXT + { 0x2404, BIDI_ON }, // SYMBOL FOR END OF TRANSMISSION + { 0x2405, BIDI_ON }, // SYMBOL FOR ENQUIRY + { 0x2406, BIDI_ON }, // SYMBOL FOR ACKNOWLEDGE + { 0x2407, BIDI_ON }, // SYMBOL FOR BELL + { 0x2408, BIDI_ON }, // SYMBOL FOR BACKSPACE + { 0x2409, BIDI_ON }, // SYMBOL FOR HORIZONTAL TABULATION + { 0x240A, BIDI_ON }, // SYMBOL FOR LINE FEED + { 0x240B, BIDI_ON }, // SYMBOL FOR VERTICAL TABULATION + { 0x240C, BIDI_ON }, // SYMBOL FOR FORM FEED + { 0x240D, BIDI_ON }, // SYMBOL FOR CARRIAGE RETURN + { 0x240E, BIDI_ON }, // SYMBOL FOR SHIFT OUT + { 0x240F, BIDI_ON }, // SYMBOL FOR SHIFT IN + { 0x2410, BIDI_ON }, // SYMBOL FOR DATA LINK ESCAPE + { 0x2411, BIDI_ON }, // SYMBOL FOR DEVICE CONTROL ONE + { 0x2412, BIDI_ON }, // SYMBOL FOR DEVICE CONTROL TWO + { 0x2413, BIDI_ON }, // SYMBOL FOR DEVICE CONTROL THREE + { 0x2414, BIDI_ON }, // SYMBOL FOR DEVICE CONTROL FOUR + { 0x2415, BIDI_ON }, // SYMBOL FOR NEGATIVE ACKNOWLEDGE + { 0x2416, BIDI_ON }, // SYMBOL FOR SYNCHRONOUS IDLE + { 0x2417, BIDI_ON }, // SYMBOL FOR END OF TRANSMISSION BLOCK + { 0x2418, BIDI_ON }, // SYMBOL FOR CANCEL + { 0x2419, BIDI_ON }, // SYMBOL FOR END OF MEDIUM + { 0x241A, BIDI_ON }, // SYMBOL FOR SUBSTITUTE + { 0x241B, BIDI_ON }, // SYMBOL FOR ESCAPE + { 0x241C, BIDI_ON }, // SYMBOL FOR FILE SEPARATOR + { 0x241D, BIDI_ON }, // SYMBOL FOR GROUP SEPARATOR + { 0x241E, BIDI_ON }, // SYMBOL FOR RECORD SEPARATOR + { 0x241F, BIDI_ON }, // SYMBOL FOR UNIT SEPARATOR + { 0x2420, BIDI_ON }, // SYMBOL FOR SPACE + { 0x2421, BIDI_ON }, // SYMBOL FOR DELETE + { 0x2422, BIDI_ON }, // BLANK SYMBOL + { 0x2423, BIDI_ON }, // OPEN BOX + { 0x2424, BIDI_ON }, // SYMBOL FOR NEWLINE + { 0x2425, BIDI_ON }, // SYMBOL FOR DELETE FORM TWO + { 0x2426, BIDI_ON }, // SYMBOL FOR SUBSTITUTE FORM TWO + { 0x2440, BIDI_ON }, // OCR HOOK + { 0x2441, BIDI_ON }, // OCR CHAIR + { 0x2442, BIDI_ON }, // OCR FORK + { 0x2443, BIDI_ON }, // OCR INVERTED FORK + { 0x2444, BIDI_ON }, // OCR BELT BUCKLE + { 0x2445, BIDI_ON }, // OCR BOW TIE + { 0x2446, BIDI_ON }, // OCR BRANCH BANK IDENTIFICATION + { 0x2447, BIDI_ON }, // OCR AMOUNT OF CHECK + { 0x2448, BIDI_ON }, // OCR DASH + { 0x2449, BIDI_ON }, // OCR CUSTOMER ACCOUNT NUMBER + { 0x244A, BIDI_ON }, // OCR DOUBLE BACKSLASH + { 0x2460, BIDI_ON }, // CIRCLED DIGIT ONE + { 0x2461, BIDI_ON }, // CIRCLED DIGIT TWO + { 0x2462, BIDI_ON }, // CIRCLED DIGIT THREE + { 0x2463, BIDI_ON }, // CIRCLED DIGIT FOUR + { 0x2464, BIDI_ON }, // CIRCLED DIGIT FIVE + { 0x2465, BIDI_ON }, // CIRCLED DIGIT SIX + { 0x2466, BIDI_ON }, // CIRCLED DIGIT SEVEN + { 0x2467, BIDI_ON }, // CIRCLED DIGIT EIGHT + { 0x2468, BIDI_ON }, // CIRCLED DIGIT NINE + { 0x2469, BIDI_ON }, // CIRCLED NUMBER TEN + { 0x246A, BIDI_ON }, // CIRCLED NUMBER ELEVEN + { 0x246B, BIDI_ON }, // CIRCLED NUMBER TWELVE + { 0x246C, BIDI_ON }, // CIRCLED NUMBER THIRTEEN + { 0x246D, BIDI_ON }, // CIRCLED NUMBER FOURTEEN + { 0x246E, BIDI_ON }, // CIRCLED NUMBER FIFTEEN + { 0x246F, BIDI_ON }, // CIRCLED NUMBER SIXTEEN + { 0x2470, BIDI_ON }, // CIRCLED NUMBER SEVENTEEN + { 0x2471, BIDI_ON }, // CIRCLED NUMBER EIGHTEEN + { 0x2472, BIDI_ON }, // CIRCLED NUMBER NINETEEN + { 0x2473, BIDI_ON }, // CIRCLED NUMBER TWENTY + { 0x2474, BIDI_ON }, // PARENTHESIZED DIGIT ONE + { 0x2475, BIDI_ON }, // PARENTHESIZED DIGIT TWO + { 0x2476, BIDI_ON }, // PARENTHESIZED DIGIT THREE + { 0x2477, BIDI_ON }, // PARENTHESIZED DIGIT FOUR + { 0x2478, BIDI_ON }, // PARENTHESIZED DIGIT FIVE + { 0x2479, BIDI_ON }, // PARENTHESIZED DIGIT SIX + { 0x247A, BIDI_ON }, // PARENTHESIZED DIGIT SEVEN + { 0x247B, BIDI_ON }, // PARENTHESIZED DIGIT EIGHT + { 0x247C, BIDI_ON }, // PARENTHESIZED DIGIT NINE + { 0x247D, BIDI_ON }, // PARENTHESIZED NUMBER TEN + { 0x247E, BIDI_ON }, // PARENTHESIZED NUMBER ELEVEN + { 0x247F, BIDI_ON }, // PARENTHESIZED NUMBER TWELVE + { 0x2480, BIDI_ON }, // PARENTHESIZED NUMBER THIRTEEN + { 0x2481, BIDI_ON }, // PARENTHESIZED NUMBER FOURTEEN + { 0x2482, BIDI_ON }, // PARENTHESIZED NUMBER FIFTEEN + { 0x2483, BIDI_ON }, // PARENTHESIZED NUMBER SIXTEEN + { 0x2484, BIDI_ON }, // PARENTHESIZED NUMBER SEVENTEEN + { 0x2485, BIDI_ON }, // PARENTHESIZED NUMBER EIGHTEEN + { 0x2486, BIDI_ON }, // PARENTHESIZED NUMBER NINETEEN + { 0x2487, BIDI_ON }, // PARENTHESIZED NUMBER TWENTY + { 0x2488, BIDI_EN }, // DIGIT ONE FULL STOP + { 0x2489, BIDI_EN }, // DIGIT TWO FULL STOP + { 0x248A, BIDI_EN }, // DIGIT THREE FULL STOP + { 0x248B, BIDI_EN }, // DIGIT FOUR FULL STOP + { 0x248C, BIDI_EN }, // DIGIT FIVE FULL STOP + { 0x248D, BIDI_EN }, // DIGIT SIX FULL STOP + { 0x248E, BIDI_EN }, // DIGIT SEVEN FULL STOP + { 0x248F, BIDI_EN }, // DIGIT EIGHT FULL STOP + { 0x2490, BIDI_EN }, // DIGIT NINE FULL STOP + { 0x2491, BIDI_EN }, // NUMBER TEN FULL STOP + { 0x2492, BIDI_EN }, // NUMBER ELEVEN FULL STOP + { 0x2493, BIDI_EN }, // NUMBER TWELVE FULL STOP + { 0x2494, BIDI_EN }, // NUMBER THIRTEEN FULL STOP + { 0x2495, BIDI_EN }, // NUMBER FOURTEEN FULL STOP + { 0x2496, BIDI_EN }, // NUMBER FIFTEEN FULL STOP + { 0x2497, BIDI_EN }, // NUMBER SIXTEEN FULL STOP + { 0x2498, BIDI_EN }, // NUMBER SEVENTEEN FULL STOP + { 0x2499, BIDI_EN }, // NUMBER EIGHTEEN FULL STOP + { 0x249A, BIDI_EN }, // NUMBER NINETEEN FULL STOP + { 0x249B, BIDI_EN }, // NUMBER TWENTY FULL STOP + { 0x249C, BIDI_L }, // PARENTHESIZED LATIN SMALL LETTER A + { 0x249D, BIDI_L }, // PARENTHESIZED LATIN SMALL LETTER B + { 0x249E, BIDI_L }, // PARENTHESIZED LATIN SMALL LETTER C + { 0x249F, BIDI_L }, // PARENTHESIZED LATIN SMALL LETTER D + { 0x24A0, BIDI_L }, // PARENTHESIZED LATIN SMALL LETTER E + { 0x24A1, BIDI_L }, // PARENTHESIZED LATIN SMALL LETTER F + { 0x24A2, BIDI_L }, // PARENTHESIZED LATIN SMALL LETTER G + { 0x24A3, BIDI_L }, // PARENTHESIZED LATIN SMALL LETTER H + { 0x24A4, BIDI_L }, // PARENTHESIZED LATIN SMALL LETTER I + { 0x24A5, BIDI_L }, // PARENTHESIZED LATIN SMALL LETTER J + { 0x24A6, BIDI_L }, // PARENTHESIZED LATIN SMALL LETTER K + { 0x24A7, BIDI_L }, // PARENTHESIZED LATIN SMALL LETTER L + { 0x24A8, BIDI_L }, // PARENTHESIZED LATIN SMALL LETTER M + { 0x24A9, BIDI_L }, // PARENTHESIZED LATIN SMALL LETTER N + { 0x24AA, BIDI_L }, // PARENTHESIZED LATIN SMALL LETTER O + { 0x24AB, BIDI_L }, // PARENTHESIZED LATIN SMALL LETTER P + { 0x24AC, BIDI_L }, // PARENTHESIZED LATIN SMALL LETTER Q + { 0x24AD, BIDI_L }, // PARENTHESIZED LATIN SMALL LETTER R + { 0x24AE, BIDI_L }, // PARENTHESIZED LATIN SMALL LETTER S + { 0x24AF, BIDI_L }, // PARENTHESIZED LATIN SMALL LETTER T + { 0x24B0, BIDI_L }, // PARENTHESIZED LATIN SMALL LETTER U + { 0x24B1, BIDI_L }, // PARENTHESIZED LATIN SMALL LETTER V + { 0x24B2, BIDI_L }, // PARENTHESIZED LATIN SMALL LETTER W + { 0x24B3, BIDI_L }, // PARENTHESIZED LATIN SMALL LETTER X + { 0x24B4, BIDI_L }, // PARENTHESIZED LATIN SMALL LETTER Y + { 0x24B5, BIDI_L }, // PARENTHESIZED LATIN SMALL LETTER Z + { 0x24B6, BIDI_L }, // CIRCLED LATIN CAPITAL LETTER A + { 0x24B7, BIDI_L }, // CIRCLED LATIN CAPITAL LETTER B + { 0x24B8, BIDI_L }, // CIRCLED LATIN CAPITAL LETTER C + { 0x24B9, BIDI_L }, // CIRCLED LATIN CAPITAL LETTER D + { 0x24BA, BIDI_L }, // CIRCLED LATIN CAPITAL LETTER E + { 0x24BB, BIDI_L }, // CIRCLED LATIN CAPITAL LETTER F + { 0x24BC, BIDI_L }, // CIRCLED LATIN CAPITAL LETTER G + { 0x24BD, BIDI_L }, // CIRCLED LATIN CAPITAL LETTER H + { 0x24BE, BIDI_L }, // CIRCLED LATIN CAPITAL LETTER I + { 0x24BF, BIDI_L }, // CIRCLED LATIN CAPITAL LETTER J + { 0x24C0, BIDI_L }, // CIRCLED LATIN CAPITAL LETTER K + { 0x24C1, BIDI_L }, // CIRCLED LATIN CAPITAL LETTER L + { 0x24C2, BIDI_L }, // CIRCLED LATIN CAPITAL LETTER M + { 0x24C3, BIDI_L }, // CIRCLED LATIN CAPITAL LETTER N + { 0x24C4, BIDI_L }, // CIRCLED LATIN CAPITAL LETTER O + { 0x24C5, BIDI_L }, // CIRCLED LATIN CAPITAL LETTER P + { 0x24C6, BIDI_L }, // CIRCLED LATIN CAPITAL LETTER Q + { 0x24C7, BIDI_L }, // CIRCLED LATIN CAPITAL LETTER R + { 0x24C8, BIDI_L }, // CIRCLED LATIN CAPITAL LETTER S + { 0x24C9, BIDI_L }, // CIRCLED LATIN CAPITAL LETTER T + { 0x24CA, BIDI_L }, // CIRCLED LATIN CAPITAL LETTER U + { 0x24CB, BIDI_L }, // CIRCLED LATIN CAPITAL LETTER V + { 0x24CC, BIDI_L }, // CIRCLED LATIN CAPITAL LETTER W + { 0x24CD, BIDI_L }, // CIRCLED LATIN CAPITAL LETTER X + { 0x24CE, BIDI_L }, // CIRCLED LATIN CAPITAL LETTER Y + { 0x24CF, BIDI_L }, // CIRCLED LATIN CAPITAL LETTER Z + { 0x24D0, BIDI_L }, // CIRCLED LATIN SMALL LETTER A + { 0x24D1, BIDI_L }, // CIRCLED LATIN SMALL LETTER B + { 0x24D2, BIDI_L }, // CIRCLED LATIN SMALL LETTER C + { 0x24D3, BIDI_L }, // CIRCLED LATIN SMALL LETTER D + { 0x24D4, BIDI_L }, // CIRCLED LATIN SMALL LETTER E + { 0x24D5, BIDI_L }, // CIRCLED LATIN SMALL LETTER F + { 0x24D6, BIDI_L }, // CIRCLED LATIN SMALL LETTER G + { 0x24D7, BIDI_L }, // CIRCLED LATIN SMALL LETTER H + { 0x24D8, BIDI_L }, // CIRCLED LATIN SMALL LETTER I + { 0x24D9, BIDI_L }, // CIRCLED LATIN SMALL LETTER J + { 0x24DA, BIDI_L }, // CIRCLED LATIN SMALL LETTER K + { 0x24DB, BIDI_L }, // CIRCLED LATIN SMALL LETTER L + { 0x24DC, BIDI_L }, // CIRCLED LATIN SMALL LETTER M + { 0x24DD, BIDI_L }, // CIRCLED LATIN SMALL LETTER N + { 0x24DE, BIDI_L }, // CIRCLED LATIN SMALL LETTER O + { 0x24DF, BIDI_L }, // CIRCLED LATIN SMALL LETTER P + { 0x24E0, BIDI_L }, // CIRCLED LATIN SMALL LETTER Q + { 0x24E1, BIDI_L }, // CIRCLED LATIN SMALL LETTER R + { 0x24E2, BIDI_L }, // CIRCLED LATIN SMALL LETTER S + { 0x24E3, BIDI_L }, // CIRCLED LATIN SMALL LETTER T + { 0x24E4, BIDI_L }, // CIRCLED LATIN SMALL LETTER U + { 0x24E5, BIDI_L }, // CIRCLED LATIN SMALL LETTER V + { 0x24E6, BIDI_L }, // CIRCLED LATIN SMALL LETTER W + { 0x24E7, BIDI_L }, // CIRCLED LATIN SMALL LETTER X + { 0x24E8, BIDI_L }, // CIRCLED LATIN SMALL LETTER Y + { 0x24E9, BIDI_L }, // CIRCLED LATIN SMALL LETTER Z + { 0x24EA, BIDI_ON }, // CIRCLED DIGIT ZERO + { 0x24EB, BIDI_ON }, // NEGATIVE CIRCLED NUMBER ELEVEN + { 0x24EC, BIDI_ON }, // NEGATIVE CIRCLED NUMBER TWELVE + { 0x24ED, BIDI_ON }, // NEGATIVE CIRCLED NUMBER THIRTEEN + { 0x24EE, BIDI_ON }, // NEGATIVE CIRCLED NUMBER FOURTEEN + { 0x24EF, BIDI_ON }, // NEGATIVE CIRCLED NUMBER FIFTEEN + { 0x24F0, BIDI_ON }, // NEGATIVE CIRCLED NUMBER SIXTEEN + { 0x24F1, BIDI_ON }, // NEGATIVE CIRCLED NUMBER SEVENTEEN + { 0x24F2, BIDI_ON }, // NEGATIVE CIRCLED NUMBER EIGHTEEN + { 0x24F3, BIDI_ON }, // NEGATIVE CIRCLED NUMBER NINETEEN + { 0x24F4, BIDI_ON }, // NEGATIVE CIRCLED NUMBER TWENTY + { 0x24F5, BIDI_ON }, // DOUBLE CIRCLED DIGIT ONE + { 0x24F6, BIDI_ON }, // DOUBLE CIRCLED DIGIT TWO + { 0x24F7, BIDI_ON }, // DOUBLE CIRCLED DIGIT THREE + { 0x24F8, BIDI_ON }, // DOUBLE CIRCLED DIGIT FOUR + { 0x24F9, BIDI_ON }, // DOUBLE CIRCLED DIGIT FIVE + { 0x24FA, BIDI_ON }, // DOUBLE CIRCLED DIGIT SIX + { 0x24FB, BIDI_ON }, // DOUBLE CIRCLED DIGIT SEVEN + { 0x24FC, BIDI_ON }, // DOUBLE CIRCLED DIGIT EIGHT + { 0x24FD, BIDI_ON }, // DOUBLE CIRCLED DIGIT NINE + { 0x24FE, BIDI_ON }, // DOUBLE CIRCLED NUMBER TEN + { 0x24FF, BIDI_ON }, // NEGATIVE CIRCLED DIGIT ZERO + { 0x2500, BIDI_ON }, // BOX DRAWINGS LIGHT HORIZONTAL + { 0x2501, BIDI_ON }, // BOX DRAWINGS HEAVY HORIZONTAL + { 0x2502, BIDI_ON }, // BOX DRAWINGS LIGHT VERTICAL + { 0x2503, BIDI_ON }, // BOX DRAWINGS HEAVY VERTICAL + { 0x2504, BIDI_ON }, // BOX DRAWINGS LIGHT TRIPLE DASH HORIZONTAL + { 0x2505, BIDI_ON }, // BOX DRAWINGS HEAVY TRIPLE DASH HORIZONTAL + { 0x2506, BIDI_ON }, // BOX DRAWINGS LIGHT TRIPLE DASH VERTICAL + { 0x2507, BIDI_ON }, // BOX DRAWINGS HEAVY TRIPLE DASH VERTICAL + { 0x2508, BIDI_ON }, // BOX DRAWINGS LIGHT QUADRUPLE DASH HORIZONTAL + { 0x2509, BIDI_ON }, // BOX DRAWINGS HEAVY QUADRUPLE DASH HORIZONTAL + { 0x250A, BIDI_ON }, // BOX DRAWINGS LIGHT QUADRUPLE DASH VERTICAL + { 0x250B, BIDI_ON }, // BOX DRAWINGS HEAVY QUADRUPLE DASH VERTICAL + { 0x250C, BIDI_ON }, // BOX DRAWINGS LIGHT DOWN AND RIGHT + { 0x250D, BIDI_ON }, // BOX DRAWINGS DOWN LIGHT AND RIGHT HEAVY + { 0x250E, BIDI_ON }, // BOX DRAWINGS DOWN HEAVY AND RIGHT LIGHT + { 0x250F, BIDI_ON }, // BOX DRAWINGS HEAVY DOWN AND RIGHT + { 0x2510, BIDI_ON }, // BOX DRAWINGS LIGHT DOWN AND LEFT + { 0x2511, BIDI_ON }, // BOX DRAWINGS DOWN LIGHT AND LEFT HEAVY + { 0x2512, BIDI_ON }, // BOX DRAWINGS DOWN HEAVY AND LEFT LIGHT + { 0x2513, BIDI_ON }, // BOX DRAWINGS HEAVY DOWN AND LEFT + { 0x2514, BIDI_ON }, // BOX DRAWINGS LIGHT UP AND RIGHT + { 0x2515, BIDI_ON }, // BOX DRAWINGS UP LIGHT AND RIGHT HEAVY + { 0x2516, BIDI_ON }, // BOX DRAWINGS UP HEAVY AND RIGHT LIGHT + { 0x2517, BIDI_ON }, // BOX DRAWINGS HEAVY UP AND RIGHT + { 0x2518, BIDI_ON }, // BOX DRAWINGS LIGHT UP AND LEFT + { 0x2519, BIDI_ON }, // BOX DRAWINGS UP LIGHT AND LEFT HEAVY + { 0x251A, BIDI_ON }, // BOX DRAWINGS UP HEAVY AND LEFT LIGHT + { 0x251B, BIDI_ON }, // BOX DRAWINGS HEAVY UP AND LEFT + { 0x251C, BIDI_ON }, // BOX DRAWINGS LIGHT VERTICAL AND RIGHT + { 0x251D, BIDI_ON }, // BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY + { 0x251E, BIDI_ON }, // BOX DRAWINGS UP HEAVY AND RIGHT DOWN LIGHT + { 0x251F, BIDI_ON }, // BOX DRAWINGS DOWN HEAVY AND RIGHT UP LIGHT + { 0x2520, BIDI_ON }, // BOX DRAWINGS VERTICAL HEAVY AND RIGHT LIGHT + { 0x2521, BIDI_ON }, // BOX DRAWINGS DOWN LIGHT AND RIGHT UP HEAVY + { 0x2522, BIDI_ON }, // BOX DRAWINGS UP LIGHT AND RIGHT DOWN HEAVY + { 0x2523, BIDI_ON }, // BOX DRAWINGS HEAVY VERTICAL AND RIGHT + { 0x2524, BIDI_ON }, // BOX DRAWINGS LIGHT VERTICAL AND LEFT + { 0x2525, BIDI_ON }, // BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY + { 0x2526, BIDI_ON }, // BOX DRAWINGS UP HEAVY AND LEFT DOWN LIGHT + { 0x2527, BIDI_ON }, // BOX DRAWINGS DOWN HEAVY AND LEFT UP LIGHT + { 0x2528, BIDI_ON }, // BOX DRAWINGS VERTICAL HEAVY AND LEFT LIGHT + { 0x2529, BIDI_ON }, // BOX DRAWINGS DOWN LIGHT AND LEFT UP HEAVY + { 0x252A, BIDI_ON }, // BOX DRAWINGS UP LIGHT AND LEFT DOWN HEAVY + { 0x252B, BIDI_ON }, // BOX DRAWINGS HEAVY VERTICAL AND LEFT + { 0x252C, BIDI_ON }, // BOX DRAWINGS LIGHT DOWN AND HORIZONTAL + { 0x252D, BIDI_ON }, // BOX DRAWINGS LEFT HEAVY AND RIGHT DOWN LIGHT + { 0x252E, BIDI_ON }, // BOX DRAWINGS RIGHT HEAVY AND LEFT DOWN LIGHT + { 0x252F, BIDI_ON }, // BOX DRAWINGS DOWN LIGHT AND HORIZONTAL HEAVY + { 0x2530, BIDI_ON }, // BOX DRAWINGS DOWN HEAVY AND HORIZONTAL LIGHT + { 0x2531, BIDI_ON }, // BOX DRAWINGS RIGHT LIGHT AND LEFT DOWN HEAVY + { 0x2532, BIDI_ON }, // BOX DRAWINGS LEFT LIGHT AND RIGHT DOWN HEAVY + { 0x2533, BIDI_ON }, // BOX DRAWINGS HEAVY DOWN AND HORIZONTAL + { 0x2534, BIDI_ON }, // BOX DRAWINGS LIGHT UP AND HORIZONTAL + { 0x2535, BIDI_ON }, // BOX DRAWINGS LEFT HEAVY AND RIGHT UP LIGHT + { 0x2536, BIDI_ON }, // BOX DRAWINGS RIGHT HEAVY AND LEFT UP LIGHT + { 0x2537, BIDI_ON }, // BOX DRAWINGS UP LIGHT AND HORIZONTAL HEAVY + { 0x2538, BIDI_ON }, // BOX DRAWINGS UP HEAVY AND HORIZONTAL LIGHT + { 0x2539, BIDI_ON }, // BOX DRAWINGS RIGHT LIGHT AND LEFT UP HEAVY + { 0x253A, BIDI_ON }, // BOX DRAWINGS LEFT LIGHT AND RIGHT UP HEAVY + { 0x253B, BIDI_ON }, // BOX DRAWINGS HEAVY UP AND HORIZONTAL + { 0x253C, BIDI_ON }, // BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL + { 0x253D, BIDI_ON }, // BOX DRAWINGS LEFT HEAVY AND RIGHT VERTICAL LIGHT + { 0x253E, BIDI_ON }, // BOX DRAWINGS RIGHT HEAVY AND LEFT VERTICAL LIGHT + { 0x253F, BIDI_ON }, // BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY + { 0x2540, BIDI_ON }, // BOX DRAWINGS UP HEAVY AND DOWN HORIZONTAL LIGHT + { 0x2541, BIDI_ON }, // BOX DRAWINGS DOWN HEAVY AND UP HORIZONTAL LIGHT + { 0x2542, BIDI_ON }, // BOX DRAWINGS VERTICAL HEAVY AND HORIZONTAL LIGHT + { 0x2543, BIDI_ON }, // BOX DRAWINGS LEFT UP HEAVY AND RIGHT DOWN LIGHT + { 0x2544, BIDI_ON }, // BOX DRAWINGS RIGHT UP HEAVY AND LEFT DOWN LIGHT + { 0x2545, BIDI_ON }, // BOX DRAWINGS LEFT DOWN HEAVY AND RIGHT UP LIGHT + { 0x2546, BIDI_ON }, // BOX DRAWINGS RIGHT DOWN HEAVY AND LEFT UP LIGHT + { 0x2547, BIDI_ON }, // BOX DRAWINGS DOWN LIGHT AND UP HORIZONTAL HEAVY + { 0x2548, BIDI_ON }, // BOX DRAWINGS UP LIGHT AND DOWN HORIZONTAL HEAVY + { 0x2549, BIDI_ON }, // BOX DRAWINGS RIGHT LIGHT AND LEFT VERTICAL HEAVY + { 0x254A, BIDI_ON }, // BOX DRAWINGS LEFT LIGHT AND RIGHT VERTICAL HEAVY + { 0x254B, BIDI_ON }, // BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL + { 0x254C, BIDI_ON }, // BOX DRAWINGS LIGHT DOUBLE DASH HORIZONTAL + { 0x254D, BIDI_ON }, // BOX DRAWINGS HEAVY DOUBLE DASH HORIZONTAL + { 0x254E, BIDI_ON }, // BOX DRAWINGS LIGHT DOUBLE DASH VERTICAL + { 0x254F, BIDI_ON }, // BOX DRAWINGS HEAVY DOUBLE DASH VERTICAL + { 0x2550, BIDI_ON }, // BOX DRAWINGS DOUBLE HORIZONTAL + { 0x2551, BIDI_ON }, // BOX DRAWINGS DOUBLE VERTICAL + { 0x2552, BIDI_ON }, // BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE + { 0x2553, BIDI_ON }, // BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE + { 0x2554, BIDI_ON }, // BOX DRAWINGS DOUBLE DOWN AND RIGHT + { 0x2555, BIDI_ON }, // BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE + { 0x2556, BIDI_ON }, // BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE + { 0x2557, BIDI_ON }, // BOX DRAWINGS DOUBLE DOWN AND LEFT + { 0x2558, BIDI_ON }, // BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE + { 0x2559, BIDI_ON }, // BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE + { 0x255A, BIDI_ON }, // BOX DRAWINGS DOUBLE UP AND RIGHT + { 0x255B, BIDI_ON }, // BOX DRAWINGS UP SINGLE AND LEFT DOUBLE + { 0x255C, BIDI_ON }, // BOX DRAWINGS UP DOUBLE AND LEFT SINGLE + { 0x255D, BIDI_ON }, // BOX DRAWINGS DOUBLE UP AND LEFT + { 0x255E, BIDI_ON }, // BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + { 0x255F, BIDI_ON }, // BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE + { 0x2560, BIDI_ON }, // BOX DRAWINGS DOUBLE VERTICAL AND RIGHT + { 0x2561, BIDI_ON }, // BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + { 0x2562, BIDI_ON }, // BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE + { 0x2563, BIDI_ON }, // BOX DRAWINGS DOUBLE VERTICAL AND LEFT + { 0x2564, BIDI_ON }, // BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE + { 0x2565, BIDI_ON }, // BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE + { 0x2566, BIDI_ON }, // BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL + { 0x2567, BIDI_ON }, // BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE + { 0x2568, BIDI_ON }, // BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE + { 0x2569, BIDI_ON }, // BOX DRAWINGS DOUBLE UP AND HORIZONTAL + { 0x256A, BIDI_ON }, // BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + { 0x256B, BIDI_ON }, // BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE + { 0x256C, BIDI_ON }, // BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL + { 0x256D, BIDI_ON }, // BOX DRAWINGS LIGHT ARC DOWN AND RIGHT + { 0x256E, BIDI_ON }, // BOX DRAWINGS LIGHT ARC DOWN AND LEFT + { 0x256F, BIDI_ON }, // BOX DRAWINGS LIGHT ARC UP AND LEFT + { 0x2570, BIDI_ON }, // BOX DRAWINGS LIGHT ARC UP AND RIGHT + { 0x2571, BIDI_ON }, // BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT + { 0x2572, BIDI_ON }, // BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT + { 0x2573, BIDI_ON }, // BOX DRAWINGS LIGHT DIAGONAL CROSS + { 0x2574, BIDI_ON }, // BOX DRAWINGS LIGHT LEFT + { 0x2575, BIDI_ON }, // BOX DRAWINGS LIGHT UP + { 0x2576, BIDI_ON }, // BOX DRAWINGS LIGHT RIGHT + { 0x2577, BIDI_ON }, // BOX DRAWINGS LIGHT DOWN + { 0x2578, BIDI_ON }, // BOX DRAWINGS HEAVY LEFT + { 0x2579, BIDI_ON }, // BOX DRAWINGS HEAVY UP + { 0x257A, BIDI_ON }, // BOX DRAWINGS HEAVY RIGHT + { 0x257B, BIDI_ON }, // BOX DRAWINGS HEAVY DOWN + { 0x257C, BIDI_ON }, // BOX DRAWINGS LIGHT LEFT AND HEAVY RIGHT + { 0x257D, BIDI_ON }, // BOX DRAWINGS LIGHT UP AND HEAVY DOWN + { 0x257E, BIDI_ON }, // BOX DRAWINGS HEAVY LEFT AND LIGHT RIGHT + { 0x257F, BIDI_ON }, // BOX DRAWINGS HEAVY UP AND LIGHT DOWN + { 0x2580, BIDI_ON }, // UPPER HALF BLOCK + { 0x2581, BIDI_ON }, // LOWER ONE EIGHTH BLOCK + { 0x2582, BIDI_ON }, // LOWER ONE QUARTER BLOCK + { 0x2583, BIDI_ON }, // LOWER THREE EIGHTHS BLOCK + { 0x2584, BIDI_ON }, // LOWER HALF BLOCK + { 0x2585, BIDI_ON }, // LOWER FIVE EIGHTHS BLOCK + { 0x2586, BIDI_ON }, // LOWER THREE QUARTERS BLOCK + { 0x2587, BIDI_ON }, // LOWER SEVEN EIGHTHS BLOCK + { 0x2588, BIDI_ON }, // FULL BLOCK + { 0x2589, BIDI_ON }, // LEFT SEVEN EIGHTHS BLOCK + { 0x258A, BIDI_ON }, // LEFT THREE QUARTERS BLOCK + { 0x258B, BIDI_ON }, // LEFT FIVE EIGHTHS BLOCK + { 0x258C, BIDI_ON }, // LEFT HALF BLOCK + { 0x258D, BIDI_ON }, // LEFT THREE EIGHTHS BLOCK + { 0x258E, BIDI_ON }, // LEFT ONE QUARTER BLOCK + { 0x258F, BIDI_ON }, // LEFT ONE EIGHTH BLOCK + { 0x2590, BIDI_ON }, // RIGHT HALF BLOCK + { 0x2591, BIDI_ON }, // LIGHT SHADE + { 0x2592, BIDI_ON }, // MEDIUM SHADE + { 0x2593, BIDI_ON }, // DARK SHADE + { 0x2594, BIDI_ON }, // UPPER ONE EIGHTH BLOCK + { 0x2595, BIDI_ON }, // RIGHT ONE EIGHTH BLOCK + { 0x2596, BIDI_ON }, // QUADRANT LOWER LEFT + { 0x2597, BIDI_ON }, // QUADRANT LOWER RIGHT + { 0x2598, BIDI_ON }, // QUADRANT UPPER LEFT + { 0x2599, BIDI_ON }, // QUADRANT UPPER LEFT AND LOWER LEFT AND LOWER RIGHT + { 0x259A, BIDI_ON }, // QUADRANT UPPER LEFT AND LOWER RIGHT + { 0x259B, BIDI_ON }, // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER LEFT + { 0x259C, BIDI_ON }, // QUADRANT UPPER LEFT AND UPPER RIGHT AND LOWER RIGHT + { 0x259D, BIDI_ON }, // QUADRANT UPPER RIGHT + { 0x259E, BIDI_ON }, // QUADRANT UPPER RIGHT AND LOWER LEFT + { 0x259F, BIDI_ON }, // QUADRANT UPPER RIGHT AND LOWER LEFT AND LOWER RIGHT + { 0x25A0, BIDI_ON }, // BLACK SQUARE + { 0x25A1, BIDI_ON }, // WHITE SQUARE + { 0x25A2, BIDI_ON }, // WHITE SQUARE WITH ROUNDED CORNERS + { 0x25A3, BIDI_ON }, // WHITE SQUARE CONTAINING BLACK SMALL SQUARE + { 0x25A4, BIDI_ON }, // SQUARE WITH HORIZONTAL FILL + { 0x25A5, BIDI_ON }, // SQUARE WITH VERTICAL FILL + { 0x25A6, BIDI_ON }, // SQUARE WITH ORTHOGONAL CROSSHATCH FILL + { 0x25A7, BIDI_ON }, // SQUARE WITH UPPER LEFT TO LOWER RIGHT FILL + { 0x25A8, BIDI_ON }, // SQUARE WITH UPPER RIGHT TO LOWER LEFT FILL + { 0x25A9, BIDI_ON }, // SQUARE WITH DIAGONAL CROSSHATCH FILL + { 0x25AA, BIDI_ON }, // BLACK SMALL SQUARE + { 0x25AB, BIDI_ON }, // WHITE SMALL SQUARE + { 0x25AC, BIDI_ON }, // BLACK RECTANGLE + { 0x25AD, BIDI_ON }, // WHITE RECTANGLE + { 0x25AE, BIDI_ON }, // BLACK VERTICAL RECTANGLE + { 0x25AF, BIDI_ON }, // WHITE VERTICAL RECTANGLE + { 0x25B0, BIDI_ON }, // BLACK PARALLELOGRAM + { 0x25B1, BIDI_ON }, // WHITE PARALLELOGRAM + { 0x25B2, BIDI_ON }, // BLACK UP-POINTING TRIANGLE + { 0x25B3, BIDI_ON }, // WHITE UP-POINTING TRIANGLE + { 0x25B4, BIDI_ON }, // BLACK UP-POINTING SMALL TRIANGLE + { 0x25B5, BIDI_ON }, // WHITE UP-POINTING SMALL TRIANGLE + { 0x25B6, BIDI_ON }, // BLACK RIGHT-POINTING TRIANGLE + { 0x25B7, BIDI_ON }, // WHITE RIGHT-POINTING TRIANGLE + { 0x25B8, BIDI_ON }, // BLACK RIGHT-POINTING SMALL TRIANGLE + { 0x25B9, BIDI_ON }, // WHITE RIGHT-POINTING SMALL TRIANGLE + { 0x25BA, BIDI_ON }, // BLACK RIGHT-POINTING POINTER + { 0x25BB, BIDI_ON }, // WHITE RIGHT-POINTING POINTER + { 0x25BC, BIDI_ON }, // BLACK DOWN-POINTING TRIANGLE + { 0x25BD, BIDI_ON }, // WHITE DOWN-POINTING TRIANGLE + { 0x25BE, BIDI_ON }, // BLACK DOWN-POINTING SMALL TRIANGLE + { 0x25BF, BIDI_ON }, // WHITE DOWN-POINTING SMALL TRIANGLE + { 0x25C0, BIDI_ON }, // BLACK LEFT-POINTING TRIANGLE + { 0x25C1, BIDI_ON }, // WHITE LEFT-POINTING TRIANGLE + { 0x25C2, BIDI_ON }, // BLACK LEFT-POINTING SMALL TRIANGLE + { 0x25C3, BIDI_ON }, // WHITE LEFT-POINTING SMALL TRIANGLE + { 0x25C4, BIDI_ON }, // BLACK LEFT-POINTING POINTER + { 0x25C5, BIDI_ON }, // WHITE LEFT-POINTING POINTER + { 0x25C6, BIDI_ON }, // BLACK DIAMOND + { 0x25C7, BIDI_ON }, // WHITE DIAMOND + { 0x25C8, BIDI_ON }, // WHITE DIAMOND CONTAINING BLACK SMALL DIAMOND + { 0x25C9, BIDI_ON }, // FISHEYE + { 0x25CA, BIDI_ON }, // LOZENGE + { 0x25CB, BIDI_ON }, // WHITE CIRCLE + { 0x25CC, BIDI_ON }, // DOTTED CIRCLE + { 0x25CD, BIDI_ON }, // CIRCLE WITH VERTICAL FILL + { 0x25CE, BIDI_ON }, // BULLSEYE + { 0x25CF, BIDI_ON }, // BLACK CIRCLE + { 0x25D0, BIDI_ON }, // CIRCLE WITH LEFT HALF BLACK + { 0x25D1, BIDI_ON }, // CIRCLE WITH RIGHT HALF BLACK + { 0x25D2, BIDI_ON }, // CIRCLE WITH LOWER HALF BLACK + { 0x25D3, BIDI_ON }, // CIRCLE WITH UPPER HALF BLACK + { 0x25D4, BIDI_ON }, // CIRCLE WITH UPPER RIGHT QUADRANT BLACK + { 0x25D5, BIDI_ON }, // CIRCLE WITH ALL BUT UPPER LEFT QUADRANT BLACK + { 0x25D6, BIDI_ON }, // LEFT HALF BLACK CIRCLE + { 0x25D7, BIDI_ON }, // RIGHT HALF BLACK CIRCLE + { 0x25D8, BIDI_ON }, // INVERSE BULLET + { 0x25D9, BIDI_ON }, // INVERSE WHITE CIRCLE + { 0x25DA, BIDI_ON }, // UPPER HALF INVERSE WHITE CIRCLE + { 0x25DB, BIDI_ON }, // LOWER HALF INVERSE WHITE CIRCLE + { 0x25DC, BIDI_ON }, // UPPER LEFT QUADRANT CIRCULAR ARC + { 0x25DD, BIDI_ON }, // UPPER RIGHT QUADRANT CIRCULAR ARC + { 0x25DE, BIDI_ON }, // LOWER RIGHT QUADRANT CIRCULAR ARC + { 0x25DF, BIDI_ON }, // LOWER LEFT QUADRANT CIRCULAR ARC + { 0x25E0, BIDI_ON }, // UPPER HALF CIRCLE + { 0x25E1, BIDI_ON }, // LOWER HALF CIRCLE + { 0x25E2, BIDI_ON }, // BLACK LOWER RIGHT TRIANGLE + { 0x25E3, BIDI_ON }, // BLACK LOWER LEFT TRIANGLE + { 0x25E4, BIDI_ON }, // BLACK UPPER LEFT TRIANGLE + { 0x25E5, BIDI_ON }, // BLACK UPPER RIGHT TRIANGLE + { 0x25E6, BIDI_ON }, // WHITE BULLET + { 0x25E7, BIDI_ON }, // SQUARE WITH LEFT HALF BLACK + { 0x25E8, BIDI_ON }, // SQUARE WITH RIGHT HALF BLACK + { 0x25E9, BIDI_ON }, // SQUARE WITH UPPER LEFT DIAGONAL HALF BLACK + { 0x25EA, BIDI_ON }, // SQUARE WITH LOWER RIGHT DIAGONAL HALF BLACK + { 0x25EB, BIDI_ON }, // WHITE SQUARE WITH VERTICAL BISECTING LINE + { 0x25EC, BIDI_ON }, // WHITE UP-POINTING TRIANGLE WITH DOT + { 0x25ED, BIDI_ON }, // UP-POINTING TRIANGLE WITH LEFT HALF BLACK + { 0x25EE, BIDI_ON }, // UP-POINTING TRIANGLE WITH RIGHT HALF BLACK + { 0x25EF, BIDI_ON }, // LARGE CIRCLE + { 0x25F0, BIDI_ON }, // WHITE SQUARE WITH UPPER LEFT QUADRANT + { 0x25F1, BIDI_ON }, // WHITE SQUARE WITH LOWER LEFT QUADRANT + { 0x25F2, BIDI_ON }, // WHITE SQUARE WITH LOWER RIGHT QUADRANT + { 0x25F3, BIDI_ON }, // WHITE SQUARE WITH UPPER RIGHT QUADRANT + { 0x25F4, BIDI_ON }, // WHITE CIRCLE WITH UPPER LEFT QUADRANT + { 0x25F5, BIDI_ON }, // WHITE CIRCLE WITH LOWER LEFT QUADRANT + { 0x25F6, BIDI_ON }, // WHITE CIRCLE WITH LOWER RIGHT QUADRANT + { 0x25F7, BIDI_ON }, // WHITE CIRCLE WITH UPPER RIGHT QUADRANT + { 0x25F8, BIDI_ON }, // UPPER LEFT TRIANGLE + { 0x25F9, BIDI_ON }, // UPPER RIGHT TRIANGLE + { 0x25FA, BIDI_ON }, // LOWER LEFT TRIANGLE + { 0x25FB, BIDI_ON }, // WHITE MEDIUM SQUARE + { 0x25FC, BIDI_ON }, // BLACK MEDIUM SQUARE + { 0x25FD, BIDI_ON }, // WHITE MEDIUM SMALL SQUARE + { 0x25FE, BIDI_ON }, // BLACK MEDIUM SMALL SQUARE + { 0x25FF, BIDI_ON }, // LOWER RIGHT TRIANGLE + { 0x2600, BIDI_ON }, // BLACK SUN WITH RAYS + { 0x2601, BIDI_ON }, // CLOUD + { 0x2602, BIDI_ON }, // UMBRELLA + { 0x2603, BIDI_ON }, // SNOWMAN + { 0x2604, BIDI_ON }, // COMET + { 0x2605, BIDI_ON }, // BLACK STAR + { 0x2606, BIDI_ON }, // WHITE STAR + { 0x2607, BIDI_ON }, // LIGHTNING + { 0x2608, BIDI_ON }, // THUNDERSTORM + { 0x2609, BIDI_ON }, // SUN + { 0x260A, BIDI_ON }, // ASCENDING NODE + { 0x260B, BIDI_ON }, // DESCENDING NODE + { 0x260C, BIDI_ON }, // CONJUNCTION + { 0x260D, BIDI_ON }, // OPPOSITION + { 0x260E, BIDI_ON }, // BLACK TELEPHONE + { 0x260F, BIDI_ON }, // WHITE TELEPHONE + { 0x2610, BIDI_ON }, // BALLOT BOX + { 0x2611, BIDI_ON }, // BALLOT BOX WITH CHECK + { 0x2612, BIDI_ON }, // BALLOT BOX WITH X + { 0x2613, BIDI_ON }, // SALTIRE + { 0x2614, BIDI_ON }, // UMBRELLA WITH RAIN DROPS + { 0x2615, BIDI_ON }, // HOT BEVERAGE + { 0x2616, BIDI_ON }, // WHITE SHOGI PIECE + { 0x2617, BIDI_ON }, // BLACK SHOGI PIECE + { 0x2618, BIDI_ON }, // SHAMROCK + { 0x2619, BIDI_ON }, // REVERSED ROTATED FLORAL HEART BULLET + { 0x261A, BIDI_ON }, // BLACK LEFT POINTING INDEX + { 0x261B, BIDI_ON }, // BLACK RIGHT POINTING INDEX + { 0x261C, BIDI_ON }, // WHITE LEFT POINTING INDEX + { 0x261D, BIDI_ON }, // WHITE UP POINTING INDEX + { 0x261E, BIDI_ON }, // WHITE RIGHT POINTING INDEX + { 0x261F, BIDI_ON }, // WHITE DOWN POINTING INDEX + { 0x2620, BIDI_ON }, // SKULL AND CROSSBONES + { 0x2621, BIDI_ON }, // CAUTION SIGN + { 0x2622, BIDI_ON }, // RADIOACTIVE SIGN + { 0x2623, BIDI_ON }, // BIOHAZARD SIGN + { 0x2624, BIDI_ON }, // CADUCEUS + { 0x2625, BIDI_ON }, // ANKH + { 0x2626, BIDI_ON }, // ORTHODOX CROSS + { 0x2627, BIDI_ON }, // CHI RHO + { 0x2628, BIDI_ON }, // CROSS OF LORRAINE + { 0x2629, BIDI_ON }, // CROSS OF JERUSALEM + { 0x262A, BIDI_ON }, // STAR AND CRESCENT + { 0x262B, BIDI_ON }, // FARSI SYMBOL + { 0x262C, BIDI_ON }, // ADI SHAKTI + { 0x262D, BIDI_ON }, // HAMMER AND SICKLE + { 0x262E, BIDI_ON }, // PEACE SYMBOL + { 0x262F, BIDI_ON }, // YIN YANG + { 0x2630, BIDI_ON }, // TRIGRAM FOR HEAVEN + { 0x2631, BIDI_ON }, // TRIGRAM FOR LAKE + { 0x2632, BIDI_ON }, // TRIGRAM FOR FIRE + { 0x2633, BIDI_ON }, // TRIGRAM FOR THUNDER + { 0x2634, BIDI_ON }, // TRIGRAM FOR WIND + { 0x2635, BIDI_ON }, // TRIGRAM FOR WATER + { 0x2636, BIDI_ON }, // TRIGRAM FOR MOUNTAIN + { 0x2637, BIDI_ON }, // TRIGRAM FOR EARTH + { 0x2638, BIDI_ON }, // WHEEL OF DHARMA + { 0x2639, BIDI_ON }, // WHITE FROWNING FACE + { 0x263A, BIDI_ON }, // WHITE SMILING FACE + { 0x263B, BIDI_ON }, // BLACK SMILING FACE + { 0x263C, BIDI_ON }, // WHITE SUN WITH RAYS + { 0x263D, BIDI_ON }, // FIRST QUARTER MOON + { 0x263E, BIDI_ON }, // LAST QUARTER MOON + { 0x263F, BIDI_ON }, // MERCURY + { 0x2640, BIDI_ON }, // FEMALE SIGN + { 0x2641, BIDI_ON }, // EARTH + { 0x2642, BIDI_ON }, // MALE SIGN + { 0x2643, BIDI_ON }, // JUPITER + { 0x2644, BIDI_ON }, // SATURN + { 0x2645, BIDI_ON }, // URANUS + { 0x2646, BIDI_ON }, // NEPTUNE + { 0x2647, BIDI_ON }, // PLUTO + { 0x2648, BIDI_ON }, // ARIES + { 0x2649, BIDI_ON }, // TAURUS + { 0x264A, BIDI_ON }, // GEMINI + { 0x264B, BIDI_ON }, // CANCER + { 0x264C, BIDI_ON }, // LEO + { 0x264D, BIDI_ON }, // VIRGO + { 0x264E, BIDI_ON }, // LIBRA + { 0x264F, BIDI_ON }, // SCORPIUS + { 0x2650, BIDI_ON }, // SAGITTARIUS + { 0x2651, BIDI_ON }, // CAPRICORN + { 0x2652, BIDI_ON }, // AQUARIUS + { 0x2653, BIDI_ON }, // PISCES + { 0x2654, BIDI_ON }, // WHITE CHESS KING + { 0x2655, BIDI_ON }, // WHITE CHESS QUEEN + { 0x2656, BIDI_ON }, // WHITE CHESS ROOK + { 0x2657, BIDI_ON }, // WHITE CHESS BISHOP + { 0x2658, BIDI_ON }, // WHITE CHESS KNIGHT + { 0x2659, BIDI_ON }, // WHITE CHESS PAWN + { 0x265A, BIDI_ON }, // BLACK CHESS KING + { 0x265B, BIDI_ON }, // BLACK CHESS QUEEN + { 0x265C, BIDI_ON }, // BLACK CHESS ROOK + { 0x265D, BIDI_ON }, // BLACK CHESS BISHOP + { 0x265E, BIDI_ON }, // BLACK CHESS KNIGHT + { 0x265F, BIDI_ON }, // BLACK CHESS PAWN + { 0x2660, BIDI_ON }, // BLACK SPADE SUIT + { 0x2661, BIDI_ON }, // WHITE HEART SUIT + { 0x2662, BIDI_ON }, // WHITE DIAMOND SUIT + { 0x2663, BIDI_ON }, // BLACK CLUB SUIT + { 0x2664, BIDI_ON }, // WHITE SPADE SUIT + { 0x2665, BIDI_ON }, // BLACK HEART SUIT + { 0x2666, BIDI_ON }, // BLACK DIAMOND SUIT + { 0x2667, BIDI_ON }, // WHITE CLUB SUIT + { 0x2668, BIDI_ON }, // HOT SPRINGS + { 0x2669, BIDI_ON }, // QUARTER NOTE + { 0x266A, BIDI_ON }, // EIGHTH NOTE + { 0x266B, BIDI_ON }, // BEAMED EIGHTH NOTES + { 0x266C, BIDI_ON }, // BEAMED SIXTEENTH NOTES + { 0x266D, BIDI_ON }, // MUSIC FLAT SIGN + { 0x266E, BIDI_ON }, // MUSIC NATURAL SIGN + { 0x266F, BIDI_ON }, // MUSIC SHARP SIGN + { 0x2670, BIDI_ON }, // WEST SYRIAC CROSS + { 0x2671, BIDI_ON }, // EAST SYRIAC CROSS + { 0x2672, BIDI_ON }, // UNIVERSAL RECYCLING SYMBOL + { 0x2673, BIDI_ON }, // RECYCLING SYMBOL FOR TYPE-1 PLASTICS + { 0x2674, BIDI_ON }, // RECYCLING SYMBOL FOR TYPE-2 PLASTICS + { 0x2675, BIDI_ON }, // RECYCLING SYMBOL FOR TYPE-3 PLASTICS + { 0x2676, BIDI_ON }, // RECYCLING SYMBOL FOR TYPE-4 PLASTICS + { 0x2677, BIDI_ON }, // RECYCLING SYMBOL FOR TYPE-5 PLASTICS + { 0x2678, BIDI_ON }, // RECYCLING SYMBOL FOR TYPE-6 PLASTICS + { 0x2679, BIDI_ON }, // RECYCLING SYMBOL FOR TYPE-7 PLASTICS + { 0x267A, BIDI_ON }, // RECYCLING SYMBOL FOR GENERIC MATERIALS + { 0x267B, BIDI_ON }, // BLACK UNIVERSAL RECYCLING SYMBOL + { 0x267C, BIDI_ON }, // RECYCLED PAPER SYMBOL + { 0x267D, BIDI_ON }, // PARTIALLY-RECYCLED PAPER SYMBOL + { 0x267E, BIDI_ON }, // PERMANENT PAPER SIGN + { 0x267F, BIDI_ON }, // WHEELCHAIR SYMBOL + { 0x2680, BIDI_ON }, // DIE FACE-1 + { 0x2681, BIDI_ON }, // DIE FACE-2 + { 0x2682, BIDI_ON }, // DIE FACE-3 + { 0x2683, BIDI_ON }, // DIE FACE-4 + { 0x2684, BIDI_ON }, // DIE FACE-5 + { 0x2685, BIDI_ON }, // DIE FACE-6 + { 0x2686, BIDI_ON }, // WHITE CIRCLE WITH DOT RIGHT + { 0x2687, BIDI_ON }, // WHITE CIRCLE WITH TWO DOTS + { 0x2688, BIDI_ON }, // BLACK CIRCLE WITH WHITE DOT RIGHT + { 0x2689, BIDI_ON }, // BLACK CIRCLE WITH TWO WHITE DOTS + { 0x268A, BIDI_ON }, // MONOGRAM FOR YANG + { 0x268B, BIDI_ON }, // MONOGRAM FOR YIN + { 0x268C, BIDI_ON }, // DIGRAM FOR GREATER YANG + { 0x268D, BIDI_ON }, // DIGRAM FOR LESSER YIN + { 0x268E, BIDI_ON }, // DIGRAM FOR LESSER YANG + { 0x268F, BIDI_ON }, // DIGRAM FOR GREATER YIN + { 0x2690, BIDI_ON }, // WHITE FLAG + { 0x2691, BIDI_ON }, // BLACK FLAG + { 0x2692, BIDI_ON }, // HAMMER AND PICK + { 0x2693, BIDI_ON }, // ANCHOR + { 0x2694, BIDI_ON }, // CROSSED SWORDS + { 0x2695, BIDI_ON }, // STAFF OF AESCULAPIUS + { 0x2696, BIDI_ON }, // SCALES + { 0x2697, BIDI_ON }, // ALEMBIC + { 0x2698, BIDI_ON }, // FLOWER + { 0x2699, BIDI_ON }, // GEAR + { 0x269A, BIDI_ON }, // STAFF OF HERMES + { 0x269B, BIDI_ON }, // ATOM SYMBOL + { 0x269C, BIDI_ON }, // FLEUR-DE-LIS + { 0x269D, BIDI_ON }, // OUTLINED WHITE STAR + { 0x269E, BIDI_ON }, // THREE LINES CONVERGING RIGHT + { 0x269F, BIDI_ON }, // THREE LINES CONVERGING LEFT + { 0x26A0, BIDI_ON }, // WARNING SIGN + { 0x26A1, BIDI_ON }, // HIGH VOLTAGE SIGN + { 0x26A2, BIDI_ON }, // DOUBLED FEMALE SIGN + { 0x26A3, BIDI_ON }, // DOUBLED MALE SIGN + { 0x26A4, BIDI_ON }, // INTERLOCKED FEMALE AND MALE SIGN + { 0x26A5, BIDI_ON }, // MALE AND FEMALE SIGN + { 0x26A6, BIDI_ON }, // MALE WITH STROKE SIGN + { 0x26A7, BIDI_ON }, // MALE WITH STROKE AND MALE AND FEMALE SIGN + { 0x26A8, BIDI_ON }, // VERTICAL MALE WITH STROKE SIGN + { 0x26A9, BIDI_ON }, // HORIZONTAL MALE WITH STROKE SIGN + { 0x26AA, BIDI_ON }, // MEDIUM WHITE CIRCLE + { 0x26AB, BIDI_ON }, // MEDIUM BLACK CIRCLE + { 0x26AC, BIDI_L }, // MEDIUM SMALL WHITE CIRCLE + { 0x26AD, BIDI_ON }, // MARRIAGE SYMBOL + { 0x26AE, BIDI_ON }, // DIVORCE SYMBOL + { 0x26AF, BIDI_ON }, // UNMARRIED PARTNERSHIP SYMBOL + { 0x26B0, BIDI_ON }, // COFFIN + { 0x26B1, BIDI_ON }, // FUNERAL URN + { 0x26B2, BIDI_ON }, // NEUTER + { 0x26B3, BIDI_ON }, // CERES + { 0x26B4, BIDI_ON }, // PALLAS + { 0x26B5, BIDI_ON }, // JUNO + { 0x26B6, BIDI_ON }, // VESTA + { 0x26B7, BIDI_ON }, // CHIRON + { 0x26B8, BIDI_ON }, // BLACK MOON LILITH + { 0x26B9, BIDI_ON }, // SEXTILE + { 0x26BA, BIDI_ON }, // SEMISEXTILE + { 0x26BB, BIDI_ON }, // QUINCUNX + { 0x26BC, BIDI_ON }, // SESQUIQUADRATE + { 0x26BD, BIDI_ON }, // SOCCER BALL + { 0x26BE, BIDI_ON }, // BASEBALL + { 0x26BF, BIDI_ON }, // SQUARED KEY + { 0x26C0, BIDI_ON }, // WHITE DRAUGHTS MAN + { 0x26C1, BIDI_ON }, // WHITE DRAUGHTS KING + { 0x26C2, BIDI_ON }, // BLACK DRAUGHTS MAN + { 0x26C3, BIDI_ON }, // BLACK DRAUGHTS KING + { 0x26C4, BIDI_ON }, // SNOWMAN WITHOUT SNOW + { 0x26C5, BIDI_ON }, // SUN BEHIND CLOUD + { 0x26C6, BIDI_ON }, // RAIN + { 0x26C7, BIDI_ON }, // BLACK SNOWMAN + { 0x26C8, BIDI_ON }, // THUNDER CLOUD AND RAIN + { 0x26C9, BIDI_ON }, // TURNED WHITE SHOGI PIECE + { 0x26CA, BIDI_ON }, // TURNED BLACK SHOGI PIECE + { 0x26CB, BIDI_ON }, // WHITE DIAMOND IN SQUARE + { 0x26CC, BIDI_ON }, // CROSSING LANES + { 0x26CD, BIDI_ON }, // DISABLED CAR + { 0x26CE, BIDI_ON }, // OPHIUCHUS + { 0x26CF, BIDI_ON }, // PICK + { 0x26D0, BIDI_ON }, // CAR SLIDING + { 0x26D1, BIDI_ON }, // HELMET WITH WHITE CROSS + { 0x26D2, BIDI_ON }, // CIRCLED CROSSING LANES + { 0x26D3, BIDI_ON }, // CHAINS + { 0x26D4, BIDI_ON }, // NO ENTRY + { 0x26D5, BIDI_ON }, // ALTERNATE ONE-WAY LEFT WAY TRAFFIC + { 0x26D6, BIDI_ON }, // BLACK TWO-WAY LEFT WAY TRAFFIC + { 0x26D7, BIDI_ON }, // WHITE TWO-WAY LEFT WAY TRAFFIC + { 0x26D8, BIDI_ON }, // BLACK LEFT LANE MERGE + { 0x26D9, BIDI_ON }, // WHITE LEFT LANE MERGE + { 0x26DA, BIDI_ON }, // DRIVE SLOW SIGN + { 0x26DB, BIDI_ON }, // HEAVY WHITE DOWN-POINTING TRIANGLE + { 0x26DC, BIDI_ON }, // LEFT CLOSED ENTRY + { 0x26DD, BIDI_ON }, // SQUARED SALTIRE + { 0x26DE, BIDI_ON }, // FALLING DIAGONAL IN WHITE CIRCLE IN BLACK SQUARE + { 0x26DF, BIDI_ON }, // BLACK TRUCK + { 0x26E0, BIDI_ON }, // RESTRICTED LEFT ENTRY-1 + { 0x26E1, BIDI_ON }, // RESTRICTED LEFT ENTRY-2 + { 0x26E2, BIDI_ON }, // ASTRONOMICAL SYMBOL FOR URANUS + { 0x26E3, BIDI_ON }, // HEAVY CIRCLE WITH STROKE AND TWO DOTS ABOVE + { 0x26E4, BIDI_ON }, // PENTAGRAM + { 0x26E5, BIDI_ON }, // RIGHT-HANDED INTERLACED PENTAGRAM + { 0x26E6, BIDI_ON }, // LEFT-HANDED INTERLACED PENTAGRAM + { 0x26E7, BIDI_ON }, // INVERTED PENTAGRAM + { 0x26E8, BIDI_ON }, // BLACK CROSS ON SHIELD + { 0x26E9, BIDI_ON }, // SHINTO SHRINE + { 0x26EA, BIDI_ON }, // CHURCH + { 0x26EB, BIDI_ON }, // CASTLE + { 0x26EC, BIDI_ON }, // HISTORIC SITE + { 0x26ED, BIDI_ON }, // GEAR WITHOUT HUB + { 0x26EE, BIDI_ON }, // GEAR WITH HANDLES + { 0x26EF, BIDI_ON }, // MAP SYMBOL FOR LIGHTHOUSE + { 0x26F0, BIDI_ON }, // MOUNTAIN + { 0x26F1, BIDI_ON }, // UMBRELLA ON GROUND + { 0x26F2, BIDI_ON }, // FOUNTAIN + { 0x26F3, BIDI_ON }, // FLAG IN HOLE + { 0x26F4, BIDI_ON }, // FERRY + { 0x26F5, BIDI_ON }, // SAILBOAT + { 0x26F6, BIDI_ON }, // SQUARE FOUR CORNERS + { 0x26F7, BIDI_ON }, // SKIER + { 0x26F8, BIDI_ON }, // ICE SKATE + { 0x26F9, BIDI_ON }, // PERSON WITH BALL + { 0x26FA, BIDI_ON }, // TENT + { 0x26FB, BIDI_ON }, // JAPANESE BANK SYMBOL + { 0x26FC, BIDI_ON }, // HEADSTONE GRAVEYARD SYMBOL + { 0x26FD, BIDI_ON }, // FUEL PUMP + { 0x26FE, BIDI_ON }, // CUP ON BLACK SQUARE + { 0x26FF, BIDI_ON }, // WHITE FLAG WITH HORIZONTAL MIDDLE BLACK STRIPE + { 0x2700, BIDI_ON }, // BLACK SAFETY SCISSORS + { 0x2701, BIDI_ON }, // UPPER BLADE SCISSORS + { 0x2702, BIDI_ON }, // BLACK SCISSORS + { 0x2703, BIDI_ON }, // LOWER BLADE SCISSORS + { 0x2704, BIDI_ON }, // WHITE SCISSORS + { 0x2705, BIDI_ON }, // WHITE HEAVY CHECK MARK + { 0x2706, BIDI_ON }, // TELEPHONE LOCATION SIGN + { 0x2707, BIDI_ON }, // TAPE DRIVE + { 0x2708, BIDI_ON }, // AIRPLANE + { 0x2709, BIDI_ON }, // ENVELOPE + { 0x270A, BIDI_ON }, // RAISED FIST + { 0x270B, BIDI_ON }, // RAISED HAND + { 0x270C, BIDI_ON }, // VICTORY HAND + { 0x270D, BIDI_ON }, // WRITING HAND + { 0x270E, BIDI_ON }, // LOWER RIGHT PENCIL + { 0x270F, BIDI_ON }, // PENCIL + { 0x2710, BIDI_ON }, // UPPER RIGHT PENCIL + { 0x2711, BIDI_ON }, // WHITE NIB + { 0x2712, BIDI_ON }, // BLACK NIB + { 0x2713, BIDI_ON }, // CHECK MARK + { 0x2714, BIDI_ON }, // HEAVY CHECK MARK + { 0x2715, BIDI_ON }, // MULTIPLICATION X + { 0x2716, BIDI_ON }, // HEAVY MULTIPLICATION X + { 0x2717, BIDI_ON }, // BALLOT X + { 0x2718, BIDI_ON }, // HEAVY BALLOT X + { 0x2719, BIDI_ON }, // OUTLINED GREEK CROSS + { 0x271A, BIDI_ON }, // HEAVY GREEK CROSS + { 0x271B, BIDI_ON }, // OPEN CENTRE CROSS + { 0x271C, BIDI_ON }, // HEAVY OPEN CENTRE CROSS + { 0x271D, BIDI_ON }, // LATIN CROSS + { 0x271E, BIDI_ON }, // SHADOWED WHITE LATIN CROSS + { 0x271F, BIDI_ON }, // OUTLINED LATIN CROSS + { 0x2720, BIDI_ON }, // MALTESE CROSS + { 0x2721, BIDI_ON }, // STAR OF DAVID + { 0x2722, BIDI_ON }, // FOUR TEARDROP-SPOKED ASTERISK + { 0x2723, BIDI_ON }, // FOUR BALLOON-SPOKED ASTERISK + { 0x2724, BIDI_ON }, // HEAVY FOUR BALLOON-SPOKED ASTERISK + { 0x2725, BIDI_ON }, // FOUR CLUB-SPOKED ASTERISK + { 0x2726, BIDI_ON }, // BLACK FOUR POINTED STAR + { 0x2727, BIDI_ON }, // WHITE FOUR POINTED STAR + { 0x2728, BIDI_ON }, // SPARKLES + { 0x2729, BIDI_ON }, // STRESS OUTLINED WHITE STAR + { 0x272A, BIDI_ON }, // CIRCLED WHITE STAR + { 0x272B, BIDI_ON }, // OPEN CENTRE BLACK STAR + { 0x272C, BIDI_ON }, // BLACK CENTRE WHITE STAR + { 0x272D, BIDI_ON }, // OUTLINED BLACK STAR + { 0x272E, BIDI_ON }, // HEAVY OUTLINED BLACK STAR + { 0x272F, BIDI_ON }, // PINWHEEL STAR + { 0x2730, BIDI_ON }, // SHADOWED WHITE STAR + { 0x2731, BIDI_ON }, // HEAVY ASTERISK + { 0x2732, BIDI_ON }, // OPEN CENTRE ASTERISK + { 0x2733, BIDI_ON }, // EIGHT SPOKED ASTERISK + { 0x2734, BIDI_ON }, // EIGHT POINTED BLACK STAR + { 0x2735, BIDI_ON }, // EIGHT POINTED PINWHEEL STAR + { 0x2736, BIDI_ON }, // SIX POINTED BLACK STAR + { 0x2737, BIDI_ON }, // EIGHT POINTED RECTILINEAR BLACK STAR + { 0x2738, BIDI_ON }, // HEAVY EIGHT POINTED RECTILINEAR BLACK STAR + { 0x2739, BIDI_ON }, // TWELVE POINTED BLACK STAR + { 0x273A, BIDI_ON }, // SIXTEEN POINTED ASTERISK + { 0x273B, BIDI_ON }, // TEARDROP-SPOKED ASTERISK + { 0x273C, BIDI_ON }, // OPEN CENTRE TEARDROP-SPOKED ASTERISK + { 0x273D, BIDI_ON }, // HEAVY TEARDROP-SPOKED ASTERISK + { 0x273E, BIDI_ON }, // SIX PETALLED BLACK AND WHITE FLORETTE + { 0x273F, BIDI_ON }, // BLACK FLORETTE + { 0x2740, BIDI_ON }, // WHITE FLORETTE + { 0x2741, BIDI_ON }, // EIGHT PETALLED OUTLINED BLACK FLORETTE + { 0x2742, BIDI_ON }, // CIRCLED OPEN CENTRE EIGHT POINTED STAR + { 0x2743, BIDI_ON }, // HEAVY TEARDROP-SPOKED PINWHEEL ASTERISK + { 0x2744, BIDI_ON }, // SNOWFLAKE + { 0x2745, BIDI_ON }, // TIGHT TRIFOLIATE SNOWFLAKE + { 0x2746, BIDI_ON }, // HEAVY CHEVRON SNOWFLAKE + { 0x2747, BIDI_ON }, // SPARKLE + { 0x2748, BIDI_ON }, // HEAVY SPARKLE + { 0x2749, BIDI_ON }, // BALLOON-SPOKED ASTERISK + { 0x274A, BIDI_ON }, // EIGHT TEARDROP-SPOKED PROPELLER ASTERISK + { 0x274B, BIDI_ON }, // HEAVY EIGHT TEARDROP-SPOKED PROPELLER ASTERISK + { 0x274C, BIDI_ON }, // CROSS MARK + { 0x274D, BIDI_ON }, // SHADOWED WHITE CIRCLE + { 0x274E, BIDI_ON }, // NEGATIVE SQUARED CROSS MARK + { 0x274F, BIDI_ON }, // LOWER RIGHT DROP-SHADOWED WHITE SQUARE + { 0x2750, BIDI_ON }, // UPPER RIGHT DROP-SHADOWED WHITE SQUARE + { 0x2751, BIDI_ON }, // LOWER RIGHT SHADOWED WHITE SQUARE + { 0x2752, BIDI_ON }, // UPPER RIGHT SHADOWED WHITE SQUARE + { 0x2753, BIDI_ON }, // BLACK QUESTION MARK ORNAMENT + { 0x2754, BIDI_ON }, // WHITE QUESTION MARK ORNAMENT + { 0x2755, BIDI_ON }, // WHITE EXCLAMATION MARK ORNAMENT + { 0x2756, BIDI_ON }, // BLACK DIAMOND MINUS WHITE X + { 0x2757, BIDI_ON }, // HEAVY EXCLAMATION MARK SYMBOL + { 0x2758, BIDI_ON }, // LIGHT VERTICAL BAR + { 0x2759, BIDI_ON }, // MEDIUM VERTICAL BAR + { 0x275A, BIDI_ON }, // HEAVY VERTICAL BAR + { 0x275B, BIDI_ON }, // HEAVY SINGLE TURNED COMMA QUOTATION MARK ORNAMENT + { 0x275C, BIDI_ON }, // HEAVY SINGLE COMMA QUOTATION MARK ORNAMENT + { 0x275D, BIDI_ON }, // HEAVY DOUBLE TURNED COMMA QUOTATION MARK ORNAMENT + { 0x275E, BIDI_ON }, // HEAVY DOUBLE COMMA QUOTATION MARK ORNAMENT + { 0x275F, BIDI_ON }, // HEAVY LOW SINGLE COMMA QUOTATION MARK ORNAMENT + { 0x2760, BIDI_ON }, // HEAVY LOW DOUBLE COMMA QUOTATION MARK ORNAMENT + { 0x2761, BIDI_ON }, // CURVED STEM PARAGRAPH SIGN ORNAMENT + { 0x2762, BIDI_ON }, // HEAVY EXCLAMATION MARK ORNAMENT + { 0x2763, BIDI_ON }, // HEAVY HEART EXCLAMATION MARK ORNAMENT + { 0x2764, BIDI_ON }, // HEAVY BLACK HEART + { 0x2765, BIDI_ON }, // ROTATED HEAVY BLACK HEART BULLET + { 0x2766, BIDI_ON }, // FLORAL HEART + { 0x2767, BIDI_ON }, // ROTATED FLORAL HEART BULLET + { 0x2768, BIDI_ON }, // MEDIUM LEFT PARENTHESIS ORNAMENT + { 0x2769, BIDI_ON }, // MEDIUM RIGHT PARENTHESIS ORNAMENT + { 0x276A, BIDI_ON }, // MEDIUM FLATTENED LEFT PARENTHESIS ORNAMENT + { 0x276B, BIDI_ON }, // MEDIUM FLATTENED RIGHT PARENTHESIS ORNAMENT + { 0x276C, BIDI_ON }, // MEDIUM LEFT-POINTING ANGLE BRACKET ORNAMENT + { 0x276D, BIDI_ON }, // MEDIUM RIGHT-POINTING ANGLE BRACKET ORNAMENT + { 0x276E, BIDI_ON }, // HEAVY LEFT-POINTING ANGLE QUOTATION MARK ORNAMENT + { 0x276F, BIDI_ON }, // HEAVY RIGHT-POINTING ANGLE QUOTATION MARK ORNAMENT + { 0x2770, BIDI_ON }, // HEAVY LEFT-POINTING ANGLE BRACKET ORNAMENT + { 0x2771, BIDI_ON }, // HEAVY RIGHT-POINTING ANGLE BRACKET ORNAMENT + { 0x2772, BIDI_ON }, // LIGHT LEFT TORTOISE SHELL BRACKET ORNAMENT + { 0x2773, BIDI_ON }, // LIGHT RIGHT TORTOISE SHELL BRACKET ORNAMENT + { 0x2774, BIDI_ON }, // MEDIUM LEFT CURLY BRACKET ORNAMENT + { 0x2775, BIDI_ON }, // MEDIUM RIGHT CURLY BRACKET ORNAMENT + { 0x2776, BIDI_ON }, // DINGBAT NEGATIVE CIRCLED DIGIT ONE + { 0x2777, BIDI_ON }, // DINGBAT NEGATIVE CIRCLED DIGIT TWO + { 0x2778, BIDI_ON }, // DINGBAT NEGATIVE CIRCLED DIGIT THREE + { 0x2779, BIDI_ON }, // DINGBAT NEGATIVE CIRCLED DIGIT FOUR + { 0x277A, BIDI_ON }, // DINGBAT NEGATIVE CIRCLED DIGIT FIVE + { 0x277B, BIDI_ON }, // DINGBAT NEGATIVE CIRCLED DIGIT SIX + { 0x277C, BIDI_ON }, // DINGBAT NEGATIVE CIRCLED DIGIT SEVEN + { 0x277D, BIDI_ON }, // DINGBAT NEGATIVE CIRCLED DIGIT EIGHT + { 0x277E, BIDI_ON }, // DINGBAT NEGATIVE CIRCLED DIGIT NINE + { 0x277F, BIDI_ON }, // DINGBAT NEGATIVE CIRCLED NUMBER TEN + { 0x2780, BIDI_ON }, // DINGBAT CIRCLED SANS-SERIF DIGIT ONE + { 0x2781, BIDI_ON }, // DINGBAT CIRCLED SANS-SERIF DIGIT TWO + { 0x2782, BIDI_ON }, // DINGBAT CIRCLED SANS-SERIF DIGIT THREE + { 0x2783, BIDI_ON }, // DINGBAT CIRCLED SANS-SERIF DIGIT FOUR + { 0x2784, BIDI_ON }, // DINGBAT CIRCLED SANS-SERIF DIGIT FIVE + { 0x2785, BIDI_ON }, // DINGBAT CIRCLED SANS-SERIF DIGIT SIX + { 0x2786, BIDI_ON }, // DINGBAT CIRCLED SANS-SERIF DIGIT SEVEN + { 0x2787, BIDI_ON }, // DINGBAT CIRCLED SANS-SERIF DIGIT EIGHT + { 0x2788, BIDI_ON }, // DINGBAT CIRCLED SANS-SERIF DIGIT NINE + { 0x2789, BIDI_ON }, // DINGBAT CIRCLED SANS-SERIF NUMBER TEN + { 0x278A, BIDI_ON }, // DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT ONE + { 0x278B, BIDI_ON }, // DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT TWO + { 0x278C, BIDI_ON }, // DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT THREE + { 0x278D, BIDI_ON }, // DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT FOUR + { 0x278E, BIDI_ON }, // DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT FIVE + { 0x278F, BIDI_ON }, // DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT SIX + { 0x2790, BIDI_ON }, // DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT SEVEN + { 0x2791, BIDI_ON }, // DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT EIGHT + { 0x2792, BIDI_ON }, // DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT NINE + { 0x2793, BIDI_ON }, // DINGBAT NEGATIVE CIRCLED SANS-SERIF NUMBER TEN + { 0x2794, BIDI_ON }, // HEAVY WIDE-HEADED RIGHTWARDS ARROW + { 0x2795, BIDI_ON }, // HEAVY PLUS SIGN + { 0x2796, BIDI_ON }, // HEAVY MINUS SIGN + { 0x2797, BIDI_ON }, // HEAVY DIVISION SIGN + { 0x2798, BIDI_ON }, // HEAVY SOUTH EAST ARROW + { 0x2799, BIDI_ON }, // HEAVY RIGHTWARDS ARROW + { 0x279A, BIDI_ON }, // HEAVY NORTH EAST ARROW + { 0x279B, BIDI_ON }, // DRAFTING POINT RIGHTWARDS ARROW + { 0x279C, BIDI_ON }, // HEAVY ROUND-TIPPED RIGHTWARDS ARROW + { 0x279D, BIDI_ON }, // TRIANGLE-HEADED RIGHTWARDS ARROW + { 0x279E, BIDI_ON }, // HEAVY TRIANGLE-HEADED RIGHTWARDS ARROW + { 0x279F, BIDI_ON }, // DASHED TRIANGLE-HEADED RIGHTWARDS ARROW + { 0x27A0, BIDI_ON }, // HEAVY DASHED TRIANGLE-HEADED RIGHTWARDS ARROW + { 0x27A1, BIDI_ON }, // BLACK RIGHTWARDS ARROW + { 0x27A2, BIDI_ON }, // THREE-D TOP-LIGHTED RIGHTWARDS ARROWHEAD + { 0x27A3, BIDI_ON }, // THREE-D BOTTOM-LIGHTED RIGHTWARDS ARROWHEAD + { 0x27A4, BIDI_ON }, // BLACK RIGHTWARDS ARROWHEAD + { 0x27A5, BIDI_ON }, // HEAVY BLACK CURVED DOWNWARDS AND RIGHTWARDS ARROW + { 0x27A6, BIDI_ON }, // HEAVY BLACK CURVED UPWARDS AND RIGHTWARDS ARROW + { 0x27A7, BIDI_ON }, // SQUAT BLACK RIGHTWARDS ARROW + { 0x27A8, BIDI_ON }, // HEAVY CONCAVE-POINTED BLACK RIGHTWARDS ARROW + { 0x27A9, BIDI_ON }, // RIGHT-SHADED WHITE RIGHTWARDS ARROW + { 0x27AA, BIDI_ON }, // LEFT-SHADED WHITE RIGHTWARDS ARROW + { 0x27AB, BIDI_ON }, // BACK-TILTED SHADOWED WHITE RIGHTWARDS ARROW + { 0x27AC, BIDI_ON }, // FRONT-TILTED SHADOWED WHITE RIGHTWARDS ARROW + { 0x27AD, BIDI_ON }, // HEAVY LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW + { 0x27AE, BIDI_ON }, // HEAVY UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW + { 0x27AF, BIDI_ON }, // NOTCHED LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW + { 0x27B0, BIDI_ON }, // CURLY LOOP + { 0x27B1, BIDI_ON }, // NOTCHED UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW + { 0x27B2, BIDI_ON }, // CIRCLED HEAVY WHITE RIGHTWARDS ARROW + { 0x27B3, BIDI_ON }, // WHITE-FEATHERED RIGHTWARDS ARROW + { 0x27B4, BIDI_ON }, // BLACK-FEATHERED SOUTH EAST ARROW + { 0x27B5, BIDI_ON }, // BLACK-FEATHERED RIGHTWARDS ARROW + { 0x27B6, BIDI_ON }, // BLACK-FEATHERED NORTH EAST ARROW + { 0x27B7, BIDI_ON }, // HEAVY BLACK-FEATHERED SOUTH EAST ARROW + { 0x27B8, BIDI_ON }, // HEAVY BLACK-FEATHERED RIGHTWARDS ARROW + { 0x27B9, BIDI_ON }, // HEAVY BLACK-FEATHERED NORTH EAST ARROW + { 0x27BA, BIDI_ON }, // TEARDROP-BARBED RIGHTWARDS ARROW + { 0x27BB, BIDI_ON }, // HEAVY TEARDROP-SHANKED RIGHTWARDS ARROW + { 0x27BC, BIDI_ON }, // WEDGE-TAILED RIGHTWARDS ARROW + { 0x27BD, BIDI_ON }, // HEAVY WEDGE-TAILED RIGHTWARDS ARROW + { 0x27BE, BIDI_ON }, // OPEN-OUTLINED RIGHTWARDS ARROW + { 0x27BF, BIDI_ON }, // DOUBLE CURLY LOOP + { 0x27C0, BIDI_ON }, // THREE DIMENSIONAL ANGLE + { 0x27C1, BIDI_ON }, // WHITE TRIANGLE CONTAINING SMALL WHITE TRIANGLE + { 0x27C2, BIDI_ON }, // PERPENDICULAR + { 0x27C3, BIDI_ON }, // OPEN SUBSET + { 0x27C4, BIDI_ON }, // OPEN SUPERSET + { 0x27C5, BIDI_ON }, // LEFT S-SHAPED BAG DELIMITER + { 0x27C6, BIDI_ON }, // RIGHT S-SHAPED BAG DELIMITER + { 0x27C7, BIDI_ON }, // OR WITH DOT INSIDE + { 0x27C8, BIDI_ON }, // REVERSE SOLIDUS PRECEDING SUBSET + { 0x27C9, BIDI_ON }, // SUPERSET PRECEDING SOLIDUS + { 0x27CA, BIDI_ON }, // VERTICAL BAR WITH HORIZONTAL STROKE + { 0x27CB, BIDI_ON }, // MATHEMATICAL RISING DIAGONAL + { 0x27CC, BIDI_ON }, // LONG DIVISION + { 0x27CD, BIDI_ON }, // MATHEMATICAL FALLING DIAGONAL + { 0x27CE, BIDI_ON }, // SQUARED LOGICAL AND + { 0x27CF, BIDI_ON }, // SQUARED LOGICAL OR + { 0x27D0, BIDI_ON }, // WHITE DIAMOND WITH CENTRED DOT + { 0x27D1, BIDI_ON }, // AND WITH DOT + { 0x27D2, BIDI_ON }, // ELEMENT OF OPENING UPWARDS + { 0x27D3, BIDI_ON }, // LOWER RIGHT CORNER WITH DOT + { 0x27D4, BIDI_ON }, // UPPER LEFT CORNER WITH DOT + { 0x27D5, BIDI_ON }, // LEFT OUTER JOIN + { 0x27D6, BIDI_ON }, // RIGHT OUTER JOIN + { 0x27D7, BIDI_ON }, // FULL OUTER JOIN + { 0x27D8, BIDI_ON }, // LARGE UP TACK + { 0x27D9, BIDI_ON }, // LARGE DOWN TACK + { 0x27DA, BIDI_ON }, // LEFT AND RIGHT DOUBLE TURNSTILE + { 0x27DB, BIDI_ON }, // LEFT AND RIGHT TACK + { 0x27DC, BIDI_ON }, // LEFT MULTIMAP + { 0x27DD, BIDI_ON }, // LONG RIGHT TACK + { 0x27DE, BIDI_ON }, // LONG LEFT TACK + { 0x27DF, BIDI_ON }, // UP TACK WITH CIRCLE ABOVE + { 0x27E0, BIDI_ON }, // LOZENGE DIVIDED BY HORIZONTAL RULE + { 0x27E1, BIDI_ON }, // WHITE CONCAVE-SIDED DIAMOND + { 0x27E2, BIDI_ON }, // WHITE CONCAVE-SIDED DIAMOND WITH LEFTWARDS TICK + { 0x27E3, BIDI_ON }, // WHITE CONCAVE-SIDED DIAMOND WITH RIGHTWARDS TICK + { 0x27E4, BIDI_ON }, // WHITE SQUARE WITH LEFTWARDS TICK + { 0x27E5, BIDI_ON }, // WHITE SQUARE WITH RIGHTWARDS TICK + { 0x27E6, BIDI_ON }, // MATHEMATICAL LEFT WHITE SQUARE BRACKET + { 0x27E7, BIDI_ON }, // MATHEMATICAL RIGHT WHITE SQUARE BRACKET + { 0x27E8, BIDI_ON }, // MATHEMATICAL LEFT ANGLE BRACKET + { 0x27E9, BIDI_ON }, // MATHEMATICAL RIGHT ANGLE BRACKET + { 0x27EA, BIDI_ON }, // MATHEMATICAL LEFT DOUBLE ANGLE BRACKET + { 0x27EB, BIDI_ON }, // MATHEMATICAL RIGHT DOUBLE ANGLE BRACKET + { 0x27EC, BIDI_ON }, // MATHEMATICAL LEFT WHITE TORTOISE SHELL BRACKET + { 0x27ED, BIDI_ON }, // MATHEMATICAL RIGHT WHITE TORTOISE SHELL BRACKET + { 0x27EE, BIDI_ON }, // MATHEMATICAL LEFT FLATTENED PARENTHESIS + { 0x27EF, BIDI_ON }, // MATHEMATICAL RIGHT FLATTENED PARENTHESIS + { 0x27F0, BIDI_ON }, // UPWARDS QUADRUPLE ARROW + { 0x27F1, BIDI_ON }, // DOWNWARDS QUADRUPLE ARROW + { 0x27F2, BIDI_ON }, // ANTICLOCKWISE GAPPED CIRCLE ARROW + { 0x27F3, BIDI_ON }, // CLOCKWISE GAPPED CIRCLE ARROW + { 0x27F4, BIDI_ON }, // RIGHT ARROW WITH CIRCLED PLUS + { 0x27F5, BIDI_ON }, // LONG LEFTWARDS ARROW + { 0x27F6, BIDI_ON }, // LONG RIGHTWARDS ARROW + { 0x27F7, BIDI_ON }, // LONG LEFT RIGHT ARROW + { 0x27F8, BIDI_ON }, // LONG LEFTWARDS DOUBLE ARROW + { 0x27F9, BIDI_ON }, // LONG RIGHTWARDS DOUBLE ARROW + { 0x27FA, BIDI_ON }, // LONG LEFT RIGHT DOUBLE ARROW + { 0x27FB, BIDI_ON }, // LONG LEFTWARDS ARROW FROM BAR + { 0x27FC, BIDI_ON }, // LONG RIGHTWARDS ARROW FROM BAR + { 0x27FD, BIDI_ON }, // LONG LEFTWARDS DOUBLE ARROW FROM BAR + { 0x27FE, BIDI_ON }, // LONG RIGHTWARDS DOUBLE ARROW FROM BAR + { 0x27FF, BIDI_ON }, // LONG RIGHTWARDS SQUIGGLE ARROW + { 0x2800, BIDI_L }, // BRAILLE PATTERN BLANK + { 0x2801, BIDI_L }, // BRAILLE PATTERN DOTS-1 + { 0x2802, BIDI_L }, // BRAILLE PATTERN DOTS-2 + { 0x2803, BIDI_L }, // BRAILLE PATTERN DOTS-12 + { 0x2804, BIDI_L }, // BRAILLE PATTERN DOTS-3 + { 0x2805, BIDI_L }, // BRAILLE PATTERN DOTS-13 + { 0x2806, BIDI_L }, // BRAILLE PATTERN DOTS-23 + { 0x2807, BIDI_L }, // BRAILLE PATTERN DOTS-123 + { 0x2808, BIDI_L }, // BRAILLE PATTERN DOTS-4 + { 0x2809, BIDI_L }, // BRAILLE PATTERN DOTS-14 + { 0x280A, BIDI_L }, // BRAILLE PATTERN DOTS-24 + { 0x280B, BIDI_L }, // BRAILLE PATTERN DOTS-124 + { 0x280C, BIDI_L }, // BRAILLE PATTERN DOTS-34 + { 0x280D, BIDI_L }, // BRAILLE PATTERN DOTS-134 + { 0x280E, BIDI_L }, // BRAILLE PATTERN DOTS-234 + { 0x280F, BIDI_L }, // BRAILLE PATTERN DOTS-1234 + { 0x2810, BIDI_L }, // BRAILLE PATTERN DOTS-5 + { 0x2811, BIDI_L }, // BRAILLE PATTERN DOTS-15 + { 0x2812, BIDI_L }, // BRAILLE PATTERN DOTS-25 + { 0x2813, BIDI_L }, // BRAILLE PATTERN DOTS-125 + { 0x2814, BIDI_L }, // BRAILLE PATTERN DOTS-35 + { 0x2815, BIDI_L }, // BRAILLE PATTERN DOTS-135 + { 0x2816, BIDI_L }, // BRAILLE PATTERN DOTS-235 + { 0x2817, BIDI_L }, // BRAILLE PATTERN DOTS-1235 + { 0x2818, BIDI_L }, // BRAILLE PATTERN DOTS-45 + { 0x2819, BIDI_L }, // BRAILLE PATTERN DOTS-145 + { 0x281A, BIDI_L }, // BRAILLE PATTERN DOTS-245 + { 0x281B, BIDI_L }, // BRAILLE PATTERN DOTS-1245 + { 0x281C, BIDI_L }, // BRAILLE PATTERN DOTS-345 + { 0x281D, BIDI_L }, // BRAILLE PATTERN DOTS-1345 + { 0x281E, BIDI_L }, // BRAILLE PATTERN DOTS-2345 + { 0x281F, BIDI_L }, // BRAILLE PATTERN DOTS-12345 + { 0x2820, BIDI_L }, // BRAILLE PATTERN DOTS-6 + { 0x2821, BIDI_L }, // BRAILLE PATTERN DOTS-16 + { 0x2822, BIDI_L }, // BRAILLE PATTERN DOTS-26 + { 0x2823, BIDI_L }, // BRAILLE PATTERN DOTS-126 + { 0x2824, BIDI_L }, // BRAILLE PATTERN DOTS-36 + { 0x2825, BIDI_L }, // BRAILLE PATTERN DOTS-136 + { 0x2826, BIDI_L }, // BRAILLE PATTERN DOTS-236 + { 0x2827, BIDI_L }, // BRAILLE PATTERN DOTS-1236 + { 0x2828, BIDI_L }, // BRAILLE PATTERN DOTS-46 + { 0x2829, BIDI_L }, // BRAILLE PATTERN DOTS-146 + { 0x282A, BIDI_L }, // BRAILLE PATTERN DOTS-246 + { 0x282B, BIDI_L }, // BRAILLE PATTERN DOTS-1246 + { 0x282C, BIDI_L }, // BRAILLE PATTERN DOTS-346 + { 0x282D, BIDI_L }, // BRAILLE PATTERN DOTS-1346 + { 0x282E, BIDI_L }, // BRAILLE PATTERN DOTS-2346 + { 0x282F, BIDI_L }, // BRAILLE PATTERN DOTS-12346 + { 0x2830, BIDI_L }, // BRAILLE PATTERN DOTS-56 + { 0x2831, BIDI_L }, // BRAILLE PATTERN DOTS-156 + { 0x2832, BIDI_L }, // BRAILLE PATTERN DOTS-256 + { 0x2833, BIDI_L }, // BRAILLE PATTERN DOTS-1256 + { 0x2834, BIDI_L }, // BRAILLE PATTERN DOTS-356 + { 0x2835, BIDI_L }, // BRAILLE PATTERN DOTS-1356 + { 0x2836, BIDI_L }, // BRAILLE PATTERN DOTS-2356 + { 0x2837, BIDI_L }, // BRAILLE PATTERN DOTS-12356 + { 0x2838, BIDI_L }, // BRAILLE PATTERN DOTS-456 + { 0x2839, BIDI_L }, // BRAILLE PATTERN DOTS-1456 + { 0x283A, BIDI_L }, // BRAILLE PATTERN DOTS-2456 + { 0x283B, BIDI_L }, // BRAILLE PATTERN DOTS-12456 + { 0x283C, BIDI_L }, // BRAILLE PATTERN DOTS-3456 + { 0x283D, BIDI_L }, // BRAILLE PATTERN DOTS-13456 + { 0x283E, BIDI_L }, // BRAILLE PATTERN DOTS-23456 + { 0x283F, BIDI_L }, // BRAILLE PATTERN DOTS-123456 + { 0x2840, BIDI_L }, // BRAILLE PATTERN DOTS-7 + { 0x2841, BIDI_L }, // BRAILLE PATTERN DOTS-17 + { 0x2842, BIDI_L }, // BRAILLE PATTERN DOTS-27 + { 0x2843, BIDI_L }, // BRAILLE PATTERN DOTS-127 + { 0x2844, BIDI_L }, // BRAILLE PATTERN DOTS-37 + { 0x2845, BIDI_L }, // BRAILLE PATTERN DOTS-137 + { 0x2846, BIDI_L }, // BRAILLE PATTERN DOTS-237 + { 0x2847, BIDI_L }, // BRAILLE PATTERN DOTS-1237 + { 0x2848, BIDI_L }, // BRAILLE PATTERN DOTS-47 + { 0x2849, BIDI_L }, // BRAILLE PATTERN DOTS-147 + { 0x284A, BIDI_L }, // BRAILLE PATTERN DOTS-247 + { 0x284B, BIDI_L }, // BRAILLE PATTERN DOTS-1247 + { 0x284C, BIDI_L }, // BRAILLE PATTERN DOTS-347 + { 0x284D, BIDI_L }, // BRAILLE PATTERN DOTS-1347 + { 0x284E, BIDI_L }, // BRAILLE PATTERN DOTS-2347 + { 0x284F, BIDI_L }, // BRAILLE PATTERN DOTS-12347 + { 0x2850, BIDI_L }, // BRAILLE PATTERN DOTS-57 + { 0x2851, BIDI_L }, // BRAILLE PATTERN DOTS-157 + { 0x2852, BIDI_L }, // BRAILLE PATTERN DOTS-257 + { 0x2853, BIDI_L }, // BRAILLE PATTERN DOTS-1257 + { 0x2854, BIDI_L }, // BRAILLE PATTERN DOTS-357 + { 0x2855, BIDI_L }, // BRAILLE PATTERN DOTS-1357 + { 0x2856, BIDI_L }, // BRAILLE PATTERN DOTS-2357 + { 0x2857, BIDI_L }, // BRAILLE PATTERN DOTS-12357 + { 0x2858, BIDI_L }, // BRAILLE PATTERN DOTS-457 + { 0x2859, BIDI_L }, // BRAILLE PATTERN DOTS-1457 + { 0x285A, BIDI_L }, // BRAILLE PATTERN DOTS-2457 + { 0x285B, BIDI_L }, // BRAILLE PATTERN DOTS-12457 + { 0x285C, BIDI_L }, // BRAILLE PATTERN DOTS-3457 + { 0x285D, BIDI_L }, // BRAILLE PATTERN DOTS-13457 + { 0x285E, BIDI_L }, // BRAILLE PATTERN DOTS-23457 + { 0x285F, BIDI_L }, // BRAILLE PATTERN DOTS-123457 + { 0x2860, BIDI_L }, // BRAILLE PATTERN DOTS-67 + { 0x2861, BIDI_L }, // BRAILLE PATTERN DOTS-167 + { 0x2862, BIDI_L }, // BRAILLE PATTERN DOTS-267 + { 0x2863, BIDI_L }, // BRAILLE PATTERN DOTS-1267 + { 0x2864, BIDI_L }, // BRAILLE PATTERN DOTS-367 + { 0x2865, BIDI_L }, // BRAILLE PATTERN DOTS-1367 + { 0x2866, BIDI_L }, // BRAILLE PATTERN DOTS-2367 + { 0x2867, BIDI_L }, // BRAILLE PATTERN DOTS-12367 + { 0x2868, BIDI_L }, // BRAILLE PATTERN DOTS-467 + { 0x2869, BIDI_L }, // BRAILLE PATTERN DOTS-1467 + { 0x286A, BIDI_L }, // BRAILLE PATTERN DOTS-2467 + { 0x286B, BIDI_L }, // BRAILLE PATTERN DOTS-12467 + { 0x286C, BIDI_L }, // BRAILLE PATTERN DOTS-3467 + { 0x286D, BIDI_L }, // BRAILLE PATTERN DOTS-13467 + { 0x286E, BIDI_L }, // BRAILLE PATTERN DOTS-23467 + { 0x286F, BIDI_L }, // BRAILLE PATTERN DOTS-123467 + { 0x2870, BIDI_L }, // BRAILLE PATTERN DOTS-567 + { 0x2871, BIDI_L }, // BRAILLE PATTERN DOTS-1567 + { 0x2872, BIDI_L }, // BRAILLE PATTERN DOTS-2567 + { 0x2873, BIDI_L }, // BRAILLE PATTERN DOTS-12567 + { 0x2874, BIDI_L }, // BRAILLE PATTERN DOTS-3567 + { 0x2875, BIDI_L }, // BRAILLE PATTERN DOTS-13567 + { 0x2876, BIDI_L }, // BRAILLE PATTERN DOTS-23567 + { 0x2877, BIDI_L }, // BRAILLE PATTERN DOTS-123567 + { 0x2878, BIDI_L }, // BRAILLE PATTERN DOTS-4567 + { 0x2879, BIDI_L }, // BRAILLE PATTERN DOTS-14567 + { 0x287A, BIDI_L }, // BRAILLE PATTERN DOTS-24567 + { 0x287B, BIDI_L }, // BRAILLE PATTERN DOTS-124567 + { 0x287C, BIDI_L }, // BRAILLE PATTERN DOTS-34567 + { 0x287D, BIDI_L }, // BRAILLE PATTERN DOTS-134567 + { 0x287E, BIDI_L }, // BRAILLE PATTERN DOTS-234567 + { 0x287F, BIDI_L }, // BRAILLE PATTERN DOTS-1234567 + { 0x2880, BIDI_L }, // BRAILLE PATTERN DOTS-8 + { 0x2881, BIDI_L }, // BRAILLE PATTERN DOTS-18 + { 0x2882, BIDI_L }, // BRAILLE PATTERN DOTS-28 + { 0x2883, BIDI_L }, // BRAILLE PATTERN DOTS-128 + { 0x2884, BIDI_L }, // BRAILLE PATTERN DOTS-38 + { 0x2885, BIDI_L }, // BRAILLE PATTERN DOTS-138 + { 0x2886, BIDI_L }, // BRAILLE PATTERN DOTS-238 + { 0x2887, BIDI_L }, // BRAILLE PATTERN DOTS-1238 + { 0x2888, BIDI_L }, // BRAILLE PATTERN DOTS-48 + { 0x2889, BIDI_L }, // BRAILLE PATTERN DOTS-148 + { 0x288A, BIDI_L }, // BRAILLE PATTERN DOTS-248 + { 0x288B, BIDI_L }, // BRAILLE PATTERN DOTS-1248 + { 0x288C, BIDI_L }, // BRAILLE PATTERN DOTS-348 + { 0x288D, BIDI_L }, // BRAILLE PATTERN DOTS-1348 + { 0x288E, BIDI_L }, // BRAILLE PATTERN DOTS-2348 + { 0x288F, BIDI_L }, // BRAILLE PATTERN DOTS-12348 + { 0x2890, BIDI_L }, // BRAILLE PATTERN DOTS-58 + { 0x2891, BIDI_L }, // BRAILLE PATTERN DOTS-158 + { 0x2892, BIDI_L }, // BRAILLE PATTERN DOTS-258 + { 0x2893, BIDI_L }, // BRAILLE PATTERN DOTS-1258 + { 0x2894, BIDI_L }, // BRAILLE PATTERN DOTS-358 + { 0x2895, BIDI_L }, // BRAILLE PATTERN DOTS-1358 + { 0x2896, BIDI_L }, // BRAILLE PATTERN DOTS-2358 + { 0x2897, BIDI_L }, // BRAILLE PATTERN DOTS-12358 + { 0x2898, BIDI_L }, // BRAILLE PATTERN DOTS-458 + { 0x2899, BIDI_L }, // BRAILLE PATTERN DOTS-1458 + { 0x289A, BIDI_L }, // BRAILLE PATTERN DOTS-2458 + { 0x289B, BIDI_L }, // BRAILLE PATTERN DOTS-12458 + { 0x289C, BIDI_L }, // BRAILLE PATTERN DOTS-3458 + { 0x289D, BIDI_L }, // BRAILLE PATTERN DOTS-13458 + { 0x289E, BIDI_L }, // BRAILLE PATTERN DOTS-23458 + { 0x289F, BIDI_L }, // BRAILLE PATTERN DOTS-123458 + { 0x28A0, BIDI_L }, // BRAILLE PATTERN DOTS-68 + { 0x28A1, BIDI_L }, // BRAILLE PATTERN DOTS-168 + { 0x28A2, BIDI_L }, // BRAILLE PATTERN DOTS-268 + { 0x28A3, BIDI_L }, // BRAILLE PATTERN DOTS-1268 + { 0x28A4, BIDI_L }, // BRAILLE PATTERN DOTS-368 + { 0x28A5, BIDI_L }, // BRAILLE PATTERN DOTS-1368 + { 0x28A6, BIDI_L }, // BRAILLE PATTERN DOTS-2368 + { 0x28A7, BIDI_L }, // BRAILLE PATTERN DOTS-12368 + { 0x28A8, BIDI_L }, // BRAILLE PATTERN DOTS-468 + { 0x28A9, BIDI_L }, // BRAILLE PATTERN DOTS-1468 + { 0x28AA, BIDI_L }, // BRAILLE PATTERN DOTS-2468 + { 0x28AB, BIDI_L }, // BRAILLE PATTERN DOTS-12468 + { 0x28AC, BIDI_L }, // BRAILLE PATTERN DOTS-3468 + { 0x28AD, BIDI_L }, // BRAILLE PATTERN DOTS-13468 + { 0x28AE, BIDI_L }, // BRAILLE PATTERN DOTS-23468 + { 0x28AF, BIDI_L }, // BRAILLE PATTERN DOTS-123468 + { 0x28B0, BIDI_L }, // BRAILLE PATTERN DOTS-568 + { 0x28B1, BIDI_L }, // BRAILLE PATTERN DOTS-1568 + { 0x28B2, BIDI_L }, // BRAILLE PATTERN DOTS-2568 + { 0x28B3, BIDI_L }, // BRAILLE PATTERN DOTS-12568 + { 0x28B4, BIDI_L }, // BRAILLE PATTERN DOTS-3568 + { 0x28B5, BIDI_L }, // BRAILLE PATTERN DOTS-13568 + { 0x28B6, BIDI_L }, // BRAILLE PATTERN DOTS-23568 + { 0x28B7, BIDI_L }, // BRAILLE PATTERN DOTS-123568 + { 0x28B8, BIDI_L }, // BRAILLE PATTERN DOTS-4568 + { 0x28B9, BIDI_L }, // BRAILLE PATTERN DOTS-14568 + { 0x28BA, BIDI_L }, // BRAILLE PATTERN DOTS-24568 + { 0x28BB, BIDI_L }, // BRAILLE PATTERN DOTS-124568 + { 0x28BC, BIDI_L }, // BRAILLE PATTERN DOTS-34568 + { 0x28BD, BIDI_L }, // BRAILLE PATTERN DOTS-134568 + { 0x28BE, BIDI_L }, // BRAILLE PATTERN DOTS-234568 + { 0x28BF, BIDI_L }, // BRAILLE PATTERN DOTS-1234568 + { 0x28C0, BIDI_L }, // BRAILLE PATTERN DOTS-78 + { 0x28C1, BIDI_L }, // BRAILLE PATTERN DOTS-178 + { 0x28C2, BIDI_L }, // BRAILLE PATTERN DOTS-278 + { 0x28C3, BIDI_L }, // BRAILLE PATTERN DOTS-1278 + { 0x28C4, BIDI_L }, // BRAILLE PATTERN DOTS-378 + { 0x28C5, BIDI_L }, // BRAILLE PATTERN DOTS-1378 + { 0x28C6, BIDI_L }, // BRAILLE PATTERN DOTS-2378 + { 0x28C7, BIDI_L }, // BRAILLE PATTERN DOTS-12378 + { 0x28C8, BIDI_L }, // BRAILLE PATTERN DOTS-478 + { 0x28C9, BIDI_L }, // BRAILLE PATTERN DOTS-1478 + { 0x28CA, BIDI_L }, // BRAILLE PATTERN DOTS-2478 + { 0x28CB, BIDI_L }, // BRAILLE PATTERN DOTS-12478 + { 0x28CC, BIDI_L }, // BRAILLE PATTERN DOTS-3478 + { 0x28CD, BIDI_L }, // BRAILLE PATTERN DOTS-13478 + { 0x28CE, BIDI_L }, // BRAILLE PATTERN DOTS-23478 + { 0x28CF, BIDI_L }, // BRAILLE PATTERN DOTS-123478 + { 0x28D0, BIDI_L }, // BRAILLE PATTERN DOTS-578 + { 0x28D1, BIDI_L }, // BRAILLE PATTERN DOTS-1578 + { 0x28D2, BIDI_L }, // BRAILLE PATTERN DOTS-2578 + { 0x28D3, BIDI_L }, // BRAILLE PATTERN DOTS-12578 + { 0x28D4, BIDI_L }, // BRAILLE PATTERN DOTS-3578 + { 0x28D5, BIDI_L }, // BRAILLE PATTERN DOTS-13578 + { 0x28D6, BIDI_L }, // BRAILLE PATTERN DOTS-23578 + { 0x28D7, BIDI_L }, // BRAILLE PATTERN DOTS-123578 + { 0x28D8, BIDI_L }, // BRAILLE PATTERN DOTS-4578 + { 0x28D9, BIDI_L }, // BRAILLE PATTERN DOTS-14578 + { 0x28DA, BIDI_L }, // BRAILLE PATTERN DOTS-24578 + { 0x28DB, BIDI_L }, // BRAILLE PATTERN DOTS-124578 + { 0x28DC, BIDI_L }, // BRAILLE PATTERN DOTS-34578 + { 0x28DD, BIDI_L }, // BRAILLE PATTERN DOTS-134578 + { 0x28DE, BIDI_L }, // BRAILLE PATTERN DOTS-234578 + { 0x28DF, BIDI_L }, // BRAILLE PATTERN DOTS-1234578 + { 0x28E0, BIDI_L }, // BRAILLE PATTERN DOTS-678 + { 0x28E1, BIDI_L }, // BRAILLE PATTERN DOTS-1678 + { 0x28E2, BIDI_L }, // BRAILLE PATTERN DOTS-2678 + { 0x28E3, BIDI_L }, // BRAILLE PATTERN DOTS-12678 + { 0x28E4, BIDI_L }, // BRAILLE PATTERN DOTS-3678 + { 0x28E5, BIDI_L }, // BRAILLE PATTERN DOTS-13678 + { 0x28E6, BIDI_L }, // BRAILLE PATTERN DOTS-23678 + { 0x28E7, BIDI_L }, // BRAILLE PATTERN DOTS-123678 + { 0x28E8, BIDI_L }, // BRAILLE PATTERN DOTS-4678 + { 0x28E9, BIDI_L }, // BRAILLE PATTERN DOTS-14678 + { 0x28EA, BIDI_L }, // BRAILLE PATTERN DOTS-24678 + { 0x28EB, BIDI_L }, // BRAILLE PATTERN DOTS-124678 + { 0x28EC, BIDI_L }, // BRAILLE PATTERN DOTS-34678 + { 0x28ED, BIDI_L }, // BRAILLE PATTERN DOTS-134678 + { 0x28EE, BIDI_L }, // BRAILLE PATTERN DOTS-234678 + { 0x28EF, BIDI_L }, // BRAILLE PATTERN DOTS-1234678 + { 0x28F0, BIDI_L }, // BRAILLE PATTERN DOTS-5678 + { 0x28F1, BIDI_L }, // BRAILLE PATTERN DOTS-15678 + { 0x28F2, BIDI_L }, // BRAILLE PATTERN DOTS-25678 + { 0x28F3, BIDI_L }, // BRAILLE PATTERN DOTS-125678 + { 0x28F4, BIDI_L }, // BRAILLE PATTERN DOTS-35678 + { 0x28F5, BIDI_L }, // BRAILLE PATTERN DOTS-135678 + { 0x28F6, BIDI_L }, // BRAILLE PATTERN DOTS-235678 + { 0x28F7, BIDI_L }, // BRAILLE PATTERN DOTS-1235678 + { 0x28F8, BIDI_L }, // BRAILLE PATTERN DOTS-45678 + { 0x28F9, BIDI_L }, // BRAILLE PATTERN DOTS-145678 + { 0x28FA, BIDI_L }, // BRAILLE PATTERN DOTS-245678 + { 0x28FB, BIDI_L }, // BRAILLE PATTERN DOTS-1245678 + { 0x28FC, BIDI_L }, // BRAILLE PATTERN DOTS-345678 + { 0x28FD, BIDI_L }, // BRAILLE PATTERN DOTS-1345678 + { 0x28FE, BIDI_L }, // BRAILLE PATTERN DOTS-2345678 + { 0x28FF, BIDI_L }, // BRAILLE PATTERN DOTS-12345678 + { 0x2900, BIDI_ON }, // RIGHTWARDS TWO-HEADED ARROW WITH VERTICAL STROKE + { 0x2901, BIDI_ON }, // RIGHTWARDS TWO-HEADED ARROW WITH DOUBLE VERTICAL STROKE + { 0x2902, BIDI_ON }, // LEFTWARDS DOUBLE ARROW WITH VERTICAL STROKE + { 0x2903, BIDI_ON }, // RIGHTWARDS DOUBLE ARROW WITH VERTICAL STROKE + { 0x2904, BIDI_ON }, // LEFT RIGHT DOUBLE ARROW WITH VERTICAL STROKE + { 0x2905, BIDI_ON }, // RIGHTWARDS TWO-HEADED ARROW FROM BAR + { 0x2906, BIDI_ON }, // LEFTWARDS DOUBLE ARROW FROM BAR + { 0x2907, BIDI_ON }, // RIGHTWARDS DOUBLE ARROW FROM BAR + { 0x2908, BIDI_ON }, // DOWNWARDS ARROW WITH HORIZONTAL STROKE + { 0x2909, BIDI_ON }, // UPWARDS ARROW WITH HORIZONTAL STROKE + { 0x290A, BIDI_ON }, // UPWARDS TRIPLE ARROW + { 0x290B, BIDI_ON }, // DOWNWARDS TRIPLE ARROW + { 0x290C, BIDI_ON }, // LEFTWARDS DOUBLE DASH ARROW + { 0x290D, BIDI_ON }, // RIGHTWARDS DOUBLE DASH ARROW + { 0x290E, BIDI_ON }, // LEFTWARDS TRIPLE DASH ARROW + { 0x290F, BIDI_ON }, // RIGHTWARDS TRIPLE DASH ARROW + { 0x2910, BIDI_ON }, // RIGHTWARDS TWO-HEADED TRIPLE DASH ARROW + { 0x2911, BIDI_ON }, // RIGHTWARDS ARROW WITH DOTTED STEM + { 0x2912, BIDI_ON }, // UPWARDS ARROW TO BAR + { 0x2913, BIDI_ON }, // DOWNWARDS ARROW TO BAR + { 0x2914, BIDI_ON }, // RIGHTWARDS ARROW WITH TAIL WITH VERTICAL STROKE + { 0x2915, BIDI_ON }, // RIGHTWARDS ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE + { 0x2916, BIDI_ON }, // RIGHTWARDS TWO-HEADED ARROW WITH TAIL + { 0x2917, BIDI_ON }, // RIGHTWARDS TWO-HEADED ARROW WITH TAIL WITH VERTICAL STROKE + { 0x2918, BIDI_ON }, // RIGHTWARDS TWO-HEADED ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE + { 0x2919, BIDI_ON }, // LEFTWARDS ARROW-TAIL + { 0x291A, BIDI_ON }, // RIGHTWARDS ARROW-TAIL + { 0x291B, BIDI_ON }, // LEFTWARDS DOUBLE ARROW-TAIL + { 0x291C, BIDI_ON }, // RIGHTWARDS DOUBLE ARROW-TAIL + { 0x291D, BIDI_ON }, // LEFTWARDS ARROW TO BLACK DIAMOND + { 0x291E, BIDI_ON }, // RIGHTWARDS ARROW TO BLACK DIAMOND + { 0x291F, BIDI_ON }, // LEFTWARDS ARROW FROM BAR TO BLACK DIAMOND + { 0x2920, BIDI_ON }, // RIGHTWARDS ARROW FROM BAR TO BLACK DIAMOND + { 0x2921, BIDI_ON }, // NORTH WEST AND SOUTH EAST ARROW + { 0x2922, BIDI_ON }, // NORTH EAST AND SOUTH WEST ARROW + { 0x2923, BIDI_ON }, // NORTH WEST ARROW WITH HOOK + { 0x2924, BIDI_ON }, // NORTH EAST ARROW WITH HOOK + { 0x2925, BIDI_ON }, // SOUTH EAST ARROW WITH HOOK + { 0x2926, BIDI_ON }, // SOUTH WEST ARROW WITH HOOK + { 0x2927, BIDI_ON }, // NORTH WEST ARROW AND NORTH EAST ARROW + { 0x2928, BIDI_ON }, // NORTH EAST ARROW AND SOUTH EAST ARROW + { 0x2929, BIDI_ON }, // SOUTH EAST ARROW AND SOUTH WEST ARROW + { 0x292A, BIDI_ON }, // SOUTH WEST ARROW AND NORTH WEST ARROW + { 0x292B, BIDI_ON }, // RISING DIAGONAL CROSSING FALLING DIAGONAL + { 0x292C, BIDI_ON }, // FALLING DIAGONAL CROSSING RISING DIAGONAL + { 0x292D, BIDI_ON }, // SOUTH EAST ARROW CROSSING NORTH EAST ARROW + { 0x292E, BIDI_ON }, // NORTH EAST ARROW CROSSING SOUTH EAST ARROW + { 0x292F, BIDI_ON }, // FALLING DIAGONAL CROSSING NORTH EAST ARROW + { 0x2930, BIDI_ON }, // RISING DIAGONAL CROSSING SOUTH EAST ARROW + { 0x2931, BIDI_ON }, // NORTH EAST ARROW CROSSING NORTH WEST ARROW + { 0x2932, BIDI_ON }, // NORTH WEST ARROW CROSSING NORTH EAST ARROW + { 0x2933, BIDI_ON }, // WAVE ARROW POINTING DIRECTLY RIGHT + { 0x2934, BIDI_ON }, // ARROW POINTING RIGHTWARDS THEN CURVING UPWARDS + { 0x2935, BIDI_ON }, // ARROW POINTING RIGHTWARDS THEN CURVING DOWNWARDS + { 0x2936, BIDI_ON }, // ARROW POINTING DOWNWARDS THEN CURVING LEFTWARDS + { 0x2937, BIDI_ON }, // ARROW POINTING DOWNWARDS THEN CURVING RIGHTWARDS + { 0x2938, BIDI_ON }, // RIGHT-SIDE ARC CLOCKWISE ARROW + { 0x2939, BIDI_ON }, // LEFT-SIDE ARC ANTICLOCKWISE ARROW + { 0x293A, BIDI_ON }, // TOP ARC ANTICLOCKWISE ARROW + { 0x293B, BIDI_ON }, // BOTTOM ARC ANTICLOCKWISE ARROW + { 0x293C, BIDI_ON }, // TOP ARC CLOCKWISE ARROW WITH MINUS + { 0x293D, BIDI_ON }, // TOP ARC ANTICLOCKWISE ARROW WITH PLUS + { 0x293E, BIDI_ON }, // LOWER RIGHT SEMICIRCULAR CLOCKWISE ARROW + { 0x293F, BIDI_ON }, // LOWER LEFT SEMICIRCULAR ANTICLOCKWISE ARROW + { 0x2940, BIDI_ON }, // ANTICLOCKWISE CLOSED CIRCLE ARROW + { 0x2941, BIDI_ON }, // CLOCKWISE CLOSED CIRCLE ARROW + { 0x2942, BIDI_ON }, // RIGHTWARDS ARROW ABOVE SHORT LEFTWARDS ARROW + { 0x2943, BIDI_ON }, // LEFTWARDS ARROW ABOVE SHORT RIGHTWARDS ARROW + { 0x2944, BIDI_ON }, // SHORT RIGHTWARDS ARROW ABOVE LEFTWARDS ARROW + { 0x2945, BIDI_ON }, // RIGHTWARDS ARROW WITH PLUS BELOW + { 0x2946, BIDI_ON }, // LEFTWARDS ARROW WITH PLUS BELOW + { 0x2947, BIDI_ON }, // RIGHTWARDS ARROW THROUGH X + { 0x2948, BIDI_ON }, // LEFT RIGHT ARROW THROUGH SMALL CIRCLE + { 0x2949, BIDI_ON }, // UPWARDS TWO-HEADED ARROW FROM SMALL CIRCLE + { 0x294A, BIDI_ON }, // LEFT BARB UP RIGHT BARB DOWN HARPOON + { 0x294B, BIDI_ON }, // LEFT BARB DOWN RIGHT BARB UP HARPOON + { 0x294C, BIDI_ON }, // UP BARB RIGHT DOWN BARB LEFT HARPOON + { 0x294D, BIDI_ON }, // UP BARB LEFT DOWN BARB RIGHT HARPOON + { 0x294E, BIDI_ON }, // LEFT BARB UP RIGHT BARB UP HARPOON + { 0x294F, BIDI_ON }, // UP BARB RIGHT DOWN BARB RIGHT HARPOON + { 0x2950, BIDI_ON }, // LEFT BARB DOWN RIGHT BARB DOWN HARPOON + { 0x2951, BIDI_ON }, // UP BARB LEFT DOWN BARB LEFT HARPOON + { 0x2952, BIDI_ON }, // LEFTWARDS HARPOON WITH BARB UP TO BAR + { 0x2953, BIDI_ON }, // RIGHTWARDS HARPOON WITH BARB UP TO BAR + { 0x2954, BIDI_ON }, // UPWARDS HARPOON WITH BARB RIGHT TO BAR + { 0x2955, BIDI_ON }, // DOWNWARDS HARPOON WITH BARB RIGHT TO BAR + { 0x2956, BIDI_ON }, // LEFTWARDS HARPOON WITH BARB DOWN TO BAR + { 0x2957, BIDI_ON }, // RIGHTWARDS HARPOON WITH BARB DOWN TO BAR + { 0x2958, BIDI_ON }, // UPWARDS HARPOON WITH BARB LEFT TO BAR + { 0x2959, BIDI_ON }, // DOWNWARDS HARPOON WITH BARB LEFT TO BAR + { 0x295A, BIDI_ON }, // LEFTWARDS HARPOON WITH BARB UP FROM BAR + { 0x295B, BIDI_ON }, // RIGHTWARDS HARPOON WITH BARB UP FROM BAR + { 0x295C, BIDI_ON }, // UPWARDS HARPOON WITH BARB RIGHT FROM BAR + { 0x295D, BIDI_ON }, // DOWNWARDS HARPOON WITH BARB RIGHT FROM BAR + { 0x295E, BIDI_ON }, // LEFTWARDS HARPOON WITH BARB DOWN FROM BAR + { 0x295F, BIDI_ON }, // RIGHTWARDS HARPOON WITH BARB DOWN FROM BAR + { 0x2960, BIDI_ON }, // UPWARDS HARPOON WITH BARB LEFT FROM BAR + { 0x2961, BIDI_ON }, // DOWNWARDS HARPOON WITH BARB LEFT FROM BAR + { 0x2962, BIDI_ON }, // LEFTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB DOWN + { 0x2963, BIDI_ON }, // UPWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT + { 0x2964, BIDI_ON }, // RIGHTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB DOWN + { 0x2965, BIDI_ON }, // DOWNWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT + { 0x2966, BIDI_ON }, // LEFTWARDS HARPOON WITH BARB UP ABOVE RIGHTWARDS HARPOON WITH BARB UP + { 0x2967, BIDI_ON }, // LEFTWARDS HARPOON WITH BARB DOWN ABOVE RIGHTWARDS HARPOON WITH BARB DOWN + { 0x2968, BIDI_ON }, // RIGHTWARDS HARPOON WITH BARB UP ABOVE LEFTWARDS HARPOON WITH BARB UP + { 0x2969, BIDI_ON }, // RIGHTWARDS HARPOON WITH BARB DOWN ABOVE LEFTWARDS HARPOON WITH BARB DOWN + { 0x296A, BIDI_ON }, // LEFTWARDS HARPOON WITH BARB UP ABOVE LONG DASH + { 0x296B, BIDI_ON }, // LEFTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH + { 0x296C, BIDI_ON }, // RIGHTWARDS HARPOON WITH BARB UP ABOVE LONG DASH + { 0x296D, BIDI_ON }, // RIGHTWARDS HARPOON WITH BARB DOWN BELOW LONG DASH + { 0x296E, BIDI_ON }, // UPWARDS HARPOON WITH BARB LEFT BESIDE DOWNWARDS HARPOON WITH BARB RIGHT + { 0x296F, BIDI_ON }, // DOWNWARDS HARPOON WITH BARB LEFT BESIDE UPWARDS HARPOON WITH BARB RIGHT + { 0x2970, BIDI_ON }, // RIGHT DOUBLE ARROW WITH ROUNDED HEAD + { 0x2971, BIDI_ON }, // EQUALS SIGN ABOVE RIGHTWARDS ARROW + { 0x2972, BIDI_ON }, // TILDE OPERATOR ABOVE RIGHTWARDS ARROW + { 0x2973, BIDI_ON }, // LEFTWARDS ARROW ABOVE TILDE OPERATOR + { 0x2974, BIDI_ON }, // RIGHTWARDS ARROW ABOVE TILDE OPERATOR + { 0x2975, BIDI_ON }, // RIGHTWARDS ARROW ABOVE ALMOST EQUAL TO + { 0x2976, BIDI_ON }, // LESS-THAN ABOVE LEFTWARDS ARROW + { 0x2977, BIDI_ON }, // LEFTWARDS ARROW THROUGH LESS-THAN + { 0x2978, BIDI_ON }, // GREATER-THAN ABOVE RIGHTWARDS ARROW + { 0x2979, BIDI_ON }, // SUBSET ABOVE RIGHTWARDS ARROW + { 0x297A, BIDI_ON }, // LEFTWARDS ARROW THROUGH SUBSET + { 0x297B, BIDI_ON }, // SUPERSET ABOVE LEFTWARDS ARROW + { 0x297C, BIDI_ON }, // LEFT FISH TAIL + { 0x297D, BIDI_ON }, // RIGHT FISH TAIL + { 0x297E, BIDI_ON }, // UP FISH TAIL + { 0x297F, BIDI_ON }, // DOWN FISH TAIL + { 0x2980, BIDI_ON }, // TRIPLE VERTICAL BAR DELIMITER + { 0x2981, BIDI_ON }, // Z NOTATION SPOT + { 0x2982, BIDI_ON }, // Z NOTATION TYPE COLON + { 0x2983, BIDI_ON }, // LEFT WHITE CURLY BRACKET + { 0x2984, BIDI_ON }, // RIGHT WHITE CURLY BRACKET + { 0x2985, BIDI_ON }, // LEFT WHITE PARENTHESIS + { 0x2986, BIDI_ON }, // RIGHT WHITE PARENTHESIS + { 0x2987, BIDI_ON }, // Z NOTATION LEFT IMAGE BRACKET + { 0x2988, BIDI_ON }, // Z NOTATION RIGHT IMAGE BRACKET + { 0x2989, BIDI_ON }, // Z NOTATION LEFT BINDING BRACKET + { 0x298A, BIDI_ON }, // Z NOTATION RIGHT BINDING BRACKET + { 0x298B, BIDI_ON }, // LEFT SQUARE BRACKET WITH UNDERBAR + { 0x298C, BIDI_ON }, // RIGHT SQUARE BRACKET WITH UNDERBAR + { 0x298D, BIDI_ON }, // LEFT SQUARE BRACKET WITH TICK IN TOP CORNER + { 0x298E, BIDI_ON }, // RIGHT SQUARE BRACKET WITH TICK IN BOTTOM CORNER + { 0x298F, BIDI_ON }, // LEFT SQUARE BRACKET WITH TICK IN BOTTOM CORNER + { 0x2990, BIDI_ON }, // RIGHT SQUARE BRACKET WITH TICK IN TOP CORNER + { 0x2991, BIDI_ON }, // LEFT ANGLE BRACKET WITH DOT + { 0x2992, BIDI_ON }, // RIGHT ANGLE BRACKET WITH DOT + { 0x2993, BIDI_ON }, // LEFT ARC LESS-THAN BRACKET + { 0x2994, BIDI_ON }, // RIGHT ARC GREATER-THAN BRACKET + { 0x2995, BIDI_ON }, // DOUBLE LEFT ARC GREATER-THAN BRACKET + { 0x2996, BIDI_ON }, // DOUBLE RIGHT ARC LESS-THAN BRACKET + { 0x2997, BIDI_ON }, // LEFT BLACK TORTOISE SHELL BRACKET + { 0x2998, BIDI_ON }, // RIGHT BLACK TORTOISE SHELL BRACKET + { 0x2999, BIDI_ON }, // DOTTED FENCE + { 0x299A, BIDI_ON }, // VERTICAL ZIGZAG LINE + { 0x299B, BIDI_ON }, // MEASURED ANGLE OPENING LEFT + { 0x299C, BIDI_ON }, // RIGHT ANGLE VARIANT WITH SQUARE + { 0x299D, BIDI_ON }, // MEASURED RIGHT ANGLE WITH DOT + { 0x299E, BIDI_ON }, // ANGLE WITH S INSIDE + { 0x299F, BIDI_ON }, // ACUTE ANGLE + { 0x29A0, BIDI_ON }, // SPHERICAL ANGLE OPENING LEFT + { 0x29A1, BIDI_ON }, // SPHERICAL ANGLE OPENING UP + { 0x29A2, BIDI_ON }, // TURNED ANGLE + { 0x29A3, BIDI_ON }, // REVERSED ANGLE + { 0x29A4, BIDI_ON }, // ANGLE WITH UNDERBAR + { 0x29A5, BIDI_ON }, // REVERSED ANGLE WITH UNDERBAR + { 0x29A6, BIDI_ON }, // OBLIQUE ANGLE OPENING UP + { 0x29A7, BIDI_ON }, // OBLIQUE ANGLE OPENING DOWN + { 0x29A8, BIDI_ON }, // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND RIGHT + { 0x29A9, BIDI_ON }, // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING UP AND LEFT + { 0x29AA, BIDI_ON }, // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND RIGHT + { 0x29AB, BIDI_ON }, // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING DOWN AND LEFT + { 0x29AC, BIDI_ON }, // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND UP + { 0x29AD, BIDI_ON }, // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND UP + { 0x29AE, BIDI_ON }, // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING RIGHT AND DOWN + { 0x29AF, BIDI_ON }, // MEASURED ANGLE WITH OPEN ARM ENDING IN ARROW POINTING LEFT AND DOWN + { 0x29B0, BIDI_ON }, // REVERSED EMPTY SET + { 0x29B1, BIDI_ON }, // EMPTY SET WITH OVERBAR + { 0x29B2, BIDI_ON }, // EMPTY SET WITH SMALL CIRCLE ABOVE + { 0x29B3, BIDI_ON }, // EMPTY SET WITH RIGHT ARROW ABOVE + { 0x29B4, BIDI_ON }, // EMPTY SET WITH LEFT ARROW ABOVE + { 0x29B5, BIDI_ON }, // CIRCLE WITH HORIZONTAL BAR + { 0x29B6, BIDI_ON }, // CIRCLED VERTICAL BAR + { 0x29B7, BIDI_ON }, // CIRCLED PARALLEL + { 0x29B8, BIDI_ON }, // CIRCLED REVERSE SOLIDUS + { 0x29B9, BIDI_ON }, // CIRCLED PERPENDICULAR + { 0x29BA, BIDI_ON }, // CIRCLE DIVIDED BY HORIZONTAL BAR AND TOP HALF DIVIDED BY VERTICAL BAR + { 0x29BB, BIDI_ON }, // CIRCLE WITH SUPERIMPOSED X + { 0x29BC, BIDI_ON }, // CIRCLED ANTICLOCKWISE-ROTATED DIVISION SIGN + { 0x29BD, BIDI_ON }, // UP ARROW THROUGH CIRCLE + { 0x29BE, BIDI_ON }, // CIRCLED WHITE BULLET + { 0x29BF, BIDI_ON }, // CIRCLED BULLET + { 0x29C0, BIDI_ON }, // CIRCLED LESS-THAN + { 0x29C1, BIDI_ON }, // CIRCLED GREATER-THAN + { 0x29C2, BIDI_ON }, // CIRCLE WITH SMALL CIRCLE TO THE RIGHT + { 0x29C3, BIDI_ON }, // CIRCLE WITH TWO HORIZONTAL STROKES TO THE RIGHT + { 0x29C4, BIDI_ON }, // SQUARED RISING DIAGONAL SLASH + { 0x29C5, BIDI_ON }, // SQUARED FALLING DIAGONAL SLASH + { 0x29C6, BIDI_ON }, // SQUARED ASTERISK + { 0x29C7, BIDI_ON }, // SQUARED SMALL CIRCLE + { 0x29C8, BIDI_ON }, // SQUARED SQUARE + { 0x29C9, BIDI_ON }, // TWO JOINED SQUARES + { 0x29CA, BIDI_ON }, // TRIANGLE WITH DOT ABOVE + { 0x29CB, BIDI_ON }, // TRIANGLE WITH UNDERBAR + { 0x29CC, BIDI_ON }, // S IN TRIANGLE + { 0x29CD, BIDI_ON }, // TRIANGLE WITH SERIFS AT BOTTOM + { 0x29CE, BIDI_ON }, // RIGHT TRIANGLE ABOVE LEFT TRIANGLE + { 0x29CF, BIDI_ON }, // LEFT TRIANGLE BESIDE VERTICAL BAR + { 0x29D0, BIDI_ON }, // VERTICAL BAR BESIDE RIGHT TRIANGLE + { 0x29D1, BIDI_ON }, // BOWTIE WITH LEFT HALF BLACK + { 0x29D2, BIDI_ON }, // BOWTIE WITH RIGHT HALF BLACK + { 0x29D3, BIDI_ON }, // BLACK BOWTIE + { 0x29D4, BIDI_ON }, // TIMES WITH LEFT HALF BLACK + { 0x29D5, BIDI_ON }, // TIMES WITH RIGHT HALF BLACK + { 0x29D6, BIDI_ON }, // WHITE HOURGLASS + { 0x29D7, BIDI_ON }, // BLACK HOURGLASS + { 0x29D8, BIDI_ON }, // LEFT WIGGLY FENCE + { 0x29D9, BIDI_ON }, // RIGHT WIGGLY FENCE + { 0x29DA, BIDI_ON }, // LEFT DOUBLE WIGGLY FENCE + { 0x29DB, BIDI_ON }, // RIGHT DOUBLE WIGGLY FENCE + { 0x29DC, BIDI_ON }, // INCOMPLETE INFINITY + { 0x29DD, BIDI_ON }, // TIE OVER INFINITY + { 0x29DE, BIDI_ON }, // INFINITY NEGATED WITH VERTICAL BAR + { 0x29DF, BIDI_ON }, // DOUBLE-ENDED MULTIMAP + { 0x29E0, BIDI_ON }, // SQUARE WITH CONTOURED OUTLINE + { 0x29E1, BIDI_ON }, // INCREASES AS + { 0x29E2, BIDI_ON }, // SHUFFLE PRODUCT + { 0x29E3, BIDI_ON }, // EQUALS SIGN AND SLANTED PARALLEL + { 0x29E4, BIDI_ON }, // EQUALS SIGN AND SLANTED PARALLEL WITH TILDE ABOVE + { 0x29E5, BIDI_ON }, // IDENTICAL TO AND SLANTED PARALLEL + { 0x29E6, BIDI_ON }, // GLEICH STARK + { 0x29E7, BIDI_ON }, // THERMODYNAMIC + { 0x29E8, BIDI_ON }, // DOWN-POINTING TRIANGLE WITH LEFT HALF BLACK + { 0x29E9, BIDI_ON }, // DOWN-POINTING TRIANGLE WITH RIGHT HALF BLACK + { 0x29EA, BIDI_ON }, // BLACK DIAMOND WITH DOWN ARROW + { 0x29EB, BIDI_ON }, // BLACK LOZENGE + { 0x29EC, BIDI_ON }, // WHITE CIRCLE WITH DOWN ARROW + { 0x29ED, BIDI_ON }, // BLACK CIRCLE WITH DOWN ARROW + { 0x29EE, BIDI_ON }, // ERROR-BARRED WHITE SQUARE + { 0x29EF, BIDI_ON }, // ERROR-BARRED BLACK SQUARE + { 0x29F0, BIDI_ON }, // ERROR-BARRED WHITE DIAMOND + { 0x29F1, BIDI_ON }, // ERROR-BARRED BLACK DIAMOND + { 0x29F2, BIDI_ON }, // ERROR-BARRED WHITE CIRCLE + { 0x29F3, BIDI_ON }, // ERROR-BARRED BLACK CIRCLE + { 0x29F4, BIDI_ON }, // RULE-DELAYED + { 0x29F5, BIDI_ON }, // REVERSE SOLIDUS OPERATOR + { 0x29F6, BIDI_ON }, // SOLIDUS WITH OVERBAR + { 0x29F7, BIDI_ON }, // REVERSE SOLIDUS WITH HORIZONTAL STROKE + { 0x29F8, BIDI_ON }, // BIG SOLIDUS + { 0x29F9, BIDI_ON }, // BIG REVERSE SOLIDUS + { 0x29FA, BIDI_ON }, // DOUBLE PLUS + { 0x29FB, BIDI_ON }, // TRIPLE PLUS + { 0x29FC, BIDI_ON }, // LEFT-POINTING CURVED ANGLE BRACKET + { 0x29FD, BIDI_ON }, // RIGHT-POINTING CURVED ANGLE BRACKET + { 0x29FE, BIDI_ON }, // TINY + { 0x29FF, BIDI_ON }, // MINY + { 0x2A00, BIDI_ON }, // N-ARY CIRCLED DOT OPERATOR + { 0x2A01, BIDI_ON }, // N-ARY CIRCLED PLUS OPERATOR + { 0x2A02, BIDI_ON }, // N-ARY CIRCLED TIMES OPERATOR + { 0x2A03, BIDI_ON }, // N-ARY UNION OPERATOR WITH DOT + { 0x2A04, BIDI_ON }, // N-ARY UNION OPERATOR WITH PLUS + { 0x2A05, BIDI_ON }, // N-ARY SQUARE INTERSECTION OPERATOR + { 0x2A06, BIDI_ON }, // N-ARY SQUARE UNION OPERATOR + { 0x2A07, BIDI_ON }, // TWO LOGICAL AND OPERATOR + { 0x2A08, BIDI_ON }, // TWO LOGICAL OR OPERATOR + { 0x2A09, BIDI_ON }, // N-ARY TIMES OPERATOR + { 0x2A0A, BIDI_ON }, // MODULO TWO SUM + { 0x2A0B, BIDI_ON }, // SUMMATION WITH INTEGRAL + { 0x2A0C, BIDI_ON }, // QUADRUPLE INTEGRAL OPERATOR + { 0x2A0D, BIDI_ON }, // FINITE PART INTEGRAL + { 0x2A0E, BIDI_ON }, // INTEGRAL WITH DOUBLE STROKE + { 0x2A0F, BIDI_ON }, // INTEGRAL AVERAGE WITH SLASH + { 0x2A10, BIDI_ON }, // CIRCULATION FUNCTION + { 0x2A11, BIDI_ON }, // ANTICLOCKWISE INTEGRATION + { 0x2A12, BIDI_ON }, // LINE INTEGRATION WITH RECTANGULAR PATH AROUND POLE + { 0x2A13, BIDI_ON }, // LINE INTEGRATION WITH SEMICIRCULAR PATH AROUND POLE + { 0x2A14, BIDI_ON }, // LINE INTEGRATION NOT INCLUDING THE POLE + { 0x2A15, BIDI_ON }, // INTEGRAL AROUND A POINT OPERATOR + { 0x2A16, BIDI_ON }, // QUATERNION INTEGRAL OPERATOR + { 0x2A17, BIDI_ON }, // INTEGRAL WITH LEFTWARDS ARROW WITH HOOK + { 0x2A18, BIDI_ON }, // INTEGRAL WITH TIMES SIGN + { 0x2A19, BIDI_ON }, // INTEGRAL WITH INTERSECTION + { 0x2A1A, BIDI_ON }, // INTEGRAL WITH UNION + { 0x2A1B, BIDI_ON }, // INTEGRAL WITH OVERBAR + { 0x2A1C, BIDI_ON }, // INTEGRAL WITH UNDERBAR + { 0x2A1D, BIDI_ON }, // JOIN + { 0x2A1E, BIDI_ON }, // LARGE LEFT TRIANGLE OPERATOR + { 0x2A1F, BIDI_ON }, // Z NOTATION SCHEMA COMPOSITION + { 0x2A20, BIDI_ON }, // Z NOTATION SCHEMA PIPING + { 0x2A21, BIDI_ON }, // Z NOTATION SCHEMA PROJECTION + { 0x2A22, BIDI_ON }, // PLUS SIGN WITH SMALL CIRCLE ABOVE + { 0x2A23, BIDI_ON }, // PLUS SIGN WITH CIRCUMFLEX ACCENT ABOVE + { 0x2A24, BIDI_ON }, // PLUS SIGN WITH TILDE ABOVE + { 0x2A25, BIDI_ON }, // PLUS SIGN WITH DOT BELOW + { 0x2A26, BIDI_ON }, // PLUS SIGN WITH TILDE BELOW + { 0x2A27, BIDI_ON }, // PLUS SIGN WITH SUBSCRIPT TWO + { 0x2A28, BIDI_ON }, // PLUS SIGN WITH BLACK TRIANGLE + { 0x2A29, BIDI_ON }, // MINUS SIGN WITH COMMA ABOVE + { 0x2A2A, BIDI_ON }, // MINUS SIGN WITH DOT BELOW + { 0x2A2B, BIDI_ON }, // MINUS SIGN WITH FALLING DOTS + { 0x2A2C, BIDI_ON }, // MINUS SIGN WITH RISING DOTS + { 0x2A2D, BIDI_ON }, // PLUS SIGN IN LEFT HALF CIRCLE + { 0x2A2E, BIDI_ON }, // PLUS SIGN IN RIGHT HALF CIRCLE + { 0x2A2F, BIDI_ON }, // VECTOR OR CROSS PRODUCT + { 0x2A30, BIDI_ON }, // MULTIPLICATION SIGN WITH DOT ABOVE + { 0x2A31, BIDI_ON }, // MULTIPLICATION SIGN WITH UNDERBAR + { 0x2A32, BIDI_ON }, // SEMIDIRECT PRODUCT WITH BOTTOM CLOSED + { 0x2A33, BIDI_ON }, // SMASH PRODUCT + { 0x2A34, BIDI_ON }, // MULTIPLICATION SIGN IN LEFT HALF CIRCLE + { 0x2A35, BIDI_ON }, // MULTIPLICATION SIGN IN RIGHT HALF CIRCLE + { 0x2A36, BIDI_ON }, // CIRCLED MULTIPLICATION SIGN WITH CIRCUMFLEX ACCENT + { 0x2A37, BIDI_ON }, // MULTIPLICATION SIGN IN DOUBLE CIRCLE + { 0x2A38, BIDI_ON }, // CIRCLED DIVISION SIGN + { 0x2A39, BIDI_ON }, // PLUS SIGN IN TRIANGLE + { 0x2A3A, BIDI_ON }, // MINUS SIGN IN TRIANGLE + { 0x2A3B, BIDI_ON }, // MULTIPLICATION SIGN IN TRIANGLE + { 0x2A3C, BIDI_ON }, // INTERIOR PRODUCT + { 0x2A3D, BIDI_ON }, // RIGHTHAND INTERIOR PRODUCT + { 0x2A3E, BIDI_ON }, // Z NOTATION RELATIONAL COMPOSITION + { 0x2A3F, BIDI_ON }, // AMALGAMATION OR COPRODUCT + { 0x2A40, BIDI_ON }, // INTERSECTION WITH DOT + { 0x2A41, BIDI_ON }, // UNION WITH MINUS SIGN + { 0x2A42, BIDI_ON }, // UNION WITH OVERBAR + { 0x2A43, BIDI_ON }, // INTERSECTION WITH OVERBAR + { 0x2A44, BIDI_ON }, // INTERSECTION WITH LOGICAL AND + { 0x2A45, BIDI_ON }, // UNION WITH LOGICAL OR + { 0x2A46, BIDI_ON }, // UNION ABOVE INTERSECTION + { 0x2A47, BIDI_ON }, // INTERSECTION ABOVE UNION + { 0x2A48, BIDI_ON }, // UNION ABOVE BAR ABOVE INTERSECTION + { 0x2A49, BIDI_ON }, // INTERSECTION ABOVE BAR ABOVE UNION + { 0x2A4A, BIDI_ON }, // UNION BESIDE AND JOINED WITH UNION + { 0x2A4B, BIDI_ON }, // INTERSECTION BESIDE AND JOINED WITH INTERSECTION + { 0x2A4C, BIDI_ON }, // CLOSED UNION WITH SERIFS + { 0x2A4D, BIDI_ON }, // CLOSED INTERSECTION WITH SERIFS + { 0x2A4E, BIDI_ON }, // DOUBLE SQUARE INTERSECTION + { 0x2A4F, BIDI_ON }, // DOUBLE SQUARE UNION + { 0x2A50, BIDI_ON }, // CLOSED UNION WITH SERIFS AND SMASH PRODUCT + { 0x2A51, BIDI_ON }, // LOGICAL AND WITH DOT ABOVE + { 0x2A52, BIDI_ON }, // LOGICAL OR WITH DOT ABOVE + { 0x2A53, BIDI_ON }, // DOUBLE LOGICAL AND + { 0x2A54, BIDI_ON }, // DOUBLE LOGICAL OR + { 0x2A55, BIDI_ON }, // TWO INTERSECTING LOGICAL AND + { 0x2A56, BIDI_ON }, // TWO INTERSECTING LOGICAL OR + { 0x2A57, BIDI_ON }, // SLOPING LARGE OR + { 0x2A58, BIDI_ON }, // SLOPING LARGE AND + { 0x2A59, BIDI_ON }, // LOGICAL OR OVERLAPPING LOGICAL AND + { 0x2A5A, BIDI_ON }, // LOGICAL AND WITH MIDDLE STEM + { 0x2A5B, BIDI_ON }, // LOGICAL OR WITH MIDDLE STEM + { 0x2A5C, BIDI_ON }, // LOGICAL AND WITH HORIZONTAL DASH + { 0x2A5D, BIDI_ON }, // LOGICAL OR WITH HORIZONTAL DASH + { 0x2A5E, BIDI_ON }, // LOGICAL AND WITH DOUBLE OVERBAR + { 0x2A5F, BIDI_ON }, // LOGICAL AND WITH UNDERBAR + { 0x2A60, BIDI_ON }, // LOGICAL AND WITH DOUBLE UNDERBAR + { 0x2A61, BIDI_ON }, // SMALL VEE WITH UNDERBAR + { 0x2A62, BIDI_ON }, // LOGICAL OR WITH DOUBLE OVERBAR + { 0x2A63, BIDI_ON }, // LOGICAL OR WITH DOUBLE UNDERBAR + { 0x2A64, BIDI_ON }, // Z NOTATION DOMAIN ANTIRESTRICTION + { 0x2A65, BIDI_ON }, // Z NOTATION RANGE ANTIRESTRICTION + { 0x2A66, BIDI_ON }, // EQUALS SIGN WITH DOT BELOW + { 0x2A67, BIDI_ON }, // IDENTICAL WITH DOT ABOVE + { 0x2A68, BIDI_ON }, // TRIPLE HORIZONTAL BAR WITH DOUBLE VERTICAL STROKE + { 0x2A69, BIDI_ON }, // TRIPLE HORIZONTAL BAR WITH TRIPLE VERTICAL STROKE + { 0x2A6A, BIDI_ON }, // TILDE OPERATOR WITH DOT ABOVE + { 0x2A6B, BIDI_ON }, // TILDE OPERATOR WITH RISING DOTS + { 0x2A6C, BIDI_ON }, // SIMILAR MINUS SIMILAR + { 0x2A6D, BIDI_ON }, // CONGRUENT WITH DOT ABOVE + { 0x2A6E, BIDI_ON }, // EQUALS WITH ASTERISK + { 0x2A6F, BIDI_ON }, // ALMOST EQUAL TO WITH CIRCUMFLEX ACCENT + { 0x2A70, BIDI_ON }, // APPROXIMATELY EQUAL OR EQUAL TO + { 0x2A71, BIDI_ON }, // EQUALS SIGN ABOVE PLUS SIGN + { 0x2A72, BIDI_ON }, // PLUS SIGN ABOVE EQUALS SIGN + { 0x2A73, BIDI_ON }, // EQUALS SIGN ABOVE TILDE OPERATOR + { 0x2A74, BIDI_ON }, // DOUBLE COLON EQUAL + { 0x2A75, BIDI_ON }, // TWO CONSECUTIVE EQUALS SIGNS + { 0x2A76, BIDI_ON }, // THREE CONSECUTIVE EQUALS SIGNS + { 0x2A77, BIDI_ON }, // EQUALS SIGN WITH TWO DOTS ABOVE AND TWO DOTS BELOW + { 0x2A78, BIDI_ON }, // EQUIVALENT WITH FOUR DOTS ABOVE + { 0x2A79, BIDI_ON }, // LESS-THAN WITH CIRCLE INSIDE + { 0x2A7A, BIDI_ON }, // GREATER-THAN WITH CIRCLE INSIDE + { 0x2A7B, BIDI_ON }, // LESS-THAN WITH QUESTION MARK ABOVE + { 0x2A7C, BIDI_ON }, // GREATER-THAN WITH QUESTION MARK ABOVE + { 0x2A7D, BIDI_ON }, // LESS-THAN OR SLANTED EQUAL TO + { 0x2A7E, BIDI_ON }, // GREATER-THAN OR SLANTED EQUAL TO + { 0x2A7F, BIDI_ON }, // LESS-THAN OR SLANTED EQUAL TO WITH DOT INSIDE + { 0x2A80, BIDI_ON }, // GREATER-THAN OR SLANTED EQUAL TO WITH DOT INSIDE + { 0x2A81, BIDI_ON }, // LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE + { 0x2A82, BIDI_ON }, // GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE + { 0x2A83, BIDI_ON }, // LESS-THAN OR SLANTED EQUAL TO WITH DOT ABOVE RIGHT + { 0x2A84, BIDI_ON }, // GREATER-THAN OR SLANTED EQUAL TO WITH DOT ABOVE LEFT + { 0x2A85, BIDI_ON }, // LESS-THAN OR APPROXIMATE + { 0x2A86, BIDI_ON }, // GREATER-THAN OR APPROXIMATE + { 0x2A87, BIDI_ON }, // LESS-THAN AND SINGLE-LINE NOT EQUAL TO + { 0x2A88, BIDI_ON }, // GREATER-THAN AND SINGLE-LINE NOT EQUAL TO + { 0x2A89, BIDI_ON }, // LESS-THAN AND NOT APPROXIMATE + { 0x2A8A, BIDI_ON }, // GREATER-THAN AND NOT APPROXIMATE + { 0x2A8B, BIDI_ON }, // LESS-THAN ABOVE DOUBLE-LINE EQUAL ABOVE GREATER-THAN + { 0x2A8C, BIDI_ON }, // GREATER-THAN ABOVE DOUBLE-LINE EQUAL ABOVE LESS-THAN + { 0x2A8D, BIDI_ON }, // LESS-THAN ABOVE SIMILAR OR EQUAL + { 0x2A8E, BIDI_ON }, // GREATER-THAN ABOVE SIMILAR OR EQUAL + { 0x2A8F, BIDI_ON }, // LESS-THAN ABOVE SIMILAR ABOVE GREATER-THAN + { 0x2A90, BIDI_ON }, // GREATER-THAN ABOVE SIMILAR ABOVE LESS-THAN + { 0x2A91, BIDI_ON }, // LESS-THAN ABOVE GREATER-THAN ABOVE DOUBLE-LINE EQUAL + { 0x2A92, BIDI_ON }, // GREATER-THAN ABOVE LESS-THAN ABOVE DOUBLE-LINE EQUAL + { 0x2A93, BIDI_ON }, // LESS-THAN ABOVE SLANTED EQUAL ABOVE GREATER-THAN ABOVE SLANTED EQUAL + { 0x2A94, BIDI_ON }, // GREATER-THAN ABOVE SLANTED EQUAL ABOVE LESS-THAN ABOVE SLANTED EQUAL + { 0x2A95, BIDI_ON }, // SLANTED EQUAL TO OR LESS-THAN + { 0x2A96, BIDI_ON }, // SLANTED EQUAL TO OR GREATER-THAN + { 0x2A97, BIDI_ON }, // SLANTED EQUAL TO OR LESS-THAN WITH DOT INSIDE + { 0x2A98, BIDI_ON }, // SLANTED EQUAL TO OR GREATER-THAN WITH DOT INSIDE + { 0x2A99, BIDI_ON }, // DOUBLE-LINE EQUAL TO OR LESS-THAN + { 0x2A9A, BIDI_ON }, // DOUBLE-LINE EQUAL TO OR GREATER-THAN + { 0x2A9B, BIDI_ON }, // DOUBLE-LINE SLANTED EQUAL TO OR LESS-THAN + { 0x2A9C, BIDI_ON }, // DOUBLE-LINE SLANTED EQUAL TO OR GREATER-THAN + { 0x2A9D, BIDI_ON }, // SIMILAR OR LESS-THAN + { 0x2A9E, BIDI_ON }, // SIMILAR OR GREATER-THAN + { 0x2A9F, BIDI_ON }, // SIMILAR ABOVE LESS-THAN ABOVE EQUALS SIGN + { 0x2AA0, BIDI_ON }, // SIMILAR ABOVE GREATER-THAN ABOVE EQUALS SIGN + { 0x2AA1, BIDI_ON }, // DOUBLE NESTED LESS-THAN + { 0x2AA2, BIDI_ON }, // DOUBLE NESTED GREATER-THAN + { 0x2AA3, BIDI_ON }, // DOUBLE NESTED LESS-THAN WITH UNDERBAR + { 0x2AA4, BIDI_ON }, // GREATER-THAN OVERLAPPING LESS-THAN + { 0x2AA5, BIDI_ON }, // GREATER-THAN BESIDE LESS-THAN + { 0x2AA6, BIDI_ON }, // LESS-THAN CLOSED BY CURVE + { 0x2AA7, BIDI_ON }, // GREATER-THAN CLOSED BY CURVE + { 0x2AA8, BIDI_ON }, // LESS-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL + { 0x2AA9, BIDI_ON }, // GREATER-THAN CLOSED BY CURVE ABOVE SLANTED EQUAL + { 0x2AAA, BIDI_ON }, // SMALLER THAN + { 0x2AAB, BIDI_ON }, // LARGER THAN + { 0x2AAC, BIDI_ON }, // SMALLER THAN OR EQUAL TO + { 0x2AAD, BIDI_ON }, // LARGER THAN OR EQUAL TO + { 0x2AAE, BIDI_ON }, // EQUALS SIGN WITH BUMPY ABOVE + { 0x2AAF, BIDI_ON }, // PRECEDES ABOVE SINGLE-LINE EQUALS SIGN + { 0x2AB0, BIDI_ON }, // SUCCEEDS ABOVE SINGLE-LINE EQUALS SIGN + { 0x2AB1, BIDI_ON }, // PRECEDES ABOVE SINGLE-LINE NOT EQUAL TO + { 0x2AB2, BIDI_ON }, // SUCCEEDS ABOVE SINGLE-LINE NOT EQUAL TO + { 0x2AB3, BIDI_ON }, // PRECEDES ABOVE EQUALS SIGN + { 0x2AB4, BIDI_ON }, // SUCCEEDS ABOVE EQUALS SIGN + { 0x2AB5, BIDI_ON }, // PRECEDES ABOVE NOT EQUAL TO + { 0x2AB6, BIDI_ON }, // SUCCEEDS ABOVE NOT EQUAL TO + { 0x2AB7, BIDI_ON }, // PRECEDES ABOVE ALMOST EQUAL TO + { 0x2AB8, BIDI_ON }, // SUCCEEDS ABOVE ALMOST EQUAL TO + { 0x2AB9, BIDI_ON }, // PRECEDES ABOVE NOT ALMOST EQUAL TO + { 0x2ABA, BIDI_ON }, // SUCCEEDS ABOVE NOT ALMOST EQUAL TO + { 0x2ABB, BIDI_ON }, // DOUBLE PRECEDES + { 0x2ABC, BIDI_ON }, // DOUBLE SUCCEEDS + { 0x2ABD, BIDI_ON }, // SUBSET WITH DOT + { 0x2ABE, BIDI_ON }, // SUPERSET WITH DOT + { 0x2ABF, BIDI_ON }, // SUBSET WITH PLUS SIGN BELOW + { 0x2AC0, BIDI_ON }, // SUPERSET WITH PLUS SIGN BELOW + { 0x2AC1, BIDI_ON }, // SUBSET WITH MULTIPLICATION SIGN BELOW + { 0x2AC2, BIDI_ON }, // SUPERSET WITH MULTIPLICATION SIGN BELOW + { 0x2AC3, BIDI_ON }, // SUBSET OF OR EQUAL TO WITH DOT ABOVE + { 0x2AC4, BIDI_ON }, // SUPERSET OF OR EQUAL TO WITH DOT ABOVE + { 0x2AC5, BIDI_ON }, // SUBSET OF ABOVE EQUALS SIGN + { 0x2AC6, BIDI_ON }, // SUPERSET OF ABOVE EQUALS SIGN + { 0x2AC7, BIDI_ON }, // SUBSET OF ABOVE TILDE OPERATOR + { 0x2AC8, BIDI_ON }, // SUPERSET OF ABOVE TILDE OPERATOR + { 0x2AC9, BIDI_ON }, // SUBSET OF ABOVE ALMOST EQUAL TO + { 0x2ACA, BIDI_ON }, // SUPERSET OF ABOVE ALMOST EQUAL TO + { 0x2ACB, BIDI_ON }, // SUBSET OF ABOVE NOT EQUAL TO + { 0x2ACC, BIDI_ON }, // SUPERSET OF ABOVE NOT EQUAL TO + { 0x2ACD, BIDI_ON }, // SQUARE LEFT OPEN BOX OPERATOR + { 0x2ACE, BIDI_ON }, // SQUARE RIGHT OPEN BOX OPERATOR + { 0x2ACF, BIDI_ON }, // CLOSED SUBSET + { 0x2AD0, BIDI_ON }, // CLOSED SUPERSET + { 0x2AD1, BIDI_ON }, // CLOSED SUBSET OR EQUAL TO + { 0x2AD2, BIDI_ON }, // CLOSED SUPERSET OR EQUAL TO + { 0x2AD3, BIDI_ON }, // SUBSET ABOVE SUPERSET + { 0x2AD4, BIDI_ON }, // SUPERSET ABOVE SUBSET + { 0x2AD5, BIDI_ON }, // SUBSET ABOVE SUBSET + { 0x2AD6, BIDI_ON }, // SUPERSET ABOVE SUPERSET + { 0x2AD7, BIDI_ON }, // SUPERSET BESIDE SUBSET + { 0x2AD8, BIDI_ON }, // SUPERSET BESIDE AND JOINED BY DASH WITH SUBSET + { 0x2AD9, BIDI_ON }, // ELEMENT OF OPENING DOWNWARDS + { 0x2ADA, BIDI_ON }, // PITCHFORK WITH TEE TOP + { 0x2ADB, BIDI_ON }, // TRANSVERSAL INTERSECTION + { 0x2ADC, BIDI_ON }, // FORKING + { 0x2ADD, BIDI_ON }, // NONFORKING + { 0x2ADE, BIDI_ON }, // SHORT LEFT TACK + { 0x2ADF, BIDI_ON }, // SHORT DOWN TACK + { 0x2AE0, BIDI_ON }, // SHORT UP TACK + { 0x2AE1, BIDI_ON }, // PERPENDICULAR WITH S + { 0x2AE2, BIDI_ON }, // VERTICAL BAR TRIPLE RIGHT TURNSTILE + { 0x2AE3, BIDI_ON }, // DOUBLE VERTICAL BAR LEFT TURNSTILE + { 0x2AE4, BIDI_ON }, // VERTICAL BAR DOUBLE LEFT TURNSTILE + { 0x2AE5, BIDI_ON }, // DOUBLE VERTICAL BAR DOUBLE LEFT TURNSTILE + { 0x2AE6, BIDI_ON }, // LONG DASH FROM LEFT MEMBER OF DOUBLE VERTICAL + { 0x2AE7, BIDI_ON }, // SHORT DOWN TACK WITH OVERBAR + { 0x2AE8, BIDI_ON }, // SHORT UP TACK WITH UNDERBAR + { 0x2AE9, BIDI_ON }, // SHORT UP TACK ABOVE SHORT DOWN TACK + { 0x2AEA, BIDI_ON }, // DOUBLE DOWN TACK + { 0x2AEB, BIDI_ON }, // DOUBLE UP TACK + { 0x2AEC, BIDI_ON }, // DOUBLE STROKE NOT SIGN + { 0x2AED, BIDI_ON }, // REVERSED DOUBLE STROKE NOT SIGN + { 0x2AEE, BIDI_ON }, // DOES NOT DIVIDE WITH REVERSED NEGATION SLASH + { 0x2AEF, BIDI_ON }, // VERTICAL LINE WITH CIRCLE ABOVE + { 0x2AF0, BIDI_ON }, // VERTICAL LINE WITH CIRCLE BELOW + { 0x2AF1, BIDI_ON }, // DOWN TACK WITH CIRCLE BELOW + { 0x2AF2, BIDI_ON }, // PARALLEL WITH HORIZONTAL STROKE + { 0x2AF3, BIDI_ON }, // PARALLEL WITH TILDE OPERATOR + { 0x2AF4, BIDI_ON }, // TRIPLE VERTICAL BAR BINARY RELATION + { 0x2AF5, BIDI_ON }, // TRIPLE VERTICAL BAR WITH HORIZONTAL STROKE + { 0x2AF6, BIDI_ON }, // TRIPLE COLON OPERATOR + { 0x2AF7, BIDI_ON }, // TRIPLE NESTED LESS-THAN + { 0x2AF8, BIDI_ON }, // TRIPLE NESTED GREATER-THAN + { 0x2AF9, BIDI_ON }, // DOUBLE-LINE SLANTED LESS-THAN OR EQUAL TO + { 0x2AFA, BIDI_ON }, // DOUBLE-LINE SLANTED GREATER-THAN OR EQUAL TO + { 0x2AFB, BIDI_ON }, // TRIPLE SOLIDUS BINARY RELATION + { 0x2AFC, BIDI_ON }, // LARGE TRIPLE VERTICAL BAR OPERATOR + { 0x2AFD, BIDI_ON }, // DOUBLE SOLIDUS OPERATOR + { 0x2AFE, BIDI_ON }, // WHITE VERTICAL BAR + { 0x2AFF, BIDI_ON }, // N-ARY WHITE VERTICAL BAR + { 0x2B00, BIDI_ON }, // NORTH EAST WHITE ARROW + { 0x2B01, BIDI_ON }, // NORTH WEST WHITE ARROW + { 0x2B02, BIDI_ON }, // SOUTH EAST WHITE ARROW + { 0x2B03, BIDI_ON }, // SOUTH WEST WHITE ARROW + { 0x2B04, BIDI_ON }, // LEFT RIGHT WHITE ARROW + { 0x2B05, BIDI_ON }, // LEFTWARDS BLACK ARROW + { 0x2B06, BIDI_ON }, // UPWARDS BLACK ARROW + { 0x2B07, BIDI_ON }, // DOWNWARDS BLACK ARROW + { 0x2B08, BIDI_ON }, // NORTH EAST BLACK ARROW + { 0x2B09, BIDI_ON }, // NORTH WEST BLACK ARROW + { 0x2B0A, BIDI_ON }, // SOUTH EAST BLACK ARROW + { 0x2B0B, BIDI_ON }, // SOUTH WEST BLACK ARROW + { 0x2B0C, BIDI_ON }, // LEFT RIGHT BLACK ARROW + { 0x2B0D, BIDI_ON }, // UP DOWN BLACK ARROW + { 0x2B0E, BIDI_ON }, // RIGHTWARDS ARROW WITH TIP DOWNWARDS + { 0x2B0F, BIDI_ON }, // RIGHTWARDS ARROW WITH TIP UPWARDS + { 0x2B10, BIDI_ON }, // LEFTWARDS ARROW WITH TIP DOWNWARDS + { 0x2B11, BIDI_ON }, // LEFTWARDS ARROW WITH TIP UPWARDS + { 0x2B12, BIDI_ON }, // SQUARE WITH TOP HALF BLACK + { 0x2B13, BIDI_ON }, // SQUARE WITH BOTTOM HALF BLACK + { 0x2B14, BIDI_ON }, // SQUARE WITH UPPER RIGHT DIAGONAL HALF BLACK + { 0x2B15, BIDI_ON }, // SQUARE WITH LOWER LEFT DIAGONAL HALF BLACK + { 0x2B16, BIDI_ON }, // DIAMOND WITH LEFT HALF BLACK + { 0x2B17, BIDI_ON }, // DIAMOND WITH RIGHT HALF BLACK + { 0x2B18, BIDI_ON }, // DIAMOND WITH TOP HALF BLACK + { 0x2B19, BIDI_ON }, // DIAMOND WITH BOTTOM HALF BLACK + { 0x2B1A, BIDI_ON }, // DOTTED SQUARE + { 0x2B1B, BIDI_ON }, // BLACK LARGE SQUARE + { 0x2B1C, BIDI_ON }, // WHITE LARGE SQUARE + { 0x2B1D, BIDI_ON }, // BLACK VERY SMALL SQUARE + { 0x2B1E, BIDI_ON }, // WHITE VERY SMALL SQUARE + { 0x2B1F, BIDI_ON }, // BLACK PENTAGON + { 0x2B20, BIDI_ON }, // WHITE PENTAGON + { 0x2B21, BIDI_ON }, // WHITE HEXAGON + { 0x2B22, BIDI_ON }, // BLACK HEXAGON + { 0x2B23, BIDI_ON }, // HORIZONTAL BLACK HEXAGON + { 0x2B24, BIDI_ON }, // BLACK LARGE CIRCLE + { 0x2B25, BIDI_ON }, // BLACK MEDIUM DIAMOND + { 0x2B26, BIDI_ON }, // WHITE MEDIUM DIAMOND + { 0x2B27, BIDI_ON }, // BLACK MEDIUM LOZENGE + { 0x2B28, BIDI_ON }, // WHITE MEDIUM LOZENGE + { 0x2B29, BIDI_ON }, // BLACK SMALL DIAMOND + { 0x2B2A, BIDI_ON }, // BLACK SMALL LOZENGE + { 0x2B2B, BIDI_ON }, // WHITE SMALL LOZENGE + { 0x2B2C, BIDI_ON }, // BLACK HORIZONTAL ELLIPSE + { 0x2B2D, BIDI_ON }, // WHITE HORIZONTAL ELLIPSE + { 0x2B2E, BIDI_ON }, // BLACK VERTICAL ELLIPSE + { 0x2B2F, BIDI_ON }, // WHITE VERTICAL ELLIPSE + { 0x2B30, BIDI_ON }, // LEFT ARROW WITH SMALL CIRCLE + { 0x2B31, BIDI_ON }, // THREE LEFTWARDS ARROWS + { 0x2B32, BIDI_ON }, // LEFT ARROW WITH CIRCLED PLUS + { 0x2B33, BIDI_ON }, // LONG LEFTWARDS SQUIGGLE ARROW + { 0x2B34, BIDI_ON }, // LEFTWARDS TWO-HEADED ARROW WITH VERTICAL STROKE + { 0x2B35, BIDI_ON }, // LEFTWARDS TWO-HEADED ARROW WITH DOUBLE VERTICAL STROKE + { 0x2B36, BIDI_ON }, // LEFTWARDS TWO-HEADED ARROW FROM BAR + { 0x2B37, BIDI_ON }, // LEFTWARDS TWO-HEADED TRIPLE DASH ARROW + { 0x2B38, BIDI_ON }, // LEFTWARDS ARROW WITH DOTTED STEM + { 0x2B39, BIDI_ON }, // LEFTWARDS ARROW WITH TAIL WITH VERTICAL STROKE + { 0x2B3A, BIDI_ON }, // LEFTWARDS ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE + { 0x2B3B, BIDI_ON }, // LEFTWARDS TWO-HEADED ARROW WITH TAIL + { 0x2B3C, BIDI_ON }, // LEFTWARDS TWO-HEADED ARROW WITH TAIL WITH VERTICAL STROKE + { 0x2B3D, BIDI_ON }, // LEFTWARDS TWO-HEADED ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE + { 0x2B3E, BIDI_ON }, // LEFTWARDS ARROW THROUGH X + { 0x2B3F, BIDI_ON }, // WAVE ARROW POINTING DIRECTLY LEFT + { 0x2B40, BIDI_ON }, // EQUALS SIGN ABOVE LEFTWARDS ARROW + { 0x2B41, BIDI_ON }, // REVERSE TILDE OPERATOR ABOVE LEFTWARDS ARROW + { 0x2B42, BIDI_ON }, // LEFTWARDS ARROW ABOVE REVERSE ALMOST EQUAL TO + { 0x2B43, BIDI_ON }, // RIGHTWARDS ARROW THROUGH GREATER-THAN + { 0x2B44, BIDI_ON }, // RIGHTWARDS ARROW THROUGH SUPERSET + { 0x2B45, BIDI_ON }, // LEFTWARDS QUADRUPLE ARROW + { 0x2B46, BIDI_ON }, // RIGHTWARDS QUADRUPLE ARROW + { 0x2B47, BIDI_ON }, // REVERSE TILDE OPERATOR ABOVE RIGHTWARDS ARROW + { 0x2B48, BIDI_ON }, // RIGHTWARDS ARROW ABOVE REVERSE ALMOST EQUAL TO + { 0x2B49, BIDI_ON }, // TILDE OPERATOR ABOVE LEFTWARDS ARROW + { 0x2B4A, BIDI_ON }, // LEFTWARDS ARROW ABOVE ALMOST EQUAL TO + { 0x2B4B, BIDI_ON }, // LEFTWARDS ARROW ABOVE REVERSE TILDE OPERATOR + { 0x2B4C, BIDI_ON }, // RIGHTWARDS ARROW ABOVE REVERSE TILDE OPERATOR + { 0x2B4D, BIDI_ON }, // DOWNWARDS TRIANGLE-HEADED ZIGZAG ARROW + { 0x2B4E, BIDI_ON }, // SHORT SLANTED NORTH ARROW + { 0x2B4F, BIDI_ON }, // SHORT BACKSLANTED SOUTH ARROW + { 0x2B50, BIDI_ON }, // WHITE MEDIUM STAR + { 0x2B51, BIDI_ON }, // BLACK SMALL STAR + { 0x2B52, BIDI_ON }, // WHITE SMALL STAR + { 0x2B53, BIDI_ON }, // BLACK RIGHT-POINTING PENTAGON + { 0x2B54, BIDI_ON }, // WHITE RIGHT-POINTING PENTAGON + { 0x2B55, BIDI_ON }, // HEAVY LARGE CIRCLE + { 0x2B56, BIDI_ON }, // HEAVY OVAL WITH OVAL INSIDE + { 0x2B57, BIDI_ON }, // HEAVY CIRCLE WITH CIRCLE INSIDE + { 0x2B58, BIDI_ON }, // HEAVY CIRCLE + { 0x2B59, BIDI_ON }, // HEAVY CIRCLED SALTIRE + { 0x2B5A, BIDI_ON }, // SLANTED NORTH ARROW WITH HOOKED HEAD + { 0x2B5B, BIDI_ON }, // BACKSLANTED SOUTH ARROW WITH HOOKED TAIL + { 0x2B5C, BIDI_ON }, // SLANTED NORTH ARROW WITH HORIZONTAL TAIL + { 0x2B5D, BIDI_ON }, // BACKSLANTED SOUTH ARROW WITH HORIZONTAL TAIL + { 0x2B5E, BIDI_ON }, // BENT ARROW POINTING DOWNWARDS THEN NORTH EAST + { 0x2B5F, BIDI_ON }, // SHORT BENT ARROW POINTING DOWNWARDS THEN NORTH EAST + { 0x2B60, BIDI_ON }, // LEFTWARDS TRIANGLE-HEADED ARROW + { 0x2B61, BIDI_ON }, // UPWARDS TRIANGLE-HEADED ARROW + { 0x2B62, BIDI_ON }, // RIGHTWARDS TRIANGLE-HEADED ARROW + { 0x2B63, BIDI_ON }, // DOWNWARDS TRIANGLE-HEADED ARROW + { 0x2B64, BIDI_ON }, // LEFT RIGHT TRIANGLE-HEADED ARROW + { 0x2B65, BIDI_ON }, // UP DOWN TRIANGLE-HEADED ARROW + { 0x2B66, BIDI_ON }, // NORTH WEST TRIANGLE-HEADED ARROW + { 0x2B67, BIDI_ON }, // NORTH EAST TRIANGLE-HEADED ARROW + { 0x2B68, BIDI_ON }, // SOUTH EAST TRIANGLE-HEADED ARROW + { 0x2B69, BIDI_ON }, // SOUTH WEST TRIANGLE-HEADED ARROW + { 0x2B6A, BIDI_ON }, // LEFTWARDS TRIANGLE-HEADED DASHED ARROW + { 0x2B6B, BIDI_ON }, // UPWARDS TRIANGLE-HEADED DASHED ARROW + { 0x2B6C, BIDI_ON }, // RIGHTWARDS TRIANGLE-HEADED DASHED ARROW + { 0x2B6D, BIDI_ON }, // DOWNWARDS TRIANGLE-HEADED DASHED ARROW + { 0x2B6E, BIDI_ON }, // CLOCKWISE TRIANGLE-HEADED OPEN CIRCLE ARROW + { 0x2B6F, BIDI_ON }, // ANTICLOCKWISE TRIANGLE-HEADED OPEN CIRCLE ARROW + { 0x2B70, BIDI_ON }, // LEFTWARDS TRIANGLE-HEADED ARROW TO BAR + { 0x2B71, BIDI_ON }, // UPWARDS TRIANGLE-HEADED ARROW TO BAR + { 0x2B72, BIDI_ON }, // RIGHTWARDS TRIANGLE-HEADED ARROW TO BAR + { 0x2B73, BIDI_ON }, // DOWNWARDS TRIANGLE-HEADED ARROW TO BAR + { 0x2B76, BIDI_ON }, // NORTH WEST TRIANGLE-HEADED ARROW TO BAR + { 0x2B77, BIDI_ON }, // NORTH EAST TRIANGLE-HEADED ARROW TO BAR + { 0x2B78, BIDI_ON }, // SOUTH EAST TRIANGLE-HEADED ARROW TO BAR + { 0x2B79, BIDI_ON }, // SOUTH WEST TRIANGLE-HEADED ARROW TO BAR + { 0x2B7A, BIDI_ON }, // LEFTWARDS TRIANGLE-HEADED ARROW WITH DOUBLE HORIZONTAL STROKE + { 0x2B7B, BIDI_ON }, // UPWARDS TRIANGLE-HEADED ARROW WITH DOUBLE HORIZONTAL STROKE + { 0x2B7C, BIDI_ON }, // RIGHTWARDS TRIANGLE-HEADED ARROW WITH DOUBLE HORIZONTAL STROKE + { 0x2B7D, BIDI_ON }, // DOWNWARDS TRIANGLE-HEADED ARROW WITH DOUBLE HORIZONTAL STROKE + { 0x2B7E, BIDI_ON }, // HORIZONTAL TAB KEY + { 0x2B7F, BIDI_ON }, // VERTICAL TAB KEY + { 0x2B80, BIDI_ON }, // LEFTWARDS TRIANGLE-HEADED ARROW OVER RIGHTWARDS TRIANGLE-HEADED ARROW + { 0x2B81, BIDI_ON }, // UPWARDS TRIANGLE-HEADED ARROW LEFTWARDS OF DOWNWARDS TRIANGLE-HEADED ARROW + { 0x2B82, BIDI_ON }, // RIGHTWARDS TRIANGLE-HEADED ARROW OVER LEFTWARDS TRIANGLE-HEADED ARROW + { 0x2B83, BIDI_ON }, // DOWNWARDS TRIANGLE-HEADED ARROW LEFTWARDS OF UPWARDS TRIANGLE-HEADED ARROW + { 0x2B84, BIDI_ON }, // LEFTWARDS TRIANGLE-HEADED PAIRED ARROWS + { 0x2B85, BIDI_ON }, // UPWARDS TRIANGLE-HEADED PAIRED ARROWS + { 0x2B86, BIDI_ON }, // RIGHTWARDS TRIANGLE-HEADED PAIRED ARROWS + { 0x2B87, BIDI_ON }, // DOWNWARDS TRIANGLE-HEADED PAIRED ARROWS + { 0x2B88, BIDI_ON }, // LEFTWARDS BLACK CIRCLED WHITE ARROW + { 0x2B89, BIDI_ON }, // UPWARDS BLACK CIRCLED WHITE ARROW + { 0x2B8A, BIDI_ON }, // RIGHTWARDS BLACK CIRCLED WHITE ARROW + { 0x2B8B, BIDI_ON }, // DOWNWARDS BLACK CIRCLED WHITE ARROW + { 0x2B8C, BIDI_ON }, // ANTICLOCKWISE TRIANGLE-HEADED RIGHT U-SHAPED ARROW + { 0x2B8D, BIDI_ON }, // ANTICLOCKWISE TRIANGLE-HEADED BOTTOM U-SHAPED ARROW + { 0x2B8E, BIDI_ON }, // ANTICLOCKWISE TRIANGLE-HEADED LEFT U-SHAPED ARROW + { 0x2B8F, BIDI_ON }, // ANTICLOCKWISE TRIANGLE-HEADED TOP U-SHAPED ARROW + { 0x2B90, BIDI_ON }, // RETURN LEFT + { 0x2B91, BIDI_ON }, // RETURN RIGHT + { 0x2B92, BIDI_ON }, // NEWLINE LEFT + { 0x2B93, BIDI_ON }, // NEWLINE RIGHT + { 0x2B94, BIDI_ON }, // FOUR CORNER ARROWS CIRCLING ANTICLOCKWISE + { 0x2B95, BIDI_ON }, // RIGHTWARDS BLACK ARROW + { 0x2B98, BIDI_ON }, // THREE-D TOP-LIGHTED LEFTWARDS EQUILATERAL ARROWHEAD + { 0x2B99, BIDI_ON }, // THREE-D RIGHT-LIGHTED UPWARDS EQUILATERAL ARROWHEAD + { 0x2B9A, BIDI_ON }, // THREE-D TOP-LIGHTED RIGHTWARDS EQUILATERAL ARROWHEAD + { 0x2B9B, BIDI_ON }, // THREE-D LEFT-LIGHTED DOWNWARDS EQUILATERAL ARROWHEAD + { 0x2B9C, BIDI_ON }, // BLACK LEFTWARDS EQUILATERAL ARROWHEAD + { 0x2B9D, BIDI_ON }, // BLACK UPWARDS EQUILATERAL ARROWHEAD + { 0x2B9E, BIDI_ON }, // BLACK RIGHTWARDS EQUILATERAL ARROWHEAD + { 0x2B9F, BIDI_ON }, // BLACK DOWNWARDS EQUILATERAL ARROWHEAD + { 0x2BA0, BIDI_ON }, // DOWNWARDS TRIANGLE-HEADED ARROW WITH LONG TIP LEFTWARDS + { 0x2BA1, BIDI_ON }, // DOWNWARDS TRIANGLE-HEADED ARROW WITH LONG TIP RIGHTWARDS + { 0x2BA2, BIDI_ON }, // UPWARDS TRIANGLE-HEADED ARROW WITH LONG TIP LEFTWARDS + { 0x2BA3, BIDI_ON }, // UPWARDS TRIANGLE-HEADED ARROW WITH LONG TIP RIGHTWARDS + { 0x2BA4, BIDI_ON }, // LEFTWARDS TRIANGLE-HEADED ARROW WITH LONG TIP UPWARDS + { 0x2BA5, BIDI_ON }, // RIGHTWARDS TRIANGLE-HEADED ARROW WITH LONG TIP UPWARDS + { 0x2BA6, BIDI_ON }, // LEFTWARDS TRIANGLE-HEADED ARROW WITH LONG TIP DOWNWARDS + { 0x2BA7, BIDI_ON }, // RIGHTWARDS TRIANGLE-HEADED ARROW WITH LONG TIP DOWNWARDS + { 0x2BA8, BIDI_ON }, // BLACK CURVED DOWNWARDS AND LEFTWARDS ARROW + { 0x2BA9, BIDI_ON }, // BLACK CURVED DOWNWARDS AND RIGHTWARDS ARROW + { 0x2BAA, BIDI_ON }, // BLACK CURVED UPWARDS AND LEFTWARDS ARROW + { 0x2BAB, BIDI_ON }, // BLACK CURVED UPWARDS AND RIGHTWARDS ARROW + { 0x2BAC, BIDI_ON }, // BLACK CURVED LEFTWARDS AND UPWARDS ARROW + { 0x2BAD, BIDI_ON }, // BLACK CURVED RIGHTWARDS AND UPWARDS ARROW + { 0x2BAE, BIDI_ON }, // BLACK CURVED LEFTWARDS AND DOWNWARDS ARROW + { 0x2BAF, BIDI_ON }, // BLACK CURVED RIGHTWARDS AND DOWNWARDS ARROW + { 0x2BB0, BIDI_ON }, // RIBBON ARROW DOWN LEFT + { 0x2BB1, BIDI_ON }, // RIBBON ARROW DOWN RIGHT + { 0x2BB2, BIDI_ON }, // RIBBON ARROW UP LEFT + { 0x2BB3, BIDI_ON }, // RIBBON ARROW UP RIGHT + { 0x2BB4, BIDI_ON }, // RIBBON ARROW LEFT UP + { 0x2BB5, BIDI_ON }, // RIBBON ARROW RIGHT UP + { 0x2BB6, BIDI_ON }, // RIBBON ARROW LEFT DOWN + { 0x2BB7, BIDI_ON }, // RIBBON ARROW RIGHT DOWN + { 0x2BB8, BIDI_ON }, // UPWARDS WHITE ARROW FROM BAR WITH HORIZONTAL BAR + { 0x2BB9, BIDI_ON }, // UP ARROWHEAD IN A RECTANGLE BOX + { 0x2BBD, BIDI_ON }, // BALLOT BOX WITH LIGHT X + { 0x2BBE, BIDI_ON }, // CIRCLED X + { 0x2BBF, BIDI_ON }, // CIRCLED BOLD X + { 0x2BC0, BIDI_ON }, // BLACK SQUARE CENTRED + { 0x2BC1, BIDI_ON }, // BLACK DIAMOND CENTRED + { 0x2BC2, BIDI_ON }, // TURNED BLACK PENTAGON + { 0x2BC3, BIDI_ON }, // HORIZONTAL BLACK OCTAGON + { 0x2BC4, BIDI_ON }, // BLACK OCTAGON + { 0x2BC5, BIDI_ON }, // BLACK MEDIUM UP-POINTING TRIANGLE CENTRED + { 0x2BC6, BIDI_ON }, // BLACK MEDIUM DOWN-POINTING TRIANGLE CENTRED + { 0x2BC7, BIDI_ON }, // BLACK MEDIUM LEFT-POINTING TRIANGLE CENTRED + { 0x2BC8, BIDI_ON }, // BLACK MEDIUM RIGHT-POINTING TRIANGLE CENTRED + { 0x2BCA, BIDI_ON }, // TOP HALF BLACK CIRCLE + { 0x2BCB, BIDI_ON }, // BOTTOM HALF BLACK CIRCLE + { 0x2BCC, BIDI_ON }, // LIGHT FOUR POINTED BLACK CUSP + { 0x2BCD, BIDI_ON }, // ROTATED LIGHT FOUR POINTED BLACK CUSP + { 0x2BCE, BIDI_ON }, // WHITE FOUR POINTED CUSP + { 0x2BCF, BIDI_ON }, // ROTATED WHITE FOUR POINTED CUSP + { 0x2BD0, BIDI_ON }, // SQUARE POSITION INDICATOR + { 0x2BD1, BIDI_ON }, // UNCERTAINTY SIGN + { 0x2BEC, BIDI_ON }, // LEFTWARDS TWO-HEADED ARROW WITH TRIANGLE ARROWHEADS + { 0x2BED, BIDI_ON }, // UPWARDS TWO-HEADED ARROW WITH TRIANGLE ARROWHEADS + { 0x2BEE, BIDI_ON }, // RIGHTWARDS TWO-HEADED ARROW WITH TRIANGLE ARROWHEADS + { 0x2BEF, BIDI_ON }, // DOWNWARDS TWO-HEADED ARROW WITH TRIANGLE ARROWHEADS + { 0x2C00, BIDI_L }, // GLAGOLITIC CAPITAL LETTER AZU + { 0x2C01, BIDI_L }, // GLAGOLITIC CAPITAL LETTER BUKY + { 0x2C02, BIDI_L }, // GLAGOLITIC CAPITAL LETTER VEDE + { 0x2C03, BIDI_L }, // GLAGOLITIC CAPITAL LETTER GLAGOLI + { 0x2C04, BIDI_L }, // GLAGOLITIC CAPITAL LETTER DOBRO + { 0x2C05, BIDI_L }, // GLAGOLITIC CAPITAL LETTER YESTU + { 0x2C06, BIDI_L }, // GLAGOLITIC CAPITAL LETTER ZHIVETE + { 0x2C07, BIDI_L }, // GLAGOLITIC CAPITAL LETTER DZELO + { 0x2C08, BIDI_L }, // GLAGOLITIC CAPITAL LETTER ZEMLJA + { 0x2C09, BIDI_L }, // GLAGOLITIC CAPITAL LETTER IZHE + { 0x2C0A, BIDI_L }, // GLAGOLITIC CAPITAL LETTER INITIAL IZHE + { 0x2C0B, BIDI_L }, // GLAGOLITIC CAPITAL LETTER I + { 0x2C0C, BIDI_L }, // GLAGOLITIC CAPITAL LETTER DJERVI + { 0x2C0D, BIDI_L }, // GLAGOLITIC CAPITAL LETTER KAKO + { 0x2C0E, BIDI_L }, // GLAGOLITIC CAPITAL LETTER LJUDIJE + { 0x2C0F, BIDI_L }, // GLAGOLITIC CAPITAL LETTER MYSLITE + { 0x2C10, BIDI_L }, // GLAGOLITIC CAPITAL LETTER NASHI + { 0x2C11, BIDI_L }, // GLAGOLITIC CAPITAL LETTER ONU + { 0x2C12, BIDI_L }, // GLAGOLITIC CAPITAL LETTER POKOJI + { 0x2C13, BIDI_L }, // GLAGOLITIC CAPITAL LETTER RITSI + { 0x2C14, BIDI_L }, // GLAGOLITIC CAPITAL LETTER SLOVO + { 0x2C15, BIDI_L }, // GLAGOLITIC CAPITAL LETTER TVRIDO + { 0x2C16, BIDI_L }, // GLAGOLITIC CAPITAL LETTER UKU + { 0x2C17, BIDI_L }, // GLAGOLITIC CAPITAL LETTER FRITU + { 0x2C18, BIDI_L }, // GLAGOLITIC CAPITAL LETTER HERU + { 0x2C19, BIDI_L }, // GLAGOLITIC CAPITAL LETTER OTU + { 0x2C1A, BIDI_L }, // GLAGOLITIC CAPITAL LETTER PE + { 0x2C1B, BIDI_L }, // GLAGOLITIC CAPITAL LETTER SHTA + { 0x2C1C, BIDI_L }, // GLAGOLITIC CAPITAL LETTER TSI + { 0x2C1D, BIDI_L }, // GLAGOLITIC CAPITAL LETTER CHRIVI + { 0x2C1E, BIDI_L }, // GLAGOLITIC CAPITAL LETTER SHA + { 0x2C1F, BIDI_L }, // GLAGOLITIC CAPITAL LETTER YERU + { 0x2C20, BIDI_L }, // GLAGOLITIC CAPITAL LETTER YERI + { 0x2C21, BIDI_L }, // GLAGOLITIC CAPITAL LETTER YATI + { 0x2C22, BIDI_L }, // GLAGOLITIC CAPITAL LETTER SPIDERY HA + { 0x2C23, BIDI_L }, // GLAGOLITIC CAPITAL LETTER YU + { 0x2C24, BIDI_L }, // GLAGOLITIC CAPITAL LETTER SMALL YUS + { 0x2C25, BIDI_L }, // GLAGOLITIC CAPITAL LETTER SMALL YUS WITH TAIL + { 0x2C26, BIDI_L }, // GLAGOLITIC CAPITAL LETTER YO + { 0x2C27, BIDI_L }, // GLAGOLITIC CAPITAL LETTER IOTATED SMALL YUS + { 0x2C28, BIDI_L }, // GLAGOLITIC CAPITAL LETTER BIG YUS + { 0x2C29, BIDI_L }, // GLAGOLITIC CAPITAL LETTER IOTATED BIG YUS + { 0x2C2A, BIDI_L }, // GLAGOLITIC CAPITAL LETTER FITA + { 0x2C2B, BIDI_L }, // GLAGOLITIC CAPITAL LETTER IZHITSA + { 0x2C2C, BIDI_L }, // GLAGOLITIC CAPITAL LETTER SHTAPIC + { 0x2C2D, BIDI_L }, // GLAGOLITIC CAPITAL LETTER TROKUTASTI A + { 0x2C2E, BIDI_L }, // GLAGOLITIC CAPITAL LETTER LATINATE MYSLITE + { 0x2C30, BIDI_L }, // GLAGOLITIC SMALL LETTER AZU + { 0x2C31, BIDI_L }, // GLAGOLITIC SMALL LETTER BUKY + { 0x2C32, BIDI_L }, // GLAGOLITIC SMALL LETTER VEDE + { 0x2C33, BIDI_L }, // GLAGOLITIC SMALL LETTER GLAGOLI + { 0x2C34, BIDI_L }, // GLAGOLITIC SMALL LETTER DOBRO + { 0x2C35, BIDI_L }, // GLAGOLITIC SMALL LETTER YESTU + { 0x2C36, BIDI_L }, // GLAGOLITIC SMALL LETTER ZHIVETE + { 0x2C37, BIDI_L }, // GLAGOLITIC SMALL LETTER DZELO + { 0x2C38, BIDI_L }, // GLAGOLITIC SMALL LETTER ZEMLJA + { 0x2C39, BIDI_L }, // GLAGOLITIC SMALL LETTER IZHE + { 0x2C3A, BIDI_L }, // GLAGOLITIC SMALL LETTER INITIAL IZHE + { 0x2C3B, BIDI_L }, // GLAGOLITIC SMALL LETTER I + { 0x2C3C, BIDI_L }, // GLAGOLITIC SMALL LETTER DJERVI + { 0x2C3D, BIDI_L }, // GLAGOLITIC SMALL LETTER KAKO + { 0x2C3E, BIDI_L }, // GLAGOLITIC SMALL LETTER LJUDIJE + { 0x2C3F, BIDI_L }, // GLAGOLITIC SMALL LETTER MYSLITE + { 0x2C40, BIDI_L }, // GLAGOLITIC SMALL LETTER NASHI + { 0x2C41, BIDI_L }, // GLAGOLITIC SMALL LETTER ONU + { 0x2C42, BIDI_L }, // GLAGOLITIC SMALL LETTER POKOJI + { 0x2C43, BIDI_L }, // GLAGOLITIC SMALL LETTER RITSI + { 0x2C44, BIDI_L }, // GLAGOLITIC SMALL LETTER SLOVO + { 0x2C45, BIDI_L }, // GLAGOLITIC SMALL LETTER TVRIDO + { 0x2C46, BIDI_L }, // GLAGOLITIC SMALL LETTER UKU + { 0x2C47, BIDI_L }, // GLAGOLITIC SMALL LETTER FRITU + { 0x2C48, BIDI_L }, // GLAGOLITIC SMALL LETTER HERU + { 0x2C49, BIDI_L }, // GLAGOLITIC SMALL LETTER OTU + { 0x2C4A, BIDI_L }, // GLAGOLITIC SMALL LETTER PE + { 0x2C4B, BIDI_L }, // GLAGOLITIC SMALL LETTER SHTA + { 0x2C4C, BIDI_L }, // GLAGOLITIC SMALL LETTER TSI + { 0x2C4D, BIDI_L }, // GLAGOLITIC SMALL LETTER CHRIVI + { 0x2C4E, BIDI_L }, // GLAGOLITIC SMALL LETTER SHA + { 0x2C4F, BIDI_L }, // GLAGOLITIC SMALL LETTER YERU + { 0x2C50, BIDI_L }, // GLAGOLITIC SMALL LETTER YERI + { 0x2C51, BIDI_L }, // GLAGOLITIC SMALL LETTER YATI + { 0x2C52, BIDI_L }, // GLAGOLITIC SMALL LETTER SPIDERY HA + { 0x2C53, BIDI_L }, // GLAGOLITIC SMALL LETTER YU + { 0x2C54, BIDI_L }, // GLAGOLITIC SMALL LETTER SMALL YUS + { 0x2C55, BIDI_L }, // GLAGOLITIC SMALL LETTER SMALL YUS WITH TAIL + { 0x2C56, BIDI_L }, // GLAGOLITIC SMALL LETTER YO + { 0x2C57, BIDI_L }, // GLAGOLITIC SMALL LETTER IOTATED SMALL YUS + { 0x2C58, BIDI_L }, // GLAGOLITIC SMALL LETTER BIG YUS + { 0x2C59, BIDI_L }, // GLAGOLITIC SMALL LETTER IOTATED BIG YUS + { 0x2C5A, BIDI_L }, // GLAGOLITIC SMALL LETTER FITA + { 0x2C5B, BIDI_L }, // GLAGOLITIC SMALL LETTER IZHITSA + { 0x2C5C, BIDI_L }, // GLAGOLITIC SMALL LETTER SHTAPIC + { 0x2C5D, BIDI_L }, // GLAGOLITIC SMALL LETTER TROKUTASTI A + { 0x2C5E, BIDI_L }, // GLAGOLITIC SMALL LETTER LATINATE MYSLITE + { 0x2C60, BIDI_L }, // LATIN CAPITAL LETTER L WITH DOUBLE BAR + { 0x2C61, BIDI_L }, // LATIN SMALL LETTER L WITH DOUBLE BAR + { 0x2C62, BIDI_L }, // LATIN CAPITAL LETTER L WITH MIDDLE TILDE + { 0x2C63, BIDI_L }, // LATIN CAPITAL LETTER P WITH STROKE + { 0x2C64, BIDI_L }, // LATIN CAPITAL LETTER R WITH TAIL + { 0x2C65, BIDI_L }, // LATIN SMALL LETTER A WITH STROKE + { 0x2C66, BIDI_L }, // LATIN SMALL LETTER T WITH DIAGONAL STROKE + { 0x2C67, BIDI_L }, // LATIN CAPITAL LETTER H WITH DESCENDER + { 0x2C68, BIDI_L }, // LATIN SMALL LETTER H WITH DESCENDER + { 0x2C69, BIDI_L }, // LATIN CAPITAL LETTER K WITH DESCENDER + { 0x2C6A, BIDI_L }, // LATIN SMALL LETTER K WITH DESCENDER + { 0x2C6B, BIDI_L }, // LATIN CAPITAL LETTER Z WITH DESCENDER + { 0x2C6C, BIDI_L }, // LATIN SMALL LETTER Z WITH DESCENDER + { 0x2C6D, BIDI_L }, // LATIN CAPITAL LETTER ALPHA + { 0x2C6E, BIDI_L }, // LATIN CAPITAL LETTER M WITH HOOK + { 0x2C6F, BIDI_L }, // LATIN CAPITAL LETTER TURNED A + { 0x2C70, BIDI_L }, // LATIN CAPITAL LETTER TURNED ALPHA + { 0x2C71, BIDI_L }, // LATIN SMALL LETTER V WITH RIGHT HOOK + { 0x2C72, BIDI_L }, // LATIN CAPITAL LETTER W WITH HOOK + { 0x2C73, BIDI_L }, // LATIN SMALL LETTER W WITH HOOK + { 0x2C74, BIDI_L }, // LATIN SMALL LETTER V WITH CURL + { 0x2C75, BIDI_L }, // LATIN CAPITAL LETTER HALF H + { 0x2C76, BIDI_L }, // LATIN SMALL LETTER HALF H + { 0x2C77, BIDI_L }, // LATIN SMALL LETTER TAILLESS PHI + { 0x2C78, BIDI_L }, // LATIN SMALL LETTER E WITH NOTCH + { 0x2C79, BIDI_L }, // LATIN SMALL LETTER TURNED R WITH TAIL + { 0x2C7A, BIDI_L }, // LATIN SMALL LETTER O WITH LOW RING INSIDE + { 0x2C7B, BIDI_L }, // LATIN LETTER SMALL CAPITAL TURNED E + { 0x2C7C, BIDI_L }, // LATIN SUBSCRIPT SMALL LETTER J + { 0x2C7D, BIDI_L }, // MODIFIER LETTER CAPITAL V + { 0x2C7E, BIDI_L }, // LATIN CAPITAL LETTER S WITH SWASH TAIL + { 0x2C7F, BIDI_L }, // LATIN CAPITAL LETTER Z WITH SWASH TAIL + { 0x2C80, BIDI_L }, // COPTIC CAPITAL LETTER ALFA + { 0x2C81, BIDI_L }, // COPTIC SMALL LETTER ALFA + { 0x2C82, BIDI_L }, // COPTIC CAPITAL LETTER VIDA + { 0x2C83, BIDI_L }, // COPTIC SMALL LETTER VIDA + { 0x2C84, BIDI_L }, // COPTIC CAPITAL LETTER GAMMA + { 0x2C85, BIDI_L }, // COPTIC SMALL LETTER GAMMA + { 0x2C86, BIDI_L }, // COPTIC CAPITAL LETTER DALDA + { 0x2C87, BIDI_L }, // COPTIC SMALL LETTER DALDA + { 0x2C88, BIDI_L }, // COPTIC CAPITAL LETTER EIE + { 0x2C89, BIDI_L }, // COPTIC SMALL LETTER EIE + { 0x2C8A, BIDI_L }, // COPTIC CAPITAL LETTER SOU + { 0x2C8B, BIDI_L }, // COPTIC SMALL LETTER SOU + { 0x2C8C, BIDI_L }, // COPTIC CAPITAL LETTER ZATA + { 0x2C8D, BIDI_L }, // COPTIC SMALL LETTER ZATA + { 0x2C8E, BIDI_L }, // COPTIC CAPITAL LETTER HATE + { 0x2C8F, BIDI_L }, // COPTIC SMALL LETTER HATE + { 0x2C90, BIDI_L }, // COPTIC CAPITAL LETTER THETHE + { 0x2C91, BIDI_L }, // COPTIC SMALL LETTER THETHE + { 0x2C92, BIDI_L }, // COPTIC CAPITAL LETTER IAUDA + { 0x2C93, BIDI_L }, // COPTIC SMALL LETTER IAUDA + { 0x2C94, BIDI_L }, // COPTIC CAPITAL LETTER KAPA + { 0x2C95, BIDI_L }, // COPTIC SMALL LETTER KAPA + { 0x2C96, BIDI_L }, // COPTIC CAPITAL LETTER LAULA + { 0x2C97, BIDI_L }, // COPTIC SMALL LETTER LAULA + { 0x2C98, BIDI_L }, // COPTIC CAPITAL LETTER MI + { 0x2C99, BIDI_L }, // COPTIC SMALL LETTER MI + { 0x2C9A, BIDI_L }, // COPTIC CAPITAL LETTER NI + { 0x2C9B, BIDI_L }, // COPTIC SMALL LETTER NI + { 0x2C9C, BIDI_L }, // COPTIC CAPITAL LETTER KSI + { 0x2C9D, BIDI_L }, // COPTIC SMALL LETTER KSI + { 0x2C9E, BIDI_L }, // COPTIC CAPITAL LETTER O + { 0x2C9F, BIDI_L }, // COPTIC SMALL LETTER O + { 0x2CA0, BIDI_L }, // COPTIC CAPITAL LETTER PI + { 0x2CA1, BIDI_L }, // COPTIC SMALL LETTER PI + { 0x2CA2, BIDI_L }, // COPTIC CAPITAL LETTER RO + { 0x2CA3, BIDI_L }, // COPTIC SMALL LETTER RO + { 0x2CA4, BIDI_L }, // COPTIC CAPITAL LETTER SIMA + { 0x2CA5, BIDI_L }, // COPTIC SMALL LETTER SIMA + { 0x2CA6, BIDI_L }, // COPTIC CAPITAL LETTER TAU + { 0x2CA7, BIDI_L }, // COPTIC SMALL LETTER TAU + { 0x2CA8, BIDI_L }, // COPTIC CAPITAL LETTER UA + { 0x2CA9, BIDI_L }, // COPTIC SMALL LETTER UA + { 0x2CAA, BIDI_L }, // COPTIC CAPITAL LETTER FI + { 0x2CAB, BIDI_L }, // COPTIC SMALL LETTER FI + { 0x2CAC, BIDI_L }, // COPTIC CAPITAL LETTER KHI + { 0x2CAD, BIDI_L }, // COPTIC SMALL LETTER KHI + { 0x2CAE, BIDI_L }, // COPTIC CAPITAL LETTER PSI + { 0x2CAF, BIDI_L }, // COPTIC SMALL LETTER PSI + { 0x2CB0, BIDI_L }, // COPTIC CAPITAL LETTER OOU + { 0x2CB1, BIDI_L }, // COPTIC SMALL LETTER OOU + { 0x2CB2, BIDI_L }, // COPTIC CAPITAL LETTER DIALECT-P ALEF + { 0x2CB3, BIDI_L }, // COPTIC SMALL LETTER DIALECT-P ALEF + { 0x2CB4, BIDI_L }, // COPTIC CAPITAL LETTER OLD COPTIC AIN + { 0x2CB5, BIDI_L }, // COPTIC SMALL LETTER OLD COPTIC AIN + { 0x2CB6, BIDI_L }, // COPTIC CAPITAL LETTER CRYPTOGRAMMIC EIE + { 0x2CB7, BIDI_L }, // COPTIC SMALL LETTER CRYPTOGRAMMIC EIE + { 0x2CB8, BIDI_L }, // COPTIC CAPITAL LETTER DIALECT-P KAPA + { 0x2CB9, BIDI_L }, // COPTIC SMALL LETTER DIALECT-P KAPA + { 0x2CBA, BIDI_L }, // COPTIC CAPITAL LETTER DIALECT-P NI + { 0x2CBB, BIDI_L }, // COPTIC SMALL LETTER DIALECT-P NI + { 0x2CBC, BIDI_L }, // COPTIC CAPITAL LETTER CRYPTOGRAMMIC NI + { 0x2CBD, BIDI_L }, // COPTIC SMALL LETTER CRYPTOGRAMMIC NI + { 0x2CBE, BIDI_L }, // COPTIC CAPITAL LETTER OLD COPTIC OOU + { 0x2CBF, BIDI_L }, // COPTIC SMALL LETTER OLD COPTIC OOU + { 0x2CC0, BIDI_L }, // COPTIC CAPITAL LETTER SAMPI + { 0x2CC1, BIDI_L }, // COPTIC SMALL LETTER SAMPI + { 0x2CC2, BIDI_L }, // COPTIC CAPITAL LETTER CROSSED SHEI + { 0x2CC3, BIDI_L }, // COPTIC SMALL LETTER CROSSED SHEI + { 0x2CC4, BIDI_L }, // COPTIC CAPITAL LETTER OLD COPTIC SHEI + { 0x2CC5, BIDI_L }, // COPTIC SMALL LETTER OLD COPTIC SHEI + { 0x2CC6, BIDI_L }, // COPTIC CAPITAL LETTER OLD COPTIC ESH + { 0x2CC7, BIDI_L }, // COPTIC SMALL LETTER OLD COPTIC ESH + { 0x2CC8, BIDI_L }, // COPTIC CAPITAL LETTER AKHMIMIC KHEI + { 0x2CC9, BIDI_L }, // COPTIC SMALL LETTER AKHMIMIC KHEI + { 0x2CCA, BIDI_L }, // COPTIC CAPITAL LETTER DIALECT-P HORI + { 0x2CCB, BIDI_L }, // COPTIC SMALL LETTER DIALECT-P HORI + { 0x2CCC, BIDI_L }, // COPTIC CAPITAL LETTER OLD COPTIC HORI + { 0x2CCD, BIDI_L }, // COPTIC SMALL LETTER OLD COPTIC HORI + { 0x2CCE, BIDI_L }, // COPTIC CAPITAL LETTER OLD COPTIC HA + { 0x2CCF, BIDI_L }, // COPTIC SMALL LETTER OLD COPTIC HA + { 0x2CD0, BIDI_L }, // COPTIC CAPITAL LETTER L-SHAPED HA + { 0x2CD1, BIDI_L }, // COPTIC SMALL LETTER L-SHAPED HA + { 0x2CD2, BIDI_L }, // COPTIC CAPITAL LETTER OLD COPTIC HEI + { 0x2CD3, BIDI_L }, // COPTIC SMALL LETTER OLD COPTIC HEI + { 0x2CD4, BIDI_L }, // COPTIC CAPITAL LETTER OLD COPTIC HAT + { 0x2CD5, BIDI_L }, // COPTIC SMALL LETTER OLD COPTIC HAT + { 0x2CD6, BIDI_L }, // COPTIC CAPITAL LETTER OLD COPTIC GANGIA + { 0x2CD7, BIDI_L }, // COPTIC SMALL LETTER OLD COPTIC GANGIA + { 0x2CD8, BIDI_L }, // COPTIC CAPITAL LETTER OLD COPTIC DJA + { 0x2CD9, BIDI_L }, // COPTIC SMALL LETTER OLD COPTIC DJA + { 0x2CDA, BIDI_L }, // COPTIC CAPITAL LETTER OLD COPTIC SHIMA + { 0x2CDB, BIDI_L }, // COPTIC SMALL LETTER OLD COPTIC SHIMA + { 0x2CDC, BIDI_L }, // COPTIC CAPITAL LETTER OLD NUBIAN SHIMA + { 0x2CDD, BIDI_L }, // COPTIC SMALL LETTER OLD NUBIAN SHIMA + { 0x2CDE, BIDI_L }, // COPTIC CAPITAL LETTER OLD NUBIAN NGI + { 0x2CDF, BIDI_L }, // COPTIC SMALL LETTER OLD NUBIAN NGI + { 0x2CE0, BIDI_L }, // COPTIC CAPITAL LETTER OLD NUBIAN NYI + { 0x2CE1, BIDI_L }, // COPTIC SMALL LETTER OLD NUBIAN NYI + { 0x2CE2, BIDI_L }, // COPTIC CAPITAL LETTER OLD NUBIAN WAU + { 0x2CE3, BIDI_L }, // COPTIC SMALL LETTER OLD NUBIAN WAU + { 0x2CE4, BIDI_L }, // COPTIC SYMBOL KAI + { 0x2CE5, BIDI_ON }, // COPTIC SYMBOL MI RO + { 0x2CE6, BIDI_ON }, // COPTIC SYMBOL PI RO + { 0x2CE7, BIDI_ON }, // COPTIC SYMBOL STAUROS + { 0x2CE8, BIDI_ON }, // COPTIC SYMBOL TAU RO + { 0x2CE9, BIDI_ON }, // COPTIC SYMBOL KHI RO + { 0x2CEA, BIDI_ON }, // COPTIC SYMBOL SHIMA SIMA + { 0x2CEB, BIDI_L }, // COPTIC CAPITAL LETTER CRYPTOGRAMMIC SHEI + { 0x2CEC, BIDI_L }, // COPTIC SMALL LETTER CRYPTOGRAMMIC SHEI + { 0x2CED, BIDI_L }, // COPTIC CAPITAL LETTER CRYPTOGRAMMIC GANGIA + { 0x2CEE, BIDI_L }, // COPTIC SMALL LETTER CRYPTOGRAMMIC GANGIA + { 0x2CEF, BIDI_NSM }, // COPTIC COMBINING NI ABOVE + { 0x2CF0, BIDI_NSM }, // COPTIC COMBINING SPIRITUS ASPER + { 0x2CF1, BIDI_NSM }, // COPTIC COMBINING SPIRITUS LENIS + { 0x2CF2, BIDI_L }, // COPTIC CAPITAL LETTER BOHAIRIC KHEI + { 0x2CF3, BIDI_L }, // COPTIC SMALL LETTER BOHAIRIC KHEI + { 0x2CF9, BIDI_ON }, // COPTIC OLD NUBIAN FULL STOP + { 0x2CFA, BIDI_ON }, // COPTIC OLD NUBIAN DIRECT QUESTION MARK + { 0x2CFB, BIDI_ON }, // COPTIC OLD NUBIAN INDIRECT QUESTION MARK + { 0x2CFC, BIDI_ON }, // COPTIC OLD NUBIAN VERSE DIVIDER + { 0x2CFD, BIDI_ON }, // COPTIC FRACTION ONE HALF + { 0x2CFE, BIDI_ON }, // COPTIC FULL STOP + { 0x2CFF, BIDI_ON }, // COPTIC MORPHOLOGICAL DIVIDER + { 0x2D00, BIDI_L }, // GEORGIAN SMALL LETTER AN + { 0x2D01, BIDI_L }, // GEORGIAN SMALL LETTER BAN + { 0x2D02, BIDI_L }, // GEORGIAN SMALL LETTER GAN + { 0x2D03, BIDI_L }, // GEORGIAN SMALL LETTER DON + { 0x2D04, BIDI_L }, // GEORGIAN SMALL LETTER EN + { 0x2D05, BIDI_L }, // GEORGIAN SMALL LETTER VIN + { 0x2D06, BIDI_L }, // GEORGIAN SMALL LETTER ZEN + { 0x2D07, BIDI_L }, // GEORGIAN SMALL LETTER TAN + { 0x2D08, BIDI_L }, // GEORGIAN SMALL LETTER IN + { 0x2D09, BIDI_L }, // GEORGIAN SMALL LETTER KAN + { 0x2D0A, BIDI_L }, // GEORGIAN SMALL LETTER LAS + { 0x2D0B, BIDI_L }, // GEORGIAN SMALL LETTER MAN + { 0x2D0C, BIDI_L }, // GEORGIAN SMALL LETTER NAR + { 0x2D0D, BIDI_L }, // GEORGIAN SMALL LETTER ON + { 0x2D0E, BIDI_L }, // GEORGIAN SMALL LETTER PAR + { 0x2D0F, BIDI_L }, // GEORGIAN SMALL LETTER ZHAR + { 0x2D10, BIDI_L }, // GEORGIAN SMALL LETTER RAE + { 0x2D11, BIDI_L }, // GEORGIAN SMALL LETTER SAN + { 0x2D12, BIDI_L }, // GEORGIAN SMALL LETTER TAR + { 0x2D13, BIDI_L }, // GEORGIAN SMALL LETTER UN + { 0x2D14, BIDI_L }, // GEORGIAN SMALL LETTER PHAR + { 0x2D15, BIDI_L }, // GEORGIAN SMALL LETTER KHAR + { 0x2D16, BIDI_L }, // GEORGIAN SMALL LETTER GHAN + { 0x2D17, BIDI_L }, // GEORGIAN SMALL LETTER QAR + { 0x2D18, BIDI_L }, // GEORGIAN SMALL LETTER SHIN + { 0x2D19, BIDI_L }, // GEORGIAN SMALL LETTER CHIN + { 0x2D1A, BIDI_L }, // GEORGIAN SMALL LETTER CAN + { 0x2D1B, BIDI_L }, // GEORGIAN SMALL LETTER JIL + { 0x2D1C, BIDI_L }, // GEORGIAN SMALL LETTER CIL + { 0x2D1D, BIDI_L }, // GEORGIAN SMALL LETTER CHAR + { 0x2D1E, BIDI_L }, // GEORGIAN SMALL LETTER XAN + { 0x2D1F, BIDI_L }, // GEORGIAN SMALL LETTER JHAN + { 0x2D20, BIDI_L }, // GEORGIAN SMALL LETTER HAE + { 0x2D21, BIDI_L }, // GEORGIAN SMALL LETTER HE + { 0x2D22, BIDI_L }, // GEORGIAN SMALL LETTER HIE + { 0x2D23, BIDI_L }, // GEORGIAN SMALL LETTER WE + { 0x2D24, BIDI_L }, // GEORGIAN SMALL LETTER HAR + { 0x2D25, BIDI_L }, // GEORGIAN SMALL LETTER HOE + { 0x2D27, BIDI_L }, // GEORGIAN SMALL LETTER YN + { 0x2D2D, BIDI_L }, // GEORGIAN SMALL LETTER AEN + { 0x2D30, BIDI_L }, // TIFINAGH LETTER YA + { 0x2D31, BIDI_L }, // TIFINAGH LETTER YAB + { 0x2D32, BIDI_L }, // TIFINAGH LETTER YABH + { 0x2D33, BIDI_L }, // TIFINAGH LETTER YAG + { 0x2D34, BIDI_L }, // TIFINAGH LETTER YAGHH + { 0x2D35, BIDI_L }, // TIFINAGH LETTER BERBER ACADEMY YAJ + { 0x2D36, BIDI_L }, // TIFINAGH LETTER YAJ + { 0x2D37, BIDI_L }, // TIFINAGH LETTER YAD + { 0x2D38, BIDI_L }, // TIFINAGH LETTER YADH + { 0x2D39, BIDI_L }, // TIFINAGH LETTER YADD + { 0x2D3A, BIDI_L }, // TIFINAGH LETTER YADDH + { 0x2D3B, BIDI_L }, // TIFINAGH LETTER YEY + { 0x2D3C, BIDI_L }, // TIFINAGH LETTER YAF + { 0x2D3D, BIDI_L }, // TIFINAGH LETTER YAK + { 0x2D3E, BIDI_L }, // TIFINAGH LETTER TUAREG YAK + { 0x2D3F, BIDI_L }, // TIFINAGH LETTER YAKHH + { 0x2D40, BIDI_L }, // TIFINAGH LETTER YAH + { 0x2D41, BIDI_L }, // TIFINAGH LETTER BERBER ACADEMY YAH + { 0x2D42, BIDI_L }, // TIFINAGH LETTER TUAREG YAH + { 0x2D43, BIDI_L }, // TIFINAGH LETTER YAHH + { 0x2D44, BIDI_L }, // TIFINAGH LETTER YAA + { 0x2D45, BIDI_L }, // TIFINAGH LETTER YAKH + { 0x2D46, BIDI_L }, // TIFINAGH LETTER TUAREG YAKH + { 0x2D47, BIDI_L }, // TIFINAGH LETTER YAQ + { 0x2D48, BIDI_L }, // TIFINAGH LETTER TUAREG YAQ + { 0x2D49, BIDI_L }, // TIFINAGH LETTER YI + { 0x2D4A, BIDI_L }, // TIFINAGH LETTER YAZH + { 0x2D4B, BIDI_L }, // TIFINAGH LETTER AHAGGAR YAZH + { 0x2D4C, BIDI_L }, // TIFINAGH LETTER TUAREG YAZH + { 0x2D4D, BIDI_L }, // TIFINAGH LETTER YAL + { 0x2D4E, BIDI_L }, // TIFINAGH LETTER YAM + { 0x2D4F, BIDI_L }, // TIFINAGH LETTER YAN + { 0x2D50, BIDI_L }, // TIFINAGH LETTER TUAREG YAGN + { 0x2D51, BIDI_L }, // TIFINAGH LETTER TUAREG YANG + { 0x2D52, BIDI_L }, // TIFINAGH LETTER YAP + { 0x2D53, BIDI_L }, // TIFINAGH LETTER YU + { 0x2D54, BIDI_L }, // TIFINAGH LETTER YAR + { 0x2D55, BIDI_L }, // TIFINAGH LETTER YARR + { 0x2D56, BIDI_L }, // TIFINAGH LETTER YAGH + { 0x2D57, BIDI_L }, // TIFINAGH LETTER TUAREG YAGH + { 0x2D58, BIDI_L }, // TIFINAGH LETTER AYER YAGH + { 0x2D59, BIDI_L }, // TIFINAGH LETTER YAS + { 0x2D5A, BIDI_L }, // TIFINAGH LETTER YASS + { 0x2D5B, BIDI_L }, // TIFINAGH LETTER YASH + { 0x2D5C, BIDI_L }, // TIFINAGH LETTER YAT + { 0x2D5D, BIDI_L }, // TIFINAGH LETTER YATH + { 0x2D5E, BIDI_L }, // TIFINAGH LETTER YACH + { 0x2D5F, BIDI_L }, // TIFINAGH LETTER YATT + { 0x2D60, BIDI_L }, // TIFINAGH LETTER YAV + { 0x2D61, BIDI_L }, // TIFINAGH LETTER YAW + { 0x2D62, BIDI_L }, // TIFINAGH LETTER YAY + { 0x2D63, BIDI_L }, // TIFINAGH LETTER YAZ + { 0x2D64, BIDI_L }, // TIFINAGH LETTER TAWELLEMET YAZ + { 0x2D65, BIDI_L }, // TIFINAGH LETTER YAZZ + { 0x2D66, BIDI_L }, // TIFINAGH LETTER YE + { 0x2D67, BIDI_L }, // TIFINAGH LETTER YO + { 0x2D6F, BIDI_L }, // TIFINAGH MODIFIER LETTER LABIALIZATION MARK + { 0x2D70, BIDI_L }, // TIFINAGH SEPARATOR MARK + { 0x2D7F, BIDI_NSM }, // TIFINAGH CONSONANT JOINER + { 0x2D80, BIDI_L }, // ETHIOPIC SYLLABLE LOA + { 0x2D81, BIDI_L }, // ETHIOPIC SYLLABLE MOA + { 0x2D82, BIDI_L }, // ETHIOPIC SYLLABLE ROA + { 0x2D83, BIDI_L }, // ETHIOPIC SYLLABLE SOA + { 0x2D84, BIDI_L }, // ETHIOPIC SYLLABLE SHOA + { 0x2D85, BIDI_L }, // ETHIOPIC SYLLABLE BOA + { 0x2D86, BIDI_L }, // ETHIOPIC SYLLABLE TOA + { 0x2D87, BIDI_L }, // ETHIOPIC SYLLABLE COA + { 0x2D88, BIDI_L }, // ETHIOPIC SYLLABLE NOA + { 0x2D89, BIDI_L }, // ETHIOPIC SYLLABLE NYOA + { 0x2D8A, BIDI_L }, // ETHIOPIC SYLLABLE GLOTTAL OA + { 0x2D8B, BIDI_L }, // ETHIOPIC SYLLABLE ZOA + { 0x2D8C, BIDI_L }, // ETHIOPIC SYLLABLE DOA + { 0x2D8D, BIDI_L }, // ETHIOPIC SYLLABLE DDOA + { 0x2D8E, BIDI_L }, // ETHIOPIC SYLLABLE JOA + { 0x2D8F, BIDI_L }, // ETHIOPIC SYLLABLE THOA + { 0x2D90, BIDI_L }, // ETHIOPIC SYLLABLE CHOA + { 0x2D91, BIDI_L }, // ETHIOPIC SYLLABLE PHOA + { 0x2D92, BIDI_L }, // ETHIOPIC SYLLABLE POA + { 0x2D93, BIDI_L }, // ETHIOPIC SYLLABLE GGWA + { 0x2D94, BIDI_L }, // ETHIOPIC SYLLABLE GGWI + { 0x2D95, BIDI_L }, // ETHIOPIC SYLLABLE GGWEE + { 0x2D96, BIDI_L }, // ETHIOPIC SYLLABLE GGWE + { 0x2DA0, BIDI_L }, // ETHIOPIC SYLLABLE SSA + { 0x2DA1, BIDI_L }, // ETHIOPIC SYLLABLE SSU + { 0x2DA2, BIDI_L }, // ETHIOPIC SYLLABLE SSI + { 0x2DA3, BIDI_L }, // ETHIOPIC SYLLABLE SSAA + { 0x2DA4, BIDI_L }, // ETHIOPIC SYLLABLE SSEE + { 0x2DA5, BIDI_L }, // ETHIOPIC SYLLABLE SSE + { 0x2DA6, BIDI_L }, // ETHIOPIC SYLLABLE SSO + { 0x2DA8, BIDI_L }, // ETHIOPIC SYLLABLE CCA + { 0x2DA9, BIDI_L }, // ETHIOPIC SYLLABLE CCU + { 0x2DAA, BIDI_L }, // ETHIOPIC SYLLABLE CCI + { 0x2DAB, BIDI_L }, // ETHIOPIC SYLLABLE CCAA + { 0x2DAC, BIDI_L }, // ETHIOPIC SYLLABLE CCEE + { 0x2DAD, BIDI_L }, // ETHIOPIC SYLLABLE CCE + { 0x2DAE, BIDI_L }, // ETHIOPIC SYLLABLE CCO + { 0x2DB0, BIDI_L }, // ETHIOPIC SYLLABLE ZZA + { 0x2DB1, BIDI_L }, // ETHIOPIC SYLLABLE ZZU + { 0x2DB2, BIDI_L }, // ETHIOPIC SYLLABLE ZZI + { 0x2DB3, BIDI_L }, // ETHIOPIC SYLLABLE ZZAA + { 0x2DB4, BIDI_L }, // ETHIOPIC SYLLABLE ZZEE + { 0x2DB5, BIDI_L }, // ETHIOPIC SYLLABLE ZZE + { 0x2DB6, BIDI_L }, // ETHIOPIC SYLLABLE ZZO + { 0x2DB8, BIDI_L }, // ETHIOPIC SYLLABLE CCHA + { 0x2DB9, BIDI_L }, // ETHIOPIC SYLLABLE CCHU + { 0x2DBA, BIDI_L }, // ETHIOPIC SYLLABLE CCHI + { 0x2DBB, BIDI_L }, // ETHIOPIC SYLLABLE CCHAA + { 0x2DBC, BIDI_L }, // ETHIOPIC SYLLABLE CCHEE + { 0x2DBD, BIDI_L }, // ETHIOPIC SYLLABLE CCHE + { 0x2DBE, BIDI_L }, // ETHIOPIC SYLLABLE CCHO + { 0x2DC0, BIDI_L }, // ETHIOPIC SYLLABLE QYA + { 0x2DC1, BIDI_L }, // ETHIOPIC SYLLABLE QYU + { 0x2DC2, BIDI_L }, // ETHIOPIC SYLLABLE QYI + { 0x2DC3, BIDI_L }, // ETHIOPIC SYLLABLE QYAA + { 0x2DC4, BIDI_L }, // ETHIOPIC SYLLABLE QYEE + { 0x2DC5, BIDI_L }, // ETHIOPIC SYLLABLE QYE + { 0x2DC6, BIDI_L }, // ETHIOPIC SYLLABLE QYO + { 0x2DC8, BIDI_L }, // ETHIOPIC SYLLABLE KYA + { 0x2DC9, BIDI_L }, // ETHIOPIC SYLLABLE KYU + { 0x2DCA, BIDI_L }, // ETHIOPIC SYLLABLE KYI + { 0x2DCB, BIDI_L }, // ETHIOPIC SYLLABLE KYAA + { 0x2DCC, BIDI_L }, // ETHIOPIC SYLLABLE KYEE + { 0x2DCD, BIDI_L }, // ETHIOPIC SYLLABLE KYE + { 0x2DCE, BIDI_L }, // ETHIOPIC SYLLABLE KYO + { 0x2DD0, BIDI_L }, // ETHIOPIC SYLLABLE XYA + { 0x2DD1, BIDI_L }, // ETHIOPIC SYLLABLE XYU + { 0x2DD2, BIDI_L }, // ETHIOPIC SYLLABLE XYI + { 0x2DD3, BIDI_L }, // ETHIOPIC SYLLABLE XYAA + { 0x2DD4, BIDI_L }, // ETHIOPIC SYLLABLE XYEE + { 0x2DD5, BIDI_L }, // ETHIOPIC SYLLABLE XYE + { 0x2DD6, BIDI_L }, // ETHIOPIC SYLLABLE XYO + { 0x2DD8, BIDI_L }, // ETHIOPIC SYLLABLE GYA + { 0x2DD9, BIDI_L }, // ETHIOPIC SYLLABLE GYU + { 0x2DDA, BIDI_L }, // ETHIOPIC SYLLABLE GYI + { 0x2DDB, BIDI_L }, // ETHIOPIC SYLLABLE GYAA + { 0x2DDC, BIDI_L }, // ETHIOPIC SYLLABLE GYEE + { 0x2DDD, BIDI_L }, // ETHIOPIC SYLLABLE GYE + { 0x2DDE, BIDI_L }, // ETHIOPIC SYLLABLE GYO + { 0x2DE0, BIDI_NSM }, // COMBINING CYRILLIC LETTER BE + { 0x2DE1, BIDI_NSM }, // COMBINING CYRILLIC LETTER VE + { 0x2DE2, BIDI_NSM }, // COMBINING CYRILLIC LETTER GHE + { 0x2DE3, BIDI_NSM }, // COMBINING CYRILLIC LETTER DE + { 0x2DE4, BIDI_NSM }, // COMBINING CYRILLIC LETTER ZHE + { 0x2DE5, BIDI_NSM }, // COMBINING CYRILLIC LETTER ZE + { 0x2DE6, BIDI_NSM }, // COMBINING CYRILLIC LETTER KA + { 0x2DE7, BIDI_NSM }, // COMBINING CYRILLIC LETTER EL + { 0x2DE8, BIDI_NSM }, // COMBINING CYRILLIC LETTER EM + { 0x2DE9, BIDI_NSM }, // COMBINING CYRILLIC LETTER EN + { 0x2DEA, BIDI_NSM }, // COMBINING CYRILLIC LETTER O + { 0x2DEB, BIDI_NSM }, // COMBINING CYRILLIC LETTER PE + { 0x2DEC, BIDI_NSM }, // COMBINING CYRILLIC LETTER ER + { 0x2DED, BIDI_NSM }, // COMBINING CYRILLIC LETTER ES + { 0x2DEE, BIDI_NSM }, // COMBINING CYRILLIC LETTER TE + { 0x2DEF, BIDI_NSM }, // COMBINING CYRILLIC LETTER HA + { 0x2DF0, BIDI_NSM }, // COMBINING CYRILLIC LETTER TSE + { 0x2DF1, BIDI_NSM }, // COMBINING CYRILLIC LETTER CHE + { 0x2DF2, BIDI_NSM }, // COMBINING CYRILLIC LETTER SHA + { 0x2DF3, BIDI_NSM }, // COMBINING CYRILLIC LETTER SHCHA + { 0x2DF4, BIDI_NSM }, // COMBINING CYRILLIC LETTER FITA + { 0x2DF5, BIDI_NSM }, // COMBINING CYRILLIC LETTER ES-TE + { 0x2DF6, BIDI_NSM }, // COMBINING CYRILLIC LETTER A + { 0x2DF7, BIDI_NSM }, // COMBINING CYRILLIC LETTER IE + { 0x2DF8, BIDI_NSM }, // COMBINING CYRILLIC LETTER DJERV + { 0x2DF9, BIDI_NSM }, // COMBINING CYRILLIC LETTER MONOGRAPH UK + { 0x2DFA, BIDI_NSM }, // COMBINING CYRILLIC LETTER YAT + { 0x2DFB, BIDI_NSM }, // COMBINING CYRILLIC LETTER YU + { 0x2DFC, BIDI_NSM }, // COMBINING CYRILLIC LETTER IOTIFIED A + { 0x2DFD, BIDI_NSM }, // COMBINING CYRILLIC LETTER LITTLE YUS + { 0x2DFE, BIDI_NSM }, // COMBINING CYRILLIC LETTER BIG YUS + { 0x2DFF, BIDI_NSM }, // COMBINING CYRILLIC LETTER IOTIFIED BIG YUS + { 0x2E00, BIDI_ON }, // RIGHT ANGLE SUBSTITUTION MARKER + { 0x2E01, BIDI_ON }, // RIGHT ANGLE DOTTED SUBSTITUTION MARKER + { 0x2E02, BIDI_ON }, // LEFT SUBSTITUTION BRACKET + { 0x2E03, BIDI_ON }, // RIGHT SUBSTITUTION BRACKET + { 0x2E04, BIDI_ON }, // LEFT DOTTED SUBSTITUTION BRACKET + { 0x2E05, BIDI_ON }, // RIGHT DOTTED SUBSTITUTION BRACKET + { 0x2E06, BIDI_ON }, // RAISED INTERPOLATION MARKER + { 0x2E07, BIDI_ON }, // RAISED DOTTED INTERPOLATION MARKER + { 0x2E08, BIDI_ON }, // DOTTED TRANSPOSITION MARKER + { 0x2E09, BIDI_ON }, // LEFT TRANSPOSITION BRACKET + { 0x2E0A, BIDI_ON }, // RIGHT TRANSPOSITION BRACKET + { 0x2E0B, BIDI_ON }, // RAISED SQUARE + { 0x2E0C, BIDI_ON }, // LEFT RAISED OMISSION BRACKET + { 0x2E0D, BIDI_ON }, // RIGHT RAISED OMISSION BRACKET + { 0x2E0E, BIDI_ON }, // EDITORIAL CORONIS + { 0x2E0F, BIDI_ON }, // PARAGRAPHOS + { 0x2E10, BIDI_ON }, // FORKED PARAGRAPHOS + { 0x2E11, BIDI_ON }, // REVERSED FORKED PARAGRAPHOS + { 0x2E12, BIDI_ON }, // HYPODIASTOLE + { 0x2E13, BIDI_ON }, // DOTTED OBELOS + { 0x2E14, BIDI_ON }, // DOWNWARDS ANCORA + { 0x2E15, BIDI_ON }, // UPWARDS ANCORA + { 0x2E16, BIDI_ON }, // DOTTED RIGHT-POINTING ANGLE + { 0x2E17, BIDI_ON }, // DOUBLE OBLIQUE HYPHEN + { 0x2E18, BIDI_ON }, // INVERTED INTERROBANG + { 0x2E19, BIDI_ON }, // PALM BRANCH + { 0x2E1A, BIDI_ON }, // HYPHEN WITH DIAERESIS + { 0x2E1B, BIDI_ON }, // TILDE WITH RING ABOVE + { 0x2E1C, BIDI_ON }, // LEFT LOW PARAPHRASE BRACKET + { 0x2E1D, BIDI_ON }, // RIGHT LOW PARAPHRASE BRACKET + { 0x2E1E, BIDI_ON }, // TILDE WITH DOT ABOVE + { 0x2E1F, BIDI_ON }, // TILDE WITH DOT BELOW + { 0x2E20, BIDI_ON }, // LEFT VERTICAL BAR WITH QUILL + { 0x2E21, BIDI_ON }, // RIGHT VERTICAL BAR WITH QUILL + { 0x2E22, BIDI_ON }, // TOP LEFT HALF BRACKET + { 0x2E23, BIDI_ON }, // TOP RIGHT HALF BRACKET + { 0x2E24, BIDI_ON }, // BOTTOM LEFT HALF BRACKET + { 0x2E25, BIDI_ON }, // BOTTOM RIGHT HALF BRACKET + { 0x2E26, BIDI_ON }, // LEFT SIDEWAYS U BRACKET + { 0x2E27, BIDI_ON }, // RIGHT SIDEWAYS U BRACKET + { 0x2E28, BIDI_ON }, // LEFT DOUBLE PARENTHESIS + { 0x2E29, BIDI_ON }, // RIGHT DOUBLE PARENTHESIS + { 0x2E2A, BIDI_ON }, // TWO DOTS OVER ONE DOT PUNCTUATION + { 0x2E2B, BIDI_ON }, // ONE DOT OVER TWO DOTS PUNCTUATION + { 0x2E2C, BIDI_ON }, // SQUARED FOUR DOT PUNCTUATION + { 0x2E2D, BIDI_ON }, // FIVE DOT MARK + { 0x2E2E, BIDI_ON }, // REVERSED QUESTION MARK + { 0x2E2F, BIDI_ON }, // VERTICAL TILDE + { 0x2E30, BIDI_ON }, // RING POINT + { 0x2E31, BIDI_ON }, // WORD SEPARATOR MIDDLE DOT + { 0x2E32, BIDI_ON }, // TURNED COMMA + { 0x2E33, BIDI_ON }, // RAISED DOT + { 0x2E34, BIDI_ON }, // RAISED COMMA + { 0x2E35, BIDI_ON }, // TURNED SEMICOLON + { 0x2E36, BIDI_ON }, // DAGGER WITH LEFT GUARD + { 0x2E37, BIDI_ON }, // DAGGER WITH RIGHT GUARD + { 0x2E38, BIDI_ON }, // TURNED DAGGER + { 0x2E39, BIDI_ON }, // TOP HALF SECTION SIGN + { 0x2E3A, BIDI_ON }, // TWO-EM DASH + { 0x2E3B, BIDI_ON }, // THREE-EM DASH + { 0x2E3C, BIDI_ON }, // STENOGRAPHIC FULL STOP + { 0x2E3D, BIDI_ON }, // VERTICAL SIX DOTS + { 0x2E3E, BIDI_ON }, // WIGGLY VERTICAL LINE + { 0x2E3F, BIDI_ON }, // CAPITULUM + { 0x2E40, BIDI_ON }, // DOUBLE HYPHEN + { 0x2E41, BIDI_ON }, // REVERSED COMMA + { 0x2E42, BIDI_ON }, // DOUBLE LOW-REVERSED-9 QUOTATION MARK + { 0x2E80, BIDI_ON }, // CJK RADICAL REPEAT + { 0x2E81, BIDI_ON }, // CJK RADICAL CLIFF + { 0x2E82, BIDI_ON }, // CJK RADICAL SECOND ONE + { 0x2E83, BIDI_ON }, // CJK RADICAL SECOND TWO + { 0x2E84, BIDI_ON }, // CJK RADICAL SECOND THREE + { 0x2E85, BIDI_ON }, // CJK RADICAL PERSON + { 0x2E86, BIDI_ON }, // CJK RADICAL BOX + { 0x2E87, BIDI_ON }, // CJK RADICAL TABLE + { 0x2E88, BIDI_ON }, // CJK RADICAL KNIFE ONE + { 0x2E89, BIDI_ON }, // CJK RADICAL KNIFE TWO + { 0x2E8A, BIDI_ON }, // CJK RADICAL DIVINATION + { 0x2E8B, BIDI_ON }, // CJK RADICAL SEAL + { 0x2E8C, BIDI_ON }, // CJK RADICAL SMALL ONE + { 0x2E8D, BIDI_ON }, // CJK RADICAL SMALL TWO + { 0x2E8E, BIDI_ON }, // CJK RADICAL LAME ONE + { 0x2E8F, BIDI_ON }, // CJK RADICAL LAME TWO + { 0x2E90, BIDI_ON }, // CJK RADICAL LAME THREE + { 0x2E91, BIDI_ON }, // CJK RADICAL LAME FOUR + { 0x2E92, BIDI_ON }, // CJK RADICAL SNAKE + { 0x2E93, BIDI_ON }, // CJK RADICAL THREAD + { 0x2E94, BIDI_ON }, // CJK RADICAL SNOUT ONE + { 0x2E95, BIDI_ON }, // CJK RADICAL SNOUT TWO + { 0x2E96, BIDI_ON }, // CJK RADICAL HEART ONE + { 0x2E97, BIDI_ON }, // CJK RADICAL HEART TWO + { 0x2E98, BIDI_ON }, // CJK RADICAL HAND + { 0x2E99, BIDI_ON }, // CJK RADICAL RAP + { 0x2E9B, BIDI_ON }, // CJK RADICAL CHOKE + { 0x2E9C, BIDI_ON }, // CJK RADICAL SUN + { 0x2E9D, BIDI_ON }, // CJK RADICAL MOON + { 0x2E9E, BIDI_ON }, // CJK RADICAL DEATH + { 0x2E9F, BIDI_ON }, // CJK RADICAL MOTHER + { 0x2EA0, BIDI_ON }, // CJK RADICAL CIVILIAN + { 0x2EA1, BIDI_ON }, // CJK RADICAL WATER ONE + { 0x2EA2, BIDI_ON }, // CJK RADICAL WATER TWO + { 0x2EA3, BIDI_ON }, // CJK RADICAL FIRE + { 0x2EA4, BIDI_ON }, // CJK RADICAL PAW ONE + { 0x2EA5, BIDI_ON }, // CJK RADICAL PAW TWO + { 0x2EA6, BIDI_ON }, // CJK RADICAL SIMPLIFIED HALF TREE TRUNK + { 0x2EA7, BIDI_ON }, // CJK RADICAL COW + { 0x2EA8, BIDI_ON }, // CJK RADICAL DOG + { 0x2EA9, BIDI_ON }, // CJK RADICAL JADE + { 0x2EAA, BIDI_ON }, // CJK RADICAL BOLT OF CLOTH + { 0x2EAB, BIDI_ON }, // CJK RADICAL EYE + { 0x2EAC, BIDI_ON }, // CJK RADICAL SPIRIT ONE + { 0x2EAD, BIDI_ON }, // CJK RADICAL SPIRIT TWO + { 0x2EAE, BIDI_ON }, // CJK RADICAL BAMBOO + { 0x2EAF, BIDI_ON }, // CJK RADICAL SILK + { 0x2EB0, BIDI_ON }, // CJK RADICAL C-SIMPLIFIED SILK + { 0x2EB1, BIDI_ON }, // CJK RADICAL NET ONE + { 0x2EB2, BIDI_ON }, // CJK RADICAL NET TWO + { 0x2EB3, BIDI_ON }, // CJK RADICAL NET THREE + { 0x2EB4, BIDI_ON }, // CJK RADICAL NET FOUR + { 0x2EB5, BIDI_ON }, // CJK RADICAL MESH + { 0x2EB6, BIDI_ON }, // CJK RADICAL SHEEP + { 0x2EB7, BIDI_ON }, // CJK RADICAL RAM + { 0x2EB8, BIDI_ON }, // CJK RADICAL EWE + { 0x2EB9, BIDI_ON }, // CJK RADICAL OLD + { 0x2EBA, BIDI_ON }, // CJK RADICAL BRUSH ONE + { 0x2EBB, BIDI_ON }, // CJK RADICAL BRUSH TWO + { 0x2EBC, BIDI_ON }, // CJK RADICAL MEAT + { 0x2EBD, BIDI_ON }, // CJK RADICAL MORTAR + { 0x2EBE, BIDI_ON }, // CJK RADICAL GRASS ONE + { 0x2EBF, BIDI_ON }, // CJK RADICAL GRASS TWO + { 0x2EC0, BIDI_ON }, // CJK RADICAL GRASS THREE + { 0x2EC1, BIDI_ON }, // CJK RADICAL TIGER + { 0x2EC2, BIDI_ON }, // CJK RADICAL CLOTHES + { 0x2EC3, BIDI_ON }, // CJK RADICAL WEST ONE + { 0x2EC4, BIDI_ON }, // CJK RADICAL WEST TWO + { 0x2EC5, BIDI_ON }, // CJK RADICAL C-SIMPLIFIED SEE + { 0x2EC6, BIDI_ON }, // CJK RADICAL SIMPLIFIED HORN + { 0x2EC7, BIDI_ON }, // CJK RADICAL HORN + { 0x2EC8, BIDI_ON }, // CJK RADICAL C-SIMPLIFIED SPEECH + { 0x2EC9, BIDI_ON }, // CJK RADICAL C-SIMPLIFIED SHELL + { 0x2ECA, BIDI_ON }, // CJK RADICAL FOOT + { 0x2ECB, BIDI_ON }, // CJK RADICAL C-SIMPLIFIED CART + { 0x2ECC, BIDI_ON }, // CJK RADICAL SIMPLIFIED WALK + { 0x2ECD, BIDI_ON }, // CJK RADICAL WALK ONE + { 0x2ECE, BIDI_ON }, // CJK RADICAL WALK TWO + { 0x2ECF, BIDI_ON }, // CJK RADICAL CITY + { 0x2ED0, BIDI_ON }, // CJK RADICAL C-SIMPLIFIED GOLD + { 0x2ED1, BIDI_ON }, // CJK RADICAL LONG ONE + { 0x2ED2, BIDI_ON }, // CJK RADICAL LONG TWO + { 0x2ED3, BIDI_ON }, // CJK RADICAL C-SIMPLIFIED LONG + { 0x2ED4, BIDI_ON }, // CJK RADICAL C-SIMPLIFIED GATE + { 0x2ED5, BIDI_ON }, // CJK RADICAL MOUND ONE + { 0x2ED6, BIDI_ON }, // CJK RADICAL MOUND TWO + { 0x2ED7, BIDI_ON }, // CJK RADICAL RAIN + { 0x2ED8, BIDI_ON }, // CJK RADICAL BLUE + { 0x2ED9, BIDI_ON }, // CJK RADICAL C-SIMPLIFIED TANNED LEATHER + { 0x2EDA, BIDI_ON }, // CJK RADICAL C-SIMPLIFIED LEAF + { 0x2EDB, BIDI_ON }, // CJK RADICAL C-SIMPLIFIED WIND + { 0x2EDC, BIDI_ON }, // CJK RADICAL C-SIMPLIFIED FLY + { 0x2EDD, BIDI_ON }, // CJK RADICAL EAT ONE + { 0x2EDE, BIDI_ON }, // CJK RADICAL EAT TWO + { 0x2EDF, BIDI_ON }, // CJK RADICAL EAT THREE + { 0x2EE0, BIDI_ON }, // CJK RADICAL C-SIMPLIFIED EAT + { 0x2EE1, BIDI_ON }, // CJK RADICAL HEAD + { 0x2EE2, BIDI_ON }, // CJK RADICAL C-SIMPLIFIED HORSE + { 0x2EE3, BIDI_ON }, // CJK RADICAL BONE + { 0x2EE4, BIDI_ON }, // CJK RADICAL GHOST + { 0x2EE5, BIDI_ON }, // CJK RADICAL C-SIMPLIFIED FISH + { 0x2EE6, BIDI_ON }, // CJK RADICAL C-SIMPLIFIED BIRD + { 0x2EE7, BIDI_ON }, // CJK RADICAL C-SIMPLIFIED SALT + { 0x2EE8, BIDI_ON }, // CJK RADICAL SIMPLIFIED WHEAT + { 0x2EE9, BIDI_ON }, // CJK RADICAL SIMPLIFIED YELLOW + { 0x2EEA, BIDI_ON }, // CJK RADICAL C-SIMPLIFIED FROG + { 0x2EEB, BIDI_ON }, // CJK RADICAL J-SIMPLIFIED EVEN + { 0x2EEC, BIDI_ON }, // CJK RADICAL C-SIMPLIFIED EVEN + { 0x2EED, BIDI_ON }, // CJK RADICAL J-SIMPLIFIED TOOTH + { 0x2EEE, BIDI_ON }, // CJK RADICAL C-SIMPLIFIED TOOTH + { 0x2EEF, BIDI_ON }, // CJK RADICAL J-SIMPLIFIED DRAGON + { 0x2EF0, BIDI_ON }, // CJK RADICAL C-SIMPLIFIED DRAGON + { 0x2EF1, BIDI_ON }, // CJK RADICAL TURTLE + { 0x2EF2, BIDI_ON }, // CJK RADICAL J-SIMPLIFIED TURTLE + { 0x2EF3, BIDI_ON }, // CJK RADICAL C-SIMPLIFIED TURTLE + { 0x2F00, BIDI_ON }, // KANGXI RADICAL ONE + { 0x2F01, BIDI_ON }, // KANGXI RADICAL LINE + { 0x2F02, BIDI_ON }, // KANGXI RADICAL DOT + { 0x2F03, BIDI_ON }, // KANGXI RADICAL SLASH + { 0x2F04, BIDI_ON }, // KANGXI RADICAL SECOND + { 0x2F05, BIDI_ON }, // KANGXI RADICAL HOOK + { 0x2F06, BIDI_ON }, // KANGXI RADICAL TWO + { 0x2F07, BIDI_ON }, // KANGXI RADICAL LID + { 0x2F08, BIDI_ON }, // KANGXI RADICAL MAN + { 0x2F09, BIDI_ON }, // KANGXI RADICAL LEGS + { 0x2F0A, BIDI_ON }, // KANGXI RADICAL ENTER + { 0x2F0B, BIDI_ON }, // KANGXI RADICAL EIGHT + { 0x2F0C, BIDI_ON }, // KANGXI RADICAL DOWN BOX + { 0x2F0D, BIDI_ON }, // KANGXI RADICAL COVER + { 0x2F0E, BIDI_ON }, // KANGXI RADICAL ICE + { 0x2F0F, BIDI_ON }, // KANGXI RADICAL TABLE + { 0x2F10, BIDI_ON }, // KANGXI RADICAL OPEN BOX + { 0x2F11, BIDI_ON }, // KANGXI RADICAL KNIFE + { 0x2F12, BIDI_ON }, // KANGXI RADICAL POWER + { 0x2F13, BIDI_ON }, // KANGXI RADICAL WRAP + { 0x2F14, BIDI_ON }, // KANGXI RADICAL SPOON + { 0x2F15, BIDI_ON }, // KANGXI RADICAL RIGHT OPEN BOX + { 0x2F16, BIDI_ON }, // KANGXI RADICAL HIDING ENCLOSURE + { 0x2F17, BIDI_ON }, // KANGXI RADICAL TEN + { 0x2F18, BIDI_ON }, // KANGXI RADICAL DIVINATION + { 0x2F19, BIDI_ON }, // KANGXI RADICAL SEAL + { 0x2F1A, BIDI_ON }, // KANGXI RADICAL CLIFF + { 0x2F1B, BIDI_ON }, // KANGXI RADICAL PRIVATE + { 0x2F1C, BIDI_ON }, // KANGXI RADICAL AGAIN + { 0x2F1D, BIDI_ON }, // KANGXI RADICAL MOUTH + { 0x2F1E, BIDI_ON }, // KANGXI RADICAL ENCLOSURE + { 0x2F1F, BIDI_ON }, // KANGXI RADICAL EARTH + { 0x2F20, BIDI_ON }, // KANGXI RADICAL SCHOLAR + { 0x2F21, BIDI_ON }, // KANGXI RADICAL GO + { 0x2F22, BIDI_ON }, // KANGXI RADICAL GO SLOWLY + { 0x2F23, BIDI_ON }, // KANGXI RADICAL EVENING + { 0x2F24, BIDI_ON }, // KANGXI RADICAL BIG + { 0x2F25, BIDI_ON }, // KANGXI RADICAL WOMAN + { 0x2F26, BIDI_ON }, // KANGXI RADICAL CHILD + { 0x2F27, BIDI_ON }, // KANGXI RADICAL ROOF + { 0x2F28, BIDI_ON }, // KANGXI RADICAL INCH + { 0x2F29, BIDI_ON }, // KANGXI RADICAL SMALL + { 0x2F2A, BIDI_ON }, // KANGXI RADICAL LAME + { 0x2F2B, BIDI_ON }, // KANGXI RADICAL CORPSE + { 0x2F2C, BIDI_ON }, // KANGXI RADICAL SPROUT + { 0x2F2D, BIDI_ON }, // KANGXI RADICAL MOUNTAIN + { 0x2F2E, BIDI_ON }, // KANGXI RADICAL RIVER + { 0x2F2F, BIDI_ON }, // KANGXI RADICAL WORK + { 0x2F30, BIDI_ON }, // KANGXI RADICAL ONESELF + { 0x2F31, BIDI_ON }, // KANGXI RADICAL TURBAN + { 0x2F32, BIDI_ON }, // KANGXI RADICAL DRY + { 0x2F33, BIDI_ON }, // KANGXI RADICAL SHORT THREAD + { 0x2F34, BIDI_ON }, // KANGXI RADICAL DOTTED CLIFF + { 0x2F35, BIDI_ON }, // KANGXI RADICAL LONG STRIDE + { 0x2F36, BIDI_ON }, // KANGXI RADICAL TWO HANDS + { 0x2F37, BIDI_ON }, // KANGXI RADICAL SHOOT + { 0x2F38, BIDI_ON }, // KANGXI RADICAL BOW + { 0x2F39, BIDI_ON }, // KANGXI RADICAL SNOUT + { 0x2F3A, BIDI_ON }, // KANGXI RADICAL BRISTLE + { 0x2F3B, BIDI_ON }, // KANGXI RADICAL STEP + { 0x2F3C, BIDI_ON }, // KANGXI RADICAL HEART + { 0x2F3D, BIDI_ON }, // KANGXI RADICAL HALBERD + { 0x2F3E, BIDI_ON }, // KANGXI RADICAL DOOR + { 0x2F3F, BIDI_ON }, // KANGXI RADICAL HAND + { 0x2F40, BIDI_ON }, // KANGXI RADICAL BRANCH + { 0x2F41, BIDI_ON }, // KANGXI RADICAL RAP + { 0x2F42, BIDI_ON }, // KANGXI RADICAL SCRIPT + { 0x2F43, BIDI_ON }, // KANGXI RADICAL DIPPER + { 0x2F44, BIDI_ON }, // KANGXI RADICAL AXE + { 0x2F45, BIDI_ON }, // KANGXI RADICAL SQUARE + { 0x2F46, BIDI_ON }, // KANGXI RADICAL NOT + { 0x2F47, BIDI_ON }, // KANGXI RADICAL SUN + { 0x2F48, BIDI_ON }, // KANGXI RADICAL SAY + { 0x2F49, BIDI_ON }, // KANGXI RADICAL MOON + { 0x2F4A, BIDI_ON }, // KANGXI RADICAL TREE + { 0x2F4B, BIDI_ON }, // KANGXI RADICAL LACK + { 0x2F4C, BIDI_ON }, // KANGXI RADICAL STOP + { 0x2F4D, BIDI_ON }, // KANGXI RADICAL DEATH + { 0x2F4E, BIDI_ON }, // KANGXI RADICAL WEAPON + { 0x2F4F, BIDI_ON }, // KANGXI RADICAL DO NOT + { 0x2F50, BIDI_ON }, // KANGXI RADICAL COMPARE + { 0x2F51, BIDI_ON }, // KANGXI RADICAL FUR + { 0x2F52, BIDI_ON }, // KANGXI RADICAL CLAN + { 0x2F53, BIDI_ON }, // KANGXI RADICAL STEAM + { 0x2F54, BIDI_ON }, // KANGXI RADICAL WATER + { 0x2F55, BIDI_ON }, // KANGXI RADICAL FIRE + { 0x2F56, BIDI_ON }, // KANGXI RADICAL CLAW + { 0x2F57, BIDI_ON }, // KANGXI RADICAL FATHER + { 0x2F58, BIDI_ON }, // KANGXI RADICAL DOUBLE X + { 0x2F59, BIDI_ON }, // KANGXI RADICAL HALF TREE TRUNK + { 0x2F5A, BIDI_ON }, // KANGXI RADICAL SLICE + { 0x2F5B, BIDI_ON }, // KANGXI RADICAL FANG + { 0x2F5C, BIDI_ON }, // KANGXI RADICAL COW + { 0x2F5D, BIDI_ON }, // KANGXI RADICAL DOG + { 0x2F5E, BIDI_ON }, // KANGXI RADICAL PROFOUND + { 0x2F5F, BIDI_ON }, // KANGXI RADICAL JADE + { 0x2F60, BIDI_ON }, // KANGXI RADICAL MELON + { 0x2F61, BIDI_ON }, // KANGXI RADICAL TILE + { 0x2F62, BIDI_ON }, // KANGXI RADICAL SWEET + { 0x2F63, BIDI_ON }, // KANGXI RADICAL LIFE + { 0x2F64, BIDI_ON }, // KANGXI RADICAL USE + { 0x2F65, BIDI_ON }, // KANGXI RADICAL FIELD + { 0x2F66, BIDI_ON }, // KANGXI RADICAL BOLT OF CLOTH + { 0x2F67, BIDI_ON }, // KANGXI RADICAL SICKNESS + { 0x2F68, BIDI_ON }, // KANGXI RADICAL DOTTED TENT + { 0x2F69, BIDI_ON }, // KANGXI RADICAL WHITE + { 0x2F6A, BIDI_ON }, // KANGXI RADICAL SKIN + { 0x2F6B, BIDI_ON }, // KANGXI RADICAL DISH + { 0x2F6C, BIDI_ON }, // KANGXI RADICAL EYE + { 0x2F6D, BIDI_ON }, // KANGXI RADICAL SPEAR + { 0x2F6E, BIDI_ON }, // KANGXI RADICAL ARROW + { 0x2F6F, BIDI_ON }, // KANGXI RADICAL STONE + { 0x2F70, BIDI_ON }, // KANGXI RADICAL SPIRIT + { 0x2F71, BIDI_ON }, // KANGXI RADICAL TRACK + { 0x2F72, BIDI_ON }, // KANGXI RADICAL GRAIN + { 0x2F73, BIDI_ON }, // KANGXI RADICAL CAVE + { 0x2F74, BIDI_ON }, // KANGXI RADICAL STAND + { 0x2F75, BIDI_ON }, // KANGXI RADICAL BAMBOO + { 0x2F76, BIDI_ON }, // KANGXI RADICAL RICE + { 0x2F77, BIDI_ON }, // KANGXI RADICAL SILK + { 0x2F78, BIDI_ON }, // KANGXI RADICAL JAR + { 0x2F79, BIDI_ON }, // KANGXI RADICAL NET + { 0x2F7A, BIDI_ON }, // KANGXI RADICAL SHEEP + { 0x2F7B, BIDI_ON }, // KANGXI RADICAL FEATHER + { 0x2F7C, BIDI_ON }, // KANGXI RADICAL OLD + { 0x2F7D, BIDI_ON }, // KANGXI RADICAL AND + { 0x2F7E, BIDI_ON }, // KANGXI RADICAL PLOW + { 0x2F7F, BIDI_ON }, // KANGXI RADICAL EAR + { 0x2F80, BIDI_ON }, // KANGXI RADICAL BRUSH + { 0x2F81, BIDI_ON }, // KANGXI RADICAL MEAT + { 0x2F82, BIDI_ON }, // KANGXI RADICAL MINISTER + { 0x2F83, BIDI_ON }, // KANGXI RADICAL SELF + { 0x2F84, BIDI_ON }, // KANGXI RADICAL ARRIVE + { 0x2F85, BIDI_ON }, // KANGXI RADICAL MORTAR + { 0x2F86, BIDI_ON }, // KANGXI RADICAL TONGUE + { 0x2F87, BIDI_ON }, // KANGXI RADICAL OPPOSE + { 0x2F88, BIDI_ON }, // KANGXI RADICAL BOAT + { 0x2F89, BIDI_ON }, // KANGXI RADICAL STOPPING + { 0x2F8A, BIDI_ON }, // KANGXI RADICAL COLOR + { 0x2F8B, BIDI_ON }, // KANGXI RADICAL GRASS + { 0x2F8C, BIDI_ON }, // KANGXI RADICAL TIGER + { 0x2F8D, BIDI_ON }, // KANGXI RADICAL INSECT + { 0x2F8E, BIDI_ON }, // KANGXI RADICAL BLOOD + { 0x2F8F, BIDI_ON }, // KANGXI RADICAL WALK ENCLOSURE + { 0x2F90, BIDI_ON }, // KANGXI RADICAL CLOTHES + { 0x2F91, BIDI_ON }, // KANGXI RADICAL WEST + { 0x2F92, BIDI_ON }, // KANGXI RADICAL SEE + { 0x2F93, BIDI_ON }, // KANGXI RADICAL HORN + { 0x2F94, BIDI_ON }, // KANGXI RADICAL SPEECH + { 0x2F95, BIDI_ON }, // KANGXI RADICAL VALLEY + { 0x2F96, BIDI_ON }, // KANGXI RADICAL BEAN + { 0x2F97, BIDI_ON }, // KANGXI RADICAL PIG + { 0x2F98, BIDI_ON }, // KANGXI RADICAL BADGER + { 0x2F99, BIDI_ON }, // KANGXI RADICAL SHELL + { 0x2F9A, BIDI_ON }, // KANGXI RADICAL RED + { 0x2F9B, BIDI_ON }, // KANGXI RADICAL RUN + { 0x2F9C, BIDI_ON }, // KANGXI RADICAL FOOT + { 0x2F9D, BIDI_ON }, // KANGXI RADICAL BODY + { 0x2F9E, BIDI_ON }, // KANGXI RADICAL CART + { 0x2F9F, BIDI_ON }, // KANGXI RADICAL BITTER + { 0x2FA0, BIDI_ON }, // KANGXI RADICAL MORNING + { 0x2FA1, BIDI_ON }, // KANGXI RADICAL WALK + { 0x2FA2, BIDI_ON }, // KANGXI RADICAL CITY + { 0x2FA3, BIDI_ON }, // KANGXI RADICAL WINE + { 0x2FA4, BIDI_ON }, // KANGXI RADICAL DISTINGUISH + { 0x2FA5, BIDI_ON }, // KANGXI RADICAL VILLAGE + { 0x2FA6, BIDI_ON }, // KANGXI RADICAL GOLD + { 0x2FA7, BIDI_ON }, // KANGXI RADICAL LONG + { 0x2FA8, BIDI_ON }, // KANGXI RADICAL GATE + { 0x2FA9, BIDI_ON }, // KANGXI RADICAL MOUND + { 0x2FAA, BIDI_ON }, // KANGXI RADICAL SLAVE + { 0x2FAB, BIDI_ON }, // KANGXI RADICAL SHORT TAILED BIRD + { 0x2FAC, BIDI_ON }, // KANGXI RADICAL RAIN + { 0x2FAD, BIDI_ON }, // KANGXI RADICAL BLUE + { 0x2FAE, BIDI_ON }, // KANGXI RADICAL WRONG + { 0x2FAF, BIDI_ON }, // KANGXI RADICAL FACE + { 0x2FB0, BIDI_ON }, // KANGXI RADICAL LEATHER + { 0x2FB1, BIDI_ON }, // KANGXI RADICAL TANNED LEATHER + { 0x2FB2, BIDI_ON }, // KANGXI RADICAL LEEK + { 0x2FB3, BIDI_ON }, // KANGXI RADICAL SOUND + { 0x2FB4, BIDI_ON }, // KANGXI RADICAL LEAF + { 0x2FB5, BIDI_ON }, // KANGXI RADICAL WIND + { 0x2FB6, BIDI_ON }, // KANGXI RADICAL FLY + { 0x2FB7, BIDI_ON }, // KANGXI RADICAL EAT + { 0x2FB8, BIDI_ON }, // KANGXI RADICAL HEAD + { 0x2FB9, BIDI_ON }, // KANGXI RADICAL FRAGRANT + { 0x2FBA, BIDI_ON }, // KANGXI RADICAL HORSE + { 0x2FBB, BIDI_ON }, // KANGXI RADICAL BONE + { 0x2FBC, BIDI_ON }, // KANGXI RADICAL TALL + { 0x2FBD, BIDI_ON }, // KANGXI RADICAL HAIR + { 0x2FBE, BIDI_ON }, // KANGXI RADICAL FIGHT + { 0x2FBF, BIDI_ON }, // KANGXI RADICAL SACRIFICIAL WINE + { 0x2FC0, BIDI_ON }, // KANGXI RADICAL CAULDRON + { 0x2FC1, BIDI_ON }, // KANGXI RADICAL GHOST + { 0x2FC2, BIDI_ON }, // KANGXI RADICAL FISH + { 0x2FC3, BIDI_ON }, // KANGXI RADICAL BIRD + { 0x2FC4, BIDI_ON }, // KANGXI RADICAL SALT + { 0x2FC5, BIDI_ON }, // KANGXI RADICAL DEER + { 0x2FC6, BIDI_ON }, // KANGXI RADICAL WHEAT + { 0x2FC7, BIDI_ON }, // KANGXI RADICAL HEMP + { 0x2FC8, BIDI_ON }, // KANGXI RADICAL YELLOW + { 0x2FC9, BIDI_ON }, // KANGXI RADICAL MILLET + { 0x2FCA, BIDI_ON }, // KANGXI RADICAL BLACK + { 0x2FCB, BIDI_ON }, // KANGXI RADICAL EMBROIDERY + { 0x2FCC, BIDI_ON }, // KANGXI RADICAL FROG + { 0x2FCD, BIDI_ON }, // KANGXI RADICAL TRIPOD + { 0x2FCE, BIDI_ON }, // KANGXI RADICAL DRUM + { 0x2FCF, BIDI_ON }, // KANGXI RADICAL RAT + { 0x2FD0, BIDI_ON }, // KANGXI RADICAL NOSE + { 0x2FD1, BIDI_ON }, // KANGXI RADICAL EVEN + { 0x2FD2, BIDI_ON }, // KANGXI RADICAL TOOTH + { 0x2FD3, BIDI_ON }, // KANGXI RADICAL DRAGON + { 0x2FD4, BIDI_ON }, // KANGXI RADICAL TURTLE + { 0x2FD5, BIDI_ON }, // KANGXI RADICAL FLUTE + { 0x2FF0, BIDI_ON }, // IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO RIGHT + { 0x2FF1, BIDI_ON }, // IDEOGRAPHIC DESCRIPTION CHARACTER ABOVE TO BELOW + { 0x2FF2, BIDI_ON }, // IDEOGRAPHIC DESCRIPTION CHARACTER LEFT TO MIDDLE AND RIGHT + { 0x2FF3, BIDI_ON }, // IDEOGRAPHIC DESCRIPTION CHARACTER ABOVE TO MIDDLE AND BELOW + { 0x2FF4, BIDI_ON }, // IDEOGRAPHIC DESCRIPTION CHARACTER FULL SURROUND + { 0x2FF5, BIDI_ON }, // IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM ABOVE + { 0x2FF6, BIDI_ON }, // IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM BELOW + { 0x2FF7, BIDI_ON }, // IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM LEFT + { 0x2FF8, BIDI_ON }, // IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM UPPER LEFT + { 0x2FF9, BIDI_ON }, // IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM UPPER RIGHT + { 0x2FFA, BIDI_ON }, // IDEOGRAPHIC DESCRIPTION CHARACTER SURROUND FROM LOWER LEFT + { 0x2FFB, BIDI_ON }, // IDEOGRAPHIC DESCRIPTION CHARACTER OVERLAID + +#endif +#if (GUI_BIDI_SUPPORT_RANGE_3 == 1) + + { 0x3000, BIDI_WS }, // IDEOGRAPHIC SPACE + { 0x3001, BIDI_ON }, // IDEOGRAPHIC COMMA + { 0x3002, BIDI_ON }, // IDEOGRAPHIC FULL STOP + { 0x3003, BIDI_ON }, // DITTO MARK + { 0x3004, BIDI_ON }, // JAPANESE INDUSTRIAL STANDARD SYMBOL + { 0x3005, BIDI_L }, // IDEOGRAPHIC ITERATION MARK + { 0x3006, BIDI_L }, // IDEOGRAPHIC CLOSING MARK + { 0x3007, BIDI_L }, // IDEOGRAPHIC NUMBER ZERO + { 0x3008, BIDI_ON }, // LEFT ANGLE BRACKET + { 0x3009, BIDI_ON }, // RIGHT ANGLE BRACKET + { 0x300A, BIDI_ON }, // LEFT DOUBLE ANGLE BRACKET + { 0x300B, BIDI_ON }, // RIGHT DOUBLE ANGLE BRACKET + { 0x300C, BIDI_ON }, // LEFT CORNER BRACKET + { 0x300D, BIDI_ON }, // RIGHT CORNER BRACKET + { 0x300E, BIDI_ON }, // LEFT WHITE CORNER BRACKET + { 0x300F, BIDI_ON }, // RIGHT WHITE CORNER BRACKET + { 0x3010, BIDI_ON }, // LEFT BLACK LENTICULAR BRACKET + { 0x3011, BIDI_ON }, // RIGHT BLACK LENTICULAR BRACKET + { 0x3012, BIDI_ON }, // POSTAL MARK + { 0x3013, BIDI_ON }, // GETA MARK + { 0x3014, BIDI_ON }, // LEFT TORTOISE SHELL BRACKET + { 0x3015, BIDI_ON }, // RIGHT TORTOISE SHELL BRACKET + { 0x3016, BIDI_ON }, // LEFT WHITE LENTICULAR BRACKET + { 0x3017, BIDI_ON }, // RIGHT WHITE LENTICULAR BRACKET + { 0x3018, BIDI_ON }, // LEFT WHITE TORTOISE SHELL BRACKET + { 0x3019, BIDI_ON }, // RIGHT WHITE TORTOISE SHELL BRACKET + { 0x301A, BIDI_ON }, // LEFT WHITE SQUARE BRACKET + { 0x301B, BIDI_ON }, // RIGHT WHITE SQUARE BRACKET + { 0x301C, BIDI_ON }, // WAVE DASH + { 0x301D, BIDI_ON }, // REVERSED DOUBLE PRIME QUOTATION MARK + { 0x301E, BIDI_ON }, // DOUBLE PRIME QUOTATION MARK + { 0x301F, BIDI_ON }, // LOW DOUBLE PRIME QUOTATION MARK + { 0x3020, BIDI_ON }, // POSTAL MARK FACE + { 0x3021, BIDI_L }, // HANGZHOU NUMERAL ONE + { 0x3022, BIDI_L }, // HANGZHOU NUMERAL TWO + { 0x3023, BIDI_L }, // HANGZHOU NUMERAL THREE + { 0x3024, BIDI_L }, // HANGZHOU NUMERAL FOUR + { 0x3025, BIDI_L }, // HANGZHOU NUMERAL FIVE + { 0x3026, BIDI_L }, // HANGZHOU NUMERAL SIX + { 0x3027, BIDI_L }, // HANGZHOU NUMERAL SEVEN + { 0x3028, BIDI_L }, // HANGZHOU NUMERAL EIGHT + { 0x3029, BIDI_L }, // HANGZHOU NUMERAL NINE + { 0x302A, BIDI_NSM }, // IDEOGRAPHIC LEVEL TONE MARK + { 0x302B, BIDI_NSM }, // IDEOGRAPHIC RISING TONE MARK + { 0x302C, BIDI_NSM }, // IDEOGRAPHIC DEPARTING TONE MARK + { 0x302D, BIDI_NSM }, // IDEOGRAPHIC ENTERING TONE MARK + { 0x302E, BIDI_L }, // HANGUL SINGLE DOT TONE MARK + { 0x302F, BIDI_L }, // HANGUL DOUBLE DOT TONE MARK + { 0x3030, BIDI_ON }, // WAVY DASH + { 0x3031, BIDI_L }, // VERTICAL KANA REPEAT MARK + { 0x3032, BIDI_L }, // VERTICAL KANA REPEAT WITH VOICED SOUND MARK + { 0x3033, BIDI_L }, // VERTICAL KANA REPEAT MARK UPPER HALF + { 0x3034, BIDI_L }, // VERTICAL KANA REPEAT WITH VOICED SOUND MARK UPPER HALF + { 0x3035, BIDI_L }, // VERTICAL KANA REPEAT MARK LOWER HALF + { 0x3036, BIDI_ON }, // CIRCLED POSTAL MARK + { 0x3037, BIDI_ON }, // IDEOGRAPHIC TELEGRAPH LINE FEED SEPARATOR SYMBOL + { 0x3038, BIDI_L }, // HANGZHOU NUMERAL TEN + { 0x3039, BIDI_L }, // HANGZHOU NUMERAL TWENTY + { 0x303A, BIDI_L }, // HANGZHOU NUMERAL THIRTY + { 0x303B, BIDI_L }, // VERTICAL IDEOGRAPHIC ITERATION MARK + { 0x303C, BIDI_L }, // MASU MARK + { 0x303D, BIDI_ON }, // PART ALTERNATION MARK + { 0x303E, BIDI_ON }, // IDEOGRAPHIC VARIATION INDICATOR + { 0x303F, BIDI_ON }, // IDEOGRAPHIC HALF FILL SPACE + { 0x3041, BIDI_L }, // HIRAGANA LETTER SMALL A + { 0x3042, BIDI_L }, // HIRAGANA LETTER A + { 0x3043, BIDI_L }, // HIRAGANA LETTER SMALL I + { 0x3044, BIDI_L }, // HIRAGANA LETTER I + { 0x3045, BIDI_L }, // HIRAGANA LETTER SMALL U + { 0x3046, BIDI_L }, // HIRAGANA LETTER U + { 0x3047, BIDI_L }, // HIRAGANA LETTER SMALL E + { 0x3048, BIDI_L }, // HIRAGANA LETTER E + { 0x3049, BIDI_L }, // HIRAGANA LETTER SMALL O + { 0x304A, BIDI_L }, // HIRAGANA LETTER O + { 0x304B, BIDI_L }, // HIRAGANA LETTER KA + { 0x304C, BIDI_L }, // HIRAGANA LETTER GA + { 0x304D, BIDI_L }, // HIRAGANA LETTER KI + { 0x304E, BIDI_L }, // HIRAGANA LETTER GI + { 0x304F, BIDI_L }, // HIRAGANA LETTER KU + { 0x3050, BIDI_L }, // HIRAGANA LETTER GU + { 0x3051, BIDI_L }, // HIRAGANA LETTER KE + { 0x3052, BIDI_L }, // HIRAGANA LETTER GE + { 0x3053, BIDI_L }, // HIRAGANA LETTER KO + { 0x3054, BIDI_L }, // HIRAGANA LETTER GO + { 0x3055, BIDI_L }, // HIRAGANA LETTER SA + { 0x3056, BIDI_L }, // HIRAGANA LETTER ZA + { 0x3057, BIDI_L }, // HIRAGANA LETTER SI + { 0x3058, BIDI_L }, // HIRAGANA LETTER ZI + { 0x3059, BIDI_L }, // HIRAGANA LETTER SU + { 0x305A, BIDI_L }, // HIRAGANA LETTER ZU + { 0x305B, BIDI_L }, // HIRAGANA LETTER SE + { 0x305C, BIDI_L }, // HIRAGANA LETTER ZE + { 0x305D, BIDI_L }, // HIRAGANA LETTER SO + { 0x305E, BIDI_L }, // HIRAGANA LETTER ZO + { 0x305F, BIDI_L }, // HIRAGANA LETTER TA + { 0x3060, BIDI_L }, // HIRAGANA LETTER DA + { 0x3061, BIDI_L }, // HIRAGANA LETTER TI + { 0x3062, BIDI_L }, // HIRAGANA LETTER DI + { 0x3063, BIDI_L }, // HIRAGANA LETTER SMALL TU + { 0x3064, BIDI_L }, // HIRAGANA LETTER TU + { 0x3065, BIDI_L }, // HIRAGANA LETTER DU + { 0x3066, BIDI_L }, // HIRAGANA LETTER TE + { 0x3067, BIDI_L }, // HIRAGANA LETTER DE + { 0x3068, BIDI_L }, // HIRAGANA LETTER TO + { 0x3069, BIDI_L }, // HIRAGANA LETTER DO + { 0x306A, BIDI_L }, // HIRAGANA LETTER NA + { 0x306B, BIDI_L }, // HIRAGANA LETTER NI + { 0x306C, BIDI_L }, // HIRAGANA LETTER NU + { 0x306D, BIDI_L }, // HIRAGANA LETTER NE + { 0x306E, BIDI_L }, // HIRAGANA LETTER NO + { 0x306F, BIDI_L }, // HIRAGANA LETTER HA + { 0x3070, BIDI_L }, // HIRAGANA LETTER BA + { 0x3071, BIDI_L }, // HIRAGANA LETTER PA + { 0x3072, BIDI_L }, // HIRAGANA LETTER HI + { 0x3073, BIDI_L }, // HIRAGANA LETTER BI + { 0x3074, BIDI_L }, // HIRAGANA LETTER PI + { 0x3075, BIDI_L }, // HIRAGANA LETTER HU + { 0x3076, BIDI_L }, // HIRAGANA LETTER BU + { 0x3077, BIDI_L }, // HIRAGANA LETTER PU + { 0x3078, BIDI_L }, // HIRAGANA LETTER HE + { 0x3079, BIDI_L }, // HIRAGANA LETTER BE + { 0x307A, BIDI_L }, // HIRAGANA LETTER PE + { 0x307B, BIDI_L }, // HIRAGANA LETTER HO + { 0x307C, BIDI_L }, // HIRAGANA LETTER BO + { 0x307D, BIDI_L }, // HIRAGANA LETTER PO + { 0x307E, BIDI_L }, // HIRAGANA LETTER MA + { 0x307F, BIDI_L }, // HIRAGANA LETTER MI + { 0x3080, BIDI_L }, // HIRAGANA LETTER MU + { 0x3081, BIDI_L }, // HIRAGANA LETTER ME + { 0x3082, BIDI_L }, // HIRAGANA LETTER MO + { 0x3083, BIDI_L }, // HIRAGANA LETTER SMALL YA + { 0x3084, BIDI_L }, // HIRAGANA LETTER YA + { 0x3085, BIDI_L }, // HIRAGANA LETTER SMALL YU + { 0x3086, BIDI_L }, // HIRAGANA LETTER YU + { 0x3087, BIDI_L }, // HIRAGANA LETTER SMALL YO + { 0x3088, BIDI_L }, // HIRAGANA LETTER YO + { 0x3089, BIDI_L }, // HIRAGANA LETTER RA + { 0x308A, BIDI_L }, // HIRAGANA LETTER RI + { 0x308B, BIDI_L }, // HIRAGANA LETTER RU + { 0x308C, BIDI_L }, // HIRAGANA LETTER RE + { 0x308D, BIDI_L }, // HIRAGANA LETTER RO + { 0x308E, BIDI_L }, // HIRAGANA LETTER SMALL WA + { 0x308F, BIDI_L }, // HIRAGANA LETTER WA + { 0x3090, BIDI_L }, // HIRAGANA LETTER WI + { 0x3091, BIDI_L }, // HIRAGANA LETTER WE + { 0x3092, BIDI_L }, // HIRAGANA LETTER WO + { 0x3093, BIDI_L }, // HIRAGANA LETTER N + { 0x3094, BIDI_L }, // HIRAGANA LETTER VU + { 0x3095, BIDI_L }, // HIRAGANA LETTER SMALL KA + { 0x3096, BIDI_L }, // HIRAGANA LETTER SMALL KE + { 0x3099, BIDI_NSM }, // COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK + { 0x309A, BIDI_NSM }, // COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK + { 0x309B, BIDI_ON }, // KATAKANA-HIRAGANA VOICED SOUND MARK + { 0x309C, BIDI_ON }, // KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK + { 0x309D, BIDI_L }, // HIRAGANA ITERATION MARK + { 0x309E, BIDI_L }, // HIRAGANA VOICED ITERATION MARK + { 0x309F, BIDI_L }, // HIRAGANA DIGRAPH YORI + { 0x30A0, BIDI_ON }, // KATAKANA-HIRAGANA DOUBLE HYPHEN + { 0x30A1, BIDI_L }, // KATAKANA LETTER SMALL A + { 0x30A2, BIDI_L }, // KATAKANA LETTER A + { 0x30A3, BIDI_L }, // KATAKANA LETTER SMALL I + { 0x30A4, BIDI_L }, // KATAKANA LETTER I + { 0x30A5, BIDI_L }, // KATAKANA LETTER SMALL U + { 0x30A6, BIDI_L }, // KATAKANA LETTER U + { 0x30A7, BIDI_L }, // KATAKANA LETTER SMALL E + { 0x30A8, BIDI_L }, // KATAKANA LETTER E + { 0x30A9, BIDI_L }, // KATAKANA LETTER SMALL O + { 0x30AA, BIDI_L }, // KATAKANA LETTER O + { 0x30AB, BIDI_L }, // KATAKANA LETTER KA + { 0x30AC, BIDI_L }, // KATAKANA LETTER GA + { 0x30AD, BIDI_L }, // KATAKANA LETTER KI + { 0x30AE, BIDI_L }, // KATAKANA LETTER GI + { 0x30AF, BIDI_L }, // KATAKANA LETTER KU + { 0x30B0, BIDI_L }, // KATAKANA LETTER GU + { 0x30B1, BIDI_L }, // KATAKANA LETTER KE + { 0x30B2, BIDI_L }, // KATAKANA LETTER GE + { 0x30B3, BIDI_L }, // KATAKANA LETTER KO + { 0x30B4, BIDI_L }, // KATAKANA LETTER GO + { 0x30B5, BIDI_L }, // KATAKANA LETTER SA + { 0x30B6, BIDI_L }, // KATAKANA LETTER ZA + { 0x30B7, BIDI_L }, // KATAKANA LETTER SI + { 0x30B8, BIDI_L }, // KATAKANA LETTER ZI + { 0x30B9, BIDI_L }, // KATAKANA LETTER SU + { 0x30BA, BIDI_L }, // KATAKANA LETTER ZU + { 0x30BB, BIDI_L }, // KATAKANA LETTER SE + { 0x30BC, BIDI_L }, // KATAKANA LETTER ZE + { 0x30BD, BIDI_L }, // KATAKANA LETTER SO + { 0x30BE, BIDI_L }, // KATAKANA LETTER ZO + { 0x30BF, BIDI_L }, // KATAKANA LETTER TA + { 0x30C0, BIDI_L }, // KATAKANA LETTER DA + { 0x30C1, BIDI_L }, // KATAKANA LETTER TI + { 0x30C2, BIDI_L }, // KATAKANA LETTER DI + { 0x30C3, BIDI_L }, // KATAKANA LETTER SMALL TU + { 0x30C4, BIDI_L }, // KATAKANA LETTER TU + { 0x30C5, BIDI_L }, // KATAKANA LETTER DU + { 0x30C6, BIDI_L }, // KATAKANA LETTER TE + { 0x30C7, BIDI_L }, // KATAKANA LETTER DE + { 0x30C8, BIDI_L }, // KATAKANA LETTER TO + { 0x30C9, BIDI_L }, // KATAKANA LETTER DO + { 0x30CA, BIDI_L }, // KATAKANA LETTER NA + { 0x30CB, BIDI_L }, // KATAKANA LETTER NI + { 0x30CC, BIDI_L }, // KATAKANA LETTER NU + { 0x30CD, BIDI_L }, // KATAKANA LETTER NE + { 0x30CE, BIDI_L }, // KATAKANA LETTER NO + { 0x30CF, BIDI_L }, // KATAKANA LETTER HA + { 0x30D0, BIDI_L }, // KATAKANA LETTER BA + { 0x30D1, BIDI_L }, // KATAKANA LETTER PA + { 0x30D2, BIDI_L }, // KATAKANA LETTER HI + { 0x30D3, BIDI_L }, // KATAKANA LETTER BI + { 0x30D4, BIDI_L }, // KATAKANA LETTER PI + { 0x30D5, BIDI_L }, // KATAKANA LETTER HU + { 0x30D6, BIDI_L }, // KATAKANA LETTER BU + { 0x30D7, BIDI_L }, // KATAKANA LETTER PU + { 0x30D8, BIDI_L }, // KATAKANA LETTER HE + { 0x30D9, BIDI_L }, // KATAKANA LETTER BE + { 0x30DA, BIDI_L }, // KATAKANA LETTER PE + { 0x30DB, BIDI_L }, // KATAKANA LETTER HO + { 0x30DC, BIDI_L }, // KATAKANA LETTER BO + { 0x30DD, BIDI_L }, // KATAKANA LETTER PO + { 0x30DE, BIDI_L }, // KATAKANA LETTER MA + { 0x30DF, BIDI_L }, // KATAKANA LETTER MI + { 0x30E0, BIDI_L }, // KATAKANA LETTER MU + { 0x30E1, BIDI_L }, // KATAKANA LETTER ME + { 0x30E2, BIDI_L }, // KATAKANA LETTER MO + { 0x30E3, BIDI_L }, // KATAKANA LETTER SMALL YA + { 0x30E4, BIDI_L }, // KATAKANA LETTER YA + { 0x30E5, BIDI_L }, // KATAKANA LETTER SMALL YU + { 0x30E6, BIDI_L }, // KATAKANA LETTER YU + { 0x30E7, BIDI_L }, // KATAKANA LETTER SMALL YO + { 0x30E8, BIDI_L }, // KATAKANA LETTER YO + { 0x30E9, BIDI_L }, // KATAKANA LETTER RA + { 0x30EA, BIDI_L }, // KATAKANA LETTER RI + { 0x30EB, BIDI_L }, // KATAKANA LETTER RU + { 0x30EC, BIDI_L }, // KATAKANA LETTER RE + { 0x30ED, BIDI_L }, // KATAKANA LETTER RO + { 0x30EE, BIDI_L }, // KATAKANA LETTER SMALL WA + { 0x30EF, BIDI_L }, // KATAKANA LETTER WA + { 0x30F0, BIDI_L }, // KATAKANA LETTER WI + { 0x30F1, BIDI_L }, // KATAKANA LETTER WE + { 0x30F2, BIDI_L }, // KATAKANA LETTER WO + { 0x30F3, BIDI_L }, // KATAKANA LETTER N + { 0x30F4, BIDI_L }, // KATAKANA LETTER VU + { 0x30F5, BIDI_L }, // KATAKANA LETTER SMALL KA + { 0x30F6, BIDI_L }, // KATAKANA LETTER SMALL KE + { 0x30F7, BIDI_L }, // KATAKANA LETTER VA + { 0x30F8, BIDI_L }, // KATAKANA LETTER VI + { 0x30F9, BIDI_L }, // KATAKANA LETTER VE + { 0x30FA, BIDI_L }, // KATAKANA LETTER VO + { 0x30FB, BIDI_ON }, // KATAKANA MIDDLE DOT + { 0x30FC, BIDI_L }, // KATAKANA-HIRAGANA PROLONGED SOUND MARK + { 0x30FD, BIDI_L }, // KATAKANA ITERATION MARK + { 0x30FE, BIDI_L }, // KATAKANA VOICED ITERATION MARK + { 0x30FF, BIDI_L }, // KATAKANA DIGRAPH KOTO + { 0x3105, BIDI_L }, // BOPOMOFO LETTER B + { 0x3106, BIDI_L }, // BOPOMOFO LETTER P + { 0x3107, BIDI_L }, // BOPOMOFO LETTER M + { 0x3108, BIDI_L }, // BOPOMOFO LETTER F + { 0x3109, BIDI_L }, // BOPOMOFO LETTER D + { 0x310A, BIDI_L }, // BOPOMOFO LETTER T + { 0x310B, BIDI_L }, // BOPOMOFO LETTER N + { 0x310C, BIDI_L }, // BOPOMOFO LETTER L + { 0x310D, BIDI_L }, // BOPOMOFO LETTER G + { 0x310E, BIDI_L }, // BOPOMOFO LETTER K + { 0x310F, BIDI_L }, // BOPOMOFO LETTER H + { 0x3110, BIDI_L }, // BOPOMOFO LETTER J + { 0x3111, BIDI_L }, // BOPOMOFO LETTER Q + { 0x3112, BIDI_L }, // BOPOMOFO LETTER X + { 0x3113, BIDI_L }, // BOPOMOFO LETTER ZH + { 0x3114, BIDI_L }, // BOPOMOFO LETTER CH + { 0x3115, BIDI_L }, // BOPOMOFO LETTER SH + { 0x3116, BIDI_L }, // BOPOMOFO LETTER R + { 0x3117, BIDI_L }, // BOPOMOFO LETTER Z + { 0x3118, BIDI_L }, // BOPOMOFO LETTER C + { 0x3119, BIDI_L }, // BOPOMOFO LETTER S + { 0x311A, BIDI_L }, // BOPOMOFO LETTER A + { 0x311B, BIDI_L }, // BOPOMOFO LETTER O + { 0x311C, BIDI_L }, // BOPOMOFO LETTER E + { 0x311D, BIDI_L }, // BOPOMOFO LETTER EH + { 0x311E, BIDI_L }, // BOPOMOFO LETTER AI + { 0x311F, BIDI_L }, // BOPOMOFO LETTER EI + { 0x3120, BIDI_L }, // BOPOMOFO LETTER AU + { 0x3121, BIDI_L }, // BOPOMOFO LETTER OU + { 0x3122, BIDI_L }, // BOPOMOFO LETTER AN + { 0x3123, BIDI_L }, // BOPOMOFO LETTER EN + { 0x3124, BIDI_L }, // BOPOMOFO LETTER ANG + { 0x3125, BIDI_L }, // BOPOMOFO LETTER ENG + { 0x3126, BIDI_L }, // BOPOMOFO LETTER ER + { 0x3127, BIDI_L }, // BOPOMOFO LETTER I + { 0x3128, BIDI_L }, // BOPOMOFO LETTER U + { 0x3129, BIDI_L }, // BOPOMOFO LETTER IU + { 0x312A, BIDI_L }, // BOPOMOFO LETTER V + { 0x312B, BIDI_L }, // BOPOMOFO LETTER NG + { 0x312C, BIDI_L }, // BOPOMOFO LETTER GN + { 0x312D, BIDI_L }, // BOPOMOFO LETTER IH + { 0x3131, BIDI_L }, // HANGUL LETTER KIYEOK + { 0x3132, BIDI_L }, // HANGUL LETTER SSANGKIYEOK + { 0x3133, BIDI_L }, // HANGUL LETTER KIYEOK-SIOS + { 0x3134, BIDI_L }, // HANGUL LETTER NIEUN + { 0x3135, BIDI_L }, // HANGUL LETTER NIEUN-CIEUC + { 0x3136, BIDI_L }, // HANGUL LETTER NIEUN-HIEUH + { 0x3137, BIDI_L }, // HANGUL LETTER TIKEUT + { 0x3138, BIDI_L }, // HANGUL LETTER SSANGTIKEUT + { 0x3139, BIDI_L }, // HANGUL LETTER RIEUL + { 0x313A, BIDI_L }, // HANGUL LETTER RIEUL-KIYEOK + { 0x313B, BIDI_L }, // HANGUL LETTER RIEUL-MIEUM + { 0x313C, BIDI_L }, // HANGUL LETTER RIEUL-PIEUP + { 0x313D, BIDI_L }, // HANGUL LETTER RIEUL-SIOS + { 0x313E, BIDI_L }, // HANGUL LETTER RIEUL-THIEUTH + { 0x313F, BIDI_L }, // HANGUL LETTER RIEUL-PHIEUPH + { 0x3140, BIDI_L }, // HANGUL LETTER RIEUL-HIEUH + { 0x3141, BIDI_L }, // HANGUL LETTER MIEUM + { 0x3142, BIDI_L }, // HANGUL LETTER PIEUP + { 0x3143, BIDI_L }, // HANGUL LETTER SSANGPIEUP + { 0x3144, BIDI_L }, // HANGUL LETTER PIEUP-SIOS + { 0x3145, BIDI_L }, // HANGUL LETTER SIOS + { 0x3146, BIDI_L }, // HANGUL LETTER SSANGSIOS + { 0x3147, BIDI_L }, // HANGUL LETTER IEUNG + { 0x3148, BIDI_L }, // HANGUL LETTER CIEUC + { 0x3149, BIDI_L }, // HANGUL LETTER SSANGCIEUC + { 0x314A, BIDI_L }, // HANGUL LETTER CHIEUCH + { 0x314B, BIDI_L }, // HANGUL LETTER KHIEUKH + { 0x314C, BIDI_L }, // HANGUL LETTER THIEUTH + { 0x314D, BIDI_L }, // HANGUL LETTER PHIEUPH + { 0x314E, BIDI_L }, // HANGUL LETTER HIEUH + { 0x314F, BIDI_L }, // HANGUL LETTER A + { 0x3150, BIDI_L }, // HANGUL LETTER AE + { 0x3151, BIDI_L }, // HANGUL LETTER YA + { 0x3152, BIDI_L }, // HANGUL LETTER YAE + { 0x3153, BIDI_L }, // HANGUL LETTER EO + { 0x3154, BIDI_L }, // HANGUL LETTER E + { 0x3155, BIDI_L }, // HANGUL LETTER YEO + { 0x3156, BIDI_L }, // HANGUL LETTER YE + { 0x3157, BIDI_L }, // HANGUL LETTER O + { 0x3158, BIDI_L }, // HANGUL LETTER WA + { 0x3159, BIDI_L }, // HANGUL LETTER WAE + { 0x315A, BIDI_L }, // HANGUL LETTER OE + { 0x315B, BIDI_L }, // HANGUL LETTER YO + { 0x315C, BIDI_L }, // HANGUL LETTER U + { 0x315D, BIDI_L }, // HANGUL LETTER WEO + { 0x315E, BIDI_L }, // HANGUL LETTER WE + { 0x315F, BIDI_L }, // HANGUL LETTER WI + { 0x3160, BIDI_L }, // HANGUL LETTER YU + { 0x3161, BIDI_L }, // HANGUL LETTER EU + { 0x3162, BIDI_L }, // HANGUL LETTER YI + { 0x3163, BIDI_L }, // HANGUL LETTER I + { 0x3164, BIDI_L }, // HANGUL FILLER + { 0x3165, BIDI_L }, // HANGUL LETTER SSANGNIEUN + { 0x3166, BIDI_L }, // HANGUL LETTER NIEUN-TIKEUT + { 0x3167, BIDI_L }, // HANGUL LETTER NIEUN-SIOS + { 0x3168, BIDI_L }, // HANGUL LETTER NIEUN-PANSIOS + { 0x3169, BIDI_L }, // HANGUL LETTER RIEUL-KIYEOK-SIOS + { 0x316A, BIDI_L }, // HANGUL LETTER RIEUL-TIKEUT + { 0x316B, BIDI_L }, // HANGUL LETTER RIEUL-PIEUP-SIOS + { 0x316C, BIDI_L }, // HANGUL LETTER RIEUL-PANSIOS + { 0x316D, BIDI_L }, // HANGUL LETTER RIEUL-YEORINHIEUH + { 0x316E, BIDI_L }, // HANGUL LETTER MIEUM-PIEUP + { 0x316F, BIDI_L }, // HANGUL LETTER MIEUM-SIOS + { 0x3170, BIDI_L }, // HANGUL LETTER MIEUM-PANSIOS + { 0x3171, BIDI_L }, // HANGUL LETTER KAPYEOUNMIEUM + { 0x3172, BIDI_L }, // HANGUL LETTER PIEUP-KIYEOK + { 0x3173, BIDI_L }, // HANGUL LETTER PIEUP-TIKEUT + { 0x3174, BIDI_L }, // HANGUL LETTER PIEUP-SIOS-KIYEOK + { 0x3175, BIDI_L }, // HANGUL LETTER PIEUP-SIOS-TIKEUT + { 0x3176, BIDI_L }, // HANGUL LETTER PIEUP-CIEUC + { 0x3177, BIDI_L }, // HANGUL LETTER PIEUP-THIEUTH + { 0x3178, BIDI_L }, // HANGUL LETTER KAPYEOUNPIEUP + { 0x3179, BIDI_L }, // HANGUL LETTER KAPYEOUNSSANGPIEUP + { 0x317A, BIDI_L }, // HANGUL LETTER SIOS-KIYEOK + { 0x317B, BIDI_L }, // HANGUL LETTER SIOS-NIEUN + { 0x317C, BIDI_L }, // HANGUL LETTER SIOS-TIKEUT + { 0x317D, BIDI_L }, // HANGUL LETTER SIOS-PIEUP + { 0x317E, BIDI_L }, // HANGUL LETTER SIOS-CIEUC + { 0x317F, BIDI_L }, // HANGUL LETTER PANSIOS + { 0x3180, BIDI_L }, // HANGUL LETTER SSANGIEUNG + { 0x3181, BIDI_L }, // HANGUL LETTER YESIEUNG + { 0x3182, BIDI_L }, // HANGUL LETTER YESIEUNG-SIOS + { 0x3183, BIDI_L }, // HANGUL LETTER YESIEUNG-PANSIOS + { 0x3184, BIDI_L }, // HANGUL LETTER KAPYEOUNPHIEUPH + { 0x3185, BIDI_L }, // HANGUL LETTER SSANGHIEUH + { 0x3186, BIDI_L }, // HANGUL LETTER YEORINHIEUH + { 0x3187, BIDI_L }, // HANGUL LETTER YO-YA + { 0x3188, BIDI_L }, // HANGUL LETTER YO-YAE + { 0x3189, BIDI_L }, // HANGUL LETTER YO-I + { 0x318A, BIDI_L }, // HANGUL LETTER YU-YEO + { 0x318B, BIDI_L }, // HANGUL LETTER YU-YE + { 0x318C, BIDI_L }, // HANGUL LETTER YU-I + { 0x318D, BIDI_L }, // HANGUL LETTER ARAEA + { 0x318E, BIDI_L }, // HANGUL LETTER ARAEAE + { 0x3190, BIDI_L }, // IDEOGRAPHIC ANNOTATION LINKING MARK + { 0x3191, BIDI_L }, // IDEOGRAPHIC ANNOTATION REVERSE MARK + { 0x3192, BIDI_L }, // IDEOGRAPHIC ANNOTATION ONE MARK + { 0x3193, BIDI_L }, // IDEOGRAPHIC ANNOTATION TWO MARK + { 0x3194, BIDI_L }, // IDEOGRAPHIC ANNOTATION THREE MARK + { 0x3195, BIDI_L }, // IDEOGRAPHIC ANNOTATION FOUR MARK + { 0x3196, BIDI_L }, // IDEOGRAPHIC ANNOTATION TOP MARK + { 0x3197, BIDI_L }, // IDEOGRAPHIC ANNOTATION MIDDLE MARK + { 0x3198, BIDI_L }, // IDEOGRAPHIC ANNOTATION BOTTOM MARK + { 0x3199, BIDI_L }, // IDEOGRAPHIC ANNOTATION FIRST MARK + { 0x319A, BIDI_L }, // IDEOGRAPHIC ANNOTATION SECOND MARK + { 0x319B, BIDI_L }, // IDEOGRAPHIC ANNOTATION THIRD MARK + { 0x319C, BIDI_L }, // IDEOGRAPHIC ANNOTATION FOURTH MARK + { 0x319D, BIDI_L }, // IDEOGRAPHIC ANNOTATION HEAVEN MARK + { 0x319E, BIDI_L }, // IDEOGRAPHIC ANNOTATION EARTH MARK + { 0x319F, BIDI_L }, // IDEOGRAPHIC ANNOTATION MAN MARK + { 0x31A0, BIDI_L }, // BOPOMOFO LETTER BU + { 0x31A1, BIDI_L }, // BOPOMOFO LETTER ZI + { 0x31A2, BIDI_L }, // BOPOMOFO LETTER JI + { 0x31A3, BIDI_L }, // BOPOMOFO LETTER GU + { 0x31A4, BIDI_L }, // BOPOMOFO LETTER EE + { 0x31A5, BIDI_L }, // BOPOMOFO LETTER ENN + { 0x31A6, BIDI_L }, // BOPOMOFO LETTER OO + { 0x31A7, BIDI_L }, // BOPOMOFO LETTER ONN + { 0x31A8, BIDI_L }, // BOPOMOFO LETTER IR + { 0x31A9, BIDI_L }, // BOPOMOFO LETTER ANN + { 0x31AA, BIDI_L }, // BOPOMOFO LETTER INN + { 0x31AB, BIDI_L }, // BOPOMOFO LETTER UNN + { 0x31AC, BIDI_L }, // BOPOMOFO LETTER IM + { 0x31AD, BIDI_L }, // BOPOMOFO LETTER NGG + { 0x31AE, BIDI_L }, // BOPOMOFO LETTER AINN + { 0x31AF, BIDI_L }, // BOPOMOFO LETTER AUNN + { 0x31B0, BIDI_L }, // BOPOMOFO LETTER AM + { 0x31B1, BIDI_L }, // BOPOMOFO LETTER OM + { 0x31B2, BIDI_L }, // BOPOMOFO LETTER ONG + { 0x31B3, BIDI_L }, // BOPOMOFO LETTER INNN + { 0x31B4, BIDI_L }, // BOPOMOFO FINAL LETTER P + { 0x31B5, BIDI_L }, // BOPOMOFO FINAL LETTER T + { 0x31B6, BIDI_L }, // BOPOMOFO FINAL LETTER K + { 0x31B7, BIDI_L }, // BOPOMOFO FINAL LETTER H + { 0x31B8, BIDI_L }, // BOPOMOFO LETTER GH + { 0x31B9, BIDI_L }, // BOPOMOFO LETTER LH + { 0x31BA, BIDI_L }, // BOPOMOFO LETTER ZY + { 0x31C0, BIDI_ON }, // CJK STROKE T + { 0x31C1, BIDI_ON }, // CJK STROKE WG + { 0x31C2, BIDI_ON }, // CJK STROKE XG + { 0x31C3, BIDI_ON }, // CJK STROKE BXG + { 0x31C4, BIDI_ON }, // CJK STROKE SW + { 0x31C5, BIDI_ON }, // CJK STROKE HZZ + { 0x31C6, BIDI_ON }, // CJK STROKE HZG + { 0x31C7, BIDI_ON }, // CJK STROKE HP + { 0x31C8, BIDI_ON }, // CJK STROKE HZWG + { 0x31C9, BIDI_ON }, // CJK STROKE SZWG + { 0x31CA, BIDI_ON }, // CJK STROKE HZT + { 0x31CB, BIDI_ON }, // CJK STROKE HZZP + { 0x31CC, BIDI_ON }, // CJK STROKE HPWG + { 0x31CD, BIDI_ON }, // CJK STROKE HZW + { 0x31CE, BIDI_ON }, // CJK STROKE HZZZ + { 0x31CF, BIDI_ON }, // CJK STROKE N + { 0x31D0, BIDI_ON }, // CJK STROKE H + { 0x31D1, BIDI_ON }, // CJK STROKE S + { 0x31D2, BIDI_ON }, // CJK STROKE P + { 0x31D3, BIDI_ON }, // CJK STROKE SP + { 0x31D4, BIDI_ON }, // CJK STROKE D + { 0x31D5, BIDI_ON }, // CJK STROKE HZ + { 0x31D6, BIDI_ON }, // CJK STROKE HG + { 0x31D7, BIDI_ON }, // CJK STROKE SZ + { 0x31D8, BIDI_ON }, // CJK STROKE SWZ + { 0x31D9, BIDI_ON }, // CJK STROKE ST + { 0x31DA, BIDI_ON }, // CJK STROKE SG + { 0x31DB, BIDI_ON }, // CJK STROKE PD + { 0x31DC, BIDI_ON }, // CJK STROKE PZ + { 0x31DD, BIDI_ON }, // CJK STROKE TN + { 0x31DE, BIDI_ON }, // CJK STROKE SZZ + { 0x31DF, BIDI_ON }, // CJK STROKE SWG + { 0x31E0, BIDI_ON }, // CJK STROKE HXWG + { 0x31E1, BIDI_ON }, // CJK STROKE HZZZG + { 0x31E2, BIDI_ON }, // CJK STROKE PG + { 0x31E3, BIDI_ON }, // CJK STROKE Q + { 0x31F0, BIDI_L }, // KATAKANA LETTER SMALL KU + { 0x31F1, BIDI_L }, // KATAKANA LETTER SMALL SI + { 0x31F2, BIDI_L }, // KATAKANA LETTER SMALL SU + { 0x31F3, BIDI_L }, // KATAKANA LETTER SMALL TO + { 0x31F4, BIDI_L }, // KATAKANA LETTER SMALL NU + { 0x31F5, BIDI_L }, // KATAKANA LETTER SMALL HA + { 0x31F6, BIDI_L }, // KATAKANA LETTER SMALL HI + { 0x31F7, BIDI_L }, // KATAKANA LETTER SMALL HU + { 0x31F8, BIDI_L }, // KATAKANA LETTER SMALL HE + { 0x31F9, BIDI_L }, // KATAKANA LETTER SMALL HO + { 0x31FA, BIDI_L }, // KATAKANA LETTER SMALL MU + { 0x31FB, BIDI_L }, // KATAKANA LETTER SMALL RA + { 0x31FC, BIDI_L }, // KATAKANA LETTER SMALL RI + { 0x31FD, BIDI_L }, // KATAKANA LETTER SMALL RU + { 0x31FE, BIDI_L }, // KATAKANA LETTER SMALL RE + { 0x31FF, BIDI_L }, // KATAKANA LETTER SMALL RO + { 0x3200, BIDI_L }, // PARENTHESIZED HANGUL KIYEOK + { 0x3201, BIDI_L }, // PARENTHESIZED HANGUL NIEUN + { 0x3202, BIDI_L }, // PARENTHESIZED HANGUL TIKEUT + { 0x3203, BIDI_L }, // PARENTHESIZED HANGUL RIEUL + { 0x3204, BIDI_L }, // PARENTHESIZED HANGUL MIEUM + { 0x3205, BIDI_L }, // PARENTHESIZED HANGUL PIEUP + { 0x3206, BIDI_L }, // PARENTHESIZED HANGUL SIOS + { 0x3207, BIDI_L }, // PARENTHESIZED HANGUL IEUNG + { 0x3208, BIDI_L }, // PARENTHESIZED HANGUL CIEUC + { 0x3209, BIDI_L }, // PARENTHESIZED HANGUL CHIEUCH + { 0x320A, BIDI_L }, // PARENTHESIZED HANGUL KHIEUKH + { 0x320B, BIDI_L }, // PARENTHESIZED HANGUL THIEUTH + { 0x320C, BIDI_L }, // PARENTHESIZED HANGUL PHIEUPH + { 0x320D, BIDI_L }, // PARENTHESIZED HANGUL HIEUH + { 0x320E, BIDI_L }, // PARENTHESIZED HANGUL KIYEOK A + { 0x320F, BIDI_L }, // PARENTHESIZED HANGUL NIEUN A + { 0x3210, BIDI_L }, // PARENTHESIZED HANGUL TIKEUT A + { 0x3211, BIDI_L }, // PARENTHESIZED HANGUL RIEUL A + { 0x3212, BIDI_L }, // PARENTHESIZED HANGUL MIEUM A + { 0x3213, BIDI_L }, // PARENTHESIZED HANGUL PIEUP A + { 0x3214, BIDI_L }, // PARENTHESIZED HANGUL SIOS A + { 0x3215, BIDI_L }, // PARENTHESIZED HANGUL IEUNG A + { 0x3216, BIDI_L }, // PARENTHESIZED HANGUL CIEUC A + { 0x3217, BIDI_L }, // PARENTHESIZED HANGUL CHIEUCH A + { 0x3218, BIDI_L }, // PARENTHESIZED HANGUL KHIEUKH A + { 0x3219, BIDI_L }, // PARENTHESIZED HANGUL THIEUTH A + { 0x321A, BIDI_L }, // PARENTHESIZED HANGUL PHIEUPH A + { 0x321B, BIDI_L }, // PARENTHESIZED HANGUL HIEUH A + { 0x321C, BIDI_L }, // PARENTHESIZED HANGUL CIEUC U + { 0x321D, BIDI_ON }, // PARENTHESIZED KOREAN CHARACTER OJEON + { 0x321E, BIDI_ON }, // PARENTHESIZED KOREAN CHARACTER O HU + { 0x3220, BIDI_L }, // PARENTHESIZED IDEOGRAPH ONE + { 0x3221, BIDI_L }, // PARENTHESIZED IDEOGRAPH TWO + { 0x3222, BIDI_L }, // PARENTHESIZED IDEOGRAPH THREE + { 0x3223, BIDI_L }, // PARENTHESIZED IDEOGRAPH FOUR + { 0x3224, BIDI_L }, // PARENTHESIZED IDEOGRAPH FIVE + { 0x3225, BIDI_L }, // PARENTHESIZED IDEOGRAPH SIX + { 0x3226, BIDI_L }, // PARENTHESIZED IDEOGRAPH SEVEN + { 0x3227, BIDI_L }, // PARENTHESIZED IDEOGRAPH EIGHT + { 0x3228, BIDI_L }, // PARENTHESIZED IDEOGRAPH NINE + { 0x3229, BIDI_L }, // PARENTHESIZED IDEOGRAPH TEN + { 0x322A, BIDI_L }, // PARENTHESIZED IDEOGRAPH MOON + { 0x322B, BIDI_L }, // PARENTHESIZED IDEOGRAPH FIRE + { 0x322C, BIDI_L }, // PARENTHESIZED IDEOGRAPH WATER + { 0x322D, BIDI_L }, // PARENTHESIZED IDEOGRAPH WOOD + { 0x322E, BIDI_L }, // PARENTHESIZED IDEOGRAPH METAL + { 0x322F, BIDI_L }, // PARENTHESIZED IDEOGRAPH EARTH + { 0x3230, BIDI_L }, // PARENTHESIZED IDEOGRAPH SUN + { 0x3231, BIDI_L }, // PARENTHESIZED IDEOGRAPH STOCK + { 0x3232, BIDI_L }, // PARENTHESIZED IDEOGRAPH HAVE + { 0x3233, BIDI_L }, // PARENTHESIZED IDEOGRAPH SOCIETY + { 0x3234, BIDI_L }, // PARENTHESIZED IDEOGRAPH NAME + { 0x3235, BIDI_L }, // PARENTHESIZED IDEOGRAPH SPECIAL + { 0x3236, BIDI_L }, // PARENTHESIZED IDEOGRAPH FINANCIAL + { 0x3237, BIDI_L }, // PARENTHESIZED IDEOGRAPH CONGRATULATION + { 0x3238, BIDI_L }, // PARENTHESIZED IDEOGRAPH LABOR + { 0x3239, BIDI_L }, // PARENTHESIZED IDEOGRAPH REPRESENT + { 0x323A, BIDI_L }, // PARENTHESIZED IDEOGRAPH CALL + { 0x323B, BIDI_L }, // PARENTHESIZED IDEOGRAPH STUDY + { 0x323C, BIDI_L }, // PARENTHESIZED IDEOGRAPH SUPERVISE + { 0x323D, BIDI_L }, // PARENTHESIZED IDEOGRAPH ENTERPRISE + { 0x323E, BIDI_L }, // PARENTHESIZED IDEOGRAPH RESOURCE + { 0x323F, BIDI_L }, // PARENTHESIZED IDEOGRAPH ALLIANCE + { 0x3240, BIDI_L }, // PARENTHESIZED IDEOGRAPH FESTIVAL + { 0x3241, BIDI_L }, // PARENTHESIZED IDEOGRAPH REST + { 0x3242, BIDI_L }, // PARENTHESIZED IDEOGRAPH SELF + { 0x3243, BIDI_L }, // PARENTHESIZED IDEOGRAPH REACH + { 0x3244, BIDI_L }, // CIRCLED IDEOGRAPH QUESTION + { 0x3245, BIDI_L }, // CIRCLED IDEOGRAPH KINDERGARTEN + { 0x3246, BIDI_L }, // CIRCLED IDEOGRAPH SCHOOL + { 0x3247, BIDI_L }, // CIRCLED IDEOGRAPH KOTO + { 0x3248, BIDI_L }, // CIRCLED NUMBER TEN ON BLACK SQUARE + { 0x3249, BIDI_L }, // CIRCLED NUMBER TWENTY ON BLACK SQUARE + { 0x324A, BIDI_L }, // CIRCLED NUMBER THIRTY ON BLACK SQUARE + { 0x324B, BIDI_L }, // CIRCLED NUMBER FORTY ON BLACK SQUARE + { 0x324C, BIDI_L }, // CIRCLED NUMBER FIFTY ON BLACK SQUARE + { 0x324D, BIDI_L }, // CIRCLED NUMBER SIXTY ON BLACK SQUARE + { 0x324E, BIDI_L }, // CIRCLED NUMBER SEVENTY ON BLACK SQUARE + { 0x324F, BIDI_L }, // CIRCLED NUMBER EIGHTY ON BLACK SQUARE + { 0x3250, BIDI_ON }, // PARTNERSHIP SIGN + { 0x3251, BIDI_ON }, // CIRCLED NUMBER TWENTY ONE + { 0x3252, BIDI_ON }, // CIRCLED NUMBER TWENTY TWO + { 0x3253, BIDI_ON }, // CIRCLED NUMBER TWENTY THREE + { 0x3254, BIDI_ON }, // CIRCLED NUMBER TWENTY FOUR + { 0x3255, BIDI_ON }, // CIRCLED NUMBER TWENTY FIVE + { 0x3256, BIDI_ON }, // CIRCLED NUMBER TWENTY SIX + { 0x3257, BIDI_ON }, // CIRCLED NUMBER TWENTY SEVEN + { 0x3258, BIDI_ON }, // CIRCLED NUMBER TWENTY EIGHT + { 0x3259, BIDI_ON }, // CIRCLED NUMBER TWENTY NINE + { 0x325A, BIDI_ON }, // CIRCLED NUMBER THIRTY + { 0x325B, BIDI_ON }, // CIRCLED NUMBER THIRTY ONE + { 0x325C, BIDI_ON }, // CIRCLED NUMBER THIRTY TWO + { 0x325D, BIDI_ON }, // CIRCLED NUMBER THIRTY THREE + { 0x325E, BIDI_ON }, // CIRCLED NUMBER THIRTY FOUR + { 0x325F, BIDI_ON }, // CIRCLED NUMBER THIRTY FIVE + { 0x3260, BIDI_L }, // CIRCLED HANGUL KIYEOK + { 0x3261, BIDI_L }, // CIRCLED HANGUL NIEUN + { 0x3262, BIDI_L }, // CIRCLED HANGUL TIKEUT + { 0x3263, BIDI_L }, // CIRCLED HANGUL RIEUL + { 0x3264, BIDI_L }, // CIRCLED HANGUL MIEUM + { 0x3265, BIDI_L }, // CIRCLED HANGUL PIEUP + { 0x3266, BIDI_L }, // CIRCLED HANGUL SIOS + { 0x3267, BIDI_L }, // CIRCLED HANGUL IEUNG + { 0x3268, BIDI_L }, // CIRCLED HANGUL CIEUC + { 0x3269, BIDI_L }, // CIRCLED HANGUL CHIEUCH + { 0x326A, BIDI_L }, // CIRCLED HANGUL KHIEUKH + { 0x326B, BIDI_L }, // CIRCLED HANGUL THIEUTH + { 0x326C, BIDI_L }, // CIRCLED HANGUL PHIEUPH + { 0x326D, BIDI_L }, // CIRCLED HANGUL HIEUH + { 0x326E, BIDI_L }, // CIRCLED HANGUL KIYEOK A + { 0x326F, BIDI_L }, // CIRCLED HANGUL NIEUN A + { 0x3270, BIDI_L }, // CIRCLED HANGUL TIKEUT A + { 0x3271, BIDI_L }, // CIRCLED HANGUL RIEUL A + { 0x3272, BIDI_L }, // CIRCLED HANGUL MIEUM A + { 0x3273, BIDI_L }, // CIRCLED HANGUL PIEUP A + { 0x3274, BIDI_L }, // CIRCLED HANGUL SIOS A + { 0x3275, BIDI_L }, // CIRCLED HANGUL IEUNG A + { 0x3276, BIDI_L }, // CIRCLED HANGUL CIEUC A + { 0x3277, BIDI_L }, // CIRCLED HANGUL CHIEUCH A + { 0x3278, BIDI_L }, // CIRCLED HANGUL KHIEUKH A + { 0x3279, BIDI_L }, // CIRCLED HANGUL THIEUTH A + { 0x327A, BIDI_L }, // CIRCLED HANGUL PHIEUPH A + { 0x327B, BIDI_L }, // CIRCLED HANGUL HIEUH A + { 0x327C, BIDI_ON }, // CIRCLED KOREAN CHARACTER CHAMKO + { 0x327D, BIDI_ON }, // CIRCLED KOREAN CHARACTER JUEUI + { 0x327E, BIDI_ON }, // CIRCLED HANGUL IEUNG U + { 0x327F, BIDI_L }, // KOREAN STANDARD SYMBOL + { 0x3280, BIDI_L }, // CIRCLED IDEOGRAPH ONE + { 0x3281, BIDI_L }, // CIRCLED IDEOGRAPH TWO + { 0x3282, BIDI_L }, // CIRCLED IDEOGRAPH THREE + { 0x3283, BIDI_L }, // CIRCLED IDEOGRAPH FOUR + { 0x3284, BIDI_L }, // CIRCLED IDEOGRAPH FIVE + { 0x3285, BIDI_L }, // CIRCLED IDEOGRAPH SIX + { 0x3286, BIDI_L }, // CIRCLED IDEOGRAPH SEVEN + { 0x3287, BIDI_L }, // CIRCLED IDEOGRAPH EIGHT + { 0x3288, BIDI_L }, // CIRCLED IDEOGRAPH NINE + { 0x3289, BIDI_L }, // CIRCLED IDEOGRAPH TEN + { 0x328A, BIDI_L }, // CIRCLED IDEOGRAPH MOON + { 0x328B, BIDI_L }, // CIRCLED IDEOGRAPH FIRE + { 0x328C, BIDI_L }, // CIRCLED IDEOGRAPH WATER + { 0x328D, BIDI_L }, // CIRCLED IDEOGRAPH WOOD + { 0x328E, BIDI_L }, // CIRCLED IDEOGRAPH METAL + { 0x328F, BIDI_L }, // CIRCLED IDEOGRAPH EARTH + { 0x3290, BIDI_L }, // CIRCLED IDEOGRAPH SUN + { 0x3291, BIDI_L }, // CIRCLED IDEOGRAPH STOCK + { 0x3292, BIDI_L }, // CIRCLED IDEOGRAPH HAVE + { 0x3293, BIDI_L }, // CIRCLED IDEOGRAPH SOCIETY + { 0x3294, BIDI_L }, // CIRCLED IDEOGRAPH NAME + { 0x3295, BIDI_L }, // CIRCLED IDEOGRAPH SPECIAL + { 0x3296, BIDI_L }, // CIRCLED IDEOGRAPH FINANCIAL + { 0x3297, BIDI_L }, // CIRCLED IDEOGRAPH CONGRATULATION + { 0x3298, BIDI_L }, // CIRCLED IDEOGRAPH LABOR + { 0x3299, BIDI_L }, // CIRCLED IDEOGRAPH SECRET + { 0x329A, BIDI_L }, // CIRCLED IDEOGRAPH MALE + { 0x329B, BIDI_L }, // CIRCLED IDEOGRAPH FEMALE + { 0x329C, BIDI_L }, // CIRCLED IDEOGRAPH SUITABLE + { 0x329D, BIDI_L }, // CIRCLED IDEOGRAPH EXCELLENT + { 0x329E, BIDI_L }, // CIRCLED IDEOGRAPH PRINT + { 0x329F, BIDI_L }, // CIRCLED IDEOGRAPH ATTENTION + { 0x32A0, BIDI_L }, // CIRCLED IDEOGRAPH ITEM + { 0x32A1, BIDI_L }, // CIRCLED IDEOGRAPH REST + { 0x32A2, BIDI_L }, // CIRCLED IDEOGRAPH COPY + { 0x32A3, BIDI_L }, // CIRCLED IDEOGRAPH CORRECT + { 0x32A4, BIDI_L }, // CIRCLED IDEOGRAPH HIGH + { 0x32A5, BIDI_L }, // CIRCLED IDEOGRAPH CENTRE + { 0x32A6, BIDI_L }, // CIRCLED IDEOGRAPH LOW + { 0x32A7, BIDI_L }, // CIRCLED IDEOGRAPH LEFT + { 0x32A8, BIDI_L }, // CIRCLED IDEOGRAPH RIGHT + { 0x32A9, BIDI_L }, // CIRCLED IDEOGRAPH MEDICINE + { 0x32AA, BIDI_L }, // CIRCLED IDEOGRAPH RELIGION + { 0x32AB, BIDI_L }, // CIRCLED IDEOGRAPH STUDY + { 0x32AC, BIDI_L }, // CIRCLED IDEOGRAPH SUPERVISE + { 0x32AD, BIDI_L }, // CIRCLED IDEOGRAPH ENTERPRISE + { 0x32AE, BIDI_L }, // CIRCLED IDEOGRAPH RESOURCE + { 0x32AF, BIDI_L }, // CIRCLED IDEOGRAPH ALLIANCE + { 0x32B0, BIDI_L }, // CIRCLED IDEOGRAPH NIGHT + { 0x32B1, BIDI_ON }, // CIRCLED NUMBER THIRTY SIX + { 0x32B2, BIDI_ON }, // CIRCLED NUMBER THIRTY SEVEN + { 0x32B3, BIDI_ON }, // CIRCLED NUMBER THIRTY EIGHT + { 0x32B4, BIDI_ON }, // CIRCLED NUMBER THIRTY NINE + { 0x32B5, BIDI_ON }, // CIRCLED NUMBER FORTY + { 0x32B6, BIDI_ON }, // CIRCLED NUMBER FORTY ONE + { 0x32B7, BIDI_ON }, // CIRCLED NUMBER FORTY TWO + { 0x32B8, BIDI_ON }, // CIRCLED NUMBER FORTY THREE + { 0x32B9, BIDI_ON }, // CIRCLED NUMBER FORTY FOUR + { 0x32BA, BIDI_ON }, // CIRCLED NUMBER FORTY FIVE + { 0x32BB, BIDI_ON }, // CIRCLED NUMBER FORTY SIX + { 0x32BC, BIDI_ON }, // CIRCLED NUMBER FORTY SEVEN + { 0x32BD, BIDI_ON }, // CIRCLED NUMBER FORTY EIGHT + { 0x32BE, BIDI_ON }, // CIRCLED NUMBER FORTY NINE + { 0x32BF, BIDI_ON }, // CIRCLED NUMBER FIFTY + { 0x32C0, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR JANUARY + { 0x32C1, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR FEBRUARY + { 0x32C2, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR MARCH + { 0x32C3, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR APRIL + { 0x32C4, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR MAY + { 0x32C5, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR JUNE + { 0x32C6, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR JULY + { 0x32C7, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR AUGUST + { 0x32C8, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR SEPTEMBER + { 0x32C9, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR OCTOBER + { 0x32CA, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR NOVEMBER + { 0x32CB, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR DECEMBER + { 0x32CC, BIDI_ON }, // SQUARE HG + { 0x32CD, BIDI_ON }, // SQUARE ERG + { 0x32CE, BIDI_ON }, // SQUARE EV + { 0x32CF, BIDI_ON }, // LIMITED LIABILITY SIGN + { 0x32D0, BIDI_L }, // CIRCLED KATAKANA A + { 0x32D1, BIDI_L }, // CIRCLED KATAKANA I + { 0x32D2, BIDI_L }, // CIRCLED KATAKANA U + { 0x32D3, BIDI_L }, // CIRCLED KATAKANA E + { 0x32D4, BIDI_L }, // CIRCLED KATAKANA O + { 0x32D5, BIDI_L }, // CIRCLED KATAKANA KA + { 0x32D6, BIDI_L }, // CIRCLED KATAKANA KI + { 0x32D7, BIDI_L }, // CIRCLED KATAKANA KU + { 0x32D8, BIDI_L }, // CIRCLED KATAKANA KE + { 0x32D9, BIDI_L }, // CIRCLED KATAKANA KO + { 0x32DA, BIDI_L }, // CIRCLED KATAKANA SA + { 0x32DB, BIDI_L }, // CIRCLED KATAKANA SI + { 0x32DC, BIDI_L }, // CIRCLED KATAKANA SU + { 0x32DD, BIDI_L }, // CIRCLED KATAKANA SE + { 0x32DE, BIDI_L }, // CIRCLED KATAKANA SO + { 0x32DF, BIDI_L }, // CIRCLED KATAKANA TA + { 0x32E0, BIDI_L }, // CIRCLED KATAKANA TI + { 0x32E1, BIDI_L }, // CIRCLED KATAKANA TU + { 0x32E2, BIDI_L }, // CIRCLED KATAKANA TE + { 0x32E3, BIDI_L }, // CIRCLED KATAKANA TO + { 0x32E4, BIDI_L }, // CIRCLED KATAKANA NA + { 0x32E5, BIDI_L }, // CIRCLED KATAKANA NI + { 0x32E6, BIDI_L }, // CIRCLED KATAKANA NU + { 0x32E7, BIDI_L }, // CIRCLED KATAKANA NE + { 0x32E8, BIDI_L }, // CIRCLED KATAKANA NO + { 0x32E9, BIDI_L }, // CIRCLED KATAKANA HA + { 0x32EA, BIDI_L }, // CIRCLED KATAKANA HI + { 0x32EB, BIDI_L }, // CIRCLED KATAKANA HU + { 0x32EC, BIDI_L }, // CIRCLED KATAKANA HE + { 0x32ED, BIDI_L }, // CIRCLED KATAKANA HO + { 0x32EE, BIDI_L }, // CIRCLED KATAKANA MA + { 0x32EF, BIDI_L }, // CIRCLED KATAKANA MI + { 0x32F0, BIDI_L }, // CIRCLED KATAKANA MU + { 0x32F1, BIDI_L }, // CIRCLED KATAKANA ME + { 0x32F2, BIDI_L }, // CIRCLED KATAKANA MO + { 0x32F3, BIDI_L }, // CIRCLED KATAKANA YA + { 0x32F4, BIDI_L }, // CIRCLED KATAKANA YU + { 0x32F5, BIDI_L }, // CIRCLED KATAKANA YO + { 0x32F6, BIDI_L }, // CIRCLED KATAKANA RA + { 0x32F7, BIDI_L }, // CIRCLED KATAKANA RI + { 0x32F8, BIDI_L }, // CIRCLED KATAKANA RU + { 0x32F9, BIDI_L }, // CIRCLED KATAKANA RE + { 0x32FA, BIDI_L }, // CIRCLED KATAKANA RO + { 0x32FB, BIDI_L }, // CIRCLED KATAKANA WA + { 0x32FC, BIDI_L }, // CIRCLED KATAKANA WI + { 0x32FD, BIDI_L }, // CIRCLED KATAKANA WE + { 0x32FE, BIDI_L }, // CIRCLED KATAKANA WO + { 0x3300, BIDI_L }, // SQUARE APAATO + { 0x3301, BIDI_L }, // SQUARE ARUHUA + { 0x3302, BIDI_L }, // SQUARE ANPEA + { 0x3303, BIDI_L }, // SQUARE AARU + { 0x3304, BIDI_L }, // SQUARE ININGU + { 0x3305, BIDI_L }, // SQUARE INTI + { 0x3306, BIDI_L }, // SQUARE UON + { 0x3307, BIDI_L }, // SQUARE ESUKUUDO + { 0x3308, BIDI_L }, // SQUARE EEKAA + { 0x3309, BIDI_L }, // SQUARE ONSU + { 0x330A, BIDI_L }, // SQUARE OOMU + { 0x330B, BIDI_L }, // SQUARE KAIRI + { 0x330C, BIDI_L }, // SQUARE KARATTO + { 0x330D, BIDI_L }, // SQUARE KARORII + { 0x330E, BIDI_L }, // SQUARE GARON + { 0x330F, BIDI_L }, // SQUARE GANMA + { 0x3310, BIDI_L }, // SQUARE GIGA + { 0x3311, BIDI_L }, // SQUARE GINII + { 0x3312, BIDI_L }, // SQUARE KYURII + { 0x3313, BIDI_L }, // SQUARE GIRUDAA + { 0x3314, BIDI_L }, // SQUARE KIRO + { 0x3315, BIDI_L }, // SQUARE KIROGURAMU + { 0x3316, BIDI_L }, // SQUARE KIROMEETORU + { 0x3317, BIDI_L }, // SQUARE KIROWATTO + { 0x3318, BIDI_L }, // SQUARE GURAMU + { 0x3319, BIDI_L }, // SQUARE GURAMUTON + { 0x331A, BIDI_L }, // SQUARE KURUZEIRO + { 0x331B, BIDI_L }, // SQUARE KUROONE + { 0x331C, BIDI_L }, // SQUARE KEESU + { 0x331D, BIDI_L }, // SQUARE KORUNA + { 0x331E, BIDI_L }, // SQUARE KOOPO + { 0x331F, BIDI_L }, // SQUARE SAIKURU + { 0x3320, BIDI_L }, // SQUARE SANTIIMU + { 0x3321, BIDI_L }, // SQUARE SIRINGU + { 0x3322, BIDI_L }, // SQUARE SENTI + { 0x3323, BIDI_L }, // SQUARE SENTO + { 0x3324, BIDI_L }, // SQUARE DAASU + { 0x3325, BIDI_L }, // SQUARE DESI + { 0x3326, BIDI_L }, // SQUARE DORU + { 0x3327, BIDI_L }, // SQUARE TON + { 0x3328, BIDI_L }, // SQUARE NANO + { 0x3329, BIDI_L }, // SQUARE NOTTO + { 0x332A, BIDI_L }, // SQUARE HAITU + { 0x332B, BIDI_L }, // SQUARE PAASENTO + { 0x332C, BIDI_L }, // SQUARE PAATU + { 0x332D, BIDI_L }, // SQUARE BAARERU + { 0x332E, BIDI_L }, // SQUARE PIASUTORU + { 0x332F, BIDI_L }, // SQUARE PIKURU + { 0x3330, BIDI_L }, // SQUARE PIKO + { 0x3331, BIDI_L }, // SQUARE BIRU + { 0x3332, BIDI_L }, // SQUARE HUARADDO + { 0x3333, BIDI_L }, // SQUARE HUIITO + { 0x3334, BIDI_L }, // SQUARE BUSSYERU + { 0x3335, BIDI_L }, // SQUARE HURAN + { 0x3336, BIDI_L }, // SQUARE HEKUTAARU + { 0x3337, BIDI_L }, // SQUARE PESO + { 0x3338, BIDI_L }, // SQUARE PENIHI + { 0x3339, BIDI_L }, // SQUARE HERUTU + { 0x333A, BIDI_L }, // SQUARE PENSU + { 0x333B, BIDI_L }, // SQUARE PEEZI + { 0x333C, BIDI_L }, // SQUARE BEETA + { 0x333D, BIDI_L }, // SQUARE POINTO + { 0x333E, BIDI_L }, // SQUARE BORUTO + { 0x333F, BIDI_L }, // SQUARE HON + { 0x3340, BIDI_L }, // SQUARE PONDO + { 0x3341, BIDI_L }, // SQUARE HOORU + { 0x3342, BIDI_L }, // SQUARE HOON + { 0x3343, BIDI_L }, // SQUARE MAIKURO + { 0x3344, BIDI_L }, // SQUARE MAIRU + { 0x3345, BIDI_L }, // SQUARE MAHHA + { 0x3346, BIDI_L }, // SQUARE MARUKU + { 0x3347, BIDI_L }, // SQUARE MANSYON + { 0x3348, BIDI_L }, // SQUARE MIKURON + { 0x3349, BIDI_L }, // SQUARE MIRI + { 0x334A, BIDI_L }, // SQUARE MIRIBAARU + { 0x334B, BIDI_L }, // SQUARE MEGA + { 0x334C, BIDI_L }, // SQUARE MEGATON + { 0x334D, BIDI_L }, // SQUARE MEETORU + { 0x334E, BIDI_L }, // SQUARE YAADO + { 0x334F, BIDI_L }, // SQUARE YAARU + { 0x3350, BIDI_L }, // SQUARE YUAN + { 0x3351, BIDI_L }, // SQUARE RITTORU + { 0x3352, BIDI_L }, // SQUARE RIRA + { 0x3353, BIDI_L }, // SQUARE RUPII + { 0x3354, BIDI_L }, // SQUARE RUUBURU + { 0x3355, BIDI_L }, // SQUARE REMU + { 0x3356, BIDI_L }, // SQUARE RENTOGEN + { 0x3357, BIDI_L }, // SQUARE WATTO + { 0x3358, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ZERO + { 0x3359, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ONE + { 0x335A, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWO + { 0x335B, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR THREE + { 0x335C, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FOUR + { 0x335D, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FIVE + { 0x335E, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SIX + { 0x335F, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SEVEN + { 0x3360, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR EIGHT + { 0x3361, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR NINE + { 0x3362, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TEN + { 0x3363, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ELEVEN + { 0x3364, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWELVE + { 0x3365, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR THIRTEEN + { 0x3366, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FOURTEEN + { 0x3367, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FIFTEEN + { 0x3368, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SIXTEEN + { 0x3369, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SEVENTEEN + { 0x336A, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR EIGHTEEN + { 0x336B, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR NINETEEN + { 0x336C, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY + { 0x336D, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-ONE + { 0x336E, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-TWO + { 0x336F, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-THREE + { 0x3370, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-FOUR + { 0x3371, BIDI_L }, // SQUARE HPA + { 0x3372, BIDI_L }, // SQUARE DA + { 0x3373, BIDI_L }, // SQUARE AU + { 0x3374, BIDI_L }, // SQUARE BAR + { 0x3375, BIDI_L }, // SQUARE OV + { 0x3376, BIDI_L }, // SQUARE PC + { 0x3377, BIDI_ON }, // SQUARE DM + { 0x3378, BIDI_ON }, // SQUARE DM SQUARED + { 0x3379, BIDI_ON }, // SQUARE DM CUBED + { 0x337A, BIDI_ON }, // SQUARE IU + { 0x337B, BIDI_L }, // SQUARE ERA NAME HEISEI + { 0x337C, BIDI_L }, // SQUARE ERA NAME SYOUWA + { 0x337D, BIDI_L }, // SQUARE ERA NAME TAISYOU + { 0x337E, BIDI_L }, // SQUARE ERA NAME MEIZI + { 0x337F, BIDI_L }, // SQUARE CORPORATION + { 0x3380, BIDI_L }, // SQUARE PA AMPS + { 0x3381, BIDI_L }, // SQUARE NA + { 0x3382, BIDI_L }, // SQUARE MU A + { 0x3383, BIDI_L }, // SQUARE MA + { 0x3384, BIDI_L }, // SQUARE KA + { 0x3385, BIDI_L }, // SQUARE KB + { 0x3386, BIDI_L }, // SQUARE MB + { 0x3387, BIDI_L }, // SQUARE GB + { 0x3388, BIDI_L }, // SQUARE CAL + { 0x3389, BIDI_L }, // SQUARE KCAL + { 0x338A, BIDI_L }, // SQUARE PF + { 0x338B, BIDI_L }, // SQUARE NF + { 0x338C, BIDI_L }, // SQUARE MU F + { 0x338D, BIDI_L }, // SQUARE MU G + { 0x338E, BIDI_L }, // SQUARE MG + { 0x338F, BIDI_L }, // SQUARE KG + { 0x3390, BIDI_L }, // SQUARE HZ + { 0x3391, BIDI_L }, // SQUARE KHZ + { 0x3392, BIDI_L }, // SQUARE MHZ + { 0x3393, BIDI_L }, // SQUARE GHZ + { 0x3394, BIDI_L }, // SQUARE THZ + { 0x3395, BIDI_L }, // SQUARE MU L + { 0x3396, BIDI_L }, // SQUARE ML + { 0x3397, BIDI_L }, // SQUARE DL + { 0x3398, BIDI_L }, // SQUARE KL + { 0x3399, BIDI_L }, // SQUARE FM + { 0x339A, BIDI_L }, // SQUARE NM + { 0x339B, BIDI_L }, // SQUARE MU M + { 0x339C, BIDI_L }, // SQUARE MM + { 0x339D, BIDI_L }, // SQUARE CM + { 0x339E, BIDI_L }, // SQUARE KM + { 0x339F, BIDI_L }, // SQUARE MM SQUARED + { 0x33A0, BIDI_L }, // SQUARE CM SQUARED + { 0x33A1, BIDI_L }, // SQUARE M SQUARED + { 0x33A2, BIDI_L }, // SQUARE KM SQUARED + { 0x33A3, BIDI_L }, // SQUARE MM CUBED + { 0x33A4, BIDI_L }, // SQUARE CM CUBED + { 0x33A5, BIDI_L }, // SQUARE M CUBED + { 0x33A6, BIDI_L }, // SQUARE KM CUBED + { 0x33A7, BIDI_L }, // SQUARE M OVER S + { 0x33A8, BIDI_L }, // SQUARE M OVER S SQUARED + { 0x33A9, BIDI_L }, // SQUARE PA + { 0x33AA, BIDI_L }, // SQUARE KPA + { 0x33AB, BIDI_L }, // SQUARE MPA + { 0x33AC, BIDI_L }, // SQUARE GPA + { 0x33AD, BIDI_L }, // SQUARE RAD + { 0x33AE, BIDI_L }, // SQUARE RAD OVER S + { 0x33AF, BIDI_L }, // SQUARE RAD OVER S SQUARED + { 0x33B0, BIDI_L }, // SQUARE PS + { 0x33B1, BIDI_L }, // SQUARE NS + { 0x33B2, BIDI_L }, // SQUARE MU S + { 0x33B3, BIDI_L }, // SQUARE MS + { 0x33B4, BIDI_L }, // SQUARE PV + { 0x33B5, BIDI_L }, // SQUARE NV + { 0x33B6, BIDI_L }, // SQUARE MU V + { 0x33B7, BIDI_L }, // SQUARE MV + { 0x33B8, BIDI_L }, // SQUARE KV + { 0x33B9, BIDI_L }, // SQUARE MV MEGA + { 0x33BA, BIDI_L }, // SQUARE PW + { 0x33BB, BIDI_L }, // SQUARE NW + { 0x33BC, BIDI_L }, // SQUARE MU W + { 0x33BD, BIDI_L }, // SQUARE MW + { 0x33BE, BIDI_L }, // SQUARE KW + { 0x33BF, BIDI_L }, // SQUARE MW MEGA + { 0x33C0, BIDI_L }, // SQUARE K OHM + { 0x33C1, BIDI_L }, // SQUARE M OHM + { 0x33C2, BIDI_L }, // SQUARE AM + { 0x33C3, BIDI_L }, // SQUARE BQ + { 0x33C4, BIDI_L }, // SQUARE CC + { 0x33C5, BIDI_L }, // SQUARE CD + { 0x33C6, BIDI_L }, // SQUARE C OVER KG + { 0x33C7, BIDI_L }, // SQUARE CO + { 0x33C8, BIDI_L }, // SQUARE DB + { 0x33C9, BIDI_L }, // SQUARE GY + { 0x33CA, BIDI_L }, // SQUARE HA + { 0x33CB, BIDI_L }, // SQUARE HP + { 0x33CC, BIDI_L }, // SQUARE IN + { 0x33CD, BIDI_L }, // SQUARE KK + { 0x33CE, BIDI_L }, // SQUARE KM CAPITAL + { 0x33CF, BIDI_L }, // SQUARE KT + { 0x33D0, BIDI_L }, // SQUARE LM + { 0x33D1, BIDI_L }, // SQUARE LN + { 0x33D2, BIDI_L }, // SQUARE LOG + { 0x33D3, BIDI_L }, // SQUARE LX + { 0x33D4, BIDI_L }, // SQUARE MB SMALL + { 0x33D5, BIDI_L }, // SQUARE MIL + { 0x33D6, BIDI_L }, // SQUARE MOL + { 0x33D7, BIDI_L }, // SQUARE PH + { 0x33D8, BIDI_L }, // SQUARE PM + { 0x33D9, BIDI_L }, // SQUARE PPM + { 0x33DA, BIDI_L }, // SQUARE PR + { 0x33DB, BIDI_L }, // SQUARE SR + { 0x33DC, BIDI_L }, // SQUARE SV + { 0x33DD, BIDI_L }, // SQUARE WB + { 0x33DE, BIDI_ON }, // SQUARE V OVER M + { 0x33DF, BIDI_ON }, // SQUARE A OVER M + { 0x33E0, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY ONE + { 0x33E1, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWO + { 0x33E2, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THREE + { 0x33E3, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FOUR + { 0x33E4, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FIVE + { 0x33E5, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SIX + { 0x33E6, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SEVEN + { 0x33E7, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY EIGHT + { 0x33E8, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY NINE + { 0x33E9, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TEN + { 0x33EA, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY ELEVEN + { 0x33EB, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWELVE + { 0x33EC, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTEEN + { 0x33ED, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FOURTEEN + { 0x33EE, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FIFTEEN + { 0x33EF, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SIXTEEN + { 0x33F0, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SEVENTEEN + { 0x33F1, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY EIGHTEEN + { 0x33F2, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY NINETEEN + { 0x33F3, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY + { 0x33F4, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-ONE + { 0x33F5, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-TWO + { 0x33F6, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-THREE + { 0x33F7, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-FOUR + { 0x33F8, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-FIVE + { 0x33F9, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-SIX + { 0x33FA, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-SEVEN + { 0x33FB, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-EIGHT + { 0x33FC, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-NINE + { 0x33FD, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTY + { 0x33FE, BIDI_L }, // IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTY-ONE + { 0x33FF, BIDI_ON }, // SQUARE GAL + //{ 0x3400, BIDI_L }, // + //{ 0x4DB5, BIDI_L }, // + +#endif +#if (GUI_BIDI_SUPPORT_RANGE_4 == 1) + + { 0x4DC0, BIDI_ON }, // HEXAGRAM FOR THE CREATIVE HEAVEN + { 0x4DC1, BIDI_ON }, // HEXAGRAM FOR THE RECEPTIVE EARTH + { 0x4DC2, BIDI_ON }, // HEXAGRAM FOR DIFFICULTY AT THE BEGINNING + { 0x4DC3, BIDI_ON }, // HEXAGRAM FOR YOUTHFUL FOLLY + { 0x4DC4, BIDI_ON }, // HEXAGRAM FOR WAITING + { 0x4DC5, BIDI_ON }, // HEXAGRAM FOR CONFLICT + { 0x4DC6, BIDI_ON }, // HEXAGRAM FOR THE ARMY + { 0x4DC7, BIDI_ON }, // HEXAGRAM FOR HOLDING TOGETHER + { 0x4DC8, BIDI_ON }, // HEXAGRAM FOR SMALL TAMING + { 0x4DC9, BIDI_ON }, // HEXAGRAM FOR TREADING + { 0x4DCA, BIDI_ON }, // HEXAGRAM FOR PEACE + { 0x4DCB, BIDI_ON }, // HEXAGRAM FOR STANDSTILL + { 0x4DCC, BIDI_ON }, // HEXAGRAM FOR FELLOWSHIP + { 0x4DCD, BIDI_ON }, // HEXAGRAM FOR GREAT POSSESSION + { 0x4DCE, BIDI_ON }, // HEXAGRAM FOR MODESTY + { 0x4DCF, BIDI_ON }, // HEXAGRAM FOR ENTHUSIASM + { 0x4DD0, BIDI_ON }, // HEXAGRAM FOR FOLLOWING + { 0x4DD1, BIDI_ON }, // HEXAGRAM FOR WORK ON THE DECAYED + { 0x4DD2, BIDI_ON }, // HEXAGRAM FOR APPROACH + { 0x4DD3, BIDI_ON }, // HEXAGRAM FOR CONTEMPLATION + { 0x4DD4, BIDI_ON }, // HEXAGRAM FOR BITING THROUGH + { 0x4DD5, BIDI_ON }, // HEXAGRAM FOR GRACE + { 0x4DD6, BIDI_ON }, // HEXAGRAM FOR SPLITTING APART + { 0x4DD7, BIDI_ON }, // HEXAGRAM FOR RETURN + { 0x4DD8, BIDI_ON }, // HEXAGRAM FOR INNOCENCE + { 0x4DD9, BIDI_ON }, // HEXAGRAM FOR GREAT TAMING + { 0x4DDA, BIDI_ON }, // HEXAGRAM FOR MOUTH CORNERS + { 0x4DDB, BIDI_ON }, // HEXAGRAM FOR GREAT PREPONDERANCE + { 0x4DDC, BIDI_ON }, // HEXAGRAM FOR THE ABYSMAL WATER + { 0x4DDD, BIDI_ON }, // HEXAGRAM FOR THE CLINGING FIRE + { 0x4DDE, BIDI_ON }, // HEXAGRAM FOR INFLUENCE + { 0x4DDF, BIDI_ON }, // HEXAGRAM FOR DURATION + { 0x4DE0, BIDI_ON }, // HEXAGRAM FOR RETREAT + { 0x4DE1, BIDI_ON }, // HEXAGRAM FOR GREAT POWER + { 0x4DE2, BIDI_ON }, // HEXAGRAM FOR PROGRESS + { 0x4DE3, BIDI_ON }, // HEXAGRAM FOR DARKENING OF THE LIGHT + { 0x4DE4, BIDI_ON }, // HEXAGRAM FOR THE FAMILY + { 0x4DE5, BIDI_ON }, // HEXAGRAM FOR OPPOSITION + { 0x4DE6, BIDI_ON }, // HEXAGRAM FOR OBSTRUCTION + { 0x4DE7, BIDI_ON }, // HEXAGRAM FOR DELIVERANCE + { 0x4DE8, BIDI_ON }, // HEXAGRAM FOR DECREASE + { 0x4DE9, BIDI_ON }, // HEXAGRAM FOR INCREASE + { 0x4DEA, BIDI_ON }, // HEXAGRAM FOR BREAKTHROUGH + { 0x4DEB, BIDI_ON }, // HEXAGRAM FOR COMING TO MEET + { 0x4DEC, BIDI_ON }, // HEXAGRAM FOR GATHERING TOGETHER + { 0x4DED, BIDI_ON }, // HEXAGRAM FOR PUSHING UPWARD + { 0x4DEE, BIDI_ON }, // HEXAGRAM FOR OPPRESSION + { 0x4DEF, BIDI_ON }, // HEXAGRAM FOR THE WELL + { 0x4DF0, BIDI_ON }, // HEXAGRAM FOR REVOLUTION + { 0x4DF1, BIDI_ON }, // HEXAGRAM FOR THE CAULDRON + { 0x4DF2, BIDI_ON }, // HEXAGRAM FOR THE AROUSING THUNDER + { 0x4DF3, BIDI_ON }, // HEXAGRAM FOR THE KEEPING STILL MOUNTAIN + { 0x4DF4, BIDI_ON }, // HEXAGRAM FOR DEVELOPMENT + { 0x4DF5, BIDI_ON }, // HEXAGRAM FOR THE MARRYING MAIDEN + { 0x4DF6, BIDI_ON }, // HEXAGRAM FOR ABUNDANCE + { 0x4DF7, BIDI_ON }, // HEXAGRAM FOR THE WANDERER + { 0x4DF8, BIDI_ON }, // HEXAGRAM FOR THE GENTLE WIND + { 0x4DF9, BIDI_ON }, // HEXAGRAM FOR THE JOYOUS LAKE + { 0x4DFA, BIDI_ON }, // HEXAGRAM FOR DISPERSION + { 0x4DFB, BIDI_ON }, // HEXAGRAM FOR LIMITATION + { 0x4DFC, BIDI_ON }, // HEXAGRAM FOR INNER TRUTH + { 0x4DFD, BIDI_ON }, // HEXAGRAM FOR SMALL PREPONDERANCE + { 0x4DFE, BIDI_ON }, // HEXAGRAM FOR AFTER COMPLETION + { 0x4DFF, BIDI_ON }, // HEXAGRAM FOR BEFORE COMPLETION + //{ 0x4E00, BIDI_L }, // + //{ 0x9FD5, BIDI_L }, // + +#endif +#if (GUI_BIDI_SUPPORT_RANGE_A == 1) + + { 0xA000, BIDI_L }, // YI SYLLABLE IT + { 0xA001, BIDI_L }, // YI SYLLABLE IX + { 0xA002, BIDI_L }, // YI SYLLABLE I + { 0xA003, BIDI_L }, // YI SYLLABLE IP + { 0xA004, BIDI_L }, // YI SYLLABLE IET + { 0xA005, BIDI_L }, // YI SYLLABLE IEX + { 0xA006, BIDI_L }, // YI SYLLABLE IE + { 0xA007, BIDI_L }, // YI SYLLABLE IEP + { 0xA008, BIDI_L }, // YI SYLLABLE AT + { 0xA009, BIDI_L }, // YI SYLLABLE AX + { 0xA00A, BIDI_L }, // YI SYLLABLE A + { 0xA00B, BIDI_L }, // YI SYLLABLE AP + { 0xA00C, BIDI_L }, // YI SYLLABLE UOX + { 0xA00D, BIDI_L }, // YI SYLLABLE UO + { 0xA00E, BIDI_L }, // YI SYLLABLE UOP + { 0xA00F, BIDI_L }, // YI SYLLABLE OT + { 0xA010, BIDI_L }, // YI SYLLABLE OX + { 0xA011, BIDI_L }, // YI SYLLABLE O + { 0xA012, BIDI_L }, // YI SYLLABLE OP + { 0xA013, BIDI_L }, // YI SYLLABLE EX + { 0xA014, BIDI_L }, // YI SYLLABLE E + { 0xA015, BIDI_L }, // YI SYLLABLE WU + { 0xA016, BIDI_L }, // YI SYLLABLE BIT + { 0xA017, BIDI_L }, // YI SYLLABLE BIX + { 0xA018, BIDI_L }, // YI SYLLABLE BI + { 0xA019, BIDI_L }, // YI SYLLABLE BIP + { 0xA01A, BIDI_L }, // YI SYLLABLE BIET + { 0xA01B, BIDI_L }, // YI SYLLABLE BIEX + { 0xA01C, BIDI_L }, // YI SYLLABLE BIE + { 0xA01D, BIDI_L }, // YI SYLLABLE BIEP + { 0xA01E, BIDI_L }, // YI SYLLABLE BAT + { 0xA01F, BIDI_L }, // YI SYLLABLE BAX + { 0xA020, BIDI_L }, // YI SYLLABLE BA + { 0xA021, BIDI_L }, // YI SYLLABLE BAP + { 0xA022, BIDI_L }, // YI SYLLABLE BUOX + { 0xA023, BIDI_L }, // YI SYLLABLE BUO + { 0xA024, BIDI_L }, // YI SYLLABLE BUOP + { 0xA025, BIDI_L }, // YI SYLLABLE BOT + { 0xA026, BIDI_L }, // YI SYLLABLE BOX + { 0xA027, BIDI_L }, // YI SYLLABLE BO + { 0xA028, BIDI_L }, // YI SYLLABLE BOP + { 0xA029, BIDI_L }, // YI SYLLABLE BEX + { 0xA02A, BIDI_L }, // YI SYLLABLE BE + { 0xA02B, BIDI_L }, // YI SYLLABLE BEP + { 0xA02C, BIDI_L }, // YI SYLLABLE BUT + { 0xA02D, BIDI_L }, // YI SYLLABLE BUX + { 0xA02E, BIDI_L }, // YI SYLLABLE BU + { 0xA02F, BIDI_L }, // YI SYLLABLE BUP + { 0xA030, BIDI_L }, // YI SYLLABLE BURX + { 0xA031, BIDI_L }, // YI SYLLABLE BUR + { 0xA032, BIDI_L }, // YI SYLLABLE BYT + { 0xA033, BIDI_L }, // YI SYLLABLE BYX + { 0xA034, BIDI_L }, // YI SYLLABLE BY + { 0xA035, BIDI_L }, // YI SYLLABLE BYP + { 0xA036, BIDI_L }, // YI SYLLABLE BYRX + { 0xA037, BIDI_L }, // YI SYLLABLE BYR + { 0xA038, BIDI_L }, // YI SYLLABLE PIT + { 0xA039, BIDI_L }, // YI SYLLABLE PIX + { 0xA03A, BIDI_L }, // YI SYLLABLE PI + { 0xA03B, BIDI_L }, // YI SYLLABLE PIP + { 0xA03C, BIDI_L }, // YI SYLLABLE PIEX + { 0xA03D, BIDI_L }, // YI SYLLABLE PIE + { 0xA03E, BIDI_L }, // YI SYLLABLE PIEP + { 0xA03F, BIDI_L }, // YI SYLLABLE PAT + { 0xA040, BIDI_L }, // YI SYLLABLE PAX + { 0xA041, BIDI_L }, // YI SYLLABLE PA + { 0xA042, BIDI_L }, // YI SYLLABLE PAP + { 0xA043, BIDI_L }, // YI SYLLABLE PUOX + { 0xA044, BIDI_L }, // YI SYLLABLE PUO + { 0xA045, BIDI_L }, // YI SYLLABLE PUOP + { 0xA046, BIDI_L }, // YI SYLLABLE POT + { 0xA047, BIDI_L }, // YI SYLLABLE POX + { 0xA048, BIDI_L }, // YI SYLLABLE PO + { 0xA049, BIDI_L }, // YI SYLLABLE POP + { 0xA04A, BIDI_L }, // YI SYLLABLE PUT + { 0xA04B, BIDI_L }, // YI SYLLABLE PUX + { 0xA04C, BIDI_L }, // YI SYLLABLE PU + { 0xA04D, BIDI_L }, // YI SYLLABLE PUP + { 0xA04E, BIDI_L }, // YI SYLLABLE PURX + { 0xA04F, BIDI_L }, // YI SYLLABLE PUR + { 0xA050, BIDI_L }, // YI SYLLABLE PYT + { 0xA051, BIDI_L }, // YI SYLLABLE PYX + { 0xA052, BIDI_L }, // YI SYLLABLE PY + { 0xA053, BIDI_L }, // YI SYLLABLE PYP + { 0xA054, BIDI_L }, // YI SYLLABLE PYRX + { 0xA055, BIDI_L }, // YI SYLLABLE PYR + { 0xA056, BIDI_L }, // YI SYLLABLE BBIT + { 0xA057, BIDI_L }, // YI SYLLABLE BBIX + { 0xA058, BIDI_L }, // YI SYLLABLE BBI + { 0xA059, BIDI_L }, // YI SYLLABLE BBIP + { 0xA05A, BIDI_L }, // YI SYLLABLE BBIET + { 0xA05B, BIDI_L }, // YI SYLLABLE BBIEX + { 0xA05C, BIDI_L }, // YI SYLLABLE BBIE + { 0xA05D, BIDI_L }, // YI SYLLABLE BBIEP + { 0xA05E, BIDI_L }, // YI SYLLABLE BBAT + { 0xA05F, BIDI_L }, // YI SYLLABLE BBAX + { 0xA060, BIDI_L }, // YI SYLLABLE BBA + { 0xA061, BIDI_L }, // YI SYLLABLE BBAP + { 0xA062, BIDI_L }, // YI SYLLABLE BBUOX + { 0xA063, BIDI_L }, // YI SYLLABLE BBUO + { 0xA064, BIDI_L }, // YI SYLLABLE BBUOP + { 0xA065, BIDI_L }, // YI SYLLABLE BBOT + { 0xA066, BIDI_L }, // YI SYLLABLE BBOX + { 0xA067, BIDI_L }, // YI SYLLABLE BBO + { 0xA068, BIDI_L }, // YI SYLLABLE BBOP + { 0xA069, BIDI_L }, // YI SYLLABLE BBEX + { 0xA06A, BIDI_L }, // YI SYLLABLE BBE + { 0xA06B, BIDI_L }, // YI SYLLABLE BBEP + { 0xA06C, BIDI_L }, // YI SYLLABLE BBUT + { 0xA06D, BIDI_L }, // YI SYLLABLE BBUX + { 0xA06E, BIDI_L }, // YI SYLLABLE BBU + { 0xA06F, BIDI_L }, // YI SYLLABLE BBUP + { 0xA070, BIDI_L }, // YI SYLLABLE BBURX + { 0xA071, BIDI_L }, // YI SYLLABLE BBUR + { 0xA072, BIDI_L }, // YI SYLLABLE BBYT + { 0xA073, BIDI_L }, // YI SYLLABLE BBYX + { 0xA074, BIDI_L }, // YI SYLLABLE BBY + { 0xA075, BIDI_L }, // YI SYLLABLE BBYP + { 0xA076, BIDI_L }, // YI SYLLABLE NBIT + { 0xA077, BIDI_L }, // YI SYLLABLE NBIX + { 0xA078, BIDI_L }, // YI SYLLABLE NBI + { 0xA079, BIDI_L }, // YI SYLLABLE NBIP + { 0xA07A, BIDI_L }, // YI SYLLABLE NBIEX + { 0xA07B, BIDI_L }, // YI SYLLABLE NBIE + { 0xA07C, BIDI_L }, // YI SYLLABLE NBIEP + { 0xA07D, BIDI_L }, // YI SYLLABLE NBAT + { 0xA07E, BIDI_L }, // YI SYLLABLE NBAX + { 0xA07F, BIDI_L }, // YI SYLLABLE NBA + { 0xA080, BIDI_L }, // YI SYLLABLE NBAP + { 0xA081, BIDI_L }, // YI SYLLABLE NBOT + { 0xA082, BIDI_L }, // YI SYLLABLE NBOX + { 0xA083, BIDI_L }, // YI SYLLABLE NBO + { 0xA084, BIDI_L }, // YI SYLLABLE NBOP + { 0xA085, BIDI_L }, // YI SYLLABLE NBUT + { 0xA086, BIDI_L }, // YI SYLLABLE NBUX + { 0xA087, BIDI_L }, // YI SYLLABLE NBU + { 0xA088, BIDI_L }, // YI SYLLABLE NBUP + { 0xA089, BIDI_L }, // YI SYLLABLE NBURX + { 0xA08A, BIDI_L }, // YI SYLLABLE NBUR + { 0xA08B, BIDI_L }, // YI SYLLABLE NBYT + { 0xA08C, BIDI_L }, // YI SYLLABLE NBYX + { 0xA08D, BIDI_L }, // YI SYLLABLE NBY + { 0xA08E, BIDI_L }, // YI SYLLABLE NBYP + { 0xA08F, BIDI_L }, // YI SYLLABLE NBYRX + { 0xA090, BIDI_L }, // YI SYLLABLE NBYR + { 0xA091, BIDI_L }, // YI SYLLABLE HMIT + { 0xA092, BIDI_L }, // YI SYLLABLE HMIX + { 0xA093, BIDI_L }, // YI SYLLABLE HMI + { 0xA094, BIDI_L }, // YI SYLLABLE HMIP + { 0xA095, BIDI_L }, // YI SYLLABLE HMIEX + { 0xA096, BIDI_L }, // YI SYLLABLE HMIE + { 0xA097, BIDI_L }, // YI SYLLABLE HMIEP + { 0xA098, BIDI_L }, // YI SYLLABLE HMAT + { 0xA099, BIDI_L }, // YI SYLLABLE HMAX + { 0xA09A, BIDI_L }, // YI SYLLABLE HMA + { 0xA09B, BIDI_L }, // YI SYLLABLE HMAP + { 0xA09C, BIDI_L }, // YI SYLLABLE HMUOX + { 0xA09D, BIDI_L }, // YI SYLLABLE HMUO + { 0xA09E, BIDI_L }, // YI SYLLABLE HMUOP + { 0xA09F, BIDI_L }, // YI SYLLABLE HMOT + { 0xA0A0, BIDI_L }, // YI SYLLABLE HMOX + { 0xA0A1, BIDI_L }, // YI SYLLABLE HMO + { 0xA0A2, BIDI_L }, // YI SYLLABLE HMOP + { 0xA0A3, BIDI_L }, // YI SYLLABLE HMUT + { 0xA0A4, BIDI_L }, // YI SYLLABLE HMUX + { 0xA0A5, BIDI_L }, // YI SYLLABLE HMU + { 0xA0A6, BIDI_L }, // YI SYLLABLE HMUP + { 0xA0A7, BIDI_L }, // YI SYLLABLE HMURX + { 0xA0A8, BIDI_L }, // YI SYLLABLE HMUR + { 0xA0A9, BIDI_L }, // YI SYLLABLE HMYX + { 0xA0AA, BIDI_L }, // YI SYLLABLE HMY + { 0xA0AB, BIDI_L }, // YI SYLLABLE HMYP + { 0xA0AC, BIDI_L }, // YI SYLLABLE HMYRX + { 0xA0AD, BIDI_L }, // YI SYLLABLE HMYR + { 0xA0AE, BIDI_L }, // YI SYLLABLE MIT + { 0xA0AF, BIDI_L }, // YI SYLLABLE MIX + { 0xA0B0, BIDI_L }, // YI SYLLABLE MI + { 0xA0B1, BIDI_L }, // YI SYLLABLE MIP + { 0xA0B2, BIDI_L }, // YI SYLLABLE MIEX + { 0xA0B3, BIDI_L }, // YI SYLLABLE MIE + { 0xA0B4, BIDI_L }, // YI SYLLABLE MIEP + { 0xA0B5, BIDI_L }, // YI SYLLABLE MAT + { 0xA0B6, BIDI_L }, // YI SYLLABLE MAX + { 0xA0B7, BIDI_L }, // YI SYLLABLE MA + { 0xA0B8, BIDI_L }, // YI SYLLABLE MAP + { 0xA0B9, BIDI_L }, // YI SYLLABLE MUOT + { 0xA0BA, BIDI_L }, // YI SYLLABLE MUOX + { 0xA0BB, BIDI_L }, // YI SYLLABLE MUO + { 0xA0BC, BIDI_L }, // YI SYLLABLE MUOP + { 0xA0BD, BIDI_L }, // YI SYLLABLE MOT + { 0xA0BE, BIDI_L }, // YI SYLLABLE MOX + { 0xA0BF, BIDI_L }, // YI SYLLABLE MO + { 0xA0C0, BIDI_L }, // YI SYLLABLE MOP + { 0xA0C1, BIDI_L }, // YI SYLLABLE MEX + { 0xA0C2, BIDI_L }, // YI SYLLABLE ME + { 0xA0C3, BIDI_L }, // YI SYLLABLE MUT + { 0xA0C4, BIDI_L }, // YI SYLLABLE MUX + { 0xA0C5, BIDI_L }, // YI SYLLABLE MU + { 0xA0C6, BIDI_L }, // YI SYLLABLE MUP + { 0xA0C7, BIDI_L }, // YI SYLLABLE MURX + { 0xA0C8, BIDI_L }, // YI SYLLABLE MUR + { 0xA0C9, BIDI_L }, // YI SYLLABLE MYT + { 0xA0CA, BIDI_L }, // YI SYLLABLE MYX + { 0xA0CB, BIDI_L }, // YI SYLLABLE MY + { 0xA0CC, BIDI_L }, // YI SYLLABLE MYP + { 0xA0CD, BIDI_L }, // YI SYLLABLE FIT + { 0xA0CE, BIDI_L }, // YI SYLLABLE FIX + { 0xA0CF, BIDI_L }, // YI SYLLABLE FI + { 0xA0D0, BIDI_L }, // YI SYLLABLE FIP + { 0xA0D1, BIDI_L }, // YI SYLLABLE FAT + { 0xA0D2, BIDI_L }, // YI SYLLABLE FAX + { 0xA0D3, BIDI_L }, // YI SYLLABLE FA + { 0xA0D4, BIDI_L }, // YI SYLLABLE FAP + { 0xA0D5, BIDI_L }, // YI SYLLABLE FOX + { 0xA0D6, BIDI_L }, // YI SYLLABLE FO + { 0xA0D7, BIDI_L }, // YI SYLLABLE FOP + { 0xA0D8, BIDI_L }, // YI SYLLABLE FUT + { 0xA0D9, BIDI_L }, // YI SYLLABLE FUX + { 0xA0DA, BIDI_L }, // YI SYLLABLE FU + { 0xA0DB, BIDI_L }, // YI SYLLABLE FUP + { 0xA0DC, BIDI_L }, // YI SYLLABLE FURX + { 0xA0DD, BIDI_L }, // YI SYLLABLE FUR + { 0xA0DE, BIDI_L }, // YI SYLLABLE FYT + { 0xA0DF, BIDI_L }, // YI SYLLABLE FYX + { 0xA0E0, BIDI_L }, // YI SYLLABLE FY + { 0xA0E1, BIDI_L }, // YI SYLLABLE FYP + { 0xA0E2, BIDI_L }, // YI SYLLABLE VIT + { 0xA0E3, BIDI_L }, // YI SYLLABLE VIX + { 0xA0E4, BIDI_L }, // YI SYLLABLE VI + { 0xA0E5, BIDI_L }, // YI SYLLABLE VIP + { 0xA0E6, BIDI_L }, // YI SYLLABLE VIET + { 0xA0E7, BIDI_L }, // YI SYLLABLE VIEX + { 0xA0E8, BIDI_L }, // YI SYLLABLE VIE + { 0xA0E9, BIDI_L }, // YI SYLLABLE VIEP + { 0xA0EA, BIDI_L }, // YI SYLLABLE VAT + { 0xA0EB, BIDI_L }, // YI SYLLABLE VAX + { 0xA0EC, BIDI_L }, // YI SYLLABLE VA + { 0xA0ED, BIDI_L }, // YI SYLLABLE VAP + { 0xA0EE, BIDI_L }, // YI SYLLABLE VOT + { 0xA0EF, BIDI_L }, // YI SYLLABLE VOX + { 0xA0F0, BIDI_L }, // YI SYLLABLE VO + { 0xA0F1, BIDI_L }, // YI SYLLABLE VOP + { 0xA0F2, BIDI_L }, // YI SYLLABLE VEX + { 0xA0F3, BIDI_L }, // YI SYLLABLE VEP + { 0xA0F4, BIDI_L }, // YI SYLLABLE VUT + { 0xA0F5, BIDI_L }, // YI SYLLABLE VUX + { 0xA0F6, BIDI_L }, // YI SYLLABLE VU + { 0xA0F7, BIDI_L }, // YI SYLLABLE VUP + { 0xA0F8, BIDI_L }, // YI SYLLABLE VURX + { 0xA0F9, BIDI_L }, // YI SYLLABLE VUR + { 0xA0FA, BIDI_L }, // YI SYLLABLE VYT + { 0xA0FB, BIDI_L }, // YI SYLLABLE VYX + { 0xA0FC, BIDI_L }, // YI SYLLABLE VY + { 0xA0FD, BIDI_L }, // YI SYLLABLE VYP + { 0xA0FE, BIDI_L }, // YI SYLLABLE VYRX + { 0xA0FF, BIDI_L }, // YI SYLLABLE VYR + { 0xA100, BIDI_L }, // YI SYLLABLE DIT + { 0xA101, BIDI_L }, // YI SYLLABLE DIX + { 0xA102, BIDI_L }, // YI SYLLABLE DI + { 0xA103, BIDI_L }, // YI SYLLABLE DIP + { 0xA104, BIDI_L }, // YI SYLLABLE DIEX + { 0xA105, BIDI_L }, // YI SYLLABLE DIE + { 0xA106, BIDI_L }, // YI SYLLABLE DIEP + { 0xA107, BIDI_L }, // YI SYLLABLE DAT + { 0xA108, BIDI_L }, // YI SYLLABLE DAX + { 0xA109, BIDI_L }, // YI SYLLABLE DA + { 0xA10A, BIDI_L }, // YI SYLLABLE DAP + { 0xA10B, BIDI_L }, // YI SYLLABLE DUOX + { 0xA10C, BIDI_L }, // YI SYLLABLE DUO + { 0xA10D, BIDI_L }, // YI SYLLABLE DOT + { 0xA10E, BIDI_L }, // YI SYLLABLE DOX + { 0xA10F, BIDI_L }, // YI SYLLABLE DO + { 0xA110, BIDI_L }, // YI SYLLABLE DOP + { 0xA111, BIDI_L }, // YI SYLLABLE DEX + { 0xA112, BIDI_L }, // YI SYLLABLE DE + { 0xA113, BIDI_L }, // YI SYLLABLE DEP + { 0xA114, BIDI_L }, // YI SYLLABLE DUT + { 0xA115, BIDI_L }, // YI SYLLABLE DUX + { 0xA116, BIDI_L }, // YI SYLLABLE DU + { 0xA117, BIDI_L }, // YI SYLLABLE DUP + { 0xA118, BIDI_L }, // YI SYLLABLE DURX + { 0xA119, BIDI_L }, // YI SYLLABLE DUR + { 0xA11A, BIDI_L }, // YI SYLLABLE TIT + { 0xA11B, BIDI_L }, // YI SYLLABLE TIX + { 0xA11C, BIDI_L }, // YI SYLLABLE TI + { 0xA11D, BIDI_L }, // YI SYLLABLE TIP + { 0xA11E, BIDI_L }, // YI SYLLABLE TIEX + { 0xA11F, BIDI_L }, // YI SYLLABLE TIE + { 0xA120, BIDI_L }, // YI SYLLABLE TIEP + { 0xA121, BIDI_L }, // YI SYLLABLE TAT + { 0xA122, BIDI_L }, // YI SYLLABLE TAX + { 0xA123, BIDI_L }, // YI SYLLABLE TA + { 0xA124, BIDI_L }, // YI SYLLABLE TAP + { 0xA125, BIDI_L }, // YI SYLLABLE TUOT + { 0xA126, BIDI_L }, // YI SYLLABLE TUOX + { 0xA127, BIDI_L }, // YI SYLLABLE TUO + { 0xA128, BIDI_L }, // YI SYLLABLE TUOP + { 0xA129, BIDI_L }, // YI SYLLABLE TOT + { 0xA12A, BIDI_L }, // YI SYLLABLE TOX + { 0xA12B, BIDI_L }, // YI SYLLABLE TO + { 0xA12C, BIDI_L }, // YI SYLLABLE TOP + { 0xA12D, BIDI_L }, // YI SYLLABLE TEX + { 0xA12E, BIDI_L }, // YI SYLLABLE TE + { 0xA12F, BIDI_L }, // YI SYLLABLE TEP + { 0xA130, BIDI_L }, // YI SYLLABLE TUT + { 0xA131, BIDI_L }, // YI SYLLABLE TUX + { 0xA132, BIDI_L }, // YI SYLLABLE TU + { 0xA133, BIDI_L }, // YI SYLLABLE TUP + { 0xA134, BIDI_L }, // YI SYLLABLE TURX + { 0xA135, BIDI_L }, // YI SYLLABLE TUR + { 0xA136, BIDI_L }, // YI SYLLABLE DDIT + { 0xA137, BIDI_L }, // YI SYLLABLE DDIX + { 0xA138, BIDI_L }, // YI SYLLABLE DDI + { 0xA139, BIDI_L }, // YI SYLLABLE DDIP + { 0xA13A, BIDI_L }, // YI SYLLABLE DDIEX + { 0xA13B, BIDI_L }, // YI SYLLABLE DDIE + { 0xA13C, BIDI_L }, // YI SYLLABLE DDIEP + { 0xA13D, BIDI_L }, // YI SYLLABLE DDAT + { 0xA13E, BIDI_L }, // YI SYLLABLE DDAX + { 0xA13F, BIDI_L }, // YI SYLLABLE DDA + { 0xA140, BIDI_L }, // YI SYLLABLE DDAP + { 0xA141, BIDI_L }, // YI SYLLABLE DDUOX + { 0xA142, BIDI_L }, // YI SYLLABLE DDUO + { 0xA143, BIDI_L }, // YI SYLLABLE DDUOP + { 0xA144, BIDI_L }, // YI SYLLABLE DDOT + { 0xA145, BIDI_L }, // YI SYLLABLE DDOX + { 0xA146, BIDI_L }, // YI SYLLABLE DDO + { 0xA147, BIDI_L }, // YI SYLLABLE DDOP + { 0xA148, BIDI_L }, // YI SYLLABLE DDEX + { 0xA149, BIDI_L }, // YI SYLLABLE DDE + { 0xA14A, BIDI_L }, // YI SYLLABLE DDEP + { 0xA14B, BIDI_L }, // YI SYLLABLE DDUT + { 0xA14C, BIDI_L }, // YI SYLLABLE DDUX + { 0xA14D, BIDI_L }, // YI SYLLABLE DDU + { 0xA14E, BIDI_L }, // YI SYLLABLE DDUP + { 0xA14F, BIDI_L }, // YI SYLLABLE DDURX + { 0xA150, BIDI_L }, // YI SYLLABLE DDUR + { 0xA151, BIDI_L }, // YI SYLLABLE NDIT + { 0xA152, BIDI_L }, // YI SYLLABLE NDIX + { 0xA153, BIDI_L }, // YI SYLLABLE NDI + { 0xA154, BIDI_L }, // YI SYLLABLE NDIP + { 0xA155, BIDI_L }, // YI SYLLABLE NDIEX + { 0xA156, BIDI_L }, // YI SYLLABLE NDIE + { 0xA157, BIDI_L }, // YI SYLLABLE NDAT + { 0xA158, BIDI_L }, // YI SYLLABLE NDAX + { 0xA159, BIDI_L }, // YI SYLLABLE NDA + { 0xA15A, BIDI_L }, // YI SYLLABLE NDAP + { 0xA15B, BIDI_L }, // YI SYLLABLE NDOT + { 0xA15C, BIDI_L }, // YI SYLLABLE NDOX + { 0xA15D, BIDI_L }, // YI SYLLABLE NDO + { 0xA15E, BIDI_L }, // YI SYLLABLE NDOP + { 0xA15F, BIDI_L }, // YI SYLLABLE NDEX + { 0xA160, BIDI_L }, // YI SYLLABLE NDE + { 0xA161, BIDI_L }, // YI SYLLABLE NDEP + { 0xA162, BIDI_L }, // YI SYLLABLE NDUT + { 0xA163, BIDI_L }, // YI SYLLABLE NDUX + { 0xA164, BIDI_L }, // YI SYLLABLE NDU + { 0xA165, BIDI_L }, // YI SYLLABLE NDUP + { 0xA166, BIDI_L }, // YI SYLLABLE NDURX + { 0xA167, BIDI_L }, // YI SYLLABLE NDUR + { 0xA168, BIDI_L }, // YI SYLLABLE HNIT + { 0xA169, BIDI_L }, // YI SYLLABLE HNIX + { 0xA16A, BIDI_L }, // YI SYLLABLE HNI + { 0xA16B, BIDI_L }, // YI SYLLABLE HNIP + { 0xA16C, BIDI_L }, // YI SYLLABLE HNIET + { 0xA16D, BIDI_L }, // YI SYLLABLE HNIEX + { 0xA16E, BIDI_L }, // YI SYLLABLE HNIE + { 0xA16F, BIDI_L }, // YI SYLLABLE HNIEP + { 0xA170, BIDI_L }, // YI SYLLABLE HNAT + { 0xA171, BIDI_L }, // YI SYLLABLE HNAX + { 0xA172, BIDI_L }, // YI SYLLABLE HNA + { 0xA173, BIDI_L }, // YI SYLLABLE HNAP + { 0xA174, BIDI_L }, // YI SYLLABLE HNUOX + { 0xA175, BIDI_L }, // YI SYLLABLE HNUO + { 0xA176, BIDI_L }, // YI SYLLABLE HNOT + { 0xA177, BIDI_L }, // YI SYLLABLE HNOX + { 0xA178, BIDI_L }, // YI SYLLABLE HNOP + { 0xA179, BIDI_L }, // YI SYLLABLE HNEX + { 0xA17A, BIDI_L }, // YI SYLLABLE HNE + { 0xA17B, BIDI_L }, // YI SYLLABLE HNEP + { 0xA17C, BIDI_L }, // YI SYLLABLE HNUT + { 0xA17D, BIDI_L }, // YI SYLLABLE NIT + { 0xA17E, BIDI_L }, // YI SYLLABLE NIX + { 0xA17F, BIDI_L }, // YI SYLLABLE NI + { 0xA180, BIDI_L }, // YI SYLLABLE NIP + { 0xA181, BIDI_L }, // YI SYLLABLE NIEX + { 0xA182, BIDI_L }, // YI SYLLABLE NIE + { 0xA183, BIDI_L }, // YI SYLLABLE NIEP + { 0xA184, BIDI_L }, // YI SYLLABLE NAX + { 0xA185, BIDI_L }, // YI SYLLABLE NA + { 0xA186, BIDI_L }, // YI SYLLABLE NAP + { 0xA187, BIDI_L }, // YI SYLLABLE NUOX + { 0xA188, BIDI_L }, // YI SYLLABLE NUO + { 0xA189, BIDI_L }, // YI SYLLABLE NUOP + { 0xA18A, BIDI_L }, // YI SYLLABLE NOT + { 0xA18B, BIDI_L }, // YI SYLLABLE NOX + { 0xA18C, BIDI_L }, // YI SYLLABLE NO + { 0xA18D, BIDI_L }, // YI SYLLABLE NOP + { 0xA18E, BIDI_L }, // YI SYLLABLE NEX + { 0xA18F, BIDI_L }, // YI SYLLABLE NE + { 0xA190, BIDI_L }, // YI SYLLABLE NEP + { 0xA191, BIDI_L }, // YI SYLLABLE NUT + { 0xA192, BIDI_L }, // YI SYLLABLE NUX + { 0xA193, BIDI_L }, // YI SYLLABLE NU + { 0xA194, BIDI_L }, // YI SYLLABLE NUP + { 0xA195, BIDI_L }, // YI SYLLABLE NURX + { 0xA196, BIDI_L }, // YI SYLLABLE NUR + { 0xA197, BIDI_L }, // YI SYLLABLE HLIT + { 0xA198, BIDI_L }, // YI SYLLABLE HLIX + { 0xA199, BIDI_L }, // YI SYLLABLE HLI + { 0xA19A, BIDI_L }, // YI SYLLABLE HLIP + { 0xA19B, BIDI_L }, // YI SYLLABLE HLIEX + { 0xA19C, BIDI_L }, // YI SYLLABLE HLIE + { 0xA19D, BIDI_L }, // YI SYLLABLE HLIEP + { 0xA19E, BIDI_L }, // YI SYLLABLE HLAT + { 0xA19F, BIDI_L }, // YI SYLLABLE HLAX + { 0xA1A0, BIDI_L }, // YI SYLLABLE HLA + { 0xA1A1, BIDI_L }, // YI SYLLABLE HLAP + { 0xA1A2, BIDI_L }, // YI SYLLABLE HLUOX + { 0xA1A3, BIDI_L }, // YI SYLLABLE HLUO + { 0xA1A4, BIDI_L }, // YI SYLLABLE HLUOP + { 0xA1A5, BIDI_L }, // YI SYLLABLE HLOX + { 0xA1A6, BIDI_L }, // YI SYLLABLE HLO + { 0xA1A7, BIDI_L }, // YI SYLLABLE HLOP + { 0xA1A8, BIDI_L }, // YI SYLLABLE HLEX + { 0xA1A9, BIDI_L }, // YI SYLLABLE HLE + { 0xA1AA, BIDI_L }, // YI SYLLABLE HLEP + { 0xA1AB, BIDI_L }, // YI SYLLABLE HLUT + { 0xA1AC, BIDI_L }, // YI SYLLABLE HLUX + { 0xA1AD, BIDI_L }, // YI SYLLABLE HLU + { 0xA1AE, BIDI_L }, // YI SYLLABLE HLUP + { 0xA1AF, BIDI_L }, // YI SYLLABLE HLURX + { 0xA1B0, BIDI_L }, // YI SYLLABLE HLUR + { 0xA1B1, BIDI_L }, // YI SYLLABLE HLYT + { 0xA1B2, BIDI_L }, // YI SYLLABLE HLYX + { 0xA1B3, BIDI_L }, // YI SYLLABLE HLY + { 0xA1B4, BIDI_L }, // YI SYLLABLE HLYP + { 0xA1B5, BIDI_L }, // YI SYLLABLE HLYRX + { 0xA1B6, BIDI_L }, // YI SYLLABLE HLYR + { 0xA1B7, BIDI_L }, // YI SYLLABLE LIT + { 0xA1B8, BIDI_L }, // YI SYLLABLE LIX + { 0xA1B9, BIDI_L }, // YI SYLLABLE LI + { 0xA1BA, BIDI_L }, // YI SYLLABLE LIP + { 0xA1BB, BIDI_L }, // YI SYLLABLE LIET + { 0xA1BC, BIDI_L }, // YI SYLLABLE LIEX + { 0xA1BD, BIDI_L }, // YI SYLLABLE LIE + { 0xA1BE, BIDI_L }, // YI SYLLABLE LIEP + { 0xA1BF, BIDI_L }, // YI SYLLABLE LAT + { 0xA1C0, BIDI_L }, // YI SYLLABLE LAX + { 0xA1C1, BIDI_L }, // YI SYLLABLE LA + { 0xA1C2, BIDI_L }, // YI SYLLABLE LAP + { 0xA1C3, BIDI_L }, // YI SYLLABLE LUOT + { 0xA1C4, BIDI_L }, // YI SYLLABLE LUOX + { 0xA1C5, BIDI_L }, // YI SYLLABLE LUO + { 0xA1C6, BIDI_L }, // YI SYLLABLE LUOP + { 0xA1C7, BIDI_L }, // YI SYLLABLE LOT + { 0xA1C8, BIDI_L }, // YI SYLLABLE LOX + { 0xA1C9, BIDI_L }, // YI SYLLABLE LO + { 0xA1CA, BIDI_L }, // YI SYLLABLE LOP + { 0xA1CB, BIDI_L }, // YI SYLLABLE LEX + { 0xA1CC, BIDI_L }, // YI SYLLABLE LE + { 0xA1CD, BIDI_L }, // YI SYLLABLE LEP + { 0xA1CE, BIDI_L }, // YI SYLLABLE LUT + { 0xA1CF, BIDI_L }, // YI SYLLABLE LUX + { 0xA1D0, BIDI_L }, // YI SYLLABLE LU + { 0xA1D1, BIDI_L }, // YI SYLLABLE LUP + { 0xA1D2, BIDI_L }, // YI SYLLABLE LURX + { 0xA1D3, BIDI_L }, // YI SYLLABLE LUR + { 0xA1D4, BIDI_L }, // YI SYLLABLE LYT + { 0xA1D5, BIDI_L }, // YI SYLLABLE LYX + { 0xA1D6, BIDI_L }, // YI SYLLABLE LY + { 0xA1D7, BIDI_L }, // YI SYLLABLE LYP + { 0xA1D8, BIDI_L }, // YI SYLLABLE LYRX + { 0xA1D9, BIDI_L }, // YI SYLLABLE LYR + { 0xA1DA, BIDI_L }, // YI SYLLABLE GIT + { 0xA1DB, BIDI_L }, // YI SYLLABLE GIX + { 0xA1DC, BIDI_L }, // YI SYLLABLE GI + { 0xA1DD, BIDI_L }, // YI SYLLABLE GIP + { 0xA1DE, BIDI_L }, // YI SYLLABLE GIET + { 0xA1DF, BIDI_L }, // YI SYLLABLE GIEX + { 0xA1E0, BIDI_L }, // YI SYLLABLE GIE + { 0xA1E1, BIDI_L }, // YI SYLLABLE GIEP + { 0xA1E2, BIDI_L }, // YI SYLLABLE GAT + { 0xA1E3, BIDI_L }, // YI SYLLABLE GAX + { 0xA1E4, BIDI_L }, // YI SYLLABLE GA + { 0xA1E5, BIDI_L }, // YI SYLLABLE GAP + { 0xA1E6, BIDI_L }, // YI SYLLABLE GUOT + { 0xA1E7, BIDI_L }, // YI SYLLABLE GUOX + { 0xA1E8, BIDI_L }, // YI SYLLABLE GUO + { 0xA1E9, BIDI_L }, // YI SYLLABLE GUOP + { 0xA1EA, BIDI_L }, // YI SYLLABLE GOT + { 0xA1EB, BIDI_L }, // YI SYLLABLE GOX + { 0xA1EC, BIDI_L }, // YI SYLLABLE GO + { 0xA1ED, BIDI_L }, // YI SYLLABLE GOP + { 0xA1EE, BIDI_L }, // YI SYLLABLE GET + { 0xA1EF, BIDI_L }, // YI SYLLABLE GEX + { 0xA1F0, BIDI_L }, // YI SYLLABLE GE + { 0xA1F1, BIDI_L }, // YI SYLLABLE GEP + { 0xA1F2, BIDI_L }, // YI SYLLABLE GUT + { 0xA1F3, BIDI_L }, // YI SYLLABLE GUX + { 0xA1F4, BIDI_L }, // YI SYLLABLE GU + { 0xA1F5, BIDI_L }, // YI SYLLABLE GUP + { 0xA1F6, BIDI_L }, // YI SYLLABLE GURX + { 0xA1F7, BIDI_L }, // YI SYLLABLE GUR + { 0xA1F8, BIDI_L }, // YI SYLLABLE KIT + { 0xA1F9, BIDI_L }, // YI SYLLABLE KIX + { 0xA1FA, BIDI_L }, // YI SYLLABLE KI + { 0xA1FB, BIDI_L }, // YI SYLLABLE KIP + { 0xA1FC, BIDI_L }, // YI SYLLABLE KIEX + { 0xA1FD, BIDI_L }, // YI SYLLABLE KIE + { 0xA1FE, BIDI_L }, // YI SYLLABLE KIEP + { 0xA1FF, BIDI_L }, // YI SYLLABLE KAT + { 0xA200, BIDI_L }, // YI SYLLABLE KAX + { 0xA201, BIDI_L }, // YI SYLLABLE KA + { 0xA202, BIDI_L }, // YI SYLLABLE KAP + { 0xA203, BIDI_L }, // YI SYLLABLE KUOX + { 0xA204, BIDI_L }, // YI SYLLABLE KUO + { 0xA205, BIDI_L }, // YI SYLLABLE KUOP + { 0xA206, BIDI_L }, // YI SYLLABLE KOT + { 0xA207, BIDI_L }, // YI SYLLABLE KOX + { 0xA208, BIDI_L }, // YI SYLLABLE KO + { 0xA209, BIDI_L }, // YI SYLLABLE KOP + { 0xA20A, BIDI_L }, // YI SYLLABLE KET + { 0xA20B, BIDI_L }, // YI SYLLABLE KEX + { 0xA20C, BIDI_L }, // YI SYLLABLE KE + { 0xA20D, BIDI_L }, // YI SYLLABLE KEP + { 0xA20E, BIDI_L }, // YI SYLLABLE KUT + { 0xA20F, BIDI_L }, // YI SYLLABLE KUX + { 0xA210, BIDI_L }, // YI SYLLABLE KU + { 0xA211, BIDI_L }, // YI SYLLABLE KUP + { 0xA212, BIDI_L }, // YI SYLLABLE KURX + { 0xA213, BIDI_L }, // YI SYLLABLE KUR + { 0xA214, BIDI_L }, // YI SYLLABLE GGIT + { 0xA215, BIDI_L }, // YI SYLLABLE GGIX + { 0xA216, BIDI_L }, // YI SYLLABLE GGI + { 0xA217, BIDI_L }, // YI SYLLABLE GGIEX + { 0xA218, BIDI_L }, // YI SYLLABLE GGIE + { 0xA219, BIDI_L }, // YI SYLLABLE GGIEP + { 0xA21A, BIDI_L }, // YI SYLLABLE GGAT + { 0xA21B, BIDI_L }, // YI SYLLABLE GGAX + { 0xA21C, BIDI_L }, // YI SYLLABLE GGA + { 0xA21D, BIDI_L }, // YI SYLLABLE GGAP + { 0xA21E, BIDI_L }, // YI SYLLABLE GGUOT + { 0xA21F, BIDI_L }, // YI SYLLABLE GGUOX + { 0xA220, BIDI_L }, // YI SYLLABLE GGUO + { 0xA221, BIDI_L }, // YI SYLLABLE GGUOP + { 0xA222, BIDI_L }, // YI SYLLABLE GGOT + { 0xA223, BIDI_L }, // YI SYLLABLE GGOX + { 0xA224, BIDI_L }, // YI SYLLABLE GGO + { 0xA225, BIDI_L }, // YI SYLLABLE GGOP + { 0xA226, BIDI_L }, // YI SYLLABLE GGET + { 0xA227, BIDI_L }, // YI SYLLABLE GGEX + { 0xA228, BIDI_L }, // YI SYLLABLE GGE + { 0xA229, BIDI_L }, // YI SYLLABLE GGEP + { 0xA22A, BIDI_L }, // YI SYLLABLE GGUT + { 0xA22B, BIDI_L }, // YI SYLLABLE GGUX + { 0xA22C, BIDI_L }, // YI SYLLABLE GGU + { 0xA22D, BIDI_L }, // YI SYLLABLE GGUP + { 0xA22E, BIDI_L }, // YI SYLLABLE GGURX + { 0xA22F, BIDI_L }, // YI SYLLABLE GGUR + { 0xA230, BIDI_L }, // YI SYLLABLE MGIEX + { 0xA231, BIDI_L }, // YI SYLLABLE MGIE + { 0xA232, BIDI_L }, // YI SYLLABLE MGAT + { 0xA233, BIDI_L }, // YI SYLLABLE MGAX + { 0xA234, BIDI_L }, // YI SYLLABLE MGA + { 0xA235, BIDI_L }, // YI SYLLABLE MGAP + { 0xA236, BIDI_L }, // YI SYLLABLE MGUOX + { 0xA237, BIDI_L }, // YI SYLLABLE MGUO + { 0xA238, BIDI_L }, // YI SYLLABLE MGUOP + { 0xA239, BIDI_L }, // YI SYLLABLE MGOT + { 0xA23A, BIDI_L }, // YI SYLLABLE MGOX + { 0xA23B, BIDI_L }, // YI SYLLABLE MGO + { 0xA23C, BIDI_L }, // YI SYLLABLE MGOP + { 0xA23D, BIDI_L }, // YI SYLLABLE MGEX + { 0xA23E, BIDI_L }, // YI SYLLABLE MGE + { 0xA23F, BIDI_L }, // YI SYLLABLE MGEP + { 0xA240, BIDI_L }, // YI SYLLABLE MGUT + { 0xA241, BIDI_L }, // YI SYLLABLE MGUX + { 0xA242, BIDI_L }, // YI SYLLABLE MGU + { 0xA243, BIDI_L }, // YI SYLLABLE MGUP + { 0xA244, BIDI_L }, // YI SYLLABLE MGURX + { 0xA245, BIDI_L }, // YI SYLLABLE MGUR + { 0xA246, BIDI_L }, // YI SYLLABLE HXIT + { 0xA247, BIDI_L }, // YI SYLLABLE HXIX + { 0xA248, BIDI_L }, // YI SYLLABLE HXI + { 0xA249, BIDI_L }, // YI SYLLABLE HXIP + { 0xA24A, BIDI_L }, // YI SYLLABLE HXIET + { 0xA24B, BIDI_L }, // YI SYLLABLE HXIEX + { 0xA24C, BIDI_L }, // YI SYLLABLE HXIE + { 0xA24D, BIDI_L }, // YI SYLLABLE HXIEP + { 0xA24E, BIDI_L }, // YI SYLLABLE HXAT + { 0xA24F, BIDI_L }, // YI SYLLABLE HXAX + { 0xA250, BIDI_L }, // YI SYLLABLE HXA + { 0xA251, BIDI_L }, // YI SYLLABLE HXAP + { 0xA252, BIDI_L }, // YI SYLLABLE HXUOT + { 0xA253, BIDI_L }, // YI SYLLABLE HXUOX + { 0xA254, BIDI_L }, // YI SYLLABLE HXUO + { 0xA255, BIDI_L }, // YI SYLLABLE HXUOP + { 0xA256, BIDI_L }, // YI SYLLABLE HXOT + { 0xA257, BIDI_L }, // YI SYLLABLE HXOX + { 0xA258, BIDI_L }, // YI SYLLABLE HXO + { 0xA259, BIDI_L }, // YI SYLLABLE HXOP + { 0xA25A, BIDI_L }, // YI SYLLABLE HXEX + { 0xA25B, BIDI_L }, // YI SYLLABLE HXE + { 0xA25C, BIDI_L }, // YI SYLLABLE HXEP + { 0xA25D, BIDI_L }, // YI SYLLABLE NGIEX + { 0xA25E, BIDI_L }, // YI SYLLABLE NGIE + { 0xA25F, BIDI_L }, // YI SYLLABLE NGIEP + { 0xA260, BIDI_L }, // YI SYLLABLE NGAT + { 0xA261, BIDI_L }, // YI SYLLABLE NGAX + { 0xA262, BIDI_L }, // YI SYLLABLE NGA + { 0xA263, BIDI_L }, // YI SYLLABLE NGAP + { 0xA264, BIDI_L }, // YI SYLLABLE NGUOT + { 0xA265, BIDI_L }, // YI SYLLABLE NGUOX + { 0xA266, BIDI_L }, // YI SYLLABLE NGUO + { 0xA267, BIDI_L }, // YI SYLLABLE NGOT + { 0xA268, BIDI_L }, // YI SYLLABLE NGOX + { 0xA269, BIDI_L }, // YI SYLLABLE NGO + { 0xA26A, BIDI_L }, // YI SYLLABLE NGOP + { 0xA26B, BIDI_L }, // YI SYLLABLE NGEX + { 0xA26C, BIDI_L }, // YI SYLLABLE NGE + { 0xA26D, BIDI_L }, // YI SYLLABLE NGEP + { 0xA26E, BIDI_L }, // YI SYLLABLE HIT + { 0xA26F, BIDI_L }, // YI SYLLABLE HIEX + { 0xA270, BIDI_L }, // YI SYLLABLE HIE + { 0xA271, BIDI_L }, // YI SYLLABLE HAT + { 0xA272, BIDI_L }, // YI SYLLABLE HAX + { 0xA273, BIDI_L }, // YI SYLLABLE HA + { 0xA274, BIDI_L }, // YI SYLLABLE HAP + { 0xA275, BIDI_L }, // YI SYLLABLE HUOT + { 0xA276, BIDI_L }, // YI SYLLABLE HUOX + { 0xA277, BIDI_L }, // YI SYLLABLE HUO + { 0xA278, BIDI_L }, // YI SYLLABLE HUOP + { 0xA279, BIDI_L }, // YI SYLLABLE HOT + { 0xA27A, BIDI_L }, // YI SYLLABLE HOX + { 0xA27B, BIDI_L }, // YI SYLLABLE HO + { 0xA27C, BIDI_L }, // YI SYLLABLE HOP + { 0xA27D, BIDI_L }, // YI SYLLABLE HEX + { 0xA27E, BIDI_L }, // YI SYLLABLE HE + { 0xA27F, BIDI_L }, // YI SYLLABLE HEP + { 0xA280, BIDI_L }, // YI SYLLABLE WAT + { 0xA281, BIDI_L }, // YI SYLLABLE WAX + { 0xA282, BIDI_L }, // YI SYLLABLE WA + { 0xA283, BIDI_L }, // YI SYLLABLE WAP + { 0xA284, BIDI_L }, // YI SYLLABLE WUOX + { 0xA285, BIDI_L }, // YI SYLLABLE WUO + { 0xA286, BIDI_L }, // YI SYLLABLE WUOP + { 0xA287, BIDI_L }, // YI SYLLABLE WOX + { 0xA288, BIDI_L }, // YI SYLLABLE WO + { 0xA289, BIDI_L }, // YI SYLLABLE WOP + { 0xA28A, BIDI_L }, // YI SYLLABLE WEX + { 0xA28B, BIDI_L }, // YI SYLLABLE WE + { 0xA28C, BIDI_L }, // YI SYLLABLE WEP + { 0xA28D, BIDI_L }, // YI SYLLABLE ZIT + { 0xA28E, BIDI_L }, // YI SYLLABLE ZIX + { 0xA28F, BIDI_L }, // YI SYLLABLE ZI + { 0xA290, BIDI_L }, // YI SYLLABLE ZIP + { 0xA291, BIDI_L }, // YI SYLLABLE ZIEX + { 0xA292, BIDI_L }, // YI SYLLABLE ZIE + { 0xA293, BIDI_L }, // YI SYLLABLE ZIEP + { 0xA294, BIDI_L }, // YI SYLLABLE ZAT + { 0xA295, BIDI_L }, // YI SYLLABLE ZAX + { 0xA296, BIDI_L }, // YI SYLLABLE ZA + { 0xA297, BIDI_L }, // YI SYLLABLE ZAP + { 0xA298, BIDI_L }, // YI SYLLABLE ZUOX + { 0xA299, BIDI_L }, // YI SYLLABLE ZUO + { 0xA29A, BIDI_L }, // YI SYLLABLE ZUOP + { 0xA29B, BIDI_L }, // YI SYLLABLE ZOT + { 0xA29C, BIDI_L }, // YI SYLLABLE ZOX + { 0xA29D, BIDI_L }, // YI SYLLABLE ZO + { 0xA29E, BIDI_L }, // YI SYLLABLE ZOP + { 0xA29F, BIDI_L }, // YI SYLLABLE ZEX + { 0xA2A0, BIDI_L }, // YI SYLLABLE ZE + { 0xA2A1, BIDI_L }, // YI SYLLABLE ZEP + { 0xA2A2, BIDI_L }, // YI SYLLABLE ZUT + { 0xA2A3, BIDI_L }, // YI SYLLABLE ZUX + { 0xA2A4, BIDI_L }, // YI SYLLABLE ZU + { 0xA2A5, BIDI_L }, // YI SYLLABLE ZUP + { 0xA2A6, BIDI_L }, // YI SYLLABLE ZURX + { 0xA2A7, BIDI_L }, // YI SYLLABLE ZUR + { 0xA2A8, BIDI_L }, // YI SYLLABLE ZYT + { 0xA2A9, BIDI_L }, // YI SYLLABLE ZYX + { 0xA2AA, BIDI_L }, // YI SYLLABLE ZY + { 0xA2AB, BIDI_L }, // YI SYLLABLE ZYP + { 0xA2AC, BIDI_L }, // YI SYLLABLE ZYRX + { 0xA2AD, BIDI_L }, // YI SYLLABLE ZYR + { 0xA2AE, BIDI_L }, // YI SYLLABLE CIT + { 0xA2AF, BIDI_L }, // YI SYLLABLE CIX + { 0xA2B0, BIDI_L }, // YI SYLLABLE CI + { 0xA2B1, BIDI_L }, // YI SYLLABLE CIP + { 0xA2B2, BIDI_L }, // YI SYLLABLE CIET + { 0xA2B3, BIDI_L }, // YI SYLLABLE CIEX + { 0xA2B4, BIDI_L }, // YI SYLLABLE CIE + { 0xA2B5, BIDI_L }, // YI SYLLABLE CIEP + { 0xA2B6, BIDI_L }, // YI SYLLABLE CAT + { 0xA2B7, BIDI_L }, // YI SYLLABLE CAX + { 0xA2B8, BIDI_L }, // YI SYLLABLE CA + { 0xA2B9, BIDI_L }, // YI SYLLABLE CAP + { 0xA2BA, BIDI_L }, // YI SYLLABLE CUOX + { 0xA2BB, BIDI_L }, // YI SYLLABLE CUO + { 0xA2BC, BIDI_L }, // YI SYLLABLE CUOP + { 0xA2BD, BIDI_L }, // YI SYLLABLE COT + { 0xA2BE, BIDI_L }, // YI SYLLABLE COX + { 0xA2BF, BIDI_L }, // YI SYLLABLE CO + { 0xA2C0, BIDI_L }, // YI SYLLABLE COP + { 0xA2C1, BIDI_L }, // YI SYLLABLE CEX + { 0xA2C2, BIDI_L }, // YI SYLLABLE CE + { 0xA2C3, BIDI_L }, // YI SYLLABLE CEP + { 0xA2C4, BIDI_L }, // YI SYLLABLE CUT + { 0xA2C5, BIDI_L }, // YI SYLLABLE CUX + { 0xA2C6, BIDI_L }, // YI SYLLABLE CU + { 0xA2C7, BIDI_L }, // YI SYLLABLE CUP + { 0xA2C8, BIDI_L }, // YI SYLLABLE CURX + { 0xA2C9, BIDI_L }, // YI SYLLABLE CUR + { 0xA2CA, BIDI_L }, // YI SYLLABLE CYT + { 0xA2CB, BIDI_L }, // YI SYLLABLE CYX + { 0xA2CC, BIDI_L }, // YI SYLLABLE CY + { 0xA2CD, BIDI_L }, // YI SYLLABLE CYP + { 0xA2CE, BIDI_L }, // YI SYLLABLE CYRX + { 0xA2CF, BIDI_L }, // YI SYLLABLE CYR + { 0xA2D0, BIDI_L }, // YI SYLLABLE ZZIT + { 0xA2D1, BIDI_L }, // YI SYLLABLE ZZIX + { 0xA2D2, BIDI_L }, // YI SYLLABLE ZZI + { 0xA2D3, BIDI_L }, // YI SYLLABLE ZZIP + { 0xA2D4, BIDI_L }, // YI SYLLABLE ZZIET + { 0xA2D5, BIDI_L }, // YI SYLLABLE ZZIEX + { 0xA2D6, BIDI_L }, // YI SYLLABLE ZZIE + { 0xA2D7, BIDI_L }, // YI SYLLABLE ZZIEP + { 0xA2D8, BIDI_L }, // YI SYLLABLE ZZAT + { 0xA2D9, BIDI_L }, // YI SYLLABLE ZZAX + { 0xA2DA, BIDI_L }, // YI SYLLABLE ZZA + { 0xA2DB, BIDI_L }, // YI SYLLABLE ZZAP + { 0xA2DC, BIDI_L }, // YI SYLLABLE ZZOX + { 0xA2DD, BIDI_L }, // YI SYLLABLE ZZO + { 0xA2DE, BIDI_L }, // YI SYLLABLE ZZOP + { 0xA2DF, BIDI_L }, // YI SYLLABLE ZZEX + { 0xA2E0, BIDI_L }, // YI SYLLABLE ZZE + { 0xA2E1, BIDI_L }, // YI SYLLABLE ZZEP + { 0xA2E2, BIDI_L }, // YI SYLLABLE ZZUX + { 0xA2E3, BIDI_L }, // YI SYLLABLE ZZU + { 0xA2E4, BIDI_L }, // YI SYLLABLE ZZUP + { 0xA2E5, BIDI_L }, // YI SYLLABLE ZZURX + { 0xA2E6, BIDI_L }, // YI SYLLABLE ZZUR + { 0xA2E7, BIDI_L }, // YI SYLLABLE ZZYT + { 0xA2E8, BIDI_L }, // YI SYLLABLE ZZYX + { 0xA2E9, BIDI_L }, // YI SYLLABLE ZZY + { 0xA2EA, BIDI_L }, // YI SYLLABLE ZZYP + { 0xA2EB, BIDI_L }, // YI SYLLABLE ZZYRX + { 0xA2EC, BIDI_L }, // YI SYLLABLE ZZYR + { 0xA2ED, BIDI_L }, // YI SYLLABLE NZIT + { 0xA2EE, BIDI_L }, // YI SYLLABLE NZIX + { 0xA2EF, BIDI_L }, // YI SYLLABLE NZI + { 0xA2F0, BIDI_L }, // YI SYLLABLE NZIP + { 0xA2F1, BIDI_L }, // YI SYLLABLE NZIEX + { 0xA2F2, BIDI_L }, // YI SYLLABLE NZIE + { 0xA2F3, BIDI_L }, // YI SYLLABLE NZIEP + { 0xA2F4, BIDI_L }, // YI SYLLABLE NZAT + { 0xA2F5, BIDI_L }, // YI SYLLABLE NZAX + { 0xA2F6, BIDI_L }, // YI SYLLABLE NZA + { 0xA2F7, BIDI_L }, // YI SYLLABLE NZAP + { 0xA2F8, BIDI_L }, // YI SYLLABLE NZUOX + { 0xA2F9, BIDI_L }, // YI SYLLABLE NZUO + { 0xA2FA, BIDI_L }, // YI SYLLABLE NZOX + { 0xA2FB, BIDI_L }, // YI SYLLABLE NZOP + { 0xA2FC, BIDI_L }, // YI SYLLABLE NZEX + { 0xA2FD, BIDI_L }, // YI SYLLABLE NZE + { 0xA2FE, BIDI_L }, // YI SYLLABLE NZUX + { 0xA2FF, BIDI_L }, // YI SYLLABLE NZU + { 0xA300, BIDI_L }, // YI SYLLABLE NZUP + { 0xA301, BIDI_L }, // YI SYLLABLE NZURX + { 0xA302, BIDI_L }, // YI SYLLABLE NZUR + { 0xA303, BIDI_L }, // YI SYLLABLE NZYT + { 0xA304, BIDI_L }, // YI SYLLABLE NZYX + { 0xA305, BIDI_L }, // YI SYLLABLE NZY + { 0xA306, BIDI_L }, // YI SYLLABLE NZYP + { 0xA307, BIDI_L }, // YI SYLLABLE NZYRX + { 0xA308, BIDI_L }, // YI SYLLABLE NZYR + { 0xA309, BIDI_L }, // YI SYLLABLE SIT + { 0xA30A, BIDI_L }, // YI SYLLABLE SIX + { 0xA30B, BIDI_L }, // YI SYLLABLE SI + { 0xA30C, BIDI_L }, // YI SYLLABLE SIP + { 0xA30D, BIDI_L }, // YI SYLLABLE SIEX + { 0xA30E, BIDI_L }, // YI SYLLABLE SIE + { 0xA30F, BIDI_L }, // YI SYLLABLE SIEP + { 0xA310, BIDI_L }, // YI SYLLABLE SAT + { 0xA311, BIDI_L }, // YI SYLLABLE SAX + { 0xA312, BIDI_L }, // YI SYLLABLE SA + { 0xA313, BIDI_L }, // YI SYLLABLE SAP + { 0xA314, BIDI_L }, // YI SYLLABLE SUOX + { 0xA315, BIDI_L }, // YI SYLLABLE SUO + { 0xA316, BIDI_L }, // YI SYLLABLE SUOP + { 0xA317, BIDI_L }, // YI SYLLABLE SOT + { 0xA318, BIDI_L }, // YI SYLLABLE SOX + { 0xA319, BIDI_L }, // YI SYLLABLE SO + { 0xA31A, BIDI_L }, // YI SYLLABLE SOP + { 0xA31B, BIDI_L }, // YI SYLLABLE SEX + { 0xA31C, BIDI_L }, // YI SYLLABLE SE + { 0xA31D, BIDI_L }, // YI SYLLABLE SEP + { 0xA31E, BIDI_L }, // YI SYLLABLE SUT + { 0xA31F, BIDI_L }, // YI SYLLABLE SUX + { 0xA320, BIDI_L }, // YI SYLLABLE SU + { 0xA321, BIDI_L }, // YI SYLLABLE SUP + { 0xA322, BIDI_L }, // YI SYLLABLE SURX + { 0xA323, BIDI_L }, // YI SYLLABLE SUR + { 0xA324, BIDI_L }, // YI SYLLABLE SYT + { 0xA325, BIDI_L }, // YI SYLLABLE SYX + { 0xA326, BIDI_L }, // YI SYLLABLE SY + { 0xA327, BIDI_L }, // YI SYLLABLE SYP + { 0xA328, BIDI_L }, // YI SYLLABLE SYRX + { 0xA329, BIDI_L }, // YI SYLLABLE SYR + { 0xA32A, BIDI_L }, // YI SYLLABLE SSIT + { 0xA32B, BIDI_L }, // YI SYLLABLE SSIX + { 0xA32C, BIDI_L }, // YI SYLLABLE SSI + { 0xA32D, BIDI_L }, // YI SYLLABLE SSIP + { 0xA32E, BIDI_L }, // YI SYLLABLE SSIEX + { 0xA32F, BIDI_L }, // YI SYLLABLE SSIE + { 0xA330, BIDI_L }, // YI SYLLABLE SSIEP + { 0xA331, BIDI_L }, // YI SYLLABLE SSAT + { 0xA332, BIDI_L }, // YI SYLLABLE SSAX + { 0xA333, BIDI_L }, // YI SYLLABLE SSA + { 0xA334, BIDI_L }, // YI SYLLABLE SSAP + { 0xA335, BIDI_L }, // YI SYLLABLE SSOT + { 0xA336, BIDI_L }, // YI SYLLABLE SSOX + { 0xA337, BIDI_L }, // YI SYLLABLE SSO + { 0xA338, BIDI_L }, // YI SYLLABLE SSOP + { 0xA339, BIDI_L }, // YI SYLLABLE SSEX + { 0xA33A, BIDI_L }, // YI SYLLABLE SSE + { 0xA33B, BIDI_L }, // YI SYLLABLE SSEP + { 0xA33C, BIDI_L }, // YI SYLLABLE SSUT + { 0xA33D, BIDI_L }, // YI SYLLABLE SSUX + { 0xA33E, BIDI_L }, // YI SYLLABLE SSU + { 0xA33F, BIDI_L }, // YI SYLLABLE SSUP + { 0xA340, BIDI_L }, // YI SYLLABLE SSYT + { 0xA341, BIDI_L }, // YI SYLLABLE SSYX + { 0xA342, BIDI_L }, // YI SYLLABLE SSY + { 0xA343, BIDI_L }, // YI SYLLABLE SSYP + { 0xA344, BIDI_L }, // YI SYLLABLE SSYRX + { 0xA345, BIDI_L }, // YI SYLLABLE SSYR + { 0xA346, BIDI_L }, // YI SYLLABLE ZHAT + { 0xA347, BIDI_L }, // YI SYLLABLE ZHAX + { 0xA348, BIDI_L }, // YI SYLLABLE ZHA + { 0xA349, BIDI_L }, // YI SYLLABLE ZHAP + { 0xA34A, BIDI_L }, // YI SYLLABLE ZHUOX + { 0xA34B, BIDI_L }, // YI SYLLABLE ZHUO + { 0xA34C, BIDI_L }, // YI SYLLABLE ZHUOP + { 0xA34D, BIDI_L }, // YI SYLLABLE ZHOT + { 0xA34E, BIDI_L }, // YI SYLLABLE ZHOX + { 0xA34F, BIDI_L }, // YI SYLLABLE ZHO + { 0xA350, BIDI_L }, // YI SYLLABLE ZHOP + { 0xA351, BIDI_L }, // YI SYLLABLE ZHET + { 0xA352, BIDI_L }, // YI SYLLABLE ZHEX + { 0xA353, BIDI_L }, // YI SYLLABLE ZHE + { 0xA354, BIDI_L }, // YI SYLLABLE ZHEP + { 0xA355, BIDI_L }, // YI SYLLABLE ZHUT + { 0xA356, BIDI_L }, // YI SYLLABLE ZHUX + { 0xA357, BIDI_L }, // YI SYLLABLE ZHU + { 0xA358, BIDI_L }, // YI SYLLABLE ZHUP + { 0xA359, BIDI_L }, // YI SYLLABLE ZHURX + { 0xA35A, BIDI_L }, // YI SYLLABLE ZHUR + { 0xA35B, BIDI_L }, // YI SYLLABLE ZHYT + { 0xA35C, BIDI_L }, // YI SYLLABLE ZHYX + { 0xA35D, BIDI_L }, // YI SYLLABLE ZHY + { 0xA35E, BIDI_L }, // YI SYLLABLE ZHYP + { 0xA35F, BIDI_L }, // YI SYLLABLE ZHYRX + { 0xA360, BIDI_L }, // YI SYLLABLE ZHYR + { 0xA361, BIDI_L }, // YI SYLLABLE CHAT + { 0xA362, BIDI_L }, // YI SYLLABLE CHAX + { 0xA363, BIDI_L }, // YI SYLLABLE CHA + { 0xA364, BIDI_L }, // YI SYLLABLE CHAP + { 0xA365, BIDI_L }, // YI SYLLABLE CHUOT + { 0xA366, BIDI_L }, // YI SYLLABLE CHUOX + { 0xA367, BIDI_L }, // YI SYLLABLE CHUO + { 0xA368, BIDI_L }, // YI SYLLABLE CHUOP + { 0xA369, BIDI_L }, // YI SYLLABLE CHOT + { 0xA36A, BIDI_L }, // YI SYLLABLE CHOX + { 0xA36B, BIDI_L }, // YI SYLLABLE CHO + { 0xA36C, BIDI_L }, // YI SYLLABLE CHOP + { 0xA36D, BIDI_L }, // YI SYLLABLE CHET + { 0xA36E, BIDI_L }, // YI SYLLABLE CHEX + { 0xA36F, BIDI_L }, // YI SYLLABLE CHE + { 0xA370, BIDI_L }, // YI SYLLABLE CHEP + { 0xA371, BIDI_L }, // YI SYLLABLE CHUX + { 0xA372, BIDI_L }, // YI SYLLABLE CHU + { 0xA373, BIDI_L }, // YI SYLLABLE CHUP + { 0xA374, BIDI_L }, // YI SYLLABLE CHURX + { 0xA375, BIDI_L }, // YI SYLLABLE CHUR + { 0xA376, BIDI_L }, // YI SYLLABLE CHYT + { 0xA377, BIDI_L }, // YI SYLLABLE CHYX + { 0xA378, BIDI_L }, // YI SYLLABLE CHY + { 0xA379, BIDI_L }, // YI SYLLABLE CHYP + { 0xA37A, BIDI_L }, // YI SYLLABLE CHYRX + { 0xA37B, BIDI_L }, // YI SYLLABLE CHYR + { 0xA37C, BIDI_L }, // YI SYLLABLE RRAX + { 0xA37D, BIDI_L }, // YI SYLLABLE RRA + { 0xA37E, BIDI_L }, // YI SYLLABLE RRUOX + { 0xA37F, BIDI_L }, // YI SYLLABLE RRUO + { 0xA380, BIDI_L }, // YI SYLLABLE RROT + { 0xA381, BIDI_L }, // YI SYLLABLE RROX + { 0xA382, BIDI_L }, // YI SYLLABLE RRO + { 0xA383, BIDI_L }, // YI SYLLABLE RROP + { 0xA384, BIDI_L }, // YI SYLLABLE RRET + { 0xA385, BIDI_L }, // YI SYLLABLE RREX + { 0xA386, BIDI_L }, // YI SYLLABLE RRE + { 0xA387, BIDI_L }, // YI SYLLABLE RREP + { 0xA388, BIDI_L }, // YI SYLLABLE RRUT + { 0xA389, BIDI_L }, // YI SYLLABLE RRUX + { 0xA38A, BIDI_L }, // YI SYLLABLE RRU + { 0xA38B, BIDI_L }, // YI SYLLABLE RRUP + { 0xA38C, BIDI_L }, // YI SYLLABLE RRURX + { 0xA38D, BIDI_L }, // YI SYLLABLE RRUR + { 0xA38E, BIDI_L }, // YI SYLLABLE RRYT + { 0xA38F, BIDI_L }, // YI SYLLABLE RRYX + { 0xA390, BIDI_L }, // YI SYLLABLE RRY + { 0xA391, BIDI_L }, // YI SYLLABLE RRYP + { 0xA392, BIDI_L }, // YI SYLLABLE RRYRX + { 0xA393, BIDI_L }, // YI SYLLABLE RRYR + { 0xA394, BIDI_L }, // YI SYLLABLE NRAT + { 0xA395, BIDI_L }, // YI SYLLABLE NRAX + { 0xA396, BIDI_L }, // YI SYLLABLE NRA + { 0xA397, BIDI_L }, // YI SYLLABLE NRAP + { 0xA398, BIDI_L }, // YI SYLLABLE NROX + { 0xA399, BIDI_L }, // YI SYLLABLE NRO + { 0xA39A, BIDI_L }, // YI SYLLABLE NROP + { 0xA39B, BIDI_L }, // YI SYLLABLE NRET + { 0xA39C, BIDI_L }, // YI SYLLABLE NREX + { 0xA39D, BIDI_L }, // YI SYLLABLE NRE + { 0xA39E, BIDI_L }, // YI SYLLABLE NREP + { 0xA39F, BIDI_L }, // YI SYLLABLE NRUT + { 0xA3A0, BIDI_L }, // YI SYLLABLE NRUX + { 0xA3A1, BIDI_L }, // YI SYLLABLE NRU + { 0xA3A2, BIDI_L }, // YI SYLLABLE NRUP + { 0xA3A3, BIDI_L }, // YI SYLLABLE NRURX + { 0xA3A4, BIDI_L }, // YI SYLLABLE NRUR + { 0xA3A5, BIDI_L }, // YI SYLLABLE NRYT + { 0xA3A6, BIDI_L }, // YI SYLLABLE NRYX + { 0xA3A7, BIDI_L }, // YI SYLLABLE NRY + { 0xA3A8, BIDI_L }, // YI SYLLABLE NRYP + { 0xA3A9, BIDI_L }, // YI SYLLABLE NRYRX + { 0xA3AA, BIDI_L }, // YI SYLLABLE NRYR + { 0xA3AB, BIDI_L }, // YI SYLLABLE SHAT + { 0xA3AC, BIDI_L }, // YI SYLLABLE SHAX + { 0xA3AD, BIDI_L }, // YI SYLLABLE SHA + { 0xA3AE, BIDI_L }, // YI SYLLABLE SHAP + { 0xA3AF, BIDI_L }, // YI SYLLABLE SHUOX + { 0xA3B0, BIDI_L }, // YI SYLLABLE SHUO + { 0xA3B1, BIDI_L }, // YI SYLLABLE SHUOP + { 0xA3B2, BIDI_L }, // YI SYLLABLE SHOT + { 0xA3B3, BIDI_L }, // YI SYLLABLE SHOX + { 0xA3B4, BIDI_L }, // YI SYLLABLE SHO + { 0xA3B5, BIDI_L }, // YI SYLLABLE SHOP + { 0xA3B6, BIDI_L }, // YI SYLLABLE SHET + { 0xA3B7, BIDI_L }, // YI SYLLABLE SHEX + { 0xA3B8, BIDI_L }, // YI SYLLABLE SHE + { 0xA3B9, BIDI_L }, // YI SYLLABLE SHEP + { 0xA3BA, BIDI_L }, // YI SYLLABLE SHUT + { 0xA3BB, BIDI_L }, // YI SYLLABLE SHUX + { 0xA3BC, BIDI_L }, // YI SYLLABLE SHU + { 0xA3BD, BIDI_L }, // YI SYLLABLE SHUP + { 0xA3BE, BIDI_L }, // YI SYLLABLE SHURX + { 0xA3BF, BIDI_L }, // YI SYLLABLE SHUR + { 0xA3C0, BIDI_L }, // YI SYLLABLE SHYT + { 0xA3C1, BIDI_L }, // YI SYLLABLE SHYX + { 0xA3C2, BIDI_L }, // YI SYLLABLE SHY + { 0xA3C3, BIDI_L }, // YI SYLLABLE SHYP + { 0xA3C4, BIDI_L }, // YI SYLLABLE SHYRX + { 0xA3C5, BIDI_L }, // YI SYLLABLE SHYR + { 0xA3C6, BIDI_L }, // YI SYLLABLE RAT + { 0xA3C7, BIDI_L }, // YI SYLLABLE RAX + { 0xA3C8, BIDI_L }, // YI SYLLABLE RA + { 0xA3C9, BIDI_L }, // YI SYLLABLE RAP + { 0xA3CA, BIDI_L }, // YI SYLLABLE RUOX + { 0xA3CB, BIDI_L }, // YI SYLLABLE RUO + { 0xA3CC, BIDI_L }, // YI SYLLABLE RUOP + { 0xA3CD, BIDI_L }, // YI SYLLABLE ROT + { 0xA3CE, BIDI_L }, // YI SYLLABLE ROX + { 0xA3CF, BIDI_L }, // YI SYLLABLE RO + { 0xA3D0, BIDI_L }, // YI SYLLABLE ROP + { 0xA3D1, BIDI_L }, // YI SYLLABLE REX + { 0xA3D2, BIDI_L }, // YI SYLLABLE RE + { 0xA3D3, BIDI_L }, // YI SYLLABLE REP + { 0xA3D4, BIDI_L }, // YI SYLLABLE RUT + { 0xA3D5, BIDI_L }, // YI SYLLABLE RUX + { 0xA3D6, BIDI_L }, // YI SYLLABLE RU + { 0xA3D7, BIDI_L }, // YI SYLLABLE RUP + { 0xA3D8, BIDI_L }, // YI SYLLABLE RURX + { 0xA3D9, BIDI_L }, // YI SYLLABLE RUR + { 0xA3DA, BIDI_L }, // YI SYLLABLE RYT + { 0xA3DB, BIDI_L }, // YI SYLLABLE RYX + { 0xA3DC, BIDI_L }, // YI SYLLABLE RY + { 0xA3DD, BIDI_L }, // YI SYLLABLE RYP + { 0xA3DE, BIDI_L }, // YI SYLLABLE RYRX + { 0xA3DF, BIDI_L }, // YI SYLLABLE RYR + { 0xA3E0, BIDI_L }, // YI SYLLABLE JIT + { 0xA3E1, BIDI_L }, // YI SYLLABLE JIX + { 0xA3E2, BIDI_L }, // YI SYLLABLE JI + { 0xA3E3, BIDI_L }, // YI SYLLABLE JIP + { 0xA3E4, BIDI_L }, // YI SYLLABLE JIET + { 0xA3E5, BIDI_L }, // YI SYLLABLE JIEX + { 0xA3E6, BIDI_L }, // YI SYLLABLE JIE + { 0xA3E7, BIDI_L }, // YI SYLLABLE JIEP + { 0xA3E8, BIDI_L }, // YI SYLLABLE JUOT + { 0xA3E9, BIDI_L }, // YI SYLLABLE JUOX + { 0xA3EA, BIDI_L }, // YI SYLLABLE JUO + { 0xA3EB, BIDI_L }, // YI SYLLABLE JUOP + { 0xA3EC, BIDI_L }, // YI SYLLABLE JOT + { 0xA3ED, BIDI_L }, // YI SYLLABLE JOX + { 0xA3EE, BIDI_L }, // YI SYLLABLE JO + { 0xA3EF, BIDI_L }, // YI SYLLABLE JOP + { 0xA3F0, BIDI_L }, // YI SYLLABLE JUT + { 0xA3F1, BIDI_L }, // YI SYLLABLE JUX + { 0xA3F2, BIDI_L }, // YI SYLLABLE JU + { 0xA3F3, BIDI_L }, // YI SYLLABLE JUP + { 0xA3F4, BIDI_L }, // YI SYLLABLE JURX + { 0xA3F5, BIDI_L }, // YI SYLLABLE JUR + { 0xA3F6, BIDI_L }, // YI SYLLABLE JYT + { 0xA3F7, BIDI_L }, // YI SYLLABLE JYX + { 0xA3F8, BIDI_L }, // YI SYLLABLE JY + { 0xA3F9, BIDI_L }, // YI SYLLABLE JYP + { 0xA3FA, BIDI_L }, // YI SYLLABLE JYRX + { 0xA3FB, BIDI_L }, // YI SYLLABLE JYR + { 0xA3FC, BIDI_L }, // YI SYLLABLE QIT + { 0xA3FD, BIDI_L }, // YI SYLLABLE QIX + { 0xA3FE, BIDI_L }, // YI SYLLABLE QI + { 0xA3FF, BIDI_L }, // YI SYLLABLE QIP + { 0xA400, BIDI_L }, // YI SYLLABLE QIET + { 0xA401, BIDI_L }, // YI SYLLABLE QIEX + { 0xA402, BIDI_L }, // YI SYLLABLE QIE + { 0xA403, BIDI_L }, // YI SYLLABLE QIEP + { 0xA404, BIDI_L }, // YI SYLLABLE QUOT + { 0xA405, BIDI_L }, // YI SYLLABLE QUOX + { 0xA406, BIDI_L }, // YI SYLLABLE QUO + { 0xA407, BIDI_L }, // YI SYLLABLE QUOP + { 0xA408, BIDI_L }, // YI SYLLABLE QOT + { 0xA409, BIDI_L }, // YI SYLLABLE QOX + { 0xA40A, BIDI_L }, // YI SYLLABLE QO + { 0xA40B, BIDI_L }, // YI SYLLABLE QOP + { 0xA40C, BIDI_L }, // YI SYLLABLE QUT + { 0xA40D, BIDI_L }, // YI SYLLABLE QUX + { 0xA40E, BIDI_L }, // YI SYLLABLE QU + { 0xA40F, BIDI_L }, // YI SYLLABLE QUP + { 0xA410, BIDI_L }, // YI SYLLABLE QURX + { 0xA411, BIDI_L }, // YI SYLLABLE QUR + { 0xA412, BIDI_L }, // YI SYLLABLE QYT + { 0xA413, BIDI_L }, // YI SYLLABLE QYX + { 0xA414, BIDI_L }, // YI SYLLABLE QY + { 0xA415, BIDI_L }, // YI SYLLABLE QYP + { 0xA416, BIDI_L }, // YI SYLLABLE QYRX + { 0xA417, BIDI_L }, // YI SYLLABLE QYR + { 0xA418, BIDI_L }, // YI SYLLABLE JJIT + { 0xA419, BIDI_L }, // YI SYLLABLE JJIX + { 0xA41A, BIDI_L }, // YI SYLLABLE JJI + { 0xA41B, BIDI_L }, // YI SYLLABLE JJIP + { 0xA41C, BIDI_L }, // YI SYLLABLE JJIET + { 0xA41D, BIDI_L }, // YI SYLLABLE JJIEX + { 0xA41E, BIDI_L }, // YI SYLLABLE JJIE + { 0xA41F, BIDI_L }, // YI SYLLABLE JJIEP + { 0xA420, BIDI_L }, // YI SYLLABLE JJUOX + { 0xA421, BIDI_L }, // YI SYLLABLE JJUO + { 0xA422, BIDI_L }, // YI SYLLABLE JJUOP + { 0xA423, BIDI_L }, // YI SYLLABLE JJOT + { 0xA424, BIDI_L }, // YI SYLLABLE JJOX + { 0xA425, BIDI_L }, // YI SYLLABLE JJO + { 0xA426, BIDI_L }, // YI SYLLABLE JJOP + { 0xA427, BIDI_L }, // YI SYLLABLE JJUT + { 0xA428, BIDI_L }, // YI SYLLABLE JJUX + { 0xA429, BIDI_L }, // YI SYLLABLE JJU + { 0xA42A, BIDI_L }, // YI SYLLABLE JJUP + { 0xA42B, BIDI_L }, // YI SYLLABLE JJURX + { 0xA42C, BIDI_L }, // YI SYLLABLE JJUR + { 0xA42D, BIDI_L }, // YI SYLLABLE JJYT + { 0xA42E, BIDI_L }, // YI SYLLABLE JJYX + { 0xA42F, BIDI_L }, // YI SYLLABLE JJY + { 0xA430, BIDI_L }, // YI SYLLABLE JJYP + { 0xA431, BIDI_L }, // YI SYLLABLE NJIT + { 0xA432, BIDI_L }, // YI SYLLABLE NJIX + { 0xA433, BIDI_L }, // YI SYLLABLE NJI + { 0xA434, BIDI_L }, // YI SYLLABLE NJIP + { 0xA435, BIDI_L }, // YI SYLLABLE NJIET + { 0xA436, BIDI_L }, // YI SYLLABLE NJIEX + { 0xA437, BIDI_L }, // YI SYLLABLE NJIE + { 0xA438, BIDI_L }, // YI SYLLABLE NJIEP + { 0xA439, BIDI_L }, // YI SYLLABLE NJUOX + { 0xA43A, BIDI_L }, // YI SYLLABLE NJUO + { 0xA43B, BIDI_L }, // YI SYLLABLE NJOT + { 0xA43C, BIDI_L }, // YI SYLLABLE NJOX + { 0xA43D, BIDI_L }, // YI SYLLABLE NJO + { 0xA43E, BIDI_L }, // YI SYLLABLE NJOP + { 0xA43F, BIDI_L }, // YI SYLLABLE NJUX + { 0xA440, BIDI_L }, // YI SYLLABLE NJU + { 0xA441, BIDI_L }, // YI SYLLABLE NJUP + { 0xA442, BIDI_L }, // YI SYLLABLE NJURX + { 0xA443, BIDI_L }, // YI SYLLABLE NJUR + { 0xA444, BIDI_L }, // YI SYLLABLE NJYT + { 0xA445, BIDI_L }, // YI SYLLABLE NJYX + { 0xA446, BIDI_L }, // YI SYLLABLE NJY + { 0xA447, BIDI_L }, // YI SYLLABLE NJYP + { 0xA448, BIDI_L }, // YI SYLLABLE NJYRX + { 0xA449, BIDI_L }, // YI SYLLABLE NJYR + { 0xA44A, BIDI_L }, // YI SYLLABLE NYIT + { 0xA44B, BIDI_L }, // YI SYLLABLE NYIX + { 0xA44C, BIDI_L }, // YI SYLLABLE NYI + { 0xA44D, BIDI_L }, // YI SYLLABLE NYIP + { 0xA44E, BIDI_L }, // YI SYLLABLE NYIET + { 0xA44F, BIDI_L }, // YI SYLLABLE NYIEX + { 0xA450, BIDI_L }, // YI SYLLABLE NYIE + { 0xA451, BIDI_L }, // YI SYLLABLE NYIEP + { 0xA452, BIDI_L }, // YI SYLLABLE NYUOX + { 0xA453, BIDI_L }, // YI SYLLABLE NYUO + { 0xA454, BIDI_L }, // YI SYLLABLE NYUOP + { 0xA455, BIDI_L }, // YI SYLLABLE NYOT + { 0xA456, BIDI_L }, // YI SYLLABLE NYOX + { 0xA457, BIDI_L }, // YI SYLLABLE NYO + { 0xA458, BIDI_L }, // YI SYLLABLE NYOP + { 0xA459, BIDI_L }, // YI SYLLABLE NYUT + { 0xA45A, BIDI_L }, // YI SYLLABLE NYUX + { 0xA45B, BIDI_L }, // YI SYLLABLE NYU + { 0xA45C, BIDI_L }, // YI SYLLABLE NYUP + { 0xA45D, BIDI_L }, // YI SYLLABLE XIT + { 0xA45E, BIDI_L }, // YI SYLLABLE XIX + { 0xA45F, BIDI_L }, // YI SYLLABLE XI + { 0xA460, BIDI_L }, // YI SYLLABLE XIP + { 0xA461, BIDI_L }, // YI SYLLABLE XIET + { 0xA462, BIDI_L }, // YI SYLLABLE XIEX + { 0xA463, BIDI_L }, // YI SYLLABLE XIE + { 0xA464, BIDI_L }, // YI SYLLABLE XIEP + { 0xA465, BIDI_L }, // YI SYLLABLE XUOX + { 0xA466, BIDI_L }, // YI SYLLABLE XUO + { 0xA467, BIDI_L }, // YI SYLLABLE XOT + { 0xA468, BIDI_L }, // YI SYLLABLE XOX + { 0xA469, BIDI_L }, // YI SYLLABLE XO + { 0xA46A, BIDI_L }, // YI SYLLABLE XOP + { 0xA46B, BIDI_L }, // YI SYLLABLE XYT + { 0xA46C, BIDI_L }, // YI SYLLABLE XYX + { 0xA46D, BIDI_L }, // YI SYLLABLE XY + { 0xA46E, BIDI_L }, // YI SYLLABLE XYP + { 0xA46F, BIDI_L }, // YI SYLLABLE XYRX + { 0xA470, BIDI_L }, // YI SYLLABLE XYR + { 0xA471, BIDI_L }, // YI SYLLABLE YIT + { 0xA472, BIDI_L }, // YI SYLLABLE YIX + { 0xA473, BIDI_L }, // YI SYLLABLE YI + { 0xA474, BIDI_L }, // YI SYLLABLE YIP + { 0xA475, BIDI_L }, // YI SYLLABLE YIET + { 0xA476, BIDI_L }, // YI SYLLABLE YIEX + { 0xA477, BIDI_L }, // YI SYLLABLE YIE + { 0xA478, BIDI_L }, // YI SYLLABLE YIEP + { 0xA479, BIDI_L }, // YI SYLLABLE YUOT + { 0xA47A, BIDI_L }, // YI SYLLABLE YUOX + { 0xA47B, BIDI_L }, // YI SYLLABLE YUO + { 0xA47C, BIDI_L }, // YI SYLLABLE YUOP + { 0xA47D, BIDI_L }, // YI SYLLABLE YOT + { 0xA47E, BIDI_L }, // YI SYLLABLE YOX + { 0xA47F, BIDI_L }, // YI SYLLABLE YO + { 0xA480, BIDI_L }, // YI SYLLABLE YOP + { 0xA481, BIDI_L }, // YI SYLLABLE YUT + { 0xA482, BIDI_L }, // YI SYLLABLE YUX + { 0xA483, BIDI_L }, // YI SYLLABLE YU + { 0xA484, BIDI_L }, // YI SYLLABLE YUP + { 0xA485, BIDI_L }, // YI SYLLABLE YURX + { 0xA486, BIDI_L }, // YI SYLLABLE YUR + { 0xA487, BIDI_L }, // YI SYLLABLE YYT + { 0xA488, BIDI_L }, // YI SYLLABLE YYX + { 0xA489, BIDI_L }, // YI SYLLABLE YY + { 0xA48A, BIDI_L }, // YI SYLLABLE YYP + { 0xA48B, BIDI_L }, // YI SYLLABLE YYRX + { 0xA48C, BIDI_L }, // YI SYLLABLE YYR + { 0xA490, BIDI_ON }, // YI RADICAL QOT + { 0xA491, BIDI_ON }, // YI RADICAL LI + { 0xA492, BIDI_ON }, // YI RADICAL KIT + { 0xA493, BIDI_ON }, // YI RADICAL NYIP + { 0xA494, BIDI_ON }, // YI RADICAL CYP + { 0xA495, BIDI_ON }, // YI RADICAL SSI + { 0xA496, BIDI_ON }, // YI RADICAL GGOP + { 0xA497, BIDI_ON }, // YI RADICAL GEP + { 0xA498, BIDI_ON }, // YI RADICAL MI + { 0xA499, BIDI_ON }, // YI RADICAL HXIT + { 0xA49A, BIDI_ON }, // YI RADICAL LYR + { 0xA49B, BIDI_ON }, // YI RADICAL BBUT + { 0xA49C, BIDI_ON }, // YI RADICAL MOP + { 0xA49D, BIDI_ON }, // YI RADICAL YO + { 0xA49E, BIDI_ON }, // YI RADICAL PUT + { 0xA49F, BIDI_ON }, // YI RADICAL HXUO + { 0xA4A0, BIDI_ON }, // YI RADICAL TAT + { 0xA4A1, BIDI_ON }, // YI RADICAL GA + { 0xA4A2, BIDI_ON }, // YI RADICAL ZUP + { 0xA4A3, BIDI_ON }, // YI RADICAL CYT + { 0xA4A4, BIDI_ON }, // YI RADICAL DDUR + { 0xA4A5, BIDI_ON }, // YI RADICAL BUR + { 0xA4A6, BIDI_ON }, // YI RADICAL GGUO + { 0xA4A7, BIDI_ON }, // YI RADICAL NYOP + { 0xA4A8, BIDI_ON }, // YI RADICAL TU + { 0xA4A9, BIDI_ON }, // YI RADICAL OP + { 0xA4AA, BIDI_ON }, // YI RADICAL JJUT + { 0xA4AB, BIDI_ON }, // YI RADICAL ZOT + { 0xA4AC, BIDI_ON }, // YI RADICAL PYT + { 0xA4AD, BIDI_ON }, // YI RADICAL HMO + { 0xA4AE, BIDI_ON }, // YI RADICAL YIT + { 0xA4AF, BIDI_ON }, // YI RADICAL VUR + { 0xA4B0, BIDI_ON }, // YI RADICAL SHY + { 0xA4B1, BIDI_ON }, // YI RADICAL VEP + { 0xA4B2, BIDI_ON }, // YI RADICAL ZA + { 0xA4B3, BIDI_ON }, // YI RADICAL JO + { 0xA4B4, BIDI_ON }, // YI RADICAL NZUP + { 0xA4B5, BIDI_ON }, // YI RADICAL JJY + { 0xA4B6, BIDI_ON }, // YI RADICAL GOT + { 0xA4B7, BIDI_ON }, // YI RADICAL JJIE + { 0xA4B8, BIDI_ON }, // YI RADICAL WO + { 0xA4B9, BIDI_ON }, // YI RADICAL DU + { 0xA4BA, BIDI_ON }, // YI RADICAL SHUR + { 0xA4BB, BIDI_ON }, // YI RADICAL LIE + { 0xA4BC, BIDI_ON }, // YI RADICAL CY + { 0xA4BD, BIDI_ON }, // YI RADICAL CUOP + { 0xA4BE, BIDI_ON }, // YI RADICAL CIP + { 0xA4BF, BIDI_ON }, // YI RADICAL HXOP + { 0xA4C0, BIDI_ON }, // YI RADICAL SHAT + { 0xA4C1, BIDI_ON }, // YI RADICAL ZUR + { 0xA4C2, BIDI_ON }, // YI RADICAL SHOP + { 0xA4C3, BIDI_ON }, // YI RADICAL CHE + { 0xA4C4, BIDI_ON }, // YI RADICAL ZZIET + { 0xA4C5, BIDI_ON }, // YI RADICAL NBIE + { 0xA4C6, BIDI_ON }, // YI RADICAL KE + { 0xA4D0, BIDI_L }, // LISU LETTER BA + { 0xA4D1, BIDI_L }, // LISU LETTER PA + { 0xA4D2, BIDI_L }, // LISU LETTER PHA + { 0xA4D3, BIDI_L }, // LISU LETTER DA + { 0xA4D4, BIDI_L }, // LISU LETTER TA + { 0xA4D5, BIDI_L }, // LISU LETTER THA + { 0xA4D6, BIDI_L }, // LISU LETTER GA + { 0xA4D7, BIDI_L }, // LISU LETTER KA + { 0xA4D8, BIDI_L }, // LISU LETTER KHA + { 0xA4D9, BIDI_L }, // LISU LETTER JA + { 0xA4DA, BIDI_L }, // LISU LETTER CA + { 0xA4DB, BIDI_L }, // LISU LETTER CHA + { 0xA4DC, BIDI_L }, // LISU LETTER DZA + { 0xA4DD, BIDI_L }, // LISU LETTER TSA + { 0xA4DE, BIDI_L }, // LISU LETTER TSHA + { 0xA4DF, BIDI_L }, // LISU LETTER MA + { 0xA4E0, BIDI_L }, // LISU LETTER NA + { 0xA4E1, BIDI_L }, // LISU LETTER LA + { 0xA4E2, BIDI_L }, // LISU LETTER SA + { 0xA4E3, BIDI_L }, // LISU LETTER ZHA + { 0xA4E4, BIDI_L }, // LISU LETTER ZA + { 0xA4E5, BIDI_L }, // LISU LETTER NGA + { 0xA4E6, BIDI_L }, // LISU LETTER HA + { 0xA4E7, BIDI_L }, // LISU LETTER XA + { 0xA4E8, BIDI_L }, // LISU LETTER HHA + { 0xA4E9, BIDI_L }, // LISU LETTER FA + { 0xA4EA, BIDI_L }, // LISU LETTER WA + { 0xA4EB, BIDI_L }, // LISU LETTER SHA + { 0xA4EC, BIDI_L }, // LISU LETTER YA + { 0xA4ED, BIDI_L }, // LISU LETTER GHA + { 0xA4EE, BIDI_L }, // LISU LETTER A + { 0xA4EF, BIDI_L }, // LISU LETTER AE + { 0xA4F0, BIDI_L }, // LISU LETTER E + { 0xA4F1, BIDI_L }, // LISU LETTER EU + { 0xA4F2, BIDI_L }, // LISU LETTER I + { 0xA4F3, BIDI_L }, // LISU LETTER O + { 0xA4F4, BIDI_L }, // LISU LETTER U + { 0xA4F5, BIDI_L }, // LISU LETTER UE + { 0xA4F6, BIDI_L }, // LISU LETTER UH + { 0xA4F7, BIDI_L }, // LISU LETTER OE + { 0xA4F8, BIDI_L }, // LISU LETTER TONE MYA TI + { 0xA4F9, BIDI_L }, // LISU LETTER TONE NA PO + { 0xA4FA, BIDI_L }, // LISU LETTER TONE MYA CYA + { 0xA4FB, BIDI_L }, // LISU LETTER TONE MYA BO + { 0xA4FC, BIDI_L }, // LISU LETTER TONE MYA NA + { 0xA4FD, BIDI_L }, // LISU LETTER TONE MYA JEU + { 0xA4FE, BIDI_L }, // LISU PUNCTUATION COMMA + { 0xA4FF, BIDI_L }, // LISU PUNCTUATION FULL STOP + { 0xA500, BIDI_L }, // VAI SYLLABLE EE + { 0xA501, BIDI_L }, // VAI SYLLABLE EEN + { 0xA502, BIDI_L }, // VAI SYLLABLE HEE + { 0xA503, BIDI_L }, // VAI SYLLABLE WEE + { 0xA504, BIDI_L }, // VAI SYLLABLE WEEN + { 0xA505, BIDI_L }, // VAI SYLLABLE PEE + { 0xA506, BIDI_L }, // VAI SYLLABLE BHEE + { 0xA507, BIDI_L }, // VAI SYLLABLE BEE + { 0xA508, BIDI_L }, // VAI SYLLABLE MBEE + { 0xA509, BIDI_L }, // VAI SYLLABLE KPEE + { 0xA50A, BIDI_L }, // VAI SYLLABLE MGBEE + { 0xA50B, BIDI_L }, // VAI SYLLABLE GBEE + { 0xA50C, BIDI_L }, // VAI SYLLABLE FEE + { 0xA50D, BIDI_L }, // VAI SYLLABLE VEE + { 0xA50E, BIDI_L }, // VAI SYLLABLE TEE + { 0xA50F, BIDI_L }, // VAI SYLLABLE THEE + { 0xA510, BIDI_L }, // VAI SYLLABLE DHEE + { 0xA511, BIDI_L }, // VAI SYLLABLE DHHEE + { 0xA512, BIDI_L }, // VAI SYLLABLE LEE + { 0xA513, BIDI_L }, // VAI SYLLABLE REE + { 0xA514, BIDI_L }, // VAI SYLLABLE DEE + { 0xA515, BIDI_L }, // VAI SYLLABLE NDEE + { 0xA516, BIDI_L }, // VAI SYLLABLE SEE + { 0xA517, BIDI_L }, // VAI SYLLABLE SHEE + { 0xA518, BIDI_L }, // VAI SYLLABLE ZEE + { 0xA519, BIDI_L }, // VAI SYLLABLE ZHEE + { 0xA51A, BIDI_L }, // VAI SYLLABLE CEE + { 0xA51B, BIDI_L }, // VAI SYLLABLE JEE + { 0xA51C, BIDI_L }, // VAI SYLLABLE NJEE + { 0xA51D, BIDI_L }, // VAI SYLLABLE YEE + { 0xA51E, BIDI_L }, // VAI SYLLABLE KEE + { 0xA51F, BIDI_L }, // VAI SYLLABLE NGGEE + { 0xA520, BIDI_L }, // VAI SYLLABLE GEE + { 0xA521, BIDI_L }, // VAI SYLLABLE MEE + { 0xA522, BIDI_L }, // VAI SYLLABLE NEE + { 0xA523, BIDI_L }, // VAI SYLLABLE NYEE + { 0xA524, BIDI_L }, // VAI SYLLABLE I + { 0xA525, BIDI_L }, // VAI SYLLABLE IN + { 0xA526, BIDI_L }, // VAI SYLLABLE HI + { 0xA527, BIDI_L }, // VAI SYLLABLE HIN + { 0xA528, BIDI_L }, // VAI SYLLABLE WI + { 0xA529, BIDI_L }, // VAI SYLLABLE WIN + { 0xA52A, BIDI_L }, // VAI SYLLABLE PI + { 0xA52B, BIDI_L }, // VAI SYLLABLE BHI + { 0xA52C, BIDI_L }, // VAI SYLLABLE BI + { 0xA52D, BIDI_L }, // VAI SYLLABLE MBI + { 0xA52E, BIDI_L }, // VAI SYLLABLE KPI + { 0xA52F, BIDI_L }, // VAI SYLLABLE MGBI + { 0xA530, BIDI_L }, // VAI SYLLABLE GBI + { 0xA531, BIDI_L }, // VAI SYLLABLE FI + { 0xA532, BIDI_L }, // VAI SYLLABLE VI + { 0xA533, BIDI_L }, // VAI SYLLABLE TI + { 0xA534, BIDI_L }, // VAI SYLLABLE THI + { 0xA535, BIDI_L }, // VAI SYLLABLE DHI + { 0xA536, BIDI_L }, // VAI SYLLABLE DHHI + { 0xA537, BIDI_L }, // VAI SYLLABLE LI + { 0xA538, BIDI_L }, // VAI SYLLABLE RI + { 0xA539, BIDI_L }, // VAI SYLLABLE DI + { 0xA53A, BIDI_L }, // VAI SYLLABLE NDI + { 0xA53B, BIDI_L }, // VAI SYLLABLE SI + { 0xA53C, BIDI_L }, // VAI SYLLABLE SHI + { 0xA53D, BIDI_L }, // VAI SYLLABLE ZI + { 0xA53E, BIDI_L }, // VAI SYLLABLE ZHI + { 0xA53F, BIDI_L }, // VAI SYLLABLE CI + { 0xA540, BIDI_L }, // VAI SYLLABLE JI + { 0xA541, BIDI_L }, // VAI SYLLABLE NJI + { 0xA542, BIDI_L }, // VAI SYLLABLE YI + { 0xA543, BIDI_L }, // VAI SYLLABLE KI + { 0xA544, BIDI_L }, // VAI SYLLABLE NGGI + { 0xA545, BIDI_L }, // VAI SYLLABLE GI + { 0xA546, BIDI_L }, // VAI SYLLABLE MI + { 0xA547, BIDI_L }, // VAI SYLLABLE NI + { 0xA548, BIDI_L }, // VAI SYLLABLE NYI + { 0xA549, BIDI_L }, // VAI SYLLABLE A + { 0xA54A, BIDI_L }, // VAI SYLLABLE AN + { 0xA54B, BIDI_L }, // VAI SYLLABLE NGAN + { 0xA54C, BIDI_L }, // VAI SYLLABLE HA + { 0xA54D, BIDI_L }, // VAI SYLLABLE HAN + { 0xA54E, BIDI_L }, // VAI SYLLABLE WA + { 0xA54F, BIDI_L }, // VAI SYLLABLE WAN + { 0xA550, BIDI_L }, // VAI SYLLABLE PA + { 0xA551, BIDI_L }, // VAI SYLLABLE BHA + { 0xA552, BIDI_L }, // VAI SYLLABLE BA + { 0xA553, BIDI_L }, // VAI SYLLABLE MBA + { 0xA554, BIDI_L }, // VAI SYLLABLE KPA + { 0xA555, BIDI_L }, // VAI SYLLABLE KPAN + { 0xA556, BIDI_L }, // VAI SYLLABLE MGBA + { 0xA557, BIDI_L }, // VAI SYLLABLE GBA + { 0xA558, BIDI_L }, // VAI SYLLABLE FA + { 0xA559, BIDI_L }, // VAI SYLLABLE VA + { 0xA55A, BIDI_L }, // VAI SYLLABLE TA + { 0xA55B, BIDI_L }, // VAI SYLLABLE THA + { 0xA55C, BIDI_L }, // VAI SYLLABLE DHA + { 0xA55D, BIDI_L }, // VAI SYLLABLE DHHA + { 0xA55E, BIDI_L }, // VAI SYLLABLE LA + { 0xA55F, BIDI_L }, // VAI SYLLABLE RA + { 0xA560, BIDI_L }, // VAI SYLLABLE DA + { 0xA561, BIDI_L }, // VAI SYLLABLE NDA + { 0xA562, BIDI_L }, // VAI SYLLABLE SA + { 0xA563, BIDI_L }, // VAI SYLLABLE SHA + { 0xA564, BIDI_L }, // VAI SYLLABLE ZA + { 0xA565, BIDI_L }, // VAI SYLLABLE ZHA + { 0xA566, BIDI_L }, // VAI SYLLABLE CA + { 0xA567, BIDI_L }, // VAI SYLLABLE JA + { 0xA568, BIDI_L }, // VAI SYLLABLE NJA + { 0xA569, BIDI_L }, // VAI SYLLABLE YA + { 0xA56A, BIDI_L }, // VAI SYLLABLE KA + { 0xA56B, BIDI_L }, // VAI SYLLABLE KAN + { 0xA56C, BIDI_L }, // VAI SYLLABLE NGGA + { 0xA56D, BIDI_L }, // VAI SYLLABLE GA + { 0xA56E, BIDI_L }, // VAI SYLLABLE MA + { 0xA56F, BIDI_L }, // VAI SYLLABLE NA + { 0xA570, BIDI_L }, // VAI SYLLABLE NYA + { 0xA571, BIDI_L }, // VAI SYLLABLE OO + { 0xA572, BIDI_L }, // VAI SYLLABLE OON + { 0xA573, BIDI_L }, // VAI SYLLABLE HOO + { 0xA574, BIDI_L }, // VAI SYLLABLE WOO + { 0xA575, BIDI_L }, // VAI SYLLABLE WOON + { 0xA576, BIDI_L }, // VAI SYLLABLE POO + { 0xA577, BIDI_L }, // VAI SYLLABLE BHOO + { 0xA578, BIDI_L }, // VAI SYLLABLE BOO + { 0xA579, BIDI_L }, // VAI SYLLABLE MBOO + { 0xA57A, BIDI_L }, // VAI SYLLABLE KPOO + { 0xA57B, BIDI_L }, // VAI SYLLABLE MGBOO + { 0xA57C, BIDI_L }, // VAI SYLLABLE GBOO + { 0xA57D, BIDI_L }, // VAI SYLLABLE FOO + { 0xA57E, BIDI_L }, // VAI SYLLABLE VOO + { 0xA57F, BIDI_L }, // VAI SYLLABLE TOO + { 0xA580, BIDI_L }, // VAI SYLLABLE THOO + { 0xA581, BIDI_L }, // VAI SYLLABLE DHOO + { 0xA582, BIDI_L }, // VAI SYLLABLE DHHOO + { 0xA583, BIDI_L }, // VAI SYLLABLE LOO + { 0xA584, BIDI_L }, // VAI SYLLABLE ROO + { 0xA585, BIDI_L }, // VAI SYLLABLE DOO + { 0xA586, BIDI_L }, // VAI SYLLABLE NDOO + { 0xA587, BIDI_L }, // VAI SYLLABLE SOO + { 0xA588, BIDI_L }, // VAI SYLLABLE SHOO + { 0xA589, BIDI_L }, // VAI SYLLABLE ZOO + { 0xA58A, BIDI_L }, // VAI SYLLABLE ZHOO + { 0xA58B, BIDI_L }, // VAI SYLLABLE COO + { 0xA58C, BIDI_L }, // VAI SYLLABLE JOO + { 0xA58D, BIDI_L }, // VAI SYLLABLE NJOO + { 0xA58E, BIDI_L }, // VAI SYLLABLE YOO + { 0xA58F, BIDI_L }, // VAI SYLLABLE KOO + { 0xA590, BIDI_L }, // VAI SYLLABLE NGGOO + { 0xA591, BIDI_L }, // VAI SYLLABLE GOO + { 0xA592, BIDI_L }, // VAI SYLLABLE MOO + { 0xA593, BIDI_L }, // VAI SYLLABLE NOO + { 0xA594, BIDI_L }, // VAI SYLLABLE NYOO + { 0xA595, BIDI_L }, // VAI SYLLABLE U + { 0xA596, BIDI_L }, // VAI SYLLABLE UN + { 0xA597, BIDI_L }, // VAI SYLLABLE HU + { 0xA598, BIDI_L }, // VAI SYLLABLE HUN + { 0xA599, BIDI_L }, // VAI SYLLABLE WU + { 0xA59A, BIDI_L }, // VAI SYLLABLE WUN + { 0xA59B, BIDI_L }, // VAI SYLLABLE PU + { 0xA59C, BIDI_L }, // VAI SYLLABLE BHU + { 0xA59D, BIDI_L }, // VAI SYLLABLE BU + { 0xA59E, BIDI_L }, // VAI SYLLABLE MBU + { 0xA59F, BIDI_L }, // VAI SYLLABLE KPU + { 0xA5A0, BIDI_L }, // VAI SYLLABLE MGBU + { 0xA5A1, BIDI_L }, // VAI SYLLABLE GBU + { 0xA5A2, BIDI_L }, // VAI SYLLABLE FU + { 0xA5A3, BIDI_L }, // VAI SYLLABLE VU + { 0xA5A4, BIDI_L }, // VAI SYLLABLE TU + { 0xA5A5, BIDI_L }, // VAI SYLLABLE THU + { 0xA5A6, BIDI_L }, // VAI SYLLABLE DHU + { 0xA5A7, BIDI_L }, // VAI SYLLABLE DHHU + { 0xA5A8, BIDI_L }, // VAI SYLLABLE LU + { 0xA5A9, BIDI_L }, // VAI SYLLABLE RU + { 0xA5AA, BIDI_L }, // VAI SYLLABLE DU + { 0xA5AB, BIDI_L }, // VAI SYLLABLE NDU + { 0xA5AC, BIDI_L }, // VAI SYLLABLE SU + { 0xA5AD, BIDI_L }, // VAI SYLLABLE SHU + { 0xA5AE, BIDI_L }, // VAI SYLLABLE ZU + { 0xA5AF, BIDI_L }, // VAI SYLLABLE ZHU + { 0xA5B0, BIDI_L }, // VAI SYLLABLE CU + { 0xA5B1, BIDI_L }, // VAI SYLLABLE JU + { 0xA5B2, BIDI_L }, // VAI SYLLABLE NJU + { 0xA5B3, BIDI_L }, // VAI SYLLABLE YU + { 0xA5B4, BIDI_L }, // VAI SYLLABLE KU + { 0xA5B5, BIDI_L }, // VAI SYLLABLE NGGU + { 0xA5B6, BIDI_L }, // VAI SYLLABLE GU + { 0xA5B7, BIDI_L }, // VAI SYLLABLE MU + { 0xA5B8, BIDI_L }, // VAI SYLLABLE NU + { 0xA5B9, BIDI_L }, // VAI SYLLABLE NYU + { 0xA5BA, BIDI_L }, // VAI SYLLABLE O + { 0xA5BB, BIDI_L }, // VAI SYLLABLE ON + { 0xA5BC, BIDI_L }, // VAI SYLLABLE NGON + { 0xA5BD, BIDI_L }, // VAI SYLLABLE HO + { 0xA5BE, BIDI_L }, // VAI SYLLABLE HON + { 0xA5BF, BIDI_L }, // VAI SYLLABLE WO + { 0xA5C0, BIDI_L }, // VAI SYLLABLE WON + { 0xA5C1, BIDI_L }, // VAI SYLLABLE PO + { 0xA5C2, BIDI_L }, // VAI SYLLABLE BHO + { 0xA5C3, BIDI_L }, // VAI SYLLABLE BO + { 0xA5C4, BIDI_L }, // VAI SYLLABLE MBO + { 0xA5C5, BIDI_L }, // VAI SYLLABLE KPO + { 0xA5C6, BIDI_L }, // VAI SYLLABLE MGBO + { 0xA5C7, BIDI_L }, // VAI SYLLABLE GBO + { 0xA5C8, BIDI_L }, // VAI SYLLABLE GBON + { 0xA5C9, BIDI_L }, // VAI SYLLABLE FO + { 0xA5CA, BIDI_L }, // VAI SYLLABLE VO + { 0xA5CB, BIDI_L }, // VAI SYLLABLE TO + { 0xA5CC, BIDI_L }, // VAI SYLLABLE THO + { 0xA5CD, BIDI_L }, // VAI SYLLABLE DHO + { 0xA5CE, BIDI_L }, // VAI SYLLABLE DHHO + { 0xA5CF, BIDI_L }, // VAI SYLLABLE LO + { 0xA5D0, BIDI_L }, // VAI SYLLABLE RO + { 0xA5D1, BIDI_L }, // VAI SYLLABLE DO + { 0xA5D2, BIDI_L }, // VAI SYLLABLE NDO + { 0xA5D3, BIDI_L }, // VAI SYLLABLE SO + { 0xA5D4, BIDI_L }, // VAI SYLLABLE SHO + { 0xA5D5, BIDI_L }, // VAI SYLLABLE ZO + { 0xA5D6, BIDI_L }, // VAI SYLLABLE ZHO + { 0xA5D7, BIDI_L }, // VAI SYLLABLE CO + { 0xA5D8, BIDI_L }, // VAI SYLLABLE JO + { 0xA5D9, BIDI_L }, // VAI SYLLABLE NJO + { 0xA5DA, BIDI_L }, // VAI SYLLABLE YO + { 0xA5DB, BIDI_L }, // VAI SYLLABLE KO + { 0xA5DC, BIDI_L }, // VAI SYLLABLE NGGO + { 0xA5DD, BIDI_L }, // VAI SYLLABLE GO + { 0xA5DE, BIDI_L }, // VAI SYLLABLE MO + { 0xA5DF, BIDI_L }, // VAI SYLLABLE NO + { 0xA5E0, BIDI_L }, // VAI SYLLABLE NYO + { 0xA5E1, BIDI_L }, // VAI SYLLABLE E + { 0xA5E2, BIDI_L }, // VAI SYLLABLE EN + { 0xA5E3, BIDI_L }, // VAI SYLLABLE NGEN + { 0xA5E4, BIDI_L }, // VAI SYLLABLE HE + { 0xA5E5, BIDI_L }, // VAI SYLLABLE HEN + { 0xA5E6, BIDI_L }, // VAI SYLLABLE WE + { 0xA5E7, BIDI_L }, // VAI SYLLABLE WEN + { 0xA5E8, BIDI_L }, // VAI SYLLABLE PE + { 0xA5E9, BIDI_L }, // VAI SYLLABLE BHE + { 0xA5EA, BIDI_L }, // VAI SYLLABLE BE + { 0xA5EB, BIDI_L }, // VAI SYLLABLE MBE + { 0xA5EC, BIDI_L }, // VAI SYLLABLE KPE + { 0xA5ED, BIDI_L }, // VAI SYLLABLE KPEN + { 0xA5EE, BIDI_L }, // VAI SYLLABLE MGBE + { 0xA5EF, BIDI_L }, // VAI SYLLABLE GBE + { 0xA5F0, BIDI_L }, // VAI SYLLABLE GBEN + { 0xA5F1, BIDI_L }, // VAI SYLLABLE FE + { 0xA5F2, BIDI_L }, // VAI SYLLABLE VE + { 0xA5F3, BIDI_L }, // VAI SYLLABLE TE + { 0xA5F4, BIDI_L }, // VAI SYLLABLE THE + { 0xA5F5, BIDI_L }, // VAI SYLLABLE DHE + { 0xA5F6, BIDI_L }, // VAI SYLLABLE DHHE + { 0xA5F7, BIDI_L }, // VAI SYLLABLE LE + { 0xA5F8, BIDI_L }, // VAI SYLLABLE RE + { 0xA5F9, BIDI_L }, // VAI SYLLABLE DE + { 0xA5FA, BIDI_L }, // VAI SYLLABLE NDE + { 0xA5FB, BIDI_L }, // VAI SYLLABLE SE + { 0xA5FC, BIDI_L }, // VAI SYLLABLE SHE + { 0xA5FD, BIDI_L }, // VAI SYLLABLE ZE + { 0xA5FE, BIDI_L }, // VAI SYLLABLE ZHE + { 0xA5FF, BIDI_L }, // VAI SYLLABLE CE + { 0xA600, BIDI_L }, // VAI SYLLABLE JE + { 0xA601, BIDI_L }, // VAI SYLLABLE NJE + { 0xA602, BIDI_L }, // VAI SYLLABLE YE + { 0xA603, BIDI_L }, // VAI SYLLABLE KE + { 0xA604, BIDI_L }, // VAI SYLLABLE NGGE + { 0xA605, BIDI_L }, // VAI SYLLABLE NGGEN + { 0xA606, BIDI_L }, // VAI SYLLABLE GE + { 0xA607, BIDI_L }, // VAI SYLLABLE GEN + { 0xA608, BIDI_L }, // VAI SYLLABLE ME + { 0xA609, BIDI_L }, // VAI SYLLABLE NE + { 0xA60A, BIDI_L }, // VAI SYLLABLE NYE + { 0xA60B, BIDI_L }, // VAI SYLLABLE NG + { 0xA60C, BIDI_L }, // VAI SYLLABLE LENGTHENER + { 0xA60D, BIDI_ON }, // VAI COMMA + { 0xA60E, BIDI_ON }, // VAI FULL STOP + { 0xA60F, BIDI_ON }, // VAI QUESTION MARK + { 0xA610, BIDI_L }, // VAI SYLLABLE NDOLE FA + { 0xA611, BIDI_L }, // VAI SYLLABLE NDOLE KA + { 0xA612, BIDI_L }, // VAI SYLLABLE NDOLE SOO + { 0xA613, BIDI_L }, // VAI SYMBOL FEENG + { 0xA614, BIDI_L }, // VAI SYMBOL KEENG + { 0xA615, BIDI_L }, // VAI SYMBOL TING + { 0xA616, BIDI_L }, // VAI SYMBOL NII + { 0xA617, BIDI_L }, // VAI SYMBOL BANG + { 0xA618, BIDI_L }, // VAI SYMBOL FAA + { 0xA619, BIDI_L }, // VAI SYMBOL TAA + { 0xA61A, BIDI_L }, // VAI SYMBOL DANG + { 0xA61B, BIDI_L }, // VAI SYMBOL DOONG + { 0xA61C, BIDI_L }, // VAI SYMBOL KUNG + { 0xA61D, BIDI_L }, // VAI SYMBOL TONG + { 0xA61E, BIDI_L }, // VAI SYMBOL DO-O + { 0xA61F, BIDI_L }, // VAI SYMBOL JONG + { 0xA620, BIDI_L }, // VAI DIGIT ZERO + { 0xA621, BIDI_L }, // VAI DIGIT ONE + { 0xA622, BIDI_L }, // VAI DIGIT TWO + { 0xA623, BIDI_L }, // VAI DIGIT THREE + { 0xA624, BIDI_L }, // VAI DIGIT FOUR + { 0xA625, BIDI_L }, // VAI DIGIT FIVE + { 0xA626, BIDI_L }, // VAI DIGIT SIX + { 0xA627, BIDI_L }, // VAI DIGIT SEVEN + { 0xA628, BIDI_L }, // VAI DIGIT EIGHT + { 0xA629, BIDI_L }, // VAI DIGIT NINE + { 0xA62A, BIDI_L }, // VAI SYLLABLE NDOLE MA + { 0xA62B, BIDI_L }, // VAI SYLLABLE NDOLE DO + { 0xA640, BIDI_L }, // CYRILLIC CAPITAL LETTER ZEMLYA + { 0xA641, BIDI_L }, // CYRILLIC SMALL LETTER ZEMLYA + { 0xA642, BIDI_L }, // CYRILLIC CAPITAL LETTER DZELO + { 0xA643, BIDI_L }, // CYRILLIC SMALL LETTER DZELO + { 0xA644, BIDI_L }, // CYRILLIC CAPITAL LETTER REVERSED DZE + { 0xA645, BIDI_L }, // CYRILLIC SMALL LETTER REVERSED DZE + { 0xA646, BIDI_L }, // CYRILLIC CAPITAL LETTER IOTA + { 0xA647, BIDI_L }, // CYRILLIC SMALL LETTER IOTA + { 0xA648, BIDI_L }, // CYRILLIC CAPITAL LETTER DJERV + { 0xA649, BIDI_L }, // CYRILLIC SMALL LETTER DJERV + { 0xA64A, BIDI_L }, // CYRILLIC CAPITAL LETTER MONOGRAPH UK + { 0xA64B, BIDI_L }, // CYRILLIC SMALL LETTER MONOGRAPH UK + { 0xA64C, BIDI_L }, // CYRILLIC CAPITAL LETTER BROAD OMEGA + { 0xA64D, BIDI_L }, // CYRILLIC SMALL LETTER BROAD OMEGA + { 0xA64E, BIDI_L }, // CYRILLIC CAPITAL LETTER NEUTRAL YER + { 0xA64F, BIDI_L }, // CYRILLIC SMALL LETTER NEUTRAL YER + { 0xA650, BIDI_L }, // CYRILLIC CAPITAL LETTER YERU WITH BACK YER + { 0xA651, BIDI_L }, // CYRILLIC SMALL LETTER YERU WITH BACK YER + { 0xA652, BIDI_L }, // CYRILLIC CAPITAL LETTER IOTIFIED YAT + { 0xA653, BIDI_L }, // CYRILLIC SMALL LETTER IOTIFIED YAT + { 0xA654, BIDI_L }, // CYRILLIC CAPITAL LETTER REVERSED YU + { 0xA655, BIDI_L }, // CYRILLIC SMALL LETTER REVERSED YU + { 0xA656, BIDI_L }, // CYRILLIC CAPITAL LETTER IOTIFIED A + { 0xA657, BIDI_L }, // CYRILLIC SMALL LETTER IOTIFIED A + { 0xA658, BIDI_L }, // CYRILLIC CAPITAL LETTER CLOSED LITTLE YUS + { 0xA659, BIDI_L }, // CYRILLIC SMALL LETTER CLOSED LITTLE YUS + { 0xA65A, BIDI_L }, // CYRILLIC CAPITAL LETTER BLENDED YUS + { 0xA65B, BIDI_L }, // CYRILLIC SMALL LETTER BLENDED YUS + { 0xA65C, BIDI_L }, // CYRILLIC CAPITAL LETTER IOTIFIED CLOSED LITTLE YUS + { 0xA65D, BIDI_L }, // CYRILLIC SMALL LETTER IOTIFIED CLOSED LITTLE YUS + { 0xA65E, BIDI_L }, // CYRILLIC CAPITAL LETTER YN + { 0xA65F, BIDI_L }, // CYRILLIC SMALL LETTER YN + { 0xA660, BIDI_L }, // CYRILLIC CAPITAL LETTER REVERSED TSE + { 0xA661, BIDI_L }, // CYRILLIC SMALL LETTER REVERSED TSE + { 0xA662, BIDI_L }, // CYRILLIC CAPITAL LETTER SOFT DE + { 0xA663, BIDI_L }, // CYRILLIC SMALL LETTER SOFT DE + { 0xA664, BIDI_L }, // CYRILLIC CAPITAL LETTER SOFT EL + { 0xA665, BIDI_L }, // CYRILLIC SMALL LETTER SOFT EL + { 0xA666, BIDI_L }, // CYRILLIC CAPITAL LETTER SOFT EM + { 0xA667, BIDI_L }, // CYRILLIC SMALL LETTER SOFT EM + { 0xA668, BIDI_L }, // CYRILLIC CAPITAL LETTER MONOCULAR O + { 0xA669, BIDI_L }, // CYRILLIC SMALL LETTER MONOCULAR O + { 0xA66A, BIDI_L }, // CYRILLIC CAPITAL LETTER BINOCULAR O + { 0xA66B, BIDI_L }, // CYRILLIC SMALL LETTER BINOCULAR O + { 0xA66C, BIDI_L }, // CYRILLIC CAPITAL LETTER DOUBLE MONOCULAR O + { 0xA66D, BIDI_L }, // CYRILLIC SMALL LETTER DOUBLE MONOCULAR O + { 0xA66E, BIDI_L }, // CYRILLIC LETTER MULTIOCULAR O + { 0xA66F, BIDI_NSM }, // COMBINING CYRILLIC VZMET + { 0xA670, BIDI_NSM }, // COMBINING CYRILLIC TEN MILLIONS SIGN + { 0xA671, BIDI_NSM }, // COMBINING CYRILLIC HUNDRED MILLIONS SIGN + { 0xA672, BIDI_NSM }, // COMBINING CYRILLIC THOUSAND MILLIONS SIGN + { 0xA673, BIDI_ON }, // SLAVONIC ASTERISK + { 0xA674, BIDI_NSM }, // COMBINING CYRILLIC LETTER UKRAINIAN IE + { 0xA675, BIDI_NSM }, // COMBINING CYRILLIC LETTER I + { 0xA676, BIDI_NSM }, // COMBINING CYRILLIC LETTER YI + { 0xA677, BIDI_NSM }, // COMBINING CYRILLIC LETTER U + { 0xA678, BIDI_NSM }, // COMBINING CYRILLIC LETTER HARD SIGN + { 0xA679, BIDI_NSM }, // COMBINING CYRILLIC LETTER YERU + { 0xA67A, BIDI_NSM }, // COMBINING CYRILLIC LETTER SOFT SIGN + { 0xA67B, BIDI_NSM }, // COMBINING CYRILLIC LETTER OMEGA + { 0xA67C, BIDI_NSM }, // COMBINING CYRILLIC KAVYKA + { 0xA67D, BIDI_NSM }, // COMBINING CYRILLIC PAYEROK + { 0xA67E, BIDI_ON }, // CYRILLIC KAVYKA + { 0xA67F, BIDI_ON }, // CYRILLIC PAYEROK + { 0xA680, BIDI_L }, // CYRILLIC CAPITAL LETTER DWE + { 0xA681, BIDI_L }, // CYRILLIC SMALL LETTER DWE + { 0xA682, BIDI_L }, // CYRILLIC CAPITAL LETTER DZWE + { 0xA683, BIDI_L }, // CYRILLIC SMALL LETTER DZWE + { 0xA684, BIDI_L }, // CYRILLIC CAPITAL LETTER ZHWE + { 0xA685, BIDI_L }, // CYRILLIC SMALL LETTER ZHWE + { 0xA686, BIDI_L }, // CYRILLIC CAPITAL LETTER CCHE + { 0xA687, BIDI_L }, // CYRILLIC SMALL LETTER CCHE + { 0xA688, BIDI_L }, // CYRILLIC CAPITAL LETTER DZZE + { 0xA689, BIDI_L }, // CYRILLIC SMALL LETTER DZZE + { 0xA68A, BIDI_L }, // CYRILLIC CAPITAL LETTER TE WITH MIDDLE HOOK + { 0xA68B, BIDI_L }, // CYRILLIC SMALL LETTER TE WITH MIDDLE HOOK + { 0xA68C, BIDI_L }, // CYRILLIC CAPITAL LETTER TWE + { 0xA68D, BIDI_L }, // CYRILLIC SMALL LETTER TWE + { 0xA68E, BIDI_L }, // CYRILLIC CAPITAL LETTER TSWE + { 0xA68F, BIDI_L }, // CYRILLIC SMALL LETTER TSWE + { 0xA690, BIDI_L }, // CYRILLIC CAPITAL LETTER TSSE + { 0xA691, BIDI_L }, // CYRILLIC SMALL LETTER TSSE + { 0xA692, BIDI_L }, // CYRILLIC CAPITAL LETTER TCHE + { 0xA693, BIDI_L }, // CYRILLIC SMALL LETTER TCHE + { 0xA694, BIDI_L }, // CYRILLIC CAPITAL LETTER HWE + { 0xA695, BIDI_L }, // CYRILLIC SMALL LETTER HWE + { 0xA696, BIDI_L }, // CYRILLIC CAPITAL LETTER SHWE + { 0xA697, BIDI_L }, // CYRILLIC SMALL LETTER SHWE + { 0xA698, BIDI_L }, // CYRILLIC CAPITAL LETTER DOUBLE O + { 0xA699, BIDI_L }, // CYRILLIC SMALL LETTER DOUBLE O + { 0xA69A, BIDI_L }, // CYRILLIC CAPITAL LETTER CROSSED O + { 0xA69B, BIDI_L }, // CYRILLIC SMALL LETTER CROSSED O + { 0xA69C, BIDI_L }, // MODIFIER LETTER CYRILLIC HARD SIGN + { 0xA69D, BIDI_L }, // MODIFIER LETTER CYRILLIC SOFT SIGN + { 0xA69E, BIDI_NSM }, // COMBINING CYRILLIC LETTER EF + { 0xA69F, BIDI_NSM }, // COMBINING CYRILLIC LETTER IOTIFIED E + { 0xA6A0, BIDI_L }, // BAMUM LETTER A + { 0xA6A1, BIDI_L }, // BAMUM LETTER KA + { 0xA6A2, BIDI_L }, // BAMUM LETTER U + { 0xA6A3, BIDI_L }, // BAMUM LETTER KU + { 0xA6A4, BIDI_L }, // BAMUM LETTER EE + { 0xA6A5, BIDI_L }, // BAMUM LETTER REE + { 0xA6A6, BIDI_L }, // BAMUM LETTER TAE + { 0xA6A7, BIDI_L }, // BAMUM LETTER O + { 0xA6A8, BIDI_L }, // BAMUM LETTER NYI + { 0xA6A9, BIDI_L }, // BAMUM LETTER I + { 0xA6AA, BIDI_L }, // BAMUM LETTER LA + { 0xA6AB, BIDI_L }, // BAMUM LETTER PA + { 0xA6AC, BIDI_L }, // BAMUM LETTER RII + { 0xA6AD, BIDI_L }, // BAMUM LETTER RIEE + { 0xA6AE, BIDI_L }, // BAMUM LETTER LEEEE + { 0xA6AF, BIDI_L }, // BAMUM LETTER MEEEE + { 0xA6B0, BIDI_L }, // BAMUM LETTER TAA + { 0xA6B1, BIDI_L }, // BAMUM LETTER NDAA + { 0xA6B2, BIDI_L }, // BAMUM LETTER NJAEM + { 0xA6B3, BIDI_L }, // BAMUM LETTER M + { 0xA6B4, BIDI_L }, // BAMUM LETTER SUU + { 0xA6B5, BIDI_L }, // BAMUM LETTER MU + { 0xA6B6, BIDI_L }, // BAMUM LETTER SHII + { 0xA6B7, BIDI_L }, // BAMUM LETTER SI + { 0xA6B8, BIDI_L }, // BAMUM LETTER SHEUX + { 0xA6B9, BIDI_L }, // BAMUM LETTER SEUX + { 0xA6BA, BIDI_L }, // BAMUM LETTER KYEE + { 0xA6BB, BIDI_L }, // BAMUM LETTER KET + { 0xA6BC, BIDI_L }, // BAMUM LETTER NUAE + { 0xA6BD, BIDI_L }, // BAMUM LETTER NU + { 0xA6BE, BIDI_L }, // BAMUM LETTER NJUAE + { 0xA6BF, BIDI_L }, // BAMUM LETTER YOQ + { 0xA6C0, BIDI_L }, // BAMUM LETTER SHU + { 0xA6C1, BIDI_L }, // BAMUM LETTER YUQ + { 0xA6C2, BIDI_L }, // BAMUM LETTER YA + { 0xA6C3, BIDI_L }, // BAMUM LETTER NSHA + { 0xA6C4, BIDI_L }, // BAMUM LETTER KEUX + { 0xA6C5, BIDI_L }, // BAMUM LETTER PEUX + { 0xA6C6, BIDI_L }, // BAMUM LETTER NJEE + { 0xA6C7, BIDI_L }, // BAMUM LETTER NTEE + { 0xA6C8, BIDI_L }, // BAMUM LETTER PUE + { 0xA6C9, BIDI_L }, // BAMUM LETTER WUE + { 0xA6CA, BIDI_L }, // BAMUM LETTER PEE + { 0xA6CB, BIDI_L }, // BAMUM LETTER FEE + { 0xA6CC, BIDI_L }, // BAMUM LETTER RU + { 0xA6CD, BIDI_L }, // BAMUM LETTER LU + { 0xA6CE, BIDI_L }, // BAMUM LETTER MI + { 0xA6CF, BIDI_L }, // BAMUM LETTER NI + { 0xA6D0, BIDI_L }, // BAMUM LETTER REUX + { 0xA6D1, BIDI_L }, // BAMUM LETTER RAE + { 0xA6D2, BIDI_L }, // BAMUM LETTER KEN + { 0xA6D3, BIDI_L }, // BAMUM LETTER NGKWAEN + { 0xA6D4, BIDI_L }, // BAMUM LETTER NGGA + { 0xA6D5, BIDI_L }, // BAMUM LETTER NGA + { 0xA6D6, BIDI_L }, // BAMUM LETTER SHO + { 0xA6D7, BIDI_L }, // BAMUM LETTER PUAE + { 0xA6D8, BIDI_L }, // BAMUM LETTER FU + { 0xA6D9, BIDI_L }, // BAMUM LETTER FOM + { 0xA6DA, BIDI_L }, // BAMUM LETTER WA + { 0xA6DB, BIDI_L }, // BAMUM LETTER NA + { 0xA6DC, BIDI_L }, // BAMUM LETTER LI + { 0xA6DD, BIDI_L }, // BAMUM LETTER PI + { 0xA6DE, BIDI_L }, // BAMUM LETTER LOQ + { 0xA6DF, BIDI_L }, // BAMUM LETTER KO + { 0xA6E0, BIDI_L }, // BAMUM LETTER MBEN + { 0xA6E1, BIDI_L }, // BAMUM LETTER REN + { 0xA6E2, BIDI_L }, // BAMUM LETTER MEN + { 0xA6E3, BIDI_L }, // BAMUM LETTER MA + { 0xA6E4, BIDI_L }, // BAMUM LETTER TI + { 0xA6E5, BIDI_L }, // BAMUM LETTER KI + { 0xA6E6, BIDI_L }, // BAMUM LETTER MO + { 0xA6E7, BIDI_L }, // BAMUM LETTER MBAA + { 0xA6E8, BIDI_L }, // BAMUM LETTER TET + { 0xA6E9, BIDI_L }, // BAMUM LETTER KPA + { 0xA6EA, BIDI_L }, // BAMUM LETTER TEN + { 0xA6EB, BIDI_L }, // BAMUM LETTER NTUU + { 0xA6EC, BIDI_L }, // BAMUM LETTER SAMBA + { 0xA6ED, BIDI_L }, // BAMUM LETTER FAAMAE + { 0xA6EE, BIDI_L }, // BAMUM LETTER KOVUU + { 0xA6EF, BIDI_L }, // BAMUM LETTER KOGHOM + { 0xA6F0, BIDI_NSM }, // BAMUM COMBINING MARK KOQNDON + { 0xA6F1, BIDI_NSM }, // BAMUM COMBINING MARK TUKWENTIS + { 0xA6F2, BIDI_L }, // BAMUM NJAEMLI + { 0xA6F3, BIDI_L }, // BAMUM FULL STOP + { 0xA6F4, BIDI_L }, // BAMUM COLON + { 0xA6F5, BIDI_L }, // BAMUM COMMA + { 0xA6F6, BIDI_L }, // BAMUM SEMICOLON + { 0xA6F7, BIDI_L }, // BAMUM QUESTION MARK + { 0xA700, BIDI_ON }, // MODIFIER LETTER CHINESE TONE YIN PING + { 0xA701, BIDI_ON }, // MODIFIER LETTER CHINESE TONE YANG PING + { 0xA702, BIDI_ON }, // MODIFIER LETTER CHINESE TONE YIN SHANG + { 0xA703, BIDI_ON }, // MODIFIER LETTER CHINESE TONE YANG SHANG + { 0xA704, BIDI_ON }, // MODIFIER LETTER CHINESE TONE YIN QU + { 0xA705, BIDI_ON }, // MODIFIER LETTER CHINESE TONE YANG QU + { 0xA706, BIDI_ON }, // MODIFIER LETTER CHINESE TONE YIN RU + { 0xA707, BIDI_ON }, // MODIFIER LETTER CHINESE TONE YANG RU + { 0xA708, BIDI_ON }, // MODIFIER LETTER EXTRA-HIGH DOTTED TONE BAR + { 0xA709, BIDI_ON }, // MODIFIER LETTER HIGH DOTTED TONE BAR + { 0xA70A, BIDI_ON }, // MODIFIER LETTER MID DOTTED TONE BAR + { 0xA70B, BIDI_ON }, // MODIFIER LETTER LOW DOTTED TONE BAR + { 0xA70C, BIDI_ON }, // MODIFIER LETTER EXTRA-LOW DOTTED TONE BAR + { 0xA70D, BIDI_ON }, // MODIFIER LETTER EXTRA-HIGH DOTTED LEFT-STEM TONE BAR + { 0xA70E, BIDI_ON }, // MODIFIER LETTER HIGH DOTTED LEFT-STEM TONE BAR + { 0xA70F, BIDI_ON }, // MODIFIER LETTER MID DOTTED LEFT-STEM TONE BAR + { 0xA710, BIDI_ON }, // MODIFIER LETTER LOW DOTTED LEFT-STEM TONE BAR + { 0xA711, BIDI_ON }, // MODIFIER LETTER EXTRA-LOW DOTTED LEFT-STEM TONE BAR + { 0xA712, BIDI_ON }, // MODIFIER LETTER EXTRA-HIGH LEFT-STEM TONE BAR + { 0xA713, BIDI_ON }, // MODIFIER LETTER HIGH LEFT-STEM TONE BAR + { 0xA714, BIDI_ON }, // MODIFIER LETTER MID LEFT-STEM TONE BAR + { 0xA715, BIDI_ON }, // MODIFIER LETTER LOW LEFT-STEM TONE BAR + { 0xA716, BIDI_ON }, // MODIFIER LETTER EXTRA-LOW LEFT-STEM TONE BAR + { 0xA717, BIDI_ON }, // MODIFIER LETTER DOT VERTICAL BAR + { 0xA718, BIDI_ON }, // MODIFIER LETTER DOT SLASH + { 0xA719, BIDI_ON }, // MODIFIER LETTER DOT HORIZONTAL BAR + { 0xA71A, BIDI_ON }, // MODIFIER LETTER LOWER RIGHT CORNER ANGLE + { 0xA71B, BIDI_ON }, // MODIFIER LETTER RAISED UP ARROW + { 0xA71C, BIDI_ON }, // MODIFIER LETTER RAISED DOWN ARROW + { 0xA71D, BIDI_ON }, // MODIFIER LETTER RAISED EXCLAMATION MARK + { 0xA71E, BIDI_ON }, // MODIFIER LETTER RAISED INVERTED EXCLAMATION MARK + { 0xA71F, BIDI_ON }, // MODIFIER LETTER LOW INVERTED EXCLAMATION MARK + { 0xA720, BIDI_ON }, // MODIFIER LETTER STRESS AND HIGH TONE + { 0xA721, BIDI_ON }, // MODIFIER LETTER STRESS AND LOW TONE + { 0xA722, BIDI_L }, // LATIN CAPITAL LETTER EGYPTOLOGICAL ALEF + { 0xA723, BIDI_L }, // LATIN SMALL LETTER EGYPTOLOGICAL ALEF + { 0xA724, BIDI_L }, // LATIN CAPITAL LETTER EGYPTOLOGICAL AIN + { 0xA725, BIDI_L }, // LATIN SMALL LETTER EGYPTOLOGICAL AIN + { 0xA726, BIDI_L }, // LATIN CAPITAL LETTER HENG + { 0xA727, BIDI_L }, // LATIN SMALL LETTER HENG + { 0xA728, BIDI_L }, // LATIN CAPITAL LETTER TZ + { 0xA729, BIDI_L }, // LATIN SMALL LETTER TZ + { 0xA72A, BIDI_L }, // LATIN CAPITAL LETTER TRESILLO + { 0xA72B, BIDI_L }, // LATIN SMALL LETTER TRESILLO + { 0xA72C, BIDI_L }, // LATIN CAPITAL LETTER CUATRILLO + { 0xA72D, BIDI_L }, // LATIN SMALL LETTER CUATRILLO + { 0xA72E, BIDI_L }, // LATIN CAPITAL LETTER CUATRILLO WITH COMMA + { 0xA72F, BIDI_L }, // LATIN SMALL LETTER CUATRILLO WITH COMMA + { 0xA730, BIDI_L }, // LATIN LETTER SMALL CAPITAL F + { 0xA731, BIDI_L }, // LATIN LETTER SMALL CAPITAL S + { 0xA732, BIDI_L }, // LATIN CAPITAL LETTER AA + { 0xA733, BIDI_L }, // LATIN SMALL LETTER AA + { 0xA734, BIDI_L }, // LATIN CAPITAL LETTER AO + { 0xA735, BIDI_L }, // LATIN SMALL LETTER AO + { 0xA736, BIDI_L }, // LATIN CAPITAL LETTER AU + { 0xA737, BIDI_L }, // LATIN SMALL LETTER AU + { 0xA738, BIDI_L }, // LATIN CAPITAL LETTER AV + { 0xA739, BIDI_L }, // LATIN SMALL LETTER AV + { 0xA73A, BIDI_L }, // LATIN CAPITAL LETTER AV WITH HORIZONTAL BAR + { 0xA73B, BIDI_L }, // LATIN SMALL LETTER AV WITH HORIZONTAL BAR + { 0xA73C, BIDI_L }, // LATIN CAPITAL LETTER AY + { 0xA73D, BIDI_L }, // LATIN SMALL LETTER AY + { 0xA73E, BIDI_L }, // LATIN CAPITAL LETTER REVERSED C WITH DOT + { 0xA73F, BIDI_L }, // LATIN SMALL LETTER REVERSED C WITH DOT + { 0xA740, BIDI_L }, // LATIN CAPITAL LETTER K WITH STROKE + { 0xA741, BIDI_L }, // LATIN SMALL LETTER K WITH STROKE + { 0xA742, BIDI_L }, // LATIN CAPITAL LETTER K WITH DIAGONAL STROKE + { 0xA743, BIDI_L }, // LATIN SMALL LETTER K WITH DIAGONAL STROKE + { 0xA744, BIDI_L }, // LATIN CAPITAL LETTER K WITH STROKE AND DIAGONAL STROKE + { 0xA745, BIDI_L }, // LATIN SMALL LETTER K WITH STROKE AND DIAGONAL STROKE + { 0xA746, BIDI_L }, // LATIN CAPITAL LETTER BROKEN L + { 0xA747, BIDI_L }, // LATIN SMALL LETTER BROKEN L + { 0xA748, BIDI_L }, // LATIN CAPITAL LETTER L WITH HIGH STROKE + { 0xA749, BIDI_L }, // LATIN SMALL LETTER L WITH HIGH STROKE + { 0xA74A, BIDI_L }, // LATIN CAPITAL LETTER O WITH LONG STROKE OVERLAY + { 0xA74B, BIDI_L }, // LATIN SMALL LETTER O WITH LONG STROKE OVERLAY + { 0xA74C, BIDI_L }, // LATIN CAPITAL LETTER O WITH LOOP + { 0xA74D, BIDI_L }, // LATIN SMALL LETTER O WITH LOOP + { 0xA74E, BIDI_L }, // LATIN CAPITAL LETTER OO + { 0xA74F, BIDI_L }, // LATIN SMALL LETTER OO + { 0xA750, BIDI_L }, // LATIN CAPITAL LETTER P WITH STROKE THROUGH DESCENDER + { 0xA751, BIDI_L }, // LATIN SMALL LETTER P WITH STROKE THROUGH DESCENDER + { 0xA752, BIDI_L }, // LATIN CAPITAL LETTER P WITH FLOURISH + { 0xA753, BIDI_L }, // LATIN SMALL LETTER P WITH FLOURISH + { 0xA754, BIDI_L }, // LATIN CAPITAL LETTER P WITH SQUIRREL TAIL + { 0xA755, BIDI_L }, // LATIN SMALL LETTER P WITH SQUIRREL TAIL + { 0xA756, BIDI_L }, // LATIN CAPITAL LETTER Q WITH STROKE THROUGH DESCENDER + { 0xA757, BIDI_L }, // LATIN SMALL LETTER Q WITH STROKE THROUGH DESCENDER + { 0xA758, BIDI_L }, // LATIN CAPITAL LETTER Q WITH DIAGONAL STROKE + { 0xA759, BIDI_L }, // LATIN SMALL LETTER Q WITH DIAGONAL STROKE + { 0xA75A, BIDI_L }, // LATIN CAPITAL LETTER R ROTUNDA + { 0xA75B, BIDI_L }, // LATIN SMALL LETTER R ROTUNDA + { 0xA75C, BIDI_L }, // LATIN CAPITAL LETTER RUM ROTUNDA + { 0xA75D, BIDI_L }, // LATIN SMALL LETTER RUM ROTUNDA + { 0xA75E, BIDI_L }, // LATIN CAPITAL LETTER V WITH DIAGONAL STROKE + { 0xA75F, BIDI_L }, // LATIN SMALL LETTER V WITH DIAGONAL STROKE + { 0xA760, BIDI_L }, // LATIN CAPITAL LETTER VY + { 0xA761, BIDI_L }, // LATIN SMALL LETTER VY + { 0xA762, BIDI_L }, // LATIN CAPITAL LETTER VISIGOTHIC Z + { 0xA763, BIDI_L }, // LATIN SMALL LETTER VISIGOTHIC Z + { 0xA764, BIDI_L }, // LATIN CAPITAL LETTER THORN WITH STROKE + { 0xA765, BIDI_L }, // LATIN SMALL LETTER THORN WITH STROKE + { 0xA766, BIDI_L }, // LATIN CAPITAL LETTER THORN WITH STROKE THROUGH DESCENDER + { 0xA767, BIDI_L }, // LATIN SMALL LETTER THORN WITH STROKE THROUGH DESCENDER + { 0xA768, BIDI_L }, // LATIN CAPITAL LETTER VEND + { 0xA769, BIDI_L }, // LATIN SMALL LETTER VEND + { 0xA76A, BIDI_L }, // LATIN CAPITAL LETTER ET + { 0xA76B, BIDI_L }, // LATIN SMALL LETTER ET + { 0xA76C, BIDI_L }, // LATIN CAPITAL LETTER IS + { 0xA76D, BIDI_L }, // LATIN SMALL LETTER IS + { 0xA76E, BIDI_L }, // LATIN CAPITAL LETTER CON + { 0xA76F, BIDI_L }, // LATIN SMALL LETTER CON + { 0xA770, BIDI_L }, // MODIFIER LETTER US + { 0xA771, BIDI_L }, // LATIN SMALL LETTER DUM + { 0xA772, BIDI_L }, // LATIN SMALL LETTER LUM + { 0xA773, BIDI_L }, // LATIN SMALL LETTER MUM + { 0xA774, BIDI_L }, // LATIN SMALL LETTER NUM + { 0xA775, BIDI_L }, // LATIN SMALL LETTER RUM + { 0xA776, BIDI_L }, // LATIN LETTER SMALL CAPITAL RUM + { 0xA777, BIDI_L }, // LATIN SMALL LETTER TUM + { 0xA778, BIDI_L }, // LATIN SMALL LETTER UM + { 0xA779, BIDI_L }, // LATIN CAPITAL LETTER INSULAR D + { 0xA77A, BIDI_L }, // LATIN SMALL LETTER INSULAR D + { 0xA77B, BIDI_L }, // LATIN CAPITAL LETTER INSULAR F + { 0xA77C, BIDI_L }, // LATIN SMALL LETTER INSULAR F + { 0xA77D, BIDI_L }, // LATIN CAPITAL LETTER INSULAR G + { 0xA77E, BIDI_L }, // LATIN CAPITAL LETTER TURNED INSULAR G + { 0xA77F, BIDI_L }, // LATIN SMALL LETTER TURNED INSULAR G + { 0xA780, BIDI_L }, // LATIN CAPITAL LETTER TURNED L + { 0xA781, BIDI_L }, // LATIN SMALL LETTER TURNED L + { 0xA782, BIDI_L }, // LATIN CAPITAL LETTER INSULAR R + { 0xA783, BIDI_L }, // LATIN SMALL LETTER INSULAR R + { 0xA784, BIDI_L }, // LATIN CAPITAL LETTER INSULAR S + { 0xA785, BIDI_L }, // LATIN SMALL LETTER INSULAR S + { 0xA786, BIDI_L }, // LATIN CAPITAL LETTER INSULAR T + { 0xA787, BIDI_L }, // LATIN SMALL LETTER INSULAR T + { 0xA788, BIDI_ON }, // MODIFIER LETTER LOW CIRCUMFLEX ACCENT + { 0xA789, BIDI_L }, // MODIFIER LETTER COLON + { 0xA78A, BIDI_L }, // MODIFIER LETTER SHORT EQUALS SIGN + { 0xA78B, BIDI_L }, // LATIN CAPITAL LETTER SALTILLO + { 0xA78C, BIDI_L }, // LATIN SMALL LETTER SALTILLO + { 0xA78D, BIDI_L }, // LATIN CAPITAL LETTER TURNED H + { 0xA78E, BIDI_L }, // LATIN SMALL LETTER L WITH RETROFLEX HOOK AND BELT + { 0xA78F, BIDI_L }, // LATIN LETTER SINOLOGICAL DOT + { 0xA790, BIDI_L }, // LATIN CAPITAL LETTER N WITH DESCENDER + { 0xA791, BIDI_L }, // LATIN SMALL LETTER N WITH DESCENDER + { 0xA792, BIDI_L }, // LATIN CAPITAL LETTER C WITH BAR + { 0xA793, BIDI_L }, // LATIN SMALL LETTER C WITH BAR + { 0xA794, BIDI_L }, // LATIN SMALL LETTER C WITH PALATAL HOOK + { 0xA795, BIDI_L }, // LATIN SMALL LETTER H WITH PALATAL HOOK + { 0xA796, BIDI_L }, // LATIN CAPITAL LETTER B WITH FLOURISH + { 0xA797, BIDI_L }, // LATIN SMALL LETTER B WITH FLOURISH + { 0xA798, BIDI_L }, // LATIN CAPITAL LETTER F WITH STROKE + { 0xA799, BIDI_L }, // LATIN SMALL LETTER F WITH STROKE + { 0xA79A, BIDI_L }, // LATIN CAPITAL LETTER VOLAPUK AE + { 0xA79B, BIDI_L }, // LATIN SMALL LETTER VOLAPUK AE + { 0xA79C, BIDI_L }, // LATIN CAPITAL LETTER VOLAPUK OE + { 0xA79D, BIDI_L }, // LATIN SMALL LETTER VOLAPUK OE + { 0xA79E, BIDI_L }, // LATIN CAPITAL LETTER VOLAPUK UE + { 0xA79F, BIDI_L }, // LATIN SMALL LETTER VOLAPUK UE + { 0xA7A0, BIDI_L }, // LATIN CAPITAL LETTER G WITH OBLIQUE STROKE + { 0xA7A1, BIDI_L }, // LATIN SMALL LETTER G WITH OBLIQUE STROKE + { 0xA7A2, BIDI_L }, // LATIN CAPITAL LETTER K WITH OBLIQUE STROKE + { 0xA7A3, BIDI_L }, // LATIN SMALL LETTER K WITH OBLIQUE STROKE + { 0xA7A4, BIDI_L }, // LATIN CAPITAL LETTER N WITH OBLIQUE STROKE + { 0xA7A5, BIDI_L }, // LATIN SMALL LETTER N WITH OBLIQUE STROKE + { 0xA7A6, BIDI_L }, // LATIN CAPITAL LETTER R WITH OBLIQUE STROKE + { 0xA7A7, BIDI_L }, // LATIN SMALL LETTER R WITH OBLIQUE STROKE + { 0xA7A8, BIDI_L }, // LATIN CAPITAL LETTER S WITH OBLIQUE STROKE + { 0xA7A9, BIDI_L }, // LATIN SMALL LETTER S WITH OBLIQUE STROKE + { 0xA7AA, BIDI_L }, // LATIN CAPITAL LETTER H WITH HOOK + { 0xA7AB, BIDI_L }, // LATIN CAPITAL LETTER REVERSED OPEN E + { 0xA7AC, BIDI_L }, // LATIN CAPITAL LETTER SCRIPT G + { 0xA7AD, BIDI_L }, // LATIN CAPITAL LETTER L WITH BELT + { 0xA7B0, BIDI_L }, // LATIN CAPITAL LETTER TURNED K + { 0xA7B1, BIDI_L }, // LATIN CAPITAL LETTER TURNED T + { 0xA7B2, BIDI_L }, // LATIN CAPITAL LETTER J WITH CROSSED-TAIL + { 0xA7B3, BIDI_L }, // LATIN CAPITAL LETTER CHI + { 0xA7B4, BIDI_L }, // LATIN CAPITAL LETTER BETA + { 0xA7B5, BIDI_L }, // LATIN SMALL LETTER BETA + { 0xA7B6, BIDI_L }, // LATIN CAPITAL LETTER OMEGA + { 0xA7B7, BIDI_L }, // LATIN SMALL LETTER OMEGA + { 0xA7F7, BIDI_L }, // LATIN EPIGRAPHIC LETTER SIDEWAYS I + { 0xA7F8, BIDI_L }, // MODIFIER LETTER CAPITAL H WITH STROKE + { 0xA7F9, BIDI_L }, // MODIFIER LETTER SMALL LIGATURE OE + { 0xA7FA, BIDI_L }, // LATIN LETTER SMALL CAPITAL TURNED M + { 0xA7FB, BIDI_L }, // LATIN EPIGRAPHIC LETTER REVERSED F + { 0xA7FC, BIDI_L }, // LATIN EPIGRAPHIC LETTER REVERSED P + { 0xA7FD, BIDI_L }, // LATIN EPIGRAPHIC LETTER INVERTED M + { 0xA7FE, BIDI_L }, // LATIN EPIGRAPHIC LETTER I LONGA + { 0xA7FF, BIDI_L }, // LATIN EPIGRAPHIC LETTER ARCHAIC M + { 0xA800, BIDI_L }, // SYLOTI NAGRI LETTER A + { 0xA801, BIDI_L }, // SYLOTI NAGRI LETTER I + { 0xA802, BIDI_NSM }, // SYLOTI NAGRI SIGN DVISVARA + { 0xA803, BIDI_L }, // SYLOTI NAGRI LETTER U + { 0xA804, BIDI_L }, // SYLOTI NAGRI LETTER E + { 0xA805, BIDI_L }, // SYLOTI NAGRI LETTER O + { 0xA806, BIDI_NSM }, // SYLOTI NAGRI SIGN HASANTA + { 0xA807, BIDI_L }, // SYLOTI NAGRI LETTER KO + { 0xA808, BIDI_L }, // SYLOTI NAGRI LETTER KHO + { 0xA809, BIDI_L }, // SYLOTI NAGRI LETTER GO + { 0xA80A, BIDI_L }, // SYLOTI NAGRI LETTER GHO + { 0xA80B, BIDI_NSM }, // SYLOTI NAGRI SIGN ANUSVARA + { 0xA80C, BIDI_L }, // SYLOTI NAGRI LETTER CO + { 0xA80D, BIDI_L }, // SYLOTI NAGRI LETTER CHO + { 0xA80E, BIDI_L }, // SYLOTI NAGRI LETTER JO + { 0xA80F, BIDI_L }, // SYLOTI NAGRI LETTER JHO + { 0xA810, BIDI_L }, // SYLOTI NAGRI LETTER TTO + { 0xA811, BIDI_L }, // SYLOTI NAGRI LETTER TTHO + { 0xA812, BIDI_L }, // SYLOTI NAGRI LETTER DDO + { 0xA813, BIDI_L }, // SYLOTI NAGRI LETTER DDHO + { 0xA814, BIDI_L }, // SYLOTI NAGRI LETTER TO + { 0xA815, BIDI_L }, // SYLOTI NAGRI LETTER THO + { 0xA816, BIDI_L }, // SYLOTI NAGRI LETTER DO + { 0xA817, BIDI_L }, // SYLOTI NAGRI LETTER DHO + { 0xA818, BIDI_L }, // SYLOTI NAGRI LETTER NO + { 0xA819, BIDI_L }, // SYLOTI NAGRI LETTER PO + { 0xA81A, BIDI_L }, // SYLOTI NAGRI LETTER PHO + { 0xA81B, BIDI_L }, // SYLOTI NAGRI LETTER BO + { 0xA81C, BIDI_L }, // SYLOTI NAGRI LETTER BHO + { 0xA81D, BIDI_L }, // SYLOTI NAGRI LETTER MO + { 0xA81E, BIDI_L }, // SYLOTI NAGRI LETTER RO + { 0xA81F, BIDI_L }, // SYLOTI NAGRI LETTER LO + { 0xA820, BIDI_L }, // SYLOTI NAGRI LETTER RRO + { 0xA821, BIDI_L }, // SYLOTI NAGRI LETTER SO + { 0xA822, BIDI_L }, // SYLOTI NAGRI LETTER HO + { 0xA823, BIDI_L }, // SYLOTI NAGRI VOWEL SIGN A + { 0xA824, BIDI_L }, // SYLOTI NAGRI VOWEL SIGN I + { 0xA825, BIDI_NSM }, // SYLOTI NAGRI VOWEL SIGN U + { 0xA826, BIDI_NSM }, // SYLOTI NAGRI VOWEL SIGN E + { 0xA827, BIDI_L }, // SYLOTI NAGRI VOWEL SIGN OO + { 0xA828, BIDI_ON }, // SYLOTI NAGRI POETRY MARK-1 + { 0xA829, BIDI_ON }, // SYLOTI NAGRI POETRY MARK-2 + { 0xA82A, BIDI_ON }, // SYLOTI NAGRI POETRY MARK-3 + { 0xA82B, BIDI_ON }, // SYLOTI NAGRI POETRY MARK-4 + { 0xA830, BIDI_L }, // NORTH INDIC FRACTION ONE QUARTER + { 0xA831, BIDI_L }, // NORTH INDIC FRACTION ONE HALF + { 0xA832, BIDI_L }, // NORTH INDIC FRACTION THREE QUARTERS + { 0xA833, BIDI_L }, // NORTH INDIC FRACTION ONE SIXTEENTH + { 0xA834, BIDI_L }, // NORTH INDIC FRACTION ONE EIGHTH + { 0xA835, BIDI_L }, // NORTH INDIC FRACTION THREE SIXTEENTHS + { 0xA836, BIDI_L }, // NORTH INDIC QUARTER MARK + { 0xA837, BIDI_L }, // NORTH INDIC PLACEHOLDER MARK + { 0xA838, BIDI_ET }, // NORTH INDIC RUPEE MARK + { 0xA839, BIDI_ET }, // NORTH INDIC QUANTITY MARK + { 0xA840, BIDI_L }, // PHAGS-PA LETTER KA + { 0xA841, BIDI_L }, // PHAGS-PA LETTER KHA + { 0xA842, BIDI_L }, // PHAGS-PA LETTER GA + { 0xA843, BIDI_L }, // PHAGS-PA LETTER NGA + { 0xA844, BIDI_L }, // PHAGS-PA LETTER CA + { 0xA845, BIDI_L }, // PHAGS-PA LETTER CHA + { 0xA846, BIDI_L }, // PHAGS-PA LETTER JA + { 0xA847, BIDI_L }, // PHAGS-PA LETTER NYA + { 0xA848, BIDI_L }, // PHAGS-PA LETTER TA + { 0xA849, BIDI_L }, // PHAGS-PA LETTER THA + { 0xA84A, BIDI_L }, // PHAGS-PA LETTER DA + { 0xA84B, BIDI_L }, // PHAGS-PA LETTER NA + { 0xA84C, BIDI_L }, // PHAGS-PA LETTER PA + { 0xA84D, BIDI_L }, // PHAGS-PA LETTER PHA + { 0xA84E, BIDI_L }, // PHAGS-PA LETTER BA + { 0xA84F, BIDI_L }, // PHAGS-PA LETTER MA + { 0xA850, BIDI_L }, // PHAGS-PA LETTER TSA + { 0xA851, BIDI_L }, // PHAGS-PA LETTER TSHA + { 0xA852, BIDI_L }, // PHAGS-PA LETTER DZA + { 0xA853, BIDI_L }, // PHAGS-PA LETTER WA + { 0xA854, BIDI_L }, // PHAGS-PA LETTER ZHA + { 0xA855, BIDI_L }, // PHAGS-PA LETTER ZA + { 0xA856, BIDI_L }, // PHAGS-PA LETTER SMALL A + { 0xA857, BIDI_L }, // PHAGS-PA LETTER YA + { 0xA858, BIDI_L }, // PHAGS-PA LETTER RA + { 0xA859, BIDI_L }, // PHAGS-PA LETTER LA + { 0xA85A, BIDI_L }, // PHAGS-PA LETTER SHA + { 0xA85B, BIDI_L }, // PHAGS-PA LETTER SA + { 0xA85C, BIDI_L }, // PHAGS-PA LETTER HA + { 0xA85D, BIDI_L }, // PHAGS-PA LETTER A + { 0xA85E, BIDI_L }, // PHAGS-PA LETTER I + { 0xA85F, BIDI_L }, // PHAGS-PA LETTER U + { 0xA860, BIDI_L }, // PHAGS-PA LETTER E + { 0xA861, BIDI_L }, // PHAGS-PA LETTER O + { 0xA862, BIDI_L }, // PHAGS-PA LETTER QA + { 0xA863, BIDI_L }, // PHAGS-PA LETTER XA + { 0xA864, BIDI_L }, // PHAGS-PA LETTER FA + { 0xA865, BIDI_L }, // PHAGS-PA LETTER GGA + { 0xA866, BIDI_L }, // PHAGS-PA LETTER EE + { 0xA867, BIDI_L }, // PHAGS-PA SUBJOINED LETTER WA + { 0xA868, BIDI_L }, // PHAGS-PA SUBJOINED LETTER YA + { 0xA869, BIDI_L }, // PHAGS-PA LETTER TTA + { 0xA86A, BIDI_L }, // PHAGS-PA LETTER TTHA + { 0xA86B, BIDI_L }, // PHAGS-PA LETTER DDA + { 0xA86C, BIDI_L }, // PHAGS-PA LETTER NNA + { 0xA86D, BIDI_L }, // PHAGS-PA LETTER ALTERNATE YA + { 0xA86E, BIDI_L }, // PHAGS-PA LETTER VOICELESS SHA + { 0xA86F, BIDI_L }, // PHAGS-PA LETTER VOICED HA + { 0xA870, BIDI_L }, // PHAGS-PA LETTER ASPIRATED FA + { 0xA871, BIDI_L }, // PHAGS-PA SUBJOINED LETTER RA + { 0xA872, BIDI_L }, // PHAGS-PA SUPERFIXED LETTER RA + { 0xA873, BIDI_L }, // PHAGS-PA LETTER CANDRABINDU + { 0xA874, BIDI_ON }, // PHAGS-PA SINGLE HEAD MARK + { 0xA875, BIDI_ON }, // PHAGS-PA DOUBLE HEAD MARK + { 0xA876, BIDI_ON }, // PHAGS-PA MARK SHAD + { 0xA877, BIDI_ON }, // PHAGS-PA MARK DOUBLE SHAD + { 0xA880, BIDI_L }, // SAURASHTRA SIGN ANUSVARA + { 0xA881, BIDI_L }, // SAURASHTRA SIGN VISARGA + { 0xA882, BIDI_L }, // SAURASHTRA LETTER A + { 0xA883, BIDI_L }, // SAURASHTRA LETTER AA + { 0xA884, BIDI_L }, // SAURASHTRA LETTER I + { 0xA885, BIDI_L }, // SAURASHTRA LETTER II + { 0xA886, BIDI_L }, // SAURASHTRA LETTER U + { 0xA887, BIDI_L }, // SAURASHTRA LETTER UU + { 0xA888, BIDI_L }, // SAURASHTRA LETTER VOCALIC R + { 0xA889, BIDI_L }, // SAURASHTRA LETTER VOCALIC RR + { 0xA88A, BIDI_L }, // SAURASHTRA LETTER VOCALIC L + { 0xA88B, BIDI_L }, // SAURASHTRA LETTER VOCALIC LL + { 0xA88C, BIDI_L }, // SAURASHTRA LETTER E + { 0xA88D, BIDI_L }, // SAURASHTRA LETTER EE + { 0xA88E, BIDI_L }, // SAURASHTRA LETTER AI + { 0xA88F, BIDI_L }, // SAURASHTRA LETTER O + { 0xA890, BIDI_L }, // SAURASHTRA LETTER OO + { 0xA891, BIDI_L }, // SAURASHTRA LETTER AU + { 0xA892, BIDI_L }, // SAURASHTRA LETTER KA + { 0xA893, BIDI_L }, // SAURASHTRA LETTER KHA + { 0xA894, BIDI_L }, // SAURASHTRA LETTER GA + { 0xA895, BIDI_L }, // SAURASHTRA LETTER GHA + { 0xA896, BIDI_L }, // SAURASHTRA LETTER NGA + { 0xA897, BIDI_L }, // SAURASHTRA LETTER CA + { 0xA898, BIDI_L }, // SAURASHTRA LETTER CHA + { 0xA899, BIDI_L }, // SAURASHTRA LETTER JA + { 0xA89A, BIDI_L }, // SAURASHTRA LETTER JHA + { 0xA89B, BIDI_L }, // SAURASHTRA LETTER NYA + { 0xA89C, BIDI_L }, // SAURASHTRA LETTER TTA + { 0xA89D, BIDI_L }, // SAURASHTRA LETTER TTHA + { 0xA89E, BIDI_L }, // SAURASHTRA LETTER DDA + { 0xA89F, BIDI_L }, // SAURASHTRA LETTER DDHA + { 0xA8A0, BIDI_L }, // SAURASHTRA LETTER NNA + { 0xA8A1, BIDI_L }, // SAURASHTRA LETTER TA + { 0xA8A2, BIDI_L }, // SAURASHTRA LETTER THA + { 0xA8A3, BIDI_L }, // SAURASHTRA LETTER DA + { 0xA8A4, BIDI_L }, // SAURASHTRA LETTER DHA + { 0xA8A5, BIDI_L }, // SAURASHTRA LETTER NA + { 0xA8A6, BIDI_L }, // SAURASHTRA LETTER PA + { 0xA8A7, BIDI_L }, // SAURASHTRA LETTER PHA + { 0xA8A8, BIDI_L }, // SAURASHTRA LETTER BA + { 0xA8A9, BIDI_L }, // SAURASHTRA LETTER BHA + { 0xA8AA, BIDI_L }, // SAURASHTRA LETTER MA + { 0xA8AB, BIDI_L }, // SAURASHTRA LETTER YA + { 0xA8AC, BIDI_L }, // SAURASHTRA LETTER RA + { 0xA8AD, BIDI_L }, // SAURASHTRA LETTER LA + { 0xA8AE, BIDI_L }, // SAURASHTRA LETTER VA + { 0xA8AF, BIDI_L }, // SAURASHTRA LETTER SHA + { 0xA8B0, BIDI_L }, // SAURASHTRA LETTER SSA + { 0xA8B1, BIDI_L }, // SAURASHTRA LETTER SA + { 0xA8B2, BIDI_L }, // SAURASHTRA LETTER HA + { 0xA8B3, BIDI_L }, // SAURASHTRA LETTER LLA + { 0xA8B4, BIDI_L }, // SAURASHTRA CONSONANT SIGN HAARU + { 0xA8B5, BIDI_L }, // SAURASHTRA VOWEL SIGN AA + { 0xA8B6, BIDI_L }, // SAURASHTRA VOWEL SIGN I + { 0xA8B7, BIDI_L }, // SAURASHTRA VOWEL SIGN II + { 0xA8B8, BIDI_L }, // SAURASHTRA VOWEL SIGN U + { 0xA8B9, BIDI_L }, // SAURASHTRA VOWEL SIGN UU + { 0xA8BA, BIDI_L }, // SAURASHTRA VOWEL SIGN VOCALIC R + { 0xA8BB, BIDI_L }, // SAURASHTRA VOWEL SIGN VOCALIC RR + { 0xA8BC, BIDI_L }, // SAURASHTRA VOWEL SIGN VOCALIC L + { 0xA8BD, BIDI_L }, // SAURASHTRA VOWEL SIGN VOCALIC LL + { 0xA8BE, BIDI_L }, // SAURASHTRA VOWEL SIGN E + { 0xA8BF, BIDI_L }, // SAURASHTRA VOWEL SIGN EE + { 0xA8C0, BIDI_L }, // SAURASHTRA VOWEL SIGN AI + { 0xA8C1, BIDI_L }, // SAURASHTRA VOWEL SIGN O + { 0xA8C2, BIDI_L }, // SAURASHTRA VOWEL SIGN OO + { 0xA8C3, BIDI_L }, // SAURASHTRA VOWEL SIGN AU + { 0xA8C4, BIDI_NSM }, // SAURASHTRA SIGN VIRAMA + { 0xA8CE, BIDI_L }, // SAURASHTRA DANDA + { 0xA8CF, BIDI_L }, // SAURASHTRA DOUBLE DANDA + { 0xA8D0, BIDI_L }, // SAURASHTRA DIGIT ZERO + { 0xA8D1, BIDI_L }, // SAURASHTRA DIGIT ONE + { 0xA8D2, BIDI_L }, // SAURASHTRA DIGIT TWO + { 0xA8D3, BIDI_L }, // SAURASHTRA DIGIT THREE + { 0xA8D4, BIDI_L }, // SAURASHTRA DIGIT FOUR + { 0xA8D5, BIDI_L }, // SAURASHTRA DIGIT FIVE + { 0xA8D6, BIDI_L }, // SAURASHTRA DIGIT SIX + { 0xA8D7, BIDI_L }, // SAURASHTRA DIGIT SEVEN + { 0xA8D8, BIDI_L }, // SAURASHTRA DIGIT EIGHT + { 0xA8D9, BIDI_L }, // SAURASHTRA DIGIT NINE + { 0xA8E0, BIDI_NSM }, // COMBINING DEVANAGARI DIGIT ZERO + { 0xA8E1, BIDI_NSM }, // COMBINING DEVANAGARI DIGIT ONE + { 0xA8E2, BIDI_NSM }, // COMBINING DEVANAGARI DIGIT TWO + { 0xA8E3, BIDI_NSM }, // COMBINING DEVANAGARI DIGIT THREE + { 0xA8E4, BIDI_NSM }, // COMBINING DEVANAGARI DIGIT FOUR + { 0xA8E5, BIDI_NSM }, // COMBINING DEVANAGARI DIGIT FIVE + { 0xA8E6, BIDI_NSM }, // COMBINING DEVANAGARI DIGIT SIX + { 0xA8E7, BIDI_NSM }, // COMBINING DEVANAGARI DIGIT SEVEN + { 0xA8E8, BIDI_NSM }, // COMBINING DEVANAGARI DIGIT EIGHT + { 0xA8E9, BIDI_NSM }, // COMBINING DEVANAGARI DIGIT NINE + { 0xA8EA, BIDI_NSM }, // COMBINING DEVANAGARI LETTER A + { 0xA8EB, BIDI_NSM }, // COMBINING DEVANAGARI LETTER U + { 0xA8EC, BIDI_NSM }, // COMBINING DEVANAGARI LETTER KA + { 0xA8ED, BIDI_NSM }, // COMBINING DEVANAGARI LETTER NA + { 0xA8EE, BIDI_NSM }, // COMBINING DEVANAGARI LETTER PA + { 0xA8EF, BIDI_NSM }, // COMBINING DEVANAGARI LETTER RA + { 0xA8F0, BIDI_NSM }, // COMBINING DEVANAGARI LETTER VI + { 0xA8F1, BIDI_NSM }, // COMBINING DEVANAGARI SIGN AVAGRAHA + { 0xA8F2, BIDI_L }, // DEVANAGARI SIGN SPACING CANDRABINDU + { 0xA8F3, BIDI_L }, // DEVANAGARI SIGN CANDRABINDU VIRAMA + { 0xA8F4, BIDI_L }, // DEVANAGARI SIGN DOUBLE CANDRABINDU VIRAMA + { 0xA8F5, BIDI_L }, // DEVANAGARI SIGN CANDRABINDU TWO + { 0xA8F6, BIDI_L }, // DEVANAGARI SIGN CANDRABINDU THREE + { 0xA8F7, BIDI_L }, // DEVANAGARI SIGN CANDRABINDU AVAGRAHA + { 0xA8F8, BIDI_L }, // DEVANAGARI SIGN PUSHPIKA + { 0xA8F9, BIDI_L }, // DEVANAGARI GAP FILLER + { 0xA8FA, BIDI_L }, // DEVANAGARI CARET + { 0xA8FB, BIDI_L }, // DEVANAGARI HEADSTROKE + { 0xA8FC, BIDI_L }, // DEVANAGARI SIGN SIDDHAM + { 0xA8FD, BIDI_L }, // DEVANAGARI JAIN OM + { 0xA900, BIDI_L }, // KAYAH LI DIGIT ZERO + { 0xA901, BIDI_L }, // KAYAH LI DIGIT ONE + { 0xA902, BIDI_L }, // KAYAH LI DIGIT TWO + { 0xA903, BIDI_L }, // KAYAH LI DIGIT THREE + { 0xA904, BIDI_L }, // KAYAH LI DIGIT FOUR + { 0xA905, BIDI_L }, // KAYAH LI DIGIT FIVE + { 0xA906, BIDI_L }, // KAYAH LI DIGIT SIX + { 0xA907, BIDI_L }, // KAYAH LI DIGIT SEVEN + { 0xA908, BIDI_L }, // KAYAH LI DIGIT EIGHT + { 0xA909, BIDI_L }, // KAYAH LI DIGIT NINE + { 0xA90A, BIDI_L }, // KAYAH LI LETTER KA + { 0xA90B, BIDI_L }, // KAYAH LI LETTER KHA + { 0xA90C, BIDI_L }, // KAYAH LI LETTER GA + { 0xA90D, BIDI_L }, // KAYAH LI LETTER NGA + { 0xA90E, BIDI_L }, // KAYAH LI LETTER SA + { 0xA90F, BIDI_L }, // KAYAH LI LETTER SHA + { 0xA910, BIDI_L }, // KAYAH LI LETTER ZA + { 0xA911, BIDI_L }, // KAYAH LI LETTER NYA + { 0xA912, BIDI_L }, // KAYAH LI LETTER TA + { 0xA913, BIDI_L }, // KAYAH LI LETTER HTA + { 0xA914, BIDI_L }, // KAYAH LI LETTER NA + { 0xA915, BIDI_L }, // KAYAH LI LETTER PA + { 0xA916, BIDI_L }, // KAYAH LI LETTER PHA + { 0xA917, BIDI_L }, // KAYAH LI LETTER MA + { 0xA918, BIDI_L }, // KAYAH LI LETTER DA + { 0xA919, BIDI_L }, // KAYAH LI LETTER BA + { 0xA91A, BIDI_L }, // KAYAH LI LETTER RA + { 0xA91B, BIDI_L }, // KAYAH LI LETTER YA + { 0xA91C, BIDI_L }, // KAYAH LI LETTER LA + { 0xA91D, BIDI_L }, // KAYAH LI LETTER WA + { 0xA91E, BIDI_L }, // KAYAH LI LETTER THA + { 0xA91F, BIDI_L }, // KAYAH LI LETTER HA + { 0xA920, BIDI_L }, // KAYAH LI LETTER VA + { 0xA921, BIDI_L }, // KAYAH LI LETTER CA + { 0xA922, BIDI_L }, // KAYAH LI LETTER A + { 0xA923, BIDI_L }, // KAYAH LI LETTER OE + { 0xA924, BIDI_L }, // KAYAH LI LETTER I + { 0xA925, BIDI_L }, // KAYAH LI LETTER OO + { 0xA926, BIDI_NSM }, // KAYAH LI VOWEL UE + { 0xA927, BIDI_NSM }, // KAYAH LI VOWEL E + { 0xA928, BIDI_NSM }, // KAYAH LI VOWEL U + { 0xA929, BIDI_NSM }, // KAYAH LI VOWEL EE + { 0xA92A, BIDI_NSM }, // KAYAH LI VOWEL O + { 0xA92B, BIDI_NSM }, // KAYAH LI TONE PLOPHU + { 0xA92C, BIDI_NSM }, // KAYAH LI TONE CALYA + { 0xA92D, BIDI_NSM }, // KAYAH LI TONE CALYA PLOPHU + { 0xA92E, BIDI_L }, // KAYAH LI SIGN CWI + { 0xA92F, BIDI_L }, // KAYAH LI SIGN SHYA + { 0xA930, BIDI_L }, // REJANG LETTER KA + { 0xA931, BIDI_L }, // REJANG LETTER GA + { 0xA932, BIDI_L }, // REJANG LETTER NGA + { 0xA933, BIDI_L }, // REJANG LETTER TA + { 0xA934, BIDI_L }, // REJANG LETTER DA + { 0xA935, BIDI_L }, // REJANG LETTER NA + { 0xA936, BIDI_L }, // REJANG LETTER PA + { 0xA937, BIDI_L }, // REJANG LETTER BA + { 0xA938, BIDI_L }, // REJANG LETTER MA + { 0xA939, BIDI_L }, // REJANG LETTER CA + { 0xA93A, BIDI_L }, // REJANG LETTER JA + { 0xA93B, BIDI_L }, // REJANG LETTER NYA + { 0xA93C, BIDI_L }, // REJANG LETTER SA + { 0xA93D, BIDI_L }, // REJANG LETTER RA + { 0xA93E, BIDI_L }, // REJANG LETTER LA + { 0xA93F, BIDI_L }, // REJANG LETTER YA + { 0xA940, BIDI_L }, // REJANG LETTER WA + { 0xA941, BIDI_L }, // REJANG LETTER HA + { 0xA942, BIDI_L }, // REJANG LETTER MBA + { 0xA943, BIDI_L }, // REJANG LETTER NGGA + { 0xA944, BIDI_L }, // REJANG LETTER NDA + { 0xA945, BIDI_L }, // REJANG LETTER NYJA + { 0xA946, BIDI_L }, // REJANG LETTER A + { 0xA947, BIDI_NSM }, // REJANG VOWEL SIGN I + { 0xA948, BIDI_NSM }, // REJANG VOWEL SIGN U + { 0xA949, BIDI_NSM }, // REJANG VOWEL SIGN E + { 0xA94A, BIDI_NSM }, // REJANG VOWEL SIGN AI + { 0xA94B, BIDI_NSM }, // REJANG VOWEL SIGN O + { 0xA94C, BIDI_NSM }, // REJANG VOWEL SIGN AU + { 0xA94D, BIDI_NSM }, // REJANG VOWEL SIGN EU + { 0xA94E, BIDI_NSM }, // REJANG VOWEL SIGN EA + { 0xA94F, BIDI_NSM }, // REJANG CONSONANT SIGN NG + { 0xA950, BIDI_NSM }, // REJANG CONSONANT SIGN N + { 0xA951, BIDI_NSM }, // REJANG CONSONANT SIGN R + { 0xA952, BIDI_L }, // REJANG CONSONANT SIGN H + { 0xA953, BIDI_L }, // REJANG VIRAMA + { 0xA95F, BIDI_L }, // REJANG SECTION MARK + { 0xA960, BIDI_L }, // HANGUL CHOSEONG TIKEUT-MIEUM + { 0xA961, BIDI_L }, // HANGUL CHOSEONG TIKEUT-PIEUP + { 0xA962, BIDI_L }, // HANGUL CHOSEONG TIKEUT-SIOS + { 0xA963, BIDI_L }, // HANGUL CHOSEONG TIKEUT-CIEUC + { 0xA964, BIDI_L }, // HANGUL CHOSEONG RIEUL-KIYEOK + { 0xA965, BIDI_L }, // HANGUL CHOSEONG RIEUL-SSANGKIYEOK + { 0xA966, BIDI_L }, // HANGUL CHOSEONG RIEUL-TIKEUT + { 0xA967, BIDI_L }, // HANGUL CHOSEONG RIEUL-SSANGTIKEUT + { 0xA968, BIDI_L }, // HANGUL CHOSEONG RIEUL-MIEUM + { 0xA969, BIDI_L }, // HANGUL CHOSEONG RIEUL-PIEUP + { 0xA96A, BIDI_L }, // HANGUL CHOSEONG RIEUL-SSANGPIEUP + { 0xA96B, BIDI_L }, // HANGUL CHOSEONG RIEUL-KAPYEOUNPIEUP + { 0xA96C, BIDI_L }, // HANGUL CHOSEONG RIEUL-SIOS + { 0xA96D, BIDI_L }, // HANGUL CHOSEONG RIEUL-CIEUC + { 0xA96E, BIDI_L }, // HANGUL CHOSEONG RIEUL-KHIEUKH + { 0xA96F, BIDI_L }, // HANGUL CHOSEONG MIEUM-KIYEOK + { 0xA970, BIDI_L }, // HANGUL CHOSEONG MIEUM-TIKEUT + { 0xA971, BIDI_L }, // HANGUL CHOSEONG MIEUM-SIOS + { 0xA972, BIDI_L }, // HANGUL CHOSEONG PIEUP-SIOS-THIEUTH + { 0xA973, BIDI_L }, // HANGUL CHOSEONG PIEUP-KHIEUKH + { 0xA974, BIDI_L }, // HANGUL CHOSEONG PIEUP-HIEUH + { 0xA975, BIDI_L }, // HANGUL CHOSEONG SSANGSIOS-PIEUP + { 0xA976, BIDI_L }, // HANGUL CHOSEONG IEUNG-RIEUL + { 0xA977, BIDI_L }, // HANGUL CHOSEONG IEUNG-HIEUH + { 0xA978, BIDI_L }, // HANGUL CHOSEONG SSANGCIEUC-HIEUH + { 0xA979, BIDI_L }, // HANGUL CHOSEONG SSANGTHIEUTH + { 0xA97A, BIDI_L }, // HANGUL CHOSEONG PHIEUPH-HIEUH + { 0xA97B, BIDI_L }, // HANGUL CHOSEONG HIEUH-SIOS + { 0xA97C, BIDI_L }, // HANGUL CHOSEONG SSANGYEORINHIEUH + { 0xA980, BIDI_NSM }, // JAVANESE SIGN PANYANGGA + { 0xA981, BIDI_NSM }, // JAVANESE SIGN CECAK + { 0xA982, BIDI_NSM }, // JAVANESE SIGN LAYAR + { 0xA983, BIDI_L }, // JAVANESE SIGN WIGNYAN + { 0xA984, BIDI_L }, // JAVANESE LETTER A + { 0xA985, BIDI_L }, // JAVANESE LETTER I KAWI + { 0xA986, BIDI_L }, // JAVANESE LETTER I + { 0xA987, BIDI_L }, // JAVANESE LETTER II + { 0xA988, BIDI_L }, // JAVANESE LETTER U + { 0xA989, BIDI_L }, // JAVANESE LETTER PA CEREK + { 0xA98A, BIDI_L }, // JAVANESE LETTER NGA LELET + { 0xA98B, BIDI_L }, // JAVANESE LETTER NGA LELET RASWADI + { 0xA98C, BIDI_L }, // JAVANESE LETTER E + { 0xA98D, BIDI_L }, // JAVANESE LETTER AI + { 0xA98E, BIDI_L }, // JAVANESE LETTER O + { 0xA98F, BIDI_L }, // JAVANESE LETTER KA + { 0xA990, BIDI_L }, // JAVANESE LETTER KA SASAK + { 0xA991, BIDI_L }, // JAVANESE LETTER KA MURDA + { 0xA992, BIDI_L }, // JAVANESE LETTER GA + { 0xA993, BIDI_L }, // JAVANESE LETTER GA MURDA + { 0xA994, BIDI_L }, // JAVANESE LETTER NGA + { 0xA995, BIDI_L }, // JAVANESE LETTER CA + { 0xA996, BIDI_L }, // JAVANESE LETTER CA MURDA + { 0xA997, BIDI_L }, // JAVANESE LETTER JA + { 0xA998, BIDI_L }, // JAVANESE LETTER NYA MURDA + { 0xA999, BIDI_L }, // JAVANESE LETTER JA MAHAPRANA + { 0xA99A, BIDI_L }, // JAVANESE LETTER NYA + { 0xA99B, BIDI_L }, // JAVANESE LETTER TTA + { 0xA99C, BIDI_L }, // JAVANESE LETTER TTA MAHAPRANA + { 0xA99D, BIDI_L }, // JAVANESE LETTER DDA + { 0xA99E, BIDI_L }, // JAVANESE LETTER DDA MAHAPRANA + { 0xA99F, BIDI_L }, // JAVANESE LETTER NA MURDA + { 0xA9A0, BIDI_L }, // JAVANESE LETTER TA + { 0xA9A1, BIDI_L }, // JAVANESE LETTER TA MURDA + { 0xA9A2, BIDI_L }, // JAVANESE LETTER DA + { 0xA9A3, BIDI_L }, // JAVANESE LETTER DA MAHAPRANA + { 0xA9A4, BIDI_L }, // JAVANESE LETTER NA + { 0xA9A5, BIDI_L }, // JAVANESE LETTER PA + { 0xA9A6, BIDI_L }, // JAVANESE LETTER PA MURDA + { 0xA9A7, BIDI_L }, // JAVANESE LETTER BA + { 0xA9A8, BIDI_L }, // JAVANESE LETTER BA MURDA + { 0xA9A9, BIDI_L }, // JAVANESE LETTER MA + { 0xA9AA, BIDI_L }, // JAVANESE LETTER YA + { 0xA9AB, BIDI_L }, // JAVANESE LETTER RA + { 0xA9AC, BIDI_L }, // JAVANESE LETTER RA AGUNG + { 0xA9AD, BIDI_L }, // JAVANESE LETTER LA + { 0xA9AE, BIDI_L }, // JAVANESE LETTER WA + { 0xA9AF, BIDI_L }, // JAVANESE LETTER SA MURDA + { 0xA9B0, BIDI_L }, // JAVANESE LETTER SA MAHAPRANA + { 0xA9B1, BIDI_L }, // JAVANESE LETTER SA + { 0xA9B2, BIDI_L }, // JAVANESE LETTER HA + { 0xA9B3, BIDI_NSM }, // JAVANESE SIGN CECAK TELU + { 0xA9B4, BIDI_L }, // JAVANESE VOWEL SIGN TARUNG + { 0xA9B5, BIDI_L }, // JAVANESE VOWEL SIGN TOLONG + { 0xA9B6, BIDI_NSM }, // JAVANESE VOWEL SIGN WULU + { 0xA9B7, BIDI_NSM }, // JAVANESE VOWEL SIGN WULU MELIK + { 0xA9B8, BIDI_NSM }, // JAVANESE VOWEL SIGN SUKU + { 0xA9B9, BIDI_NSM }, // JAVANESE VOWEL SIGN SUKU MENDUT + { 0xA9BA, BIDI_L }, // JAVANESE VOWEL SIGN TALING + { 0xA9BB, BIDI_L }, // JAVANESE VOWEL SIGN DIRGA MURE + { 0xA9BC, BIDI_NSM }, // JAVANESE VOWEL SIGN PEPET + { 0xA9BD, BIDI_L }, // JAVANESE CONSONANT SIGN KERET + { 0xA9BE, BIDI_L }, // JAVANESE CONSONANT SIGN PENGKAL + { 0xA9BF, BIDI_L }, // JAVANESE CONSONANT SIGN CAKRA + { 0xA9C0, BIDI_L }, // JAVANESE PANGKON + { 0xA9C1, BIDI_L }, // JAVANESE LEFT RERENGGAN + { 0xA9C2, BIDI_L }, // JAVANESE RIGHT RERENGGAN + { 0xA9C3, BIDI_L }, // JAVANESE PADA ANDAP + { 0xA9C4, BIDI_L }, // JAVANESE PADA MADYA + { 0xA9C5, BIDI_L }, // JAVANESE PADA LUHUR + { 0xA9C6, BIDI_L }, // JAVANESE PADA WINDU + { 0xA9C7, BIDI_L }, // JAVANESE PADA PANGKAT + { 0xA9C8, BIDI_L }, // JAVANESE PADA LINGSA + { 0xA9C9, BIDI_L }, // JAVANESE PADA LUNGSI + { 0xA9CA, BIDI_L }, // JAVANESE PADA ADEG + { 0xA9CB, BIDI_L }, // JAVANESE PADA ADEG ADEG + { 0xA9CC, BIDI_L }, // JAVANESE PADA PISELEH + { 0xA9CD, BIDI_L }, // JAVANESE TURNED PADA PISELEH + { 0xA9CF, BIDI_L }, // JAVANESE PANGRANGKEP + { 0xA9D0, BIDI_L }, // JAVANESE DIGIT ZERO + { 0xA9D1, BIDI_L }, // JAVANESE DIGIT ONE + { 0xA9D2, BIDI_L }, // JAVANESE DIGIT TWO + { 0xA9D3, BIDI_L }, // JAVANESE DIGIT THREE + { 0xA9D4, BIDI_L }, // JAVANESE DIGIT FOUR + { 0xA9D5, BIDI_L }, // JAVANESE DIGIT FIVE + { 0xA9D6, BIDI_L }, // JAVANESE DIGIT SIX + { 0xA9D7, BIDI_L }, // JAVANESE DIGIT SEVEN + { 0xA9D8, BIDI_L }, // JAVANESE DIGIT EIGHT + { 0xA9D9, BIDI_L }, // JAVANESE DIGIT NINE + { 0xA9DE, BIDI_L }, // JAVANESE PADA TIRTA TUMETES + { 0xA9DF, BIDI_L }, // JAVANESE PADA ISEN-ISEN + { 0xA9E0, BIDI_L }, // MYANMAR LETTER SHAN GHA + { 0xA9E1, BIDI_L }, // MYANMAR LETTER SHAN CHA + { 0xA9E2, BIDI_L }, // MYANMAR LETTER SHAN JHA + { 0xA9E3, BIDI_L }, // MYANMAR LETTER SHAN NNA + { 0xA9E4, BIDI_L }, // MYANMAR LETTER SHAN BHA + { 0xA9E5, BIDI_NSM }, // MYANMAR SIGN SHAN SAW + { 0xA9E6, BIDI_L }, // MYANMAR MODIFIER LETTER SHAN REDUPLICATION + { 0xA9E7, BIDI_L }, // MYANMAR LETTER TAI LAING NYA + { 0xA9E8, BIDI_L }, // MYANMAR LETTER TAI LAING FA + { 0xA9E9, BIDI_L }, // MYANMAR LETTER TAI LAING GA + { 0xA9EA, BIDI_L }, // MYANMAR LETTER TAI LAING GHA + { 0xA9EB, BIDI_L }, // MYANMAR LETTER TAI LAING JA + { 0xA9EC, BIDI_L }, // MYANMAR LETTER TAI LAING JHA + { 0xA9ED, BIDI_L }, // MYANMAR LETTER TAI LAING DDA + { 0xA9EE, BIDI_L }, // MYANMAR LETTER TAI LAING DDHA + { 0xA9EF, BIDI_L }, // MYANMAR LETTER TAI LAING NNA + { 0xA9F0, BIDI_L }, // MYANMAR TAI LAING DIGIT ZERO + { 0xA9F1, BIDI_L }, // MYANMAR TAI LAING DIGIT ONE + { 0xA9F2, BIDI_L }, // MYANMAR TAI LAING DIGIT TWO + { 0xA9F3, BIDI_L }, // MYANMAR TAI LAING DIGIT THREE + { 0xA9F4, BIDI_L }, // MYANMAR TAI LAING DIGIT FOUR + { 0xA9F5, BIDI_L }, // MYANMAR TAI LAING DIGIT FIVE + { 0xA9F6, BIDI_L }, // MYANMAR TAI LAING DIGIT SIX + { 0xA9F7, BIDI_L }, // MYANMAR TAI LAING DIGIT SEVEN + { 0xA9F8, BIDI_L }, // MYANMAR TAI LAING DIGIT EIGHT + { 0xA9F9, BIDI_L }, // MYANMAR TAI LAING DIGIT NINE + { 0xA9FA, BIDI_L }, // MYANMAR LETTER TAI LAING LLA + { 0xA9FB, BIDI_L }, // MYANMAR LETTER TAI LAING DA + { 0xA9FC, BIDI_L }, // MYANMAR LETTER TAI LAING DHA + { 0xA9FD, BIDI_L }, // MYANMAR LETTER TAI LAING BA + { 0xA9FE, BIDI_L }, // MYANMAR LETTER TAI LAING BHA + { 0xAA00, BIDI_L }, // CHAM LETTER A + { 0xAA01, BIDI_L }, // CHAM LETTER I + { 0xAA02, BIDI_L }, // CHAM LETTER U + { 0xAA03, BIDI_L }, // CHAM LETTER E + { 0xAA04, BIDI_L }, // CHAM LETTER AI + { 0xAA05, BIDI_L }, // CHAM LETTER O + { 0xAA06, BIDI_L }, // CHAM LETTER KA + { 0xAA07, BIDI_L }, // CHAM LETTER KHA + { 0xAA08, BIDI_L }, // CHAM LETTER GA + { 0xAA09, BIDI_L }, // CHAM LETTER GHA + { 0xAA0A, BIDI_L }, // CHAM LETTER NGUE + { 0xAA0B, BIDI_L }, // CHAM LETTER NGA + { 0xAA0C, BIDI_L }, // CHAM LETTER CHA + { 0xAA0D, BIDI_L }, // CHAM LETTER CHHA + { 0xAA0E, BIDI_L }, // CHAM LETTER JA + { 0xAA0F, BIDI_L }, // CHAM LETTER JHA + { 0xAA10, BIDI_L }, // CHAM LETTER NHUE + { 0xAA11, BIDI_L }, // CHAM LETTER NHA + { 0xAA12, BIDI_L }, // CHAM LETTER NHJA + { 0xAA13, BIDI_L }, // CHAM LETTER TA + { 0xAA14, BIDI_L }, // CHAM LETTER THA + { 0xAA15, BIDI_L }, // CHAM LETTER DA + { 0xAA16, BIDI_L }, // CHAM LETTER DHA + { 0xAA17, BIDI_L }, // CHAM LETTER NUE + { 0xAA18, BIDI_L }, // CHAM LETTER NA + { 0xAA19, BIDI_L }, // CHAM LETTER DDA + { 0xAA1A, BIDI_L }, // CHAM LETTER PA + { 0xAA1B, BIDI_L }, // CHAM LETTER PPA + { 0xAA1C, BIDI_L }, // CHAM LETTER PHA + { 0xAA1D, BIDI_L }, // CHAM LETTER BA + { 0xAA1E, BIDI_L }, // CHAM LETTER BHA + { 0xAA1F, BIDI_L }, // CHAM LETTER MUE + { 0xAA20, BIDI_L }, // CHAM LETTER MA + { 0xAA21, BIDI_L }, // CHAM LETTER BBA + { 0xAA22, BIDI_L }, // CHAM LETTER YA + { 0xAA23, BIDI_L }, // CHAM LETTER RA + { 0xAA24, BIDI_L }, // CHAM LETTER LA + { 0xAA25, BIDI_L }, // CHAM LETTER VA + { 0xAA26, BIDI_L }, // CHAM LETTER SSA + { 0xAA27, BIDI_L }, // CHAM LETTER SA + { 0xAA28, BIDI_L }, // CHAM LETTER HA + { 0xAA29, BIDI_NSM }, // CHAM VOWEL SIGN AA + { 0xAA2A, BIDI_NSM }, // CHAM VOWEL SIGN I + { 0xAA2B, BIDI_NSM }, // CHAM VOWEL SIGN II + { 0xAA2C, BIDI_NSM }, // CHAM VOWEL SIGN EI + { 0xAA2D, BIDI_NSM }, // CHAM VOWEL SIGN U + { 0xAA2E, BIDI_NSM }, // CHAM VOWEL SIGN OE + { 0xAA2F, BIDI_L }, // CHAM VOWEL SIGN O + { 0xAA30, BIDI_L }, // CHAM VOWEL SIGN AI + { 0xAA31, BIDI_NSM }, // CHAM VOWEL SIGN AU + { 0xAA32, BIDI_NSM }, // CHAM VOWEL SIGN UE + { 0xAA33, BIDI_L }, // CHAM CONSONANT SIGN YA + { 0xAA34, BIDI_L }, // CHAM CONSONANT SIGN RA + { 0xAA35, BIDI_NSM }, // CHAM CONSONANT SIGN LA + { 0xAA36, BIDI_NSM }, // CHAM CONSONANT SIGN WA + { 0xAA40, BIDI_L }, // CHAM LETTER FINAL K + { 0xAA41, BIDI_L }, // CHAM LETTER FINAL G + { 0xAA42, BIDI_L }, // CHAM LETTER FINAL NG + { 0xAA43, BIDI_NSM }, // CHAM CONSONANT SIGN FINAL NG + { 0xAA44, BIDI_L }, // CHAM LETTER FINAL CH + { 0xAA45, BIDI_L }, // CHAM LETTER FINAL T + { 0xAA46, BIDI_L }, // CHAM LETTER FINAL N + { 0xAA47, BIDI_L }, // CHAM LETTER FINAL P + { 0xAA48, BIDI_L }, // CHAM LETTER FINAL Y + { 0xAA49, BIDI_L }, // CHAM LETTER FINAL R + { 0xAA4A, BIDI_L }, // CHAM LETTER FINAL L + { 0xAA4B, BIDI_L }, // CHAM LETTER FINAL SS + { 0xAA4C, BIDI_NSM }, // CHAM CONSONANT SIGN FINAL M + { 0xAA4D, BIDI_L }, // CHAM CONSONANT SIGN FINAL H + { 0xAA50, BIDI_L }, // CHAM DIGIT ZERO + { 0xAA51, BIDI_L }, // CHAM DIGIT ONE + { 0xAA52, BIDI_L }, // CHAM DIGIT TWO + { 0xAA53, BIDI_L }, // CHAM DIGIT THREE + { 0xAA54, BIDI_L }, // CHAM DIGIT FOUR + { 0xAA55, BIDI_L }, // CHAM DIGIT FIVE + { 0xAA56, BIDI_L }, // CHAM DIGIT SIX + { 0xAA57, BIDI_L }, // CHAM DIGIT SEVEN + { 0xAA58, BIDI_L }, // CHAM DIGIT EIGHT + { 0xAA59, BIDI_L }, // CHAM DIGIT NINE + { 0xAA5C, BIDI_L }, // CHAM PUNCTUATION SPIRAL + { 0xAA5D, BIDI_L }, // CHAM PUNCTUATION DANDA + { 0xAA5E, BIDI_L }, // CHAM PUNCTUATION DOUBLE DANDA + { 0xAA5F, BIDI_L }, // CHAM PUNCTUATION TRIPLE DANDA + { 0xAA60, BIDI_L }, // MYANMAR LETTER KHAMTI GA + { 0xAA61, BIDI_L }, // MYANMAR LETTER KHAMTI CA + { 0xAA62, BIDI_L }, // MYANMAR LETTER KHAMTI CHA + { 0xAA63, BIDI_L }, // MYANMAR LETTER KHAMTI JA + { 0xAA64, BIDI_L }, // MYANMAR LETTER KHAMTI JHA + { 0xAA65, BIDI_L }, // MYANMAR LETTER KHAMTI NYA + { 0xAA66, BIDI_L }, // MYANMAR LETTER KHAMTI TTA + { 0xAA67, BIDI_L }, // MYANMAR LETTER KHAMTI TTHA + { 0xAA68, BIDI_L }, // MYANMAR LETTER KHAMTI DDA + { 0xAA69, BIDI_L }, // MYANMAR LETTER KHAMTI DDHA + { 0xAA6A, BIDI_L }, // MYANMAR LETTER KHAMTI DHA + { 0xAA6B, BIDI_L }, // MYANMAR LETTER KHAMTI NA + { 0xAA6C, BIDI_L }, // MYANMAR LETTER KHAMTI SA + { 0xAA6D, BIDI_L }, // MYANMAR LETTER KHAMTI HA + { 0xAA6E, BIDI_L }, // MYANMAR LETTER KHAMTI HHA + { 0xAA6F, BIDI_L }, // MYANMAR LETTER KHAMTI FA + { 0xAA70, BIDI_L }, // MYANMAR MODIFIER LETTER KHAMTI REDUPLICATION + { 0xAA71, BIDI_L }, // MYANMAR LETTER KHAMTI XA + { 0xAA72, BIDI_L }, // MYANMAR LETTER KHAMTI ZA + { 0xAA73, BIDI_L }, // MYANMAR LETTER KHAMTI RA + { 0xAA74, BIDI_L }, // MYANMAR LOGOGRAM KHAMTI OAY + { 0xAA75, BIDI_L }, // MYANMAR LOGOGRAM KHAMTI QN + { 0xAA76, BIDI_L }, // MYANMAR LOGOGRAM KHAMTI HM + { 0xAA77, BIDI_L }, // MYANMAR SYMBOL AITON EXCLAMATION + { 0xAA78, BIDI_L }, // MYANMAR SYMBOL AITON ONE + { 0xAA79, BIDI_L }, // MYANMAR SYMBOL AITON TWO + { 0xAA7A, BIDI_L }, // MYANMAR LETTER AITON RA + { 0xAA7B, BIDI_L }, // MYANMAR SIGN PAO KAREN TONE + { 0xAA7C, BIDI_NSM }, // MYANMAR SIGN TAI LAING TONE-2 + { 0xAA7D, BIDI_L }, // MYANMAR SIGN TAI LAING TONE-5 + { 0xAA7E, BIDI_L }, // MYANMAR LETTER SHWE PALAUNG CHA + { 0xAA7F, BIDI_L }, // MYANMAR LETTER SHWE PALAUNG SHA + { 0xAA80, BIDI_L }, // TAI VIET LETTER LOW KO + { 0xAA81, BIDI_L }, // TAI VIET LETTER HIGH KO + { 0xAA82, BIDI_L }, // TAI VIET LETTER LOW KHO + { 0xAA83, BIDI_L }, // TAI VIET LETTER HIGH KHO + { 0xAA84, BIDI_L }, // TAI VIET LETTER LOW KHHO + { 0xAA85, BIDI_L }, // TAI VIET LETTER HIGH KHHO + { 0xAA86, BIDI_L }, // TAI VIET LETTER LOW GO + { 0xAA87, BIDI_L }, // TAI VIET LETTER HIGH GO + { 0xAA88, BIDI_L }, // TAI VIET LETTER LOW NGO + { 0xAA89, BIDI_L }, // TAI VIET LETTER HIGH NGO + { 0xAA8A, BIDI_L }, // TAI VIET LETTER LOW CO + { 0xAA8B, BIDI_L }, // TAI VIET LETTER HIGH CO + { 0xAA8C, BIDI_L }, // TAI VIET LETTER LOW CHO + { 0xAA8D, BIDI_L }, // TAI VIET LETTER HIGH CHO + { 0xAA8E, BIDI_L }, // TAI VIET LETTER LOW SO + { 0xAA8F, BIDI_L }, // TAI VIET LETTER HIGH SO + { 0xAA90, BIDI_L }, // TAI VIET LETTER LOW NYO + { 0xAA91, BIDI_L }, // TAI VIET LETTER HIGH NYO + { 0xAA92, BIDI_L }, // TAI VIET LETTER LOW DO + { 0xAA93, BIDI_L }, // TAI VIET LETTER HIGH DO + { 0xAA94, BIDI_L }, // TAI VIET LETTER LOW TO + { 0xAA95, BIDI_L }, // TAI VIET LETTER HIGH TO + { 0xAA96, BIDI_L }, // TAI VIET LETTER LOW THO + { 0xAA97, BIDI_L }, // TAI VIET LETTER HIGH THO + { 0xAA98, BIDI_L }, // TAI VIET LETTER LOW NO + { 0xAA99, BIDI_L }, // TAI VIET LETTER HIGH NO + { 0xAA9A, BIDI_L }, // TAI VIET LETTER LOW BO + { 0xAA9B, BIDI_L }, // TAI VIET LETTER HIGH BO + { 0xAA9C, BIDI_L }, // TAI VIET LETTER LOW PO + { 0xAA9D, BIDI_L }, // TAI VIET LETTER HIGH PO + { 0xAA9E, BIDI_L }, // TAI VIET LETTER LOW PHO + { 0xAA9F, BIDI_L }, // TAI VIET LETTER HIGH PHO + { 0xAAA0, BIDI_L }, // TAI VIET LETTER LOW FO + { 0xAAA1, BIDI_L }, // TAI VIET LETTER HIGH FO + { 0xAAA2, BIDI_L }, // TAI VIET LETTER LOW MO + { 0xAAA3, BIDI_L }, // TAI VIET LETTER HIGH MO + { 0xAAA4, BIDI_L }, // TAI VIET LETTER LOW YO + { 0xAAA5, BIDI_L }, // TAI VIET LETTER HIGH YO + { 0xAAA6, BIDI_L }, // TAI VIET LETTER LOW RO + { 0xAAA7, BIDI_L }, // TAI VIET LETTER HIGH RO + { 0xAAA8, BIDI_L }, // TAI VIET LETTER LOW LO + { 0xAAA9, BIDI_L }, // TAI VIET LETTER HIGH LO + { 0xAAAA, BIDI_L }, // TAI VIET LETTER LOW VO + { 0xAAAB, BIDI_L }, // TAI VIET LETTER HIGH VO + { 0xAAAC, BIDI_L }, // TAI VIET LETTER LOW HO + { 0xAAAD, BIDI_L }, // TAI VIET LETTER HIGH HO + { 0xAAAE, BIDI_L }, // TAI VIET LETTER LOW O + { 0xAAAF, BIDI_L }, // TAI VIET LETTER HIGH O + { 0xAAB0, BIDI_NSM }, // TAI VIET MAI KANG + { 0xAAB1, BIDI_L }, // TAI VIET VOWEL AA + { 0xAAB2, BIDI_NSM }, // TAI VIET VOWEL I + { 0xAAB3, BIDI_NSM }, // TAI VIET VOWEL UE + { 0xAAB4, BIDI_NSM }, // TAI VIET VOWEL U + { 0xAAB5, BIDI_L }, // TAI VIET VOWEL E + { 0xAAB6, BIDI_L }, // TAI VIET VOWEL O + { 0xAAB7, BIDI_NSM }, // TAI VIET MAI KHIT + { 0xAAB8, BIDI_NSM }, // TAI VIET VOWEL IA + { 0xAAB9, BIDI_L }, // TAI VIET VOWEL UEA + { 0xAABA, BIDI_L }, // TAI VIET VOWEL UA + { 0xAABB, BIDI_L }, // TAI VIET VOWEL AUE + { 0xAABC, BIDI_L }, // TAI VIET VOWEL AY + { 0xAABD, BIDI_L }, // TAI VIET VOWEL AN + { 0xAABE, BIDI_NSM }, // TAI VIET VOWEL AM + { 0xAABF, BIDI_NSM }, // TAI VIET TONE MAI EK + { 0xAAC0, BIDI_L }, // TAI VIET TONE MAI NUENG + { 0xAAC1, BIDI_NSM }, // TAI VIET TONE MAI THO + { 0xAAC2, BIDI_L }, // TAI VIET TONE MAI SONG + { 0xAADB, BIDI_L }, // TAI VIET SYMBOL KON + { 0xAADC, BIDI_L }, // TAI VIET SYMBOL NUENG + { 0xAADD, BIDI_L }, // TAI VIET SYMBOL SAM + { 0xAADE, BIDI_L }, // TAI VIET SYMBOL HO HOI + { 0xAADF, BIDI_L }, // TAI VIET SYMBOL KOI KOI + { 0xAAE0, BIDI_L }, // MEETEI MAYEK LETTER E + { 0xAAE1, BIDI_L }, // MEETEI MAYEK LETTER O + { 0xAAE2, BIDI_L }, // MEETEI MAYEK LETTER CHA + { 0xAAE3, BIDI_L }, // MEETEI MAYEK LETTER NYA + { 0xAAE4, BIDI_L }, // MEETEI MAYEK LETTER TTA + { 0xAAE5, BIDI_L }, // MEETEI MAYEK LETTER TTHA + { 0xAAE6, BIDI_L }, // MEETEI MAYEK LETTER DDA + { 0xAAE7, BIDI_L }, // MEETEI MAYEK LETTER DDHA + { 0xAAE8, BIDI_L }, // MEETEI MAYEK LETTER NNA + { 0xAAE9, BIDI_L }, // MEETEI MAYEK LETTER SHA + { 0xAAEA, BIDI_L }, // MEETEI MAYEK LETTER SSA + { 0xAAEB, BIDI_L }, // MEETEI MAYEK VOWEL SIGN II + { 0xAAEC, BIDI_NSM }, // MEETEI MAYEK VOWEL SIGN UU + { 0xAAED, BIDI_NSM }, // MEETEI MAYEK VOWEL SIGN AAI + { 0xAAEE, BIDI_L }, // MEETEI MAYEK VOWEL SIGN AU + { 0xAAEF, BIDI_L }, // MEETEI MAYEK VOWEL SIGN AAU + { 0xAAF0, BIDI_L }, // MEETEI MAYEK CHEIKHAN + { 0xAAF1, BIDI_L }, // MEETEI MAYEK AHANG KHUDAM + { 0xAAF2, BIDI_L }, // MEETEI MAYEK ANJI + { 0xAAF3, BIDI_L }, // MEETEI MAYEK SYLLABLE REPETITION MARK + { 0xAAF4, BIDI_L }, // MEETEI MAYEK WORD REPETITION MARK + { 0xAAF5, BIDI_L }, // MEETEI MAYEK VOWEL SIGN VISARGA + { 0xAAF6, BIDI_NSM }, // MEETEI MAYEK VIRAMA + { 0xAB01, BIDI_L }, // ETHIOPIC SYLLABLE TTHU + { 0xAB02, BIDI_L }, // ETHIOPIC SYLLABLE TTHI + { 0xAB03, BIDI_L }, // ETHIOPIC SYLLABLE TTHAA + { 0xAB04, BIDI_L }, // ETHIOPIC SYLLABLE TTHEE + { 0xAB05, BIDI_L }, // ETHIOPIC SYLLABLE TTHE + { 0xAB06, BIDI_L }, // ETHIOPIC SYLLABLE TTHO + { 0xAB09, BIDI_L }, // ETHIOPIC SYLLABLE DDHU + { 0xAB0A, BIDI_L }, // ETHIOPIC SYLLABLE DDHI + { 0xAB0B, BIDI_L }, // ETHIOPIC SYLLABLE DDHAA + { 0xAB0C, BIDI_L }, // ETHIOPIC SYLLABLE DDHEE + { 0xAB0D, BIDI_L }, // ETHIOPIC SYLLABLE DDHE + { 0xAB0E, BIDI_L }, // ETHIOPIC SYLLABLE DDHO + { 0xAB11, BIDI_L }, // ETHIOPIC SYLLABLE DZU + { 0xAB12, BIDI_L }, // ETHIOPIC SYLLABLE DZI + { 0xAB13, BIDI_L }, // ETHIOPIC SYLLABLE DZAA + { 0xAB14, BIDI_L }, // ETHIOPIC SYLLABLE DZEE + { 0xAB15, BIDI_L }, // ETHIOPIC SYLLABLE DZE + { 0xAB16, BIDI_L }, // ETHIOPIC SYLLABLE DZO + { 0xAB20, BIDI_L }, // ETHIOPIC SYLLABLE CCHHA + { 0xAB21, BIDI_L }, // ETHIOPIC SYLLABLE CCHHU + { 0xAB22, BIDI_L }, // ETHIOPIC SYLLABLE CCHHI + { 0xAB23, BIDI_L }, // ETHIOPIC SYLLABLE CCHHAA + { 0xAB24, BIDI_L }, // ETHIOPIC SYLLABLE CCHHEE + { 0xAB25, BIDI_L }, // ETHIOPIC SYLLABLE CCHHE + { 0xAB26, BIDI_L }, // ETHIOPIC SYLLABLE CCHHO + { 0xAB28, BIDI_L }, // ETHIOPIC SYLLABLE BBA + { 0xAB29, BIDI_L }, // ETHIOPIC SYLLABLE BBU + { 0xAB2A, BIDI_L }, // ETHIOPIC SYLLABLE BBI + { 0xAB2B, BIDI_L }, // ETHIOPIC SYLLABLE BBAA + { 0xAB2C, BIDI_L }, // ETHIOPIC SYLLABLE BBEE + { 0xAB2D, BIDI_L }, // ETHIOPIC SYLLABLE BBE + { 0xAB2E, BIDI_L }, // ETHIOPIC SYLLABLE BBO + { 0xAB30, BIDI_L }, // LATIN SMALL LETTER BARRED ALPHA + { 0xAB31, BIDI_L }, // LATIN SMALL LETTER A REVERSED-SCHWA + { 0xAB32, BIDI_L }, // LATIN SMALL LETTER BLACKLETTER E + { 0xAB33, BIDI_L }, // LATIN SMALL LETTER BARRED E + { 0xAB34, BIDI_L }, // LATIN SMALL LETTER E WITH FLOURISH + { 0xAB35, BIDI_L }, // LATIN SMALL LETTER LENIS F + { 0xAB36, BIDI_L }, // LATIN SMALL LETTER SCRIPT G WITH CROSSED-TAIL + { 0xAB37, BIDI_L }, // LATIN SMALL LETTER L WITH INVERTED LAZY S + { 0xAB38, BIDI_L }, // LATIN SMALL LETTER L WITH DOUBLE MIDDLE TILDE + { 0xAB39, BIDI_L }, // LATIN SMALL LETTER L WITH MIDDLE RING + { 0xAB3A, BIDI_L }, // LATIN SMALL LETTER M WITH CROSSED-TAIL + { 0xAB3B, BIDI_L }, // LATIN SMALL LETTER N WITH CROSSED-TAIL + { 0xAB3C, BIDI_L }, // LATIN SMALL LETTER ENG WITH CROSSED-TAIL + { 0xAB3D, BIDI_L }, // LATIN SMALL LETTER BLACKLETTER O + { 0xAB3E, BIDI_L }, // LATIN SMALL LETTER BLACKLETTER O WITH STROKE + { 0xAB3F, BIDI_L }, // LATIN SMALL LETTER OPEN O WITH STROKE + { 0xAB40, BIDI_L }, // LATIN SMALL LETTER INVERTED OE + { 0xAB41, BIDI_L }, // LATIN SMALL LETTER TURNED OE WITH STROKE + { 0xAB42, BIDI_L }, // LATIN SMALL LETTER TURNED OE WITH HORIZONTAL STROKE + { 0xAB43, BIDI_L }, // LATIN SMALL LETTER TURNED O OPEN-O + { 0xAB44, BIDI_L }, // LATIN SMALL LETTER TURNED O OPEN-O WITH STROKE + { 0xAB45, BIDI_L }, // LATIN SMALL LETTER STIRRUP R + { 0xAB46, BIDI_L }, // LATIN LETTER SMALL CAPITAL R WITH RIGHT LEG + { 0xAB47, BIDI_L }, // LATIN SMALL LETTER R WITHOUT HANDLE + { 0xAB48, BIDI_L }, // LATIN SMALL LETTER DOUBLE R + { 0xAB49, BIDI_L }, // LATIN SMALL LETTER R WITH CROSSED-TAIL + { 0xAB4A, BIDI_L }, // LATIN SMALL LETTER DOUBLE R WITH CROSSED-TAIL + { 0xAB4B, BIDI_L }, // LATIN SMALL LETTER SCRIPT R + { 0xAB4C, BIDI_L }, // LATIN SMALL LETTER SCRIPT R WITH RING + { 0xAB4D, BIDI_L }, // LATIN SMALL LETTER BASELINE ESH + { 0xAB4E, BIDI_L }, // LATIN SMALL LETTER U WITH SHORT RIGHT LEG + { 0xAB4F, BIDI_L }, // LATIN SMALL LETTER U BAR WITH SHORT RIGHT LEG + { 0xAB50, BIDI_L }, // LATIN SMALL LETTER UI + { 0xAB51, BIDI_L }, // LATIN SMALL LETTER TURNED UI + { 0xAB52, BIDI_L }, // LATIN SMALL LETTER U WITH LEFT HOOK + { 0xAB53, BIDI_L }, // LATIN SMALL LETTER CHI + { 0xAB54, BIDI_L }, // LATIN SMALL LETTER CHI WITH LOW RIGHT RING + { 0xAB55, BIDI_L }, // LATIN SMALL LETTER CHI WITH LOW LEFT SERIF + { 0xAB56, BIDI_L }, // LATIN SMALL LETTER X WITH LOW RIGHT RING + { 0xAB57, BIDI_L }, // LATIN SMALL LETTER X WITH LONG LEFT LEG + { 0xAB58, BIDI_L }, // LATIN SMALL LETTER X WITH LONG LEFT LEG AND LOW RIGHT RING + { 0xAB59, BIDI_L }, // LATIN SMALL LETTER X WITH LONG LEFT LEG WITH SERIF + { 0xAB5A, BIDI_L }, // LATIN SMALL LETTER Y WITH SHORT RIGHT LEG + { 0xAB5B, BIDI_L }, // MODIFIER BREVE WITH INVERTED BREVE + { 0xAB5C, BIDI_L }, // MODIFIER LETTER SMALL HENG + { 0xAB5D, BIDI_L }, // MODIFIER LETTER SMALL L WITH INVERTED LAZY S + { 0xAB5E, BIDI_L }, // MODIFIER LETTER SMALL L WITH MIDDLE TILDE + { 0xAB5F, BIDI_L }, // MODIFIER LETTER SMALL U WITH LEFT HOOK + { 0xAB60, BIDI_L }, // LATIN SMALL LETTER SAKHA YAT + { 0xAB61, BIDI_L }, // LATIN SMALL LETTER IOTIFIED E + { 0xAB62, BIDI_L }, // LATIN SMALL LETTER OPEN OE + { 0xAB63, BIDI_L }, // LATIN SMALL LETTER UO + { 0xAB64, BIDI_L }, // LATIN SMALL LETTER INVERTED ALPHA + { 0xAB65, BIDI_L }, // GREEK LETTER SMALL CAPITAL OMEGA + { 0xAB70, BIDI_L }, // CHEROKEE SMALL LETTER A + { 0xAB71, BIDI_L }, // CHEROKEE SMALL LETTER E + { 0xAB72, BIDI_L }, // CHEROKEE SMALL LETTER I + { 0xAB73, BIDI_L }, // CHEROKEE SMALL LETTER O + { 0xAB74, BIDI_L }, // CHEROKEE SMALL LETTER U + { 0xAB75, BIDI_L }, // CHEROKEE SMALL LETTER V + { 0xAB76, BIDI_L }, // CHEROKEE SMALL LETTER GA + { 0xAB77, BIDI_L }, // CHEROKEE SMALL LETTER KA + { 0xAB78, BIDI_L }, // CHEROKEE SMALL LETTER GE + { 0xAB79, BIDI_L }, // CHEROKEE SMALL LETTER GI + { 0xAB7A, BIDI_L }, // CHEROKEE SMALL LETTER GO + { 0xAB7B, BIDI_L }, // CHEROKEE SMALL LETTER GU + { 0xAB7C, BIDI_L }, // CHEROKEE SMALL LETTER GV + { 0xAB7D, BIDI_L }, // CHEROKEE SMALL LETTER HA + { 0xAB7E, BIDI_L }, // CHEROKEE SMALL LETTER HE + { 0xAB7F, BIDI_L }, // CHEROKEE SMALL LETTER HI + { 0xAB80, BIDI_L }, // CHEROKEE SMALL LETTER HO + { 0xAB81, BIDI_L }, // CHEROKEE SMALL LETTER HU + { 0xAB82, BIDI_L }, // CHEROKEE SMALL LETTER HV + { 0xAB83, BIDI_L }, // CHEROKEE SMALL LETTER LA + { 0xAB84, BIDI_L }, // CHEROKEE SMALL LETTER LE + { 0xAB85, BIDI_L }, // CHEROKEE SMALL LETTER LI + { 0xAB86, BIDI_L }, // CHEROKEE SMALL LETTER LO + { 0xAB87, BIDI_L }, // CHEROKEE SMALL LETTER LU + { 0xAB88, BIDI_L }, // CHEROKEE SMALL LETTER LV + { 0xAB89, BIDI_L }, // CHEROKEE SMALL LETTER MA + { 0xAB8A, BIDI_L }, // CHEROKEE SMALL LETTER ME + { 0xAB8B, BIDI_L }, // CHEROKEE SMALL LETTER MI + { 0xAB8C, BIDI_L }, // CHEROKEE SMALL LETTER MO + { 0xAB8D, BIDI_L }, // CHEROKEE SMALL LETTER MU + { 0xAB8E, BIDI_L }, // CHEROKEE SMALL LETTER NA + { 0xAB8F, BIDI_L }, // CHEROKEE SMALL LETTER HNA + { 0xAB90, BIDI_L }, // CHEROKEE SMALL LETTER NAH + { 0xAB91, BIDI_L }, // CHEROKEE SMALL LETTER NE + { 0xAB92, BIDI_L }, // CHEROKEE SMALL LETTER NI + { 0xAB93, BIDI_L }, // CHEROKEE SMALL LETTER NO + { 0xAB94, BIDI_L }, // CHEROKEE SMALL LETTER NU + { 0xAB95, BIDI_L }, // CHEROKEE SMALL LETTER NV + { 0xAB96, BIDI_L }, // CHEROKEE SMALL LETTER QUA + { 0xAB97, BIDI_L }, // CHEROKEE SMALL LETTER QUE + { 0xAB98, BIDI_L }, // CHEROKEE SMALL LETTER QUI + { 0xAB99, BIDI_L }, // CHEROKEE SMALL LETTER QUO + { 0xAB9A, BIDI_L }, // CHEROKEE SMALL LETTER QUU + { 0xAB9B, BIDI_L }, // CHEROKEE SMALL LETTER QUV + { 0xAB9C, BIDI_L }, // CHEROKEE SMALL LETTER SA + { 0xAB9D, BIDI_L }, // CHEROKEE SMALL LETTER S + { 0xAB9E, BIDI_L }, // CHEROKEE SMALL LETTER SE + { 0xAB9F, BIDI_L }, // CHEROKEE SMALL LETTER SI + { 0xABA0, BIDI_L }, // CHEROKEE SMALL LETTER SO + { 0xABA1, BIDI_L }, // CHEROKEE SMALL LETTER SU + { 0xABA2, BIDI_L }, // CHEROKEE SMALL LETTER SV + { 0xABA3, BIDI_L }, // CHEROKEE SMALL LETTER DA + { 0xABA4, BIDI_L }, // CHEROKEE SMALL LETTER TA + { 0xABA5, BIDI_L }, // CHEROKEE SMALL LETTER DE + { 0xABA6, BIDI_L }, // CHEROKEE SMALL LETTER TE + { 0xABA7, BIDI_L }, // CHEROKEE SMALL LETTER DI + { 0xABA8, BIDI_L }, // CHEROKEE SMALL LETTER TI + { 0xABA9, BIDI_L }, // CHEROKEE SMALL LETTER DO + { 0xABAA, BIDI_L }, // CHEROKEE SMALL LETTER DU + { 0xABAB, BIDI_L }, // CHEROKEE SMALL LETTER DV + { 0xABAC, BIDI_L }, // CHEROKEE SMALL LETTER DLA + { 0xABAD, BIDI_L }, // CHEROKEE SMALL LETTER TLA + { 0xABAE, BIDI_L }, // CHEROKEE SMALL LETTER TLE + { 0xABAF, BIDI_L }, // CHEROKEE SMALL LETTER TLI + { 0xABB0, BIDI_L }, // CHEROKEE SMALL LETTER TLO + { 0xABB1, BIDI_L }, // CHEROKEE SMALL LETTER TLU + { 0xABB2, BIDI_L }, // CHEROKEE SMALL LETTER TLV + { 0xABB3, BIDI_L }, // CHEROKEE SMALL LETTER TSA + { 0xABB4, BIDI_L }, // CHEROKEE SMALL LETTER TSE + { 0xABB5, BIDI_L }, // CHEROKEE SMALL LETTER TSI + { 0xABB6, BIDI_L }, // CHEROKEE SMALL LETTER TSO + { 0xABB7, BIDI_L }, // CHEROKEE SMALL LETTER TSU + { 0xABB8, BIDI_L }, // CHEROKEE SMALL LETTER TSV + { 0xABB9, BIDI_L }, // CHEROKEE SMALL LETTER WA + { 0xABBA, BIDI_L }, // CHEROKEE SMALL LETTER WE + { 0xABBB, BIDI_L }, // CHEROKEE SMALL LETTER WI + { 0xABBC, BIDI_L }, // CHEROKEE SMALL LETTER WO + { 0xABBD, BIDI_L }, // CHEROKEE SMALL LETTER WU + { 0xABBE, BIDI_L }, // CHEROKEE SMALL LETTER WV + { 0xABBF, BIDI_L }, // CHEROKEE SMALL LETTER YA + { 0xABC0, BIDI_L }, // MEETEI MAYEK LETTER KOK + { 0xABC1, BIDI_L }, // MEETEI MAYEK LETTER SAM + { 0xABC2, BIDI_L }, // MEETEI MAYEK LETTER LAI + { 0xABC3, BIDI_L }, // MEETEI MAYEK LETTER MIT + { 0xABC4, BIDI_L }, // MEETEI MAYEK LETTER PA + { 0xABC5, BIDI_L }, // MEETEI MAYEK LETTER NA + { 0xABC6, BIDI_L }, // MEETEI MAYEK LETTER CHIL + { 0xABC7, BIDI_L }, // MEETEI MAYEK LETTER TIL + { 0xABC8, BIDI_L }, // MEETEI MAYEK LETTER KHOU + { 0xABC9, BIDI_L }, // MEETEI MAYEK LETTER NGOU + { 0xABCA, BIDI_L }, // MEETEI MAYEK LETTER THOU + { 0xABCB, BIDI_L }, // MEETEI MAYEK LETTER WAI + { 0xABCC, BIDI_L }, // MEETEI MAYEK LETTER YANG + { 0xABCD, BIDI_L }, // MEETEI MAYEK LETTER HUK + { 0xABCE, BIDI_L }, // MEETEI MAYEK LETTER UN + { 0xABCF, BIDI_L }, // MEETEI MAYEK LETTER I + { 0xABD0, BIDI_L }, // MEETEI MAYEK LETTER PHAM + { 0xABD1, BIDI_L }, // MEETEI MAYEK LETTER ATIYA + { 0xABD2, BIDI_L }, // MEETEI MAYEK LETTER GOK + { 0xABD3, BIDI_L }, // MEETEI MAYEK LETTER JHAM + { 0xABD4, BIDI_L }, // MEETEI MAYEK LETTER RAI + { 0xABD5, BIDI_L }, // MEETEI MAYEK LETTER BA + { 0xABD6, BIDI_L }, // MEETEI MAYEK LETTER JIL + { 0xABD7, BIDI_L }, // MEETEI MAYEK LETTER DIL + { 0xABD8, BIDI_L }, // MEETEI MAYEK LETTER GHOU + { 0xABD9, BIDI_L }, // MEETEI MAYEK LETTER DHOU + { 0xABDA, BIDI_L }, // MEETEI MAYEK LETTER BHAM + { 0xABDB, BIDI_L }, // MEETEI MAYEK LETTER KOK LONSUM + { 0xABDC, BIDI_L }, // MEETEI MAYEK LETTER LAI LONSUM + { 0xABDD, BIDI_L }, // MEETEI MAYEK LETTER MIT LONSUM + { 0xABDE, BIDI_L }, // MEETEI MAYEK LETTER PA LONSUM + { 0xABDF, BIDI_L }, // MEETEI MAYEK LETTER NA LONSUM + { 0xABE0, BIDI_L }, // MEETEI MAYEK LETTER TIL LONSUM + { 0xABE1, BIDI_L }, // MEETEI MAYEK LETTER NGOU LONSUM + { 0xABE2, BIDI_L }, // MEETEI MAYEK LETTER I LONSUM + { 0xABE3, BIDI_L }, // MEETEI MAYEK VOWEL SIGN ONAP + { 0xABE4, BIDI_L }, // MEETEI MAYEK VOWEL SIGN INAP + { 0xABE5, BIDI_NSM }, // MEETEI MAYEK VOWEL SIGN ANAP + { 0xABE6, BIDI_L }, // MEETEI MAYEK VOWEL SIGN YENAP + { 0xABE7, BIDI_L }, // MEETEI MAYEK VOWEL SIGN SOUNAP + { 0xABE8, BIDI_NSM }, // MEETEI MAYEK VOWEL SIGN UNAP + { 0xABE9, BIDI_L }, // MEETEI MAYEK VOWEL SIGN CHEINAP + { 0xABEA, BIDI_L }, // MEETEI MAYEK VOWEL SIGN NUNG + { 0xABEB, BIDI_L }, // MEETEI MAYEK CHEIKHEI + { 0xABEC, BIDI_L }, // MEETEI MAYEK LUM IYEK + { 0xABED, BIDI_NSM }, // MEETEI MAYEK APUN IYEK + { 0xABF0, BIDI_L }, // MEETEI MAYEK DIGIT ZERO + { 0xABF1, BIDI_L }, // MEETEI MAYEK DIGIT ONE + { 0xABF2, BIDI_L }, // MEETEI MAYEK DIGIT TWO + { 0xABF3, BIDI_L }, // MEETEI MAYEK DIGIT THREE + { 0xABF4, BIDI_L }, // MEETEI MAYEK DIGIT FOUR + { 0xABF5, BIDI_L }, // MEETEI MAYEK DIGIT FIVE + { 0xABF6, BIDI_L }, // MEETEI MAYEK DIGIT SIX + { 0xABF7, BIDI_L }, // MEETEI MAYEK DIGIT SEVEN + { 0xABF8, BIDI_L }, // MEETEI MAYEK DIGIT EIGHT + { 0xABF9, BIDI_L }, // MEETEI MAYEK DIGIT NINE + //{ 0xAC00, BIDI_L }, // + //{ 0xD7A3, BIDI_L }, // + +#endif +#if (GUI_BIDI_SUPPORT_RANGE_D == 1) + + { 0xD7B0, BIDI_L }, // HANGUL JUNGSEONG O-YEO + { 0xD7B1, BIDI_L }, // HANGUL JUNGSEONG O-O-I + { 0xD7B2, BIDI_L }, // HANGUL JUNGSEONG YO-A + { 0xD7B3, BIDI_L }, // HANGUL JUNGSEONG YO-AE + { 0xD7B4, BIDI_L }, // HANGUL JUNGSEONG YO-EO + { 0xD7B5, BIDI_L }, // HANGUL JUNGSEONG U-YEO + { 0xD7B6, BIDI_L }, // HANGUL JUNGSEONG U-I-I + { 0xD7B7, BIDI_L }, // HANGUL JUNGSEONG YU-AE + { 0xD7B8, BIDI_L }, // HANGUL JUNGSEONG YU-O + { 0xD7B9, BIDI_L }, // HANGUL JUNGSEONG EU-A + { 0xD7BA, BIDI_L }, // HANGUL JUNGSEONG EU-EO + { 0xD7BB, BIDI_L }, // HANGUL JUNGSEONG EU-E + { 0xD7BC, BIDI_L }, // HANGUL JUNGSEONG EU-O + { 0xD7BD, BIDI_L }, // HANGUL JUNGSEONG I-YA-O + { 0xD7BE, BIDI_L }, // HANGUL JUNGSEONG I-YAE + { 0xD7BF, BIDI_L }, // HANGUL JUNGSEONG I-YEO + { 0xD7C0, BIDI_L }, // HANGUL JUNGSEONG I-YE + { 0xD7C1, BIDI_L }, // HANGUL JUNGSEONG I-O-I + { 0xD7C2, BIDI_L }, // HANGUL JUNGSEONG I-YO + { 0xD7C3, BIDI_L }, // HANGUL JUNGSEONG I-YU + { 0xD7C4, BIDI_L }, // HANGUL JUNGSEONG I-I + { 0xD7C5, BIDI_L }, // HANGUL JUNGSEONG ARAEA-A + { 0xD7C6, BIDI_L }, // HANGUL JUNGSEONG ARAEA-E + { 0xD7CB, BIDI_L }, // HANGUL JONGSEONG NIEUN-RIEUL + { 0xD7CC, BIDI_L }, // HANGUL JONGSEONG NIEUN-CHIEUCH + { 0xD7CD, BIDI_L }, // HANGUL JONGSEONG SSANGTIKEUT + { 0xD7CE, BIDI_L }, // HANGUL JONGSEONG SSANGTIKEUT-PIEUP + { 0xD7CF, BIDI_L }, // HANGUL JONGSEONG TIKEUT-PIEUP + { 0xD7D0, BIDI_L }, // HANGUL JONGSEONG TIKEUT-SIOS + { 0xD7D1, BIDI_L }, // HANGUL JONGSEONG TIKEUT-SIOS-KIYEOK + { 0xD7D2, BIDI_L }, // HANGUL JONGSEONG TIKEUT-CIEUC + { 0xD7D3, BIDI_L }, // HANGUL JONGSEONG TIKEUT-CHIEUCH + { 0xD7D4, BIDI_L }, // HANGUL JONGSEONG TIKEUT-THIEUTH + { 0xD7D5, BIDI_L }, // HANGUL JONGSEONG RIEUL-SSANGKIYEOK + { 0xD7D6, BIDI_L }, // HANGUL JONGSEONG RIEUL-KIYEOK-HIEUH + { 0xD7D7, BIDI_L }, // HANGUL JONGSEONG SSANGRIEUL-KHIEUKH + { 0xD7D8, BIDI_L }, // HANGUL JONGSEONG RIEUL-MIEUM-HIEUH + { 0xD7D9, BIDI_L }, // HANGUL JONGSEONG RIEUL-PIEUP-TIKEUT + { 0xD7DA, BIDI_L }, // HANGUL JONGSEONG RIEUL-PIEUP-PHIEUPH + { 0xD7DB, BIDI_L }, // HANGUL JONGSEONG RIEUL-YESIEUNG + { 0xD7DC, BIDI_L }, // HANGUL JONGSEONG RIEUL-YEORINHIEUH-HIEUH + { 0xD7DD, BIDI_L }, // HANGUL JONGSEONG KAPYEOUNRIEUL + { 0xD7DE, BIDI_L }, // HANGUL JONGSEONG MIEUM-NIEUN + { 0xD7DF, BIDI_L }, // HANGUL JONGSEONG MIEUM-SSANGNIEUN + { 0xD7E0, BIDI_L }, // HANGUL JONGSEONG SSANGMIEUM + { 0xD7E1, BIDI_L }, // HANGUL JONGSEONG MIEUM-PIEUP-SIOS + { 0xD7E2, BIDI_L }, // HANGUL JONGSEONG MIEUM-CIEUC + { 0xD7E3, BIDI_L }, // HANGUL JONGSEONG PIEUP-TIKEUT + { 0xD7E4, BIDI_L }, // HANGUL JONGSEONG PIEUP-RIEUL-PHIEUPH + { 0xD7E5, BIDI_L }, // HANGUL JONGSEONG PIEUP-MIEUM + { 0xD7E6, BIDI_L }, // HANGUL JONGSEONG SSANGPIEUP + { 0xD7E7, BIDI_L }, // HANGUL JONGSEONG PIEUP-SIOS-TIKEUT + { 0xD7E8, BIDI_L }, // HANGUL JONGSEONG PIEUP-CIEUC + { 0xD7E9, BIDI_L }, // HANGUL JONGSEONG PIEUP-CHIEUCH + { 0xD7EA, BIDI_L }, // HANGUL JONGSEONG SIOS-MIEUM + { 0xD7EB, BIDI_L }, // HANGUL JONGSEONG SIOS-KAPYEOUNPIEUP + { 0xD7EC, BIDI_L }, // HANGUL JONGSEONG SSANGSIOS-KIYEOK + { 0xD7ED, BIDI_L }, // HANGUL JONGSEONG SSANGSIOS-TIKEUT + { 0xD7EE, BIDI_L }, // HANGUL JONGSEONG SIOS-PANSIOS + { 0xD7EF, BIDI_L }, // HANGUL JONGSEONG SIOS-CIEUC + { 0xD7F0, BIDI_L }, // HANGUL JONGSEONG SIOS-CHIEUCH + { 0xD7F1, BIDI_L }, // HANGUL JONGSEONG SIOS-THIEUTH + { 0xD7F2, BIDI_L }, // HANGUL JONGSEONG SIOS-HIEUH + { 0xD7F3, BIDI_L }, // HANGUL JONGSEONG PANSIOS-PIEUP + { 0xD7F4, BIDI_L }, // HANGUL JONGSEONG PANSIOS-KAPYEOUNPIEUP + { 0xD7F5, BIDI_L }, // HANGUL JONGSEONG YESIEUNG-MIEUM + { 0xD7F6, BIDI_L }, // HANGUL JONGSEONG YESIEUNG-HIEUH + { 0xD7F7, BIDI_L }, // HANGUL JONGSEONG CIEUC-PIEUP + { 0xD7F8, BIDI_L }, // HANGUL JONGSEONG CIEUC-SSANGPIEUP + { 0xD7F9, BIDI_L }, // HANGUL JONGSEONG SSANGCIEUC + { 0xD7FA, BIDI_L }, // HANGUL JONGSEONG PHIEUPH-SIOS + { 0xD7FB, BIDI_L }, // HANGUL JONGSEONG PHIEUPH-THIEUTH + //{ 0xD800, BIDI_L }, // + //{ 0xDB7F, BIDI_L }, // + //{ 0xDB80, BIDI_L }, // + //{ 0xDBFF, BIDI_L }, // + //{ 0xDC00, BIDI_L }, // + //{ 0xDFFF, BIDI_L }, // + //{ 0xE000, BIDI_L }, // + //{ 0xF8FF, BIDI_L }, // + +#endif +#if (GUI_BIDI_SUPPORT_RANGE_F == 1) + + { 0xF900, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F900 + { 0xF901, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F901 + { 0xF902, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F902 + { 0xF903, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F903 + { 0xF904, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F904 + { 0xF905, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F905 + { 0xF906, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F906 + { 0xF907, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F907 + { 0xF908, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F908 + { 0xF909, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F909 + { 0xF90A, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F90A + { 0xF90B, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F90B + { 0xF90C, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F90C + { 0xF90D, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F90D + { 0xF90E, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F90E + { 0xF90F, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F90F + { 0xF910, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F910 + { 0xF911, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F911 + { 0xF912, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F912 + { 0xF913, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F913 + { 0xF914, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F914 + { 0xF915, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F915 + { 0xF916, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F916 + { 0xF917, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F917 + { 0xF918, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F918 + { 0xF919, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F919 + { 0xF91A, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F91A + { 0xF91B, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F91B + { 0xF91C, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F91C + { 0xF91D, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F91D + { 0xF91E, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F91E + { 0xF91F, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F91F + { 0xF920, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F920 + { 0xF921, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F921 + { 0xF922, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F922 + { 0xF923, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F923 + { 0xF924, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F924 + { 0xF925, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F925 + { 0xF926, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F926 + { 0xF927, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F927 + { 0xF928, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F928 + { 0xF929, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F929 + { 0xF92A, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F92A + { 0xF92B, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F92B + { 0xF92C, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F92C + { 0xF92D, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F92D + { 0xF92E, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F92E + { 0xF92F, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F92F + { 0xF930, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F930 + { 0xF931, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F931 + { 0xF932, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F932 + { 0xF933, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F933 + { 0xF934, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F934 + { 0xF935, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F935 + { 0xF936, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F936 + { 0xF937, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F937 + { 0xF938, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F938 + { 0xF939, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F939 + { 0xF93A, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F93A + { 0xF93B, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F93B + { 0xF93C, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F93C + { 0xF93D, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F93D + { 0xF93E, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F93E + { 0xF93F, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F93F + { 0xF940, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F940 + { 0xF941, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F941 + { 0xF942, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F942 + { 0xF943, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F943 + { 0xF944, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F944 + { 0xF945, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F945 + { 0xF946, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F946 + { 0xF947, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F947 + { 0xF948, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F948 + { 0xF949, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F949 + { 0xF94A, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F94A + { 0xF94B, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F94B + { 0xF94C, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F94C + { 0xF94D, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F94D + { 0xF94E, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F94E + { 0xF94F, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F94F + { 0xF950, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F950 + { 0xF951, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F951 + { 0xF952, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F952 + { 0xF953, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F953 + { 0xF954, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F954 + { 0xF955, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F955 + { 0xF956, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F956 + { 0xF957, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F957 + { 0xF958, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F958 + { 0xF959, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F959 + { 0xF95A, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F95A + { 0xF95B, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F95B + { 0xF95C, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F95C + { 0xF95D, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F95D + { 0xF95E, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F95E + { 0xF95F, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F95F + { 0xF960, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F960 + { 0xF961, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F961 + { 0xF962, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F962 + { 0xF963, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F963 + { 0xF964, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F964 + { 0xF965, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F965 + { 0xF966, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F966 + { 0xF967, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F967 + { 0xF968, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F968 + { 0xF969, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F969 + { 0xF96A, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F96A + { 0xF96B, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F96B + { 0xF96C, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F96C + { 0xF96D, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F96D + { 0xF96E, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F96E + { 0xF96F, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F96F + { 0xF970, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F970 + { 0xF971, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F971 + { 0xF972, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F972 + { 0xF973, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F973 + { 0xF974, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F974 + { 0xF975, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F975 + { 0xF976, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F976 + { 0xF977, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F977 + { 0xF978, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F978 + { 0xF979, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F979 + { 0xF97A, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F97A + { 0xF97B, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F97B + { 0xF97C, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F97C + { 0xF97D, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F97D + { 0xF97E, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F97E + { 0xF97F, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F97F + { 0xF980, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F980 + { 0xF981, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F981 + { 0xF982, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F982 + { 0xF983, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F983 + { 0xF984, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F984 + { 0xF985, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F985 + { 0xF986, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F986 + { 0xF987, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F987 + { 0xF988, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F988 + { 0xF989, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F989 + { 0xF98A, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F98A + { 0xF98B, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F98B + { 0xF98C, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F98C + { 0xF98D, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F98D + { 0xF98E, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F98E + { 0xF98F, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F98F + { 0xF990, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F990 + { 0xF991, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F991 + { 0xF992, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F992 + { 0xF993, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F993 + { 0xF994, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F994 + { 0xF995, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F995 + { 0xF996, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F996 + { 0xF997, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F997 + { 0xF998, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F998 + { 0xF999, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F999 + { 0xF99A, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F99A + { 0xF99B, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F99B + { 0xF99C, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F99C + { 0xF99D, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F99D + { 0xF99E, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F99E + { 0xF99F, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F99F + { 0xF9A0, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9A0 + { 0xF9A1, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9A1 + { 0xF9A2, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9A2 + { 0xF9A3, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9A3 + { 0xF9A4, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9A4 + { 0xF9A5, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9A5 + { 0xF9A6, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9A6 + { 0xF9A7, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9A7 + { 0xF9A8, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9A8 + { 0xF9A9, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9A9 + { 0xF9AA, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9AA + { 0xF9AB, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9AB + { 0xF9AC, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9AC + { 0xF9AD, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9AD + { 0xF9AE, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9AE + { 0xF9AF, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9AF + { 0xF9B0, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9B0 + { 0xF9B1, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9B1 + { 0xF9B2, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9B2 + { 0xF9B3, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9B3 + { 0xF9B4, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9B4 + { 0xF9B5, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9B5 + { 0xF9B6, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9B6 + { 0xF9B7, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9B7 + { 0xF9B8, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9B8 + { 0xF9B9, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9B9 + { 0xF9BA, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9BA + { 0xF9BB, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9BB + { 0xF9BC, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9BC + { 0xF9BD, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9BD + { 0xF9BE, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9BE + { 0xF9BF, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9BF + { 0xF9C0, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9C0 + { 0xF9C1, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9C1 + { 0xF9C2, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9C2 + { 0xF9C3, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9C3 + { 0xF9C4, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9C4 + { 0xF9C5, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9C5 + { 0xF9C6, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9C6 + { 0xF9C7, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9C7 + { 0xF9C8, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9C8 + { 0xF9C9, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9C9 + { 0xF9CA, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9CA + { 0xF9CB, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9CB + { 0xF9CC, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9CC + { 0xF9CD, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9CD + { 0xF9CE, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9CE + { 0xF9CF, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9CF + { 0xF9D0, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9D0 + { 0xF9D1, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9D1 + { 0xF9D2, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9D2 + { 0xF9D3, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9D3 + { 0xF9D4, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9D4 + { 0xF9D5, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9D5 + { 0xF9D6, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9D6 + { 0xF9D7, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9D7 + { 0xF9D8, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9D8 + { 0xF9D9, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9D9 + { 0xF9DA, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9DA + { 0xF9DB, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9DB + { 0xF9DC, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9DC + { 0xF9DD, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9DD + { 0xF9DE, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9DE + { 0xF9DF, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9DF + { 0xF9E0, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9E0 + { 0xF9E1, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9E1 + { 0xF9E2, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9E2 + { 0xF9E3, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9E3 + { 0xF9E4, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9E4 + { 0xF9E5, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9E5 + { 0xF9E6, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9E6 + { 0xF9E7, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9E7 + { 0xF9E8, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9E8 + { 0xF9E9, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9E9 + { 0xF9EA, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9EA + { 0xF9EB, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9EB + { 0xF9EC, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9EC + { 0xF9ED, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9ED + { 0xF9EE, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9EE + { 0xF9EF, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9EF + { 0xF9F0, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9F0 + { 0xF9F1, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9F1 + { 0xF9F2, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9F2 + { 0xF9F3, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9F3 + { 0xF9F4, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9F4 + { 0xF9F5, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9F5 + { 0xF9F6, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9F6 + { 0xF9F7, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9F7 + { 0xF9F8, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9F8 + { 0xF9F9, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9F9 + { 0xF9FA, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9FA + { 0xF9FB, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9FB + { 0xF9FC, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9FC + { 0xF9FD, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9FD + { 0xF9FE, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9FE + { 0xF9FF, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-F9FF + { 0xFA00, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA00 + { 0xFA01, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA01 + { 0xFA02, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA02 + { 0xFA03, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA03 + { 0xFA04, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA04 + { 0xFA05, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA05 + { 0xFA06, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA06 + { 0xFA07, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA07 + { 0xFA08, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA08 + { 0xFA09, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA09 + { 0xFA0A, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA0A + { 0xFA0B, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA0B + { 0xFA0C, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA0C + { 0xFA0D, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA0D + { 0xFA0E, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA0E + { 0xFA0F, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA0F + { 0xFA10, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA10 + { 0xFA11, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA11 + { 0xFA12, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA12 + { 0xFA13, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA13 + { 0xFA14, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA14 + { 0xFA15, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA15 + { 0xFA16, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA16 + { 0xFA17, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA17 + { 0xFA18, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA18 + { 0xFA19, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA19 + { 0xFA1A, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA1A + { 0xFA1B, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA1B + { 0xFA1C, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA1C + { 0xFA1D, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA1D + { 0xFA1E, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA1E + { 0xFA1F, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA1F + { 0xFA20, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA20 + { 0xFA21, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA21 + { 0xFA22, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA22 + { 0xFA23, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA23 + { 0xFA24, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA24 + { 0xFA25, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA25 + { 0xFA26, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA26 + { 0xFA27, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA27 + { 0xFA28, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA28 + { 0xFA29, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA29 + { 0xFA2A, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA2A + { 0xFA2B, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA2B + { 0xFA2C, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA2C + { 0xFA2D, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA2D + { 0xFA2E, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA2E + { 0xFA2F, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA2F + { 0xFA30, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA30 + { 0xFA31, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA31 + { 0xFA32, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA32 + { 0xFA33, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA33 + { 0xFA34, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA34 + { 0xFA35, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA35 + { 0xFA36, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA36 + { 0xFA37, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA37 + { 0xFA38, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA38 + { 0xFA39, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA39 + { 0xFA3A, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA3A + { 0xFA3B, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA3B + { 0xFA3C, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA3C + { 0xFA3D, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA3D + { 0xFA3E, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA3E + { 0xFA3F, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA3F + { 0xFA40, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA40 + { 0xFA41, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA41 + { 0xFA42, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA42 + { 0xFA43, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA43 + { 0xFA44, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA44 + { 0xFA45, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA45 + { 0xFA46, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA46 + { 0xFA47, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA47 + { 0xFA48, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA48 + { 0xFA49, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA49 + { 0xFA4A, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA4A + { 0xFA4B, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA4B + { 0xFA4C, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA4C + { 0xFA4D, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA4D + { 0xFA4E, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA4E + { 0xFA4F, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA4F + { 0xFA50, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA50 + { 0xFA51, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA51 + { 0xFA52, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA52 + { 0xFA53, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA53 + { 0xFA54, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA54 + { 0xFA55, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA55 + { 0xFA56, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA56 + { 0xFA57, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA57 + { 0xFA58, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA58 + { 0xFA59, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA59 + { 0xFA5A, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA5A + { 0xFA5B, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA5B + { 0xFA5C, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA5C + { 0xFA5D, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA5D + { 0xFA5E, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA5E + { 0xFA5F, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA5F + { 0xFA60, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA60 + { 0xFA61, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA61 + { 0xFA62, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA62 + { 0xFA63, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA63 + { 0xFA64, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA64 + { 0xFA65, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA65 + { 0xFA66, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA66 + { 0xFA67, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA67 + { 0xFA68, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA68 + { 0xFA69, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA69 + { 0xFA6A, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA6A + { 0xFA6B, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA6B + { 0xFA6C, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA6C + { 0xFA6D, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA6D + { 0xFA70, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA70 + { 0xFA71, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA71 + { 0xFA72, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA72 + { 0xFA73, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA73 + { 0xFA74, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA74 + { 0xFA75, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA75 + { 0xFA76, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA76 + { 0xFA77, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA77 + { 0xFA78, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA78 + { 0xFA79, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA79 + { 0xFA7A, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA7A + { 0xFA7B, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA7B + { 0xFA7C, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA7C + { 0xFA7D, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA7D + { 0xFA7E, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA7E + { 0xFA7F, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA7F + { 0xFA80, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA80 + { 0xFA81, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA81 + { 0xFA82, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA82 + { 0xFA83, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA83 + { 0xFA84, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA84 + { 0xFA85, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA85 + { 0xFA86, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA86 + { 0xFA87, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA87 + { 0xFA88, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA88 + { 0xFA89, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA89 + { 0xFA8A, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA8A + { 0xFA8B, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA8B + { 0xFA8C, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA8C + { 0xFA8D, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA8D + { 0xFA8E, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA8E + { 0xFA8F, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA8F + { 0xFA90, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA90 + { 0xFA91, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA91 + { 0xFA92, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA92 + { 0xFA93, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA93 + { 0xFA94, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA94 + { 0xFA95, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA95 + { 0xFA96, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA96 + { 0xFA97, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA97 + { 0xFA98, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA98 + { 0xFA99, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA99 + { 0xFA9A, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA9A + { 0xFA9B, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA9B + { 0xFA9C, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA9C + { 0xFA9D, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA9D + { 0xFA9E, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA9E + { 0xFA9F, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FA9F + { 0xFAA0, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FAA0 + { 0xFAA1, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FAA1 + { 0xFAA2, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FAA2 + { 0xFAA3, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FAA3 + { 0xFAA4, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FAA4 + { 0xFAA5, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FAA5 + { 0xFAA6, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FAA6 + { 0xFAA7, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FAA7 + { 0xFAA8, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FAA8 + { 0xFAA9, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FAA9 + { 0xFAAA, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FAAA + { 0xFAAB, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FAAB + { 0xFAAC, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FAAC + { 0xFAAD, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FAAD + { 0xFAAE, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FAAE + { 0xFAAF, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FAAF + { 0xFAB0, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FAB0 + { 0xFAB1, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FAB1 + { 0xFAB2, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FAB2 + { 0xFAB3, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FAB3 + { 0xFAB4, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FAB4 + { 0xFAB5, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FAB5 + { 0xFAB6, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FAB6 + { 0xFAB7, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FAB7 + { 0xFAB8, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FAB8 + { 0xFAB9, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FAB9 + { 0xFABA, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FABA + { 0xFABB, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FABB + { 0xFABC, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FABC + { 0xFABD, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FABD + { 0xFABE, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FABE + { 0xFABF, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FABF + { 0xFAC0, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FAC0 + { 0xFAC1, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FAC1 + { 0xFAC2, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FAC2 + { 0xFAC3, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FAC3 + { 0xFAC4, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FAC4 + { 0xFAC5, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FAC5 + { 0xFAC6, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FAC6 + { 0xFAC7, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FAC7 + { 0xFAC8, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FAC8 + { 0xFAC9, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FAC9 + { 0xFACA, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FACA + { 0xFACB, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FACB + { 0xFACC, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FACC + { 0xFACD, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FACD + { 0xFACE, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FACE + { 0xFACF, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FACF + { 0xFAD0, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FAD0 + { 0xFAD1, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FAD1 + { 0xFAD2, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FAD2 + { 0xFAD3, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FAD3 + { 0xFAD4, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FAD4 + { 0xFAD5, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FAD5 + { 0xFAD6, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FAD6 + { 0xFAD7, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FAD7 + { 0xFAD8, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FAD8 + { 0xFAD9, BIDI_L }, // CJK COMPATIBILITY IDEOGRAPH-FAD9 + { 0xFB00, BIDI_L }, // LATIN SMALL LIGATURE FF + { 0xFB01, BIDI_L }, // LATIN SMALL LIGATURE FI + { 0xFB02, BIDI_L }, // LATIN SMALL LIGATURE FL + { 0xFB03, BIDI_L }, // LATIN SMALL LIGATURE FFI + { 0xFB04, BIDI_L }, // LATIN SMALL LIGATURE FFL + { 0xFB05, BIDI_L }, // LATIN SMALL LIGATURE LONG S T + { 0xFB06, BIDI_L }, // LATIN SMALL LIGATURE ST + { 0xFB13, BIDI_L }, // ARMENIAN SMALL LIGATURE MEN NOW + { 0xFB14, BIDI_L }, // ARMENIAN SMALL LIGATURE MEN ECH + { 0xFB15, BIDI_L }, // ARMENIAN SMALL LIGATURE MEN INI + { 0xFB16, BIDI_L }, // ARMENIAN SMALL LIGATURE VEW NOW + { 0xFB17, BIDI_L }, // ARMENIAN SMALL LIGATURE MEN XEH + { 0xFB1D, BIDI_R }, // HEBREW LETTER YOD WITH HIRIQ + { 0xFB1E, BIDI_NSM }, // HEBREW POINT JUDEO-SPANISH VARIKA + { 0xFB1F, BIDI_R }, // HEBREW LIGATURE YIDDISH YOD YOD PATAH + { 0xFB20, BIDI_R }, // HEBREW LETTER ALTERNATIVE AYIN + { 0xFB21, BIDI_R }, // HEBREW LETTER WIDE ALEF + { 0xFB22, BIDI_R }, // HEBREW LETTER WIDE DALET + { 0xFB23, BIDI_R }, // HEBREW LETTER WIDE HE + { 0xFB24, BIDI_R }, // HEBREW LETTER WIDE KAF + { 0xFB25, BIDI_R }, // HEBREW LETTER WIDE LAMED + { 0xFB26, BIDI_R }, // HEBREW LETTER WIDE FINAL MEM + { 0xFB27, BIDI_R }, // HEBREW LETTER WIDE RESH + { 0xFB28, BIDI_R }, // HEBREW LETTER WIDE TAV + { 0xFB29, BIDI_ES }, // HEBREW LETTER ALTERNATIVE PLUS SIGN + { 0xFB2A, BIDI_R }, // HEBREW LETTER SHIN WITH SHIN DOT + { 0xFB2B, BIDI_R }, // HEBREW LETTER SHIN WITH SIN DOT + { 0xFB2C, BIDI_R }, // HEBREW LETTER SHIN WITH DAGESH AND SHIN DOT + { 0xFB2D, BIDI_R }, // HEBREW LETTER SHIN WITH DAGESH AND SIN DOT + { 0xFB2E, BIDI_R }, // HEBREW LETTER ALEF WITH PATAH + { 0xFB2F, BIDI_R }, // HEBREW LETTER ALEF WITH QAMATS + { 0xFB30, BIDI_R }, // HEBREW LETTER ALEF WITH MAPIQ + { 0xFB31, BIDI_R }, // HEBREW LETTER BET WITH DAGESH + { 0xFB32, BIDI_R }, // HEBREW LETTER GIMEL WITH DAGESH + { 0xFB33, BIDI_R }, // HEBREW LETTER DALET WITH DAGESH + { 0xFB34, BIDI_R }, // HEBREW LETTER HE WITH MAPIQ + { 0xFB35, BIDI_R }, // HEBREW LETTER VAV WITH DAGESH + { 0xFB36, BIDI_R }, // HEBREW LETTER ZAYIN WITH DAGESH + { 0xFB38, BIDI_R }, // HEBREW LETTER TET WITH DAGESH + { 0xFB39, BIDI_R }, // HEBREW LETTER YOD WITH DAGESH + { 0xFB3A, BIDI_R }, // HEBREW LETTER FINAL KAF WITH DAGESH + { 0xFB3B, BIDI_R }, // HEBREW LETTER KAF WITH DAGESH + { 0xFB3C, BIDI_R }, // HEBREW LETTER LAMED WITH DAGESH + { 0xFB3E, BIDI_R }, // HEBREW LETTER MEM WITH DAGESH + { 0xFB40, BIDI_R }, // HEBREW LETTER NUN WITH DAGESH + { 0xFB41, BIDI_R }, // HEBREW LETTER SAMEKH WITH DAGESH + { 0xFB43, BIDI_R }, // HEBREW LETTER FINAL PE WITH DAGESH + { 0xFB44, BIDI_R }, // HEBREW LETTER PE WITH DAGESH + { 0xFB46, BIDI_R }, // HEBREW LETTER TSADI WITH DAGESH + { 0xFB47, BIDI_R }, // HEBREW LETTER QOF WITH DAGESH + { 0xFB48, BIDI_R }, // HEBREW LETTER RESH WITH DAGESH + { 0xFB49, BIDI_R }, // HEBREW LETTER SHIN WITH DAGESH + { 0xFB4A, BIDI_R }, // HEBREW LETTER TAV WITH DAGESH + { 0xFB4B, BIDI_R }, // HEBREW LETTER VAV WITH HOLAM + { 0xFB4C, BIDI_R }, // HEBREW LETTER BET WITH RAFE + { 0xFB4D, BIDI_R }, // HEBREW LETTER KAF WITH RAFE + { 0xFB4E, BIDI_R }, // HEBREW LETTER PE WITH RAFE + { 0xFB4F, BIDI_R }, // HEBREW LIGATURE ALEF LAMED + { 0xFB50, BIDI_AL }, // ARABIC LETTER ALEF WASLA ISOLATED FORM + { 0xFB51, BIDI_AL }, // ARABIC LETTER ALEF WASLA FINAL FORM + { 0xFB52, BIDI_AL }, // ARABIC LETTER BEEH ISOLATED FORM + { 0xFB53, BIDI_AL }, // ARABIC LETTER BEEH FINAL FORM + { 0xFB54, BIDI_AL }, // ARABIC LETTER BEEH INITIAL FORM + { 0xFB55, BIDI_AL }, // ARABIC LETTER BEEH MEDIAL FORM + { 0xFB56, BIDI_AL }, // ARABIC LETTER PEH ISOLATED FORM + { 0xFB57, BIDI_AL }, // ARABIC LETTER PEH FINAL FORM + { 0xFB58, BIDI_AL }, // ARABIC LETTER PEH INITIAL FORM + { 0xFB59, BIDI_AL }, // ARABIC LETTER PEH MEDIAL FORM + { 0xFB5A, BIDI_AL }, // ARABIC LETTER BEHEH ISOLATED FORM + { 0xFB5B, BIDI_AL }, // ARABIC LETTER BEHEH FINAL FORM + { 0xFB5C, BIDI_AL }, // ARABIC LETTER BEHEH INITIAL FORM + { 0xFB5D, BIDI_AL }, // ARABIC LETTER BEHEH MEDIAL FORM + { 0xFB5E, BIDI_AL }, // ARABIC LETTER TTEHEH ISOLATED FORM + { 0xFB5F, BIDI_AL }, // ARABIC LETTER TTEHEH FINAL FORM + { 0xFB60, BIDI_AL }, // ARABIC LETTER TTEHEH INITIAL FORM + { 0xFB61, BIDI_AL }, // ARABIC LETTER TTEHEH MEDIAL FORM + { 0xFB62, BIDI_AL }, // ARABIC LETTER TEHEH ISOLATED FORM + { 0xFB63, BIDI_AL }, // ARABIC LETTER TEHEH FINAL FORM + { 0xFB64, BIDI_AL }, // ARABIC LETTER TEHEH INITIAL FORM + { 0xFB65, BIDI_AL }, // ARABIC LETTER TEHEH MEDIAL FORM + { 0xFB66, BIDI_AL }, // ARABIC LETTER TTEH ISOLATED FORM + { 0xFB67, BIDI_AL }, // ARABIC LETTER TTEH FINAL FORM + { 0xFB68, BIDI_AL }, // ARABIC LETTER TTEH INITIAL FORM + { 0xFB69, BIDI_AL }, // ARABIC LETTER TTEH MEDIAL FORM + { 0xFB6A, BIDI_AL }, // ARABIC LETTER VEH ISOLATED FORM + { 0xFB6B, BIDI_AL }, // ARABIC LETTER VEH FINAL FORM + { 0xFB6C, BIDI_AL }, // ARABIC LETTER VEH INITIAL FORM + { 0xFB6D, BIDI_AL }, // ARABIC LETTER VEH MEDIAL FORM + { 0xFB6E, BIDI_AL }, // ARABIC LETTER PEHEH ISOLATED FORM + { 0xFB6F, BIDI_AL }, // ARABIC LETTER PEHEH FINAL FORM + { 0xFB70, BIDI_AL }, // ARABIC LETTER PEHEH INITIAL FORM + { 0xFB71, BIDI_AL }, // ARABIC LETTER PEHEH MEDIAL FORM + { 0xFB72, BIDI_AL }, // ARABIC LETTER DYEH ISOLATED FORM + { 0xFB73, BIDI_AL }, // ARABIC LETTER DYEH FINAL FORM + { 0xFB74, BIDI_AL }, // ARABIC LETTER DYEH INITIAL FORM + { 0xFB75, BIDI_AL }, // ARABIC LETTER DYEH MEDIAL FORM + { 0xFB76, BIDI_AL }, // ARABIC LETTER NYEH ISOLATED FORM + { 0xFB77, BIDI_AL }, // ARABIC LETTER NYEH FINAL FORM + { 0xFB78, BIDI_AL }, // ARABIC LETTER NYEH INITIAL FORM + { 0xFB79, BIDI_AL }, // ARABIC LETTER NYEH MEDIAL FORM + { 0xFB7A, BIDI_AL }, // ARABIC LETTER TCHEH ISOLATED FORM + { 0xFB7B, BIDI_AL }, // ARABIC LETTER TCHEH FINAL FORM + { 0xFB7C, BIDI_AL }, // ARABIC LETTER TCHEH INITIAL FORM + { 0xFB7D, BIDI_AL }, // ARABIC LETTER TCHEH MEDIAL FORM + { 0xFB7E, BIDI_AL }, // ARABIC LETTER TCHEHEH ISOLATED FORM + { 0xFB7F, BIDI_AL }, // ARABIC LETTER TCHEHEH FINAL FORM + { 0xFB80, BIDI_AL }, // ARABIC LETTER TCHEHEH INITIAL FORM + { 0xFB81, BIDI_AL }, // ARABIC LETTER TCHEHEH MEDIAL FORM + { 0xFB82, BIDI_AL }, // ARABIC LETTER DDAHAL ISOLATED FORM + { 0xFB83, BIDI_AL }, // ARABIC LETTER DDAHAL FINAL FORM + { 0xFB84, BIDI_AL }, // ARABIC LETTER DAHAL ISOLATED FORM + { 0xFB85, BIDI_AL }, // ARABIC LETTER DAHAL FINAL FORM + { 0xFB86, BIDI_AL }, // ARABIC LETTER DUL ISOLATED FORM + { 0xFB87, BIDI_AL }, // ARABIC LETTER DUL FINAL FORM + { 0xFB88, BIDI_AL }, // ARABIC LETTER DDAL ISOLATED FORM + { 0xFB89, BIDI_AL }, // ARABIC LETTER DDAL FINAL FORM + { 0xFB8A, BIDI_AL }, // ARABIC LETTER JEH ISOLATED FORM + { 0xFB8B, BIDI_AL }, // ARABIC LETTER JEH FINAL FORM + { 0xFB8C, BIDI_AL }, // ARABIC LETTER RREH ISOLATED FORM + { 0xFB8D, BIDI_AL }, // ARABIC LETTER RREH FINAL FORM + { 0xFB8E, BIDI_AL }, // ARABIC LETTER KEHEH ISOLATED FORM + { 0xFB8F, BIDI_AL }, // ARABIC LETTER KEHEH FINAL FORM + { 0xFB90, BIDI_AL }, // ARABIC LETTER KEHEH INITIAL FORM + { 0xFB91, BIDI_AL }, // ARABIC LETTER KEHEH MEDIAL FORM + { 0xFB92, BIDI_AL }, // ARABIC LETTER GAF ISOLATED FORM + { 0xFB93, BIDI_AL }, // ARABIC LETTER GAF FINAL FORM + { 0xFB94, BIDI_AL }, // ARABIC LETTER GAF INITIAL FORM + { 0xFB95, BIDI_AL }, // ARABIC LETTER GAF MEDIAL FORM + { 0xFB96, BIDI_AL }, // ARABIC LETTER GUEH ISOLATED FORM + { 0xFB97, BIDI_AL }, // ARABIC LETTER GUEH FINAL FORM + { 0xFB98, BIDI_AL }, // ARABIC LETTER GUEH INITIAL FORM + { 0xFB99, BIDI_AL }, // ARABIC LETTER GUEH MEDIAL FORM + { 0xFB9A, BIDI_AL }, // ARABIC LETTER NGOEH ISOLATED FORM + { 0xFB9B, BIDI_AL }, // ARABIC LETTER NGOEH FINAL FORM + { 0xFB9C, BIDI_AL }, // ARABIC LETTER NGOEH INITIAL FORM + { 0xFB9D, BIDI_AL }, // ARABIC LETTER NGOEH MEDIAL FORM + { 0xFB9E, BIDI_AL }, // ARABIC LETTER NOON GHUNNA ISOLATED FORM + { 0xFB9F, BIDI_AL }, // ARABIC LETTER NOON GHUNNA FINAL FORM + { 0xFBA0, BIDI_AL }, // ARABIC LETTER RNOON ISOLATED FORM + { 0xFBA1, BIDI_AL }, // ARABIC LETTER RNOON FINAL FORM + { 0xFBA2, BIDI_AL }, // ARABIC LETTER RNOON INITIAL FORM + { 0xFBA3, BIDI_AL }, // ARABIC LETTER RNOON MEDIAL FORM + { 0xFBA4, BIDI_AL }, // ARABIC LETTER HEH WITH YEH ABOVE ISOLATED FORM + { 0xFBA5, BIDI_AL }, // ARABIC LETTER HEH WITH YEH ABOVE FINAL FORM + { 0xFBA6, BIDI_AL }, // ARABIC LETTER HEH GOAL ISOLATED FORM + { 0xFBA7, BIDI_AL }, // ARABIC LETTER HEH GOAL FINAL FORM + { 0xFBA8, BIDI_AL }, // ARABIC LETTER HEH GOAL INITIAL FORM + { 0xFBA9, BIDI_AL }, // ARABIC LETTER HEH GOAL MEDIAL FORM + { 0xFBAA, BIDI_AL }, // ARABIC LETTER HEH DOACHASHMEE ISOLATED FORM + { 0xFBAB, BIDI_AL }, // ARABIC LETTER HEH DOACHASHMEE FINAL FORM + { 0xFBAC, BIDI_AL }, // ARABIC LETTER HEH DOACHASHMEE INITIAL FORM + { 0xFBAD, BIDI_AL }, // ARABIC LETTER HEH DOACHASHMEE MEDIAL FORM + { 0xFBAE, BIDI_AL }, // ARABIC LETTER YEH BARREE ISOLATED FORM + { 0xFBAF, BIDI_AL }, // ARABIC LETTER YEH BARREE FINAL FORM + { 0xFBB0, BIDI_AL }, // ARABIC LETTER YEH BARREE WITH HAMZA ABOVE ISOLATED FORM + { 0xFBB1, BIDI_AL }, // ARABIC LETTER YEH BARREE WITH HAMZA ABOVE FINAL FORM + { 0xFBB2, BIDI_AL }, // ARABIC SYMBOL DOT ABOVE + { 0xFBB3, BIDI_AL }, // ARABIC SYMBOL DOT BELOW + { 0xFBB4, BIDI_AL }, // ARABIC SYMBOL TWO DOTS ABOVE + { 0xFBB5, BIDI_AL }, // ARABIC SYMBOL TWO DOTS BELOW + { 0xFBB6, BIDI_AL }, // ARABIC SYMBOL THREE DOTS ABOVE + { 0xFBB7, BIDI_AL }, // ARABIC SYMBOL THREE DOTS BELOW + { 0xFBB8, BIDI_AL }, // ARABIC SYMBOL THREE DOTS POINTING DOWNWARDS ABOVE + { 0xFBB9, BIDI_AL }, // ARABIC SYMBOL THREE DOTS POINTING DOWNWARDS BELOW + { 0xFBBA, BIDI_AL }, // ARABIC SYMBOL FOUR DOTS ABOVE + { 0xFBBB, BIDI_AL }, // ARABIC SYMBOL FOUR DOTS BELOW + { 0xFBBC, BIDI_AL }, // ARABIC SYMBOL DOUBLE VERTICAL BAR BELOW + { 0xFBBD, BIDI_AL }, // ARABIC SYMBOL TWO DOTS VERTICALLY ABOVE + { 0xFBBE, BIDI_AL }, // ARABIC SYMBOL TWO DOTS VERTICALLY BELOW + { 0xFBBF, BIDI_AL }, // ARABIC SYMBOL RING + { 0xFBC0, BIDI_AL }, // ARABIC SYMBOL SMALL TAH ABOVE + { 0xFBC1, BIDI_AL }, // ARABIC SYMBOL SMALL TAH BELOW + { 0xFBD3, BIDI_AL }, // ARABIC LETTER NG ISOLATED FORM + { 0xFBD4, BIDI_AL }, // ARABIC LETTER NG FINAL FORM + { 0xFBD5, BIDI_AL }, // ARABIC LETTER NG INITIAL FORM + { 0xFBD6, BIDI_AL }, // ARABIC LETTER NG MEDIAL FORM + { 0xFBD7, BIDI_AL }, // ARABIC LETTER U ISOLATED FORM + { 0xFBD8, BIDI_AL }, // ARABIC LETTER U FINAL FORM + { 0xFBD9, BIDI_AL }, // ARABIC LETTER OE ISOLATED FORM + { 0xFBDA, BIDI_AL }, // ARABIC LETTER OE FINAL FORM + { 0xFBDB, BIDI_AL }, // ARABIC LETTER YU ISOLATED FORM + { 0xFBDC, BIDI_AL }, // ARABIC LETTER YU FINAL FORM + { 0xFBDD, BIDI_AL }, // ARABIC LETTER U WITH HAMZA ABOVE ISOLATED FORM + { 0xFBDE, BIDI_AL }, // ARABIC LETTER VE ISOLATED FORM + { 0xFBDF, BIDI_AL }, // ARABIC LETTER VE FINAL FORM + { 0xFBE0, BIDI_AL }, // ARABIC LETTER KIRGHIZ OE ISOLATED FORM + { 0xFBE1, BIDI_AL }, // ARABIC LETTER KIRGHIZ OE FINAL FORM + { 0xFBE2, BIDI_AL }, // ARABIC LETTER KIRGHIZ YU ISOLATED FORM + { 0xFBE3, BIDI_AL }, // ARABIC LETTER KIRGHIZ YU FINAL FORM + { 0xFBE4, BIDI_AL }, // ARABIC LETTER E ISOLATED FORM + { 0xFBE5, BIDI_AL }, // ARABIC LETTER E FINAL FORM + { 0xFBE6, BIDI_AL }, // ARABIC LETTER E INITIAL FORM + { 0xFBE7, BIDI_AL }, // ARABIC LETTER E MEDIAL FORM + { 0xFBE8, BIDI_AL }, // ARABIC LETTER UIGHUR KAZAKH KIRGHIZ ALEF MAKSURA INITIAL FORM + { 0xFBE9, BIDI_AL }, // ARABIC LETTER UIGHUR KAZAKH KIRGHIZ ALEF MAKSURA MEDIAL FORM + { 0xFBEA, BIDI_AL }, // ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF ISOLATED FORM + { 0xFBEB, BIDI_AL }, // ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF FINAL FORM + { 0xFBEC, BIDI_AL }, // ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH AE ISOLATED FORM + { 0xFBED, BIDI_AL }, // ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH AE FINAL FORM + { 0xFBEE, BIDI_AL }, // ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH WAW ISOLATED FORM + { 0xFBEF, BIDI_AL }, // ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH WAW FINAL FORM + { 0xFBF0, BIDI_AL }, // ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH U ISOLATED FORM + { 0xFBF1, BIDI_AL }, // ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH U FINAL FORM + { 0xFBF2, BIDI_AL }, // ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH OE ISOLATED FORM + { 0xFBF3, BIDI_AL }, // ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH OE FINAL FORM + { 0xFBF4, BIDI_AL }, // ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YU ISOLATED FORM + { 0xFBF5, BIDI_AL }, // ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YU FINAL FORM + { 0xFBF6, BIDI_AL }, // ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E ISOLATED FORM + { 0xFBF7, BIDI_AL }, // ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E FINAL FORM + { 0xFBF8, BIDI_AL }, // ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH E INITIAL FORM + { 0xFBF9, BIDI_AL }, // ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA ISOLATED FORM + { 0xFBFA, BIDI_AL }, // ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA FINAL FORM + { 0xFBFB, BIDI_AL }, // ARABIC LIGATURE UIGHUR KIRGHIZ YEH WITH HAMZA ABOVE WITH ALEF MAKSURA INITIAL FORM + { 0xFBFC, BIDI_AL }, // ARABIC LETTER FARSI YEH ISOLATED FORM + { 0xFBFD, BIDI_AL }, // ARABIC LETTER FARSI YEH FINAL FORM + { 0xFBFE, BIDI_AL }, // ARABIC LETTER FARSI YEH INITIAL FORM + { 0xFBFF, BIDI_AL }, // ARABIC LETTER FARSI YEH MEDIAL FORM + { 0xFC00, BIDI_AL }, // ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH JEEM ISOLATED FORM + { 0xFC01, BIDI_AL }, // ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HAH ISOLATED FORM + { 0xFC02, BIDI_AL }, // ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM ISOLATED FORM + { 0xFC03, BIDI_AL }, // ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF MAKSURA ISOLATED FORM + { 0xFC04, BIDI_AL }, // ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YEH ISOLATED FORM + { 0xFC05, BIDI_AL }, // ARABIC LIGATURE BEH WITH JEEM ISOLATED FORM + { 0xFC06, BIDI_AL }, // ARABIC LIGATURE BEH WITH HAH ISOLATED FORM + { 0xFC07, BIDI_AL }, // ARABIC LIGATURE BEH WITH KHAH ISOLATED FORM + { 0xFC08, BIDI_AL }, // ARABIC LIGATURE BEH WITH MEEM ISOLATED FORM + { 0xFC09, BIDI_AL }, // ARABIC LIGATURE BEH WITH ALEF MAKSURA ISOLATED FORM + { 0xFC0A, BIDI_AL }, // ARABIC LIGATURE BEH WITH YEH ISOLATED FORM + { 0xFC0B, BIDI_AL }, // ARABIC LIGATURE TEH WITH JEEM ISOLATED FORM + { 0xFC0C, BIDI_AL }, // ARABIC LIGATURE TEH WITH HAH ISOLATED FORM + { 0xFC0D, BIDI_AL }, // ARABIC LIGATURE TEH WITH KHAH ISOLATED FORM + { 0xFC0E, BIDI_AL }, // ARABIC LIGATURE TEH WITH MEEM ISOLATED FORM + { 0xFC0F, BIDI_AL }, // ARABIC LIGATURE TEH WITH ALEF MAKSURA ISOLATED FORM + { 0xFC10, BIDI_AL }, // ARABIC LIGATURE TEH WITH YEH ISOLATED FORM + { 0xFC11, BIDI_AL }, // ARABIC LIGATURE THEH WITH JEEM ISOLATED FORM + { 0xFC12, BIDI_AL }, // ARABIC LIGATURE THEH WITH MEEM ISOLATED FORM + { 0xFC13, BIDI_AL }, // ARABIC LIGATURE THEH WITH ALEF MAKSURA ISOLATED FORM + { 0xFC14, BIDI_AL }, // ARABIC LIGATURE THEH WITH YEH ISOLATED FORM + { 0xFC15, BIDI_AL }, // ARABIC LIGATURE JEEM WITH HAH ISOLATED FORM + { 0xFC16, BIDI_AL }, // ARABIC LIGATURE JEEM WITH MEEM ISOLATED FORM + { 0xFC17, BIDI_AL }, // ARABIC LIGATURE HAH WITH JEEM ISOLATED FORM + { 0xFC18, BIDI_AL }, // ARABIC LIGATURE HAH WITH MEEM ISOLATED FORM + { 0xFC19, BIDI_AL }, // ARABIC LIGATURE KHAH WITH JEEM ISOLATED FORM + { 0xFC1A, BIDI_AL }, // ARABIC LIGATURE KHAH WITH HAH ISOLATED FORM + { 0xFC1B, BIDI_AL }, // ARABIC LIGATURE KHAH WITH MEEM ISOLATED FORM + { 0xFC1C, BIDI_AL }, // ARABIC LIGATURE SEEN WITH JEEM ISOLATED FORM + { 0xFC1D, BIDI_AL }, // ARABIC LIGATURE SEEN WITH HAH ISOLATED FORM + { 0xFC1E, BIDI_AL }, // ARABIC LIGATURE SEEN WITH KHAH ISOLATED FORM + { 0xFC1F, BIDI_AL }, // ARABIC LIGATURE SEEN WITH MEEM ISOLATED FORM + { 0xFC20, BIDI_AL }, // ARABIC LIGATURE SAD WITH HAH ISOLATED FORM + { 0xFC21, BIDI_AL }, // ARABIC LIGATURE SAD WITH MEEM ISOLATED FORM + { 0xFC22, BIDI_AL }, // ARABIC LIGATURE DAD WITH JEEM ISOLATED FORM + { 0xFC23, BIDI_AL }, // ARABIC LIGATURE DAD WITH HAH ISOLATED FORM + { 0xFC24, BIDI_AL }, // ARABIC LIGATURE DAD WITH KHAH ISOLATED FORM + { 0xFC25, BIDI_AL }, // ARABIC LIGATURE DAD WITH MEEM ISOLATED FORM + { 0xFC26, BIDI_AL }, // ARABIC LIGATURE TAH WITH HAH ISOLATED FORM + { 0xFC27, BIDI_AL }, // ARABIC LIGATURE TAH WITH MEEM ISOLATED FORM + { 0xFC28, BIDI_AL }, // ARABIC LIGATURE ZAH WITH MEEM ISOLATED FORM + { 0xFC29, BIDI_AL }, // ARABIC LIGATURE AIN WITH JEEM ISOLATED FORM + { 0xFC2A, BIDI_AL }, // ARABIC LIGATURE AIN WITH MEEM ISOLATED FORM + { 0xFC2B, BIDI_AL }, // ARABIC LIGATURE GHAIN WITH JEEM ISOLATED FORM + { 0xFC2C, BIDI_AL }, // ARABIC LIGATURE GHAIN WITH MEEM ISOLATED FORM + { 0xFC2D, BIDI_AL }, // ARABIC LIGATURE FEH WITH JEEM ISOLATED FORM + { 0xFC2E, BIDI_AL }, // ARABIC LIGATURE FEH WITH HAH ISOLATED FORM + { 0xFC2F, BIDI_AL }, // ARABIC LIGATURE FEH WITH KHAH ISOLATED FORM + { 0xFC30, BIDI_AL }, // ARABIC LIGATURE FEH WITH MEEM ISOLATED FORM + { 0xFC31, BIDI_AL }, // ARABIC LIGATURE FEH WITH ALEF MAKSURA ISOLATED FORM + { 0xFC32, BIDI_AL }, // ARABIC LIGATURE FEH WITH YEH ISOLATED FORM + { 0xFC33, BIDI_AL }, // ARABIC LIGATURE QAF WITH HAH ISOLATED FORM + { 0xFC34, BIDI_AL }, // ARABIC LIGATURE QAF WITH MEEM ISOLATED FORM + { 0xFC35, BIDI_AL }, // ARABIC LIGATURE QAF WITH ALEF MAKSURA ISOLATED FORM + { 0xFC36, BIDI_AL }, // ARABIC LIGATURE QAF WITH YEH ISOLATED FORM + { 0xFC37, BIDI_AL }, // ARABIC LIGATURE KAF WITH ALEF ISOLATED FORM + { 0xFC38, BIDI_AL }, // ARABIC LIGATURE KAF WITH JEEM ISOLATED FORM + { 0xFC39, BIDI_AL }, // ARABIC LIGATURE KAF WITH HAH ISOLATED FORM + { 0xFC3A, BIDI_AL }, // ARABIC LIGATURE KAF WITH KHAH ISOLATED FORM + { 0xFC3B, BIDI_AL }, // ARABIC LIGATURE KAF WITH LAM ISOLATED FORM + { 0xFC3C, BIDI_AL }, // ARABIC LIGATURE KAF WITH MEEM ISOLATED FORM + { 0xFC3D, BIDI_AL }, // ARABIC LIGATURE KAF WITH ALEF MAKSURA ISOLATED FORM + { 0xFC3E, BIDI_AL }, // ARABIC LIGATURE KAF WITH YEH ISOLATED FORM + { 0xFC3F, BIDI_AL }, // ARABIC LIGATURE LAM WITH JEEM ISOLATED FORM + { 0xFC40, BIDI_AL }, // ARABIC LIGATURE LAM WITH HAH ISOLATED FORM + { 0xFC41, BIDI_AL }, // ARABIC LIGATURE LAM WITH KHAH ISOLATED FORM + { 0xFC42, BIDI_AL }, // ARABIC LIGATURE LAM WITH MEEM ISOLATED FORM + { 0xFC43, BIDI_AL }, // ARABIC LIGATURE LAM WITH ALEF MAKSURA ISOLATED FORM + { 0xFC44, BIDI_AL }, // ARABIC LIGATURE LAM WITH YEH ISOLATED FORM + { 0xFC45, BIDI_AL }, // ARABIC LIGATURE MEEM WITH JEEM ISOLATED FORM + { 0xFC46, BIDI_AL }, // ARABIC LIGATURE MEEM WITH HAH ISOLATED FORM + { 0xFC47, BIDI_AL }, // ARABIC LIGATURE MEEM WITH KHAH ISOLATED FORM + { 0xFC48, BIDI_AL }, // ARABIC LIGATURE MEEM WITH MEEM ISOLATED FORM + { 0xFC49, BIDI_AL }, // ARABIC LIGATURE MEEM WITH ALEF MAKSURA ISOLATED FORM + { 0xFC4A, BIDI_AL }, // ARABIC LIGATURE MEEM WITH YEH ISOLATED FORM + { 0xFC4B, BIDI_AL }, // ARABIC LIGATURE NOON WITH JEEM ISOLATED FORM + { 0xFC4C, BIDI_AL }, // ARABIC LIGATURE NOON WITH HAH ISOLATED FORM + { 0xFC4D, BIDI_AL }, // ARABIC LIGATURE NOON WITH KHAH ISOLATED FORM + { 0xFC4E, BIDI_AL }, // ARABIC LIGATURE NOON WITH MEEM ISOLATED FORM + { 0xFC4F, BIDI_AL }, // ARABIC LIGATURE NOON WITH ALEF MAKSURA ISOLATED FORM + { 0xFC50, BIDI_AL }, // ARABIC LIGATURE NOON WITH YEH ISOLATED FORM + { 0xFC51, BIDI_AL }, // ARABIC LIGATURE HEH WITH JEEM ISOLATED FORM + { 0xFC52, BIDI_AL }, // ARABIC LIGATURE HEH WITH MEEM ISOLATED FORM + { 0xFC53, BIDI_AL }, // ARABIC LIGATURE HEH WITH ALEF MAKSURA ISOLATED FORM + { 0xFC54, BIDI_AL }, // ARABIC LIGATURE HEH WITH YEH ISOLATED FORM + { 0xFC55, BIDI_AL }, // ARABIC LIGATURE YEH WITH JEEM ISOLATED FORM + { 0xFC56, BIDI_AL }, // ARABIC LIGATURE YEH WITH HAH ISOLATED FORM + { 0xFC57, BIDI_AL }, // ARABIC LIGATURE YEH WITH KHAH ISOLATED FORM + { 0xFC58, BIDI_AL }, // ARABIC LIGATURE YEH WITH MEEM ISOLATED FORM + { 0xFC59, BIDI_AL }, // ARABIC LIGATURE YEH WITH ALEF MAKSURA ISOLATED FORM + { 0xFC5A, BIDI_AL }, // ARABIC LIGATURE YEH WITH YEH ISOLATED FORM + { 0xFC5B, BIDI_AL }, // ARABIC LIGATURE THAL WITH SUPERSCRIPT ALEF ISOLATED FORM + { 0xFC5C, BIDI_AL }, // ARABIC LIGATURE REH WITH SUPERSCRIPT ALEF ISOLATED FORM + { 0xFC5D, BIDI_AL }, // ARABIC LIGATURE ALEF MAKSURA WITH SUPERSCRIPT ALEF ISOLATED FORM + { 0xFC5E, BIDI_AL }, // ARABIC LIGATURE SHADDA WITH DAMMATAN ISOLATED FORM + { 0xFC5F, BIDI_AL }, // ARABIC LIGATURE SHADDA WITH KASRATAN ISOLATED FORM + { 0xFC60, BIDI_AL }, // ARABIC LIGATURE SHADDA WITH FATHA ISOLATED FORM + { 0xFC61, BIDI_AL }, // ARABIC LIGATURE SHADDA WITH DAMMA ISOLATED FORM + { 0xFC62, BIDI_AL }, // ARABIC LIGATURE SHADDA WITH KASRA ISOLATED FORM + { 0xFC63, BIDI_AL }, // ARABIC LIGATURE SHADDA WITH SUPERSCRIPT ALEF ISOLATED FORM + { 0xFC64, BIDI_AL }, // ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH REH FINAL FORM + { 0xFC65, BIDI_AL }, // ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ZAIN FINAL FORM + { 0xFC66, BIDI_AL }, // ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM FINAL FORM + { 0xFC67, BIDI_AL }, // ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH NOON FINAL FORM + { 0xFC68, BIDI_AL }, // ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF MAKSURA FINAL FORM + { 0xFC69, BIDI_AL }, // ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH YEH FINAL FORM + { 0xFC6A, BIDI_AL }, // ARABIC LIGATURE BEH WITH REH FINAL FORM + { 0xFC6B, BIDI_AL }, // ARABIC LIGATURE BEH WITH ZAIN FINAL FORM + { 0xFC6C, BIDI_AL }, // ARABIC LIGATURE BEH WITH MEEM FINAL FORM + { 0xFC6D, BIDI_AL }, // ARABIC LIGATURE BEH WITH NOON FINAL FORM + { 0xFC6E, BIDI_AL }, // ARABIC LIGATURE BEH WITH ALEF MAKSURA FINAL FORM + { 0xFC6F, BIDI_AL }, // ARABIC LIGATURE BEH WITH YEH FINAL FORM + { 0xFC70, BIDI_AL }, // ARABIC LIGATURE TEH WITH REH FINAL FORM + { 0xFC71, BIDI_AL }, // ARABIC LIGATURE TEH WITH ZAIN FINAL FORM + { 0xFC72, BIDI_AL }, // ARABIC LIGATURE TEH WITH MEEM FINAL FORM + { 0xFC73, BIDI_AL }, // ARABIC LIGATURE TEH WITH NOON FINAL FORM + { 0xFC74, BIDI_AL }, // ARABIC LIGATURE TEH WITH ALEF MAKSURA FINAL FORM + { 0xFC75, BIDI_AL }, // ARABIC LIGATURE TEH WITH YEH FINAL FORM + { 0xFC76, BIDI_AL }, // ARABIC LIGATURE THEH WITH REH FINAL FORM + { 0xFC77, BIDI_AL }, // ARABIC LIGATURE THEH WITH ZAIN FINAL FORM + { 0xFC78, BIDI_AL }, // ARABIC LIGATURE THEH WITH MEEM FINAL FORM + { 0xFC79, BIDI_AL }, // ARABIC LIGATURE THEH WITH NOON FINAL FORM + { 0xFC7A, BIDI_AL }, // ARABIC LIGATURE THEH WITH ALEF MAKSURA FINAL FORM + { 0xFC7B, BIDI_AL }, // ARABIC LIGATURE THEH WITH YEH FINAL FORM + { 0xFC7C, BIDI_AL }, // ARABIC LIGATURE FEH WITH ALEF MAKSURA FINAL FORM + { 0xFC7D, BIDI_AL }, // ARABIC LIGATURE FEH WITH YEH FINAL FORM + { 0xFC7E, BIDI_AL }, // ARABIC LIGATURE QAF WITH ALEF MAKSURA FINAL FORM + { 0xFC7F, BIDI_AL }, // ARABIC LIGATURE QAF WITH YEH FINAL FORM + { 0xFC80, BIDI_AL }, // ARABIC LIGATURE KAF WITH ALEF FINAL FORM + { 0xFC81, BIDI_AL }, // ARABIC LIGATURE KAF WITH LAM FINAL FORM + { 0xFC82, BIDI_AL }, // ARABIC LIGATURE KAF WITH MEEM FINAL FORM + { 0xFC83, BIDI_AL }, // ARABIC LIGATURE KAF WITH ALEF MAKSURA FINAL FORM + { 0xFC84, BIDI_AL }, // ARABIC LIGATURE KAF WITH YEH FINAL FORM + { 0xFC85, BIDI_AL }, // ARABIC LIGATURE LAM WITH MEEM FINAL FORM + { 0xFC86, BIDI_AL }, // ARABIC LIGATURE LAM WITH ALEF MAKSURA FINAL FORM + { 0xFC87, BIDI_AL }, // ARABIC LIGATURE LAM WITH YEH FINAL FORM + { 0xFC88, BIDI_AL }, // ARABIC LIGATURE MEEM WITH ALEF FINAL FORM + { 0xFC89, BIDI_AL }, // ARABIC LIGATURE MEEM WITH MEEM FINAL FORM + { 0xFC8A, BIDI_AL }, // ARABIC LIGATURE NOON WITH REH FINAL FORM + { 0xFC8B, BIDI_AL }, // ARABIC LIGATURE NOON WITH ZAIN FINAL FORM + { 0xFC8C, BIDI_AL }, // ARABIC LIGATURE NOON WITH MEEM FINAL FORM + { 0xFC8D, BIDI_AL }, // ARABIC LIGATURE NOON WITH NOON FINAL FORM + { 0xFC8E, BIDI_AL }, // ARABIC LIGATURE NOON WITH ALEF MAKSURA FINAL FORM + { 0xFC8F, BIDI_AL }, // ARABIC LIGATURE NOON WITH YEH FINAL FORM + { 0xFC90, BIDI_AL }, // ARABIC LIGATURE ALEF MAKSURA WITH SUPERSCRIPT ALEF FINAL FORM + { 0xFC91, BIDI_AL }, // ARABIC LIGATURE YEH WITH REH FINAL FORM + { 0xFC92, BIDI_AL }, // ARABIC LIGATURE YEH WITH ZAIN FINAL FORM + { 0xFC93, BIDI_AL }, // ARABIC LIGATURE YEH WITH MEEM FINAL FORM + { 0xFC94, BIDI_AL }, // ARABIC LIGATURE YEH WITH NOON FINAL FORM + { 0xFC95, BIDI_AL }, // ARABIC LIGATURE YEH WITH ALEF MAKSURA FINAL FORM + { 0xFC96, BIDI_AL }, // ARABIC LIGATURE YEH WITH YEH FINAL FORM + { 0xFC97, BIDI_AL }, // ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH JEEM INITIAL FORM + { 0xFC98, BIDI_AL }, // ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HAH INITIAL FORM + { 0xFC99, BIDI_AL }, // ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH KHAH INITIAL FORM + { 0xFC9A, BIDI_AL }, // ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM INITIAL FORM + { 0xFC9B, BIDI_AL }, // ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HEH INITIAL FORM + { 0xFC9C, BIDI_AL }, // ARABIC LIGATURE BEH WITH JEEM INITIAL FORM + { 0xFC9D, BIDI_AL }, // ARABIC LIGATURE BEH WITH HAH INITIAL FORM + { 0xFC9E, BIDI_AL }, // ARABIC LIGATURE BEH WITH KHAH INITIAL FORM + { 0xFC9F, BIDI_AL }, // ARABIC LIGATURE BEH WITH MEEM INITIAL FORM + { 0xFCA0, BIDI_AL }, // ARABIC LIGATURE BEH WITH HEH INITIAL FORM + { 0xFCA1, BIDI_AL }, // ARABIC LIGATURE TEH WITH JEEM INITIAL FORM + { 0xFCA2, BIDI_AL }, // ARABIC LIGATURE TEH WITH HAH INITIAL FORM + { 0xFCA3, BIDI_AL }, // ARABIC LIGATURE TEH WITH KHAH INITIAL FORM + { 0xFCA4, BIDI_AL }, // ARABIC LIGATURE TEH WITH MEEM INITIAL FORM + { 0xFCA5, BIDI_AL }, // ARABIC LIGATURE TEH WITH HEH INITIAL FORM + { 0xFCA6, BIDI_AL }, // ARABIC LIGATURE THEH WITH MEEM INITIAL FORM + { 0xFCA7, BIDI_AL }, // ARABIC LIGATURE JEEM WITH HAH INITIAL FORM + { 0xFCA8, BIDI_AL }, // ARABIC LIGATURE JEEM WITH MEEM INITIAL FORM + { 0xFCA9, BIDI_AL }, // ARABIC LIGATURE HAH WITH JEEM INITIAL FORM + { 0xFCAA, BIDI_AL }, // ARABIC LIGATURE HAH WITH MEEM INITIAL FORM + { 0xFCAB, BIDI_AL }, // ARABIC LIGATURE KHAH WITH JEEM INITIAL FORM + { 0xFCAC, BIDI_AL }, // ARABIC LIGATURE KHAH WITH MEEM INITIAL FORM + { 0xFCAD, BIDI_AL }, // ARABIC LIGATURE SEEN WITH JEEM INITIAL FORM + { 0xFCAE, BIDI_AL }, // ARABIC LIGATURE SEEN WITH HAH INITIAL FORM + { 0xFCAF, BIDI_AL }, // ARABIC LIGATURE SEEN WITH KHAH INITIAL FORM + { 0xFCB0, BIDI_AL }, // ARABIC LIGATURE SEEN WITH MEEM INITIAL FORM + { 0xFCB1, BIDI_AL }, // ARABIC LIGATURE SAD WITH HAH INITIAL FORM + { 0xFCB2, BIDI_AL }, // ARABIC LIGATURE SAD WITH KHAH INITIAL FORM + { 0xFCB3, BIDI_AL }, // ARABIC LIGATURE SAD WITH MEEM INITIAL FORM + { 0xFCB4, BIDI_AL }, // ARABIC LIGATURE DAD WITH JEEM INITIAL FORM + { 0xFCB5, BIDI_AL }, // ARABIC LIGATURE DAD WITH HAH INITIAL FORM + { 0xFCB6, BIDI_AL }, // ARABIC LIGATURE DAD WITH KHAH INITIAL FORM + { 0xFCB7, BIDI_AL }, // ARABIC LIGATURE DAD WITH MEEM INITIAL FORM + { 0xFCB8, BIDI_AL }, // ARABIC LIGATURE TAH WITH HAH INITIAL FORM + { 0xFCB9, BIDI_AL }, // ARABIC LIGATURE ZAH WITH MEEM INITIAL FORM + { 0xFCBA, BIDI_AL }, // ARABIC LIGATURE AIN WITH JEEM INITIAL FORM + { 0xFCBB, BIDI_AL }, // ARABIC LIGATURE AIN WITH MEEM INITIAL FORM + { 0xFCBC, BIDI_AL }, // ARABIC LIGATURE GHAIN WITH JEEM INITIAL FORM + { 0xFCBD, BIDI_AL }, // ARABIC LIGATURE GHAIN WITH MEEM INITIAL FORM + { 0xFCBE, BIDI_AL }, // ARABIC LIGATURE FEH WITH JEEM INITIAL FORM + { 0xFCBF, BIDI_AL }, // ARABIC LIGATURE FEH WITH HAH INITIAL FORM + { 0xFCC0, BIDI_AL }, // ARABIC LIGATURE FEH WITH KHAH INITIAL FORM + { 0xFCC1, BIDI_AL }, // ARABIC LIGATURE FEH WITH MEEM INITIAL FORM + { 0xFCC2, BIDI_AL }, // ARABIC LIGATURE QAF WITH HAH INITIAL FORM + { 0xFCC3, BIDI_AL }, // ARABIC LIGATURE QAF WITH MEEM INITIAL FORM + { 0xFCC4, BIDI_AL }, // ARABIC LIGATURE KAF WITH JEEM INITIAL FORM + { 0xFCC5, BIDI_AL }, // ARABIC LIGATURE KAF WITH HAH INITIAL FORM + { 0xFCC6, BIDI_AL }, // ARABIC LIGATURE KAF WITH KHAH INITIAL FORM + { 0xFCC7, BIDI_AL }, // ARABIC LIGATURE KAF WITH LAM INITIAL FORM + { 0xFCC8, BIDI_AL }, // ARABIC LIGATURE KAF WITH MEEM INITIAL FORM + { 0xFCC9, BIDI_AL }, // ARABIC LIGATURE LAM WITH JEEM INITIAL FORM + { 0xFCCA, BIDI_AL }, // ARABIC LIGATURE LAM WITH HAH INITIAL FORM + { 0xFCCB, BIDI_AL }, // ARABIC LIGATURE LAM WITH KHAH INITIAL FORM + { 0xFCCC, BIDI_AL }, // ARABIC LIGATURE LAM WITH MEEM INITIAL FORM + { 0xFCCD, BIDI_AL }, // ARABIC LIGATURE LAM WITH HEH INITIAL FORM + { 0xFCCE, BIDI_AL }, // ARABIC LIGATURE MEEM WITH JEEM INITIAL FORM + { 0xFCCF, BIDI_AL }, // ARABIC LIGATURE MEEM WITH HAH INITIAL FORM + { 0xFCD0, BIDI_AL }, // ARABIC LIGATURE MEEM WITH KHAH INITIAL FORM + { 0xFCD1, BIDI_AL }, // ARABIC LIGATURE MEEM WITH MEEM INITIAL FORM + { 0xFCD2, BIDI_AL }, // ARABIC LIGATURE NOON WITH JEEM INITIAL FORM + { 0xFCD3, BIDI_AL }, // ARABIC LIGATURE NOON WITH HAH INITIAL FORM + { 0xFCD4, BIDI_AL }, // ARABIC LIGATURE NOON WITH KHAH INITIAL FORM + { 0xFCD5, BIDI_AL }, // ARABIC LIGATURE NOON WITH MEEM INITIAL FORM + { 0xFCD6, BIDI_AL }, // ARABIC LIGATURE NOON WITH HEH INITIAL FORM + { 0xFCD7, BIDI_AL }, // ARABIC LIGATURE HEH WITH JEEM INITIAL FORM + { 0xFCD8, BIDI_AL }, // ARABIC LIGATURE HEH WITH MEEM INITIAL FORM + { 0xFCD9, BIDI_AL }, // ARABIC LIGATURE HEH WITH SUPERSCRIPT ALEF INITIAL FORM + { 0xFCDA, BIDI_AL }, // ARABIC LIGATURE YEH WITH JEEM INITIAL FORM + { 0xFCDB, BIDI_AL }, // ARABIC LIGATURE YEH WITH HAH INITIAL FORM + { 0xFCDC, BIDI_AL }, // ARABIC LIGATURE YEH WITH KHAH INITIAL FORM + { 0xFCDD, BIDI_AL }, // ARABIC LIGATURE YEH WITH MEEM INITIAL FORM + { 0xFCDE, BIDI_AL }, // ARABIC LIGATURE YEH WITH HEH INITIAL FORM + { 0xFCDF, BIDI_AL }, // ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH MEEM MEDIAL FORM + { 0xFCE0, BIDI_AL }, // ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH HEH MEDIAL FORM + { 0xFCE1, BIDI_AL }, // ARABIC LIGATURE BEH WITH MEEM MEDIAL FORM + { 0xFCE2, BIDI_AL }, // ARABIC LIGATURE BEH WITH HEH MEDIAL FORM + { 0xFCE3, BIDI_AL }, // ARABIC LIGATURE TEH WITH MEEM MEDIAL FORM + { 0xFCE4, BIDI_AL }, // ARABIC LIGATURE TEH WITH HEH MEDIAL FORM + { 0xFCE5, BIDI_AL }, // ARABIC LIGATURE THEH WITH MEEM MEDIAL FORM + { 0xFCE6, BIDI_AL }, // ARABIC LIGATURE THEH WITH HEH MEDIAL FORM + { 0xFCE7, BIDI_AL }, // ARABIC LIGATURE SEEN WITH MEEM MEDIAL FORM + { 0xFCE8, BIDI_AL }, // ARABIC LIGATURE SEEN WITH HEH MEDIAL FORM + { 0xFCE9, BIDI_AL }, // ARABIC LIGATURE SHEEN WITH MEEM MEDIAL FORM + { 0xFCEA, BIDI_AL }, // ARABIC LIGATURE SHEEN WITH HEH MEDIAL FORM + { 0xFCEB, BIDI_AL }, // ARABIC LIGATURE KAF WITH LAM MEDIAL FORM + { 0xFCEC, BIDI_AL }, // ARABIC LIGATURE KAF WITH MEEM MEDIAL FORM + { 0xFCED, BIDI_AL }, // ARABIC LIGATURE LAM WITH MEEM MEDIAL FORM + { 0xFCEE, BIDI_AL }, // ARABIC LIGATURE NOON WITH MEEM MEDIAL FORM + { 0xFCEF, BIDI_AL }, // ARABIC LIGATURE NOON WITH HEH MEDIAL FORM + { 0xFCF0, BIDI_AL }, // ARABIC LIGATURE YEH WITH MEEM MEDIAL FORM + { 0xFCF1, BIDI_AL }, // ARABIC LIGATURE YEH WITH HEH MEDIAL FORM + { 0xFCF2, BIDI_AL }, // ARABIC LIGATURE SHADDA WITH FATHA MEDIAL FORM + { 0xFCF3, BIDI_AL }, // ARABIC LIGATURE SHADDA WITH DAMMA MEDIAL FORM + { 0xFCF4, BIDI_AL }, // ARABIC LIGATURE SHADDA WITH KASRA MEDIAL FORM + { 0xFCF5, BIDI_AL }, // ARABIC LIGATURE TAH WITH ALEF MAKSURA ISOLATED FORM + { 0xFCF6, BIDI_AL }, // ARABIC LIGATURE TAH WITH YEH ISOLATED FORM + { 0xFCF7, BIDI_AL }, // ARABIC LIGATURE AIN WITH ALEF MAKSURA ISOLATED FORM + { 0xFCF8, BIDI_AL }, // ARABIC LIGATURE AIN WITH YEH ISOLATED FORM + { 0xFCF9, BIDI_AL }, // ARABIC LIGATURE GHAIN WITH ALEF MAKSURA ISOLATED FORM + { 0xFCFA, BIDI_AL }, // ARABIC LIGATURE GHAIN WITH YEH ISOLATED FORM + { 0xFCFB, BIDI_AL }, // ARABIC LIGATURE SEEN WITH ALEF MAKSURA ISOLATED FORM + { 0xFCFC, BIDI_AL }, // ARABIC LIGATURE SEEN WITH YEH ISOLATED FORM + { 0xFCFD, BIDI_AL }, // ARABIC LIGATURE SHEEN WITH ALEF MAKSURA ISOLATED FORM + { 0xFCFE, BIDI_AL }, // ARABIC LIGATURE SHEEN WITH YEH ISOLATED FORM + { 0xFCFF, BIDI_AL }, // ARABIC LIGATURE HAH WITH ALEF MAKSURA ISOLATED FORM + { 0xFD00, BIDI_AL }, // ARABIC LIGATURE HAH WITH YEH ISOLATED FORM + { 0xFD01, BIDI_AL }, // ARABIC LIGATURE JEEM WITH ALEF MAKSURA ISOLATED FORM + { 0xFD02, BIDI_AL }, // ARABIC LIGATURE JEEM WITH YEH ISOLATED FORM + { 0xFD03, BIDI_AL }, // ARABIC LIGATURE KHAH WITH ALEF MAKSURA ISOLATED FORM + { 0xFD04, BIDI_AL }, // ARABIC LIGATURE KHAH WITH YEH ISOLATED FORM + { 0xFD05, BIDI_AL }, // ARABIC LIGATURE SAD WITH ALEF MAKSURA ISOLATED FORM + { 0xFD06, BIDI_AL }, // ARABIC LIGATURE SAD WITH YEH ISOLATED FORM + { 0xFD07, BIDI_AL }, // ARABIC LIGATURE DAD WITH ALEF MAKSURA ISOLATED FORM + { 0xFD08, BIDI_AL }, // ARABIC LIGATURE DAD WITH YEH ISOLATED FORM + { 0xFD09, BIDI_AL }, // ARABIC LIGATURE SHEEN WITH JEEM ISOLATED FORM + { 0xFD0A, BIDI_AL }, // ARABIC LIGATURE SHEEN WITH HAH ISOLATED FORM + { 0xFD0B, BIDI_AL }, // ARABIC LIGATURE SHEEN WITH KHAH ISOLATED FORM + { 0xFD0C, BIDI_AL }, // ARABIC LIGATURE SHEEN WITH MEEM ISOLATED FORM + { 0xFD0D, BIDI_AL }, // ARABIC LIGATURE SHEEN WITH REH ISOLATED FORM + { 0xFD0E, BIDI_AL }, // ARABIC LIGATURE SEEN WITH REH ISOLATED FORM + { 0xFD0F, BIDI_AL }, // ARABIC LIGATURE SAD WITH REH ISOLATED FORM + { 0xFD10, BIDI_AL }, // ARABIC LIGATURE DAD WITH REH ISOLATED FORM + { 0xFD11, BIDI_AL }, // ARABIC LIGATURE TAH WITH ALEF MAKSURA FINAL FORM + { 0xFD12, BIDI_AL }, // ARABIC LIGATURE TAH WITH YEH FINAL FORM + { 0xFD13, BIDI_AL }, // ARABIC LIGATURE AIN WITH ALEF MAKSURA FINAL FORM + { 0xFD14, BIDI_AL }, // ARABIC LIGATURE AIN WITH YEH FINAL FORM + { 0xFD15, BIDI_AL }, // ARABIC LIGATURE GHAIN WITH ALEF MAKSURA FINAL FORM + { 0xFD16, BIDI_AL }, // ARABIC LIGATURE GHAIN WITH YEH FINAL FORM + { 0xFD17, BIDI_AL }, // ARABIC LIGATURE SEEN WITH ALEF MAKSURA FINAL FORM + { 0xFD18, BIDI_AL }, // ARABIC LIGATURE SEEN WITH YEH FINAL FORM + { 0xFD19, BIDI_AL }, // ARABIC LIGATURE SHEEN WITH ALEF MAKSURA FINAL FORM + { 0xFD1A, BIDI_AL }, // ARABIC LIGATURE SHEEN WITH YEH FINAL FORM + { 0xFD1B, BIDI_AL }, // ARABIC LIGATURE HAH WITH ALEF MAKSURA FINAL FORM + { 0xFD1C, BIDI_AL }, // ARABIC LIGATURE HAH WITH YEH FINAL FORM + { 0xFD1D, BIDI_AL }, // ARABIC LIGATURE JEEM WITH ALEF MAKSURA FINAL FORM + { 0xFD1E, BIDI_AL }, // ARABIC LIGATURE JEEM WITH YEH FINAL FORM + { 0xFD1F, BIDI_AL }, // ARABIC LIGATURE KHAH WITH ALEF MAKSURA FINAL FORM + { 0xFD20, BIDI_AL }, // ARABIC LIGATURE KHAH WITH YEH FINAL FORM + { 0xFD21, BIDI_AL }, // ARABIC LIGATURE SAD WITH ALEF MAKSURA FINAL FORM + { 0xFD22, BIDI_AL }, // ARABIC LIGATURE SAD WITH YEH FINAL FORM + { 0xFD23, BIDI_AL }, // ARABIC LIGATURE DAD WITH ALEF MAKSURA FINAL FORM + { 0xFD24, BIDI_AL }, // ARABIC LIGATURE DAD WITH YEH FINAL FORM + { 0xFD25, BIDI_AL }, // ARABIC LIGATURE SHEEN WITH JEEM FINAL FORM + { 0xFD26, BIDI_AL }, // ARABIC LIGATURE SHEEN WITH HAH FINAL FORM + { 0xFD27, BIDI_AL }, // ARABIC LIGATURE SHEEN WITH KHAH FINAL FORM + { 0xFD28, BIDI_AL }, // ARABIC LIGATURE SHEEN WITH MEEM FINAL FORM + { 0xFD29, BIDI_AL }, // ARABIC LIGATURE SHEEN WITH REH FINAL FORM + { 0xFD2A, BIDI_AL }, // ARABIC LIGATURE SEEN WITH REH FINAL FORM + { 0xFD2B, BIDI_AL }, // ARABIC LIGATURE SAD WITH REH FINAL FORM + { 0xFD2C, BIDI_AL }, // ARABIC LIGATURE DAD WITH REH FINAL FORM + { 0xFD2D, BIDI_AL }, // ARABIC LIGATURE SHEEN WITH JEEM INITIAL FORM + { 0xFD2E, BIDI_AL }, // ARABIC LIGATURE SHEEN WITH HAH INITIAL FORM + { 0xFD2F, BIDI_AL }, // ARABIC LIGATURE SHEEN WITH KHAH INITIAL FORM + { 0xFD30, BIDI_AL }, // ARABIC LIGATURE SHEEN WITH MEEM INITIAL FORM + { 0xFD31, BIDI_AL }, // ARABIC LIGATURE SEEN WITH HEH INITIAL FORM + { 0xFD32, BIDI_AL }, // ARABIC LIGATURE SHEEN WITH HEH INITIAL FORM + { 0xFD33, BIDI_AL }, // ARABIC LIGATURE TAH WITH MEEM INITIAL FORM + { 0xFD34, BIDI_AL }, // ARABIC LIGATURE SEEN WITH JEEM MEDIAL FORM + { 0xFD35, BIDI_AL }, // ARABIC LIGATURE SEEN WITH HAH MEDIAL FORM + { 0xFD36, BIDI_AL }, // ARABIC LIGATURE SEEN WITH KHAH MEDIAL FORM + { 0xFD37, BIDI_AL }, // ARABIC LIGATURE SHEEN WITH JEEM MEDIAL FORM + { 0xFD38, BIDI_AL }, // ARABIC LIGATURE SHEEN WITH HAH MEDIAL FORM + { 0xFD39, BIDI_AL }, // ARABIC LIGATURE SHEEN WITH KHAH MEDIAL FORM + { 0xFD3A, BIDI_AL }, // ARABIC LIGATURE TAH WITH MEEM MEDIAL FORM + { 0xFD3B, BIDI_AL }, // ARABIC LIGATURE ZAH WITH MEEM MEDIAL FORM + { 0xFD3C, BIDI_AL }, // ARABIC LIGATURE ALEF WITH FATHATAN FINAL FORM + { 0xFD3D, BIDI_AL }, // ARABIC LIGATURE ALEF WITH FATHATAN ISOLATED FORM + { 0xFD3E, BIDI_ON }, // ORNATE LEFT PARENTHESIS + { 0xFD3F, BIDI_ON }, // ORNATE RIGHT PARENTHESIS + { 0xFD50, BIDI_AL }, // ARABIC LIGATURE TEH WITH JEEM WITH MEEM INITIAL FORM + { 0xFD51, BIDI_AL }, // ARABIC LIGATURE TEH WITH HAH WITH JEEM FINAL FORM + { 0xFD52, BIDI_AL }, // ARABIC LIGATURE TEH WITH HAH WITH JEEM INITIAL FORM + { 0xFD53, BIDI_AL }, // ARABIC LIGATURE TEH WITH HAH WITH MEEM INITIAL FORM + { 0xFD54, BIDI_AL }, // ARABIC LIGATURE TEH WITH KHAH WITH MEEM INITIAL FORM + { 0xFD55, BIDI_AL }, // ARABIC LIGATURE TEH WITH MEEM WITH JEEM INITIAL FORM + { 0xFD56, BIDI_AL }, // ARABIC LIGATURE TEH WITH MEEM WITH HAH INITIAL FORM + { 0xFD57, BIDI_AL }, // ARABIC LIGATURE TEH WITH MEEM WITH KHAH INITIAL FORM + { 0xFD58, BIDI_AL }, // ARABIC LIGATURE JEEM WITH MEEM WITH HAH FINAL FORM + { 0xFD59, BIDI_AL }, // ARABIC LIGATURE JEEM WITH MEEM WITH HAH INITIAL FORM + { 0xFD5A, BIDI_AL }, // ARABIC LIGATURE HAH WITH MEEM WITH YEH FINAL FORM + { 0xFD5B, BIDI_AL }, // ARABIC LIGATURE HAH WITH MEEM WITH ALEF MAKSURA FINAL FORM + { 0xFD5C, BIDI_AL }, // ARABIC LIGATURE SEEN WITH HAH WITH JEEM INITIAL FORM + { 0xFD5D, BIDI_AL }, // ARABIC LIGATURE SEEN WITH JEEM WITH HAH INITIAL FORM + { 0xFD5E, BIDI_AL }, // ARABIC LIGATURE SEEN WITH JEEM WITH ALEF MAKSURA FINAL FORM + { 0xFD5F, BIDI_AL }, // ARABIC LIGATURE SEEN WITH MEEM WITH HAH FINAL FORM + { 0xFD60, BIDI_AL }, // ARABIC LIGATURE SEEN WITH MEEM WITH HAH INITIAL FORM + { 0xFD61, BIDI_AL }, // ARABIC LIGATURE SEEN WITH MEEM WITH JEEM INITIAL FORM + { 0xFD62, BIDI_AL }, // ARABIC LIGATURE SEEN WITH MEEM WITH MEEM FINAL FORM + { 0xFD63, BIDI_AL }, // ARABIC LIGATURE SEEN WITH MEEM WITH MEEM INITIAL FORM + { 0xFD64, BIDI_AL }, // ARABIC LIGATURE SAD WITH HAH WITH HAH FINAL FORM + { 0xFD65, BIDI_AL }, // ARABIC LIGATURE SAD WITH HAH WITH HAH INITIAL FORM + { 0xFD66, BIDI_AL }, // ARABIC LIGATURE SAD WITH MEEM WITH MEEM FINAL FORM + { 0xFD67, BIDI_AL }, // ARABIC LIGATURE SHEEN WITH HAH WITH MEEM FINAL FORM + { 0xFD68, BIDI_AL }, // ARABIC LIGATURE SHEEN WITH HAH WITH MEEM INITIAL FORM + { 0xFD69, BIDI_AL }, // ARABIC LIGATURE SHEEN WITH JEEM WITH YEH FINAL FORM + { 0xFD6A, BIDI_AL }, // ARABIC LIGATURE SHEEN WITH MEEM WITH KHAH FINAL FORM + { 0xFD6B, BIDI_AL }, // ARABIC LIGATURE SHEEN WITH MEEM WITH KHAH INITIAL FORM + { 0xFD6C, BIDI_AL }, // ARABIC LIGATURE SHEEN WITH MEEM WITH MEEM FINAL FORM + { 0xFD6D, BIDI_AL }, // ARABIC LIGATURE SHEEN WITH MEEM WITH MEEM INITIAL FORM + { 0xFD6E, BIDI_AL }, // ARABIC LIGATURE DAD WITH HAH WITH ALEF MAKSURA FINAL FORM + { 0xFD6F, BIDI_AL }, // ARABIC LIGATURE DAD WITH KHAH WITH MEEM FINAL FORM + { 0xFD70, BIDI_AL }, // ARABIC LIGATURE DAD WITH KHAH WITH MEEM INITIAL FORM + { 0xFD71, BIDI_AL }, // ARABIC LIGATURE TAH WITH MEEM WITH HAH FINAL FORM + { 0xFD72, BIDI_AL }, // ARABIC LIGATURE TAH WITH MEEM WITH HAH INITIAL FORM + { 0xFD73, BIDI_AL }, // ARABIC LIGATURE TAH WITH MEEM WITH MEEM INITIAL FORM + { 0xFD74, BIDI_AL }, // ARABIC LIGATURE TAH WITH MEEM WITH YEH FINAL FORM + { 0xFD75, BIDI_AL }, // ARABIC LIGATURE AIN WITH JEEM WITH MEEM FINAL FORM + { 0xFD76, BIDI_AL }, // ARABIC LIGATURE AIN WITH MEEM WITH MEEM FINAL FORM + { 0xFD77, BIDI_AL }, // ARABIC LIGATURE AIN WITH MEEM WITH MEEM INITIAL FORM + { 0xFD78, BIDI_AL }, // ARABIC LIGATURE AIN WITH MEEM WITH ALEF MAKSURA FINAL FORM + { 0xFD79, BIDI_AL }, // ARABIC LIGATURE GHAIN WITH MEEM WITH MEEM FINAL FORM + { 0xFD7A, BIDI_AL }, // ARABIC LIGATURE GHAIN WITH MEEM WITH YEH FINAL FORM + { 0xFD7B, BIDI_AL }, // ARABIC LIGATURE GHAIN WITH MEEM WITH ALEF MAKSURA FINAL FORM + { 0xFD7C, BIDI_AL }, // ARABIC LIGATURE FEH WITH KHAH WITH MEEM FINAL FORM + { 0xFD7D, BIDI_AL }, // ARABIC LIGATURE FEH WITH KHAH WITH MEEM INITIAL FORM + { 0xFD7E, BIDI_AL }, // ARABIC LIGATURE QAF WITH MEEM WITH HAH FINAL FORM + { 0xFD7F, BIDI_AL }, // ARABIC LIGATURE QAF WITH MEEM WITH MEEM FINAL FORM + { 0xFD80, BIDI_AL }, // ARABIC LIGATURE LAM WITH HAH WITH MEEM FINAL FORM + { 0xFD81, BIDI_AL }, // ARABIC LIGATURE LAM WITH HAH WITH YEH FINAL FORM + { 0xFD82, BIDI_AL }, // ARABIC LIGATURE LAM WITH HAH WITH ALEF MAKSURA FINAL FORM + { 0xFD83, BIDI_AL }, // ARABIC LIGATURE LAM WITH JEEM WITH JEEM INITIAL FORM + { 0xFD84, BIDI_AL }, // ARABIC LIGATURE LAM WITH JEEM WITH JEEM FINAL FORM + { 0xFD85, BIDI_AL }, // ARABIC LIGATURE LAM WITH KHAH WITH MEEM FINAL FORM + { 0xFD86, BIDI_AL }, // ARABIC LIGATURE LAM WITH KHAH WITH MEEM INITIAL FORM + { 0xFD87, BIDI_AL }, // ARABIC LIGATURE LAM WITH MEEM WITH HAH FINAL FORM + { 0xFD88, BIDI_AL }, // ARABIC LIGATURE LAM WITH MEEM WITH HAH INITIAL FORM + { 0xFD89, BIDI_AL }, // ARABIC LIGATURE MEEM WITH HAH WITH JEEM INITIAL FORM + { 0xFD8A, BIDI_AL }, // ARABIC LIGATURE MEEM WITH HAH WITH MEEM INITIAL FORM + { 0xFD8B, BIDI_AL }, // ARABIC LIGATURE MEEM WITH HAH WITH YEH FINAL FORM + { 0xFD8C, BIDI_AL }, // ARABIC LIGATURE MEEM WITH JEEM WITH HAH INITIAL FORM + { 0xFD8D, BIDI_AL }, // ARABIC LIGATURE MEEM WITH JEEM WITH MEEM INITIAL FORM + { 0xFD8E, BIDI_AL }, // ARABIC LIGATURE MEEM WITH KHAH WITH JEEM INITIAL FORM + { 0xFD8F, BIDI_AL }, // ARABIC LIGATURE MEEM WITH KHAH WITH MEEM INITIAL FORM + { 0xFD92, BIDI_AL }, // ARABIC LIGATURE MEEM WITH JEEM WITH KHAH INITIAL FORM + { 0xFD93, BIDI_AL }, // ARABIC LIGATURE HEH WITH MEEM WITH JEEM INITIAL FORM + { 0xFD94, BIDI_AL }, // ARABIC LIGATURE HEH WITH MEEM WITH MEEM INITIAL FORM + { 0xFD95, BIDI_AL }, // ARABIC LIGATURE NOON WITH HAH WITH MEEM INITIAL FORM + { 0xFD96, BIDI_AL }, // ARABIC LIGATURE NOON WITH HAH WITH ALEF MAKSURA FINAL FORM + { 0xFD97, BIDI_AL }, // ARABIC LIGATURE NOON WITH JEEM WITH MEEM FINAL FORM + { 0xFD98, BIDI_AL }, // ARABIC LIGATURE NOON WITH JEEM WITH MEEM INITIAL FORM + { 0xFD99, BIDI_AL }, // ARABIC LIGATURE NOON WITH JEEM WITH ALEF MAKSURA FINAL FORM + { 0xFD9A, BIDI_AL }, // ARABIC LIGATURE NOON WITH MEEM WITH YEH FINAL FORM + { 0xFD9B, BIDI_AL }, // ARABIC LIGATURE NOON WITH MEEM WITH ALEF MAKSURA FINAL FORM + { 0xFD9C, BIDI_AL }, // ARABIC LIGATURE YEH WITH MEEM WITH MEEM FINAL FORM + { 0xFD9D, BIDI_AL }, // ARABIC LIGATURE YEH WITH MEEM WITH MEEM INITIAL FORM + { 0xFD9E, BIDI_AL }, // ARABIC LIGATURE BEH WITH KHAH WITH YEH FINAL FORM + { 0xFD9F, BIDI_AL }, // ARABIC LIGATURE TEH WITH JEEM WITH YEH FINAL FORM + { 0xFDA0, BIDI_AL }, // ARABIC LIGATURE TEH WITH JEEM WITH ALEF MAKSURA FINAL FORM + { 0xFDA1, BIDI_AL }, // ARABIC LIGATURE TEH WITH KHAH WITH YEH FINAL FORM + { 0xFDA2, BIDI_AL }, // ARABIC LIGATURE TEH WITH KHAH WITH ALEF MAKSURA FINAL FORM + { 0xFDA3, BIDI_AL }, // ARABIC LIGATURE TEH WITH MEEM WITH YEH FINAL FORM + { 0xFDA4, BIDI_AL }, // ARABIC LIGATURE TEH WITH MEEM WITH ALEF MAKSURA FINAL FORM + { 0xFDA5, BIDI_AL }, // ARABIC LIGATURE JEEM WITH MEEM WITH YEH FINAL FORM + { 0xFDA6, BIDI_AL }, // ARABIC LIGATURE JEEM WITH HAH WITH ALEF MAKSURA FINAL FORM + { 0xFDA7, BIDI_AL }, // ARABIC LIGATURE JEEM WITH MEEM WITH ALEF MAKSURA FINAL FORM + { 0xFDA8, BIDI_AL }, // ARABIC LIGATURE SEEN WITH KHAH WITH ALEF MAKSURA FINAL FORM + { 0xFDA9, BIDI_AL }, // ARABIC LIGATURE SAD WITH HAH WITH YEH FINAL FORM + { 0xFDAA, BIDI_AL }, // ARABIC LIGATURE SHEEN WITH HAH WITH YEH FINAL FORM + { 0xFDAB, BIDI_AL }, // ARABIC LIGATURE DAD WITH HAH WITH YEH FINAL FORM + { 0xFDAC, BIDI_AL }, // ARABIC LIGATURE LAM WITH JEEM WITH YEH FINAL FORM + { 0xFDAD, BIDI_AL }, // ARABIC LIGATURE LAM WITH MEEM WITH YEH FINAL FORM + { 0xFDAE, BIDI_AL }, // ARABIC LIGATURE YEH WITH HAH WITH YEH FINAL FORM + { 0xFDAF, BIDI_AL }, // ARABIC LIGATURE YEH WITH JEEM WITH YEH FINAL FORM + { 0xFDB0, BIDI_AL }, // ARABIC LIGATURE YEH WITH MEEM WITH YEH FINAL FORM + { 0xFDB1, BIDI_AL }, // ARABIC LIGATURE MEEM WITH MEEM WITH YEH FINAL FORM + { 0xFDB2, BIDI_AL }, // ARABIC LIGATURE QAF WITH MEEM WITH YEH FINAL FORM + { 0xFDB3, BIDI_AL }, // ARABIC LIGATURE NOON WITH HAH WITH YEH FINAL FORM + { 0xFDB4, BIDI_AL }, // ARABIC LIGATURE QAF WITH MEEM WITH HAH INITIAL FORM + { 0xFDB5, BIDI_AL }, // ARABIC LIGATURE LAM WITH HAH WITH MEEM INITIAL FORM + { 0xFDB6, BIDI_AL }, // ARABIC LIGATURE AIN WITH MEEM WITH YEH FINAL FORM + { 0xFDB7, BIDI_AL }, // ARABIC LIGATURE KAF WITH MEEM WITH YEH FINAL FORM + { 0xFDB8, BIDI_AL }, // ARABIC LIGATURE NOON WITH JEEM WITH HAH INITIAL FORM + { 0xFDB9, BIDI_AL }, // ARABIC LIGATURE MEEM WITH KHAH WITH YEH FINAL FORM + { 0xFDBA, BIDI_AL }, // ARABIC LIGATURE LAM WITH JEEM WITH MEEM INITIAL FORM + { 0xFDBB, BIDI_AL }, // ARABIC LIGATURE KAF WITH MEEM WITH MEEM FINAL FORM + { 0xFDBC, BIDI_AL }, // ARABIC LIGATURE LAM WITH JEEM WITH MEEM FINAL FORM + { 0xFDBD, BIDI_AL }, // ARABIC LIGATURE NOON WITH JEEM WITH HAH FINAL FORM + { 0xFDBE, BIDI_AL }, // ARABIC LIGATURE JEEM WITH HAH WITH YEH FINAL FORM + { 0xFDBF, BIDI_AL }, // ARABIC LIGATURE HAH WITH JEEM WITH YEH FINAL FORM + { 0xFDC0, BIDI_AL }, // ARABIC LIGATURE MEEM WITH JEEM WITH YEH FINAL FORM + { 0xFDC1, BIDI_AL }, // ARABIC LIGATURE FEH WITH MEEM WITH YEH FINAL FORM + { 0xFDC2, BIDI_AL }, // ARABIC LIGATURE BEH WITH HAH WITH YEH FINAL FORM + { 0xFDC3, BIDI_AL }, // ARABIC LIGATURE KAF WITH MEEM WITH MEEM INITIAL FORM + { 0xFDC4, BIDI_AL }, // ARABIC LIGATURE AIN WITH JEEM WITH MEEM INITIAL FORM + { 0xFDC5, BIDI_AL }, // ARABIC LIGATURE SAD WITH MEEM WITH MEEM INITIAL FORM + { 0xFDC6, BIDI_AL }, // ARABIC LIGATURE SEEN WITH KHAH WITH YEH FINAL FORM + { 0xFDC7, BIDI_AL }, // ARABIC LIGATURE NOON WITH JEEM WITH YEH FINAL FORM + { 0xFDF0, BIDI_AL }, // ARABIC LIGATURE SALLA USED AS KORANIC STOP SIGN ISOLATED FORM + { 0xFDF1, BIDI_AL }, // ARABIC LIGATURE QALA USED AS KORANIC STOP SIGN ISOLATED FORM + { 0xFDF2, BIDI_AL }, // ARABIC LIGATURE ALLAH ISOLATED FORM + { 0xFDF3, BIDI_AL }, // ARABIC LIGATURE AKBAR ISOLATED FORM + { 0xFDF4, BIDI_AL }, // ARABIC LIGATURE MOHAMMAD ISOLATED FORM + { 0xFDF5, BIDI_AL }, // ARABIC LIGATURE SALAM ISOLATED FORM + { 0xFDF6, BIDI_AL }, // ARABIC LIGATURE RASOUL ISOLATED FORM + { 0xFDF7, BIDI_AL }, // ARABIC LIGATURE ALAYHE ISOLATED FORM + { 0xFDF8, BIDI_AL }, // ARABIC LIGATURE WASALLAM ISOLATED FORM + { 0xFDF9, BIDI_AL }, // ARABIC LIGATURE SALLA ISOLATED FORM + { 0xFDFA, BIDI_AL }, // ARABIC LIGATURE SALLALLAHOU ALAYHE WASALLAM + { 0xFDFB, BIDI_AL }, // ARABIC LIGATURE JALLAJALALOUHOU + { 0xFDFC, BIDI_AL }, // RIAL SIGN + { 0xFDFD, BIDI_ON }, // ARABIC LIGATURE BISMILLAH AR-RAHMAN AR-RAHEEM + { 0xFE00, BIDI_NSM }, // VARIATION SELECTOR-1 + { 0xFE01, BIDI_NSM }, // VARIATION SELECTOR-2 + { 0xFE02, BIDI_NSM }, // VARIATION SELECTOR-3 + { 0xFE03, BIDI_NSM }, // VARIATION SELECTOR-4 + { 0xFE04, BIDI_NSM }, // VARIATION SELECTOR-5 + { 0xFE05, BIDI_NSM }, // VARIATION SELECTOR-6 + { 0xFE06, BIDI_NSM }, // VARIATION SELECTOR-7 + { 0xFE07, BIDI_NSM }, // VARIATION SELECTOR-8 + { 0xFE08, BIDI_NSM }, // VARIATION SELECTOR-9 + { 0xFE09, BIDI_NSM }, // VARIATION SELECTOR-10 + { 0xFE0A, BIDI_NSM }, // VARIATION SELECTOR-11 + { 0xFE0B, BIDI_NSM }, // VARIATION SELECTOR-12 + { 0xFE0C, BIDI_NSM }, // VARIATION SELECTOR-13 + { 0xFE0D, BIDI_NSM }, // VARIATION SELECTOR-14 + { 0xFE0E, BIDI_NSM }, // VARIATION SELECTOR-15 + { 0xFE0F, BIDI_NSM }, // VARIATION SELECTOR-16 + { 0xFE10, BIDI_ON }, // PRESENTATION FORM FOR VERTICAL COMMA + { 0xFE11, BIDI_ON }, // PRESENTATION FORM FOR VERTICAL IDEOGRAPHIC COMMA + { 0xFE12, BIDI_ON }, // PRESENTATION FORM FOR VERTICAL IDEOGRAPHIC FULL STOP + { 0xFE13, BIDI_ON }, // PRESENTATION FORM FOR VERTICAL COLON + { 0xFE14, BIDI_ON }, // PRESENTATION FORM FOR VERTICAL SEMICOLON + { 0xFE15, BIDI_ON }, // PRESENTATION FORM FOR VERTICAL EXCLAMATION MARK + { 0xFE16, BIDI_ON }, // PRESENTATION FORM FOR VERTICAL QUESTION MARK + { 0xFE17, BIDI_ON }, // PRESENTATION FORM FOR VERTICAL LEFT WHITE LENTICULAR BRACKET + { 0xFE18, BIDI_ON }, // PRESENTATION FORM FOR VERTICAL RIGHT WHITE LENTICULAR BRAKCET + { 0xFE19, BIDI_ON }, // PRESENTATION FORM FOR VERTICAL HORIZONTAL ELLIPSIS + { 0xFE20, BIDI_NSM }, // COMBINING LIGATURE LEFT HALF + { 0xFE21, BIDI_NSM }, // COMBINING LIGATURE RIGHT HALF + { 0xFE22, BIDI_NSM }, // COMBINING DOUBLE TILDE LEFT HALF + { 0xFE23, BIDI_NSM }, // COMBINING DOUBLE TILDE RIGHT HALF + { 0xFE24, BIDI_NSM }, // COMBINING MACRON LEFT HALF + { 0xFE25, BIDI_NSM }, // COMBINING MACRON RIGHT HALF + { 0xFE26, BIDI_NSM }, // COMBINING CONJOINING MACRON + { 0xFE27, BIDI_NSM }, // COMBINING LIGATURE LEFT HALF BELOW + { 0xFE28, BIDI_NSM }, // COMBINING LIGATURE RIGHT HALF BELOW + { 0xFE29, BIDI_NSM }, // COMBINING TILDE LEFT HALF BELOW + { 0xFE2A, BIDI_NSM }, // COMBINING TILDE RIGHT HALF BELOW + { 0xFE2B, BIDI_NSM }, // COMBINING MACRON LEFT HALF BELOW + { 0xFE2C, BIDI_NSM }, // COMBINING MACRON RIGHT HALF BELOW + { 0xFE2D, BIDI_NSM }, // COMBINING CONJOINING MACRON BELOW + { 0xFE2E, BIDI_NSM }, // COMBINING CYRILLIC TITLO LEFT HALF + { 0xFE2F, BIDI_NSM }, // COMBINING CYRILLIC TITLO RIGHT HALF + { 0xFE30, BIDI_ON }, // PRESENTATION FORM FOR VERTICAL TWO DOT LEADER + { 0xFE31, BIDI_ON }, // PRESENTATION FORM FOR VERTICAL EM DASH + { 0xFE32, BIDI_ON }, // PRESENTATION FORM FOR VERTICAL EN DASH + { 0xFE33, BIDI_ON }, // PRESENTATION FORM FOR VERTICAL LOW LINE + { 0xFE34, BIDI_ON }, // PRESENTATION FORM FOR VERTICAL WAVY LOW LINE + { 0xFE35, BIDI_ON }, // PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS + { 0xFE36, BIDI_ON }, // PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS + { 0xFE37, BIDI_ON }, // PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET + { 0xFE38, BIDI_ON }, // PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET + { 0xFE39, BIDI_ON }, // PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET + { 0xFE3A, BIDI_ON }, // PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET + { 0xFE3B, BIDI_ON }, // PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET + { 0xFE3C, BIDI_ON }, // PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET + { 0xFE3D, BIDI_ON }, // PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET + { 0xFE3E, BIDI_ON }, // PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET + { 0xFE3F, BIDI_ON }, // PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET + { 0xFE40, BIDI_ON }, // PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET + { 0xFE41, BIDI_ON }, // PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET + { 0xFE42, BIDI_ON }, // PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET + { 0xFE43, BIDI_ON }, // PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET + { 0xFE44, BIDI_ON }, // PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET + { 0xFE45, BIDI_ON }, // SESAME DOT + { 0xFE46, BIDI_ON }, // WHITE SESAME DOT + { 0xFE47, BIDI_ON }, // PRESENTATION FORM FOR VERTICAL LEFT SQUARE BRACKET + { 0xFE48, BIDI_ON }, // PRESENTATION FORM FOR VERTICAL RIGHT SQUARE BRACKET + { 0xFE49, BIDI_ON }, // DASHED OVERLINE + { 0xFE4A, BIDI_ON }, // CENTRELINE OVERLINE + { 0xFE4B, BIDI_ON }, // WAVY OVERLINE + { 0xFE4C, BIDI_ON }, // DOUBLE WAVY OVERLINE + { 0xFE4D, BIDI_ON }, // DASHED LOW LINE + { 0xFE4E, BIDI_ON }, // CENTRELINE LOW LINE + { 0xFE4F, BIDI_ON }, // WAVY LOW LINE + { 0xFE50, BIDI_CS }, // SMALL COMMA + { 0xFE51, BIDI_ON }, // SMALL IDEOGRAPHIC COMMA + { 0xFE52, BIDI_CS }, // SMALL FULL STOP + { 0xFE54, BIDI_ON }, // SMALL SEMICOLON + { 0xFE55, BIDI_CS }, // SMALL COLON + { 0xFE56, BIDI_ON }, // SMALL QUESTION MARK + { 0xFE57, BIDI_ON }, // SMALL EXCLAMATION MARK + { 0xFE58, BIDI_ON }, // SMALL EM DASH + { 0xFE59, BIDI_ON }, // SMALL LEFT PARENTHESIS + { 0xFE5A, BIDI_ON }, // SMALL RIGHT PARENTHESIS + { 0xFE5B, BIDI_ON }, // SMALL LEFT CURLY BRACKET + { 0xFE5C, BIDI_ON }, // SMALL RIGHT CURLY BRACKET + { 0xFE5D, BIDI_ON }, // SMALL LEFT TORTOISE SHELL BRACKET + { 0xFE5E, BIDI_ON }, // SMALL RIGHT TORTOISE SHELL BRACKET + { 0xFE5F, BIDI_ET }, // SMALL NUMBER SIGN + { 0xFE60, BIDI_ON }, // SMALL AMPERSAND + { 0xFE61, BIDI_ON }, // SMALL ASTERISK + { 0xFE62, BIDI_ES }, // SMALL PLUS SIGN + { 0xFE63, BIDI_ES }, // SMALL HYPHEN-MINUS + { 0xFE64, BIDI_ON }, // SMALL LESS-THAN SIGN + { 0xFE65, BIDI_ON }, // SMALL GREATER-THAN SIGN + { 0xFE66, BIDI_ON }, // SMALL EQUALS SIGN + { 0xFE68, BIDI_ON }, // SMALL REVERSE SOLIDUS + { 0xFE69, BIDI_ET }, // SMALL DOLLAR SIGN + { 0xFE6A, BIDI_ET }, // SMALL PERCENT SIGN + { 0xFE6B, BIDI_ON }, // SMALL COMMERCIAL AT + { 0xFE70, BIDI_AL }, // ARABIC FATHATAN ISOLATED FORM + { 0xFE71, BIDI_AL }, // ARABIC TATWEEL WITH FATHATAN ABOVE + { 0xFE72, BIDI_AL }, // ARABIC DAMMATAN ISOLATED FORM + { 0xFE73, BIDI_AL }, // ARABIC TAIL FRAGMENT + { 0xFE74, BIDI_AL }, // ARABIC KASRATAN ISOLATED FORM + { 0xFE76, BIDI_AL }, // ARABIC FATHA ISOLATED FORM + { 0xFE77, BIDI_AL }, // ARABIC FATHA MEDIAL FORM + { 0xFE78, BIDI_AL }, // ARABIC DAMMA ISOLATED FORM + { 0xFE79, BIDI_AL }, // ARABIC DAMMA MEDIAL FORM + { 0xFE7A, BIDI_AL }, // ARABIC KASRA ISOLATED FORM + { 0xFE7B, BIDI_AL }, // ARABIC KASRA MEDIAL FORM + { 0xFE7C, BIDI_AL }, // ARABIC SHADDA ISOLATED FORM + { 0xFE7D, BIDI_AL }, // ARABIC SHADDA MEDIAL FORM + { 0xFE7E, BIDI_AL }, // ARABIC SUKUN ISOLATED FORM + { 0xFE7F, BIDI_AL }, // ARABIC SUKUN MEDIAL FORM + { 0xFE80, BIDI_AL }, // ARABIC LETTER HAMZA ISOLATED FORM + { 0xFE81, BIDI_AL }, // ARABIC LETTER ALEF WITH MADDA ABOVE ISOLATED FORM + { 0xFE82, BIDI_AL }, // ARABIC LETTER ALEF WITH MADDA ABOVE FINAL FORM + { 0xFE83, BIDI_AL }, // ARABIC LETTER ALEF WITH HAMZA ABOVE ISOLATED FORM + { 0xFE84, BIDI_AL }, // ARABIC LETTER ALEF WITH HAMZA ABOVE FINAL FORM + { 0xFE85, BIDI_AL }, // ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM + { 0xFE86, BIDI_AL }, // ARABIC LETTER WAW WITH HAMZA ABOVE FINAL FORM + { 0xFE87, BIDI_AL }, // ARABIC LETTER ALEF WITH HAMZA BELOW ISOLATED FORM + { 0xFE88, BIDI_AL }, // ARABIC LETTER ALEF WITH HAMZA BELOW FINAL FORM + { 0xFE89, BIDI_AL }, // ARABIC LETTER YEH WITH HAMZA ABOVE ISOLATED FORM + { 0xFE8A, BIDI_AL }, // ARABIC LETTER YEH WITH HAMZA ABOVE FINAL FORM + { 0xFE8B, BIDI_AL }, // ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM + { 0xFE8C, BIDI_AL }, // ARABIC LETTER YEH WITH HAMZA ABOVE MEDIAL FORM + { 0xFE8D, BIDI_AL }, // ARABIC LETTER ALEF ISOLATED FORM + { 0xFE8E, BIDI_AL }, // ARABIC LETTER ALEF FINAL FORM + { 0xFE8F, BIDI_AL }, // ARABIC LETTER BEH ISOLATED FORM + { 0xFE90, BIDI_AL }, // ARABIC LETTER BEH FINAL FORM + { 0xFE91, BIDI_AL }, // ARABIC LETTER BEH INITIAL FORM + { 0xFE92, BIDI_AL }, // ARABIC LETTER BEH MEDIAL FORM + { 0xFE93, BIDI_AL }, // ARABIC LETTER TEH MARBUTA ISOLATED FORM + { 0xFE94, BIDI_AL }, // ARABIC LETTER TEH MARBUTA FINAL FORM + { 0xFE95, BIDI_AL }, // ARABIC LETTER TEH ISOLATED FORM + { 0xFE96, BIDI_AL }, // ARABIC LETTER TEH FINAL FORM + { 0xFE97, BIDI_AL }, // ARABIC LETTER TEH INITIAL FORM + { 0xFE98, BIDI_AL }, // ARABIC LETTER TEH MEDIAL FORM + { 0xFE99, BIDI_AL }, // ARABIC LETTER THEH ISOLATED FORM + { 0xFE9A, BIDI_AL }, // ARABIC LETTER THEH FINAL FORM + { 0xFE9B, BIDI_AL }, // ARABIC LETTER THEH INITIAL FORM + { 0xFE9C, BIDI_AL }, // ARABIC LETTER THEH MEDIAL FORM + { 0xFE9D, BIDI_AL }, // ARABIC LETTER JEEM ISOLATED FORM + { 0xFE9E, BIDI_AL }, // ARABIC LETTER JEEM FINAL FORM + { 0xFE9F, BIDI_AL }, // ARABIC LETTER JEEM INITIAL FORM + { 0xFEA0, BIDI_AL }, // ARABIC LETTER JEEM MEDIAL FORM + { 0xFEA1, BIDI_AL }, // ARABIC LETTER HAH ISOLATED FORM + { 0xFEA2, BIDI_AL }, // ARABIC LETTER HAH FINAL FORM + { 0xFEA3, BIDI_AL }, // ARABIC LETTER HAH INITIAL FORM + { 0xFEA4, BIDI_AL }, // ARABIC LETTER HAH MEDIAL FORM + { 0xFEA5, BIDI_AL }, // ARABIC LETTER KHAH ISOLATED FORM + { 0xFEA6, BIDI_AL }, // ARABIC LETTER KHAH FINAL FORM + { 0xFEA7, BIDI_AL }, // ARABIC LETTER KHAH INITIAL FORM + { 0xFEA8, BIDI_AL }, // ARABIC LETTER KHAH MEDIAL FORM + { 0xFEA9, BIDI_AL }, // ARABIC LETTER DAL ISOLATED FORM + { 0xFEAA, BIDI_AL }, // ARABIC LETTER DAL FINAL FORM + { 0xFEAB, BIDI_AL }, // ARABIC LETTER THAL ISOLATED FORM + { 0xFEAC, BIDI_AL }, // ARABIC LETTER THAL FINAL FORM + { 0xFEAD, BIDI_AL }, // ARABIC LETTER REH ISOLATED FORM + { 0xFEAE, BIDI_AL }, // ARABIC LETTER REH FINAL FORM + { 0xFEAF, BIDI_AL }, // ARABIC LETTER ZAIN ISOLATED FORM + { 0xFEB0, BIDI_AL }, // ARABIC LETTER ZAIN FINAL FORM + { 0xFEB1, BIDI_AL }, // ARABIC LETTER SEEN ISOLATED FORM + { 0xFEB2, BIDI_AL }, // ARABIC LETTER SEEN FINAL FORM + { 0xFEB3, BIDI_AL }, // ARABIC LETTER SEEN INITIAL FORM + { 0xFEB4, BIDI_AL }, // ARABIC LETTER SEEN MEDIAL FORM + { 0xFEB5, BIDI_AL }, // ARABIC LETTER SHEEN ISOLATED FORM + { 0xFEB6, BIDI_AL }, // ARABIC LETTER SHEEN FINAL FORM + { 0xFEB7, BIDI_AL }, // ARABIC LETTER SHEEN INITIAL FORM + { 0xFEB8, BIDI_AL }, // ARABIC LETTER SHEEN MEDIAL FORM + { 0xFEB9, BIDI_AL }, // ARABIC LETTER SAD ISOLATED FORM + { 0xFEBA, BIDI_AL }, // ARABIC LETTER SAD FINAL FORM + { 0xFEBB, BIDI_AL }, // ARABIC LETTER SAD INITIAL FORM + { 0xFEBC, BIDI_AL }, // ARABIC LETTER SAD MEDIAL FORM + { 0xFEBD, BIDI_AL }, // ARABIC LETTER DAD ISOLATED FORM + { 0xFEBE, BIDI_AL }, // ARABIC LETTER DAD FINAL FORM + { 0xFEBF, BIDI_AL }, // ARABIC LETTER DAD INITIAL FORM + { 0xFEC0, BIDI_AL }, // ARABIC LETTER DAD MEDIAL FORM + { 0xFEC1, BIDI_AL }, // ARABIC LETTER TAH ISOLATED FORM + { 0xFEC2, BIDI_AL }, // ARABIC LETTER TAH FINAL FORM + { 0xFEC3, BIDI_AL }, // ARABIC LETTER TAH INITIAL FORM + { 0xFEC4, BIDI_AL }, // ARABIC LETTER TAH MEDIAL FORM + { 0xFEC5, BIDI_AL }, // ARABIC LETTER ZAH ISOLATED FORM + { 0xFEC6, BIDI_AL }, // ARABIC LETTER ZAH FINAL FORM + { 0xFEC7, BIDI_AL }, // ARABIC LETTER ZAH INITIAL FORM + { 0xFEC8, BIDI_AL }, // ARABIC LETTER ZAH MEDIAL FORM + { 0xFEC9, BIDI_AL }, // ARABIC LETTER AIN ISOLATED FORM + { 0xFECA, BIDI_AL }, // ARABIC LETTER AIN FINAL FORM + { 0xFECB, BIDI_AL }, // ARABIC LETTER AIN INITIAL FORM + { 0xFECC, BIDI_AL }, // ARABIC LETTER AIN MEDIAL FORM + { 0xFECD, BIDI_AL }, // ARABIC LETTER GHAIN ISOLATED FORM + { 0xFECE, BIDI_AL }, // ARABIC LETTER GHAIN FINAL FORM + { 0xFECF, BIDI_AL }, // ARABIC LETTER GHAIN INITIAL FORM + { 0xFED0, BIDI_AL }, // ARABIC LETTER GHAIN MEDIAL FORM + { 0xFED1, BIDI_AL }, // ARABIC LETTER FEH ISOLATED FORM + { 0xFED2, BIDI_AL }, // ARABIC LETTER FEH FINAL FORM + { 0xFED3, BIDI_AL }, // ARABIC LETTER FEH INITIAL FORM + { 0xFED4, BIDI_AL }, // ARABIC LETTER FEH MEDIAL FORM + { 0xFED5, BIDI_AL }, // ARABIC LETTER QAF ISOLATED FORM + { 0xFED6, BIDI_AL }, // ARABIC LETTER QAF FINAL FORM + { 0xFED7, BIDI_AL }, // ARABIC LETTER QAF INITIAL FORM + { 0xFED8, BIDI_AL }, // ARABIC LETTER QAF MEDIAL FORM + { 0xFED9, BIDI_AL }, // ARABIC LETTER KAF ISOLATED FORM + { 0xFEDA, BIDI_AL }, // ARABIC LETTER KAF FINAL FORM + { 0xFEDB, BIDI_AL }, // ARABIC LETTER KAF INITIAL FORM + { 0xFEDC, BIDI_AL }, // ARABIC LETTER KAF MEDIAL FORM + { 0xFEDD, BIDI_AL }, // ARABIC LETTER LAM ISOLATED FORM + { 0xFEDE, BIDI_AL }, // ARABIC LETTER LAM FINAL FORM + { 0xFEDF, BIDI_AL }, // ARABIC LETTER LAM INITIAL FORM + { 0xFEE0, BIDI_AL }, // ARABIC LETTER LAM MEDIAL FORM + { 0xFEE1, BIDI_AL }, // ARABIC LETTER MEEM ISOLATED FORM + { 0xFEE2, BIDI_AL }, // ARABIC LETTER MEEM FINAL FORM + { 0xFEE3, BIDI_AL }, // ARABIC LETTER MEEM INITIAL FORM + { 0xFEE4, BIDI_AL }, // ARABIC LETTER MEEM MEDIAL FORM + { 0xFEE5, BIDI_AL }, // ARABIC LETTER NOON ISOLATED FORM + { 0xFEE6, BIDI_AL }, // ARABIC LETTER NOON FINAL FORM + { 0xFEE7, BIDI_AL }, // ARABIC LETTER NOON INITIAL FORM + { 0xFEE8, BIDI_AL }, // ARABIC LETTER NOON MEDIAL FORM + { 0xFEE9, BIDI_AL }, // ARABIC LETTER HEH ISOLATED FORM + { 0xFEEA, BIDI_AL }, // ARABIC LETTER HEH FINAL FORM + { 0xFEEB, BIDI_AL }, // ARABIC LETTER HEH INITIAL FORM + { 0xFEEC, BIDI_AL }, // ARABIC LETTER HEH MEDIAL FORM + { 0xFEED, BIDI_AL }, // ARABIC LETTER WAW ISOLATED FORM + { 0xFEEE, BIDI_AL }, // ARABIC LETTER WAW FINAL FORM + { 0xFEEF, BIDI_AL }, // ARABIC LETTER ALEF MAKSURA ISOLATED FORM + { 0xFEF0, BIDI_AL }, // ARABIC LETTER ALEF MAKSURA FINAL FORM + { 0xFEF1, BIDI_AL }, // ARABIC LETTER YEH ISOLATED FORM + { 0xFEF2, BIDI_AL }, // ARABIC LETTER YEH FINAL FORM + { 0xFEF3, BIDI_AL }, // ARABIC LETTER YEH INITIAL FORM + { 0xFEF4, BIDI_AL }, // ARABIC LETTER YEH MEDIAL FORM + { 0xFEF5, BIDI_AL }, // ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM + { 0xFEF6, BIDI_AL }, // ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM + { 0xFEF7, BIDI_AL }, // ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM + { 0xFEF8, BIDI_AL }, // ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM + { 0xFEF9, BIDI_AL }, // ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM + { 0xFEFA, BIDI_AL }, // ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW FINAL FORM + { 0xFEFB, BIDI_AL }, // ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM + { 0xFEFC, BIDI_AL }, // ARABIC LIGATURE LAM WITH ALEF FINAL FORM + { 0xFEFF, BIDI_BN }, // ZERO WIDTH NO-BREAK SPACE + { 0xFF01, BIDI_ON }, // FULLWIDTH EXCLAMATION MARK + { 0xFF02, BIDI_ON }, // FULLWIDTH QUOTATION MARK + { 0xFF03, BIDI_ET }, // FULLWIDTH NUMBER SIGN + { 0xFF04, BIDI_ET }, // FULLWIDTH DOLLAR SIGN + { 0xFF05, BIDI_ET }, // FULLWIDTH PERCENT SIGN + { 0xFF06, BIDI_ON }, // FULLWIDTH AMPERSAND + { 0xFF07, BIDI_ON }, // FULLWIDTH APOSTROPHE + { 0xFF08, BIDI_ON }, // FULLWIDTH LEFT PARENTHESIS + { 0xFF09, BIDI_ON }, // FULLWIDTH RIGHT PARENTHESIS + { 0xFF0A, BIDI_ON }, // FULLWIDTH ASTERISK + { 0xFF0B, BIDI_ES }, // FULLWIDTH PLUS SIGN + { 0xFF0C, BIDI_CS }, // FULLWIDTH COMMA + { 0xFF0D, BIDI_ES }, // FULLWIDTH HYPHEN-MINUS + { 0xFF0E, BIDI_CS }, // FULLWIDTH FULL STOP + { 0xFF0F, BIDI_CS }, // FULLWIDTH SOLIDUS + { 0xFF10, BIDI_EN }, // FULLWIDTH DIGIT ZERO + { 0xFF11, BIDI_EN }, // FULLWIDTH DIGIT ONE + { 0xFF12, BIDI_EN }, // FULLWIDTH DIGIT TWO + { 0xFF13, BIDI_EN }, // FULLWIDTH DIGIT THREE + { 0xFF14, BIDI_EN }, // FULLWIDTH DIGIT FOUR + { 0xFF15, BIDI_EN }, // FULLWIDTH DIGIT FIVE + { 0xFF16, BIDI_EN }, // FULLWIDTH DIGIT SIX + { 0xFF17, BIDI_EN }, // FULLWIDTH DIGIT SEVEN + { 0xFF18, BIDI_EN }, // FULLWIDTH DIGIT EIGHT + { 0xFF19, BIDI_EN }, // FULLWIDTH DIGIT NINE + { 0xFF1A, BIDI_CS }, // FULLWIDTH COLON + { 0xFF1B, BIDI_ON }, // FULLWIDTH SEMICOLON + { 0xFF1C, BIDI_ON }, // FULLWIDTH LESS-THAN SIGN + { 0xFF1D, BIDI_ON }, // FULLWIDTH EQUALS SIGN + { 0xFF1E, BIDI_ON }, // FULLWIDTH GREATER-THAN SIGN + { 0xFF1F, BIDI_ON }, // FULLWIDTH QUESTION MARK + { 0xFF20, BIDI_ON }, // FULLWIDTH COMMERCIAL AT + { 0xFF21, BIDI_L }, // FULLWIDTH LATIN CAPITAL LETTER A + { 0xFF22, BIDI_L }, // FULLWIDTH LATIN CAPITAL LETTER B + { 0xFF23, BIDI_L }, // FULLWIDTH LATIN CAPITAL LETTER C + { 0xFF24, BIDI_L }, // FULLWIDTH LATIN CAPITAL LETTER D + { 0xFF25, BIDI_L }, // FULLWIDTH LATIN CAPITAL LETTER E + { 0xFF26, BIDI_L }, // FULLWIDTH LATIN CAPITAL LETTER F + { 0xFF27, BIDI_L }, // FULLWIDTH LATIN CAPITAL LETTER G + { 0xFF28, BIDI_L }, // FULLWIDTH LATIN CAPITAL LETTER H + { 0xFF29, BIDI_L }, // FULLWIDTH LATIN CAPITAL LETTER I + { 0xFF2A, BIDI_L }, // FULLWIDTH LATIN CAPITAL LETTER J + { 0xFF2B, BIDI_L }, // FULLWIDTH LATIN CAPITAL LETTER K + { 0xFF2C, BIDI_L }, // FULLWIDTH LATIN CAPITAL LETTER L + { 0xFF2D, BIDI_L }, // FULLWIDTH LATIN CAPITAL LETTER M + { 0xFF2E, BIDI_L }, // FULLWIDTH LATIN CAPITAL LETTER N + { 0xFF2F, BIDI_L }, // FULLWIDTH LATIN CAPITAL LETTER O + { 0xFF30, BIDI_L }, // FULLWIDTH LATIN CAPITAL LETTER P + { 0xFF31, BIDI_L }, // FULLWIDTH LATIN CAPITAL LETTER Q + { 0xFF32, BIDI_L }, // FULLWIDTH LATIN CAPITAL LETTER R + { 0xFF33, BIDI_L }, // FULLWIDTH LATIN CAPITAL LETTER S + { 0xFF34, BIDI_L }, // FULLWIDTH LATIN CAPITAL LETTER T + { 0xFF35, BIDI_L }, // FULLWIDTH LATIN CAPITAL LETTER U + { 0xFF36, BIDI_L }, // FULLWIDTH LATIN CAPITAL LETTER V + { 0xFF37, BIDI_L }, // FULLWIDTH LATIN CAPITAL LETTER W + { 0xFF38, BIDI_L }, // FULLWIDTH LATIN CAPITAL LETTER X + { 0xFF39, BIDI_L }, // FULLWIDTH LATIN CAPITAL LETTER Y + { 0xFF3A, BIDI_L }, // FULLWIDTH LATIN CAPITAL LETTER Z + { 0xFF3B, BIDI_ON }, // FULLWIDTH LEFT SQUARE BRACKET + { 0xFF3C, BIDI_ON }, // FULLWIDTH REVERSE SOLIDUS + { 0xFF3D, BIDI_ON }, // FULLWIDTH RIGHT SQUARE BRACKET + { 0xFF3E, BIDI_ON }, // FULLWIDTH CIRCUMFLEX ACCENT + { 0xFF3F, BIDI_ON }, // FULLWIDTH LOW LINE + { 0xFF40, BIDI_ON }, // FULLWIDTH GRAVE ACCENT + { 0xFF41, BIDI_L }, // FULLWIDTH LATIN SMALL LETTER A + { 0xFF42, BIDI_L }, // FULLWIDTH LATIN SMALL LETTER B + { 0xFF43, BIDI_L }, // FULLWIDTH LATIN SMALL LETTER C + { 0xFF44, BIDI_L }, // FULLWIDTH LATIN SMALL LETTER D + { 0xFF45, BIDI_L }, // FULLWIDTH LATIN SMALL LETTER E + { 0xFF46, BIDI_L }, // FULLWIDTH LATIN SMALL LETTER F + { 0xFF47, BIDI_L }, // FULLWIDTH LATIN SMALL LETTER G + { 0xFF48, BIDI_L }, // FULLWIDTH LATIN SMALL LETTER H + { 0xFF49, BIDI_L }, // FULLWIDTH LATIN SMALL LETTER I + { 0xFF4A, BIDI_L }, // FULLWIDTH LATIN SMALL LETTER J + { 0xFF4B, BIDI_L }, // FULLWIDTH LATIN SMALL LETTER K + { 0xFF4C, BIDI_L }, // FULLWIDTH LATIN SMALL LETTER L + { 0xFF4D, BIDI_L }, // FULLWIDTH LATIN SMALL LETTER M + { 0xFF4E, BIDI_L }, // FULLWIDTH LATIN SMALL LETTER N + { 0xFF4F, BIDI_L }, // FULLWIDTH LATIN SMALL LETTER O + { 0xFF50, BIDI_L }, // FULLWIDTH LATIN SMALL LETTER P + { 0xFF51, BIDI_L }, // FULLWIDTH LATIN SMALL LETTER Q + { 0xFF52, BIDI_L }, // FULLWIDTH LATIN SMALL LETTER R + { 0xFF53, BIDI_L }, // FULLWIDTH LATIN SMALL LETTER S + { 0xFF54, BIDI_L }, // FULLWIDTH LATIN SMALL LETTER T + { 0xFF55, BIDI_L }, // FULLWIDTH LATIN SMALL LETTER U + { 0xFF56, BIDI_L }, // FULLWIDTH LATIN SMALL LETTER V + { 0xFF57, BIDI_L }, // FULLWIDTH LATIN SMALL LETTER W + { 0xFF58, BIDI_L }, // FULLWIDTH LATIN SMALL LETTER X + { 0xFF59, BIDI_L }, // FULLWIDTH LATIN SMALL LETTER Y + { 0xFF5A, BIDI_L }, // FULLWIDTH LATIN SMALL LETTER Z + { 0xFF5B, BIDI_ON }, // FULLWIDTH LEFT CURLY BRACKET + { 0xFF5C, BIDI_ON }, // FULLWIDTH VERTICAL LINE + { 0xFF5D, BIDI_ON }, // FULLWIDTH RIGHT CURLY BRACKET + { 0xFF5E, BIDI_ON }, // FULLWIDTH TILDE + { 0xFF5F, BIDI_ON }, // FULLWIDTH LEFT WHITE PARENTHESIS + { 0xFF60, BIDI_ON }, // FULLWIDTH RIGHT WHITE PARENTHESIS + { 0xFF61, BIDI_ON }, // HALFWIDTH IDEOGRAPHIC FULL STOP + { 0xFF62, BIDI_ON }, // HALFWIDTH LEFT CORNER BRACKET + { 0xFF63, BIDI_ON }, // HALFWIDTH RIGHT CORNER BRACKET + { 0xFF64, BIDI_ON }, // HALFWIDTH IDEOGRAPHIC COMMA + { 0xFF65, BIDI_ON }, // HALFWIDTH KATAKANA MIDDLE DOT + { 0xFF66, BIDI_L }, // HALFWIDTH KATAKANA LETTER WO + { 0xFF67, BIDI_L }, // HALFWIDTH KATAKANA LETTER SMALL A + { 0xFF68, BIDI_L }, // HALFWIDTH KATAKANA LETTER SMALL I + { 0xFF69, BIDI_L }, // HALFWIDTH KATAKANA LETTER SMALL U + { 0xFF6A, BIDI_L }, // HALFWIDTH KATAKANA LETTER SMALL E + { 0xFF6B, BIDI_L }, // HALFWIDTH KATAKANA LETTER SMALL O + { 0xFF6C, BIDI_L }, // HALFWIDTH KATAKANA LETTER SMALL YA + { 0xFF6D, BIDI_L }, // HALFWIDTH KATAKANA LETTER SMALL YU + { 0xFF6E, BIDI_L }, // HALFWIDTH KATAKANA LETTER SMALL YO + { 0xFF6F, BIDI_L }, // HALFWIDTH KATAKANA LETTER SMALL TU + { 0xFF70, BIDI_L }, // HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK + { 0xFF71, BIDI_L }, // HALFWIDTH KATAKANA LETTER A + { 0xFF72, BIDI_L }, // HALFWIDTH KATAKANA LETTER I + { 0xFF73, BIDI_L }, // HALFWIDTH KATAKANA LETTER U + { 0xFF74, BIDI_L }, // HALFWIDTH KATAKANA LETTER E + { 0xFF75, BIDI_L }, // HALFWIDTH KATAKANA LETTER O + { 0xFF76, BIDI_L }, // HALFWIDTH KATAKANA LETTER KA + { 0xFF77, BIDI_L }, // HALFWIDTH KATAKANA LETTER KI + { 0xFF78, BIDI_L }, // HALFWIDTH KATAKANA LETTER KU + { 0xFF79, BIDI_L }, // HALFWIDTH KATAKANA LETTER KE + { 0xFF7A, BIDI_L }, // HALFWIDTH KATAKANA LETTER KO + { 0xFF7B, BIDI_L }, // HALFWIDTH KATAKANA LETTER SA + { 0xFF7C, BIDI_L }, // HALFWIDTH KATAKANA LETTER SI + { 0xFF7D, BIDI_L }, // HALFWIDTH KATAKANA LETTER SU + { 0xFF7E, BIDI_L }, // HALFWIDTH KATAKANA LETTER SE + { 0xFF7F, BIDI_L }, // HALFWIDTH KATAKANA LETTER SO + { 0xFF80, BIDI_L }, // HALFWIDTH KATAKANA LETTER TA + { 0xFF81, BIDI_L }, // HALFWIDTH KATAKANA LETTER TI + { 0xFF82, BIDI_L }, // HALFWIDTH KATAKANA LETTER TU + { 0xFF83, BIDI_L }, // HALFWIDTH KATAKANA LETTER TE + { 0xFF84, BIDI_L }, // HALFWIDTH KATAKANA LETTER TO + { 0xFF85, BIDI_L }, // HALFWIDTH KATAKANA LETTER NA + { 0xFF86, BIDI_L }, // HALFWIDTH KATAKANA LETTER NI + { 0xFF87, BIDI_L }, // HALFWIDTH KATAKANA LETTER NU + { 0xFF88, BIDI_L }, // HALFWIDTH KATAKANA LETTER NE + { 0xFF89, BIDI_L }, // HALFWIDTH KATAKANA LETTER NO + { 0xFF8A, BIDI_L }, // HALFWIDTH KATAKANA LETTER HA + { 0xFF8B, BIDI_L }, // HALFWIDTH KATAKANA LETTER HI + { 0xFF8C, BIDI_L }, // HALFWIDTH KATAKANA LETTER HU + { 0xFF8D, BIDI_L }, // HALFWIDTH KATAKANA LETTER HE + { 0xFF8E, BIDI_L }, // HALFWIDTH KATAKANA LETTER HO + { 0xFF8F, BIDI_L }, // HALFWIDTH KATAKANA LETTER MA + { 0xFF90, BIDI_L }, // HALFWIDTH KATAKANA LETTER MI + { 0xFF91, BIDI_L }, // HALFWIDTH KATAKANA LETTER MU + { 0xFF92, BIDI_L }, // HALFWIDTH KATAKANA LETTER ME + { 0xFF93, BIDI_L }, // HALFWIDTH KATAKANA LETTER MO + { 0xFF94, BIDI_L }, // HALFWIDTH KATAKANA LETTER YA + { 0xFF95, BIDI_L }, // HALFWIDTH KATAKANA LETTER YU + { 0xFF96, BIDI_L }, // HALFWIDTH KATAKANA LETTER YO + { 0xFF97, BIDI_L }, // HALFWIDTH KATAKANA LETTER RA + { 0xFF98, BIDI_L }, // HALFWIDTH KATAKANA LETTER RI + { 0xFF99, BIDI_L }, // HALFWIDTH KATAKANA LETTER RU + { 0xFF9A, BIDI_L }, // HALFWIDTH KATAKANA LETTER RE + { 0xFF9B, BIDI_L }, // HALFWIDTH KATAKANA LETTER RO + { 0xFF9C, BIDI_L }, // HALFWIDTH KATAKANA LETTER WA + { 0xFF9D, BIDI_L }, // HALFWIDTH KATAKANA LETTER N + { 0xFF9E, BIDI_L }, // HALFWIDTH KATAKANA VOICED SOUND MARK + { 0xFF9F, BIDI_L }, // HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK + { 0xFFA0, BIDI_L }, // HALFWIDTH HANGUL FILLER + { 0xFFA1, BIDI_L }, // HALFWIDTH HANGUL LETTER KIYEOK + { 0xFFA2, BIDI_L }, // HALFWIDTH HANGUL LETTER SSANGKIYEOK + { 0xFFA3, BIDI_L }, // HALFWIDTH HANGUL LETTER KIYEOK-SIOS + { 0xFFA4, BIDI_L }, // HALFWIDTH HANGUL LETTER NIEUN + { 0xFFA5, BIDI_L }, // HALFWIDTH HANGUL LETTER NIEUN-CIEUC + { 0xFFA6, BIDI_L }, // HALFWIDTH HANGUL LETTER NIEUN-HIEUH + { 0xFFA7, BIDI_L }, // HALFWIDTH HANGUL LETTER TIKEUT + { 0xFFA8, BIDI_L }, // HALFWIDTH HANGUL LETTER SSANGTIKEUT + { 0xFFA9, BIDI_L }, // HALFWIDTH HANGUL LETTER RIEUL + { 0xFFAA, BIDI_L }, // HALFWIDTH HANGUL LETTER RIEUL-KIYEOK + { 0xFFAB, BIDI_L }, // HALFWIDTH HANGUL LETTER RIEUL-MIEUM + { 0xFFAC, BIDI_L }, // HALFWIDTH HANGUL LETTER RIEUL-PIEUP + { 0xFFAD, BIDI_L }, // HALFWIDTH HANGUL LETTER RIEUL-SIOS + { 0xFFAE, BIDI_L }, // HALFWIDTH HANGUL LETTER RIEUL-THIEUTH + { 0xFFAF, BIDI_L }, // HALFWIDTH HANGUL LETTER RIEUL-PHIEUPH + { 0xFFB0, BIDI_L }, // HALFWIDTH HANGUL LETTER RIEUL-HIEUH + { 0xFFB1, BIDI_L }, // HALFWIDTH HANGUL LETTER MIEUM + { 0xFFB2, BIDI_L }, // HALFWIDTH HANGUL LETTER PIEUP + { 0xFFB3, BIDI_L }, // HALFWIDTH HANGUL LETTER SSANGPIEUP + { 0xFFB4, BIDI_L }, // HALFWIDTH HANGUL LETTER PIEUP-SIOS + { 0xFFB5, BIDI_L }, // HALFWIDTH HANGUL LETTER SIOS + { 0xFFB6, BIDI_L }, // HALFWIDTH HANGUL LETTER SSANGSIOS + { 0xFFB7, BIDI_L }, // HALFWIDTH HANGUL LETTER IEUNG + { 0xFFB8, BIDI_L }, // HALFWIDTH HANGUL LETTER CIEUC + { 0xFFB9, BIDI_L }, // HALFWIDTH HANGUL LETTER SSANGCIEUC + { 0xFFBA, BIDI_L }, // HALFWIDTH HANGUL LETTER CHIEUCH + { 0xFFBB, BIDI_L }, // HALFWIDTH HANGUL LETTER KHIEUKH + { 0xFFBC, BIDI_L }, // HALFWIDTH HANGUL LETTER THIEUTH + { 0xFFBD, BIDI_L }, // HALFWIDTH HANGUL LETTER PHIEUPH + { 0xFFBE, BIDI_L }, // HALFWIDTH HANGUL LETTER HIEUH + { 0xFFC2, BIDI_L }, // HALFWIDTH HANGUL LETTER A + { 0xFFC3, BIDI_L }, // HALFWIDTH HANGUL LETTER AE + { 0xFFC4, BIDI_L }, // HALFWIDTH HANGUL LETTER YA + { 0xFFC5, BIDI_L }, // HALFWIDTH HANGUL LETTER YAE + { 0xFFC6, BIDI_L }, // HALFWIDTH HANGUL LETTER EO + { 0xFFC7, BIDI_L }, // HALFWIDTH HANGUL LETTER E + { 0xFFCA, BIDI_L }, // HALFWIDTH HANGUL LETTER YEO + { 0xFFCB, BIDI_L }, // HALFWIDTH HANGUL LETTER YE + { 0xFFCC, BIDI_L }, // HALFWIDTH HANGUL LETTER O + { 0xFFCD, BIDI_L }, // HALFWIDTH HANGUL LETTER WA + { 0xFFCE, BIDI_L }, // HALFWIDTH HANGUL LETTER WAE + { 0xFFCF, BIDI_L }, // HALFWIDTH HANGUL LETTER OE + { 0xFFD2, BIDI_L }, // HALFWIDTH HANGUL LETTER YO + { 0xFFD3, BIDI_L }, // HALFWIDTH HANGUL LETTER U + { 0xFFD4, BIDI_L }, // HALFWIDTH HANGUL LETTER WEO + { 0xFFD5, BIDI_L }, // HALFWIDTH HANGUL LETTER WE + { 0xFFD6, BIDI_L }, // HALFWIDTH HANGUL LETTER WI + { 0xFFD7, BIDI_L }, // HALFWIDTH HANGUL LETTER YU + { 0xFFDA, BIDI_L }, // HALFWIDTH HANGUL LETTER EU + { 0xFFDB, BIDI_L }, // HALFWIDTH HANGUL LETTER YI + { 0xFFDC, BIDI_L }, // HALFWIDTH HANGUL LETTER I + { 0xFFE0, BIDI_ET }, // FULLWIDTH CENT SIGN + { 0xFFE1, BIDI_ET }, // FULLWIDTH POUND SIGN + { 0xFFE2, BIDI_ON }, // FULLWIDTH NOT SIGN + { 0xFFE3, BIDI_ON }, // FULLWIDTH MACRON + { 0xFFE4, BIDI_ON }, // FULLWIDTH BROKEN BAR + { 0xFFE5, BIDI_ET }, // FULLWIDTH YEN SIGN + { 0xFFE6, BIDI_ET }, // FULLWIDTH WON SIGN + { 0xFFE8, BIDI_ON }, // HALFWIDTH FORMS LIGHT VERTICAL + { 0xFFE9, BIDI_ON }, // HALFWIDTH LEFTWARDS ARROW + { 0xFFEA, BIDI_ON }, // HALFWIDTH UPWARDS ARROW + { 0xFFEB, BIDI_ON }, // HALFWIDTH RIGHTWARDS ARROW + { 0xFFEC, BIDI_ON }, // HALFWIDTH DOWNWARDS ARROW + { 0xFFED, BIDI_ON }, // HALFWIDTH BLACK SQUARE + { 0xFFEE, BIDI_ON }, // HALFWIDTH WHITE CIRCLE + { 0xFFF9, BIDI_ON }, // INTERLINEAR ANNOTATION ANCHOR + { 0xFFFA, BIDI_ON }, // INTERLINEAR ANNOTATION SEPARATOR + { 0xFFFB, BIDI_ON }, // INTERLINEAR ANNOTATION TERMINATOR + { 0xFFFC, BIDI_ON }, // OBJECT REPLACEMENT CHARACTER + { 0xFFFD, BIDI_ON }, // REPLACEMENT CHARACTER + +#endif // GUI_BIDI_SUPPORT_RANGE_F + +#endif // GUI__BIDI2 + +/*************************** End of file ****************************/ + diff --git a/example/GUI/STemWin/inc/Global.h b/example/GUI/STemWin/inc/Global.h new file mode 100755 index 0000000000..21006bcf17 --- /dev/null +++ b/example/GUI/STemWin/inc/Global.h @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GLOBAL.h +Purpose : Global types etc. +---------------------------END-OF-HEADER------------------------------ +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef GLOBAL_H // Guard against multiple inclusion +#define GLOBAL_H + +#define U8 unsigned char +#define I8 signed char +#define U16 unsigned short +#define I16 signed short +#ifdef __x86_64__ +#define U32 unsigned +#define I32 int +#else +#define U32 unsigned long +#define I32 signed long +#endif + +#ifdef _WIN32 + // + // Microsoft VC6 compiler related + // + #ifdef __MINGW32__ + #define U64 unsigned long long + #define I64 long long + #else + #define U64 unsigned __int64 + #define U128 unsigned __int128 + #define I64 __int64 + #define I128 __int128 + #if _MSC_VER <= 1200 + #define U64_C(x) x##UI64 + #else + #define U64_C(x) x##ULL + #endif + #endif +#else + // + // C99 compliant compiler + // + #define U64 unsigned long long + #define I64 signed long long + #define U64_C(x) x##ULL +#endif + +#endif // Avoid multiple inclusion + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/HEADER.h b/example/GUI/STemWin/inc/HEADER.h new file mode 100755 index 0000000000..418d5e1d32 --- /dev/null +++ b/example/GUI/STemWin/inc/HEADER.h @@ -0,0 +1,209 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : HEADER.h +Purpose : HEADER include +--------------------END-OF-HEADER------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef HEADER_H +#define HEADER_H + +#include "WM.h" +#include "DIALOG_Intern.h" /* Req. for Create indirect data structure */ +#include "WIDGET.h" + +#if GUI_WINSUPPORT + +#if defined(__cplusplus) + extern "C" { /* Make sure we have C-declarations in C++ programs */ +#endif + +/********************************************************************* +* +* Public Types +* +********************************************************************** +*/ + +typedef WM_HMEM HEADER_Handle; + +typedef struct { + GUI_COLOR aColorFrame[2]; + GUI_COLOR aColorUpper[2]; + GUI_COLOR aColorLower[2]; + GUI_COLOR ColorArrow; +} HEADER_SKINFLEX_PROPS; + +/********************************************************************* +* +* Create functions +* +********************************************************************** +*/ + +HEADER_Handle HEADER_Create (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int Id, int Flags, int SpecialFlags); +HEADER_Handle HEADER_CreateAttached(WM_HWIN hParent, int Id, int SpecialFlags); +HEADER_Handle HEADER_CreateEx (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int WinFlags, int ExFlags, int Id); +HEADER_Handle HEADER_CreateUser (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int WinFlags, int ExFlags, int Id, int NumExtraBytes); +HEADER_Handle HEADER_CreateIndirect(const GUI_WIDGET_CREATE_INFO * pCreateInfo, WM_HWIN hWinParent, int x0, int y0, WM_CALLBACK * cb); + +/********************************************************************* +* +* The callback ... +* +* Do not call it directly ! It is only to be used from within an +* overwritten callback. +*/ +void HEADER_Callback(WM_MESSAGE * pMsg); + +/********************************************************************* +* +* Managing default values +* +********************************************************************** +*/ +/* Set defaults */ +GUI_COLOR HEADER_SetDefaultArrowColor(GUI_COLOR Color); +GUI_COLOR HEADER_SetDefaultBkColor (GUI_COLOR Color); +const GUI_CURSOR * HEADER_SetDefaultCursor (const GUI_CURSOR * pCursor); +const GUI_FONT * HEADER_SetDefaultFont (const GUI_FONT * pFont); +int HEADER_SetDefaultBorderH (int Spacing); +int HEADER_SetDefaultBorderV (int Spacing); +GUI_COLOR HEADER_SetDefaultTextColor (GUI_COLOR Color); + +/* Get defaults */ +GUI_COLOR HEADER_GetDefaultArrowColor(void); +GUI_COLOR HEADER_GetDefaultBkColor (void); +const GUI_CURSOR * HEADER_GetDefaultCursor (void); +const GUI_FONT * HEADER_GetDefaultFont (void); +int HEADER_GetDefaultBorderH (void); +int HEADER_GetDefaultBorderV (void); +GUI_COLOR HEADER_GetDefaultTextColor (void); + +/********************************************************************* +* +* Member functions +* +********************************************************************** +*/ +void HEADER_AddItem (HEADER_Handle hObj, int Width, const char * s, int Align); +void HEADER_DeleteItem (HEADER_Handle hObj, unsigned Index); +GUI_COLOR HEADER_GetArrowColor (HEADER_Handle hObj); +GUI_COLOR HEADER_GetBkColor (HEADER_Handle hObj); +int HEADER_GetHeight (HEADER_Handle hObj); +int HEADER_GetItemWidth (HEADER_Handle hObj, unsigned int Index); +int HEADER_GetNumItems (HEADER_Handle hObj); +int HEADER_GetSel (HEADER_Handle hObj); +GUI_COLOR HEADER_GetTextColor (HEADER_Handle hObj); +int HEADER_GetUserData (HEADER_Handle hObj, void * pDest, int NumBytes); +void HEADER_SetArrowColor (HEADER_Handle hObj, GUI_COLOR Color); +void HEADER_SetBitmap (HEADER_Handle hObj, unsigned int Index, const GUI_BITMAP * pBitmap); +void HEADER_SetBitmapEx (HEADER_Handle hObj, unsigned int Index, const GUI_BITMAP * pBitmap, int x, int y); +void HEADER_SetBkColor (HEADER_Handle hObj, GUI_COLOR Color); +void HEADER_SetBMP (HEADER_Handle hObj, unsigned int Index, const void * pBitmap); +void HEADER_SetBMPEx (HEADER_Handle hObj, unsigned int Index, const void * pBitmap, int x, int y); +void HEADER_SetDirIndicator (HEADER_Handle hObj, int Column, int Reverse); /* !!!Not to be documented!!! */ +void HEADER_SetDragLimit (HEADER_Handle hObj, unsigned DragLimit); +unsigned HEADER_SetFixed (HEADER_Handle hObj, unsigned Fixed); +void HEADER_SetFont (HEADER_Handle hObj, const GUI_FONT * pFont); +void HEADER_SetHeight (HEADER_Handle hObj, int Height); +void HEADER_SetTextAlign (HEADER_Handle hObj, unsigned int Index, int Align); +void HEADER_SetItemText (HEADER_Handle hObj, unsigned int Index, const char * s); +void HEADER_SetItemWidth (HEADER_Handle hObj, unsigned int Index, int Width); +void HEADER_SetScrollPos (HEADER_Handle hObj, int ScrollPos); +void HEADER_SetStreamedBitmap (HEADER_Handle hObj, unsigned int Index, const GUI_BITMAP_STREAM * pBitmap); +void HEADER_SetStreamedBitmapEx(HEADER_Handle hObj, unsigned int Index, const GUI_BITMAP_STREAM * pBitmap, int x, int y); +void HEADER_SetTextColor (HEADER_Handle hObj, GUI_COLOR Color); +int HEADER_SetUserData (HEADER_Handle hObj, const void * pSrc, int NumBytes); + +/********************************************************************* +* +* Member functions: Skinning +* +********************************************************************** +*/ +void HEADER_GetSkinFlexProps (HEADER_SKINFLEX_PROPS * pProps, int Index); +void HEADER_SetSkinClassic (HEADER_Handle hObj); +void HEADER_SetSkin (HEADER_Handle hObj, WIDGET_DRAW_ITEM_FUNC * pfDrawSkin); +int HEADER_DrawSkinFlex (const WIDGET_ITEM_DRAW_INFO * pDrawItemInfo); +void HEADER_SetSkinFlexProps (const HEADER_SKINFLEX_PROPS * pProps, int Index); +void HEADER_SetDefaultSkinClassic(void); +WIDGET_DRAW_ITEM_FUNC * HEADER_SetDefaultSkin(WIDGET_DRAW_ITEM_FUNC * pfDrawSkin); + +#define HEADER_SKIN_FLEX HEADER_DrawSkinFlex + +/********************************************************************* +* +* Macros for compatibility with older versions +* +********************************************************************** +*/ + +#ifdef HEADER_SPACING_H + #define HEADER_BORDER_H_DEFAULT HEADER_SPACING_H +#endif +#ifdef HEADER_SPACING_V + #define HEADER_BORDER_V_DEFAULT HEADER_SPACING_V +#endif +#define HEADER_SetDefaultSpacingH(Value) HEADER_SetDefaultBorderH(Value) +#define HEADER_SetDefaultSpacingV(Value) HEADER_SetDefaultBorderV(Value) +#define HEADER_GetDefaultSpacingH() HEADER_GetDefaultBorderH() +#define HEADER_GetDefaultSpacingV() HEADER_GetDefaultBorderV() + +#if defined(__cplusplus) + } +#endif + +#endif // GUI_WINSUPPORT +#endif // HEADER_H + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/HEADER_Private.h b/example/GUI/STemWin/inc/HEADER_Private.h new file mode 100755 index 0000000000..3ce1e0da3b --- /dev/null +++ b/example/GUI/STemWin/inc/HEADER_Private.h @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : HEADER_Private.h +Purpose : Private HEADER include +--------------------END-OF-HEADER------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef HEADER_PRIVATE_H +#define HEADER_PRIVATE_H + + +#include "HEADER.h" +#include "WIDGET.h" +#include "WM.h" +#include "GUI_ARRAY.h" + +#if GUI_WINSUPPORT + +/********************************************************************* +* +* Object definition +* +********************************************************************** +*/ +typedef struct { + int Width; + I16 Align; + WM_HMEM hDrawObj; + char acText[1]; +} HEADER_COLUMN; + +typedef struct { + WIDGET_DRAW_ITEM_FUNC * pfDrawSkin; +} HEADER_SKIN_PRIVATE; + +typedef struct { + const GUI_FONT * pFont; + GUI_COLOR BkColor; + GUI_COLOR TextColor; + GUI_COLOR ArrowColor; + HEADER_SKIN_PRIVATE SkinPrivate; +} HEADER_PROPS; + +typedef struct { + WIDGET Widget; + HEADER_PROPS Props; + WIDGET_SKIN const * pWidgetSkin; + GUI_ARRAY Columns; + int CapturePosX; + int CaptureItem; + int ScrollPos; + int Sel; + int DirIndicatorColumn; + int DirIndicatorReverse; + unsigned Fixed; + U8 DragLimit; +} HEADER_Obj; + +/********************************************************************* +* +* Private (module internal) data +* +********************************************************************** +*/ + +extern HEADER_PROPS HEADER__DefaultProps; +extern const GUI_CURSOR * HEADER__pDefaultCursor; +extern int HEADER__DefaultBorderH; +extern int HEADER__DefaultBorderV; + +extern const WIDGET_SKIN HEADER__SkinClassic; +extern WIDGET_SKIN HEADER__Skin; + +extern WIDGET_SKIN const * HEADER__pSkinDefault; + +/********************************************************************* +* +* Macros for internal use +* +********************************************************************** +*/ +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL + #define HEADER_INIT_ID(p) (p->Widget.DebugId = HEADER_ID) +#else + #define HEADER_INIT_ID(p) +#endif + +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL + HEADER_Obj * HEADER_LockH(HEADER_Handle h); + #define HEADER_LOCK_H(h) HEADER_LockH(h) +#else + #define HEADER_LOCK_H(h) (HEADER_Obj *)GUI_LOCK_H(h) +#endif + +void HEADER__SetDrawObj(HEADER_Handle hObj, unsigned Index, GUI_DRAW_HANDLE hDrawObj); + + +#endif // GUI_WINSUPPORT +#endif // Avoid multiple inclusion + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/ICONVIEW.h b/example/GUI/STemWin/inc/ICONVIEW.h new file mode 100755 index 0000000000..9d7ead9e06 --- /dev/null +++ b/example/GUI/STemWin/inc/ICONVIEW.h @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : ICONVIEW.h +Purpose : ICONVIEW include +--------------------END-OF-HEADER------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef ICONVIEW_H +#define ICONVIEW_H + +#include "WM.h" +#include "DIALOG_Intern.h" /* Req. for Create indirect data structure */ +#include "WIDGET.h" + +#if GUI_WINSUPPORT + +#if defined(__cplusplus) + extern "C" { /* Make sure we have C-declarations in C++ programs */ +#endif + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ +// +// Status- and create flags +// +#define ICONVIEW_CF_AUTOSCROLLBAR_V (1 << 1) +#define ICONVIEW_SF_AUTOSCROLLBAR_V ICONVIEW_CF_AUTOSCROLLBAR_V + +// +// Color indices +// +#define ICONVIEW_CI_BK 0 +#define ICONVIEW_CI_UNSEL 0 +#define ICONVIEW_CI_SEL 1 +#define ICONVIEW_CI_DISABLED 2 + +// +// Icon alignment flags, horizontal +// +#define ICONVIEW_IA_HCENTER (0 << 0) +#define ICONVIEW_IA_LEFT (1 << 0) +#define ICONVIEW_IA_RIGHT (2 << 0) + +// +// Icon alignment flags, vertical +// +#define ICONVIEW_IA_VCENTER (0 << 2) +#define ICONVIEW_IA_BOTTOM (1 << 2) +#define ICONVIEW_IA_TOP (2 << 2) + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ +typedef WM_HMEM ICONVIEW_Handle; + +/********************************************************************* +* +* Public functions +* +********************************************************************** +*/ +ICONVIEW_Handle ICONVIEW_CreateEx (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int WinFlags, int ExFlags, int Id, int xSizeItems, int ySizeItems); +ICONVIEW_Handle ICONVIEW_CreateUser (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int WinFlags, int ExFlags, int Id, int xSizeItems, int ySizeItems, int NumExtraBytes); +ICONVIEW_Handle ICONVIEW_CreateIndirect(const GUI_WIDGET_CREATE_INFO * pCreateInfo, WM_HWIN hWinParent, int x0, int y0, WM_CALLBACK * cb); + +int ICONVIEW_AddBitmapItem (ICONVIEW_Handle hObj, const GUI_BITMAP * pBitmap, const char * pText); +int ICONVIEW_AddBMPItem (ICONVIEW_Handle hObj, const U8 * pBMP, const char * pText); +int ICONVIEW_AddBMPItemEx (ICONVIEW_Handle hObj, const void * pBMP, GUI_GET_DATA_FUNC * pfGetData, const char * pText); +int ICONVIEW_AddStreamedBitmapItem (ICONVIEW_Handle hObj, const void * pStreamedBitmap, const char * pText); +void ICONVIEW_DeleteItem (ICONVIEW_Handle hObj, unsigned Index); +//void ICONVIEW_EnableStreamAuto (void); +U32 ICONVIEW_GetItemUserData (ICONVIEW_Handle hObj, int Index); +int ICONVIEW_GetNumItems (ICONVIEW_Handle hObj); +int ICONVIEW_GetItemText (ICONVIEW_Handle hObj, int Index, char * pBuffer, int MaxSize); +int ICONVIEW_GetSel (ICONVIEW_Handle hObj); +int ICONVIEW_GetUserData (ICONVIEW_Handle hObj, void * pDest, int NumBytes); +GUI_BITMAP * ICONVIEW_GetItemBitmap (ICONVIEW_Handle hObj, int ItemIndex); +int ICONVIEW_InsertBitmapItem (ICONVIEW_Handle hObj, const GUI_BITMAP * pBitmap, const char * pText, int Index); +int ICONVIEW_InsertBMPItem (ICONVIEW_Handle hObj, const U8 * pBMP, const char * pText, int Index); +int ICONVIEW_InsertBMPItemEx (ICONVIEW_Handle hObj, const void * pBMP, GUI_GET_DATA_FUNC * pfGetData, const char * pText, int Index); +int ICONVIEW_InsertStreamedBitmapItem(ICONVIEW_Handle hObj, const void * pStreamedBitmap, const char * pText, int Index); +int ICONVIEW_OwnerDraw (const WIDGET_ITEM_DRAW_INFO * pDrawItemInfo); +int ICONVIEW_SetBitmapItem (ICONVIEW_Handle hObj, int Index, const GUI_BITMAP * pBitmap); +void ICONVIEW_SetBkColor (ICONVIEW_Handle hObj, int Index, GUI_COLOR Color); +int ICONVIEW_SetBMPItem (ICONVIEW_Handle hObj, const U8 * pBMP, int Index); +int ICONVIEW_SetBMPItemEx (ICONVIEW_Handle hObj, const void * pBMP, GUI_GET_DATA_FUNC * pfGetData, int Index); +void ICONVIEW_SetFont (ICONVIEW_Handle hObj, const GUI_FONT * pFont); +void ICONVIEW_SetFrame (ICONVIEW_Handle hObj, int Coord, int Value); +void ICONVIEW_SetItemText (ICONVIEW_Handle hObj, int Index, const char * pText); +void ICONVIEW_SetItemUserData (ICONVIEW_Handle hObj, int Index, U32 UserData); +void ICONVIEW_SetOwnerDraw (ICONVIEW_Handle hObj, WIDGET_DRAW_ITEM_FUNC * pfDrawItem); +void ICONVIEW_SetSel (ICONVIEW_Handle hObj, int Sel); +void ICONVIEW_SetSpace (ICONVIEW_Handle hObj, int Coord, int Value); +int ICONVIEW_SetStreamedBitmapItem (ICONVIEW_Handle hObj, int Index, const void * pStreamedBitmap); +void ICONVIEW_SetIconAlign (ICONVIEW_Handle hObj, int IconAlign); +void ICONVIEW_SetTextAlign (ICONVIEW_Handle hObj, int TextAlign); +void ICONVIEW_SetTextColor (ICONVIEW_Handle hObj, int Index, GUI_COLOR Color); +int ICONVIEW_SetUserData (ICONVIEW_Handle hObj, const void * pSrc, int NumBytes); +void ICONVIEW_SetWrapMode (ICONVIEW_Handle hObj, GUI_WRAPMODE WrapMode); + +void ICONVIEW_Callback (WM_MESSAGE * pMsg); + +// +// Compatibility macro +// +#define ICONVIEW_EnableStreamAuto() GUI_DrawStreamedEnableAuto() + +#if defined(__cplusplus) + } +#endif + +#endif // GUI_WINSUPPORT +#endif // ICONVIEW_H + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/ICONVIEW_Private.h b/example/GUI/STemWin/inc/ICONVIEW_Private.h new file mode 100755 index 0000000000..b642338dee --- /dev/null +++ b/example/GUI/STemWin/inc/ICONVIEW_Private.h @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : ICONVIEW_Private.h +Purpose : ICONVIEW private header file +--------------------END-OF-HEADER------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef ICONVIEW_PRIVATE_H +#define ICONVIEW_PRIVATE_H + +#include "WM.h" +#include "GUI_ARRAY.h" +#include "ICONVIEW.h" + +#if GUI_WINSUPPORT + +#if defined(__cplusplus) + extern "C" { // Make sure we have C-declarations in C++ programs +#endif + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ +typedef struct { + const GUI_FONT * pFont; + GUI_COLOR aBkColor[3]; + GUI_COLOR aTextColor[3]; + int FrameX, FrameY; + int SpaceX, SpaceY; + int TextAlign; + int IconAlign; + GUI_WRAPMODE WrapMode; +} ICONVIEW_PROPS; + +typedef struct { + WIDGET Widget; + WM_SCROLL_STATE ScrollStateV; + WM_SCROLL_STATE ScrollStateH; + ICONVIEW_PROPS Props; + GUI_ARRAY ItemArray; + int xSizeItems; + int ySizeItems; + int Sel; + U16 Flags; + WIDGET_DRAW_ITEM_FUNC * pfDrawItem; +} ICONVIEW_OBJ; + +typedef void tDrawImage (const void * pData, GUI_GET_DATA_FUNC * pfGetData, int xPos, int yPos); +typedef void tDrawText (ICONVIEW_OBJ * pObj, GUI_RECT * pRect, const char * s); +typedef void tGetImageSizes(const void * pData, GUI_GET_DATA_FUNC * pfGetData, int * xSize, int * ySize); + +typedef struct { + tDrawImage * pfDrawImage; + tDrawText * pfDrawText; + tGetImageSizes * pfGetImageSizes; + GUI_GET_DATA_FUNC * pfGetData; + const void * pData; + U32 UserData; + int SizeOfData; + char acText[1]; +} ICONVIEW_ITEM; + +/********************************************************************* +* +* Macros for internal use +* +********************************************************************** +*/ +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL + #define ICONVIEW_INIT_ID(p) (p->Widget.DebugId = ICONVIEW_ID) +#else + #define ICONVIEW_INIT_ID(p) +#endif + +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL + ICONVIEW_OBJ * ICONVIEW_LockH(ICONVIEW_Handle h); + #define ICONVIEW_LOCK_H(h) ICONVIEW_LockH(h) +#else + #define ICONVIEW_LOCK_H(h) (ICONVIEW_OBJ *)GUI_LOCK_H(h) +#endif + +/********************************************************************* +* +* Private functions +* +********************************************************************** +*/ +void ICONVIEW__DrawText (ICONVIEW_OBJ * pObj, GUI_RECT * pRect, const char * pText); +void ICONVIEW__ManageAutoScroll(ICONVIEW_Handle hObj); + +#if defined(__cplusplus) + } +#endif + +#endif // GUI_WINSUPPORT +#endif // ICONVIEW_H + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/IMAGE.h b/example/GUI/STemWin/inc/IMAGE.h new file mode 100755 index 0000000000..d34653924b --- /dev/null +++ b/example/GUI/STemWin/inc/IMAGE.h @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : IMAGE.h +Purpose : Image include +--------------------END-OF-HEADER------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef IMAGE_H +#define IMAGE_H + +#include "WM.h" +#include "DIALOG_Intern.h" +#include "WIDGET.h" + +#if GUI_WINSUPPORT + +#if defined(__cplusplus) + extern "C" { // Make sure we have C-declarations in C++ programs +#endif + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ +#define IMAGE_CF_MEMDEV (1 << 0) // Widget uses an internal memory device which speeds up use of compressed images (GIF, JPEG, PNG) +#define IMAGE_CF_TILE (1 << 1) // Uses tiling to fill up the whole area of the widget +#define IMAGE_CF_ALPHA (1 << 2) // Needs to be set if alpha blending is required (PNG) +#define IMAGE_CF_ATTACHED (1 << 3) // Widget size is fixed to the parent border +#define IMAGE_CF_AUTOSIZE (1 << 4) // Widget size is taken from the attached image + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ +typedef WM_HMEM IMAGE_Handle; + +/********************************************************************* +* +* Public functions +* +********************************************************************** +*/ +IMAGE_Handle IMAGE_CreateEx (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int WinFlags, int ExFlags, int Id); +IMAGE_Handle IMAGE_CreateUser (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int WinFlags, int ExFlags, int Id, int NumExtraBytes); +IMAGE_Handle IMAGE_CreateIndirect(const GUI_WIDGET_CREATE_INFO * pCreateInfo, WM_HWIN hWinParent, int x0, int y0, WM_CALLBACK * cb); + +void IMAGE_Callback(WM_MESSAGE * pMsg); + +/********************************************************************* +* +* Member functions +* +********************************************************************** +*/ +int IMAGE_GetUserData(IMAGE_Handle hObj, void * pDest, int NumBytes); +void IMAGE_SetBitmap (IMAGE_Handle hWin, const GUI_BITMAP * pBitmap); +void IMAGE_SetBMP (IMAGE_Handle hObj, const void * pData, U32 FileSize); +void IMAGE_SetBMPEx (IMAGE_Handle hObj, GUI_GET_DATA_FUNC * pfGetData, void * pVoid); +void IMAGE_SetDTA (IMAGE_Handle hObj, const void * pData, U32 FileSize); +void IMAGE_SetDTAEx (IMAGE_Handle hObj, GUI_GET_DATA_FUNC * pfGetData, void * pVoid); +void IMAGE_SetGIF (IMAGE_Handle hObj, const void * pData, U32 FileSize); +void IMAGE_SetGIFEx (IMAGE_Handle hObj, GUI_GET_DATA_FUNC * pfGetData, void * pVoid); +void IMAGE_SetJPEG (IMAGE_Handle hObj, const void * pData, U32 FileSize); +void IMAGE_SetJPEGEx (IMAGE_Handle hObj, GUI_GET_DATA_FUNC * pfGetData, void * pVoid); +void IMAGE_SetPNG (IMAGE_Handle hObj, const void * pData, U32 FileSize); +void IMAGE_SetPNGEx (IMAGE_Handle hObj, GUI_GET_DATA_FUNC * pfGetData, void * pVoid); +int IMAGE_SetUserData(IMAGE_Handle hObj, const void * pSrc, int NumBytes); + + +#if defined(__cplusplus) + } +#endif + +#endif // GUI_WINSUPPORT +#endif // IMAGE_H + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/IMAGE_Private.h b/example/GUI/STemWin/inc/IMAGE_Private.h new file mode 100755 index 0000000000..793f757fda --- /dev/null +++ b/example/GUI/STemWin/inc/IMAGE_Private.h @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : IMAGE_Private.h +Purpose : Private IMAGE include +--------------------END-OF-HEADER------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef IMAGE_PRIVATE_H +#define IMAGE_PRIVATE_H + +#include "IMAGE.h" +#include "GUI_Private.h" + +#if GUI_WINSUPPORT + +/********************************************************************* +* +* Private config defaults +* +********************************************************************** +*/ +#ifndef IMAGE_SUPPORT_TRANSPARENCY + #define IMAGE_SUPPORT_TRANSPARENCY WM_SUPPORT_TRANSPARENCY +#endif + +/********************************************************************* +* +* Object definition +* +********************************************************************** +*/ +typedef struct { + U32 Flags; +} IMAGE_PROPS; + +typedef struct { + WIDGET Widget; + IMAGE_PROPS Props; + const void * pData; // Data pointer of the object to be drawn (Bitmap, BMP, GIF, JPEG, PNG) + void (* pfDrawImageAt) (IMAGE_Handle hObj, int xPos, int yPos); // Object specific (Bitmap, BMP, GIF, JPEG, PNG) code + void (* pfPaint) (IMAGE_Handle hObj); // Drawing method specific (Default, Tiled, Magnified) code + void (* pfGetImageSize)(IMAGE_Handle hObj, int * pxSize, int * pySize); // Returns the image size of the attached item + void (* pfOnTimer) (IMAGE_Handle hObj); // Timer function for animated images (currently only animated GIFs are supported) + U32 FileSize; + // + // Data items used by IAMGE_GIF.c + // + int NumImages; // Number of (sub)images + int CurrentImage; // Image index used for animated images + GUI_TIMER_HANDLE hTimer; // Timer used for animated images + // + // Data items used by IAMGE_DTA.c + // + GUI_BITMAP Bitmap; // Bitmap structure + GUI_LOGPALETTE Palette; // Palette structure + // + // Data items used by Image_...Ex() - functions + // + void * pVoid; // Void pointer passed to GetData() function + GUI_GET_DATA_FUNC * pfGetData; // Pointer to GetData() function + // + // Data items used if memory devices are available and IMAGE_CF_MEMDEV has been set + // + #if GUI_SUPPORT_MEMDEV + GUI_MEMDEV_Handle hMem; + #endif +} IMAGE_OBJ; + +/********************************************************************* +* +* Macros for internal use +* +********************************************************************** +*/ +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL + #define IMAGE_INIT_ID(p) (p->Widget.DebugId = IMAGE_ID) +#else + #define IMAGE_INIT_ID(p) +#endif + +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL + IMAGE_OBJ * IMAGE__LockH(IMAGE_Handle h); + #define IMAGE_LOCK_H(h) IMAGE__LockH(h) +#else + #define IMAGE_LOCK_H(h) (IMAGE_OBJ *)GUI_LOCK_H(h) +#endif + +/********************************************************************* +* +* Module internal data +* +********************************************************************** +*/ +extern IMAGE_PROPS IMAGE__DefaultProps; + +/********************************************************************* +* +* Private functions +* +********************************************************************** +*/ +void IMAGE__SetWindowSize(IMAGE_Handle hObj); +void IMAGE__FreeAttached (IMAGE_Handle hObj, int LeaveTimer); + +#endif // GUI_WINSUPPORT +#endif // IMAGE_PRIVATE_H + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/IP_FS.h b/example/GUI/STemWin/inc/IP_FS.h new file mode 100755 index 0000000000..b75e04d034 --- /dev/null +++ b/example/GUI/STemWin/inc/IP_FS.h @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +Licensing information +Licensor: SEGGER Software GmbH +Licensed to: STMicroelectronics International NV, 39, Chemin du Champ-des Filles, 1228 Plan Les Ouates, Geneva, SWITZERLAND +Licensed SEGGER software: emWin +License number: GUI-00429 +License model: Buyout SRC [Buyout Source Code License, signed November 29th 2012] +Licensed product: - +Licensed platform: STMs ARM Cortex-M based 32 BIT CPUs +Licensed number of seats: - +---------------------------------------------------------------------- +Support and Update Agreement (SUA) +SUA period: 2012-12-07 - 2017-12-31 +Contact to extend SUA: sales@segger.com +---------------------------------------------------------------------- +File : IP_FS.h +Purpose : File system abstraction layer +---------------------------END-OF-HEADER------------------------------ + +Attention : Do not modify this file ! +*/ + +#ifndef IP_FS_H +#define IP_FS_H + +#include "SEGGER.h" + +#if defined(__cplusplus) +extern "C" { /* Make sure we have C-declarations in C++ programs */ +#endif + +/********************************************************************* +* +* Functions +* +********************************************************************** +*/ + +typedef struct { + // + // Read only file operations. These have to be present on ANY file system, even the simplest one. + // + void* (*pfOpenFile) (const char* sFilename); + int (*pfCloseFile) (void* hFile); + int (*pfReadAt) (void* hFile, void* pBuffer, U32 Pos, U32 NumBytes); + long (*pfGetLen) (void* hFile); + // + // Directory query operations. + // + void (*pfForEachDirEntry) (void* pContext, const char* sDir, void (*pf)(void* pContext, void* pFileEntry)); + void (*pfGetDirEntryFileName) (void* pFileEntry, char* sFileName, U32 SizeOfBuffer); + U32 (*pfGetDirEntryFileSize) (void* pFileEntry, U32* pFileSizeHigh); + U32 (*pfGetDirEntryFileTime) (void* pFileEntry); + int (*pfGetDirEntryAttributes)(void* pFileEntry); + // + // Write file operations. + // + void* (*pfCreate) (const char* sFileName); + void* (*pfDeleteFile) (const char* sFilename); + int (*pfRenameFile) (const char* sOldFilename, const char* sNewFilename); + int (*pfWriteAt) (void* hFile, void* pBuffer, U32 Pos, U32 NumBytes); + // + // Additional directory operations + // + int (*pfMKDir) (const char* sDirName); + int (*pfRMDir) (const char* sDirName); + // + // Additional operations + // + int (*pfIsFolder) (const char* sPath); + int (*pfMove) (const char* sOldFilename, const char* sNewFilename); +} IP_FS_API; + +extern const IP_FS_API IP_FS_ReadOnly; // Read-only file system, typically located in flash memory. +extern const IP_FS_API IP_FS_Win32; // File system interface for Win32. +extern const IP_FS_API IP_FS_Linux; // File system interface for Linux +extern const IP_FS_API IP_FS_FS; // Target file system (emFile), shows and allows access to hidden files. +extern const IP_FS_API IP_FS_FS_AllowHiddenAccess; // Target file system (emFile), does not show hidden files but allows access to them. +extern const IP_FS_API IP_FS_FS_DenyHiddenAccess; // Target file system (emFile), does not show hidden files and does not allow access to them. + +void IP_FS_WIN32_ConfigBaseDir(const char* sDir); + + +#if defined(__cplusplus) + } +#endif + + +#endif /* Avoid multiple inclusion */ + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/KNOB.h b/example/GUI/STemWin/inc/KNOB.h new file mode 100755 index 0000000000..619c5a6010 --- /dev/null +++ b/example/GUI/STemWin/inc/KNOB.h @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : KNOB.h +Purpose : KNOB include +--------------------END-OF-HEADER------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef KNOB_H +#define KNOB_H + +#include "WM.h" +#include "DIALOG_Intern.h" // Req. for Create indirect data structure +#include "WIDGET.h" +#include "GUI_Debug.h" + +#if (GUI_SUPPORT_MEMDEV && GUI_WINSUPPORT) + +#if defined(__cplusplus) + extern "C" { // Make sure we have C-declarations in C++ programs +#endif + +/********************************************************************* +* +* Public Types +* +********************************************************************** +*/ +typedef WM_HMEM KNOB_Handle; + +/********************************************************************* +* +* Create functions +* +********************************************************************** +*/ +KNOB_Handle KNOB_CreateEx (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int WinFlags, int Id); +KNOB_Handle KNOB_CreateUser (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int WinFlags, int Id, int NumExtraBytes); +KNOB_Handle KNOB_CreateIndirect(const GUI_WIDGET_CREATE_INFO * pCreateInfo, WM_HWIN hWinParent, int x0, int y0, WM_CALLBACK * cb); + +/********************************************************************* +* +* The callback ... +* +* Do not call it directly ! It is only to be used from within an +* overwritten callback. +*/ +void KNOB_Callback(WM_MESSAGE * pMsg); + +/********************************************************************* +* +* Member functions +* +********************************************************************** +*/ +void KNOB_AddValue (KNOB_Handle hObj, I32 Value); +int KNOB_GetUserData(KNOB_Handle hObj, void * pDest, int NumBytes); // Gets user defined data +I32 KNOB_GetValue (KNOB_Handle hObj); // Returns the position of the knob in tenth of degree +void KNOB_SetBkColor (KNOB_Handle hObj, GUI_COLOR Color); // Sets the BK color of the widget +void KNOB_SetBkDevice(KNOB_Handle hObj, GUI_MEMDEV_Handle hMemBk); // Sets the background device +void KNOB_SetDevice (KNOB_Handle hObj, GUI_MEMDEV_Handle hMemSrc); // Sets the memory device with the drawn knob +void KNOB_SetKeyValue(KNOB_Handle hObj, I32 KeyValue); // Sets the value the knob will rotate on one key press +void KNOB_SetOffset (KNOB_Handle hObj, I32 Offset); // Sets the offset angle of the knob +void KNOB_SetPeriod (KNOB_Handle hObj, I32 Period); // Sets the period in which the knob stops +void KNOB_SetPos (KNOB_Handle hObj, I32 Pos); // Sets position of the knob in tenth of degree +void KNOB_SetRange (KNOB_Handle hObj, I32 MinRange, I32 MaxRange); // Sets the usable range of the knob widget +void KNOB_SetSnap (KNOB_Handle hObj, I32 Snap); // Sets Snap positions where the knob stops +void KNOB_SetTickSize(KNOB_Handle hObj, I32 TickSize); // Sets the ticksize, in 1/10 of degree +int KNOB_SetUserData(KNOB_Handle hObj, const void * pSrc, int NumBytes); // Sets user defined data + +/********************************************************************* +* +* Global functions +* +********************************************************************** +*/ + +#if defined(__cplusplus) + } +#endif + +#endif // (GUI_SUPPORT_MEMDEV && GUI_WINSUPPORT) +#endif // KNOB_H + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/KNOB_Private.h b/example/GUI/STemWin/inc/KNOB_Private.h new file mode 100755 index 0000000000..0eb4d2fee2 --- /dev/null +++ b/example/GUI/STemWin/inc/KNOB_Private.h @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : KNOB.h +Purpose : KNOB include +--------------------END-OF-HEADER------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef KNOB_PRIVATE_H +#define KNOB_PRIVATE_H + +#include "KNOB.h" +#include "GUI_Private.h" + +#if (GUI_SUPPORT_MEMDEV && GUI_WINSUPPORT) + +/********************************************************************* +* +* Object definition +* +********************************************************************** +*/ +typedef struct { + I32 Snap; // Position where the knob snaps + I32 Period; // Time it takes to stop the knob in ms + GUI_COLOR BkColor; // The Bk color + I32 Offset; // the offset + I32 MinRange; + I32 MaxRange; + I32 TickSize; // Minimum movement range in 1/10 of degree + I32 KeyValue; // Range of movement for one key push +} KNOB_PROPS; + +typedef struct { + WIDGET Widget; + KNOB_PROPS Props; + WM_HMEM hContext; + I32 Angle; + I32 Value; + int xSize; + int ySize; + GUI_MEMDEV_Handle hMemSrc; + GUI_MEMDEV_Handle hMemDst; + GUI_MEMDEV_Handle hMemBk; +} KNOB_OBJ; + +/********************************************************************* +* +* Macros for internal use +* +********************************************************************** +*/ +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL + #define KNOB_INIT_ID(p) p->Widget.DebugId = KNOB_ID +#else + #define KNOB_INIT_ID(p) +#endif + +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL + KNOB_OBJ * KNOB_LockH(KNOB_Handle h); + #define KNOB_LOCK_H(h) KNOB_LockH(h) +#else + #define KNOB_LOCK_H(h) (KNOB_OBJ *)GUI_LOCK_H(h) +#endif + +/********************************************************************* +* +* Module internal data +* +********************************************************************** +*/ +extern KNOB_PROPS KNOB__DefaultProps; + +#endif // (GUI_SUPPORT_MEMDEV && GUI_WINSUPPORT) +#endif // KNOB_PRIVATE_H diff --git a/example/GUI/STemWin/inc/LCD.h b/example/GUI/STemWin/inc/LCD.h new file mode 100755 index 0000000000..229cd02f75 --- /dev/null +++ b/example/GUI/STemWin/inc/LCD.h @@ -0,0 +1,772 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : LCD.h +Purpose : Declares LCD interface functions +---------------------------------------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef LCD_H +#define LCD_H + +#include "GUI_ConfDefaults.h" /* Used for GUI_CONST_STORAGE */ +#include "Global.h" + +#if defined(__cplusplus) +extern "C" { /* Make sure we have C-declarations in C++ programs */ +#endif + +/********************************************************************* +* +* Basic type defines +* +* The follwing are defines for types used in the LCD-driver and the +* GUI layers on top of that. Since "C" does not provide data types of +* fixed length which are identical on all platforms, this is done here. +* For most 16/32 controllers, the settings will work fine. However, if +* you have similar defines in other sections of your program, you might +* want to change or relocate these defines, e.g. in a TYPE.h file. +*/ +#define I16P I16 /* signed 16 bits OR MORE ! */ +#define U16P U16 /* unsigned 16 bits OR MORE ! */ + +/********************************************************************* +* +* Settings for windows simulation +* +* Some settings in the configuration may conflict with the values required +* in the Simulation. This is why we ignore the target settings for data +* types and use the correct settings for the simulation. +* (U32 could be defined as long, which would yield a 64 bit type on +* the PC) +*/ +#ifdef WIN32 + #pragma warning( disable : 4244 ) // Disable warning messages in simulation + #pragma warning( disable : 4761 ) // Disable warning "integral size mismatch in argument; conversion supplied" +#endif + +/********************************************************************* +* +* Constants +*/ +#define LCD_ERR0 (0x10) +#define LCD_ERR_CONTROLLER_NOT_FOUND (LCD_ERR0+1) +#define LCD_ERR_MEMORY (LCD_ERR0+2) + +/********************************************************************* +* +* Drawing modes +*/ +#define LCD_DRAWMODE_NORMAL (0) +#define LCD_DRAWMODE_XOR (1<<0) +#define LCD_DRAWMODE_TRANS (1<<1) +#define LCD_DRAWMODE_REV (1<<2) + +/********************************************************************* +* +* Typedefs +*/ +typedef int LCD_DRAWMODE; +typedef U32 LCD_COLOR; + +/********************************************************************* +* +* Data structures +*/ +typedef struct { I16P x,y; } GUI_POINT; +typedef struct { I16 x0,y0,x1,y1; } LCD_RECT; + +typedef struct { + int NumEntries; + char HasTrans; + const LCD_COLOR * pPalEntries; +} LCD_LOGPALETTE; + +/* This is used for the simulation only ! */ +typedef struct { + int x,y; + unsigned char KeyStat; +} LCD_tMouseState; + +typedef struct { + int NumEntries; + const LCD_COLOR * pPalEntries; +} LCD_PHYSPALETTE; + +/********************************************************************* +* +* LCD_L0_... color conversion +*/ +typedef LCD_COLOR tLCDDEV_Index2Color (LCD_PIXELINDEX Index); +typedef LCD_PIXELINDEX tLCDDEV_Color2Index (LCD_COLOR Color); +typedef LCD_PIXELINDEX tLCDDEV_GetIndexMask (void); + +typedef void tLCDDEV_Index2ColorBulk(void * pIndex, LCD_COLOR * pColor, U32 NumItems, U8 SizeOfIndex); +typedef void tLCDDEV_Color2IndexBulk(LCD_COLOR * pColor, void * pIndex, U32 NumItems, U8 SizeOfIndex); + +/********************************************************************* +* +* Color conversion API tables +*/ +typedef struct { + tLCDDEV_Color2Index * pfColor2Index; + tLCDDEV_Index2Color * pfIndex2Color; + tLCDDEV_GetIndexMask * pfGetIndexMask; + int NoAlpha; + tLCDDEV_Color2IndexBulk * pfColor2IndexBulk; + tLCDDEV_Index2ColorBulk * pfIndex2ColorBulk; +} LCD_API_COLOR_CONV; + +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_0; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_1; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_1_2; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_1_4; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_1_5; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_1_8; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_1_16; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_1_24; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_2; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_4; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_5; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_6; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_8; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_16; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_1616I; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_111; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_222; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_233; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_323; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_332; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_444_12; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_444_12_1; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_444_16; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_555; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_565; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_556; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_655; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_666; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_666_9; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_822216; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_84444; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_8666; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_8666_1; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_88666I; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_888; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_8888; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_M111; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_M1555I; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_M222; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_M233; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_M323; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_M332; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_M4444I; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_M444_12; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_M444_12_1; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_M444_16; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_M555; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_M565; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_M556; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_M655; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_M666; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_M666_9; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_M8565; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_M888; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_M8888; +extern const LCD_API_COLOR_CONV LCD_API_ColorConv_M8888I; + +#define GUICC_0 &LCD_API_ColorConv_0 +#define GUICC_1 &LCD_API_ColorConv_1 +#define GUICC_1_2 &LCD_API_ColorConv_1_2 +#define GUICC_1_4 &LCD_API_ColorConv_1_4 +#define GUICC_1_5 &LCD_API_ColorConv_1_5 +#define GUICC_1_8 &LCD_API_ColorConv_1_8 +#define GUICC_1_16 &LCD_API_ColorConv_1_16 +#define GUICC_1_24 &LCD_API_ColorConv_1_24 +#define GUICC_2 &LCD_API_ColorConv_2 +#define GUICC_4 &LCD_API_ColorConv_4 +#define GUICC_5 &LCD_API_ColorConv_5 +#define GUICC_6 &LCD_API_ColorConv_6 +#define GUICC_8 &LCD_API_ColorConv_8 +#define GUICC_16 &LCD_API_ColorConv_16 +#define GUICC_1616I &LCD_API_ColorConv_1616I +#define GUICC_111 &LCD_API_ColorConv_111 +#define GUICC_222 &LCD_API_ColorConv_222 +#define GUICC_233 &LCD_API_ColorConv_233 +#define GUICC_323 &LCD_API_ColorConv_323 +#define GUICC_332 &LCD_API_ColorConv_332 +#define GUICC_M4444I &LCD_API_ColorConv_M4444I +#define GUICC_444_12 &LCD_API_ColorConv_444_12 +#define GUICC_444_12_1 &LCD_API_ColorConv_444_12_1 +#define GUICC_444_16 &LCD_API_ColorConv_444_16 +#define GUICC_555 &LCD_API_ColorConv_555 +#define GUICC_565 &LCD_API_ColorConv_565 +#define GUICC_556 &LCD_API_ColorConv_556 +#define GUICC_655 &LCD_API_ColorConv_655 +#define GUICC_666 &LCD_API_ColorConv_666 +#define GUICC_666_9 &LCD_API_ColorConv_666_9 +#define GUICC_822216 &LCD_API_ColorConv_822216 +#define GUICC_84444 &LCD_API_ColorConv_84444 +#define GUICC_8666 &LCD_API_ColorConv_8666 +#define GUICC_8666_1 &LCD_API_ColorConv_8666_1 +#define GUICC_88666I &LCD_API_ColorConv_88666I +#define GUICC_888 &LCD_API_ColorConv_888 +#define GUICC_8888 &LCD_API_ColorConv_8888 +#define GUICC_M111 &LCD_API_ColorConv_M111 +#define GUICC_M1555I &LCD_API_ColorConv_M1555I +#define GUICC_M222 &LCD_API_ColorConv_M222 +#define GUICC_M233 &LCD_API_ColorConv_M233 +#define GUICC_M323 &LCD_API_ColorConv_M323 +#define GUICC_M332 &LCD_API_ColorConv_M332 +#define GUICC_M444_12 &LCD_API_ColorConv_M444_12 +#define GUICC_M444_12_1 &LCD_API_ColorConv_M444_12_1 +#define GUICC_M444_16 &LCD_API_ColorConv_M444_16 +#define GUICC_M555 &LCD_API_ColorConv_M555 +#define GUICC_M565 &LCD_API_ColorConv_M565 +#define GUICC_M556 &LCD_API_ColorConv_M556 +#define GUICC_M655 &LCD_API_ColorConv_M655 +#define GUICC_M666 &LCD_API_ColorConv_M666 +#define GUICC_M666_9 &LCD_API_ColorConv_M666_9 +#define GUICC_M8565 &LCD_API_ColorConv_M8565 +#define GUICC_M888 &LCD_API_ColorConv_M888 +#define GUICC_M8888 &LCD_API_ColorConv_M8888 +#define GUICC_M8888I &LCD_API_ColorConv_M8888I + +void GUICC_M1555I_SetCustColorConv(tLCDDEV_Color2IndexBulk * pfColor2IndexBulk, tLCDDEV_Index2ColorBulk * pfIndex2ColorBulk); +void GUICC_M565_SetCustColorConv (tLCDDEV_Color2IndexBulk * pfColor2IndexBulk, tLCDDEV_Index2ColorBulk * pfIndex2ColorBulk); +void GUICC_M4444I_SetCustColorConv(tLCDDEV_Color2IndexBulk * pfColor2IndexBulk, tLCDDEV_Index2ColorBulk * pfIndex2ColorBulk); +void GUICC_M888_SetCustColorConv (tLCDDEV_Color2IndexBulk * pfColor2IndexBulk, tLCDDEV_Index2ColorBulk * pfIndex2ColorBulk); +void GUICC_M8888I_SetCustColorConv(tLCDDEV_Color2IndexBulk * pfColor2IndexBulk, tLCDDEV_Index2ColorBulk * pfIndex2ColorBulk); + +/********************************************************************* +* +* Compatibility defines for older versions +*/ +#define GUI_COLOR_CONV_1 GUICC_1 +#define GUI_COLOR_CONV_2 GUICC_2 +#define GUI_COLOR_CONV_4 GUICC_4 +#define GUI_COLOR_CONV_8666 GUICC_8666 +#define GUI_COLOR_CONV_888 GUICC_888 +#define GUI_COLOR_CONV_8888 GUICC_8888 +#define GUI_COLOR_CONV_565 GUICC_565 +#define GUI_COLOR_CONV_M565 GUICC_M565 + +/********************************************************************* +* +* LCDDEV function table +* +* Below the routines which need to in an LCDDEV routine table are +* defined. All of these routines have to be in the low-level driver +* (LCD_L0) or in the memory device which can be used to replace the +* driver. +* The one exception to this is the SetClipRect routine, which would +* be identical for all drivers and is therefor contained in the +* level above (LCD). +*/ +typedef void tLCDDEV_DrawPixel (int x, int y); +typedef void tLCDDEV_DrawHLine (int x0, int y0, int x1); +typedef void tLCDDEV_DrawVLine (int x , int y0, int y1); +typedef void tLCDDEV_FillRect (int x0, int y0, int x1, int y1); +typedef unsigned int tLCDDEV_GetPixelIndex(int x, int y); +typedef void tLCDDEV_SetPixelIndex(int x, int y, int ColorIndex); +typedef void tLCDDEV_XorPixel (int x, int y); +typedef void tLCDDEV_FillPolygon (const GUI_POINT * pPoints, int NumPoints, int x0, int y0); +typedef void tLCDDEV_FillPolygonAA(const GUI_POINT * pPoints, int NumPoints, int x0, int y0); +typedef void tLCDDEV_GetRect (LCD_RECT * pRect); +typedef int tLCDDEV_Init (void); +typedef void tLCDDEV_On (void); +typedef void tLCDDEV_Off (void); +typedef void tLCDDEV_SetLUTEntry (U8 Pos, LCD_COLOR color); +typedef void * tLCDDEV_GetDevFunc (int Index); +typedef I32 tLCDDEV_GetDevProp (int Index); +typedef void tLCDDEV_SetOrg (int x, int y); + +/********************************************************************* +* +* Memory device API tables +*/ +typedef struct GUI_DEVICE GUI_DEVICE; +typedef struct GUI_DEVICE_API GUI_DEVICE_API; + +typedef void tLCDDEV_DrawBitmap (int x0, int y0, int xsize, int ysize, + int BitsPerPixel, int BytesPerLine, + const U8 * pData, int Diff, + const void * pTrans); /* Really LCD_PIXELINDEX, but is void to avoid compiler warnings */ +#define GUI_MEMDEV_APILIST_1 &GUI_MEMDEV_DEVICE_1 +#define GUI_MEMDEV_APILIST_8 &GUI_MEMDEV_DEVICE_8 +#define GUI_MEMDEV_APILIST_16 &GUI_MEMDEV_DEVICE_16 +#define GUI_MEMDEV_APILIST_32 &GUI_MEMDEV_DEVICE_32 + +/********************************************************************* +* +* Defines for device capabilities +* +* The following is the list of device capabilities which can, but do +* not have to be implemented in the driver. This way the driver can be +* enhanced in the future without affecting the driver interface, +* keeping older drivers compatible. +* More DevCaps can always be added in the future, as older drivers +* are guaranteed to return 0 for all unimplemented features or queries. +* +* The values below define the legal parameters to the LCD_GetDeviceCaps +* and the LCD_GetpCapFunc routines. +*/ + +#define LCD_DEVCAP_XSIZE 0x01 /* Quest horiz. res. of display */ +#define LCD_DEVCAP_YSIZE 0x02 /* Quest vert. res. of display */ +#define LCD_DEVCAP_VXSIZE 0x03 /* Quest vert. res. of virtual disp.*/ +#define LCD_DEVCAP_VYSIZE 0x04 /* Quest vert. res. of virtual disp.*/ +#define LCD_DEVCAP_XORG 0x05 /* X-origin ... usually 0 */ +#define LCD_DEVCAP_YORG 0x06 /* Y-origin ... usually 0 */ +#define LCD_DEVCAP_CONTROLLER 0x07 /* LCD Controller (Numerical) */ +#define LCD_DEVCAP_BITSPERPIXEL 0x08 /* Bits per pixel ... 1/2/4/8 */ +#define LCD_DEVCAP_NUMCOLORS 0x09 /* Quest number of colors */ +#define LCD_DEVCAP_XMAG 0x0A +#define LCD_DEVCAP_YMAG 0x0B +#define LCD_DEVCAP_MIRROR_X 0x0C +#define LCD_DEVCAP_MIRROR_Y 0x0D +#define LCD_DEVCAP_SWAP_XY 0x0E +#define LCD_DEVCAP_SWAP_RB 0x0F + +int LCD_GetXSizeMax(void); +int LCD_GetYSizeMax(void); +int LCD_GetVXSizeMax(void); +int LCD_GetVYSizeMax(void); +int LCD_GetBitsPerPixelMax(void); +void LCD_SetDisplaySize(int xSizeDisplay, int ySizeDisplay); +int LCD_GetXSizeDisplay(void); +int LCD_GetYSizeDisplay(void); + +int LCD_GetXSizeEx (int LayerIndex); +int LCD_GetYSizeEx (int LayerIndex); +int LCD_GetVXSizeEx (int LayerIndex); +int LCD_GetVYSizeEx (int LayerIndex); +int LCD_GetBitsPerPixelEx (int LayerIndex); +U32 LCD_GetNumColorsEx (int LayerIndex); +int LCD_GetXMagEx (int LayerIndex); +int LCD_GetYMagEx (int LayerIndex); +int LCD_GetMirrorXEx (int LayerIndex); +int LCD_GetMirrorYEx (int LayerIndex); +int LCD_GetSwapXYEx (int LayerIndex); +int LCD_GetReversLUTEx (int LayerIndex); +int LCD_GetPhysColorsInRAMEx(int LayerIndex); + +int LCD_GetXSize (void); +int LCD_GetYSize (void); +int LCD_GetVXSize (void); +int LCD_GetVYSize (void); +int LCD_GetBitsPerPixel (void); +U32 LCD_GetNumColors (void); +int LCD_GetXMag (void); +int LCD_GetYMag (void); +int LCD_GetMirrorX (void); +int LCD_GetMirrorY (void); +int LCD_GetSwapXY (void); +int LCD_GetReversLUT (void); +int LCD_GetPhysColorsInRAM (void); + +I32 LCD__GetBPP (U32 IndexMask); +I32 LCD__GetBPPDevice(U32 IndexMask); + +tLCDDEV_Index2Color * LCD_GetpfIndex2ColorEx(int LayerIndex); +tLCDDEV_Color2Index * LCD_GetpfColor2IndexEx(int LayerIndex); + +tLCDDEV_Color2Index * LCD_GetpfColor2Index(void); + +int LCD_GetNumLayers(void); + +LCD_COLOR * LCD_GetPalette (void); +LCD_COLOR * LCD_GetPaletteEx(int LayerIndex); + +void (* LCD_GetDevFunc(int LayerIndex, int Item))(void); + +/********************************************************************* +* +* Values for requesting and setting function pointers (display driver) +*/ + /* Request of a function pointer for... */ +#define LCD_DEVFUNC_READRECT 0x01 /* ...reading a rectangular display area */ +#define LCD_DEVFUNC_SETALPHA 0x02 /* ...setting the alpha blending factor */ +#define LCD_DEVFUNC_SETPOS 0x03 /* ...setting the layer position */ +#define LCD_DEVFUNC_GETPOS 0x04 /* ...getting the layer position */ +#define LCD_DEVFUNC_SETSIZE 0x05 /* ...setting the layer size */ +#define LCD_DEVFUNC_SETVIS 0x06 /* ...setting the visibility of a layer */ +#define LCD_DEVFUNC_24BPP 0x07 /* ...drawing 24bpp bitmaps */ +#define LCD_DEVFUNC_NEXT_PIXEL 0x08 /* ...drawing a bitmap pixel by pixel */ +#define LCD_DEVFUNC_SET_VRAM_ADDR 0x09 /* ...setting the VRAM address */ +#define LCD_DEVFUNC_SET_VSIZE 0x0A /* ...setting the VRAM size */ +#define LCD_DEVFUNC_SET_SIZE 0x0B /* ...setting the display size */ +#define LCD_DEVFUNC_INIT 0x0C /* ...initializing the display controller */ +#define LCD_DEVFUNC_CONTROLCACHE 0x0D /* ...controlling the cache */ +#define LCD_DEVFUNC_ON 0x0E /* ...switching the display on */ +#define LCD_DEVFUNC_OFF 0x0F /* ...switching the display off */ +#define LCD_DEVFUNC_SETLUTENTRY 0x10 /* ...setting a LUT entry */ +#define LCD_DEVFUNC_FILLPOLY 0x11 /* ...filling a polygon */ +#define LCD_DEVFUNC_FILLPOLYAA 0x12 /* ...filling an antialiased polygon */ +#define LCD_DEVFUNC_ALPHAMODE 0x13 /* ...setting the alpha blending mode */ +#define LCD_DEVFUNC_CHROMAMODE 0x14 /* ...setting the chroma blending mode */ +#define LCD_DEVFUNC_CHROMA 0x15 /* ...setting the chroma values */ +#define LCD_DEVFUNC_SETFUNC 0x16 /* ...setting a function pointer */ +#define LCD_DEVFUNC_REFRESH 0x17 /* ...refreshing the display */ +#define LCD_DEVFUNC_SETRECT 0x18 /* ...setting the drawing rectangle */ + /* Setting a function pointer for... */ +#define LCD_DEVFUNC_FILLRECT 0x19 /* ...filling a rectangular area */ +#define LCD_DEVFUNC_DRAWBMP_1BPP 0x20 /* ...drawing a 1bpp bitmap */ +#define LCD_DEVFUNC_COPYBUFFER 0x21 /* ...copying complete frame buffers */ +#define LCD_DEVFUNC_SHOWBUFFER 0x22 /* ...shows the given buffer */ +#define LCD_DEVFUNC_COPYRECT 0x23 /* ...filling a rectangular area */ +#define LCD_DEVFUNC_DRAWBMP_16BPP 0x24 /* ...drawing a 16bpp bitmap */ +#define LCD_DEVFUNC_DRAWBMP_8BPP 0x25 /* ...drawing a 8bpp bitmap */ +#define LCD_DEVFUNC_READPIXEL 0x26 /* ...reading a pixel index */ +#define LCD_DEVFUNC_READMPIXELS 0x27 /* ...reading multiple pixel indices */ +#define LCD_DEVFUNC_DRAWBMP_32BPP 0x28 /* ...drawing a 32bpp bitmap */ + +/********************************************************************* +* +* Values for requesting function pointers (memory devices) +*/ + /* Request of a function pointer for... */ +#define MEMDEV_DEVFUNC_WRITETOACTIVE 0x16 /* ...writing the memory device */ + +/********************************************************************* +* +* Values for requesting data +*/ + /* Request pointer to... */ +#define LCD_DEVDATA_MEMDEV 0x01 /* ...default memory device API */ +#define LCD_DEVDATA_PHYSPAL 0x02 /* ...physical palette */ + +/********************************************************************* +* +* Structures for passing data to LCD_X_DisplayDriver() +*/ +typedef struct { + void * pVRAM; +} LCD_X_SETVRAMADDR_INFO; + +typedef struct { + int xPos, yPos; +} LCD_X_SETORG_INFO; + +typedef struct { + LCD_COLOR Color; + U8 Pos; +} LCD_X_SETLUTENTRY_INFO; + +typedef struct { + int xSize, ySize; +} LCD_X_SETSIZE_INFO; + +typedef struct { + int xPos, yPos; + int xLen, yLen; + int BytesPerPixel; + U32 Off; +} LCD_X_SETPOS_INFO; + +typedef struct { + int Alpha; +} LCD_X_SETALPHA_INFO; + +typedef struct { + int OnOff; +} LCD_X_SETVIS_INFO; + +typedef struct { + int AlphaMode; +} LCD_X_SETALPHAMODE_INFO; + +typedef struct { + int ChromaMode; +} LCD_X_SETCHROMAMODE_INFO; + +typedef struct { + LCD_COLOR ChromaMin; + LCD_COLOR ChromaMax; +} LCD_X_SETCHROMA_INFO; + +typedef struct { + int Index; +} LCD_X_SHOWBUFFER_INFO; + +/********************************************************************* +* +* Commands for LCD_X_DisplayDriver() +*/ +#define LCD_X_INITCONTROLLER 0x01 /* Initializing the display controller */ +#define LCD_X_SETVRAMADDR 0x02 /* Setting the video RAM address */ +#define LCD_X_SETORG 0x03 /* Setting the origin within a layer */ +#define LCD_X_SETLUTENTRY 0x04 /* Setting an entry of the LUT */ +#define LCD_X_ON 0x05 /* Switching the display on */ +#define LCD_X_OFF 0x06 /* Switching the display off */ +#define LCD_X_SETSIZE 0x07 /* Setting the layer size */ +#define LCD_X_SETPOS 0x08 /* Setting the layer position */ +#define LCD_X_SETVIS 0x09 /* Setting the visibility of a layer */ +#define LCD_X_SETALPHA 0x0A /* Setting the alpha value of the layer */ +#define LCD_X_SETALPHAMODE 0x0B /* Setting the alpha blending mode */ +#define LCD_X_SETCHROMAMODE 0x0C /* Setting the chroma blending mode */ +#define LCD_X_SETCHROMA 0x0D /* Setting the chroma values */ +#define LCD_X_SHOWBUFFER 0x0E /* Switching to the given buffer */ + +int LCD_X_DisplayDriver(unsigned LayerIndex, unsigned Cmd, void * pData); +void LCD_X_Config(void); + +/********************************************************************* +* +* Set layer properties +*/ +int LCD_SetAlphaEx (int LayerIndex, int Alpha); +int LCD_SetPosEx (int LayerIndex, int xPos, int yPos); +int LCD_SetSizeEx (int LayerIndex, int xSize, int ySize); +int LCD_SetVisEx (int LayerIndex, int OnOff); +int LCD_SetVRAMAddrEx (int LayerIndex, void * pVRAM); +int LCD_SetVSizeEx (int LayerIndex, int xSize, int ySize); +int LCD_SetAlphaModeEx (int LayerIndex, int AlphaMode); +int LCD_SetChromaModeEx(int LayerIndex, int ChromaMode); +int LCD_SetChromaEx (int LayerIndex, LCD_COLOR ChromaMin, LCD_COLOR ChromaMax); + +int LCD_SetAlpha (int Alpha); +int LCD_SetVRAMAddr (void * pVRAM); +int LCD_SetVSize (int xSize, int ySize); +int LCD_SetSize (int xSize, int ySize); +int LCD_SetVis (int OnOff); +int LCD_SetPos (int xPos, int yPos); +int LCD_SetAlphaMode (int AlphaMode); +int LCD_SetChromaMode(int ChromaMode); +int LCD_SetChroma (LCD_COLOR ChromaMin, LCD_COLOR ChromaMax); +int LCD_SetLUTEntry (U8 Pos, LCD_COLOR Color); +int LCD_SetDevFunc (int LayerIndex, int IdFunc, void (* pDriverFunc)(void)); + +void LCD_SetOrg(int xOrg, int yOrg); + +int LCD_OnEx (int LayerIndex); +int LCD_OffEx(int LayerIndex); +int LCD_On (void); +int LCD_Off (void); + +/********************************************************************* +* +* Get layer properties +*/ +int LCD_GetPosEx(int LayerIndex, int * pxPos, int * pyPos); + +int LCD_GetPos (int * pxPos, int * pyPos); + +/********************************************************************* +* +* Display refresh (optional) +*/ +int LCD_Refresh (void); +int LCD_RefreshEx(int LayerIndex); + +/********************************************************************* +* +* NEXT_PIXEL API support +*/ +typedef struct { + int (* pfStart) (int x0, int y0, int x1, int y1); + void (* pfSetPixel)(LCD_PIXELINDEX PixelIndex); + void (* pfNextLine)(void); + void (* pfEnd) (void); +} LCD_API_NEXT_PIXEL; + +LCD_API_NEXT_PIXEL * LCD_GetNextPixelAPI(void); + +/********************************************************************* +* +* LCD_CLIP function table +*/ +typedef void tLCD_HL_DrawHLine (int x0, int y0, int x1); +typedef void tLCD_HL_DrawPixel (int x0, int y0); + +typedef struct { + tLCD_HL_DrawHLine * pfDrawHLine; + tLCD_HL_DrawPixel * pfDrawPixel; +} tLCD_HL_APIList; + +void LCD_DrawHLine(int x0, int y0, int x1); +void LCD_DrawPixel(int x0, int y0); +void LCD_DrawVLine(int x, int y0, int y1); + + +/********************************************************************* +* +* Declarations for LCD_ +*/ +void LCD_SetClipRectEx(const LCD_RECT * pRect); +void LCD_SetClipRectMax(void); + +/* Get device capabilities (0 if not supported) */ +I32 LCD_GetDevCap (int Index); +I32 LCD_GetDevCapEx(int LayerIndex, int Index); + +/* Initialize LCD using config-parameters */ +int emWin_LCD_Init(void); +int LCD_InitColors(void); + +void LCD_SetBkColor (LCD_COLOR Color); /* Set background color */ +void LCD_SetColor (LCD_COLOR Color); /* Set foreground color */ +void LCD_SetPixelIndex(int x, int y, int ColorIndex); + +/* Palette routines (Not available on all drivers) */ +void LCD_InitLUT(void); +int LCD_SetLUTEntryEx(int LayerIndex, U8 Pos, LCD_COLOR Color); +void LCD_SetLUTEx(int LayerIndex, const LCD_PHYSPALETTE * pPalette); +void LCD_SetLUT (const LCD_PHYSPALETTE * pPalette); + +LCD_DRAWMODE LCD_SetDrawMode (LCD_DRAWMODE dm); +void LCD_SetColorIndex(unsigned PixelIndex); +void LCD_SetBkColorIndex(unsigned PixelIndex); +void LCD_FillRect(int x0, int y0, int x1, int y1); +typedef void tLCD_SetPixelAA(int x, int y, U8 Intens); + +void LCD_SetPixelAA4_Trans (int x, int y, U8 Intens); +void LCD_SetPixelAA4_NoTrans(int x, int y, U8 Intens); + +void LCD_SetPixelAA8_Trans (int x, int y, U8 Intens); +void LCD_SetPixelAA8_NoTrans(int x, int y, U8 Intens); + +void LCD_AA_EnableGamma(int OnOff); +void LCD_AA_SetGamma (U8 * pGamma); +void LCD_AA_GetGamma (U8 * pGamma); + +LCD_COLOR LCD_AA_MixColors16 (LCD_COLOR Color, LCD_COLOR BkColor, U8 Intens); +LCD_COLOR LCD_AA_MixColors256(LCD_COLOR Color, LCD_COLOR BkColor, U8 Intens); +LCD_COLOR LCD_MixColors256 (LCD_COLOR Color, LCD_COLOR BkColor, unsigned Intens); +LCD_COLOR LCD_GetPixelColor(int x, int y); /* Get RGB color of pixel */ +unsigned int LCD_GetPixelIndex(int x, int y); +int LCD_GetBkColorIndex (void); +int LCD_GetColorIndex (void); +#if (GUI_USE_ARGB) +U32 LCD_AA_SetOrMask(U32 OrMask); +#else +U32 LCD_AA_SetAndMask(U32 AndMask); +#endif + +/* Configuration */ +int LCD_SetMaxNumColors(unsigned MaxNumColors); +int LCD_GetMaxNumColors(void); +void LCD__SetPaletteConversionHook(void (* pfPaletteConversionHook)(const LCD_LOGPALETTE * pLogPal)); + +/********************************************************************* +* +* Optional support for rotation +*/ +#if GUI_SUPPORT_ROTATION + +typedef void tLCD_DrawBitmap(int x0, int y0, int xsize, int ysize, + int xMul, int yMul, int BitsPerPixel, int BytesPerLine, + const U8 * pPixel, const void * pTrans); +typedef void tRect2TextRect (LCD_RECT * pRect); + +struct tLCD_APIList_struct { + tLCD_DrawBitmap * pfDrawBitmap; + tRect2TextRect * pfRect2TextRect; + tRect2TextRect * pfTransformRect; +}; + +typedef struct tLCD_APIList_struct tLCD_APIList; + +extern tLCD_APIList LCD_APIListCCW; +extern tLCD_APIList LCD_APIListCW; +extern tLCD_APIList LCD_APIList180; + +#define GUI_ROTATION tLCD_APIList +#define GUI_ROTATE_CCW &LCD_APIListCCW +#define GUI_ROTATE_CW &LCD_APIListCW +#define GUI_ROTATE_180 &LCD_APIList180 +#define GUI_ROTATE_0 0 + +tLCD_SetPixelAA * LCD__GetPfSetPixel(int BitsPerPixel); + +#endif + +/********************************************************************* +* +* Physical color access, internally used only +*/ +void LCD__SetPhysColor(U8 Pos, LCD_COLOR Color); + +/********************************************************************* +* +* Cache control +*/ +#define LCD_CC_UNLOCK (0) /* Default mode: Cache is transparent */ +#define LCD_CC_LOCK (1) /* Cache is locked, no write operations */ +#define LCD_CC_FLUSH (2) /* Flush cache, do not change mode */ + +int LCD_ControlCache (int Cmd); +int LCD_ControlCacheEx(int LayerIndex, int Cmd); + +/********************************************************************* +* +* Color conversion +*/ +LCD_PIXELINDEX LCD_Color2Index (LCD_COLOR Color); +LCD_COLOR LCD_Index2Color (int Index); +LCD_COLOR LCD_Index2ColorEx (int i, unsigned LayerIndex); + +/********************************************************************* +* +* LCD_X_... +*/ +unsigned char LCD_X_Read00(void); +unsigned char LCD_X_Read01(void); +void LCD_X_Write00 (unsigned char c); +void LCD_X_Write01 (unsigned char c); +void LCD_X_WriteM01(unsigned char * pData, int NumBytes); + +#if defined(__cplusplus) + } +#endif + +#endif /* LCD_H */ + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/LCD_ConfDefaults.h b/example/GUI/STemWin/inc/LCD_ConfDefaults.h new file mode 100755 index 0000000000..7ea7371d99 --- /dev/null +++ b/example/GUI/STemWin/inc/LCD_ConfDefaults.h @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : LCD_ConfDefaults.h +Purpose : Valid LCD configuration and defaults +---------------------------------------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef LCD_CONFIG_DEFAULTS_H +#define LCD_CONFIG_DEFAULTS_H + +#include "LCDConf.h" /* Configuration header file */ + +/********************************************************** +* +* Configuration defaults +*/ +#ifndef LCD_MIRROR_X + #define LCD_MIRROR_X 0 +#endif +#ifndef LCD_MIRROR_Y + #define LCD_MIRROR_Y 0 +#endif +#ifndef LCD_SWAP_XY + #define LCD_SWAP_XY 0 +#endif +#ifndef LCD_FIRSTCOM0 + #define LCD_FIRSTCOM0 0 +#endif +#ifndef LCD_FIRSTSEG0 + #define LCD_FIRSTSEG0 0 +#endif +#ifndef LCD_SWAP_RB + #define LCD_SWAP_RB 0 +#endif +#ifndef LCD_DISPLAY_INDEX + #define LCD_DISPLAY_INDEX 0 +#endif +#ifndef LCD_ENDIAN_BIG + #define LCD_ENDIAN_BIG 0 +#endif +#ifndef LCD_ALLOW_NON_OPTIMIZED_MODE + #define LCD_ALLOW_NON_OPTIMIZED_MODE 1 +#endif + +#endif /* LCD_CONFIG_DEFAULTS_H */ + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/LCD_Private.h b/example/GUI/STemWin/inc/LCD_Private.h new file mode 100755 index 0000000000..cd7de97b1c --- /dev/null +++ b/example/GUI/STemWin/inc/LCD_Private.h @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : LCD_Private.h +Purpose : To be used only by the display drivers +---------------------------------------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef LCD_Private_H +#define LCD_Private_H + +#include "LCDConf.h" +#include "LCD_Protected.h" +#include "GUI.h" + +/********************************************************************* +* +* API functions +*/ +extern const struct tLCDDEV_APIList_struct * /* const */ LCD_aAPI[GUI_NUM_LAYERS]; + +/********************************************************************* +* +* Support for Segment/COMLUTs +*/ +#define LCD_TYPE_SEGTRANS U16 +#define LCD_TYPE_COMTRANS U16 + +#ifdef LCD_LUT_COM + extern LCD_TYPE_COMTRANS LCD__aLine2Com0[LCD_YSIZE]; +#endif + +#ifdef LCD_LUT_SEG + extern LCD_TYPE_COMTRANS LCD__aCol2Seg0[LCD_XSIZE]; +#endif + +/********************************************************************* +* +* Support for multiple display controllers +*/ +#define DECLARE_PROTOTYPES(DISTX) \ + void LCD_##DISTX##_SetPixelIndex(int x, int y, int PixelIndex); \ + unsigned LCD_##DISTX##_GetPixelIndex(int x, int y); \ + void LCD_##DISTX##_XorPixel (int x, int y); \ + void LCD_##DISTX##_DrawHLine (int x0, int y, int x1); \ + void LCD_##DISTX##_DrawVLine (int x, int y0, int y1); \ + void LCD_##DISTX##_FillRect (int x0, int y0, int x1, int y1); \ + void LCD_##DISTX##_DrawBitmap (int x0, int y0, int xsize, int ysize, int BitsPerPixel, int BytesPerLine, const U8 * pData, int Diff, const LCD_PIXELINDEX * pTrans); \ + void LCD_##DISTX##_SetOrg (int x, int y); \ + void LCD_##DISTX##_On (void); \ + void LCD_##DISTX##_Off (void); \ + int LCD_##DISTX##_Init (void); \ + void LCD_##DISTX##_SetLUTEntry (U8 Pos, LCD_COLOR Color); \ + void * LCD_##DISTX##_GetDevFunc (int Index); \ + void LCD_##DISTX##_ReInit (void) + +DECLARE_PROTOTYPES(DIST0); +DECLARE_PROTOTYPES(DIST1); +DECLARE_PROTOTYPES(DIST2); +DECLARE_PROTOTYPES(DIST3); + +#endif /* Avoid multiple inclusion */ + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/LCD_Protected.h b/example/GUI/STemWin/inc/LCD_Protected.h new file mode 100755 index 0000000000..2d593d31d2 --- /dev/null +++ b/example/GUI/STemWin/inc/LCD_Protected.h @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : LCD_Protected.h +Purpose : LCD level - To be used only internally by the GUI +---------------------------------------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef LCD_PROTECTED_H +#define LCD_PROTECTED_H + +#include "LCD.h" + +#if defined(__cplusplus) +extern "C" { /* Make sure we have C-declarations in C++ programs */ +#endif + +/********************************************************************* +* +* Data types +*/ +typedef struct { + LCD_COLOR * paColor; + I16 NumEntries; +} LCD_LUT_INFO; + +typedef struct { + tLCDDEV_DrawPixel * pfDrawPixel; + tLCDDEV_DrawHLine * pfDrawHLine; + tLCDDEV_DrawVLine * pfDrawVLine; + tLCDDEV_FillRect * pfFillRect; + tLCDDEV_DrawBitmap * pfDrawBitmap; +} LCD_API_LIST; + +/********************************************************************* +* +* External data +*/ +extern GUI_CONST_STORAGE U8 LCD_aMirror[256]; +extern LCD_PIXELINDEX * LCD__aConvTable; + +/********************************************************************* +* +* Misc functions +*/ +void LCD_UpdateColorIndices (void); +int LCD_PassingBitmapsAllowed(void); +void LCD_EnableCursor (int OnOff); +void LCD_SelectLCD (void); + +void LCD_DrawBitmap(int x0, int y0, + int xsize, int ysize, + int xMul, int yMul, + int BitsPerPixel, + int BytesPerLine, + const U8 * pPixel, + const LCD_PIXELINDEX * pTrans); + +void LCD__DrawBitmap_1bpp(int x0, int y0, + int xsize, int ysize, + int xMul, int yMul, + int BitsPerPixel, + int BytesPerLine, + const U8 * pPixel, + const LCD_PIXELINDEX * pTrans, + int OffData); + +/********************************************************************* +* +* Internal used color conversion routines +*/ +tLCDDEV_Index2Color LCD_Index2Color_444_12; +tLCDDEV_Index2Color LCD_Index2Color_M444_12; +tLCDDEV_Index2Color LCD_Index2Color_444_12_1; +tLCDDEV_Index2Color LCD_Index2Color_M444_12_1; +tLCDDEV_Index2Color LCD_Index2Color_444_16; +tLCDDEV_Index2Color LCD_Index2Color_M444_16; +tLCDDEV_Index2Color LCD_Index2Color_555; +tLCDDEV_Index2Color LCD_Index2Color_565; +tLCDDEV_Index2Color LCD_Index2Color_8666; +tLCDDEV_Index2Color LCD_Index2Color_888; +tLCDDEV_Index2Color LCD_Index2Color_8888; +tLCDDEV_Index2Color LCD_Index2Color_M8888I; +tLCDDEV_Index2Color LCD_Index2Color_M555; +tLCDDEV_Index2Color LCD_Index2Color_M565; +tLCDDEV_Index2Color LCD_Index2Color_M888; + +tLCDDEV_Color2Index LCD_Color2Index_8666; + +#if defined(__cplusplus) +} +#endif + +#endif /* LCD_PROTECTED_H */ + +/*************************** End of file ****************************/ + diff --git a/example/GUI/STemWin/inc/LCD_SIM.h b/example/GUI/STemWin/inc/LCD_SIM.h new file mode 100755 index 0000000000..22ac8e168b --- /dev/null +++ b/example/GUI/STemWin/inc/LCD_SIM.h @@ -0,0 +1,222 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : LCD_SIM.h +Purpose : Declares LCD interface functions +---------------------------------------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef LCDSIM_H +#define LCDSIM_H + +#include "LCD.h" + +/************************************************************ +* +* Defines +* +************************************************************* +*/ +#define LCDSIM_MAX_DISPLAYS GUI_NUM_LAYERS + +#define GUI_TRANSMODE_PIXELALPHA 0 +#define GUI_TRANSMODE_CHROMA 1 +#define GUI_TRANSMODE_ZERO 2 + +/************************************************************ +* +* LCDSIM_ General declarations +* +************************************************************* +*/ +void LCDSIM_PreInit(void); +char* LCDSIM_Init(void); +void LCDSIM_Exit(void); +int LCDSIM_GetMouseState(LCD_tMouseState *pState); +void LCDSIM_SetMouseState(int x, int y, int KeyStat, int LayerIndex); +void LCDSIM_CheckMouseState(int LayerIndex); +int LCDSIM_SaveSBMP (const char * sFileName); +int LCDSIM_SaveSBMPEx(const char * sFileName, int x0, int y0, int xSize, int ySize); +void LCDSIM_SetRGBOrder(unsigned RGBOrder); + +/************************************************************ +* +* LCDSIM_ Functions for each display +* +************************************************************* +*/ +void LCDSIM_FillRect(int x0, int y0, int x1, int y1, int Index, int LayerIndex); +int LCDSIM_GetModifyCnt(int LayerIndex); +int LCDSIM_GetModifyCntInfo(int LayerIndex); +int LCDSIM_GetPixelColor(int x, int y, int LayerIndex); +int LCDSIM_GetPixelIndex(int x, int y, int LayerIndex); +int LCDSIM_Index2Color(int Index, int LayerIndex); +int LCDSIM_RLUT_GetPixelIndex(int x, int y, int LayerIndex); +void LCDSIM_RLUT_SetPixelIndex(int x, int y, int Index, int LayerIndex); +void LCDSIM_SetLUTEntry(U8 Pos, LCD_COLOR color, int LayerIndex); +void LCDSIM_SetPixelIndex(int x, int y, int Index, int LayerIndex); +void LCDSIM_SetPixelColor(int x, int y, LCD_COLOR PixelColor, int LayerIndex); +void LCDSIM_SetSubPixel(int x, int y, U8 Value, int LayerIndex); +void LCDSIM_SetPixelPhys(int x, int y, int Index, int LayerIndex); +int LCDSIM_GetPixelPhys(int xPhys, int yPhys, int LayerIndex); +void LCDSIM_FillRectPhys(int x0Phys, int y0Phys, int x1Phys, int y1Phys, int Index, int LayerIndex); +void LCDSIM_SetOrg(int x, int y, int LayerIndex); +void LCDSIM_SetAlpha(int Alpha, int LayerIndex); +int LCDSIM_GetAlpha(int LayerIndex); +void LCDSIM_SetLayerPos(int xPos, int yPos, int LayerIndex); +void LCDSIM_SetLayerVis(int OnOff, int LayerIndex); +void LCDSIM_SetSize(int LayerIndex, int xSize, int ySize); +void LCDSIM_SetTransMode(int LayerIndex, int TransMode); +void LCDSIM_SetChroma(int LayerIndex, LCD_COLOR ChromaMin, LCD_COLOR ChromaMax); +void LCDSIM_SetCompositeColor(U32 Color); +void LCDSIM_SetCompositeSize(int xSize, int ySize); +void LCDSIM_CopyBuffer(int LayerIndex, int IndexSrc, int IndexDst); +void LCDSIM_Invalidate(int LayerIndex); + +/******************************************************************** +* +* Publics for LCD +* +********************************************************************* +*/ +void SIM_GUI_SetCompositeSize(int xSize, int ySize); +void SIM_GUI_SetCompositeColor(U32 Color); +U32 SIM_GUI_GetCompositeColor(void); +void SIM_GUI_SetLCDPos(int xPos, int yPos); +int SIM_GUI_SaveBMP(const char * sFileName); +int SIM_GUI_SaveBMPEx(const char * sFileName, int x0, int y0, int xSize, int ySize); +int SIM_GUI_SaveCompositeBMP(const char * sFileName); +int SIM_GUI_SetTransColor(int Color); +int SIM_GUI_SetLCDColorBlack (unsigned int Index, int Color); +int SIM_GUI_SetLCDColorWhite (unsigned int Index, int Color); +void SIM_GUI_SetMag(int MagX, int MagY); +int SIM_GUI_GetMagX(void); +int SIM_GUI_GetMagY(void); +int SIM_GUI_GetForwardRButton(void); +void SIM_GUI_SetForwardRButton(int OnOff); +void SIM_GUI_SetTransMode(int LayerIndex, int TransMode); +void SIM_GUI_SetChroma(int LayerIndex, unsigned long ChromaMin, unsigned long ChromaMax); +void SIM_GUI_UseCustomBitmaps(void); +void SIM_GUI_SetAccellerator(int Accellerator); +void SIM_GUI_SetMainScreenOffset(int x, int y); +void SIM_GUI_SetCompositeTouch(int LayerIndex); +int SIM_GUI_GetCompositeTouch(void); + +/******************************************************************** +* +* Routine(s) in user application +* +********************************************************************* +*/ +void SIM_X_Config(void); /* Allow init before application starts ... Use it to set LCD offset etc */ + +/******************************************************************** +* +* Publics used by GUI_X module +* +********************************************************************* +*/ +void SIM_GUI_Delay (int ms); +void SIM_GUI_ExecIdle(void); +int SIM_GUI_GetTime(void); +int SIM_GUI_GetKey(void); +int SIM_GUI_WaitKey(void); +void SIM_GUI_StoreKey(int); + +/******************************************************************** +* +* Publics for logging, warning, errorout +* +********************************************************************* +*/ +void SIM_GUI_Log(const char *s); +void SIM_GUI_Log1(const char *s, int p0); +void SIM_GUI_Log2(const char *s, int p0, int p1); +void SIM_GUI_Log3(const char *s, int p0, int p1, int p2); +void SIM_GUI_Log4(const char *s, int p0, int p1, int p2,int p3); +void SIM_GUI_Warn(const char *s); +void SIM_GUI_Warn1(const char *s, int p0); +void SIM_GUI_Warn2(const char *s, int p0, int p1); +void SIM_GUI_Warn3(const char *s, int p0, int p1, int p2); +void SIM_GUI_Warn4(const char *s, int p0, int p1, int p2, int p3); +void SIM_GUI_ErrorOut(const char *s); +void SIM_GUI_ErrorOut1(const char *s, int p0); +void SIM_GUI_ErrorOut2(const char *s, int p0, int p1); +void SIM_GUI_ErrorOut3(const char *s, int p0, int p1, int p2); +void SIM_GUI_ErrorOut4(const char *s, int p0, int p1, int p2, int p3); +void SIM_GUI_EnableMessageBoxOnError(int Status); + +/******************************************************************** +* +* Commandline support +* +********************************************************************* +*/ +const char *SIM_GUI_GetCmdLine(void); + +/******************************************************************** +* +* Multitasking support +* +********************************************************************* +*/ +void SIM_GUI_CreateTask(char * pName, void * pFunc); +void SIM_GUI_Start(void); +unsigned long SIM_GUI_GetTaskID(void); +void SIM_GUI_Lock(void); +void SIM_GUI_Unlock(void); +void SIM_GUI_InitOS(void); + +#endif /* LCD_H */ + + + + diff --git a/example/GUI/STemWin/inc/LISTBOX.h b/example/GUI/STemWin/inc/LISTBOX.h new file mode 100755 index 0000000000..19afdfa6d9 --- /dev/null +++ b/example/GUI/STemWin/inc/LISTBOX.h @@ -0,0 +1,234 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : LISTBOX.h +Purpose : LISTBOX widget include +--------------------END-OF-HEADER------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef LISTBOX_H +#define LISTBOX_H + +#include "WM.h" +#include "WIDGET.h" /* Req. for WIDGET_DRAW_ITEM_FUNC */ +#include "DIALOG_Intern.h" /* Req. for Create indirect data structure */ + +#if GUI_WINSUPPORT + +#if defined(__cplusplus) + extern "C" { /* Make sure we have C-declarations in C++ programs */ +#endif + +/********************************************************************* +* +* defines +* +********************************************************************** +*/ + +#define LISTBOX_ALL_ITEMS -1 + +/********************************************************************* +* +* Color indices +*/ +#define LISTBOX_CI_UNSEL 0 +#define LISTBOX_CI_SEL 1 +#define LISTBOX_CI_SELFOCUS 2 +#define LISTBOX_CI_DISABLED 3 + +/************************************************************ +* +* States +*/ +typedef WM_HMEM LISTBOX_Handle; + +/********************************************************************* +* +* Notification codes +* +* The following is the list of notification codes specific to this widget, +* Send with the WM_NOTIFY_PARENT message +*/ +#define LISTBOX_NOTIFICATION_LOST_FOCUS (WM_NOTIFICATION_WIDGET + 0) + +/************************************************************ +* +* Create / Status flags +*/ +#define LISTBOX_CF_AUTOSCROLLBAR_H (1<<0) +#define LISTBOX_CF_AUTOSCROLLBAR_V (1<<1) +#define LISTBOX_CF_MULTISEL (1<<2) +#define LISTBOX_CF_WRAP (1<<3) +#define LISTBOX_SF_AUTOSCROLLBAR_H LISTBOX_CF_AUTOSCROLLBAR_H +#define LISTBOX_SF_AUTOSCROLLBAR_V LISTBOX_CF_AUTOSCROLLBAR_V +#define LISTBOX_SF_MULTISEL LISTBOX_CF_MULTISEL +#define LISTBOX_SF_WRAP LISTBOX_CF_WRAP + +/************************************************************ +* +* Fixed scroll mode flags +*/ +#define LISTBOX_FM_OFF 0 // Turn fixed mode off +#define LISTBOX_FM_ON 1 // Turn fixed mode on +#define LISTBOX_FM_CENTER 2 // Set fixed mode to center + +/********************************************************************* +* +* Create functions +* +********************************************************************** +*/ + +LISTBOX_Handle LISTBOX_Create (const GUI_ConstString * ppText, int x0, int y0, int xSize, int ySize, int Flags); +LISTBOX_Handle LISTBOX_CreateAsChild (const GUI_ConstString * ppText, WM_HWIN hWinParent, int x0, int y0, int xSize, int ySize, int Flags); +LISTBOX_Handle LISTBOX_CreateEx (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int WinFlags, int ExFlags, int Id, const GUI_ConstString * ppText); +LISTBOX_Handle LISTBOX_CreateUser (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int WinFlags, int ExFlags, int Id, const GUI_ConstString * ppText, int NumExtraBytes); +LISTBOX_Handle LISTBOX_CreateIndirect(const GUI_WIDGET_CREATE_INFO * pCreateInfo, WM_HWIN hWinParent, int x0, int y0, WM_CALLBACK * cb); + +/********************************************************************* +* +* The callback ... +* +* Do not call it directly ! It is only to be used from within an +* overwritten callback. +*/ +void LISTBOX_Callback(WM_MESSAGE * pMsg); + +/********************************************************************* +* +* Member functions +* +********************************************************************** +*/ + +int LISTBOX_AddKey (LISTBOX_Handle hObj, int Key); +void LISTBOX_AddString (LISTBOX_Handle hObj, const char * s); +void LISTBOX_AddStringH (LISTBOX_Handle hObj, WM_HMEM hString); /* Not to be documented!!! */ +void LISTBOX_DecSel (LISTBOX_Handle hObj); +void LISTBOX_DeleteItem (LISTBOX_Handle hObj, unsigned int Index); +void LISTBOX_EnableFixedScrollMode(LISTBOX_Handle hObj, unsigned int OnOff, U8 FixedPos); +void LISTBOX_EnableWrapMode (LISTBOX_Handle hObj, int OnOff); +unsigned LISTBOX_GetItemSpacing (LISTBOX_Handle hObj); +unsigned LISTBOX_GetNumItems (LISTBOX_Handle hObj); +int LISTBOX_GetSel (LISTBOX_Handle hObj); +const GUI_FONT * LISTBOX_GetFont (LISTBOX_Handle hObj); +int LISTBOX_GetItemDisabled (LISTBOX_Handle hObj, unsigned Index); +int LISTBOX_GetItemSel (LISTBOX_Handle hObj, unsigned Index); +void LISTBOX_GetItemText (LISTBOX_Handle hObj, unsigned Index, char * pBuffer, int MaxSize); +int LISTBOX_GetMulti (LISTBOX_Handle hObj); +WM_HWIN LISTBOX_GetOwner (LISTBOX_Handle hObj); +int LISTBOX_GetScrollStepH (LISTBOX_Handle hObj); +int LISTBOX_GetTextAlign (LISTBOX_Handle hObj); +int LISTBOX_GetUserData (LISTBOX_Handle hObj, void * pDest, int NumBytes); +void LISTBOX_IncSel (LISTBOX_Handle hObj); +void LISTBOX_InsertString (LISTBOX_Handle hObj, const char * s, unsigned int Index); +void LISTBOX_InvalidateItem (LISTBOX_Handle hObj, int Index); +int LISTBOX_OwnerDraw (const WIDGET_ITEM_DRAW_INFO * pDrawItemInfo); +void LISTBOX_SetAutoScrollH (LISTBOX_Handle hObj, int OnOff); +void LISTBOX_SetAutoScrollV (LISTBOX_Handle hObj, int OnOff); +void LISTBOX_SetBkColor (LISTBOX_Handle hObj, unsigned int Index, GUI_COLOR color); +void LISTBOX_SetFont (LISTBOX_Handle hObj, const GUI_FONT * pFont); +void LISTBOX_SetItemDisabled (LISTBOX_Handle hObj, unsigned Index, int OnOff); +void LISTBOX_SetItemSel (LISTBOX_Handle hObj, unsigned Index, int OnOff); +void LISTBOX_SetItemSpacing (LISTBOX_Handle hObj, unsigned Value); +void LISTBOX_SetMulti (LISTBOX_Handle hObj, int Mode); +void LISTBOX_SetOwner (LISTBOX_Handle hObj, WM_HWIN hOwner); +void LISTBOX_SetOwnerDraw (LISTBOX_Handle hObj, WIDGET_DRAW_ITEM_FUNC * pfDrawItem); +void LISTBOX_SetScrollStepH (LISTBOX_Handle hObj, int Value); +void LISTBOX_SetSel (LISTBOX_Handle hObj, int Sel); +void LISTBOX_SetScrollbarColor(LISTBOX_Handle hObj, unsigned Index, GUI_COLOR Color); +void LISTBOX_SetScrollbarWidth(LISTBOX_Handle hObj, unsigned Width); +void LISTBOX_SetString (LISTBOX_Handle hObj, const char * s, unsigned int Index); +void LISTBOX_SetText (LISTBOX_Handle hObj, const GUI_ConstString * ppText); +void LISTBOX_SetTextAlign (LISTBOX_Handle hObj, int Align); +GUI_COLOR LISTBOX_SetTextColor (LISTBOX_Handle hObj, unsigned int Index, GUI_COLOR Color); +int LISTBOX_SetUserData (LISTBOX_Handle hObj, const void * pSrc, int NumBytes); +int LISTBOX_UpdateScrollers (LISTBOX_Handle hObj); + +/********************************************************************* +* +* Managing default values +* +********************************************************************** +*/ + +const GUI_FONT * LISTBOX_GetDefaultFont(void); +int LISTBOX_GetDefaultScrollStepH (void); +GUI_COLOR LISTBOX_GetDefaultBkColor (unsigned Index); +int LISTBOX_GetDefaultTextAlign (void); +GUI_COLOR LISTBOX_GetDefaultTextColor (unsigned Index); +int LISTBOX_GetDefaultScrollMode (void); +void LISTBOX_SetDefaultFont (const GUI_FONT * pFont); +void LISTBOX_SetDefaultScrollStepH (int Value); +void LISTBOX_SetDefaultBkColor (unsigned Index, GUI_COLOR Color); +void LISTBOX_SetDefaultTextAlign (int Align); +void LISTBOX_SetDefaultTextColor (unsigned Index, GUI_COLOR Color); +void LISTBOX_SetDefaultScrollMode (U8 ScrollMode); + +/********************************************************************* +* +* Compatibility to older versions +* +********************************************************************** +*/ + +#define LISTBOX_SetBackColor(hObj, Index, Color) LISTBOX_SetBkColor(hObj, Index, Color) +#define LISTBOX_DeleteString LISTBOX_DeleteItem + +#if defined(__cplusplus) + } +#endif + +#endif // GUI_WINSUPPORT +#endif // LISTBOX_H + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/LISTBOX_Private.h b/example/GUI/STemWin/inc/LISTBOX_Private.h new file mode 100755 index 0000000000..ce565fe7f2 --- /dev/null +++ b/example/GUI/STemWin/inc/LISTBOX_Private.h @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : LISTBOX_Private.h +Purpose : Private LISTBOX include +--------------------END-OF-HEADER------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef LISTBOX_PRIVATE_H +#define LISTBOX_PRIVATE_H + +#include "LISTBOX.h" +#include "WM.h" +#include "GUI_ARRAY.h" +#include "WIDGET.h" + +#if GUI_WINSUPPORT + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ +#define LISTBOX_ITEM_SELECTED (1 << 0) +#define LISTBOX_ITEM_DISABLED (1 << 1) + +/********************************************************************* +* +* Object definition +* +********************************************************************** +*/ + +typedef struct { + U16 xSize, ySize; + I32 ItemPosY; + U8 Status; + char acText[1]; +} LISTBOX_ITEM; + +typedef struct { + const GUI_FONT * pFont; + U16 ScrollStepH; + GUI_COLOR aBackColor[4]; + GUI_COLOR aTextColor[4]; + GUI_COLOR aScrollbarColor[3]; + I16 Align; + U8 FixedScrollMode; +} LISTBOX_PROPS; + +typedef struct { + WIDGET Widget; + GUI_ARRAY ItemArray; + WIDGET_DRAW_ITEM_FUNC* pfDrawItem; + WM_SCROLL_STATE ScrollStateV; + WM_SCROLL_STATE ScrollStateH; + LISTBOX_PROPS Props; + WM_HWIN hOwner; + I16 Sel; /* current selection */ + U8 Flags; + U8 ScrollbarWidth; + U16 ItemSpacing; + U16 ContentSizeX; + U8 FixedScrollPos; +} LISTBOX_Obj; + +/********************************************************************* +* +* Macros for internal use +* +********************************************************************** +*/ +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL + #define LISTBOX_INIT_ID(p) p->Widget.DebugId = LISTBOX_ID +#else + #define LISTBOX_INIT_ID(p) +#endif + +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL + LISTBOX_Obj * LISTBOX_LockH(LISTBOX_Handle h); + #define LISTBOX_LOCK_H(h) LISTBOX_LockH(h) +#else + #define LISTBOX_LOCK_H(h) (LISTBOX_Obj *)GUI_LOCK_H(h) +#endif + +/********************************************************************* +* +* Private (module internal) data +* +********************************************************************** +*/ + +extern LISTBOX_PROPS LISTBOX_DefaultProps; + +/********************************************************************* +* +* Private (module internal) functions +* +********************************************************************** +*/ +unsigned LISTBOX__GetNumItems (const LISTBOX_Obj * pObj); +const char * LISTBOX__GetpStringLocked (LISTBOX_Handle hObj, int Index, LISTBOX_ITEM ** ppItem); +void LISTBOX__InvalidateInsideArea (LISTBOX_Handle hObj); +void LISTBOX__InvalidateItem (LISTBOX_Handle hObj, int Sel); +void LISTBOX__InvalidateItemAndBelow(LISTBOX_Handle hObj, int Sel); +void LISTBOX__InvalidateItemSize (const LISTBOX_Obj * pObj, unsigned Index); +void LISTBOX__SetScrollbarColor (LISTBOX_Handle hObj, const LISTBOX_Obj * pObj); +void LISTBOX__SetScrollbarWidth (LISTBOX_Handle hObj, const LISTBOX_Obj * pObj); +void LISTBOX__AddSize (LISTBOX_Obj * pObj, int Index); + +#endif /* GUI_WINSUPPORT */ + +#else /* Avoid problems with empty object modules */ + void LISTBOX_C(void) {} +#endif + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/LISTVIEW.h b/example/GUI/STemWin/inc/LISTVIEW.h new file mode 100755 index 0000000000..e6a6b0485e --- /dev/null +++ b/example/GUI/STemWin/inc/LISTVIEW.h @@ -0,0 +1,215 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : LISTVIEW.h +Purpose : LISTVIEW include +--------------------END-OF-HEADER------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef LISTVIEW_H +#define LISTVIEW_H + +#include "WM.h" +#include "DIALOG_Intern.h" // Req. for Create indirect data structure +#include "ICONVIEW.h" +#include "HEADER.h" + +#if GUI_WINSUPPORT + +#if defined(__cplusplus) + extern "C" { /* Make sure we have C-declarations in C++ programs */ +#endif + +/********************************************************************* +* +* Defines +*/ +#define LISTVIEW_ALL_ITEMS -1 + +/********************************************************************* +* +* Color indices +*/ +#define LISTVIEW_CI_UNSEL 0 +#define LISTVIEW_CI_SEL 1 +#define LISTVIEW_CI_SELFOCUS 2 +#define LISTVIEW_CI_DISABLED 3 + +/************************************************************ +* +* Create / Status flags +*/ +#define LISTVIEW_CF_AUTOSCROLLBAR_H (1 << 0) +#define LISTVIEW_CF_AUTOSCROLLBAR_V (1 << 1) +#define LISTVIEW_CF_CELL_SELECT (1 << 2) // Create Flag used to enable cell selection +#define LISTVIEW_SF_AUTOSCROLLBAR_H LISTVIEW_CF_AUTOSCROLLBAR_H +#define LISTVIEW_SF_AUTOSCROLLBAR_V LISTVIEW_CF_AUTOSCROLLBAR_V + +/********************************************************************* +* +* Public Types +* +********************************************************************** +*/ +typedef WM_HMEM LISTVIEW_Handle; + +/********************************************************************* +* +* Create functions +* +********************************************************************** +*/ +LISTVIEW_Handle LISTVIEW_Create (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int Id, int Flags, int SpecialFlags); +LISTVIEW_Handle LISTVIEW_CreateEx (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int WinFlags, int ExFlags, int Id); +LISTVIEW_Handle LISTVIEW_CreateUser (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int WinFlags, int ExFlags, int Id, int NumExtraBytes); +LISTVIEW_Handle LISTVIEW_CreateAttached(WM_HWIN hParent, int Id, int SpecialFlags); +LISTVIEW_Handle LISTVIEW_CreateIndirect(const GUI_WIDGET_CREATE_INFO * pCreateInfo, WM_HWIN hWinParent, int x0, int y0, WM_CALLBACK * cb); + +/********************************************************************* +* +* The callback ... +* +* Do not call it directly ! It is only to be used from within an +* overwritten callback. +*/ +void LISTVIEW_Callback(WM_MESSAGE * pMsg); + +/********************************************************************* +* +* Member functions +* +********************************************************************** +*/ +int LISTVIEW_AddColumn (LISTVIEW_Handle hObj, int Width, const char * s, int Align); +int LISTVIEW_AddRow (LISTVIEW_Handle hObj, const GUI_ConstString * ppText); +int LISTVIEW_CompareText (const void * p0, const void * p1); +int LISTVIEW_CompareDec (const void * p0, const void * p1); +void LISTVIEW_DecSel (LISTVIEW_Handle hObj); +void LISTVIEW_DeleteAllRows (LISTVIEW_Handle hObj); +void LISTVIEW_DeleteColumn (LISTVIEW_Handle hObj, unsigned Index); +void LISTVIEW_DeleteRow (LISTVIEW_Handle hObj, unsigned Index); +void LISTVIEW_DeleteRowSorted (LISTVIEW_Handle hObj, int Row); +void LISTVIEW_DisableRow (LISTVIEW_Handle hObj, unsigned Row); +void LISTVIEW_DisableSort (LISTVIEW_Handle hObj); +void LISTVIEW_EnableCellSelect (LISTVIEW_Handle hObj, unsigned OnOff); // Enables/disables cell selection +void LISTVIEW_EnableRow (LISTVIEW_Handle hObj, unsigned Row); +void LISTVIEW_EnableSort (LISTVIEW_Handle hObj); +GUI_COLOR LISTVIEW_GetBkColor (LISTVIEW_Handle hObj, unsigned Index); +const GUI_FONT * LISTVIEW_GetFont (LISTVIEW_Handle hObj); +HEADER_Handle LISTVIEW_GetHeader (LISTVIEW_Handle hObj); +void LISTVIEW_GetItemRect (LISTVIEW_Handle hObj, U32 Col, U32 Row, GUI_RECT * pRect); +void LISTVIEW_GetItemText (LISTVIEW_Handle hObj, unsigned Column, unsigned Row, char * pBuffer, unsigned MaxSize); +unsigned LISTVIEW_GetItemTextLen (LISTVIEW_Handle hObj, unsigned Column, unsigned Row); +void LISTVIEW_GetItemTextSorted (LISTVIEW_Handle hObj, unsigned Column, unsigned Row, char * pBuffer, unsigned MaxSize); +unsigned LISTVIEW_GetLBorder (LISTVIEW_Handle hObj); +unsigned LISTVIEW_GetNumColumns (LISTVIEW_Handle hObj); +unsigned LISTVIEW_GetNumRows (LISTVIEW_Handle hObj); +unsigned LISTVIEW_GetRBorder (LISTVIEW_Handle hObj); +int LISTVIEW_GetSel (LISTVIEW_Handle hObj); +int LISTVIEW_GetSelCol (LISTVIEW_Handle hObj); +int LISTVIEW_GetSelUnsorted (LISTVIEW_Handle hObj); +int LISTVIEW_GetTextAlign (LISTVIEW_Handle hObj, unsigned ColIndex); +GUI_COLOR LISTVIEW_GetTextColor (LISTVIEW_Handle hObj, unsigned Index); +int LISTVIEW_GetUserData (LISTVIEW_Handle hObj, void * pDest, int NumBytes); +U32 LISTVIEW_GetUserDataRow (LISTVIEW_Handle hObj, unsigned Row); +GUI_WRAPMODE LISTVIEW_GetWrapMode (LISTVIEW_Handle hObj); +void LISTVIEW_IncSel (LISTVIEW_Handle hObj); +int LISTVIEW_InsertRow (LISTVIEW_Handle hObj, unsigned Index, const GUI_ConstString * ppText); +int LISTVIEW_OwnerDraw (const WIDGET_ITEM_DRAW_INFO * pDrawItemInfo); +unsigned LISTVIEW_RowIsDisabled (LISTVIEW_Handle hObj, unsigned Row); +void LISTVIEW_SetAutoScrollH (LISTVIEW_Handle hObj, int OnOff); +void LISTVIEW_SetAutoScrollV (LISTVIEW_Handle hObj, int OnOff); +void LISTVIEW_SetItemBitmap (LISTVIEW_Handle hObj, unsigned Column, unsigned Row, int xOff, int yOff, const GUI_BITMAP * pBitmap); +void LISTVIEW_SetBkColor (LISTVIEW_Handle hObj, unsigned int Index, GUI_COLOR Color); +void LISTVIEW_SetColumnWidth (LISTVIEW_Handle hObj, unsigned int Index, int Width); +void LISTVIEW_SetCompareFunc (LISTVIEW_Handle hObj, unsigned Column, int (* fpCompare)(const void * p0, const void * p1)); +unsigned LISTVIEW_SetFixed (LISTVIEW_Handle hObj, unsigned Fixed); +void LISTVIEW_SetFont (LISTVIEW_Handle hObj, const GUI_FONT * pFont); +int LISTVIEW_SetGridVis (LISTVIEW_Handle hObj, int Show); +void LISTVIEW_SetHeaderHeight (LISTVIEW_Handle hObj, unsigned HeaderHeight); +void LISTVIEW_SetItemBkColor (LISTVIEW_Handle hObj, unsigned Column, unsigned Row, unsigned int Index, GUI_COLOR Color); +void LISTVIEW_SetItemText (LISTVIEW_Handle hObj, unsigned Column, unsigned Row, const char * s); +void LISTVIEW_SetItemTextColor (LISTVIEW_Handle hObj, unsigned Column, unsigned Row, unsigned int Index, GUI_COLOR Color); +void LISTVIEW_SetItemTextSorted (LISTVIEW_Handle hObj, unsigned Column, unsigned Row, const char * pText); +void LISTVIEW_SetLBorder (LISTVIEW_Handle hObj, unsigned BorderSize); +void LISTVIEW_SetOwnerDraw (LISTVIEW_Handle hObj, WIDGET_DRAW_ITEM_FUNC * pfDrawItem); +void LISTVIEW_SetRBorder (LISTVIEW_Handle hObj, unsigned BorderSize); +unsigned LISTVIEW_SetRowHeight (LISTVIEW_Handle hObj, unsigned RowHeight); +void LISTVIEW_SetSel (LISTVIEW_Handle hObj, int Sel); +void LISTVIEW_SetSelCol (LISTVIEW_Handle hObj, int NewCol); +void LISTVIEW_SetSelUnsorted (LISTVIEW_Handle hObj, int Sel); +unsigned LISTVIEW_SetSort (LISTVIEW_Handle hObj, unsigned Column, unsigned Reverse); +void LISTVIEW_SetTextAlign (LISTVIEW_Handle hObj, unsigned int Index, int Align); +void LISTVIEW_SetTextColor (LISTVIEW_Handle hObj, unsigned int Index, GUI_COLOR Color); +int LISTVIEW_SetUserData (LISTVIEW_Handle hObj, const void * pSrc, int NumBytes); +void LISTVIEW_SetUserDataRow (LISTVIEW_Handle hObj, unsigned Row, U32 UserData); +void LISTVIEW_SetWrapMode (LISTVIEW_Handle hObj, GUI_WRAPMODE WrapMode); + +/********************************************************************* +* +* Managing default values +* +********************************************************************** +*/ + +GUI_COLOR LISTVIEW_SetDefaultBkColor (unsigned Index, GUI_COLOR Color); +const GUI_FONT * LISTVIEW_SetDefaultFont (const GUI_FONT * pFont); +GUI_COLOR LISTVIEW_SetDefaultGridColor(GUI_COLOR Color); +GUI_COLOR LISTVIEW_SetDefaultTextColor(unsigned Index, GUI_COLOR Color); + +#if defined(__cplusplus) + } +#endif + +#endif // GUI_WINSUPPORT +#endif // LISTVIEW_H + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/LISTVIEW_Private.h b/example/GUI/STemWin/inc/LISTVIEW_Private.h new file mode 100755 index 0000000000..d1d550d99b --- /dev/null +++ b/example/GUI/STemWin/inc/LISTVIEW_Private.h @@ -0,0 +1,206 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : LISTVIEW_Private.h +Purpose : Private LISTVIEW include +--------------------END-OF-HEADER------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef LISTVIEW_PRIVATE_H +#define LISTVIEW_PRIVATE_H + +#include "WM.h" + +#if GUI_WINSUPPORT + +#include + +#include "LISTVIEW.h" +#include "GUI_ARRAY.h" + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ +#define SORT_TYPE U16 + +#define LISTVIEW_CELL_INFO_COLORS (1 << 0) +#define LISTVIEW_CELL_INFO_BITMAP (1 << 1) + +/********************************************************************* +* +* Object definition +* +********************************************************************** +*/ + +typedef struct { + GUI_COLOR aBkColor[4]; + GUI_COLOR aTextColor[4]; + GUI_COLOR GridColor; + const GUI_FONT * pFont; + U16 ScrollStepH; + GUI_WRAPMODE WrapMode; + int DefaultAlign; +} LISTVIEW_PROPS; + +typedef struct { + void (* pfDraw)(LISTVIEW_Handle hObj, unsigned Column, unsigned Row, GUI_RECT * pRect); + void * pData; + GUI_COLOR aBkColor[4]; + GUI_COLOR aTextColor[4]; + I16 xOff, yOff; + U8 Flags; +} LISTVIEW_CELL_INFO; + +typedef struct { + WM_HMEM hCellInfo; // Optional cell info. If 0, there is no cell info. (Defaults used) + char acText[1]; +} LISTVIEW_CELL; + +typedef struct { + GUI_ARRAY hCellArray; + char Disabled; + U32 UserData; +} LISTVIEW_ROW; + +typedef struct { + U8 Align; + int (* fpCompare) (const void * p0, const void * p1); // User function to be called to compare the contents of 2 cells +} LISTVIEW_COLUMN; + +typedef struct LISTVIEW_Obj LISTVIEW_Obj; + +typedef struct { + WM_HMEM hSortArray; + SORT_TYPE SortArrayNumItems; + int (* fpSort)(LISTVIEW_Handle hObj); // Function to be called to get a sorted array + void (* fpFree)(WM_HMEM hObj); // Function to be called to free the sort object + U8 Reverse; +} LISTVIEW_SORT; + +struct LISTVIEW_Obj { + WIDGET Widget; + HEADER_Handle hHeader; + WIDGET_DRAW_ITEM_FUNC * pfDrawItem; + GUI_ARRAY hRowArray; // Each entry is a handle of LISTVIEW_ROW structure. + GUI_ARRAY hColumnArray; // Each entry is a handle of LISTVIEW_COLUMN structure. + LISTVIEW_PROPS Props; + int Sel; + int SelCol; + int ShowGrid; + int SortIndex; // Column for sorting + unsigned RowDistY; + unsigned LBorder; + unsigned RBorder; + unsigned Fixed; + WM_SCROLL_STATE ScrollStateV; + WM_SCROLL_STATE ScrollStateH; + WM_HMEM hSort; + U8 IsSorted; + U8 IsPresorted; + U8 ReverseSort; // Set to 1 if reverse sorting is required + U8 Flags; +}; + +/********************************************************************* +* +* Macros for internal use +* +********************************************************************** +*/ +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL + #define LISTVIEW_INIT_ID(p) (p->Widget.DebugId = LISTVIEW_ID) +#else + #define LISTVIEW_INIT_ID(p) +#endif + +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL + LISTVIEW_Obj * LISTVIEW_LockH(LISTVIEW_Handle h); + #define LISTVIEW_LOCK_H(h) LISTVIEW_LockH(h) +#else + #define LISTVIEW_LOCK_H(h) (LISTVIEW_Obj *)GUI_LOCK_H(h) +#endif + +/********************************************************************* +* +* Private (module internal) data +* +********************************************************************** +*/ +extern LISTVIEW_PROPS LISTVIEW_DefaultProps; + +/********************************************************************* +* +* Private (module internal) functions +* +********************************************************************** +*/ +LISTVIEW_CELL_INFO * LISTVIEW__CreateCellInfoLocked (LISTVIEW_Handle hObj, unsigned Column, unsigned Row); +unsigned LISTVIEW__GetNumColumns (LISTVIEW_Obj * pObj); +unsigned LISTVIEW__GetNumRows (LISTVIEW_Obj * pObj); +LISTVIEW_CELL_INFO * LISTVIEW__GetpCellInfo (LISTVIEW_Handle hObj, unsigned Column, unsigned Row); +LISTVIEW_ROW * LISTVIEW__GetpRow (LISTVIEW_Handle hObj, int Row); +unsigned LISTVIEW__GetRowDistY (LISTVIEW_Obj * pObj); +unsigned LISTVIEW__GetRowSorted (LISTVIEW_Handle hObj, int Row); +void LISTVIEW__InvalidateInsideArea (LISTVIEW_Handle hObj); +void LISTVIEW__InvalidateRow (LISTVIEW_Handle hObj, int Sel); +void LISTVIEW__InvalidateRowAndBelow(LISTVIEW_Handle hObj, int Sel); +void LISTVIEW__SetSel (LISTVIEW_Handle hObj, int NewSel); +void LISTVIEW__SetSelCol (LISTVIEW_Handle hObj, int NewSelCol); +int LISTVIEW__UpdateScrollParas (LISTVIEW_Handle hObj); + +#endif // GUI_WINSUPPORT +#endif // LISTVIEW_PRIVATE_H + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/LISTWHEEL.h b/example/GUI/STemWin/inc/LISTWHEEL.h new file mode 100755 index 0000000000..9253729752 --- /dev/null +++ b/example/GUI/STemWin/inc/LISTWHEEL.h @@ -0,0 +1,165 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : LISTWHEEL.h +Purpose : LISTWHEEL widget include +--------------------END-OF-HEADER------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef LISTWHEEL_H +#define LISTWHEEL_H + +#include "WM.h" +#include "DIALOG_Intern.h" +#include "WIDGET.h" + +#if GUI_WINSUPPORT + +#if defined(__cplusplus) + extern "C" { // Make sure we have C-declarations in C++ programs +#endif + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ +#define LISTWHEEL_CI_UNSEL 0 +#define LISTWHEEL_CI_SEL 1 + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ +typedef WM_HMEM LISTWHEEL_Handle; + +/********************************************************************* +* +* Standard member functions +* +********************************************************************** +*/ +/********************************************************************* +* +* Create functions +* +********************************************************************** +*/ +LISTWHEEL_Handle LISTWHEEL_Create (const GUI_ConstString * ppText, int x0, int y0, int xSize, int ySize, int Flags); +LISTWHEEL_Handle LISTWHEEL_CreateAsChild (const GUI_ConstString * ppText, WM_HWIN hWinParent, int x0, int y0, int xSize, int ySize, int Flags); +LISTWHEEL_Handle LISTWHEEL_CreateIndirect(const GUI_WIDGET_CREATE_INFO * pCreateInfo, WM_HWIN hWinParent, int x0, int y0, WM_CALLBACK * cb); +LISTWHEEL_Handle LISTWHEEL_CreateEx (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, + int WinFlags, int ExFlags, int Id, const GUI_ConstString * ppText); +LISTWHEEL_Handle LISTWHEEL_CreateUser (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, + int WinFlags, int ExFlags, int Id, const GUI_ConstString * ppText, int NumExtraBytes); + +/********************************************************************* +* +* The callback ... +* +* Do not call it directly ! It is only to be used from within an +* overwritten callback. +*/ +void LISTWHEEL_Callback(WM_MESSAGE * pMsg); + +/********************************************************************* +* +* Member functions +* +********************************************************************** +*/ +void LISTWHEEL_AddString (LISTWHEEL_Handle hObj, const char * s); +void * LISTWHEEL_GetItemData (LISTWHEEL_Handle hObj, unsigned Index); /* not to be documented */ +void LISTWHEEL_GetItemText (LISTWHEEL_Handle hObj, unsigned Index, char * pBuffer, int MaxSize); +int LISTWHEEL_GetItemFromPos (LISTWHEEL_Handle hObj, int yPos); +int LISTWHEEL_GetLBorder (LISTWHEEL_Handle hObj); +unsigned LISTWHEEL_GetLineHeight (LISTWHEEL_Handle hObj); +int LISTWHEEL_GetNumItems (LISTWHEEL_Handle hObj); +int LISTWHEEL_GetPos (LISTWHEEL_Handle hObj); +int LISTWHEEL_GetRBorder (LISTWHEEL_Handle hObj); +int LISTWHEEL_GetSel (LISTWHEEL_Handle hObj); +int LISTWHEEL_GetSnapPosition(LISTWHEEL_Handle hObj); +int LISTWHEEL_GetTextAlign (LISTWHEEL_Handle hObj); +int LISTWHEEL_GetUserData (LISTWHEEL_Handle hObj, void * pDest, int NumBytes); +int LISTWHEEL_IsMoving (LISTWHEEL_Handle hObj); +void LISTWHEEL_MoveToPos (LISTWHEEL_Handle hObj, unsigned int Index); +int LISTWHEEL_OwnerDraw (const WIDGET_ITEM_DRAW_INFO * pDrawItemInfo); +void LISTWHEEL_SetBkColor (LISTWHEEL_Handle hObj, unsigned int Index, GUI_COLOR Color); +void LISTWHEEL_SetDeceleration(LISTWHEEL_Handle hObj, unsigned Deceleration); +void LISTWHEEL_SetFont (LISTWHEEL_Handle hObj, const GUI_FONT * pFont); +void LISTWHEEL_SetItemData (LISTWHEEL_Handle hObj, unsigned Index, void * pData); /* not to be documented */ +void LISTWHEEL_SetLBorder (LISTWHEEL_Handle hObj, unsigned BorderSize); +void LISTWHEEL_SetLineHeight (LISTWHEEL_Handle hObj, unsigned LineHeight); +void LISTWHEEL_SetOwnerDraw (LISTWHEEL_Handle hObj, WIDGET_DRAW_ITEM_FUNC * pfOwnerDraw); +void LISTWHEEL_SetPos (LISTWHEEL_Handle hObj, unsigned int Index); +void LISTWHEEL_SetRBorder (LISTWHEEL_Handle hObj, unsigned BorderSize); +void LISTWHEEL_SetSel (LISTWHEEL_Handle hObj, int Sel); +void LISTWHEEL_SetSnapPosition(LISTWHEEL_Handle hObj, int SnapPosition); +void LISTWHEEL_SetText (LISTWHEEL_Handle hObj, const GUI_ConstString * ppText); +void LISTWHEEL_SetTextAlign (LISTWHEEL_Handle hObj, int Align); +void LISTWHEEL_SetTextColor (LISTWHEEL_Handle hObj, unsigned int Index, GUI_COLOR Color); +void LISTWHEEL_SetTimerPeriod (LISTWHEEL_Handle hObj, GUI_TIMER_TIME TimerPeriod); +int LISTWHEEL_SetUserData (LISTWHEEL_Handle hObj, const void * pSrc, int NumBytes); +void LISTWHEEL_SetVelocity (LISTWHEEL_Handle hObj, int Velocity); + +const GUI_FONT * LISTWHEEL_GetFont(LISTWHEEL_Handle hObj); + +#if defined(__cplusplus) + } +#endif + +#endif // GUI_WINSUPPORT +#endif // LISTWHEEL_H + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/LISTWHEEL_Private.h b/example/GUI/STemWin/inc/LISTWHEEL_Private.h new file mode 100755 index 0000000000..8620b2d54f --- /dev/null +++ b/example/GUI/STemWin/inc/LISTWHEEL_Private.h @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : LISTWHEEL_Private.h +Purpose : Private LISTWHEEL include +--------------------END-OF-HEADER------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef LISTWHEEL_PRIVATE_H +#define LISTWHEEL_PRIVATE_H + +#include "LISTWHEEL.h" +#include "WM.h" +#include "GUI_ARRAY.h" +#include "WIDGET.h" + +#if GUI_WINSUPPORT + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ +#define LISTWHEEL_STATE_PRESSED WIDGET_STATE_USER0 + +/********************************************************************* +* +* Object definition +* +********************************************************************** +*/ + +typedef struct { + void * pData; + char acText[1]; +} LISTWHEEL_ITEM; + +typedef struct { + const GUI_FONT * pFont; + GUI_COLOR aBackColor[2]; + GUI_COLOR aTextColor[2]; + I16 Align; + unsigned Deceleration; +} LISTWHEEL_PROPS; + +typedef struct { + WIDGET Widget; + GUI_ARRAY ItemArray; + WIDGET_DRAW_ITEM_FUNC * pfOwnerDraw; + LISTWHEEL_PROPS Props; + WM_HMEM hTimer; + unsigned LBorder; + unsigned RBorder; + unsigned LineHeight; + int Sel; + GUI_TIMER_TIME TimeTouched; // Time stamp of last touch event + GUI_TIMER_TIME TimeTouchedLast; // Time of the last touch + int PosTouchedLast; // Last touched position in pixels + int Pos; // Current position in pixels + int Velocity; // Motion in pixels + int SnapPosition; // Snap position in pixels + int TouchPos; // Y-position of last touch event + int ySizeData; // Data size in pixels + int Destination; // Destination position in pixels + GUI_TIMER_TIME TimerPeriod; // Period of timer events +} LISTWHEEL_OBJ; + +/********************************************************************* +* +* Macros for internal use +* +********************************************************************** +*/ +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL + #define LISTWHEEL_INIT_ID(p) (p->Widget.DebugId = LISTWHEEL_ID) +#else + #define LISTWHEEL_INIT_ID(p) +#endif + +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL + LISTWHEEL_OBJ * LISTWHEEL_LockH(LISTWHEEL_Handle h); + #define LISTWHEEL_LOCK_H(h) LISTWHEEL_LockH(h) +#else + #define LISTWHEEL_LOCK_H(h) (LISTWHEEL_OBJ *)GUI_LOCK_H(h) +#endif + +/********************************************************************* +* +* Private (module internal) data +* +********************************************************************** +*/ +extern LISTWHEEL_PROPS LISTWHEEL_DefaultProps; + +/********************************************************************* +* +* Private (module internal) functions +* +********************************************************************** +*/ +const char * LISTWHEEL__GetpStringLocked(LISTWHEEL_Handle hObj, int Index, LISTWHEEL_ITEM ** ppItem); + +#endif // GUI_WINSUPPORT +#endif // LISTWHEEL_PRIVATE_H + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/MENU.h b/example/GUI/STemWin/inc/MENU.h new file mode 100755 index 0000000000..3cccce0905 --- /dev/null +++ b/example/GUI/STemWin/inc/MENU.h @@ -0,0 +1,282 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : MENU.h +Purpose : MENU include +--------------------END-OF-HEADER------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef MENU_H +#define MENU_H + +#include "WM.h" +#include "WIDGET.h" +#include "DIALOG_Intern.h" // Required for Create indirect data structure + +#if GUI_WINSUPPORT + +#if defined(__cplusplus) + extern "C" { // Make sure we have C-declarations in C++ programs +#endif + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ +#define MENU_SKIN_FLEX MENU_DrawSkinFlex + +/********************************************************************* +* +* Create flags +*/ +#define MENU_CF_HORIZONTAL (0<<0) +#define MENU_CF_VERTICAL (1<<0) +#define MENU_CF_OPEN_ON_POINTEROVER (1<<1) // Normally a menu opens first when clicked on it +#define MENU_CF_CLOSE_ON_SECOND_CLICK (1<<2) // Normally a menu closes only when clicked outside it +#define MENU_CF_HIDE_DISABLED_SEL (1<<3) // Hides the selection when a disabled item is selected + +/********************************************************************* +* +* Menu item flags +*/ +#define MENU_IF_DISABLED (1<<0) // Indicates that item is disabled +#define MENU_IF_SEPARATOR (1<<1) // Indicates that item is a separator + +/********************************************************************* +* +* Color indices +*/ +#define MENU_CI_ENABLED 0 +#define MENU_CI_SELECTED 1 +#define MENU_CI_DISABLED 2 +#define MENU_CI_DISABLED_SEL 3 +#define MENU_CI_ACTIVE_SUBMENU 4 + +/********************************************************************* +* +* Border indices +*/ +#define MENU_BI_LEFT 0 +#define MENU_BI_RIGHT 1 +#define MENU_BI_TOP 2 +#define MENU_BI_BOTTOM 3 + +/********************************************************************* +* +* Message types +*/ +#define MENU_ON_ITEMSELECT 0 // Send to owner when selecting a menu item +#define MENU_ON_INITMENU 1 // Send to owner when for the first time selecting a submenu +#define MENU_ON_INITSUBMENU 2 // Send to owner when selecting a submenu +#define MENU_ON_OPEN 3 // Internal message of menu widget (only send to submenus) +#define MENU_ON_CLOSE 4 // Internal message of menu widget (only send to submenus) +#define MENU_IS_MENU 5 // Internal message of menu widget. Owner must call + // WM_DefaultProc() when not handle the message +#define MENU_ON_ITEMACTIVATE 6 // Send to owner when highlighting a menu item +#define MENU_ON_ITEMPRESSED 7 // Send to owner when a menu item has been pressed + +/********************************************************************* +* +* Skinning property indices +*/ +#define MENU_SKINFLEX_PI_ENABLED 0 +#define MENU_SKINFLEX_PI_SELECTED 1 +#define MENU_SKINFLEX_PI_DISABLED 2 +#define MENU_SKINFLEX_PI_DISABLED_SEL 3 +#define MENU_SKINFLEX_PI_ACTIVE_SUBMENU 4 + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ + +typedef WM_HMEM MENU_Handle; + +typedef struct { + // + // Background + // + GUI_COLOR aBkColorH[2]; + GUI_COLOR BkColorV; + GUI_COLOR FrameColorH; + GUI_COLOR FrameColorV; + // + // Selection + // + GUI_COLOR aSelColorH[2]; + GUI_COLOR aSelColorV[2]; + GUI_COLOR FrameColorSelH; + GUI_COLOR FrameColorSelV; + // + // Separator + // + GUI_COLOR aSepColorH[2]; + GUI_COLOR aSepColorV[2]; + // + // Arrow + // + GUI_COLOR ArrowColor; + // + // Text + // + GUI_COLOR TextColor; +} MENU_SKINFLEX_PROPS; + +/********************************************************************* +* +* Menu message data +*/ +typedef struct { + U16 MsgType; + U16 ItemId; +} MENU_MSG_DATA; + +/********************************************************************* +* +* Menu item data +*/ +typedef struct { + const char * pText; + U16 Id; + U16 Flags; + MENU_Handle hSubmenu; +} MENU_ITEM_DATA; + +/********************************************************************* +* +* Create functions +* +********************************************************************** +*/ +MENU_Handle MENU_CreateIndirect(const GUI_WIDGET_CREATE_INFO * pCreateInfo, WM_HWIN hWinParent, int x0, int y0, WM_CALLBACK * cb); +MENU_Handle MENU_CreateEx (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int WinFlags, int ExFlags, int Id); +MENU_Handle MENU_CreateUser (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int WinFlags, int ExFlags, int Id, int NumExtraBytes); + +/********************************************************************* +* +* The callback ... +* +* Do not call it directly ! It is only to be used from within an +* overwritten callback. +*/ +void MENU_Callback(WM_MESSAGE * pMsg); + +/********************************************************************* +* +* Individual member functions +* +********************************************************************** +*/ +void MENU_AddItem (MENU_Handle hObj, const MENU_ITEM_DATA * pItemData); +void MENU_Attach (MENU_Handle hObj, WM_HWIN hDestWin, int x, int y, int xSize, int ySize, int Flags); +void MENU_DeleteItem (MENU_Handle hObj, U16 ItemId); +void MENU_DisableItem (MENU_Handle hObj, U16 ItemId); +void MENU_EnableItem (MENU_Handle hObj, U16 ItemId); +void MENU_GetItem (MENU_Handle hObj, U16 ItemId, MENU_ITEM_DATA * pItemData); +void MENU_GetItemText (MENU_Handle hObj, U16 ItemId, char * pBuffer, unsigned BufferSize); +unsigned MENU_GetNumItems (MENU_Handle hObj); +WM_HWIN MENU_GetOwner (MENU_Handle hObj); +int MENU_GetUserData (MENU_Handle hObj, void * pDest, int NumBytes); +void MENU_InsertItem (MENU_Handle hObj, U16 ItemId, const MENU_ITEM_DATA * pItemData); +void MENU_Popup (MENU_Handle hObj, WM_HWIN hDestWin, int x, int y, int xSize, int ySize, int Flags); +void MENU_SetBkColor (MENU_Handle hObj, unsigned ColorIndex, GUI_COLOR Color); +void MENU_SetBorderSize(MENU_Handle hObj, unsigned BorderIndex, U8 BorderSize); +void MENU_SetFont (MENU_Handle hObj, const GUI_FONT * pFont); +void MENU_SetItem (MENU_Handle hObj, U16 ItemId, const MENU_ITEM_DATA * pItemData); +void MENU_SetOwner (MENU_Handle hObj, WM_HWIN hOwner); +int MENU_SetSel (MENU_Handle hObj, int Sel); +void MENU_SetTextColor (MENU_Handle hObj, unsigned ColorIndex, GUI_COLOR Color); +int MENU_SetUserData (MENU_Handle hObj, const void * pSrc, int NumBytes); + +/********************************************************************* +* +* Managing default values +* +********************************************************************** +*/ +GUI_COLOR MENU_GetDefaultTextColor (unsigned ColorIndex); +GUI_COLOR MENU_GetDefaultBkColor (unsigned ColorIndex); +U8 MENU_GetDefaultBorderSize (unsigned BorderIndex); +const WIDGET_EFFECT * MENU_GetDefaultEffect (void); +const GUI_FONT * MENU_GetDefaultFont (void); +void MENU_SetDefaultTextColor (unsigned ColorIndex, GUI_COLOR Color); +void MENU_SetDefaultBkColor (unsigned ColorIndex, GUI_COLOR Color); +void MENU_SetDefaultBorderSize (unsigned BorderIndex, U8 BorderSize); +void MENU_SetDefaultEffect (const WIDGET_EFFECT * pEffect); +void MENU_SetDefaultFont (const GUI_FONT * pFont); + +/********************************************************************* +* +* Member functions: Skinning +* +********************************************************************** +*/ +int MENU_DrawSkinFlex (const WIDGET_ITEM_DRAW_INFO * pDrawItemInfo); +void MENU_GetSkinFlexProps (MENU_SKINFLEX_PROPS * pProps, int Index); +WIDGET_DRAW_ITEM_FUNC * MENU_SetDefaultSkin (WIDGET_DRAW_ITEM_FUNC * pfDrawSkin); +void MENU_SetDefaultSkinClassic(void); +void MENU_SetSkinClassic (MENU_Handle hObj); +void MENU_SetSkin (MENU_Handle hObj, WIDGET_DRAW_ITEM_FUNC * pfDrawSkin); +void MENU_SetSkinFlexProps (const MENU_SKINFLEX_PROPS * pProps, int Index); +void MENU_SkinEnableArrow (MENU_Handle hObj, int OnOff); + +#if defined(__cplusplus) + } +#endif + +#endif // GUI_WINSUPPORT +#endif // MENU_H + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/MENU_Private.h b/example/GUI/STemWin/inc/MENU_Private.h new file mode 100755 index 0000000000..3104949ae8 --- /dev/null +++ b/example/GUI/STemWin/inc/MENU_Private.h @@ -0,0 +1,196 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : MENU_Private.h +Purpose : Internal header file +---------------------------END-OF-HEADER------------------------------ +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef MENU_PRIVATE_H +#define MENU_PRIVATE_H + +#include "WIDGET.h" +#include "MENU.h" +#include "GUI_ARRAY.h" + +#if GUI_WINSUPPORT + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ +/********************************************************************* +* +* Status flags +*/ +#define MENU_SF_HORIZONTAL MENU_CF_HORIZONTAL +#define MENU_SF_VERTICAL MENU_CF_VERTICAL +#define MENU_SF_OPEN_ON_POINTEROVER MENU_CF_OPEN_ON_POINTEROVER +#define MENU_SF_CLOSE_ON_SECOND_CLICK MENU_CF_CLOSE_ON_SECOND_CLICK +#define MENU_SF_HIDE_DISABLED_SEL MENU_CF_HIDE_DISABLED_SEL + +#define MENU_SF_ACTIVE (1 << 6) // Internal flag only +#define MENU_SF_POPUP (1 << 7) // Internal flag only +#define MENU_SF_ARROW (1 << 8) // Internal flag only + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ +// +// MENU_SKIN_PRIVATE +// +typedef struct { + WIDGET_DRAW_ITEM_FUNC * pfDrawSkin; +} MENU_SKIN_PRIVATE; + +// +// MENU_ITEM +// +typedef struct { + MENU_Handle hSubmenu; + U16 Id; + U16 Flags; + int TextWidth; + char acText[1]; +} MENU_ITEM; + +// +// MENU_PROPS +// +typedef struct { + GUI_COLOR aTextColor[5]; + GUI_COLOR aBkColor[5]; + U8 aBorder[4]; + const GUI_FONT * pFont; + MENU_SKIN_PRIVATE SkinPrivate; +} MENU_PROPS; + +// +// MENU_Obj +// +typedef struct { + WIDGET Widget; + MENU_PROPS Props; + GUI_ARRAY ItemArray; + WM_HWIN hOwner; + U16 Flags; + char IsSubmenuActive; + int Width; + int Height; + int Sel; + unsigned ArrowAreaWidth; + WIDGET_SKIN const * pWidgetSkin; +} MENU_Obj; + +/********************************************************************* +* +* Macros for internal use +* +********************************************************************** +*/ +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL + #define MENU_INIT_ID(pObj) (pObj->Widget.DebugId = MENU_ID) +#else + #define MENU_INIT_ID(pObj) +#endif + +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL + MENU_Obj * MENU_LockH(MENU_Handle hObj); + #define MENU_LOCK_H(hObj) MENU_LockH(hObj) +#else + #define MENU_LOCK_H(hObj) (MENU_Obj *)GUI_LOCK_H(hObj) +#endif + +/********************************************************************* +* +* Public data (internal defaults) +* +********************************************************************** +*/ + +extern MENU_PROPS MENU__DefaultProps; +extern const WIDGET_EFFECT * MENU__pDefaultEffect; + +extern const WIDGET_SKIN MENU__SkinClassic; +extern WIDGET_SKIN MENU__Skin; + +extern WIDGET_SKIN const * MENU__pSkinDefault; + +/********************************************************************* +* +* Private functions +* +********************************************************************** +*/ +int MENU__CalcMenuSizeX (MENU_Handle hObj); +int MENU__CalcMenuSizeY (MENU_Handle hObj); +int MENU__FindItem (MENU_Handle hObj, U16 ItemId, MENU_Handle* phMenu); +int MENU__GetEffectSize (MENU_Handle hObj); +int MENU__GetItemHeight (MENU_Handle hObj, unsigned Index); +int MENU__GetItemWidth (MENU_Handle hObj, unsigned Index); +unsigned MENU__GetNumItems (MENU_Obj * pObj); +int MENU__HasEffect (MENU_Handle hObj, MENU_Obj * pObj); +void MENU__InvalidateItem (MENU_Handle hObj, unsigned Index); +void MENU__RecalcTextWidthOfItems(MENU_Obj * pObj); +void MENU__ResizeMenu (MENU_Handle hObj); +int MENU__SendMenuMessage (MENU_Handle hObj, WM_HWIN hDestWin, U16 MsgType, U16 ItemId); +char MENU__SetItem (MENU_Handle hObj, unsigned Index, const MENU_ITEM_DATA* pItemData); +void MENU__SetItemFlags (MENU_Obj * pObj, unsigned Index, U16 Mask, U16 Flags); + +#endif // GUI_WINSUPPORT +#endif // MENU_PRIVATE_H + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/MESSAGEBOX.h b/example/GUI/STemWin/inc/MESSAGEBOX.h new file mode 100755 index 0000000000..e6b8e78539 --- /dev/null +++ b/example/GUI/STemWin/inc/MESSAGEBOX.h @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : MESSAGEBOX.h +Purpose : Message box interface +--------------------END-OF-HEADER------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef MESSAGEBOX_H +#define MESSAGEBOX_H + +#include "WM.h" + +#if GUI_WINSUPPORT + +#if defined(__cplusplus) +extern "C" { /* Make sure we have C-declarations in C++ programs */ +#endif + +WM_HWIN MESSAGEBOX_Create(const char * sMessage, const char * sCaption, int Flags); + +/********************************************************************* +* +* The callback ... +* +* Do not call it directly ! It is only to be used from within an +* overwritten callback. +*/ +void MESSAGEBOX_Callback(WM_MESSAGE * pMsg); + +#if defined(__cplusplus) + } +#endif + +#endif /* GUI_WINSUPPORT */ + +#endif /* MESSAGEBOX */ + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/MULTIEDIT.h b/example/GUI/STemWin/inc/MULTIEDIT.h new file mode 100755 index 0000000000..d505946bcb --- /dev/null +++ b/example/GUI/STemWin/inc/MULTIEDIT.h @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : MULTIEDIT.h +Purpose : MULTIEDIT include +--------------------END-OF-HEADER------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef MULTIEDIT_H +#define MULTIEDIT_H + +#include "WM.h" +#include "DIALOG_Intern.h" /* Req. for Create indirect data structure */ + +#if GUI_WINSUPPORT + +#if defined(__cplusplus) + extern "C" { /* Make sure we have C-declarations in C++ programs */ +#endif + +#define MULTIEDIT_CF_READONLY (1 << 0) +#define MULTIEDIT_CF_INSERT (1 << 2) +#define MULTIEDIT_CF_AUTOSCROLLBAR_V (1 << 3) +#define MULTIEDIT_CF_AUTOSCROLLBAR_H (1 << 4) +#define MULTIEDIT_CF_PASSWORD (1 << 5) + +#define MULTIEDIT_SF_READONLY MULTIEDIT_CF_READONLY +#define MULTIEDIT_SF_INSERT MULTIEDIT_CF_INSERT +#define MULTIEDIT_SF_AUTOSCROLLBAR_V MULTIEDIT_CF_AUTOSCROLLBAR_V +#define MULTIEDIT_SF_AUTOSCROLLBAR_H MULTIEDIT_CF_AUTOSCROLLBAR_H +#define MULTIEDIT_SF_PASSWORD MULTIEDIT_CF_PASSWORD + +/********************************************************************* +* +* Color indices +*/ +#define MULTIEDIT_CI_EDIT 0 +#define MULTIEDIT_CI_READONLY 1 + +/********************************************************************* +* +* Public Types +* +********************************************************************** +*/ + +typedef WM_HMEM MULTIEDIT_HANDLE; + +/********************************************************************* +* +* Create functions +* +********************************************************************** +*/ +MULTIEDIT_HANDLE MULTIEDIT_Create (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int Id, int Flags, int ExFlags, const char * pText, int MaxLen); +MULTIEDIT_HANDLE MULTIEDIT_CreateEx (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int WinFlags, int ExFlags, int Id, int BufferSize, const char * pText); +MULTIEDIT_HANDLE MULTIEDIT_CreateIndirect(const GUI_WIDGET_CREATE_INFO* pCreateInfo, WM_HWIN hWinParent, int x0, int y0, WM_CALLBACK * cb); +MULTIEDIT_HANDLE MULTIEDIT_CreateUser (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int WinFlags, int ExFlags, int Id, int BufferSize, const char * pText, int NumExtraBytes); + +/********************************************************************* +* +* The callback ... +* +* Do not call it directly ! It is only to be used from within an +* overwritten callback. +*/ +void MULTIEDIT_Callback(WM_MESSAGE * pMsg); + +/********************************************************************* +* +* Member functions +* +********************************************************************** +*/ + +int MULTIEDIT_AddKey (MULTIEDIT_HANDLE hObj, U16 Key); +int MULTIEDIT_AddText (MULTIEDIT_HANDLE hObj, const char * s); +void MULTIEDIT_EnableBlink (MULTIEDIT_HANDLE hObj, int Period, int OnOff); +int MULTIEDIT_GetCursorCharPos (MULTIEDIT_HANDLE hObj); +void MULTIEDIT_GetCursorPixelPos(MULTIEDIT_HANDLE hObj, int * pxPos, int * pyPos); +void MULTIEDIT_GetPrompt (MULTIEDIT_HANDLE hObj, char* sDest, int MaxNumChars); +int MULTIEDIT_GetTextSize (MULTIEDIT_HANDLE hObj); +void MULTIEDIT_GetText (MULTIEDIT_HANDLE hObj, char* sDest, int MaxNumChars); +int MULTIEDIT_GetUserData (MULTIEDIT_HANDLE hObj, void * pDest, int NumBytes); +void MULTIEDIT_SetTextAlign (MULTIEDIT_HANDLE hObj, int Align); +void MULTIEDIT_SetAutoScrollH (MULTIEDIT_HANDLE hObj, int OnOff); +void MULTIEDIT_SetAutoScrollV (MULTIEDIT_HANDLE hObj, int OnOff); +void MULTIEDIT_SetBkColor (MULTIEDIT_HANDLE hObj, unsigned Index, GUI_COLOR color); +void MULTIEDIT_SetCursorCharPos (MULTIEDIT_HANDLE hObj, int x, int y); /* Not yet implemented */ +void MULTIEDIT_SetCursorPixelPos(MULTIEDIT_HANDLE hObj, int x, int y); /* Not yet implemented */ +void MULTIEDIT_SetCursorOffset (MULTIEDIT_HANDLE hObj, int Offset); +void MULTIEDIT_SetHBorder (MULTIEDIT_HANDLE hObj, unsigned HBorder); +void MULTIEDIT_SetFocusable (MULTIEDIT_HANDLE hObj, int State); +void MULTIEDIT_SetFont (MULTIEDIT_HANDLE hObj, const GUI_FONT * pFont); +void MULTIEDIT_SetInsertMode (MULTIEDIT_HANDLE hObj, int OnOff); +void MULTIEDIT_SetBufferSize (MULTIEDIT_HANDLE hObj, int BufferSize); +void MULTIEDIT_SetMaxNumChars (MULTIEDIT_HANDLE hObj, unsigned MaxNumChars); +void MULTIEDIT_SetPrompt (MULTIEDIT_HANDLE hObj, const char* sPrompt); +void MULTIEDIT_SetReadOnly (MULTIEDIT_HANDLE hObj, int OnOff); +void MULTIEDIT_SetPasswordMode (MULTIEDIT_HANDLE hObj, int OnOff); +void MULTIEDIT_SetText (MULTIEDIT_HANDLE hObj, const char* s); +void MULTIEDIT_SetTextColor (MULTIEDIT_HANDLE hObj, unsigned Index, GUI_COLOR color); +int MULTIEDIT_SetUserData (MULTIEDIT_HANDLE hObj, const void * pSrc, int NumBytes); +void MULTIEDIT_SetWrapNone (MULTIEDIT_HANDLE hObj); +void MULTIEDIT_SetWrapChar (MULTIEDIT_HANDLE hObj); +void MULTIEDIT_SetWrapWord (MULTIEDIT_HANDLE hObj); + +#define MULTIEDIT_SetFocussable MULTIEDIT_SetFocusable + +/********************************************************************* +* +* Macros for compatibility with older versions +* +********************************************************************** +*/ + +#define MULTIEDIT_SetMaxLen(hObj, MaxLen) MULTIEDIT_SetBufferSize(hObj, MaxLen) +#define MULTIEDIT_GetStringSize MULTIEDIT_GetTextSize + +#if defined(__cplusplus) + } +#endif + +#endif // GUI_WINSUPPORT +#endif // MULTIEDIT_H + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/MULTIPAGE.h b/example/GUI/STemWin/inc/MULTIPAGE.h new file mode 100755 index 0000000000..804d6a4aa0 --- /dev/null +++ b/example/GUI/STemWin/inc/MULTIPAGE.h @@ -0,0 +1,237 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : MULTIPAGE.h +Purpose : MULTIPAGE include +--------------------END-OF-HEADER------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef MULTIPAGE_H +#define MULTIPAGE_H + +#include "WM.h" +#include "DIALOG.h" // Required for Create indirect data structure + +#if GUI_WINSUPPORT + +#if defined(__cplusplus) + extern "C" { // Make sure we have C-declarations in C++ programs +#endif + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ +/********************************************************************* +* +* Create / Status flags +*/ +#define MULTIPAGE_ALIGN_LEFT (0 << 0) +#define MULTIPAGE_ALIGN_RIGHT (1 << 0) +#define MULTIPAGE_ALIGN_TOP (0 << 2) +#define MULTIPAGE_ALIGN_BOTTOM (1 << 2) + +#define MULTIPAGE_CF_ROTATE_CW WIDGET_CF_VERTICAL + +#define MULTIPAGE_CI_DISABLED 0 +#define MULTIPAGE_CI_ENABLED 1 + +#define MULTIPAGE_SKIN_FRAME_LEFT (1 << 0) +#define MULTIPAGE_SKIN_FRAME_RIGHT (1 << 1) +#define MULTIPAGE_SKIN_FRAME_TOP (1 << 2) +#define MULTIPAGE_SKIN_FRAME_BOTTOM (1 << 3) +#define MULTIPAGE_SKIN_FRAME_ALL (MULTIPAGE_SKIN_FRAME_LEFT | MULTIPAGE_SKIN_FRAME_RIGHT | MULTIPAGE_SKIN_FRAME_TOP | MULTIPAGE_SKIN_FRAME_BOTTOM) + +#define MULTIPAGE_SKINFLEX_PI_ENABLED 0 +#define MULTIPAGE_SKINFLEX_PI_SELECTED 1 +#define MULTIPAGE_SKINFLEX_PI_DISABLED 2 + +#define SCROLLBAR_SIZE 32 // Defines the space for the scrollbar arrows + +#define MULTIPAGE_BI_SELECTED 0 +#define MULTIPAGE_BI_UNSELECTED 1 +#define MULTIPAGE_BI_DISABLED 2 +#define MULTIPAGE_BI_MAX 3 // The defines above are used as array indices. + +/********************************************************************* +* +* Public Types +* +********************************************************************** +*/ +typedef WM_HMEM MULTIPAGE_Handle; + +typedef struct { + GUI_COLOR BkColor; + GUI_COLOR aBkUpper[2]; + GUI_COLOR aBkLower[2]; + GUI_COLOR FrameColor; + GUI_COLOR TextColor; +} MULTIPAGE_SKINFLEX_PROPS; + +typedef struct { + U8 SelSideBorderInc; // Number of pixels to add on both sides when drawing the selected item. + U8 SelTopBorderInc; // Number of pixels to add on top of selected items. +} MULTIPAGE_SKIN_PROPS; + +typedef struct { + #if GUI_SUPPORT_ROTATION + GUI_ROTATION * pRotation; + #endif + unsigned Align; + int Sel; + U16 State; + U8 FrameFlags; // Flags to let the drawing function know which parts of the frame to display. + U8 PageStatus; + GUI_DRAW_HANDLE * pDrawObj; +} MULTIPAGE_SKIN_INFO; + +/********************************************************************* +* +* Create functions +* +********************************************************************** +*/ +MULTIPAGE_Handle MULTIPAGE_Create (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int Id, int Flags, int SpecialFlags); +MULTIPAGE_Handle MULTIPAGE_CreateEx (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int WinFlags, int ExFlags, int Id); +MULTIPAGE_Handle MULTIPAGE_CreateUser (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int WinFlags, int ExFlags, int Id, int NumExtraBytes); +MULTIPAGE_Handle MULTIPAGE_CreateIndirect(const GUI_WIDGET_CREATE_INFO * pCreateInfo, WM_HWIN hWinParent, int x0, int y0, WM_CALLBACK * cb); + +/********************************************************************* +* +* The callback ... +* +* Do not call it directly ! It is only to be used from within an +* overwritten callback. +*/ +void MULTIPAGE_Callback(WM_MESSAGE * pMsg); + +/********************************************************************* +* +* Member functions +* +********************************************************************** +*/ +void MULTIPAGE_AddEmptyPage (MULTIPAGE_Handle hObj, WM_HWIN hWin ,const char * pText); +void MULTIPAGE_AddPage (MULTIPAGE_Handle hObj, WM_HWIN hWin ,const char * pText); +WM_HWIN MULTIPAGE_AttachWindow (MULTIPAGE_Handle hObj, unsigned Index, WM_HWIN hWin); +void MULTIPAGE_DeletePage (MULTIPAGE_Handle hObj, unsigned Index, int Delete); +void MULTIPAGE_DisablePage (MULTIPAGE_Handle hObj, unsigned Index); +void MULTIPAGE_EnablePage (MULTIPAGE_Handle hObj, unsigned Index); +void MULTIPAGE_EnableScrollbar(MULTIPAGE_Handle hObj, unsigned OnOff); +const GUI_FONT * MULTIPAGE_GetFont (MULTIPAGE_Handle hObj); +int MULTIPAGE_GetSelection (MULTIPAGE_Handle hObj); +int MULTIPAGE_GetPageText (MULTIPAGE_Handle hObj, unsigned Index, char * pBuffer, int MaxLen); +int MULTIPAGE_GetUserData (MULTIPAGE_Handle hObj, void * pDest, int NumBytes); +WM_HWIN MULTIPAGE_GetWindow (MULTIPAGE_Handle hObj, unsigned Index); +int MULTIPAGE_IsPageEnabled (MULTIPAGE_Handle hObj, unsigned Index); +void MULTIPAGE_SelectPage (MULTIPAGE_Handle hObj, unsigned Index); +void MULTIPAGE_SetAlign (MULTIPAGE_Handle hObj, unsigned Align); +int MULTIPAGE_SetBitmapEx (MULTIPAGE_Handle hObj, const GUI_BITMAP * pBitmap, int x, int y, int Index, int State); +int MULTIPAGE_SetBitmap (MULTIPAGE_Handle hObj, const GUI_BITMAP * pBitmap, int Index, int State); +void MULTIPAGE_SetBkColor (MULTIPAGE_Handle hObj, GUI_COLOR Color, unsigned Index); +void MULTIPAGE_SetFont (MULTIPAGE_Handle hObj, const GUI_FONT * pFont); +void MULTIPAGE_SetRotation (MULTIPAGE_Handle hObj, unsigned Rotation); +void MULTIPAGE_SetTabWidth (MULTIPAGE_Handle hObj, int Width, int Index); +void MULTIPAGE_SetTabHeight (MULTIPAGE_Handle hObj, int Height); +void MULTIPAGE_SetTextAlign (MULTIPAGE_Handle hObj, unsigned Align); +void MULTIPAGE_SetText (MULTIPAGE_Handle hObj, const char * pText, unsigned Index); +void MULTIPAGE_SetTextColor (MULTIPAGE_Handle hObj, GUI_COLOR Color, unsigned Index); +int MULTIPAGE_SetUserData (MULTIPAGE_Handle hObj, const void * pSrc, int NumBytes); + +/********************************************************************* +* +* Managing default values +* +********************************************************************** +*/ +unsigned MULTIPAGE_GetDefaultAlign (void); +GUI_COLOR MULTIPAGE_GetDefaultBkColor (unsigned Index); +const GUI_FONT * MULTIPAGE_GetDefaultFont (void); +GUI_COLOR MULTIPAGE_GetDefaultTextColor (unsigned Index); + +void MULTIPAGE_SetDefaultAlign (unsigned Align); +void MULTIPAGE_SetDefaultBkColor (GUI_COLOR Color, unsigned Index); +void MULTIPAGE_SetDefaultBorderSizeX(unsigned Size); +void MULTIPAGE_SetDefaultBorderSizeY(unsigned Size); +void MULTIPAGE_SetDefaultFont (const GUI_FONT * pFont); +void MULTIPAGE_SetDefaultTextColor (GUI_COLOR Color, unsigned Index); + +void MULTIPAGE_SetEffectColor (unsigned Index, GUI_COLOR Color); +GUI_COLOR MULTIPAGE_GetEffectColor (unsigned Index); +int MULTIPAGE_GetNumEffectColors (void); + +/********************************************************************* +* +* Member functions: Skinning +* +********************************************************************** +*/ +int MULTIPAGE_DrawSkinFlex (const WIDGET_ITEM_DRAW_INFO * pDrawItemInfo); +void MULTIPAGE_GetSkinFlexProps (MULTIPAGE_SKINFLEX_PROPS * pProps, int Index); +WIDGET_DRAW_ITEM_FUNC * MULTIPAGE_SetDefaultSkin (WIDGET_DRAW_ITEM_FUNC * pfDrawSkin); +void MULTIPAGE_SetDefaultSkinClassic(void); +void MULTIPAGE_SetSkinClassic (MULTIPAGE_Handle hObj); +void MULTIPAGE_SetSkin (MULTIPAGE_Handle hObj, WIDGET_DRAW_ITEM_FUNC * pfDrawSkin); +void MULTIPAGE_SetSkinFlexProps (const MULTIPAGE_SKINFLEX_PROPS * pProps, int Index); + +#define MULTIPAGE_SKIN_FLEX MULTIPAGE_DrawSkinFlex + +#if defined(__cplusplus) + } +#endif + +#endif // GUI_WINSUPPORT +#endif // MULTIPAGE_H + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/MULTIPAGE_Private.h b/example/GUI/STemWin/inc/MULTIPAGE_Private.h new file mode 100755 index 0000000000..bfe8e366d3 --- /dev/null +++ b/example/GUI/STemWin/inc/MULTIPAGE_Private.h @@ -0,0 +1,198 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : MULTIPAGE_Private.h +Purpose : Private MULTIPAGE include +--------------------END-OF-HEADER------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef MULTIPAGE_PRIVATE_H +#define MULTIPAGE_PRIVATE_H + +#include "GUI_Debug.h" +#include "GUI_ARRAY.h" +#include "MULTIPAGE.h" + +#if GUI_WINSUPPORT + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ +#define MULTIPAGE_STATE_ENABLED (1 << 0) +#define MULTIPAGE_STATE_SCROLLMODE WIDGET_STATE_USER0 + +#define MULTIPAGE_NUMCOLORS 2 + +/********************************************************************* +* +* Object definition +* +********************************************************************** +*/ +// +// MULTIPAGE_PAGE +// +typedef struct { + WM_HWIN hWin; + U8 Status; + int ItemWidth; + WM_HMEM hDrawObj[3]; + char acText; +} MULTIPAGE_PAGE; + +// +// MULTIPAGE_SKIN_PRIVATE +// +typedef struct { + WIDGET_DRAW_ITEM_FUNC * pfDrawSkin; +} MULTIPAGE_SKIN_PRIVATE; + +// +// MULTIPAGE_PROPS +// +typedef struct { + const GUI_FONT * pFont; + unsigned Align; + GUI_COLOR aBkColor[MULTIPAGE_NUMCOLORS]; + GUI_COLOR aTextColor[MULTIPAGE_NUMCOLORS]; + MULTIPAGE_SKIN_PRIVATE SkinPrivate; + int BorderSize0; + int BorderSize1; + unsigned TextAlign; + unsigned Scrollbar; + int (* pfGetTouchedPage)(MULTIPAGE_Handle hObj, int x, int y); + int (* pfGetTabBarWidth)(MULTIPAGE_Handle hObj); +} MULTIPAGE_PROPS; + +// +// MULTIPAGE_Obj +// +typedef struct MULTIPAGE_Obj MULTIPAGE_Obj; + +struct MULTIPAGE_Obj { + WIDGET Widget; + void (* pfDrawTextItem)(MULTIPAGE_Obj * pObj, const char * pText, unsigned Index, const GUI_RECT * pRect, int x0, int xSize, int ColorIndex); + WM_HWIN hClient; + GUI_ARRAY hPageArray; + unsigned Selection; + int ScrollState; + MULTIPAGE_PROPS Props; + WIDGET_SKIN const * pWidgetSkin; + MULTIPAGE_SKIN_PROPS SkinProps; + int ItemHeight; + int MaxHeight; +}; + +/********************************************************************* +* +* Macros for internal use +* +********************************************************************** +*/ +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL + #define MULTIPAGE_INIT_ID(p) (p->Widget.DebugId = MULTIPAGE_ID) +#else + #define MULTIPAGE_INIT_ID(p) +#endif + +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL + MULTIPAGE_Obj * MULTIPAGE_LockH(MULTIPAGE_Handle h); + #define MULTIPAGE_LOCK_H(h) MULTIPAGE_LockH(h) +#else + #define MULTIPAGE_LOCK_H(h) (MULTIPAGE_Obj *)GUI_LOCK_H(h) +#endif + +/********************************************************************* +* +* Externals +* +********************************************************************** +*/ +extern GUI_COLOR MULTIPAGE__aEffectColor[2]; +extern MULTIPAGE_PROPS MULTIPAGE__DefaultProps; + +extern const WIDGET_SKIN MULTIPAGE__SkinClassic; +extern WIDGET_SKIN MULTIPAGE__Skin; + +extern WIDGET_SKIN const * MULTIPAGE__pSkinDefault; + +/********************************************************************* +* +* Private functions +* +********************************************************************** +*/ +void MULTIPAGE__CalcBorderRect (MULTIPAGE_Obj * pObj, GUI_RECT * pRect); +void MULTIPAGE__CalcClientRect (MULTIPAGE_Handle hObj, GUI_RECT * pRect); +void MULTIPAGE__DeleteScrollbar(MULTIPAGE_Handle hObj); +void MULTIPAGE__DrawTextItemH (MULTIPAGE_Obj * pObj, const char * pText, unsigned Index, const GUI_RECT * pRect, int x0, int w, int ColorIndex); +int MULTIPAGE__GetPagePos (MULTIPAGE_Handle hObj, unsigned Index); +int MULTIPAGE__GetPageWidth (MULTIPAGE_Handle hObj, unsigned Index); +void MULTIPAGE__GetTabBarRect (MULTIPAGE_Handle hObj, GUI_RECT * pRect); +void MULTIPAGE__UpdatePositions(MULTIPAGE_Handle hObj); + +/********************************************************************* +* +* Private Skinning functions +* +********************************************************************** +*/ +int MULTIPAGE_SKIN__GetPagePos (MULTIPAGE_Handle hObj, unsigned Index); +int MULTIPAGE_SKIN__GetTabBarWidth(MULTIPAGE_Handle hObj); +int MULTIPAGE_SKIN__GetTouchedPage(MULTIPAGE_Handle hObj, int TouchX, int TouchY); + +#endif // GUI_WINSUPPORT +#endif // MULTIPAGE_PRIVATE_H + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/PROGBAR.h b/example/GUI/STemWin/inc/PROGBAR.h new file mode 100755 index 0000000000..ebea7d2710 --- /dev/null +++ b/example/GUI/STemWin/inc/PROGBAR.h @@ -0,0 +1,179 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : PROGBAR.h +Purpose : Progressbar include +--------------------END-OF-HEADER------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef PROGBAR_H /* Avoid multiple inclusion */ +#define PROGBAR_H + +#include "WM.h" +#include "DIALOG_Intern.h" /* Req. for Create indirect data structure */ +#include "WIDGET.h" + +#if GUI_WINSUPPORT + +#if defined(__cplusplus) + extern "C" { /* Make sure we have C-declarations in C++ programs */ +#endif + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ +/********************************************************************* +* +* Create flags +*/ +#define PROGBAR_CF_HORIZONTAL (0 << 0) +#define PROGBAR_CF_VERTICAL (1 << 0) +#define PROGBAR_CF_USER (1 << 1) + +/********************************************************************* +* +* Skinning constants +*/ +#define PROGBAR_SKINFLEX_L 0 +#define PROGBAR_SKINFLEX_R 1 + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ +typedef WM_HMEM PROGBAR_Handle; + +typedef struct { + GUI_COLOR aColorUpperL[2]; + GUI_COLOR aColorLowerL[2]; + GUI_COLOR aColorUpperR[2]; + GUI_COLOR aColorLowerR[2]; + GUI_COLOR ColorFrame; + GUI_COLOR ColorText; +} PROGBAR_SKINFLEX_PROPS; + +typedef struct { + int IsVertical; + int Index; + const char * pText; +} PROGBAR_SKINFLEX_INFO; + +/********************************************************************* +* +* Create functions +* +********************************************************************** +*/ + +PROGBAR_Handle PROGBAR_Create (int x0, int y0, int xSize, int ySize, int Flags); +PROGBAR_Handle PROGBAR_CreateAsChild (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int Id, int Flags); +PROGBAR_Handle PROGBAR_CreateEx (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int WinFlags, int ExFlags, int Id); +PROGBAR_Handle PROGBAR_CreateUser (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int WinFlags, int ExFlags, int Id, int NumExtraBytes); +PROGBAR_Handle PROGBAR_CreateIndirect(const GUI_WIDGET_CREATE_INFO * pCreateInfo, WM_HWIN hWinParent, int x0, int y0, WM_CALLBACK * cb); + +/********************************************************************* +* +* The callback ... +* +* Do not call it directly ! It is only to be used from within an +* overwritten callback. +*/ +void PROGBAR_Callback(WM_MESSAGE * pMsg); + +/********************************************************************* +* +* Individual member functions +* +********************************************************************** +*/ + +void PROGBAR_GetMinMax (PROGBAR_Handle hObj, int * pMin, int * pMax); +int PROGBAR_GetUserData (PROGBAR_Handle hObj, void * pDest, int NumBytes); +int PROGBAR_GetValue (PROGBAR_Handle hObj); +void PROGBAR_SetBarColor (PROGBAR_Handle hObj, unsigned int index, GUI_COLOR color); +void PROGBAR_SetFont (PROGBAR_Handle hObj, const GUI_FONT * pfont); +void PROGBAR_SetMinMax (PROGBAR_Handle hObj, int Min, int Max); +void PROGBAR_SetText (PROGBAR_Handle hObj, const char* s); +void PROGBAR_SetTextAlign(PROGBAR_Handle hObj, int Align); +void PROGBAR_SetTextColor(PROGBAR_Handle hObj, unsigned int index, GUI_COLOR color); +void PROGBAR_SetTextPos (PROGBAR_Handle hObj, int XOff, int YOff); +void PROGBAR_SetValue (PROGBAR_Handle hObj, int v); +int PROGBAR_SetUserData (PROGBAR_Handle hObj, const void * pSrc, int NumBytes); + +/********************************************************************* +* +* Member functions: Skinning +* +********************************************************************** +*/ +void PROGBAR_GetSkinFlexProps (PROGBAR_SKINFLEX_PROPS * pProps, int Index); +void PROGBAR_SetSkinClassic (PROGBAR_Handle hObj); +void PROGBAR_SetSkin (PROGBAR_Handle hObj, WIDGET_DRAW_ITEM_FUNC * pfDrawSkin); +int PROGBAR_DrawSkinFlex (const WIDGET_ITEM_DRAW_INFO * pDrawItemInfo); +void PROGBAR_SetSkinFlexProps (const PROGBAR_SKINFLEX_PROPS * pProps, int Index); +void PROGBAR_SetDefaultSkinClassic(void); +WIDGET_DRAW_ITEM_FUNC * PROGBAR_SetDefaultSkin(WIDGET_DRAW_ITEM_FUNC * pfDrawSkin); + +#define PROGBAR_SKIN_FLEX PROGBAR_DrawSkinFlex + +#if defined(__cplusplus) + } +#endif + +#endif // GUI_WINSUPPORT +#endif // PROGBAR_H + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/PROGBAR_Private.h b/example/GUI/STemWin/inc/PROGBAR_Private.h new file mode 100755 index 0000000000..9467bcf102 --- /dev/null +++ b/example/GUI/STemWin/inc/PROGBAR_Private.h @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : PROGBAR_Private.h +Purpose : Internal header file +---------------------------END-OF-HEADER------------------------------ +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef PROGBAR_PRIVATE_H +#define PROGBAR_PRIVATE_H + +#include "PROGBAR.h" +#include "WIDGET.h" + +#if GUI_WINSUPPORT + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ +#define PROGBAR_SF_HORIZONTAL PROGBAR_CF_HORIZONTAL +#define PROGBAR_SF_VERTICAL PROGBAR_CF_VERTICAL +#define PROGBAR_SF_USER PROGBAR_CF_USER + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ +typedef struct { + WIDGET_DRAW_ITEM_FUNC * pfDrawSkin; +} PROGBAR_SKIN_PRIVATE; + +typedef struct { + const GUI_FONT * pFont; + GUI_COLOR aBarColor[2]; + GUI_COLOR aTextColor[2]; + PROGBAR_SKIN_PRIVATE SkinPrivate; +} PROGBAR_PROPS; + +typedef struct { + WIDGET Widget; + int v; + WM_HMEM hpText; + I16 XOff, YOff; + I16 TextAlign; + int Min, Max; + PROGBAR_PROPS Props; + WIDGET_SKIN const * pWidgetSkin; + U8 Flags; +} PROGBAR_Obj; + +/********************************************************************* +* +* Macros for internal use +* +********************************************************************** +*/ +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL + #define PROGBAR_INIT_ID(p) p->Widget.DebugId = PROGBAR_ID +#else + #define PROGBAR_INIT_ID(p) +#endif + +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL + PROGBAR_Obj * PROGBAR_LockH(PROGBAR_Handle h); + #define PROGBAR_LOCK_H(h) PROGBAR_LockH(h) +#else + #define PROGBAR_LOCK_H(h) (PROGBAR_Obj *)GUI_LOCK_H(h) +#endif + +/********************************************************************* +* +* Public data (internal defaults) +* +********************************************************************** +*/ +extern PROGBAR_PROPS PROGBAR__DefaultProps; + +extern const WIDGET_SKIN PROGBAR__SkinClassic; +extern WIDGET_SKIN PROGBAR__Skin; + +extern WIDGET_SKIN const * PROGBAR__pSkinDefault; + +/********************************************************************* +* +* Public functions (internal) +* +********************************************************************** +*/ +char * PROGBAR__GetTextLocked(const PROGBAR_Obj * pObj); +void PROGBAR__GetTextRect (const PROGBAR_Obj * pObj, GUI_RECT * pRect, const char * pText); +int PROGBAR__Value2Pos (const PROGBAR_Obj * pObj, int v); + +#endif /* GUI_WINSUPPORT */ +#endif /* PROGBAR_PRIVATE_H */ + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/RADIO.h b/example/GUI/STemWin/inc/RADIO.h new file mode 100755 index 0000000000..afddc05807 --- /dev/null +++ b/example/GUI/STemWin/inc/RADIO.h @@ -0,0 +1,207 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : RADIO.h +Purpose : RADIO include +--------------------END-OF-HEADER------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef RADIO_H +#define RADIO_H + +#include "WM.h" +#include "DIALOG_Intern.h" /* Req. for Create indirect data structure */ +#include "WIDGET.h" + +#if GUI_WINSUPPORT + +#if defined(__cplusplus) + extern "C" { /* Make sure we have C-declarations in C++ programs */ +#endif + +/********************************************************************* +* +* Bitmap indices +*/ +#define RADIO_BI_INACTIV 0 +#define RADIO_BI_ACTIV 1 +#define RADIO_BI_CHECK 2 + +/********************************************************************* +* +* Skinning property indices +*/ +#define RADIO_SKINFLEX_PI_PRESSED 0 +#define RADIO_SKINFLEX_PI_UNPRESSED 1 + +/********************************************************************* +* +* Defaults for public configuration switches +* +********************************************************************** + +The following are defaults for config switches which affect the +interface specified in this module +*/ + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ +#define RADIO_TEXTPOS_RIGHT 0 +#define RADIO_TEXTPOS_LEFT WIDGET_STATE_USER0 /* Not implemented, TBD */ + +/********************************************************************* +* +* Public Types +* +********************************************************************** +*/ +typedef WM_HMEM RADIO_Handle; + +typedef struct { + GUI_COLOR aColorButton[4]; + int ButtonSize; +} RADIO_SKINFLEX_PROPS; + +/********************************************************************* +* +* Create functions +* +********************************************************************** +*/ + +RADIO_Handle RADIO_Create (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int Id, int Flags, unsigned Para); +RADIO_Handle RADIO_CreateEx (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int WinFlags, int ExFlags, int Id, int NumItems, int Spacing); +RADIO_Handle RADIO_CreateUser (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int WinFlags, int ExFlags, int Id, int NumItems, int Spacing, int NumExtraBytes); +RADIO_Handle RADIO_CreateIndirect(const GUI_WIDGET_CREATE_INFO * pCreateInfo, WM_HWIN hWinParent, int x0, int y0, WM_CALLBACK * cb); + +/********************************************************************* +* +* The callback ... +* +* Do not call it directly ! It is only to be used from within an +* overwritten callback. +*/ +void RADIO_Callback(WM_MESSAGE * pMsg); + +/********************************************************************* +* +* Managing default values +* +********************************************************************** +*/ + +void RADIO_SetDefaultFont (const GUI_FONT * pFont); +GUI_COLOR RADIO_SetDefaultFocusColor(GUI_COLOR Color); +void RADIO_SetDefaultImage (const GUI_BITMAP * pBitmap, unsigned int Index); +void RADIO_SetDefaultTextColor (GUI_COLOR TextColor); +const GUI_FONT * RADIO_GetDefaultFont (void); +GUI_COLOR RADIO_GetDefaultTextColor (void); + +/********************************************************************* +* +* Member functions +* +********************************************************************** +*/ + +void RADIO_AddValue (RADIO_Handle hObj, int Add); +void RADIO_Dec (RADIO_Handle hObj); +int RADIO_GetText (RADIO_Handle hObj, unsigned Index, char * pBuffer, int MaxLen); +int RADIO_GetUserData (RADIO_Handle hObj, void * pDest, int NumBytes); +void RADIO_Inc (RADIO_Handle hObj); +void RADIO_SetBkColor (RADIO_Handle hObj, GUI_COLOR Color); +GUI_COLOR RADIO_SetFocusColor(RADIO_Handle hObj, GUI_COLOR Color); +void RADIO_SetFont (RADIO_Handle hObj, const GUI_FONT * pFont); +void RADIO_SetGroupId (RADIO_Handle hObj, U8 GroupId); +void RADIO_SetImage (RADIO_Handle hObj, const GUI_BITMAP * pBitmap, unsigned int Index); +void RADIO_SetText (RADIO_Handle hObj, const char* pText, unsigned Index); +void RADIO_SetTextColor (RADIO_Handle hObj, GUI_COLOR Color); +void RADIO_SetValue (RADIO_Handle hObj, int v); +int RADIO_SetUserData (RADIO_Handle hObj, const void * pSrc, int NumBytes); + +const GUI_BITMAP * RADIO_GetImage(RADIO_Handle hObj, unsigned int Index); + +/********************************************************************* +* +* Member functions: Skinning +* +********************************************************************** +*/ +void RADIO_GetSkinFlexProps (RADIO_SKINFLEX_PROPS * pProps, int Index); +void RADIO_SetSkinClassic (RADIO_Handle hObj); +void RADIO_SetSkin (RADIO_Handle hObj, WIDGET_DRAW_ITEM_FUNC * pfDrawSkin); +int RADIO_DrawSkinFlex (const WIDGET_ITEM_DRAW_INFO * pDrawItemInfo); +void RADIO_SetSkinFlexProps (const RADIO_SKINFLEX_PROPS * pProps, int Index); +void RADIO_SetDefaultSkinClassic(void); +WIDGET_DRAW_ITEM_FUNC * RADIO_SetDefaultSkin(WIDGET_DRAW_ITEM_FUNC * pfDrawSkin); + +#define RADIO_SKIN_FLEX RADIO_DrawSkinFlex + +/********************************************************************* +* +* Query state +* +********************************************************************** +*/ +int RADIO_GetValue(RADIO_Handle hObj); + +#if defined(__cplusplus) + } +#endif + +#endif // GUI_WINSUPPORT +#endif // RADIO_H + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/RADIO_Private.h b/example/GUI/STemWin/inc/RADIO_Private.h new file mode 100755 index 0000000000..c46e7e44b9 --- /dev/null +++ b/example/GUI/STemWin/inc/RADIO_Private.h @@ -0,0 +1,214 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : RADIO_Private.h +Purpose : RADIO private header file +--------------------END-OF-HEADER------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef RADIO_PRIVATE_H +#define RADIO_PRIVATE_H + +#include "WM.h" + +#if GUI_WINSUPPORT + +#include "RADIO.h" +#include "WIDGET.h" +#include "GUI_ARRAY.h" + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ +/* Define default image inactiv */ +#ifndef RADIO_IMAGE0_DEFAULT + #define RADIO_IMAGE0_DEFAULT &RADIO__abmRadio[0] +#endif + +/* Define default image activ */ +#ifndef RADIO_IMAGE1_DEFAULT + #define RADIO_IMAGE1_DEFAULT &RADIO__abmRadio[1] +#endif + +/* Define default image check */ +#ifndef RADIO_IMAGE_CHECK_DEFAULT + #define RADIO_IMAGE_CHECK_DEFAULT &RADIO__bmCheck +#endif + +/* Define default font */ +#ifndef RADIO_FONT_DEFAULT + #if WIDGET_USE_SCHEME_SMALL + #define RADIO_SPACING_DEFAULT 20 + #define RADIO_FONT_DEFAULT &GUI_Font13_1 + #elif WIDGET_USE_SCHEME_MEDIUM + #define RADIO_SPACING_DEFAULT 24 + #define RADIO_FONT_DEFAULT &GUI_Font16_1 + #elif WIDGET_USE_SCHEME_LARGE + #define RADIO_SPACING_DEFAULT 30 + #define RADIO_FONT_DEFAULT &GUI_Font24_1 + #endif +#endif + +/* Define vertical default spacing */ +#ifndef RADIO_SPACING_DEFAULT + #define RADIO_SPACING_DEFAULT 20 +#endif + +/* Define default text color */ +#ifndef RADIO_DEFAULT_TEXT_COLOR + #define RADIO_DEFAULT_TEXT_COLOR GUI_BLACK +#endif + +/* Define default background color */ +#ifndef RADIO_DEFAULT_BKCOLOR + #define RADIO_DEFAULT_BKCOLOR GUI_GRAY_C0 +#endif + +#ifndef RADIO_FOCUSCOLOR_DEFAULT + #define RADIO_FOCUSCOLOR_DEFAULT GUI_BLACK +#endif + +#define RADIO_BORDER 2 + +/********************************************************************* +* +* Object definition +* +********************************************************************** +*/ +typedef struct { + unsigned (* pfGetButtonSize)(RADIO_Handle hObj); + WIDGET_DRAW_ITEM_FUNC * pfDrawSkin; +} RADIO_SKIN_PRIVATE; + +typedef struct { + GUI_COLOR BkColor; + GUI_COLOR TextColor; + GUI_COLOR FocusColor; + const GUI_FONT * pFont; + const GUI_BITMAP * apBmRadio[2]; + const GUI_BITMAP * pBmCheck; + RADIO_SKIN_PRIVATE SkinPrivate; +} RADIO_PROPS; + +typedef struct { + WIDGET Widget; + RADIO_PROPS Props; + WIDGET_SKIN const * pWidgetSkin; + GUI_ARRAY TextArray; + I16 Sel; /* current selection */ + U16 Spacing; + U16 NumItems; + U8 GroupId; +} RADIO_Obj; + +/********************************************************************* +* +* Macros for internal use +* +********************************************************************** +*/ +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL + #define RADIO_INIT_ID(p) p->Widget.DebugId = RADIO_ID +#else + #define RADIO_INIT_ID(p) +#endif + +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL + RADIO_Obj * RADIO_LockH(RADIO_Handle h); + #define RADIO_LOCK_H(h) RADIO_LockH(h) +#else + #define RADIO_LOCK_H(h) (RADIO_Obj *)GUI_LOCK_H(h) +#endif + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ + +typedef void tRADIO_SetValue(RADIO_Handle hObj, int v); + +/********************************************************************* +* +* Extern data +* +********************************************************************** +*/ + +extern RADIO_PROPS RADIO__DefaultProps; + +extern const WIDGET_SKIN RADIO__SkinClassic; +extern WIDGET_SKIN RADIO__Skin; + +extern WIDGET_SKIN const * RADIO__pSkinDefault; + +extern const GUI_BITMAP RADIO__abmRadio[2]; +extern const GUI_BITMAP RADIO__bmCheck; +extern tRADIO_SetValue* RADIO__pfHandleSetValue; + +/********************************************************************* +* +* public functions (internal) +* +********************************************************************** +*/ +void RADIO__SetValue (RADIO_Handle hObj, int v); +unsigned RADIO__GetButtonSize(RADIO_Handle hObj); + +#endif /* GUI_WINSUPPORT */ +#endif /* RADIO_PRIVATE_H */ + +/************************* end of file ******************************/ diff --git a/example/GUI/STemWin/inc/SCROLLBAR.h b/example/GUI/STemWin/inc/SCROLLBAR.h new file mode 100755 index 0000000000..281eafe530 --- /dev/null +++ b/example/GUI/STemWin/inc/SCROLLBAR.h @@ -0,0 +1,228 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : SCROLLBAR.h +Purpose : SCROLLBAR include +--------------------END-OF-HEADER------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef SCROLLBAR_H +#define SCROLLBAR_H + +#include "WM.h" +#include "DIALOG_Intern.h" /* Req. for Create indirect data structure */ +#include "WIDGET.h" + +#if GUI_WINSUPPORT + +#if defined(__cplusplus) + extern "C" { /* Make sure we have C-declarations in C++ programs */ +#endif + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ +#define SCROLLBAR_CI_THUMB 0 +#define SCROLLBAR_CI_SHAFT 1 +#define SCROLLBAR_CI_ARROW 2 + +/********************************************************************* +* +* States +*/ +#define SCROLLBAR_STATE_PRESSED WIDGET_STATE_USER0 + +/********************************************************************* +* +* Create / Status flags +*/ +#define SCROLLBAR_CF_VERTICAL WIDGET_CF_VERTICAL +#define SCROLLBAR_CF_FOCUSABLE WIDGET_STATE_FOCUSABLE + +#define SCROLLBAR_CF_FOCUSSABLE SCROLLBAR_CF_FOCUSABLE + +/************************************************************ +* +* Skinning property indices +*/ +#define SCROLLBAR_SKINFLEX_PI_PRESSED 0 +#define SCROLLBAR_SKINFLEX_PI_UNPRESSED 1 + +/********************************************************************* +* +* Public Types +* +********************************************************************** +*/ +typedef WM_HMEM SCROLLBAR_Handle; + +typedef struct { + GUI_COLOR aColorFrame[3]; + GUI_COLOR aColorUpper[2]; + GUI_COLOR aColorLower[2]; + GUI_COLOR aColorShaft[2]; + GUI_COLOR ColorArrow; + GUI_COLOR ColorGrasp; +} SCROLLBAR_SKINFLEX_PROPS; + +typedef struct { + int IsVertical; + int State; +} SCROLLBAR_SKINFLEX_INFO; + +/********************************************************************* +* +* Create functions +* +********************************************************************** +*/ +SCROLLBAR_Handle SCROLLBAR_Create (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int Id, int WinFlags, int SpecialFlags); +SCROLLBAR_Handle SCROLLBAR_CreateAttached(WM_HWIN hParent, int SpecialFlags); +SCROLLBAR_Handle SCROLLBAR_CreateEx (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int WinFlags, int ExFlags, int Id); +SCROLLBAR_Handle SCROLLBAR_CreateUser (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int WinFlags, int ExFlags, int Id, int NumExtraBytes); +SCROLLBAR_Handle SCROLLBAR_CreateIndirect(const GUI_WIDGET_CREATE_INFO * pCreateInfo, WM_HWIN hWinParent, int x0, int y0, WM_CALLBACK * cb); + +/********************************************************************* +* +* The callback ... +* +* Do not call it directly ! It is only to be used from within an +* overwritten callback. +*/ +void SCROLLBAR_Callback(WM_MESSAGE * pMsg); + +/********************************************************************* +* +* Member functions +* +********************************************************************** +*/ + +/* Methods changing properties */ + +void SCROLLBAR_AddValue (SCROLLBAR_Handle hObj, int Add); +void SCROLLBAR_Dec (SCROLLBAR_Handle hObj); +void SCROLLBAR_Inc (SCROLLBAR_Handle hObj); +int SCROLLBAR_GetUserData(SCROLLBAR_Handle hObj, void * pDest, int NumBytes); +GUI_COLOR SCROLLBAR_SetColor (SCROLLBAR_Handle hObj, int Index, GUI_COLOR Color); +void SCROLLBAR_SetNumItems(SCROLLBAR_Handle hObj, int NumItems); +void SCROLLBAR_SetPageSize(SCROLLBAR_Handle hObj, int PageSize); +void SCROLLBAR_SetValue (SCROLLBAR_Handle hObj, int v); +int SCROLLBAR_SetWidth (SCROLLBAR_Handle hObj, int Width); +void SCROLLBAR_SetState (SCROLLBAR_Handle hObj, const WM_SCROLL_STATE* pState); +int SCROLLBAR_SetUserData(SCROLLBAR_Handle hObj, const void * pSrc, int NumBytes); + +/********************************************************************* +* +* Member functions: Skinning +* +********************************************************************** +*/ +void SCROLLBAR_GetSkinFlexProps (SCROLLBAR_SKINFLEX_PROPS * pProps, int Index); +void SCROLLBAR_SetSkinClassic (SCROLLBAR_Handle hObj); +void SCROLLBAR_SetSkin (SCROLLBAR_Handle hObj, WIDGET_DRAW_ITEM_FUNC * pfDrawSkin); +int SCROLLBAR_DrawSkinFlex (const WIDGET_ITEM_DRAW_INFO * pDrawItemInfo); +void SCROLLBAR_SetSkinFlexProps (const SCROLLBAR_SKINFLEX_PROPS * pProps, int Index); +void SCROLLBAR_SetDefaultSkinClassic(void); +WIDGET_DRAW_ITEM_FUNC * SCROLLBAR_SetDefaultSkin(WIDGET_DRAW_ITEM_FUNC * pfDrawSkin); + +#define SCROLLBAR_SKIN_FLEX SCROLLBAR_DrawSkinFlex + +/********************************************************************* +* +* Managing default values +* +********************************************************************** +*/ +int SCROLLBAR_GetDefaultWidth(void); +GUI_COLOR SCROLLBAR_SetDefaultColor(GUI_COLOR Color, unsigned int Index); /* Not yet documented */ +int SCROLLBAR_SetDefaultWidth(int DefaultWidth); + +/********************************************************************* +* +* Global functions +* +********************************************************************** +*/ +int SCROLLBAR_GetThumbSizeMin(void); +int SCROLLBAR_SetThumbSizeMin(int ThumbSizeMin); + +/********************************************************************* +* +* Query state +* +********************************************************************** +*/ +int SCROLLBAR_GetNumItems(SCROLLBAR_Handle hObj); +int SCROLLBAR_GetPageSize(SCROLLBAR_Handle hObj); +int SCROLLBAR_GetValue (SCROLLBAR_Handle hObj); + +/********************************************************************* +* +* Macros for compatibility +* +********************************************************************** +*/ +#define SCROLLBAR_BKCOLOR0_DEFAULT SCROLLBAR_COLOR_ARROW_DEFAULT +#define SCROLLBAR_BKCOLOR1_DEFAULT SCROLLBAR_COLOR_SHAFT_DEFAULT +#define SCROLLBAR_COLOR0_DEFAULT SCROLLBAR_COLOR_THUMB_DEFAULT + +#if defined(__cplusplus) + } +#endif + +#endif // GUI_WINSUPPORT +#endif // SCROLLBAR_H + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/SCROLLBAR_Private.h b/example/GUI/STemWin/inc/SCROLLBAR_Private.h new file mode 100755 index 0000000000..9394950830 --- /dev/null +++ b/example/GUI/STemWin/inc/SCROLLBAR_Private.h @@ -0,0 +1,209 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : SCROLLBAR_Private.h +Purpose : SCROLLBAR internal header file +---------------------------END-OF-HEADER------------------------------ +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef SCROLLBAR_PRIVATE_H +#define SCROLLBAR_PRIVATE_H + +#include "SCROLLBAR.h" +#include "WIDGET.h" +#include "GUI_Debug.h" + +#if GUI_WINSUPPORT + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ +#define PRESSED_STATE_NONE 0 +#define PRESSED_STATE_RIGHT 1 +#define PRESSED_STATE_LEFT 2 +#define PRESSED_STATE_THUMB 3 + +/********************************************************************* +* +* Private config defaults +* +********************************************************************** +*/ + +/* Define colors */ +#ifndef SCROLLBAR_COLOR_SHAFT_DEFAULT + #define SCROLLBAR_COLOR_SHAFT_DEFAULT GUI_GRAY +#endif + +#ifndef SCROLLBAR_COLOR_ARROW_DEFAULT + #define SCROLLBAR_COLOR_ARROW_DEFAULT GUI_BLACK +#endif + +#ifndef SCROLLBAR_COLOR_THUMB_DEFAULT + #define SCROLLBAR_COLOR_THUMB_DEFAULT GUI_GRAY_C0 +#endif + +#ifndef SCROLLBAR_THUMB_SIZE_MIN_DEFAULT + #define SCROLLBAR_THUMB_SIZE_MIN_DEFAULT 4 +#endif + +#ifndef SCROLLBAR_DEFAULT_WIDTH + #if WIDGET_USE_SCHEME_SMALL + #define SCROLLBAR_DEFAULT_WIDTH 11 + #elif WIDGET_USE_SCHEME_MEDIUM + #define SCROLLBAR_DEFAULT_WIDTH 16 + #elif WIDGET_USE_SCHEME_LARGE + #define SCROLLBAR_DEFAULT_WIDTH 22 + #endif +#endif + +#define SCROLLBAR_TIMER_ID 1234 + +/********************************************************************* +* +* Module internal data +* +********************************************************************** +*/ +extern GUI_COLOR SCROLLBAR__aDefaultBkColor[2]; +extern GUI_COLOR SCROLLBAR__aDefaultColor[2]; +extern I16 SCROLLBAR__DefaultWidth; +extern I16 SCROLLBAR__ThumbSizeMin; + +/********************************************************************* +* +* Object definition +* +********************************************************************** +*/ +typedef struct { + WIDGET_DRAW_ITEM_FUNC * pfDrawSkin; +} SCROLLBAR_SKIN_PRIVATE; + +typedef struct { + GUI_COLOR aColor[3]; + SCROLLBAR_SKIN_PRIVATE SkinPrivate; +} SCROLLBAR_PROPS; + +typedef struct { + int x0_LeftArrow; + int x1_LeftArrow; + int x0_Thumb; + int x1_Thumb; + int x0_RightArrow; + int x1_RightArrow; + int x1; + int xSizeMoveable; + int ThumbSize; +} SCROLLBAR_POSITIONS; + +typedef struct SCROLLBAR_OBJ SCROLLBAR_OBJ; + +struct SCROLLBAR_OBJ { + WIDGET Widget; + SCROLLBAR_PROPS Props; + WIDGET_SKIN const * pWidgetSkin; + void (* pfCalcPositions)(SCROLLBAR_Handle hObj, SCROLLBAR_POSITIONS * pPos); + int NumItems, v, PageSize; + int State; + int TimerStep; + int TouchPos; + WM_HMEM hTimer; +}; + +/********************************************************************* +* +* Private macros +* +********************************************************************** +*/ +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL + #define SCROLLBAR_INIT_ID(p) (p->Widget.DebugId = SCROLLBAR_ID) +#else + #define SCROLLBAR_INIT_ID(p) +#endif + +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL + SCROLLBAR_OBJ * SCROLLBAR_LockH(SCROLLBAR_Handle h); + #define SCROLLBAR_LOCK_H(h) SCROLLBAR_LockH(h) +#else + #define SCROLLBAR_LOCK_H(h) (SCROLLBAR_OBJ *)GUI_LOCK_H(h) +#endif + +/********************************************************************* +* +* Private functions +* +********************************************************************** +*/ +void SCROLLBAR__InvalidatePartner(SCROLLBAR_Handle hObj); +void SCROLLBAR__Rect2VRect (const WIDGET * pWidget, GUI_RECT * pRect); + +/********************************************************************* +* +* Private data +* +********************************************************************** +*/ +extern SCROLLBAR_PROPS SCROLLBAR__DefaultProps; + +extern const WIDGET_SKIN SCROLLBAR__SkinClassic; +extern WIDGET_SKIN SCROLLBAR__Skin; + +extern WIDGET_SKIN const * SCROLLBAR__pSkinDefault; + +#endif /* GUI_WINSUPPORT */ +#endif /* Avoid multiple inclusion */ + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/SEGGER.h b/example/GUI/STemWin/inc/SEGGER.h new file mode 100755 index 0000000000..3274e3b2ca --- /dev/null +++ b/example/GUI/STemWin/inc/SEGGER.h @@ -0,0 +1,197 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +Licensing information +Licensor: SEGGER Software GmbH +Licensed to: STMicroelectronics International NV, 39, Chemin du Champ-des Filles, 1228 Plan Les Ouates, Geneva, SWITZERLAND +Licensed SEGGER software: emWin +License number: GUI-00429 +License model: Buyout SRC [Buyout Source Code License, signed November 29th 2012] +Licensed product: - +Licensed platform: STMs ARM Cortex-M based 32 BIT CPUs +Licensed number of seats: - +---------------------------------------------------------------------- +Support and Update Agreement (SUA) +SUA period: 2012-12-07 - 2017-12-31 +Contact to extend SUA: sales@segger.com +---------------------------------------------------------------------- +File : SEGGER.h +Purpose : Global types etc & general purpose utility functions +Revision: $Rev: 6176 $ +---------------------------END-OF-HEADER------------------------------ +*/ + +#ifndef SEGGER_H // Guard against multiple inclusion +#define SEGGER_H + +#include +#include "Global.h" // Type definitions: U8, U16, U32, I8, I16, I32 + +#if defined(__cplusplus) +extern "C" { /* Make sure we have C-declarations in C++ programs */ +#endif + +/********************************************************************* +* +* Keywords/specifiers +* +********************************************************************** +*/ + +#ifndef INLINE + #ifdef _WIN32 + // + // Microsoft VC6 and newer. + // Force inlining without cost checking. + // + #define INLINE __forceinline + #else + #if (defined(__GNUC__)) + // + // Force inlining with GCC + // + #define INLINE inline __attribute__((always_inline)) + #elif (defined(__ICCARM__) || defined(__CC_ARM) || defined(__RX) || defined(__ICCRX__)) + // + // Other known compilers. + // + #define INLINE inline + #else + // + // Unknown compilers. + // + #define INLINE + #endif + #endif +#endif + +/********************************************************************* +* +* Function-like macros +* +********************************************************************** +*/ + +#define SEGGER_COUNTOF(a) (sizeof((a))/sizeof((a)[0])) +#define SEGGER_MIN(a,b) (((a) < (b)) ? (a) : (b)) +#define SEGGER_MAX(a,b) (((a) > (b)) ? (a) : (b)) + +#ifndef SEGGER_USE_PARA // Some compiler complain about unused parameters. + #define SEGGER_USE_PARA(Para) (void)Para // This works for most compilers. +#endif + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ + +#define SEGGER_PRINTF_FLAG_ADJLEFT (1 << 0) +#define SEGGER_PRINTF_FLAG_SIGNFORCE (1 << 1) +#define SEGGER_PRINTF_FLAG_SIGNSPACE (1 << 2) +#define SEGGER_PRINTF_FLAG_PRECEED (1 << 3) +#define SEGGER_PRINTF_FLAG_ZEROPAD (1 << 4) +#define SEGGER_PRINTF_FLAG_NEGATIVE (1 << 5) + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ + +typedef struct { + char* pBuffer; + int BufferSize; + int Cnt; +} SEGGER_BUFFER_DESC; + +typedef struct { + int CacheLineSize; // 0: No Cache. Most Systems such as ARM9 use a 32 bytes cache line size. + void (*pfDMB) (void); // Optional DMB function for Data Memory Barrier to make sure all memory operations are completed. + void (*pfClean) (void *p, unsigned NumBytes); // Optional clean function for cached memory. + void (*pfInvalidate)(void *p, unsigned NumBytes); // Optional invalidate function for cached memory. +} SEGGER_CACHE_CONFIG; + +typedef struct SEGGER_SNPRINTF_CONTEXT_struct SEGGER_SNPRINTF_CONTEXT; + +struct SEGGER_SNPRINTF_CONTEXT_struct { + void* pContext; // Application specific context. + SEGGER_BUFFER_DESC* pBufferDesc; // Buffer descriptor to use for output. + void (*pfFlush)(SEGGER_SNPRINTF_CONTEXT* pContext); // Callback executed once the buffer is full. Callback decides if the buffer gets cleared to store more or not. +}; + +typedef struct { + void (*pfStoreChar) (SEGGER_BUFFER_DESC* pBufferDesc, SEGGER_SNPRINTF_CONTEXT* pContext, char c); + int (*pfPrintUnsigned) (SEGGER_BUFFER_DESC* pBufferDesc, SEGGER_SNPRINTF_CONTEXT* pContext, U32 v, unsigned Base, char Flags, int Width, int Precision); + int (*pfPrintInt) (SEGGER_BUFFER_DESC* pBufferDesc, SEGGER_SNPRINTF_CONTEXT* pContext, I32 v, unsigned Base, char Flags, int Width, int Precision); +} SEGGER_PRINTF_API; + +typedef void (*SEGGER_pFormatter)(SEGGER_BUFFER_DESC* pBufferDesc, SEGGER_SNPRINTF_CONTEXT* pContext, const SEGGER_PRINTF_API* pApi, va_list* pParamList, char Lead, int Width, int Precision); + +typedef struct SEGGER_PRINTF_FORMATTER { + struct SEGGER_PRINTF_FORMATTER* pNext; // Pointer to next formatter. + SEGGER_pFormatter pfFormatter; // Formatter function. + char Specifier; // Format specifier. +} SEGGER_PRINTF_FORMATTER; + +/********************************************************************* +* +* Utility functions +* +********************************************************************** +*/ + +void SEGGER_ARM_memcpy(void* pDest, const void* pSrc, int NumBytes); +void SEGGER_memcpy (void* pDest, const void* pSrc, int NumBytes); +void SEGGER_memxor (void* pDest, const void* pSrc, unsigned NumBytes); + +void SEGGER_StoreChar (SEGGER_BUFFER_DESC* pBufferDesc, char c); +void SEGGER_PrintUnsigned(SEGGER_BUFFER_DESC* pBufferDesc, U32 v, unsigned Base, int Precision); +void SEGGER_PrintInt (SEGGER_BUFFER_DESC* pBufferDesc, I32 v, unsigned Base, int Precision); +int SEGGER_snprintf (char* pBuffer, int BufferSize, const char* sFormat, ...); +int SEGGER_vsnprintf (char* pBuffer, int BufferSize, const char* sFormat, va_list ParamList); +int SEGGER_vsnprintfEx (SEGGER_SNPRINTF_CONTEXT* pContext, const char* sFormat, va_list ParamList); + +int SEGGER_PRINTF_AddFormatter (SEGGER_PRINTF_FORMATTER* pFormatter, SEGGER_pFormatter pfFormatter, char c); +void SEGGER_PRINTF_AddDoubleFormatter(void); +void SEGGER_PRINTF_AddIPFormatter (void); +void SEGGER_PRINTF_AddHTMLFormatter (void); + +#if defined(__cplusplus) +} /* Make sure we have C-declarations in C++ programs */ +#endif + +#endif // Avoid multiple inclusion + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/SLIDER.h b/example/GUI/STemWin/inc/SLIDER.h new file mode 100755 index 0000000000..11b47bbf0b --- /dev/null +++ b/example/GUI/STemWin/inc/SLIDER.h @@ -0,0 +1,207 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : SLIDER.h +Purpose : SLIDER include +--------------------END-OF-HEADER------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef SLIDER_H +#define SLIDER_H + +#include "WM.h" +#include "DIALOG_Intern.h" /* Req. for Create indirect data structure */ +#include "WIDGET.h" + +#if GUI_WINSUPPORT + +#if defined(__cplusplus) + extern "C" { /* Make sure we have C-declarations in C++ programs */ +#endif + +/************************************************************ +* +* Defines +* +************************************************************* +*/ +/************************************************************ +* +* States +*/ +#define SLIDER_STATE_PRESSED WIDGET_STATE_USER0 + +/************************************************************ +* +* Create / Status flags +*/ +#define SLIDER_CF_HORIZONTAL 0 +#define SLIDER_CF_VERTICAL WIDGET_CF_VERTICAL + +/************************************************************ +* +* Skinning property indices +*/ +#define SLIDER_SKINFLEX_PI_PRESSED 0 +#define SLIDER_SKINFLEX_PI_UNPRESSED 1 + +/********************************************************************* +* +* Public Types +* +********************************************************************** +*/ +typedef WM_HMEM SLIDER_Handle; + +typedef struct { + GUI_COLOR aColorFrame[2]; + GUI_COLOR aColorInner[2]; + GUI_COLOR aColorShaft[3]; + GUI_COLOR ColorTick; + GUI_COLOR ColorFocus; + int TickSize; + int ShaftSize; +} SLIDER_SKINFLEX_PROPS; + +typedef struct { + int Width; + int NumTicks; + int Size; + int IsPressed; + int IsVertical; +} SLIDER_SKINFLEX_INFO; + +/********************************************************************* +* +* Create functions +* +********************************************************************** +*/ +SLIDER_Handle SLIDER_Create (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int Id, int WinFlags, int SpecialFlags); +SLIDER_Handle SLIDER_CreateEx (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int WinFlags, int ExFlags, int Id); +SLIDER_Handle SLIDER_CreateUser (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int WinFlags, int ExFlags, int Id, int NumExtraBytes); +SLIDER_Handle SLIDER_CreateIndirect(const GUI_WIDGET_CREATE_INFO * pCreateInfo, WM_HWIN hWinParent, int x0, int y0, WM_CALLBACK * cb); + +/********************************************************************* +* +* The callback ... +* +* Do not call it directly ! It is only to be used from within an +* overwritten callback. +*/ +void SLIDER_Callback(WM_MESSAGE * pMsg); + +/********************************************************************* +* +* Member functions +* +********************************************************************** +*/ +void SLIDER_Dec (SLIDER_Handle hObj); +void SLIDER_EnableFocusRect(SLIDER_Handle hObj, int OnOff); +GUI_COLOR SLIDER_GetBarColor (SLIDER_Handle hObj); +GUI_COLOR SLIDER_GetBkColor (SLIDER_Handle hObj); +U8 SLIDER_GetFlag (SLIDER_Handle hObj, U8 Flag); +GUI_COLOR SLIDER_GetFocusColor (SLIDER_Handle hObj); +void SLIDER_GetRange (SLIDER_Handle hObj, int * pMin, int * pMax); +GUI_COLOR SLIDER_GetTickColor (SLIDER_Handle hObj); +int SLIDER_GetUserData (SLIDER_Handle hObj, void * pDest, int NumBytes); +int SLIDER_GetValue (SLIDER_Handle hObj); +void SLIDER_Inc (SLIDER_Handle hObj); +void SLIDER_SetBarColor (SLIDER_Handle hObj, GUI_COLOR Color); +void SLIDER_SetBkColor (SLIDER_Handle hObj, GUI_COLOR Color); +GUI_COLOR SLIDER_SetFocusColor (SLIDER_Handle hObj, GUI_COLOR Color); +void SLIDER_SetNumTicks (SLIDER_Handle hObj, int NumTicks); +void SLIDER_SetRange (SLIDER_Handle hObj, int Min, int Max); +void SLIDER_SetTickColor (SLIDER_Handle hObj, GUI_COLOR Color); +int SLIDER_SetUserData (SLIDER_Handle hObj, const void * pSrc, int NumBytes); +void SLIDER_SetValue (SLIDER_Handle hObj, int v); +void SLIDER_SetWidth (SLIDER_Handle hObj, int Width); + +/********************************************************************* +* +* Member functions: Skinning +* +********************************************************************** +*/ +void SLIDER_GetSkinFlexProps (SLIDER_SKINFLEX_PROPS * pProps, int Index); +void SLIDER_SetSkinClassic (SLIDER_Handle hObj); +void SLIDER_SetSkin (SLIDER_Handle hObj, WIDGET_DRAW_ITEM_FUNC * pfDrawSkin); +int SLIDER_DrawSkinFlex (const WIDGET_ITEM_DRAW_INFO * pDrawItemInfo); +void SLIDER_SetSkinFlexProps (const SLIDER_SKINFLEX_PROPS * pProps, int Index); +void SLIDER_SetDefaultSkinClassic(void); +WIDGET_DRAW_ITEM_FUNC * SLIDER_SetDefaultSkin(WIDGET_DRAW_ITEM_FUNC * pfDrawSkin); + +#define SLIDER_SKIN_FLEX SLIDER_DrawSkinFlex + +/********************************************************************* +* +* Managing default values +* +********************************************************************** +*/ +GUI_COLOR SLIDER_GetDefaultBkColor (void); +GUI_COLOR SLIDER_GetDefaultBarColor (void); +GUI_COLOR SLIDER_GetDefaultFocusColor(void); +GUI_COLOR SLIDER_GetDefaultTickColor (void); +void SLIDER_SetDefaultBkColor (GUI_COLOR Color); +void SLIDER_SetDefaultBarColor (GUI_COLOR Color); +GUI_COLOR SLIDER_SetDefaultFocusColor(GUI_COLOR Color); +void SLIDER_SetDefaultTickColor (GUI_COLOR Color); + +#if defined(__cplusplus) + } +#endif + +#endif // GUI_WINSUPPORT +#endif // SLIDER_H + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/SLIDER_Private.h b/example/GUI/STemWin/inc/SLIDER_Private.h new file mode 100755 index 0000000000..e92b04e03f --- /dev/null +++ b/example/GUI/STemWin/inc/SLIDER_Private.h @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : SLIDER_Private.h +Purpose : SLIDER private header file +--------------------END-OF-HEADER------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef SLIDER_PRIVATE_H +#define SLIDER_PRIVATE_H + +#include "WM.h" +#include "WIDGET.h" +#include "SLIDER.h" + +#if GUI_WINSUPPORT + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ +// +// Flags +// +#define SLIDER_FLAG_DRAW_FOCUS_RECT (1 << 0) + +/********************************************************************* +* +* Object definition +* +********************************************************************** +*/ +typedef struct { + WIDGET_DRAW_ITEM_FUNC * pfDrawSkin; +} SLIDER_SKIN_PRIVATE; + +typedef struct { + U8 Flags; + GUI_COLOR BkColor; + GUI_COLOR BarColor; + GUI_COLOR FocusColor; + GUI_COLOR TickColor; + SLIDER_SKIN_PRIVATE SkinPrivate; +} SLIDER_PROPS; + +typedef struct { + WIDGET Widget; + SLIDER_PROPS Props; + WIDGET_SKIN const * pWidgetSkin; + int NumTicks; + int Max; + int Min; + int v; + I16 Width; +} SLIDER_Obj; + +/********************************************************************* +* +* Macros for internal use +* +********************************************************************** +*/ +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL + #define SLIDER_INIT_ID(p) (p->Widget.DebugId = SLIDER_ID) +#else + #define SLIDER_INIT_ID(p) +#endif + +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL + SLIDER_Obj * SLIDER_LockH(SLIDER_Handle h); + #define SLIDER_LOCK_H(h) SLIDER_LockH(h) +#else + #define SLIDER_LOCK_H(h) (SLIDER_Obj *)GUI_LOCK_H(h) +#endif + +#ifndef SLIDER_SUPPORT_TRANSPARENCY + #define SLIDER_SUPPORT_TRANSPARENCY WM_SUPPORT_TRANSPARENCY +#endif + +/********************************************************************* +* +* Public data (internal defaults) +* +********************************************************************** +*/ +extern SLIDER_PROPS SLIDER__DefaultProps; +extern const WIDGET_SKIN SLIDER__SkinClassic; +extern WIDGET_SKIN SLIDER__Skin; +extern const WIDGET_SKIN * SLIDER__pSkinDefault; + +#endif // GUI_WINSUPPORT +#endif // SLIDER_PRIVATE_H + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/SPINBOX.h b/example/GUI/STemWin/inc/SPINBOX.h new file mode 100755 index 0000000000..6df8ffea3f --- /dev/null +++ b/example/GUI/STemWin/inc/SPINBOX.h @@ -0,0 +1,202 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : SPINBOX.h +Purpose : SPINBOX header file +--------------------END-OF-HEADER------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef SPINBOX_H +#define SPINBOX_H + +#include "WM.h" +#include "DIALOG_Intern.h" // Required for Create indirect data structure +#include "WIDGET.h" +#include "GUI_Debug.h" +#include "EDIT.h" + +#if GUI_WINSUPPORT + +#if defined(__cplusplus) + extern "C" { // Make sure we have C-declarations in C++ programs +#endif + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ +/********************************************************************* +* +* States +*/ +#define SPINBOX_STATE_PRESSED(x) (U8)(1 << (U8)x) // These flags are stored in (SPINBOX_OBJ->State) | x must be 0 or 1 +#define SPINBOX_STATE_FOCUS WIDGET_STATE_FOCUS // This is read from (SPINBOX_OBJ->Widget.State) + +#define SPINBOX_EDGE_RIGHT 0 +#define SPINBOX_EDGE_LEFT 1 +#define SPINBOX_EDGE_CENTER 2 + +#define SPINBOX_EM_STEP 0 +#define SPINBOX_EM_EDIT 1 + +#ifndef SPINBOX_EM_DEFAULT + #define SPINBOX_EM_DEFAULT SPINBOX_EM_STEP +#endif + +/********************************************************************* +* +* Color indices +*/ +#define SPINBOX_CI_DISABLED EDIT_CI_DISABLED +#define SPINBOX_CI_ENABLED EDIT_CI_ENABLED +#define SPINBOX_CI_PRESSED 2 + +/********************************************************************* +* +* Skinning property indices +*/ +#define SPINBOX_SKIN_FLEX SPINBOX_DrawSkinFlex + +#define SPINBOX_SKINFLEX_PI_PRESSED 0 +#define SPINBOX_SKINFLEX_PI_FOCUSED 1 +#define SPINBOX_SKINFLEX_PI_ENABLED 2 +#define SPINBOX_SKINFLEX_PI_DISABLED 3 +#define SPINBOX_SKIN_FLEX_RADIUS 2 + +/********************************************************************* +* +* Public Types +* +********************************************************************** +*/ +typedef WM_HMEM SPINBOX_Handle; + +typedef struct { + GUI_COLOR aColorFrame[2]; // [0] Outer color of surrounding frame. [1] Inner color of surrounding frame. + GUI_COLOR aColorUpper[2]; // [0] Upper color of gradient for upper button. [1] Lower color of gradient for upper button. + GUI_COLOR aColorLower[2]; // [0] Upper color of gradient for lower button. [1] Lower color of gradient for lower button. + GUI_COLOR ColorArrow; // Color of the button arrow. + GUI_COLOR ColorBk; // Color of the background. // See WIDGET_ITEM_CREATE in SPINBOX_DrawSkinFlex() + GUI_COLOR ColorText; // Color of the text. // See WIDGET_ITEM_CREATE in SPINBOX_DrawSkinFlex() + GUI_COLOR ColorButtonFrame; // Color of the button frame. +} SPINBOX_SKINFLEX_PROPS; + +/********************************************************************* +* +* Prototypes +* +********************************************************************** +*/ +/********************************************************************* +* +* Creation +*/ +SPINBOX_Handle SPINBOX_CreateEx (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int WinFlags, int Id, int Min, int Max); +SPINBOX_Handle SPINBOX_CreateUser (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int WinFlags, int Id, int Min, int Max, int NumExtraBytes); +SPINBOX_Handle SPINBOX_CreateIndirect(const GUI_WIDGET_CREATE_INFO * pCreateInfo, WM_HWIN hWinParent, int x0, int y0, WM_CALLBACK * cb); + +/********************************************************************* +* +* Callback, should be called only from within a custom callback. +*/ +void SPINBOX_Callback(WM_MESSAGE * pMsg); + +/********************************************************************* +* +* Get / Set properties +*/ +void SPINBOX_EnableBlink (SPINBOX_Handle hObj, int Period, int OnOff); +GUI_COLOR SPINBOX_GetBkColor (SPINBOX_Handle hObj, unsigned int Index); +GUI_COLOR SPINBOX_GetButtonBkColor(SPINBOX_Handle hObj, unsigned int Index); +EDIT_Handle SPINBOX_GetEditHandle (SPINBOX_Handle hObj); +int SPINBOX_GetUserData (SPINBOX_Handle hObj, void * pDest, int NumBytes); +I32 SPINBOX_GetValue (SPINBOX_Handle hObj); +void SPINBOX_SetBkColor (SPINBOX_Handle hObj, unsigned int Index, GUI_COLOR Color); +void SPINBOX_SetButtonBkColor(SPINBOX_Handle hObj, unsigned int Index, GUI_COLOR Color); +void SPINBOX_SetButtonSize (SPINBOX_Handle hObj, unsigned ButtonSize); +void SPINBOX_SetEdge (SPINBOX_Handle hObj, U8 Edge); +void SPINBOX_SetEditMode (SPINBOX_Handle hObj, U8 EditMode); +void SPINBOX_SetFont (SPINBOX_Handle hObj, const GUI_FONT * pFont); +void SPINBOX_SetRange (SPINBOX_Handle hObj, I32 Min, I32 Max); +U16 SPINBOX_SetStep (SPINBOX_Handle hObj, U16 Step); +void SPINBOX_SetTextColor (SPINBOX_Handle hObj, unsigned int Index, GUI_COLOR Color); +int SPINBOX_SetUserData (SPINBOX_Handle hObj, const void * pSrc, int NumBytes); +void SPINBOX_SetValue (SPINBOX_Handle hObj, I32 Value); + +/********************************************************************* +* +* Managing default values +*/ +U16 SPINBOX_GetDefaultButtonSize(void); +void SPINBOX_SetDefaultButtonSize(U16 ButtonSize); + +/********************************************************************* +* +* Skinning +*/ +void SPINBOX_GetSkinFlexProps (SPINBOX_SKINFLEX_PROPS * pProps, int Index); +void SPINBOX_SetSkinClassic (SPINBOX_Handle hObj); +void SPINBOX_SetSkin (SPINBOX_Handle hObj, WIDGET_DRAW_ITEM_FUNC * pfDrawSkin); +int SPINBOX_DrawSkinFlex (const WIDGET_ITEM_DRAW_INFO * pDrawItemInfo); +void SPINBOX_SetSkinFlexProps (const SPINBOX_SKINFLEX_PROPS * pProps, int Index); +void SPINBOX_SetDefaultSkinClassic(void); +WIDGET_DRAW_ITEM_FUNC * SPINBOX_SetDefaultSkin(WIDGET_DRAW_ITEM_FUNC * pfDrawSkin); + +#if defined(__cplusplus) + } +#endif + +#endif // GUI_WINSUPPORT +#endif // SPINBOX_H + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/SPINBOX_Private.h b/example/GUI/STemWin/inc/SPINBOX_Private.h new file mode 100755 index 0000000000..ee77451cb5 --- /dev/null +++ b/example/GUI/STemWin/inc/SPINBOX_Private.h @@ -0,0 +1,169 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : SPINBOX_Private.h +Purpose : Private SPINBOX include +--------------------END-OF-HEADER------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef SPINBOX_PRIVATE_H +#define SPINBOX_PRIVATE_H + +#include "SPINBOX.h" +#include "EDIT.h" +#include "GUI_Private.h" + +#if GUI_WINSUPPORT + +/********************************************************************* +* +* Private config defaults +* +********************************************************************** +*/ + +/********************************************************************* +* +* Object definition +* +********************************************************************** +*/ +typedef struct { + WIDGET_DRAW_ITEM_FUNC * pfDrawSkin; +} SPINBOX_SKIN_PRIVATE; + +typedef struct { + GUI_COLOR aButtonBkColor[3]; // Button background color for the states (disabled, pressed, unpressed). + GUI_COLOR aButtonUpperColor[3]; // Upper color for the button states (disabled, pressed, unpressed). + GUI_COLOR aButtonLowerColor[3]; // Lower color for the button states (disabled, pressed, unpressed). + GUI_COLOR aButtonOuterColor[3]; // Outer color for the button states (disabled, pressed, unpressed). + GUI_COLOR aTriangleColor[3]; // Color of the triangle for the button states (disabled, pressed, unpressed). + GUI_COLOR aBkColor[2]; // Background color for the states (enabled, disabled). + GUI_COLOR aTextColor[2]; // Text color for the states (enabled, disabled). + I32 Min; // Minimum allowed value. + I32 Max; // Maximum allowed value. + U16 Step; // Value will be increased/decreased by this amount when a button is clicked. + U16 ButtonSize; // Size of the button depending on the orientation. + U8 Edge; // Buttons reside on the left or right edge of the widget. + SPINBOX_SKIN_PRIVATE SkinPrivate; // Structure containing a pointer to the used DrawSkin-function. +} SPINBOX_PROPS; + +typedef struct { + WIDGET Widget; + SPINBOX_PROPS Props; + const WIDGET_SKIN * pWidgetSkin; + EDIT_Handle hEdit; + GUI_TIMER_HANDLE hTimer; + I8 TimerButton; + I8 LastButton; + I8 NoAction; + U8 State; // Pressed state +} SPINBOX_OBJ; + +/********************************************************************* +* +* Macros for internal use +* +********************************************************************** +*/ +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL + #define SPINBOX_INIT_ID(p) (p->Widget.DebugId = SPINBOX_ID) +#else + #define SPINBOX_INIT_ID(p) +#endif + +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL + SPINBOX_OBJ * SPINBOX_LockH(SPINBOX_Handle h); + #define SPINBOX_LOCK_H(h) SPINBOX_LockH(h) +#else + #define SPINBOX_LOCK_H(h) (SPINBOX_OBJ *)GUI_LOCK_H(h) +#endif + +#define SPINBOX_BUTTON_NONE -1 +#define SPINBOX_BUTTON_0 0 +#define SPINBOX_BUTTON_1 1 + +#define SPINBOX_TIMER_ID 1234 + +/********************************************************************* +* +* Private function prototypes +* +********************************************************************** +*/ +void SPINBOX__ApplyProps (SPINBOX_Handle hObj, SPINBOX_SKINFLEX_PROPS * const * ppProps); +void SPINBOX__DrawBk (SPINBOX_Handle hObj, GUI_COLOR Color); +void SPINBOX__GetButtonRect (SPINBOX_Handle hObj, GUI_RECT * pButtonRect, U8 ButtonIndex); +void SPINBOX__GetButtonRectEx(SPINBOX_Handle hObj, WIDGET_ITEM_DRAW_INFO * ItemInfo); +int SPINBOX__GetDefaultMax (void); +int SPINBOX__GetDefaultMin (void); + +/********************************************************************* +* +* Module internal data +* +********************************************************************** +*/ +/********************************************************************* +* +* Public data (internal defaults) +* +********************************************************************** +*/ +extern SPINBOX_PROPS SPINBOX__DefaultProps; +extern const WIDGET_SKIN SPINBOX__SkinClassic; +extern WIDGET_SKIN SPINBOX__Skin; +extern const WIDGET_SKIN * SPINBOX__pSkinDefault; + +#endif // GUI_WINSUPPORT +#endif // SPINBOX_PRIVATE_H + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/SWIPELIST.h b/example/GUI/STemWin/inc/SWIPELIST.h new file mode 100755 index 0000000000..b9a78c2818 --- /dev/null +++ b/example/GUI/STemWin/inc/SWIPELIST.h @@ -0,0 +1,223 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : SWIPELIST.h +Purpose : SWIPELIST include +--------------------END-OF-HEADER------------------------------------- +*/ + +#ifndef SWIPELIST_H +#define SWIPELIST_H + +#include "WM.h" +#include "DIALOG_Intern.h" // Req. for Create indirect data structure +#include "WIDGET.h" +#include "GUI_Debug.h" + +#if GUI_WINSUPPORT + +#if defined(__cplusplus) + extern "C" { // Make sure we have C-declarations in C++ programs +#endif + +/********************************************************************* +* +* Create flags +* +********************************************************************** +*/ +#define SWIPELIST_CF_HORIZONTAL (0 << 0) +#define SWIPELIST_CF_VERTICAL (1 << 0) + +/********************************************************************* +* +* Getting border size +*/ +#define SWIPELIST_BI_LEFT 0 +#define SWIPELIST_BI_RIGHT 1 +#define SWIPELIST_BI_TOP 2 +#define SWIPELIST_BI_BOTTOM 3 + +/********************************************************************* +* +* Getting font +*/ +#define SWIPELIST_FI_SEP_ITEM 0 +#define SWIPELIST_FI_ITEM_HEADER 1 +#define SWIPELIST_FI_ITEM_TEXT 2 + +/********************************************************************* +* +* Getting color +*/ +#define SWIPELIST_CI_ITEM_HEADER_UNSEL 0 +#define SWIPELIST_CI_ITEM_HEADER_SEL 1 +#define SWIPELIST_CI_ITEM_TEXT_UNSEL 2 +#define SWIPELIST_CI_ITEM_TEXT_SEL 3 +#define SWIPELIST_CI_SEP_ITEM_TEXT 4 + +#define SWIPELIST_CI_BK_ITEM_UNSEL 0 +#define SWIPELIST_CI_BK_ITEM_SEL 1 +#define SWIPELIST_CI_BK_SEP_ITEM 2 + +/********************************************************************* +* +* Bitmap align +*/ +#define SWIPELIST_BA_LEFT (0<<0) +#define SWIPELIST_BA_RIGHT (1<<0) +#define SWIPELIST_BA_HCENTER (2<<0) + +#define SWIPELIST_BA_VCENTER (3<<2) +#define SWIPELIST_BA_TOP (0<<2) +#define SWIPELIST_BA_BOTTOM (1<<2) + + +/********************************************************************* +* +* Public Types +* +********************************************************************** +*/ +typedef WM_HMEM SWIPELIST_Handle; + +/********************************************************************* +* +* Create functions +* +********************************************************************** +*/ +SWIPELIST_Handle SWIPELIST_CreateAsChild (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int Id, int Flags); +SWIPELIST_Handle SWIPELIST_CreateEx (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int WinFlags, int ExFlags, int Id); +SWIPELIST_Handle SWIPELIST_CreateIndirect (const GUI_WIDGET_CREATE_INFO * pCreateInfo, WM_HWIN hWinParent, int x0, int y0, WM_CALLBACK * cb); +SWIPELIST_Handle SWIPELIST_CreateUser (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int WinFlags, int ExFlags, int Id, int NumExtraBytes); + +/********************************************************************* +* +* The callback ... +* +* Do not call it directly ! It is only to be used from within an +* overwritten callback. +*/ +void SWIPELIST_Callback(WM_MESSAGE * pMsg); + +/********************************************************************* +* +* Member functions +* +********************************************************************** +*/ + + +int SWIPELIST_AddItem (SWIPELIST_Handle hObj, const char * sText, int ItemSize); +int SWIPELIST_AddItemText (SWIPELIST_Handle hObj, unsigned ItemIndex, const char * sText); +int SWIPELIST_AddSepItem (SWIPELIST_Handle hObj, const char * sText, int ItemSize); +void SWIPELIST_DeleteItem (SWIPELIST_Handle hObj, unsigned ItemIndex); + +const GUI_BITMAP * SWIPELIST_GetBitmap (SWIPELIST_Handle hObj, unsigned ItemIndex); +int SWIPELIST_GetBitmapSpace (SWIPELIST_Handle hObj); +GUI_COLOR SWIPELIST_GetBkColor (SWIPELIST_Handle hObj, unsigned Index); +int SWIPELIST_GetBorderSize (SWIPELIST_Handle hObj, unsigned Index); +const GUI_FONT * SWIPELIST_GetFont (SWIPELIST_Handle hObj, unsigned Index); +int SWIPELIST_GetItemSize (SWIPELIST_Handle hObj, unsigned ItemIndex); +U32 SWIPELIST_GetItemUserData (SWIPELIST_Handle hObj, unsigned ItemIndex); +int SWIPELIST_GetNumItems (SWIPELIST_Handle hObj); +int SWIPELIST_GetNumText (SWIPELIST_Handle hObj, unsigned ItemIndex); +int SWIPELIST_GetReleasedItem (SWIPELIST_Handle hObj); +int SWIPELIST_GetScrollPos (SWIPELIST_Handle hObj); +int SWIPELIST_GetSelItem (SWIPELIST_Handle hObj); +GUI_COLOR SWIPELIST_GetSepColor (SWIPELIST_Handle hObj, unsigned ItemIndex); +int SWIPELIST_GetSepSize (SWIPELIST_Handle hObj, unsigned ItemIndex); +void SWIPELIST_GetText (SWIPELIST_Handle hObj, unsigned ItemIndex, unsigned TextIndex, char * pBuffer, int MaxSize); +int SWIPELIST_GetTextAlign (SWIPELIST_Handle hObj, unsigned ItemIndex); +GUI_COLOR SWIPELIST_GetTextColor (SWIPELIST_Handle hObj, unsigned Index); +int SWIPELIST_GetThreshold (SWIPELIST_Handle hObj); +int SWIPELIST_GetUserData (SWIPELIST_Handle hObj, void * pDest, int NumBytes); + +int SWIPELIST_ItemAttachWindow (SWIPELIST_Handle hObj, unsigned ItemIndex, WM_HWIN hWin, int x0, int y0); +void SWIPELIST_ItemDetachWindow (SWIPELIST_Handle hObj, WM_HWIN hWin); +int SWIPELIST_OwnerDraw (const WIDGET_ITEM_DRAW_INFO * pDrawItemInfo); + +void SWIPELIST_SetAttachedWindowPos (SWIPELIST_Handle hObj, WM_HWIN hWin, int x0, int y0); +void SWIPELIST_SetBitmap (SWIPELIST_Handle hObj, unsigned ItemIndex, int Align, const GUI_BITMAP * pBitmap); +void SWIPELIST_SetBitmapEx (SWIPELIST_Handle hObj, unsigned ItemIndex, int Align, const GUI_BITMAP * pBitmap, int x, int y); +void SWIPELIST_SetBitmapSpace (SWIPELIST_Handle hObj, unsigned Size); +void SWIPELIST_SetBkColor (SWIPELIST_Handle hObj, unsigned Index, GUI_COLOR Color); +void SWIPELIST_SetBorderSize (SWIPELIST_Handle hObj, unsigned Index, unsigned Size); +void SWIPELIST_SetFont (SWIPELIST_Handle hObj, unsigned Index, const GUI_FONT * pFont); +void SWIPELIST_SetItemSize (SWIPELIST_Handle hObj, unsigned ItemIndex, unsigned Size); +void SWIPELIST_SetItemUserData (SWIPELIST_Handle hObj, unsigned ItemIndex, U32 UserData); +void SWIPELIST_SetOwnerDraw (SWIPELIST_Handle hObj, WIDGET_DRAW_ITEM_FUNC * pfDrawItem); +void SWIPELIST_SetScrollPos (SWIPELIST_Handle hObj, int Pos); +void SWIPELIST_SetScrollPosItem (SWIPELIST_Handle hObj, unsigned ItemIndex); +void SWIPELIST_SetSepColor (SWIPELIST_Handle hObj, unsigned ItemIndex, GUI_COLOR Color); +void SWIPELIST_SetSepSize (SWIPELIST_Handle hObj, unsigned ItemIndex, int Size); +void SWIPELIST_SetText (SWIPELIST_Handle hObj, unsigned ItemIndex, unsigned TextIndex, char * sText); +void SWIPELIST_SetTextAlign (SWIPELIST_Handle hObj, unsigned ItemIndex, int Align); +void SWIPELIST_SetTextColor (SWIPELIST_Handle hObj, unsigned Index, GUI_COLOR Color); +int SWIPELIST_SetThreshold (SWIPELIST_Handle hObj, int Threshold); +int SWIPELIST_SetUserData (SWIPELIST_Handle hObj, const void * pSrc, int NumBytes); + +/********************************************************************* +* +* Global functions +* +********************************************************************** +*/ +int SWIPELIST_GetDefaultBitmapSpace (void); +GUI_COLOR SWIPELIST_GetDefaultBkColor (unsigned Index); +int SWIPELIST_GetDefaultBorderSize (unsigned Index); +const GUI_FONT * SWIPELIST_GetDefaultFont (unsigned Index); +GUI_COLOR SWIPELIST_GetDefaultSepColor (void); +unsigned SWIPELIST_GetDefaultSepSize (void); +GUI_COLOR SWIPELIST_GetDefaultTextColor (unsigned Index); +int SWIPELIST_GetDefaultTextAlign (void); +int SWIPELIST_GetDefaultThreshold (void); + +void SWIPELIST_SetDefaultBitmapSpace (unsigned Size); +void SWIPELIST_SetDefaultBkColor (unsigned Index, GUI_COLOR Color); +void SWIPELIST_SetDefaultBorderSize (unsigned Index, unsigned Size); +void SWIPELIST_SetDefaultFont (unsigned Index, const GUI_FONT * pFont); +void SWIPELIST_SetDefaultSepColor (GUI_COLOR Color); +void SWIPELIST_SetDefaultSepSize (unsigned Size); +void SWIPELIST_SetDefaultTextColor (unsigned Index, GUI_COLOR Color); +void SWIPELIST_SetDefaultTextAlign (int Align); +void SWIPELIST_SetDefaultThreshold (int Threshold); + +#if defined(__cplusplus) + } +#endif + +#endif // GUI_WINSUPPORT +#endif // SWIPELIST_H + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/SWIPELIST_Private.h b/example/GUI/STemWin/inc/SWIPELIST_Private.h new file mode 100755 index 0000000000..15ba4598b0 --- /dev/null +++ b/example/GUI/STemWin/inc/SWIPELIST_Private.h @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : SWIPELIST.h +Purpose : SWIPELIST include +--------------------END-OF-HEADER------------------------------------- +*/ + +#ifndef SWIPELIST_PRIVATE_H +#define SWIPELIST_PRIVATE_H + +#include "SWIPELIST.h" +#include "GUI_Private.h" +#include "GUI_ARRAY.h" + +#if GUI_WINSUPPORT + +/********************************************************************* +* +* Object definition +* +********************************************************************** +*/ +typedef struct { + WM_HWIN hWin; + int xPos; + int yPos; +} SWIPELIST_WIN; + +typedef struct { + GUI_ARRAY WinArray; + GUI_ARRAY TextArray; + int TextSize; + WM_HMEM hDrawObj; + GUI_COLOR SepColor; + int SepSize; + int Pos; + int Size; + int BitmapAlign; + int TextAlign; + U8 Flags; + U32 UserData; +} SWIPELIST_ITEM; + +typedef struct { + const GUI_FONT * pSepFont; + const GUI_FONT * pHeaderFont; + const GUI_FONT * pTextFont; + GUI_COLOR aTextColor[5]; + GUI_COLOR aBkColor[3]; + int BitmapSpace; + int aBorderSize[4]; + U8 Flags; + int Threshold; +} SWIPELIST_PROPS; + +typedef struct { + WIDGET Widget; + SWIPELIST_PROPS Props; + WIDGET_DRAW_ITEM_FUNC * pfDrawItem; + GUI_ARRAY ItemArray; + int Pos; + int Size; + int FirstVisible; + int LastVisible; + int Sel; + int ReleasedItem; +} SWIPELIST_OBJ; + +/********************************************************************* +* +* Macros for internal use +* +********************************************************************** +*/ +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL + #define SWIPELIST_INIT_ID(p) p->Widget.DebugId = SWIPELIST_ID +#else + #define SWIPELIST_INIT_ID(p) +#endif + +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL + SWIPELIST_OBJ * SWIPELIST_LockH(SWIPELIST_Handle h); + #define SWIPELIST_LOCK_H(h) SWIPELIST_LockH(h) +#else + #define SWIPELIST_LOCK_H(h) (SWIPELIST_OBJ *)GUI_LOCK_H(h) +#endif + +/********************************************************************* +* +* Module internal data +* +********************************************************************** +*/ +extern SWIPELIST_PROPS SWIPELIST__DefaultProps; +extern GUI_COLOR SWIPELIST__DefaultSepColor; +extern int SWIPELIST__DefaultSepSize; +extern int SWIPELIST__DefaultTextAlign; + +/********************************************************************* +* +* Private functions +* +********************************************************************** +*/ +void SWIPELIST__SetDrawObj (SWIPELIST_Handle hObj, int Index, int Align, GUI_DRAW_HANDLE hDrawObj); +void SWIPELIST__CalcItemPos (GUI_ARRAY ItemArray, int StartIndex, int EndIndex, int AddSize); +int SWIPELIST__CalcItemSize (SWIPELIST_Handle hObj, int ItemIndex); + +#endif /* if GUI_WINSUPPORT */ +#endif /* SWIPELIST_PRIVATE_H */ diff --git a/example/GUI/STemWin/inc/TEXT.h b/example/GUI/STemWin/inc/TEXT.h new file mode 100755 index 0000000000..b03b3aac1d --- /dev/null +++ b/example/GUI/STemWin/inc/TEXT.h @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : TEXT.h +Purpose : TEXT include +--------------------END-OF-HEADER------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef TEXT_H +#define TEXT_H + +#include "WM.h" +#include "DIALOG_Intern.h" /* Req. for Create indirect data structure */ +#include "WIDGET.h" +#include "GUI_Debug.h" + +#if GUI_WINSUPPORT + +#if defined(__cplusplus) + extern "C" { /* Make sure we have C-declarations in C++ programs */ +#endif + +/************************************************************ +* +* #defines +* +************************************************************* +*/ + +/************************************************************ +* +* Create / Status flags +*/ +#define TEXT_CF_LEFT GUI_TA_LEFT +#define TEXT_CF_RIGHT GUI_TA_RIGHT +#define TEXT_CF_HCENTER GUI_TA_HCENTER + +#define TEXT_CF_VCENTER GUI_TA_VCENTER +#define TEXT_CF_TOP GUI_TA_TOP +#define TEXT_CF_BOTTOM GUI_TA_BOTTOM + + +/********************************************************************* +* +* Public Types +* +********************************************************************** + +*/ +typedef WM_HMEM TEXT_Handle; + +/********************************************************************* +* +* Create functions +* +********************************************************************** +*/ +TEXT_Handle TEXT_Create (int x0, int y0, int xSize, int ySize, int Id, int Flags, const char * s, int Align); +TEXT_Handle TEXT_CreateAsChild (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int Id, int Flags, const char * s, int Align); +TEXT_Handle TEXT_CreateEx (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int WinFlags, int ExFlags, int Id, const char * pText); +TEXT_Handle TEXT_CreateUser (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int WinFlags, int ExFlags, int Id, const char * pText, int NumExtraBytes); +TEXT_Handle TEXT_CreateIndirect(const GUI_WIDGET_CREATE_INFO * pCreateInfo, WM_HWIN hWinParent, int x0, int y0, WM_CALLBACK * cb); + +/********************************************************************* +* +* The callback ... +* +* Do not call it directly ! It is only to be used from within an +* overwritten callback. +*/ +void TEXT_Callback(WM_MESSAGE * pMsg); + +/********************************************************************* +* +* Member functions +* +********************************************************************** +*/ + +/* Methods changing properties */ + +GUI_COLOR TEXT_GetBkColor (TEXT_Handle hObj); +const GUI_FONT * TEXT_GetFont (TEXT_Handle hObj); +int TEXT_GetNumLines (TEXT_Handle hObj); +int TEXT_GetText (TEXT_Handle hObj, char * pDest, U32 BufferSize); +int TEXT_GetTextAlign(TEXT_Handle hObj); +GUI_COLOR TEXT_GetTextColor(TEXT_Handle hObj); +int TEXT_GetUserData (TEXT_Handle hObj, void * pDest, int NumBytes); +GUI_WRAPMODE TEXT_GetWrapMode (TEXT_Handle hObj); +void TEXT_SetBkColor (TEXT_Handle hObj, GUI_COLOR Color); +void TEXT_SetFont (TEXT_Handle hObj, const GUI_FONT * pFont); +int TEXT_SetText (TEXT_Handle hObj, const char * s); +void TEXT_SetTextAlign(TEXT_Handle hObj, int Align); +void TEXT_SetTextColor(TEXT_Handle hObj, GUI_COLOR Color); +int TEXT_SetUserData (TEXT_Handle hObj, const void * pSrc, int NumBytes); +void TEXT_SetWrapMode (TEXT_Handle hObj, GUI_WRAPMODE WrapMode); + +/********************************************************************* +* +* Managing default values +* +********************************************************************** +*/ + +const GUI_FONT * TEXT_GetDefaultFont (void); +GUI_COLOR TEXT_GetDefaultTextColor(void); +GUI_WRAPMODE TEXT_GetDefaultWrapMode (void); +void TEXT_SetDefaultFont (const GUI_FONT * pFont); +void TEXT_SetDefaultTextColor(GUI_COLOR Color); +GUI_WRAPMODE TEXT_SetDefaultWrapMode (GUI_WRAPMODE WrapMode); + +#if defined(__cplusplus) + } +#endif + +#endif // GUI_WINSUPPORT +#endif // TEXT_H + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/TEXT_Private.h b/example/GUI/STemWin/inc/TEXT_Private.h new file mode 100755 index 0000000000..ea7bb1f79e --- /dev/null +++ b/example/GUI/STemWin/inc/TEXT_Private.h @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : TEXT.h +Purpose : TEXT include +--------------------END-OF-HEADER------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef TEXT_PRIVATE_H +#define TEXT_PRIVATE_H + +#include "TEXT.h" +#include "GUI_Private.h" + +#if GUI_WINSUPPORT + +/********************************************************************* +* +* Object definition +* +********************************************************************** +*/ +typedef struct { + const GUI_FONT * pFont; + GUI_COLOR TextColor; + GUI_COLOR BkColor; + GUI_WRAPMODE WrapMode; +} TEXT_PROPS; + +typedef struct { + WIDGET Widget; + TEXT_PROPS Props; + WM_HMEM hpText; + I16 Align; +} TEXT_OBJ; + +/********************************************************************* +* +* Macros for internal use +* +********************************************************************** +*/ +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL + #define TEXT_INIT_ID(p) p->Widget.DebugId = TEXT_ID +#else + #define TEXT_INIT_ID(p) +#endif + +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL + TEXT_OBJ * TEXT_LockH(TEXT_Handle h); + #define TEXT_LOCK_H(h) TEXT_LockH(h) +#else + #define TEXT_LOCK_H(h) (TEXT_OBJ *)GUI_LOCK_H(h) +#endif + +/********************************************************************* +* +* Module internal data +* +********************************************************************** +*/ +extern TEXT_PROPS TEXT__DefaultProps; + +#endif /* if GUI_WINSUPPORT */ +#endif /* TEXT_PRIVATE_H */ + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/TREEVIEW.h b/example/GUI/STemWin/inc/TREEVIEW.h new file mode 100755 index 0000000000..4e7fa4115c --- /dev/null +++ b/example/GUI/STemWin/inc/TREEVIEW.h @@ -0,0 +1,253 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : TREEVIEW.h +Purpose : TREEVIEW include +--------------------END-OF-HEADER------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef TREEVIEW_H +#define TREEVIEW_H + +#include "WM.h" +#include "DIALOG_Intern.h" /* Req. for Create indirect data structure */ +#include "WIDGET.h" + +#if GUI_WINSUPPORT + +#if defined(__cplusplus) + extern "C" { /* Make sure we have C-declarations in C++ programs */ +#endif + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ +/* Status- and create flags */ +#define TREEVIEW_CF_HIDELINES (1 << 0) +#define TREEVIEW_CF_ROWSELECT (1 << 1) +#define TREEVIEW_CF_AUTOSCROLLBAR_H (1 << 2) +#define TREEVIEW_CF_AUTOSCROLLBAR_V (1 << 3) +#define TREEVIEW_SF_HIDELINES TREEVIEW_CF_HIDELINES +#define TREEVIEW_SF_ROWSELECT TREEVIEW_CF_ROWSELECT +#define TREEVIEW_SF_AUTOSCROLLBAR_H TREEVIEW_CF_AUTOSCROLLBAR_H +#define TREEVIEW_SF_AUTOSCROLLBAR_V TREEVIEW_CF_AUTOSCROLLBAR_V + +/* Bitmap indices */ +#define TREEVIEW_BI_CLOSED 0 +#define TREEVIEW_BI_OPEN 1 +#define TREEVIEW_BI_LEAF 2 +#define TREEVIEW_BI_PLUS 3 +#define TREEVIEW_BI_MINUS 4 +#define TREEVIEW_BI_PM 5 + +/* Color indices */ +#define TREEVIEW_CI_UNSEL 0 +#define TREEVIEW_CI_SEL 1 +#define TREEVIEW_CI_DISABLED 2 + +/* Relative positions (create) */ +#define TREEVIEW_INSERT_ABOVE 0 +#define TREEVIEW_INSERT_BELOW 1 +#define TREEVIEW_INSERT_FIRST_CHILD 2 + +/* Relative positions (retrieve) */ +#define TREEVIEW_GET_FIRST 0 +#define TREEVIEW_GET_LAST 1 +#define TREEVIEW_GET_NEXT_SIBLING 2 +#define TREEVIEW_GET_PREV_SIBLING 3 +#define TREEVIEW_GET_FIRST_CHILD 4 +#define TREEVIEW_GET_PARENT 5 + +/* Item flags */ +#define TREEVIEW_ITEM_TYPE_LEAF (0 << 0) +#define TREEVIEW_ITEM_TYPE_NODE (1 << 0) + +/* Selection mode */ +#define TREEVIEW_SELMODE_ROW 1 +#define TREEVIEW_SELMODE_TEXT 0 + +/************************************************************ +* +* Types +* +************************************************************* +*/ +typedef WM_HMEM TREEVIEW_Handle; +typedef WM_HMEM TREEVIEW_ITEM_Handle; + +typedef struct { + int IsNode; + int IsExpanded; + int HasLines; + int HasRowSelect; + int Level; +} TREEVIEW_ITEM_INFO; + +typedef struct { + GUI_COLOR ColorBk; + GUI_COLOR ColorText; + GUI_COLOR ColorTextBk; + GUI_COLOR ColorLines; + GUI_RECT rText; + TREEVIEW_ITEM_Handle hItem; + const GUI_FONT * pFont; + char * pText; + U8 NumLines; + I16 ax0[3]; + I16 ay0[3]; + I16 ax1[3]; + I16 ay1[3]; + U8 NumConnectors; + I16 axc[16]; + const GUI_BITMAP * pBmPM; + const GUI_BITMAP * pBmOCL; + I16 xPosPM, xPosOCL; + U8 IndexPM; + U8 IndexOCL; +} TREEVIEW_ITEM_DRAW_INFO; + +/********************************************************************* +* +* Create functions +* +********************************************************************** +*/ +TREEVIEW_Handle TREEVIEW_CreateEx (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int WinFlags, int ExFlags, int Id); +TREEVIEW_Handle TREEVIEW_CreateUser (int x0, int y0, int xSize, int ySize, WM_HWIN hParent, int WinFlags, int ExFlags, int Id, int NumExtraBytes); +TREEVIEW_Handle TREEVIEW_CreateIndirect(const GUI_WIDGET_CREATE_INFO * pCreateInfo, WM_HWIN hWinParent, int x0, int y0, WM_CALLBACK * cb); + +/********************************************************************* +* +* The callback ... +* +* Do not call it directly ! It is only to be used from within an +* overwritten callback. +*/ +void TREEVIEW_Callback(WM_MESSAGE * pMsg); + +/********************************************************************* +* +* Common functions +* +********************************************************************** +*/ +int TREEVIEW_AttachItem (TREEVIEW_Handle hObj, TREEVIEW_ITEM_Handle hItem, TREEVIEW_ITEM_Handle hItemAt, int Position); +void TREEVIEW_DecSel (TREEVIEW_Handle hObj); +TREEVIEW_ITEM_Handle TREEVIEW_GetItem (TREEVIEW_Handle hObj, TREEVIEW_ITEM_Handle hItem, int Flags); +TREEVIEW_ITEM_Handle TREEVIEW_GetSel (TREEVIEW_Handle hObj); +int TREEVIEW_GetUserData (TREEVIEW_Handle hObj, void * pDest, int NumBytes); +void TREEVIEW_IncSel (TREEVIEW_Handle hObj); +TREEVIEW_ITEM_Handle TREEVIEW_InsertItem (TREEVIEW_Handle hObj, int IsNode, TREEVIEW_ITEM_Handle hItemPrev, int Position, const char * s); +int TREEVIEW_OwnerDraw (const WIDGET_ITEM_DRAW_INFO * pDrawItemInfo); +void TREEVIEW_ScrollToSel (TREEVIEW_Handle hObj); +void TREEVIEW_SetAutoScrollH (TREEVIEW_Handle hObj, int State); +void TREEVIEW_SetAutoScrollV (TREEVIEW_Handle hObj, int State); +void TREEVIEW_SetBitmapOffset(TREEVIEW_Handle hObj, int Index, int xOff, int yOff); +void TREEVIEW_SetBkColor (TREEVIEW_Handle hObj, int Index, GUI_COLOR Color); +void TREEVIEW_SetFont (TREEVIEW_Handle hObj, const GUI_FONT * pFont); +void TREEVIEW_SetHasLines (TREEVIEW_Handle hObj, int State); +void TREEVIEW_SetImage (TREEVIEW_Handle hObj, int Index, const GUI_BITMAP * pBitmap); +int TREEVIEW_SetIndent (TREEVIEW_Handle hObj, int Indent); +void TREEVIEW_SetLineColor (TREEVIEW_Handle hObj, int Index, GUI_COLOR Color); +void TREEVIEW_SetOwnerDraw (TREEVIEW_Handle hObj, WIDGET_DRAW_ITEM_FUNC * pfDrawItem); +void TREEVIEW_SetSel (TREEVIEW_Handle hObj, TREEVIEW_ITEM_Handle hItem); +void TREEVIEW_SetSelMode (TREEVIEW_Handle hObj, int Mode); +void TREEVIEW_SetTextColor (TREEVIEW_Handle hObj, int Index, GUI_COLOR Color); +int TREEVIEW_SetTextIndent (TREEVIEW_Handle hObj, int TextIndent); +int TREEVIEW_SetUserData (TREEVIEW_Handle hObj, const void * pSrc, int NumBytes); + + +/********************************************************************* +* +* Treeview item related functions +* +********************************************************************** +*/ +void TREEVIEW_ITEM_Collapse (TREEVIEW_ITEM_Handle hItem); +void TREEVIEW_ITEM_CollapseAll(TREEVIEW_ITEM_Handle hItem); +TREEVIEW_ITEM_Handle TREEVIEW_ITEM_Create (int IsNode, const char * s, U32 UserData); +void TREEVIEW_ITEM_Delete (TREEVIEW_ITEM_Handle hItem); +void TREEVIEW_ITEM_Detach (TREEVIEW_ITEM_Handle hItem); +void TREEVIEW_ITEM_Expand (TREEVIEW_ITEM_Handle hItem); +void TREEVIEW_ITEM_ExpandAll (TREEVIEW_ITEM_Handle hItem); +void TREEVIEW_ITEM_GetInfo (TREEVIEW_ITEM_Handle hItem, TREEVIEW_ITEM_INFO * pInfo); +void TREEVIEW_ITEM_GetText (TREEVIEW_ITEM_Handle hItem, U8 * pBuffer, int MaxNumBytes); +U32 TREEVIEW_ITEM_GetUserData(TREEVIEW_ITEM_Handle hItem); +void TREEVIEW_ITEM_SetImage (TREEVIEW_ITEM_Handle hItem, int Index, const GUI_BITMAP * pBitmap); +TREEVIEW_ITEM_Handle TREEVIEW_ITEM_SetText (TREEVIEW_ITEM_Handle hItem, const char * s); +void TREEVIEW_ITEM_SetUserData(TREEVIEW_ITEM_Handle hItem, U32 UserData); + +/********************************************************************* +* +* Managing default values +* +********************************************************************** +*/ +GUI_COLOR TREEVIEW_GetDefaultBkColor (int Index); +const GUI_FONT * TREEVIEW_GetDefaultFont (void); +GUI_COLOR TREEVIEW_GetDefaultLineColor(int Index); +GUI_COLOR TREEVIEW_GetDefaultTextColor(int Index); +void TREEVIEW_SetDefaultBkColor (int Index, GUI_COLOR Color); +void TREEVIEW_SetDefaultFont (const GUI_FONT * pFont); +void TREEVIEW_SetDefaultLineColor(int Index, GUI_COLOR Color); +void TREEVIEW_SetDefaultTextColor(int Index, GUI_COLOR Color); + +#if defined(__cplusplus) + } +#endif + +#endif // GUI_WINSUPPORT +#endif // TREEVIEW_H + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/TREEVIEW_Private.h b/example/GUI/STemWin/inc/TREEVIEW_Private.h new file mode 100755 index 0000000000..e383ac06cc --- /dev/null +++ b/example/GUI/STemWin/inc/TREEVIEW_Private.h @@ -0,0 +1,171 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : TREEVIEW_Private.h +Purpose : TREEVIEW private header file +--------------------END-OF-HEADER------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef TREEVIEW_PRIVATE_H +#define TREEVIEW_PRIVATE_H + +#include "WM.h" +#include "TREEVIEW.h" + +#if GUI_WINSUPPORT + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ +#define TREEVIEW_ITEM_STATE_EXPANDED (1 << 1) +#define TREEVIEW_ITEM_STATE_ISLAST (1 << 2) + +#define TREEVIEW_STATE_HASLINES (1 << 0) + +#define TREEVIEW_COLORS_BK 0 +#define TREEVIEW_COLORS_TEXT 1 +#define TREEVIEW_COLORS_LINE 2 + +/********************************************************************* +* +* Types +* +********************************************************************** +*/ +typedef struct { + const GUI_BITMAP * apBm[3]; /* Closed, Open, Leaf */ +} TREEVIEW_ITEM_DATA; + +typedef struct { + WM_HMEM hParent; /* Handle to treeview object */ + TREEVIEW_ITEM_Handle hNext; + TREEVIEW_ITEM_Handle hPrev; + U32 UserData; + WM_HMEM hData; /* Handle of TREEVIEW_ITEM_DATA structure */ + U16 xSize; + U16 ySize; + U16 Flags; + U16 Connectors; + U8 Level; /* 0...15 */ + char acText[1]; +} TREEVIEW_ITEM_OBJ; + +typedef struct { + const GUI_FONT * pFont; + GUI_COLOR aBkColor[3]; + GUI_COLOR aTextColor[3]; + GUI_COLOR aLineColor[3]; + GUI_COLOR FocusColor; + const GUI_BITMAP * apBm[5]; /* Closed, Open, Leaf, Plus, Minus */ + int Indent; + int TextIndent; + int MinItemHeight; +} TREEVIEW_PROPS; + +typedef struct { + WIDGET Widget; + WIDGET_DRAW_ITEM_FUNC * pfDrawItem; + WM_SCROLL_STATE ScrollStateV; + WM_SCROLL_STATE ScrollStateH; + TREEVIEW_PROPS Props; + U16 Flags; + TREEVIEW_ITEM_Handle hFirst; + TREEVIEW_ITEM_Handle hLast; + TREEVIEW_ITEM_Handle hSel; + GUI_TIMER_HANDLE hTimer; + /* Cache variables */ + int NumItems; + int NumVisItems; + int xSizeItems; /* xSize in pixel used for all visible items */ + int ySizeItems; /* ySize in pixel used for all visible items */ + I16 xOffPM, yOffPM; /* x/y offset of PM bitmap */ + U16 xOverlapHLine; +} TREEVIEW_OBJ; + +/********************************************************************* +* +* Macros for internal use +* +********************************************************************** +*/ +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL + #define TREEVIEW_INIT_ID(p) p->Widget.DebugId = TREEVIEW_ID +#else + #define TREEVIEW_INIT_ID(p) +#endif + +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_CHECK_ALL + TREEVIEW_OBJ * TREEVIEW_LockH(TREEVIEW_Handle h); + #define TREEVIEW_LOCK_H(h) TREEVIEW_LockH(h) +#else + #define TREEVIEW_LOCK_H(h) (TREEVIEW_OBJ *)GUI_LOCK_H(h) +#endif + +/********************************************************************* +* +* Module internal data +* +********************************************************************** +*/ +extern TREEVIEW_PROPS TREEVIEW__DefaultProps; +extern GUI_CONST_STORAGE GUI_BITMAP TREEVIEW__bmOpen; +extern GUI_CONST_STORAGE GUI_BITMAP TREEVIEW__bmClosed; +extern GUI_CONST_STORAGE GUI_BITMAP TREEVIEW__bmLeaf; +extern GUI_CONST_STORAGE GUI_BITMAP TREEVIEW__bmPlus; +extern GUI_CONST_STORAGE GUI_BITMAP TREEVIEW__bmMinus; + +#endif /* GUI_WINSUPPORT */ +#endif /* TREEVIEW_H */ + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/WIDGET.h b/example/GUI/STemWin/inc/WIDGET.h new file mode 100755 index 0000000000..9f3b0084f2 --- /dev/null +++ b/example/GUI/STemWin/inc/WIDGET.h @@ -0,0 +1,413 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : WIDGET.h +Purpose : Widget interface +---------------------------END-OF-HEADER------------------------------ +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef WIDGET_H /* Avoid multiple inclusion */ +#define WIDGET_H + +#if defined(__cplusplus) +extern "C" { /* Make sure we have C-declarations in C++ programs */ +#endif + +#include "WM_Intern.h" /* Window manager, including some internals, which speed things up */ + +#if GUI_WINSUPPORT + +/********************************************************************* +* +* Typedefs +* +********************************************************************** +*/ +typedef struct { + WM_HWIN hWin; + int Cmd; /* WIDGET_ITEM_GET_XSIZE, WIDGET_ITEM_GET_YSIZE, WIDGET_ITEM_DRAW, */ + int ItemIndex; + int Col; + int x0, y0, x1, y1; + void * p; +} WIDGET_ITEM_DRAW_INFO; + +typedef int WIDGET_DRAW_ITEM_FUNC(const WIDGET_ITEM_DRAW_INFO * pDrawItemInfo); +typedef void WIDGET_PAINT (WM_HWIN hObj); +typedef void WIDGET_CREATE (WM_HWIN hObj); + +typedef struct { + WIDGET_PAINT * pfPaint; + WIDGET_CREATE * pfCreate; + void * pSkinPrivate; +} WIDGET_SKIN; + +/********************************************************************* +* +* Important: WIDGET_DRAW_ITEM_FUNC needs to be defined +* in SCROLLBAR.h! +* +********************************************************************** +*/ +#include "SCROLLBAR.h" + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ +/********************************************************************* +* +* Unique widget id's +*/ +#define BUTTON_ID 0x42555454UL /* BUTT */ +#define CHECKBOX_ID 0x43484543UL /* CHEC */ +#define DROPDOWN_ID 0x44524f50UL /* DROP */ +#define EDIT_ID 0x45444954UL /* EDIT */ +#define FRAMEWIN_ID 0x4652414dUL /* FRAM */ +#define FRAMECLNT_ID 0x46524143UL /* FRAC */ +#define GRAPH_ID 0x47524150UL /* GRAP */ +#define HEADER_ID 0x48454144UL /* HEAD */ +#define LISTBOX_ID 0x4C495342UL /* LISB */ +#define LISTVIEW_ID 0x4C495356UL /* LISV */ +#define LISTWHEEL_ID 0x4C495357UL /* LISW */ +#define MENU_ID 0x4d454e55UL /* MENU */ +#define MULTIEDIT_ID 0x4d554c45UL /* MULE */ +#define MULTIPAGE_ID 0x4d554c50UL /* MULP */ +#define MPAGECLNT_ID 0x4d50434CUL /* MPCL */ +#define PROGBAR_ID 0x50524f47UL /* PROG */ +#define RADIO_ID 0x52414449UL /* RADI */ +#define SCROLLBAR_ID 0x5343524fUL /* SCRO */ +#define SLIDER_ID 0x534c4944UL /* SLID */ +#define SWIPELIST_ID 0x53574950UL /* SWIP */ +#define TEXT_ID 0x54455854UL /* TEXT */ +#define TREEVIEW_ID 0x54524545UL /* TREE */ +#define ICONVIEW_ID 0x49434f4eUL /* ICON */ +#define IMAGE_ID 0x494d4147UL /* IMAG */ +#define SPINBOX_ID 0x5350494eUL /* SPIN */ +#define KNOB_ID 0x4b4e4f42UL /* KNOB */ +#define WINDOW_ID 0x57494e44UL /* WIND */ + +#define WIDGET_LOCK(hWin) ((WIDGET*)GUI_LOCK_H(hWin)) + +/********************************************************************* +* +* Config switches +*/ + +#ifndef WIDGET_USE_PARENT_EFFECT + #define WIDGET_USE_PARENT_EFFECT 0 +#endif +#ifndef WIDGET_USE_FLEX_SKIN + #define WIDGET_USE_FLEX_SKIN 1 +#endif +#if !defined(WIDGET_USE_SCHEME_SMALL) && !defined(WIDGET_USE_SCHEME_MEDIUM) && !defined(WIDGET_USE_SCHEME_LARGE) + #define WIDGET_USE_SCHEME_SMALL 1 + #define WIDGET_USE_SCHEME_MEDIUM 0 + #define WIDGET_USE_SCHEME_LARGE 0 +#endif +#ifndef WIDGET_USE_SCHEME_SMALL + #define WIDGET_USE_SCHEME_SMALL 0 +#endif +#ifndef WIDGET_USE_SCHEME_MEDIUM + #define WIDGET_USE_SCHEME_MEDIUM 0 +#endif +#ifndef WIDGET_USE_SCHEME_LARGE + #define WIDGET_USE_SCHEME_LARGE 0 +#endif +#if (WIDGET_USE_SCHEME_SMALL + WIDGET_USE_SCHEME_MEDIUM + WIDGET_USE_SCHEME_LARGE) > 1 + #error Only one scheme can be selected! +#endif + +/********************************************************************* +* +* States +*/ + +#define WIDGET_STATE_FOCUS (1 << 0) +#define WIDGET_STATE_VERTICAL (1 << 3) +#define WIDGET_STATE_FOCUSABLE (1 << 4) + +#define WIDGET_STATE_USER0 (1 << 8) /* Freely available for derived widget */ +#define WIDGET_STATE_USER1 (1 << 9) /* Freely available for derived widget */ +#define WIDGET_STATE_USER2 (1 << 10) /* Freely available for derived widget */ + +#define WIDGET_STATE_FOCUSSABLE WIDGET_STATE_FOCUSABLE + +/********************************************************************* +* +* Skinning message identifiers +*/ +#define WIDGET_ITEM_CREATE 0 +#define WIDGET_ITEM_DRAW 1 +#define WIDGET_ITEM_DRAW_ARROW 2 +#define WIDGET_ITEM_DRAW_ARROW_L 3 +#define WIDGET_ITEM_DRAW_ARROW_R 4 +#define WIDGET_ITEM_DRAW_BACKGROUND 5 +#define WIDGET_ITEM_DRAW_BITMAP 6 +#define WIDGET_ITEM_DRAW_BUTTON 7 +#define WIDGET_ITEM_DRAW_BUTTON_L 8 +#define WIDGET_ITEM_DRAW_BUTTON_R 9 +#define WIDGET_ITEM_DRAW_FOCUS 10 +#define WIDGET_ITEM_DRAW_FRAME 11 +#define WIDGET_ITEM_DRAW_OVERLAP 12 +#define WIDGET_ITEM_DRAW_OVERLAY 13 +#define WIDGET_ITEM_DRAW_SEP 14 +#define WIDGET_ITEM_DRAW_SHAFT 15 +#define WIDGET_ITEM_DRAW_SHAFT_L 16 +#define WIDGET_ITEM_DRAW_SHAFT_R 17 +#define WIDGET_ITEM_DRAW_TEXT 18 +#define WIDGET_ITEM_DRAW_THUMB 19 +#define WIDGET_ITEM_DRAW_TICKS 20 +#define WIDGET_ITEM_GET_BORDERSIZE_B 21 +#define WIDGET_ITEM_GET_BORDERSIZE_L 22 +#define WIDGET_ITEM_GET_BORDERSIZE_R 23 +#define WIDGET_ITEM_GET_BORDERSIZE_T 24 +#define WIDGET_ITEM_GET_BUTTONSIZE 25 +#define WIDGET_ITEM_GET_XSIZE 26 +#define WIDGET_ITEM_GET_YSIZE 27 +#define WIDGET_ITEM_GET_RADIUS 28 +#define WIDGET_ITEM_APPLY_PROPS 29 // Not to be documented. Use this message identifier to update the + // properties of attached widgets from _DrawSkinFlex(). +#define WIDGET_DRAW_BACKGROUND 30 + +#define WIDGET_DRAW_OVERLAY WIDGET_ITEM_DRAW_OVERLAY + +/********************************************************************* +* +* Messages +*/ + +#define WM_WIDGET_SET_EFFECT (WM_WIDGET + 0) + +/********************************************************************* +* +* Create flags +*/ + +#define WIDGET_CF_VERTICAL WIDGET_STATE_VERTICAL + +/********************************************************************* +* +* Widget object +* +* The widget object is the base class for most widgets +*/ +typedef struct { + int EffectSize; + void (* pfDrawUp) (void); + void (* pfDrawUpRect) (const GUI_RECT * pRect); + void (* pfDrawDown) (void); + void (* pfDrawDownRect)(const GUI_RECT * pRect); + void (* pfDrawFlat) (void); + void (* pfDrawFlatRect)(const GUI_RECT * pRect); +} WIDGET_EFFECT; + +typedef struct { + WM_Obj Win; + const WIDGET_EFFECT* pEffect; + I16 Id; + U16 State; + #if GUI_DEBUG_LEVEL > 1 + U32 DebugId; + #endif +} WIDGET; + + +/********************************************************************* +* +* GUI_DRAW +* +* The GUI_DRAW object is used as base class for selfdrawing, +* non-windows objects. They are used as content of different widgets, +* such as the bitmap or header widgets. +*/ +/* Declare Object struct */ +typedef struct GUI_DRAW GUI_DRAW; +typedef void GUI_DRAW_SELF_CB (WM_HWIN hWin); +typedef WM_HMEM GUI_DRAW_HANDLE; + +/* Declare Object constants (member functions etc) */ +typedef struct { + void (* pfDraw) (GUI_DRAW_HANDLE hDrawObj, WM_HWIN hObj, int x, int y); + int (* pfGetXSize)(GUI_DRAW_HANDLE hDrawObj); + int (* pfGetYSize)(GUI_DRAW_HANDLE hDrawObj); +} GUI_DRAW_CONSTS; + +/* Declare Object */ +struct GUI_DRAW { + const GUI_DRAW_CONSTS* pConsts; + union { + const void * pData; + GUI_DRAW_SELF_CB* pfDraw; + } Data; + I16 xOff, yOff; +}; + +/* GUI_DRAW_ API */ +void GUI_DRAW__Draw (GUI_DRAW_HANDLE hDrawObj, WM_HWIN hObj, int x, int y); +int GUI_DRAW__GetXSize(GUI_DRAW_HANDLE hDrawObj); +int GUI_DRAW__GetYSize(GUI_DRAW_HANDLE hDrawObj); + +void GUI_DrawStreamedEnableAuto(void); + +/* GUI_DRAW_ Constructurs for different objects */ +WM_HMEM GUI_DRAW_BITMAP_Create (const GUI_BITMAP* pBitmap, int x, int y); +WM_HMEM GUI_DRAW_BMP_Create (const void* pBMP, int x, int y); +WM_HMEM GUI_DRAW_STREAMED_Create(const GUI_BITMAP_STREAM * pBitmap, int x, int y); +WM_HMEM GUI_DRAW_SELF_Create(GUI_DRAW_SELF_CB* pfDraw, int x, int y); + +/********************************************************************* +* +* Global data +* +********************************************************************** +*/ + +extern const WIDGET_EFFECT WIDGET_Effect_3D; +extern const WIDGET_EFFECT WIDGET_Effect_3D1L; +extern const WIDGET_EFFECT WIDGET_Effect_3D2L; +extern const WIDGET_EFFECT WIDGET_Effect_None; +extern const WIDGET_EFFECT WIDGET_Effect_Simple; + +/********************************************************************* +* +* Internal API routines +* +********************************************************************** +*/ + +void WIDGET__DrawFocusRect (WIDGET * pWidget, const GUI_RECT * pRect, int Dist); +void WIDGET__DrawHLine (WIDGET * pWidget, int y, int x0, int x1); +void WIDGET__DrawTriangle (WIDGET * pWidget, int x, int y, int Size, int Inc); +void WIDGET__DrawVLine (WIDGET * pWidget, int x, int y0, int y1); +void WIDGET__EFFECT_DrawDownRect(WIDGET * pWidget, GUI_RECT * pRect); +void WIDGET__EFFECT_DrawDown (WIDGET * pWidget); +void WIDGET__EFFECT_DrawUpRect (WIDGET * pWidget, GUI_RECT * pRect); +void WIDGET__FillRectEx (WIDGET * pWidget, const GUI_RECT * pRect); +int WIDGET__GetWindowSizeX (WM_HWIN hWin); +GUI_COLOR WIDGET__GetBkColor (WM_HWIN hObj); +int WIDGET__GetXSize (const WIDGET * pWidget); +int WIDGET__GetYSize (const WIDGET * pWidget); +void WIDGET__GetClientRect (WIDGET * pWidget, GUI_RECT * pRect); +void WIDGET__GetInsideRect (WIDGET * pWidget, GUI_RECT * pRect); +void WIDGET__Init (WIDGET * pWidget, int Id, U16 State); +void WIDGET__RotateRect90 (WIDGET * pWidget, GUI_RECT * pDest, const GUI_RECT * pRect); +void WIDGET__SetScrollState (WM_HWIN hWin, const WM_SCROLL_STATE * pVState, const WM_SCROLL_STATE * pState); +void WIDGET__FillStringInRect (const char * pText, const GUI_RECT * pFillRect, const GUI_RECT * pTextRectMax, const GUI_RECT * pTextRectAct); + +// +// Function pointers for drawing streamed bitmaps +// +extern void (* GUI__pfDrawStreamedBitmap) (const void * p, int x, int y); +extern int (* GUI__pfDrawStreamedBitmapEx)(GUI_GET_DATA_FUNC * pfGetData, const void * p, int x, int y); + +/********************************************************************* +* +* API routines +* +********************************************************************** +*/ +void WIDGET_SetState (WM_HWIN hObj, int State); +void WIDGET_AndState (WM_HWIN hObj, int State); +void WIDGET_OrState (WM_HWIN hObj, int State); +int WIDGET_HandleActive (WM_HWIN hObj, WM_MESSAGE* pMsg); +int WIDGET_GetState (WM_HWIN hObj); +int WIDGET_SetWidth (WM_HWIN hObj, int Width); +void WIDGET_SetFocusable (WM_HWIN hObj, int State); + +void WIDGET_EFFECT_3D_DrawUp(void); + +const WIDGET_EFFECT* WIDGET_SetDefaultEffect(const WIDGET_EFFECT* pEffect); + +void WIDGET_SetEffect (WM_HWIN hObj, const WIDGET_EFFECT* pEffect); + +const WIDGET_EFFECT* WIDGET_GetDefaultEffect(void); + +void WIDGET_EFFECT_3D_SetColor (unsigned Index, GUI_COLOR Color); +void WIDGET_EFFECT_3D1L_SetColor (unsigned Index, GUI_COLOR Color); +void WIDGET_EFFECT_3D2L_SetColor (unsigned Index, GUI_COLOR Color); +void WIDGET_EFFECT_Simple_SetColor(unsigned Index, GUI_COLOR Color); + +GUI_COLOR WIDGET_EFFECT_3D_GetColor (unsigned Index); +GUI_COLOR WIDGET_EFFECT_3D1L_GetColor (unsigned Index); +GUI_COLOR WIDGET_EFFECT_3D2L_GetColor (unsigned Index); +GUI_COLOR WIDGET_EFFECT_Simple_GetColor(unsigned Index); + +int WIDGET_EFFECT_3D_GetNumColors(void); +int WIDGET_EFFECT_3D1L_GetNumColors(void); +int WIDGET_EFFECT_3D2L_GetNumColors(void); +int WIDGET_EFFECT_Simple_GetNumColors(void); + +/********************************************************************* +* +* Compatibility macros +* +********************************************************************** +*/ +#define WIDGET_EnableStreamAuto() GUI_DrawStreamedEnableAuto() + +#define WIDGET_SetDefaultEffect_3D() WIDGET_SetDefaultEffect(&WIDGET_Effect_3D) +#define WIDGET_SetDefaultEffect_3D1L() WIDGET_SetDefaultEffect(&WIDGET_Effect_3D1L) +#define WIDGET_SetDefaultEffect_3D2L() WIDGET_SetDefaultEffect(&WIDGET_Effect_3D2L) +#define WIDGET_SetDefaultEffect_None() WIDGET_SetDefaultEffect(&WIDGET_Effect_None) +#define WIDGET_SetDefaultEffect_Simple() WIDGET_SetDefaultEffect(&WIDGET_Effect_Simple) + +#endif /* GUI_WINSUPPORT */ + +#if defined(__cplusplus) + } +#endif + +#endif /* SLIDER_H */ + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/WINDOW_Private.h b/example/GUI/STemWin/inc/WINDOW_Private.h new file mode 100755 index 0000000000..e325da7b7e --- /dev/null +++ b/example/GUI/STemWin/inc/WINDOW_Private.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : WINDOW_Private.h +Purpose : WINDOW private header file +--------------------END-OF-HEADER------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef WINDOW_PRIVATE_H +#define WINDOW_PRIVATE_H + +#include "WM.h" + +#if GUI_WINSUPPORT + +/********************************************************************* +* +* Externals +* +********************************************************************** +*/ + +extern GUI_COLOR WINDOW__DefaultBkColor; + +#endif /* GUI_WINSUPPORT */ +#endif /* WINDOW_PRIVATE_H */ + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/WM.h b/example/GUI/STemWin/inc/WM.h new file mode 100755 index 0000000000..50328dc213 --- /dev/null +++ b/example/GUI/STemWin/inc/WM.h @@ -0,0 +1,797 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : WM.h +Purpose : Windows manager include +---------------------------------------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef WM_H /* Make sure we only include it once */ +#define WM_H + + +#include "GUI_ConfDefaults.h" +#include "GUI_Type.h" /* Needed because of typedefs only */ +#include "WM_GUI.h" /* Some functions needed by GUI routines */ +#include "GUI.h" + +#if defined(__cplusplus) +extern "C" { /* Make sure we have C-declarations in C++ programs */ +#endif + +/* Static memory devices */ +#ifndef WM_SUPPORT_STATIC_MEMDEV + #define WM_SUPPORT_STATIC_MEMDEV GUI_SUPPORT_MEMDEV +#endif + +/* Support for transparency. Switching it off makes Wm smaller and faster */ +#ifndef WM_SUPPORT_TRANSPARENCY + #define WM_SUPPORT_TRANSPARENCY 1 /* Should be defined outside of GUI_WINSUPPORT because of '#if GUI_WINSUPPORT && WM_SUPPORT_TRANSPARENCY' in some files */ +#endif + +/* This is for tests only. It will fill the invalid area of a window. + Can be used for debugging. */ +#ifndef WM_SUPPORT_DIAG + #ifdef WIN32 /* In simulation */ + #define WM_SUPPORT_DIAG GUI_WINSUPPORT + #else + #define WM_SUPPORT_DIAG 0 + #endif +#endif + +/* Make sure we actually have configured windows. If we have not, + there is no point for a windows manager and it will therefor not + generate any code ! +*/ + +#if GUI_WINSUPPORT + +/********************************************************************* +* +* Config defaults +*/ +#ifndef WM_ASSERT + #define WM_ASSERT(expr) GUI_DEBUG_ASSERT(expr) +#endif + +#ifndef WM_SUPPORT_TOUCH + #define WM_SUPPORT_TOUCH GUI_SUPPORT_TOUCH +#endif + +/* Allow older API calls */ +#ifndef WM_COMPATIBLE_MODE + #define WM_COMPATIBLE_MODE 1 +#endif + +/* Send a message if visibility of a window has changed */ +#ifndef WM_SUPPORT_NOTIFY_VIS_CHANGED + #define WM_SUPPORT_NOTIFY_VIS_CHANGED 0 +#endif + +#ifndef WM_SUPPORT_CPP + #if defined (_MSC_VER) + #define WM_SUPPORT_CPP 1 + #else + #define WM_SUPPORT_CPP 0 + #endif +#endif + +/********************************************************************* +* +* Locking macros +*/ +#define WM_LOCK() GUI_LOCK() +#define WM_UNLOCK() GUI_UNLOCK() + +#define WM_LOCK_H(hWin) (WM_Obj *)GUI_LOCK_H(hWin) + +/********************************************************************* +* +* Data types +*/ +typedef struct WM_WINDOW_INFO WM_WINDOW_INFO; + +struct WM_WINDOW_INFO { + GUI_HMEM hWin; + GUI_HMEM hParent; + GUI_HMEM hFirstChild; + GUI_HMEM hNext; + GUI_RECT Rect; + U32 Status; + U32 DebugId; + WM_WINDOW_INFO * pNext; +}; + +typedef struct { + int Key, PressedCnt; +} WM_KEY_INFO; + +typedef struct { + int NumItems, v, PageSize; +} WM_SCROLL_STATE; + +typedef struct { + int Done; + int ReturnValue; +} WM_DIALOG_STATUS; + +typedef struct { + int x,y; + U8 State; + U8 StatePrev; +} WM_PID_STATE_CHANGED_INFO; + +typedef struct { + U8 Cmd; + U8 FinalMove; + U8 StopMotion; + U8 IsDragging; + int dx, dy, da; + int xPos, yPos; + int Period; + int SnapX; + int SnapY; + U8 IsOutside; + unsigned Overlap; + U32 Flags; + GUI_PID_STATE * pState; + GUI_HMEM hContext; +} WM_MOTION_INFO; + +typedef struct { + I32 FactorMin; // Minimum factor to be used (<< 16) + I32 FactorMax; // Maximum factor to be used (<< 16) + U32 xSize; // Native xSize of window to be zoomed in pixels + U32 ySize; // Native ySize of window to be zoomed in pixels + U32 xSizeParent; // xSize of parent window + U32 ySizeParent; // ySize of parent window + I32 Factor0; // Primary factor when starting zoom gesture (<< 16) + int xPos0; // Primary window position in x when starting the gesture + int yPos0; // Primary window position in y when starting the gesture + GUI_POINT Center0; // Primary center point when starting the gesture +} WM_ZOOM_INFO; + +typedef struct { + int Flags; // Information regarding gesture type + GUI_POINT Point; // Relative movement + GUI_POINT Center; // Center point for zooming + I32 Angle; // Angle between the touch points + I32 Factor; // Current zoom factor + WM_ZOOM_INFO * pZoomInfo; // Pointer to WM_ZOOM_INFO structure +} WM_GESTURE_INFO; + +typedef struct { + int dx, dy; +} WM_MOVE_INFO; + +/********************************************************************* +* +* Gesture flags for multi touch support +*/ +#define WM_GF_BEGIN (1 << 0) +#define WM_GF_END (1 << 1) +#define WM_GF_PAN (1 << 2) +#define WM_GF_ZOOM (1 << 3) +#define WM_GF_ROTATE (1 << 4) +#define WM_GF_DTAP (1 << 5) + +/********************************************************************* +* +* Messages Ids +* +* The following is the list of windows messages. +*/ +#define WM_CREATE 0x0001 /* The first message received, right after client has actually been created */ +#define WM_MOVE 0x0003 /* window has been moved (Same as WIN32) */ + +#define WM_SIZE 0x0005 /* Is sent to a window after its size has changed (Same as WIN32, do not change !) */ + +#define WM_DELETE 11 /* Delete (Destroy) command: This tells the client to free its data strutures since the window + it is associates with no longer exists.*/ +#define WM_TOUCH 0x0240 /* Touch screen message */ +#define WM_TOUCH_CHILD 13 /* Touch screen message to ancestors */ +#define WM_KEY 14 /* Key has been pressed */ + +#define WM_PAINT 0x000F /* Repaint window (because content is (partially) invalid */ + +#if GUI_SUPPORT_MOUSE +#define WM_MOUSEOVER 16 /* Mouse has moved, no key pressed */ +#define WM_MOUSEOVER_END 18 /* Mouse has moved, no key pressed */ +#endif + +#define WM_PID_STATE_CHANGED 17 /* Pointer input device state has changed */ + +#define WM_GET_INSIDE_RECT 20 /* get inside rectangle: client rectangle minus pixels lost to effect */ +#define WM_GET_ID 21 /* Get id of widget */ +#define WM_SET_ID 22 /* Set id of widget */ +#define WM_GET_CLIENT_WINDOW 23 /* Get window handle of client window. Default is the same as window */ +#define WM_CAPTURE_RELEASED 24 /* Let window know that mouse capture is over */ + +#define WM_INIT_DIALOG 29 /* Inform dialog that it is ready for init */ + +#define WM_SET_FOCUS 30 /* Inform window that it has gotten or lost the focus */ +#define WM_GET_ACCEPT_FOCUS 31 /* Find out if window can accept the focus */ +#define WM_NOTIFY_CHILD_HAS_FOCUS 32 /* Sent to parent when child receives / loses focus */ + +#define WM_NOTIFY_OWNER_KEY 33 /* Some widgets (e.g. listbox) notify owner when receiving key messages */ + +#define WM_GET_BKCOLOR 34 /* Return back ground color (only frame window and similar) */ +#define WM_GET_SCROLL_STATE 35 /* Query state of scroll bar */ + +#define WM_SET_SCROLL_STATE 36 /* Set scroll info ... only effective for scrollbars */ + +#define WM_NOTIFY_CLIENTCHANGE 37 /* Client area may have changed */ +#define WM_NOTIFY_PARENT 38 /* Notify parent. Information is detailed as notification code */ +#define WM_NOTIFY_PARENT_REFLECTION 39 /* Notify parent reflection. + Sometimes send back as a result of the WM_NOTIFY_PARENT message + to let child react on behalf of its parent. + Information is detailed as notification code */ +#define WM_NOTIFY_ENABLE 40 /* Enable or disable widget */ +#define WM_NOTIFY_VIS_CHANGED 41 /* Visibility of a window has or may have changed */ + +#define WM_HANDLE_DIALOG_STATUS 42 /* Set or get dialog status */ +#define WM_GET_RADIOGROUP 43 /* Send to all siblings and children of a radio control when + selection changed */ +#define WM_MENU 44 /* Send to owner window of menu widget */ +#define WM_SCREENSIZE_CHANGED 45 /* Send to all windows when size of screen has changed */ +#define WM_PRE_PAINT 46 /* Send to a window before it receives a WM_PAINT message */ +#define WM_POST_PAINT 47 /* Send to a window after (the last) WM_PAINT message */ + +#define WM_MOTION 48 /* Automatic motion messages */ + +#define WM_GET_WINDOW_ID 49 /* Return widget type specific Id (DebugId) */ + +#define WM_PRE_BANDING 50 +#define WM_POST_BANDING 51 + +#define WM_GESTURE 0x0119 /* Gesture message */ + +#define WM_TIMER 0x0113 /* Timer has expired (Keep the same as WIN32) */ +#define WM_WIDGET 0x0300 /* 256 messages reserved for Widget messages */ +#define WM_USER 0x0400 /* Reserved for user messages ... (Keep the same as WIN32) */ + +/********************************************************************* +* +* Motion messages +*/ +#define WM_MOTION_INIT 0 +#define WM_MOTION_MOVE 1 +#define WM_MOTION_GETPOS 2 +#define WM_MOTION_GETCONTEXT 3 + +/********************************************************************* +* +* Motion flags +*/ +#define WM_MOTION_MANAGE_BY_WINDOW (1 << 0) // Window movement is managed by window itself + +/********************************************************************* +* +* Notification codes +* +* The following is the list of notification codes send +* with the WM_NOTIFY_PARENT message +*/ +#define WM_NOTIFICATION_CLICKED 1 +#define WM_NOTIFICATION_RELEASED 2 +#define WM_NOTIFICATION_MOVED_OUT 3 +#define WM_NOTIFICATION_SEL_CHANGED 4 +#define WM_NOTIFICATION_VALUE_CHANGED 5 +#define WM_NOTIFICATION_SCROLLBAR_ADDED 6 /* Scroller added */ +#define WM_NOTIFICATION_CHILD_DELETED 7 /* Inform window that child is about to be deleted */ +#define WM_NOTIFICATION_GOT_FOCUS 8 +#define WM_NOTIFICATION_LOST_FOCUS 9 +#define WM_NOTIFICATION_SCROLL_CHANGED 10 + +#define WM_NOTIFICATION_WIDGET 11 /* Space for widget defined notifications */ +#define WM_NOTIFICATION_USER 16 /* Space for application (user) defined notifications */ + +/********************************************************************* +* +* Memory management +*/ +#define WM_HWIN GUI_HWIN +#define WM_HWIN_NULL GUI_HMEM_NULL +#define WM_HMEM GUI_HMEM +#define WM_HMEM_NULL GUI_HMEM_NULL +#define WM_HTIMER GUI_HMEM + +/********************************************************************* +* +* Window defines +*/ +#define WM_HBKWIN WM_GetDesktopWindow() /* Handle of background window */ +#define WM_UNATTACHED ((WM_HMEM) - 1) /* Do not attach to a window */ + +/********************************************************************* +* +* Window create flags. +* +* These flags can be passed to the create window +* function as flag-parameter. The flags are combinable using the +* binary or operator. +*/ +#define WM_CF_HASTRANS (1UL << 0) /* Has transparency. Needs to be defined for windows which do not fill the entire + section of their (client) rectangle. */ +#define WM_CF_HIDE (0UL << 1) /* Hide window after creation (default !) */ +#define WM_CF_SHOW (1UL << 1) /* Show window after creation */ +#define WM_CF_MEMDEV (1UL << 2) /* Use memory device for redraws */ +#define WM_CF_STAYONTOP (1UL << 3) /* Stay on top */ +#define WM_CF_DISABLED (1UL << 4) /* Disabled: Does not receive PID (mouse & touch) input */ + +/* Create only flags ... Not available as status flags */ +#define WM_CF_ACTIVATE (1UL << 5) /* If automatic activation upon creation of window is desired */ +#define WM_CF_FGND (0UL << 6) /* Put window in foreground after creation (default !) */ +#define WM_CF_BGND (1UL << 6) /* Put window in background after creation */ + +/* Anchor flags */ +#define WM_CF_ANCHOR_RIGHT (1UL << 7) /* Right anchor ... If parent is resized, distance to right will remain const (left is default) */ +#define WM_CF_ANCHOR_BOTTOM (1UL << 8) /* Bottom anchor ... If parent is resized, distance to bottom will remain const (top is default) */ +#define WM_CF_ANCHOR_LEFT (1UL << 9) /* Left anchor ... If parent is resized, distance to left will remain const (left is default) */ +#define WM_CF_ANCHOR_TOP (1UL << 10) /* Top anchor ... If parent is resized, distance to top will remain const (top is default) */ + +#define WM_CF_CONST_OUTLINE (1UL << 11) /* Constant outline. This is relevant for transparent windows only. If a window is transparent + and does not have a constant outline, its background is invalided instead of the window itself. + This causes add. computation time when redrawing. */ +#define WM_CF_LATE_CLIP (1UL << 12) +#define WM_CF_MEMDEV_ON_REDRAW (1UL << 13) + +#define WM_SF_INVALID_DRAW (1UL << 14) +#define WM_SF_DELETE (1UL << 15) /* Marks the window to be deleted within WM_Exec() when no callback routine is executed */ + +#define WM_CF_STATIC (1UL << 16) /* Use static memory device for redraws */ + +#define WM_CF_MOTION_X (1UL << 17) /* Window can be moved automatically in X axis */ +#define WM_CF_MOTION_Y (1UL << 18) /* Window can be moved automatically in Y axis */ + +#define WM_CF_GESTURE (1UL << 19) /* Marks the window to be a able to receive gesture messages */ + +#define WM_CF_ZOOM (1UL << 20) /* Window can be scaled automatically by multi touch gesture input */ + +#define WM_CF_MOTION_R (1UL << 21) // Window can be rotated + +/********************************************************************* +* +* Window manager types +*/ +typedef struct WM_Obj WM_Obj; +typedef struct WM_MESSAGE WM_MESSAGE; + +typedef void WM_CALLBACK( WM_MESSAGE * pMsg); + +struct WM_MESSAGE { + int MsgId; /* type of message */ + WM_HWIN hWin; /* Destination window */ + WM_HWIN hWinSrc; /* Source window */ + union { + const void * p; /* Some messages need more info ... Pointer is declared "const" because some systems (M16C) have 4 byte const, byte 2 byte default ptrs */ + int v; + GUI_COLOR Color; + } Data; +}; + +struct WM_Obj { + GUI_RECT Rect; /* Outer dimensions of window */ + GUI_RECT InvalidRect; /* Invalid rectangle */ + WM_CALLBACK* cb; /* Ptr to notification callback */ + WM_HWIN hNextLin; /* Next window in linear list */ + WM_HWIN hParent; + WM_HWIN hFirstChild; + WM_HWIN hNext; + #if WM_SUPPORT_STATIC_MEMDEV + GUI_MEMDEV_Handle hMem; /* Static memory device */ + #endif + U32 Status; /* Status flags */ + #if WM_SUPPORT_CPP + void * ObjPtr; + #endif +}; + +typedef void WM_tfPollPID(void); +typedef void WM_tfForEach(WM_HWIN hWin, void * pData); + +typedef void (* WM_tfInvalidateParent) (const GUI_RECT * pInvalidRect, WM_HWIN hParent, WM_HWIN hStop); +typedef void (* WM_tfInvalidateDrawFunc)(WM_HWIN hWin); +typedef void (* WM_tfPaint1Func) (WM_HWIN hWin); + +typedef struct { + WM_HMEM hTimer; + WM_HWIN hWin; + int UserId; +} WM_TIMER_OBJ; + +/********************************************************************* +* +* General control routines +*/ +void WM_Activate (void); +void WM_Deactivate(void); +void WM_Init (void); +int WM_Exec (void); /* Execute all jobs ... Return 0 if nothing was done. */ +int WM_Exec1 (void); // Execute only one job +U32 WM_SetCreateFlags(U32 Flags); +WM_tfPollPID * WM_SetpfPollPID(WM_tfPollPID * pf); + +/********************************************************************* +* +* Window manager interface +*/ +void WM_AttachWindow (WM_HWIN hWin, WM_HWIN hParent); +void WM_AttachWindowAt (WM_HWIN hWin, WM_HWIN hParent, int x, int y); +int WM_CheckScrollPos (WM_SCROLL_STATE * pScrollState, int Pos, int LowerDist, int UpperDist); /* not to be documented (may change in future version) */ +void WM_ClrHasTrans (WM_HWIN hWin); +WM_HWIN WM_CreateWindow (int x0, int y0, int xSize, int ySize, U32 Style, WM_CALLBACK * cb, int NumExtraBytes); +WM_HWIN WM_CreateWindowAsChild (int x0, int y0, int xSize, int ySize, WM_HWIN hWinParent, U32 Style, WM_CALLBACK* cb, int NumExtraBytes); +void WM_DeleteWindow (WM_HWIN hWin); +void WM_DetachWindow (WM_HWIN hWin); +void WM_EnableGestures (WM_HWIN hWin, int OnOff); +int WM_GetHasTrans (WM_HWIN hWin); +WM_HWIN WM_GetFocusedWindow (void); +int WM_GetInvalidRect (WM_HWIN hWin, GUI_RECT * pRect); +int WM_GetStayOnTop (WM_HWIN hWin); +void WM_HideWindow (WM_HWIN hWin); +void WM_InvalidateArea (const GUI_RECT * pRect); +void WM_InvalidateRect (WM_HWIN hWin, const GUI_RECT * pRect); +void WM_InvalidateWindow (WM_HWIN hWin); +void WM_InvalidateWindowAndDescsEx(WM_HWIN hWin, const GUI_RECT * pInvalidRect, U16 Flags); +void WM_InvalidateWindowAndDescs (WM_HWIN hWin); /* not to be documented (may change in future version) */ +int WM_IsEnabled (WM_HWIN hObj); +char WM_IsCompletelyCovered (WM_HWIN hWin); /* Checks if the window is completely covered by other windows */ +char WM_IsCompletelyVisible (WM_HWIN hWin); /* Is the window completely visible ? */ +int WM_IsFocusable (WM_HWIN hWin); +int WM_IsVisible (WM_HWIN hWin); +int WM_IsWindow (WM_HWIN hWin); /* Check validity */ +void WM_SetAnchor (WM_HWIN hWin, U16 AnchorFlags); +void WM_SetHasTrans (WM_HWIN hWin); +void WM_SetId (WM_HWIN hObj, int Id); +void WM_SetStayOnTop (WM_HWIN hWin, int OnOff); +void WM_SetTransState (WM_HWIN hWin, unsigned State); +void WM_ShowWindow (WM_HWIN hWin); +void WM_ValidateRect (WM_HWIN hWin, const GUI_RECT * pRect); +void WM_ValidateWindow (WM_HWIN hWin); + +#define WM_GetFocussedWindow WM_GetFocusedWindow +#define WM_IsFocussable WM_IsFocusable + +/* Gesture support */ +void WM_GESTURE_Enable (int OnOff); +int WM_GESTURE_EnableEx(int OnOff, int MaxFactor); +void WM_GESTURE_Exec (void); +I32 WM_GESTURE_SetThresholdAngle(I32 ThresholdAngle); +I32 WM_GESTURE_SetThresholdDist (I32 ThresholdDist); + +/* Motion support */ +void WM_MOTION_Enable (int OnOff); +void WM_MOTION_SetMovement (WM_HWIN hWin, int Axis, I32 Speed, I32 Dist); +void WM_MOTION_SetMotion (WM_HWIN hWin, int Axis, I32 Speed, I32 Deceleration); +void WM_MOTION_SetMoveable (WM_HWIN hWin, U32 Flags, int OnOff); +void WM_MOTION_SetDeceleration (WM_HWIN hWin, int Axis, I32 Deceleration); +unsigned WM_MOTION_SetDefaultPeriod(unsigned Period); +void WM_MOTION_SetSpeed (WM_HWIN hWin, int Axis, I32 Velocity); +void WM_MOTION_SetMinMotion (unsigned MinMotion); +void WM_MOTION_SetThreshold (unsigned Threshold); + +/* Motion support, private interface */ +WM_HMEM WM_MOTION__CreateContext(void); +void WM_MOTION__DeleteContext(WM_HMEM hContext); + +/* Motion support, private function(s) */ +void WM__SetMotionCallback (void(* cbMotion) (GUI_PID_STATE * pState, void * p)); + +/* Static memory devices */ +#if (GUI_SUPPORT_MEMDEV) + #define GUI_MEMDEV_EDGE_LEFT 0 + #define GUI_MEMDEV_EDGE_RIGHT 1 + #define GUI_MEMDEV_EDGE_TOP 2 + #define GUI_MEMDEV_EDGE_BOTTOM 3 + + int GUI_MEMDEV_BlendWinBk (WM_HWIN hWin, int Period, U32 BlendColor, U8 BlendIntens); + int GUI_MEMDEV_BlurAndBlendWinBk(WM_HWIN hWin, int Period, U8 BlurDepth, U32 BlendColor, U8 BlendIntens); + int GUI_MEMDEV_BlurWinBk (WM_HWIN hWin, int Period, U8 BlurDepth); + void GUI_MEMDEV_CreateStatic (WM_HWIN hWin); + GUI_MEMDEV_Handle GUI_MEMDEV_CreateWindowDevice(WM_HWIN hWin); + int GUI_MEMDEV_FadeInWindow (WM_HWIN hWin, int Period); + int GUI_MEMDEV_FadeOutWindow (WM_HWIN hWin, int Period); + GUI_MEMDEV_Handle GUI_MEMDEV_GetStaticDevice (WM_HWIN hWin); + GUI_MEMDEV_Handle GUI_MEMDEV_GetWindowDevice (WM_HWIN hWin); + int GUI_MEMDEV_MoveInWindow (WM_HWIN hWin, int x, int y, int a180, int Period); + int GUI_MEMDEV_MoveOutWindow (WM_HWIN hWin, int x, int y, int a180, int Period); + void GUI_MEMDEV_Paint1Static (WM_HWIN hWin); /* not to be documented */ + int GUI_MEMDEV_ShiftInWindow (WM_HWIN hWin, int Period, int Direction); + int GUI_MEMDEV_ShiftOutWindow (WM_HWIN hWin, int Period, int Direction); + int GUI_MEMDEV_SwapWindow (WM_HWIN hWin, int Period, int Edge); + + void GUI_MEMDEV__CreateStatic (WM_HWIN hWin); +#endif + +/* Move/resize windows */ +void WM_MoveWindow (WM_HWIN hWin, int dx, int dy); +void WM_ResizeWindow (WM_HWIN hWin, int dx, int dy); +void WM_MoveTo (WM_HWIN hWin, int x, int y); +void WM_MoveChildTo (WM_HWIN hWin, int x, int y); +void WM_SetSize (WM_HWIN hWin, int XSize, int YSize); +void WM_SetWindowPos (WM_HWIN hWin, int xPos, int yPos, int xSize, int ySize); +int WM_SetXSize (WM_HWIN hWin, int xSize); +int WM_SetYSize (WM_HWIN hWin, int ySize); +int WM_SetScrollbarH (WM_HWIN hWin, int OnOff); /* not to be documented (may change in future version) */ +int WM_SetScrollbarV (WM_HWIN hWin, int OnOff); /* not to be documented (may change in future version) */ + +/* ToolTip support */ +#define WM_TOOLTIP_PI_FIRST 0 +#define WM_TOOLTIP_PI_SHOW 1 +#define WM_TOOLTIP_PI_NEXT 2 + +#define WM_TOOLTIP_CI_BK 0 +#define WM_TOOLTIP_CI_FRAME 1 +#define WM_TOOLTIP_CI_TEXT 2 + +typedef WM_HMEM WM_TOOLTIP_HANDLE; + +typedef struct { + int Id; + const char * pText; +} TOOLTIP_INFO; + +int WM_TOOLTIP_AddTool (WM_TOOLTIP_HANDLE hToolTip, WM_HWIN hTool, const char * pText); +WM_TOOLTIP_HANDLE WM_TOOLTIP_Create (WM_HWIN hDlg, const TOOLTIP_INFO * pInfo, unsigned NumItems); +void WM_TOOLTIP_Delete (WM_TOOLTIP_HANDLE hToolTip); +GUI_COLOR WM_TOOLTIP_SetDefaultColor (unsigned Index, GUI_COLOR Color); +const GUI_FONT * WM_TOOLTIP_SetDefaultFont (const GUI_FONT * pFont); +unsigned WM_TOOLTIP_SetDefaultPeriod(unsigned Index, unsigned Period); + +/* ToolTip support, private */ +void WM__SetToolTipCallback(void(* cbToolTip)(GUI_PID_STATE * pState, WM_HWIN)); + +/* Timer */ +#ifdef GUI_X_CREATE_TIMER + int WM_CreateTimer (WM_HWIN hWin, int UserID, int Period, int Mode); /* not to be documented (may change in future version) */ + void WM_DeleteTimer (WM_HWIN hWin, int UserId); /* not to be documented (may change in future version) */ +#else + WM_HMEM WM_CreateTimer (WM_HWIN hWin, int UserID, int Period, int Mode); /* not to be documented (may change in future version) */ + void WM_DeleteTimer (WM_HMEM hTimer); /* not to be documented (may change in future version) */ + void WM_RestartTimer(WM_HMEM hTimer, int Period); +#endif +int WM_GetTimerId(WM_HTIMER hTimer); + +/* Diagnostics */ +int WM_GetNumWindows(void); +int WM_GetNumInvalidWindows(void); + +/* Scroll state related functions */ +void WM_CheckScrollBounds(WM_SCROLL_STATE * pScrollState); /* not to be documented (may change in future version) */ +int WM_GetScrollPosH (WM_HWIN hWin); +int WM_GetScrollPosV (WM_HWIN hWin); +void WM_SetScrollPosH (WM_HWIN hWin, unsigned ScrollPos); +void WM_SetScrollPosV (WM_HWIN hWin, unsigned ScrollPos); +int WM_SetScrollValue (WM_SCROLL_STATE * pScrollState, int v); /* not to be documented (may change in future version) */ + +/* Get / Set (new) callback function */ +WM_CALLBACK * WM_SetCallback(WM_HWIN hWin, WM_CALLBACK * cb); +WM_CALLBACK * WM_GetCallback(WM_HWIN hWin); + +/* Get size/origin of a window */ +void WM_GetClientRect (GUI_RECT * pRect); +void WM_GetClientRectEx (WM_HWIN hWin, GUI_RECT * pRect); +void WM_GetInsideRect (GUI_RECT * pRect); +void WM_GetInsideRectEx (WM_HWIN hWin, GUI_RECT * pRect); +void WM_GetInsideRectExScrollbar(WM_HWIN hWin, GUI_RECT * pRect); /* not to be documented (may change in future version) */ +void WM_GetWindowRect (GUI_RECT * pRect); +void WM_GetWindowRectEx (WM_HWIN hWin, GUI_RECT * pRect); +int WM_GetOrgX (void); +int WM_GetOrgY (void); +int WM_GetWindowOrgX (WM_HWIN hWin); +int WM_GetWindowOrgY (WM_HWIN hWin); +int WM_GetWindowSizeX (WM_HWIN hWin); +int WM_GetWindowSizeY (WM_HWIN hWin); +WM_HWIN WM_GetFirstChild (WM_HWIN hWin); +WM_HWIN WM_GetNextSibling (WM_HWIN hWin); +WM_HWIN WM_GetParent (WM_HWIN hWin); +WM_HWIN WM_GetPrevSibling (WM_HWIN hWin); +int WM_GetId (WM_HWIN hWin); +WM_HWIN WM_GetScrollbarV (WM_HWIN hWin); +WM_HWIN WM_GetScrollbarH (WM_HWIN hWin); +WM_HWIN WM_GetScrollPartner (WM_HWIN hWin); +WM_HWIN WM_GetClientWindow (WM_HWIN hObj); +GUI_COLOR WM_GetBkColor (WM_HWIN hObj); + +/* Change Z-Order of windows */ +void WM_BringToBottom(WM_HWIN hWin); +void WM_BringToTop(WM_HWIN hWin); + +GUI_COLOR WM_SetDesktopColor (GUI_COLOR Color); +GUI_COLOR WM_SetDesktopColorEx(GUI_COLOR Color, unsigned int LayerIndex); +void WM_SetDesktopColors (GUI_COLOR Color); + +/* Select window used for drawing operations */ +WM_HWIN WM_SelectWindow (WM_HWIN hWin); +WM_HWIN WM_GetActiveWindow (void); +void WM_Paint (WM_HWIN hObj); +void WM_Update (WM_HWIN hWin); +void WM_PaintWindowAndDescs (WM_HWIN hWin); +void WM_UpdateWindowAndDescs (WM_HWIN hWin); + +/* Get foreground/background windows */ +WM_HWIN WM_GetDesktopWindow (void); +WM_HWIN WM_GetDesktopWindowEx(unsigned int LayerIndex); + +/* Reduce clipping area of a window */ +const GUI_RECT * WM_SetUserClipRect(const GUI_RECT * pRect); +void WM_SetDefault (void); + +/* Use of memory devices */ +void WM_EnableMemdev (WM_HWIN hWin); +void WM_DisableMemdev (WM_HWIN hWin); + +/* Automatic use of multiple buffers */ +int WM_MULTIBUF_Enable (int OnOff); +int WM_MULTIBUF_EnableEx(int OnOff, U32 LayerMask); + +extern const GUI_MULTIBUF_API * WM_MULTIBUF__pAPI; + +typedef void (* T_WM_EXEC_GESTURE)(void); + +extern T_WM_EXEC_GESTURE WM__pExecGestures; + +/* ... */ +int WM_OnKey(int Key, int Pressed); +void WM_MakeModal(WM_HWIN hWin); +int WM_SetModalLayer(int LayerIndex); +int WM_GetModalLayer(void); + +/********************************************************************* +* +* Message related functions +* +* Please note that some of these functions do not yet show up in the +* documentation, as they should not be required by application program. +*/ +void WM_NotifyParent (WM_HWIN hWin, int Notification); +void WM_SendMessage (WM_HWIN hWin, WM_MESSAGE * p); +void WM_SendMessageNoPara (WM_HWIN hWin, int MsgId); /* not to be documented (may change in future */ +void WM_DefaultProc (WM_MESSAGE * pMsg); +int WM_BroadcastMessage (WM_MESSAGE * pMsg); +void WM_SetScrollState (WM_HWIN hWin, const WM_SCROLL_STATE * pState); +void WM_SetEnableState (WM_HWIN hItem, int State); +void WM_SendToParent (WM_HWIN hWin, WM_MESSAGE * pMsg); +int WM_HasFocus (WM_HWIN hWin); +int WM_SetFocus (WM_HWIN hWin); +WM_HWIN WM_SetFocusOnNextChild (WM_HWIN hParent); /* Set the focus to the next child */ +WM_HWIN WM_SetFocusOnPrevChild (WM_HWIN hParent); /* Set the focus to the previous child */ +WM_HWIN WM_GetDialogItem (WM_HWIN hWin, int Id); +void WM_EnableWindow (WM_HWIN hWin); +void WM_DisableWindow (WM_HWIN hWin); +void WM_GetScrollState (WM_HWIN hObj, WM_SCROLL_STATE * pScrollState); + +/********************************************************************* +* +* Managing user data +*/ +int WM_GetUserData (WM_HWIN hWin, void * pDest, int SizeOfBuffer); +int WM_SetUserData (WM_HWIN hWin, const void * pSrc, int SizeOfBuffer); +int WM__GetUserDataEx(WM_HWIN hWin, void * pDest, int NumBytes, int SizeOfObject); +int WM__SetUserDataEx(WM_HWIN hWin, const void * pSrc, int NumBytes, int SizeOfObject); + +/********************************************************************* +* +* Capturing input focus +*/ +int WM_HasCaptured (WM_HWIN hWin); +void WM_SetCapture (WM_HWIN hObj, int AutoRelease); +void WM_SetCaptureMove(WM_HWIN hWin, const GUI_PID_STATE * pState, int MinVisibility, int LimitTop); /* Not yet documented */ +void WM_ReleaseCapture(void); + +/********************************************************************* +* +* Misc routines +*/ +int WM_HandlePID (void); +WM_HWIN WM_Screen2hWin (int x, int y); +WM_HWIN WM_Screen2hWinEx (WM_HWIN hStop, int x, int y); +void WM_ForEachDesc (WM_HWIN hWin, WM_tfForEach * pcb, void * pData); +void WM_SetScreenSize (int xSize, int ySize); +int WM_PollSimMsg (void); +int WM_GetWindowInfo (WM_WINDOW_INFO * pInfo, int FirstWindow); + +/********************************************************************* +* +* Diagnostics routines +*/ +#if (WM_SUPPORT_DIAG) +void WM_DIAG_EnableInvalidationColoring(int OnOff); +#endif + +/********************************************************************* +* +* Macros for compatibility with older versions +*/ +#if WM_COMPATIBLE_MODE + #define HBWIN WM_HWIN + #define HBWIN_NULL WM_HWIN_NULL + + #define WM_HideWin WM_HideWindow + #define WM_ShowWin WM_ShowWindow + #define WM_GetKey GUI_GetKey + #define WM_WaitKey GUI_WaitKey + + #define WM_ExecIdle WM_Exec + #define WM_ExecIdle1 WM_Exec1 + + #define WM_Invalidate WM_InvalidateWindow + #define WM_GetWinRect WM_GetWindowRect + #define WM_GetWinOrgX WM_GetWindowOrgX + #define WM_GetWinOrgY WM_GetWindowOrgY + #define WM_GetWinSizeX WM_GetWindowSizeX + #define WM_GetWinSizeY WM_GetWindowSizeY + #define WM_GetXSize WM_GetWindowSizeX + #define WM_GetYSize WM_GetWindowSizeY + #define WM_SelWin WM_SelectWindow + #define WM_GetBackgroundWindow WM_GetDesktopWindow + #define WM_GetForegroundWindow 0 + #define WM_SetForegroundWindow WM_BringToTop + #define WM_SetUserClipArea WM_SetUserClipRect + + + #define WM_Start() + #define WM_Stop() + #define WM_SetBkWindowColor(Color) WM_SetDesktopColor(Color) + +#endif + + +#endif /* GUI_WINSUPPORT */ + +#if defined(__cplusplus) +} +#endif + +#endif /* WM_H */ + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/WM_GUI.h b/example/GUI/STemWin/inc/WM_GUI.h new file mode 100755 index 0000000000..c49f0a9859 --- /dev/null +++ b/example/GUI/STemWin/inc/WM_GUI.h @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : WM_GUI.h +Purpose : Windows manager include for low level GUI routines +---------------------------------------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef WM_GUI_H /* Make sure we only include it once */ +#define WM_GUI_H + +#if defined(__cplusplus) +extern "C" { /* Make sure we have C-declarations in C++ programs */ +#endif + +int WM__InitIVRSearch(const GUI_RECT* pMaxRect); +int WM__GetNextIVR (void); +int WM__GetOrgX_AA(void); +int WM__GetOrgY_AA(void); + +#define WM_ITERATE_START(pRect) \ + { \ + if (WM__InitIVRSearch(pRect)) \ + do { + +#define WM_ITERATE_END() \ + } while (WM__GetNextIVR()); \ + } + +#define WM_ADDORGX(x) (x += GUI_pContext->xOff) +#define WM_ADDORGY(y) (y += GUI_pContext->yOff) +#define WM_ADDORG(x0,y0) WM_ADDORGX(x0); WM_ADDORGY(y0) +#define WM_ADDORGX_AA(x) (x += WM__GetOrgX_AA()) +#define WM_ADDORGY_AA(y) (y += WM__GetOrgY_AA()) +#define WM_ADDORG_AA(x0,y0) WM_ADDORGX_AA(x0); WM_ADDORGY_AA(y0) +#define WM_SUBORGX(x) (x -= GUI_pContext->xOff) +#define WM_SUBORGY(y) (y -= GUI_pContext->yOff) +#define WM_SUBORG(x0,y0) WM_SUBORGX(x0); WM_SUBORGY(y0) + +#if defined(__cplusplus) + } +#endif + + +#endif /* Avoid multiple inclusion */ + +/*************************** End of file ****************************/ diff --git a/example/GUI/STemWin/inc/WM_Intern.h b/example/GUI/STemWin/inc/WM_Intern.h new file mode 100755 index 0000000000..14a8981ea9 --- /dev/null +++ b/example/GUI/STemWin/inc/WM_Intern.h @@ -0,0 +1,278 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : WM_Intern.h +Purpose : Windows manager internal include +---------------------------------------------------------------------- +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +#ifndef WM_INTERN_H /* Make sure we only include it once */ +#define WM_INTERN_H /* Make sure we only include it once */ + +#include "WM.h" +#include "GUI_Private.h" + + +#if defined(__cplusplus) +extern "C" { /* Make sure we have C-declarations in C++ programs */ +#endif + +#if GUI_WINSUPPORT + +/********************************************************************* +* +* defines +* +********************************************************************** + + The following could be placed in a file of its own as it is not + used outside of the window manager + +*/ +/* Basic Windows status flags. + For module-internally use only ! +*/ +#define WM_SF_HASTRANS WM_CF_HASTRANS +#define WM_SF_MEMDEV WM_CF_MEMDEV +#define WM_SF_MEMDEV_ON_REDRAW WM_CF_MEMDEV_ON_REDRAW +#define WM_SF_DISABLED WM_CF_DISABLED /* Disabled: Does not receive PID (mouse & touch) input */ +#define WM_SF_ISVIS WM_CF_SHOW /* Is visible flag */ + +#define WM_SF_STAYONTOP WM_CF_STAYONTOP +#define WM_SF_LATE_CLIP WM_CF_LATE_CLIP +#define WM_SF_ANCHOR_RIGHT WM_CF_ANCHOR_RIGHT +#define WM_SF_ANCHOR_BOTTOM WM_CF_ANCHOR_BOTTOM +#define WM_SF_ANCHOR_LEFT WM_CF_ANCHOR_LEFT +#define WM_SF_ANCHOR_TOP WM_CF_ANCHOR_TOP + +#define WM_SF_INVALID WM_CF_ACTIVATE /* We reuse this flag, as it is create only and Invalid is status only */ + +#define WM_SF_CONST_OUTLINE WM_CF_CONST_OUTLINE /* Constant outline.*/ + +#define WM_H2P(hWin) ((WM_Obj*)GUI_ALLOC_h2p(hWin)) + + +#if GUI_DEBUG_LEVEL >= GUI_DEBUG_LEVEL_LOG_WARNINGS + #define WM_ASSERT_NOT_IN_PAINT() { if (WM__PaintCallbackCnt) \ + GUI_DEBUG_ERROROUT("Function may not be called from within a paint event"); \ + } +#else + #define WM_ASSERT_NOT_IN_PAINT() +#endif + +/********************************************************************* +* +* Data types & structures +* +********************************************************************** +*/ +typedef struct { + WM_HWIN hOld; + WM_HWIN hNew; +} WM_NOTIFY_CHILD_HAS_FOCUS_INFO; + +typedef struct WM_CRITICAL_HANDLE { + struct WM_CRITICAL_HANDLE * pNext; + volatile WM_HWIN hWin; +} WM_CRITICAL_HANDLE; + +/********************************************************************* +* +* Data (extern) +* +********************************************************************** +*/ +extern U32 WM__CreateFlags; +extern WM_HWIN WM__ahCapture[GUI_NUM_LAYERS]; +extern WM_HWIN WM__ahWinFocus[GUI_NUM_LAYERS]; +extern char WM__CaptureReleaseAuto; +extern WM_tfPollPID * WM_pfPollPID; +extern U8 WM__PaintCallbackCnt; /* Public for assertions only */ +extern WM_HWIN WM__hCreateStatic; + +#if WM_SUPPORT_TRANSPARENCY + extern int WM__TransWindowCnt; + extern WM_HWIN WM__hATransWindow; +#endif + +#if WM_SUPPORT_DIAG + extern void (*WM__pfShowInvalid)(WM_HWIN hWin); +#endif + +extern WM_CRITICAL_HANDLE WM__aCHWinModal[GUI_NUM_LAYERS]; +extern WM_CRITICAL_HANDLE WM__aCHWinLast[GUI_NUM_LAYERS]; +extern int WM__ModalLayer; + +#if GUI_SUPPORT_MOUSE + extern WM_CRITICAL_HANDLE WM__aCHWinMouseOver[GUI_NUM_LAYERS]; +#endif + +#ifdef WM_C + #define GUI_EXTERN +#else + #define GUI_EXTERN extern +#endif + +#if (GUI_NUM_LAYERS > 1) + GUI_EXTERN U32 WM__InvalidLayerMask; + GUI_EXTERN unsigned WM__TouchedLayer; + #define WM__TOUCHED_LAYER WM__TouchedLayer +#else + #define WM__TOUCHED_LAYER GUI_CURSOR_LAYER +#endif + +GUI_EXTERN U16 WM__NumWindows; +GUI_EXTERN U16 WM__NumInvalidWindows; +GUI_EXTERN WM_HWIN WM__FirstWin; +GUI_EXTERN WM_CRITICAL_HANDLE * WM__pFirstCriticalHandle; + +GUI_EXTERN WM_HWIN WM__ahDesktopWin[GUI_NUM_LAYERS]; +GUI_EXTERN GUI_COLOR WM__aBkColor[GUI_NUM_LAYERS]; + +#undef GUI_EXTERN + +/********************************************************************* +* +* Prototypes +* +********************************************************************** +*/ +void WM__ActivateClipRect (void); +int WM__ClipAtParentBorders (GUI_RECT * pRect, WM_HWIN hWin); +void WM__Client2Screen (const WM_Obj * pWin, GUI_RECT * pRect); +void WM__DeleteAssocTimer (WM_HWIN hWin); +void WM__DeleteSecure (WM_HWIN hWin); +void WM__DetachWindow (WM_HWIN hChild); +void WM__ForEachDesc (WM_HWIN hWin, WM_tfForEach * pcb, void * pData); +void WM__GetClientRectWin (const WM_Obj * pWin, GUI_RECT * pRect); +void WM__GetClientRectEx (WM_HWIN hWin, GUI_RECT * pRect); +WM_HWIN WM__GetFirstSibling (WM_HWIN hWin); +WM_HWIN WM__GetFocusedChild (WM_HWIN hWin); +int WM__GetHasFocus (WM_HWIN hWin); +WM_HWIN WM__GetLastSibling (WM_HWIN hWin); +WM_HWIN WM__GetPrevSibling (WM_HWIN hWin); +int WM__GetTopLevelLayer (WM_HWIN hWin); +int WM__GetWindowSizeX (const WM_Obj * pWin); +int WM__GetWindowSizeY (const WM_Obj * pWin); +void WM__InsertWindowIntoList (WM_HWIN hWin, WM_HWIN hParent); +void WM__Invalidate1Abs (WM_HWIN hWin, const GUI_RECT * pRect); +void WM__InvalidateAreaBelow (const GUI_RECT * pRect, WM_HWIN StopWin); +void WM__InvalidateRectEx (const GUI_RECT * pInvalidRect, WM_HWIN hParent, WM_HWIN hStop); +void WM__InvalidateTransAreaAbove(const GUI_RECT * pRect, WM_HWIN StopWin); +int WM__IntersectRect (GUI_RECT * pDest, const GUI_RECT * pr0, const GUI_RECT * pr1); +int WM__IsAncestor (WM_HWIN hChild, WM_HWIN hParent); +int WM__IsAncestorOrSelf (WM_HWIN hChild, WM_HWIN hParent); +int WM__IsChild (WM_HWIN hWin, WM_HWIN hParent); +int WM__IsEnabled (WM_HWIN hWin); +int WM__IsInModalArea (WM_HWIN hWin); +int WM__IsInWindow (WM_Obj * pWin, int x, int y); +int WM__IsWindow (WM_HWIN hWin); +void WM__LeaveIVRSearch (void); +void WM__MoveTo (WM_HWIN hWin, int x, int y); +void WM__MoveWindow (WM_HWIN hWin, int dx, int dy); +void WM__NotifyVisChanged (WM_HWIN hWin, GUI_RECT * pRect); +int WM__RectIsNZ (const GUI_RECT * pr); +void WM__RemoveWindowFromList (WM_HWIN hWin); +void WM__Screen2Client (const WM_Obj * pWin, GUI_RECT * pRect); +void WM__SelectTopLevelLayer (WM_HWIN hWin); +void WM__SendMsgNoData (WM_HWIN hWin, U8 MsgId); +void WM__SendMessage (WM_HWIN hWin, WM_MESSAGE * pm); +void WM__SendMessageIfEnabled (WM_HWIN hWin, WM_MESSAGE * pm); +void WM__SendMessageNoPara (WM_HWIN hWin, int MsgId); +void WM__SendPIDMessage (WM_HWIN hWin, WM_MESSAGE * pMsg); +int WM__SetScrollbarH (WM_HWIN hWin, int OnOff); +int WM__SetScrollbarV (WM_HWIN hWin, int OnOff); +void WM__UpdateChildPositions (WM_Obj * pObj, int dx0, int dy0, int dx1, int dy1); +void WM_PID__GetPrevState (GUI_PID_STATE * pPrevState, int Layer); +void WM_PID__SetPrevState (GUI_PID_STATE * pPrevState, int Layer); +void WM__SendTouchMessage (WM_HWIN hWin, WM_MESSAGE * pMsg); + +U16 WM_GetFlags (WM_HWIN hWin); +int WM__Paint (WM_HWIN hWin); +void WM__Paint1 (WM_HWIN hWin); +void WM__AddCriticalHandle (WM_CRITICAL_HANDLE * pCH); +void WM__RemoveCriticalHandle (WM_CRITICAL_HANDLE * pCH); +void WM__SetLastTouched (WM_HWIN hWin); + +#if WM_SUPPORT_STATIC_MEMDEV + void WM__InvalidateDrawAndDescs(WM_HWIN hWin); +#else + #define WM__InvalidateDrawAndDescs(hWin) +#endif + +/* Static memory devices */ +#if (GUI_SUPPORT_MEMDEV) + typedef struct { + int xSize, ySize; // Size of bk window + } EFFECT_CONTEXT; + + int GUI_MEMDEV__CalcParaFadeIn (int Period, int TimeUsed); + void GUI_MEMDEV__ClipBK (EFFECT_CONTEXT * pContext); + void GUI_MEMDEV__RemoveStaticDevice(WM_HWIN hWin); + void GUI_MEMDEV__UndoClipBK (EFFECT_CONTEXT * pContext); +#endif + +void WM__InvalidateParent(const GUI_RECT * pInvalidRect, WM_HWIN hParent, WM_HWIN hStop); +void WM__InvalidateRect (const GUI_RECT * pInvalidRect, WM_HWIN hParent, WM_HWIN hStop, U16 Flags); + +WM_tfInvalidateParent WM__SetInvalidateParentFunc(WM_tfInvalidateParent pfInvalidateParentFunc); +WM_tfInvalidateDrawFunc WM__SetInvalidateDrawFunc (WM_tfInvalidateDrawFunc pfInvalidateDrawFunc); +WM_tfPaint1Func WM__SetPaint1Func (WM_tfPaint1Func pfPaint1Func); + +#endif /* GUI_WINSUPPORT */ + +#if defined(__cplusplus) + } +#endif + +#endif /* WM_INTERN_H */ + +/*************************** End of file ****************************/ diff --git a/example/GUI/app/GUIDEMO.c b/example/GUI/app/GUIDEMO.c new file mode 100755 index 0000000000..e3d64b51cd --- /dev/null +++ b/example/GUI/app/GUIDEMO.c @@ -0,0 +1,429 @@ +/********************************************************************* +* Portions COPYRIGHT 2013 STMicroelectronics * +* Portions SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2013 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.22 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GUIDEMO.c +Purpose : Several GUIDEMO routines +---------------------------------------------------------------------- +*/ + +/** + ****************************************************************************** + * @file GUIDEMO.c + * @author MCD Application Team + * @brief Several GUIDEMO routines + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * 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 "GUIDEMO.h" +/********************************************************************* +* +* Dialog resources +* +********************************************************************** +*/ + +/********************************************************************* +* +* Static variables +* +********************************************************************** +*/ +static GUIDEMO_CONFIG _GUIDemoConfig; +static WM_HWIN _hDialogControl; +static WM_HWIN _hDialogInfo; + +static void (* _pfDrawBk)(int DrawLogo); +static int _iDemo; +static int _iDemoMinor; +static int _HaltTime; +static int _HaltTimeStart; +static int _Halt; +int _Next; + +/********************************************************************* +* +* Static functions +* +********************************************************************** +*/ +/********************************************************************* +* +* _ClearHalt +* +* This function is called if the next button is pressed after +* the demo was halted +*/ +static void _ClearHalt(void) { + _Halt = 0; + _HaltTime = 0; + _HaltTimeStart = 0; +} + +/********************************************************************* +* +* _DrawBkSimple +*/ +static void _DrawBkSimple(int DrawLogo) { + GUI_SetBkColor(BK_COLOR_1); + GUI_Clear(); + if (DrawLogo) { +// GUI_DrawBitmap(&bmSTLogo70x35, 5, 5); + } +} + + +/********************************************************************* +* +* _HideProgress +*/ +static void _HideProgress(void) { + PROGBAR_Handle hProg; + + hProg = WM_GetDialogItem(_hDialogControl, GUI_ID_PROGBAR0); + WM_HideWindow(hProg); +} + +/********************************************************************* +* +* _ShowProgress +*/ +static void _ShowProgress(void) { + PROGBAR_Handle hProg; + + hProg = WM_GetDialogItem(_hDialogControl, GUI_ID_PROGBAR0); + WM_ShowWindow(hProg); +} + +/********************************************************************* +* +* _Main +*/ +/********************************************************************* +* +* GUIDEMO_SetDrawLogo +*/ +void GUIDEMO_AddIntToString(char * pText, unsigned int Number) { + int TextLen; + int LenNum; + int i; + + TextLen = 0; + while (*(pText + TextLen)) { + TextLen++; + } + i = 1; + LenNum = 1; + while ((Number / i) >= 10) { + i *= 10; + LenNum++; + } + *(pText + TextLen + LenNum) = '\0'; + while (LenNum) { + *(pText + TextLen + LenNum - 1) = '0' + Number % 10; + Number /= 10; + LenNum--; + } +} + +/********************************************************************* +* +* GUIDEMO_AddStringToString +*/ +void GUIDEMO_AddStringToString(char * pText, const char * acAdd) { + int i; + int j; + + i = 0; + j = 0; + while (*(pText + i)) { + i++; + } + while (*(acAdd + j)) { + *(pText + i) = *(acAdd + j); + i++; + j++; + } + *(pText + i) = '\0'; +} + +/********************************************************************* +* +* GUIDEMO_CheckCancel +*/ +int GUIDEMO_CheckCancel(void) { + // + // Do not return until the button is released + // + while (_Halt == 1) { + GUI_Delay(10); + } + // + // Check Next Button + // + if (_Next == 1) { + _Next = 0; + return 1; + } + return 0; +} + +/********************************************************************* +* +* GUIDEMO_ClearText +* +*/ +void GUIDEMO_ClearText(char * pText) { + *pText = 0; +} + +/********************************************************************* +* +* GUIDEMO_Delay +* +* This function has to be called if the current step of the sample +* is the last one and consists of a single frame +*/ +void GUIDEMO_Delay(int TimeDelay) { + PROGBAR_Handle hProg; + int NextState; + U32 TimeStart; + U32 TimeDiff; + + hProg = WM_GetDialogItem(_hDialogControl, GUI_ID_PROGBAR0); + if (TimeDelay > SHOW_PROGBAR_AT) { + _ShowProgress(); + } + PROGBAR_SetValue(hProg, 0); + PROGBAR_SetMinMax(hProg, 0, TimeDelay); + TimeStart = GUI_GetTime(); + do { + + + TimeDiff = GUIDEMO_GetTime() - TimeStart; + if (TimeDelay > SHOW_PROGBAR_AT) { + PROGBAR_SetValue(hProg, TimeDiff); + } + GUI_Delay(5); + NextState = GUIDEMO_CheckCancel(); + } while (TimeDiff < (U32)TimeDelay && !NextState); + if (TimeDelay > SHOW_PROGBAR_AT) { + _HideProgress(); + } + GUI_Exec(); +} + +/********************************************************************* +* +* GUIDEMO_DrawBk +*/ +void GUIDEMO_DrawBk(int DrawLogo) { + _pfDrawBk(DrawLogo); +} + +/********************************************************************* +* +* GUIDEMO_GetConfFlag +*/ +U16 GUIDEMO_GetConfFlag(U16 Flag) { + return (_GUIDemoConfig.Flags & Flag) ? 1 : 0; +} + +/********************************************************************* +* +* GUIDEMO_GetTime +*/ +int GUIDEMO_GetTime(void) { + return _Halt ? _HaltTimeStart : GUI_GetTime() - _HaltTime; +} + +/********************************************************************* +* +* GUIDEMO_HideControlWin +*/ +void GUIDEMO_HideControlWin(void) { + WM_HideWindow(_hDialogControl); + WM_ValidateWindow(WM_HBKWIN); +} + +/********************************************************************* +* +* GUIDEMO_HideInfoWin +*/ +void GUIDEMO_HideInfoWin(void) { + WM_HideWindow(_hDialogInfo); + WM_ValidateWindow(WM_HBKWIN); +} + +/********************************************************************* +* +* GUIDEMO_NotifyStartNext +* +* Use this function if the next step of the current sample will be +* shown immediately +*/ +void GUIDEMO_NotifyStartNext(void) { + _iDemoMinor++; + _ClearHalt(); + GUIDEMO_UpdateControlText(); +} + +/********************************************************************* +* +* GUIDEMO_ShowControlWin +*/ +void GUIDEMO_ShowControlWin(void) { + WM_ShowWindow(_hDialogControl); + GUI_Exec(); +} + +/********************************************************************* +* +* GUIDEMO_ShowInfo +*/ +void GUIDEMO_ShowInfo(const char * acInfo) { + TEXT_Handle hText; + + if (WM_IsVisible(_hDialogInfo)) { + hText = WM_GetDialogItem(_hDialogInfo, GUI_ID_TEXT0); + TEXT_SetWrapMode(hText, GUI_WRAPMODE_WORD); + TEXT_SetText(hText, acInfo); + } +} + +/********************************************************************* +* +* GUIDEMO_ShowInfoWin +*/ +void GUIDEMO_ShowInfoWin(void) { + WM_ShowWindow(_hDialogInfo); +} + +/********************************************************************* +* +* GUIDEMO_UpdateControlText +*/ +void GUIDEMO_UpdateControlText(void) { + TEXT_Handle hText; + char acText[20] = { 0 }; + + hText = WM_GetDialogItem(_hDialogControl, GUI_ID_TEXT0); + GUIDEMO_AddStringToString(acText, "Demo "); + GUIDEMO_AddIntToString (acText, _iDemo + 1); + GUIDEMO_AddStringToString(acText, "."); + GUIDEMO_AddIntToString (acText, _iDemoMinor); + GUIDEMO_AddStringToString(acText, "/"); + GUIDEMO_AddIntToString (acText, _GUIDemoConfig.NumDemos - 1); + TEXT_SetText (hText, acText); +} + +/********************************************************************* +* +* GUIDEMO_Wait +* +* This function has to be called if the current step is a static +* frame and another step will follow +*/ +void GUIDEMO_Wait(int TimeWait) { + GUIDEMO_Delay(TimeWait); + GUIDEMO_NotifyStartNext(); +} + +/********************************************************************* +* +* GUIDEMO_Main +*/ + +static void _Main(void) { + WM_SelectWindow(WM_HBKWIN); + GUI_Clear(); + + WM_InvalidateWindow(_hDialogControl); + WM_DisableMemdev(WM_HBKWIN); + GUI_Exec(); + WM_EnableMemdev(WM_HBKWIN); + + GUIDEMO_Intro(); + GUIDEMO_TransparentDialog(); + GUIDEMO_Graph(); + GUIDEMO_ColorBar(); + + _iDemo = 0; + + WM_DeleteWindow(_hDialogControl); +} + +void GUIDEMO_Main(void) { + _pfDrawBk = _DrawBkSimple; + + while (1) { + printf("hello world! \n"); + _Main(); + } +} + +/*************************** End of file ****************************/ + diff --git a/example/GUI/app/GUIDEMO_BarGraph.c b/example/GUI/app/GUIDEMO_BarGraph.c new file mode 100755 index 0000000000..b436dde773 --- /dev/null +++ b/example/GUI/app/GUIDEMO_BarGraph.c @@ -0,0 +1,562 @@ +/********************************************************************* +* Portions COPYRIGHT 2013 STMicroelectronics * +* Portions SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2013 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.22 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GUIDEMO_Bargraph.c +Purpose : Shows a bargraph with alpha effect +---------------------------------------------------------------------- +*/ + +/** + ****************************************************************************** + * @file GUIDEMO_Bargraph.c + * @author MCD Application Team + * @brief Shows a bargraph with alpha effect + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + + +#include "GUI.h" +#include "GUIDEMO.h" + +#if (SHOW_GUIDEMO_BARGRAPH && GUI_SUPPORT_MEMDEV) + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ +#define GRAPH_WIDTH 172 +#define GRAPH_HEIGHT 122 +#define SHOW_TIME 15000 +#define TIME_STEP 31 + +/********************************************************************* +* +* Static data +* +********************************************************************** +*/ +/********************************************************************* +* +* Antialiased digit font for labeling +*/ +GUI_CONST_STORAGE unsigned char acGUI_FontD9_AA4_0030[ 36] = { /* code 0030, DIGIT ZERO */ + 0x07, 0xEF, 0x91, 0x00, + 0x4F, 0xCA, 0xF7, 0x00, + 0x8F, 0x20, 0xDC, 0x00, + 0xBF, 0x00, 0xBF, 0x00, + 0xBF, 0x00, 0xBF, 0x00, + 0xBF, 0x00, 0xBF, 0x00, + 0x7F, 0x41, 0xEB, 0x00, + 0x2F, 0xED, 0xF6, 0x00, + 0x04, 0xAB, 0x60, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontD9_AA4_0031[ 27] = { /* code 0031, DIGIT ONE */ + 0x00, 0xAF, 0x00, + 0x19, 0xFF, 0x00, + 0xEE, 0xDF, 0x00, + 0x82, 0xBF, 0x00, + 0x00, 0xBF, 0x00, + 0x00, 0xBF, 0x00, + 0x00, 0xBF, 0x00, + 0x00, 0xBF, 0x00, + 0x00, 0x8B, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontD9_AA4_0032[ 36] = { /* code 0032, DIGIT TWO */ + 0x06, 0xEF, 0xC3, 0x00, + 0x3F, 0xC8, 0xFD, 0x00, + 0x5B, 0x30, 0xBF, 0x00, + 0x00, 0x01, 0xEB, 0x00, + 0x00, 0x1C, 0xE3, 0x00, + 0x01, 0xCE, 0x30, 0x00, + 0x0B, 0xE3, 0x00, 0x00, + 0x6F, 0xFF, 0xFF, 0x00, + 0x8B, 0xBB, 0xBB, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontD9_AA4_0033[ 36] = { /* code 0033, DIGIT THREE */ + 0x3B, 0xFD, 0x30, 0x00, + 0xAF, 0x8E, 0xD0, 0x00, + 0x46, 0x0C, 0xE0, 0x00, + 0x00, 0xBE, 0x50, 0x00, + 0x00, 0x7C, 0xC1, 0x00, + 0x00, 0x05, 0xF7, 0x00, + 0xB9, 0x06, 0xF7, 0x00, + 0xAF, 0xCF, 0xE1, 0x00, + 0x18, 0xB9, 0x20, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontD9_AA4_0034[ 36] = { /* code 0034, DIGIT FOUR */ + 0x00, 0x0C, 0xF0, 0x00, + 0x00, 0x7F, 0xF0, 0x00, + 0x04, 0xFE, 0xF0, 0x00, + 0x1D, 0x8B, 0xF0, 0x00, + 0x8D, 0x1B, 0xF0, 0x00, + 0xBA, 0x7D, 0xF7, 0x00, + 0xBF, 0xFF, 0xFF, 0x00, + 0x00, 0x0B, 0xF0, 0x00, + 0x00, 0x08, 0xB0, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontD9_AA4_0035[ 36] = { /* code 0035, DIGIT FIVE */ + 0x05, 0xFF, 0xFB, 0x00, + 0x07, 0xFC, 0xB8, 0x00, + 0x0B, 0xF0, 0x00, 0x00, + 0x0E, 0xFE, 0xD5, 0x00, + 0x2F, 0xD7, 0xEE, 0x10, + 0x02, 0x10, 0x7F, 0x40, + 0x5F, 0x60, 0x9F, 0x30, + 0x2E, 0xFB, 0xFB, 0x00, + 0x03, 0x9B, 0x71, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontD9_AA4_0036[ 36] = { /* code 0036, DIGIT SIX */ + 0x05, 0xDF, 0xB1, 0x00, + 0x2F, 0xCA, 0xF7, 0x00, + 0x8F, 0x10, 0x74, 0x00, + 0xBE, 0x7B, 0x70, 0x00, + 0xBF, 0xDC, 0xF8, 0x00, + 0xBF, 0x10, 0xCF, 0x00, + 0x7F, 0x20, 0xCF, 0x00, + 0x2E, 0xEC, 0xF8, 0x00, + 0x03, 0xAB, 0x70, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontD9_AA4_0037[ 36] = { /* code 0037, DIGIT SEVEN */ + 0xBF, 0xFF, 0xFB, 0x00, + 0x8B, 0xBC, 0xF8, 0x00, + 0x00, 0x0C, 0xB0, 0x00, + 0x00, 0x7F, 0x20, 0x00, + 0x00, 0xE9, 0x00, 0x00, + 0x06, 0xF5, 0x00, 0x00, + 0x0A, 0xF1, 0x00, 0x00, + 0x0D, 0xC0, 0x00, 0x00, + 0x0B, 0x80, 0x00, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontD9_AA4_0038[ 36] = { /* code 0038, DIGIT EIGHT */ + 0x08, 0xEF, 0xA1, 0x00, + 0x6F, 0x97, 0xF9, 0x00, + 0x7F, 0x40, 0xFB, 0x00, + 0x2D, 0xCA, 0xE5, 0x00, + 0x1B, 0xDC, 0xD3, 0x00, + 0x9F, 0x20, 0xDD, 0x00, + 0xBF, 0x10, 0xCF, 0x00, + 0x5F, 0xB8, 0xF9, 0x00, + 0x05, 0xAB, 0x70, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontD9_AA4_0039[ 36] = { /* code 0039, DIGIT NINE */ + 0x08, 0xFF, 0x80, 0x00, + 0x7F, 0xA9, 0xF7, 0x00, + 0xBF, 0x00, 0xCC, 0x00, + 0xAF, 0x31, 0xDF, 0x00, + 0x3E, 0xFF, 0xEF, 0x00, + 0x02, 0x76, 0xBF, 0x00, + 0x4B, 0x40, 0xDA, 0x00, + 0x3F, 0xED, 0xF5, 0x00, + 0x05, 0xBA, 0x40, 0x00 +}; + +GUI_CONST_STORAGE GUI_CHARINFO GUI_FontD9_AA4_CharInfo[10] = { + { 7, 7, 4, acGUI_FontD9_AA4_0030 } /* code 0030 */ + ,{ 5, 5, 3, acGUI_FontD9_AA4_0031 } /* code 0031 */ + ,{ 7, 7, 4, acGUI_FontD9_AA4_0032 } /* code 0032 */ + ,{ 7, 7, 4, acGUI_FontD9_AA4_0033 } /* code 0033 */ + ,{ 7, 7, 4, acGUI_FontD9_AA4_0034 } /* code 0034 */ + ,{ 7, 7, 4, acGUI_FontD9_AA4_0035 } /* code 0035 */ + ,{ 7, 7, 4, acGUI_FontD9_AA4_0036 } /* code 0036 */ + ,{ 7, 7, 4, acGUI_FontD9_AA4_0037 } /* code 0037 */ + ,{ 7, 7, 4, acGUI_FontD9_AA4_0038 } /* code 0038 */ + ,{ 7, 7, 4, acGUI_FontD9_AA4_0039 } /* code 0039 */ +}; + +GUI_CONST_STORAGE GUI_FONT_PROP GUI_FontD9_AA4_Prop1 = { + 0x0030 /* first character */ + ,0x0039 /* last character */ + ,&GUI_FontD9_AA4_CharInfo[ 0] /* address of first character */ + ,(GUI_CONST_STORAGE GUI_FONT_PROP *)0 /* pointer to next GUI_FONT_PROP */ +}; + +GUI_CONST_STORAGE GUI_FONT GUI_FontD9_AA4 = { + GUI_FONTTYPE_PROP_AA4 /* type of font */ + ,9 /* height of font */ + ,9 /* space of font y */ + ,1 /* magnification x */ + ,1 /* magnification y */ + ,{&GUI_FontD9_AA4_Prop1} + ,0 /* Baseline */ + ,0 /* Height of lowercase characters */ + ,0 /* Height of capital characters */ +}; + +/********************************************************************* +* +* Alpha bitmap for the orange dot at the left of the diagramm +*/ +static GUI_CONST_STORAGE unsigned long _acCircleOrange_14x14[] = { + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFA0094F3, 0x860094F3, 0x790094F3, 0x140094F3, 0x140094F3, 0x790094F3, 0x860094F3, 0xFA0094F3, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xB90094F3, 0x450094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x450094F3, 0xB90094F3, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xC10094F3, 0x050094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x050094F3, 0xC10094F3, 0xFFFFFFFF, + 0xF10094F3, 0x3E0094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x3E0094F3, 0xF10094F3, + 0x870094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x870094F3, + 0x760094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x760094F3, + 0x140094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x140094F3, + 0x140094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x140094F3, + 0x760094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x760094F3, + 0x870094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x870094F3, + 0xF10094F3, 0x3E0094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x3E0094F3, 0xF10094F3, + 0xFFFFFFFF, 0xC10094F3, 0x050094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x050094F3, 0xC10094F3, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xB90094F3, 0x450094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x000094F3, 0x450094F3, 0xB90094F3, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFA0094F3, 0x860094F3, 0x790094F3, 0x140094F3, 0x140094F3, 0x790094F3, 0x860094F3, 0xFA0094F3, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF +}; + +static GUI_CONST_STORAGE GUI_BITMAP _bmCircleOrange_14x14 = { + 14, /* XSize */ + 14, /* YSize */ + 56, /* BytesPerLine */ + 32, /* BitsPerPixel */ + (unsigned char *)_acCircleOrange_14x14, /* Pointer to picture data */ + NULL /* Pointer to palette */ + ,GUI_DRAW_BMP8888 +}; + +/********************************************************************* +* +* Bitmaps for drawing the bars +*/ +static GUI_CONST_STORAGE GUI_COLOR ColorsBarOrange_12x1[] = { + 0x2268E2,0x3785EC,0x509FEF,0x4B97F1 + ,0x63B1F3,0x69B5F3,0x71B9F5,0x7BBDF7 + ,0x86C4F8,0x8DC8FA,0xBADEFC,0xD5E9FE +}; + +static GUI_CONST_STORAGE GUI_COLOR ColorsBarBluegreen_12x1[] = { + 0x746E2D,0x918F3E,0x959041,0x979147 + ,0x9B9650,0xA19C5E,0xA9A56D,0xB2B182 + ,0xBFBE98,0xC3C29A,0xCFCFB3,0xE1E3D4 +}; + +static GUI_CONST_STORAGE GUI_COLOR ColorsBarBlue_12x1[] = { + 0x825100,0xC3942C,0xCE953F,0xCD964A + ,0xCF9B56,0xD4A465,0xDAAD76,0xE0B986 + ,0xE4C496,0xEBD1A7,0xEAD1A8,0xF4E1BF +}; + +static GUI_CONST_STORAGE GUI_LOGPALETTE PalBarOrange_12x1 = { + 12, /* number of entries */ + 0, /* No transparency */ + &ColorsBarOrange_12x1[0] +}; + +static GUI_CONST_STORAGE GUI_LOGPALETTE PalBarBluegreen_12x1 = { + 12, /* number of entries */ + 0, /* No transparency */ + &ColorsBarBluegreen_12x1[0] +}; + +static GUI_CONST_STORAGE GUI_LOGPALETTE PalBarBlue_12x1 = { + 12, /* number of entries */ + 0, /* No transparency */ + &ColorsBarBlue_12x1[0] +}; + +static GUI_CONST_STORAGE unsigned char _acBarOrange_12x1[] = { + 0x3B, 0xA9, 0x87, 0x65, 0x42, 0x10 +}; + +static GUI_CONST_STORAGE unsigned char _acBarBluegreen_12x1[] = { + 0x09, 0xBA, 0x87, 0x65, 0x43, 0x21 +}; + +static GUI_CONST_STORAGE unsigned char _acBarBlue_12x1[] = { + 0x01, 0xAB, 0x98, 0x76, 0x54, 0x32 +}; + +static GUI_CONST_STORAGE GUI_BITMAP _bmBarOrange_12x1 = { + 12, /* XSize */ + 1, /* YSize */ + 6, /* BytesPerLine */ + 4, /* BitsPerPixel */ + _acBarOrange_12x1, /* Pointer to picture data (indices) */ + &PalBarOrange_12x1 /* Pointer to palette */ +}; + +static GUI_CONST_STORAGE GUI_BITMAP _bmBarBluegreen_12x1 = { + 12, /* XSize */ + 1, /* YSize */ + 6, /* BytesPerLine */ + 4, /* BitsPerPixel */ + _acBarBluegreen_12x1, /* Pointer to picture data (indices) */ + &PalBarBluegreen_12x1 /* Pointer to palette */ +}; + +static GUI_CONST_STORAGE GUI_BITMAP _bmBarBlue_12x1 = { + 12, /* XSize */ + 1, /* YSize */ + 6, /* BytesPerLine */ + 4, /* BitsPerPixel */ + _acBarBlue_12x1, /* Pointer to picture data (indices) */ + &PalBarBlue_12x1 /* Pointer to palette */ +}; + +static GUI_CONST_STORAGE GUI_BITMAP * _apBmBar[] = { + &_bmBarBlue_12x1, + &_bmBarBluegreen_12x1, + &_bmBarOrange_12x1 +}; + +/********************************************************************* +* +* Static code +* +********************************************************************** +*/ +static void _DrawLabel(GUI_MEMDEV_Handle hMem, int xPos, int yPos) { + GUI_MEMDEV_Handle hMemOld; + int FontSizeY, i, x0, y0; + + hMemOld = GUI_MEMDEV_Select(hMem); + GUI_SetFont(&GUI_FontD9_AA4); + GUI_SetTextMode(GUI_TM_TRANS); + FontSizeY = GUI_GetFontSizeY(); + for (i = 0; i < 5; i++) { + x0 = xPos - 7; + y0 = yPos + 96 - i * 20 - 7; + //GUI_ClearRect(x0, y0, x0 + 6, y0 + 13); + GUI_DrawBitmap(&_bmCircleOrange_14x14, x0, y0); + GUI_GotoXY(x0 + 7, y0 + 7 - FontSizeY / 2); + GUI_SetTextAlign(GUI_TA_HCENTER); + GUI_SetColor(GUI_BLACK); + GUI_DispDecMin((i + 1) * 2); + } + GUI_MEMDEV_Select(hMemOld); +} + + +/********************************************************************* +* +* _DrawDiagramAt +*/ +static void _DrawDiagramAt(GUI_MEMDEV_Handle hMem, int xPos, int yPos, int * py, int xBlend) { + GUI_MEMDEV_Handle hMemOld; + GUI_RECT Rect; + int i, ySizeBar, IndexBmBar; + + hMemOld = GUI_MEMDEV_Select(hMem); + // + // Draw blue background + // + GUI_SetColor(0x4a2210); + GUI_FillRoundedRect(xPos, yPos, xPos + GRAPH_WIDTH, yPos + GRAPH_HEIGHT, 4); + // + // Draw grid lines + // + GUI_SetColor(0x774830); + for (i = 0; i < 12; i++) { + GUI_DrawHLine(yPos + 6 + i * 10, xPos + 2, xPos + GRAPH_WIDTH - 2); + } + // + // Draw bars + // + for (i = 0; i < 10; i++) { + IndexBmBar = (i < 6) ? i / 2 : 4 - (i / 2); + ySizeBar = *(py + i); + GUI_DrawBitmapMag(_apBmBar[IndexBmBar], xPos + 8 + i * 16, yPos + GRAPH_HEIGHT - ySizeBar - 6, 1, ySizeBar); + } + // + // Draw alpha effect + // + Rect.x0 = xPos; + Rect.x1 = xPos + 3; + Rect.y0 = yPos; + Rect.y1 = yPos + GRAPH_HEIGHT; + GUI_SetClipRect(&Rect); + GUI_SetColor(0xd99100); + GUI_SetAlpha(168); + GUI_FillRoundedRect(xPos, yPos, xPos + GRAPH_WIDTH, yPos + GRAPH_HEIGHT, 4); + GUI_SetClipRect(NULL); + GUI_FillRect(xPos + 4, yPos + 1, xPos + xBlend, yPos + GRAPH_HEIGHT - 1); + GUI_SetAlpha(0); + // + // Draw orange frame + // + GUI_SetColor(0x0094f3); + GUI_DrawRoundedRect(xPos, yPos, xPos + GRAPH_WIDTH, yPos + GRAPH_HEIGHT, 4); + // + // Label + // + _DrawLabel(hMem, xPos, yPos); + GUI_MEMDEV_CopyToLCD(hMem); + GUI_MEMDEV_Select(hMemOld); +} + +/********************************************************************* +* +* _DemoBarGraph +*/ +static void _DemoBarGraph(void) { + GUI_MEMDEV_Handle hMem; + int xSize, ySize, xPosGraph, yPosGraph, yPosText, i; + int ayOrg[] = {10, 20, 40, 50, 90, 100, 80, 30, 20, 10}; + int ayCur[] = {10, 20, 40, 50, 90, 100, 80, 30, 20, 10}; + int aAdd[GUI_COUNTOF(ayOrg)]; + int AddBlend = 1; + int Blend = 64; + int NumItems = GUI_COUNTOF(ayOrg); + int TimeStart, TimeDiff, TimeStep; + int NextState; + + // + // Calculate positions + // + xSize = LCD_GetXSize(); + ySize = LCD_GetYSize(); + xPosGraph = (xSize - GRAPH_WIDTH) >> 1; + yPosGraph = (ySize - GRAPH_HEIGHT) >> 1; + // + // Label demo + // +// GUI_SetFont(&GUI_FontRounded22); +// yPosText = LOGO_DIST_BORDER + ((bmSTLogo70x35.YSize - GUI_GetFontSizeY()) >> 1); +// GUI_DispStringHCenterAt("Bargraph demo", (xSize + bmSTLogo70x35.XSize) >> 1, yPosText); + // + // Initialize values; Create MEMDEV + // + hMem = GUI_MEMDEV_Create(xPosGraph, yPosGraph, GRAPH_WIDTH + 7 + 1, GRAPH_HEIGHT + 1); + if (hMem == 0) { + return; + } + for (i = 0; i < NumItems; i++) { + aAdd[i] = (i & 1) * 2 - 1; + } + _DrawLabel(0, xPosGraph, yPosGraph); + TimeStart = GUIDEMO_GetTime(); + do { + TimeDiff = GUIDEMO_GetTime() - TimeStart; + // + // Draw diagram + // + _DrawDiagramAt(hMem, xPosGraph, yPosGraph, ayCur, Blend); + // + // Change blending area + // + Blend += AddBlend; + if ((Blend >= 164) || (Blend <= 8)) { + AddBlend = -AddBlend; + } + // + // Change values + // + for (i = 0; i < NumItems; i++) { + *(ayCur + i) += *(aAdd + i); + if ((*(ayCur + i) > (*(ayOrg + i) + 10)) || (*(ayCur + i) < (*(ayOrg + i) - 10))) { + *(aAdd + i) = -*(aAdd + i); + } + } + TimeStep = GUIDEMO_GetTime() - TimeStart; + if ((TimeStep - TimeDiff) < TIME_STEP) { + GUI_Delay(TIME_STEP - (TimeStep - TimeDiff)); + } else { + GUI_Exec(); + } + NextState = GUIDEMO_CheckCancel(); + } while ((TimeDiff < SHOW_TIME) && (NextState == 0)); + GUI_MEMDEV_Delete(hMem); +} + +/********************************************************************* +* +* Public code +* +********************************************************************** +*/ +/********************************************************************* +* +* GUIDEMO_BarGraph +*/ +void GUIDEMO_BarGraph(void) { + GUIDEMO_DrawBk(1); +#if GUI_SUPPORT_CURSOR + GUI_CURSOR_Hide(); +#endif + _DemoBarGraph(); +#if GUI_SUPPORT_CURSOR + GUI_CURSOR_Show(); +#endif +} + +#else + +void GUIDEMO_BarGraph(void) {} + +#endif + +/*************************** End of file ****************************/ + diff --git a/example/GUI/app/GUIDEMO_ColorBar.c b/example/GUI/app/GUIDEMO_ColorBar.c new file mode 100755 index 0000000000..e0c5979d4d --- /dev/null +++ b/example/GUI/app/GUIDEMO_ColorBar.c @@ -0,0 +1,197 @@ +/********************************************************************* +* Portions COPYRIGHT 2013 STMicroelectronics * +* Portions SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2013 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.22 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GUIDEMO_ColorBar.c +Purpose : Draws color bars +---------------------------------------------------------------------- +*/ + +/** + ****************************************************************************** + * @file GUIDEMO_ColorBar.c + * @author MCD Application Team + * @brief Draws color bars + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + + +#include "GUIDEMO.h" + +/********************************************************************* +* +* GUIDEMO_ShowColorBar +* +********************************************************************** +*/ + +#if (SHOW_GUIDEMO_COLORBAR) + +#define GRADIENT_START_X 60 +#define Y_START 43 +#define Y_STEP 10 + +#define TIME_PAUSE 500 +#define TIME_STEP 500 +#define TIME_RUN (TIME_PAUSE + TIME_STEP) * 6 + +void GUIDEMO_ColorBar(void) { + GUI_COLOR ColorStartBlack, ColorStartWhite; + char acText[80] = { 0 }; + int NumColors, BitsPerPixel, xSize, ySize; + int Time, TimeStart; + int Dir, Index; + + xSize = LCD_GetXSize(); + ySize = LCD_GetYSize(); + + GUIDEMO_HideInfoWin(); + GUIDEMO_ShowControlWin(); + GUI_Exec(); + GUIDEMO_DrawBk(1); + GUI_SetColor(GUI_BLACK); + GUIDEMO_DrawBk(1); + // + // Heading + // + + GUI_SetColor(GUI_WHITE); + GUI_SetFont(&GUI_FontRounded22); + GUI_DispStringHCenterAt("Color bars", xSize >> 1, 12); + GUI_SetFont(&GUI_Font16_ASCII); + // + // Colors + // + GUI_DispStringAt("Red", 1, Y_START); + GUI_DispStringAt("Green", 1, Y_START + Y_STEP * 2); + GUI_DispStringAt("Blue", 1, Y_START + Y_STEP * 4); + GUI_DispStringAt("Grey", 1, Y_START + Y_STEP * 5 + (Y_STEP >> 1)); + GUI_DispStringAt("Yellow", 1, Y_START + Y_STEP * 7); + GUI_DispStringAt("Cyan", 1, Y_START + Y_STEP * 9); + GUI_DispStringAt("Magenta", 1, Y_START + Y_STEP * 11); + // + // Additional Information + // + GUI_SetFont(&GUI_Font8_ASCII); + // + // LCD Controller + // + #ifdef LCD_CONTROLLER + GUIDEMO_AddStringToString(acText, "LCD Controller: "); + GUIDEMO_AddStringToString(acText, LCD_CONTROLLER); + GUI_DispStringAt (acText, 12, ySize - 45); + GUIDEMO_ClearText (acText); + #endif + // + // BPP and number of colors + // + BitsPerPixel = LCD_GetBitsPerPixel(); + GUIDEMO_AddIntToString (acText, BitsPerPixel); + GUIDEMO_AddStringToString(acText, " bpp"); + NumColors = LCD_GetDevCap(LCD_DEVCAP_NUMCOLORS); + if (NumColors) { + GUIDEMO_AddStringToString(acText, ", "); + GUIDEMO_AddIntToString (acText, NumColors); + GUIDEMO_AddStringToString(acText, " colors"); + } + GUI_DispStringAt(acText, 12, ySize - 25); + // + // Gradients + // + TimeStart = GUIDEMO_GetTime(); + while (((GUIDEMO_GetTime() - TimeStart) < TIME_RUN) && (GUIDEMO_CheckCancel() == 0)) { + Time = (GUIDEMO_GetTime() - TimeStart) % ((TIME_PAUSE + TIME_STEP) << 1); + Dir = Time / (TIME_PAUSE + TIME_STEP); + Time -= Dir * (TIME_PAUSE + TIME_STEP); + if (Time > TIME_PAUSE) { + continue; + } + Index = ((Time * 0xFF) / TIME_STEP) ^ (Dir * 0xFF); + ColorStartBlack = 0x000000 + 0x010101 * Index; + ColorStartWhite = 0xFFFFFF - ColorStartBlack; + GUI_DrawGradientH(GRADIENT_START_X, Y_START + Y_STEP * 0, xSize, (Y_START + Y_STEP * 1) - 1, GUI_RED, ColorStartBlack); + GUI_DrawGradientH(GRADIENT_START_X, Y_START + Y_STEP * 1, xSize, (Y_START + Y_STEP * 2) - 1, GUI_RED, ColorStartWhite); + GUI_DrawGradientH(GRADIENT_START_X, Y_START + Y_STEP * 2, xSize, (Y_START + Y_STEP * 3) - 1, GUI_GREEN, ColorStartBlack); + GUI_DrawGradientH(GRADIENT_START_X, Y_START + Y_STEP * 3, xSize, (Y_START + Y_STEP * 4) - 1, GUI_GREEN, ColorStartWhite); + GUI_DrawGradientH(GRADIENT_START_X, Y_START + Y_STEP * 4, xSize, (Y_START + Y_STEP * 5) - 1, GUI_BLUE, ColorStartBlack); + GUI_DrawGradientH(GRADIENT_START_X, Y_START + Y_STEP * 5, xSize, (Y_START + Y_STEP * 6) - 1, GUI_BLUE, ColorStartWhite); + GUI_DrawGradientH(GRADIENT_START_X, Y_START + Y_STEP * 6, xSize, (Y_START + Y_STEP * 7) - 1, GUI_GRAY, ColorStartBlack); + GUI_DrawGradientH(GRADIENT_START_X, Y_START + Y_STEP * 7, xSize, (Y_START + Y_STEP * 8) - 1, GUI_YELLOW, ColorStartWhite); + GUI_DrawGradientH(GRADIENT_START_X, Y_START + Y_STEP * 8, xSize, (Y_START + Y_STEP * 9) - 1, GUI_YELLOW, ColorStartBlack); + GUI_DrawGradientH(GRADIENT_START_X, Y_START + Y_STEP * 9, xSize, (Y_START + Y_STEP * 10) - 1, GUI_CYAN, ColorStartWhite); + GUI_DrawGradientH(GRADIENT_START_X, Y_START + Y_STEP * 10, xSize, (Y_START + Y_STEP * 11) - 1, GUI_CYAN, ColorStartBlack); + GUI_DrawGradientH(GRADIENT_START_X, Y_START + Y_STEP * 11, xSize, (Y_START + Y_STEP * 12) - 1, GUI_MAGENTA, ColorStartWhite); + GUI_DrawGradientH(GRADIENT_START_X, Y_START + Y_STEP * 12, xSize, (Y_START + Y_STEP * 13) - 1, GUI_MAGENTA, ColorStartBlack); + GUI_Exec(); + } +} + +#else + +void GUIDEMO_ColorBar(void) {} + +#endif + +/*************************** End of file ****************************/ diff --git a/example/GUI/app/GUIDEMO_Conf.c b/example/GUI/app/GUIDEMO_Conf.c new file mode 100755 index 0000000000..a3fa1dd21c --- /dev/null +++ b/example/GUI/app/GUIDEMO_Conf.c @@ -0,0 +1,174 @@ +/********************************************************************* +* Portions COPYRIGHT 2013 STMicroelectronics * +* Portions SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2013 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.22 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GUIDEMO_Conf.c +Purpose : Runtime configurability of the GUIDEMO +---------------------------------------------------------------------- +*/ + +/** + ****************************************************************************** + * @file GUIDEMO_Conf.c + * @author MCD Application Team + * @brief Runtime configurability of the GUIDEMO + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + + +/********************************************************************* +* +* Includes +* +********************************************************************** +*/ +#include "GUI.h" +#include "GUIDEMO.h" +#if GUIDEMO_USE_VNC + #include "GUI_VNC.h" +#endif + +/********************************************************************* +* +* Routine table +*/ +static void (* _apfTest[])(void) = { +#if (SHOW_GUIDEMO_SPEEDOMETER && GUI_SUPPORT_MEMDEV) +// GUIDEMO_Speedometer, +#endif +#if (SHOW_GUIDEMO_ZOOMANDROTATE && GUI_WINSUPPORT && GUI_SUPPORT_MEMDEV) +// GUIDEMO_ZoomAndRotate, +#endif +#if (SHOW_GUIDEMO_RADIALMENU && GUI_WINSUPPORT) +// GUIDEMO_RadialMenu, +#endif +#if (SHOW_GUIDEMO_SKINNING && GUI_WINSUPPORT && GUI_SUPPORT_MEMDEV) +// GUIDEMO_Skinning, +#endif +#if (SHOW_GUIDEMO_BARGRAPH && GUI_SUPPORT_MEMDEV) +// GUIDEMO_BarGraph, +#endif +#if (SHOW_GUIDEMO_FADING && GUI_SUPPORT_MEMDEV) +// GUIDEMO_Fading, +#endif +#if SHOW_GUIDEMO_AATEXT +// GUIDEMO_AntialiasedText, +#endif +#if (SHOW_GUIDEMO_TRANSPARENTDIALOG && GUI_WINSUPPORT && GUI_SUPPORT_MEMDEV) +// GUIDEMO_TransparentDialog, +#endif +#if (SHOW_GUIDEMO_WASHINGMACHINE && GUI_WINSUPPORT && GUI_SUPPORT_MEMDEV) +// GUIDEMO_WashingMachine, +#endif +#if (SHOW_GUIDEMO_ICONVIEW && GUI_WINSUPPORT && GUI_SUPPORT_MEMDEV) +// GUIDEMO_IconView, +#endif +#if (SHOW_GUIDEMO_IMAGEFLOW && GUI_WINSUPPORT && GUI_SUPPORT_MEMDEV) +// GUIDEMO_ImageFlow, +#endif +#if (SHOW_GUIDEMO_TREEVIEW && GUI_WINSUPPORT) +// GUIDEMO_Treeview, +#endif +#if (SHOW_GUIDEMO_LISTVIEW && GUI_WINSUPPORT) +// GUIDEMO_Listview, +#endif +#if SHOW_GUIDEMO_VSCREEN +// GUIDEMO_VScreen, +#endif +#if (SHOW_GUIDEMO_GRAPH && GUI_SUPPORT_MEMDEV) +// GUIDEMO_Graph, +#endif +#if SHOW_GUIDEMO_SPEED +// GUIDEMO_Speed, +#endif +#if SHOW_GUIDEMO_BITMAP +// GUIDEMO_Bitmap, +#endif +#if (SHOW_GUIDEMO_CURSOR && GUI_SUPPORT_CURSOR && GUI_SUPPORT_TOUCH) +// GUIDEMO_Cursor, +#endif +#if SHOW_GUIDEMO_COLORBAR +// GUIDEMO_ColorBar, +#endif +#if (SHOW_GUIDEMO_AUTOMOTIVE && GUI_SUPPORT_MEMDEV) +// GUIDEMO_Automotive, +#endif + 0 +}; + +/********************************************************************* +* +* GUIDEMO_Config +*/ +void GUIDEMO_Config(GUIDEMO_CONFIG * pConfig) { + pConfig->apFunc = _apfTest; + pConfig->NumDemos = GUI_COUNTOF(_apfTest); + pConfig->Flags = GUIDEMO_CF_SHOW_SPRITES | GUIDEMO_CF_USE_VNC | GUIDEMO_CF_USE_AUTO_BK; + #if GUIDEMO_USE_VNC + pConfig->pGUI_VNC_X_StartServer = GUI_VNC_X_StartServer; + #endif +} + +/*************************** End of file ****************************/ diff --git a/example/GUI/app/GUIDEMO_Graph.c b/example/GUI/app/GUIDEMO_Graph.c new file mode 100755 index 0000000000..8109b92186 --- /dev/null +++ b/example/GUI/app/GUIDEMO_Graph.c @@ -0,0 +1,415 @@ +/********************************************************************* +* Portions COPYRIGHT 2013 STMicroelectronics * +* Portions SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2013 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.22 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GUIDEMO_Graph.c +Purpose : Several GUIDEMO routines +---------------------------------------------------------------------- +*/ + +/** + ****************************************************************************** + * @file GUIDEMO_Graph.c + * @author MCD Application Team + * @brief Several GUIDEMO routines + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + + +#include "GUIDEMO.h" + +#if (SHOW_GUIDEMO_GRAPH && GUI_SUPPORT_MEMDEV) + +/********************************************************************* +* +* Configuration defines +* +********************************************************************** +*/ +#define MAX_GRAPH_SIZE_X 440 +#define MAX_GRAPH_SIZE_Y (MAX_GRAPH_SIZE_X * 11) / 20 + +#define DIST_TO_BORDER 10 +#define DIST_TO_WIN 5 + +#define BORDER_TOP 0 +#define BORDER_BOTTOM 9 +#define BORDER_LEFT 19 +#define BORDER_RIGHT 0 + +#define COLOR_BK GUI_DARKGRAY +#define COLOR_BORDER BK_COLOR_1 +#define COLOR_FRAME GUI_BLACK +#define COLOR_GRID GUI_GRAY + +#define SCALE_H_HEIGHT 4 + +#define TICK_DIST_H 25 +#define TICK_DIST_V 20 + +#define TIME_RUN 5000 +#define TIME_STEP 15 + +#define HEARTBEAT_TIME 1000 + +#define MAX_NUM_DATA_OBJ 5 + +#define GRAPH_DIV 9 // (2^9 = 512) If this value is changed _aWaves[] need to be changed too! +#define GRID_DIST_X 25 +#define GRID_DIST_Y 10 +#define GRID_OFF_Y 25 + +/********************************************************************* +* +* Typedef / Data +* +********************************************************************** +*/ +typedef struct { + char * Name; + int ScaleVOff; + int DataVOff; + int GridVOff; + void (* pfAddData)(GRAPH_DATA_Handle hData, int DataID); + int NumWaves; +} GRAPH_WAVE; + +static int _HeartBeat[] = { + 2, 4, 6, 8, 10, 6, 2, 0, 0, 0, + -8, 16, 40, 64, 88, 58, 28, -2, -32, -30, + -20, -10, 0, 2, 2, 4, 4, 6, 6, 8, + 8, 10, 12, 14, 16, 18, 20, 16, 12, 8, + 4, 2, 2, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +static GUI_COLOR _aColorData[MAX_NUM_DATA_OBJ] = { + 0x50C0FF, + 0xFFC050, + 0x50FFC0, + 0x800000, + 0x000080 +}; + +GRAPH_SCALE_Handle _hScaleH, _hScaleV; +static int _DataAdjust; + +/********************************************************************* +* +* Static functions +* +********************************************************************** +*/ +/********************************************************************* +* +* _AddData_Sine +*/ +static void _AddData_Sine(GRAPH_DATA_Handle hData, int DataID) { + static int x1000[MAX_NUM_DATA_OBJ]; + I32 SinHQ; + int Multi, Step; + + switch (DataID) { + case 0: + Multi = 70; + Step = 3; + break; + case 1: + Multi = 50; + Step = 1; + break; + case 2: + Multi = 30; + Step = 7; + break; + default: + return; + } + SinHQ = GUI__SinHQ(x1000[DataID]); + x1000[DataID] += 1000 * Step; + GRAPH_DATA_YT_AddValue(hData, ((SinHQ * Multi) >> 16) + _DataAdjust); +} + +/********************************************************************* +* +* _AddData_Heartbeat +*/ +static void _AddData_Heartbeat(GRAPH_DATA_Handle hData, int DataID) { + static int Index; + + GUI_USE_PARA(DataID); + GRAPH_DATA_YT_AddValue(hData, (_HeartBeat[Index]) + _DataAdjust); + if (++Index == GUI_COUNTOF(_HeartBeat)) { + Index = 0; + } +} + +/********************************************************************* +* +* DATA _aWave - Keep below _AddData-functions +*/ +GRAPH_WAVE _aWave[] = { + { "Heartbeat", // Name + 157, // Vertical scale offset in relation to GRAPH_DIV + 152, // Vertical data offset in relation to GRAPH_DIV + 21, // Vertical grid offset in relation to GRAPH_DIV + _AddData_Heartbeat, // Pointer to specific AddData function + 1 // Number of waves + }, + { "Sine Waves", + 265, + 253, + 23, + _AddData_Sine, + 3 + }, + 0 +}; + +/********************************************************************* +* +* _ShowGraph +*/ +static void _ShowGraph(GRAPH_Handle hGraph, GRAPH_DATA_Handle hData[], int DataCount, void (* pfAddData)(GRAPH_DATA_Handle hData, int DataID)) { + int Count, Data_xSize, xSize; + int TimeStart, TimeDiff, TimeStep; + int NextState, i, Flag; + + xSize = LCD_GetXSize(); + Data_xSize = xSize - (DIST_TO_BORDER << 1) - (BORDER_LEFT + BORDER_RIGHT); + Count = 0; + // + // Attach data objects + // + for (i = 0; i < DataCount; i++) { + GRAPH_AttachData(hGraph, hData[i]); + } + // + // Add values before GRAPH is displayed + // + while (Count < Data_xSize) { + for (i = 0; i < DataCount; i++) { + pfAddData(hData[i], i); + } + Count++; + } + // + // Add values depending on time + // + + TimeStart = GUIDEMO_GetTime(); + Flag = 1; + do { + TimeDiff = GUIDEMO_GetTime() - TimeStart; + for (i = 0; i < DataCount; i++) { + pfAddData(hData[i], i); + } + if (Flag) { + Flag = 0; + GUI_Exec(); + GRAPH_DetachScale(hGraph, _hScaleH); + GRAPH_DetachScale(hGraph, _hScaleV); + WM_ValidateWindow(hGraph); + } + NextState = GUIDEMO_CheckCancel(); + TimeStep = GUIDEMO_GetTime() - TimeStart; + if ((TimeStep - TimeDiff) < TIME_STEP) { + GUI_Delay(TIME_STEP - (TimeStep - TimeDiff)); + } + } while ((TimeDiff < TIME_RUN) && (NextState == 0)); + for (i = 0; i < DataCount; i++) { + GRAPH_DetachData(hGraph, hData[i]); + } + GUIDEMO_NotifyStartNext(); +} + +/********************************************************************* +* +* _cbBk +*/ +static void _cbBk(WM_MESSAGE * pMsg) { + switch (pMsg->MsgId) { + case WM_PAINT: + GUIDEMO_DrawBk(1); + break; + default: + WM_DefaultProc(pMsg); + } +} + +/********************************************************************* +* +* _GraphDemo +*/ +static void _GraphDemo(void) { + const WIDGET_EFFECT * pEffectOld; + GRAPH_Handle hGraph; + GRAPH_DATA_Handle hData[MAX_NUM_DATA_OBJ]; + int xSize, ySize, i; + int Graph_xSize, Graph_ySize, Data_ySize; + int Graph_xPos, Graph_yPos; + + xSize = LCD_GetXSize(); + ySize = LCD_GetYSize(); + pEffectOld = WIDGET_SetDefaultEffect(&WIDGET_Effect_Simple); + // + // Set Callback function for background window + // + WM_SetCallback(WM_HBKWIN, _cbBk); + // + // Determine size of GRAPH + // + Graph_xSize = xSize - (DIST_TO_BORDER << 1); // xsize = Screen size subtracting twice the distance to the border of the screen + Graph_ySize = ySize - INFO_SIZE_Y - (DIST_TO_WIN << 1); // ysize = Screen size subtracting the window sizes and twice the distance to the windows + if (Graph_ySize > MAX_GRAPH_SIZE_Y) { + Graph_ySize = MAX_GRAPH_SIZE_Y; + if (Graph_xSize > (Graph_ySize * 20) / 11) { + Graph_xSize = (Graph_ySize * 20) / 11; + } + } + // + // Create and configure GRAPH_WIDGET + // + Graph_xPos = (xSize - Graph_xSize) >> 1; + Graph_yPos = (ySize - Graph_ySize) >> 1; + if (Graph_yPos < INFO_SIZE_Y + DIST_TO_WIN) { + Graph_yPos = INFO_SIZE_Y + DIST_TO_WIN; + } + hGraph = GRAPH_CreateEx(Graph_xPos, Graph_yPos, Graph_xSize, Graph_ySize, WM_HBKWIN, WM_CF_SHOW | WM_CF_CONST_OUTLINE, 0, 0); + GRAPH_SetBorder(hGraph, BORDER_LEFT, BORDER_TOP, BORDER_RIGHT, BORDER_BOTTOM); + WM_SetHasTrans (hGraph); + GRAPH_SetColor (hGraph, COLOR_BK, GRAPH_CI_BK); + GRAPH_SetColor (hGraph, COLOR_BORDER, GRAPH_CI_BORDER); + GRAPH_SetColor (hGraph, COLOR_FRAME, GRAPH_CI_FRAME); + GRAPH_SetColor (hGraph, COLOR_GRID, GRAPH_CI_GRID); + // + // Adjust grid + // + GRAPH_SetGridVis (hGraph, 1); + GRAPH_SetGridDistX(hGraph, GRID_DIST_X); + GRAPH_SetGridDistY(hGraph, GRID_DIST_Y); + WM_BringToBottom (hGraph); + // + // Create and configure GRAPH_DATA_YT object + // + for (i = 0; i < MAX_NUM_DATA_OBJ; i++) { + hData[i] = GRAPH_DATA_YT_Create(_aColorData[i], xSize - (DIST_TO_BORDER << 1) - BORDER_LEFT, 0, 0); + } + Data_ySize = Graph_ySize - BORDER_BOTTOM; + // + // Create and configure GRAPH_SCALE objects + // + _hScaleH = GRAPH_SCALE_Create(BORDER_BOTTOM >> 1, GUI_TA_VCENTER, GRAPH_SCALE_CF_HORIZONTAL, TICK_DIST_H); + _hScaleV = GRAPH_SCALE_Create(BORDER_LEFT >> 1, GUI_TA_HCENTER, GRAPH_SCALE_CF_VERTICAL, TICK_DIST_V); + GRAPH_SCALE_SetPos(_hScaleH, Graph_ySize - SCALE_H_HEIGHT); + GRAPH_SCALE_SetOff(_hScaleH, -5); + // + // Show some graphs + // + i = 0; + while (_aWave[i].pfAddData != 0) { + GUIDEMO_ShowInfo(_aWave[i].Name); + GRAPH_AttachScale(hGraph, _hScaleH); + GRAPH_AttachScale(hGraph, _hScaleV); + _DataAdjust = (Data_ySize * _aWave[i].DataVOff) >> GRAPH_DIV; + GRAPH_SetGridOffY (hGraph, (Data_ySize * _aWave[i].GridVOff) >> GRAPH_DIV); + GRAPH_SCALE_SetOff(_hScaleV, (((Data_ySize - BORDER_BOTTOM) * _aWave[i].ScaleVOff) >> GRAPH_DIV)); + _ShowGraph(hGraph, hData, _aWave[i].NumWaves, _aWave[i].pfAddData); + i++; + } + // + // Clean up + // + GRAPH_DetachScale(hGraph, _hScaleH); + GRAPH_DetachScale(hGraph, _hScaleV); + GRAPH_SCALE_Delete(_hScaleH); + GRAPH_SCALE_Delete(_hScaleV); + for (i = 0; i < MAX_NUM_DATA_OBJ; i++) { + GRAPH_DATA_YT_Delete(hData[i]); + } + WM_DeleteWindow(hGraph); + WIDGET_SetDefaultEffect(pEffectOld); +} + +/********************************************************************* +* +* Public functions +* +********************************************************************** +*/ +void GUIDEMO_Graph(void) { + GUIDEMO_ShowInfoWin(); + _GraphDemo(); + GUIDEMO_NotifyStartNext(); +} + +#else + +void GUIDEMO_Graph(void) {} + +#endif + +/*************************** End of file ****************************/ diff --git a/example/GUI/app/GUIDEMO_Intro.c b/example/GUI/app/GUIDEMO_Intro.c new file mode 100755 index 0000000000..c5af8b9282 --- /dev/null +++ b/example/GUI/app/GUIDEMO_Intro.c @@ -0,0 +1,114 @@ +/********************************************************************* +* Portions COPYRIGHT 2013 STMicroelectronics * +* Portions SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2013 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.22 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GUIDEMO_Intro.c +Purpose : Introduction for emWin generic demo + (This is also a good file to demo and explain basic + emWin features by setting breakpoints) +---------------------------------------------------------------------- +*/ + +/** + ****************************************************************************** + * @file GUIDEMO_Intro.c + * @author MCD Application Team + * @brief Introduction for emWin generic demo + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * 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 "GUIDEMO.h" + +/********************************************************************* +* +* Defines +*/ +#define SCREEN_DIV 6 // 2^6 = 64 + +#define FACTOR_EMWIN 4 +#define FACTOR_DESC 11 +#define FACTOR_ANY_COMP 22 +#define FACTOR_VERSION 31 +#define FACTOR_LOGO 38 +#define FACTOR_WWW 56 + +#define DIST_ANY_COMP 18 + +extern GUI_CONST_STORAGE GUI_BITMAP bmAliOS_Things_logo; +/********************************************************************* +* +* GUIDEMO_Intro +* +********************************************************************** +*/ +void GUIDEMO_Intro(void) { + GUI_DrawBitmap(&bmAliOS_Things_logo, 60, 60); +// GUI_JPEG_Draw(&_acAliOS,sizeof(_acAliOS), 60, 60); + GUIDEMO_Delay(5000); +} + +/*************************** End of file ****************************/ diff --git a/example/GUI/app/GUIDEMO_Resource.c b/example/GUI/app/GUIDEMO_Resource.c new file mode 100755 index 0000000000..8af2a2dc07 --- /dev/null +++ b/example/GUI/app/GUIDEMO_Resource.c @@ -0,0 +1,3803 @@ +/********************************************************************* +* Portions COPYRIGHT 2013 STMicroelectronics * +* Portions SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2013 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.22 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GUIDEMO_Resource.c +Purpose : Contains fonts and bitmaps used in the demo. +---------------------------END-OF-HEADER------------------------------ +*/ + +/** + ****************************************************************************** + * @file GUIDEMO_Resource.c + * @author MCD Application Team + * @brief Contains fonts and bitmaps used in the demo. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + + +#include "GUIDEMO.h" + +#ifndef GUI_CONST_STORAGE + #define GUI_CONST_STORAGE const +#endif + +/********************************************************************* +* * +* Fonts * +* * +********************************************************************** +*/ +/********************************************************************* +* * +* GUI_FontD6x8 * +* * +* Used in GUIDEMO.c (PROGBAR) * +* * +********************************************************************** +*/ +static GUI_CONST_STORAGE unsigned char acFontD6x8[16][8] = { + { + _XXX____, + X___X___, + X___X___, + X___X___, + X___X___, + X___X___, + X___X___, + _XXX____, + },{ + __X_____, + _XX_____, + __X_____, + __X_____, + __X_____, + __X_____, + __X_____, + _XXX____, + },{ + _XXX____, + X___X___, + ____X___, + ___X____, + __X_____, + _X______, + X_______, + XXXXX___, + },{ + _XXX____, + X___X___, + ____X___, + ___X____, + ___X____, + ____X___, + X___X___, + _XXX____, + },{ + ___X____, + __XX____, + _X_X____, + X__X____, + XXXXX___, + ___X____, + ___X____, + ___X____, + },{ + XXXXX___, + X_______, + X_______, + XXXX____, + ____X___, + ____X___, + X___X___, + _XXX____, + },{ + __XX____, + _X______, + X_______, + XXXX____, + X___X___, + X___X___, + X___X___, + _XXX____, + },{ + XXXXX___, + ____X___, + ____X___, + ___X____, + __X_____, + _X______, + _X______, + _X______, + },{ + _XXX____, + X___X___, + X___X___, + _XXX____, + X___X___, + X___X___, + X___X___, + _XXX____, + },{ + _XXX____, + X___X___, + X___X___, + _XXXX___, + ____X___, + ____X___, + ___X____, + _XX_____, + },{ + ________, + ________, + __X_____, + __X_____, + XXXXX___, + __X_____, + __X_____, + ________, + },{ + ________, + ________, + ________, + ________, + XXXXX___, + ________, + ________, + ________, + },{ + ________, + ________, + ________, + ________, + ________, + ________, + ________, + ________, + },{ + ________, + ________, + ________, + ________, + ________, + ________, + _XX_____, + _XX_____, + },{ + ________, + ________, + _XX_____, + _XX_____, + ________, + _XX_____, + _XX_____, + ________ + },{ + ________, + _XX___X_, + _XX__X__, + ____X___, + ___X____, + __X__XX_, + _X___XX_, + ________} + +}; + +static GUI_CONST_STORAGE GUI_CHARINFO GUI_FontD6x8_CharInfo[16] = { + { 6, 6, 1, acFontD6x8[12] } /* code 0020 ' ' */ + ,{ 6, 6, 1, acFontD6x8[15] } /* code 0025 '%' */ + ,{ 6, 6, 1, acFontD6x8[10] } /* code 002B '+' */ + ,{ 6, 6, 1, acFontD6x8[11] } /* code 002D '-' */ + ,{ 6, 6, 1, acFontD6x8[13] } /* code 002E '.' */ + ,{ 6, 6, 1, acFontD6x8[0] } /* code 0030 '0' */ + ,{ 6, 6, 1, acFontD6x8[1] } /* code 0031 '1' */ + ,{ 6, 6, 1, acFontD6x8[2] } /* code 0032 '2' */ + ,{ 6, 6, 1, acFontD6x8[3] } /* code 0033 '3' */ + ,{ 6, 6, 1, acFontD6x8[4] } /* code 0034 '4' */ + ,{ 6, 6, 1, acFontD6x8[5] } /* code 0035 '5' */ + ,{ 6, 6, 1, acFontD6x8[6] } /* code 0036 '6' */ + ,{ 6, 6, 1, acFontD6x8[7] } /* code 0037 '7' */ + ,{ 6, 6, 1, acFontD6x8[8] } /* code 0038 '8' */ + ,{ 6, 6, 1, acFontD6x8[9] } /* code 0039 '9' */ + ,{ 6, 6, 1, acFontD6x8[14] } /* code 003A ':' */ +}; + +static GUI_CONST_STORAGE GUI_FONT_PROP GUI_FontD6x8_Prop5 = { + 0x0030 /* first character */ + ,0x003A /* last character */ + ,&GUI_FontD6x8_CharInfo[ 5] /* address of first character */ + ,(GUI_CONST_STORAGE GUI_FONT_PROP*)0 /* pointer to next GUI_FONT_PROP */ +}; + +static GUI_CONST_STORAGE GUI_FONT_PROP GUI_FontD6x8_Prop4 = { + 0x002D /* first character */ + ,0x002E /* last character */ + ,&GUI_FontD6x8_CharInfo[ 3] /* address of first character */ + ,&GUI_FontD6x8_Prop5 /* pointer to next GUI_FONT_PROP */ +}; + +static GUI_CONST_STORAGE GUI_FONT_PROP GUI_FontD6x8_Prop3 = { + 0x002B /* first character */ + ,0x002B /* last character */ + ,&GUI_FontD6x8_CharInfo[ 2] /* address of first character */ + ,&GUI_FontD6x8_Prop4 /* pointer to next GUI_FONT_PROP */ +}; + +static GUI_CONST_STORAGE GUI_FONT_PROP GUI_FontD6x8_Prop2 = { + 0x0025 /* first character */ + ,0x0025 /* last character */ + ,&GUI_FontD6x8_CharInfo[ 1] /* address of first character */ + ,&GUI_FontD6x8_Prop3 /* pointer to next GUI_FONT_PROP */ +}; + +static GUI_CONST_STORAGE GUI_FONT_PROP GUI_FontD6x8_Prop1 = { + 0x0020 /* first character */ + ,0x0020 /* last character */ + ,&GUI_FontD6x8_CharInfo[ 0] /* address of first character */ + ,&GUI_FontD6x8_Prop2 /* pointer to next GUI_FONT_PROP */ +}; + +GUI_CONST_STORAGE GUI_FONT GUI_FontD6x8 = { + GUI_FONTTYPE_PROP /* type of font */ + ,8 /* height of font */ + ,8 /* space of font y */ + ,1 /* magnification x */ + ,1 /* magnification y */ + ,{&GUI_FontD6x8_Prop1} + ,8 /* Baseline */ + ,0 /* LHeight */ + ,8 /* CHeight */ +}; + +/********************************************************************* +* * +* GUI_FontRounded16 * +* * +* Used in * +* - GUIDEMO_Automotive.c * +* - GUIDEMO_Cursor.c * +* - GUIDEMO_Speedometer.c * +* * +********************************************************************** +*/ +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0020[ 1] = { /* code 0020, SPACE */ + 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0021[ 22] = { /* code 0021, EXCLAMATION MARK */ + 0x56, 0x00, + 0xFF, 0x10, + 0xFF, 0x20, + 0xEF, 0x10, + 0xCE, 0x00, + 0xAC, 0x00, + 0x89, 0x00, + 0x01, 0x00, + 0xCD, 0x10, + 0xCE, 0x10, + 0x01, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0022[ 15] = { /* code 0022, QUOTATION MARK */ + 0x36, 0x07, 0x30, + 0x9F, 0x3F, 0x90, + 0x9F, 0x4F, 0x90, + 0x9F, 0x3F, 0x90, + 0x24, 0x05, 0x20 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0023[ 44] = { /* code 0023, NUMBER SIGN */ + 0x00, 0x03, 0x02, 0x10, + 0x00, 0x5E, 0x0D, 0x60, + 0x00, 0x8C, 0x0F, 0x40, + 0x07, 0xDE, 0xAF, 0xA1, + 0x09, 0xFD, 0xDF, 0xB2, + 0x00, 0xE6, 0x7D, 0x00, + 0x3B, 0xFC, 0xDE, 0x90, + 0x19, 0xF8, 0xDC, 0x50, + 0x05, 0xF0, 0xD7, 0x00, + 0x07, 0xC0, 0xF4, 0x00, + 0x00, 0x10, 0x10, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0024[ 48] = { /* code 0024, DOLLAR SIGN */ + 0x00, 0x17, 0x71, 0x00, + 0x08, 0xFF, 0xFF, 0x91, + 0x4F, 0x87, 0x79, 0xF7, + 0x7F, 0x36, 0x60, 0x62, + 0x3F, 0xEC, 0x92, 0x00, + 0x05, 0xCF, 0xFF, 0xB1, + 0x00, 0x06, 0x9B, 0xF7, + 0x9E, 0x06, 0x60, 0xF9, + 0x7F, 0x97, 0x78, 0xF6, + 0x09, 0xFF, 0xFF, 0x80, + 0x00, 0x17, 0x70, 0x00, + 0x00, 0x02, 0x20, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0025[ 66] = { /* code 0025, PERCENT SIGN */ + 0x02, 0x30, 0x00, 0x04, 0x30, 0x00, + 0x6F, 0xDC, 0x00, 0x1E, 0x30, 0x00, + 0xD8, 0x2F, 0x50, 0x79, 0x00, 0x00, + 0xF7, 0x0F, 0x61, 0xE2, 0x00, 0x00, + 0xBB, 0x7F, 0x28, 0x90, 0x00, 0x00, + 0x19, 0xB5, 0x2E, 0x16, 0xBA, 0x20, + 0x00, 0x00, 0x98, 0x3F, 0x6B, 0xB0, + 0x00, 0x02, 0xE1, 0x6F, 0x07, 0xF0, + 0x00, 0x0A, 0x70, 0x4F, 0x28, 0xD0, + 0x00, 0x3E, 0x00, 0x0B, 0xEF, 0x60, + 0x00, 0x24, 0x00, 0x00, 0x21, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0026[ 55] = { /* code 0026, AMPERSAND */ + 0x00, 0x05, 0x74, 0x00, 0x00, + 0x00, 0xCF, 0xEF, 0x80, 0x00, + 0x03, 0xF8, 0x0B, 0xF0, 0x00, + 0x02, 0xFB, 0x2D, 0xD0, 0x00, + 0x00, 0xAF, 0xFE, 0x40, 0x00, + 0x08, 0xFF, 0xFB, 0x07, 0x50, + 0x3F, 0xD2, 0xBF, 0xBF, 0x90, + 0x6F, 0x70, 0x1D, 0xFE, 0x20, + 0x3F, 0xD6, 0x7E, 0xFF, 0x50, + 0x08, 0xFF, 0xFB, 0x4E, 0x90, + 0x00, 0x12, 0x10, 0x01, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0027[ 5] = { /* code 0027, APOSTROPHE */ + 0x45, + 0xBD, + 0xBD, + 0xBD, + 0x33 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0028[ 26] = { /* code 0028, LEFT PARENTHESIS */ + 0x00, 0x37, + 0x00, 0xCB, + 0x04, 0xF7, + 0x09, 0xF2, + 0x0D, 0xD0, + 0x1F, 0xB0, + 0x2F, 0xB0, + 0x1F, 0xB0, + 0x0D, 0xD0, + 0x09, 0xF2, + 0x04, 0xF6, + 0x00, 0xCB, + 0x00, 0x37 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0029[ 26] = { /* code 0029, RIGHT PARENTHESIS */ + 0x36, 0x00, + 0x6F, 0x20, + 0x2F, 0x90, + 0x0C, 0xE0, + 0x08, 0xF3, + 0x06, 0xF6, + 0x06, 0xF7, + 0x06, 0xF6, + 0x08, 0xF3, + 0x0C, 0xE0, + 0x2F, 0x90, + 0x6F, 0x30, + 0x47, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_002A[ 18] = { /* code 002A, ASTERISK */ + 0x00, 0x33, 0x00, + 0x12, 0x79, 0x21, + 0x4F, 0xEE, 0xF5, + 0x02, 0xFE, 0x30, + 0x0A, 0x98, 0xA0, + 0x01, 0x00, 0x10 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_002B[ 32] = { /* code 002B, PLUS SIGN */ + 0x00, 0x03, 0x20, 0x00, + 0x00, 0x0D, 0xA0, 0x00, + 0x00, 0x0D, 0xB0, 0x00, + 0x37, 0x7E, 0xD7, 0x72, + 0xAF, 0xFF, 0xFF, 0xF7, + 0x02, 0x2D, 0xC2, 0x20, + 0x00, 0x0D, 0xB0, 0x00, + 0x00, 0x0B, 0x80, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_002C[ 8] = { /* code 002C, COMMA */ + 0x0D, 0xD0, + 0x0E, 0xF3, + 0x01, 0xD1, + 0x0B, 0x50 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_002D[ 9] = { /* code 002D, HYPHEN-MINUS */ + 0x17, 0x77, 0x30, + 0x7F, 0xFF, 0xB0, + 0x04, 0x65, 0x20 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_002E[ 6] = { /* code 002E, FULL STOP */ + 0x0D, 0xD0, + 0x0D, 0xD0, + 0x00, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_002F[ 33] = { /* code 002F, SOLIDUS */ + 0x00, 0x04, 0x50, + 0x00, 0x0D, 0x90, + 0x00, 0x4F, 0x30, + 0x00, 0xAD, 0x00, + 0x01, 0xF7, 0x00, + 0x06, 0xF2, 0x00, + 0x0C, 0xB0, 0x00, + 0x3F, 0x50, 0x00, + 0x8E, 0x00, 0x00, + 0xD9, 0x00, 0x00, + 0x20, 0x00, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0030[ 44] = { /* code 0030, DIGIT ZERO */ + 0x00, 0x03, 0x30, 0x00, + 0x03, 0xDF, 0xFD, 0x30, + 0x0D, 0xF7, 0x7F, 0xD0, + 0x4F, 0xA0, 0x0B, 0xF4, + 0x7F, 0x70, 0x07, 0xF6, + 0x7F, 0x60, 0x07, 0xF7, + 0x6F, 0x70, 0x07, 0xF6, + 0x4F, 0xA0, 0x0B, 0xF3, + 0x0D, 0xF7, 0x8F, 0xC0, + 0x02, 0xDF, 0xFC, 0x20, + 0x00, 0x02, 0x20, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0031[ 33] = { /* code 0031, DIGIT ONE */ + 0x00, 0x00, 0x30, + 0x00, 0x07, 0xF3, + 0x04, 0x8F, 0xF4, + 0x1F, 0xFF, 0xF4, + 0x01, 0x2C, 0xF4, + 0x00, 0x0B, 0xF4, + 0x00, 0x0B, 0xF4, + 0x00, 0x0B, 0xF4, + 0x00, 0x0B, 0xF4, + 0x00, 0x0A, 0xF2, + 0x00, 0x00, 0x10 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0032[ 40] = { /* code 0032, DIGIT TWO */ + 0x00, 0x13, 0x30, 0x00, + 0x06, 0xEF, 0xFE, 0x50, + 0x4F, 0xD6, 0x7F, 0xF1, + 0x7F, 0x50, 0x0B, 0xF4, + 0x25, 0x00, 0x1E, 0xF1, + 0x00, 0x05, 0xEF, 0x70, + 0x01, 0xBF, 0xC4, 0x00, + 0x1D, 0xF7, 0x00, 0x00, + 0x7F, 0xD9, 0x99, 0x92, + 0x6F, 0xFF, 0xFF, 0xF3 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0033[ 44] = { /* code 0033, DIGIT THREE */ + 0x00, 0x13, 0x30, 0x00, + 0x08, 0xFF, 0xFD, 0x20, + 0x4F, 0xC6, 0x8F, 0xB0, + 0x3B, 0x20, 0x0F, 0xC0, + 0x00, 0x07, 0xAF, 0x60, + 0x00, 0x1E, 0xFF, 0x70, + 0x00, 0x00, 0x3F, 0xF1, + 0x7E, 0x20, 0x0E, 0xF1, + 0x7F, 0xC6, 0xAF, 0xC0, + 0x09, 0xFF, 0xFB, 0x20, + 0x00, 0x12, 0x10, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0034[ 44] = { /* code 0034, DIGIT FOUR */ + 0x00, 0x00, 0x13, 0x00, + 0x00, 0x01, 0xCF, 0x30, + 0x00, 0x0A, 0xFF, 0x40, + 0x00, 0x7E, 0xBF, 0x40, + 0x03, 0xF5, 0x9F, 0x40, + 0x1E, 0x90, 0x9F, 0x40, + 0xAF, 0xA9, 0xDF, 0xB4, + 0x9D, 0xDD, 0xEF, 0xE7, + 0x00, 0x00, 0x9F, 0x40, + 0x00, 0x00, 0x8F, 0x30, + 0x00, 0x00, 0x02, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0035[ 44] = { /* code 0035, DIGIT FIVE */ + 0x00, 0x22, 0x22, 0x00, + 0x0C, 0xFF, 0xFF, 0x90, + 0x1F, 0xC9, 0x99, 0x40, + 0x3F, 0x50, 0x00, 0x00, + 0x6F, 0xCF, 0xFB, 0x10, + 0x5F, 0xA6, 0xBF, 0xB0, + 0x00, 0x00, 0x0E, 0xF1, + 0x37, 0x00, 0x0E, 0xF0, + 0x8F, 0xB6, 0xAF, 0xB0, + 0x1B, 0xFF, 0xFA, 0x10, + 0x00, 0x12, 0x10, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0036[ 44] = { /* code 0036, DIGIT SIX */ + 0x00, 0x03, 0x41, 0x00, + 0x02, 0xCF, 0xFF, 0x80, + 0x0C, 0xF5, 0x3D, 0xF0, + 0x3F, 0x90, 0x01, 0x30, + 0x6F, 0x9B, 0xDB, 0x40, + 0x7F, 0xF9, 0x8E, 0xE2, + 0x7F, 0x90, 0x08, 0xF6, + 0x5F, 0x90, 0x08, 0xF6, + 0x0D, 0xE7, 0x6E, 0xF2, + 0x03, 0xDF, 0xFE, 0x50, + 0x00, 0x02, 0x20, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0037[ 44] = { /* code 0037, DIGIT SEVEN */ + 0x02, 0x22, 0x22, 0x10, + 0xCF, 0xFF, 0xFF, 0xF1, + 0x59, 0x99, 0xAF, 0xD0, + 0x00, 0x00, 0xAE, 0x20, + 0x00, 0x05, 0xF6, 0x00, + 0x00, 0x0D, 0xD0, 0x00, + 0x00, 0x6F, 0x70, 0x00, + 0x00, 0xCF, 0x20, 0x00, + 0x02, 0xFD, 0x00, 0x00, + 0x03, 0xF9, 0x00, 0x00, + 0x00, 0x20, 0x00, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0038[ 44] = { /* code 0038, DIGIT EIGHT */ + 0x00, 0x13, 0x31, 0x00, + 0x06, 0xFF, 0xFE, 0x60, + 0x2F, 0xD3, 0x4D, 0xF1, + 0x3F, 0xA0, 0x0A, 0xF2, + 0x0B, 0xE8, 0x8F, 0xB0, + 0x09, 0xFD, 0xDF, 0x90, + 0x6F, 0xA0, 0x0B, 0xF5, + 0x7F, 0x60, 0x08, 0xF7, + 0x3F, 0xE6, 0x6E, 0xF3, + 0x06, 0xEF, 0xFE, 0x60, + 0x00, 0x02, 0x20, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0039[ 44] = { /* code 0039, DIGIT NINE */ + 0x00, 0x13, 0x30, 0x00, + 0x06, 0xFF, 0xFD, 0x30, + 0x3F, 0xD5, 0x5E, 0xD0, + 0x7F, 0x70, 0x0A, 0xF4, + 0x7F, 0x80, 0x0B, 0xF7, + 0x2E, 0xF9, 0xAF, 0xF7, + 0x03, 0xBD, 0xAA, 0xF5, + 0x04, 0x10, 0x0A, 0xF2, + 0x0F, 0xD4, 0x7F, 0xB0, + 0x07, 0xFF, 0xFB, 0x10, + 0x00, 0x12, 0x10, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_003A[ 16] = { /* code 003A, COLON */ + 0x09, 0x90, + 0x1F, 0xF0, + 0x03, 0x30, + 0x00, 0x00, + 0x00, 0x00, + 0x0D, 0xD0, + 0x0D, 0xD0, + 0x00, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_003B[ 18] = { /* code 003B, SEMICOLON */ + 0x09, 0x90, + 0x1F, 0xF0, + 0x03, 0x30, + 0x00, 0x00, + 0x00, 0x00, + 0x0D, 0xD0, + 0x0E, 0xF3, + 0x01, 0xD1, + 0x0B, 0x50 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_003C[ 28] = { /* code 003C, LESS-THAN SIGN */ + 0x00, 0x00, 0x28, 0xF6, + 0x00, 0x3A, 0xFF, 0xA2, + 0x3B, 0xFE, 0x82, 0x00, + 0x9F, 0xF5, 0x00, 0x00, + 0x06, 0xDF, 0xD7, 0x10, + 0x00, 0x05, 0xCF, 0xE4, + 0x00, 0x00, 0x03, 0x94 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_003D[ 20] = { /* code 003D, EQUALS SIGN */ + 0xAF, 0xFF, 0xFF, 0xF7, + 0x49, 0x99, 0x99, 0x93, + 0x00, 0x00, 0x00, 0x00, + 0x8D, 0xDD, 0xDD, 0xD6, + 0x59, 0x99, 0x99, 0x93 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_003E[ 28] = { /* code 003E, GREATER-THAN SIGN */ + 0x9E, 0x71, 0x00, 0x00, + 0x3B, 0xFF, 0x82, 0x00, + 0x00, 0x39, 0xFF, 0xA2, + 0x00, 0x00, 0x8F, 0xF7, + 0x02, 0x8E, 0xFB, 0x50, + 0x7F, 0xFA, 0x30, 0x00, + 0x58, 0x20, 0x00, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_003F[ 44] = { /* code 003F, QUESTION MARK */ + 0x00, 0x57, 0x72, 0x00, + 0x0B, 0xFF, 0xFF, 0x50, + 0x5F, 0x90, 0x4F, 0xC0, + 0x39, 0x10, 0x3F, 0xD0, + 0x00, 0x03, 0xEF, 0x50, + 0x00, 0x2E, 0xE4, 0x00, + 0x00, 0x4F, 0x50, 0x00, + 0x00, 0x01, 0x00, 0x00, + 0x00, 0x5F, 0x60, 0x00, + 0x00, 0x5F, 0x70, 0x00, + 0x00, 0x01, 0x00, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0040[ 55] = { /* code 0040, COMMERCIAL AT */ + 0x00, 0x03, 0x79, 0x73, 0x00, + 0x01, 0xBF, 0xB9, 0xBF, 0x90, + 0x0B, 0xE3, 0x13, 0x03, 0xE7, + 0x3F, 0x46, 0xFF, 0xCE, 0x6E, + 0x8E, 0x1F, 0x94, 0xDC, 0x2F, + 0x9C, 0x5F, 0x20, 0xAA, 0x3D, + 0x7E, 0x4F, 0x75, 0xE9, 0xB7, + 0x2F, 0x7B, 0xFD, 0xFF, 0x80, + 0x06, 0xF7, 0x30, 0x27, 0x80, + 0x00, 0x5D, 0xFF, 0xFC, 0x30, + 0x00, 0x00, 0x24, 0x10, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0041[ 55] = { /* code 0041, LATIN CAPITAL LETTER A */ + 0x00, 0x05, 0x73, 0x00, 0x00, + 0x00, 0x1F, 0xFD, 0x00, 0x00, + 0x00, 0x7F, 0xFF, 0x30, 0x00, + 0x00, 0xCF, 0x7F, 0x90, 0x00, + 0x03, 0xFB, 0x1F, 0xE0, 0x00, + 0x09, 0xF7, 0x0B, 0xF4, 0x00, + 0x0E, 0xF9, 0x7B, 0xFA, 0x00, + 0x5F, 0xFF, 0xFF, 0xFF, 0x10, + 0xBF, 0x70, 0x00, 0xCF, 0x60, + 0xCF, 0x10, 0x00, 0x6F, 0x70, + 0x11, 0x00, 0x00, 0x02, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0042[ 40] = { /* code 0042, LATIN CAPITAL LETTER B */ + 0x36, 0x66, 0x63, 0x00, + 0xFF, 0xFF, 0xFF, 0xC1, + 0xFF, 0x54, 0x5E, 0xF6, + 0xFF, 0x20, 0x0A, 0xF6, + 0xFF, 0x87, 0x9F, 0xC1, + 0xFF, 0xDD, 0xEF, 0xD3, + 0xFF, 0x20, 0x08, 0xFB, + 0xFF, 0x20, 0x06, 0xFB, + 0xFF, 0xA9, 0xAF, 0xF7, + 0xCF, 0xFF, 0xFD, 0x80 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0043[ 55] = { /* code 0043, LATIN CAPITAL LETTER C */ + 0x00, 0x04, 0x89, 0x61, 0x00, + 0x01, 0xBF, 0xFF, 0xFE, 0x50, + 0x09, 0xFD, 0x42, 0x8F, 0xE0, + 0x1F, 0xF3, 0x00, 0x09, 0xA0, + 0x3F, 0xE0, 0x00, 0x00, 0x00, + 0x4F, 0xD0, 0x00, 0x00, 0x00, + 0x3F, 0xE0, 0x00, 0x02, 0x20, + 0x0E, 0xF6, 0x00, 0x1E, 0xF0, + 0x07, 0xFF, 0xA8, 0xDF, 0xB0, + 0x00, 0x7E, 0xFF, 0xFA, 0x10, + 0x00, 0x00, 0x33, 0x10, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0044[ 50] = { /* code 0044, LATIN CAPITAL LETTER D */ + 0x36, 0x66, 0x52, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0xB1, 0x00, + 0xFF, 0x76, 0x7D, 0xFA, 0x00, + 0xFF, 0x20, 0x03, 0xFF, 0x10, + 0xFF, 0x20, 0x00, 0xEF, 0x40, + 0xFF, 0x20, 0x00, 0xDF, 0x40, + 0xFF, 0x20, 0x00, 0xFF, 0x30, + 0xFF, 0x20, 0x07, 0xFE, 0x00, + 0xFF, 0xCB, 0xCF, 0xF5, 0x00, + 0xCF, 0xFF, 0xFB, 0x40, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0045[ 40] = { /* code 0045, LATIN CAPITAL LETTER E */ + 0x26, 0x66, 0x66, 0x51, + 0xEF, 0xFF, 0xFF, 0xF5, + 0xFF, 0x76, 0x66, 0x50, + 0xFF, 0x20, 0x00, 0x00, + 0xFF, 0xA9, 0x99, 0x50, + 0xFF, 0xFF, 0xFF, 0xA0, + 0xFF, 0x20, 0x00, 0x00, + 0xFF, 0x20, 0x00, 0x00, + 0xFF, 0xCB, 0xBB, 0xB3, + 0xBF, 0xFF, 0xFF, 0xF5 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0046[ 44] = { /* code 0046, LATIN CAPITAL LETTER F */ + 0x26, 0x66, 0x66, 0x40, + 0xEF, 0xFF, 0xFF, 0xF0, + 0xFF, 0x76, 0x66, 0x40, + 0xFF, 0x20, 0x00, 0x00, + 0xFF, 0x87, 0x77, 0x10, + 0xFF, 0xFF, 0xFF, 0x50, + 0xFF, 0x32, 0x22, 0x00, + 0xFF, 0x20, 0x00, 0x00, + 0xFF, 0x20, 0x00, 0x00, + 0xDF, 0x10, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0047[ 55] = { /* code 0047, LATIN CAPITAL LETTER G */ + 0x00, 0x03, 0x79, 0x73, 0x00, + 0x01, 0xBF, 0xFF, 0xFF, 0x80, + 0x09, 0xFD, 0x52, 0x5E, 0xF2, + 0x1F, 0xF3, 0x00, 0x04, 0x80, + 0x4F, 0xE0, 0x00, 0x00, 0x00, + 0x4F, 0xD0, 0x08, 0xFF, 0xF8, + 0x3F, 0xE0, 0x04, 0x9B, 0xF9, + 0x0E, 0xF6, 0x00, 0x09, 0xF9, + 0x07, 0xFF, 0x96, 0xAF, 0xF9, + 0x00, 0x7E, 0xFF, 0xF7, 0xC9, + 0x00, 0x00, 0x33, 0x10, 0x11 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0048[ 55] = { /* code 0048, LATIN CAPITAL LETTER H */ + 0x56, 0x00, 0x00, 0x56, 0x00, + 0xFF, 0x20, 0x00, 0xFF, 0x20, + 0xFF, 0x20, 0x00, 0xFF, 0x20, + 0xFF, 0x20, 0x00, 0xFF, 0x20, + 0xFF, 0xDD, 0xDD, 0xFF, 0x20, + 0xFF, 0xFF, 0xFF, 0xFF, 0x20, + 0xFF, 0x20, 0x00, 0xFF, 0x20, + 0xFF, 0x20, 0x00, 0xFF, 0x20, + 0xFF, 0x20, 0x00, 0xFF, 0x20, + 0xDE, 0x10, 0x00, 0xDE, 0x10, + 0x11, 0x00, 0x00, 0x11, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0049[ 22] = { /* code 0049, LATIN CAPITAL LETTER I */ + 0x56, 0x00, + 0xFF, 0x20, + 0xFF, 0x20, + 0xFF, 0x20, + 0xFF, 0x20, + 0xFF, 0x20, + 0xFF, 0x20, + 0xFF, 0x20, + 0xFF, 0x20, + 0xDE, 0x10, + 0x11, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_004A[ 44] = { /* code 004A, LATIN CAPITAL LETTER J */ + 0x00, 0x00, 0x27, 0x10, + 0x00, 0x00, 0x9F, 0x70, + 0x00, 0x00, 0x9F, 0x70, + 0x00, 0x00, 0x9F, 0x70, + 0x00, 0x00, 0x9F, 0x70, + 0x00, 0x00, 0x9F, 0x70, + 0x4A, 0x00, 0x9F, 0x70, + 0xBF, 0x30, 0xAF, 0x70, + 0x9F, 0xB7, 0xFF, 0x30, + 0x1C, 0xFF, 0xF8, 0x00, + 0x00, 0x33, 0x10, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_004B[ 44] = { /* code 004B, LATIN CAPITAL LETTER K */ + 0x56, 0x00, 0x02, 0x71, + 0xFF, 0x20, 0x2E, 0xF4, + 0xFF, 0x21, 0xDF, 0x80, + 0xFF, 0x3C, 0xF9, 0x00, + 0xFF, 0xDF, 0xE1, 0x00, + 0xFF, 0xFF, 0xF8, 0x00, + 0xFF, 0x84, 0xFF, 0x30, + 0xFF, 0x20, 0x9F, 0xD0, + 0xFF, 0x20, 0x1D, 0xF8, + 0xDE, 0x10, 0x05, 0xFA, + 0x11, 0x00, 0x00, 0x20 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_004C[ 40] = { /* code 004C, LATIN CAPITAL LETTER L */ + 0x56, 0x00, 0x00, 0x00, + 0xFF, 0x20, 0x00, 0x00, + 0xFF, 0x20, 0x00, 0x00, + 0xFF, 0x20, 0x00, 0x00, + 0xFF, 0x20, 0x00, 0x00, + 0xFF, 0x20, 0x00, 0x00, + 0xFF, 0x20, 0x00, 0x00, + 0xFF, 0x20, 0x00, 0x00, + 0xFF, 0xCB, 0xBB, 0x70, + 0xCF, 0xFF, 0xFF, 0x90 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_004D[ 55] = { /* code 004D, LATIN CAPITAL LETTER M */ + 0x67, 0x40, 0x00, 0x07, 0x72, + 0xFF, 0xE0, 0x00, 0x5F, 0xF9, + 0xFF, 0xF4, 0x00, 0xAF, 0xF9, + 0xFE, 0xF8, 0x00, 0xED, 0xF9, + 0xFD, 0xBD, 0x04, 0xF8, 0xF9, + 0xFD, 0x7F, 0x39, 0xE4, 0xF9, + 0xFD, 0x2F, 0x7D, 0xA4, 0xF9, + 0xFD, 0x0C, 0xEF, 0x54, 0xF9, + 0xFD, 0x07, 0xFF, 0x14, 0xF9, + 0xEB, 0x02, 0xFA, 0x03, 0xF8, + 0x11, 0x00, 0x10, 0x00, 0x20 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_004E[ 55] = { /* code 004E, LATIN CAPITAL LETTER N */ + 0x57, 0x10, 0x00, 0x57, 0x00, + 0xFF, 0xA0, 0x00, 0xDF, 0x20, + 0xFF, 0xF4, 0x00, 0xDF, 0x20, + 0xFF, 0xFD, 0x00, 0xDF, 0x20, + 0xFF, 0x7F, 0x70, 0xDF, 0x20, + 0xFF, 0x0D, 0xF2, 0xDF, 0x20, + 0xFF, 0x03, 0xFB, 0xDF, 0x20, + 0xFF, 0x00, 0x9F, 0xFF, 0x20, + 0xFF, 0x00, 0x1D, 0xFF, 0x20, + 0xEE, 0x00, 0x05, 0xFE, 0x10, + 0x11, 0x00, 0x00, 0x11, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_004F[ 55] = { /* code 004F, LATIN CAPITAL LETTER O */ + 0x00, 0x04, 0x89, 0x72, 0x00, + 0x01, 0xCF, 0xFF, 0xFF, 0x80, + 0x0B, 0xFC, 0x42, 0x6E, 0xF5, + 0x3F, 0xF1, 0x00, 0x07, 0xFB, + 0x6F, 0xB0, 0x00, 0x02, 0xFF, + 0x6F, 0xB0, 0x00, 0x02, 0xFF, + 0x5F, 0xD0, 0x00, 0x04, 0xFD, + 0x1F, 0xF4, 0x00, 0x0A, 0xF9, + 0x07, 0xFF, 0x97, 0xCF, 0xE2, + 0x00, 0x7E, 0xFF, 0xFB, 0x20, + 0x00, 0x00, 0x33, 0x10, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0050[ 44] = { /* code 0050, LATIN CAPITAL LETTER P */ + 0x36, 0x66, 0x63, 0x00, + 0xFF, 0xFF, 0xFF, 0xC1, + 0xFF, 0x54, 0x5D, 0xF8, + 0xFF, 0x20, 0x06, 0xFB, + 0xFF, 0x32, 0x2B, 0xF9, + 0xFF, 0xFF, 0xFF, 0xE2, + 0xFF, 0xA9, 0x87, 0x10, + 0xFF, 0x20, 0x00, 0x00, + 0xFF, 0x20, 0x00, 0x00, + 0xDE, 0x10, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0051[ 55] = { /* code 0051, LATIN CAPITAL LETTER Q */ + 0x00, 0x04, 0x89, 0x72, 0x00, + 0x01, 0xCF, 0xFF, 0xFF, 0x80, + 0x0B, 0xFC, 0x42, 0x6E, 0xF5, + 0x3F, 0xF1, 0x00, 0x07, 0xFB, + 0x6F, 0xB0, 0x00, 0x02, 0xFF, + 0x6F, 0xB0, 0x00, 0x02, 0xFF, + 0x5F, 0xD0, 0x03, 0x34, 0xFE, + 0x1F, 0xF4, 0x09, 0xFC, 0xF9, + 0x07, 0xFF, 0x98, 0xFF, 0xE2, + 0x00, 0x7E, 0xFF, 0xFD, 0xF6, + 0x00, 0x00, 0x33, 0x10, 0x76 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0052[ 44] = { /* code 0052, LATIN CAPITAL LETTER R */ + 0x36, 0x66, 0x65, 0x10, + 0xFF, 0xFF, 0xFF, 0xF5, + 0xFF, 0x54, 0x4A, 0xFD, + 0xFF, 0x20, 0x02, 0xFF, + 0xFF, 0x54, 0x49, 0xFA, + 0xFF, 0xFF, 0xFF, 0xD1, + 0xFF, 0x76, 0x6D, 0xF8, + 0xFF, 0x20, 0x06, 0xFA, + 0xFF, 0x20, 0x05, 0xFC, + 0xDE, 0x10, 0x02, 0xFD, + 0x11, 0x00, 0x00, 0x11 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0053[ 55] = { /* code 0053, LATIN CAPITAL LETTER S */ + 0x00, 0x48, 0x97, 0x10, 0x00, + 0x0A, 0xFF, 0xFF, 0xF6, 0x00, + 0x4F, 0xD3, 0x26, 0xFE, 0x00, + 0x6F, 0xC0, 0x00, 0x44, 0x00, + 0x2F, 0xFE, 0xB8, 0x30, 0x00, + 0x03, 0xBF, 0xFF, 0xFA, 0x00, + 0x00, 0x00, 0x48, 0xFF, 0x30, + 0x4F, 0x50, 0x00, 0xCF, 0x50, + 0x3F, 0xF8, 0x69, 0xFE, 0x10, + 0x06, 0xEF, 0xFF, 0xD4, 0x00, + 0x00, 0x02, 0x42, 0x00, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0054[ 55] = { /* code 0054, LATIN CAPITAL LETTER T */ + 0x26, 0x66, 0x66, 0x65, 0x10, + 0xCF, 0xFF, 0xFF, 0xFF, 0x70, + 0x37, 0x7D, 0xFA, 0x76, 0x10, + 0x00, 0x0B, 0xF6, 0x00, 0x00, + 0x00, 0x0B, 0xF6, 0x00, 0x00, + 0x00, 0x0B, 0xF6, 0x00, 0x00, + 0x00, 0x0B, 0xF6, 0x00, 0x00, + 0x00, 0x0B, 0xF6, 0x00, 0x00, + 0x00, 0x0B, 0xF6, 0x00, 0x00, + 0x00, 0x09, 0xF4, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x00, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0055[ 55] = { /* code 0055, LATIN CAPITAL LETTER U */ + 0x56, 0x00, 0x00, 0x56, 0x00, + 0xFF, 0x20, 0x00, 0xFF, 0x20, + 0xFF, 0x20, 0x00, 0xFF, 0x20, + 0xFF, 0x20, 0x00, 0xFF, 0x20, + 0xFF, 0x20, 0x00, 0xFF, 0x20, + 0xFF, 0x20, 0x00, 0xFF, 0x20, + 0xFF, 0x20, 0x00, 0xFF, 0x20, + 0xEF, 0x40, 0x02, 0xFF, 0x10, + 0x8F, 0xE8, 0x8D, 0xFA, 0x00, + 0x09, 0xFF, 0xFF, 0xA1, 0x00, + 0x00, 0x13, 0x31, 0x00, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0056[ 55] = { /* code 0056, LATIN CAPITAL LETTER V */ + 0x57, 0x00, 0x00, 0x37, 0x10, + 0xDF, 0x50, 0x00, 0xCF, 0x40, + 0x9F, 0x90, 0x02, 0xFE, 0x10, + 0x3F, 0xE0, 0x07, 0xFA, 0x00, + 0x0D, 0xF3, 0x0B, 0xF4, 0x00, + 0x08, 0xF8, 0x1F, 0xD0, 0x00, + 0x02, 0xFC, 0x6F, 0x80, 0x00, + 0x00, 0xCF, 0xCF, 0x30, 0x00, + 0x00, 0x7F, 0xFC, 0x00, 0x00, + 0x00, 0x2E, 0xF6, 0x00, 0x00, + 0x00, 0x01, 0x20, 0x00, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0057[ 66] = { /* code 0057, LATIN CAPITAL LETTER W */ + 0x46, 0x00, 0x06, 0x70, 0x00, 0x64, + 0xDF, 0x20, 0x2F, 0xF3, 0x01, 0xFD, + 0xAF, 0x60, 0x6F, 0xF7, 0x05, 0xFA, + 0x6F, 0x90, 0x9E, 0xEA, 0x08, 0xF7, + 0x2F, 0xC0, 0xDB, 0xAE, 0x0B, 0xF3, + 0x0E, 0xF2, 0xF7, 0x7F, 0x2E, 0xE0, + 0x09, 0xF7, 0xF4, 0x3F, 0x7F, 0xA0, + 0x06, 0xFE, 0xF0, 0x0E, 0xEF, 0x60, + 0x02, 0xFF, 0xB0, 0x0B, 0xFF, 0x20, + 0x00, 0xCF, 0x70, 0x06, 0xFD, 0x00, + 0x00, 0x12, 0x00, 0x00, 0x21, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0058[ 44] = { /* code 0058, LATIN CAPITAL LETTER X */ + 0x27, 0x10, 0x02, 0x71, + 0x8F, 0xA0, 0x0B, 0xF6, + 0x2F, 0xF3, 0x6F, 0xD1, + 0x07, 0xFC, 0xEF, 0x30, + 0x00, 0xCF, 0xF8, 0x00, + 0x00, 0x8F, 0xF5, 0x00, + 0x04, 0xFF, 0xFD, 0x10, + 0x1D, 0xF6, 0xBF, 0x90, + 0x9F, 0xC0, 0x2F, 0xF4, + 0xBF, 0x30, 0x08, 0xF7, + 0x11, 0x00, 0x00, 0x20 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0059[ 44] = { /* code 0059, LATIN CAPITAL LETTER Y */ + 0x47, 0x00, 0x00, 0x74, + 0xDF, 0x60, 0x06, 0xFC, + 0x6F, 0xD0, 0x0D, 0xF5, + 0x0C, 0xF7, 0x7F, 0xB0, + 0x03, 0xFE, 0xEF, 0x30, + 0x00, 0x9F, 0xF8, 0x00, + 0x00, 0x2F, 0xF1, 0x00, + 0x00, 0x2F, 0xF0, 0x00, + 0x00, 0x2F, 0xF0, 0x00, + 0x00, 0x1E, 0xE0, 0x00, + 0x00, 0x01, 0x10, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_005A[ 50] = { /* code 005A, LATIN CAPITAL LETTER Z */ + 0x04, 0x66, 0x66, 0x65, 0x10, + 0x3F, 0xFF, 0xFF, 0xFF, 0x60, + 0x05, 0x77, 0x7D, 0xFE, 0x20, + 0x00, 0x00, 0x5F, 0xF3, 0x00, + 0x00, 0x03, 0xFF, 0x60, 0x00, + 0x00, 0x2E, 0xF8, 0x00, 0x00, + 0x01, 0xDF, 0xA0, 0x00, 0x00, + 0x0B, 0xFC, 0x10, 0x00, 0x00, + 0x7F, 0xFC, 0xBB, 0xBB, 0x40, + 0x7F, 0xFF, 0xFF, 0xFF, 0x50 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_005B[ 26] = { /* code 005B, LEFT SQUARE BRACKET */ + 0x36, 0x62, + 0xDF, 0xF7, + 0xDD, 0x00, + 0xDD, 0x00, + 0xDD, 0x00, + 0xDD, 0x00, + 0xDD, 0x00, + 0xDD, 0x00, + 0xDD, 0x00, + 0xDD, 0x00, + 0xDD, 0x00, + 0xDF, 0xF7, + 0x36, 0x62 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_005C[ 33] = { /* code 005C, REVERSE SOLIDUS */ + 0x73, 0x00, 0x00, + 0xCB, 0x00, 0x00, + 0x6F, 0x20, 0x00, + 0x1F, 0x70, 0x00, + 0x0A, 0xD0, 0x00, + 0x04, 0xF3, 0x00, + 0x00, 0xD9, 0x00, + 0x00, 0x8E, 0x00, + 0x00, 0x2F, 0x60, + 0x00, 0x0B, 0xA0, + 0x00, 0x01, 0x10 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_005D[ 26] = { /* code 005D, RIGHT SQUARE BRACKET */ + 0x46, 0x51, + 0xEF, 0xF6, + 0x04, 0xF7, + 0x04, 0xF7, + 0x04, 0xF7, + 0x04, 0xF7, + 0x04, 0xF7, + 0x04, 0xF7, + 0x04, 0xF7, + 0x04, 0xF7, + 0x04, 0xF7, + 0xEF, 0xF6, + 0x46, 0x51 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_005E[ 28] = { /* code 005E, CIRCUMFLEX ACCENT */ + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1D, 0xB0, 0x00, + 0x00, 0x7F, 0xF5, 0x00, + 0x01, 0xF9, 0xCD, 0x00, + 0x09, 0xF1, 0x4F, 0x60, + 0x1F, 0x70, 0x0A, 0xD0, + 0x02, 0x00, 0x00, 0x10 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_005F[ 4] = { /* code 005F, LOW LINE */ + 0x39, 0x99, 0x99, 0x98 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0060[ 6] = { /* code 0060, GRAVE ACCENT */ + 0xC7, 0x00, + 0x8F, 0xA0, + 0x03, 0x60 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0061[ 32] = { /* code 0061, LATIN SMALL LETTER A */ + 0x03, 0xBE, 0xEC, 0x40, + 0x0E, 0xE8, 0x8F, 0xE0, + 0x06, 0x20, 0x2E, 0xF2, + 0x07, 0xCF, 0xFF, 0xF2, + 0x5F, 0xB3, 0x1D, 0xF2, + 0x7F, 0xA2, 0x6F, 0xF2, + 0x1C, 0xFF, 0xAA, 0xF3, + 0x00, 0x21, 0x00, 0x20 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0062[ 44] = { /* code 0062, LATIN SMALL LETTER B */ + 0x07, 0x30, 0x00, 0x00, + 0x4F, 0x90, 0x00, 0x00, + 0x4F, 0x90, 0x00, 0x00, + 0x4F, 0xBB, 0xFC, 0x30, + 0x4F, 0xFA, 0x9F, 0xE1, + 0x4F, 0xB0, 0x09, 0xF5, + 0x4F, 0x80, 0x06, 0xF7, + 0x4F, 0xA0, 0x08, 0xF6, + 0x4F, 0xF7, 0x7E, 0xF2, + 0x3F, 0xAE, 0xFE, 0x50, + 0x02, 0x00, 0x20, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0063[ 32] = { /* code 0063, LATIN SMALL LETTER C */ + 0x03, 0xBE, 0xE9, 0x10, + 0x1E, 0xF9, 0xAF, 0xA0, + 0x7F, 0x80, 0x07, 0x50, + 0x9F, 0x40, 0x00, 0x00, + 0x8F, 0x60, 0x05, 0x40, + 0x3F, 0xE6, 0x7F, 0xA0, + 0x06, 0xEF, 0xFC, 0x20, + 0x00, 0x02, 0x20, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0064[ 44] = { /* code 0064, LATIN SMALL LETTER D */ + 0x00, 0x00, 0x03, 0x70, + 0x00, 0x00, 0x0B, 0xF3, + 0x00, 0x00, 0x0B, 0xF4, + 0x04, 0xCF, 0xAC, 0xF4, + 0x1E, 0xF9, 0xAF, 0xF4, + 0x6F, 0x90, 0x0C, 0xF4, + 0x7F, 0x60, 0x09, 0xF4, + 0x7F, 0x70, 0x0B, 0xF4, + 0x2F, 0xE7, 0x7F, 0xF4, + 0x06, 0xFF, 0xEA, 0xF2, + 0x00, 0x12, 0x00, 0x20 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0065[ 32] = { /* code 0065, LATIN SMALL LETTER E */ + 0x02, 0xAE, 0xEB, 0x20, + 0x0D, 0xE7, 0x7E, 0xE1, + 0x6F, 0x82, 0x28, 0xF6, + 0x7F, 0xFF, 0xFF, 0xF6, + 0x7F, 0x70, 0x00, 0x30, + 0x2E, 0xE7, 0x6C, 0xF1, + 0x04, 0xDF, 0xFE, 0x70, + 0x00, 0x02, 0x20, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0066[ 33] = { /* code 0066, LATIN SMALL LETTER F */ + 0x00, 0x69, 0x30, + 0x07, 0xFF, 0x90, + 0x09, 0xF4, 0x00, + 0x9E, 0xFC, 0x70, + 0x4C, 0xF9, 0x30, + 0x09, 0xF4, 0x00, + 0x09, 0xF4, 0x00, + 0x09, 0xF4, 0x00, + 0x09, 0xF4, 0x00, + 0x08, 0xF3, 0x00, + 0x00, 0x10, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0067[ 40] = { /* code 0067, LATIN SMALL LETTER G */ + 0x03, 0xCF, 0xB7, 0xE1, + 0x1E, 0xF9, 0xAF, 0xF4, + 0x6F, 0x80, 0x0C, 0xF4, + 0x7F, 0x60, 0x09, 0xF4, + 0x7F, 0x80, 0x0C, 0xF4, + 0x1E, 0xFA, 0xBF, 0xF4, + 0x03, 0xAB, 0x8A, 0xF3, + 0x08, 0x30, 0x0C, 0xF1, + 0x0E, 0xFA, 0xCF, 0x90, + 0x02, 0x9B, 0xB7, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0068[ 44] = { /* code 0068, LATIN SMALL LETTER H */ + 0x07, 0x30, 0x00, 0x00, + 0x4F, 0x90, 0x00, 0x00, + 0x4F, 0x90, 0x00, 0x00, + 0x4F, 0xAA, 0xED, 0x50, + 0x4F, 0xFB, 0xAF, 0xF1, + 0x4F, 0xC0, 0x0C, 0xF3, + 0x4F, 0x90, 0x0B, 0xF4, + 0x4F, 0x90, 0x0B, 0xF4, + 0x4F, 0x90, 0x0B, 0xF4, + 0x3F, 0x90, 0x0A, 0xF2, + 0x02, 0x00, 0x00, 0x10 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0069[ 22] = { /* code 0069, LATIN SMALL LETTER I */ + 0x07, 0x40, + 0x2F, 0xB0, + 0x04, 0x20, + 0x1E, 0x80, + 0x2F, 0xB0, + 0x2F, 0xB0, + 0x2F, 0xB0, + 0x2F, 0xB0, + 0x2F, 0xB0, + 0x1F, 0xA0, + 0x01, 0x10 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_006A[ 26] = { /* code 006A, LATIN SMALL LETTER J */ + 0x00, 0x74, + 0x02, 0xFB, + 0x00, 0x42, + 0x01, 0xE8, + 0x02, 0xFB, + 0x02, 0xFB, + 0x02, 0xFB, + 0x02, 0xFB, + 0x02, 0xFB, + 0x02, 0xFB, + 0x02, 0xFB, + 0x2C, 0xFA, + 0x19, 0x92 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_006B[ 44] = { /* code 006B, LATIN SMALL LETTER K */ + 0x07, 0x30, 0x00, 0x00, + 0x4F, 0x90, 0x00, 0x00, + 0x4F, 0x90, 0x00, 0x00, + 0x4F, 0x90, 0x5E, 0x30, + 0x4F, 0x94, 0xFE, 0x20, + 0x4F, 0xCE, 0xE3, 0x00, + 0x4F, 0xFF, 0xE2, 0x00, + 0x4F, 0xD8, 0xFC, 0x00, + 0x4F, 0x90, 0xBF, 0x80, + 0x3F, 0x90, 0x2E, 0xB0, + 0x01, 0x00, 0x01, 0x10 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_006C[ 22] = { /* code 006C, LATIN SMALL LETTER L */ + 0x07, 0x40, + 0x2F, 0xB0, + 0x2F, 0xB0, + 0x2F, 0xB0, + 0x2F, 0xB0, + 0x2F, 0xB0, + 0x2F, 0xB0, + 0x2F, 0xB0, + 0x2F, 0xB0, + 0x1F, 0xA0, + 0x01, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_006D[ 48] = { /* code 006D, LATIN SMALL LETTER M */ + 0x2E, 0x69, 0xED, 0x38, 0xEE, 0x70, + 0x4F, 0xEB, 0xBF, 0xED, 0xAF, 0xF3, + 0x4F, 0xC0, 0x0F, 0xF2, 0x0A, 0xF4, + 0x4F, 0x90, 0x0F, 0xF0, 0x09, 0xF4, + 0x4F, 0x90, 0x0F, 0xF0, 0x09, 0xF4, + 0x4F, 0x90, 0x0F, 0xF0, 0x09, 0xF4, + 0x3F, 0x90, 0x0D, 0xE0, 0x08, 0xF3, + 0x02, 0x00, 0x01, 0x10, 0x00, 0x20 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_006E[ 32] = { /* code 006E, LATIN SMALL LETTER N */ + 0x2E, 0x6A, 0xED, 0x50, + 0x4F, 0xFB, 0xAF, 0xF1, + 0x4F, 0xC0, 0x0C, 0xF3, + 0x4F, 0x90, 0x0B, 0xF4, + 0x4F, 0x90, 0x0B, 0xF4, + 0x4F, 0x90, 0x0B, 0xF4, + 0x3F, 0x90, 0x0A, 0xF2, + 0x02, 0x00, 0x00, 0x10 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_006F[ 32] = { /* code 006F, LATIN SMALL LETTER O */ + 0x02, 0xBE, 0xEA, 0x20, + 0x1D, 0xF8, 0x8F, 0xD0, + 0x6F, 0x80, 0x09, 0xF5, + 0x7F, 0x60, 0x06, 0xF7, + 0x7F, 0x70, 0x08, 0xF6, + 0x2F, 0xE5, 0x5E, 0xF2, + 0x05, 0xEF, 0xFE, 0x40, + 0x00, 0x02, 0x20, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0070[ 40] = { /* code 0070, LATIN SMALL LETTER P */ + 0x2E, 0x7B, 0xFC, 0x30, + 0x4F, 0xFA, 0x9F, 0xE1, + 0x4F, 0xB0, 0x0A, 0xF5, + 0x4F, 0x80, 0x06, 0xF7, + 0x4F, 0xA0, 0x08, 0xF6, + 0x4F, 0xF7, 0x7E, 0xF2, + 0x4F, 0xBD, 0xFF, 0x50, + 0x4F, 0x90, 0x21, 0x00, + 0x4F, 0x90, 0x00, 0x00, + 0x19, 0x40, 0x00, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0071[ 40] = { /* code 0071, LATIN SMALL LETTER Q */ + 0x03, 0xCF, 0xB7, 0xE1, + 0x1E, 0xF9, 0xAF, 0xF4, + 0x6F, 0x90, 0x0C, 0xF4, + 0x7F, 0x60, 0x09, 0xF4, + 0x7F, 0x70, 0x0B, 0xF4, + 0x3F, 0xE6, 0x7F, 0xF4, + 0x06, 0xFF, 0xDD, 0xF4, + 0x00, 0x12, 0x0B, 0xF4, + 0x00, 0x00, 0x0B, 0xF3, + 0x00, 0x00, 0x05, 0x90 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0072[ 24] = { /* code 0072, LATIN SMALL LETTER R */ + 0x1E, 0x7B, 0xE1, + 0x2F, 0xEE, 0xC1, + 0x2F, 0xE1, 0x00, + 0x2F, 0xB0, 0x00, + 0x2F, 0xB0, 0x00, + 0x2F, 0xB0, 0x00, + 0x1F, 0xA0, 0x00, + 0x01, 0x10, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0073[ 32] = { /* code 0073, LATIN SMALL LETTER S */ + 0x08, 0xDF, 0xC7, 0x00, + 0x6F, 0xB7, 0xCF, 0x20, + 0x7F, 0xB4, 0x13, 0x00, + 0x2C, 0xFF, 0xFA, 0x10, + 0x13, 0x36, 0xCF, 0x70, + 0x7F, 0x72, 0x9F, 0x60, + 0x1B, 0xFF, 0xFA, 0x00, + 0x00, 0x12, 0x10, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0074[ 30] = { /* code 0074, LATIN SMALL LETTER T */ + 0x08, 0xC1, 0x00, + 0x0B, 0xF2, 0x00, + 0x9E, 0xFC, 0x60, + 0x4D, 0xF8, 0x30, + 0x0B, 0xF2, 0x00, + 0x0B, 0xF2, 0x00, + 0x0B, 0xF2, 0x00, + 0x0B, 0xF7, 0x20, + 0x07, 0xFF, 0x70, + 0x00, 0x12, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0075[ 32] = { /* code 0075, LATIN SMALL LETTER U */ + 0x2E, 0x70, 0x08, 0xE1, + 0x4F, 0x90, 0x0B, 0xF4, + 0x4F, 0x90, 0x0B, 0xF4, + 0x4F, 0x90, 0x0B, 0xF4, + 0x4F, 0xA0, 0x0C, 0xF4, + 0x2F, 0xF7, 0x9F, 0xF4, + 0x08, 0xFF, 0xC8, 0xF2, + 0x00, 0x12, 0x00, 0x10 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0076[ 32] = { /* code 0076, LATIN SMALL LETTER V */ + 0xBB, 0x00, 0x4E, 0x30, + 0xCF, 0x20, 0xAF, 0x40, + 0x7F, 0x70, 0xEE, 0x00, + 0x1F, 0xB4, 0xF9, 0x00, + 0x0B, 0xF9, 0xF3, 0x00, + 0x05, 0xFF, 0xD0, 0x00, + 0x01, 0xEF, 0x70, 0x00, + 0x00, 0x12, 0x00, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0077[ 40] = { /* code 0077, LATIN SMALL LETTER W */ + 0x9C, 0x00, 0xCD, 0x10, 0xBB, + 0xBF, 0x23, 0xFF, 0x51, 0xFC, + 0x7F, 0x66, 0xFE, 0x84, 0xF8, + 0x2F, 0xA9, 0xCA, 0xC7, 0xF3, + 0x0C, 0xDC, 0x87, 0xFB, 0xE0, + 0x08, 0xFF, 0x43, 0xFF, 0x90, + 0x03, 0xFE, 0x10, 0xDF, 0x40, + 0x00, 0x11, 0x00, 0x12, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0078[ 24] = { /* code 0078, LATIN SMALL LETTER X */ + 0x6E, 0x20, 0xAC, + 0x6F, 0xB5, 0xFB, + 0x0B, 0xFE, 0xE2, + 0x03, 0xFF, 0x80, + 0x0B, 0xFF, 0xE2, + 0x6F, 0xA7, 0xFB, + 0xBE, 0x20, 0xCE, + 0x01, 0x00, 0x11 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_0079[ 40] = { /* code 0079, LATIN SMALL LETTER Y */ + 0xAC, 0x00, 0x5E, 0x30, + 0xBF, 0x40, 0xBF, 0x30, + 0x6F, 0x80, 0xED, 0x00, + 0x1F, 0xC4, 0xF7, 0x00, + 0x0A, 0xF9, 0xF2, 0x00, + 0x05, 0xFF, 0xC0, 0x00, + 0x00, 0xEF, 0x70, 0x00, + 0x00, 0xBF, 0x10, 0x00, + 0x4F, 0xFA, 0x00, 0x00, + 0x19, 0x81, 0x00, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_007A[ 28] = { /* code 007A, LATIN SMALL LETTER Z */ + 0x2B, 0xBB, 0xBB, 0x70, + 0x2A, 0xBB, 0xFF, 0x90, + 0x00, 0x08, 0xFA, 0x00, + 0x00, 0x7F, 0xB1, 0x00, + 0x06, 0xFD, 0x10, 0x00, + 0x4F, 0xF9, 0x77, 0x50, + 0x7F, 0xFF, 0xFF, 0xB0 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_007B[ 39] = { /* code 007B, LEFT CURLY BRACKET */ + 0x00, 0x46, 0x20, + 0x08, 0xFE, 0x50, + 0x0B, 0xF0, 0x00, + 0x0B, 0xF0, 0x00, + 0x0B, 0xF0, 0x00, + 0x1C, 0xF0, 0x00, + 0xEF, 0x70, 0x00, + 0x1C, 0xF0, 0x00, + 0x0B, 0xF0, 0x00, + 0x0B, 0xF0, 0x00, + 0x0B, 0xF0, 0x00, + 0x08, 0xFC, 0x50, + 0x00, 0x56, 0x20 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_007C[ 22] = { /* code 007C, VERTICAL LINE */ + 0x18, 0x00, + 0x6F, 0x40, + 0x6F, 0x40, + 0x6F, 0x40, + 0x6F, 0x40, + 0x6F, 0x40, + 0x6F, 0x40, + 0x6F, 0x40, + 0x6F, 0x40, + 0x5F, 0x30, + 0x03, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_007D[ 39] = { /* code 007D, RIGHT CURLY BRACKET */ + 0x46, 0x30, 0x00, + 0xBE, 0xF2, 0x00, + 0x08, 0xF4, 0x00, + 0x07, 0xF4, 0x00, + 0x07, 0xF4, 0x00, + 0x06, 0xF6, 0x00, + 0x00, 0xCF, 0x70, + 0x06, 0xF7, 0x00, + 0x07, 0xF4, 0x00, + 0x07, 0xF4, 0x00, + 0x07, 0xF4, 0x00, + 0xAE, 0xF2, 0x00, + 0x56, 0x30, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded16_007E[ 12] = { /* code 007E, TILDE */ + 0x0A, 0xDA, 0x41, 0xA2, + 0x6F, 0xAE, 0xFF, 0xE2, + 0x23, 0x00, 0x67, 0x30 +}; + +GUI_CONST_STORAGE GUI_CHARINFO_EXT GUI_FontRounded16_CharInfo[95] = { + { 1, 1, 0, 13, 4, acGUI_FontRounded16_0020 } /* code 0020, SPACE */ + ,{ 3, 11, 1, 3, 4, acGUI_FontRounded16_0021 } /* code 0021, EXCLAMATION MARK */ + ,{ 5, 5, 1, 3, 7, acGUI_FontRounded16_0022 } /* code 0022, QUOTATION MARK */ + ,{ 8, 11, 0, 3, 8, acGUI_FontRounded16_0023 } /* code 0023, NUMBER SIGN */ + ,{ 8, 12, 0, 3, 8, acGUI_FontRounded16_0024 } /* code 0024, DOLLAR SIGN */ + ,{ 11, 11, 1, 3, 13, acGUI_FontRounded16_0025 } /* code 0025, PERCENT SIGN */ + ,{ 9, 11, 0, 3, 9, acGUI_FontRounded16_0026 } /* code 0026, AMPERSAND */ + ,{ 2, 5, 1, 3, 4, acGUI_FontRounded16_0027 } /* code 0027, APOSTROPHE */ + ,{ 4, 13, 0, 3, 4, acGUI_FontRounded16_0028 } /* code 0028, LEFT PARENTHESIS */ + ,{ 4, 13, 0, 3, 4, acGUI_FontRounded16_0029 } /* code 0029, RIGHT PARENTHESIS */ + ,{ 6, 6, 0, 3, 6, acGUI_FontRounded16_002A } /* code 002A, ASTERISK */ + ,{ 8, 8, 0, 5, 8, acGUI_FontRounded16_002B } /* code 002B, PLUS SIGN */ + ,{ 4, 4, 0, 11, 4, acGUI_FontRounded16_002C } /* code 002C, COMMA */ + ,{ 5, 3, 0, 8, 5, acGUI_FontRounded16_002D } /* code 002D, HYPHEN-MINUS */ + ,{ 4, 3, 0, 11, 4, acGUI_FontRounded16_002E } /* code 002E, FULL STOP */ + ,{ 5, 11, 0, 3, 5, acGUI_FontRounded16_002F } /* code 002F, SOLIDUS */ + ,{ 8, 11, 0, 3, 8, acGUI_FontRounded16_0030 } /* code 0030, DIGIT ZERO */ + ,{ 6, 11, -1, 3, 5, acGUI_FontRounded16_0031 } /* code 0031, DIGIT ONE */ + ,{ 8, 10, 0, 3, 8, acGUI_FontRounded16_0032 } /* code 0032, DIGIT TWO */ + ,{ 8, 11, 0, 3, 8, acGUI_FontRounded16_0033 } /* code 0033, DIGIT THREE */ + ,{ 8, 11, 0, 3, 8, acGUI_FontRounded16_0034 } /* code 0034, DIGIT FOUR */ + ,{ 8, 11, 0, 3, 8, acGUI_FontRounded16_0035 } /* code 0035, DIGIT FIVE */ + ,{ 8, 11, 0, 3, 8, acGUI_FontRounded16_0036 } /* code 0036, DIGIT SIX */ + ,{ 8, 11, 0, 3, 7, acGUI_FontRounded16_0037 } /* code 0037, DIGIT SEVEN */ + ,{ 8, 11, 0, 3, 8, acGUI_FontRounded16_0038 } /* code 0038, DIGIT EIGHT */ + ,{ 8, 11, 0, 3, 8, acGUI_FontRounded16_0039 } /* code 0039, DIGIT NINE */ + ,{ 4, 8, 0, 6, 4, acGUI_FontRounded16_003A } /* code 003A, COLON */ + ,{ 4, 9, 0, 6, 4, acGUI_FontRounded16_003B } /* code 003B, SEMICOLON */ + ,{ 8, 7, 0, 6, 8, acGUI_FontRounded16_003C } /* code 003C, LESS-THAN SIGN */ + ,{ 8, 5, 0, 7, 8, acGUI_FontRounded16_003D } /* code 003D, EQUALS SIGN */ + ,{ 8, 7, 0, 6, 8, acGUI_FontRounded16_003E } /* code 003E, GREATER-THAN SIGN */ + ,{ 7, 11, 0, 3, 7, acGUI_FontRounded16_003F } /* code 003F, QUESTION MARK */ + ,{ 10, 11, 0, 3, 10, acGUI_FontRounded16_0040 } /* code 0040, COMMERCIAL AT */ + ,{ 9, 11, 0, 3, 9, acGUI_FontRounded16_0041 } /* code 0041, LATIN CAPITAL LETTER A */ + ,{ 8, 10, 1, 3, 9, acGUI_FontRounded16_0042 } /* code 0042, LATIN CAPITAL LETTER B */ + ,{ 9, 11, 0, 3, 9, acGUI_FontRounded16_0043 } /* code 0043, LATIN CAPITAL LETTER C */ + ,{ 9, 10, 1, 3, 10, acGUI_FontRounded16_0044 } /* code 0044, LATIN CAPITAL LETTER D */ + ,{ 8, 10, 1, 3, 9, acGUI_FontRounded16_0045 } /* code 0045, LATIN CAPITAL LETTER E */ + ,{ 8, 11, 1, 3, 8, acGUI_FontRounded16_0046 } /* code 0046, LATIN CAPITAL LETTER F */ + ,{ 10, 11, 0, 3, 11, acGUI_FontRounded16_0047 } /* code 0047, LATIN CAPITAL LETTER G */ + ,{ 9, 11, 1, 3, 10, acGUI_FontRounded16_0048 } /* code 0048, LATIN CAPITAL LETTER H */ + ,{ 3, 11, 1, 3, 4, acGUI_FontRounded16_0049 } /* code 0049, LATIN CAPITAL LETTER I */ + ,{ 7, 11, 0, 3, 7, acGUI_FontRounded16_004A } /* code 004A, LATIN CAPITAL LETTER J */ + ,{ 8, 11, 1, 3, 9, acGUI_FontRounded16_004B } /* code 004B, LATIN CAPITAL LETTER K */ + ,{ 7, 10, 1, 3, 8, acGUI_FontRounded16_004C } /* code 004C, LATIN CAPITAL LETTER L */ + ,{ 10, 11, 1, 3, 12, acGUI_FontRounded16_004D } /* code 004D, LATIN CAPITAL LETTER M */ + ,{ 9, 11, 1, 3, 10, acGUI_FontRounded16_004E } /* code 004E, LATIN CAPITAL LETTER N */ + ,{ 10, 11, 0, 3, 11, acGUI_FontRounded16_004F } /* code 004F, LATIN CAPITAL LETTER O */ + ,{ 8, 11, 1, 3, 9, acGUI_FontRounded16_0050 } /* code 0050, LATIN CAPITAL LETTER P */ + ,{ 10, 11, 0, 3, 11, acGUI_FontRounded16_0051 } /* code 0051, LATIN CAPITAL LETTER Q */ + ,{ 8, 11, 1, 3, 10, acGUI_FontRounded16_0052 } /* code 0052, LATIN CAPITAL LETTER R */ + ,{ 9, 11, 0, 3, 9, acGUI_FontRounded16_0053 } /* code 0053, LATIN CAPITAL LETTER S */ + ,{ 9, 11, 0, 3, 9, acGUI_FontRounded16_0054 } /* code 0054, LATIN CAPITAL LETTER T */ + ,{ 9, 11, 1, 3, 10, acGUI_FontRounded16_0055 } /* code 0055, LATIN CAPITAL LETTER U */ + ,{ 9, 11, 0, 3, 8, acGUI_FontRounded16_0056 } /* code 0056, LATIN CAPITAL LETTER V */ + ,{ 12, 11, 0, 3, 12, acGUI_FontRounded16_0057 } /* code 0057, LATIN CAPITAL LETTER W */ + ,{ 8, 11, 0, 3, 8, acGUI_FontRounded16_0058 } /* code 0058, LATIN CAPITAL LETTER X */ + ,{ 8, 11, 0, 3, 8, acGUI_FontRounded16_0059 } /* code 0059, LATIN CAPITAL LETTER Y */ + ,{ 9, 10, 0, 3, 9, acGUI_FontRounded16_005A } /* code 005A, LATIN CAPITAL LETTER Z */ + ,{ 4, 13, 1, 3, 5, acGUI_FontRounded16_005B } /* code 005B, LEFT SQUARE BRACKET */ + ,{ 5, 11, 0, 3, 5, acGUI_FontRounded16_005C } /* code 005C, REVERSE SOLIDUS */ + ,{ 4, 13, 0, 3, 5, acGUI_FontRounded16_005D } /* code 005D, RIGHT SQUARE BRACKET */ + ,{ 7, 7, 0, 3, 8, acGUI_FontRounded16_005E } /* code 005E, CIRCUMFLEX ACCENT */ + ,{ 8, 1, -1, 14, 7, acGUI_FontRounded16_005F } /* code 005F, LOW LINE */ + ,{ 3, 3, 0, 3, 4, acGUI_FontRounded16_0060 } /* code 0060, GRAVE ACCENT */ + ,{ 8, 8, 0, 6, 8, acGUI_FontRounded16_0061 } /* code 0061, LATIN SMALL LETTER A */ + ,{ 8, 11, 0, 3, 8, acGUI_FontRounded16_0062 } /* code 0062, LATIN SMALL LETTER B */ + ,{ 7, 8, 0, 6, 7, acGUI_FontRounded16_0063 } /* code 0063, LATIN SMALL LETTER C */ + ,{ 8, 11, 0, 3, 8, acGUI_FontRounded16_0064 } /* code 0064, LATIN SMALL LETTER D */ + ,{ 8, 8, 0, 6, 8, acGUI_FontRounded16_0065 } /* code 0065, LATIN SMALL LETTER E */ + ,{ 5, 11, 0, 3, 5, acGUI_FontRounded16_0066 } /* code 0066, LATIN SMALL LETTER F */ + ,{ 8, 10, 0, 6, 8, acGUI_FontRounded16_0067 } /* code 0067, LATIN SMALL LETTER G */ + ,{ 8, 11, 0, 3, 8, acGUI_FontRounded16_0068 } /* code 0068, LATIN SMALL LETTER H */ + ,{ 3, 11, 0, 3, 4, acGUI_FontRounded16_0069 } /* code 0069, LATIN SMALL LETTER I */ + ,{ 4, 13, -1, 3, 4, acGUI_FontRounded16_006A } /* code 006A, LATIN SMALL LETTER J */ + ,{ 7, 11, 0, 3, 7, acGUI_FontRounded16_006B } /* code 006B, LATIN SMALL LETTER K */ + ,{ 3, 11, 0, 3, 4, acGUI_FontRounded16_006C } /* code 006C, LATIN SMALL LETTER L */ + ,{ 12, 8, 0, 6, 12, acGUI_FontRounded16_006D } /* code 006D, LATIN SMALL LETTER M */ + ,{ 8, 8, 0, 6, 8, acGUI_FontRounded16_006E } /* code 006E, LATIN SMALL LETTER N */ + ,{ 8, 8, 0, 6, 8, acGUI_FontRounded16_006F } /* code 006F, LATIN SMALL LETTER O */ + ,{ 8, 10, 0, 6, 8, acGUI_FontRounded16_0070 } /* code 0070, LATIN SMALL LETTER P */ + ,{ 8, 10, 0, 6, 8, acGUI_FontRounded16_0071 } /* code 0071, LATIN SMALL LETTER Q */ + ,{ 6, 8, 0, 6, 5, acGUI_FontRounded16_0072 } /* code 0072, LATIN SMALL LETTER R */ + ,{ 7, 8, 0, 6, 7, acGUI_FontRounded16_0073 } /* code 0073, LATIN SMALL LETTER S */ + ,{ 5, 10, 0, 4, 5, acGUI_FontRounded16_0074 } /* code 0074, LATIN SMALL LETTER T */ + ,{ 8, 8, 0, 6, 8, acGUI_FontRounded16_0075 } /* code 0075, LATIN SMALL LETTER U */ + ,{ 7, 8, 0, 6, 7, acGUI_FontRounded16_0076 } /* code 0076, LATIN SMALL LETTER V */ + ,{ 10, 8, 0, 6, 10, acGUI_FontRounded16_0077 } /* code 0077, LATIN SMALL LETTER W */ + ,{ 6, 8, 0, 6, 6, acGUI_FontRounded16_0078 } /* code 0078, LATIN SMALL LETTER X */ + ,{ 7, 10, 0, 6, 7, acGUI_FontRounded16_0079 } /* code 0079, LATIN SMALL LETTER Y */ + ,{ 7, 7, 0, 6, 7, acGUI_FontRounded16_007A } /* code 007A, LATIN SMALL LETTER Z */ + ,{ 5, 13, 0, 3, 5, acGUI_FontRounded16_007B } /* code 007B, LEFT CURLY BRACKET */ + ,{ 3, 11, 0, 3, 3, acGUI_FontRounded16_007C } /* code 007C, VERTICAL LINE */ + ,{ 5, 13, 0, 3, 5, acGUI_FontRounded16_007D } /* code 007D, RIGHT CURLY BRACKET */ + ,{ 8, 3, 0, 8, 8, acGUI_FontRounded16_007E } /* code 007E, TILDE */ +}; + +GUI_CONST_STORAGE GUI_FONT_PROP_EXT GUI_FontRounded16_Prop1 = { + 0x0020 /* first character */ + ,0x007E /* last character */ + ,&GUI_FontRounded16_CharInfo[ 0] /* address of first character */ + ,(GUI_CONST_STORAGE GUI_FONT_PROP_EXT *)0 /* pointer to next GUI_FONT_PROP_EXT */ +}; + +GUI_CONST_STORAGE GUI_FONT GUI_FontRounded16 = { + GUI_FONTTYPE_PROP_AA4_EXT /* type of font */ + ,16 /* height of font */ + ,16 /* space of font y */ + ,1 /* magnification x */ + ,1 /* magnification y */ + ,{&GUI_FontRounded16_Prop1} + ,16 /* Baseline */ + ,8 /* Height of lowercase characters */ + ,11 /* Height of capital characters */ +}; + +/********************************************************************* +* * +* GUI_FontRounded22 * +* * +* Used in * +* - GUIDEMO.c * +* - GUIDEMO_AntiAliasedText.c * +* - GUIDEMO_Automotive.c * +* - GUIDEMO_Bargraph.c * +* - GUIDEMO_ColorBar.c * +* - GUIDEMO_IconView.c * +* - GUIDEMO_ImageFlow.c * +* - GUIDEMO_Intro.c * +* * +********************************************************************** +*/ +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0020[ 1] = { /* code 0020, SPACE */ + 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0021[ 30] = { /* code 0021, EXCLAMATION MARK */ + 0x02, 0x10, + 0x6F, 0xE2, + 0x9F, 0xF4, + 0x9F, 0xF4, + 0x9F, 0xF4, + 0x7F, 0xF2, + 0x5F, 0xF0, + 0x3F, 0xD0, + 0x1F, 0xB0, + 0x0D, 0x80, + 0x00, 0x00, + 0x2B, 0xA0, + 0x9F, 0xF4, + 0x5F, 0xE1, + 0x01, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0022[ 28] = { /* code 0022, QUOTATION MARK */ + 0x01, 0x10, 0x02, 0x00, + 0x0E, 0xF2, 0x7F, 0x90, + 0x2F, 0xF4, 0x9F, 0xB0, + 0x2F, 0xF4, 0x9F, 0xB0, + 0x2F, 0xF4, 0x9F, 0xB0, + 0x1E, 0xF2, 0x8F, 0xA0, + 0x02, 0x20, 0x03, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0023[ 84] = { /* code 0023, NUMBER SIGN */ + 0x00, 0x02, 0xB4, 0x08, 0x90, 0x00, + 0x00, 0x06, 0xF7, 0x0F, 0xD0, 0x00, + 0x00, 0x08, 0xF5, 0x2F, 0xB0, 0x00, + 0x00, 0x2B, 0xF4, 0x5F, 0xA1, 0x00, + 0x07, 0xFF, 0xFF, 0xFF, 0xFE, 0x10, + 0x03, 0x9F, 0xE9, 0xDF, 0xB8, 0x00, + 0x00, 0x1F, 0xB0, 0xAF, 0x30, 0x00, + 0x02, 0x6F, 0xB4, 0xDF, 0x40, 0x00, + 0x0F, 0xFF, 0xFF, 0xFF, 0xF7, 0x00, + 0x06, 0xBF, 0x98, 0xFD, 0x72, 0x00, + 0x00, 0xAF, 0x33, 0xF9, 0x00, 0x00, + 0x00, 0xCF, 0x15, 0xF7, 0x00, 0x00, + 0x00, 0xDD, 0x07, 0xF4, 0x00, 0x00, + 0x00, 0x22, 0x00, 0x30, 0x00, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0024[ 96] = { /* code 0024, DOLLAR SIGN */ + 0x00, 0x00, 0x0B, 0x10, 0x00, 0x00, + 0x00, 0x28, 0xBF, 0xC8, 0x30, 0x00, + 0x05, 0xFF, 0xFF, 0xFF, 0xF9, 0x00, + 0x1E, 0xF9, 0x2F, 0x39, 0xFF, 0x50, + 0x3F, 0xF0, 0x0F, 0x20, 0x9E, 0x30, + 0x3F, 0xF6, 0x0F, 0x20, 0x00, 0x00, + 0x0D, 0xFF, 0xDF, 0x73, 0x00, 0x00, + 0x02, 0xCF, 0xFF, 0xFF, 0xC3, 0x00, + 0x00, 0x04, 0x8F, 0xEF, 0xFE, 0x10, + 0x03, 0x00, 0x0F, 0x25, 0xFF, 0x70, + 0x7F, 0xA0, 0x0F, 0x20, 0xBF, 0x80, + 0x7F, 0xF3, 0x0F, 0x21, 0xEF, 0x60, + 0x1D, 0xFE, 0xAF, 0xBE, 0xFD, 0x10, + 0x01, 0xAF, 0xFF, 0xFF, 0xA2, 0x00, + 0x00, 0x01, 0x3F, 0x41, 0x00, 0x00, + 0x00, 0x00, 0x0D, 0x10, 0x00, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0025[120] = { /* code 0025, PERCENT SIGN */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, + 0x03, 0xAB, 0xA2, 0x00, 0x00, 0x7F, 0x00, 0x00, + 0x2E, 0xEA, 0xFE, 0x10, 0x01, 0xE8, 0x00, 0x00, + 0x7F, 0x70, 0x9F, 0x50, 0x08, 0xE1, 0x00, 0x00, + 0x9F, 0x60, 0x7F, 0x70, 0x2F, 0x70, 0x00, 0x00, + 0x7F, 0x60, 0x8F, 0x60, 0x9E, 0x10, 0x00, 0x00, + 0x3F, 0xD6, 0xEF, 0x22, 0xF7, 0x00, 0x00, 0x00, + 0x07, 0xEF, 0xE6, 0x0A, 0xE0, 0x17, 0x98, 0x20, + 0x00, 0x01, 0x00, 0x3F, 0x60, 0xCF, 0xCF, 0xE1, + 0x00, 0x00, 0x00, 0xBD, 0x04, 0xFA, 0x09, 0xF6, + 0x00, 0x00, 0x04, 0xF5, 0x07, 0xF7, 0x06, 0xF9, + 0x00, 0x00, 0x0C, 0xC0, 0x06, 0xF8, 0x06, 0xF8, + 0x00, 0x00, 0x5F, 0x40, 0x03, 0xFC, 0x3B, 0xF4, + 0x00, 0x00, 0xCB, 0x00, 0x00, 0x8F, 0xFF, 0x90, + 0x00, 0x00, 0x93, 0x00, 0x00, 0x01, 0x42, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0026[105] = { /* code 0026, AMPERSAND */ + 0x00, 0x00, 0x01, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x04, 0xDF, 0xFD, 0x50, 0x00, 0x00, + 0x00, 0x3F, 0xFD, 0xCF, 0xF4, 0x00, 0x00, + 0x00, 0x9F, 0xD0, 0x0B, 0xFA, 0x00, 0x00, + 0x00, 0x9F, 0xD0, 0x0B, 0xFA, 0x00, 0x00, + 0x00, 0x4F, 0xF9, 0x8F, 0xF5, 0x00, 0x00, + 0x00, 0x0A, 0xFF, 0xFF, 0x80, 0x00, 0x00, + 0x00, 0x9F, 0xFF, 0xFB, 0x00, 0x54, 0x00, + 0x09, 0xFF, 0xBA, 0xFF, 0x74, 0xFF, 0x00, + 0x1F, 0xFB, 0x00, 0xBF, 0xFE, 0xFC, 0x00, + 0x3F, 0xF7, 0x00, 0x1D, 0xFF, 0xE3, 0x00, + 0x1F, 0xFB, 0x00, 0x2C, 0xFF, 0xE3, 0x00, + 0x0A, 0xFF, 0xED, 0xFF, 0xEE, 0xFD, 0x00, + 0x01, 0xAF, 0xFF, 0xFB, 0x24, 0xFD, 0x00, + 0x00, 0x01, 0x43, 0x10, 0x00, 0x10, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0027[ 14] = { /* code 0027, APOSTROPHE */ + 0x01, 0x10, + 0x3F, 0xD0, + 0x6F, 0xF0, + 0x6F, 0xF0, + 0x6F, 0xF0, + 0x3F, 0xE0, + 0x03, 0x10 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0028[ 54] = { /* code 0028, LEFT PARENTHESIS */ + 0x00, 0x03, 0x00, + 0x00, 0x9F, 0x40, + 0x02, 0xFF, 0x20, + 0x08, 0xFB, 0x00, + 0x0E, 0xF7, 0x00, + 0x4F, 0xF3, 0x00, + 0x7F, 0xE0, 0x00, + 0xAF, 0xC0, 0x00, + 0xBF, 0xB0, 0x00, + 0xBF, 0xB0, 0x00, + 0xBF, 0xB0, 0x00, + 0x8F, 0xE0, 0x00, + 0x5F, 0xF2, 0x00, + 0x1F, 0xF5, 0x00, + 0x0A, 0xFA, 0x00, + 0x04, 0xFE, 0x10, + 0x00, 0xCF, 0x50, + 0x00, 0x29, 0x10 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0029[ 54] = { /* code 0029, RIGHT PARENTHESIS */ + 0x03, 0x00, 0x00, + 0x5F, 0x90, 0x00, + 0x2F, 0xF2, 0x00, + 0x0B, 0xF8, 0x00, + 0x07, 0xFE, 0x00, + 0x03, 0xFF, 0x30, + 0x00, 0xFF, 0x70, + 0x00, 0xCF, 0xA0, + 0x00, 0xBF, 0xB0, + 0x00, 0xBF, 0xB0, + 0x00, 0xCF, 0xB0, + 0x00, 0xEF, 0x80, + 0x02, 0xFF, 0x50, + 0x05, 0xFF, 0x10, + 0x0A, 0xFA, 0x00, + 0x1E, 0xF4, 0x00, + 0x5F, 0xC0, 0x00, + 0x19, 0x20, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_002A[ 32] = { /* code 002A, ASTERISK */ + 0x00, 0x00, 0x10, 0x00, + 0x00, 0x08, 0xE0, 0x00, + 0x05, 0x29, 0xF0, 0x51, + 0x2F, 0xFE, 0xFE, 0xF7, + 0x02, 0x7F, 0xFB, 0x40, + 0x00, 0xAF, 0xCE, 0x20, + 0x03, 0xF7, 0x2F, 0x90, + 0x00, 0x30, 0x03, 0x10 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_002B[ 66] = { /* code 002B, PLUS SIGN */ + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x8F, 0x50, 0x00, 0x00, + 0x00, 0x00, 0xBF, 0x70, 0x00, 0x00, + 0x00, 0x00, 0xBF, 0x70, 0x00, 0x00, + 0x02, 0x22, 0xCF, 0x82, 0x22, 0x00, + 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0x60, + 0x6F, 0xFF, 0xFF, 0xFF, 0xFE, 0x40, + 0x00, 0x00, 0xBF, 0x70, 0x00, 0x00, + 0x00, 0x00, 0xBF, 0x70, 0x00, 0x00, + 0x00, 0x00, 0xBF, 0x70, 0x00, 0x00, + 0x00, 0x00, 0x7F, 0x40, 0x00, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_002C[ 12] = { /* code 002C, COMMA */ + 0x3C, 0x90, + 0xBF, 0xF5, + 0x6F, 0xF7, + 0x01, 0xE5, + 0x4C, 0xC0, + 0x67, 0x10 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_002D[ 16] = { /* code 002D, HYPHEN-MINUS */ + 0x01, 0x44, 0x42, 0x00, + 0x2F, 0xFF, 0xFF, 0x70, + 0x3F, 0xFF, 0xFF, 0x80, + 0x02, 0x44, 0x43, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_002E[ 8] = { /* code 002E, FULL STOP */ + 0x3C, 0x90, + 0xBF, 0xF3, + 0x6F, 0xD1, + 0x01, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_002F[ 60] = { /* code 002F, SOLIDUS */ + 0x00, 0x00, 0x03, 0x00, + 0x00, 0x00, 0x6F, 0x70, + 0x00, 0x00, 0xCF, 0x40, + 0x00, 0x03, 0xFD, 0x00, + 0x00, 0x08, 0xF8, 0x00, + 0x00, 0x0E, 0xF2, 0x00, + 0x00, 0x5F, 0xB0, 0x00, + 0x00, 0xBF, 0x60, 0x00, + 0x01, 0xFE, 0x10, 0x00, + 0x07, 0xF9, 0x00, 0x00, + 0x0D, 0xF3, 0x00, 0x00, + 0x3F, 0xD0, 0x00, 0x00, + 0x9F, 0x70, 0x00, 0x00, + 0xCF, 0x20, 0x00, 0x00, + 0x23, 0x00, 0x00, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0030[ 84] = { /* code 0030, DIGIT ZERO */ + 0x00, 0x05, 0xBB, 0xB6, 0x00, 0x00, + 0x00, 0xAF, 0xFF, 0xFF, 0xA0, 0x00, + 0x06, 0xFF, 0xA6, 0xAF, 0xF7, 0x00, + 0x0D, 0xFC, 0x00, 0x0C, 0xFD, 0x00, + 0x2F, 0xF8, 0x00, 0x08, 0xFF, 0x20, + 0x4F, 0xF6, 0x00, 0x06, 0xFF, 0x40, + 0x4F, 0xF6, 0x00, 0x06, 0xFF, 0x40, + 0x4F, 0xF6, 0x00, 0x06, 0xFF, 0x40, + 0x2F, 0xF7, 0x00, 0x06, 0xFF, 0x30, + 0x0E, 0xFA, 0x00, 0x0A, 0xFE, 0x00, + 0x09, 0xFF, 0x40, 0x4F, 0xF9, 0x00, + 0x02, 0xEF, 0xFE, 0xFF, 0xE2, 0x00, + 0x00, 0x3C, 0xFF, 0xFC, 0x30, 0x00, + 0x00, 0x00, 0x24, 0x20, 0x00, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0031[ 56] = { /* code 0031, DIGIT ONE */ + 0x00, 0x00, 0x2B, 0x70, + 0x00, 0x00, 0xAF, 0xC0, + 0x01, 0x49, 0xFF, 0xD0, + 0x1E, 0xFF, 0xFF, 0xD0, + 0x1B, 0xDD, 0xFF, 0xD0, + 0x00, 0x00, 0xDF, 0xD0, + 0x00, 0x00, 0xDF, 0xD0, + 0x00, 0x00, 0xDF, 0xD0, + 0x00, 0x00, 0xDF, 0xD0, + 0x00, 0x00, 0xDF, 0xD0, + 0x00, 0x00, 0xDF, 0xD0, + 0x00, 0x00, 0xDF, 0xC0, + 0x00, 0x00, 0xBF, 0xA0, + 0x00, 0x00, 0x13, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0032[ 78] = { /* code 0032, DIGIT TWO */ + 0x00, 0x17, 0xBB, 0xB6, 0x00, 0x00, + 0x03, 0xEF, 0xFF, 0xFF, 0xD1, 0x00, + 0x0D, 0xFE, 0x86, 0xAF, 0xFB, 0x00, + 0x5F, 0xF6, 0x00, 0x0D, 0xFF, 0x00, + 0x4F, 0xE1, 0x00, 0x0B, 0xFF, 0x00, + 0x03, 0x20, 0x00, 0x3F, 0xFB, 0x00, + 0x00, 0x00, 0x07, 0xEF, 0xF3, 0x00, + 0x00, 0x03, 0xCF, 0xFD, 0x30, 0x00, + 0x00, 0x6F, 0xFE, 0x70, 0x00, 0x00, + 0x06, 0xFF, 0xA2, 0x00, 0x00, 0x00, + 0x2F, 0xFC, 0x44, 0x44, 0x42, 0x00, + 0x6F, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, + 0x3E, 0xFF, 0xFF, 0xFF, 0xFD, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0033[ 70] = { /* code 0033, DIGIT THREE */ + 0x00, 0x28, 0xBB, 0xA5, 0x00, + 0x05, 0xFF, 0xFF, 0xFF, 0xA0, + 0x1F, 0xFE, 0x76, 0xCF, 0xF4, + 0x2F, 0xF4, 0x00, 0x2F, 0xF7, + 0x04, 0x40, 0x00, 0x2F, 0xF5, + 0x00, 0x00, 0x5A, 0xEF, 0xB0, + 0x00, 0x00, 0xFF, 0xFF, 0x90, + 0x00, 0x00, 0x38, 0xCF, 0xF8, + 0x01, 0x00, 0x00, 0x1E, 0xFC, + 0x3F, 0xC0, 0x00, 0x0E, 0xFD, + 0x5F, 0xF8, 0x00, 0x7F, 0xF9, + 0x1D, 0xFF, 0xFE, 0xFF, 0xE2, + 0x02, 0xBF, 0xFF, 0xFB, 0x30, + 0x00, 0x01, 0x33, 0x10, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0034[ 84] = { /* code 0034, DIGIT FOUR */ + 0x00, 0x00, 0x00, 0x9B, 0x40, 0x00, + 0x00, 0x00, 0x07, 0xFF, 0x90, 0x00, + 0x00, 0x00, 0x4F, 0xFF, 0x90, 0x00, + 0x00, 0x02, 0xEE, 0xEF, 0x90, 0x00, + 0x00, 0x0C, 0xF4, 0xDF, 0x90, 0x00, + 0x00, 0x9F, 0x80, 0xDF, 0x90, 0x00, + 0x06, 0xFB, 0x00, 0xDF, 0x90, 0x00, + 0x3F, 0xE2, 0x00, 0xDF, 0x90, 0x00, + 0xBF, 0xFF, 0xFF, 0xFF, 0xFE, 0x50, + 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0x60, + 0x02, 0x22, 0x22, 0xDF, 0xA2, 0x00, + 0x00, 0x00, 0x00, 0xDF, 0x90, 0x00, + 0x00, 0x00, 0x00, 0xBF, 0x80, 0x00, + 0x00, 0x00, 0x00, 0x13, 0x00, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0035[ 70] = { /* code 0035, DIGIT FIVE */ + 0x01, 0x89, 0x99, 0x99, 0x70, + 0x07, 0xFF, 0xFF, 0xFF, 0xF3, + 0x0A, 0xFD, 0xBB, 0xBB, 0x90, + 0x0C, 0xF5, 0x00, 0x00, 0x00, + 0x0F, 0xF3, 0x46, 0x51, 0x00, + 0x3F, 0xFD, 0xFF, 0xFE, 0x60, + 0x3F, 0xFE, 0xAB, 0xFF, 0xF3, + 0x06, 0x60, 0x00, 0x4F, 0xFA, + 0x00, 0x00, 0x00, 0x0D, 0xFB, + 0x17, 0x40, 0x00, 0x0E, 0xFB, + 0x5F, 0xF4, 0x00, 0x8F, 0xF7, + 0x3F, 0xFF, 0xDE, 0xFF, 0xD1, + 0x04, 0xCF, 0xFF, 0xFA, 0x10, + 0x00, 0x02, 0x43, 0x10, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0036[ 84] = { /* code 0036, DIGIT SIX */ + 0x00, 0x04, 0x9B, 0xB9, 0x30, 0x00, + 0x00, 0x8F, 0xFF, 0xFF, 0xF4, 0x00, + 0x04, 0xFF, 0x93, 0x4E, 0xFB, 0x00, + 0x0B, 0xFC, 0x00, 0x02, 0x93, 0x00, + 0x1F, 0xF7, 0x02, 0x31, 0x00, 0x00, + 0x3F, 0xF9, 0xDF, 0xFF, 0x91, 0x00, + 0x4F, 0xFF, 0xEB, 0xDF, 0xFA, 0x00, + 0x4F, 0xFD, 0x10, 0x0B, 0xFF, 0x20, + 0x3F, 0xF8, 0x00, 0x06, 0xFF, 0x40, + 0x1F, 0xF8, 0x00, 0x06, 0xFF, 0x40, + 0x0B, 0xFE, 0x20, 0x1C, 0xFF, 0x10, + 0x03, 0xEF, 0xFD, 0xEF, 0xF7, 0x00, + 0x00, 0x3C, 0xFF, 0xFE, 0x70, 0x00, + 0x00, 0x00, 0x24, 0x30, 0x00, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0037[ 70] = { /* code 0037, DIGIT SEVEN */ + 0x49, 0x99, 0x99, 0x99, 0x94, + 0xBF, 0xFF, 0xFF, 0xFF, 0xFD, + 0x5B, 0xBB, 0xBB, 0xBF, 0xF9, + 0x00, 0x00, 0x00, 0x9F, 0xC0, + 0x00, 0x00, 0x05, 0xFE, 0x20, + 0x00, 0x00, 0x1E, 0xF6, 0x00, + 0x00, 0x00, 0x9F, 0xD0, 0x00, + 0x00, 0x02, 0xFF, 0x70, 0x00, + 0x00, 0x08, 0xFF, 0x10, 0x00, + 0x00, 0x0E, 0xFB, 0x00, 0x00, + 0x00, 0x4F, 0xF7, 0x00, 0x00, + 0x00, 0x7F, 0xF3, 0x00, 0x00, + 0x00, 0x6F, 0xD0, 0x00, 0x00, + 0x00, 0x03, 0x10, 0x00, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0038[ 84] = { /* code 0038, DIGIT EIGHT */ + 0x00, 0x17, 0xBB, 0xB8, 0x10, 0x00, + 0x02, 0xEF, 0xFF, 0xFF, 0xE3, 0x00, + 0x0B, 0xFE, 0x62, 0x6E, 0xFB, 0x00, + 0x0D, 0xFA, 0x00, 0x0A, 0xFF, 0x00, + 0x0C, 0xFB, 0x00, 0x0B, 0xFC, 0x00, + 0x04, 0xFF, 0xB8, 0xBF, 0xF4, 0x00, + 0x02, 0xBF, 0xFF, 0xFF, 0xB2, 0x00, + 0x0C, 0xFE, 0x64, 0x6E, 0xFD, 0x00, + 0x3F, 0xF7, 0x00, 0x07, 0xFF, 0x30, + 0x4F, 0xF6, 0x00, 0x06, 0xFF, 0x40, + 0x2F, 0xFC, 0x10, 0x1B, 0xFF, 0x20, + 0x09, 0xFF, 0xED, 0xEF, 0xF9, 0x00, + 0x00, 0x7E, 0xFF, 0xFE, 0x80, 0x00, + 0x00, 0x00, 0x24, 0x30, 0x00, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0039[ 84] = { /* code 0039, DIGIT NINE */ + 0x00, 0x17, 0xBB, 0xB6, 0x00, 0x00, + 0x03, 0xEF, 0xFF, 0xFF, 0xB0, 0x00, + 0x0C, 0xFE, 0x74, 0x8F, 0xF8, 0x00, + 0x3F, 0xF8, 0x00, 0x0A, 0xFE, 0x00, + 0x4F, 0xF6, 0x00, 0x07, 0xFF, 0x30, + 0x3F, 0xF7, 0x00, 0x0A, 0xFF, 0x40, + 0x0D, 0xFF, 0x74, 0x9F, 0xFF, 0x40, + 0x03, 0xEF, 0xFF, 0xFD, 0xFF, 0x40, + 0x00, 0x17, 0x99, 0x56, 0xFF, 0x20, + 0x00, 0x30, 0x00, 0x09, 0xFD, 0x00, + 0x09, 0xFA, 0x00, 0x3F, 0xF8, 0x00, + 0x08, 0xFF, 0xDB, 0xFF, 0xD1, 0x00, + 0x01, 0x9F, 0xFF, 0xFA, 0x20, 0x00, + 0x00, 0x01, 0x33, 0x10, 0x00, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_003A[ 22] = { /* code 003A, COLON */ + 0x05, 0x30, + 0x9F, 0xF2, + 0x9F, 0xF2, + 0x17, 0x40, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x3C, 0x90, + 0xBF, 0xF3, + 0x6F, 0xD1, + 0x01, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_003B[ 26] = { /* code 003B, SEMICOLON */ + 0x05, 0x30, + 0x9F, 0xF2, + 0x9F, 0xF2, + 0x17, 0x40, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x3C, 0x90, + 0xBF, 0xF5, + 0x6F, 0xF7, + 0x01, 0xE5, + 0x4C, 0xC0, + 0x67, 0x10 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_003C[ 60] = { /* code 003C, LESS-THAN SIGN */ + 0x00, 0x00, 0x00, 0x01, 0x8B, 0x20, + 0x00, 0x00, 0x02, 0x9F, 0xFF, 0x50, + 0x00, 0x03, 0xAF, 0xFF, 0xC6, 0x00, + 0x05, 0xCF, 0xFF, 0xB4, 0x00, 0x00, + 0x7F, 0xFF, 0x92, 0x00, 0x00, 0x00, + 0x5F, 0xFF, 0xB5, 0x00, 0x00, 0x00, + 0x02, 0x9F, 0xFF, 0xD7, 0x10, 0x00, + 0x00, 0x01, 0x7E, 0xFF, 0xF8, 0x10, + 0x00, 0x00, 0x00, 0x7D, 0xFF, 0x50, + 0x00, 0x00, 0x00, 0x00, 0x57, 0x10 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_003D[ 48] = { /* code 003D, EQUALS SIGN */ + 0x04, 0x44, 0x44, 0x44, 0x43, 0x00, + 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0x70, + 0x5D, 0xDD, 0xDD, 0xDD, 0xDC, 0x30, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x50, + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x50, + 0x02, 0x22, 0x22, 0x22, 0x21, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_003E[ 60] = { /* code 003E, GREATER-THAN SIGN */ + 0x4B, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x8F, 0xFE, 0x81, 0x00, 0x00, 0x00, + 0x17, 0xEF, 0xFF, 0x92, 0x00, 0x00, + 0x00, 0x05, 0xCF, 0xFF, 0xA3, 0x00, + 0x00, 0x00, 0x03, 0xAF, 0xFF, 0x40, + 0x00, 0x00, 0x06, 0xDF, 0xFE, 0x30, + 0x00, 0x28, 0xEF, 0xFE, 0x71, 0x00, + 0x1A, 0xFF, 0xFD, 0x60, 0x00, 0x00, + 0x9F, 0xFC, 0x50, 0x00, 0x00, 0x00, + 0x27, 0x30, 0x00, 0x00, 0x00, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_003F[ 75] = { /* code 003F, QUESTION MARK */ + 0x00, 0x00, 0x22, 0x00, 0x00, + 0x00, 0x7E, 0xFF, 0xFA, 0x20, + 0x09, 0xFF, 0xEE, 0xFF, 0xE1, + 0x2F, 0xFA, 0x00, 0x7F, 0xF7, + 0x2F, 0xE2, 0x00, 0x3F, 0xF7, + 0x02, 0x20, 0x00, 0xAF, 0xF5, + 0x00, 0x00, 0x1B, 0xFF, 0xA0, + 0x00, 0x00, 0xCF, 0xF7, 0x00, + 0x00, 0x05, 0xFF, 0x50, 0x00, + 0x00, 0x02, 0xEC, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0xBA, 0x10, 0x00, + 0x00, 0x08, 0xFF, 0x50, 0x00, + 0x00, 0x04, 0xFE, 0x20, 0x00, + 0x00, 0x00, 0x11, 0x00, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0040[105] = { /* code 0040, COMMERCIAL AT */ + 0x00, 0x00, 0x00, 0x34, 0x31, 0x00, 0x00, + 0x00, 0x02, 0x9E, 0xFF, 0xFF, 0xA2, 0x00, + 0x00, 0x3E, 0xFB, 0x76, 0x7A, 0xFE, 0x50, + 0x02, 0xEF, 0x50, 0x00, 0x00, 0x3E, 0xE2, + 0x0B, 0xF6, 0x07, 0xEE, 0x96, 0xB5, 0xF8, + 0x2F, 0xD0, 0x7F, 0xFF, 0xFF, 0xF0, 0xEC, + 0x5F, 0x91, 0xEF, 0x40, 0x8F, 0xC0, 0xBD, + 0x7F, 0x74, 0xFA, 0x00, 0x4F, 0x90, 0xCB, + 0x6F, 0x85, 0xFB, 0x00, 0x6F, 0x71, 0xF7, + 0x3F, 0xC2, 0xFF, 0x98, 0xEF, 0xAC, 0xD1, + 0x0C, 0xF4, 0x9F, 0xFF, 0xEF, 0xFB, 0x20, + 0x03, 0xFE, 0x45, 0x73, 0x37, 0x57, 0x00, + 0x00, 0x5E, 0xFB, 0x66, 0x69, 0xEE, 0x10, + 0x00, 0x02, 0x9F, 0xFF, 0xFF, 0xA2, 0x00, + 0x00, 0x00, 0x01, 0x34, 0x31, 0x00, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0041[ 90] = { /* code 0041, LATIN CAPITAL LETTER A */ + 0x00, 0x00, 0x02, 0x30, 0x00, 0x00, + 0x00, 0x00, 0x9F, 0xFB, 0x00, 0x00, + 0x00, 0x01, 0xFF, 0xFF, 0x30, 0x00, + 0x00, 0x06, 0xFF, 0xFF, 0x80, 0x00, + 0x00, 0x0C, 0xFD, 0xCF, 0xE0, 0x00, + 0x00, 0x3F, 0xF8, 0x7F, 0xF4, 0x00, + 0x00, 0x8F, 0xF3, 0x2F, 0xFA, 0x00, + 0x00, 0xEF, 0xD0, 0x0D, 0xFF, 0x10, + 0x04, 0xFF, 0x80, 0x08, 0xFF, 0x60, + 0x0A, 0xFF, 0xCB, 0xBC, 0xFF, 0xB0, + 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF2, + 0x7F, 0xF9, 0x44, 0x44, 0x9F, 0xF7, + 0xCF, 0xF3, 0x00, 0x00, 0x3F, 0xFC, + 0xAF, 0xC0, 0x00, 0x00, 0x0C, 0xFA, + 0x03, 0x10, 0x00, 0x00, 0x01, 0x30 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0042[ 78] = { /* code 0042, LATIN CAPITAL LETTER B */ + 0x3D, 0xFF, 0xFF, 0xED, 0xA3, 0x00, + 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0x30, + 0x9F, 0xF8, 0x44, 0x4C, 0xFF, 0xA0, + 0x9F, 0xF6, 0x00, 0x04, 0xFF, 0xB0, + 0x9F, 0xF6, 0x00, 0x06, 0xFF, 0x70, + 0x9F, 0xFB, 0x99, 0xBF, 0xFB, 0x10, + 0x9F, 0xFF, 0xFF, 0xFF, 0xFB, 0x20, + 0x9F, 0xF8, 0x44, 0x4A, 0xFF, 0xD0, + 0x9F, 0xF6, 0x00, 0x00, 0xCF, 0xF2, + 0x9F, 0xF6, 0x00, 0x00, 0xCF, 0xF3, + 0x9F, 0xF8, 0x44, 0x5A, 0xFF, 0xE0, + 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0x60, + 0x4E, 0xFF, 0xFF, 0xFE, 0xB4, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0043[ 90] = { /* code 0043, LATIN CAPITAL LETTER C */ + 0x00, 0x00, 0x13, 0x43, 0x00, 0x00, + 0x00, 0x2A, 0xFF, 0xFF, 0xE7, 0x00, + 0x03, 0xEF, 0xFF, 0xFF, 0xFF, 0xB0, + 0x1E, 0xFF, 0xB3, 0x25, 0xEF, 0xF6, + 0x7F, 0xFB, 0x00, 0x00, 0x4F, 0xF7, + 0xCF, 0xF3, 0x00, 0x00, 0x03, 0x61, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, + 0xDF, 0xF3, 0x00, 0x00, 0x05, 0x71, + 0x9F, 0xFA, 0x00, 0x00, 0x4F, 0xF7, + 0x3F, 0xFF, 0x93, 0x25, 0xEF, 0xF5, + 0x06, 0xFF, 0xFF, 0xFF, 0xFF, 0xA0, + 0x00, 0x4C, 0xFF, 0xFF, 0xE7, 0x00, + 0x00, 0x00, 0x24, 0x43, 0x00, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0044[ 78] = { /* code 0044, LATIN CAPITAL LETTER D */ + 0x3D, 0xFF, 0xFF, 0xEC, 0x71, 0x00, + 0x9F, 0xFF, 0xFF, 0xFF, 0xFE, 0x30, + 0x9F, 0xF9, 0x66, 0x7D, 0xFF, 0xD0, + 0x9F, 0xF6, 0x00, 0x01, 0xCF, 0xF6, + 0x9F, 0xF6, 0x00, 0x00, 0x5F, 0xFA, + 0x9F, 0xF6, 0x00, 0x00, 0x2F, 0xFD, + 0x9F, 0xF6, 0x00, 0x00, 0x2F, 0xFD, + 0x9F, 0xF6, 0x00, 0x00, 0x2F, 0xFC, + 0x9F, 0xF6, 0x00, 0x00, 0x6F, 0xFA, + 0x9F, 0xF6, 0x00, 0x01, 0xDF, 0xF5, + 0x9F, 0xF9, 0x66, 0x7D, 0xFF, 0xC0, + 0x9F, 0xFF, 0xFF, 0xFF, 0xFD, 0x20, + 0x4E, 0xFF, 0xFF, 0xFC, 0x71, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0045[ 78] = { /* code 0045, LATIN CAPITAL LETTER E */ + 0x3D, 0xFF, 0xFF, 0xFF, 0xFE, 0x50, + 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, + 0x9F, 0xF9, 0x66, 0x66, 0x65, 0x10, + 0x9F, 0xF6, 0x00, 0x00, 0x00, 0x00, + 0x9F, 0xF6, 0x00, 0x00, 0x00, 0x00, + 0x9F, 0xFD, 0xBB, 0xBB, 0xB6, 0x00, + 0x9F, 0xFF, 0xFF, 0xFF, 0xFB, 0x00, + 0x9F, 0xFA, 0x77, 0x77, 0x73, 0x00, + 0x9F, 0xF6, 0x00, 0x00, 0x00, 0x00, + 0x9F, 0xF6, 0x00, 0x00, 0x00, 0x00, + 0x9F, 0xF9, 0x66, 0x66, 0x65, 0x10, + 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0xA0, + 0x3D, 0xFF, 0xFF, 0xFF, 0xFF, 0x70 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0046[ 84] = { /* code 0046, LATIN CAPITAL LETTER F */ + 0x3D, 0xFF, 0xFF, 0xFF, 0xFB, 0x10, + 0x8F, 0xFF, 0xFF, 0xFF, 0xFF, 0x10, + 0x9F, 0xF9, 0x66, 0x66, 0x64, 0x00, + 0x9F, 0xF6, 0x00, 0x00, 0x00, 0x00, + 0x9F, 0xF6, 0x00, 0x00, 0x00, 0x00, + 0x9F, 0xFB, 0x99, 0x99, 0x70, 0x00, + 0x9F, 0xFF, 0xFF, 0xFF, 0xF3, 0x00, + 0x9F, 0xFD, 0xBB, 0xBB, 0x90, 0x00, + 0x9F, 0xF6, 0x00, 0x00, 0x00, 0x00, + 0x9F, 0xF6, 0x00, 0x00, 0x00, 0x00, + 0x9F, 0xF6, 0x00, 0x00, 0x00, 0x00, + 0x9F, 0xF6, 0x00, 0x00, 0x00, 0x00, + 0x5F, 0xF3, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x20, 0x00, 0x00, 0x00, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0047[105] = { /* code 0047, LATIN CAPITAL LETTER G */ + 0x00, 0x00, 0x03, 0x43, 0x10, 0x00, 0x00, + 0x00, 0x2A, 0xFF, 0xFF, 0xFA, 0x20, 0x00, + 0x03, 0xEF, 0xFF, 0xFF, 0xFF, 0xE2, 0x00, + 0x1E, 0xFF, 0xB4, 0x23, 0xAF, 0xFA, 0x00, + 0x8F, 0xFB, 0x00, 0x00, 0x0B, 0xF8, 0x00, + 0xCF, 0xF3, 0x00, 0x00, 0x00, 0x20, 0x00, + 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xFF, 0xD0, 0x00, 0x5D, 0xDD, 0xDD, 0x30, + 0xFF, 0xE0, 0x00, 0x8F, 0xFF, 0xFF, 0x60, + 0xDF, 0xF2, 0x00, 0x15, 0x69, 0xFF, 0x60, + 0x9F, 0xF9, 0x00, 0x00, 0x0B, 0xFF, 0x60, + 0x2F, 0xFF, 0x82, 0x02, 0x9F, 0xFF, 0x60, + 0x06, 0xFF, 0xFF, 0xFF, 0xFE, 0xEF, 0x60, + 0x00, 0x4C, 0xFF, 0xFF, 0xD3, 0x9F, 0x50, + 0x00, 0x00, 0x24, 0x43, 0x00, 0x03, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0048[ 90] = { /* code 0048, LATIN CAPITAL LETTER H */ + 0x02, 0x10, 0x00, 0x00, 0x01, 0x20, + 0x6F, 0xE2, 0x00, 0x00, 0x2E, 0xF6, + 0x9F, 0xF5, 0x00, 0x00, 0x5F, 0xF9, + 0x9F, 0xF6, 0x00, 0x00, 0x6F, 0xF9, + 0x9F, 0xF6, 0x00, 0x00, 0x6F, 0xF9, + 0x9F, 0xF6, 0x00, 0x00, 0x6F, 0xF9, + 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, + 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, + 0x9F, 0xFA, 0x77, 0x77, 0xAF, 0xF9, + 0x9F, 0xF6, 0x00, 0x00, 0x6F, 0xF9, + 0x9F, 0xF6, 0x00, 0x00, 0x6F, 0xF9, + 0x9F, 0xF6, 0x00, 0x00, 0x6F, 0xF9, + 0x9F, 0xF5, 0x00, 0x00, 0x5F, 0xF9, + 0x6F, 0xE2, 0x00, 0x00, 0x2E, 0xF7, + 0x03, 0x20, 0x00, 0x00, 0x02, 0x30 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0049[ 30] = { /* code 0049, LATIN CAPITAL LETTER I */ + 0x02, 0x10, + 0x6F, 0xE2, + 0x9F, 0xF5, + 0x9F, 0xF6, + 0x9F, 0xF6, + 0x9F, 0xF6, + 0x9F, 0xF6, + 0x9F, 0xF6, + 0x9F, 0xF6, + 0x9F, 0xF6, + 0x9F, 0xF6, + 0x9F, 0xF6, + 0x9F, 0xF5, + 0x6F, 0xE2, + 0x03, 0x20 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_004A[ 75] = { /* code 004A, LATIN CAPITAL LETTER J */ + 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x00, 0xBF, 0xB0, + 0x00, 0x00, 0x00, 0xFF, 0xF0, + 0x00, 0x00, 0x00, 0xFF, 0xF0, + 0x00, 0x00, 0x00, 0xFF, 0xF0, + 0x00, 0x00, 0x00, 0xFF, 0xF0, + 0x00, 0x00, 0x00, 0xFF, 0xF0, + 0x00, 0x00, 0x00, 0xFF, 0xF0, + 0x01, 0x00, 0x00, 0xFF, 0xF0, + 0x5F, 0xC0, 0x00, 0xFF, 0xF0, + 0x9F, 0xF1, 0x00, 0xFF, 0xE0, + 0x9F, 0xF6, 0x07, 0xFF, 0xB0, + 0x3F, 0xFF, 0xFF, 0xFF, 0x50, + 0x05, 0xEF, 0xFF, 0xF7, 0x00, + 0x00, 0x03, 0x43, 0x10, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_004B[ 90] = { /* code 004B, LATIN CAPITAL LETTER K */ + 0x02, 0x10, 0x00, 0x00, 0x11, 0x00, + 0x6F, 0xE2, 0x00, 0x02, 0xEF, 0x50, + 0x9F, 0xF5, 0x00, 0x1D, 0xFF, 0x60, + 0x9F, 0xF6, 0x01, 0xDF, 0xF8, 0x00, + 0x9F, 0xF6, 0x1B, 0xFF, 0x90, 0x00, + 0x9F, 0xF6, 0xAF, 0xFA, 0x00, 0x00, + 0x9F, 0xFE, 0xFF, 0xF4, 0x00, 0x00, + 0x9F, 0xFF, 0xFF, 0xFD, 0x00, 0x00, + 0x9F, 0xFF, 0xAD, 0xFF, 0x80, 0x00, + 0x9F, 0xFA, 0x03, 0xFF, 0xF3, 0x00, + 0x9F, 0xF6, 0x00, 0x9F, 0xFD, 0x00, + 0x9F, 0xF6, 0x00, 0x1D, 0xFF, 0x70, + 0x9F, 0xF5, 0x00, 0x04, 0xFF, 0xF1, + 0x6F, 0xE2, 0x00, 0x00, 0x9F, 0xE1, + 0x03, 0x20, 0x00, 0x00, 0x03, 0x10 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_004C[ 70] = { /* code 004C, LATIN CAPITAL LETTER L */ + 0x02, 0x10, 0x00, 0x00, 0x00, + 0x6F, 0xE2, 0x00, 0x00, 0x00, + 0x9F, 0xF5, 0x00, 0x00, 0x00, + 0x9F, 0xF6, 0x00, 0x00, 0x00, + 0x9F, 0xF6, 0x00, 0x00, 0x00, + 0x9F, 0xF6, 0x00, 0x00, 0x00, + 0x9F, 0xF6, 0x00, 0x00, 0x00, + 0x9F, 0xF6, 0x00, 0x00, 0x00, + 0x9F, 0xF6, 0x00, 0x00, 0x00, + 0x9F, 0xF6, 0x00, 0x00, 0x00, + 0x9F, 0xF6, 0x00, 0x00, 0x00, + 0x9F, 0xFA, 0x77, 0x77, 0x72, + 0x9F, 0xFF, 0xFF, 0xFF, 0xFB, + 0x4E, 0xFF, 0xFF, 0xFF, 0xF7 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_004D[105] = { /* code 004D, LATIN CAPITAL LETTER M */ + 0x02, 0x31, 0x00, 0x00, 0x00, 0x13, 0x20, + 0x7F, 0xFE, 0x30, 0x00, 0x02, 0xEF, 0xF7, + 0xBF, 0xFF, 0x80, 0x00, 0x08, 0xFF, 0xF9, + 0xBF, 0xFF, 0xD0, 0x00, 0x0C, 0xFF, 0xF9, + 0xBF, 0xFF, 0xF2, 0x00, 0x2F, 0xFF, 0xF9, + 0xBF, 0xFB, 0xF7, 0x00, 0x7F, 0xBF, 0xF9, + 0xBF, 0xF7, 0xFC, 0x00, 0xBF, 0x7F, 0xF9, + 0xBF, 0xF2, 0xFF, 0x21, 0xFF, 0x2F, 0xF9, + 0xBF, 0xF0, 0xCF, 0x65, 0xFC, 0x0F, 0xF9, + 0xBF, 0xF0, 0x8F, 0xBA, 0xF7, 0x0F, 0xF9, + 0xBF, 0xF0, 0x3F, 0xFE, 0xF3, 0x0F, 0xF9, + 0xBF, 0xF0, 0x0D, 0xFF, 0xD0, 0x0F, 0xF9, + 0xBF, 0xF0, 0x08, 0xFF, 0x80, 0x0F, 0xF9, + 0x8F, 0xB0, 0x03, 0xFF, 0x30, 0x0B, 0xF7, + 0x03, 0x10, 0x00, 0x22, 0x00, 0x01, 0x30 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_004E[ 90] = { /* code 004E, LATIN CAPITAL LETTER N */ + 0x01, 0x20, 0x00, 0x00, 0x01, 0x20, + 0x6F, 0xF8, 0x00, 0x00, 0x1E, 0xF8, + 0xAF, 0xFF, 0x30, 0x00, 0x2F, 0xFB, + 0xBF, 0xFF, 0xC0, 0x00, 0x2F, 0xFB, + 0xBF, 0xFF, 0xF7, 0x00, 0x2F, 0xFB, + 0xBF, 0xFC, 0xFE, 0x20, 0x2F, 0xFB, + 0xBF, 0xF4, 0xEF, 0xB0, 0x2F, 0xFB, + 0xBF, 0xF2, 0x7F, 0xF5, 0x2F, 0xFB, + 0xBF, 0xF2, 0x0C, 0xFD, 0x3F, 0xFB, + 0xBF, 0xF2, 0x03, 0xFF, 0xAF, 0xFB, + 0xBF, 0xF2, 0x00, 0x8F, 0xFF, 0xFB, + 0xBF, 0xF2, 0x00, 0x0D, 0xFF, 0xFB, + 0xBF, 0xF2, 0x00, 0x04, 0xFF, 0xFA, + 0x8F, 0xE1, 0x00, 0x00, 0x9F, 0xF6, + 0x03, 0x10, 0x00, 0x00, 0x03, 0x30 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_004F[105] = { /* code 004F, LATIN CAPITAL LETTER O */ + 0x00, 0x00, 0x01, 0x34, 0x30, 0x00, 0x00, + 0x00, 0x03, 0xBF, 0xFF, 0xFE, 0x91, 0x00, + 0x00, 0x6F, 0xFF, 0xFF, 0xFF, 0xFE, 0x20, + 0x03, 0xFF, 0xF9, 0x32, 0x4B, 0xFF, 0xD0, + 0x0B, 0xFF, 0x80, 0x00, 0x00, 0xCF, 0xF6, + 0x0F, 0xFF, 0x10, 0x00, 0x00, 0x5F, 0xFA, + 0x2F, 0xFC, 0x00, 0x00, 0x00, 0x2F, 0xFD, + 0x4F, 0xFB, 0x00, 0x00, 0x00, 0x2F, 0xFD, + 0x2F, 0xFC, 0x00, 0x00, 0x00, 0x2F, 0xFC, + 0x0F, 0xFF, 0x10, 0x00, 0x00, 0x5F, 0xF9, + 0x0A, 0xFF, 0x70, 0x00, 0x00, 0xCF, 0xF4, + 0x03, 0xFF, 0xF8, 0x22, 0x3B, 0xFF, 0xC0, + 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFD, 0x20, + 0x00, 0x05, 0xDF, 0xFF, 0xFF, 0x91, 0x00, + 0x00, 0x00, 0x02, 0x44, 0x31, 0x00, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0050[ 84] = { /* code 0050, LATIN CAPITAL LETTER P */ + 0x3D, 0xFF, 0xFF, 0xFD, 0xA3, 0x00, + 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0x40, + 0x9F, 0xF9, 0x66, 0x6B, 0xFF, 0xC0, + 0x9F, 0xF6, 0x00, 0x00, 0xEF, 0xF1, + 0x9F, 0xF6, 0x00, 0x00, 0xEF, 0xF1, + 0x9F, 0xF6, 0x00, 0x18, 0xFF, 0xD0, + 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0x60, + 0x9F, 0xFF, 0xFF, 0xFF, 0xE6, 0x00, + 0x9F, 0xF8, 0x44, 0x43, 0x00, 0x00, + 0x9F, 0xF6, 0x00, 0x00, 0x00, 0x00, + 0x9F, 0xF6, 0x00, 0x00, 0x00, 0x00, + 0x9F, 0xF5, 0x00, 0x00, 0x00, 0x00, + 0x6F, 0xE2, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x20, 0x00, 0x00, 0x00, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0051[105] = { /* code 0051, LATIN CAPITAL LETTER Q */ + 0x00, 0x00, 0x01, 0x34, 0x30, 0x00, 0x00, + 0x00, 0x03, 0xBF, 0xFF, 0xFE, 0x91, 0x00, + 0x00, 0x6F, 0xFF, 0xFF, 0xFF, 0xFE, 0x20, + 0x03, 0xFF, 0xF9, 0x32, 0x4B, 0xFF, 0xD0, + 0x0B, 0xFF, 0x80, 0x00, 0x00, 0xCF, 0xF6, + 0x0F, 0xFF, 0x10, 0x00, 0x00, 0x5F, 0xFA, + 0x2F, 0xFC, 0x00, 0x00, 0x00, 0x2F, 0xFD, + 0x4F, 0xFB, 0x00, 0x00, 0x00, 0x2F, 0xFD, + 0x2F, 0xFC, 0x00, 0x00, 0x00, 0x2F, 0xFC, + 0x0F, 0xFF, 0x10, 0x04, 0xB2, 0x5F, 0xF9, + 0x0A, 0xFF, 0x70, 0x09, 0xFE, 0xCF, 0xF4, + 0x03, 0xFF, 0xF8, 0x23, 0xCF, 0xFF, 0xC0, + 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x60, + 0x00, 0x05, 0xDF, 0xFF, 0xFF, 0xBF, 0xF4, + 0x00, 0x00, 0x02, 0x44, 0x30, 0x08, 0xF4 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0052[ 84] = { /* code 0052, LATIN CAPITAL LETTER R */ + 0x3D, 0xFF, 0xFF, 0xFE, 0xC7, 0x10, + 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0xB0, + 0x9F, 0xF9, 0x66, 0x67, 0xEF, 0xF4, + 0x9F, 0xF6, 0x00, 0x00, 0x9F, 0xF7, + 0x9F, 0xF6, 0x00, 0x00, 0x8F, 0xF5, + 0x9F, 0xF8, 0x44, 0x46, 0xEF, 0xD0, + 0x9F, 0xFF, 0xFF, 0xFF, 0xFC, 0x20, + 0x9F, 0xFF, 0xFF, 0xFF, 0xFF, 0x70, + 0x9F, 0xF6, 0x00, 0x06, 0xFF, 0xE0, + 0x9F, 0xF6, 0x00, 0x00, 0xDF, 0xF0, + 0x9F, 0xF6, 0x00, 0x00, 0xBF, 0xF1, + 0x9F, 0xF5, 0x00, 0x00, 0xBF, 0xF5, + 0x6F, 0xE2, 0x00, 0x00, 0x5F, 0xF4, + 0x03, 0x20, 0x00, 0x00, 0x03, 0x20 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0053[ 90] = { /* code 0053, LATIN CAPITAL LETTER S */ + 0x00, 0x00, 0x24, 0x41, 0x00, 0x00, + 0x00, 0x5D, 0xFF, 0xFF, 0xC4, 0x00, + 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0x70, + 0x0E, 0xFE, 0x40, 0x16, 0xEF, 0xF0, + 0x2F, 0xFA, 0x00, 0x00, 0x4D, 0x90, + 0x1F, 0xFF, 0x72, 0x00, 0x00, 0x00, + 0x0B, 0xFF, 0xFF, 0xDA, 0x61, 0x00, + 0x01, 0xAF, 0xFF, 0xFF, 0xFE, 0x50, + 0x00, 0x01, 0x69, 0xDF, 0xFF, 0xF2, + 0x01, 0x10, 0x00, 0x02, 0xCF, 0xF7, + 0x2E, 0xF4, 0x00, 0x00, 0x6F, 0xF7, + 0x2F, 0xFE, 0x40, 0x02, 0xDF, 0xF5, + 0x09, 0xFF, 0xFE, 0xDF, 0xFF, 0xC0, + 0x00, 0x6D, 0xFF, 0xFF, 0xF9, 0x10, + 0x00, 0x00, 0x34, 0x43, 0x10, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0054[ 84] = { /* code 0054, LATIN CAPITAL LETTER T */ + 0x6E, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, + 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, + 0x27, 0x77, 0xBF, 0xFB, 0x77, 0x72, + 0x00, 0x00, 0x7F, 0xF7, 0x00, 0x00, + 0x00, 0x00, 0x7F, 0xF7, 0x00, 0x00, + 0x00, 0x00, 0x7F, 0xF7, 0x00, 0x00, + 0x00, 0x00, 0x7F, 0xF7, 0x00, 0x00, + 0x00, 0x00, 0x7F, 0xF7, 0x00, 0x00, + 0x00, 0x00, 0x7F, 0xF7, 0x00, 0x00, + 0x00, 0x00, 0x7F, 0xF7, 0x00, 0x00, + 0x00, 0x00, 0x7F, 0xF7, 0x00, 0x00, + 0x00, 0x00, 0x7F, 0xF7, 0x00, 0x00, + 0x00, 0x00, 0x4F, 0xF4, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x20, 0x00, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0055[ 90] = { /* code 0055, LATIN CAPITAL LETTER U */ + 0x02, 0x10, 0x00, 0x00, 0x01, 0x20, + 0x6F, 0xE2, 0x00, 0x00, 0x2E, 0xF6, + 0x9F, 0xF5, 0x00, 0x00, 0x5F, 0xF9, + 0x9F, 0xF6, 0x00, 0x00, 0x6F, 0xF9, + 0x9F, 0xF6, 0x00, 0x00, 0x6F, 0xF9, + 0x9F, 0xF6, 0x00, 0x00, 0x6F, 0xF9, + 0x9F, 0xF6, 0x00, 0x00, 0x6F, 0xF9, + 0x9F, 0xF6, 0x00, 0x00, 0x6F, 0xF9, + 0x9F, 0xF6, 0x00, 0x00, 0x6F, 0xF9, + 0x9F, 0xF6, 0x00, 0x00, 0x6F, 0xF9, + 0x7F, 0xF7, 0x00, 0x00, 0x7F, 0xF8, + 0x3F, 0xFE, 0x62, 0x26, 0xEF, 0xF3, + 0x0A, 0xFF, 0xFF, 0xFF, 0xFF, 0xA0, + 0x00, 0x7E, 0xFF, 0xFF, 0xE7, 0x00, + 0x00, 0x00, 0x34, 0x43, 0x00, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0056[ 90] = { /* code 0056, LATIN CAPITAL LETTER V */ + 0x02, 0x00, 0x00, 0x00, 0x01, 0x10, + 0xAF, 0xC0, 0x00, 0x00, 0x2E, 0xF5, + 0xCF, 0xF4, 0x00, 0x00, 0x7F, 0xF7, + 0x7F, 0xF9, 0x00, 0x00, 0xCF, 0xF2, + 0x2F, 0xFD, 0x00, 0x02, 0xFF, 0xB0, + 0x0B, 0xFF, 0x30, 0x07, 0xFF, 0x60, + 0x06, 0xFF, 0x70, 0x0B, 0xFF, 0x10, + 0x01, 0xFF, 0xB0, 0x1F, 0xFA, 0x00, + 0x00, 0xAF, 0xF1, 0x6F, 0xF5, 0x00, + 0x00, 0x5F, 0xF6, 0xBF, 0xE0, 0x00, + 0x00, 0x0E, 0xFB, 0xFF, 0x80, 0x00, + 0x00, 0x09, 0xFF, 0xFF, 0x30, 0x00, + 0x00, 0x04, 0xFF, 0xFD, 0x00, 0x00, + 0x00, 0x00, 0xCF, 0xF6, 0x00, 0x00, + 0x00, 0x00, 0x03, 0x20, 0x00, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0057[135] = { /* code 0057, LATIN CAPITAL LETTER W */ + 0x02, 0x00, 0x00, 0x01, 0x20, 0x00, 0x00, 0x11, 0x00, + 0xAF, 0xC0, 0x00, 0x2E, 0xFB, 0x00, 0x01, 0xEF, 0x50, + 0xCF, 0xF1, 0x00, 0x6F, 0xFF, 0x10, 0x05, 0xFF, 0x70, + 0x8F, 0xF4, 0x00, 0x9F, 0xFF, 0x40, 0x08, 0xFF, 0x30, + 0x4F, 0xF7, 0x00, 0xCF, 0xFF, 0x80, 0x0B, 0xFE, 0x00, + 0x1F, 0xFA, 0x01, 0xFF, 0xAF, 0xB0, 0x0E, 0xFB, 0x00, + 0x0C, 0xFD, 0x05, 0xFE, 0x4F, 0xF0, 0x3F, 0xF7, 0x00, + 0x08, 0xFF, 0x18, 0xFA, 0x0F, 0xF3, 0x6F, 0xF3, 0x00, + 0x04, 0xFF, 0x4B, 0xF7, 0x0B, 0xF7, 0x9F, 0xE0, 0x00, + 0x00, 0xFF, 0x8F, 0xF3, 0x08, 0xFA, 0xCF, 0xA0, 0x00, + 0x00, 0xBF, 0xDF, 0xE0, 0x04, 0xFE, 0xFF, 0x70, 0x00, + 0x00, 0x7F, 0xFF, 0xA0, 0x01, 0xFF, 0xFF, 0x20, 0x00, + 0x00, 0x4F, 0xFF, 0x70, 0x00, 0xCF, 0xFE, 0x00, 0x00, + 0x00, 0x0C, 0xFE, 0x20, 0x00, 0x6F, 0xF8, 0x00, 0x00, + 0x00, 0x01, 0x41, 0x00, 0x00, 0x03, 0x30, 0x00, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0058[ 90] = { /* code 0058, LATIN CAPITAL LETTER X */ + 0x01, 0x10, 0x00, 0x00, 0x11, 0x00, + 0x3F, 0xF3, 0x00, 0x04, 0xFF, 0x20, + 0x5F, 0xFC, 0x00, 0x0D, 0xFF, 0x30, + 0x0D, 0xFF, 0x60, 0x8F, 0xFA, 0x00, + 0x03, 0xFF, 0xE3, 0xFF, 0xD1, 0x00, + 0x00, 0x8F, 0xFF, 0xFF, 0x40, 0x00, + 0x00, 0x0D, 0xFF, 0xF9, 0x00, 0x00, + 0x00, 0x07, 0xFF, 0xF3, 0x00, 0x00, + 0x00, 0x2F, 0xFF, 0xFC, 0x00, 0x00, + 0x00, 0xCF, 0xFD, 0xFF, 0x70, 0x00, + 0x07, 0xFF, 0xB2, 0xFF, 0xF3, 0x00, + 0x3F, 0xFF, 0x20, 0x8F, 0xFC, 0x00, + 0xAF, 0xF7, 0x00, 0x0D, 0xFF, 0x60, + 0xAF, 0xC0, 0x00, 0x05, 0xFF, 0x40, + 0x03, 0x10, 0x00, 0x00, 0x32, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0059[ 90] = { /* code 0059, LATIN CAPITAL LETTER Y */ + 0x02, 0x10, 0x00, 0x00, 0x02, 0x00, + 0x9F, 0xC0, 0x00, 0x00, 0xBF, 0x90, + 0xBF, 0xF7, 0x00, 0x05, 0xFF, 0xC0, + 0x4F, 0xFE, 0x10, 0x0D, 0xFF, 0x40, + 0x0A, 0xFF, 0x80, 0x6F, 0xFA, 0x00, + 0x01, 0xEF, 0xF2, 0xEF, 0xE2, 0x00, + 0x00, 0x7F, 0xFE, 0xFF, 0x70, 0x00, + 0x00, 0x0C, 0xFF, 0xFD, 0x00, 0x00, + 0x00, 0x03, 0xFF, 0xF4, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0x00, 0xFF, 0xF0, 0x00, 0x00, + 0x00, 0x00, 0xCF, 0xC0, 0x00, 0x00, + 0x00, 0x00, 0x03, 0x00, 0x00, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_005A[ 78] = { /* code 005A, LATIN CAPITAL LETTER Z */ + 0x09, 0xFF, 0xFF, 0xFF, 0xFF, 0xE6, + 0x0E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, + 0x03, 0x77, 0x77, 0x7B, 0xFF, 0xF4, + 0x00, 0x00, 0x00, 0x3E, 0xFF, 0x60, + 0x00, 0x00, 0x01, 0xDF, 0xF8, 0x00, + 0x00, 0x00, 0x0C, 0xFF, 0xB0, 0x00, + 0x00, 0x00, 0xAF, 0xFC, 0x10, 0x00, + 0x00, 0x07, 0xFF, 0xE2, 0x00, 0x00, + 0x00, 0x5F, 0xFF, 0x30, 0x00, 0x00, + 0x03, 0xFF, 0xF5, 0x00, 0x00, 0x00, + 0x2E, 0xFF, 0xD7, 0x77, 0x77, 0x72, + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB, + 0x3D, 0xFF, 0xFF, 0xFF, 0xFF, 0xF7 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_005B[ 51] = { /* code 005B, LEFT SQUARE BRACKET */ + 0x3D, 0xFF, 0xE2, + 0x7F, 0xFF, 0xE2, + 0x7F, 0xF0, 0x00, + 0x7F, 0xF0, 0x00, + 0x7F, 0xF0, 0x00, + 0x7F, 0xF0, 0x00, + 0x7F, 0xF0, 0x00, + 0x7F, 0xF0, 0x00, + 0x7F, 0xF0, 0x00, + 0x7F, 0xF0, 0x00, + 0x7F, 0xF0, 0x00, + 0x7F, 0xF0, 0x00, + 0x7F, 0xF0, 0x00, + 0x7F, 0xF0, 0x00, + 0x7F, 0xF9, 0x91, + 0x4F, 0xFF, 0xF3, + 0x03, 0x66, 0x40 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_005C[ 60] = { /* code 005C, REVERSE SOLIDUS */ + 0x12, 0x00, 0x00, 0x00, + 0xCF, 0x10, 0x00, 0x00, + 0x9F, 0x70, 0x00, 0x00, + 0x4F, 0xC0, 0x00, 0x00, + 0x0D, 0xF3, 0x00, 0x00, + 0x07, 0xF9, 0x00, 0x00, + 0x02, 0xFE, 0x00, 0x00, + 0x00, 0xBF, 0x50, 0x00, + 0x00, 0x5F, 0xB0, 0x00, + 0x00, 0x0E, 0xF2, 0x00, + 0x00, 0x09, 0xF7, 0x00, + 0x00, 0x03, 0xFD, 0x00, + 0x00, 0x00, 0xCF, 0x40, + 0x00, 0x00, 0x6F, 0x70, + 0x00, 0x00, 0x04, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_005D[ 51] = { /* code 005D, RIGHT SQUARE BRACKET */ + 0xBF, 0xFE, 0x60, + 0xCF, 0xFF, 0xB0, + 0x00, 0x9F, 0xB0, + 0x00, 0x9F, 0xB0, + 0x00, 0x9F, 0xB0, + 0x00, 0x9F, 0xB0, + 0x00, 0x9F, 0xB0, + 0x00, 0x9F, 0xB0, + 0x00, 0x9F, 0xB0, + 0x00, 0x9F, 0xB0, + 0x00, 0x9F, 0xB0, + 0x00, 0x9F, 0xB0, + 0x00, 0x9F, 0xB0, + 0x00, 0x9F, 0xB0, + 0x79, 0xDF, 0xB0, + 0xEF, 0xFF, 0x90, + 0x25, 0x64, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_005E[ 40] = { /* code 005E, CIRCUMFLEX ACCENT */ + 0x00, 0x03, 0x72, 0x00, 0x00, + 0x00, 0x0E, 0xFB, 0x00, 0x00, + 0x00, 0x7F, 0xFF, 0x50, 0x00, + 0x01, 0xEF, 0xAF, 0xD0, 0x00, + 0x09, 0xFB, 0x0D, 0xF6, 0x00, + 0x2F, 0xF3, 0x06, 0xFE, 0x10, + 0xAF, 0x90, 0x00, 0xCF, 0x70, + 0x69, 0x10, 0x00, 0x39, 0x50 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_005F[ 12] = { /* code 005F, LOW LINE */ + 0x49, 0x99, 0x99, 0x99, 0x99, 0x40, + 0x14, 0x44, 0x44, 0x44, 0x44, 0x10 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0060[ 8] = { /* code 0060, GRAVE ACCENT */ + 0x78, 0x00, + 0xEF, 0xC2, + 0x3C, 0xFE, + 0x00, 0x78 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0061[ 55] = { /* code 0061, LATIN SMALL LETTER A */ + 0x00, 0x05, 0x99, 0x96, 0x10, + 0x02, 0xDF, 0xFF, 0xFF, 0xE3, + 0x09, 0xFE, 0x74, 0x8F, 0xFB, + 0x04, 0xB3, 0x00, 0x0E, 0xFB, + 0x00, 0x15, 0x79, 0xCF, 0xFB, + 0x06, 0xFF, 0xFF, 0xDE, 0xFB, + 0x2F, 0xFC, 0x41, 0x0D, 0xFB, + 0x4F, 0xF6, 0x00, 0x3F, 0xFB, + 0x2F, 0xFE, 0x89, 0xEE, 0xFD, + 0x05, 0xEF, 0xFE, 0x67, 0xFE, + 0x00, 0x13, 0x30, 0x00, 0x31 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0062[ 75] = { /* code 0062, LATIN SMALL LETTER B */ + 0x02, 0x00, 0x00, 0x00, 0x00, + 0xCF, 0x80, 0x00, 0x00, 0x00, + 0xFF, 0x90, 0x00, 0x00, 0x00, + 0xFF, 0x90, 0x00, 0x00, 0x00, + 0xFF, 0x92, 0x89, 0x71, 0x00, + 0xFF, 0xCE, 0xFF, 0xFE, 0x20, + 0xFF, 0xFB, 0x69, 0xFF, 0xB0, + 0xFF, 0xE0, 0x00, 0xAF, 0xF2, + 0xFF, 0x90, 0x00, 0x5F, 0xF4, + 0xFF, 0x80, 0x00, 0x4F, 0xF6, + 0xFF, 0xB0, 0x00, 0x7F, 0xF3, + 0xFF, 0xF3, 0x02, 0xDF, 0xE0, + 0xFF, 0xEF, 0xDF, 0xFF, 0x70, + 0xDF, 0x6C, 0xFF, 0xF7, 0x00, + 0x13, 0x00, 0x33, 0x10, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0063[ 55] = { /* code 0063, LATIN SMALL LETTER C */ + 0x00, 0x05, 0x99, 0x83, 0x00, + 0x01, 0xCF, 0xFF, 0xFF, 0xA0, + 0x0B, 0xFF, 0xA6, 0xBF, 0xF3, + 0x3F, 0xF9, 0x00, 0x0B, 0xD2, + 0x6F, 0xF4, 0x00, 0x00, 0x00, + 0x7F, 0xF2, 0x00, 0x00, 0x00, + 0x5F, 0xF4, 0x00, 0x04, 0x70, + 0x2F, 0xFC, 0x10, 0x3F, 0xF4, + 0x09, 0xFF, 0xED, 0xFF, 0xE1, + 0x00, 0x8E, 0xFF, 0xFC, 0x30, + 0x00, 0x00, 0x34, 0x20, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0064[ 75] = { /* code 0064, LATIN SMALL LETTER D */ + 0x00, 0x00, 0x00, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x08, 0xFC, + 0x00, 0x00, 0x00, 0x09, 0xFF, + 0x00, 0x00, 0x00, 0x09, 0xFF, + 0x00, 0x17, 0x98, 0x29, 0xFF, + 0x02, 0xEF, 0xFF, 0xEC, 0xFF, + 0x0B, 0xFF, 0x96, 0xBF, 0xFF, + 0x2F, 0xFA, 0x00, 0x0E, 0xFF, + 0x5F, 0xF5, 0x00, 0x09, 0xFF, + 0x6F, 0xF4, 0x00, 0x08, 0xFF, + 0x4F, 0xF7, 0x00, 0x0B, 0xFF, + 0x1E, 0xFD, 0x20, 0x3F, 0xFF, + 0x07, 0xFF, 0xFD, 0xFE, 0xFF, + 0x00, 0x7F, 0xFF, 0xC6, 0xFD, + 0x00, 0x01, 0x32, 0x00, 0x31 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0065[ 66] = { /* code 0065, LATIN SMALL LETTER E */ + 0x00, 0x03, 0x89, 0x95, 0x00, 0x00, + 0x00, 0xAF, 0xFF, 0xFF, 0xC1, 0x00, + 0x09, 0xFF, 0x74, 0x6E, 0xFB, 0x00, + 0x1F, 0xF8, 0x00, 0x05, 0xFF, 0x30, + 0x4F, 0xFC, 0xBB, 0xBC, 0xFF, 0x60, + 0x6F, 0xFC, 0xBB, 0xBB, 0xBB, 0x30, + 0x4F, 0xF6, 0x00, 0x00, 0x10, 0x00, + 0x0E, 0xFD, 0x20, 0x06, 0xFA, 0x00, + 0x05, 0xFF, 0xFD, 0xEF, 0xFA, 0x00, + 0x00, 0x5D, 0xFF, 0xFE, 0x91, 0x00, + 0x00, 0x00, 0x24, 0x30, 0x00, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0066[ 60] = { /* code 0066, LATIN SMALL LETTER F */ + 0x00, 0x01, 0x42, 0x00, + 0x00, 0x6F, 0xFF, 0x50, + 0x01, 0xFF, 0xFD, 0x40, + 0x02, 0xFF, 0x80, 0x00, + 0x37, 0xFF, 0xA6, 0x10, + 0xBF, 0xFF, 0xFF, 0x70, + 0x26, 0xFF, 0xA4, 0x10, + 0x02, 0xFF, 0x70, 0x00, + 0x02, 0xFF, 0x70, 0x00, + 0x02, 0xFF, 0x70, 0x00, + 0x02, 0xFF, 0x70, 0x00, + 0x02, 0xFF, 0x70, 0x00, + 0x02, 0xFF, 0x70, 0x00, + 0x01, 0xEF, 0x60, 0x00, + 0x00, 0x13, 0x00, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0067[ 70] = { /* code 0067, LATIN SMALL LETTER G */ + 0x00, 0x16, 0x98, 0x31, 0x96, + 0x02, 0xDF, 0xFF, 0xFA, 0xFE, + 0x0B, 0xFF, 0xA6, 0xBF, 0xFF, + 0x2F, 0xF9, 0x00, 0x0C, 0xFF, + 0x5F, 0xF5, 0x00, 0x09, 0xFF, + 0x6F, 0xF4, 0x00, 0x09, 0xFF, + 0x3F, 0xF8, 0x00, 0x0C, 0xFF, + 0x0E, 0xFF, 0x64, 0x8F, 0xFF, + 0x04, 0xFF, 0xFF, 0xFE, 0xFF, + 0x00, 0x38, 0xBA, 0x49, 0xFF, + 0x01, 0x61, 0x00, 0x0B, 0xFC, + 0x09, 0xFD, 0x32, 0x6F, 0xF7, + 0x05, 0xFF, 0xFF, 0xFF, 0xB1, + 0x00, 0x39, 0xCD, 0xB7, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0068[ 75] = { /* code 0068, LATIN SMALL LETTER H */ + 0x02, 0x00, 0x00, 0x00, 0x00, + 0xCF, 0x80, 0x00, 0x00, 0x00, + 0xFF, 0x90, 0x00, 0x00, 0x00, + 0xFF, 0x90, 0x00, 0x00, 0x00, + 0xFF, 0x91, 0x79, 0x83, 0x00, + 0xFF, 0xBE, 0xFF, 0xFF, 0x40, + 0xFF, 0xFD, 0x8B, 0xFF, 0xB0, + 0xFF, 0xE1, 0x00, 0xDF, 0xE0, + 0xFF, 0xA0, 0x00, 0x9F, 0xF0, + 0xFF, 0x90, 0x00, 0x9F, 0xF0, + 0xFF, 0x90, 0x00, 0x9F, 0xF0, + 0xFF, 0x90, 0x00, 0x9F, 0xF0, + 0xFF, 0x90, 0x00, 0x9F, 0xF0, + 0xCF, 0x80, 0x00, 0x8F, 0xC0, + 0x13, 0x00, 0x00, 0x03, 0x10 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0069[ 30] = { /* code 0069, LATIN SMALL LETTER I */ + 0x04, 0x00, + 0xAF, 0xB0, + 0xCF, 0xC0, + 0x27, 0x20, + 0x49, 0x40, + 0xCF, 0xC0, + 0xDF, 0xD0, + 0xDF, 0xD0, + 0xDF, 0xD0, + 0xDF, 0xD0, + 0xDF, 0xD0, + 0xDF, 0xD0, + 0xDF, 0xD0, + 0xAF, 0xA0, + 0x04, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_006A[ 54] = { /* code 006A, LATIN SMALL LETTER J */ + 0x00, 0x04, 0x00, + 0x00, 0xAF, 0xB0, + 0x00, 0xCF, 0xC0, + 0x00, 0x27, 0x20, + 0x00, 0x49, 0x40, + 0x00, 0xCF, 0xC0, + 0x00, 0xDF, 0xD0, + 0x00, 0xDF, 0xD0, + 0x00, 0xDF, 0xD0, + 0x00, 0xDF, 0xD0, + 0x00, 0xDF, 0xD0, + 0x00, 0xDF, 0xD0, + 0x00, 0xDF, 0xD0, + 0x00, 0xDF, 0xD0, + 0x00, 0xDF, 0xD0, + 0x05, 0xEF, 0xB0, + 0x4F, 0xFF, 0x80, + 0x1A, 0xB7, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_006B[ 75] = { /* code 006B, LATIN SMALL LETTER K */ + 0x02, 0x00, 0x00, 0x00, 0x00, + 0xCF, 0x80, 0x00, 0x00, 0x00, + 0xFF, 0x90, 0x00, 0x00, 0x00, + 0xFF, 0x90, 0x00, 0x00, 0x00, + 0xFF, 0x90, 0x02, 0x93, 0x00, + 0xFF, 0x90, 0x1D, 0xFC, 0x00, + 0xFF, 0x91, 0xDF, 0xF5, 0x00, + 0xFF, 0xAB, 0xFF, 0x60, 0x00, + 0xFF, 0xFF, 0xFB, 0x00, 0x00, + 0xFF, 0xFF, 0xFF, 0x40, 0x00, + 0xFF, 0xE6, 0xFF, 0xE2, 0x00, + 0xFF, 0x90, 0x6F, 0xFB, 0x00, + 0xFF, 0x90, 0x0B, 0xFF, 0x60, + 0xCF, 0x80, 0x01, 0xEF, 0x50, + 0x13, 0x00, 0x00, 0x13, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_006C[ 30] = { /* code 006C, LATIN SMALL LETTER L */ + 0x02, 0x00, + 0xAF, 0xA0, + 0xDF, 0xD0, + 0xDF, 0xD0, + 0xDF, 0xD0, + 0xDF, 0xD0, + 0xDF, 0xD0, + 0xDF, 0xD0, + 0xDF, 0xD0, + 0xDF, 0xD0, + 0xDF, 0xD0, + 0xDF, 0xD0, + 0xDF, 0xD0, + 0xAF, 0xA0, + 0x03, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_006D[ 88] = { /* code 006D, LATIN SMALL LETTER M */ + 0x59, 0x11, 0x79, 0x82, 0x03, 0x89, 0x72, 0x00, + 0xEF, 0x9D, 0xFF, 0xFE, 0x6F, 0xFF, 0xFE, 0x20, + 0xFF, 0xFC, 0x8C, 0xFF, 0xFC, 0x8C, 0xFF, 0x70, + 0xFF, 0xE1, 0x02, 0xFF, 0xD1, 0x02, 0xFF, 0x90, + 0xFF, 0xA0, 0x00, 0xFF, 0xA0, 0x00, 0xFF, 0x90, + 0xFF, 0x90, 0x00, 0xFF, 0x90, 0x00, 0xFF, 0x90, + 0xFF, 0x90, 0x00, 0xFF, 0x90, 0x00, 0xFF, 0x90, + 0xFF, 0x90, 0x00, 0xFF, 0x90, 0x00, 0xFF, 0x90, + 0xFF, 0x90, 0x00, 0xFF, 0x90, 0x00, 0xFF, 0x90, + 0xCF, 0x80, 0x00, 0xDF, 0x80, 0x00, 0xDF, 0x70, + 0x13, 0x00, 0x00, 0x13, 0x00, 0x00, 0x13, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_006E[ 55] = { /* code 006E, LATIN SMALL LETTER N */ + 0x59, 0x11, 0x79, 0x83, 0x00, + 0xEF, 0x8E, 0xFF, 0xFF, 0x40, + 0xFF, 0xFD, 0x8B, 0xFF, 0xB0, + 0xFF, 0xE1, 0x00, 0xDF, 0xE0, + 0xFF, 0xA0, 0x00, 0x9F, 0xF0, + 0xFF, 0x90, 0x00, 0x9F, 0xF0, + 0xFF, 0x90, 0x00, 0x9F, 0xF0, + 0xFF, 0x90, 0x00, 0x9F, 0xF0, + 0xFF, 0x90, 0x00, 0x9F, 0xF0, + 0xCF, 0x80, 0x00, 0x8F, 0xC0, + 0x13, 0x00, 0x00, 0x03, 0x10 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_006F[ 66] = { /* code 006F, LATIN SMALL LETTER O */ + 0x00, 0x04, 0x89, 0x84, 0x00, 0x00, + 0x01, 0xBF, 0xFF, 0xFF, 0xB1, 0x00, + 0x0A, 0xFF, 0x95, 0x8F, 0xFA, 0x00, + 0x1F, 0xFA, 0x00, 0x0A, 0xFF, 0x20, + 0x5F, 0xF5, 0x00, 0x05, 0xFF, 0x50, + 0x6F, 0xF4, 0x00, 0x04, 0xFF, 0x60, + 0x4F, 0xF7, 0x00, 0x06, 0xFF, 0x40, + 0x0E, 0xFD, 0x10, 0x1D, 0xFE, 0x10, + 0x07, 0xFF, 0xEB, 0xEF, 0xF7, 0x00, + 0x00, 0x6E, 0xFF, 0xFE, 0x60, 0x00, + 0x00, 0x00, 0x34, 0x30, 0x00, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0070[ 70] = { /* code 0070, LATIN SMALL LETTER P */ + 0x69, 0x13, 0x99, 0x61, 0x00, + 0xEF, 0xAF, 0xFF, 0xFD, 0x20, + 0xFF, 0xFB, 0x6A, 0xFF, 0xB0, + 0xFF, 0xD0, 0x00, 0xAF, 0xF2, + 0xFF, 0x90, 0x00, 0x5F, 0xF4, + 0xFF, 0x80, 0x00, 0x4F, 0xF6, + 0xFF, 0xB0, 0x00, 0x7F, 0xF3, + 0xFF, 0xF3, 0x01, 0xDF, 0xE1, + 0xFF, 0xFF, 0xDE, 0xFF, 0x80, + 0xFF, 0xAB, 0xFF, 0xF9, 0x00, + 0xFF, 0x90, 0x24, 0x10, 0x00, + 0xFF, 0x90, 0x00, 0x00, 0x00, + 0xEF, 0x90, 0x00, 0x00, 0x00, + 0x6B, 0x30, 0x00, 0x00, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0071[ 70] = { /* code 0071, LATIN SMALL LETTER Q */ + 0x00, 0x16, 0x99, 0x31, 0x96, + 0x02, 0xDF, 0xFF, 0xFA, 0xFE, + 0x0B, 0xFF, 0xA6, 0xBF, 0xFF, + 0x2F, 0xFA, 0x00, 0x0D, 0xFF, + 0x5F, 0xF5, 0x00, 0x09, 0xFF, + 0x6F, 0xF4, 0x00, 0x08, 0xFF, + 0x4F, 0xF7, 0x00, 0x0B, 0xFF, + 0x1F, 0xFD, 0x10, 0x3F, 0xFF, + 0x08, 0xFF, 0xED, 0xFF, 0xFF, + 0x00, 0x9F, 0xFF, 0xBA, 0xFF, + 0x00, 0x01, 0x42, 0x09, 0xFF, + 0x00, 0x00, 0x00, 0x09, 0xFF, + 0x00, 0x00, 0x00, 0x09, 0xFE, + 0x00, 0x00, 0x00, 0x03, 0xB6 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0072[ 44] = { /* code 0072, LATIN SMALL LETTER R */ + 0x49, 0x22, 0x97, 0x00, + 0xCF, 0x9E, 0xFF, 0x30, + 0xDF, 0xFF, 0xFB, 0x10, + 0xDF, 0xF5, 0x00, 0x00, + 0xDF, 0xE0, 0x00, 0x00, + 0xDF, 0xD0, 0x00, 0x00, + 0xDF, 0xD0, 0x00, 0x00, + 0xDF, 0xD0, 0x00, 0x00, + 0xDF, 0xD0, 0x00, 0x00, + 0xAF, 0xA0, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0073[ 55] = { /* code 0073, LATIN SMALL LETTER S */ + 0x00, 0x48, 0x99, 0x61, 0x00, + 0x0A, 0xFF, 0xFF, 0xFE, 0x30, + 0x4F, 0xFA, 0x46, 0xEF, 0x80, + 0x6F, 0xF7, 0x00, 0x27, 0x10, + 0x2F, 0xFF, 0xFB, 0x82, 0x00, + 0x04, 0xCF, 0xFF, 0xFF, 0x50, + 0x03, 0x01, 0x59, 0xEF, 0xE0, + 0x4F, 0xC1, 0x00, 0xAF, 0xF0, + 0x3F, 0xFE, 0xAB, 0xFF, 0xA0, + 0x04, 0xCF, 0xFF, 0xF9, 0x10, + 0x00, 0x01, 0x33, 0x10, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0074[ 56] = { /* code 0074, LATIN SMALL LETTER T */ + 0x00, 0x33, 0x00, 0x00, + 0x02, 0xFF, 0x40, 0x00, + 0x04, 0xFF, 0x60, 0x00, + 0x38, 0xFF, 0x95, 0x10, + 0xBF, 0xFF, 0xFF, 0x50, + 0x27, 0xFF, 0x94, 0x00, + 0x04, 0xFF, 0x60, 0x00, + 0x04, 0xFF, 0x60, 0x00, + 0x04, 0xFF, 0x60, 0x00, + 0x04, 0xFF, 0x60, 0x00, + 0x04, 0xFF, 0x60, 0x00, + 0x03, 0xFF, 0xEC, 0x30, + 0x00, 0xBF, 0xFF, 0x30, + 0x00, 0x02, 0x41, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0075[ 55] = { /* code 0075, LATIN SMALL LETTER U */ + 0x59, 0x30, 0x00, 0x39, 0x50, + 0xEF, 0x90, 0x00, 0x9F, 0xE0, + 0xFF, 0x90, 0x00, 0x9F, 0xF0, + 0xFF, 0x90, 0x00, 0x9F, 0xF0, + 0xFF, 0x90, 0x00, 0x9F, 0xF0, + 0xFF, 0x90, 0x00, 0x9F, 0xF0, + 0xFF, 0xA0, 0x00, 0xBF, 0xF0, + 0xEF, 0xE2, 0x06, 0xFF, 0xF0, + 0x9F, 0xFF, 0xEF, 0xEF, 0xF0, + 0x1C, 0xFF, 0xF9, 0x5F, 0xD0, + 0x00, 0x24, 0x10, 0x03, 0x10 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0076[ 55] = { /* code 0076, LATIN SMALL LETTER V */ + 0x49, 0x20, 0x00, 0x29, 0x40, + 0xDF, 0xB0, 0x00, 0xBF, 0xD0, + 0xAF, 0xF1, 0x01, 0xFF, 0xA0, + 0x5F, 0xF5, 0x05, 0xFF, 0x50, + 0x0E, 0xF9, 0x09, 0xFE, 0x00, + 0x09, 0xFE, 0x0E, 0xF9, 0x00, + 0x03, 0xFF, 0x7F, 0xF3, 0x00, + 0x00, 0xDF, 0xEF, 0xD0, 0x00, + 0x00, 0x8F, 0xFF, 0x80, 0x00, + 0x00, 0x2F, 0xFF, 0x20, 0x00, + 0x00, 0x02, 0x42, 0x00, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0077[ 77] = { /* code 0077, LATIN SMALL LETTER W */ + 0x39, 0x40, 0x01, 0x89, 0x10, 0x04, 0x93, + 0xBF, 0xB0, 0x07, 0xFF, 0x80, 0x0B, 0xFB, + 0x9F, 0xF1, 0x0B, 0xFF, 0xC0, 0x0F, 0xF9, + 0x4F, 0xF4, 0x0E, 0xFF, 0xF1, 0x3F, 0xF4, + 0x0E, 0xF7, 0x2F, 0xCC, 0xF3, 0x7F, 0xE0, + 0x0A, 0xFB, 0x5F, 0x88, 0xF7, 0xAF, 0xA0, + 0x06, 0xFE, 0x9F, 0x44, 0xFA, 0xDF, 0x60, + 0x01, 0xFF, 0xEF, 0x11, 0xFE, 0xFF, 0x10, + 0x00, 0xBF, 0xFC, 0x00, 0xCF, 0xFB, 0x00, + 0x00, 0x6F, 0xF7, 0x00, 0x7F, 0xF6, 0x00, + 0x00, 0x03, 0x30, 0x00, 0x03, 0x30, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0078[ 55] = { /* code 0078, LATIN SMALL LETTER X */ + 0x18, 0x70, 0x00, 0x78, 0x00, + 0x7F, 0xF4, 0x05, 0xFF, 0x30, + 0x2F, 0xFD, 0x1E, 0xFD, 0x00, + 0x07, 0xFF, 0xDF, 0xF3, 0x00, + 0x00, 0xCF, 0xFF, 0x80, 0x00, + 0x00, 0x8F, 0xFF, 0x50, 0x00, + 0x04, 0xFF, 0xFF, 0xD1, 0x00, + 0x1D, 0xFE, 0x6F, 0xF9, 0x00, + 0x8F, 0xF5, 0x0B, 0xFF, 0x30, + 0x8F, 0xB0, 0x02, 0xEF, 0x30, + 0x03, 0x00, 0x00, 0x22, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_0079[ 70] = { /* code 0079, LATIN SMALL LETTER Y */ + 0x39, 0x40, 0x00, 0x39, 0x30, + 0xBF, 0xD0, 0x00, 0xCF, 0xB0, + 0x8F, 0xF2, 0x01, 0xFF, 0x80, + 0x3F, 0xF7, 0x05, 0xFF, 0x30, + 0x0D, 0xFB, 0x09, 0xFD, 0x00, + 0x08, 0xFE, 0x0D, 0xF7, 0x00, + 0x03, 0xFF, 0x6F, 0xF2, 0x00, + 0x00, 0xCF, 0xEF, 0xB0, 0x00, + 0x00, 0x7F, 0xFF, 0x70, 0x00, + 0x00, 0x2F, 0xFF, 0x10, 0x00, + 0x00, 0x0C, 0xFB, 0x00, 0x00, + 0x06, 0x8F, 0xF5, 0x00, 0x00, + 0x1F, 0xFF, 0xC0, 0x00, 0x00, + 0x07, 0xB8, 0x10, 0x00, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_007A[ 50] = { /* code 007A, LATIN SMALL LETTER Z */ + 0x03, 0x66, 0x66, 0x66, 0x50, + 0x0F, 0xFF, 0xFF, 0xFF, 0xF5, + 0x07, 0x99, 0x9B, 0xFF, 0xE1, + 0x00, 0x00, 0x1D, 0xFE, 0x30, + 0x00, 0x01, 0xDF, 0xF4, 0x00, + 0x00, 0x1B, 0xFF, 0x50, 0x00, + 0x00, 0xBF, 0xF7, 0x00, 0x00, + 0x0A, 0xFF, 0x80, 0x00, 0x00, + 0x5F, 0xFF, 0xFF, 0xFF, 0xF5, + 0x4F, 0xFF, 0xFF, 0xFF, 0xF4 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_007B[ 68] = { /* code 007B, LEFT CURLY BRACKET */ + 0x00, 0x6D, 0xFE, 0x30, + 0x01, 0xFF, 0xC9, 0x20, + 0x03, 0xFF, 0x40, 0x00, + 0x04, 0xFF, 0x40, 0x00, + 0x04, 0xFF, 0x40, 0x00, + 0x04, 0xFF, 0x40, 0x00, + 0x04, 0xFF, 0x30, 0x00, + 0x8D, 0xFB, 0x00, 0x00, + 0xDF, 0xE7, 0x00, 0x00, + 0x06, 0xFF, 0x10, 0x00, + 0x04, 0xFF, 0x40, 0x00, + 0x04, 0xFF, 0x40, 0x00, + 0x04, 0xFF, 0x40, 0x00, + 0x03, 0xFF, 0x40, 0x00, + 0x02, 0xFF, 0x95, 0x00, + 0x00, 0xBF, 0xFF, 0x40, + 0x00, 0x03, 0x55, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_007C[ 30] = { /* code 007C, VERTICAL LINE */ + 0x02, 0x20, + 0x1E, 0xE1, + 0x2F, 0xF2, + 0x2F, 0xF2, + 0x2F, 0xF2, + 0x2F, 0xF2, + 0x2F, 0xF2, + 0x2F, 0xF2, + 0x2F, 0xF2, + 0x2F, 0xF2, + 0x2F, 0xF2, + 0x2F, 0xF2, + 0x2F, 0xF2, + 0x1F, 0xF1, + 0x02, 0x20 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_007D[ 68] = { /* code 007D, RIGHT CURLY BRACKET */ + 0xCF, 0xEA, 0x00, 0x00, + 0x8B, 0xFF, 0x60, 0x00, + 0x00, 0xDF, 0x70, 0x00, + 0x00, 0xDF, 0x70, 0x00, + 0x00, 0xDF, 0x70, 0x00, + 0x00, 0xDF, 0x70, 0x00, + 0x00, 0xDF, 0x80, 0x00, + 0x00, 0x7F, 0xEA, 0x10, + 0x00, 0x3C, 0xFF, 0x30, + 0x00, 0xCF, 0xA0, 0x00, + 0x00, 0xDF, 0x70, 0x00, + 0x00, 0xDF, 0x70, 0x00, + 0x00, 0xDF, 0x70, 0x00, + 0x00, 0xDF, 0x70, 0x00, + 0x36, 0xFF, 0x70, 0x00, + 0xEF, 0xFE, 0x20, 0x00, + 0x36, 0x41, 0x00, 0x00 +}; + +GUI_CONST_STORAGE unsigned char acGUI_FontRounded22_007E[ 24] = { /* code 007E, TILDE */ + 0x02, 0xAB, 0x83, 0x00, 0x38, 0x00, + 0x0D, 0xFF, 0xFF, 0xBA, 0xFF, 0x00, + 0x4F, 0xC6, 0xAF, 0xFF, 0xF9, 0x00, + 0x06, 0x10, 0x01, 0x79, 0x50, 0x00 +}; + +GUI_CONST_STORAGE GUI_CHARINFO_EXT GUI_FontRounded22_CharInfo[95] = { + { 1, 1, 0, 18, 6, acGUI_FontRounded22_0020 } /* code 0020, SPACE */ + ,{ 4, 15, 1, 4, 6, acGUI_FontRounded22_0021 } /* code 0021, EXCLAMATION MARK */ + ,{ 7, 7, 1, 4, 10, acGUI_FontRounded22_0022 } /* code 0022, QUOTATION MARK */ + ,{ 11, 14, 0, 5, 11, acGUI_FontRounded22_0023 } /* code 0023, NUMBER SIGN */ + ,{ 11, 16, 0, 4, 11, acGUI_FontRounded22_0024 } /* code 0024, DOLLAR SIGN */ + ,{ 16, 15, 1, 4, 18, acGUI_FontRounded22_0025 } /* code 0025, PERCENT SIGN */ + ,{ 13, 15, 0, 4, 13, acGUI_FontRounded22_0026 } /* code 0026, AMPERSAND */ + ,{ 3, 7, 1, 4, 6, acGUI_FontRounded22_0027 } /* code 0027, APOSTROPHE */ + ,{ 5, 18, 1, 4, 6, acGUI_FontRounded22_0028 } /* code 0028, LEFT PARENTHESIS */ + ,{ 5, 18, 0, 4, 6, acGUI_FontRounded22_0029 } /* code 0029, RIGHT PARENTHESIS */ + ,{ 8, 8, 0, 4, 8, acGUI_FontRounded22_002A } /* code 002A, ASTERISK */ + ,{ 11, 11, 0, 7, 11, acGUI_FontRounded22_002B } /* code 002B, PLUS SIGN */ + ,{ 4, 6, 1, 15, 6, acGUI_FontRounded22_002C } /* code 002C, COMMA */ + ,{ 7, 4, 0, 11, 7, acGUI_FontRounded22_002D } /* code 002D, HYPHEN-MINUS */ + ,{ 4, 4, 1, 15, 6, acGUI_FontRounded22_002E } /* code 002E, FULL STOP */ + ,{ 7, 15, 0, 4, 7, acGUI_FontRounded22_002F } /* code 002F, SOLIDUS */ + ,{ 11, 14, 0, 5, 11, acGUI_FontRounded22_0030 } /* code 0030, DIGIT ZERO */ + ,{ 7, 14, -1, 5, 7, acGUI_FontRounded22_0031 } /* code 0031, DIGIT ONE */ + ,{ 11, 13, 0, 5, 11, acGUI_FontRounded22_0032 } /* code 0032, DIGIT TWO */ + ,{ 10, 14, 0, 5, 11, acGUI_FontRounded22_0033 } /* code 0033, DIGIT THREE */ + ,{ 11, 14, 0, 5, 11, acGUI_FontRounded22_0034 } /* code 0034, DIGIT FOUR */ + ,{ 10, 14, 0, 5, 11, acGUI_FontRounded22_0035 } /* code 0035, DIGIT FIVE */ + ,{ 11, 14, 0, 5, 11, acGUI_FontRounded22_0036 } /* code 0036, DIGIT SIX */ + ,{ 10, 14, 0, 5, 10, acGUI_FontRounded22_0037 } /* code 0037, DIGIT SEVEN */ + ,{ 11, 14, 0, 5, 11, acGUI_FontRounded22_0038 } /* code 0038, DIGIT EIGHT */ + ,{ 11, 14, 0, 5, 11, acGUI_FontRounded22_0039 } /* code 0039, DIGIT NINE */ + ,{ 4, 11, 1, 8, 6, acGUI_FontRounded22_003A } /* code 003A, COLON */ + ,{ 4, 13, 1, 8, 6, acGUI_FontRounded22_003B } /* code 003B, SEMICOLON */ + ,{ 11, 10, 0, 8, 11, acGUI_FontRounded22_003C } /* code 003C, LESS-THAN SIGN */ + ,{ 11, 8, 0, 9, 11, acGUI_FontRounded22_003D } /* code 003D, EQUALS SIGN */ + ,{ 11, 10, 0, 8, 11, acGUI_FontRounded22_003E } /* code 003E, GREATER-THAN SIGN */ + ,{ 10, 15, 0, 4, 10, acGUI_FontRounded22_003F } /* code 003F, QUESTION MARK */ + ,{ 14, 15, 0, 4, 14, acGUI_FontRounded22_0040 } /* code 0040, COMMERCIAL AT */ + ,{ 12, 15, 0, 4, 12, acGUI_FontRounded22_0041 } /* code 0041, LATIN CAPITAL LETTER A */ + ,{ 12, 13, 1, 5, 13, acGUI_FontRounded22_0042 } /* code 0042, LATIN CAPITAL LETTER B */ + ,{ 12, 15, 1, 4, 13, acGUI_FontRounded22_0043 } /* code 0043, LATIN CAPITAL LETTER C */ + ,{ 12, 13, 1, 5, 14, acGUI_FontRounded22_0044 } /* code 0044, LATIN CAPITAL LETTER D */ + ,{ 11, 13, 1, 5, 12, acGUI_FontRounded22_0045 } /* code 0045, LATIN CAPITAL LETTER E */ + ,{ 11, 14, 1, 5, 11, acGUI_FontRounded22_0046 } /* code 0046, LATIN CAPITAL LETTER F */ + ,{ 13, 15, 1, 4, 15, acGUI_FontRounded22_0047 } /* code 0047, LATIN CAPITAL LETTER G */ + ,{ 12, 15, 1, 4, 14, acGUI_FontRounded22_0048 } /* code 0048, LATIN CAPITAL LETTER H */ + ,{ 4, 15, 1, 4, 6, acGUI_FontRounded22_0049 } /* code 0049, LATIN CAPITAL LETTER I */ + ,{ 9, 15, 0, 4, 10, acGUI_FontRounded22_004A } /* code 004A, LATIN CAPITAL LETTER J */ + ,{ 12, 15, 1, 4, 12, acGUI_FontRounded22_004B } /* code 004B, LATIN CAPITAL LETTER K */ + ,{ 10, 14, 1, 4, 11, acGUI_FontRounded22_004C } /* code 004C, LATIN CAPITAL LETTER L */ + ,{ 14, 15, 1, 4, 16, acGUI_FontRounded22_004D } /* code 004D, LATIN CAPITAL LETTER M */ + ,{ 12, 15, 1, 4, 14, acGUI_FontRounded22_004E } /* code 004E, LATIN CAPITAL LETTER N */ + ,{ 14, 15, 0, 4, 15, acGUI_FontRounded22_004F } /* code 004F, LATIN CAPITAL LETTER O */ + ,{ 12, 14, 1, 5, 13, acGUI_FontRounded22_0050 } /* code 0050, LATIN CAPITAL LETTER P */ + ,{ 14, 15, 0, 4, 15, acGUI_FontRounded22_0051 } /* code 0051, LATIN CAPITAL LETTER Q */ + ,{ 12, 14, 1, 5, 13, acGUI_FontRounded22_0052 } /* code 0052, LATIN CAPITAL LETTER R */ + ,{ 12, 15, 0, 4, 12, acGUI_FontRounded22_0053 } /* code 0053, LATIN CAPITAL LETTER S */ + ,{ 12, 14, 0, 5, 12, acGUI_FontRounded22_0054 } /* code 0054, LATIN CAPITAL LETTER T */ + ,{ 12, 15, 1, 4, 14, acGUI_FontRounded22_0055 } /* code 0055, LATIN CAPITAL LETTER U */ + ,{ 12, 15, 0, 4, 12, acGUI_FontRounded22_0056 } /* code 0056, LATIN CAPITAL LETTER V */ + ,{ 17, 15, 0, 4, 17, acGUI_FontRounded22_0057 } /* code 0057, LATIN CAPITAL LETTER W */ + ,{ 11, 15, 0, 4, 11, acGUI_FontRounded22_0058 } /* code 0058, LATIN CAPITAL LETTER X */ + ,{ 11, 15, 0, 4, 11, acGUI_FontRounded22_0059 } /* code 0059, LATIN CAPITAL LETTER Y */ + ,{ 12, 13, 0, 5, 12, acGUI_FontRounded22_005A } /* code 005A, LATIN CAPITAL LETTER Z */ + ,{ 6, 17, 1, 5, 6, acGUI_FontRounded22_005B } /* code 005B, LEFT SQUARE BRACKET */ + ,{ 7, 15, 0, 4, 7, acGUI_FontRounded22_005C } /* code 005C, REVERSE SOLIDUS */ + ,{ 5, 17, 0, 5, 6, acGUI_FontRounded22_005D } /* code 005D, RIGHT SQUARE BRACKET */ + ,{ 9, 8, 1, 5, 11, acGUI_FontRounded22_005E } /* code 005E, CIRCUMFLEX ACCENT */ + ,{ 11, 2, -1, 19, 9, acGUI_FontRounded22_005F } /* code 005F, LOW LINE */ + ,{ 4, 4, 0, 4, 5, acGUI_FontRounded22_0060 } /* code 0060, GRAVE ACCENT */ + ,{ 10, 11, 0, 8, 11, acGUI_FontRounded22_0061 } /* code 0061, LATIN SMALL LETTER A */ + ,{ 10, 15, 1, 4, 11, acGUI_FontRounded22_0062 } /* code 0062, LATIN SMALL LETTER B */ + ,{ 10, 11, 0, 8, 10, acGUI_FontRounded22_0063 } /* code 0063, LATIN SMALL LETTER C */ + ,{ 10, 15, 0, 4, 11, acGUI_FontRounded22_0064 } /* code 0064, LATIN SMALL LETTER D */ + ,{ 11, 11, 0, 8, 11, acGUI_FontRounded22_0065 } /* code 0065, LATIN SMALL LETTER E */ + ,{ 7, 15, 0, 4, 7, acGUI_FontRounded22_0066 } /* code 0066, LATIN SMALL LETTER F */ + ,{ 10, 14, 0, 8, 11, acGUI_FontRounded22_0067 } /* code 0067, LATIN SMALL LETTER G */ + ,{ 9, 15, 1, 4, 11, acGUI_FontRounded22_0068 } /* code 0068, LATIN SMALL LETTER H */ + ,{ 3, 15, 1, 4, 5, acGUI_FontRounded22_0069 } /* code 0069, LATIN SMALL LETTER I */ + ,{ 5, 18, -1, 4, 5, acGUI_FontRounded22_006A } /* code 006A, LATIN SMALL LETTER J */ + ,{ 9, 15, 1, 4, 10, acGUI_FontRounded22_006B } /* code 006B, LATIN SMALL LETTER K */ + ,{ 3, 15, 1, 4, 5, acGUI_FontRounded22_006C } /* code 006C, LATIN SMALL LETTER L */ + ,{ 15, 11, 1, 8, 17, acGUI_FontRounded22_006D } /* code 006D, LATIN SMALL LETTER M */ + ,{ 9, 11, 1, 8, 11, acGUI_FontRounded22_006E } /* code 006E, LATIN SMALL LETTER N */ + ,{ 11, 11, 0, 8, 11, acGUI_FontRounded22_006F } /* code 006F, LATIN SMALL LETTER O */ + ,{ 10, 14, 1, 8, 11, acGUI_FontRounded22_0070 } /* code 0070, LATIN SMALL LETTER P */ + ,{ 10, 14, 0, 8, 11, acGUI_FontRounded22_0071 } /* code 0071, LATIN SMALL LETTER Q */ + ,{ 7, 11, 1, 8, 7, acGUI_FontRounded22_0072 } /* code 0072, LATIN SMALL LETTER R */ + ,{ 9, 11, 0, 8, 10, acGUI_FontRounded22_0073 } /* code 0073, LATIN SMALL LETTER S */ + ,{ 7, 14, 0, 5, 7, acGUI_FontRounded22_0074 } /* code 0074, LATIN SMALL LETTER T */ + ,{ 9, 11, 1, 8, 11, acGUI_FontRounded22_0075 } /* code 0075, LATIN SMALL LETTER U */ + ,{ 9, 11, 0, 8, 9, acGUI_FontRounded22_0076 } /* code 0076, LATIN SMALL LETTER V */ + ,{ 14, 11, 0, 8, 14, acGUI_FontRounded22_0077 } /* code 0077, LATIN SMALL LETTER W */ + ,{ 9, 11, 0, 8, 9, acGUI_FontRounded22_0078 } /* code 0078, LATIN SMALL LETTER X */ + ,{ 9, 14, 0, 8, 9, acGUI_FontRounded22_0079 } /* code 0079, LATIN SMALL LETTER Y */ + ,{ 10, 10, 0, 8, 10, acGUI_FontRounded22_007A } /* code 007A, LATIN SMALL LETTER Z */ + ,{ 7, 17, 0, 5, 6, acGUI_FontRounded22_007B } /* code 007B, LEFT CURLY BRACKET */ + ,{ 4, 15, 0, 4, 4, acGUI_FontRounded22_007C } /* code 007C, VERTICAL LINE */ + ,{ 7, 17, 0, 5, 6, acGUI_FontRounded22_007D } /* code 007D, RIGHT CURLY BRACKET */ + ,{ 11, 4, 0, 11, 11, acGUI_FontRounded22_007E } /* code 007E, TILDE */ +}; + +GUI_CONST_STORAGE GUI_FONT_PROP_EXT GUI_FontRounded22_Prop1 = { + 0x0020 /* first character */ + ,0x007E /* last character */ + ,&GUI_FontRounded22_CharInfo[ 0] /* address of first character */ + ,(GUI_CONST_STORAGE GUI_FONT_PROP_EXT *)0 /* pointer to next GUI_FONT_PROP_EXT */ +}; + +GUI_CONST_STORAGE GUI_FONT GUI_FontRounded22 = { + GUI_FONTTYPE_PROP_AA4_EXT /* type of font */ + ,22 /* height of font */ + ,22 /* space of font y */ + ,1 /* magnification x */ + ,1 /* magnification y */ + ,{&GUI_FontRounded22_Prop1} + ,22 /* Baseline */ + ,11 /* Height of lowercase characters */ + ,15 /* Height of capital characters */ +}; + +extern GUI_CONST_STORAGE GUI_BITMAP bmAliOS_Things_logo; + +/********************************************************************* +* +* Palette +* +* Description +* The following are the entries of the palette table. +* The entries are stored as a 32-bit values of which 24 bits are +* actually used according to the following bit mask: 0xBBGGRR +* +* The lower 8 bits represent the Red component. +* The middle 8 bits represent the Green component. +* The highest 8 bits represent the Blue component. +*/ +static GUI_CONST_STORAGE GUI_COLOR _ColorsAliOS_Things_logo[] = { +#if (GUI_USE_ARGB == 0) + 0x000000, 0x000024, 0x000048, 0x00006D, + 0x000091, 0x0000B6, 0x0000DA, 0x0000FF, + 0x002400, 0x002424, 0x002448, 0x00246D, + 0x002491, 0x0024B6, 0x0024DA, 0x0024FF, + 0x004800, 0x004824, 0x004848, 0x00486D, + 0x004891, 0x0048B6, 0x0048DA, 0x0048FF, + 0x006D00, 0x006D24, 0x006D48, 0x006D6D, + 0x006D91, 0x006DB6, 0x006DDA, 0x006DFF, + 0x009100, 0x009124, 0x009148, 0x00916D, + 0x009191, 0x0091B6, 0x0091DA, 0x0091FF, + 0x00B600, 0x00B624, 0x00B648, 0x00B66D, + 0x00B691, 0x00B6B6, 0x00B6DA, 0x00B6FF, + 0x00DA00, 0x00DA24, 0x00DA48, 0x00DA6D, + 0x00DA91, 0x00DAB6, 0x00DADA, 0x00DAFF, + 0x00FF00, 0x00FF24, 0x00FF48, 0x00FF6D, + 0x00FF91, 0x00FFB6, 0x00FFDA, 0x00FFFF, + 0x550000, 0x550024, 0x550048, 0x55006D, + 0x550091, 0x5500B6, 0x5500DA, 0x5500FF, + 0x552400, 0x552424, 0x552448, 0x55246D, + 0x552491, 0x5524B6, 0x5524DA, 0x5524FF, + 0x554800, 0x554824, 0x554848, 0x55486D, + 0x554891, 0x5548B6, 0x5548DA, 0x5548FF, + 0x556D00, 0x556D24, 0x556D48, 0x556D6D, + 0x556D91, 0x556DB6, 0x556DDA, 0x556DFF, + 0x559100, 0x559124, 0x559148, 0x55916D, + 0x559191, 0x5591B6, 0x5591DA, 0x5591FF, + 0x55B600, 0x55B624, 0x55B648, 0x55B66D, + 0x55B691, 0x55B6B6, 0x55B6DA, 0x55B6FF, + 0x55DA00, 0x55DA24, 0x55DA48, 0x55DA6D, + 0x55DA91, 0x55DAB6, 0x55DADA, 0x55DAFF, + 0x55FF00, 0x55FF24, 0x55FF48, 0x55FF6D, + 0x55FF91, 0x55FFB6, 0x55FFDA, 0x55FFFF, + 0xAA0000, 0xAA0024, 0xAA0048, 0xAA006D, + 0xAA0091, 0xAA00B6, 0xAA00DA, 0xAA00FF, + 0xAA2400, 0xAA2424, 0xAA2448, 0xAA246D, + 0xAA2491, 0xAA24B6, 0xAA24DA, 0xAA24FF, + 0xAA4800, 0xAA4824, 0xAA4848, 0xAA486D, + 0xAA4891, 0xAA48B6, 0xAA48DA, 0xAA48FF, + 0xAA6D00, 0xAA6D24, 0xAA6D48, 0xAA6D6D, + 0xAA6D91, 0xAA6DB6, 0xAA6DDA, 0xAA6DFF, + 0xAA9100, 0xAA9124, 0xAA9148, 0xAA916D, + 0xAA9191, 0xAA91B6, 0xAA91DA, 0xAA91FF, + 0xAAB600, 0xAAB624, 0xAAB648, 0xAAB66D, + 0xAAB691, 0xAAB6B6, 0xAAB6DA, 0xAAB6FF, + 0xAADA00, 0xAADA24, 0xAADA48, 0xAADA6D, + 0xAADA91, 0xAADAB6, 0xAADADA, 0xAADAFF, + 0xAAFF00, 0xAAFF24, 0xAAFF48, 0xAAFF6D, + 0xAAFF91, 0xAAFFB6, 0xAAFFDA, 0xAAFFFF, + 0xFF0000, 0xFF0024, 0xFF0048, 0xFF006D, + 0xFF0091, 0xFF00B6, 0xFF00DA, 0xFF00FF, + 0xFF2400, 0xFF2424, 0xFF2448, 0xFF246D, + 0xFF2491, 0xFF24B6, 0xFF24DA, 0xFF24FF, + 0xFF4800, 0xFF4824, 0xFF4848, 0xFF486D, + 0xFF4891, 0xFF48B6, 0xFF48DA, 0xFF48FF, + 0xFF6D00, 0xFF6D24, 0xFF6D48, 0xFF6D6D, + 0xFF6D91, 0xFF6DB6, 0xFF6DDA, 0xFF6DFF, + 0xFF9100, 0xFF9124, 0xFF9148, 0xFF916D, + 0xFF9191, 0xFF91B6, 0xFF91DA, 0xFF91FF, + 0xFFB600, 0xFFB624, 0xFFB648, 0xFFB66D, + 0xFFB691, 0xFFB6B6, 0xFFB6DA, 0xFFB6FF, + 0xFFDA00, 0xFFDA24, 0xFFDA48, 0xFFDA6D, + 0xFFDA91, 0xFFDAB6, 0xFFDADA, 0xFFDAFF, + 0xFFFF00, 0xFFFF24, 0xFFFF48, 0xFFFF6D, + 0xFFFF91, 0xFFFFB6, 0xFFFFDA, 0xFFFFFF +#else + 0xFF000000, 0xFF240000, 0xFF480000, 0xFF6D0000, + 0xFF910000, 0xFFB60000, 0xFFDA0000, 0xFFFF0000, + 0xFF002400, 0xFF242400, 0xFF482400, 0xFF6D2400, + 0xFF912400, 0xFFB62400, 0xFFDA2400, 0xFFFF2400, + 0xFF004800, 0xFF244800, 0xFF484800, 0xFF6D4800, + 0xFF914800, 0xFFB64800, 0xFFDA4800, 0xFFFF4800, + 0xFF006D00, 0xFF246D00, 0xFF486D00, 0xFF6D6D00, + 0xFF916D00, 0xFFB66D00, 0xFFDA6D00, 0xFFFF6D00, + 0xFF009100, 0xFF249100, 0xFF489100, 0xFF6D9100, + 0xFF919100, 0xFFB69100, 0xFFDA9100, 0xFFFF9100, + 0xFF00B600, 0xFF24B600, 0xFF48B600, 0xFF6DB600, + 0xFF91B600, 0xFFB6B600, 0xFFDAB600, 0xFFFFB600, + 0xFF00DA00, 0xFF24DA00, 0xFF48DA00, 0xFF6DDA00, + 0xFF91DA00, 0xFFB6DA00, 0xFFDADA00, 0xFFFFDA00, + 0xFF00FF00, 0xFF24FF00, 0xFF48FF00, 0xFF6DFF00, + 0xFF91FF00, 0xFFB6FF00, 0xFFDAFF00, 0xFFFFFF00, + 0xFF000055, 0xFF240055, 0xFF480055, 0xFF6D0055, + 0xFF910055, 0xFFB60055, 0xFFDA0055, 0xFFFF0055, + 0xFF002455, 0xFF242455, 0xFF482455, 0xFF6D2455, + 0xFF912455, 0xFFB62455, 0xFFDA2455, 0xFFFF2455, + 0xFF004855, 0xFF244855, 0xFF484855, 0xFF6D4855, + 0xFF914855, 0xFFB64855, 0xFFDA4855, 0xFFFF4855, + 0xFF006D55, 0xFF246D55, 0xFF486D55, 0xFF6D6D55, + 0xFF916D55, 0xFFB66D55, 0xFFDA6D55, 0xFFFF6D55, + 0xFF009155, 0xFF249155, 0xFF489155, 0xFF6D9155, + 0xFF919155, 0xFFB69155, 0xFFDA9155, 0xFFFF9155, + 0xFF00B655, 0xFF24B655, 0xFF48B655, 0xFF6DB655, + 0xFF91B655, 0xFFB6B655, 0xFFDAB655, 0xFFFFB655, + 0xFF00DA55, 0xFF24DA55, 0xFF48DA55, 0xFF6DDA55, + 0xFF91DA55, 0xFFB6DA55, 0xFFDADA55, 0xFFFFDA55, + 0xFF00FF55, 0xFF24FF55, 0xFF48FF55, 0xFF6DFF55, + 0xFF91FF55, 0xFFB6FF55, 0xFFDAFF55, 0xFFFFFF55, + 0xFF0000AA, 0xFF2400AA, 0xFF4800AA, 0xFF6D00AA, + 0xFF9100AA, 0xFFB600AA, 0xFFDA00AA, 0xFFFF00AA, + 0xFF0024AA, 0xFF2424AA, 0xFF4824AA, 0xFF6D24AA, + 0xFF9124AA, 0xFFB624AA, 0xFFDA24AA, 0xFFFF24AA, + 0xFF0048AA, 0xFF2448AA, 0xFF4848AA, 0xFF6D48AA, + 0xFF9148AA, 0xFFB648AA, 0xFFDA48AA, 0xFFFF48AA, + 0xFF006DAA, 0xFF246DAA, 0xFF486DAA, 0xFF6D6DAA, + 0xFF916DAA, 0xFFB66DAA, 0xFFDA6DAA, 0xFFFF6DAA, + 0xFF0091AA, 0xFF2491AA, 0xFF4891AA, 0xFF6D91AA, + 0xFF9191AA, 0xFFB691AA, 0xFFDA91AA, 0xFFFF91AA, + 0xFF00B6AA, 0xFF24B6AA, 0xFF48B6AA, 0xFF6DB6AA, + 0xFF91B6AA, 0xFFB6B6AA, 0xFFDAB6AA, 0xFFFFB6AA, + 0xFF00DAAA, 0xFF24DAAA, 0xFF48DAAA, 0xFF6DDAAA, + 0xFF91DAAA, 0xFFB6DAAA, 0xFFDADAAA, 0xFFFFDAAA, + 0xFF00FFAA, 0xFF24FFAA, 0xFF48FFAA, 0xFF6DFFAA, + 0xFF91FFAA, 0xFFB6FFAA, 0xFFDAFFAA, 0xFFFFFFAA, + 0xFF0000FF, 0xFF2400FF, 0xFF4800FF, 0xFF6D00FF, + 0xFF9100FF, 0xFFB600FF, 0xFFDA00FF, 0xFFFF00FF, + 0xFF0024FF, 0xFF2424FF, 0xFF4824FF, 0xFF6D24FF, + 0xFF9124FF, 0xFFB624FF, 0xFFDA24FF, 0xFFFF24FF, + 0xFF0048FF, 0xFF2448FF, 0xFF4848FF, 0xFF6D48FF, + 0xFF9148FF, 0xFFB648FF, 0xFFDA48FF, 0xFFFF48FF, + 0xFF006DFF, 0xFF246DFF, 0xFF486DFF, 0xFF6D6DFF, + 0xFF916DFF, 0xFFB66DFF, 0xFFDA6DFF, 0xFFFF6DFF, + 0xFF0091FF, 0xFF2491FF, 0xFF4891FF, 0xFF6D91FF, + 0xFF9191FF, 0xFFB691FF, 0xFFDA91FF, 0xFFFF91FF, + 0xFF00B6FF, 0xFF24B6FF, 0xFF48B6FF, 0xFF6DB6FF, + 0xFF91B6FF, 0xFFB6B6FF, 0xFFDAB6FF, 0xFFFFB6FF, + 0xFF00DAFF, 0xFF24DAFF, 0xFF48DAFF, 0xFF6DDAFF, + 0xFF91DAFF, 0xFFB6DAFF, 0xFFDADAFF, 0xFFFFDAFF, + 0xFF00FFFF, 0xFF24FFFF, 0xFF48FFFF, 0xFF6DFFFF, + 0xFF91FFFF, 0xFFB6FFFF, 0xFFDAFFFF, 0xFFFFFFFF +#endif + +}; + +static GUI_CONST_STORAGE GUI_LOGPALETTE _PalAliOS_Things_logo = { + 256, // Number of entries + 0, // No transparency + &_ColorsAliOS_Things_logo[0] +}; + +static GUI_CONST_STORAGE unsigned char _acAliOS_Things_logo[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xB3, 0xAB, 0xB3, 0xF4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xF5, + 0xF5, 0xF5, 0xF5, 0xF5, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF6, 0xB4, 0xAB, 0xAB, 0xAB, 0xB4, 0xF5, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xF4, 0xB3, 0xAB, 0xAB, 0xB3, 0xF4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xA9, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xA9, 0xB3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xA9, + 0xA9, 0xA9, 0xA9, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xA9, 0xA9, 0xA9, 0xA9, 0xA8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xA9, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xA9, 0xAB, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xA9, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xA9, 0xAA, 0xF5, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAA, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF6, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xAB, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAA, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAB, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xAA, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF6, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xF5, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xB3, 0xF5, 0xB4, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xAB, 0xF4, 0xF5, 0xF4, 0xB3, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xB3, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xAA, 0xB4, 0xF5, 0xF5, 0xB4, 0xA9, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xF4, 0xFF, 0xFF, 0xFF, 0xF5, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, + 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB3, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xF6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xB4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF6, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xF5, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xA9, 0xA9, 0xA9, 0xA9, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xAA, 0xAA, 0xAA, 0xAA, 0xAB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB3, 0xAA, 0xAA, 0xAA, 0xAA, 0xAB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xF5, 0xF5, 0xF5, 0xF5, 0xF4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAB, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB3, 0xAA, 0xAA, 0xAA, 0xAA, + 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xF5, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xF4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xF5, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA9, 0xAA, 0xAA, 0xAA, + 0xA9, 0xF5, 0xFF, 0xFF, 0xFF, 0xFF, 0xAB, 0xAA, 0xAA, 0xAA, 0xAA, 0xAB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAB, 0xAA, 0xAA, 0xAA, + 0xAA, 0xB4, 0xFF, 0xFF, 0xFF, 0xFF, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xF5, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xF4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xAA, 0xAA, 0xAA, + 0xAA, 0xB3, 0xFF, 0xFF, 0xFF, 0xFF, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xA0, 0xA9, 0xA9, 0xA9, 0xA0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB3, 0xAA, 0xAA, 0xAA, 0xAA, 0xB3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xAA, 0xAB, 0xAB, 0xAB, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xA9, 0xAA, 0xAA, + 0xAA, 0xAB, 0xFF, 0xFF, 0xFF, 0xFF, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xF5, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF6, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xA9, 0xAA, 0xAA, + 0xAA, 0xAB, 0xFF, 0xFF, 0xFF, 0xFF, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xF5, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xF6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xA9, 0xAA, 0xAA, + 0xAA, 0xAB, 0xFF, 0xFF, 0xFF, 0xFF, 0xAB, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xB4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xA9, 0xAA, 0xAA, + 0xAA, 0xAB, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAB, 0xAA, 0xAA, 0xAA, 0xAA, 0xB4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xA9, 0xAA, 0xAA, + 0xAA, 0xAB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xA9, 0xAA, 0xB4, 0xF6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xF5, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xA9, 0xAA, 0xAA, + 0xAA, 0xAB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xA9, 0xAA, 0xB4, 0xF5, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xF5, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xA9, 0xAA, 0xAA, + 0xAA, 0xAB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xA9, 0xA9, 0xB4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAB, 0xAA, 0xAA, 0xAA, 0xAA, 0xB3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xA9, 0xAA, 0xAA, + 0xAA, 0xAB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xA9, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xF5, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xB4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xA9, 0xAA, 0xAA, + 0xAA, 0xAB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xAA, 0xA9, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xF4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xA9, 0xAA, 0xAA, + 0xAA, 0xAB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xF4, 0xAB, 0xA9, 0xA9, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xF4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xA9, 0xAA, 0xAA, + 0xAA, 0xAB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xB3, 0xAA, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB3, 0xAA, 0xAA, 0xAA, 0xAA, 0xAB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xAA, 0xAA, 0xAA, 0xAA, 0xAB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xA9, 0xAA, 0xAA, + 0xAA, 0xAB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xF5, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xF5, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xA9, 0xAA, 0xAA, + 0xAA, 0xAB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xA9, 0xAA, 0xAA, + 0xAA, 0xAB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xB4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xA9, 0xAA, 0xAA, + 0xAA, 0xAB, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAB, 0xAA, 0xAA, 0xAA, 0xAA, 0xB3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xF6, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xAA, 0xAA, 0xAA, + 0xAA, 0xB3, 0xFF, 0xFF, 0xFF, 0xFF, 0xA0, 0xA9, 0xA9, 0xA9, 0xA0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xF5, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAB, 0xAA, 0xAA, 0xAA, + 0xAA, 0xB4, 0xFF, 0xFF, 0xFF, 0xFF, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xF5, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xF5, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xF5, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA9, 0xAA, 0xAA, 0xAA, + 0xA9, 0xF5, 0xFF, 0xFF, 0xFF, 0xFF, 0xAB, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xB3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAB, 0xAA, 0xAA, 0xAA, 0xAA, 0xB3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAB, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAB, 0xAA, 0xAA, 0xAA, 0xAA, + 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xF5, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xB4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF6, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, + 0xAB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAB, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xF4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xF5, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xF5, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xAA, 0xB4, 0xB4, 0xB4, 0xAA, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xB4, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xA9, 0xAB, 0xB4, 0xB4, 0xAB, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xAA, 0xAA, 0xAA, 0xAA, 0xAB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB3, 0xAA, 0xAA, 0xAA, 0xAA, 0xAB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xF4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xAA, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xAA, + 0xAA, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xA9, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xF4, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAB, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xAB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xF5, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xB4, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xA9, + 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xB4, 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xA9, 0xA9, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xA9, 0xB3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xAB, 0xA9, 0xA9, 0xAA, 0xAA, 0xAA, 0xAA, 0xA9, 0xA9, 0xAB, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xF4, 0xB3, 0xB3, 0xB3, 0xB3, 0xF4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xB3, 0xB4, 0xB4, 0xB3, 0xB4, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xAB, + 0xB3, 0xB3, 0xB3, 0xAB, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xAB, 0xB3, 0xB3, 0xB3, 0xAB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xB4, 0xB4, 0xB4, 0xF4, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF5, 0xB4, 0xB4, 0xB4, 0xB4, 0xF5, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xF6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x5B, 0x09, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x5B, 0x09, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x5B, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x9B, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x52, 0x00, 0x49, 0xF6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x5B, 0x49, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x49, 0x5B, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x5B, 0x49, 0x52, 0x52, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x5B, 0x49, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x49, 0x5B, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x52, 0x52, 0x52, 0x52, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x5B, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x9B, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xA4, 0x49, 0x52, 0x49, 0x52, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA4, 0x49, 0x52, 0x49, 0xA4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA4, 0x52, 0x5B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9B, 0x49, 0x52, 0x49, 0xA4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9B, 0x49, 0x52, 0x49, 0xA4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAD, 0xAD, 0xAD, 0xF6, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAD, 0xAD, 0xAD, 0xB6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAD, + 0xAD, 0xAD, 0xB5, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF6, 0xAD, 0xAD, 0xAD, 0xAD, 0xF6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9B, 0x49, 0x52, 0x49, 0xA4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xFF, 0xFF, 0xAD, 0x52, 0x09, 0x49, 0x49, 0x49, 0x49, 0x09, 0x5B, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xA4, 0x00, 0x09, 0x00, 0x52, 0xFF, 0xFF, 0xFF, 0x00, 0x09, 0x00, 0xA4, 0xFF, 0xFF, 0xAD, 0x49, 0x09, 0x49, 0x49, 0x49, 0x49, 0x08, 0x52, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x5B, 0x08, 0x49, + 0x49, 0x49, 0x49, 0x08, 0x5B, 0xFF, 0xFF, 0xFF, 0x00, 0x09, 0x00, 0xA4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF6, 0x52, 0x08, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x09, 0x5B, 0xAD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9B, 0x49, 0x52, 0x49, 0xA4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x09, 0xFF, 0x5B, 0x49, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x51, 0x00, 0xF6, + 0xFF, 0xFF, 0xFF, 0xFF, 0xA4, 0x49, 0x52, 0x52, 0x5B, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x51, 0x5B, 0xFF, 0x52, 0x49, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x00, 0xF6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF6, 0x00, 0x51, 0x52, 0x52, + 0x52, 0x52, 0x52, 0x52, 0x52, 0x00, 0xF6, 0xFF, 0x49, 0x52, 0x49, 0xAD, 0xFF, 0xFF, 0xFF, 0xFF, 0x5B, 0x09, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x49, 0xA4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9B, 0x49, 0x52, 0x49, 0xA4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xA4, 0x49, 0x52, 0x49, 0x09, 0x49, 0x09, 0x49, 0x52, 0x52, 0x52, 0x52, 0x08, + 0xFF, 0xFF, 0xFF, 0xFF, 0xA4, 0x49, 0x52, 0x51, 0x5B, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x52, 0x5B, 0x49, 0x52, 0x49, 0x09, 0x49, 0x09, 0x49, 0x52, 0x52, 0x52, 0x52, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x52, 0x52, 0x52, 0x49, + 0x49, 0x09, 0x09, 0x49, 0x49, 0x52, 0x09, 0xA4, 0x49, 0x52, 0x49, 0xAD, 0xFF, 0xFF, 0xFF, 0xA4, 0x49, 0x52, 0x52, 0x49, 0x09, 0x52, 0x52, 0x52, 0x09, 0x49, 0x49, 0x52, 0x09, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9B, 0x49, 0x52, 0x49, 0xA4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x52, 0x49, 0x49, 0x52, 0xB6, 0xFF, 0xFF, 0xFF, 0xF6, 0x52, 0x49, 0x52, 0x52, 0x49, + 0xA4, 0xFF, 0xFF, 0xFF, 0xA4, 0x49, 0x52, 0x51, 0x5B, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x52, 0x49, 0x49, 0x52, 0xB6, 0xFF, 0xFF, 0xFF, 0xFF, 0x52, 0x49, 0x52, 0x52, 0x49, 0x9B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x52, 0x49, 0x5B, + 0xFF, 0xFF, 0xFF, 0xFF, 0xA4, 0x49, 0x52, 0x49, 0x52, 0x52, 0x49, 0xAD, 0xFF, 0xFF, 0xFF, 0x09, 0x52, 0x52, 0x49, 0xA4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF6, 0xA4, 0x49, 0x9B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9B, 0x49, 0x52, 0x49, 0xA4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x52, 0x51, 0x5A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x52, 0x52, 0x52, 0x52, + 0x49, 0xFF, 0xFF, 0xFF, 0xA4, 0x49, 0x52, 0x51, 0x5B, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x52, 0x52, 0x52, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x52, 0x52, 0x52, 0x52, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xAD, 0x49, 0x52, 0x52, 0x49, 0xAD, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x52, 0x49, 0xAD, 0xFF, 0xFF, 0xF6, 0x49, 0x52, 0x52, 0x52, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9B, 0x49, 0x52, 0x49, 0xA4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x52, 0x09, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF6, 0x49, 0x52, 0x52, + 0x09, 0xFF, 0xFF, 0xFF, 0xA4, 0x49, 0x52, 0x51, 0x5B, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x52, 0x09, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF6, 0x49, 0x52, 0x52, 0x09, 0xFF, 0xFF, 0xFF, 0xFF, 0x5B, 0x52, 0x52, 0x52, 0x52, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAD, 0x49, 0x52, 0x52, 0x49, 0xAD, 0xFF, 0xFF, 0xF6, 0x49, 0x52, 0x52, 0x52, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9B, 0x49, 0x52, 0x49, 0xA4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x51, 0x5B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x09, 0x52, 0x52, + 0x49, 0xFF, 0xFF, 0xFF, 0xA4, 0x49, 0x52, 0x51, 0x5B, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x51, 0x5B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x09, 0x52, 0x52, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0x09, 0x52, 0x52, 0x49, 0xAD, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x09, 0x52, 0x52, 0x49, 0xAD, 0xFF, 0xFF, 0xFF, 0x09, 0x52, 0x52, 0x49, 0xAD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9B, 0x49, 0x52, 0x49, 0xA4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xAD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, + 0x49, 0xFF, 0xFF, 0xFF, 0xA4, 0x49, 0x52, 0x51, 0x5B, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xAC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xF6, 0xFF, 0xFF, 0xF6, 0x49, 0x52, 0x52, 0x09, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x52, 0x52, 0x52, 0x49, 0xAD, 0xFF, 0xFF, 0xFF, 0x52, 0x52, 0x52, 0x52, 0x49, 0x52, 0xF6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9B, 0x49, 0x52, 0x49, 0xA4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xF6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, + 0x49, 0xFF, 0xFF, 0xFF, 0xA4, 0x49, 0x52, 0x51, 0x5B, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xF6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xFE, 0xFF, 0xFF, 0xAD, 0x49, 0x52, 0x52, 0x49, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9B, 0x49, 0x52, 0x49, 0xAD, 0xFF, 0xFF, 0xFF, 0xFF, 0x08, 0x52, 0x52, 0x52, 0x52, 0x49, 0x52, 0xAD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9B, 0x49, 0x52, 0x49, 0xA4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xF6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, + 0x49, 0xFF, 0xFF, 0xFF, 0xA4, 0x49, 0x52, 0x51, 0x5B, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xF6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xFE, 0xFF, 0xFF, 0xAD, 0x49, 0x52, 0x52, 0x52, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA4, 0x49, 0x52, 0x49, 0xAD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x49, 0x49, 0x52, 0x52, 0x52, 0x52, 0x49, 0x09, 0x9B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9B, 0x49, 0x52, 0x49, 0xA4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, + 0x49, 0xFF, 0xFF, 0xFF, 0xA4, 0x49, 0x52, 0x51, 0x5B, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xFE, 0xFF, 0xFF, 0xAC, 0x49, 0x52, 0x52, 0x52, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA4, 0x49, 0x52, 0x49, 0xAD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA4, 0x49, 0x49, 0x52, 0x52, 0x52, 0x52, 0x49, 0x08, 0xA4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9B, 0x49, 0x52, 0x49, 0xA4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, + 0x49, 0xFF, 0xFF, 0xFF, 0xA4, 0x49, 0x52, 0x51, 0x5B, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xF6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xFE, 0xFF, 0xFF, 0xAD, 0x49, 0x52, 0x52, 0x52, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA4, 0x49, 0x52, 0x49, 0xAD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAD, 0x52, 0x09, 0x51, 0x52, 0x52, 0x52, 0x49, 0x52, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9B, 0x49, 0x52, 0x49, 0xA4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, + 0x49, 0xFF, 0xFF, 0xFF, 0xA4, 0x49, 0x52, 0x51, 0x5B, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xF6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xFE, 0xFF, 0xFF, 0xAD, 0x49, 0x52, 0x52, 0x49, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA4, 0x49, 0x52, 0x49, 0xAD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x5B, 0x09, 0x52, 0x52, 0x52, 0x49, 0xAD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9B, 0x49, 0x52, 0x49, 0xA4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, + 0x49, 0xFF, 0xFF, 0xFF, 0xA4, 0x49, 0x52, 0x51, 0x5B, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xF6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xFE, 0xFF, 0xFF, 0xF6, 0x49, 0x52, 0x52, 0x09, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x5B, 0x51, 0x52, 0x49, 0xAD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x52, 0x52, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9B, 0x49, 0x52, 0x49, 0xA4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, + 0x49, 0xFF, 0xFF, 0xFF, 0xA4, 0x49, 0x52, 0x51, 0x5B, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xF6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xFE, 0xFF, 0xFF, 0xFF, 0x09, 0x52, 0x52, 0x49, 0xAD, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xAD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF6, 0x49, 0x52, 0x52, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9B, 0x49, 0x52, 0x49, 0xA4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, + 0x49, 0xFF, 0xFF, 0xFF, 0xA4, 0x49, 0x52, 0x51, 0x5B, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xF6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xFE, 0xFF, 0xFF, 0xFF, 0x5B, 0x52, 0x52, 0x52, 0x52, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF6, 0x49, 0x52, 0x52, 0x49, 0xAD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x09, 0x52, 0x52, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9B, 0x49, 0x52, 0x49, 0xA4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, + 0x49, 0xFF, 0xFF, 0xFF, 0xA4, 0x49, 0x52, 0x51, 0x5B, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xF6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xFE, 0xFF, 0xFF, 0xFF, 0xAD, 0x49, 0x52, 0x52, 0x49, 0xAD, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x52, 0x49, 0xAD, 0xFF, 0xFF, 0xF6, 0xAD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF6, 0x49, 0x52, 0x52, 0x52, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9B, 0x49, 0x52, 0x49, 0xA4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, + 0x49, 0xFF, 0xFF, 0xFF, 0xA4, 0x49, 0x52, 0x51, 0x5B, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xF6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x52, 0x52, 0x52, 0x52, 0x49, 0x5B, + 0xFF, 0xFF, 0xFF, 0xFF, 0xAD, 0x49, 0x52, 0x49, 0x52, 0x52, 0x49, 0xAD, 0xFF, 0xFF, 0xF6, 0x00, 0x49, 0xA4, 0xB6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAD, 0x49, 0x52, 0x52, 0x49, 0xA4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9B, 0x49, 0x52, 0x49, 0xA4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, + 0x49, 0xFF, 0xFF, 0xFF, 0xA4, 0x49, 0x52, 0x51, 0x5B, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xF6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x08, 0x52, 0x52, 0x52, 0x51, + 0x49, 0x09, 0x09, 0x49, 0x49, 0x52, 0x49, 0xA4, 0x51, 0x52, 0x49, 0xAD, 0xFF, 0xFF, 0xF6, 0x49, 0x52, 0x49, 0x49, 0x09, 0x49, 0x49, 0x49, 0x09, 0x49, 0x52, 0x52, 0x52, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9B, 0x49, 0x52, 0x49, 0xA4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, + 0x49, 0xFF, 0xFF, 0xFF, 0xA4, 0x49, 0x52, 0x49, 0x5B, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xF6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF6, 0x09, 0x49, 0x52, 0x52, + 0x52, 0x52, 0x52, 0x52, 0x49, 0x09, 0xFF, 0x9B, 0x51, 0x52, 0x49, 0xAD, 0xFF, 0xFF, 0xF6, 0x00, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x49, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9B, 0x49, 0x49, 0x49, 0xA4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x09, 0x49, 0x49, 0x09, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x49, 0x49, + 0x09, 0xFF, 0xFF, 0xFF, 0xA4, 0x49, 0x49, 0x49, 0x5B, 0xFF, 0xFF, 0xFF, 0x49, 0x49, 0x49, 0x09, 0xF6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x49, 0x49, 0x09, 0xF6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x9B, 0x49, 0x49, + 0x49, 0x49, 0x49, 0x49, 0x9B, 0xFF, 0xFF, 0x5B, 0x51, 0x52, 0x49, 0xAD, 0xFF, 0xFF, 0xFF, 0xAD, 0x5B, 0x49, 0x09, 0x49, 0x49, 0x49, 0x49, 0x49, 0x09, 0x52, 0xAD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xB6, 0xB6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x5B, 0x51, 0x52, 0x49, 0xAD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF6, 0xF6, 0xB6, 0xF6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x52, 0x52, 0x52, 0x49, 0xAD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0xF6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xAD, 0x49, 0x52, 0x52, 0x09, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x51, 0x5B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x09, 0x52, 0xA4, 0xAD, 0xFF, + 0xFF, 0xFF, 0xFF, 0xF6, 0xA4, 0x09, 0x52, 0x52, 0x52, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x49, 0x52, 0x52, 0x49, 0x49, 0x49, + 0x09, 0x09, 0x09, 0x49, 0x49, 0x52, 0x52, 0x52, 0x09, 0xAD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x49, 0x51, 0x52, 0x52, 0x52, + 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x49, 0x09, 0xB6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xA4, 0x5B, 0x49, 0x09, 0x49, + 0x49, 0x49, 0x49, 0x49, 0x09, 0x52, 0xA4, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xF6, 0xF6, 0xF6, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}; + +GUI_CONST_STORAGE GUI_BITMAP bmAliOS_Things_logo = { + 120, // xSize + 120, // ySize + 120, // BytesPerLine + 8, // BitsPerPixel + _acAliOS_Things_logo, // Pointer to picture data (indices) + &_PalAliOS_Things_logo // Pointer to palette +}; +/*************************** End of file ****************************/ diff --git a/example/GUI/app/GUIDEMO_Start.c b/example/GUI/app/GUIDEMO_Start.c new file mode 100755 index 0000000000..fc47feec46 --- /dev/null +++ b/example/GUI/app/GUIDEMO_Start.c @@ -0,0 +1,95 @@ +/********************************************************************* +* Portions COPYRIGHT 2013 STMicroelectronics * +* Portions SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2013 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.22 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GUIDEMO_Start.c +Purpose : GUIDEMO initialization +---------------------------------------------------------------------- +*/ + +/** + ****************************************************************************** + * @file GUIDEMO_Start.c + * @author MCD Application Team + * @brief GUIDEMO initialization + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + + +#include "GUIDEMO.h" + +/********************************************************************* +* +* MainTask +*/ +void MainTask(void); +void MainTask(void) { + WM_SetCreateFlags(WM_CF_MEMDEV); + GUI_Init(); + GUIDEMO_Main(); +} + +/*************************** End of file ****************************/ + diff --git a/example/GUI/app/GUIDEMO_TransparentDialog.c b/example/GUI/app/GUIDEMO_TransparentDialog.c new file mode 100755 index 0000000000..4e6af6f0fc --- /dev/null +++ b/example/GUI/app/GUIDEMO_TransparentDialog.c @@ -0,0 +1,7045 @@ +/********************************************************************* +* Portions COPYRIGHT 2013 STMicroelectronics * +* Portions SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2013 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.22 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GUIDEMO_TransparentDialog.c +Purpose : Demo of a semi transparent dialog +---------------------------END-OF-HEADER------------------------------ +*/ + +/** + ****************************************************************************** + * @file GUIDEMO_TransparentDialog.c + * @author MCD Application Team + * @brief Demo of a semi transparent dialog + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + + +#include "GUIDEMO.h" + +#if (SHOW_GUIDEMO_TRANSPARENTDIALOG && GUI_WINSUPPORT && GUI_SUPPORT_MEMDEV) + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ +#define APP_TIMER (WM_USER + 0) +#define APP_INIT (WM_USER + 1) +#define PERIOD 40 +#define DURATION 10000 + +/********************************************************************* +* +* Static data +* +********************************************************************** +*/ +static GUI_CONST_STORAGE GUI_COLOR ColorsMap_400x320[] = { + 0xEEEEEE,0x99CCFF,0xCCFFCC,0xFFFFFF + ,0xCCCCCC,0x0000FF,0x888888,0x99CC99 + ,0x000000,0x33FFFF,0x444444,0xDDDDDD + ,0xBBBBBB,0x777777,0xAAAAAA,0x555555 + ,0x00FFFF,0x666666,0x999999,0x660000 + ,0x669966,0xCCCCFF,0xCC0033,0xFF0066 + ,0xCCFFFF,0x9999FF,0x6666FF,0x99FFFF +}; + +static GUI_CONST_STORAGE GUI_LOGPALETTE PalMap_400x320 = { + 28, /* number of entries */ + 0, /* No transparency */ + &ColorsMap_400x320[0] +}; + +static GUI_CONST_STORAGE unsigned char acMap_400x320[] = { + /* RLE: 007 Pixels @ 000,000*/ 7, 0x07, + /* RLE: 001 Pixels @ 007,000*/ 1, 0x14, + /* RLE: 010 Pixels @ 008,000*/ 10, 0x07, + /* RLE: 001 Pixels @ 018,000*/ 1, 0x14, + /* RLE: 014 Pixels @ 019,000*/ 14, 0x07, + /* ABS: 008 Pixels @ 033,000*/ 0, 8, 0x14, 0x07, 0x14, 0x07, 0x07, 0x07, 0x14, 0x14, + /* RLE: 006 Pixels @ 041,000*/ 6, 0x07, + /* ABS: 005 Pixels @ 047,000*/ 0, 5, 0x14, 0x07, 0x07, 0x07, 0x02, + /* RLE: 005 Pixels @ 052,000*/ 5, 0x01, + /* RLE: 003 Pixels @ 057,000*/ 3, 0x04, + /* RLE: 008 Pixels @ 060,000*/ 8, 0x03, + /* ABS: 002 Pixels @ 068,000*/ 0, 2, 0x04, 0x04, + /* RLE: 090 Pixels @ 070,000*/ 90, 0x00, + /* ABS: 004 Pixels @ 160,000*/ 0, 4, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 039 Pixels @ 164,000*/ 39, 0x01, + /* ABS: 002 Pixels @ 203,000*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 205,000*/ 9, 0x03, + /* ABS: 002 Pixels @ 214,000*/ 0, 2, 0x04, 0x04, + /* RLE: 057 Pixels @ 216,000*/ 57, 0x01, + /* RLE: 001 Pixels @ 273,000*/ 1, 0x04, + /* RLE: 019 Pixels @ 274,000*/ 19, 0x03, + /* RLE: 003 Pixels @ 293,000*/ 3, 0x04, + /* RLE: 058 Pixels @ 296,000*/ 58, 0x01, + /* ABS: 002 Pixels @ 354,000*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 356,000*/ 8, 0x03, + /* ABS: 002 Pixels @ 364,000*/ 0, 2, 0x04, 0x04, + /* RLE: 034 Pixels @ 366,000*/ 34, 0x00, + /* RLE: 006 Pixels @ 000,001*/ 6, 0x07, + /* ABS: 003 Pixels @ 006,001*/ 0, 3, 0x14, 0x07, 0x14, + /* RLE: 005 Pixels @ 009,001*/ 5, 0x07, + /* RLE: 001 Pixels @ 014,001*/ 1, 0x14, + /* RLE: 007 Pixels @ 015,001*/ 7, 0x07, + /* RLE: 003 Pixels @ 022,001*/ 3, 0x14, + /* RLE: 009 Pixels @ 025,001*/ 9, 0x07, + /* RLE: 001 Pixels @ 034,001*/ 1, 0x14, + /* RLE: 004 Pixels @ 035,001*/ 4, 0x07, + /* ABS: 002 Pixels @ 039,001*/ 0, 2, 0x14, 0x14, + /* RLE: 007 Pixels @ 041,001*/ 7, 0x07, + /* ABS: 003 Pixels @ 048,001*/ 0, 3, 0x14, 0x07, 0x02, + /* RLE: 008 Pixels @ 051,001*/ 8, 0x01, + /* ABS: 002 Pixels @ 059,001*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 061,001*/ 8, 0x03, + /* ABS: 002 Pixels @ 069,001*/ 0, 2, 0x04, 0x04, + /* RLE: 090 Pixels @ 071,001*/ 90, 0x00, + /* ABS: 005 Pixels @ 161,001*/ 0, 5, 0x0D, 0x06, 0x03, 0x06, 0x0D, + /* RLE: 038 Pixels @ 166,001*/ 38, 0x01, + /* ABS: 002 Pixels @ 204,001*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 206,001*/ 9, 0x03, + /* ABS: 002 Pixels @ 215,001*/ 0, 2, 0x04, 0x04, + /* RLE: 056 Pixels @ 217,001*/ 56, 0x01, + /* RLE: 001 Pixels @ 273,001*/ 1, 0x04, + /* RLE: 015 Pixels @ 274,001*/ 15, 0x03, + /* RLE: 003 Pixels @ 289,001*/ 3, 0x04, + /* RLE: 063 Pixels @ 292,001*/ 63, 0x01, + /* ABS: 002 Pixels @ 355,001*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 357,001*/ 8, 0x03, + /* ABS: 002 Pixels @ 365,001*/ 0, 2, 0x04, 0x04, + /* RLE: 033 Pixels @ 367,001*/ 33, 0x00, + /* RLE: 004 Pixels @ 000,002*/ 4, 0x07, + /* ABS: 006 Pixels @ 004,002*/ 0, 6, 0x14, 0x14, 0x07, 0x07, 0x14, 0x14, + /* RLE: 011 Pixels @ 010,002*/ 11, 0x07, + /* ABS: 005 Pixels @ 021,002*/ 0, 5, 0x14, 0x07, 0x07, 0x14, 0x14, + /* RLE: 009 Pixels @ 026,002*/ 9, 0x07, + /* ABS: 005 Pixels @ 035,002*/ 0, 5, 0x14, 0x07, 0x07, 0x07, 0x14, + /* RLE: 009 Pixels @ 040,002*/ 9, 0x07, + /* RLE: 011 Pixels @ 049,002*/ 11, 0x01, + /* ABS: 002 Pixels @ 060,002*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 062,002*/ 8, 0x03, + /* ABS: 002 Pixels @ 070,002*/ 0, 2, 0x04, 0x04, + /* RLE: 090 Pixels @ 072,002*/ 90, 0x00, + /* ABS: 005 Pixels @ 162,002*/ 0, 5, 0x0D, 0x06, 0x03, 0x06, 0x06, + /* RLE: 038 Pixels @ 167,002*/ 38, 0x01, + /* ABS: 002 Pixels @ 205,002*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 207,002*/ 9, 0x03, + /* ABS: 002 Pixels @ 216,002*/ 0, 2, 0x04, 0x04, + /* RLE: 055 Pixels @ 218,002*/ 55, 0x01, + /* RLE: 001 Pixels @ 273,002*/ 1, 0x04, + /* RLE: 011 Pixels @ 274,002*/ 11, 0x03, + /* RLE: 003 Pixels @ 285,002*/ 3, 0x04, + /* RLE: 068 Pixels @ 288,002*/ 68, 0x01, + /* ABS: 002 Pixels @ 356,002*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 358,002*/ 8, 0x03, + /* ABS: 002 Pixels @ 366,002*/ 0, 2, 0x04, 0x04, + /* RLE: 032 Pixels @ 368,002*/ 32, 0x00, + /* RLE: 003 Pixels @ 000,003*/ 3, 0x07, + /* RLE: 001 Pixels @ 003,003*/ 1, 0x14, + /* RLE: 005 Pixels @ 004,003*/ 5, 0x07, + /* ABS: 002 Pixels @ 009,003*/ 0, 2, 0x14, 0x14, + /* RLE: 010 Pixels @ 011,003*/ 10, 0x07, + /* ABS: 006 Pixels @ 021,003*/ 0, 6, 0x14, 0x07, 0x07, 0x07, 0x14, 0x14, + /* RLE: 009 Pixels @ 027,003*/ 9, 0x07, + /* ABS: 004 Pixels @ 036,003*/ 0, 4, 0x14, 0x07, 0x14, 0x14, + /* RLE: 008 Pixels @ 040,003*/ 8, 0x07, + /* RLE: 013 Pixels @ 048,003*/ 13, 0x01, + /* ABS: 002 Pixels @ 061,003*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 063,003*/ 8, 0x03, + /* ABS: 002 Pixels @ 071,003*/ 0, 2, 0x04, 0x04, + /* RLE: 090 Pixels @ 073,003*/ 90, 0x00, + /* ABS: 005 Pixels @ 163,003*/ 0, 5, 0x0D, 0x0D, 0x03, 0x06, 0x06, + /* RLE: 038 Pixels @ 168,003*/ 38, 0x01, + /* ABS: 002 Pixels @ 206,003*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 208,003*/ 9, 0x03, + /* ABS: 002 Pixels @ 217,003*/ 0, 2, 0x04, 0x04, + /* RLE: 054 Pixels @ 219,003*/ 54, 0x01, + /* ABS: 002 Pixels @ 273,003*/ 0, 2, 0x04, 0x04, + /* RLE: 006 Pixels @ 275,003*/ 6, 0x03, + /* RLE: 003 Pixels @ 281,003*/ 3, 0x04, + /* RLE: 073 Pixels @ 284,003*/ 73, 0x01, + /* ABS: 002 Pixels @ 357,003*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 359,003*/ 8, 0x03, + /* ABS: 002 Pixels @ 367,003*/ 0, 2, 0x04, 0x04, + /* RLE: 031 Pixels @ 369,003*/ 31, 0x00, + /* RLE: 004 Pixels @ 000,004*/ 4, 0x07, + /* RLE: 001 Pixels @ 004,004*/ 1, 0x14, + /* RLE: 004 Pixels @ 005,004*/ 4, 0x07, + /* ABS: 002 Pixels @ 009,004*/ 0, 2, 0x14, 0x14, + /* RLE: 009 Pixels @ 011,004*/ 9, 0x07, + /* RLE: 001 Pixels @ 020,004*/ 1, 0x14, + /* RLE: 004 Pixels @ 021,004*/ 4, 0x07, + /* ABS: 002 Pixels @ 025,004*/ 0, 2, 0x14, 0x14, + /* RLE: 011 Pixels @ 027,004*/ 11, 0x07, + /* RLE: 001 Pixels @ 038,004*/ 1, 0x14, + /* RLE: 008 Pixels @ 039,004*/ 8, 0x07, + /* RLE: 015 Pixels @ 047,004*/ 15, 0x01, + /* ABS: 002 Pixels @ 062,004*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 064,004*/ 8, 0x03, + /* ABS: 002 Pixels @ 072,004*/ 0, 2, 0x04, 0x04, + /* RLE: 091 Pixels @ 074,004*/ 91, 0x00, + /* ABS: 004 Pixels @ 165,004*/ 0, 4, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 038 Pixels @ 169,004*/ 38, 0x01, + /* ABS: 002 Pixels @ 207,004*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 209,004*/ 9, 0x03, + /* ABS: 002 Pixels @ 218,004*/ 0, 2, 0x04, 0x04, + /* RLE: 054 Pixels @ 220,004*/ 54, 0x01, + /* RLE: 006 Pixels @ 274,004*/ 6, 0x04, + /* RLE: 079 Pixels @ 280,004*/ 79, 0x01, + /* RLE: 001 Pixels @ 359,004*/ 1, 0x04, + /* RLE: 008 Pixels @ 360,004*/ 8, 0x03, + /* ABS: 002 Pixels @ 368,004*/ 0, 2, 0x04, 0x04, + /* RLE: 030 Pixels @ 370,004*/ 30, 0x00, + /* RLE: 003 Pixels @ 000,005*/ 3, 0x07, + /* RLE: 001 Pixels @ 003,005*/ 1, 0x14, + /* RLE: 006 Pixels @ 004,005*/ 6, 0x07, + /* ABS: 002 Pixels @ 010,005*/ 0, 2, 0x14, 0x14, + /* RLE: 009 Pixels @ 012,005*/ 9, 0x07, + /* ABS: 005 Pixels @ 021,005*/ 0, 5, 0x14, 0x07, 0x07, 0x07, 0x14, + /* RLE: 005 Pixels @ 026,005*/ 5, 0x07, + /* RLE: 001 Pixels @ 031,005*/ 1, 0x14, + /* RLE: 006 Pixels @ 032,005*/ 6, 0x07, + /* RLE: 001 Pixels @ 038,005*/ 1, 0x14, + /* RLE: 007 Pixels @ 039,005*/ 7, 0x07, + /* RLE: 017 Pixels @ 046,005*/ 17, 0x01, + /* ABS: 002 Pixels @ 063,005*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 065,005*/ 8, 0x03, + /* ABS: 002 Pixels @ 073,005*/ 0, 2, 0x04, 0x04, + /* RLE: 091 Pixels @ 075,005*/ 91, 0x00, + /* ABS: 004 Pixels @ 166,005*/ 0, 4, 0x0D, 0x06, 0x06, 0x0D, + /* RLE: 038 Pixels @ 170,005*/ 38, 0x01, + /* ABS: 002 Pixels @ 208,005*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 210,005*/ 9, 0x03, + /* ABS: 002 Pixels @ 219,005*/ 0, 2, 0x04, 0x04, + /* RLE: 138 Pixels @ 221,005*/ 138, 0x01, + /* ABS: 002 Pixels @ 359,005*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 361,005*/ 8, 0x03, + /* ABS: 002 Pixels @ 369,005*/ 0, 2, 0x04, 0x04, + /* RLE: 029 Pixels @ 371,005*/ 29, 0x00, + /* RLE: 003 Pixels @ 000,006*/ 3, 0x07, + /* RLE: 001 Pixels @ 003,006*/ 1, 0x14, + /* RLE: 005 Pixels @ 004,006*/ 5, 0x07, + /* ABS: 002 Pixels @ 009,006*/ 0, 2, 0x14, 0x14, + /* RLE: 011 Pixels @ 011,006*/ 11, 0x07, + /* ABS: 004 Pixels @ 022,006*/ 0, 4, 0x14, 0x07, 0x14, 0x14, + /* RLE: 012 Pixels @ 026,006*/ 12, 0x07, + /* RLE: 001 Pixels @ 038,006*/ 1, 0x14, + /* RLE: 006 Pixels @ 039,006*/ 6, 0x07, + /* RLE: 019 Pixels @ 045,006*/ 19, 0x01, + /* ABS: 002 Pixels @ 064,006*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 066,006*/ 8, 0x03, + /* ABS: 002 Pixels @ 074,006*/ 0, 2, 0x04, 0x04, + /* RLE: 091 Pixels @ 076,006*/ 91, 0x00, + /* ABS: 004 Pixels @ 167,006*/ 0, 4, 0x0D, 0x06, 0x03, 0x06, + /* RLE: 038 Pixels @ 171,006*/ 38, 0x01, + /* ABS: 002 Pixels @ 209,006*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 211,006*/ 9, 0x03, + /* ABS: 002 Pixels @ 220,006*/ 0, 2, 0x04, 0x04, + /* RLE: 137 Pixels @ 222,006*/ 137, 0x01, + /* RLE: 003 Pixels @ 359,006*/ 3, 0x04, + /* RLE: 008 Pixels @ 362,006*/ 8, 0x03, + /* ABS: 002 Pixels @ 370,006*/ 0, 2, 0x04, 0x04, + /* RLE: 028 Pixels @ 372,006*/ 28, 0x00, + /* RLE: 004 Pixels @ 000,007*/ 4, 0x07, + /* ABS: 006 Pixels @ 004,007*/ 0, 6, 0x14, 0x07, 0x07, 0x07, 0x14, 0x14, + /* RLE: 008 Pixels @ 010,007*/ 8, 0x07, + /* RLE: 001 Pixels @ 018,007*/ 1, 0x14, + /* RLE: 005 Pixels @ 019,007*/ 5, 0x07, + /* RLE: 001 Pixels @ 024,007*/ 1, 0x14, + /* RLE: 009 Pixels @ 025,007*/ 9, 0x07, + /* RLE: 001 Pixels @ 034,007*/ 1, 0x14, + /* RLE: 009 Pixels @ 035,007*/ 9, 0x07, + /* RLE: 021 Pixels @ 044,007*/ 21, 0x01, + /* ABS: 002 Pixels @ 065,007*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 067,007*/ 8, 0x03, + /* ABS: 002 Pixels @ 075,007*/ 0, 2, 0x04, 0x04, + /* RLE: 091 Pixels @ 077,007*/ 91, 0x00, + /* ABS: 004 Pixels @ 168,007*/ 0, 4, 0x0D, 0x06, 0x03, 0x06, + /* RLE: 039 Pixels @ 172,007*/ 39, 0x01, + /* ABS: 002 Pixels @ 211,007*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 213,007*/ 9, 0x03, + /* ABS: 002 Pixels @ 222,007*/ 0, 2, 0x04, 0x04, + /* RLE: 137 Pixels @ 224,007*/ 137, 0x01, + /* ABS: 002 Pixels @ 361,007*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 363,007*/ 8, 0x03, + /* ABS: 002 Pixels @ 371,007*/ 0, 2, 0x04, 0x04, + /* RLE: 027 Pixels @ 373,007*/ 27, 0x00, + /* RLE: 005 Pixels @ 000,008*/ 5, 0x07, + /* ABS: 004 Pixels @ 005,008*/ 0, 4, 0x14, 0x07, 0x07, 0x14, + /* RLE: 015 Pixels @ 009,008*/ 15, 0x07, + /* RLE: 001 Pixels @ 024,008*/ 1, 0x14, + /* RLE: 017 Pixels @ 025,008*/ 17, 0x07, + /* RLE: 001 Pixels @ 042,008*/ 1, 0x14, + /* RLE: 023 Pixels @ 043,008*/ 23, 0x01, + /* ABS: 002 Pixels @ 066,008*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 068,008*/ 8, 0x03, + /* ABS: 002 Pixels @ 076,008*/ 0, 2, 0x04, 0x04, + /* RLE: 091 Pixels @ 078,008*/ 91, 0x00, + /* ABS: 005 Pixels @ 169,008*/ 0, 5, 0x0D, 0x06, 0x03, 0x06, 0x06, + /* RLE: 038 Pixels @ 174,008*/ 38, 0x01, + /* ABS: 002 Pixels @ 212,008*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 214,008*/ 9, 0x03, + /* ABS: 002 Pixels @ 223,008*/ 0, 2, 0x04, 0x04, + /* RLE: 137 Pixels @ 225,008*/ 137, 0x01, + /* ABS: 002 Pixels @ 362,008*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 364,008*/ 8, 0x03, + /* ABS: 002 Pixels @ 372,008*/ 0, 2, 0x04, 0x04, + /* RLE: 026 Pixels @ 374,008*/ 26, 0x00, + /* RLE: 008 Pixels @ 000,009*/ 8, 0x07, + /* RLE: 001 Pixels @ 008,009*/ 1, 0x14, + /* RLE: 015 Pixels @ 009,009*/ 15, 0x07, + /* RLE: 001 Pixels @ 024,009*/ 1, 0x14, + /* RLE: 017 Pixels @ 025,009*/ 17, 0x07, + /* RLE: 025 Pixels @ 042,009*/ 25, 0x01, + /* ABS: 002 Pixels @ 067,009*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 069,009*/ 8, 0x03, + /* ABS: 002 Pixels @ 077,009*/ 0, 2, 0x04, 0x04, + /* RLE: 091 Pixels @ 079,009*/ 91, 0x00, + /* RLE: 001 Pixels @ 170,009*/ 1, 0x0D, + /* RLE: 004 Pixels @ 171,009*/ 4, 0x06, + /* RLE: 038 Pixels @ 175,009*/ 38, 0x01, + /* ABS: 002 Pixels @ 213,009*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 215,009*/ 9, 0x03, + /* ABS: 002 Pixels @ 224,009*/ 0, 2, 0x04, 0x04, + /* RLE: 137 Pixels @ 226,009*/ 137, 0x01, + /* ABS: 002 Pixels @ 363,009*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 365,009*/ 8, 0x03, + /* ABS: 002 Pixels @ 373,009*/ 0, 2, 0x04, 0x04, + /* RLE: 025 Pixels @ 375,009*/ 25, 0x00, + /* RLE: 008 Pixels @ 000,010*/ 8, 0x07, + /* ABS: 002 Pixels @ 008,010*/ 0, 2, 0x14, 0x14, + /* RLE: 030 Pixels @ 010,010*/ 30, 0x07, + /* RLE: 028 Pixels @ 040,010*/ 28, 0x01, + /* ABS: 002 Pixels @ 068,010*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 070,010*/ 8, 0x03, + /* ABS: 002 Pixels @ 078,010*/ 0, 2, 0x04, 0x04, + /* RLE: 091 Pixels @ 080,010*/ 91, 0x00, + /* ABS: 005 Pixels @ 171,010*/ 0, 5, 0x0D, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 038 Pixels @ 176,010*/ 38, 0x01, + /* ABS: 002 Pixels @ 214,010*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 216,010*/ 9, 0x03, + /* ABS: 002 Pixels @ 225,010*/ 0, 2, 0x04, 0x04, + /* RLE: 137 Pixels @ 227,010*/ 137, 0x01, + /* ABS: 002 Pixels @ 364,010*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 366,010*/ 8, 0x03, + /* ABS: 002 Pixels @ 374,010*/ 0, 2, 0x04, 0x04, + /* RLE: 024 Pixels @ 376,010*/ 24, 0x00, + /* RLE: 013 Pixels @ 000,011*/ 13, 0x07, + /* RLE: 001 Pixels @ 013,011*/ 1, 0x14, + /* RLE: 025 Pixels @ 014,011*/ 25, 0x07, + /* RLE: 030 Pixels @ 039,011*/ 30, 0x01, + /* ABS: 002 Pixels @ 069,011*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 071,011*/ 8, 0x03, + /* ABS: 002 Pixels @ 079,011*/ 0, 2, 0x04, 0x04, + /* RLE: 092 Pixels @ 081,011*/ 92, 0x00, + /* ABS: 004 Pixels @ 173,011*/ 0, 4, 0x0D, 0x06, 0x06, 0x0D, + /* RLE: 038 Pixels @ 177,011*/ 38, 0x01, + /* ABS: 002 Pixels @ 215,011*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 217,011*/ 9, 0x03, + /* ABS: 002 Pixels @ 226,011*/ 0, 2, 0x04, 0x04, + /* RLE: 137 Pixels @ 228,011*/ 137, 0x01, + /* ABS: 002 Pixels @ 365,011*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 367,011*/ 8, 0x03, + /* ABS: 002 Pixels @ 375,011*/ 0, 2, 0x04, 0x04, + /* RLE: 023 Pixels @ 377,011*/ 23, 0x00, + /* RLE: 011 Pixels @ 000,012*/ 11, 0x07, + /* RLE: 001 Pixels @ 011,012*/ 1, 0x14, + /* RLE: 026 Pixels @ 012,012*/ 26, 0x07, + /* RLE: 032 Pixels @ 038,012*/ 32, 0x01, + /* ABS: 002 Pixels @ 070,012*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 072,012*/ 8, 0x03, + /* ABS: 002 Pixels @ 080,012*/ 0, 2, 0x04, 0x04, + /* RLE: 092 Pixels @ 082,012*/ 92, 0x00, + /* ABS: 004 Pixels @ 174,012*/ 0, 4, 0x0D, 0x03, 0x03, 0x06, + /* RLE: 038 Pixels @ 178,012*/ 38, 0x01, + /* ABS: 002 Pixels @ 216,012*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 218,012*/ 9, 0x03, + /* ABS: 002 Pixels @ 227,012*/ 0, 2, 0x04, 0x04, + /* RLE: 137 Pixels @ 229,012*/ 137, 0x01, + /* ABS: 002 Pixels @ 366,012*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 368,012*/ 8, 0x03, + /* ABS: 002 Pixels @ 376,012*/ 0, 2, 0x04, 0x04, + /* RLE: 022 Pixels @ 378,012*/ 22, 0x00, + /* RLE: 006 Pixels @ 000,013*/ 6, 0x07, + /* RLE: 001 Pixels @ 006,013*/ 1, 0x14, + /* RLE: 005 Pixels @ 007,013*/ 5, 0x07, + /* RLE: 001 Pixels @ 012,013*/ 1, 0x14, + /* RLE: 007 Pixels @ 013,013*/ 7, 0x07, + /* RLE: 003 Pixels @ 020,013*/ 3, 0x14, + /* RLE: 014 Pixels @ 023,013*/ 14, 0x07, + /* RLE: 034 Pixels @ 037,013*/ 34, 0x01, + /* ABS: 002 Pixels @ 071,013*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 073,013*/ 8, 0x03, + /* ABS: 002 Pixels @ 081,013*/ 0, 2, 0x04, 0x04, + /* RLE: 091 Pixels @ 083,013*/ 91, 0x00, + /* ABS: 004 Pixels @ 174,013*/ 0, 4, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 039 Pixels @ 178,013*/ 39, 0x01, + /* RLE: 003 Pixels @ 217,013*/ 3, 0x04, + /* RLE: 008 Pixels @ 220,013*/ 8, 0x03, + /* RLE: 003 Pixels @ 228,013*/ 3, 0x04, + /* RLE: 136 Pixels @ 231,013*/ 136, 0x01, + /* ABS: 002 Pixels @ 367,013*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 369,013*/ 8, 0x03, + /* ABS: 002 Pixels @ 377,013*/ 0, 2, 0x04, 0x04, + /* RLE: 021 Pixels @ 379,013*/ 21, 0x00, + /* RLE: 019 Pixels @ 000,014*/ 19, 0x07, + /* ABS: 005 Pixels @ 019,014*/ 0, 5, 0x14, 0x07, 0x07, 0x14, 0x14, + /* RLE: 011 Pixels @ 024,014*/ 11, 0x07, + /* ABS: 002 Pixels @ 035,014*/ 0, 2, 0x08, 0x08, + /* RLE: 036 Pixels @ 037,014*/ 36, 0x01, + /* RLE: 001 Pixels @ 073,014*/ 1, 0x04, + /* RLE: 008 Pixels @ 074,014*/ 8, 0x03, + /* ABS: 002 Pixels @ 082,014*/ 0, 2, 0x04, 0x04, + /* RLE: 091 Pixels @ 084,014*/ 91, 0x00, + /* RLE: 001 Pixels @ 175,014*/ 1, 0x0D, + /* RLE: 004 Pixels @ 176,014*/ 4, 0x06, + /* RLE: 039 Pixels @ 180,014*/ 39, 0x01, + /* ABS: 002 Pixels @ 219,014*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 221,014*/ 9, 0x03, + /* ABS: 002 Pixels @ 230,014*/ 0, 2, 0x04, 0x04, + /* RLE: 136 Pixels @ 232,014*/ 136, 0x01, + /* ABS: 002 Pixels @ 368,014*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 370,014*/ 8, 0x03, + /* ABS: 002 Pixels @ 378,014*/ 0, 2, 0x04, 0x04, + /* RLE: 020 Pixels @ 380,014*/ 20, 0x00, + /* RLE: 019 Pixels @ 000,015*/ 19, 0x07, + /* ABS: 006 Pixels @ 019,015*/ 0, 6, 0x14, 0x07, 0x07, 0x07, 0x14, 0x14, + /* RLE: 006 Pixels @ 025,015*/ 6, 0x07, + /* ABS: 005 Pixels @ 031,015*/ 0, 5, 0x14, 0x07, 0x07, 0x08, 0x02, + /* RLE: 037 Pixels @ 036,015*/ 37, 0x01, + /* ABS: 002 Pixels @ 073,015*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 075,015*/ 8, 0x03, + /* ABS: 002 Pixels @ 083,015*/ 0, 2, 0x04, 0x04, + /* RLE: 091 Pixels @ 085,015*/ 91, 0x00, + /* ABS: 005 Pixels @ 176,015*/ 0, 5, 0x0D, 0x06, 0x03, 0x06, 0x06, + /* RLE: 039 Pixels @ 181,015*/ 39, 0x01, + /* ABS: 002 Pixels @ 220,015*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 222,015*/ 9, 0x03, + /* ABS: 002 Pixels @ 231,015*/ 0, 2, 0x04, 0x04, + /* RLE: 136 Pixels @ 233,015*/ 136, 0x01, + /* ABS: 002 Pixels @ 369,015*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 371,015*/ 8, 0x03, + /* ABS: 002 Pixels @ 379,015*/ 0, 2, 0x04, 0x04, + /* RLE: 019 Pixels @ 381,015*/ 19, 0x00, + /* RLE: 001 Pixels @ 000,016*/ 1, 0x14, + /* RLE: 017 Pixels @ 001,016*/ 17, 0x07, + /* RLE: 001 Pixels @ 018,016*/ 1, 0x14, + /* RLE: 004 Pixels @ 019,016*/ 4, 0x07, + /* ABS: 002 Pixels @ 023,016*/ 0, 2, 0x14, 0x14, + /* RLE: 007 Pixels @ 025,016*/ 7, 0x07, + /* ABS: 003 Pixels @ 032,016*/ 0, 3, 0x14, 0x07, 0x02, + /* RLE: 038 Pixels @ 035,016*/ 38, 0x01, + /* RLE: 003 Pixels @ 073,016*/ 3, 0x04, + /* RLE: 008 Pixels @ 076,016*/ 8, 0x03, + /* ABS: 002 Pixels @ 084,016*/ 0, 2, 0x04, 0x04, + /* RLE: 091 Pixels @ 086,016*/ 91, 0x00, + /* ABS: 005 Pixels @ 177,016*/ 0, 5, 0x0D, 0x0D, 0x03, 0x06, 0x0D, + /* RLE: 039 Pixels @ 182,016*/ 39, 0x01, + /* ABS: 002 Pixels @ 221,016*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 223,016*/ 9, 0x03, + /* ABS: 002 Pixels @ 232,016*/ 0, 2, 0x04, 0x04, + /* RLE: 136 Pixels @ 234,016*/ 136, 0x01, + /* ABS: 002 Pixels @ 370,016*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 372,016*/ 8, 0x03, + /* ABS: 002 Pixels @ 380,016*/ 0, 2, 0x04, 0x04, + /* RLE: 018 Pixels @ 382,016*/ 18, 0x00, + /* RLE: 007 Pixels @ 000,017*/ 7, 0x07, + /* RLE: 001 Pixels @ 007,017*/ 1, 0x14, + /* RLE: 011 Pixels @ 008,017*/ 11, 0x07, + /* ABS: 005 Pixels @ 019,017*/ 0, 5, 0x14, 0x07, 0x07, 0x07, 0x14, + /* RLE: 009 Pixels @ 024,017*/ 9, 0x07, + /* RLE: 042 Pixels @ 033,017*/ 42, 0x01, + /* ABS: 002 Pixels @ 075,017*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 077,017*/ 8, 0x03, + /* ABS: 002 Pixels @ 085,017*/ 0, 2, 0x04, 0x04, + /* RLE: 092 Pixels @ 087,017*/ 92, 0x00, + /* ABS: 004 Pixels @ 179,017*/ 0, 4, 0x0D, 0x03, 0x06, 0x06, + /* RLE: 039 Pixels @ 183,017*/ 39, 0x01, + /* ABS: 002 Pixels @ 222,017*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 224,017*/ 9, 0x03, + /* ABS: 002 Pixels @ 233,017*/ 0, 2, 0x04, 0x04, + /* RLE: 136 Pixels @ 235,017*/ 136, 0x01, + /* ABS: 002 Pixels @ 371,017*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 373,017*/ 8, 0x03, + /* ABS: 002 Pixels @ 381,017*/ 0, 2, 0x04, 0x04, + /* RLE: 017 Pixels @ 383,017*/ 17, 0x00, + /* RLE: 006 Pixels @ 000,018*/ 6, 0x07, + /* ABS: 003 Pixels @ 006,018*/ 0, 3, 0x14, 0x07, 0x14, + /* RLE: 005 Pixels @ 009,018*/ 5, 0x07, + /* RLE: 001 Pixels @ 014,018*/ 1, 0x14, + /* RLE: 005 Pixels @ 015,018*/ 5, 0x07, + /* ABS: 004 Pixels @ 020,018*/ 0, 4, 0x14, 0x07, 0x14, 0x14, + /* RLE: 008 Pixels @ 024,018*/ 8, 0x07, + /* RLE: 044 Pixels @ 032,018*/ 44, 0x01, + /* ABS: 002 Pixels @ 076,018*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 078,018*/ 8, 0x03, + /* ABS: 002 Pixels @ 086,018*/ 0, 2, 0x04, 0x04, + /* RLE: 092 Pixels @ 088,018*/ 92, 0x00, + /* ABS: 004 Pixels @ 180,018*/ 0, 4, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 039 Pixels @ 184,018*/ 39, 0x01, + /* ABS: 002 Pixels @ 223,018*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 225,018*/ 9, 0x03, + /* ABS: 002 Pixels @ 234,018*/ 0, 2, 0x04, 0x04, + /* RLE: 136 Pixels @ 236,018*/ 136, 0x01, + /* ABS: 002 Pixels @ 372,018*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 374,018*/ 8, 0x03, + /* ABS: 002 Pixels @ 382,018*/ 0, 2, 0x04, 0x04, + /* RLE: 016 Pixels @ 384,018*/ 16, 0x00, + /* RLE: 004 Pixels @ 000,019*/ 4, 0x07, + /* ABS: 006 Pixels @ 004,019*/ 0, 6, 0x14, 0x14, 0x07, 0x07, 0x14, 0x14, + /* RLE: 012 Pixels @ 010,019*/ 12, 0x07, + /* RLE: 001 Pixels @ 022,019*/ 1, 0x14, + /* RLE: 008 Pixels @ 023,019*/ 8, 0x07, + /* RLE: 046 Pixels @ 031,019*/ 46, 0x01, + /* ABS: 002 Pixels @ 077,019*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 079,019*/ 8, 0x03, + /* ABS: 002 Pixels @ 087,019*/ 0, 2, 0x04, 0x04, + /* RLE: 092 Pixels @ 089,019*/ 92, 0x00, + /* ABS: 004 Pixels @ 181,019*/ 0, 4, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 040 Pixels @ 185,019*/ 40, 0x01, + /* ABS: 002 Pixels @ 225,019*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 227,019*/ 8, 0x03, + /* ABS: 002 Pixels @ 235,019*/ 0, 2, 0x04, 0x04, + /* RLE: 136 Pixels @ 237,019*/ 136, 0x01, + /* ABS: 002 Pixels @ 373,019*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 375,019*/ 8, 0x03, + /* ABS: 002 Pixels @ 383,019*/ 0, 2, 0x04, 0x04, + /* RLE: 015 Pixels @ 385,019*/ 15, 0x00, + /* RLE: 003 Pixels @ 000,020*/ 3, 0x07, + /* RLE: 001 Pixels @ 003,020*/ 1, 0x14, + /* RLE: 005 Pixels @ 004,020*/ 5, 0x07, + /* ABS: 002 Pixels @ 009,020*/ 0, 2, 0x14, 0x14, + /* RLE: 011 Pixels @ 011,020*/ 11, 0x07, + /* RLE: 001 Pixels @ 022,020*/ 1, 0x14, + /* RLE: 007 Pixels @ 023,020*/ 7, 0x07, + /* RLE: 048 Pixels @ 030,020*/ 48, 0x01, + /* ABS: 002 Pixels @ 078,020*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 080,020*/ 8, 0x03, + /* ABS: 002 Pixels @ 088,020*/ 0, 2, 0x04, 0x04, + /* RLE: 092 Pixels @ 090,020*/ 92, 0x00, + /* ABS: 005 Pixels @ 182,020*/ 0, 5, 0x0D, 0x06, 0x03, 0x06, 0x0D, + /* RLE: 039 Pixels @ 187,020*/ 39, 0x01, + /* ABS: 002 Pixels @ 226,020*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 228,020*/ 9, 0x03, + /* ABS: 002 Pixels @ 237,020*/ 0, 2, 0x04, 0x04, + /* RLE: 135 Pixels @ 239,020*/ 135, 0x01, + /* ABS: 002 Pixels @ 374,020*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 376,020*/ 9, 0x03, + /* ABS: 002 Pixels @ 385,020*/ 0, 2, 0x04, 0x04, + /* RLE: 013 Pixels @ 387,020*/ 13, 0x00, + /* RLE: 004 Pixels @ 000,021*/ 4, 0x07, + /* RLE: 001 Pixels @ 004,021*/ 1, 0x14, + /* RLE: 004 Pixels @ 005,021*/ 4, 0x07, + /* ABS: 002 Pixels @ 009,021*/ 0, 2, 0x14, 0x14, + /* RLE: 011 Pixels @ 011,021*/ 11, 0x07, + /* RLE: 001 Pixels @ 022,021*/ 1, 0x14, + /* RLE: 006 Pixels @ 023,021*/ 6, 0x07, + /* RLE: 050 Pixels @ 029,021*/ 50, 0x01, + /* ABS: 002 Pixels @ 079,021*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 081,021*/ 8, 0x03, + /* ABS: 002 Pixels @ 089,021*/ 0, 2, 0x04, 0x04, + /* RLE: 092 Pixels @ 091,021*/ 92, 0x00, + /* ABS: 005 Pixels @ 183,021*/ 0, 5, 0x0D, 0x06, 0x03, 0x06, 0x06, + /* RLE: 039 Pixels @ 188,021*/ 39, 0x01, + /* ABS: 002 Pixels @ 227,021*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 229,021*/ 9, 0x03, + /* ABS: 002 Pixels @ 238,021*/ 0, 2, 0x04, 0x04, + /* RLE: 135 Pixels @ 240,021*/ 135, 0x01, + /* ABS: 002 Pixels @ 375,021*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 377,021*/ 9, 0x03, + /* ABS: 002 Pixels @ 386,021*/ 0, 2, 0x04, 0x04, + /* RLE: 012 Pixels @ 388,021*/ 12, 0x00, + /* RLE: 003 Pixels @ 000,022*/ 3, 0x07, + /* RLE: 001 Pixels @ 003,022*/ 1, 0x14, + /* RLE: 006 Pixels @ 004,022*/ 6, 0x07, + /* ABS: 002 Pixels @ 010,022*/ 0, 2, 0x14, 0x14, + /* RLE: 016 Pixels @ 012,022*/ 16, 0x07, + /* RLE: 052 Pixels @ 028,022*/ 52, 0x01, + /* ABS: 002 Pixels @ 080,022*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 082,022*/ 8, 0x03, + /* ABS: 002 Pixels @ 090,022*/ 0, 2, 0x04, 0x04, + /* RLE: 092 Pixels @ 092,022*/ 92, 0x00, + /* ABS: 005 Pixels @ 184,022*/ 0, 5, 0x0D, 0x0D, 0x03, 0x06, 0x06, + /* RLE: 039 Pixels @ 189,022*/ 39, 0x01, + /* ABS: 002 Pixels @ 228,022*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 230,022*/ 9, 0x03, + /* ABS: 002 Pixels @ 239,022*/ 0, 2, 0x04, 0x04, + /* RLE: 135 Pixels @ 241,022*/ 135, 0x01, + /* ABS: 002 Pixels @ 376,022*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 378,022*/ 9, 0x03, + /* ABS: 002 Pixels @ 387,022*/ 0, 2, 0x04, 0x04, + /* RLE: 011 Pixels @ 389,022*/ 11, 0x00, + /* RLE: 003 Pixels @ 000,023*/ 3, 0x07, + /* RLE: 001 Pixels @ 003,023*/ 1, 0x14, + /* RLE: 005 Pixels @ 004,023*/ 5, 0x07, + /* ABS: 002 Pixels @ 009,023*/ 0, 2, 0x14, 0x14, + /* RLE: 015 Pixels @ 011,023*/ 15, 0x07, + /* RLE: 001 Pixels @ 026,023*/ 1, 0x14, + /* RLE: 054 Pixels @ 027,023*/ 54, 0x01, + /* ABS: 002 Pixels @ 081,023*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 083,023*/ 8, 0x03, + /* ABS: 002 Pixels @ 091,023*/ 0, 2, 0x04, 0x04, + /* RLE: 093 Pixels @ 093,023*/ 93, 0x00, + /* ABS: 004 Pixels @ 186,023*/ 0, 4, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 039 Pixels @ 190,023*/ 39, 0x01, + /* ABS: 002 Pixels @ 229,023*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 231,023*/ 9, 0x03, + /* RLE: 001 Pixels @ 240,023*/ 1, 0x04, + /* RLE: 136 Pixels @ 241,023*/ 136, 0x01, + /* ABS: 002 Pixels @ 377,023*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 379,023*/ 9, 0x03, + /* ABS: 002 Pixels @ 388,023*/ 0, 2, 0x04, 0x04, + /* RLE: 010 Pixels @ 390,023*/ 10, 0x00, + /* RLE: 004 Pixels @ 000,024*/ 4, 0x07, + /* ABS: 006 Pixels @ 004,024*/ 0, 6, 0x14, 0x07, 0x07, 0x07, 0x14, 0x14, + /* RLE: 016 Pixels @ 010,024*/ 16, 0x07, + /* RLE: 056 Pixels @ 026,024*/ 56, 0x01, + /* ABS: 002 Pixels @ 082,024*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 084,024*/ 8, 0x03, + /* ABS: 002 Pixels @ 092,024*/ 0, 2, 0x04, 0x04, + /* RLE: 093 Pixels @ 094,024*/ 93, 0x00, + /* ABS: 004 Pixels @ 187,024*/ 0, 4, 0x0D, 0x06, 0x06, 0x0D, + /* RLE: 039 Pixels @ 191,024*/ 39, 0x01, + /* ABS: 002 Pixels @ 230,024*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 232,024*/ 9, 0x03, + /* RLE: 137 Pixels @ 241,024*/ 137, 0x01, + /* ABS: 002 Pixels @ 378,024*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 380,024*/ 9, 0x03, + /* ABS: 002 Pixels @ 389,024*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 391,024*/ 9, 0x00, + /* RLE: 005 Pixels @ 000,025*/ 5, 0x07, + /* ABS: 004 Pixels @ 005,025*/ 0, 4, 0x14, 0x07, 0x07, 0x14, + /* RLE: 008 Pixels @ 009,025*/ 8, 0x07, + /* RLE: 001 Pixels @ 017,025*/ 1, 0x14, + /* RLE: 006 Pixels @ 018,025*/ 6, 0x07, + /* RLE: 059 Pixels @ 024,025*/ 59, 0x01, + /* ABS: 002 Pixels @ 083,025*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 085,025*/ 8, 0x03, + /* ABS: 002 Pixels @ 093,025*/ 0, 2, 0x04, 0x04, + /* RLE: 093 Pixels @ 095,025*/ 93, 0x00, + /* ABS: 004 Pixels @ 188,025*/ 0, 4, 0x0D, 0x06, 0x03, 0x06, + /* RLE: 039 Pixels @ 192,025*/ 39, 0x01, + /* ABS: 002 Pixels @ 231,025*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 233,025*/ 9, 0x03, + /* ABS: 002 Pixels @ 242,025*/ 0, 2, 0x04, 0x04, + /* RLE: 135 Pixels @ 244,025*/ 135, 0x01, + /* RLE: 003 Pixels @ 379,025*/ 3, 0x04, + /* RLE: 008 Pixels @ 382,025*/ 8, 0x03, + /* ABS: 002 Pixels @ 390,025*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 392,025*/ 8, 0x00, + /* RLE: 008 Pixels @ 000,026*/ 8, 0x07, + /* RLE: 001 Pixels @ 008,026*/ 1, 0x14, + /* RLE: 014 Pixels @ 009,026*/ 14, 0x07, + /* RLE: 061 Pixels @ 023,026*/ 61, 0x01, + /* ABS: 002 Pixels @ 084,026*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 086,026*/ 8, 0x03, + /* ABS: 002 Pixels @ 094,026*/ 0, 2, 0x04, 0x04, + /* RLE: 093 Pixels @ 096,026*/ 93, 0x00, + /* ABS: 004 Pixels @ 189,026*/ 0, 4, 0x0D, 0x06, 0x03, 0x06, + /* RLE: 039 Pixels @ 193,026*/ 39, 0x01, + /* ABS: 002 Pixels @ 232,026*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 234,026*/ 9, 0x03, + /* ABS: 002 Pixels @ 243,026*/ 0, 2, 0x04, 0x04, + /* RLE: 136 Pixels @ 245,026*/ 136, 0x01, + /* ABS: 002 Pixels @ 381,026*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 383,026*/ 8, 0x03, + /* ABS: 002 Pixels @ 391,026*/ 0, 2, 0x04, 0x04, + /* RLE: 007 Pixels @ 393,026*/ 7, 0x00, + /* RLE: 008 Pixels @ 000,027*/ 8, 0x07, + /* ABS: 002 Pixels @ 008,027*/ 0, 2, 0x14, 0x14, + /* RLE: 012 Pixels @ 010,027*/ 12, 0x07, + /* RLE: 063 Pixels @ 022,027*/ 63, 0x01, + /* ABS: 002 Pixels @ 085,027*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 087,027*/ 8, 0x03, + /* ABS: 002 Pixels @ 095,027*/ 0, 2, 0x04, 0x04, + /* RLE: 093 Pixels @ 097,027*/ 93, 0x00, + /* ABS: 005 Pixels @ 190,027*/ 0, 5, 0x0D, 0x06, 0x03, 0x06, 0x06, + /* RLE: 038 Pixels @ 195,027*/ 38, 0x01, + /* ABS: 002 Pixels @ 233,027*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 235,027*/ 9, 0x03, + /* ABS: 002 Pixels @ 244,027*/ 0, 2, 0x04, 0x04, + /* RLE: 136 Pixels @ 246,027*/ 136, 0x01, + /* ABS: 002 Pixels @ 382,027*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 384,027*/ 8, 0x03, + /* ABS: 002 Pixels @ 392,027*/ 0, 2, 0x04, 0x04, + /* RLE: 006 Pixels @ 394,027*/ 6, 0x00, + /* RLE: 013 Pixels @ 000,028*/ 13, 0x07, + /* RLE: 001 Pixels @ 013,028*/ 1, 0x14, + /* RLE: 007 Pixels @ 014,028*/ 7, 0x07, + /* RLE: 065 Pixels @ 021,028*/ 65, 0x01, + /* ABS: 002 Pixels @ 086,028*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 088,028*/ 8, 0x03, + /* ABS: 002 Pixels @ 096,028*/ 0, 2, 0x04, 0x04, + /* RLE: 093 Pixels @ 098,028*/ 93, 0x00, + /* RLE: 001 Pixels @ 191,028*/ 1, 0x0D, + /* RLE: 004 Pixels @ 192,028*/ 4, 0x06, + /* RLE: 038 Pixels @ 196,028*/ 38, 0x01, + /* ABS: 002 Pixels @ 234,028*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 236,028*/ 9, 0x03, + /* ABS: 002 Pixels @ 245,028*/ 0, 2, 0x04, 0x04, + /* RLE: 136 Pixels @ 247,028*/ 136, 0x01, + /* ABS: 002 Pixels @ 383,028*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 385,028*/ 8, 0x03, + /* ABS: 002 Pixels @ 393,028*/ 0, 2, 0x04, 0x04, + /* RLE: 005 Pixels @ 395,028*/ 5, 0x00, + /* RLE: 019 Pixels @ 000,029*/ 19, 0x07, + /* ABS: 002 Pixels @ 019,029*/ 0, 2, 0x08, 0x08, + /* RLE: 066 Pixels @ 021,029*/ 66, 0x01, + /* ABS: 002 Pixels @ 087,029*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 089,029*/ 8, 0x03, + /* ABS: 002 Pixels @ 097,029*/ 0, 2, 0x04, 0x04, + /* RLE: 093 Pixels @ 099,029*/ 93, 0x00, + /* ABS: 005 Pixels @ 192,029*/ 0, 5, 0x0D, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 038 Pixels @ 197,029*/ 38, 0x01, + /* ABS: 002 Pixels @ 235,029*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 237,029*/ 9, 0x03, + /* ABS: 002 Pixels @ 246,029*/ 0, 2, 0x04, 0x04, + /* RLE: 136 Pixels @ 248,029*/ 136, 0x01, + /* ABS: 002 Pixels @ 384,029*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 386,029*/ 8, 0x03, + /* ABS: 002 Pixels @ 394,029*/ 0, 2, 0x04, 0x04, + /* RLE: 004 Pixels @ 396,029*/ 4, 0x00, + /* RLE: 007 Pixels @ 000,030*/ 7, 0x07, + /* RLE: 001 Pixels @ 007,030*/ 1, 0x14, + /* RLE: 010 Pixels @ 008,030*/ 10, 0x07, + /* ABS: 002 Pixels @ 018,030*/ 0, 2, 0x08, 0x02, + /* RLE: 068 Pixels @ 020,030*/ 68, 0x01, + /* ABS: 002 Pixels @ 088,030*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 090,030*/ 9, 0x03, + /* ABS: 002 Pixels @ 099,030*/ 0, 2, 0x04, 0x04, + /* RLE: 093 Pixels @ 101,030*/ 93, 0x00, + /* ABS: 004 Pixels @ 194,030*/ 0, 4, 0x0D, 0x06, 0x06, 0x0D, + /* RLE: 039 Pixels @ 198,030*/ 39, 0x01, + /* ABS: 002 Pixels @ 237,030*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 239,030*/ 9, 0x03, + /* ABS: 002 Pixels @ 248,030*/ 0, 2, 0x04, 0x04, + /* RLE: 135 Pixels @ 250,030*/ 135, 0x01, + /* ABS: 002 Pixels @ 385,030*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 387,030*/ 8, 0x03, + /* ABS: 008 Pixels @ 395,030*/ 0, 8, 0x04, 0x04, 0x00, 0x00, 0x00, 0x14, 0x14, 0x14, + /* RLE: 013 Pixels @ 003,031*/ 13, 0x07, + /* RLE: 004 Pixels @ 016,031*/ 4, 0x02, + /* RLE: 069 Pixels @ 020,031*/ 69, 0x01, + /* ABS: 002 Pixels @ 089,031*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 091,031*/ 9, 0x03, + /* ABS: 002 Pixels @ 100,031*/ 0, 2, 0x04, 0x04, + /* RLE: 093 Pixels @ 102,031*/ 93, 0x00, + /* ABS: 004 Pixels @ 195,031*/ 0, 4, 0x0D, 0x03, 0x03, 0x06, + /* RLE: 039 Pixels @ 199,031*/ 39, 0x01, + /* ABS: 002 Pixels @ 238,031*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 240,031*/ 9, 0x03, + /* ABS: 002 Pixels @ 249,031*/ 0, 2, 0x04, 0x04, + /* RLE: 135 Pixels @ 251,031*/ 135, 0x01, + /* ABS: 002 Pixels @ 386,031*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 388,031*/ 8, 0x03, + /* ABS: 008 Pixels @ 396,031*/ 0, 8, 0x04, 0x04, 0x00, 0x00, 0x07, 0x07, 0x14, 0x14, + /* RLE: 008 Pixels @ 004,032*/ 8, 0x07, + /* ABS: 003 Pixels @ 012,032*/ 0, 3, 0x14, 0x08, 0x08, + /* RLE: 006 Pixels @ 015,032*/ 6, 0x02, + /* RLE: 069 Pixels @ 021,032*/ 69, 0x01, + /* ABS: 002 Pixels @ 090,032*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 092,032*/ 9, 0x03, + /* ABS: 002 Pixels @ 101,032*/ 0, 2, 0x04, 0x04, + /* RLE: 093 Pixels @ 103,032*/ 93, 0x00, + /* ABS: 004 Pixels @ 196,032*/ 0, 4, 0x0D, 0x06, 0x03, 0x06, + /* RLE: 039 Pixels @ 200,032*/ 39, 0x01, + /* ABS: 002 Pixels @ 239,032*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 241,032*/ 9, 0x03, + /* ABS: 002 Pixels @ 250,032*/ 0, 2, 0x04, 0x04, + /* RLE: 135 Pixels @ 252,032*/ 135, 0x01, + /* ABS: 002 Pixels @ 387,032*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 389,032*/ 8, 0x03, + /* ABS: 008 Pixels @ 397,032*/ 0, 8, 0x04, 0x04, 0x00, 0x07, 0x07, 0x07, 0x14, 0x14, + /* RLE: 007 Pixels @ 005,033*/ 7, 0x07, + /* RLE: 001 Pixels @ 012,033*/ 1, 0x08, + /* RLE: 008 Pixels @ 013,033*/ 8, 0x02, + /* RLE: 001 Pixels @ 021,033*/ 1, 0x08, + /* RLE: 069 Pixels @ 022,033*/ 69, 0x01, + /* ABS: 002 Pixels @ 091,033*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 093,033*/ 9, 0x03, + /* ABS: 002 Pixels @ 102,033*/ 0, 2, 0x04, 0x04, + /* RLE: 093 Pixels @ 104,033*/ 93, 0x00, + /* RLE: 001 Pixels @ 197,033*/ 1, 0x0D, + /* RLE: 004 Pixels @ 198,033*/ 4, 0x06, + /* RLE: 038 Pixels @ 202,033*/ 38, 0x01, + /* ABS: 002 Pixels @ 240,033*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 242,033*/ 9, 0x03, + /* ABS: 002 Pixels @ 251,033*/ 0, 2, 0x04, 0x04, + /* RLE: 135 Pixels @ 253,033*/ 135, 0x01, + /* ABS: 002 Pixels @ 388,033*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 390,033*/ 8, 0x03, + /* ABS: 007 Pixels @ 398,033*/ 0, 7, 0x04, 0x04, 0x07, 0x07, 0x07, 0x14, 0x14, + /* RLE: 005 Pixels @ 005,034*/ 5, 0x07, + /* RLE: 011 Pixels @ 010,034*/ 11, 0x02, + /* RLE: 001 Pixels @ 021,034*/ 1, 0x08, + /* RLE: 070 Pixels @ 022,034*/ 70, 0x01, + /* ABS: 002 Pixels @ 092,034*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 094,034*/ 9, 0x03, + /* ABS: 002 Pixels @ 103,034*/ 0, 2, 0x04, 0x04, + /* RLE: 093 Pixels @ 105,034*/ 93, 0x00, + /* RLE: 001 Pixels @ 198,034*/ 1, 0x0D, + /* RLE: 004 Pixels @ 199,034*/ 4, 0x06, + /* RLE: 038 Pixels @ 203,034*/ 38, 0x01, + /* ABS: 002 Pixels @ 241,034*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 243,034*/ 9, 0x03, + /* ABS: 002 Pixels @ 252,034*/ 0, 2, 0x04, 0x04, + /* RLE: 135 Pixels @ 254,034*/ 135, 0x01, + /* ABS: 002 Pixels @ 389,034*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 391,034*/ 8, 0x03, + /* ABS: 010 Pixels @ 399,034*/ 0, 10, 0x04, 0x07, 0x07, 0x07, 0x14, 0x14, 0x07, 0x07, 0x08, 0x08, + /* RLE: 012 Pixels @ 009,035*/ 12, 0x02, + /* RLE: 001 Pixels @ 021,035*/ 1, 0x08, + /* RLE: 071 Pixels @ 022,035*/ 71, 0x01, + /* RLE: 003 Pixels @ 093,035*/ 3, 0x04, + /* RLE: 008 Pixels @ 096,035*/ 8, 0x03, + /* ABS: 002 Pixels @ 104,035*/ 0, 2, 0x04, 0x04, + /* RLE: 093 Pixels @ 106,035*/ 93, 0x00, + /* ABS: 005 Pixels @ 199,035*/ 0, 5, 0x0D, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 038 Pixels @ 204,035*/ 38, 0x01, + /* ABS: 002 Pixels @ 242,035*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 244,035*/ 9, 0x03, + /* ABS: 002 Pixels @ 253,035*/ 0, 2, 0x04, 0x04, + /* RLE: 135 Pixels @ 255,035*/ 135, 0x01, + /* ABS: 002 Pixels @ 390,035*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 392,035*/ 8, 0x03, + /* ABS: 007 Pixels @ 000,036*/ 0, 7, 0x07, 0x07, 0x14, 0x14, 0x07, 0x07, 0x08, + /* RLE: 014 Pixels @ 007,036*/ 14, 0x02, + /* RLE: 074 Pixels @ 021,036*/ 74, 0x01, + /* ABS: 002 Pixels @ 095,036*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 097,036*/ 8, 0x03, + /* ABS: 002 Pixels @ 105,036*/ 0, 2, 0x04, 0x04, + /* RLE: 094 Pixels @ 107,036*/ 94, 0x00, + /* ABS: 004 Pixels @ 201,036*/ 0, 4, 0x0D, 0x03, 0x06, 0x0D, + /* RLE: 038 Pixels @ 205,036*/ 38, 0x01, + /* RLE: 003 Pixels @ 243,036*/ 3, 0x04, + /* RLE: 008 Pixels @ 246,036*/ 8, 0x03, + /* RLE: 003 Pixels @ 254,036*/ 3, 0x04, + /* RLE: 134 Pixels @ 257,036*/ 134, 0x01, + /* ABS: 002 Pixels @ 391,036*/ 0, 2, 0x04, 0x04, + /* RLE: 007 Pixels @ 393,036*/ 7, 0x03, + /* ABS: 004 Pixels @ 000,037*/ 0, 4, 0x07, 0x07, 0x14, 0x07, + /* RLE: 017 Pixels @ 004,037*/ 17, 0x02, + /* RLE: 075 Pixels @ 021,037*/ 75, 0x01, + /* ABS: 002 Pixels @ 096,037*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 098,037*/ 8, 0x03, + /* ABS: 002 Pixels @ 106,037*/ 0, 2, 0x04, 0x04, + /* RLE: 094 Pixels @ 108,037*/ 94, 0x00, + /* ABS: 004 Pixels @ 202,037*/ 0, 4, 0x0D, 0x03, 0x03, 0x06, + /* RLE: 039 Pixels @ 206,037*/ 39, 0x01, + /* ABS: 002 Pixels @ 245,037*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 247,037*/ 9, 0x03, + /* ABS: 002 Pixels @ 256,037*/ 0, 2, 0x04, 0x04, + /* RLE: 134 Pixels @ 258,037*/ 134, 0x01, + /* ABS: 002 Pixels @ 392,037*/ 0, 2, 0x04, 0x04, + /* RLE: 006 Pixels @ 394,037*/ 6, 0x03, + /* ABS: 003 Pixels @ 000,038*/ 0, 3, 0x07, 0x08, 0x08, + /* RLE: 019 Pixels @ 003,038*/ 19, 0x02, + /* RLE: 075 Pixels @ 022,038*/ 75, 0x01, + /* ABS: 002 Pixels @ 097,038*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 099,038*/ 8, 0x03, + /* ABS: 002 Pixels @ 107,038*/ 0, 2, 0x04, 0x04, + /* RLE: 094 Pixels @ 109,038*/ 94, 0x00, + /* ABS: 004 Pixels @ 203,038*/ 0, 4, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 039 Pixels @ 207,038*/ 39, 0x01, + /* ABS: 002 Pixels @ 246,038*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 248,038*/ 9, 0x03, + /* ABS: 002 Pixels @ 257,038*/ 0, 2, 0x04, 0x04, + /* RLE: 134 Pixels @ 259,038*/ 134, 0x01, + /* ABS: 002 Pixels @ 393,038*/ 0, 2, 0x04, 0x04, + /* RLE: 005 Pixels @ 395,038*/ 5, 0x03, + /* RLE: 001 Pixels @ 000,039*/ 1, 0x08, + /* RLE: 021 Pixels @ 001,039*/ 21, 0x02, + /* RLE: 001 Pixels @ 022,039*/ 1, 0x08, + /* RLE: 075 Pixels @ 023,039*/ 75, 0x01, + /* ABS: 002 Pixels @ 098,039*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 100,039*/ 8, 0x03, + /* ABS: 002 Pixels @ 108,039*/ 0, 2, 0x04, 0x04, + /* RLE: 094 Pixels @ 110,039*/ 94, 0x00, + /* ABS: 004 Pixels @ 204,039*/ 0, 4, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 039 Pixels @ 208,039*/ 39, 0x01, + /* ABS: 002 Pixels @ 247,039*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 249,039*/ 9, 0x03, + /* ABS: 002 Pixels @ 258,039*/ 0, 2, 0x04, 0x04, + /* RLE: 134 Pixels @ 260,039*/ 134, 0x01, + /* ABS: 002 Pixels @ 394,039*/ 0, 2, 0x04, 0x04, + /* RLE: 004 Pixels @ 396,039*/ 4, 0x03, + /* RLE: 022 Pixels @ 000,040*/ 22, 0x02, + /* RLE: 001 Pixels @ 022,040*/ 1, 0x08, + /* RLE: 076 Pixels @ 023,040*/ 76, 0x01, + /* ABS: 002 Pixels @ 099,040*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 101,040*/ 8, 0x03, + /* ABS: 002 Pixels @ 109,040*/ 0, 2, 0x04, 0x04, + /* RLE: 094 Pixels @ 111,040*/ 94, 0x00, + /* RLE: 001 Pixels @ 205,040*/ 1, 0x0D, + /* RLE: 004 Pixels @ 206,040*/ 4, 0x06, + /* RLE: 038 Pixels @ 210,040*/ 38, 0x01, + /* ABS: 002 Pixels @ 248,040*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 250,040*/ 9, 0x03, + /* ABS: 002 Pixels @ 259,040*/ 0, 2, 0x04, 0x04, + /* RLE: 134 Pixels @ 261,040*/ 134, 0x01, + /* ABS: 005 Pixels @ 395,040*/ 0, 5, 0x04, 0x04, 0x03, 0x03, 0x03, + /* RLE: 021 Pixels @ 000,041*/ 21, 0x02, + /* RLE: 005 Pixels @ 021,041*/ 5, 0x04, + /* RLE: 074 Pixels @ 026,041*/ 74, 0x01, + /* ABS: 002 Pixels @ 100,041*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 102,041*/ 8, 0x03, + /* ABS: 002 Pixels @ 110,041*/ 0, 2, 0x04, 0x04, + /* RLE: 094 Pixels @ 112,041*/ 94, 0x00, + /* ABS: 005 Pixels @ 206,041*/ 0, 5, 0x0D, 0x06, 0x03, 0x06, 0x06, + /* RLE: 038 Pixels @ 211,041*/ 38, 0x01, + /* ABS: 002 Pixels @ 249,041*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 251,041*/ 9, 0x03, + /* ABS: 002 Pixels @ 260,041*/ 0, 2, 0x04, 0x04, + /* RLE: 134 Pixels @ 262,041*/ 134, 0x01, + /* ABS: 004 Pixels @ 396,041*/ 0, 4, 0x04, 0x04, 0x03, 0x03, + /* RLE: 020 Pixels @ 000,042*/ 20, 0x02, + /* ABS: 007 Pixels @ 020,042*/ 0, 7, 0x04, 0x04, 0x03, 0x03, 0x03, 0x04, 0x04, + /* RLE: 074 Pixels @ 027,042*/ 74, 0x01, + /* ABS: 002 Pixels @ 101,042*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 103,042*/ 8, 0x03, + /* ABS: 002 Pixels @ 111,042*/ 0, 2, 0x04, 0x04, + /* RLE: 094 Pixels @ 113,042*/ 94, 0x00, + /* ABS: 005 Pixels @ 207,042*/ 0, 5, 0x0D, 0x0D, 0x03, 0x06, 0x0D, + /* RLE: 039 Pixels @ 212,042*/ 39, 0x01, + /* ABS: 002 Pixels @ 251,042*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 253,042*/ 8, 0x03, + /* ABS: 002 Pixels @ 261,042*/ 0, 2, 0x04, 0x04, + /* RLE: 134 Pixels @ 263,042*/ 134, 0x01, + /* ABS: 003 Pixels @ 397,042*/ 0, 3, 0x04, 0x04, 0x03, + /* RLE: 020 Pixels @ 000,043*/ 20, 0x02, + /* RLE: 001 Pixels @ 020,043*/ 1, 0x04, + /* RLE: 005 Pixels @ 021,043*/ 5, 0x03, + /* RLE: 001 Pixels @ 026,043*/ 1, 0x04, + /* RLE: 075 Pixels @ 027,043*/ 75, 0x01, + /* ABS: 002 Pixels @ 102,043*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 104,043*/ 8, 0x03, + /* ABS: 002 Pixels @ 112,043*/ 0, 2, 0x04, 0x04, + /* RLE: 095 Pixels @ 114,043*/ 95, 0x00, + /* ABS: 004 Pixels @ 209,043*/ 0, 4, 0x0D, 0x03, 0x06, 0x06, + /* RLE: 039 Pixels @ 213,043*/ 39, 0x01, + /* ABS: 002 Pixels @ 252,043*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 254,043*/ 9, 0x03, + /* ABS: 002 Pixels @ 263,043*/ 0, 2, 0x04, 0x04, + /* RLE: 133 Pixels @ 265,043*/ 133, 0x01, + /* ABS: 002 Pixels @ 398,043*/ 0, 2, 0x04, 0x04, + /* RLE: 019 Pixels @ 000,044*/ 19, 0x02, + /* ABS: 002 Pixels @ 019,044*/ 0, 2, 0x04, 0x04, + /* RLE: 006 Pixels @ 021,044*/ 6, 0x03, + /* RLE: 076 Pixels @ 027,044*/ 76, 0x01, + /* ABS: 002 Pixels @ 103,044*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 105,044*/ 8, 0x03, + /* ABS: 002 Pixels @ 113,044*/ 0, 2, 0x04, 0x04, + /* RLE: 095 Pixels @ 115,044*/ 95, 0x00, + /* ABS: 004 Pixels @ 210,044*/ 0, 4, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 039 Pixels @ 214,044*/ 39, 0x01, + /* ABS: 002 Pixels @ 253,044*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 255,044*/ 9, 0x03, + /* ABS: 002 Pixels @ 264,044*/ 0, 2, 0x04, 0x04, + /* RLE: 133 Pixels @ 266,044*/ 133, 0x01, + /* RLE: 001 Pixels @ 399,044*/ 1, 0x04, + /* RLE: 020 Pixels @ 000,045*/ 20, 0x02, + /* RLE: 001 Pixels @ 020,045*/ 1, 0x04, + /* RLE: 006 Pixels @ 021,045*/ 6, 0x03, + /* RLE: 001 Pixels @ 027,045*/ 1, 0x04, + /* RLE: 076 Pixels @ 028,045*/ 76, 0x01, + /* ABS: 002 Pixels @ 104,045*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 106,045*/ 8, 0x03, + /* ABS: 002 Pixels @ 114,045*/ 0, 2, 0x04, 0x04, + /* RLE: 095 Pixels @ 116,045*/ 95, 0x00, + /* ABS: 004 Pixels @ 211,045*/ 0, 4, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 039 Pixels @ 215,045*/ 39, 0x01, + /* ABS: 002 Pixels @ 254,045*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 256,045*/ 9, 0x03, + /* ABS: 002 Pixels @ 265,045*/ 0, 2, 0x04, 0x04, + /* RLE: 133 Pixels @ 267,045*/ 133, 0x01, + /* RLE: 020 Pixels @ 000,046*/ 20, 0x02, + /* RLE: 001 Pixels @ 020,046*/ 1, 0x04, + /* RLE: 006 Pixels @ 021,046*/ 6, 0x03, + /* RLE: 001 Pixels @ 027,046*/ 1, 0x04, + /* RLE: 077 Pixels @ 028,046*/ 77, 0x01, + /* ABS: 002 Pixels @ 105,046*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 107,046*/ 8, 0x03, + /* ABS: 002 Pixels @ 115,046*/ 0, 2, 0x04, 0x04, + /* RLE: 062 Pixels @ 117,046*/ 62, 0x00, + /* ABS: 002 Pixels @ 179,046*/ 0, 2, 0x03, 0x03, + /* RLE: 031 Pixels @ 181,046*/ 31, 0x00, + /* ABS: 005 Pixels @ 212,046*/ 0, 5, 0x0D, 0x06, 0x03, 0x06, 0x0D, + /* RLE: 038 Pixels @ 217,046*/ 38, 0x01, + /* ABS: 002 Pixels @ 255,046*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 257,046*/ 9, 0x03, + /* RLE: 001 Pixels @ 266,046*/ 1, 0x04, + /* RLE: 133 Pixels @ 267,046*/ 133, 0x01, + /* RLE: 020 Pixels @ 000,047*/ 20, 0x02, + /* RLE: 001 Pixels @ 020,047*/ 1, 0x04, + /* RLE: 006 Pixels @ 021,047*/ 6, 0x03, + /* RLE: 001 Pixels @ 027,047*/ 1, 0x04, + /* RLE: 078 Pixels @ 028,047*/ 78, 0x01, + /* ABS: 002 Pixels @ 106,047*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 108,047*/ 8, 0x03, + /* ABS: 002 Pixels @ 116,047*/ 0, 2, 0x04, 0x04, + /* RLE: 060 Pixels @ 118,047*/ 60, 0x00, + /* ABS: 004 Pixels @ 178,047*/ 0, 4, 0x03, 0x0B, 0x0E, 0x03, + /* RLE: 031 Pixels @ 182,047*/ 31, 0x00, + /* ABS: 005 Pixels @ 213,047*/ 0, 5, 0x0D, 0x06, 0x03, 0x06, 0x06, + /* RLE: 038 Pixels @ 218,047*/ 38, 0x01, + /* ABS: 002 Pixels @ 256,047*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 258,047*/ 9, 0x03, + /* RLE: 133 Pixels @ 267,047*/ 133, 0x01, + /* RLE: 020 Pixels @ 000,048*/ 20, 0x02, + /* RLE: 001 Pixels @ 020,048*/ 1, 0x04, + /* RLE: 006 Pixels @ 021,048*/ 6, 0x03, + /* RLE: 001 Pixels @ 027,048*/ 1, 0x04, + /* RLE: 079 Pixels @ 028,048*/ 79, 0x01, + /* ABS: 002 Pixels @ 107,048*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 109,048*/ 8, 0x03, + /* ABS: 002 Pixels @ 117,048*/ 0, 2, 0x04, 0x04, + /* RLE: 054 Pixels @ 119,048*/ 54, 0x00, + /* ABS: 009 Pixels @ 173,048*/ 0, 9, 0x03, 0x00, 0x03, 0x00, 0x03, 0x0C, 0x0D, 0x0E, 0x03, + /* RLE: 004 Pixels @ 182,048*/ 4, 0x00, + /* RLE: 001 Pixels @ 186,048*/ 1, 0x0B, + /* RLE: 027 Pixels @ 187,048*/ 27, 0x00, + /* ABS: 005 Pixels @ 214,048*/ 0, 5, 0x0D, 0x0D, 0x03, 0x06, 0x06, + /* RLE: 038 Pixels @ 219,048*/ 38, 0x01, + /* ABS: 002 Pixels @ 257,048*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 259,048*/ 9, 0x03, + /* ABS: 002 Pixels @ 268,048*/ 0, 2, 0x04, 0x04, + /* RLE: 130 Pixels @ 270,048*/ 130, 0x01, + /* RLE: 020 Pixels @ 000,049*/ 20, 0x02, + /* RLE: 001 Pixels @ 020,049*/ 1, 0x04, + /* RLE: 006 Pixels @ 021,049*/ 6, 0x03, + /* RLE: 001 Pixels @ 027,049*/ 1, 0x04, + /* RLE: 080 Pixels @ 028,049*/ 80, 0x01, + /* ABS: 002 Pixels @ 108,049*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 110,049*/ 8, 0x03, + /* ABS: 002 Pixels @ 118,049*/ 0, 2, 0x04, 0x04, + /* RLE: 053 Pixels @ 120,049*/ 53, 0x00, + /* ABS: 014 Pixels @ 173,049*/ 0, 14, 0x03, 0x0E, 0x0E, 0x00, 0x03, 0x0F, 0x08, 0x03, 0x03, 0x00, 0x03, 0x00, 0x03, 0x03, + /* RLE: 029 Pixels @ 187,049*/ 29, 0x00, + /* ABS: 004 Pixels @ 216,049*/ 0, 4, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 038 Pixels @ 220,049*/ 38, 0x01, + /* ABS: 002 Pixels @ 258,049*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 260,049*/ 9, 0x03, + /* ABS: 002 Pixels @ 269,049*/ 0, 2, 0x04, 0x04, + /* RLE: 129 Pixels @ 271,049*/ 129, 0x01, + /* RLE: 021 Pixels @ 000,050*/ 21, 0x02, + /* RLE: 007 Pixels @ 021,050*/ 7, 0x03, + /* RLE: 001 Pixels @ 028,050*/ 1, 0x04, + /* RLE: 080 Pixels @ 029,050*/ 80, 0x01, + /* ABS: 002 Pixels @ 109,050*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 111,050*/ 8, 0x03, + /* ABS: 002 Pixels @ 119,050*/ 0, 2, 0x04, 0x04, + /* RLE: 052 Pixels @ 121,050*/ 52, 0x00, + /* ABS: 014 Pixels @ 173,050*/ 0, 14, 0x03, 0x0C, 0x08, 0x08, 0x00, 0x04, 0x08, 0x04, 0x03, 0x00, 0x03, 0x11, 0x12, 0x03, + /* RLE: 030 Pixels @ 187,050*/ 30, 0x00, + /* ABS: 004 Pixels @ 217,050*/ 0, 4, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 038 Pixels @ 221,050*/ 38, 0x01, + /* ABS: 002 Pixels @ 259,050*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 261,050*/ 9, 0x03, + /* ABS: 002 Pixels @ 270,050*/ 0, 2, 0x04, 0x04, + /* RLE: 128 Pixels @ 272,050*/ 128, 0x01, + /* RLE: 021 Pixels @ 000,051*/ 21, 0x02, + /* RLE: 001 Pixels @ 021,051*/ 1, 0x04, + /* RLE: 006 Pixels @ 022,051*/ 6, 0x03, + /* RLE: 001 Pixels @ 028,051*/ 1, 0x04, + /* RLE: 081 Pixels @ 029,051*/ 81, 0x01, + /* ABS: 002 Pixels @ 110,051*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 112,051*/ 8, 0x03, + /* ABS: 002 Pixels @ 120,051*/ 0, 2, 0x04, 0x04, + /* RLE: 050 Pixels @ 122,051*/ 50, 0x00, + /* ABS: 015 Pixels @ 172,051*/ 0, 15, 0x04, 0x03, 0x0E, 0x08, 0x11, 0x03, 0x03, 0x06, 0x0F, 0x03, 0x03, 0x03, 0x0B, 0x00, 0x03, + /* RLE: 031 Pixels @ 187,051*/ 31, 0x00, + /* ABS: 004 Pixels @ 218,051*/ 0, 4, 0x0D, 0x06, 0x03, 0x06, + /* RLE: 038 Pixels @ 222,051*/ 38, 0x01, + /* ABS: 002 Pixels @ 260,051*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 262,051*/ 9, 0x03, + /* ABS: 002 Pixels @ 271,051*/ 0, 2, 0x04, 0x04, + /* RLE: 127 Pixels @ 273,051*/ 127, 0x01, + /* RLE: 021 Pixels @ 000,052*/ 21, 0x02, + /* RLE: 001 Pixels @ 021,052*/ 1, 0x04, + /* RLE: 006 Pixels @ 022,052*/ 6, 0x03, + /* RLE: 001 Pixels @ 028,052*/ 1, 0x04, + /* RLE: 082 Pixels @ 029,052*/ 82, 0x01, + /* ABS: 002 Pixels @ 111,052*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 113,052*/ 8, 0x03, + /* ABS: 002 Pixels @ 121,052*/ 0, 2, 0x04, 0x04, + /* RLE: 048 Pixels @ 123,052*/ 48, 0x00, + /* RLE: 004 Pixels @ 171,052*/ 4, 0x03, + /* ABS: 011 Pixels @ 175,052*/ 0, 11, 0x0B, 0x08, 0x0C, 0x03, 0x00, 0x08, 0x0E, 0x03, 0x00, 0x03, 0x03, + /* RLE: 033 Pixels @ 186,052*/ 33, 0x00, + /* ABS: 005 Pixels @ 219,052*/ 0, 5, 0x0D, 0x06, 0x03, 0x06, 0x0D, + /* RLE: 037 Pixels @ 224,052*/ 37, 0x01, + /* ABS: 002 Pixels @ 261,052*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 263,052*/ 9, 0x03, + /* ABS: 002 Pixels @ 272,052*/ 0, 2, 0x04, 0x04, + /* RLE: 126 Pixels @ 274,052*/ 126, 0x01, + /* RLE: 021 Pixels @ 000,053*/ 21, 0x02, + /* RLE: 001 Pixels @ 021,053*/ 1, 0x04, + /* RLE: 006 Pixels @ 022,053*/ 6, 0x03, + /* RLE: 001 Pixels @ 028,053*/ 1, 0x04, + /* RLE: 083 Pixels @ 029,053*/ 83, 0x01, + /* ABS: 002 Pixels @ 112,053*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 114,053*/ 8, 0x03, + /* ABS: 002 Pixels @ 122,053*/ 0, 2, 0x04, 0x04, + /* RLE: 046 Pixels @ 124,053*/ 46, 0x00, + /* ABS: 015 Pixels @ 170,053*/ 0, 15, 0x03, 0x0B, 0x06, 0x12, 0x03, 0x03, 0x0E, 0x08, 0x04, 0x04, 0x04, 0x00, 0x03, 0x04, 0x04, + /* RLE: 035 Pixels @ 185,053*/ 35, 0x00, + /* ABS: 005 Pixels @ 220,053*/ 0, 5, 0x0D, 0x06, 0x03, 0x06, 0x06, + /* RLE: 038 Pixels @ 225,053*/ 38, 0x01, + /* ABS: 002 Pixels @ 263,053*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 265,053*/ 9, 0x03, + /* ABS: 002 Pixels @ 274,053*/ 0, 2, 0x04, 0x04, + /* RLE: 124 Pixels @ 276,053*/ 124, 0x01, + /* RLE: 021 Pixels @ 000,054*/ 21, 0x02, + /* RLE: 001 Pixels @ 021,054*/ 1, 0x04, + /* RLE: 006 Pixels @ 022,054*/ 6, 0x03, + /* RLE: 001 Pixels @ 028,054*/ 1, 0x04, + /* RLE: 084 Pixels @ 029,054*/ 84, 0x01, + /* ABS: 002 Pixels @ 113,054*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 115,054*/ 8, 0x03, + /* ABS: 002 Pixels @ 123,054*/ 0, 2, 0x04, 0x04, + /* RLE: 044 Pixels @ 125,054*/ 44, 0x00, + /* ABS: 011 Pixels @ 169,054*/ 0, 11, 0x03, 0x0E, 0x11, 0x0C, 0x0B, 0x03, 0x03, 0x03, 0x11, 0x08, 0x04, + /* RLE: 004 Pixels @ 180,054*/ 4, 0x03, + /* RLE: 001 Pixels @ 184,054*/ 1, 0x04, + /* RLE: 036 Pixels @ 185,054*/ 36, 0x00, + /* ABS: 005 Pixels @ 221,054*/ 0, 5, 0x06, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 038 Pixels @ 226,054*/ 38, 0x01, + /* ABS: 002 Pixels @ 264,054*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 266,054*/ 9, 0x03, + /* ABS: 002 Pixels @ 275,054*/ 0, 2, 0x04, 0x04, + /* RLE: 123 Pixels @ 277,054*/ 123, 0x01, + /* RLE: 021 Pixels @ 000,055*/ 21, 0x02, + /* RLE: 001 Pixels @ 021,055*/ 1, 0x04, + /* RLE: 007 Pixels @ 022,055*/ 7, 0x03, + /* RLE: 085 Pixels @ 029,055*/ 85, 0x01, + /* ABS: 002 Pixels @ 114,055*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 116,055*/ 8, 0x03, + /* ABS: 002 Pixels @ 124,055*/ 0, 2, 0x04, 0x04, + /* RLE: 039 Pixels @ 126,055*/ 39, 0x00, + /* ABS: 014 Pixels @ 165,055*/ 0, 14, 0x03, 0x03, 0x00, 0x03, 0x03, 0x08, 0x0C, 0x0E, 0x11, 0x08, 0x0E, 0x03, 0x03, 0x00, + /* RLE: 006 Pixels @ 179,055*/ 6, 0x03, + /* RLE: 038 Pixels @ 185,055*/ 38, 0x00, + /* ABS: 004 Pixels @ 223,055*/ 0, 4, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 038 Pixels @ 227,055*/ 38, 0x01, + /* ABS: 002 Pixels @ 265,055*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 267,055*/ 9, 0x03, + /* ABS: 002 Pixels @ 276,055*/ 0, 2, 0x04, 0x04, + /* RLE: 122 Pixels @ 278,055*/ 122, 0x01, + /* RLE: 022 Pixels @ 000,056*/ 22, 0x02, + /* RLE: 001 Pixels @ 022,056*/ 1, 0x04, + /* RLE: 006 Pixels @ 023,056*/ 6, 0x03, + /* RLE: 001 Pixels @ 029,056*/ 1, 0x04, + /* RLE: 085 Pixels @ 030,056*/ 85, 0x01, + /* ABS: 002 Pixels @ 115,056*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 117,056*/ 8, 0x03, + /* ABS: 002 Pixels @ 125,056*/ 0, 2, 0x04, 0x04, + /* RLE: 037 Pixels @ 127,056*/ 37, 0x00, + /* ABS: 012 Pixels @ 164,056*/ 0, 12, 0x03, 0x00, 0x0F, 0x08, 0x0E, 0x03, 0x0E, 0x08, 0x0F, 0x0E, 0x06, 0x11, + /* RLE: 009 Pixels @ 176,056*/ 9, 0x03, + /* RLE: 001 Pixels @ 185,056*/ 1, 0x04, + /* RLE: 038 Pixels @ 186,056*/ 38, 0x00, + /* ABS: 004 Pixels @ 224,056*/ 0, 4, 0x0D, 0x06, 0x03, 0x0D, + /* RLE: 038 Pixels @ 228,056*/ 38, 0x01, + /* ABS: 002 Pixels @ 266,056*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 268,056*/ 9, 0x03, + /* ABS: 002 Pixels @ 277,056*/ 0, 2, 0x04, 0x04, + /* RLE: 121 Pixels @ 279,056*/ 121, 0x01, + /* RLE: 022 Pixels @ 000,057*/ 22, 0x02, + /* RLE: 001 Pixels @ 022,057*/ 1, 0x04, + /* RLE: 006 Pixels @ 023,057*/ 6, 0x03, + /* RLE: 001 Pixels @ 029,057*/ 1, 0x04, + /* RLE: 086 Pixels @ 030,057*/ 86, 0x01, + /* ABS: 002 Pixels @ 116,057*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 118,057*/ 8, 0x03, + /* ABS: 002 Pixels @ 126,057*/ 0, 2, 0x04, 0x04, + /* RLE: 034 Pixels @ 128,057*/ 34, 0x00, + /* ABS: 016 Pixels @ 162,057*/ 0, 16, 0x04, 0x03, 0x0E, 0x06, 0x0C, 0x0C, 0x08, 0x04, 0x03, 0x03, 0x00, 0x00, 0x0D, 0x0E, 0x03, 0x04, + /* RLE: 007 Pixels @ 178,057*/ 7, 0x03, + /* RLE: 001 Pixels @ 185,057*/ 1, 0x04, + /* RLE: 039 Pixels @ 186,057*/ 39, 0x00, + /* ABS: 004 Pixels @ 225,057*/ 0, 4, 0x0D, 0x06, 0x03, 0x06, + /* RLE: 038 Pixels @ 229,057*/ 38, 0x01, + /* ABS: 002 Pixels @ 267,057*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 269,057*/ 9, 0x03, + /* ABS: 002 Pixels @ 278,057*/ 0, 2, 0x04, 0x04, + /* RLE: 120 Pixels @ 280,057*/ 120, 0x01, + /* RLE: 022 Pixels @ 000,058*/ 22, 0x02, + /* RLE: 001 Pixels @ 022,058*/ 1, 0x04, + /* RLE: 007 Pixels @ 023,058*/ 7, 0x03, + /* RLE: 001 Pixels @ 030,058*/ 1, 0x00, + /* RLE: 086 Pixels @ 031,058*/ 86, 0x01, + /* ABS: 002 Pixels @ 117,058*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 119,058*/ 8, 0x03, + /* ABS: 002 Pixels @ 127,058*/ 0, 2, 0x04, 0x04, + /* RLE: 031 Pixels @ 129,058*/ 31, 0x00, + /* RLE: 004 Pixels @ 160,058*/ 4, 0x03, + /* ABS: 015 Pixels @ 164,058*/ 0, 15, 0x11, 0x08, 0x03, 0x03, 0x06, 0x0F, 0x03, 0x0C, 0x08, 0x08, 0x0E, 0x03, 0x03, 0x00, 0x04, + /* RLE: 007 Pixels @ 179,058*/ 7, 0x03, + /* RLE: 040 Pixels @ 186,058*/ 40, 0x00, + /* ABS: 004 Pixels @ 226,058*/ 0, 4, 0x0D, 0x06, 0x03, 0x06, + /* RLE: 038 Pixels @ 230,058*/ 38, 0x01, + /* ABS: 002 Pixels @ 268,058*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 270,058*/ 9, 0x03, + /* ABS: 002 Pixels @ 279,058*/ 0, 2, 0x04, 0x04, + /* RLE: 119 Pixels @ 281,058*/ 119, 0x01, + /* RLE: 021 Pixels @ 000,059*/ 21, 0x02, + /* RLE: 001 Pixels @ 021,059*/ 1, 0x18, + /* RLE: 005 Pixels @ 022,059*/ 5, 0x03, + /* ABS: 005 Pixels @ 027,059*/ 0, 5, 0x00, 0x04, 0x0E, 0x03, 0x18, + /* RLE: 086 Pixels @ 032,059*/ 86, 0x01, + /* ABS: 002 Pixels @ 118,059*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 120,059*/ 9, 0x03, + /* ABS: 002 Pixels @ 129,059*/ 0, 2, 0x04, 0x04, + /* RLE: 028 Pixels @ 131,059*/ 28, 0x00, + /* ABS: 012 Pixels @ 159,059*/ 0, 12, 0x03, 0x0B, 0x06, 0x0E, 0x00, 0x0B, 0x08, 0x0C, 0x03, 0x00, 0x0F, 0x0E, + /* RLE: 005 Pixels @ 171,059*/ 5, 0x03, + /* RLE: 003 Pixels @ 176,059*/ 3, 0x00, + /* RLE: 001 Pixels @ 179,059*/ 1, 0x04, + /* RLE: 006 Pixels @ 180,059*/ 6, 0x03, + /* RLE: 001 Pixels @ 186,059*/ 1, 0x04, + /* RLE: 040 Pixels @ 187,059*/ 40, 0x00, + /* RLE: 001 Pixels @ 227,059*/ 1, 0x0D, + /* RLE: 004 Pixels @ 228,059*/ 4, 0x06, + /* RLE: 037 Pixels @ 232,059*/ 37, 0x01, + /* RLE: 003 Pixels @ 269,059*/ 3, 0x04, + /* RLE: 008 Pixels @ 272,059*/ 8, 0x03, + /* RLE: 003 Pixels @ 280,059*/ 3, 0x04, + /* RLE: 117 Pixels @ 283,059*/ 117, 0x01, + /* RLE: 021 Pixels @ 000,060*/ 21, 0x02, + /* ABS: 005 Pixels @ 021,060*/ 0, 5, 0x03, 0x00, 0x0C, 0x12, 0x0D, + /* RLE: 004 Pixels @ 026,060*/ 4, 0x08, + /* ABS: 002 Pixels @ 030,060*/ 0, 2, 0x0B, 0x15, + /* RLE: 083 Pixels @ 032,060*/ 83, 0x01, + /* ABS: 005 Pixels @ 115,060*/ 0, 5, 0x15, 0x03, 0x00, 0x18, 0x00, + /* RLE: 010 Pixels @ 120,060*/ 10, 0x03, + /* ABS: 002 Pixels @ 130,060*/ 0, 2, 0x04, 0x04, + /* RLE: 026 Pixels @ 132,060*/ 26, 0x00, + /* ABS: 015 Pixels @ 158,060*/ 0, 15, 0x03, 0x04, 0x0F, 0x0C, 0x0D, 0x0F, 0x03, 0x12, 0x0F, 0x00, 0x03, 0x04, 0x00, 0x03, 0x04, + /* RLE: 005 Pixels @ 173,060*/ 5, 0x00, + /* ABS: 002 Pixels @ 178,060*/ 0, 2, 0x0B, 0x04, + /* RLE: 006 Pixels @ 180,060*/ 6, 0x03, + /* RLE: 001 Pixels @ 186,060*/ 1, 0x04, + /* RLE: 041 Pixels @ 187,060*/ 41, 0x00, + /* RLE: 001 Pixels @ 228,060*/ 1, 0x0D, + /* RLE: 004 Pixels @ 229,060*/ 4, 0x06, + /* RLE: 038 Pixels @ 233,060*/ 38, 0x01, + /* ABS: 002 Pixels @ 271,060*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 273,060*/ 9, 0x03, + /* ABS: 002 Pixels @ 282,060*/ 0, 2, 0x04, 0x04, + /* RLE: 116 Pixels @ 284,060*/ 116, 0x01, + /* RLE: 021 Pixels @ 000,061*/ 21, 0x02, + /* ABS: 011 Pixels @ 021,061*/ 0, 11, 0x03, 0x06, 0x08, 0x08, 0x06, 0x0E, 0x04, 0x0B, 0x03, 0x03, 0x15, + /* RLE: 083 Pixels @ 032,061*/ 83, 0x01, + /* ABS: 007 Pixels @ 115,061*/ 0, 7, 0x03, 0x0B, 0x04, 0x03, 0x03, 0x0C, 0x0B, + /* RLE: 009 Pixels @ 122,061*/ 9, 0x03, + /* ABS: 002 Pixels @ 131,061*/ 0, 2, 0x04, 0x04, + /* RLE: 023 Pixels @ 133,061*/ 23, 0x00, + /* ABS: 014 Pixels @ 156,061*/ 0, 14, 0x04, 0x04, 0x03, 0x06, 0x0E, 0x00, 0x06, 0x12, 0x00, 0x00, 0x0F, 0x12, 0x03, 0x03, + /* RLE: 009 Pixels @ 170,061*/ 9, 0x00, + /* RLE: 001 Pixels @ 179,061*/ 1, 0x04, + /* RLE: 007 Pixels @ 180,061*/ 7, 0x03, + /* RLE: 042 Pixels @ 187,061*/ 42, 0x00, + /* RLE: 001 Pixels @ 229,061*/ 1, 0x0D, + /* RLE: 004 Pixels @ 230,061*/ 4, 0x06, + /* RLE: 038 Pixels @ 234,061*/ 38, 0x01, + /* ABS: 002 Pixels @ 272,061*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 274,061*/ 9, 0x03, + /* ABS: 002 Pixels @ 283,061*/ 0, 2, 0x04, 0x04, + /* RLE: 115 Pixels @ 285,061*/ 115, 0x01, + /* RLE: 021 Pixels @ 000,062*/ 21, 0x02, + /* ABS: 010 Pixels @ 021,062*/ 0, 10, 0x03, 0x00, 0x00, 0x03, 0x03, 0x03, 0x00, 0x00, 0x03, 0x04, + /* RLE: 084 Pixels @ 031,062*/ 84, 0x01, + /* ABS: 007 Pixels @ 115,062*/ 0, 7, 0x03, 0x06, 0x0F, 0x00, 0x00, 0x08, 0x0B, + /* RLE: 010 Pixels @ 122,062*/ 10, 0x03, + /* ABS: 002 Pixels @ 132,062*/ 0, 2, 0x04, 0x04, + /* RLE: 016 Pixels @ 134,062*/ 16, 0x00, + /* RLE: 001 Pixels @ 150,062*/ 1, 0x03, + /* RLE: 004 Pixels @ 151,062*/ 4, 0x00, + /* RLE: 004 Pixels @ 155,062*/ 4, 0x03, + /* ABS: 011 Pixels @ 159,062*/ 0, 11, 0x0E, 0x0F, 0x11, 0x0B, 0x04, 0x06, 0x03, 0x0B, 0x00, 0x03, 0x04, + /* RLE: 010 Pixels @ 170,062*/ 10, 0x00, + /* RLE: 001 Pixels @ 180,062*/ 1, 0x04, + /* RLE: 006 Pixels @ 181,062*/ 6, 0x03, + /* RLE: 001 Pixels @ 187,062*/ 1, 0x04, + /* RLE: 043 Pixels @ 188,062*/ 43, 0x00, + /* ABS: 004 Pixels @ 231,062*/ 0, 4, 0x0D, 0x03, 0x06, 0x0D, + /* RLE: 038 Pixels @ 235,062*/ 38, 0x01, + /* ABS: 002 Pixels @ 273,062*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 275,062*/ 9, 0x03, + /* ABS: 002 Pixels @ 284,062*/ 0, 2, 0x04, 0x04, + /* RLE: 114 Pixels @ 286,062*/ 114, 0x01, + /* RLE: 021 Pixels @ 000,063*/ 21, 0x02, + /* ABS: 010 Pixels @ 021,063*/ 0, 10, 0x18, 0x03, 0x04, 0x0E, 0x06, 0x0F, 0x08, 0x08, 0x03, 0x04, + /* RLE: 084 Pixels @ 031,063*/ 84, 0x01, + /* ABS: 007 Pixels @ 115,063*/ 0, 7, 0x03, 0x00, 0x0F, 0x0D, 0x00, 0x08, 0x00, + /* RLE: 011 Pixels @ 122,063*/ 11, 0x03, + /* ABS: 002 Pixels @ 133,063*/ 0, 2, 0x04, 0x04, + /* RLE: 014 Pixels @ 135,063*/ 14, 0x00, + /* ABS: 017 Pixels @ 149,063*/ 0, 17, 0x03, 0x0C, 0x03, 0x00, 0x00, 0x03, 0x0B, 0x06, 0x12, 0x03, 0x00, 0x08, 0x12, 0x0B, 0x06, 0x0E, 0x03, + /* RLE: 014 Pixels @ 166,063*/ 14, 0x00, + /* RLE: 001 Pixels @ 180,063*/ 1, 0x04, + /* RLE: 006 Pixels @ 181,063*/ 6, 0x03, + /* RLE: 001 Pixels @ 187,063*/ 1, 0x04, + /* RLE: 044 Pixels @ 188,063*/ 44, 0x00, + /* ABS: 004 Pixels @ 232,063*/ 0, 4, 0x0D, 0x03, 0x03, 0x06, + /* RLE: 038 Pixels @ 236,063*/ 38, 0x01, + /* ABS: 002 Pixels @ 274,063*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 276,063*/ 9, 0x03, + /* ABS: 002 Pixels @ 285,063*/ 0, 2, 0x04, 0x04, + /* RLE: 113 Pixels @ 287,063*/ 113, 0x01, + /* RLE: 022 Pixels @ 000,064*/ 22, 0x02, + /* ABS: 009 Pixels @ 022,064*/ 0, 9, 0x03, 0x06, 0x08, 0x06, 0x0E, 0x0E, 0x0D, 0x03, 0x00, + /* RLE: 084 Pixels @ 031,064*/ 84, 0x01, + /* ABS: 009 Pixels @ 115,064*/ 0, 9, 0x00, 0x03, 0x0B, 0x08, 0x0D, 0x08, 0x08, 0x0E, 0x00, + /* RLE: 010 Pixels @ 124,064*/ 10, 0x03, + /* ABS: 002 Pixels @ 134,064*/ 0, 2, 0x04, 0x04, + /* RLE: 013 Pixels @ 136,064*/ 13, 0x00, + /* ABS: 018 Pixels @ 149,064*/ 0, 18, 0x0B, 0x08, 0x0C, 0x03, 0x03, 0x0E, 0x11, 0x0C, 0x0B, 0x03, 0x03, 0x0B, 0x11, 0x0F, 0x0E, 0x03, 0x00, 0x04, + /* RLE: 012 Pixels @ 167,064*/ 12, 0x00, + /* ABS: 002 Pixels @ 179,064*/ 0, 2, 0x0B, 0x04, + /* RLE: 007 Pixels @ 181,064*/ 7, 0x03, + /* RLE: 045 Pixels @ 188,064*/ 45, 0x00, + /* ABS: 004 Pixels @ 233,064*/ 0, 4, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 038 Pixels @ 237,064*/ 38, 0x01, + /* ABS: 002 Pixels @ 275,064*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 277,064*/ 9, 0x03, + /* ABS: 002 Pixels @ 286,064*/ 0, 2, 0x04, 0x04, + /* RLE: 112 Pixels @ 288,064*/ 112, 0x01, + /* RLE: 022 Pixels @ 000,065*/ 22, 0x02, + /* RLE: 006 Pixels @ 022,065*/ 6, 0x03, + /* ABS: 003 Pixels @ 028,065*/ 0, 3, 0x06, 0x0C, 0x03, + /* RLE: 082 Pixels @ 031,065*/ 82, 0x01, + /* ABS: 014 Pixels @ 113,065*/ 0, 14, 0x15, 0x03, 0x03, 0x0B, 0x00, 0x0E, 0x08, 0x0D, 0x0C, 0x11, 0x08, 0x0E, 0x03, 0x04, + /* RLE: 008 Pixels @ 127,065*/ 8, 0x03, + /* ABS: 002 Pixels @ 135,065*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 137,065*/ 8, 0x00, + /* RLE: 005 Pixels @ 145,065*/ 5, 0x03, + /* ABS: 010 Pixels @ 150,065*/ 0, 10, 0x0E, 0x08, 0x00, 0x03, 0x08, 0x0C, 0x0E, 0x11, 0x08, 0x0E, + /* RLE: 005 Pixels @ 160,065*/ 5, 0x03, + /* RLE: 016 Pixels @ 165,065*/ 16, 0x00, + /* RLE: 001 Pixels @ 181,065*/ 1, 0x04, + /* RLE: 006 Pixels @ 182,065*/ 6, 0x03, + /* RLE: 001 Pixels @ 188,065*/ 1, 0x04, + /* RLE: 045 Pixels @ 189,065*/ 45, 0x00, + /* RLE: 001 Pixels @ 234,065*/ 1, 0x0D, + /* RLE: 004 Pixels @ 235,065*/ 4, 0x06, + /* RLE: 038 Pixels @ 239,065*/ 38, 0x01, + /* ABS: 002 Pixels @ 277,065*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 279,065*/ 8, 0x03, + /* ABS: 002 Pixels @ 287,065*/ 0, 2, 0x04, 0x04, + /* RLE: 111 Pixels @ 289,065*/ 111, 0x01, + /* RLE: 022 Pixels @ 000,066*/ 22, 0x02, + /* ABS: 009 Pixels @ 022,066*/ 0, 9, 0x00, 0x03, 0x03, 0x0B, 0x04, 0x0E, 0x0F, 0x0C, 0x03, + /* RLE: 081 Pixels @ 031,066*/ 81, 0x01, + /* ABS: 016 Pixels @ 112,066*/ 0, 16, 0x04, 0x03, 0x00, 0x0D, 0x08, 0x0F, 0x03, 0x0D, 0x0F, 0x03, 0x03, 0x0B, 0x03, 0x00, 0x04, 0x04, + /* RLE: 008 Pixels @ 128,066*/ 8, 0x03, + /* ABS: 002 Pixels @ 136,066*/ 0, 2, 0x04, 0x04, + /* RLE: 006 Pixels @ 138,066*/ 6, 0x00, + /* ABS: 020 Pixels @ 144,066*/ 0, 20, 0x03, 0x03, 0x0D, 0x00, 0x03, 0x03, 0x03, 0x11, 0x06, 0x03, 0x0E, 0x08, 0x0F, 0x0E, 0x06, 0x11, 0x03, 0x04, 0x04, 0x04, + /* RLE: 017 Pixels @ 164,066*/ 17, 0x00, + /* RLE: 001 Pixels @ 181,066*/ 1, 0x04, + /* RLE: 006 Pixels @ 182,066*/ 6, 0x03, + /* RLE: 001 Pixels @ 188,066*/ 1, 0x04, + /* RLE: 046 Pixels @ 189,066*/ 46, 0x00, + /* RLE: 001 Pixels @ 235,066*/ 1, 0x0D, + /* RLE: 004 Pixels @ 236,066*/ 4, 0x06, + /* RLE: 038 Pixels @ 240,066*/ 38, 0x01, + /* ABS: 002 Pixels @ 278,066*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 280,066*/ 9, 0x03, + /* ABS: 002 Pixels @ 289,066*/ 0, 2, 0x04, 0x04, + /* RLE: 109 Pixels @ 291,066*/ 109, 0x01, + /* RLE: 022 Pixels @ 000,067*/ 22, 0x02, + /* ABS: 002 Pixels @ 022,067*/ 0, 2, 0x00, 0x0B, + /* RLE: 005 Pixels @ 024,067*/ 5, 0x08, + /* ABS: 003 Pixels @ 029,067*/ 0, 3, 0x00, 0x03, 0x04, + /* RLE: 077 Pixels @ 032,067*/ 77, 0x01, + /* ABS: 014 Pixels @ 109,067*/ 0, 14, 0x15, 0x00, 0x00, 0x00, 0x03, 0x06, 0x12, 0x03, 0x00, 0x03, 0x00, 0x08, 0x0E, 0x03, + /* RLE: 004 Pixels @ 123,067*/ 4, 0x00, + /* ABS: 002 Pixels @ 127,067*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 129,067*/ 8, 0x03, + /* ABS: 002 Pixels @ 137,067*/ 0, 2, 0x04, 0x04, + /* RLE: 004 Pixels @ 139,067*/ 4, 0x00, + /* ABS: 020 Pixels @ 143,067*/ 0, 20, 0x03, 0x0E, 0x00, 0x0C, 0x03, 0x0C, 0x00, 0x03, 0x0B, 0x08, 0x0C, 0x03, 0x03, 0x00, 0x00, 0x0D, 0x0E, 0x03, 0x04, 0x0B, + /* RLE: 018 Pixels @ 163,067*/ 18, 0x00, + /* RLE: 001 Pixels @ 181,067*/ 1, 0x04, + /* RLE: 007 Pixels @ 182,067*/ 7, 0x03, + /* RLE: 047 Pixels @ 189,067*/ 47, 0x00, + /* ABS: 005 Pixels @ 236,067*/ 0, 5, 0x0D, 0x06, 0x03, 0x06, 0x06, + /* RLE: 038 Pixels @ 241,067*/ 38, 0x01, + /* ABS: 002 Pixels @ 279,067*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 281,067*/ 9, 0x03, + /* ABS: 002 Pixels @ 290,067*/ 0, 2, 0x04, 0x04, + /* RLE: 108 Pixels @ 292,067*/ 108, 0x01, + /* RLE: 022 Pixels @ 000,068*/ 22, 0x02, + /* ABS: 010 Pixels @ 022,068*/ 0, 10, 0x18, 0x03, 0x0C, 0x04, 0x0B, 0x03, 0x0C, 0x0D, 0x03, 0x00, + /* RLE: 075 Pixels @ 032,068*/ 75, 0x01, + /* ABS: 017 Pixels @ 107,068*/ 0, 17, 0x15, 0x03, 0x03, 0x0B, 0x00, 0x03, 0x03, 0x08, 0x0C, 0x03, 0x03, 0x0C, 0x06, 0x0B, 0x03, 0x03, 0x04, + /* RLE: 004 Pixels @ 124,068*/ 4, 0x00, + /* ABS: 002 Pixels @ 128,068*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 130,068*/ 8, 0x03, + /* ABS: 022 Pixels @ 138,068*/ 0, 22, 0x04, 0x04, 0x00, 0x03, 0x03, 0x03, 0x0E, 0x00, 0x03, 0x03, 0x0F, 0x12, 0x03, 0x03, 0x12, 0x0F, 0x03, 0x0C, 0x08, 0x08, 0x0E, 0x03, + /* RLE: 021 Pixels @ 160,068*/ 21, 0x00, + /* ABS: 002 Pixels @ 181,068*/ 0, 2, 0x0B, 0x04, + /* RLE: 006 Pixels @ 183,068*/ 6, 0x03, + /* RLE: 001 Pixels @ 189,068*/ 1, 0x04, + /* RLE: 048 Pixels @ 190,068*/ 48, 0x00, + /* ABS: 004 Pixels @ 238,068*/ 0, 4, 0x0D, 0x03, 0x06, 0x0D, + /* RLE: 038 Pixels @ 242,068*/ 38, 0x01, + /* ABS: 002 Pixels @ 280,068*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 282,068*/ 9, 0x03, + /* ABS: 002 Pixels @ 291,068*/ 0, 2, 0x04, 0x04, + /* RLE: 107 Pixels @ 293,068*/ 107, 0x01, + /* RLE: 023 Pixels @ 000,069*/ 23, 0x02, + /* RLE: 005 Pixels @ 023,069*/ 5, 0x03, + /* ABS: 004 Pixels @ 028,069*/ 0, 4, 0x04, 0x08, 0x00, 0x00, + /* RLE: 071 Pixels @ 032,069*/ 71, 0x01, + /* ABS: 020 Pixels @ 103,069*/ 0, 20, 0x15, 0x00, 0x00, 0x15, 0x03, 0x00, 0x0D, 0x08, 0x08, 0x0F, 0x00, 0x0D, 0x0F, 0x03, 0x03, 0x0E, 0x11, 0x03, 0x00, 0x04, + /* RLE: 006 Pixels @ 123,069*/ 6, 0x00, + /* ABS: 002 Pixels @ 129,069*/ 0, 2, 0x04, 0x04, + /* RLE: 010 Pixels @ 131,069*/ 10, 0x03, + /* ABS: 014 Pixels @ 141,069*/ 0, 14, 0x00, 0x0F, 0x00, 0x03, 0x0E, 0x00, 0x03, 0x0C, 0x08, 0x0B, 0x03, 0x00, 0x0F, 0x12, + /* RLE: 005 Pixels @ 155,069*/ 5, 0x03, + /* RLE: 022 Pixels @ 160,069*/ 22, 0x00, + /* RLE: 001 Pixels @ 182,069*/ 1, 0x04, + /* RLE: 006 Pixels @ 183,069*/ 6, 0x03, + /* RLE: 001 Pixels @ 189,069*/ 1, 0x04, + /* RLE: 049 Pixels @ 190,069*/ 49, 0x00, + /* ABS: 004 Pixels @ 239,069*/ 0, 4, 0x0D, 0x03, 0x06, 0x06, + /* RLE: 038 Pixels @ 243,069*/ 38, 0x01, + /* ABS: 002 Pixels @ 281,069*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 283,069*/ 9, 0x03, + /* RLE: 001 Pixels @ 292,069*/ 1, 0x04, + /* RLE: 105 Pixels @ 293,069*/ 105, 0x01, + /* ABS: 002 Pixels @ 398,069*/ 0, 2, 0x15, 0x00, + /* RLE: 023 Pixels @ 000,070*/ 23, 0x02, + /* ABS: 009 Pixels @ 023,070*/ 0, 9, 0x03, 0x04, 0x0E, 0x0D, 0x08, 0x08, 0x0F, 0x03, 0x00, + /* RLE: 071 Pixels @ 032,070*/ 71, 0x01, + /* ABS: 018 Pixels @ 103,070*/ 0, 18, 0x03, 0x00, 0x0B, 0x03, 0x03, 0x12, 0x0D, 0x03, 0x00, 0x0F, 0x0D, 0x0B, 0x08, 0x11, 0x0E, 0x08, 0x04, 0x03, + /* RLE: 009 Pixels @ 121,070*/ 9, 0x00, + /* ABS: 002 Pixels @ 130,070*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 132,070*/ 9, 0x03, + /* ABS: 016 Pixels @ 141,070*/ 0, 16, 0x00, 0x0F, 0x06, 0x03, 0x0F, 0x06, 0x03, 0x03, 0x06, 0x0F, 0x03, 0x03, 0x0B, 0x00, 0x03, 0x04, + /* RLE: 024 Pixels @ 157,070*/ 24, 0x00, + /* ABS: 002 Pixels @ 181,070*/ 0, 2, 0x0B, 0x04, + /* RLE: 006 Pixels @ 183,070*/ 6, 0x03, + /* RLE: 001 Pixels @ 189,070*/ 1, 0x04, + /* RLE: 050 Pixels @ 190,070*/ 50, 0x00, + /* ABS: 004 Pixels @ 240,070*/ 0, 4, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 038 Pixels @ 244,070*/ 38, 0x01, + /* ABS: 002 Pixels @ 282,070*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 284,070*/ 9, 0x03, + /* RLE: 105 Pixels @ 293,070*/ 105, 0x01, + /* ABS: 002 Pixels @ 398,070*/ 0, 2, 0x03, 0x00, + /* RLE: 023 Pixels @ 000,071*/ 23, 0x02, + /* ABS: 009 Pixels @ 023,071*/ 0, 9, 0x03, 0x0C, 0x0F, 0x06, 0x0C, 0x04, 0x03, 0x03, 0x04, + /* RLE: 071 Pixels @ 032,071*/ 71, 0x01, + /* ABS: 017 Pixels @ 103,071*/ 0, 17, 0x03, 0x0F, 0x0F, 0x03, 0x03, 0x08, 0x0C, 0x03, 0x03, 0x0C, 0x08, 0x03, 0x0B, 0x12, 0x06, 0x0B, 0x03, + /* RLE: 011 Pixels @ 120,071*/ 11, 0x00, + /* ABS: 002 Pixels @ 131,071*/ 0, 2, 0x04, 0x04, + /* RLE: 005 Pixels @ 133,071*/ 5, 0x03, + /* ABS: 018 Pixels @ 138,071*/ 0, 18, 0x0C, 0x03, 0x03, 0x03, 0x04, 0x08, 0x04, 0x0B, 0x08, 0x0C, 0x03, 0x04, 0x08, 0x0E, 0x03, 0x03, 0x00, 0x0B, + /* RLE: 027 Pixels @ 156,071*/ 27, 0x00, + /* RLE: 007 Pixels @ 183,071*/ 7, 0x03, + /* RLE: 001 Pixels @ 190,071*/ 1, 0x04, + /* RLE: 050 Pixels @ 191,071*/ 50, 0x00, + /* RLE: 001 Pixels @ 241,071*/ 1, 0x0D, + /* RLE: 004 Pixels @ 242,071*/ 4, 0x06, + /* RLE: 037 Pixels @ 246,071*/ 37, 0x01, + /* ABS: 002 Pixels @ 283,071*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 285,071*/ 9, 0x03, + /* ABS: 002 Pixels @ 294,071*/ 0, 2, 0x04, 0x04, + /* RLE: 102 Pixels @ 296,071*/ 102, 0x01, + /* ABS: 002 Pixels @ 398,071*/ 0, 2, 0x03, 0x0E, + /* RLE: 023 Pixels @ 000,072*/ 23, 0x02, + /* RLE: 001 Pixels @ 023,072*/ 1, 0x00, + /* RLE: 008 Pixels @ 024,072*/ 8, 0x03, + /* RLE: 001 Pixels @ 032,072*/ 1, 0x04, + /* RLE: 066 Pixels @ 033,072*/ 66, 0x01, + /* ABS: 015 Pixels @ 099,072*/ 0, 15, 0x15, 0x03, 0x03, 0x00, 0x03, 0x0B, 0x08, 0x12, 0x03, 0x0D, 0x11, 0x03, 0x03, 0x0C, 0x0F, + /* RLE: 005 Pixels @ 114,072*/ 5, 0x03, + /* RLE: 013 Pixels @ 119,072*/ 13, 0x00, + /* ABS: 022 Pixels @ 132,072*/ 0, 22, 0x04, 0x04, 0x03, 0x03, 0x03, 0x00, 0x08, 0x0E, 0x03, 0x03, 0x0C, 0x08, 0x0F, 0x03, 0x06, 0x0F, 0x04, 0x0D, 0x0C, 0x00, 0x03, 0x04, + /* RLE: 029 Pixels @ 154,072*/ 29, 0x00, + /* RLE: 001 Pixels @ 183,072*/ 1, 0x04, + /* RLE: 006 Pixels @ 184,072*/ 6, 0x03, + /* RLE: 001 Pixels @ 190,072*/ 1, 0x04, + /* RLE: 051 Pixels @ 191,072*/ 51, 0x00, + /* ABS: 005 Pixels @ 242,072*/ 0, 5, 0x0D, 0x06, 0x03, 0x06, 0x0D, + /* RLE: 037 Pixels @ 247,072*/ 37, 0x01, + /* ABS: 002 Pixels @ 284,072*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 286,072*/ 9, 0x03, + /* ABS: 002 Pixels @ 295,072*/ 0, 2, 0x04, 0x04, + /* RLE: 100 Pixels @ 297,072*/ 100, 0x01, + /* ABS: 003 Pixels @ 397,072*/ 0, 3, 0x00, 0x03, 0x03, + /* RLE: 025 Pixels @ 000,073*/ 25, 0x02, + /* RLE: 001 Pixels @ 025,073*/ 1, 0x04, + /* RLE: 006 Pixels @ 026,073*/ 6, 0x03, + /* RLE: 001 Pixels @ 032,073*/ 1, 0x04, + /* RLE: 066 Pixels @ 033,073*/ 66, 0x01, + /* ABS: 018 Pixels @ 099,073*/ 0, 18, 0x03, 0x0B, 0x0C, 0x03, 0x03, 0x03, 0x0E, 0x08, 0x0C, 0x00, 0x08, 0x11, 0x06, 0x08, 0x0C, 0x03, 0x04, 0x04, + /* RLE: 016 Pixels @ 117,073*/ 16, 0x00, + /* ABS: 019 Pixels @ 133,073*/ 0, 19, 0x04, 0x04, 0x03, 0x03, 0x03, 0x0E, 0x08, 0x0C, 0x06, 0x0F, 0x0E, 0x08, 0x12, 0x03, 0x11, 0x08, 0x0C, 0x03, 0x03, + /* RLE: 031 Pixels @ 152,073*/ 31, 0x00, + /* RLE: 001 Pixels @ 183,073*/ 1, 0x04, + /* RLE: 006 Pixels @ 184,073*/ 6, 0x03, + /* RLE: 001 Pixels @ 190,073*/ 1, 0x04, + /* RLE: 052 Pixels @ 191,073*/ 52, 0x00, + /* ABS: 005 Pixels @ 243,073*/ 0, 5, 0x0D, 0x06, 0x03, 0x06, 0x06, + /* RLE: 037 Pixels @ 248,073*/ 37, 0x01, + /* ABS: 002 Pixels @ 285,073*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 287,073*/ 9, 0x03, + /* ABS: 002 Pixels @ 296,073*/ 0, 2, 0x04, 0x04, + /* RLE: 094 Pixels @ 298,073*/ 94, 0x01, + /* RLE: 003 Pixels @ 392,073*/ 3, 0x18, + /* ABS: 005 Pixels @ 395,073*/ 0, 5, 0x15, 0x03, 0x03, 0x06, 0x0E, + /* RLE: 025 Pixels @ 000,074*/ 25, 0x02, + /* RLE: 001 Pixels @ 025,074*/ 1, 0x04, + /* RLE: 007 Pixels @ 026,074*/ 7, 0x03, + /* RLE: 001 Pixels @ 033,074*/ 1, 0x00, + /* RLE: 065 Pixels @ 034,074*/ 65, 0x01, + /* ABS: 017 Pixels @ 099,074*/ 0, 17, 0x03, 0x12, 0x08, 0x0B, 0x03, 0x0B, 0x0F, 0x08, 0x08, 0x00, 0x0B, 0x12, 0x12, 0x0B, 0x03, 0x00, 0x04, + /* RLE: 018 Pixels @ 116,074*/ 18, 0x00, + /* ABS: 016 Pixels @ 134,074*/ 0, 16, 0x04, 0x04, 0x03, 0x03, 0x03, 0x11, 0x08, 0x06, 0x00, 0x03, 0x0C, 0x08, 0x00, 0x03, 0x03, 0x03, + /* RLE: 033 Pixels @ 150,074*/ 33, 0x00, + /* RLE: 001 Pixels @ 183,074*/ 1, 0x0B, + /* RLE: 007 Pixels @ 184,074*/ 7, 0x03, + /* RLE: 001 Pixels @ 191,074*/ 1, 0x04, + /* RLE: 053 Pixels @ 192,074*/ 53, 0x00, + /* ABS: 004 Pixels @ 245,074*/ 0, 4, 0x0D, 0x03, 0x06, 0x06, + /* RLE: 037 Pixels @ 249,074*/ 37, 0x01, + /* ABS: 002 Pixels @ 286,074*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 288,074*/ 9, 0x03, + /* ABS: 002 Pixels @ 297,074*/ 0, 2, 0x04, 0x04, + /* RLE: 093 Pixels @ 299,074*/ 93, 0x01, + /* ABS: 008 Pixels @ 392,074*/ 0, 8, 0x03, 0x04, 0x03, 0x03, 0x0B, 0x12, 0x0F, 0x0B, + /* RLE: 024 Pixels @ 000,075*/ 24, 0x02, + /* ABS: 002 Pixels @ 024,075*/ 0, 2, 0x18, 0x00, + /* RLE: 004 Pixels @ 026,075*/ 4, 0x03, + /* ABS: 005 Pixels @ 030,075*/ 0, 5, 0x00, 0x0B, 0x0C, 0x03, 0x15, + /* RLE: 064 Pixels @ 035,075*/ 64, 0x01, + /* ABS: 010 Pixels @ 099,075*/ 0, 10, 0x00, 0x03, 0x0F, 0x0F, 0x0E, 0x08, 0x0E, 0x00, 0x0F, 0x0D, + /* RLE: 004 Pixels @ 109,075*/ 4, 0x03, + /* RLE: 022 Pixels @ 113,075*/ 22, 0x00, + /* RLE: 003 Pixels @ 135,075*/ 3, 0x04, + /* ABS: 011 Pixels @ 138,075*/ 0, 11, 0x03, 0x00, 0x08, 0x0C, 0x03, 0x03, 0x03, 0x11, 0x0C, 0x03, 0x04, + /* RLE: 035 Pixels @ 149,075*/ 35, 0x00, + /* RLE: 001 Pixels @ 184,075*/ 1, 0x04, + /* RLE: 006 Pixels @ 185,075*/ 6, 0x03, + /* RLE: 001 Pixels @ 191,075*/ 1, 0x04, + /* RLE: 054 Pixels @ 192,075*/ 54, 0x00, + /* ABS: 004 Pixels @ 246,075*/ 0, 4, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 037 Pixels @ 250,075*/ 37, 0x01, + /* ABS: 002 Pixels @ 287,075*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 289,075*/ 9, 0x03, + /* ABS: 002 Pixels @ 298,075*/ 0, 2, 0x04, 0x04, + /* RLE: 092 Pixels @ 300,075*/ 92, 0x01, + /* ABS: 008 Pixels @ 392,075*/ 0, 8, 0x03, 0x0F, 0x04, 0x04, 0x00, 0x08, 0x0D, 0x03, + /* RLE: 024 Pixels @ 000,076*/ 24, 0x02, + /* ABS: 005 Pixels @ 024,076*/ 0, 5, 0x03, 0x00, 0x0C, 0x0E, 0x06, + /* RLE: 004 Pixels @ 029,076*/ 4, 0x08, + /* ABS: 002 Pixels @ 033,076*/ 0, 2, 0x0B, 0x15, + /* RLE: 064 Pixels @ 035,076*/ 64, 0x01, + /* ABS: 014 Pixels @ 099,076*/ 0, 14, 0x04, 0x03, 0x0B, 0x08, 0x08, 0x04, 0x03, 0x03, 0x04, 0x08, 0x0E, 0x03, 0x04, 0x04, + /* RLE: 026 Pixels @ 113,076*/ 26, 0x00, + /* ABS: 004 Pixels @ 139,076*/ 0, 4, 0x03, 0x12, 0x08, 0x00, + /* RLE: 004 Pixels @ 143,076*/ 4, 0x03, + /* RLE: 036 Pixels @ 147,076*/ 36, 0x00, + /* ABS: 002 Pixels @ 183,076*/ 0, 2, 0x0B, 0x04, + /* RLE: 006 Pixels @ 185,076*/ 6, 0x03, + /* RLE: 001 Pixels @ 191,076*/ 1, 0x04, + /* RLE: 055 Pixels @ 192,076*/ 55, 0x00, + /* ABS: 004 Pixels @ 247,076*/ 0, 4, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 038 Pixels @ 251,076*/ 38, 0x01, + /* ABS: 002 Pixels @ 289,076*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 291,076*/ 9, 0x03, + /* ABS: 002 Pixels @ 300,076*/ 0, 2, 0x04, 0x04, + /* RLE: 090 Pixels @ 302,076*/ 90, 0x01, + /* ABS: 008 Pixels @ 392,076*/ 0, 8, 0x03, 0x11, 0x08, 0x0D, 0x03, 0x0E, 0x08, 0x00, + /* RLE: 024 Pixels @ 000,077*/ 24, 0x02, + /* ABS: 011 Pixels @ 024,077*/ 0, 11, 0x03, 0x06, 0x08, 0x08, 0x0D, 0x08, 0x0E, 0x0B, 0x00, 0x03, 0x15, + /* RLE: 062 Pixels @ 035,077*/ 62, 0x01, + /* ABS: 015 Pixels @ 097,077*/ 0, 15, 0x04, 0x04, 0x03, 0x03, 0x03, 0x0E, 0x08, 0x0C, 0x03, 0x03, 0x03, 0x0C, 0x03, 0x00, 0x04, + /* RLE: 027 Pixels @ 112,077*/ 27, 0x00, + /* ABS: 006 Pixels @ 139,077*/ 0, 6, 0x03, 0x03, 0x0F, 0x06, 0x03, 0x0B, + /* RLE: 040 Pixels @ 145,077*/ 40, 0x00, + /* RLE: 007 Pixels @ 185,077*/ 7, 0x03, + /* RLE: 001 Pixels @ 192,077*/ 1, 0x04, + /* RLE: 055 Pixels @ 193,077*/ 55, 0x00, + /* ABS: 004 Pixels @ 248,077*/ 0, 4, 0x0D, 0x06, 0x03, 0x06, + /* RLE: 038 Pixels @ 252,077*/ 38, 0x01, + /* ABS: 002 Pixels @ 290,077*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 292,077*/ 9, 0x03, + /* ABS: 002 Pixels @ 301,077*/ 0, 2, 0x04, 0x04, + /* RLE: 050 Pixels @ 303,077*/ 50, 0x01, + /* RLE: 005 Pixels @ 353,077*/ 5, 0x04, + /* RLE: 034 Pixels @ 358,077*/ 34, 0x01, + /* ABS: 008 Pixels @ 392,077*/ 0, 8, 0x03, 0x11, 0x0F, 0x06, 0x03, 0x03, 0x0D, 0x0F, + /* RLE: 024 Pixels @ 000,078*/ 24, 0x02, + /* ABS: 010 Pixels @ 024,078*/ 0, 10, 0x03, 0x0B, 0x00, 0x03, 0x03, 0x08, 0x04, 0x03, 0x03, 0x00, + /* RLE: 060 Pixels @ 034,078*/ 60, 0x01, + /* ABS: 004 Pixels @ 094,078*/ 0, 4, 0x15, 0x00, 0x03, 0x00, + /* RLE: 005 Pixels @ 098,078*/ 5, 0x03, + /* ABS: 005 Pixels @ 103,078*/ 0, 5, 0x0D, 0x08, 0x00, 0x03, 0x03, + /* RLE: 032 Pixels @ 108,078*/ 32, 0x00, + /* ABS: 004 Pixels @ 140,078*/ 0, 4, 0x03, 0x0B, 0x00, 0x03, + /* RLE: 041 Pixels @ 144,078*/ 41, 0x00, + /* RLE: 001 Pixels @ 185,078*/ 1, 0x04, + /* RLE: 006 Pixels @ 186,078*/ 6, 0x03, + /* RLE: 001 Pixels @ 192,078*/ 1, 0x04, + /* RLE: 056 Pixels @ 193,078*/ 56, 0x00, + /* ABS: 005 Pixels @ 249,078*/ 0, 5, 0x0D, 0x06, 0x03, 0x06, 0x0D, + /* RLE: 037 Pixels @ 254,078*/ 37, 0x01, + /* ABS: 002 Pixels @ 291,078*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 293,078*/ 9, 0x03, + /* ABS: 002 Pixels @ 302,078*/ 0, 2, 0x04, 0x04, + /* RLE: 048 Pixels @ 304,078*/ 48, 0x01, + /* ABS: 002 Pixels @ 352,078*/ 0, 2, 0x04, 0x04, + /* RLE: 005 Pixels @ 354,078*/ 5, 0x03, + /* ABS: 002 Pixels @ 359,078*/ 0, 2, 0x04, 0x04, + /* RLE: 028 Pixels @ 361,078*/ 28, 0x01, + /* RLE: 005 Pixels @ 389,078*/ 5, 0x03, + /* ABS: 006 Pixels @ 394,078*/ 0, 6, 0x0C, 0x08, 0x0C, 0x03, 0x00, 0x08, + /* RLE: 024 Pixels @ 000,079*/ 24, 0x02, + /* ABS: 007 Pixels @ 024,079*/ 0, 7, 0x18, 0x03, 0x00, 0x03, 0x03, 0x0D, 0x0E, + /* RLE: 004 Pixels @ 031,079*/ 4, 0x03, + /* RLE: 058 Pixels @ 035,079*/ 58, 0x01, + /* ABS: 005 Pixels @ 093,079*/ 0, 5, 0x15, 0x03, 0x00, 0x04, 0x00, + /* RLE: 005 Pixels @ 098,079*/ 5, 0x03, + /* ABS: 006 Pixels @ 103,079*/ 0, 6, 0x00, 0x0F, 0x12, 0x03, 0x04, 0x04, + /* RLE: 032 Pixels @ 109,079*/ 32, 0x00, + /* ABS: 002 Pixels @ 141,079*/ 0, 2, 0x03, 0x03, + /* RLE: 006 Pixels @ 143,079*/ 6, 0x00, + /* RLE: 001 Pixels @ 149,079*/ 1, 0x08, + /* RLE: 035 Pixels @ 150,079*/ 35, 0x00, + /* RLE: 001 Pixels @ 185,079*/ 1, 0x04, + /* RLE: 006 Pixels @ 186,079*/ 6, 0x03, + /* RLE: 001 Pixels @ 192,079*/ 1, 0x04, + /* RLE: 057 Pixels @ 193,079*/ 57, 0x00, + /* ABS: 005 Pixels @ 250,079*/ 0, 5, 0x0D, 0x06, 0x03, 0x06, 0x06, + /* RLE: 037 Pixels @ 255,079*/ 37, 0x01, + /* ABS: 002 Pixels @ 292,079*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 294,079*/ 9, 0x03, + /* ABS: 002 Pixels @ 303,079*/ 0, 2, 0x04, 0x04, + /* RLE: 047 Pixels @ 305,079*/ 47, 0x01, + /* RLE: 001 Pixels @ 352,079*/ 1, 0x04, + /* RLE: 009 Pixels @ 353,079*/ 9, 0x03, + /* ABS: 002 Pixels @ 362,079*/ 0, 2, 0x04, 0x04, + /* RLE: 024 Pixels @ 364,079*/ 24, 0x01, + /* ABS: 012 Pixels @ 388,079*/ 0, 12, 0x03, 0x03, 0x06, 0x08, 0x12, 0x03, 0x03, 0x12, 0x08, 0x0E, 0x0C, 0x0B, + /* RLE: 025 Pixels @ 000,080*/ 25, 0x02, + /* ABS: 010 Pixels @ 025,080*/ 0, 10, 0x00, 0x03, 0x03, 0x03, 0x12, 0x0D, 0x0C, 0x12, 0x0D, 0x03, + /* RLE: 057 Pixels @ 035,080*/ 57, 0x01, + /* ABS: 007 Pixels @ 092,080*/ 0, 7, 0x18, 0x03, 0x00, 0x0F, 0x08, 0x0F, 0x00, + /* RLE: 005 Pixels @ 099,080*/ 5, 0x03, + /* ABS: 003 Pixels @ 104,080*/ 0, 3, 0x0B, 0x03, 0x03, + /* RLE: 042 Pixels @ 107,080*/ 42, 0x00, + /* RLE: 001 Pixels @ 149,080*/ 1, 0x08, + /* RLE: 035 Pixels @ 150,080*/ 35, 0x00, + /* RLE: 001 Pixels @ 185,080*/ 1, 0x0B, + /* RLE: 007 Pixels @ 186,080*/ 7, 0x03, + /* RLE: 001 Pixels @ 193,080*/ 1, 0x04, + /* RLE: 057 Pixels @ 194,080*/ 57, 0x00, + /* ABS: 005 Pixels @ 251,080*/ 0, 5, 0x06, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 037 Pixels @ 256,080*/ 37, 0x01, + /* ABS: 002 Pixels @ 293,080*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 295,080*/ 9, 0x03, + /* ABS: 002 Pixels @ 304,080*/ 0, 2, 0x04, 0x04, + /* RLE: 046 Pixels @ 306,080*/ 46, 0x01, + /* RLE: 001 Pixels @ 352,080*/ 1, 0x04, + /* RLE: 012 Pixels @ 353,080*/ 12, 0x03, + /* ABS: 002 Pixels @ 365,080*/ 0, 2, 0x04, 0x04, + /* RLE: 020 Pixels @ 367,080*/ 20, 0x01, + /* ABS: 013 Pixels @ 387,080*/ 0, 13, 0x15, 0x03, 0x11, 0x0E, 0x0B, 0x00, 0x00, 0x03, 0x03, 0x0D, 0x0F, 0x04, 0x03, + /* RLE: 025 Pixels @ 000,081*/ 25, 0x02, + /* ABS: 004 Pixels @ 025,081*/ 0, 4, 0x03, 0x0E, 0x06, 0x0F, + /* RLE: 004 Pixels @ 029,081*/ 4, 0x08, + /* ABS: 002 Pixels @ 033,081*/ 0, 2, 0x06, 0x03, + /* RLE: 051 Pixels @ 035,081*/ 51, 0x01, + /* ABS: 013 Pixels @ 086,081*/ 0, 13, 0x15, 0x00, 0x03, 0x18, 0x01, 0x03, 0x03, 0x04, 0x0E, 0x0C, 0x00, 0x0F, 0x0D, + /* RLE: 005 Pixels @ 099,081*/ 5, 0x03, + /* RLE: 046 Pixels @ 104,081*/ 46, 0x00, + /* RLE: 001 Pixels @ 150,081*/ 1, 0x08, + /* RLE: 035 Pixels @ 151,081*/ 35, 0x00, + /* RLE: 001 Pixels @ 186,081*/ 1, 0x04, + /* RLE: 006 Pixels @ 187,081*/ 6, 0x03, + /* RLE: 001 Pixels @ 193,081*/ 1, 0x04, + /* RLE: 059 Pixels @ 194,081*/ 59, 0x00, + /* ABS: 004 Pixels @ 253,081*/ 0, 4, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 037 Pixels @ 257,081*/ 37, 0x01, + /* ABS: 002 Pixels @ 294,081*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 296,081*/ 9, 0x03, + /* ABS: 002 Pixels @ 305,081*/ 0, 2, 0x04, 0x04, + /* RLE: 045 Pixels @ 307,081*/ 45, 0x01, + /* RLE: 001 Pixels @ 352,081*/ 1, 0x04, + /* RLE: 015 Pixels @ 353,081*/ 15, 0x03, + /* ABS: 002 Pixels @ 368,081*/ 0, 2, 0x04, 0x04, + /* RLE: 010 Pixels @ 370,081*/ 10, 0x01, + /* RLE: 003 Pixels @ 380,081*/ 3, 0x15, + /* RLE: 004 Pixels @ 383,081*/ 4, 0x01, + /* ABS: 008 Pixels @ 387,081*/ 0, 8, 0x00, 0x00, 0x08, 0x0C, 0x0D, 0x08, 0x08, 0x0E, + /* RLE: 004 Pixels @ 395,081*/ 4, 0x03, + /* RLE: 001 Pixels @ 399,081*/ 1, 0x00, + /* RLE: 025 Pixels @ 000,082*/ 25, 0x02, + /* ABS: 010 Pixels @ 025,082*/ 0, 10, 0x03, 0x0D, 0x11, 0x06, 0x0C, 0x0B, 0x00, 0x03, 0x03, 0x00, + /* RLE: 051 Pixels @ 035,082*/ 51, 0x01, + /* ABS: 020 Pixels @ 086,082*/ 0, 20, 0x03, 0x00, 0x0C, 0x03, 0x03, 0x03, 0x0D, 0x08, 0x08, 0x0C, 0x03, 0x0B, 0x08, 0x0E, 0x03, 0x03, 0x04, 0x04, 0x04, 0x0B, + /* RLE: 080 Pixels @ 106,082*/ 80, 0x00, + /* RLE: 001 Pixels @ 186,082*/ 1, 0x04, + /* RLE: 006 Pixels @ 187,082*/ 6, 0x03, + /* RLE: 001 Pixels @ 193,082*/ 1, 0x04, + /* RLE: 060 Pixels @ 194,082*/ 60, 0x00, + /* ABS: 004 Pixels @ 254,082*/ 0, 4, 0x0D, 0x06, 0x03, 0x0D, + /* RLE: 037 Pixels @ 258,082*/ 37, 0x01, + /* RLE: 003 Pixels @ 295,082*/ 3, 0x04, + /* RLE: 008 Pixels @ 298,082*/ 8, 0x03, + /* RLE: 003 Pixels @ 306,082*/ 3, 0x04, + /* RLE: 043 Pixels @ 309,082*/ 43, 0x01, + /* ABS: 002 Pixels @ 352,082*/ 0, 2, 0x04, 0x04, + /* RLE: 017 Pixels @ 354,082*/ 17, 0x03, + /* ABS: 002 Pixels @ 371,082*/ 0, 2, 0x04, 0x04, + /* RLE: 006 Pixels @ 373,082*/ 6, 0x01, + /* ABS: 005 Pixels @ 379,082*/ 0, 5, 0x15, 0x03, 0x00, 0x03, 0x18, + /* RLE: 005 Pixels @ 384,082*/ 5, 0x03, + /* ABS: 011 Pixels @ 389,082*/ 0, 11, 0x0D, 0x08, 0x0D, 0x04, 0x0E, 0x06, 0x03, 0x03, 0x04, 0x04, 0x04, + /* RLE: 025 Pixels @ 000,083*/ 25, 0x02, + /* RLE: 004 Pixels @ 025,083*/ 4, 0x03, + /* RLE: 001 Pixels @ 029,083*/ 1, 0x00, + /* RLE: 004 Pixels @ 030,083*/ 4, 0x03, + /* RLE: 001 Pixels @ 034,083*/ 1, 0x04, + /* RLE: 051 Pixels @ 035,083*/ 51, 0x01, + /* ABS: 017 Pixels @ 086,083*/ 0, 17, 0x03, 0x06, 0x08, 0x00, 0x0B, 0x06, 0x12, 0x03, 0x0D, 0x0F, 0x00, 0x03, 0x0E, 0x08, 0x00, 0x00, 0x04, + /* RLE: 083 Pixels @ 103,083*/ 83, 0x00, + /* RLE: 001 Pixels @ 186,083*/ 1, 0x04, + /* RLE: 007 Pixels @ 187,083*/ 7, 0x03, + /* RLE: 061 Pixels @ 194,083*/ 61, 0x00, + /* ABS: 004 Pixels @ 255,083*/ 0, 4, 0x0D, 0x06, 0x03, 0x06, + /* RLE: 038 Pixels @ 259,083*/ 38, 0x01, + /* ABS: 002 Pixels @ 297,083*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 299,083*/ 9, 0x03, + /* ABS: 002 Pixels @ 308,083*/ 0, 2, 0x04, 0x04, + /* RLE: 043 Pixels @ 310,083*/ 43, 0x01, + /* ABS: 002 Pixels @ 353,083*/ 0, 2, 0x04, 0x04, + /* RLE: 019 Pixels @ 355,083*/ 19, 0x03, + /* ABS: 026 Pixels @ 374,083*/ 0, 26, 0x04, 0x04, 0x01, 0x01, 0x01, 0x15, 0x00, 0x0F, 0x04, 0x03, 0x03, 0x06, 0x08, 0x11, 0x00, 0x03, 0x03, 0x0B, 0x0B, 0x0F, 0x0C, 0x03, 0x04, 0x04, 0x01, 0x01, + /* RLE: 025 Pixels @ 000,084*/ 25, 0x02, + /* ABS: 010 Pixels @ 025,084*/ 0, 10, 0x00, 0x03, 0x0C, 0x0F, 0x08, 0x0F, 0x04, 0x03, 0x03, 0x04, + /* RLE: 051 Pixels @ 035,084*/ 51, 0x01, + /* ABS: 015 Pixels @ 086,084*/ 0, 15, 0x03, 0x00, 0x0F, 0x11, 0x0C, 0x08, 0x0E, 0x03, 0x00, 0x0F, 0x06, 0x03, 0x03, 0x0B, 0x03, + /* RLE: 085 Pixels @ 101,084*/ 85, 0x00, + /* ABS: 002 Pixels @ 186,084*/ 0, 2, 0x0B, 0x04, + /* RLE: 006 Pixels @ 188,084*/ 6, 0x03, + /* RLE: 001 Pixels @ 194,084*/ 1, 0x04, + /* RLE: 061 Pixels @ 195,084*/ 61, 0x00, + /* ABS: 005 Pixels @ 256,084*/ 0, 5, 0x0D, 0x06, 0x03, 0x06, 0x06, + /* RLE: 037 Pixels @ 261,084*/ 37, 0x01, + /* ABS: 002 Pixels @ 298,084*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 300,084*/ 9, 0x03, + /* ABS: 002 Pixels @ 309,084*/ 0, 2, 0x04, 0x04, + /* RLE: 044 Pixels @ 311,084*/ 44, 0x01, + /* RLE: 003 Pixels @ 355,084*/ 3, 0x04, + /* RLE: 023 Pixels @ 358,084*/ 23, 0x03, + /* ABS: 019 Pixels @ 381,084*/ 0, 19, 0x0F, 0x12, 0x03, 0x06, 0x06, 0x00, 0x0D, 0x0F, 0x03, 0x0C, 0x08, 0x0F, 0x0C, 0x03, 0x00, 0x04, 0x01, 0x01, 0x01, + /* RLE: 025 Pixels @ 000,085*/ 25, 0x02, + /* ABS: 010 Pixels @ 025,085*/ 0, 10, 0x03, 0x0B, 0x08, 0x06, 0x0C, 0x12, 0x08, 0x00, 0x03, 0x04, + /* RLE: 051 Pixels @ 035,085*/ 51, 0x01, + /* ABS: 013 Pixels @ 086,085*/ 0, 13, 0x0B, 0x03, 0x0B, 0x08, 0x12, 0x12, 0x08, 0x00, 0x03, 0x04, 0x08, 0x04, 0x03, + /* RLE: 053 Pixels @ 099,085*/ 53, 0x00, + /* RLE: 001 Pixels @ 152,085*/ 1, 0x08, + /* RLE: 034 Pixels @ 153,085*/ 34, 0x00, + /* RLE: 001 Pixels @ 187,085*/ 1, 0x04, + /* RLE: 006 Pixels @ 188,085*/ 6, 0x03, + /* RLE: 001 Pixels @ 194,085*/ 1, 0x04, + /* RLE: 062 Pixels @ 195,085*/ 62, 0x00, + /* RLE: 001 Pixels @ 257,085*/ 1, 0x0D, + /* RLE: 004 Pixels @ 258,085*/ 4, 0x06, + /* RLE: 037 Pixels @ 262,085*/ 37, 0x01, + /* ABS: 002 Pixels @ 299,085*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 301,085*/ 9, 0x03, + /* ABS: 002 Pixels @ 310,085*/ 0, 2, 0x04, 0x04, + /* RLE: 046 Pixels @ 312,085*/ 46, 0x01, + /* RLE: 003 Pixels @ 358,085*/ 3, 0x04, + /* RLE: 016 Pixels @ 361,085*/ 16, 0x03, + /* ABS: 013 Pixels @ 377,085*/ 0, 13, 0x00, 0x0D, 0x00, 0x03, 0x0C, 0x08, 0x00, 0x08, 0x04, 0x0C, 0x0F, 0x04, 0x00, + /* RLE: 004 Pixels @ 390,085*/ 4, 0x03, + /* RLE: 001 Pixels @ 394,085*/ 1, 0x00, + /* RLE: 005 Pixels @ 395,085*/ 5, 0x01, + /* RLE: 025 Pixels @ 000,086*/ 25, 0x02, + /* ABS: 010 Pixels @ 025,086*/ 0, 10, 0x03, 0x0C, 0x0D, 0x03, 0x03, 0x03, 0x0D, 0x0C, 0x03, 0x04, + /* RLE: 050 Pixels @ 035,086*/ 50, 0x01, + /* ABS: 013 Pixels @ 085,086*/ 0, 13, 0x04, 0x04, 0x03, 0x03, 0x0E, 0x08, 0x04, 0x0F, 0x11, 0x03, 0x03, 0x04, 0x03, + /* RLE: 008 Pixels @ 098,086*/ 8, 0x00, + /* RLE: 001 Pixels @ 106,086*/ 1, 0x0B, + /* RLE: 045 Pixels @ 107,086*/ 45, 0x00, + /* RLE: 001 Pixels @ 152,086*/ 1, 0x08, + /* RLE: 034 Pixels @ 153,086*/ 34, 0x00, + /* RLE: 001 Pixels @ 187,086*/ 1, 0x04, + /* RLE: 007 Pixels @ 188,086*/ 7, 0x03, + /* RLE: 063 Pixels @ 195,086*/ 63, 0x00, + /* ABS: 005 Pixels @ 258,086*/ 0, 5, 0x06, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 037 Pixels @ 263,086*/ 37, 0x01, + /* ABS: 002 Pixels @ 300,086*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 302,086*/ 9, 0x03, + /* ABS: 002 Pixels @ 311,086*/ 0, 2, 0x04, 0x04, + /* RLE: 048 Pixels @ 313,086*/ 48, 0x01, + /* RLE: 003 Pixels @ 361,086*/ 3, 0x04, + /* RLE: 013 Pixels @ 364,086*/ 13, 0x03, + /* ABS: 017 Pixels @ 377,086*/ 0, 17, 0x11, 0x08, 0x0F, 0x0B, 0x00, 0x08, 0x0C, 0x11, 0x08, 0x12, 0x03, 0x0E, 0x06, 0x03, 0x03, 0x04, 0x04, + /* RLE: 006 Pixels @ 394,086*/ 6, 0x01, + /* RLE: 025 Pixels @ 000,087*/ 25, 0x02, + /* ABS: 010 Pixels @ 025,087*/ 0, 10, 0x03, 0x0C, 0x0D, 0x03, 0x03, 0x03, 0x0F, 0x0C, 0x03, 0x04, + /* RLE: 048 Pixels @ 035,087*/ 48, 0x01, + /* RLE: 003 Pixels @ 083,087*/ 3, 0x04, + /* RLE: 004 Pixels @ 086,087*/ 4, 0x03, + /* ABS: 006 Pixels @ 090,087*/ 0, 6, 0x0D, 0x0F, 0x00, 0x08, 0x0C, 0x03, + /* RLE: 013 Pixels @ 096,087*/ 13, 0x00, + /* RLE: 001 Pixels @ 109,087*/ 1, 0x0B, + /* RLE: 042 Pixels @ 110,087*/ 42, 0x00, + /* RLE: 001 Pixels @ 152,087*/ 1, 0x08, + /* RLE: 035 Pixels @ 153,087*/ 35, 0x00, + /* RLE: 001 Pixels @ 188,087*/ 1, 0x04, + /* RLE: 006 Pixels @ 189,087*/ 6, 0x03, + /* RLE: 001 Pixels @ 195,087*/ 1, 0x04, + /* RLE: 064 Pixels @ 196,087*/ 64, 0x00, + /* ABS: 004 Pixels @ 260,087*/ 0, 4, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 037 Pixels @ 264,087*/ 37, 0x01, + /* ABS: 002 Pixels @ 301,087*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 303,087*/ 9, 0x03, + /* ABS: 002 Pixels @ 312,087*/ 0, 2, 0x04, 0x04, + /* RLE: 050 Pixels @ 314,087*/ 50, 0x01, + /* RLE: 003 Pixels @ 364,087*/ 3, 0x04, + /* RLE: 007 Pixels @ 367,087*/ 7, 0x03, + /* ABS: 019 Pixels @ 374,087*/ 0, 19, 0x00, 0x03, 0x03, 0x0C, 0x08, 0x06, 0x08, 0x04, 0x12, 0x11, 0x0B, 0x08, 0x12, 0x0C, 0x0F, 0x0C, 0x03, 0x04, 0x04, + /* RLE: 007 Pixels @ 393,087*/ 7, 0x01, + /* RLE: 025 Pixels @ 000,088*/ 25, 0x02, + /* ABS: 010 Pixels @ 025,088*/ 0, 10, 0x03, 0x00, 0x0F, 0x11, 0x06, 0x0F, 0x0F, 0x00, 0x03, 0x03, + /* RLE: 047 Pixels @ 035,088*/ 47, 0x01, + /* ABS: 002 Pixels @ 082,088*/ 0, 2, 0x04, 0x04, + /* RLE: 006 Pixels @ 084,088*/ 6, 0x03, + /* ABS: 005 Pixels @ 090,088*/ 0, 5, 0x00, 0x08, 0x12, 0x0B, 0x03, + /* RLE: 013 Pixels @ 095,088*/ 13, 0x00, + /* RLE: 001 Pixels @ 108,088*/ 1, 0x0B, + /* RLE: 076 Pixels @ 109,088*/ 76, 0x00, + /* ABS: 004 Pixels @ 185,088*/ 0, 4, 0x0B, 0x00, 0x0B, 0x04, + /* RLE: 006 Pixels @ 189,088*/ 6, 0x03, + /* RLE: 001 Pixels @ 195,088*/ 1, 0x04, + /* RLE: 065 Pixels @ 196,088*/ 65, 0x00, + /* ABS: 004 Pixels @ 261,088*/ 0, 4, 0x0D, 0x03, 0x03, 0x0D, + /* RLE: 038 Pixels @ 265,088*/ 38, 0x01, + /* ABS: 002 Pixels @ 303,088*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 305,088*/ 8, 0x03, + /* ABS: 002 Pixels @ 313,088*/ 0, 2, 0x04, 0x04, + /* RLE: 052 Pixels @ 315,088*/ 52, 0x01, + /* RLE: 003 Pixels @ 367,088*/ 3, 0x04, + /* RLE: 003 Pixels @ 370,088*/ 3, 0x03, + /* ABS: 018 Pixels @ 373,088*/ 0, 18, 0x00, 0x08, 0x0D, 0x03, 0x00, 0x08, 0x04, 0x0E, 0x08, 0x11, 0x08, 0x0B, 0x0B, 0x0D, 0x0D, 0x04, 0x03, 0x00, + /* RLE: 009 Pixels @ 391,088*/ 9, 0x01, + /* RLE: 025 Pixels @ 000,089*/ 25, 0x02, + /* ABS: 011 Pixels @ 025,089*/ 0, 11, 0x0B, 0x03, 0x00, 0x12, 0x06, 0x12, 0x00, 0x03, 0x03, 0x03, 0x04, + /* RLE: 044 Pixels @ 036,089*/ 44, 0x01, + /* RLE: 003 Pixels @ 080,089*/ 3, 0x04, + /* RLE: 008 Pixels @ 083,089*/ 8, 0x03, + /* ABS: 003 Pixels @ 091,089*/ 0, 3, 0x0B, 0x03, 0x03, + /* RLE: 015 Pixels @ 094,089*/ 15, 0x00, + /* RLE: 001 Pixels @ 109,089*/ 1, 0x0B, + /* RLE: 078 Pixels @ 110,089*/ 78, 0x00, + /* RLE: 001 Pixels @ 188,089*/ 1, 0x04, + /* RLE: 007 Pixels @ 189,089*/ 7, 0x03, + /* RLE: 066 Pixels @ 196,089*/ 66, 0x00, + /* ABS: 004 Pixels @ 262,089*/ 0, 4, 0x0D, 0x06, 0x03, 0x06, + /* RLE: 038 Pixels @ 266,089*/ 38, 0x01, + /* ABS: 002 Pixels @ 304,089*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 306,089*/ 9, 0x03, + /* ABS: 002 Pixels @ 315,089*/ 0, 2, 0x04, 0x04, + /* RLE: 053 Pixels @ 317,089*/ 53, 0x01, + /* ABS: 015 Pixels @ 370,089*/ 0, 15, 0x04, 0x04, 0x00, 0x03, 0x04, 0x08, 0x0D, 0x03, 0x06, 0x12, 0x03, 0x04, 0x08, 0x08, 0x0E, + /* RLE: 004 Pixels @ 385,089*/ 4, 0x03, + /* RLE: 001 Pixels @ 389,089*/ 1, 0x00, + /* RLE: 010 Pixels @ 390,089*/ 10, 0x01, + /* RLE: 026 Pixels @ 000,090*/ 26, 0x02, + /* ABS: 010 Pixels @ 026,090*/ 0, 10, 0x18, 0x03, 0x03, 0x0C, 0x0F, 0x08, 0x08, 0x0C, 0x03, 0x00, + /* RLE: 043 Pixels @ 036,090*/ 43, 0x01, + /* ABS: 002 Pixels @ 079,090*/ 0, 2, 0x04, 0x04, + /* RLE: 010 Pixels @ 081,090*/ 10, 0x03, + /* ABS: 003 Pixels @ 091,090*/ 0, 3, 0x00, 0x00, 0x04, + /* RLE: 095 Pixels @ 094,090*/ 95, 0x00, + /* RLE: 001 Pixels @ 189,090*/ 1, 0x04, + /* RLE: 006 Pixels @ 190,090*/ 6, 0x03, + /* RLE: 001 Pixels @ 196,090*/ 1, 0x04, + /* RLE: 066 Pixels @ 197,090*/ 66, 0x00, + /* RLE: 001 Pixels @ 263,090*/ 1, 0x0D, + /* RLE: 004 Pixels @ 264,090*/ 4, 0x06, + /* RLE: 037 Pixels @ 268,090*/ 37, 0x01, + /* ABS: 002 Pixels @ 305,090*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 307,090*/ 9, 0x03, + /* ABS: 002 Pixels @ 316,090*/ 0, 2, 0x04, 0x04, + /* RLE: 055 Pixels @ 318,090*/ 55, 0x01, + /* ABS: 015 Pixels @ 373,090*/ 0, 15, 0x00, 0x03, 0x04, 0x0F, 0x0D, 0x0E, 0x08, 0x00, 0x03, 0x0B, 0x0F, 0x0C, 0x03, 0x04, 0x04, + /* RLE: 012 Pixels @ 388,090*/ 12, 0x01, + /* RLE: 027 Pixels @ 000,091*/ 27, 0x02, + /* ABS: 009 Pixels @ 027,091*/ 0, 9, 0x03, 0x04, 0x08, 0x06, 0x0C, 0x0E, 0x08, 0x00, 0x03, + /* RLE: 041 Pixels @ 036,091*/ 41, 0x01, + /* ABS: 002 Pixels @ 077,091*/ 0, 2, 0x04, 0x04, + /* RLE: 011 Pixels @ 079,091*/ 11, 0x03, + /* ABS: 002 Pixels @ 090,091*/ 0, 2, 0x04, 0x04, + /* RLE: 062 Pixels @ 092,091*/ 62, 0x00, + /* RLE: 001 Pixels @ 154,091*/ 1, 0x08, + /* RLE: 034 Pixels @ 155,091*/ 34, 0x00, + /* RLE: 001 Pixels @ 189,091*/ 1, 0x04, + /* RLE: 006 Pixels @ 190,091*/ 6, 0x03, + /* RLE: 001 Pixels @ 196,091*/ 1, 0x04, + /* RLE: 067 Pixels @ 197,091*/ 67, 0x00, + /* RLE: 001 Pixels @ 264,091*/ 1, 0x0D, + /* RLE: 004 Pixels @ 265,091*/ 4, 0x06, + /* RLE: 037 Pixels @ 269,091*/ 37, 0x01, + /* ABS: 002 Pixels @ 306,091*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 308,091*/ 9, 0x03, + /* ABS: 002 Pixels @ 317,091*/ 0, 2, 0x04, 0x04, + /* RLE: 055 Pixels @ 319,091*/ 55, 0x01, + /* ABS: 007 Pixels @ 374,091*/ 0, 7, 0x18, 0x03, 0x00, 0x0F, 0x08, 0x08, 0x0C, + /* RLE: 004 Pixels @ 381,091*/ 4, 0x03, + /* ABS: 002 Pixels @ 385,091*/ 0, 2, 0x00, 0x04, + /* RLE: 013 Pixels @ 387,091*/ 13, 0x01, + /* RLE: 027 Pixels @ 000,092*/ 27, 0x02, + /* ABS: 009 Pixels @ 027,092*/ 0, 9, 0x03, 0x0C, 0x0D, 0x03, 0x03, 0x03, 0x06, 0x0C, 0x00, + /* RLE: 039 Pixels @ 036,092*/ 39, 0x01, + /* RLE: 003 Pixels @ 075,092*/ 3, 0x04, + /* RLE: 011 Pixels @ 078,092*/ 11, 0x03, + /* ABS: 002 Pixels @ 089,092*/ 0, 2, 0x04, 0x04, + /* RLE: 017 Pixels @ 091,092*/ 17, 0x00, + /* RLE: 001 Pixels @ 108,092*/ 1, 0x0B, + /* RLE: 046 Pixels @ 109,092*/ 46, 0x00, + /* RLE: 001 Pixels @ 155,092*/ 1, 0x08, + /* RLE: 032 Pixels @ 156,092*/ 32, 0x00, + /* ABS: 002 Pixels @ 188,092*/ 0, 2, 0x0B, 0x04, + /* RLE: 007 Pixels @ 190,092*/ 7, 0x03, + /* RLE: 068 Pixels @ 197,092*/ 68, 0x00, + /* ABS: 005 Pixels @ 265,092*/ 0, 5, 0x06, 0x0D, 0x06, 0x06, 0x0D, + /* RLE: 037 Pixels @ 270,092*/ 37, 0x01, + /* ABS: 002 Pixels @ 307,092*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 309,092*/ 9, 0x03, + /* RLE: 001 Pixels @ 318,092*/ 1, 0x04, + /* RLE: 056 Pixels @ 319,092*/ 56, 0x01, + /* ABS: 010 Pixels @ 375,092*/ 0, 10, 0x15, 0x03, 0x00, 0x11, 0x08, 0x11, 0x03, 0x04, 0x04, 0x04, + /* RLE: 015 Pixels @ 385,092*/ 15, 0x01, + /* RLE: 027 Pixels @ 000,093*/ 27, 0x02, + /* ABS: 009 Pixels @ 027,093*/ 0, 9, 0x03, 0x0C, 0x11, 0x03, 0x03, 0x00, 0x0F, 0x04, 0x03, + /* RLE: 038 Pixels @ 036,093*/ 38, 0x01, + /* ABS: 002 Pixels @ 074,093*/ 0, 2, 0x04, 0x04, + /* RLE: 011 Pixels @ 076,093*/ 11, 0x03, + /* ABS: 002 Pixels @ 087,093*/ 0, 2, 0x04, 0x04, + /* RLE: 066 Pixels @ 089,093*/ 66, 0x00, + /* RLE: 001 Pixels @ 155,093*/ 1, 0x08, + /* RLE: 034 Pixels @ 156,093*/ 34, 0x00, + /* RLE: 001 Pixels @ 190,093*/ 1, 0x04, + /* RLE: 006 Pixels @ 191,093*/ 6, 0x03, + /* RLE: 001 Pixels @ 197,093*/ 1, 0x04, + /* RLE: 069 Pixels @ 198,093*/ 69, 0x00, + /* ABS: 004 Pixels @ 267,093*/ 0, 4, 0x0D, 0x03, 0x06, 0x06, + /* RLE: 037 Pixels @ 271,093*/ 37, 0x01, + /* ABS: 002 Pixels @ 308,093*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 310,093*/ 9, 0x03, + /* RLE: 057 Pixels @ 319,093*/ 57, 0x01, + /* ABS: 006 Pixels @ 376,093*/ 0, 6, 0x15, 0x03, 0x03, 0x06, 0x0B, 0x03, + /* RLE: 018 Pixels @ 382,093*/ 18, 0x01, + /* RLE: 027 Pixels @ 000,094*/ 27, 0x02, + /* ABS: 011 Pixels @ 027,094*/ 0, 11, 0x03, 0x00, 0x0F, 0x08, 0x03, 0x00, 0x06, 0x03, 0x03, 0x03, 0x00, + /* RLE: 034 Pixels @ 038,094*/ 34, 0x01, + /* RLE: 003 Pixels @ 072,094*/ 3, 0x04, + /* RLE: 011 Pixels @ 075,094*/ 11, 0x03, + /* ABS: 002 Pixels @ 086,094*/ 0, 2, 0x04, 0x04, + /* RLE: 102 Pixels @ 088,094*/ 102, 0x00, + /* RLE: 001 Pixels @ 190,094*/ 1, 0x04, + /* RLE: 006 Pixels @ 191,094*/ 6, 0x03, + /* RLE: 001 Pixels @ 197,094*/ 1, 0x04, + /* RLE: 070 Pixels @ 198,094*/ 70, 0x00, + /* ABS: 004 Pixels @ 268,094*/ 0, 4, 0x0D, 0x03, 0x03, 0x06, + /* RLE: 037 Pixels @ 272,094*/ 37, 0x01, + /* ABS: 002 Pixels @ 309,094*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 311,094*/ 9, 0x03, + /* ABS: 002 Pixels @ 320,094*/ 0, 2, 0x04, 0x04, + /* RLE: 056 Pixels @ 322,094*/ 56, 0x01, + /* ABS: 004 Pixels @ 378,094*/ 0, 4, 0x00, 0x03, 0x03, 0x15, + /* RLE: 018 Pixels @ 382,094*/ 18, 0x01, + /* RLE: 027 Pixels @ 000,095*/ 27, 0x02, + /* ABS: 012 Pixels @ 027,095*/ 0, 12, 0x0B, 0x03, 0x00, 0x0C, 0x03, 0x03, 0x03, 0x00, 0x0C, 0x0E, 0x03, 0x15, + /* RLE: 032 Pixels @ 039,095*/ 32, 0x01, + /* ABS: 002 Pixels @ 071,095*/ 0, 2, 0x04, 0x04, + /* RLE: 011 Pixels @ 073,095*/ 11, 0x03, + /* ABS: 002 Pixels @ 084,095*/ 0, 2, 0x04, 0x04, + /* RLE: 023 Pixels @ 086,095*/ 23, 0x00, + /* RLE: 001 Pixels @ 109,095*/ 1, 0x0B, + /* RLE: 080 Pixels @ 110,095*/ 80, 0x00, + /* RLE: 001 Pixels @ 190,095*/ 1, 0x04, + /* RLE: 007 Pixels @ 191,095*/ 7, 0x03, + /* RLE: 071 Pixels @ 198,095*/ 71, 0x00, + /* ABS: 004 Pixels @ 269,095*/ 0, 4, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 037 Pixels @ 273,095*/ 37, 0x01, + /* ABS: 002 Pixels @ 310,095*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 312,095*/ 9, 0x03, + /* ABS: 002 Pixels @ 321,095*/ 0, 2, 0x04, 0x04, + /* RLE: 077 Pixels @ 323,095*/ 77, 0x01, + /* RLE: 028 Pixels @ 000,096*/ 28, 0x02, + /* ABS: 005 Pixels @ 028,096*/ 0, 5, 0x03, 0x0B, 0x0C, 0x12, 0x11, + /* RLE: 004 Pixels @ 033,096*/ 4, 0x08, + /* ABS: 002 Pixels @ 037,096*/ 0, 2, 0x00, 0x15, + /* RLE: 030 Pixels @ 039,096*/ 30, 0x01, + /* ABS: 002 Pixels @ 069,096*/ 0, 2, 0x04, 0x04, + /* RLE: 011 Pixels @ 071,096*/ 11, 0x03, + /* RLE: 003 Pixels @ 082,096*/ 3, 0x04, + /* RLE: 105 Pixels @ 085,096*/ 105, 0x00, + /* ABS: 002 Pixels @ 190,096*/ 0, 2, 0x0B, 0x04, + /* RLE: 006 Pixels @ 192,096*/ 6, 0x03, + /* RLE: 001 Pixels @ 198,096*/ 1, 0x04, + /* RLE: 071 Pixels @ 199,096*/ 71, 0x00, + /* ABS: 004 Pixels @ 270,096*/ 0, 4, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 037 Pixels @ 274,096*/ 37, 0x01, + /* ABS: 002 Pixels @ 311,096*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 313,096*/ 9, 0x03, + /* ABS: 002 Pixels @ 322,096*/ 0, 2, 0x04, 0x04, + /* RLE: 076 Pixels @ 324,096*/ 76, 0x01, + /* RLE: 028 Pixels @ 000,097*/ 28, 0x02, + /* ABS: 011 Pixels @ 028,097*/ 0, 11, 0x03, 0x06, 0x08, 0x08, 0x08, 0x12, 0x0B, 0x00, 0x03, 0x03, 0x15, + /* RLE: 028 Pixels @ 039,097*/ 28, 0x01, + /* RLE: 003 Pixels @ 067,097*/ 3, 0x04, + /* RLE: 011 Pixels @ 070,097*/ 11, 0x03, + /* ABS: 002 Pixels @ 081,097*/ 0, 2, 0x04, 0x04, + /* RLE: 074 Pixels @ 083,097*/ 74, 0x00, + /* RLE: 001 Pixels @ 157,097*/ 1, 0x08, + /* RLE: 033 Pixels @ 158,097*/ 33, 0x00, + /* RLE: 001 Pixels @ 191,097*/ 1, 0x04, + /* RLE: 006 Pixels @ 192,097*/ 6, 0x03, + /* RLE: 001 Pixels @ 198,097*/ 1, 0x04, + /* RLE: 072 Pixels @ 199,097*/ 72, 0x00, + /* RLE: 001 Pixels @ 271,097*/ 1, 0x0D, + /* RLE: 004 Pixels @ 272,097*/ 4, 0x06, + /* RLE: 036 Pixels @ 276,097*/ 36, 0x01, + /* ABS: 002 Pixels @ 312,097*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 314,097*/ 9, 0x03, + /* ABS: 002 Pixels @ 323,097*/ 0, 2, 0x04, 0x04, + /* RLE: 075 Pixels @ 325,097*/ 75, 0x01, + /* RLE: 028 Pixels @ 000,098*/ 28, 0x02, + /* ABS: 009 Pixels @ 028,098*/ 0, 9, 0x03, 0x00, 0x03, 0x00, 0x08, 0x08, 0x0E, 0x03, 0x00, + /* RLE: 030 Pixels @ 037,098*/ 30, 0x01, + /* RLE: 001 Pixels @ 067,098*/ 1, 0x04, + /* RLE: 011 Pixels @ 068,098*/ 11, 0x03, + /* ABS: 002 Pixels @ 079,098*/ 0, 2, 0x04, 0x04, + /* RLE: 027 Pixels @ 081,098*/ 27, 0x00, + /* RLE: 001 Pixels @ 108,098*/ 1, 0x0B, + /* RLE: 048 Pixels @ 109,098*/ 48, 0x00, + /* RLE: 001 Pixels @ 157,098*/ 1, 0x08, + /* RLE: 032 Pixels @ 158,098*/ 32, 0x00, + /* ABS: 002 Pixels @ 190,098*/ 0, 2, 0x0B, 0x04, + /* RLE: 006 Pixels @ 192,098*/ 6, 0x03, + /* RLE: 001 Pixels @ 198,098*/ 1, 0x04, + /* RLE: 073 Pixels @ 199,098*/ 73, 0x00, + /* ABS: 005 Pixels @ 272,098*/ 0, 5, 0x0D, 0x06, 0x03, 0x06, 0x0D, + /* RLE: 036 Pixels @ 277,098*/ 36, 0x01, + /* ABS: 002 Pixels @ 313,098*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 315,098*/ 9, 0x03, + /* ABS: 002 Pixels @ 324,098*/ 0, 2, 0x04, 0x04, + /* RLE: 074 Pixels @ 326,098*/ 74, 0x01, + /* RLE: 028 Pixels @ 000,099*/ 28, 0x02, + /* ABS: 009 Pixels @ 028,099*/ 0, 9, 0x00, 0x03, 0x00, 0x0F, 0x11, 0x0C, 0x0F, 0x0C, 0x03, + /* RLE: 029 Pixels @ 037,099*/ 29, 0x01, + /* ABS: 002 Pixels @ 066,099*/ 0, 2, 0x04, 0x04, + /* RLE: 010 Pixels @ 068,099*/ 10, 0x03, + /* ABS: 002 Pixels @ 078,099*/ 0, 2, 0x04, 0x04, + /* RLE: 078 Pixels @ 080,099*/ 78, 0x00, + /* RLE: 001 Pixels @ 158,099*/ 1, 0x08, + /* RLE: 033 Pixels @ 159,099*/ 33, 0x00, + /* RLE: 007 Pixels @ 192,099*/ 7, 0x03, + /* RLE: 001 Pixels @ 199,099*/ 1, 0x04, + /* RLE: 073 Pixels @ 200,099*/ 73, 0x00, + /* ABS: 005 Pixels @ 273,099*/ 0, 5, 0x0D, 0x06, 0x03, 0x06, 0x06, + /* RLE: 037 Pixels @ 278,099*/ 37, 0x01, + /* ABS: 002 Pixels @ 315,099*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 317,099*/ 9, 0x03, + /* ABS: 002 Pixels @ 326,099*/ 0, 2, 0x04, 0x04, + /* RLE: 072 Pixels @ 328,099*/ 72, 0x01, + /* RLE: 028 Pixels @ 000,100*/ 28, 0x02, + /* ABS: 010 Pixels @ 028,100*/ 0, 10, 0x18, 0x00, 0x08, 0x0D, 0x03, 0x03, 0x03, 0x04, 0x03, 0x04, + /* RLE: 027 Pixels @ 038,100*/ 27, 0x01, + /* ABS: 002 Pixels @ 065,100*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 067,100*/ 9, 0x03, + /* ABS: 002 Pixels @ 076,100*/ 0, 2, 0x04, 0x04, + /* RLE: 114 Pixels @ 078,100*/ 114, 0x00, + /* RLE: 001 Pixels @ 192,100*/ 1, 0x04, + /* RLE: 006 Pixels @ 193,100*/ 6, 0x03, + /* RLE: 001 Pixels @ 199,100*/ 1, 0x04, + /* RLE: 075 Pixels @ 200,100*/ 75, 0x00, + /* ABS: 004 Pixels @ 275,100*/ 0, 4, 0x0D, 0x03, 0x06, 0x06, + /* RLE: 037 Pixels @ 279,100*/ 37, 0x01, + /* ABS: 002 Pixels @ 316,100*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 318,100*/ 9, 0x03, + /* ABS: 002 Pixels @ 327,100*/ 0, 2, 0x04, 0x04, + /* RLE: 071 Pixels @ 329,100*/ 71, 0x01, + /* RLE: 028 Pixels @ 000,101*/ 28, 0x02, + /* ABS: 003 Pixels @ 028,101*/ 0, 3, 0x18, 0x03, 0x0E, + /* RLE: 006 Pixels @ 031,101*/ 6, 0x03, + /* RLE: 001 Pixels @ 037,101*/ 1, 0x04, + /* RLE: 026 Pixels @ 038,101*/ 26, 0x01, + /* ABS: 002 Pixels @ 064,101*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 066,101*/ 8, 0x03, + /* RLE: 003 Pixels @ 074,101*/ 3, 0x04, + /* RLE: 033 Pixels @ 077,101*/ 33, 0x00, + /* RLE: 001 Pixels @ 110,101*/ 1, 0x0B, + /* RLE: 081 Pixels @ 111,101*/ 81, 0x00, + /* RLE: 001 Pixels @ 192,101*/ 1, 0x04, + /* RLE: 006 Pixels @ 193,101*/ 6, 0x03, + /* RLE: 001 Pixels @ 199,101*/ 1, 0x04, + /* RLE: 076 Pixels @ 200,101*/ 76, 0x00, + /* ABS: 004 Pixels @ 276,101*/ 0, 4, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 037 Pixels @ 280,101*/ 37, 0x01, + /* ABS: 002 Pixels @ 317,101*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 319,101*/ 9, 0x03, + /* ABS: 002 Pixels @ 328,101*/ 0, 2, 0x04, 0x04, + /* RLE: 070 Pixels @ 330,101*/ 70, 0x01, + /* RLE: 029 Pixels @ 000,102*/ 29, 0x02, + /* ABS: 002 Pixels @ 029,102*/ 0, 2, 0x03, 0x00, + /* RLE: 006 Pixels @ 031,102*/ 6, 0x03, + /* RLE: 001 Pixels @ 037,102*/ 1, 0x04, + /* RLE: 025 Pixels @ 038,102*/ 25, 0x01, + /* ABS: 002 Pixels @ 063,102*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 065,102*/ 8, 0x03, + /* ABS: 002 Pixels @ 073,102*/ 0, 2, 0x04, 0x04, + /* RLE: 117 Pixels @ 075,102*/ 117, 0x00, + /* RLE: 001 Pixels @ 192,102*/ 1, 0x0B, + /* RLE: 007 Pixels @ 193,102*/ 7, 0x03, + /* RLE: 001 Pixels @ 200,102*/ 1, 0x04, + /* RLE: 076 Pixels @ 201,102*/ 76, 0x00, + /* ABS: 004 Pixels @ 277,102*/ 0, 4, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 037 Pixels @ 281,102*/ 37, 0x01, + /* ABS: 002 Pixels @ 318,102*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 320,102*/ 9, 0x03, + /* ABS: 002 Pixels @ 329,102*/ 0, 2, 0x04, 0x04, + /* RLE: 069 Pixels @ 331,102*/ 69, 0x01, + /* RLE: 030 Pixels @ 000,103*/ 30, 0x02, + /* RLE: 001 Pixels @ 030,103*/ 1, 0x04, + /* RLE: 006 Pixels @ 031,103*/ 6, 0x03, + /* RLE: 001 Pixels @ 037,103*/ 1, 0x04, + /* RLE: 024 Pixels @ 038,103*/ 24, 0x01, + /* ABS: 002 Pixels @ 062,103*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 064,103*/ 8, 0x03, + /* RLE: 001 Pixels @ 072,103*/ 1, 0x04, + /* RLE: 028 Pixels @ 073,103*/ 28, 0x00, + /* ABS: 006 Pixels @ 101,103*/ 0, 6, 0x03, 0x03, 0x00, 0x03, 0x03, 0x03, + /* RLE: 052 Pixels @ 107,103*/ 52, 0x00, + /* RLE: 001 Pixels @ 159,103*/ 1, 0x08, + /* RLE: 033 Pixels @ 160,103*/ 33, 0x00, + /* RLE: 001 Pixels @ 193,103*/ 1, 0x04, + /* RLE: 006 Pixels @ 194,103*/ 6, 0x03, + /* RLE: 001 Pixels @ 200,103*/ 1, 0x04, + /* RLE: 077 Pixels @ 201,103*/ 77, 0x00, + /* ABS: 005 Pixels @ 278,103*/ 0, 5, 0x0D, 0x06, 0x03, 0x06, 0x06, + /* RLE: 036 Pixels @ 283,103*/ 36, 0x01, + /* ABS: 002 Pixels @ 319,103*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 321,103*/ 9, 0x03, + /* ABS: 002 Pixels @ 330,103*/ 0, 2, 0x04, 0x04, + /* RLE: 068 Pixels @ 332,103*/ 68, 0x01, + /* RLE: 030 Pixels @ 000,104*/ 30, 0x02, + /* RLE: 001 Pixels @ 030,104*/ 1, 0x04, + /* RLE: 006 Pixels @ 031,104*/ 6, 0x03, + /* RLE: 001 Pixels @ 037,104*/ 1, 0x04, + /* RLE: 023 Pixels @ 038,104*/ 23, 0x01, + /* ABS: 002 Pixels @ 061,104*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 063,104*/ 8, 0x03, + /* ABS: 002 Pixels @ 071,104*/ 0, 2, 0x04, 0x04, + /* RLE: 027 Pixels @ 073,104*/ 27, 0x00, + /* ABS: 007 Pixels @ 100,104*/ 0, 7, 0x03, 0x04, 0x0B, 0x03, 0x03, 0x12, 0x0B, + /* RLE: 053 Pixels @ 107,104*/ 53, 0x00, + /* RLE: 001 Pixels @ 160,104*/ 1, 0x08, + /* RLE: 032 Pixels @ 161,104*/ 32, 0x00, + /* RLE: 001 Pixels @ 193,104*/ 1, 0x04, + /* RLE: 006 Pixels @ 194,104*/ 6, 0x03, + /* RLE: 001 Pixels @ 200,104*/ 1, 0x04, + /* RLE: 078 Pixels @ 201,104*/ 78, 0x00, + /* ABS: 005 Pixels @ 279,104*/ 0, 5, 0x0D, 0x06, 0x03, 0x06, 0x0D, + /* RLE: 036 Pixels @ 284,104*/ 36, 0x01, + /* ABS: 002 Pixels @ 320,104*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 322,104*/ 9, 0x03, + /* ABS: 002 Pixels @ 331,104*/ 0, 2, 0x04, 0x04, + /* RLE: 067 Pixels @ 333,104*/ 67, 0x01, + /* RLE: 031 Pixels @ 000,105*/ 31, 0x02, + /* RLE: 007 Pixels @ 031,105*/ 7, 0x03, + /* RLE: 001 Pixels @ 038,105*/ 1, 0x04, + /* RLE: 021 Pixels @ 039,105*/ 21, 0x01, + /* ABS: 002 Pixels @ 060,105*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 062,105*/ 8, 0x03, + /* ABS: 002 Pixels @ 070,105*/ 0, 2, 0x04, 0x04, + /* RLE: 028 Pixels @ 072,105*/ 28, 0x00, + /* ABS: 008 Pixels @ 100,105*/ 0, 8, 0x03, 0x11, 0x0F, 0x03, 0x0B, 0x08, 0x03, 0x03, + /* RLE: 052 Pixels @ 108,105*/ 52, 0x00, + /* RLE: 001 Pixels @ 160,105*/ 1, 0x08, + /* RLE: 033 Pixels @ 161,105*/ 33, 0x00, + /* RLE: 007 Pixels @ 194,105*/ 7, 0x03, + /* RLE: 001 Pixels @ 201,105*/ 1, 0x04, + /* RLE: 078 Pixels @ 202,105*/ 78, 0x00, + /* ABS: 005 Pixels @ 280,105*/ 0, 5, 0x0D, 0x06, 0x03, 0x06, 0x06, + /* RLE: 036 Pixels @ 285,105*/ 36, 0x01, + /* RLE: 003 Pixels @ 321,105*/ 3, 0x04, + /* RLE: 008 Pixels @ 324,105*/ 8, 0x03, + /* RLE: 003 Pixels @ 332,105*/ 3, 0x04, + /* RLE: 065 Pixels @ 335,105*/ 65, 0x01, + /* RLE: 031 Pixels @ 000,106*/ 31, 0x02, + /* RLE: 001 Pixels @ 031,106*/ 1, 0x04, + /* RLE: 006 Pixels @ 032,106*/ 6, 0x03, + /* RLE: 001 Pixels @ 038,106*/ 1, 0x04, + /* RLE: 020 Pixels @ 039,106*/ 20, 0x01, + /* ABS: 002 Pixels @ 059,106*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 061,106*/ 8, 0x03, + /* ABS: 002 Pixels @ 069,106*/ 0, 2, 0x04, 0x04, + /* RLE: 029 Pixels @ 071,106*/ 29, 0x00, + /* ABS: 010 Pixels @ 100,106*/ 0, 10, 0x03, 0x00, 0x08, 0x06, 0x00, 0x08, 0x00, 0x03, 0x03, 0x03, + /* RLE: 083 Pixels @ 110,106*/ 83, 0x00, + /* ABS: 002 Pixels @ 193,106*/ 0, 2, 0x0B, 0x04, + /* RLE: 006 Pixels @ 195,106*/ 6, 0x03, + /* RLE: 001 Pixels @ 201,106*/ 1, 0x04, + /* RLE: 080 Pixels @ 202,106*/ 80, 0x00, + /* ABS: 004 Pixels @ 282,106*/ 0, 4, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 037 Pixels @ 286,106*/ 37, 0x01, + /* ABS: 002 Pixels @ 323,106*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 325,106*/ 9, 0x03, + /* ABS: 002 Pixels @ 334,106*/ 0, 2, 0x04, 0x04, + /* RLE: 064 Pixels @ 336,106*/ 64, 0x01, + /* RLE: 031 Pixels @ 000,107*/ 31, 0x02, + /* RLE: 001 Pixels @ 031,107*/ 1, 0x04, + /* RLE: 006 Pixels @ 032,107*/ 6, 0x03, + /* RLE: 001 Pixels @ 038,107*/ 1, 0x04, + /* RLE: 019 Pixels @ 039,107*/ 19, 0x01, + /* ABS: 002 Pixels @ 058,107*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 060,107*/ 8, 0x03, + /* ABS: 002 Pixels @ 068,107*/ 0, 2, 0x04, 0x04, + /* RLE: 030 Pixels @ 070,107*/ 30, 0x00, + /* ABS: 011 Pixels @ 100,107*/ 0, 11, 0x03, 0x03, 0x0C, 0x08, 0x0F, 0x08, 0x08, 0x06, 0x0B, 0x03, 0x03, + /* RLE: 083 Pixels @ 111,107*/ 83, 0x00, + /* RLE: 001 Pixels @ 194,107*/ 1, 0x04, + /* RLE: 006 Pixels @ 195,107*/ 6, 0x03, + /* RLE: 001 Pixels @ 201,107*/ 1, 0x04, + /* RLE: 081 Pixels @ 202,107*/ 81, 0x00, + /* ABS: 004 Pixels @ 283,107*/ 0, 4, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 037 Pixels @ 287,107*/ 37, 0x01, + /* ABS: 002 Pixels @ 324,107*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 326,107*/ 9, 0x03, + /* ABS: 002 Pixels @ 335,107*/ 0, 2, 0x04, 0x04, + /* RLE: 063 Pixels @ 337,107*/ 63, 0x01, + /* RLE: 031 Pixels @ 000,108*/ 31, 0x02, + /* RLE: 001 Pixels @ 031,108*/ 1, 0x04, + /* RLE: 006 Pixels @ 032,108*/ 6, 0x03, + /* RLE: 001 Pixels @ 038,108*/ 1, 0x04, + /* RLE: 018 Pixels @ 039,108*/ 18, 0x01, + /* ABS: 002 Pixels @ 057,108*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 059,108*/ 8, 0x03, + /* ABS: 002 Pixels @ 067,108*/ 0, 2, 0x04, 0x04, + /* RLE: 029 Pixels @ 069,108*/ 29, 0x00, + /* ABS: 013 Pixels @ 098,108*/ 0, 13, 0x03, 0x03, 0x04, 0x00, 0x03, 0x12, 0x08, 0x06, 0x04, 0x11, 0x08, 0x0E, 0x03, + /* RLE: 084 Pixels @ 111,108*/ 84, 0x00, + /* RLE: 007 Pixels @ 195,108*/ 7, 0x03, + /* RLE: 001 Pixels @ 202,108*/ 1, 0x04, + /* RLE: 081 Pixels @ 203,108*/ 81, 0x00, + /* ABS: 004 Pixels @ 284,108*/ 0, 4, 0x0D, 0x06, 0x03, 0x06, + /* RLE: 037 Pixels @ 288,108*/ 37, 0x01, + /* ABS: 002 Pixels @ 325,108*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 327,108*/ 9, 0x03, + /* ABS: 002 Pixels @ 336,108*/ 0, 2, 0x04, 0x04, + /* RLE: 062 Pixels @ 338,108*/ 62, 0x01, + /* RLE: 031 Pixels @ 000,109*/ 31, 0x02, + /* RLE: 001 Pixels @ 031,109*/ 1, 0x04, + /* RLE: 006 Pixels @ 032,109*/ 6, 0x03, + /* RLE: 001 Pixels @ 038,109*/ 1, 0x04, + /* RLE: 017 Pixels @ 039,109*/ 17, 0x01, + /* ABS: 002 Pixels @ 056,109*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 058,109*/ 8, 0x03, + /* ABS: 002 Pixels @ 066,109*/ 0, 2, 0x04, 0x04, + /* RLE: 028 Pixels @ 068,109*/ 28, 0x00, + /* ABS: 015 Pixels @ 096,109*/ 0, 15, 0x04, 0x03, 0x00, 0x0F, 0x08, 0x0D, 0x03, 0x03, 0x11, 0x0F, 0x03, 0x03, 0x00, 0x03, 0x03, + /* RLE: 051 Pixels @ 111,109*/ 51, 0x00, + /* ABS: 004 Pixels @ 162,109*/ 0, 4, 0x08, 0x00, 0x00, 0x0B, + /* RLE: 029 Pixels @ 166,109*/ 29, 0x00, + /* RLE: 001 Pixels @ 195,109*/ 1, 0x04, + /* RLE: 006 Pixels @ 196,109*/ 6, 0x03, + /* RLE: 001 Pixels @ 202,109*/ 1, 0x04, + /* RLE: 082 Pixels @ 203,109*/ 82, 0x00, + /* ABS: 005 Pixels @ 285,109*/ 0, 5, 0x0D, 0x06, 0x03, 0x06, 0x06, + /* RLE: 036 Pixels @ 290,109*/ 36, 0x01, + /* ABS: 002 Pixels @ 326,109*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 328,109*/ 9, 0x03, + /* ABS: 002 Pixels @ 337,109*/ 0, 2, 0x04, 0x04, + /* RLE: 061 Pixels @ 339,109*/ 61, 0x01, + /* RLE: 031 Pixels @ 000,110*/ 31, 0x02, + /* RLE: 001 Pixels @ 031,110*/ 1, 0x04, + /* RLE: 007 Pixels @ 032,110*/ 7, 0x03, + /* RLE: 016 Pixels @ 039,110*/ 16, 0x01, + /* ABS: 002 Pixels @ 055,110*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 057,110*/ 8, 0x03, + /* ABS: 002 Pixels @ 065,110*/ 0, 2, 0x04, 0x04, + /* RLE: 028 Pixels @ 067,110*/ 28, 0x00, + /* ABS: 013 Pixels @ 095,110*/ 0, 13, 0x04, 0x04, 0x03, 0x0F, 0x0E, 0x03, 0x00, 0x03, 0x03, 0x00, 0x08, 0x0E, 0x03, + /* RLE: 054 Pixels @ 108,110*/ 54, 0x00, + /* ABS: 003 Pixels @ 162,110*/ 0, 3, 0x08, 0x00, 0x0B, + /* RLE: 029 Pixels @ 165,110*/ 29, 0x00, + /* ABS: 002 Pixels @ 194,110*/ 0, 2, 0x0B, 0x04, + /* RLE: 006 Pixels @ 196,110*/ 6, 0x03, + /* RLE: 001 Pixels @ 202,110*/ 1, 0x04, + /* RLE: 083 Pixels @ 203,110*/ 83, 0x00, + /* ABS: 005 Pixels @ 286,110*/ 0, 5, 0x0D, 0x06, 0x03, 0x06, 0x0D, + /* RLE: 036 Pixels @ 291,110*/ 36, 0x01, + /* ABS: 002 Pixels @ 327,110*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 329,110*/ 9, 0x03, + /* ABS: 002 Pixels @ 338,110*/ 0, 2, 0x04, 0x04, + /* RLE: 060 Pixels @ 340,110*/ 60, 0x01, + /* RLE: 032 Pixels @ 000,111*/ 32, 0x02, + /* RLE: 001 Pixels @ 032,111*/ 1, 0x04, + /* RLE: 006 Pixels @ 033,111*/ 6, 0x03, + /* RLE: 001 Pixels @ 039,111*/ 1, 0x04, + /* RLE: 014 Pixels @ 040,111*/ 14, 0x01, + /* ABS: 002 Pixels @ 054,111*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 056,111*/ 8, 0x03, + /* ABS: 002 Pixels @ 064,111*/ 0, 2, 0x04, 0x04, + /* RLE: 029 Pixels @ 066,111*/ 29, 0x00, + /* RLE: 003 Pixels @ 095,111*/ 3, 0x03, + /* ABS: 010 Pixels @ 098,111*/ 0, 10, 0x08, 0x04, 0x03, 0x03, 0x0C, 0x06, 0x03, 0x0B, 0x03, 0x03, + /* RLE: 055 Pixels @ 108,111*/ 55, 0x00, + /* ABS: 004 Pixels @ 163,111*/ 0, 4, 0x08, 0x00, 0x00, 0x0B, + /* RLE: 028 Pixels @ 167,111*/ 28, 0x00, + /* RLE: 001 Pixels @ 195,111*/ 1, 0x0B, + /* RLE: 007 Pixels @ 196,111*/ 7, 0x03, + /* RLE: 084 Pixels @ 203,111*/ 84, 0x00, + /* RLE: 001 Pixels @ 287,111*/ 1, 0x0D, + /* RLE: 004 Pixels @ 288,111*/ 4, 0x06, + /* RLE: 037 Pixels @ 292,111*/ 37, 0x01, + /* ABS: 002 Pixels @ 329,111*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 331,111*/ 8, 0x03, + /* ABS: 002 Pixels @ 339,111*/ 0, 2, 0x04, 0x04, + /* RLE: 059 Pixels @ 341,111*/ 59, 0x01, + /* RLE: 032 Pixels @ 000,112*/ 32, 0x02, + /* RLE: 001 Pixels @ 032,112*/ 1, 0x04, + /* RLE: 006 Pixels @ 033,112*/ 6, 0x03, + /* RLE: 001 Pixels @ 039,112*/ 1, 0x04, + /* RLE: 013 Pixels @ 040,112*/ 13, 0x01, + /* ABS: 002 Pixels @ 053,112*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 055,112*/ 8, 0x03, + /* ABS: 002 Pixels @ 063,112*/ 0, 2, 0x04, 0x04, + /* RLE: 024 Pixels @ 065,112*/ 24, 0x00, + /* ABS: 016 Pixels @ 089,112*/ 0, 16, 0x03, 0x03, 0x00, 0x00, 0x03, 0x03, 0x04, 0x0C, 0x00, 0x11, 0x11, 0x03, 0x03, 0x0E, 0x0D, 0x03, + /* RLE: 058 Pixels @ 105,112*/ 58, 0x00, + /* ABS: 003 Pixels @ 163,112*/ 0, 3, 0x0B, 0x00, 0x0B, + /* RLE: 027 Pixels @ 166,112*/ 27, 0x00, + /* ABS: 004 Pixels @ 193,112*/ 0, 4, 0x0B, 0x00, 0x0B, 0x04, + /* RLE: 006 Pixels @ 197,112*/ 6, 0x03, + /* RLE: 001 Pixels @ 203,112*/ 1, 0x04, + /* RLE: 085 Pixels @ 204,112*/ 85, 0x00, + /* RLE: 004 Pixels @ 289,112*/ 4, 0x06, + /* RLE: 037 Pixels @ 293,112*/ 37, 0x01, + /* ABS: 002 Pixels @ 330,112*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 332,112*/ 9, 0x03, + /* ABS: 002 Pixels @ 341,112*/ 0, 2, 0x04, 0x04, + /* RLE: 057 Pixels @ 343,112*/ 57, 0x01, + /* RLE: 032 Pixels @ 000,113*/ 32, 0x02, + /* RLE: 001 Pixels @ 032,113*/ 1, 0x04, + /* RLE: 006 Pixels @ 033,113*/ 6, 0x03, + /* RLE: 001 Pixels @ 039,113*/ 1, 0x04, + /* RLE: 012 Pixels @ 040,113*/ 12, 0x01, + /* ABS: 002 Pixels @ 052,113*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 054,113*/ 8, 0x03, + /* ABS: 002 Pixels @ 062,113*/ 0, 2, 0x04, 0x04, + /* RLE: 024 Pixels @ 064,113*/ 24, 0x00, + /* ABS: 017 Pixels @ 088,113*/ 0, 17, 0x03, 0x0C, 0x00, 0x03, 0x03, 0x00, 0x0F, 0x08, 0x08, 0x0F, 0x00, 0x08, 0x11, 0x06, 0x08, 0x0B, 0x03, + /* RLE: 061 Pixels @ 105,113*/ 61, 0x00, + /* RLE: 001 Pixels @ 166,113*/ 1, 0x0B, + /* RLE: 029 Pixels @ 167,113*/ 29, 0x00, + /* RLE: 001 Pixels @ 196,113*/ 1, 0x04, + /* RLE: 006 Pixels @ 197,113*/ 6, 0x03, + /* RLE: 001 Pixels @ 203,113*/ 1, 0x04, + /* RLE: 086 Pixels @ 204,113*/ 86, 0x00, + /* ABS: 004 Pixels @ 290,113*/ 0, 4, 0x0D, 0x06, 0x03, 0x06, + /* RLE: 037 Pixels @ 294,113*/ 37, 0x01, + /* ABS: 002 Pixels @ 331,113*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 333,113*/ 9, 0x03, + /* ABS: 002 Pixels @ 342,113*/ 0, 2, 0x04, 0x04, + /* RLE: 056 Pixels @ 344,113*/ 56, 0x01, + /* RLE: 032 Pixels @ 000,114*/ 32, 0x02, + /* RLE: 001 Pixels @ 032,114*/ 1, 0x04, + /* RLE: 006 Pixels @ 033,114*/ 6, 0x03, + /* RLE: 001 Pixels @ 039,114*/ 1, 0x04, + /* RLE: 011 Pixels @ 040,114*/ 11, 0x01, + /* ABS: 002 Pixels @ 051,114*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 053,114*/ 8, 0x03, + /* ABS: 002 Pixels @ 061,114*/ 0, 2, 0x04, 0x04, + /* RLE: 026 Pixels @ 063,114*/ 26, 0x00, + /* ABS: 015 Pixels @ 089,114*/ 0, 15, 0x0F, 0x11, 0x03, 0x03, 0x11, 0x12, 0x03, 0x00, 0x0F, 0x11, 0x0B, 0x12, 0x12, 0x0B, 0x03, + /* RLE: 058 Pixels @ 104,114*/ 58, 0x00, + /* RLE: 001 Pixels @ 162,114*/ 1, 0x0B, + /* RLE: 033 Pixels @ 163,114*/ 33, 0x00, + /* RLE: 001 Pixels @ 196,114*/ 1, 0x04, + /* RLE: 007 Pixels @ 197,114*/ 7, 0x03, + /* RLE: 087 Pixels @ 204,114*/ 87, 0x00, + /* ABS: 004 Pixels @ 291,114*/ 0, 4, 0x06, 0x06, 0x03, 0x0D, + /* RLE: 037 Pixels @ 295,114*/ 37, 0x01, + /* ABS: 002 Pixels @ 332,114*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 334,114*/ 9, 0x03, + /* ABS: 002 Pixels @ 343,114*/ 0, 2, 0x04, 0x04, + /* RLE: 055 Pixels @ 345,114*/ 55, 0x01, + /* RLE: 032 Pixels @ 000,115*/ 32, 0x02, + /* RLE: 001 Pixels @ 032,115*/ 1, 0x04, + /* RLE: 006 Pixels @ 033,115*/ 6, 0x03, + /* RLE: 001 Pixels @ 039,115*/ 1, 0x04, + /* RLE: 010 Pixels @ 040,115*/ 10, 0x01, + /* ABS: 002 Pixels @ 050,115*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 052,115*/ 8, 0x03, + /* ABS: 002 Pixels @ 060,115*/ 0, 2, 0x04, 0x04, + /* RLE: 022 Pixels @ 062,115*/ 22, 0x00, + /* RLE: 005 Pixels @ 084,115*/ 5, 0x03, + /* ABS: 010 Pixels @ 089,115*/ 0, 10, 0x0B, 0x08, 0x12, 0x03, 0x08, 0x0C, 0x03, 0x03, 0x0C, 0x08, + /* RLE: 004 Pixels @ 099,115*/ 4, 0x03, + /* RLE: 061 Pixels @ 103,115*/ 61, 0x00, + /* ABS: 004 Pixels @ 164,115*/ 0, 4, 0x08, 0x00, 0x00, 0x0B, + /* RLE: 029 Pixels @ 168,115*/ 29, 0x00, + /* RLE: 001 Pixels @ 197,115*/ 1, 0x04, + /* RLE: 006 Pixels @ 198,115*/ 6, 0x03, + /* RLE: 001 Pixels @ 204,115*/ 1, 0x04, + /* RLE: 087 Pixels @ 205,115*/ 87, 0x00, + /* ABS: 004 Pixels @ 292,115*/ 0, 4, 0x0D, 0x06, 0x03, 0x06, + /* RLE: 037 Pixels @ 296,115*/ 37, 0x01, + /* ABS: 002 Pixels @ 333,115*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 335,115*/ 9, 0x03, + /* RLE: 001 Pixels @ 344,115*/ 1, 0x04, + /* RLE: 055 Pixels @ 345,115*/ 55, 0x01, + /* RLE: 032 Pixels @ 000,116*/ 32, 0x02, + /* RLE: 001 Pixels @ 032,116*/ 1, 0x04, + /* RLE: 007 Pixels @ 033,116*/ 7, 0x03, + /* RLE: 001 Pixels @ 040,116*/ 1, 0x04, + /* RLE: 007 Pixels @ 041,116*/ 7, 0x01, + /* ABS: 002 Pixels @ 048,116*/ 0, 2, 0x04, 0x04, + /* RLE: 010 Pixels @ 050,116*/ 10, 0x03, + /* ABS: 002 Pixels @ 060,116*/ 0, 2, 0x04, 0x04, + /* RLE: 022 Pixels @ 062,116*/ 22, 0x00, + /* ABS: 017 Pixels @ 084,116*/ 0, 17, 0x03, 0x04, 0x0C, 0x03, 0x03, 0x03, 0x0E, 0x08, 0x0C, 0x11, 0x11, 0x03, 0x03, 0x0E, 0x0F, 0x03, 0x04, + /* RLE: 062 Pixels @ 101,116*/ 62, 0x00, + /* ABS: 004 Pixels @ 163,116*/ 0, 4, 0x0B, 0x00, 0x08, 0x0B, + /* RLE: 029 Pixels @ 167,116*/ 29, 0x00, + /* ABS: 002 Pixels @ 196,116*/ 0, 2, 0x0B, 0x04, + /* RLE: 006 Pixels @ 198,116*/ 6, 0x03, + /* RLE: 001 Pixels @ 204,116*/ 1, 0x04, + /* RLE: 088 Pixels @ 205,116*/ 88, 0x00, + /* RLE: 005 Pixels @ 293,116*/ 5, 0x06, + /* RLE: 036 Pixels @ 298,116*/ 36, 0x01, + /* ABS: 002 Pixels @ 334,116*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 336,116*/ 9, 0x03, + /* RLE: 009 Pixels @ 345,116*/ 9, 0x0A, + /* RLE: 046 Pixels @ 354,116*/ 46, 0x01, + /* RLE: 033 Pixels @ 000,117*/ 33, 0x02, + /* RLE: 001 Pixels @ 033,117*/ 1, 0x04, + /* RLE: 006 Pixels @ 034,117*/ 6, 0x03, + /* RLE: 001 Pixels @ 040,117*/ 1, 0x04, + /* RLE: 005 Pixels @ 041,117*/ 5, 0x01, + /* RLE: 003 Pixels @ 046,117*/ 3, 0x04, + /* RLE: 013 Pixels @ 049,117*/ 13, 0x03, + /* ABS: 002 Pixels @ 062,117*/ 0, 2, 0x04, 0x04, + /* RLE: 020 Pixels @ 064,117*/ 20, 0x00, + /* ABS: 017 Pixels @ 084,117*/ 0, 17, 0x03, 0x0D, 0x08, 0x00, 0x03, 0x0C, 0x08, 0x0F, 0x08, 0x04, 0x08, 0x11, 0x06, 0x08, 0x04, 0x03, 0x0B, + /* RLE: 064 Pixels @ 101,117*/ 64, 0x00, + /* ABS: 003 Pixels @ 165,117*/ 0, 3, 0x08, 0x00, 0x0B, + /* RLE: 029 Pixels @ 168,117*/ 29, 0x00, + /* RLE: 001 Pixels @ 197,117*/ 1, 0x0B, + /* RLE: 007 Pixels @ 198,117*/ 7, 0x03, + /* RLE: 089 Pixels @ 205,117*/ 89, 0x00, + /* RLE: 001 Pixels @ 294,117*/ 1, 0x0D, + /* RLE: 004 Pixels @ 295,117*/ 4, 0x06, + /* RLE: 029 Pixels @ 299,117*/ 29, 0x01, + /* RLE: 016 Pixels @ 328,117*/ 16, 0x0A, + /* RLE: 010 Pixels @ 344,117*/ 10, 0x05, + /* RLE: 006 Pixels @ 354,117*/ 6, 0x0A, + /* RLE: 040 Pixels @ 360,117*/ 40, 0x01, + /* RLE: 033 Pixels @ 000,118*/ 33, 0x02, + /* RLE: 001 Pixels @ 033,118*/ 1, 0x04, + /* RLE: 007 Pixels @ 034,118*/ 7, 0x03, + /* ABS: 006 Pixels @ 041,118*/ 0, 6, 0x04, 0x01, 0x01, 0x04, 0x04, 0x04, + /* RLE: 018 Pixels @ 047,118*/ 18, 0x03, + /* ABS: 002 Pixels @ 065,118*/ 0, 2, 0x04, 0x04, + /* RLE: 017 Pixels @ 067,118*/ 17, 0x00, + /* ABS: 015 Pixels @ 084,118*/ 0, 15, 0x03, 0x00, 0x0F, 0x11, 0x06, 0x08, 0x0C, 0x00, 0x0F, 0x11, 0x0B, 0x12, 0x0E, 0x0B, 0x03, + /* RLE: 098 Pixels @ 099,118*/ 98, 0x00, + /* ABS: 002 Pixels @ 197,118*/ 0, 2, 0x0B, 0x04, + /* RLE: 006 Pixels @ 199,118*/ 6, 0x03, + /* RLE: 001 Pixels @ 205,118*/ 1, 0x04, + /* RLE: 089 Pixels @ 206,118*/ 89, 0x00, + /* ABS: 005 Pixels @ 295,118*/ 0, 5, 0x06, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 011 Pixels @ 300,118*/ 11, 0x01, + /* ABS: 003 Pixels @ 311,118*/ 0, 3, 0x00, 0x00, 0x0B, + /* RLE: 014 Pixels @ 314,118*/ 14, 0x0A, + /* ABS: 003 Pixels @ 328,118*/ 0, 3, 0x05, 0x05, 0x1A, + /* RLE: 005 Pixels @ 331,118*/ 5, 0x03, + /* ABS: 002 Pixels @ 336,118*/ 0, 2, 0x15, 0x15, + /* RLE: 004 Pixels @ 338,118*/ 4, 0x03, + /* RLE: 001 Pixels @ 342,118*/ 1, 0x19, + /* RLE: 017 Pixels @ 343,118*/ 17, 0x05, + /* RLE: 006 Pixels @ 360,118*/ 6, 0x0A, + /* RLE: 034 Pixels @ 366,118*/ 34, 0x01, + /* RLE: 033 Pixels @ 000,119*/ 33, 0x02, + /* ABS: 002 Pixels @ 033,119*/ 0, 2, 0x04, 0x04, + /* RLE: 006 Pixels @ 035,119*/ 6, 0x03, + /* ABS: 004 Pixels @ 041,119*/ 0, 4, 0x04, 0x01, 0x04, 0x04, + /* RLE: 022 Pixels @ 045,119*/ 22, 0x03, + /* ABS: 002 Pixels @ 067,119*/ 0, 2, 0x04, 0x04, + /* RLE: 014 Pixels @ 069,119*/ 14, 0x00, + /* ABS: 015 Pixels @ 083,119*/ 0, 15, 0x04, 0x0B, 0x03, 0x04, 0x08, 0x08, 0x00, 0x03, 0x03, 0x0B, 0x08, 0x0E, 0x03, 0x03, 0x03, + /* RLE: 068 Pixels @ 098,119*/ 68, 0x00, + /* ABS: 004 Pixels @ 166,119*/ 0, 4, 0x0B, 0x00, 0x00, 0x0B, + /* RLE: 028 Pixels @ 170,119*/ 28, 0x00, + /* RLE: 001 Pixels @ 198,119*/ 1, 0x04, + /* RLE: 006 Pixels @ 199,119*/ 6, 0x03, + /* RLE: 001 Pixels @ 205,119*/ 1, 0x04, + /* RLE: 068 Pixels @ 206,119*/ 68, 0x00, + /* ABS: 003 Pixels @ 274,119*/ 0, 3, 0x03, 0x00, 0x00, + /* RLE: 004 Pixels @ 277,119*/ 4, 0x03, + /* RLE: 016 Pixels @ 281,119*/ 16, 0x00, + /* RLE: 001 Pixels @ 297,119*/ 1, 0x0D, + /* RLE: 012 Pixels @ 298,119*/ 12, 0x0A, + /* ABS: 005 Pixels @ 310,119*/ 0, 5, 0x04, 0x03, 0x12, 0x03, 0x15, + /* RLE: 009 Pixels @ 315,119*/ 9, 0x03, + /* RLE: 001 Pixels @ 324,119*/ 1, 0x00, + /* RLE: 006 Pixels @ 325,119*/ 6, 0x03, + /* ABS: 013 Pixels @ 331,119*/ 0, 13, 0x00, 0x11, 0x08, 0x08, 0x0E, 0x03, 0x03, 0x06, 0x08, 0x0F, 0x04, 0x03, 0x1A, + /* RLE: 022 Pixels @ 344,119*/ 22, 0x05, + /* RLE: 006 Pixels @ 366,119*/ 6, 0x0A, + /* RLE: 028 Pixels @ 372,119*/ 28, 0x01, + /* RLE: 034 Pixels @ 000,120*/ 34, 0x02, + /* RLE: 001 Pixels @ 034,120*/ 1, 0x04, + /* RLE: 006 Pixels @ 035,120*/ 6, 0x03, + /* ABS: 002 Pixels @ 041,120*/ 0, 2, 0x04, 0x04, + /* RLE: 027 Pixels @ 043,120*/ 27, 0x03, + /* ABS: 002 Pixels @ 070,120*/ 0, 2, 0x04, 0x04, + /* RLE: 010 Pixels @ 072,120*/ 10, 0x00, + /* ABS: 013 Pixels @ 082,120*/ 0, 13, 0x04, 0x04, 0x03, 0x03, 0x03, 0x0E, 0x08, 0x0C, 0x03, 0x03, 0x03, 0x04, 0x03, + /* RLE: 073 Pixels @ 095,120*/ 73, 0x00, + /* RLE: 001 Pixels @ 168,120*/ 1, 0x0B, + /* RLE: 029 Pixels @ 169,120*/ 29, 0x00, + /* RLE: 001 Pixels @ 198,120*/ 1, 0x04, + /* RLE: 007 Pixels @ 199,120*/ 7, 0x03, + /* RLE: 061 Pixels @ 206,120*/ 61, 0x00, + /* RLE: 004 Pixels @ 267,120*/ 4, 0x03, + /* ABS: 015 Pixels @ 271,120*/ 0, 15, 0x00, 0x03, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x03, 0x0B, 0x03, 0x00, 0x03, 0x03, 0x00, + /* RLE: 012 Pixels @ 286,120*/ 12, 0x0A, + /* RLE: 006 Pixels @ 298,120*/ 6, 0x05, + /* RLE: 001 Pixels @ 304,120*/ 1, 0x1A, + /* RLE: 006 Pixels @ 305,120*/ 6, 0x03, + /* ABS: 033 Pixels @ 311,120*/ 0, 33, 0x0C, 0x08, 0x03, 0x03, 0x0C, 0x0E, 0x0D, 0x0F, 0x00, 0x06, 0x08, 0x08, 0x12, 0x03, 0x00, 0x11, 0x08, 0x08, 0x0E, 0x03, 0x06, 0x06, 0x03, 0x04, 0x0C, 0x03, 0x0E, 0x0F, 0x00, 0x0C, 0x08, 0x00, 0x15, + /* RLE: 028 Pixels @ 344,120*/ 28, 0x05, + /* RLE: 006 Pixels @ 372,120*/ 6, 0x0A, + /* RLE: 022 Pixels @ 378,120*/ 22, 0x01, + /* RLE: 034 Pixels @ 000,121*/ 34, 0x02, + /* RLE: 001 Pixels @ 034,121*/ 1, 0x04, + /* RLE: 018 Pixels @ 035,121*/ 18, 0x03, + /* RLE: 003 Pixels @ 053,121*/ 3, 0x04, + /* RLE: 016 Pixels @ 056,121*/ 16, 0x03, + /* ABS: 002 Pixels @ 072,121*/ 0, 2, 0x04, 0x04, + /* RLE: 006 Pixels @ 074,121*/ 6, 0x00, + /* RLE: 008 Pixels @ 080,121*/ 8, 0x03, + /* ABS: 007 Pixels @ 088,121*/ 0, 7, 0x0D, 0x08, 0x00, 0x03, 0x00, 0x00, 0x03, + /* RLE: 071 Pixels @ 095,121*/ 71, 0x00, + /* ABS: 005 Pixels @ 166,121*/ 0, 5, 0x0B, 0x08, 0x00, 0x00, 0x0B, + /* RLE: 028 Pixels @ 171,121*/ 28, 0x00, + /* RLE: 001 Pixels @ 199,121*/ 1, 0x04, + /* RLE: 006 Pixels @ 200,121*/ 6, 0x03, + /* RLE: 001 Pixels @ 206,121*/ 1, 0x04, + /* RLE: 061 Pixels @ 207,121*/ 61, 0x00, + /* ABS: 017 Pixels @ 268,121*/ 0, 17, 0x06, 0x08, 0x03, 0x0A, 0x03, 0x08, 0x12, 0x03, 0x0B, 0x0C, 0x0D, 0x00, 0x08, 0x0B, 0x03, 0x06, 0x06, + /* RLE: 006 Pixels @ 285,121*/ 6, 0x03, + /* ABS: 002 Pixels @ 291,121*/ 0, 2, 0x15, 0x15, + /* RLE: 004 Pixels @ 293,121*/ 4, 0x03, + /* ABS: 002 Pixels @ 297,121*/ 0, 2, 0x15, 0x00, + /* RLE: 006 Pixels @ 299,121*/ 6, 0x03, + /* ABS: 039 Pixels @ 305,121*/ 0, 39, 0x00, 0x11, 0x08, 0x08, 0x0E, 0x00, 0x11, 0x08, 0x0F, 0x03, 0x0C, 0x08, 0x0E, 0x0B, 0x0C, 0x06, 0x00, 0x0C, 0x08, 0x00, 0x06, 0x06, 0x03, 0x04, 0x04, 0x03, 0x0E, 0x08, 0x0F, 0x06, 0x04, 0x03, 0x06, 0x11, 0x0C, + 0x0C, 0x08, 0x0C, 0x00, + /* RLE: 034 Pixels @ 344,121*/ 34, 0x05, + /* RLE: 006 Pixels @ 378,121*/ 6, 0x0A, + /* RLE: 016 Pixels @ 384,121*/ 16, 0x01, + /* RLE: 035 Pixels @ 000,122*/ 35, 0x02, + /* RLE: 001 Pixels @ 035,122*/ 1, 0x04, + /* RLE: 016 Pixels @ 036,122*/ 16, 0x03, + /* ABS: 007 Pixels @ 052,122*/ 0, 7, 0x04, 0x04, 0x00, 0x00, 0x00, 0x04, 0x04, + /* RLE: 016 Pixels @ 059,122*/ 16, 0x03, + /* ABS: 008 Pixels @ 075,122*/ 0, 8, 0x04, 0x04, 0x00, 0x00, 0x03, 0x00, 0x0E, 0x0B, + /* RLE: 005 Pixels @ 083,122*/ 5, 0x03, + /* ABS: 005 Pixels @ 088,122*/ 0, 5, 0x00, 0x0F, 0x06, 0x03, 0x04, + /* RLE: 072 Pixels @ 093,122*/ 72, 0x00, + /* ABS: 005 Pixels @ 165,122*/ 0, 5, 0x0B, 0x00, 0x08, 0x00, 0x0B, + /* RLE: 028 Pixels @ 170,122*/ 28, 0x00, + /* ABS: 002 Pixels @ 198,122*/ 0, 2, 0x0B, 0x04, + /* RLE: 006 Pixels @ 200,122*/ 6, 0x03, + /* RLE: 001 Pixels @ 206,122*/ 1, 0x04, + /* RLE: 050 Pixels @ 207,122*/ 50, 0x00, + /* RLE: 010 Pixels @ 257,122*/ 10, 0x0A, + /* ABS: 008 Pixels @ 267,122*/ 0, 8, 0x03, 0x0E, 0x08, 0x03, 0x05, 0x03, 0x0F, 0x06, + /* RLE: 008 Pixels @ 275,122*/ 8, 0x03, + /* ABS: 061 Pixels @ 283,122*/ 0, 61, 0x0E, 0x11, 0x03, 0x00, 0x11, 0x08, 0x08, 0x0E, 0x03, 0x03, 0x06, 0x08, 0x0F, 0x04, 0x03, 0x04, 0x0E, 0x0E, 0x08, 0x0F, 0x0B, 0x03, 0x06, 0x06, 0x03, 0x04, 0x0C, 0x00, 0x06, 0x08, 0x00, 0x03, 0x0C, 0x08, 0x03, + 0x03, 0x03, 0x0B, 0x0E, 0x11, 0x08, 0x0B, 0x0E, 0x08, 0x0F, 0x06, 0x0C, 0x03, 0x03, 0x0B, 0x0E, 0x0D, 0x08, 0x0C, 0x06, 0x11, 0x0C, 0x00, 0x00, 0x00, 0x03, + /* RLE: 040 Pixels @ 344,122*/ 40, 0x05, + /* RLE: 004 Pixels @ 384,122*/ 4, 0x0A, + /* RLE: 012 Pixels @ 388,122*/ 12, 0x01, + /* RLE: 035 Pixels @ 000,123*/ 35, 0x02, + /* RLE: 001 Pixels @ 035,123*/ 1, 0x04, + /* RLE: 014 Pixels @ 036,123*/ 14, 0x03, + /* ABS: 003 Pixels @ 050,123*/ 0, 3, 0x04, 0x04, 0x0B, + /* RLE: 006 Pixels @ 053,123*/ 6, 0x00, + /* ABS: 002 Pixels @ 059,123*/ 0, 2, 0x04, 0x04, + /* RLE: 018 Pixels @ 061,123*/ 18, 0x03, + /* ABS: 005 Pixels @ 079,123*/ 0, 5, 0x0B, 0x08, 0x0F, 0x08, 0x00, + /* RLE: 005 Pixels @ 084,123*/ 5, 0x03, + /* ABS: 003 Pixels @ 089,123*/ 0, 3, 0x0B, 0x03, 0x03, + /* RLE: 076 Pixels @ 092,123*/ 76, 0x00, + /* ABS: 004 Pixels @ 168,123*/ 0, 4, 0x08, 0x00, 0x00, 0x0B, + /* RLE: 027 Pixels @ 172,123*/ 27, 0x00, + /* RLE: 001 Pixels @ 199,123*/ 1, 0x04, + /* RLE: 007 Pixels @ 200,123*/ 7, 0x03, + /* RLE: 046 Pixels @ 207,123*/ 46, 0x00, + /* RLE: 004 Pixels @ 253,123*/ 4, 0x0A, + /* RLE: 010 Pixels @ 257,123*/ 10, 0x05, + /* ABS: 077 Pixels @ 267,123*/ 0, 77, 0x03, 0x0C, 0x08, 0x03, 0x03, 0x03, 0x0D, 0x06, 0x03, 0x0C, 0x06, 0x03, 0x03, 0x08, 0x0E, 0x03, 0x0C, 0x08, 0x03, 0x06, 0x06, 0x03, 0x04, 0x04, 0x03, 0x0E, 0x0F, 0x00, 0x0C, 0x08, 0x00, 0x0C, 0x08, 0x0C, 0x00, + 0x0F, 0x12, 0x03, 0x0E, 0x08, 0x0F, 0x06, 0x04, 0x03, 0x0B, 0x08, 0x0B, 0x03, 0x0C, 0x08, 0x03, 0x03, 0x0C, 0x0F, 0x04, 0x04, 0x08, 0x00, 0x03, 0x04, 0x0E, 0x0D, 0x08, 0x0C, 0x0C, 0x0D, 0x00, 0x04, 0x08, 0x04, 0x0C, 0x08, 0x0B, 0x0C, 0x08, 0x04, + 0x15, + /* RLE: 044 Pixels @ 344,123*/ 44, 0x05, + /* ABS: 002 Pixels @ 388,123*/ 0, 2, 0x0A, 0x0A, + /* RLE: 010 Pixels @ 390,123*/ 10, 0x01, + /* RLE: 036 Pixels @ 000,124*/ 36, 0x02, + /* RLE: 001 Pixels @ 036,124*/ 1, 0x04, + /* RLE: 011 Pixels @ 037,124*/ 11, 0x03, + /* ABS: 002 Pixels @ 048,124*/ 0, 2, 0x04, 0x04, + /* RLE: 012 Pixels @ 050,124*/ 12, 0x00, + /* ABS: 002 Pixels @ 062,124*/ 0, 2, 0x04, 0x04, + /* RLE: 013 Pixels @ 064,124*/ 13, 0x03, + /* ABS: 007 Pixels @ 077,124*/ 0, 7, 0x00, 0x0C, 0x06, 0x04, 0x03, 0x11, 0x11, + /* RLE: 004 Pixels @ 084,124*/ 4, 0x03, + /* RLE: 082 Pixels @ 088,124*/ 82, 0x00, + /* RLE: 001 Pixels @ 170,124*/ 1, 0x0B, + /* RLE: 029 Pixels @ 171,124*/ 29, 0x00, + /* RLE: 001 Pixels @ 200,124*/ 1, 0x04, + /* RLE: 006 Pixels @ 201,124*/ 6, 0x03, + /* RLE: 001 Pixels @ 207,124*/ 1, 0x04, + /* RLE: 041 Pixels @ 208,124*/ 41, 0x00, + /* RLE: 004 Pixels @ 249,124*/ 4, 0x0A, + /* RLE: 014 Pixels @ 253,124*/ 14, 0x05, + /* ABS: 002 Pixels @ 267,124*/ 0, 2, 0x03, 0x0C, + /* RLE: 005 Pixels @ 269,124*/ 5, 0x08, + /* ABS: 070 Pixels @ 274,124*/ 0, 70, 0x06, 0x03, 0x0C, 0x08, 0x03, 0x03, 0x06, 0x06, 0x03, 0x0C, 0x08, 0x03, 0x0E, 0x08, 0x0F, 0x06, 0x0C, 0x03, 0x06, 0x11, 0x0C, 0x0C, 0x08, 0x0C, 0x0C, 0x08, 0x03, 0x03, 0x06, 0x06, 0x03, 0x03, 0x0B, 0x0E, 0x0D, + 0x08, 0x04, 0x0B, 0x08, 0x00, 0x03, 0x04, 0x08, 0x0B, 0x03, 0x12, 0x11, 0x00, 0x0E, 0x08, 0x0B, 0x0C, 0x0D, 0x00, 0x0B, 0x08, 0x04, 0x00, 0x12, 0x08, 0x11, 0x0C, 0x03, 0x03, 0x0E, 0x0F, 0x11, 0x0C, 0x03, 0x19, + /* RLE: 046 Pixels @ 344,124*/ 46, 0x05, + /* RLE: 006 Pixels @ 390,124*/ 6, 0x0A, + /* RLE: 004 Pixels @ 396,124*/ 4, 0x01, + /* RLE: 035 Pixels @ 000,125*/ 35, 0x02, + /* ABS: 002 Pixels @ 035,125*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 037,125*/ 9, 0x03, + /* RLE: 003 Pixels @ 046,125*/ 3, 0x04, + /* RLE: 001 Pixels @ 049,125*/ 1, 0x0B, + /* RLE: 014 Pixels @ 050,125*/ 14, 0x00, + /* ABS: 002 Pixels @ 064,125*/ 0, 2, 0x04, 0x04, + /* RLE: 011 Pixels @ 066,125*/ 11, 0x03, + /* ABS: 013 Pixels @ 077,125*/ 0, 13, 0x0F, 0x08, 0x08, 0x0C, 0x03, 0x00, 0x08, 0x12, 0x03, 0x03, 0x04, 0x04, 0x0B, + /* RLE: 079 Pixels @ 090,125*/ 79, 0x00, + /* RLE: 001 Pixels @ 169,125*/ 1, 0x0B, + /* RLE: 030 Pixels @ 170,125*/ 30, 0x00, + /* RLE: 001 Pixels @ 200,125*/ 1, 0x04, + /* RLE: 010 Pixels @ 201,125*/ 10, 0x03, + /* RLE: 034 Pixels @ 211,125*/ 34, 0x00, + /* RLE: 004 Pixels @ 245,125*/ 4, 0x0A, + /* RLE: 018 Pixels @ 249,125*/ 18, 0x05, + /* ABS: 063 Pixels @ 267,125*/ 0, 63, 0x03, 0x0C, 0x08, 0x0E, 0x0B, 0x0B, 0x0D, 0x0F, 0x03, 0x0C, 0x08, 0x03, 0x03, 0x06, 0x06, 0x03, 0x0C, 0x08, 0x03, 0x03, 0x0B, 0x0E, 0x0D, 0x08, 0x0C, 0x06, 0x11, 0x0C, 0x00, 0x0B, 0x00, 0x04, 0x08, 0x00, 0x03, + 0x06, 0x06, 0x03, 0x0C, 0x0D, 0x00, 0x04, 0x08, 0x04, 0x00, 0x08, 0x0C, 0x00, 0x0B, 0x08, 0x00, 0x03, 0x00, 0x11, 0x0F, 0x0E, 0x12, 0x0C, 0x00, 0x12, 0x08, 0x11, 0x0C, + /* RLE: 006 Pixels @ 330,125*/ 6, 0x03, + /* ABS: 002 Pixels @ 336,125*/ 0, 2, 0x15, 0x15, + /* RLE: 004 Pixels @ 338,125*/ 4, 0x03, + /* RLE: 001 Pixels @ 342,125*/ 1, 0x15, + /* RLE: 053 Pixels @ 343,125*/ 53, 0x05, + /* RLE: 004 Pixels @ 396,125*/ 4, 0x0A, + /* RLE: 034 Pixels @ 000,126*/ 34, 0x02, + /* ABS: 002 Pixels @ 034,126*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 036,126*/ 9, 0x03, + /* ABS: 002 Pixels @ 045,126*/ 0, 2, 0x04, 0x04, + /* RLE: 020 Pixels @ 047,126*/ 20, 0x00, + /* ABS: 021 Pixels @ 067,126*/ 0, 21, 0x04, 0x04, 0x03, 0x03, 0x03, 0x0C, 0x04, 0x03, 0x0C, 0x06, 0x0E, 0x03, 0x0D, 0x0F, 0x00, 0x03, 0x0C, 0x0F, 0x00, 0x00, 0x04, + /* RLE: 079 Pixels @ 088,126*/ 79, 0x00, + /* ABS: 005 Pixels @ 167,126*/ 0, 5, 0x0B, 0x00, 0x00, 0x00, 0x0B, + /* RLE: 027 Pixels @ 172,126*/ 27, 0x00, + /* ABS: 002 Pixels @ 199,126*/ 0, 2, 0x0B, 0x04, + /* RLE: 005 Pixels @ 201,126*/ 5, 0x03, + /* ABS: 005 Pixels @ 206,126*/ 0, 5, 0x00, 0x0B, 0x0C, 0x06, 0x03, + /* RLE: 029 Pixels @ 211,126*/ 29, 0x00, + /* RLE: 005 Pixels @ 240,126*/ 5, 0x0A, + /* RLE: 022 Pixels @ 245,126*/ 22, 0x05, + /* ABS: 052 Pixels @ 267,126*/ 0, 52, 0x03, 0x0B, 0x08, 0x0B, 0x03, 0x03, 0x0E, 0x08, 0x03, 0x0C, 0x08, 0x00, 0x03, 0x06, 0x06, 0x03, 0x0B, 0x08, 0x00, 0x0C, 0x0D, 0x00, 0x0B, 0x08, 0x04, 0x0C, 0x08, 0x0B, 0x0C, 0x08, 0x04, 0x00, 0x08, 0x0B, 0x03, + 0x0E, 0x08, 0x03, 0x00, 0x12, 0x08, 0x11, 0x0C, 0x03, 0x03, 0x0D, 0x08, 0x04, 0x03, 0x03, 0x03, 0x15, + /* RLE: 011 Pixels @ 319,126*/ 11, 0x03, + /* RLE: 001 Pixels @ 330,126*/ 1, 0x15, + /* RLE: 013 Pixels @ 331,126*/ 13, 0x05, + /* RLE: 005 Pixels @ 344,126*/ 5, 0x0A, + /* RLE: 005 Pixels @ 349,126*/ 5, 0x03, + /* RLE: 046 Pixels @ 354,126*/ 46, 0x05, + /* RLE: 034 Pixels @ 000,127*/ 34, 0x02, + /* RLE: 001 Pixels @ 034,127*/ 1, 0x04, + /* RLE: 008 Pixels @ 035,127*/ 8, 0x03, + /* ABS: 002 Pixels @ 043,127*/ 0, 2, 0x04, 0x04, + /* RLE: 024 Pixels @ 045,127*/ 24, 0x00, + /* ABS: 017 Pixels @ 069,127*/ 0, 17, 0x04, 0x04, 0x03, 0x11, 0x0F, 0x00, 0x0C, 0x08, 0x0E, 0x03, 0x00, 0x0F, 0x0D, 0x03, 0x03, 0x00, 0x03, + /* RLE: 083 Pixels @ 086,127*/ 83, 0x00, + /* RLE: 001 Pixels @ 169,127*/ 1, 0x08, + /* RLE: 031 Pixels @ 170,127*/ 31, 0x00, + /* ABS: 009 Pixels @ 201,127*/ 0, 9, 0x03, 0x00, 0x0C, 0x06, 0x0F, 0x08, 0x08, 0x08, 0x0F, + /* RLE: 026 Pixels @ 210,127*/ 26, 0x00, + /* RLE: 004 Pixels @ 236,127*/ 4, 0x0A, + /* RLE: 027 Pixels @ 240,127*/ 27, 0x05, + /* ABS: 039 Pixels @ 267,127*/ 0, 39, 0x00, 0x0B, 0x08, 0x0B, 0x00, 0x03, 0x0C, 0x08, 0x03, 0x0B, 0x08, 0x0C, 0x0B, 0x0F, 0x11, 0x03, 0x0B, 0x08, 0x0B, 0x00, 0x12, 0x08, 0x11, 0x0C, 0x03, 0x03, 0x0E, 0x0F, 0x11, 0x0C, 0x03, 0x0B, 0x0F, 0x00, 0x03, + 0x04, 0x12, 0x03, 0x00, + /* RLE: 004 Pixels @ 306,127*/ 4, 0x03, + /* ABS: 006 Pixels @ 310,127*/ 0, 6, 0x15, 0x00, 0x03, 0x03, 0x03, 0x19, + /* RLE: 012 Pixels @ 316,127*/ 12, 0x05, + /* RLE: 016 Pixels @ 328,127*/ 16, 0x0A, + /* RLE: 005 Pixels @ 344,127*/ 5, 0x01, + /* RLE: 001 Pixels @ 349,127*/ 1, 0x04, + /* RLE: 008 Pixels @ 350,127*/ 8, 0x03, + /* ABS: 002 Pixels @ 358,127*/ 0, 2, 0x0A, 0x0A, + /* RLE: 040 Pixels @ 360,127*/ 40, 0x05, + /* RLE: 034 Pixels @ 000,128*/ 34, 0x02, + /* RLE: 001 Pixels @ 034,128*/ 1, 0x04, + /* RLE: 007 Pixels @ 035,128*/ 7, 0x03, + /* RLE: 001 Pixels @ 042,128*/ 1, 0x04, + /* RLE: 027 Pixels @ 043,128*/ 27, 0x00, + /* ABS: 013 Pixels @ 070,128*/ 0, 13, 0x0B, 0x03, 0x00, 0x08, 0x0D, 0x03, 0x06, 0x08, 0x00, 0x03, 0x04, 0x08, 0x04, + /* RLE: 085 Pixels @ 083,128*/ 85, 0x00, + /* ABS: 006 Pixels @ 168,128*/ 0, 6, 0x0B, 0x00, 0x08, 0x0B, 0x00, 0x0B, + /* RLE: 024 Pixels @ 174,128*/ 24, 0x00, + /* ABS: 013 Pixels @ 198,128*/ 0, 13, 0x0B, 0x00, 0x0B, 0x03, 0x12, 0x08, 0x0F, 0x06, 0x0C, 0x0B, 0x00, 0x03, 0x03, + /* RLE: 021 Pixels @ 211,128*/ 21, 0x00, + /* RLE: 004 Pixels @ 232,128*/ 4, 0x0A, + /* RLE: 031 Pixels @ 236,128*/ 31, 0x05, + /* ABS: 019 Pixels @ 267,128*/ 0, 19, 0x15, 0x0B, 0x08, 0x0B, 0x15, 0x00, 0x0B, 0x0C, 0x03, 0x03, 0x12, 0x08, 0x06, 0x0C, 0x12, 0x03, 0x0B, 0x0F, 0x00, + /* RLE: 005 Pixels @ 286,128*/ 5, 0x03, + /* ABS: 002 Pixels @ 291,128*/ 0, 2, 0x15, 0x15, + /* RLE: 004 Pixels @ 293,128*/ 4, 0x03, + /* ABS: 008 Pixels @ 297,128*/ 0, 8, 0x15, 0x03, 0x03, 0x03, 0x15, 0x03, 0x00, 0x15, + /* RLE: 008 Pixels @ 305,128*/ 8, 0x05, + /* RLE: 015 Pixels @ 313,128*/ 15, 0x0A, + /* RLE: 021 Pixels @ 328,128*/ 21, 0x01, + /* ABS: 002 Pixels @ 349,128*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 351,128*/ 8, 0x03, + /* RLE: 001 Pixels @ 359,128*/ 1, 0x04, + /* RLE: 006 Pixels @ 360,128*/ 6, 0x0A, + /* RLE: 034 Pixels @ 366,128*/ 34, 0x05, + /* RLE: 033 Pixels @ 000,129*/ 33, 0x02, + /* ABS: 002 Pixels @ 033,129*/ 0, 2, 0x04, 0x04, + /* RLE: 006 Pixels @ 035,129*/ 6, 0x03, + /* ABS: 003 Pixels @ 041,129*/ 0, 3, 0x04, 0x04, 0x0B, + /* RLE: 028 Pixels @ 044,129*/ 28, 0x00, + /* ABS: 013 Pixels @ 072,129*/ 0, 13, 0x03, 0x04, 0x08, 0x0E, 0x03, 0x0F, 0x11, 0x03, 0x03, 0x0B, 0x03, 0x00, 0x0B, + /* RLE: 085 Pixels @ 085,129*/ 85, 0x00, + /* ABS: 003 Pixels @ 170,129*/ 0, 3, 0x08, 0x00, 0x0B, + /* RLE: 028 Pixels @ 173,129*/ 28, 0x00, + /* ABS: 008 Pixels @ 201,129*/ 0, 8, 0x03, 0x00, 0x00, 0x03, 0x03, 0x00, 0x04, 0x03, + /* RLE: 019 Pixels @ 209,129*/ 19, 0x00, + /* RLE: 004 Pixels @ 228,129*/ 4, 0x0A, + /* RLE: 035 Pixels @ 232,129*/ 35, 0x05, + /* ABS: 010 Pixels @ 267,129*/ 0, 10, 0x19, 0x03, 0x03, 0x03, 0x19, 0x19, 0x00, 0x00, 0x15, 0x15, + /* RLE: 005 Pixels @ 277,129*/ 5, 0x03, + /* ABS: 005 Pixels @ 282,129*/ 0, 5, 0x00, 0x03, 0x03, 0x03, 0x1A, + /* RLE: 011 Pixels @ 287,129*/ 11, 0x05, + /* RLE: 015 Pixels @ 298,129*/ 15, 0x0A, + /* RLE: 036 Pixels @ 313,129*/ 36, 0x01, + /* RLE: 003 Pixels @ 349,129*/ 3, 0x04, + /* RLE: 008 Pixels @ 352,129*/ 8, 0x03, + /* RLE: 003 Pixels @ 360,129*/ 3, 0x04, + /* RLE: 003 Pixels @ 363,129*/ 3, 0x01, + /* RLE: 006 Pixels @ 366,129*/ 6, 0x0A, + /* RLE: 028 Pixels @ 372,129*/ 28, 0x05, + /* RLE: 034 Pixels @ 000,130*/ 34, 0x02, + /* RLE: 001 Pixels @ 034,130*/ 1, 0x04, + /* RLE: 006 Pixels @ 035,130*/ 6, 0x03, + /* RLE: 001 Pixels @ 041,130*/ 1, 0x04, + /* RLE: 030 Pixels @ 042,130*/ 30, 0x00, + /* ABS: 012 Pixels @ 072,130*/ 0, 12, 0x03, 0x03, 0x12, 0x08, 0x04, 0x0B, 0x08, 0x0C, 0x03, 0x03, 0x03, 0x04, + /* RLE: 116 Pixels @ 084,130*/ 116, 0x00, + /* ABS: 010 Pixels @ 200,130*/ 0, 10, 0x0B, 0x03, 0x04, 0x0E, 0x0D, 0x08, 0x08, 0x08, 0x03, 0x0B, + /* RLE: 013 Pixels @ 210,130*/ 13, 0x00, + /* RLE: 005 Pixels @ 223,130*/ 5, 0x0A, + /* RLE: 054 Pixels @ 228,130*/ 54, 0x05, + /* RLE: 016 Pixels @ 282,130*/ 16, 0x0A, + /* RLE: 005 Pixels @ 298,130*/ 5, 0x00, + /* ABS: 011 Pixels @ 303,130*/ 0, 11, 0x0D, 0x03, 0x06, 0x00, 0x00, 0x00, 0x06, 0x06, 0x03, 0x06, 0x06, + /* RLE: 037 Pixels @ 314,130*/ 37, 0x01, + /* ABS: 002 Pixels @ 351,130*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 353,130*/ 9, 0x03, + /* ABS: 002 Pixels @ 362,130*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 364,130*/ 8, 0x01, + /* RLE: 006 Pixels @ 372,130*/ 6, 0x0A, + /* RLE: 022 Pixels @ 378,130*/ 22, 0x05, + /* RLE: 034 Pixels @ 000,131*/ 34, 0x02, + /* RLE: 001 Pixels @ 034,131*/ 1, 0x04, + /* RLE: 006 Pixels @ 035,131*/ 6, 0x03, + /* ABS: 002 Pixels @ 041,131*/ 0, 2, 0x04, 0x0B, + /* RLE: 030 Pixels @ 043,131*/ 30, 0x00, + /* ABS: 006 Pixels @ 073,131*/ 0, 6, 0x03, 0x03, 0x11, 0x0F, 0x00, 0x0B, + /* RLE: 004 Pixels @ 079,131*/ 4, 0x03, + /* ABS: 002 Pixels @ 083,131*/ 0, 2, 0x04, 0x0B, + /* RLE: 116 Pixels @ 085,131*/ 116, 0x00, + /* ABS: 009 Pixels @ 201,131*/ 0, 9, 0x03, 0x12, 0x08, 0x06, 0x0E, 0x0E, 0x0D, 0x00, 0x03, + /* RLE: 009 Pixels @ 210,131*/ 9, 0x00, + /* RLE: 004 Pixels @ 219,131*/ 4, 0x0A, + /* RLE: 044 Pixels @ 223,131*/ 44, 0x05, + /* RLE: 015 Pixels @ 267,131*/ 15, 0x0A, + /* RLE: 021 Pixels @ 282,131*/ 21, 0x00, + /* ABS: 004 Pixels @ 303,131*/ 0, 4, 0x0D, 0x0D, 0x06, 0x06, + /* RLE: 004 Pixels @ 307,131*/ 4, 0x00, + /* ABS: 004 Pixels @ 311,131*/ 0, 4, 0x06, 0x03, 0x06, 0x06, + /* RLE: 037 Pixels @ 315,131*/ 37, 0x01, + /* ABS: 002 Pixels @ 352,131*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 354,131*/ 9, 0x03, + /* ABS: 002 Pixels @ 363,131*/ 0, 2, 0x04, 0x04, + /* RLE: 013 Pixels @ 365,131*/ 13, 0x01, + /* RLE: 006 Pixels @ 378,131*/ 6, 0x0A, + /* RLE: 016 Pixels @ 384,131*/ 16, 0x05, + /* RLE: 034 Pixels @ 000,132*/ 34, 0x02, + /* RLE: 001 Pixels @ 034,132*/ 1, 0x04, + /* RLE: 006 Pixels @ 035,132*/ 6, 0x03, + /* RLE: 001 Pixels @ 041,132*/ 1, 0x04, + /* RLE: 032 Pixels @ 042,132*/ 32, 0x00, + /* ABS: 004 Pixels @ 074,132*/ 0, 4, 0x03, 0x00, 0x08, 0x12, + /* RLE: 005 Pixels @ 078,132*/ 5, 0x03, + /* ABS: 003 Pixels @ 083,132*/ 0, 3, 0x04, 0x00, 0x0B, + /* RLE: 084 Pixels @ 086,132*/ 84, 0x00, + /* ABS: 004 Pixels @ 170,132*/ 0, 4, 0x0B, 0x00, 0x00, 0x0B, + /* RLE: 026 Pixels @ 174,132*/ 26, 0x00, + /* RLE: 001 Pixels @ 200,132*/ 1, 0x0B, + /* RLE: 006 Pixels @ 201,132*/ 6, 0x03, + /* ABS: 003 Pixels @ 207,132*/ 0, 3, 0x06, 0x0E, 0x03, + /* RLE: 005 Pixels @ 210,132*/ 5, 0x00, + /* RLE: 004 Pixels @ 215,132*/ 4, 0x0A, + /* RLE: 038 Pixels @ 219,132*/ 38, 0x05, + /* RLE: 010 Pixels @ 257,132*/ 10, 0x0A, + /* RLE: 037 Pixels @ 267,132*/ 37, 0x00, + /* RLE: 003 Pixels @ 304,132*/ 3, 0x06, + /* RLE: 005 Pixels @ 307,132*/ 5, 0x00, + /* RLE: 004 Pixels @ 312,132*/ 4, 0x06, + /* RLE: 037 Pixels @ 316,132*/ 37, 0x01, + /* ABS: 002 Pixels @ 353,132*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 355,132*/ 9, 0x03, + /* ABS: 002 Pixels @ 364,132*/ 0, 2, 0x04, 0x04, + /* RLE: 018 Pixels @ 366,132*/ 18, 0x01, + /* RLE: 004 Pixels @ 384,132*/ 4, 0x0A, + /* RLE: 012 Pixels @ 388,132*/ 12, 0x05, + /* RLE: 034 Pixels @ 000,133*/ 34, 0x02, + /* RLE: 001 Pixels @ 034,133*/ 1, 0x04, + /* RLE: 006 Pixels @ 035,133*/ 6, 0x03, + /* ABS: 003 Pixels @ 041,133*/ 0, 3, 0x04, 0x00, 0x0B, + /* RLE: 031 Pixels @ 044,133*/ 31, 0x00, + /* ABS: 002 Pixels @ 075,133*/ 0, 2, 0x03, 0x0B, + /* RLE: 006 Pixels @ 077,133*/ 6, 0x03, + /* ABS: 002 Pixels @ 083,133*/ 0, 2, 0x04, 0x04, + /* RLE: 086 Pixels @ 085,133*/ 86, 0x00, + /* ABS: 004 Pixels @ 171,133*/ 0, 4, 0x0B, 0x08, 0x00, 0x0B, + /* RLE: 026 Pixels @ 175,133*/ 26, 0x00, + /* ABS: 010 Pixels @ 201,133*/ 0, 10, 0x0B, 0x03, 0x03, 0x00, 0x0C, 0x0E, 0x0F, 0x0E, 0x03, 0x04, + /* RLE: 004 Pixels @ 211,133*/ 4, 0x0A, + /* RLE: 038 Pixels @ 215,133*/ 38, 0x05, + /* RLE: 004 Pixels @ 253,133*/ 4, 0x0A, + /* RLE: 047 Pixels @ 257,133*/ 47, 0x00, + /* ABS: 003 Pixels @ 304,133*/ 0, 3, 0x0D, 0x06, 0x06, + /* RLE: 006 Pixels @ 307,133*/ 6, 0x00, + /* RLE: 005 Pixels @ 313,133*/ 5, 0x06, + /* RLE: 036 Pixels @ 318,133*/ 36, 0x01, + /* ABS: 002 Pixels @ 354,133*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 356,133*/ 9, 0x03, + /* ABS: 002 Pixels @ 365,133*/ 0, 2, 0x04, 0x04, + /* RLE: 021 Pixels @ 367,133*/ 21, 0x01, + /* ABS: 002 Pixels @ 388,133*/ 0, 2, 0x0A, 0x0A, + /* RLE: 010 Pixels @ 390,133*/ 10, 0x05, + /* RLE: 034 Pixels @ 000,134*/ 34, 0x02, + /* RLE: 001 Pixels @ 034,134*/ 1, 0x04, + /* RLE: 006 Pixels @ 035,134*/ 6, 0x03, + /* ABS: 002 Pixels @ 041,134*/ 0, 2, 0x04, 0x0B, + /* RLE: 034 Pixels @ 043,134*/ 34, 0x00, + /* RLE: 007 Pixels @ 077,134*/ 7, 0x03, + /* ABS: 003 Pixels @ 084,134*/ 0, 3, 0x04, 0x04, 0x0B, + /* RLE: 083 Pixels @ 087,134*/ 83, 0x00, + /* ABS: 033 Pixels @ 170,134*/ 0, 33, 0x0B, 0x00, 0x08, 0x00, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x00, 0x03, + /* RLE: 005 Pixels @ 203,134*/ 5, 0x08, + /* ABS: 003 Pixels @ 208,134*/ 0, 3, 0x0B, 0x03, 0x06, + /* RLE: 038 Pixels @ 211,134*/ 38, 0x05, + /* RLE: 004 Pixels @ 249,134*/ 4, 0x0A, + /* RLE: 051 Pixels @ 253,134*/ 51, 0x00, + /* ABS: 003 Pixels @ 304,134*/ 0, 3, 0x06, 0x03, 0x06, + /* RLE: 007 Pixels @ 307,134*/ 7, 0x00, + /* ABS: 005 Pixels @ 314,134*/ 0, 5, 0x06, 0x06, 0x03, 0x06, 0x06, + /* RLE: 036 Pixels @ 319,134*/ 36, 0x01, + /* ABS: 002 Pixels @ 355,134*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 357,134*/ 9, 0x03, + /* ABS: 002 Pixels @ 366,134*/ 0, 2, 0x04, 0x04, + /* RLE: 022 Pixels @ 368,134*/ 22, 0x01, + /* RLE: 006 Pixels @ 390,134*/ 6, 0x0A, + /* RLE: 004 Pixels @ 396,134*/ 4, 0x05, + /* RLE: 035 Pixels @ 000,135*/ 35, 0x02, + /* RLE: 007 Pixels @ 035,135*/ 7, 0x03, + /* RLE: 001 Pixels @ 042,135*/ 1, 0x04, + /* RLE: 034 Pixels @ 043,135*/ 34, 0x00, + /* RLE: 001 Pixels @ 077,135*/ 1, 0x04, + /* RLE: 007 Pixels @ 078,135*/ 7, 0x03, + /* ABS: 003 Pixels @ 085,135*/ 0, 3, 0x04, 0x04, 0x0B, + /* RLE: 085 Pixels @ 088,135*/ 85, 0x00, + /* ABS: 038 Pixels @ 173,135*/ 0, 38, 0x08, 0x00, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x03, 0x0E, 0x04, 0x00, 0x03, 0x00, + 0x08, 0x00, 0x15, + /* RLE: 034 Pixels @ 211,135*/ 34, 0x05, + /* RLE: 004 Pixels @ 245,135*/ 4, 0x0A, + /* RLE: 055 Pixels @ 249,135*/ 55, 0x00, + /* ABS: 003 Pixels @ 304,135*/ 0, 3, 0x0D, 0x03, 0x06, + /* RLE: 008 Pixels @ 307,135*/ 8, 0x00, + /* ABS: 005 Pixels @ 315,135*/ 0, 5, 0x06, 0x06, 0x03, 0x06, 0x06, + /* RLE: 037 Pixels @ 320,135*/ 37, 0x01, + /* ABS: 002 Pixels @ 357,135*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 359,135*/ 9, 0x03, + /* ABS: 002 Pixels @ 368,135*/ 0, 2, 0x04, 0x04, + /* RLE: 026 Pixels @ 370,135*/ 26, 0x01, + /* RLE: 004 Pixels @ 396,135*/ 4, 0x0A, + /* RLE: 035 Pixels @ 000,136*/ 35, 0x02, + /* RLE: 001 Pixels @ 035,136*/ 1, 0x04, + /* RLE: 006 Pixels @ 036,136*/ 6, 0x03, + /* RLE: 001 Pixels @ 042,136*/ 1, 0x04, + /* RLE: 033 Pixels @ 043,136*/ 33, 0x00, + /* ABS: 002 Pixels @ 076,136*/ 0, 2, 0x0B, 0x04, + /* RLE: 008 Pixels @ 078,136*/ 8, 0x03, + /* ABS: 003 Pixels @ 086,136*/ 0, 3, 0x04, 0x00, 0x0B, + /* RLE: 086 Pixels @ 089,136*/ 86, 0x00, + /* RLE: 001 Pixels @ 175,136*/ 1, 0x0B, + /* RLE: 023 Pixels @ 176,136*/ 23, 0x00, + /* RLE: 003 Pixels @ 199,136*/ 3, 0x0A, + /* RLE: 001 Pixels @ 202,136*/ 1, 0x00, + /* RLE: 004 Pixels @ 203,136*/ 4, 0x03, + /* ABS: 004 Pixels @ 207,136*/ 0, 4, 0x0B, 0x08, 0x00, 0x15, + /* RLE: 029 Pixels @ 211,136*/ 29, 0x05, + /* RLE: 005 Pixels @ 240,136*/ 5, 0x0A, + /* RLE: 059 Pixels @ 245,136*/ 59, 0x00, + /* ABS: 003 Pixels @ 304,136*/ 0, 3, 0x06, 0x03, 0x06, + /* RLE: 010 Pixels @ 307,136*/ 10, 0x00, + /* ABS: 004 Pixels @ 317,136*/ 0, 4, 0x06, 0x03, 0x06, 0x06, + /* RLE: 037 Pixels @ 321,136*/ 37, 0x01, + /* ABS: 002 Pixels @ 358,136*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 360,136*/ 9, 0x03, + /* ABS: 002 Pixels @ 369,136*/ 0, 2, 0x04, 0x04, + /* RLE: 029 Pixels @ 371,136*/ 29, 0x01, + /* RLE: 035 Pixels @ 000,137*/ 35, 0x02, + /* RLE: 001 Pixels @ 035,137*/ 1, 0x04, + /* RLE: 006 Pixels @ 036,137*/ 6, 0x03, + /* ABS: 003 Pixels @ 042,137*/ 0, 3, 0x04, 0x00, 0x0B, + /* RLE: 032 Pixels @ 045,137*/ 32, 0x00, + /* ABS: 002 Pixels @ 077,137*/ 0, 2, 0x0B, 0x04, + /* RLE: 008 Pixels @ 079,137*/ 8, 0x03, + /* ABS: 003 Pixels @ 087,137*/ 0, 3, 0x04, 0x00, 0x0B, + /* RLE: 084 Pixels @ 090,137*/ 84, 0x00, + /* RLE: 001 Pixels @ 174,137*/ 1, 0x0B, + /* RLE: 020 Pixels @ 175,137*/ 20, 0x00, + /* RLE: 004 Pixels @ 195,137*/ 4, 0x0A, + /* RLE: 003 Pixels @ 199,137*/ 3, 0x05, + /* ABS: 009 Pixels @ 202,137*/ 0, 9, 0x15, 0x00, 0x0E, 0x0D, 0x08, 0x08, 0x0F, 0x00, 0x15, + /* RLE: 025 Pixels @ 211,137*/ 25, 0x05, + /* RLE: 004 Pixels @ 236,137*/ 4, 0x0A, + /* RLE: 064 Pixels @ 240,137*/ 64, 0x00, + /* ABS: 004 Pixels @ 304,137*/ 0, 4, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 010 Pixels @ 308,137*/ 10, 0x00, + /* RLE: 004 Pixels @ 318,137*/ 4, 0x06, + /* RLE: 037 Pixels @ 322,137*/ 37, 0x01, + /* ABS: 002 Pixels @ 359,137*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 361,137*/ 9, 0x03, + /* ABS: 002 Pixels @ 370,137*/ 0, 2, 0x04, 0x04, + /* RLE: 028 Pixels @ 372,137*/ 28, 0x01, + /* RLE: 035 Pixels @ 000,138*/ 35, 0x02, + /* RLE: 001 Pixels @ 035,138*/ 1, 0x04, + /* RLE: 006 Pixels @ 036,138*/ 6, 0x03, + /* ABS: 002 Pixels @ 042,138*/ 0, 2, 0x04, 0x0B, + /* RLE: 033 Pixels @ 044,138*/ 33, 0x00, + /* ABS: 003 Pixels @ 077,138*/ 0, 3, 0x0B, 0x04, 0x04, + /* RLE: 007 Pixels @ 080,138*/ 7, 0x03, + /* ABS: 005 Pixels @ 087,138*/ 0, 5, 0x04, 0x04, 0x00, 0x00, 0x0B, + /* RLE: 048 Pixels @ 092,138*/ 48, 0x00, + /* ABS: 033 Pixels @ 140,138*/ 0, 33, 0x0B, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0B, + /* RLE: 019 Pixels @ 173,138*/ 19, 0x00, + /* RLE: 003 Pixels @ 192,138*/ 3, 0x0A, + /* RLE: 007 Pixels @ 195,138*/ 7, 0x05, + /* ABS: 009 Pixels @ 202,138*/ 0, 9, 0x15, 0x0B, 0x0F, 0x06, 0x0C, 0x04, 0x03, 0x03, 0x1A, + /* RLE: 021 Pixels @ 211,138*/ 21, 0x05, + /* RLE: 004 Pixels @ 232,138*/ 4, 0x0A, + /* RLE: 069 Pixels @ 236,138*/ 69, 0x00, + /* RLE: 003 Pixels @ 305,138*/ 3, 0x06, + /* RLE: 011 Pixels @ 308,138*/ 11, 0x00, + /* RLE: 004 Pixels @ 319,138*/ 4, 0x06, + /* RLE: 037 Pixels @ 323,138*/ 37, 0x01, + /* ABS: 002 Pixels @ 360,138*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 362,138*/ 9, 0x03, + /* ABS: 002 Pixels @ 371,138*/ 0, 2, 0x04, 0x04, + /* RLE: 027 Pixels @ 373,138*/ 27, 0x01, + /* RLE: 035 Pixels @ 000,139*/ 35, 0x02, + /* RLE: 001 Pixels @ 035,139*/ 1, 0x04, + /* RLE: 006 Pixels @ 036,139*/ 6, 0x03, + /* ABS: 003 Pixels @ 042,139*/ 0, 3, 0x04, 0x00, 0x0B, + /* RLE: 034 Pixels @ 045,139*/ 34, 0x00, + /* ABS: 002 Pixels @ 079,139*/ 0, 2, 0x04, 0x04, + /* RLE: 007 Pixels @ 081,139*/ 7, 0x03, + /* ABS: 003 Pixels @ 088,139*/ 0, 3, 0x04, 0x04, 0x0B, + /* RLE: 048 Pixels @ 091,139*/ 48, 0x00, + /* ABS: 037 Pixels @ 139,139*/ 0, 37, 0x0B, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0B, + 0x00, 0x08, + /* RLE: 012 Pixels @ 176,139*/ 12, 0x00, + /* RLE: 004 Pixels @ 188,139*/ 4, 0x0A, + /* RLE: 010 Pixels @ 192,139*/ 10, 0x05, + /* RLE: 001 Pixels @ 202,139*/ 1, 0x19, + /* RLE: 004 Pixels @ 203,139*/ 4, 0x03, + /* ABS: 002 Pixels @ 207,139*/ 0, 2, 0x00, 0x19, + /* RLE: 019 Pixels @ 209,139*/ 19, 0x05, + /* RLE: 004 Pixels @ 228,139*/ 4, 0x0A, + /* RLE: 073 Pixels @ 232,139*/ 73, 0x00, + /* ABS: 003 Pixels @ 305,139*/ 0, 3, 0x0D, 0x06, 0x06, + /* RLE: 012 Pixels @ 308,139*/ 12, 0x00, + /* ABS: 005 Pixels @ 320,139*/ 0, 5, 0x06, 0x06, 0x03, 0x06, 0x06, + /* RLE: 036 Pixels @ 325,139*/ 36, 0x01, + /* ABS: 002 Pixels @ 361,139*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 363,139*/ 9, 0x03, + /* ABS: 002 Pixels @ 372,139*/ 0, 2, 0x04, 0x04, + /* RLE: 026 Pixels @ 374,139*/ 26, 0x01, + /* RLE: 035 Pixels @ 000,140*/ 35, 0x02, + /* RLE: 001 Pixels @ 035,140*/ 1, 0x04, + /* RLE: 006 Pixels @ 036,140*/ 6, 0x03, + /* ABS: 002 Pixels @ 042,140*/ 0, 2, 0x04, 0x0B, + /* RLE: 036 Pixels @ 044,140*/ 36, 0x00, + /* ABS: 002 Pixels @ 080,140*/ 0, 2, 0x04, 0x04, + /* RLE: 007 Pixels @ 082,140*/ 7, 0x03, + /* ABS: 002 Pixels @ 089,140*/ 0, 2, 0x04, 0x04, + /* RLE: 043 Pixels @ 091,140*/ 43, 0x00, + /* ABS: 005 Pixels @ 134,140*/ 0, 5, 0x0B, 0x00, 0x00, 0x00, 0x0B, + /* RLE: 036 Pixels @ 139,140*/ 36, 0x00, + /* RLE: 001 Pixels @ 175,140*/ 1, 0x08, + /* RLE: 008 Pixels @ 176,140*/ 8, 0x00, + /* RLE: 004 Pixels @ 184,140*/ 4, 0x0A, + /* RLE: 021 Pixels @ 188,140*/ 21, 0x05, + /* ABS: 006 Pixels @ 209,140*/ 0, 6, 0x19, 0x15, 0x03, 0x03, 0x00, 0x1A, + /* RLE: 008 Pixels @ 215,140*/ 8, 0x05, + /* RLE: 005 Pixels @ 223,140*/ 5, 0x0A, + /* RLE: 077 Pixels @ 228,140*/ 77, 0x00, + /* ABS: 003 Pixels @ 305,140*/ 0, 3, 0x06, 0x03, 0x06, + /* RLE: 013 Pixels @ 308,140*/ 13, 0x00, + /* ABS: 005 Pixels @ 321,140*/ 0, 5, 0x06, 0x06, 0x03, 0x06, 0x06, + /* RLE: 036 Pixels @ 326,140*/ 36, 0x01, + /* RLE: 003 Pixels @ 362,140*/ 3, 0x04, + /* RLE: 008 Pixels @ 365,140*/ 8, 0x03, + /* RLE: 003 Pixels @ 373,140*/ 3, 0x04, + /* RLE: 024 Pixels @ 376,140*/ 24, 0x01, + /* RLE: 036 Pixels @ 000,141*/ 36, 0x02, + /* RLE: 007 Pixels @ 036,141*/ 7, 0x03, + /* RLE: 001 Pixels @ 043,141*/ 1, 0x04, + /* RLE: 037 Pixels @ 044,141*/ 37, 0x00, + /* RLE: 001 Pixels @ 081,141*/ 1, 0x04, + /* RLE: 008 Pixels @ 082,141*/ 8, 0x03, + /* ABS: 004 Pixels @ 090,141*/ 0, 4, 0x04, 0x00, 0x00, 0x0B, + /* RLE: 041 Pixels @ 094,141*/ 41, 0x00, + /* ABS: 003 Pixels @ 135,141*/ 0, 3, 0x0B, 0x00, 0x0B, + /* RLE: 037 Pixels @ 138,141*/ 37, 0x00, + /* RLE: 001 Pixels @ 175,141*/ 1, 0x08, + /* RLE: 004 Pixels @ 176,141*/ 4, 0x00, + /* RLE: 004 Pixels @ 180,141*/ 4, 0x0A, + /* RLE: 020 Pixels @ 184,141*/ 20, 0x05, + /* ABS: 002 Pixels @ 204,141*/ 0, 2, 0x1A, 0x15, + /* RLE: 004 Pixels @ 206,141*/ 4, 0x03, + /* ABS: 005 Pixels @ 210,141*/ 0, 5, 0x00, 0x0C, 0x12, 0x00, 0x19, + /* RLE: 004 Pixels @ 215,141*/ 4, 0x05, + /* RLE: 004 Pixels @ 219,141*/ 4, 0x0A, + /* RLE: 082 Pixels @ 223,141*/ 82, 0x00, + /* ABS: 003 Pixels @ 305,141*/ 0, 3, 0x0D, 0x03, 0x06, + /* RLE: 014 Pixels @ 308,141*/ 14, 0x00, + /* ABS: 005 Pixels @ 322,141*/ 0, 5, 0x06, 0x06, 0x03, 0x06, 0x06, + /* RLE: 037 Pixels @ 327,141*/ 37, 0x01, + /* ABS: 002 Pixels @ 364,141*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 366,141*/ 9, 0x03, + /* ABS: 002 Pixels @ 375,141*/ 0, 2, 0x04, 0x04, + /* RLE: 023 Pixels @ 377,141*/ 23, 0x01, + /* RLE: 036 Pixels @ 000,142*/ 36, 0x02, + /* RLE: 001 Pixels @ 036,142*/ 1, 0x04, + /* RLE: 006 Pixels @ 037,142*/ 6, 0x03, + /* RLE: 001 Pixels @ 043,142*/ 1, 0x04, + /* RLE: 036 Pixels @ 044,142*/ 36, 0x00, + /* ABS: 003 Pixels @ 080,142*/ 0, 3, 0x0B, 0x04, 0x04, + /* RLE: 007 Pixels @ 083,142*/ 7, 0x03, + /* ABS: 003 Pixels @ 090,142*/ 0, 3, 0x04, 0x04, 0x0B, + /* RLE: 039 Pixels @ 093,142*/ 39, 0x00, + /* ABS: 003 Pixels @ 132,142*/ 0, 3, 0x0B, 0x00, 0x0B, + /* RLE: 042 Pixels @ 135,142*/ 42, 0x00, + /* RLE: 003 Pixels @ 177,142*/ 3, 0x0A, + /* RLE: 024 Pixels @ 180,142*/ 24, 0x05, + /* ABS: 005 Pixels @ 204,142*/ 0, 5, 0x00, 0x00, 0x0C, 0x12, 0x11, + /* RLE: 004 Pixels @ 209,142*/ 4, 0x08, + /* ABS: 002 Pixels @ 213,142*/ 0, 2, 0x00, 0x19, + /* RLE: 004 Pixels @ 215,142*/ 4, 0x0A, + /* RLE: 086 Pixels @ 219,142*/ 86, 0x00, + /* ABS: 004 Pixels @ 305,142*/ 0, 4, 0x0D, 0x03, 0x06, 0x06, + /* RLE: 015 Pixels @ 309,142*/ 15, 0x00, + /* RLE: 004 Pixels @ 324,142*/ 4, 0x06, + /* RLE: 037 Pixels @ 328,142*/ 37, 0x01, + /* ABS: 002 Pixels @ 365,142*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 367,142*/ 9, 0x03, + /* ABS: 002 Pixels @ 376,142*/ 0, 2, 0x04, 0x04, + /* RLE: 022 Pixels @ 378,142*/ 22, 0x01, + /* RLE: 001 Pixels @ 000,143*/ 1, 0x0A, + /* RLE: 035 Pixels @ 001,143*/ 35, 0x02, + /* RLE: 001 Pixels @ 036,143*/ 1, 0x04, + /* RLE: 006 Pixels @ 037,143*/ 6, 0x03, + /* ABS: 003 Pixels @ 043,143*/ 0, 3, 0x04, 0x00, 0x0B, + /* RLE: 036 Pixels @ 046,143*/ 36, 0x00, + /* ABS: 002 Pixels @ 082,143*/ 0, 2, 0x0B, 0x04, + /* RLE: 007 Pixels @ 084,143*/ 7, 0x03, + /* ABS: 003 Pixels @ 091,143*/ 0, 3, 0x04, 0x04, 0x0B, + /* RLE: 041 Pixels @ 094,143*/ 41, 0x00, + /* RLE: 001 Pixels @ 135,143*/ 1, 0x0B, + /* RLE: 037 Pixels @ 136,143*/ 37, 0x00, + /* RLE: 004 Pixels @ 173,143*/ 4, 0x0A, + /* RLE: 027 Pixels @ 177,143*/ 27, 0x05, + /* ABS: 011 Pixels @ 204,143*/ 0, 11, 0x03, 0x12, 0x08, 0x08, 0x06, 0x08, 0x0C, 0x00, 0x03, 0x03, 0x12, + /* RLE: 091 Pixels @ 215,143*/ 91, 0x00, + /* ABS: 003 Pixels @ 306,143*/ 0, 3, 0x0D, 0x06, 0x06, + /* RLE: 016 Pixels @ 309,143*/ 16, 0x00, + /* RLE: 004 Pixels @ 325,143*/ 4, 0x06, + /* RLE: 037 Pixels @ 329,143*/ 37, 0x01, + /* ABS: 002 Pixels @ 366,143*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 368,143*/ 9, 0x03, + /* ABS: 002 Pixels @ 377,143*/ 0, 2, 0x04, 0x04, + /* RLE: 021 Pixels @ 379,143*/ 21, 0x01, + /* RLE: 003 Pixels @ 000,144*/ 3, 0x0A, + /* RLE: 033 Pixels @ 003,144*/ 33, 0x02, + /* RLE: 001 Pixels @ 036,144*/ 1, 0x04, + /* RLE: 006 Pixels @ 037,144*/ 6, 0x03, + /* ABS: 002 Pixels @ 043,144*/ 0, 2, 0x04, 0x0B, + /* RLE: 037 Pixels @ 045,144*/ 37, 0x00, + /* ABS: 003 Pixels @ 082,144*/ 0, 3, 0x0B, 0x04, 0x04, + /* RLE: 007 Pixels @ 085,144*/ 7, 0x03, + /* ABS: 002 Pixels @ 092,144*/ 0, 2, 0x04, 0x04, + /* RLE: 075 Pixels @ 094,144*/ 75, 0x00, + /* RLE: 004 Pixels @ 169,144*/ 4, 0x0A, + /* RLE: 031 Pixels @ 173,144*/ 31, 0x05, + /* RLE: 003 Pixels @ 204,144*/ 3, 0x00, + /* ABS: 007 Pixels @ 207,144*/ 0, 7, 0x03, 0x03, 0x0F, 0x0C, 0x03, 0x03, 0x04, + /* RLE: 092 Pixels @ 214,144*/ 92, 0x00, + /* RLE: 003 Pixels @ 306,144*/ 3, 0x06, + /* RLE: 017 Pixels @ 309,144*/ 17, 0x00, + /* ABS: 005 Pixels @ 326,144*/ 0, 5, 0x06, 0x06, 0x03, 0x06, 0x06, + /* RLE: 036 Pixels @ 331,144*/ 36, 0x01, + /* ABS: 002 Pixels @ 367,144*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 369,144*/ 9, 0x03, + /* ABS: 002 Pixels @ 378,144*/ 0, 2, 0x04, 0x04, + /* RLE: 020 Pixels @ 380,144*/ 20, 0x01, + /* ABS: 005 Pixels @ 000,145*/ 0, 5, 0x05, 0x05, 0x0A, 0x0A, 0x0A, + /* RLE: 031 Pixels @ 005,145*/ 31, 0x02, + /* RLE: 001 Pixels @ 036,145*/ 1, 0x04, + /* RLE: 006 Pixels @ 037,145*/ 6, 0x03, + /* ABS: 003 Pixels @ 043,145*/ 0, 3, 0x04, 0x00, 0x0B, + /* RLE: 038 Pixels @ 046,145*/ 38, 0x00, + /* RLE: 001 Pixels @ 084,145*/ 1, 0x0B, + /* RLE: 008 Pixels @ 085,145*/ 8, 0x03, + /* ABS: 002 Pixels @ 093,145*/ 0, 2, 0x04, 0x0B, + /* RLE: 070 Pixels @ 095,145*/ 70, 0x00, + /* RLE: 004 Pixels @ 165,145*/ 4, 0x0A, + /* RLE: 034 Pixels @ 169,145*/ 34, 0x05, + /* ABS: 008 Pixels @ 203,145*/ 0, 8, 0x0A, 0x12, 0x04, 0x04, 0x03, 0x03, 0x06, 0x12, + /* RLE: 004 Pixels @ 211,145*/ 4, 0x03, + /* RLE: 091 Pixels @ 215,145*/ 91, 0x00, + /* ABS: 004 Pixels @ 306,145*/ 0, 4, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 017 Pixels @ 310,145*/ 17, 0x00, + /* ABS: 005 Pixels @ 327,145*/ 0, 5, 0x06, 0x06, 0x03, 0x06, 0x06, + /* RLE: 036 Pixels @ 332,145*/ 36, 0x01, + /* ABS: 002 Pixels @ 368,145*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 370,145*/ 9, 0x03, + /* ABS: 002 Pixels @ 379,145*/ 0, 2, 0x04, 0x04, + /* RLE: 019 Pixels @ 381,145*/ 19, 0x01, + /* ABS: 007 Pixels @ 000,146*/ 0, 7, 0x00, 0x00, 0x1A, 0x05, 0x0A, 0x0A, 0x0A, + /* RLE: 029 Pixels @ 007,146*/ 29, 0x02, + /* RLE: 001 Pixels @ 036,146*/ 1, 0x04, + /* RLE: 006 Pixels @ 037,146*/ 6, 0x03, + /* ABS: 002 Pixels @ 043,146*/ 0, 2, 0x04, 0x0B, + /* RLE: 039 Pixels @ 045,146*/ 39, 0x00, + /* ABS: 002 Pixels @ 084,146*/ 0, 2, 0x0B, 0x04, + /* RLE: 008 Pixels @ 086,146*/ 8, 0x03, + /* ABS: 003 Pixels @ 094,146*/ 0, 3, 0x04, 0x00, 0x0B, + /* RLE: 037 Pixels @ 097,146*/ 37, 0x00, + /* ABS: 004 Pixels @ 134,146*/ 0, 4, 0x0B, 0x00, 0x00, 0x00, + /* RLE: 022 Pixels @ 138,146*/ 22, 0x08, + /* RLE: 001 Pixels @ 160,146*/ 1, 0x00, + /* RLE: 004 Pixels @ 161,146*/ 4, 0x0A, + /* RLE: 034 Pixels @ 165,146*/ 34, 0x05, + /* RLE: 004 Pixels @ 199,146*/ 4, 0x0A, + /* RLE: 003 Pixels @ 203,146*/ 3, 0x00, + /* RLE: 003 Pixels @ 206,146*/ 3, 0x03, + /* ABS: 005 Pixels @ 209,146*/ 0, 5, 0x0E, 0x11, 0x0E, 0x06, 0x08, + /* RLE: 093 Pixels @ 214,146*/ 93, 0x00, + /* ABS: 004 Pixels @ 307,146*/ 0, 4, 0x0D, 0x0D, 0x06, 0x06, + /* RLE: 017 Pixels @ 311,146*/ 17, 0x00, + /* ABS: 005 Pixels @ 328,146*/ 0, 5, 0x06, 0x06, 0x03, 0x06, 0x06, + /* RLE: 037 Pixels @ 333,146*/ 37, 0x01, + /* ABS: 002 Pixels @ 370,146*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 372,146*/ 9, 0x03, + /* ABS: 002 Pixels @ 381,146*/ 0, 2, 0x04, 0x04, + /* RLE: 017 Pixels @ 383,146*/ 17, 0x01, + /* ABS: 009 Pixels @ 000,147*/ 0, 9, 0x12, 0x00, 0x03, 0x03, 0x19, 0x05, 0x0A, 0x0A, 0x0A, + /* RLE: 028 Pixels @ 009,147*/ 28, 0x02, + /* RLE: 007 Pixels @ 037,147*/ 7, 0x03, + /* ABS: 004 Pixels @ 044,147*/ 0, 4, 0x04, 0x0B, 0x00, 0x0B, + /* RLE: 037 Pixels @ 048,147*/ 37, 0x00, + /* ABS: 002 Pixels @ 085,147*/ 0, 2, 0x0B, 0x04, + /* RLE: 007 Pixels @ 087,147*/ 7, 0x03, + /* ABS: 002 Pixels @ 094,147*/ 0, 2, 0x04, 0x04, + /* RLE: 039 Pixels @ 096,147*/ 39, 0x00, + /* ABS: 003 Pixels @ 135,147*/ 0, 3, 0x0B, 0x00, 0x08, + /* RLE: 022 Pixels @ 138,147*/ 22, 0x10, + /* RLE: 001 Pixels @ 160,147*/ 1, 0x08, + /* RLE: 034 Pixels @ 161,147*/ 34, 0x05, + /* RLE: 004 Pixels @ 195,147*/ 4, 0x0A, + /* RLE: 006 Pixels @ 199,147*/ 6, 0x00, + /* ABS: 003 Pixels @ 205,147*/ 0, 3, 0x03, 0x0C, 0x06, + /* RLE: 004 Pixels @ 208,147*/ 4, 0x08, + /* ABS: 004 Pixels @ 212,147*/ 0, 4, 0x11, 0x12, 0x00, 0x03, + /* RLE: 092 Pixels @ 216,147*/ 92, 0x00, + /* ABS: 004 Pixels @ 308,147*/ 0, 4, 0x0D, 0x03, 0x06, 0x06, + /* RLE: 018 Pixels @ 312,147*/ 18, 0x00, + /* RLE: 004 Pixels @ 330,147*/ 4, 0x06, + /* RLE: 037 Pixels @ 334,147*/ 37, 0x01, + /* ABS: 002 Pixels @ 371,147*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 373,147*/ 9, 0x03, + /* ABS: 002 Pixels @ 382,147*/ 0, 2, 0x04, 0x04, + /* RLE: 016 Pixels @ 384,147*/ 16, 0x01, + /* ABS: 011 Pixels @ 000,148*/ 0, 11, 0x08, 0x06, 0x06, 0x0B, 0x03, 0x19, 0x05, 0x05, 0x0A, 0x0A, 0x0A, + /* RLE: 026 Pixels @ 011,148*/ 26, 0x02, + /* RLE: 001 Pixels @ 037,148*/ 1, 0x04, + /* RLE: 006 Pixels @ 038,148*/ 6, 0x03, + /* RLE: 001 Pixels @ 044,148*/ 1, 0x04, + /* RLE: 040 Pixels @ 045,148*/ 40, 0x00, + /* ABS: 003 Pixels @ 085,148*/ 0, 3, 0x0B, 0x04, 0x04, + /* RLE: 007 Pixels @ 088,148*/ 7, 0x03, + /* ABS: 003 Pixels @ 095,148*/ 0, 3, 0x04, 0x04, 0x0B, + /* RLE: 036 Pixels @ 098,148*/ 36, 0x00, + /* ABS: 005 Pixels @ 134,148*/ 0, 5, 0x0B, 0x00, 0x08, 0x10, 0x10, + /* RLE: 020 Pixels @ 139,148*/ 20, 0x08, + /* ABS: 003 Pixels @ 159,148*/ 0, 3, 0x10, 0x10, 0x08, + /* RLE: 030 Pixels @ 162,148*/ 30, 0x05, + /* RLE: 003 Pixels @ 192,148*/ 3, 0x0A, + /* RLE: 010 Pixels @ 195,148*/ 10, 0x00, + /* ABS: 006 Pixels @ 205,148*/ 0, 6, 0x03, 0x12, 0x11, 0x12, 0x0C, 0x0B, + /* RLE: 004 Pixels @ 211,148*/ 4, 0x03, + /* RLE: 094 Pixels @ 215,148*/ 94, 0x00, + /* ABS: 004 Pixels @ 309,148*/ 0, 4, 0x0D, 0x03, 0x03, 0x06, + /* RLE: 018 Pixels @ 313,148*/ 18, 0x00, + /* RLE: 004 Pixels @ 331,148*/ 4, 0x06, + /* RLE: 037 Pixels @ 335,148*/ 37, 0x01, + /* ABS: 002 Pixels @ 372,148*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 374,148*/ 9, 0x03, + /* ABS: 002 Pixels @ 383,148*/ 0, 2, 0x04, 0x04, + /* RLE: 015 Pixels @ 385,148*/ 15, 0x01, + /* ABS: 004 Pixels @ 000,149*/ 0, 4, 0x0D, 0x0B, 0x0C, 0x08, + /* RLE: 004 Pixels @ 004,149*/ 4, 0x00, + /* ABS: 005 Pixels @ 008,149*/ 0, 5, 0x19, 0x05, 0x0A, 0x0A, 0x0A, + /* RLE: 024 Pixels @ 013,149*/ 24, 0x02, + /* RLE: 001 Pixels @ 037,149*/ 1, 0x04, + /* RLE: 006 Pixels @ 038,149*/ 6, 0x03, + /* ABS: 002 Pixels @ 044,149*/ 0, 2, 0x04, 0x0B, + /* RLE: 041 Pixels @ 046,149*/ 41, 0x00, + /* ABS: 002 Pixels @ 087,149*/ 0, 2, 0x0B, 0x04, + /* RLE: 007 Pixels @ 089,149*/ 7, 0x03, + /* ABS: 003 Pixels @ 096,149*/ 0, 3, 0x04, 0x04, 0x0B, + /* RLE: 036 Pixels @ 099,149*/ 36, 0x00, + /* ABS: 004 Pixels @ 135,149*/ 0, 4, 0x0B, 0x08, 0x10, 0x08, + /* RLE: 020 Pixels @ 139,149*/ 20, 0x10, + /* ABS: 003 Pixels @ 159,149*/ 0, 3, 0x08, 0x10, 0x08, + /* RLE: 026 Pixels @ 162,149*/ 26, 0x05, + /* RLE: 004 Pixels @ 188,149*/ 4, 0x0A, + /* RLE: 014 Pixels @ 192,149*/ 14, 0x00, + /* RLE: 004 Pixels @ 206,149*/ 4, 0x03, + /* ABS: 005 Pixels @ 210,149*/ 0, 5, 0x00, 0x0B, 0x03, 0x03, 0x03, + /* RLE: 095 Pixels @ 215,149*/ 95, 0x00, + /* ABS: 004 Pixels @ 310,149*/ 0, 4, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 018 Pixels @ 314,149*/ 18, 0x00, + /* ABS: 004 Pixels @ 332,149*/ 0, 4, 0x06, 0x06, 0x03, 0x06, + /* RLE: 037 Pixels @ 336,149*/ 37, 0x01, + /* ABS: 002 Pixels @ 373,149*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 375,149*/ 9, 0x03, + /* ABS: 002 Pixels @ 384,149*/ 0, 2, 0x04, 0x04, + /* RLE: 014 Pixels @ 386,149*/ 14, 0x01, + /* ABS: 015 Pixels @ 000,150*/ 0, 15, 0x0B, 0x03, 0x0B, 0x08, 0x0B, 0x03, 0x0C, 0x0B, 0x03, 0x03, 0x1A, 0x05, 0x0A, 0x0A, 0x0A, + /* RLE: 022 Pixels @ 015,150*/ 22, 0x02, + /* RLE: 001 Pixels @ 037,150*/ 1, 0x04, + /* RLE: 006 Pixels @ 038,150*/ 6, 0x03, + /* RLE: 001 Pixels @ 044,150*/ 1, 0x04, + /* RLE: 042 Pixels @ 045,150*/ 42, 0x00, + /* ABS: 002 Pixels @ 087,150*/ 0, 2, 0x0B, 0x04, + /* RLE: 008 Pixels @ 089,150*/ 8, 0x03, + /* ABS: 004 Pixels @ 097,150*/ 0, 4, 0x04, 0x00, 0x00, 0x0B, + /* RLE: 032 Pixels @ 101,150*/ 32, 0x00, + /* ABS: 006 Pixels @ 133,150*/ 0, 6, 0x0B, 0x00, 0x00, 0x08, 0x10, 0x08, + /* RLE: 020 Pixels @ 139,150*/ 20, 0x10, + /* ABS: 003 Pixels @ 159,150*/ 0, 3, 0x08, 0x10, 0x08, + /* RLE: 022 Pixels @ 162,150*/ 22, 0x05, + /* RLE: 004 Pixels @ 184,150*/ 4, 0x0A, + /* RLE: 017 Pixels @ 188,150*/ 17, 0x00, + /* ABS: 011 Pixels @ 205,150*/ 0, 11, 0x03, 0x03, 0x0C, 0x06, 0x0F, 0x08, 0x08, 0x03, 0x04, 0x0B, 0x03, + /* RLE: 095 Pixels @ 216,150*/ 95, 0x00, + /* ABS: 005 Pixels @ 311,150*/ 0, 5, 0x0D, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 017 Pixels @ 316,150*/ 17, 0x00, + /* ABS: 005 Pixels @ 333,150*/ 0, 5, 0x06, 0x06, 0x03, 0x06, 0x06, + /* RLE: 036 Pixels @ 338,150*/ 36, 0x01, + /* ABS: 002 Pixels @ 374,150*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 376,150*/ 9, 0x03, + /* ABS: 002 Pixels @ 385,150*/ 0, 2, 0x04, 0x04, + /* RLE: 013 Pixels @ 387,150*/ 13, 0x01, + /* ABS: 017 Pixels @ 000,151*/ 0, 17, 0x03, 0x03, 0x06, 0x0F, 0x03, 0x06, 0x11, 0x11, 0x11, 0x00, 0x00, 0x19, 0x03, 0x03, 0x03, 0x0C, 0x0A, + /* RLE: 020 Pixels @ 017,151*/ 20, 0x02, + /* RLE: 001 Pixels @ 037,151*/ 1, 0x04, + /* RLE: 006 Pixels @ 038,151*/ 6, 0x03, + /* ABS: 003 Pixels @ 044,151*/ 0, 3, 0x04, 0x00, 0x0B, + /* RLE: 041 Pixels @ 047,151*/ 41, 0x00, + /* ABS: 002 Pixels @ 088,151*/ 0, 2, 0x0B, 0x04, + /* RLE: 007 Pixels @ 090,151*/ 7, 0x03, + /* ABS: 003 Pixels @ 097,151*/ 0, 3, 0x04, 0x04, 0x0B, + /* RLE: 034 Pixels @ 100,151*/ 34, 0x00, + /* ABS: 008 Pixels @ 134,151*/ 0, 8, 0x0B, 0x00, 0x08, 0x10, 0x08, 0x10, 0x10, 0x08, + /* RLE: 005 Pixels @ 142,151*/ 5, 0x10, + /* RLE: 003 Pixels @ 147,151*/ 3, 0x08, + /* RLE: 003 Pixels @ 150,151*/ 3, 0x10, + /* RLE: 004 Pixels @ 153,151*/ 4, 0x08, + /* ABS: 005 Pixels @ 157,151*/ 0, 5, 0x10, 0x10, 0x08, 0x10, 0x08, + /* RLE: 018 Pixels @ 162,151*/ 18, 0x05, + /* RLE: 004 Pixels @ 180,151*/ 4, 0x0A, + /* RLE: 022 Pixels @ 184,151*/ 22, 0x00, + /* ABS: 010 Pixels @ 206,151*/ 0, 10, 0x04, 0x08, 0x11, 0x0E, 0x0C, 0x00, 0x03, 0x12, 0x0C, 0x03, + /* RLE: 096 Pixels @ 216,151*/ 96, 0x00, + /* ABS: 005 Pixels @ 312,151*/ 0, 5, 0x0D, 0x06, 0x06, 0x0D, 0x06, + /* RLE: 017 Pixels @ 317,151*/ 17, 0x00, + /* ABS: 005 Pixels @ 334,151*/ 0, 5, 0x06, 0x06, 0x03, 0x06, 0x06, + /* RLE: 036 Pixels @ 339,151*/ 36, 0x01, + /* ABS: 002 Pixels @ 375,151*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 377,151*/ 9, 0x03, + /* ABS: 002 Pixels @ 386,151*/ 0, 2, 0x04, 0x04, + /* RLE: 012 Pixels @ 388,151*/ 12, 0x01, + /* ABS: 019 Pixels @ 000,152*/ 0, 19, 0x03, 0x00, 0x08, 0x0C, 0x03, 0x11, 0x0D, 0x03, 0x12, 0x12, 0x03, 0x03, 0x0B, 0x0F, 0x04, 0x19, 0x0A, 0x0A, 0x0A, + /* RLE: 018 Pixels @ 019,152*/ 18, 0x02, + /* RLE: 001 Pixels @ 037,152*/ 1, 0x04, + /* RLE: 007 Pixels @ 038,152*/ 7, 0x03, + /* RLE: 001 Pixels @ 045,152*/ 1, 0x0B, + /* RLE: 042 Pixels @ 046,152*/ 42, 0x00, + /* ABS: 003 Pixels @ 088,152*/ 0, 3, 0x0B, 0x04, 0x04, + /* RLE: 007 Pixels @ 091,152*/ 7, 0x03, + /* ABS: 002 Pixels @ 098,152*/ 0, 2, 0x04, 0x04, + /* RLE: 033 Pixels @ 100,152*/ 33, 0x00, + /* ABS: 009 Pixels @ 133,152*/ 0, 9, 0x0B, 0x00, 0x00, 0x08, 0x10, 0x08, 0x10, 0x10, 0x08, + /* RLE: 004 Pixels @ 142,152*/ 4, 0x10, + /* ABS: 008 Pixels @ 146,152*/ 0, 8, 0x08, 0x10, 0x10, 0x10, 0x08, 0x10, 0x10, 0x08, + /* RLE: 005 Pixels @ 154,152*/ 5, 0x10, + /* ABS: 003 Pixels @ 159,152*/ 0, 3, 0x08, 0x10, 0x08, + /* RLE: 015 Pixels @ 162,152*/ 15, 0x05, + /* RLE: 003 Pixels @ 177,152*/ 3, 0x0A, + /* RLE: 025 Pixels @ 180,152*/ 25, 0x00, + /* ABS: 003 Pixels @ 205,152*/ 0, 3, 0x03, 0x0E, 0x0D, + /* RLE: 006 Pixels @ 208,152*/ 6, 0x03, + /* ABS: 002 Pixels @ 214,152*/ 0, 2, 0x00, 0x03, + /* RLE: 097 Pixels @ 216,152*/ 97, 0x00, + /* ABS: 005 Pixels @ 313,152*/ 0, 5, 0x0D, 0x0D, 0x03, 0x06, 0x06, + /* RLE: 017 Pixels @ 318,152*/ 17, 0x00, + /* RLE: 005 Pixels @ 335,152*/ 5, 0x06, + /* RLE: 036 Pixels @ 340,152*/ 36, 0x01, + /* RLE: 003 Pixels @ 376,152*/ 3, 0x04, + /* RLE: 008 Pixels @ 379,152*/ 8, 0x03, + /* RLE: 003 Pixels @ 387,152*/ 3, 0x04, + /* RLE: 010 Pixels @ 390,152*/ 10, 0x01, + /* ABS: 021 Pixels @ 000,153*/ 0, 21, 0x03, 0x06, 0x0F, 0x03, 0x00, 0x0B, 0x08, 0x0D, 0x0B, 0x0B, 0x03, 0x0E, 0x08, 0x11, 0x03, 0x03, 0x00, 0x1A, 0x0A, 0x0A, 0x0A, + /* RLE: 017 Pixels @ 021,153*/ 17, 0x02, + /* RLE: 001 Pixels @ 038,153*/ 1, 0x04, + /* RLE: 006 Pixels @ 039,153*/ 6, 0x03, + /* ABS: 002 Pixels @ 045,153*/ 0, 2, 0x04, 0x0B, + /* RLE: 043 Pixels @ 047,153*/ 43, 0x00, + /* ABS: 002 Pixels @ 090,153*/ 0, 2, 0x04, 0x04, + /* RLE: 007 Pixels @ 092,153*/ 7, 0x03, + /* ABS: 004 Pixels @ 099,153*/ 0, 4, 0x04, 0x04, 0x00, 0x0B, + /* RLE: 026 Pixels @ 103,153*/ 26, 0x00, + /* ABS: 013 Pixels @ 129,153*/ 0, 13, 0x0B, 0x00, 0x00, 0x0B, 0x00, 0x0B, 0x0A, 0x08, 0x10, 0x08, 0x10, 0x10, 0x08, + /* RLE: 004 Pixels @ 142,153*/ 4, 0x10, + /* ABS: 006 Pixels @ 146,153*/ 0, 6, 0x08, 0x10, 0x10, 0x10, 0x08, 0x10, + /* RLE: 004 Pixels @ 152,153*/ 4, 0x08, + /* RLE: 003 Pixels @ 156,153*/ 3, 0x10, + /* ABS: 003 Pixels @ 159,153*/ 0, 3, 0x08, 0x10, 0x08, + /* RLE: 011 Pixels @ 162,153*/ 11, 0x05, + /* RLE: 004 Pixels @ 173,153*/ 4, 0x0A, + /* RLE: 028 Pixels @ 177,153*/ 28, 0x00, + /* ABS: 011 Pixels @ 205,153*/ 0, 11, 0x03, 0x0B, 0x11, 0x03, 0x03, 0x00, 0x0C, 0x0C, 0x04, 0x08, 0x03, + /* RLE: 099 Pixels @ 216,153*/ 99, 0x00, + /* ABS: 004 Pixels @ 315,153*/ 0, 4, 0x0D, 0x03, 0x06, 0x06, + /* RLE: 018 Pixels @ 319,153*/ 18, 0x00, + /* RLE: 004 Pixels @ 337,153*/ 4, 0x06, + /* RLE: 037 Pixels @ 341,153*/ 37, 0x01, + /* ABS: 002 Pixels @ 378,153*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 380,153*/ 9, 0x03, + /* ABS: 002 Pixels @ 389,153*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 391,153*/ 9, 0x01, + /* ABS: 023 Pixels @ 000,154*/ 0, 23, 0x00, 0x00, 0x04, 0x03, 0x08, 0x0C, 0x00, 0x0F, 0x0D, 0x03, 0x03, 0x0C, 0x08, 0x08, 0x04, 0x06, 0x00, 0x03, 0x03, 0x1A, 0x0A, 0x0A, 0x0A, + /* RLE: 015 Pixels @ 023,154*/ 15, 0x02, + /* RLE: 001 Pixels @ 038,154*/ 1, 0x04, + /* RLE: 006 Pixels @ 039,154*/ 6, 0x03, + /* RLE: 001 Pixels @ 045,154*/ 1, 0x04, + /* RLE: 045 Pixels @ 046,154*/ 45, 0x00, + /* RLE: 001 Pixels @ 091,154*/ 1, 0x04, + /* RLE: 008 Pixels @ 092,154*/ 8, 0x03, + /* ABS: 002 Pixels @ 100,154*/ 0, 2, 0x04, 0x0B, + /* RLE: 018 Pixels @ 102,154*/ 18, 0x00, + /* RLE: 001 Pixels @ 120,154*/ 1, 0x0B, + /* RLE: 004 Pixels @ 121,154*/ 4, 0x00, + /* ABS: 006 Pixels @ 125,154*/ 0, 6, 0x0B, 0x00, 0x00, 0x0B, 0x00, 0x0B, + /* RLE: 004 Pixels @ 131,154*/ 4, 0x0A, + /* ABS: 007 Pixels @ 135,154*/ 0, 7, 0x05, 0x08, 0x10, 0x08, 0x10, 0x10, 0x08, + /* RLE: 005 Pixels @ 142,154*/ 5, 0x10, + /* RLE: 003 Pixels @ 147,154*/ 3, 0x08, + /* ABS: 012 Pixels @ 150,154*/ 0, 12, 0x10, 0x10, 0x08, 0x10, 0x10, 0x10, 0x08, 0x10, 0x10, 0x08, 0x10, 0x08, + /* RLE: 007 Pixels @ 162,154*/ 7, 0x05, + /* RLE: 004 Pixels @ 169,154*/ 4, 0x0A, + /* RLE: 033 Pixels @ 173,154*/ 33, 0x00, + /* ABS: 002 Pixels @ 206,154*/ 0, 2, 0x03, 0x06, + /* RLE: 004 Pixels @ 208,154*/ 4, 0x08, + /* ABS: 004 Pixels @ 212,154*/ 0, 4, 0x06, 0x03, 0x00, 0x03, + /* RLE: 100 Pixels @ 216,154*/ 100, 0x00, + /* ABS: 004 Pixels @ 316,154*/ 0, 4, 0x0D, 0x03, 0x06, 0x06, + /* RLE: 018 Pixels @ 320,154*/ 18, 0x00, + /* ABS: 004 Pixels @ 338,154*/ 0, 4, 0x06, 0x06, 0x03, 0x06, + /* RLE: 037 Pixels @ 342,154*/ 37, 0x01, + /* ABS: 002 Pixels @ 379,154*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 381,154*/ 9, 0x03, + /* ABS: 002 Pixels @ 390,154*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 392,154*/ 8, 0x01, + /* ABS: 022 Pixels @ 000,155*/ 0, 22, 0x0B, 0x0B, 0x04, 0x03, 0x0E, 0x0F, 0x0C, 0x06, 0x0F, 0x03, 0x03, 0x11, 0x11, 0x00, 0x0C, 0x08, 0x11, 0x11, 0x00, 0x00, 0x15, 0x19, + /* RLE: 004 Pixels @ 022,155*/ 4, 0x0A, + /* RLE: 012 Pixels @ 026,155*/ 12, 0x02, + /* RLE: 001 Pixels @ 038,155*/ 1, 0x04, + /* RLE: 006 Pixels @ 039,155*/ 6, 0x03, + /* ABS: 002 Pixels @ 045,155*/ 0, 2, 0x04, 0x0B, + /* RLE: 045 Pixels @ 047,155*/ 45, 0x00, + /* RLE: 001 Pixels @ 092,155*/ 1, 0x04, + /* RLE: 008 Pixels @ 093,155*/ 8, 0x03, + /* RLE: 001 Pixels @ 101,155*/ 1, 0x04, + /* RLE: 017 Pixels @ 102,155*/ 17, 0x00, + /* ABS: 008 Pixels @ 119,155*/ 0, 8, 0x0B, 0x00, 0x0B, 0x00, 0x00, 0x0B, 0x00, 0x0B, + /* RLE: 004 Pixels @ 127,155*/ 4, 0x0A, + /* RLE: 005 Pixels @ 131,155*/ 5, 0x05, + /* ABS: 006 Pixels @ 136,155*/ 0, 6, 0x08, 0x10, 0x08, 0x10, 0x10, 0x08, + /* RLE: 004 Pixels @ 142,155*/ 4, 0x10, + /* ABS: 005 Pixels @ 146,155*/ 0, 5, 0x08, 0x10, 0x10, 0x10, 0x08, + /* RLE: 005 Pixels @ 151,155*/ 5, 0x10, + /* ABS: 009 Pixels @ 156,155*/ 0, 9, 0x08, 0x10, 0x10, 0x08, 0x10, 0x08, 0x05, 0x05, 0x05, + /* RLE: 004 Pixels @ 165,155*/ 4, 0x0A, + /* RLE: 037 Pixels @ 169,155*/ 37, 0x00, + /* ABS: 005 Pixels @ 206,155*/ 0, 5, 0x03, 0x06, 0x12, 0x0C, 0x0B, + /* RLE: 005 Pixels @ 211,155*/ 5, 0x03, + /* RLE: 101 Pixels @ 216,155*/ 101, 0x00, + /* ABS: 004 Pixels @ 317,155*/ 0, 4, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 018 Pixels @ 321,155*/ 18, 0x00, + /* ABS: 005 Pixels @ 339,155*/ 0, 5, 0x06, 0x06, 0x03, 0x06, 0x06, + /* RLE: 036 Pixels @ 344,155*/ 36, 0x01, + /* ABS: 002 Pixels @ 380,155*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 382,155*/ 9, 0x03, + /* ABS: 002 Pixels @ 391,155*/ 0, 2, 0x04, 0x04, + /* RLE: 007 Pixels @ 393,155*/ 7, 0x01, + /* RLE: 003 Pixels @ 000,156*/ 3, 0x02, + /* ABS: 025 Pixels @ 003,156*/ 0, 25, 0x04, 0x03, 0x0B, 0x12, 0x06, 0x04, 0x03, 0x04, 0x08, 0x04, 0x03, 0x0F, 0x0D, 0x04, 0x12, 0x03, 0x0B, 0x00, 0x03, 0x03, 0x1A, 0x05, 0x0A, 0x0A, 0x0A, + /* RLE: 010 Pixels @ 028,156*/ 10, 0x02, + /* RLE: 001 Pixels @ 038,156*/ 1, 0x04, + /* RLE: 006 Pixels @ 039,156*/ 6, 0x03, + /* RLE: 001 Pixels @ 045,156*/ 1, 0x04, + /* RLE: 045 Pixels @ 046,156*/ 45, 0x00, + /* ABS: 003 Pixels @ 091,156*/ 0, 3, 0x0B, 0x04, 0x04, + /* RLE: 007 Pixels @ 094,156*/ 7, 0x03, + /* RLE: 001 Pixels @ 101,156*/ 1, 0x04, + /* RLE: 016 Pixels @ 102,156*/ 16, 0x00, + /* ABS: 005 Pixels @ 118,156*/ 0, 5, 0x0B, 0x00, 0x00, 0x00, 0x0B, + /* RLE: 004 Pixels @ 123,156*/ 4, 0x0A, + /* RLE: 009 Pixels @ 127,156*/ 9, 0x05, + /* ABS: 006 Pixels @ 136,156*/ 0, 6, 0x08, 0x10, 0x08, 0x10, 0x10, 0x08, + /* RLE: 004 Pixels @ 142,156*/ 4, 0x10, + /* ABS: 019 Pixels @ 146,156*/ 0, 19, 0x08, 0x10, 0x10, 0x10, 0x08, 0x10, 0x08, 0x10, 0x10, 0x10, 0x08, 0x10, 0x10, 0x08, 0x10, 0x08, 0x0A, 0x0A, 0x0A, + /* RLE: 042 Pixels @ 165,156*/ 42, 0x00, + /* RLE: 006 Pixels @ 207,156*/ 6, 0x03, + /* ABS: 004 Pixels @ 213,156*/ 0, 4, 0x00, 0x0C, 0x12, 0x03, + /* RLE: 101 Pixels @ 217,156*/ 101, 0x00, + /* ABS: 005 Pixels @ 318,156*/ 0, 5, 0x0D, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 017 Pixels @ 323,156*/ 17, 0x00, + /* ABS: 005 Pixels @ 340,156*/ 0, 5, 0x06, 0x06, 0x03, 0x06, 0x06, + /* RLE: 036 Pixels @ 345,156*/ 36, 0x01, + /* ABS: 002 Pixels @ 381,156*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 383,156*/ 9, 0x03, + /* ABS: 002 Pixels @ 392,156*/ 0, 2, 0x04, 0x04, + /* RLE: 006 Pixels @ 394,156*/ 6, 0x01, + /* RLE: 004 Pixels @ 000,157*/ 4, 0x02, + /* ABS: 002 Pixels @ 004,157*/ 0, 2, 0x00, 0x00, + /* RLE: 004 Pixels @ 006,157*/ 4, 0x03, + /* ABS: 020 Pixels @ 010,157*/ 0, 20, 0x12, 0x11, 0x03, 0x0C, 0x08, 0x0B, 0x03, 0x03, 0x04, 0x08, 0x08, 0x11, 0x00, 0x03, 0x05, 0x05, 0x05, 0x0A, 0x0A, 0x0A, + /* RLE: 008 Pixels @ 030,157*/ 8, 0x02, + /* RLE: 001 Pixels @ 038,157*/ 1, 0x04, + /* RLE: 006 Pixels @ 039,157*/ 6, 0x03, + /* ABS: 003 Pixels @ 045,157*/ 0, 3, 0x04, 0x00, 0x0B, + /* RLE: 045 Pixels @ 048,157*/ 45, 0x00, + /* ABS: 002 Pixels @ 093,157*/ 0, 2, 0x0B, 0x04, + /* RLE: 006 Pixels @ 095,157*/ 6, 0x03, + /* RLE: 001 Pixels @ 101,157*/ 1, 0x04, + /* RLE: 012 Pixels @ 102,157*/ 12, 0x00, + /* ABS: 009 Pixels @ 114,157*/ 0, 9, 0x0B, 0x00, 0x00, 0x0B, 0x00, 0x0B, 0x0A, 0x0A, 0x0A, + /* RLE: 013 Pixels @ 123,157*/ 13, 0x05, + /* ABS: 005 Pixels @ 136,157*/ 0, 5, 0x08, 0x10, 0x08, 0x10, 0x10, + /* RLE: 005 Pixels @ 141,157*/ 5, 0x08, + /* ABS: 016 Pixels @ 146,157*/ 0, 16, 0x10, 0x08, 0x08, 0x08, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x10, 0x10, 0x10, 0x08, 0x10, 0x08, + /* RLE: 045 Pixels @ 162,157*/ 45, 0x00, + /* ABS: 009 Pixels @ 207,157*/ 0, 9, 0x03, 0x00, 0x0C, 0x12, 0x11, 0x08, 0x08, 0x08, 0x11, + /* RLE: 103 Pixels @ 216,157*/ 103, 0x00, + /* ABS: 005 Pixels @ 319,157*/ 0, 5, 0x0D, 0x06, 0x03, 0x06, 0x06, + /* RLE: 017 Pixels @ 324,157*/ 17, 0x00, + /* RLE: 005 Pixels @ 341,157*/ 5, 0x06, + /* RLE: 036 Pixels @ 346,157*/ 36, 0x01, + /* ABS: 002 Pixels @ 382,157*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 384,157*/ 9, 0x03, + /* ABS: 002 Pixels @ 393,157*/ 0, 2, 0x04, 0x04, + /* RLE: 005 Pixels @ 395,157*/ 5, 0x01, + /* RLE: 007 Pixels @ 000,158*/ 7, 0x02, + /* ABS: 025 Pixels @ 007,158*/ 0, 25, 0x0A, 0x0A, 0x03, 0x0E, 0x08, 0x0C, 0x0F, 0x06, 0x03, 0x03, 0x03, 0x00, 0x03, 0x03, 0x12, 0x11, 0x03, 0x19, 0x00, 0x00, 0x19, 0x05, 0x0A, 0x0A, 0x0A, + /* RLE: 006 Pixels @ 032,158*/ 6, 0x02, + /* RLE: 001 Pixels @ 038,158*/ 1, 0x04, + /* RLE: 007 Pixels @ 039,158*/ 7, 0x03, + /* RLE: 001 Pixels @ 046,158*/ 1, 0x0B, + /* RLE: 046 Pixels @ 047,158*/ 46, 0x00, + /* ABS: 003 Pixels @ 093,158*/ 0, 3, 0x0B, 0x04, 0x04, + /* RLE: 005 Pixels @ 096,158*/ 5, 0x03, + /* RLE: 001 Pixels @ 101,158*/ 1, 0x04, + /* RLE: 008 Pixels @ 102,158*/ 8, 0x00, + /* ABS: 006 Pixels @ 110,158*/ 0, 6, 0x0B, 0x00, 0x00, 0x0B, 0x00, 0x0B, + /* RLE: 004 Pixels @ 116,158*/ 4, 0x0A, + /* RLE: 016 Pixels @ 120,158*/ 16, 0x05, + /* ABS: 003 Pixels @ 136,158*/ 0, 3, 0x08, 0x10, 0x08, + /* RLE: 020 Pixels @ 139,158*/ 20, 0x10, + /* ABS: 003 Pixels @ 159,158*/ 0, 3, 0x08, 0x10, 0x08, + /* RLE: 045 Pixels @ 162,158*/ 45, 0x00, + /* ABS: 010 Pixels @ 207,158*/ 0, 10, 0x03, 0x12, 0x08, 0x11, 0x12, 0x0C, 0x00, 0x03, 0x03, 0x03, + /* RLE: 103 Pixels @ 217,158*/ 103, 0x00, + /* ABS: 005 Pixels @ 320,158*/ 0, 5, 0x0D, 0x0D, 0x03, 0x06, 0x06, + /* RLE: 018 Pixels @ 325,158*/ 18, 0x00, + /* RLE: 004 Pixels @ 343,158*/ 4, 0x06, + /* RLE: 037 Pixels @ 347,158*/ 37, 0x01, + /* ABS: 002 Pixels @ 384,158*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 386,158*/ 8, 0x03, + /* ABS: 002 Pixels @ 394,158*/ 0, 2, 0x04, 0x04, + /* RLE: 004 Pixels @ 396,158*/ 4, 0x01, + /* RLE: 009 Pixels @ 000,159*/ 9, 0x02, + /* ABS: 025 Pixels @ 009,159*/ 0, 25, 0x04, 0x03, 0x0B, 0x00, 0x06, 0x0B, 0x03, 0x03, 0x0D, 0x08, 0x08, 0x06, 0x0F, 0x06, 0x03, 0x03, 0x0C, 0x0B, 0x03, 0x03, 0x1A, 0x05, 0x0A, 0x0A, 0x0A, + /* RLE: 005 Pixels @ 034,159*/ 5, 0x02, + /* RLE: 001 Pixels @ 039,159*/ 1, 0x04, + /* RLE: 006 Pixels @ 040,159*/ 6, 0x03, + /* ABS: 002 Pixels @ 046,159*/ 0, 2, 0x04, 0x0B, + /* RLE: 047 Pixels @ 048,159*/ 47, 0x00, + /* ABS: 017 Pixels @ 095,159*/ 0, 17, 0x04, 0x04, 0x03, 0x03, 0x03, 0x04, 0x04, 0x00, 0x0B, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x0B, 0x00, 0x0B, + /* RLE: 004 Pixels @ 112,159*/ 4, 0x0A, + /* RLE: 020 Pixels @ 116,159*/ 20, 0x05, + /* ABS: 003 Pixels @ 136,159*/ 0, 3, 0x08, 0x10, 0x08, + /* RLE: 020 Pixels @ 139,159*/ 20, 0x10, + /* ABS: 003 Pixels @ 159,159*/ 0, 3, 0x08, 0x10, 0x08, + /* RLE: 045 Pixels @ 162,159*/ 45, 0x00, + /* ABS: 010 Pixels @ 207,159*/ 0, 10, 0x03, 0x00, 0x03, 0x03, 0x00, 0x04, 0x00, 0x03, 0x03, 0x04, + /* RLE: 105 Pixels @ 217,159*/ 105, 0x00, + /* ABS: 004 Pixels @ 322,159*/ 0, 4, 0x0D, 0x03, 0x06, 0x06, + /* RLE: 018 Pixels @ 326,159*/ 18, 0x00, + /* ABS: 004 Pixels @ 344,159*/ 0, 4, 0x06, 0x06, 0x03, 0x06, + /* RLE: 037 Pixels @ 348,159*/ 37, 0x01, + /* ABS: 002 Pixels @ 385,159*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 387,159*/ 9, 0x03, + /* ABS: 004 Pixels @ 396,159*/ 0, 4, 0x04, 0x04, 0x01, 0x01, + /* RLE: 010 Pixels @ 000,160*/ 10, 0x02, + /* ABS: 030 Pixels @ 010,160*/ 0, 30, 0x00, 0x04, 0x03, 0x00, 0x00, 0x15, 0x00, 0x08, 0x0C, 0x03, 0x0C, 0x08, 0x0B, 0x03, 0x06, 0x11, 0x11, 0x11, 0x00, 0x00, 0x05, 0x05, 0x05, 0x0A, 0x0A, 0x0A, 0x02, 0x02, 0x02, 0x04, + /* RLE: 006 Pixels @ 040,160*/ 6, 0x03, + /* RLE: 001 Pixels @ 046,160*/ 1, 0x04, + /* RLE: 048 Pixels @ 047,160*/ 48, 0x00, + /* ABS: 013 Pixels @ 095,160*/ 0, 13, 0x04, 0x0B, 0x04, 0x0B, 0x04, 0x04, 0x00, 0x0B, 0x00, 0x00, 0x0B, 0x00, 0x0B, + /* RLE: 004 Pixels @ 108,160*/ 4, 0x0A, + /* RLE: 024 Pixels @ 112,160*/ 24, 0x05, + /* ABS: 003 Pixels @ 136,160*/ 0, 3, 0x08, 0x10, 0x10, + /* RLE: 020 Pixels @ 139,160*/ 20, 0x08, + /* ABS: 003 Pixels @ 159,160*/ 0, 3, 0x10, 0x10, 0x08, + /* RLE: 045 Pixels @ 162,160*/ 45, 0x00, + /* ABS: 010 Pixels @ 207,160*/ 0, 10, 0x03, 0x00, 0x0D, 0x03, 0x11, 0x08, 0x0F, 0x03, 0x03, 0x04, + /* RLE: 106 Pixels @ 217,160*/ 106, 0x00, + /* ABS: 004 Pixels @ 323,160*/ 0, 4, 0x0D, 0x0D, 0x06, 0x06, + /* RLE: 018 Pixels @ 327,160*/ 18, 0x00, + /* ABS: 004 Pixels @ 345,160*/ 0, 4, 0x06, 0x06, 0x03, 0x06, + /* RLE: 037 Pixels @ 349,160*/ 37, 0x01, + /* ABS: 002 Pixels @ 386,160*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 388,160*/ 9, 0x03, + /* ABS: 003 Pixels @ 397,160*/ 0, 3, 0x04, 0x04, 0x01, + /* RLE: 013 Pixels @ 000,161*/ 13, 0x02, + /* ABS: 027 Pixels @ 013,161*/ 0, 27, 0x0A, 0x0A, 0x06, 0x03, 0x06, 0x11, 0x0C, 0x0F, 0x11, 0x03, 0x03, 0x11, 0x0D, 0x03, 0x12, 0x12, 0x03, 0x15, 0x00, 0x19, 0x05, 0x05, 0x0A, 0x0A, 0x0A, 0x02, 0x04, + /* RLE: 006 Pixels @ 040,161*/ 6, 0x03, + /* ABS: 002 Pixels @ 046,161*/ 0, 2, 0x04, 0x0B, + /* RLE: 048 Pixels @ 048,161*/ 48, 0x00, + /* ABS: 008 Pixels @ 096,161*/ 0, 8, 0x0B, 0x00, 0x0B, 0x00, 0x00, 0x0B, 0x00, 0x0B, + /* RLE: 004 Pixels @ 104,161*/ 4, 0x0A, + /* RLE: 029 Pixels @ 108,161*/ 29, 0x05, + /* RLE: 001 Pixels @ 137,161*/ 1, 0x08, + /* RLE: 022 Pixels @ 138,161*/ 22, 0x10, + /* RLE: 001 Pixels @ 160,161*/ 1, 0x08, + /* RLE: 047 Pixels @ 161,161*/ 47, 0x00, + /* ABS: 009 Pixels @ 208,161*/ 0, 9, 0x0C, 0x11, 0x00, 0x08, 0x04, 0x0D, 0x04, 0x03, 0x04, + /* RLE: 107 Pixels @ 217,161*/ 107, 0x00, + /* ABS: 004 Pixels @ 324,161*/ 0, 4, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 018 Pixels @ 328,161*/ 18, 0x00, + /* ABS: 005 Pixels @ 346,161*/ 0, 5, 0x06, 0x06, 0x03, 0x06, 0x06, + /* RLE: 036 Pixels @ 351,161*/ 36, 0x01, + /* ABS: 002 Pixels @ 387,161*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 389,161*/ 9, 0x03, + /* ABS: 002 Pixels @ 398,161*/ 0, 2, 0x04, 0x04, + /* RLE: 015 Pixels @ 000,162*/ 15, 0x02, + /* ABS: 025 Pixels @ 015,162*/ 0, 25, 0x0A, 0x00, 0x03, 0x0B, 0x0B, 0x08, 0x04, 0x03, 0x00, 0x0B, 0x08, 0x0D, 0x0B, 0x0B, 0x03, 0x0C, 0x0B, 0x03, 0x03, 0x1A, 0x05, 0x05, 0x0A, 0x0A, 0x0A, + /* RLE: 006 Pixels @ 040,162*/ 6, 0x03, + /* RLE: 001 Pixels @ 046,162*/ 1, 0x04, + /* RLE: 048 Pixels @ 047,162*/ 48, 0x00, + /* ABS: 005 Pixels @ 095,162*/ 0, 5, 0x0B, 0x00, 0x00, 0x00, 0x0B, + /* RLE: 004 Pixels @ 100,162*/ 4, 0x0A, + /* RLE: 034 Pixels @ 104,162*/ 34, 0x05, + /* RLE: 022 Pixels @ 138,162*/ 22, 0x08, + /* RLE: 047 Pixels @ 160,162*/ 47, 0x00, + /* ABS: 010 Pixels @ 207,162*/ 0, 10, 0x03, 0x0C, 0x0C, 0x0B, 0x08, 0x00, 0x12, 0x0C, 0x03, 0x04, + /* RLE: 108 Pixels @ 217,162*/ 108, 0x00, + /* ABS: 004 Pixels @ 325,162*/ 0, 4, 0x0D, 0x06, 0x03, 0x06, + /* RLE: 018 Pixels @ 329,162*/ 18, 0x00, + /* RLE: 005 Pixels @ 347,162*/ 5, 0x06, + /* RLE: 036 Pixels @ 352,162*/ 36, 0x01, + /* ABS: 002 Pixels @ 388,162*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 390,162*/ 9, 0x03, + /* RLE: 001 Pixels @ 399,162*/ 1, 0x04, + /* RLE: 017 Pixels @ 000,163*/ 17, 0x02, + /* ABS: 023 Pixels @ 017,163*/ 0, 23, 0x18, 0x0B, 0x03, 0x00, 0x00, 0x03, 0x08, 0x0C, 0x00, 0x0F, 0x0D, 0x03, 0x06, 0x11, 0x11, 0x11, 0x00, 0x00, 0x1A, 0x15, 0x15, 0x19, 0x0A, + /* RLE: 006 Pixels @ 040,163*/ 6, 0x03, + /* ABS: 004 Pixels @ 046,163*/ 0, 4, 0x04, 0x00, 0x00, 0x0B, + /* RLE: 041 Pixels @ 050,163*/ 41, 0x00, + /* ABS: 009 Pixels @ 091,163*/ 0, 9, 0x0B, 0x00, 0x00, 0x0B, 0x00, 0x0B, 0x0A, 0x0A, 0x0A, + /* RLE: 035 Pixels @ 100,163*/ 35, 0x05, + /* RLE: 004 Pixels @ 135,163*/ 4, 0x0A, + /* RLE: 068 Pixels @ 139,163*/ 68, 0x00, + /* ABS: 010 Pixels @ 207,163*/ 0, 10, 0x03, 0x04, 0x11, 0x04, 0x08, 0x0B, 0x0F, 0x04, 0x03, 0x03, + /* RLE: 109 Pixels @ 217,163*/ 109, 0x00, + /* ABS: 005 Pixels @ 326,163*/ 0, 5, 0x0D, 0x06, 0x03, 0x06, 0x06, + /* RLE: 017 Pixels @ 331,163*/ 17, 0x00, + /* RLE: 005 Pixels @ 348,163*/ 5, 0x06, + /* RLE: 036 Pixels @ 353,163*/ 36, 0x01, + /* ABS: 002 Pixels @ 389,163*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 391,163*/ 9, 0x03, + /* RLE: 019 Pixels @ 000,164*/ 19, 0x02, + /* ABS: 022 Pixels @ 019,164*/ 0, 22, 0x18, 0x0E, 0x0C, 0x03, 0x0E, 0x0F, 0x04, 0x06, 0x0F, 0x03, 0x11, 0x0D, 0x03, 0x12, 0x12, 0x03, 0x03, 0x00, 0x00, 0x03, 0x03, 0x1A, + /* RLE: 006 Pixels @ 041,164*/ 6, 0x03, + /* ABS: 013 Pixels @ 047,164*/ 0, 13, 0x00, 0x0B, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0B, + /* RLE: 027 Pixels @ 060,164*/ 27, 0x00, + /* ABS: 006 Pixels @ 087,164*/ 0, 6, 0x0B, 0x00, 0x00, 0x0B, 0x00, 0x0B, + /* RLE: 004 Pixels @ 093,164*/ 4, 0x0A, + /* RLE: 034 Pixels @ 097,164*/ 34, 0x05, + /* RLE: 004 Pixels @ 131,164*/ 4, 0x0A, + /* RLE: 073 Pixels @ 135,164*/ 73, 0x00, + /* ABS: 010 Pixels @ 208,164*/ 0, 10, 0x03, 0x0D, 0x08, 0x0F, 0x03, 0x04, 0x03, 0x03, 0x03, 0x04, + /* RLE: 109 Pixels @ 218,164*/ 109, 0x00, + /* ABS: 005 Pixels @ 327,164*/ 0, 5, 0x0D, 0x0D, 0x03, 0x06, 0x06, + /* RLE: 018 Pixels @ 332,164*/ 18, 0x00, + /* RLE: 004 Pixels @ 350,164*/ 4, 0x06, + /* RLE: 036 Pixels @ 354,164*/ 36, 0x01, + /* RLE: 003 Pixels @ 390,164*/ 3, 0x04, + /* RLE: 007 Pixels @ 393,164*/ 7, 0x03, + /* RLE: 022 Pixels @ 000,165*/ 22, 0x02, + /* ABS: 021 Pixels @ 022,165*/ 0, 21, 0x04, 0x03, 0x04, 0x12, 0x06, 0x04, 0x00, 0x0B, 0x08, 0x0D, 0x0B, 0x0B, 0x03, 0x0E, 0x08, 0x08, 0x0D, 0x00, 0x00, 0x05, 0x05, + /* RLE: 004 Pixels @ 043,165*/ 4, 0x03, + /* RLE: 003 Pixels @ 047,165*/ 3, 0x0A, + /* ABS: 022 Pixels @ 050,165*/ 0, 22, 0x0B, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0B, + /* RLE: 011 Pixels @ 072,165*/ 11, 0x00, + /* ABS: 006 Pixels @ 083,165*/ 0, 6, 0x0B, 0x00, 0x00, 0x0B, 0x00, 0x0B, + /* RLE: 004 Pixels @ 089,165*/ 4, 0x0A, + /* RLE: 034 Pixels @ 093,165*/ 34, 0x05, + /* RLE: 004 Pixels @ 127,165*/ 4, 0x0A, + /* RLE: 001 Pixels @ 131,165*/ 1, 0x0B, + /* RLE: 077 Pixels @ 132,165*/ 77, 0x00, + /* ABS: 009 Pixels @ 209,165*/ 0, 9, 0x03, 0x0B, 0x03, 0x00, 0x00, 0x0B, 0x03, 0x03, 0x04, + /* RLE: 110 Pixels @ 218,165*/ 110, 0x00, + /* ABS: 005 Pixels @ 328,165*/ 0, 5, 0x0D, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 018 Pixels @ 333,165*/ 18, 0x00, + /* ABS: 004 Pixels @ 351,165*/ 0, 4, 0x06, 0x03, 0x03, 0x06, + /* RLE: 037 Pixels @ 355,165*/ 37, 0x01, + /* ABS: 002 Pixels @ 392,165*/ 0, 2, 0x04, 0x04, + /* RLE: 006 Pixels @ 394,165*/ 6, 0x03, + /* RLE: 023 Pixels @ 000,166*/ 23, 0x02, + /* RLE: 003 Pixels @ 023,166*/ 3, 0x00, + /* ABS: 015 Pixels @ 026,166*/ 0, 15, 0x03, 0x03, 0x08, 0x0C, 0x00, 0x0F, 0x0D, 0x03, 0x04, 0x08, 0x0C, 0x03, 0x06, 0x12, 0x03, + /* RLE: 009 Pixels @ 041,166*/ 9, 0x05, + /* RLE: 012 Pixels @ 050,166*/ 12, 0x0A, + /* ABS: 023 Pixels @ 062,166*/ 0, 23, 0x0B, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x0B, 0x00, 0x0B, + /* RLE: 004 Pixels @ 085,166*/ 4, 0x0A, + /* RLE: 034 Pixels @ 089,166*/ 34, 0x05, + /* RLE: 004 Pixels @ 123,166*/ 4, 0x0A, + /* RLE: 082 Pixels @ 127,166*/ 82, 0x00, + /* ABS: 008 Pixels @ 209,166*/ 0, 8, 0x03, 0x03, 0x0E, 0x08, 0x08, 0x08, 0x06, 0x03, + /* RLE: 113 Pixels @ 217,166*/ 113, 0x00, + /* ABS: 004 Pixels @ 330,166*/ 0, 4, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 018 Pixels @ 334,166*/ 18, 0x00, + /* ABS: 004 Pixels @ 352,166*/ 0, 4, 0x06, 0x06, 0x03, 0x06, + /* RLE: 037 Pixels @ 356,166*/ 37, 0x01, + /* ABS: 002 Pixels @ 393,166*/ 0, 2, 0x04, 0x04, + /* RLE: 005 Pixels @ 395,166*/ 5, 0x03, + /* RLE: 026 Pixels @ 000,167*/ 26, 0x02, + /* ABS: 015 Pixels @ 026,167*/ 0, 15, 0x0A, 0x03, 0x0E, 0x0F, 0x0C, 0x06, 0x0F, 0x03, 0x06, 0x0F, 0x11, 0x0E, 0x12, 0x06, 0x03, + /* RLE: 021 Pixels @ 041,167*/ 21, 0x05, + /* RLE: 012 Pixels @ 062,167*/ 12, 0x0A, + /* ABS: 007 Pixels @ 074,167*/ 0, 7, 0x0B, 0x00, 0x0B, 0x00, 0x0B, 0x00, 0x0B, + /* RLE: 004 Pixels @ 081,167*/ 4, 0x0A, + /* RLE: 035 Pixels @ 085,167*/ 35, 0x05, + /* RLE: 003 Pixels @ 120,167*/ 3, 0x0A, + /* RLE: 087 Pixels @ 123,167*/ 87, 0x00, + /* ABS: 007 Pixels @ 210,167*/ 0, 7, 0x04, 0x08, 0x0E, 0x0D, 0x0B, 0x0F, 0x04, + /* RLE: 114 Pixels @ 217,167*/ 114, 0x00, + /* ABS: 004 Pixels @ 331,167*/ 0, 4, 0x0D, 0x06, 0x03, 0x06, + /* RLE: 018 Pixels @ 335,167*/ 18, 0x00, + /* RLE: 005 Pixels @ 353,167*/ 5, 0x06, + /* RLE: 036 Pixels @ 358,167*/ 36, 0x01, + /* ABS: 002 Pixels @ 394,167*/ 0, 2, 0x04, 0x04, + /* RLE: 004 Pixels @ 396,167*/ 4, 0x03, + /* RLE: 027 Pixels @ 000,168*/ 27, 0x02, + /* ABS: 014 Pixels @ 027,168*/ 0, 14, 0x00, 0x03, 0x04, 0x12, 0x06, 0x0B, 0x03, 0x06, 0x0E, 0x03, 0x0C, 0x11, 0x0E, 0x03, + /* RLE: 033 Pixels @ 041,168*/ 33, 0x05, + /* RLE: 007 Pixels @ 074,168*/ 7, 0x0A, + /* RLE: 035 Pixels @ 081,168*/ 35, 0x05, + /* RLE: 004 Pixels @ 116,168*/ 4, 0x0A, + /* RLE: 089 Pixels @ 120,168*/ 89, 0x00, + /* ABS: 009 Pixels @ 209,168*/ 0, 9, 0x03, 0x0C, 0x12, 0x03, 0x08, 0x03, 0x06, 0x0C, 0x03, + /* RLE: 114 Pixels @ 218,168*/ 114, 0x00, + /* ABS: 004 Pixels @ 332,168*/ 0, 4, 0x0D, 0x0D, 0x03, 0x06, + /* RLE: 018 Pixels @ 336,168*/ 18, 0x00, + /* RLE: 005 Pixels @ 354,168*/ 5, 0x06, + /* RLE: 036 Pixels @ 359,168*/ 36, 0x01, + /* ABS: 005 Pixels @ 395,168*/ 0, 5, 0x04, 0x04, 0x03, 0x03, 0x03, + /* RLE: 028 Pixels @ 000,169*/ 28, 0x02, + /* ABS: 013 Pixels @ 028,169*/ 0, 13, 0x00, 0x03, 0x03, 0x00, 0x00, 0x03, 0x04, 0x0F, 0x0C, 0x0E, 0x00, 0x03, 0x15, + /* RLE: 071 Pixels @ 041,169*/ 71, 0x05, + /* RLE: 004 Pixels @ 112,169*/ 4, 0x0A, + /* RLE: 001 Pixels @ 116,169*/ 1, 0x0B, + /* RLE: 092 Pixels @ 117,169*/ 92, 0x00, + /* ABS: 010 Pixels @ 209,169*/ 0, 10, 0x03, 0x04, 0x11, 0x0B, 0x06, 0x12, 0x08, 0x00, 0x03, 0x04, + /* RLE: 114 Pixels @ 219,169*/ 114, 0x00, + /* ABS: 005 Pixels @ 333,169*/ 0, 5, 0x0D, 0x06, 0x03, 0x06, 0x06, + /* RLE: 017 Pixels @ 338,169*/ 17, 0x00, + /* RLE: 005 Pixels @ 355,169*/ 5, 0x06, + /* RLE: 036 Pixels @ 360,169*/ 36, 0x01, + /* ABS: 004 Pixels @ 396,169*/ 0, 4, 0x04, 0x04, 0x03, 0x03, + /* RLE: 032 Pixels @ 000,170*/ 32, 0x02, + /* ABS: 008 Pixels @ 032,170*/ 0, 8, 0x0A, 0x0C, 0x03, 0x04, 0x12, 0x06, 0x0B, 0x15, + /* RLE: 068 Pixels @ 040,170*/ 68, 0x05, + /* RLE: 004 Pixels @ 108,170*/ 4, 0x0A, + /* RLE: 098 Pixels @ 112,170*/ 98, 0x00, + /* ABS: 009 Pixels @ 210,170*/ 0, 9, 0x03, 0x0D, 0x06, 0x0E, 0x0F, 0x04, 0x03, 0x03, 0x04, + /* RLE: 115 Pixels @ 219,170*/ 115, 0x00, + /* RLE: 001 Pixels @ 334,170*/ 1, 0x0D, + /* RLE: 004 Pixels @ 335,170*/ 4, 0x06, + /* RLE: 018 Pixels @ 339,170*/ 18, 0x00, + /* ABS: 004 Pixels @ 357,170*/ 0, 4, 0x06, 0x03, 0x03, 0x06, + /* RLE: 036 Pixels @ 361,170*/ 36, 0x01, + /* RLE: 003 Pixels @ 397,170*/ 3, 0x04, + /* RLE: 034 Pixels @ 000,171*/ 34, 0x02, + /* ABS: 006 Pixels @ 034,171*/ 0, 6, 0x0E, 0x00, 0x03, 0x03, 0x03, 0x19, + /* RLE: 064 Pixels @ 040,171*/ 64, 0x05, + /* RLE: 004 Pixels @ 104,171*/ 4, 0x0A, + /* RLE: 103 Pixels @ 108,171*/ 103, 0x00, + /* ABS: 008 Pixels @ 211,171*/ 0, 8, 0x03, 0x00, 0x00, 0x03, 0x03, 0x0B, 0x03, 0x04, + /* RLE: 116 Pixels @ 219,171*/ 116, 0x00, + /* ABS: 005 Pixels @ 335,171*/ 0, 5, 0x0D, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 018 Pixels @ 340,171*/ 18, 0x00, + /* ABS: 004 Pixels @ 358,171*/ 0, 4, 0x06, 0x06, 0x03, 0x06, + /* RLE: 038 Pixels @ 362,171*/ 38, 0x01, + /* RLE: 036 Pixels @ 000,172*/ 36, 0x02, + /* RLE: 003 Pixels @ 036,172*/ 3, 0x0A, + /* RLE: 061 Pixels @ 039,172*/ 61, 0x05, + /* RLE: 004 Pixels @ 100,172*/ 4, 0x0A, + /* RLE: 106 Pixels @ 104,172*/ 106, 0x00, + /* ABS: 008 Pixels @ 210,172*/ 0, 8, 0x03, 0x00, 0x0C, 0x12, 0x11, 0x08, 0x08, 0x03, + /* RLE: 119 Pixels @ 218,172*/ 119, 0x00, + /* ABS: 004 Pixels @ 337,172*/ 0, 4, 0x0D, 0x0D, 0x06, 0x06, + /* RLE: 018 Pixels @ 341,172*/ 18, 0x00, + /* RLE: 005 Pixels @ 359,172*/ 5, 0x06, + /* RLE: 036 Pixels @ 364,172*/ 36, 0x01, + /* RLE: 038 Pixels @ 000,173*/ 38, 0x02, + /* RLE: 003 Pixels @ 038,173*/ 3, 0x0A, + /* RLE: 056 Pixels @ 041,173*/ 56, 0x05, + /* RLE: 003 Pixels @ 097,173*/ 3, 0x0A, + /* RLE: 110 Pixels @ 100,173*/ 110, 0x00, + /* ABS: 009 Pixels @ 210,173*/ 0, 9, 0x03, 0x12, 0x08, 0x11, 0x12, 0x0E, 0x0D, 0x00, 0x03, + /* RLE: 119 Pixels @ 219,173*/ 119, 0x00, + /* ABS: 004 Pixels @ 338,173*/ 0, 4, 0x0D, 0x03, 0x03, 0x06, + /* RLE: 018 Pixels @ 342,173*/ 18, 0x00, + /* RLE: 005 Pixels @ 360,173*/ 5, 0x06, + /* RLE: 035 Pixels @ 365,173*/ 35, 0x01, + /* RLE: 040 Pixels @ 000,174*/ 40, 0x02, + /* RLE: 003 Pixels @ 040,174*/ 3, 0x0A, + /* RLE: 050 Pixels @ 043,174*/ 50, 0x05, + /* RLE: 004 Pixels @ 093,174*/ 4, 0x0A, + /* RLE: 113 Pixels @ 097,174*/ 113, 0x00, + /* ABS: 002 Pixels @ 210,174*/ 0, 2, 0x03, 0x00, + /* RLE: 004 Pixels @ 212,174*/ 4, 0x03, + /* ABS: 004 Pixels @ 216,174*/ 0, 4, 0x0E, 0x0C, 0x03, 0x04, + /* RLE: 119 Pixels @ 220,174*/ 119, 0x00, + /* ABS: 004 Pixels @ 339,174*/ 0, 4, 0x0D, 0x06, 0x03, 0x06, + /* RLE: 018 Pixels @ 343,174*/ 18, 0x00, + /* RLE: 005 Pixels @ 361,174*/ 5, 0x06, + /* RLE: 034 Pixels @ 366,174*/ 34, 0x01, + /* RLE: 043 Pixels @ 000,175*/ 43, 0x02, + /* RLE: 007 Pixels @ 043,175*/ 7, 0x0A, + /* RLE: 039 Pixels @ 050,175*/ 39, 0x05, + /* RLE: 004 Pixels @ 089,175*/ 4, 0x0A, + /* RLE: 118 Pixels @ 093,175*/ 118, 0x00, + /* RLE: 004 Pixels @ 211,175*/ 4, 0x03, + /* ABS: 005 Pixels @ 215,175*/ 0, 5, 0x0B, 0x11, 0x06, 0x03, 0x04, + /* RLE: 120 Pixels @ 220,175*/ 120, 0x00, + /* RLE: 001 Pixels @ 340,175*/ 1, 0x0D, + /* RLE: 004 Pixels @ 341,175*/ 4, 0x06, + /* RLE: 018 Pixels @ 345,175*/ 18, 0x00, + /* ABS: 004 Pixels @ 363,175*/ 0, 4, 0x06, 0x03, 0x06, 0x06, + /* RLE: 033 Pixels @ 367,175*/ 33, 0x01, + /* RLE: 044 Pixels @ 000,176*/ 44, 0x02, + /* ABS: 002 Pixels @ 044,176*/ 0, 2, 0x01, 0x04, + /* RLE: 004 Pixels @ 046,176*/ 4, 0x00, + /* RLE: 012 Pixels @ 050,176*/ 12, 0x0A, + /* RLE: 023 Pixels @ 062,176*/ 23, 0x05, + /* RLE: 004 Pixels @ 085,176*/ 4, 0x0A, + /* RLE: 122 Pixels @ 089,176*/ 122, 0x00, + /* ABS: 009 Pixels @ 211,176*/ 0, 9, 0x03, 0x12, 0x11, 0x08, 0x08, 0x08, 0x0B, 0x03, 0x03, + /* RLE: 121 Pixels @ 220,176*/ 121, 0x00, + /* ABS: 005 Pixels @ 341,176*/ 0, 5, 0x0D, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 018 Pixels @ 346,176*/ 18, 0x00, + /* ABS: 004 Pixels @ 364,176*/ 0, 4, 0x06, 0x03, 0x03, 0x06, + /* RLE: 032 Pixels @ 368,176*/ 32, 0x01, + /* RLE: 043 Pixels @ 000,177*/ 43, 0x02, + /* RLE: 005 Pixels @ 043,177*/ 5, 0x04, + /* RLE: 014 Pixels @ 048,177*/ 14, 0x00, + /* RLE: 012 Pixels @ 062,177*/ 12, 0x0A, + /* RLE: 007 Pixels @ 074,177*/ 7, 0x05, + /* RLE: 005 Pixels @ 081,177*/ 5, 0x09, + /* RLE: 001 Pixels @ 086,177*/ 1, 0x0C, + /* RLE: 124 Pixels @ 087,177*/ 124, 0x00, + /* ABS: 010 Pixels @ 211,177*/ 0, 10, 0x03, 0x0D, 0x06, 0x0C, 0x04, 0x00, 0x0D, 0x00, 0x0B, 0x03, + /* RLE: 121 Pixels @ 221,177*/ 121, 0x00, + /* ABS: 005 Pixels @ 342,177*/ 0, 5, 0x0D, 0x0D, 0x06, 0x0D, 0x06, + /* RLE: 018 Pixels @ 347,177*/ 18, 0x00, + /* RLE: 004 Pixels @ 365,177*/ 4, 0x06, + /* RLE: 031 Pixels @ 369,177*/ 31, 0x01, + /* RLE: 042 Pixels @ 000,178*/ 42, 0x02, + /* ABS: 007 Pixels @ 042,178*/ 0, 7, 0x04, 0x04, 0x03, 0x03, 0x03, 0x04, 0x04, + /* RLE: 025 Pixels @ 049,178*/ 25, 0x00, + /* RLE: 003 Pixels @ 074,178*/ 3, 0x0A, + /* RLE: 009 Pixels @ 077,178*/ 9, 0x09, + /* RLE: 001 Pixels @ 086,178*/ 1, 0x0C, + /* RLE: 124 Pixels @ 087,178*/ 124, 0x00, + /* ABS: 011 Pixels @ 211,178*/ 0, 11, 0x03, 0x03, 0x00, 0x0C, 0x06, 0x0F, 0x08, 0x08, 0x08, 0x04, 0x03, + /* RLE: 122 Pixels @ 222,178*/ 122, 0x00, + /* ABS: 004 Pixels @ 344,178*/ 0, 4, 0x0D, 0x03, 0x06, 0x06, + /* RLE: 018 Pixels @ 348,178*/ 18, 0x00, + /* RLE: 005 Pixels @ 366,178*/ 5, 0x06, + /* RLE: 029 Pixels @ 371,178*/ 29, 0x01, + /* RLE: 042 Pixels @ 000,179*/ 42, 0x02, + /* RLE: 001 Pixels @ 042,179*/ 1, 0x04, + /* RLE: 005 Pixels @ 043,179*/ 5, 0x03, + /* RLE: 001 Pixels @ 048,179*/ 1, 0x04, + /* RLE: 028 Pixels @ 049,179*/ 28, 0x00, + /* RLE: 001 Pixels @ 077,179*/ 1, 0x0C, + /* RLE: 009 Pixels @ 078,179*/ 9, 0x09, + /* RLE: 001 Pixels @ 087,179*/ 1, 0x0C, + /* RLE: 123 Pixels @ 088,179*/ 123, 0x00, + /* ABS: 011 Pixels @ 211,179*/ 0, 11, 0x03, 0x12, 0x08, 0x08, 0x11, 0x12, 0x08, 0x0C, 0x12, 0x0E, 0x03, + /* RLE: 034 Pixels @ 222,179*/ 34, 0x00, + /* RLE: 005 Pixels @ 256,179*/ 5, 0x04, + /* RLE: 084 Pixels @ 261,179*/ 84, 0x00, + /* ABS: 004 Pixels @ 345,179*/ 0, 4, 0x0D, 0x03, 0x03, 0x06, + /* RLE: 018 Pixels @ 349,179*/ 18, 0x00, + /* RLE: 005 Pixels @ 367,179*/ 5, 0x06, + /* RLE: 028 Pixels @ 372,179*/ 28, 0x01, + /* RLE: 041 Pixels @ 000,180*/ 41, 0x02, + /* ABS: 002 Pixels @ 041,180*/ 0, 2, 0x04, 0x04, + /* RLE: 006 Pixels @ 043,180*/ 6, 0x03, + /* RLE: 029 Pixels @ 049,180*/ 29, 0x00, + /* RLE: 009 Pixels @ 078,180*/ 9, 0x09, + /* RLE: 001 Pixels @ 087,180*/ 1, 0x0C, + /* RLE: 123 Pixels @ 088,180*/ 123, 0x00, + /* ABS: 011 Pixels @ 211,180*/ 0, 11, 0x03, 0x0B, 0x00, 0x03, 0x03, 0x03, 0x04, 0x00, 0x0B, 0x04, 0x03, + /* RLE: 033 Pixels @ 222,180*/ 33, 0x00, + /* ABS: 007 Pixels @ 255,180*/ 0, 7, 0x04, 0x04, 0x03, 0x03, 0x03, 0x04, 0x04, + /* RLE: 084 Pixels @ 262,180*/ 84, 0x00, + /* ABS: 004 Pixels @ 346,180*/ 0, 4, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 018 Pixels @ 350,180*/ 18, 0x00, + /* ABS: 005 Pixels @ 368,180*/ 0, 5, 0x06, 0x06, 0x03, 0x06, 0x06, + /* RLE: 027 Pixels @ 373,180*/ 27, 0x01, + /* RLE: 042 Pixels @ 000,181*/ 42, 0x02, + /* RLE: 001 Pixels @ 042,181*/ 1, 0x04, + /* RLE: 006 Pixels @ 043,181*/ 6, 0x03, + /* RLE: 001 Pixels @ 049,181*/ 1, 0x04, + /* RLE: 028 Pixels @ 050,181*/ 28, 0x00, + /* RLE: 001 Pixels @ 078,181*/ 1, 0x0C, + /* RLE: 009 Pixels @ 079,181*/ 9, 0x09, + /* RLE: 001 Pixels @ 088,181*/ 1, 0x0C, + /* RLE: 121 Pixels @ 089,181*/ 121, 0x00, + /* ABS: 011 Pixels @ 210,181*/ 0, 11, 0x04, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x0B, 0x03, 0x03, 0x03, + /* RLE: 034 Pixels @ 221,181*/ 34, 0x00, + /* RLE: 001 Pixels @ 255,181*/ 1, 0x04, + /* RLE: 005 Pixels @ 256,181*/ 5, 0x03, + /* RLE: 001 Pixels @ 261,181*/ 1, 0x04, + /* RLE: 085 Pixels @ 262,181*/ 85, 0x00, + /* RLE: 001 Pixels @ 347,181*/ 1, 0x0D, + /* RLE: 004 Pixels @ 348,181*/ 4, 0x06, + /* RLE: 018 Pixels @ 352,181*/ 18, 0x00, + /* ABS: 004 Pixels @ 370,181*/ 0, 4, 0x06, 0x03, 0x03, 0x06, + /* RLE: 026 Pixels @ 374,181*/ 26, 0x01, + /* RLE: 042 Pixels @ 000,182*/ 42, 0x02, + /* RLE: 001 Pixels @ 042,182*/ 1, 0x04, + /* RLE: 006 Pixels @ 043,182*/ 6, 0x03, + /* RLE: 001 Pixels @ 049,182*/ 1, 0x04, + /* RLE: 029 Pixels @ 050,182*/ 29, 0x00, + /* RLE: 009 Pixels @ 079,182*/ 9, 0x09, + /* RLE: 001 Pixels @ 088,182*/ 1, 0x0C, + /* RLE: 117 Pixels @ 089,182*/ 117, 0x00, + /* RLE: 003 Pixels @ 206,182*/ 3, 0x04, + /* RLE: 005 Pixels @ 209,182*/ 5, 0x03, + /* ABS: 006 Pixels @ 214,182*/ 0, 6, 0x0E, 0x08, 0x08, 0x08, 0x06, 0x03, + /* RLE: 034 Pixels @ 220,182*/ 34, 0x00, + /* RLE: 001 Pixels @ 254,182*/ 1, 0x04, + /* RLE: 006 Pixels @ 255,182*/ 6, 0x03, + /* RLE: 001 Pixels @ 261,182*/ 1, 0x04, + /* RLE: 086 Pixels @ 262,182*/ 86, 0x00, + /* ABS: 005 Pixels @ 348,182*/ 0, 5, 0x0D, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 018 Pixels @ 353,182*/ 18, 0x00, + /* RLE: 004 Pixels @ 371,182*/ 4, 0x06, + /* RLE: 025 Pixels @ 375,182*/ 25, 0x01, + /* RLE: 042 Pixels @ 000,183*/ 42, 0x02, + /* RLE: 001 Pixels @ 042,183*/ 1, 0x04, + /* RLE: 006 Pixels @ 043,183*/ 6, 0x03, + /* RLE: 001 Pixels @ 049,183*/ 1, 0x04, + /* RLE: 029 Pixels @ 050,183*/ 29, 0x00, + /* RLE: 001 Pixels @ 079,183*/ 1, 0x0C, + /* RLE: 009 Pixels @ 080,183*/ 9, 0x09, + /* RLE: 001 Pixels @ 089,183*/ 1, 0x0C, + /* RLE: 112 Pixels @ 090,183*/ 112, 0x00, + /* RLE: 003 Pixels @ 202,183*/ 3, 0x04, + /* RLE: 008 Pixels @ 205,183*/ 8, 0x03, + /* ABS: 008 Pixels @ 213,183*/ 0, 8, 0x0C, 0x08, 0x0E, 0x0D, 0x0B, 0x0F, 0x04, 0x03, + /* RLE: 033 Pixels @ 221,183*/ 33, 0x00, + /* RLE: 001 Pixels @ 254,183*/ 1, 0x04, + /* RLE: 006 Pixels @ 255,183*/ 6, 0x03, + /* RLE: 001 Pixels @ 261,183*/ 1, 0x04, + /* RLE: 087 Pixels @ 262,183*/ 87, 0x00, + /* ABS: 005 Pixels @ 349,183*/ 0, 5, 0x0D, 0x0D, 0x03, 0x0D, 0x06, + /* RLE: 018 Pixels @ 354,183*/ 18, 0x00, + /* RLE: 005 Pixels @ 372,183*/ 5, 0x06, + /* RLE: 023 Pixels @ 377,183*/ 23, 0x01, + /* RLE: 042 Pixels @ 000,184*/ 42, 0x02, + /* RLE: 001 Pixels @ 042,184*/ 1, 0x04, + /* RLE: 006 Pixels @ 043,184*/ 6, 0x03, + /* RLE: 001 Pixels @ 049,184*/ 1, 0x04, + /* RLE: 030 Pixels @ 050,184*/ 30, 0x00, + /* RLE: 009 Pixels @ 080,184*/ 9, 0x09, + /* RLE: 001 Pixels @ 089,184*/ 1, 0x0C, + /* RLE: 108 Pixels @ 090,184*/ 108, 0x00, + /* RLE: 003 Pixels @ 198,184*/ 3, 0x04, + /* RLE: 012 Pixels @ 201,184*/ 12, 0x03, + /* ABS: 009 Pixels @ 213,184*/ 0, 9, 0x0C, 0x12, 0x03, 0x08, 0x03, 0x06, 0x0C, 0x03, 0x04, + /* RLE: 032 Pixels @ 222,184*/ 32, 0x00, + /* RLE: 001 Pixels @ 254,184*/ 1, 0x04, + /* RLE: 006 Pixels @ 255,184*/ 6, 0x03, + /* RLE: 001 Pixels @ 261,184*/ 1, 0x04, + /* RLE: 089 Pixels @ 262,184*/ 89, 0x00, + /* ABS: 004 Pixels @ 351,184*/ 0, 4, 0x0D, 0x03, 0x06, 0x06, + /* RLE: 018 Pixels @ 355,184*/ 18, 0x00, + /* RLE: 005 Pixels @ 373,184*/ 5, 0x06, + /* RLE: 022 Pixels @ 378,184*/ 22, 0x01, + /* RLE: 042 Pixels @ 000,185*/ 42, 0x02, + /* RLE: 001 Pixels @ 042,185*/ 1, 0x04, + /* RLE: 006 Pixels @ 043,185*/ 6, 0x03, + /* RLE: 001 Pixels @ 049,185*/ 1, 0x04, + /* RLE: 030 Pixels @ 050,185*/ 30, 0x00, + /* RLE: 001 Pixels @ 080,185*/ 1, 0x0C, + /* RLE: 009 Pixels @ 081,185*/ 9, 0x09, + /* RLE: 104 Pixels @ 090,185*/ 104, 0x00, + /* RLE: 003 Pixels @ 194,185*/ 3, 0x04, + /* RLE: 016 Pixels @ 197,185*/ 16, 0x03, + /* ABS: 009 Pixels @ 213,185*/ 0, 9, 0x04, 0x11, 0x0B, 0x06, 0x12, 0x08, 0x0B, 0x03, 0x04, + /* RLE: 032 Pixels @ 222,185*/ 32, 0x00, + /* RLE: 001 Pixels @ 254,185*/ 1, 0x04, + /* RLE: 006 Pixels @ 255,185*/ 6, 0x03, + /* RLE: 001 Pixels @ 261,185*/ 1, 0x04, + /* RLE: 090 Pixels @ 262,185*/ 90, 0x00, + /* ABS: 004 Pixels @ 352,185*/ 0, 4, 0x0D, 0x03, 0x06, 0x06, + /* RLE: 018 Pixels @ 356,185*/ 18, 0x00, + /* ABS: 005 Pixels @ 374,185*/ 0, 5, 0x06, 0x06, 0x03, 0x06, 0x06, + /* RLE: 021 Pixels @ 379,185*/ 21, 0x01, + /* RLE: 042 Pixels @ 000,186*/ 42, 0x02, + /* RLE: 001 Pixels @ 042,186*/ 1, 0x04, + /* RLE: 007 Pixels @ 043,186*/ 7, 0x03, + /* RLE: 031 Pixels @ 050,186*/ 31, 0x00, + /* RLE: 009 Pixels @ 081,186*/ 9, 0x09, + /* RLE: 001 Pixels @ 090,186*/ 1, 0x0C, + /* RLE: 099 Pixels @ 091,186*/ 99, 0x00, + /* RLE: 003 Pixels @ 190,186*/ 3, 0x04, + /* RLE: 021 Pixels @ 193,186*/ 21, 0x03, + /* ABS: 005 Pixels @ 214,186*/ 0, 5, 0x0D, 0x06, 0x0E, 0x0F, 0x04, + /* RLE: 004 Pixels @ 219,186*/ 4, 0x03, + /* RLE: 031 Pixels @ 223,186*/ 31, 0x00, + /* RLE: 001 Pixels @ 254,186*/ 1, 0x04, + /* RLE: 006 Pixels @ 255,186*/ 6, 0x03, + /* RLE: 001 Pixels @ 261,186*/ 1, 0x04, + /* RLE: 091 Pixels @ 262,186*/ 91, 0x00, + /* ABS: 004 Pixels @ 353,186*/ 0, 4, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 019 Pixels @ 357,186*/ 19, 0x00, + /* ABS: 004 Pixels @ 376,186*/ 0, 4, 0x06, 0x03, 0x06, 0x06, + /* RLE: 020 Pixels @ 380,186*/ 20, 0x01, + /* RLE: 043 Pixels @ 000,187*/ 43, 0x02, + /* RLE: 001 Pixels @ 043,187*/ 1, 0x04, + /* RLE: 006 Pixels @ 044,187*/ 6, 0x03, + /* RLE: 001 Pixels @ 050,187*/ 1, 0x04, + /* RLE: 030 Pixels @ 051,187*/ 30, 0x00, + /* RLE: 001 Pixels @ 081,187*/ 1, 0x0C, + /* RLE: 009 Pixels @ 082,187*/ 9, 0x09, + /* RLE: 095 Pixels @ 091,187*/ 95, 0x00, + /* RLE: 004 Pixels @ 186,187*/ 4, 0x04, + /* RLE: 025 Pixels @ 190,187*/ 25, 0x03, + /* ABS: 008 Pixels @ 215,187*/ 0, 8, 0x00, 0x00, 0x03, 0x03, 0x00, 0x0C, 0x12, 0x03, + /* RLE: 031 Pixels @ 223,187*/ 31, 0x00, + /* RLE: 001 Pixels @ 254,187*/ 1, 0x04, + /* RLE: 006 Pixels @ 255,187*/ 6, 0x03, + /* RLE: 001 Pixels @ 261,187*/ 1, 0x04, + /* RLE: 092 Pixels @ 262,187*/ 92, 0x00, + /* ABS: 004 Pixels @ 354,187*/ 0, 4, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 019 Pixels @ 358,187*/ 19, 0x00, + /* ABS: 004 Pixels @ 377,187*/ 0, 4, 0x06, 0x03, 0x06, 0x06, + /* RLE: 019 Pixels @ 381,187*/ 19, 0x01, + /* RLE: 043 Pixels @ 000,188*/ 43, 0x02, + /* RLE: 001 Pixels @ 043,188*/ 1, 0x04, + /* RLE: 006 Pixels @ 044,188*/ 6, 0x03, + /* RLE: 001 Pixels @ 050,188*/ 1, 0x04, + /* RLE: 031 Pixels @ 051,188*/ 31, 0x00, + /* RLE: 009 Pixels @ 082,188*/ 9, 0x09, + /* RLE: 001 Pixels @ 091,188*/ 1, 0x0C, + /* RLE: 090 Pixels @ 092,188*/ 90, 0x00, + /* RLE: 004 Pixels @ 182,188*/ 4, 0x04, + /* RLE: 024 Pixels @ 186,188*/ 24, 0x03, + /* RLE: 003 Pixels @ 210,188*/ 3, 0x04, + /* ABS: 009 Pixels @ 213,188*/ 0, 9, 0x03, 0x00, 0x0C, 0x12, 0x11, 0x08, 0x08, 0x08, 0x11, + /* RLE: 032 Pixels @ 222,188*/ 32, 0x00, + /* RLE: 001 Pixels @ 254,188*/ 1, 0x04, + /* RLE: 006 Pixels @ 255,188*/ 6, 0x03, + /* RLE: 001 Pixels @ 261,188*/ 1, 0x04, + /* RLE: 093 Pixels @ 262,188*/ 93, 0x00, + /* ABS: 005 Pixels @ 355,188*/ 0, 5, 0x0D, 0x0D, 0x03, 0x06, 0x06, + /* RLE: 018 Pixels @ 360,188*/ 18, 0x00, + /* RLE: 004 Pixels @ 378,188*/ 4, 0x06, + /* RLE: 018 Pixels @ 382,188*/ 18, 0x01, + /* RLE: 043 Pixels @ 000,189*/ 43, 0x02, + /* RLE: 001 Pixels @ 043,189*/ 1, 0x04, + /* RLE: 006 Pixels @ 044,189*/ 6, 0x03, + /* RLE: 001 Pixels @ 050,189*/ 1, 0x04, + /* RLE: 031 Pixels @ 051,189*/ 31, 0x00, + /* RLE: 001 Pixels @ 082,189*/ 1, 0x0C, + /* RLE: 009 Pixels @ 083,189*/ 9, 0x09, + /* RLE: 086 Pixels @ 092,189*/ 86, 0x00, + /* RLE: 004 Pixels @ 178,189*/ 4, 0x04, + /* RLE: 024 Pixels @ 182,189*/ 24, 0x03, + /* RLE: 004 Pixels @ 206,189*/ 4, 0x04, + /* RLE: 003 Pixels @ 210,189*/ 3, 0x00, + /* ABS: 010 Pixels @ 213,189*/ 0, 10, 0x03, 0x12, 0x08, 0x11, 0x12, 0x0C, 0x0B, 0x03, 0x03, 0x03, + /* RLE: 030 Pixels @ 223,189*/ 30, 0x00, + /* RLE: 001 Pixels @ 253,189*/ 1, 0x04, + /* RLE: 007 Pixels @ 254,189*/ 7, 0x03, + /* RLE: 095 Pixels @ 261,189*/ 95, 0x00, + /* ABS: 005 Pixels @ 356,189*/ 0, 5, 0x0D, 0x06, 0x03, 0x06, 0x06, + /* RLE: 018 Pixels @ 361,189*/ 18, 0x00, + /* RLE: 005 Pixels @ 379,189*/ 5, 0x06, + /* RLE: 016 Pixels @ 384,189*/ 16, 0x01, + /* RLE: 043 Pixels @ 000,190*/ 43, 0x02, + /* RLE: 001 Pixels @ 043,190*/ 1, 0x04, + /* RLE: 006 Pixels @ 044,190*/ 6, 0x03, + /* RLE: 001 Pixels @ 050,190*/ 1, 0x04, + /* RLE: 032 Pixels @ 051,190*/ 32, 0x00, + /* RLE: 009 Pixels @ 083,190*/ 9, 0x09, + /* RLE: 001 Pixels @ 092,190*/ 1, 0x0C, + /* RLE: 081 Pixels @ 093,190*/ 81, 0x00, + /* RLE: 004 Pixels @ 174,190*/ 4, 0x04, + /* RLE: 024 Pixels @ 178,190*/ 24, 0x03, + /* RLE: 004 Pixels @ 202,190*/ 4, 0x04, + /* RLE: 007 Pixels @ 206,190*/ 7, 0x00, + /* ABS: 011 Pixels @ 213,190*/ 0, 11, 0x03, 0x00, 0x03, 0x03, 0x03, 0x00, 0x00, 0x03, 0x03, 0x03, 0x04, + /* RLE: 029 Pixels @ 224,190*/ 29, 0x00, + /* RLE: 001 Pixels @ 253,190*/ 1, 0x04, + /* RLE: 006 Pixels @ 254,190*/ 6, 0x03, + /* RLE: 001 Pixels @ 260,190*/ 1, 0x04, + /* RLE: 096 Pixels @ 261,190*/ 96, 0x00, + /* ABS: 005 Pixels @ 357,190*/ 0, 5, 0x0D, 0x0D, 0x03, 0x06, 0x06, + /* RLE: 018 Pixels @ 362,190*/ 18, 0x00, + /* ABS: 005 Pixels @ 380,190*/ 0, 5, 0x06, 0x06, 0x03, 0x06, 0x06, + /* RLE: 015 Pixels @ 385,190*/ 15, 0x01, + /* RLE: 043 Pixels @ 000,191*/ 43, 0x02, + /* RLE: 001 Pixels @ 043,191*/ 1, 0x04, + /* RLE: 006 Pixels @ 044,191*/ 6, 0x03, + /* RLE: 001 Pixels @ 050,191*/ 1, 0x04, + /* RLE: 032 Pixels @ 051,191*/ 32, 0x00, + /* RLE: 001 Pixels @ 083,191*/ 1, 0x0C, + /* RLE: 009 Pixels @ 084,191*/ 9, 0x09, + /* RLE: 077 Pixels @ 093,191*/ 77, 0x00, + /* RLE: 004 Pixels @ 170,191*/ 4, 0x04, + /* RLE: 024 Pixels @ 174,191*/ 24, 0x03, + /* RLE: 004 Pixels @ 198,191*/ 4, 0x04, + /* RLE: 013 Pixels @ 202,191*/ 13, 0x00, + /* ABS: 009 Pixels @ 215,191*/ 0, 9, 0x03, 0x0E, 0x08, 0x08, 0x08, 0x06, 0x03, 0x03, 0x04, + /* RLE: 029 Pixels @ 224,191*/ 29, 0x00, + /* RLE: 001 Pixels @ 253,191*/ 1, 0x04, + /* RLE: 006 Pixels @ 254,191*/ 6, 0x03, + /* RLE: 001 Pixels @ 260,191*/ 1, 0x04, + /* RLE: 098 Pixels @ 261,191*/ 98, 0x00, + /* ABS: 004 Pixels @ 359,191*/ 0, 4, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 018 Pixels @ 363,191*/ 18, 0x00, + /* ABS: 005 Pixels @ 381,191*/ 0, 5, 0x06, 0x06, 0x03, 0x06, 0x06, + /* RLE: 014 Pixels @ 386,191*/ 14, 0x01, + /* RLE: 043 Pixels @ 000,192*/ 43, 0x02, + /* RLE: 001 Pixels @ 043,192*/ 1, 0x04, + /* RLE: 007 Pixels @ 044,192*/ 7, 0x03, + /* RLE: 032 Pixels @ 051,192*/ 32, 0x00, + /* RLE: 001 Pixels @ 083,192*/ 1, 0x0C, + /* RLE: 009 Pixels @ 084,192*/ 9, 0x09, + /* RLE: 001 Pixels @ 093,192*/ 1, 0x0C, + /* RLE: 072 Pixels @ 094,192*/ 72, 0x00, + /* RLE: 004 Pixels @ 166,192*/ 4, 0x04, + /* RLE: 024 Pixels @ 170,192*/ 24, 0x03, + /* RLE: 004 Pixels @ 194,192*/ 4, 0x04, + /* RLE: 016 Pixels @ 198,192*/ 16, 0x00, + /* ABS: 010 Pixels @ 214,192*/ 0, 10, 0x03, 0x04, 0x08, 0x12, 0x04, 0x04, 0x0F, 0x04, 0x03, 0x04, + /* RLE: 029 Pixels @ 224,192*/ 29, 0x00, + /* RLE: 001 Pixels @ 253,192*/ 1, 0x04, + /* RLE: 006 Pixels @ 254,192*/ 6, 0x03, + /* RLE: 001 Pixels @ 260,192*/ 1, 0x04, + /* RLE: 099 Pixels @ 261,192*/ 99, 0x00, + /* ABS: 004 Pixels @ 360,192*/ 0, 4, 0x0D, 0x0D, 0x06, 0x06, + /* RLE: 019 Pixels @ 364,192*/ 19, 0x00, + /* ABS: 004 Pixels @ 383,192*/ 0, 4, 0x06, 0x03, 0x06, 0x06, + /* RLE: 013 Pixels @ 387,192*/ 13, 0x01, + /* RLE: 044 Pixels @ 000,193*/ 44, 0x02, + /* RLE: 001 Pixels @ 044,193*/ 1, 0x04, + /* RLE: 006 Pixels @ 045,193*/ 6, 0x03, + /* RLE: 001 Pixels @ 051,193*/ 1, 0x04, + /* RLE: 032 Pixels @ 052,193*/ 32, 0x00, + /* RLE: 001 Pixels @ 084,193*/ 1, 0x0C, + /* RLE: 009 Pixels @ 085,193*/ 9, 0x09, + /* RLE: 069 Pixels @ 094,193*/ 69, 0x00, + /* RLE: 003 Pixels @ 163,193*/ 3, 0x04, + /* RLE: 025 Pixels @ 166,193*/ 25, 0x03, + /* RLE: 003 Pixels @ 191,193*/ 3, 0x04, + /* RLE: 020 Pixels @ 194,193*/ 20, 0x00, + /* ABS: 011 Pixels @ 214,193*/ 0, 11, 0x03, 0x0C, 0x0D, 0x03, 0x03, 0x03, 0x06, 0x0C, 0x03, 0x03, 0x03, + /* RLE: 028 Pixels @ 225,193*/ 28, 0x00, + /* RLE: 001 Pixels @ 253,193*/ 1, 0x04, + /* RLE: 006 Pixels @ 254,193*/ 6, 0x03, + /* RLE: 001 Pixels @ 260,193*/ 1, 0x04, + /* RLE: 100 Pixels @ 261,193*/ 100, 0x00, + /* ABS: 004 Pixels @ 361,193*/ 0, 4, 0x0D, 0x06, 0x03, 0x06, + /* RLE: 019 Pixels @ 365,193*/ 19, 0x00, + /* RLE: 004 Pixels @ 384,193*/ 4, 0x06, + /* RLE: 012 Pixels @ 388,193*/ 12, 0x01, + /* RLE: 044 Pixels @ 000,194*/ 44, 0x02, + /* RLE: 001 Pixels @ 044,194*/ 1, 0x04, + /* RLE: 006 Pixels @ 045,194*/ 6, 0x03, + /* RLE: 001 Pixels @ 051,194*/ 1, 0x04, + /* RLE: 032 Pixels @ 052,194*/ 32, 0x00, + /* RLE: 001 Pixels @ 084,194*/ 1, 0x0C, + /* RLE: 009 Pixels @ 085,194*/ 9, 0x09, + /* RLE: 001 Pixels @ 094,194*/ 1, 0x0C, + /* RLE: 067 Pixels @ 095,194*/ 67, 0x00, + /* ABS: 002 Pixels @ 162,194*/ 0, 2, 0x04, 0x04, + /* RLE: 023 Pixels @ 164,194*/ 23, 0x03, + /* RLE: 003 Pixels @ 187,194*/ 3, 0x04, + /* RLE: 024 Pixels @ 190,194*/ 24, 0x00, + /* ABS: 011 Pixels @ 214,194*/ 0, 11, 0x03, 0x0B, 0x11, 0x00, 0x03, 0x0B, 0x0F, 0x12, 0x0D, 0x0F, 0x03, + /* RLE: 028 Pixels @ 225,194*/ 28, 0x00, + /* RLE: 001 Pixels @ 253,194*/ 1, 0x04, + /* RLE: 006 Pixels @ 254,194*/ 6, 0x03, + /* RLE: 001 Pixels @ 260,194*/ 1, 0x04, + /* RLE: 101 Pixels @ 261,194*/ 101, 0x00, + /* ABS: 005 Pixels @ 362,194*/ 0, 5, 0x0D, 0x06, 0x03, 0x06, 0x06, + /* RLE: 018 Pixels @ 367,194*/ 18, 0x00, + /* RLE: 004 Pixels @ 385,194*/ 4, 0x06, + /* RLE: 011 Pixels @ 389,194*/ 11, 0x01, + /* RLE: 044 Pixels @ 000,195*/ 44, 0x02, + /* RLE: 001 Pixels @ 044,195*/ 1, 0x04, + /* RLE: 006 Pixels @ 045,195*/ 6, 0x03, + /* RLE: 001 Pixels @ 051,195*/ 1, 0x04, + /* RLE: 033 Pixels @ 052,195*/ 33, 0x00, + /* RLE: 001 Pixels @ 085,195*/ 1, 0x0C, + /* RLE: 009 Pixels @ 086,195*/ 9, 0x09, + /* RLE: 065 Pixels @ 095,195*/ 65, 0x00, + /* RLE: 003 Pixels @ 160,195*/ 3, 0x04, + /* RLE: 020 Pixels @ 163,195*/ 20, 0x03, + /* RLE: 003 Pixels @ 183,195*/ 3, 0x04, + /* RLE: 029 Pixels @ 186,195*/ 29, 0x00, + /* ABS: 002 Pixels @ 215,195*/ 0, 2, 0x03, 0x0D, + /* RLE: 004 Pixels @ 217,195*/ 4, 0x08, + /* ABS: 004 Pixels @ 221,195*/ 0, 4, 0x0F, 0x06, 0x0C, 0x03, + /* RLE: 028 Pixels @ 225,195*/ 28, 0x00, + /* RLE: 001 Pixels @ 253,195*/ 1, 0x04, + /* RLE: 006 Pixels @ 254,195*/ 6, 0x03, + /* RLE: 001 Pixels @ 260,195*/ 1, 0x04, + /* RLE: 102 Pixels @ 261,195*/ 102, 0x00, + /* ABS: 005 Pixels @ 363,195*/ 0, 5, 0x0D, 0x06, 0x03, 0x06, 0x06, + /* RLE: 018 Pixels @ 368,195*/ 18, 0x00, + /* RLE: 004 Pixels @ 386,195*/ 4, 0x06, + /* RLE: 010 Pixels @ 390,195*/ 10, 0x01, + /* RLE: 044 Pixels @ 000,196*/ 44, 0x02, + /* RLE: 001 Pixels @ 044,196*/ 1, 0x04, + /* RLE: 006 Pixels @ 045,196*/ 6, 0x03, + /* RLE: 001 Pixels @ 051,196*/ 1, 0x04, + /* RLE: 033 Pixels @ 052,196*/ 33, 0x00, + /* RLE: 001 Pixels @ 085,196*/ 1, 0x0C, + /* RLE: 009 Pixels @ 086,196*/ 9, 0x09, + /* RLE: 001 Pixels @ 095,196*/ 1, 0x0C, + /* RLE: 063 Pixels @ 096,196*/ 63, 0x00, + /* ABS: 002 Pixels @ 159,196*/ 0, 2, 0x04, 0x04, + /* RLE: 018 Pixels @ 161,196*/ 18, 0x03, + /* RLE: 003 Pixels @ 179,196*/ 3, 0x04, + /* RLE: 033 Pixels @ 182,196*/ 33, 0x00, + /* ABS: 009 Pixels @ 215,196*/ 0, 9, 0x03, 0x11, 0x06, 0x0E, 0x04, 0x00, 0x03, 0x03, 0x03, + /* RLE: 028 Pixels @ 224,196*/ 28, 0x00, + /* RLE: 001 Pixels @ 252,196*/ 1, 0x04, + /* RLE: 007 Pixels @ 253,196*/ 7, 0x03, + /* RLE: 104 Pixels @ 260,196*/ 104, 0x00, + /* RLE: 003 Pixels @ 364,196*/ 3, 0x0D, + /* ABS: 002 Pixels @ 367,196*/ 0, 2, 0x06, 0x06, + /* RLE: 018 Pixels @ 369,196*/ 18, 0x00, + /* RLE: 005 Pixels @ 387,196*/ 5, 0x06, + /* RLE: 008 Pixels @ 392,196*/ 8, 0x01, + /* RLE: 044 Pixels @ 000,197*/ 44, 0x02, + /* RLE: 001 Pixels @ 044,197*/ 1, 0x04, + /* RLE: 006 Pixels @ 045,197*/ 6, 0x03, + /* RLE: 001 Pixels @ 051,197*/ 1, 0x04, + /* RLE: 034 Pixels @ 052,197*/ 34, 0x00, + /* RLE: 001 Pixels @ 086,197*/ 1, 0x0C, + /* RLE: 009 Pixels @ 087,197*/ 9, 0x09, + /* RLE: 061 Pixels @ 096,197*/ 61, 0x00, + /* ABS: 002 Pixels @ 157,197*/ 0, 2, 0x04, 0x04, + /* RLE: 016 Pixels @ 159,197*/ 16, 0x03, + /* RLE: 003 Pixels @ 175,197*/ 3, 0x04, + /* RLE: 037 Pixels @ 178,197*/ 37, 0x00, + /* RLE: 010 Pixels @ 215,197*/ 10, 0x03, + /* RLE: 001 Pixels @ 225,197*/ 1, 0x04, + /* RLE: 026 Pixels @ 226,197*/ 26, 0x00, + /* RLE: 001 Pixels @ 252,197*/ 1, 0x04, + /* RLE: 006 Pixels @ 253,197*/ 6, 0x03, + /* RLE: 001 Pixels @ 259,197*/ 1, 0x04, + /* RLE: 106 Pixels @ 260,197*/ 106, 0x00, + /* ABS: 004 Pixels @ 366,197*/ 0, 4, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 018 Pixels @ 370,197*/ 18, 0x00, + /* RLE: 005 Pixels @ 388,197*/ 5, 0x06, + /* RLE: 007 Pixels @ 393,197*/ 7, 0x01, + /* RLE: 044 Pixels @ 000,198*/ 44, 0x02, + /* RLE: 001 Pixels @ 044,198*/ 1, 0x04, + /* RLE: 007 Pixels @ 045,198*/ 7, 0x03, + /* RLE: 034 Pixels @ 052,198*/ 34, 0x00, + /* RLE: 001 Pixels @ 086,198*/ 1, 0x0C, + /* RLE: 009 Pixels @ 087,198*/ 9, 0x09, + /* RLE: 001 Pixels @ 096,198*/ 1, 0x0C, + /* RLE: 059 Pixels @ 097,198*/ 59, 0x00, + /* ABS: 002 Pixels @ 156,198*/ 0, 2, 0x04, 0x04, + /* RLE: 013 Pixels @ 158,198*/ 13, 0x03, + /* RLE: 003 Pixels @ 171,198*/ 3, 0x04, + /* RLE: 044 Pixels @ 174,198*/ 44, 0x00, + /* RLE: 001 Pixels @ 218,198*/ 1, 0x04, + /* RLE: 006 Pixels @ 219,198*/ 6, 0x03, + /* RLE: 001 Pixels @ 225,198*/ 1, 0x04, + /* RLE: 026 Pixels @ 226,198*/ 26, 0x00, + /* RLE: 001 Pixels @ 252,198*/ 1, 0x04, + /* RLE: 006 Pixels @ 253,198*/ 6, 0x03, + /* RLE: 001 Pixels @ 259,198*/ 1, 0x04, + /* RLE: 107 Pixels @ 260,198*/ 107, 0x00, + /* ABS: 004 Pixels @ 367,198*/ 0, 4, 0x0D, 0x06, 0x03, 0x06, + /* RLE: 018 Pixels @ 371,198*/ 18, 0x00, + /* ABS: 005 Pixels @ 389,198*/ 0, 5, 0x06, 0x06, 0x03, 0x06, 0x06, + /* RLE: 006 Pixels @ 394,198*/ 6, 0x01, + /* RLE: 045 Pixels @ 000,199*/ 45, 0x02, + /* RLE: 001 Pixels @ 045,199*/ 1, 0x04, + /* RLE: 006 Pixels @ 046,199*/ 6, 0x03, + /* RLE: 001 Pixels @ 052,199*/ 1, 0x04, + /* RLE: 034 Pixels @ 053,199*/ 34, 0x00, + /* RLE: 001 Pixels @ 087,199*/ 1, 0x0C, + /* RLE: 009 Pixels @ 088,199*/ 9, 0x09, + /* RLE: 057 Pixels @ 097,199*/ 57, 0x00, + /* ABS: 002 Pixels @ 154,199*/ 0, 2, 0x04, 0x04, + /* RLE: 011 Pixels @ 156,199*/ 11, 0x03, + /* RLE: 003 Pixels @ 167,199*/ 3, 0x04, + /* RLE: 048 Pixels @ 170,199*/ 48, 0x00, + /* RLE: 001 Pixels @ 218,199*/ 1, 0x04, + /* RLE: 006 Pixels @ 219,199*/ 6, 0x03, + /* RLE: 001 Pixels @ 225,199*/ 1, 0x04, + /* RLE: 026 Pixels @ 226,199*/ 26, 0x00, + /* RLE: 001 Pixels @ 252,199*/ 1, 0x04, + /* RLE: 006 Pixels @ 253,199*/ 6, 0x03, + /* RLE: 001 Pixels @ 259,199*/ 1, 0x04, + /* RLE: 108 Pixels @ 260,199*/ 108, 0x00, + /* ABS: 004 Pixels @ 368,199*/ 0, 4, 0x0D, 0x06, 0x03, 0x06, + /* RLE: 019 Pixels @ 372,199*/ 19, 0x00, + /* ABS: 004 Pixels @ 391,199*/ 0, 4, 0x06, 0x03, 0x06, 0x06, + /* RLE: 005 Pixels @ 395,199*/ 5, 0x01, + /* RLE: 045 Pixels @ 000,200*/ 45, 0x02, + /* RLE: 001 Pixels @ 045,200*/ 1, 0x04, + /* RLE: 006 Pixels @ 046,200*/ 6, 0x03, + /* RLE: 001 Pixels @ 052,200*/ 1, 0x04, + /* RLE: 034 Pixels @ 053,200*/ 34, 0x00, + /* RLE: 001 Pixels @ 087,200*/ 1, 0x0C, + /* RLE: 009 Pixels @ 088,200*/ 9, 0x09, + /* RLE: 001 Pixels @ 097,200*/ 1, 0x0C, + /* RLE: 054 Pixels @ 098,200*/ 54, 0x00, + /* RLE: 003 Pixels @ 152,200*/ 3, 0x04, + /* RLE: 011 Pixels @ 155,200*/ 11, 0x03, + /* ABS: 002 Pixels @ 166,200*/ 0, 2, 0x04, 0x04, + /* RLE: 050 Pixels @ 168,200*/ 50, 0x00, + /* RLE: 001 Pixels @ 218,200*/ 1, 0x04, + /* RLE: 007 Pixels @ 219,200*/ 7, 0x03, + /* RLE: 026 Pixels @ 226,200*/ 26, 0x00, + /* RLE: 001 Pixels @ 252,200*/ 1, 0x04, + /* RLE: 006 Pixels @ 253,200*/ 6, 0x03, + /* RLE: 001 Pixels @ 259,200*/ 1, 0x04, + /* RLE: 109 Pixels @ 260,200*/ 109, 0x00, + /* ABS: 005 Pixels @ 369,200*/ 0, 5, 0x0D, 0x0D, 0x03, 0x06, 0x06, + /* RLE: 018 Pixels @ 374,200*/ 18, 0x00, + /* ABS: 004 Pixels @ 392,200*/ 0, 4, 0x06, 0x03, 0x06, 0x06, + /* RLE: 004 Pixels @ 396,200*/ 4, 0x01, + /* RLE: 045 Pixels @ 000,201*/ 45, 0x02, + /* RLE: 001 Pixels @ 045,201*/ 1, 0x04, + /* RLE: 006 Pixels @ 046,201*/ 6, 0x03, + /* RLE: 001 Pixels @ 052,201*/ 1, 0x04, + /* RLE: 035 Pixels @ 053,201*/ 35, 0x00, + /* RLE: 001 Pixels @ 088,201*/ 1, 0x0C, + /* RLE: 008 Pixels @ 089,201*/ 8, 0x09, + /* RLE: 001 Pixels @ 097,201*/ 1, 0x0C, + /* RLE: 054 Pixels @ 098,201*/ 54, 0x00, + /* ABS: 002 Pixels @ 152,201*/ 0, 2, 0x04, 0x04, + /* RLE: 010 Pixels @ 154,201*/ 10, 0x03, + /* ABS: 002 Pixels @ 164,201*/ 0, 2, 0x04, 0x04, + /* RLE: 053 Pixels @ 166,201*/ 53, 0x00, + /* RLE: 001 Pixels @ 219,201*/ 1, 0x04, + /* RLE: 006 Pixels @ 220,201*/ 6, 0x03, + /* RLE: 001 Pixels @ 226,201*/ 1, 0x04, + /* RLE: 025 Pixels @ 227,201*/ 25, 0x00, + /* RLE: 001 Pixels @ 252,201*/ 1, 0x04, + /* RLE: 006 Pixels @ 253,201*/ 6, 0x03, + /* RLE: 001 Pixels @ 259,201*/ 1, 0x04, + /* RLE: 110 Pixels @ 260,201*/ 110, 0x00, + /* RLE: 001 Pixels @ 370,201*/ 1, 0x0D, + /* RLE: 004 Pixels @ 371,201*/ 4, 0x06, + /* RLE: 018 Pixels @ 375,201*/ 18, 0x00, + /* RLE: 004 Pixels @ 393,201*/ 4, 0x06, + /* RLE: 003 Pixels @ 397,201*/ 3, 0x01, + /* RLE: 045 Pixels @ 000,202*/ 45, 0x02, + /* RLE: 001 Pixels @ 045,202*/ 1, 0x04, + /* RLE: 006 Pixels @ 046,202*/ 6, 0x03, + /* RLE: 001 Pixels @ 052,202*/ 1, 0x04, + /* RLE: 035 Pixels @ 053,202*/ 35, 0x00, + /* RLE: 001 Pixels @ 088,202*/ 1, 0x0C, + /* RLE: 009 Pixels @ 089,202*/ 9, 0x09, + /* RLE: 001 Pixels @ 098,202*/ 1, 0x0C, + /* RLE: 053 Pixels @ 099,202*/ 53, 0x00, + /* RLE: 001 Pixels @ 152,202*/ 1, 0x04, + /* RLE: 009 Pixels @ 153,202*/ 9, 0x03, + /* RLE: 003 Pixels @ 162,202*/ 3, 0x04, + /* RLE: 054 Pixels @ 165,202*/ 54, 0x00, + /* RLE: 001 Pixels @ 219,202*/ 1, 0x04, + /* RLE: 006 Pixels @ 220,202*/ 6, 0x03, + /* RLE: 001 Pixels @ 226,202*/ 1, 0x04, + /* RLE: 024 Pixels @ 227,202*/ 24, 0x00, + /* ABS: 002 Pixels @ 251,202*/ 0, 2, 0x04, 0x04, + /* RLE: 006 Pixels @ 253,202*/ 6, 0x03, + /* RLE: 001 Pixels @ 259,202*/ 1, 0x04, + /* RLE: 111 Pixels @ 260,202*/ 111, 0x00, + /* ABS: 005 Pixels @ 371,202*/ 0, 5, 0x0D, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 018 Pixels @ 376,202*/ 18, 0x00, + /* RLE: 005 Pixels @ 394,202*/ 5, 0x06, + /* RLE: 001 Pixels @ 399,202*/ 1, 0x01, + /* RLE: 045 Pixels @ 000,203*/ 45, 0x02, + /* RLE: 001 Pixels @ 045,203*/ 1, 0x04, + /* RLE: 006 Pixels @ 046,203*/ 6, 0x03, + /* RLE: 001 Pixels @ 052,203*/ 1, 0x04, + /* RLE: 036 Pixels @ 053,203*/ 36, 0x00, + /* RLE: 001 Pixels @ 089,203*/ 1, 0x0C, + /* RLE: 008 Pixels @ 090,203*/ 8, 0x09, + /* RLE: 001 Pixels @ 098,203*/ 1, 0x0C, + /* RLE: 051 Pixels @ 099,203*/ 51, 0x00, + /* RLE: 011 Pixels @ 150,203*/ 11, 0x03, + /* ABS: 002 Pixels @ 161,203*/ 0, 2, 0x04, 0x04, + /* RLE: 056 Pixels @ 163,203*/ 56, 0x00, + /* RLE: 001 Pixels @ 219,203*/ 1, 0x04, + /* RLE: 006 Pixels @ 220,203*/ 6, 0x03, + /* RLE: 001 Pixels @ 226,203*/ 1, 0x04, + /* RLE: 024 Pixels @ 227,203*/ 24, 0x00, + /* RLE: 001 Pixels @ 251,203*/ 1, 0x04, + /* RLE: 007 Pixels @ 252,203*/ 7, 0x03, + /* RLE: 114 Pixels @ 259,203*/ 114, 0x00, + /* ABS: 004 Pixels @ 373,203*/ 0, 4, 0x0D, 0x0D, 0x06, 0x06, + /* RLE: 018 Pixels @ 377,203*/ 18, 0x00, + /* ABS: 005 Pixels @ 395,203*/ 0, 5, 0x06, 0x06, 0x03, 0x06, 0x06, + /* RLE: 045 Pixels @ 000,204*/ 45, 0x02, + /* RLE: 001 Pixels @ 045,204*/ 1, 0x04, + /* RLE: 007 Pixels @ 046,204*/ 7, 0x03, + /* RLE: 036 Pixels @ 053,204*/ 36, 0x00, + /* RLE: 001 Pixels @ 089,204*/ 1, 0x0C, + /* RLE: 009 Pixels @ 090,204*/ 9, 0x09, + /* RLE: 050 Pixels @ 099,204*/ 50, 0x00, + /* ABS: 006 Pixels @ 149,204*/ 0, 6, 0x03, 0x00, 0x0C, 0x0C, 0x04, 0x00, + /* RLE: 004 Pixels @ 155,204*/ 4, 0x03, + /* RLE: 003 Pixels @ 159,204*/ 3, 0x04, + /* RLE: 058 Pixels @ 162,204*/ 58, 0x00, + /* RLE: 007 Pixels @ 220,204*/ 7, 0x03, + /* RLE: 001 Pixels @ 227,204*/ 1, 0x04, + /* RLE: 022 Pixels @ 228,204*/ 22, 0x00, + /* ABS: 002 Pixels @ 250,204*/ 0, 2, 0x04, 0x04, + /* RLE: 006 Pixels @ 252,204*/ 6, 0x03, + /* RLE: 001 Pixels @ 258,204*/ 1, 0x04, + /* RLE: 115 Pixels @ 259,204*/ 115, 0x00, + /* ABS: 004 Pixels @ 374,204*/ 0, 4, 0x0D, 0x03, 0x03, 0x06, + /* RLE: 018 Pixels @ 378,204*/ 18, 0x00, + /* ABS: 004 Pixels @ 396,204*/ 0, 4, 0x06, 0x06, 0x03, 0x06, + /* RLE: 046 Pixels @ 000,205*/ 46, 0x02, + /* RLE: 001 Pixels @ 046,205*/ 1, 0x04, + /* RLE: 006 Pixels @ 047,205*/ 6, 0x03, + /* RLE: 001 Pixels @ 053,205*/ 1, 0x04, + /* RLE: 036 Pixels @ 054,205*/ 36, 0x00, + /* RLE: 001 Pixels @ 090,205*/ 1, 0x0C, + /* RLE: 008 Pixels @ 091,205*/ 8, 0x09, + /* RLE: 001 Pixels @ 099,205*/ 1, 0x0C, + /* RLE: 048 Pixels @ 100,205*/ 48, 0x00, + /* ABS: 003 Pixels @ 148,205*/ 0, 3, 0x03, 0x00, 0x0F, + /* RLE: 004 Pixels @ 151,205*/ 4, 0x08, + /* ABS: 005 Pixels @ 155,205*/ 0, 5, 0x06, 0x03, 0x03, 0x04, 0x04, + /* RLE: 060 Pixels @ 160,205*/ 60, 0x00, + /* RLE: 001 Pixels @ 220,205*/ 1, 0x04, + /* RLE: 006 Pixels @ 221,205*/ 6, 0x03, + /* RLE: 001 Pixels @ 227,205*/ 1, 0x04, + /* RLE: 022 Pixels @ 228,205*/ 22, 0x00, + /* RLE: 001 Pixels @ 250,205*/ 1, 0x04, + /* RLE: 007 Pixels @ 251,205*/ 7, 0x03, + /* RLE: 001 Pixels @ 258,205*/ 1, 0x04, + /* RLE: 116 Pixels @ 259,205*/ 116, 0x00, + /* ABS: 004 Pixels @ 375,205*/ 0, 4, 0x0D, 0x06, 0x03, 0x06, + /* RLE: 019 Pixels @ 379,205*/ 19, 0x00, + /* ABS: 002 Pixels @ 398,205*/ 0, 2, 0x06, 0x03, + /* RLE: 046 Pixels @ 000,206*/ 46, 0x02, + /* RLE: 001 Pixels @ 046,206*/ 1, 0x04, + /* RLE: 006 Pixels @ 047,206*/ 6, 0x03, + /* RLE: 001 Pixels @ 053,206*/ 1, 0x04, + /* RLE: 036 Pixels @ 054,206*/ 36, 0x00, + /* RLE: 001 Pixels @ 090,206*/ 1, 0x0C, + /* RLE: 008 Pixels @ 091,206*/ 8, 0x09, + /* RLE: 001 Pixels @ 099,206*/ 1, 0x0C, + /* RLE: 050 Pixels @ 100,206*/ 50, 0x00, + /* ABS: 008 Pixels @ 150,206*/ 0, 8, 0x11, 0x03, 0x03, 0x00, 0x04, 0x04, 0x03, 0x03, + /* RLE: 062 Pixels @ 158,206*/ 62, 0x00, + /* RLE: 001 Pixels @ 220,206*/ 1, 0x04, + /* RLE: 006 Pixels @ 221,206*/ 6, 0x03, + /* ABS: 002 Pixels @ 227,206*/ 0, 2, 0x04, 0x04, + /* RLE: 020 Pixels @ 229,206*/ 20, 0x00, + /* RLE: 001 Pixels @ 249,206*/ 1, 0x04, + /* RLE: 007 Pixels @ 250,206*/ 7, 0x03, + /* RLE: 001 Pixels @ 257,206*/ 1, 0x04, + /* RLE: 118 Pixels @ 258,206*/ 118, 0x00, + /* RLE: 001 Pixels @ 376,206*/ 1, 0x0D, + /* RLE: 004 Pixels @ 377,206*/ 4, 0x06, + /* RLE: 018 Pixels @ 381,206*/ 18, 0x00, + /* RLE: 001 Pixels @ 399,206*/ 1, 0x06, + /* RLE: 046 Pixels @ 000,207*/ 46, 0x02, + /* RLE: 001 Pixels @ 046,207*/ 1, 0x04, + /* RLE: 006 Pixels @ 047,207*/ 6, 0x03, + /* RLE: 001 Pixels @ 053,207*/ 1, 0x04, + /* RLE: 037 Pixels @ 054,207*/ 37, 0x00, + /* RLE: 009 Pixels @ 091,207*/ 9, 0x09, + /* RLE: 001 Pixels @ 100,207*/ 1, 0x0C, + /* RLE: 048 Pixels @ 101,207*/ 48, 0x00, + /* ABS: 002 Pixels @ 149,207*/ 0, 2, 0x03, 0x11, + /* RLE: 006 Pixels @ 151,207*/ 6, 0x03, + /* RLE: 001 Pixels @ 157,207*/ 1, 0x04, + /* RLE: 062 Pixels @ 158,207*/ 62, 0x00, + /* RLE: 001 Pixels @ 220,207*/ 1, 0x04, + /* RLE: 007 Pixels @ 221,207*/ 7, 0x03, + /* RLE: 001 Pixels @ 228,207*/ 1, 0x04, + /* RLE: 019 Pixels @ 229,207*/ 19, 0x00, + /* ABS: 002 Pixels @ 248,207*/ 0, 2, 0x04, 0x04, + /* RLE: 007 Pixels @ 250,207*/ 7, 0x03, + /* RLE: 001 Pixels @ 257,207*/ 1, 0x04, + /* RLE: 119 Pixels @ 258,207*/ 119, 0x00, + /* RLE: 001 Pixels @ 377,207*/ 1, 0x0D, + /* RLE: 004 Pixels @ 378,207*/ 4, 0x06, + /* RLE: 018 Pixels @ 382,207*/ 18, 0x00, + /* RLE: 046 Pixels @ 000,208*/ 46, 0x02, + /* RLE: 001 Pixels @ 046,208*/ 1, 0x04, + /* RLE: 006 Pixels @ 047,208*/ 6, 0x03, + /* RLE: 001 Pixels @ 053,208*/ 1, 0x04, + /* RLE: 037 Pixels @ 054,208*/ 37, 0x00, + /* RLE: 001 Pixels @ 091,208*/ 1, 0x0C, + /* RLE: 008 Pixels @ 092,208*/ 8, 0x09, + /* RLE: 001 Pixels @ 100,208*/ 1, 0x0C, + /* RLE: 047 Pixels @ 101,208*/ 47, 0x00, + /* ABS: 010 Pixels @ 148,208*/ 0, 10, 0x03, 0x0C, 0x08, 0x0F, 0x06, 0x0C, 0x0C, 0x03, 0x03, 0x04, + /* RLE: 063 Pixels @ 158,208*/ 63, 0x00, + /* RLE: 001 Pixels @ 221,208*/ 1, 0x04, + /* RLE: 006 Pixels @ 222,208*/ 6, 0x03, + /* ABS: 002 Pixels @ 228,208*/ 0, 2, 0x04, 0x04, + /* RLE: 018 Pixels @ 230,208*/ 18, 0x00, + /* RLE: 001 Pixels @ 248,208*/ 1, 0x04, + /* RLE: 007 Pixels @ 249,208*/ 7, 0x03, + /* RLE: 001 Pixels @ 256,208*/ 1, 0x04, + /* RLE: 121 Pixels @ 257,208*/ 121, 0x00, + /* RLE: 003 Pixels @ 378,208*/ 3, 0x0D, + /* ABS: 002 Pixels @ 381,208*/ 0, 2, 0x06, 0x06, + /* RLE: 017 Pixels @ 383,208*/ 17, 0x00, + /* RLE: 046 Pixels @ 000,209*/ 46, 0x02, + /* RLE: 001 Pixels @ 046,209*/ 1, 0x04, + /* RLE: 006 Pixels @ 047,209*/ 6, 0x03, + /* RLE: 001 Pixels @ 053,209*/ 1, 0x04, + /* RLE: 037 Pixels @ 054,209*/ 37, 0x00, + /* RLE: 001 Pixels @ 091,209*/ 1, 0x0C, + /* RLE: 009 Pixels @ 092,209*/ 9, 0x09, + /* RLE: 049 Pixels @ 101,209*/ 49, 0x00, + /* ABS: 005 Pixels @ 150,209*/ 0, 5, 0x0C, 0x06, 0x0D, 0x08, 0x08, + /* RLE: 066 Pixels @ 155,209*/ 66, 0x00, + /* RLE: 001 Pixels @ 221,209*/ 1, 0x04, + /* RLE: 007 Pixels @ 222,209*/ 7, 0x03, + /* RLE: 001 Pixels @ 229,209*/ 1, 0x04, + /* RLE: 017 Pixels @ 230,209*/ 17, 0x00, + /* ABS: 002 Pixels @ 247,209*/ 0, 2, 0x04, 0x04, + /* RLE: 006 Pixels @ 249,209*/ 6, 0x03, + /* ABS: 002 Pixels @ 255,209*/ 0, 2, 0x04, 0x04, + /* RLE: 123 Pixels @ 257,209*/ 123, 0x00, + /* ABS: 004 Pixels @ 380,209*/ 0, 4, 0x0D, 0x03, 0x0D, 0x06, + /* RLE: 016 Pixels @ 384,209*/ 16, 0x00, + /* RLE: 046 Pixels @ 000,210*/ 46, 0x02, + /* RLE: 001 Pixels @ 046,210*/ 1, 0x04, + /* RLE: 006 Pixels @ 047,210*/ 6, 0x03, + /* RLE: 001 Pixels @ 053,210*/ 1, 0x04, + /* RLE: 038 Pixels @ 054,210*/ 38, 0x00, + /* RLE: 001 Pixels @ 092,210*/ 1, 0x0C, + /* RLE: 008 Pixels @ 093,210*/ 8, 0x09, + /* RLE: 001 Pixels @ 101,210*/ 1, 0x0C, + /* RLE: 046 Pixels @ 102,210*/ 46, 0x00, + /* RLE: 006 Pixels @ 148,210*/ 6, 0x03, + /* ABS: 002 Pixels @ 154,210*/ 0, 2, 0x00, 0x03, + /* RLE: 065 Pixels @ 156,210*/ 65, 0x00, + /* ABS: 002 Pixels @ 221,210*/ 0, 2, 0x04, 0x04, + /* RLE: 007 Pixels @ 223,210*/ 7, 0x03, + /* RLE: 001 Pixels @ 230,210*/ 1, 0x04, + /* RLE: 016 Pixels @ 231,210*/ 16, 0x00, + /* RLE: 001 Pixels @ 247,210*/ 1, 0x04, + /* RLE: 007 Pixels @ 248,210*/ 7, 0x03, + /* RLE: 001 Pixels @ 255,210*/ 1, 0x04, + /* RLE: 125 Pixels @ 256,210*/ 125, 0x00, + /* ABS: 004 Pixels @ 381,210*/ 0, 4, 0x0D, 0x03, 0x03, 0x06, + /* RLE: 015 Pixels @ 385,210*/ 15, 0x00, + /* RLE: 047 Pixels @ 000,211*/ 47, 0x02, + /* RLE: 007 Pixels @ 047,211*/ 7, 0x03, + /* RLE: 038 Pixels @ 054,211*/ 38, 0x00, + /* RLE: 001 Pixels @ 092,211*/ 1, 0x0C, + /* RLE: 008 Pixels @ 093,211*/ 8, 0x09, + /* RLE: 001 Pixels @ 101,211*/ 1, 0x0C, + /* RLE: 046 Pixels @ 102,211*/ 46, 0x00, + /* ABS: 008 Pixels @ 148,211*/ 0, 8, 0x03, 0x0C, 0x08, 0x08, 0x0B, 0x0E, 0x03, 0x03, + /* RLE: 066 Pixels @ 156,211*/ 66, 0x00, + /* RLE: 001 Pixels @ 222,211*/ 1, 0x04, + /* RLE: 007 Pixels @ 223,211*/ 7, 0x03, + /* ABS: 002 Pixels @ 230,211*/ 0, 2, 0x04, 0x04, + /* RLE: 014 Pixels @ 232,211*/ 14, 0x00, + /* RLE: 001 Pixels @ 246,211*/ 1, 0x04, + /* RLE: 007 Pixels @ 247,211*/ 7, 0x03, + /* ABS: 002 Pixels @ 254,211*/ 0, 2, 0x04, 0x04, + /* RLE: 126 Pixels @ 256,211*/ 126, 0x00, + /* ABS: 004 Pixels @ 382,211*/ 0, 4, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 014 Pixels @ 386,211*/ 14, 0x00, + /* RLE: 046 Pixels @ 000,212*/ 46, 0x02, + /* RLE: 001 Pixels @ 046,212*/ 1, 0x00, + /* RLE: 006 Pixels @ 047,212*/ 6, 0x03, + /* ABS: 003 Pixels @ 053,212*/ 0, 3, 0x00, 0x04, 0x03, + /* RLE: 037 Pixels @ 056,212*/ 37, 0x00, + /* RLE: 009 Pixels @ 093,212*/ 9, 0x09, + /* RLE: 001 Pixels @ 102,212*/ 1, 0x0C, + /* RLE: 044 Pixels @ 103,212*/ 44, 0x00, + /* ABS: 008 Pixels @ 147,212*/ 0, 8, 0x03, 0x00, 0x08, 0x04, 0x0D, 0x04, 0x0F, 0x04, + /* RLE: 068 Pixels @ 155,212*/ 68, 0x00, + /* RLE: 001 Pixels @ 223,212*/ 1, 0x04, + /* RLE: 007 Pixels @ 224,212*/ 7, 0x03, + /* RLE: 001 Pixels @ 231,212*/ 1, 0x04, + /* RLE: 013 Pixels @ 232,212*/ 13, 0x00, + /* ABS: 002 Pixels @ 245,212*/ 0, 2, 0x04, 0x04, + /* RLE: 007 Pixels @ 247,212*/ 7, 0x03, + /* RLE: 001 Pixels @ 254,212*/ 1, 0x04, + /* RLE: 128 Pixels @ 255,212*/ 128, 0x00, + /* ABS: 004 Pixels @ 383,212*/ 0, 4, 0x0D, 0x06, 0x06, 0x06, + /* RLE: 013 Pixels @ 387,212*/ 13, 0x00, + /* RLE: 046 Pixels @ 000,213*/ 46, 0x02, + /* ABS: 009 Pixels @ 046,213*/ 0, 9, 0x03, 0x0B, 0x0C, 0x0E, 0x06, 0x11, 0x08, 0x08, 0x08, + /* RLE: 038 Pixels @ 055,213*/ 38, 0x00, + /* RLE: 001 Pixels @ 093,213*/ 1, 0x0C, + /* RLE: 008 Pixels @ 094,213*/ 8, 0x09, + /* RLE: 001 Pixels @ 102,213*/ 1, 0x0C, + /* RLE: 045 Pixels @ 103,213*/ 45, 0x00, + /* ABS: 008 Pixels @ 148,213*/ 0, 8, 0x0C, 0x06, 0x03, 0x0F, 0x03, 0x0E, 0x0C, 0x03, + /* RLE: 067 Pixels @ 156,213*/ 67, 0x00, + /* ABS: 002 Pixels @ 223,213*/ 0, 2, 0x04, 0x04, + /* RLE: 006 Pixels @ 225,213*/ 6, 0x03, + /* ABS: 002 Pixels @ 231,213*/ 0, 2, 0x04, 0x04, + /* RLE: 011 Pixels @ 233,213*/ 11, 0x00, + /* ABS: 002 Pixels @ 244,213*/ 0, 2, 0x04, 0x04, + /* RLE: 007 Pixels @ 246,213*/ 7, 0x03, + /* RLE: 001 Pixels @ 253,213*/ 1, 0x04, + /* RLE: 130 Pixels @ 254,213*/ 130, 0x00, + /* RLE: 001 Pixels @ 384,213*/ 1, 0x0D, + /* RLE: 004 Pixels @ 385,213*/ 4, 0x06, + /* RLE: 011 Pixels @ 389,213*/ 11, 0x00, + /* RLE: 046 Pixels @ 000,214*/ 46, 0x02, + /* ABS: 002 Pixels @ 046,214*/ 0, 2, 0x03, 0x06, + /* RLE: 004 Pixels @ 048,214*/ 4, 0x08, + /* ABS: 005 Pixels @ 052,214*/ 0, 5, 0x0E, 0x0C, 0x08, 0x04, 0x03, + /* RLE: 036 Pixels @ 057,214*/ 36, 0x00, + /* RLE: 001 Pixels @ 093,214*/ 1, 0x0C, + /* RLE: 009 Pixels @ 094,214*/ 9, 0x09, + /* RLE: 044 Pixels @ 103,214*/ 44, 0x00, + /* ABS: 009 Pixels @ 147,214*/ 0, 9, 0x03, 0x00, 0x08, 0x0E, 0x0F, 0x0B, 0x11, 0x0C, 0x03, + /* RLE: 068 Pixels @ 156,214*/ 68, 0x00, + /* RLE: 001 Pixels @ 224,214*/ 1, 0x04, + /* RLE: 007 Pixels @ 225,214*/ 7, 0x03, + /* RLE: 001 Pixels @ 232,214*/ 1, 0x04, + /* RLE: 010 Pixels @ 233,214*/ 10, 0x00, + /* ABS: 002 Pixels @ 243,214*/ 0, 2, 0x04, 0x04, + /* RLE: 007 Pixels @ 245,214*/ 7, 0x03, + /* ABS: 002 Pixels @ 252,214*/ 0, 2, 0x04, 0x04, + /* RLE: 131 Pixels @ 254,214*/ 131, 0x00, + /* ABS: 005 Pixels @ 385,214*/ 0, 5, 0x0D, 0x06, 0x03, 0x06, 0x06, + /* RLE: 010 Pixels @ 390,214*/ 10, 0x00, + /* RLE: 046 Pixels @ 000,215*/ 46, 0x02, + /* ABS: 011 Pixels @ 046,215*/ 0, 11, 0x03, 0x00, 0x0B, 0x03, 0x00, 0x08, 0x00, 0x03, 0x11, 0x0C, 0x03, + /* RLE: 037 Pixels @ 057,215*/ 37, 0x00, + /* RLE: 001 Pixels @ 094,215*/ 1, 0x0C, + /* RLE: 008 Pixels @ 095,215*/ 8, 0x09, + /* RLE: 001 Pixels @ 103,215*/ 1, 0x0C, + /* RLE: 044 Pixels @ 104,215*/ 44, 0x00, + /* ABS: 007 Pixels @ 148,215*/ 0, 7, 0x03, 0x0E, 0x08, 0x08, 0x08, 0x0D, 0x03, + /* RLE: 069 Pixels @ 155,215*/ 69, 0x00, + /* ABS: 002 Pixels @ 224,215*/ 0, 2, 0x04, 0x04, + /* RLE: 007 Pixels @ 226,215*/ 7, 0x03, + /* RLE: 001 Pixels @ 233,215*/ 1, 0x04, + /* RLE: 008 Pixels @ 234,215*/ 8, 0x00, + /* ABS: 002 Pixels @ 242,215*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 244,215*/ 8, 0x03, + /* RLE: 001 Pixels @ 252,215*/ 1, 0x04, + /* RLE: 133 Pixels @ 253,215*/ 133, 0x00, + /* RLE: 001 Pixels @ 386,215*/ 1, 0x0D, + /* RLE: 004 Pixels @ 387,215*/ 4, 0x06, + /* RLE: 009 Pixels @ 391,215*/ 9, 0x00, + /* RLE: 046 Pixels @ 000,216*/ 46, 0x02, + /* ABS: 011 Pixels @ 046,216*/ 0, 11, 0x00, 0x00, 0x03, 0x03, 0x03, 0x08, 0x04, 0x03, 0x06, 0x0E, 0x03, + /* RLE: 037 Pixels @ 057,216*/ 37, 0x00, + /* RLE: 001 Pixels @ 094,216*/ 1, 0x0C, + /* RLE: 008 Pixels @ 095,216*/ 8, 0x09, + /* RLE: 001 Pixels @ 103,216*/ 1, 0x0C, + /* RLE: 044 Pixels @ 104,216*/ 44, 0x00, + /* RLE: 003 Pixels @ 148,216*/ 3, 0x03, + /* ABS: 005 Pixels @ 151,216*/ 0, 5, 0x00, 0x0B, 0x03, 0x03, 0x04, + /* RLE: 069 Pixels @ 156,216*/ 69, 0x00, + /* RLE: 001 Pixels @ 225,216*/ 1, 0x04, + /* RLE: 007 Pixels @ 226,216*/ 7, 0x03, + /* ABS: 002 Pixels @ 233,216*/ 0, 2, 0x04, 0x04, + /* RLE: 006 Pixels @ 235,216*/ 6, 0x00, + /* ABS: 002 Pixels @ 241,216*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 243,216*/ 8, 0x03, + /* ABS: 002 Pixels @ 251,216*/ 0, 2, 0x04, 0x04, + /* RLE: 135 Pixels @ 253,216*/ 135, 0x00, + /* ABS: 004 Pixels @ 388,216*/ 0, 4, 0x0D, 0x0D, 0x06, 0x06, + /* RLE: 008 Pixels @ 392,216*/ 8, 0x00, + /* RLE: 048 Pixels @ 000,217*/ 48, 0x02, + /* RLE: 003 Pixels @ 048,217*/ 3, 0x03, + /* ABS: 006 Pixels @ 051,217*/ 0, 6, 0x0D, 0x0C, 0x03, 0x0C, 0x06, 0x03, + /* RLE: 038 Pixels @ 057,217*/ 38, 0x00, + /* RLE: 009 Pixels @ 095,217*/ 9, 0x09, + /* RLE: 001 Pixels @ 104,217*/ 1, 0x0C, + /* RLE: 042 Pixels @ 105,217*/ 42, 0x00, + /* ABS: 009 Pixels @ 147,217*/ 0, 9, 0x03, 0x0E, 0x0C, 0x00, 0x06, 0x12, 0x03, 0x03, 0x04, + /* RLE: 070 Pixels @ 156,217*/ 70, 0x00, + /* RLE: 001 Pixels @ 226,217*/ 1, 0x04, + /* RLE: 007 Pixels @ 227,217*/ 7, 0x03, + /* RLE: 001 Pixels @ 234,217*/ 1, 0x04, + /* RLE: 005 Pixels @ 235,217*/ 5, 0x00, + /* ABS: 002 Pixels @ 240,217*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 242,217*/ 8, 0x03, + /* ABS: 002 Pixels @ 250,217*/ 0, 2, 0x04, 0x04, + /* RLE: 137 Pixels @ 252,217*/ 137, 0x00, + /* ABS: 004 Pixels @ 389,217*/ 0, 4, 0x0D, 0x03, 0x03, 0x06, + /* RLE: 007 Pixels @ 393,217*/ 7, 0x00, + /* RLE: 048 Pixels @ 000,218*/ 48, 0x02, + /* RLE: 001 Pixels @ 048,218*/ 1, 0x04, + /* RLE: 008 Pixels @ 049,218*/ 8, 0x03, + /* RLE: 038 Pixels @ 057,218*/ 38, 0x00, + /* RLE: 001 Pixels @ 095,218*/ 1, 0x0C, + /* RLE: 008 Pixels @ 096,218*/ 8, 0x09, + /* RLE: 001 Pixels @ 104,218*/ 1, 0x0C, + /* RLE: 041 Pixels @ 105,218*/ 41, 0x00, + /* ABS: 009 Pixels @ 146,218*/ 0, 9, 0x03, 0x00, 0x0F, 0x00, 0x11, 0x11, 0x0F, 0x0C, 0x03, + /* RLE: 071 Pixels @ 155,218*/ 71, 0x00, + /* ABS: 002 Pixels @ 226,218*/ 0, 2, 0x04, 0x04, + /* RLE: 006 Pixels @ 228,218*/ 6, 0x03, + /* ABS: 007 Pixels @ 234,218*/ 0, 7, 0x04, 0x04, 0x00, 0x00, 0x00, 0x04, 0x04, + /* RLE: 008 Pixels @ 241,218*/ 8, 0x03, + /* ABS: 002 Pixels @ 249,218*/ 0, 2, 0x04, 0x04, + /* RLE: 139 Pixels @ 251,218*/ 139, 0x00, + /* ABS: 004 Pixels @ 390,218*/ 0, 4, 0x0D, 0x06, 0x03, 0x06, + /* RLE: 006 Pixels @ 394,218*/ 6, 0x00, + /* RLE: 048 Pixels @ 000,219*/ 48, 0x02, + /* RLE: 001 Pixels @ 048,219*/ 1, 0x00, + /* RLE: 006 Pixels @ 049,219*/ 6, 0x03, + /* RLE: 001 Pixels @ 055,219*/ 1, 0x04, + /* RLE: 039 Pixels @ 056,219*/ 39, 0x00, + /* RLE: 001 Pixels @ 095,219*/ 1, 0x0C, + /* RLE: 009 Pixels @ 096,219*/ 9, 0x09, + /* RLE: 041 Pixels @ 105,219*/ 41, 0x00, + /* ABS: 009 Pixels @ 146,219*/ 0, 9, 0x03, 0x0C, 0x06, 0x0B, 0x08, 0x04, 0x0C, 0x0C, 0x03, + /* RLE: 072 Pixels @ 155,219*/ 72, 0x00, + /* RLE: 001 Pixels @ 227,219*/ 1, 0x04, + /* RLE: 007 Pixels @ 228,219*/ 7, 0x03, + /* ABS: 005 Pixels @ 235,219*/ 0, 5, 0x04, 0x00, 0x00, 0x04, 0x04, + /* RLE: 008 Pixels @ 240,219*/ 8, 0x03, + /* ABS: 002 Pixels @ 248,219*/ 0, 2, 0x04, 0x04, + /* RLE: 141 Pixels @ 250,219*/ 141, 0x00, + /* RLE: 001 Pixels @ 391,219*/ 1, 0x0D, + /* RLE: 004 Pixels @ 392,219*/ 4, 0x06, + /* RLE: 004 Pixels @ 396,219*/ 4, 0x00, + /* RLE: 047 Pixels @ 000,220*/ 47, 0x02, + /* ABS: 008 Pixels @ 047,220*/ 0, 8, 0x00, 0x03, 0x0C, 0x0F, 0x08, 0x11, 0x0B, 0x03, + /* RLE: 041 Pixels @ 055,220*/ 41, 0x00, + /* RLE: 001 Pixels @ 096,220*/ 1, 0x0C, + /* RLE: 008 Pixels @ 097,220*/ 8, 0x09, + /* RLE: 001 Pixels @ 105,220*/ 1, 0x0C, + /* RLE: 040 Pixels @ 106,220*/ 40, 0x00, + /* ABS: 009 Pixels @ 146,220*/ 0, 9, 0x03, 0x0C, 0x11, 0x0D, 0x11, 0x03, 0x06, 0x04, 0x03, + /* RLE: 072 Pixels @ 155,220*/ 72, 0x00, + /* ABS: 002 Pixels @ 227,220*/ 0, 2, 0x04, 0x04, + /* RLE: 007 Pixels @ 229,220*/ 7, 0x03, + /* RLE: 003 Pixels @ 236,220*/ 3, 0x04, + /* RLE: 008 Pixels @ 239,220*/ 8, 0x03, + /* ABS: 002 Pixels @ 247,220*/ 0, 2, 0x04, 0x04, + /* RLE: 143 Pixels @ 249,220*/ 143, 0x00, + /* RLE: 001 Pixels @ 392,220*/ 1, 0x0D, + /* RLE: 004 Pixels @ 393,220*/ 4, 0x06, + /* RLE: 003 Pixels @ 397,220*/ 3, 0x00, + /* RLE: 047 Pixels @ 000,221*/ 47, 0x02, + /* ABS: 007 Pixels @ 047,221*/ 0, 7, 0x03, 0x04, 0x08, 0x06, 0x0C, 0x06, 0x0F, + /* RLE: 042 Pixels @ 054,221*/ 42, 0x00, + /* RLE: 001 Pixels @ 096,221*/ 1, 0x0C, + /* RLE: 008 Pixels @ 097,221*/ 8, 0x09, + /* RLE: 001 Pixels @ 105,221*/ 1, 0x0C, + /* RLE: 038 Pixels @ 106,221*/ 38, 0x00, + /* ABS: 009 Pixels @ 144,221*/ 0, 9, 0x03, 0x00, 0x03, 0x03, 0x06, 0x0F, 0x04, 0x0C, 0x0F, + /* RLE: 075 Pixels @ 153,221*/ 75, 0x00, + /* RLE: 001 Pixels @ 228,221*/ 1, 0x04, + /* RLE: 007 Pixels @ 229,221*/ 7, 0x03, + /* ABS: 002 Pixels @ 236,221*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 238,221*/ 8, 0x03, + /* ABS: 002 Pixels @ 246,221*/ 0, 2, 0x04, 0x04, + /* RLE: 145 Pixels @ 248,221*/ 145, 0x00, + /* RLE: 003 Pixels @ 393,221*/ 3, 0x0D, + /* ABS: 004 Pixels @ 396,221*/ 0, 4, 0x06, 0x06, 0x00, 0x00, + /* RLE: 047 Pixels @ 000,222*/ 47, 0x02, + /* ABS: 009 Pixels @ 047,222*/ 0, 9, 0x03, 0x0C, 0x0D, 0x03, 0x03, 0x03, 0x11, 0x04, 0x03, + /* RLE: 041 Pixels @ 056,222*/ 41, 0x00, + /* RLE: 009 Pixels @ 097,222*/ 9, 0x09, + /* RLE: 001 Pixels @ 106,222*/ 1, 0x0C, + /* RLE: 036 Pixels @ 107,222*/ 36, 0x00, + /* ABS: 004 Pixels @ 143,222*/ 0, 4, 0x03, 0x00, 0x00, 0x00, + /* RLE: 004 Pixels @ 147,222*/ 4, 0x03, + /* ABS: 003 Pixels @ 151,222*/ 0, 3, 0x00, 0x00, 0x03, + /* RLE: 075 Pixels @ 154,222*/ 75, 0x00, + /* RLE: 001 Pixels @ 229,222*/ 1, 0x04, + /* RLE: 015 Pixels @ 230,222*/ 15, 0x03, + /* ABS: 002 Pixels @ 245,222*/ 0, 2, 0x04, 0x04, + /* RLE: 148 Pixels @ 247,222*/ 148, 0x00, + /* ABS: 005 Pixels @ 395,222*/ 0, 5, 0x0D, 0x03, 0x0D, 0x06, 0x00, + /* RLE: 047 Pixels @ 000,223*/ 47, 0x02, + /* ABS: 010 Pixels @ 047,223*/ 0, 10, 0x03, 0x0C, 0x0D, 0x03, 0x03, 0x03, 0x0F, 0x04, 0x03, 0x04, + /* RLE: 040 Pixels @ 057,223*/ 40, 0x00, + /* RLE: 001 Pixels @ 097,223*/ 1, 0x0C, + /* RLE: 008 Pixels @ 098,223*/ 8, 0x09, + /* RLE: 001 Pixels @ 106,223*/ 1, 0x0C, + /* RLE: 036 Pixels @ 107,223*/ 36, 0x00, + /* ABS: 012 Pixels @ 143,223*/ 0, 12, 0x03, 0x06, 0x08, 0x08, 0x08, 0x0D, 0x06, 0x0C, 0x0C, 0x03, 0x03, 0x04, + /* RLE: 074 Pixels @ 155,223*/ 74, 0x00, + /* ABS: 002 Pixels @ 229,223*/ 0, 2, 0x04, 0x04, + /* RLE: 013 Pixels @ 231,223*/ 13, 0x03, + /* ABS: 002 Pixels @ 244,223*/ 0, 2, 0x04, 0x04, + /* RLE: 150 Pixels @ 246,223*/ 150, 0x00, + /* ABS: 004 Pixels @ 396,223*/ 0, 4, 0x0D, 0x03, 0x03, 0x06, + /* RLE: 047 Pixels @ 000,224*/ 47, 0x02, + /* ABS: 009 Pixels @ 047,224*/ 0, 9, 0x03, 0x00, 0x08, 0x0D, 0x06, 0x0F, 0x0F, 0x03, 0x03, + /* RLE: 041 Pixels @ 056,224*/ 41, 0x00, + /* RLE: 001 Pixels @ 097,224*/ 1, 0x0C, + /* RLE: 004 Pixels @ 098,224*/ 4, 0x09, + /* ABS: 002 Pixels @ 102,224*/ 0, 2, 0x1B, 0x18, + /* RLE: 004 Pixels @ 104,224*/ 4, 0x03, + /* RLE: 035 Pixels @ 108,224*/ 35, 0x00, + /* ABS: 012 Pixels @ 143,224*/ 0, 12, 0x03, 0x00, 0x0B, 0x0C, 0x0C, 0x06, 0x0D, 0x08, 0x08, 0x00, 0x03, 0x04, + /* RLE: 075 Pixels @ 155,224*/ 75, 0x00, + /* RLE: 001 Pixels @ 230,224*/ 1, 0x04, + /* RLE: 012 Pixels @ 231,224*/ 12, 0x03, + /* ABS: 002 Pixels @ 243,224*/ 0, 2, 0x04, 0x04, + /* RLE: 152 Pixels @ 245,224*/ 152, 0x00, + /* ABS: 003 Pixels @ 397,224*/ 0, 3, 0x0D, 0x06, 0x06, + /* RLE: 047 Pixels @ 000,225*/ 47, 0x02, + /* ABS: 010 Pixels @ 047,225*/ 0, 10, 0x18, 0x03, 0x0B, 0x0D, 0x0F, 0x12, 0x00, 0x03, 0x00, 0x03, + /* RLE: 041 Pixels @ 057,225*/ 41, 0x00, + /* ABS: 009 Pixels @ 098,225*/ 0, 9, 0x0B, 0x18, 0x03, 0x03, 0x03, 0x00, 0x04, 0x0E, 0x0D, + /* RLE: 036 Pixels @ 107,225*/ 36, 0x00, + /* RLE: 008 Pixels @ 143,225*/ 8, 0x03, + /* ABS: 003 Pixels @ 151,225*/ 0, 3, 0x00, 0x03, 0x03, + /* RLE: 076 Pixels @ 154,225*/ 76, 0x00, + /* ABS: 002 Pixels @ 230,225*/ 0, 2, 0x04, 0x04, + /* RLE: 010 Pixels @ 232,225*/ 10, 0x03, + /* ABS: 002 Pixels @ 242,225*/ 0, 2, 0x04, 0x04, + /* RLE: 154 Pixels @ 244,225*/ 154, 0x00, + /* ABS: 002 Pixels @ 398,225*/ 0, 2, 0x0D, 0x06, + /* RLE: 048 Pixels @ 000,226*/ 48, 0x02, + /* ABS: 009 Pixels @ 048,226*/ 0, 9, 0x00, 0x03, 0x0B, 0x0C, 0x12, 0x0D, 0x08, 0x0F, 0x03, + /* RLE: 041 Pixels @ 057,226*/ 41, 0x00, + /* ABS: 005 Pixels @ 098,226*/ 0, 5, 0x03, 0x00, 0x0C, 0x12, 0x0F, + /* RLE: 004 Pixels @ 103,226*/ 4, 0x08, + /* ABS: 002 Pixels @ 107,226*/ 0, 2, 0x04, 0x03, + /* RLE: 033 Pixels @ 109,226*/ 33, 0x00, + /* ABS: 012 Pixels @ 142,226*/ 0, 12, 0x03, 0x00, 0x06, 0x03, 0x12, 0x0E, 0x0C, 0x00, 0x00, 0x03, 0x03, 0x04, + /* RLE: 077 Pixels @ 154,226*/ 77, 0x00, + /* RLE: 001 Pixels @ 231,226*/ 1, 0x04, + /* RLE: 009 Pixels @ 232,226*/ 9, 0x03, + /* ABS: 002 Pixels @ 241,226*/ 0, 2, 0x04, 0x04, + /* RLE: 156 Pixels @ 243,226*/ 156, 0x00, + /* RLE: 001 Pixels @ 399,226*/ 1, 0x0D, + /* RLE: 049 Pixels @ 000,227*/ 49, 0x02, + /* ABS: 008 Pixels @ 049,227*/ 0, 8, 0x00, 0x06, 0x08, 0x0F, 0x06, 0x11, 0x06, 0x03, + /* RLE: 042 Pixels @ 057,227*/ 42, 0x00, + /* ABS: 009 Pixels @ 099,227*/ 0, 9, 0x12, 0x08, 0x11, 0x0E, 0x0C, 0x0D, 0x08, 0x0C, 0x03, + /* RLE: 036 Pixels @ 108,227*/ 36, 0x00, + /* ABS: 003 Pixels @ 144,227*/ 0, 3, 0x0E, 0x03, 0x0D, + /* RLE: 004 Pixels @ 147,227*/ 4, 0x08, + /* ABS: 003 Pixels @ 151,227*/ 0, 3, 0x06, 0x03, 0x04, + /* RLE: 078 Pixels @ 154,227*/ 78, 0x00, + /* RLE: 001 Pixels @ 232,227*/ 1, 0x04, + /* RLE: 007 Pixels @ 233,227*/ 7, 0x03, + /* ABS: 002 Pixels @ 240,227*/ 0, 2, 0x04, 0x04, + /* RLE: 158 Pixels @ 242,227*/ 158, 0x00, + /* RLE: 049 Pixels @ 000,228*/ 49, 0x02, + /* ABS: 002 Pixels @ 049,228*/ 0, 2, 0x03, 0x00, + /* RLE: 004 Pixels @ 051,228*/ 4, 0x03, + /* ABS: 003 Pixels @ 055,228*/ 0, 3, 0x08, 0x04, 0x03, + /* RLE: 040 Pixels @ 058,228*/ 40, 0x00, + /* ABS: 009 Pixels @ 098,228*/ 0, 9, 0x03, 0x00, 0x03, 0x03, 0x03, 0x0E, 0x08, 0x04, 0x03, + /* RLE: 035 Pixels @ 107,228*/ 35, 0x00, + /* ABS: 012 Pixels @ 142,228*/ 0, 12, 0x03, 0x00, 0x0B, 0x03, 0x03, 0x03, 0x00, 0x04, 0x0D, 0x04, 0x03, 0x04, + /* RLE: 078 Pixels @ 154,228*/ 78, 0x00, + /* ABS: 002 Pixels @ 232,228*/ 0, 2, 0x04, 0x04, + /* RLE: 006 Pixels @ 234,228*/ 6, 0x03, + /* ABS: 002 Pixels @ 240,228*/ 0, 2, 0x04, 0x04, + /* RLE: 158 Pixels @ 242,228*/ 158, 0x00, + /* RLE: 049 Pixels @ 000,229*/ 49, 0x02, + /* RLE: 001 Pixels @ 049,229*/ 1, 0x18, + /* RLE: 005 Pixels @ 050,229*/ 5, 0x03, + /* RLE: 001 Pixels @ 055,229*/ 1, 0x04, + /* RLE: 043 Pixels @ 056,229*/ 43, 0x00, + /* ABS: 006 Pixels @ 099,229*/ 0, 6, 0x0B, 0x03, 0x03, 0x0D, 0x08, 0x04, + /* RLE: 004 Pixels @ 105,229*/ 4, 0x03, + /* RLE: 033 Pixels @ 109,229*/ 33, 0x00, + /* ABS: 003 Pixels @ 142,229*/ 0, 3, 0x03, 0x0E, 0x12, + /* RLE: 005 Pixels @ 145,229*/ 5, 0x03, + /* ABS: 004 Pixels @ 150,229*/ 0, 4, 0x0C, 0x0C, 0x03, 0x04, + /* RLE: 079 Pixels @ 154,229*/ 79, 0x00, + /* RLE: 001 Pixels @ 233,229*/ 1, 0x04, + /* RLE: 007 Pixels @ 234,229*/ 7, 0x03, + /* RLE: 001 Pixels @ 241,229*/ 1, 0x04, + /* RLE: 091 Pixels @ 242,229*/ 91, 0x00, + /* RLE: 006 Pixels @ 333,229*/ 6, 0x04, + /* RLE: 061 Pixels @ 339,229*/ 61, 0x00, + /* RLE: 049 Pixels @ 000,230*/ 49, 0x02, + /* RLE: 001 Pixels @ 049,230*/ 1, 0x18, + /* RLE: 004 Pixels @ 050,230*/ 4, 0x03, + /* ABS: 003 Pixels @ 054,230*/ 0, 3, 0x00, 0x03, 0x03, + /* RLE: 043 Pixels @ 057,230*/ 43, 0x00, + /* ABS: 008 Pixels @ 100,230*/ 0, 8, 0x03, 0x0D, 0x08, 0x0C, 0x0B, 0x0E, 0x06, 0x08, + /* RLE: 035 Pixels @ 108,230*/ 35, 0x00, + /* ABS: 011 Pixels @ 143,230*/ 0, 11, 0x03, 0x03, 0x0C, 0x08, 0x06, 0x12, 0x0C, 0x0F, 0x0C, 0x03, 0x04, + /* RLE: 079 Pixels @ 154,230*/ 79, 0x00, + /* ABS: 002 Pixels @ 233,230*/ 0, 2, 0x04, 0x04, + /* RLE: 007 Pixels @ 235,230*/ 7, 0x03, + /* RLE: 001 Pixels @ 242,230*/ 1, 0x04, + /* RLE: 090 Pixels @ 243,230*/ 90, 0x00, + /* ABS: 007 Pixels @ 333,230*/ 0, 7, 0x04, 0x04, 0x03, 0x03, 0x03, 0x04, 0x04, + /* RLE: 060 Pixels @ 340,230*/ 60, 0x00, + /* RLE: 049 Pixels @ 000,231*/ 49, 0x02, + /* ABS: 008 Pixels @ 049,231*/ 0, 8, 0x03, 0x00, 0x12, 0x03, 0x0D, 0x08, 0x06, 0x03, + /* RLE: 042 Pixels @ 057,231*/ 42, 0x00, + /* ABS: 002 Pixels @ 099,231*/ 0, 2, 0x03, 0x12, + /* RLE: 005 Pixels @ 101,231*/ 5, 0x08, + /* ABS: 004 Pixels @ 106,231*/ 0, 4, 0x06, 0x0E, 0x00, 0x03, + /* RLE: 034 Pixels @ 110,231*/ 34, 0x00, + /* ABS: 010 Pixels @ 144,231*/ 0, 10, 0x03, 0x0B, 0x0E, 0x06, 0x11, 0x08, 0x0D, 0x03, 0x03, 0x04, + /* RLE: 080 Pixels @ 154,231*/ 80, 0x00, + /* RLE: 001 Pixels @ 234,231*/ 1, 0x04, + /* RLE: 007 Pixels @ 235,231*/ 7, 0x03, + /* ABS: 002 Pixels @ 242,231*/ 0, 2, 0x04, 0x04, + /* RLE: 088 Pixels @ 244,231*/ 88, 0x00, + /* ABS: 002 Pixels @ 332,231*/ 0, 2, 0x04, 0x04, + /* RLE: 005 Pixels @ 334,231*/ 5, 0x03, + /* RLE: 001 Pixels @ 339,231*/ 1, 0x04, + /* RLE: 060 Pixels @ 340,231*/ 60, 0x00, + /* RLE: 049 Pixels @ 000,232*/ 49, 0x02, + /* ABS: 007 Pixels @ 049,232*/ 0, 7, 0x03, 0x0E, 0x0D, 0x0B, 0x08, 0x04, 0x0F, + /* RLE: 043 Pixels @ 056,232*/ 43, 0x00, + /* ABS: 010 Pixels @ 099,232*/ 0, 10, 0x03, 0x0E, 0x11, 0x0E, 0x0C, 0x00, 0x00, 0x04, 0x00, 0x0D, + /* RLE: 036 Pixels @ 109,232*/ 36, 0x00, + /* RLE: 008 Pixels @ 145,232*/ 8, 0x03, + /* RLE: 082 Pixels @ 153,232*/ 82, 0x00, + /* RLE: 001 Pixels @ 235,232*/ 1, 0x04, + /* RLE: 007 Pixels @ 236,232*/ 7, 0x03, + /* RLE: 001 Pixels @ 243,232*/ 1, 0x04, + /* RLE: 088 Pixels @ 244,232*/ 88, 0x00, + /* RLE: 001 Pixels @ 332,232*/ 1, 0x04, + /* RLE: 006 Pixels @ 333,232*/ 6, 0x03, + /* RLE: 001 Pixels @ 339,232*/ 1, 0x04, + /* RLE: 060 Pixels @ 340,232*/ 60, 0x00, + /* RLE: 049 Pixels @ 000,233*/ 49, 0x02, + /* ABS: 007 Pixels @ 049,233*/ 0, 7, 0x03, 0x06, 0x0C, 0x0B, 0x08, 0x00, 0x06, + /* RLE: 044 Pixels @ 056,233*/ 44, 0x00, + /* ABS: 011 Pixels @ 100,233*/ 0, 11, 0x03, 0x00, 0x0C, 0x06, 0x0F, 0x08, 0x08, 0x0B, 0x06, 0x0B, 0x03, + /* RLE: 033 Pixels @ 111,233*/ 33, 0x00, + /* ABS: 009 Pixels @ 144,233*/ 0, 9, 0x03, 0x00, 0x0C, 0x0C, 0x0B, 0x00, 0x03, 0x03, 0x04, + /* RLE: 082 Pixels @ 153,233*/ 82, 0x00, + /* ABS: 002 Pixels @ 235,233*/ 0, 2, 0x04, 0x04, + /* RLE: 006 Pixels @ 237,233*/ 6, 0x03, + /* ABS: 002 Pixels @ 243,233*/ 0, 2, 0x04, 0x04, + /* RLE: 086 Pixels @ 245,233*/ 86, 0x00, + /* ABS: 002 Pixels @ 331,233*/ 0, 2, 0x04, 0x04, + /* RLE: 006 Pixels @ 333,233*/ 6, 0x03, + /* RLE: 001 Pixels @ 339,233*/ 1, 0x04, + /* RLE: 060 Pixels @ 340,233*/ 60, 0x00, + /* RLE: 049 Pixels @ 000,234*/ 49, 0x02, + /* ABS: 007 Pixels @ 049,234*/ 0, 7, 0x03, 0x0C, 0x12, 0x0E, 0x08, 0x00, 0x08, + /* RLE: 044 Pixels @ 056,234*/ 44, 0x00, + /* ABS: 010 Pixels @ 100,234*/ 0, 10, 0x03, 0x12, 0x08, 0x11, 0x0E, 0x0C, 0x00, 0x03, 0x03, 0x03, + /* RLE: 033 Pixels @ 110,234*/ 33, 0x00, + /* ABS: 003 Pixels @ 143,234*/ 0, 3, 0x03, 0x00, 0x0F, + /* RLE: 004 Pixels @ 146,234*/ 4, 0x08, + /* ABS: 003 Pixels @ 150,234*/ 0, 3, 0x06, 0x03, 0x04, + /* RLE: 083 Pixels @ 153,234*/ 83, 0x00, + /* RLE: 001 Pixels @ 236,234*/ 1, 0x04, + /* RLE: 007 Pixels @ 237,234*/ 7, 0x03, + /* RLE: 001 Pixels @ 244,234*/ 1, 0x04, + /* RLE: 086 Pixels @ 245,234*/ 86, 0x00, + /* RLE: 001 Pixels @ 331,234*/ 1, 0x04, + /* RLE: 007 Pixels @ 332,234*/ 7, 0x03, + /* RLE: 001 Pixels @ 339,234*/ 1, 0x04, + /* RLE: 060 Pixels @ 340,234*/ 60, 0x00, + /* RLE: 049 Pixels @ 000,235*/ 49, 0x02, + /* ABS: 009 Pixels @ 049,235*/ 0, 9, 0x03, 0x00, 0x0F, 0x08, 0x06, 0x03, 0x0C, 0x03, 0x03, + /* RLE: 044 Pixels @ 058,235*/ 44, 0x00, + /* ABS: 008 Pixels @ 102,235*/ 0, 8, 0x03, 0x03, 0x00, 0x0B, 0x00, 0x03, 0x03, 0x0C, + /* RLE: 032 Pixels @ 110,235*/ 32, 0x00, + /* ABS: 011 Pixels @ 142,235*/ 0, 11, 0x03, 0x00, 0x00, 0x11, 0x03, 0x03, 0x00, 0x04, 0x04, 0x03, 0x04, + /* RLE: 083 Pixels @ 153,235*/ 83, 0x00, + /* ABS: 002 Pixels @ 236,235*/ 0, 2, 0x04, 0x04, + /* RLE: 007 Pixels @ 238,235*/ 7, 0x03, + /* RLE: 001 Pixels @ 245,235*/ 1, 0x04, + /* RLE: 084 Pixels @ 246,235*/ 84, 0x00, + /* ABS: 002 Pixels @ 330,235*/ 0, 2, 0x04, 0x04, + /* RLE: 006 Pixels @ 332,235*/ 6, 0x03, + /* RLE: 001 Pixels @ 338,235*/ 1, 0x04, + /* RLE: 061 Pixels @ 339,235*/ 61, 0x00, + /* RLE: 049 Pixels @ 000,236*/ 49, 0x02, + /* ABS: 010 Pixels @ 049,236*/ 0, 10, 0x18, 0x03, 0x00, 0x0B, 0x03, 0x03, 0x00, 0x0E, 0x00, 0x03, + /* RLE: 041 Pixels @ 059,236*/ 41, 0x00, + /* ABS: 009 Pixels @ 100,236*/ 0, 9, 0x0B, 0x18, 0x03, 0x0E, 0x08, 0x08, 0x08, 0x0D, 0x03, + /* RLE: 032 Pixels @ 109,236*/ 32, 0x00, + /* ABS: 005 Pixels @ 141,236*/ 0, 5, 0x03, 0x00, 0x00, 0x00, 0x11, + /* RLE: 006 Pixels @ 146,236*/ 6, 0x03, + /* RLE: 001 Pixels @ 152,236*/ 1, 0x04, + /* RLE: 084 Pixels @ 153,236*/ 84, 0x00, + /* RLE: 001 Pixels @ 237,236*/ 1, 0x04, + /* RLE: 007 Pixels @ 238,236*/ 7, 0x03, + /* RLE: 001 Pixels @ 245,236*/ 1, 0x04, + /* RLE: 084 Pixels @ 246,236*/ 84, 0x00, + /* RLE: 001 Pixels @ 330,236*/ 1, 0x04, + /* RLE: 007 Pixels @ 331,236*/ 7, 0x03, + /* RLE: 001 Pixels @ 338,236*/ 1, 0x04, + /* RLE: 061 Pixels @ 339,236*/ 61, 0x00, + /* RLE: 050 Pixels @ 000,237*/ 50, 0x02, + /* ABS: 010 Pixels @ 050,237*/ 0, 10, 0x03, 0x03, 0x04, 0x0C, 0x12, 0x0D, 0x08, 0x08, 0x0E, 0x03, + /* RLE: 040 Pixels @ 060,237*/ 40, 0x00, + /* ABS: 010 Pixels @ 100,237*/ 0, 10, 0x0C, 0x03, 0x04, 0x08, 0x0E, 0x11, 0x0B, 0x11, 0x0C, 0x03, + /* RLE: 031 Pixels @ 110,237*/ 31, 0x00, + /* ABS: 012 Pixels @ 141,237*/ 0, 12, 0x03, 0x06, 0x08, 0x08, 0x08, 0x0F, 0x06, 0x0C, 0x0C, 0x03, 0x03, 0x04, + /* RLE: 085 Pixels @ 153,237*/ 85, 0x00, + /* RLE: 001 Pixels @ 238,237*/ 1, 0x04, + /* RLE: 007 Pixels @ 239,237*/ 7, 0x03, + /* RLE: 001 Pixels @ 246,237*/ 1, 0x04, + /* RLE: 082 Pixels @ 247,237*/ 82, 0x00, + /* ABS: 002 Pixels @ 329,237*/ 0, 2, 0x04, 0x04, + /* RLE: 006 Pixels @ 331,237*/ 6, 0x03, + /* RLE: 001 Pixels @ 337,237*/ 1, 0x04, + /* RLE: 062 Pixels @ 338,237*/ 62, 0x00, + /* RLE: 050 Pixels @ 000,238*/ 50, 0x02, + /* ABS: 010 Pixels @ 050,238*/ 0, 10, 0x03, 0x12, 0x08, 0x08, 0x11, 0x06, 0x08, 0x04, 0x0B, 0x03, + /* RLE: 041 Pixels @ 060,238*/ 41, 0x00, + /* ABS: 010 Pixels @ 101,238*/ 0, 10, 0x03, 0x0C, 0x06, 0x03, 0x0F, 0x03, 0x06, 0x0C, 0x03, 0x0C, + /* RLE: 030 Pixels @ 111,238*/ 30, 0x00, + /* ABS: 012 Pixels @ 141,238*/ 0, 12, 0x03, 0x00, 0x00, 0x0C, 0x0C, 0x06, 0x0D, 0x08, 0x08, 0x0B, 0x03, 0x04, + /* RLE: 085 Pixels @ 153,238*/ 85, 0x00, + /* ABS: 002 Pixels @ 238,238*/ 0, 2, 0x04, 0x04, + /* RLE: 006 Pixels @ 240,238*/ 6, 0x03, + /* RLE: 001 Pixels @ 246,238*/ 1, 0x04, + /* RLE: 081 Pixels @ 247,238*/ 81, 0x00, + /* ABS: 002 Pixels @ 328,238*/ 0, 2, 0x04, 0x04, + /* RLE: 007 Pixels @ 330,238*/ 7, 0x03, + /* RLE: 001 Pixels @ 337,238*/ 1, 0x04, + /* RLE: 062 Pixels @ 338,238*/ 62, 0x00, + /* RLE: 050 Pixels @ 000,239*/ 50, 0x02, + /* ABS: 009 Pixels @ 050,239*/ 0, 9, 0x03, 0x06, 0x12, 0x03, 0x03, 0x03, 0x06, 0x00, 0x03, + /* RLE: 043 Pixels @ 059,239*/ 43, 0x00, + /* ABS: 009 Pixels @ 102,239*/ 0, 9, 0x04, 0x0F, 0x0B, 0x12, 0x06, 0x08, 0x00, 0x18, 0x0C, + /* RLE: 031 Pixels @ 111,239*/ 31, 0x00, + /* RLE: 003 Pixels @ 142,239*/ 3, 0x03, + /* ABS: 007 Pixels @ 145,239*/ 0, 7, 0x00, 0x0C, 0x0C, 0x0B, 0x00, 0x03, 0x03, + /* RLE: 087 Pixels @ 152,239*/ 87, 0x00, + /* RLE: 001 Pixels @ 239,239*/ 1, 0x04, + /* RLE: 007 Pixels @ 240,239*/ 7, 0x03, + /* RLE: 001 Pixels @ 247,239*/ 1, 0x04, + /* RLE: 078 Pixels @ 248,239*/ 78, 0x00, + /* ABS: 002 Pixels @ 326,239*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 328,239*/ 8, 0x03, + /* RLE: 001 Pixels @ 336,239*/ 1, 0x04, + /* RLE: 063 Pixels @ 337,239*/ 63, 0x00, + /* RLE: 050 Pixels @ 000,240*/ 50, 0x02, + /* ABS: 009 Pixels @ 050,240*/ 0, 9, 0x03, 0x0B, 0x0B, 0x12, 0x03, 0x0D, 0x08, 0x06, 0x03, + /* RLE: 043 Pixels @ 059,240*/ 43, 0x00, + /* ABS: 009 Pixels @ 102,240*/ 0, 9, 0x03, 0x06, 0x06, 0x0C, 0x0F, 0x04, 0x03, 0x1B, 0x0C, + /* RLE: 034 Pixels @ 111,240*/ 34, 0x00, + /* RLE: 001 Pixels @ 145,240*/ 1, 0x0F, + /* RLE: 004 Pixels @ 146,240*/ 4, 0x08, + /* ABS: 002 Pixels @ 150,240*/ 0, 2, 0x06, 0x03, + /* RLE: 087 Pixels @ 152,240*/ 87, 0x00, + /* ABS: 002 Pixels @ 239,240*/ 0, 2, 0x04, 0x04, + /* RLE: 006 Pixels @ 241,240*/ 6, 0x03, + /* RLE: 001 Pixels @ 247,240*/ 1, 0x04, + /* RLE: 076 Pixels @ 248,240*/ 76, 0x00, + /* ABS: 002 Pixels @ 324,240*/ 0, 2, 0x04, 0x04, + /* RLE: 010 Pixels @ 326,240*/ 10, 0x03, + /* RLE: 001 Pixels @ 336,240*/ 1, 0x04, + /* RLE: 063 Pixels @ 337,240*/ 63, 0x00, + /* RLE: 050 Pixels @ 000,241*/ 50, 0x02, + /* ABS: 010 Pixels @ 050,241*/ 0, 10, 0x18, 0x03, 0x0E, 0x0D, 0x0B, 0x08, 0x0C, 0x0F, 0x00, 0x03, + /* RLE: 041 Pixels @ 060,241*/ 41, 0x00, + /* ABS: 010 Pixels @ 101,241*/ 0, 10, 0x0C, 0x03, 0x03, 0x00, 0x03, 0x00, 0x0B, 0x03, 0x03, 0x0C, + /* RLE: 033 Pixels @ 111,241*/ 33, 0x00, + /* ABS: 008 Pixels @ 144,241*/ 0, 8, 0x0B, 0x11, 0x03, 0x03, 0x0B, 0x04, 0x04, 0x03, + /* RLE: 088 Pixels @ 152,241*/ 88, 0x00, + /* RLE: 001 Pixels @ 240,241*/ 1, 0x04, + /* RLE: 007 Pixels @ 241,241*/ 7, 0x03, + /* RLE: 001 Pixels @ 248,241*/ 1, 0x04, + /* RLE: 073 Pixels @ 249,241*/ 73, 0x00, + /* RLE: 003 Pixels @ 322,241*/ 3, 0x04, + /* RLE: 010 Pixels @ 325,241*/ 10, 0x03, + /* RLE: 001 Pixels @ 335,241*/ 1, 0x04, + /* RLE: 064 Pixels @ 336,241*/ 64, 0x00, + /* RLE: 051 Pixels @ 000,242*/ 51, 0x02, + /* ABS: 007 Pixels @ 051,242*/ 0, 7, 0x03, 0x06, 0x0C, 0x00, 0x08, 0x00, 0x06, + /* RLE: 043 Pixels @ 058,242*/ 43, 0x00, + /* ABS: 009 Pixels @ 101,242*/ 0, 9, 0x0C, 0x18, 0x03, 0x0E, 0x08, 0x08, 0x08, 0x0D, 0x03, + /* RLE: 033 Pixels @ 110,242*/ 33, 0x00, + /* ABS: 003 Pixels @ 143,242*/ 0, 3, 0x03, 0x03, 0x11, + /* RLE: 005 Pixels @ 146,242*/ 5, 0x03, + /* RLE: 089 Pixels @ 151,242*/ 89, 0x00, + /* ABS: 002 Pixels @ 240,242*/ 0, 2, 0x04, 0x04, + /* RLE: 006 Pixels @ 242,242*/ 6, 0x03, + /* RLE: 001 Pixels @ 248,242*/ 1, 0x04, + /* RLE: 054 Pixels @ 249,242*/ 54, 0x00, + /* ABS: 007 Pixels @ 303,242*/ 0, 7, 0x03, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, + /* RLE: 010 Pixels @ 310,242*/ 10, 0x00, + /* RLE: 003 Pixels @ 320,242*/ 3, 0x04, + /* RLE: 011 Pixels @ 323,242*/ 11, 0x03, + /* ABS: 002 Pixels @ 334,242*/ 0, 2, 0x04, 0x04, + /* RLE: 064 Pixels @ 336,242*/ 64, 0x00, + /* RLE: 051 Pixels @ 000,243*/ 51, 0x02, + /* ABS: 007 Pixels @ 051,243*/ 0, 7, 0x03, 0x0C, 0x12, 0x0E, 0x08, 0x00, 0x08, + /* RLE: 045 Pixels @ 058,243*/ 45, 0x00, + /* ABS: 009 Pixels @ 103,243*/ 0, 9, 0x04, 0x08, 0x12, 0x04, 0x0B, 0x0F, 0x04, 0x03, 0x0B, + /* RLE: 031 Pixels @ 112,243*/ 31, 0x00, + /* ABS: 008 Pixels @ 143,243*/ 0, 8, 0x03, 0x0C, 0x08, 0x0F, 0x06, 0x0C, 0x04, 0x03, + /* RLE: 090 Pixels @ 151,243*/ 90, 0x00, + /* RLE: 001 Pixels @ 241,243*/ 1, 0x04, + /* RLE: 007 Pixels @ 242,243*/ 7, 0x03, + /* RLE: 001 Pixels @ 249,243*/ 1, 0x04, + /* RLE: 051 Pixels @ 250,243*/ 51, 0x00, + /* ABS: 009 Pixels @ 301,243*/ 0, 9, 0x03, 0x00, 0x04, 0x03, 0x03, 0x03, 0x04, 0x06, 0x03, + /* RLE: 009 Pixels @ 310,243*/ 9, 0x00, + /* ABS: 002 Pixels @ 319,243*/ 0, 2, 0x04, 0x04, + /* RLE: 012 Pixels @ 321,243*/ 12, 0x03, + /* ABS: 002 Pixels @ 333,243*/ 0, 2, 0x04, 0x04, + /* RLE: 065 Pixels @ 335,243*/ 65, 0x00, + /* RLE: 051 Pixels @ 000,244*/ 51, 0x02, + /* ABS: 009 Pixels @ 051,244*/ 0, 9, 0x03, 0x00, 0x0F, 0x08, 0x06, 0x03, 0x0C, 0x03, 0x03, + /* RLE: 042 Pixels @ 060,244*/ 42, 0x00, + /* ABS: 011 Pixels @ 102,244*/ 0, 11, 0x03, 0x0C, 0x0D, 0x03, 0x03, 0x03, 0x0E, 0x0C, 0x03, 0x00, 0x03, + /* RLE: 028 Pixels @ 113,244*/ 28, 0x00, + /* ABS: 010 Pixels @ 141,244*/ 0, 10, 0x03, 0x00, 0x03, 0x0B, 0x0C, 0x06, 0x0D, 0x08, 0x08, 0x0B, + /* RLE: 090 Pixels @ 151,244*/ 90, 0x00, + /* ABS: 002 Pixels @ 241,244*/ 0, 2, 0x04, 0x04, + /* RLE: 006 Pixels @ 243,244*/ 6, 0x03, + /* RLE: 001 Pixels @ 249,244*/ 1, 0x04, + /* RLE: 046 Pixels @ 250,244*/ 46, 0x00, + /* RLE: 006 Pixels @ 296,244*/ 6, 0x03, + /* ABS: 008 Pixels @ 302,244*/ 0, 8, 0x0E, 0x11, 0x0B, 0x00, 0x0D, 0x11, 0x06, 0x03, + /* RLE: 007 Pixels @ 310,244*/ 7, 0x00, + /* ABS: 002 Pixels @ 317,244*/ 0, 2, 0x04, 0x04, + /* RLE: 012 Pixels @ 319,244*/ 12, 0x03, + /* RLE: 003 Pixels @ 331,244*/ 3, 0x04, + /* RLE: 066 Pixels @ 334,244*/ 66, 0x00, + /* RLE: 051 Pixels @ 000,245*/ 51, 0x02, + /* ABS: 010 Pixels @ 051,245*/ 0, 10, 0x18, 0x03, 0x00, 0x00, 0x03, 0x03, 0x0B, 0x0E, 0x00, 0x03, + /* RLE: 042 Pixels @ 061,245*/ 42, 0x00, + /* ABS: 010 Pixels @ 103,245*/ 0, 10, 0x0B, 0x0F, 0x00, 0x03, 0x0B, 0x0F, 0x06, 0x0F, 0x08, 0x03, + /* RLE: 027 Pixels @ 113,245*/ 27, 0x00, + /* ABS: 003 Pixels @ 140,245*/ 0, 3, 0x03, 0x00, 0x00, + /* RLE: 006 Pixels @ 143,245*/ 6, 0x03, + /* ABS: 002 Pixels @ 149,245*/ 0, 2, 0x00, 0x03, + /* RLE: 091 Pixels @ 151,245*/ 91, 0x00, + /* RLE: 001 Pixels @ 242,245*/ 1, 0x04, + /* RLE: 007 Pixels @ 243,245*/ 7, 0x03, + /* RLE: 001 Pixels @ 250,245*/ 1, 0x04, + /* RLE: 044 Pixels @ 251,245*/ 44, 0x00, + /* ABS: 022 Pixels @ 295,245*/ 0, 22, 0x03, 0x00, 0x12, 0x08, 0x11, 0x00, 0x03, 0x12, 0x08, 0x0F, 0x00, 0x08, 0x06, 0x03, 0x03, 0x00, 0x03, 0x03, 0x03, 0x00, 0x04, 0x04, + /* RLE: 012 Pixels @ 317,245*/ 12, 0x03, + /* RLE: 003 Pixels @ 329,245*/ 3, 0x04, + /* RLE: 068 Pixels @ 332,245*/ 68, 0x00, + /* RLE: 052 Pixels @ 000,246*/ 52, 0x02, + /* ABS: 010 Pixels @ 052,246*/ 0, 10, 0x00, 0x03, 0x04, 0x0C, 0x12, 0x0D, 0x08, 0x08, 0x0E, 0x03, + /* RLE: 040 Pixels @ 062,246*/ 40, 0x00, + /* ABS: 003 Pixels @ 102,246*/ 0, 3, 0x0B, 0x03, 0x06, + /* RLE: 004 Pixels @ 105,246*/ 4, 0x08, + /* ABS: 004 Pixels @ 109,246*/ 0, 4, 0x11, 0x12, 0x0C, 0x03, + /* RLE: 027 Pixels @ 113,246*/ 27, 0x00, + /* ABS: 011 Pixels @ 140,246*/ 0, 11, 0x03, 0x06, 0x06, 0x0C, 0x08, 0x0D, 0x06, 0x0C, 0x0C, 0x03, 0x03, + /* RLE: 091 Pixels @ 151,246*/ 91, 0x00, + /* ABS: 002 Pixels @ 242,246*/ 0, 2, 0x04, 0x04, + /* RLE: 006 Pixels @ 244,246*/ 6, 0x03, + /* RLE: 001 Pixels @ 250,246*/ 1, 0x04, + /* RLE: 043 Pixels @ 251,246*/ 43, 0x00, + /* ABS: 022 Pixels @ 294,246*/ 0, 22, 0x03, 0x0B, 0x08, 0x12, 0x0C, 0x11, 0x0C, 0x03, 0x0E, 0x0F, 0x0E, 0x03, 0x12, 0x0F, 0x03, 0x00, 0x03, 0x12, 0x11, 0x03, 0x04, 0x04, + /* RLE: 012 Pixels @ 316,246*/ 12, 0x03, + /* ABS: 002 Pixels @ 328,246*/ 0, 2, 0x04, 0x04, + /* RLE: 070 Pixels @ 330,246*/ 70, 0x00, + /* RLE: 052 Pixels @ 000,247*/ 52, 0x02, + /* ABS: 010 Pixels @ 052,247*/ 0, 10, 0x03, 0x12, 0x08, 0x08, 0x11, 0x06, 0x08, 0x04, 0x0B, 0x03, + /* RLE: 041 Pixels @ 062,247*/ 41, 0x00, + /* ABS: 009 Pixels @ 103,247*/ 0, 9, 0x03, 0x0D, 0x06, 0x0C, 0x0B, 0x00, 0x03, 0x03, 0x03, + /* RLE: 028 Pixels @ 112,247*/ 28, 0x00, + /* ABS: 009 Pixels @ 140,247*/ 0, 9, 0x03, 0x00, 0x00, 0x00, 0x0C, 0x06, 0x0D, 0x08, 0x08, + /* RLE: 094 Pixels @ 149,247*/ 94, 0x00, + /* RLE: 001 Pixels @ 243,247*/ 1, 0x04, + /* RLE: 007 Pixels @ 244,247*/ 7, 0x03, + /* RLE: 001 Pixels @ 251,247*/ 1, 0x04, + /* RLE: 042 Pixels @ 252,247*/ 42, 0x00, + /* ABS: 003 Pixels @ 294,247*/ 0, 3, 0x03, 0x06, 0x0D, + /* RLE: 006 Pixels @ 297,247*/ 6, 0x03, + /* ABS: 010 Pixels @ 303,247*/ 0, 10, 0x0E, 0x08, 0x00, 0x00, 0x08, 0x04, 0x03, 0x03, 0x04, 0x04, + /* RLE: 013 Pixels @ 313,247*/ 13, 0x03, + /* ABS: 002 Pixels @ 326,247*/ 0, 2, 0x04, 0x04, + /* RLE: 072 Pixels @ 328,247*/ 72, 0x00, + /* RLE: 052 Pixels @ 000,248*/ 52, 0x02, + /* ABS: 009 Pixels @ 052,248*/ 0, 9, 0x03, 0x06, 0x12, 0x03, 0x03, 0x03, 0x0E, 0x00, 0x03, + /* RLE: 042 Pixels @ 061,248*/ 42, 0x00, + /* RLE: 003 Pixels @ 103,248*/ 3, 0x03, + /* ABS: 007 Pixels @ 106,248*/ 0, 7, 0x00, 0x04, 0x00, 0x03, 0x03, 0x09, 0x0C, + /* RLE: 028 Pixels @ 113,248*/ 28, 0x00, + /* RLE: 007 Pixels @ 141,248*/ 7, 0x03, + /* ABS: 002 Pixels @ 148,248*/ 0, 2, 0x00, 0x03, + /* RLE: 093 Pixels @ 150,248*/ 93, 0x00, + /* ABS: 002 Pixels @ 243,248*/ 0, 2, 0x04, 0x04, + /* RLE: 006 Pixels @ 245,248*/ 6, 0x03, + /* RLE: 001 Pixels @ 251,248*/ 1, 0x04, + /* RLE: 042 Pixels @ 252,248*/ 42, 0x00, + /* ABS: 015 Pixels @ 294,248*/ 0, 15, 0x03, 0x0C, 0x08, 0x0D, 0x0F, 0x08, 0x08, 0x12, 0x03, 0x00, 0x08, 0x0C, 0x00, 0x11, 0x06, + /* RLE: 015 Pixels @ 309,248*/ 15, 0x03, + /* ABS: 002 Pixels @ 324,248*/ 0, 2, 0x04, 0x04, + /* RLE: 074 Pixels @ 326,248*/ 74, 0x00, + /* RLE: 052 Pixels @ 000,249*/ 52, 0x02, + /* ABS: 008 Pixels @ 052,249*/ 0, 8, 0x03, 0x0B, 0x00, 0x03, 0x03, 0x03, 0x00, 0x03, + /* RLE: 044 Pixels @ 060,249*/ 44, 0x00, + /* ABS: 009 Pixels @ 104,249*/ 0, 9, 0x03, 0x0E, 0x08, 0x08, 0x08, 0x0D, 0x03, 0x18, 0x0C, + /* RLE: 029 Pixels @ 113,249*/ 29, 0x00, + /* ABS: 009 Pixels @ 142,249*/ 0, 9, 0x03, 0x0C, 0x08, 0x08, 0x0B, 0x0E, 0x03, 0x03, 0x04, + /* RLE: 093 Pixels @ 151,249*/ 93, 0x00, + /* RLE: 001 Pixels @ 244,249*/ 1, 0x04, + /* RLE: 007 Pixels @ 245,249*/ 7, 0x03, + /* RLE: 001 Pixels @ 252,249*/ 1, 0x04, + /* RLE: 039 Pixels @ 253,249*/ 39, 0x00, + /* ABS: 017 Pixels @ 292,249*/ 0, 17, 0x04, 0x04, 0x03, 0x03, 0x0C, 0x06, 0x12, 0x0C, 0x12, 0x08, 0x04, 0x03, 0x0E, 0x08, 0x0F, 0x04, 0x04, + /* RLE: 013 Pixels @ 309,249*/ 13, 0x03, + /* RLE: 003 Pixels @ 322,249*/ 3, 0x04, + /* RLE: 075 Pixels @ 325,249*/ 75, 0x00, + /* RLE: 052 Pixels @ 000,250*/ 52, 0x02, + /* ABS: 009 Pixels @ 052,250*/ 0, 9, 0x03, 0x0B, 0x0C, 0x12, 0x0D, 0x08, 0x0F, 0x03, 0x04, + /* RLE: 042 Pixels @ 061,250*/ 42, 0x00, + /* ABS: 010 Pixels @ 103,250*/ 0, 10, 0x03, 0x04, 0x08, 0x0E, 0x11, 0x00, 0x11, 0x0C, 0x03, 0x0C, + /* RLE: 028 Pixels @ 113,250*/ 28, 0x00, + /* ABS: 010 Pixels @ 141,250*/ 0, 10, 0x03, 0x00, 0x08, 0x04, 0x0D, 0x0B, 0x0F, 0x0C, 0x03, 0x04, + /* RLE: 093 Pixels @ 151,250*/ 93, 0x00, + /* ABS: 002 Pixels @ 244,250*/ 0, 2, 0x04, 0x04, + /* RLE: 006 Pixels @ 246,250*/ 6, 0x03, + /* RLE: 001 Pixels @ 252,250*/ 1, 0x04, + /* RLE: 035 Pixels @ 253,250*/ 35, 0x00, + /* RLE: 007 Pixels @ 288,250*/ 7, 0x03, + /* RLE: 001 Pixels @ 295,250*/ 1, 0x0B, + /* RLE: 005 Pixels @ 296,250*/ 5, 0x03, + /* ABS: 006 Pixels @ 301,250*/ 0, 6, 0x08, 0x0C, 0x03, 0x03, 0x0B, 0x00, + /* RLE: 013 Pixels @ 307,250*/ 13, 0x03, + /* RLE: 003 Pixels @ 320,250*/ 3, 0x04, + /* RLE: 077 Pixels @ 323,250*/ 77, 0x00, + /* RLE: 052 Pixels @ 000,251*/ 52, 0x02, + /* ABS: 008 Pixels @ 052,251*/ 0, 8, 0x03, 0x06, 0x08, 0x0F, 0x06, 0x11, 0x06, 0x03, + /* RLE: 043 Pixels @ 060,251*/ 43, 0x00, + /* ABS: 010 Pixels @ 103,251*/ 0, 10, 0x03, 0x0C, 0x06, 0x03, 0x0F, 0x03, 0x06, 0x0C, 0x03, 0x0C, + /* RLE: 029 Pixels @ 113,251*/ 29, 0x00, + /* ABS: 009 Pixels @ 142,251*/ 0, 9, 0x0C, 0x06, 0x03, 0x0F, 0x03, 0x0E, 0x0C, 0x03, 0x04, + /* RLE: 094 Pixels @ 151,251*/ 94, 0x00, + /* RLE: 001 Pixels @ 245,251*/ 1, 0x04, + /* RLE: 006 Pixels @ 246,251*/ 6, 0x03, + /* ABS: 002 Pixels @ 252,251*/ 0, 2, 0x04, 0x04, + /* RLE: 024 Pixels @ 254,251*/ 24, 0x00, + /* RLE: 003 Pixels @ 278,251*/ 3, 0x03, + /* RLE: 005 Pixels @ 281,251*/ 5, 0x00, + /* ABS: 017 Pixels @ 286,251*/ 0, 17, 0x03, 0x03, 0x00, 0x11, 0x08, 0x0C, 0x03, 0x0E, 0x08, 0x08, 0x04, 0x08, 0x0C, 0x04, 0x0D, 0x0F, 0x00, + /* RLE: 016 Pixels @ 303,251*/ 16, 0x03, + /* ABS: 002 Pixels @ 319,251*/ 0, 2, 0x04, 0x04, + /* RLE: 079 Pixels @ 321,251*/ 79, 0x00, + /* RLE: 052 Pixels @ 000,252*/ 52, 0x02, + /* ABS: 002 Pixels @ 052,252*/ 0, 2, 0x03, 0x00, + /* RLE: 004 Pixels @ 054,252*/ 4, 0x03, + /* ABS: 002 Pixels @ 058,252*/ 0, 2, 0x08, 0x04, + /* RLE: 043 Pixels @ 060,252*/ 43, 0x00, + /* ABS: 011 Pixels @ 103,252*/ 0, 11, 0x03, 0x04, 0x0F, 0x0B, 0x12, 0x06, 0x08, 0x0B, 0x18, 0x09, 0x0C, + /* RLE: 027 Pixels @ 114,252*/ 27, 0x00, + /* ABS: 010 Pixels @ 141,252*/ 0, 10, 0x03, 0x00, 0x08, 0x0E, 0x0F, 0x0B, 0x11, 0x0C, 0x03, 0x04, + /* RLE: 094 Pixels @ 151,252*/ 94, 0x00, + /* RLE: 001 Pixels @ 245,252*/ 1, 0x04, + /* RLE: 007 Pixels @ 246,252*/ 7, 0x03, + /* RLE: 001 Pixels @ 253,252*/ 1, 0x04, + /* RLE: 024 Pixels @ 254,252*/ 24, 0x00, + /* ABS: 003 Pixels @ 278,252*/ 0, 3, 0x03, 0x06, 0x04, + /* RLE: 004 Pixels @ 281,252*/ 4, 0x03, + /* ABS: 017 Pixels @ 285,252*/ 0, 17, 0x00, 0x00, 0x11, 0x06, 0x04, 0x06, 0x08, 0x00, 0x0E, 0x0E, 0x00, 0x03, 0x06, 0x08, 0x08, 0x12, 0x00, + /* RLE: 015 Pixels @ 302,252*/ 15, 0x03, + /* ABS: 002 Pixels @ 317,252*/ 0, 2, 0x04, 0x04, + /* RLE: 081 Pixels @ 319,252*/ 81, 0x00, + /* RLE: 052 Pixels @ 000,253*/ 52, 0x02, + /* ABS: 002 Pixels @ 052,253*/ 0, 2, 0x18, 0x00, + /* RLE: 004 Pixels @ 054,253*/ 4, 0x03, + /* ABS: 003 Pixels @ 058,253*/ 0, 3, 0x04, 0x00, 0x03, + /* RLE: 037 Pixels @ 061,253*/ 37, 0x00, + /* RLE: 005 Pixels @ 098,253*/ 5, 0x03, + /* ABS: 011 Pixels @ 103,253*/ 0, 11, 0x00, 0x03, 0x06, 0x06, 0x0C, 0x0F, 0x04, 0x03, 0x03, 0x18, 0x0C, + /* RLE: 026 Pixels @ 114,253*/ 26, 0x00, + /* ABS: 010 Pixels @ 140,253*/ 0, 10, 0x03, 0x00, 0x03, 0x0E, 0x08, 0x08, 0x08, 0x0D, 0x03, 0x03, + /* RLE: 096 Pixels @ 150,253*/ 96, 0x00, + /* RLE: 001 Pixels @ 246,253*/ 1, 0x04, + /* RLE: 006 Pixels @ 247,253*/ 6, 0x03, + /* ABS: 002 Pixels @ 253,253*/ 0, 2, 0x04, 0x04, + /* RLE: 023 Pixels @ 255,253*/ 23, 0x00, + /* ABS: 015 Pixels @ 278,253*/ 0, 15, 0x03, 0x11, 0x06, 0x00, 0x11, 0x08, 0x0C, 0x03, 0x03, 0x08, 0x06, 0x03, 0x00, 0x08, 0x0C, + /* RLE: 025 Pixels @ 293,253*/ 25, 0x03, + /* ABS: 002 Pixels @ 318,253*/ 0, 2, 0x04, 0x04, + /* RLE: 080 Pixels @ 320,253*/ 80, 0x00, + /* RLE: 053 Pixels @ 000,254*/ 53, 0x02, + /* ABS: 003 Pixels @ 053,254*/ 0, 3, 0x03, 0x0B, 0x0B, + /* RLE: 005 Pixels @ 056,254*/ 5, 0x03, + /* RLE: 001 Pixels @ 061,254*/ 1, 0x04, + /* RLE: 033 Pixels @ 062,254*/ 33, 0x00, + /* RLE: 003 Pixels @ 095,254*/ 3, 0x03, + /* RLE: 005 Pixels @ 098,254*/ 5, 0x13, + /* RLE: 003 Pixels @ 103,254*/ 3, 0x03, + /* ABS: 008 Pixels @ 106,254*/ 0, 8, 0x00, 0x03, 0x03, 0x03, 0x00, 0x04, 0x03, 0x0C, + /* RLE: 025 Pixels @ 114,254*/ 25, 0x00, + /* ABS: 011 Pixels @ 139,254*/ 0, 11, 0x03, 0x00, 0x00, 0x00, 0x03, 0x03, 0x0B, 0x00, 0x03, 0x03, 0x04, + /* RLE: 096 Pixels @ 150,254*/ 96, 0x00, + /* RLE: 001 Pixels @ 246,254*/ 1, 0x04, + /* RLE: 007 Pixels @ 247,254*/ 7, 0x03, + /* RLE: 001 Pixels @ 254,254*/ 1, 0x04, + /* RLE: 023 Pixels @ 255,254*/ 23, 0x00, + /* ABS: 015 Pixels @ 278,254*/ 0, 15, 0x03, 0x0C, 0x08, 0x0D, 0x04, 0x12, 0x08, 0x00, 0x03, 0x0E, 0x0F, 0x03, 0x03, 0x12, 0x11, + /* RLE: 004 Pixels @ 293,254*/ 4, 0x03, + /* RLE: 014 Pixels @ 297,254*/ 14, 0x04, + /* RLE: 008 Pixels @ 311,254*/ 8, 0x03, + /* ABS: 002 Pixels @ 319,254*/ 0, 2, 0x04, 0x04, + /* RLE: 079 Pixels @ 321,254*/ 79, 0x00, + /* RLE: 053 Pixels @ 000,255*/ 53, 0x02, + /* ABS: 003 Pixels @ 053,255*/ 0, 3, 0x03, 0x06, 0x06, + /* RLE: 005 Pixels @ 056,255*/ 5, 0x03, + /* RLE: 001 Pixels @ 061,255*/ 1, 0x04, + /* RLE: 032 Pixels @ 062,255*/ 32, 0x00, + /* ABS: 004 Pixels @ 094,255*/ 0, 4, 0x03, 0x03, 0x13, 0x13, + /* RLE: 005 Pixels @ 098,255*/ 5, 0x17, + /* ABS: 011 Pixels @ 103,255*/ 0, 11, 0x13, 0x13, 0x03, 0x03, 0x0C, 0x06, 0x0F, 0x08, 0x08, 0x03, 0x0C, + /* RLE: 025 Pixels @ 114,255*/ 25, 0x00, + /* ABS: 010 Pixels @ 139,255*/ 0, 10, 0x03, 0x06, 0x08, 0x08, 0x08, 0x0D, 0x06, 0x0C, 0x0C, 0x03, + /* RLE: 098 Pixels @ 149,255*/ 98, 0x00, + /* RLE: 001 Pixels @ 247,255*/ 1, 0x04, + /* RLE: 006 Pixels @ 248,255*/ 6, 0x03, + /* ABS: 002 Pixels @ 254,255*/ 0, 2, 0x04, 0x04, + /* RLE: 014 Pixels @ 256,255*/ 14, 0x00, + /* ABS: 002 Pixels @ 270,255*/ 0, 2, 0x03, 0x03, + /* RLE: 004 Pixels @ 272,255*/ 4, 0x00, + /* RLE: 004 Pixels @ 276,255*/ 4, 0x03, + /* ABS: 016 Pixels @ 280,255*/ 0, 16, 0x0F, 0x06, 0x03, 0x00, 0x08, 0x0C, 0x03, 0x00, 0x08, 0x04, 0x03, 0x0B, 0x08, 0x00, 0x03, 0x04, + /* RLE: 014 Pixels @ 296,255*/ 14, 0x00, + /* ABS: 002 Pixels @ 310,255*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 312,255*/ 8, 0x03, + /* ABS: 002 Pixels @ 320,255*/ 0, 2, 0x04, 0x04, + /* RLE: 078 Pixels @ 322,255*/ 78, 0x00, + /* RLE: 053 Pixels @ 000,256*/ 53, 0x02, + /* ABS: 003 Pixels @ 053,256*/ 0, 3, 0x03, 0x00, 0x00, + /* RLE: 005 Pixels @ 056,256*/ 5, 0x03, + /* RLE: 001 Pixels @ 061,256*/ 1, 0x04, + /* RLE: 031 Pixels @ 062,256*/ 31, 0x00, + /* ABS: 003 Pixels @ 093,256*/ 0, 3, 0x03, 0x03, 0x13, + /* RLE: 007 Pixels @ 096,256*/ 7, 0x17, + /* ABS: 010 Pixels @ 103,256*/ 0, 10, 0x16, 0x16, 0x13, 0x03, 0x03, 0x0D, 0x0E, 0x0E, 0x06, 0x03, + /* RLE: 026 Pixels @ 113,256*/ 26, 0x00, + /* ABS: 009 Pixels @ 139,256*/ 0, 9, 0x03, 0x00, 0x00, 0x0C, 0x0C, 0x06, 0x0D, 0x08, 0x08, + /* RLE: 099 Pixels @ 148,256*/ 99, 0x00, + /* RLE: 001 Pixels @ 247,256*/ 1, 0x04, + /* RLE: 007 Pixels @ 248,256*/ 7, 0x03, + /* RLE: 001 Pixels @ 255,256*/ 1, 0x04, + /* RLE: 013 Pixels @ 256,256*/ 13, 0x00, + /* ABS: 025 Pixels @ 269,256*/ 0, 25, 0x03, 0x04, 0x0C, 0x03, 0x00, 0x03, 0x03, 0x04, 0x06, 0x12, 0x03, 0x0E, 0x0F, 0x03, 0x03, 0x12, 0x11, 0x03, 0x03, 0x0D, 0x0D, 0x03, 0x03, 0x00, 0x03, + /* RLE: 017 Pixels @ 294,256*/ 17, 0x00, + /* ABS: 002 Pixels @ 311,256*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 313,256*/ 8, 0x03, + /* ABS: 002 Pixels @ 321,256*/ 0, 2, 0x04, 0x04, + /* RLE: 077 Pixels @ 323,256*/ 77, 0x00, + /* RLE: 053 Pixels @ 000,257*/ 53, 0x02, + /* ABS: 002 Pixels @ 053,257*/ 0, 2, 0x18, 0x00, + /* RLE: 006 Pixels @ 055,257*/ 6, 0x03, + /* RLE: 001 Pixels @ 061,257*/ 1, 0x04, + /* RLE: 030 Pixels @ 062,257*/ 30, 0x00, + /* ABS: 008 Pixels @ 092,257*/ 0, 8, 0x03, 0x03, 0x13, 0x17, 0x17, 0x17, 0x03, 0x03, + /* RLE: 004 Pixels @ 100,257*/ 4, 0x17, + /* ABS: 003 Pixels @ 104,257*/ 0, 3, 0x16, 0x16, 0x13, + /* RLE: 004 Pixels @ 107,257*/ 4, 0x03, + /* ABS: 004 Pixels @ 111,257*/ 0, 4, 0x0E, 0x0E, 0x03, 0x0C, + /* RLE: 024 Pixels @ 115,257*/ 24, 0x00, + /* ABS: 002 Pixels @ 139,257*/ 0, 2, 0x03, 0x04, + /* RLE: 006 Pixels @ 141,257*/ 6, 0x03, + /* ABS: 002 Pixels @ 147,257*/ 0, 2, 0x00, 0x03, + /* RLE: 099 Pixels @ 149,257*/ 99, 0x00, + /* RLE: 001 Pixels @ 248,257*/ 1, 0x04, + /* RLE: 006 Pixels @ 249,257*/ 6, 0x03, + /* ABS: 002 Pixels @ 255,257*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 257,257*/ 8, 0x00, + /* RLE: 003 Pixels @ 265,257*/ 3, 0x03, + /* ABS: 024 Pixels @ 268,257*/ 0, 24, 0x00, 0x03, 0x0E, 0x08, 0x03, 0x00, 0x03, 0x0D, 0x11, 0x0C, 0x08, 0x0C, 0x00, 0x08, 0x04, 0x03, 0x0B, 0x08, 0x00, 0x03, 0x0B, 0x04, 0x03, 0x0B, + /* RLE: 020 Pixels @ 292,257*/ 20, 0x00, + /* ABS: 002 Pixels @ 312,257*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 314,257*/ 8, 0x03, + /* ABS: 002 Pixels @ 322,257*/ 0, 2, 0x04, 0x04, + /* RLE: 076 Pixels @ 324,257*/ 76, 0x00, + /* RLE: 054 Pixels @ 000,258*/ 54, 0x02, + /* RLE: 001 Pixels @ 054,258*/ 1, 0x04, + /* RLE: 006 Pixels @ 055,258*/ 6, 0x03, + /* RLE: 001 Pixels @ 061,258*/ 1, 0x04, + /* RLE: 030 Pixels @ 062,258*/ 30, 0x00, + /* ABS: 005 Pixels @ 092,258*/ 0, 5, 0x03, 0x13, 0x16, 0x17, 0x17, + /* RLE: 004 Pixels @ 097,258*/ 4, 0x03, + /* RLE: 003 Pixels @ 101,258*/ 3, 0x17, + /* RLE: 003 Pixels @ 104,258*/ 3, 0x16, + /* ABS: 008 Pixels @ 107,258*/ 0, 8, 0x13, 0x03, 0x03, 0x0B, 0x0D, 0x06, 0x03, 0x0C, + /* RLE: 024 Pixels @ 115,258*/ 24, 0x00, + /* ABS: 003 Pixels @ 139,258*/ 0, 3, 0x03, 0x08, 0x0B, + /* RLE: 004 Pixels @ 142,258*/ 4, 0x03, + /* ABS: 004 Pixels @ 146,258*/ 0, 4, 0x00, 0x0E, 0x03, 0x04, + /* RLE: 098 Pixels @ 150,258*/ 98, 0x00, + /* RLE: 001 Pixels @ 248,258*/ 1, 0x04, + /* RLE: 007 Pixels @ 249,258*/ 7, 0x03, + /* RLE: 001 Pixels @ 256,258*/ 1, 0x04, + /* RLE: 008 Pixels @ 257,258*/ 8, 0x00, + /* ABS: 025 Pixels @ 265,258*/ 0, 25, 0x03, 0x06, 0x0C, 0x03, 0x03, 0x00, 0x08, 0x0C, 0x03, 0x03, 0x0D, 0x00, 0x0B, 0x0F, 0x11, 0x03, 0x06, 0x0D, 0x03, 0x03, 0x00, 0x03, 0x00, 0x00, 0x03, + /* RLE: 023 Pixels @ 290,258*/ 23, 0x00, + /* ABS: 002 Pixels @ 313,258*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 315,258*/ 8, 0x03, + /* ABS: 002 Pixels @ 323,258*/ 0, 2, 0x04, 0x04, + /* RLE: 075 Pixels @ 325,258*/ 75, 0x00, + /* RLE: 054 Pixels @ 000,259*/ 54, 0x02, + /* RLE: 001 Pixels @ 054,259*/ 1, 0x04, + /* RLE: 007 Pixels @ 055,259*/ 7, 0x03, + /* RLE: 030 Pixels @ 062,259*/ 30, 0x00, + /* ABS: 005 Pixels @ 092,259*/ 0, 5, 0x03, 0x13, 0x16, 0x17, 0x17, + /* RLE: 004 Pixels @ 097,259*/ 4, 0x03, + /* RLE: 004 Pixels @ 101,259*/ 4, 0x17, + /* ABS: 010 Pixels @ 105,259*/ 0, 10, 0x16, 0x16, 0x13, 0x03, 0x08, 0x08, 0x08, 0x0B, 0x03, 0x0C, + /* RLE: 024 Pixels @ 115,259*/ 24, 0x00, + /* ABS: 011 Pixels @ 139,259*/ 0, 11, 0x03, 0x0D, 0x0F, 0x00, 0x03, 0x00, 0x12, 0x08, 0x08, 0x03, 0x04, + /* RLE: 099 Pixels @ 150,259*/ 99, 0x00, + /* RLE: 001 Pixels @ 249,259*/ 1, 0x04, + /* RLE: 006 Pixels @ 250,259*/ 6, 0x03, + /* ABS: 002 Pixels @ 256,259*/ 0, 2, 0x04, 0x04, + /* RLE: 007 Pixels @ 258,259*/ 7, 0x00, + /* ABS: 021 Pixels @ 265,259*/ 0, 21, 0x03, 0x11, 0x11, 0x03, 0x03, 0x00, 0x0F, 0x11, 0x03, 0x03, 0x03, 0x0E, 0x0D, 0x0C, 0x08, 0x0B, 0x0B, 0x04, 0x03, 0x03, 0x0B, + /* RLE: 028 Pixels @ 286,259*/ 28, 0x00, + /* ABS: 002 Pixels @ 314,259*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 316,259*/ 8, 0x03, + /* ABS: 002 Pixels @ 324,259*/ 0, 2, 0x04, 0x04, + /* RLE: 074 Pixels @ 326,259*/ 74, 0x00, + /* RLE: 055 Pixels @ 000,260*/ 55, 0x02, + /* RLE: 001 Pixels @ 055,260*/ 1, 0x04, + /* RLE: 006 Pixels @ 056,260*/ 6, 0x03, + /* RLE: 001 Pixels @ 062,260*/ 1, 0x04, + /* RLE: 029 Pixels @ 063,260*/ 29, 0x00, + /* ABS: 008 Pixels @ 092,260*/ 0, 8, 0x03, 0x13, 0x16, 0x17, 0x17, 0x17, 0x03, 0x03, + /* RLE: 005 Pixels @ 100,260*/ 5, 0x17, + /* ABS: 010 Pixels @ 105,260*/ 0, 10, 0x16, 0x16, 0x13, 0x03, 0x0C, 0x0B, 0x03, 0x03, 0x18, 0x0C, + /* RLE: 024 Pixels @ 115,260*/ 24, 0x00, + /* ABS: 010 Pixels @ 139,260*/ 0, 10, 0x03, 0x00, 0x0F, 0x0D, 0x06, 0x08, 0x08, 0x12, 0x0B, 0x03, + /* RLE: 100 Pixels @ 149,260*/ 100, 0x00, + /* RLE: 001 Pixels @ 249,260*/ 1, 0x04, + /* RLE: 007 Pixels @ 250,260*/ 7, 0x03, + /* RLE: 001 Pixels @ 257,260*/ 1, 0x0C, + /* RLE: 007 Pixels @ 258,260*/ 7, 0x00, + /* ABS: 018 Pixels @ 265,260*/ 0, 18, 0x03, 0x04, 0x08, 0x04, 0x12, 0x08, 0x0F, 0x08, 0x0B, 0x03, 0x00, 0x08, 0x00, 0x00, 0x08, 0x0D, 0x03, 0x03, + /* RLE: 032 Pixels @ 283,260*/ 32, 0x00, + /* ABS: 002 Pixels @ 315,260*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 317,260*/ 8, 0x03, + /* RLE: 001 Pixels @ 325,260*/ 1, 0x04, + /* RLE: 074 Pixels @ 326,260*/ 74, 0x00, + /* RLE: 055 Pixels @ 000,261*/ 55, 0x02, + /* RLE: 001 Pixels @ 055,261*/ 1, 0x04, + /* RLE: 006 Pixels @ 056,261*/ 6, 0x03, + /* RLE: 001 Pixels @ 062,261*/ 1, 0x04, + /* RLE: 029 Pixels @ 063,261*/ 29, 0x00, + /* ABS: 003 Pixels @ 092,261*/ 0, 3, 0x03, 0x13, 0x16, + /* RLE: 009 Pixels @ 095,261*/ 9, 0x17, + /* RLE: 003 Pixels @ 104,261*/ 3, 0x16, + /* ABS: 009 Pixels @ 107,261*/ 0, 9, 0x13, 0x03, 0x03, 0x00, 0x0C, 0x00, 0x03, 0x1B, 0x0C, + /* RLE: 023 Pixels @ 116,261*/ 23, 0x00, + /* ABS: 009 Pixels @ 139,261*/ 0, 9, 0x03, 0x03, 0x0B, 0x08, 0x08, 0x0C, 0x00, 0x03, 0x03, + /* RLE: 102 Pixels @ 148,261*/ 102, 0x00, + /* ABS: 002 Pixels @ 250,261*/ 0, 2, 0x04, 0x03, + /* RLE: 006 Pixels @ 252,261*/ 6, 0x09, + /* ABS: 024 Pixels @ 258,261*/ 0, 24, 0x0C, 0x0C, 0x00, 0x00, 0x00, 0x04, 0x04, 0x03, 0x03, 0x0F, 0x08, 0x12, 0x0B, 0x03, 0x0F, 0x12, 0x03, 0x00, 0x08, 0x11, 0x11, 0x00, 0x00, 0x03, + /* RLE: 034 Pixels @ 282,261*/ 34, 0x00, + /* ABS: 002 Pixels @ 316,261*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 318,261*/ 8, 0x03, + /* RLE: 074 Pixels @ 326,261*/ 74, 0x00, + /* RLE: 055 Pixels @ 000,262*/ 55, 0x02, + /* RLE: 001 Pixels @ 055,262*/ 1, 0x04, + /* RLE: 006 Pixels @ 056,262*/ 6, 0x03, + /* RLE: 001 Pixels @ 062,262*/ 1, 0x04, + /* RLE: 029 Pixels @ 063,262*/ 29, 0x00, + /* ABS: 004 Pixels @ 092,262*/ 0, 4, 0x03, 0x13, 0x16, 0x16, + /* RLE: 007 Pixels @ 096,262*/ 7, 0x17, + /* RLE: 004 Pixels @ 103,262*/ 4, 0x16, + /* ABS: 009 Pixels @ 107,262*/ 0, 9, 0x13, 0x03, 0x03, 0x0F, 0x08, 0x0F, 0x00, 0x18, 0x0C, + /* RLE: 022 Pixels @ 116,262*/ 22, 0x00, + /* ABS: 011 Pixels @ 138,262*/ 0, 11, 0x03, 0x00, 0x04, 0x00, 0x0C, 0x08, 0x04, 0x03, 0x03, 0x03, 0x0B, + /* RLE: 101 Pixels @ 149,262*/ 101, 0x00, + /* ABS: 009 Pixels @ 250,262*/ 0, 9, 0x04, 0x03, 0x1B, 0x18, 0x18, 0x18, 0x09, 0x09, 0x1B, + /* RLE: 007 Pixels @ 259,262*/ 7, 0x03, + /* ABS: 015 Pixels @ 266,262*/ 0, 15, 0x0B, 0x0E, 0x08, 0x00, 0x03, 0x03, 0x0E, 0x08, 0x00, 0x03, 0x00, 0x0C, 0x00, 0x03, 0x03, + /* RLE: 036 Pixels @ 281,262*/ 36, 0x00, + /* ABS: 002 Pixels @ 317,262*/ 0, 2, 0x04, 0x04, + /* RLE: 007 Pixels @ 319,262*/ 7, 0x03, + /* RLE: 001 Pixels @ 326,262*/ 1, 0x04, + /* RLE: 073 Pixels @ 327,262*/ 73, 0x00, + /* RLE: 055 Pixels @ 000,263*/ 55, 0x02, + /* RLE: 001 Pixels @ 055,263*/ 1, 0x04, + /* RLE: 006 Pixels @ 056,263*/ 6, 0x03, + /* RLE: 001 Pixels @ 062,263*/ 1, 0x04, + /* RLE: 029 Pixels @ 063,263*/ 29, 0x00, + /* ABS: 002 Pixels @ 092,263*/ 0, 2, 0x03, 0x13, + /* RLE: 004 Pixels @ 094,263*/ 4, 0x16, + /* RLE: 004 Pixels @ 098,263*/ 4, 0x17, + /* RLE: 005 Pixels @ 102,263*/ 5, 0x16, + /* ABS: 009 Pixels @ 107,263*/ 0, 9, 0x13, 0x03, 0x0B, 0x08, 0x04, 0x06, 0x0C, 0x03, 0x0C, + /* RLE: 022 Pixels @ 116,263*/ 22, 0x00, + /* ABS: 002 Pixels @ 138,263*/ 0, 2, 0x03, 0x12, + /* RLE: 004 Pixels @ 140,263*/ 4, 0x08, + /* ABS: 005 Pixels @ 144,263*/ 0, 5, 0x0F, 0x12, 0x0C, 0x00, 0x03, + /* RLE: 102 Pixels @ 149,263*/ 102, 0x00, + /* ABS: 027 Pixels @ 251,263*/ 0, 27, 0x09, 0x18, 0x00, 0x04, 0x03, 0x1B, 0x18, 0x03, 0x04, 0x06, 0x06, 0x04, 0x03, 0x0E, 0x08, 0x08, 0x00, 0x08, 0x0C, 0x03, 0x03, 0x00, 0x06, 0x00, 0x03, 0x00, 0x03, + /* RLE: 040 Pixels @ 278,263*/ 40, 0x00, + /* ABS: 002 Pixels @ 318,263*/ 0, 2, 0x04, 0x04, + /* RLE: 006 Pixels @ 320,263*/ 6, 0x03, + /* RLE: 001 Pixels @ 326,263*/ 1, 0x04, + /* RLE: 073 Pixels @ 327,263*/ 73, 0x00, + /* RLE: 055 Pixels @ 000,264*/ 55, 0x02, + /* RLE: 001 Pixels @ 055,264*/ 1, 0x04, + /* RLE: 006 Pixels @ 056,264*/ 6, 0x03, + /* RLE: 001 Pixels @ 062,264*/ 1, 0x04, + /* RLE: 029 Pixels @ 063,264*/ 29, 0x00, + /* ABS: 003 Pixels @ 092,264*/ 0, 3, 0x03, 0x03, 0x13, + /* RLE: 011 Pixels @ 095,264*/ 11, 0x16, + /* ABS: 010 Pixels @ 106,264*/ 0, 10, 0x13, 0x03, 0x03, 0x00, 0x08, 0x0B, 0x0E, 0x0C, 0x03, 0x0C, + /* RLE: 023 Pixels @ 116,264*/ 23, 0x00, + /* ABS: 010 Pixels @ 139,264*/ 0, 10, 0x03, 0x0B, 0x04, 0x0C, 0x12, 0x06, 0x08, 0x08, 0x0B, 0x03, + /* RLE: 102 Pixels @ 149,264*/ 102, 0x00, + /* ABS: 019 Pixels @ 251,264*/ 0, 19, 0x18, 0x03, 0x0E, 0x11, 0x0B, 0x03, 0x03, 0x0C, 0x0F, 0x0E, 0x12, 0x08, 0x04, 0x0E, 0x0E, 0x00, 0x03, 0x06, 0x11, + /* RLE: 005 Pixels @ 270,264*/ 5, 0x03, + /* RLE: 045 Pixels @ 275,264*/ 45, 0x00, + /* RLE: 007 Pixels @ 320,264*/ 7, 0x03, + /* RLE: 001 Pixels @ 327,264*/ 1, 0x04, + /* RLE: 072 Pixels @ 328,264*/ 72, 0x00, + /* RLE: 055 Pixels @ 000,265*/ 55, 0x02, + /* RLE: 001 Pixels @ 055,265*/ 1, 0x04, + /* RLE: 006 Pixels @ 056,265*/ 6, 0x03, + /* RLE: 001 Pixels @ 062,265*/ 1, 0x04, + /* RLE: 030 Pixels @ 063,265*/ 30, 0x00, + /* ABS: 003 Pixels @ 093,265*/ 0, 3, 0x03, 0x03, 0x13, + /* RLE: 009 Pixels @ 096,265*/ 9, 0x16, + /* ABS: 011 Pixels @ 105,265*/ 0, 11, 0x13, 0x03, 0x03, 0x11, 0x0C, 0x08, 0x00, 0x11, 0x04, 0x03, 0x0C, + /* RLE: 021 Pixels @ 116,265*/ 21, 0x00, + /* ABS: 002 Pixels @ 137,265*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 139,265*/ 9, 0x03, + /* RLE: 097 Pixels @ 148,265*/ 97, 0x00, + /* ABS: 019 Pixels @ 245,265*/ 0, 19, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x04, 0x03, 0x12, 0x08, 0x0F, 0x0B, 0x03, 0x11, 0x0E, 0x03, 0x03, 0x0D, 0x0D, + /* RLE: 004 Pixels @ 264,265*/ 4, 0x03, + /* ABS: 004 Pixels @ 268,265*/ 0, 4, 0x0B, 0x04, 0x03, 0x04, + /* RLE: 048 Pixels @ 272,265*/ 48, 0x00, + /* RLE: 001 Pixels @ 320,265*/ 1, 0x04, + /* RLE: 006 Pixels @ 321,265*/ 6, 0x03, + /* RLE: 001 Pixels @ 327,265*/ 1, 0x04, + /* RLE: 072 Pixels @ 328,265*/ 72, 0x00, + /* RLE: 056 Pixels @ 000,266*/ 56, 0x02, + /* RLE: 007 Pixels @ 056,266*/ 7, 0x03, + /* RLE: 001 Pixels @ 063,266*/ 1, 0x04, + /* RLE: 030 Pixels @ 064,266*/ 30, 0x00, + /* ABS: 004 Pixels @ 094,266*/ 0, 4, 0x03, 0x03, 0x13, 0x13, + /* RLE: 005 Pixels @ 098,266*/ 5, 0x16, + /* ABS: 014 Pixels @ 103,266*/ 0, 14, 0x13, 0x13, 0x03, 0x03, 0x03, 0x0D, 0x08, 0x0F, 0x03, 0x0B, 0x03, 0x03, 0x18, 0x0B, + /* RLE: 018 Pixels @ 117,266*/ 18, 0x00, + /* RLE: 003 Pixels @ 135,266*/ 3, 0x04, + /* RLE: 007 Pixels @ 138,266*/ 7, 0x03, + /* ABS: 002 Pixels @ 145,266*/ 0, 2, 0x04, 0x04, + /* RLE: 096 Pixels @ 147,266*/ 96, 0x00, + /* ABS: 021 Pixels @ 243,266*/ 0, 21, 0x03, 0x03, 0x00, 0x00, 0x03, 0x03, 0x03, 0x0E, 0x11, 0x0B, 0x0E, 0x0F, 0x0E, 0x03, 0x03, 0x11, 0x12, 0x03, 0x03, 0x0C, 0x0F, + /* RLE: 005 Pixels @ 264,266*/ 5, 0x03, + /* RLE: 051 Pixels @ 269,266*/ 51, 0x00, + /* RLE: 001 Pixels @ 320,266*/ 1, 0x04, + /* RLE: 007 Pixels @ 321,266*/ 7, 0x03, + /* RLE: 072 Pixels @ 328,266*/ 72, 0x00, + /* RLE: 056 Pixels @ 000,267*/ 56, 0x02, + /* RLE: 001 Pixels @ 056,267*/ 1, 0x04, + /* RLE: 006 Pixels @ 057,267*/ 6, 0x03, + /* RLE: 001 Pixels @ 063,267*/ 1, 0x04, + /* RLE: 028 Pixels @ 064,267*/ 28, 0x00, + /* ABS: 006 Pixels @ 092,267*/ 0, 6, 0x0B, 0x00, 0x00, 0x03, 0x13, 0x00, + /* RLE: 005 Pixels @ 098,267*/ 5, 0x13, + /* RLE: 003 Pixels @ 103,267*/ 3, 0x03, + /* ABS: 011 Pixels @ 106,267*/ 0, 11, 0x00, 0x03, 0x03, 0x0B, 0x03, 0x03, 0x0B, 0x11, 0x0E, 0x00, 0x03, + /* RLE: 016 Pixels @ 117,267*/ 16, 0x00, + /* ABS: 002 Pixels @ 133,267*/ 0, 2, 0x04, 0x04, + /* RLE: 010 Pixels @ 135,267*/ 10, 0x03, + /* RLE: 001 Pixels @ 145,267*/ 1, 0x04, + /* RLE: 096 Pixels @ 146,267*/ 96, 0x00, + /* ABS: 026 Pixels @ 242,267*/ 0, 26, 0x03, 0x00, 0x06, 0x08, 0x08, 0x08, 0x0E, 0x03, 0x12, 0x08, 0x0F, 0x0B, 0x0E, 0x08, 0x00, 0x03, 0x0C, 0x08, 0x0C, 0x0B, 0x11, 0x0E, 0x03, 0x03, 0x04, 0x04, + /* RLE: 053 Pixels @ 268,267*/ 53, 0x00, + /* RLE: 001 Pixels @ 321,267*/ 1, 0x04, + /* RLE: 006 Pixels @ 322,267*/ 6, 0x03, + /* RLE: 001 Pixels @ 328,267*/ 1, 0x04, + /* RLE: 071 Pixels @ 329,267*/ 71, 0x00, + /* RLE: 056 Pixels @ 000,268*/ 56, 0x02, + /* RLE: 001 Pixels @ 056,268*/ 1, 0x04, + /* RLE: 006 Pixels @ 057,268*/ 6, 0x03, + /* RLE: 001 Pixels @ 063,268*/ 1, 0x04, + /* RLE: 029 Pixels @ 064,268*/ 29, 0x00, + /* ABS: 006 Pixels @ 093,268*/ 0, 6, 0x0B, 0x03, 0x13, 0x00, 0x13, 0x13, + /* RLE: 005 Pixels @ 099,268*/ 5, 0x03, + /* RLE: 004 Pixels @ 104,268*/ 4, 0x00, + /* ABS: 009 Pixels @ 108,268*/ 0, 9, 0x03, 0x04, 0x0E, 0x11, 0x08, 0x08, 0x08, 0x06, 0x03, + /* RLE: 013 Pixels @ 117,268*/ 13, 0x00, + /* RLE: 003 Pixels @ 130,268*/ 3, 0x04, + /* RLE: 011 Pixels @ 133,268*/ 11, 0x03, + /* RLE: 001 Pixels @ 144,268*/ 1, 0x04, + /* RLE: 096 Pixels @ 145,268*/ 96, 0x00, + /* ABS: 023 Pixels @ 241,268*/ 0, 23, 0x03, 0x03, 0x11, 0x0D, 0x04, 0x00, 0x0E, 0x08, 0x0C, 0x0E, 0x0F, 0x0E, 0x03, 0x00, 0x08, 0x0C, 0x00, 0x03, 0x12, 0x08, 0x08, 0x0E, 0x03, + /* RLE: 057 Pixels @ 264,268*/ 57, 0x00, + /* RLE: 001 Pixels @ 321,268*/ 1, 0x04, + /* RLE: 006 Pixels @ 322,268*/ 6, 0x03, + /* RLE: 001 Pixels @ 328,268*/ 1, 0x04, + /* RLE: 071 Pixels @ 329,268*/ 71, 0x00, + /* RLE: 056 Pixels @ 000,269*/ 56, 0x02, + /* RLE: 001 Pixels @ 056,269*/ 1, 0x04, + /* RLE: 006 Pixels @ 057,269*/ 6, 0x03, + /* RLE: 001 Pixels @ 063,269*/ 1, 0x04, + /* RLE: 029 Pixels @ 064,269*/ 29, 0x00, + /* ABS: 007 Pixels @ 093,269*/ 0, 7, 0x03, 0x03, 0x13, 0x00, 0x13, 0x13, 0x03, + /* RLE: 007 Pixels @ 100,269*/ 7, 0x00, + /* ABS: 009 Pixels @ 107,269*/ 0, 9, 0x03, 0x0E, 0x08, 0x0F, 0x06, 0x0C, 0x0F, 0x04, 0x03, + /* RLE: 012 Pixels @ 116,269*/ 12, 0x00, + /* RLE: 003 Pixels @ 128,269*/ 3, 0x04, + /* RLE: 012 Pixels @ 131,269*/ 12, 0x03, + /* ABS: 002 Pixels @ 143,269*/ 0, 2, 0x04, 0x04, + /* RLE: 096 Pixels @ 145,269*/ 96, 0x00, + /* ABS: 017 Pixels @ 241,269*/ 0, 17, 0x03, 0x04, 0x08, 0x0B, 0x03, 0x03, 0x03, 0x11, 0x0F, 0x03, 0x0E, 0x08, 0x00, 0x03, 0x0E, 0x08, 0x0F, + /* RLE: 005 Pixels @ 258,269*/ 5, 0x03, + /* RLE: 059 Pixels @ 263,269*/ 59, 0x00, + /* RLE: 007 Pixels @ 322,269*/ 7, 0x03, + /* RLE: 001 Pixels @ 329,269*/ 1, 0x04, + /* RLE: 070 Pixels @ 330,269*/ 70, 0x00, + /* RLE: 056 Pixels @ 000,270*/ 56, 0x02, + /* RLE: 001 Pixels @ 056,270*/ 1, 0x04, + /* RLE: 006 Pixels @ 057,270*/ 6, 0x03, + /* RLE: 001 Pixels @ 063,270*/ 1, 0x04, + /* RLE: 029 Pixels @ 064,270*/ 29, 0x00, + /* ABS: 007 Pixels @ 093,270*/ 0, 7, 0x03, 0x13, 0x0B, 0x13, 0x13, 0x03, 0x03, + /* RLE: 007 Pixels @ 100,270*/ 7, 0x00, + /* ABS: 011 Pixels @ 107,270*/ 0, 11, 0x03, 0x0E, 0x06, 0x03, 0x03, 0x03, 0x00, 0x0C, 0x03, 0x09, 0x0C, + /* RLE: 008 Pixels @ 118,270*/ 8, 0x00, + /* ABS: 002 Pixels @ 126,270*/ 0, 2, 0x04, 0x04, + /* RLE: 014 Pixels @ 128,270*/ 14, 0x03, + /* ABS: 002 Pixels @ 142,270*/ 0, 2, 0x04, 0x04, + /* RLE: 094 Pixels @ 144,270*/ 94, 0x00, + /* ABS: 021 Pixels @ 238,270*/ 0, 21, 0x04, 0x04, 0x03, 0x03, 0x0C, 0x08, 0x00, 0x03, 0x03, 0x03, 0x0C, 0x08, 0x00, 0x00, 0x08, 0x0C, 0x00, 0x03, 0x0B, 0x00, 0x03, + /* RLE: 004 Pixels @ 259,270*/ 4, 0x09, + /* RLE: 001 Pixels @ 263,270*/ 1, 0x0C, + /* RLE: 058 Pixels @ 264,270*/ 58, 0x00, + /* RLE: 001 Pixels @ 322,270*/ 1, 0x04, + /* RLE: 006 Pixels @ 323,270*/ 6, 0x03, + /* RLE: 001 Pixels @ 329,270*/ 1, 0x04, + /* RLE: 070 Pixels @ 330,270*/ 70, 0x00, + /* RLE: 056 Pixels @ 000,271*/ 56, 0x02, + /* RLE: 001 Pixels @ 056,271*/ 1, 0x04, + /* RLE: 006 Pixels @ 057,271*/ 6, 0x03, + /* RLE: 001 Pixels @ 063,271*/ 1, 0x04, + /* RLE: 029 Pixels @ 064,271*/ 29, 0x00, + /* ABS: 006 Pixels @ 093,271*/ 0, 6, 0x03, 0x13, 0x00, 0x13, 0x13, 0x03, + /* RLE: 008 Pixels @ 099,271*/ 8, 0x00, + /* ABS: 011 Pixels @ 107,271*/ 0, 11, 0x03, 0x00, 0x0B, 0x0E, 0x0D, 0x08, 0x08, 0x08, 0x03, 0x1B, 0x0C, + /* RLE: 005 Pixels @ 118,271*/ 5, 0x00, + /* RLE: 003 Pixels @ 123,271*/ 3, 0x04, + /* RLE: 015 Pixels @ 126,271*/ 15, 0x03, + /* ABS: 002 Pixels @ 141,271*/ 0, 2, 0x04, 0x04, + /* RLE: 093 Pixels @ 143,271*/ 93, 0x00, + /* ABS: 002 Pixels @ 236,271*/ 0, 2, 0x04, 0x04, + /* RLE: 004 Pixels @ 238,271*/ 4, 0x03, + /* ABS: 021 Pixels @ 242,271*/ 0, 21, 0x04, 0x08, 0x04, 0x03, 0x03, 0x03, 0x00, 0x08, 0x00, 0x03, 0x0E, 0x08, 0x0F, 0x03, 0x18, 0x18, 0x1B, 0x09, 0x09, 0x09, 0x0C, + /* RLE: 059 Pixels @ 263,271*/ 59, 0x00, + /* RLE: 001 Pixels @ 322,271*/ 1, 0x04, + /* RLE: 007 Pixels @ 323,271*/ 7, 0x03, + /* RLE: 070 Pixels @ 330,271*/ 70, 0x00, + /* RLE: 057 Pixels @ 000,272*/ 57, 0x02, + /* RLE: 007 Pixels @ 057,272*/ 7, 0x03, + /* RLE: 001 Pixels @ 064,272*/ 1, 0x04, + /* RLE: 027 Pixels @ 065,272*/ 27, 0x00, + /* ABS: 011 Pixels @ 092,272*/ 0, 11, 0x03, 0x13, 0x00, 0x13, 0x13, 0x03, 0x03, 0x00, 0x0B, 0x00, 0x00, + /* RLE: 007 Pixels @ 103,272*/ 7, 0x03, + /* ABS: 013 Pixels @ 110,272*/ 0, 13, 0x08, 0x06, 0x0E, 0x0E, 0x11, 0x00, 0x18, 0x0C, 0x00, 0x00, 0x00, 0x04, 0x04, + /* RLE: 016 Pixels @ 123,272*/ 16, 0x03, + /* ABS: 002 Pixels @ 139,272*/ 0, 2, 0x04, 0x04, + /* RLE: 092 Pixels @ 141,272*/ 92, 0x00, + /* ABS: 002 Pixels @ 233,272*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 235,272*/ 8, 0x03, + /* ABS: 013 Pixels @ 243,272*/ 0, 13, 0x0F, 0x11, 0x03, 0x03, 0x03, 0x12, 0x08, 0x03, 0x03, 0x03, 0x0B, 0x00, 0x03, + /* RLE: 006 Pixels @ 256,272*/ 6, 0x09, + /* RLE: 001 Pixels @ 262,272*/ 1, 0x0C, + /* RLE: 060 Pixels @ 263,272*/ 60, 0x00, + /* RLE: 001 Pixels @ 323,272*/ 1, 0x04, + /* RLE: 006 Pixels @ 324,272*/ 6, 0x03, + /* RLE: 001 Pixels @ 330,272*/ 1, 0x04, + /* RLE: 069 Pixels @ 331,272*/ 69, 0x00, + /* RLE: 057 Pixels @ 000,273*/ 57, 0x02, + /* RLE: 001 Pixels @ 057,273*/ 1, 0x04, + /* RLE: 006 Pixels @ 058,273*/ 6, 0x03, + /* RLE: 001 Pixels @ 064,273*/ 1, 0x04, + /* RLE: 026 Pixels @ 065,273*/ 26, 0x00, + /* ABS: 007 Pixels @ 091,273*/ 0, 7, 0x03, 0x03, 0x13, 0x00, 0x13, 0x13, 0x03, + /* RLE: 004 Pixels @ 098,273*/ 4, 0x00, + /* ABS: 002 Pixels @ 102,273*/ 0, 2, 0x03, 0x03, + /* RLE: 005 Pixels @ 104,273*/ 5, 0x13, + /* RLE: 005 Pixels @ 109,273*/ 5, 0x03, + /* ABS: 007 Pixels @ 114,273*/ 0, 7, 0x06, 0x0C, 0x03, 0x0C, 0x00, 0x04, 0x04, + /* RLE: 015 Pixels @ 121,273*/ 15, 0x03, + /* RLE: 003 Pixels @ 136,273*/ 3, 0x04, + /* RLE: 092 Pixels @ 139,273*/ 92, 0x00, + /* ABS: 002 Pixels @ 231,273*/ 0, 2, 0x04, 0x04, + /* RLE: 010 Pixels @ 233,273*/ 10, 0x03, + /* ABS: 013 Pixels @ 243,273*/ 0, 13, 0x0B, 0x08, 0x11, 0x0E, 0x06, 0x08, 0x04, 0x03, 0x00, 0x00, 0x00, 0x18, 0x1B, + /* RLE: 006 Pixels @ 256,273*/ 6, 0x09, + /* RLE: 001 Pixels @ 262,273*/ 1, 0x0C, + /* RLE: 060 Pixels @ 263,273*/ 60, 0x00, + /* RLE: 001 Pixels @ 323,273*/ 1, 0x04, + /* RLE: 006 Pixels @ 324,273*/ 6, 0x03, + /* RLE: 001 Pixels @ 330,273*/ 1, 0x04, + /* RLE: 069 Pixels @ 331,273*/ 69, 0x00, + /* RLE: 057 Pixels @ 000,274*/ 57, 0x02, + /* RLE: 001 Pixels @ 057,274*/ 1, 0x04, + /* RLE: 006 Pixels @ 058,274*/ 6, 0x03, + /* RLE: 001 Pixels @ 064,274*/ 1, 0x04, + /* RLE: 026 Pixels @ 065,274*/ 26, 0x00, + /* ABS: 011 Pixels @ 091,274*/ 0, 11, 0x03, 0x13, 0x00, 0x13, 0x13, 0x03, 0x03, 0x00, 0x00, 0x0B, 0x03, + /* RLE: 009 Pixels @ 102,274*/ 9, 0x13, + /* ABS: 008 Pixels @ 111,274*/ 0, 8, 0x03, 0x1B, 0x03, 0x00, 0x00, 0x18, 0x0C, 0x04, + /* RLE: 015 Pixels @ 119,274*/ 15, 0x03, + /* ABS: 002 Pixels @ 134,274*/ 0, 2, 0x04, 0x04, + /* RLE: 092 Pixels @ 136,274*/ 92, 0x00, + /* ABS: 002 Pixels @ 228,274*/ 0, 2, 0x04, 0x04, + /* RLE: 014 Pixels @ 230,274*/ 14, 0x03, + /* ABS: 006 Pixels @ 244,274*/ 0, 6, 0x0B, 0x12, 0x06, 0x12, 0x0B, 0x03, + /* RLE: 004 Pixels @ 250,274*/ 4, 0x00, + /* RLE: 001 Pixels @ 254,274*/ 1, 0x0C, + /* RLE: 006 Pixels @ 255,274*/ 6, 0x09, + /* ABS: 003 Pixels @ 261,274*/ 0, 3, 0x03, 0x03, 0x04, + /* RLE: 060 Pixels @ 264,274*/ 60, 0x00, + /* RLE: 007 Pixels @ 324,274*/ 7, 0x03, + /* RLE: 001 Pixels @ 331,274*/ 1, 0x04, + /* RLE: 068 Pixels @ 332,274*/ 68, 0x00, + /* RLE: 057 Pixels @ 000,275*/ 57, 0x02, + /* RLE: 001 Pixels @ 057,275*/ 1, 0x04, + /* RLE: 006 Pixels @ 058,275*/ 6, 0x03, + /* RLE: 001 Pixels @ 064,275*/ 1, 0x04, + /* RLE: 025 Pixels @ 065,275*/ 25, 0x00, + /* ABS: 011 Pixels @ 090,275*/ 0, 11, 0x03, 0x03, 0x13, 0x00, 0x13, 0x13, 0x03, 0x00, 0x00, 0x00, 0x03, + /* RLE: 011 Pixels @ 101,275*/ 11, 0x13, + /* RLE: 001 Pixels @ 112,275*/ 1, 0x03, + /* RLE: 004 Pixels @ 113,275*/ 4, 0x1B, + /* RLE: 001 Pixels @ 117,275*/ 1, 0x09, + /* RLE: 014 Pixels @ 118,275*/ 14, 0x03, + /* ABS: 002 Pixels @ 132,275*/ 0, 2, 0x04, 0x04, + /* RLE: 092 Pixels @ 134,275*/ 92, 0x00, + /* ABS: 002 Pixels @ 226,275*/ 0, 2, 0x04, 0x04, + /* RLE: 021 Pixels @ 228,275*/ 21, 0x03, + /* RLE: 007 Pixels @ 249,275*/ 7, 0x00, + /* RLE: 001 Pixels @ 256,275*/ 1, 0x0C, + /* RLE: 006 Pixels @ 257,275*/ 6, 0x03, + /* RLE: 001 Pixels @ 263,275*/ 1, 0x04, + /* RLE: 060 Pixels @ 264,275*/ 60, 0x00, + /* RLE: 001 Pixels @ 324,275*/ 1, 0x04, + /* RLE: 006 Pixels @ 325,275*/ 6, 0x03, + /* RLE: 001 Pixels @ 331,275*/ 1, 0x04, + /* RLE: 068 Pixels @ 332,275*/ 68, 0x00, + /* RLE: 057 Pixels @ 000,276*/ 57, 0x02, + /* RLE: 001 Pixels @ 057,276*/ 1, 0x04, + /* RLE: 006 Pixels @ 058,276*/ 6, 0x03, + /* RLE: 001 Pixels @ 064,276*/ 1, 0x04, + /* RLE: 024 Pixels @ 065,276*/ 24, 0x00, + /* ABS: 012 Pixels @ 089,276*/ 0, 12, 0x0B, 0x03, 0x13, 0x00, 0x13, 0x13, 0x03, 0x03, 0x00, 0x00, 0x00, 0x03, + /* RLE: 011 Pixels @ 101,276*/ 11, 0x13, + /* RLE: 001 Pixels @ 112,276*/ 1, 0x03, + /* RLE: 005 Pixels @ 113,276*/ 5, 0x09, + /* RLE: 011 Pixels @ 118,276*/ 11, 0x03, + /* RLE: 003 Pixels @ 129,276*/ 3, 0x04, + /* RLE: 091 Pixels @ 132,276*/ 91, 0x00, + /* ABS: 002 Pixels @ 223,276*/ 0, 2, 0x04, 0x04, + /* RLE: 016 Pixels @ 225,276*/ 16, 0x03, + /* ABS: 002 Pixels @ 241,276*/ 0, 2, 0x04, 0x04, + /* RLE: 013 Pixels @ 243,276*/ 13, 0x00, + /* RLE: 001 Pixels @ 256,276*/ 1, 0x04, + /* RLE: 007 Pixels @ 257,276*/ 7, 0x03, + /* RLE: 060 Pixels @ 264,276*/ 60, 0x00, + /* RLE: 001 Pixels @ 324,276*/ 1, 0x04, + /* RLE: 007 Pixels @ 325,276*/ 7, 0x03, + /* RLE: 068 Pixels @ 332,276*/ 68, 0x00, + /* RLE: 057 Pixels @ 000,277*/ 57, 0x02, + /* RLE: 001 Pixels @ 057,277*/ 1, 0x04, + /* RLE: 006 Pixels @ 058,277*/ 6, 0x03, + /* RLE: 001 Pixels @ 064,277*/ 1, 0x04, + /* RLE: 024 Pixels @ 065,277*/ 24, 0x00, + /* ABS: 007 Pixels @ 089,277*/ 0, 7, 0x03, 0x03, 0x13, 0x00, 0x13, 0x13, 0x03, + /* RLE: 004 Pixels @ 096,277*/ 4, 0x00, + /* RLE: 001 Pixels @ 100,277*/ 1, 0x03, + /* RLE: 011 Pixels @ 101,277*/ 11, 0x13, + /* RLE: 001 Pixels @ 112,277*/ 1, 0x03, + /* RLE: 005 Pixels @ 113,277*/ 5, 0x09, + /* RLE: 009 Pixels @ 118,277*/ 9, 0x03, + /* ABS: 002 Pixels @ 127,277*/ 0, 2, 0x04, 0x04, + /* RLE: 092 Pixels @ 129,277*/ 92, 0x00, + /* ABS: 002 Pixels @ 221,277*/ 0, 2, 0x04, 0x04, + /* RLE: 016 Pixels @ 223,277*/ 16, 0x03, + /* ABS: 002 Pixels @ 239,277*/ 0, 2, 0x04, 0x04, + /* RLE: 016 Pixels @ 241,277*/ 16, 0x00, + /* RLE: 001 Pixels @ 257,277*/ 1, 0x04, + /* RLE: 006 Pixels @ 258,277*/ 6, 0x03, + /* RLE: 001 Pixels @ 264,277*/ 1, 0x04, + /* RLE: 060 Pixels @ 265,277*/ 60, 0x00, + /* RLE: 001 Pixels @ 325,277*/ 1, 0x04, + /* RLE: 006 Pixels @ 326,277*/ 6, 0x03, + /* RLE: 001 Pixels @ 332,277*/ 1, 0x04, + /* RLE: 067 Pixels @ 333,277*/ 67, 0x00, + /* RLE: 058 Pixels @ 000,278*/ 58, 0x02, + /* RLE: 007 Pixels @ 058,278*/ 7, 0x03, + /* RLE: 001 Pixels @ 065,278*/ 1, 0x04, + /* RLE: 023 Pixels @ 066,278*/ 23, 0x00, + /* ABS: 007 Pixels @ 089,278*/ 0, 7, 0x03, 0x13, 0x0B, 0x13, 0x13, 0x03, 0x03, + /* RLE: 004 Pixels @ 096,278*/ 4, 0x00, + /* RLE: 001 Pixels @ 100,278*/ 1, 0x03, + /* RLE: 011 Pixels @ 101,278*/ 11, 0x13, + /* RLE: 001 Pixels @ 112,278*/ 1, 0x03, + /* RLE: 005 Pixels @ 113,278*/ 5, 0x09, + /* RLE: 006 Pixels @ 118,278*/ 6, 0x03, + /* RLE: 003 Pixels @ 124,278*/ 3, 0x04, + /* RLE: 091 Pixels @ 127,278*/ 91, 0x00, + /* ABS: 002 Pixels @ 218,278*/ 0, 2, 0x04, 0x04, + /* RLE: 016 Pixels @ 220,278*/ 16, 0x03, + /* ABS: 002 Pixels @ 236,278*/ 0, 2, 0x04, 0x04, + /* RLE: 019 Pixels @ 238,278*/ 19, 0x00, + /* RLE: 001 Pixels @ 257,278*/ 1, 0x04, + /* RLE: 006 Pixels @ 258,278*/ 6, 0x03, + /* RLE: 001 Pixels @ 264,278*/ 1, 0x04, + /* RLE: 060 Pixels @ 265,278*/ 60, 0x00, + /* RLE: 001 Pixels @ 325,278*/ 1, 0x04, + /* RLE: 006 Pixels @ 326,278*/ 6, 0x03, + /* RLE: 001 Pixels @ 332,278*/ 1, 0x04, + /* RLE: 067 Pixels @ 333,278*/ 67, 0x00, + /* RLE: 058 Pixels @ 000,279*/ 58, 0x02, + /* RLE: 001 Pixels @ 058,279*/ 1, 0x04, + /* RLE: 006 Pixels @ 059,279*/ 6, 0x03, + /* RLE: 001 Pixels @ 065,279*/ 1, 0x04, + /* RLE: 022 Pixels @ 066,279*/ 22, 0x00, + /* ABS: 012 Pixels @ 088,279*/ 0, 12, 0x03, 0x03, 0x13, 0x00, 0x13, 0x13, 0x03, 0x00, 0x04, 0x04, 0x03, 0x03, + /* RLE: 011 Pixels @ 100,279*/ 11, 0x13, + /* ABS: 002 Pixels @ 111,279*/ 0, 2, 0x03, 0x03, + /* RLE: 005 Pixels @ 113,279*/ 5, 0x09, + /* RLE: 004 Pixels @ 118,279*/ 4, 0x03, + /* RLE: 003 Pixels @ 122,279*/ 3, 0x04, + /* RLE: 090 Pixels @ 125,279*/ 90, 0x00, + /* RLE: 003 Pixels @ 215,279*/ 3, 0x04, + /* RLE: 016 Pixels @ 218,279*/ 16, 0x03, + /* ABS: 002 Pixels @ 234,279*/ 0, 2, 0x04, 0x04, + /* RLE: 021 Pixels @ 236,279*/ 21, 0x00, + /* RLE: 001 Pixels @ 257,279*/ 1, 0x04, + /* RLE: 007 Pixels @ 258,279*/ 7, 0x03, + /* RLE: 061 Pixels @ 265,279*/ 61, 0x00, + /* RLE: 007 Pixels @ 326,279*/ 7, 0x03, + /* RLE: 001 Pixels @ 333,279*/ 1, 0x04, + /* RLE: 066 Pixels @ 334,279*/ 66, 0x00, + /* RLE: 058 Pixels @ 000,280*/ 58, 0x02, + /* RLE: 001 Pixels @ 058,280*/ 1, 0x04, + /* RLE: 006 Pixels @ 059,280*/ 6, 0x03, + /* RLE: 001 Pixels @ 065,280*/ 1, 0x04, + /* RLE: 021 Pixels @ 066,280*/ 21, 0x00, + /* ABS: 013 Pixels @ 087,280*/ 0, 13, 0x03, 0x03, 0x13, 0x00, 0x13, 0x13, 0x03, 0x04, 0x03, 0x03, 0x03, 0x13, 0x13, + /* RLE: 004 Pixels @ 100,280*/ 4, 0x03, + /* RLE: 005 Pixels @ 104,280*/ 5, 0x13, + /* RLE: 003 Pixels @ 109,280*/ 3, 0x03, + /* RLE: 007 Pixels @ 112,280*/ 7, 0x09, + /* ABS: 003 Pixels @ 119,280*/ 0, 3, 0x03, 0x04, 0x04, + /* RLE: 090 Pixels @ 122,280*/ 90, 0x00, + /* RLE: 003 Pixels @ 212,280*/ 3, 0x04, + /* RLE: 016 Pixels @ 215,280*/ 16, 0x03, + /* ABS: 002 Pixels @ 231,280*/ 0, 2, 0x04, 0x04, + /* RLE: 025 Pixels @ 233,280*/ 25, 0x00, + /* RLE: 001 Pixels @ 258,280*/ 1, 0x04, + /* RLE: 006 Pixels @ 259,280*/ 6, 0x03, + /* RLE: 001 Pixels @ 265,280*/ 1, 0x04, + /* RLE: 060 Pixels @ 266,280*/ 60, 0x00, + /* RLE: 001 Pixels @ 326,280*/ 1, 0x04, + /* RLE: 006 Pixels @ 327,280*/ 6, 0x03, + /* RLE: 001 Pixels @ 333,280*/ 1, 0x04, + /* RLE: 066 Pixels @ 334,280*/ 66, 0x00, + /* RLE: 058 Pixels @ 000,281*/ 58, 0x02, + /* RLE: 001 Pixels @ 058,281*/ 1, 0x04, + /* RLE: 006 Pixels @ 059,281*/ 6, 0x03, + /* RLE: 001 Pixels @ 065,281*/ 1, 0x04, + /* RLE: 021 Pixels @ 066,281*/ 21, 0x00, + /* ABS: 011 Pixels @ 087,281*/ 0, 11, 0x03, 0x03, 0x13, 0x04, 0x13, 0x13, 0x03, 0x03, 0x03, 0x13, 0x13, + /* RLE: 013 Pixels @ 098,281*/ 13, 0x03, + /* RLE: 008 Pixels @ 111,281*/ 8, 0x09, + /* RLE: 001 Pixels @ 119,281*/ 1, 0x0C, + /* RLE: 091 Pixels @ 120,281*/ 91, 0x00, + /* ABS: 002 Pixels @ 211,281*/ 0, 2, 0x04, 0x04, + /* RLE: 016 Pixels @ 213,281*/ 16, 0x03, + /* ABS: 002 Pixels @ 229,281*/ 0, 2, 0x04, 0x04, + /* RLE: 027 Pixels @ 231,281*/ 27, 0x00, + /* RLE: 001 Pixels @ 258,281*/ 1, 0x04, + /* RLE: 006 Pixels @ 259,281*/ 6, 0x03, + /* RLE: 001 Pixels @ 265,281*/ 1, 0x04, + /* RLE: 060 Pixels @ 266,281*/ 60, 0x00, + /* RLE: 001 Pixels @ 326,281*/ 1, 0x04, + /* RLE: 007 Pixels @ 327,281*/ 7, 0x03, + /* RLE: 066 Pixels @ 334,281*/ 66, 0x00, + /* RLE: 058 Pixels @ 000,282*/ 58, 0x02, + /* RLE: 001 Pixels @ 058,282*/ 1, 0x04, + /* RLE: 006 Pixels @ 059,282*/ 6, 0x03, + /* RLE: 001 Pixels @ 065,282*/ 1, 0x04, + /* RLE: 016 Pixels @ 066,282*/ 16, 0x00, + /* RLE: 004 Pixels @ 082,282*/ 4, 0x04, + /* ABS: 010 Pixels @ 086,282*/ 0, 10, 0x03, 0x03, 0x13, 0x03, 0x13, 0x13, 0x13, 0x03, 0x13, 0x13, + /* RLE: 015 Pixels @ 096,282*/ 15, 0x03, + /* RLE: 008 Pixels @ 111,282*/ 8, 0x09, + /* RLE: 001 Pixels @ 119,282*/ 1, 0x0C, + /* RLE: 090 Pixels @ 120,282*/ 90, 0x00, + /* ABS: 002 Pixels @ 210,282*/ 0, 2, 0x04, 0x04, + /* RLE: 014 Pixels @ 212,282*/ 14, 0x03, + /* ABS: 002 Pixels @ 226,282*/ 0, 2, 0x04, 0x04, + /* RLE: 031 Pixels @ 228,282*/ 31, 0x00, + /* RLE: 007 Pixels @ 259,282*/ 7, 0x03, + /* RLE: 001 Pixels @ 266,282*/ 1, 0x04, + /* RLE: 060 Pixels @ 267,282*/ 60, 0x00, + /* RLE: 001 Pixels @ 327,282*/ 1, 0x04, + /* RLE: 006 Pixels @ 328,282*/ 6, 0x03, + /* RLE: 001 Pixels @ 334,282*/ 1, 0x04, + /* RLE: 065 Pixels @ 335,282*/ 65, 0x00, + /* RLE: 058 Pixels @ 000,283*/ 58, 0x02, + /* RLE: 001 Pixels @ 058,283*/ 1, 0x04, + /* RLE: 006 Pixels @ 059,283*/ 6, 0x03, + /* RLE: 001 Pixels @ 065,283*/ 1, 0x04, + /* RLE: 011 Pixels @ 066,283*/ 11, 0x00, + /* RLE: 005 Pixels @ 077,283*/ 5, 0x04, + /* RLE: 006 Pixels @ 082,283*/ 6, 0x03, + /* ABS: 002 Pixels @ 088,283*/ 0, 2, 0x13, 0x03, + /* RLE: 004 Pixels @ 090,283*/ 4, 0x13, + /* RLE: 016 Pixels @ 094,283*/ 16, 0x03, + /* RLE: 001 Pixels @ 110,283*/ 1, 0x0C, + /* RLE: 008 Pixels @ 111,283*/ 8, 0x09, + /* RLE: 001 Pixels @ 119,283*/ 1, 0x0C, + /* RLE: 089 Pixels @ 120,283*/ 89, 0x00, + /* ABS: 002 Pixels @ 209,283*/ 0, 2, 0x04, 0x04, + /* RLE: 013 Pixels @ 211,283*/ 13, 0x03, + /* ABS: 002 Pixels @ 224,283*/ 0, 2, 0x04, 0x04, + /* RLE: 033 Pixels @ 226,283*/ 33, 0x00, + /* RLE: 001 Pixels @ 259,283*/ 1, 0x04, + /* RLE: 006 Pixels @ 260,283*/ 6, 0x03, + /* RLE: 001 Pixels @ 266,283*/ 1, 0x04, + /* RLE: 060 Pixels @ 267,283*/ 60, 0x00, + /* RLE: 001 Pixels @ 327,283*/ 1, 0x04, + /* RLE: 006 Pixels @ 328,283*/ 6, 0x03, + /* RLE: 001 Pixels @ 334,283*/ 1, 0x04, + /* RLE: 065 Pixels @ 335,283*/ 65, 0x00, + /* RLE: 059 Pixels @ 000,284*/ 59, 0x02, + /* RLE: 007 Pixels @ 059,284*/ 7, 0x03, + /* RLE: 001 Pixels @ 066,284*/ 1, 0x04, + /* RLE: 006 Pixels @ 067,284*/ 6, 0x00, + /* RLE: 004 Pixels @ 073,284*/ 4, 0x04, + /* RLE: 011 Pixels @ 077,284*/ 11, 0x03, + /* RLE: 004 Pixels @ 088,284*/ 4, 0x13, + /* RLE: 014 Pixels @ 092,284*/ 14, 0x03, + /* RLE: 004 Pixels @ 106,284*/ 4, 0x04, + /* ABS: 002 Pixels @ 110,284*/ 0, 2, 0x00, 0x0C, + /* RLE: 008 Pixels @ 112,284*/ 8, 0x09, + /* RLE: 001 Pixels @ 120,284*/ 1, 0x0C, + /* RLE: 087 Pixels @ 121,284*/ 87, 0x00, + /* ABS: 002 Pixels @ 208,284*/ 0, 2, 0x04, 0x04, + /* RLE: 011 Pixels @ 210,284*/ 11, 0x03, + /* ABS: 002 Pixels @ 221,284*/ 0, 2, 0x04, 0x04, + /* RLE: 036 Pixels @ 223,284*/ 36, 0x00, + /* RLE: 001 Pixels @ 259,284*/ 1, 0x04, + /* RLE: 007 Pixels @ 260,284*/ 7, 0x03, + /* RLE: 061 Pixels @ 267,284*/ 61, 0x00, + /* RLE: 007 Pixels @ 328,284*/ 7, 0x03, + /* RLE: 001 Pixels @ 335,284*/ 1, 0x04, + /* RLE: 064 Pixels @ 336,284*/ 64, 0x00, + /* RLE: 059 Pixels @ 000,285*/ 59, 0x02, + /* RLE: 001 Pixels @ 059,285*/ 1, 0x04, + /* RLE: 006 Pixels @ 060,285*/ 6, 0x03, + /* ABS: 002 Pixels @ 066,285*/ 0, 2, 0x04, 0x00, + /* RLE: 004 Pixels @ 068,285*/ 4, 0x04, + /* RLE: 029 Pixels @ 072,285*/ 29, 0x03, + /* RLE: 004 Pixels @ 101,285*/ 4, 0x04, + /* RLE: 006 Pixels @ 105,285*/ 6, 0x00, + /* RLE: 001 Pixels @ 111,285*/ 1, 0x0C, + /* RLE: 008 Pixels @ 112,285*/ 8, 0x09, + /* RLE: 001 Pixels @ 120,285*/ 1, 0x0C, + /* RLE: 086 Pixels @ 121,285*/ 86, 0x00, + /* ABS: 002 Pixels @ 207,285*/ 0, 2, 0x04, 0x04, + /* RLE: 010 Pixels @ 209,285*/ 10, 0x03, + /* ABS: 002 Pixels @ 219,285*/ 0, 2, 0x04, 0x04, + /* RLE: 039 Pixels @ 221,285*/ 39, 0x00, + /* RLE: 001 Pixels @ 260,285*/ 1, 0x04, + /* RLE: 006 Pixels @ 261,285*/ 6, 0x03, + /* RLE: 001 Pixels @ 267,285*/ 1, 0x04, + /* RLE: 060 Pixels @ 268,285*/ 60, 0x00, + /* RLE: 001 Pixels @ 328,285*/ 1, 0x04, + /* RLE: 006 Pixels @ 329,285*/ 6, 0x03, + /* RLE: 065 Pixels @ 335,285*/ 65, 0x00, + /* RLE: 057 Pixels @ 000,286*/ 57, 0x02, + /* RLE: 001 Pixels @ 057,286*/ 1, 0x18, + /* RLE: 008 Pixels @ 058,286*/ 8, 0x03, + /* ABS: 002 Pixels @ 066,286*/ 0, 2, 0x04, 0x04, + /* RLE: 028 Pixels @ 068,286*/ 28, 0x03, + /* RLE: 005 Pixels @ 096,286*/ 5, 0x04, + /* RLE: 010 Pixels @ 101,286*/ 10, 0x00, + /* RLE: 001 Pixels @ 111,286*/ 1, 0x0C, + /* RLE: 008 Pixels @ 112,286*/ 8, 0x09, + /* RLE: 001 Pixels @ 120,286*/ 1, 0x0C, + /* RLE: 085 Pixels @ 121,286*/ 85, 0x00, + /* ABS: 002 Pixels @ 206,286*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 208,286*/ 8, 0x03, + /* ABS: 002 Pixels @ 216,286*/ 0, 2, 0x04, 0x04, + /* RLE: 042 Pixels @ 218,286*/ 42, 0x00, + /* RLE: 001 Pixels @ 260,286*/ 1, 0x04, + /* RLE: 006 Pixels @ 261,286*/ 6, 0x03, + /* RLE: 001 Pixels @ 267,286*/ 1, 0x04, + /* RLE: 060 Pixels @ 268,286*/ 60, 0x00, + /* RLE: 001 Pixels @ 328,286*/ 1, 0x04, + /* RLE: 004 Pixels @ 329,286*/ 4, 0x03, + /* RLE: 003 Pixels @ 333,286*/ 3, 0x00, + /* ABS: 002 Pixels @ 336,286*/ 0, 2, 0x03, 0x03, + /* RLE: 062 Pixels @ 338,286*/ 62, 0x00, + /* RLE: 034 Pixels @ 000,287*/ 34, 0x02, + /* ABS: 002 Pixels @ 034,287*/ 0, 2, 0x00, 0x00, + /* RLE: 006 Pixels @ 036,287*/ 6, 0x03, + /* ABS: 019 Pixels @ 042,287*/ 0, 19, 0x00, 0x18, 0x00, 0x03, 0x00, 0x18, 0x02, 0x02, 0x00, 0x00, 0x00, 0x18, 0x02, 0x03, 0x03, 0x03, 0x00, 0x0C, 0x00, + /* RLE: 031 Pixels @ 061,287*/ 31, 0x03, + /* RLE: 004 Pixels @ 092,287*/ 4, 0x04, + /* RLE: 015 Pixels @ 096,287*/ 15, 0x00, + /* RLE: 001 Pixels @ 111,287*/ 1, 0x0C, + /* RLE: 008 Pixels @ 112,287*/ 8, 0x09, + /* RLE: 001 Pixels @ 120,287*/ 1, 0x0C, + /* RLE: 084 Pixels @ 121,287*/ 84, 0x00, + /* ABS: 002 Pixels @ 205,287*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 207,287*/ 8, 0x03, + /* ABS: 002 Pixels @ 215,287*/ 0, 2, 0x04, 0x04, + /* RLE: 043 Pixels @ 217,287*/ 43, 0x00, + /* RLE: 001 Pixels @ 260,287*/ 1, 0x04, + /* RLE: 007 Pixels @ 261,287*/ 7, 0x03, + /* RLE: 062 Pixels @ 268,287*/ 62, 0x00, + /* ABS: 008 Pixels @ 330,287*/ 0, 8, 0x03, 0x0B, 0x11, 0x08, 0x08, 0x08, 0x06, 0x03, + /* RLE: 062 Pixels @ 338,287*/ 62, 0x00, + /* RLE: 034 Pixels @ 000,288*/ 34, 0x02, + /* ABS: 013 Pixels @ 034,288*/ 0, 13, 0x03, 0x04, 0x00, 0x0E, 0x04, 0x00, 0x08, 0x00, 0x03, 0x03, 0x00, 0x0B, 0x00, + /* RLE: 004 Pixels @ 047,288*/ 4, 0x03, + /* ABS: 011 Pixels @ 051,288*/ 0, 11, 0x0B, 0x00, 0x03, 0x00, 0x03, 0x11, 0x06, 0x0F, 0x0F, 0x08, 0x00, + /* RLE: 025 Pixels @ 062,288*/ 25, 0x03, + /* RLE: 004 Pixels @ 087,288*/ 4, 0x04, + /* RLE: 020 Pixels @ 091,288*/ 20, 0x00, + /* RLE: 001 Pixels @ 111,288*/ 1, 0x0C, + /* RLE: 008 Pixels @ 112,288*/ 8, 0x09, + /* RLE: 001 Pixels @ 120,288*/ 1, 0x0C, + /* RLE: 083 Pixels @ 121,288*/ 83, 0x00, + /* ABS: 002 Pixels @ 204,288*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 206,288*/ 8, 0x03, + /* ABS: 002 Pixels @ 214,288*/ 0, 2, 0x04, 0x04, + /* RLE: 045 Pixels @ 216,288*/ 45, 0x00, + /* RLE: 001 Pixels @ 261,288*/ 1, 0x04, + /* RLE: 006 Pixels @ 262,288*/ 6, 0x03, + /* RLE: 001 Pixels @ 268,288*/ 1, 0x04, + /* RLE: 060 Pixels @ 269,288*/ 60, 0x00, + /* ABS: 010 Pixels @ 329,288*/ 0, 10, 0x03, 0x0B, 0x08, 0x11, 0x0C, 0x0B, 0x04, 0x0F, 0x0C, 0x03, + /* RLE: 061 Pixels @ 339,288*/ 61, 0x00, + /* RLE: 025 Pixels @ 000,289*/ 25, 0x02, + /* ABS: 005 Pixels @ 025,289*/ 0, 5, 0x18, 0x03, 0x03, 0x03, 0x18, + /* RLE: 004 Pixels @ 030,289*/ 4, 0x02, + /* ABS: 028 Pixels @ 034,289*/ 0, 28, 0x03, 0x08, 0x00, 0x0C, 0x04, 0x03, 0x08, 0x0C, 0x03, 0x0E, 0x08, 0x0D, 0x08, 0x0C, 0x03, 0x04, 0x08, 0x08, 0x08, 0x04, 0x03, 0x03, 0x0D, 0x0F, 0x03, 0x00, 0x08, 0x0C, + /* RLE: 021 Pixels @ 062,289*/ 21, 0x03, + /* RLE: 004 Pixels @ 083,289*/ 4, 0x04, + /* RLE: 025 Pixels @ 087,289*/ 25, 0x00, + /* RLE: 001 Pixels @ 112,289*/ 1, 0x0C, + /* RLE: 008 Pixels @ 113,289*/ 8, 0x09, + /* RLE: 001 Pixels @ 121,289*/ 1, 0x0C, + /* RLE: 082 Pixels @ 122,289*/ 82, 0x00, + /* ABS: 002 Pixels @ 204,289*/ 0, 2, 0x04, 0x04, + /* RLE: 007 Pixels @ 206,289*/ 7, 0x03, + /* ABS: 002 Pixels @ 213,289*/ 0, 2, 0x04, 0x04, + /* RLE: 046 Pixels @ 215,289*/ 46, 0x00, + /* RLE: 001 Pixels @ 261,289*/ 1, 0x04, + /* RLE: 006 Pixels @ 262,289*/ 6, 0x03, + /* RLE: 001 Pixels @ 268,289*/ 1, 0x04, + /* RLE: 060 Pixels @ 269,289*/ 60, 0x00, + /* ABS: 003 Pixels @ 329,289*/ 0, 3, 0x03, 0x06, 0x11, + /* RLE: 004 Pixels @ 332,289*/ 4, 0x03, + /* ABS: 003 Pixels @ 336,289*/ 0, 3, 0x0C, 0x0F, 0x03, + /* RLE: 061 Pixels @ 339,289*/ 61, 0x00, + /* RLE: 015 Pixels @ 000,290*/ 15, 0x02, + /* ABS: 005 Pixels @ 015,290*/ 0, 5, 0x00, 0x03, 0x03, 0x03, 0x00, + /* RLE: 005 Pixels @ 020,290*/ 5, 0x02, + /* ABS: 008 Pixels @ 025,290*/ 0, 8, 0x03, 0x0B, 0x08, 0x00, 0x03, 0x03, 0x03, 0x18, + /* RLE: 005 Pixels @ 033,290*/ 5, 0x03, + /* ABS: 024 Pixels @ 038,290*/ 0, 24, 0x0C, 0x00, 0x08, 0x0C, 0x03, 0x08, 0x0C, 0x03, 0x00, 0x03, 0x03, 0x0F, 0x0E, 0x03, 0x0C, 0x08, 0x03, 0x03, 0x06, 0x0D, 0x03, 0x03, 0x08, 0x0E, + /* RLE: 016 Pixels @ 062,290*/ 16, 0x03, + /* RLE: 004 Pixels @ 078,290*/ 4, 0x04, + /* RLE: 030 Pixels @ 082,290*/ 30, 0x00, + /* RLE: 001 Pixels @ 112,290*/ 1, 0x0C, + /* RLE: 008 Pixels @ 113,290*/ 8, 0x09, + /* RLE: 001 Pixels @ 121,290*/ 1, 0x0C, + /* RLE: 082 Pixels @ 122,290*/ 82, 0x00, + /* RLE: 001 Pixels @ 204,290*/ 1, 0x04, + /* RLE: 007 Pixels @ 205,290*/ 7, 0x03, + /* ABS: 002 Pixels @ 212,290*/ 0, 2, 0x04, 0x04, + /* RLE: 048 Pixels @ 214,290*/ 48, 0x00, + /* RLE: 007 Pixels @ 262,290*/ 7, 0x03, + /* RLE: 001 Pixels @ 269,290*/ 1, 0x04, + /* RLE: 059 Pixels @ 270,290*/ 59, 0x00, + /* ABS: 003 Pixels @ 329,290*/ 0, 3, 0x03, 0x08, 0x0C, + /* RLE: 004 Pixels @ 332,290*/ 4, 0x03, + /* ABS: 003 Pixels @ 336,290*/ 0, 3, 0x00, 0x08, 0x03, + /* RLE: 061 Pixels @ 339,290*/ 61, 0x00, + /* RLE: 003 Pixels @ 000,291*/ 3, 0x02, + /* RLE: 001 Pixels @ 003,291*/ 1, 0x00, + /* RLE: 006 Pixels @ 004,291*/ 6, 0x03, + /* RLE: 001 Pixels @ 010,291*/ 1, 0x00, + /* RLE: 004 Pixels @ 011,291*/ 4, 0x02, + /* ABS: 007 Pixels @ 015,291*/ 0, 7, 0x00, 0x00, 0x08, 0x00, 0x00, 0x02, 0x18, + /* RLE: 004 Pixels @ 022,291*/ 4, 0x03, + /* ABS: 036 Pixels @ 026,291*/ 0, 36, 0x00, 0x08, 0x0C, 0x00, 0x0C, 0x00, 0x03, 0x03, 0x11, 0x0C, 0x03, 0x0B, 0x08, 0x0B, 0x06, 0x06, 0x03, 0x0D, 0x08, 0x08, 0x08, 0x12, 0x03, 0x08, 0x11, 0x06, 0x0F, 0x0F, 0x00, 0x03, 0x0C, 0x08, 0x03, 0x03, 0x06, + 0x06, + /* RLE: 011 Pixels @ 062,291*/ 11, 0x03, + /* RLE: 004 Pixels @ 073,291*/ 4, 0x04, + /* RLE: 035 Pixels @ 077,291*/ 35, 0x00, + /* RLE: 001 Pixels @ 112,291*/ 1, 0x0C, + /* RLE: 008 Pixels @ 113,291*/ 8, 0x09, + /* RLE: 001 Pixels @ 121,291*/ 1, 0x0C, + /* RLE: 081 Pixels @ 122,291*/ 81, 0x00, + /* RLE: 001 Pixels @ 203,291*/ 1, 0x04, + /* RLE: 007 Pixels @ 204,291*/ 7, 0x03, + /* ABS: 002 Pixels @ 211,291*/ 0, 2, 0x04, 0x04, + /* RLE: 049 Pixels @ 213,291*/ 49, 0x00, + /* RLE: 001 Pixels @ 262,291*/ 1, 0x04, + /* RLE: 006 Pixels @ 263,291*/ 6, 0x03, + /* RLE: 001 Pixels @ 269,291*/ 1, 0x04, + /* RLE: 059 Pixels @ 270,291*/ 59, 0x00, + /* ABS: 003 Pixels @ 329,291*/ 0, 3, 0x03, 0x06, 0x0E, + /* RLE: 004 Pixels @ 332,291*/ 4, 0x03, + /* ABS: 003 Pixels @ 336,291*/ 0, 3, 0x12, 0x0F, 0x03, + /* RLE: 061 Pixels @ 339,291*/ 61, 0x00, + /* RLE: 004 Pixels @ 000,292*/ 4, 0x03, + /* ABS: 058 Pixels @ 004,292*/ 0, 58, 0x0C, 0x06, 0x04, 0x0B, 0x08, 0x00, 0x03, 0x02, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x00, 0x0C, 0x00, 0x03, 0x03, 0x08, 0x06, 0x0F, 0x11, 0x08, 0x00, 0x03, 0x11, 0x12, 0x03, 0x00, 0x08, + 0x0C, 0x06, 0x0D, 0x03, 0x03, 0x0B, 0x04, 0x0E, 0x08, 0x00, 0x08, 0x12, 0x00, 0x00, 0x0B, 0x00, 0x03, 0x04, 0x08, 0x00, 0x03, 0x12, 0x11, + /* RLE: 007 Pixels @ 062,292*/ 7, 0x03, + /* RLE: 004 Pixels @ 069,292*/ 4, 0x04, + /* RLE: 039 Pixels @ 073,292*/ 39, 0x00, + /* RLE: 001 Pixels @ 112,292*/ 1, 0x0C, + /* RLE: 008 Pixels @ 113,292*/ 8, 0x09, + /* RLE: 001 Pixels @ 121,292*/ 1, 0x0C, + /* RLE: 081 Pixels @ 122,292*/ 81, 0x00, + /* RLE: 001 Pixels @ 203,292*/ 1, 0x04, + /* RLE: 006 Pixels @ 204,292*/ 6, 0x03, + /* ABS: 002 Pixels @ 210,292*/ 0, 2, 0x04, 0x04, + /* RLE: 050 Pixels @ 212,292*/ 50, 0x00, + /* RLE: 001 Pixels @ 262,292*/ 1, 0x04, + /* RLE: 007 Pixels @ 263,292*/ 7, 0x03, + /* RLE: 059 Pixels @ 270,292*/ 59, 0x00, + /* ABS: 010 Pixels @ 329,292*/ 0, 10, 0x03, 0x04, 0x08, 0x0C, 0x00, 0x04, 0x06, 0x08, 0x0C, 0x03, + /* RLE: 061 Pixels @ 339,292*/ 61, 0x00, + /* ABS: 062 Pixels @ 000,293*/ 0, 62, 0x08, 0x0C, 0x03, 0x0B, 0x08, 0x0E, 0x03, 0x03, 0x08, 0x0C, 0x03, 0x03, 0x03, 0x00, 0x00, 0x03, 0x03, 0x11, 0x0E, 0x03, 0x11, 0x06, 0x0F, 0x0F, 0x08, 0x00, 0x03, 0x0D, 0x0F, 0x03, 0x00, 0x08, 0x0C, 0x03, 0x06, + 0x06, 0x03, 0x03, 0x08, 0x0E, 0x0C, 0x08, 0x03, 0x12, 0x0D, 0x0C, 0x12, 0x08, 0x00, 0x0E, 0x08, 0x0E, 0x12, 0x0F, 0x00, 0x03, 0x0B, 0x06, 0x00, 0x03, 0x00, 0x0B, + /* RLE: 005 Pixels @ 062,293*/ 5, 0x03, + /* RLE: 001 Pixels @ 067,293*/ 1, 0x04, + /* RLE: 044 Pixels @ 068,293*/ 44, 0x00, + /* RLE: 001 Pixels @ 112,293*/ 1, 0x0C, + /* RLE: 008 Pixels @ 113,293*/ 8, 0x09, + /* RLE: 001 Pixels @ 121,293*/ 1, 0x0C, + /* RLE: 081 Pixels @ 122,293*/ 81, 0x00, + /* RLE: 001 Pixels @ 203,293*/ 1, 0x04, + /* RLE: 006 Pixels @ 204,293*/ 6, 0x03, + /* RLE: 001 Pixels @ 210,293*/ 1, 0x04, + /* RLE: 052 Pixels @ 211,293*/ 52, 0x00, + /* RLE: 001 Pixels @ 263,293*/ 1, 0x04, + /* RLE: 006 Pixels @ 264,293*/ 6, 0x03, + /* RLE: 001 Pixels @ 270,293*/ 1, 0x04, + /* RLE: 059 Pixels @ 271,293*/ 59, 0x00, + /* ABS: 009 Pixels @ 330,293*/ 0, 9, 0x03, 0x0E, 0x08, 0x08, 0x08, 0x0F, 0x0C, 0x03, 0x03, + /* RLE: 061 Pixels @ 339,293*/ 61, 0x00, + /* ABS: 054 Pixels @ 000,294*/ 0, 54, 0x08, 0x0C, 0x03, 0x0F, 0x0D, 0x03, 0x00, 0x03, 0x08, 0x0C, 0x03, 0x04, 0x08, 0x08, 0x08, 0x04, 0x03, 0x06, 0x06, 0x03, 0x0D, 0x0F, 0x03, 0x00, 0x08, 0x0C, 0x03, 0x06, 0x0D, 0x03, 0x03, 0x08, 0x0E, 0x03, 0x0E, + 0x08, 0x03, 0x03, 0x08, 0x06, 0x04, 0x08, 0x00, 0x00, 0x0E, 0x06, 0x0E, 0x00, 0x03, 0x03, 0x0C, 0x06, 0x0E, 0x00, + /* RLE: 005 Pixels @ 054,294*/ 5, 0x03, + /* ABS: 002 Pixels @ 059,294*/ 0, 2, 0x00, 0x00, + /* RLE: 006 Pixels @ 061,294*/ 6, 0x03, + /* RLE: 001 Pixels @ 067,294*/ 1, 0x04, + /* RLE: 045 Pixels @ 068,294*/ 45, 0x00, + /* RLE: 001 Pixels @ 113,294*/ 1, 0x0C, + /* RLE: 008 Pixels @ 114,294*/ 8, 0x09, + /* RLE: 001 Pixels @ 122,294*/ 1, 0x0C, + /* RLE: 080 Pixels @ 123,294*/ 80, 0x00, + /* RLE: 001 Pixels @ 203,294*/ 1, 0x04, + /* RLE: 006 Pixels @ 204,294*/ 6, 0x03, + /* RLE: 001 Pixels @ 210,294*/ 1, 0x04, + /* RLE: 052 Pixels @ 211,294*/ 52, 0x00, + /* RLE: 001 Pixels @ 263,294*/ 1, 0x04, + /* RLE: 006 Pixels @ 264,294*/ 6, 0x03, + /* RLE: 001 Pixels @ 270,294*/ 1, 0x04, + /* RLE: 060 Pixels @ 271,294*/ 60, 0x00, + /* ABS: 010 Pixels @ 331,294*/ 0, 10, 0x03, 0x00, 0x0B, 0x00, 0x03, 0x0C, 0x0E, 0x0C, 0x03, 0x03, + /* RLE: 059 Pixels @ 341,294*/ 59, 0x00, + /* ABS: 043 Pixels @ 000,295*/ 0, 43, 0x08, 0x06, 0x12, 0x08, 0x04, 0x03, 0x03, 0x03, 0x06, 0x06, 0x03, 0x0F, 0x0E, 0x03, 0x0C, 0x08, 0x03, 0x12, 0x0D, 0x03, 0x06, 0x0D, 0x03, 0x03, 0x08, 0x0E, 0x03, 0x0C, 0x08, 0x03, 0x03, 0x06, 0x06, 0x03, 0x04, + 0x08, 0x12, 0x12, 0x11, 0x11, 0x0B, 0x06, 0x00, + /* RLE: 007 Pixels @ 043,295*/ 7, 0x03, + /* ABS: 006 Pixels @ 050,295*/ 0, 6, 0x00, 0x03, 0x03, 0x00, 0x00, 0x04, + /* RLE: 004 Pixels @ 056,295*/ 4, 0x02, + /* RLE: 001 Pixels @ 060,295*/ 1, 0x04, + /* RLE: 006 Pixels @ 061,295*/ 6, 0x03, + /* RLE: 001 Pixels @ 067,295*/ 1, 0x04, + /* RLE: 045 Pixels @ 068,295*/ 45, 0x00, + /* RLE: 001 Pixels @ 113,295*/ 1, 0x0C, + /* RLE: 008 Pixels @ 114,295*/ 8, 0x09, + /* RLE: 001 Pixels @ 122,295*/ 1, 0x0C, + /* RLE: 079 Pixels @ 123,295*/ 79, 0x00, + /* RLE: 001 Pixels @ 202,295*/ 1, 0x04, + /* RLE: 007 Pixels @ 203,295*/ 7, 0x03, + /* RLE: 053 Pixels @ 210,295*/ 53, 0x00, + /* RLE: 001 Pixels @ 263,295*/ 1, 0x04, + /* RLE: 007 Pixels @ 264,295*/ 7, 0x03, + /* RLE: 061 Pixels @ 271,295*/ 61, 0x00, + /* RLE: 003 Pixels @ 332,295*/ 3, 0x03, + /* ABS: 006 Pixels @ 335,295*/ 0, 6, 0x0C, 0x11, 0x08, 0x0F, 0x04, 0x03, + /* RLE: 059 Pixels @ 341,295*/ 59, 0x00, + /* ABS: 044 Pixels @ 000,296*/ 0, 44, 0x06, 0x0F, 0x08, 0x0F, 0x11, 0x03, 0x03, 0x03, 0x06, 0x0D, 0x03, 0x08, 0x11, 0x06, 0x0F, 0x0F, 0x00, 0x0C, 0x08, 0x03, 0x0C, 0x08, 0x03, 0x03, 0x06, 0x06, 0x03, 0x04, 0x08, 0x00, 0x03, 0x12, 0x11, 0x03, 0x03, + 0x0E, 0x06, 0x0C, 0x00, 0x0B, 0x03, 0x03, 0x03, 0x00, + /* RLE: 005 Pixels @ 044,296*/ 5, 0x04, + /* RLE: 012 Pixels @ 049,296*/ 12, 0x02, + /* RLE: 007 Pixels @ 061,296*/ 7, 0x03, + /* RLE: 001 Pixels @ 068,296*/ 1, 0x04, + /* RLE: 044 Pixels @ 069,296*/ 44, 0x00, + /* RLE: 001 Pixels @ 113,296*/ 1, 0x0C, + /* RLE: 008 Pixels @ 114,296*/ 8, 0x09, + /* RLE: 001 Pixels @ 122,296*/ 1, 0x0C, + /* RLE: 079 Pixels @ 123,296*/ 79, 0x00, + /* RLE: 001 Pixels @ 202,296*/ 1, 0x04, + /* RLE: 006 Pixels @ 203,296*/ 6, 0x03, + /* RLE: 001 Pixels @ 209,296*/ 1, 0x04, + /* RLE: 054 Pixels @ 210,296*/ 54, 0x00, + /* RLE: 001 Pixels @ 264,296*/ 1, 0x04, + /* RLE: 006 Pixels @ 265,296*/ 6, 0x03, + /* RLE: 001 Pixels @ 271,296*/ 1, 0x04, + /* RLE: 059 Pixels @ 272,296*/ 59, 0x00, + /* ABS: 010 Pixels @ 331,296*/ 0, 10, 0x03, 0x03, 0x0E, 0x08, 0x08, 0x06, 0x08, 0x00, 0x03, 0x03, + /* RLE: 059 Pixels @ 341,296*/ 59, 0x00, + /* ABS: 033 Pixels @ 000,297*/ 0, 33, 0x12, 0x08, 0x12, 0x00, 0x08, 0x0D, 0x03, 0x03, 0x0C, 0x08, 0x03, 0x08, 0x12, 0x0B, 0x00, 0x0B, 0x00, 0x04, 0x08, 0x00, 0x04, 0x08, 0x00, 0x03, 0x12, 0x11, 0x03, 0x0B, 0x06, 0x00, 0x03, 0x00, 0x0B, + /* RLE: 006 Pixels @ 033,297*/ 6, 0x03, + /* ABS: 003 Pixels @ 039,297*/ 0, 3, 0x00, 0x00, 0x04, + /* RLE: 019 Pixels @ 042,297*/ 19, 0x02, + /* RLE: 001 Pixels @ 061,297*/ 1, 0x04, + /* RLE: 006 Pixels @ 062,297*/ 6, 0x03, + /* RLE: 001 Pixels @ 068,297*/ 1, 0x04, + /* RLE: 044 Pixels @ 069,297*/ 44, 0x00, + /* RLE: 001 Pixels @ 113,297*/ 1, 0x0C, + /* RLE: 008 Pixels @ 114,297*/ 8, 0x09, + /* RLE: 001 Pixels @ 122,297*/ 1, 0x0C, + /* RLE: 079 Pixels @ 123,297*/ 79, 0x00, + /* RLE: 001 Pixels @ 202,297*/ 1, 0x04, + /* RLE: 006 Pixels @ 203,297*/ 6, 0x03, + /* RLE: 001 Pixels @ 209,297*/ 1, 0x04, + /* RLE: 054 Pixels @ 210,297*/ 54, 0x00, + /* RLE: 001 Pixels @ 264,297*/ 1, 0x04, + /* RLE: 006 Pixels @ 265,297*/ 6, 0x03, + /* RLE: 001 Pixels @ 271,297*/ 1, 0x04, + /* RLE: 060 Pixels @ 272,297*/ 60, 0x00, + /* ABS: 010 Pixels @ 332,297*/ 0, 10, 0x0C, 0x08, 0x0C, 0x00, 0x03, 0x0C, 0x0E, 0x0C, 0x03, 0x03, + /* RLE: 058 Pixels @ 342,297*/ 58, 0x00, + /* ABS: 026 Pixels @ 000,298*/ 0, 26, 0x0C, 0x08, 0x00, 0x03, 0x0C, 0x08, 0x12, 0x03, 0x04, 0x08, 0x00, 0x0E, 0x08, 0x0E, 0x12, 0x0F, 0x00, 0x0B, 0x06, 0x00, 0x0B, 0x06, 0x00, 0x03, 0x00, 0x0B, + /* RLE: 004 Pixels @ 026,298*/ 4, 0x03, + /* RLE: 004 Pixels @ 030,298*/ 4, 0x00, + /* RLE: 001 Pixels @ 034,298*/ 1, 0x04, + /* RLE: 026 Pixels @ 035,298*/ 26, 0x02, + /* RLE: 001 Pixels @ 061,298*/ 1, 0x04, + /* RLE: 006 Pixels @ 062,298*/ 6, 0x03, + /* RLE: 001 Pixels @ 068,298*/ 1, 0x04, + /* RLE: 044 Pixels @ 069,298*/ 44, 0x00, + /* RLE: 001 Pixels @ 113,298*/ 1, 0x0C, + /* RLE: 008 Pixels @ 114,298*/ 8, 0x09, + /* RLE: 001 Pixels @ 122,298*/ 1, 0x0C, + /* RLE: 079 Pixels @ 123,298*/ 79, 0x00, + /* RLE: 001 Pixels @ 202,298*/ 1, 0x04, + /* RLE: 006 Pixels @ 203,298*/ 6, 0x03, + /* RLE: 001 Pixels @ 209,298*/ 1, 0x04, + /* RLE: 055 Pixels @ 210,298*/ 55, 0x00, + /* RLE: 007 Pixels @ 265,298*/ 7, 0x03, + /* RLE: 001 Pixels @ 272,298*/ 1, 0x04, + /* RLE: 057 Pixels @ 273,298*/ 57, 0x00, + /* ABS: 012 Pixels @ 330,298*/ 0, 12, 0x0B, 0x03, 0x00, 0x08, 0x00, 0x03, 0x04, 0x11, 0x08, 0x0F, 0x04, 0x03, + /* RLE: 058 Pixels @ 342,298*/ 58, 0x00, + /* ABS: 016 Pixels @ 000,299*/ 0, 16, 0x04, 0x08, 0x00, 0x03, 0x03, 0x0E, 0x08, 0x0E, 0x0B, 0x06, 0x00, 0x03, 0x0C, 0x06, 0x0E, 0x00, + /* RLE: 007 Pixels @ 016,299*/ 7, 0x03, + /* RLE: 004 Pixels @ 023,299*/ 4, 0x00, + /* RLE: 001 Pixels @ 027,299*/ 1, 0x04, + /* RLE: 033 Pixels @ 028,299*/ 33, 0x02, + /* RLE: 001 Pixels @ 061,299*/ 1, 0x04, + /* RLE: 006 Pixels @ 062,299*/ 6, 0x03, + /* RLE: 001 Pixels @ 068,299*/ 1, 0x04, + /* RLE: 045 Pixels @ 069,299*/ 45, 0x00, + /* RLE: 001 Pixels @ 114,299*/ 1, 0x0C, + /* RLE: 008 Pixels @ 115,299*/ 8, 0x09, + /* RLE: 001 Pixels @ 123,299*/ 1, 0x0C, + /* RLE: 077 Pixels @ 124,299*/ 77, 0x00, + /* ABS: 002 Pixels @ 201,299*/ 0, 2, 0x04, 0x04, + /* RLE: 006 Pixels @ 203,299*/ 6, 0x03, + /* RLE: 056 Pixels @ 209,299*/ 56, 0x00, + /* RLE: 001 Pixels @ 265,299*/ 1, 0x04, + /* RLE: 006 Pixels @ 266,299*/ 6, 0x03, + /* RLE: 001 Pixels @ 272,299*/ 1, 0x04, + /* RLE: 059 Pixels @ 273,299*/ 59, 0x00, + /* ABS: 009 Pixels @ 332,299*/ 0, 9, 0x03, 0x03, 0x0E, 0x08, 0x08, 0x06, 0x08, 0x00, 0x03, + /* RLE: 059 Pixels @ 341,299*/ 59, 0x00, + /* ABS: 003 Pixels @ 000,300*/ 0, 3, 0x0B, 0x06, 0x0B, + /* RLE: 012 Pixels @ 003,300*/ 12, 0x03, + /* ABS: 002 Pixels @ 015,300*/ 0, 2, 0x00, 0x00, + /* RLE: 004 Pixels @ 017,300*/ 4, 0x04, + /* RLE: 040 Pixels @ 021,300*/ 40, 0x02, + /* RLE: 001 Pixels @ 061,300*/ 1, 0x04, + /* RLE: 006 Pixels @ 062,300*/ 6, 0x03, + /* RLE: 001 Pixels @ 068,300*/ 1, 0x04, + /* RLE: 045 Pixels @ 069,300*/ 45, 0x00, + /* RLE: 001 Pixels @ 114,300*/ 1, 0x0C, + /* RLE: 008 Pixels @ 115,300*/ 8, 0x09, + /* RLE: 001 Pixels @ 123,300*/ 1, 0x0C, + /* RLE: 078 Pixels @ 124,300*/ 78, 0x00, + /* RLE: 001 Pixels @ 202,300*/ 1, 0x04, + /* RLE: 006 Pixels @ 203,300*/ 6, 0x03, + /* RLE: 001 Pixels @ 209,300*/ 1, 0x04, + /* RLE: 055 Pixels @ 210,300*/ 55, 0x00, + /* RLE: 001 Pixels @ 265,300*/ 1, 0x04, + /* RLE: 007 Pixels @ 266,300*/ 7, 0x03, + /* RLE: 059 Pixels @ 273,300*/ 59, 0x00, + /* ABS: 010 Pixels @ 332,300*/ 0, 10, 0x03, 0x0C, 0x08, 0x0C, 0x00, 0x03, 0x00, 0x00, 0x03, 0x04, + /* RLE: 058 Pixels @ 342,300*/ 58, 0x00, + /* RLE: 007 Pixels @ 000,301*/ 7, 0x03, + /* RLE: 007 Pixels @ 007,301*/ 7, 0x04, + /* RLE: 047 Pixels @ 014,301*/ 47, 0x02, + /* RLE: 001 Pixels @ 061,301*/ 1, 0x04, + /* RLE: 006 Pixels @ 062,301*/ 6, 0x03, + /* RLE: 001 Pixels @ 068,301*/ 1, 0x04, + /* RLE: 045 Pixels @ 069,301*/ 45, 0x00, + /* RLE: 001 Pixels @ 114,301*/ 1, 0x0C, + /* RLE: 008 Pixels @ 115,301*/ 8, 0x09, + /* RLE: 001 Pixels @ 123,301*/ 1, 0x0C, + /* RLE: 078 Pixels @ 124,301*/ 78, 0x00, + /* RLE: 001 Pixels @ 202,301*/ 1, 0x04, + /* RLE: 006 Pixels @ 203,301*/ 6, 0x03, + /* RLE: 001 Pixels @ 209,301*/ 1, 0x04, + /* RLE: 056 Pixels @ 210,301*/ 56, 0x00, + /* RLE: 001 Pixels @ 266,301*/ 1, 0x04, + /* RLE: 006 Pixels @ 267,301*/ 6, 0x03, + /* RLE: 001 Pixels @ 273,301*/ 1, 0x04, + /* RLE: 058 Pixels @ 274,301*/ 58, 0x00, + /* ABS: 004 Pixels @ 332,301*/ 0, 4, 0x03, 0x00, 0x08, 0x00, + /* RLE: 005 Pixels @ 336,301*/ 5, 0x03, + /* RLE: 059 Pixels @ 341,301*/ 59, 0x00, + /* RLE: 007 Pixels @ 000,302*/ 7, 0x04, + /* RLE: 055 Pixels @ 007,302*/ 55, 0x02, + /* RLE: 007 Pixels @ 062,302*/ 7, 0x03, + /* RLE: 001 Pixels @ 069,302*/ 1, 0x04, + /* RLE: 044 Pixels @ 070,302*/ 44, 0x00, + /* RLE: 001 Pixels @ 114,302*/ 1, 0x0C, + /* RLE: 008 Pixels @ 115,302*/ 8, 0x09, + /* RLE: 001 Pixels @ 123,302*/ 1, 0x0C, + /* RLE: 078 Pixels @ 124,302*/ 78, 0x00, + /* RLE: 001 Pixels @ 202,302*/ 1, 0x04, + /* RLE: 006 Pixels @ 203,302*/ 6, 0x03, + /* RLE: 001 Pixels @ 209,302*/ 1, 0x04, + /* RLE: 056 Pixels @ 210,302*/ 56, 0x00, + /* RLE: 001 Pixels @ 266,302*/ 1, 0x04, + /* RLE: 006 Pixels @ 267,302*/ 6, 0x03, + /* RLE: 001 Pixels @ 273,302*/ 1, 0x04, + /* RLE: 059 Pixels @ 274,302*/ 59, 0x00, + /* RLE: 004 Pixels @ 333,302*/ 4, 0x03, + /* ABS: 005 Pixels @ 337,302*/ 0, 5, 0x0C, 0x06, 0x06, 0x0B, 0x03, + /* RLE: 058 Pixels @ 342,302*/ 58, 0x00, + /* RLE: 062 Pixels @ 000,303*/ 62, 0x02, + /* RLE: 001 Pixels @ 062,303*/ 1, 0x04, + /* RLE: 006 Pixels @ 063,303*/ 6, 0x03, + /* RLE: 001 Pixels @ 069,303*/ 1, 0x04, + /* RLE: 044 Pixels @ 070,303*/ 44, 0x00, + /* RLE: 001 Pixels @ 114,303*/ 1, 0x0C, + /* RLE: 008 Pixels @ 115,303*/ 8, 0x09, + /* RLE: 001 Pixels @ 123,303*/ 1, 0x0C, + /* RLE: 079 Pixels @ 124,303*/ 79, 0x00, + /* RLE: 007 Pixels @ 203,303*/ 7, 0x03, + /* RLE: 001 Pixels @ 210,303*/ 1, 0x04, + /* RLE: 055 Pixels @ 211,303*/ 55, 0x00, + /* RLE: 001 Pixels @ 266,303*/ 1, 0x04, + /* RLE: 007 Pixels @ 267,303*/ 7, 0x03, + /* RLE: 061 Pixels @ 274,303*/ 61, 0x00, + /* ABS: 006 Pixels @ 335,303*/ 0, 6, 0x03, 0x06, 0x08, 0x06, 0x12, 0x08, + /* RLE: 059 Pixels @ 341,303*/ 59, 0x00, + /* RLE: 062 Pixels @ 000,304*/ 62, 0x02, + /* RLE: 001 Pixels @ 062,304*/ 1, 0x04, + /* RLE: 006 Pixels @ 063,304*/ 6, 0x03, + /* RLE: 001 Pixels @ 069,304*/ 1, 0x04, + /* RLE: 045 Pixels @ 070,304*/ 45, 0x00, + /* RLE: 001 Pixels @ 115,304*/ 1, 0x0C, + /* RLE: 008 Pixels @ 116,304*/ 8, 0x09, + /* RLE: 001 Pixels @ 124,304*/ 1, 0x0C, + /* RLE: 078 Pixels @ 125,304*/ 78, 0x00, + /* RLE: 001 Pixels @ 203,304*/ 1, 0x04, + /* RLE: 006 Pixels @ 204,304*/ 6, 0x03, + /* RLE: 001 Pixels @ 210,304*/ 1, 0x04, + /* RLE: 056 Pixels @ 211,304*/ 56, 0x00, + /* RLE: 001 Pixels @ 267,304*/ 1, 0x04, + /* RLE: 006 Pixels @ 268,304*/ 6, 0x03, + /* RLE: 001 Pixels @ 274,304*/ 1, 0x04, + /* RLE: 060 Pixels @ 275,304*/ 60, 0x00, + /* ABS: 008 Pixels @ 335,304*/ 0, 8, 0x03, 0x08, 0x0C, 0x03, 0x03, 0x0E, 0x0E, 0x03, + /* RLE: 057 Pixels @ 343,304*/ 57, 0x00, + /* RLE: 062 Pixels @ 000,305*/ 62, 0x02, + /* RLE: 001 Pixels @ 062,305*/ 1, 0x04, + /* RLE: 006 Pixels @ 063,305*/ 6, 0x03, + /* RLE: 001 Pixels @ 069,305*/ 1, 0x04, + /* RLE: 045 Pixels @ 070,305*/ 45, 0x00, + /* RLE: 001 Pixels @ 115,305*/ 1, 0x0C, + /* RLE: 008 Pixels @ 116,305*/ 8, 0x09, + /* RLE: 001 Pixels @ 124,305*/ 1, 0x0C, + /* RLE: 078 Pixels @ 125,305*/ 78, 0x00, + /* RLE: 001 Pixels @ 203,305*/ 1, 0x04, + /* RLE: 006 Pixels @ 204,305*/ 6, 0x03, + /* RLE: 001 Pixels @ 210,305*/ 1, 0x04, + /* RLE: 056 Pixels @ 211,305*/ 56, 0x00, + /* RLE: 001 Pixels @ 267,305*/ 1, 0x04, + /* RLE: 006 Pixels @ 268,305*/ 6, 0x03, + /* RLE: 001 Pixels @ 274,305*/ 1, 0x04, + /* RLE: 060 Pixels @ 275,305*/ 60, 0x00, + /* ABS: 009 Pixels @ 335,305*/ 0, 9, 0x03, 0x08, 0x00, 0x03, 0x03, 0x12, 0x12, 0x03, 0x04, + /* RLE: 056 Pixels @ 344,305*/ 56, 0x00, + /* RLE: 062 Pixels @ 000,306*/ 62, 0x02, + /* RLE: 001 Pixels @ 062,306*/ 1, 0x04, + /* RLE: 006 Pixels @ 063,306*/ 6, 0x03, + /* RLE: 001 Pixels @ 069,306*/ 1, 0x04, + /* RLE: 045 Pixels @ 070,306*/ 45, 0x00, + /* RLE: 001 Pixels @ 115,306*/ 1, 0x0C, + /* RLE: 008 Pixels @ 116,306*/ 8, 0x09, + /* RLE: 001 Pixels @ 124,306*/ 1, 0x0C, + /* RLE: 078 Pixels @ 125,306*/ 78, 0x00, + /* RLE: 001 Pixels @ 203,306*/ 1, 0x04, + /* RLE: 006 Pixels @ 204,306*/ 6, 0x03, + /* RLE: 001 Pixels @ 210,306*/ 1, 0x04, + /* RLE: 057 Pixels @ 211,306*/ 57, 0x00, + /* RLE: 007 Pixels @ 268,306*/ 7, 0x03, + /* RLE: 001 Pixels @ 275,306*/ 1, 0x04, + /* RLE: 059 Pixels @ 276,306*/ 59, 0x00, + /* ABS: 009 Pixels @ 335,306*/ 0, 9, 0x03, 0x06, 0x0D, 0x0C, 0x06, 0x08, 0x04, 0x03, 0x04, + /* RLE: 056 Pixels @ 344,306*/ 56, 0x00, + /* RLE: 062 Pixels @ 000,307*/ 62, 0x02, + /* RLE: 001 Pixels @ 062,307*/ 1, 0x04, + /* RLE: 006 Pixels @ 063,307*/ 6, 0x03, + /* RLE: 001 Pixels @ 069,307*/ 1, 0x04, + /* RLE: 045 Pixels @ 070,307*/ 45, 0x00, + /* RLE: 001 Pixels @ 115,307*/ 1, 0x0C, + /* RLE: 008 Pixels @ 116,307*/ 8, 0x09, + /* RLE: 001 Pixels @ 124,307*/ 1, 0x0C, + /* RLE: 079 Pixels @ 125,307*/ 79, 0x00, + /* RLE: 007 Pixels @ 204,307*/ 7, 0x03, + /* RLE: 001 Pixels @ 211,307*/ 1, 0x04, + /* RLE: 056 Pixels @ 212,307*/ 56, 0x00, + /* RLE: 001 Pixels @ 268,307*/ 1, 0x04, + /* RLE: 008 Pixels @ 269,307*/ 8, 0x03, + /* RLE: 058 Pixels @ 277,307*/ 58, 0x00, + /* ABS: 010 Pixels @ 335,307*/ 0, 10, 0x03, 0x03, 0x0E, 0x08, 0x11, 0x0B, 0x03, 0x03, 0x03, 0x04, + /* RLE: 055 Pixels @ 345,307*/ 55, 0x00, + /* RLE: 063 Pixels @ 000,308*/ 63, 0x02, + /* RLE: 007 Pixels @ 063,308*/ 7, 0x03, + /* RLE: 001 Pixels @ 070,308*/ 1, 0x04, + /* RLE: 045 Pixels @ 071,308*/ 45, 0x00, + /* RLE: 001 Pixels @ 116,308*/ 1, 0x0C, + /* RLE: 008 Pixels @ 117,308*/ 8, 0x09, + /* RLE: 001 Pixels @ 125,308*/ 1, 0x0C, + /* RLE: 078 Pixels @ 126,308*/ 78, 0x00, + /* RLE: 001 Pixels @ 204,308*/ 1, 0x04, + /* RLE: 006 Pixels @ 205,308*/ 6, 0x03, + /* RLE: 001 Pixels @ 211,308*/ 1, 0x04, + /* RLE: 056 Pixels @ 212,308*/ 56, 0x00, + /* RLE: 001 Pixels @ 268,308*/ 1, 0x04, + /* RLE: 004 Pixels @ 269,308*/ 4, 0x03, + /* ABS: 004 Pixels @ 273,308*/ 0, 4, 0x04, 0x0D, 0x12, 0x03, + /* RLE: 059 Pixels @ 277,308*/ 59, 0x00, + /* RLE: 003 Pixels @ 336,308*/ 3, 0x03, + /* ABS: 006 Pixels @ 339,308*/ 0, 6, 0x0E, 0x0E, 0x03, 0x03, 0x03, 0x04, + /* RLE: 055 Pixels @ 345,308*/ 55, 0x00, + /* RLE: 063 Pixels @ 000,309*/ 63, 0x02, + /* RLE: 001 Pixels @ 063,309*/ 1, 0x04, + /* RLE: 006 Pixels @ 064,309*/ 6, 0x03, + /* RLE: 001 Pixels @ 070,309*/ 1, 0x04, + /* RLE: 045 Pixels @ 071,309*/ 45, 0x00, + /* RLE: 001 Pixels @ 116,309*/ 1, 0x0C, + /* RLE: 008 Pixels @ 117,309*/ 8, 0x09, + /* RLE: 001 Pixels @ 125,309*/ 1, 0x0C, + /* RLE: 078 Pixels @ 126,309*/ 78, 0x00, + /* RLE: 001 Pixels @ 204,309*/ 1, 0x04, + /* RLE: 006 Pixels @ 205,309*/ 6, 0x03, + /* RLE: 001 Pixels @ 211,309*/ 1, 0x04, + /* RLE: 056 Pixels @ 212,309*/ 56, 0x00, + /* ABS: 009 Pixels @ 268,309*/ 0, 9, 0x03, 0x03, 0x00, 0x0E, 0x0F, 0x08, 0x11, 0x0C, 0x03, + /* RLE: 060 Pixels @ 277,309*/ 60, 0x00, + /* ABS: 004 Pixels @ 337,309*/ 0, 4, 0x04, 0x03, 0x0E, 0x0F, + /* RLE: 005 Pixels @ 341,309*/ 5, 0x03, + /* RLE: 054 Pixels @ 346,309*/ 54, 0x00, + /* RLE: 063 Pixels @ 000,310*/ 63, 0x02, + /* RLE: 001 Pixels @ 063,310*/ 1, 0x04, + /* RLE: 006 Pixels @ 064,310*/ 6, 0x03, + /* RLE: 001 Pixels @ 070,310*/ 1, 0x04, + /* RLE: 045 Pixels @ 071,310*/ 45, 0x00, + /* RLE: 001 Pixels @ 116,310*/ 1, 0x0C, + /* RLE: 008 Pixels @ 117,310*/ 8, 0x09, + /* RLE: 001 Pixels @ 125,310*/ 1, 0x0C, + /* RLE: 078 Pixels @ 126,310*/ 78, 0x00, + /* RLE: 001 Pixels @ 204,310*/ 1, 0x04, + /* RLE: 007 Pixels @ 205,310*/ 7, 0x03, + /* RLE: 054 Pixels @ 212,310*/ 54, 0x00, + /* ABS: 010 Pixels @ 266,310*/ 0, 10, 0x04, 0x00, 0x0B, 0x0D, 0x08, 0x08, 0x0E, 0x00, 0x03, 0x03, + /* RLE: 062 Pixels @ 276,310*/ 62, 0x00, + /* ABS: 009 Pixels @ 338,310*/ 0, 9, 0x03, 0x00, 0x08, 0x00, 0x03, 0x04, 0x12, 0x0E, 0x03, + /* RLE: 053 Pixels @ 347,310*/ 53, 0x00, + /* RLE: 063 Pixels @ 000,311*/ 63, 0x02, + /* RLE: 001 Pixels @ 063,311*/ 1, 0x04, + /* RLE: 006 Pixels @ 064,311*/ 6, 0x03, + /* RLE: 001 Pixels @ 070,311*/ 1, 0x04, + /* RLE: 045 Pixels @ 071,311*/ 45, 0x00, + /* RLE: 001 Pixels @ 116,311*/ 1, 0x0C, + /* RLE: 008 Pixels @ 117,311*/ 8, 0x09, + /* RLE: 001 Pixels @ 125,311*/ 1, 0x0C, + /* RLE: 079 Pixels @ 126,311*/ 79, 0x00, + /* RLE: 001 Pixels @ 205,311*/ 1, 0x04, + /* RLE: 006 Pixels @ 206,311*/ 6, 0x03, + /* RLE: 001 Pixels @ 212,311*/ 1, 0x04, + /* RLE: 050 Pixels @ 213,311*/ 50, 0x00, + /* ABS: 015 Pixels @ 263,311*/ 0, 15, 0x04, 0x04, 0x03, 0x03, 0x03, 0x04, 0x11, 0x0C, 0x03, 0x03, 0x00, 0x00, 0x03, 0x03, 0x04, + /* RLE: 060 Pixels @ 278,311*/ 60, 0x00, + /* ABS: 009 Pixels @ 338,311*/ 0, 9, 0x03, 0x03, 0x00, 0x0E, 0x11, 0x08, 0x0F, 0x0E, 0x03, + /* RLE: 053 Pixels @ 347,311*/ 53, 0x00, + /* RLE: 063 Pixels @ 000,312*/ 63, 0x02, + /* RLE: 001 Pixels @ 063,312*/ 1, 0x04, + /* RLE: 006 Pixels @ 064,312*/ 6, 0x03, + /* RLE: 001 Pixels @ 070,312*/ 1, 0x04, + /* RLE: 045 Pixels @ 071,312*/ 45, 0x00, + /* RLE: 001 Pixels @ 116,312*/ 1, 0x0C, + /* RLE: 008 Pixels @ 117,312*/ 8, 0x09, + /* RLE: 001 Pixels @ 125,312*/ 1, 0x0C, + /* RLE: 027 Pixels @ 126,312*/ 27, 0x00, + /* RLE: 005 Pixels @ 153,312*/ 5, 0x04, + /* RLE: 047 Pixels @ 158,312*/ 47, 0x00, + /* RLE: 001 Pixels @ 205,312*/ 1, 0x04, + /* RLE: 006 Pixels @ 206,312*/ 6, 0x03, + /* RLE: 001 Pixels @ 212,312*/ 1, 0x04, + /* RLE: 048 Pixels @ 213,312*/ 48, 0x00, + /* ABS: 002 Pixels @ 261,312*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 263,312*/ 8, 0x03, + /* ABS: 007 Pixels @ 271,312*/ 0, 7, 0x0B, 0x12, 0x08, 0x0D, 0x03, 0x03, 0x04, + /* RLE: 059 Pixels @ 278,312*/ 59, 0x00, + /* ABS: 009 Pixels @ 337,312*/ 0, 9, 0x03, 0x0B, 0x06, 0x08, 0x08, 0x08, 0x0C, 0x03, 0x03, + /* RLE: 054 Pixels @ 346,312*/ 54, 0x00, + /* RLE: 063 Pixels @ 000,313*/ 63, 0x02, + /* RLE: 001 Pixels @ 063,313*/ 1, 0x04, + /* RLE: 006 Pixels @ 064,313*/ 6, 0x03, + /* RLE: 001 Pixels @ 070,313*/ 1, 0x04, + /* RLE: 046 Pixels @ 071,313*/ 46, 0x00, + /* RLE: 001 Pixels @ 117,313*/ 1, 0x0C, + /* RLE: 008 Pixels @ 118,313*/ 8, 0x09, + /* RLE: 001 Pixels @ 126,313*/ 1, 0x0C, + /* RLE: 023 Pixels @ 127,313*/ 23, 0x00, + /* ABS: 002 Pixels @ 150,313*/ 0, 2, 0x04, 0x04, + /* RLE: 005 Pixels @ 152,313*/ 5, 0x03, + /* ABS: 002 Pixels @ 157,313*/ 0, 2, 0x04, 0x04, + /* RLE: 046 Pixels @ 159,313*/ 46, 0x00, + /* RLE: 001 Pixels @ 205,313*/ 1, 0x04, + /* RLE: 006 Pixels @ 206,313*/ 6, 0x03, + /* RLE: 001 Pixels @ 212,313*/ 1, 0x04, + /* RLE: 045 Pixels @ 213,313*/ 45, 0x00, + /* ABS: 002 Pixels @ 258,313*/ 0, 2, 0x04, 0x04, + /* RLE: 009 Pixels @ 260,313*/ 9, 0x03, + /* ABS: 010 Pixels @ 269,313*/ 0, 10, 0x0C, 0x11, 0x08, 0x11, 0x06, 0x12, 0x00, 0x03, 0x03, 0x04, + /* RLE: 058 Pixels @ 279,313*/ 58, 0x00, + /* ABS: 007 Pixels @ 337,313*/ 0, 7, 0x03, 0x04, 0x11, 0x0E, 0x00, 0x06, 0x0E, + /* RLE: 004 Pixels @ 344,313*/ 4, 0x03, + /* RLE: 052 Pixels @ 348,313*/ 52, 0x00, + /* RLE: 064 Pixels @ 000,314*/ 64, 0x02, + /* RLE: 007 Pixels @ 064,314*/ 7, 0x03, + /* RLE: 001 Pixels @ 071,314*/ 1, 0x04, + /* RLE: 045 Pixels @ 072,314*/ 45, 0x00, + /* RLE: 001 Pixels @ 117,314*/ 1, 0x0C, + /* RLE: 008 Pixels @ 118,314*/ 8, 0x09, + /* RLE: 001 Pixels @ 126,314*/ 1, 0x0C, + /* RLE: 021 Pixels @ 127,314*/ 21, 0x00, + /* ABS: 002 Pixels @ 148,314*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 150,314*/ 8, 0x03, + /* RLE: 001 Pixels @ 158,314*/ 1, 0x04, + /* RLE: 046 Pixels @ 159,314*/ 46, 0x00, + /* RLE: 001 Pixels @ 205,314*/ 1, 0x04, + /* RLE: 007 Pixels @ 206,314*/ 7, 0x03, + /* RLE: 043 Pixels @ 213,314*/ 43, 0x00, + /* ABS: 002 Pixels @ 256,314*/ 0, 2, 0x04, 0x04, + /* RLE: 011 Pixels @ 258,314*/ 11, 0x03, + /* ABS: 010 Pixels @ 269,314*/ 0, 10, 0x04, 0x12, 0x0B, 0x03, 0x03, 0x0E, 0x12, 0x03, 0x03, 0x04, + /* RLE: 059 Pixels @ 279,314*/ 59, 0x00, + /* RLE: 004 Pixels @ 338,314*/ 4, 0x03, + /* ABS: 007 Pixels @ 342,314*/ 0, 7, 0x0C, 0x0F, 0x03, 0x00, 0x0E, 0x00, 0x03, + /* RLE: 051 Pixels @ 349,314*/ 51, 0x00, + /* RLE: 064 Pixels @ 000,315*/ 64, 0x02, + /* RLE: 001 Pixels @ 064,315*/ 1, 0x04, + /* RLE: 006 Pixels @ 065,315*/ 6, 0x03, + /* RLE: 001 Pixels @ 071,315*/ 1, 0x04, + /* RLE: 045 Pixels @ 072,315*/ 45, 0x00, + /* RLE: 001 Pixels @ 117,315*/ 1, 0x0C, + /* RLE: 008 Pixels @ 118,315*/ 8, 0x09, + /* RLE: 001 Pixels @ 126,315*/ 1, 0x0C, + /* RLE: 018 Pixels @ 127,315*/ 18, 0x00, + /* ABS: 002 Pixels @ 145,315*/ 0, 2, 0x04, 0x04, + /* RLE: 011 Pixels @ 147,315*/ 11, 0x03, + /* RLE: 001 Pixels @ 158,315*/ 1, 0x04, + /* RLE: 047 Pixels @ 159,315*/ 47, 0x00, + /* RLE: 001 Pixels @ 206,315*/ 1, 0x04, + /* RLE: 006 Pixels @ 207,315*/ 6, 0x03, + /* RLE: 001 Pixels @ 213,315*/ 1, 0x04, + /* RLE: 039 Pixels @ 214,315*/ 39, 0x00, + /* ABS: 002 Pixels @ 253,315*/ 0, 2, 0x04, 0x04, + /* RLE: 018 Pixels @ 255,315*/ 18, 0x03, + /* ABS: 006 Pixels @ 273,315*/ 0, 6, 0x0C, 0x0F, 0x06, 0x03, 0x03, 0x04, + /* RLE: 061 Pixels @ 279,315*/ 61, 0x00, + /* RLE: 003 Pixels @ 340,315*/ 3, 0x03, + /* ABS: 005 Pixels @ 343,315*/ 0, 5, 0x08, 0x11, 0x08, 0x08, 0x04, + /* RLE: 052 Pixels @ 348,315*/ 52, 0x00, + /* RLE: 064 Pixels @ 000,316*/ 64, 0x02, + /* RLE: 001 Pixels @ 064,316*/ 1, 0x04, + /* RLE: 006 Pixels @ 065,316*/ 6, 0x03, + /* RLE: 001 Pixels @ 071,316*/ 1, 0x04, + /* RLE: 045 Pixels @ 072,316*/ 45, 0x00, + /* RLE: 001 Pixels @ 117,316*/ 1, 0x0C, + /* RLE: 008 Pixels @ 118,316*/ 8, 0x09, + /* RLE: 001 Pixels @ 126,316*/ 1, 0x0C, + /* RLE: 016 Pixels @ 127,316*/ 16, 0x00, + /* ABS: 002 Pixels @ 143,316*/ 0, 2, 0x04, 0x04, + /* RLE: 013 Pixels @ 145,316*/ 13, 0x03, + /* RLE: 001 Pixels @ 158,316*/ 1, 0x04, + /* RLE: 047 Pixels @ 159,316*/ 47, 0x00, + /* RLE: 001 Pixels @ 206,316*/ 1, 0x04, + /* RLE: 006 Pixels @ 207,316*/ 6, 0x03, + /* RLE: 001 Pixels @ 213,316*/ 1, 0x04, + /* RLE: 037 Pixels @ 214,316*/ 37, 0x00, + /* ABS: 002 Pixels @ 251,316*/ 0, 2, 0x04, 0x04, + /* RLE: 016 Pixels @ 253,316*/ 16, 0x03, + /* ABS: 011 Pixels @ 269,316*/ 0, 11, 0x00, 0x00, 0x0E, 0x08, 0x08, 0x0D, 0x0D, 0x00, 0x03, 0x03, 0x04, + /* RLE: 059 Pixels @ 280,316*/ 59, 0x00, + /* ABS: 009 Pixels @ 339,316*/ 0, 9, 0x03, 0x00, 0x0E, 0x0F, 0x08, 0x11, 0x0C, 0x00, 0x03, + /* RLE: 052 Pixels @ 348,316*/ 52, 0x00, + /* RLE: 064 Pixels @ 000,317*/ 64, 0x02, + /* RLE: 001 Pixels @ 064,317*/ 1, 0x04, + /* RLE: 006 Pixels @ 065,317*/ 6, 0x03, + /* RLE: 001 Pixels @ 071,317*/ 1, 0x04, + /* RLE: 045 Pixels @ 072,317*/ 45, 0x00, + /* RLE: 001 Pixels @ 117,317*/ 1, 0x0C, + /* RLE: 008 Pixels @ 118,317*/ 8, 0x09, + /* RLE: 001 Pixels @ 126,317*/ 1, 0x0C, + /* RLE: 013 Pixels @ 127,317*/ 13, 0x00, + /* ABS: 002 Pixels @ 140,317*/ 0, 2, 0x04, 0x04, + /* RLE: 015 Pixels @ 142,317*/ 15, 0x03, + /* ABS: 002 Pixels @ 157,317*/ 0, 2, 0x04, 0x04, + /* RLE: 047 Pixels @ 159,317*/ 47, 0x00, + /* RLE: 001 Pixels @ 206,317*/ 1, 0x04, + /* RLE: 006 Pixels @ 207,317*/ 6, 0x03, + /* ABS: 002 Pixels @ 213,317*/ 0, 2, 0x04, 0x04, + /* RLE: 033 Pixels @ 215,317*/ 33, 0x00, + /* ABS: 002 Pixels @ 248,317*/ 0, 2, 0x04, 0x04, + /* RLE: 016 Pixels @ 250,317*/ 16, 0x03, + /* ABS: 014 Pixels @ 266,317*/ 0, 14, 0x04, 0x04, 0x00, 0x03, 0x00, 0x0F, 0x0E, 0x00, 0x03, 0x0B, 0x0F, 0x03, 0x03, 0x04, + /* RLE: 059 Pixels @ 280,317*/ 59, 0x00, + /* ABS: 005 Pixels @ 339,317*/ 0, 5, 0x03, 0x11, 0x08, 0x12, 0x0B, + /* RLE: 004 Pixels @ 344,317*/ 4, 0x03, + /* RLE: 001 Pixels @ 348,317*/ 1, 0x04, + /* RLE: 051 Pixels @ 349,317*/ 51, 0x00, + /* RLE: 064 Pixels @ 000,318*/ 64, 0x02, + /* RLE: 001 Pixels @ 064,318*/ 1, 0x04, + /* RLE: 006 Pixels @ 065,318*/ 6, 0x03, + /* RLE: 001 Pixels @ 071,318*/ 1, 0x04, + /* RLE: 046 Pixels @ 072,318*/ 46, 0x00, + /* RLE: 001 Pixels @ 118,318*/ 1, 0x0C, + /* RLE: 008 Pixels @ 119,318*/ 8, 0x09, + /* RLE: 001 Pixels @ 127,318*/ 1, 0x0C, + /* RLE: 009 Pixels @ 128,318*/ 9, 0x00, + /* ABS: 002 Pixels @ 137,318*/ 0, 2, 0x04, 0x04, + /* RLE: 017 Pixels @ 139,318*/ 17, 0x03, + /* ABS: 002 Pixels @ 156,318*/ 0, 2, 0x04, 0x04, + /* RLE: 048 Pixels @ 158,318*/ 48, 0x00, + /* RLE: 001 Pixels @ 206,318*/ 1, 0x04, + /* RLE: 007 Pixels @ 207,318*/ 7, 0x03, + /* ABS: 002 Pixels @ 214,318*/ 0, 2, 0x04, 0x04, + /* RLE: 030 Pixels @ 216,318*/ 30, 0x00, + /* ABS: 002 Pixels @ 246,318*/ 0, 2, 0x04, 0x04, + /* RLE: 016 Pixels @ 248,318*/ 16, 0x03, + /* ABS: 002 Pixels @ 264,318*/ 0, 2, 0x04, 0x04, + /* RLE: 004 Pixels @ 266,318*/ 4, 0x00, + /* RLE: 004 Pixels @ 270,318*/ 4, 0x03, + /* ABS: 007 Pixels @ 274,318*/ 0, 7, 0x00, 0x12, 0x08, 0x03, 0x03, 0x03, 0x04, + /* RLE: 058 Pixels @ 281,318*/ 58, 0x00, + /* ABS: 002 Pixels @ 339,318*/ 0, 2, 0x03, 0x00, + /* RLE: 007 Pixels @ 341,318*/ 7, 0x03, + /* RLE: 001 Pixels @ 348,318*/ 1, 0x04, + /* RLE: 051 Pixels @ 349,318*/ 51, 0x00, + /* RLE: 064 Pixels @ 000,319*/ 64, 0x02, + /* RLE: 001 Pixels @ 064,319*/ 1, 0x04, + /* RLE: 006 Pixels @ 065,319*/ 6, 0x03, + /* RLE: 001 Pixels @ 071,319*/ 1, 0x04, + /* RLE: 046 Pixels @ 072,319*/ 46, 0x00, + /* RLE: 001 Pixels @ 118,319*/ 1, 0x0C, + /* RLE: 008 Pixels @ 119,319*/ 8, 0x09, + /* RLE: 001 Pixels @ 127,319*/ 1, 0x0C, + /* RLE: 007 Pixels @ 128,319*/ 7, 0x00, + /* ABS: 002 Pixels @ 135,319*/ 0, 2, 0x04, 0x04, + /* RLE: 016 Pixels @ 137,319*/ 16, 0x03, + /* ABS: 002 Pixels @ 153,319*/ 0, 2, 0x04, 0x04, + /* RLE: 052 Pixels @ 155,319*/ 52, 0x00, + /* RLE: 001 Pixels @ 207,319*/ 1, 0x04, + /* RLE: 007 Pixels @ 208,319*/ 7, 0x03, + /* ABS: 002 Pixels @ 215,319*/ 0, 2, 0x04, 0x04, + /* RLE: 026 Pixels @ 217,319*/ 26, 0x00, + /* ABS: 002 Pixels @ 243,319*/ 0, 2, 0x04, 0x04, + /* RLE: 016 Pixels @ 245,319*/ 16, 0x03, + /* ABS: 002 Pixels @ 261,319*/ 0, 2, 0x04, 0x04, + /* RLE: 008 Pixels @ 263,319*/ 8, 0x00, + /* ABS: 010 Pixels @ 271,319*/ 0, 10, 0x03, 0x0C, 0x11, 0x08, 0x0F, 0x04, 0x03, 0x03, 0x03, 0x04, + /* RLE: 059 Pixels @ 281,319*/ 59, 0x00, + /* ABS: 009 Pixels @ 340,319*/ 0, 9, 0x03, 0x03, 0x00, 0x00, 0x03, 0x11, 0x0E, 0x03, 0x03, + /* RLE: 051 Pixels @ 349,319*/ 51, 0x00, + + + 0}; /* 23077 for 128000 pixels */ + +static GUI_CONST_STORAGE GUI_BITMAP _bmMap_400x320 = { + 400, /* XSize */ + 320, /* YSize */ + 400, /* BytesPerLine */ + GUI_COMPRESS_RLE8, /* BitsPerPixel */ + acMap_400x320, /* Pointer to picture data (indices) */ + &PalMap_400x320 /* Pointer to palette */ + ,GUI_DRAW_RLE8 +}; + +static int _Alpha_0 = 85; +static int _Alpha_1 = 0; + +static WM_CALLBACK * _pcbClient; + +static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = { + { FRAMEWIN_CreateIndirect, "Transparent dialog", 0, 0, 0, 220, 100, FRAMEWIN_CF_MOVEABLE}, + { TEXT_CreateIndirect, "Background:", GUI_ID_TEXT0, 5, 10, 90, 20, TEXT_CF_LEFT }, + { TEXT_CreateIndirect, "Title:", GUI_ID_TEXT1, 5, 40, 90, 20, TEXT_CF_LEFT }, + { SLIDER_CreateIndirect, NULL, GUI_ID_SLIDER0, 100, 10, 100, 20 }, + { SLIDER_CreateIndirect, NULL, GUI_ID_SLIDER1, 100, 40, 100, 20 }, +}; + +/********************************************************************* +* +* Static code +* +********************************************************************** +*/ +/********************************************************************* +* +* _cbWin +* +* Purpose: +* Callback routine of map window. On receiving a timer message it +* invalidates itself and restarts the timer. +*/ +static void _cbWin(WM_MESSAGE * pMsg) { + static int xAdd, yAdd, xPos, yPos; + int xSize, ySize, xSizeBmp, ySizeBmp; + WM_HWIN hWin; + + hWin = pMsg->hWin; + xSize = LCD_GetXSize(); + ySize = LCD_GetYSize(); + xSizeBmp = _bmMap_400x320.XSize; + ySizeBmp = _bmMap_400x320.YSize; + switch (pMsg->MsgId) { + case APP_INIT: + if ((xAdd == 0) && (yAdd == 0)) { + xAdd = 0; + yAdd = 2; + } + case APP_TIMER: + xSizeBmp = _bmMap_400x320.XSize; + ySizeBmp = _bmMap_400x320.YSize; + if (xAdd < 0) { + if (xPos <= (xSize - xSizeBmp)) { + xAdd = 0; + yAdd = -2; + } + } else if (yAdd < 0) { + if (yPos <= (ySize - ySizeBmp)) { + xAdd = 2; + yAdd = 0; + } + } else if (xAdd > 0) { + if (xPos >= 0) { + xAdd = 0; + yAdd = 2; + } + } else if (yAdd > 0) { + if (yPos >= 0) { + xAdd = -2; + yAdd = 0; + } + } + if (xSize < xSizeBmp) { + xPos += xAdd; + } + if (ySize < ySizeBmp) { + yPos += yAdd; + } + WM_InvalidateWindow(hWin); + break; + case WM_PAINT: + GUI_SetBkColor(GUI_WHITE); + if (xSize > xSizeBmp) { + xPos = (xSize - xSizeBmp) >> 1; + } + if (ySize > ySizeBmp) { + yPos = (ySize - ySizeBmp) >> 1; + } + GUI_DrawBitmap(&_bmMap_400x320, xPos, yPos); + if (xPos) { + GUI_ClearRect(0, 0, xPos - 1, ySize - 1); + } + if ((xPos + xSizeBmp) < xSize) { + GUI_ClearRect(xPos + xSizeBmp, 0, xSize - 1, ySize - 1); + } + if (yPos) { + GUI_ClearRect(xPos, 0, xPos + xSizeBmp - 1, yPos - 1); + } + if ((yPos + ySizeBmp) < ySize) { + GUI_ClearRect(xPos, yPos + ySizeBmp, xPos + xSizeBmp - 1, ySize - 1); + } + break; + } +} + +/********************************************************************* +* +* _OnValueChanged +*/ +static void _OnValueChanged(WM_HWIN hDlg, int Id) { + WM_HWIN hItem; + int Value; + hItem = WM_GetDialogItem(hDlg, Id); + Value = SLIDER_GetValue(hItem); + switch (Id) { + case GUI_ID_SLIDER0: + _Alpha_0 = Value; + WM_InvalidateWindow(hDlg); + break; + case GUI_ID_SLIDER1: + _Alpha_1 = Value; + WM_InvalidateWindow(WM_GetParent(hDlg)); + break; + } +} + +/********************************************************************* +* +* _cbClient +* +* Purpose: +* Callback routine of property dialog +*/ +static void _cbClient(WM_MESSAGE * pMsg) { + WM_HWIN hDlg, hItem; + int NCode, Id; + hDlg = pMsg->hWin; + switch (pMsg->MsgId) { + case WM_INIT_DIALOG: + hItem = WM_GetDialogItem(hDlg, GUI_ID_SLIDER0); + SLIDER_SetRange(hItem, 0, 255); + SLIDER_SetValue(hItem, _Alpha_0); + hItem = WM_GetDialogItem(hDlg, GUI_ID_SLIDER1); + SLIDER_SetRange(hItem, 0, 255); + SLIDER_SetValue(hItem, _Alpha_1); + break; + case WM_NOTIFY_PARENT: + Id = WM_GetId(pMsg->hWinSrc); // Id of widget + NCode = pMsg->Data.v; // Notification code + switch (NCode) { + case WM_NOTIFICATION_VALUE_CHANGED: // Value has changed + _OnValueChanged(hDlg, Id); + break; + } + break; + case WM_PAINT: + GUI_SetAlpha(_Alpha_0); // Set alpha value for drawing operations + GUI_SetBkColor(0xAAAAAA); // Draw gray background... + GUI_Clear(); // ...with alpha blending + GUI_SetAlpha(0); // Set alpha value to default + return; + } + if (_pcbClient) { + _pcbClient(pMsg); + } +} + +/********************************************************************* +* +* _cbFrame +* +* Purpose: +* Callback routine of frame window +*/ +static void _cbFrame(WM_MESSAGE * pMsg) { + switch (pMsg->MsgId) { + case WM_PAINT: + GUI_SetAlpha(_Alpha_1); + break; + } + FRAMEWIN_Callback(pMsg); + GUI_SetAlpha(0); +} + +/********************************************************************* +* +* _TransparentDialog +*/ +static void _TransparentDialog(void) { + WM_HWIN hFrame, hClient, hSlider0, hSlider1; + int xSize, TimeNow, TimeNext, TimeStart, TimeUsed, Value; + const GUI_FONT GUI_UNI_PTR * pFontOld; + WM_CALLBACK * pCbOld; + + xSize = LCD_GetXSize(); + // + // Set default properties + // + FRAMEWIN_SetDefaultFont(&GUI_FontComic18B_ASCII); + FRAMEWIN_SetDefaultTextAlign(GUI_TA_CENTER); + FRAMEWIN_SetDefaultBarColor(0, GUI_MAGENTA); + FRAMEWIN_SetDefaultBarColor(1, GUI_MAGENTA); + pFontOld = TEXT_GetDefaultFont(); + TEXT_SetDefaultFont(&GUI_FontComic18B_ASCII); + TEXT_SetDefaultTextColor(GUI_BLUE); + // + // Create window with moving map + // + pCbOld = WM_SetCallback(WM_HBKWIN, _cbWin); + WM_SendMessageNoPara(WM_HBKWIN, APP_INIT); + // + // Create dialog + // + hFrame = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), 0, 0, (xSize - 220) / 2, 55); + WM_SetHasTrans(hFrame); // Set transparency + WM_SetCallback(hFrame, _cbFrame); // Overwrite callback + // + // Set client attributes + // + hClient = WM_GetClientWindow(hFrame); // Get handle of client window + WM_SetHasTrans(hClient); // Set transparency + _pcbClient = WM_SetCallback(hClient, _cbClient); // Overwrite callback + WM_SendMessageNoPara(hClient, WM_INIT_DIALOG); // Send WM_INIT_DIALOG + // + // Get slider handles + // + hSlider0 = WM_GetDialogItem(WM_GetClientWindow(hFrame), GUI_ID_SLIDER0); + hSlider1 = WM_GetDialogItem(WM_GetClientWindow(hFrame), GUI_ID_SLIDER1); + // + // Loop + // + TimeStart= GUIDEMO_GetTime(); + TimeNext = TimeStart + PERIOD; + do { + GUI_Delay(1); + TimeNow = GUIDEMO_GetTime(); + TimeUsed = TimeNow - TimeStart; + if (TimeNow >= TimeNext) { + TimeNext = TimeNow + PERIOD; + WM_SendMessageNoPara(WM_HBKWIN, APP_TIMER); + TimeUsed = TimeUsed % (DURATION / 2); + if (TimeUsed < (DURATION / 4)) { + Value = (TimeUsed * 255 * 4) / DURATION; + } else { + Value = 255 - ((TimeUsed - (DURATION / 4)) * 255 * 4) / DURATION; + } + SLIDER_SetValue(hSlider0, Value); + SLIDER_SetValue(hSlider1, 255 - Value); + } + } while (((GUIDEMO_GetTime() - TimeStart) < DURATION) && (GUIDEMO_CheckCancel() == 0)); + // + // Free memory + // + WM_DeleteWindow(hFrame); + // + // Set default values + // + FRAMEWIN_SetDefaultFont(&GUI_Font8_1); + FRAMEWIN_SetDefaultTextAlign(GUI_TA_LEFT); + FRAMEWIN_SetDefaultBarColor(0, 0x404040); + FRAMEWIN_SetDefaultBarColor(1, GUI_BLUE); + TEXT_SetDefaultFont(pFontOld); + TEXT_SetDefaultTextColor(GUI_BLACK); + WM_SetCallback(WM_HBKWIN, pCbOld); +} + +/********************************************************************* +* +* Public code +* +********************************************************************** +*/ +/********************************************************************* +* +* GUIDEMO_TransparentDialog +*/ +void GUIDEMO_TransparentDialog(void) { + _TransparentDialog(); +} + +#else + +void GUIDEMO_TransparentDialog(void) {} + +#endif + +/*************************** End of file ****************************/ diff --git a/example/GUI/core/GUI_init.c b/example/GUI/core/GUI_init.c new file mode 100755 index 0000000000..61d0babe5a --- /dev/null +++ b/example/GUI/core/GUI_init.c @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/********************************************************************* +* SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2017 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.40 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GUIConf.c +Purpose : Display controller initialization +---------------------------END-OF-HEADER------------------------------ +*/ + +/** + ****************************************************************************** + * @attention + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * 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. + * + ****************************************************************************** + */ + +/** +* @brief BSP_Background. +* @param None +* @retval None +*/ + +#include "soc_init.h" +#include "stdint.h" +#include "errno.h" +#include "WM.h" +#include "stm32l4xx_hal.h" + +#if defined(__ICCARM__) +#include "sys/errno.h" +#endif + +uint8_t GUI_Initialized = 0; +static void IO_Init(void); + +/** + * @brief Initializes the STM32L496G-Discovery's LCD and LEDs resources. + * @param None + * @retval None + */ +void BSP_GUI_init(void) +{ + /*## LCD Configuration ##################################################*/ + /* I/O initialization, required before LCD initialization */ + IO_Init(); + + /* LCD initialization */ + // BSP_LCD_Init(); + + /* Enable the CRC Module */ + __HAL_RCC_CRC_CLK_ENABLE(); + + /* Init the STemWin GUI Library */ + GUI_Init(); + GUI_Initialized = 1; + + /* Activate the use of memory device feature */ + WM_SetCreateFlags(WM_CF_MEMDEV); +} + +/** + * @brief IO initialization. + * @note GPIO PH.00 setting to activate STM32L496 Discovery I/Os + * and I/O initialization. + * @retval None + */ +static void IO_Init(void) +{ + GPIO_InitTypeDef GPIO_InitStruct; + + __HAL_RCC_GPIOH_CLK_ENABLE(); + + GPIO_InitStruct.Pin = GPIO_PIN_0; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Alternate = 0; + GPIO_InitStruct.Speed = GPIO_SPEED_LOW; + + HAL_GPIO_Init( GPIOH, &GPIO_InitStruct ); + + HAL_GPIO_WritePin( GPIOH, GPIO_PIN_0, GPIO_PIN_RESET); +} + +/*************************** End of file ****************************/ diff --git a/example/GUI/core/include/GUIDEMO.h b/example/GUI/core/include/GUIDEMO.h new file mode 100755 index 0000000000..4873be7a62 --- /dev/null +++ b/example/GUI/core/include/GUIDEMO.h @@ -0,0 +1,329 @@ +/********************************************************************* +* Portions COPYRIGHT 2013 STMicroelectronics * +* Portions SEGGER Microcontroller GmbH & Co. KG * +* Solutions for real time microcontroller applications * +********************************************************************** +* * +* (c) 1996 - 2013 SEGGER Microcontroller GmbH & Co. KG * +* * +* Internet: www.segger.com Support: support@segger.com * +* * +********************************************************************** + +** emWin V5.22 - Graphical user interface for embedded applications ** +All Intellectual Property rights in the Software belongs to SEGGER. +emWin is protected by international copyright laws. Knowledge of the +source code may not be used to write a similar product. This file may +only be used in accordance with the following terms: + +The software has been licensed to STMicroelectronics International +N.V. a Dutch company with a Swiss branch and its headquarters in Plan- +les-Ouates, Geneva, 39 Chemin du Champ des Filles, Switzerland for the +purposes of creating libraries for ARM Cortex-M-based 32-bit microcon_ +troller products commercialized by Licensee only, sublicensed and dis_ +tributed under the terms and conditions of the End User License Agree_ +ment supplied by STMicroelectronics International N.V. +Full source code is available at: www.segger.com + +We appreciate your understanding and fairness. +---------------------------------------------------------------------- +File : GUIDEMO.h +Purpose : Configuration file of GUIDemo +---------------------------------------------------------------------- +*/ + +/** + ****************************************************************************** + * @file GUIDEMO.c + * @author MCD Application Team + * @brief Configuration file of GUIDemo + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + + +#ifndef GUIDEMO_H +#define GUIDEMO_H + +#if defined(__cplusplus) +extern "C" { /* Make sure we have C-declarations in C++ programs */ +#endif + +#include "GUI.h" + +#if GUI_WINSUPPORT + #include "WM.h" + +// #include "CHECKBOX.h" + #include "FRAMEWIN.h" + #include "PROGBAR.h" + #include "TEXT.h" +// #include "BUTTON.h" + #include "SLIDER.h" +// #include "HEADER.h" + #include "GRAPH.h" +// #include "ICONVIEW.h" +// #include "LISTVIEW.h" +// #include "TREEVIEW.h" +#endif + +/********************************************************************* +* +* Defines +* +********************************************************************** +*/ +#define CONTROL_SIZE_X 80 +#define CONTROL_SIZE_Y 48 +#define INFO_SIZE_Y 65 +#define BUTTON_SIZE_X 32 +#define BUTTON_SIZE_Y 20 +#define PROGBAR_SIZE_X 66 +#define PROGBAR_SIZE_Y 12 +#define TEXT_SIZE_X 69 +#define TEXT_SIZE_Y 7 +#define SHOW_PROGBAR_AT 100 +#define GUI_ID_HALT (GUI_ID_USER + 0) +#define GUI_ID_NEXT (GUI_ID_USER + 1) + +#define BK_COLOR_0 0xFF5555 +#define BK_COLOR_1 0x880000 + +#define NUMBYTES_NEEDED 0x200000 + +#define CIRCLE_RADIUS 100 + +#define LOGO_DIST_BORDER 5 + +#define CHAR_READING_TIME 80 + +/********************************************************************* +* +* Configuration of modules to be used +* +********************************************************************** +*/ + +#ifndef SHOW_GUIDEMO_BITMAP + #define SHOW_GUIDEMO_BITMAP (1) +#endif + +#ifndef SHOW_GUIDEMO_COLORBAR + #define SHOW_GUIDEMO_COLORBAR (1) +#endif + +#ifndef SHOW_GUIDEMO_CURSOR + #define SHOW_GUIDEMO_CURSOR (1) +#endif + +#ifndef SHOW_GUIDEMO_GRAPH + #define SHOW_GUIDEMO_GRAPH (1) +#endif + +#ifndef SHOW_GUIDEMO_LISTVIEW + #define SHOW_GUIDEMO_LISTVIEW (1) +#endif + +#ifndef SHOW_GUIDEMO_SPEED + #define SHOW_GUIDEMO_SPEED (1) +#endif + +#ifndef SHOW_GUIDEMO_TREEVIEW + #define SHOW_GUIDEMO_TREEVIEW (1) +#endif + +#ifndef SHOW_GUIDEMO_ICONVIEW + #define SHOW_GUIDEMO_ICONVIEW (1) +#endif + +#ifndef SHOW_GUIDEMO_RADIALMENU + #define SHOW_GUIDEMO_RADIALMENU (0) +#endif + +#ifndef SHOW_GUIDEMO_VSCREEN + #define SHOW_GUIDEMO_VSCREEN (0) +#endif + +#ifndef SHOW_GUIDEMO_AUTOMOTIVE + #define SHOW_GUIDEMO_AUTOMOTIVE (1) +#endif + +#ifndef SHOW_GUIDEMO_TRANSPARENTDIALOG + #define SHOW_GUIDEMO_TRANSPARENTDIALOG (1) +#endif + +#ifndef SHOW_GUIDEMO_AATEXT + #define SHOW_GUIDEMO_AATEXT (0) +#endif + +#ifndef SHOW_GUIDEMO_BARGRAPH + #define SHOW_GUIDEMO_BARGRAPH (1) +#endif + +#ifndef SHOW_GUIDEMO_FADING + #define SHOW_GUIDEMO_FADING (0) +#endif + +#ifndef SHOW_GUIDEMO_SKINNING + #define SHOW_GUIDEMO_SKINNING (0) +#endif + +#ifndef SHOW_GUIDEMO_SPEEDOMETER + #define SHOW_GUIDEMO_SPEEDOMETER (0) +#endif + +#ifndef SHOW_GUIDEMO_IMAGEFLOW + #define SHOW_GUIDEMO_IMAGEFLOW (0) +#endif + +/********************************************************************* +* +* Configuration macros +* +********************************************************************** +*/ +#ifndef GUIDEMO_SHOW_SPRITES + #define GUIDEMO_SHOW_SPRITES (1) +#endif +#ifndef GUIDEMO_USE_VNC + #define GUIDEMO_USE_VNC (0) +#endif +#ifndef GUIDEMO_USE_AUTO_BK + #define GUIDEMO_USE_AUTO_BK (1) +#endif + +#define GUIDEMO_CF_SHOW_SPRITES (GUIDEMO_SHOW_SPRITES << 0) +#define GUIDEMO_CF_USE_VNC (GUIDEMO_USE_VNC << 1) +#define GUIDEMO_CF_USE_AUTO_BK (GUIDEMO_USE_AUTO_BK << 2) + +/********************************************************************* +* +* GUIDEMO_CONFIG +*/ +typedef struct GUIDEMO_CONFIG { + void (* * apFunc)(void); + int NumDemos; + U16 Flags; + #if GUIDEMO_USE_VNC + int (* pGUI_VNC_X_StartServer)(int LayerIndex, int ServerIndex); + #endif +} GUIDEMO_CONFIG; + +/********************************************************************* +* +* Internal functions +* +********************************************************************** +*/ +void GUIDEMO_AddIntToString (char * acText, unsigned int Number); +void GUIDEMO_AddStringToString(char * acText, const char * acAdd); +int GUIDEMO_CheckCancel (void); +void GUIDEMO_ClearText (char * acText); +void GUIDEMO_Config (GUIDEMO_CONFIG * pConfig); +void GUIDEMO_Delay (int t); +void GUIDEMO_DrawBk (int DrawLogo); +U16 GUIDEMO_GetConfFlag (U16 Flag); +int GUIDEMO_GetTime (void); +void GUIDEMO_HideControlWin (void); +void GUIDEMO_HideInfoWin (void); +void GUIDEMO_NotifyStartNext (void); +void GUIDEMO_SetDrawLogo (U8 OnOff); +void GUIDEMO_ShowControlWin (void); +void GUIDEMO_ShowInfo (const char * acInfo); +void GUIDEMO_ShowInfoWin (void); +void GUIDEMO_ShowIntro (const char * acText, const char * acDescription); +void GUIDEMO_UpdateControlText(void); +void GUIDEMO_Wait (int TimeWait); +void GUIDEMO_Main (void); + +/********************************************************************* +* +* Demo modules +* +********************************************************************** +*/ +void GUIDEMO_AntialiasedText (void); +void GUIDEMO_Automotive (void); +void GUIDEMO_BarGraph (void); +void GUIDEMO_Bitmap (void); +void GUIDEMO_ColorBar (void); +void GUIDEMO_Cursor (void); +void GUIDEMO_Fading (void); +void GUIDEMO_Graph (void); +void GUIDEMO_IconView (void); +void GUIDEMO_ImageFlow (void); +void GUIDEMO_Intro (void); +void GUIDEMO_Intro1 (void); +void GUIDEMO_Listview (void); +void GUIDEMO_RadialMenu (void); +void GUIDEMO_Skinning (void); +void GUIDEMO_Speed (void); +void GUIDEMO_Speedometer (void); +void GUIDEMO_TransparentDialog(void); +void GUIDEMO_Treeview (void); +void GUIDEMO_VScreen (void); +void GUIDEMO_WashingMachine (void); +void GUIDEMO_ZoomAndRotate (void); + +/********************************************************************* +* +* Externs +* +********************************************************************** +*/ +//extern GUI_CONST_STORAGE GUI_BITMAP bmSTLogo; +//extern GUI_CONST_STORAGE GUI_BITMAP bmSeggerLogo; +//extern GUI_CONST_STORAGE GUI_BITMAP bmSeggerLogo70x35; +extern GUI_CONST_STORAGE GUI_BITMAP bmSTLogo70x35; + +extern GUI_CONST_STORAGE GUI_FONT GUI_FontRounded16; +extern GUI_CONST_STORAGE GUI_FONT GUI_FontRounded22; +//extern GUI_CONST_STORAGE GUI_FONT GUI_FontSouvenir18; +extern GUI_CONST_STORAGE GUI_FONT GUI_FontD6x8; +extern GUI_CONST_STORAGE GUI_FONT GUI_FontAA2_32; +extern GUI_CONST_STORAGE GUI_FONT GUI_FontAA4_32; + + +#if defined(__cplusplus) + } +#endif + +#endif // avoid multiple inclusion + +/*************************** End of file ****************************/ diff --git a/example/GUI/core/include/GUI_init.h b/example/GUI/core/include/GUI_init.h new file mode 100755 index 0000000000..eb5db6aaa7 --- /dev/null +++ b/example/GUI/core/include/GUI_init.h @@ -0,0 +1,61 @@ +/** + ****************************************************************************** + * @file GUI_init.h + * @author MCD Application Team + * @brief Header for main.c module + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __GUI_INIT_H +#define __GUI_INIT_H + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l4xx_hal.h" +#include "GUI.h" + +void BSP_GUI_init(void); + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +#endif /* __GUI_INIT_H*/ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/example/GUI/core/include/tsConf.h b/example/GUI/core/include/tsConf.h new file mode 100755 index 0000000000..06f2773cbd --- /dev/null +++ b/example/GUI/core/include/tsConf.h @@ -0,0 +1,62 @@ +/** + ****************************************************************************** + * @file tsConf.h + * @author MCD Application Team + * @brief Header for main.c module + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __TSCONF_H +#define __TSCONF_H + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l4xx_hal.h" +#include "GUI.h" +#include "calibration.h" + +void ts_update(void); + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +#endif /* __TSCONF_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/example/GUI/main.c b/example/GUI/main.c new file mode 100755 index 0000000000..60b3dc88f4 --- /dev/null +++ b/example/GUI/main.c @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#include +#include +#include +#include "GUIDEMO.h" + +#define DEMO_TASK_STACKSIZE 512 //512*cpu_stack_t = 2048byte +#define DEMO_TASK_PRIORITY 20 + +extern void stm32_soc_init(void); +static ktask_t demo_task_obj; +cpu_stack_t demo_task_buf[DEMO_TASK_STACKSIZE]; + +void demo_task(void *arg) +{ + int count = 0; + printf("demo_task here!\n"); + + GUIDEMO_Main(); + + while (1) + { + printf("hello world! count %d\n", count++); + //sleep 1 second + krhino_task_sleep(RHINO_CONFIG_TICKS_PER_SECOND); + }; +} + +int main(void) +{ + krhino_init(); + krhino_task_create(&demo_task_obj, "demo_task", 0,DEMO_TASK_PRIORITY, + 50, demo_task_buf, DEMO_TASK_STACKSIZE, demo_task, 1); + + //uart init + stm32_soc_init(); + + krhino_start(); + + return 0; +} + diff --git a/example/alinkapp/alinkapp.mk b/example/alinkapp/alinkapp.mk index 1aacc66150..c687540fa5 100644 --- a/example/alinkapp/alinkapp.mk +++ b/example/alinkapp/alinkapp.mk @@ -13,14 +13,9 @@ LWIP = 1 endif ifeq ($(sal),1) -$(NAME)_COMPONENTS += sal gateway := 0 endif -ifneq (,$(module)) -$(NAME)_COMPONENTS += sal.$(module) -endif - ifneq (,$(filter linux,$(HOST_MCU_FAMILY))) gateway ?= 0 else diff --git a/example/atapp/atapp.c b/example/atapp/atapp.c index d36f7e3632..6ea4bbd4a5 100644 --- a/example/atapp/atapp.c +++ b/example/atapp/atapp.c @@ -13,7 +13,7 @@ #include #include #ifdef AOS_AT_ADAPTER -#include +#include #include #endif #include "atapp.h" @@ -102,12 +102,12 @@ static void at_enet_helper(void *arg) goto end; } - fd = lwip_socket(PF_INET, SOCK_DGRAM, 0); + fd = socket(PF_INET, SOCK_DGRAM, 0); memset(&saddr, 0, sizeof(saddr)); saddr.sin_family = AF_INET; saddr.sin_port = htons(port); saddr.sin_addr.s_addr = inet_addr(info->ip); - ret = lwip_sendto(fd, info->data, info->len, 0, + ret = sendto(fd, info->data, info->len, 0, (struct sockaddr *)&saddr, sizeof(saddr)); if (ret < 0) printf("Error: sendto failed\r\n"); @@ -115,7 +115,7 @@ static void at_enet_helper(void *arg) fd, saddr.sin_addr.s_addr, saddr.sin_port); while (1) { - if((num = lwip_recvfrom(fd, buf, MAXDATASIZE, 0, + if((num = recvfrom(fd, buf, MAXDATASIZE, 0, (struct sockaddr *)&recvaddr, &addrlen)) < 0) { printf("recvfrom() error\n"); break; @@ -136,7 +136,7 @@ static void at_enet_helper(void *arg) break; } - lwip_close(fd); + close(fd); end: if (info) { diff --git a/example/bleapp/README b/example/bleapp/README deleted file mode 100644 index a4b2559cf8..0000000000 --- a/example/bleapp/README +++ /dev/null @@ -1,2 +0,0 @@ - -This is a BLE adv example using *ESP32* BLE stack. diff --git a/example/bleapp/bleapp.mk b/example/bleapp/bleapp.mk deleted file mode 100644 index efdad44280..0000000000 --- a/example/bleapp/bleapp.mk +++ /dev/null @@ -1,12 +0,0 @@ -NAME := bleapp - -$(NAME)_SOURCES := main.c - -GLOBAL_DEFINES += AOS_NO_WIFI - -$(NAME)_COMPONENTS := yloop cli - -CURRENT_TIME = $(shell /bin/date +%Y%m%d.%H%M) -CONFIG_SYSINFO_APP_VERSION = APP-1.0.0-$(CURRENT_TIME) -$(info app_version:${CONFIG_SYSINFO_APP_VERSION}) -GLOBAL_CFLAGS += -DSYSINFO_APP_VERSION=\"$(CONFIG_SYSINFO_APP_VERSION)\" diff --git a/example/bleapp/main.c b/example/bleapp/main.c deleted file mode 100644 index 0a42203c3b..0000000000 --- a/example/bleapp/main.c +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#include -#include -#include - -#include "bt.h" -#include "nvs_flash.h" - -#define HCI_H4_CMD_PREAMBLE_SIZE (4) - -/* HCI Command opcode group field(OGF) */ -#define HCI_GRP_HOST_CONT_BASEBAND_CMDS (0x03 << 10) /* 0x0C00 */ -#define HCI_GRP_BLE_CMDS (0x08 << 10) - -#define HCI_RESET (0x0003 | HCI_GRP_HOST_CONT_BASEBAND_CMDS) -#define HCI_BLE_WRITE_ADV_ENABLE (0x000A | HCI_GRP_BLE_CMDS) -#define HCI_BLE_WRITE_ADV_PARAMS (0x0006 | HCI_GRP_BLE_CMDS) -#define HCI_BLE_WRITE_ADV_DATA (0x0008 | HCI_GRP_BLE_CMDS) - -#define HCIC_PARAM_SIZE_WRITE_ADV_ENABLE (1) -#define HCIC_PARAM_SIZE_BLE_WRITE_ADV_PARAMS (15) -#define HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA (31) - -#define BD_ADDR_LEN (6) /* Device address length */ -typedef uint8_t bd_addr_t[BD_ADDR_LEN]; /* Device address */ - -#define UINT16_TO_STREAM(p, u16) {*(p)++ = (uint8_t)(u16); *(p)++ = (uint8_t)((u16) >> 8);} -#define UINT8_TO_STREAM(p, u8) {*(p)++ = (uint8_t)(u8);} -#define BDADDR_TO_STREAM(p, a) {int ijk; for (ijk = 0; ijk < BD_ADDR_LEN; ijk++) *(p)++ = (uint8_t) a[BD_ADDR_LEN - 1 - ijk];} -#define ARRAY_TO_STREAM(p, a, len) {int ijk; for (ijk = 0; ijk < len; ijk++) *(p)++ = (uint8_t) a[ijk];} - -enum { - H4_TYPE_COMMAND = 1, - H4_TYPE_ACL = 2, - H4_TYPE_SCO = 3, - H4_TYPE_EVENT = 4 -}; - -static uint8_t hci_cmd_buf[128]; - -static void controller_rcv_pkt_ready(void) -{ - printf("controller rcv pkt ready\n"); -} - -static int host_rcv_pkt(uint8_t *data, uint16_t len) -{ - printf("host rcv pkt: "); - for (uint16_t i = 0; i < len; i++) { - printf("%02x", data[i]); - } - printf("\n"); - return 0; -} - -static esp_vhci_host_callback_t vhci_host_cb = { - controller_rcv_pkt_ready, - host_rcv_pkt -}; - -static uint16_t make_cmd_reset(uint8_t *buf) -{ - UINT8_TO_STREAM (buf, H4_TYPE_COMMAND); - UINT16_TO_STREAM (buf, HCI_RESET); - UINT8_TO_STREAM (buf, 0); - return HCI_H4_CMD_PREAMBLE_SIZE; -} - -static uint16_t make_cmd_ble_set_adv_enable (uint8_t *buf, uint8_t adv_enable) -{ - UINT8_TO_STREAM (buf, H4_TYPE_COMMAND); - UINT16_TO_STREAM (buf, HCI_BLE_WRITE_ADV_ENABLE); - UINT8_TO_STREAM (buf, HCIC_PARAM_SIZE_WRITE_ADV_ENABLE); - UINT8_TO_STREAM (buf, adv_enable); - return HCI_H4_CMD_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_ADV_ENABLE; -} - -static uint16_t make_cmd_ble_set_adv_param (uint8_t *buf, uint16_t adv_int_min, uint16_t adv_int_max, - uint8_t adv_type, uint8_t addr_type_own, - uint8_t addr_type_dir, bd_addr_t direct_bda, - uint8_t channel_map, uint8_t adv_filter_policy) -{ - UINT8_TO_STREAM (buf, H4_TYPE_COMMAND); - UINT16_TO_STREAM (buf, HCI_BLE_WRITE_ADV_PARAMS); - UINT8_TO_STREAM (buf, HCIC_PARAM_SIZE_BLE_WRITE_ADV_PARAMS ); - - UINT16_TO_STREAM (buf, adv_int_min); - UINT16_TO_STREAM (buf, adv_int_max); - UINT8_TO_STREAM (buf, adv_type); - UINT8_TO_STREAM (buf, addr_type_own); - UINT8_TO_STREAM (buf, addr_type_dir); - BDADDR_TO_STREAM (buf, direct_bda); - UINT8_TO_STREAM (buf, channel_map); - UINT8_TO_STREAM (buf, adv_filter_policy); - return HCI_H4_CMD_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_WRITE_ADV_PARAMS; -} - -static uint16_t make_cmd_ble_set_adv_data(uint8_t *buf, uint8_t data_len, uint8_t *p_data) -{ - UINT8_TO_STREAM (buf, H4_TYPE_COMMAND); - UINT16_TO_STREAM (buf, HCI_BLE_WRITE_ADV_DATA); - UINT8_TO_STREAM (buf, HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA + 1); - - memset(buf, 0, HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA); - - if (p_data != NULL && data_len > 0) { - if (data_len > HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA) { - data_len = HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA; - } - - UINT8_TO_STREAM (buf, data_len); - - ARRAY_TO_STREAM (buf, p_data, data_len); - } - return HCI_H4_CMD_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA + 1; -} - -static void hci_cmd_send_reset(void) -{ - uint16_t sz = make_cmd_reset (hci_cmd_buf); - esp_vhci_host_send_packet(hci_cmd_buf, sz); -} - -static void hci_cmd_send_ble_adv_start(void) -{ - uint16_t sz = make_cmd_ble_set_adv_enable (hci_cmd_buf, 1); - esp_vhci_host_send_packet(hci_cmd_buf, sz); -} - -static void hci_cmd_send_ble_set_adv_param(void) -{ - uint16_t adv_intv_min = 256; // 160ms - uint16_t adv_intv_max = 256; // 160ms - uint8_t adv_type = 0; // connectable undirected advertising (ADV_IND) - uint8_t own_addr_type = 0; // Public Device Address - uint8_t peer_addr_type = 0; // Public Device Address - uint8_t peer_addr[6] = {0x80, 0x81, 0x82, 0x83, 0x84, 0x85}; - uint8_t adv_chn_map = 0x07; // 37, 38, 39 - uint8_t adv_filter_policy = 0; // Process All Conn and Scan - - uint16_t sz = make_cmd_ble_set_adv_param(hci_cmd_buf, - adv_intv_min, - adv_intv_max, - adv_type, - own_addr_type, - peer_addr_type, - peer_addr, - adv_chn_map, - adv_filter_policy); - esp_vhci_host_send_packet(hci_cmd_buf, sz); -} - -static void hci_cmd_send_ble_set_adv_data(void) -{ - char *adv_name = "AOS-ESP-BLE-HELLO"; - uint8_t name_len = (uint8_t)strlen(adv_name); - uint8_t adv_data[31] = {0x02, 0x01, 0x06, 0x0, 0x09}; - uint8_t adv_data_len; - - adv_data[3] = name_len + 1; - for (int i = 0; i < name_len; i++) { - adv_data[5 + i] = (uint8_t)adv_name[i]; - } - adv_data_len = 5 + name_len; - - uint16_t sz = make_cmd_ble_set_adv_data(hci_cmd_buf, adv_data_len, (uint8_t *)adv_data); - esp_vhci_host_send_packet(hci_cmd_buf, sz); -} - -static void ble_adv_action(void *arg) -{ - static int cmd_cnt = 0; - bool send_avail = false; - - send_avail = esp_vhci_host_check_send_available(); - if (send_avail) { - switch (cmd_cnt) { - case 0: - hci_cmd_send_reset(); - (++cmd_cnt) % 4; - break; - case 1: - hci_cmd_send_ble_set_adv_param(); - (++cmd_cnt) % 4; - break; - case 2: - hci_cmd_send_ble_set_adv_data(); - (++cmd_cnt) % 4; - break; - case 3: - hci_cmd_send_ble_adv_start(); - (++cmd_cnt) % 4; - break; - } - } - printf("BLE Advertise, flag_send_avail: %d, cmd_sent: %d\n", send_avail, cmd_cnt); - aos_post_delayed_action(1000, ble_adv_action, NULL); -} - -static void app_delayed_action(void *arg) -{ - esp_err_t ret = nvs_flash_init(); - if (ret == ESP_ERR_NVS_NO_FREE_PAGES) { - ESP_ERROR_CHECK(nvs_flash_erase()); - ret = nvs_flash_init(); - } - ESP_ERROR_CHECK( ret ); - esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); - - if (esp_bt_controller_init(&bt_cfg) != ESP_OK) { - printf("Bluetooth controller initialize failed\r\n"); - return; - } - - if (esp_bt_controller_enable(ESP_BT_MODE_BTDM) != ESP_OK) { - printf("Bluetooth controller enable failed\r\n"); - return; - } - - esp_vhci_host_register_callback(&vhci_host_cb); - aos_post_delayed_action(1000, ble_adv_action, NULL); -} - -int application_start(int argc, char **argv) -{ - aos_post_delayed_action(1000, app_delayed_action, NULL); - aos_loop_run(); - return 0; -} - diff --git a/example/bluetooth/ble_advertisements/ReadMe.md b/example/bluetooth/ble_advertisements/ReadMe.md deleted file mode 100644 index 3ae9661825..0000000000 --- a/example/bluetooth/ble_advertisements/ReadMe.md +++ /dev/null @@ -1,2 +0,0 @@ -# READ ME -------------------------------------------------------------------------------- diff --git a/example/bluetooth/ble_advertisements/ble_advertisements.c b/example/bluetooth/ble_advertisements/ble_advertisements.c index 6f479f4ff8..55566efc7e 100644 --- a/example/bluetooth/ble_advertisements/ble_advertisements.c +++ b/example/bluetooth/ble_advertisements/ble_advertisements.c @@ -2,107 +2,42 @@ * Copyright (C) 2015-2017 Alibaba Group Holding Limited */ -#include -#include "sdpdefs.h" -#include "smartbt_cfg.h" -#include "smartbt.h" -#include "smartbt_peripheral.h" +#include -#include "ble_advertisements.h" - -#define MANUFACTURER "BleTestManufacturer" -#define MODEL "BleTestModel" - -//#define printf(M, ...) custom_log( "LE ADVERT", M, ##__VA_ARGS__ ) - -/****************************************************************************** - * Constants - ******************************************************************************/ - -/****************************************************************************** - * Function Prototypes - ******************************************************************************/ - -static void hello_sensor_change_advertisements( CLI_ARGS ); -static void hello_sensor_change_filter_policy ( CLI_ARGS ); -static void hello_sensor_get_whitelist_size ( CLI_ARGS ); - -static void hello_sensor_start_advertisements( void ); -static void hello_sensor_stop_advertisements( void ); - -#ifdef USE_AOSKit_EXT -static const char *pBT_ShortStr( aos_bt_smart_advertising_type_t type ); -#endif - -static const char *pBT_AdvertStr( aos_bt_smart_advertising_type_t type ); - -/****************************************************************************** - * Structures - ******************************************************************************/ +static int connection_handler() +{ -/* Peripheral auto advertising settings */ -static aos_bt_smart_advertising_settings_t advertising_settings = { - .type = BT_SMART_UNDIRECTED_ADVERTISING, /**< Advertising type */ - .use_high_duty = AOS_TRUE, /**< Using high duty to start advertising */ - .high_duty_interval = AOS_BT_CFG_DEFAULT_HIGH_DUTY_ADV_MIN_INTERVAL, /**< High duty advertising interval */ - .high_duty_duration = 5, /**< High duty advertising duration in seconds (0 for infinite) */ - .low_duty_interval = AOS_BT_CFG_DEFAULT_LOW_DUTY_ADV_MIN_INTERVAL, /**< Low duty advertising interval */ - .low_duty_duration = 60, /**< Low duty advertising duration in seconds (0 for infinite) */ +} - /* Used Directed Advertisement */ - .directed_advertisement_addr_type = BT_SMART_ADDR_TYPE_PUBLIC, - .directed_advertisement_addr = { 11, 22, 33, 44, 55, 66 }, -}; +static int disconnection_handler() +{ -/* Peripheral security settings */ -static const aos_bt_smart_security_settings_t security_settings = { - .timeout_second = 15, - .io_capabilities = BT_SMART_IO_DISPLAY_ONLY, - .authentication_requirements = BT_SMART_AUTH_REQ_BONDING, - .oob_authentication = BT_SMART_OOB_AUTH_NONE, - .max_encryption_key_size = 16, - .master_key_distribution = BT_SMART_DISTRIBUTE_ALL_KEYS, - .slave_key_distribution = BT_SMART_DISTRIBUTE_ALL_KEYS, -}; +} -struct cli_command hello_sensor_send_message_cmd[] = { - { - "advert", - " <0:Generic undirected/1:Discoverable advertising/2:Directed/3:Non-connectable Undirected> <0:Low Duty/1:High Duty>", - hello_sensor_change_advertisements - }, - { - "policy", - "<0:Not use white list/1:filter all connection request and whitelist scan reuqest/2:filter whitelist connection request and all scan request/3:filter whitelist connection request and whitelist scan request>", - hello_sensor_change_filter_policy - }, - { - "wlsize", - "Get the number of devices in the white list", - hello_sensor_get_whitelist_size - } -}; +typedef enum { + HDLS_GENERIC_ATTRIBUTE = 0x1, + HDLC_GENERIC_ATTRIBUTE_SERVICE_CHANGED, + HDLC_GENERIC_ATTRIBUTE_SERVICE_CHANGED_VALUE, -#define USER_CLI_COMMAND_SIZE ( sizeof( hello_sensor_send_message_cmd ) / sizeof( hello_sensor_send_message_cmd[0] ) ) + HDLS_GENERIC_ACCESS = 0x14, + HDLC_GENERIC_ACCESS_DEVICE_NAME, + HDLC_GENERIC_ACCESS_DEVICE_NAME_VALUE, -/****************************************************************************** - * Variables Definitions - ******************************************************************************/ + HDLC_GENERIC_ACCESS_APPEARANCE, + HDLC_GENERIC_ACCESS_APPEARANCE_VALUE, -/* Initialized attribute value */ -static uint8_t hello_sensor_appearance_name[2] = { BIT16_TO_8( APPEARANCE_GENERIC_TAG ) }; -static uint8_t hello_sensor_char_system_id_value[] = { 0xbb, 0xb8, 0xa1, 0x80, 0x5f, 0x9f, 0x91, - 0x71 - }; + HDLS_DEV_INFO = 0x50, + HDLC_DEV_INFO_MFR_NAME, + HDLC_DEV_INFO_MFR_NAME_VALUE, -/* AOS BT Smart peripheral connection controller */ -static aos_bt_peripheral_socket_t peripheral_socket; + HDLC_DEV_INFO_MODEL_NUM, + HDLC_DEV_INFO_MODEL_NUM_VALUE, -/****************************************************************************** - * GATT DATABASE - ******************************************************************************/ + HDLC_DEV_INFO_SYSTEM_ID, + HDLC_DEV_INFO_SYSTEM_ID_VALUE, +} adv_db_tags; -const uint8_t hello_sensor_gatt_database[] = { +static const uint8_t adv_gatt_db[] = { /* Declare mandatory GATT service */ PRIMARY_SERVICE_UUID16( HDLS_GENERIC_ATTRIBUTE, UUID_SERVCLASS_GATT_SERVER ), @@ -158,430 +93,23 @@ const uint8_t hello_sensor_gatt_database[] = { LEGATTDB_PERM_READABLE ), }; -/****************************************************************************** - * Function Definitions - ******************************************************************************/ - -static void hello_sensor_create_attribute_db( void ); - -/* Peripheral connection handlers */ -static OSStatus connection_handler( aos_bt_peripheral_socket_t *socket ); -static OSStatus disconnection_handler( aos_bt_peripheral_socket_t *socket ); - -static OSStatus hello_sensor_set_advertisement_data( void ); -static OSStatus advertisement_complete_handle( void *arg ); - -/* - * Entry point to the application. - */ - -int application_start( void ) -{ - OSStatus err = oNoErr; - -#ifdef USE_AOSKit_EXT - OLED_ShowString( OLED_DISPLAY_COLUMN_START, OLED_DISPLAY_ROW_2, "BLE Advertising" ); -#endif - - /* Initialize AOS bluetooth Framework */ - err = aos_bt_init( AOS_BT_HCI_MODE, "MK3239 Advert", 0, 1 ); - require_noerr_string( err, exit, "Error initialising AOS Bluetooth Framework" ); - - /* Initialize AOS bluetooth peripheral */ - aos_bt_peripheral_init( &peripheral_socket, &security_settings, connection_handler, - disconnection_handler, NULL ); - - /* Build BT Stack layer GATT database */ - aos_bt_gatt_db_init( hello_sensor_gatt_database, sizeof(hello_sensor_gatt_database) ); - - /* Build BT Application Layer GATT database */ - hello_sensor_create_attribute_db( ); - - /* Set the advertising parameters and make the device discoverable */ - hello_sensor_set_advertisement_data( ); - - /* Start advertising */ - hello_sensor_start_advertisements( ); - -#ifdef AOS_CLI_ENABLE - cli_register_commands( hello_sensor_send_message_cmd, USER_CLI_COMMAND_SIZE ); -#endif - -exit: - aos_rtos_delete_thread( NULL ); - return err; -} - -/*********************************************************************************************************** - * Handler or Callback function - */ - -/* This function is invoked when advertisements changed. */ -static OSStatus advertisement_complete_handle( void *arg ) -{ - aos_bt_peripheral_socket_status_t status; - - UNUSED_PARAMETER( arg ); - - printf( "Advertisements Stopped successfully!" ); - printf( "" ); - - aos_bt_peripheral_get_socket_status( &peripheral_socket, &status ); - if ( status == PERIPHERAL_SOCKET_DISCONNECTED ) { - hello_sensor_start_advertisements( ); - } - return oNoErr; -} - -/* Peripheral connection handlers */ -static OSStatus connection_handler( aos_bt_peripheral_socket_t *socket ) -{ - hello_sensor_stop_advertisements( ); - - printf( "Connection established! id: 0x%x", socket->connection_handle ); - printf( "" ); - -#ifdef USE_AOSKit_EXT - OLED_ShowString( OLED_DISPLAY_COLUMN_START, OLED_DISPLAY_ROW_3, " STOP!! " ); - OLED_ShowString( OLED_DISPLAY_COLUMN_START, OLED_DISPLAY_ROW_4, " Connected " ); -#endif - - /* Add device to whitelist */ - aos_bt_peripheral_update_advertisements_white_list( AOS_TRUE, socket->remote_device.address); - - return oNoErr; -} - -static OSStatus disconnection_handler( aos_bt_peripheral_socket_t *socket ) -{ - printf( "Connection disconnected!\r\n" ); - printf( "" ); - - /* Start advertising */ - hello_sensor_start_advertisements( ); - - return oNoErr; -} - -/************************************************************************************************************** - * Command line handle - */ - -/* This function will be triggered by command "advert" on command line */ -static void hello_sensor_change_advertisements( char *pcWriteBuffer, int xWriteBufferLen, int argc, - char **argv ) +static int adv_complete_cb(void *arg) { - aos_bt_smart_advertising_type_t type = BT_SMART_UNDIRECTED_ADVERTISING; //default - aos_bool_t duty = AOS_TRUE; //default - require( argc >= 2, err ); - - /* Change current advertisement type and state. */ - if ( (strcmp( argv[1], "stop" ) == 0) ) { - /* Stop advertisement */ - hello_sensor_stop_advertisements( ); - - } else if ( strcmp( argv[1], "start" ) == 0 ) { - - /* Check the second option parameter -- advertisement type */ - if ( argc >= 3 ) { - require( strlen( argv[2] ) == 1, err ); - type = argv[2][0] - '0'; - require( type <= BT_SMART_NON_CONNECTABLE_UNDIRECTED_ADVERTISING, err ); - } - - /* Check the third option parameter -- advertisement duty */ - if ( argc >= 4 ) { - require( strlen( argv[3] ) == 1, err ); - duty = argv[3][0] - '0'; - require( duty == AOS_TRUE || duty == AOS_FALSE, err ); - } - - switch ( type ) { - case BT_SMART_UNDIRECTED_ADVERTISING: - advertising_settings.high_duty_interval = AOS_BT_CFG_DEFAULT_HIGH_DUTY_ADV_MIN_INTERVAL; - advertising_settings.low_duty_interval = AOS_BT_CFG_DEFAULT_LOW_DUTY_ADV_MAX_INTERVAL; - break; - case BT_SMART_DISCOVERABLE_ADVERTISING: - case BT_SMART_NON_CONNECTABLE_UNDIRECTED_ADVERTISING: - advertising_settings.high_duty_interval = AOS_BT_CFG_DEFAULT_HIGH_DUTY_NONCONN_ADV_MIN_INTERVAL; - advertising_settings.low_duty_interval = AOS_BT_CFG_DEFAULT_LOW_DUTY_NONCONN_ADV_MAX_INTERVAL; - break; - case BT_SMART_DIRECTED_ADVERTISING: - advertising_settings.high_duty_interval = AOS_BT_CFG_DEFAULT_HIGH_DUTY_DIRECTED_ADV_MIN_INTERVAL; - advertising_settings.low_duty_interval = AOS_BT_CFG_DEFAULT_LOW_DUTY_DIRECTED_ADV_MIN_INTERVAL; - break; - default: - break; - } - - /* Start Advertisement */ - advertising_settings.use_high_duty = duty; - advertising_settings.type = type; - - hello_sensor_start_advertisements( ); - } else { -err: - printf( "CLI: Unknown command or Unknown arguments" ); - printf( "" ); - } -} - -/* This function will be triggered by command "policy" on command line */ -static void hello_sensor_change_filter_policy( char *pcWriteBuffer, int xWriteBufferLen, int argc, - char **argv ) -{ - aos_bt_peripheral_adv_filter_policy_t policy; - - require( argc == 2, err ); - - switch ( argv[1][0] ) { - case '0': // PERIPHERAL_ADVERT_FILTER_ALL_CONNECTION_REQ_ALL_SCAN_REQ - printf( "PERIPHERAL_ADVERT_FILTER_ALL_CONNECTION_REQ_ALL_SCAN_REQ" ); - policy = PERIPHERAL_ADVERT_FILTER_ALL_CONNECTION_REQ_ALL_SCAN_REQ; - break; - case '1': // PERIPHERAL_ADVERT_FILTER_ALL_CONNECTION_REQ_WHITELIST_SCAN_REQ - printf( "PERIPHERAL_ADVERT_FILTER_ALL_CONNECTION_REQ_WHITELIST_SCAN_REQ" ); - policy = PERIPHERAL_ADVERT_FILTER_ALL_CONNECTION_REQ_WHITELIST_SCAN_REQ; - break; - case '2': // PERIPHERAL_ADVERT_FILTER_WHITELIST_CONNECTION_REQ_ALL_SCAN_REQ - printf( "PERIPHERAL_ADVERT_FILTER_WHITELIST_CONNECTION_REQ_ALL_SCAN_REQ" ); - policy = PERIPHERAL_ADVERT_FILTER_WHITELIST_CONNECTION_REQ_ALL_SCAN_REQ; - break; - case '3': // PERIPHERAL_ADVERT_FILTER_WHITELIST_CONNECTION_REQ_WHITELIST_SCAN_REQ - printf( "PERIPHERAL_ADVERT_FILTER_WHITELIST_CONNECTION_REQ_WHITELIST_SCAN_REQ" ); - policy = PERIPHERAL_ADVERT_FILTER_WHITELIST_CONNECTION_REQ_WHITELIST_SCAN_REQ; - break; - default: -err: - printf( "hello_sensor_change_filter_policy: Unknown command or Unknown arguments" ); - return; - } - - if ( aos_bt_peripheral_set_advertisements_filter_policy( policy ) != oNoErr ) { - printf( "update advertisement filter policy unsuccessfully!!" ); - } else { - printf( "update advertisement filter policy successfully!!" ); - } -} - -/* This function will be triggered by command "wlsize" on command line */ -static void hello_sensor_get_whitelist_size( char *pcWriteBuffer, int xWriteBufferLen, int argc, - char **argv ) -{ - uint8_t size = 0; - - require( argc == 2, err ); - - switch ( argv[1][0] ) { - case '1': - aos_bt_peripheral_get_advertisements_white_list_size( &size ); - snprintf( pcWriteBuffer, xWriteBufferLen, "size: %d", size ); - break; - - case '2': - aos_bt_get_whitelist_capability( &size ); - snprintf( pcWriteBuffer, xWriteBufferLen, "capability: %d", size ); - break; - - default: -err: - printf( "hello_sensor_get_whitelist_size: Unknown command or Unknown arguments" ); - return; - } -} - -/* - * Local function - */ - -/* Set advertisement data and scanning response data */ -static OSStatus hello_sensor_set_advertisement_data( void ) -{ - OSStatus err = oNoErr; - - uint16_t uuid[1] = { UUID_SERVCLASS_DEVICE_INFO }; - aos_bt_ble_advert_data_t adv_data; - - aos_bt_ble_service_t advert_services_16 = { - .num_service = 1, - .list_cmpl = true, - .p_uuid = uuid, - }; - - aos_bt_ble_manu_t advert_manufacture = { - .len = strlen( "MXCHIP" ), - .p_val = (uint8_t *) "MXCHIP", - }; - - adv_data.flag = BTM_BLE_GENERAL_DISCOVERABLE_FLAG | BTM_BLE_BREDR_NOT_SUPPORTED; - adv_data.p_services = &advert_services_16; - adv_data.p_manu = &advert_manufacture; - - aos_bt_ble_set_advertisement_data( - BTM_BLE_ADVERT_BIT_DEV_NAME | BTM_BLE_ADVERT_BIT_SERVICE | BTM_BLE_ADVERT_BIT_FLAGS, - &adv_data ); - aos_bt_ble_set_scan_response_data( BTM_BLE_ADVERT_BIT_MANUFACTURER, &adv_data ); - - return err; } -/* Display Advertisement Arguments */ -static void hello_sensor_start_advertisements( void ) -{ -#ifdef USE_AOSKit_EXT - char display_str[20]; -#endif - - aos_bt_dev_status_t status; - aos_bt_peripheral_socket_status_t socket_status = PERIPHERAL_SOCKET_CONNECTED; - - /* Check current connection state. */ - aos_bt_peripheral_get_socket_status( &peripheral_socket, &socket_status ); - if ( socket_status != PERIPHERAL_SOCKET_DISCONNECTED ) { - printf( "Advertisements Started unsuccessfully! Existed connection" ); - printf( "" ); - return; - } - - /* Start advertisements */ - status = aos_bt_peripheral_start_advertisements( &advertising_settings, - advertisement_complete_handle ); - - /* AOSKit LCD Display */ -#ifdef USE_AOSKit_EXT - sprintf( display_str, "Type: %s", pBT_ShortStr( advertising_settings.type ) ); - OLED_ShowString( OLED_DISPLAY_COLUMN_START, OLED_DISPLAY_ROW_3, display_str ); - sprintf( display_str, "Duty: %s ", advertising_settings.use_high_duty == AOS_TRUE ? "High" : "Low" ); - OLED_ShowString( OLED_DISPLAY_COLUMN_START, OLED_DISPLAY_ROW_4, display_str ); -#endif - - /* LOG */ - printf(""); - if ( status == AOS_BT_SUCCESS ) { - printf( "Advertisements Started successfully! Arguments: " ); - } else if ( status == AOS_BT_ILLEGAL_VALUE ) { - printf( "Advertisements Started unsuccessfully! Illegal value: " ); - } else { - printf( "Advertisements Started unsuccessfully! Unknown error: " ); - } - printf( "" ); - printf( "\t\t type : %s", pBT_AdvertStr( advertising_settings.type ) ); - printf( "\t\t duty : %s", - advertising_settings.use_high_duty == AOS_TRUE ? "High duty" : "Low duty" ); - printf( "\t\t high_duty_interval: %-4d (slots, 0.625ms)", - advertising_settings.high_duty_interval ); - printf( "\t\t high_duty_duration: %-4d (seconds)", - advertising_settings.high_duty_duration ); - printf( "\t\t low_duty_interval : %-4d (slots, 0.625ms)", - advertising_settings.low_duty_interval ); - printf( "\t\t low_duty_duration : %-4d (seconds)", - advertising_settings.low_duty_duration ); - printf( "" ); -} - -/* Stop Advertisement Arguments */ -static void hello_sensor_stop_advertisements( void ) -{ - aos_bt_dev_status_t status; - - /* AOSKit LCD Display */ -#ifdef USE_AOSKit_EXT - OLED_ShowString( OLED_DISPLAY_COLUMN_START, OLED_DISPLAY_ROW_3, " STOP!! " ); - OLED_ShowString( OLED_DISPLAY_COLUMN_START, OLED_DISPLAY_ROW_4, " " ); -#endif - - status = aos_bt_peripheral_stop_advertisements( ); - if ( status == AOS_BT_SUCCESS ) { - printf( "Advertisements Stopped successfully!" ); - } else { - printf( "Advertisements Stopped unsuccessfully!" ); - } - printf( "" ); -} - -/* Add attribute value for some characteristic attribute */ -static void hello_sensor_create_attribute_db( void ) -{ - extern aos_bt_cfg_settings_t aos_bt_cfg_settings; - - /* - * Create BLE GATT external value database - */ - - // Primary service 'Generic Attribute' - aos_bt_peripheral_ext_attribute_add( HDLC_GENERIC_ATTRIBUTE_SERVICE_CHANGED_VALUE, - 0, - NULL, NULL ); - - // Primary service 'Generic Access' - aos_bt_peripheral_ext_attribute_add( HDLC_GENERIC_ACCESS_DEVICE_NAME_VALUE, - strlen( (char *) aos_bt_cfg_settings.device_name ), - aos_bt_cfg_settings.device_name, - NULL ); - aos_bt_peripheral_ext_attribute_add( HDLC_GENERIC_ACCESS_APPEARANCE_VALUE, - sizeof(hello_sensor_appearance_name), - hello_sensor_appearance_name, - NULL ); - - // Primary service 'Device info' - aos_bt_peripheral_ext_attribute_add( HDLC_DEV_INFO_MFR_NAME_VALUE, - strlen( (char *) MANUFACTURER ), - (uint8_t *) MANUFACTURER, - NULL ); - aos_bt_peripheral_ext_attribute_add( HDLC_DEV_INFO_MODEL_NUM_VALUE, - strlen( (char *) MODEL ), - (uint8_t *) MODEL, - NULL ); - aos_bt_peripheral_ext_attribute_add( HDLC_DEV_INFO_SYSTEM_ID_VALUE, - sizeof(hello_sensor_char_system_id_value), - hello_sensor_char_system_id_value, - NULL ); -} - -#ifdef USE_AOSKit_EXT - -/* Used in OLED Display */ -static const char *pBT_ShortStr(aos_bt_smart_advertising_type_t type) -{ - switch ( type ) { - case BT_SMART_UNDIRECTED_ADVERTISING: - return "UNDIRECT"; - - case BT_SMART_DISCOVERABLE_ADVERTISING: - return "DISCOVER"; - - case BT_SMART_DIRECTED_ADVERTISING: - return "DIRECTED"; - - case BT_SMART_NON_CONNECTABLE_UNDIRECTED_ADVERTISING: - return "NON-CONN"; - - default: - return "Unknown "; - } -} - -#endif - -/* Convert advertising type to friendly information. */ -static const char *pBT_AdvertStr( aos_bt_smart_advertising_type_t type ) +#define BLE_DEVICE_NAME "TestDevice" +#define MANUFACURE_NAME "TestManufacture" +int application_start( void ) { - switch ( type ) { - case BT_SMART_UNDIRECTED_ADVERTISING: - return "Generic undirected advertising"; + peripheral_hdl_t hdl; - case BT_SMART_DISCOVERABLE_ADVERTISING: - return "Discoverable advertising"; + peripheral_init_t p = {BLE_DEVICE_NAME, 0, 1}; - case BT_SMART_DIRECTED_ADVERTISING: - return "Directed advertising"; + hdl = ble_peripheral_init(&p, connection_handler, disconnection_handler, + adv_gatt_db, sizeof(adv_gatt_db)); - case BT_SMART_NON_CONNECTABLE_UNDIRECTED_ADVERTISING: - return "Non-connectable Undirected advertising"; + ble_adv_start(adv_complete_cb, MANUFACURE_NAME, hdl); - default: - return "Unknown advertising type"; - } + return 0; } - diff --git a/example/bluetooth/ble_advertisements/ble_advertisements.h b/example/bluetooth/ble_advertisements/ble_advertisements.h deleted file mode 100644 index 59c627f6cf..0000000000 --- a/example/bluetooth/ble_advertisements/ble_advertisements.h +++ /dev/null @@ -1,113 +0,0 @@ -/** - ****************************************************************************** - * @file ble_advertisements.h - * @author Jian Zhang - * @version V1.1.0 - * @date 24-Aug-2016 - * @file BLE advertisement demonstration via command line interface - * ****************************************************************************** - * - * The MIT License - * Copyright (c) 2014 MXCHIP Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR - * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ****************************************************************************** - * BLE Vendor Specific Device - * - * Features demonstrated - * - GATT database and Device configuration initialization - * - Processing user command over UART to control BLE Advertisements. - * - Demonstrate advertisement type and filter policy by UART command line. - * - * To demonstrate the demo, work through the following steps. - * 1. Plug the MiCOKit board into your computer, open a serial terminal - * 2. Build and download the application (to the MiCOKit board) - * 3. Type command "advert start" and "advert stop" on serial terminal to control - * BLE Advertisements. - * 4. Turn on your a Central device and connect to this borad. This Central device - * is added to the white list now. - * 5. Disconnect and re-advert. - * 6. Type command "policy" on serial terminal to control BLE Advertisements - * filter policy - using white list or not. You can - * 7. Now you can observe the filter policy. - * 8. Type command "wlsize" to get a size of white list. - * - ****************************************************************************** - **/ -#ifdef __cplusplus -extern "C" { -#endif - - -/****************************************************************************** - * Constants - ******************************************************************************/ - -/****************************************************************************** - * Constants - ******************************************************************************/ - -/****************************************************************************** - * Type Definitions - ******************************************************************************/ - -typedef enum { - HDLS_GENERIC_ATTRIBUTE = 0x1, - HDLC_GENERIC_ATTRIBUTE_SERVICE_CHANGED, - HDLC_GENERIC_ATTRIBUTE_SERVICE_CHANGED_VALUE, - - HDLS_GENERIC_ACCESS = 0x14, - HDLC_GENERIC_ACCESS_DEVICE_NAME, - HDLC_GENERIC_ACCESS_DEVICE_NAME_VALUE, - - HDLC_GENERIC_ACCESS_APPEARANCE, - HDLC_GENERIC_ACCESS_APPEARANCE_VALUE, - - HDLS_HELLO_SENSOR = 0x30, - HDLC_HELLO_SENSOR_NOTIFY, - HDLC_HELLO_SENSOR_NOTIFY_VALUE, - HDLC_HELLO_SENSOR_NOTIFY_CFG_DESC, - - HDLC_HELLO_SENSOR_COLOR, - HDLC_HELLO_SENSOR_COLOR_VALUE, - - HDLS_SPP = 0x40, - HDLC_SPP_IN, - HDLC_SPP_IN_VALUE, - HDLC_SPP_IN_DESCRIPTION, - - HDLC_SPP_OUT, - HDLC_SPP_OUT_VALUE, - HDLC_SPP_OUT_DESCRIPTION, - - HDLS_DEV_INFO = 0x50, - HDLC_DEV_INFO_MFR_NAME, - HDLC_DEV_INFO_MFR_NAME_VALUE, - - HDLC_DEV_INFO_MODEL_NUM, - HDLC_DEV_INFO_MODEL_NUM_VALUE, - - HDLC_DEV_INFO_SYSTEM_ID, - HDLC_DEV_INFO_SYSTEM_ID_VALUE, - - HDLS_BAT = 0x60, - HDLC_BAT_LEVEL, - HDLC_BAT_LEVEL_VALUE, - -} hello_sensor_db_tags; diff --git a/example/bluetooth/ble_advertisements/ble_advertisements.mk b/example/bluetooth/ble_advertisements/ble_advertisements.mk index e58f5be8ee..e1519446de 100644 --- a/example/bluetooth/ble_advertisements/ble_advertisements.mk +++ b/example/bluetooth/ble_advertisements/ble_advertisements.mk @@ -1,8 +1,5 @@ -NAME := App_Ble_Advertisements +NAME := ble_Advertisements $(NAME)_SOURCES := ble_advertisements.c -$(NAME)_COMPONENTS := bluetooth.smartbt \ - bluetooth.mk3239.low_energy - -GLOBAL_DEFINES := QC_TEST_BLUETOOTH_ENABLE +$(NAME)_COMPONENTS := bluetooth.ble_app_framework diff --git a/example/bluetooth/ble_hello_center/ReadMe.md b/example/bluetooth/ble_hello_center/ReadMe.md deleted file mode 100644 index 3ae9661825..0000000000 --- a/example/bluetooth/ble_hello_center/ReadMe.md +++ /dev/null @@ -1,2 +0,0 @@ -# READ ME -------------------------------------------------------------------------------- diff --git a/example/bluetooth/ble_hello_center/ble_command_line.c b/example/bluetooth/ble_hello_center/ble_command_line.c deleted file mode 100644 index fd3a69bfa5..0000000000 --- a/example/bluetooth/ble_hello_center/ble_command_line.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#include -#include - -#include "smartbt.h" -#include "smartbt_cfg.h" -#include "smartbt_smart_interface.h" -#include "smartbt_smartbridge.h" -#include "smartbt_smartbridge_gatt.h" - -#include "StringUtils.h" -#include "LinkListUtils.h" - -#ifdef MICO_CLI_ENABLE - -static void socket_list ( CLI_ARGS ); -static void paired_list ( CLI_ARGS ); - -static mico_bt_smartbridge_socket_t *smartbridge_socket = NULL; -static uint8_t smartbridge_socket_count = 0; - - -struct cli_command ble_scan_cmd[] = { - { "blesocket", "list ble connection status", socket_list }, - { "blepaired", "list ble paired devices information", paired_list }, -}; - -void ble_commands_init ( mico_bt_smartbridge_socket_t *socket, uint8_t socket_count ) -{ - smartbridge_socket = socket; - smartbridge_socket_count = socket_count; - /* Register an user command to cli interface */ - cli_register_commands( ble_scan_cmd, 2 ); -} - - - -/* Define a command: blesocket, display ble socket infors - */ -static void socket_list ( CLI_ARGS ) -{ - uint32_t i; - - char *status_str[3] = { "DISCONNECTED", "CONNECTING ", "CONNECTED " }; - mico_bt_smartbridge_socket_status_t status; - char *bt_addr_str = NULL; - - /* Iterate all sockets and look for the first available socket */ - printf("+-ID-+-------Address-------+-----Status-----+--Handle---+\r\n"); - for ( i = 0; i < smartbridge_socket_count; i++ ) { - bt_addr_str = DataToHexStringWithColons( smartbridge_socket[i].remote_device.address, BD_ADDR_LEN ); - mico_bt_smartbridge_get_socket_status( &smartbridge_socket[i], &status ); - printf("+-%02ld-+-[%s]-+--%s--+--0x%04x---+\r\n", i, bt_addr_str, status_str[status], - smartbridge_socket[i].connection_handle); - } -} - -/* Define a command: blepairedinfo, display paired devices and keys - */ -static void printf_device_data( uint8_t *address ) -{ - char *debug_str = NULL; - debug_str = DataToHexStringWithSpaces(address, BD_ADDR_LEN); - printf("===============Peer Device:[%s]=====================\r\n", debug_str); - free(debug_str); -} - -static void printf_key_data( char *name, uint8_t *p_data, uint16_t len ) -{ - char *debug_str = NULL; - debug_str = DataToHexStringWithSpaces(p_data, len); - printf(" %s:[%s]\r\n", name, debug_str); - free(debug_str); -} - -static void printf_key_number( char *name, uint32_t number ) -{ - printf(" %s:%ld\r\n", name, number); -} - -static void printf_key_desp( char *name, char *desp ) -{ - printf(" %s:%s\r\n", name, desp); -} - -static void printf_security_level( mico_bt_security_level level ) -{ - if ( level == BTM_LE_SEC_NONE ) { - printf(" Security Level:Not secured\r\n"); - } else if ( level == BTM_LE_SEC_UNAUTHENTICATE ) { - printf(" Security Level:Not authenticated\r\n"); - } else if ( level == BTM_LE_SEC_AUTHENTICATED ) { - printf(" Security Level:Authenticated\r\n"); - } else { - printf(" Security Level:Unknown value\r\n"); - } -} - - -static void paired_list ( CLI_ARGS ) -{ - OSStatus err = kNoErr; - mico_bt_dev_bonded_device_info_t device_info[20]; - uint16_t i, num_devices = 20; - mico_bt_security_key_value_t p_sec_keys; - - err = mico_bt_dev_get_bonded_devices(device_info, &num_devices); - require_noerr(err, exit); - - for ( i = 0; i < num_devices; i++ ) { - printf_device_data( device_info[i].bd_addr ); - - if ( kNoErr == mico_bt_dev_get_key_by_keytype(device_info[i].bd_addr, BTM_LE_KEY_PENC, &p_sec_keys) ) { - printf(" Encryption information of peer device:\r\n"); - printf_key_data ( "LTK ", p_sec_keys.le_keys.penc_key.ltk, BT_OCTET16_LEN ); - printf_key_data ( "rand ", p_sec_keys.le_keys.penc_key.rand, BT_OCTET8_LEN ); - printf_key_number ( "ediv ", p_sec_keys.le_keys.penc_key.ediv ); - printf_key_number ( "Key size ", p_sec_keys.le_keys.penc_key.key_size ); - printf_security_level ( p_sec_keys.le_keys.penc_key.sec_level ); - } - - if ( kNoErr == mico_bt_dev_get_key_by_keytype(device_info[i].bd_addr, BTM_LE_KEY_PID, &p_sec_keys)) { - printf(" Identity key of the peer device:\r\n"); - printf_key_data ( "IRK ", p_sec_keys.le_keys.pid_key.irk, BT_OCTET16_LEN ); - printf_key_data ( "Static Addr ", p_sec_keys.le_keys.pid_key.static_addr, BD_ADDR_LEN ); - printf_key_desp ( "Address Type ", (p_sec_keys.le_keys.pid_key.addr_type) ? "Static" : "Random" ); - } - - if ( kNoErr == mico_bt_dev_get_key_by_keytype(device_info[i].bd_addr, BTM_LE_KEY_LENC, &p_sec_keys)) { - printf(" Encryption information of local device:\r\n"); - printf_key_data ( "LTK ", p_sec_keys.le_keys.lenc_key.ltk, BT_OCTET16_LEN ); - printf_key_number ( "Div ", p_sec_keys.le_keys.lenc_key.div ); - printf_key_number ( "Key size ", p_sec_keys.le_keys.lenc_key.key_size ); - printf_security_level ( p_sec_keys.le_keys.lenc_key.sec_level ); - } - - if ( kNoErr == mico_bt_dev_get_key_by_keytype(device_info[i].bd_addr, BTM_LE_KEY_LID, &p_sec_keys)) { - printf(" Identity key of the local device:\r\n"); - } - - if ( kNoErr == mico_bt_dev_get_key_by_keytype(device_info[i].bd_addr, BTM_LE_KEY_LCSRK, &p_sec_keys)) { - printf(" local CSRK has been deliver to peer:\r\n"); - printf_key_data ( "LCSRK ", p_sec_keys.le_keys.lcsrk_key.csrk, BT_OCTET16_LEN ); - printf_key_number ( "counter ", p_sec_keys.le_keys.lcsrk_key.counter ); - printf_key_number ( "Div ", p_sec_keys.le_keys.lcsrk_key.div ); - printf_security_level ( p_sec_keys.le_keys.lcsrk_key.sec_level ); - } - } - -exit: - return; -} - -#endif - - - - - - - - diff --git a/example/bluetooth/ble_hello_center/ble_hello_center.c b/example/bluetooth/ble_hello_center/ble_hello_center.c deleted file mode 100644 index 387e12de70..0000000000 --- a/example/bluetooth/ble_hello_center/ble_hello_center.c +++ /dev/null @@ -1,472 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#include -#include - -#include "smartbt.h" -#include "smartbt_cfg.h" -#include "smartbt_smart_interface.h" -#include "smartbt_smartbridge.h" -#include "smartbt_smartbridge_gatt.h" - -#include "StringUtils.h" -#include "LinkListUtils.h" - -/****************************************************** - * Macros - ******************************************************/ -/****************************************************** - * Constants - ******************************************************/ - -#define MAX_CONCURRENT_CONNECTIONS (10) - -#define MAX_ATTRIBUTE_CACHE_COUNTS (10) - -#define OUT_OF_BAND_AUTHENTICATION BT_SMART_OOB_AUTH_NONE - -#define AUTHENTICATION_REQUIREMENTS BT_SMART_AUTH_REQ_BONDING - -/* UUID value of the Hello Sensor Service */ -#define UUID_HELLO_SERVICE 0x23, 0x20, 0x56, 0x7c, 0x05, 0xcf, 0x6e, 0xb4, 0xc3, 0x41, 0x77, 0x28, 0x51, 0x82, 0x7e, 0x1b - -/* UUID value of the Hello Sensor Characteristic, Value Notification */ -#define UUID_HELLO_CHARACTERISTIC_NOTIFY 0x26, 0xf6, 0x69, 0x91, 0x68, 0xee, 0xc2, 0xbe, 0x44, 0x4d, 0xb9, 0x5c, 0x3f, 0x2d, 0xc3, 0x8a - -/* UUID value of the Hello Sensor Characteristic, Color Configuration */ -#define UUID_HELLO_CHARACTERISTIC_COLOR 0x1a, 0x89, 0x07, 0x4a, 0x2f, 0x3b, 0x7e, 0xa6, 0x81, 0x44, 0x3f, 0xf9, 0xa8, 0xf2, 0x9b, 0x5e - - -#define LENGTH_HELLO_CHARACTERISTIC_COLOR (1) - - -/****************************************************** - * Enumerations - ******************************************************/ - -/****************************************************** - * Type Definitions - ******************************************************/ - -/* Device info ready to connect */ -typedef struct { - linked_list_node_t this_node; /* Linked-list node of this deivice */ - aos_bt_smart_device_t device; /* Remote BT device */ -} connecting_device_t; - -/****************************************************** - * Structures - ******************************************************/ - -/* SmartBridge security settings */ -const aos_bt_smart_security_settings_t security_settings = { - .timeout_second = 15, - .io_capabilities = BT_SMART_IO_DISPLAY_ONLY, - .authentication_requirements = AUTHENTICATION_REQUIREMENTS, - .oob_authentication = OUT_OF_BAND_AUTHENTICATION, - .max_encryption_key_size = 16, - .master_key_distribution = BT_SMART_DISTRIBUTE_ENCRYPTION_AND_SIGN_KEYS, - .slave_key_distribution = BT_SMART_DISTRIBUTE_ALL_KEYS, -}; - -/* SmartBridge connection settings */ -static const aos_bt_smart_connection_settings_t connection_settings = { - .timeout_second = 10, - .filter_policy = FILTER_POLICY_NONE, - .interval_min = AOS_BT_CFG_DEFAULT_CONN_MIN_INTERVAL, - .interval_max = AOS_BT_CFG_DEFAULT_CONN_MAX_INTERVAL, - .latency = AOS_BT_CFG_DEFAULT_CONN_LATENCY, - .supervision_timeout = AOS_BT_CFG_DEFAULT_CONN_SUPERVISION_TIMEOUT, - .ce_length_min = 0, - .ce_length_max = 0, - .attribute_protocol_timeout_ms = 10000, -}; - -/* SmartBridge auto scan settings */ -static const aos_bt_smart_scan_settings_t scan_settings = { - .type = BT_SMART_PASSIVE_SCAN, - .filter_policy = FILTER_POLICY_NONE, - .filter_duplicates = DUPLICATES_FILTER_ENABLED, - .interval = 512, - .window = 48, - .duration_second = 10, -}; - -/****************************************************** - * Static Function Declarations - ******************************************************/ -static OSStatus connect_handler ( void *arg ); -static OSStatus disconnection_handler ( aos_bt_smartbridge_socket_t *socket ); -static OSStatus notification_handler ( aos_bt_smartbridge_socket_t *socket, uint16_t attribute_handle ); -static OSStatus scan_complete_handler ( void *arg ); -static OSStatus scan_result_handler ( const aos_bt_smart_advertising_report_t *result ); -static OSStatus sensor_trigger_handler_t ( void *arg ); - -/* Remote device list management */ -static OSStatus connect_list_init ( void ); -static OSStatus connect_list_add ( aos_bt_smart_device_t remote_device ); -static OSStatus connect_list_get ( aos_bt_smart_device_t **address ); -static OSStatus connect_list_remove ( aos_bt_smart_device_t *device ); - -/****************************************************** - * Function Declarations - ******************************************************/ - -extern void ble_commands_init ( aos_bt_smartbridge_socket_t *socket, uint8_t socket_count ); -extern OSStatus ble_hello_peripheral_init( void ); - -/* Wlan test thread, connect to a TCP server and echo */ -extern OSStatus wlan_coexist_test_start( void ); - -/****************************************************** - * Variable Definitions - ******************************************************/ - -const char desired_peer_device[] = "AOSKit-3239"; /* Name of desired peer device to connect to */ -const aos_bt_uuid_t hello_service_uuid = { .len = LEN_UUID_128, .uu.uuid128 = { UUID_HELLO_SERVICE } }; /* Service for operation */ -const aos_bt_uuid_t hello_color_uuid = { .len = LEN_UUID_128, .uu.uuid128 = { UUID_HELLO_CHARACTERISTIC_COLOR } }; /* Characteristic for AOSKit led control */ - -static aos_bt_smartbridge_socket_t smartbridge_socket[MAX_CONCURRENT_CONNECTIONS]; /* Sockets to manage connections */ -static uint32_t -hello_color_value_handle[MAX_CONCURRENT_CONNECTIONS]; /* Handles to manage characteristic for each connection */ - -static aos_worker_thread_t hello_center_worker_thread; /* Worker thread to manage connection events */ - -static aos_worker_thread_t -hello_sensor_color_toggle_worker_thread; /* Worker thread to manage timed event for AOSKit led control */ -static aos_timed_event_t hello_sensor_color_toggle_event; - -static uint8_t color_idx = 0; /* Currnet color index for every connected AOSKit */ -static linked_list_t connecting_device_list; - -/****************************************************** - * Function Definitions - ******************************************************/ -int application_start(void) -{ - OSStatus err = oNoErr; - uint32_t a; - - /* start a wlan function */ -#ifdef WLAN_COEXIST_TEST - err = wlan_coexist_test_start(); - require_noerr( err, exit ); -#endif - - /* Initialise AOS Bluetooth Framework */ - err = aos_bt_init( AOS_BT_HCI_MODE, "SmartBridge Device", MAX_CONCURRENT_CONNECTIONS, - 1 ); //Client + server connections - require_noerr_string( err, exit, "Error initialising AOS Bluetooth Framework" ); - - err = ble_hello_peripheral_init( ); - require_noerr_string( err, exit, "Failed to init ble hello peripheral demo!" ); - - /* Initialise AOS SmartBridge */ - err = aos_bt_smartbridge_init( MAX_CONCURRENT_CONNECTIONS ); - require_noerr( err, exit ); - - printf( "Initialize success"); - - /* Enable Attribute Cache and set maximum number of caches */ - err = aos_bt_smartbridge_enable_attribute_cache( MAX_ATTRIBUTE_CACHE_COUNTS, (aos_bt_uuid_t *)&hello_service_uuid, 1 ); - require_noerr_string( err, exit, "Failed to enable ATT Cache" ); - - /* Create all sockets and make them ready to connect. A socket can connect and disconnect multiple times. */ - for ( a = 0; a < MAX_CONCURRENT_CONNECTIONS; a++ ) { - aos_bt_smartbridge_create_socket( &smartbridge_socket[a] ); - } - - /* Create a worker thread for making a connection and control event */ - aos_rtos_create_worker_thread( &hello_center_worker_thread, AOS_APPLICATION_PRIORITY, 2048, 1 ); - - aos_rtos_create_worker_thread( &hello_sensor_color_toggle_worker_thread, AOS_APPLICATION_PRIORITY, 1024, 1 ); - - aos_rtos_register_timed_event( &hello_sensor_color_toggle_event, &hello_sensor_color_toggle_worker_thread, - sensor_trigger_handler_t, 1000, NULL ); - - printf("Scanning for %s...\n", desired_peer_device); - - err = connect_list_init( ); - require_noerr( err, exit ); - - aos_bt_smartbridge_start_scan( &scan_settings, scan_complete_handler, scan_result_handler ); - -#ifdef AOS_CLI_ENABLE - /* Register ble helper commands to cli interface */ - ble_commands_init( smartbridge_socket, MAX_CONCURRENT_CONNECTIONS ); -#endif - -exit: - aos_rtos_delete_thread( NULL ); - return err; -} - -OSStatus sensor_trigger_handler_t(void *arg) -{ - UNUSED_PARAMETER(arg); - uint32_t i; - aos_bt_smartbridge_socket_status_t status; - OSStatus err = oNoErr; - - aos_bt_smart_attribute_t *characteristic_value = NULL; - - aos_bt_smart_attribute_create( &characteristic_value, AOS_ATTRIBUTE_TYPE_CHARACTERISTIC_VALUE, - LENGTH_HELLO_CHARACTERISTIC_COLOR ); - - for ( i = 0; i < MAX_CONCURRENT_CONNECTIONS; i++ ) { - aos_bt_smartbridge_get_socket_status( &smartbridge_socket[i], &status ); - - if ( status == SMARTBRIDGE_SOCKET_CONNECTED && smartbridge_socket[i].att_cache != NULL ) { - err = aos_bt_smartbridge_get_attribute_cache_by_handle( &smartbridge_socket[i], hello_color_value_handle[i], - characteristic_value, ATTR_CHARACTERISTIC_VALUE_SIZE( LENGTH_HELLO_CHARACTERISTIC_COLOR ) ); - if ( err == oNoErr ) { - memcpy( characteristic_value->value.value, &color_idx, 1); - aos_bt_smartbridge_write_attribute_cache_characteristic_value( &smartbridge_socket[i], characteristic_value ); - } else if ( err == AOS_BT_DISCOVER_IN_PROGRESS ) { - printf( "ATT cache discover is in progress"); - } else { - printf( "Hello color characteristic not found, disconnect"); - aos_bt_smartbridge_disconnect( &smartbridge_socket[i], FALSE ); - } - } - } - - color_idx ++; - - if ( characteristic_value != NULL ) { - aos_bt_smart_attribute_delete( characteristic_value ); - } - - return oNoErr; -} - -/* Scan complete handler. Scan complete event reported via this callback. - * It runs on the AOS_NETWORKING_WORKER_THREAD context. - */ -OSStatus scan_complete_handler( void *arg ) -{ - UNUSED_PARAMETER(arg); - /* Scan complete, start a new scan. Donot use a infinit scan, it may store every result in RAM. */ - aos_bt_smartbridge_start_scan( &scan_settings, scan_complete_handler, scan_result_handler ); - return oNoErr; -} - - -OSStatus scan_result_handler( const aos_bt_smart_advertising_report_t *scan_result ) -{ - /* If connection not initiated yet, and this device has the name we are looking for, then initiate teh connection */ - if ( memcmp( scan_result->remote_device.name, desired_peer_device, strlen(desired_peer_device)) == 0) { - connect_list_add( scan_result->remote_device ); - aos_rtos_send_asynchronous_event( &hello_center_worker_thread, connect_handler, (void *)scan_result ); - } - return oNoErr; -} - -/* Connect handler. Smartbridge connect is executed in this callback. - * It runs on the connect_worker_thread context - */ -static OSStatus connect_handler( void *arg ) -{ - UNUSED_PARAMETER(arg); - uint32_t i; - OSStatus err = oNoErr; - aos_bt_smartbridge_socket_status_t status; - - uint8_t attribute_buffer[100]; - aos_bt_smart_attribute_t *attribute = (aos_bt_smart_attribute_t *)attribute_buffer; - char *bt_addr_str = NULL; - - aos_bt_smart_device_t *remote_device; - - while ( connect_list_get( &remote_device ) == oNoErr ) { - bt_addr_str = DataToHexStringWithColons( (uint8_t *)remote_device->address, 6 ); - printf("Opening GATT connection to [%s] (addr type=%s)...", bt_addr_str, - (remote_device->address_type == BT_SMART_ADDR_TYPE_PUBLIC ) ? "Public" : "Random"); - free( bt_addr_str ); - - /* Iterate all sockets and look for the first available socket */ - for ( i = 0; i < MAX_CONCURRENT_CONNECTIONS; i++ ) { - aos_bt_smartbridge_get_socket_status( &smartbridge_socket[i], &status ); - - /* A free socket is found. Use it to connect */ - if ( status == SMARTBRIDGE_SOCKET_DISCONNECTED ) { - /* If there is a previously stored device, then connect to it */ - if (security_settings.authentication_requirements != BT_SMART_AUTH_REQ_NONE) { - if ( aos_bt_dev_find_bonded_device( (uint8_t *)remote_device->address ) == AOS_FALSE ) { - printf( "Bond info not found. Initiate pairing request." ); - aos_bt_smartbridge_enable_pairing( &smartbridge_socket[i], &security_settings, NULL ); - } else { - printf( "Bond info found. Encrypt use bond info." ); - aos_bt_smartbridge_set_bond_info( &smartbridge_socket[i], &security_settings, NULL ); - } - } - - /* Connect */ - err = aos_bt_smartbridge_connect( &smartbridge_socket[i], remote_device, &connection_settings, disconnection_handler, - notification_handler ); - require_noerr_string( err, exit, "Hello sensor connect failed." ); - printf( "Smartbridge connection established." ); - - /* Find service */ - err = aos_bt_smartbridge_get_service_from_attribute_cache_by_uuid( &smartbridge_socket[i], &hello_service_uuid, 0x0, - 0xFFFF, attribute, 100 ); - require_noerr_action_string( err, exit, aos_bt_smartbridge_disconnect( &smartbridge_socket[i], FALSE ), - "Hello service not found, disconnect." ); - - /* Find characteristic, and save characteristic value handle */ - err = aos_bt_smartbridge_get_characteritics_from_attribute_cache_by_uuid( &smartbridge_socket[i], &hello_color_uuid, - attribute->value.service.start_handle, attribute->value.service.end_handle, - (aos_bt_smart_attribute_t *)attribute_buffer, 100 ); - if ( err != oNoErr ) { - printf( "Hello color characteristic not found, remove att cache and disconnect." ); - aos_bt_smartbridge_remove_attribute_cache( &smartbridge_socket[i] ); - aos_bt_smartbridge_disconnect( &smartbridge_socket[i], FALSE ); - } - - hello_color_value_handle[i] = attribute->value.characteristic.value_handle; - - /* Enable Attribute Cache notification */ - //err = aos_bt_smartbridge_enable_attribute_cache_notification( &smartbridge_socket[i], AOS_TRUE ); - //require_noerr_string( err, exit, "Attribute cache notification failed." ); - - goto exit; - } - } -exit: - connect_list_remove( remote_device ); - continue; - } - return err; -} - -/* Disconnection handler. Disconnection by remote device is reported via this callback. - * It runs on the AOS_NETWORKING_WORKER_THREAD context. - */ -static OSStatus disconnection_handler( aos_bt_smartbridge_socket_t *socket ) -{ - char *bt_addr_str = DataToHexStringWithColons( (uint8_t *)socket->remote_device.address, 6 ); - printf( "Disconnected from [%s]", bt_addr_str ); - free( bt_addr_str ); - return oNoErr; -} - -/* Notification handler. GATT notification by remote device is reported via this callback. - * It runs on the AOS_NETWORKING_WORKER_THREAD context. - */ -static OSStatus notification_handler( aos_bt_smartbridge_socket_t *socket, uint16_t attribute_handle ) -{ - /* GATT value notification event. attribute_handle is the handle - * which value of the attribute is updated by the remote device. - */ - OSStatus err = oNoErr; - char *bt_addr_str = NULL; - char *data_str = NULL; - aos_bt_smart_attribute_t *characteristic_value = NULL; - - /* Read sender's address */ - bt_addr_str = DataToHexStringWithColons( (uint8_t *)socket->remote_device.address, 6 ); - - /* Read cached data */ - err = aos_bt_smart_attribute_create( &characteristic_value, AOS_ATTRIBUTE_TYPE_CHARACTERISTIC_VALUE, - MAX_CHARACTERISTIC_VALUE_LENGTH ); - require_noerr(err, exit); - err = aos_bt_smartbridge_get_attribute_cache_by_handle( socket, attribute_handle, characteristic_value, - ATTR_CHARACTERISTIC_VALUE_SIZE( MAX_CHARACTERISTIC_VALUE_LENGTH ) ); - require_noerr_string(err, exit, "This is not a cached value handle, ignore..."); - data_str = DataToHexStringWithSpaces( characteristic_value->value.value, characteristic_value->value_length ); - - printf( "Recv data from [%s], handle 0x%x: %s", bt_addr_str, attribute_handle, data_str ); - -exit: - if ( bt_addr_str != NULL ) { - free( bt_addr_str ); - } - if ( data_str != NULL ) { - free( data_str ); - } - if ( characteristic_value != NULL ) { - aos_bt_smart_attribute_delete( characteristic_value ); - } - return err; -} - -static OSStatus connect_list_init( void ) -{ - return linked_list_init( &connecting_device_list ); -} - -static bool compare_device_by_address( linked_list_node_t *node_to_compare, void *user_data ) -{ - connecting_device_t *device = (connecting_device_t * )node_to_compare; - aos_bt_device_address_t *device_address = (aos_bt_device_address_t *)user_data; - - if ( memcmp( device->device.address, device_address, BD_ADDR_LEN ) == 0 ) { - return true; - } else { - return false; - } -} - -static OSStatus connect_list_add( aos_bt_smart_device_t remote_device ) -{ - OSStatus err = oNoErr; - connecting_device_t *device_found, *new_device; - - err = linked_list_find_node( &connecting_device_list, compare_device_by_address, remote_device.address, - (linked_list_node_t **)&device_found ); - require_quiet( err == oNotFoundErr, exit ); - - new_device = malloc( sizeof(connecting_device_t) ); - require_action( new_device, exit, err = oNoMemoryErr ); - - memcpy( &new_device->device, &remote_device, sizeof(aos_bt_smart_device_t) ); - - err = linked_list_insert_node_at_rear( &connecting_device_list, &new_device->this_node ); - require_noerr(err, exit); - -exit: - return err; -} - -static OSStatus connect_list_get( aos_bt_smart_device_t **device ) -{ - OSStatus err = oNoErr; - connecting_device_t *current_device; - - err = linked_list_get_front_node( &connecting_device_list, (linked_list_node_t **)¤t_device ); - require_noerr_quiet(err, exit); - - *device = ¤t_device->device; - -exit: - return err; -} - -static OSStatus connect_list_remove( aos_bt_smart_device_t *device ) -{ - OSStatus err = oNoErr; - connecting_device_t *current_device; - - err = linked_list_find_node( &connecting_device_list, compare_device_by_address, device->address, - (linked_list_node_t **)¤t_device ); - require_noerr( err, exit ); - - err = linked_list_remove_node( &connecting_device_list, ¤t_device->this_node ); - require_noerr( err, exit ); - - free( current_device ); -exit: - return err; -} - - - - - - - - - - diff --git a/example/bluetooth/ble_hello_center/ble_hello_center.mk b/example/bluetooth/ble_hello_center/ble_hello_center.mk deleted file mode 100644 index 53a6282b02..0000000000 --- a/example/bluetooth/ble_hello_center/ble_hello_center.mk +++ /dev/null @@ -1,11 +0,0 @@ -NAME := App_Ble_Hello_Center - -$(NAME)_SOURCES := ble_hello_center.c \ - ble_hello_peripheral.c \ - ble_command_line.c \ - ble_wlan_coexist.c - -$(NAME)_COMPONENTS := bluetooth.smartbt \ - bluetooth.mk3239.low_energy - -GLOBAL_DEFINES := QC_TEST_BLUETOOTH_ENABLE diff --git a/example/bluetooth/ble_hello_center/ble_hello_peripheral.c b/example/bluetooth/ble_hello_center/ble_hello_peripheral.c deleted file mode 100644 index 65758b4fb9..0000000000 --- a/example/bluetooth/ble_hello_center/ble_hello_peripheral.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#include "sdpdefs.h" -#include "smartbt_cfg.h" -#include "smartbt_peripheral.h" - -#define MANUFACTURER "BleTestManufacturer" -#define MODEL "BleTestModel" - -/****************************************************************************** - * Constants -******************************************************************************/ - -/****************************************************************************** - * Enumerations -******************************************************************************/ - -enum { - HDLS_DEV_INFO = 0x50, - HDLC_DEV_INFO_MFR_NAME, - HDLC_DEV_INFO_MFR_NAME_VALUE, - - HDLC_DEV_INFO_MODEL_NUM, - HDLC_DEV_INFO_MODEL_NUM_VALUE, - - HDLC_DEV_INFO_SYSTEM_ID, - HDLC_DEV_INFO_SYSTEM_ID_VALUE, -}; - -/****************************************************************************** - * Function Prototypes - ******************************************************************************/ - -/****************************************************************************** - * Structures - ******************************************************************************/ - -/* SmartBridge auto scan settings */ -static aos_bt_smart_advertising_settings_t advertising_settings = { - .type = BT_SMART_UNDIRECTED_ADVERTISING, /**< Advertising type */ - .use_high_duty = AOS_TRUE, /**< Using high duty to start advertising */ - .high_duty_interval = AOS_BT_CFG_DEFAULT_HIGH_DUTY_ADV_MIN_INTERVAL, /**< High duty advertising interval */ - .high_duty_duration = 30, /**< High duty advertising duration in seconds (0 for infinite) */ - .low_duty_interval = AOS_BT_CFG_DEFAULT_LOW_DUTY_ADV_MIN_INTERVAL, /**< Low duty advertising interval */ - .low_duty_duration = 0, /**< Low duty advertising duration in seconds (0 for infinite) */ -}; - -/****************************************************************************** - * Variables Definitions - ******************************************************************************/ -extern aos_bt_cfg_settings_t aos_bt_cfg_settings; -extern aos_bt_smart_security_settings_t security_settings; - -static uint8_t hello_sensor_char_system_id_value[] = { 0xbb, 0xb8, 0xa1, 0x80, 0x5f, 0x9f, 0x91, 0x71 }; - -static aos_bt_peripheral_socket_t peripheral_socket; - -/****************************************************************************** - * GATT DATABASE - ******************************************************************************/ -/* - * This is the GATT database for the Hello Sensor application. It defines - * services, characteristics and descriptors supported by the sensor. Each - * attribute in the database has a handle, (characteristic has two, one for - * characteristic itself, another for the value). The handles are used by - * the peer to access attributes, and can be used locally by application for - * example to retrieve data written by the peer. Definition of characteristics - * and descriptors has GATT Properties (read, write, notify...) but also has - * permissions which identify if and how peer is allowed to read or write - * into it. All handles do not need to be sequential, but need to be in - * ascending order. - */ -const uint8_t hello_sensor_gatt_database[] = { - /* Declare Device info service */ - PRIMARY_SERVICE_UUID16( HDLS_DEV_INFO, UUID_SERVCLASS_DEVICE_INFO ), - - /* Handle 0x4e: characteristic Manufacturer Name */ - CHARACTERISTIC_UUID16( HDLC_DEV_INFO_MFR_NAME, HDLC_DEV_INFO_MFR_NAME_VALUE, - GATT_UUID_MANU_NAME, LEGATTDB_CHAR_PROP_READ, LEGATTDB_PERM_READABLE ), - - /* Handle 0x50: characteristic Model Number */ - CHARACTERISTIC_UUID16( HDLC_DEV_INFO_MODEL_NUM, HDLC_DEV_INFO_MODEL_NUM_VALUE, - GATT_UUID_MODEL_NUMBER_STR, LEGATTDB_CHAR_PROP_READ, LEGATTDB_PERM_READABLE ), - - /* Handle 0x52: characteristic System ID */ - CHARACTERISTIC_UUID16( HDLC_DEV_INFO_SYSTEM_ID, HDLC_DEV_INFO_SYSTEM_ID_VALUE, - GATT_UUID_SYSTEM_ID, LEGATTDB_CHAR_PROP_READ, LEGATTDB_PERM_READABLE ), -}; - -/****************************************************************************** - * Function Definitions - ******************************************************************************/ - -static void hello_peripheral_create_attribute_db(void); -static OSStatus connection_handler( aos_bt_peripheral_socket_t *socket ); -static OSStatus disconnection_handler( aos_bt_peripheral_socket_t *socket ); -static OSStatus hello_peripheral_set_advertisement_data( void ); - -/* - * Entry point to the ble hello peripheral demo. - */ - -OSStatus ble_hello_peripheral_init( void ) -{ - OSStatus err = oNoErr; - - err = aos_bt_peripheral_init( &peripheral_socket, &security_settings, connection_handler, disconnection_handler, NULL ); - require_noerr(err, exit); - - /* Build BT stack layer GATT database (handle, uuid, permission, properity)*/ - aos_bt_gatt_db_init( hello_sensor_gatt_database, sizeof( hello_sensor_gatt_database ) ); - require_noerr(err, exit); - - /* Build BT application layer GATT database ( extenal value, callback functions )*/ - hello_peripheral_create_attribute_db(); - - /* Set the advertising parameters and make the device discoverable */ - hello_peripheral_set_advertisement_data(); - - aos_bt_peripheral_start_advertisements( &advertising_settings, NULL ); - - printf( "Hello Peripheral started." ); - -exit: - return err; -} - -OSStatus hello_peripheral_set_advertisement_data( void ) -{ - OSStatus err = oNoErr; - - aos_bt_ble_advert_data_t adv_data; - - adv_data.flag = BTM_BLE_GENERAL_DISCOVERABLE_FLAG | BTM_BLE_BREDR_NOT_SUPPORTED; - - aos_bt_ble_set_advertisement_data( BTM_BLE_ADVERT_BIT_DEV_NAME | - BTM_BLE_ADVERT_BIT_FLAGS, &adv_data ); - - return err; -} - - -void hello_peripheral_create_attribute_db(void) -{ - // ***** Primary service 'Device info' - aos_bt_peripheral_ext_attribute_add( HDLC_DEV_INFO_MFR_NAME_VALUE, strlen((char *)MANUFACTURER), - (uint8_t *)MANUFACTURER, NULL ); - aos_bt_peripheral_ext_attribute_add( HDLC_DEV_INFO_MODEL_NUM_VALUE, strlen((char *)MODEL), (uint8_t *)MODEL, NULL ); - aos_bt_peripheral_ext_attribute_add( HDLC_DEV_INFO_SYSTEM_ID_VALUE, sizeof(hello_sensor_char_system_id_value), - hello_sensor_char_system_id_value, NULL ); -} - -OSStatus connection_handler( aos_bt_peripheral_socket_t *socket ) -{ - /* Stop advertising */ - printf( "Peripheral Connected." ); - return aos_bt_peripheral_stop_advertisements( ); -} - -OSStatus disconnection_handler( aos_bt_peripheral_socket_t *socket ) -{ - /* - * If we are configured to stay connected, disconnection was - * caused by the peer, start high advertisements, so that peer - * can connect when it wakes up - */ - printf( "Peripheral Disconected." ); - return aos_bt_peripheral_start_advertisements( &advertising_settings, NULL ); -} diff --git a/example/bluetooth/ble_hello_center/ble_wlan_coexist.c b/example/bluetooth/ble_hello_center/ble_wlan_coexist.c deleted file mode 100644 index 41038f2e13..0000000000 --- a/example/bluetooth/ble_hello_center/ble_wlan_coexist.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#include -#include -#include "lwip/sockets.h" -#include "mico.h" - -//#define wlan_log(M, ...) custom_log("WLAN", M, ##__VA_ARGS__) -#define wlan_log(M, ...) - -static char tcp_remote_ip[16] = "192.168.3.190"; -static int tcp_remote_port = 6000; - -static void tcp_client_thread( uint32_t arg ) -{ - UNUSED_PARAMETER(arg); - - OSStatus err; - struct sockaddr_in addr; - struct timeval t; - fd_set readfds; - int tcp_fd = -1, len; - char *buf = NULL; - - buf = (char *)malloc(1024); - require_action(buf, exit, err = kNoMemoryErr); - -re_connect: - /* Connect to TCP Server. */ - tcp_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - require_action(IsValidSocket(tcp_fd), exit, err = kNoResourcesErr); - - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = inet_addr(tcp_remote_ip); - addr.sin_port = htons(tcp_remote_port); - - wlan_log("Connecting to server: ip = %s port = %d", - tcp_remote_ip, tcp_remote_port); - err = connect(tcp_fd, (struct sockaddr *)&addr, sizeof(addr)); - require_noerr_action(err, exit, err = kConnectionErr); - wlan_log("Connect success"); - - t.tv_sec = 2; - t.tv_usec = 0; - - /* Poll data */ - while (1) { - FD_ZERO(&readfds); - FD_SET(tcp_fd, &readfds); - - require_action( select(tcp_fd + 1, &readfds, NULL, NULL, &t) >= 0, exit, err = kConnectionErr ); - - if (FD_ISSET(tcp_fd, &readfds)) { - len = recv(tcp_fd, buf, 1024, 0); - require_action(len >= 0, exit, err = kConnectionErr); - - if (len == 0) { - wlan_log("TCP_Client is disconnected, fd: %d", tcp_fd); - err = kConnectionErr; - goto exit; - } - len = send(tcp_fd, buf, len, 0); - } - } - -exit: - if ( err == kConnectionErr ) { - SocketClose(&tcp_fd); - mico_rtos_delay_milliseconds( 2 * 1000 ); - goto re_connect; - } - if (err != kNoErr) { - wlan_log("TCP Client thread exit with err: %d", err); - } - if (buf != NULL) { - free(buf); - } - SocketClose(&tcp_fd); - mico_rtos_delete_thread(NULL); -} - -OSStatus wlan_coexist_test_start( void ) -{ - return mico_rtos_create_thread( NULL, MICO_APPLICATION_PRIORITY, "TCP Client", tcp_client_thread, 0x800, 0 ); -} - - - - - - diff --git a/example/bluetooth/ble_hello_sensor/ReadMe.md b/example/bluetooth/ble_hello_sensor/ReadMe.md deleted file mode 100644 index 3ae9661825..0000000000 --- a/example/bluetooth/ble_hello_sensor/ReadMe.md +++ /dev/null @@ -1,2 +0,0 @@ -# READ ME -------------------------------------------------------------------------------- diff --git a/example/bluetooth/ble_hello_sensor/ble_hello_sensor.c b/example/bluetooth/ble_hello_sensor/ble_hello_sensor.c deleted file mode 100644 index 1405fb0ab6..0000000000 --- a/example/bluetooth/ble_hello_sensor/ble_hello_sensor.c +++ /dev/null @@ -1,651 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#include -#include -#include "ble_hello_sensor.h" -#include "sdpdefs.h" -#include "smartbt_cfg.h" -#include "smartbt.h" -#include "smartbt_peripheral.h" - -#define DEFAULT_NAME "BleTestHelloSensor" -#define MANUFACTURER "BleTestHelloSensorManufacturer" -#define MODEL "BleTestHelloSensorModle" -#define UART_FOR_APP 1 - -/****************************************************************************** - * Constants -******************************************************************************/ - -/****************************************************************************** - * Function Prototypes - ******************************************************************************/ - -static void hello_sensor_send_notification( CLI_ARGS ); -static void hello_sensor_send_indication( CLI_ARGS ); - -/****************************************************************************** - * Structures - ******************************************************************************/ - -typedef struct { -uint8_t flag_stay_connected; /* stay connected or disconnect after all messages are sent */ -uint8_t battery_level; /* dummy battery level */ -uint8_t led_color_idx; /* RGB led color index */ -} hello_sensor_state_t; - -typedef struct { -aos_bt_device_address_t bdaddr; -uint16_t service_changed; /* BD address of the bonded host */ -uint16_t -characteristic_client_configuration; /* Current value of the client configuration descriptor */ -} host_info_t; - -/* Peripheral auto advertising settings */ -static aos_bt_smart_advertising_settings_t advertising_settings = { -.type = BT_SMART_UNDIRECTED_ADVERTISING, /**< Advertising type */ -.use_high_duty = AOS_TRUE, /**< Using high duty to start advertising */ -.high_duty_interval = AOS_BT_CFG_DEFAULT_HIGH_DUTY_ADV_MIN_INTERVAL, /**< High duty advertising interval */ -.high_duty_duration = 5, /**< High duty advertising duration in seconds (0 for infinite) */ -.low_duty_interval = AOS_BT_CFG_DEFAULT_LOW_DUTY_ADV_MIN_INTERVAL, /**< Low duty advertising interval */ -.low_duty_duration = 60, /**< Low duty advertising duration in seconds (0 for infinite) */ -}; - -/* Peripheral security settings */ -static const aos_bt_smart_security_settings_t security_settings = { - .timeout_second = 15, - .io_capabilities = BT_SMART_IO_NO_INPUT_NO_OUTPUT, - .authentication_requirements = BT_SMART_AUTH_REQ_BONDING, - .oob_authentication = BT_SMART_OOB_AUTH_NONE, - .max_encryption_key_size = 16, - .master_key_distribution = BT_SMART_DISTRIBUTE_ALL_KEYS, - .slave_key_distribution = BT_SMART_DISTRIBUTE_ALL_KEYS, -}; - -struct cli_command hello_sensor_send_message_cmd[] = { - { "notify", "Send Notification", hello_sensor_send_notification }, - { "indicate", "Send Indication", hello_sensor_send_indication }, -}; - - -/****************************************************************************** - * Variables Definitions - ******************************************************************************/ -/* Initialized attribute value */ -static uint8_t hello_sensor_appearance_name[2] = { BIT16_TO_8(APPEARANCE_GENERIC_TAG) }; -static uint8_t hello_sensor_char_system_id_value[] = { 0xbb, 0xb8, 0xa1, 0x80, 0x5f, 0x9f, 0x91, 0x71 }; -static char hello_sensor_char_disable_value[] = { 'D', 'I', 'S', 'A', 'B', 'L', 'E', 'D' }; -static char hello_sensor_char_notify_value[] = { 'H', 'E', 'L', 'L', 'O', '0' }; -static char hello_sensor_char_indicate_value[] = { 'I', 'N', 'D', 'I', 'C', 'A', 'T', 'E', '0' }; - -static hello_sensor_state_t hello_sensor_state; -static host_info_t hello_sensor_hostinfo; - -/* Attributes used to send notify or indicate to le client */ -static aos_bt_ext_attribute_value_t *hello_notify_indicate_attribute = NULL; -static aos_bt_ext_attribute_value_t *spp_out_attribute = NULL; - -/* AOS BT smart peripheral connection controller */ -static aos_bt_peripheral_socket_t peripheral_socket; - - -/****************************************************************************** - * GATT DATABASE - ******************************************************************************/ -/* - * This is the GATT database for the Hello Sensor application. It defines - * services, characteristics and descriptors supported by the sensor. Each - * attribute in the database has a handle, (characteristic has two, one for - * characteristic itself, another for the value). The handles are used by - * the peer to access attributes, and can be used locally by application for - * example to retrieve data written by the peer. Definition of characteristics - * and descriptors has GATT Properties (read, write, notify...) but also has - * permissions which identify if and how peer is allowed to read or write - * into it. All handles do not need to be sequential, but need to be in - * ascending order. - */ -const uint8_t hello_sensor_gatt_database[] = { - /* Declare mandatory GATT service */ - PRIMARY_SERVICE_UUID16( HDLS_GENERIC_ATTRIBUTE, UUID_SERVCLASS_GATT_SERVER ), - - CHARACTERISTIC_UUID16( HDLC_GENERIC_ATTRIBUTE_SERVICE_CHANGED, - HDLC_GENERIC_ATTRIBUTE_SERVICE_CHANGED_VALUE, - GATT_UUID_GATT_SRV_CHGD, - LEGATTDB_CHAR_PROP_INDICATE, - LEGATTDB_PERM_NONE ), - - /* Declare mandatory GAP service. Device Name and Appearance are mandatory - * characteristics of GAP service */ - PRIMARY_SERVICE_UUID16( HDLS_GENERIC_ACCESS, UUID_SERVCLASS_GAP_SERVER ), - - /* Declare mandatory GAP service characteristic: Dev Name */ - CHARACTERISTIC_UUID16( HDLC_GENERIC_ACCESS_DEVICE_NAME, HDLC_GENERIC_ACCESS_DEVICE_NAME_VALUE, - GATT_UUID_GAP_DEVICE_NAME, - LEGATTDB_CHAR_PROP_READ, LEGATTDB_PERM_READABLE ), - - /* Declare mandatory GAP service characteristic: Appearance */ - CHARACTERISTIC_UUID16( HDLC_GENERIC_ACCESS_APPEARANCE, HDLC_GENERIC_ACCESS_APPEARANCE_VALUE, - GATT_UUID_GAP_ICON, - LEGATTDB_CHAR_PROP_READ, LEGATTDB_PERM_READABLE ), - - /* Declare proprietary Hello Service with 128 byte UUID */ - PRIMARY_SERVICE_UUID128( HDLS_HELLO_SENSOR, UUID_HELLO_SERVICE ), - - /* Declare characteristic used to notify/indicate change */ - CHARACTERISTIC_UUID128( HDLC_HELLO_SENSOR_NOTIFY, HDLC_HELLO_SENSOR_NOTIFY_VALUE, - UUID_HELLO_CHARACTERISTIC_NOTIFY, - LEGATTDB_CHAR_PROP_READ | LEGATTDB_CHAR_PROP_NOTIFY | LEGATTDB_CHAR_PROP_INDICATE, - LEGATTDB_PERM_READABLE ), - - /* Declare client characteristic configuration descriptor - * Value of the descriptor can be modified by the client - * Value modified shall be retained during connection and across connection - * for bonded devices. Setting value to 1 tells this application to send notification - * when value of the characteristic changes. Value 2 is to allow indications. */ - CHAR_DESCRIPTOR_UUID16_WRITABLE( HDLC_HELLO_SENSOR_NOTIFY_CFG_DESC, GATT_UUID_CHAR_CLIENT_CONFIG, - LEGATTDB_PERM_READABLE | LEGATTDB_PERM_WRITE_REQ ), - - /* Declare characteristic Hello Configuration */ - CHARACTERISTIC_UUID128_WRITABLE( HDLC_HELLO_SENSOR_COLOR, HDLC_HELLO_SENSOR_COLOR_VALUE, - UUID_HELLO_CHARACTERISTIC_COLOR, - LEGATTDB_CHAR_PROP_READ | LEGATTDB_CHAR_PROP_WRITE, - LEGATTDB_PERM_READABLE | LEGATTDB_PERM_WRITE_CMD | LEGATTDB_PERM_WRITE_REQ ), - - // /* Declare SPP Service with 128 byte UUID */ - PRIMARY_SERVICE_UUID128( HDLS_SPP, UUID_SPP_SERVICE ), - - /* Declare characteristic used to write spp data to server */ - CHARACTERISTIC_UUID128_WRITABLE( HDLC_SPP_IN, HDLC_SPP_IN_VALUE, - UUID_SPP_SERVICE_CHARACTERISTIC_IN, - LEGATTDB_CHAR_PROP_WRITE, LEGATTDB_PERM_WRITE_CMD | LEGATTDB_PERM_WRITE_REQ ), - - CHAR_DESCRIPTOR_UUID16( HDLC_SPP_IN_DESCRIPTION, GATT_UUID_CHAR_DESCRIPTION, - LEGATTDB_PERM_READABLE ), - - /* Declare characteristic used to send spp data to client */ - CHARACTERISTIC_UUID128( HDLC_SPP_OUT, HDLC_SPP_OUT_VALUE, - UUID_SPP_SERVICE_CHARACTERISTIC_OUT, - LEGATTDB_CHAR_PROP_INDICATE | LEGATTDB_CHAR_PROP_NOTIFY, LEGATTDB_PERM_NONE ), - - CHAR_DESCRIPTOR_UUID16( HDLC_SPP_OUT_DESCRIPTION, GATT_UUID_CHAR_DESCRIPTION, - LEGATTDB_PERM_READABLE ), - - /* Declare Device info service */ - PRIMARY_SERVICE_UUID16( HDLS_DEV_INFO, UUID_SERVCLASS_DEVICE_INFO ), - - /* Handle 0x4e: characteristic Manufacturer Name */ - CHARACTERISTIC_UUID16( HDLC_DEV_INFO_MFR_NAME, HDLC_DEV_INFO_MFR_NAME_VALUE, - GATT_UUID_MANU_NAME, - LEGATTDB_CHAR_PROP_READ, LEGATTDB_PERM_READABLE ), - - /* Handle 0x50: characteristic Model Number */ - CHARACTERISTIC_UUID16( HDLC_DEV_INFO_MODEL_NUM, HDLC_DEV_INFO_MODEL_NUM_VALUE, - GATT_UUID_MODEL_NUMBER_STR, - LEGATTDB_CHAR_PROP_READ, LEGATTDB_PERM_READABLE ), - - /* Handle 0x52: characteristic System ID */ - CHARACTERISTIC_UUID16( HDLC_DEV_INFO_SYSTEM_ID, HDLC_DEV_INFO_SYSTEM_ID_VALUE, - GATT_UUID_SYSTEM_ID, - LEGATTDB_CHAR_PROP_READ, LEGATTDB_PERM_READABLE ), - - /* Declare Battery service */ - PRIMARY_SERVICE_UUID16( HDLS_BAT, UUID_SERVCLASS_BATTERY ), - - /* Handle 0x62: characteristic Battery Level, handle 0x63 characteristic value */ - CHARACTERISTIC_UUID16( HDLC_BAT_LEVEL, HDLC_BAT_LEVEL_VALUE, - GATT_UUID_BATTERY_LEVEL, - LEGATTDB_CHAR_PROP_READ, LEGATTDB_PERM_READABLE ), -}; - -static uart_dev_t uart_1; -/****************************************************************************** - * Function Definitions - ******************************************************************************/ - -static void hello_sensor_create_attribute_db(void); - -/* Peripheral connection handlers */ -static OSStatus connection_handler( aos_bt_peripheral_socket_t *socket ); -static OSStatus disconnection_handler( aos_bt_peripheral_socket_t *socket ); - -static OSStatus hello_sensor_set_advertisement_data( void ); -static OSStatus advertisement_complete_handle( void *arg ); - -/* Peripheral attribute operation handlers */ -static aos_bt_gatt_status_t battery_level_callback ( aos_bt_ext_attribute_value_t *attribute, - aos_bt_gatt_request_type_t op ); -static aos_bt_gatt_status_t color_val_callback ( aos_bt_ext_attribute_value_t *attribute, - aos_bt_gatt_request_type_t op ); -static aos_bt_gatt_status_t notification_char_callback ( aos_bt_ext_attribute_value_t *attribute, - aos_bt_gatt_request_type_t op ); -static aos_bt_gatt_status_t char_cfg_callback ( aos_bt_ext_attribute_value_t *attribute, - aos_bt_gatt_request_type_t op ); -static aos_bt_gatt_status_t spp_data_in_callback ( aos_bt_ext_attribute_value_t *attribute, - aos_bt_gatt_request_type_t op ); - -/* Read UART data in SPP service */ -static void uartRecv_thread(uint32_t arg); - -/* - * Entry point to the application. - */ - -int application_start( void ) -{ - OSStatus err = oNoErr; - - /* Initialise AOS Bluetooth Framework */ - err = aos_bt_init( AOS_BT_HCI_MODE, DEFAULT_NAME, 0, 1 ); //Client + server connections - require_noerr_string( err, exit, "Error initialising AOS Bluetooth Framework" ); - - /* Initialise AOS Bluetooth Peripheral interface */ - aos_bt_peripheral_init( &peripheral_socket, &security_settings, connection_handler, disconnection_handler, NULL ); - - /* Build BT stack layer GATT database (handle, uuid, permission, properity)*/ - aos_bt_gatt_db_init( hello_sensor_gatt_database, sizeof( hello_sensor_gatt_database ) ); - - /* Build BT application layer GATT database ( extenal value, callback functions )*/ - hello_sensor_create_attribute_db(); - - printf( "hello_sensor_application_init" ); - - /* Set the advertising parameters and make the device discoverable */ - hello_sensor_set_advertisement_data(); - - aos_bt_peripheral_start_advertisements( &advertising_settings, advertisement_complete_handle ); - - /* - * Set flag_stay_connected to remain connected after all messages are sent - * Reset flag to 0, to disconnect - */ - hello_sensor_state.flag_stay_connected = 1; - hello_sensor_state.battery_level = 0; - hello_sensor_state.led_color_idx = 0; - -#ifdef USE_AOSKit_EXT - hsb2rgb_led_open( (hello_sensor_state.led_color_idx * 60) % 360 , 100, 5 ); -#endif - -#if defined(AOS_CLI_ENABLE) - if ( UART_FOR_APP == CLI_UART ) { - printf( "BLE SPP demo disabled by limited UART peripherals" ); - } else { - // SPP UART data receive thread - err = aos_rtos_create_thread( NULL, AOS_APPLICATION_PRIORITY, "UART Recv", uartRecv_thread, 500, 0 ); - require_noerr_string( err, exit, "ERROR: Unable to start the uart recv thread." ); - } -#else - err = aos_rtos_create_thread( NULL, AOS_APPLICATION_PRIORITY, "UART Recv", uartRecv_thread, 500, 0 ); - require_noerr_string( err, exit, "ERROR: Unable to start the uart recv thread." ); -#endif - -#if defined AOS_CLI_ENABLE - cli_register_commands( hello_sensor_send_message_cmd, 2 ); -#endif - -exit: - aos_rtos_delete_thread( NULL ); - return err; -} - - -OSStatus hello_sensor_set_advertisement_data( void ) -{ - OSStatus err = oNoErr; - - uint16_t uuid[1] = { UUID_SERVCLASS_BATTERY }; - aos_bt_ble_service_t adver_services_16 = { .num_service = 1, .list_cmpl = false, .p_uuid = uuid }; - aos_bt_ble_128service_t adver_services_128 = { .list_cmpl = false, .uuid128 = { UUID_HELLO_SERVICE }}; - - aos_bt_ble_advert_data_t adv_data; - - adv_data.flag = BTM_BLE_GENERAL_DISCOVERABLE_FLAG | BTM_BLE_BREDR_NOT_SUPPORTED; - adv_data.p_services = &adver_services_16; - adv_data.p_services_128b = &adver_services_128; - - aos_bt_ble_set_advertisement_data( BTM_BLE_ADVERT_BIT_DEV_NAME | - BTM_BLE_ADVERT_BIT_SERVICE | - BTM_BLE_ADVERT_BIT_FLAGS, &adv_data); - - aos_bt_ble_set_scan_response_data( BTM_BLE_ADVERT_BIT_SERVICE_128, &adv_data); - - return err; -} - -/* - * This function is invoked when advertisements changed. If we are configured to stay connected, - * disconnection was caused by the peer, start low advertisements, so that peer can connect - * when it wakes up - */ - -OSStatus advertisement_complete_handle( void *arg ) -{ - UNUSED_PARAMETER(arg); - OSStatus result = oNoErr; - aos_bt_peripheral_socket_status_t status; - - aos_bt_peripheral_get_socket_status( &peripheral_socket, &status ); - if ( hello_sensor_state.flag_stay_connected && status == PERIPHERAL_SOCKET_DISCONNECTED ) { - advertising_settings.use_high_duty = AOS_FALSE; - result = aos_bt_peripheral_start_advertisements( &advertising_settings, advertisement_complete_handle ); - printf( "aos_bt_start_advertisements: %d", result ); - } else { - printf( "ADV stop" ); - } - return result; -} - -void hello_sensor_create_attribute_db(void) -{ - extern aos_bt_cfg_settings_t aos_bt_cfg_settings; - - /* Create BLE GATT value database */ - // ***** Primary service 'Generic Attribute' - aos_bt_peripheral_ext_attribute_add( HDLC_GENERIC_ATTRIBUTE_SERVICE_CHANGED_VALUE, 0, NULL, NULL ); - - // ***** Primary service 'Generic Access' - aos_bt_peripheral_ext_attribute_add( HDLC_GENERIC_ACCESS_DEVICE_NAME_VALUE, - strlen((char *)aos_bt_cfg_settings.device_name), aos_bt_cfg_settings.device_name, NULL ); - aos_bt_peripheral_ext_attribute_add( HDLC_GENERIC_ACCESS_APPEARANCE_VALUE, sizeof(hello_sensor_appearance_name), - hello_sensor_appearance_name, NULL ); - - // ***** Primary service 'Device info' - aos_bt_peripheral_ext_attribute_add( HDLC_DEV_INFO_MFR_NAME_VALUE, strlen((char *)MANUFACTURER), - (uint8_t *)MANUFACTURER, NULL ); - aos_bt_peripheral_ext_attribute_add( HDLC_DEV_INFO_MODEL_NUM_VALUE, strlen((char *)MODEL), (uint8_t *)MODEL, NULL ); - aos_bt_peripheral_ext_attribute_add( HDLC_DEV_INFO_SYSTEM_ID_VALUE, sizeof(hello_sensor_char_system_id_value), - hello_sensor_char_system_id_value, NULL ); - - // ***** Primary service 'Battery' - aos_bt_peripheral_ext_attribute_add( HDLC_BAT_LEVEL_VALUE, 0, NULL, battery_level_callback ); - - // ***** Primary service 'Hello' (Vender specific) - hello_notify_indicate_attribute = aos_bt_peripheral_ext_attribute_add( HDLC_HELLO_SENSOR_NOTIFY_VALUE, 0, NULL, - notification_char_callback ); - aos_bt_peripheral_ext_attribute_add( HDLC_HELLO_SENSOR_NOTIFY_CFG_DESC, 2, - (uint8_t *)&hello_sensor_hostinfo.characteristic_client_configuration, char_cfg_callback ); - - aos_bt_peripheral_ext_attribute_add( HDLC_HELLO_SENSOR_COLOR_VALUE, 0, NULL, color_val_callback ); - - // ***** Primary service 'SPP' (Vender specific) - aos_bt_peripheral_ext_attribute_add( HDLC_SPP_IN_VALUE, 0, NULL, spp_data_in_callback ); - aos_bt_peripheral_ext_attribute_add( HDLC_SPP_IN_DESCRIPTION, strlen("SPP Data IN"), (uint8_t *)"SPP Data IN", NULL ); - - spp_out_attribute = aos_bt_peripheral_ext_attribute_add( HDLC_SPP_OUT_VALUE, 0, NULL, NULL ); - aos_bt_peripheral_ext_attribute_add( HDLC_SPP_OUT_DESCRIPTION, strlen("SPP Data OUT"), (uint8_t *)"SPP Data OUT", - NULL ); - - aos_bt_peripheral_ext_attribute_find_by_handle( HDLC_HELLO_SENSOR_NOTIFY_VALUE, &hello_notify_indicate_attribute ); - aos_bt_peripheral_ext_attribute_find_by_handle( HDLC_SPP_OUT_VALUE, &spp_out_attribute ); -} - -/* TX Power report handler */ -static void hello_sensor_tx_power_callback( aos_bt_tx_power_result_t *p_tx_power ) -{ - if ( ( p_tx_power->status == AOS_BT_SUCCESS ) && ( p_tx_power->hci_status == HCI_SUCCESS ) ) { - printf( "Local TX: %d", p_tx_power->tx_power ); -#ifdef USE_AOSKit_EXT - char display_str[20]; - sprintf( display_str, "Local TX: %d ", p_tx_power->tx_power ); - OLED_ShowString(OLED_DISPLAY_COLUMN_START, OLED_DISPLAY_ROW_2, display_str); -#endif - } else { - printf( "Unable to read Local TX power. (btm_status=0x%x, hci_status=0x%x)", p_tx_power->status, - p_tx_power->hci_status ); - } -} - -/* RSSI report handler */ -static void hello_sensor_rssi_callback( aos_bt_dev_rssi_result_t *p_rssi ) -{ - if ( ( p_rssi->status == AOS_BT_SUCCESS ) && ( p_rssi->hci_status == HCI_SUCCESS ) ) { - printf( "RSSI: %d", p_rssi->rssi ); -#ifdef USE_AOSKit_EXT - char display_str[20]; - sprintf( display_str, "RSSI: %d ", p_rssi->rssi ); - OLED_ShowString(OLED_DISPLAY_COLUMN_START, OLED_DISPLAY_ROW_3, display_str); -#endif - } else { - printf( "Unable to read RSSI. (btm_status=0x%x, hci_status=0x%x)", p_rssi->status, p_rssi->hci_status ); - } -} - - -OSStatus connection_handler( aos_bt_peripheral_socket_t *socket ) -{ - OSStatus result; - - printf( "hello_sensor_conn_up id:0x%4x:", socket->connection_handle ); - - /* Stop advertising */ - result = aos_bt_peripheral_stop_advertisements( ); - - printf( "Stopping Advertisements%d", result); - - aos_bt_dev_read_tx_power( socket->remote_device.address, BT_TRANSPORT_LE, - (aos_bt_dev_cmpl_cback_t *) hello_sensor_tx_power_callback ); - - hello_sensor_hostinfo.characteristic_client_configuration = GATT_CLIENT_CONFIG_NONE; - hello_sensor_hostinfo.service_changed = 1; - - return oNoErr; -} - -OSStatus disconnection_handler( aos_bt_peripheral_socket_t *socket ) -{ - OSStatus result; - - printf( "hello_sensor_conn_down id:0x%4x:", socket->connection_handle ); - - /* - * If we are configured to stay connected, disconnection was - * caused by the peer, start low advertisements, so that peer - * can connect when it wakes up - */ - if ( hello_sensor_state.flag_stay_connected ) { - advertising_settings.use_high_duty = TRUE; - result = aos_bt_peripheral_start_advertisements( &advertising_settings, advertisement_complete_handle ); - printf( "aos_bt_start_advertisements %d", result ); - } - - return oNoErr; -} - -/* - * Hello Sensor functions - */ - -/* - * This function will be triggered by command "notify" on command line - */ -void hello_sensor_send_notification( char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv ) -{ - uint8_t *p_attr = (uint8_t *)hello_sensor_char_notify_value; - aos_bt_peripheral_socket_status_t status; - - aos_bt_peripheral_get_socket_status( &peripheral_socket, &status); - if ( status == PERIPHERAL_SOCKET_CONNECTED ) { - if ( hello_sensor_hostinfo.characteristic_client_configuration & GATT_CLIENT_CONFIG_NOTIFICATION ) { - /*incrementing the value field , to ensure that notification values are changing*/ - hello_sensor_char_notify_value[5]++; - aos_bt_peripheral_ext_attribute_value_write(hello_notify_indicate_attribute, sizeof(hello_sensor_char_notify_value), 0, - p_attr ); - aos_bt_peripheral_gatt_notify_attribute_value( &peripheral_socket, hello_notify_indicate_attribute ); - snprintf( pcWriteBuffer, xWriteBufferLen, "Notify is sent" ); - } else { - snprintf(pcWriteBuffer, xWriteBufferLen, "Client configuration not allow"); - } - } else { - snprintf(pcWriteBuffer, xWriteBufferLen, "Cannot send notification, hello sensor not connected"); - } -} - -/* - * This function will be triggered by command "inticate" on command line - */ -void hello_sensor_send_indication( char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv ) -{ - uint8_t *p_attr = (uint8_t *)hello_sensor_char_indicate_value; - aos_bt_peripheral_socket_status_t status; - - aos_bt_peripheral_get_socket_status( &peripheral_socket, &status); - if ( status == PERIPHERAL_SOCKET_CONNECTED ) { - if ( hello_sensor_hostinfo.characteristic_client_configuration & GATT_CLIENT_CONFIG_INDICATION ) { - /*incrementing the value field , to ensure that indication values are changing*/ - hello_sensor_char_indicate_value[8]++; - aos_bt_peripheral_ext_attribute_value_write(hello_notify_indicate_attribute, sizeof(hello_sensor_char_indicate_value), - 0, p_attr ); - aos_bt_peripheral_gatt_indicate_attribute_value( &peripheral_socket, hello_notify_indicate_attribute ); - snprintf( pcWriteBuffer, xWriteBufferLen, "Indicate is sent" ); - } else { - snprintf(pcWriteBuffer, xWriteBufferLen, "client configuration not allow"); - } - } else { - snprintf(pcWriteBuffer, xWriteBufferLen, "Cannot send indication, hello sensor not connected"); - } -} - - -aos_bt_gatt_status_t color_val_callback( aos_bt_ext_attribute_value_t *attribute, aos_bt_gatt_request_type_t op ) -{ - if ( op == GATTS_REQ_TYPE_READ ) { - - printf( "hello_sensor_read_handler: led_color_idx: %d", hello_sensor_state.led_color_idx ); - aos_bt_peripheral_ext_attribute_value_write( attribute, 1, 0, &hello_sensor_state.led_color_idx ); - return AOS_BT_GATT_SUCCESS; - } else if ( op == GATTS_REQ_TYPE_WRITE ) { - if ( attribute->value_length != 1 ) { - return AOS_BT_GATT_INVALID_ATTR_LEN; - } - hello_sensor_state.led_color_idx = attribute->p_value[0]; - printf( "hello_sensor_write_handler: led_color_idx: %d", hello_sensor_state.led_color_idx ); - aos_bt_dev_read_rssi( peripheral_socket.remote_device.address, BT_TRANSPORT_LE, - (aos_bt_dev_cmpl_cback_t *) hello_sensor_rssi_callback ); - -#ifdef USE_AOSKit_EXT - hsb2rgb_led_open( (hello_sensor_state.led_color_idx * 60) % 360 , 100, 5); -#endif - - return AOS_BT_GATT_SUCCESS; - } else { - return AOS_BT_GATT_ERROR; - } -} - -static aos_bt_gatt_status_t notification_char_callback( aos_bt_ext_attribute_value_t *attribute, - aos_bt_gatt_request_type_t op ) -{ - uint8_t *p_attr; - - if ( op == GATTS_REQ_TYPE_READ ) { - /* If client has not registered for indication or notification, no action */ - if ( hello_sensor_hostinfo.characteristic_client_configuration == 0 ) { - p_attr = (uint8_t *)hello_sensor_char_disable_value; - aos_bt_peripheral_ext_attribute_value_write(attribute, sizeof(hello_sensor_char_disable_value), 0, p_attr ); - } else if ( hello_sensor_hostinfo.characteristic_client_configuration & GATT_CLIENT_CONFIG_NOTIFICATION ) { - p_attr = (uint8_t *)hello_sensor_char_notify_value; - aos_bt_peripheral_ext_attribute_value_write(attribute, sizeof(hello_sensor_char_notify_value), 0, p_attr ); - } else { - p_attr = (uint8_t *)hello_sensor_char_indicate_value; - aos_bt_peripheral_ext_attribute_value_write(attribute, sizeof(hello_sensor_char_indicate_value), 0, p_attr ); - } - return AOS_BT_GATT_SUCCESS; - } else { - return AOS_BT_GATT_ERROR; - } -} - -aos_bt_gatt_status_t char_cfg_callback( aos_bt_ext_attribute_value_t *attribute, aos_bt_gatt_request_type_t op ) -{ - - if ( op == GATTS_REQ_TYPE_READ ) { - return AOS_BT_GATT_SUCCESS; - } else if ( op == GATTS_REQ_TYPE_WRITE ) { - if ( attribute->value_length != 2 ) { - return AOS_BT_GATT_INVALID_ATTR_LEN; - } - hello_sensor_hostinfo.characteristic_client_configuration = attribute->p_value[0] | ( attribute->p_value[1] << 8 ); - return AOS_BT_GATT_SUCCESS; - } else { - return AOS_BT_GATT_ERROR; - } -} - -/* - * UART SPP Functions - */ -static aos_bt_gatt_status_t spp_data_in_callback( aos_bt_ext_attribute_value_t *attribute, - aos_bt_gatt_request_type_t op ) -{ - if ( op == GATTS_REQ_TYPE_WRITE ) { - hal_uart_send(&uart_1, attribute->p_value, attribute->value_length, 1000); - return AOS_BT_GATT_SUCCESS; - } else { - return AOS_BT_GATT_ERROR; - } -} - - -size_t _uart_get_one_packet(uint8_t *inBuf, int inBufLen) -{ - int datalen; - - while (1) { - if (hal_uart_recv(&uart_1, inBuf, inBufLen, &datalen, SPP_UART_RECV_TIMEOUT) == 0) { - return datalen; - } - } -} - -void uartRecv_thread(uint32_t arg) -{ - UNUSED_PARAMETER( arg ); - int recvlen; - uint8_t *spp_data_recv_buffer; - - spp_data_recv_buffer = malloc(SPP_UART_ONE_PACKAGE_LENGTH); - require(spp_data_recv_buffer, exit); - - uart_1.port = UART_FOR_APP; - uart_1.config.baud_rate = 115200; - uart_1.config.data_width = DATA_WIDTH_8BIT; - uart_1.config.parity = NO_PARITY; - uart_1.config.stop_bits = STOP_BITS_1; - uart_1.config.flow_control = FLOW_CONTROL_DISABLED; - - hal_uart_init(&uart_1); - while (1) { - recvlen = _uart_get_one_packet(spp_data_recv_buffer, SPP_UART_ONE_PACKAGE_LENGTH); - if (recvlen <= 0) { - continue; - } - - aos_bt_peripheral_ext_attribute_value_write(spp_out_attribute, recvlen, 0, spp_data_recv_buffer ); - aos_bt_peripheral_gatt_indicate_attribute_value( &peripheral_socket, spp_out_attribute ); - } - -exit: - if (spp_data_recv_buffer) { - free(spp_data_recv_buffer); - } - aos_rtos_delete_thread(NULL); -} - -/* - * Demo battery functions - */ -aos_bt_gatt_status_t battery_level_callback( aos_bt_ext_attribute_value_t *attribute, aos_bt_gatt_request_type_t op ) -{ - if ( op == GATTS_REQ_TYPE_READ ) { - hello_sensor_state.battery_level = (hello_sensor_state.battery_level + 1) % 100; - printf( "Read battery level %d", hello_sensor_state.battery_level ); - aos_bt_peripheral_ext_attribute_value_write( attribute, 1, 0, &hello_sensor_state.battery_level ); - return AOS_BT_GATT_SUCCESS; - } else { - return AOS_BT_GATT_ERROR; - } -} - - diff --git a/example/bluetooth/ble_hello_sensor/ble_hello_sensor.h b/example/bluetooth/ble_hello_sensor/ble_hello_sensor.h deleted file mode 100644 index e68fd87272..0000000000 --- a/example/bluetooth/ble_hello_sensor/ble_hello_sensor.h +++ /dev/null @@ -1,122 +0,0 @@ -/** - ****************************************************************************** - * @file ble_hello_sensor.h - * @author William Xu - * @version V1.0.0 - * @date 17-Feb-2016 - * @file This file provides GATT UUID and handler definitions for BLE - * peripheral demo device - * ****************************************************************************** - * - * The MIT License - * Copyright (c) 2014 MXCHIP Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR - * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - ****************************************************************************** - **/ - -#ifdef __cplusplus -extern "C" { -#endif - - -/****************************************************************************** - * Constants - ******************************************************************************/ - -#define SPP_UART_ONE_PACKAGE_LENGTH (128) - -#define SPP_UART_DRIVER_BUFFER_LENGTH (1024) - -#define SPP_UART_RECV_TIMEOUT (50) - - -/****************************************************************************** - * Constants - ******************************************************************************/ - -/* UUID value of the Hello Sensor Service */ -#define UUID_HELLO_SERVICE 0x23, 0x20, 0x56, 0x7c, 0x05, 0xcf, 0x6e, 0xb4, 0xc3, 0x41, 0x77, 0x28, 0x51, 0x82, 0x7e, 0x1b - -/* UUID value of the Hello Sensor Characteristic, Value Notification */ -#define UUID_HELLO_CHARACTERISTIC_NOTIFY 0x26, 0xf6, 0x69, 0x91, 0x68, 0xee, 0xc2, 0xbe, 0x44, 0x4d, 0xb9, 0x5c, 0x3f, 0x2d, 0xc3, 0x8a - -/* UUID value of the Hello Sensor Characteristic, Color Configuration */ -#define UUID_HELLO_CHARACTERISTIC_COLOR 0x1a, 0x89, 0x07, 0x4a, 0x2f, 0x3b, 0x7e, 0xa6, 0x81, 0x44, 0x3f, 0xf9, 0xa8, 0xf2, 0x9b, 0x5e - -/* UUID value of the SPP Service */ -#define UUID_SPP_SERVICE 0x5E, 0x67, 0x21, 0x8A, 0x3f, 0x4b, 0x4D, 0x32, 0x91, 0x36, 0x38, 0xE3, 0xD8, 0xED, 0x63, 0x71 - -/* UUID value of the SPP Characteristic, Data In */ -#define UUID_SPP_SERVICE_CHARACTERISTIC_IN 0x45, 0x39, 0x3E, 0x90, 0x24, 0x1D, 0x21, 0x78, 0x32, 0x70, 0x21, 0x35, 0xB4, 0xBA, 0xAE, 0xE2 - -/* UUID value of the SPP Characteristic, Data OUT */ -#define UUID_SPP_SERVICE_CHARACTERISTIC_OUT 0x32, 0x15, 0x1a, 0x5e, 0x82, 0x2e, 0x12, 0x2a, 0x91, 0x43, 0x27, 0x52, 0xba, 0x1d, 0xf3, 0x30 - -/****************************************************************************** - * Type Definitions - ******************************************************************************/ - -typedef enum { - HDLS_GENERIC_ATTRIBUTE = 0x1, - HDLC_GENERIC_ATTRIBUTE_SERVICE_CHANGED, - HDLC_GENERIC_ATTRIBUTE_SERVICE_CHANGED_VALUE, - - HDLS_GENERIC_ACCESS = 0x14, - HDLC_GENERIC_ACCESS_DEVICE_NAME, - HDLC_GENERIC_ACCESS_DEVICE_NAME_VALUE, - - HDLC_GENERIC_ACCESS_APPEARANCE, - HDLC_GENERIC_ACCESS_APPEARANCE_VALUE, - - HDLS_HELLO_SENSOR = 0x30, - HDLC_HELLO_SENSOR_NOTIFY, - HDLC_HELLO_SENSOR_NOTIFY_VALUE, - HDLC_HELLO_SENSOR_NOTIFY_CFG_DESC, - - HDLC_HELLO_SENSOR_COLOR, - HDLC_HELLO_SENSOR_COLOR_VALUE, - - HDLS_SPP = 0x40, - HDLC_SPP_IN, - HDLC_SPP_IN_VALUE, - HDLC_SPP_IN_DESCRIPTION, - - HDLC_SPP_OUT, - HDLC_SPP_OUT_VALUE, - HDLC_SPP_OUT_DESCRIPTION, - - HDLS_DEV_INFO = 0x50, - HDLC_DEV_INFO_MFR_NAME, - HDLC_DEV_INFO_MFR_NAME_VALUE, - - HDLC_DEV_INFO_MODEL_NUM, - HDLC_DEV_INFO_MODEL_NUM_VALUE, - - HDLC_DEV_INFO_SYSTEM_ID, - HDLC_DEV_INFO_SYSTEM_ID_VALUE, - - HDLS_BAT = 0x60, - HDLC_BAT_LEVEL, - HDLC_BAT_LEVEL_VALUE, - -} hello_sensor_db_tags; - - - diff --git a/example/bluetooth/ble_hello_sensor/ble_hello_sensor.mk b/example/bluetooth/ble_hello_sensor/ble_hello_sensor.mk deleted file mode 100644 index 53e2d6d25c..0000000000 --- a/example/bluetooth/ble_hello_sensor/ble_hello_sensor.mk +++ /dev/null @@ -1,8 +0,0 @@ -NAME := App_Ble_Hello_Sensor - -$(NAME)_SOURCES := ble_hello_sensor.c - -$(NAME)_COMPONENTS := bluetooth.smartbt \ - bluetooth.mk3239.low_energy - -GLOBAL_DEFINES := QC_TEST_BLUETOOTH_ENABLE diff --git a/example/bluetooth/ble_scan/ReadMe.md b/example/bluetooth/ble_scan/ReadMe.md deleted file mode 100644 index 3ae9661825..0000000000 --- a/example/bluetooth/ble_scan/ReadMe.md +++ /dev/null @@ -1,2 +0,0 @@ -# READ ME -------------------------------------------------------------------------------- diff --git a/example/bluetooth/ble_scan/ble_scan.c b/example/bluetooth/ble_scan/ble_scan.c deleted file mode 100644 index d23ea7c15a..0000000000 --- a/example/bluetooth/ble_scan/ble_scan.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#include "aos/aos.h" -#include "smartbt.h" -#include "smartbt_smartbridge.h" - -#include "StringUtils.h" - -#define ble_scan_log(M, ...) custom_log("LE SCAN", M, ##__VA_ARGS__) - -/****************************************************************************** - * Constants -******************************************************************************/ - -/****************************************************************************** - * Function Prototypes - ******************************************************************************/ - -/****************************************************************************** - * Structures - ******************************************************************************/ - - -/****************************************************************************** - * Variables Definitions - ******************************************************************************/ - -static void start_scan ( CLI_ARGS ); -static OSStatus scan_complete_handler ( void *arg ); - -struct cli_command ble_scan_cmd[] = { - { "blescan", "blescan ", start_scan }, -}; - -/****************************************************************************** - * Function Definitions - ******************************************************************************/ - -/* - * Entry point to the application. - */ - -int application_start( void ) -{ - OSStatus err = oNoErr; - - - /* Initialise AOS Bluetooth Framework */ - err = aos_bt_init( AOS_BT_HCI_MODE, "SmartBridge Device", 0, 0 ); - require_noerr( err, exit ); - - /* Initialise AOS SmartBridge, no connection is actually needed */ - err = aos_bt_smartbridge_init( 0 ); - require_noerr( err, exit ); - - /* Register an user command to cli interface */ - err = aos_cli_register_commands( ble_scan_cmd, 1 ); - require_noerr( err, exit ); - - LOG( "Initialize success, input \"blescan\" to start..."); - -exit: - //aos_rtos_delete_thread( NULL ); - aos_task_exit(0); - return err; -} - -/* Start scan process - */ -static void start_scan ( CLI_ARGS ) -{ - /* Scan settings */ - aos_bt_smart_scan_settings_t scan_settings; - - scan_settings.type = BT_SMART_PASSIVE_SCAN; - scan_settings.filter_policy = FILTER_POLICY_NONE; - scan_settings.filter_duplicates = DUPLICATES_FILTER_DISABLED; - scan_settings.interval = 96; - scan_settings.window = 48; - scan_settings.duration_second = 3; - - if (!strcasecmp(argv[1], "active")) { - aos_cli_printf("Start ble active scan\r\n"); - scan_settings.type = BT_SMART_ACTIVE_SCAN; - } else { - aos_cli_printf("Start ble passive scan\r\n"); - scan_settings.type = BT_SMART_PASSIVE_SCAN; - } - - /* Start scan */ - //aos_bt_smartbridge_stop_scan( ); - aos_bt_smartbridge_start_scan( &scan_settings, scan_complete_handler, NULL ); -} - -static void print_adv_data( uint8_t *adv_data, uint8_t adv_data_len ) -{ - uint8_t adv_type; - uint8_t adv_data_length; - uint8_t *p; - char *adv_data_str = NULL; - - p = adv_data; - STREAM_TO_UINT8( adv_data_length, p ); - - while ( (p - adv_data <= adv_data_len ) ) { - STREAM_TO_UINT8( adv_type, p ); - - adv_data_str = DataToHexStringWithSpaces( p, adv_data_length ); - printf( " =>(%2x):%s\r\n", adv_type, adv_data_str ); - free( adv_data_str ); - - p += adv_data_length - 1; /* skip the length of data */ - STREAM_TO_UINT8( adv_data_length, p ); - } -} - - -/* Scan complete handler. Scan complete event reported via this callback. - * It runs on the AOS_NETWORKING_WORKER_THREAD context. - */ -static OSStatus scan_complete_handler( void *arg ) -{ - OSStatus err = oNoErr; - uint32_t count = 0; - char *bd_addr_str = NULL; - aos_bt_smart_scan_result_t *scan_result = NULL; - - printf("Scan complete\r\n"); - err = aos_bt_smartbridge_get_scan_result_list( &scan_result, &count ); - require_noerr( err, exit ); - - if ( count == 0 ) { - printf( "No ble device found\r\n" ); - err = oNotFoundErr; - goto exit; - } - - while ( scan_result != NULL ) { - bd_addr_str = DataToHexStringWithColons( (uint8_t *)scan_result->remote_device.address, 6 ); - printf("[%s] ", bd_addr_str ); - printf("address type: %x ", (uint16_t)scan_result->remote_device.address_type ); - printf("rssi: %d ", scan_result->signal_strength ); - printf("name: %s\r\n", scan_result->remote_device.name ); - free( bd_addr_str ); - - printf(" =>Advertisement data: \r\n" ); - print_adv_data( scan_result->last_advertising_event_received.eir_data, - scan_result->last_advertising_event_received.eir_data_length ); - - if ( scan_result->last_scan_response_received.event == BT_SMART_SCAN_RESPONSE_EVENT) { - printf(" =>Scan respond data: \r\n" ); - print_adv_data( scan_result->last_scan_response_received.eir_data, - scan_result->last_scan_response_received.eir_data_length ); - } - - printf("\r\n"); - scan_result = scan_result->next; - } - -exit: - /* Scan duration is complete */ - return err; -} - - diff --git a/example/bluetooth/ble_scan/ble_scan.mk b/example/bluetooth/ble_scan/ble_scan.mk deleted file mode 100644 index f8ead6273f..0000000000 --- a/example/bluetooth/ble_scan/ble_scan.mk +++ /dev/null @@ -1,8 +0,0 @@ -NAME := App_Ble_Scan - -$(NAME)_SOURCES := ble_scan.c - -$(NAME)_COMPONENTS := bluetooth.smartbt \ - bluetooth.mk3239.low_energy - -GLOBAL_DEFINES := QC_TEST_BLUETOOTH_ENABLE diff --git a/example/bluetooth/ble_show_system_time/ble_show_system_time.c b/example/bluetooth/ble_show_system_time/ble_show_system_time.c new file mode 100644 index 0000000000..70c567cab5 --- /dev/null +++ b/example/bluetooth/ble_show_system_time/ble_show_system_time.c @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#include +#include + +static int connection_handler() +{ + +} + +static int disconnection_handler() +{ + +} + +/* UUID value of the TIME Service */ +#define UUID_TIME_SERVICE 0x5E, 0x67, 0x21, 0x8A, 0x3f, 0x4b, 0x4D, 0x32, 0x91, 0x36, 0x38, 0xE3, 0xD8, 0xED, 0x63, 0x71 +/* UUID value of the TIME Characteristic, Data OUT */ +#define UUID_TIME_SERVICE_CHARACTERISTIC_OUT 0x32, 0x15, 0x1a, 0x5e, 0x82, 0x2e, 0x12, 0x2a, 0x91, 0x43, 0x27, 0x52, 0xba, 0x1d, 0xf3, 0x30 + +typedef enum { + HDLS_GENERIC_ATTRIBUTE = 0x1, + HDLC_GENERIC_ATTRIBUTE_SERVICE_CHANGED, + HDLC_GENERIC_ATTRIBUTE_SERVICE_CHANGED_VALUE, + + HDLS_GENERIC_ACCESS = 0x14, + HDLC_GENERIC_ACCESS_DEVICE_NAME, + HDLC_GENERIC_ACCESS_DEVICE_NAME_VALUE, + + HDLC_GENERIC_ACCESS_APPEARANCE, + HDLC_GENERIC_ACCESS_APPEARANCE_VALUE, + + HDLS_TIME = 0x40, + HDLC_TIME_OUT, + HDLC_TIME_OUT_VALUE, + HDLC_TIME_OUT_DESCRIPTION, + + HDLS_DEV_INFO = 0x50, + HDLC_DEV_INFO_MFR_NAME, + HDLC_DEV_INFO_MFR_NAME_VALUE, + + HDLC_DEV_INFO_MODEL_NUM, + HDLC_DEV_INFO_MODEL_NUM_VALUE, + + HDLC_DEV_INFO_SYSTEM_ID, + HDLC_DEV_INFO_SYSTEM_ID_VALUE, +} adv_db_tags; + +static const uint8_t adv_gatt_db[] = { + /* Declare mandatory GATT service */ + PRIMARY_SERVICE_UUID16( HDLS_GENERIC_ATTRIBUTE, UUID_SERVCLASS_GATT_SERVER ), + + CHARACTERISTIC_UUID16( HDLC_GENERIC_ATTRIBUTE_SERVICE_CHANGED, + HDLC_GENERIC_ATTRIBUTE_SERVICE_CHANGED_VALUE, + GATT_UUID_GATT_SRV_CHGD, + LEGATTDB_CHAR_PROP_INDICATE, + LEGATTDB_PERM_NONE ), + + /* Declare mandatory GAP service. Device Name and Appearance are mandatory + * characteristics of GAP service */ + PRIMARY_SERVICE_UUID16( HDLS_GENERIC_ACCESS, UUID_SERVCLASS_GAP_SERVER ), + + /* Declare mandatory GAP service characteristic: Dev Name */ + CHARACTERISTIC_UUID16( HDLC_GENERIC_ACCESS_DEVICE_NAME, HDLC_GENERIC_ACCESS_DEVICE_NAME_VALUE, + GATT_UUID_GAP_DEVICE_NAME, + LEGATTDB_CHAR_PROP_READ, LEGATTDB_PERM_READABLE ), + + /* Declare mandatory GAP service characteristic: Appearance */ + CHARACTERISTIC_UUID16( HDLC_GENERIC_ACCESS_APPEARANCE, HDLC_GENERIC_ACCESS_APPEARANCE_VALUE, + GATT_UUID_GAP_ICON, + LEGATTDB_CHAR_PROP_READ, LEGATTDB_PERM_READABLE ), + + // /* Declare TIME Service with 128 byte UUID */ + PRIMARY_SERVICE_UUID128( HDLS_TIME, UUID_TIME_SERVICE ), + + /* Declare characteristic used to send time data to client */ + CHARACTERISTIC_UUID128( HDLC_TIME_OUT, HDLC_TIME_OUT_VALUE, + UUID_TIME_SERVICE_CHARACTERISTIC_OUT, + LEGATTDB_CHAR_PROP_INDICATE | LEGATTDB_CHAR_PROP_NOTIFY, LEGATTDB_PERM_NONE ), + + CHAR_DESCRIPTOR_UUID16( HDLC_TIME_OUT_DESCRIPTION, GATT_UUID_CHAR_DESCRIPTION, + LEGATTDB_PERM_READABLE ), + + /* Declare Device info service */ + PRIMARY_SERVICE_UUID16( HDLS_DEV_INFO, UUID_SERVCLASS_DEVICE_INFO ), + + /* Handle 0x4e: characteristic Manufacturer Name */ + CHARACTERISTIC_UUID16( HDLC_DEV_INFO_MFR_NAME, HDLC_DEV_INFO_MFR_NAME_VALUE, + GATT_UUID_MANU_NAME, + LEGATTDB_CHAR_PROP_READ, LEGATTDB_PERM_READABLE ), + + /* Handle 0x50: characteristic Model Number */ + CHARACTERISTIC_UUID16( HDLC_DEV_INFO_MODEL_NUM, HDLC_DEV_INFO_MODEL_NUM_VALUE, + GATT_UUID_MODEL_NUMBER_STR, + LEGATTDB_CHAR_PROP_READ, LEGATTDB_PERM_READABLE ), + + /* Handle 0x52: characteristic System ID */ + CHARACTERISTIC_UUID16( HDLC_DEV_INFO_SYSTEM_ID, HDLC_DEV_INFO_SYSTEM_ID_VALUE, + GATT_UUID_SYSTEM_ID, + LEGATTDB_CHAR_PROP_READ, LEGATTDB_PERM_READABLE ), +}; + +static int adv_complete_cb(void *arg) +{ + +} + +struct indicate_arg_s { + ble_gatt_attr_t *attr; + peripheral_hdl_t hdl; +}; + +static void indicate_handler(void *arg) +{ + struct indicate_arg_s *ind = (struct indicate_arg_s *)arg; + long long time = aos_now_ms(); + + ble_attr_indicate(ind->attr, ind->hdl, sizeof(time), (uint8_t *)&time); + aos_post_delayed_action(1000, indicate_handler, arg); +} + +#define BLE_DEVICE_NAME "TestDevice" +#define MANUFACURE_NAME "TestManufacture" +int application_start( void ) +{ + peripheral_hdl_t hdl; + ble_gatt_attr_t *attr; + struct indicate_arg_s ind_arg; + + peripheral_init_t p = {BLE_DEVICE_NAME, 0, 1}; + + hdl = ble_peripheral_init(&p, connection_handler, disconnection_handler, + adv_gatt_db, sizeof(adv_gatt_db)); + + ble_adv_start(adv_complete_cb, MANUFACURE_NAME, hdl); + + attr = ble_attr_add(HDLC_TIME_OUT_VALUE, 0, NULL); + + ind_arg.hdl = hdl; + ind_arg.attr = attr; + aos_post_delayed_action(1000, indicate_handler, &ind_arg); + + aos_loop_run(); + + return 0; +} diff --git a/example/bluetooth/ble_show_system_time/ble_show_system_time.mk b/example/bluetooth/ble_show_system_time/ble_show_system_time.mk new file mode 100644 index 0000000000..4c9299d3bc --- /dev/null +++ b/example/bluetooth/ble_show_system_time/ble_show_system_time.mk @@ -0,0 +1,5 @@ +NAME := app_ble_show_system_time + +$(NAME)_SOURCES := ble_show_system_time.c + +$(NAME)_COMPONENTS := bluetooth.ble_app_framework diff --git a/example/bluetooth/ble_whitelist_connect/ReadMe.md b/example/bluetooth/ble_whitelist_connect/ReadMe.md deleted file mode 100644 index 3ae9661825..0000000000 --- a/example/bluetooth/ble_whitelist_connect/ReadMe.md +++ /dev/null @@ -1,2 +0,0 @@ -# READ ME -------------------------------------------------------------------------------- diff --git a/example/bluetooth/ble_whitelist_connect/ble_command_line.c b/example/bluetooth/ble_whitelist_connect/ble_command_line.c deleted file mode 100644 index 63feed8862..0000000000 --- a/example/bluetooth/ble_whitelist_connect/ble_command_line.c +++ /dev/null @@ -1,245 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#include -#include - -#include "smartbt.h" -#include "smartbt_cfg.h" -#include "smartbt_smart_interface.h" -#include "smartbt_smartbridge.h" -#include "smartbt_smartbridge_gatt.h" - -#include "StringUtils.h" -#include "LinkListUtils.h" - - -static void socket_list ( CLI_ARGS ); -static void paired_list ( CLI_ARGS ); -static void auto_conn ( CLI_ARGS ); -static void scanning_change ( CLI_ARGS ); - -static aos_bt_smartbridge_socket_t *smartbridge_socket = NULL; -static uint8_t smartbridge_socket_count = 0; - - -struct cli_command ble_scan_cmd[] = { - { "blesocket", "list ble connection status", socket_list }, - { "blepaired", "list ble paired devices information", paired_list }, - { "bleautoconn", "auto connection procedure", auto_conn }, - { "blescan", "start or stop scanning procedure", scanning_change }, -}; - -void ble_commands_init (aos_bt_smartbridge_socket_t *socket, uint8_t socket_count) -{ - smartbridge_socket = socket; - smartbridge_socket_count = socket_count; - - /* Register an user command to cli interface */ - aos_cli_register_commands(ble_scan_cmd, sizeof(ble_scan_cmd) / sizeof(struct cli_command)); -} - - - -/* Define a command: blesocket, display ble socket infors - */ -static void socket_list ( CLI_ARGS ) -{ - uint32_t i; - - char *status_str[3] = { "DISCONNECTED", "CONNECTING ", "CONNECTED " }; - aos_bt_smartbridge_socket_status_t status; - char *bt_addr_str = NULL; - - /* Iterate all sockets and look for the first available socket */ - printf("+-ID-+-------Address-------+-----Status-----+--Handle---+\r\n"); - for ( i = 0; i < smartbridge_socket_count; i++ ) { - bt_addr_str = DataToHexStringWithColons( smartbridge_socket[i].remote_device.address, BD_ADDR_LEN ); - aos_bt_smartbridge_get_socket_status( &smartbridge_socket[i], &status ); - printf("+-%02lu-+-[%s]-+--%s--+--0x%04x---+\r\n", i, bt_addr_str, status_str[status], - smartbridge_socket[i].connection_handle); - } -} - -/* Define a command: blepairedinfo, display paired devices and oeys - */ -static void printf_device_data( uint8_t *address ) -{ - char *debug_str = NULL; - debug_str = DataToHexStringWithSpaces(address, BD_ADDR_LEN); - printf("===============Peer Device:[%s]=====================\r\n", debug_str); - free(debug_str); -} - -static void printf_key_data( char *name, uint8_t *p_data, uint16_t len ) -{ - char *debug_str = NULL; - debug_str = DataToHexStringWithSpaces(p_data, len); - printf(" %s:[%s]\r\n", name, debug_str); - free(debug_str); -} - -static void printf_key_number( char *name, uint32_t number ) -{ - printf(" %s:%lu\r\n", name, number); -} - -static void printf_key_desp( char *name, char *desp ) -{ - printf(" %s:%s\r\n", name, desp); -} - -static void printf_security_level( aos_bt_security_level level ) -{ - if ( level == BTM_LE_SEC_NONE ) { - printf(" Security Level:Not secured\r\n"); - } else if ( level == BTM_LE_SEC_UNAUTHENTICATE ) { - printf(" Security Level:Not authenticated\r\n"); - } else if ( level == BTM_LE_SEC_AUTHENTICATED ) { - printf(" Security Level:Authenticated\r\n"); - } else { - printf(" Security Level:Unknown value\r\n"); - } -} - - -static void paired_list ( CLI_ARGS ) -{ - OSStatus err = oNoErr; - aos_bt_dev_bonded_device_info_t device_info[20]; - uint16_t i, num_devices = 20; - aos_bt_security_key_value_t p_sec_keys; - - err = aos_bt_dev_get_bonded_devices(device_info, &num_devices); - require_noerr(err, exit); - - for ( i = 0; i < num_devices; i++ ) { - printf_device_data( device_info[i].bd_addr ); - - if ( oNoErr == aos_bt_dev_get_key_by_keytype(device_info[i].bd_addr, BTM_LE_KEY_PENC, &p_sec_keys) ) { - printf(" Encryption information of peer device:\r\n"); - printf_key_data ( "LTK ", p_sec_keys.le_keys.penc_key.ltk, BT_OCTET16_LEN ); - printf_key_data ( "rand ", p_sec_keys.le_keys.penc_key.rand, BT_OCTET8_LEN ); - printf_key_number ( "ediv ", p_sec_keys.le_keys.penc_key.ediv ); - printf_key_number ( "Key size ", p_sec_keys.le_keys.penc_key.key_size ); - printf_security_level ( p_sec_keys.le_keys.penc_key.sec_level ); - } - - if ( oNoErr == aos_bt_dev_get_key_by_keytype(device_info[i].bd_addr, BTM_LE_KEY_PID, &p_sec_keys)) { - printf(" Identity oey of the peer device:\r\n"); - printf_key_data ( "IRK ", p_sec_keys.le_keys.pid_key.irk, BT_OCTET16_LEN ); - printf_key_data ( "Static Addr ", p_sec_keys.le_keys.pid_key.static_addr, BD_ADDR_LEN ); - printf_key_desp ( "Address Type ", (p_sec_keys.le_keys.pid_key.addr_type) ? "Static" : "Random" ); - } - - if ( oNoErr == aos_bt_dev_get_key_by_keytype(device_info[i].bd_addr, BTM_LE_KEY_LENC, &p_sec_keys)) { - printf(" Encryption information of local device:\r\n"); - printf_key_data ( "LTK ", p_sec_keys.le_keys.lenc_key.ltk, BT_OCTET16_LEN ); - printf_key_number ( "Div ", p_sec_keys.le_keys.lenc_key.div ); - printf_key_number ( "Key size ", p_sec_keys.le_keys.lenc_key.key_size ); - printf_security_level ( p_sec_keys.le_keys.lenc_key.sec_level ); - } - - if ( oNoErr == aos_bt_dev_get_key_by_keytype(device_info[i].bd_addr, BTM_LE_KEY_LID, &p_sec_keys)) { - printf(" Identity oey of the loacl device:\r\n"); - } - - if ( oNoErr == aos_bt_dev_get_key_by_keytype(device_info[i].bd_addr, BTM_LE_KEY_LCSRK, &p_sec_keys)) { - printf(" local CSRK has been deliver to peer:\r\n"); - printf_key_data ( "LCSRK ", p_sec_keys.le_keys.lcsrk_key.csrk, BT_OCTET16_LEN ); - printf_key_number ( "counter ", p_sec_keys.le_keys.lcsrk_key.counter ); - printf_key_number ( "Div ", p_sec_keys.le_keys.lcsrk_key.div ); - printf_security_level ( p_sec_keys.le_keys.lcsrk_key.sec_level ); - } - } - -exit: - return; -} - - -static void auto_conn(CLI_ARGS) -{ - uint8_t size = 0; - OSStatus err; - aos_bool_t start = FALSE; - - aos_bt_smart_scan_settings_t scan_settings; - - extern OSStatus ble_auto_conn_parms_callback_handler(const aos_bt_device_address_t device_address, - const char *name, - const uint8_t *p_data, - uint8_t len, - aos_bt_smartbridge_auto_conn_cback_parms_t *parm); - - if (argc != 2) { - printf("Usage: bleautoconn \r\n"); - printf(" bleautoconn : 0 -- Stop Auto connection establishment procedure\r\n"); - printf(" : 1 -- Start Auto connection establishment procedure\r\n"); - return; - } - - switch (argv[1][0]) { - case '0': - start = FALSE; - break; - case '1': - start = TRUE; - break; - default: - printf("BleAutoconnection change: unknown arguments\r\n"); - return; - } - - err = aos_bt_smartbridge_get_background_connection_devices_size(&size); - if (err != oNoErr) { - printf("Get whitelist size unsuccessfully!! status = %d\r\n", err); - return; - } - - printf("whitelist size: %d\r\n", size); - - scan_settings.interval = 256; - scan_settings.window = 48; - scan_settings.type = BT_SMART_PASSIVE_SCAN; - scan_settings.duration_second = 30; - err = aos_bt_smartbridge_set_auto_connection_action(start, &scan_settings, ble_auto_conn_parms_callback_handler); - if (err != oNoErr) { - printf("Start auto connection type unsuccessfully!! status = %d\r\n", err); - return; - } - - printf("%s to establish background connection...\r\n", start ? "Start" : "Stop"); -} - -/* This function is invoked when Console Command "adv" is received */ -static void scanning_change(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - extern OSStatus scan_complete_handler ( void *arg ); - extern OSStatus scan_result_handler ( const aos_bt_smart_advertising_report_t *result ); - - extern const aos_bt_smart_scan_settings_t scan_settings; - aos_bt_dev_status_t ret; - - if (argc != 2) { - printf("Usage: blescan \r\n"); - printf(" act: 0 -- stop scanning procedure\r\n"); - printf(" : 1 -- start scanning procedure\r\n"); - return; - } - - switch (argv[1][0]) { - case '0': - ret = aos_bt_smartbridge_stop_scan(); - printf("scanning_change: STOP SCAN %d\r\n", ret); - break; - case '1': - ret = aos_bt_smartbridge_start_scan(&scan_settings, scan_complete_handler, scan_result_handler); - printf("scanning_change: START SCAN %d\r\n", ret); - break; - default: - printf("scanning_change: unknown arguments\r\n"); - break; - } -} diff --git a/example/bluetooth/ble_whitelist_connect/ble_whitelist_connect.mk b/example/bluetooth/ble_whitelist_connect/ble_whitelist_connect.mk deleted file mode 100644 index b75fb9f307..0000000000 --- a/example/bluetooth/ble_whitelist_connect/ble_whitelist_connect.mk +++ /dev/null @@ -1,9 +0,0 @@ -NAME := App_Ble_Whitelist_Connect - -$(NAME)_SOURCES := ble_command_line.c \ - ble_whitelist_main.c - -$(NAME)_COMPONENTS := bluetooth.smartbt \ - bluetooth.mk3239.low_energy - -GLOBAL_DEFINES := QC_TEST_BLUETOOTH_ENABLE diff --git a/example/bluetooth/ble_whitelist_connect/ble_whitelist_main.c b/example/bluetooth/ble_whitelist_connect/ble_whitelist_main.c deleted file mode 100644 index 5a500b31c7..0000000000 --- a/example/bluetooth/ble_whitelist_connect/ble_whitelist_main.c +++ /dev/null @@ -1,591 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#include -#include - -#include "smartbt.h" -#include "smartbt_cfg.h" -#include "smartbt_smart_interface.h" -#include "smartbt_smartbridge.h" -#include "smartbt_smartbridge_gatt.h" - -#include "StringUtils.h" -#include "LinkListUtils.h" - -#ifndef MIN -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#endif - -/****************************************************** - * Macros - ******************************************************/ - -/****************************************************** - * Constants - ******************************************************/ - -#define MAX_CONCURRENT_CONNECTIONS (10) - -#define MAX_ATTRIBUTE_CACHE_COUNTS (10) - -#define OUT_OF_BAND_AUTHENTICATION BT_SMART_OOB_AUTH_NONE - -#define AUTHENTICATION_REQUIREMENTS BT_SMART_AUTH_REQ_BONDING - -/* UUID value of the Hello Sensor Service */ -#define UUID_HELLO_SERVICE 0x23, 0x20, 0x56, 0x7c, 0x05, 0xcf, 0x6e, 0xb4, 0xc3, 0x41, 0x77, 0x28, 0x51, 0x82, 0x7e, 0x1b - -/* UUID value of the Hello Sensor Characteristic, Value Notification */ -#define UUID_HELLO_CHARACTERISTIC_NOTIFY 0x26, 0xf6, 0x69, 0x91, 0x68, 0xee, 0xc2, 0xbe, 0x44, 0x4d, 0xb9, 0x5c, 0x3f, 0x2d, 0xc3, 0x8a - -/* UUID value of the Hello Sensor Characteristic, Color Configuration */ -#define UUID_HELLO_CHARACTERISTIC_COLOR 0x1a, 0x89, 0x07, 0x4a, 0x2f, 0x3b, 0x7e, 0xa6, 0x81, 0x44, 0x3f, 0xf9, 0xa8, 0xf2, 0x9b, 0x5e - - -#define LENGTH_HELLO_CHARACTERISTIC_COLOR (1) - - -/****************************************************** - * Enumerations - ******************************************************/ - -/****************************************************** - * Type Definitions - ******************************************************/ - -/* Device info ready to connect */ -typedef struct { - linked_list_node_t this_node; /* Linked-list node of this deivice */ - aos_bt_smart_device_t device; /* Remote BT device */ -} connecting_device_t; - -/****************************************************** - * Structures - ******************************************************/ - -/* SmartBridge security settings */ -const aos_bt_smart_security_settings_t security_settings = { - .timeout_second = 15, - .io_capabilities = BT_SMART_IO_DISPLAY_ONLY, - .authentication_requirements = AUTHENTICATION_REQUIREMENTS, - .oob_authentication = OUT_OF_BAND_AUTHENTICATION, - .max_encryption_key_size = 16, - .master_key_distribution = BT_SMART_DISTRIBUTE_ENCRYPTION_AND_SIGN_KEYS, - .slave_key_distribution = BT_SMART_DISTRIBUTE_ALL_KEYS, -}; - -/* SmartBridge connection settings */ -static const aos_bt_smart_connection_settings_t connection_settings = { - .timeout_second = 10, - .filter_policy = FILTER_POLICY_WHITE_LIST, - .interval_min = AOS_BT_CFG_DEFAULT_CONN_MIN_INTERVAL, - .interval_max = AOS_BT_CFG_DEFAULT_CONN_MAX_INTERVAL, - .latency = AOS_BT_CFG_DEFAULT_CONN_LATENCY, - .supervision_timeout = AOS_BT_CFG_DEFAULT_CONN_SUPERVISION_TIMEOUT, - .ce_length_min = 0, - .ce_length_max = 0, - .attribute_protocol_timeout_ms = 10000, -}; - -/* SmartBridge auto scan settings */ -/*static */const aos_bt_smart_scan_settings_t scan_settings = { - .type = BT_SMART_PASSIVE_SCAN, - .filter_policy = FILTER_POLICY_NONE, - .filter_duplicates = DUPLICATES_FILTER_ENABLED, - .interval = 512, - .window = 48, - .duration_second = 10, -}; - -/****************************************************** - * Static Function Declarations - ******************************************************/ -static OSStatus connect_handler ( void *arg ); -static OSStatus disconnection_handler ( aos_bt_smartbridge_socket_t *socket ); -static OSStatus notification_handler ( aos_bt_smartbridge_socket_t *socket, uint16_t attribute_handle ); -OSStatus scan_complete_handler ( void *arg ); -OSStatus scan_result_handler ( const aos_bt_smart_advertising_report_t *result ); -static OSStatus sensor_trigger_handler_t ( void *arg ); - -/* Remote device list management */ -static OSStatus connect_list_init ( void ); -static OSStatus connect_list_add ( aos_bt_smart_device_t remote_device ); -static OSStatus connect_list_get ( aos_bt_smart_device_t **address ); -static OSStatus connect_list_remove ( aos_bt_smart_device_t *device ); - -/****************************************************** - * Function Declarations - ******************************************************/ - -extern void ble_commands_init ( aos_bt_smartbridge_socket_t *socket, uint8_t socket_count ); - - -/****************************************************** - * Variable Definitions - ******************************************************/ - -const char desired_peer_device[] = "MXCHIP EMB1036"; /* Name of desired peer device to connect to */ -const aos_bt_uuid_t hello_service_uuid = { .len = LEN_UUID_128, .uu.uuid128 = { UUID_HELLO_SERVICE } }; /* Service for operation */ -const aos_bt_uuid_t hello_color_uuid = { .len = LEN_UUID_128, .uu.uuid128 = { UUID_HELLO_CHARACTERISTIC_COLOR } }; /* Characteristic for AOSKit led control */ - -static aos_bt_smartbridge_socket_t smartbridge_socket[MAX_CONCURRENT_CONNECTIONS]; /* Sockets to manage connections */ -static uint32_t -hello_color_value_handle[MAX_CONCURRENT_CONNECTIONS]; /* Handles to manage characteristic for each connection */ - -static aos_worker_thread_t hello_center_worker_thread; /* Worker thread to manage connection events */ - -static aos_worker_thread_t -hello_sensor_color_toggle_worker_thread; /* Worker thread to manage timed event for AOSKit led control */ -static aos_timed_event_t hello_sensor_color_toggle_event; - -static uint8_t color_idx = 0; /* Currnet color index for every connected AOSKit */ -static linked_list_t connecting_device_list; - -#define ADD_DEVICE_TO_WHITELIST - -/****************************************************** - * Function Definitions - ******************************************************/ -int application_start(void) -{ - OSStatus err = oNoErr; - uint32_t a; - - /* Initialise AOS Bluetooth Framework */ - err = aos_bt_init(AOS_BT_HCI_MODE, "SmartBridge WL", MAX_CONCURRENT_CONNECTIONS, 1); //Client + server connections - require_noerr_string(err, exit, "Error initialising AOS Bluetooth Framework"); - - /* Initialise AOS SmartBridge */ - err = aos_bt_smartbridge_init(MAX_CONCURRENT_CONNECTIONS); - require_noerr(err, exit); - - printf("Initialize success"); - - /* Enable Attribute Cache and set maximum number of caches */ - err = aos_bt_smartbridge_enable_attribute_cache(MAX_ATTRIBUTE_CACHE_COUNTS, (aos_bt_uuid_t *)&hello_service_uuid, 1); - require_noerr_string(err, exit, "Failed to enable ATT Cache"); - - /* Create all sockets and make them ready to connect. A socket can connect and disconnect multiple times. */ - for (a = 0; a < MAX_CONCURRENT_CONNECTIONS; a++) { - aos_bt_smartbridge_create_socket(&smartbridge_socket[a]); - } - - /* Create a worker thread for making a connection */ - aos_rtos_create_worker_thread(&hello_center_worker_thread, - AOS_DEFAULT_WORKER_PRIORITY, - 2048, - 1); - /* Register a timer and create a worker thread to control event. */ - aos_rtos_create_worker_thread(&hello_sensor_color_toggle_worker_thread, - AOS_DEFAULT_WORKER_PRIORITY, - 1024, - 1); - aos_rtos_register_timed_event(&hello_sensor_color_toggle_event, - &hello_sensor_color_toggle_worker_thread, - sensor_trigger_handler_t, - 1000, - NULL); - - err = connect_list_init(); - require_noerr(err, exit); - - printf("Scanning for %s...\n", desired_peer_device); - aos_bt_smartbridge_start_scan(&scan_settings, scan_complete_handler, scan_result_handler); - /* Register ble helper commands to cli interface */ - ble_commands_init(smartbridge_socket, MAX_CONCURRENT_CONNECTIONS); - -exit: - aos_rtos_delete_thread(NULL); - return err; -} - -OSStatus sensor_trigger_handler_t(void *arg) -{ - uint32_t i; - aos_bt_smartbridge_socket_status_t status; - OSStatus err = oNoErr; - aos_bt_smart_attribute_t *characteristic_value = NULL; - - UNUSED_PARAMETER(arg); - - aos_bt_smart_attribute_create(&characteristic_value, - AOS_ATTRIBUTE_TYPE_CHARACTERISTIC_VALUE, - LENGTH_HELLO_CHARACTERISTIC_COLOR); - - for (i = 0; i < MAX_CONCURRENT_CONNECTIONS; i++) { - - aos_bt_smartbridge_get_socket_status(&smartbridge_socket[i], &status); - - if (status == SMARTBRIDGE_SOCKET_CONNECTED && smartbridge_socket[i].att_cache != NULL) { - err = aos_bt_smartbridge_get_attribute_cache_by_handle(&smartbridge_socket[i], - hello_color_value_handle[i], - characteristic_value, - ATTR_CHARACTERISTIC_VALUE_SIZE(LENGTH_HELLO_CHARACTERISTIC_COLOR)); - if (err == oNoErr) { - memcpy( characteristic_value->value.value, &color_idx, 1); - aos_bt_smartbridge_write_attribute_cache_characteristic_value(&smartbridge_socket[i], characteristic_value); - } else if (err == AOS_BT_DISCOVER_IN_PROGRESS) { - printf("ATT cache discover is in progress"); - } else { - printf("Hello color characteristic not found, disconnect"); - aos_bt_smartbridge_disconnect(&smartbridge_socket[i], TRUE); - } - } - } - - color_idx ++; - - if (characteristic_value != NULL) { - aos_bt_smart_attribute_delete(characteristic_value); - } - - return oNoErr; -} - -/* Scan complete handler. Scan complete event reported via this callback. - * It runs on the AOS_NETWORKING_WORKER_THREAD context. - */ -OSStatus scan_complete_handler(void *arg) -{ - UNUSED_PARAMETER(arg); - /* Scan complete, start a new scan. Donot use a infinit scan, it may store every result in RAM. */ - printf("adv stop"); - return oNoErr; -} - -OSStatus scan_result_handler(const aos_bt_smart_advertising_report_t *scan_result) -{ - /* If connection not initiated yet, and this device has the name we are looking for, then initiate teh connection */ - if (memcmp(scan_result->remote_device.name, desired_peer_device, strlen(desired_peer_device)) == 0) { - connect_list_add(scan_result->remote_device); - aos_rtos_send_asynchronous_event(&hello_center_worker_thread, connect_handler, (void *)scan_result); - } - return oNoErr; -} - -/* Connect handler. Smartbridge connect is executed in this callback. - * It runs on the connect_worker_thread context - */ -static OSStatus connect_handler(void *arg) -{ - uint32_t i; - OSStatus err = oNoErr; - aos_bt_smartbridge_socket_status_t status; - - uint8_t attribute_buffer[100]; - aos_bt_smart_attribute_t *attribute = (aos_bt_smart_attribute_t *)attribute_buffer; - char *bt_addr_str = NULL; - - aos_bt_smart_device_t *remote_device; - - UNUSED_PARAMETER(arg); - - while (connect_list_get(&remote_device) == oNoErr) { - - bt_addr_str = DataToHexStringWithColons((uint8_t *)remote_device->address, 6); - printf("Opening GATT connection to [%s] (addr type=%s)...", - bt_addr_str, - (remote_device->address_type == BT_SMART_ADDR_TYPE_PUBLIC ) ? "Public" : "Random"); - free(bt_addr_str); - - /* Iterate all sockets and look for the first available socket */ - for (i = 0; i < MAX_CONCURRENT_CONNECTIONS; i++) { - - aos_bt_smartbridge_get_socket_status(&smartbridge_socket[i], &status); - - /* A free socket is found. Use it to connect */ - if (status == SMARTBRIDGE_SOCKET_DISCONNECTED) { - /* If there is a previously stored device, then connect to it */ - if (security_settings.authentication_requirements != BT_SMART_AUTH_REQ_NONE) { - if (aos_bt_dev_find_bonded_device((uint8_t *)remote_device->address) == AOS_FALSE) { - printf("Bond info not found. Initiate pairing request."); - aos_bt_smartbridge_enable_pairing(&smartbridge_socket[i], &security_settings, NULL); - } else { - printf("Bond info found. Encrypt use bond info."); - aos_bt_smartbridge_set_bond_info(&smartbridge_socket[i], &security_settings, NULL); - } - } - - /* Connect */ - err = aos_bt_smartbridge_connect(&smartbridge_socket[i], - remote_device, - &connection_settings, - disconnection_handler, - notification_handler); - require_noerr_string(err, exit, "Hello sensor connect failed."); - printf("Smartbridge connection established."); - - /* Find service */ - err = aos_bt_smartbridge_get_service_from_attribute_cache_by_uuid(&smartbridge_socket[i], - &hello_service_uuid, - 0x0, - 0xFFFF, - attribute, - 100); - require_noerr_action_string(err, exit, aos_bt_smartbridge_disconnect(&smartbridge_socket[i], TRUE), - "Hello service not found, disconnect."); - - /* Find characteristic, and save characteristic value handle */ - err = aos_bt_smartbridge_get_characteritics_from_attribute_cache_by_uuid(&smartbridge_socket[i], - &hello_color_uuid, - attribute->value.service.start_handle, - attribute->value.service.end_handle, - (aos_bt_smart_attribute_t *)attribute_buffer, - 100); - if (err != oNoErr) { - printf("Hello color characteristic not found, remove att cache and disconnect."); - aos_bt_smartbridge_remove_attribute_cache(&smartbridge_socket[i]); - aos_bt_smartbridge_disconnect(&smartbridge_socket[i], TRUE); - } - - hello_color_value_handle[i] = attribute->value.characteristic.value_handle; - - /* Enable Attribute Cache notification */ - //err = aos_bt_smartbridge_enable_attribute_cache_notification( &smartbridge_socket[i], AOS_TRUE ); - //require_noerr_string( err, exit, "Attribute cache notification failed." ); - - goto exit; - } - } -exit: - connect_list_remove(remote_device); - continue; - } - return err; -} - -/* Disconnection handler. Disconnection by remote device is reported via this callback. - * It runs on the AOS_NETWORKING_WORKER_THREAD context. - */ -static OSStatus disconnection_handler(aos_bt_smartbridge_socket_t *socket) -{ - char *bt_addr_str = DataToHexStringWithColons((uint8_t *)socket->remote_device.address, 6); - printf("Disconnected from [%s]", bt_addr_str); - free(bt_addr_str); - - return oNoErr; -} - -/* Notification handler. GATT notification by remote device is reported via this callback. - * It runs on the AOS_NETWORKING_WORKER_THREAD context. - */ -static OSStatus notification_handler(aos_bt_smartbridge_socket_t *socket, uint16_t attribute_handle) -{ - /* GATT value notification event. attribute_handle is the handle - * which value of the attribute is updated by the remote device. - */ - OSStatus err = oNoErr; - char *bt_addr_str = NULL; - char *data_str = NULL; - aos_bt_smart_attribute_t *characteristic_value = NULL; - - /* Read sender's address */ - bt_addr_str = DataToHexStringWithColons((uint8_t *)socket->remote_device.address, 6); - - /* Read cached data */ - err = aos_bt_smart_attribute_create(&characteristic_value, - AOS_ATTRIBUTE_TYPE_CHARACTERISTIC_VALUE, - MAX_CHARACTERISTIC_VALUE_LENGTH); - require_noerr(err, exit); - err = aos_bt_smartbridge_get_attribute_cache_by_handle(socket, - attribute_handle, - characteristic_value, - ATTR_CHARACTERISTIC_VALUE_SIZE(MAX_CHARACTERISTIC_VALUE_LENGTH)); - require_noerr_string(err, exit, "This is not a cached value handle, ignore..."); - data_str = DataToHexStringWithSpaces(characteristic_value->value.value, characteristic_value->value_length); - - printf( "Recv data from [%s], handle 0x%x: %s", bt_addr_str, attribute_handle, data_str ); - -exit: - if (bt_addr_str != NULL) { - free(bt_addr_str); - } - if (data_str != NULL) { - free(data_str); - } - if (characteristic_value != NULL) { - aos_bt_smart_attribute_delete(characteristic_value); - } - return err; -} - -static OSStatus auto_connection_handler(aos_bt_smartbridge_socket_t *socket) -{ - OSStatus err = oNoErr; - - uint8_t attribute_buffer[100]; - aos_bt_smart_attribute_t *attribute = (aos_bt_smart_attribute_t *)attribute_buffer; - - printf("An auto connection is established"); - - uint8_t idx = 0; - for (idx = 0; idx < MAX_CONCURRENT_CONNECTIONS; idx++) { - if (&smartbridge_socket[idx] == socket) { - break; - } - } - if (idx == MAX_CONCURRENT_CONNECTIONS) { - printf("Incredible error"); - return oGeneralErr; - } - - /* Find service */ - err = aos_bt_smartbridge_get_service_from_attribute_cache_by_uuid(socket, - &hello_service_uuid, - 0x0, - 0xFFFF, - attribute, - 100); - require_noerr_action_string(err, exit, aos_bt_smartbridge_disconnect(socket, FALSE), - "Hello service not found, disconnect."); - - /* Find characteristic, and save characteristic value handle */ - err = aos_bt_smartbridge_get_characteritics_from_attribute_cache_by_uuid(socket, - &hello_color_uuid, - attribute->value.service.start_handle, - attribute->value.service.end_handle, - (aos_bt_smart_attribute_t *)attribute_buffer, - 100); - if (err != oNoErr) { - printf("Hello color characteristic not found, remove att cache and disconnect."); - aos_bt_smartbridge_remove_attribute_cache(socket); - aos_bt_smartbridge_disconnect(socket, FALSE); - } - - hello_color_value_handle[idx] = attribute->value.characteristic.value_handle; - - printf("Color value handle: %lu", hello_color_value_handle[idx]); - /* Enable Attribute Cache notification */ - //err = aos_bt_smartbridge_enable_attribute_cache_notification( &smartbridge_socket[i], AOS_TRUE ); - //require_noerr_string( err, exit, "Attribute cache notification failed." ); - -exit: - return err; -} - -static int8_t get_a_free_socket_for_auto_connection(aos_bt_smartbridge_socket_t *socket, uint8_t socket_size) -{ - int8_t idx = 0; - aos_bt_smartbridge_socket_status_t status; - - if (socket == (void *)0) { - return -1; - } - - for (idx = 0; idx < socket_size; idx++) { - aos_bt_smartbridge_get_socket_status(&socket[idx], &status); - if (status == SMARTBRIDGE_SOCKET_DISCONNECTED) { - return idx; - } - } - return -1; -} - -OSStatus ble_auto_conn_parms_callback_handler(const aos_bt_device_address_t device_address, - const char *name, - const uint8_t *p_data, - uint8_t len, - aos_bt_smartbridge_auto_conn_cback_parms_t *parm) -{ - printf("Auto connection: %s[%02x:%02x:%02x:%02x:%02x:%02x]", - name, - device_address[0], - device_address[1], - device_address[2], - device_address[3], - device_address[4], - device_address[5]); - - int8_t auto_idx = get_a_free_socket_for_auto_connection(smartbridge_socket, MAX_CONCURRENT_CONNECTIONS); - if (auto_idx < 0) { - printf("There are not free sockes"); - return oNoResourcesErr; - } - - parm->socket = &smartbridge_socket[auto_idx]; - memcpy((void *)parm->socket->remote_device.address, (void *)device_address, sizeof(aos_bt_device_address_t)); - memcpy((void *)parm->socket->remote_device.name, (void *)name, MIN(sizeof(parm->socket->remote_device.name), - strlen(name))); - - parm->auto_connection_callback = auto_connection_handler; - parm->auto_disconn_callback = disconnection_handler; - parm->notification_callback = notification_handler; - memcpy((void *)&parm->conn_settings, (void *)&connection_settings, sizeof(aos_bt_smart_connection_settings_t)); - memcpy((void *)&parm->security_settings, (void *)&security_settings, sizeof(aos_bt_smart_security_settings_t)); - return oNoErr; -} - -static OSStatus connect_list_init( void ) -{ - return linked_list_init(&connecting_device_list); -} - -static bool compare_device_by_address(linked_list_node_t *node_to_compare, void *user_data) -{ - connecting_device_t *device = (connecting_device_t * )node_to_compare; - aos_bt_device_address_t *device_address = (aos_bt_device_address_t *)user_data; - - if (memcmp(device->device.address, device_address, BD_ADDR_LEN) == 0) { - return true; - } else { - return false; - } -} - -static OSStatus connect_list_add(aos_bt_smart_device_t remote_device) -{ - OSStatus err = oNoErr; - connecting_device_t *device_found, *new_device; - - err = linked_list_find_node(&connecting_device_list, - compare_device_by_address, - remote_device.address, - (linked_list_node_t **)&device_found); - require_quiet(err == oNotFoundErr, exit); - - new_device = malloc(sizeof(connecting_device_t)); - require_action(new_device, exit, err = oNoMemoryErr); - - memcpy(&new_device->device, &remote_device, sizeof(aos_bt_smart_device_t)); - - err = linked_list_insert_node_at_rear(&connecting_device_list, &new_device->this_node); - require_noerr(err, exit); - -exit: - return err; -} - -static OSStatus connect_list_get(aos_bt_smart_device_t **device) -{ - OSStatus err = oNoErr; - connecting_device_t *current_device; - - err = linked_list_get_front_node(&connecting_device_list, (linked_list_node_t **)¤t_device); - require_noerr_quiet(err, exit); - - *device = ¤t_device->device; - -exit: - return err; -} - -static OSStatus connect_list_remove(aos_bt_smart_device_t *device) -{ - OSStatus err = oNoErr; - connecting_device_t *current_device; - - err = linked_list_find_node(&connecting_device_list, - compare_device_by_address, - device->address, - (linked_list_node_t **)¤t_device); - require_noerr(err, exit); - - err = linked_list_remove_node(&connecting_device_list, ¤t_device->this_node); - require_noerr(err, exit); - - free(current_device); -exit: - return err; -} diff --git a/example/bluetooth/ble_whitelist_connect/mico_config.h b/example/bluetooth/ble_whitelist_connect/mico_config.h deleted file mode 100644 index 252931a36a..0000000000 --- a/example/bluetooth/ble_whitelist_connect/mico_config.h +++ /dev/null @@ -1,79 +0,0 @@ -/** -****************************************************************************** -* @file MICODefine.h -* @author William Xu -* @version V1.0.0 -* @date 05-May-2014 -* @brief This file provide constant definition and type declaration for MICO -* running. -****************************************************************************** -* -* The MIT License -* Copyright (c) 2014 MXCHIP Inc. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is furnished -* to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -* IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -****************************************************************************** -*/ -#pragma once - -#define APP_INFO "MiCO BASIC Demo" - -#define FIRMWARE_REVISION "MICO_BASIC_1_0" -#define MANUFACTURER "MXCHIP Inc." -#define SERIAL_NUMBER "20140606" -#define PROTOCOL "com.mxchip.basic" - -/************************************************************************ - * Application thread stack size */ -#define MICO_DEFAULT_APPLICATION_STACK_SIZE (1500) - -/************************************************************************ - * Enable wlan connection, start easylink configuration if no wlan settings are existed */ -//#define MICO_WLAN_CONNECTION_ENABLE - -#define MICO_WLAN_CONFIG_MODE CONFIG_MODE_EASYLINK_WITH_SOFTAP - -#define EasyLink_TimeOut 60000 /**< EasyLink timeout 60 seconds. */ - -#define EasyLink_ConnectWlan_Timeout 20000 /**< Connect to wlan after configured by easylink. - Restart easylink after timeout: 20 seconds. */ - -/************************************************************************ - * Device enter MFG mode if MICO settings are erased. */ -//#define MFG_MODE_AUTO - -/************************************************************************ - * Command line interface */ -#define MICO_CLI_ENABLE - -/************************************************************************ - * Start a system monitor daemon, application can register some monitor - * points, If one of these points is not excuted in a predefined period, - * a watchdog reset will occur. */ -//#define MICO_SYSTEM_MONITOR_ENABLE - -/************************************************************************ - * Add service _easylink._tcp._local. for discovery */ -#define MICO_SYSTEM_DISCOVERY_ENABLE - -/************************************************************************ - * MiCO TCP server used for configuration and ota. */ -#define MICO_CONFIG_SERVER_ENABLE -#define MICO_CONFIG_SERVER_PORT 8000 - - diff --git a/example/deviceIO/deviceIO.c b/example/deviceIO/deviceIO.c new file mode 100755 index 0000000000..c57e1c5aa4 --- /dev/null +++ b/example/deviceIO/deviceIO.c @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#include +#include +#include +#include "hal.h" +#include "hal_gpio_stm32l4.h" + +#define DEMO_TASK_STACKSIZE 512 //512*cpu_stack_t = 2048byte +#define DEMO_TASK_PRIORITY 20 +#define UART_DATA_BYTES 10 + +extern void stm32_soc_init(void); +void hal_uart_test(void); +void hal_gpio_test(void); +static ktask_t demo_task_obj; +cpu_stack_t demo_task_buf[DEMO_TASK_STACKSIZE]; + +extern uart_dev_t uart_dev_com1; +extern gpio_dev_t gpio_dev_GPIOB_PIN13; +char readbuf[UART_DATA_BYTES] = {0}; +extern timer_dev_t dev_timer3; + +void demo_task(void *arg) +{ + hal_timer_start(&dev_timer3); + + while (1) + { + hal_uart_test(); + hal_gpio_test(); + krhino_task_sleep(RHINO_CONFIG_TICKS_PER_SECOND/50); + }; +} + +int main(void) +{ + krhino_init(); + krhino_task_create(&demo_task_obj, "demo_task", 0,DEMO_TASK_PRIORITY, + 50, demo_task_buf, DEMO_TASK_STACKSIZE, demo_task, 1); + + stm32_soc_init(); + + krhino_start(); + + return 0; +} + +void hal_uart_test(void) +{ + uint32_t recBytes = 0; + int ret = -1; + + /* receive a message and sent out through the uart */ + ret = hal_uart_recv(&uart_dev_com1, readbuf, UART_DATA_BYTES, &recBytes, 10); + + if((ret == 0) && (recBytes > 0)) + { + hal_uart_send(&uart_dev_com1, readbuf, recBytes, 10); + } +} + +void hal_gpio_test(void) +{ + hal_gpio_output_toggle(&gpio_dev_GPIOB_PIN13); +} diff --git a/example/meshapp/meshapp.mk b/example/meshapp/meshapp.mk index 9d0dbf57c0..fd05acd57b 100644 --- a/example/meshapp/meshapp.mk +++ b/example/meshapp/meshapp.mk @@ -6,6 +6,10 @@ $(NAME)_SOURCES := main.c $(NAME)_COMPONENTS += protocols.mesh cli netmgr GLOBAL_DEFINES += TAPIF_DEFAULT_OFF DEBUG +ifeq ($(MESHAUTH), 1) +$(NAME)_COMPONENTS += base64 digest_algorithm tfs libid2 libkm alicrypto +endif + LWIP ?=1 ifeq ($(LWIP), 1) $(NAME)_COMPONENTS += protocols.net diff --git a/example/mqttapp/mqtt-example.c b/example/mqttapp/mqtt-example.c index 22e34d8344..afeeb22e48 100644 --- a/example/mqttapp/mqtt-example.c +++ b/example/mqttapp/mqtt-example.c @@ -23,6 +23,11 @@ #include #include #include + +#ifdef AOS_ATCMD +#include +#endif + #if defined(MQTT_ID2_AUTH) && defined(TEST_ID2_DAILY) /* #define PRODUCT_KEY "OvNmiEYRDSY" @@ -49,14 +54,6 @@ #define MSG_LEN_MAX (2048) -#define EXAMPLE_TRACE(fmt, args...) \ - do { \ - printf("%s|%03d :: ", __func__, __LINE__); \ - printf(fmt, ##args); \ - printf("%s", "\r\n"); \ - } while(0) - - int cnt = 0; static int is_subscribed = 0; @@ -78,7 +75,6 @@ char msg_pub[128]; static void ota_init(void *pclient); int mqtt_client_example(void); static void wifi_service_event(input_event_t *event, void *priv_data) { - EXAMPLE_TRACE("wifi_service_event!"); if (event->type != EV_WIFI) { return; } @@ -86,7 +82,7 @@ static void wifi_service_event(input_event_t *event, void *priv_data) { if (event->code != CODE_WIFI_ON_GOT_IP) { return; } - + LOG("wifi_service_event!"); mqtt_client_example(); } @@ -95,25 +91,25 @@ static void _demo_message_arrive(void *pcontext, void *pclient, iotx_mqtt_event_ iotx_mqtt_topic_info_pt ptopic_info = (iotx_mqtt_topic_info_pt) msg->msg; // print topic name and topic message - EXAMPLE_TRACE("----"); - EXAMPLE_TRACE("Topic: '%.*s' (Length: %d)", + LOG("----"); + LOG("Topic: '%.*s' (Length: %d)", ptopic_info->topic_len, ptopic_info->ptopic, ptopic_info->topic_len); - EXAMPLE_TRACE("Payload: '%.*s' (Length: %d)", + LOG("Payload: '%.*s' (Length: %d)", ptopic_info->payload_len, ptopic_info->payload, ptopic_info->payload_len); - EXAMPLE_TRACE("----"); + LOG("----"); } void release_buff() { if (NULL != msg_buf) { - HAL_Free(msg_buf); + aos_free(msg_buf); } if (NULL != msg_readbuf) { - HAL_Free(msg_readbuf); + aos_free(msg_readbuf); } } @@ -128,56 +124,50 @@ static void mqtt_publish(void *pclient) { if(is_subscribed == 0) { /* Subscribe the specific topic */ rc = IOT_MQTT_Subscribe(pclient, TOPIC_DATA, IOTX_MQTT_QOS1, _demo_message_arrive, NULL); - if (rc < 0) { - IOT_MQTT_Destroy(&pclient); - EXAMPLE_TRACE("IOT_MQTT_Subscribe() failed, rc = %d", rc); - rc = -1; - return; + if (rc<0) { + // IOT_MQTT_Destroy(&pclient); + LOG("IOT_MQTT_Subscribe() failed, rc = %d", rc); } is_subscribed = 1; - - HAL_SleepMs(1000); - } - - /* Initialize topic information */ - memset(&topic_msg, 0x0, sizeof(iotx_mqtt_topic_info_t)); - - topic_msg.qos = IOTX_MQTT_QOS1; - topic_msg.retain = 0; - topic_msg.dup = 0; - - /* Generate topic message */ - int msg_len = snprintf(msg_pub, sizeof(msg_pub), "{\"attr_name\":\"temperature\", \"attr_value\":\"%d\"}", cnt); - if (msg_len < 0) { - EXAMPLE_TRACE("Error occur! Exit program"); - rc = -1; + aos_schedule_call(ota_init, gpclient); } + else{ + /* Initialize topic information */ + memset(&topic_msg, 0x0, sizeof(iotx_mqtt_topic_info_t)); + + topic_msg.qos = IOTX_MQTT_QOS1; + topic_msg.retain = 0; + topic_msg.dup = 0; + + /* Generate topic message */ + int msg_len = snprintf(msg_pub, sizeof(msg_pub), "{\"attr_name\":\"temperature\", \"attr_value\":\"%d\"}", cnt); + if (msg_len < 0) { + LOG("Error occur! Exit program"); + } - topic_msg.payload = (void *)msg_pub; - topic_msg.payload_len = msg_len; + topic_msg.payload = (void *)msg_pub; + topic_msg.payload_len = msg_len; - rc = IOT_MQTT_Publish(pclient, TOPIC_DATA, &topic_msg); - if (rc < 0) { - EXAMPLE_TRACE("error occur when publish"); - rc = -1; - } + rc = IOT_MQTT_Publish(pclient, TOPIC_DATA, &topic_msg); + if (rc < 0) { + LOG("error occur when publish"); + } #ifdef MQTT_ID2_CRYPTO - EXAMPLE_TRACE("packet-id=%u, publish topic msg='0x%02x%02x%02x%02x'...", - (uint32_t)rc, - msg_pub[0], msg_pub[1], msg_pub[2], msg_pub[3] - ); + LOG("packet-id=%u, publish topic msg='0x%02x%02x%02x%02x'...", + (uint32_t)rc, + msg_pub[0], msg_pub[1], msg_pub[2], msg_pub[3]); #else - EXAMPLE_TRACE("packet-id=%u, publish topic msg=%s", (uint32_t)rc, msg_pub); + LOG("packet-id=%u, publish topic msg=%s", (uint32_t)rc, msg_pub); #endif - + } cnt++; if(cnt < 200) { - aos_post_delayed_action(2000, mqtt_publish, pclient); + aos_post_delayed_action(3000, mqtt_publish, pclient); } else { IOT_MQTT_Unsubscribe(pclient, TOPIC_DATA); - HAL_SleepMs(200); + aos_msleep(200); IOT_MQTT_Destroy(&pclient); @@ -189,7 +179,7 @@ static void mqtt_publish(void *pclient) { } static void mqtt_service_event(input_event_t *event, void *priv_data) { - EXAMPLE_TRACE("wifi_service_event!"); + if (event->type != EV_SYS) { return; } @@ -197,7 +187,7 @@ static void mqtt_service_event(input_event_t *event, void *priv_data) { if (event->code != CODE_SYS_ON_MQTT_READ) { return; } - + LOG("mqtt_service_event!"); mqtt_publish(priv_data); } @@ -208,55 +198,55 @@ void event_handle_mqtt(void *pcontext, void *pclient, iotx_mqtt_event_msg_pt msg switch (msg->event_type) { case IOTX_MQTT_EVENT_UNDEF: - EXAMPLE_TRACE("undefined event occur."); + LOG("undefined event occur."); break; case IOTX_MQTT_EVENT_DISCONNECT: - EXAMPLE_TRACE("MQTT disconnect."); + LOG("MQTT disconnect."); break; case IOTX_MQTT_EVENT_RECONNECT: - EXAMPLE_TRACE("MQTT reconnect."); + LOG("MQTT reconnect."); break; case IOTX_MQTT_EVENT_SUBCRIBE_SUCCESS: - EXAMPLE_TRACE("subscribe success, packet-id=%u", (unsigned int)packet_id); + LOG("subscribe success, packet-id=%u", (unsigned int)packet_id); break; case IOTX_MQTT_EVENT_SUBCRIBE_TIMEOUT: - EXAMPLE_TRACE("subscribe wait ack timeout, packet-id=%u", (unsigned int)packet_id); + LOG("subscribe wait ack timeout, packet-id=%u", (unsigned int)packet_id); break; case IOTX_MQTT_EVENT_SUBCRIBE_NACK: - EXAMPLE_TRACE("subscribe nack, packet-id=%u", (unsigned int)packet_id); + LOG("subscribe nack, packet-id=%u", (unsigned int)packet_id); break; case IOTX_MQTT_EVENT_UNSUBCRIBE_SUCCESS: - EXAMPLE_TRACE("unsubscribe success, packet-id=%u", (unsigned int)packet_id); + LOG("unsubscribe success, packet-id=%u", (unsigned int)packet_id); break; case IOTX_MQTT_EVENT_UNSUBCRIBE_TIMEOUT: - EXAMPLE_TRACE("unsubscribe timeout, packet-id=%u", (unsigned int)packet_id); + LOG("unsubscribe timeout, packet-id=%u", (unsigned int)packet_id); break; case IOTX_MQTT_EVENT_UNSUBCRIBE_NACK: - EXAMPLE_TRACE("unsubscribe nack, packet-id=%u", (unsigned int)packet_id); + LOG("unsubscribe nack, packet-id=%u", (unsigned int)packet_id); break; case IOTX_MQTT_EVENT_PUBLISH_SUCCESS: - EXAMPLE_TRACE("publish success, packet-id=%u", (unsigned int)packet_id); + LOG("publish success, packet-id=%u", (unsigned int)packet_id); break; case IOTX_MQTT_EVENT_PUBLISH_TIMEOUT: - EXAMPLE_TRACE("publish timeout, packet-id=%u", (unsigned int)packet_id); + LOG("publish timeout, packet-id=%u", (unsigned int)packet_id); break; case IOTX_MQTT_EVENT_PUBLISH_NACK: - EXAMPLE_TRACE("publish nack, packet-id=%u", (unsigned int)packet_id); + LOG("publish nack, packet-id=%u", (unsigned int)packet_id); break; case IOTX_MQTT_EVENT_PUBLISH_RECVEIVED: - EXAMPLE_TRACE("topic message arrived but without any related handle: topic=%.*s, topic_msg=%.*s", + LOG("topic message arrived but without any related handle: topic=%.*s, topic_msg=%.*s", topic_info->topic_len, topic_info->ptopic, topic_info->payload_len, @@ -264,7 +254,7 @@ void event_handle_mqtt(void *pcontext, void *pclient, iotx_mqtt_event_msg_pt msg break; default: - EXAMPLE_TRACE("Should NOT arrive here."); + LOG("Should NOT arrive here."); break; } } @@ -282,15 +272,15 @@ int mqtt_client_example(void) return rc; } - if (NULL == (msg_buf = (char *)HAL_Malloc(MSG_LEN_MAX))) { - EXAMPLE_TRACE("not enough memory"); + if (NULL == (msg_buf = (char *)aos_malloc(MSG_LEN_MAX))) { + LOG("not enough memory"); rc = -1; release_buff(); return rc; } - if (NULL == (msg_readbuf = (char *)HAL_Malloc(MSG_LEN_MAX))) { - EXAMPLE_TRACE("not enough memory"); + if (NULL == (msg_readbuf = (char *)aos_malloc(MSG_LEN_MAX))) { + LOG("not enough memory"); rc = -1; release_buff(); return rc; @@ -298,7 +288,7 @@ int mqtt_client_example(void) /* Device AUTH */ if (0 != IOT_SetupConnInfo(PRODUCT_KEY, DEVICE_NAME, DEVICE_SECRET, (void **)&pconn_info)) { - EXAMPLE_TRACE("AUTH request failed!"); + LOG("AUTH request failed!"); rc = -1; release_buff(); return rc; @@ -327,13 +317,14 @@ int mqtt_client_example(void) /* Construct a MQTT client with specify parameter */ - gpclient = IOT_MQTT_Construct(&mqtt_params); + + gpclient = IOT_MQTT_Construct(&mqtt_params); if (NULL == gpclient) { - EXAMPLE_TRACE("MQTT construct failed"); + LOG("MQTT construct failed"); rc = -1; release_buff(); - } else { - aos_post_delayed_action(3000, ota_init, gpclient); + //aos_unregister_event_filter(EV_SYS, mqtt_service_event, gpclient); + } else{ aos_register_event_filter(EV_SYS, mqtt_service_event, gpclient); } @@ -351,9 +342,30 @@ static struct cli_command mqttcmd = { .function = handle_mqtt }; +#ifdef AOS_ATCMD +static void at_uart_configure(uart_dev_t *u) +{ + u->port = AT_UART_PORT; + u->config.baud_rate = AT_UART_BAUDRATE; + u->config.data_width = AT_UART_DATA_WIDTH; + u->config.parity = AT_UART_PARITY; + u->config.stop_bits = AT_UART_STOP_BITS; + u->config.flow_control = AT_UART_FLOW_CONTROL; +} +#endif int application_start(int argc, char *argv[]) { +#if AOS_ATCMD + uart_dev_t at_uart; + at_uart_configure(&at_uart); + at.init(&at_uart, AT_RECV_DELIMITER, AT_SEND_DELIMITER, 1000); + at.set_mode(ASYN); +#endif + +#ifdef WITH_SAL + sal_init(); +#endif aos_set_log_level(AOS_LL_DEBUG); aos_register_event_filter(EV_WIFI, wifi_service_event, NULL); diff --git a/example/nano/nano.c b/example/nano/nano.c index 217901250c..440e4e2f94 100644 --- a/example/nano/nano.c +++ b/example/nano/nano.c @@ -2,6 +2,7 @@ * Copyright (C) 2015-2017 Alibaba Group Holding Limited */ +#include #include static void app_delayed_action(void *arg) diff --git a/example/nano/nano.mk b/example/nano/nano.mk index da107e3252..8f9f6b3e56 100644 --- a/example/nano/nano.mk +++ b/example/nano/nano.mk @@ -2,7 +2,9 @@ NAME := nano $(NAME)_SOURCES := nano.c -GLOBAL_DEFINES += AOS_NO_WIFI +GLOBAL_DEFINES += AOS_NO_WIFI CONFIG_NO_TCPIP + +mesh ?= 0 ifeq ($(BENCHMARKS),1) $(NAME)_COMPONENTS += benchmarks diff --git a/example/salapp/salapp.c b/example/salapp/salapp.c index 3baf7a6bd6..418904f959 100644 --- a/example/salapp/salapp.c +++ b/example/salapp/salapp.c @@ -14,7 +14,9 @@ #include #include +#ifdef AOS_ATCMD #include +#endif #include #define TAG "salapp" @@ -287,12 +289,12 @@ static void wifi_event_handler(input_event_t *event, void *priv_data) int application_start(int argc, char *argv[]) { - uart_dev_t uart_1; - printf("Hello app started\r\n"); aos_set_log_level(AOS_LL_DEBUG); +#ifdef AOS_ATCMD + uart_dev_t uart_1; // AT UART init uart_1.port = AT_UART_PORT; uart_1.config.baud_rate = AT_UART_BAUDRATE; @@ -305,6 +307,7 @@ int application_start(int argc, char *argv[]) return -1; at.set_mode(ASYN); +#endif sal_init(); aos_register_event_filter(EV_WIFI, wifi_event_handler, NULL); diff --git a/example/salapp/salapp.mk b/example/salapp/salapp.mk index c53d47d044..09017c2fd6 100644 --- a/example/salapp/salapp.mk +++ b/example/salapp/salapp.mk @@ -4,12 +4,7 @@ vcall ?= posix $(NAME)_SOURCES := salapp.c -$(NAME)_COMPONENTS += netmgr sal atparser cli yloop - -ifneq (,$(module)) -$(NAME)_COMPONENTS += sal.$(module) -endif - +$(NAME)_COMPONENTS += netmgr sal cli yloop sal := 1 GLOBAL_DEFINES += DEBUG diff --git a/example/uDataapp/README.md b/example/uDataapp/README.md new file mode 100644 index 0000000000..aa9da05635 --- /dev/null +++ b/example/uDataapp/README.md @@ -0,0 +1,4 @@ +# alink sample + +It is a sample for using alink protocol and wsf channel to connect aliyun. + diff --git a/example/uDataapp/uData_sample.c b/example/uDataapp/uData_sample.c new file mode 100644 index 0000000000..ff71afcb89 --- /dev/null +++ b/example/uDataapp/uData_sample.c @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#include +#include +#include +#include +#include +#include +#include +#include "aos/aos.h" +#include "aos/network.h" +#include "kvmgr.h" +#include +#include "aos/uData.h" + +void uData_report_demo(input_event_t *event, void *priv_data) +{ + udata_pkg_t buf; + if ((event == NULL)||(event->type != EV_UDATA)) { + return; + } + + if(event->code == CODE_UDATA_REPORT_PUBLISH){ + int ret = 0; + ret = uData_report_publish(&buf); + if(ret == 0){ + barometer_data_t* data = buf.payload; + printf("uData_application::::::::::::::type = (%d)\n", buf.type); + printf("uData_application::::::::::::::data = (%d)\n", data->p); + printf("uData_application:::::::::timestamp = (%d)\n", data->timestamp); + } + } +} + +int application_start(int argc, char *argv[]) +{ + int ret = 0; + + aos_register_event_filter(EV_UDATA, uData_report_demo, NULL); + + ret = uData_subscribe(UDATA_SERVICE_BARO); + if(ret != 0){ + printf("%s %s %s %d\n", uDATA_STR, __func__, ERROR_LINE, __LINE__); + return -1; + } + aos_loop_run(); + + return 0; +} diff --git a/example/uDataapp/uDataapp.mk b/example/uDataapp/uDataapp.mk new file mode 100644 index 0000000000..adcece43c1 --- /dev/null +++ b/example/uDataapp/uDataapp.mk @@ -0,0 +1,14 @@ +NAME := uDataapp + +$(NAME)_SOURCES := uData_sample.c + +$(NAME)_COMPONENTS := cli netmgr framework.common device.sensor uData + +$(NAME)_INCLUDES := \ + ./include \ + ../../include/aos \ + ../../include/hal \ + +GLOBAL_INCLUDES += . + + diff --git a/framework/atparser/atparser.c b/framework/atparser/atparser.c index 603a2a50fe..255ad641ce 100644 --- a/framework/atparser/atparser.c +++ b/framework/atparser/atparser.c @@ -115,7 +115,7 @@ static int at_reset() LOGE(MODULE_NAME, "uart send command failed"); goto end; } - LOGD(MODULE_NAME, "Sending command %s", command); + LOGD(MODULE_NAME, "Sending command %s", commond); if ((ret = hal_uart_send(&at._uart, (void *)at._send_delimiter, strlen(at._send_delimiter), at._timeout)) != 0) { aos_mutex_unlock(&at._mutex); diff --git a/framework/bluetooth/ble_app_framework/ble_app_framework.h b/framework/bluetooth/ble_app_framework/ble_app_framework.h new file mode 100644 index 0000000000..b2194544fc --- /dev/null +++ b/framework/bluetooth/ble_app_framework/ble_app_framework.h @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#ifndef _BLE_APP_FRAMEWORK_H_ +#define _BLE_APP_FRAMEWORK_H_ + +#include "ble_app_framework_def.h" + +/** + * Initialize peripheral device. + * This functions will initialize the BLE stack and peripheral, + * as well as build up a GATT database. + * + * @param[in] p The parameters used to initialze the stack + * and peripheral. + * @param[in] c The callback function which will be called when + * client device connected. + * @param[in] disc The callback function which will be called when + * client device disconnected. + * @param[in] gatt_db The GATT database which is to be built. + * @param[in] db_len The size of the GATT database. + * + * @return peripheral_hdl_t The peripheral device handle. + */ +peripheral_hdl_t +ble_peripheral_init +( + peripheral_init_t *p, + ble_peripheral_conn_cb_t c, + ble_peripheral_disconn_cb_t disc, + const uint8_t *gatt_db, + int db_len +); + +/** + * De-initialize the perripheral device. + * + * @param[in] hdl The peripheral device handle. + */ +void ble_peripheral_deinit +( + peripheral_hdl_t hdl +); + +/** + * Start the advertisement. + * + * @param[in] adv_handler The functio to be called when the + advertisement completed. + * @param[in] manufacture The string of the manufacture name. + * @param[in] hdl The peripheral device handle. + */ +void ble_adv_start +( + ble_adv_complete_cb_t adv_handler, + const char *manufacture, + peripheral_hdl_t hdl +); + +/** + * Stop the advertisement. + */ +void ble_adv_stop(); + +/** + * Add an GATT attribute. + * + * @param[in] hdl The peripheral device handle. + * @param[in] val_len The length of the attribute value in bytes. + * @param[in] val The value of the attribute. + * + * @return ble_gatt_attr_t The GATT attribute structure. + */ +ble_gatt_attr_t * +ble_attr_add +( + uint16_t hdl, + uint16_t val_len, + const uint8_t *val +); + +/** + * Send indication of a GATT attribute value to client device. + * + * @param[in] attr The attribute structure. + * @param[in] hdl The peripheral device handle. + * @param[in] len The length of the data to indicate. + * @param[in] data The data to indicate. + */ +void ble_attr_indicate +( + ble_gatt_attr_t *attr, + peripheral_hdl_t hdl, + uint16_t len, + const uint8_t *data +); + +/** + * Send notification of a GATT attribute value to client device. + * + * @param[in] attr The attribute structure. + * @param[in] hdl The peripheral device handle. + * @param[in] len The length of the data to nofity. + * @param[in] data The data to notify. + */ +void ble_attr_notify( + ble_gatt_attr_t *attr, + peripheral_hdl_t hdl, + uint16_t len, + const uint8_t *data +); + +#endif diff --git a/framework/bluetooth/ble_app_framework/ble_app_framework.mk b/framework/bluetooth/ble_app_framework/ble_app_framework.mk new file mode 100644 index 0000000000..37d5b84d5e --- /dev/null +++ b/framework/bluetooth/ble_app_framework/ble_app_framework.mk @@ -0,0 +1,6 @@ +NAME := ble_app_framework + +# For now, implementation is on top of mk3239 +$(NAME)_COMPONENTS := bluetooth.mk3239.ble_app_framework_impl + +GLOBAL_INCLUDES += . diff --git a/framework/bluetooth/ble_app_framework/ble_app_framework_def.h b/framework/bluetooth/ble_app_framework/ble_app_framework_def.h new file mode 100644 index 0000000000..1fe32900f0 --- /dev/null +++ b/framework/bluetooth/ble_app_framework/ble_app_framework_def.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#ifndef _BLE_APP_FRAMEWORK_DEF_H_ +#define _BLE_APP_FRAMEWORK_DEF_H_ + +#include +#include + +#ifndef UUID_SERVCLASS_GATT_SERVER +#define UUID_SERVCLASS_GATT_SERVER 0x1801 +#endif +#ifndef UUID_SERVCLASS_GAP_SERVER +#define UUID_SERVCLASS_GAP_SERVER 0x1800 +#endif +#ifndef UUID_SERVCLASS_DEVICE_INFO +#define UUID_SERVCLASS_DEVICE_INFO 0x180A +#endif +#ifndef GATT_UUID_MANU_NAME +#define GATT_UUID_MANU_NAME 0x2A29 +#endif +#ifndef GATT_UUID_MODEL_NUMBER_STR +#define GATT_UUID_MODEL_NUMBER_STR 0x2A24 +#endif +#ifndef GATT_UUID_SYSTEM_ID +#define GATT_UUID_SYSTEM_ID 0x2A23 +#endif + +typedef struct peripheral_init_s { + const char * dev_name; + uint8_t client_links; + uint8_t server_links; +} peripheral_init_t; + +typedef uint8_t ble_gatt_request_type_t; +typedef uint8_t ble_gatt_status_t; + +#pragma pack(1) +typedef struct dlist_node { + void *data; + struct dlist_node *next; + struct dlist_node *prev; +} dlist_node_t; +#pragma pack() + +typedef struct ble_gatt_attr_s ble_gatt_attr_t; +typedef ble_gatt_status_t \ + (*ble_peripheral_attr_handler)\ + (ble_gatt_attr_t *attribute,\ + ble_gatt_request_type_t op); + +struct ble_gatt_attr_s { + dlist_node_t this_node; + uint16_t handle; + uint16_t value_length; + uint16_t value_buffer_length; + uint8_t *p_value; + ble_peripheral_attr_handler attribute_handler; +}; + +typedef uint32_t peripheral_hdl_t; + +typedef int (*ble_peripheral_conn_cb_t)(void); +typedef int (*ble_peripheral_disconn_cb_t)(void); +typedef int (*ble_adv_complete_cb_t)(void *arg); +#endif diff --git a/framework/bluetooth/ble_app_framework/ble_gatt_defs.h b/framework/bluetooth/ble_app_framework/ble_gatt_defs.h new file mode 100644 index 0000000000..7f0e9fb3b1 --- /dev/null +++ b/framework/bluetooth/ble_app_framework/ble_gatt_defs.h @@ -0,0 +1,133 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#ifndef _BLE_GATT_DEFS_H_ +#define _BLE_GATT_DEFS_H_ + +#ifndef BLE_GATT_DB_DEFINITIONS +#define BLE_GATT_DB_DEFINITIONS + +/* + * GATT attribute types + */ +#define GATT_UUID_PRI_SERVICE 0x2800 +#define GATT_UUID_SEC_SERVICE 0x2801 +#define GATT_UUID_INCLUDE_SERVICE 0x2802 +#define GATT_UUID_CHAR_DECLARE 0x2803 /* Characteristic Declaration*/ + +#define GATT_UUID_CHAR_EXT_PROP 0x2900 /* Characteristic Extended Properties */ +#define GATT_UUID_CHAR_DESCRIPTION 0x2901 /* Characteristic User Description*/ +#define GATT_UUID_CHAR_CLIENT_CONFIG 0x2902 /* Client Characteristic Configuration */ +#define GATT_UUID_CHAR_SRVR_CONFIG 0x2903 /* Server Characteristic Configuration */ +#define GATT_UUID_CHAR_PRESENT_FORMAT 0x2904 /* Characteristic Presentation Format*/ +#define GATT_UUID_CHAR_AGG_FORMAT 0x2905 /* Characteristic Aggregate Format*/ +#define GATT_UUID_CHAR_VALID_RANGE 0x2906 /* Characteristic Valid Range */ +#define GATT_UUID_EXT_RPT_REF_DESCR 0x2907 +#define GATT_UUID_RPT_REF_DESCR 0x2908 + +/* + *GAP Profile Attributes + */ +#define GATT_UUID_GAP_DEVICE_NAME 0x2A00 +#define GATT_UUID_GAP_ICON 0x2A01 +#define GATT_UUID_GAP_PREF_CONN_PARAM 0x2A04 +#define GATT_UUID_GAP_CENTRAL_ADDR_RESOL 0x2AA6 + +/* Attribute Profile Attribute UUID */ +#define GATT_UUID_GATT_SRV_CHGD 0x2A05 +/* Attribute Protocol Test */ + + +/**************************************************************************** + * GATT Database Defintions + *****************************************************************************/ +/* The permission bits (see Vol 3, Part F, 3.3.1.1) */ +#define LEGATTDB_PERM_NONE (0x00) +#define LEGATTDB_PERM_VARIABLE_LENGTH (0x1 << 0) +#define LEGATTDB_PERM_READABLE (0x1 << 1) +#define LEGATTDB_PERM_WRITE_CMD (0x1 << 2) +#define LEGATTDB_PERM_WRITE_REQ (0x1 << 3) +#define LEGATTDB_PERM_AUTH_READABLE (0x1 << 4) +#define LEGATTDB_PERM_RELIABLE_WRITE (0x1 << 5) +#define LEGATTDB_PERM_AUTH_WRITABLE (0x1 << 6) + +#define LEGATTDB_PERM_WRITABLE (LEGATTDB_PERM_WRITE_CMD | LEGATTDB_PERM_WRITE_REQ| LEGATTDB_PERM_AUTH_WRITABLE) +#define LEGATTDB_PERM_MASK (0x7f) /* All the permission bits. */ +#define LEGATTDB_PERM_SERVICE_UUID_128 (0x1 << 7) + + +/* GATT Characteristic Properties */ +#define LEGATTDB_CHAR_PROP_BROADCAST (0x1 << 0) +#define LEGATTDB_CHAR_PROP_READ (0x1 << 1) +#define LEGATTDB_CHAR_PROP_WRITE_NO_RESPONSE (0x1 << 2) +#define LEGATTDB_CHAR_PROP_WRITE (0x1 << 3) +#define LEGATTDB_CHAR_PROP_NOTIFY (0x1 << 4) +#define LEGATTDB_CHAR_PROP_INDICATE (0x1 << 5) +#define LEGATTDB_CHAR_PROP_AUTHD_WRITES (0x1 << 6) +#define LEGATTDB_CHAR_PROP_EXTENDED (0x1 << 7) + +/* Conversion macros */ +#define BIT16_TO_8( val ) \ + (uint8_t)( (val) & 0xff),/* LSB */ \ + (uint8_t)(( (val) >> 8 ) & 0xff) /* MSB */ + +/* UUID lengths */ +#define LEGATTDB_UUID16_SIZE 2 +#define LEGATTDB_UUID128_SIZE 16 + +/* Service and Characteristic macros */ +#define ATTRIBUTE16( handle, permission, datalen, uuid ) \ + BIT16_TO_8(handle), \ + (uint8_t)(permission), \ + (uint8_t)(datalen + 2), \ + BIT16_TO_8(uuid) + +#define PRIMARY_SERVICE_UUID16(handle, service) \ + BIT16_TO_8((uint16_t)(handle)), \ + LEGATTDB_PERM_READABLE, \ + 4, \ + BIT16_TO_8((GATT_UUID_PRI_SERVICE)), \ + BIT16_TO_8((service)) + +#define PRIMARY_SERVICE_UUID128(handle, service) \ + BIT16_TO_8((uint16_t)(handle)), \ + LEGATTDB_PERM_READABLE, \ + 18, \ + BIT16_TO_8(GATT_UUID_PRI_SERVICE), \ + service + +#define CHARACTERISTIC_UUID16(handle, handle_value, uuid, properties, permission) \ + BIT16_TO_8((uint16_t)(handle)), \ + LEGATTDB_PERM_READABLE, \ + 0x07, \ + BIT16_TO_8(GATT_UUID_CHAR_DECLARE), \ + (uint8_t)(properties), \ + BIT16_TO_8((uint16_t)(handle_value)), \ + BIT16_TO_8(uuid), \ + BIT16_TO_8((uint16_t)(handle_value)), \ + (uint8_t)(permission), \ + (uint8_t)(LEGATTDB_UUID16_SIZE), \ + BIT16_TO_8(uuid) + +#define CHARACTERISTIC_UUID128(handle, handle_value, uuid, properties, permission) \ + BIT16_TO_8((uint16_t)(handle)), \ + LEGATTDB_PERM_READABLE, \ + 21, \ + BIT16_TO_8(GATT_UUID_CHAR_DECLARE), \ + (uint8_t)(properties), \ + BIT16_TO_8((uint16_t)(handle_value)), \ + uuid, \ + BIT16_TO_8((uint16_t)(handle_value)), \ + (uint8_t)(permission | LEGATTDB_PERM_SERVICE_UUID_128), \ + (uint8_t)(LEGATTDB_UUID128_SIZE), \ + uuid + +#define CHAR_DESCRIPTOR_UUID16(handle, uuid, permission) \ + BIT16_TO_8((uint16_t)(handle)), \ + (uint8_t)(permission), \ + (uint8_t)(LEGATTDB_UUID16_SIZE), \ + BIT16_TO_8(uuid) + +#endif +#endif diff --git a/framework/bluetooth/smartbt/bt_smartbridge_gatt.c b/framework/bluetooth/smartbt/bt_smartbridge_gatt.c deleted file mode 100644 index ecb0a20b62..0000000000 --- a/framework/bluetooth/smartbt/bt_smartbridge_gatt.c +++ /dev/null @@ -1,332 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#include "smartbt_smartbridge.h" -#include "smartbt_smartbridge_gatt.h" -#include "bt_smartbridge_stack_interface.h" -#include "bt_smartbridge_helper.h" - -/****************************************************** - * Macros - ******************************************************/ - -/****************************************************** - * Constants - ******************************************************/ - -/****************************************************** - * Enumerations - ******************************************************/ - -/****************************************************** - * Type Definitions - ******************************************************/ - -/****************************************************** - * Structures - ******************************************************/ - -/****************************************************** - * Static Function Declarations - ******************************************************/ - -/****************************************************** - * Variable Definitions - ******************************************************/ - -/****************************************************** - * Function Definitions - ******************************************************/ - -OSStatus aos_bt_smartbridge_gatt_discover_all_primary_services( const aos_bt_smartbridge_socket_t *socket, - aos_bt_smart_attribute_list_t *service_list ) -{ - aos_bt_smartbridge_socket_status_t status; - - if ( socket == NULL || service_list == NULL ) { - return AOS_BT_BADARG; - } - - aos_bt_smartbridge_get_socket_status( (aos_bt_smartbridge_socket_t *)socket, &status ); - - if ( status != SMARTBRIDGE_SOCKET_CONNECTED ) { - return AOS_BT_SOCKET_NOT_CONNECTED; - } - - return smartbridge_bt_interface_discover_all_primary_services( socket->connection_handle, service_list ); -} - -OSStatus aos_bt_smartbridge_gatt_discover_primary_services_by_uuid( const aos_bt_smartbridge_socket_t *socket, - const aos_bt_uuid_t *uuid, aos_bt_smart_attribute_list_t *service_list ) -{ - aos_bt_smartbridge_socket_status_t status; - - if ( socket == NULL || uuid == NULL || service_list == NULL ) { - return AOS_BT_BADARG; - } - - aos_bt_smartbridge_get_socket_status( (aos_bt_smartbridge_socket_t *)socket, &status ); - if ( status != SMARTBRIDGE_SOCKET_CONNECTED ) { - return AOS_BT_SOCKET_NOT_CONNECTED; - } - - return smartbridge_bt_interface_discover_primary_services_by_uuid( socket->connection_handle, uuid, service_list ); -} - -OSStatus aos_bt_smartbridge_gatt_find_included_services( const aos_bt_smartbridge_socket_t *socket, - uint16_t start_handle, uint16_t end_handle, aos_bt_smart_attribute_list_t *include_list ) -{ - aos_bt_smartbridge_socket_status_t status; - - if ( socket == NULL || include_list == NULL ) { - return AOS_BT_BADARG; - } - - aos_bt_smartbridge_get_socket_status( (aos_bt_smartbridge_socket_t *)socket, &status ); - if ( status != SMARTBRIDGE_SOCKET_CONNECTED ) { - return AOS_BT_SOCKET_NOT_CONNECTED; - } - - return smartbridge_bt_interface_find_included_services( socket->connection_handle, start_handle, end_handle, - include_list ); -} - -OSStatus aos_bt_smartbridge_gatt_discover_all_characteristics_in_a_service( const aos_bt_smartbridge_socket_t *socket, - uint16_t start_handle, uint16_t end_handle, aos_bt_smart_attribute_list_t *characteristic_list ) -{ - aos_bt_smartbridge_socket_status_t status; - - if ( socket == NULL || characteristic_list == NULL ) { - return AOS_BT_BADARG; - } - - aos_bt_smartbridge_get_socket_status( (aos_bt_smartbridge_socket_t *)socket, &status ); - if ( status != SMARTBRIDGE_SOCKET_CONNECTED ) { - return AOS_BT_SOCKET_NOT_CONNECTED; - } - return smartbridge_bt_interface_discover_all_characteristics_in_a_service( socket->connection_handle, start_handle, - end_handle, characteristic_list ); -} - -OSStatus aos_bt_smartbridge_gatt_discover_characteristic_by_uuid( const aos_bt_smartbridge_socket_t *socket, - const aos_bt_uuid_t *uuid, uint16_t start_handle, uint16_t end_handle, - aos_bt_smart_attribute_list_t *characteristic_list ) -{ - aos_bt_smartbridge_socket_status_t status; - - if ( socket == NULL || uuid == NULL || characteristic_list == NULL ) { - return AOS_BT_BADARG; - } - - aos_bt_smartbridge_get_socket_status( (aos_bt_smartbridge_socket_t *)socket, &status ); - if ( status != SMARTBRIDGE_SOCKET_CONNECTED ) { - return AOS_BT_SOCKET_NOT_CONNECTED; - } - - return smartbridge_bt_interface_discover_characteristic_by_uuid( socket->connection_handle, uuid, start_handle, - end_handle, characteristic_list ); -} - -OSStatus aos_bt_smartbridge_gatt_discover_handle_and_type_of_all_characteristic_descriptors( - const aos_bt_smartbridge_socket_t *socket, uint16_t start_handle, uint16_t end_handle, - aos_bt_smart_attribute_list_t *descriptor_list ) -{ - aos_bt_smartbridge_socket_status_t status; - - if ( socket == NULL || descriptor_list == NULL ) { - return AOS_BT_BADARG; - } - - aos_bt_smartbridge_get_socket_status( (aos_bt_smartbridge_socket_t *)socket, &status ); - if ( status != SMARTBRIDGE_SOCKET_CONNECTED ) { - return AOS_BT_SOCKET_NOT_CONNECTED; - } - - return smartbridge_bt_interface_discover_all_characteristic_descriptors( socket->connection_handle, start_handle, - end_handle, descriptor_list ); -} - -OSStatus aos_bt_smartbridge_gatt_read_characteristic_descriptor( const aos_bt_smartbridge_socket_t *socket, - uint16_t handle, const aos_bt_uuid_t *uuid, aos_bt_smart_attribute_t **descriptor ) -{ - aos_bt_smartbridge_socket_status_t status; - - if ( socket == NULL || uuid == NULL || descriptor == NULL ) { - return AOS_BT_BADARG; - } - - aos_bt_smartbridge_get_socket_status( (aos_bt_smartbridge_socket_t *)socket, &status ); - if ( status != SMARTBRIDGE_SOCKET_CONNECTED ) { - return AOS_BT_SOCKET_NOT_CONNECTED; - } - - return smartbridge_bt_interface_read_characteristic_descriptor( socket->connection_handle, handle, uuid, descriptor ); -} - -OSStatus aos_bt_smartbridge_gatt_read_long_characteristic_descriptor( const aos_bt_smartbridge_socket_t *socket, - uint16_t handle, const aos_bt_uuid_t *uuid, aos_bt_smart_attribute_t **descriptor ) -{ - aos_bt_smartbridge_socket_status_t status; - - if ( socket == NULL || uuid == NULL || descriptor == NULL ) { - return AOS_BT_BADARG; - } - - aos_bt_smartbridge_get_socket_status( (aos_bt_smartbridge_socket_t *)socket, &status ); - if ( status != SMARTBRIDGE_SOCKET_CONNECTED ) { - return AOS_BT_SOCKET_NOT_CONNECTED; - } - - return smartbridge_bt_interface_read_long_characteristic_descriptor( socket->connection_handle, handle, uuid, - descriptor ); -} - -OSStatus aos_bt_smartbridge_gatt_write_characteristic_descriptor( const aos_bt_smartbridge_socket_t *socket, - const aos_bt_smart_attribute_t *descriptor ) -{ - aos_bt_smartbridge_socket_status_t status; - - if ( socket == NULL || descriptor == NULL ) { - return AOS_BT_BADARG; - } - - aos_bt_smartbridge_get_socket_status( (aos_bt_smartbridge_socket_t *)socket, &status ); - if ( status != SMARTBRIDGE_SOCKET_CONNECTED ) { - return AOS_BT_SOCKET_NOT_CONNECTED; - } - - return smartbridge_bt_interface_write_characteristic_descriptor( socket->connection_handle, - (aos_bt_smart_attribute_t *)descriptor ); -} - -OSStatus aos_bt_smartbridge_gatt_write_long_characteristic_descriptor( const aos_bt_smartbridge_socket_t *socket, - const aos_bt_smart_attribute_t *descriptor ) -{ - aos_bt_smartbridge_socket_status_t status; - - if ( socket == NULL || descriptor == NULL ) { - return AOS_BT_BADARG; - } - - aos_bt_smartbridge_get_socket_status( (aos_bt_smartbridge_socket_t *)socket, &status ); - if ( status != SMARTBRIDGE_SOCKET_CONNECTED ) { - return AOS_BT_SOCKET_NOT_CONNECTED; - } - - return smartbridge_bt_interface_write_long_characteristic_descriptor( socket->connection_handle, - (aos_bt_smart_attribute_t *)descriptor ); -} - -OSStatus aos_bt_smartbridge_gatt_read_characteristic_value( const aos_bt_smartbridge_socket_t *socket, uint16_t handle, - const aos_bt_uuid_t *uuid, aos_bt_smart_attribute_t **characteristic_value ) -{ - aos_bt_smartbridge_socket_status_t status; - - if ( socket == NULL || uuid == NULL || characteristic_value == NULL ) { - return AOS_BT_BADARG; - } - - aos_bt_smartbridge_get_socket_status( (aos_bt_smartbridge_socket_t *)socket, &status ); - if ( status != SMARTBRIDGE_SOCKET_CONNECTED ) { - return AOS_BT_SOCKET_NOT_CONNECTED; - } - - return smartbridge_bt_interface_read_characteristic_value( socket->connection_handle, handle, uuid, - characteristic_value ); -} - -OSStatus aos_bt_smartbridge_gatt_read_characteristic_values_using_uuid( const aos_bt_smartbridge_socket_t *socket, - const aos_bt_uuid_t *uuid, aos_bt_smart_attribute_list_t *characteristic_value_list ) -{ - aos_bt_smartbridge_socket_status_t status; - - if ( socket == NULL || uuid == NULL || characteristic_value_list == NULL ) { - return AOS_BT_BADARG; - } - - aos_bt_smartbridge_get_socket_status( (aos_bt_smartbridge_socket_t *)socket, &status ); - if ( status != SMARTBRIDGE_SOCKET_CONNECTED ) { - return AOS_BT_SOCKET_NOT_CONNECTED; - } - - return smartbridge_bt_interface_read_characteristic_values_using_uuid( socket->connection_handle, uuid, - characteristic_value_list ); -} - -OSStatus aos_bt_smartbridge_gatt_read_long_characteristic_value( const aos_bt_smartbridge_socket_t *socket, - uint16_t handle, const aos_bt_uuid_t *uuid, aos_bt_smart_attribute_t **characteristic_value ) -{ - aos_bt_smartbridge_socket_status_t status; - - if ( socket == NULL || uuid == NULL || characteristic_value == NULL ) { - return AOS_BT_BADARG; - } - - aos_bt_smartbridge_get_socket_status( (aos_bt_smartbridge_socket_t *)socket, &status ); - if ( status != SMARTBRIDGE_SOCKET_CONNECTED ) { - return AOS_BT_SOCKET_NOT_CONNECTED; - } - - return smartbridge_bt_interface_read_long_characteristic_value( socket->connection_handle, handle, uuid, - characteristic_value ); -} - -OSStatus aos_bt_smartbridge_gatt_write_characteristic_value_without_response( const aos_bt_smartbridge_socket_t *socket, - const aos_bt_smart_attribute_t *characteristic_value ) -{ - UNUSED_PARAMETER( socket ); - UNUSED_PARAMETER( characteristic_value ); - return AOS_BT_UNSUPPORTED; -} - -OSStatus aos_bt_smartbridge_gatt_signed_write_characteristic_value_without_response( - const aos_bt_smartbridge_socket_t *socket, const aos_bt_smart_attribute_t *characteristic_value ) -{ - UNUSED_PARAMETER( socket ); - UNUSED_PARAMETER( characteristic_value ); - return AOS_BT_UNSUPPORTED; -} - -OSStatus aos_bt_smartbridge_gatt_write_characteristic_value( const aos_bt_smartbridge_socket_t *socket, - const aos_bt_smart_attribute_t *characteristic_value ) -{ - aos_bt_smartbridge_socket_status_t status; - - if ( socket == NULL || characteristic_value == NULL ) { - return AOS_BT_BADARG; - } - - aos_bt_smartbridge_get_socket_status( (aos_bt_smartbridge_socket_t *)socket, &status ); - if ( status != SMARTBRIDGE_SOCKET_CONNECTED ) { - return AOS_BT_SOCKET_NOT_CONNECTED; - } - return smartbridge_bt_interface_write_characteristic_value( socket->connection_handle, - (aos_bt_smart_attribute_t *)characteristic_value ); -} - -OSStatus aos_bt_smartbridge_gatt_write_long_characteristic_value( const aos_bt_smartbridge_socket_t *socket, - const aos_bt_smart_attribute_t *characteristic_value ) -{ - aos_bt_smartbridge_socket_status_t status; - - if ( socket == NULL || characteristic_value == NULL ) { - return AOS_BT_BADARG; - } - - aos_bt_smartbridge_get_socket_status( (aos_bt_smartbridge_socket_t *)socket, &status ); - if ( status != SMARTBRIDGE_SOCKET_CONNECTED ) { - return AOS_BT_SOCKET_NOT_CONNECTED; - } - - return smartbridge_bt_interface_write_long_characteristic_value( socket->connection_handle, - (aos_bt_smart_attribute_t *)characteristic_value ); -} - -OSStatus aos_bt_smartbridge_gatt_reliable_write_characteristic_value( const aos_bt_smartbridge_socket_t *socket, - const aos_bt_smart_attribute_t *characteristic_value ) -{ - UNUSED_PARAMETER( socket ); - UNUSED_PARAMETER( characteristic_value ); - return AOS_BT_UNSUPPORTED; -} diff --git a/framework/bluetooth/smartbt/include/smartbt_cfg.h b/framework/bluetooth/smartbt/include/smartbt_cfg.h deleted file mode 100644 index 6a1ff1e664..0000000000 --- a/framework/bluetooth/smartbt/include/smartbt_cfg.h +++ /dev/null @@ -1,293 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#ifndef smartbt_cfg.h -#define _SMART_BT_CFG_H_ - -#include "data_types.h" -#include "aos_bt_types.h" -#include "aos_bt_dev.h" -#include "aos_bt_ble.h" -#include "aos_bt_gatt.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/**************************************************************************** - * Default configuration values - ****************************************************************************/ -#define AOS_BT_CFG_DEFAULT_INQUIRY_SCAN_INTERVAL 0x0800 /* Inquiry scan interval */ -#define AOS_BT_CFG_DEFAULT_INQUIRY_SCAN_WINDOW 0x0012 /* Inquiry scan window */ -#define AOS_BT_CFG_DEFAULT_PAGE_SCAN_INTERVAL 0x0800 /* Page scan interval */ -#define AOS_BT_CFG_DEFAULT_PAGE_SCAN_WINDOW 0x0012 /* Page scan window */ -#define AOS_BT_CFG_DEFAULT_HIGH_DUTY_SCAN_INTERVAL 96 /* High duty scan interval */ -#define AOS_BT_CFG_DEFAULT_HIGH_DUTY_SCAN_WINDOW 48 /* High duty scan window */ -#define AOS_BT_CFG_DEFAULT_LOW_DUTY_SCAN_INTERVAL 2048 /* Low duty scan interval */ -#define AOS_BT_CFG_DEFAULT_LOW_DUTY_SCAN_WINDOW 18 /* Low duty scan window */ -#define AOS_BT_CFG_DEFAULT_HIGH_DUTY_CONN_SCAN_INTERVAL 96 /* High duty cycle connection scan interval BTM_BLE_SCAN_FAST_INT*/ -#define AOS_BT_CFG_DEFAULT_HIGH_DUTY_CONN_SCAN_WINDOW 48 /* High duty cycle connection scan window BTM_BLE_SCAN_FAST_WIN */ -#define AOS_BT_CFG_DEFAULT_LOW_DUTY_CONN_SCAN_INTERVAL 2048 /* Low duty cycle connection scan interval BTM_BLE_SCAN_SLOW_INT_1 */ -#define AOS_BT_CFG_DEFAULT_LOW_DUTY_CONN_SCAN_WINDOW 18 /* Low duty cycle connection scan window BTM_BLE_SCAN_SLOW_WIN_1 */ -#define AOS_BT_CFG_DEFAULT_CONN_MIN_INTERVAL 24 /* Minimum connection event interval */ -#define AOS_BT_CFG_DEFAULT_CONN_MAX_INTERVAL 40 /* Maximum connection event interval */ -#define AOS_BT_CFG_DEFAULT_CONN_LATENCY 0 /* Connection latency */ -#define AOS_BT_CFG_DEFAULT_CONN_SUPERVISION_TIMEOUT 700 /* Connection link supervsion timeout */ - -/* undirected connectable advertisement high/low duty cycle interval default */ -#define AOS_BT_CFG_DEFAULT_HIGH_DUTY_ADV_MIN_INTERVAL 48 /* Tgap(adv_fast_interval1) = 30(used) ~ 60 ms = 48 *0.625 */ -#define AOS_BT_CFG_DEFAULT_HIGH_DUTY_ADV_MAX_INTERVAL 48 /* Tgap(adv_fast_interval1) = 30(used) ~ 60 ms = 48 *0.625 */ -#define AOS_BT_CFG_DEFAULT_LOW_DUTY_ADV_MIN_INTERVAL 2048 /* Tgap(adv_slow_interval) = 1.28 s= 512 * 0.625 ms */ -#define AOS_BT_CFG_DEFAULT_LOW_DUTY_ADV_MAX_INTERVAL 2048 /* Tgap(adv_slow_interval) = 1.28 s= 512 * 0.625 ms */ - -/* non-connectable advertisement high/low duty cycle advertisement interval default */ -#define AOS_BT_CFG_DEFAULT_HIGH_DUTY_NONCONN_ADV_MIN_INTERVAL 160 /* Tgap(adv_fast_interval2) = 100(used) ~ 150 ms = 160 * 0.625 ms */ -#define AOS_BT_CFG_DEFAULT_HIGH_DUTY_NONCONN_ADV_MAX_INTERVAL 160 /* Tgap(adv_fast_interval2) = 100(used) ~ 150 ms = 160 * 0.625 ms */ -#define AOS_BT_CFG_DEFAULT_LOW_DUTY_NONCONN_ADV_MIN_INTERVAL 2048 /* Tgap(adv_slow_interval) = 1.28 s= 512 * 0.625 ms */ -#define AOS_BT_CFG_DEFAULT_LOW_DUTY_NONCONN_ADV_MAX_INTERVAL 2048 /* Tgap(adv_slow_interval) = 1.28 s= 512 * 0.625 ms */ - -/* directed connectable advertisement high/low duty cycle interval default */ -#define AOS_BT_CFG_DEFAULT_HIGH_DUTY_DIRECTED_ADV_MIN_INTERVAL 400 /* Tgap(dir_conn_adv_int_max) = 250 ms = 400 * 0.625 ms */ -#define AOS_BT_CFG_DEFAULT_HIGH_DUTY_DIRECTED_ADV_MAX_INTERVAL 800 /* Tgap(dir_conn_adv_int_min) = 500 ms = 800 * 0.625 ms */ -#define AOS_BT_CFG_DEFAULT_LOW_DUTY_DIRECTED_ADV_MIN_INTERVAL 48 /* Tgap(adv_fast_interval1) = 30(used) ~ 60 ms = 48 *0.625 */ -#define AOS_BT_CFG_DEFAULT_LOW_DUTY_DIRECTED_ADV_MAX_INTERVAL 48 /* Tgap(adv_fast_interval1) = 30(used) ~ 60 ms = 48 *0.625 */ - -/**************************************************************************** - * aos_bt core stack configuration - ****************************************************************************/ - -/* BR/EDR scan settings */ -typedef struct { - uint16_t - inquiry_scan_type; /* Inquiry scan type (BTM_SCAN_TYPE_STANDARD or BTM_SCAN_TYPE_INTERLACED) */ - uint16_t - inquiry_scan_interval; /* Inquiry scan interval (default: AOS_BT_CFG_DEFAULT_INQUIRY_SCAN_INTERVAL) */ - uint16_t - inquiry_scan_window; /* Inquiry scan window (default: AOS_BT_CFG_DEFAULT_INQUIRY_SCAN_WINDOW) */ - - uint16_t - page_scan_type; /* Page scan type (BTM_SCAN_TYPE_STANDARD or BTM_SCAN_TYPE_INTERLACED) */ - uint16_t - page_scan_interval; /* Page scan interval (default: AOS_BT_CFG_DEFAULT_PAGE_SCAN_INTERVAL) */ - uint16_t - page_scan_window; /* Page scan window (default: AOS_BT_CFG_DEFAULT_PAGE_SCAN_WINDOW) */ -} aos_bt_cfg_br_edr_scan_settings_t; -extern const aos_bt_cfg_br_edr_scan_settings_t -*aos_bt_cfg_br_edr_scan_settings; /* BR/EDR Scan settings (NULL to use defaults) */ - -/* LE Scan settings */ -typedef struct { - aos_bt_ble_scan_mode_t - scan_mode; /* BLE scan mode (BTM_BLE_SCAN_MODE_PASSIVE, BTM_BLE_SCAN_MODE_ACTIVE) */ - aos_bt_ble_scan_filter_policy_t - scan_filter_policy; /* BLE scan filter policy (FILTER_POLICY_NONE or FILTER_POLICY_WHITE_LIST) */ - - /* Advertisement scan configuration */ - uint16_t - high_duty_scan_interval; /* High duty scan interval (default: AOS_BT_CFG_DEFAULT_HIGH_DUTY_SCAN_INTERVAL) */ - uint16_t - high_duty_scan_window; /* High duty scan window (default: AOS_BT_CFG_DEFAULT_HIGH_DUTY_SCAN_WINDOW) */ - uint16_t - high_duty_scan_duration; /* High duty scan duration in seconds (0 for infinite) */ - - uint16_t - low_duty_scan_interval; /* Low duty scan interval (default: AOS_BT_CFG_DEFAULT_LOW_DUTY_SCAN_INTERVAL) */ - uint16_t - low_duty_scan_window; /* Low duty scan window (default: AOS_BT_CFG_DEFAULT_LOW_DUTY_SCAN_WINDOW) */ - uint16_t - low_duty_scan_duration; /* Low duty scan duration in seconds (0 for infinite) */ - - /* Connection scan configuration */ - uint16_t - high_duty_conn_scan_interval; /* High duty cycle connection scan interval (default: AOS_BT_CFG_DEFAULT_HIGH_DUTY_CONN_SCAN_INTERVAL) */ - uint16_t - high_duty_conn_scan_window; /* High duty cycle connection scan window (default: AOS_BT_CFG_DEFAULT_HIGH_DUTY_CONN_SCAN_WINDOW) */ - uint16_t - high_duty_conn_duration; /* High duty cycle connection duration in seconds (0 for infinite) */ - - uint16_t - low_duty_conn_scan_interval; /* Low duty cycle connection scan interval (default: AOS_BT_CFG_DEFAULT_LOW_DUTY_CONN_SCAN_INTERVAL) */ - uint16_t - low_duty_conn_scan_window; /* Low duty cycle connection scan window (default: AOS_BT_CFG_DEFAULT_LOW_DUTY_CONN_SCAN_WINDOW) */ - uint16_t - low_duty_conn_duration; /* Low duty cycle connection duration in seconds (0 for infinite) */ - - /* Connection configuration */ - uint16_t - conn_min_interval; /* Minimum connection interval (default: AOS_BT_CFG_DEFAULT_CONN_MIN_INTERVAL) */ - uint16_t - conn_max_interval; /* Maximum connection interval (default: AOS_BT_CFG_DEFAULT_CONN_MAX_INTERVAL) */ - uint16_t - conn_latency; /* Connection latency (default: AOS_BT_CFG_DEFAULT_CONN_LATENCY) */ - uint16_t - conn_supervision_timeout; /* Connection link supervision timeout (default: AOS_BT_CFG_DEFAULT_ CONN_SUPERVISION_TIMEOUT) */ -} aos_bt_cfg_ble_scan_settings_t; - -/* Advertising settings */ -typedef struct { - aos_bt_ble_advert_chnl_map_t - channel_map; /* Advertising channel map (mask of BTM_BLE_ADVERT_CHNL_37, BTM_BLE_ADVERT_CHNL_38, BTM_BLE_ADVERT_CHNL_39) */ - - uint16_t - high_duty_min_interval; /* High duty undirected connectable advert minimum advertising interval (default: AOS_BT_CFG_DEFAULT_HIGH_DUTY_ADV_MIN_INTERVAL) */ - uint16_t - high_duty_max_interval; /* High duty undirected connectable advert maximum advertising interval (default: AOS_BT_CFG_DEFAULT_HIGH_DUTY_ADV_MAX_INTERVAL) */ - uint16_t - high_duty_duration; /* High duty advertising duration in seconds (0 for infinite) */ - - uint16_t - low_duty_min_interval; /* Low duty undirected connectable advert minimum advertising interval (default: AOS_BT_CFG_DEFAULT_LOW_DUTY_ADV_MIN_INTERVAL) */ - uint16_t - low_duty_max_interval; /* Low duty undirected connectable advert maximum advertising interval (default: AOS_BT_CFG_DEFAULT_LOW_DUTY_ADV_MAX_INTERVAL) */ - uint16_t - low_duty_duration; /* Low duty advertising duration in seconds (0 for infinite) */ - - uint16_t - high_duty_directed_min_interval; /* high duty directed adv minimum advertising interval (default: AOS_BT_CFG_DEFAULT_HIGH_DUTY_DIRECTED_ADV_MIN_INTERVAL) */ - uint16_t - high_duty_directed_max_interval; /* high duty directed adv maximum advertising interval (default: AOS_BT_CFG_DEFAULT_HIGH_DUTY_DIRECTED_ADV_MAX_INTERVAL) */ - - uint16_t - low_duty_directed_min_interval; /* Low duty directed adv minimum advertising interval (default: AOS_BT_CFG_DEFAULT_LOW_DUTY_DIRECTED_ADV_MIN_INTERVAL) */ - uint16_t - low_duty_directed_max_interval; /* Low duty directed adv maximum advertising interval (default: AOS_BT_CFG_DEFAULT_LOW_DUTY_DIRECTED_ADV_MAX_INTERVAL) */ - uint16_t - low_duty_directed_duration; /* Low duty directed advertising duration in seconds (0 for infinite) */ - - uint16_t - high_duty_nonconn_min_interval; /* High duty non-connectable adv minimum advertising interval (default: AOS_BT_CFG_DEFAULT_HIGH_DUTY_NONCONN_ADV_MIN_INTERVAL) */ - uint16_t - high_duty_nonconn_max_interval; /* High duty non-connectable adv maximum advertising interval (default: AOS_BT_CFG_DEFAULT_HIGH_DUTY_NONCONN_ADV_MAX_INTERVAL) */ - uint16_t - high_duty_nonconn_duration; /* High duty non-connectable advertising duration in seconds (0 for infinite) */ - - uint16_t - low_duty_nonconn_min_interval; /* Low duty non-connectable adv minimum advertising interval (default: AOS_BT_CFG_DEFAULT_LOW_DUTY_NONCONN_ADV_MIN_INTERVAL) */ - uint16_t - low_duty_nonconn_max_interval; /* Low duty non-connectable adv maximum advertising interval (default: AOS_BT_CFG_DEFAULT_LOW_DUTY_NONCONN_ADV_MAX_INTERVAL) */ - uint16_t - low_duty_nonconn_duration; /* Low duty non-connectable advertising duration in seconds (0 for infinite) */ - -} aos_bt_cfg_ble_advert_settings_t; - -/* GATT settings */ -typedef struct { - aos_bt_gatt_appearance_t appearance; /* GATT appearance (see #gatt_appearance_e) */ - uint8_t - client_max_links; /* Client config: maximum number of servers that local client can connect to */ - uint8_t - server_max_links; /* Server config: maximum number of remote clients connections allowed by the local */ - uint16_t - max_attr_len; /* Maximum attribute length; gki_cfg must have a corresponding buffer pool that can hold this length */ -} aos_bt_cfg_gatt_settings_t; - -/* Settings for application managed L2CAP protocols (optional) */ -typedef struct { - uint8_t - max_links; /* Maximum number of application-managed l2cap links (BR/EDR and LE) */ - - /* BR EDR l2cap configuration */ - uint8_t - max_psm; /* Maximum number of application-managed BR/EDR PSMs */ - uint8_t - max_channels; /* Maximum number of application-managed BR/EDR channels */ - - /* LE L2cap connection-oriented channels configuration */ - uint8_t - max_le_psm; /* Maximum number of application-managed LE PSMs */ - uint8_t - max_le_channels; /* Maximum number of application-managed LE channels */ - -} aos_bt_cfg_l2cap_application_t; - -/* Audio/Video Distribution configuration */ -typedef struct { - uint8_t max_links; /* Maximum simultaneous audio/video links */ -} aos_bt_cfg_avdt_t; - -/* Audio/Video Remote Control configuration */ -typedef struct { - uint8_t - roles; /* Mask of local roles supported (AVRC_CONN_INITIATOR|AVRC_CONN_ACCEPTOR) */ - uint8_t max_links; /* Maximum simultaneous remote control links */ -} aos_bt_cfg_avrc_t; - - -/* RFCOMM configuration */ -typedef struct { - uint8_t - max_links; /* Maximum number of simultaneous connected remote devices*/ - uint8_t max_ports; /* Maximum number of simultaneous RFCOMM ports */ -} aos_bt_cfg_rfcomm_t; - - -/* Bluetooth stack configuration */ -typedef struct { - uint8_t *device_name; /* Local device name (NULL terminated) */ - aos_bt_dev_class_t device_class; /* Local device class */ - uint8_t - security_requirement_mask; /* Security requirements mask (BTM_SEC_NONE, or combination of BTM_SEC_IN_AUTHENTICATE, BTM_SEC_OUT_AUTHENTICATE, BTM_SEC_ENCRYPT (see #aos_bt_sec_level_e)) */ - uint8_t - max_simultaneous_links; /* Maximum number simultaneous links to different devices */ - - /* Scan and advertisement configuration */ - aos_bt_cfg_br_edr_scan_settings_t br_edr_scan_cfg; /* BR/EDR scan settings */ - aos_bt_cfg_ble_scan_settings_t ble_scan_cfg; /* BLE scan settings */ - aos_bt_cfg_ble_advert_settings_t ble_advert_cfg; /* BLE advertisement settings */ - - /* GATT configuration */ - aos_bt_cfg_gatt_settings_t gatt_cfg; /* GATT settings */ - - /* RFCOMM configuration */ - aos_bt_cfg_rfcomm_t rfcomm_cfg; /* RFCOMM settings */ - - /* Application managed l2cap protocol configuration */ - aos_bt_cfg_l2cap_application_t - l2cap_application; /* Application managed l2cap protocol configuration */ - - /* Audio/Video Distribution configuration */ - aos_bt_cfg_avdt_t avdt_cfg; /* Audio/Video Distribution configuration */ - - /* Audio/Video Remote Control configuration */ - aos_bt_cfg_avrc_t avrc_cfg; /* Audio/Video Remote Control configuration */ - - /* LE Address Resolution DB size */ - uint8_t - addr_resolution_db_size; /* LE Address Resolution DB settings - effective only for pre 4.2 controller*/ - -} aos_bt_cfg_settings_t; - -/**************************************************************************** - * Buffer pool configuration - * - * Pools must be ordered in increasing buf_size. - * If a pool runs out of buffers, the next pool will be used - * - * Pool usage (4 pools): - * Pool 0: Small Buffer Pool - miscellaneous use (small HCI messages) - * Pool 1: Medium Buffer Pool - HCI & RFCOMM control messages, min recommended buf_size is 360 - * Pool 2: Large Buffer Pool - HCI ACL data messages - * Pool 3: Extra Large Buffer Pool - Used for avdt media packets and miscellaneous (if not needed, set buf_count to 0) - * - ****************************************************************************/ -#define AOS_BT_CFG_NUM_BUF_POOLS (4) /* aos_bt stack uses 4 pools */ -typedef struct { - uint16_t buf_size; /* size of buffers in the pool */ - uint16_t buf_count; /* number of buffers in the pool */ -} aos_bt_cfg_buf_pool_t; - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#define DEMO_APP_BLE_REPORTER 1 -#define DEMO_APP_BLE_MONITOR 2 -#define DEMO_APP_RFCOMM_CLT 3 -#define DEMO_APP_RFCOMM_SVR 4 -#define DEMO_APP_SCAN 5 -#define DEMO_APP_FLOOD_BRIDGE 6 - -#define DEMO_APP_TYPE DEMO_APP_FLOOD_BRIDGE - -#endif diff --git a/framework/bluetooth/smartbt/include/smartbt_peripheral.h b/framework/bluetooth/smartbt/include/smartbt_peripheral.h deleted file mode 100644 index 4995dc7eae..0000000000 --- a/framework/bluetooth/smartbt/include/smartbt_peripheral.h +++ /dev/null @@ -1,405 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#ifndef _SMART_BT_PERIPHERAL_H_ -#define _SMART_BT_PERIPHERAL_H_ - -#include "../internal/os_wrapper.h" -#include "smartbt_smart_interface.h" -#include "LinkListUtils.h" -#include "aos_bt_gatt.h" -/* @file - * Defines functions for bridging Bluetooth Smart with Wi-Fi - */ - -#ifdef __cplusplus -extern "C" { -#endif - -/***************************************************** - * Macros - ******************************************************/ - -/***************************************************** - * Enumerations - ******************************************************/ - -/* - * BT smart peripheral socket status - */ -typedef enum { - PERIPHERAL_SOCKET_DISCONNECTED, /* Socket is disconnected */ - PERIPHERAL_SOCKET_CONNECTING, /* Socket is in connecting state */ - PERIPHERAL_SOCKET_CONNECTED, /* Socket is connected with a remote device */ -} aos_bt_peripheral_socket_status_t; - -/* - * Advertising filter policy - */ -typedef enum { - PERIPHERAL_ADVERT_FILTER_ALL_CONNECTION_REQ_ALL_SCAN_REQ = 0x00, /* Process scan and connection requests from all devices (i.e., the White List is not in use) (default) */ - PERIPHERAL_ADVERT_FILTER_ALL_CONNECTION_REQ_WHITELIST_SCAN_REQ = 0x01, /* Process connection requests from all devices and only scan requests from devices that are in the White List. */ - PERIPHERAL_ADVERT_FILTER_WHITELIST_CONNECTION_REQ_ALL_SCAN_REQ = 0x02, /* Process scan requests from all devices and only connection requests from devices that are in the White List */ - PERIPHERAL_ADVERT_FILTER_WHITELIST_CONNECTION_REQ_WHITELIST_SCAN_REQ = 0x03, /* Process scan and connection requests only from devices in the White List. */ - PERIPHERAL_ADVERT_FILTER_MAX -} aos_bt_peripheral_adv_filter_policy_t; - - -/***************************************************** - * Type Definitions - ******************************************************/ - -typedef struct _bt_ext_attribute_value_t aos_bt_ext_attribute_value_t; - -/* - * Socket to create a BT smart peripheral connection - */ -typedef struct aos_bt_peripheral_socket aos_bt_peripheral_socket_t; - -/* - * Socket connection callback - */ -typedef OSStatus (* aos_bt_peripheral_connection_callback_t) ( aos_bt_peripheral_socket_t *socket ); - -/* - * Socket disconnection callback - */ -typedef OSStatus (* aos_bt_peripheral_disconnection_callback_t) ( aos_bt_peripheral_socket_t *socket ); - -/* - * Attrubute request callback - */ -typedef aos_bt_gatt_status_t (* aos_bt_peripheral_attribute_handler)( aos_bt_ext_attribute_value_t *attribute, - aos_bt_gatt_request_type_t op ); - - -/***************************************************** - * Structures - ******************************************************/ - - -#define BT_SMART_S_NONE ( 0x0 ) -#define BT_SMART_S_INDICATE ( 0x1 << 0 ) -#define BT_SMART_S_NOTIFICATION ( 0x1 << 1 ) - -typedef uint8_t bt_smart_server_send_type_t; - -struct _bt_ext_attribute_value_t { - linked_list_node_t this_node; /* Linked-list node of this characteristic */ - uint16_t handle; /* Attribute handle */ - uint16_t value_length; /* Attribute value length */ - uint16_t value_buffer_length; /* Attribute value buffer length */ - uint8_t *p_value; /* Pointer to characteristic value */ - aos_bt_peripheral_attribute_handler attribute_handler; -}; - - -/* - * Socket to create a Smart Peripheral connection - * @warning The content of the socket structure is for INTERNAL USE only. Modifying - * the content of this structure is prohibited. Please use the Bluetooth SmartBridge - * API to retrieve socket information. - */ -struct aos_bt_peripheral_socket { - aos_bt_smart_device_t - remote_device; /* Remote Bluetooth device AOS is connected with (BLE server) */ - uint16_t - connection_handle; /* Connection handle */ - uint8_t - state; /* Internal state */ - uint8_t - actions; /* Internal socket actions */ - aos_bt_peripheral_connection_callback_t - connection_callback; /* Callback for handling connection event by remote device */ - aos_bt_peripheral_disconnection_callback_t - disconnection_callback; /* Callback for handling disconnection event by remote device */ - aos_bt_smart_bonding_callback_t - bonding_callback; /* Callback for handling bonding evnet by remote device */ - aos_bt_smart_security_settings_t - security_settings; /* Security settings */ - aos_bt_smart_bond_request_t - bond_req; /* Bond Request Structure */ - aos_semaphore_t - semaphore; /* Semaphore */ - linked_list_t - attribute_database; /* Attribute database */ - uint16_t mtu; -}; - -/***************************************************** - * Function declarations - ******************************************************/ - -/****************************************************************************/ -/* @addtogroup smartbridge SmartBridge - * @ingroup aosbt - * - * Bluetooth SmartBridge Functions - * - * - * @{ - */ -/****************************************************************************/ - -/****************************************************************************/ -/* @addtogroup sbmgmt SmartBridge Management - * @ingroup smartbridge - * - * SmartBridge Management Functions - * - * - * @{ - */ -/****************************************************************************/ - - -/* Initialise the AOS BT peripheral - * - * @note - * This function initialises: - * \li Generic Attribute Profile (GATT) Server - * \li Generic Access Profile (GAP) Peripheral Role - * \li Security settings used when conneted by BT client - * \li Initialises the socket internals to make it ready to connect to - * a Bluetooth Smart Central - * - * - * @return AOS_BT_SUCCESS: success , else @ref OSStatus - */ -OSStatus aos_bt_peripheral_init( aos_bt_peripheral_socket_t *socket, - const aos_bt_smart_security_settings_t *settings, - aos_bt_peripheral_connection_callback_t connection_callback, - aos_bt_peripheral_disconnection_callback_t disconnection_callback, - aos_bt_smart_bonding_callback_t bonding_callback ); - - -/* Deinitialise the AOS BT peripheral - * - * @note - * This function deinitialises: - * \li Generic Attribute Profile (GATT) Server - * \li Generic Access Profile (GAP) Peripheral Role - * \li Create BT peripheral Socket ready to be connected - * - * @return AOS_BT_SUCCESS: success - */ -OSStatus aos_bt_peripheral_deinit( void ); - - -/* @} */ - - -/****************************************************************************/ -/* @addtogroup sbsock BT peripheral Socket and Connection Management - * @ingroup SmartPeripheral - * - * BT peripheral Socket and Connection Functions - * - * - * @{ - */ -/****************************************************************************/ - - -/* Get BT peripheral socket status - * - * @param[in] socket : pointer to the socket to get the status - * @param[out] status : socket status - * - * @return AOS_BT_SUCCESS: success - * AOS_BT_SMART_APPL_UNINITIALISED: Smart peripheral framework is uninitialized - */ -OSStatus aos_bt_peripheral_get_socket_status( aos_bt_peripheral_socket_t *socket, - aos_bt_peripheral_socket_status_t *status ); - -/* Disconnect BT peripheral connection - * - * @note - * This function disconnects a connection with remote client. - * - * @return AOS_BT_SUCCESS: success - * AOS_BT_SMART_APPL_UNINITIALISED: Smart peripheral framework is uninitialized - */ -OSStatus aos_bt_peripheral_disconnect( void ); - - -/* @} */ - -/****************************************************************************/ -/* @addtogroup sbscan Smart Peripheral Advert - * @ingroup SmartPeripheral - * - * Smart Peripheral Advertising Functions - * - * - * @{ - */ -/****************************************************************************/ - -/* Start advertising local Bluetooth Smart devices - * - * @note - * This function instructs the Bluetooth controller to start advertising. Advertising data - * sould be set first use aos_bt_ble_set_advertisement_data(). - * - * @warning - * \li complete_callback is an intermediate report callback. - * - * @param[in] settings : advertising settings - * @param[in] complete_callback : callback function which is called when advertising is - * complete,running under AOS_BT_EVT_WORKER_THREAD - * - * @return AOS_BG_SUCCESS, else @ref OSStatus - */ -OSStatus aos_bt_peripheral_start_advertisements( aos_bt_smart_advertising_settings_t *settings, - aos_bt_smart_advertising_complete_callback_t complete_callback); - -/* Stop the ongoing advertising process - * - * This function instructs the Bluetooth controller to advertising local - * Bluetooth Smart devices. - * - * @return AOS_BG_SUCCESS, else @ref OSStatus - */ -OSStatus aos_bt_peripheral_stop_advertisements( void ); - -/* @} */ - -/****************************************************************************/ -/* @addtogroup sbwhitelist SmartBridge Whitelist Filter - * @ingroup smartbridge - * - * SmartBridge Whitelist Filter Functions - * - * - * @{ - */ -/****************************************************************************/ - -/* Update the devices in white list. - * - * @param[in] add : Add or remove this device specified by device_address. - * @param[in] device_address : Bluetooth address of the device to add to the whitelist - * - * @return @ref OSStatus - */ -OSStatus aos_bt_peripheral_update_advertisements_white_list( aos_bool_t add, aos_bt_device_address_t device_address ); - -/* Get the number of devices in white list - * - * @param[out] size : The number of devices in white list. - * - * @return @ref OSStatus - */ -OSStatus aos_bt_peripheral_get_advertisements_white_list_size( uint8_t *size ); - -/* Set Advertisements Filter Policy - * - * @param[in] policy : Advertisements filter policy - * - * @return @ref OSStatus - */ -OSStatus aos_bt_peripheral_set_advertisements_filter_policy( aos_bt_peripheral_adv_filter_policy_t policy ); - -/* @} */ - -/****************************************************************************/ -/* @addtogroup sbattr Smart peripheral Attribute Value database - * @ingroup SmartPeripheral - * - * Smart Peripheral External Attribute Value Database Functions - * - * - * @{ - */ -/****************************************************************************/ - -/* Add an external attribute vale to BT peripheral - * - * @param handle[in] : Handle of an attribution - * @param length[in] : Attribute value length (0, if value is not existed) - * @param value[in] : Point to the Attribute value (NULL, if value is not existed) - * @param handler[in] : Attribute request handler is synchronized triggerd - * after an attribute write by remote GATT write operation - * or before anattribute read by remote GATT read operation - * - * @return The address of the external attrbute value object, NULL if failed - */ -aos_bt_ext_attribute_value_t *aos_bt_peripheral_ext_attribute_add( uint16_t handle, uint16_t length, - const uint8_t *value, aos_bt_peripheral_attribute_handler handler ); - - -/* Remove an external attribute vale from BT peripheral - * - * @param attribute[in] : The address of the external attrbute value object - * - * @return @ref OSStatus - */ -OSStatus aos_bt_peripheral_ext_attribute_remove( aos_bt_ext_attribute_value_t *attribute ); - -/* Find an external attribute value from BT peripheral using handle - * - * @param handle[in] : Handle of an attribute - * @param attribute_found[in,out] : Pointer to the external attribute address find by handle - * - * @return @ref OSStatus - */ -OSStatus aos_bt_peripheral_ext_attribute_find_by_handle( uint16_t handle, - aos_bt_ext_attribute_value_t **attribute_found ); - - -/* Write or update data to the external attribute value object - * - * @note - * The value will copy to attrubute object, free after write - * - * @param handle[in] : Handle of an attribute - * @param length[in] : Data length - * @param length[in] : Attrubute value offset where data is written to - * @param value[in] : Point to the data - * - * @return @ref OSStatus - */ -OSStatus aos_bt_peripheral_ext_attribute_value_write( aos_bt_ext_attribute_value_t *attribute, uint16_t length, - uint16_t value_offset, const uint8_t *value ); - - -/* Remove all external attribute vale from BT peripheral - * - * @return @ref OSStatus - */ -OSStatus aos_bt_peripheral_ext_attribute_remove_all( void ); - - -/* Send external attribute value to BT client using indicate - * - * - * @param socket[in] : Pointer to the socket to send attribute value - * @param attribute[in] : Pointer to the external attribute that hold the value to be sent - * - * @return @ref OSStatus - */ -OSStatus aos_bt_peripheral_gatt_indicate_attribute_value ( aos_bt_peripheral_socket_t *socket, - const aos_bt_ext_attribute_value_t *attribute ); - - -/* Send external attribute value to BT client using notify - * - * - * @param socket[in] : Pointer to the socket to send attribute value - * @param attribute[in] : Pointer to the external attribute that hold the value to be sent - * - * @return @ref OSStatus - */ -OSStatus aos_bt_peripheral_gatt_notify_attribute_value( aos_bt_peripheral_socket_t *socket, - const aos_bt_ext_attribute_value_t *attribute ); - - -/* @} */ - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif diff --git a/framework/bluetooth/smartbt/include/smartbt_smart_attribute.h b/framework/bluetooth/smartbt/include/smartbt_smart_attribute.h deleted file mode 100644 index a97f3605f0..0000000000 --- a/framework/bluetooth/smartbt/include/smartbt_smart_attribute.h +++ /dev/null @@ -1,417 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#ifndef _SMART_BT_SMART_ATTRIBUTE_H_ -#define _SMART_BT_SMART_ATTRIBUTE_H_ - -#include "smartbt_smartbridge_constants.h" -#include "aos_bt_types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/***************************************************** - * Macros - ******************************************************/ - -/***************************************************** - * Constants - ******************************************************/ - -/* @cond !ADDTHIS*/ -/* Attribute structure fixed length */ -#define ATTR_COMMON_FIELDS_SIZE ( sizeof(aos_bt_smart_attribute_t*) + sizeof(uint16_t) + sizeof(aos_bt_uuid_t) + sizeof(uint8_t) + sizeof(uint32_t) + + sizeof(uint32_t)) - -#define ATTR_NO_VALUE_SIZE ( ATTR_COMMON_FIELDS_SIZE + sizeof(uint8_t) ) -#define ATTR_LONG_VALUE_SIZE ( ATTR_COMMON_FIELDS_SIZE + sizeof(uint8_t) * MAX_CHARACTERISTIC_VALUE_LENGTH ) -#define ATTR_SERVICE_SIZE ( ATTR_COMMON_FIELDS_SIZE + sizeof(attr_val_service_t) ) -#define ATTR_INCLUDE_SIZE ( ATTR_COMMON_FIELDS_SIZE + sizeof(attr_val_include_t) ) -#define ATTR_CHARACTERISTIC_SIZE ( ATTR_COMMON_FIELDS_SIZE + sizeof(attr_val_characteristic_t) ) -#define ATTR_CHARACTERISTIC_VALUE_SIZE( value_length ) ( ATTR_COMMON_FIELDS_SIZE + (sizeof(uint8_t) * value_length) ) -#define ATTR_EXTENDED_PROPERTIES_SIZE ( ATTR_COMMON_FIELDS_SIZE + sizeof(attr_val_extended_properties_t) ) -#define ATTR_USER_DESCRIPTION_SIZE( string_length ) ( ATTR_COMMON_FIELDS_SIZE + (sizeof(char) * string_length) ) -#define ATTR_CLIENT_CONFIG_SIZE ( ATTR_COMMON_FIELDS_SIZE + sizeof(attr_val_client_config_t) ) -#define ATTR_SERVER_CONFIG_SIZE ( ATTR_COMMON_FIELDS_SIZE + sizeof(attr_val_server_config_t) ) -#define ATTR_PRESENTATION_FORMAT_SIZE ( ATTR_COMMON_FIELDS_SIZE + sizeof(attr_val_presentation_format_t) ) -#define ATTR_AGGREGATE_FORMAT_SIZE( handle_count ) ( ATTR_COMMON_FIELDS_SIZE + (sizeof(uint16_t) * handle_count) ) - -/* Maximum characteristic value length */ -#define MAX_CHARACTERISTIC_VALUE_LENGTH 512 -/* @endcond */ - -/***************************************************** - * Enumerations - ******************************************************/ - -/* - * Bluetooth Smart Attribute type - */ -typedef enum { - AOS_ATTRIBUTE_TYPE_NO_VALUE, /* Attribute with no value */ - AOS_ATTRIBUTE_TYPE_LONG_VALUE, /* Attribute with long value */ - AOS_ATTRIBUTE_TYPE_PRIMARY_SERVICE, /* Primary service */ - AOS_ATTRIBUTE_TYPE_INCLUDE, /* Included Service */ - AOS_ATTRIBUTE_TYPE_CHARACTERISTIC, /* Characteristic */ - AOS_ATTRIBUTE_TYPE_CHARACTERISTIC_VALUE, /* Characteristic Value */ - AOS_ATTRIBUTE_TYPE_CHARACTERISTIC_DESCRIPTOR_EXTENDED_PROPERTIES, /* Characteristic Descriptor: Extended Properties */ - AOS_ATTRIBUTE_TYPE_CHARACTERISTIC_DESCRIPTOR_USER_DESCRIPTION, /* Characteristic Descriptor: User Description */ - AOS_ATTRIBUTE_TYPE_CHARACTERISTIC_DESCRIPTOR_CLIENT_CONFIGURATION, /* Characteristic Descriptor: Client Configuration */ - AOS_ATTRIBUTE_TYPE_CHARACTERISTIC_DESCRIPTOR_SERVER_CONFIGURATION, /* Characteristic Descriptor: Server Configuration */ - AOS_ATTRIBUTE_TYPE_CHARACTERISTIC_DESCRIPTOR_PRESENTATION_FORMAT, /* Characteristic Descriptor: Presentation Format */ - AOS_ATTRIBUTE_TYPE_CHARACTERISTIC_DESCRIPTOR_AGGREGATE_FORMAT /* Characteristic Descriptor: Aggregate Format */ -} aos_bt_smart_attribute_type_t; - -/***************************************************** - * Type Definitions - ******************************************************/ - -/***************************************************** - * Structures - ******************************************************/ - -#pragma pack(1) -/* @note: The following Attribute Values follow the Bluetooth Core Spec v4.0 - * Volume 3 Part G Section 3 closely. This allows for direct memcpy from - * the ATT response PDU to the Attribute Value structure. Also note that - * any additional fields follow the fields in the specification. - */ - -/* - * 3.1 Attribute Value of Service Definition - */ -typedef struct { - uint16_t start_handle; /* Starting handle */ - uint16_t end_handle; /* Ending handle */ - aos_bt_uuid_t uuid; /* UUID */ -} attr_val_service_t; - -/* - * 3.2 Attribute Value of Include Definition - */ -typedef struct { - uint16_t included_service_handle; /* Included service handle */ - uint16_t end_group_handle; /* End group handle */ - aos_bt_uuid_t uuid; /* UUID */ -} attr_val_include_t; - -/* - * 3.3.1 Attribute Value of Characteristic Declaration - */ -typedef struct { - uint8_t properties; /* Properties */ - uint16_t value_handle; /* Value handle */ - aos_bt_uuid_t uuid; /* UUID */ - - uint16_t descriptor_start_handle; /* Descriptor start handle. Additional field. Not in spec */ - uint16_t descriptor_end_handle; /* Descriptor end handle. Additional field. Not in spec */ -} attr_val_characteristic_t; - -/* - * 3.3.2 Attribute Value of Characteristic Value Declaration - */ -typedef struct { - uint8_t value[1]; /* Start of value */ -} attr_val_characteristic_value_t; - -/* - * 3.3.3.1 Attribute Value of Characteristic Extended Properties - */ -typedef struct { - uint8_t properties; /* Properties */ -} attr_val_extended_properties_t; - -/* - * 3.3.3.2 Attribute Value of Characteristic User Description - */ -typedef struct { - char string[1]; /* User description string */ -} attr_val_user_description_t; - -/* - * 3.3.3.3 Attribute Value of Client Characteristic Configuration - */ -typedef struct { - uint16_t config_bits; /* Configuration bits */ -} attr_val_client_config_t; - -/* - * 3.3.3.4 Attribute Value of Server Characteristic Configuration - */ -typedef struct { - uint16_t config_bits; /* Configuration bits */ -} attr_val_server_config_t; - -/* - * 3.3.3.5 Attribute Value of Characteristic Presentation Format - */ -typedef struct { - uint8_t format; /* Format */ - uint8_t exponent; /* Exponent */ - uint16_t unit; /* Unit */ - uint8_t name_space; /* Namespace */ - uint16_t description; /* Description */ -} attr_val_presentation_format_t; - -/* - * 3.3.3.6 Attribute Value of Characteristic Aggregate Format - */ -typedef struct { - uint16_t handle_list[1]; /* Handle list */ -} attr_val_aggregate_format_t; - -/* - * Vol 3 Part C 12.1 Attribute Value of Device Name Characteristic - */ -typedef struct { - char device_name[1]; /* Maximum length is 248 bytes */ -} attr_val_device_name_t; - -/* - * Vol 3 Part C 12.2 Attribute Value of Appearance Characteristic - */ -typedef struct { - uint16_t appearance; /* Enumerated value defined in "Assigned Numbers" */ -} attr_val_appearance_t; - -/* - * Vol 3 Part C 12.3 Attribute Value of Peripheral Privacy Flag Characteristic - */ -typedef struct { - uint8_t periph_privacy_flag; /* Peripheral privacy flag: 0 if disabled; 1 if enabled */ -} attr_val_periph_privacy_flag_t; - -/* - * Vol 3 Part C 12.4 Attribute Value of Reconnection Address Characteristic - */ -typedef struct { - uint8_t reconn_address[6]; /* Network-order reconnection address */ -} attr_val_reconnection_address_t; - -/* - * Vol 3 Part C 12.5 Attribute Value of Peripheral Preferred Connection Parameters Characteristic - */ -typedef struct { - uint16_t min_conn_interval; /* Minimum connection interval */ - uint16_t max_conn_interval; /* Maximum connection interval */ - uint16_t slave_latency; /* Slave latency */ - uint16_t conn_supervision_timeout_multiplier; /* Connection supervision timeout multiplier */ -} attr_val_periph_preferred_conn_params_t; - -/* - * Attribute Structure - */ -typedef struct aos_bt_attribute { - struct aos_bt_attribute - *next; /* Pointer to the next attribute in the list. NULL if not a list */ - uint16_t - handle; /* Attribute Handle */ - aos_bt_uuid_t - type; /* Attribute Type (UUID) */ - uint8_t - permission; /* Attribute Permission(s). Unused in GATT client */ - uint32_t - value_length; /* Length of the Attribute Value. If no value, this equals 0 */ - uint32_t - value_struct_size; /* Size of the value structure */ - - /* Union of Attribute Values. Use the right format based on Attribute Type */ - union { - uint8_t - value[MAX_CHARACTERISTIC_VALUE_LENGTH]; /* Long Value */ - attr_val_service_t - service; /* Attribute Value for Service */ - attr_val_include_t - include; /* Attribute Value for Include */ - attr_val_characteristic_t - characteristic; /* Attribute Value for Characteristic */ - attr_val_characteristic_value_t - characteristic_value; /* Attribute Value for Characteristic Value */ - attr_val_extended_properties_t - extended_properties; /* Attribute Value for Descriptor: Characteristic Extended Properties */ - attr_val_user_description_t - user_description; /* Attribute Value for Descriptor: Characteristic User_Description */ - attr_val_client_config_t - client_config; /* Attribute Value for Descriptor: Client Characteristic Configuration */ - attr_val_server_config_t - server_config; /* Attribute Value for Descriptor: Server Characteristic Configuration */ - attr_val_presentation_format_t - presentation_format; /* Attribute Value for Descriptor: Characteristic Presentation Format */ - attr_val_aggregate_format_t - aggregate_format; /* Attribute Value for Descriptor: Characteristic Aggregate Format */ - attr_val_device_name_t - device_name; /* Attribute Value for Characteristic Type: Device Name */ - attr_val_appearance_t - appearance; /* Attribute Value for Characteristic Type: Appearance */ - attr_val_periph_privacy_flag_t - periph_privacy_flag; /* Attribute Value for Characteristic Type: Peripheral Privacy Flag */ - attr_val_reconnection_address_t - reconn_address; /* Attribute Value for Characteristic Type: Reconnection Address */ - attr_val_periph_preferred_conn_params_t - periph_preferred_conn_params; /* Attribute Value for Characteristic Type: Peripheral Preferred Connection Parameters */ - } value; /* Union of Attribute Values. Use the right format based on Attribute Type */ - -} aos_bt_smart_attribute_t; - -/* - * Attribute List Structure - */ -typedef struct { - uint32_t count; /* Attribute count */ - aos_bt_smart_attribute_t *list; /* Pointer to attribute linked-list */ -} aos_bt_smart_attribute_list_t; - -#pragma pack() - -/***************************************************** - * Global Variables - ******************************************************/ - -/***************************************************** - * Function Declarations - ******************************************************/ - -/****************************************************************************/ -/* @addtogroup btattr Attribute - * @ingroup aosbt - * - * Bluetooth Smart Attribute Abstraction - * - * - * @{ - */ -/****************************************************************************/ - -/* Create a Bluetooth Smart Attribute structure - * - * @param[out] attribute : pointer that will receive the attribute structure - * @param[in] type : attribute type - * @param[in] variable_length : length of the variable part of the attribute. - * For some attribute types, this argument is not - * used. - * - * @return AOS_BT_SUCCESS:success,AOS_BT_BADARG:input argument error - */ -OSStatus aos_bt_smart_attribute_create( aos_bt_smart_attribute_t **attribute, aos_bt_smart_attribute_type_t type, - uint16_t variable_length ); - -/* Delete a Bluetooth Smart Attribute structure - * - * @param[in,out] attribute : attribute structure to delete - * - * @return AOS_BT_SUCCESS:success,AOS_BT_BADARG:input argument error - */ -OSStatus aos_bt_smart_attribute_delete( aos_bt_smart_attribute_t *attribute ); - -/* Initialise a list of Bluetooth Smart Attributes - * - * @param[out] list : list to initialise - * - * @return AOS_BT_SUCCESS:success,AOS_BT_BADARG:input argument error - */ -OSStatus aos_bt_smart_attribute_create_list( aos_bt_smart_attribute_list_t *list ); - -/* Deinitialise a list of Bluetooth Smart Attributes - * - * @param[out] list : list to deinitialise - * - * @return @ref OSStatus - */ -OSStatus aos_bt_smart_attribute_delete_list( aos_bt_smart_attribute_list_t *list ); - -/* Add a Bluetooth Smart Attribute to a list - * - * @param[in,out] list : list to add attribute to - * @param[in] attribute : attribute to add to the list - * - * @return @ref OSStatus - */ -OSStatus aos_bt_smart_attribute_add_to_list( aos_bt_smart_attribute_list_t *list, aos_bt_smart_attribute_t *attribute ); - -/* Remove a Bluetooth Smart Attribute with the given handle from a list - * - * @param[in,out] list : list to remote attribute from - * @param[in] handle : handle of the attribute to remove - * - * @return @ref OSStatus - */ -OSStatus aos_bt_smart_attribute_remove_from_list( aos_bt_smart_attribute_list_t *list, uint16_t handle ); - -/* Find a Bluetooth Smart Attribute with the given handle from a list - * - * @param[in,out] list : list to find attribute in - * @param[in] handle : handle of the attribute to find - * @param[out] attribute : pointer that will receive the attribute - * - * @return @ref OSStatus - */ -OSStatus aos_bt_smart_attribute_search_list_by_handle( const aos_bt_smart_attribute_list_t *list, uint16_t handle, - aos_bt_smart_attribute_t **attribute ); - -/* Find a Bluetooth Smart Attribute with the given handle from a list - * - * @param[in,out] list : list to find attribute in - * @param[in] uuid : UUID of the attribute to find - * @param[in] starting_handle : handle to start the search - * @param[in] ending_handle : handle to end the search - * @param[out] attribute : pointer that will receive the attribute - * - * @return @ref OSStatus - */ -OSStatus aos_bt_smart_attribute_search_list_by_uuid( const aos_bt_smart_attribute_list_t *list, - const aos_bt_uuid_t *uuid, uint16_t starting_handle, uint16_t ending_handle, aos_bt_smart_attribute_t **attribute ); - -/* Merge two Bluetooth Smart Attribute lists - * - * @param[in,out] trunk_list : list that will receive all of the attributes from the branch list - * @param[in,out] branch_list : list whose attributes will be removed and inserted into the trunk list - * - * @return @ref OSStatus - */ -OSStatus aos_bt_smart_attribute_merge_lists( aos_bt_smart_attribute_list_t *trunk_list, - aos_bt_smart_attribute_list_t *branch_list ); - -/* Print attribute contents - * - * @param[in] attribute : attribute to print - * - * @return @ref OSStatus - */ -OSStatus aos_bt_smart_attribute_print( const aos_bt_smart_attribute_t *attribute ); - -/* Print the contents of all attributes in a list - * - * @param[in] list : list whose attributes to print - * - * @return @ref OSStatus - */ -OSStatus aos_bt_smart_attribute_print_list( const aos_bt_smart_attribute_list_t *list ); - -/* Get attribute list head - * - * @param[in] list : attribute list - * @param[out] head : pointer that will receive the list head - * - * @return @ref OSStatus - */ -OSStatus aos_bt_smart_attribute_get_list_head( const aos_bt_smart_attribute_list_t *list, - aos_bt_smart_attribute_t **head ); - - -/* Get attribute list count - * - * @param[in] list : attribute list - * @param[out] count : variable that will receive the count - * - * @return @ref OSStatus - */ -OSStatus aos_bt_smart_attribute_get_list_count( const aos_bt_smart_attribute_list_t *list, uint32_t *count ); - -/* @} */ - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif diff --git a/framework/bluetooth/smartbt/include/smartbt_smart_interface.h b/framework/bluetooth/smartbt/include/smartbt_smart_interface.h deleted file mode 100644 index 4d5eee5683..0000000000 --- a/framework/bluetooth/smartbt/include/smartbt_smart_interface.h +++ /dev/null @@ -1,431 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#ifndef _SMART_BT_SMART_INTERFACE_H_ -#define _SMART_BT_SMART_INTERFACE_H_ - -#include "smartbt_smartbridge_constants.h" -#include "smartbt_smart_attribute.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/***************************************************** - * Macros - ******************************************************/ - -/***************************************************** - * Constants - ******************************************************/ - -/* @cond !ADDTHIS*/ -/* Limits and Default Value for Scan Interval */ -#define DEFAULT_SCAN_INTERVAL 0x0010 -#define MIN_SCAN_INTERVAL 0x0004 -#define MAX_SCAN_INTERVAL 0x4000 - -/* Limits and Default Value for Scan Window */ -#define DEFAULT_SCAN_WINDOW 0x0010 -#define MIN_SCAN_WINDOW 0x0004 -#define MAX_SCAN_WINDOW 0x4000 - -#define BONDING_DISABLED 0x00 -#define BONDING_ENABLED 0x01 -#define PASSKEY_ENTRY_ENABLED 0x04 -#define SECURE_CONNECTION_ENABLE 0x08 - -#define DISTRIBUTE_ENCRYPTION_KEY 0x01 -#define DISTRIBUTE_ID_KEY 0x02 -#define DISTRIBUTE_SIGN_KEY 0x04 -/* @endcond */ - -/***************************************************** - * Enumerations - ******************************************************/ - -/* - * Bluetooth Smart filter policy - */ -typedef enum { - FILTER_POLICY_NONE = 0x00, /* No filter policy */ - FILTER_POLICY_WHITE_LIST = 0x01, /* White list filter policy */ -} aos_bt_smart_filter_policy_t; - -/* - * Bluetooth Smart scan duplicates filter - */ -typedef enum { - DUPLICATES_FILTER_DISABLED = 0x00, /* Duplicates filter is disabled */ - DUPLICATES_FILTER_ENABLED = 0x01, /* Duplicates filter is enabled */ -} aos_bt_smart_filter_duplicated_t; - -/* - * Bluetooth Smart address type - */ -typedef enum { - BT_SMART_ADDR_TYPE_PUBLIC = 0x00, /* Public address */ - BT_SMART_ADDR_TYPE_RANDOM = 0x01 /* Random address */ -} aos_bt_smart_address_type_t; - -/* - * Bluetooth Smart link role - */ -typedef enum { - BT_SMART_LINK_ROLE_MASTER = 0x00, /* Public address */ - BT_SMART_LINK_ROLE_SLAVE = 0x01 /* Random address */ -} aos_bt_smart_link_role_t; - -/* - * Bluetooth Smart scan type - */ -typedef enum { - BT_SMART_PASSIVE_SCAN = 0x00, /* Passive scan. Controller does not send SCAN_REQ and listens for Advertising from remote devices */ - BT_SMART_ACTIVE_SCAN = 0x01, /* Active scan. Controller sends SCAN_REQ. Controller listens for Advertising from remote devices and may receive SCAN_RSP from remote devices */ -} aos_bt_smart_scan_type_t; - -/* - * Bluetooth Smart advertising event - */ -typedef enum { - BT_SMART_CONNECTABLE_UNDIRECTED_ADVERTISING_EVENT = 0x00, /* ADV_IND : Connectable undirected advertising event */ - BT_SMART_CONNECTABLE_DIRECTED_ADVERTISING_EVENT = 0x01, /* ADV_DIRECT_IND : Connectable directed advertising event */ - BT_SMART_SCANNABLE_UNDIRECTED_ADVERTISING_EVENT = 0x02, /* ADV_SCAN_IND : Scannable undirected advertising event */ - BT_SMART_NON_CONNECTABLE_UNDIRECTED_ADVERTISING_EVENT = 0x03, /* ADV_NONCONN_IND : Non-connectable undirected advertising event */ - BT_SMART_SCAN_RESPONSE_EVENT = 0x04, /* SCAN_RSP : Scan response event */ -} aos_bt_smart_advertising_event_t; - -/* - * Bluetooth Smart advertising event - */ -typedef enum { - BT_SMART_UNDIRECTED_ADVERTISING = 0x00, /* General undirected advertising */ - BT_SMART_DISCOVERABLE_ADVERTISING = 0x01, /* Discoverable advertising */ - BT_SMART_DIRECTED_ADVERTISING = 0x02, /* Directed advertising */ - BT_SMART_NON_CONNECTABLE_UNDIRECTED_ADVERTISING = 0x03, /* Non-connectable undirected advertising */ -} aos_bt_smart_advertising_type_t; - -/* - * Bluetooth Smart device input/output (IO) capabilities - */ -typedef enum { - BT_SMART_IO_DISPLAY_ONLY = 0x00, - BT_SMART_IO_DISPLAY_YES_NO_BUTTONS = 0x01, - BT_SMART_IO_KEYBOARD_ONLY = 0x02, - BT_SMART_IO_NO_INPUT_NO_OUTPUT = 0x03, - BT_SMART_IO_KEYBOARD_DISPLAY = 0x04, -} aos_bt_io_capabilities_t; - -/* - * Bluetooth Smart device Authentication Requirements (AuthReq) - */ -typedef enum { - BT_SMART_AUTH_REQ_NONE = 0, - BT_SMART_AUTH_REQ_BONDING = ( BONDING_ENABLED ), - BT_SMART_AUTH_REQ_PASSKEY_ENTRY = ( PASSKEY_ENTRY_ENABLED ), - BT_SMART_AUTH_REQ_BONDING_AND_PASSKEY_ENTRY = ( BONDING_ENABLED | PASSKEY_ENTRY_ENABLED ), -} aos_bt_smart_auth_req_t; - -/* - * Bluetooth Smart device bonding request type - */ -typedef enum { - /* Bonding event -- user should reply it with #aos_bt_smart_bond_reply() */ - AOS_BT_SMART_BOND_PASS_KEY_REQ = 0x01, - /* Bonding event -- user should reply it with #aos_bt_smart_bond_reply() */ - AOS_BT_SMART_BOND_USR_CONFIRM_REQ = 0x02, - /* Bonding event -- user should reply it with #aos_bt_smart_bond_reply() */ - AOS_BT_SMART_BOND_OOB_DATA_REQ = 0x03, - /* Bonding event -- user should not reply it */ - AOS_BT_SMART_BOND_PASS_KEY_NOTIFY = 0x04, -} aos_bt_smart_bond_request_type_t; - -/* - * Bluetooth Smart device key distribution types - */ -typedef enum { - BT_SMART_DISTRIBUTE_NONE = 0, - BT_SMART_DISTRIBUTE_ENCRYPTION_KEY = ( DISTRIBUTE_ENCRYPTION_KEY ), - BT_SMART_DISTRIBUTE_ID_KEY = ( DISTRIBUTE_ID_KEY ), - BT_SMART_DISTRIBUTE_ENCRYPTION_AND_ID_KEYS = ( DISTRIBUTE_ID_KEY | DISTRIBUTE_ENCRYPTION_KEY ), - BT_SMART_DISTRIBUTE_SIGN_KEY = ( DISTRIBUTE_SIGN_KEY ), - BT_SMART_DISTRIBUTE_ENCRYPTION_AND_SIGN_KEYS = ( DISTRIBUTE_SIGN_KEY | DISTRIBUTE_ENCRYPTION_KEY ), - BT_SMART_DISTRIBUTE_ID_AND_SIGN_KEYS = ( DISTRIBUTE_SIGN_KEY | DISTRIBUTE_ID_KEY ), - BT_SMART_DISTRIBUTE_ALL_KEYS = ( DISTRIBUTE_SIGN_KEY | DISTRIBUTE_ID_KEY | DISTRIBUTE_ENCRYPTION_KEY ), -} aos_bt_smart_key_distribution_t; - -/* - * Bluetooth Smart Out-of-Band (OOB) authentication data - */ -typedef enum { - BT_SMART_OOB_AUTH_NONE, /* OOB authentication data is not available */ - BT_SMART_OOB_AUTH_AVAILABLE, /* OOB authentication data is available */ -} aos_bt_smart_oob_auth_t; - -/***************************************************** - * Structures - ******************************************************/ - -#pragma pack(1) - -/* - * Bluetooth Smart device - */ -typedef struct { - aos_bt_device_address_t address; /* Bluetooth device address */ - aos_bt_smart_address_type_t address_type; /* Address Type */ - char name[31]; /* User-friendly name */ -} aos_bt_smart_device_t; - -/* - * Bluetooth Smart scan settings - */ -typedef struct { - aos_bt_smart_scan_type_t - type; /* Scan type */ - aos_bt_smart_filter_policy_t - filter_policy; /* Scan filter policy */ - aos_bt_smart_filter_duplicated_t - filter_duplicates; /* Scan duplicates filter */ - uint16_t - interval; /* Interval between scans. Unit: 0.625ms. Range: 0x0004 - 0x4000 (2.5ms - 10.24s) */ - uint16_t - window; /* Scan window. Must be <= scan interval. Unit: 0.625ms. Range: 0x0004 - 0x4000 (2.5ms - 10.24s) */ - uint16_t - duration_second; /* Scan duration in seconds */ -} aos_bt_smart_scan_settings_t; - -/* - * Bluetooth Smart advertising report - */ -typedef struct { - aos_bt_smart_device_t remote_device; /* Remote device */ - int8_t signal_strength; /* RSSI in dBm */ - aos_bt_smart_advertising_event_t event; /* Advertising event received */ - uint8_t eir_data_length; /* Length of EIR data received with advertising event */ - uint8_t eir_data[31]; /* EIR data of advertising event */ -} aos_bt_smart_advertising_report_t; - -/* - * Bluetooth Smart scan result - */ -typedef struct aos_bt_smart_scan_result { - aos_bt_smart_device_t remote_device; /* Remote device */ - int8_t signal_strength; /* RSSI in dBm */ - aos_bt_smart_advertising_report_t last_scan_response_received; /* Last scan response event received */ - aos_bt_smart_advertising_report_t last_advertising_event_received; /* Last advertising event received */ - struct aos_bt_smart_scan_result *next; /* Pointer to the next scan result */ - - /* Additional flag to help application filter scan results */ - aos_bool_t filter_display; /* Set to AOS_TRUE if filter display */ - -} aos_bt_smart_scan_result_t; - -/* - * Bluetooth Smart advertise settings - */ -typedef struct { - aos_bt_smart_advertising_type_t - type; /* Advertising type */ - aos_bool_t - use_high_duty; /* Start advertising use high duty cycle interval */ - uint16_t - high_duty_interval; /* High duty advertising interval */ - uint16_t - high_duty_duration; /* High duty advertising duration in seconds (0 for infinite) */ - uint16_t - low_duty_interval; /* Low duty advertising interval */ - uint16_t - low_duty_duration; /* Low duty advertising duration in seconds (0 for infinite) */ - aos_bt_smart_address_type_t - directed_advertisement_addr_type; /* Target device address type for directed advertising */ - aos_bt_device_address_t - directed_advertisement_addr; /* Target device address for directed advertising */ -} aos_bt_smart_advertising_settings_t; - -/* - * Bluetooth Smart connection settings - */ -typedef struct { - uint16_t - timeout_second; /* Connection timeout in seconds */ - aos_bt_smart_filter_policy_t - filter_policy; /* Connection initiator filter policy: No filter or using white list */ - uint16_t - interval_min; /* Connection Interval Min. Unit: 1.25ms. Range: 0x000A - 0x0C80 (7.5ms - 4s) */ - uint16_t - interval_max; /* Connection Interval Max. Unit: 1.25ms. Range: 0x000A - 0x0C80 (7.5ms - 4s) */ - uint16_t - latency; /* Connection Latency. Unit: Connection Events. Range: 0x0000 - 0x01F4 */ - uint16_t - supervision_timeout; /* Supervision Timeout. Unit: 10ms. Range: 0x000A - 0x0C80 (100ms - 32s)*/ - uint16_t - ce_length_min; /* Connection Event Length Min. Unit: Connection Events. Range: 0x0000 - 0xFFFF */ - uint16_t - ce_length_max; /* Connection Event Length Max. Unit: Connection Events. Range: 0x0000 - 0xFFFF */ - uint32_t - attribute_protocol_timeout_ms; /* Attribute protocol timeout in milliseconds */ -} aos_bt_smart_connection_settings_t; - -/* - * Bluetooth Smart Extended Inquiry Response (EIR) data structure - */ -typedef struct { - uint8_t length; /* Length */ - uint8_t type; /* Type */ - uint8_t data[1]; /* Start of data */ -} aos_bt_smart_eir_data_structure_t; - -/* - * Bluetooth Smart security settings - */ -typedef struct { - uint16_t timeout_second; /* Timeout in second. Default is 30 seconds */ - aos_bt_io_capabilities_t io_capabilities; /* Device I/O capability */ - aos_bt_smart_auth_req_t authentication_requirements; /* Authentication requirements */ - aos_bt_smart_oob_auth_t oob_authentication; /* OOB authentication data */ - uint8_t max_encryption_key_size; /* Encryption key size (7 to 16 bytes) */ - aos_bt_smart_key_distribution_t master_key_distribution; /* Bit mask of master/initiator key distribution */ - aos_bt_smart_key_distribution_t slave_key_distribution; /* Bit mask of slave/responder key distribution */ -} aos_bt_smart_security_settings_t; - -/* - * Bluetooth Smart Peer Device Bond Info - */ -typedef struct { - aos_bt_device_address_t - peer_address; /* Bonded peer device address */ - aos_bt_smart_address_type_t - address_type; /* Peer device's address type */ - uint8_t - irk [16]; /* Peer device's Identity Resolving Key (IRK). Used for random address generation and resolution */ - uint8_t - csrk[16]; /* Peer device's Connection Signature Resolving Key (CSRK). Used for signing data and verifying messages */ - uint8_t - ltk [16]; /* Peer device's Long Term Key (LTK). Used for encryption */ - uint8_t - rand[8]; /* Peer device's Random Number (Rand). Used for identifying LTK */ - uint16_t - ediv; /* Peer device's Encrypted Diversifier (EDIV). Used for identifying LTK */ -} aos_bt_smart_bond_info_t; - -/* - * Bluetooth Smart Device Bond Request Event Parameters. - */ -typedef struct { - /* Type of the request */ - aos_bt_smart_bond_request_type_t type; - - union { - /* AOS_BT_SMART_BOND_PASS_KEY_REQ */ - struct { - aos_bt_device_address_t addr; - } passkey; - - /* AOS_BT_SMART_BOND_USR_CONFIRM_REQ */ - struct { - aos_bt_device_address_t addr; - /* An up to six-digit number (from 0 to 999999) to display or - * request remote entry - */ - uint32_t passkey; - } confirm; - - /* AOS_BT_SMART_BOND_OOB_DATA_REQ */ - struct { - aos_bt_device_address_t addr; - } oob_data; - - /* AOS_BT_SMART_BOND_PASS_KEY_NOTIFY */ - struct { - aos_bt_device_address_t addr; - uint32_t passkey; - } notify; - } u; -} aos_bt_smart_bond_request_t; - -/* - * Bluetooth Smart Device Bond Replay information. - */ -typedef struct { - /* Type of the request */ - aos_bt_smart_bond_request_type_t type; - - /* reply status */ - aos_bt_result_t res; - - /* reply data -- only valid when 'res' is AOS_BT_SUCCESS */ - union { - /* Used for AOS_BT_SMART_BOND_USER_CONFIRM */ - struct { - aos_bt_device_address_t addr; - } confirm; - - /* Used for AOS_BT_SMART_BOND_PASS_KEY_REQ */ - struct { - aos_bt_device_address_t addr; - uint32_t passkey; - } passkey; - - /* Used for AOS_BT_SMART_BOND_OOB_DATA_REQ */ - struct { - aos_bt_device_address_t addr; - uint8_t *data; - uint8_t len; - } oob_data; - } u; -} aos_bt_smart_bond_reply_t; - -#pragma pack() - -/***************************************************** - * Type Definitions - ******************************************************/ - -/* - * Bluetooth Smart scan complete callback - */ -//typedef event_handler_t aos_bt_smart_scan_complete_callback_t; -typedef OSStatus (*aos_bt_smart_scan_complete_callback_t)( void *arg ); - -/* - * Bluetooth Smart advertising report callback - */ -typedef OSStatus (*aos_bt_smart_advertising_report_callback_t) ( const aos_bt_smart_advertising_report_t *result ); - -/* - * Bluetooth Smart Device Bond Callback. - */ -typedef OSStatus (*aos_bt_smart_bonding_callback_t)(const aos_bt_smart_bond_request_t *request); - -/* - * Bluetooth Smart advertising complete callback - */ -//typedef event_handler_t aos_bt_smart_advertising_complete_callback_t; -typedef OSStatus (*aos_bt_smart_advertising_complete_callback_t)( void *arg ); - -/***************************************************** - * Global Variables - ******************************************************/ - -/***************************************************** - * Function Declarations - ******************************************************/ - -/* aos_bt_smart_bond_reply - * - * This function is called to reply BLE Bond Event posted by #aos_bt_smart_bonding_callback_t. - * You should fill a strcutre #aos_bt_smart_bond_reply_t to complete this bonding procedure. - * - * @param[in] response the response to current bonding event. - * - * @return OSStatus - */ -extern OSStatus aos_bt_smart_bond_reply(const aos_bt_smart_bond_reply_t *response); - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif diff --git a/framework/bluetooth/smartbt/include/smartbt_smartbridge_constants.h b/framework/bluetooth/smartbt/include/smartbt_smartbridge_constants.h deleted file mode 100644 index b2799c17e6..0000000000 --- a/framework/bluetooth/smartbt/include/smartbt_smartbridge_constants.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#ifndef _SMART_BT_SMART_BRIDGE_CONSTANTS_H_ -#define _SMART_BT_SMART_BRIDGE_CONSTANTS_H_ - -#include "aos_bt_constants.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/***************************************************** - * Macros - ******************************************************/ - -/***************************************************** - * Constants - ******************************************************/ - -/* @cond !ADDTHIS*/ -#define AOS_BT_ADDRESS_BYTE_SIZE 6 -/* @endcond */ - -/***************************************************** - * Enumerations - ******************************************************/ - -/* - * UUID size - */ -typedef enum { - UUID_16BIT = 0x02, /* 16-bit */ - UUID_32BIT = 0x04, /* 32-bit */ - UUID_128BIT = 0x10 /* 128-bit */ -} aos_bt_uuid_size_t; - -/***************************************************** - * Type Definitions - ******************************************************/ - -/***************************************************** - * Structures - ******************************************************/ - -/***************************************************** - * Global Variables - ******************************************************/ - -/***************************************************** - * Function Declarations - ******************************************************/ - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif diff --git a/framework/bluetooth/smartbt/internal/os_err.h b/framework/bluetooth/smartbt/internal/os_err.h deleted file mode 100644 index 81504a639d..0000000000 --- a/framework/bluetooth/smartbt/internal/os_err.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#ifndef _OS_ERR_H_ -#define _OS_ERR_H_ - -#define oNoErr 0 //! No error occurred. -#define oGeneralErr -1 //! General error. -#define oInProgressErr 1 //! Operation in progress. - -// Generic error codes are in the range -6700 to -6779. - -#define oGenericErrorBase -6700 //! Starting error code for all generic errors. - -#define oUnknownErr -6700 //! Unknown error occurred. -#define oOptionErr -6701 //! Option was not acceptable. -#define oSelectorErr -6702 //! Selector passed in is invalid or unknown. -#define oExecutionStateErr -6703 //! Call made in the wrong execution state (e.g. called at interrupt time). -#define oPathErr -6704 //! Path is invalid, too long, or otherwise not usable. -#define oParamErr -6705 //! Parameter is incorrect, missing, or not appropriate. -#define oUserRequiredErr -6706 //! User interaction is required. -#define oCommandErr -6707 //! Command invalid or not supported. -#define oIDErr -6708 //! Unknown, invalid, or inappropriate identifier. -#define oStateErr -6709 //! Not in appropriate state to perform operation. -#define oRangeErr -6710 //! Index is out of range or not valid. -#define oRequestErr -6711 //! Request was improperly formed or not appropriate. -#define oResponseErr -6712 //! Response was incorrect or out of sequence. -#define oChecksumErr -6713 //! Checksum does not match the actual data. -#define oNotHandledErr -6714 //! Operation was not handled (or not handled completely). -#define oVersionErr -6715 //! Version is not correct or not compatible. -#define oSignatureErr -6716 //! Signature did not match what was expected. -#define oFormatErr -6717 //! Unknown, invalid, or inappropriate file/data format. -#define oNotInitializedErr -6718 //! Action request before needed services were initialized. -#define oAlreadyInitializedErr -6719 //! Attempt made to initialize when already initialized. -#define oNotInUseErr -6720 //! Object not in use (e.g. cannot abort if not already in use). -#define oAlreadyInUseErr -6721 //! Object is in use (e.g. cannot reuse active param blocks). -#define oTimeoutErr -6722 //! Timeout occurred. -#define oCanceledErr -6723 //! Operation canceled (successful cancel). -#define oAlreadyCanceledErr -6724 //! Operation has already been canceled. -#define oCannotCancelErr -6725 //! Operation could not be canceled (maybe already done or invalid). -#define oDeletedErr -6726 //! Object has already been deleted. -#define oNotFoundErr -6727 //! Something was not found. -#define oNoMemoryErr -6728 //! Not enough memory was available to perform the operation. -#define oNoResourcesErr -6729 //! Resources unavailable to perform the operation. -#define oDuplicateErr -6730 //! Duplicate found or something is a duplicate. -#define oImmutableErr -6731 //! Entity is not changeable. -#define oUnsupportedDataErr -6732 //! Data is unknown or not supported. -#define oIntegrityErr -6733 //! Data is corrupt. -#define oIncompatibleErr -6734 //! Data is not compatible or it is in an incompatible format. -#define oUnsupportedErr -6735 //! Feature or option is not supported. -#define oUnexpectedErr -6736 //! Error occurred that was not expected. -#define oValueErr -6737 //! Value is not appropriate. -#define oNotReadableErr -6738 //! Could not read or reading is not allowed. -#define oNotWritableErr -6739 //! Could not write or writing is not allowed. -#define oBadReferenceErr -6740 //! An invalid or inappropriate reference was specified. -#define oFlagErr -6741 //! An invalid, inappropriate, or unsupported flag was specified. -#define oMalformedErr -6742 //! Something was not formed correctly. -#define oSizeErr -6743 //! Size was too big, too small, or not appropriate. -#define oNameErr -6744 //! Name was not correct, allowed, or appropriate. -#define oNotPreparedErr -6745 //! Device or service is not ready. -#define oReadErr -6746 //! Could not read. -#define oWriteErr -6747 //! Could not write. -#define oMismatchErr -6748 //! Something does not match. -#define oDateErr -6749 //! Date is invalid or out-of-range. -#define oUnderrunErr -6750 //! Less data than expected. -#define oOverrunErr -6751 //! More data than expected. -#define oEndingErr -6752 //! Connection, session, or something is ending. -#define oConnectionErr -6753 //! Connection failed or could not be established. -#define oAuthenticationErr -6754 //! Authentication failed or is not supported. -#define oOpenErr -6755 //! Could not open file, pipe, device, etc. -#define oTypeErr -6756 //! Incorrect or incompatible type (e.g. file, data, etc.). -#define oSkipErr -6757 //! Items should be or was skipped. -#define oNoAckErr -6758 //! No acknowledge. -#define oCollisionErr -6759 //! Collision occurred (e.g. two on bus at same time). -#define oBackoffErr -6760 //! Backoff in progress and operation intentionally failed. -#define oNoAddressAckErr -6761 //! No acknowledge of address. -#define oInternalErr -6762 //! An error internal to the implementation occurred. -#define oNoSpaceErr -6763 //! Not enough space to perform operation. -#define oCountErr -6764 //! Count is incorrect. -#define oEndOfDataErr -6765 //! Reached the end of the data (e.g. recv returned 0). -#define oWouldBlockErr -6766 //! Would need to block to continue (e.g. non-blocking read/write). -#define oLookErr -6767 //! Special case that needs to be looked at (e.g. interleaved data). -#define oSecurityRequiredErr -6768 //! Security is required for the operation (e.g. must use encryption). -#define oOrderErr -6769 //! Order is incorrect. -#define oUpgradeErr -6770 //! Must upgrade. -#define oAsyncNoErr -6771 //! Async operation successfully started and is now in progress. -#define oDeprecatedErr -6772 //! Operation or data is deprecated. -#define oPermissionErr -6773 //! Permission denied. - -#define oGenericErrorEnd -6779 //! Last generic error code (inclusive) - -#endif diff --git a/framework/bluetooth/smartbt/internal/os_wrapper.c b/framework/bluetooth/smartbt/internal/os_wrapper.c deleted file mode 100644 index fdaf209ad2..0000000000 --- a/framework/bluetooth/smartbt/internal/os_wrapper.c +++ /dev/null @@ -1,590 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#include -#include -#include -#include "os_wrapper.h" - -typedef struct { - event_handler_t function; - void *arg; -} aos_event_message_t; - -OSStatus aos_rtos_create_thread( aos_thread_t *thread, uint8_t priority, const char *name, - aos_thread_function_t function, uint32_t stack_size, aos_thread_arg_t arg ) -{ - kstat_t ret; - ktask_t *task_tmp; - - if (thread == NULL) { - ret = krhino_task_dyn_create(&task_tmp, name, (void *)arg, priority, 0, stack_size / 4, (task_entry_t)function, 1); - } else { - ret = krhino_task_dyn_create((ktask_t **)thread, name, (void *)arg, priority, 0, stack_size / 4, (task_entry_t)function, - 1); - } - - if (ret == RHINO_SUCCESS) { - return oNoErr; - } - - return oGeneralErr; -} - -OSStatus aos_rtos_delete_thread( aos_thread_t *thread ) -{ - kstat_t ret; - - if (thread == NULL) { - ret = krhino_task_dyn_del(NULL); - } else { - ret = krhino_task_dyn_del(*((ktask_t **)thread)); - } - - if (ret == RHINO_SUCCESS) { - return oNoErr; - } - - return oGeneralErr; -} - -void aos_rtos_suspend_thread(aos_thread_t *thread) -{ - if (thread == NULL) { - krhino_task_suspend(krhino_cur_task_get()); - } else { - krhino_task_suspend(*((ktask_t **)thread)); - } -} - -void aos_rtos_suspend_all_thread(void) -{ - krhino_sched_disable(); -} - -long aos_rtos_resume_all_thread(void) -{ - kstat_t ret; - - ret = krhino_sched_enable(); - - if (ret == RHINO_SUCCESS) { - return oNoErr; - } - - return oGeneralErr; -} - -OSStatus aos_rtos_thread_join( aos_thread_t *thread ) -{ - return oNoErr; -} - - -OSStatus aos_rtos_thread_force_awake( aos_thread_t *thread ) -{ - kstat_t ret; - - ret = krhino_task_wait_abort(*((ktask_t **)thread)); - - if (ret == RHINO_SUCCESS) { - return oNoErr; - } - - return oGeneralErr; -} - - -bool aos_rtos_is_current_thread( aos_thread_t *thread ) -{ - ktask_t *t; - - t = *((ktask_t **)thread); - - if (t == krhino_cur_task_get()) { - return true; - } - - return false; -} - -OSStatus aos_rtos_delay_milliseconds( uint32_t num_ms ) -{ - uint32_t ticks; - - ticks = krhino_ms_to_ticks(num_ms); - if (ticks == 0) { - ticks = 1; - } - - krhino_task_sleep(ticks); - - return oNoErr; -} - -OSStatus aos_rtos_print_thread_status( char *pcWriteBuffer, int xWriteBufferLen ) -{ - pcWriteBuffer[0] = 'n'; - pcWriteBuffer[1] = '\0'; - - (void)xWriteBufferLen; - - return oNoErr; -} - -OSStatus aos_rtos_init_semaphore( aos_semaphore_t *semaphore, int count ) -{ - kstat_t ret; - - ret = krhino_sem_dyn_create((ksem_t **)semaphore, "sema", 0); - - if (ret == RHINO_SUCCESS) { - return oNoErr; - } - - return oGeneralErr; -} - -OSStatus aos_rtos_set_semaphore( aos_semaphore_t *semaphore ) -{ - kstat_t ret; - - ret = krhino_sem_give(*((ksem_t **)semaphore)); - - if (ret == RHINO_SUCCESS) { - return oNoErr; - } - - return oGeneralErr; -} - -OSStatus aos_rtos_get_semaphore( aos_semaphore_t *semaphore, uint32_t timeout_ms ) -{ - kstat_t ret; - tick_t ticks; - - if (timeout_ms == AOS_NEVER_TIMEOUT) { - ret = krhino_sem_take(*((ksem_t **)semaphore), RHINO_WAIT_FOREVER); - } else { - ticks = krhino_ms_to_ticks(timeout_ms); - ret = krhino_sem_take(*((ksem_t **)semaphore), ticks); - } - - if (ret == RHINO_SUCCESS) { - return oNoErr; - } - - return oGeneralErr; -} - -OSStatus aos_rtos_deinit_semaphore( aos_semaphore_t *semaphore ) -{ - kstat_t ret; - - ret = krhino_sem_dyn_del(*((ksem_t **)semaphore)); - - if (ret == RHINO_SUCCESS) { - return oNoErr; - } - - return oGeneralErr; -} - -OSStatus aos_rtos_init_mutex( aos_mutex_t *mutex ) -{ - kstat_t ret; - - ret = krhino_mutex_dyn_create((kmutex_t **)mutex, "mutex"); - - if (ret == RHINO_SUCCESS) { - return oNoErr; - } - - return oGeneralErr; -} - -OSStatus aos_rtos_lock_mutex( aos_mutex_t *mutex ) -{ - kstat_t ret; - - ret = krhino_mutex_lock(*((kmutex_t **)mutex), RHINO_WAIT_FOREVER); - - if (ret == RHINO_SUCCESS) { - return oNoErr; - } - - return oGeneralErr; -} - -OSStatus aos_rtos_unlock_mutex( aos_mutex_t *mutex ) -{ - kstat_t ret; - - ret = krhino_mutex_unlock(*((kmutex_t **)mutex)); - - if (ret == RHINO_SUCCESS) { - return oNoErr; - } - - return oGeneralErr; -} - -OSStatus aos_rtos_deinit_mutex( aos_mutex_t *mutex ) -{ - kstat_t ret; - - ret = krhino_mutex_dyn_del(*((kmutex_t **)mutex)); - - if (ret == RHINO_SUCCESS) { - return oNoErr; - } - - return oGeneralErr; -} - -OSStatus aos_rtos_init_queue( aos_queue_t *queue, const char *name, uint32_t message_size, uint32_t number_of_messages ) -{ - kstat_t ret; - - if (name == NULL) { - name = "default_queue"; - } - - ret = krhino_buf_queue_dyn_create((kbuf_queue_t **)queue, name, - number_of_messages * (message_size + COMPRESS_LEN(message_size)), message_size); - - if (ret == RHINO_SUCCESS) { - return oNoErr; - } - - return oGeneralErr; -} - - -OSStatus aos_rtos_push_to_queue( aos_queue_t *queue, void *message, uint32_t timeout_ms ) -{ - kstat_t ret; - kbuf_queue_t *q = *((kbuf_queue_t **)queue); - - timeout_ms = timeout_ms; - - ret = krhino_buf_queue_send(q, message, q->max_msg_size); - - if (ret == RHINO_SUCCESS) { - return oNoErr; - } - - return oGeneralErr; -} - -OSStatus aos_rtos_pop_from_queue( aos_queue_t *queue, void *message, uint32_t timeout_ms ) -{ - kstat_t ret; - size_t msg_len; - - ret = krhino_buf_queue_recv(*((kbuf_queue_t **)queue), krhino_ms_to_ticks(timeout_ms), message, &msg_len); - - if (ret == RHINO_SUCCESS) { - return oNoErr; - } - - return oGeneralErr; -} - -OSStatus aos_rtos_deinit_queue( aos_queue_t *queue ) -{ - kstat_t ret; - - ret = krhino_buf_queue_dyn_del(*((kbuf_queue_t **)queue)); - - if (ret == RHINO_SUCCESS) { - return oNoErr; - } - - return oGeneralErr; -} - - -bool aos_rtos_is_queue_empty( aos_queue_t *queue ) -{ - bool ret; - CPSR_ALLOC(); - - kbuf_queue_t *q = *((kbuf_queue_t **)queue); - - RHINO_CRITICAL_ENTER(); - - if (q->cur_num == 0) { - ret = true; - } else { - ret = false;; - } - - RHINO_CRITICAL_EXIT(); - - return ret; -} - -bool aos_rtos_is_queue_full( aos_queue_t *queue ) -{ - bool ret; - CPSR_ALLOC(); - - kbuf_queue_t *q = *((kbuf_queue_t **)queue); - uint32_t max_msg_num; - - RHINO_CRITICAL_ENTER(); - - max_msg_num = (q->ringbuf.end - q->ringbuf.buf) / (q->max_msg_size + COMPRESS_LEN(q->max_msg_size)); - - if (q->cur_num == max_msg_num) { - ret = true; - } else { - ret = false; - } - - RHINO_CRITICAL_EXIT(); - - return ret; -} - -aos_time_t aos_rtos_get_time( void ) -{ - return orhino_ticks_to_ms(krhino_sys_tick_get()); -} - -static void timmer_wrapper(void *timer, void *arg) -{ - (void)timer; - - aos_bt_timer_t *timer_arg = arg; - - if (timer_arg->function != 0) { - timer_arg->function(timer_arg->arg); - } -} - -OSStatus aos_rtos_init_timer( aos_bt_timer_t *timer, uint32_t time_ms, timer_handler_t function, void *arg ) -{ - kstat_t ret; - - timer->function = function; - timer->arg = arg; - - ret = krhino_timer_dyn_create((ktimer_t **)(&timer->handle), "timer", timmer_wrapper, - krhino_ms_to_ticks(time_ms), krhino_ms_to_ticks(time_ms), timer, 0); - - if (ret == RHINO_SUCCESS) { - return oNoErr; - } - - return oGeneralErr; -} - -OSStatus aos_rtos_init_oneshot_timer( aos_bt_timer_t *timer, uint32_t time_ms, timer_handler_t function, void *arg ) -{ - kstat_t ret; - - timer->function = function; - timer->arg = arg; - - ret = krhino_timer_dyn_create((ktimer_t **)(&timer->handle), "timer", timmer_wrapper, - krhino_ms_to_ticks(time_ms), 0, timer, 0); - - if (ret == RHINO_SUCCESS) { - return oNoErr; - } - - return oGeneralErr; -} - - -OSStatus aos_rtos_start_timer( aos_bt_timer_t *timer ) -{ - kstat_t ret; - - ret = krhino_timer_start((ktimer_t *)(timer->handle)); - - if (ret == RHINO_SUCCESS) { - return oNoErr; - } - - return oGeneralErr; -} - -OSStatus aos_rtos_stop_timer( aos_bt_timer_t *timer ) -{ - kstat_t ret; - - ret = krhino_timer_stop((ktimer_t *)(timer->handle)); - - - if (ret == RHINO_SUCCESS) { - return oNoErr; - } - - return oGeneralErr; -} - - -OSStatus aos_rtos_reload_timer( aos_bt_timer_t *timer ) -{ - kstat_t ret; - - - krhino_timer_stop((ktimer_t *)(timer->handle)); - - ret = krhino_timer_start((ktimer_t *)(timer->handle)); - - if (ret == RHINO_SUCCESS) { - return oNoErr; - } - - return oGeneralErr; -} - -OSStatus aos_rtos_deinit_timer( aos_bt_timer_t *timer ) -{ - kstat_t ret; - - - krhino_timer_stop((ktimer_t *)(timer->handle)); - ret = krhino_timer_dyn_del((ktimer_t *)(timer->handle)); - - if (ret == RHINO_SUCCESS) { - return oNoErr; - } - - return oGeneralErr; -} - -bool aos_rtos_is_timer_running( aos_bt_timer_t *timer ) -{ - ktimer_t *t; - - t = (ktimer_t *)timer->handle; - - if (t->timer_state == TIMER_ACTIVE) { - - return true; - } - - return false; -} - -bool aos_rtos_is_timer_init( aos_bt_timer_t *timer ) -{ - if (timer == NULL) { - return false; - } - if (timer->handle == NULL) { - return false; - } - - return true; -} - -static void worker_thread_main( uint32_t arg ) -{ - aos_worker_thread_t *worker_thread = (aos_worker_thread_t *) arg; - - while ( 1 ) { - aos_event_message_t message; - - if ( aos_rtos_pop_from_queue( &worker_thread->event_queue, &message, AOS_WAIT_FOREVER ) == oNoErr ) { - message.function( message.arg ); - } - } -} - -OSStatus aos_rtos_create_worker_thread( aos_worker_thread_t *worker_thread, uint8_t priority, uint32_t stack_size, - uint32_t event_queue_size ) -{ - memset( worker_thread, 0, sizeof( *worker_thread ) ); - - if ( aos_rtos_init_queue( &worker_thread->event_queue, "worker queue", sizeof(aos_event_message_t), - event_queue_size ) != oNoErr ) { - return oGeneralErr; - } - - if ( aos_rtos_create_thread( &worker_thread->thread, priority , "worker thread", worker_thread_main, stack_size, - (aos_thread_arg_t) worker_thread ) != oNoErr ) { - aos_rtos_deinit_queue( &worker_thread->event_queue ); - return oGeneralErr; - } - - return oNoErr; -} - -OSStatus aos_rtos_delete_worker_thread( aos_worker_thread_t *worker_thread ) -{ - if ( aos_rtos_delete_thread( &worker_thread->thread ) != oNoErr ) { - return oGeneralErr; - } - - if ( aos_rtos_deinit_queue( &worker_thread->event_queue ) != oNoErr ) { - return oGeneralErr; - } - - return oNoErr; -} - -OSStatus aos_rtos_send_asynchronous_event( aos_worker_thread_t *worker_thread, event_handler_t function, void *arg ) -{ - aos_event_message_t message; - - if ( worker_thread->thread == NULL ) { - return oNotInitializedErr; - } - - message.function = function; - message.arg = arg; - - return aos_rtos_push_to_queue( &worker_thread->event_queue, &message, AOS_NO_WAIT ); -} - -static void timed_event_handler( void *arg ) -{ - aos_timed_event_t *event_object = (aos_timed_event_t *) arg; - aos_event_message_t message; - - message.function = event_object->function; - message.arg = event_object->arg; - - aos_rtos_push_to_queue( &event_object->thread->event_queue, &message, AOS_NO_WAIT ); -} - -OSStatus aos_rtos_register_timed_event( aos_timed_event_t *event_object, aos_worker_thread_t *worker_thread, - event_handler_t function, uint32_t time_ms, void *arg ) -{ - if ( worker_thread->thread == NULL ) { - return oNotInitializedErr; - } - - if ( aos_rtos_init_timer( &event_object->timer, time_ms, timed_event_handler, (void *) event_object ) != oNoErr ) { - return oGeneralErr; - } - - event_object->function = function; - event_object->thread = worker_thread; - event_object->arg = arg; - - if ( aos_rtos_start_timer( &event_object->timer ) != oNoErr ) { - aos_rtos_deinit_timer( &event_object->timer ); - return oGeneralErr; - } - - return oNoErr; -} - -OSStatus aos_rtos_deregister_timed_event( aos_timed_event_t *event_object ) -{ - if ( aos_rtos_deinit_timer( &event_object->timer ) != oNoErr ) { - return oGeneralErr; - } - - - return oNoErr; -} - diff --git a/framework/bluetooth/smartbt/internal/os_wrapper.h b/framework/bluetooth/smartbt/internal/os_wrapper.h deleted file mode 100644 index 8cfedc5284..0000000000 --- a/framework/bluetooth/smartbt/internal/os_wrapper.h +++ /dev/null @@ -1,658 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#ifndef __AOSRTOS_H__ -#define __AOSRTOS_H__ - -//#include "common.h" -#include -#include -#include "os_err.h" - -/** @addtogroup AOS_Core_APIs - * @{ - */ - -/** @defgroup AOS_RTOS AOS RTOS Operations - * @brief Provide management APIs for Thread, Mutex, Timer, Semaphore and FIFO - * @{ - */ - -#define AOS_HARDWARE_IO_WORKER_THREAD ( (aos_worker_thread_t*)&aos_hardware_io_worker_thread) -#define AOS_NETWORKING_WORKER_THREAD ( (aos_worker_thread_t*)&aos_worker_thread ) -#define AOS_WORKER_THREAD ( (aos_worker_thread_t*)&aos_worker_thread ) - -#define AOS_NETWORK_WORKER_PRIORITY (3) -#define AOS_DEFAULT_WORKER_PRIORITY (5) -#define AOS_DEFAULT_LIBRARY_PRIORITY (5) -#define AOS_APPLICATION_PRIORITY (7) - -#define kNanosecondsPerSecond 1000000000UUL -#define kMicrosecondsPerSecond 1000000UL -#define kMillisecondsPerSecond 1000 - -#define AOS_NEVER_TIMEOUT (0xFFFFFFFF) -#define AOS_WAIT_FOREVER (0xFFFFFFFF) -#define AOS_NO_WAIT (0) - -#define AOS_FALSE (0) -#define AOS_TRUE (1) - -typedef int OSStatus; -typedef uint8_t aos_bool_t; - -#if 0 -typedef enum { - WAIT_FOR_ANY_EVENT, - WAIT_FOR_ALL_EVENTS, -} aos_event_flags_wait_option_t; -#endif - -typedef uint32_t aos_event_flags_t; -typedef void *aos_semaphore_t; -//typedef void * aos_mutex_t; -typedef void *aos_thread_t; -//typedef void * aos_queue_t; -typedef void *aos_event_t; // AOS OS event: aos_semaphore_t, aos_mutex_t or aos_queue_t -typedef void (*timer_handler_t)( void *arg ); -typedef OSStatus (*event_handler_t)( void *arg ); -typedef uint32_t aos_time_t; - -typedef struct { - void *handle; - timer_handler_t function; - void *arg; -} aos_bt_timer_t; - -typedef struct { - aos_thread_t thread; - aos_queue_t event_queue; -} aos_worker_thread_t; - -typedef struct { - event_handler_t function; - void *arg; - aos_bt_timer_t timer; - aos_worker_thread_t *thread; -} aos_timed_event_t; - -typedef uint32_t aos_thread_arg_t; -typedef void (*aos_thread_function_t)( aos_thread_arg_t arg ); - -extern aos_worker_thread_t aos_hardware_io_worker_thread; -extern aos_worker_thread_t aos_worker_thread; - -/* Legacy definitions */ -#define aos_thread_sleep aos_rtos_thread_sleep -#define aos_thread_msleep aos_rtos_thread_msleep -#define aos_rtos_init_timer aos_init_timer -#define aos_rtos_start_timer aos_start_timer -#define aos_rtos_stop_timer aos_stop_timer -#define aos_rtos_reload_timer aos_reload_timer -#define aos_rtos_deinit_timer aos_deinit_timer -#define aos_rtos_is_timer_running aos_is_timer_running -#define aos_rtos_init_event_fd aos_create_event_fd -#define aos_rtos_deinit_event_fd aos_delete_event_fd - -#define aos_rtos_thread_msleep aos_rtos_delay_milliseconds - -/** @addtogroup AOS_Core_APIs - * @{ - */ - -/** @defgroup AOS_RTOS AOS RTOS Operations - * @{ - */ - - -/** @defgroup AOS_RTOS_COMMON AOS RTOS Common Functions - * @brief Provide Generic RTOS Functions. - * @{ - */ - - -/** - * @} - */ - -/** @defgroup AOS_RTOS_Thread AOS RTOS Thread Management Functions - * @brief Provide thread creation, delete, suspend, resume, and other RTOS management API - * @verbatim - * AOS thread priority table - * - * +----------+-----------------+ - * | Priority | Thread | - * |----------|-----------------| - * | 0 | AOS | Highest priority - * | 1 | Network | - * | 2 | | - * | 3 | Network worker | - * | 4 | | - * | 5 | Default Library | - * | | Default worker | - * | 6 | | - * | 7 | Application | - * | 8 | | - * | 9 | Idle | Lowest priority - * +----------+-----------------+ - * @endverbatim - * @{ - */ - - -/** @brief Creates and starts a new thread - * - * @param thread : Pointer to variable that will receive the thread handle (can be null) - * @param priority : A priority number. - * @param name : a text name for the thread (can be null) - * @param function : the main thread function - * @param stack_size : stack size for this thread - * @param arg : argument which will be passed to thread function - * - * @return kNoErr : on success. - * @return kGeneralErr : if an error occurred - */ -OSStatus aos_rtos_create_thread( aos_thread_t *thread, uint8_t priority, const char *name, - aos_thread_function_t function, uint32_t stack_size, aos_thread_arg_t arg ); - -/** @brief Deletes a terminated thread - * - * @param thread : the handle of the thread to delete, , NULL is the current thread - * - * @return kNoErr : on success. - * @return kGeneralErr : if an error occurred - */ -OSStatus aos_rtos_delete_thread( aos_thread_t *thread ); - -/** @brief Creates a worker thread - * - * Creates a worker thread - * A worker thread is a thread in whose context timed and asynchronous events - * execute. - * - * @param worker_thread : a pointer to the worker thread to be created - * @param priority : thread priority - * @param stack_size : thread's stack size in number of bytes - * @param event_queue_size : number of events can be pushed into the queue - * - * @return kNoErr : on success. - * @return kGeneralErr : if an error occurred - */ -OSStatus aos_rtos_create_worker_thread( aos_worker_thread_t *worker_thread, uint8_t priority, uint32_t stack_size, - uint32_t event_queue_size ); - - -/** @brief Deletes a worker thread - * - * @param worker_thread : a pointer to the worker thread to be created - * - * @return kNoErr : on success. - * @return kGeneralErr : if an error occurred - */ -OSStatus aos_rtos_delete_worker_thread( aos_worker_thread_t *worker_thread ); - - -/** @brief Suspend a thread - * - * @param thread : the handle of the thread to suspend, NULL is the current thread - * - * @return kNoErr : on success. - * @return kGeneralErr : if an error occurred - */ -void aos_rtos_suspend_thread(aos_thread_t *thread); - - - -/** @brief Suspend all other thread - * - * @param none - * - * @return none - */ -void aos_rtos_suspend_all_thread(void); - - -/** @brief Rresume all other thread - * - * @param none - * - * @return none - */ -long aos_rtos_resume_all_thread(void); - - -/** @brief Sleeps until another thread has terminated - * - * @Details Causes the current thread to sleep until the specified other thread - * has terminated. If the processor is heavily loaded with higher priority - * tasks, this thread may not wake until significantly after the thread termination. - * - * @param thread : the handle of the other thread which will terminate - * - * @return kNoErr : on success. - * @return kGeneralErr : if an error occurred - */ -OSStatus aos_rtos_thread_join( aos_thread_t *thread ); - - -/** @brief Forcibly wakes another thread - * - * @Details Causes the specified thread to wake from suspension. This will usually - * cause an error or timeout in that thread, since the task it was waiting on - * is not complete. - * - * @param thread : the handle of the other thread which will be woken - * - * @return kNoErr : on success. - * @return kGeneralErr : if an error occurred - */ -OSStatus aos_rtos_thread_force_awake( aos_thread_t *thread ); - - -/** @brief Checks if a thread is the current thread - * - * @Details Checks if a specified thread is the currently running thread - * - * @param thread : the handle of the other thread against which the current thread - * will be compared - * - * @return true : specified thread is the current thread - * @return false : specified thread is not currently running - */ -bool aos_rtos_is_current_thread( aos_thread_t *thread ); - - - -/** @brief Suspend current thread for a specific time - * - * @param num_ms : A time interval (Unit: millisecond) - * - * @return kNoErr. - */ -OSStatus aos_rtos_delay_milliseconds( uint32_t num_ms ); - - -/** @brief Print Thread status into buffer - * - * @param buffer, point to buffer to store thread status - * @param length, length of the buffer - * - * @return none - */ -OSStatus aos_rtos_print_thread_status( char *buffer, int length ); - -/** - * @} - */ - -/** @defgroup AOS_RTOS_SEM AOS RTOS Semaphore Functions - * @brief Provide management APIs for semaphore such as init,set,get and dinit. - * @{ - */ - -/** @brief Initialises a counting semaphore and set count to 0 - * - * @param semaphore : a pointer to the semaphore handle to be initialised - * @param count : the max count number of this semaphore - * - * @return kNoErr : on success. - * @return kGeneralErr : if an error occurred - */ -OSStatus aos_rtos_init_semaphore( aos_semaphore_t *semaphore, int count ); - - -/** @brief Set (post/put/increment) a semaphore - * - * @param semaphore : a pointer to the semaphore handle to be set - * - * @return kNoErr : on success. - * @return kGeneralErr : if an error occurred - */ -OSStatus aos_rtos_set_semaphore( aos_semaphore_t *semaphore ); - - -/** @brief Get (wait/decrement) a semaphore - * - * @Details Attempts to get (wait/decrement) a semaphore. If semaphore is at zero already, - * then the calling thread will be suspended until another thread sets the - * semaphore with @ref aos_rtos_set_semaphore - * - * @param semaphore : a pointer to the semaphore handle - * @param timeout_ms: the number of milliseconds to wait before returning - * - * @return kNoErr : on success. - * @return kGeneralErr : if an error occurred - */ -OSStatus aos_rtos_get_semaphore( aos_semaphore_t *semaphore, uint32_t timeout_ms ); - - -/** @brief De-initialise a semaphore - * - * @Details Deletes a semaphore created with @ref aos_rtos_init_semaphore - * - * @param semaphore : a pointer to the semaphore handle - * - * @return kNoErr : on success. - * @return kGeneralErr : if an error occurred - */ -OSStatus aos_rtos_deinit_semaphore( aos_semaphore_t *semaphore ); -/** - * @} - */ - -/** @defgroup AOS_RTOS_MUTEX AOS RTOS Mutex Functions - * @brief Provide management APIs for Mutex such as init,lock,unlock and dinit. - * @{ - */ - -/** @brief Initialises a mutex - * - * @Details A mutex is different to a semaphore in that a thread that already holds - * the lock on the mutex can request the lock again (nested) without causing - * it to be suspended. - * - * @param mutex : a pointer to the mutex handle to be initialised - * - * @return kNoErr : on success. - * @return kGeneralErr : if an error occurred - */ -OSStatus aos_rtos_init_mutex( aos_mutex_t *mutex ); - - -/** @brief Obtains the lock on a mutex - * - * @Details Attempts to obtain the lock on a mutex. If the lock is already held - * by another thead, the calling thread will be suspended until the mutex - * lock is released by the other thread. - * - * @param mutex : a pointer to the mutex handle to be locked - * - * @return kNoErr : on success. - * @return kGeneralErr : if an error occurred - */ -OSStatus aos_rtos_lock_mutex( aos_mutex_t *mutex ); - - -/** @brief Releases the lock on a mutex - * - * @Details Releases a currently held lock on a mutex. If another thread - * is waiting on the mutex lock, then it will be resumed. - * - * @param mutex : a pointer to the mutex handle to be unlocked - * - * @return kNoErr : on success. - * @return kGeneralErr : if an error occurred - */ -OSStatus aos_rtos_unlock_mutex( aos_mutex_t *mutex ); - - -/** @brief De-initialise a mutex - * - * @Details Deletes a mutex created with @ref aos_rtos_init_mutex - * - * @param mutex : a pointer to the mutex handle - * - * @return kNoErr : on success. - * @return kGeneralErr : if an error occurred - */ -OSStatus aos_rtos_deinit_mutex( aos_mutex_t *mutex ); -/** - * @} - */ - -/** @defgroup AOS_RTOS_QUEUE AOS RTOS FIFO Queue Functions - * @brief Provide management APIs for FIFO such as init,push,pop and dinit. - * @{ - */ - -/** @brief Initialises a FIFO queue - * - * @param queue : a pointer to the queue handle to be initialised - * @param name : a text string name for the queue (NULL is allowed) - * @param message_size : size in bytes of objects that will be held in the queue - * @param number_of_messages : depth of the queue - i.e. max number of objects in the queue - * - * @return kNoErr : on success. - * @return kGeneralErr : if an error occurred - */ -OSStatus aos_rtos_init_queue( aos_queue_t *queue, const char *name, uint32_t message_size, - uint32_t number_of_messages ); - - -/** @brief Pushes an object onto a queue - * - * @param queue : a pointer to the queue handle - * @param message : the object to be added to the queue. Size is assumed to be - * the size specified in @ref aos_rtos_init_queue - * @param timeout_ms: the number of milliseconds to wait before returning - * - * @return kNoErr : on success. - * @return kGeneralErr : if an error or timeout occurred - */ -OSStatus aos_rtos_push_to_queue( aos_queue_t *queue, void *message, uint32_t timeout_ms ); - - -/** @brief Pops an object off a queue - * - * @param queue : a pointer to the queue handle - * @param message : pointer to a buffer that will receive the object being - * popped off the queue. Size is assumed to be - * the size specified in @ref aos_rtos_init_queue , hence - * you must ensure the buffer is long enough or memory - * corruption will result - * @param timeout_ms: the number of milliseconds to wait before returning - * - * @return kNoErr : on success. - * @return kGeneralErr : if an error or timeout occurred - */ -OSStatus aos_rtos_pop_from_queue( aos_queue_t *queue, void *message, uint32_t timeout_ms ); - - -/** @brief De-initialise a queue created with @ref aos_rtos_init_queue - * - * @param queue : a pointer to the queue handle - * - * @return kNoErr : on success. - * @return kGeneralErr : if an error occurred - */ -OSStatus aos_rtos_deinit_queue( aos_queue_t *queue ); - - -/** @brief Check if a queue is empty - * - * @param queue : a pointer to the queue handle - * - * @return true : queue is empty. - * @return false : queue is not empty. - */ -bool aos_rtos_is_queue_empty( aos_queue_t *queue ); - - -/** @brief Check if a queue is full - * - * @param queue : a pointer to the queue handle - * - * @return true : queue is empty. - * @return false : queue is not empty. - */ -bool aos_rtos_is_queue_full( aos_queue_t *queue ); - -/** - * @} - */ - - -/** @defgroup AOS_RTOS_EVENT AOS RTOS Event Functions - * @{ - */ - -/** - * @brief Sends an asynchronous event to the associated worker thread - * - * @param worker_thread :the worker thread in which context the callback should execute from - * @param function : the callback function to be called from the worker thread - * @param arg : the argument to be passed to the callback function - * - * @return kNoErr : on success. - * @return kGeneralErr : if an error occurred - */ -OSStatus aos_rtos_send_asynchronous_event( aos_worker_thread_t *worker_thread, event_handler_t function, void *arg ); - -/** Requests a function be called at a regular interval - * - * This function registers a function that will be called at a regular - * interval. Since this is based on the RTOS time-slice scheduling, the - * accuracy is not high, and is affected by processor load. - * - * @param event_object : pointer to a event handle which will be initialised - * @param worker_thread : pointer to the worker thread in whose context the - * callback function runs on - * @param function : the callback function that is to be called regularly - * @param time_ms : the time period between function calls in milliseconds - * @param arg : an argument that will be supplied to the function when - * it is called - * - * @return kNoErr : on success. - * @return kGeneralErr : if an error occurred - */ -OSStatus aos_rtos_register_timed_event( aos_timed_event_t *event_object, aos_worker_thread_t *worker_thread, - event_handler_t function, uint32_t time_ms, void *arg ); - - -/** Removes a request for a regular function execution - * - * This function de-registers a function that has previously been set-up - * with @ref aos_rtos_register_timed_event. - * - * @param event_object : the event handle used with @ref aos_rtos_register_timed_event - * - * @return kNoErr : on success. - * @return kGeneralErr : if an error occurred - */ -OSStatus aos_rtos_deregister_timed_event( aos_timed_event_t *event_object ); - - -/** - * @} - */ - -/** @defgroup AOS_RTOS_TIMER AOS RTOS Timer Functions - * @brief Provide management APIs for timer such as init,start,stop,reload and dinit. - * @{ - */ - -/** - * @brief Gets time in miiliseconds since RTOS start - * - * @note: Since this is only 32 bits, it will roll over every 49 days, 17 hours. - * - * @returns Time in milliseconds since RTOS started. - */ -uint32_t aos_rtos_get_time(void); - - -/** - * @brief Initialize a RTOS timer - * - * @note Timer does not start running until @ref aos_start_timer is called - * - * @param timer : a pointer to the timer handle to be initialised - * @param time_ms : Timer period in milliseconds - * @param function : the callback handler function that is called each time the - * timer expires - * @param arg : an argument that will be passed to the callback function - * - * @return kNoErr : on success. - * @return kGeneralErr : if an error occurred - */ -OSStatus aos_rtos_init_timer( aos_bt_timer_t *timer, uint32_t time_ms, timer_handler_t function, void *arg ); - - -/** @brief Starts a RTOS timer running - * - * @note Timer must have been previously initialised with @ref aos_rtos_init_timer - * - * @param timer : a pointer to the timer handle to start - * - * @return kNoErr : on success. - * @return kGeneralErr : if an error occurred - */ -OSStatus aos_rtos_start_timer( aos_bt_timer_t *timer ); - - -/** @brief Stops a running RTOS timer - * - * @note Timer must have been previously started with @ref aos_rtos_init_timer - * - * @param timer : a pointer to the timer handle to stop - * - * @return kNoErr : on success. - * @return kGeneralErr : if an error occurred - */ -OSStatus aos_rtos_stop_timer( aos_bt_timer_t *timer ); - - -/** @brief Reloads a RTOS timer that has expired - * - * @note This is usually called in the timer callback handler, to - * reschedule the timer for the next period. - * - * @param timer : a pointer to the timer handle to reload - * - * @return kNoErr : on success. - * @return kGeneralErr : if an error occurred - */ -OSStatus aos_rtos_reload_timer( aos_bt_timer_t *timer ); - - -/** @brief De-initialise a RTOS timer - * - * @note Deletes a RTOS timer created with @ref aos_rtos_init_timer - * - * @param timer : a pointer to the RTOS timer handle - * - * @return kNoErr : on success. - * @return kGeneralErr : if an error occurred - */ -OSStatus aos_rtos_deinit_timer( aos_bt_timer_t *timer ); - - -/** @brief Check if an RTOS timer is running - * - * @param timer : a pointer to the RTOS timer handle - * - * @return true : if running. - * @return false : if not running - */ -bool aos_rtos_is_timer_running( aos_bt_timer_t *timer ); - -int SetTimer(unsigned long ms, void (*psysTimerHandler)(void)); -int SetTimer_uniq(unsigned long ms, void (*psysTimerHandler)(void)); -int UnSetTimer(void (*psysTimerHandler)(void)); - -/** @brief Initialize an endpoint for a RTOS event, a file descriptor - * will be created, can be used for select - * - * @param event_handle : aos_semaphore_t, aos_mutex_t or aos_queue_t - * - * @retval On success, a file descriptor for RTOS event is returned. - * On error, -1 is returned. - */ -int aos_rtos_init_event_fd(aos_event_t event_handle); - -/** @brief De-initialise an endpoint created from a RTOS event - * - * @param fd : file descriptor for RTOS event - * - * @retval 0 for success. On error, -1 is returned. - */ -int aos_rtos_deinit_event_fd(int fd); - -#define malloc_named(name,size) aos_malloc(size) -#define malloc_transfer_to_curr_thread(block) -#ifndef UNUSED_PARAMETER -#define UNUSED_PARAMETER(x) ( (void)(x) ) -#endif - -#endif diff --git "a/framework/bone_engine/doc/BoneEngine@lite for aos \344\275\277\347\224\250\350\257\264\346\230\216.md" "b/framework/bone_engine/doc/BoneEngine@lite for aos \344\275\277\347\224\250\350\257\264\346\230\216.md" index 56b29f8714..ee7e55df98 100755 --- "a/framework/bone_engine/doc/BoneEngine@lite for aos \344\275\277\347\224\250\350\257\264\346\230\216.md" +++ "b/framework/bone_engine/doc/BoneEngine@lite for aos \344\275\277\347\224\250\350\257\264\346\230\216.md" @@ -34,7 +34,7 @@ aos make boneengine_demo@mk3060 JTAG=jlink download ``` cat out/boneengine_demo@mk3060/libraries/bone_engine.c_opts - -c -MD -DSYSINFO_KERNEL_VERSION=\"AOS-R-1.1.2\" -DMESH_GATEWAY_SERVICE -DGATEWAY_SDK -mcpu=arm968e-s -march=armv5te -mthumb -mthumb-interwork -mlittle-endian -w -DSYSINFO_PRODUCT_MODEL=\"ALI_AOS_MK3060\" -DSYSINFO_DEVICE_NAME=\"MK3060\" -DSYSINFO_APP_VERSION=\"APP-1.0.0-20171117.0857\" -ggdb -Os -Wall -Wfatal-errors -fsigned-char -ffunction-sections -fdata-sections -fno-common -std=gnu11 -DAOS_SDK_VERSION_MAJOR=3 -DAOS_SDK_VERSION_MINOR=2 -DAOS_SDK_VERSION_REVISION=3 -Iout/boneengine_demo@mk3060/resources/ -DPLATFORM=\"mk3060\" -I./security/alicrypto/inc -I./security/alicrypto/test -I./framework/gateway/msdp/. -I./framework/gateway/devmgr/. -I./kernel/protocols/mesh/include -I./framework/fota/socket/./ -I./framework/fota/platform/./ -I./kernel/modules/fs/kv/include -I./utility/hashtable/. -I./utility/base64/. -I./framework/connectivity/wsf/. -I./kernel/protocols/net/include -I./kernel/protocols/net/port/include -I././platform/mcu/beken/beken7231/beken378/driver/entry/. -I./utility/digest_algorithm/. -I./utility/cjson/include -I./security/mbedtls/include -I./kernel/rhino/core/include -I././platform/arch/arm/armv5/. -I./framework/gateway/./ -I./framework/ywss/. -I./framework/bone_engine/include -I./framework/bone_engine/boards/ALI_AOS_MK3060 -I./framework/netmgr/include -I./framework/netmgr/../protocol/alink/os/platform/ -I./framework/fota/. -I./tools/cli/include -I./framework/protocol/alink/. -I./framework/protocol/alink/accs -I./framework/protocol/alink/json -I./framework/protocol/alink/system -I./framework/protocol/alink/os -I./kernel/vfs/include -I./kernel/vcall/./mico/include -I././platform/mcu/beken/beken7231/beken378/func/mxchip/lwip-2.0.2/port -I././platform/mcu/beken/beken7231/beken378/common -I././platform/mcu/beken/beken7231/beken378/app/config -I././platform/mcu/beken/beken7231/beken378/func/include -I././platform/mcu/beken/beken7231/beken378/os/include -I././platform/mcu/beken/beken7231/beken378/driver/include -I././platform/mcu/beken/beken7231/beken378/driver/common -I././platform/mcu/beken/beken7231/beken378/ip/common -I././platform/mcu/beken/beken7231/beken378/os/FreeRTOSv9.0.0/FreeRTOS/Source/portable/Keil/ARM968es -I./board/mk3060/. -I./include -I./example/boneengine_demo -DBUILD_BIN -DCONFIG_ALICRYPTO -DCONFIG_AOS_MESH -DAOS_KV -DAOS_LOOP -DWITH_LWIP -DCONFIG_NET_LWIP -DAOS_HAL -DCONFIG_YWSS -DAOS_FRAMEWORK_COMMON -DAOS_NETMGR -DAOS_FOTA -DHAVE_NOT_ADVANCED_FORMATE -DCONFIG_AOS_CLI -DAOS_VFS -DVCALL_RHINO -DCONFIG_MX108 -DCONFIG_AOS_KV_MULTIPTN_MODE -DCONFIG_AOS_KV_PTN=6 -DCONFIG_AOS_KV_SECOND_PTN=7 -DCONFIG_AOS_KV_PTN_SIZE=4096 -DCONFIG_AOS_KV_BUFFER_SIZE=8192 -DSTDIO_UART=0 + -c -MD -DSYSINFO_KERNEL_VERSION=\"AOS-R-1.2.0\" -DMESH_GATEWAY_SERVICE -DGATEWAY_SDK -mcpu=arm968e-s -march=armv5te -mthumb -mthumb-interwork -mlittle-endian -w -DSYSINFO_PRODUCT_MODEL=\"ALI_AOS_MK3060\" -DSYSINFO_DEVICE_NAME=\"MK3060\" -DSYSINFO_APP_VERSION=\"APP-1.0.0-20171117.0857\" -ggdb -Os -Wall -Wfatal-errors -fsigned-char -ffunction-sections -fdata-sections -fno-common -std=gnu11 -DAOS_SDK_VERSION_MAJOR=3 -DAOS_SDK_VERSION_MINOR=2 -DAOS_SDK_VERSION_REVISION=3 -Iout/boneengine_demo@mk3060/resources/ -DPLATFORM=\"mk3060\" -I./security/alicrypto/inc -I./security/alicrypto/test -I./framework/gateway/msdp/. -I./framework/gateway/devmgr/. -I./kernel/protocols/mesh/include -I./framework/fota/socket/./ -I./framework/fota/platform/./ -I./kernel/modules/fs/kv/include -I./utility/hashtable/. -I./utility/base64/. -I./framework/connectivity/wsf/. -I./kernel/protocols/net/include -I./kernel/protocols/net/port/include -I././platform/mcu/beken/beken7231/beken378/driver/entry/. -I./utility/digest_algorithm/. -I./utility/cjson/include -I./security/mbedtls/include -I./kernel/rhino/core/include -I././platform/arch/arm/armv5/. -I./framework/gateway/./ -I./framework/ywss/. -I./framework/bone_engine/include -I./framework/bone_engine/boards/ALI_AOS_MK3060 -I./framework/netmgr/include -I./framework/netmgr/../protocol/alink/os/platform/ -I./framework/fota/. -I./tools/cli/include -I./framework/protocol/alink/. -I./framework/protocol/alink/accs -I./framework/protocol/alink/json -I./framework/protocol/alink/system -I./framework/protocol/alink/os -I./kernel/vfs/include -I./kernel/vcall/./mico/include -I././platform/mcu/beken/beken7231/beken378/func/mxchip/lwip-2.0.2/port -I././platform/mcu/beken/beken7231/beken378/common -I././platform/mcu/beken/beken7231/beken378/app/config -I././platform/mcu/beken/beken7231/beken378/func/include -I././platform/mcu/beken/beken7231/beken378/os/include -I././platform/mcu/beken/beken7231/beken378/driver/include -I././platform/mcu/beken/beken7231/beken378/driver/common -I././platform/mcu/beken/beken7231/beken378/ip/common -I././platform/mcu/beken/beken7231/beken378/os/FreeRTOSv9.0.0/FreeRTOS/Source/portable/Keil/ARM968es -I./board/mk3060/. -I./include -I./example/boneengine_demo -DBUILD_BIN -DCONFIG_ALICRYPTO -DCONFIG_AOS_MESH -DAOS_KV -DAOS_LOOP -DWITH_LWIP -DCONFIG_NET_LWIP -DAOS_HAL -DCONFIG_YWSS -DAOS_FRAMEWORK_COMMON -DAOS_NETMGR -DAOS_FOTA -DHAVE_NOT_ADVANCED_FORMATE -DCONFIG_AOS_CLI -DAOS_VFS -DVCALL_RHINO -DCONFIG_MX108 -DCONFIG_AOS_KV_MULTIPTN_MODE -DCONFIG_AOS_KV_PTN=6 -DCONFIG_AOS_KV_SECOND_PTN=7 -DCONFIG_AOS_KV_PTN_SIZE=4096 -DCONFIG_AOS_KV_BUFFER_SIZE=8192 -DSTDIO_UART=0 ``` diff --git a/framework/bone_engine/examples/boneengine_demo.mk b/framework/bone_engine/examples/boneengine_demo.mk index f42df24e53..0fc87b00b6 100755 --- a/framework/bone_engine/examples/boneengine_demo.mk +++ b/framework/bone_engine/examples/boneengine_demo.mk @@ -80,9 +80,3 @@ GLOBAL_DEFINES += CONFIG_CMD_BENCHMARKS endif - -#CURRENT_TIME = $(shell /bin/date +%Y%m%d.%H%M) -#CONFIG_SYSINFO_APP_VERSION = APP-1.0.0-$(CURRENT_TIME) -#$(info app_version:${CONFIG_SYSINFO_APP_VERSION}) -#GLOBAL_CFLAGS += -DSYSINFO_APP_VERSION=\"$(CONFIG_SYSINFO_APP_VERSION)\" - diff --git a/framework/common/common.mk b/framework/common/common.mk index 6537e3dd81..8852526bc3 100644 --- a/framework/common/common.mk +++ b/framework/common/common.mk @@ -9,7 +9,6 @@ ifneq (,${BINS}) GLOBAL_CFLAGS += -DSYSINFO_OS_BINS endif -CURRENT_TIME = $(shell /bin/date +%Y%m%d.%H%M) CONFIG_SYSINFO_APP_VERSION = app-1.0.0-$(CURRENT_TIME) $(info app_version:${CONFIG_SYSINFO_APP_VERSION}) GLOBAL_CFLAGS += -DSYSINFO_APP_VERSION=\"$(CONFIG_SYSINFO_APP_VERSION)\" diff --git a/framework/common/main.c b/framework/common/main.c index 2a696c90c9..e6fbfb429f 100644 --- a/framework/common/main.c +++ b/framework/common/main.c @@ -11,7 +11,7 @@ extern void ota_service_init(void); extern void version_init(void); - +extern int uData_main(void); int aos_framework_init(void) { LOG("aos framework init."); @@ -25,6 +25,10 @@ int aos_framework_init(void) // ota_service_init(); #endif +#ifdef AOS_UDATA + uData_main(); +#endif + return 0; } diff --git a/framework/connectivity/mqtt/mqtt_client.c b/framework/connectivity/mqtt/mqtt_client.c index 592eea40bc..e6b06b31fd 100644 --- a/framework/connectivity/mqtt/mqtt_client.c +++ b/framework/connectivity/mqtt/mqtt_client.c @@ -175,7 +175,7 @@ typedef struct Client { } iotx_mc_client_t, *iotx_mc_client_pt; static int iotx_mc_send_packet(iotx_mc_client_t *c, char *buf, int length, iotx_time_t *timer); -static iotx_mc_state_t iotx_mc_get_client_state(iotx_mc_client_t *pClient); +static int iotx_mc_get_client_state(iotx_mc_client_t *pClient); static void iotx_mc_set_client_state(iotx_mc_client_t *pClient, iotx_mc_state_t newState); static int iotx_mc_keepalive_sub(iotx_mc_client_t *pClient); static void iotx_mc_disconnect_callback(iotx_mc_client_t *pClient) ; @@ -324,7 +324,6 @@ int MQTTConnect(iotx_mc_client_t *pClient) MQTTPacket_connectData *pConnectParams; iotx_time_t connectTimer; int len = 0; - int rc = 0; if (!pClient) { return FAIL_RETURN; @@ -341,7 +340,7 @@ int MQTTConnect(iotx_mc_client_t *pClient) /* send the connect packet*/ iotx_time_init(&connectTimer); utils_time_countdown_ms(&connectTimer, pClient->request_timeout_ms); - if ((rc = iotx_mc_send_packet(pClient, pClient->buf_send, len, &connectTimer)) != SUCCESS_RETURN) { + if ((iotx_mc_send_packet(pClient, pClient->buf_send, len, &connectTimer)) != SUCCESS_RETURN) { HAL_MutexUnlock(pClient->lock_write_buf); log_err("send connect packet failed"); return MQTT_NETWORK_ERROR; @@ -463,7 +462,6 @@ static int MQTTPuback(iotx_mc_client_t *c, unsigned int msgId, enum msgTypes typ static int MQTTSubscribe(iotx_mc_client_t *c, const char *topicFilter, iotx_mqtt_qos_t qos, unsigned int msgId, iotx_mqtt_event_handle_func_fpt messageHandler, void *pcontext) { - int rc = 0; int len = 0; iotx_time_t timer; MQTTString topic = MQTTString_initializer; @@ -502,7 +500,7 @@ static int MQTTSubscribe(iotx_mc_client_t *c, const char *topicFilter, iotx_mqtt return MQTT_PUSH_TO_LIST_ERROR; } - if ((rc = iotx_mc_send_packet(c, c->buf_send, len, &timer)) != SUCCESS_RETURN) { // send the subscribe packet + if ((iotx_mc_send_packet(c, c->buf_send, len, &timer)) != SUCCESS_RETURN) { // send the subscribe packet // If send failed, remove it HAL_MutexLock(c->lock_list_sub); list_remove(c->list_sub_wait_ack, node); @@ -523,7 +521,6 @@ static int MQTTUnsubscribe(iotx_mc_client_t *c, const char *topicFilter, unsigne iotx_time_t timer; MQTTString topic = MQTTString_initializer; int len = 0; - int rc = 0; if (!c || !topicFilter) { return FAIL_RETURN; @@ -551,7 +548,7 @@ static int MQTTUnsubscribe(iotx_mc_client_t *c, const char *topicFilter, unsigne return MQTT_PUSH_TO_LIST_ERROR; } - if ((rc = iotx_mc_send_packet(c, c->buf_send, len, &timer)) != SUCCESS_RETURN) { // send the subscribe packet + if ((iotx_mc_send_packet(c, c->buf_send, len, &timer)) != SUCCESS_RETURN) { // send the subscribe packet // remove from list HAL_MutexLock(c->lock_list_sub); list_remove(c->list_sub_wait_ack, node); @@ -1519,7 +1516,7 @@ static int iotx_mc_cycle(iotx_mc_client_t *c, iotx_time_t *timer) return FAIL_RETURN; } - iotx_mc_state_t state = iotx_mc_get_client_state(c); + int state = iotx_mc_get_client_state(c); if (state != IOTX_MC_STATE_CONNECTED) { log_debug("state = %d", state); return MQTT_STATE_ERROR; @@ -1647,7 +1644,7 @@ static int iotx_mc_check_handle_is_identical(iotx_mc_topic_handle_t *messageHand // subscribe -static iotx_err_t iotx_mc_subscribe(iotx_mc_client_t *c, +static int iotx_mc_subscribe(iotx_mc_client_t *c, const char *topicFilter, iotx_mqtt_qos_t qos, iotx_mqtt_event_handle_func_fpt topic_handle_func, @@ -1659,7 +1656,7 @@ static iotx_err_t iotx_mc_subscribe(iotx_mc_client_t *c, int rc = FAIL_RETURN; - if (qos < IOTX_MQTT_QOS0 || qos > IOTX_MQTT_QOS2) { + if ((int)qos < IOTX_MQTT_QOS0 || (int)qos > IOTX_MQTT_QOS2) { return rc; } @@ -1690,7 +1687,7 @@ static iotx_err_t iotx_mc_subscribe(iotx_mc_client_t *c, // unsubscribe -static iotx_err_t iotx_mc_unsubscribe(iotx_mc_client_t *c, const char *topicFilter) +static int iotx_mc_unsubscribe(iotx_mc_client_t *c, const char *topicFilter) { if (NULL == c || NULL == topicFilter) { return NULL_VALUE_ERROR; @@ -1725,7 +1722,7 @@ static iotx_err_t iotx_mc_unsubscribe(iotx_mc_client_t *c, const char *topicFilt } // publish -static iotx_err_t iotx_mc_publish(iotx_mc_client_t *c, const char *topicName, iotx_mqtt_topic_info_pt topic_msg) +static int iotx_mc_publish(iotx_mc_client_t *c, const char *topicName, iotx_mqtt_topic_info_pt topic_msg) { uint16_t msg_id = 0; @@ -1772,14 +1769,14 @@ static iotx_err_t iotx_mc_publish(iotx_mc_client_t *c, const char *topicName, io // get state of MQTT client -static iotx_mc_state_t iotx_mc_get_client_state(iotx_mc_client_t *pClient) +static int iotx_mc_get_client_state(iotx_mc_client_t *pClient) { if (!pClient) { return -1; } - iotx_mc_state_t state; + int state; HAL_MutexLock(pClient->lock_generic); state = pClient->client_state; HAL_MutexUnlock(pClient->lock_generic); @@ -1848,7 +1845,7 @@ static int iotx_mc_set_connect_params(iotx_mc_client_t *pClient, MQTTPacket_conn // Initialize MQTT client -static iotx_err_t iotx_mc_init(iotx_mc_client_t *pClient, iotx_mqtt_param_t *pInitParams) +static int iotx_mc_init(iotx_mc_client_t *pClient, iotx_mqtt_param_t *pInitParams) { int rc = FAIL_RETURN; int mc_state = IOTX_MC_STATE_INVALID; @@ -1965,7 +1962,7 @@ RETURN : pClient->lock_write_buf = NULL; } } - iotx_mc_set_client_state(pClient, mc_state); + iotx_mc_set_client_state(pClient, (iotx_mc_state_t)mc_state); return rc; } @@ -2107,7 +2104,7 @@ static void iotx_mc_keepalive(iotx_mc_client_t *pClient) /*Periodic sending ping packet to detect whether the network is connected*/ iotx_mc_keepalive_sub(pClient); - iotx_mc_state_t currentState = iotx_mc_get_client_state(pClient); + int currentState = iotx_mc_get_client_state(pClient); do { /*if Exceeds the maximum delay time, then return reconnect timeout*/ if (IOTX_MC_STATE_DISCONNECTED_RECONNECTING == currentState) { @@ -2173,7 +2170,7 @@ static int MQTTRePublish(iotx_mc_client_t *c, char *buf, int len) static int MQTTPubInfoProc(iotx_mc_client_t *pClient) { int rc = 0; - iotx_mc_state_t state = IOTX_MC_STATE_INVALID; + int state = IOTX_MC_STATE_INVALID; if (!pClient) { return FAIL_RETURN; @@ -2376,12 +2373,14 @@ static int iotx_mc_handle_reconnect(iotx_mc_client_t *pClient) // disconnect static int iotx_mc_disconnect(iotx_mc_client_t *pClient) { + int rc = -1; if (NULL == pClient) { return NULL_VALUE_ERROR; } - if (!iotx_mc_check_state_normal(pClient)) { - return SUCCESS_RETURN; + if (iotx_mc_check_state_normal(pClient)) { + rc = MQTTDisconnect(pClient); + log_debug("rc = MQTTDisconnect() = %d", rc); } #ifndef STM32_USE_SPI_WIFI if (is_connected) { @@ -2389,7 +2388,6 @@ static int iotx_mc_disconnect(iotx_mc_client_t *pClient) is_connected = 0; } #endif - (void)MQTTDisconnect(pClient); /*close tcp/ip socket or free tls resources*/ pClient->ipstack->disconnect(pClient->ipstack); @@ -2510,7 +2508,7 @@ static int iotx_mc_keepalive_sub(iotx_mc_client_t *pClient) /************************ Public Interface ************************/ void *IOT_MQTT_Construct(iotx_mqtt_param_t *pInitParams) { - iotx_err_t err; + int err; iotx_mc_client_t *pclient; POINTER_SANITY_CHECK(pInitParams, NULL); @@ -2584,6 +2582,10 @@ int IOT_MQTT_Yield(void *handle, int timeout_ms) // check list of wait subscribe(or unsubscribe) ACK to remove node that is ACKED or timeout MQTTSubInfoProc(pClient); +#ifdef STM32_USE_SPI_WIFI + } else { + return rc; +#endif } // Keep MQTT alive or reconnect if connection abort. @@ -2612,7 +2614,7 @@ int IOT_MQTT_Subscribe(void *handle, POINTER_SANITY_CHECK(topic_handle_func, NULL_VALUE_ERROR); STRING_PTR_SANITY_CHECK(topic_filter, NULL_VALUE_ERROR); - if (qos < IOTX_MQTT_QOS0 || qos > IOTX_MQTT_QOS2) { + if ((int)qos < IOTX_MQTT_QOS0 || (int)qos > IOTX_MQTT_QOS2) { log_warning("Invalid qos(%d) out of [%d, %d], using %d", qos, IOTX_MQTT_QOS0, IOTX_MQTT_QOS2, IOTX_MQTT_QOS0); diff --git a/framework/fota/download/http/ota_download.c b/framework/fota/download/http/ota_download.c index a156908b15..80751fa611 100644 --- a/framework/fota/download/http/ota_download.c +++ b/framework/fota/download/http/ota_download.c @@ -102,19 +102,19 @@ int ota_download(char *url, write_flash_cb_t func, char *md5) int sockfd = 0; int port = 0; int nbytes = 0; - char *host_file = NULL; - char *host_addr = NULL; - char http_buffer[OTA_BUFFER_MAX_SIZE] = {0}; - // char host_file[OTA_URL_MAX_LEN] = {0}; - // char host_addr[256] = {0}; int send = 0; int totalsend = 0; uint32_t breakpoint = 0; + int size = 0; + int header_found = 0; + char *pos = 0; + int file_size = 0; char last_md5[33] = {0}; + char *host_file = NULL; + char *host_addr = NULL; + char http_buffer[OTA_BUFFER_MAX_SIZE] = {0}; http_gethost_info(url, &host_addr, &host_file, &port); - // OTA_LOG_I("host_addr is: %s\n ", host_addr); - // OTA_LOG_I("host_file is: %s\n ", host_file); - // OTA_LOG_I("port is: %d\n ", port); + if (host_file == NULL || host_addr == NULL) { ret = OTA_DOWNLOAD_URL_FAIL; return ret; @@ -128,9 +128,9 @@ int ota_download(char *url, write_flash_cb_t func, char *md5) } breakpoint = ota_get_update_breakpoint(); ota_get_last_MD5(last_md5); - OTA_LOG_I("----breakpoint=%d------", breakpoint); + if (breakpoint && !strncmp(last_md5, md5, 32)) { - OTA_LOG_I("----resume download------"); + OTA_LOG_I("----resume download,breakpoint=%d------", breakpoint); sprintf(http_buffer, HTTP_HEADER_RESUME, host_file, breakpoint, host_addr, port); ota_get_last_MD5_context(&g_ctx); } else { @@ -153,13 +153,9 @@ int ota_download(char *url, write_flash_cb_t func, char *md5) totalsend += send; OTA_LOG_I("%d bytes send OK!\n ", totalsend); } - int size = 0; - int header_found = 0; - char *pos = 0; - int file_size = 0; memset(http_buffer, 0, OTA_BUFFER_MAX_SIZE); - while ((nbytes = ota_socket_recv(sockfd, http_buffer, OTA_BUFFER_MAX_SIZE - 1))) { + while ((nbytes = ota_socket_recv(sockfd, http_buffer, OTA_BUFFER_MAX_SIZE - 1))!=0) { //aos_msleep(25);//for slow-motion test if (nbytes < 0) { OTA_LOG_I("ota_socket_recv nbytes < 0"); diff --git a/framework/fota/download/http/socket/stm32wifi/ota_socket.c b/framework/fota/download/http/socket/stm32wifi/ota_socket.c index e80d1ec013..b0872079b1 100644 --- a/framework/fota/download/http/socket/stm32wifi/ota_socket.c +++ b/framework/fota/download/http/socket/stm32wifi/ota_socket.c @@ -45,8 +45,6 @@ int ota_socket_send(int socket, const char *buf, size_t len) { WIFI_Status_t ret; uint16_t send_size; - uint8_t ip_address[4]; - char ip[16]; if (socket < 0) { OTA_LOG_E("ota_socket_send: invalid socket fd\n"); @@ -84,7 +82,7 @@ int ota_socket_recv(int socket, char *buf, size_t len) int err_count = 0; do { ret = WIFI_ReceiveData((uint8_t)socket, - buf, (uint16_t)len, + (uint8_t*)buf, (uint16_t)len, &recv_size, WIFI_READ_TIMEOUT); if (ret != WIFI_STATUS_OK) { OTA_LOG_E("ota_socket_recv: receive data fail - %d\n", ret); @@ -124,4 +122,4 @@ void ota_socket_close(int socket) int ota_socket_check_conn(int sock) { return sock; -} \ No newline at end of file +} diff --git a/framework/fota/download/ota_download.h b/framework/fota/download/ota_download.h index 3981ca4009..4c6b7aa943 100644 --- a/framework/fota/download/ota_download.h +++ b/framework/fota/download/ota_download.h @@ -11,7 +11,7 @@ int ota_download(char *url, write_flash_cb_t func, char *md5); int check_md5(const char *buffer, const int32_t len); -uint32_t ota_get_update_breakpoint(); +uint32_t ota_get_update_breakpoint(void); void save_state(uint32_t breakpoint, MD5_CTX *pMD5); int ota_set_update_breakpoint(uint32_t offset); int ota_get_last_MD5_context(MD5_CTX *ctx); diff --git a/framework/fota/ota_service.c b/framework/fota/ota_service.c index 4bbc4030a2..647dd0541f 100644 --- a/framework/fota/ota_service.c +++ b/framework/fota/ota_service.c @@ -34,7 +34,7 @@ static int ota_hal_write_cb(int32_t writed_size, uint8_t *buf, int32_t buf_len, return hal_ota_write(hal_ota_get_default_module(), NULL, buf, buf_len); } -static int ota_hal_finish_cb(int32_t finished_result, void *updated_type) +static int ota_hal_finish_cb(OTA_ENUM_RESULT_TYPE finished_result, void *updated_type) { ota_finish_param_t finsh_para; finsh_para.update_type = *(OTA_ENUM_UPDATE_TYPE *)updated_type; diff --git a/framework/fota/ota_update_manifest.c b/framework/fota/ota_update_manifest.c index 2edf21f1e3..6f59f8bb9a 100644 --- a/framework/fota/ota_update_manifest.c +++ b/framework/fota/ota_update_manifest.c @@ -22,7 +22,7 @@ static char *msg_temp = NULL; char md5[33]; -static char *const get_download_url() +static char * get_download_url() { return msg_temp; } @@ -53,7 +53,7 @@ static void free_msg_temp() } } -char *const ota_get_resp_msg() +const char * ota_get_resp_msg() { return msg_temp; } diff --git a/framework/fota/ota_update_manifest.h b/framework/fota/ota_update_manifest.h index 64421a281c..f47d26451e 100644 --- a/framework/fota/ota_update_manifest.h +++ b/framework/fota/ota_update_manifest.h @@ -5,12 +5,14 @@ #ifndef OTA_UPDATE_MANIFEST_H_ #define OTA_UPDATE_MANIFEST_H_ #include +#include #include "ota_transport.h" + typedef int (*write_flash_cb_t)(int32_t writed_size, uint8_t *buf, int32_t buf_len, int type); -typedef int (*ota_finish_cb_t)(int32_t finish_result, void *updated_version); +typedef int (*ota_finish_cb_t)(OTA_ENUM_RESULT_TYPE finish_result, void *updated_version); int8_t ota_do_update_packet(ota_response_params *response_parmas, ota_request_params *request_parmas, @@ -20,7 +22,7 @@ int8_t ota_cancel_update_packet(ota_response_params *response_parmas); int8_t ota_post_version_msg(void); -char *const ota_get_resp_msg(); +const char * ota_get_resp_msg(void); int ota_set_resp_msg(const char *value); #endif /* OTA_UPDATE_MANIFEST_H_ */ diff --git a/framework/fota/ota_util.h b/framework/fota/ota_util.h index 0db5fa8e27..83a9a27cd8 100644 --- a/framework/fota/ota_util.h +++ b/framework/fota/ota_util.h @@ -61,7 +61,7 @@ typedef struct { void ota_status_init(void); -void ota_status_deinit(); +void ota_status_deinit(void); void ota_set_status(OTA_STATUS_T status); @@ -75,7 +75,7 @@ int8_t ota_status_post(int percent); int8_t ota_result_post(void); -const char *ota_get_version(); +const char *ota_get_version(void); void ota_set_version(const char *ota_version); diff --git a/framework/fota/ota_version.h b/framework/fota/ota_version.h index 32de5e382a..da1f330c95 100644 --- a/framework/fota/ota_version.h +++ b/framework/fota/ota_version.h @@ -20,9 +20,9 @@ typedef struct version_config { } version_config_t; -const char *ota_get_system_version(); -const char *ota_get_dev_version(); -const char *ota_get_ota_version(); +const char *ota_get_system_version(void); +const char *ota_get_dev_version(void); +const char *ota_get_ota_version(void); void ota_set_ota_version(const char *version); void ota_set_dev_version(const char *dev_version); diff --git a/framework/fota/platform/ota_platform_os.c b/framework/fota/platform/ota_platform_os.c index 813fc2b456..24f3a6d8d3 100644 --- a/framework/fota/platform/ota_platform_os.c +++ b/framework/fota/platform/ota_platform_os.c @@ -68,13 +68,9 @@ void *ota_semaphore_init(void) return sem; } -int8_t ota_semaphore_wait( void *sem, uint32_t timeout_ms) +int ota_semaphore_wait( void *sem, int32_t timeout_ms) { - if (-1 == timeout_ms) { - return aos_sem_wait((aos_sem_t *)sem, -1); - } else { - return aos_sem_wait((aos_sem_t *)sem, timeout_ms); - } + return aos_sem_wait((aos_sem_t *)sem, timeout_ms); } void ota_semaphore_post(void *sem) diff --git a/framework/fota/platform/ota_platform_os.h b/framework/fota/platform/ota_platform_os.h index 234ccee4cb..42af02b27f 100644 --- a/framework/fota/platform/ota_platform_os.h +++ b/framework/fota/platform/ota_platform_os.h @@ -20,7 +20,7 @@ void ota_mutex_destroy(void *mutex); void *ota_semaphore_init(void); -int8_t ota_semaphore_wait(void *sem, uint32_t timeout_ms); +int ota_semaphore_wait(void *sem, int32_t timeout_ms); void ota_semaphore_post(void *sem); diff --git a/framework/fota/platform/ota_transport.h b/framework/fota/platform/ota_transport.h index fc3b25ca69..01e57dbce8 100644 --- a/framework/fota/platform/ota_transport.h +++ b/framework/fota/platform/ota_transport.h @@ -48,5 +48,5 @@ int8_t platform_ota_status_post(int status, int percent); int8_t platform_ota_result_post(void); -const char *platform_ota_get_id(); +const char *platform_ota_get_id(void); #endif /* OTA_TRANSPORT_H_ */ diff --git a/framework/fsyscall/syscall_ftbl.c b/framework/fsyscall/syscall_ftbl.c index d4c1b504c8..9903ad3e34 100644 --- a/framework/fsyscall/syscall_ftbl.c +++ b/framework/fsyscall/syscall_ftbl.c @@ -14,8 +14,9 @@ #include #include #endif +#ifdef AOS_NETMGR #include - +#endif extern const char *gateway_get_uuid(void); extern bool gateway_is_connected(void); diff --git a/framework/gateway/gateway.mk b/framework/gateway/gateway.mk index 4b4952c7b4..2621393554 100644 --- a/framework/gateway/gateway.mk +++ b/framework/gateway/gateway.mk @@ -8,22 +8,6 @@ GLOBAL_CFLAGS += -DMESH_GATEWAY_SERVICE -DGATEWAY_SDK $(NAME)_SOURCES += gateway_service.c -ifeq ($(COMPILER),) -$(NAME)_CFLAGS += -Wall -Werror -Wno-unused-variable -Wno-unused-parameter -Wno-implicit-function-declaration -$(NAME)_CFLAGS += -Wno-type-limits -Wno-sign-compare -Wno-pointer-sign -Wno-uninitialized -$(NAME)_CFLAGS += -Wno-return-type -Wno-unused-function -Wno-unused-but-set-variable -$(NAME)_CFLAGS += -Wno-unused-value -Wno-strict-aliasing -else ifeq ($(COMPILER),gcc) -$(NAME)_CFLAGS += -Wall -Werror -Wno-unused-variable -Wno-unused-parameter -Wno-implicit-function-declaration -$(NAME)_CFLAGS += -Wno-type-limits -Wno-sign-compare -Wno-pointer-sign -Wno-uninitialized -$(NAME)_CFLAGS += -Wno-return-type -Wno-unused-function -Wno-unused-but-set-variable -$(NAME)_CFLAGS += -Wno-unused-value -Wno-strict-aliasing -endif - $(NAME)_COMPONENTS += cjson protocols.mesh protocol.alink gateway.devmgr gateway.msdp -ifneq ($(sal),1) -$(NAME)_COMPONENTS += protocols.net -endif - GLOBAL_DEFINES += CONFIG_GATEWAY diff --git a/framework/gateway/mqtt_sn.h b/framework/gateway/mqtt_sn.h index 7053b89ab0..265a267229 100644 --- a/framework/gateway/mqtt_sn.h +++ b/framework/gateway/mqtt_sn.h @@ -63,14 +63,14 @@ typedef struct { uint8_t Flags; uint8_t TopicId[2]; uint8_t MsgId[2]; - uint8_t payload[0]; + uint8_t payload[]; } __attribute__((packed)) pub_body_t; typedef struct { uint8_t Flags; uint8_t MsgId[2]; union { - char TopicName[0]; + char TopicName[1]; uint8_t TopicId[2]; }; } __attribute__((packed)) sub_body_t; @@ -79,18 +79,18 @@ typedef struct { uint8_t Flags; uint8_t ProtocolId; uint8_t Duration[2]; - char ClientId[0]; + char ClientId[]; } __attribute__((packed)) conn_body_t; typedef struct { uint8_t ReturnCode; - uint8_t payload[0]; + uint8_t payload[]; } __attribute__((packed)) conn_ack_t; typedef struct { uint8_t GwId; uint8_t Duration[2]; - uint8_t payload[0]; + uint8_t payload[]; } __attribute__((packed)) adv_body_t; static inline int msn_parse_header(uint8_t *buf, int l, uint8_t **pbuf) diff --git a/framework/protocol/alink/accs/accs.c b/framework/protocol/alink/accs/accs.c index c5c2b57092..6932135666 100644 --- a/framework/protocol/alink/accs/accs.c +++ b/framework/protocol/alink/accs/accs.c @@ -81,7 +81,7 @@ int accs_start() int accs_stop() { if (accs_get_state() != SERVICE_STATE_STOP) { - LOG("accs will stop current session.\n"); + LOG("accs will stop current session."); cm_get_conn("wsf")->disconnect();//wsf_disconnect cm_release_conn("wsf", &accs_conn_listener); accs_set_state(SERVICE_STATE_STOP); @@ -141,7 +141,7 @@ int accs_add_listener(service_cb func) service_listener_t)); listener->listen = func; dlist_add(&listener->list_head, &g_accs_listener_list); - LOGD(MODULE_NAME_ACCS, "accs add listerner: %p\n", func); + LOGD(MODULE_NAME_ACCS, "accs add listerner: %p", func); accs_notify_event(func, SERVICE_ATTACH); return SERVICE_RESULT_OK; } @@ -153,7 +153,7 @@ int accs_del_listener(service_cb func) dlist_for_each_entry_safe(&g_accs_listener_list, tmp, pos, service_listener_t, list_head) { if (pos->listen == func) { - LOGD(MODULE_NAME_ACCS, "accs del listerner: %p\n", func); + LOGD(MODULE_NAME_ACCS, "accs del listerner: %p", func); accs_notify_event(func, SERVICE_DETACH); dlist_del(&pos->list_head); os_free(pos); @@ -188,9 +188,10 @@ static int accs_conn_listener(int type, void *data, int dlen, void *result, ; //ignore connect open event } else if (st == CONNECT_STATE_READY) { accs_set_state(SERVICE_STATE_PREPARE); - LOG("we will start handshake work.\n"); + LOG("we will start handshake work."); start_accs_work(0); } else if (st == CONNECT_STATE_CLOSE) { + LOG("ACCS: disconnected"); void *cb = alink_cb_func[_ALINK_CLOUD_DISCONNECTED]; if (cb) { void (*func)(void) = cb; @@ -259,11 +260,12 @@ static int accs_broadcast_data(void *data, int dlen, void *result, int *rlen) static void accs_handshake_async(void *arg) { - LOG("handshake work started. \n"); + LOG("handshake work started."); if (accs_get_state() == SERVICE_STATE_PREPARE) { if (alink_handshake_async() == SERVICE_RESULT_OK) { - void *cb = alink_cb_func[_ALINK_CLOUD_CONNECTED]; accs_set_state(SERVICE_STATE_READY); + LOG("ACCS: connected"); + void *cb = alink_cb_func[_ALINK_CLOUD_CONNECTED]; if (cb) { void (*func)(void) = cb; func(); @@ -286,6 +288,7 @@ static void accs_handshake(void *arg) */ if (accs_get_state() == SERVICE_STATE_PREPARE) { if (alink_handshake() == SERVICE_RESULT_OK) { + LOG("ACCS: connected"); void *cb = alink_cb_func[_ALINK_CLOUD_CONNECTED]; accs_set_state(SERVICE_STATE_READY); if (cb) { @@ -343,7 +346,7 @@ static int accs_event_handler(int type, void *data, int dlen, void *result, ret = EVENT_IGNORE; //TODO: setDeviceStatusArray not support } else if (!strcmp(p->method, "upgradeDevice")) { - LOGW(MODULE_NAME_ACCS, "start to OTA now...%s\n", p->data); + LOGW(MODULE_NAME_ACCS, "start to OTA now...%s", p->data); aos_cloud_trigger(_ALINK_UPGRADE_DEVICE, p->data); cb = alink_cb_func[_ALINK_UPGRADE_DEVICE]; ret = EVENT_CONSUMED; @@ -352,7 +355,7 @@ static int accs_event_handler(int type, void *data, int dlen, void *result, func(p->data); } } else if (!strcmp(p->method, "unUpgradeDevice")) { - LOGW(MODULE_NAME_ACCS, "stop to OTA now...%s\n", p->data); + LOGW(MODULE_NAME_ACCS, "stop to OTA now...%s", p->data); aos_cloud_trigger(_ALINK_CANCEL_UPGRADE_DEVICE, p->data); cb = alink_cb_func[_ALINK_CANCEL_UPGRADE_DEVICE]; ret = EVENT_CONSUMED; diff --git a/framework/protocol/alink/os/os.h b/framework/protocol/alink/os/os.h index 4dd83b8866..2373261d6a 100644 --- a/framework/protocol/alink/os/os.h +++ b/framework/protocol/alink/os/os.h @@ -618,7 +618,7 @@ extern void __os_free_debug(const char *func, void *ptr); #else static inline void os_free(_IN_ void *ptr) { - return platform_free(ptr); + platform_free(ptr); } #endif diff --git a/framework/protocol/alink/os/platform/aos_awss.c b/framework/protocol/alink/os/platform/aos_awss.c index d582c80909..4ef238e791 100644 --- a/framework/protocol/alink/os/platform/aos_awss.c +++ b/framework/protocol/alink/os/platform/aos_awss.c @@ -249,7 +249,7 @@ int platform_wifi_low_power(int timeout_ms) return 0; } -static void mgnt_rx_cb(uint8_t *data, int len) +static void mgnt_rx_cb(uint8_t *data, int len, hal_wifi_link_info_t *info) { if (monitor_cb) { monitor_cb(data, len, 0, 0); diff --git a/framework/uData/abs_data_model/abs_data_model.c b/framework/uData/abs_data_model/abs_data_model.c new file mode 100644 index 0000000000..4d8fd3daba --- /dev/null +++ b/framework/uData/abs_data_model/abs_data_model.c @@ -0,0 +1,438 @@ +/* +* Copyright (C) 2015-2017 Alibaba Group Holding Limited +* +* +* abstract(abs) data model +* +* +*/ + +#include "abs_data_model.h" +#include +#include +#include +#include + +typedef sensor_list_t abs_data_list_t; +#define DEFAULT_TIMER_INTERVAL 1000 /* 1000ms */ +static bool is_timer_work = false; +static int cur_interval = 0; +static uint32_t abs_data_cnt = 0; +static abs_data_pkg_t* g_abs_data_db[ABS_DATA_MAX_CNT]; +static aos_timer_t g_abs_data_timer; +static abs_data_list_t g_abs_data_table; + +/* NOTE: please follow the sensor order of the "sensor_tag_e" + which is defined the the sensor.h file */ +sensor_node_t g_sensor_node[] = { + { TAG_DEV_ACC, dev_acc_path, 0}, + { TAG_DEV_MAG, dev_mag_path, 0}, + { TAG_DEV_GYRO, dev_gyro_path, 0}, + { TAG_DEV_ALS, dev_als_path, 0}, + { TAG_DEV_PS, dev_ps_path, 0}, + { TAG_DEV_BARO, dev_baro_path, 0}, + { TAG_DEV_TEMP, dev_temp_path, 0}, + { TAG_DEV_UV, dev_uv_path, 0}, + { TAG_DEV_HUMI, dev_humi_path, 0}, + { TAG_DEV_HALL, dev_hall_path, 0}, + { TAG_DEV_HR, dev_hr_path, 0}, +}; + +static bool abs_data_get_timer_status(void) +{ + return is_timer_work; +} + +static void abs_data_set_timer_status(bool status) +{ + is_timer_work = status; +} + +static int abs_data_create_obj_ctx(int arg, void* pdata) +{ + g_abs_data_db[abs_data_cnt] = (abs_data_pkg_t*)aos_malloc(sizeof(abs_data_pkg_t)); + if((pdata == NULL)||(g_abs_data_db[abs_data_cnt] == NULL)){ + return -1; + } + memset(g_abs_data_db[abs_data_cnt], 0, (sizeof(abs_data_pkg_t))); + + uData_service_t* service = pdata; + g_abs_data_db[abs_data_cnt]->tag = service->tag; + g_abs_data_db[abs_data_cnt]->interval = arg; + g_abs_data_db[abs_data_cnt]->poweron = true; + g_abs_data_db[abs_data_cnt]->cur_timestamp = aos_now_ms(); + g_abs_data_db[abs_data_cnt]->full_info.config.odr = service->config.odr; + g_abs_data_db[abs_data_cnt]->full_info.config.range = service->config.range; + g_abs_data_db[abs_data_cnt]->calibrated_algo_process_cb = NULL; + g_abs_data_db[abs_data_cnt]->srv_cnt++; + abs_data_cnt++; + + return 0; +} + +static int abs_data_get_obj_index(sensor_tag_e tag){ + int i = 0; + for(i = 0; i< abs_data_cnt; i++){ + if(g_abs_data_db[i]->tag == tag){ + return i; + } + } + return -1; +} + +static void abs_data_post_timer_expried_dev(uint64_t timestamp) +{ + uint8_t i = 0; + for(i = 0; i < abs_data_cnt; i++){ + if((timestamp - g_abs_data_db[i]->cur_timestamp) >= (g_abs_data_db[i]->interval)){ + aos_post_event(EV_UDATA, CODE_UDATA_DEV_READ, (g_abs_data_db[i]->tag)); + /* update the timestamp of triggered sensor here for the next timer hadler */ + g_abs_data_db[i]->cur_timestamp = timestamp; + } + } + +} + +int abs_data_dev_enable(sensor_tag_e tag) +{ + int ret = 0; + + + if(abs_data_get_timer_status()){ + return 0; + } + + ret = aos_timer_start(&g_abs_data_timer); + if(unlikely(ret)){ + return -1; + } + return 0; +} + +int abs_data_dev_disable(sensor_tag_e tag) +{ + int ret = 0; + if(!abs_data_get_timer_status()){ + return 0; + } + ret = aos_timer_stop(&g_abs_data_timer); + if(unlikely(ret)){ + return -1; + } + return 0; +} + +static int abs_data_biuld_dev_tree(void* buf) +{ + abs_data_list_t* table = buf; + if(table == NULL){ + return -1; + } + + g_abs_data_table.cnt = table->cnt; + for(int i = 0; i < g_abs_data_table.cnt; i++){ + g_abs_data_table.list[i] = table->list[i]; + } +} + + +static int abs_data_collect_dev_list(void* buf) +{ + int fd = 0; + int ret = 0; + if(buf == NULL){ + return -1; + } + + fd = aos_open(sensor_node_path, O_RDWR); + if(fd < 0){ + return -1; + } + + ret = aos_ioctl(fd, SENSOR_IOCTL_GET_SENSOR_LIST, buf); + if(ret < 0){ + return -1; + } + ret = aos_close(fd); + if(ret < 0){ + return -1; + } + return 0; +} + +static bool abs_data_check_dev_tree(sensor_tag_e tag) +{ + for(int i = 0; i < g_abs_data_table.cnt; i++){ + if(g_abs_data_table.list[i] == tag){ + return true; + } + } + return false; +} + +static int abs_data_timer_update(sensor_tag_e tag, int interval) +{ + int ret = 0; + + if(interval <= 0){ + return -1; + } + + /* no need change the interval in this case here */ + if(interval > cur_interval){ + return 0; + } + /* fill the timer info inot the interval lists of timer from sensor service side, + set the timer of abs sensor model by the min interval */ + + ret = aos_timer_stop(&g_abs_data_timer); + if(unlikely(ret)){ + return -1; + } + ret = aos_timer_change(&g_abs_data_timer, interval); + if(unlikely(ret)){ + return -1; + } + + ret = aos_timer_start(&g_abs_data_timer); + if(unlikely(ret)){ + return -1; + } + + abs_data_set_timer_status(true); + cur_interval = interval; + return 0; +} + +int abs_data_open(uData_service_t *service) +{ + int ret = 0; + int interval = 0; + int fd = 0; + int index = 0; + + if(service == NULL){ + return -1; + } + + /* check the target in the dev tree */ + if(!(abs_data_check_dev_tree(service->tag))){ + return -1; + } + + interval = HZ_2_INTERVAL(service->config.odr); + ret = abs_data_timer_update(service->tag, interval); + if(unlikely(ret)){ + return -1; + } + + /* chekc the device if it already exists here */ + index = abs_data_get_obj_index(service->tag); + if(index >= 0){ + /* no operation if the device is already open and power on */ + if((g_abs_data_db[index]->poweron == 1)){ + return 0; + } + else{ + /* just power on the device if the device is already open but power off */ + ret = aos_ioctl(g_sensor_node[service->tag].fd, SENSOR_IOCTL_SET_POWER, true); + if(ret <= 0){ + return -1; + } + g_abs_data_db[index]->poweron = 1; + return 0; + } + } + + fd = aos_open((g_sensor_node[service->tag].path), O_RDWR); + if(fd <= 0){ + return -1; + } + + g_sensor_node[service->tag].fd = fd; + + /* set the configuration para from the service algo */ + if((service->config.id & SENSOR_IOCTL_ODR_SET) != 0){ + ret = aos_ioctl(fd,service->config.id, service->config.odr); + if(ret < 0){ + return -1; + } + } + + if((service->config.id & SENSOR_IOCTL_RANGE_SET) != 0){ + ret = aos_ioctl(fd,service->config.id, service->config.range); + if(ret < 0){ + return -1; + } + } + + ret = abs_data_create_obj_ctx(interval, service); + if(unlikely(ret)){ + return -1; + } + LOG("%s %s successfully\n", uDATA_STR, __func__); + return 0; +} + +int abs_data_close(sensor_tag_e tag) +{ + int ret = 0; + uint32_t index = 0; + if(g_sensor_node[tag].fd <= 0){ + return -1; + } + ret = aos_ioctl(g_sensor_node[tag].fd, SENSOR_IOCTL_SET_POWER, false); + if(ret < 0){ + return -1; + } + + /* + ret = aos_close(g_sensor_node[tag].fd); + if(unlikely(ret)){ + return -1; + } + */ + index = abs_data_get_obj_index(tag); + g_abs_data_db[index]->poweron = false; + for(index = 0; index < abs_data_cnt; index++){ + if(g_abs_data_db[index]->poweron == true){ + break; + } + if(abs_data_get_timer_status() != false){ + aos_timer_stop(&g_abs_data_timer); + } + } + return 0; +} + +int abs_data_read(sensor_tag_e tag, void* pdata, uint32_t nbyte) +{ + int ret = 0; + int index = 0; + /* read the physical sensor data by posix way */ + ret = aos_read(g_sensor_node[tag].fd, pdata, nbyte); + if(ret <= 0){ + LOG("%s %s %s %d\n", uDATA_STR, __func__, ERROR_LINE, __LINE__); + return -1; + } + /* update the legth of the data here */ + nbyte = ret; + + /* check if calibrated aglo registed base on this sensor. + yes for invoking the callback here */ + index = abs_data_get_obj_index(tag); + if((g_abs_data_db[index] != NULL)&&(g_abs_data_db[index]->calibrated_algo_process_cb != NULL)){ + g_abs_data_db[index]->calibrated_algo_process_cb(pdata); + } + + ret = aos_post_event(EV_UDATA, CODE_UDATA_SERVICE_PROCESS, tag); + if(ret < 0){ + return -1; + } + + LOG("%s %s successfully \n", uDATA_STR, __func__); + return 0; +} + +int abs_data_ioctl(sensor_tag_e tag, void* config) +{ + int ret = 0; + unsigned long arg = 0; + dev_sensor_full_info_t* sensor_config = config; + + if(sensor_config->config.id == SENSOR_IOCTL_ODR_SET){ + arg = sensor_config->config.odr; + } + else if(sensor_config->config.id == SENSOR_IOCTL_RANGE_SET){ + arg = sensor_config->config.range; + } + else if(sensor_config->config.id == SENSOR_IOCTL_GET_INFO){ + /* fill the dev info addr, then get back after filling by the phy sensor */ + arg = &sensor_config->info; + } + else if(sensor_config->config.id == SENSOR_IOCTL_GET_SENSOR_LIST){ + /* should open the sensor hale node to get all the senor list */ + //ret = abs_data_get_dev_list(&(sensor_config->info.list)); + //if(unlikely(ret)){ + //LOG("%s %s %s %d\n", uDATA_STR, __func__, ERROR_LINE, __LINE__); + // return -1; + //} + //return 0; + } + + ret = aos_ioctl(g_sensor_node[tag].fd, sensor_config->config.id, arg); + if(ret <= 0){ + return -1; + } + return 0; +} + +int abs_cali_data_register(sensor_tag_e tag, void* cb) +{ + int ret = 0; + int index = 0; + + if(cb == NULL){ + return -1; + } + + /* also can copy the data struct here */ + index = abs_data_get_obj_index(tag); + if(g_abs_data_db[index] == NULL){ + return -1; + } + g_abs_data_db[index]->calibrated_algo_process_cb = cb; + + return 0; +} + +int abs_cali_data_unregister(udata_type_e type) +{ + // TODO; +} + +static void abs_data_timer_process(void* arg) +{ + abs_data_post_timer_expried_dev(aos_now_ms()); +} + +int abs_data_cali_init(void){ + int ret = 0; + ret = cali_example_example_init(); + if(unlikely(ret)){ + return -1; + } + + LOG("%s %s successfully \n", uDATA_STR, __func__); + return 0; +} + +int abs_data_model_init(void) +{ + int ret = 0; + + ret = aos_timer_new_ext(&g_abs_data_timer, abs_data_timer_process, NULL, DEFAULT_TIMER_INTERVAL, 0, 0); + + /* must stop the timer here, since the timer is triggered after be created */ + if(unlikely(ret)){ + return -1; + } + + abs_data_set_timer_status(false); + cur_interval = DEFAULT_TIMER_INTERVAL; + + memset(&g_abs_data_table, 0, sizeof(g_abs_data_table)); + ret = abs_data_collect_dev_list(&g_abs_data_table); + if(unlikely(ret)){ + return -1; + } + /* + ret = abs_data_biuld_dev_tree(&g_abs_data_table); + if(unlikely(ret)){ + return -1; + } + */ + + LOG("%s %s successfully \n", uDATA_STR, __func__); + return 0; +} diff --git a/framework/uData/cali_data/calibrated_example_algo.c b/framework/uData/cali_data/calibrated_example_algo.c new file mode 100644 index 0000000000..646e4d1d2a --- /dev/null +++ b/framework/uData/cali_data/calibrated_example_algo.c @@ -0,0 +1,36 @@ +/* +* Copyright (C) 2015-2017 Alibaba Group Holding Limited +* +* +*/ + +#include "abs_data_model.h" +#include +#include +#include +#include + +int cali_example_process_cb(void* pdata) +{ + /* just a simple example here + show how to register inot the abs model */ + + LOG("%s %s successfully \n", uDATA_STR, __func__); + return 0; +} + + +int cali_example_example_init(void){ + int ret = 0; + ret = abs_cali_data_register(TAG_DEV_ACC, cali_example_process_cb); + if(unlikely(ret)){ + return -1; + } + + LOG("%s %s successfully \n", uDATA_STR, __func__); + return 0; +} + + + + diff --git a/framework/uData/include/abs_data_model.h b/framework/uData/include/abs_data_model.h new file mode 100644 index 0000000000..e78f844a6e --- /dev/null +++ b/framework/uData/include/abs_data_model.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/** + * @abstract data model + * @brief abstract data api + * @version since 0.0.1 + */ + +#ifndef ABS_SENSOR_MODEL_H +#define ABS_SENSOR_MODEL_H + +#include "uData_com_desc.h" + +int abs_data_model_init(void); +int abs_data_open(uData_service_t *service); +int abs_data_close(sensor_tag_e tag); +int abs_data_read(sensor_tag_e tag, void* pdata, uint32_t nbyte); +int abs_data_ioctl(sensor_tag_e tag, void* config); +int abs_cali_data_register(sensor_tag_e tag, void* cb); +int abs_cali_data_unregister(udata_type_e type); + +#endif /*ABS_SENSOR_MODEL_H*/ + diff --git a/framework/uData/include/service_algo.h b/framework/uData/include/service_algo.h new file mode 100644 index 0000000000..5ae50d227c --- /dev/null +++ b/framework/uData/include/service_algo.h @@ -0,0 +1,12 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#ifndef SERVICE_ALGO_H +#define SERVICE_ALGO_H + +extern int service_example_init(void); + + +#endif /* SERVICE_ALGO_H */ + diff --git a/framework/uData/include/service_mgr.h b/framework/uData/include/service_mgr.h new file mode 100644 index 0000000000..17e747f0b8 --- /dev/null +++ b/framework/uData/include/service_mgr.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/** + * @uData service manager + * @brief serive manager API + * @version since 0.0.1 + */ + +#ifndef SERVICE_MANAGER_H +#define SERVICE_MANAGER_H + +#include "uData_com_desc.h" + + +int uData_service_mgr_init(void); +int uData_service_register(uData_service_t *service); +int uData_service_unregister(udata_type_e type); + +#endif /*SERVICE_MANAGER_H*/ + diff --git a/framework/uData/include/uData_com_desc.h b/framework/uData/include/uData_com_desc.h new file mode 100644 index 0000000000..3347f4af78 --- /dev/null +++ b/framework/uData/include/uData_com_desc.h @@ -0,0 +1,122 @@ + +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +/** + * @uData + * @brief uData object desc + * @version since 0.0.1 + */ + +#ifndef UDATA_OBJ_DESC_H +#define UDATA_OBJ_DESC_H + +#include +#include "hal/sensor.h" +#include "aos/log.h" + + +#define DO_FOREVER + +#define uDATA_STR "uData: " /* uData debug header */ + +#define TIMESTAMP_2_MS(t) ((t) / 1000) +#define MS_2_TIMESTAMP(ms) ((ms) * 1000) + +#define INTERVAL_2_MS(i) TIMESTAMP_2_MS(i) +#define MS_TO_INTERVAL(ms) MS_2_TIMESTAMP(ms) + +#define HZ_2_INTERVAL(hz) ((hz) ? ((1000) / (hz)) : 0) +#define INTERVAL_2_HZ(i) ((i) == 0 ? 0 : ((i) > MS_2_TIMESTAMP(1000) ? 1 : (MS_2_TIMESTAMP(1000) / (i)))) + +#define HZ_2_TIMESTAMP(hz) HZ_2_INTERVAL(hz) +#define TIMESTAMP_2_HZ(t) INTERVAL_2_HZ(t) + +typedef bool b_subscribed; +typedef bool b_enbled; +typedef int (*fn_cb)(void* pData); /* callback for calibrated algo */ + +typedef enum +{ + UDATA_SERVICE_ACC = 0, /* Accelerometer */ + UDATA_SERVICE_MAG, /* Magnetometer */ + UDATA_SERVICE_GYRO, /* Gyroscope */ + UDATA_SERVICE_ALS, /* Ambient light sensor */ + UDATA_SERVICE_PS, /* Proximity */ + UDATA_SERVICE_BARO, /* Barometer */ + UDATA_SERVICE_TEMP, /* Temperature */ + UDATA_SERVICE_UV, /* Ultraviolet */ + UDATA_SERVICE_HUMI, /* Humidity */ + UDATA_SERVICE_HALL, /* HALL sensor */ + UDATA_SERVICE_HR, /* Heart Rate sensor */ + UDATA_SERVICE_PEDOMETER, + UDATA_SERVICE_PDR, + UDATA_SERVICE_VDR, + + UDATA_MAX_CNT, +}udata_type_e; + +/* the max size of the dat buf */ +#define DATA_SIZE 20 +#define ABS_DATA_MAX_CNT TAG_DEV_SENSOR_NUM_MAX + +struct _abs_cali_cb_t { + sensor_tag_e tag; + int (*calibrated_algo_process_cb)(sensor_tag_e tag, void* pData); /* callback for calibrated algo */ +}; +typedef struct _abs_cali_cb_t abs_cali_cb_t; + +struct _abs_data_pkg_t { + sensor_tag_e tag; + uint8_t srv_cnt; /* count of the registed service base on this sensor */ + bool poweron; /* the power status of the registed service base on this sensor */ + uint32_t interval;/* the report data interval of the sensor*/ + uint64_t cur_timestamp; /* the current timestamp for every sensor, the unit is ms */ + int (*calibrated_algo_process_cb)(void* pData); /* callback for calibrated algo */ + dev_sensor_full_info_t full_info; +}; +typedef struct _abs_data_pkg_t abs_data_pkg_t; + +/* sensor service manager layer*/ +struct _uData_service_t { + udata_type_e type; + sensor_tag_e tag; + b_subscribed subscribe; /* subscribe only from aliyun side */ + b_enbled running; + dev_sensor_config_t config; + uint8_t payload[DATA_SIZE]; + size_t(*service_process_cb)(sensor_tag_e tag, void* pdata); /* process callback for udata service handle */ + int(*service_ioctl_cb)(udata_type_e type, sensor_tag_e tag); /* ioclt callback for udata service handle */ +}; +typedef struct _uData_service_t uData_service_t; + +struct _sensor_msg_pkg_t { + sensor_tag_e tag; + uint8_t cmd; + dev_sensor_config_t config; +}; +typedef struct _sensor_msg_pkg_t sensor_msg_pkg_t; + +/* define the udata serivce struct here, please aline with aliyun side + for the physical sensor, should be same as the dev sensor struct */ +typedef struct _dev_barometer_data_t service_barometer_t; + +typedef struct _service_pedometer_t{ + udata_type_e type; + uint32_t step; +} service_pedometer_t; + +typedef struct _udata_t{ + udata_type_e type; + uint16_t value; +} udata_t; + +typedef struct _udata_pkg_t{ + bool valid; + udata_type_e type; + char payload[DATA_SIZE]; +}udata_pkg_t; + +#endif /*UDATA_OBJ_DESC_H*/ + diff --git a/framework/uData/service_algo/udata_baro_service.c b/framework/uData/service_algo/udata_baro_service.c new file mode 100644 index 0000000000..a1ab8193f9 --- /dev/null +++ b/framework/uData/service_algo/udata_baro_service.c @@ -0,0 +1,55 @@ +/* +* Copyright (C) 2015-2017 Alibaba Group Holding Limited +* +* +* uData service example +*/ + +#include "service_mgr.h" + +int udata_baro_service_ioctl_cb(udata_type_e type, sensor_tag_e tag) +{ + + tag = TAG_DEV_BARO; + return 0; +} + +size_t udata_baro_service_process_cb(sensor_tag_e tag, void* pdata) +{ + barometer_data_t * baro = (barometer_data_t *)pdata; + size_t len = sizeof(barometer_data_t); + + LOG("%s udata_baro_service_cb = (%d), (%d), (%d)\n",uDATA_STR, tag, baro->p, baro->timestamp); + return len; +} + +int udata_baro_service_result(void* pdata){ + return 0; +} + +int udata_baro_service_init(void) +{ + int ret = 0; + uData_service_t * baro; + baro = (uData_service_t *)malloc(sizeof(uData_service_t)); + if(baro == NULL){ + return -1; + } + baro->type = UDATA_SERVICE_BARO; + baro->tag = TAG_DEV_BARO; + baro->config.id = SENSOR_IOCTL_ODR_SET; + baro->config.odr = 2; /* 2Hz */ + baro->config.range = 0; /* no need here, set by the default value in the driver layer */ + baro->service_process_cb = udata_baro_service_process_cb; + baro->service_ioctl_cb = udata_baro_service_ioctl_cb; + ret = uData_service_register(baro); + if(unlikely(ret)){ + free(baro); + LOG("%s %s %s %d\n", uDATA_STR, __func__, ERROR_LINE, __LINE__); + return -1; + } + free(baro); + LOG("%s %s successfully\n", uDATA_STR, __func__); + return 0; +} + diff --git a/framework/uData/service_mgr/service_mgr.c b/framework/uData/service_mgr/service_mgr.c new file mode 100644 index 0000000000..f4404c2d9c --- /dev/null +++ b/framework/uData/service_mgr/service_mgr.c @@ -0,0 +1,335 @@ +/* +* Copyright (C) 2015-2017 Alibaba Group Holding Limited +* +* +* uData service manager part +*/ + +#include "service_mgr.h" +#include +#include +#include +#include "service_algo.h" + +static uData_service_t* g_service_db[UDATA_MAX_CNT]; +static uint32_t g_service_cnt = 0; +static udata_pkg_t g_pkg_buf; + +static uData_service_t* uData_get_service_obj(sensor_tag_e tag) +{ + int index = 0; + for(index = 0; index < g_service_cnt; index++){ + if(g_service_db[index]->tag == tag){ + return g_service_db[index]; + } + } + return NULL; +} + +static int uData_find_service(udata_type_e type) +{ + int index = 0; + for(index = 0; index < g_service_cnt; index++){ + if(g_service_db[index]->type == type){ + return index; + } + } + + return -1; +} + +static int uData_dev_enable(sensor_tag_e tag) +{ + int ret = 0; + ret = abs_data_dev_enable(tag); + if(unlikely(ret)){ + return -1; + } + return 0; +} +int uData_get_report_pkg(void* buf) +{ + if(buf == NULL){ + return -1; + } + + memcpy(buf, &g_pkg_buf, sizeof(udata_pkg_t)); + + LOG("%s %s successfully\n", uDATA_STR, __func__); + return 0; +} +static int uData_install_report_pkg(int index, void* pdata, size_t len) +{ + if(pdata == NULL){ + return -1; + } + /* intall the report data package here */ + memset(&g_pkg_buf, 0, sizeof(udata_pkg_t)); + g_pkg_buf.valid = true; + g_pkg_buf.type = g_service_db[index]->type; + memcpy(g_pkg_buf.payload, pdata, len); + + aos_post_event(EV_UDATA, CODE_UDATA_REPORT_PUBLISH, NULL); + + return 0; +} + +static int uData_get_dev_list(void* pdata) +{ + dev_sensor_full_info_t* sensor; + sensor = aos_malloc(sizeof(dev_sensor_full_info_t)); + if(sensor == NULL){ + return -1; + } + sensor->config.id = SENSOR_IOCTL_GET_SENSOR_LIST; + int ret = abs_data_ioctl(NULL, sensor); + if(unlikely(ret)){ + aos_free(sensor); + return -1; + } + aos_free(sensor); + return 0; +} + + +int uData_service_subscribe(udata_type_e type) +{ + int ret = 0; + int index = 0; + + index = uData_find_service(type); + if(index < 0){ + return -1; + } + + if(g_service_db[index]->type == type){ + if(g_service_db[index]->running != true){ + ret = abs_data_open(g_service_db[index]); + if(unlikely(ret)){ + return -1; + } + } + g_service_db[index]->subscribe = true; + g_service_db[index]->running = true; + } + return 0; +} + +int uData_service_unsubscribe(udata_type_e type) +{ + int ret = 0; + int index = 0; + + index = uData_find_service(type); + if(index < 0) + return -1; + + if(g_service_db[index]->type == type){ + if(g_service_db[index]->running != false){ + ret = abs_data_close(g_service_db[index]->tag); + if(unlikely(ret)){ + return -1; + } + } + g_service_db[index]->subscribe = false; + } + return 0; +} + + +int uData_service_register(uData_service_t* service) +{ + + int ret = 0; + if(service == NULL){ + return -1; + } + g_service_db[g_service_cnt] = (uData_service_t*)aos_malloc(sizeof(uData_service_t)); + if(g_service_db[g_service_cnt] == NULL){ + return -1; + } + + memset(g_service_db[g_service_cnt], 0, sizeof(uData_service_t)); + + /* also can copy the data struct by memcpy here */ + g_service_db[g_service_cnt]->type = service->type; + g_service_db[g_service_cnt]->tag = service->tag; + g_service_db[g_service_cnt]->config.odr = service->config.odr; + g_service_db[g_service_cnt]->config.range = service->config.range; + g_service_db[g_service_cnt]->service_process_cb = service->service_process_cb; + g_service_db[g_service_cnt]->service_ioctl_cb = service->service_ioctl_cb; + + ret = abs_data_open(g_service_db[g_service_cnt]); + if(unlikely(ret)){ + goto error; + } + + /* set the defaul status and no subsrcribed from aliyun side */ + g_service_db[g_service_cnt]->running = true; + g_service_db[g_service_cnt]->subscribe = false; + g_service_cnt++; + + LOG("%s %s successfully\n", uDATA_STR, __func__); + return 0; + +error: + aos_free(g_service_db[g_service_cnt]); + return -1; +} + +int uData_service_unregister(udata_type_e type) +{ + + int index = 0; + int ret = 0; + /* find the matched service, then del it from the list here */ + for(index = 0; index < g_service_cnt; index++){ + if(g_service_db[index]->type == type){ + ret = abs_data_close(g_service_db[index]->tag); + if(unlikely(ret)){ + return -1; + } + memset(g_service_db[index], 0, sizeof(uData_service_t)); + if(g_service_cnt > 0){ + g_service_cnt--; + } + return 0; + } + } + + return -1; +} + +static int uData_service_process(sensor_tag_e tag, void* pdata) +{ + + int ret = 0; + int index = 0; + size_t len = 0; + if(pdata == NULL){ + return -1; + } + + /* find the matched service, then run the registered callback here */ + for(index = 0; index < g_service_cnt; index++){ + if((g_service_db[index]->tag == tag) && (g_service_db[index]->service_process_cb != NULL)){ + len = g_service_db[index]->service_process_cb(tag, pdata); + if((len != 0) && (g_service_db[index]->subscribe == true)){ + ret = uData_install_report_pkg(index, pdata, len); + if(unlikely(ret)){ + return -1; + } + } + } + } + return 0; +} + +int uData_service_ioctl(udata_type_e type, void* parm) +{ + int index = 0; + int ret = 0; + sensor_tag_e tag; + dev_sensor_full_info_t * sensor_config = parm; + if(parm == NULL) + return -1; + + /* find the matched service, then run the registered ioctl callback here */ + for(index = 0; index < g_service_cnt; index++){ + if((g_service_db[index]->type == type) && (g_service_db[index]->service_ioctl_cb != NULL)){ + g_service_db[index]->service_ioctl_cb(type, tag); + /* if get the dev info, then run here */ + ret = abs_data_ioctl(tag, sensor_config); + if(unlikely(ret)){ + return -1; + } + } + } + + LOG("%s %s successfully \n", uDATA_STR, __func__); + return 0; +} + + +static void uData_service_dispatcher(input_event_t *event, void *priv_data) +{ + int ret = 0; + + /* all the cmd of sensorhub will be sent to be handled here; + the dispatcher will asign the new sub task to the fitted model */ + if ((event == NULL)||(event->type != EV_UDATA)) { + return; + } + + uData_service_t* service = uData_get_service_obj(event->value); + if(service == NULL){ + return -1; + } + + switch(event->code){ + case CODE_UDATA_DEV_READ:{ + memset(service->payload, 0, DATA_SIZE); + ret = abs_data_read(event->value, service->payload, DATA_SIZE); + if(unlikely(ret)){ + return -1; + } + }break; + + case CODE_UDATA_SERVICE_PROCESS:{ + uData_service_process(event->value, service->payload); + }break; + + case CODE_UDATA_DEV_IOCTL:{ + abs_data_ioctl(event->value, service->payload); + }break; + + case CODE_UDATA_DEV_OPEN:{ + abs_data_open(priv_data); + }break; + + case CODE_UDATA_DEV_ENABLE:{ + uData_dev_enable(event->value); + }break; + + case CODE_UDATA_DEV_DISABLE:{ + }break; + + case CODE_UDATA_SERVICE_SUBSRIBE:{ + uData_service_subscribe(event->value); + }break; + + case CODE_UDATA_SERVICE_UNSUBSRIBE:{ + uData_service_unsubscribe(event->value); + }break; + + case CODE_UDATA_DEV_CLOSE:{ + abs_data_close(event->value); + }break; + + default:break; + } +} + +int uData_service_init(void) +{ +#ifdef AOS_UDATA_SERVICE_BARO + udata_baro_service_init(); +#endif /* UDATA_SERVICE_BARO */ + + return 0; +} + +int uData_service_mgr_init(void) +{ + int ret = 0; + g_service_cnt = 0; + + ret = aos_register_event_filter(EV_UDATA, uData_service_dispatcher, NULL); + if(unlikely(ret)){ + return -1; + } + + LOG("%s %s successfully \n", uDATA_STR, __func__); + return 0; +} + diff --git a/framework/uData/uData.mk b/framework/uData/uData.mk new file mode 100644 index 0000000000..673275b52e --- /dev/null +++ b/framework/uData/uData.mk @@ -0,0 +1,30 @@ +NAME := uData + +$(NAME)_SOURCES += \ + uData_main.c \ + uData_interface.c \ + service_mgr/service_mgr.c \ + cali_data/calibrated_example_algo.c \ + abs_data_model/abs_data_model.c \ + service_algo/udata_baro_service.c \ + + +$(NAME)_INCLUDES := \ + ./include \ + ../../include/aos \ + ../../include/hal \ + +GLOBAL_INCLUDES += . + +$(NAME)_TYPE := framework + +GLOBAL_DEFINES += AOS_UDATA + +GLOBAL_DEFINES += AOS_UDATA_SERVICE_BARO +#GLOBAL_DEFINES += AOS_UDATA_SERVICE_ALS +#GLOBAL_DEFINES += AOS_UDATA_SERVICE_TEMP +#GLOBAL_DEFINES += AOS_UDATA_SERVICE_HUMI +#GLOBAL_DEFINES += UDATA_SERVICE_PROXIMITY + + + diff --git a/framework/uData/uData_interface.c b/framework/uData/uData_interface.c new file mode 100644 index 0000000000..ea5a1dcf12 --- /dev/null +++ b/framework/uData/uData_interface.c @@ -0,0 +1,56 @@ +/* +* Copyright (C) 2015-2017 Alibaba Group Holding Limited +* +* +* uData api for external part +*/ + +#include +#include +#include +#include +#include +#include "uData_com_desc.h" + +int uData_report_publish(void *pdata) +{ + if(pdata == NULL){ + return -1; + } + uData_get_report_pkg(pdata); + return 0; +} +AOS_EXPORT(int, uData_report_publish, void *); + +int uData_dev_ioctl(udata_t* pkg, uint8_t cmd, void* parm) +{ + /* set the udata_type and related info here */ + //will be supported later +} + +int uData_subscribe(udata_type_e type) +{ + int ret = 0; + ret = uData_service_subscribe(type); + if(unlikely(ret)){ + return -1; + } + + LOG("%s %s successfully\n", uDATA_STR, __func__); + return 0; +} +AOS_EXPORT(int, uData_subscribe, udata_type_e); + +int uData_unsubscribe(udata_type_e type) +{ + int ret = 0; + ret = uData_service_unsubscribe(type); + if(unlikely(ret)){ + return -1; + } + + LOG("%s %s successfully\n", uDATA_STR, __func__); + return 0; +} + + diff --git a/framework/uData/uData_main.c b/framework/uData/uData_main.c new file mode 100644 index 0000000000..201138908a --- /dev/null +++ b/framework/uData/uData_main.c @@ -0,0 +1,41 @@ +/* +* Copyright (C) 2015-2017 Alibaba Group Holding Limited +* +* +* uData main +*/ + +#include "abs_data_model.h" +#include "service_mgr.h" + + +int uData_main(void) +{ + int ret = 0; + + /* NOTE: + * please run the abs data init firstly, then run udata service init */ + + ret = abs_data_model_init(); + if(unlikely(ret)){ + return -1; + } + + ret = uData_service_mgr_init(); + if(unlikely(ret)){ + return -1; + } + + ret = uData_service_init(); + if(unlikely(ret)){ + return -1; + } + + ret = abs_data_cali_init(); + if(unlikely(ret)){ + return -1; + } + LOG("%s %s successfully\n", uDATA_STR, __func__); + return 0; +} + diff --git a/framework/ywss/lib/arm968es/libywss.a b/framework/ywss/lib/arm968es/libywss.a index 7609d6dfcc..83116b26e6 100644 Binary files a/framework/ywss/lib/arm968es/libywss.a and b/framework/ywss/lib/arm968es/libywss.a differ diff --git a/framework/ywss/lib/linux/libywss.a b/framework/ywss/lib/linux/libywss.a index e431c646eb..bc1376d78b 100644 Binary files a/framework/ywss/lib/linux/libywss.a and b/framework/ywss/lib/linux/libywss.a differ diff --git a/framework/ywss/lib/xtensa/libywss.a b/framework/ywss/lib/xtensa/libywss.a index 9da18aed6d..836b446894 100644 Binary files a/framework/ywss/lib/xtensa/libywss.a and b/framework/ywss/lib/xtensa/libywss.a differ diff --git a/include/aos/cli.h b/include/aos/cli.h index 53758f410b..01fe974cac 100644 --- a/include/aos/cli.h +++ b/include/aos/cli.h @@ -10,6 +10,10 @@ #define OUTBUF_SIZE 2048 #define HIS_SIZE 5 +#define CLI_MAX_ARG_NUM 16 +#define CLI_MAX_ONCECMD_NUM 6 + + #ifndef FUNCPTR typedef void (*FUNCPTR)(void); #endif diff --git a/include/aos/kernel.h b/include/aos/kernel.h index f71bf5ab31..7c49e6a323 100644 --- a/include/aos/kernel.h +++ b/include/aos/kernel.h @@ -13,6 +13,7 @@ extern "C" { #endif #define AOS_WAIT_FOREVER 0xffffffffu +#define AOS_NO_WAIT 0x0 #define AOS_DEFAULT_APP_PRI 32 typedef struct { @@ -25,6 +26,7 @@ typedef aos_hdl_t aos_sem_t; typedef aos_hdl_t aos_queue_t; typedef aos_hdl_t aos_timer_t; typedef aos_hdl_t aos_work_t; +typedef aos_hdl_t aos_event_t; typedef struct { void *hdl; @@ -225,6 +227,64 @@ int aos_sem_is_valid(aos_sem_t *sem); */ void aos_sem_signal_all(aos_sem_t *sem); +/** + * This function will create an event with an initialization flag set. + * This function should not be called from interrupt context. + * + * @param[in] event event object pointer. + * @param[in] flags initialization flag set(provided by caller). + * + * @return 0: success. + */ + +int aos_event_new(aos_event_t *event, unsigned int flags); + +/** + * This function will free an event. + * This function shoud not be called from interrupt context. + * + * @param[in] event memory refered by hdl pointer in event will be freed. + * + * @return N/A. + */ + +void aos_event_free(aos_event_t *event); + +/** + * This function will try to get flag set from given event, if the request flag + * set is satisfied, it will return immediately, if the request flag set is not + * satisfied with timeout(RHINO_WAIT_FOREVER,0xFFFFFFFF), the caller task will be + * pended on event until the flag is satisfied, if the request flag is not + * satisfied with timeout(RHINO_NO_WAIT, 0x0), it will also return immediately. + * Note, this function should not be called from interrupt context because it has + * possible to lead context switch and an interrupt has no TCB to save context. + * + * @param[in] event event object pointer. + * @param[in] flags request flag set. + * @param[in] opt operation type, such as AND,OR,AND_CLEAR,OR_CLEAR. + * @param[out] actl_flags the internal flags value hold by event. + * @param[in] flags request flag set. + * @param[in] timeout max wait time in millisecond. + * + * @return 0: success. + */ + +int aos_event_get(aos_event_t *event, unsigned int flags, unsigned char opt, + unsigned int *actl_flags, unsigned int timeout); + +/** +* This function will set flag set to given event, and it will check if any task +* which is pending on the event should be waken up. +* +* @param[in] event event object pointer. +* @param[in] flags flag set to be set into event. +* @param[in] opt operation type, such as AND,OR. +* +* @return 0: success. +*/ + +int aos_event_set(aos_event_t *event, unsigned int flags, unsigned char opt); + /** * This function will create a queue. * @@ -235,6 +295,7 @@ void aos_sem_signal_all(aos_sem_t *sem); * * @return 0: success. */ + int aos_queue_new(aos_queue_t *queue, void *buf, unsigned int size, int max_msg); /** diff --git a/include/aos/list.h b/include/aos/list.h index ba1a33a425..50a047f329 100644 --- a/include/aos/list.h +++ b/include/aos/list.h @@ -182,12 +182,17 @@ static inline int dlist_empty(const dlist_t *head) * * @param[in] queue the head for your list. */ -#define dlist_entry_number(queue) ({ \ - int num; \ - dlist_t *cur = queue; \ - for (num=0;cur->next != queue;cur=cur->next, num++); \ - num; \ -}) +static inline int dlist_entry_number(dlist_t *queue) +{ + int num; + dlist_t *cur = queue; + for (num=0;cur->next != queue;cur=cur->next, num++) + ; + + return num; +} + + /* * Initialise the list. @@ -279,7 +284,7 @@ static inline void slist_init(slist_t *head) * * @param[in] name the list to be initialized. */ -#define AOS_SLIST_HEAD_INIT(name) { } +#define AOS_SLIST_HEAD_INIT(name) {0} /* * Initialise the list. @@ -295,9 +300,9 @@ static inline void slist_init(slist_t *head) * @param[in] type the type of the struct this is embedded in. * @param[in] member the name of the slist_t within the struct. */ -#define slist_entry(addr, type, member) ({ \ - addr ? (type *)((long)addr - aos_offsetof(type, member)) : (type *)addr; \ -}) +#define slist_entry(addr, type, member) ( \ + addr ? (type *)((long)addr - aos_offsetof(type, member)) : (type *)addr \ +) /* * Get the first element from a list. @@ -314,12 +319,16 @@ static inline void slist_init(slist_t *head) * * @param[in] queue the head for your list. */ -#define slist_entry_number(queue) ({ \ - int num; \ - slist_t *cur = queue; \ - for (num=0;cur->next;cur=cur->next, num++); \ - num; \ -}) +static inline int slist_entry_number(slist_t *queue) +{ + int num; + slist_t *cur = queue; + for (num=0;cur->next;cur=cur->next, num++) + ; + + return num; +} + #ifdef __cplusplus } diff --git a/include/aos/types.h b/include/aos/types.h index 7b43de2b7f..ee3de3d6cd 100644 --- a/include/aos/types.h +++ b/include/aos/types.h @@ -31,21 +31,21 @@ struct pollfd { * define the AOS_EXPORT macro* */ -#define AOS_EXPORT(ret, fun, argstype...) +#define AOS_EXPORT(ret, fun, ...) #endif #ifndef AOS_COMPONENT_INIT /** * define the AOS_COMPONENT_INIT macro */ -#define AOS_COMPONENT_INIT(fun, args...) +#define AOS_COMPONENT_INIT(fun, ...) #endif #ifndef AOS_TESTCASE /** * define the AOS_TESTCASE macro */ -#define AOS_TESTCASE(fun, args...) +#define AOS_TESTCASE(fun, ...) #endif #endif /* AOS_TYPES_H */ diff --git a/include/aos/uData.h b/include/aos/uData.h new file mode 100644 index 0000000000..df99a7194d --- /dev/null +++ b/include/aos/uData.h @@ -0,0 +1,19 @@ + +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#ifndef UDATA_H +#define UDATA_H + +#include "../../framework/uData/include/uData_com_desc.h" + + +int uData_report_publish(void *pdata); +int uData_dev_ioctl(udata_t* pkg, uint8_t cmd, long long parm); +int uData_subscribe(udata_type_e type); +int uData_unsubscribe(udata_type_e type); + + +#endif /*UDATA_H*/ + diff --git a/include/aos/yloop.h b/include/aos/yloop.h index 6d0050e122..43a298a6d9 100644 --- a/include/aos/yloop.h +++ b/include/aos/yloop.h @@ -45,6 +45,21 @@ extern "C" { /* user app start 0x1000 - 0x7fff */ #define EV_USER 0x1000 +/** uData event */ +#define EV_UDATA 0x0004 +#define CODE_UDATA_DEV_READ 1 +#define CODE_UDATA_DEV_IOCTL 2 +#define CODE_UDATA_DEV_OPEN 3 +#define CODE_UDATA_DEV_CLOSE 4 +#define CODE_UDATA_DEV_ENABLE 5 +#define CODE_UDATA_DEV_DISABLE 6 +#define CODE_UDATA_SERVICE_SUBSRIBE 7 /* for external component */ +#define CODE_UDATA_SERVICE_UNSUBSRIBE 8 /* for external component */ +#define CODE_UDATA_SERVICE_PROCESS 9 +#define CODE_UDATA_SERVICE_IOCTL 10 +#define CODE_UDATA_REPORT_PUBLISH 11 + + #endif typedef struct { diff --git a/include/hal/sensor.h b/include/hal/sensor.h index 1b55d0a57f..abe629f4fa 100644 --- a/include/hal/sensor.h +++ b/include/hal/sensor.h @@ -1,101 +1,293 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - - -#ifndef HAL_SENSOR_H -#define HAL_SENSOR_H - -#define SENSOR_TYPE_TEMPERATURE 1 - -typedef struct hal_sensor_module_s hal_sensor_module_t; - -typedef int sensor_type; - -typedef struct { - sensor_type type; - const char *sensor_name; -} sensor_node_t; - -struct hal_sensor_module_s { - hal_module_base_t base; - - /* Link to HW */ - int (*init)(hal_sensor_module_t *m, void *something); - int (*get_sensor_list)(hal_sensor_module_t *m, sensor_node_t const **list); - int (*enable)(hal_sensor_module_t *m, sensor_type type); - int (*disable)(hal_sensor_module_t *m, sensor_type type); - int (*read)(hal_sensor_module_t *m, sensor_type type, char *buf, int buf_size); -}; - -/** - * Arch register a new module before HAL startup - */ -void hal_sensor_register_module(hal_sensor_module_t *module); - -/** - * HAL sensor init. - * - * @return 0 if init success, -1 if fail - */ -int hal_sensor_init(void); - -/** - * enbale sensor with type - * - * @param[in] m Refer the sensor module which will be used,default module will be used if value is NULL - * @param[in] list The list of the sensor which will be return - * - * @return negative value indicates an error - */ -int hal_sensor_get_sensor_list(hal_sensor_module_t *m, sensor_node_t const **list); - -/** - * enable sensor with type - * - * @param[in] m Refer the sensor module which will be used,default module will be used if value is NULL - * @param[in] type The type of the sensor which must be supplied - * - * @return 0 if enable ok, negative value indicates an error - */ -int hal_sensor_enable(hal_sensor_module_t *m, sensor_type type); - -/** - * disable sensor with type - * - * @param[in] m Refer the sensor module which will be used,default module will be used if value is NULL - * @param[in] type The type of the sensor which must be supplied - * - * @return 0 if disable ok, negative value indicates an error - */ -int hal_sensor_disable(hal_sensor_module_t *m, sensor_type type); - -/** - * read sensor data when enable sensor - * - * @param[in] m Refer the sensor module which will be used,default module will be used if value is NULL - * @param[in] type The type of the sensor which must be supplied - * @param[in] buf receive buf for sensor data - * @param[in] buf_size the size buf of input - * - * @return 0 if read ok, negative value indicates an error - */ -int hal_sensor_read(hal_sensor_module_t *m, sensor_type type, char *buf, int buf_size); - -/** - * Get the default sensor module - * - * @return return the first registered sensor module ,which is the head of module list - */ -hal_sensor_module_t *hal_sensor_get_default_module(void); - -/** - * Get the next sensor HAL - * The system may have more than 1 sensor HAL instances. - * - * @return Instance pointer or NULL - */ -hal_sensor_module_t *hal_sensor_get_next_module(hal_sensor_module_t *m); - -#endif /* HAL_SENSOR_H */ - +/* +* Copyright (C) 2015-2017 Alibaba Group Holding Limited +* +* sensor hal +*/ + +#ifndef HAL_SENSOR_H +#define HAL_SENSOR_H + +#include +#include +#include +#include +#include +#include "hal/soc/soc.h" +#include "hal/soc/gpio.h" +#include "hal/soc/i2c.h" + + +#define I2C_REG_LEN 1 +#define I2C_DATA_LEN 1 +#define I2C_OP_RETRIES AOS_WAIT_FOREVER + +/* ioctl cmd list for sensor */ +#define SENSOR_IOCTL_ODR_SET (0x01<<0) +#define SENSOR_IOCTL_RANGE_SET (0x01<<1) +#define SENSOR_IOCTL_GET_INFO (0x01<<2) +#define SENSOR_IOCTL_BIST_PROCESS (0x01<<3) +#define SENSOR_IOCTL_WHO_AM_I (0x01<<4) +#define SENSOR_IOCTL_SET_POWER (0x01<<5) +#define SENSOR_IOCTL_GET_SENSOR_LIST (0x01<<6) + +#ifndef likely +#define likely(x) __builtin_expect(!!(x), 1) +#endif +#ifndef unlikely +#define unlikely(x) __builtin_expect(!!(x), 0) +#endif + +/* Physical generic sensor data defs generic structs here*/ +#define DATA_AXIS_X 0 +#define DATA_AXIS_Y 1 +#define DATA_AXIS_Z 2 + +#define dev_acc_path "/dev/acc" +#define dev_mag_path "/dev/mag" +#define dev_gyro_path "/dev/gyro" +#define dev_als_path "/dev/als" +#define dev_ps_path "/dev/ps" +#define dev_baro_path "/dev/baro" +#define dev_temp_path "/dev/temp" +#define dev_uv_path "/dev/uv" +#define dev_humi_path "/dev/humi" +#define dev_hall_path "/dev/hall" +#define dev_hr_path "/dev/hr" +#define sensor_node_path "/dev/sensor" + +#define SENSOR_STR "sensor: " /* sensor debug header */ +#define ERROR_LINE "error on line is " + +#define ACCELEROMETER_UNIT_FACTOR 1000 //mg +#define MAGNETOMETER_UNIT_FACTOR 1000 //mGauss +#define GYROSCOPE_UNIT_FACTOR 1000000 //uDPS + +/* add the new sensor type into the last postion */ +typedef enum{ + TAG_DEV_ACC = 0, /* Accelerometer */ + TAG_DEV_MAG, /* Magnetometer */ + TAG_DEV_GYRO, /* Gyroscope */ + TAG_DEV_ALS, /* Ambient light sensor */ + TAG_DEV_PS, /* Proximity */ + TAG_DEV_BARO, /* Barometer */ + TAG_DEV_TEMP, /* Temperature */ + TAG_DEV_UV, /* Ultraviolet */ + TAG_DEV_HUMI, /* Humidity */ + TAG_DEV_HALL, /* HALL */ + TAG_DEV_HR, /* Heart Rate */ + TAG_DEV_SENSOR_NUM_MAX, +} sensor_tag_e; + + +typedef enum { + DEV_SENSOR_VENDOR_STM = 0, + DEV_SENSOR_VENDOR_SEMTECH, + DEV_SENSOR_VENDOR_AKM, + DEV_SENSOR_VENDOR_CAPELLA, + DEV_SENSOR_VENDOR_INVENSENSE, + DEV_SENSOR_VENDOR_ROHM, + DEV_SENSOR_VENDOR_BOSCH, + DEV_SENSOR_VENDOR_KIONIX, + DEV_SENSOR_VENDOR_LITEON, + DEV_SENSOR_VENDOR_AMS, + DEV_SENSOR_VENDOR_CNT_MAXIM, +} vendor_id_e; + +typedef enum { + I2C_PORT, + SPI_PORT, + I2S_PORT, + UART_PORT, +} dev_io_port_e; + +typedef enum { + DEV_POWER_OFF = 0, + DEV_POWER_ON, + DEV_SLEEP, + DEV_SUSPEND, + DEV_DEEP_SUSPEND, +} dev_power_mode_e; + +typedef enum { + DEV_HEALTH_GOOD, + DEV_HEALTH_SICK, +} dev_health_state_e; + + +typedef enum { + DEV_POLLING = 0, + DEV_INT, + DEV_DATA_READY, + DEV_FIFO, +} work_mode_e; + +typedef enum { + mg = 0, + uGauss, + udps, + lux, + cm, + pa, + pecent, + bpm, +} value_unit_e; + +typedef struct _dev_accel_data_t { + uint64_t timestamp; + int32_t data[3]; +}accel_data_t; + +typedef struct _dev_gyro_data_t { + uint64_t timestamp; + int32_t data[3]; +}gyro_data_t; + +typedef struct _dev_mag_data_t { + uint64_t timestamp; + int32_t data[3]; +}mag_data_t; + +typedef struct _dev_barometer_data_t{ + uint64_t timestamp; + uint32_t p; +}barometer_data_t; + +typedef struct _dev_temperature_data_t{ + uint64_t timestamp; + int32_t t; +}temperature_data_t; + +typedef struct _dev_humidity_data_t{ + uint64_t timestamp; + uint32_t h; +}humidity_data_t; + +typedef struct _dev_als_data_t{ + uint64_t timestamp; + uint32_t lux; +}als_data_t; + +typedef struct _dev_uv_data_t{ + uint64_t timestamp; + uint16_t uvi; +}uv_data_t; + +typedef struct _dev_proximity_data_t{ + uint64_t timestamp; + uint32_t present; +}proximity_data_t; + +typedef struct _dev_hall_data_t { + uint64_t timestamp; + uint8_t hall_level; +}hall_data_t; + +typedef struct _dev_rgb_data_t{ + uint64_t timestamp; + uint32_t data[3]; +}rgb_data_t; + +typedef struct _dev_ir_data_t{ + uint64_t timestamp; + uint32_t ir; +}ir_data_t; + +typedef struct _dev_ecg_data_t{ + uint64_t timestamp; + int16_t raw_data; +}ecg_data_t; + +typedef struct _dev_heart_rate_data_t { + uint64_t timestamp; + uint8_t hear_rate; +}heart_rate_data_t; + +typedef struct _dev_blood_pressure_data_t { + uint64_t timestamp; + uint16_t systolic; + uint16_t diastolic; +}blood_pressure_t; + +typedef struct _dev_sensor_config_t { + uint8_t id; + uint32_t range; + uint32_t odr; +}dev_sensor_config_t; + +typedef struct _sensor_list_t{ + uint32_t cnt; + uint8_t list[TAG_DEV_SENSOR_NUM_MAX]; +}sensor_list_t; +#if defined ( __GNUC__ ) +typedef struct _dev_sensor_info_t { + vendor_id_e vendor; + char* model; + value_unit_e unit; + uint32_t range_max; + uint32_t range_min; + dev_health_state_e health; + //sensor_list_t list; +}dev_sensor_info_t; + +typedef struct _dev_sensor_full_info_t { + dev_sensor_info_t info; + dev_sensor_config_t config; +}dev_sensor_full_info_t; + +typedef struct _dev_sensor_data_t { + uint64_t timestamp; + int32_t data[3]; +}dev_sensor_data_t; + +typedef struct _dev_sensor_pkg_t { + sensor_tag_e tag; + union{ + dev_sensor_info_t info; + dev_sensor_config_t config; + dev_sensor_data_t data; + }allocator; +}dev_sensor_pkg_t; + +typedef struct _sensor_obj_t { + char* path; + sensor_tag_e tag; + dev_io_port_e io_port; + //uint8_t i2c_addr; + work_mode_e mode; + dev_power_mode_e power; + gpio_dev_t gpio; + dev_sensor_full_info_t info; + i2c_dev_t* bus; + int (*open)(void); + int (*close)(void); + int (*read)(void *, size_t); + int (*write)(const void *buf, size_t len); + int (*ioctl)(int cmd, unsigned long arg); + void(*irq_handle)(void); +}sensor_obj_t; + +#endif +typedef struct _sensor_node_t{ + sensor_tag_e tag; + char *path; + int fd; +} sensor_node_t; + +typedef enum{ + ACC_RANGE_2G, + ACC_RANGE_4G, + ACC_RANGE_8G, + ACC_RANGE_16G, +}acc_range_e; + +typedef enum{ + GYRO_RANGE_125DPS, + GYRO_RANGE_250DPS, + GYRO_RANGE_500DPS, + GYRO_RANGE_1000DPS, + GYRO_RANGE_2000DPS +}gyro_range_e; + + +#endif /* HAL_SENSOR_H */ + diff --git a/include/hal/soc/atcmd.h b/include/hal/soc/atcmd.h index 6f63f871c6..ce2da64dd5 100644 --- a/include/hal/soc/atcmd.h +++ b/include/hal/soc/atcmd.h @@ -48,6 +48,7 @@ #ifdef AOS_ATCMD #include +#include #endif #endif // #ifndef _ATCMD_H_ diff --git a/include/hal/soc/gpio.h b/include/hal/soc/gpio.h old mode 100644 new mode 100755 index ae2f19c11c..7f2725cf0a --- a/include/hal/soc/gpio.h +++ b/include/hal/soc/gpio.h @@ -9,6 +9,8 @@ * Pin configuration */ typedef enum { + ANALOG_MODE, /* Used as a function pin, input and output analog */ + IRQ_MODE, /* Used to trigger interrupt */ INPUT_PULL_UP, /* Input with an internal pull-up resistor - use with devices that actively drive the signal low - e.g. button connected to ground */ INPUT_PULL_DOWN, /* Input with an internal pull-down resistor - use with devices @@ -24,6 +26,15 @@ typedef enum { can be connected to other open-drain/open-collector outputs. */ } gpio_config_t; +/* + * GPIO dev struct + */ +typedef struct { + uint8_t port; /* gpio port */ + gpio_config_t config; /* gpio config */ + void *priv; /* priv data */ +} gpio_dev_t; + /* * GPIO interrupt trigger */ @@ -33,12 +44,6 @@ typedef enum { IRQ_TRIGGER_BOTH_EDGES = IRQ_TRIGGER_RISING_EDGE | IRQ_TRIGGER_FALLING_EDGE, } gpio_irq_trigger_t; -typedef struct { - uint8_t port; /* gpio port */ - gpio_config_t config; /* gpio config */ - void *priv; /* priv data */ -} gpio_dev_t; - /* * GPIO interrupt callback handler */ diff --git a/include/hal/soc/i2c.h b/include/hal/soc/i2c.h old mode 100644 new mode 100755 index f2afbf6af1..8880206cb5 --- a/include/hal/soc/i2c.h +++ b/include/hal/soc/i2c.h @@ -73,7 +73,7 @@ int32_t hal_i2c_master_recv(i2c_dev_t *i2c, uint16_t dev_addr, uint8_t *data, * * @return 0 : on success, EIO : if an error occurred during initialisation */ -int32_t hal_i2C_slave_send(i2c_dev_t *i2c, const uint8_t *data, uint16_t size, uint32_t timeout); +int32_t hal_i2c_slave_send(i2c_dev_t *i2c, const uint8_t *data, uint16_t size, uint32_t timeout); /** * I2c slave receive diff --git a/include/hal/soc/spi.h b/include/hal/soc/spi.h index 76372c4c90..36b7557390 100644 --- a/include/hal/soc/spi.h +++ b/include/hal/soc/spi.h @@ -5,9 +5,12 @@ #ifndef HAL_SPI_H #define HAL_SPI_H +#define HAL_SPI_MODE_MASTER 1 /* spi communication is master mode */ +#define HAL_SPI_MODE_SLAVE 2 /* spi communication is slave mode */ + typedef struct { - uint32_t mode; - uint32_t freq; + uint32_t mode; /* spi communication mode */ + uint32_t freq; /* communication frequency Hz */ } spi_config_t; typedef struct { diff --git a/include/hal/soc/timer.h b/include/hal/soc/timer.h index dc4d202359..855dff7a96 100644 --- a/include/hal/soc/timer.h +++ b/include/hal/soc/timer.h @@ -5,14 +5,23 @@ #ifndef HAL_TIMER_H #define HAL_TIMER_H +#define TIMER_RELOAD_AUTO 1 /* timer reload automatic */ +#define TIMER_RELOAD_MANU 2 /* timer reload manual */ + typedef void (*hal_timer_cb_t)(void *arg); typedef struct { - int8_t ch; - void *priv; + uint32_t period; + uint8_t reload_mode; hal_timer_cb_t cb; void *arg; -} hal_timer_t; +} timer_config_t; + +typedef struct { + int8_t port; /* timer port */ + timer_config_t config; /* timer config */ + void *priv; /* priv data */ +} timer_dev_t; /** * init a hardware timer @@ -24,16 +33,14 @@ typedef struct { * @param[in] ch timer channel * @param[in] arg passed to cb */ -void hal_timer_init(hal_timer_t *tmr, unsigned int period, - unsigned char auto_reload, unsigned char ch, - hal_timer_cb_t cb, void *arg); +int32_t hal_timer_init(timer_dev_t *tim); /** - * init a hardware timer + * start a hardware timer * * @return 0 == success, EIO == failure */ -int32_t hal_timer_start(hal_timer_t *tmr); +int32_t hal_timer_start(timer_dev_t *tim); /** * stop a hardware timer @@ -42,7 +49,7 @@ int32_t hal_timer_start(hal_timer_t *tmr); * @param[in] cb callback to be triggered after useconds * @param[in] arg passed to cb */ -void hal_timer_stop(hal_timer_t *tmr); +void hal_timer_stop(timer_dev_t *tim); /** * De-initialises an TIMER interface, Turns off an TIMER hardware interface @@ -51,7 +58,7 @@ void hal_timer_stop(hal_timer_t *tmr); * * @return 0 : on success, EIO : if an error occurred with any step */ -int32_t hal_timer_finalize(hal_timer_t *timer); +int32_t hal_timer_finalize(timer_dev_t *tim); #endif /* HAL_TIMER_H*/ diff --git a/include/hal/soc/uart.h b/include/hal/soc/uart.h old mode 100644 new mode 100755 index 5148ed4703..9bce7de8a2 --- a/include/hal/soc/uart.h +++ b/include/hal/soc/uart.h @@ -21,7 +21,7 @@ typedef enum { */ typedef enum { STOP_BITS_1, - STOP_BITS_2, + STOP_BITS_2 } hal_uart_stop_bits_t; /* @@ -40,9 +40,18 @@ typedef enum { typedef enum { NO_PARITY, ODD_PARITY, - EVEN_PARITY, + EVEN_PARITY } hal_uart_parity_t; +/* + * UART mode + */ +typedef enum { + MODE_TX, + MODE_RX, + MODE_TX_RX +} hal_uart_mode_t; + /* * UART configuration */ @@ -52,6 +61,7 @@ typedef struct { hal_uart_parity_t parity; hal_uart_stop_bits_t stop_bits; hal_uart_flow_control_t flow_control; + hal_uart_mode_t mode; } uart_config_t; typedef struct { diff --git a/include/hal/wifi.h b/include/hal/wifi.h index 7ecf63507c..7915b9fe1a 100644 --- a/include/hal/wifi.h +++ b/include/hal/wifi.h @@ -174,13 +174,25 @@ struct hal_wifi_module_s { int (*suspend_station)(hal_wifi_module_t *m); int (*suspend_soft_ap)(hal_wifi_module_t *m); int (*set_channel)(hal_wifi_module_t *m, int ch); + int (*get_channel)(hal_wifi_module_t *m); + int (*get_channel_list)(hal_wifi_module_t *m, const uint8_t **chnlist); void (*start_monitor)(hal_wifi_module_t *m); void (*stop_monitor)(hal_wifi_module_t *m); void (*register_monitor_cb)(hal_wifi_module_t *m, monitor_data_cb_t fn); void (*register_wlan_mgnt_monitor_cb)(hal_wifi_module_t *m, monitor_data_cb_t fn); int (*wlan_send_80211_raw_frame)(hal_wifi_module_t *m, uint8_t *buf, int len); + + /* debug related */ void (*start_debug_mode)(hal_wifi_module_t *m); void (*stop_debug_mode)(hal_wifi_module_t *m); + + /* mesh related */ + void (*mesh_register_cb)(hal_wifi_module_t *m, monitor_data_cb_t fn); + void (*mesh_set_bssid)(hal_wifi_module_t *m, const uint8_t *mac); + int (*mesh_enable)(hal_wifi_module_t *m); + int (*mesh_disable)(hal_wifi_module_t *m); + int (*mesh_radio_sleep)(hal_wifi_module_t *m); + int (*mesh_radio_wakeup)(hal_wifi_module_t *m); }; /** @@ -339,6 +351,25 @@ int hal_wifi_suspend_soft_ap(hal_wifi_module_t *m); */ int hal_wifi_set_channel(hal_wifi_module_t *m, int ch); +/** + * Get the channel of the wifi instance. + * + * @param[in] m the wifi instance, NULL if default. + * + * @return -1 on failure, otherwise current channel number. + */ +int hal_wifi_get_channel(hal_wifi_module_t *m); + +/** + * Get the channel list of the wifi instance. + * + * @param[in] m the wifi instance, NULL if default. + * @param[out] chnlist channel list in array + * + * @return -1 on failure, otherwise number of available channels. + */ +int hal_wifi_get_channel_list(hal_wifi_module_t *m, const uint8_t **chnlist); + /** * Start the monitor mode of the wifi instance. * @@ -361,6 +392,23 @@ void hal_wifi_stop_wifi_monitor(hal_wifi_module_t *m); */ void hal_wifi_register_monitor_cb(hal_wifi_module_t *m, monitor_data_cb_t fn); +/** + * Register management frame montior callback on the wifi instance. + * + * @param[in] m the wifi instance, NULL if default. + * @param[in] fn the callback function. + */ +void hal_wlan_register_mgnt_monitor_cb(hal_wifi_module_t *m, monitor_data_cb_t fn); + +/** + * Send 802.11 raw frame + * + * @param[in] m the wifi instance, NULL if default. + * @param[in] buf frame buffer. + * @param[in] len length of frame buffer. + */ +int hal_wlan_send_80211_raw_frame(hal_wifi_module_t *m, uint8_t *buf, int len); + /** * Start debug mode of the wifi instance. * @@ -386,5 +434,12 @@ void hal_wifi_stop_debug_mode(hal_wifi_module_t *m); */ void hal_wifi_install_event(hal_wifi_module_t *m, const hal_wifi_event_cb_t *cb); +/** + * Regster a wifi instance to the uMesh + * + * @param[in] m the wifi instance. + */ +void hal_umesh_register_wifi(hal_wifi_module_t *m); + #endif /* HAL_WIFI_H */ diff --git a/kernel/hal/wifi.c b/kernel/hal/wifi.c index 7fbd8ab65c..a01f279f68 100644 --- a/kernel/hal/wifi.c +++ b/kernel/hal/wifi.c @@ -193,6 +193,26 @@ int hal_wifi_set_channel(hal_wifi_module_t *m, int ch) } AOS_EXPORT(int, hal_wifi_set_channel, hal_wifi_module_t *, int); +int hal_wifi_get_channel(hal_wifi_module_t *m) +{ + if (m == NULL) { + m = hal_wifi_get_default_module(); + } + + return m->get_channel(m); +} +AOS_EXPORT(int, hal_wifi_get_channel, hal_wifi_module_t *); + +int hal_wifi_get_channel_list(hal_wifi_module_t *m, const uint8_t **chnlist) +{ + if (m == NULL) { + m = hal_wifi_get_default_module(); + } + + return m->get_channel_list(m, chnlist); +} +AOS_EXPORT(int, hal_wifi_get_channel_list, hal_wifi_module_t *, const uint8_t **); + void hal_wifi_start_wifi_monitor(hal_wifi_module_t *m) { if (m == NULL) { diff --git a/kernel/init/aos_init.c b/kernel/init/aos_init.c index b11cc84de5..30e6d72f5b 100644 --- a/kernel/init/aos_init.c +++ b/kernel/init/aos_init.c @@ -86,6 +86,9 @@ int aos_kernel_init(kinit_t *kinit) ota_service_init(); #endif +#ifdef AOS_SENSOR + sensor_init(); +#endif // auto_component generated by the compiler system, now gcc support #if defined (__GNUC__) aos_components_init(); diff --git a/kernel/protocols/bluetooth/bluetooth.mk b/kernel/protocols/bluetooth/bluetooth.mk index e0343e38ef..75b8bc8bb3 100644 --- a/kernel/protocols/bluetooth/bluetooth.mk +++ b/kernel/protocols/bluetooth/bluetooth.mk @@ -1,3 +1,56 @@ -NAME := btprotocol +NAME := bluetooth -GLOBAL_INCLUDES += ./include/ +$(NAME)_TYPE := kernel +GLOBAL_INCLUDES += include \ + include/drivers \ + port/include + +$(NAME)_INCLUDES += core/tinycrypt/include \ + core/include \ + profile \ + ../../rhino/core/include + +$(NAME)_COMPONENTS += yloop + +$(NAME)_SOURCES := core/atomic_c.c \ + core/buf.c \ + host/uuid.c \ + host/hci_core.c \ + host/log.c \ + core/tinycrypt/source/utils.c \ + core/tinycrypt/source/sha256.c \ + core/tinycrypt/source/hmac.c \ + core/tinycrypt/source/hmac_prng.c \ + host/conn.c \ + host/l2cap.c \ + host/att.c \ + host/gatt.c \ + host/smp_null.c \ + core/work.c \ + port/rhino_port.c + +ifeq ($(COMPILER),) +$(NAME)_CFLAGS += -Wall +else ifeq ($(COMPILER),gcc) +$(NAME)_CFLAGS += -Wall +endif + +GLOBAL_DEFINES += CONFIG_AOS_BLUETOOTH +GLOBAL_DEFINES += CONFIG_BLUETOOTH +GLOBAL_DEFINES += CONFIG_AOS_RHINO +GLOBAL_DEFINES += CONFIG_BLUETOOTH_PERIPHERAL + +## BLE debug log general control macro (Note: still to be affected by DEBUG) +## Enable below macros if BLE stack debug needed +#GLOBAL_DEFINES += CONFIG_BLUETOOTH_DEBUG_LOG +#GLOBAL_DEFINES += CONFIG_BLUETOOTH_DEBUG + +## BLE subsystem debug log control macro +## Enable below macros if component-specific debug needed +#GLOBAL_DEFINES += CONFIG_BLUETOOTH_DEBUG_L2CAP +#GLOBAL_DEFINES += CONFIG_BLUETOOTH_DEBUG_CONN +#GLOBAL_DEFINES += CONFIG_BLUETOOTH_DEBUG_ATT +#GLOBAL_DEFINES += CONFIG_BLUETOOTH_DEBUG_GATT +#GLOBAL_DEFINES += CONFIG_BLUETOOTH_DEBUG_HCI_DRIVER +#GLOBAL_DEFINES += CONFIG_BLUETOOTH_DEBUG_HCI_CORE +#GLOBAL_DEFINES += CONFIG_BLUETOOTH_DEBUG_CORE diff --git a/kernel/protocols/bluetooth/core/atomic_c.c b/kernel/protocols/bluetooth/core/atomic_c.c new file mode 100644 index 0000000000..78bb4efac6 --- /dev/null +++ b/kernel/protocols/bluetooth/core/atomic_c.c @@ -0,0 +1,351 @@ +/* + * Copyright (c) 2016 Intel Corporation + * Copyright (c) 2011-2014 Wind River Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file Atomic ops in pure C + * + * This module provides the atomic operators for processors + * which do not support native atomic operations. + * + * The atomic operations are guaranteed to be atomic with respect + * to interrupt service routines, and to operations performed by peer + * processors. + * + * (originally from x86's atomic.c) + */ + +#include +#include + +/** + * + * @brief Atomic compare-and-set primitive + * + * This routine provides the compare-and-set operator. If the original value at + * equals , then is stored at and the + * function returns 1. + * + * If the original value at does not equal , then the store + * is not done and the function returns 0. + * + * The reading of the original value at , the comparison, + * and the write of the new value (if it occurs) all happen atomically with + * respect to both interrupts and accesses of other processors to . + * + * @param target address to be tested + * @param old_value value to compare against + * @param new_value value to compare against + * @return Returns 1 if is written, 0 otherwise. + */ +int atomic_cas(atomic_t *target, atomic_val_t old_value, + atomic_val_t new_value) +{ + unsigned int key; + int ret = 0; + + key = irq_lock(); + + if (*target == old_value) { + *target = new_value; + ret = 1; + } + + irq_unlock(key); + + return ret; +} + +/** + * + * @brief Atomic addition primitive + * + * This routine provides the atomic addition operator. The is + * atomically added to the value at , placing the result at , + * and the old value from is returned. + * + * @param target memory location to add to + * @param value the value to add + * + * @return The previous value from + */ +atomic_val_t atomic_add(atomic_t *target, atomic_val_t value) +{ + unsigned int key; + atomic_val_t ret; + + key = irq_lock(); + + ret = *target; + *target += value; + + irq_unlock(key); + + return ret; +} + +/** + * + * @brief Atomic subtraction primitive + * + * This routine provides the atomic subtraction operator. The is + * atomically subtracted from the value at , placing the result at + * , and the old value from is returned. + * + * @param target the memory location to subtract from + * @param value the value to subtract + * + * @return The previous value from + */ +atomic_val_t atomic_sub(atomic_t *target, atomic_val_t value) +{ + unsigned int key; + atomic_val_t ret; + + key = irq_lock(); + + ret = *target; + *target -= value; + + irq_unlock(key); + + return ret; +} + +/** + * + * @brief Atomic increment primitive + * + * @param target memory location to increment + * + * This routine provides the atomic increment operator. The value at + * is atomically incremented by 1, and the old value from is returned. + * + * @return The value from before the increment + */ +atomic_val_t atomic_inc(atomic_t *target) +{ + unsigned int key; + atomic_val_t ret; + + key = irq_lock(); + + ret = *target; + (*target)++; + + irq_unlock(key); + + return ret; +} + +/** + * + * @brief Atomic decrement primitive + * + * @param target memory location to decrement + * + * This routine provides the atomic decrement operator. The value at + * is atomically decremented by 1, and the old value from is returned. + * + * @return The value from prior to the decrement + */ +atomic_val_t atomic_dec(atomic_t *target) +{ + unsigned int key; + atomic_val_t ret; + + key = irq_lock(); + + ret = *target; + (*target)--; + + irq_unlock(key); + + return ret; +} + +/** + * + * @brief Atomic get primitive + * + * @param target memory location to read from + * + * This routine provides the atomic get primitive to atomically read + * a value from . It simply does an ordinary load. Note that + * is expected to be aligned to a 4-byte boundary. + * + * @return The value read from + */ +atomic_val_t atomic_get(const atomic_t *target) +{ + return *target; +} + +/** + * + * @brief Atomic get-and-set primitive + * + * This routine provides the atomic set operator. The is atomically + * written at and the previous value at is returned. + * + * @param target the memory location to write to + * @param value the value to write + * + * @return The previous value from + */ +atomic_val_t atomic_set(atomic_t *target, atomic_val_t value) +{ + unsigned int key; + atomic_val_t ret; + + key = irq_lock(); + + ret = *target; + *target = value; + + irq_unlock(key); + + return ret; +} + +/** + * + * @brief Atomic clear primitive + * + * This routine provides the atomic clear operator. The value of 0 is atomically + * written at and the previous value at is returned. (Hence, + * atomic_clear(pAtomicVar) is equivalent to atomic_set(pAtomicVar, 0).) + * + * @param target the memory location to write + * + * @return The previous value from + */ +atomic_val_t atomic_clear(atomic_t *target) +{ + unsigned int key; + atomic_val_t ret; + + key = irq_lock(); + + ret = *target; + *target = 0; + + irq_unlock(key); + + return ret; +} + +/** + * + * @brief Atomic bitwise inclusive OR primitive + * + * This routine provides the atomic bitwise inclusive OR operator. The + * is atomically bitwise OR'ed with the value at , placing the result + * at , and the previous value at is returned. + * + * @param target the memory location to be modified + * @param value the value to OR + * + * @return The previous value from + */ +atomic_val_t atomic_or(atomic_t *target, atomic_val_t value) +{ + unsigned int key; + atomic_val_t ret; + + key = irq_lock(); + + ret = *target; + *target |= value; + + irq_unlock(key); + + return ret; +} + +/** + * + * @brief Atomic bitwise exclusive OR (XOR) primitive + * + * This routine provides the atomic bitwise exclusive OR operator. The + * is atomically bitwise XOR'ed with the value at , placing the result + * at , and the previous value at is returned. + * + * @param target the memory location to be modified + * @param value the value to XOR + * + * @return The previous value from + */ +atomic_val_t atomic_xor(atomic_t *target, atomic_val_t value) +{ + unsigned int key; + atomic_val_t ret; + + key = irq_lock(); + + ret = *target; + *target ^= value; + + irq_unlock(key); + + return ret; +} + +/** + * + * @brief Atomic bitwise AND primitive + * + * This routine provides the atomic bitwise AND operator. The is + * atomically bitwise AND'ed with the value at , placing the result + * at , and the previous value at is returned. + * + * @param target the memory location to be modified + * @param value the value to AND + * + * @return The previous value from + */ +atomic_val_t atomic_and(atomic_t *target, atomic_val_t value) +{ + unsigned int key; + atomic_val_t ret; + + key = irq_lock(); + + ret = *target; + *target &= value; + + irq_unlock(key); + + return ret; +} + +/** + * + * @brief Atomic bitwise NAND primitive + * + * This routine provides the atomic bitwise NAND operator. The is + * atomically bitwise NAND'ed with the value at , placing the result + * at , and the previous value at is returned. + * + * @param target the memory location to be modified + * @param value the value to NAND + * + * @return The previous value from + */ +atomic_val_t atomic_nand(atomic_t *target, atomic_val_t value) +{ + unsigned int key; + atomic_val_t ret; + + key = irq_lock(); + + ret = *target; + *target = ~(*target & value); + + irq_unlock(key); + + return ret; +} diff --git a/kernel/protocols/bluetooth/core/buf.c b/kernel/protocols/bluetooth/core/buf.c new file mode 100644 index 0000000000..f06c9b812d --- /dev/null +++ b/kernel/protocols/bluetooth/core/buf.c @@ -0,0 +1,529 @@ +/* buf.c - Buffer management */ + +/* + * Copyright (c) 2015 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#include + +#if defined(CONFIG_NET_BUF_LOG) +#define SYS_LOG_DOMAIN "net/buf" +#define SYS_LOG_LEVEL CONFIG_SYS_LOG_NET_BUF_LEVEL +//#include + +#define NET_BUF_DBG(fmt, ...) SYS_LOG_DBG(fmt, \ + ##__VA_ARGS__) +#define NET_BUF_ERR(fmt, ...) SYS_LOG_ERR(fmt, ##__VA_ARGS__) +#define NET_BUF_WARN(fmt, ...) SYS_LOG_WRN(fmt, ##__VA_ARGS__) +#define NET_BUF_INFO(fmt, ...) SYS_LOG_INF(fmt, ##__VA_ARGS__) +#define NET_BUF_ASSERT(cond) do { if (!(cond)) { \ + NET_BUF_ERR("assert: '" #cond "' failed"); \ + } } while (0) +#else + +#define NET_BUF_DBG(fmt, ...) +#define NET_BUF_ERR(fmt, ...) +#define NET_BUF_WARN(fmt, ...) +#define NET_BUF_INFO(fmt, ...) +#define NET_BUF_ASSERT(cond) +#endif /* CONFIG_NET_BUF_LOG */ + +/* Helpers to access the storage array, since we don't have access to its + * type at this point anymore. + */ +#define BUF_SIZE(pool) (sizeof(struct net_buf) + \ + ROUND_UP(pool->buf_size, 4) + \ + ROUND_UP(pool->user_data_size, 4)) +#define UNINIT_BUF(pool, n) (struct net_buf *)(((uint8_t *)(pool->__bufs)) + \ + ((n) * BUF_SIZE(pool))) + +static inline struct net_buf *pool_get_uninit(struct net_buf_pool *pool, + uint16_t uninit_count) +{ + struct net_buf *buf; + + buf = UNINIT_BUF(pool, pool->buf_count - uninit_count); + + buf->pool = pool; + buf->size = pool->buf_size; + + return buf; +} + +#if defined(CONFIG_NET_BUF_LOG) +struct net_buf *net_buf_alloc_debug(struct net_buf_pool *pool, int32_t timeout, + const char *func, int line) +#else +struct net_buf *net_buf_alloc(struct net_buf_pool *pool, int32_t timeout) +#endif +{ + struct net_buf *buf; + unsigned int key; + + NET_BUF_ASSERT(pool); + + NET_BUF_DBG("%s():%d: pool %p timeout %d,pool->uninit_count %d", func, line, pool, timeout, pool->uninit_count); + + /* We need to lock interrupts temporarily to prevent race conditions + * when accessing pool->uninit_count. + */ + key = irq_lock(); + + /* If there are uninitialized buffers we're guaranteed to succeed + * with the allocation one way or another. + */ + if (pool->uninit_count) { + uint16_t uninit_count; + + /* If this is not the first access to the pool, we can + * be opportunistic and try to fetch a previously used + * buffer from the LIFO with K_NO_WAIT. + */ + if (pool->uninit_count < pool->buf_count) { + buf = k_lifo_get(&pool->free, K_NO_WAIT); + + if (buf) { + irq_unlock(key); + goto success; + } + } + + uninit_count = pool->uninit_count--; + irq_unlock(key); + + buf = pool_get_uninit(pool, uninit_count); + goto success; + } + + irq_unlock(key); + +#if defined(CONFIG_NET_BUF_LOG) && SYS_LOG_LEVEL >= SYS_LOG_LEVEL_WARNING + + if (timeout == K_FOREVER) { + buf = k_lifo_get(&pool->free, K_NO_WAIT); + + if (!buf) { + NET_BUF_WARN("%s():%d: Pool %p low on buffers.", + func, line, pool); + buf = k_lifo_get(&pool->free, timeout); + } + } else { + buf = k_lifo_get(&pool->free, timeout); + } + +#else + buf = k_lifo_get(&pool->free, timeout); +#endif + + if (!buf) { + NET_BUF_ERR("%s():%d: Failed to get free buffer", func, line); + return NULL; + } + +success: + NET_BUF_DBG("allocated buf %p", buf); + + buf->ref = 1; + buf->len = 0; + buf->data = buf->__buf; + buf->flags = 0; + buf->frags = NULL; + +#if defined(CONFIG_NET_BUF_POOL_USAGE) + buf->pool->avail_count--; + NET_BUF_ASSERT(buf->pool->avail_count >= 0); +#endif + + return buf; +} + +#if defined(CONFIG_NET_BUF_LOG) +struct net_buf *net_buf_get_debug(struct k_fifo *fifo, int32_t timeout, + const char *func, int line) +#else +struct net_buf *net_buf_get(struct k_fifo *fifo, int32_t timeout) +#endif +{ + struct net_buf *buf, *frag; + + NET_BUF_DBG("%s():%d: fifo %p timeout %d", func, line, fifo, timeout); + + buf = k_fifo_get(fifo, timeout); + + if (!buf) { + NET_BUF_DBG("Failed to get free buffer"); + return NULL; + } + + NET_BUF_DBG("%s():%d: buf %p fifo %p", func, line, buf, fifo); + + /* Get any fragments belonging to this buffer */ + for (frag = buf; (frag->flags & NET_BUF_FRAGS); frag = frag->frags) { + frag->frags = k_fifo_get(fifo, K_NO_WAIT); + NET_BUF_ASSERT(frag->frags); + + /* The fragments flag is only for FIFO-internal usage */ + frag->flags &= ~NET_BUF_FRAGS; + } + + /* Mark the end of the fragment list */ + frag->frags = NULL; + + return buf; +} + +void net_buf_reserve(struct net_buf *buf, size_t reserve) +{ + NET_BUF_ASSERT(buf); + NET_BUF_ASSERT(buf->len == 0); + NET_BUF_DBG("buf %p reserve %zu", buf, reserve); + + buf->data = buf->__buf + reserve; +} + +void net_buf_put(struct k_fifo *fifo, struct net_buf *buf) +{ + struct net_buf *tail; + + NET_BUF_ASSERT(fifo); + NET_BUF_ASSERT(buf); + + for (tail = buf; tail->frags; tail = tail->frags) { + tail->flags |= NET_BUF_FRAGS; + k_fifo_put(fifo, tail); + } + + k_fifo_put(fifo, tail); +} + +#if defined(CONFIG_NET_BUF_LOG) +void net_buf_unref_debug(struct net_buf *buf, const char *func, int line) +#else +void net_buf_unref(struct net_buf *buf) +#endif +{ + NET_BUF_ASSERT(buf); + + while (buf) { + struct net_buf *frags = buf->frags; + +#if defined(CONFIG_NET_BUF_LOG) + + if (!buf->ref) { + NET_BUF_ERR("%s():%d: buf %p double free", func, line, + buf); + return; + } + +#endif + NET_BUF_DBG("buf %p ref %u pool %p frags %p", buf, buf->ref, + buf->pool, buf->frags); + + if (--buf->ref > 0) { + return; + } + + buf->frags = NULL; + +#if defined(CONFIG_NET_BUF_POOL_USAGE) + buf->pool->avail_count++; + NET_BUF_ASSERT(buf->pool->avail_count <= buf->pool->buf_count); +#endif + + if (buf->pool->destroy) { + buf->pool->destroy(buf); + } else { + net_buf_destroy(buf); + } + + buf = frags; + } +} + +struct net_buf *net_buf_ref(struct net_buf *buf) +{ + NET_BUF_ASSERT(buf); + + NET_BUF_DBG("buf %p (old) ref %u pool %p", + buf, buf->ref, buf->pool); + buf->ref++; + return buf; +} + +struct net_buf *net_buf_clone(struct net_buf *buf, int32_t timeout) +{ + struct net_buf *clone; + + NET_BUF_ASSERT(buf); + + clone = net_buf_alloc(buf->pool, timeout); + + if (!clone) { + return NULL; + } + + net_buf_reserve(clone, net_buf_headroom(buf)); + + /* TODO: Add reference to the original buffer instead of copying it. */ + memcpy(net_buf_add(clone, buf->len), buf->data, buf->len); + + return clone; +} + +struct net_buf *net_buf_frag_last(struct net_buf *buf) +{ + NET_BUF_ASSERT(buf); + + while (buf->frags) { + buf = buf->frags; + } + + return buf; +} + +void net_buf_frag_insert(struct net_buf *parent, struct net_buf *frag) +{ + NET_BUF_ASSERT(parent); + NET_BUF_ASSERT(frag); + + if (parent->frags) { + net_buf_frag_last(frag)->frags = parent->frags; + } + + /* Take ownership of the fragment reference */ + parent->frags = frag; +} + +struct net_buf *net_buf_frag_add(struct net_buf *head, struct net_buf *frag) +{ + NET_BUF_ASSERT(frag); + + if (!head) { + return net_buf_ref(frag); + } + + net_buf_frag_insert(net_buf_frag_last(head), frag); + + return head; +} + +#if defined(CONFIG_NET_BUF_LOG) +struct net_buf *net_buf_frag_del_debug(struct net_buf *parent, + struct net_buf *frag, + const char *func, int line) +#else +struct net_buf *net_buf_frag_del(struct net_buf *parent, struct net_buf *frag) +#endif +{ + struct net_buf *next_frag; + + NET_BUF_ASSERT(frag); + + if (parent) { + NET_BUF_ASSERT(parent->frags); + NET_BUF_ASSERT(parent->frags == frag); + parent->frags = frag->frags; + } + + next_frag = frag->frags; + + frag->frags = NULL; + +#if defined(CONFIG_NET_BUF_LOG) + net_buf_unref_debug(frag, func, line); +#else + net_buf_unref(frag); +#endif + + return next_frag; +} + +#if defined(CONFIG_NET_BUF_SIMPLE_LOG) +#define NET_BUF_SIMPLE_DBG(fmt, ...) NET_BUF_DBG(fmt, ##__VA_ARGS__) +#define NET_BUF_SIMPLE_ERR(fmt, ...) NET_BUF_ERR(fmt, ##__VA_ARGS__) +#define NET_BUF_SIMPLE_WARN(fmt, ...) NET_BUF_WARN(fmt, ##__VA_ARGS__) +#define NET_BUF_SIMPLE_INFO(fmt, ...) NET_BUF_INFO(fmt, ##__VA_ARGS__) +#define NET_BUF_SIMPLE_ASSERT(cond) NET_BUF_ASSERT(cond) +#else +#define NET_BUF_SIMPLE_DBG(fmt, ...) +#define NET_BUF_SIMPLE_ERR(fmt, ...) +#define NET_BUF_SIMPLE_WARN(fmt, ...) +#define NET_BUF_SIMPLE_INFO(fmt, ...) +#define NET_BUF_SIMPLE_ASSERT(cond) +#endif /* CONFIG_NET_BUF_SIMPLE_LOG */ + +void *net_buf_simple_add(struct net_buf_simple *buf, size_t len) +{ + uint8_t *tail = net_buf_simple_tail(buf); + + NET_BUF_SIMPLE_DBG("buf %p len %zu", buf, len); + + NET_BUF_SIMPLE_ASSERT(net_buf_simple_tailroom(buf) >= len); + + buf->len += len; + return tail; +} + +void *net_buf_simple_add_mem(struct net_buf_simple *buf, const void *mem, + size_t len) +{ + NET_BUF_SIMPLE_DBG("buf %p len %zu", buf, len); + + return memcpy(net_buf_simple_add(buf, len), mem, len); +} + +uint8_t *net_buf_simple_add_u8(struct net_buf_simple *buf, uint8_t val) +{ + uint8_t *u8; + + NET_BUF_SIMPLE_DBG("buf %p val 0x%02x", buf, val); + + u8 = net_buf_simple_add(buf, 1); + *u8 = val; + + return u8; +} + +void net_buf_simple_add_le16(struct net_buf_simple *buf, uint16_t val) +{ + NET_BUF_SIMPLE_DBG("buf %p val %u", buf, val); + + val = sys_cpu_to_le16(val); + memcpy(net_buf_simple_add(buf, sizeof(val)), &val, sizeof(val)); +} + +void net_buf_simple_add_be16(struct net_buf_simple *buf, uint16_t val) +{ + NET_BUF_SIMPLE_DBG("buf %p val %u", buf, val); + + val = sys_cpu_to_be16(val); + memcpy(net_buf_simple_add(buf, sizeof(val)), &val, sizeof(val)); +} + +void net_buf_simple_add_le32(struct net_buf_simple *buf, uint32_t val) +{ + NET_BUF_SIMPLE_DBG("buf %p val %u", buf, val); + + val = sys_cpu_to_le32(val); + memcpy(net_buf_simple_add(buf, sizeof(val)), &val, sizeof(val)); +} + +void net_buf_simple_add_be32(struct net_buf_simple *buf, uint32_t val) +{ + NET_BUF_SIMPLE_DBG("buf %p val %u", buf, val); + + val = sys_cpu_to_be32(val); + memcpy(net_buf_simple_add(buf, sizeof(val)), &val, sizeof(val)); +} + +void *net_buf_simple_push(struct net_buf_simple *buf, size_t len) +{ + NET_BUF_SIMPLE_DBG("buf %p len %zu", buf, len); + + NET_BUF_SIMPLE_ASSERT(net_buf_simple_headroom(buf) >= len); + + buf->data -= len; + buf->len += len; + return buf->data; +} + +void net_buf_simple_push_le16(struct net_buf_simple *buf, uint16_t val) +{ + NET_BUF_SIMPLE_DBG("buf %p val %u", buf, val); + + val = sys_cpu_to_le16(val); + memcpy(net_buf_simple_push(buf, sizeof(val)), &val, sizeof(val)); +} + +void net_buf_simple_push_be16(struct net_buf_simple *buf, uint16_t val) +{ + NET_BUF_SIMPLE_DBG("buf %p val %u", buf, val); + + val = sys_cpu_to_be16(val); + memcpy(net_buf_simple_push(buf, sizeof(val)), &val, sizeof(val)); +} + +void net_buf_simple_push_u8(struct net_buf_simple *buf, uint8_t val) +{ + uint8_t *data = net_buf_simple_push(buf, 1); + + *data = val; +} + +void *net_buf_simple_pull(struct net_buf_simple *buf, size_t len) +{ + NET_BUF_SIMPLE_DBG("buf %p len %zu", buf, len); + + NET_BUF_SIMPLE_ASSERT(buf->len >= len); + + buf->len -= len; + return buf->data += len; +} + +uint8_t net_buf_simple_pull_u8(struct net_buf_simple *buf) +{ + uint8_t val; + + val = buf->data[0]; + net_buf_simple_pull(buf, 1); + + return val; +} + +uint16_t net_buf_simple_pull_le16(struct net_buf_simple *buf) +{ + uint16_t val; + + val = UNALIGNED_GET((uint16_t *)buf->data); + net_buf_simple_pull(buf, sizeof(val)); + + return sys_le16_to_cpu(val); +} + +uint16_t net_buf_simple_pull_be16(struct net_buf_simple *buf) +{ + uint16_t val; + + val = UNALIGNED_GET((uint16_t *)buf->data); + net_buf_simple_pull(buf, sizeof(val)); + + return sys_be16_to_cpu(val); +} + +uint32_t net_buf_simple_pull_le32(struct net_buf_simple *buf) +{ + uint32_t val; + + val = UNALIGNED_GET((uint32_t *)buf->data); + net_buf_simple_pull(buf, sizeof(val)); + + return sys_le32_to_cpu(val); +} + +uint32_t net_buf_simple_pull_be32(struct net_buf_simple *buf) +{ + uint32_t val; + + val = UNALIGNED_GET((uint32_t *)buf->data); + net_buf_simple_pull(buf, sizeof(val)); + + return sys_be32_to_cpu(val); +} + +size_t net_buf_simple_headroom(struct net_buf_simple *buf) +{ + return buf->data - buf->__buf; +} + +size_t net_buf_simple_tailroom(struct net_buf_simple *buf) +{ + return buf->size - net_buf_simple_headroom(buf) - buf->len; +} diff --git a/kernel/protocols/bluetooth/core/include/atomic.h b/kernel/protocols/bluetooth/core/include/atomic.h new file mode 100644 index 0000000000..e77adfff9b --- /dev/null +++ b/kernel/protocols/bluetooth/core/include/atomic.h @@ -0,0 +1,420 @@ +/* atomic operations */ + +/* + * Copyright (c) 1997-2015, Wind River Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __ATOMIC_H__ +#define __ATOMIC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef int atomic_t; +typedef atomic_t atomic_val_t; + +/** + * @defgroup atomic_apis Atomic Services APIs + * @ingroup kernel_apis + * @{ + */ + +/** + * @brief Atomic compare-and-set. + * + * This routine performs an atomic compare-and-set on @a target. If the current + * value of @a target equals @a old_value, @a target is set to @a new_value. + * If the current value of @a target does not equal @a old_value, @a target + * is left unchanged. + * + * @param target Address of atomic variable. + * @param old_value Original value to compare against. + * @param new_value New value to store. + * @return 1 if @a new_value is written, 0 otherwise. + */ +#ifdef CONFIG_ATOMIC_OPERATIONS_BUILTIN +static inline int atomic_cas(atomic_t *target, atomic_val_t old_value, + atomic_val_t new_value) +{ + return __atomic_compare_exchange_n(target, &old_value, new_value, + 0, __ATOMIC_SEQ_CST, + __ATOMIC_SEQ_CST); +} +#else +extern int atomic_cas(atomic_t *target, atomic_val_t old_value, + atomic_val_t new_value); +#endif + +/** + * + * @brief Atomic addition. + * + * This routine performs an atomic addition on @a target. + * + * @param target Address of atomic variable. + * @param value Value to add. + * + * @return Previous value of @a target. + */ +#ifdef CONFIG_ATOMIC_OPERATIONS_BUILTIN +static inline atomic_val_t atomic_add(atomic_t *target, atomic_val_t value) +{ + return __atomic_fetch_add(target, value, __ATOMIC_SEQ_CST); +} +#else +extern atomic_val_t atomic_add(atomic_t *target, atomic_val_t value); +#endif + +/** + * + * @brief Atomic subtraction. + * + * This routine performs an atomic subtraction on @a target. + * + * @param target Address of atomic variable. + * @param value Value to subtract. + * + * @return Previous value of @a target. + */ +#ifdef CONFIG_ATOMIC_OPERATIONS_BUILTIN +static inline atomic_val_t atomic_sub(atomic_t *target, atomic_val_t value) +{ + return __atomic_fetch_sub(target, value, __ATOMIC_SEQ_CST); +} +#else +extern atomic_val_t atomic_sub(atomic_t *target, atomic_val_t value); +#endif + +/** + * + * @brief Atomic increment. + * + * This routine performs an atomic increment by 1 on @a target. + * + * @param target Address of atomic variable. + * + * @return Previous value of @a target. + */ +#ifdef CONFIG_ATOMIC_OPERATIONS_BUILTIN +static inline atomic_val_t atomic_inc(atomic_t *target) +{ + return atomic_add(target, 1); +} +#else +extern atomic_val_t atomic_inc(atomic_t *target); +#endif + +/** + * + * @brief Atomic decrement. + * + * This routine performs an atomic decrement by 1 on @a target. + * + * @param target Address of atomic variable. + * + * @return Previous value of @a target. + */ +#ifdef CONFIG_ATOMIC_OPERATIONS_BUILTIN +static inline atomic_val_t atomic_dec(atomic_t *target) +{ + return atomic_sub(target, 1); +} +#else +extern atomic_val_t atomic_dec(atomic_t *target); +#endif + +/** + * + * @brief Atomic get. + * + * This routine performs an atomic read on @a target. + * + * @param target Address of atomic variable. + * + * @return Value of @a target. + */ +#ifdef CONFIG_ATOMIC_OPERATIONS_BUILTIN +static inline atomic_val_t atomic_get(const atomic_t *target) +{ + return __atomic_load_n(target, __ATOMIC_SEQ_CST); +} +#else +extern atomic_val_t atomic_get(const atomic_t *target); +#endif + +/** + * + * @brief Atomic get-and-set. + * + * This routine atomically sets @a target to @a value and returns + * the previous value of @a target. + * + * @param target Address of atomic variable. + * @param value Value to write to @a target. + * + * @return Previous value of @a target. + */ +#ifdef CONFIG_ATOMIC_OPERATIONS_BUILTIN +static inline atomic_val_t atomic_set(atomic_t *target, atomic_val_t value) +{ + /* This builtin, as described by Intel, is not a traditional + * test-and-set operation, but rather an atomic exchange operation. It + * writes value into *ptr, and returns the previous contents of *ptr. + */ + return __atomic_exchange_n(target, value, __ATOMIC_SEQ_CST); +} +#else +extern atomic_val_t atomic_set(atomic_t *target, atomic_val_t value); +#endif + +/** + * + * @brief Atomic clear. + * + * This routine atomically sets @a target to zero and returns its previous + * value. (Hence, it is equivalent to atomic_set(target, 0).) + * + * @param target Address of atomic variable. + * + * @return Previous value of @a target. + */ +#ifdef CONFIG_ATOMIC_OPERATIONS_BUILTIN +static inline atomic_val_t atomic_clear(atomic_t *target) +{ + return atomic_set(target, 0); +} +#else +extern atomic_val_t atomic_clear(atomic_t *target); +#endif + +/** + * + * @brief Atomic bitwise inclusive OR. + * + * This routine atomically sets @a target to the bitwise inclusive OR of + * @a target and @a value. + * + * @param target Address of atomic variable. + * @param value Value to OR. + * + * @return Previous value of @a target. + */ +#ifdef CONFIG_ATOMIC_OPERATIONS_BUILTIN +static inline atomic_val_t atomic_or(atomic_t *target, atomic_val_t value) +{ + return __atomic_fetch_or(target, value, __ATOMIC_SEQ_CST); +} +#else +extern atomic_val_t atomic_or(atomic_t *target, atomic_val_t value); +#endif + +/** + * + * @brief Atomic bitwise exclusive OR (XOR). + * + * This routine atomically sets @a target to the bitwise exclusive OR (XOR) of + * @a target and @a value. + * + * @param target Address of atomic variable. + * @param value Value to XOR + * + * @return Previous value of @a target. + */ +#ifdef CONFIG_ATOMIC_OPERATIONS_BUILTIN +static inline atomic_val_t atomic_xor(atomic_t *target, atomic_val_t value) +{ + return __atomic_fetch_xor(target, value, __ATOMIC_SEQ_CST); +} +#else +extern atomic_val_t atomic_xor(atomic_t *target, atomic_val_t value); +#endif + +/** + * + * @brief Atomic bitwise AND. + * + * This routine atomically sets @a target to the bitwise AND of @a target + * and @a value. + * + * @param target Address of atomic variable. + * @param value Value to AND. + * + * @return Previous value of @a target. + */ +#ifdef CONFIG_ATOMIC_OPERATIONS_BUILTIN +static inline atomic_val_t atomic_and(atomic_t *target, atomic_val_t value) +{ + return __atomic_fetch_and(target, value, __ATOMIC_SEQ_CST); +} +#else +extern atomic_val_t atomic_and(atomic_t *target, atomic_val_t value); +#endif + +/** + * + * @brief Atomic bitwise NAND. + * + * This routine atomically sets @a target to the bitwise NAND of @a target + * and @a value. (This operation is equivalent to target = ~(target & value).) + * + * @param target Address of atomic variable. + * @param value Value to NAND. + * + * @return Previous value of @a target. + */ +#ifdef CONFIG_ATOMIC_OPERATIONS_BUILTIN +static inline atomic_val_t atomic_nand(atomic_t *target, atomic_val_t value) +{ + return __atomic_fetch_nand(target, value, __ATOMIC_SEQ_CST); +} +#else +extern atomic_val_t atomic_nand(atomic_t *target, atomic_val_t value); +#endif + + +/** + * @brief Initialize an atomic variable. + * + * This macro can be used to initialize an atomic variable. For example, + * @code atomic_t my_var = ATOMIC_INIT(75); @endcode + * + * @param i Value to assign to atomic variable. + */ +#define ATOMIC_INIT(i) (i) + +/** + * @cond INTERNAL_HIDDEN + */ + +#define ATOMIC_BITS (sizeof(atomic_val_t) * 8) +#define ATOMIC_MASK(bit) (1 << ((bit) & (ATOMIC_BITS - 1))) +#define ATOMIC_ELEM(addr, bit) ((addr) + ((bit) / ATOMIC_BITS)) + +/** + * INTERNAL_HIDDEN @endcond + */ + +/** + * @brief Define an array of atomic variables. + * + * This macro defines an array of atomic variables containing at least + * @a num_bits bits. + * + * @note + * If used from file scope, the bits of the array are initialized to zero; + * if used from within a function, the bits are left uninitialized. + * + * @param name Name of array of atomic variables. + * @param num_bits Number of bits needed. + */ +#define ATOMIC_DEFINE(name, num_bits) \ + atomic_t name[1 + ((num_bits) - 1) / ATOMIC_BITS] + +/** + * @brief Atomically test a bit. + * + * This routine tests whether bit number @a bit of @a target is set or not. + * The target may be a single atomic variable or an array of them. + * + * @param target Address of atomic variable or array. + * @param bit Bit number (starting from 0). + * + * @return 1 if the bit was set, 0 if it wasn't. + */ +static inline int atomic_test_bit(const atomic_t *target, int bit) +{ + atomic_val_t val = atomic_get(ATOMIC_ELEM(target, bit)); + + return (1 & (val >> (bit & (ATOMIC_BITS - 1)))); +} + +/** + * @brief Atomically test and clear a bit. + * + * Atomically clear bit number @a bit of @a target and return its old value. + * The target may be a single atomic variable or an array of them. + * + * @param target Address of atomic variable or array. + * @param bit Bit number (starting from 0). + * + * @return 1 if the bit was set, 0 if it wasn't. + */ +static inline int atomic_test_and_clear_bit(atomic_t *target, int bit) +{ + atomic_val_t mask = ATOMIC_MASK(bit); + atomic_val_t old; + + old = atomic_and(ATOMIC_ELEM(target, bit), ~mask); + + return (old & mask) != 0; +} + +/** + * @brief Atomically set a bit. + * + * Atomically set bit number @a bit of @a target and return its old value. + * The target may be a single atomic variable or an array of them. + * + * @param target Address of atomic variable or array. + * @param bit Bit number (starting from 0). + * + * @return 1 if the bit was set, 0 if it wasn't. + */ +static inline int atomic_test_and_set_bit(atomic_t *target, int bit) +{ + atomic_val_t mask = ATOMIC_MASK(bit); + atomic_val_t old; + + old = atomic_or(ATOMIC_ELEM(target, bit), mask); + + return (old & mask) != 0; +} + +/** + * @brief Atomically clear a bit. + * + * Atomically clear bit number @a bit of @a target. + * The target may be a single atomic variable or an array of them. + * + * @param target Address of atomic variable or array. + * @param bit Bit number (starting from 0). + * + * @return N/A + */ +static inline void atomic_clear_bit(atomic_t *target, int bit) +{ + atomic_val_t mask = ATOMIC_MASK(bit); + + atomic_and(ATOMIC_ELEM(target, bit), ~mask); +} + +/** + * @brief Atomically set a bit. + * + * Atomically set bit number @a bit of @a target. + * The target may be a single atomic variable or an array of them. + * + * @param target Address of atomic variable or array. + * @param bit Bit number (starting from 0). + * + * @return N/A + */ +static inline void atomic_set_bit(atomic_t *target, int bit) +{ + atomic_val_t mask = ATOMIC_MASK(bit); + + atomic_or(ATOMIC_ELEM(target, bit), mask); +} + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ATOMIC_H__ */ diff --git a/kernel/protocols/bluetooth/core/include/errno.h b/kernel/protocols/bluetooth/core/include/errno.h new file mode 100644 index 0000000000..4c15b490fc --- /dev/null +++ b/kernel/protocols/bluetooth/core/include/errno.h @@ -0,0 +1,133 @@ +/* errno.h - errno numbers */ + +/* + * Copyright (c) 1984-1999, 2012 Wind River Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Copyright (c) 1982, 1986 Regents of the University of California. + * All rights reserved. The Berkeley software License Agreement + * specifies the terms and conditions for redistribution. + * + * @(#)errno.h 7.1 (Berkeley) 6/4/86 + */ + +#ifndef __INCerrnoh +#define __INCerrnoh + +#ifdef __cplusplus +extern "C" { +#endif + + +extern int *_get_errno(void); +#define errno (*_get_errno()) + +/* + * POSIX Error codes + */ + +#define EPERM 1 /* Not owner */ +#define ENOENT 2 /* No such file or directory */ +#define ESRCH 3 /* No such context */ +#define EINTR 4 /* Interrupted system call */ +#define EIO 5 /* I/O error */ +#define ENXIO 6 /* No such device or address */ +#define E2BIG 7 /* Arg list too long */ +#define ENOEXEC 8 /* Exec format error */ +#define EBADF 9 /* Bad file number */ +#define ECHILD 10 /* No children */ +#define EAGAIN 11 /* No more contexts */ +#define ENOMEM 12 /* Not enough core */ +#define EACCES 13 /* Permission denied */ +#define EFAULT 14 /* Bad address */ +#define ENOTEMPTY 15 /* Directory not empty */ +#define EBUSY 16 /* Mount device busy */ +#define EEXIST 17 /* File exists */ +#define EXDEV 18 /* Cross-device link */ +#define ENODEV 19 /* No such device */ +#define ENOTDIR 20 /* Not a directory */ +#define EISDIR 21 /* Is a directory */ +#define EINVAL 22 /* Invalid argument */ +#define ENFILE 23 /* File table overflow */ +#define EMFILE 24 /* Too many open files */ +#define ENOTTY 25 /* Not a typewriter */ +#define ENAMETOOLONG 26 /* File name too long */ +#define EFBIG 27 /* File too large */ +#define ENOSPC 28 /* No space left on device */ +#define ESPIPE 29 /* Illegal seek */ +#define EROFS 30 /* Read-only file system */ +#define EMLINK 31 /* Too many links */ +#define EPIPE 32 /* Broken pipe */ +#define EDEADLK 33 /* Resource deadlock avoided */ +#define ENOLCK 34 /* No locks available */ +#define ENOTSUP 35 /* Unsupported value */ +#define EMSGSIZE 36 /* Message size */ + +/* ANSI math software */ +#define EDOM 37 /* Argument too large */ +#define ERANGE 38 /* Result too large */ + +/* ipc/network software */ + +/* argument errors */ +#define EDESTADDRREQ 40 /* Destination address required */ +#define EPROTOTYPE 41 /* Protocol wrong type for socket */ +#define ENOPROTOOPT 42 /* Protocol not available */ +#define EPROTONOSUPPORT 43 /* Protocol not supported */ +#define ESOCKTNOSUPPORT 44 /* Socket type not supported */ +#define EOPNOTSUPP 45 /* Operation not supported on socket */ +#define EPFNOSUPPORT 46 /* Protocol family not supported */ +#define EAFNOSUPPORT 47 /* Addr family not supported */ +#define EADDRINUSE 48 /* Address already in use */ +#define EADDRNOTAVAIL 49 /* Can't assign requested address */ +#define ENOTSOCK 50 /* Socket operation on non-socket */ + +/* operational errors */ +#define ENETUNREACH 51 /* Network is unreachable */ +#define ENETRESET 52 /* Network dropped connection on reset */ +#define ECONNABORTED 53 /* Software caused connection abort */ +#define ECONNRESET 54 /* Connection reset by peer */ +#define ENOBUFS 55 /* No buffer space available */ +#define EISCONN 56 /* Socket is already connected */ +#define ENOTCONN 57 /* Socket is not connected */ +#define ESHUTDOWN 58 /* Can't send after socket shutdown */ +#define ETOOMANYREFS 59 /* Too many references: can't splice */ +#define ETIMEDOUT 60 /* Connection timed out */ +#define ECONNREFUSED 61 /* Connection refused */ +#define ENETDOWN 62 /* Network is down */ +#define ETXTBSY 63 /* Text file busy */ +#define ELOOP 64 /* Too many levels of symbolic links */ +#define EHOSTUNREACH 65 /* No route to host */ +#define ENOTBLK 66 /* Block device required */ +#define EHOSTDOWN 67 /* Host is down */ + +/* non-blocking and interrupt i/o */ +#define EINPROGRESS 68 /* Operation now in progress */ +#define EALREADY 69 /* Operation already in progress */ +#define EWOULDBLOCK EAGAIN /* Operation would block */ + +#define ENOSYS 71 /* Function not implemented */ + +/* aio errors (should be under posix) */ +#define ECANCELED 72 /* Operation canceled */ + +#define ERRMAX 81 + +/* specific STREAMS errno values */ + +#define ENOSR 74 /* Insufficient memory */ +#define ENOSTR 75 /* STREAMS device required */ +#define EPROTO 76 /* Generic STREAMS error */ +#define EBADMSG 77 /* Invalid STREAMS message */ +#define ENODATA 78 /* Missing expected message data */ +#define ETIME 79 /* STREAMS timeout occurred */ +#define ENOMSG 80 /* Unexpected message type */ + +#ifdef __cplusplus +} +#endif + +#endif /* __INCerrnoh */ diff --git a/kernel/protocols/bluetooth/core/include/mbox.h b/kernel/protocols/bluetooth/core/include/mbox.h new file mode 100644 index 0000000000..6396542101 --- /dev/null +++ b/kernel/protocols/bluetooth/core/include/mbox.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#ifndef MBOX_H +#define MBOX_H + +#if defined(__cplusplus) +extern "C" +{ +#endif + +#define K_MBOX_SIZE 128 + +#define SYS_ARCH_TIMEOUT 0xffffffffUL +#define SYS_MBOX_EMPTY SYS_ARCH_TIMEOUT + +typedef struct k_mbox { + int first, last; + void *msgs[K_MBOX_SIZE]; + struct k_sem not_empty; + struct k_sem not_full; + struct k_sem mutex; + int wait_send; +} k_mbox_t; + +int k_mbox_new(k_mbox_t **mb, int size); +void k_mbox_free(k_mbox_t *mb); +void k_mbox_post(k_mbox_t *mb, void *msg); +int k_mbox_trypost(k_mbox_t *mb, void *msg); +int k_mbox_fetch(k_mbox_t *mb, void **msg, uint32_t timeout); +int k_mbox_tryfetch(k_mbox_t *mb, void **msg); + +#ifdef __cplusplus +} +#endif + +#endif /* MBOX_H */ + diff --git a/kernel/protocols/bluetooth/core/include/misc/__assert.h b/kernel/protocols/bluetooth/core/include/misc/__assert.h new file mode 100644 index 0000000000..5e3be3169b --- /dev/null +++ b/kernel/protocols/bluetooth/core/include/misc/__assert.h @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2011-2014 Wind River Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Debug aid + * + * + * The __ASSERT() macro can be used inside kernel code. + * + * Assertions are enabled by setting the __ASSERT_ON symbol to a non-zero value. + * There are two ways to do this: + * a) Use the ASSERT and ASSERT_LEVEL kconfig options + * b) Add "CFLAGS += -D__ASSERT_ON=" at the end of a project's Makefile + * The Makefile method takes precedence over the kconfig option if both are + * used. + * + * Specifying an assertion level of 1 causes the compiler to issue warnings that + * the kernel contains debug-type __ASSERT() statements; this reminder is issued + * since assertion code is not normally present in a final product. Specifying + * assertion level 2 suppresses these warnings. + * + * The __ASSERT_EVAL() macro can also be used inside kernel code. + * + * It makes use of the __ASSERT() macro, but has some extra flexibility. It + * allows the developer to specify different actions depending whether the + * __ASSERT() macro is enabled or not. This can be particularly useful to + * prevent the compiler from generating comments (errors, warnings or remarks) + * about variables that are only used with __ASSERT() being assigned a value, + * but otherwise unused when the __ASSERT() macro is disabled. + * + * Consider the following example: + * + * int x; + * + * x = foo (); + * __ASSERT (x != 0, "foo() returned zero!"); + * + * If __ASSERT() is disabled, then 'x' is assigned a value, but never used. + * This type of situation can be resolved using the __ASSERT_EVAL() macro. + * + * __ASSERT_EVAL ((void) foo(), + * int x = foo(), + * x != 0, + * "foo() returned zero!"); + * + * The first parameter tells __ASSERT_EVAL() what to do if __ASSERT() is + * disabled. The second parameter tells __ASSERT_EVAL() what to do if + * __ASSERT() is enabled. The third and fourth parameters are the parameters + * it passes to __ASSERT(). + * + * The __ASSERT_NO_MSG() macro can be used to perform an assertion that reports + * the failed test and its location, but lacks additional debugging information + * provided to assist the user in diagnosing the problem; its use is + * discouraged. + */ + +#ifndef ___ASSERT__H_ +#define ___ASSERT__H_ + +#ifdef CONFIG_ASSERT +#ifndef __ASSERT_ON +#define __ASSERT_ON CONFIG_ASSERT_LEVEL +#endif +#endif + +#ifdef __ASSERT_ON +#if (__ASSERT_ON < 0) || (__ASSERT_ON > 2) +#error "Invalid __ASSERT() level: must be between 0 and 2" +#endif + +#if __ASSERT_ON +#include +#define __ASSERT(test, fmt, ...) \ + do { \ + if (!(test)) { \ + SYS_LOG_ERR("ASSERTION FAIL [%s] @ %s:%d:\n\t", \ + _STRINGIFY(test), \ + __FILE__, \ + __LINE__); \ + SYS_LOG_ERR(fmt, ##__VA_ARGS__); \ + for (;;) \ + ; /* spin thread */ \ + } \ + } while ((0)) + +#define __ASSERT_EVAL(expr1, expr2, test, fmt, ...) \ + do { \ + expr2; \ + __ASSERT(test, fmt, ##__VA_ARGS__); \ + } while (0) + +#if (__ASSERT_ON == 1) +#warning "__ASSERT() statements are ENABLED" +#endif +#else +#define __ASSERT(test, fmt, ...) \ + do {/* nothing */ \ + } while ((0)) +#define __ASSERT_EVAL(expr1, expr2, test, fmt, ...) expr1 +#endif +#else +#define __ASSERT(test, fmt, ...) \ + do {/* nothing */ \ + } while ((0)) +#define __ASSERT_EVAL(expr1, expr2, test, fmt, ...) expr1 +#endif + +#endif /* ___ASSERT__H_ */ diff --git a/kernel/protocols/bluetooth/core/include/misc/byteorder.h b/kernel/protocols/bluetooth/core/include/misc/byteorder.h new file mode 100644 index 0000000000..a8531466d9 --- /dev/null +++ b/kernel/protocols/bluetooth/core/include/misc/byteorder.h @@ -0,0 +1,309 @@ +/** @file + * @brief Byte order helpers. + */ + +/* + * Copyright (c) 2015-2016, Intel Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __BYTEORDER_H__ +#define __BYTEORDER_H__ + +#include +#include +#include + +/* Internal helpers only used by the sys_* APIs further below */ +#define __bswap_16(x) ((uint16_t) ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8))) +#define __bswap_32(x) ((uint32_t) ((((x) >> 24) & 0xff) | \ + (((x) >> 8) & 0xff00) | \ + (((x) & 0xff00) << 8) | \ + (((x) & 0xff) << 24))) + +/** @def sys_le16_to_cpu + * @brief Convert 16-bit integer from little-endian to host endianness. + * + * @param val 16-bit integer in little-endian format. + * + * @return 16-bit integer in host endianness. + */ + +/** @def sys_cpu_to_le16 + * @brief Convert 16-bit integer from host endianness to little-endian. + * + * @param val 16-bit integer in host endianness. + * + * @return 16-bit integer in little-endian format. + */ + +/** @def sys_be16_to_cpu + * @brief Convert 16-bit integer from big-endian to host endianness. + * + * @param val 16-bit integer in big-endian format. + * + * @return 16-bit integer in host endianness. + */ + +/** @def sys_cpu_to_be16 + * @brief Convert 16-bit integer from host endianness to big-endian. + * + * @param val 16-bit integer in host endianness. + * + * @return 16-bit integer in big-endian format. + */ + +/** @def sys_le32_to_cpu + * @brief Convert 32-bit integer from little-endian to host endianness. + * + * @param val 32-bit integer in little-endian format. + * + * @return 32-bit integer in host endianness. + */ + +/** @def sys_cpu_to_le32 + * @brief Convert 32-bit integer from host endianness to little-endian. + * + * @param val 32-bit integer in host endianness. + * + * @return 32-bit integer in little-endian format. + */ + +/** @def sys_be32_to_cpu + * @brief Convert 32-bit integer from big-endian to host endianness. + * + * @param val 32-bit integer in big-endian format. + * + * @return 32-bit integer in host endianness. + */ + +/** @def sys_cpu_to_be32 + * @brief Convert 32-bit integer from host endianness to big-endian. + * + * @param val 32-bit integer in host endianness. + * + * @return 32-bit integer in big-endian format. + */ + +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +#define sys_le16_to_cpu(val) (val) +#define sys_cpu_to_le16(val) (val) +#define sys_be16_to_cpu(val) __bswap_16(val) +#define sys_cpu_to_be16(val) __bswap_16(val) +#define sys_le32_to_cpu(val) (val) +#define sys_cpu_to_le32(val) (val) +#define sys_be32_to_cpu(val) __bswap_32(val) +#define sys_cpu_to_be32(val) __bswap_32(val) +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +#define sys_le16_to_cpu(val) __bswap_16(val) +#define sys_cpu_to_le16(val) __bswap_16(val) +#define sys_be16_to_cpu(val) (val) +#define sys_cpu_to_be16(val) (val) +#define sys_le32_to_cpu(val) __bswap_32(val) +#define sys_cpu_to_le32(val) __bswap_32(val) +#define sys_be32_to_cpu(val) (val) +#define sys_cpu_to_be32(val) (val) +#else +#error "Unknown byte order" +#endif + +/** + * @brief Put a 16-bit intger as big-endian to arbitrary location. + * + * Put a 16-bit integer, originally in host endianness, to a + * potentially unaligned memory location in big-endian format. + * + * @param val 16-bit integer in host endianness. + * @param dst Destination memory address to store the result. + */ +static inline void sys_put_be16(uint16_t val, uint8_t dst[2]) +{ + dst[0] = val >> 8; + dst[1] = val; +} + +/** + * @brief Put a 32-bit intger as big-endian to arbitrary location. + * + * Put a 32-bit integer, originally in host endianness, to a + * potentially unaligned memory location in big-endian format. + * + * @param val 32-bit integer in host endianness. + * @param dst Destination memory address to store the result. + */ +static inline void sys_put_be32(uint32_t val, uint8_t dst[4]) +{ + sys_put_be16(val >> 16, dst); + sys_put_be16(val, &dst[2]); +} + +/** + * @brief Put a 16-bit intger as little-endian to arbitrary location. + * + * Put a 16-bit integer, originally in host endianness, to a + * potentially unaligned memory location in little-endian format. + * + * @param val 16-bit integer in host endianness. + * @param dst Destination memory address to store the result. + */ +static inline void sys_put_le16(uint16_t val, uint8_t dst[2]) +{ + dst[0] = val; + dst[1] = val >> 8; +} + +/** + * @brief Put a 32-bit intger as little-endian to arbitrary location. + * + * Put a 32-bit integer, originally in host endianness, to a + * potentially unaligned memory location in little-endian format. + * + * @param val 32-bit integer in host endianness. + * @param dst Destination memory address to store the result. + */ +static inline void sys_put_le32(uint32_t val, uint8_t dst[4]) +{ + sys_put_le16(val, dst); + sys_put_le16(val >> 16, &dst[2]); +} + +/** + * @brief Put a 64-bit integer as little-endian to arbitrary location. + * + * Put a 64-bit integer, originally in host endianness, to a + * potentially unaligned memory location in little-endian format. + * + * @param val 64-bit integer in host endianness. + * @param dst Destination memory address to store the result. + */ +static inline void sys_put_le64(uint64_t val, uint8_t dst[8]) +{ + sys_put_le32(val, dst); + sys_put_le32(val >> 32, &dst[4]); +} + +/** + * @brief Get a 16-bit intger stored in big-endian format. + * + * Get a 16-bit integer, stored in big-endian format in a potentially + * unaligned memory location, and convert it to the host endianness. + * + * @param src Location of the big-endian 16-bit integer to get. + * + * @return 16-bit integer in host endianness. + */ +static inline uint16_t sys_get_be16(const uint8_t src[2]) +{ + return ((uint16_t)src[0] << 8) | src[1]; +} + +/** + * @brief Get a 32-bit intger stored in big-endian format. + * + * Get a 32-bit integer, stored in big-endian format in a potentially + * unaligned memory location, and convert it to the host endianness. + * + * @param src Location of the big-endian 32-bit integer to get. + * + * @return 32-bit integer in host endianness. + */ +static inline uint32_t sys_get_be32(const uint8_t src[4]) +{ + return ((uint32_t)sys_get_be16(&src[0]) << 16) | sys_get_be16(&src[2]); +} + +/** + * @brief Get a 16-bit intger stored in little-endian format. + * + * Get a 16-bit integer, stored in little-endian format in a potentially + * unaligned memory location, and convert it to the host endianness. + * + * @param src Location of the little-endian 16-bit integer to get. + * + * @return 16-bit integer in host endianness. + */ +static inline uint16_t sys_get_le16(const uint8_t src[2]) +{ + return ((uint16_t)src[1] << 8) | src[0]; +} + +/** + * @brief Get a 32-bit intger stored in little-endian format. + * + * Get a 32-bit integer, stored in little-endian format in a potentially + * unaligned memory location, and convert it to the host endianness. + * + * @param src Location of the little-endian 32-bit integer to get. + * + * @return 32-bit integer in host endianness. + */ +static inline uint32_t sys_get_le32(const uint8_t src[4]) +{ + return ((uint32_t)sys_get_le16(&src[2]) << 16) | sys_get_le16(&src[0]); +} + +/** + * @brief Get a 64-bit integer stored in little-endian format. + * + * Get a 64-bit integer, stored in little-endian format in a potentially + * unaligned memory location, and convert it to the host endianness. + * + * @param src Location of the little-endian 64-bit integer to get. + * + * @return 64-bit integer in host endianness. + */ +static inline uint64_t sys_get_le64(const uint8_t src[8]) +{ + return ((uint64_t)sys_get_le32(&src[4]) << 32) | sys_get_le32(&src[0]); +} + +/** + * @brief Swap one buffer content into another + * + * Copy the content of src buffer into dst buffer in reversed order, + * i.e.: src[n] will be put in dst[end-n] + * Where n is an index and 'end' the last index in both arrays. + * The 2 memory pointers must be pointing to different areas, and have + * a minimum size of given length. + * + * @param dst A valid pointer on a memory area where to copy the data in + * @param src A valid pointer on a memory area where to copy the data from + * @param length Size of both dst and src memory areas + */ +static inline void sys_memcpy_swap(void *dst, const void *src, size_t length) +{ + __ASSERT(((src < dst && (src + length) <= dst) || + (src > dst && (dst + length) <= src)), + "Source and destination buffers must not overlap"); + + src += length - 1; + + for (; length > 0; length--) { + *((uint8_t *)dst++) = *((uint8_t *)src--); + } +} + +/** + * @brief Swap buffer content + * + * In-place memory swap, where final content will be reversed. + * I.e.: buf[n] will be put in buf[end-n] + * Where n is an index and 'end' the last index of buf. + * + * @param buf A valid pointer on a memory area to swap + * @param length Size of buf memory area + */ +static inline void sys_mem_swap(void *buf, size_t length) +{ + size_t i; + + for (i = 0; i < (length/2); i++) { + uint8_t tmp = ((uint8_t *)buf)[i]; + + ((uint8_t *)buf)[i] = ((uint8_t *)buf)[length - 1 - i]; + ((uint8_t *)buf)[length - 1 - i] = tmp; + } +} + +#endif /* __BYTEORDER_H__ */ diff --git a/kernel/protocols/bluetooth/core/include/misc/printk.h b/kernel/protocols/bluetooth/core/include/misc/printk.h new file mode 100644 index 0000000000..215bb0efdf --- /dev/null +++ b/kernel/protocols/bluetooth/core/include/misc/printk.h @@ -0,0 +1,28 @@ +/* printk.h - low-level debug output */ + +/* + * Copyright (c) 2010-2012, 2014 Wind River Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef _PRINTK_H_ +#define _PRINTK_H_ + +#include +#include +#include + +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +#define snprintk snprintf + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kernel/protocols/bluetooth/core/include/misc/slist.h b/kernel/protocols/bluetooth/core/include/misc/slist.h new file mode 100644 index 0000000000..b018720683 --- /dev/null +++ b/kernel/protocols/bluetooth/core/include/misc/slist.h @@ -0,0 +1,428 @@ +/* + * Copyright (c) 2016 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * + * @brief Header where single linked list utility code is found + */ + +#ifndef __SLIST_H__ +#define __SLIST_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +struct _snode { + struct _snode *next; +}; + +typedef struct _snode sys_snode_t; + +struct _slist { + sys_snode_t *head; + sys_snode_t *tail; +}; + +typedef struct _slist sys_slist_t; + +/** + * @brief Provide the primitive to iterate on a list + * Note: the loop is unsafe and thus __sn should not be removed + * + * User _MUST_ add the loop statement curly braces enclosing its own code: + * + * SYS_SLIST_FOR_EACH_NODE(l, n) { + * + * } + * + * @param __sl A pointer on a sys_slist_t to iterate on + * @param __sn A sys_snode_t pointer to peek each node of the list + */ +#define SYS_SLIST_FOR_EACH_NODE(__sl, __sn) \ + for (__sn = sys_slist_peek_head(__sl); __sn; \ + __sn = sys_slist_peek_next(__sn)) + +/** + * @brief Provide the primitive to iterate on a list, from a node in the list + * Note: the loop is unsafe and thus __sn should not be removed + * + * User _MUST_ add the loop statement curly braces enclosing its own code: + * + * SYS_SLIST_ITERATE_FROM_NODE(l, n) { + * + * } + * + * Like SYS_SLIST_FOR_EACH_NODE(), but __dn already contains a node in the list + * where to start searching for the next entry from. If NULL, it starts from + * the head. + * + * @param __sl A pointer on a sys_slist_t to iterate on + * @param __sn A sys_snode_t pointer to peek each node of the list + * it contains the starting node, or NULL to start from the head + */ +#define SYS_SLIST_ITERATE_FROM_NODE(__sl, __sn) \ + for (__sn = __sn ? sys_slist_peek_next_no_check(__sn) \ + : sys_slist_peek_head(__sl); \ + __sn; \ + __sn = sys_slist_peek_next(__sn)) + +/** + * @brief Provide the primitive to safely iterate on a list + * Note: __sn can be removed, it will not break the loop. + * + * User _MUST_ add the loop statement curly braces enclosing its own code: + * + * SYS_SLIST_FOR_EACH_NODE_SAFE(l, n, s) { + * + * } + * + * @param __sl A pointer on a sys_slist_t to iterate on + * @param __sn A sys_snode_t pointer to peek each node of the list + * @param __sns A sys_snode_t pointer for the loop to run safely + */ +#define SYS_SLIST_FOR_EACH_NODE_SAFE(__sl, __sn, __sns) \ + for (__sn = sys_slist_peek_head(__sl), \ + __sns = sys_slist_peek_next(__sn); \ + __sn; __sn = __sns, \ + __sns = sys_slist_peek_next(__sn)) + +/* + * @brief Provide the primitive to resolve the container of a list node + * Note: it is safe to use with NULL pointer nodes + * + * @param __ln A pointer on a sys_node_t to get its container + * @param __cn Container struct type pointer + * @param __n The field name of sys_node_t within the container struct + */ +#define SYS_SLIST_CONTAINER(__ln, __cn, __n) \ + (__ln ? CONTAINER_OF(__ln, __typeof__(*__cn), __n) : NULL) +/* + * @brief Provide the primitive to peek container of the list head + * + * @param __sl A pointer on a sys_slist_t to peek + * @param __cn Container struct type pointer + * @param __n The field name of sys_node_t within the container struct + */ +#define SYS_SLIST_PEEK_HEAD_CONTAINER(__sl, __cn, __n) \ + SYS_SLIST_CONTAINER(sys_slist_peek_head(__sl), __cn, __n) + +/* + * @brief Provide the primitive to peek the next container + * + * @param __cn Container struct type pointer + * @param __n The field name of sys_node_t within the container struct + */ + +#define SYS_SLIST_PEEK_NEXT_CONTAINER(__cn, __n) \ + (__cn ? SYS_SLIST_CONTAINER(sys_slist_peek_next(&(__cn->__n)), __cn, __n) : NULL) + +/** + * @brief Provide the primitive to iterate on a list under a container + * Note: the loop is unsafe and thus __cn should not be dettached + * + * User _MUST_ add the loop statement curly braces enclosing its own code: + * + * SYS_SLIST_FOR_EACH_CONTAINER(l, c, n) { + * + * } + * + * @param __sl A pointer on a sys_slist_t to iterate on + * @param __cn A pointer to peek each entry of the list + * @param __n The field name of sys_node_t within the container struct + */ +#define SYS_SLIST_FOR_EACH_CONTAINER(__sl, __cn, __n) \ + for (__cn = SYS_SLIST_PEEK_HEAD_CONTAINER(__sl, __cn, __n); __cn; \ + __cn = SYS_SLIST_PEEK_NEXT_CONTAINER(__cn, __n)) + +/** + * @brief Provide the primitive to safely iterate on a list under a container + * Note: __cn can be dettached, it will not break the loop. + * + * User _MUST_ add the loop statement curly braces enclosing its own code: + * + * SYS_SLIST_FOR_EACH_NODE_SAFE(l, c, cn, n) { + * + * } + * + * @param __sl A pointer on a sys_slist_t to iterate on + * @param __cn A pointer to peek each entry of the list + * @param __cns A pointer for the loop to run safely + * @param __n The field name of sys_node_t within the container struct + */ +#define SYS_SLIST_FOR_EACH_CONTAINER_SAFE(__sl, __cn, __cns, __n) \ + for (__cn = SYS_SLIST_PEEK_HEAD_CONTAINER(__sl, __cn, __n), \ + __cns = SYS_SLIST_PEEK_NEXT_CONTAINER(__cn, __n); __cn; \ + __cn = __cns, __cns = SYS_SLIST_PEEK_NEXT_CONTAINER(__cn, __n)) + +/** + * @brief Initialize a list + * + * @param list A pointer on the list to initialize + */ +static inline void sys_slist_init(sys_slist_t *list) +{ + list->head = NULL; + list->tail = NULL; +} + +#define SYS_SLIST_STATIC_INIT(ptr_to_list) {NULL, NULL} + +/** + * @brief Test if the given list is empty + * + * @param list A pointer on the list to test + * + * @return a boolean, true if it's empty, false otherwise + */ +static inline bool sys_slist_is_empty(sys_slist_t *list) +{ + return (!list->head); +} + +/** + * @brief Peek the first node from the list + * + * @param list A point on the list to peek the first node from + * + * @return A pointer on the first node of the list (or NULL if none) + */ +static inline sys_snode_t *sys_slist_peek_head(sys_slist_t *list) +{ + return list->head; +} + +/** + * @brief Peek the last node from the list + * + * @param list A point on the list to peek the last node from + * + * @return A pointer on the last node of the list (or NULL if none) + */ +static inline sys_snode_t *sys_slist_peek_tail(sys_slist_t *list) +{ + return list->tail; +} + +/** + * @brief Peek the next node from current node, node is not NULL + * + * Faster then sys_slist_peek_next() if node is known not to be NULL. + * + * @param node A pointer on the node where to peek the next node + * + * @return a pointer on the next node (or NULL if none) + */ +static inline sys_snode_t *sys_slist_peek_next_no_check(sys_snode_t *node) +{ + return node->next; +} + +/** + * @brief Peek the next node from current node + * + * @param node A pointer on the node where to peek the next node + * + * @return a pointer on the next node (or NULL if none) + */ +static inline sys_snode_t *sys_slist_peek_next(sys_snode_t *node) +{ + return node ? sys_slist_peek_next_no_check(node) : NULL; +} + +/** + * @brief Prepend a node to the given list + * + * @param list A pointer on the list to affect + * @param node A pointer on the node to prepend + */ +static inline void sys_slist_prepend(sys_slist_t *list, + sys_snode_t *node) +{ + node->next = list->head; + list->head = node; + + if (!list->tail) { + list->tail = list->head; + } +} + +/** + * @brief Append a node to the given list + * + * @param list A pointer on the list to affect + * @param node A pointer on the node to append + */ +static inline void sys_slist_append(sys_slist_t *list, + sys_snode_t *node) +{ + node->next = NULL; + + if (!list->tail) { + list->tail = node; + list->head = node; + } else { + list->tail->next = node; + list->tail = node; + } +} + +/** + * @brief Append a list to the given list + * + * Append a singly-linked, NULL-terminated list consisting of nodes containing + * the pointer to the next node as the first element of a node, to @a list. + * + * @param list A pointer on the list to affect + * @param head A pointer to the first element of the list to append + * @param tail A pointer to the last element of the list to append + */ +static inline void sys_slist_append_list(sys_slist_t *list, + void *head, void *tail) +{ + if (!list->tail) { + list->head = (sys_snode_t *)head; + list->tail = (sys_snode_t *)tail; + } else { + list->tail->next = (sys_snode_t *)head; + list->tail = (sys_snode_t *)tail; + } +} + +/** + * @brief merge two slists, appending the second one to the first + * + * When the operation is completed, the original list is empty. + * + * @param list A pointer on the list to affect + * @param list_to_append A pointer to the list to append. + */ +static inline void sys_slist_merge_slist(sys_slist_t *list, + sys_slist_t *list_to_append) +{ + sys_slist_append_list(list, list_to_append->head, + list_to_append->tail); + sys_slist_init(list); +} + +/** + * @brief Insert a node to the given list + * + * @param list A pointer on the list to affect + * @param prev A pointer on the previous node + * @param node A pointer on the node to insert + */ +static inline void sys_slist_insert(sys_slist_t *list, + sys_snode_t *prev, + sys_snode_t *node) +{ + if (!prev) { + sys_slist_prepend(list, node); + } else if (!prev->next) { + sys_slist_append(list, node); + } else { + node->next = prev->next; + prev->next = node; + } +} + +/** + * @brief Fetch and remove the first node of the given list + * + * List must be known to be non-empty. + * + * @param list A pointer on the list to affect + * + * @return A pointer to the first node of the list + */ +static inline sys_snode_t *sys_slist_get_not_empty(sys_slist_t *list) +{ + sys_snode_t *node = list->head; + + list->head = node->next; + if (list->tail == node) { + list->tail = list->head; + } + + return node; +} + +/** + * @brief Fetch and remove the first node of the given list + * + * @param list A pointer on the list to affect + * + * @return A pointer to the first node of the list (or NULL if empty) + */ +static inline sys_snode_t *sys_slist_get(sys_slist_t *list) +{ + return sys_slist_is_empty(list) ? NULL : sys_slist_get_not_empty(list); +} + +/** + * @brief Remove a node + * + * @param list A pointer on the list to affect + * @param prev_node A pointer on the previous node + * (can be NULL, which means the node is the list's head) + * @param node A pointer on the node to remove + */ +static inline void sys_slist_remove(sys_slist_t *list, + sys_snode_t *prev_node, + sys_snode_t *node) +{ + if (!prev_node) { + list->head = node->next; + + /* Was node also the tail? */ + if (list->tail == node) { + list->tail = list->head; + } + } else { + prev_node->next = node->next; + + /* Was node the tail? */ + if (list->tail == node) { + list->tail = prev_node; + } + } + + node->next = NULL; +} + +/** + * @brief Find and remove a node from a list + * + * @param list A pointer on the list to affect + * @param node A pointer on the node to remove from the list + */ +static inline void sys_slist_find_and_remove(sys_slist_t *list, + sys_snode_t *node) +{ + sys_snode_t *prev = NULL; + sys_snode_t *test; + + SYS_SLIST_FOR_EACH_NODE(list, test) { + if (test == node) { + sys_slist_remove(list, prev, node); + break; + } + + prev = test; + } +} + + +#ifdef __cplusplus +} +#endif + +#endif /* __SLIST_H__ */ diff --git a/kernel/protocols/bluetooth/core/include/misc/util.h b/kernel/protocols/bluetooth/core/include/misc/util.h new file mode 100644 index 0000000000..89ab4f070a --- /dev/null +++ b/kernel/protocols/bluetooth/core/include/misc/util.h @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2011-2014, Wind River Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Misc utilities + * + * Misc utilities usable by the kernel and application code. + */ + +#ifndef _UTIL__H_ +#define _UTIL__H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef _ASMLANGUAGE + +#include + +/* Helper to pass a int as a pointer or vice-versa. + * Those are available for 32 bits architectures: + */ +#define POINTER_TO_UINT(x) ((uint32_t) (x)) +#define UINT_TO_POINTER(x) ((void *) (x)) +#define POINTER_TO_INT(x) ((int32_t) (x)) +#define INT_TO_POINTER(x) ((void *) (x)) + +/* Evaluates to 0 if cond is true-ish; compile error otherwise */ +#define ZERO_OR_COMPILE_ERROR(cond) ((int) sizeof(char[1 - 2 * !(cond)]) - 1) + +/* Evaluates to 0 if array is an array; compile error if not array (e.g. + * pointer) + */ +#define IS_ARRAY(array) \ + ZERO_OR_COMPILE_ERROR( \ + !__builtin_types_compatible_p(__typeof__(array), \ + __typeof__(&(array)[0]))) + +/* Evaluates to number of elements in an array; compile error if not + * an array (e.g. pointer) + */ +#define ARRAY_SIZE(array) \ + ((unsigned long) (IS_ARRAY(array) + \ + (sizeof(array) / sizeof((array)[0])))) + +/* Evaluates to 1 if ptr is part of array, 0 otherwise; compile error if + * "array" argument is not an array (e.g. "ptr" and "array" mixed up) + */ +#define PART_OF_ARRAY(array, ptr) \ + ((ptr) && ((ptr) >= &array[0] && (ptr) < &array[ARRAY_SIZE(array)])) + +#define CONTAINER_OF(ptr, type, field) \ + ((type *)(((char *)(ptr)) - offsetof(type, field))) + +/* round "x" up/down to next multiple of "align" (which must be a power of 2) */ +#define ROUND_UP(x, align) \ + (((unsigned long)(x) + ((unsigned long)align - 1)) & \ + ~((unsigned long)align - 1)) +#define ROUND_DOWN(x, align) ((unsigned long)(x) & ~((unsigned long)align - 1)) + +#define ceiling_fraction(numerator, divider) \ + (((numerator) + ((divider) - 1)) / (divider)) + +#ifdef INLINED +#define INLINE inline +#else +#define INLINE +#endif + +#ifndef max +#define max(a, b) (((a) > (b)) ? (a) : (b)) +#endif + +#ifndef min +#define min(a, b) (((a) < (b)) ? (a) : (b)) +#endif + +static inline int is_power_of_two(unsigned int x) +{ + return (x != 0) && !(x & (x - 1)); +} + +static inline int64_t arithmetic_shift_right(int64_t value, uint8_t shift) +{ + int64_t sign_ext; + + if (shift == 0) { + return value; + } + + /* extract sign bit */ + sign_ext = (value >> 63) & 1; + + /* make all bits of sign_ext be the same as the value's sign bit */ + sign_ext = -sign_ext; + + /* shift value and fill opened bit positions with sign bit */ + return (value >> shift) | (sign_ext << (64 - shift)); +} + +#endif /* !_ASMLANGUAGE */ + +/* KB, MB, GB */ +#define KB(x) ((x) << 10) +#define MB(x) (KB(x) << 10) +#define GB(x) (MB(x) << 10) + +/* KHZ, MHZ */ +#define KHZ(x) ((x) * 1000) +#define MHZ(x) (KHZ(x) * 1000) + +#ifndef BIT +//#define BIT(n) (1UL << (n)) +#endif + +#define BIT_MASK(n) (BIT(n) - 1) + +/** + * @brief Check for macro definition in compiler-visible expressions + * + * This trick was pioneered in Linux as the config_enabled() macro. + * The madness has the effect of taking a macro value that may be + * defined to "1" (e.g. CONFIG_MYFEATURE), or may not be defined at + * all and turning it into a literal expression that can be used at + * "runtime". That is, it works similarly to + * "defined(CONFIG_MYFEATURE)" does except that it is an expansion + * that can exist in a standard expression and be seen by the compiler + * and optimizer. Thus much ifdef usage can be replaced with cleaner + * expressions like: + * + * if (IS_ENABLED(CONFIG_MYFEATURE)) + * myfeature_enable(); + * + * INTERNAL + * First pass just to expand any existing macros, we need the macro + * value to be e.g. a literal "1" at expansion time in the next macro, + * not "(1)", etc... Standard recursive expansion does not work. + */ +#define IS_ENABLED(config_macro) _IS_ENABLED1(config_macro) + +/* Now stick on a "_XXXX" prefix, it will now be "_XXXX1" if config_macro + * is "1", or just "_XXXX" if it's undefined. + * ENABLED: _IS_ENABLED2(_XXXX1) + * DISABLED _IS_ENABLED2(_XXXX) + */ +#define _IS_ENABLED1(config_macro) _IS_ENABLED2(_XXXX##config_macro) + +/* Here's the core trick, we map "_XXXX1" to "_YYYY," (i.e. a string + * with a trailing comma), so it has the effect of making this a + * two-argument tuple to the preprocessor only in the case where the + * value is defined to "1" + * ENABLED: _YYYY, <--- note comma! + * DISABLED: _XXXX + */ +#define _XXXX1 _YYYY, + +/* Then we append an extra argument to fool the gcc preprocessor into + * accepting it as a varargs macro. + * arg1 arg2 arg3 + * ENABLED: _IS_ENABLED3(_YYYY, 1, 0) + * DISABLED _IS_ENABLED3(_XXXX 1, 0) + */ +#define _IS_ENABLED2(one_or_two_args) _IS_ENABLED3(one_or_two_args 1, 0) + +/* And our second argument is thus now cooked to be 1 in the case + * where the value is defined to 1, and 0 if not: + */ +#define _IS_ENABLED3(ignore_this, val, ...) val + +#ifdef __cplusplus +} +#endif + +#endif /* _UTIL__H_ */ diff --git a/kernel/protocols/bluetooth/core/include/net/buf.h b/kernel/protocols/bluetooth/core/include/net/buf.h new file mode 100644 index 0000000000..c071f56492 --- /dev/null +++ b/kernel/protocols/bluetooth/core/include/net/buf.h @@ -0,0 +1,1002 @@ +/** @file + * @brief Buffer management. + */ + +/* + * Copyright (c) 2015 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef __NET_BUF_H +#define __NET_BUF_H + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Alignment needed for various parts of the buffer definition */ +#define __net_buf_align __aligned(sizeof(int)) + +/** @def NET_BUF_SIMPLE + * @brief Define a net_buf_simple stack variable and get a pointer to it. + * + * This is a helper macro which is used to define a net_buf_simple object on + * the stack and the get a pointer to it as follows: + * + * struct net_buf_simple *my_buf = NET_BUF_SIMPLE(10); + * + * After creating the object it needs to be initialized by calling + * net_buf_simple_init(). + * + * @param _size Maximum data storage for the buffer. + * + * @return Pointer to stack-allocated net_buf_simple object. + */ +#define NET_BUF_SIMPLE(_size) \ + ((struct net_buf_simple *)(&(struct { \ + struct net_buf_simple buf; \ + uint8_t data[_size] __net_buf_align; \ + }) { \ + .buf.size = _size, \ + })) + +/** @brief Simple network buffer representation. + * + * This is a simpler variant of the net_buf object (in fact net_buf uses + * net_buf_simple internally). It doesn't provide any kind of reference + * counting, user data, dynamic allocation, or in general the ability to + * pass through nano-kernel objects such as FIFOs. + * + * The main use of this is for scenarios where the meta-data of the normal + * net_buf isn't needed and causes too much overhead. This could be e.g. + * when the buffer only needs to be allocated on the stack or when the + * access to and lifetime of the buffer is well controlled and constrained. + * + */ +struct net_buf_simple { + /** Pointer to the start of data in the buffer. */ + uint8_t *data; + + /** Length of the data behind the data pointer. */ + uint16_t len; + + /** Amount of data that this buffer can store. */ + uint16_t size; + + /** Start of the data storage. Not to be accessed directly + * (the data pointer should be used instead). + */ + uint8_t __buf[0] __net_buf_align; +}; + +/** @brief Initialize a net_buf_simple object. + * + * This needs to be called after creating a net_buf_simple object e.g. using + * the NET_BUF_SIMPLE macro. + * + * @param buf Buffer to initialize. + * @param reserve_head Headroom to reserve. + */ +static inline void net_buf_simple_init(struct net_buf_simple *buf, + size_t reserve_head) +{ + buf->data = buf->__buf + reserve_head; + buf->len = 0; +} + +/** + * @brief Prepare data to be added at the end of the buffer + * + * Increments the data length of a buffer to account for more data + * at the end. + * + * @param buf Buffer to update. + * @param len Number of bytes to increment the length with. + * + * @return The original tail of the buffer. + */ +void *net_buf_simple_add(struct net_buf_simple *buf, size_t len); + +/** + * @brief Copy bytes from memory to the end of the buffer + * + * Copies the given number of bytes to the end of the buffer. Increments the + * data length of the buffer to account for more data at the end. + * + * @param buf Buffer to update. + * @param mem Location of data to be added. + * @param len Length of data to be added + * + * @return The original tail of the buffer. + */ +void *net_buf_simple_add_mem(struct net_buf_simple *buf, const void *mem, + size_t len); + +/** + * @brief Add (8-bit) byte at the end of the buffer + * + * Adds a byte at the end of the buffer. Increments the data length of + * the buffer to account for more data at the end. + * + * @param buf Buffer to update. + * @param val byte value to be added. + * + * @return Pointer to the value added + */ +uint8_t *net_buf_simple_add_u8(struct net_buf_simple *buf, uint8_t val); + +/** + * @brief Add 16-bit value at the end of the buffer + * + * Adds 16-bit value in little endian format at the end of buffer. + * Increments the data length of a buffer to account for more data + * at the end. + * + * @param buf Buffer to update. + * @param val 16-bit value to be added. + */ +void net_buf_simple_add_le16(struct net_buf_simple *buf, uint16_t val); + +/** + * @brief Add 16-bit value at the end of the buffer + * + * Adds 16-bit value in big endian format at the end of buffer. + * Increments the data length of a buffer to account for more data + * at the end. + * + * @param buf Buffer to update. + * @param val 16-bit value to be added. + */ +void net_buf_simple_add_be16(struct net_buf_simple *buf, uint16_t val); + +/** + * @brief Add 32-bit value at the end of the buffer + * + * Adds 32-bit value in little endian format at the end of buffer. + * Increments the data length of a buffer to account for more data + * at the end. + * + * @param buf Buffer to update. + * @param val 32-bit value to be added. + */ +void net_buf_simple_add_le32(struct net_buf_simple *buf, uint32_t val); + +/** + * @brief Add 32-bit value at the end of the buffer + * + * Adds 32-bit value in big endian format at the end of buffer. + * Increments the data length of a buffer to account for more data + * at the end. + * + * @param buf Buffer to update. + * @param val 32-bit value to be added. + */ +void net_buf_simple_add_be32(struct net_buf_simple *buf, uint32_t val); + +/** + * @brief Push data to the beginning of the buffer. + * + * Modifies the data pointer and buffer length to account for more data + * in the beginning of the buffer. + * + * @param buf Buffer to update. + * @param len Number of bytes to add to the beginning. + * + * @return The new beginning of the buffer data. + */ +void *net_buf_simple_push(struct net_buf_simple *buf, size_t len); + +/** + * @brief Push 16-bit value to the beginning of the buffer + * + * Adds 16-bit value in little endian format to the beginning of the + * buffer. + * + * @param buf Buffer to update. + * @param val 16-bit value to be pushed to the buffer. + */ +void net_buf_simple_push_le16(struct net_buf_simple *buf, uint16_t val); + +/** + * @brief Push 16-bit value to the beginning of the buffer + * + * Adds 16-bit value in big endian format to the beginning of the + * buffer. + * + * @param buf Buffer to update. + * @param val 16-bit value to be pushed to the buffer. + */ +void net_buf_simple_push_be16(struct net_buf_simple *buf, uint16_t val); + +/** + * @brief Push 8-bit value to the beginning of the buffer + * + * Adds 8-bit value the beginning of the buffer. + * + * @param buf Buffer to update. + * @param val 8-bit value to be pushed to the buffer. + */ +void net_buf_simple_push_u8(struct net_buf_simple *buf, uint8_t val); + +/** + * @brief Remove data from the beginning of the buffer. + * + * Removes data from the beginnig of the buffer by modifying the data + * pointer and buffer length. + * + * @param buf Buffer to update. + * @param len Number of bytes to remove. + * + * @return New beginning of the buffer data. + */ +void *net_buf_simple_pull(struct net_buf_simple *buf, size_t len); + +/** + * @brief Remove a 8-bit value from the beginning of the buffer + * + * Same idea as with net_buf_simple_pull(), but a helper for operating + * on 8-bit values. + * + * @param buf A valid pointer on a buffer. + * + * @return The 8-bit removed value + */ +uint8_t net_buf_simple_pull_u8(struct net_buf_simple *buf); + +/** + * @brief Remove and convert 16 bits from the beginning of the buffer. + * + * Same idea as with net_buf_simple_pull(), but a helper for operating + * on 16-bit little endian data. + * + * @param buf A valid pointer on a buffer. + * + * @return 16-bit value converted from little endian to host endian. + */ +uint16_t net_buf_simple_pull_le16(struct net_buf_simple *buf); + +/** + * @brief Remove and convert 16 bits from the beginning of the buffer. + * + * Same idea as with net_buf_simple_pull(), but a helper for operating + * on 16-bit big endian data. + * + * @param buf A valid pointer on a buffer. + * + * @return 16-bit value converted from big endian to host endian. + */ +uint16_t net_buf_simple_pull_be16(struct net_buf_simple *buf); + +/** + * @brief Remove and convert 32 bits from the beginning of the buffer. + * + * Same idea as with net_buf_simple_pull(), but a helper for operating + * on 32-bit little endian data. + * + * @param buf A valid pointer on a buffer. + * + * @return 32-bit value converted from little endian to host endian. + */ +uint32_t net_buf_simple_pull_le32(struct net_buf_simple *buf); + +/** + * @brief Remove and convert 32 bits from the beginning of the buffer. + * + * Same idea as with net_buf_simple_pull(), but a helper for operating + * on 32-bit big endian data. + * + * @param buf A valid pointer on a buffer. + * + * @return 32-bit value converted from big endian to host endian. + */ +uint32_t net_buf_simple_pull_be32(struct net_buf_simple *buf); + +/** + * @brief Get the tail pointer for a buffer. + * + * Get a pointer to the end of the data in a buffer. + * + * @param buf Buffer. + * + * @return Tail pointer for the buffer. + */ +static inline uint8_t *net_buf_simple_tail(struct net_buf_simple *buf) +{ + return buf->data + buf->len; +} + +/** + * @brief Check buffer headroom. + * + * Check how much free space there is in the beginning of the buffer. + * + * buf A valid pointer on a buffer + * + * @return Number of bytes available in the beginning of the buffer. + */ +size_t net_buf_simple_headroom(struct net_buf_simple *buf); + +/** + * @brief Check buffer tailroom. + * + * Check how much free space there is at the end of the buffer. + * + * @param buf A valid pointer on a buffer + * + * @return Number of bytes available at the end of the buffer. + */ +size_t net_buf_simple_tailroom(struct net_buf_simple *buf); + +/** + * @brief Parsing state of a buffer. + * + * This is used for temporarily storing the parsing state of a buffer + * while giving control of the parsing to a routine which we don't + * control. + */ +struct net_buf_simple_state { + /** Offset of the data pointer from the beginning of the storage */ + uint16_t offset; + /** Length of data */ + uint16_t len; +}; + +/** + * @brief Save the parsing state of a buffer. + * + * Saves the parsing state of a buffer so it can be restored later. + * + * @param buf Buffer from which the state should be saved. + * @param state Storage for the state. + */ +static inline void net_buf_simple_save(struct net_buf_simple *buf, + struct net_buf_simple_state *state) +{ + state->offset = net_buf_simple_headroom(buf); + state->len = buf->len; +} + +/** + * @brief Restore the parsing state of a buffer. + * + * Restores the parsing state of a buffer from a state previously stored + * by net_buf_simple_save(). + * + * @param buf Buffer to which the state should be restored. + * @param state Stored state. + */ +static inline void net_buf_simple_restore(struct net_buf_simple *buf, + struct net_buf_simple_state *state) +{ + buf->data = buf->__buf + state->offset; + buf->len = state->len; +} + +/** Flag indicating that the buffer has associated fragments. Only used + * internally by the buffer handling code while the buffer is inside a + * FIFO, meaning this never needs to be explicitly set or unset by the + * net_buf API user. As long as the buffer is outside of a FIFO, i.e. + * in practice always for the user for this API, the buf->frags pointer + * should be used instead. + */ +#define NET_BUF_FRAGS BIT(0) + +/** @brief Network buffer representation. + * + * This struct is used to represent network buffers. Such buffers are + * normally defined through the NET_BUF_POOL_DEFINE() API and allocated + * using the net_buf_alloc() API. + */ +struct net_buf { + union { + /** FIFO uses first 4 bytes itself, reserve space */ + int _unused; + + /** Fragments associated with this buffer. */ + struct net_buf *frags; + }; + + /** Reference count. */ + uint8_t ref; + + /** Bit-field of buffer flags. */ + uint8_t flags; + + /** Where the buffer should go when freed up. */ + struct net_buf_pool *pool; + + /* Union for convenience access to the net_buf_simple members, also + * preserving the old API. + */ + union { + /* The ABI of this struct must match net_buf_simple */ + struct { + /** Pointer to the start of data in the buffer. */ + uint8_t *data; + + /** Length of the data behind the data pointer. */ + uint16_t len; + + /** Amount of data that this buffer can store. */ + uint16_t size; + }; + + struct net_buf_simple b; + }; + + /** Start of the data storage. Not to be accessed directly + * (the data pointer should be used instead). + */ + uint8_t __buf[0] __net_buf_align; +}; + +struct net_buf_pool { + /** LIFO to place the buffer into when free */ + struct k_lifo free; + + /** Number of buffers in pool */ + const uint16_t buf_count; + + /** Number of uninitialized buffers */ + uint16_t uninit_count; + + /** Data size of each buffer in the pool */ + const uint16_t buf_size; + + /** Size of the user data associated with each buffer. */ + const uint16_t user_data_size; + +#if defined(CONFIG_NET_BUF_POOL_USAGE) + /** Amount of available buffers in the pool. */ + int16_t avail_count; + + /** Total size of the pool. */ + const uint16_t pool_size; + + /** Name of the pool. Used when printing pool information. */ + const char *name; +#endif /* CONFIG_NET_BUF_POOL_USAGE */ + + /** Optional destroy callback when buffer is freed. */ + void (*const destroy)(struct net_buf *buf); + + /** Helper to access the start of storage (for net_buf_pool_init) */ + struct net_buf * const __bufs; +}; + +#if defined(CONFIG_NET_BUF_POOL_USAGE) +#define NET_BUF_POOL_INITIALIZER(_pool, _bufs, _count, _size, _ud_size, \ + _destroy) \ + { \ + .__bufs = (struct net_buf *)_bufs, \ + .buf_count = _count, \ + .uninit_count = _count, \ + .avail_count = _count, \ + .pool_size = sizeof(_net_buf_pool_##_pool), \ + .buf_size = _size, \ + .user_data_size = _ud_size, \ + .destroy = _destroy, \ + .name = STRINGIFY(_pool), \ + } +#else +#define NET_BUF_POOL_INITIALIZER(_pool, _bufs, _count, _size, _ud_size, \ + _destroy) \ + { \ + .__bufs = (struct net_buf *)_bufs, \ + .buf_count = _count, \ + .uninit_count = _count, \ + .buf_size = _size, \ + .user_data_size = _ud_size, \ + .destroy = _destroy, \ + } +#endif /* CONFIG_NET_BUF_POOL_USAGE */ + +/** @def NET_BUF_POOL_DEFINE + * @brief Define a new pool for buffers + * + * Defines a net_buf_pool struct and the necessary memory storage (array of + * structs) for the needed amount of buffers. After this,the buffers can be + * accessed from the pool through net_buf_alloc. The pool is defined as a + * static variable, so if it needs to be exported outside the current module + * this needs to happen with the help of a separate pointer rather than an + * extern declaration. + * + * If provided with a custom destroy callback this callback is + * responsible for eventually calling net_buf_destroy() to complete the + * process of returning the buffer to the pool. + * + * @param _name Name of the pool variable. + * @param _count Number of buffers in the pool. + * @param _size Maximum data size for each buffer. + * @param _ud_size Amount of user data space to reserve. + * @param _destroy Optional destroy callback when buffer is freed. + */ +#define NET_BUF_POOL_DEFINE(_name, _count, _size, _ud_size, _destroy) \ + static struct { \ + struct net_buf buf; \ + uint8_t data[_size] __net_buf_align; \ + uint8_t ud[ROUND_UP(_ud_size, 4)] __net_buf_align; \ + } _net_buf_pool_##_name[_count] __noinit; \ + static void* _pool_msg_##_name[_count]; \ + static struct net_buf_pool _name = \ + NET_BUF_POOL_INITIALIZER(_name, _net_buf_pool_##_name, \ + _count, _size, _ud_size, _destroy) + +#define NET_BUF_POOL_INIT(_name)\ + k_lifo_init(&_name.free,#_name,(void **)&_pool_msg_##_name,_name.buf_count) + +/** + * @brief Allocate a new buffer from a pool. + * + * Allocate a new buffer from a pool. + * + * @param pool Which pool to allocate the buffer from. + * @param timeout Affects the action taken should the pool be empty. + * If K_NO_WAIT, then return immediately. If K_FOREVER, then + * wait as long as necessary. Otherwise, wait up to the specified + * number of milliseconds before timing out. + * + * @return New buffer or NULL if out of buffers. + */ +#if defined(CONFIG_NET_BUF_LOG) +struct net_buf *net_buf_alloc_debug(struct net_buf_pool *pool, int32_t timeout, + const char *func, int line); +#define net_buf_alloc(_pool, _timeout) \ + net_buf_alloc_debug(_pool, _timeout, __func__, __LINE__) +#else +struct net_buf *net_buf_alloc(struct net_buf_pool *pool, int32_t timeout); +#endif + +/** + * @brief Get a buffer from a FIFO. + * + * Get buffer from a FIFO. + * + * @param fifo Which FIFO to take the buffer from. + * @param timeout Affects the action taken should the FIFO be empty. + * If K_NO_WAIT, then return immediately. If K_FOREVER, then wait as + * long as necessary. Otherwise, wait up to the specified number of + * milliseconds before timing out. + * + * @return New buffer or NULL if the FIFO is empty. + */ +#if defined(CONFIG_NET_BUF_LOG) +struct net_buf *net_buf_get_debug(struct k_fifo *fifo, int32_t timeout, + const char *func, int line); +#define net_buf_get(_fifo, _timeout) \ + net_buf_get_debug(_fifo, _timeout, __func__, __LINE__) +#else +struct net_buf *net_buf_get(struct k_fifo *fifo, int32_t timeout); +#endif + +/** + * @brief Destroy buffer from custom destroy callback + * + * This helper is only intended to be used from custom destroy callbacks. + * If no custom destroy callback is given to NET_BUF_POOL_DEFINE() then + * there is no need to use this API. + * + * @param buf Buffer to destroy. + */ +static inline void net_buf_destroy(struct net_buf *buf) +{ + k_lifo_put(&buf->pool->free, buf); +} + +/** + * @brief Initialize buffer with the given headroom. + * + * Initializes a buffer with a given headroom. The buffer is not expected to + * contain any data when this API is called. + * + * @param buf Buffer to initialize. + * @param reserve How much headroom to reserve. + */ +void net_buf_reserve(struct net_buf *buf, size_t reserve); + +/** + * @brief Put a buffer into a FIFO + * + * Put a buffer to the end of a FIFO. If the buffer contains follow-up + * fragments this function will take care of inserting them as well + * into the FIFO. + * + * @param fifo Which FIFO to put the buffer to. + * @param buf Buffer. + */ +void net_buf_put(struct k_fifo *fifo, struct net_buf *buf); + +/** + * @brief Decrements the reference count of a buffer. + * + * Decrements the reference count of a buffer and puts it back into the + * pool if the count reaches zero. + * + * @param buf A valid pointer on a buffer + */ +#if defined(CONFIG_NET_BUF_LOG) +void net_buf_unref_debug(struct net_buf *buf, const char *func, int line); +#define net_buf_unref(_buf) \ + net_buf_unref_debug(_buf, __func__, __LINE__) +#else +void net_buf_unref(struct net_buf *buf); +#endif + +/** + * @brief Increment the reference count of a buffer. + * + * @param buf A valid pointer on a buffer + * + * @return the buffer newly referenced + */ +struct net_buf *net_buf_ref(struct net_buf *buf); + +/** + * @brief Duplicate buffer + * + * Duplicate given buffer including any data and headers currently stored. + * + * @param buf A valid pointer on a buffer + * @param timeout Affects the action taken should the pool be empty. + * If K_NO_WAIT, then return immediately. If K_FOREVER, then + * wait as long as necessary. Otherwise, wait up to the specified + * number of milliseconds before timing out. + * + * @return Duplicated buffer or NULL if out of buffers. + */ +struct net_buf *net_buf_clone(struct net_buf *buf, int32_t timeout); + +/** + * @brief Get a pointer to the user data of a buffer. + * + * @param buf A valid pointer on a buffer + * + * @return Pointer to the user data of the buffer. + */ +static inline void *net_buf_user_data(struct net_buf *buf) +{ + return (void *)ROUND_UP((buf->__buf + buf->size), sizeof(int)); +} + +/** + * @def net_buf_add + * @brief Prepare data to be added at the end of the buffer + * + * Increments the data length of a buffer to account for more data + * at the end. + * + * @param buf Buffer to update. + * @param len Number of bytes to increment the length with. + * + * @return The original tail of the buffer. + */ +#define net_buf_add(buf, len) net_buf_simple_add(&(buf)->b, len) + +/** + * @def net_buf_add_mem + * @brief Copy bytes from memory to the end of the buffer + * + * Copies the given number of bytes to the end of the buffer. Increments the + * data length of the buffer to account for more data at the end. + * + * @param buf Buffer to update. + * @param mem Location of data to be added. + * @param len Length of data to be added + * + * @return The original tail of the buffer. + */ +#define net_buf_add_mem(buf, mem, len) net_buf_simple_add_mem(&(buf)->b, \ + mem, len) + +/** + * @def net_buf_add_u8 + * @brief Add (8-bit) byte at the end of the buffer + * + * Adds a byte at the end of the buffer. Increments the data length of + * the buffer to account for more data at the end. + * + * @param buf Buffer to update. + * @param val byte value to be added. + * + * @return Pointer to the value added + */ +#define net_buf_add_u8(buf, val) net_buf_simple_add_u8(&(buf)->b, val) + +/** + * @def net_buf_add_le16 + * @brief Add 16-bit value at the end of the buffer + * + * Adds 16-bit value in little endian format at the end of buffer. + * Increments the data length of a buffer to account for more data + * at the end. + * + * @param buf Buffer to update. + * @param val 16-bit value to be added. + */ +#define net_buf_add_le16(buf, val) net_buf_simple_add_le16(&(buf)->b, val) + +/** + * @def net_buf_add_be16 + * @brief Add 16-bit value at the end of the buffer + * + * Adds 16-bit value in big endian format at the end of buffer. + * Increments the data length of a buffer to account for more data + * at the end. + * + * @param buf Buffer to update. + * @param val 16-bit value to be added. + */ +#define net_buf_add_be16(buf, val) net_buf_simple_add_be16(&(buf)->b, val) + +/** + * @def net_buf_add_le32 + * @brief Add 32-bit value at the end of the buffer + * + * Adds 32-bit value in little endian format at the end of buffer. + * Increments the data length of a buffer to account for more data + * at the end. + * + * @param buf Buffer to update. + * @param val 32-bit value to be added. + */ +#define net_buf_add_le32(buf, val) net_buf_simple_add_le32(&(buf)->b, val) + +/** + * @def net_buf_add_be32 + * @brief Add 32-bit value at the end of the buffer + * + * Adds 32-bit value in big endian format at the end of buffer. + * Increments the data length of a buffer to account for more data + * at the end. + * + * @param buf Buffer to update. + * @param val 32-bit value to be added. + */ +#define net_buf_add_be32(buf, val) net_buf_simple_add_be32(&(buf)->b, val) + +/** + * @def net_buf_push + * @brief Push data to the beginning of the buffer. + * + * Modifies the data pointer and buffer length to account for more data + * in the beginning of the buffer. + * + * @param buf Buffer to update. + * @param len Number of bytes to add to the beginning. + * + * @return The new beginning of the buffer data. + */ +#define net_buf_push(buf, len) net_buf_simple_push(&(buf)->b, len) + +/** + * @def net_buf_push_le16 + * @brief Push 16-bit value to the beginning of the buffer + * + * Adds 16-bit value in little endian format to the beginning of the + * buffer. + * + * @param buf Buffer to update. + * @param val 16-bit value to be pushed to the buffer. + */ +#define net_buf_push_le16(buf, val) net_buf_simple_push_le16(&(buf)->b, val) + +/** + * @def net_buf_push_be16 + * @brief Push 16-bit value to the beginning of the buffer + * + * Adds 16-bit value in little endian format to the beginning of the + * buffer. + * + * @param buf Buffer to update. + * @param val 16-bit value to be pushed to the buffer. + */ +#define net_buf_push_be16(buf, val) net_buf_simple_push_be16(&(buf)->b, val) + +/** + * @def net_buf_push_u8 + * @brief Push 8-bit value to the beginning of the buffer + * + * Adds 8-bit value the beginning of the buffer. + * + * @param buf Buffer to update. + * @param val 8-bit value to be pushed to the buffer. + */ +#define net_buf_push_u8(buf, val) net_buf_simple_push_u8(&(buf)->b, val) + +/** + * @def net_buf_pull + * @brief Remove data from the beginning of the buffer. + * + * Removes data from the beginnig of the buffer by modifying the data + * pointer and buffer length. + * + * @param buf Buffer to update. + * @param len Number of bytes to remove. + * + * @return New beginning of the buffer data. + */ +#define net_buf_pull(buf, len) net_buf_simple_pull(&(buf)->b, len) + +/** + * @def net_buf_pull_u8 + * @brief Remove a 8-bit value from the beginning of the buffer + * + * Same idea as with net_buf_pull(), but a helper for operating on + * 8-bit values. + * + * @param buf A valid pointer on a buffer. + * + * @return The 8-bit removed value + */ +#define net_buf_pull_u8(buf) net_buf_simple_pull_u8(&(buf)->b) + +/** + * @def net_buf_pull_le16 + * @brief Remove and convert 16 bits from the beginning of the buffer. + * + * Same idea as with net_buf_pull(), but a helper for operating on + * 16-bit little endian data. + * + * @param buf A valid pointer on a buffer. + * + * @return 16-bit value converted from little endian to host endian. + */ +#define net_buf_pull_le16(buf) net_buf_simple_pull_le16(&(buf)->b) + +/** + * @def net_buf_pull_be16 + * @brief Remove and convert 16 bits from the beginning of the buffer. + * + * Same idea as with net_buf_pull(), but a helper for operating on + * 16-bit big endian data. + * + * @param buf A valid pointer on a buffer. + * + * @return 16-bit value converted from big endian to host endian. + */ +#define net_buf_pull_be16(buf) net_buf_simple_pull_be16(&(buf)->b) + +/** + * @def net_buf_pull_le32 + * @brief Remove and convert 32 bits from the beginning of the buffer. + * + * Same idea as with net_buf_pull(), but a helper for operating on + * 32-bit little endian data. + * + * @param buf A valid pointer on a buffer. + * + * @return 32-bit value converted from little endian to host endian. + */ +#define net_buf_pull_le32(buf) net_buf_simple_pull_le32(&(buf)->b) + +/** + * @def net_buf_pull_be32 + * @brief Remove and convert 32 bits from the beginning of the buffer. + * + * Same idea as with net_buf_pull(), but a helper for operating on + * 32-bit big endian data. + * + * @param buf A valid pointer on a buffer + * + * @return 32-bit value converted from big endian to host endian. + */ +#define net_buf_pull_be32(buf) net_buf_simple_pull_be32(&(buf)->b) + +/** + * @def net_buf_tailroom + * @brief Check buffer tailroom. + * + * Check how much free space there is at the end of the buffer. + * + * @param buf A valid pointer on a buffer + * + * @return Number of bytes available at the end of the buffer. + */ +#define net_buf_tailroom(buf) net_buf_simple_tailroom(&(buf)->b) + +/** + * @def net_buf_headroom + * @brief Check buffer headroom. + * + * Check how much free space there is in the beginning of the buffer. + * + * buf A valid pointer on a buffer + * + * @return Number of bytes available in the beginning of the buffer. + */ +#define net_buf_headroom(buf) net_buf_simple_headroom(&(buf)->b) + +/** + * @def net_buf_tail + * @brief Get the tail pointer for a buffer. + * + * Get a pointer to the end of the data in a buffer. + * + * @param buf Buffer. + * + * @return Tail pointer for the buffer. + */ +#define net_buf_tail(buf) net_buf_simple_tail(&(buf)->b) + +/** @brief Find the last fragment in the fragment list. + * + * @return Pointer to last fragment in the list. + */ +struct net_buf *net_buf_frag_last(struct net_buf *frags); + +/** @brief Insert a new fragment to a chain of bufs. + * + * Insert a new fragment into the buffer fragments list after the parent. + * + * Note: This function takes ownership of the fragment reference so the + * caller is not required to unref. + * + * @param parent Parent buffer/fragment. + * @param frag Fragment to insert. + */ +void net_buf_frag_insert(struct net_buf *parent, struct net_buf *frag); + +/** @brief Add a new fragment to the end of a chain of bufs. + * + * Append a new fragment into the buffer fragments list. + * + * Note: This function takes ownership of the fragment reference so the + * caller is not required to unref. + * + * @param head Head of the fragment chain. + * @param frag Fragment to add. + * + * @return New head of the fragment chain. Either head (if head + * was non-NULL) or frag (if head was NULL). + */ +struct net_buf *net_buf_frag_add(struct net_buf *head, struct net_buf *frag); + +/** @brief Delete existing fragment from a chain of bufs. + * + * @param parent Parent buffer/fragment, or NULL if there is no parent. + * @param frag Fragment to delete. + * + * @return Pointer to the buffer following the fragment, or NULL if it + * had no further fragments. + */ +#if defined(CONFIG_NET_BUF_LOG) +struct net_buf *net_buf_frag_del_debug(struct net_buf *parent, + struct net_buf *frag, + const char *func, int line); +#define net_buf_frag_del(_parent, _frag) \ + net_buf_frag_del_debug(_parent, _frag, __func__, __LINE__) +#else +struct net_buf *net_buf_frag_del(struct net_buf *parent, struct net_buf *frag); +#endif + +/** @brief Calculate amount of bytes stored in fragments. + * + * Calculates the total amount of data stored in the given buffer and the + * fragments linked to it. + * + * @param buf Buffer to start off with. + * + * @return Number of bytes in the buffer and its fragments. + */ +static inline size_t net_buf_frags_len(struct net_buf *buf) +{ + size_t bytes = 0; + + while (buf) { + bytes += buf->len; + buf = buf->frags; + } + + return bytes; +} + +#ifdef __cplusplus +} +#endif + +#endif /* __NET_BUF_H */ diff --git a/kernel/protocols/bluetooth/core/include/timer.h b/kernel/protocols/bluetooth/core/include/timer.h new file mode 100644 index 0000000000..74492013ad --- /dev/null +++ b/kernel/protocols/bluetooth/core/include/timer.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#ifndef TIMER_H +#define TIMER_H + +#if defined(__cplusplus) +extern "C" +{ +#endif + +typedef void (* timeout_handler)(void *arg); + +struct mtimer { + struct mtimer *next; + uint32_t time; + timeout_handler h; + void *arg; +}; + +struct mtimer *mtimer_start(uint32_t msecs, timeout_handler handler, void *arg); + +void mtimer_stop(struct mtimer *t); + +void mtimer_mbox_fetch(k_mbox_t *mbox, void **msg); + +#ifdef __cplusplus +} +#endif + +#endif /* TIMER_H */ + diff --git a/kernel/protocols/bluetooth/core/include/work.h b/kernel/protocols/bluetooth/core/include/work.h new file mode 100644 index 0000000000..cf35ad10d3 --- /dev/null +++ b/kernel/protocols/bluetooth/core/include/work.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#ifndef WORK_H +#define WORK_H +#include "atomic.h" + +#if defined(__cplusplus) +extern "C" +{ +#endif + +struct k_work_q { + struct k_fifo fifo; +}; + +int k_work_q_start(const char *name, uint32_t *stack, uint32_t stack_size, int prio); + +enum { + K_WORK_STATE_PENDING, +}; +struct k_work; +/* work define*/ +typedef void (*k_work_handler_t)(struct k_work *work); +struct k_work { + k_work_handler_t handler; + atomic_t flags[1]; +}; + +int k_work_init(struct k_work *work, k_work_handler_t handler); +void k_work_submit(struct k_work *work); + +/*delay work define*/ +struct k_delayed_work { + struct k_work work; + struct k_work_q *work_q; + k_timer_t timer; +}; + +void k_delayed_work_init(struct k_delayed_work *work, k_work_handler_t handler); +int k_delayed_work_submit(struct k_delayed_work *work, uint32_t delay); +int k_delayed_work_cancel(struct k_delayed_work *work); + + +#ifdef __cplusplus +} +#endif + +#endif /* WORK_H */ + diff --git a/kernel/protocols/bluetooth/core/mbox.c b/kernel/protocols/bluetooth/core/mbox.c new file mode 100644 index 0000000000..eee1611939 --- /dev/null +++ b/kernel/protocols/bluetooth/core/mbox.c @@ -0,0 +1,272 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#include +#include +#include + +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_CORE) + +#include +#include "mbox.h" + +struct timer *g_timer_list; + +#if defined(__cplusplus) +extern "C" +{ +#endif + +int k_mbox_new(k_mbox_t **mb, int size) +{ + k_mbox_t *mbox; + UNUSED(size); + + mbox = (k_mbox_t *)malloc(sizeof(k_mbox_t)); + + if (mbox == NULL) { + return ERR_MEM; + } + + memset(mbox, 0, sizeof(k_mbox_t)); + + mbox->first = mbox->last = 0; + k_sem_init(&mbox->not_empty, 0, 0); + k_sem_init(&mbox->not_full, 0, 0); + k_sem_init(&mbox->mutex, 1, 1); + mbox->wait_send = 0; + + *mb = mbox; + BT_DBG("k_mbox_new: mbox 0x%lx\n", mbox); + return ERR_OK; +} + +/*-----------------------------------------------------------------------------------*/ +/* + Deallocates a mailbox. If there are messages still present in the + mailbox when the mailbox is deallocated, it is an indication of a + programming error in lwIP and the developer should be notified. +*/ +void k_mbox_free(k_mbox_t *mb) +{ + if (mb != NULL) { + k_mbox_t *mbox = mb; + + k_sem_take(&mbox->mutex, K_FOREVER); + + k_sem_delete(&mbox->not_empty); + k_sem_delete(&mbox->not_full); + k_sem_delete(&mbox->mutex); + BT_DBG("sys_mbox_free: mbox 0x%lx\n", mbox); + free(mbox); + } +} + +/*-----------------------------------------------------------------------------------*/ +/* + void sys_mbox_post(k_mbox_t *mbox, void *msg) + + Posts the "msg" to the mailbox. This function have to block until the "msg" is really posted. +*/ +void k_mbox_post(k_mbox_t *mb, void *msg) +{ + u8_t first; + k_mbox_t *mbox; + + if (NULL == mb) { + BT_ERR("invaild mbox"); + return; + } + + mbox = mb; + + k_sem_take(&mbox->mutex, K_FOREVER); + + BT_DBG("sys_mbox_post: mbox %p msg %p\n", (void *)mbox, (void *)msg); + + while ((mbox->last + 1) >= (mbox->first + K_MBOX_SIZE)) { + mbox->wait_send++; + k_sem_give(&mbox->mutex); + k_sem_take(&mbox->not_full, K_FOREVER); + k_sem_take(&mbox->mutex, K_FOREVER); + mbox->wait_send--; + } + + mbox->msgs[mbox->last % K_MBOX_SIZE] = msg; + + if (mbox->last == mbox->first) { + first = 1; + } else { + first = 0; + } + + mbox->last++; + + if (first) { + k_sem_give(&mbox->not_empty); + } + + k_sem_give(&mbox->mutex); +} + +/* + err_t k_mbox_trypost(k_mbox_t *mbox, void *msg) + + Try to post the "msg" to the mailbox. Returns ERR_MEM if this one is full, else, ERR_OK if the "msg" is posted. +*/ +int k_mbox_trypost(k_mbox_t *mb, void *msg) +{ + u8_t first; + k_mbox_t *mbox; + + if (NULL == mb) { + BT_ERR("invaild mbox"); + return ERR_MEM; + } + + mbox = mb; + + k_sem_take(&mbox->mutex, K_FOREVER); + + BT_DBG("k_mbox_trypost: mbox %p msg %p\n", (void *)mbox, (void *)msg); + + if ((mbox->last + 1) >= (mbox->first + K_MBOX_SIZE)) { + k_sem_give(&mbox->mutex); + return ERR_MEM; + } + + mbox->msgs[mbox->last % K_MBOX_SIZE] = msg; + + if (mbox->last == mbox->first) { + first = 1; + } else { + first = 0; + } + + mbox->last++; + + if (first) { + k_sem_give(&mbox->not_empty); + } + + k_sem_give(&mbox->mutex); + return ERR_OK; +} + +/*-----------------------------------------------------------------------------------*/ +/* + Blocks the thread until a message arrives in the mailbox, but does + not block the thread longer than "timeout" milliseconds (similar to + the sys_arch_sem_wait() function). The "msg" argument is a result + parameter that is set by the function (i.e., by doing "*msg = + ptr"). The "msg" parameter maybe NULL to indicate that the message + should be dropped. + + The return values are the same as for the sys_arch_sem_wait() function: + Number of milliseconds spent waiting or SYS_ARCH_TIMEOUT if there was a + timeout. + + Note that a function with a similar name, sys_mbox_fetch(), is + implemented by lwIP. +*/ +int k_mbox_fetch(k_mbox_t *mb, void **msg, uint32_t timeout) +{ + uint32_t time_needed = 0; + k_mbox_t *mbox; + + if (NULL == mb) { + BT_ERR("invaild mbox"); + return ERR_MEM; + } + + mbox = mb; + BT_DBG("mbox %p\n", mbox); + + /* The mutex lock is quick so we don't bother with the timeout + stuff here. */ + k_sem_take(&mbox->mutex, K_FOREVER); + + BT_DBG("mutex taken\n"); + + while (mbox->first == mbox->last) { + k_sem_give(&mbox->mutex); + + /* We block while waiting for a mail to arrive in the mailbox. We + must be prepared to timeout. */ + if (timeout != 0) { + time_needed = k_sem_take(&mbox->not_empty, timeout); + + if (time_needed == SYS_ARCH_TIMEOUT) { + return SYS_ARCH_TIMEOUT; + } + } else { + k_sem_take(&mbox->not_empty, K_FOREVER); + } + + k_sem_take(&mbox->mutex, K_FOREVER); + } + + if (msg != NULL) { + BT_DBG("sys_mbox_fetch: mbox %p msg %p\n", (void *)mbox, *msg); + *msg = mbox->msgs[mbox->first % K_MBOX_SIZE]; + } else { + BT_DBG("sys_mbox_fetch: mbox %p, null msg\n", (void *)mbox); + } + + mbox->first++; + + if (mbox->wait_send) { + k_sem_give(&mbox->not_full); + } + + k_sem_give(&mbox->mutex); + + return time_needed; +} + +/* + uint32_t sys_arch_mbox_tryfetch(k_mbox_t *mbox, void **msg) + + similar to sys_arch_mbox_fetch, however if a message is not present in the mailbox, + it immediately returns with the code SYS_MBOX_EMPTY. +*/ +int k_mbox_tryfetch(k_mbox_t *mb, void **msg) +{ + k_mbox_t *mbox; + + if (NULL == mb) { + BT_ERR("invaild mbox"); + return ERR_MEM; + } + + mbox = mb; + + k_sem_take(&mbox->mutex, K_FOREVER); + + if (mbox->first == mbox->last) { + k_sem_give(&mbox->mutex); + return SYS_MBOX_EMPTY; + } + + if (msg != NULL) { + BT_DBG("k_mbox_tryfetch: mbox %p msg %p\n", (void *)mbox, *msg); + *msg = mbox->msgs[mbox->first % K_MBOX_SIZE]; + } else { + BT_DBG("k_mbox_tryfetch: mbox %p, null msg\n", (void *)mbox); + } + + mbox->first++; + + if (mbox->wait_send) { + k_sem_give(&mbox->not_full); + } + + k_sem_give(&mbox->mutex); + + return 0; +} + +#if defined(__cplusplus) +} +#endif diff --git a/kernel/protocols/bluetooth/core/timer.c b/kernel/protocols/bluetooth/core/timer.c new file mode 100644 index 0000000000..e01bf40cb2 --- /dev/null +++ b/kernel/protocols/bluetooth/core/timer.c @@ -0,0 +1,169 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#include +#include "timer.h" +#include + +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_CORE) +#include + +struct mtimer *g_timer_list; + +#if defined(__cplusplus) +extern "C" +{ +#endif +#define LOCK_HCI_CORE() +#define UNLOCK_HCI_CORE() + +struct mtimer *mtimer_start(uint32_t msecs, timeout_handler handler, void *arg) +{ + struct mtimer *timer_new, *t; + + timer_new = (struct mtimer *)malloc(sizeof(struct mtimer)); + + if (timer_new == NULL) { + BT_ERR("timer maloc fail"); + return NULL; + } + +#if NO_SYS + now = sys_now(); + + if (next_timeout == NULL) { + diff = 0; + timeouts_last_time = now; + } else { + diff = now - timeouts_last_time; + } + +#endif + + timer_new->next = NULL; + timer_new->h = handler; + timer_new->arg = arg; + +#if NO_SYS + timer_new->time = msecs + diff; +#else + timer_new->time = msecs; +#endif + + if (g_timer_list == NULL) { + g_timer_list = timer_new; + return timer_new; + } + + if (g_timer_list->time > msecs) { + g_timer_list->time -= msecs; + timer_new->next = g_timer_list; + g_timer_list = timer_new; + } else { + for (t = g_timer_list; t != NULL; t = t->next) { + timer_new->time -= t->time; + + if (t->next == NULL || t->next->time > timer_new->time) { + if (t->next != NULL) { + t->next->time -= timer_new->time; + } + + timer_new->next = t->next; + t->next = timer_new; + break; + } + } + } + + return timer_new; +} + +void mtimer_stop(struct mtimer *timer) +{ + struct mtimer *prev_t, *t; + + if (g_timer_list == NULL) { + return; + } + + for (t = g_timer_list, prev_t = NULL; t != NULL; prev_t = t, t = t->next) { + if (t == timer) { + /* We have a match */ + /* Unlink from previous in list */ + if (prev_t == NULL) { + g_timer_list = t->next; + } else { + prev_t->next = t->next; + } + + /* If not the last one, add time of this one back to next */ + if (t->next != NULL) { + t->next->time += t->time; + } + + free(t); + return; + } + } + + return; +} + +void mtimer_mbox_fetch(k_mbox_t *mbox, void **msg) +{ + uint32_t time_needed; + struct mtimer *tmptimeout; + timeout_handler handler; + void *arg; + +again: + + if (!g_timer_list) { + time_needed = k_mbox_fetch(mbox, msg, 0); + } else { + if (g_timer_list->time > 0) { + time_needed = k_mbox_fetch(mbox, msg, g_timer_list->time); + } else { + time_needed = SYS_ARCH_TIMEOUT; + } + + if (time_needed == SYS_ARCH_TIMEOUT) { + /* If time == SYS_ARCH_TIMEOUT, a timeout occurred before a message + could be fetched. We should now call the timeout handler and + deallocate the memory allocated for the timeout. */ + tmptimeout = g_timer_list; + g_timer_list = tmptimeout->next; + handler = tmptimeout->h; + arg = tmptimeout->arg; + free(tmptimeout); + + if (handler != NULL) { + /*lock the core before calling the timeout handler function. */ + LOCK_HCI_CORE(); + handler(arg); + UNLOCK_HCI_CORE(); + } + + /* We try again to fetch a message from the mbox. */ + goto again; + } else { + if (!g_timer_list) { + return; + } + + /* If time != SYS_ARCH_TIMEOUT, a message was received before the timeout + occured. The time variable is set to the number of + milliseconds we waited for the message. */ + if (time_needed < g_timer_list->time) { + g_timer_list->time -= time_needed; + } else { + g_timer_list->time = 0; + } + } + } +} + +#if defined(__cplusplus) +} +#endif diff --git a/kernel/protocols/bluetooth/core/tinycrypt/Kconfig b/kernel/protocols/bluetooth/core/tinycrypt/Kconfig new file mode 100644 index 0000000000..92f042a805 --- /dev/null +++ b/kernel/protocols/bluetooth/core/tinycrypt/Kconfig @@ -0,0 +1,108 @@ +# Kconfig - Cryptography primitive options for TinyCrypt version 2.0 + +# +# Copyright (c) 2015 Intel Corporation +# +# SPDX-License-Identifier: Apache-2.0 +# + +config TINYCRYPT + bool + prompt "Cryptography Support" + default n + help + This option enables the TinyCrypt cryptography library. + +config TINYCRYPT_CTR_PRNG + bool + prompt "PRNG in counter mode" + depends on TINYCRYPT + default n + help + This option enables support for the pseudo-random number + generator in counter mode. + +config TINYCRYPT_SHA256 + bool + prompt "SHA-256 Hash function support" + depends on TINYCRYPT + default n + help + This option enables support for SHA-256 + hash function primitive. + +config TINYCRYPT_SHA256_HMAC + bool + prompt "HMAC (via SHA256) message auth support" + depends on TINYCRYPT_SHA256 + default n + help + This option enables support for HMAC using SHA-256 + message authentication code. + +config TINYCRYPT_SHA256_HMAC_PRNG + bool + prompt "PRNG (via HMAC-SHA256) support" + depends on TINYCRYPT_SHA256_HMAC + default n + help + This option enables support for pseudo-random number + generator. + +config TINYCRYPT_ECC_DH + bool + prompt "ECC_DH anonymous key agreement protocol" + depends on TINYCRYPT + default n + help + This option enables support for the Elliptic curve + Diffie-Hellman anonymous key agreement protocol. + +config TINYCRYPT_ECC_DSA + bool + prompt "ECC_DSA digital signature algorithm" + depends on TINYCRYPT + default n + help + This option enables support for the Elliptic Curve Digital + Signature Algorithm (ECDSA). + +config TINYCRYPT_AES + bool + prompt "AES-128 decrypt/encrypt" + depends on TINYCRYPT + default n + help + This option enables support for AES-128 decrypt and encrypt. + +config TINYCRYPT_AES_CBC + bool + prompt "AES-128 block cipher" + depends on TINYCRYPT_AES + default n + help + This option enables support for AES-128 block cipher mode. + +config TINYCRYPT_AES_CTR + bool + prompt "AES-128 counter mode" + depends on TINYCRYPT_AES + default n + help + This option enables support for AES-128 counter mode. + +config TINYCRYPT_AES_CCM + bool + prompt "AES-128 CCM mode" + depends on TINYCRYPT_AES + default n + help + This option enables support for AES-128 CCM mode. + +config TINYCRYPT_AES_CMAC + bool + prompt "AES-128 CMAC mode" + depends on TINYCRYPT_AES + default n + help + This option enables support for AES-128 CMAC mode. diff --git a/kernel/protocols/bluetooth/core/tinycrypt/README b/kernel/protocols/bluetooth/core/tinycrypt/README new file mode 100644 index 0000000000..bcf64ef289 --- /dev/null +++ b/kernel/protocols/bluetooth/core/tinycrypt/README @@ -0,0 +1,73 @@ +The TinyCrypt library in Zephyr is a downstream of an externally maintained +open source project. The original upstream code can be found at: + +https://github.com/01org/tinycrypt + +At revision c7b1dca2b27070dfb5f92e56dab7a91a7afee18c, version 0.2.5 + +Any changes to the local version should include Zephyr's TinyCrypt +maintainer in the review. That can be found via the git history. + +The following is the license information for this code: + +================================================================================ + + TinyCrypt Cryptographic Library + +================================================================================ + + Copyright (c) 2015, Intel Corporation. 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 the Intel Corporation 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 OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(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) 2013, Kenneth MacKay +All rights reserved. + +https://github.com/kmackay/micro-ecc + +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. + +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. + +================================================================================ diff --git a/kernel/protocols/bluetooth/core/tinycrypt/include/tinycrypt/aes.h b/kernel/protocols/bluetooth/core/tinycrypt/include/tinycrypt/aes.h new file mode 100644 index 0000000000..b6dbbb54f4 --- /dev/null +++ b/kernel/protocols/bluetooth/core/tinycrypt/include/tinycrypt/aes.h @@ -0,0 +1,133 @@ +/* aes.h - TinyCrypt interface to an AES-128 implementation */ + +/* + * Copyright (C) 2015 by Intel Corporation, 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 Intel Corporation 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 OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (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 -- Interface to an AES-128 implementation. + * + * Overview: AES-128 is a NIST approved block cipher specified in + * FIPS 197. Block ciphers are deterministic algorithms that + * perform a transformation specified by a symmetric key in fixed- + * length data sets, also called blocks. + * + * Security: AES-128 provides approximately 128 bits of security. + * + * Usage: 1) call tc_aes128_set_encrypt/decrypt_key to set the key. + * + * 2) call tc_aes_encrypt/decrypt to process the data. + */ + +#ifndef __TC_AES_H__ +#define __TC_AES_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define Nb (4) /* number of columns (32-bit words) comprising the state */ +#define Nk (4) /* number of 32-bit words comprising the key */ +#define Nr (10) /* number of rounds */ +#define TC_AES_BLOCK_SIZE (Nb*Nk) +#define TC_AES_KEY_SIZE (Nb*Nk) + +struct tc_aes_key_sched_struct { + uint32_t words[Nb*(Nr+1)]; +}; +typedef struct tc_aes_key_sched_struct *TCAesKeySched_t; + +/** + * @brief Set AES-128 encryption key + * Uses key k to initialize s + * @return returns TC_CRYPTO_SUCCESS (1) + * returns TC_CRYPTO_FAIL (0) if: s == NULL or k == NULL + * @note This implementation skips the additional steps required for keys + * larger than 128 bits, and must not be used for AES-192 or + * AES-256 key schedule -- see FIPS 197 for details + * @param s IN/OUT -- initialized struct tc_aes_key_sched_struct + * @param k IN -- points to the AES key + */ +int32_t tc_aes128_set_encrypt_key(TCAesKeySched_t s, const uint8_t *k); + +/** + * @brief AES-128 Encryption procedure + * Encrypts contents of in buffer into out buffer under key; + * schedule s + * @note Assumes s was initialized by aes_set_encrypt_key; + * out and in point to 16 byte buffers + * @return returns TC_CRYPTO_SUCCESS (1) + * returns TC_CRYPTO_FAIL (0) if: out == NULL or in == NULL or s == NULL + * @param out IN/OUT -- buffer to receive ciphertext block + * @param in IN -- a plaintext block to encrypt + * @param s IN -- initialized AES key schedule + */ +int32_t tc_aes_encrypt(uint8_t *out, + const uint8_t *in, + const TCAesKeySched_t s); + +/** + * @brief Set the AES-128 decryption key + * Uses key k to initialize s + * @return returns TC_CRYPTO_SUCCESS (1) + * returns TC_CRYPTO_FAIL (0) if: s == NULL or k == NULL + * @note This is the implementation of the straightforward inverse cipher + * using the cipher documented in FIPS-197 figure 12, not the + * equivalent inverse cipher presented in Figure 15 + * @warning This routine skips the additional steps required for keys larger + * than 128, and must not be used for AES-192 or AES-256 key + * schedule -- see FIPS 197 for details + * @param s IN/OUT -- initialized struct tc_aes_key_sched_struct + * @param k IN -- points to the AES key + */ +int32_t tc_aes128_set_decrypt_key(TCAesKeySched_t s, const uint8_t *k); + +/** + * @brief AES-128 Encryption procedure + * Decrypts in buffer into out buffer under key schedule s + * @return returns TC_CRYPTO_SUCCESS (1) + * returns TC_CRYPTO_FAIL (0) if: out is NULL or in is NULL or s is NULL + * @note Assumes s was initialized by aes_set_encrypt_key + * out and in point to 16 byte buffers + * @param out IN/OUT -- buffer to receive ciphertext block + * @param in IN -- a plaintext block to encrypt + * @param s IN -- initialized AES key schedule + */ +int32_t tc_aes_decrypt(uint8_t *out, + const uint8_t *in, + const TCAesKeySched_t s); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kernel/protocols/bluetooth/core/tinycrypt/include/tinycrypt/cbc_mode.h b/kernel/protocols/bluetooth/core/tinycrypt/include/tinycrypt/cbc_mode.h new file mode 100644 index 0000000000..74d2914254 --- /dev/null +++ b/kernel/protocols/bluetooth/core/tinycrypt/include/tinycrypt/cbc_mode.h @@ -0,0 +1,151 @@ +/* cbc_mode.h - TinyCrypt interface to a CBC mode implementation */ + +/* + * Copyright (C) 2015 by Intel Corporation, 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 Intel Corporation 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 OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (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 Interface to a CBC mode implementation. + * + * Overview: CBC (for "cipher block chaining") mode is a NIST approved mode of + * operation defined in SP 800-38a. It can be used with any block + * cipher to provide confidentiality of strings whose lengths are + * multiples of the block_size of the underlying block cipher. + * TinyCrypt hard codes AES as the block cipher. + * + * Security: CBC mode provides data confidentiality given that the maximum + * number q of blocks encrypted under a single key satisfies + * q < 2^63, which is not a practical constraint (it is considered a + * good practice to replace the encryption when q == 2^56). CBC mode + * provides NO data integrity. + * + * CBC mode assumes that the IV value input into the + * tc_cbc_mode_encrypt is randomly generated. The TinyCrypt library + * provides HMAC-PRNG module, which generates suitable IVs. Other + * methods for generating IVs are acceptable, provided that the + * values of the IVs generated appear random to any adversary, + * including someone with complete knowledge of the system design. + * + * The randomness property on which CBC mode's security depends is + * the unpredictability of the IV. Since it is unpredictable, this + * means in practice that CBC mode requires that the IV is stored + * somehow with the ciphertext in order to recover the plaintext. + * + * TinyCrypt CBC encryption prepends the IV to the ciphertext, + * because this affords a more efficient (few buffers) decryption. + * Hence tc_cbc_mode_encrypt assumes the ciphertext buffer is always + * 16 bytes larger than the plaintext buffer. + * + * Requires: AES-128 + * + * Usage: 1) call tc_cbc_mode_encrypt to encrypt data. + * + * 2) call tc_cbc_mode_decrypt to decrypt data. + * + */ + +#ifndef __TC_CBC_MODE_H__ +#define __TC_CBC_MODE_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief CBC encryption procedure + * CBC encrypts inlen bytes of the in buffer into the out buffer + * using the encryption key schedule provided, prepends iv to out + * @return returns TC_CRYPTO_SUCCESS (1) + * returns TC_CRYPTO_FAIL (0) if: + * out == NULL or + * in == NULL or + * ctr == NULL or + * sched == NULL or + * inlen == 0 or + * (inlen % TC_AES_BLOCK_SIZE) != 0 or + * (outlen % TC_AES_BLOCK_SIZE) != 0 or + * outlen != inlen + TC_AES_BLOCK_SIZE + * @note Assumes: - sched has been configured by aes_set_encrypt_key + * - iv contains a 16 byte random string + * - out buffer is large enough to hold the ciphertext + iv + * - out buffer is a contiguous buffer + * - in holds the plaintext and is a contiguous buffer + * - inlen gives the number of bytes in the in buffer + * @param out IN/OUT -- buffer to receive the ciphertext + * @param outlen IN -- length of ciphertext buffer in bytes + * @param in IN -- plaintext to encrypt + * @param inlen IN -- length of plaintext buffer in bytes + * @param iv IN -- the IV for the this encrypt/decrypt + * @param sched IN -- AES key schedule for this encrypt + */ +int32_t tc_cbc_mode_encrypt(uint8_t *out, uint32_t outlen, const uint8_t *in, + uint32_t inlen, const uint8_t *iv, + const TCAesKeySched_t sched); + +/** + * @brief CBC decryption procedure + * CBC decrypts inlen bytes of the in buffer into the out buffer + * using the provided encryption key schedule + * @return returns TC_CRYPTO_SUCCESS (1) + * returns TC_CRYPTO_FAIL (0) if: + * out == NULL or + * in == NULL or + * sched == NULL or + * inlen == 0 or + * outlen == 0 or + * (inlen % TC_AES_BLOCK_SIZE) != 0 or + * (outlen % TC_AES_BLOCK_SIZE) != 0 or + * outlen != inlen + TC_AES_BLOCK_SIZE + * @note Assumes:- in == iv + ciphertext, i.e. the iv and the ciphertext are + * contiguous. This allows for a very efficient decryption + * algorithm that would not otherwise be possible + * - sched was configured by aes_set_decrypt_key + * - out buffer is large enough to hold the decrypted plaintext + * and is a contiguous buffer + * - inlen gives the number of bytes in the in buffer + * @param out IN/OUT -- buffer to receive decrypted data + * @param outlen IN -- length of plaintext buffer in bytes + * @param in IN -- ciphertext to decrypt, including IV + * @param inlen IN -- length of ciphertext buffer in bytes + * @param iv IN -- the IV for the this encrypt/decrypt + * @param sched IN -- AES key schedule for this decrypt + * + */ +int32_t tc_cbc_mode_decrypt(uint8_t *out, uint32_t outlen, const uint8_t *in, + uint32_t inlen, const uint8_t *iv, + const TCAesKeySched_t sched); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kernel/protocols/bluetooth/core/tinycrypt/include/tinycrypt/ccm_mode.h b/kernel/protocols/bluetooth/core/tinycrypt/include/tinycrypt/ccm_mode.h new file mode 100644 index 0000000000..9fa5915f03 --- /dev/null +++ b/kernel/protocols/bluetooth/core/tinycrypt/include/tinycrypt/ccm_mode.h @@ -0,0 +1,201 @@ +/* ccm_mode.h - TinyCrypt interface to a CCM mode implementation */ + +/* + * Copyright (C) 2015 by Intel Corporation, 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 Intel Corporation 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 OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (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 Interface to a CCM mode implementation. + * + * Overview: CCM (for "Counter with CBC-MAC") mode is a NIST approved mode of + * operation defined in SP 800-38C. + * + * TinyCrypt CCM implementation accepts: + * + * 1) Both non-empty payload and associated data (it encrypts and + * authenticates the payload and also authenticates the associated + * data); + * 2) Non-empty payload and empty associated data (it encrypts and + * authenticates the payload); + * 3) Non-empty associated data and empty payload (it degenerates to + * an authentication mode on the associated data). + * + * TinyCrypt CCM implementation accepts associated data of any length + * between 0 and (2^16 - 2^8) bytes. + * + * Security: The mac length parameter is an important parameter to estimate the + * security against collision attacks (that aim at finding different + * messages that produce the same authentication tag). TinyCrypt CCM + * implementation accepts any even integer between 4 and 16, as + * suggested in SP 800-38C. + * + * RFC-3610, which also specifies CCM, presents a few relevant + * security suggestions, such as: it is recommended for most + * applications to use a mac length greater than 8. Besides, the + * usage of the same nonce for two different messages which are + * encrypted with the same key destroys the security of CCM mode. + * + * Requires: AES-128 + * + * Usage: 1) call tc_ccm_config to configure. + * + * 2) call tc_ccm_mode_encrypt to encrypt data and generate tag. + * + * 3) call tc_ccm_mode_decrypt to decrypt data and verify tag. + */ + +#ifndef __TC_CCM_MODE_H__ +#define __TC_CCM_MODE_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* max additional authenticated size in bytes: 2^16 - 2^8 = 65280 */ +#define TC_CCM_AAD_MAX_BYTES 0xff00 + +/* max message size in bytes: 2^(8L) = 2^16 = 65536 */ +#define TC_CCM_PAYLOAD_MAX_BYTES 0x10000 + +/* struct tc_ccm_mode_struct represents the state of a CCM computation */ +typedef struct tc_ccm_mode_struct { + TCAesKeySched_t sched; /* AES key schedule */ + uint8_t *nonce; /* nonce required by CCM */ + uint32_t mlen; /* mac length in bytes (parameter t in SP-800 38C) */ +} *TCCcmMode_t; + +/** + * @brief CCM configuration procedure + * @return returns TC_CRYPTO_SUCCESS (1) + * returns TC_CRYPTO_FAIL (0) if: + * c == NULL or + * sched == NULL or + * nonce == NULL or + * mlen != {4, 6, 8, 10, 12, 16} + * @param c -- CCM state + * @param sched IN -- AES key schedule + * @param nonce IN - nonce + * @param nlen -- nonce length in bytes + * @param mlen -- mac length in bytes (parameter t in SP-800 38C) + */ +int32_t tc_ccm_config(TCCcmMode_t c, TCAesKeySched_t sched, uint8_t *nonce, + uint32_t nlen, uint32_t mlen); + +/** + * @brief CCM tag generation and encryption procedure + * @return returns TC_CRYPTO_SUCCESS (1) + * returns TC_CRYPTO_FAIL (0) if: + * out == NULL or + * c == NULL or + * ((plen > 0) and (payload == NULL)) or + * ((alen > 0) and (associated_data == NULL)) or + * (alen >= TC_CCM_AAD_MAX_BYTES) or + * (plen >= TC_CCM_PAYLOAD_MAX_BYTES) + * + * @param out OUT -- encrypted data + * @param associated_data IN -- associated data + * @param alen IN -- associated data length in bytes + * @param payload IN -- payload + * @param plen IN -- payload length in bytes + * @param c IN -- CCM state + * + * @note: The sequence b for encryption is formatted as follows: + * b = [FLAGS | nonce | counter ], where: + * FLAGS is 1 byte long + * nonce is 13 bytes long + * counter is 2 bytes long + * The byte FLAGS is composed by the following 8 bits: + * 0-2 bits: used to represent the value of q-1 + * 3-7 btis: always 0's + * + * @note: The sequence b for authentication is formatted as follows: + * b = [FLAGS | nonce | length(mac length)], where: + * FLAGS is 1 byte long + * nonce is 13 bytes long + * length(mac length) is 2 bytes long + * The byte FLAGS is composed by the following 8 bits: + * 0-2 bits: used to represent the value of q-1 + * 3-5 bits: mac length (encoded as: (mlen-2)/2) + * 6: Adata (0 if alen == 0, and 1 otherwise) + * 7: always 0 + */ +int32_t tc_ccm_generation_encryption(uint8_t *out, const uint8_t *associated_data, + uint32_t alen, const uint8_t *payload, + uint32_t plen, TCCcmMode_t c); + +/** + * @brief CCM decryption and tag verification procedure + * @return returns TC_CRYPTO_SUCCESS (1) + * returns TC_CRYPTO_FAIL (0) if: + * out == NULL or + * c == NULL or + * ((plen > 0) and (payload == NULL)) or + * ((alen > 0) and (associated_data == NULL)) or + * (alen >= TC_CCM_AAD_MAX_BYTES) or + * (plen >= TC_CCM_PAYLOAD_MAX_BYTES) + * + * @param out OUT -- decrypted data + * @param associated_data IN -- associated data + * @param alen IN -- associated data length in bytes + * @param payload IN -- payload + * @param plen IN -- payload length in bytes + * @param c IN -- CCM state + * + * @note: The sequence b for encryption is formatted as follows: + * b = [FLAGS | nonce | counter ], where: + * FLAGS is 1 byte long + * nonce is 13 bytes long + * counter is 2 bytes long + * The byte FLAGS is composed by the following 8 bits: + * 0-2 bits: used to represent the value of q-1 + * 3-7 btis: always 0's + * + * @note: The sequence b for authentication is formatted as follows: + * b = [FLAGS | nonce | length(mac length)], where: + * FLAGS is 1 byte long + * nonce is 13 bytes long + * length(mac length) is 2 bytes long + * The byte FLAGS is composed by the following 8 bits: + * 0-2 bits: used to represent the value of q-1 + * 3-5 bits: mac length (encoded as: (mlen-2)/2) + * 6: Adata (0 if alen == 0, and 1 otherwise) + * 7: always 0 + */ +int32_t tc_ccm_decryption_verification(uint8_t *out, const uint8_t *associated_data, + uint32_t alen, const uint8_t *payload, uint32_t plen, + TCCcmMode_t c); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kernel/protocols/bluetooth/core/tinycrypt/include/tinycrypt/cmac_mode.h b/kernel/protocols/bluetooth/core/tinycrypt/include/tinycrypt/cmac_mode.h new file mode 100644 index 0000000000..9d3f13051d --- /dev/null +++ b/kernel/protocols/bluetooth/core/tinycrypt/include/tinycrypt/cmac_mode.h @@ -0,0 +1,194 @@ +/* cmac_mode.h -- interface to a CMAC implementation */ + +/* + * Copyright (C) 2015 by Intel Corporation, 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 Intel Corporation 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 OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (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 Interface to a CMAC implementation. + * + * Overview: CMAC is defined NIST in SP 800-38B, and is the standard algorithm + * for computing a MAC using a block cipher. It can compute the MAC + * for a byte string of any length. It is distinguished from CBC-MAC + * in the processing of the final message block; CMAC uses a + * different technique to compute the final message block is full + * size or only partial, while CBC-MAC uses the same technique for + * both. This difference permits CMAC to be applied to variable + * length messages, while all messages authenticated by CBC-MAC must + * be the same length. + * + * Security: AES128-CMAC mode of operation offers 64 bits of security against + * collision attacks. Note however that an external attacker cannot + * generate the tags him/herself without knowing the MAC key. In this + * sense, to attack the collision property of AES128-CMAC, an + * external attacker would need the cooperation of the legal user to + * produce an exponentially high number of tags (e.g. 2^64) to + * finally be able to look for collisions and benefit from them. As + * an extra precaution, the current implementation allows to at most + * 2^48 calls to the tc_cmac_update function before re-calling + * tc_cmac_setup (allowing a new key to be set), as suggested in + * Appendix B of SP 800-38B. + * + * Requires: AES-128 + * + * Usage: This implementation provides a "scatter-gather" interface, so that + * the CMAC value can be computed incrementally over a message + * scattered in different segments throughout memory. Experience shows + * this style of interface tends to minimize the burden of programming + * correctly. Like all symmetric key operations, it is session + * oriented. + * + * To begin a CMAC session, use tc_cmac_setup to initialize a struct + * tc_cmac_struct with encryption key and buffer. Our implementation + * always assume that the AES key to be the same size as the block + * cipher block size. Once setup, this data structure can be used for + * many CMAC computations. + * + * Once the state has been setup with a key, computing the CMAC of + * some data requires three steps: + * + * (1) first use tc_cmac_init to initialize a new CMAC computation. + * (2) next mix all of the data into the CMAC computation state using + * tc_cmac_update. If all of the data resides in a single data + * segment then only one tc_cmac_update call is needed; if data + * is scattered throughout memory in n data segments, then n calls + * will be needed. CMAC IS ORDER SENSITIVE, to be able to detect + * attacks that swap bytes, so the order in which data is mixed + * into the state is critical! + * (3) Once all of the data for a message has been mixed, use + * tc_cmac_final to compute the CMAC tag value. + * + * Steps (1)-(3) can be repeated as many times as you want to CMAC + * multiple messages. A practical limit is 2^48 1K messages before you + * have to change the key. + * + * Once you are done computing CMAC with a key, it is a good idea to + * destroy the state so an attacker cannot recover the key; use + * tc_cmac_erase to accomplish this. + */ + +#ifndef __TC_CMAC_MODE_H__ +#define __TC_CMAC_MODE_H__ + +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* padding for last message block */ +#define TC_CMAC_PADDING 0x80 + +/* struct tc_cmac_struct represents the state of a CMAC computation */ +typedef struct tc_cmac_struct { +/* initialization vector */ + uint8_t iv[TC_AES_BLOCK_SIZE]; +/* used if message length is a multiple of block_size bytes */ + uint8_t K1[TC_AES_BLOCK_SIZE]; +/* used if message length isn't a multiple block_size bytes */ + uint8_t K2[TC_AES_BLOCK_SIZE]; +/* where to put bytes that didn't fill a block */ + uint8_t leftover[TC_AES_BLOCK_SIZE]; +/* identifies the encryption key */ + uint32_t keyid; +/* next available leftover location */ + uint32_t leftover_offset; +/* AES key schedule */ + TCAesKeySched_t sched; +/* calls to tc_cmac_update left before re-key */ + uint64_t countdown; +} *TCCmacState_t; + +/** + * @brief Configures the CMAC state to use the given AES key + * @return returns TC_CRYPTO_SUCCESS (1) after having configured the CMAC state + * returns TC_CRYPTO_FAIL (0) if: + * s == NULL or + * key == NULL + * + * @param s IN/OUT -- the state to set up + * @param key IN -- the key to use + * @param sched IN -- AES key schedule + */ +int32_t tc_cmac_setup(TCCmacState_t s, const uint8_t *key, + TCAesKeySched_t sched); + +/** + * @brief Erases the CMAC state + * @return returns TC_CRYPTO_SUCCESS (1) after having configured the CMAC state + * returns TC_CRYPTO_FAIL (0) if: + * s == NULL + * + * @param s IN/OUT -- the state to erase + */ +int32_t tc_cmac_erase(TCCmacState_t s); + +/** + * @brief Initializes a new CMAC computation + * @return returns TC_CRYPTO_SUCCESS (1) after having initialized the CMAC state + * returns TC_CRYPTO_FAIL (0) if: + * s == NULL + * + * @param s IN/OUT -- the state to initialize + */ +int32_t tc_cmac_init(TCCmacState_t s); + +/** + * @brief Incrementally computes CMAC over the next data segment + * @return returns TC_CRYPTO_SUCCESS (1) after successfully updating the CMAC state + * returns TC_CRYPTO_FAIL (0) if: + * s == NULL or + * if data == NULL when dlen > 0 + * + * @param s IN/OUT -- the CMAC state + * @param data IN -- the next data segment to MAC + * @param dlen IN -- the length of data in bytes + */ +int32_t tc_cmac_update(TCCmacState_t s, const uint8_t *data, size_t dlen); + +/** + * @brief Generates the tag from the CMAC state + * @return returns TC_CRYPTO_SUCCESS (1) after successfully generating the tag + * returns TC_CRYPTO_FAIL (0) if: + * tag == NULL or + * s == NULL + * + * @param tag OUT -- the CMAC tag + * @param s IN -- CMAC state + */ +int32_t tc_cmac_final(uint8_t *tag, TCCmacState_t s); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kernel/protocols/bluetooth/core/tinycrypt/include/tinycrypt/constants.h b/kernel/protocols/bluetooth/core/tinycrypt/include/tinycrypt/constants.h new file mode 100644 index 0000000000..1a7c9df367 --- /dev/null +++ b/kernel/protocols/bluetooth/core/tinycrypt/include/tinycrypt/constants.h @@ -0,0 +1,59 @@ +/* constants.h - TinyCrypt interface to constants */ + +/* + * Copyright (C) 2015 by Intel Corporation, 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 Intel Corporation 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 OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (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 -- Interface to constants. + * + */ + +#ifndef __TC_CONSTANTS_H__ +#define __TC_CONSTANTS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef NULL +#define NULL ((void *)0) +#endif + +#define TC_CRYPTO_SUCCESS 1 +#define TC_CRYPTO_FAIL 0 + +#define TC_ZERO_BYTE 0x00 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kernel/protocols/bluetooth/core/tinycrypt/include/tinycrypt/ctr_mode.h b/kernel/protocols/bluetooth/core/tinycrypt/include/tinycrypt/ctr_mode.h new file mode 100644 index 0000000000..5f7766ddc6 --- /dev/null +++ b/kernel/protocols/bluetooth/core/tinycrypt/include/tinycrypt/ctr_mode.h @@ -0,0 +1,108 @@ +/* ctr_mode.h - TinyCrypt interface to CTR mode */ + +/* + * Copyright (C) 2015 by Intel Corporation, 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 Intel Corporation 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 OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (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 Interface to CTR mode. + * + * Overview: CTR (pronounced "counter") mode is a NIST approved mode of + * operation defined in SP 800-38a. It can be used with any + * block cipher to provide confidentiality of strings of any + * length. TinyCrypt hard codes AES128 as the block cipher. + * + * Security: CTR mode achieves confidentiality only if the counter value is + * never reused with a same encryption key. If the counter is + * repeated, than an adversary might be able to defeat the scheme. + * + * A usual method to ensure different counter values refers to + * initialize the counter in a given value (0, for example) and + * increases it every time a new block is enciphered. This naturally + * leaves to a limitation on the number q of blocks that can be + * enciphered using a same key: q < 2^(counter size). + * + * TinyCrypt uses a counter of 32 bits. This means that after 2^32 + * block encryptions, the counter will be reused (thus losing CBC + * security). 2^32 block encryptions should be enough for most of + * applications targeting constrained devices. Applications intended + * to encrypt a larger number of blocks must replace the key after + * 2^32 block encryptions. + * + * CTR mode provides NO data integrity. + * + * Requires: AES-128 + * + * Usage: 1) call tc_ctr_mode to process the data to encrypt/decrypt. + * + */ + +#ifndef __TC_CTR_MODE_H__ +#define __TC_CTR_MODE_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief CTR mode encryption/decryption procedure. + * CTR mode encrypts (or decrypts) inlen bytes from in buffer into out buffer + * @return returns TC_CRYPTO_SUCCESS (1) + * returns TC_CRYPTO_FAIL (0) if: + * out == NULL or + * in == NULL or + * ctr == NULL or + * sched == NULL or + * inlen == 0 or + * outlen == 0 or + * inlen != outlen + * @note Assumes:- The current value in ctr has NOT been used with sched + * - out points to inlen bytes + * - in points to inlen bytes + * - ctr is an integer counter in littleEndian format + * - sched was initialized by aes_set_encrypt_key + * @param out OUT -- produced ciphertext (plaintext) + * @param outlen IN -- length of ciphertext buffer in bytes + * @param in IN -- data to encrypt (or decrypt) + * @param inlen IN -- length of input data in bytes + * @param ctr IN/OUT -- the current counter value + * @param sched IN -- an initialized AES key schedule + */ +int32_t tc_ctr_mode(uint8_t *out, uint32_t outlen, const uint8_t *in, + uint32_t inlen, uint8_t *ctr, const TCAesKeySched_t sched); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kernel/protocols/bluetooth/core/tinycrypt/include/tinycrypt/ctr_prng.h b/kernel/protocols/bluetooth/core/tinycrypt/include/tinycrypt/ctr_prng.h new file mode 100644 index 0000000000..409d9ded34 --- /dev/null +++ b/kernel/protocols/bluetooth/core/tinycrypt/include/tinycrypt/ctr_prng.h @@ -0,0 +1,167 @@ +/* ctr_prng.h - TinyCrypt interface to a CTR-PRNG implementation */ + +/* + * Copyright (c) 2016, Chris Morrison + * 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. + * + * 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. + */ + +/** + * @file + * @brief Interface to a CTR-PRNG implementation. + * + * Overview: A pseudo-random number generator (PRNG) generates a sequence + * of numbers that have a distribution close to the one expected + * for a sequence of truly random numbers. The NIST Special + * Publication 800-90A specifies several mechanisms to generate + * sequences of pseudo random numbers, including the CTR-PRNG one + * which is based on AES. TinyCrypt implements CTR-PRNG with + * AES-128. + * + * Security: A cryptographically secure PRNG depends on the existence of an + * entropy source to provide a truly random seed as well as the + * security of the primitives used as the building blocks (AES-128 + * in this instance). + * + * Requires: - AES-128 + * + * Usage: 1) call tc_ctr_prng_init to seed the prng context + * + * 2) call tc_ctr_prng_reseed to mix in additional entropy into + * the prng context + * + * 3) call tc_ctr_prng_generate to output the pseudo-random data + * + * 4) call tc_ctr_prng_uninstantiate to zero out the prng context + */ + +#ifndef __TC_CTR_PRNG_H__ +#define __TC_CTR_PRNG_H__ + +#include + +#define TC_CTR_PRNG_RESEED_REQ -1 + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct +{ + /* updated each time another BLOCKLEN_BYTES bytes are produced */ + uint8_t V[TC_AES_BLOCK_SIZE]; + + /* updated whenever the PRNG is reseeded */ + struct tc_aes_key_sched_struct key; + + /* number of requests since initialization/reseeding */ + uint64_t reseedCount; +} TCCtrPrng_t; + + +/** + * @brief CTR-PRNG initialization procedure + * Initializes prng context with entropy and personalization string (if any) + * @return returns TC_CRYPTO_SUCCESS (1) + * returns TC_CRYPTO_FAIL (0) if: + * ctx == NULL, + * entropy == NULL, + * entropyLen < (TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE) + * @note Only the first (TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE) bytes of + * both the entropy and personalization inputs are used - + * supplying additional bytes has no effect. + * @param ctx IN/OUT -- the PRNG context to initialize + * @param entropy IN -- entropy used to seed the PRNG + * @param entropyLen IN -- entropy length in bytes + * @param personalization IN -- personalization string used to seed the PRNG + * (may be null) + * @param pLen IN -- personalization length in bytes + * + */ +int32_t tc_ctr_prng_init(TCCtrPrng_t * const ctx, + uint8_t const * const entropy, + uint32_t entropyLen, + uint8_t const * const personalization, + uint32_t pLen); + +/** + * @brief CTR-PRNG reseed procedure + * Mixes entropy and additional_input into the prng context + * @return returns TC_CRYPTO_SUCCESS (1) + * returns TC_CRYPTO_FAIL (0) if: + * ctx == NULL, + * entropy == NULL, + * entropylen < (TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE) + * @note It is better to reseed an existing prng context rather than + * re-initialise, so that any existing entropy in the context is + * presereved. This offers some protection against undetected failures + * of the entropy source. + * @note Assumes tc_ctr_prng_init has been called for ctx + * @param ctx IN/OUT -- the PRNG state + * @param entropy IN -- entropy to mix into the prng + * @param entropyLen IN -- length of entropy in bytes + * @param additional_input IN -- additional input to the prng (may be null) + * @param additionallen IN -- additional input length in bytes + */ +int32_t tc_ctr_prng_reseed(TCCtrPrng_t * const ctx, + uint8_t const * const entropy, + uint32_t entropyLen, + uint8_t const * const additional_input, + uint32_t additionallen); + +/** + * @brief CTR-PRNG generate procedure + * Generates outlen pseudo-random bytes into out buffer, updates prng + * @return returns TC_CRYPTO_SUCCESS (1) + * returns TC_CTR_PRNG_RESEED_REQ (-1) if a reseed is needed + * returns TC_CRYPTO_FAIL (0) if: + * ctx == NULL, + * out == NULL, + * outlen >= 2^16 + * @note Assumes tc_ctr_prng_init has been called for ctx + * @param ctx IN/OUT -- the PRNG context + * @param additional_input IN -- additional input to the prng (may be null) + * @param additionallen IN -- additional input length in bytes + * @param out IN/OUT -- buffer to receive output + * @param outlen IN -- size of out buffer in bytes + */ +int32_t tc_ctr_prng_generate(TCCtrPrng_t * const ctx, + uint8_t const * const additional_input, + uint32_t additionallen, + uint8_t * const out, + uint32_t outlen); + +/** + * @brief CTR-PRNG uninstantiate procedure + * Zeroes the internal state of the supplied prng context + * @return none + * @param ctx IN/OUT -- the PRNG context + */ +void tc_ctr_prng_uninstantiate(TCCtrPrng_t * const ctx); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kernel/protocols/bluetooth/core/tinycrypt/include/tinycrypt/ecc.h b/kernel/protocols/bluetooth/core/tinycrypt/include/tinycrypt/ecc.h new file mode 100644 index 0000000000..74324f91b0 --- /dev/null +++ b/kernel/protocols/bluetooth/core/tinycrypt/include/tinycrypt/ecc.h @@ -0,0 +1,357 @@ +/* ecc.h - TinyCrypt interface to ECC auxiliary functions */ + +/* + * ============================================================================= + * Copyright (c) 2013, Kenneth MacKay + * All rights reserved. + * https://github.com/kmackay/micro-ecc + * + * 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. + * + * 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) 2015 by Intel Corporation, 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 Intel Corporation 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 OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (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 -- Interface to ECC auxiliary functions. + * + * Overview: This software is an implementation of auxiliary functions + * necessary to elliptic curve cryptography. This implementation uses + * curve NIST p-256. + * + * Security: The curve NIST p-256 provides approximately 128 bits of security. + * + */ + +#ifndef __TC_ECC_H__ +#define __TC_ECC_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Word size (4 bytes considering 32-bits architectures) */ +#define WORD_SIZE 4 +/* Number of words of 32 bits to represent an element of the the curve p-256: */ +#define NUM_ECC_DIGITS 8 +/* Number of bytes to represent an element of the the curve p-256: */ +#define NUM_ECC_BYTES (WORD_SIZE*NUM_ECC_DIGITS) + +/* struct to represent a point of the curve (uses X and Y coordinates): */ +typedef struct EccPoint { + uint32_t x[NUM_ECC_DIGITS]; + uint32_t y[NUM_ECC_DIGITS]; +} EccPoint; + +/* struct to represent a point of the curve in Jacobian coordinates + * (uses X, Y and Z coordinates): + */ +typedef struct EccPointJacobi { + uint32_t X[NUM_ECC_DIGITS]; + uint32_t Y[NUM_ECC_DIGITS]; + uint32_t Z[NUM_ECC_DIGITS]; +} EccPointJacobi; + +/* + * @brief Check if p_vli is zero. + * @return returns non-zero if p_vli == 0, zero otherwise. + * + * @param p_native OUT -- will be filled in with the native integer value. + * @param p_bytes IN -- standard octet representation of the integer to convert. + * + * @note Side-channel countermeasure: algorithm strengthened against timing + * attack. + */ +uint32_t vli_isZero(uint32_t *p_vli); + +/* + * @brief Set the content of p_src in p_dest. + * + * @param p_dest OUT -- Destination buffer. + * @param p_src IN -- Origin buffer. + * + */ +void vli_set(uint32_t *p_dest, uint32_t *p_src); + +/* + * @brief Computes the sign of p_left - p_right. + * @return returns the sign of p_left - p_right. + * + * @param p_left IN -- buffer to be compared. + * @param p_right IN -- buffer to be compared. + * @param word_size IN -- size of the word. + * + * @note Side-channel countermeasure: algorithm strengthened against timing + * attack. + */ +int32_t vli_cmp(uint32_t *p_left, uint32_t *p_right, int32_t word_size); + +/* + * @brief Computes p_result = p_left - p_right, returns borrow. + * @return returns the sign of p_left - p_right. + * + * @param p_result IN -- buffer to be compared. + * @param p_left IN -- buffer p_left in (p_left - p_right). + * @param p_right IN -- buffer p_right in (p_left - p_right). + * @param word_size IN -- size of the word. + * + * @note Side-channel countermeasure: algorithm strengthened against timing + * attack. + * @note Can modify in place. + */ +uint32_t vli_sub(uint32_t *p_result, uint32_t *p_left, uint32_t *p_right, + uint32_t word_size); + +/* + * @brief Conditional set: sets either 'p_true' or 'p_false' to 'output', + * depending on the value of 'cond'. + * + * @param output OUT -- result buffer after setting either p_true or p_false. + * @param p_true IN -- buffer to be used if cond is true. + * @param p_false IN -- buffer to be used if cond is false. + * @param cond IN -- boolean value that will determine which value will be set + * to output. + */ +void vli_cond_set(uint32_t *output, uint32_t *p_true, uint32_t *p_false, + uint32_t cond); + +/* + * @brief Computes p_result = (p_left + p_right) % p_mod. + * + * @param p_result OUT -- result buffer. + * @param p_left IN -- buffer p_left in (p_left + p_right) % p_mod. + * @param p_right IN -- buffer p_right in (p_left + p_right) % p_mod. + * @param p_mod IN -- module. + * + * @note Assumes that p_left < p_mod and p_right < p_mod, p_result != p_mod. + * @note Side-channel countermeasure: algorithm strengthened against timing + * attack. + */ +void vli_modAdd(uint32_t *p_result, uint32_t *p_left, uint32_t *p_right, + uint32_t *p_mod); + +/* + * @brief Computes p_result = (p_left - p_right) % p_mod. + * + * @param p_result OUT -- result buffer. + * @param p_left IN -- buffer p_left in (p_left - p_right) % p_mod. + * @param p_right IN -- buffer p_right in (p_left - p_right) % p_mod. + * @param p_mod IN -- module. + * + * @note Assumes that p_left < p_mod and p_right < p_mod, p_result != p_mod. + * @note Side-channel countermeasure: algorithm strengthened against timing + * attack. + */ +void vli_modSub(uint32_t *p_result, uint32_t *p_left, uint32_t *p_right, + uint32_t *p_mod); + +/* + * @brief Computes p_result = (p_left * p_right) % curve_p. + * + * @param p_result OUT -- result buffer. + * @param p_left IN -- buffer p_left in (p_left * p_right) % curve_p. + * @param p_right IN -- buffer p_right in (p_left * p_right) % curve_p. + */ +void vli_modMult_fast(uint32_t *p_result, uint32_t *p_left, + uint32_t *p_right); + +/* + * @brief Computes p_result = p_left^2 % curve_p. + * + * @param p_result OUT -- result buffer. + * @param p_left IN -- buffer p_left in (p_left^2 % curve_p). + */ +void vli_modSquare_fast(uint32_t *p_result, uint32_t *p_left); + +/* + * @brief Computes p_result = (p_left * p_right) % p_mod. + * + * @param p_result OUT -- result buffer. + * @param p_left IN -- buffer p_left in (p_left * p_right) % p_mod. + * @param p_right IN -- buffer p_right in (p_left * p_right) % p_mod. + * @param p_mod IN -- module. + * @param p_barrett IN -- used for Barrett reduction. + * @note Side-channel countermeasure: algorithm strengthened against timing + * attack. + */ +void vli_modMult(uint32_t *p_result, uint32_t *p_left, uint32_t *p_right, + uint32_t *p_mod, uint32_t *p_barrett); + +/* + * @brief Computes modular inversion: (1/p_intput) % p_mod. + * + * @param p_result OUT -- result buffer. + * @param p_input IN -- buffer p_input in (1/p_intput) % p_mod. + * @param p_mod IN -- module. + * @param p_barrett IN -- used for Barrett reduction. + * @note Side-channel countermeasure: algorithm strengthened against timing + * attack. + */ +void vli_modInv(uint32_t *p_result, uint32_t *p_input, + uint32_t *p_mod, uint32_t *p_barrett); + +/* + * @brief modular reduction based on Barrett's method + * @param p_result OUT -- p_product % p_mod. + * @param p_product IN -- buffer p_product in (p_product % p_mod). + * @param p_mod IN -- buffer p_mod in (p_product % p_mod). + * @param p_barrett -- used for Barrett reduction. + * @note Side-channel countermeasure: algorithm strengthened against timing + * attack. + */ +void vli_mmod_barrett( + uint32_t *p_result, + uint32_t *p_product, + uint32_t *p_mod, + uint32_t *p_barrett); + +/* + * @brief Check if a point is zero. + * @return Returns 1 if p_point is the point at infinity, 0 otherwise. + * + * @param p_point IN -- point to be checked. + */ +uint32_t EccPoint_isZero(EccPoint *p_point); + +/* + * @brief Check if point in Jacobi coordinates is zero. + * @return Returns 1 if p_point_jacobi is the point at infinity, 0 otherwise. + * + * @param p_point IN -- point to be checked. + */ +uint32_t EccPointJacobi_isZero(EccPointJacobi *p_point_jacobi); + +/* + * @brief Conversion from Jacobi coordinates to Affine coordinates. + * + * @param p_point OUT -- point in Affine coordinates. + * @param p_point_jacobi OUT -- point in Jacobi coordinates. + */ +void EccPoint_toAffine(EccPoint *p_point, EccPointJacobi *p_point_jacobi); + +/* + * @brief Elliptic curve point addition in Jacobi coordinates: P1 = P1 + P2. + * + * @param P1 IN/OUT -- P1 in P1 = P1 + P2. + * @param P2 IN -- P2 in P1 = P1 + P2. + */ +void EccPoint_add(EccPointJacobi *P1, EccPointJacobi *P2); + +/* + * @brief Elliptic curve scalar multiplication with result in Jacobi coordinates + * + * @param p_result OUT -- Product of p_point by p_scalar. + * @param p_point IN -- Elliptic curve point + * @param p_scalar IN -- Scalar integer + * @note Side-channel countermeasure: algorithm strengthened against timing + * attack. + */ +void EccPoint_mult_safe(EccPointJacobi *p_result, EccPoint *p_point, + uint32_t *p_scalar); + +/* + * @brief Fast elliptic curve scalar multiplication with result in Jacobi + * coordinates + * @note non constant time + * @param p_result OUT -- Product of p_point by p_scalar. + * @param p_point IN -- Elliptic curve point + * @param p_scalar IN -- Scalar integer + * @note algorithm NOT strengthened against timing attack. + */ +void EccPoint_mult_unsafe( + EccPointJacobi *p_result, + EccPoint *p_point, + uint32_t *p_scalar); + +/* + * @brief Convert an integer in standard octet representation to native format. + * @return returns TC_CRYPTO_SUCCESS (1) + * returns TC_CRYPTO_FAIL (0) if: + * out == NULL or + * c == NULL or + * ((plen > 0) and (payload == NULL)) or + * ((alen > 0) and (associated_data == NULL)) or + * (alen >= TC_CCM_AAD_MAX_BYTES) or + * (plen >= TC_CCM_PAYLOAD_MAX_BYTES) + * + * @param p_native OUT -- will be filled in with the native integer value. + * @param p_bytes IN -- standard octet representation of the integer to convert. + * + */ +void ecc_bytes2native(uint32_t p_native[NUM_ECC_DIGITS], + uint8_t p_bytes[NUM_ECC_DIGITS*4]); + + +/* + * @brief Convert an integer in native format to standard octet representation. + * @return returns TC_CRYPTO_SUCCESS (1) + * returns TC_CRYPTO_FAIL (0) if: + * out == NULL or + * c == NULL or + * ((plen > 0) and (payload == NULL)) or + * ((alen > 0) and (associated_data == NULL)) or + * (alen >= TC_CCM_AAD_MAX_BYTES) or + * (plen >= TC_CCM_PAYLOAD_MAX_BYTES) + * + * @param p_bytes OUT -- will be filled in with the standard octet + * representation of the integer. + * @param p_native IN -- native integer value to convert. + * + */ +void ecc_native2bytes(uint8_t p_bytes[NUM_ECC_DIGITS*4], + uint32_t p_native[NUM_ECC_DIGITS]); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kernel/protocols/bluetooth/core/tinycrypt/include/tinycrypt/ecc_dh.h b/kernel/protocols/bluetooth/core/tinycrypt/include/tinycrypt/ecc_dh.h new file mode 100644 index 0000000000..778fee272d --- /dev/null +++ b/kernel/protocols/bluetooth/core/tinycrypt/include/tinycrypt/ecc_dh.h @@ -0,0 +1,142 @@ +/* ecc_dh.h - TinyCrypt interface to EC-DH implementation */ + +/* + * ============================================================================= + * Copyright (c) 2013, Kenneth MacKay + * All rights reserved. + * https://github.com/kmackay/micro-ecc + * + * 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. + * + * 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) 2015 by Intel Corporation, 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 Intel Corporation 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 OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (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 -- Interface to EC-DH implementation. + * + * Overview: This software is an implementation of EC-DH. This implementation + * uses curve NIST p-256. + * + * Security: The curve NIST p-256 provides approximately 128 bits of security. + * + */ + +#ifndef __TC_ECC_DH_H__ +#define __TC_ECC_DH_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Create a public/private key pair. + * @return returns TC_CRYPTO_SUCCESS (1) if key pair was generated successfully + * returns TC_CRYPTO_FAIL (0) if: + * the private key is 0 + * + * @param p_publicKey OUT -- the point representing the public key. + * @param p_privateKey OUT -- the private key. + * @param p_random IN -- The random number to use to generate the key pair. + * + * @note You must use a new non-predictable random number to generate each + * new key pair. + * @note p_random must have NUM_ECC_DIGITS*2 bits of entropy to eliminate + * bias in keys. + * + * @note side-channel countermeasure: algorithm strengthened against timing + * attack. + */ +int32_t ecc_make_key(EccPoint *p_publicKey, + uint32_t p_privateKey[NUM_ECC_DIGITS], + uint32_t p_random[2 * NUM_ECC_DIGITS]); + +/** + * @brief Determine whether or not a given point is on the chosen elliptic curve + * (ie, is a valid public key). + * @return returns 0 if the given point is valid + * returns -1 if: the point is zero + * returns -2 if: curve_p - p_publicKey->x != 1 or + * curve_p - p_publicKey->y != 1 + * returns -3 if: y^2 != x^3 + ax + b + * returns -4 if: public key is the group generator + * + * @param p_publicKey IN -- The point to be checked. + */ +int32_t ecc_valid_public_key(EccPoint *p_publicKey); + +/** + * @brief Compute a shared secret given your secret key and someone else's + * public key. + * @return returns TC_CRYPTO_SUCCESS (1) if the secret was computed successfully + * returns TC_CRYPTO_FAIL (0) otherwise + * + * @param p_secret OUT -- The shared secret value. + * @param p_publicKey IN -- The public key of the remote party. + * @param p_privateKey IN -- Your private key. + * + * @note Optionally, you can provide a random multiplier for resistance to DPA + * attacks. The random multiplier should probably be different for each + * invocation of ecdh_shared_secret(). + * + * @warning It is recommended to use the output of ecdh_shared_secret() as the + * input of a recommended Key Derivation Function (see NIST SP 800-108) in + * order to produce a symmetric key. + */ +int32_t ecdh_shared_secret(uint32_t p_secret[NUM_ECC_DIGITS], EccPoint *p_publicKey, + uint32_t p_privateKey[NUM_ECC_DIGITS]); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kernel/protocols/bluetooth/core/tinycrypt/include/tinycrypt/ecc_dsa.h b/kernel/protocols/bluetooth/core/tinycrypt/include/tinycrypt/ecc_dsa.h new file mode 100644 index 0000000000..a037fa5b09 --- /dev/null +++ b/kernel/protocols/bluetooth/core/tinycrypt/include/tinycrypt/ecc_dsa.h @@ -0,0 +1,135 @@ +/* ecc_dh.h - TinyCrypt interface to EC-DSA implementation */ + +/* + * ============================================================================= + * Copyright (c) 2013, Kenneth MacKay + * All rights reserved. + * https://github.com/kmackay/micro-ecc + * + * 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. + * + * 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) 2015 by Intel Corporation, 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 Intel Corporation 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 OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (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 -- Interface to EC-DSA implementation. + * + * Overview: This software is an implementation of EC-DSA. This implementation + * uses curve NIST p-256. + * + * Security: The curve NIST p-256 provides approximately 128 bits of security. + * + * Usage: - To sign: Compute a hash of the data you wish to sign (SHA-2 is + * recommended) and pass it in to ecdsa_sign function along with your + * private key and a random number. You must use a new non-predictable + * random number to generate each new signature. + * - To verify a signature: Compute the hash of the signed data using + * the same hash as the signer and pass it to this function along with + * the signer's public key and the signature values (r and s). + */ + +#ifndef __TC_ECC_DSA_H__ +#define __TC_ECC_DSA_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Generate an ECDSA signature for a given hash value. + * @return returns TC_CRYPTO_SUCCESS (1) if the the signature generated successfully + * returns TC_CRYPTO_FAIL (0) if: + * r == 0 or + * p_random == 0 + * + * @param r OUT -- to be filled with the signature values. + * @param s OUT -- to be filled with the signature values. + * @param p_privateKey IN -- Your private key. + * @param p_random IN -- The random number to use in generating ephemeral DSA + * keys. + * @param p_hash IN -- The message hash to sign. + * + * @note p_random must have NUM_ECC_DIGITS*2 bits of entropy to eliminate + * bias in keys. + * + * @note side-channel countermeasure: algorithm strengthened against timing + * attack. + */ +int32_t ecdsa_sign(uint32_t r[NUM_ECC_DIGITS], uint32_t s[NUM_ECC_DIGITS], + uint32_t p_privateKey[NUM_ECC_DIGITS], uint32_t p_random[NUM_ECC_DIGITS * 2], + uint32_t p_hash[NUM_ECC_DIGITS]); + + +/** + * @brief Verify an ECDSA signature. + * @return returns TC_CRYPTO_SUCCESS (1) if the the signature generated successfully + * returns TC_CRYPTO_FAIL (0) if: + * r == 0 or + * p_random == 0 + * + * @param p_publicKey IN -- The signer's public key. + * @param p_hash IN -- The hash of the signed data. + * @param r IN -- The signature values. + * @param s IN -- The signature values. + * + * @note side-channel countermeasure: algorithm strengthened against timing + * attack. + */ +int32_t ecdsa_verify(EccPoint *p_publicKey, uint32_t p_hash[NUM_ECC_DIGITS], + uint32_t r[NUM_ECC_DIGITS], uint32_t s[NUM_ECC_DIGITS]); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kernel/protocols/bluetooth/core/tinycrypt/include/tinycrypt/hmac.h b/kernel/protocols/bluetooth/core/tinycrypt/include/tinycrypt/hmac.h new file mode 100644 index 0000000000..26f6cfe689 --- /dev/null +++ b/kernel/protocols/bluetooth/core/tinycrypt/include/tinycrypt/hmac.h @@ -0,0 +1,141 @@ +/* hmac.h - TinyCrypt interface to an HMAC implementation */ + +/* + * Copyright (C) 2015 by Intel Corporation, 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 Intel Corporation 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 OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (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 Interface to an HMAC implementation. + * + * Overview: HMAC is a message authentication code based on hash functions. + * TinyCrypt hard codes SHA-256 as the hash function. A message + * authentication code based on hash functions is also called a + * keyed cryptographic hash function since it performs a + * transformation specified by a key in an arbitrary length data + * set into a fixed length data set (also called tag). + * + * Security: The security of the HMAC depends on the length of the key and + * on the security of the hash function. Note that HMAC primitives + * are much less affected by collision attacks than their + * corresponding hash functions. + * + * Requires: SHA-256 + * + * Usage: 1) call tc_hmac_set_key to set the HMAC key. + * + * 2) call tc_hmac_init to initialize a struct hash_state before + * processing the data. + * + * 3) call tc_hmac_update to process the next input segment; + * tc_hmac_update can be called as many times as needed to process + * all of the segments of the input; the order is important. + * + * 4) call tc_hmac_final to out put the tag. + */ + +#ifndef __TC_HMAC_H__ +#define __TC_HMAC_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct tc_hmac_state_struct { + /* the internal state required by h */ + struct tc_sha256_state_struct hash_state; + /* HMAC key schedule */ + uint8_t key[2*TC_SHA256_BLOCK_SIZE]; +}; +typedef struct tc_hmac_state_struct *TCHmacState_t; + +/** + * @brief HMAC set key procedure + * Configures ctx to use key + * @return returns TC_CRYPTO_SUCCESS (1) + * returns TC_CRYPTO_FAIL (0) if + * ctx == NULL or + * key == NULL or + * key_size == 0 + * @param ctx IN/OUT -- the struct tc_hmac_state_struct to initial + * @param key IN -- the HMAC key to configure + * @param key_size IN -- the HMAC key size + */ +int32_t tc_hmac_set_key(TCHmacState_t ctx, + const uint8_t *key, + uint32_t key_size); + +/** + * @brief HMAC init procedure + * Initializes ctx to begin the next HMAC operation + * @return returns TC_CRYPTO_SUCCESS (1) + * returns TC_CRYPTO_FAIL (0) if: ctx == NULL or key == NULL + * @param ctx IN/OUT -- struct tc_hmac_state_struct buffer to init + */ +int32_t tc_hmac_init(TCHmacState_t ctx); + +/** + * @brief HMAC update procedure + * Mixes data_length bytes addressed by data into state + * @return returns TC_CRYPTO_SUCCCESS (1) + * returns TC_CRYPTO_FAIL (0) if: ctx == NULL or key == NULL + * @note Assumes state has been initialized by tc_hmac_init + * @param ctx IN/OUT -- state of HMAC computation so far + * @param data IN -- data to incorporate into state + * @param data_length IN -- size of data in bytes + */ +int32_t tc_hmac_update(TCHmacState_t ctx, + const void *data, + uint32_t data_length); + +/** + * @brief HMAC final procedure + * Writes the HMAC tag into the tag buffer + * @return returns TC_CRYPTO_SUCCESS (1) + * returns TC_CRYPTO_FAIL (0) if: + * tag == NULL or + * ctx == NULL or + * key == NULL or + * taglen != TC_SHA256_DIGEST_SIZE + * @note 'ctx' is erased before exiting (this must never be changed/removed). + * @note Assumes the tag bufer is at least sizeof(hmac_tag_size(state)) bytes + * state has been initialized by tc_hmac_init + * @param tag IN/OUT -- buffer to receive computed HMAC tag + * @param taglen IN -- size of tag in bytes + * @param ctx IN/OUT -- the HMAC state for computing tag + */ +int32_t tc_hmac_final(uint8_t *tag, uint32_t taglen, TCHmacState_t ctx); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kernel/protocols/bluetooth/core/tinycrypt/include/tinycrypt/hmac_prng.h b/kernel/protocols/bluetooth/core/tinycrypt/include/tinycrypt/hmac_prng.h new file mode 100644 index 0000000000..b631c2c87f --- /dev/null +++ b/kernel/protocols/bluetooth/core/tinycrypt/include/tinycrypt/hmac_prng.h @@ -0,0 +1,164 @@ +/* hmac_prng.h - TinyCrypt interface to an HMAC-PRNG implementation */ + +/* + * Copyright (C) 2015 by Intel Corporation, 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 Intel Corporation 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 OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (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 Interface to an HMAC-PRNG implementation. + * + * Overview: A pseudo-random number generator (PRNG) generates a sequence + * of numbers that have a distribution close to the one expected + * for a sequence of truly random numbers. The NIST Special + * Publication 800-90A specifies several mechanisms to generate + * sequences of pseudo random numbers, including the HMAC-PRNG one + * which is based on HMAC. TinyCrypt implements HMAC-PRNG with + * certain modifications from the NIST SP 800-90A spec. + * + * Security: A cryptographically secure PRNG depends on the existence of an + * entropy source to provide a truly random seed as well as the + * security of the primitives used as the building blocks (HMAC and + * SHA256, for TinyCrypt). + * + * The NIST SP 800-90A standard tolerates a null personalization, + * while TinyCrypt requires a non-null personalization. This is + * because a personalization string (the host name concatenated + * with a time stamp, for example) is easily computed and might be + * the last line of defense against failure of the entropy source. + * + * Requires: - SHA-256 + * - HMAC + * + * Usage: 1) call tc_hmac_prng_init to set the HMAC key and process the + * personalization data. + * + * 2) call tc_hmac_prng_reseed to process the seed and additional + * input. + * + * 3) call tc_hmac_prng_generate to out put the pseudo-random data. + */ + +#ifndef __TC_HMAC_PRNG_H__ +#define __TC_HMAC_PRNG_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define TC_HMAC_PRNG_RESEED_REQ -1 + +struct tc_hmac_prng_struct { + /* the HMAC instance for this PRNG */ + struct tc_hmac_state_struct h; + /* the PRNG key */ + uint8_t key[TC_SHA256_DIGEST_SIZE]; + /* PRNG state */ + uint8_t v[TC_SHA256_DIGEST_SIZE]; + /* calls to tc_hmac_prng_generate left before re-seed */ + uint32_t countdown; +}; + +typedef struct tc_hmac_prng_struct *TCHmacPrng_t; + +/** + * @brief HMAC-PRNG initialization procedure + * Initializes prng with personalization, disables tc_hmac_prng_generate + * @return returns TC_CRYPTO_SUCCESS (1) + * returns TC_CRYPTO_FAIL (0) if: + * prng == NULL, + * personalization == NULL, + * plen > MAX_PLEN + * @note Assumes: - personalization != NULL. + * The personalization is a platform unique string (e.g., the host + * name) and is the last line of defense against failure of the + * entropy source + * @warning NIST SP 800-90A specifies 3 items as seed material during + * initialization: entropy seed, personalization, and an optional + * nonce. TinyCrypts requires instead a non-null personalization + * (which is easily computed) and indirectly requires an entropy + * seed (since the reseed function is mandatorily called after + * init) + * @param prng IN/OUT -- the PRNG state to initialize + * @param personalization IN -- personalization string + * @param plen IN -- personalization length in bytes + */ +int32_t tc_hmac_prng_init(TCHmacPrng_t prng, + const uint8_t *personalization, + uint32_t plen); + +/** + * @brief HMAC-PRNG reseed procedure + * Mixes seed into prng, enables tc_hmac_prng_generate + * @return returns TC_CRYPTO_SUCCESS (1) + * returns TC_CRYPTO_FAIL (0) if: + * prng == NULL, + * seed == NULL, + * seedlen < MIN_SLEN, + * seendlen > MAX_SLEN, + * additional_input != (const uint8_t *) 0 && additionallen == 0, + * additional_input != (const uint8_t *) 0 && additionallen > MAX_ALEN + * @note Assumes:- tc_hmac_prng_init has been called for prng + * - seed has sufficient entropy. + * + * @param prng IN/OUT -- the PRNG state + * @param seed IN -- entropy to mix into the prng + * @param seedlen IN -- length of seed in bytes + * @param additional_input IN -- additional input to the prng + * @param additionallen IN -- additional input length in bytes + */ +int32_t tc_hmac_prng_reseed(TCHmacPrng_t prng, const uint8_t *seed, + uint32_t seedlen, const uint8_t *additional_input, + uint32_t additionallen); + +/** + * @brief HMAC-PRNG generate procedure + * Generates outlen pseudo-random bytes into out buffer, updates prng + * @return returns TC_CRYPTO_SUCCESS (1) + * returns TC_HMAC_PRNG_RESEED_REQ (-1) if a reseed is needed + * returns TC_CRYPTO_FAIL (0) if: + * out == NULL, + * prng == NULL, + * outlen == 0, + * outlen >= MAX_OUT + * @note Assumes tc_hmac_prng_init has been called for prng + * @param out IN/OUT -- buffer to receive output + * @param outlen IN -- size of out buffer in bytes + * @param prng IN/OUT -- the PRNG state + */ +int32_t tc_hmac_prng_generate(uint8_t *out, uint32_t outlen, TCHmacPrng_t prng); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kernel/protocols/bluetooth/core/tinycrypt/include/tinycrypt/sha256.h b/kernel/protocols/bluetooth/core/tinycrypt/include/tinycrypt/sha256.h new file mode 100644 index 0000000000..89166f777e --- /dev/null +++ b/kernel/protocols/bluetooth/core/tinycrypt/include/tinycrypt/sha256.h @@ -0,0 +1,131 @@ +/* sha256.h - TinyCrypt interface to a SHA-256 implementation */ + +/* + * Copyright (C) 2015 by Intel Corporation, 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 Intel Corporation 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 OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (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 Interface to a SHA-256 implementation. + * + * Overview: SHA-256 is a NIST approved cryptographic hashing algorithm + * specified in FIPS 180. A hash algorithm maps data of arbitrary + * size to data of fixed length. + * + * Security: SHA-256 provides 128 bits of security against collision attacks + * and 256 bits of security against pre-image attacks. SHA-256 does + * NOT behave like a random oracle, but it can be used as one if + * the string being hashed is prefix-free encoded before hashing. + * + * Usage: 1) call tc_sha256_init to initialize a struct + * tc_sha256_state_struct before hashing a new string. + * + * 2) call tc_sha256_update to hash the next string segment; + * tc_sha256_update can be called as many times as needed to hash + * all of the segments of a string; the order is important. + * + * 3) call tc_sha256_final to out put the digest from a hashing + * operation. + */ + +#ifndef __TC_SHA256_H__ +#define __TC_SHA256_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define TC_SHA256_BLOCK_SIZE (64) +#define TC_SHA256_DIGEST_SIZE (32) +#define TC_SHA256_STATE_BLOCKS (TC_SHA256_DIGEST_SIZE/4) + +struct tc_sha256_state_struct { + uint32_t iv[TC_SHA256_STATE_BLOCKS]; + uint64_t bits_hashed; + uint8_t leftover[TC_SHA256_BLOCK_SIZE]; + size_t leftover_offset; +}; + +typedef struct tc_sha256_state_struct *TCSha256State_t; + +/** + * @brief SHA256 initialization procedure + * Initializes s + * @return returns TC_CRYPTO_SUCCESS (1) + * returns TC_CRYPTO_FAIL (0) if s == NULL + * @param s Sha256 state struct + */ +int32_t tc_sha256_init(TCSha256State_t s); + +/** + * @brief SHA256 update procedure + * Hashes data_length bytes addressed by data into state s + * @return returns TC_CRYPTO_SUCCESS (1) + * returns TC_CRYPTO_FAIL (0) if: + * s == NULL, + * s->iv == NULL, + * data == NULL + * @note Assumes s has been initialized by tc_sha256_init + * @warning The state buffer 'leftover' is left in memory after processing + * If your application intends to have sensitive data in this + * buffer, remind to erase it after the data has been processed + * @param s Sha256 state struct + * @param data message to hash + * @param datalen length of message to hash + */ +int32_t tc_sha256_update(TCSha256State_t s, + const uint8_t *data, + size_t datalen); + +/** + * @brief SHA256 final procedure + * Inserts the completed hash computation into digest + * @return returns TC_CRYPTO_SUCCESS (1) + * returns TC_CRYPTO_FAIL (0) if: + * s == NULL, + * s->iv == NULL, + * digest == NULL + * @note Assumes: s has been initialized by tc_sha256_init + * digest points to at least TC_SHA256_DIGEST_SIZE bytes + * @warning The state buffer 'leftover' is left in memory after processing + * If your application intends to have sensitive data in this + * buffer, remind to erase it after the data has been processed + * @param digest unsigned eight bit integer + * @param s Sha256 state struct + */ +int32_t tc_sha256_final(uint8_t *digest, TCSha256State_t s); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kernel/protocols/bluetooth/core/tinycrypt/include/tinycrypt/utils.h b/kernel/protocols/bluetooth/core/tinycrypt/include/tinycrypt/utils.h new file mode 100644 index 0000000000..429934e8f6 --- /dev/null +++ b/kernel/protocols/bluetooth/core/tinycrypt/include/tinycrypt/utils.h @@ -0,0 +1,95 @@ +/* utils.h - TinyCrypt interface to platform-dependent run-time operations */ + +/* + * Copyright (C) 2015 by Intel Corporation, 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 Intel Corporation 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 OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (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 Interface to platform-dependent run-time operations. + * + */ + +#ifndef __TC_UTILS_H__ +#define __TC_UTILS_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Copy the the buffer 'from' to the buffer 'to'. + * @return returns TC_CRYPTO_SUCCESS (1) + * returns TC_CRYPTO_FAIL (0) if: + * from_len > to_len. + * + * @param to OUT -- destination buffer + * @param to_len IN -- length of destination buffer + * @param from IN -- origin buffer + * @param from_len IN -- length of origin buffer + */ +uint32_t _copy(uint8_t *to, uint32_t to_len, + const uint8_t *from, uint32_t from_len); + +/** + * @brief Set the value 'val' into the buffer 'to', 'len' times. + * + * @param to OUT -- destination buffer + * @param val IN -- value to be set in 'to' + * @param len IN -- number of times the value will be copied + */ +void _set(void *to, uint8_t val, uint32_t len); + +/* + * @brief AES specific doubling function, which utilizes + * the finite field used by AES. + * @return Returns a^2 + * + * @param a IN/OUT -- value to be doubled + */ +uint8_t _double_byte(uint8_t a); + +/* + * @brief Constant-time algorithm to compare if two sequences of bytes are equal + * @return Returns 0 if equal, and non-zero otherwise + * + * @param a IN -- sequence of bytes a + * @param b IN -- sequence of bytes b + * @param size IN -- size of sequences a and b + */ +int32_t _compare(const uint8_t *a, const uint8_t *b, size_t size); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/kernel/protocols/bluetooth/core/tinycrypt/source/aes_decrypt.c b/kernel/protocols/bluetooth/core/tinycrypt/source/aes_decrypt.c new file mode 100644 index 0000000000..2e4e3bcebf --- /dev/null +++ b/kernel/protocols/bluetooth/core/tinycrypt/source/aes_decrypt.c @@ -0,0 +1,164 @@ +/* aes_decrypt.c - TinyCrypt implementation of AES decryption procedure */ + +/* + * Copyright (C) 2015 by Intel Corporation, 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 Intel Corporation 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 OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 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 + +#define ZERO_BYTE 0x00 + +static const uint8_t inv_sbox[256] = { + 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, + 0x81, 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, + 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32, + 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e, + 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, + 0x6d, 0x8b, 0xd1, 0x25, 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, + 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50, + 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84, + 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, + 0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, + 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 0x3a, 0x91, 0x11, 0x41, + 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73, + 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, + 0x1c, 0x75, 0xdf, 0x6e, 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, + 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b, + 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4, + 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, + 0x27, 0x80, 0xec, 0x5f, 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, + 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 0xa0, 0xe0, 0x3b, 0x4d, + 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61, + 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, + 0x55, 0x21, 0x0c, 0x7d +}; + +int32_t tc_aes128_set_decrypt_key(TCAesKeySched_t s, const uint8_t *k) +{ + return tc_aes128_set_encrypt_key(s, k); +} + +#define mult8(a)(_double_byte(_double_byte(_double_byte(a)))) +#define mult9(a)(mult8(a)^(a)) +#define multb(a)(mult8(a)^_double_byte(a)^(a)) +#define multd(a)(mult8(a)^_double_byte(_double_byte(a))^(a)) +#define multe(a)(mult8(a)^_double_byte(_double_byte(a))^_double_byte(a)) + +static inline void mult_row_column(uint8_t *out, const uint8_t *in) +{ + out[0] = multe(in[0]) ^ multb(in[1]) ^ multd(in[2]) ^ mult9(in[3]); + out[1] = mult9(in[0]) ^ multe(in[1]) ^ multb(in[2]) ^ multd(in[3]); + out[2] = multd(in[0]) ^ mult9(in[1]) ^ multe(in[2]) ^ multb(in[3]); + out[3] = multb(in[0]) ^ multd(in[1]) ^ mult9(in[2]) ^ multe(in[3]); +} + +static inline void inv_mix_columns(uint8_t *s) +{ + uint8_t t[Nb*Nk]; + + mult_row_column(t, s); + mult_row_column(&t[Nb], s+Nb); + mult_row_column(&t[2*Nb], s+(2*Nb)); + mult_row_column(&t[3*Nb], s+(3*Nb)); + (void)_copy(s, sizeof(t), t, sizeof(t)); +} + +static inline void add_round_key(uint8_t *s, const uint32_t *k) +{ + s[0] ^= (uint8_t)(k[0] >> 24); s[1] ^= (uint8_t)(k[0] >> 16); + s[2] ^= (uint8_t)(k[0] >> 8); s[3] ^= (uint8_t)(k[0]); + s[4] ^= (uint8_t)(k[1] >> 24); s[5] ^= (uint8_t)(k[1] >> 16); + s[6] ^= (uint8_t)(k[1] >> 8); s[7] ^= (uint8_t)(k[1]); + s[8] ^= (uint8_t)(k[2] >> 24); s[9] ^= (uint8_t)(k[2] >> 16); + s[10] ^= (uint8_t)(k[2] >> 8); s[11] ^= (uint8_t)(k[2]); + s[12] ^= (uint8_t)(k[3] >> 24); s[13] ^= (uint8_t)(k[3] >> 16); + s[14] ^= (uint8_t)(k[3] >> 8); s[15] ^= (uint8_t)(k[3]); +} + +static inline void inv_sub_bytes(uint8_t *s) +{ + uint32_t i; + + for (i = 0; i < (Nb*Nk); ++i) { + s[i] = inv_sbox[s[i]]; + } +} + +/* + * This inv_shift_rows also implements the matrix flip required for + * inv_mix_columns, but performs it here to reduce the number of memory + * operations. + */ +static inline void inv_shift_rows(uint8_t *s) +{ + uint8_t t[Nb*Nk]; + + t[0] = s[0]; t[1] = s[13]; t[2] = s[10]; t[3] = s[7]; + t[4] = s[4]; t[5] = s[1]; t[6] = s[14]; t[7] = s[11]; + t[8] = s[8]; t[9] = s[5]; t[10] = s[2]; t[11] = s[15]; + t[12] = s[12]; t[13] = s[9]; t[14] = s[6]; t[15] = s[3]; + (void)_copy(s, sizeof(t), t, sizeof(t)); +} + +int32_t tc_aes_decrypt(uint8_t *out, const uint8_t *in, const TCAesKeySched_t s) +{ + uint8_t state[Nk*Nb]; + uint32_t i; + + if (out == (uint8_t *) 0) { + return TC_CRYPTO_FAIL; + } else if (in == (const uint8_t *) 0) { + return TC_CRYPTO_FAIL; + } else if (s == (TCAesKeySched_t) 0) { + return TC_CRYPTO_FAIL; + } + + (void)_copy(state, sizeof(state), in, sizeof(state)); + + add_round_key(state, s->words + Nb*Nr); + + for (i = Nr-1; i > 0; --i) { + inv_shift_rows(state); + inv_sub_bytes(state); + add_round_key(state, s->words + Nb*i); + inv_mix_columns(state); + } + + inv_shift_rows(state); + inv_sub_bytes(state); + add_round_key(state, s->words); + + (void)_copy(out, sizeof(state), state, sizeof(state)); + /*zeroing out one byte state buffer */ + _set(state, ZERO_BYTE, sizeof(state)); + + return TC_CRYPTO_SUCCESS; +} diff --git a/kernel/protocols/bluetooth/core/tinycrypt/source/aes_encrypt.c b/kernel/protocols/bluetooth/core/tinycrypt/source/aes_encrypt.c new file mode 100644 index 0000000000..6bc73a5810 --- /dev/null +++ b/kernel/protocols/bluetooth/core/tinycrypt/source/aes_encrypt.c @@ -0,0 +1,191 @@ +/* aes_encrypt.c - TinyCrypt implementation of AES encryption procedure */ + +/* + * Copyright (C) 2015 by Intel Corporation, 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 Intel Corporation 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 OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 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 + +static const uint8_t sbox[256] = { + 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, + 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, + 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, + 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, + 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, + 0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, + 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, + 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, + 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, + 0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, + 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec, + 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, + 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, + 0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, + 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d, + 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, + 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, + 0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, + 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, + 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, + 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, + 0xb0, 0x54, 0xbb, 0x16 +}; + +static inline uint32_t rotword(uint32_t a) +{ + return (((a) >> 24)|((a) << 8)); +} + +#define subbyte(a, o)(sbox[((a) >> (o))&0xff] << (o)) +#define subword(a)(subbyte(a, 24)|subbyte(a, 16)|subbyte(a, 8)|subbyte(a, 0)) + +int32_t tc_aes128_set_encrypt_key(TCAesKeySched_t s, const uint8_t *k) +{ + const uint32_t rconst[11] = { + 0x00000000, 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, + 0x20000000, 0x40000000, 0x80000000, 0x1b000000, 0x36000000 + }; + uint32_t i; + uint32_t t; + + if (s == (TCAesKeySched_t) 0) { + return TC_CRYPTO_FAIL; + } else if (k == (const uint8_t *) 0) { + return TC_CRYPTO_FAIL; + } + + for (i = 0; i < Nk; ++i) { + s->words[i] = (k[Nb*i]<<24) | (k[Nb*i+1]<<16) | + (k[Nb*i+2]<<8) | (k[Nb*i+3]); + } + + for (; i < (Nb*(Nr+1)); ++i) { + t = s->words[i-1]; + if ((i % Nk) == 0) { + t = subword(rotword(t)) ^ rconst[i/Nk]; + } + s->words[i] = s->words[i-Nk] ^ t; + } + + return TC_CRYPTO_SUCCESS; +} + +static inline void add_round_key(uint8_t *s, const uint32_t *k) +{ + s[0] ^= (uint8_t)(k[0] >> 24); s[1] ^= (uint8_t)(k[0] >> 16); + s[2] ^= (uint8_t)(k[0] >> 8); s[3] ^= (uint8_t)(k[0]); + s[4] ^= (uint8_t)(k[1] >> 24); s[5] ^= (uint8_t)(k[1] >> 16); + s[6] ^= (uint8_t)(k[1] >> 8); s[7] ^= (uint8_t)(k[1]); + s[8] ^= (uint8_t)(k[2] >> 24); s[9] ^= (uint8_t)(k[2] >> 16); + s[10] ^= (uint8_t)(k[2] >> 8); s[11] ^= (uint8_t)(k[2]); + s[12] ^= (uint8_t)(k[3] >> 24); s[13] ^= (uint8_t)(k[3] >> 16); + s[14] ^= (uint8_t)(k[3] >> 8); s[15] ^= (uint8_t)(k[3]); +} + +static inline void sub_bytes(uint8_t *s) +{ + uint32_t i; + + for (i = 0; i < (Nb*Nk); ++i) { + s[i] = sbox[s[i]]; + } +} + +#define triple(a)(_double_byte(a)^(a)) + +static inline void mult_row_column(uint8_t *out, const uint8_t *in) +{ + out[0] = _double_byte(in[0]) ^ triple(in[1]) ^ in[2] ^ in[3]; + out[1] = in[0] ^ _double_byte(in[1]) ^ triple(in[2]) ^ in[3]; + out[2] = in[0] ^ in[1] ^ _double_byte(in[2]) ^ triple(in[3]); + out[3] = triple(in[0]) ^ in[1] ^ in[2] ^ _double_byte(in[3]); +} + +static inline void mix_columns(uint8_t *s) +{ + uint8_t t[Nb*Nk]; + + mult_row_column(t, s); + mult_row_column(&t[Nb], s+Nb); + mult_row_column(&t[2*Nb], s+(2*Nb)); + mult_row_column(&t[3*Nb], s+(3*Nb)); + (void) _copy(s, sizeof(t), t, sizeof(t)); +} + +/* + * This shift_rows also implements the matrix flip required for mix_columns, but + * performs it here to reduce the number of memory operations. + */ +static inline void shift_rows(uint8_t *s) +{ + uint8_t t[Nb*Nk]; + + t[0] = s[0]; t[1] = s[5]; t[2] = s[10]; t[3] = s[15]; + t[4] = s[4]; t[5] = s[9]; t[6] = s[14]; t[7] = s[3]; + t[8] = s[8]; t[9] = s[13]; t[10] = s[2]; t[11] = s[7]; + t[12] = s[12]; t[13] = s[1]; t[14] = s[6]; t[15] = s[11]; + (void) _copy(s, sizeof(t), t, sizeof(t)); +} + +int32_t tc_aes_encrypt(uint8_t *out, const uint8_t *in, const TCAesKeySched_t s) +{ + uint8_t state[Nk*Nb]; + uint32_t i; + + if (out == (uint8_t *) 0) { + return TC_CRYPTO_FAIL; + } else if (in == (const uint8_t *) 0) { + return TC_CRYPTO_FAIL; + } else if (s == (TCAesKeySched_t) 0) { + return TC_CRYPTO_FAIL; + } + + (void)_copy(state, sizeof(state), in, sizeof(state)); + add_round_key(state, s->words); + + for (i = 0; i < (Nr-1); ++i) { + sub_bytes(state); + shift_rows(state); + mix_columns(state); + add_round_key(state, s->words + Nb*(i+1)); + } + + sub_bytes(state); + shift_rows(state); + add_round_key(state, s->words + Nb*(i+1)); + + (void)_copy(out, sizeof(state), state, sizeof(state)); + + /* zeroing out the state buffer */ + _set(state, TC_ZERO_BYTE, sizeof(state)); + + return TC_CRYPTO_SUCCESS; +} diff --git a/kernel/protocols/bluetooth/core/tinycrypt/source/cbc_mode.c b/kernel/protocols/bluetooth/core/tinycrypt/source/cbc_mode.c new file mode 100644 index 0000000000..8163e0d38d --- /dev/null +++ b/kernel/protocols/bluetooth/core/tinycrypt/source/cbc_mode.c @@ -0,0 +1,113 @@ +/* cbc_mode.c - TinyCrypt implementation of CBC mode encryption & decryption */ + +/* + * Copyright (C) 2015 by Intel Corporation, 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 Intel Corporation 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 OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 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 + +int32_t tc_cbc_mode_encrypt(uint8_t *out, uint32_t outlen, const uint8_t *in, + uint32_t inlen, const uint8_t *iv, + const TCAesKeySched_t sched) +{ + + uint8_t buffer[TC_AES_BLOCK_SIZE]; + uint32_t n, m; + + /* input sanity check: */ + if (out == (uint8_t *) 0 || + in == (const uint8_t *) 0 || + sched == (TCAesKeySched_t) 0 || + inlen == 0 || + outlen == 0 || + (inlen % TC_AES_BLOCK_SIZE) != 0 || + (outlen % TC_AES_BLOCK_SIZE) != 0 || + outlen != inlen + TC_AES_BLOCK_SIZE) { + return TC_CRYPTO_FAIL; + } + + /* copy iv to the buffer */ + (void)_copy(buffer, TC_AES_BLOCK_SIZE, iv, TC_AES_BLOCK_SIZE); + /* copy iv to the output buffer */ + (void)_copy(out, TC_AES_BLOCK_SIZE, iv, TC_AES_BLOCK_SIZE); + out += TC_AES_BLOCK_SIZE; + + for (n = m = 0; n < inlen; ++n) { + buffer[m++] ^= *in++; + if (m == TC_AES_BLOCK_SIZE) { + (void)tc_aes_encrypt(buffer, buffer, sched); + (void)_copy(out, TC_AES_BLOCK_SIZE, + buffer, TC_AES_BLOCK_SIZE); + out += TC_AES_BLOCK_SIZE; + m = 0; + } + } + + return TC_CRYPTO_SUCCESS; +} + +int32_t tc_cbc_mode_decrypt(uint8_t *out, uint32_t outlen, const uint8_t *in, + uint32_t inlen, const uint8_t *iv, + const TCAesKeySched_t sched) +{ + uint8_t buffer[TC_AES_BLOCK_SIZE]; + const uint8_t *p; + uint32_t n, m; + + /* sanity check the inputs */ + if (out == (uint8_t *) 0 || + in == (const uint8_t *) 0 || + sched == (TCAesKeySched_t) 0 || + inlen == 0 || + outlen == 0 || + (inlen % TC_AES_BLOCK_SIZE) != 0 || + (outlen % TC_AES_BLOCK_SIZE) != 0 || + outlen != inlen - TC_AES_BLOCK_SIZE) { + return TC_CRYPTO_FAIL; + } + + /* + * Note that in == iv + ciphertext, i.e. the iv and the ciphertext are + * contiguous. This allows for a very efficient decryption algorithm + * that would not otherwise be possible. + */ + p = iv; + for (n = m = 0; n < inlen; ++n) { + if ((n % TC_AES_BLOCK_SIZE) == 0) { + (void)tc_aes_decrypt(buffer, in, sched); + in += TC_AES_BLOCK_SIZE; + m = 0; + } + *out++ = buffer[m++] ^ *p++; + } + + return TC_CRYPTO_SUCCESS; +} diff --git a/kernel/protocols/bluetooth/core/tinycrypt/source/ccm_mode.c b/kernel/protocols/bluetooth/core/tinycrypt/source/ccm_mode.c new file mode 100644 index 0000000000..9dfa838f60 --- /dev/null +++ b/kernel/protocols/bluetooth/core/tinycrypt/source/ccm_mode.c @@ -0,0 +1,260 @@ +/* ccm_mode.c - TinyCrypt implementation of CCM mode */ + +/* + * Copyright (C) 2015 by Intel Corporation, 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 Intel Corporation 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 OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 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 + +int32_t tc_ccm_config(TCCcmMode_t c, TCAesKeySched_t sched, uint8_t *nonce, + uint32_t nlen, uint32_t mlen) +{ + + /* input sanity check: */ + if (c == (TCCcmMode_t) 0 || + sched == (TCAesKeySched_t) 0 || + nonce == (uint8_t *) 0) { + return TC_CRYPTO_FAIL; + } else if (nlen != 13) { + return TC_CRYPTO_FAIL; /* The allowed nonce size is: 13. See documentation.*/ + } else if ((mlen < 4) || (mlen > 16) || (mlen & 1)) { + return TC_CRYPTO_FAIL; /* The allowed mac sizes are: 4, 6, 8, 10, 12, 14, 16.*/ + } + + c->mlen = mlen; + c->sched = sched; + c->nonce = nonce; + + return TC_CRYPTO_SUCCESS; +} + +/** + * Variation of CBC-MAC mode used in CCM. + */ +static void ccm_cbc_mac(uint8_t *T, const uint8_t *data, uint32_t dlen, + uint32_t flag, TCAesKeySched_t sched) +{ + + uint32_t i; + + if (flag > 0) { + T[0] ^= (uint8_t)(dlen >> 8); + T[1] ^= (uint8_t)(dlen); + dlen += 2; i = 2; + } else { + i = 0; + } + + while (i < dlen) { + T[i++ % (Nb * Nk)] ^= *data++; + if (((i % (Nb * Nk)) == 0) || dlen == i) { + (void) tc_aes_encrypt(T, T, sched); + } + } +} + +/** + * Variation of CTR mode used in CCM. + * The CTR mode used by CCM is slightly different than the conventional CTR + * mode (the counter is increased before encryption, instead of after + * encryption). Besides, it is assumed that the counter is stored in the last + * 2 bytes of the nonce. + */ +static int32_t ccm_ctr_mode(uint8_t *out, uint32_t outlen, const uint8_t *in, + uint32_t inlen, uint8_t *ctr, const TCAesKeySched_t sched) +{ + + uint8_t buffer[TC_AES_BLOCK_SIZE]; + uint8_t nonce[TC_AES_BLOCK_SIZE]; + uint16_t block_num; + uint32_t i; + + /* input sanity check: */ + if (out == (uint8_t *) 0 || + in == (uint8_t *) 0 || + ctr == (uint8_t *) 0 || + sched == (TCAesKeySched_t) 0 || + inlen == 0 || + outlen == 0 || + outlen != inlen) { + return TC_CRYPTO_FAIL; + } + + /* copy the counter to the nonce */ + (void) _copy(nonce, sizeof(nonce), ctr, sizeof(nonce)); + + /* select the last 2 bytes of the nonce to be incremented */ + block_num = (uint16_t) ((nonce[14] << 8)|(nonce[15])); + for (i = 0; i < inlen; ++i) { + if ((i % (TC_AES_BLOCK_SIZE)) == 0) { + block_num++; + nonce[14] = (uint8_t)(block_num >> 8); + nonce[15] = (uint8_t)(block_num); + if (!tc_aes_encrypt(buffer, nonce, sched)) { + return TC_CRYPTO_FAIL; + } + } + /* update the output */ + *out++ = buffer[i % (TC_AES_BLOCK_SIZE)] ^ *in++; + } + + /* update the counter */ + ctr[14] = nonce[14]; ctr[15] = nonce[15]; + + return TC_CRYPTO_SUCCESS; +} + +int32_t tc_ccm_generation_encryption(uint8_t *out, const uint8_t *associated_data, + uint32_t alen, const uint8_t *payload, + uint32_t plen, TCCcmMode_t c) +{ + /* input sanity check: */ + if ((out == (uint8_t *) 0) || + (c == (TCCcmMode_t) 0) || + ((plen > 0) && (payload == (uint8_t *) 0)) || + ((alen > 0) && (associated_data == (uint8_t *) 0)) || + (alen >= TC_CCM_AAD_MAX_BYTES) || /* associated data size unsupported */ + (plen >= TC_CCM_PAYLOAD_MAX_BYTES)) { /* payload size unsupported */ + return TC_CRYPTO_FAIL; + } + + uint8_t b[Nb * Nk]; + uint8_t tag[Nb * Nk]; + uint32_t i; + + /* GENERATING THE AUTHENTICATION TAG: */ + + /* formatting the sequence b for authentication: */ + b[0] = ((alen > 0) ? 0x40:0) | (((c->mlen - 2) / 2 << 3)) | (1); + for (i = 1; i <= 13; ++i) { + b[i] = c->nonce[i - 1]; + } + b[14] = (uint8_t)(plen >> 8); + b[15] = (uint8_t)(plen); + + /* computing the authentication tag using cbc-mac: */ + (void) tc_aes_encrypt(tag, b, c->sched); + if (alen > 0) { + ccm_cbc_mac(tag, associated_data, alen, 1, c->sched); + } + if (plen > 0) { + ccm_cbc_mac(tag, payload, plen, 0, c->sched); + } + + /* ENCRYPTION: */ + + /* formatting the sequence b for encryption: */ + b[0] = 1; /* q - 1 = 2 - 1 = 1 */ + b[14] = b[15] = TC_ZERO_BYTE; + + /* encrypting payload using ctr mode: */ + ccm_ctr_mode(out, plen, payload, plen, b, c->sched); + + b[14] = b[15] = TC_ZERO_BYTE; /* restoring initial counter for ctr_mode (0):*/ + + /* encrypting b and adding the tag to the output: */ + (void) tc_aes_encrypt(b, b, c->sched); + out += plen; + for (i = 0; i < c->mlen; ++i) { + *out++ = tag[i] ^ b[i]; + } + + return TC_CRYPTO_SUCCESS; +} + +int32_t tc_ccm_decryption_verification(uint8_t *out, const uint8_t *associated_data, + uint32_t alen, const uint8_t *payload, + uint32_t plen, TCCcmMode_t c) +{ + /* input sanity check: */ + if ((out == (uint8_t *) 0) || + (c == (TCCcmMode_t) 0) || + ((plen > 0) && (payload == (uint8_t *) 0)) || + ((alen > 0) && (associated_data == (uint8_t *) 0)) || + (alen >= TC_CCM_AAD_MAX_BYTES) || /* associated data size unsupported */ + (plen >= TC_CCM_PAYLOAD_MAX_BYTES)) { /* payload size unsupported */ + return TC_CRYPTO_FAIL; + } + + uint8_t b[Nb * Nk]; + uint8_t tag[Nb * Nk]; + uint32_t i; + + /* DECRYPTION: */ + + /* formatting the sequence b for decryption: */ + b[0] = 1; /* q - 1 = 2 - 1 = 1 */ + for (i = 1; i < 14; ++i) { + b[i] = c->nonce[i - 1]; + } + b[14] = b[15] = TC_ZERO_BYTE; /* initial counter value is 0 */ + + /* decrypting payload using ctr mode: */ + ccm_ctr_mode(out, plen - c->mlen, payload, plen - c->mlen, b, c->sched); + + b[14] = b[15] = TC_ZERO_BYTE; /* restoring initial counter value (0) */ + + /* encrypting b and restoring the tag from input: */ + (void) tc_aes_encrypt(b, b, c->sched); + for (i = 0; i < c->mlen; ++i) { + tag[i] = *(payload + plen - c->mlen + i) ^ b[i]; + } + + /* VERIFYING THE AUTHENTICATION TAG: */ + + /* formatting the sequence b for authentication: */ + b[0] = ((alen > 0) ? 0x40:0)|(((c->mlen - 2) / 2 << 3)) | (1); + for (i = 1; i < 14; ++i) { + b[i] = c->nonce[i - 1]; + } + b[14] = (uint8_t)((plen - c->mlen) >> 8); + b[15] = (uint8_t)(plen - c->mlen); + + /* computing the authentication tag using cbc-mac: */ + (void) tc_aes_encrypt(b, b, c->sched); + if (alen > 0) { + ccm_cbc_mac(b, associated_data, alen, 1, c->sched); + } + if (plen > 0) { + ccm_cbc_mac(b, out, plen - c->mlen, 0, c->sched); + } + + /* comparing the received tag and the computed one: */ + if (_compare(b, tag, c->mlen) != 0) { + /* erase the decrypted buffer in case of mac validation failure: */ + _set(out, 0, sizeof(*out)); + return TC_CRYPTO_FAIL; + } + + return TC_CRYPTO_SUCCESS; +} diff --git a/kernel/protocols/bluetooth/core/tinycrypt/source/cmac_mode.c b/kernel/protocols/bluetooth/core/tinycrypt/source/cmac_mode.c new file mode 100644 index 0000000000..3b31c3e6ff --- /dev/null +++ b/kernel/protocols/bluetooth/core/tinycrypt/source/cmac_mode.c @@ -0,0 +1,254 @@ +/* cmac_mode.c - TinyCrypt CMAC mode implementation */ + +/* + * Copyright (C) 2015 by Intel Corporation, 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 Intel Corporation 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 OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 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 + +/* max number of calls until change the key (2^48).*/ +static uint64_t MAX_CALLS = ((uint64_t)1 << 48); + +/* + * gf_wrap -- In our implementation, GF(2^128) is represented as a 16 byte + * array with byte 0 the most significant and byte 15 the least significant. + * High bit carry reduction is based on the primitive polynomial + * + * X^128 + X^7 + X^2 + X + 1, + * + * which leads to the reduction formula X^128 = X^7 + X^2 + X + 1. Indeed, + * since 0 = (X^128 + X^7 + X^2 + 1) mod (X^128 + X^7 + X^2 + X + 1) and since + * addition of polynomials with coefficients in Z/Z(2) is just XOR, we can + * add X^128 to both sides to get + * + * X^128 = (X^7 + X^2 + X + 1) mod (X^128 + X^7 + X^2 + X + 1) + * + * and the coefficients of the polynomial on the right hand side form the + * string 1000 0111 = 0x87, which is the value of gf_wrap. + * + * This gets used in the following way. Doubling in GF(2^128) is just a left + * shift by 1 bit, except when the most significant bit is 1. In the latter + * case, the relation X^128 = X^7 + X^2 + X + 1 says that the high order bit + * that overflows beyond 128 bits can be replaced by addition of + * X^7 + X^2 + X + 1 <--> 0x87 to the low order 128 bits. Since addition + * in GF(2^128) is represented by XOR, we therefore only have to XOR 0x87 + * into the low order byte after a left shift when the starting high order + * bit is 1. + */ +const unsigned char gf_wrap = 0x87; + +/* + * assumes: out != NULL and points to a GF(2^n) value to receive the + * doubled value; + * in != NULL and points to a 16 byte GF(2^n) value + * to double; + * the in and out buffers do not overlap. + * effects: doubles the GF(2^n) value pointed to by "in" and places + * the result in the GF(2^n) value pointed to by "out." + */ +void gf_double(uint8_t *out, uint8_t *in) +{ + + /* start with low order byte */ + uint8_t *x = in + (TC_AES_BLOCK_SIZE - 1); + + /* if msb == 1, we need to add the gf_wrap value, otherwise add 0 */ + uint8_t carry = (in[0] >> 7) ? gf_wrap : 0; + + out += (TC_AES_BLOCK_SIZE - 1); + for (;;) { + *out-- = (*x << 1) ^ carry; + if (x == in) { + break; + } + carry = *x-- >> 7; + } +} + +int32_t tc_cmac_setup(TCCmacState_t s, const uint8_t *key, TCAesKeySched_t sched) +{ + + /* input sanity check: */ + if (s == (TCCmacState_t) 0 || + key == (const uint8_t *) 0) { + return TC_CRYPTO_FAIL; + } + + /* put s into a known state */ + _set(s, 0, sizeof(*s)); + s->sched = sched; + + /* configure the encryption key used by the underlying block cipher */ + tc_aes128_set_encrypt_key(s->sched, key); + + /* compute s->K1 and s->K2 from s->iv using s->keyid */ + _set(s->iv, 0, TC_AES_BLOCK_SIZE); + tc_aes_encrypt(s->iv, s->iv, s->sched); + gf_double (s->K1, s->iv); + gf_double (s->K2, s->K1); + + /* reset s->iv to 0 in case someone wants to compute now */ + tc_cmac_init(s); + + return TC_CRYPTO_SUCCESS; +} + +int32_t tc_cmac_erase(TCCmacState_t s) +{ + if (s == (TCCmacState_t) 0) { + return TC_CRYPTO_FAIL; + } + + /* destroy the current state */ + _set(s, 0, sizeof(*s)); + + return TC_CRYPTO_SUCCESS; +} + +int32_t tc_cmac_init(TCCmacState_t s) +{ + /* input sanity check: */ + if (s == (TCCmacState_t) 0) { + return TC_CRYPTO_FAIL; + } + + /* CMAC starts with an all zero initialization vector */ + _set(s->iv, 0, TC_AES_BLOCK_SIZE); + + /* and the leftover buffer is empty */ + _set(s->leftover, 0, TC_AES_BLOCK_SIZE); + s->leftover_offset = 0; + + /* Set countdown to max number of calls allowed before re-keying: */ + s->countdown = MAX_CALLS; + + return TC_CRYPTO_SUCCESS; +} + +int32_t tc_cmac_update(TCCmacState_t s, const uint8_t *data, size_t data_length) +{ + uint32_t i; + + /* input sanity check: */ + if (s == (TCCmacState_t) 0) { + return TC_CRYPTO_FAIL; + } + if (data_length == 0) { + return TC_CRYPTO_SUCCESS; + } + if (data == (const uint8_t *) 0) { + return TC_CRYPTO_FAIL; + } + + if (s->countdown == 0) { + return TC_CRYPTO_FAIL; + } + + s->countdown--; + + if (s->leftover_offset > 0) { + /* last data added to s didn't end on a TC_AES_BLOCK_SIZE byte boundary */ + size_t remaining_space = TC_AES_BLOCK_SIZE - s->leftover_offset; + + if (data_length < remaining_space) { + /* still not enough data to encrypt this time either */ + _copy(&s->leftover[s->leftover_offset], data_length, data, data_length); + s->leftover_offset += data_length; + return TC_CRYPTO_SUCCESS; + } + /* leftover block is now full; encrypt it first */ + _copy(&s->leftover[s->leftover_offset], + remaining_space, + data, + remaining_space); + data_length -= remaining_space; + data += remaining_space; + s->leftover_offset = 0; + + for (i = 0; i < TC_AES_BLOCK_SIZE; ++i) { + s->iv[i] ^= s->leftover[i]; + } + tc_aes_encrypt(s->iv, s->iv, s->sched); + } + + /* CBC encrypt each (except the last) of the data blocks */ + while (data_length > TC_AES_BLOCK_SIZE) { + for (i = 0; i < TC_AES_BLOCK_SIZE; ++i) { + s->iv[i] ^= data[i]; + } + tc_aes_encrypt(s->iv, s->iv, s->sched); + data += TC_AES_BLOCK_SIZE; + data_length -= TC_AES_BLOCK_SIZE; + } + + if (data_length > 0) { + /* save leftover data for next time */ + _copy(s->leftover, data_length, data, data_length); + s->leftover_offset = data_length; + } + + return TC_CRYPTO_SUCCESS; +} + +int32_t tc_cmac_final(uint8_t *tag, TCCmacState_t s) +{ + uint8_t *k; + uint32_t i; + + /* input sanity check: */ + if (tag == (uint8_t *) 0 || + s == (TCCmacState_t) 0) { + return TC_CRYPTO_FAIL; + } + + if (s->leftover_offset == TC_AES_BLOCK_SIZE) { + /* the last message block is a full-sized block */ + k = (uint8_t *) s->K1; + } else { + /* the final message block is not a full-sized block */ + size_t remaining = TC_AES_BLOCK_SIZE - s->leftover_offset; + + _set(&s->leftover[s->leftover_offset], 0, remaining); + s->leftover[s->leftover_offset] = TC_CMAC_PADDING; + k = (uint8_t *) s->K2; + } + for (i = 0; i < TC_AES_BLOCK_SIZE; ++i) { + s->iv[i] ^= s->leftover[i] ^ k[i]; + } + + tc_aes_encrypt(tag, s->iv, s->sched); + + /* erasing state: */ + tc_cmac_erase(s); + + return TC_CRYPTO_SUCCESS; +} diff --git a/kernel/protocols/bluetooth/core/tinycrypt/source/ctr_mode.c b/kernel/protocols/bluetooth/core/tinycrypt/source/ctr_mode.c new file mode 100644 index 0000000000..7ba53d0249 --- /dev/null +++ b/kernel/protocols/bluetooth/core/tinycrypt/source/ctr_mode.c @@ -0,0 +1,85 @@ +/* ctr_mode.c - TinyCrypt CTR mode implementation */ + +/* + * Copyright (C) 2015 by Intel Corporation, 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 Intel Corporation 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 OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 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 + +int32_t tc_ctr_mode(uint8_t *out, uint32_t outlen, const uint8_t *in, + uint32_t inlen, uint8_t *ctr, const TCAesKeySched_t sched) +{ + + uint8_t buffer[TC_AES_BLOCK_SIZE]; + uint8_t nonce[TC_AES_BLOCK_SIZE]; + uint32_t block_num; + uint32_t i; + + /* input sanity check: */ + if (out == (uint8_t *) 0 || + in == (uint8_t *) 0 || + ctr == (uint8_t *) 0 || + sched == (TCAesKeySched_t) 0 || + inlen == 0 || + outlen == 0 || + outlen != inlen) { + return TC_CRYPTO_FAIL; + } + + /* copy the ctr to the nonce */ + (void)_copy(nonce, sizeof(nonce), ctr, sizeof(nonce)); + + /* select the last 4 bytes of the nonce to be incremented */ + block_num = (nonce[12] << 24) | (nonce[13] << 16) | + (nonce[14] << 8) | (nonce[15]); + for (i = 0; i < inlen; ++i) { + if ((i % (TC_AES_BLOCK_SIZE)) == 0) { + /* encrypt data using the current nonce */ + if (tc_aes_encrypt(buffer, nonce, sched)) { + block_num++; + nonce[12] = (uint8_t)(block_num >> 24); + nonce[13] = (uint8_t)(block_num >> 16); + nonce[14] = (uint8_t)(block_num >> 8); + nonce[15] = (uint8_t)(block_num); + } else { + return TC_CRYPTO_FAIL; + } + } + /* update the output */ + *out++ = buffer[i%(TC_AES_BLOCK_SIZE)] ^ *in++; + } + + /* update the counter */ + ctr[12] = nonce[12]; ctr[13] = nonce[13]; + ctr[14] = nonce[14]; ctr[15] = nonce[15]; + + return TC_CRYPTO_SUCCESS; +} diff --git a/kernel/protocols/bluetooth/core/tinycrypt/source/ctr_prng.c b/kernel/protocols/bluetooth/core/tinycrypt/source/ctr_prng.c new file mode 100644 index 0000000000..bac81d8e2c --- /dev/null +++ b/kernel/protocols/bluetooth/core/tinycrypt/source/ctr_prng.c @@ -0,0 +1,308 @@ +/* ctr_prng.c - TinyCrypt implementation of CTR-PRNG */ + +/* + * Copyright (c) 2016, Chris Morrison + * 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. + * + * 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 +#include + +/* + * This PRNG is based on the CTR_DRBG described in Recommendation for Random + * Number Generation Using Deterministic Random Bit Generators, + * NIST SP 800-90A Rev. 1. + * + * Annotations to particular steps (e.g. 10.2.1.2 Step 1) refer to the steps + * described in that document. + * + */ + +/** + * @brief Array incrementer + * Treats the supplied array as one contiguous number (MSB in arr[0]), and + * increments it by one + * @return none + * @param arr IN/OUT -- array to be incremented + * @param len IN -- size of arr in bytes + */ +static void arrInc(uint8_t arr[], uint32_t len) +{ + uint32_t i; + if (0 != arr) + { + for (i = len; i > 0U; i--) + { + if (++arr[i-1] != 0U) + { + break; + } + } + } +} + +/** + * @brief CTR PRNG update + * Updates the internal state of supplied the CTR PRNG context + * increments it by one + * @return none + * @note Assumes: providedData is (TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE) bytes long + * @param ctx IN/OUT -- CTR PRNG state + * @param providedData IN -- data used when updating the internal state + */ +static void tc_ctr_prng_update(TCCtrPrng_t * const ctx, uint8_t const * const providedData) +{ + if (0 != ctx) + { + /* 10.2.1.2 step 1 */ + uint8_t temp[TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE]; + uint32_t len = 0U; + + /* 10.2.1.2 step 2 */ + while (len < sizeof temp) + { + uint32_t blocklen = sizeof(temp) - len; + uint8_t output_block[TC_AES_BLOCK_SIZE]; + + /* 10.2.1.2 step 2.1 */ + arrInc(ctx->V, sizeof ctx->V); + + /* 10.2.1.2 step 2.2 */ + if (blocklen > TC_AES_BLOCK_SIZE) + { + blocklen = TC_AES_BLOCK_SIZE; + } + (void)tc_aes_encrypt(output_block, ctx->V, &ctx->key); + + /* 10.2.1.2 step 2.3/step 3 */ + memcpy(&(temp[len]), output_block, blocklen); + + len += blocklen; + } + + /* 10.2.1.2 step 4 */ + if (0 != providedData) + { + uint32_t i; + for (i = 0U; i < sizeof temp; i++) + { + temp[i] ^= providedData[i]; + } + } + + /* 10.2.1.2 step 5 */ + (void)tc_aes128_set_encrypt_key(&ctx->key, temp); + + /* 10.2.1.2 step 6 */ + memcpy(ctx->V, &(temp[TC_AES_KEY_SIZE]), TC_AES_BLOCK_SIZE); + } +} + +int32_t tc_ctr_prng_init(TCCtrPrng_t * const ctx, + uint8_t const * const entropy, + uint32_t entropyLen, + uint8_t const * const personalization, + uint32_t pLen) +{ + int32_t result = TC_CRYPTO_FAIL; + uint32_t i; + uint8_t personalization_buf[TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE] = {0U}; + uint8_t seed_material[TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE]; + uint8_t zeroArr[TC_AES_BLOCK_SIZE] = {0U}; + + if (0 != personalization) + { + /* 10.2.1.3.1 step 1 */ + uint32_t len = pLen; + if (len > sizeof personalization_buf) + { + len = sizeof personalization_buf; + } + + /* 10.2.1.3.1 step 2 */ + memcpy(personalization_buf, personalization, len); + } + + if ((0 != ctx) && (0 != entropy) && (entropyLen >= sizeof seed_material)) + { + /* 10.2.1.3.1 step 3 */ + memcpy(seed_material, entropy, sizeof seed_material); + for (i = 0U; i < sizeof seed_material; i++) + { + seed_material[i] ^= personalization_buf[i]; + } + + /* 10.2.1.3.1 step 4 */ + (void)tc_aes128_set_encrypt_key(&ctx->key, zeroArr); + + /* 10.2.1.3.1 step 5 */ + memset(ctx->V, 0x00, sizeof ctx->V); + + /* 10.2.1.3.1 step 6 */ + tc_ctr_prng_update(ctx, seed_material); + + /* 10.2.1.3.1 step 7 */ + ctx->reseedCount = 1U; + + result = TC_CRYPTO_SUCCESS; + } + return result; +} + +int32_t tc_ctr_prng_reseed(TCCtrPrng_t * const ctx, + uint8_t const * const entropy, + uint32_t entropyLen, + uint8_t const * const additional_input, + uint32_t additionallen) +{ + uint32_t i; + int32_t result = TC_CRYPTO_FAIL; + uint8_t additional_input_buf[TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE] = {0U}; + uint8_t seed_material[TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE]; + + if (0 != additional_input) + { + /* 10.2.1.4.1 step 1 */ + uint32_t len = additionallen; + if (len > sizeof additional_input_buf) + { + len = sizeof additional_input_buf; + } + + /* 10.2.1.4.1 step 2 */ + memcpy(additional_input_buf, additional_input, len); + } + + uint32_t seedlen = (uint32_t)TC_AES_KEY_SIZE + (uint32_t)TC_AES_BLOCK_SIZE; + if ((0 != ctx) && (entropyLen >= seedlen)) + { + /* 10.2.1.4.1 step 3 */ + memcpy(seed_material, entropy, sizeof seed_material); + for (i = 0U; i < sizeof seed_material; i++) + { + seed_material[i] ^= additional_input_buf[i]; + } + + /* 10.2.1.4.1 step 4 */ + tc_ctr_prng_update(ctx, seed_material); + + /* 10.2.1.4.1 step 5 */ + ctx->reseedCount = 1U; + + result = TC_CRYPTO_SUCCESS; + } + return result; +} + +int32_t tc_ctr_prng_generate(TCCtrPrng_t * const ctx, + uint8_t const * const additional_input, + uint32_t additionallen, + uint8_t * const out, + uint32_t outlen) +{ + /* 2^48 - see section 10.2.1 */ + static const uint64_t MAX_REQS_BEFORE_RESEED = 0x1000000000000ULL; + + /* 2^19 bits - see section 10.2.1 */ + static const uint32_t MAX_BYTES_PER_REQ = 65536U; + + int32_t result = TC_CRYPTO_FAIL; + + if ((0 != ctx) && (0 != out) && (outlen < MAX_BYTES_PER_REQ)) + { + /* 10.2.1.5.1 step 1 */ + if (ctx->reseedCount > MAX_REQS_BEFORE_RESEED) + { + result = TC_CTR_PRNG_RESEED_REQ; + } + else + { + uint8_t additional_input_buf[TC_AES_KEY_SIZE + TC_AES_BLOCK_SIZE] = {0U}; + if (0 != additional_input) + { + /* 10.2.1.5.1 step 2 */ + uint32_t len = additionallen; + if (len > sizeof additional_input_buf) + { + len = sizeof additional_input_buf; + } + memcpy(additional_input_buf, additional_input, len); + tc_ctr_prng_update(ctx, additional_input_buf); + } + + /* 10.2.1.5.1 step 3 - implicit */ + + /* 10.2.1.5.1 step 4 */ + uint32_t len = 0U; + while (len < outlen) + { + uint32_t blocklen = outlen - len; + uint8_t output_block[TC_AES_BLOCK_SIZE]; + + /* 10.2.1.5.1 step 4.1 */ + arrInc(ctx->V, sizeof ctx->V); + + /* 10.2.1.5.1 step 4.2 */ + (void)tc_aes_encrypt(output_block, ctx->V, &ctx->key); + + /* 10.2.1.5.1 step 4.3/step 5 */ + if (blocklen > TC_AES_BLOCK_SIZE) + { + blocklen = TC_AES_BLOCK_SIZE; + } + memcpy(&(out[len]), output_block, blocklen); + + len += blocklen; + } + + /* 10.2.1.5.1 step 6 */ + tc_ctr_prng_update(ctx, additional_input_buf); + + /* 10.2.1.5.1 step 7 */ + ctx->reseedCount++; + + /* 10.2.1.5.1 step 8 */ + result = TC_CRYPTO_SUCCESS; + } + } + + return result; +} + +void tc_ctr_prng_uninstantiate(TCCtrPrng_t * const ctx) +{ + if (0 != ctx) + { + memset(ctx->key.words, 0x00, sizeof ctx->key.words); + memset(ctx->V, 0x00, sizeof ctx->V); + ctx->reseedCount = 0U; + } +} + + + + diff --git a/kernel/protocols/bluetooth/core/tinycrypt/source/ecc.c b/kernel/protocols/bluetooth/core/tinycrypt/source/ecc.c new file mode 100644 index 0000000000..bfe6c5f135 --- /dev/null +++ b/kernel/protocols/bluetooth/core/tinycrypt/source/ecc.c @@ -0,0 +1,625 @@ +/* ecc.c - TinyCrypt implementation of ECC auxiliary functions */ + +/* + * + * Copyright (c) 2013, Kenneth MacKay + * All rights reserved. + * https://github.com/kmackay/micro-ecc + * + * 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. + * + * 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) 2015 by Intel Corporation, 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 Intel Corporation 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 OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +/* ------ Curve NIST P-256 constants: ------ */ + +#define Curve_P {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, \ + 0x00000000, 0x00000000, 0x00000001, 0xFFFFFFFF} + +#define Curve_B {0x27D2604B, 0x3BCE3C3E, 0xCC53B0F6, 0x651D06B0, \ + 0x769886BC, 0xB3EBBD55, 0xAA3A93E7, 0x5AC635D8} + +#define Curve_N {0xFC632551, 0xF3B9CAC2, 0xA7179E84, 0xBCE6FAAD, \ + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF} + +#define Curve_G {{0xD898C296, 0xF4A13945, 0x2DEB33A0, 0x77037D81, \ + 0x63A440F2, 0xF8BCE6E5, 0xE12C4247, 0x6B17D1F2}, \ + {0x37BF51F5, 0xCBB64068, 0x6B315ECE, 0x2BCE3357, \ + 0x7C0F9E16, 0x8EE7EB4A, 0xFE1A7F9B, 0x4FE342E2} } + +#define Curve_P_Barrett {0x00000003, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFE, \ + 0xFFFFFFFE, 0xFFFFFFFE, 0xFFFFFFFF, 0x00000000, 0x00000001} + +#define Curve_N_Barrett {0xEEDF9BFE, 0x012FFD85, 0xDF1A6C21, 0x43190552, \ + 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0x00000000, 0x00000001} + +uint32_t curve_p[NUM_ECC_DIGITS] = Curve_P; +uint32_t curve_b[NUM_ECC_DIGITS] = Curve_B; +EccPoint curve_G = Curve_G; +uint32_t curve_n[NUM_ECC_DIGITS] = Curve_N; +uint32_t curve_pb[NUM_ECC_DIGITS + 1] = Curve_P_Barrett; +uint32_t curve_nb[NUM_ECC_DIGITS + 1] = Curve_N_Barrett; + +/* ------ Static functions: ------ */ + +/* Zeroing out p_vli. */ +static void vli_clear(uint32_t *p_vli) +{ + uint32_t i; + + for (i = 0; i < NUM_ECC_DIGITS; ++i) { + p_vli[i] = 0; + } +} + +/* Returns nonzero if bit p_bit of p_vli is set. + * It is assumed that the value provided in 'bit' is within + * the boundaries of the word-array 'p_vli'.*/ +static uint32_t vli_testBit(uint32_t *p_vli, uint32_t p_bit) +{ + return (p_vli[p_bit / 32] & (1 << (p_bit % 32))); +} + +uint32_t vli_isZero(uint32_t *p_vli) +{ + uint32_t acc = 0; + + for (uint32_t i = 0; i < NUM_ECC_DIGITS; ++i) { + acc |= p_vli[i]; + } + + return (!acc); +} + +/* + * Find the right-most nonzero 32-bit "digits" in p_vli. + * + * Side-channel countermeasure: algorithm strengthened against timing attack. + */ +static uint32_t vli_numDigits(uint32_t *p_vli) +{ + int32_t i; + uint32_t digits = 0; + + for (i = NUM_ECC_DIGITS - 1; i >= 0 ; --i) { + digits += p_vli[i] || digits; + } + + return digits; +} + +/* + * Find the left-most non-zero bit in p_vli. + * + * Side-channel countermeasure: algorithm strengthened against timing attack. + */ +static uint32_t vli_numBits(uint32_t *p_vli) +{ + uint32_t l_digit; + uint32_t i, acc = 32; + uint32_t l_numDigits = vli_numDigits(p_vli); + + l_digit = p_vli[l_numDigits - 1]; + + for (i = 0; i < 32; ++i) { + acc -= !l_digit; + l_digit >>= 1; + } + + return ((l_numDigits - 1) * 32 + acc); +} + +/* + * Computes p_result = p_left + p_right, returns carry. + * + * Side-channel countermeasure: algorithm strengthened against timing attack. + */ +static uint32_t vli_add(uint32_t *p_result, uint32_t *p_left, + uint32_t *p_right) +{ + + uint32_t l_carry = 0; + + for (uint32_t i = 0; i < NUM_ECC_DIGITS; ++i) { + uint32_t l_sum = p_left[i] + p_right[i] + l_carry; + + l_carry = (l_sum < p_left[i]) | ((l_sum == p_left[i]) && l_carry); + p_result[i] = l_sum; + } + + return l_carry; +} + + +/* Computes p_result = p_left * p_right. */ +static void vli_mult(uint32_t *p_result, uint32_t *p_left, + uint32_t *p_right, uint32_t word_size) +{ + + uint64_t r01 = 0; + uint32_t r2 = 0; + + /* Compute each digit of p_result in sequence, maintaining the carries. */ + for (uint32_t k = 0; k < word_size*2 - 1; ++k) { + + uint32_t l_min = (k < word_size ? 0 : (k + 1) - word_size); + + for (uint32_t i = l_min; i <= k && i < word_size; ++i) { + + uint64_t l_product = (uint64_t)p_left[i] * p_right[k - i]; + + r01 += l_product; + r2 += (r01 < l_product); + } + p_result[k] = (uint32_t)r01; + r01 = (r01 >> 32) | (((uint64_t)r2) << 32); + r2 = 0; + } + + p_result[word_size * 2 - 1] = (uint32_t)r01; +} + +/* Computes p_result = p_left^2. */ +static void vli_square(uint32_t *p_result, uint32_t *p_left) +{ + + uint64_t r01 = 0; + uint32_t r2 = 0; + uint32_t i, k; + + for (k = 0; k < NUM_ECC_DIGITS * 2 - 1; ++k) { + + uint32_t l_min = (k < NUM_ECC_DIGITS ? 0 : (k + 1) - NUM_ECC_DIGITS); + + for (i = l_min; i <= k && i <= k - i; ++i) { + + uint64_t l_product = (uint64_t)p_left[i] * p_left[k - i]; + + if (i < k - i) { + + r2 += l_product >> 63; + l_product *= 2; + } + r01 += l_product; + r2 += (r01 < l_product); + } + p_result[k] = (uint32_t)r01; + r01 = (r01 >> 32) | (((uint64_t)r2) << 32); + r2 = 0; + } + + p_result[NUM_ECC_DIGITS * 2 - 1] = (uint32_t)r01; +} + +/* Computes p_result = p_product % curve_p using Barrett reduction. */ +void vli_mmod_barrett(uint32_t *p_result, uint32_t *p_product, + uint32_t *p_mod, uint32_t *p_barrett) +{ + uint32_t i; + uint32_t q1[NUM_ECC_DIGITS + 1]; + + for (i = NUM_ECC_DIGITS - 1; i < 2 * NUM_ECC_DIGITS; i++) { + q1[i - (NUM_ECC_DIGITS - 1)] = p_product[i]; + } + + uint32_t q2[2*NUM_ECC_DIGITS + 2]; + + vli_mult(q2, q1, p_barrett, NUM_ECC_DIGITS + 1); + for (i = NUM_ECC_DIGITS + 1; i < 2 * NUM_ECC_DIGITS + 2; i++) { + q1[i - (NUM_ECC_DIGITS + 1)] = q2[i]; + } + + uint32_t prime2[2*NUM_ECC_DIGITS]; + + for (i = 0; i < NUM_ECC_DIGITS; i++) { + prime2[i] = p_mod[i]; + prime2[NUM_ECC_DIGITS + i] = 0; + } + + vli_mult(q2, q1, prime2, NUM_ECC_DIGITS + 1); + vli_sub(p_product, p_product, q2, 2 * NUM_ECC_DIGITS); + + uint32_t borrow; + + borrow = vli_sub(q1, p_product, prime2, NUM_ECC_DIGITS + 1); + vli_cond_set(p_product, p_product, q1, borrow); + p_product[NUM_ECC_DIGITS] = q1[NUM_ECC_DIGITS] * (!borrow); + borrow = vli_sub(q1, p_product, prime2, NUM_ECC_DIGITS + 1); + vli_cond_set(p_product, p_product, q1, borrow); + p_product[NUM_ECC_DIGITS] = q1[NUM_ECC_DIGITS] * (!borrow); + borrow = vli_sub(q1, p_product, prime2, NUM_ECC_DIGITS + 1); + vli_cond_set(p_product, p_product, q1, borrow); + p_product[NUM_ECC_DIGITS] = q1[NUM_ECC_DIGITS] * (!borrow); + + for (i = 0; i < NUM_ECC_DIGITS; i++) { + p_result[i] = p_product[i]; + } +} + +/* + * Computes modular exponentiation. + * + * Side-channel countermeasure: algorithm strengthened against timing attack. + */ +static void vli_modExp(uint32_t *p_result, uint32_t *p_base, + uint32_t *p_exp, uint32_t *p_mod, uint32_t *p_barrett) +{ + + uint32_t acc[NUM_ECC_DIGITS], tmp[NUM_ECC_DIGITS], product[2 * NUM_ECC_DIGITS]; + uint32_t j; + int32_t i; + + vli_clear(acc); + acc[0] = 1; + + for (i = NUM_ECC_DIGITS - 1; i >= 0; i--) { + for (j = 1 << 31; j > 0; j = j >> 1) { + vli_square(product, acc); + vli_mmod_barrett(acc, product, p_mod, p_barrett); + vli_mult(product, acc, p_base, NUM_ECC_DIGITS); + vli_mmod_barrett(tmp, product, p_mod, p_barrett); + vli_cond_set(acc, tmp, acc, j & p_exp[i]); + } + } + + vli_set(p_result, acc); +} + +/* Conversion from Affine coordinates to Jacobi coordinates. */ +static void EccPoint_fromAffine(EccPointJacobi *p_point_jacobi, + EccPoint *p_point) { + + vli_set(p_point_jacobi->X, p_point->x); + vli_set(p_point_jacobi->Y, p_point->y); + vli_clear(p_point_jacobi->Z); + p_point_jacobi->Z[0] = 1; +} + +/* + * Elliptic curve point doubling in Jacobi coordinates: P = P + P. + * + * Requires 4 squares and 4 multiplications. + */ +static void EccPoint_double(EccPointJacobi *P) +{ + + uint32_t m[NUM_ECC_DIGITS], s[NUM_ECC_DIGITS], t[NUM_ECC_DIGITS]; + + vli_modSquare_fast(t, P->Z); + vli_modSub(m, P->X, t, curve_p); + vli_modAdd(s, P->X, t, curve_p); + vli_modMult_fast(m, m, s); + vli_modAdd(s, m, m, curve_p); + vli_modAdd(m, s, m, curve_p); /* m = 3X^2 - 3Z^4 */ + vli_modSquare_fast(t, P->Y); + vli_modMult_fast(s, P->X, t); + vli_modAdd(s, s, s, curve_p); + vli_modAdd(s, s, s, curve_p); /* s = 4XY^2 */ + vli_modMult_fast(P->Z, P->Y, P->Z); + vli_modAdd(P->Z, P->Z, P->Z, curve_p); /* Z' = 2YZ */ + vli_modSquare_fast(P->X, m); + vli_modSub(P->X, P->X, s, curve_p); + vli_modSub(P->X, P->X, s, curve_p); /* X' = m^2 - 2s */ + vli_modSquare_fast(P->Y, t); + vli_modAdd(P->Y, P->Y, P->Y, curve_p); + vli_modAdd(P->Y, P->Y, P->Y, curve_p); + vli_modAdd(P->Y, P->Y, P->Y, curve_p); + vli_modSub(t, s, P->X, curve_p); + vli_modMult_fast(t, t, m); + vli_modSub(P->Y, t, P->Y, curve_p); /* Y' = m(s - X') - 8Y^4 */ + +} + +/* Copy input to target. */ +static void EccPointJacobi_set(EccPointJacobi *target, EccPointJacobi *input) +{ + vli_set(target->X, input->X); + vli_set(target->Y, input->Y); + vli_set(target->Z, input->Z); +} + +/* ------ Externally visible functions (see header file for comments): ------ */ + +void vli_set(uint32_t *p_dest, uint32_t *p_src) +{ + + uint32_t i; + + for (i = 0; i < NUM_ECC_DIGITS; ++i) { + p_dest[i] = p_src[i]; + } +} + +int32_t vli_cmp(uint32_t *p_left, uint32_t *p_right, int32_t word_size) +{ + + int32_t i, cmp = 0; + + for (i = word_size-1; i >= 0; --i) { + cmp |= ((p_left[i] > p_right[i]) - (p_left[i] < p_right[i])) * (!cmp); + } + + return cmp; +} + +uint32_t vli_sub(uint32_t *p_result, uint32_t *p_left, uint32_t *p_right, + uint32_t word_size) +{ + + uint32_t l_borrow = 0; + + for (uint32_t i = 0; i < word_size; ++i) { + uint32_t l_diff = p_left[i] - p_right[i] - l_borrow; + + l_borrow = (l_diff > p_left[i]) | ((l_diff == p_left[i]) && l_borrow); + p_result[i] = l_diff; + } + + return l_borrow; +} + +void vli_cond_set(uint32_t *output, uint32_t *p_true, uint32_t *p_false, + uint32_t cond) +{ + uint32_t i; + + cond = (!cond); + + for (i = 0; i < NUM_ECC_DIGITS; i++) { + output[i] = (p_true[i]*(!cond)) | (p_false[i]*cond); + } +} + +void vli_modAdd(uint32_t *p_result, uint32_t *p_left, uint32_t *p_right, + uint32_t *p_mod) +{ + uint32_t l_carry = vli_add(p_result, p_left, p_right); + uint32_t p_temp[NUM_ECC_DIGITS]; + + l_carry = l_carry == vli_sub(p_temp, p_result, p_mod, NUM_ECC_DIGITS); + vli_cond_set(p_result, p_temp, p_result, l_carry); +} + +void vli_modSub(uint32_t *p_result, uint32_t *p_left, uint32_t *p_right, + uint32_t *p_mod) +{ + uint32_t l_borrow = vli_sub(p_result, p_left, p_right, NUM_ECC_DIGITS); + uint32_t p_temp[NUM_ECC_DIGITS]; + + vli_add(p_temp, p_result, p_mod); + vli_cond_set(p_result, p_temp, p_result, l_borrow); +} + +void vli_modMult_fast(uint32_t *p_result, uint32_t *p_left, + uint32_t *p_right) +{ + uint32_t l_product[2 * NUM_ECC_DIGITS]; + + vli_mult(l_product, p_left, p_right, NUM_ECC_DIGITS); + vli_mmod_barrett(p_result, l_product, curve_p, curve_pb); +} + +void vli_modSquare_fast(uint32_t *p_result, uint32_t *p_left) +{ + uint32_t l_product[2 * NUM_ECC_DIGITS]; + + vli_square(l_product, p_left); + vli_mmod_barrett(p_result, l_product, curve_p, curve_pb); +} + +void vli_modMult(uint32_t *p_result, uint32_t *p_left, uint32_t *p_right, + uint32_t *p_mod, uint32_t *p_barrett) +{ + + uint32_t l_product[2 * NUM_ECC_DIGITS]; + + vli_mult(l_product, p_left, p_right, NUM_ECC_DIGITS); + vli_mmod_barrett(p_result, l_product, p_mod, p_barrett); +} + +void vli_modInv(uint32_t *p_result, uint32_t *p_input, uint32_t *p_mod, + uint32_t *p_barrett) +{ + uint32_t p_power[NUM_ECC_DIGITS]; + + vli_set(p_power, p_mod); + p_power[0] -= 2; + vli_modExp(p_result, p_input, p_power, p_mod, p_barrett); +} + +uint32_t EccPoint_isZero(EccPoint *p_point) +{ + return (vli_isZero(p_point->x) && vli_isZero(p_point->y)); +} + +uint32_t EccPointJacobi_isZero(EccPointJacobi *p_point_jacobi) +{ + return vli_isZero(p_point_jacobi->Z); +} + +void EccPoint_toAffine(EccPoint *p_point, EccPointJacobi *p_point_jacobi) +{ + + if (vli_isZero(p_point_jacobi->Z)) { + vli_clear(p_point->x); + vli_clear(p_point->y); + return; + } + + uint32_t z[NUM_ECC_DIGITS]; + + vli_set(z, p_point_jacobi->Z); + vli_modInv(z, z, curve_p, curve_pb); + vli_modSquare_fast(p_point->x, z); + vli_modMult_fast(p_point->y, p_point->x, z); + vli_modMult_fast(p_point->x, p_point->x, p_point_jacobi->X); + vli_modMult_fast(p_point->y, p_point->y, p_point_jacobi->Y); +} + +void EccPoint_add(EccPointJacobi *P1, EccPointJacobi *P2) +{ + + uint32_t s1[NUM_ECC_DIGITS], u1[NUM_ECC_DIGITS], t[NUM_ECC_DIGITS]; + uint32_t h[NUM_ECC_DIGITS], r[NUM_ECC_DIGITS]; + + vli_modSquare_fast(r, P1->Z); + vli_modSquare_fast(s1, P2->Z); + vli_modMult_fast(u1, P1->X, s1); /* u1 = X1 Z2^2 */ + vli_modMult_fast(h, P2->X, r); + vli_modMult_fast(s1, P1->Y, s1); + vli_modMult_fast(s1, s1, P2->Z); /* s1 = Y1 Z2^3 */ + vli_modMult_fast(r, P2->Y, r); + vli_modMult_fast(r, r, P1->Z); + vli_modSub(h, h, u1, curve_p); /* h = X2 Z1^2 - u1 */ + vli_modSub(r, r, s1, curve_p); /* r = Y2 Z1^3 - s1 */ + + if (vli_isZero(h)) { + if (vli_isZero(r)) { + /* P1 = P2 */ + EccPoint_double(P1); + return; + } + /* point at infinity */ + vli_clear(P1->Z); + return; + } + + vli_modMult_fast(P1->Z, P1->Z, P2->Z); + vli_modMult_fast(P1->Z, P1->Z, h); /* Z3 = h Z1 Z2 */ + vli_modSquare_fast(t, h); + vli_modMult_fast(h, t, h); + vli_modMult_fast(u1, u1, t); + vli_modSquare_fast(P1->X, r); + vli_modSub(P1->X, P1->X, h, curve_p); + vli_modSub(P1->X, P1->X, u1, curve_p); + vli_modSub(P1->X, P1->X, u1, curve_p); /* X3 = r^2 - h^3 - 2 u1 h^2 */ + vli_modMult_fast(t, s1, h); + vli_modSub(P1->Y, u1, P1->X, curve_p); + vli_modMult_fast(P1->Y, P1->Y, r); + vli_modSub(P1->Y, P1->Y, t, curve_p); /* Y3 = r(u1 h^2 - X3) - s1 h^3 */ +} + +/* + * Elliptic curve scalar multiplication with result in Jacobi coordinates: + * + * p_result = p_scalar * p_point. + */ +void EccPoint_mult_safe(EccPointJacobi *p_result, EccPoint *p_point, uint32_t *p_scalar) +{ + + int32_t i; + uint32_t bit; + EccPointJacobi p_point_jacobi, p_tmp; + + EccPoint_fromAffine(p_result, p_point); + EccPoint_fromAffine(&p_point_jacobi, p_point); + + for (i = vli_numBits(p_scalar) - 2; i >= 0; i--) { + EccPoint_double(p_result); + EccPointJacobi_set(&p_tmp, p_result); + EccPoint_add(&p_tmp, &p_point_jacobi); + bit = vli_testBit(p_scalar, i); + vli_cond_set(p_result->X, p_tmp.X, p_result->X, bit); + vli_cond_set(p_result->Y, p_tmp.Y, p_result->Y, bit); + vli_cond_set(p_result->Z, p_tmp.Z, p_result->Z, bit); + } +} + +/* Ellptic curve scalar multiplication with result in Jacobi coordinates */ +/* p_result = p_scalar * p_point */ +void EccPoint_mult_unsafe(EccPointJacobi *p_result, EccPoint *p_point, uint32_t *p_scalar) +{ + int i; + EccPointJacobi p_point_jacobi; + EccPoint_fromAffine(p_result, p_point); + EccPoint_fromAffine(&p_point_jacobi, p_point); + + for(i = vli_numBits(p_scalar) - 2; i >= 0; i--) + { + EccPoint_double(p_result); + if (vli_testBit(p_scalar, i)) + { + EccPoint_add(p_result, &p_point_jacobi); + } + } +} + +/* -------- Conversions between big endian and little endian: -------- */ + +void ecc_bytes2native(uint32_t p_native[NUM_ECC_DIGITS], + uint8_t p_bytes[NUM_ECC_DIGITS * 4]) +{ + + uint32_t i; + + for (i = 0; i < NUM_ECC_DIGITS; ++i) { + uint8_t *p_digit = p_bytes + 4 * (NUM_ECC_DIGITS - 1 - i); + + p_native[i] = ((uint32_t)p_digit[0] << 24) | + ((uint32_t)p_digit[1] << 16) | + ((uint32_t)p_digit[2] << 8) | + (uint32_t)p_digit[3]; + } +} + +void ecc_native2bytes(uint8_t p_bytes[NUM_ECC_DIGITS * 4], + uint32_t p_native[NUM_ECC_DIGITS]) +{ + + uint32_t i; + + for (i = 0; i < NUM_ECC_DIGITS; ++i) { + uint8_t *p_digit = p_bytes + 4 * (NUM_ECC_DIGITS - 1 - i); + + p_digit[0] = p_native[i] >> 24; + p_digit[1] = p_native[i] >> 16; + p_digit[2] = p_native[i] >> 8; + p_digit[3] = p_native[i]; + } +} + diff --git a/kernel/protocols/bluetooth/core/tinycrypt/source/ecc_dh.c b/kernel/protocols/bluetooth/core/tinycrypt/source/ecc_dh.c new file mode 100644 index 0000000000..861001d436 --- /dev/null +++ b/kernel/protocols/bluetooth/core/tinycrypt/source/ecc_dh.c @@ -0,0 +1,132 @@ +/* ec_dh.c - TinyCrypt implementation of EC-DH */ + +/* + * Copyright (C) 2015 by Intel Corporation, 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 Intel Corporation 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 OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 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 + +extern uint32_t curve_p[NUM_ECC_DIGITS]; +extern uint32_t curve_b[NUM_ECC_DIGITS]; +extern uint32_t curve_n[NUM_ECC_DIGITS]; +extern uint32_t curve_pb[NUM_ECC_DIGITS + 1]; +extern EccPoint curve_G; + +int32_t ecc_make_key(EccPoint *p_publicKey, uint32_t p_privateKey[NUM_ECC_DIGITS], + uint32_t p_random[NUM_ECC_DIGITS * 2]) +{ + /* computing modular reduction of p_random (see FIPS 186.4 B.4.1): */ + vli_mmod_barrett(p_privateKey, p_random, curve_p, curve_pb); + + /* Make sure the private key is in the range [1, n-1]. + * For the supported curve, n is always large enough + * that we only need to subtract once at most. + */ + uint32_t p_tmp[NUM_ECC_DIGITS]; + vli_sub(p_tmp, p_privateKey, curve_n, NUM_ECC_DIGITS); + + vli_cond_set(p_privateKey, p_privateKey, p_tmp, + vli_cmp(curve_n, p_privateKey, NUM_ECC_DIGITS) == 1); + + /* erasing temporary buffer used to store secret: */ + for (uint32_t i = 0; i < NUM_ECC_DIGITS; i++) + p_tmp[i] = 0; + + if (vli_isZero(p_privateKey)) { + return TC_CRYPTO_FAIL; /* The private key cannot be 0 (mod p). */ + } + + EccPointJacobi P; + + EccPoint_mult_safe(&P, &curve_G, p_privateKey); + EccPoint_toAffine(p_publicKey, &P); + + return TC_CRYPTO_SUCCESS; +} + +/* Compute p_result = x^3 - 3x + b */ +static void curve_x_side(uint32_t p_result[NUM_ECC_DIGITS], + uint32_t x[NUM_ECC_DIGITS]) +{ + + uint32_t _3[NUM_ECC_DIGITS] = {3}; /* -a = 3 */ + + vli_modSquare_fast(p_result, x); /* r = x^2 */ + vli_modSub(p_result, p_result, _3, curve_p); /* r = x^2 - 3 */ + vli_modMult_fast(p_result, p_result, x); /* r = x^3 - 3x */ + vli_modAdd(p_result, p_result, curve_b, curve_p); /* r = x^3 - 3x + b */ + +} + +int32_t ecc_valid_public_key(EccPoint *p_publicKey) +{ + uint32_t l_tmp1[NUM_ECC_DIGITS]; + uint32_t l_tmp2[NUM_ECC_DIGITS]; + + if (EccPoint_isZero(p_publicKey)) { + return -1; + } + + if ((vli_cmp(curve_p, p_publicKey->x, NUM_ECC_DIGITS) != 1) || + (vli_cmp(curve_p, p_publicKey->y, NUM_ECC_DIGITS) != 1)) { + return -2; + } + + vli_modSquare_fast(l_tmp1, p_publicKey->y); /* tmp1 = y^2 */ + + curve_x_side(l_tmp2, p_publicKey->x); /* tmp2 = x^3 - 3x + b */ + + /* Make sure that y^2 == x^3 + ax + b */ + if (vli_cmp(l_tmp1, l_tmp2, NUM_ECC_DIGITS) != 0) { + return -3; + } + + if (vli_cmp(p_publicKey->x, curve_G.x, NUM_ECC_DIGITS) == 0 && + vli_cmp(p_publicKey->y, curve_G.y, NUM_ECC_DIGITS) == 0 ) + return -4; + + return 0; +} + +int32_t ecdh_shared_secret(uint32_t p_secret[NUM_ECC_DIGITS], + EccPoint *p_publicKey, uint32_t p_privateKey[NUM_ECC_DIGITS]) +{ + + EccPoint p_point; + EccPointJacobi P; + + EccPoint_mult_safe(&P, p_publicKey, p_privateKey); + if (EccPointJacobi_isZero(&P)) { + return TC_CRYPTO_FAIL; + } + EccPoint_toAffine(&p_point, &P); + vli_set(p_secret, p_point.x); + + return TC_CRYPTO_SUCCESS; +} diff --git a/kernel/protocols/bluetooth/core/tinycrypt/source/ecc_dsa.c b/kernel/protocols/bluetooth/core/tinycrypt/source/ecc_dsa.c new file mode 100644 index 0000000000..dd84a1834d --- /dev/null +++ b/kernel/protocols/bluetooth/core/tinycrypt/source/ecc_dsa.c @@ -0,0 +1,115 @@ +/* ec_dsa.c - TinyCrypt implementation of EC-DSA */ + +/* + * Copyright (C) 2015 by Intel Corporation, 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 Intel Corporation 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 OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 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 + +extern uint32_t curve_n[NUM_ECC_DIGITS]; +extern EccPoint curve_G; +extern uint32_t curve_nb[NUM_ECC_DIGITS + 1]; + +int32_t ecdsa_sign(uint32_t r[NUM_ECC_DIGITS], uint32_t s[NUM_ECC_DIGITS], + uint32_t p_privateKey[NUM_ECC_DIGITS], uint32_t p_random[NUM_ECC_DIGITS], + uint32_t p_hash[NUM_ECC_DIGITS]) +{ + + uint32_t k[NUM_ECC_DIGITS], tmp[NUM_ECC_DIGITS]; + EccPoint p_point; + EccPointJacobi P; + + if (vli_isZero(p_random)) { + return TC_CRYPTO_FAIL; /* The random number must not be 0. */ + } + + vli_set(k, p_random); + + vli_sub(tmp, k, curve_n, NUM_ECC_DIGITS); + vli_cond_set(k, k, tmp, vli_cmp(curve_n, k, NUM_ECC_DIGITS) == 1); + + /* tmp = k * G */ + EccPoint_mult_safe(&P, &curve_G, k); + EccPoint_toAffine(&p_point, &P); + + /* r = x1 (mod n) */ + vli_set(r, p_point.x); + if (vli_cmp(curve_n, r, NUM_ECC_DIGITS) != 1) { + vli_sub(r, r, curve_n, NUM_ECC_DIGITS); + } + + if (vli_isZero(r)) { + return TC_CRYPTO_FAIL; /* If r == 0, fail (need a different random number). */ + } + + vli_modMult(s, r, p_privateKey, curve_n, curve_nb); /* s = r*d */ + vli_modAdd(s, p_hash, s, curve_n); /* s = e + r*d */ + vli_modInv(k, k, curve_n, curve_nb); /* k = 1 / k */ + vli_modMult(s, s, k, curve_n, curve_nb); /* s = (e + r*d) / k */ + + return TC_CRYPTO_SUCCESS; +} + +int32_t ecdsa_verify(EccPoint *p_publicKey, uint32_t p_hash[NUM_ECC_DIGITS], + uint32_t r[NUM_ECC_DIGITS], uint32_t s[NUM_ECC_DIGITS]) +{ + + uint32_t u1[NUM_ECC_DIGITS], u2[NUM_ECC_DIGITS]; + uint32_t z[NUM_ECC_DIGITS]; + EccPointJacobi P, R; + EccPoint p_point; + + if (vli_isZero(r) || vli_isZero(s)) { + return TC_CRYPTO_FAIL; /* r, s must not be 0. */ + } + + if ((vli_cmp(curve_n, r, NUM_ECC_DIGITS) != 1) || + (vli_cmp(curve_n, s, NUM_ECC_DIGITS) != 1)) { + return TC_CRYPTO_FAIL; /* r, s must be < n. */ + } + + /* Calculate u1 and u2. */ + vli_modInv(z, s, curve_n, curve_nb); /* Z = s^-1 */ + vli_modMult(u1, p_hash, z, curve_n, curve_nb); /* u1 = e/s */ + vli_modMult(u2, r, z, curve_n, curve_nb); /* u2 = r/s */ + + /* calculate P = u1*G + u2*Q */ + EccPoint_mult_unsafe(&P, &curve_G, u1); + EccPoint_mult_unsafe(&R, p_publicKey, u2); + EccPoint_add(&P, &R); + EccPoint_toAffine(&p_point, &P); + + /* Accept only if P.x == r. */ + if (!vli_sub(z, p_point.x, curve_n, NUM_ECC_DIGITS)) { + vli_set(p_point.x, z); + } + + return (vli_cmp(p_point.x, r, NUM_ECC_DIGITS) == 0); +} diff --git a/kernel/protocols/bluetooth/core/tinycrypt/source/hmac.c b/kernel/protocols/bluetooth/core/tinycrypt/source/hmac.c new file mode 100644 index 0000000000..e256846edf --- /dev/null +++ b/kernel/protocols/bluetooth/core/tinycrypt/source/hmac.c @@ -0,0 +1,147 @@ +/* hmac.c - TinyCrypt implementation of the HMAC algorithm */ + +/* + * Copyright (C) 2015 by Intel Corporation, 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 Intel Corporation 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 OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 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 + +static void rekey(uint8_t *key, const uint8_t *new_key, uint32_t key_size) +{ + const uint8_t inner_pad = (uint8_t) 0x36; + const uint8_t outer_pad = (uint8_t) 0x5c; + uint32_t i; + + for (i = 0; i < key_size; ++i) { + key[i] = inner_pad ^ new_key[i]; + key[i + TC_SHA256_BLOCK_SIZE] = outer_pad ^ new_key[i]; + } + for (; i < TC_SHA256_BLOCK_SIZE; ++i) { + key[i] = inner_pad; key[i + TC_SHA256_BLOCK_SIZE] = outer_pad; + } +} + +int32_t tc_hmac_set_key(TCHmacState_t ctx, + const uint8_t *key, + uint32_t key_size) +{ + /* input sanity check: */ + if (ctx == (TCHmacState_t) 0 || + key == (const uint8_t *) 0 || + key_size == 0) { + return TC_CRYPTO_FAIL; + } + + const uint8_t dummy_key[key_size]; + struct tc_hmac_state_struct dummy_state; + + if (key_size <= TC_SHA256_BLOCK_SIZE) { + /* + * The next three lines consist of dummy calls just to avoid + * certain timing attacks. Without these dummy calls, + * adversaries would be able to learn whether the key_size is + * greater than TC_SHA256_BLOCK_SIZE by measuring the time + * consumed in this process. + */ + (void)tc_sha256_init(&dummy_state.hash_state); + (void)tc_sha256_update(&dummy_state.hash_state, + dummy_key, + key_size); + (void)tc_sha256_final(&dummy_state.key[TC_SHA256_DIGEST_SIZE], + &dummy_state.hash_state); + + /* Actual code for when key_size <= TC_SHA256_BLOCK_SIZE: */ + rekey(ctx->key, key, key_size); + } else { + (void)tc_sha256_init(&ctx->hash_state); + (void)tc_sha256_update(&ctx->hash_state, key, key_size); + (void)tc_sha256_final(&ctx->key[TC_SHA256_DIGEST_SIZE], + &ctx->hash_state); + rekey(ctx->key, + &ctx->key[TC_SHA256_DIGEST_SIZE], + TC_SHA256_DIGEST_SIZE); + } + + return TC_CRYPTO_SUCCESS; +} + +int32_t tc_hmac_init(TCHmacState_t ctx) +{ + /* input sanity check: */ + if (ctx == (TCHmacState_t) 0) { + return TC_CRYPTO_FAIL; + } + + (void)tc_sha256_init(&ctx->hash_state); + (void)tc_sha256_update(&ctx->hash_state, + ctx->key, + TC_SHA256_BLOCK_SIZE); + + return TC_CRYPTO_SUCCESS; +} + +int32_t tc_hmac_update(TCHmacState_t ctx, + const void *data, + uint32_t data_length) +{ + /* input sanity check: */ + if (ctx == (TCHmacState_t) 0) { + return TC_CRYPTO_FAIL; + } + + (void)tc_sha256_update(&ctx->hash_state, data, data_length); + + return TC_CRYPTO_SUCCESS; +} + +int32_t tc_hmac_final(uint8_t *tag, uint32_t taglen, TCHmacState_t ctx) +{ + /* input sanity check: */ + if (tag == (uint8_t *) 0 || + taglen != TC_SHA256_DIGEST_SIZE || + ctx == (TCHmacState_t) 0) { + return TC_CRYPTO_FAIL; + } + + (void) tc_sha256_final(tag, &ctx->hash_state); + + (void)tc_sha256_init(&ctx->hash_state); + (void)tc_sha256_update(&ctx->hash_state, + &ctx->key[TC_SHA256_BLOCK_SIZE], + TC_SHA256_BLOCK_SIZE); + (void)tc_sha256_update(&ctx->hash_state, tag, TC_SHA256_DIGEST_SIZE); + (void)tc_sha256_final(tag, &ctx->hash_state); + + /* destroy the current state */ + _set(ctx, 0, sizeof(*ctx)); + + return TC_CRYPTO_SUCCESS; +} diff --git a/kernel/protocols/bluetooth/core/tinycrypt/source/hmac_prng.c b/kernel/protocols/bluetooth/core/tinycrypt/source/hmac_prng.c new file mode 100644 index 0000000000..ceac27f69d --- /dev/null +++ b/kernel/protocols/bluetooth/core/tinycrypt/source/hmac_prng.c @@ -0,0 +1,210 @@ +/* hmac_prng.c - TinyCrypt implementation of HMAC-PRNG */ + +/* + * Copyright (C) 2015 by Intel Corporation, 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 Intel Corporation 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 OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 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 + +/* + * min bytes in the seed string. + * MIN_SLEN*8 must be at least the expected security level. + */ +static const uint32_t MIN_SLEN = 32; + +/* + * max bytes in the seed string; + * SP800-90A specifies a maximum of 2^35 bits (i.e., 2^32 bytes). + */ +static const uint32_t MAX_SLEN = UINT32_MAX; + +/* + * max bytes in the personalization string; + * SP800-90A specifies a maximum of 2^35 bits (i.e., 2^32 bytes). + */ +static const uint32_t MAX_PLEN = UINT32_MAX; + +/* + * max bytes in the additional_info string; + * SP800-90A specifies a maximum of 2^35 bits (i.e., 2^32 bytes). + */ +static const uint32_t MAX_ALEN = UINT32_MAX; + +/* + * max number of generates between re-seeds; + * TinyCrypt accepts up to (2^32 - 1) which is the maximal value of + * a uint32_t variable, while SP800-90A specifies a maximum of 2^48. + */ +static const uint32_t MAX_GENS = UINT32_MAX; + +/* + * maximum bytes per generate call; + * SP800-90A specifies a maximum up to 2^19. + */ +static const uint32_t MAX_OUT = (1 << 19); + +/* + * Assumes: prng != NULL, e != NULL, len >= 0. + */ +static void update(TCHmacPrng_t prng, const uint8_t *e, uint32_t len) +{ + const uint8_t separator0 = 0x00; + const uint8_t separator1 = 0x01; + + /* use current state, e and separator 0 to compute a new prng key: */ + (void)tc_hmac_init(&prng->h); + (void)tc_hmac_update(&prng->h, prng->v, sizeof(prng->v)); + (void)tc_hmac_update(&prng->h, &separator0, sizeof(separator0)); + (void)tc_hmac_update(&prng->h, e, len); + (void)tc_hmac_final(prng->key, sizeof(prng->key), &prng->h); + /* configure the new prng key into the prng's instance of hmac */ + (void)tc_hmac_set_key(&prng->h, prng->key, sizeof(prng->key)); + + /* use the new key to compute a new state variable v */ + (void)tc_hmac_init(&prng->h); + (void)tc_hmac_update(&prng->h, prng->v, sizeof(prng->v)); + (void)tc_hmac_final(prng->v, sizeof(prng->v), &prng->h); + + /* use current state, e and separator 1 to compute a new prng key: */ + (void)tc_hmac_init(&prng->h); + (void)tc_hmac_update(&prng->h, prng->v, sizeof(prng->v)); + (void)tc_hmac_update(&prng->h, &separator1, sizeof(separator1)); + (void)tc_hmac_update(&prng->h, e, len); + (void)tc_hmac_final(prng->key, sizeof(prng->key), &prng->h); + /* configure the new prng key into the prng's instance of hmac */ + (void)tc_hmac_set_key(&prng->h, prng->key, sizeof(prng->key)); + + /* use the new key to compute a new state variable v */ + (void)tc_hmac_init(&prng->h); + (void)tc_hmac_update(&prng->h, prng->v, sizeof(prng->v)); + (void)tc_hmac_final(prng->v, sizeof(prng->v), &prng->h); +} + +int32_t tc_hmac_prng_init(TCHmacPrng_t prng, + const uint8_t *personalization, + uint32_t plen) +{ + /* input sanity check: */ + if (prng == (TCHmacPrng_t) 0 || + personalization == (uint8_t *) 0 || + plen > MAX_PLEN) { + return TC_CRYPTO_FAIL; + } + + /* put the generator into a known state: */ + _set(prng->key, 0x00, sizeof(prng->key)); + _set(prng->v, 0x01, sizeof(prng->v)); + tc_hmac_set_key(&prng->h, prng->key, sizeof(prng->key)); + /* update assumes SOME key has been configured into HMAC */ + + update(prng, personalization, plen); + + /* force a reseed before allowing tc_hmac_prng_generate to succeed: */ + prng->countdown = 0; + + return TC_CRYPTO_SUCCESS; +} + +int32_t tc_hmac_prng_reseed(TCHmacPrng_t prng, + const uint8_t *seed, + uint32_t seedlen, + const uint8_t *additional_input, + uint32_t additionallen) +{ + /* input sanity check: */ + if (prng == (TCHmacPrng_t) 0 || + seed == (const uint8_t *) 0 || + seedlen < MIN_SLEN || + seedlen > MAX_SLEN) { + return TC_CRYPTO_FAIL; + } + + if (additional_input != (const uint8_t *) 0) { + /* + * Abort if additional_input is provided but has inappropriate + * length + */ + if (additionallen == 0 || + additionallen > MAX_ALEN) { + return TC_CRYPTO_FAIL; + } else { + /* call update for the seed and additional_input */ + update(prng, seed, seedlen); + update(prng, additional_input, additionallen); + } + } else { + /* call update only for the seed */ + update(prng, seed, seedlen); + } + + /* ... and enable hmac_prng_generate */ + prng->countdown = MAX_GENS; + + return TC_CRYPTO_SUCCESS; +} + +int32_t tc_hmac_prng_generate(uint8_t *out, uint32_t outlen, TCHmacPrng_t prng) +{ + uint32_t bufferlen; + + /* input sanity check: */ + if (out == (uint8_t *) 0 || + prng == (TCHmacPrng_t) 0 || + outlen == 0 || + outlen > MAX_OUT) { + return TC_CRYPTO_FAIL; + } else if (prng->countdown == 0) { + return TC_HMAC_PRNG_RESEED_REQ; + } + + prng->countdown--; + + while (outlen != 0) { + /* operate HMAC in OFB mode to create "random" outputs */ + (void)tc_hmac_init(&prng->h); + (void)tc_hmac_update(&prng->h, prng->v, sizeof(prng->v)); + (void)tc_hmac_final(prng->v, sizeof(prng->v), &prng->h); + + bufferlen = (TC_SHA256_DIGEST_SIZE > outlen) ? + outlen : TC_SHA256_DIGEST_SIZE; + (void)_copy(out, bufferlen, prng->v, bufferlen); + + out += bufferlen; + outlen = (outlen > TC_SHA256_DIGEST_SIZE) ? + (outlen - TC_SHA256_DIGEST_SIZE) : 0; + } + + /* block future PRNG compromises from revealing past state */ + update(prng, prng->v, TC_SHA256_DIGEST_SIZE); + + return TC_CRYPTO_SUCCESS; +} diff --git a/kernel/protocols/bluetooth/core/tinycrypt/source/sha256.c b/kernel/protocols/bluetooth/core/tinycrypt/source/sha256.c new file mode 100644 index 0000000000..c27d3e1767 --- /dev/null +++ b/kernel/protocols/bluetooth/core/tinycrypt/source/sha256.c @@ -0,0 +1,217 @@ +/* sha256.c - TinyCrypt SHA-256 crypto hash algorithm implementation */ + +/* + * Copyright (C) 2015 by Intel Corporation, 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 Intel Corporation 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 OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 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 + +static void compress(uint32_t *iv, const uint8_t *data); + +int32_t tc_sha256_init(TCSha256State_t s) +{ + /* input sanity check: */ + if (s == (TCSha256State_t) 0) { + return TC_CRYPTO_FAIL; + } + + /* + * Setting the initial state values. + * These values correspond to the first 32 bits of the fractional parts + * of the square roots of the first 8 primes: 2, 3, 5, 7, 11, 13, 17 + * and 19. + */ + _set((uint8_t *) s, 0x00, sizeof(*s)); + s->iv[0] = 0x6a09e667; + s->iv[1] = 0xbb67ae85; + s->iv[2] = 0x3c6ef372; + s->iv[3] = 0xa54ff53a; + s->iv[4] = 0x510e527f; + s->iv[5] = 0x9b05688c; + s->iv[6] = 0x1f83d9ab; + s->iv[7] = 0x5be0cd19; + + return TC_CRYPTO_SUCCESS; +} + +int32_t tc_sha256_update(TCSha256State_t s, const uint8_t *data, size_t datalen) +{ + /* input sanity check: */ + if (s == (TCSha256State_t) 0 || + data == (void *) 0) { + return TC_CRYPTO_FAIL; + } else if (datalen == 0) { + return TC_CRYPTO_SUCCESS; + } + + while (datalen-- > 0) { + s->leftover[s->leftover_offset++] = *(data++); + if (s->leftover_offset >= TC_SHA256_BLOCK_SIZE) { + compress(s->iv, s->leftover); + s->leftover_offset = 0; + s->bits_hashed += (TC_SHA256_BLOCK_SIZE << 3); + } + } + + return TC_CRYPTO_SUCCESS; +} + +int32_t tc_sha256_final(uint8_t *digest, TCSha256State_t s) +{ + uint32_t i; + + /* input sanity check: */ + if (digest == (uint8_t *) 0 || + s == (TCSha256State_t) 0) { + return TC_CRYPTO_FAIL; + } + + s->bits_hashed += (s->leftover_offset << 3); + + s->leftover[s->leftover_offset++] = 0x80; /* always room for one byte */ + if (s->leftover_offset > (sizeof(s->leftover) - 8)) { + /* there is not room for all the padding in this block */ + _set(s->leftover + s->leftover_offset, 0x00, + sizeof(s->leftover) - s->leftover_offset); + compress(s->iv, s->leftover); + s->leftover_offset = 0; + } + + /* add the padding and the length in big-Endian format */ + _set(s->leftover + s->leftover_offset, 0x00, + sizeof(s->leftover) - 8 - s->leftover_offset); + s->leftover[sizeof(s->leftover) - 1] = (uint8_t)(s->bits_hashed); + s->leftover[sizeof(s->leftover) - 2] = (uint8_t)(s->bits_hashed >> 8); + s->leftover[sizeof(s->leftover) - 3] = (uint8_t)(s->bits_hashed >> 16); + s->leftover[sizeof(s->leftover) - 4] = (uint8_t)(s->bits_hashed >> 24); + s->leftover[sizeof(s->leftover) - 5] = (uint8_t)(s->bits_hashed >> 32); + s->leftover[sizeof(s->leftover) - 6] = (uint8_t)(s->bits_hashed >> 40); + s->leftover[sizeof(s->leftover) - 7] = (uint8_t)(s->bits_hashed >> 48); + s->leftover[sizeof(s->leftover) - 8] = (uint8_t)(s->bits_hashed >> 56); + + /* hash the padding and length */ + compress(s->iv, s->leftover); + + /* copy the iv out to digest */ + for (i = 0; i < TC_SHA256_STATE_BLOCKS; ++i) { + uint32_t t = *((uint32_t *) &s->iv[i]); + *digest++ = (uint8_t)(t >> 24); + *digest++ = (uint8_t)(t >> 16); + *digest++ = (uint8_t)(t >> 8); + *digest++ = (uint8_t)(t); + } + + /* destroy the current state */ + _set(s, 0, sizeof(*s)); + + return TC_CRYPTO_SUCCESS; +} + +/* + * Initializing SHA-256 Hash constant words K. + * These values correspond to the first 32 bits of the fractional parts of the + * cube roots of the first 64 primes between 2 and 311. + */ +static const uint32_t k256[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 +}; + +static inline uint32_t ROTR(uint32_t a, uint32_t n) +{ + return (((a) >> n) | ((a) << (32 - n))); +} + +#define Sigma0(a)(ROTR((a), 2) ^ ROTR((a), 13) ^ ROTR((a), 22)) +#define Sigma1(a)(ROTR((a), 6) ^ ROTR((a), 11) ^ ROTR((a), 25)) +#define sigma0(a)(ROTR((a), 7) ^ ROTR((a), 18) ^ ((a) >> 3)) +#define sigma1(a)(ROTR((a), 17) ^ ROTR((a), 19) ^ ((a) >> 10)) + +#define Ch(a, b, c)(((a) & (b)) ^ ((~(a)) & (c))) +#define Maj(a, b, c)(((a) & (b)) ^ ((a) & (c)) ^ ((b) & (c))) + +static inline uint32_t BigEndian(const uint8_t **c) +{ + uint32_t n = 0; + + n = (((uint32_t)(*((*c)++))) << 24); + n |= ((uint32_t)(*((*c)++)) << 16); + n |= ((uint32_t)(*((*c)++)) << 8); + n |= ((uint32_t)(*((*c)++))); + return n; +} + +static void compress(uint32_t *iv, const uint8_t *data) +{ + uint32_t a, b, c, d, e, f, g, h; + uint32_t s0, s1; + uint32_t t1, t2; + uint32_t work_space[16]; + uint32_t n; + uint32_t i; + + a = iv[0]; b = iv[1]; c = iv[2]; d = iv[3]; + e = iv[4]; f = iv[5]; g = iv[6]; h = iv[7]; + + for (i = 0; i < 16; ++i) { + n = BigEndian(&data); + t1 = work_space[i] = n; + t1 += h + Sigma1(e) + Ch(e, f, g) + k256[i]; + t2 = Sigma0(a) + Maj(a, b, c); + h = g; g = f; f = e; e = d + t1; + d = c; c = b; b = a; a = t1 + t2; + } + + for ( ; i < 64; ++i) { + s0 = work_space[(i+1)&0x0f]; + s0 = sigma0(s0); + s1 = work_space[(i+14)&0x0f]; + s1 = sigma1(s1); + + t1 = work_space[i&0xf] += s0 + s1 + work_space[(i+9)&0xf]; + t1 += h + Sigma1(e) + Ch(e, f, g) + k256[i]; + t2 = Sigma0(a) + Maj(a, b, c); + h = g; g = f; f = e; e = d + t1; + d = c; c = b; b = a; a = t1 + t2; + } + + iv[0] += a; iv[1] += b; iv[2] += c; iv[3] += d; + iv[4] += e; iv[5] += f; iv[6] += g; iv[7] += h; +} diff --git a/kernel/protocols/bluetooth/core/tinycrypt/source/utils.c b/kernel/protocols/bluetooth/core/tinycrypt/source/utils.c new file mode 100644 index 0000000000..147d8d407a --- /dev/null +++ b/kernel/protocols/bluetooth/core/tinycrypt/source/utils.c @@ -0,0 +1,75 @@ +/* utils.c - TinyCrypt platform-dependent run-time operations */ + +/* + * Copyright (C) 2015 by Intel Corporation, 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 Intel Corporation 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 OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 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 + +#define MASK_MOST_SIG_BIT 0x80 +#define MASK_TWENTY_SEVEN 0x1b + +uint32_t _copy(uint8_t *to, uint32_t to_len, + const uint8_t *from, uint32_t from_len) +{ + if (from_len <= to_len) { + (void)memcpy(to, from, from_len); + return from_len; + } else { + return TC_CRYPTO_FAIL; + } +} + +void _set(void *to, uint8_t val, uint32_t len) +{ + (void)memset(to, val, len); +} + +/* + * Doubles the value of a byte for values up to 127. + */ +uint8_t _double_byte(uint8_t a) +{ + return ((a<<1) ^ ((a>>7) * MASK_TWENTY_SEVEN)); +} + +int32_t _compare(const uint8_t *a, const uint8_t *b, size_t size) +{ + const uint8_t *tempa = a; + const uint8_t *tempb = b; + uint8_t result = 0; + + for (uint32_t i = 0; i < size; i++) { + result |= tempa[i] ^ tempb[i]; + } + return result; +} diff --git a/kernel/protocols/bluetooth/core/work.c b/kernel/protocols/bluetooth/core/work.c new file mode 100644 index 0000000000..e478460262 --- /dev/null +++ b/kernel/protocols/bluetooth/core/work.c @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#include +#include +#include "errno.h" + +struct timer *g_timer_list; + +#if defined(__cplusplus) +extern "C" +{ +#endif +static struct k_work_q g_work_queue_main; +#define WORK_QUEUE_LEN 10 + +static void k_work_submit_to_queue(struct k_work_q *work_q, + struct k_work *work) +{ + if (!atomic_test_and_set_bit(work->flags, K_WORK_STATE_PENDING)) { + k_fifo_put(&work_q->fifo, work); + } +} + +static void work_queue_thread(void *arg) +{ + struct k_work *work; + UNUSED(arg); + + while (1) { + work = k_fifo_get(&g_work_queue_main.fifo, K_FOREVER); + + if (atomic_test_and_clear_bit(work->flags, K_WORK_STATE_PENDING)) { + work->handler(work); + } + + k_yield(); + } +} + +static void *work_queue_msg[WORK_QUEUE_LEN]; +int k_work_q_start(const char *name, uint32_t *stack, uint32_t stack_size, int prio) +{ + k_fifo_init(&g_work_queue_main.fifo, "work queue main", (void **)&work_queue_msg, WORK_QUEUE_LEN); + return k_thread_spawn(name, NULL, stack_size, work_queue_thread, NULL, prio); +} + +int k_work_init(struct k_work *work, k_work_handler_t handler) +{ + ASSERT(work, "work is NULL"); + + atomic_clear_bit(work->flags, K_WORK_STATE_PENDING); + work->handler = handler; + return 0; +} + +void k_work_submit(struct k_work *work) +{ + k_work_submit_to_queue(&g_work_queue_main, work); +} + +static void work_timeout(void *args) +{ + struct k_delayed_work *w = (struct k_delayed_work *)args; + + /* submit work to workqueue */ + k_work_submit_to_queue(w->work_q, &w->work); + /* detach from workqueue, for cancel to return appropriate status */ + w->work_q = NULL; +} + +void k_delayed_work_init(struct k_delayed_work *work, k_work_handler_t handler) +{ + ASSERT(work, "delay work is NULL"); + k_work_init(&work->work, handler); + k_timer_init(&work->timer, work_timeout, work); + work->work_q = NULL; +} + +static int k_delayed_work_submit_to_queue(struct k_work_q *work_q, + struct k_delayed_work *work, + uint32_t delay) +{ + int key = irq_lock(); + int err; + + /* Work cannot be active in multiple queues */ + if (work->work_q && work->work_q != work_q) { + err = -EADDRINUSE; + goto done; + } + + /* Cancel if work has been submitted */ + if (work->work_q == work_q) { + err = k_delayed_work_cancel(work); + + if (err < 0) { + goto done; + } + } + + /* Attach workqueue so the timeout callback can submit it */ + work->work_q = work_q; + + if (!delay) { + /* Submit work if no ticks is 0 */ + k_work_submit_to_queue(work_q, &work->work); + } else { + /* Add timeout */ + k_timer_start(&work->timer, delay); + } + + err = 0; + +done: + irq_unlock(key); + + return err; +} + +int k_delayed_work_submit(struct k_delayed_work *work, uint32_t delay) +{ + return k_delayed_work_submit_to_queue(&g_work_queue_main, work, delay); +} +int k_delayed_work_cancel(struct k_delayed_work *work) +{ + int key = irq_lock(); + + if (atomic_test_bit(work->work.flags, K_WORK_STATE_PENDING)) { + irq_unlock(key); + return -EINPROGRESS; + } + + if (!work->work_q) { + irq_unlock(key); + return -EINVAL; + } + + /* Abort timeout, if it has expired this will do nothing */ + k_timer_stop(&work->timer); + + /* Detach from workqueue */ + work->work_q = NULL; + + irq_unlock(key); + + return 0; +} + +#if defined(__cplusplus) +} +#endif diff --git a/kernel/protocols/bluetooth/host/att.c b/kernel/protocols/bluetooth/host/att.c new file mode 100644 index 0000000000..770f1e2541 --- /dev/null +++ b/kernel/protocols/bluetooth/host/att.c @@ -0,0 +1,2013 @@ +/* att.c - Attribute protocol handling */ + +/* + * Copyright (c) 2015-2016 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_ATT) +#include +#include +#include +#include +#include +#include + +#include "hci_core.h" +#include "conn_internal.h" +#include "l2cap_internal.h" +#include "smp.h" +#include "att_internal.h" +#include "gatt_internal.h" +#undef read +#undef write +#define ATT_CHAN(_ch) CONTAINER_OF(_ch, struct bt_att, chan.chan) +#define ATT_REQ(_node) CONTAINER_OF(_node, struct bt_att_req, node) + +#define BT_GATT_PERM_READ_MASK (BT_GATT_PERM_READ | \ + BT_GATT_PERM_READ_ENCRYPT | \ + BT_GATT_PERM_READ_AUTHEN) +#define BT_GATT_PERM_WRITE_MASK (BT_GATT_PERM_WRITE | \ + BT_GATT_PERM_WRITE_ENCRYPT | \ + BT_GATT_PERM_WRITE_AUTHEN) +#define BT_GATT_PERM_ENCRYPT_MASK (BT_GATT_PERM_READ_ENCRYPT | \ + BT_GATT_PERM_WRITE_ENCRYPT) +#define BT_GATT_PERM_AUTHEN_MASK (BT_GATT_PERM_READ_AUTHEN | \ + BT_GATT_PERM_WRITE_AUTHEN) +#define BT_ATT_OP_CMD_FLAG 0x40 + +#define ATT_TIMEOUT K_SECONDS(30) + +#if CONFIG_BLUETOOTH_ATT_PREPARE_COUNT > 0 +struct bt_attr_data { + uint16_t handle; + uint16_t offset; +}; + +/* Pool for incoming ATT packets */ +NET_BUF_POOL_DEFINE(prep_pool, CONFIG_BLUETOOTH_ATT_PREPARE_COUNT, BT_ATT_MTU, + sizeof(struct bt_attr_data), NULL); +#endif /* CONFIG_BLUETOOTH_ATT_PREPARE_COUNT */ + +/* ATT channel specific context */ +struct bt_att { + /* The channel this context is associated with */ + struct bt_l2cap_le_chan chan; + struct bt_att_req *req; + sys_slist_t reqs; + struct k_delayed_work timeout_work; +#if CONFIG_BLUETOOTH_ATT_PREPARE_COUNT > 0 + struct k_fifo prep_queue; +#endif +}; + +static struct bt_att bt_req_pool[CONFIG_BLUETOOTH_MAX_CONN]; + +static void att_req_destroy(struct bt_att_req *req) +{ + if (req->buf) { + net_buf_unref(req->buf); + } + + if (req->destroy) { + req->destroy(req); + } + + memset(req, 0, sizeof(*req)); +} + +static void send_err_rsp(struct bt_conn *conn, uint8_t req, uint16_t handle, + uint8_t err) +{ + struct bt_att_error_rsp *rsp; + struct net_buf *buf; + + /* Ignore opcode 0x00 */ + if (!req) { + return; + } + + buf = bt_att_create_pdu(conn, BT_ATT_OP_ERROR_RSP, sizeof(*rsp)); + if (!buf) { + return; + } + + rsp = net_buf_add(buf, sizeof(*rsp)); + rsp->request = req; + rsp->handle = sys_cpu_to_le16(handle); + rsp->error = err; + + bt_l2cap_send(conn, BT_L2CAP_CID_ATT, buf); +} + +static uint8_t att_mtu_req(struct bt_att *att, struct net_buf *buf) +{ + struct bt_conn *conn = att->chan.chan.conn; + struct bt_att_exchange_mtu_req *req; + struct bt_att_exchange_mtu_rsp *rsp; + struct net_buf *pdu; + uint16_t mtu_client, mtu_server; + + req = (void *)buf->data; + + mtu_client = sys_le16_to_cpu(req->mtu); + + BT_DBG("Client MTU %u", mtu_client); + + /* Check if MTU is valid */ + if (mtu_client < BT_ATT_DEFAULT_LE_MTU) { + return BT_ATT_ERR_INVALID_PDU; + } + + pdu = bt_att_create_pdu(conn, BT_ATT_OP_MTU_RSP, sizeof(*rsp)); + if (!pdu) { + return BT_ATT_ERR_UNLIKELY; + } + + mtu_server = BT_ATT_MTU; + + BT_DBG("Server MTU %u", mtu_server); + + rsp = net_buf_add(pdu, sizeof(*rsp)); + rsp->mtu = sys_cpu_to_le16(mtu_server); + + bt_l2cap_send(conn, BT_L2CAP_CID_ATT, pdu); + + /* BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part F] page 484: + * + * A device's Exchange MTU Request shall contain the same MTU as the + * device's Exchange MTU Response (i.e. the MTU shall be symmetric). + */ + att->chan.rx.mtu = min(mtu_client, mtu_server); + att->chan.tx.mtu = att->chan.rx.mtu; + + BT_DBG("Negotiated MTU %u", att->chan.rx.mtu); + return 0; +} + +static int att_send_req(struct bt_att *att, struct bt_att_req *req) +{ + BT_DBG("req %p", req); + + att->req = req; + + /* Save request state so it can be resent */ + net_buf_simple_save(&req->buf->b, &req->state); + + /* Start timeout work */ + k_delayed_work_submit(&att->timeout_work, ATT_TIMEOUT); + + /* Keep a reference for resending in case of an error */ + bt_l2cap_send(att->chan.chan.conn, BT_L2CAP_CID_ATT, + net_buf_ref(req->buf)); + + return 0; +} + +static void att_process(struct bt_att *att) +{ + sys_snode_t *node; + + BT_DBG(""); + + /* Pull next request from the list */ + node = sys_slist_get(&att->reqs); + if (!node) { + return; + } + + att_send_req(att, ATT_REQ(node)); +} + +static uint8_t att_handle_rsp(struct bt_att *att, void *pdu, uint16_t len, + uint8_t err) +{ + bt_att_func_t func; + + if (!att->req) { + goto process; + } + + /* Cancel timeout if ongoing */ + k_delayed_work_cancel(&att->timeout_work); + + /* Release original buffer */ + if (att->req->buf) { + net_buf_unref(att->req->buf); + att->req->buf = NULL; + } + + /* Reset func so it can be reused by the callback */ + func = att->req->func; + att->req->func = NULL; + + if (func) + { + func(att->chan.chan.conn, err, pdu, len, att->req); + } + else + { + BT_ERR("func is NULL"); + } + + /* Don't destroy if callback had reused the request */ + if (!att->req->func) { + att_req_destroy(att->req); + } + + att->req = NULL; + +process: + /* Process pending requests */ + att_process(att); + + return 0; +} + +static uint8_t att_mtu_rsp(struct bt_att *att, struct net_buf *buf) +{ + struct bt_att_exchange_mtu_rsp *rsp; + uint16_t mtu; + + if (!att) { + return 0; + } + + rsp = (void *)buf->data; + + mtu = sys_le16_to_cpu(rsp->mtu); + + BT_DBG("Server MTU %u", mtu); + + /* Check if MTU is valid */ + if (mtu < BT_ATT_DEFAULT_LE_MTU) { + return att_handle_rsp(att, NULL, 0, BT_ATT_ERR_INVALID_PDU); + } + + att->chan.rx.mtu = min(mtu, BT_ATT_MTU); + + /* BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part F] page 484: + * + * A device's Exchange MTU Request shall contain the same MTU as the + * device's Exchange MTU Response (i.e. the MTU shall be symmetric). + */ + att->chan.tx.mtu = att->chan.rx.mtu; + + BT_DBG("Negotiated MTU %u", att->chan.rx.mtu); + + return att_handle_rsp(att, rsp, buf->len, 0); +} + +static bool range_is_valid(uint16_t start, uint16_t end, uint16_t *err) +{ + /* Handle 0 is invalid */ + if (!start || !end) { + if (err) { + *err = 0; + } + return false; + } + + /* Check if range is valid */ + if (start > end) { + if (err) { + *err = start; + } + return false; + } + + return true; +} + +struct find_info_data { + struct bt_att *att; + struct net_buf *buf; + struct bt_att_find_info_rsp *rsp; + union { + struct bt_att_info_16 *info16; + struct bt_att_info_128 *info128; + }; +}; + +static uint8_t find_info_cb(const struct bt_gatt_attr *attr, void *user_data) +{ + struct find_info_data *data = user_data; + struct bt_att *att = data->att; + + BT_DBG("handle 0x%04x", attr->handle); + + /* Initialize rsp at first entry */ + if (!data->rsp) { + data->rsp = net_buf_add(data->buf, sizeof(*data->rsp)); + data->rsp->format = (attr->uuid->type == BT_UUID_TYPE_16) ? + BT_ATT_INFO_16 : BT_ATT_INFO_128; + } + + switch (data->rsp->format) { + case BT_ATT_INFO_16: + if (attr->uuid->type != BT_UUID_TYPE_16) { + return BT_GATT_ITER_STOP; + } + + /* Fast foward to next item position */ + data->info16 = net_buf_add(data->buf, sizeof(*data->info16)); + data->info16->handle = sys_cpu_to_le16(attr->handle); + data->info16->uuid = sys_cpu_to_le16(BT_UUID_16(attr->uuid)->val); + + if (att->chan.tx.mtu - data->buf->len > + sizeof(*data->info16)) { + return BT_GATT_ITER_CONTINUE; + } + + break; + case BT_ATT_INFO_128: + if (attr->uuid->type != BT_UUID_TYPE_128) { + return BT_GATT_ITER_STOP; + } + + /* Fast foward to next item position */ + data->info128 = net_buf_add(data->buf, sizeof(*data->info128)); + data->info128->handle = sys_cpu_to_le16(attr->handle); + memcpy(data->info128->uuid, BT_UUID_128(attr->uuid)->val, + sizeof(data->info128->uuid)); + + if (att->chan.tx.mtu - data->buf->len > + sizeof(*data->info128)) { + return BT_GATT_ITER_CONTINUE; + } + } + + return BT_GATT_ITER_STOP; +} + +static uint8_t att_find_info_rsp(struct bt_att *att, uint16_t start_handle, + uint16_t end_handle) +{ + struct bt_conn *conn = att->chan.chan.conn; + struct find_info_data data; + + memset(&data, 0, sizeof(data)); + + data.buf = bt_att_create_pdu(conn, BT_ATT_OP_FIND_INFO_RSP, 0); + if (!data.buf) { + return BT_ATT_ERR_UNLIKELY; + } + + data.att = att; + bt_gatt_foreach_attr(start_handle, end_handle, find_info_cb, &data); + + if (!data.rsp) { + net_buf_unref(data.buf); + /* Respond since handle is set */ + send_err_rsp(conn, BT_ATT_OP_FIND_INFO_REQ, start_handle, + BT_ATT_ERR_ATTRIBUTE_NOT_FOUND); + return 0; + } + + bt_l2cap_send(conn, BT_L2CAP_CID_ATT, data.buf); + + return 0; +} + +static uint8_t att_find_info_req(struct bt_att *att, struct net_buf *buf) +{ + struct bt_conn *conn = att->chan.chan.conn; + struct bt_att_find_info_req *req; + uint16_t start_handle, end_handle, err_handle; + + req = (void *)buf->data; + + start_handle = sys_le16_to_cpu(req->start_handle); + end_handle = sys_le16_to_cpu(req->end_handle); + + BT_DBG("start_handle 0x%04x end_handle 0x%04x", start_handle, + end_handle); + + if (!range_is_valid(start_handle, end_handle, &err_handle)) { + send_err_rsp(conn, BT_ATT_OP_FIND_INFO_REQ, err_handle, + BT_ATT_ERR_INVALID_HANDLE); + return 0; + } + + return att_find_info_rsp(att, start_handle, end_handle); +} + +struct find_type_data { + struct bt_att *att; + struct net_buf *buf; + struct bt_att_handle_group *group; + const void *value; + uint8_t value_len; + uint8_t err; +}; + +static uint8_t find_type_cb(const struct bt_gatt_attr *attr, void *user_data) +{ + struct find_type_data *data = user_data; + struct bt_att *att = data->att; + struct bt_conn *conn = att->chan.chan.conn; + int read; + uint8_t uuid[16]; + + /* Skip secondary services */ + if (!bt_uuid_cmp(attr->uuid, BT_UUID_GATT_SECONDARY)) { + data->group = NULL; + return BT_GATT_ITER_CONTINUE; + } + + /* Update group end_handle if not a primary service */ + if (bt_uuid_cmp(attr->uuid, BT_UUID_GATT_PRIMARY)) { + if (data->group && attr->handle > data->group->end_handle) { + data->group->end_handle = sys_cpu_to_le16(attr->handle); + } + return BT_GATT_ITER_CONTINUE; + } + + BT_DBG("handle 0x%04x", attr->handle); + + /* stop if there is no space left */ + if (att->chan.tx.mtu - data->buf->len < sizeof(*data->group)) { + return BT_GATT_ITER_STOP; + } + + /* Read attribute value and store in the buffer */ + read = attr->read(conn, attr, uuid, sizeof(uuid), 0); + if (read < 0) { + /* + * Since we don't know if it is the service with requested UUID, + * we cannot respond with an error to this request. + */ + data->group = NULL; + return BT_GATT_ITER_CONTINUE; + } + + /* Check if data matches */ + if (read != data->value_len || memcmp(data->value, uuid, read)) { + data->group = NULL; + return BT_GATT_ITER_CONTINUE; + } + + /* If service has been found, error should be cleared */ + data->err = 0x00; + + /* Fast foward to next item position */ + data->group = net_buf_add(data->buf, sizeof(*data->group)); + data->group->start_handle = sys_cpu_to_le16(attr->handle); + data->group->end_handle = sys_cpu_to_le16(attr->handle); + + /* continue to find the end_handle */ + return BT_GATT_ITER_CONTINUE; +} + +static uint8_t att_find_type_rsp(struct bt_att *att, uint16_t start_handle, + uint16_t end_handle, const void *value, + uint8_t value_len) +{ + struct bt_conn *conn = att->chan.chan.conn; + struct find_type_data data; + + memset(&data, 0, sizeof(data)); + + data.buf = bt_att_create_pdu(conn, BT_ATT_OP_FIND_TYPE_RSP, 0); + if (!data.buf) { + return BT_ATT_ERR_UNLIKELY; + } + + data.att = att; + data.group = NULL; + data.value = value; + data.value_len = value_len; + + /* Pre-set error in case no service will be found */ + data.err = BT_ATT_ERR_ATTRIBUTE_NOT_FOUND; + + bt_gatt_foreach_attr(start_handle, end_handle, find_type_cb, &data); + + /* If error has not been cleared, no service has been found */ + if (data.err) { + net_buf_unref(data.buf); + /* Respond since handle is set */ + send_err_rsp(conn, BT_ATT_OP_FIND_TYPE_REQ, start_handle, + data.err); + return 0; + } + + bt_l2cap_send(conn, BT_L2CAP_CID_ATT, data.buf); + + return 0; +} + +static uint8_t att_find_type_req(struct bt_att *att, struct net_buf *buf) +{ + struct bt_conn *conn = att->chan.chan.conn; + struct bt_att_find_type_req *req; + uint16_t start_handle, end_handle, err_handle, type; + uint8_t *value; + + req = (void *)buf->data; + + start_handle = sys_le16_to_cpu(req->start_handle); + end_handle = sys_le16_to_cpu(req->end_handle); + type = sys_le16_to_cpu(req->type); + value = net_buf_pull(buf, sizeof(*req)); + + BT_DBG("start_handle 0x%04x end_handle 0x%04x type %u", start_handle, + end_handle, type); + + if (!range_is_valid(start_handle, end_handle, &err_handle)) { + send_err_rsp(conn, BT_ATT_OP_FIND_TYPE_REQ, err_handle, + BT_ATT_ERR_INVALID_HANDLE); + return 0; + } + + /* The Attribute Protocol Find By Type Value Request shall be used with + * the Attribute Type parameter set to the UUID for "Primary Service" + * and the Attribute Value set to the 16-bit Bluetooth UUID or 128-bit + * UUID for the specific primary service. + */ + if (type != BT_UUID_GATT_PRIMARY_VAL) { + send_err_rsp(conn, BT_ATT_OP_FIND_TYPE_REQ, start_handle, + BT_ATT_ERR_ATTRIBUTE_NOT_FOUND); + return 0; + } + + return att_find_type_rsp(att, start_handle, end_handle, value, + buf->len); +} + +static bool uuid_create(struct bt_uuid *uuid, struct net_buf *buf) +{ + switch (buf->len) { + case 2: + uuid->type = BT_UUID_TYPE_16; + BT_UUID_16(uuid)->val = net_buf_pull_le16(buf); + return true; + case 16: + uuid->type = BT_UUID_TYPE_128; + memcpy(BT_UUID_128(uuid)->val, buf->data, buf->len); + return true; + } + + return false; +} + +static uint8_t check_perm(struct bt_conn *conn, const struct bt_gatt_attr *attr, + uint8_t mask) +{ + if ((mask & BT_GATT_PERM_READ) && + (!(attr->perm & BT_GATT_PERM_READ_MASK) || !attr->read)) { + return BT_ATT_ERR_READ_NOT_PERMITTED; + } + + if ((mask & BT_GATT_PERM_WRITE) && + (!(attr->perm & BT_GATT_PERM_WRITE_MASK) || !attr->write)) { + return BT_ATT_ERR_WRITE_NOT_PERMITTED; + } + + mask &= attr->perm; + if (mask & BT_GATT_PERM_AUTHEN_MASK) { +#if defined(CONFIG_BLUETOOTH_SMP) + if (conn->sec_level < BT_SECURITY_HIGH) { + return BT_ATT_ERR_AUTHENTICATION; + } +#else + return BT_ATT_ERR_AUTHENTICATION; +#endif /* CONFIG_BLUETOOTH_SMP */ + } + + if ((mask & BT_GATT_PERM_ENCRYPT_MASK)) { +#if defined(CONFIG_BLUETOOTH_SMP) + if (!conn->encrypt) { + return BT_ATT_ERR_INSUFFICIENT_ENCRYPTION; + } +#else + return BT_ATT_ERR_INSUFFICIENT_ENCRYPTION; +#endif /* CONFIG_BLUETOOTH_SMP */ + } + + return 0; +} + +static uint8_t err_to_att(int err) +{ + BT_DBG("%d", err); + + if (err < 0 && err >= -0xff) { + return -err; + } + + return BT_ATT_ERR_UNLIKELY; +} + +struct read_type_data { + struct bt_att *att; + struct bt_uuid *uuid; + struct net_buf *buf; + struct bt_att_read_type_rsp *rsp; + struct bt_att_data *item; + uint8_t err; +}; + +static uint8_t read_type_cb(const struct bt_gatt_attr *attr, void *user_data) +{ + struct read_type_data *data = user_data; + struct bt_att *att = data->att; + struct bt_conn *conn = att->chan.chan.conn; + int read; + + /* Skip if doesn't match */ + if (bt_uuid_cmp(attr->uuid, data->uuid)) { + return BT_GATT_ITER_CONTINUE; + } + + BT_DBG("handle 0x%04x", attr->handle); + + /* + * If an attribute in the set of requested attributes would cause an + * Error Response then this attribute cannot be included in a + * Read By Type Response and the attributes before this attribute + * shall be returned + * + * If the first attribute in the set of requested attributes would + * cause an Error Response then no other attributes in the requested + * attributes can be considered. + */ + data->err = check_perm(conn, attr, BT_GATT_PERM_READ_MASK); + if (data->err) { + if (data->rsp->len) { + data->err = 0x00; + } + return BT_GATT_ITER_STOP; + } + + /* + * If any attribute is founded in handle range it means that error + * should be changed from pre-set: attr not found error to no error. + */ + data->err = 0x00; + + /* Fast foward to next item position */ + data->item = net_buf_add(data->buf, sizeof(*data->item)); + data->item->handle = sys_cpu_to_le16(attr->handle); + + /* Read attribute value and store in the buffer */ + read = attr->read(conn, attr, data->buf->data + data->buf->len, + att->chan.tx.mtu - data->buf->len, 0); + if (read < 0) { + data->err = err_to_att(read); + return BT_GATT_ITER_STOP; + } + + if (!data->rsp->len) { + /* Set len to be the first item found */ + data->rsp->len = read + sizeof(*data->item); + } else if (data->rsp->len != read + sizeof(*data->item)) { + /* All items should have the same size */ + data->buf->len -= sizeof(*data->item); + return BT_GATT_ITER_STOP; + } + + net_buf_add(data->buf, read); + + /* return true only if there are still space for more items */ + return att->chan.tx.mtu - data->buf->len > data->rsp->len ? + BT_GATT_ITER_CONTINUE : BT_GATT_ITER_STOP; +} + +static uint8_t att_read_type_rsp(struct bt_att *att, struct bt_uuid *uuid, + uint16_t start_handle, uint16_t end_handle) +{ + struct bt_conn *conn = att->chan.chan.conn; + struct read_type_data data; + + memset(&data, 0, sizeof(data)); + + data.buf = bt_att_create_pdu(conn, BT_ATT_OP_READ_TYPE_RSP, + sizeof(*data.rsp)); + if (!data.buf) { + return BT_ATT_ERR_UNLIKELY; + } + + data.att = att; + data.uuid = uuid; + data.rsp = net_buf_add(data.buf, sizeof(*data.rsp)); + data.rsp->len = 0; + + /* Pre-set error if no attr will be found in handle */ + data.err = BT_ATT_ERR_ATTRIBUTE_NOT_FOUND; + + bt_gatt_foreach_attr(start_handle, end_handle, read_type_cb, &data); + + if (data.err) { + net_buf_unref(data.buf); + /* Response here since handle is set */ + send_err_rsp(conn, BT_ATT_OP_READ_TYPE_REQ, start_handle, + data.err); + return 0; + } + + bt_l2cap_send(conn, BT_L2CAP_CID_ATT, data.buf); + + return 0; +} + +static uint8_t att_read_type_req(struct bt_att *att, struct net_buf *buf) +{ + struct bt_conn *conn = att->chan.chan.conn; + struct bt_att_read_type_req *req; + uint16_t start_handle, end_handle, err_handle; + union { + struct bt_uuid uuid; + struct bt_uuid_16 u16; + struct bt_uuid_128 u128; + } u; + + /* Type can only be UUID16 or UUID128 */ + if (buf->len != sizeof(*req) + 2 && buf->len != sizeof(*req) + 16) { + return BT_ATT_ERR_INVALID_PDU; + } + + req = (void *)buf->data; + + start_handle = sys_le16_to_cpu(req->start_handle); + end_handle = sys_le16_to_cpu(req->end_handle); + net_buf_pull(buf, sizeof(*req)); + + if (!uuid_create(&u.uuid, buf)) { + return BT_ATT_ERR_UNLIKELY; + } + + BT_DBG("start_handle 0x%04x end_handle 0x%04x type %s", + start_handle, end_handle, bt_uuid_str(&u.uuid)); + + if (!range_is_valid(start_handle, end_handle, &err_handle)) { + send_err_rsp(conn, BT_ATT_OP_READ_TYPE_REQ, err_handle, + BT_ATT_ERR_INVALID_HANDLE); + return 0; + } + + return att_read_type_rsp(att, &u.uuid, start_handle, end_handle); +} + +struct read_data { + struct bt_att *att; + uint16_t offset; + struct net_buf *buf; + struct bt_att_read_rsp *rsp; + uint8_t err; +}; + +static uint8_t read_cb(const struct bt_gatt_attr *attr, void *user_data) +{ + struct read_data *data = user_data; + struct bt_att *att = data->att; + struct bt_conn *conn = att->chan.chan.conn; + int read; + + BT_DBG("handle 0x%04x", attr->handle); + + data->rsp = net_buf_add(data->buf, sizeof(*data->rsp)); + + /* + * If any attribute is founded in handle range it means that error + * should be changed from pre-set: invalid handle error to no error. + */ + data->err = 0x00; + + /* Check attribute permissions */ + data->err = check_perm(conn, attr, BT_GATT_PERM_READ_MASK); + if (data->err) { + return BT_GATT_ITER_STOP; + } + + /* Read attribute value and store in the buffer */ + read = attr->read(conn, attr, data->buf->data + data->buf->len, + att->chan.tx.mtu - data->buf->len, data->offset); + if (read < 0) { + data->err = err_to_att(read); + return BT_GATT_ITER_STOP; + } + + net_buf_add(data->buf, read); + + return BT_GATT_ITER_CONTINUE; +} + +static uint8_t att_read_rsp(struct bt_att *att, uint8_t op, uint8_t rsp, + uint16_t handle, uint16_t offset) +{ + struct bt_conn *conn = att->chan.chan.conn; + struct read_data data; + + if (!handle) { + return BT_ATT_ERR_INVALID_HANDLE; + } + + memset(&data, 0, sizeof(data)); + + data.buf = bt_att_create_pdu(conn, rsp, 0); + if (!data.buf) { + return BT_ATT_ERR_UNLIKELY; + } + + data.att = att; + data.offset = offset; + + /* Pre-set error if no attr will be found in handle */ + data.err = BT_ATT_ERR_INVALID_HANDLE; + + bt_gatt_foreach_attr(handle, handle, read_cb, &data); + + /* In case of error discard data and respond with an error */ + if (data.err) { + net_buf_unref(data.buf); + /* Respond here since handle is set */ + send_err_rsp(conn, op, handle, data.err); + return 0; + } + + bt_l2cap_send(conn, BT_L2CAP_CID_ATT, data.buf); + + return 0; +} + +static uint8_t att_read_req(struct bt_att *att, struct net_buf *buf) +{ + struct bt_att_read_req *req; + uint16_t handle; + + req = (void *)buf->data; + + handle = sys_le16_to_cpu(req->handle); + + BT_DBG("handle 0x%04x", handle); + + return att_read_rsp(att, BT_ATT_OP_READ_REQ, BT_ATT_OP_READ_RSP, + handle, 0); +} + +static uint8_t att_read_blob_req(struct bt_att *att, struct net_buf *buf) +{ + struct bt_att_read_blob_req *req; + uint16_t handle, offset; + + req = (void *)buf->data; + + handle = sys_le16_to_cpu(req->handle); + offset = sys_le16_to_cpu(req->offset); + + BT_DBG("handle 0x%04x offset %u", handle, offset); + + return att_read_rsp(att, BT_ATT_OP_READ_BLOB_REQ, + BT_ATT_OP_READ_BLOB_RSP, handle, offset); +} + +static uint8_t att_read_mult_req(struct bt_att *att, struct net_buf *buf) +{ + struct bt_conn *conn = att->chan.chan.conn; + struct read_data data; + uint16_t handle; + + memset(&data, 0, sizeof(data)); + + data.buf = bt_att_create_pdu(conn, BT_ATT_OP_READ_MULT_RSP, 0); + if (!data.buf) { + return BT_ATT_ERR_UNLIKELY; + } + + data.att = att; + + while (buf->len >= sizeof(uint16_t)) { + handle = net_buf_pull_le16(buf); + + BT_DBG("handle 0x%04x ", handle); + + /* An Error Response shall be sent by the server in response to + * the Read Multiple Request [....] if a read operation is not + * permitted on any of the Characteristic Values. + * + * If handle is not valid then return invalid handle error. + * If handle is found error will be cleared by read_cb. + */ + data.err = BT_ATT_ERR_INVALID_HANDLE; + + bt_gatt_foreach_attr(handle, handle, read_cb, &data); + + /* Stop reading in case of error */ + if (data.err) { + net_buf_unref(data.buf); + /* Respond here since handle is set */ + send_err_rsp(conn, BT_ATT_OP_READ_MULT_REQ, handle, + data.err); + return 0; + } + } + + bt_l2cap_send(conn, BT_L2CAP_CID_ATT, data.buf); + + return 0; +} + +struct read_group_data { + struct bt_att *att; + struct bt_uuid *uuid; + struct net_buf *buf; + struct bt_att_read_group_rsp *rsp; + struct bt_att_group_data *group; +}; + +static uint8_t read_group_cb(const struct bt_gatt_attr *attr, void *user_data) +{ + struct read_group_data *data = user_data; + struct bt_att *att = data->att; + struct bt_conn *conn = att->chan.chan.conn; + int read; + + /* Update group end_handle if attribute is not a service */ + if (bt_uuid_cmp(attr->uuid, BT_UUID_GATT_PRIMARY) && + bt_uuid_cmp(attr->uuid, BT_UUID_GATT_SECONDARY)) { + if (data->group && attr->handle > data->group->end_handle) { + data->group->end_handle = sys_cpu_to_le16(attr->handle); + } + return BT_GATT_ITER_CONTINUE; + } + + /* If Group Type don't match skip */ + if (bt_uuid_cmp(attr->uuid, data->uuid)) { + data->group = NULL; + return BT_GATT_ITER_CONTINUE; + } + + BT_DBG("handle 0x%04x", attr->handle); + + /* Stop if there is no space left */ + if (data->rsp->len && + att->chan.tx.mtu - data->buf->len < data->rsp->len) { + return BT_GATT_ITER_STOP; + } + + /* Fast foward to next group position */ + data->group = net_buf_add(data->buf, sizeof(*data->group)); + + /* Initialize group handle range */ + data->group->start_handle = sys_cpu_to_le16(attr->handle); + data->group->end_handle = sys_cpu_to_le16(attr->handle); + + /* Read attribute value and store in the buffer */ + read = attr->read(conn, attr, data->buf->data + data->buf->len, + att->chan.tx.mtu - data->buf->len, 0); + if (read < 0) { + /* TODO: Handle read errors */ + return BT_GATT_ITER_STOP; + } + + if (!data->rsp->len) { + /* Set len to be the first group found */ + data->rsp->len = read + sizeof(*data->group); + } else if (data->rsp->len != read + sizeof(*data->group)) { + /* All groups entries should have the same size */ + data->buf->len -= sizeof(*data->group); + return false; + } + + net_buf_add(data->buf, read); + + /* Continue to find the end handle */ + return BT_GATT_ITER_CONTINUE; +} + +static uint8_t att_read_group_rsp(struct bt_att *att, struct bt_uuid *uuid, + uint16_t start_handle, uint16_t end_handle) +{ + struct bt_conn *conn = att->chan.chan.conn; + struct read_group_data data; + + memset(&data, 0, sizeof(data)); + + data.buf = bt_att_create_pdu(conn, BT_ATT_OP_READ_GROUP_RSP, + sizeof(*data.rsp)); + if (!data.buf) { + return BT_ATT_ERR_UNLIKELY; + } + + data.att = att; + data.uuid = uuid; + data.rsp = net_buf_add(data.buf, sizeof(*data.rsp)); + data.rsp->len = 0; + data.group = NULL; + + bt_gatt_foreach_attr(start_handle, end_handle, read_group_cb, &data); + + if (!data.rsp->len) { + net_buf_unref(data.buf); + /* Respond here since handle is set */ + send_err_rsp(conn, BT_ATT_OP_READ_GROUP_REQ, start_handle, + BT_ATT_ERR_ATTRIBUTE_NOT_FOUND); + return 0; + } + + bt_l2cap_send(conn, BT_L2CAP_CID_ATT, data.buf); + + return 0; +} + +static uint8_t att_read_group_req(struct bt_att *att, struct net_buf *buf) +{ + struct bt_conn *conn = att->chan.chan.conn; + struct bt_att_read_group_req *req; + uint16_t start_handle, end_handle, err_handle; + union { + struct bt_uuid uuid; + struct bt_uuid_16 u16; + struct bt_uuid_128 u128; + } u; + + /* Type can only be UUID16 or UUID128 */ + if (buf->len != sizeof(*req) + 2 && buf->len != sizeof(*req) + 16) { + return BT_ATT_ERR_INVALID_PDU; + } + + req = (void *)buf->data; + + start_handle = sys_le16_to_cpu(req->start_handle); + end_handle = sys_le16_to_cpu(req->end_handle); + net_buf_pull(buf, sizeof(*req)); + + if (!uuid_create(&u.uuid, buf)) { + return BT_ATT_ERR_UNLIKELY; + } + + BT_DBG("start_handle 0x%04x end_handle 0x%04x type %s", + start_handle, end_handle, bt_uuid_str(&u.uuid)); + + if (!range_is_valid(start_handle, end_handle, &err_handle)) { + send_err_rsp(conn, BT_ATT_OP_READ_GROUP_REQ, err_handle, + BT_ATT_ERR_INVALID_HANDLE); + return 0; + } + + /* Core v4.2, Vol 3, sec 2.5.3 Attribute Grouping: + * Not all of the grouping attributes can be used in the ATT + * Read By Group Type Request. The "Primary Service" and "Secondary + * Service" grouping types may be used in the Read By Group Type + * Request. The "Characteristic" grouping type shall not be used in + * the ATT Read By Group Type Request. + */ + if (bt_uuid_cmp(&u.uuid, BT_UUID_GATT_PRIMARY) && + bt_uuid_cmp(&u.uuid, BT_UUID_GATT_SECONDARY)) { + send_err_rsp(conn, BT_ATT_OP_READ_GROUP_REQ, start_handle, + BT_ATT_ERR_UNSUPPORTED_GROUP_TYPE); + return 0; + } + + return att_read_group_rsp(att, &u.uuid, start_handle, end_handle); +} + +struct write_data { + struct bt_conn *conn; + struct net_buf *buf; + uint8_t op; + const void *value; + uint8_t len; + uint16_t offset; + uint8_t err; +}; + +static uint8_t write_cb(const struct bt_gatt_attr *attr, void *user_data) +{ + struct write_data *data = user_data; + int write; + + BT_DBG("handle 0x%04x offset %u", attr->handle, data->offset); + + /* Check attribute permissions */ + data->err = check_perm(data->conn, attr, BT_GATT_PERM_WRITE_MASK); + if (data->err) { + return BT_GATT_ITER_STOP; + } + + /* Read attribute value and store in the buffer */ + write = attr->write(data->conn, attr, data->value, data->len, + data->offset, 0); + if (write < 0 || write != data->len) { + data->err = err_to_att(write); + return BT_GATT_ITER_STOP; + } + + data->err = 0; + + return BT_GATT_ITER_CONTINUE; +} + +static uint8_t att_write_rsp(struct bt_conn *conn, uint8_t op, uint8_t rsp, + uint16_t handle, uint16_t offset, + const void *value, uint8_t len) +{ + struct write_data data; + + if (!handle) { + return BT_ATT_ERR_INVALID_HANDLE; + } + + memset(&data, 0, sizeof(data)); + + /* Only allocate buf if required to respond */ + if (rsp) { + data.buf = bt_att_create_pdu(conn, rsp, 0); + if (!data.buf) { + return BT_ATT_ERR_UNLIKELY; + } + } + + data.conn = conn; + data.op = op; + data.offset = offset; + data.value = value; + data.len = len; + data.err = BT_ATT_ERR_INVALID_HANDLE; + + bt_gatt_foreach_attr(handle, handle, write_cb, &data); + + if (data.err) { + /* In case of error discard data and respond with an error */ + if (rsp) { + net_buf_unref(data.buf); + /* Respond here since handle is set */ + send_err_rsp(conn, op, handle, data.err); + } + return op == BT_ATT_OP_EXEC_WRITE_REQ ? data.err : 0; + } + + if (data.buf) { + bt_l2cap_send(conn, BT_L2CAP_CID_ATT, data.buf); + } + + return 0; +} + +static uint8_t att_write_req(struct bt_att *att, struct net_buf *buf) +{ + struct bt_conn *conn = att->chan.chan.conn; + uint16_t handle; + + handle = net_buf_pull_le16(buf); + + BT_DBG("handle 0x%04x", handle); + + return att_write_rsp(conn, BT_ATT_OP_WRITE_REQ, BT_ATT_OP_WRITE_RSP, + handle, 0, buf->data, buf->len); +} + +#if CONFIG_BLUETOOTH_ATT_PREPARE_COUNT > 0 +struct prep_data { + struct bt_conn *conn; + struct net_buf *buf; + const void *value; + uint8_t len; + uint16_t offset; + uint8_t err; +}; + +static uint8_t prep_write_cb(const struct bt_gatt_attr *attr, void *user_data) +{ + struct prep_data *data = user_data; + struct bt_attr_data *attr_data; + int write; + + BT_DBG("handle 0x%04x offset %u", attr->handle, data->offset); + + /* Check attribute permissions */ + data->err = check_perm(data->conn, attr, BT_GATT_PERM_WRITE_MASK); + if (data->err) { + return BT_GATT_ITER_STOP; + } + + if (!(attr->perm & BT_GATT_PERM_PREPARE_WRITE)) { + data->err = BT_ATT_ERR_WRITE_NOT_PERMITTED; + return BT_GATT_ITER_STOP; + } + + /* Write attribute value to check if device is authorized */ + write = attr->write(data->conn, attr, data->value, data->len, + data->offset, BT_GATT_WRITE_FLAG_PREPARE); + if (write != 0) { + data->err = err_to_att(write); + return BT_GATT_ITER_STOP; + } + + /* Copy data into the outstanding queue */ + data->buf = net_buf_alloc(&prep_pool, K_NO_WAIT); + if (!data->buf) { + data->err = BT_ATT_ERR_PREPARE_QUEUE_FULL; + return BT_GATT_ITER_STOP; + } + + attr_data = net_buf_user_data(data->buf); + attr_data->handle = attr->handle; + attr_data->offset = data->offset; + + net_buf_add_mem(data->buf, data->value, data->len); + + data->err = 0; + + return BT_GATT_ITER_CONTINUE; +} + +static uint8_t att_prep_write_rsp(struct bt_att *att, uint16_t handle, + uint16_t offset, const void *value, + uint8_t len) +{ + struct bt_conn *conn = att->chan.chan.conn; + struct prep_data data; + struct bt_att_prepare_write_rsp *rsp; + + if (!handle) { + return BT_ATT_ERR_INVALID_HANDLE; + } + + memset(&data, 0, sizeof(data)); + + data.conn = conn; + data.offset = offset; + data.value = value; + data.len = len; + data.err = BT_ATT_ERR_INVALID_HANDLE; + + bt_gatt_foreach_attr(handle, handle, prep_write_cb, &data); + + if (data.err) { + /* Respond here since handle is set */ + send_err_rsp(conn, BT_ATT_OP_PREPARE_WRITE_REQ, handle, + data.err); + return 0; + } + + BT_DBG("buf %p handle 0x%04x offset %u", data.buf, handle, offset); + + /* Store buffer in the outstanding queue */ + net_buf_put(&att->prep_queue, data.buf); + + /* Generate response */ + data.buf = bt_att_create_pdu(conn, BT_ATT_OP_PREPARE_WRITE_RSP, 0); + if (!data.buf) { + return BT_ATT_ERR_UNLIKELY; + } + + rsp = net_buf_add(data.buf, sizeof(*rsp)); + rsp->handle = sys_cpu_to_le16(handle); + rsp->offset = sys_cpu_to_le16(offset); + net_buf_add(data.buf, len); + memcpy(rsp->value, value, len); + + bt_l2cap_send(conn, BT_L2CAP_CID_ATT, data.buf); + + return 0; +} +#endif /* CONFIG_BLUETOOTH_ATT_PREPARE_COUNT */ + +static uint8_t att_prepare_write_req(struct bt_att *att, struct net_buf *buf) +{ +#if CONFIG_BLUETOOTH_ATT_PREPARE_COUNT == 0 + return BT_ATT_ERR_NOT_SUPPORTED; +#else + struct bt_att_prepare_write_req *req; + uint16_t handle, offset; + + req = (void *)buf->data; + + handle = sys_le16_to_cpu(req->handle); + offset = sys_le16_to_cpu(req->offset); + net_buf_pull(buf, sizeof(*req)); + + BT_DBG("handle 0x%04x offset %u", handle, offset); + + return att_prep_write_rsp(att, handle, offset, buf->data, buf->len); +#endif /* CONFIG_BLUETOOTH_ATT_PREPARE_COUNT */ +} + +#if CONFIG_BLUETOOTH_ATT_PREPARE_COUNT > 0 +static uint8_t att_exec_write_rsp(struct bt_att *att, uint8_t flags) +{ + struct bt_conn *conn = att->chan.chan.conn; + struct net_buf *buf; + uint8_t err = 0; + + while ((buf = net_buf_get(&att->prep_queue, K_NO_WAIT))) { + struct bt_attr_data *data = net_buf_user_data(buf); + + BT_DBG("buf %p handle 0x%04x offset %u", buf, data->handle, + data->offset); + + /* Just discard the data if an error was set */ + if (!err && flags == BT_ATT_FLAG_EXEC) { + err = att_write_rsp(conn, BT_ATT_OP_EXEC_WRITE_REQ, 0, + data->handle, data->offset, + buf->data, buf->len); + if (err) { + /* Respond here since handle is set */ + send_err_rsp(conn, BT_ATT_OP_EXEC_WRITE_REQ, + data->handle, err); + } + } + + net_buf_unref(buf); + } + + if (err) { + return 0; + } + + /* Generate response */ + buf = bt_att_create_pdu(conn, BT_ATT_OP_EXEC_WRITE_RSP, 0); + if (!buf) { + return BT_ATT_ERR_UNLIKELY; + } + + bt_l2cap_send(conn, BT_L2CAP_CID_ATT, buf); + + return 0; +} +#endif /* CONFIG_BLUETOOTH_ATT_PREPARE_COUNT */ + + +static uint8_t att_exec_write_req(struct bt_att *att, struct net_buf *buf) +{ +#if CONFIG_BLUETOOTH_ATT_PREPARE_COUNT == 0 + return BT_ATT_ERR_NOT_SUPPORTED; +#else + struct bt_att_exec_write_req *req; + + req = (void *)buf->data; + + BT_DBG("flags 0x%02x", req->flags); + + return att_exec_write_rsp(att, req->flags); +#endif /* CONFIG_BLUETOOTH_ATT_PREPARE_COUNT */ +} + +static uint8_t att_write_cmd(struct bt_att *att, struct net_buf *buf) +{ + struct bt_conn *conn = att->chan.chan.conn; + uint16_t handle; + + handle = net_buf_pull_le16(buf); + + BT_DBG("handle 0x%04x", handle); + + return att_write_rsp(conn, 0, 0, handle, 0, buf->data, buf->len); +} + +static uint8_t att_signed_write_cmd(struct bt_att *att, struct net_buf *buf) +{ + struct bt_conn *conn = att->chan.chan.conn; + struct bt_att_signed_write_cmd *req; + uint16_t handle; + int err; + + req = (void *)buf->data; + + handle = sys_le16_to_cpu(req->handle); + + BT_DBG("handle 0x%04x", handle); + + /* Verifying data requires full buffer including attribute header */ + net_buf_push(buf, sizeof(struct bt_att_hdr)); + err = bt_smp_sign_verify(conn, buf); + if (err) { + BT_ERR("Error verifying data"); + /* No response for this command */ + return 0; + } + + net_buf_pull(buf, sizeof(struct bt_att_hdr)); + net_buf_pull(buf, sizeof(*req)); + + return att_write_rsp(conn, 0, 0, handle, 0, buf->data, + buf->len - sizeof(struct bt_att_signature)); +} + +#if defined(CONFIG_BLUETOOTH_SMP) +static int att_change_security(struct bt_conn *conn, uint8_t err) +{ + bt_security_t sec; + + switch (err) { + case BT_ATT_ERR_INSUFFICIENT_ENCRYPTION: + if (conn->sec_level >= BT_SECURITY_MEDIUM) + return -EALREADY; + sec = BT_SECURITY_MEDIUM; + break; + case BT_ATT_ERR_AUTHENTICATION: + if (conn->sec_level < BT_SECURITY_MEDIUM) { + /* BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part C] + * page 375: + * + * If an LTK is not available, the service request + * shall be rejected with the error code 'Insufficient + * Authentication'. + * Note: When the link is not encrypted, the error code + * "Insufficient Authentication" does not indicate that + * MITM protection is required. + */ + sec = BT_SECURITY_MEDIUM; + } else if (conn->sec_level < BT_SECURITY_HIGH) { + /* BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part C] + * page 375: + * + * If an authenticated pairing is required but only an + * unauthenticated pairing has occurred and the link is + * currently encrypted, the service request shall be + * rejected with the error code 'Insufficient + * Authentication'. + * Note: When unauthenticated pairing has occurred and + * the link is currently encrypted, the error code + * 'Insufficient Authentication' indicates that MITM + * protection is required. + */ + sec = BT_SECURITY_HIGH; + } else if (conn->sec_level < BT_SECURITY_FIPS) { + /* BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part C] + * page 375: + * + * If LE Secure Connections authenticated pairing is + * required but LE legacy pairing has occurred and the + * link is currently encrypted, the service request + * shall be rejected with the error code ''Insufficient + * Authentication'. + */ + sec = BT_SECURITY_FIPS; + } else { + return -EALREADY; + } + break; + default: + return -EINVAL; + } + + return bt_conn_security(conn, sec); +} +#endif /* CONFIG_BLUETOOTH_SMP */ + +static uint8_t att_error_rsp(struct bt_att *att, struct net_buf *buf) +{ + struct bt_att_error_rsp *rsp; + uint8_t err; + + rsp = (void *)buf->data; + + BT_DBG("request 0x%02x handle 0x%04x error 0x%02x", rsp->request, + sys_le16_to_cpu(rsp->handle), rsp->error); + + if (!att->req) { + err = BT_ATT_ERR_UNLIKELY; + goto done; + } + + if (att->req->buf) { + /* Restore state to be resent */ + net_buf_simple_restore(&att->req->buf->b, &att->req->state); + } + + err = rsp->error; +#if defined(CONFIG_BLUETOOTH_SMP) + if (att->req->retrying) { + goto done; + } + + /* Check if security needs to be changed */ + if (!att_change_security(att->chan.chan.conn, err)) { + att->req->retrying = true; + /* Wait security_changed: TODO: Handle fail case */ + return 0; + } +#endif /* CONFIG_BLUETOOTH_SMP */ + +done: + return att_handle_rsp(att, NULL, 0, err); +} + +static uint8_t att_handle_find_info_rsp(struct bt_att *att, + struct net_buf *buf) +{ + BT_DBG(""); + + return att_handle_rsp(att, buf->data, buf->len, 0); +} + +static uint8_t att_handle_find_type_rsp(struct bt_att *att, + struct net_buf *buf) +{ + BT_DBG(""); + + return att_handle_rsp(att, buf->data, buf->len, 0); +} + +static uint8_t att_handle_read_type_rsp(struct bt_att *att, + struct net_buf *buf) +{ + BT_DBG(""); + + return att_handle_rsp(att, buf->data, buf->len, 0); +} + +static uint8_t att_handle_read_rsp(struct bt_att *att, + struct net_buf *buf) +{ + BT_DBG(""); + + return att_handle_rsp(att, buf->data, buf->len, 0); +} + +static uint8_t att_handle_read_blob_rsp(struct bt_att *att, + struct net_buf *buf) +{ + BT_DBG(""); + + return att_handle_rsp(att, buf->data, buf->len, 0); +} + +static uint8_t att_handle_read_mult_rsp(struct bt_att *att, + struct net_buf *buf) +{ + BT_DBG(""); + + return att_handle_rsp(att, buf->data, buf->len, 0); +} + +static uint8_t att_handle_write_rsp(struct bt_att *att, + struct net_buf *buf) +{ + BT_DBG(""); + + return att_handle_rsp(att, buf->data, buf->len, 0); +} + +static uint8_t att_handle_prepare_write_rsp(struct bt_att *att, + struct net_buf *buf) +{ + BT_DBG(""); + + return att_handle_rsp(att, buf->data, buf->len, 0); +} + +static uint8_t att_handle_exec_write_rsp(struct bt_att *att, + struct net_buf *buf) +{ + BT_DBG(""); + + return att_handle_rsp(att, buf->data, buf->len, 0); +} + +static uint8_t att_notify(struct bt_att *att, struct net_buf *buf) +{ + struct bt_conn *conn = att->chan.chan.conn; + uint16_t handle; + + handle = net_buf_pull_le16(buf); + + BT_DBG("handle 0x%04x", handle); + + bt_gatt_notification(conn, handle, buf->data, buf->len); + + return 0; +} + +static uint8_t att_indicate(struct bt_att *att, struct net_buf *buf) +{ + struct bt_conn *conn = att->chan.chan.conn; + uint16_t handle; + + handle = net_buf_pull_le16(buf); + + BT_DBG("handle 0x%04x", handle); + + bt_gatt_notification(conn, handle, buf->data, buf->len); + + buf = bt_att_create_pdu(conn, BT_ATT_OP_CONFIRM, 0); + if (!buf) { + return 0; + } + + bt_l2cap_send(conn, BT_L2CAP_CID_ATT, buf); + + return 0; +} + +static uint8_t att_confirm(struct bt_att *att, struct net_buf *buf) +{ + BT_DBG(""); + + return att_handle_rsp(att, buf->data, buf->len, 0); +} + +static const struct { + uint8_t op; + uint8_t (*func)(struct bt_att *att, struct net_buf *buf); + uint8_t expect_len; +} handlers[] = { + { BT_ATT_OP_ERROR_RSP, att_error_rsp, + sizeof(struct bt_att_error_rsp) }, + { BT_ATT_OP_MTU_REQ, att_mtu_req, + sizeof(struct bt_att_exchange_mtu_req) }, + { BT_ATT_OP_MTU_RSP, att_mtu_rsp, + sizeof(struct bt_att_exchange_mtu_rsp) }, + { BT_ATT_OP_FIND_INFO_REQ, att_find_info_req, + sizeof(struct bt_att_find_info_req) }, + { BT_ATT_OP_FIND_INFO_RSP, att_handle_find_info_rsp, + sizeof(struct bt_att_find_info_rsp) }, + { BT_ATT_OP_FIND_TYPE_REQ, att_find_type_req, + sizeof(struct bt_att_find_type_req) }, + { BT_ATT_OP_FIND_TYPE_RSP, att_handle_find_type_rsp, + sizeof(struct bt_att_find_type_rsp) }, + { BT_ATT_OP_READ_TYPE_REQ, att_read_type_req, + sizeof(struct bt_att_read_type_req) }, + { BT_ATT_OP_READ_TYPE_RSP, att_handle_read_type_rsp, + sizeof(struct bt_att_read_type_rsp) }, + { BT_ATT_OP_READ_REQ, att_read_req, + sizeof(struct bt_att_read_req) }, + { BT_ATT_OP_READ_RSP, att_handle_read_rsp, + sizeof(struct bt_att_read_rsp) }, + { BT_ATT_OP_READ_BLOB_REQ, att_read_blob_req, + sizeof(struct bt_att_read_blob_req) }, + { BT_ATT_OP_READ_BLOB_RSP, att_handle_read_blob_rsp, + sizeof(struct bt_att_read_blob_rsp) }, + { BT_ATT_OP_READ_MULT_REQ, att_read_mult_req, + BT_ATT_READ_MULT_MIN_LEN_REQ }, + { BT_ATT_OP_READ_MULT_RSP, att_handle_read_mult_rsp, + sizeof(struct bt_att_read_mult_rsp) }, + { BT_ATT_OP_READ_GROUP_REQ, att_read_group_req, + sizeof(struct bt_att_read_group_req) }, + { BT_ATT_OP_WRITE_REQ, att_write_req, + sizeof(struct bt_att_write_req) }, + { BT_ATT_OP_WRITE_RSP, att_handle_write_rsp, 0 }, + { BT_ATT_OP_PREPARE_WRITE_REQ, att_prepare_write_req, + sizeof(struct bt_att_prepare_write_req) }, + { BT_ATT_OP_PREPARE_WRITE_RSP, att_handle_prepare_write_rsp, + sizeof(struct bt_att_prepare_write_rsp) }, + { BT_ATT_OP_EXEC_WRITE_REQ, att_exec_write_req, + sizeof(struct bt_att_exec_write_req) }, + { BT_ATT_OP_EXEC_WRITE_RSP, att_handle_exec_write_rsp, 0 }, + { BT_ATT_OP_NOTIFY, att_notify, + sizeof(struct bt_att_notify) }, + { BT_ATT_OP_INDICATE, att_indicate, + sizeof(struct bt_att_indicate) }, + { BT_ATT_OP_CONFIRM, att_confirm, 0 }, + { BT_ATT_OP_WRITE_CMD, att_write_cmd, + sizeof(struct bt_att_write_cmd) }, + { BT_ATT_OP_SIGNED_WRITE_CMD, att_signed_write_cmd, + sizeof(struct bt_att_write_cmd) + sizeof(struct bt_att_signature) }, +}; + +static void bt_att_recv(struct bt_l2cap_chan *chan, struct net_buf *buf) +{ + struct bt_att *att = ATT_CHAN(chan); + struct bt_att_hdr *hdr = (void *)buf->data; + uint8_t err = BT_ATT_ERR_NOT_SUPPORTED; + size_t i; + + if (buf->len < sizeof(*hdr)) { + BT_ERR("Too small ATT PDU received"); + return; + } + + BT_DBG("Received ATT code 0x%02x len %u", hdr->code, buf->len); + + net_buf_pull(buf, sizeof(*hdr)); + + for (i = 0; i < ARRAY_SIZE(handlers); i++) { + if (hdr->code != handlers[i].op) { + continue; + } + + if (buf->len < handlers[i].expect_len) { + BT_ERR("Invalid len %u for code 0x%02x", buf->len, + hdr->code); + err = BT_ATT_ERR_INVALID_PDU; + break; + } + + err = handlers[i].func(att, buf); + break; + } + + /* Commands don't have response */ + if ((hdr->code & BT_ATT_OP_CMD_FLAG)) { + return; + } + + if (err) { + BT_DBG("ATT error 0x%02x", err); + send_err_rsp(chan->conn, hdr->code, 0, err); + } +} + +static struct bt_att *att_chan_get(struct bt_conn *conn) +{ + struct bt_l2cap_chan *chan; + + chan = bt_l2cap_le_lookup_rx_cid(conn, BT_L2CAP_CID_ATT); + if (!chan) { + BT_ERR("Unable to find ATT channel"); + return NULL; + } + + return ATT_CHAN(chan); +} + +struct net_buf *bt_att_create_pdu(struct bt_conn *conn, uint8_t op, size_t len) +{ + struct bt_att_hdr *hdr; + struct net_buf *buf; + struct bt_att *att; + + att = att_chan_get(conn); + if (!att) { + return NULL; + } + + if (len + sizeof(op) > att->chan.tx.mtu) { + BT_WARN("ATT MTU exceeded, max %u, wanted %zu", + att->chan.tx.mtu, len + sizeof(op)); + return NULL; + } + + buf = bt_l2cap_create_pdu(NULL, 0); + + hdr = net_buf_add(buf, sizeof(*hdr)); + hdr->code = op; + + return buf; +} + +static void att_reset(struct bt_att *att) +{ + struct bt_att_req *req, *tmp; +#if CONFIG_BLUETOOTH_ATT_PREPARE_COUNT > 0 + struct net_buf *buf; + + /* Discard queued buffers */ + while ((buf = k_fifo_get(&att->prep_queue, K_NO_WAIT))) { + net_buf_unref(buf); + } +#endif + + /* Notify pending requests */ + SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&att->reqs, req, tmp, node) { + if (req->func) { + req->func(NULL, BT_ATT_ERR_UNLIKELY, NULL, 0, req); + } + + att_req_destroy(req); + } + + /* Reset list */ + sys_slist_init(&att->reqs); + + if (!att->req) { + return; + } + + /* Notify outstanding request */ + att_handle_rsp(att, NULL, 0, BT_ATT_ERR_UNLIKELY); +} + +static void att_timeout(struct k_work *work) +{ + struct bt_att *att = CONTAINER_OF(work, struct bt_att, timeout_work); + struct bt_l2cap_le_chan *ch = + CONTAINER_OF(att, struct bt_l2cap_le_chan, chan); + + BT_ERR("ATT Timeout"); + + /* BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part F] page 480: + * + * A transaction not completed within 30 seconds shall time out. Such a + * transaction shall be considered to have failed and the local higher + * layers shall be informed of this failure. No more attribute protocol + * requests, commands, indications or notifications shall be sent to the + * target device on this ATT Bearer. + */ + att_reset(att); + + /* Consider the channel disconnected */ + bt_gatt_disconnected(ch->chan.conn); + ch->chan.conn = NULL; +} +static void* prep_queue_msg[CONFIG_BLUETOOTH_ATT_PREPARE_COUNT]; +static void bt_att_connected(struct bt_l2cap_chan *chan) +{ + struct bt_att *att = ATT_CHAN(chan); + struct bt_l2cap_le_chan *ch = BT_L2CAP_LE_CHAN(chan); + + BT_DBG("chan %p cid 0x%04x", ch, ch->tx.cid); + +#if CONFIG_BLUETOOTH_ATT_PREPARE_COUNT > 0 + k_fifo_init(&att->prep_queue,"prep queue",(void **)&prep_queue_msg,CONFIG_BLUETOOTH_ATT_PREPARE_COUNT); +#endif + + ch->tx.mtu = BT_ATT_DEFAULT_LE_MTU; + ch->rx.mtu = BT_ATT_DEFAULT_LE_MTU; + + k_delayed_work_init(&att->timeout_work, att_timeout); + sys_slist_init(&att->reqs); + + bt_gatt_connected(ch->chan.conn); +} + +static void bt_att_disconnected(struct bt_l2cap_chan *chan) +{ + struct bt_att *att = ATT_CHAN(chan); + struct bt_l2cap_le_chan *ch = BT_L2CAP_LE_CHAN(chan); + + BT_DBG("chan %p cid 0x%04x", ch, ch->tx.cid); + + att_reset(att); + + bt_gatt_disconnected(ch->chan.conn); + memset(att, 0, sizeof(*att)); +} + +#if defined(CONFIG_BLUETOOTH_SMP) +static void bt_att_encrypt_change(struct bt_l2cap_chan *chan, + uint8_t hci_status) +{ + struct bt_att *att = ATT_CHAN(chan); + struct bt_l2cap_le_chan *ch = BT_L2CAP_LE_CHAN(chan); + struct bt_conn *conn = ch->chan.conn; + + BT_DBG("chan %p conn %p handle %u sec_level 0x%02x status 0x%02x", ch, + conn, conn->handle, conn->sec_level, hci_status); + + /* + * If status (HCI status of security procedure) is non-zero, notify + * outstanding request about security failure. + */ + if (hci_status) { + att_handle_rsp(att, NULL, 0, BT_ATT_ERR_AUTHENTICATION); + return; + } + + if (conn->sec_level == BT_SECURITY_LOW) { + return; + } + + if (!att->req || !att->req->retrying) { + return; + } + + BT_DBG("Retrying"); + + /* Resend buffer */ + bt_l2cap_send(conn, BT_L2CAP_CID_ATT, att->req->buf); + att->req->buf = NULL; +} +#endif /* CONFIG_BLUETOOTH_SMP */ + +static int bt_att_accept(struct bt_conn *conn, struct bt_l2cap_chan **chan) +{ + int i; + static struct bt_l2cap_chan_ops ops = { + .connected = bt_att_connected, + .disconnected = bt_att_disconnected, + .recv = bt_att_recv, +#if defined(CONFIG_BLUETOOTH_SMP) + .encrypt_change = bt_att_encrypt_change, +#endif /* CONFIG_BLUETOOTH_SMP */ + }; + + BT_DBG("conn %p handle %u", conn, conn->handle); + + for (i = 0; i < ARRAY_SIZE(bt_req_pool); i++) { + struct bt_att *att = &bt_req_pool[i]; + + if (att->chan.chan.conn) { + continue; + } + + att->chan.chan.ops = &ops; + + *chan = &att->chan.chan; + + return 0; + } + + BT_ERR("No available ATT context for conn %p", conn); + + return -ENOMEM; +} + +void bt_att_init(void) +{ + static struct bt_l2cap_fixed_chan chan = { + .cid = BT_L2CAP_CID_ATT, + .accept = bt_att_accept, + }; + + bt_l2cap_le_fixed_chan_register(&chan); + +#if CONFIG_BLUETOOTH_ATT_PREPARE_COUNT > 0 + NET_BUF_POOL_INIT(prep_pool); +#endif +} + +uint16_t bt_att_get_mtu(struct bt_conn *conn) +{ + struct bt_att *att; + + att = att_chan_get(conn); + if (!att) { + return 0; + } + + /* tx and rx MTU shall be symmetric */ + return att->chan.tx.mtu; +} + +int bt_att_send(struct bt_conn *conn, struct net_buf *buf) +{ + struct bt_att *att; + struct bt_att_hdr *hdr; + + if (!conn || !buf) { + return -EINVAL; + } + + att = att_chan_get(conn); + if (!att) { + return -ENOTCONN; + } + + hdr = (void *)buf->data; + + if (hdr->code == BT_ATT_OP_SIGNED_WRITE_CMD) { + int err; + + err = bt_smp_sign(conn, buf); + if (err) { + BT_ERR("Error signing data"); + return err; + } + } + + bt_l2cap_send(conn, BT_L2CAP_CID_ATT, buf); + + return 0; +} + +int bt_att_req_send(struct bt_conn *conn, struct bt_att_req *req) +{ + struct bt_att *att; + + BT_DBG("conn %p req %p", conn, req); + + if (!conn || !req) { + return -EINVAL; + } + + att = att_chan_get(conn); + if (!att) { + return -ENOTCONN; + } + + /* Check if there is a request outstanding */ + if (att->req) { + /* Queue the request to be send later */ + sys_slist_append(&att->reqs, &req->node); + return 0; + } + + return att_send_req(att, req); +} + +void bt_att_req_cancel(struct bt_conn *conn, struct bt_att_req *req) +{ + struct bt_att *att; + + if (!conn || !req) { + return; + } + + att = att_chan_get(conn); + if (!att) { + return; + } + + /* Check if request is outstanding */ + if (att->req == req) { + att->req = NULL; + } else { + /* Remove request from the list */ + sys_slist_find_and_remove(&att->reqs, &req->node); + } + + att_req_destroy(req); +} diff --git a/kernel/protocols/bluetooth/host/att_internal.h b/kernel/protocols/bluetooth/host/att_internal.h new file mode 100644 index 0000000000..793aaa1aad --- /dev/null +++ b/kernel/protocols/bluetooth/host/att_internal.h @@ -0,0 +1,251 @@ +/* att_internal.h - Attribute protocol handling */ + +/* + * Copyright (c) 2015-2016 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define BT_ATT_DEFAULT_LE_MTU 23 + +#if BT_L2CAP_RX_MTU < CONFIG_BLUETOOTH_L2CAP_TX_MTU +#define BT_ATT_MTU BT_L2CAP_RX_MTU +#else +#define BT_ATT_MTU CONFIG_BLUETOOTH_L2CAP_TX_MTU +#endif + +struct bt_att_hdr { + uint8_t code; +} __packed; + +#define BT_ATT_OP_ERROR_RSP 0x01 +struct bt_att_error_rsp { + uint8_t request; + uint16_t handle; + uint8_t error; +} __packed; + +#define BT_ATT_OP_MTU_REQ 0x02 +struct bt_att_exchange_mtu_req { + uint16_t mtu; +} __packed; + +#define BT_ATT_OP_MTU_RSP 0x03 +struct bt_att_exchange_mtu_rsp { + uint16_t mtu; +} __packed; + +/* Find Information Request */ +#define BT_ATT_OP_FIND_INFO_REQ 0x04 +struct bt_att_find_info_req { + uint16_t start_handle; + uint16_t end_handle; +} __packed; + +/* Format field values for BT_ATT_OP_FIND_INFO_RSP */ +#define BT_ATT_INFO_16 0x01 +#define BT_ATT_INFO_128 0x02 + +struct bt_att_info_16 { + uint16_t handle; + uint16_t uuid; +} __packed; + +struct bt_att_info_128 { + uint16_t handle; + uint8_t uuid[16]; +} __packed; + +/* Find Information Response */ +#define BT_ATT_OP_FIND_INFO_RSP 0x05 +struct bt_att_find_info_rsp { + uint8_t format; + uint8_t info[0]; +} __packed; + +/* Find By Type Value Request */ +#define BT_ATT_OP_FIND_TYPE_REQ 0x06 +struct bt_att_find_type_req { + uint16_t start_handle; + uint16_t end_handle; + uint16_t type; + uint8_t value[0]; +} __packed; + +struct bt_att_handle_group { + uint16_t start_handle; + uint16_t end_handle; +} __packed; + +/* Find By Type Value Response */ +#define BT_ATT_OP_FIND_TYPE_RSP 0x07 +struct bt_att_find_type_rsp { + struct bt_att_handle_group list[0]; +} __packed; + +/* Read By Type Request */ +#define BT_ATT_OP_READ_TYPE_REQ 0x08 +struct bt_att_read_type_req { + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid[0]; +} __packed; + +struct bt_att_data { + uint16_t handle; + uint8_t value[0]; +} __packed; + +/* Read By Type Response */ +#define BT_ATT_OP_READ_TYPE_RSP 0x09 +struct bt_att_read_type_rsp { + uint8_t len; + struct bt_att_data data[0]; +} __packed; + +/* Read Request */ +#define BT_ATT_OP_READ_REQ 0x0a +struct bt_att_read_req { + uint16_t handle; +} __packed; + +/* Read Response */ +#define BT_ATT_OP_READ_RSP 0x0b +struct bt_att_read_rsp { + uint8_t value[0]; +} __packed; + +/* Read Blob Request */ +#define BT_ATT_OP_READ_BLOB_REQ 0x0c +struct bt_att_read_blob_req { + uint16_t handle; + uint16_t offset; +} __packed; + +/* Read Blob Response */ +#define BT_ATT_OP_READ_BLOB_RSP 0x0d +struct bt_att_read_blob_rsp { + uint8_t value[0]; +} __packed; + +/* Read Multiple Request */ +#define BT_ATT_READ_MULT_MIN_LEN_REQ 0x04 + +#define BT_ATT_OP_READ_MULT_REQ 0x0e +struct bt_att_read_mult_req { + uint16_t handles[0]; +} __packed; + +/* Read Multiple Respose */ +#define BT_ATT_OP_READ_MULT_RSP 0x0f +struct bt_att_read_mult_rsp { + uint8_t value[0]; +} __packed; + +/* Read by Group Type Request */ +#define BT_ATT_OP_READ_GROUP_REQ 0x10 +struct bt_att_read_group_req { + uint16_t start_handle; + uint16_t end_handle; + uint8_t uuid[0]; +} __packed; + +struct bt_att_group_data { + uint16_t start_handle; + uint16_t end_handle; + uint8_t value[0]; +} __packed; + +/* Read by Group Type Response */ +#define BT_ATT_OP_READ_GROUP_RSP 0x11 +struct bt_att_read_group_rsp { + uint8_t len; + struct bt_att_group_data data[0]; +} __packed; + +/* Write Request */ +#define BT_ATT_OP_WRITE_REQ 0x12 +struct bt_att_write_req { + uint16_t handle; + uint8_t value[0]; +} __packed; + +/* Write Response */ +#define BT_ATT_OP_WRITE_RSP 0x13 + +/* Prepare Write Request */ +#define BT_ATT_OP_PREPARE_WRITE_REQ 0x16 +struct bt_att_prepare_write_req { + uint16_t handle; + uint16_t offset; + uint8_t value[0]; +} __packed; + +/* Prepare Write Respond */ +#define BT_ATT_OP_PREPARE_WRITE_RSP 0x17 +struct bt_att_prepare_write_rsp { + uint16_t handle; + uint16_t offset; + uint8_t value[0]; +} __packed; + +/* Execute Write Request */ +#define BT_ATT_FLAG_CANCEL 0x00 +#define BT_ATT_FLAG_EXEC 0x01 + +#define BT_ATT_OP_EXEC_WRITE_REQ 0x18 +struct bt_att_exec_write_req { + uint8_t flags; +} __packed; + +/* Execute Write Response */ +#define BT_ATT_OP_EXEC_WRITE_RSP 0x19 + +/* Handle Value Notification */ +#define BT_ATT_OP_NOTIFY 0x1b +struct bt_att_notify { + uint16_t handle; + uint8_t value[0]; +} __packed; + +/* Handle Value Indication */ +#define BT_ATT_OP_INDICATE 0x1d +struct bt_att_indicate { + uint16_t handle; + uint8_t value[0]; +} __packed; + +/* Handle Value Confirm */ +#define BT_ATT_OP_CONFIRM 0x1e + +struct bt_att_signature { + uint8_t value[12]; +} __packed; + +/* Write Command */ +#define BT_ATT_OP_WRITE_CMD 0x52 +struct bt_att_write_cmd { + uint16_t handle; + uint8_t value[0]; +} __packed; + +/* Signed Write Command */ +#define BT_ATT_OP_SIGNED_WRITE_CMD 0xd2 +struct bt_att_signed_write_cmd { + uint16_t handle; + uint8_t value[0]; +} __packed; + +void bt_att_init(void); +uint16_t bt_att_get_mtu(struct bt_conn *conn); +struct net_buf *bt_att_create_pdu(struct bt_conn *conn, uint8_t op, + size_t len); + +/* Send ATT PDU over a connection */ +int bt_att_send(struct bt_conn *conn, struct net_buf *buf); + +/* Send ATT Request over a connection */ +int bt_att_req_send(struct bt_conn *conn, struct bt_att_req *req); + +/* Cancel ATT request */ +void bt_att_req_cancel(struct bt_conn *conn, struct bt_att_req *req); diff --git a/kernel/protocols/bluetooth/host/conn.c b/kernel/protocols/bluetooth/host/conn.c new file mode 100644 index 0000000000..df1cacdd19 --- /dev/null +++ b/kernel/protocols/bluetooth/host/conn.c @@ -0,0 +1,1838 @@ +/* conn.c - Bluetooth connection handling */ + +/* + * Copyright (c) 2015-2016 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include +#include +#include +#include +#include + +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_CONN) +#include +#include +#include +#include +#include +#include + +#include "hci_core.h" +#include "conn_internal.h" +#include "l2cap_internal.h" +#include "keys.h" +#include "smp.h" +#include "att_internal.h" + +NET_BUF_POOL_DEFINE(acl_tx_pool, CONFIG_BLUETOOTH_L2CAP_TX_BUF_COUNT, + BT_L2CAP_BUF_SIZE(CONFIG_BLUETOOTH_L2CAP_TX_MTU), + CONFIG_BLUETOOTH_L2CAP_TX_USER_DATA_SIZE, NULL); + +/* How long until we cancel HCI_LE_Create_Connection */ +#define CONN_TIMEOUT K_SECONDS(3) + +#if defined(CONFIG_BLUETOOTH_SMP) || defined(CONFIG_BLUETOOTH_BREDR) +const struct bt_conn_auth_cb *bt_auth; +#endif /* CONFIG_BLUETOOTH_SMP || CONFIG_BLUETOOTH_BREDR */ + +static struct bt_conn conns[CONFIG_BLUETOOTH_MAX_CONN]; +static struct bt_conn_cb *callback_list; +#if defined(CONFIG_BLUETOOTH_BREDR) +static struct bt_conn sco_conns[CONFIG_BLUETOOTH_MAX_SCO_CONN]; + +enum pairing_method { + LEGACY, /* Legacy (pre-SSP) pairing */ + JUST_WORKS, /* JustWorks pairing */ + PASSKEY_INPUT, /* Passkey Entry input */ + PASSKEY_DISPLAY, /* Passkey Entry display */ + PASSKEY_CONFIRM, /* Passkey confirm */ +}; + +/* based on table 5.7, Core Spec 4.2, Vol.3 Part C, 5.2.2.6 */ +static const uint8_t ssp_method[4 /* remote */][4 /* local */] = { + { JUST_WORKS, JUST_WORKS, PASSKEY_INPUT, JUST_WORKS }, + { JUST_WORKS, PASSKEY_CONFIRM, PASSKEY_INPUT, JUST_WORKS }, + { PASSKEY_DISPLAY, PASSKEY_DISPLAY, PASSKEY_INPUT, JUST_WORKS }, + { JUST_WORKS, JUST_WORKS, JUST_WORKS, JUST_WORKS }, +}; +#endif /* CONFIG_BLUETOOTH_BREDR */ + +static inline const char *state2str(bt_conn_state_t state) +{ + switch (state) { + case BT_CONN_DISCONNECTED: + return "disconnected"; + case BT_CONN_CONNECT_SCAN: + return "connect-scan"; + case BT_CONN_CONNECT: + return "connect"; + case BT_CONN_CONNECTED: + return "connected"; + case BT_CONN_DISCONNECT: + return "disconnect"; + default: + return "(unknown)"; + } +} + +static void notify_connected(struct bt_conn *conn) +{ + struct bt_conn_cb *cb; + + for (cb = callback_list; cb; cb = cb->_next) { + if (cb->connected) { + cb->connected(conn, conn->err); + } + } +} + +static void notify_disconnected(struct bt_conn *conn) +{ + struct bt_conn_cb *cb; + + for (cb = callback_list; cb; cb = cb->_next) { + if (cb->disconnected) { + cb->disconnected(conn, conn->err); + } + } +} + +void notify_le_param_updated(struct bt_conn *conn) +{ + struct bt_conn_cb *cb; + + for (cb = callback_list; cb; cb = cb->_next) { + if (cb->le_param_updated) { + cb->le_param_updated(conn, conn->le.interval, + conn->le.latency, + conn->le.timeout); + } + } +} + +bool le_param_req(struct bt_conn *conn, struct bt_le_conn_param *param) +{ + struct bt_conn_cb *cb; + + if (!bt_le_conn_params_valid(param)) { + return false; + } + + for (cb = callback_list; cb; cb = cb->_next) { + if (!cb->le_param_req) { + continue; + } + + if (!cb->le_param_req(conn, param)) { + return false; + } + + /* The callback may modify the parameters so we need to + * double-check that it returned valid parameters. + */ + if (!bt_le_conn_params_valid(param)) { + return false; + } + } + + /* Default to accepting if there's no app callback */ + return true; +} + +static void le_conn_update(struct k_work *work) +{ + struct bt_conn_le *le = CONTAINER_OF(work, struct bt_conn_le, + update_work); + struct bt_conn *conn = CONTAINER_OF(le, struct bt_conn, le); + const struct bt_le_conn_param *param; + + if (IS_ENABLED(CONFIG_BLUETOOTH_CENTRAL) && + conn->state == BT_CONN_CONNECT) { + bt_conn_disconnect(conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN); + return; + } + + param = BT_LE_CONN_PARAM(conn->le.interval_min, + conn->le.interval_max, + conn->le.latency, + conn->le.timeout); + + bt_conn_le_param_update(conn, param); +} + +static struct bt_conn *conn_new(void) +{ + struct bt_conn *conn = NULL; + int i; + + for (i = 0; i < ARRAY_SIZE(conns); i++) { + if (!atomic_get(&conns[i].ref)) { + conn = &conns[i]; + break; + } + } + + if (!conn) { + return NULL; + } + + memset(conn, 0, sizeof(*conn)); + + atomic_set(&conn->ref, 1); + + return conn; +} + +#if defined(CONFIG_BLUETOOTH_BREDR) +static struct bt_conn *sco_conn_new(void) +{ + struct bt_conn *sco_conn = NULL; + int i; + + for (i = 0; i < ARRAY_SIZE(sco_conns); i++) { + if (!atomic_get(&sco_conns[i].ref)) { + sco_conn = &sco_conns[i]; + break; + } + } + + if (!sco_conn) { + return NULL; + } + + memset(sco_conn, 0, sizeof(*sco_conn)); + + atomic_set(&sco_conn->ref, 1); + + return sco_conn; +} + +struct bt_conn *bt_conn_create_br(const bt_addr_t *peer, + const struct bt_br_conn_param *param) +{ + struct bt_hci_cp_connect *cp; + struct bt_conn *conn; + struct net_buf *buf; + + conn = bt_conn_lookup_addr_br(peer); + if (conn) { + switch (conn->state) { + return conn; + case BT_CONN_CONNECT: + case BT_CONN_CONNECTED: + return conn; + default: + bt_conn_unref(conn); + return NULL; + } + } + + conn = bt_conn_add_br(peer); + if (!conn) { + return NULL; + } + + buf = bt_hci_cmd_create(BT_HCI_OP_CONNECT, sizeof(*cp)); + if (!buf) { + bt_conn_unref(conn); + return NULL; + } + + cp = net_buf_add(buf, sizeof(*cp)); + + memset(cp, 0, sizeof(*cp)); + + memcpy(&cp->bdaddr, peer, sizeof(cp->bdaddr)); + cp->packet_type = sys_cpu_to_le16(0xcc18); /* DM1 DH1 DM3 DH5 DM5 DH5 */ + cp->pscan_rep_mode = 0x02; /* R2 */ + cp->allow_role_switch = param->allow_role_switch ? 0x01 : 0x00; + cp->clock_offset = 0x0000; /* TODO used cached clock offset */ + + if (bt_hci_cmd_send_sync(BT_HCI_OP_CONNECT, buf, NULL) < 0) { + bt_conn_unref(conn); + return NULL; + } + + bt_conn_set_state(conn, BT_CONN_CONNECT); + conn->role = BT_CONN_ROLE_MASTER; + + return conn; +} + +struct bt_conn *bt_conn_lookup_addr_br(const bt_addr_t *peer) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(conns); i++) { + if (!atomic_get(&conns[i].ref)) { + continue; + } + + if (conns[i].type != BT_CONN_TYPE_BR) { + continue; + } + + if (!bt_addr_cmp(peer, &conns[i].br.dst)) { + return bt_conn_ref(&conns[i]); + } + } + + return NULL; +} + +struct bt_conn *bt_conn_add_sco(const bt_addr_t *peer, int link_type) +{ + struct bt_conn *sco_conn = sco_conn_new(); + + if (!sco_conn) { + return NULL; + } + + sco_conn->sco.conn = bt_conn_lookup_addr_br(peer); + sco_conn->type = BT_CONN_TYPE_SCO; + + if (link_type == BT_HCI_SCO) { + if (BT_FEAT_LMP_ESCO_CAPABLE(bt_dev.features)) { + sco_conn->sco.pkt_type = (bt_dev.esco.pkt_type & + ESCO_PKT_MASK); + } else { + sco_conn->sco.pkt_type = (bt_dev.esco.pkt_type & + SCO_PKT_MASK); + } + } else if (link_type == BT_HCI_ESCO) { + sco_conn->sco.pkt_type = (bt_dev.esco.pkt_type & + ~EDR_ESCO_PKT_MASK); + } + + return sco_conn; +} + +struct bt_conn *bt_conn_add_br(const bt_addr_t *peer) +{ + struct bt_conn *conn = conn_new(); + + if (!conn) { + return NULL; + } + + bt_addr_copy(&conn->br.dst, peer); + conn->type = BT_CONN_TYPE_BR; + + return conn; +} + +static int pin_code_neg_reply(const bt_addr_t *bdaddr) +{ + struct bt_hci_cp_pin_code_neg_reply *cp; + struct net_buf *buf; + + BT_DBG(""); + + buf = bt_hci_cmd_create(BT_HCI_OP_PIN_CODE_NEG_REPLY, sizeof(*cp)); + if (!buf) { + return -ENOBUFS; + } + + cp = net_buf_add(buf, sizeof(*cp)); + bt_addr_copy(&cp->bdaddr, bdaddr); + + return bt_hci_cmd_send_sync(BT_HCI_OP_PIN_CODE_NEG_REPLY, buf, NULL); +} + +static int pin_code_reply(struct bt_conn *conn, const char *pin, uint8_t len) +{ + struct bt_hci_cp_pin_code_reply *cp; + struct net_buf *buf; + + BT_DBG(""); + + buf = bt_hci_cmd_create(BT_HCI_OP_PIN_CODE_REPLY, sizeof(*cp)); + if (!buf) { + return -ENOBUFS; + } + + cp = net_buf_add(buf, sizeof(*cp)); + + bt_addr_copy(&cp->bdaddr, &conn->br.dst); + cp->pin_len = len; + strncpy((char *)cp->pin_code, pin, sizeof(cp->pin_code)); + + return bt_hci_cmd_send_sync(BT_HCI_OP_PIN_CODE_REPLY, buf, NULL); +} + +int bt_conn_auth_pincode_entry(struct bt_conn *conn, const char *pin) +{ + size_t len; + + if (!bt_auth) { + return -EINVAL; + } + + if (conn->type != BT_CONN_TYPE_BR) { + return -EINVAL; + } + + len = strlen(pin); + if (len > 16) { + return -EINVAL; + } + + if (conn->required_sec_level == BT_SECURITY_HIGH && len < 16) { + BT_WARN("PIN code for %s is not 16 bytes wide", + bt_addr_str(&conn->br.dst)); + return -EPERM; + } + + /* Allow user send entered PIN to remote, then reset user state. */ + if (!atomic_test_and_clear_bit(conn->flags, BT_CONN_USER)) { + return -EPERM; + } + + if (len == 16) { + atomic_set_bit(conn->flags, BT_CONN_BR_LEGACY_SECURE); + } + + return pin_code_reply(conn, pin, len); +} + +void bt_conn_pin_code_req(struct bt_conn *conn) +{ + if (bt_auth && bt_auth->pincode_entry) { + bool secure = false; + + if (conn->required_sec_level == BT_SECURITY_HIGH) { + secure = true; + } + + atomic_set_bit(conn->flags, BT_CONN_USER); + atomic_set_bit(conn->flags, BT_CONN_BR_PAIRING); + bt_auth->pincode_entry(conn, secure); + } else { + pin_code_neg_reply(&conn->br.dst); + } +} + +uint8_t bt_conn_get_io_capa(void) +{ + if (!bt_auth) { + return BT_IO_NO_INPUT_OUTPUT; + } + + if (bt_auth->passkey_confirm && bt_auth->passkey_display) { + return BT_IO_DISPLAY_YESNO; + } + + if (bt_auth->passkey_entry) { + return BT_IO_KEYBOARD_ONLY; + } + + if (bt_auth->passkey_display) { + return BT_IO_DISPLAY_ONLY; + } + + return BT_IO_NO_INPUT_OUTPUT; +} + +static uint8_t ssp_pair_method(const struct bt_conn *conn) +{ + return ssp_method[conn->br.remote_io_capa][bt_conn_get_io_capa()]; +} + +uint8_t bt_conn_ssp_get_auth(const struct bt_conn *conn) +{ + /* Validate no bond auth request, and if valid use it. */ + if ((conn->br.remote_auth == BT_HCI_NO_BONDING) || + ((conn->br.remote_auth == BT_HCI_NO_BONDING_MITM) && + (ssp_pair_method(conn) > JUST_WORKS))) { + return conn->br.remote_auth; + } + + /* Local & remote have enough IO capabilities to get MITM protection. */ + if (ssp_pair_method(conn) > JUST_WORKS) { + return conn->br.remote_auth | BT_MITM; + } + + /* No MITM protection possible so ignore remote MITM requirement. */ + return (conn->br.remote_auth & ~BT_MITM); +} + +static int ssp_confirm_reply(struct bt_conn *conn) +{ + struct bt_hci_cp_user_confirm_reply *cp; + struct net_buf *buf; + + BT_DBG(""); + + buf = bt_hci_cmd_create(BT_HCI_OP_USER_CONFIRM_REPLY, sizeof(*cp)); + if (!buf) { + return -ENOBUFS; + } + + cp = net_buf_add(buf, sizeof(*cp)); + bt_addr_copy(&cp->bdaddr, &conn->br.dst); + + return bt_hci_cmd_send_sync(BT_HCI_OP_USER_CONFIRM_REPLY, buf, NULL); +} + +static int ssp_confirm_neg_reply(struct bt_conn *conn) +{ + struct bt_hci_cp_user_confirm_reply *cp; + struct net_buf *buf; + + BT_DBG(""); + + buf = bt_hci_cmd_create(BT_HCI_OP_USER_CONFIRM_NEG_REPLY, sizeof(*cp)); + if (!buf) { + return -ENOBUFS; + } + + cp = net_buf_add(buf, sizeof(*cp)); + bt_addr_copy(&cp->bdaddr, &conn->br.dst); + + return bt_hci_cmd_send_sync(BT_HCI_OP_USER_CONFIRM_NEG_REPLY, buf, + NULL); +} + +void bt_conn_ssp_auth(struct bt_conn *conn, uint32_t passkey) +{ + conn->br.pairing_method = ssp_pair_method(conn); + + /* + * If local required security is HIGH then MITM is mandatory. + * MITM protection is no achievable when SSP 'justworks' is applied. + */ + if (conn->required_sec_level > BT_SECURITY_MEDIUM && + conn->br.pairing_method == JUST_WORKS) { + BT_DBG("MITM protection infeasible for required security"); + ssp_confirm_neg_reply(conn); + return; + } + + switch (conn->br.pairing_method) { + case PASSKEY_CONFIRM: + atomic_set_bit(conn->flags, BT_CONN_USER); + bt_auth->passkey_confirm(conn, passkey); + break; + case PASSKEY_DISPLAY: + atomic_set_bit(conn->flags, BT_CONN_USER); + bt_auth->passkey_display(conn, passkey); + break; + case PASSKEY_INPUT: + atomic_set_bit(conn->flags, BT_CONN_USER); + bt_auth->passkey_entry(conn); + break; + case JUST_WORKS: + /* + * When local host works as pairing acceptor and 'justworks' + * model is applied then notify user about such pairing request. + * [BT Core 4.2 table 5.7, Vol 3, Part C, 5.2.2.6] + */ + if (bt_auth && bt_auth->pairing_confirm && + !atomic_test_bit(conn->flags, + BT_CONN_BR_PAIRING_INITIATOR)) { + atomic_set_bit(conn->flags, BT_CONN_USER); + bt_auth->pairing_confirm(conn); + break; + } + ssp_confirm_reply(conn); + break; + default: + break; + } +} + +static int ssp_passkey_reply(struct bt_conn *conn, unsigned int passkey) +{ + struct bt_hci_cp_user_passkey_reply *cp; + struct net_buf *buf; + + BT_DBG(""); + + buf = bt_hci_cmd_create(BT_HCI_OP_USER_PASSKEY_REPLY, sizeof(*cp)); + if (!buf) { + return -ENOBUFS; + } + + cp = net_buf_add(buf, sizeof(*cp)); + bt_addr_copy(&cp->bdaddr, &conn->br.dst); + cp->passkey = sys_cpu_to_le32(passkey); + + return bt_hci_cmd_send_sync(BT_HCI_OP_USER_PASSKEY_REPLY, buf, NULL); +} + +static int ssp_passkey_neg_reply(struct bt_conn *conn) +{ + struct bt_hci_cp_user_passkey_neg_reply *cp; + struct net_buf *buf; + + BT_DBG(""); + + buf = bt_hci_cmd_create(BT_HCI_OP_USER_PASSKEY_NEG_REPLY, sizeof(*cp)); + if (!buf) { + return -ENOBUFS; + } + + cp = net_buf_add(buf, sizeof(*cp)); + bt_addr_copy(&cp->bdaddr, &conn->br.dst); + + return bt_hci_cmd_send_sync(BT_HCI_OP_USER_PASSKEY_NEG_REPLY, buf, + NULL); +} + +static int bt_hci_connect_br_cancel(struct bt_conn *conn) +{ + struct bt_hci_cp_connect_cancel *cp; + struct bt_hci_rp_connect_cancel *rp; + struct net_buf *buf, *rsp; + int err; + + buf = bt_hci_cmd_create(BT_HCI_OP_CONNECT_CANCEL, sizeof(*cp)); + if (!buf) { + return -ENOBUFS; + } + + cp = net_buf_add(buf, sizeof(*cp)); + memcpy(&cp->bdaddr, &conn->br.dst, sizeof(cp->bdaddr)); + + err = bt_hci_cmd_send_sync(BT_HCI_OP_CONNECT_CANCEL, buf, &rsp); + if (err) { + return err; + } + + rp = (void *)rsp->data; + + err = rp->status ? -EIO : 0; + + net_buf_unref(rsp); + + return err; +} + +static int conn_auth(struct bt_conn *conn) +{ + struct bt_hci_cp_auth_requested *auth; + struct net_buf *buf; + + BT_DBG(""); + + buf = bt_hci_cmd_create(BT_HCI_OP_AUTH_REQUESTED, sizeof(*auth)); + if (!buf) { + return -ENOBUFS; + } + + auth = net_buf_add(buf, sizeof(*auth)); + auth->handle = sys_cpu_to_le16(conn->handle); + + atomic_set_bit(conn->flags, BT_CONN_BR_PAIRING_INITIATOR); + + return bt_hci_cmd_send_sync(BT_HCI_OP_AUTH_REQUESTED, buf, NULL); +} +#endif /* CONFIG_BLUETOOTH_BREDR */ + +#if defined(CONFIG_BLUETOOTH_SMP) +void bt_conn_identity_resolved(struct bt_conn *conn) +{ + const bt_addr_le_t *rpa; + struct bt_conn_cb *cb; + + if (conn->role == BT_HCI_ROLE_MASTER) { + rpa = &conn->le.resp_addr; + } else { + rpa = &conn->le.init_addr; + } + + for (cb = callback_list; cb; cb = cb->_next) { + if (cb->identity_resolved) { + cb->identity_resolved(conn, rpa, &conn->le.dst); + } + } +} + +int bt_conn_le_start_encryption(struct bt_conn *conn, uint64_t rand, + uint16_t ediv, const uint8_t *ltk, size_t len) +{ + struct bt_hci_cp_le_start_encryption *cp; + struct net_buf *buf; + + buf = bt_hci_cmd_create(BT_HCI_OP_LE_START_ENCRYPTION, sizeof(*cp)); + if (!buf) { + return -ENOBUFS; + } + + cp = net_buf_add(buf, sizeof(*cp)); + cp->handle = sys_cpu_to_le16(conn->handle); + cp->rand = rand; + cp->ediv = ediv; + + memcpy(cp->ltk, ltk, len); + if (len < sizeof(cp->ltk)) { + memset(cp->ltk + len, 0, sizeof(cp->ltk) - len); + } + + return bt_hci_cmd_send_sync(BT_HCI_OP_LE_START_ENCRYPTION, buf, NULL); +} +#endif /* CONFIG_BLUETOOTH_SMP */ + +#if defined(CONFIG_BLUETOOTH_SMP) || defined(CONFIG_BLUETOOTH_BREDR) +uint8_t bt_conn_enc_key_size(struct bt_conn *conn) +{ + if (!conn->encrypt) { + return 0; + } + + if (IS_ENABLED(CONFIG_BLUETOOTH_BREDR) && + conn->type == BT_CONN_TYPE_BR) { + struct bt_hci_cp_read_encryption_key_size *cp; + struct bt_hci_rp_read_encryption_key_size *rp; + struct net_buf *buf; + struct net_buf *rsp; + uint8_t key_size; + + buf = bt_hci_cmd_create(BT_HCI_OP_READ_ENCRYPTION_KEY_SIZE, + sizeof(*cp)); + if (!buf) { + return 0; + } + + cp = net_buf_add(buf, sizeof(*cp)); + cp->handle = sys_cpu_to_le16(conn->handle); + + if (bt_hci_cmd_send_sync(BT_HCI_OP_READ_ENCRYPTION_KEY_SIZE, + buf, &rsp)) { + return 0; + } + + rp = (void *)rsp->data; + + key_size = rp->status ? 0 : rp->key_size; + + net_buf_unref(rsp); + + return key_size; + } + + if (IS_ENABLED(CONFIG_BLUETOOTH_SMP)) { + return conn->le.keys ? conn->le.keys->enc_size : 0; + } + + return 0; +} + +void bt_conn_security_changed(struct bt_conn *conn) +{ + struct bt_conn_cb *cb; + + for (cb = callback_list; cb; cb = cb->_next) { + if (cb->security_changed) { + cb->security_changed(conn, conn->sec_level); + } + } +} + +static int start_security(struct bt_conn *conn) +{ +#if defined(CONFIG_BLUETOOTH_BREDR) + if (conn->type == BT_CONN_TYPE_BR) { + if (atomic_test_bit(conn->flags, BT_CONN_BR_PAIRING)) { + return -EBUSY; + } + + if (conn->required_sec_level > BT_SECURITY_HIGH) { + return -ENOTSUP; + } + + if (bt_conn_get_io_capa() == BT_IO_NO_INPUT_OUTPUT && + conn->required_sec_level > BT_SECURITY_MEDIUM) { + return -EINVAL; + } + + return conn_auth(conn); + } +#endif /* CONFIG_BLUETOOTH_BREDR */ + + switch (conn->role) { +#if defined(CONFIG_BLUETOOTH_CENTRAL) && defined(CONFIG_BLUETOOTH_SMP) + case BT_HCI_ROLE_MASTER: + { + if (!conn->le.keys) { + conn->le.keys = bt_keys_find(BT_KEYS_LTK_P256, + &conn->le.dst); + if (!conn->le.keys) { + conn->le.keys = bt_keys_find(BT_KEYS_LTK, + &conn->le.dst); + } + } + + if (!conn->le.keys || + !(conn->le.keys->keys & (BT_KEYS_LTK | BT_KEYS_LTK_P256))) { + return bt_smp_send_pairing_req(conn); + } + + if (conn->required_sec_level > BT_SECURITY_MEDIUM && + !atomic_test_bit(conn->le.keys->flags, + BT_KEYS_AUTHENTICATED)) { + return bt_smp_send_pairing_req(conn); + } + + if (conn->required_sec_level > BT_SECURITY_HIGH && + !atomic_test_bit(conn->le.keys->flags, + BT_KEYS_AUTHENTICATED) && + !(conn->le.keys->keys & BT_KEYS_LTK_P256)) { + return bt_smp_send_pairing_req(conn); + } + + /* LE SC LTK and legacy master LTK are stored in same place */ + return bt_conn_le_start_encryption(conn, + conn->le.keys->ltk.rand, + conn->le.keys->ltk.ediv, + conn->le.keys->ltk.val, + conn->le.keys->enc_size); + } +#endif /* CONFIG_BLUETOOTH_CENTRAL && CONFIG_BLUETOOTH_SMP */ +#if defined(CONFIG_BLUETOOTH_PERIPHERAL) && defined(CONFIG_BLUETOOTH_SMP) + case BT_HCI_ROLE_SLAVE: + return bt_smp_send_security_req(conn); +#endif /* CONFIG_BLUETOOTH_PERIPHERAL && CONFIG_BLUETOOTH_SMP */ + default: + return -EINVAL; + } +} + +int bt_conn_security(struct bt_conn *conn, bt_security_t sec) +{ + int err; + + if (conn->state != BT_CONN_CONNECTED) { + return -ENOTCONN; + } + + if (IS_ENABLED(CONFIG_BLUETOOTH_SMP_SC_ONLY) && + sec < BT_SECURITY_FIPS) { + return -EOPNOTSUPP; + } + + /* nothing to do */ + if (conn->sec_level >= sec || conn->required_sec_level >= sec) { + return 0; + } + + conn->required_sec_level = sec; + + err = start_security(conn); + + /* reset required security level in case of error */ + if (err) { + conn->required_sec_level = conn->sec_level; + } + + return err; +} +#endif /* CONFIG_BLUETOOTH_SMP */ + +void bt_conn_cb_register(struct bt_conn_cb *cb) +{ + cb->_next = callback_list; + callback_list = cb; +} + +static void bt_conn_reset_rx_state(struct bt_conn *conn) +{ + if (!conn->rx_len) { + return; + } + + net_buf_unref(conn->rx); + conn->rx = NULL; + conn->rx_len = 0; +} + +void bt_conn_recv(struct bt_conn *conn, struct net_buf *buf, uint8_t flags) +{ + struct bt_l2cap_hdr *hdr; + uint16_t len; + + BT_DBG("handle %u len %u flags %02x", conn->handle, buf->len, flags); + + /* Check packet boundary flags */ + switch (flags) { + case BT_ACL_START: + hdr = (void *)buf->data; + len = sys_le16_to_cpu(hdr->len); + + BT_DBG("First, len %u final %u", buf->len, len); + + if (conn->rx_len) { + BT_ERR("Unexpected first L2CAP frame"); + bt_conn_reset_rx_state(conn); + } + + conn->rx_len = (sizeof(*hdr) + len) - buf->len; + BT_DBG("rx_len %u", conn->rx_len); + if (conn->rx_len) { + conn->rx = buf; + return; + } + + break; + case BT_ACL_CONT: + if (!conn->rx_len) { + BT_ERR("Unexpected L2CAP continuation"); + bt_conn_reset_rx_state(conn); + net_buf_unref(buf); + return; + } + + if (buf->len > conn->rx_len) { + BT_ERR("L2CAP data overflow"); + bt_conn_reset_rx_state(conn); + net_buf_unref(buf); + return; + } + + BT_DBG("Cont, len %u rx_len %u", buf->len, conn->rx_len); + + if (buf->len > net_buf_tailroom(conn->rx)) { + BT_ERR("Not enough buffer space for L2CAP data"); + bt_conn_reset_rx_state(conn); + net_buf_unref(buf); + return; + } + + net_buf_add_mem(conn->rx, buf->data, buf->len); + conn->rx_len -= buf->len; + net_buf_unref(buf); + + if (conn->rx_len) { + return; + } + + buf = conn->rx; + conn->rx = NULL; + conn->rx_len = 0; + + break; + default: + BT_ERR("Unexpected ACL flags (0x%02x)", flags); + bt_conn_reset_rx_state(conn); + net_buf_unref(buf); + return; + } + + hdr = (void *)buf->data; + len = sys_le16_to_cpu(hdr->len); + + if (sizeof(*hdr) + len != buf->len) { + BT_ERR("ACL len mismatch (%u != %u)", len, buf->len); + net_buf_unref(buf); + return; + } + + BT_DBG("Successfully parsed %u byte L2CAP packet", buf->len); + + bt_l2cap_recv(conn, buf); +} + +extern void hci_tx_event_notify(const void* obj); +int bt_conn_send(struct bt_conn *conn, struct net_buf *buf) +{ + BT_DBG("conn handle %u buf len %u", conn->handle, buf->len); + + if (buf->pool->user_data_size < BT_BUF_USER_DATA_MIN) { + BT_ERR("Too small user data size"); + net_buf_unref(buf); + return -EINVAL; + } + + if (conn->state != BT_CONN_CONNECTED) { + BT_ERR("not connected!"); + net_buf_unref(buf); + return -ENOTCONN; + } + + net_buf_put(&conn->tx_queue, buf); + hci_tx_event_notify(&conn->tx_queue); + return 0; +} + +static bool send_frag(struct bt_conn *conn, struct net_buf *buf, uint8_t flags, + bool always_consume) +{ + struct bt_hci_acl_hdr *hdr; + int err; + + BT_DBG("conn %p buf %p len %u flags 0x%02x", conn, buf, buf->len, + flags); + + /* Wait until the controller can accept ACL packets */ + k_sem_take(bt_conn_get_pkts(conn), K_FOREVER); + + /* Check for disconnection while waiting for pkts_sem */ + if (conn->state != BT_CONN_CONNECTED) { + goto fail; + } + + hdr = net_buf_push(buf, sizeof(*hdr)); + hdr->handle = sys_cpu_to_le16(bt_acl_handle_pack(conn->handle, flags)); + hdr->len = sys_cpu_to_le16(buf->len - sizeof(*hdr)); + + bt_buf_set_type(buf, BT_BUF_ACL_OUT); + + err = bt_send(buf); + if (err) { + BT_ERR("Unable to send to driver (err %d)", err); + goto fail; + } + + conn->pending_pkts++; + return true; + +fail: + k_sem_give(bt_conn_get_pkts(conn)); + if (always_consume) { + net_buf_unref(buf); + } + return false; +} + +static inline uint16_t conn_mtu(struct bt_conn *conn) +{ +#if defined(CONFIG_BLUETOOTH_BREDR) + if (conn->type == BT_CONN_TYPE_BR || !bt_dev.le.mtu) { + return bt_dev.br.mtu; + } +#endif /* CONFIG_BLUETOOTH_BREDR */ + + return bt_dev.le.mtu; +} + +static struct net_buf *create_frag(struct bt_conn *conn, struct net_buf *buf) +{ + struct net_buf *frag; + uint16_t frag_len; + + frag = bt_conn_create_pdu(NULL, 0); + + if (conn->state != BT_CONN_CONNECTED) { + net_buf_unref(frag); + return NULL; + } + + frag_len = min(conn_mtu(conn), net_buf_tailroom(frag)); + + net_buf_add_mem(frag, buf->data, frag_len); + net_buf_pull(buf, frag_len); + + return frag; +} + +static bool send_buf(struct bt_conn *conn, struct net_buf *buf) +{ + struct net_buf *frag; + + BT_DBG("conn %p buf %p len %u", conn, buf, buf->len); + + /* Send directly if the packet fits the ACL MTU */ + if (buf->len <= conn_mtu(conn)) { + return send_frag(conn, buf, BT_ACL_START_NO_FLUSH, false); + } + + /* Create & enqueue first fragment */ + frag = create_frag(conn, buf); + if (!frag) { + return false; + } + + if (!send_frag(conn, frag, BT_ACL_START_NO_FLUSH, true)) { + return false; + } + + /* + * Send the fragments. For the last one simply use the original + * buffer (which works since we've used net_buf_pull on it. + */ + while (buf->len > conn_mtu(conn)) { + frag = create_frag(conn, buf); + if (!frag) { + return false; + } + + if (!send_frag(conn, frag, BT_ACL_CONT, true)) { + return false; + } + } + + return send_frag(conn, buf, BT_ACL_CONT, false); +} + +static struct k_poll_signal conn_change = K_POLL_SIGNAL_INITIALIZER(); + +static void conn_cleanup(struct bt_conn *conn) +{ + struct net_buf *buf; + + /* Give back any allocated buffers */ + while ((buf = net_buf_get(&conn->tx_queue, K_NO_WAIT))) { + net_buf_unref(buf); + } + + BT_ASSERT(!conn->pending_pkts); + + bt_conn_reset_rx_state(conn); + + /* Release the reference we took for the very first + * state transition. + */ + bt_conn_unref(conn); +} + +int bt_conn_prepare_events(struct k_poll_event events[]) +{ + int i, ev_count = 0; + + //BT_DBG(""); + + conn_change.signaled = 0; + k_poll_event_init(&events[ev_count++], &conn_change,BT_EVENT_CONN_CHANGE); + + for (i = 0; i < ARRAY_SIZE(conns); i++) { + struct bt_conn *conn = &conns[i]; + + if (!atomic_get(&conn->ref)) { + //continue; + } + + if (conn->state == BT_CONN_DISCONNECTED && + atomic_test_and_clear_bit(conn->flags, BT_CONN_CLEANUP)) { + conn_cleanup(conn); + //continue; + } + + if (conn->state != BT_CONN_CONNECTED) { + //continue; + } + + //BT_DBG("Adding conn %p to poll list", conn); + + k_poll_event_init(&events[ev_count++], + &conn->tx_queue,BT_EVENT_CONN_TX); + } + + return ev_count; +} + +void bt_conn_process_tx(struct bt_conn *conn) +{ + struct net_buf *buf; + + BT_DBG("conn %p", conn); + + if (conn->state == BT_CONN_DISCONNECTED && + atomic_test_and_clear_bit(conn->flags, BT_CONN_CLEANUP)) { + BT_DBG("handle %u disconnected - cleaning up", conn->handle); + conn_cleanup(conn); + return; + } + + /* Get next ACL packet for connection */ + buf = net_buf_get(&conn->tx_queue, K_NO_WAIT); + BT_ASSERT(buf); + if (!send_buf(conn, buf)) { + net_buf_unref(buf); + } +} + +struct bt_conn *bt_conn_add_le(const bt_addr_le_t *peer) +{ + struct bt_conn *conn = conn_new(); + + if (!conn) { + return NULL; + } + + bt_addr_le_copy(&conn->le.dst, peer); +#if defined(CONFIG_BLUETOOTH_SMP) + conn->sec_level = BT_SECURITY_LOW; + conn->required_sec_level = BT_SECURITY_LOW; +#endif /* CONFIG_BLUETOOTH_SMP */ + conn->type = BT_CONN_TYPE_LE; + conn->le.interval_min = BT_GAP_INIT_CONN_INT_MIN; + conn->le.interval_max = BT_GAP_INIT_CONN_INT_MAX; + k_delayed_work_init(&conn->le.update_work, le_conn_update); + + return conn; +} + +void bt_conn_set_state(struct bt_conn *conn, bt_conn_state_t state) +{ + bt_conn_state_t old_state; + + BT_DBG("%s -> %s", state2str(conn->state), state2str(state)); + + if (conn->state == state) { + BT_WARN("no transition"); + return; + } + + old_state = conn->state; + conn->state = state; + + /* Actions needed for exiting the old state */ + switch (old_state) { + case BT_CONN_DISCONNECTED: + /* Take a reference for the first state transition after + * bt_conn_add_le() and keep it until reaching DISCONNECTED + * again. + */ + bt_conn_ref(conn); + break; + case BT_CONN_CONNECT: + if (IS_ENABLED(CONFIG_BLUETOOTH_CENTRAL) && + conn->type == BT_CONN_TYPE_LE) { + k_delayed_work_cancel(&conn->le.update_work); + } + break; + default: + break; + } + + /* Actions needed for entering the new state */ + switch (conn->state) { + case BT_CONN_CONNECTED: + k_fifo_init(&conn->tx_queue,"conn tx",NULL,CONFIG_BLUETOOTH_RX_BUF_COUNT); + hci_tx_event_notify(&conn_change); + + bt_l2cap_connected(conn); + notify_connected(conn); + break; + case BT_CONN_DISCONNECTED: + /* Notify disconnection and queue a dummy buffer to wake + * up and stop the tx thread for states where it was + * running. + */ + if (old_state == BT_CONN_CONNECTED || + old_state == BT_CONN_DISCONNECT) { + bt_l2cap_disconnected(conn); + notify_disconnected(conn); + + /* Return any unacknowledged packets */ + while (conn->pending_pkts) { + k_sem_give(bt_conn_get_pkts(conn)); + conn->pending_pkts--; + } + + /* Cancel Connection Update if it is pending */ + if (conn->type == BT_CONN_TYPE_LE) { + k_delayed_work_cancel(&conn->le.update_work); + } + + atomic_set_bit(conn->flags, BT_CONN_CLEANUP); + hci_tx_event_notify(&conn_change); + /* The last ref will be dropped by the tx_thread */ + } else if (old_state == BT_CONN_CONNECT) { + /* conn->err will be set in this case */ + notify_connected(conn); + bt_conn_unref(conn); + } else if (old_state == BT_CONN_CONNECT_SCAN) { + /* this indicate LE Create Connection failed */ + if (conn->err) { + notify_connected(conn); + } + + bt_conn_unref(conn); + } + + break; + case BT_CONN_CONNECT_SCAN: + break; + case BT_CONN_CONNECT: + /* + * Timer is needed only for LE. For other link types controller + * will handle connection timeout. + */ + if (IS_ENABLED(CONFIG_BLUETOOTH_CENTRAL) && + conn->type == BT_CONN_TYPE_LE) { + k_delayed_work_submit(&conn->le.update_work, + CONN_TIMEOUT); + } + + break; + case BT_CONN_DISCONNECT: + break; + default: + BT_WARN("no valid (%u) state was set", state); + + break; + } +} + +struct bt_conn *bt_conn_lookup_handle(uint16_t handle) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(conns); i++) { + if (!atomic_get(&conns[i].ref)) { + continue; + } + + /* We only care about connections with a valid handle */ + if (conns[i].state != BT_CONN_CONNECTED && + conns[i].state != BT_CONN_DISCONNECT) { + continue; + } + + if (conns[i].handle == handle) { + return bt_conn_ref(&conns[i]); + } + } + + return NULL; +} + +int bt_conn_addr_le_cmp(const struct bt_conn *conn, const bt_addr_le_t *peer) +{ + /* Check against conn dst address as it may be the identity address */ + if (!bt_addr_le_cmp(peer, &conn->le.dst)) { + return 0; + } + + /* Check against initial connection address */ + if (conn->role == BT_HCI_ROLE_MASTER) { + return bt_addr_le_cmp(peer, &conn->le.resp_addr); + } + + return bt_addr_le_cmp(peer, &conn->le.init_addr); +} + +struct bt_conn *bt_conn_lookup_addr_le(const bt_addr_le_t *peer) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(conns); i++) { + if (!atomic_get(&conns[i].ref)) { + continue; + } + + if (conns[i].type != BT_CONN_TYPE_LE) { + continue; + } + + if (!bt_conn_addr_le_cmp(&conns[i], peer)) { + return bt_conn_ref(&conns[i]); + } + } + + return NULL; +} + +struct bt_conn *bt_conn_lookup_state_le(const bt_addr_le_t *peer, + const bt_conn_state_t state) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(conns); i++) { + if (!atomic_get(&conns[i].ref)) { + continue; + } + + if (conns[i].type != BT_CONN_TYPE_LE) { + continue; + } + + if (peer && bt_conn_addr_le_cmp(&conns[i], peer)) { + continue; + } + + if (conns[i].state == state) { + return bt_conn_ref(&conns[i]); + } + } + + return NULL; +} + +void bt_conn_disconnect_all(void) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(conns); i++) { + struct bt_conn *conn = &conns[i]; + + if (!atomic_get(&conn->ref)) { + continue; + } + + if (conn->state == BT_CONN_CONNECTED) { + bt_conn_disconnect(conn, + BT_HCI_ERR_REMOTE_USER_TERM_CONN); + } + } +} + +struct bt_conn *bt_conn_ref(struct bt_conn *conn) +{ + atomic_inc(&conn->ref); + + BT_DBG("handle %u ref %u", conn->handle, atomic_get(&conn->ref)); + + return conn; +} + +void bt_conn_unref(struct bt_conn *conn) +{ + atomic_dec(&conn->ref); + + BT_DBG("handle %u ref %u", conn->handle, atomic_get(&conn->ref)); +} + +const bt_addr_le_t *bt_conn_get_dst(const struct bt_conn *conn) +{ + return &conn->le.dst; +} + +int bt_conn_get_info(const struct bt_conn *conn, struct bt_conn_info *info) +{ + info->type = conn->type; + info->role = conn->role; + + switch (conn->type) { + case BT_CONN_TYPE_LE: + if (conn->role == BT_HCI_ROLE_MASTER) { + info->le.src = &conn->le.init_addr; + info->le.dst = &conn->le.resp_addr; + } else { + info->le.src = &conn->le.resp_addr; + info->le.dst = &conn->le.init_addr; + } + info->le.interval = conn->le.interval; + info->le.latency = conn->le.latency; + info->le.timeout = conn->le.timeout; + return 0; +#if defined(CONFIG_BLUETOOTH_BREDR) + case BT_CONN_TYPE_BR: + info->br.dst = &conn->br.dst; + return 0; +#endif + } + + return -EINVAL; +} + +static int bt_hci_disconnect(struct bt_conn *conn, uint8_t reason) +{ + struct net_buf *buf; + struct bt_hci_cp_disconnect *disconn; + int err; + + buf = bt_hci_cmd_create(BT_HCI_OP_DISCONNECT, sizeof(*disconn)); + if (!buf) { + return -ENOBUFS; + } + + disconn = net_buf_add(buf, sizeof(*disconn)); + disconn->handle = sys_cpu_to_le16(conn->handle); + disconn->reason = reason; + + err = bt_hci_cmd_send(BT_HCI_OP_DISCONNECT, buf); + if (err) { + return err; + } + + bt_conn_set_state(conn, BT_CONN_DISCONNECT); + + return 0; +} + +int bt_conn_le_param_update(struct bt_conn *conn, + const struct bt_le_conn_param *param) +{ + BT_DBG("conn %p features 0x%02x params (%d-%d %d %d)", conn, + conn->le.features[0][0], param->interval_min, + param->interval_max, param->latency, param->timeout); + + /* Check if there's a need to update conn params */ + if (conn->le.interval >= param->interval_min && + conn->le.interval <= param->interval_max) { + return -EALREADY; + } + + /* Cancel any pending update */ + k_delayed_work_cancel(&conn->le.update_work); + + /* + * If remote does not support LL Connection Parameters Request + * Procedure + */ + if ((conn->role == BT_HCI_ROLE_SLAVE) && + !BT_FEAT_LE_CONN_PARAM_REQ_PROC(conn->le.features)) { + return bt_l2cap_update_conn_param(conn, param); + } + + if (BT_FEAT_LE_CONN_PARAM_REQ_PROC(conn->le.features) && + BT_FEAT_LE_CONN_PARAM_REQ_PROC(bt_dev.le.features)) { + return bt_conn_le_conn_update(conn, param); + } + + return -EBUSY; +} + +int bt_conn_disconnect(struct bt_conn *conn, uint8_t reason) +{ + /* Disconnection is initiated by us, so auto connection shall + * be disabled. Otherwise the passive scan would be enabled + * and we could send LE Create Connection as soon as the remote + * starts advertising. + */ + if (IS_ENABLED(CONFIG_BLUETOOTH_CENTRAL) && + conn->type == BT_CONN_TYPE_LE) { + bt_le_set_auto_conn(&conn->le.dst, NULL); + } + + switch (conn->state) { + case BT_CONN_CONNECT_SCAN: + bt_conn_set_state(conn, BT_CONN_DISCONNECTED); + bt_le_scan_update(false); + return 0; + case BT_CONN_CONNECT: +#if defined(CONFIG_BLUETOOTH_BREDR) + if (conn->type == BT_CONN_TYPE_BR) { + return bt_hci_connect_br_cancel(conn); + } +#endif /* CONFIG_BLUETOOTH_BREDR */ + + if (IS_ENABLED(CONFIG_BLUETOOTH_CENTRAL)) { + k_delayed_work_cancel(&conn->le.update_work); + return bt_hci_cmd_send(BT_HCI_OP_LE_CREATE_CONN_CANCEL, + NULL); + } + + return 0; + case BT_CONN_CONNECTED: + return bt_hci_disconnect(conn, reason); + case BT_CONN_DISCONNECT: + return 0; + case BT_CONN_DISCONNECTED: + default: + return -ENOTCONN; + } +} + +#if defined(CONFIG_BLUETOOTH_CENTRAL) +static void bt_conn_set_param_le(struct bt_conn *conn, + const struct bt_le_conn_param *param) +{ + conn->le.interval_max = param->interval_max; + conn->le.latency = param->latency; + conn->le.timeout = param->timeout; +} + +struct bt_conn *bt_conn_create_le(const bt_addr_le_t *peer, + const struct bt_le_conn_param *param) +{ + struct bt_conn *conn; + + if (!bt_le_conn_params_valid(param)) { + return NULL; + } + + if (atomic_test_bit(bt_dev.flags, BT_DEV_EXPLICIT_SCAN)) { + return NULL; + } + + conn = bt_conn_lookup_addr_le(peer); + if (conn) { + switch (conn->state) { + case BT_CONN_CONNECT_SCAN: + bt_conn_set_param_le(conn, param); + return conn; + case BT_CONN_CONNECT: + case BT_CONN_CONNECTED: + return conn; + default: + bt_conn_unref(conn); + return NULL; + } + } + + conn = bt_conn_add_le(peer); + if (!conn) { + return NULL; + } + + bt_conn_set_param_le(conn, param); + + bt_conn_set_state(conn, BT_CONN_CONNECT_SCAN); + + bt_le_scan_update(true); + + return conn; +} + +int bt_le_set_auto_conn(bt_addr_le_t *addr, + const struct bt_le_conn_param *param) +{ + struct bt_conn *conn; + + if (param && !bt_le_conn_params_valid(param)) { + return -EINVAL; + } + + conn = bt_conn_lookup_addr_le(addr); + if (!conn) { + conn = bt_conn_add_le(addr); + if (!conn) { + return -ENOMEM; + } + } + + if (param) { + bt_conn_set_param_le(conn, param); + + if (!atomic_test_and_set_bit(conn->flags, + BT_CONN_AUTO_CONNECT)) { + bt_conn_ref(conn); + } + } else { + if (atomic_test_and_clear_bit(conn->flags, + BT_CONN_AUTO_CONNECT)) { + bt_conn_unref(conn); + if (conn->state == BT_CONN_CONNECT_SCAN) { + bt_conn_set_state(conn, BT_CONN_DISCONNECTED); + } + } + } + + if (conn->state == BT_CONN_DISCONNECTED && + atomic_test_bit(bt_dev.flags, BT_DEV_READY)) { + if (param) { + bt_conn_set_state(conn, BT_CONN_CONNECT_SCAN); + } + bt_le_scan_update(false); + } + + bt_conn_unref(conn); + + return 0; +} +#endif /* CONFIG_BLUETOOTH_CENTRAL */ + +#if defined(CONFIG_BLUETOOTH_PERIPHERAL) +struct bt_conn *bt_conn_create_slave_le(const bt_addr_le_t *peer, + const struct bt_le_adv_param *param) +{ + return NULL; +} +#endif /* CONFIG_BLUETOOTH_PERIPHERAL */ + +int bt_conn_le_conn_update(struct bt_conn *conn, + const struct bt_le_conn_param *param) +{ + struct hci_cp_le_conn_update *conn_update; + struct net_buf *buf; + + buf = bt_hci_cmd_create(BT_HCI_OP_LE_CONN_UPDATE, + sizeof(*conn_update)); + if (!buf) { + return -ENOBUFS; + } + + conn_update = net_buf_add(buf, sizeof(*conn_update)); + memset(conn_update, 0, sizeof(*conn_update)); + conn_update->handle = sys_cpu_to_le16(conn->handle); + conn_update->conn_interval_min = sys_cpu_to_le16(param->interval_min); + conn_update->conn_interval_max = sys_cpu_to_le16(param->interval_max); + conn_update->conn_latency = sys_cpu_to_le16(param->latency); + conn_update->supervision_timeout = sys_cpu_to_le16(param->timeout); + + return bt_hci_cmd_send(BT_HCI_OP_LE_CONN_UPDATE, buf); +} + +struct net_buf *bt_conn_create_pdu(struct net_buf_pool *pool, size_t reserve) +{ + struct net_buf *buf; + + if (!pool) { + pool = &acl_tx_pool; + } + + buf = net_buf_alloc(pool, K_FOREVER); + __ASSERT_NO_MSG(buf); + + reserve += sizeof(struct bt_hci_acl_hdr) + CONFIG_BLUETOOTH_HCI_RESERVE; + net_buf_reserve(buf, reserve); + + return buf; +} + +#if defined(CONFIG_BLUETOOTH_SMP) || defined(CONFIG_BLUETOOTH_BREDR) +int bt_conn_auth_cb_register(const struct bt_conn_auth_cb *cb) +{ + if (!cb) { + bt_auth = NULL; + return 0; + } + + /* cancel callback should always be provided */ + if (!cb->cancel) { + return -EINVAL; + } + + if (bt_auth) { + return -EALREADY; + } + + bt_auth = cb; + return 0; +} + +int bt_conn_auth_passkey_entry(struct bt_conn *conn, unsigned int passkey) +{ + if (!bt_auth) { + return -EINVAL; + } + + if (IS_ENABLED(CONFIG_BLUETOOTH_SMP) && + conn->type == BT_CONN_TYPE_LE) { + bt_smp_auth_passkey_entry(conn, passkey); + return 0; + } + +#if defined(CONFIG_BLUETOOTH_BREDR) + if (conn->type == BT_CONN_TYPE_BR) { + /* User entered passkey, reset user state. */ + if (!atomic_test_and_clear_bit(conn->flags, BT_CONN_USER)) { + return -EPERM; + } + + if (conn->br.pairing_method == PASSKEY_INPUT) { + return ssp_passkey_reply(conn, passkey); + } + } +#endif /* CONFIG_BLUETOOTH_BREDR */ + + return -EINVAL; +} + +int bt_conn_auth_passkey_confirm(struct bt_conn *conn) +{ + if (!bt_auth) { + return -EINVAL; + } + + if (IS_ENABLED(CONFIG_BLUETOOTH_SMP) && + conn->type == BT_CONN_TYPE_LE) { + return bt_smp_auth_passkey_confirm(conn); + } + +#if defined(CONFIG_BLUETOOTH_BREDR) + if (conn->type == BT_CONN_TYPE_BR) { + /* Allow user confirm passkey value, then reset user state. */ + if (!atomic_test_and_clear_bit(conn->flags, BT_CONN_USER)) { + return -EPERM; + } + + return ssp_confirm_reply(conn); + } +#endif /* CONFIG_BLUETOOTH_BREDR */ + + return -EINVAL; +} + +int bt_conn_auth_cancel(struct bt_conn *conn) +{ + if (!bt_auth) { + return -EINVAL; + } + + if (IS_ENABLED(CONFIG_BLUETOOTH_SMP) && + conn->type == BT_CONN_TYPE_LE) { + return bt_smp_auth_cancel(conn); + } + +#if defined(CONFIG_BLUETOOTH_BREDR) + if (conn->type == BT_CONN_TYPE_BR) { + /* Allow user cancel authentication, then reset user state. */ + if (!atomic_test_and_clear_bit(conn->flags, BT_CONN_USER)) { + return -EPERM; + } + + switch (conn->br.pairing_method) { + case JUST_WORKS: + case PASSKEY_CONFIRM: + return ssp_confirm_neg_reply(conn); + case PASSKEY_INPUT: + return ssp_passkey_neg_reply(conn); + case PASSKEY_DISPLAY: + return bt_conn_disconnect(conn, + BT_HCI_ERR_AUTHENTICATION_FAIL); + case LEGACY: + return pin_code_neg_reply(&conn->br.dst); + default: + break; + } + } +#endif /* CONFIG_BLUETOOTH_BREDR */ + + return -EINVAL; +} + +int bt_conn_auth_pairing_confirm(struct bt_conn *conn) +{ + if (!bt_auth) { + return -EINVAL; + } + + switch (conn->type) { +#if defined(CONFIG_BLUETOOTH_SMP) + case BT_CONN_TYPE_LE: + return bt_smp_auth_pairing_confirm(conn); +#endif /* CONFIG_BLUETOOTH_SMP */ +#if defined(CONFIG_BLUETOOTH_BREDR) + case BT_CONN_TYPE_BR: + return ssp_confirm_reply(conn); +#endif /* CONFIG_BLUETOOTH_BREDR */ + default: + return -EINVAL; + } +} +#endif /* CONFIG_BLUETOOTH_SMP || CONFIG_BLUETOOTH_BREDR */ + +int bt_conn_init(void) +{ + int err; + + NET_BUF_POOL_INIT(acl_tx_pool); + + bt_att_init(); + + err = bt_smp_init(); + if (err) { + return err; + } + + bt_l2cap_init(); + + /* Initialize background scan */ + if (IS_ENABLED(CONFIG_BLUETOOTH_CENTRAL)) { + int i; + + for (i = 0; i < ARRAY_SIZE(conns); i++) { + struct bt_conn *conn = &conns[i]; + + if (!atomic_get(&conn->ref)) { + continue; + } + + if (atomic_test_bit(conn->flags, + BT_CONN_AUTO_CONNECT)) { + bt_conn_set_state(conn, BT_CONN_CONNECT_SCAN); + } + } + } + + return 0; +} diff --git a/kernel/protocols/bluetooth/host/conn_internal.h b/kernel/protocols/bluetooth/host/conn_internal.h new file mode 100644 index 0000000000..74fccddc73 --- /dev/null +++ b/kernel/protocols/bluetooth/host/conn_internal.h @@ -0,0 +1,196 @@ +/** @file + * @brief Internal APIs for Bluetooth connection handling. + */ + +/* + * Copyright (c) 2015 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +typedef enum __packed { + BT_CONN_DISCONNECTED, + BT_CONN_CONNECT_SCAN, + BT_CONN_CONNECT, + BT_CONN_CONNECTED, + BT_CONN_DISCONNECT, +} bt_conn_state_t; + +/* bt_conn flags: the flags defined here represent connection parameters */ +enum { + BT_CONN_AUTO_CONNECT, + BT_CONN_BR_LEGACY_SECURE, /* 16 digits legacy PIN tracker */ + BT_CONN_USER, /* user I/O when pairing */ + BT_CONN_BR_PAIRING, /* BR connection in pairing context */ + BT_CONN_BR_NOBOND, /* SSP no bond pairing tracker */ + BT_CONN_BR_PAIRING_INITIATOR, /* local host starts authentication */ + BT_CONN_CLEANUP, /* Disconnected, pending cleanup */ + + /* Total number of flags - must be at the end of the enum */ + BT_CONN_NUM_FLAGS, +}; + +struct bt_conn_le { + bt_addr_le_t dst; + + bt_addr_le_t init_addr; + bt_addr_le_t resp_addr; + + uint16_t interval; + uint16_t interval_min; + uint16_t interval_max; + + uint16_t latency; + uint16_t timeout; + + uint8_t features[1][8]; + + struct bt_keys *keys; + + /* Delayed work for connection update and timeout handling */ + struct k_delayed_work update_work; +}; + +#if defined(CONFIG_BLUETOOTH_BREDR) +/* For now reserve space for 2 pages of LMP remote features */ +#define LMP_MAX_PAGES 2 + +struct bt_conn_br { + bt_addr_t dst; + uint8_t remote_io_capa; + uint8_t remote_auth; + uint8_t pairing_method; + /* remote LMP features pages per 8 bytes each */ + uint8_t features[LMP_MAX_PAGES][8]; + + struct bt_keys_link_key *link_key; +}; + +struct bt_conn_sco { + /* Reference to ACL Connection */ + struct bt_conn *conn; + uint16_t pkt_type; +}; +#endif + +struct bt_conn { + uint16_t handle; + uint8_t type; + uint8_t role; + + ATOMIC_DEFINE(flags, BT_CONN_NUM_FLAGS); + +#if defined(CONFIG_BLUETOOTH_SMP) || defined(CONFIG_BLUETOOTH_BREDR) + bt_security_t sec_level; + bt_security_t required_sec_level; + uint8_t encrypt; +#endif /* CONFIG_BLUETOOTH_SMP || CONFIG_BLUETOOTH_BREDR */ + + uint8_t pending_pkts; + + uint16_t rx_len; + struct net_buf *rx; + + /* Queue for outgoing ACL data */ + struct k_fifo tx_queue; + + /* L2CAP channels */ + void *channels; + + atomic_t ref; + + /* Connection error or reason for disconnect */ + uint8_t err; + + bt_conn_state_t state; + + union { + struct bt_conn_le le; +#if defined(CONFIG_BLUETOOTH_BREDR) + struct bt_conn_br br; + struct bt_conn_sco sco; +#endif + }; +}; + +/* Process incoming data for a connection */ +void bt_conn_recv(struct bt_conn *conn, struct net_buf *buf, uint8_t flags); + +/* Send data over a connection */ +int bt_conn_send(struct bt_conn *conn, struct net_buf *buf); + +/* Add a new LE connection */ +struct bt_conn *bt_conn_add_le(const bt_addr_le_t *peer); + +/* Add a new BR/EDR connection */ +struct bt_conn *bt_conn_add_br(const bt_addr_t *peer); + +/* Add a new SCO connection */ +struct bt_conn *bt_conn_add_sco(const bt_addr_t *peer, int link_type); + +/* Look up an existing connection by BT address */ +struct bt_conn *bt_conn_lookup_addr_br(const bt_addr_t *peer); + +void bt_conn_pin_code_req(struct bt_conn *conn); +uint8_t bt_conn_get_io_capa(void); +uint8_t bt_conn_ssp_get_auth(const struct bt_conn *conn); +void bt_conn_ssp_auth(struct bt_conn *conn, uint32_t passkey); + +void bt_conn_disconnect_all(void); + +/* Look up an existing connection */ +struct bt_conn *bt_conn_lookup_handle(uint16_t handle); + +/* Compare an address with bt_conn destination address */ +int bt_conn_addr_le_cmp(const struct bt_conn *conn, const bt_addr_le_t *peer); + +/* Look up a connection state. For BT_ADDR_LE_ANY, returns the first connection + * with the specific state + */ +struct bt_conn *bt_conn_lookup_state_le(const bt_addr_le_t *peer, + const bt_conn_state_t state); + +/* Set connection object in certain state and perform action related to state */ +void bt_conn_set_state(struct bt_conn *conn, bt_conn_state_t state); + +int bt_conn_le_conn_update(struct bt_conn *conn, + const struct bt_le_conn_param *param); + +void notify_le_param_updated(struct bt_conn *conn); + +bool le_param_req(struct bt_conn *conn, struct bt_le_conn_param *param); + +#if defined(CONFIG_BLUETOOTH_SMP) +/* rand and ediv should be in BT order */ +int bt_conn_le_start_encryption(struct bt_conn *conn, uint64_t rand, + uint16_t ediv, const uint8_t *ltk, size_t len); + +/* Notify higher layers that RPA was resolved */ +void bt_conn_identity_resolved(struct bt_conn *conn); +#endif /* CONFIG_BLUETOOTH_SMP */ + +#if defined(CONFIG_BLUETOOTH_SMP) || defined(CONFIG_BLUETOOTH_BREDR) +/* Notify higher layers that connection security changed */ +void bt_conn_security_changed(struct bt_conn *conn); +#endif /* CONFIG_BLUETOOTH_SMP || CONFIG_BLUETOOTH_BREDR */ + +/* Prepare a PDU to be sent over a connection */ +struct net_buf *bt_conn_create_pdu(struct net_buf_pool *pool, size_t reserve); + +/* Initialize connection management */ +int bt_conn_init(void); + +/* Selects based on connecton type right semaphore for ACL packets */ +static inline struct k_sem *bt_conn_get_pkts(struct bt_conn *conn) +{ +#if defined(CONFIG_BLUETOOTH_BREDR) + if (conn->type == BT_CONN_TYPE_BR || !bt_dev.le.mtu) { + return &bt_dev.br.pkts; + } +#endif /* CONFIG_BLUETOOTH_BREDR */ + + return &bt_dev.le.pkts; +} + +/* k_poll related helpers for the TX thread */ +int bt_conn_prepare_events(struct k_poll_event events[]); +void bt_conn_process_tx(struct bt_conn *conn); diff --git a/kernel/protocols/bluetooth/host/ecc.h b/kernel/protocols/bluetooth/host/ecc.h new file mode 100644 index 0000000000..418f0361b4 --- /dev/null +++ b/kernel/protocols/bluetooth/host/ecc.h @@ -0,0 +1,63 @@ +/* ecc.h - ECDH helpers */ + +/* + * Copyright (c) 2016 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* @brief Container for public key callback */ +struct bt_pub_key_cb { + /** @brief Callback type for Public Key generation. + * + * Used to notify of the local public key or that the local key is not + * available (either because of a failure to read it or because it is + * being regenerated). + * + * @param key The local public key, or NULL in case of no key. + */ + void (*func)(const uint8_t key[64]); + + struct bt_pub_key_cb *_next; +}; + +/* @brief Generate a new Public Key. + * + * Generate a new ECC Public Key. The callback will persist even after the + * key has been generated, and will be used to notify of new generation + * processes (NULL as key). + * + * @param cb Callback to notify the new key, or NULL to request an update + * without registering any new callback. + * + * @return Zero on success or negative error code otherwise + */ +int bt_pub_key_gen(struct bt_pub_key_cb *cb); + +/* @brief Get the current Public Key. + * + * Get the current ECC Public Key. + * + * @return Current key, or NULL if not available. + */ +const uint8_t *bt_pub_key_get(void); + +/* @typedef bt_dh_key_cb_t + * @brief Callback type for DH Key calculation. + * + * Used to notify of the calculated DH Key. + * + * @param key The DH Key, or NULL in case of failure. + */ +typedef void (*bt_dh_key_cb_t)(const uint8_t key[32]); + +/* @brief Calculate a DH Key from a remote Public Key. + * + * Calculate a DH Key from the remote Public Key. + * + * @param remote_pk Remote Public Key. + * @param cb Callback to notify the calculated key. + * + * @return Zero on success or negative error code otherwise + */ +int bt_dh_key_gen(const uint8_t remote_pk[64], bt_dh_key_cb_t cb); diff --git a/kernel/protocols/bluetooth/host/gatt.c b/kernel/protocols/bluetooth/host/gatt.c new file mode 100644 index 0000000000..636a32d889 --- /dev/null +++ b/kernel/protocols/bluetooth/host/gatt.c @@ -0,0 +1,1827 @@ +/* gatt.c - Generic Attribute Profile handling */ + +/* + * Copyright (c) 2015-2016 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_GATT) +#include +#include +#include +#include +#include +#include + +#include "hci_core.h" +#include "conn_internal.h" +#include "keys.h" +#include "l2cap_internal.h" +#include "att_internal.h" +#include "smp.h" +#include "gatt_internal.h" + +static struct bt_gatt_attr *db; + +#if defined(CONFIG_BLUETOOTH_GATT_CLIENT) +static sys_slist_t subscriptions; +#endif /* CONFIG_BLUETOOTH_GATT_CLIENT */ + +#if !defined(CONFIG_BLUETOOTH_GATT_DYNAMIC_DB) +static size_t attr_count; +#endif /* CONFIG_BLUETOOTH_GATT_DYNAMIC_DB */ + +int bt_gatt_register(struct bt_gatt_attr *attrs, size_t count) +{ +#if defined(CONFIG_BLUETOOTH_GATT_DYNAMIC_DB) + struct bt_gatt_attr *last; +#endif /* CONFIG_BLUETOOTH_GATT_DYNAMIC_DB */ + uint16_t handle; + + __ASSERT(attrs, "invalid parameters\n"); + __ASSERT(count, "invalid parameters\n"); + +#if !defined(CONFIG_BLUETOOTH_GATT_DYNAMIC_DB) + handle = 0; + db = attrs; + attr_count = count; +#else + if (!db) { + db = attrs; + last = NULL; + handle = 0; + goto populate; + } + + /* Fast forward to last attribute in the list */ + for (last = db; last->_next;) { + last = last->_next; + } + + handle = last->handle; + last->_next = attrs; + +populate: +#endif /* CONFIG_BLUETOOTH_GATT_DYNAMIC_DB */ + /* Populate the handles and _next pointers */ + for (; attrs && count; attrs++, count--) { + if (!attrs->handle) { + /* Allocate handle if not set already */ + attrs->handle = ++handle; + } else if (attrs->handle > handle) { + /* Use existing handle if valid */ + handle = attrs->handle; + } else { + /* Service has conflicting handles */ +#if defined(CONFIG_BLUETOOTH_GATT_DYNAMIC_DB) + last->_next = NULL; +#endif + BT_ERR("Unable to register handle 0x%04x", + attrs->handle); + return -EINVAL; + } + +#if defined(CONFIG_BLUETOOTH_GATT_DYNAMIC_DB) + if (count > 1) { + attrs->_next = &attrs[1]; + } +#endif + + BT_DBG("attr %p next %p handle 0x%04x uuid %s perm 0x%02x", + attrs, bt_gatt_attr_next(attrs), attrs->handle, + bt_uuid_str(attrs->uuid), attrs->perm); + } + + return 0; +} + +ssize_t bt_gatt_attr_read(struct bt_conn *conn, const struct bt_gatt_attr *attr, + void *buf, uint16_t buf_len, uint16_t offset, + const void *value, uint16_t value_len) +{ + uint16_t len; + + if (offset > value_len) { + return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET); + } + + len = min(buf_len, value_len - offset); + + BT_DBG("handle 0x%04x offset %u length %u", attr->handle, offset, + len); + + memcpy(buf, value + offset, len); + + return len; +} + +ssize_t bt_gatt_attr_read_service(struct bt_conn *conn, + const struct bt_gatt_attr *attr, + void *buf, uint16_t len, uint16_t offset) +{ + struct bt_uuid *uuid = attr->user_data; + + if (uuid->type == BT_UUID_TYPE_16) { + uint16_t uuid16 = sys_cpu_to_le16(BT_UUID_16(uuid)->val); + + return bt_gatt_attr_read(conn, attr, buf, len, offset, + &uuid16, 2); + } + + return bt_gatt_attr_read(conn, attr, buf, len, offset, + BT_UUID_128(uuid)->val, 16); +} + +struct gatt_incl { + uint16_t start_handle; + uint16_t end_handle; + uint16_t uuid16; +} __packed; + +static uint8_t get_service_handles(const struct bt_gatt_attr *attr, + void *user_data) +{ + struct gatt_incl *include = user_data; + + /* Stop if attribute is a service */ + if (!bt_uuid_cmp(attr->uuid, BT_UUID_GATT_PRIMARY) || + !bt_uuid_cmp(attr->uuid, BT_UUID_GATT_SECONDARY)) { + return BT_GATT_ITER_STOP; + } + + include->end_handle = attr->handle; + + return BT_GATT_ITER_CONTINUE; +} + +ssize_t bt_gatt_attr_read_included(struct bt_conn *conn, + const struct bt_gatt_attr *attr, + void *buf, uint16_t len, uint16_t offset) +{ + struct bt_gatt_attr *incl = attr->user_data; + struct bt_uuid *uuid = incl->user_data; + struct gatt_incl pdu; + uint8_t value_len; + + /* first attr points to the start handle */ + pdu.start_handle = sys_cpu_to_le16(incl->handle); + value_len = sizeof(pdu.start_handle) + sizeof(pdu.end_handle); + + /* + * Core 4.2, Vol 3, Part G, 3.2, + * The Service UUID shall only be present when the UUID is a + * 16-bit Bluetooth UUID. + */ + if (uuid->type == BT_UUID_TYPE_16) { + pdu.uuid16 = sys_cpu_to_le16(BT_UUID_16(uuid)->val); + value_len += sizeof(pdu.uuid16); + } + + /* Lookup for service end handle */ + bt_gatt_foreach_attr(incl->handle + 1, 0xffff, get_service_handles, + &pdu); + + return bt_gatt_attr_read(conn, attr, buf, len, offset, &pdu, value_len); +} + +struct gatt_chrc { + uint8_t properties; + uint16_t value_handle; + union { + uint16_t uuid16; + uint8_t uuid[16]; + }; +} __packed; + +ssize_t bt_gatt_attr_read_chrc(struct bt_conn *conn, + const struct bt_gatt_attr *attr, void *buf, + uint16_t len, uint16_t offset) +{ + struct bt_gatt_chrc *chrc = attr->user_data; + struct gatt_chrc pdu; + const struct bt_gatt_attr *next; + uint8_t value_len; + + pdu.properties = chrc->properties; + /* BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part G] page 534: + * 3.3.2 Characteristic Value Declaration + * The Characteristic Value declaration contains the value of the + * characteristic. It is the first Attribute after the characteristic + * declaration. All characteristic definitions shall have a + * Characteristic Value declaration. + */ + next = bt_gatt_attr_next(attr); + if (!next) { + BT_WARN("No value for characteristic at 0x%04x", attr->handle); + pdu.value_handle = 0x0000; + } else { + pdu.value_handle = sys_cpu_to_le16(next->handle); + } + value_len = sizeof(pdu.properties) + sizeof(pdu.value_handle); + + if (chrc->uuid->type == BT_UUID_TYPE_16) { + pdu.uuid16 = sys_cpu_to_le16(BT_UUID_16(chrc->uuid)->val); + value_len += 2; + } else { + memcpy(pdu.uuid, BT_UUID_128(chrc->uuid)->val, 16); + value_len += 16; + } + + return bt_gatt_attr_read(conn, attr, buf, len, offset, &pdu, value_len); +} + +void bt_gatt_foreach_attr(uint16_t start_handle, uint16_t end_handle, + bt_gatt_attr_func_t func, void *user_data) +{ + const struct bt_gatt_attr *attr; + + for (attr = db; attr; attr = bt_gatt_attr_next(attr)) { + /* Check if attribute handle is within range */ + if (attr->handle < start_handle || attr->handle > end_handle) { + continue; + } + + if (func(attr, user_data) == BT_GATT_ITER_STOP) { + break; + } + } +} + +struct bt_gatt_attr *bt_gatt_attr_next(const struct bt_gatt_attr *attr) +{ +#if defined(CONFIG_BLUETOOTH_GATT_DYNAMIC_DB) + return attr->_next; +#else + return ((attr < db || attr > &db[attr_count - 2]) ? NULL : + (struct bt_gatt_attr *)&attr[1]); +#endif /* CONFIG_BLUETOOTH_GATT_DYNAMIC_DB */ +} + +ssize_t bt_gatt_attr_read_ccc(struct bt_conn *conn, + const struct bt_gatt_attr *attr, void *buf, + uint16_t len, uint16_t offset) +{ + struct _bt_gatt_ccc *ccc = attr->user_data; + uint16_t value; + size_t i; + + for (i = 0; i < ccc->cfg_len; i++) { + if (bt_conn_addr_le_cmp(conn, &ccc->cfg[i].peer)) { + continue; + } + + value = sys_cpu_to_le16(ccc->cfg[i].value); + break; + } + + /* Default to disable if there is no cfg for the peer */ + if (i == ccc->cfg_len) { + value = 0x0000; + } + + return bt_gatt_attr_read(conn, attr, buf, len, offset, &value, + sizeof(value)); +} + +static void gatt_ccc_changed(const struct bt_gatt_attr *attr, + struct _bt_gatt_ccc *ccc) +{ + int i; + uint16_t value = 0x0000; + + for (i = 0; i < ccc->cfg_len; i++) { + if (ccc->cfg[i].value > value) { + value = ccc->cfg[i].value; + } + } + + BT_DBG("ccc %p value 0x%04x", ccc, value); + + if (value != ccc->value) { + ccc->value = value; + ccc->cfg_changed(attr, value); + } +} + +ssize_t bt_gatt_attr_write_ccc(struct bt_conn *conn, + const struct bt_gatt_attr *attr, const void *buf, + uint16_t len, uint16_t offset, uint8_t flags) +{ + struct _bt_gatt_ccc *ccc = attr->user_data; + uint16_t value; + size_t i; + + if (offset > sizeof(uint16_t)) { + return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET); + } + + if (offset + len > sizeof(uint16_t)) { + return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN); + } + + value = sys_get_le16(buf); + + for (i = 0; i < ccc->cfg_len; i++) { + /* Check for existing configuration */ + if (!bt_conn_addr_le_cmp(conn, &ccc->cfg[i].peer)) { + break; + } + } + + if (i == ccc->cfg_len) { + for (i = 0; i < ccc->cfg_len; i++) { + /* Check for unused configuration */ + if (ccc->cfg[i].valid) { + continue; + } + + bt_addr_le_copy(&ccc->cfg[i].peer, &conn->le.dst); + + if (value) { + ccc->cfg[i].valid = true; + } + + break; + } + + if (i == ccc->cfg_len) { + BT_WARN("No space to store CCC cfg"); + return BT_GATT_ERR(BT_ATT_ERR_INSUFFICIENT_RESOURCES); + } + } else if (!value) { + /* free existing configuration for default value */ + ccc->cfg[i].valid = false; + } + + ccc->cfg[i].value = value; + + BT_DBG("handle 0x%04x value %u", attr->handle, ccc->cfg[i].value); + + /* Update cfg if don't match */ + if (ccc->cfg[i].value != ccc->value) { + gatt_ccc_changed(attr, ccc); + } + + return len; +} + +ssize_t bt_gatt_attr_read_cep(struct bt_conn *conn, + const struct bt_gatt_attr *attr, void *buf, + uint16_t len, uint16_t offset) +{ + struct bt_gatt_cep *value = attr->user_data; + uint16_t props = sys_cpu_to_le16(value->properties); + + return bt_gatt_attr_read(conn, attr, buf, len, offset, &props, + sizeof(props)); +} + +ssize_t bt_gatt_attr_read_cud(struct bt_conn *conn, + const struct bt_gatt_attr *attr, void *buf, + uint16_t len, uint16_t offset) +{ + char *value = attr->user_data; + + return bt_gatt_attr_read(conn, attr, buf, len, offset, value, + strlen(value)); +} + +ssize_t bt_gatt_attr_read_cpf(struct bt_conn *conn, + const struct bt_gatt_attr *attr, void *buf, + uint16_t len, uint16_t offset) +{ + struct bt_gatt_cpf *value = attr->user_data; + + return bt_gatt_attr_read(conn, attr, buf, len, offset, value, + sizeof(*value)); +} + +struct notify_data { + uint16_t type; + const struct bt_gatt_attr *attr; + const void *data; + uint16_t len; + struct bt_gatt_indicate_params *params; +}; + +static int gatt_notify(struct bt_conn *conn, uint16_t handle, const void *data, + size_t len) +{ + struct net_buf *buf; + struct bt_att_notify *nfy; + + buf = bt_att_create_pdu(conn, BT_ATT_OP_NOTIFY, sizeof(*nfy) + len); + if (!buf) { + BT_WARN("No buffer available to send notification"); + return -ENOMEM; + } + + BT_DBG("conn %p handle 0x%04x", conn, handle); + + nfy = net_buf_add(buf, sizeof(*nfy)); + nfy->handle = sys_cpu_to_le16(handle); + + net_buf_add(buf, len); + memcpy(nfy->value, data, len); + + bt_l2cap_send(conn, BT_L2CAP_CID_ATT, buf); + + return 0; +} + +static void gatt_indicate_rsp(struct bt_conn *conn, uint8_t err, + const void *pdu, uint16_t length, void *user_data) +{ + struct bt_gatt_indicate_params *params = user_data; + + params->func(conn, params->attr, err); +} + +static int gatt_send(struct bt_conn *conn, struct net_buf *buf, + bt_att_func_t func, void *params, + bt_att_destroy_t destroy) +{ + int err; + + if (params) { + struct bt_att_req *req = params; + + req->buf = buf; + req->func = func; + req->destroy = destroy; + + err = bt_att_req_send(conn, req); + } else { + err = bt_att_send(conn, buf); + } + + if (err) { + BT_ERR("Error sending ATT PDU: %d", err); + net_buf_unref(buf); + } + + return err; +} + +static int gatt_indicate(struct bt_conn *conn, + struct bt_gatt_indicate_params *params) +{ + struct net_buf *buf; + struct bt_att_indicate *ind; + + buf = bt_att_create_pdu(conn, BT_ATT_OP_INDICATE, + sizeof(*ind) + params->len); + if (!buf) { + BT_WARN("No buffer available to send indication"); + return -ENOMEM; + } + + BT_DBG("conn %p handle 0x%04x", conn, params->attr->handle); + + ind = net_buf_add(buf, sizeof(*ind)); + ind->handle = sys_cpu_to_le16(params->attr->handle); + + net_buf_add(buf, params->len); + memcpy(ind->value, params->data, params->len); + + return gatt_send(conn, buf, gatt_indicate_rsp, params, NULL); +} + +static uint8_t notify_cb(const struct bt_gatt_attr *attr, void *user_data) +{ + struct notify_data *data = user_data; + struct _bt_gatt_ccc *ccc; + size_t i; + + if (bt_uuid_cmp(attr->uuid, BT_UUID_GATT_CCC)) { + /* Stop if we reach the next characteristic */ + if (!bt_uuid_cmp(attr->uuid, BT_UUID_GATT_CHRC)) { + return BT_GATT_ITER_STOP; + } + return BT_GATT_ITER_CONTINUE; + } + + /* Check attribute user_data must be of type struct _bt_gatt_ccc */ + if (attr->write != bt_gatt_attr_write_ccc) { + return BT_GATT_ITER_CONTINUE; + } + + ccc = attr->user_data; + + /* Notify all peers configured */ + for (i = 0; i < ccc->cfg_len; i++) { + struct bt_conn *conn; + int err; + + if (ccc->value != data->type) { + continue; + } + + conn = bt_conn_lookup_addr_le(&ccc->cfg[i].peer); + if (!conn) { + continue; + } + + if (conn->state != BT_CONN_CONNECTED) { + bt_conn_unref(conn); + continue; + } + + if (data->type == BT_GATT_CCC_INDICATE) { + err = gatt_indicate(conn, data->params); + } else { + err = gatt_notify(conn, data->attr->handle, data->data, + data->len); + } + + bt_conn_unref(conn); + + if (err < 0) { + return BT_GATT_ITER_STOP; + } + } + + return BT_GATT_ITER_CONTINUE; +} + +int bt_gatt_notify(struct bt_conn *conn, const struct bt_gatt_attr *attr, + const void *data, uint16_t len) +{ + struct notify_data nfy; + + __ASSERT(attr && attr->handle, "invalid parameters\n"); + + if (conn) { + return gatt_notify(conn, attr->handle, data, len); + } + + nfy.attr = attr; + nfy.type = BT_GATT_CCC_NOTIFY; + nfy.data = data; + nfy.len = len; + + bt_gatt_foreach_attr(attr->handle, 0xffff, notify_cb, &nfy); + + return 0; +} + +int bt_gatt_indicate(struct bt_conn *conn, + struct bt_gatt_indicate_params *params) +{ + struct notify_data nfy; + + __ASSERT(params, "invalid parameters\n"); + __ASSERT(params->attr && params->attr->handle, "invalid parameters\n"); + + if (conn) { + return gatt_indicate(conn, params); + } + + nfy.type = BT_GATT_CCC_INDICATE; + nfy.params = params; + + bt_gatt_foreach_attr(params->attr->handle, 0xffff, notify_cb, &nfy); + + return 0; +} + +uint16_t bt_gatt_get_mtu(struct bt_conn *conn) +{ + return bt_att_get_mtu(conn); +} + +static uint8_t connected_cb(const struct bt_gatt_attr *attr, void *user_data) +{ + struct bt_conn *conn = user_data; + struct _bt_gatt_ccc *ccc; + size_t i; + + /* Check attribute user_data must be of type struct _bt_gatt_ccc */ + if (attr->write != bt_gatt_attr_write_ccc) { + return BT_GATT_ITER_CONTINUE; + } + + ccc = attr->user_data; + + /* If already enabled skip */ + if (ccc->value) { + return BT_GATT_ITER_CONTINUE; + } + + for (i = 0; i < ccc->cfg_len; i++) { + /* Ignore configuration for different peer */ + if (bt_conn_addr_le_cmp(conn, &ccc->cfg[i].peer)) { + continue; + } + + if (ccc->cfg[i].value) { + gatt_ccc_changed(attr, ccc); + return BT_GATT_ITER_CONTINUE; + } + } + + return BT_GATT_ITER_CONTINUE; +} + +static uint8_t disconnected_cb(const struct bt_gatt_attr *attr, void *user_data) +{ + struct bt_conn *conn = user_data; + struct _bt_gatt_ccc *ccc; + size_t i; + + /* Check attribute user_data must be of type struct _bt_gatt_ccc */ + if (attr->write != bt_gatt_attr_write_ccc) { + return BT_GATT_ITER_CONTINUE; + } + + ccc = attr->user_data; + + /* If already disabled skip */ + if (!ccc->value) { + return BT_GATT_ITER_CONTINUE; + } + + for (i = 0; i < ccc->cfg_len; i++) { + /* Ignore configurations with disabled value */ + if (!ccc->cfg[i].value) { + continue; + } + + if (bt_conn_addr_le_cmp(conn, &ccc->cfg[i].peer)) { + struct bt_conn *tmp; + + /* Skip if there is another peer connected */ + tmp = bt_conn_lookup_addr_le(&ccc->cfg[i].peer); + if (tmp) { + if (tmp->state == BT_CONN_CONNECTED) { + bt_conn_unref(tmp); + return BT_GATT_ITER_CONTINUE; + } + + bt_conn_unref(tmp); + } + } else { + /* Clear value if not paired */ + if (!bt_addr_le_is_bonded(&conn->le.dst)) { + ccc->cfg[i].valid = false; + memset(&ccc->cfg[i].value, 0, + sizeof(ccc->cfg[i].value)); + } else { + /* Update address in case it has changed */ + bt_addr_le_copy(&ccc->cfg[i].peer, + &conn->le.dst); + } + } + } + + /* Reset value while disconnected */ + memset(&ccc->value, 0, sizeof(ccc->value)); + if (ccc->cfg_changed) { + ccc->cfg_changed(attr, ccc->value); + } + + BT_DBG("ccc %p reseted", ccc); + + return BT_GATT_ITER_CONTINUE; +} + +#if defined(CONFIG_BLUETOOTH_GATT_CLIENT) +void bt_gatt_notification(struct bt_conn *conn, uint16_t handle, + const void *data, uint16_t length) +{ + struct bt_gatt_subscribe_params *params, *tmp; + + BT_DBG("handle 0x%04x length %u", handle, length); + + SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&subscriptions, params, tmp, node) { + if (bt_conn_addr_le_cmp(conn, ¶ms->_peer) || + handle != params->value_handle) { + continue; + } + + if (params->notify(conn, params, data, length) == + BT_GATT_ITER_STOP) { + bt_gatt_unsubscribe(conn, params); + } + } +} + +static void update_subscription(struct bt_conn *conn, + struct bt_gatt_subscribe_params *params) +{ + if (params->_peer.type == BT_ADDR_LE_PUBLIC) { + return; + } + + /* Update address */ + bt_addr_le_copy(¶ms->_peer, &conn->le.dst); +} + +static void gatt_subscription_remove(struct bt_conn *conn, sys_snode_t *prev, + struct bt_gatt_subscribe_params *params) +{ + /* Remove subscription from the list*/ + sys_slist_remove(&subscriptions, prev, ¶ms->node); + + params->notify(conn, params, NULL, 0); +} + +static void remove_subscriptions(struct bt_conn *conn) +{ + struct bt_gatt_subscribe_params *params, *tmp; + sys_snode_t *prev = NULL; + + /* Lookup existing subscriptions */ + SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&subscriptions, params, tmp, node) { + if (bt_conn_addr_le_cmp(conn, ¶ms->_peer)) { + prev = ¶ms->node; + continue; + } + + if (!bt_addr_le_is_bonded(&conn->le.dst) || + (params->flags & BT_GATT_SUBSCRIBE_FLAG_VOLATILE)) { + /* Remove subscription */ + params->value = 0; + gatt_subscription_remove(conn, prev, params); + } else { + update_subscription(conn, params); + prev = ¶ms->node; + } + } +} + +static void gatt_mtu_rsp(struct bt_conn *conn, uint8_t err, const void *pdu, + uint16_t length, void *user_data) +{ + struct bt_gatt_exchange_params *params = user_data; + + params->func(conn, err, params); +} + +int bt_gatt_exchange_mtu(struct bt_conn *conn, + struct bt_gatt_exchange_params *params) +{ + struct bt_att_exchange_mtu_req *req; + struct net_buf *buf; + uint16_t mtu; + + __ASSERT(conn, "invalid parameter\n"); + __ASSERT(params && params->func, "invalid parameters\n"); + + if (conn->state != BT_CONN_CONNECTED) { + return -ENOTCONN; + } + + buf = bt_att_create_pdu(conn, BT_ATT_OP_MTU_REQ, sizeof(*req)); + if (!buf) { + return -ENOMEM; + } + + mtu = BT_ATT_MTU; + + BT_DBG("Client MTU %u", mtu); + + req = net_buf_add(buf, sizeof(*req)); + req->mtu = sys_cpu_to_le16(mtu); + + return gatt_send(conn, buf, gatt_mtu_rsp, params, NULL); +} + +static void gatt_discover_next(struct bt_conn *conn, uint16_t last_handle, + struct bt_gatt_discover_params *params) +{ + /* Skip if last_handle is not set */ + if (!last_handle) + goto discover; + + /* Continue from the last found handle */ + params->start_handle = last_handle; + if (params->start_handle < UINT16_MAX) { + params->start_handle++; + } + + /* Stop if over the range or the requests */ + if (params->start_handle >= params->end_handle) { + goto done; + } + +discover: + /* Discover next range */ + if (!bt_gatt_discover(conn, params)) { + return; + } + +done: + params->func(conn, NULL, params); +} + +static void gatt_find_type_rsp(struct bt_conn *conn, uint8_t err, + const void *pdu, uint16_t length, + void *user_data) +{ + const struct bt_att_find_type_rsp *rsp = pdu; + struct bt_gatt_discover_params *params = user_data; + uint8_t i; + uint16_t end_handle = 0, start_handle; + + BT_DBG("err 0x%02x", err); + + if (err) { + goto done; + } + + /* Parse attributes found */ + for (i = 0; length >= sizeof(rsp->list[i]); + i++, length -= sizeof(rsp->list[i])) { + struct bt_gatt_attr attr = {}; + struct bt_gatt_service value; + + start_handle = sys_le16_to_cpu(rsp->list[i].start_handle); + end_handle = sys_le16_to_cpu(rsp->list[i].end_handle); + + BT_DBG("start_handle 0x%04x end_handle 0x%04x", start_handle, + end_handle); + + if (params->type == BT_GATT_DISCOVER_PRIMARY) { + attr.uuid = BT_UUID_GATT_PRIMARY; + } else { + attr.uuid = BT_UUID_GATT_SECONDARY; + } + + value.end_handle = end_handle; + value.uuid = params->uuid; + + attr.handle = start_handle; + attr.user_data = &value; + + if (params->func(conn, &attr, params) == BT_GATT_ITER_STOP) { + return; + } + } + + /* Stop if could not parse the whole PDU */ + if (length > 0) { + goto done; + } + + gatt_discover_next(conn, end_handle, params); + + return; +done: + params->func(conn, NULL, params); +} + +static int gatt_find_type(struct bt_conn *conn, + struct bt_gatt_discover_params *params) +{ + struct net_buf *buf; + struct bt_att_find_type_req *req; + + buf = bt_att_create_pdu(conn, BT_ATT_OP_FIND_TYPE_REQ, sizeof(*req)); + if (!buf) { + return -ENOMEM; + } + + req = net_buf_add(buf, sizeof(*req)); + req->start_handle = sys_cpu_to_le16(params->start_handle); + req->end_handle = sys_cpu_to_le16(params->end_handle); + + if (params->type == BT_GATT_DISCOVER_PRIMARY) { + req->type = sys_cpu_to_le16(BT_UUID_GATT_PRIMARY_VAL); + } else { + req->type = sys_cpu_to_le16(BT_UUID_GATT_SECONDARY_VAL); + } + + BT_DBG("uuid %s start_handle 0x%04x end_handle 0x%04x", + bt_uuid_str(params->uuid), params->start_handle, + params->end_handle); + + switch (params->uuid->type) { + case BT_UUID_TYPE_16: + net_buf_add_le16(buf, BT_UUID_16(params->uuid)->val); + break; + case BT_UUID_TYPE_128: + net_buf_add_mem(buf, BT_UUID_128(params->uuid)->val, 16); + break; + default: + BT_ERR("Unknown UUID type %u", params->uuid->type); + net_buf_unref(buf); + return -EINVAL; + } + + return gatt_send(conn, buf, gatt_find_type_rsp, params, NULL); +} + +static void read_included_uuid_cb(struct bt_conn *conn, uint8_t err, + const void *pdu, uint16_t length, + void *user_data) +{ + struct bt_gatt_discover_params *params = user_data; + struct bt_gatt_include value; + struct bt_gatt_attr *attr; + union { + struct bt_uuid uuid; + struct bt_uuid_128 u128; + } u; + + if (length != 16) { + BT_ERR("Invalid data len %u", length); + params->func(conn, NULL, params); + return; + } + + value.start_handle = params->_included.start_handle; + value.end_handle = params->_included.end_handle; + value.uuid = &u.uuid; + u.uuid.type = BT_UUID_TYPE_128; + memcpy(u.u128.val, pdu, length); + + BT_DBG("handle 0x%04x uuid %s start_handle 0x%04x " + "end_handle 0x%04x\n", params->_included.attr_handle, + bt_uuid_str(&u.uuid), value.start_handle, value.end_handle); + + /* Skip if UUID is set but doesn't match */ + if (params->uuid && bt_uuid_cmp(&u.uuid, params->uuid)) { + goto next; + } + + attr = (&(struct bt_gatt_attr) { + .uuid = BT_UUID_GATT_INCLUDE, + .user_data = &value, }); + attr->handle = params->_included.attr_handle; + + if (params->func(conn, attr, params) == BT_GATT_ITER_STOP) { + return; + } +next: + gatt_discover_next(conn, params->start_handle, params); + + return; +} + +static int read_included_uuid(struct bt_conn *conn, + struct bt_gatt_discover_params *params) +{ + struct net_buf *buf; + struct bt_att_read_req *req; + + buf = bt_att_create_pdu(conn, BT_ATT_OP_READ_REQ, sizeof(*req)); + if (!buf) { + return -ENOMEM; + } + + req = net_buf_add(buf, sizeof(*req)); + req->handle = sys_cpu_to_le16(params->_included.start_handle); + + BT_DBG("handle 0x%04x", params->_included.start_handle); + + return gatt_send(conn, buf, read_included_uuid_cb, params, NULL); +} + +static uint16_t parse_include(struct bt_conn *conn, const void *pdu, + struct bt_gatt_discover_params *params, + uint16_t length) +{ + const struct bt_att_read_type_rsp *rsp = pdu; + uint16_t handle = 0; + struct bt_gatt_include value; + union { + struct bt_uuid uuid; + struct bt_uuid_16 u16; + struct bt_uuid_128 u128; + } u; + + /* Data can be either in UUID16 or UUID128 */ + switch (rsp->len) { + case 8: /* UUID16 */ + u.uuid.type = BT_UUID_TYPE_16; + break; + case 6: /* UUID128 */ + /* BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part G] page 550 + * To get the included service UUID when the included service + * uses a 128-bit UUID, the Read Request is used. + */ + u.uuid.type = BT_UUID_TYPE_128; + break; + default: + BT_ERR("Invalid data len %u", rsp->len); + goto done; + } + + /* Parse include found */ + for (length--, pdu = rsp->data; length >= rsp->len; + length -= rsp->len, pdu += rsp->len) { + struct bt_gatt_attr *attr; + const struct bt_att_data *data = pdu; + struct gatt_incl *incl = (void *)data->value; + + handle = sys_le16_to_cpu(data->handle); + /* Handle 0 is invalid */ + if (!handle) { + goto done; + } + + /* Convert include data, bt_gatt_incl and gatt_incl + * have different formats so the conversion have to be done + * field by field. + */ + value.start_handle = sys_le16_to_cpu(incl->start_handle); + value.end_handle = sys_le16_to_cpu(incl->end_handle); + + switch (u.uuid.type) { + case BT_UUID_TYPE_16: + value.uuid = &u.uuid; + u.u16.val = sys_le16_to_cpu(incl->uuid16); + break; + case BT_UUID_TYPE_128: + params->_included.attr_handle = handle; + params->_included.start_handle = value.start_handle; + params->_included.end_handle = value.end_handle; + + return read_included_uuid(conn, params); + } + + BT_DBG("handle 0x%04x uuid %s start_handle 0x%04x " + "end_handle 0x%04x\n", handle, bt_uuid_str(&u.uuid), + value.start_handle, value.end_handle); + + /* Skip if UUID is set but doesn't match */ + if (params->uuid && bt_uuid_cmp(&u.uuid, params->uuid)) { + continue; + } + + attr = (&(struct bt_gatt_attr) { + .uuid = BT_UUID_GATT_INCLUDE, + .user_data = &value, }); + attr->handle = handle; + + if (params->func(conn, attr, params) == BT_GATT_ITER_STOP) { + return 0; + } + } + + /* Whole PDU read without error */ + if (length == 0 && handle) { + return handle; + } + +done: + params->func(conn, NULL, params); + return 0; +} + +static uint16_t parse_characteristic(struct bt_conn *conn, const void *pdu, + struct bt_gatt_discover_params *params, + uint16_t length) +{ + const struct bt_att_read_type_rsp *rsp = pdu; + uint16_t handle = 0; + union { + struct bt_uuid uuid; + struct bt_uuid_16 u16; + struct bt_uuid_128 u128; + } u; + + /* Data can be either in UUID16 or UUID128 */ + switch (rsp->len) { + case 7: /* UUID16 */ + u.uuid.type = BT_UUID_TYPE_16; + break; + case 21: /* UUID128 */ + u.uuid.type = BT_UUID_TYPE_128; + break; + default: + BT_ERR("Invalid data len %u", rsp->len); + goto done; + } + + /* Parse characteristics found */ + for (length--, pdu = rsp->data; length >= rsp->len; + length -= rsp->len, pdu += rsp->len) { + struct bt_gatt_attr *attr; + const struct bt_att_data *data = pdu; + struct gatt_chrc *chrc = (void *)data->value; + + handle = sys_le16_to_cpu(data->handle); + /* Handle 0 is invalid */ + if (!handle) { + goto done; + } + + switch (u.uuid.type) { + case BT_UUID_TYPE_16: + u.u16.val = sys_le16_to_cpu(chrc->uuid16); + break; + case BT_UUID_TYPE_128: + memcpy(u.u128.val, chrc->uuid, sizeof(chrc->uuid)); + break; + } + + BT_DBG("handle 0x%04x uuid %s properties 0x%02x", handle, + bt_uuid_str(&u.uuid), chrc->properties); + + /* Skip if UUID is set but doesn't match */ + if (params->uuid && bt_uuid_cmp(&u.uuid, params->uuid)) { + continue; + } + + attr = (&(struct bt_gatt_attr)BT_GATT_CHARACTERISTIC(&u.uuid, + chrc->properties)); + attr->handle = handle; + + if (params->func(conn, attr, params) == BT_GATT_ITER_STOP) { + return 0; + } + } + + /* Whole PDU read without error */ + if (length == 0 && handle) { + return handle; + } + +done: + params->func(conn, NULL, params); + return 0; +} + +static void gatt_read_type_rsp(struct bt_conn *conn, uint8_t err, + const void *pdu, uint16_t length, + void *user_data) +{ + struct bt_gatt_discover_params *params = user_data; + uint16_t handle; + + BT_DBG("err 0x%02x", err); + + if (err) { + params->func(conn, NULL, params); + return; + } + + if (params->type == BT_GATT_DISCOVER_INCLUDE) { + handle = parse_include(conn, pdu, params, length); + } else { + handle = parse_characteristic(conn, pdu, params, length); + } + + if (!handle) { + return; + } + + gatt_discover_next(conn, handle, params); +} + +static int gatt_read_type(struct bt_conn *conn, + struct bt_gatt_discover_params *params) +{ + struct net_buf *buf; + struct bt_att_read_type_req *req; + + buf = bt_att_create_pdu(conn, BT_ATT_OP_READ_TYPE_REQ, sizeof(*req)); + if (!buf) { + return -ENOMEM; + } + + req = net_buf_add(buf, sizeof(*req)); + req->start_handle = sys_cpu_to_le16(params->start_handle); + req->end_handle = sys_cpu_to_le16(params->end_handle); + + if (params->type == BT_GATT_DISCOVER_INCLUDE) { + net_buf_add_le16(buf, BT_UUID_GATT_INCLUDE_VAL); + } else { + net_buf_add_le16(buf, BT_UUID_GATT_CHRC_VAL); + } + + BT_DBG("start_handle 0x%04x end_handle 0x%04x", params->start_handle, + params->end_handle); + + return gatt_send(conn, buf, gatt_read_type_rsp, params, NULL); +} + +static void gatt_find_info_rsp(struct bt_conn *conn, uint8_t err, + const void *pdu, uint16_t length, + void *user_data) +{ + const struct bt_att_find_info_rsp *rsp = pdu; + struct bt_gatt_discover_params *params = user_data; + uint16_t handle = 0; + uint8_t len; + union { + const struct bt_att_info_16 *i16; + const struct bt_att_info_128 *i128; + } info; + union { + struct bt_uuid uuid; + struct bt_uuid_16 u16; + struct bt_uuid_128 u128; + } u; + + BT_DBG("err 0x%02x", err); + + if (err) { + goto done; + } + + /* Data can be either in UUID16 or UUID128 */ + switch (rsp->format) { + case BT_ATT_INFO_16: + u.uuid.type = BT_UUID_TYPE_16; + len = sizeof(*info.i16); + break; + case BT_ATT_INFO_128: + u.uuid.type = BT_UUID_TYPE_128; + len = sizeof(*info.i128); + break; + default: + BT_ERR("Invalid format %u", rsp->format); + goto done; + } + + /* Parse descriptors found */ + for (length--, pdu = rsp->info; length >= len; + length -= len, pdu += len) { + struct bt_gatt_attr *attr; + + info.i16 = pdu; + handle = sys_le16_to_cpu(info.i16->handle); + + switch (u.uuid.type) { + case BT_UUID_TYPE_16: + u.u16.val = sys_le16_to_cpu(info.i16->uuid); + break; + case BT_UUID_TYPE_128: + memcpy(u.u128.val, info.i128->uuid, 16); + break; + } + + BT_DBG("handle 0x%04x uuid %s", handle, bt_uuid_str(&u.uuid)); + + /* Skip if UUID is set but doesn't match */ + if (params->uuid && bt_uuid_cmp(&u.uuid, params->uuid)) { + continue; + } + + attr = (&(struct bt_gatt_attr) + BT_GATT_DESCRIPTOR(&u.uuid, 0, NULL, NULL, NULL)); + attr->handle = handle; + + if (params->func(conn, attr, params) == BT_GATT_ITER_STOP) { + return; + } + } + + /* Stop if could not parse the whole PDU */ + if (length > 0) { + goto done; + } + + gatt_discover_next(conn, handle, params); + + return; + +done: + params->func(conn, NULL, params); +} + +static int gatt_find_info(struct bt_conn *conn, + struct bt_gatt_discover_params *params) +{ + struct net_buf *buf; + struct bt_att_find_info_req *req; + + buf = bt_att_create_pdu(conn, BT_ATT_OP_FIND_INFO_REQ, sizeof(*req)); + if (!buf) { + return -ENOMEM; + } + + req = net_buf_add(buf, sizeof(*req)); + req->start_handle = sys_cpu_to_le16(params->start_handle); + req->end_handle = sys_cpu_to_le16(params->end_handle); + + BT_DBG("start_handle 0x%04x end_handle 0x%04x", params->start_handle, + params->end_handle); + + return gatt_send(conn, buf, gatt_find_info_rsp, params, NULL); +} + +int bt_gatt_discover(struct bt_conn *conn, + struct bt_gatt_discover_params *params) +{ + __ASSERT(conn, "invalid parameters\n"); + __ASSERT(params && params->func, "invalid parameters\n"); + __ASSERT((params->start_handle && params->end_handle), + "invalid parameters\n"); + __ASSERT((params->start_handle < params->end_handle), + "invalid parameters\n"); + + if (conn->state != BT_CONN_CONNECTED) { + return -ENOTCONN; + } + + switch (params->type) { + case BT_GATT_DISCOVER_PRIMARY: + case BT_GATT_DISCOVER_SECONDARY: + return gatt_find_type(conn, params); + case BT_GATT_DISCOVER_INCLUDE: + case BT_GATT_DISCOVER_CHARACTERISTIC: + return gatt_read_type(conn, params); + case BT_GATT_DISCOVER_DESCRIPTOR: + return gatt_find_info(conn, params); + default: + BT_ERR("Invalid discovery type: %u", params->type); + } + + return -EINVAL; +} + +static void gatt_read_rsp(struct bt_conn *conn, uint8_t err, const void *pdu, + uint16_t length, void *user_data) +{ + struct bt_gatt_read_params *params = user_data; + + BT_DBG("err 0x%02x", err); + + if (err || !length) { + params->func(conn, err, params, NULL, 0); + return; + } + + if (params->func(conn, 0, params, pdu, length) == BT_GATT_ITER_STOP) { + return; + } + + /* + * Core Spec 4.2, Vol. 3, Part G, 4.8.1 + * If the Characteristic Value is greater than (ATT_MTU - 1) octets + * in length, the Read Long Characteristic Value procedure may be used + * if the rest of the Characteristic Value is required. + */ + if (length < (bt_att_get_mtu(conn) - 1)) { + params->func(conn, 0, params, NULL, 0); + return; + } + + params->single.offset += length; + + /* Continue reading the attribute */ + if (bt_gatt_read(conn, params) < 0) { + params->func(conn, BT_ATT_ERR_UNLIKELY, params, NULL, 0); + } +} + +static int gatt_read_blob(struct bt_conn *conn, + struct bt_gatt_read_params *params) +{ + struct net_buf *buf; + struct bt_att_read_blob_req *req; + + buf = bt_att_create_pdu(conn, BT_ATT_OP_READ_BLOB_REQ, sizeof(*req)); + if (!buf) { + return -ENOMEM; + } + + req = net_buf_add(buf, sizeof(*req)); + req->handle = sys_cpu_to_le16(params->single.handle); + req->offset = sys_cpu_to_le16(params->single.offset); + + BT_DBG("handle 0x%04x offset 0x%04x", params->single.handle, + params->single.offset); + + return gatt_send(conn, buf, gatt_read_rsp, params, NULL); +} + +static void gatt_read_multiple_rsp(struct bt_conn *conn, uint8_t err, + const void *pdu, uint16_t length, + void *user_data) +{ + struct bt_gatt_read_params *params = user_data; + + BT_DBG("err 0x%02x", err); + + if (err || !length) { + params->func(conn, err, params, NULL, 0); + return; + } + + params->func(conn, 0, params, pdu, length); + + /* mark read as complete since read multiple is single response */ + params->func(conn, 0, params, NULL, 0); +} + +static int gatt_read_multiple(struct bt_conn *conn, + struct bt_gatt_read_params *params) +{ + struct net_buf *buf; + uint8_t i; + + buf = bt_att_create_pdu(conn, BT_ATT_OP_READ_MULT_REQ, + params->handle_count * sizeof(uint16_t)); + if (!buf) { + return -ENOMEM; + } + + for (i = 0; i < params->handle_count; i++) { + net_buf_add_le16(buf, params->handles[i]); + } + + return gatt_send(conn, buf, gatt_read_multiple_rsp, params, NULL); +} + +int bt_gatt_read(struct bt_conn *conn, struct bt_gatt_read_params *params) +{ + struct net_buf *buf; + struct bt_att_read_req *req; + + __ASSERT(conn, "invalid parameters\n"); + __ASSERT(params && params->func, "invalid parameters\n"); + __ASSERT(params->handle_count, "invalid parameters\n"); + + if (conn->state != BT_CONN_CONNECTED) { + return -ENOTCONN; + } + + if (params->handle_count > 1) { + return gatt_read_multiple(conn, params); + } + + if (params->single.offset) { + return gatt_read_blob(conn, params); + } + + buf = bt_att_create_pdu(conn, BT_ATT_OP_READ_REQ, sizeof(*req)); + if (!buf) { + return -ENOMEM; + } + + req = net_buf_add(buf, sizeof(*req)); + req->handle = sys_cpu_to_le16(params->single.handle); + + BT_DBG("handle 0x%04x", params->single.handle); + + return gatt_send(conn, buf, gatt_read_rsp, params, NULL); +} + +static void gatt_write_rsp(struct bt_conn *conn, uint8_t err, const void *pdu, + uint16_t length, void *user_data) +{ + struct bt_gatt_write_params *params = user_data; + + BT_DBG("err 0x%02x", err); + + params->func(conn, err, params); +} + +static bool write_signed_allowed(struct bt_conn *conn) +{ +#if defined(CONFIG_BLUETOOTH_SMP) + return conn->encrypt == 0; +#else + return false; +#endif /* CONFIG_BLUETOOTH_SMP */ +} + +int bt_gatt_write_without_response(struct bt_conn *conn, uint16_t handle, + const void *data, uint16_t length, bool sign) +{ + struct net_buf *buf; + struct bt_att_write_cmd *cmd; + + __ASSERT(conn, "invalid parameters\n"); + __ASSERT(handle, "invalid parameters\n"); + + if (conn->state != BT_CONN_CONNECTED) { + return -ENOTCONN; + } + + if (sign && write_signed_allowed(conn)) { + buf = bt_att_create_pdu(conn, BT_ATT_OP_SIGNED_WRITE_CMD, + sizeof(*cmd) + length + 12); + } else { + buf = bt_att_create_pdu(conn, BT_ATT_OP_WRITE_CMD, + sizeof(*cmd) + length); + } + if (!buf) { + return -ENOMEM; + } + + cmd = net_buf_add(buf, sizeof(*cmd)); + cmd->handle = sys_cpu_to_le16(handle); + memcpy(cmd->value, data, length); + net_buf_add(buf, length); + + BT_DBG("handle 0x%04x length %u", handle, length); + + return gatt_send(conn, buf, NULL, NULL, NULL); +} + +static int gatt_exec_write(struct bt_conn *conn, + struct bt_gatt_write_params *params) +{ + struct net_buf *buf; + struct bt_att_exec_write_req *req; + + buf = bt_att_create_pdu(conn, BT_ATT_OP_EXEC_WRITE_REQ, sizeof(*req)); + if (!buf) { + return -ENOMEM; + } + + req = net_buf_add(buf, sizeof(*req)); + req->flags = BT_ATT_FLAG_EXEC; + + BT_DBG(""); + + return gatt_send(conn, buf, gatt_write_rsp, params, NULL); +} + +static void gatt_prepare_write_rsp(struct bt_conn *conn, uint8_t err, + const void *pdu, uint16_t length, + void *user_data) +{ + struct bt_gatt_write_params *params = user_data; + + BT_DBG("err 0x%02x", err); + + + /* Don't continue in case of error */ + if (err) { + params->func(conn, err, params); + return; + } + + /* If there is no more data execute */ + if (!params->length) { + gatt_exec_write(conn, params); + return; + } + + /* Write next chunk */ + bt_gatt_write(conn, params); +} + +static int gatt_prepare_write(struct bt_conn *conn, + struct bt_gatt_write_params *params) +{ + struct net_buf *buf; + struct bt_att_prepare_write_req *req; + uint16_t len; + + len = min(params->length, bt_att_get_mtu(conn) - sizeof(*req) - 1); + + buf = bt_att_create_pdu(conn, BT_ATT_OP_PREPARE_WRITE_REQ, + sizeof(*req) + len); + if (!buf) { + return -ENOMEM; + } + + req = net_buf_add(buf, sizeof(*req)); + req->handle = sys_cpu_to_le16(params->handle); + req->offset = sys_cpu_to_le16(params->offset); + memcpy(req->value, params->data, len); + net_buf_add(buf, len); + + /* Update params */ + params->offset += len; + params->data += len; + params->length -= len; + + BT_DBG("handle 0x%04x offset %u len %u", params->handle, params->offset, + params->length); + + return gatt_send(conn, buf, gatt_prepare_write_rsp, params, NULL); +} + +int bt_gatt_write(struct bt_conn *conn, struct bt_gatt_write_params *params) +{ + struct net_buf *buf; + struct bt_att_write_req *req; + + __ASSERT(conn, "invalid parameters\n"); + __ASSERT(params && params->func, "invalid parameters\n"); + __ASSERT(params->handle, "invalid parameters\n"); + + if (conn->state != BT_CONN_CONNECTED) { + return -ENOTCONN; + } + + /* Use Prepare Write if offset is set or Long Write is required */ + if (params->offset || + params->length > (bt_att_get_mtu(conn) - sizeof(*req) - 1)) { + return gatt_prepare_write(conn, params); + } + + buf = bt_att_create_pdu(conn, BT_ATT_OP_WRITE_REQ, + sizeof(*req) + params->length); + if (!buf) { + return -ENOMEM; + } + + req = net_buf_add(buf, sizeof(*req)); + req->handle = sys_cpu_to_le16(params->handle); + memcpy(req->value, params->data, params->length); + net_buf_add(buf, params->length); + + BT_DBG("handle 0x%04x length %u", params->handle, params->length); + + return gatt_send(conn, buf, gatt_write_rsp, params, NULL); +} + +static void gatt_subscription_add(struct bt_conn *conn, + struct bt_gatt_subscribe_params *params) +{ + bt_addr_le_copy(¶ms->_peer, &conn->le.dst); + + /* Prepend subscription */ + sys_slist_prepend(&subscriptions, ¶ms->node); +} + +static void gatt_write_ccc_rsp(struct bt_conn *conn, uint8_t err, + const void *pdu, uint16_t length, + void *user_data) +{ + struct bt_gatt_subscribe_params *params = user_data; + + BT_DBG("err 0x%02x", err); + + /* if write to CCC failed we remove subscription and notify app */ + if (err) { + sys_snode_t *node, *tmp, *prev = NULL; + + SYS_SLIST_FOR_EACH_NODE_SAFE(&subscriptions, node, tmp) { + if (node == ¶ms->node) { + gatt_subscription_remove(conn, tmp, params); + break; + } + + prev = node; + } + } +} + +static int gatt_write_ccc(struct bt_conn *conn, uint16_t handle, uint16_t value, + bt_att_func_t func, + struct bt_gatt_subscribe_params *params) +{ + struct net_buf *buf; + struct bt_att_write_req *req; + + buf = bt_att_create_pdu(conn, BT_ATT_OP_WRITE_REQ, + sizeof(*req) + sizeof(uint16_t)); + if (!buf) { + return -ENOMEM; + } + + req = net_buf_add(buf, sizeof(*req)); + req->handle = sys_cpu_to_le16(handle); + net_buf_add_le16(buf, value); + + BT_DBG("handle 0x%04x value 0x%04x", handle, value); + + return gatt_send(conn, buf, func, params, NULL); +} + +int bt_gatt_subscribe(struct bt_conn *conn, + struct bt_gatt_subscribe_params *params) +{ + struct bt_gatt_subscribe_params *tmp; + bool has_subscription = false; + + __ASSERT(conn, "invalid parameters\n"); + __ASSERT(params && params->notify, "invalid parameters\n"); + __ASSERT(params->value, "invalid parameters\n"); + __ASSERT(params->ccc_handle, "invalid parameters\n"); + + if (conn->state != BT_CONN_CONNECTED) { + return -ENOTCONN; + } + + /* Lookup existing subscriptions */ + SYS_SLIST_FOR_EACH_CONTAINER(&subscriptions, tmp, node) { + /* Fail if entry already exists */ + if (tmp == params) { + return -EALREADY; + } + + /* Check if another subscription exists */ + if (!bt_conn_addr_le_cmp(conn, &tmp->_peer) && + tmp->value_handle == params->value_handle && + tmp->value >= params->value) { + has_subscription = true; + } + } + + /* Skip write if already subscribed */ + if (!has_subscription) { + int err; + + err = gatt_write_ccc(conn, params->ccc_handle, params->value, + gatt_write_ccc_rsp, NULL); + if (err) { + return err; + } + } + + /* + * Add subscription before write complete as some implementation were + * reported to send notification before reply to CCC write. + */ + gatt_subscription_add(conn, params); + + return 0; +} + +int bt_gatt_unsubscribe(struct bt_conn *conn, + struct bt_gatt_subscribe_params *params) +{ + struct bt_gatt_subscribe_params *tmp, *next; + bool has_subscription = false, found = false; + sys_snode_t *prev = NULL; + + __ASSERT(conn, "invalid parameters\n"); + __ASSERT(params, "invalid parameters\n"); + + if (conn->state != BT_CONN_CONNECTED) { + return -ENOTCONN; + } + + /* Lookup existing subscriptions */ + SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&subscriptions, tmp, next, node) { + /* Remove subscription */ + if (params == tmp) { + found = true; + sys_slist_remove(&subscriptions, prev, &tmp->node); + continue; + } else { + prev = &tmp->node; + } + + /* Check if there still remains any other subscription */ + if (!bt_conn_addr_le_cmp(conn, &tmp->_peer) && + tmp->value_handle == params->value_handle) { + has_subscription = true; + } + } + + if (!found) { + return -EINVAL; + } + + if (has_subscription) { + return 0; + } + + return gatt_write_ccc(conn, params->ccc_handle, 0x0000, NULL, NULL); +} + +void bt_gatt_cancel(struct bt_conn *conn, void *params) +{ + bt_att_req_cancel(conn, params); +} + +static void add_subscriptions(struct bt_conn *conn) +{ + struct bt_gatt_subscribe_params *params; + + /* Lookup existing subscriptions */ + SYS_SLIST_FOR_EACH_CONTAINER(&subscriptions, params, node) { + if (bt_conn_addr_le_cmp(conn, ¶ms->_peer)) { + continue; + } + + /* Force write to CCC to workaround devices that don't track + * it properly. + */ + gatt_write_ccc(conn, params->ccc_handle, params->value, + NULL, NULL); + } +} + +#endif /* CONFIG_BLUETOOTH_GATT_CLIENT */ + +void bt_gatt_connected(struct bt_conn *conn) +{ + BT_DBG("conn %p", conn); + bt_gatt_foreach_attr(0x0001, 0xffff, connected_cb, conn); +#if defined(CONFIG_BLUETOOTH_GATT_CLIENT) + add_subscriptions(conn); +#endif /* CONFIG_BLUETOOTH_GATT_CLIENT */ +} + +void bt_gatt_disconnected(struct bt_conn *conn) +{ + BT_DBG("conn %p", conn); + bt_gatt_foreach_attr(0x0001, 0xffff, disconnected_cb, conn); + +#if defined(CONFIG_BLUETOOTH_GATT_CLIENT) + remove_subscriptions(conn); +#endif /* CONFIG_BLUETOOTH_GATT_CLIENT */ +} diff --git a/kernel/protocols/bluetooth/host/gatt_internal.h b/kernel/protocols/bluetooth/host/gatt_internal.h new file mode 100644 index 0000000000..9f97fca7e3 --- /dev/null +++ b/kernel/protocols/bluetooth/host/gatt_internal.h @@ -0,0 +1,22 @@ +/** @file + * @brief Internal API for Generic Attribute Profile handling. + */ + +/* + * Copyright (c) 2015-2016 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +void bt_gatt_connected(struct bt_conn *conn); +void bt_gatt_disconnected(struct bt_conn *conn); + +#if defined(CONFIG_BLUETOOTH_GATT_CLIENT) +void bt_gatt_notification(struct bt_conn *conn, uint16_t handle, + const void *data, uint16_t length); +#else +static inline void bt_gatt_notification(struct bt_conn *conn, uint16_t handle, + const void *data, uint16_t length) +{ +} +#endif /* CONFIG_BLUETOOTH_GATT_CLIENT */ diff --git a/kernel/protocols/bluetooth/host/hci_core.c b/kernel/protocols/bluetooth/host/hci_core.c new file mode 100644 index 0000000000..34c5bcd08f --- /dev/null +++ b/kernel/protocols/bluetooth/host/hci_core.c @@ -0,0 +1,4594 @@ +/* hci_core.c - HCI core Bluetooth handling */ + +/* + * Copyright (c) 2015-2016 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include + +#include + +#include +#include +#include +#include +#include +#include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HCI_CORE) +#include + +#include "keys.h" +#include "monitor.h" +#include "hci_core.h" +#include "hci_ecc.h" +#include "ecc.h" + +#include "conn_internal.h" +#include "l2cap_internal.h" +#include "smp.h" + +#undef read +#undef write +#undef send + +/* Peripheral timeout to initialize Connection Parameter Update procedure */ +#define CONN_UPDATE_TIMEOUT K_SECONDS(5) +#define RPA_TIMEOUT K_SECONDS(CONFIG_BLUETOOTH_RPA_TIMEOUT) + +/* Stacks for the threads */ +static BT_STACK_NOINIT(rx_thread_stack, CONFIG_BLUETOOTH_HCI_RX_STACK_SIZE); +static BT_STACK_NOINIT(tx_thread_stack, CONFIG_BLUETOOTH_HCI_TX_STACK_SIZE); + +static void init_work(struct k_work *work); + +struct bt_dev bt_dev; + +static bt_ready_cb_t ready_cb; + +const struct bt_storage *bt_storage; + +static bt_le_scan_cb_t *scan_dev_found_cb; + +static uint8_t pub_key[64]; +static struct bt_pub_key_cb *pub_key_cb; +static bt_dh_key_cb_t dh_key_cb; + +#if defined(CONFIG_BLUETOOTH_BREDR) +static bt_br_discovery_cb_t *discovery_cb; +struct bt_br_discovery_result *discovery_results; +static size_t discovery_results_size; +static size_t discovery_results_count; +#endif /* CONFIG_BLUETOOTH_BREDR */ + +struct cmd_data { + /** BT_BUF_CMD */ + uint8_t type; + + /** HCI status of the command completion */ + uint8_t status; + + /** The command OpCode that the buffer contains */ + uint16_t opcode; + + /** Used by bt_hci_cmd_send_sync. */ + struct k_sem *sync; +}; + +struct acl_data { + /** BT_BUF_ACL_IN */ + uint8_t type; + + /** ACL connection handle */ + uint16_t handle; +}; + +#define cmd(buf) ((struct cmd_data *)net_buf_user_data(buf)) +#define acl(buf) ((struct acl_data *)net_buf_user_data(buf)) + +/* HCI command buffers. Derive the needed size from BT_BUF_RX_SIZE since + * the same buffer is also used for the response. + */ +#define CMD_BUF_SIZE BT_BUF_RX_SIZE +NET_BUF_POOL_DEFINE(hci_cmd_pool, CONFIG_BLUETOOTH_HCI_CMD_COUNT, + CMD_BUF_SIZE, sizeof(struct cmd_data), NULL); + +NET_BUF_POOL_DEFINE(hci_rx_pool, CONFIG_BLUETOOTH_RX_BUF_COUNT, + BT_BUF_RX_SIZE, BT_BUF_USER_DATA_MIN, NULL); + +static void* hci_cmd_msg_buf[CONFIG_BLUETOOTH_HCI_CMD_COUNT]; + +static void* tx_event_msg_buf[CONFIG_BLUETOOTH_RX_BUF_COUNT]; + +static void* hci_rx_msg_buf[CONFIG_BLUETOOTH_RX_BUF_COUNT]; + +void hci_tx_event_notify(const void* obj); + +#if defined(CONFIG_BLUETOOTH_DEBUG) +const char *bt_addr_str(const bt_addr_t *addr) +{ + static char bufs[2][18]; + static uint8_t cur; + char *str; + + str = bufs[cur++]; + cur %= ARRAY_SIZE(bufs); + bt_addr_to_str(addr, str, sizeof(bufs[cur])); + + return str; +} + +const char *bt_addr_le_str(const bt_addr_le_t *addr) +{ + static char bufs[2][27]; + static uint8_t cur; + char *str; + + str = bufs[cur++]; + cur %= ARRAY_SIZE(bufs); + bt_addr_le_to_str(addr, str, sizeof(bufs[cur])); + + return str; +} +#else +const char *bt_addr_str(const bt_addr_t *addr) +{ + return ""; +} +const char *bt_addr_le_str(const bt_addr_le_t *addr) +{ + return ""; +} +#endif /* CONFIG_BLUETOOTH_DEBUG */ + +struct net_buf *bt_hci_cmd_create(uint16_t opcode, uint8_t param_len) +{ + struct bt_hci_cmd_hdr *hdr; + struct net_buf *buf; + + BT_DBG("opcode 0x%04x param_len %u", opcode, param_len); + + buf = net_buf_alloc(&hci_cmd_pool, K_FOREVER); + __ASSERT_NO_MSG(buf); + + BT_DBG("buf %p", buf); + + net_buf_reserve(buf, CONFIG_BLUETOOTH_HCI_RESERVE); + + cmd(buf)->type = BT_BUF_CMD; + cmd(buf)->opcode = opcode; + cmd(buf)->sync = NULL; + + hdr = net_buf_add(buf, sizeof(*hdr)); + hdr->opcode = sys_cpu_to_le16(opcode); + hdr->param_len = param_len; + + return buf; +} + +int bt_hci_cmd_send(uint16_t opcode, struct net_buf *buf) +{ + if (!buf) { + buf = bt_hci_cmd_create(opcode, 0); + if (!buf) { + return -ENOBUFS; + } + } + + BT_DBG("opcode 0x%04x len %u", opcode, buf->len); + + /* Host Number of Completed Packets can ignore the ncmd value + * and does not generate any cmd complete/status events. + */ + if (opcode == BT_HCI_OP_HOST_NUM_COMPLETED_PACKETS) { + int err; + + err = bt_send(buf); + if (err) { + BT_ERR("Unable to send to driver (err %d)", err); + net_buf_unref(buf); + } + + return err; + } + + net_buf_put(&bt_dev.cmd_tx_queue, buf); + hci_tx_event_notify(&bt_dev.cmd_tx_queue); + + return 0; +} + +int bt_hci_cmd_send_sync(uint16_t opcode, struct net_buf *buf, + struct net_buf **rsp) +{ + struct k_sem sync_sem; + int err; + + if (!buf) { + buf = bt_hci_cmd_create(opcode, 0); + if (!buf) { + return -ENOBUFS; + } + } + + BT_DBG("buf %p opcode 0x%04x len %u", buf, opcode, buf->len); + + err = k_sem_init(&sync_sem, 0, 1); + cmd(buf)->sync = &sync_sem; + BT_DBG("k_sem_init %d", err); + + /* Make sure the buffer stays around until the command completes */ + net_buf_ref(buf); + + net_buf_put(&bt_dev.cmd_tx_queue, buf); + hci_tx_event_notify(&bt_dev.cmd_tx_queue); + + k_sem_take(&sync_sem, K_FOREVER); + k_sem_delete(&sync_sem); + + BT_DBG("opcode 0x%04x status 0x%02x", opcode, cmd(buf)->status); + + if (cmd(buf)->status) { + err = -EIO; + net_buf_unref(buf); + } else { + err = 0; + if (rsp) { + *rsp = buf; + } else { + net_buf_unref(buf); + } + } + + return err; +} + +static int bt_hci_stop_scanning(void) +{ + struct net_buf *buf, *rsp; + struct bt_hci_cp_le_set_scan_enable *scan_enable; + int err; + + if (!atomic_test_bit(bt_dev.flags, BT_DEV_SCANNING)) { + return -EALREADY; + } + + buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_SCAN_ENABLE, + sizeof(*scan_enable)); + if (!buf) { + return -ENOBUFS; + } + + scan_enable = net_buf_add(buf, sizeof(*scan_enable)); + memset(scan_enable, 0, sizeof(*scan_enable)); + scan_enable->filter_dup = BT_HCI_LE_SCAN_FILTER_DUP_DISABLE; + scan_enable->enable = BT_HCI_LE_SCAN_DISABLE; + + err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_SCAN_ENABLE, buf, &rsp); + if (err) { + return err; + } + + /* Update scan state in case of success (0) status */ + err = rsp->data[0]; + if (!err) { + atomic_clear_bit(bt_dev.flags, BT_DEV_SCANNING); + atomic_clear_bit(bt_dev.flags, BT_DEV_ACTIVE_SCAN); + } + + net_buf_unref(rsp); + + return err; +} + +static const bt_addr_le_t *find_id_addr(const bt_addr_le_t *addr) +{ + if (IS_ENABLED(CONFIG_BLUETOOTH_SMP)) { + struct bt_keys *keys; + + keys = bt_keys_find_irk(addr); + if (keys) { + BT_DBG("Identity %s matched RPA %s", + bt_addr_le_str(&keys->addr), + bt_addr_le_str(addr)); + return &keys->addr; + } + } + + return addr; +} + +static int set_advertise_enable(bool enable) +{ + struct net_buf *buf; + int err; + + buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_ADV_ENABLE, 1); + if (!buf) { + return -ENOBUFS; + } + + if (enable) { + net_buf_add_u8(buf, BT_HCI_LE_ADV_ENABLE); + } else { + net_buf_add_u8(buf, BT_HCI_LE_ADV_DISABLE); + } + + err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_ADV_ENABLE, buf, NULL); + if (err) { + return err; + } + + if (enable) { + atomic_set_bit(bt_dev.flags, BT_DEV_ADVERTISING); + } else { + atomic_clear_bit(bt_dev.flags, BT_DEV_ADVERTISING); + } + + return 0; +} + +static int set_random_address(const bt_addr_t *addr) +{ + struct net_buf *buf; + int err; + + BT_DBG("%s", bt_addr_str(addr)); + + /* Do nothing if we already have the right address */ + if (!bt_addr_cmp(addr, &bt_dev.random_addr.a)) { + return 0; + } + + buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_RANDOM_ADDRESS, sizeof(*addr)); + if (!buf) { + return -ENOBUFS; + } + + net_buf_add_mem(buf, addr, sizeof(*addr)); + + err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_RANDOM_ADDRESS, buf, NULL); + if (err) { + return err; + } + + bt_addr_copy(&bt_dev.random_addr.a, addr); + bt_dev.random_addr.type = BT_ADDR_LE_RANDOM; + return 0; +} + +#if defined(CONFIG_BLUETOOTH_PRIVACY) +/* this function sets new RPA only if current one is no longer valid */ +static int le_set_private_addr(void) +{ + bt_addr_t rpa; + int err; + + /* check if RPA is valid */ + if (atomic_test_bit(bt_dev.flags, BT_DEV_RPA_VALID)) { + return 0; + } + + err = bt_smp_create_rpa(bt_dev.irk, &rpa); + if (!err) { + err = set_random_address(&rpa); + if (!err) { + atomic_set_bit(bt_dev.flags, BT_DEV_RPA_VALID); + } + } + + /* restart timer even if failed to set new RPA */ + k_delayed_work_submit(&bt_dev.rpa_update, RPA_TIMEOUT); + + return err; +} + +static void rpa_timeout(struct k_work *work) +{ + BT_DBG(""); + + /* Invalidate RPA */ + atomic_clear_bit(bt_dev.flags, BT_DEV_RPA_VALID); + + /* + * we need to update rpa only if advertising is ongoing, with + * BT_DEV_KEEP_ADVERTISING flag is handled in disconnected event + */ + if (atomic_test_bit(bt_dev.flags, BT_DEV_ADVERTISING)) { + /* make sure new address is used */ + set_advertise_enable(false); + le_set_private_addr(); + set_advertise_enable(true); + } + + if (atomic_test_bit(bt_dev.flags, BT_DEV_ACTIVE_SCAN)) { + /* TODO do we need to toggle scan? */ + le_set_private_addr(); + } +} +#else +static int le_set_private_addr(void) +{ + bt_addr_t nrpa; + int err; + + err = bt_rand(nrpa.val, sizeof(nrpa.val)); + if (err) { + return err; + } + + nrpa.val[5] &= 0x3f; + + return set_random_address(&nrpa); +} +#endif + +#if defined(CONFIG_BLUETOOTH_CONN) +static void hci_acl(struct net_buf *buf) +{ + struct bt_hci_acl_hdr *hdr = (void *)buf->data; + uint16_t handle, len = sys_le16_to_cpu(hdr->len); + struct bt_conn *conn; + uint8_t flags; + + BT_DBG("buf %p", buf); + + handle = sys_le16_to_cpu(hdr->handle); + flags = bt_acl_flags(handle); + + acl(buf)->handle = bt_acl_handle(handle); + + net_buf_pull(buf, sizeof(*hdr)); + + BT_DBG("handle %u len %u flags %u", acl(buf)->handle, len, flags); + + if (buf->len != len) { + BT_ERR("ACL data length mismatch (%u != %u)", buf->len, len); + net_buf_unref(buf); + return; + } + + conn = bt_conn_lookup_handle(acl(buf)->handle); + if (!conn) { + BT_ERR("Unable to find conn for handle %u", acl(buf)->handle); + net_buf_unref(buf); + return; + } + + bt_conn_recv(conn, buf, flags); + bt_conn_unref(conn); +} + +static void hci_num_completed_packets(struct net_buf *buf) +{ + struct bt_hci_evt_num_completed_packets *evt = (void *)buf->data; + uint16_t i, num_handles = sys_le16_to_cpu(evt->num_handles); + + BT_DBG("num_handles %u", num_handles); + + for (i = 0; i < num_handles; i++) { + uint16_t handle, count; + struct bt_conn *conn; + unsigned int key; + + handle = sys_le16_to_cpu(evt->h[i].handle); + count = sys_le16_to_cpu(evt->h[i].count); + + BT_DBG("handle %u count %u", handle, count); + + key = irq_lock(); + + conn = bt_conn_lookup_handle(handle); + if (!conn) { + BT_ERR("No connection for handle %u", handle); + irq_unlock(key); + continue; + } + + if (conn->pending_pkts >= count) { + conn->pending_pkts -= count; + } else { + BT_ERR("completed packets mismatch: %u > %u", + count, conn->pending_pkts); + conn->pending_pkts = 0; + } + + irq_unlock(key); + + while (count--) { + k_sem_give(bt_conn_get_pkts(conn)); + } + + bt_conn_unref(conn); + } +} + +static int hci_le_create_conn(const struct bt_conn *conn) +{ + struct net_buf *buf; + struct bt_hci_cp_le_create_conn *cp; + + buf = bt_hci_cmd_create(BT_HCI_OP_LE_CREATE_CONN, sizeof(*cp)); + if (!buf) { + return -ENOBUFS; + } + + cp = net_buf_add(buf, sizeof(*cp)); + memset(cp, 0, sizeof(*cp)); + + /* Interval == window for continuous scanning */ + cp->scan_interval = sys_cpu_to_le16(BT_GAP_SCAN_FAST_INTERVAL); + cp->scan_window = cp->scan_interval; + + bt_addr_le_copy(&cp->peer_addr, &conn->le.resp_addr); + cp->own_addr_type = conn->le.init_addr.type; + cp->conn_interval_min = sys_cpu_to_le16(conn->le.interval_min); + cp->conn_interval_max = sys_cpu_to_le16(conn->le.interval_max); + cp->conn_latency = sys_cpu_to_le16(conn->le.latency); + cp->supervision_timeout = sys_cpu_to_le16(conn->le.timeout); + + return bt_hci_cmd_send_sync(BT_HCI_OP_LE_CREATE_CONN, buf, NULL); +} + +static void hci_disconn_complete(struct net_buf *buf) +{ + struct bt_hci_evt_disconn_complete *evt = (void *)buf->data; + uint16_t handle = sys_le16_to_cpu(evt->handle); + struct bt_conn *conn; + + BT_DBG("status %u handle %u reason %u", evt->status, handle, + evt->reason); + + if (evt->status) { + return; + } + + conn = bt_conn_lookup_handle(handle); + if (!conn) { + BT_ERR("Unable to look up conn with handle %u", handle); + goto advertise; + } + + conn->err = evt->reason; + + bt_conn_set_state(conn, BT_CONN_DISCONNECTED); + conn->handle = 0; + + if (conn->type != BT_CONN_TYPE_LE) { +#if defined(CONFIG_BLUETOOTH_BREDR) + /* + * If only for one connection session bond was set, clear keys + * database row for this connection. + */ + if (conn->type == BT_CONN_TYPE_BR && + atomic_test_and_clear_bit(conn->flags, BT_CONN_BR_NOBOND)) { + bt_keys_link_key_clear(conn->br.link_key); + } +#endif + bt_conn_unref(conn); + return; + } + + if (atomic_test_bit(conn->flags, BT_CONN_AUTO_CONNECT)) { + bt_conn_set_state(conn, BT_CONN_CONNECT_SCAN); + bt_le_scan_update(false); + } + + bt_conn_unref(conn); + +advertise: + if (atomic_test_bit(bt_dev.flags, BT_DEV_KEEP_ADVERTISING) && + !atomic_test_bit(bt_dev.flags, BT_DEV_ADVERTISING)) { + if (IS_ENABLED(CONFIG_BLUETOOTH_PRIVACY)) { + le_set_private_addr(); + } + + set_advertise_enable(true); + } +} + +static int hci_le_read_remote_features(struct bt_conn *conn) +{ + struct bt_hci_cp_le_read_remote_features *cp; + struct net_buf *buf; + + buf = bt_hci_cmd_create(BT_HCI_OP_LE_READ_REMOTE_FEATURES, + sizeof(*cp)); + if (!buf) { + return -ENOBUFS; + } + + cp = net_buf_add(buf, sizeof(*cp)); + cp->handle = sys_cpu_to_le16(conn->handle); + bt_hci_cmd_send(BT_HCI_OP_LE_READ_REMOTE_FEATURES, buf); + + return 0; +} + +static void update_conn_param(struct bt_conn *conn) +{ + /* + * Core 4.2 Vol 3, Part C, 9.3.12.2 + * The Peripheral device should not perform a Connection Parameter + * Update procedure within 5 s after establishing a connection. + */ + k_delayed_work_submit(&conn->le.update_work, + conn->role == BT_HCI_ROLE_MASTER ? K_NO_WAIT : + CONN_UPDATE_TIMEOUT); +} + +static void le_conn_complete(struct net_buf *buf) +{ + struct bt_hci_evt_le_conn_complete *evt = (void *)buf->data; + uint16_t handle = sys_le16_to_cpu(evt->handle); + const bt_addr_le_t *id_addr; + struct bt_conn *conn; + int err; + + BT_DBG("status %u handle %u role %u %s", evt->status, handle, + evt->role, bt_addr_le_str(&evt->peer_addr)); + + if (evt->status) { + /* + * if there was an error we are only interested in pending + * connection so there is no need to check ID address as + * only one connection can be in that state + * + * Depending on error code address might not be valid anyway. + */ + conn = bt_conn_lookup_state_le(NULL, BT_CONN_CONNECT); + if (!conn) { + return; + } + + conn->err = evt->status; + + bt_conn_set_state(conn, BT_CONN_DISCONNECTED); + + /* Drop the reference got by lookup call in CONNECT state. + * We are now in DISCONNECTED state since no successful LE + * link been made. + */ + bt_conn_unref(conn); + + return; + } + + id_addr = find_id_addr(&evt->peer_addr); + + /* + * Make lookup to check if there's a connection object in + * CONNECT state associated with passed peer LE address. + */ + conn = bt_conn_lookup_state_le(id_addr, BT_CONN_CONNECT); + + if (evt->role == BT_CONN_ROLE_SLAVE) { + /* + * clear advertising even if we are not able to add connection + * object to keep host in sync with controller state + */ + atomic_clear_bit(bt_dev.flags, BT_DEV_ADVERTISING); + + /* only for slave we may need to add new connection */ + if (!conn) { + conn = bt_conn_add_le(id_addr); + } + } + + if (!conn) { + BT_ERR("Unable to add new conn for handle %u", handle); + return; + } + + conn->handle = handle; + bt_addr_le_copy(&conn->le.dst, id_addr); + conn->le.interval = sys_le16_to_cpu(evt->interval); + conn->le.latency = sys_le16_to_cpu(evt->latency); + conn->le.timeout = sys_le16_to_cpu(evt->supv_timeout); + conn->role = evt->role; + + /* + * Use connection address (instead of identity address) as initiator + * or responder address. Only slave needs to be updated. For master all + * was set during outgoing connection creation. + */ + if (conn->role == BT_HCI_ROLE_SLAVE) { + bt_addr_le_copy(&conn->le.init_addr, &evt->peer_addr); + + /* TODO Handle the probability that random address could have + * been updated by rpa_timeout or numerous other places it is + * called in this file before le_conn_complete is processed + * here. + */ + if (IS_ENABLED(CONFIG_BLUETOOTH_PRIVACY)) { + bt_addr_le_copy(&conn->le.resp_addr, + &bt_dev.random_addr); + } else { + bt_addr_le_copy(&conn->le.resp_addr, &bt_dev.id_addr); + } + + /* if the controller supports, lets advertise for another + * slave connection. + * check for connectable advertising state is sufficient as + * this is how this le connection complete for slave occurred. + */ + if (atomic_test_bit(bt_dev.flags, BT_DEV_KEEP_ADVERTISING) && + BT_LE_STATES_SLAVE_CONN_ADV(bt_dev.le.states)) { + if (IS_ENABLED(CONFIG_BLUETOOTH_PRIVACY)) { + le_set_private_addr(); + } + + set_advertise_enable(true); + } + + } + + bt_conn_set_state(conn, BT_CONN_CONNECTED); + + /* + * it is possible that connection was disconnected directly from + * connected callback so we must check state before doing connection + * parameters update + */ + if (conn->state != BT_CONN_CONNECTED) { + goto done; + } + + if ((evt->role == BT_HCI_ROLE_MASTER) || + BT_FEAT_LE_SLAVE_FEATURE_XCHG(bt_dev.le.features)) { + err = hci_le_read_remote_features(conn); + if (!err) { + goto done; + } + } + + update_conn_param(conn); + +done: + /*only need unref for master*/ + if (evt->role == BT_HCI_ROLE_MASTER) + { + bt_conn_unref(conn); + } + bt_conn_unref(conn); + bt_le_scan_update(false); +} + +static void le_remote_feat_complete(struct net_buf *buf) +{ + struct bt_hci_ev_le_remote_feat_complete *evt = (void *)buf->data; + uint16_t handle = sys_le16_to_cpu(evt->handle); + struct bt_conn *conn; + + conn = bt_conn_lookup_handle(handle); + if (!conn) { + BT_ERR("Unable to lookup conn for handle %u", handle); + return; + } + + if (!evt->status) { + memcpy(conn->le.features, evt->features, + sizeof(conn->le.features)); + } + + update_conn_param(conn); + + bt_conn_unref(conn); +} + +bool bt_le_conn_params_valid(const struct bt_le_conn_param *param) +{ + /* All limits according to BT Core spec 5.0 [Vol 2, Part E, 7.8.12] */ + + if (param->interval_min > param->interval_max || + param->interval_min < 6 || param->interval_max > 3200) { + return false; + } + + if (param->latency > 499) { + return false; + } + + if (param->timeout < 10 || param->timeout > 3200 || + ((4 * param->timeout) <= + ((1 + param->latency) * param->interval_max))) { + return false; + } + + return true; +} + +static int le_conn_param_neg_reply(uint16_t handle, uint8_t reason) +{ + struct bt_hci_cp_le_conn_param_req_neg_reply *cp; + struct net_buf *buf; + + buf = bt_hci_cmd_create(BT_HCI_OP_LE_CONN_PARAM_REQ_NEG_REPLY, + sizeof(*cp)); + if (!buf) { + return -ENOBUFS; + } + + cp = net_buf_add(buf, sizeof(*cp)); + cp->handle = sys_cpu_to_le16(handle); + cp->reason = sys_cpu_to_le16(reason); + + return bt_hci_cmd_send(BT_HCI_OP_LE_CONN_PARAM_REQ_NEG_REPLY, buf); +} + +static int le_conn_param_req_reply(uint16_t handle, + const struct bt_le_conn_param *param) +{ + struct bt_hci_cp_le_conn_param_req_reply *cp; + struct net_buf *buf; + + buf = bt_hci_cmd_create(BT_HCI_OP_LE_CONN_PARAM_REQ_REPLY, sizeof(*cp)); + if (!buf) { + return -ENOBUFS; + } + + cp = net_buf_add(buf, sizeof(*cp)); + memset(cp, 0, sizeof(*cp)); + + cp->handle = sys_cpu_to_le16(handle); + cp->interval_min = sys_cpu_to_le16(param->interval_min); + cp->interval_max = sys_cpu_to_le16(param->interval_max); + cp->latency = sys_cpu_to_le16(param->latency); + cp->timeout = sys_cpu_to_le16(param->timeout); + + return bt_hci_cmd_send(BT_HCI_OP_LE_CONN_PARAM_REQ_REPLY, buf); +} + +static int le_conn_param_req(struct net_buf *buf) +{ + struct bt_hci_evt_le_conn_param_req *evt = (void *)buf->data; + struct bt_le_conn_param param; + struct bt_conn *conn; + uint16_t handle; + int err; + + handle = sys_le16_to_cpu(evt->handle); + param.interval_min = sys_le16_to_cpu(evt->interval_min); + param.interval_max = sys_le16_to_cpu(evt->interval_max); + param.latency = sys_le16_to_cpu(evt->latency); + param.timeout = sys_le16_to_cpu(evt->timeout); + + conn = bt_conn_lookup_handle(handle); + if (!conn) { + BT_ERR("Unable to lookup conn for handle %u", handle); + return le_conn_param_neg_reply(handle, + BT_HCI_ERR_UNKNOWN_CONN_ID); + } + + if (!le_param_req(conn, ¶m)) { + err = le_conn_param_neg_reply(handle, + BT_HCI_ERR_INVALID_LL_PARAMS); + } else { + err = le_conn_param_req_reply(handle, ¶m); + } + + bt_conn_unref(conn); + return err; +} + +static void le_conn_update_complete(struct net_buf *buf) +{ + struct bt_hci_evt_le_conn_update_complete *evt = (void *)buf->data; + struct bt_conn *conn; + uint16_t handle; + + handle = sys_le16_to_cpu(evt->handle); + + BT_DBG("status %u, handle %u", evt->status, handle); + + conn = bt_conn_lookup_handle(handle); + if (!conn) { + BT_ERR("Unable to lookup conn for handle %u", handle); + return; + } + + if (!evt->status) { + conn->le.interval = sys_le16_to_cpu(evt->interval); + conn->le.latency = sys_le16_to_cpu(evt->latency); + conn->le.timeout = sys_le16_to_cpu(evt->supv_timeout); + notify_le_param_updated(conn); + } + + bt_conn_unref(conn); +} + +static void check_pending_conn(const bt_addr_le_t *id_addr, + const bt_addr_le_t *addr, uint8_t evtype) +{ + struct bt_conn *conn; + int ret; + /* No connections are allowed during explicit scanning */ + if (atomic_test_bit(bt_dev.flags, BT_DEV_EXPLICIT_SCAN)) { + return; + } + + /* Return if event is not connectable */ + if (evtype != BT_LE_ADV_IND && evtype != BT_LE_ADV_DIRECT_IND) { + return; + } + + conn = bt_conn_lookup_state_le(id_addr, BT_CONN_CONNECT_SCAN); + if (!conn) { + return; + } + + ret = bt_hci_stop_scanning(); + if (ret) { + BT_ERR("stop scanning fail %d",ret); + goto failed; + } + + if (IS_ENABLED(CONFIG_BLUETOOTH_PRIVACY)) { + if (le_set_private_addr()) { + goto failed; + } + + bt_addr_le_copy(&conn->le.init_addr, &bt_dev.random_addr); + } else { + /* If Static Random address is used as Identity address we + * need to restore it before creating connection. Otherwise + * NRPA used for active scan could be used for connection. + */ + if (atomic_test_bit(bt_dev.flags, BT_DEV_ID_STATIC_RANDOM)) { + set_random_address(&bt_dev.id_addr.a); + } + + bt_addr_le_copy(&conn->le.init_addr, &bt_dev.id_addr); + } + + bt_addr_le_copy(&conn->le.resp_addr, addr); + + ret = hci_le_create_conn(conn); + if (ret) { + BT_ERR("create conn fail %d",ret); + goto failed; + } + + bt_conn_set_state(conn, BT_CONN_CONNECT); + bt_conn_unref(conn); + return; + +failed: + conn->err = BT_HCI_ERR_UNSPECIFIED; + bt_conn_set_state(conn, BT_CONN_DISCONNECTED); + bt_conn_unref(conn); + bt_le_scan_update(false); +} +#endif /* CONFIG_BLUETOOTH_CONN */ + +#if defined(CONFIG_BLUETOOTH_BREDR) +static void reset_pairing(struct bt_conn *conn) +{ + atomic_clear_bit(conn->flags, BT_CONN_BR_PAIRING); + atomic_clear_bit(conn->flags, BT_CONN_BR_PAIRING_INITIATOR); + atomic_clear_bit(conn->flags, BT_CONN_BR_LEGACY_SECURE); + + /* Reset required security level to current operational */ + conn->required_sec_level = conn->sec_level; +} + +static int reject_conn(const bt_addr_t *bdaddr, uint8_t reason) +{ + struct bt_hci_cp_reject_conn_req *cp; + struct net_buf *buf; + int err; + + buf = bt_hci_cmd_create(BT_HCI_OP_REJECT_CONN_REQ, sizeof(*cp)); + if (!buf) { + return -ENOBUFS; + } + + cp = net_buf_add(buf, sizeof(*cp)); + bt_addr_copy(&cp->bdaddr, bdaddr); + cp->reason = reason; + + err = bt_hci_cmd_send_sync(BT_HCI_OP_REJECT_CONN_REQ, buf, NULL); + if (err) { + return err; + } + + return 0; +} + +static int accept_sco_conn(const bt_addr_t *bdaddr, struct bt_conn *sco_conn) +{ + struct bt_hci_cp_accept_sync_conn_req *cp; + struct net_buf *buf; + int err; + + buf = bt_hci_cmd_create(BT_HCI_OP_ACCEPT_SYNC_CONN_REQ, sizeof(*cp)); + if (!buf) { + return -ENOBUFS; + } + + cp = net_buf_add(buf, sizeof(*cp)); + bt_addr_copy(&cp->bdaddr, bdaddr); + cp->pkt_type = sco_conn->sco.pkt_type; + cp->tx_bandwidth = 0x00001f40; + cp->rx_bandwidth = 0x00001f40; + cp->max_latency = 0x0007; + cp->retrans_effort = 0x01; + cp->content_format = BT_VOICE_CVSD_16BIT; + + err = bt_hci_cmd_send_sync(BT_HCI_OP_ACCEPT_SYNC_CONN_REQ, buf, NULL); + if (err) { + return err; + } + + return 0; +} + +static int accept_conn(const bt_addr_t *bdaddr) +{ + struct bt_hci_cp_accept_conn_req *cp; + struct net_buf *buf; + int err; + + buf = bt_hci_cmd_create(BT_HCI_OP_ACCEPT_CONN_REQ, sizeof(*cp)); + if (!buf) { + return -ENOBUFS; + } + + cp = net_buf_add(buf, sizeof(*cp)); + bt_addr_copy(&cp->bdaddr, bdaddr); + cp->role = BT_HCI_ROLE_SLAVE; + + err = bt_hci_cmd_send_sync(BT_HCI_OP_ACCEPT_CONN_REQ, buf, NULL); + if (err) { + return err; + } + + return 0; +} + +static void bt_esco_conn_req(struct bt_hci_evt_conn_request *evt) +{ + struct bt_conn *sco_conn; + + sco_conn = bt_conn_add_sco(&evt->bdaddr, evt->link_type); + if (!sco_conn) { + reject_conn(&evt->bdaddr, BT_HCI_ERR_INSUFFICIENT_RESOURCES); + return; + } + + accept_sco_conn(&evt->bdaddr, sco_conn); + sco_conn->role = BT_HCI_ROLE_SLAVE; + bt_conn_set_state(sco_conn, BT_CONN_CONNECT); + bt_conn_unref(sco_conn); +} + +static void conn_req(struct net_buf *buf) +{ + struct bt_hci_evt_conn_request *evt = (void *)buf->data; + struct bt_conn *conn; + + BT_DBG("conn req from %s, type 0x%02x", bt_addr_str(&evt->bdaddr), + evt->link_type); + + if (evt->link_type != BT_HCI_ACL) { + bt_esco_conn_req(evt); + return; + } + + conn = bt_conn_add_br(&evt->bdaddr); + if (!conn) { + reject_conn(&evt->bdaddr, BT_HCI_ERR_INSUFFICIENT_RESOURCES); + return; + } + + accept_conn(&evt->bdaddr); + conn->role = BT_HCI_ROLE_SLAVE; + bt_conn_set_state(conn, BT_CONN_CONNECT); + bt_conn_unref(conn); +} + +static void update_sec_level_br(struct bt_conn *conn) +{ + if (!conn->encrypt) { + conn->sec_level = BT_SECURITY_LOW; + return; + } + + if (conn->br.link_key) { + if (atomic_test_bit(conn->br.link_key->flags, + BT_LINK_KEY_AUTHENTICATED)) { + if (conn->encrypt == 0x02) { + conn->sec_level = BT_SECURITY_FIPS; + } else { + conn->sec_level = BT_SECURITY_HIGH; + } + } else { + conn->sec_level = BT_SECURITY_MEDIUM; + } + } else { + BT_WARN("No BR/EDR link key found"); + conn->sec_level = BT_SECURITY_MEDIUM; + } + + if (conn->required_sec_level > conn->sec_level) { + BT_ERR("Failed to set required security level"); + bt_conn_disconnect(conn, BT_HCI_ERR_AUTHENTICATION_FAIL); + } +} + +static void conn_complete(struct net_buf *buf) +{ + struct bt_hci_evt_conn_complete *evt = (void *)buf->data; + struct bt_conn *conn; + struct bt_hci_cp_read_remote_features *cp; + uint16_t handle = sys_le16_to_cpu(evt->handle); + + BT_DBG("status 0x%02x, handle %u, type 0x%02x", evt->status, handle, + evt->link_type); + + conn = bt_conn_lookup_addr_br(&evt->bdaddr); + if (!conn) { + BT_ERR("Unable to find conn for %s", bt_addr_str(&evt->bdaddr)); + return; + } + + if (evt->status) { + conn->err = evt->status; + bt_conn_set_state(conn, BT_CONN_DISCONNECTED); + bt_conn_unref(conn); + return; + } + + conn->handle = handle; + conn->encrypt = evt->encr_enabled; + update_sec_level_br(conn); + bt_conn_set_state(conn, BT_CONN_CONNECTED); + bt_conn_unref(conn); + + buf = bt_hci_cmd_create(BT_HCI_OP_READ_REMOTE_FEATURES, sizeof(*cp)); + if (!buf) { + return; + } + + cp = net_buf_add(buf, sizeof(*cp)); + cp->handle = evt->handle; + + bt_hci_cmd_send_sync(BT_HCI_OP_READ_REMOTE_FEATURES, buf, NULL); +} + +static void pin_code_req(struct net_buf *buf) +{ + struct bt_hci_evt_pin_code_req *evt = (void *)buf->data; + struct bt_conn *conn; + + BT_DBG(""); + + conn = bt_conn_lookup_addr_br(&evt->bdaddr); + if (!conn) { + BT_ERR("Can't find conn for %s", bt_addr_str(&evt->bdaddr)); + return; + } + + bt_conn_pin_code_req(conn); + bt_conn_unref(conn); +} + +static void link_key_notify(struct net_buf *buf) +{ + struct bt_hci_ev_link_key_notify *evt = (void *)buf->data; + struct bt_conn *conn; + + conn = bt_conn_lookup_addr_br(&evt->bdaddr); + if (!conn) { + BT_ERR("Can't find conn for %s", bt_addr_str(&evt->bdaddr)); + return; + } + + BT_DBG("%s, link type 0x%02x", bt_addr_str(&evt->bdaddr), evt->key_type); + + if (!conn->br.link_key) { + conn->br.link_key = bt_keys_get_link_key(&evt->bdaddr); + } + if (!conn->br.link_key) { + BT_ERR("Can't update keys for %s", bt_addr_str(&evt->bdaddr)); + bt_conn_unref(conn); + return; + } + + /* clear any old Link Key flags */ + atomic_set(conn->br.link_key->flags, 0); + + switch (evt->key_type) { + case BT_LK_COMBINATION: + /* + * Setting Combination Link Key as AUTHENTICATED means it was + * successfully generated by 16 digits wide PIN code. + */ + if (atomic_test_and_clear_bit(conn->flags, + BT_CONN_BR_LEGACY_SECURE)) { + atomic_set_bit(conn->br.link_key->flags, + BT_LINK_KEY_AUTHENTICATED); + } + memcpy(conn->br.link_key->val, evt->link_key, 16); + break; + case BT_LK_AUTH_COMBINATION_P192: + atomic_set_bit(conn->br.link_key->flags, + BT_LINK_KEY_AUTHENTICATED); + /* fall through */ + case BT_LK_UNAUTH_COMBINATION_P192: + /* Mark no-bond so that link-key is removed on disconnection */ + if (bt_conn_ssp_get_auth(conn) < BT_HCI_DEDICATED_BONDING) { + atomic_set_bit(conn->flags, BT_CONN_BR_NOBOND); + } + + memcpy(conn->br.link_key->val, evt->link_key, 16); + break; + case BT_LK_AUTH_COMBINATION_P256: + atomic_set_bit(conn->br.link_key->flags, + BT_LINK_KEY_AUTHENTICATED); + /* fall through */ + case BT_LK_UNAUTH_COMBINATION_P256: + atomic_set_bit(conn->br.link_key->flags, BT_LINK_KEY_SC); + + /* Mark no-bond so that link-key is removed on disconnection */ + if (bt_conn_ssp_get_auth(conn) < BT_HCI_DEDICATED_BONDING) { + atomic_set_bit(conn->flags, BT_CONN_BR_NOBOND); + } + + memcpy(conn->br.link_key->val, evt->link_key, 16); + break; + default: + BT_WARN("Unsupported Link Key type %u", evt->key_type); + memset(conn->br.link_key->val, 0, + sizeof(conn->br.link_key->val)); + break; + } + + bt_conn_unref(conn); +} + +static void link_key_neg_reply(const bt_addr_t *bdaddr) +{ + struct bt_hci_cp_link_key_neg_reply *cp; + struct net_buf *buf; + + BT_DBG(""); + + buf = bt_hci_cmd_create(BT_HCI_OP_LINK_KEY_NEG_REPLY, sizeof(*cp)); + if (!buf) { + BT_ERR("Out of command buffers"); + return; + } + + cp = net_buf_add(buf, sizeof(*cp)); + bt_addr_copy(&cp->bdaddr, bdaddr); + bt_hci_cmd_send_sync(BT_HCI_OP_LINK_KEY_NEG_REPLY, buf, NULL); +} + +static void link_key_reply(const bt_addr_t *bdaddr, const uint8_t *lk) +{ + struct bt_hci_cp_link_key_reply *cp; + struct net_buf *buf; + + BT_DBG(""); + + buf = bt_hci_cmd_create(BT_HCI_OP_LINK_KEY_REPLY, sizeof(*cp)); + if (!buf) { + BT_ERR("Out of command buffers"); + return; + } + + cp = net_buf_add(buf, sizeof(*cp)); + bt_addr_copy(&cp->bdaddr, bdaddr); + memcpy(cp->link_key, lk, 16); + bt_hci_cmd_send_sync(BT_HCI_OP_LINK_KEY_REPLY, buf, NULL); +} + +static void link_key_req(struct net_buf *buf) +{ + struct bt_hci_evt_link_key_req *evt = (void *)buf->data; + struct bt_conn *conn; + + BT_DBG("%s", bt_addr_str(&evt->bdaddr)); + + conn = bt_conn_lookup_addr_br(&evt->bdaddr); + if (!conn) { + BT_ERR("Can't find conn for %s", bt_addr_str(&evt->bdaddr)); + link_key_neg_reply(&evt->bdaddr); + return; + } + + if (!conn->br.link_key) { + conn->br.link_key = bt_keys_find_link_key(&evt->bdaddr); + } + + if (!conn->br.link_key) { + link_key_neg_reply(&evt->bdaddr); + bt_conn_unref(conn); + return; + } + + /* + * Enforce regenerate by controller stronger link key since found one + * in database not covers requested security level. + */ + if (!atomic_test_bit(conn->br.link_key->flags, + BT_LINK_KEY_AUTHENTICATED) && + conn->required_sec_level > BT_SECURITY_MEDIUM) { + link_key_neg_reply(&evt->bdaddr); + bt_conn_unref(conn); + return; + } + + link_key_reply(&evt->bdaddr, conn->br.link_key->val); + bt_conn_unref(conn); +} + +static void io_capa_neg_reply(const bt_addr_t *bdaddr, const uint8_t reason) +{ + struct bt_hci_cp_io_capability_neg_reply *cp; + struct net_buf *resp_buf; + + resp_buf = bt_hci_cmd_create(BT_HCI_OP_IO_CAPABILITY_NEG_REPLY, + sizeof(*cp)); + if (!resp_buf) { + BT_ERR("Out of command buffers"); + return; + } + + cp = net_buf_add(resp_buf, sizeof(*cp)); + bt_addr_copy(&cp->bdaddr, bdaddr); + cp->reason = reason; + bt_hci_cmd_send_sync(BT_HCI_OP_IO_CAPABILITY_NEG_REPLY, resp_buf, NULL); +} + +static void io_capa_resp(struct net_buf *buf) +{ + struct bt_hci_evt_io_capa_resp *evt = (void *)buf->data; + struct bt_conn *conn; + + BT_DBG("remote %s, IOcapa 0x%02x, auth 0x%02x", + bt_addr_str(&evt->bdaddr), evt->capability, evt->authentication); + + if (evt->authentication > BT_HCI_GENERAL_BONDING_MITM) { + BT_ERR("Invalid remote authentication requirements"); + io_capa_neg_reply(&evt->bdaddr, + BT_HCI_ERR_UNSUPP_FEATURE_PARAMS_VAL); + return; + } + + if (evt->capability > BT_IO_NO_INPUT_OUTPUT) { + BT_ERR("Invalid remote io capability requirements"); + io_capa_neg_reply(&evt->bdaddr, + BT_HCI_ERR_UNSUPP_FEATURE_PARAMS_VAL); + return; + } + + conn = bt_conn_lookup_addr_br(&evt->bdaddr); + if (!conn) { + BT_ERR("Unable to find conn for %s", bt_addr_str(&evt->bdaddr)); + return; + } + + conn->br.remote_io_capa = evt->capability; + conn->br.remote_auth = evt->authentication; + atomic_set_bit(conn->flags, BT_CONN_BR_PAIRING); + bt_conn_unref(conn); +} + +static void io_capa_req(struct net_buf *buf) +{ + struct bt_hci_evt_io_capa_req *evt = (void *)buf->data; + struct net_buf *resp_buf; + struct bt_conn *conn; + struct bt_hci_cp_io_capability_reply *cp; + uint8_t auth; + + BT_DBG(""); + + conn = bt_conn_lookup_addr_br(&evt->bdaddr); + if (!conn) { + BT_ERR("Can't find conn for %s", bt_addr_str(&evt->bdaddr)); + return; + } + + resp_buf = bt_hci_cmd_create(BT_HCI_OP_IO_CAPABILITY_REPLY, + sizeof(*cp)); + if (!resp_buf) { + BT_ERR("Out of command buffers"); + bt_conn_unref(conn); + return; + } + + /* + * Set authentication requirements when acting as pairing initiator to + * 'dedicated bond' with MITM protection set if local IO capa + * potentially allows it, and for acceptor, based on local IO capa and + * remote's authentication set. + */ + if (atomic_test_bit(conn->flags, BT_CONN_BR_PAIRING_INITIATOR)) { + if (bt_conn_get_io_capa() != BT_IO_NO_INPUT_OUTPUT) { + auth = BT_HCI_DEDICATED_BONDING_MITM; + } else { + auth = BT_HCI_DEDICATED_BONDING; + } + } else { + auth = bt_conn_ssp_get_auth(conn); + } + + cp = net_buf_add(resp_buf, sizeof(*cp)); + bt_addr_copy(&cp->bdaddr, &evt->bdaddr); + cp->capability = bt_conn_get_io_capa(); + cp->authentication = auth; + cp->oob_data = 0; + bt_hci_cmd_send_sync(BT_HCI_OP_IO_CAPABILITY_REPLY, resp_buf, NULL); + bt_conn_unref(conn); +} + +static void ssp_complete(struct net_buf *buf) +{ + struct bt_hci_evt_ssp_complete *evt = (void *)buf->data; + struct bt_conn *conn; + + BT_DBG("status %u", evt->status); + + conn = bt_conn_lookup_addr_br(&evt->bdaddr); + if (!conn) { + BT_ERR("Can't find conn for %s", bt_addr_str(&evt->bdaddr)); + return; + } + + if (evt->status) { + bt_conn_disconnect(conn, BT_HCI_ERR_AUTHENTICATION_FAIL); + } + + bt_conn_unref(conn); +} + +static void user_confirm_req(struct net_buf *buf) +{ + struct bt_hci_evt_user_confirm_req *evt = (void *)buf->data; + struct bt_conn *conn; + + conn = bt_conn_lookup_addr_br(&evt->bdaddr); + if (!conn) { + BT_ERR("Can't find conn for %s", bt_addr_str(&evt->bdaddr)); + return; + } + + bt_conn_ssp_auth(conn, sys_le32_to_cpu(evt->passkey)); + bt_conn_unref(conn); +} + +static void user_passkey_notify(struct net_buf *buf) +{ + struct bt_hci_evt_user_passkey_notify *evt = (void *)buf->data; + struct bt_conn *conn; + + BT_DBG(""); + + conn = bt_conn_lookup_addr_br(&evt->bdaddr); + if (!conn) { + BT_ERR("Can't find conn for %s", bt_addr_str(&evt->bdaddr)); + return; + } + + bt_conn_ssp_auth(conn, sys_le32_to_cpu(evt->passkey)); + bt_conn_unref(conn); +} + +static void user_passkey_req(struct net_buf *buf) +{ + struct bt_hci_evt_user_passkey_req *evt = (void *)buf->data; + struct bt_conn *conn; + + conn = bt_conn_lookup_addr_br(&evt->bdaddr); + if (!conn) { + BT_ERR("Can't find conn for %s", bt_addr_str(&evt->bdaddr)); + return; + } + + bt_conn_ssp_auth(conn, 0); + bt_conn_unref(conn); +} + +struct discovery_priv { + uint16_t clock_offset; + uint8_t pscan_rep_mode; + uint8_t resolving; +} __packed; + +static int request_name(const bt_addr_t *addr, uint8_t pscan, uint16_t offset) +{ + struct bt_hci_cp_remote_name_request *cp; + struct net_buf *buf; + + buf = bt_hci_cmd_create(BT_HCI_OP_REMOTE_NAME_REQUEST, sizeof(*cp)); + if (!buf) { + return -ENOBUFS; + } + + cp = net_buf_add(buf, sizeof(*cp)); + + bt_addr_copy(&cp->bdaddr, addr); + cp->pscan_rep_mode = pscan; + cp->reserved = 0x00; /* reserver, should be set to 0x00 */ + cp->clock_offset = offset; + + return bt_hci_cmd_send_sync(BT_HCI_OP_REMOTE_NAME_REQUEST, buf, NULL); +} + +#define EIR_SHORT_NAME 0x08 +#define EIR_COMPLETE_NAME 0x09 + +static bool eir_has_name(const uint8_t *eir) +{ + int len = 240; + + while (len) { + if (len < 2) { + break; + }; + + /* Look for early termination */ + if (!eir[0]) { + break; + } + + /* Check if field length is correct */ + if (eir[0] > len - 1) { + break; + } + + switch (eir[1]) { + case EIR_SHORT_NAME: + case EIR_COMPLETE_NAME: + if (eir[0] > 1) { + return true; + } + break; + default: + break; + } + + /* Parse next AD Structure */ + len -= eir[0] + 1; + eir += eir[0] + 1; + } + + return false; +} + +static void report_discovery_results(void) +{ + bool resolving_names = false; + int i; + + for (i = 0; i < discovery_results_count; i++) { + struct discovery_priv *priv; + + priv = (struct discovery_priv *)&discovery_results[i]._priv; + + if (eir_has_name(discovery_results[i].eir)) { + continue; + } + + if (request_name(&discovery_results[i].addr, + priv->pscan_rep_mode, priv->clock_offset)) { + continue; + } + + priv->resolving = 1; + resolving_names = true; + } + + if (resolving_names) { + return; + } + + atomic_clear_bit(bt_dev.flags, BT_DEV_INQUIRY); + + discovery_cb(discovery_results, discovery_results_count); + + discovery_cb = NULL; + discovery_results = NULL; + discovery_results_size = 0; + discovery_results_count = 0; +} + +static void inquiry_complete(struct net_buf *buf) +{ + struct bt_hci_evt_inquiry_complete *evt = (void *)buf->data; + + if (evt->status) { + BT_ERR("Failed to complete inquiry"); + } + + report_discovery_results(); +} + +static struct bt_br_discovery_result *get_result_slot(const bt_addr_t *addr, + int8_t rssi) +{ + struct bt_br_discovery_result *result = NULL; + size_t i; + + /* check if already present in results */ + for (i = 0; i < discovery_results_count; i++) { + if (!bt_addr_cmp(addr, &discovery_results[i].addr)) { + return &discovery_results[i]; + } + } + + /* Pick a new slot (if available) */ + if (discovery_results_count < discovery_results_size) { + bt_addr_copy(&discovery_results[discovery_results_count].addr, + addr); + return &discovery_results[discovery_results_count++]; + } + + /* ignore if invalid RSSI */ + if (rssi == 0xff) { + return NULL; + } + + /* + * Pick slot with smallest RSSI that is smaller then passed RSSI + * TODO handle TX if present + */ + for (i = 0; i < discovery_results_size; i++) { + if (discovery_results[i].rssi > rssi) { + continue; + } + + if (!result || result->rssi > discovery_results[i].rssi) { + result = &discovery_results[i]; + } + } + + if (result) { + BT_DBG("Reusing slot (old %s rssi %d dBm)", + bt_addr_str(&result->addr), result->rssi); + + bt_addr_copy(&result->addr, addr); + } + + return result; +} + +static void inquiry_result_with_rssi(struct net_buf *buf) +{ + struct bt_hci_evt_inquiry_result_with_rssi *evt; + uint8_t num_reports = net_buf_pull_u8(buf); + + if (!atomic_test_bit(bt_dev.flags, BT_DEV_INQUIRY)) { + return; + } + + BT_DBG("number of results: %u", num_reports); + + evt = (void *)buf->data; + while (num_reports--) { + struct bt_br_discovery_result *result; + struct discovery_priv *priv; + + BT_DBG("%s rssi %d dBm", bt_addr_str(&evt->addr), evt->rssi); + + result = get_result_slot(&evt->addr, evt->rssi); + if (!result) { + return; + } + + priv = (struct discovery_priv *)&result->_priv; + priv->pscan_rep_mode = evt->pscan_rep_mode; + priv->clock_offset = evt->clock_offset; + + memcpy(result->cod, evt->cod, 3); + result->rssi = evt->rssi; + + /* we could reuse slot so make sure EIR is cleared */ + memset(result->eir, 0, sizeof(result->eir)); + + /* + * Get next report iteration by moving pointer to right offset + * in buf according to spec 4.2, Vol 2, Part E, 7.7.33. + */ + evt = net_buf_pull(buf, sizeof(*evt)); + } +} + +static void extended_inquiry_result(struct net_buf *buf) +{ + struct bt_hci_evt_extended_inquiry_result *evt = (void *)buf->data; + struct bt_br_discovery_result *result; + struct discovery_priv *priv; + + if (!atomic_test_bit(bt_dev.flags, BT_DEV_INQUIRY)) { + return; + } + + BT_DBG("%s rssi %d dBm", bt_addr_str(&evt->addr), evt->rssi); + + result = get_result_slot(&evt->addr, evt->rssi); + if (!result) { + return; + } + + priv = (struct discovery_priv *)&result->_priv; + priv->pscan_rep_mode = evt->pscan_rep_mode; + priv->clock_offset = evt->clock_offset; + + result->rssi = evt->rssi; + memcpy(result->cod, evt->cod, 3); + memcpy(result->eir, evt->eir, sizeof(result->eir)); +} + +static void remote_name_request_complete(struct net_buf *buf) +{ + struct bt_hci_evt_remote_name_req_complete *evt = (void *)buf->data; + struct bt_br_discovery_result *result; + struct discovery_priv *priv; + int eir_len = 240; + uint8_t *eir; + int i; + + result = get_result_slot(&evt->bdaddr, 0xff); + if (!result) { + return; + } + + priv = (struct discovery_priv *)&result->_priv; + priv->resolving = 0; + + if (evt->status) { + goto check_names; + } + + eir = result->eir; + + while (eir_len) { + if (eir_len < 2) { + break; + }; + + /* Look for early termination */ + if (!eir[0]) { + size_t name_len; + + eir_len -= 2; + + /* name is null terminated */ + name_len = strlen((const char *)evt->name); + + if (name_len > eir_len) { + eir[0] = eir_len + 1; + eir[1] = EIR_SHORT_NAME; + } else { + eir[0] = name_len + 1; + eir[1] = EIR_SHORT_NAME; + } + + memcpy(&eir[2], evt->name, eir[0] - 1); + + break; + } + + /* Check if field length is correct */ + if (eir[0] > eir_len - 1) { + break; + } + + /* next EIR Structure */ + eir_len -= eir[0] + 1; + eir += eir[0] + 1; + } + +check_names: + /* if still waiting for names */ + for (i = 0; i < discovery_results_count; i++) { + struct discovery_priv *priv; + + priv = (struct discovery_priv *)&discovery_results[i]._priv; + + if (priv->resolving) { + return; + } + } + + /* all names resolved, report discovery results */ + atomic_clear_bit(bt_dev.flags, BT_DEV_INQUIRY); + + discovery_cb(discovery_results, discovery_results_count); + + discovery_cb = NULL; + discovery_results = NULL; + discovery_results_size = 0; + discovery_results_count = 0; +} + +static void link_encr(const uint16_t handle) +{ + struct bt_hci_cp_set_conn_encrypt *encr; + struct net_buf *buf; + + BT_DBG(""); + + buf = bt_hci_cmd_create(BT_HCI_OP_SET_CONN_ENCRYPT, sizeof(*encr)); + if (!buf) { + BT_ERR("Out of command buffers"); + return; + } + + encr = net_buf_add(buf, sizeof(*encr)); + encr->handle = sys_cpu_to_le16(handle); + encr->encrypt = 0x01; + + bt_hci_cmd_send_sync(BT_HCI_OP_SET_CONN_ENCRYPT, buf, NULL); +} + +static void auth_complete(struct net_buf *buf) +{ + struct bt_hci_evt_auth_complete *evt = (void *)buf->data; + struct bt_conn *conn; + uint16_t handle = sys_le16_to_cpu(evt->handle); + + BT_DBG("status %u, handle %u", evt->status, handle); + + conn = bt_conn_lookup_handle(handle); + if (!conn) { + BT_ERR("Can't find conn for handle %u", handle); + return; + } + + if (evt->status) { + if (conn->state == BT_CONN_CONNECTED) { + /* + * Inform layers above HCI about non-zero authentication + * status to make them able cleanup pending jobs. + */ + bt_l2cap_encrypt_change(conn, evt->status); + } + reset_pairing(conn); + } else { + link_encr(handle); + } + + bt_conn_unref(conn); +} + +static void read_remote_features_complete(struct net_buf *buf) +{ + struct bt_hci_evt_remote_features *evt = (void *)buf->data; + uint16_t handle = sys_le16_to_cpu(evt->handle); + struct bt_hci_cp_read_remote_ext_features *cp; + struct bt_conn *conn; + + BT_DBG("status %u handle %u", evt->status, handle); + + conn = bt_conn_lookup_handle(handle); + if (!conn) { + BT_ERR("Can't find conn for handle %u", handle); + return; + } + + if (evt->status) { + goto done; + } + + memcpy(conn->br.features[0], evt->features, sizeof(evt->features)); + + if (!BT_FEAT_EXT_FEATURES(conn->br.features)) { + goto done; + } + + buf = bt_hci_cmd_create(BT_HCI_OP_READ_REMOTE_EXT_FEATURES, + sizeof(*cp)); + if (!buf) { + goto done; + } + + /* Read remote host features (page 1) */ + cp = net_buf_add(buf, sizeof(*cp)); + cp->handle = evt->handle; + cp->page = 0x01; + + bt_hci_cmd_send_sync(BT_HCI_OP_READ_REMOTE_EXT_FEATURES, buf, NULL); + +done: + bt_conn_unref(conn); +} + +static void read_remote_ext_features_complete(struct net_buf *buf) +{ + struct bt_hci_evt_remote_ext_features *evt = (void *)buf->data; + uint16_t handle = sys_le16_to_cpu(evt->handle); + struct bt_conn *conn; + + BT_DBG("status %u handle %u", evt->status, handle); + + conn = bt_conn_lookup_handle(handle); + if (!conn) { + BT_ERR("Can't find conn for handle %u", handle); + return; + } + + if (!evt->status && evt->page == 0x01) { + memcpy(conn->br.features[1], evt->features, + sizeof(conn->br.features[1])); + } + + bt_conn_unref(conn); +} + +static void role_change(struct net_buf *buf) +{ + struct bt_hci_evt_role_change *evt = (void *)buf->data; + struct bt_conn *conn; + + BT_DBG("status %u role %u addr %s", evt->status, evt->role, + bt_addr_str(&evt->bdaddr)); + + if (evt->status) { + return; + } + + conn = bt_conn_lookup_addr_br(&evt->bdaddr); + if (!conn) { + BT_ERR("Can't find conn for %s", bt_addr_str(&evt->bdaddr)); + return; + } + + if (evt->role) { + conn->role = BT_CONN_ROLE_SLAVE; + } else { + conn->role = BT_CONN_ROLE_MASTER; + } + + bt_conn_unref(conn); +} +#endif /* CONFIG_BLUETOOTH_BREDR */ + +#if defined(CONFIG_BLUETOOTH_SMP) +static void update_sec_level(struct bt_conn *conn) +{ + if (!conn->encrypt) { + conn->sec_level = BT_SECURITY_LOW; + return; + } + + if (conn->le.keys && atomic_test_bit(conn->le.keys->flags, + BT_KEYS_AUTHENTICATED)) { + if (conn->le.keys->keys & BT_KEYS_LTK_P256) { + conn->sec_level = BT_SECURITY_FIPS; + } else { + conn->sec_level = BT_SECURITY_HIGH; + } + } else { + conn->sec_level = BT_SECURITY_MEDIUM; + } + + if (conn->required_sec_level > conn->sec_level) { + BT_ERR("Failed to set required security level"); + bt_conn_disconnect(conn, BT_HCI_ERR_AUTHENTICATION_FAIL); + } +} +#endif /* CONFIG_BLUETOOTH_SMP */ + +#if defined(CONFIG_BLUETOOTH_SMP) || defined(CONFIG_BLUETOOTH_BREDR) +static void hci_encrypt_change(struct net_buf *buf) +{ + struct bt_hci_evt_encrypt_change *evt = (void *)buf->data; + uint16_t handle = sys_le16_to_cpu(evt->handle); + struct bt_conn *conn; + + BT_DBG("status %u handle %u encrypt 0x%02x", evt->status, handle, + evt->encrypt); + + conn = bt_conn_lookup_handle(handle); + if (!conn) { + BT_ERR("Unable to look up conn with handle %u", handle); + return; + } + + if (evt->status) { + /* TODO report error */ + if (conn->type == BT_CONN_TYPE_LE) { + /* reset required security level in case of error */ + conn->required_sec_level = conn->sec_level; +#if defined(CONFIG_BLUETOOTH_BREDR) + } else { + bt_l2cap_encrypt_change(conn, evt->status); + reset_pairing(conn); +#endif /* CONFIG_BLUETOOTH_BREDR */ + } + bt_conn_unref(conn); + return; + } + + conn->encrypt = evt->encrypt; + +#if defined(CONFIG_BLUETOOTH_SMP) + if (conn->type == BT_CONN_TYPE_LE) { + /* + * we update keys properties only on successful encryption to + * avoid losing valid keys if encryption was not successful. + * + * Update keys with last pairing info for proper sec level + * update. This is done only for LE transport, for BR/EDR keys + * are updated on HCI 'Link Key Notification Event' + */ + if (conn->encrypt) { + bt_smp_update_keys(conn); + } + update_sec_level(conn); + } +#endif /* CONFIG_BLUETOOTH_SMP */ +#if defined(CONFIG_BLUETOOTH_BREDR) + if (conn->type == BT_CONN_TYPE_BR) { + update_sec_level_br(conn); + + if (IS_ENABLED(CONFIG_BLUETOOTH_SMP)) { + /* + * Start SMP over BR/EDR if we are pairing and are + * master on the link + */ + if (atomic_test_bit(conn->flags, BT_CONN_BR_PAIRING) && + conn->role == BT_CONN_ROLE_MASTER) { + bt_smp_br_send_pairing_req(conn); + } + } + + reset_pairing(conn); + } +#endif /* CONFIG_BLUETOOTH_BREDR */ + + bt_l2cap_encrypt_change(conn, evt->status); + bt_conn_security_changed(conn); + + bt_conn_unref(conn); +} + +static void hci_encrypt_key_refresh_complete(struct net_buf *buf) +{ + struct bt_hci_evt_encrypt_key_refresh_complete *evt = (void *)buf->data; + struct bt_conn *conn; + uint16_t handle; + + handle = sys_le16_to_cpu(evt->handle); + + BT_DBG("status %u handle %u", evt->status, handle); + + conn = bt_conn_lookup_handle(handle); + if (!conn) { + BT_ERR("Unable to look up conn with handle %u", handle); + return; + } + + if (evt->status) { + bt_l2cap_encrypt_change(conn, evt->status); + return; + } + + /* + * Update keys with last pairing info for proper sec level update. + * This is done only for LE transport. For BR/EDR transport keys are + * updated on HCI 'Link Key Notification Event', therefore update here + * only security level based on available keys and encryption state. + */ +#if defined(CONFIG_BLUETOOTH_SMP) + if (conn->type == BT_CONN_TYPE_LE) { + bt_smp_update_keys(conn); + update_sec_level(conn); + } +#endif /* CONFIG_BLUETOOTH_SMP */ +#if defined(CONFIG_BLUETOOTH_BREDR) + if (conn->type == BT_CONN_TYPE_BR) { + update_sec_level_br(conn); + } +#endif /* CONFIG_BLUETOOTH_BREDR */ + + bt_l2cap_encrypt_change(conn, evt->status); + bt_conn_security_changed(conn); + bt_conn_unref(conn); +} +#endif /* CONFIG_BLUETOOTH_SMP || CONFIG_BLUETOOTH_BREDR */ + +#if defined(CONFIG_BLUETOOTH_SMP) +static void le_ltk_request(struct net_buf *buf) +{ + struct bt_hci_evt_le_ltk_request *evt = (void *)buf->data; + struct bt_hci_cp_le_ltk_req_neg_reply *cp; + struct bt_conn *conn; + uint16_t handle; + uint8_t tk[16]; + + handle = sys_le16_to_cpu(evt->handle); + + BT_DBG("handle %u", handle); + + conn = bt_conn_lookup_handle(handle); + if (!conn) { + BT_ERR("Unable to lookup conn for handle %u", handle); + return; + } + + /* + * if TK is present use it, that means pairing is in progress and + * we should use new TK for encryption + * + * Both legacy STK and LE SC LTK have rand and ediv equal to zero. + */ + if (evt->rand == 0 && evt->ediv == 0 && bt_smp_get_tk(conn, tk)) { + struct bt_hci_cp_le_ltk_req_reply *cp; + + buf = bt_hci_cmd_create(BT_HCI_OP_LE_LTK_REQ_REPLY, + sizeof(*cp)); + if (!buf) { + BT_ERR("Out of command buffers"); + goto done; + } + + cp = net_buf_add(buf, sizeof(*cp)); + cp->handle = evt->handle; + memcpy(cp->ltk, tk, sizeof(cp->ltk)); + + bt_hci_cmd_send(BT_HCI_OP_LE_LTK_REQ_REPLY, buf); + goto done; + } + + if (!conn->le.keys) { + conn->le.keys = bt_keys_find(BT_KEYS_LTK_P256, &conn->le.dst); + if (!conn->le.keys) { + conn->le.keys = bt_keys_find(BT_KEYS_SLAVE_LTK, + &conn->le.dst); + } + } + + if (conn->le.keys && (conn->le.keys->keys & BT_KEYS_LTK_P256) && + evt->rand == 0 && evt->ediv == 0) { + struct bt_hci_cp_le_ltk_req_reply *cp; + + buf = bt_hci_cmd_create(BT_HCI_OP_LE_LTK_REQ_REPLY, + sizeof(*cp)); + if (!buf) { + BT_ERR("Out of command buffers"); + goto done; + } + + cp = net_buf_add(buf, sizeof(*cp)); + cp->handle = evt->handle; + + /* use only enc_size bytes of key for encryption */ + memcpy(cp->ltk, conn->le.keys->ltk.val, + conn->le.keys->enc_size); + if (conn->le.keys->enc_size < sizeof(cp->ltk)) { + memset(cp->ltk + conn->le.keys->enc_size, 0, + sizeof(cp->ltk) - conn->le.keys->enc_size); + } + + bt_hci_cmd_send(BT_HCI_OP_LE_LTK_REQ_REPLY, buf); + goto done; + } + +#if !defined(CONFIG_BLUETOOTH_SMP_SC_ONLY) + if (conn->le.keys && (conn->le.keys->keys & BT_KEYS_SLAVE_LTK) && + conn->le.keys->slave_ltk.rand == evt->rand && + conn->le.keys->slave_ltk.ediv == evt->ediv) { + struct bt_hci_cp_le_ltk_req_reply *cp; + struct net_buf *buf; + + buf = bt_hci_cmd_create(BT_HCI_OP_LE_LTK_REQ_REPLY, + sizeof(*cp)); + if (!buf) { + BT_ERR("Out of command buffers"); + goto done; + } + + cp = net_buf_add(buf, sizeof(*cp)); + cp->handle = evt->handle; + + /* use only enc_size bytes of key for encryption */ + memcpy(cp->ltk, conn->le.keys->slave_ltk.val, + conn->le.keys->enc_size); + if (conn->le.keys->enc_size < sizeof(cp->ltk)) { + memset(cp->ltk + conn->le.keys->enc_size, 0, + sizeof(cp->ltk) - conn->le.keys->enc_size); + } + + bt_hci_cmd_send(BT_HCI_OP_LE_LTK_REQ_REPLY, buf); + goto done; + } +#endif /* !CONFIG_BLUETOOTH_SMP_SC_ONLY */ + + buf = bt_hci_cmd_create(BT_HCI_OP_LE_LTK_REQ_NEG_REPLY, sizeof(*cp)); + if (!buf) { + BT_ERR("Out of command buffers"); + goto done; + } + + cp = net_buf_add(buf, sizeof(*cp)); + cp->handle = evt->handle; + + bt_hci_cmd_send(BT_HCI_OP_LE_LTK_REQ_NEG_REPLY, buf); + +done: + bt_conn_unref(conn); +} +#endif /* CONFIG_BLUETOOTH_SMP */ + +static void le_pkey_complete(struct net_buf *buf) +{ + struct bt_hci_evt_le_p256_public_key_complete *evt = (void *)buf->data; + struct bt_pub_key_cb *cb; + + BT_DBG("status: 0x%x", evt->status); + + atomic_clear_bit(bt_dev.flags, BT_DEV_PUB_KEY_BUSY); + + if (!evt->status) { + memcpy(pub_key, evt->key, 64); + atomic_set_bit(bt_dev.flags, BT_DEV_HAS_PUB_KEY); + } + + for (cb = pub_key_cb; cb; cb = cb->_next) { + cb->func(evt->status ? NULL : evt->key); + } +} + +static void le_dhkey_complete(struct net_buf *buf) +{ + struct bt_hci_evt_le_generate_dhkey_complete *evt = (void *)buf->data; + + BT_DBG("status: 0x%x", evt->status); + + if (dh_key_cb) { + dh_key_cb(evt->status ? NULL : evt->dhkey); + dh_key_cb = NULL; + } +} + +static void hci_reset_complete(struct net_buf *buf) +{ + uint8_t status = buf->data[0]; + + BT_DBG("status %u", status); + + if (status) { + return; + } + + scan_dev_found_cb = NULL; +#if defined(CONFIG_BLUETOOTH_BREDR) + discovery_cb = NULL; + discovery_results = NULL; + discovery_results_size = 0; + discovery_results_count = 0; +#endif /* CONFIG_BLUETOOTH_BREDR */ + + /* we only allow to enable once so this bit must be keep set */ + atomic_set(bt_dev.flags, BIT(BT_DEV_ENABLE)); +} + +static void hci_cmd_done(uint16_t opcode, uint8_t status, struct net_buf *buf) +{ + BT_DBG("opcode 0x%04x status 0x%02x buf %p", opcode, status, buf); + + if (buf->pool != &hci_cmd_pool) { + return; + } + + if (cmd(buf)->opcode != opcode) { + BT_WARN("OpCode 0x%04x completed instead of expected 0x%04x", + opcode, cmd(buf)->opcode); + } + + /* If the command was synchronous wake up bt_hci_cmd_send_sync() */ + if (cmd(buf)->sync) { + cmd(buf)->status = status; + k_sem_give(cmd(buf)->sync); + } +} + +static void hci_cmd_complete(struct net_buf *buf) +{ + struct bt_hci_evt_cmd_complete *evt = (void *)buf->data; + uint16_t opcode = sys_le16_to_cpu(evt->opcode); + uint8_t status, ncmd = evt->ncmd; + + BT_DBG("opcode 0x%04x", opcode); + + net_buf_pull(buf, sizeof(*evt)); + + /* All command return parameters have a 1-byte status in the + * beginning, so we can safely make this generalization. + */ + status = buf->data[0]; + + hci_cmd_done(opcode, status, buf); + + /* Allow next command to be sent */ + if (ncmd) { + k_sem_give(&bt_dev.ncmd_sem); + } +} + +static void hci_cmd_status(struct net_buf *buf) +{ + struct bt_hci_evt_cmd_status *evt = (void *)buf->data; + uint16_t opcode = sys_le16_to_cpu(evt->opcode); + uint8_t ncmd = evt->ncmd; + + BT_DBG("opcode 0x%04x", opcode); + + net_buf_pull(buf, sizeof(*evt)); + + hci_cmd_done(opcode, evt->status, buf); + + /* Allow next command to be sent */ + if (ncmd) { + k_sem_give(&bt_dev.ncmd_sem); + } +} + +#include +#include +#include + +static struct tc_hmac_prng_struct prng; + +static int prng_reseed(struct tc_hmac_prng_struct *h) +{ + uint8_t seed[32]; + int64_t extra; + int ret, i; + + for (i = 0; i < (sizeof(seed) / 8); i++) { + struct bt_hci_rp_le_rand *rp; + struct net_buf *rsp; + + ret = bt_hci_cmd_send_sync(BT_HCI_OP_LE_RAND, NULL, &rsp); + if (ret) { + return ret; + } + + rp = (void *)rsp->data; + memcpy(&seed[i * 8], rp->rand, 8); + + net_buf_unref(rsp); + } + + extra = k_uptime_get(); + + ret = tc_hmac_prng_reseed(h, seed, sizeof(seed), (uint8_t *)&extra, + sizeof(extra)); + if (ret == TC_CRYPTO_FAIL) { + BT_ERR("Failed to re-seed PRNG"); + return -EIO; + } + + return 0; +} + +static int prng_init(struct tc_hmac_prng_struct *h) +{ + struct bt_hci_rp_le_rand *rp; + struct net_buf *rsp; + int ret; + + ret = bt_hci_cmd_send_sync(BT_HCI_OP_LE_RAND, NULL, &rsp); + if (ret) { + return ret; + } + + rp = (void *)rsp->data; + + ret = tc_hmac_prng_init(h, rp->rand, sizeof(rp->rand)); + + net_buf_unref(rsp); + + if (ret == TC_CRYPTO_FAIL) { + BT_ERR("Failed to initialize PRNG"); + return -EIO; + } + + /* re-seed is needed after init */ + return prng_reseed(h); +} + +int bt_rand(void *buf, size_t len) +{ + int ret; + + ret = tc_hmac_prng_generate(buf, len, &prng); + if (ret == TC_HMAC_PRNG_RESEED_REQ) { + ret = prng_reseed(&prng); + if (ret) { + return ret; + } + + ret = tc_hmac_prng_generate(buf, len, &prng); + } + + if (ret == TC_CRYPTO_SUCCESS) { + return 0; + } + + return -EIO; +} + +static int start_le_scan(uint8_t scan_type, uint16_t interval, uint16_t window, + uint8_t filter_dup) +{ + struct net_buf *buf, *rsp; + struct bt_hci_cp_le_set_scan_params *set_param; + struct bt_hci_cp_le_set_scan_enable *scan_enable; + int err; + + buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_SCAN_PARAMS, + sizeof(*set_param)); + if (!buf) { + return -ENOBUFS; + } + + set_param = net_buf_add(buf, sizeof(*set_param)); + memset(set_param, 0, sizeof(*set_param)); + set_param->scan_type = scan_type; + + /* for the rest parameters apply default values according to + * spec 4.2, vol2, part E, 7.8.10 + */ + set_param->interval = sys_cpu_to_le16(interval); + set_param->window = sys_cpu_to_le16(window); + set_param->filter_policy = 0x00; + + if (IS_ENABLED(CONFIG_BLUETOOTH_PRIVACY)) { + err = le_set_private_addr(); + if (err) { + net_buf_unref(buf); + return err; + } + + set_param->addr_type = BT_ADDR_LE_RANDOM; + } else { + set_param->addr_type = bt_dev.id_addr.type; + + /* only set NRPA if there is no advertising ongoing */ + if (scan_type == BT_HCI_LE_SCAN_ACTIVE && + !atomic_test_bit(bt_dev.flags, BT_DEV_ADVERTISING)) { + err = le_set_private_addr(); + if (err) { + net_buf_unref(buf); + return err; + } + + set_param->addr_type = BT_ADDR_LE_RANDOM; + } + } + + bt_hci_cmd_send(BT_HCI_OP_LE_SET_SCAN_PARAMS, buf); + buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_SCAN_ENABLE, + sizeof(*scan_enable)); + if (!buf) { + return -ENOBUFS; + } + + scan_enable = net_buf_add(buf, sizeof(*scan_enable)); + memset(scan_enable, 0, sizeof(*scan_enable)); + scan_enable->filter_dup = filter_dup; + scan_enable->enable = BT_HCI_LE_SCAN_ENABLE; + + err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_SCAN_ENABLE, buf, &rsp); + if (err) { + return err; + } + + /* Update scan state in case of success (0) status */ + err = rsp->data[0]; + if (!err) { + atomic_set_bit(bt_dev.flags, BT_DEV_SCANNING); + if (scan_type == BT_HCI_LE_SCAN_ACTIVE) { + atomic_set_bit(bt_dev.flags, BT_DEV_ACTIVE_SCAN); + } + } + + net_buf_unref(rsp); + + return err; +} + +int bt_le_scan_update(bool fast_scan) +{ + if (atomic_test_bit(bt_dev.flags, BT_DEV_EXPLICIT_SCAN)) { + return 0; + } + + if (atomic_test_bit(bt_dev.flags, BT_DEV_SCANNING)) { + int err; + + err = bt_hci_stop_scanning(); + if (err) { + return err; + } + } + + if (IS_ENABLED(CONFIG_BLUETOOTH_CENTRAL)) { + uint16_t interval, window; + struct bt_conn *conn; + + conn = bt_conn_lookup_state_le(NULL, BT_CONN_CONNECT_SCAN); + if (!conn) { + return 0; + } + + bt_conn_unref(conn); + + if (fast_scan) { + interval = BT_GAP_SCAN_FAST_INTERVAL; + window = BT_GAP_SCAN_FAST_WINDOW; + } else { + interval = BT_GAP_SCAN_SLOW_INTERVAL_1; + window = BT_GAP_SCAN_SLOW_WINDOW_1; + } + + return start_le_scan(BT_HCI_LE_SCAN_PASSIVE, interval, window, + 0x01); + } + + return 0; +} + +static void le_adv_report(struct net_buf *buf) +{ + uint8_t num_reports = net_buf_pull_u8(buf); + struct bt_hci_ev_le_advertising_info *info; + + BT_DBG("Adv number of reports %u", num_reports); + + while (num_reports--) { + const bt_addr_le_t *addr; + int8_t rssi; + + info = (void *)buf->data; + net_buf_pull(buf, sizeof(*info)); + + rssi = info->data[info->length]; + + BT_DBG("%s event %u, len %u, rssi %d dBm", + bt_addr_le_str(&info->addr), + info->evt_type, info->length, rssi); + + addr = find_id_addr(&info->addr); + + if (scan_dev_found_cb) { + struct net_buf_simple_state state; + + net_buf_simple_save(&buf->b, &state); + + buf->len = info->length; + scan_dev_found_cb(addr, rssi, info->evt_type, &buf->b); + + net_buf_simple_restore(&buf->b, &state); + } + +#if defined(CONFIG_BLUETOOTH_CONN) + check_pending_conn(addr, &info->addr, info->evt_type); +#endif /* CONFIG_BLUETOOTH_CONN */ + + /* Get next report iteration by moving pointer to right offset + * in buf according to spec 4.2, Vol 2, Part E, 7.7.65.2. + */ + net_buf_pull(buf, info->length + sizeof(rssi)); + } +} +static void hci_vendor_event(struct net_buf *buf) +{ + uint8_t type = net_buf_pull_u8(buf); + uint32_t line = sys_get_le32(&buf->data[buf->len-4]); + if (0xaa == type) + { + BT_ERR("Error hanppen in LL,line %d,%s",line,buf->data); + } + else + { + BT_WARN("Unhandled vendor event len %u: %s", + buf->len, bt_hex(buf->data, buf->len)); + } + return; +} + +static void hci_le_meta_event(struct net_buf *buf) +{ + struct bt_hci_evt_le_meta_event *evt = (void *)buf->data; + + net_buf_pull(buf, sizeof(*evt)); + + switch (evt->subevent) { +#if defined(CONFIG_BLUETOOTH_CONN) + case BT_HCI_EVT_LE_CONN_COMPLETE: + le_conn_complete(buf); + break; + case BT_HCI_EVT_LE_CONN_UPDATE_COMPLETE: + le_conn_update_complete(buf); + break; + case BT_HCI_EV_LE_REMOTE_FEAT_COMPLETE: + le_remote_feat_complete(buf); + break; + case BT_HCI_EVT_LE_CONN_PARAM_REQ: + le_conn_param_req(buf); + break; +#endif /* CONFIG_BLUETOOTH_CONN */ +#if defined(CONFIG_BLUETOOTH_SMP) + case BT_HCI_EVT_LE_LTK_REQUEST: + le_ltk_request(buf); + break; +#endif /* CONFIG_BLUETOOTH_SMP */ + case BT_HCI_EVT_LE_P256_PUBLIC_KEY_COMPLETE: + le_pkey_complete(buf); + break; + case BT_HCI_EVT_LE_GENERATE_DHKEY_COMPLETE: + le_dhkey_complete(buf); + break; + case BT_HCI_EVT_LE_ADVERTISING_REPORT: + le_adv_report(buf); + break; + default: + BT_WARN("Unhandled LE event 0x%02x len %u: %s", + evt->subevent, buf->len, bt_hex(buf->data, buf->len)); + break; + } +} + +static void hci_event(struct net_buf *buf) +{ + struct bt_hci_evt_hdr *hdr = (void *)buf->data; + + BT_DBG("event 0x%02x", hdr->evt); + + BT_ASSERT(!bt_hci_evt_is_prio(hdr->evt)); + + net_buf_pull(buf, sizeof(*hdr)); + + switch (hdr->evt) { +#if defined(CONFIG_BLUETOOTH_BREDR) + case BT_HCI_EVT_CONN_REQUEST: + conn_req(buf); + break; + case BT_HCI_EVT_CONN_COMPLETE: + conn_complete(buf); + break; + case BT_HCI_EVT_PIN_CODE_REQ: + pin_code_req(buf); + break; + case BT_HCI_EVT_LINK_KEY_NOTIFY: + link_key_notify(buf); + break; + case BT_HCI_EVT_LINK_KEY_REQ: + link_key_req(buf); + break; + case BT_HCI_EVT_IO_CAPA_RESP: + io_capa_resp(buf); + break; + case BT_HCI_EVT_IO_CAPA_REQ: + io_capa_req(buf); + break; + case BT_HCI_EVT_SSP_COMPLETE: + ssp_complete(buf); + break; + case BT_HCI_EVT_USER_CONFIRM_REQ: + user_confirm_req(buf); + break; + case BT_HCI_EVT_USER_PASSKEY_NOTIFY: + user_passkey_notify(buf); + break; + case BT_HCI_EVT_USER_PASSKEY_REQ: + user_passkey_req(buf); + break; + case BT_HCI_EVT_INQUIRY_COMPLETE: + inquiry_complete(buf); + break; + case BT_HCI_EVT_INQUIRY_RESULT_WITH_RSSI: + inquiry_result_with_rssi(buf); + break; + case BT_HCI_EVT_EXTENDED_INQUIRY_RESULT: + extended_inquiry_result(buf); + break; + case BT_HCI_EVT_REMOTE_NAME_REQ_COMPLETE: + remote_name_request_complete(buf); + break; + case BT_HCI_EVT_AUTH_COMPLETE: + auth_complete(buf); + break; + case BT_HCI_EVT_REMOTE_FEATURES: + read_remote_features_complete(buf); + break; + case BT_HCI_EVT_REMOTE_EXT_FEATURES: + read_remote_ext_features_complete(buf); + break; + case BT_HCI_EVT_ROLE_CHANGE: + role_change(buf); + break; +#endif +#if defined(CONFIG_BLUETOOTH_CONN) + case BT_HCI_EVT_DISCONN_COMPLETE: + hci_disconn_complete(buf); + break; +#endif /* CONFIG_BLUETOOTH_CONN */ +#if defined(CONFIG_BLUETOOTH_SMP) || defined(CONFIG_BLUETOOTH_BREDR) + case BT_HCI_EVT_ENCRYPT_CHANGE: + hci_encrypt_change(buf); + break; + case BT_HCI_EVT_ENCRYPT_KEY_REFRESH_COMPLETE: + hci_encrypt_key_refresh_complete(buf); + break; +#endif /* CONFIG_BLUETOOTH_SMP || CONFIG_BLUETOOTH_BREDR */ + case BT_HCI_EVT_LE_META_EVENT: + hci_le_meta_event(buf); + break; + case BT_HCI_EVT_VENDOR: + hci_vendor_event(buf); + break; + default: + BT_WARN("Unhandled event 0x%02x len %u: %s", hdr->evt, + buf->len, bt_hex(buf->data, buf->len)); + break; + + } + + net_buf_unref(buf); +} + +static void send_cmd(void) +{ + struct net_buf *buf; + int err; + + /* Get next command */ + BT_DBG("calling net_buf_get"); + buf = net_buf_get(&bt_dev.cmd_tx_queue, K_NO_WAIT); + BT_ASSERT(buf); + + /* Wait until ncmd > 0 */ + BT_DBG("calling sem_take_wait"); + k_sem_take(&bt_dev.ncmd_sem, K_FOREVER); + + /* Clear out any existing sent command */ + if (bt_dev.sent_cmd) { + BT_ERR("Uncleared pending sent_cmd"); + net_buf_unref(bt_dev.sent_cmd); + bt_dev.sent_cmd = NULL; + } + + bt_dev.sent_cmd = net_buf_ref(buf); + + BT_DBG("Sending command 0x%04x (buf %p) to driver", + cmd(buf)->opcode, buf); + + err = bt_send(buf); + if (err) { + BT_ERR("Unable to send to driver (err %d)", err); + k_sem_give(&bt_dev.ncmd_sem); + hci_cmd_done(cmd(buf)->opcode, BT_HCI_ERR_UNSPECIFIED, + NULL); + net_buf_unref(bt_dev.sent_cmd); + bt_dev.sent_cmd = NULL; + net_buf_unref(buf); + } +} + +static void process_events(struct k_poll_event *ev, int count) +{ + BT_DBG("count %d", count); + + for (; count; ev++, count--) { + BT_DBG("ev->state %u", ev->state); + + switch (ev->state) { + case K_POLL_STATE_SIGNALED: + break; + case K_POLL_STATE_FIFO_DATA_AVAILABLE: + if (ev->tag == BT_EVENT_CMD_TX) { + send_cmd(); + } else if (IS_ENABLED(CONFIG_BLUETOOTH_CONN) && + ev->tag == BT_EVENT_CONN_TX) { + struct bt_conn *conn; + + conn = CONTAINER_OF(ev->fifo, struct bt_conn, + tx_queue); + bt_conn_process_tx(conn); + } + break; + case K_POLL_STATE_NOT_READY: + break; + default: + BT_WARN("Unexpected k_poll event state %u", ev->state); + break; + } + } +} + +#if defined(CONFIG_BLUETOOTH_CONN) +/* command FIFO + conn_change signal + MAX_CONN */ +#define EV_COUNT (2 + CONFIG_BLUETOOTH_MAX_CONN) +#else +/* command FIFO */ +#define EV_COUNT 1 +#endif + +static struct k_poll_event g_events[EV_COUNT] = { + K_POLL_STATIC_INITIALIZER(&bt_dev.cmd_tx_queue,\ + BT_EVENT_CMD_TX), +}; + +static inline int k_poll(struct k_poll_event *events, int num_events, int32_t timeout) +{ + void *msg = NULL; + struct k_poll_event *poll_event = NULL; + +#if 1 + msg = k_fifo_get(&bt_dev.tx_event,K_FOREVER); +#else + mtimer_mbox_fetch(bt_dev.tx_event._queue,&msg); +#endif + + poll_event = (struct k_poll_event *)msg; + while (poll_event) + { + BT_DBG("event got,poll_event %p",poll_event); + poll_event->state = K_POLL_STATE_DATA_AVAILABLE; + process_events(poll_event, 1); + poll_event = k_fifo_get(&bt_dev.tx_event,K_NO_WAIT); + } + + return 0; +} + +void hci_tx_event_notify(const void* obj) +{ + int i; + BT_DBG("notify with %p",obj); + for(i = 0;idata; + + BT_DBG("status %u", rp->status); + + bt_dev.hci_version = rp->hci_version; + bt_dev.hci_revision = sys_le16_to_cpu(rp->hci_revision); + bt_dev.lmp_version = rp->lmp_version; + bt_dev.lmp_subversion = sys_le16_to_cpu(rp->lmp_subversion); + bt_dev.manufacturer = sys_le16_to_cpu(rp->manufacturer); +} + +static void read_bdaddr_complete(struct net_buf *buf) +{ + struct bt_hci_rp_read_bd_addr *rp = (void *)buf->data; + + BT_DBG("status %u", rp->status); + + bt_addr_copy(&bt_dev.id_addr.a, &rp->bdaddr); + bt_dev.id_addr.type = BT_ADDR_LE_PUBLIC; +} + +static void read_le_features_complete(struct net_buf *buf) +{ + struct bt_hci_rp_le_read_local_features *rp = (void *)buf->data; + + BT_DBG("status %u", rp->status); + + memcpy(bt_dev.le.features, rp->features, sizeof(bt_dev.le.features)); +} + +#if defined(CONFIG_BLUETOOTH_BREDR) +static void read_buffer_size_complete(struct net_buf *buf) +{ + struct bt_hci_rp_read_buffer_size *rp = (void *)buf->data; + uint16_t pkts; + + BT_DBG("status %u", rp->status); + + bt_dev.br.mtu = sys_le16_to_cpu(rp->acl_max_len); + pkts = sys_le16_to_cpu(rp->acl_max_num); + + BT_DBG("ACL BR/EDR buffers: pkts %u mtu %u", pkts, bt_dev.br.mtu); + + k_sem_init(&bt_dev.br.pkts, pkts, pkts); +} +#else +static void read_buffer_size_complete(struct net_buf *buf) +{ + struct bt_hci_rp_read_buffer_size *rp = (void *)buf->data; + uint16_t pkts; + + BT_DBG("status %u", rp->status); + + /* If LE-side has buffers we can ignore the BR/EDR values */ + if (bt_dev.le.mtu) { + return; + } + + bt_dev.le.mtu = sys_le16_to_cpu(rp->acl_max_len); + pkts = sys_le16_to_cpu(rp->acl_max_num); + + BT_DBG("ACL BR/EDR buffers: pkts %u mtu %u", pkts, bt_dev.le.mtu); + + k_sem_init(&bt_dev.le.pkts, pkts, pkts); +} +#endif + +static void le_read_buffer_size_complete(struct net_buf *buf) +{ + struct bt_hci_rp_le_read_buffer_size *rp = (void *)buf->data; + + BT_DBG("status %u", rp->status); + + bt_dev.le.mtu = sys_le16_to_cpu(rp->le_max_len); + + if (bt_dev.le.mtu) { + k_sem_init(&bt_dev.le.pkts, rp->le_max_num, rp->le_max_num); + BT_DBG("ACL LE buffers: pkts %u mtu %u", rp->le_max_num, + bt_dev.le.mtu); + } +} + +static void read_supported_commands_complete(struct net_buf *buf) +{ + struct bt_hci_rp_read_supported_commands *rp = (void *)buf->data; + + BT_DBG("status %u", rp->status); + + memcpy(bt_dev.supported_commands, rp->commands, + sizeof(bt_dev.supported_commands)); + + /* + * Report "LE Read Local P-256 Public Key" and "LE Generate DH Key" as + * supported if TinyCrypt ECC is used for emulation. + */ + if (IS_ENABLED(CONFIG_BLUETOOTH_TINYCRYPT_ECC)) { + bt_dev.supported_commands[34] |= 0x02; + bt_dev.supported_commands[34] |= 0x04; + } +} + +static void read_local_features_complete(struct net_buf *buf) +{ + struct bt_hci_rp_read_local_features *rp = (void *)buf->data; + + BT_DBG("status %u", rp->status); + + memcpy(bt_dev.features[0], rp->features, sizeof(bt_dev.features[0])); +} + +static void le_read_supp_states_complete(struct net_buf *buf) +{ + struct bt_hci_rp_le_read_supp_states *rp = (void *)buf->data; + + BT_DBG("status %u", rp->status); + + bt_dev.le.states = sys_get_le64(rp->le_states); +} + +static int common_init(void) +{ + struct net_buf *rsp; + int err; + + /* Send HCI_RESET */ + err = bt_hci_cmd_send_sync(BT_HCI_OP_RESET, NULL, &rsp); + if (err) { + return err; + } + hci_reset_complete(rsp); + net_buf_unref(rsp); + + err = prng_init(&prng); + if (err) { + return err; + } + + /* Read Local Supported Features */ + err = bt_hci_cmd_send_sync(BT_HCI_OP_READ_LOCAL_FEATURES, NULL, &rsp); + if (err) { + return err; + } + read_local_features_complete(rsp); + net_buf_unref(rsp); + + /* Read Local Version Information */ + err = bt_hci_cmd_send_sync(BT_HCI_OP_READ_LOCAL_VERSION_INFO, NULL, + &rsp); + if (err) { + return err; + } + read_local_ver_complete(rsp); + net_buf_unref(rsp); + + /* Read Bluetooth Address */ + err = bt_hci_cmd_send_sync(BT_HCI_OP_READ_BD_ADDR, NULL, &rsp); + if (err) { + return err; + } + read_bdaddr_complete(rsp); + net_buf_unref(rsp); + + /* Read Local Supported Commands */ + err = bt_hci_cmd_send_sync(BT_HCI_OP_READ_SUPPORTED_COMMANDS, NULL, + &rsp); + if (err) { + return err; + } + read_supported_commands_complete(rsp); + net_buf_unref(rsp); + + return 0; +} + +static int le_init(void) +{ + struct bt_hci_cp_write_le_host_supp *cp_le; + struct bt_hci_cp_le_set_event_mask *cp_mask; + struct net_buf *buf; + struct net_buf *rsp; + int err; + + /* For now we only support LE capable controllers */ + if (!BT_FEAT_LE(bt_dev.features)) { + BT_ERR("Non-LE capable controller detected!"); + return -ENODEV; + } + + /* Read Low Energy Supported Features */ + err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_READ_LOCAL_FEATURES, NULL, + &rsp); + if (err) { + return err; + } + read_le_features_complete(rsp); + net_buf_unref(rsp); + + /* Read LE Buffer Size */ + err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_READ_BUFFER_SIZE, NULL, &rsp); + if (err) { + return err; + } + le_read_buffer_size_complete(rsp); + net_buf_unref(rsp); + + if (BT_FEAT_BREDR(bt_dev.features)) { + buf = bt_hci_cmd_create(BT_HCI_OP_LE_WRITE_LE_HOST_SUPP, + sizeof(*cp_le)); + if (!buf) { + return -ENOBUFS; + } + + cp_le = net_buf_add(buf, sizeof(*cp_le)); + + /* Explicitly enable LE for dual-mode controllers */ + cp_le->le = 0x01; + cp_le->simul = 0x00; + err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_WRITE_LE_HOST_SUPP, buf, + NULL); + if (err) { + return err; + } + } + + /* Read LE Supported States */ + if (BT_CMD_LE_STATES(bt_dev.supported_commands)) { + err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_READ_SUPP_STATES, NULL, + &rsp); + if (err) { + return err; + } + le_read_supp_states_complete(rsp); + net_buf_unref(rsp); + } + + /* Set LE event mask */ + buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_EVENT_MASK, sizeof(*cp_mask)); + if (!buf) { + return -ENOBUFS; + } + + cp_mask = net_buf_add(buf, sizeof(*cp_mask)); + memset(cp_mask, 0, sizeof(*cp_mask)); + + cp_mask->events[0] |= 0x02; /* LE Advertising Report Event */ + + if (IS_ENABLED(CONFIG_BLUETOOTH_CONN)) { + /* LE Connection Complete Event */ + cp_mask->events[0] |= 0x01; + /* LE Connection Update Complete Event */ + cp_mask->events[0] |= 0x04; + /* LE Read Remote Used Features Compl Evt */ + cp_mask->events[0] |= 0x08; + } + + if (IS_ENABLED(CONFIG_BLUETOOTH_SMP)) { + /* LE Long Term Key Request Event */ + cp_mask->events[0] |= 0x10; + } + + /* + * If "LE Read Local P-256 Public Key" and "LE Generate DH Key" are + * supported we need to enable events generated by those commands. + */ + if ((bt_dev.supported_commands[34] & 0x02) && + (bt_dev.supported_commands[34] & 0x04)) { + cp_mask->events[0] |= 0x80; /* LE Read Local P-256 PKey Compl */ + cp_mask->events[1] |= 0x01; /* LE Generate DHKey Compl Event */ + } + + err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_EVENT_MASK, buf, NULL); + if (err) { + return err; + } + + return 0; +} + +#if defined(CONFIG_BLUETOOTH_BREDR) +static int read_ext_features(void) +{ + int i; + + /* Read Local Supported Extended Features */ + for (i = 1; i < LMP_FEAT_PAGES_COUNT; i++) { + struct bt_hci_cp_read_local_ext_features *cp; + struct bt_hci_rp_read_local_ext_features *rp; + struct net_buf *buf, *rsp; + int err; + + buf = bt_hci_cmd_create(BT_HCI_OP_READ_LOCAL_EXT_FEATURES, + sizeof(*cp)); + if (!buf) { + return -ENOBUFS; + } + + cp = net_buf_add(buf, sizeof(*cp)); + cp->page = i; + + err = bt_hci_cmd_send_sync(BT_HCI_OP_READ_LOCAL_EXT_FEATURES, + buf, &rsp); + if (err) { + return err; + } + + rp = (void *)rsp->data; + + memcpy(&bt_dev.features[i], rp->ext_features, + sizeof(bt_dev.features[i])); + + if (rp->max_page <= i) { + net_buf_unref(rsp); + break; + } + + net_buf_unref(rsp); + } + + return 0; +} + +void device_supported_pkt_type(void) +{ + /* Device supported features and sco packet types */ + if (BT_FEAT_HV2_PKT(bt_dev.features)) { + bt_dev.esco.pkt_type |= (HCI_PKT_TYPE_ESCO_HV2); + } + + if (BT_FEAT_HV3_PKT(bt_dev.features)) { + bt_dev.esco.pkt_type |= (HCI_PKT_TYPE_ESCO_HV3); + } + + if (BT_FEAT_LMP_ESCO_CAPABLE(bt_dev.features)) { + bt_dev.esco.pkt_type |= (HCI_PKT_TYPE_ESCO_EV3); + } + + if (BT_FEAT_EV4_PKT(bt_dev.features)) { + bt_dev.esco.pkt_type |= (HCI_PKT_TYPE_ESCO_EV4); + } + + if (BT_FEAT_EV5_PKT(bt_dev.features)) { + bt_dev.esco.pkt_type |= (HCI_PKT_TYPE_ESCO_EV5); + } + + if (BT_FEAT_2EV3_PKT(bt_dev.features)) { + bt_dev.esco.pkt_type |= (HCI_PKT_TYPE_ESCO_2EV3); + } + + if (BT_FEAT_3EV3_PKT(bt_dev.features)) { + bt_dev.esco.pkt_type |= (HCI_PKT_TYPE_ESCO_3EV3); + } + + if (BT_FEAT_3SLOT_PKT(bt_dev.features)) { + bt_dev.esco.pkt_type |= (HCI_PKT_TYPE_ESCO_2EV5 | + HCI_PKT_TYPE_ESCO_3EV5); + } +} + +static int br_init(void) +{ + struct net_buf *buf; + struct bt_hci_cp_write_ssp_mode *ssp_cp; + struct bt_hci_cp_write_inquiry_mode *inq_cp; + struct bt_hci_write_local_name *name_cp; + int err; + + /* Read extended local features */ + if (BT_FEAT_EXT_FEATURES(bt_dev.features)) { + err = read_ext_features(); + if (err) { + return err; + } + } + + /* Add local supported packet types to bt_dev */ + device_supported_pkt_type(); + + /* Get BR/EDR buffer size */ + err = bt_hci_cmd_send_sync(BT_HCI_OP_READ_BUFFER_SIZE, NULL, &buf); + if (err) { + return err; + } + + read_buffer_size_complete(buf); + net_buf_unref(buf); + + /* Set SSP mode */ + buf = bt_hci_cmd_create(BT_HCI_OP_WRITE_SSP_MODE, sizeof(*ssp_cp)); + if (!buf) { + return -ENOBUFS; + } + + ssp_cp = net_buf_add(buf, sizeof(*ssp_cp)); + ssp_cp->mode = 0x01; + err = bt_hci_cmd_send_sync(BT_HCI_OP_WRITE_SSP_MODE, buf, NULL); + if (err) { + return err; + } + + /* Enable Inquiry results with RSSI or extended Inquiry */ + buf = bt_hci_cmd_create(BT_HCI_OP_WRITE_INQUIRY_MODE, sizeof(*inq_cp)); + if (!buf) { + return -ENOBUFS; + } + + inq_cp = net_buf_add(buf, sizeof(*inq_cp)); + inq_cp->mode = 0x02; + err = bt_hci_cmd_send_sync(BT_HCI_OP_WRITE_INQUIRY_MODE, buf, NULL); + if (err) { + return err; + } + + /* Set local name */ + buf = bt_hci_cmd_create(BT_HCI_OP_WRITE_LOCAL_NAME, sizeof(*name_cp)); + if (!buf) { + return -ENOBUFS; + } + + name_cp = net_buf_add(buf, sizeof(*name_cp)); + strncpy((char *)name_cp->local_name, CONFIG_BLUETOOTH_DEVICE_NAME, + sizeof(name_cp->local_name)); + + err = bt_hci_cmd_send_sync(BT_HCI_OP_WRITE_LOCAL_NAME, buf, NULL); + if (err) { + return err; + } + + /* Set page timeout*/ + buf = bt_hci_cmd_create(BT_HCI_OP_WRITE_PAGE_TIMEOUT, sizeof(uint16_t)); + if (!buf) { + return -ENOBUFS; + } + + net_buf_add_le16(buf, CONFIG_BLUETOOTH_PAGE_TIMEOUT); + + err = bt_hci_cmd_send_sync(BT_HCI_OP_WRITE_PAGE_TIMEOUT, buf, NULL); + if (err) { + return err; + } + + /* Enable BR/EDR SC if supported */ + if (BT_FEAT_SC(bt_dev.features)) { + struct bt_hci_cp_write_sc_host_supp *sc_cp; + + buf = bt_hci_cmd_create(BT_HCI_OP_WRITE_SC_HOST_SUPP, + sizeof(*sc_cp)); + if (!buf) { + return -ENOBUFS; + } + + sc_cp = net_buf_add(buf, sizeof(*sc_cp)); + sc_cp->sc_support = 0x01; + + err = bt_hci_cmd_send_sync(BT_HCI_OP_WRITE_SC_HOST_SUPP, buf, + NULL); + if (err) { + return err; + } + } + + return 0; +} +#else +static int br_init(void) +{ + struct net_buf *rsp; + int err; + + if (bt_dev.le.mtu) { + return 0; + } + + /* Use BR/EDR buffer size if LE reports zero buffers */ + err = bt_hci_cmd_send_sync(BT_HCI_OP_READ_BUFFER_SIZE, NULL, &rsp); + if (err) { + return err; + } + + read_buffer_size_complete(rsp); + net_buf_unref(rsp); + + return 0; +} +#endif + +static int set_event_mask(void) +{ + struct bt_hci_cp_set_event_mask *ev; + struct net_buf *buf; + + buf = bt_hci_cmd_create(BT_HCI_OP_SET_EVENT_MASK, sizeof(*ev)); + if (!buf) { + return -ENOBUFS; + } + + ev = net_buf_add(buf, sizeof(*ev)); + memset(ev, 0, sizeof(*ev)); + + if (IS_ENABLED(CONFIG_BLUETOOTH_BREDR)) { + ev->events[0] |= 0x01; /* Inquiry Complete */ + ev->events[0] |= 0x04; /* Connection Complete */ + ev->events[0] |= 0x08; /* Connection Request */ + ev->events[0] |= 0x20; /* Authentication Complete */ + ev->events[0] |= 0x40; /* Remote Name Request Complete */ + ev->events[1] |= 0x04; /* Read Remote Feature Complete */ + ev->events[2] |= 0x02; /* Role Change */ + ev->events[2] |= 0x20; /* Pin Code Request */ + ev->events[2] |= 0x40; /* Link Key Request */ + ev->events[2] |= 0x80; /* Link Key Notif */ + ev->events[4] |= 0x02; /* Inquiry Result With RSSI */ + ev->events[4] |= 0x04; /* Remote Extended Features Complete */ + ev->events[5] |= 0x08; /* Synchronous Conn Complete Event */ + ev->events[5] |= 0x40; /* Extended Inquiry Result */ + ev->events[6] |= 0x01; /* IO Capability Request */ + ev->events[6] |= 0x02; /* IO Capability Response */ + ev->events[6] |= 0x04; /* User Confirmation Request */ + ev->events[6] |= 0x08; /* User Passkey Request */ + ev->events[6] |= 0x20; /* Simple Pairing Complete */ + ev->events[7] |= 0x04; /* User Passkey Notification */ + } + + ev->events[1] |= 0x20; /* Command Complete */ + ev->events[1] |= 0x40; /* Command Status */ + ev->events[1] |= 0x80; /* Hardware Error */ + ev->events[3] |= 0x02; /* Data Buffer Overflow */ + ev->events[7] |= 0x20; /* LE Meta-Event */ + + if (IS_ENABLED(CONFIG_BLUETOOTH_CONN)) { + ev->events[0] |= 0x10; /* Disconnection Complete */ + ev->events[1] |= 0x08; /* Read Remote Version Info Complete */ + ev->events[2] |= 0x04; /* Number of Completed Packets */ + } + + if (IS_ENABLED(CONFIG_BLUETOOTH_SMP) && + BT_FEAT_LE_ENCR(bt_dev.le.features)) { + ev->events[0] |= 0x80; /* Encryption Change */ + ev->events[5] |= 0x80; /* Encryption Key Refresh Complete */ + } + + return bt_hci_cmd_send_sync(BT_HCI_OP_SET_EVENT_MASK, buf, NULL); +} + +static inline int create_random_addr(bt_addr_le_t *addr) +{ + addr->type = BT_ADDR_LE_RANDOM; + + return bt_rand(addr->a.val, 6); +} + +int bt_addr_le_create_nrpa(bt_addr_le_t *addr) +{ + int err; + + err = create_random_addr(addr); + if (err) { + return err; + } + + BT_ADDR_SET_NRPA(&addr->a); + + return 0; +} + +int bt_addr_le_create_static(bt_addr_le_t *addr) +{ + int err; + + err = create_random_addr(addr); + if (err) { + return err; + } + + BT_ADDR_SET_STATIC(&addr->a); + + return 0; +} + +static int set_static_addr(void) +{ + int err; + + if (bt_storage) { + ssize_t ret; + + ret = bt_storage->read(NULL, BT_STORAGE_ID_ADDR, + &bt_dev.id_addr, sizeof(bt_dev.id_addr)); + if (ret == sizeof(bt_dev.id_addr)) { + goto set_addr; + } + } + +#if defined(CONFIG_SOC_FAMILY_NRF5) + /* Read address from nRF5-specific storage + * Non-initialized FICR values default to 0xFF, skip if no address + * present. Also if a public address lives in FICR, do not use in this + * function. + */ + if (((NRF_FICR->DEVICEADDR[0] != UINT32_MAX) || + ((NRF_FICR->DEVICEADDR[1] & UINT16_MAX) != UINT16_MAX)) && + (NRF_FICR->DEVICEADDRTYPE & 0x01)) { + + bt_dev.id_addr.type = BT_ADDR_LE_RANDOM; + sys_put_le32(NRF_FICR->DEVICEADDR[0], &bt_dev.id_addr.a.val[0]); + sys_put_le16(NRF_FICR->DEVICEADDR[1], &bt_dev.id_addr.a.val[4]); + /* The FICR value is a just a random number, with no knowledge + * of the Bluetooth Specification requirements for random + * static addresses. + */ + BT_ADDR_SET_STATIC(&bt_dev.id_addr.a); + + goto set_addr; + } +#endif /* CONFIG_SOC_FAMILY_NRF5 */ + + BT_DBG("Generating new static random address"); + + err = bt_addr_le_create_static(&bt_dev.id_addr); + if (err) { + return err; + } + + if (bt_storage) { + ssize_t ret; + + ret = bt_storage->write(NULL, BT_STORAGE_ID_ADDR, + &bt_dev.id_addr, + sizeof(bt_dev.id_addr)); + if (ret != sizeof(bt_dev.id_addr)) { + BT_ERR("Unable to store static address"); + } + } else { + BT_WARN("Using temporary static random address"); + } + +set_addr: + if (bt_dev.id_addr.type != BT_ADDR_LE_RANDOM || + (bt_dev.id_addr.a.val[5] & 0xc0) != 0xc0) { + BT_ERR("Only static random address supported as identity"); + return -EINVAL; + } + + err = set_random_address(&bt_dev.id_addr.a); + if (err) { + return err; + } + + atomic_set_bit(bt_dev.flags, BT_DEV_ID_STATIC_RANDOM); + return 0; +} + +#if defined(CONFIG_BLUETOOTH_DEBUG) +static const char *ver_str(uint8_t ver) +{ + const char * const str[] = { + "1.0b", "1.1", "1.2", "2.0", "2.1", "3.0", "4.0", "4.1", "4.2", + "5.0", + }; + + if (ver < ARRAY_SIZE(str)) { + return str[ver]; + } + + return "unknown"; +} + +static void show_dev_info(void) +{ + char addr[BT_ADDR_LE_STR_LEN]; + + bt_addr_le_to_str(&bt_dev.id_addr, addr, sizeof(addr)); + + BT_INFO("Identity: %s", addr); + BT_INFO("HCI: version %s (0x%02x) revision 0x%04x, manufacturer 0x%04x", + ver_str(bt_dev.hci_version), bt_dev.hci_version, + bt_dev.hci_revision, bt_dev.manufacturer); + BT_INFO("LMP: version %s (0x%02x) subver 0x%04x", + ver_str(bt_dev.lmp_version), bt_dev.lmp_version, + bt_dev.lmp_subversion); +} +#else +static inline void show_dev_info(void) +{ +} +#endif /* CONFIG_BLUETOOTH_DEBUG */ + +static int hci_init(void) +{ + int err; + + err = common_init(); + if (err) { + return err; + } + + err = le_init(); + if (err) { + return err; + } + + if (BT_FEAT_BREDR(bt_dev.features)) { + err = br_init(); + if (err) { + return err; + } + } else if (IS_ENABLED(CONFIG_BLUETOOTH_BREDR)) { + BT_ERR("Non-BR/EDR controller detected"); + return -EIO; + } + + err = set_event_mask(); + if (err) { + return err; + } + + if (!bt_addr_le_cmp(&bt_dev.id_addr, BT_ADDR_LE_ANY) || + !bt_addr_le_cmp(&bt_dev.id_addr, BT_ADDR_LE_NONE)) { + BT_DBG("No public address. Trying to set static random."); + err = set_static_addr(); + if (err) { + BT_ERR("Unable to set identity address"); + return err; + } + } + + show_dev_info(); + + return 0; +} + +int bt_send(struct net_buf *buf) +{ + BT_DBG("buf %p len %u type %u", buf, buf->len, bt_buf_get_type(buf)); + + bt_monitor_send(bt_monitor_opcode(buf), buf->data, buf->len); + + return bt_dev.drv->send(buf); +} + +int bt_recv(struct net_buf *buf) +{ + bt_monitor_send(bt_monitor_opcode(buf), buf->data, buf->len); + + BT_DBG("buf %p len %u", buf, buf->len); + + if (buf->pool->user_data_size < BT_BUF_USER_DATA_MIN) { + BT_ERR("Too small user data size"); + net_buf_unref(buf); + return -EINVAL; + } + + switch (bt_buf_get_type(buf)) { +#if defined(CONFIG_BLUETOOTH_CONN) + case BT_BUF_ACL_IN: + net_buf_put(&bt_dev.rx_queue, buf); + return 0; +#endif /* BLUETOOTH_CONN */ + case BT_BUF_EVT: + net_buf_put(&bt_dev.rx_queue, buf); + return 0; + default: + BT_ERR("Invalid buf type %u", bt_buf_get_type(buf)); + net_buf_unref(buf); + return -EINVAL; + } +} + +int bt_recv_prio(struct net_buf *buf) +{ + struct bt_hci_evt_hdr *hdr = (void *)buf->data; + + bt_monitor_send(bt_monitor_opcode(buf), buf->data, buf->len); + + BT_ASSERT(bt_buf_get_type(buf) == BT_BUF_EVT); + BT_ASSERT(buf->len >= sizeof(*hdr)); + BT_ASSERT(bt_hci_evt_is_prio(hdr->evt)); + + net_buf_pull(buf, sizeof(*hdr)); + + switch (hdr->evt) { + case BT_HCI_EVT_CMD_COMPLETE: + hci_cmd_complete(buf); + break; + case BT_HCI_EVT_CMD_STATUS: + hci_cmd_status(buf); + break; +#if defined(CONFIG_BLUETOOTH_CONN) + case BT_HCI_EVT_NUM_COMPLETED_PACKETS: + hci_num_completed_packets(buf); + break; +#endif /* CONFIG_BLUETOOTH_CONN */ + default: + net_buf_unref(buf); + BT_ASSERT(0); + return -EINVAL; + } + + net_buf_unref(buf); + + return 0; +} + +int bt_hci_driver_register(struct bt_hci_driver *drv) +{ + if (bt_dev.drv) { + return -EALREADY; + } + + if (!drv->open || !drv->send) { + return -EINVAL; + } + + bt_dev.drv = drv; + + BT_DBG("Registered %s", drv->name ? drv->name : ""); + + bt_monitor_new_index(BT_MONITOR_TYPE_PRIMARY, drv->bus, + BT_ADDR_ANY, drv->name ? drv->name : "bt0"); + + return 0; +} + +#if defined(CONFIG_BLUETOOTH_PRIVACY) +static int irk_init(void) +{ + ssize_t err; + + if (bt_storage) { + err = bt_storage->read(NULL, BT_STORAGE_LOCAL_IRK, &bt_dev.irk, + sizeof(bt_dev.irk)); + if (err == sizeof(bt_dev.irk)) { + return 0; + } + } + + BT_DBG("Generating new IRK"); + + err = bt_rand(bt_dev.irk, sizeof(bt_dev.irk)); + if (err) { + return err; + } + + if (bt_storage) { + err = bt_storage->write(NULL, BT_STORAGE_LOCAL_IRK, bt_dev.irk, + sizeof(bt_dev.irk)); + if (err != sizeof(bt_dev.irk)) { + BT_ERR("Unable to store IRK"); + } + } else { + BT_WARN("Using temporary IRK"); + } + + return 0; +} +#endif /* CONFIG_BLUETOOTH_PRIVACY */ + +static int bt_init(void) +{ + int err; + BT_INFO(""); + err = hci_init(); + if (err) { + return err; + } + + if (IS_ENABLED(CONFIG_BLUETOOTH_CONN)) { + err = bt_conn_init(); + if (err) { + return err; + } + } + +#if defined(CONFIG_BLUETOOTH_PRIVACY) + err = irk_init(); + if (err) { + return err; + } + + k_delayed_work_init(&bt_dev.rpa_update, rpa_timeout); +#endif + + bt_monitor_send(BT_MONITOR_OPEN_INDEX, NULL, 0); + atomic_set_bit(bt_dev.flags, BT_DEV_READY); + bt_le_scan_update(false); + + return 0; +} + +static void init_work(struct k_work *work) +{ + int err; + + err = bt_init(); + if (ready_cb) { + ready_cb(err); + } +} + +static void hci_rx_thread(void *args) +{ + struct net_buf *buf; + + BT_DBG("started"); + + while (1) { + BT_DBG("calling fifo_get_wait"); + buf = net_buf_get(&bt_dev.rx_queue, K_FOREVER); + + BT_DBG("buf %p type %u len %u", buf, bt_buf_get_type(buf), + buf->len); + + switch (bt_buf_get_type(buf)) { +#if defined(CONFIG_BLUETOOTH_CONN) + case BT_BUF_ACL_IN: + hci_acl(buf); + break; +#endif /* CONFIG_BLUETOOTH_CONN */ + case BT_BUF_EVT: + hci_event(buf); + break; + default: + BT_ERR("Unknown buf type %u", bt_buf_get_type(buf)); + net_buf_unref(buf); + break; + } + + /* Make sure we don't hog the CPU if the rx_queue never + * gets empty. + */ + k_yield(); + } +} + +int bt_enable(bt_ready_cb_t cb) +{ + int err; + + if (!bt_dev.drv) { + BT_ERR("No HCI driver registered"); + return -ENODEV; + } + + if (atomic_test_and_set_bit(bt_dev.flags, BT_DEV_ENABLE)) { + return -EALREADY; + } + NET_BUF_POOL_INIT(hci_cmd_pool); + NET_BUF_POOL_INIT(hci_rx_pool); + + k_fifo_init(&bt_dev.tx_event, "tx event",(void **)&tx_event_msg_buf, CONFIG_BLUETOOTH_RX_BUF_COUNT); + + k_work_q_start("work queue",NULL,CONFIG_BLUETOOTH_WORK_QUEUE_STACK_SIZE, CONFIG_BLUETOOTH_WORK_QUEUE_PRIO); + k_work_init(&bt_dev.init, init_work); + +#if !defined(CONFIG_BLUETOOTH_WAIT_NOP) + k_sem_init(&bt_dev.ncmd_sem,1,1); +#else + k_sem_init(&bt_dev.ncmd_sem,0,1); +#endif + + k_fifo_init(&bt_dev.cmd_tx_queue,"cmd_tx_queue", (void **)&hci_cmd_msg_buf,CONFIG_BLUETOOTH_HCI_CMD_COUNT); + + k_fifo_init(&bt_dev.rx_queue,"rx_queue", (void **)&hci_rx_msg_buf,CONFIG_BLUETOOTH_RX_BUF_COUNT); + + ready_cb = cb; + + /* TX thread */ + k_thread_spawn(CONFIG_BLUETOOTH_HCI_TX_NAME,tx_thread_stack, sizeof(tx_thread_stack),\ + hci_tx_thread, NULL, CONFIG_BLUETOOTH_HCI_RX_PRIO); + + /* RX thread */ + k_thread_spawn(CONFIG_BLUETOOTH_HCI_RX_NAME,rx_thread_stack, sizeof(rx_thread_stack),\ + hci_rx_thread, NULL,CONFIG_BLUETOOTH_HCI_TX_PRIO); + + bt_hci_ecc_init(); + + err = bt_dev.drv->open(); + if (err) { + BT_ERR("HCI driver open failed (%d)", err); + return err; + } + + if (!cb) { + return bt_init(); + } + + k_work_submit(&bt_dev.init); + return 0; +} + +bool bt_addr_le_is_bonded(const bt_addr_le_t *addr) +{ + if (IS_ENABLED(CONFIG_BLUETOOTH_SMP)) { + struct bt_keys *keys = bt_keys_find_addr(addr); + + /* if there are any keys stored then device is bonded */ + return keys && keys->keys; + } else { + return false; + } +} + +static bool valid_adv_param(const struct bt_le_adv_param *param) +{ + if (!(param->options & BT_LE_ADV_OPT_CONNECTABLE)) { + /* + * BT Core 4.2 [Vol 2, Part E, 7.8.5] + * The Advertising_Interval_Min and Advertising_Interval_Max + * shall not be set to less than 0x00A0 (100 ms) if the + * Advertising_Type is set to ADV_SCAN_IND or ADV_NONCONN_IND. + */ + if (bt_dev.hci_version < BT_HCI_VERSION_5_0 && + param->interval_min < 0x00a0) { + return false; + } + } + + if (param->interval_min > param->interval_max || + param->interval_min < 0x0020 || param->interval_max > 0x4000) { + return false; + } + + return true; +} + +static int set_ad(uint16_t hci_op, const struct bt_data *ad, size_t ad_len) +{ + struct bt_hci_cp_le_set_adv_data *set_data; + struct net_buf *buf; + int i; + + buf = bt_hci_cmd_create(hci_op, sizeof(*set_data)); + if (!buf) { + return -ENOBUFS; + } + + set_data = net_buf_add(buf, sizeof(*set_data)); + + memset(set_data, 0, sizeof(*set_data)); + + for (i = 0; i < ad_len; i++) { + /* Check if ad fit in the remaining buffer */ + if (set_data->len + ad[i].data_len + 2 > 31) { + net_buf_unref(buf); + return -EINVAL; + } + + set_data->data[set_data->len++] = ad[i].data_len + 1; + set_data->data[set_data->len++] = ad[i].type; + + memcpy(&set_data->data[set_data->len], ad[i].data, + ad[i].data_len); + set_data->len += ad[i].data_len; + } + + return bt_hci_cmd_send_sync(hci_op, buf, NULL); +} + +int bt_le_adv_start(const struct bt_le_adv_param *param, + const struct bt_data *ad, size_t ad_len, + const struct bt_data *sd, size_t sd_len) +{ + struct net_buf *buf; + struct bt_hci_cp_le_set_adv_param *set_param; + int err; + + if (!valid_adv_param(param)) { + return -EINVAL; + } + + if (atomic_test_bit(bt_dev.flags, BT_DEV_ADVERTISING)) { + return -EALREADY; + } + + if (ad) + { + err = set_ad(BT_HCI_OP_LE_SET_ADV_DATA, ad, ad_len); + if (err) { + return err; + } + } + + /* + * We need to set SCAN_RSP when enabling advertising type that allows + * for Scan Requests. + * + * If sd was not provided but we enable connectable undirected + * advertising sd needs to be cleared from values set by previous calls. + * Clearing sd is done by calling set_ad() with NULL data and zero len. + * So following condition check is unusual but correct. + */ + if (sd || (param->options & BT_LE_ADV_OPT_CONNECTABLE)) { + err = set_ad(BT_HCI_OP_LE_SET_SCAN_RSP_DATA, sd, sd_len); + if (err) { + return err; + } + } + + buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_ADV_PARAM, sizeof(*set_param)); + if (!buf) { + return -ENOBUFS; + } + + set_param = net_buf_add(buf, sizeof(*set_param)); + + memset(set_param, 0, sizeof(*set_param)); + set_param->min_interval = sys_cpu_to_le16(param->interval_min); + set_param->max_interval = sys_cpu_to_le16(param->interval_max); + set_param->channel_map = 0x07; + + if (param->options & BT_LE_ADV_OPT_CONNECTABLE) { + if (IS_ENABLED(CONFIG_BLUETOOTH_PRIVACY)) { + err = le_set_private_addr(); + if (err) { + net_buf_unref(buf); + return err; + } + + set_param->own_addr_type = BT_ADDR_LE_RANDOM; + } else { + /* + * If Static Random address is used as Identity + * address we need to restore it before advertising + * is enabled. Otherwise NRPA used for active scan + * could be used for advertising. + */ + if (atomic_test_bit(bt_dev.flags, + BT_DEV_ID_STATIC_RANDOM)) { + set_random_address(&bt_dev.id_addr.a); + } + + set_param->own_addr_type = bt_dev.id_addr.type; + } + if (param->options & BT_LE_ADV_OPT_DIRECT) + { + if (param->peer_addr) + { + memcpy(&set_param->direct_addr,param->peer_addr,sizeof(bt_addr_le_t)); + set_param->type = BT_LE_ADV_DIRECT_IND; + } + else + { + return -EINVAL; + } + } + else + { + set_param->type = BT_LE_ADV_IND; + } + } else { + if (param->own_addr) { + /* Only NRPA is allowed */ + if (!BT_ADDR_IS_NRPA(param->own_addr)) { + return -EINVAL; + } + + err = set_random_address(param->own_addr); + } else { + err = le_set_private_addr(); + } + + if (err) { + net_buf_unref(buf); + return err; + } + + set_param->own_addr_type = BT_ADDR_LE_RANDOM; + + if (sd) { + set_param->type = BT_LE_ADV_SCAN_IND; + } else { + set_param->type = BT_LE_ADV_NONCONN_IND; + } + } + + err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_ADV_PARAM, buf, NULL); + if (err) { + return err; + } + + err = set_advertise_enable(true); + if (err) { + return err; + } + + atomic_set_bit(bt_dev.flags, BT_DEV_KEEP_ADVERTISING); + + return 0; +} + +int bt_le_adv_stop(void) +{ + int err; + + /* Advertise disable may fail if slave connections are established, + * and advertising is not kept ON as the controller does not support + * simultaneous slave connections and connectable advertising state. + * Hence, we test and clear BT_DEV_KEEP_ADVERTISING flag before trying + * to disable advertising if BT_DEV_ADVERTISING is set. + */ + if (!atomic_test_and_clear_bit(bt_dev.flags, BT_DEV_KEEP_ADVERTISING)) { + return -EALREADY; + } + + if (!atomic_test_bit(bt_dev.flags, BT_DEV_ADVERTISING)) { + return 0; + } + + err = set_advertise_enable(false); + if (err) { + return err; + } + + if (!IS_ENABLED(CONFIG_BLUETOOTH_PRIVACY)) { + /* If active scan is ongoing set NRPA */ + if (atomic_test_bit(bt_dev.flags, BT_DEV_ACTIVE_SCAN)) { + le_set_private_addr(); + } + } + + return 0; +} + +static bool valid_le_scan_param(const struct bt_le_scan_param *param) +{ + if (param->type != BT_HCI_LE_SCAN_PASSIVE && + param->type != BT_HCI_LE_SCAN_ACTIVE) { + return false; + } + + if (param->filter_dup != BT_HCI_LE_SCAN_FILTER_DUP_DISABLE && + param->filter_dup != BT_HCI_LE_SCAN_FILTER_DUP_ENABLE) { + return false; + } + + if (param->interval < 0x0004 || param->interval > 0x4000) { + return false; + } + + if (param->window < 0x0004 || param->window > 0x4000) { + return false; + } + + if (param->window > param->interval) { + return false; + } + + return true; +} + +int bt_le_scan_start(const struct bt_le_scan_param *param, bt_le_scan_cb_t cb) +{ + int err; + + /* Check that the parameters have valid values */ + if (!valid_le_scan_param(param)) { + return -EINVAL; + } + + /* Return if active scan is already enabled */ + if (atomic_test_and_set_bit(bt_dev.flags, BT_DEV_EXPLICIT_SCAN)) { + return -EALREADY; + } + + if (atomic_test_bit(bt_dev.flags, BT_DEV_SCANNING)) { + err = bt_hci_stop_scanning(); + if (err) { + atomic_clear_bit(bt_dev.flags, BT_DEV_EXPLICIT_SCAN); + return err; + } + } + + err = start_le_scan(param->type, param->interval, param->window, + param->filter_dup); + if (err) { + atomic_clear_bit(bt_dev.flags, BT_DEV_EXPLICIT_SCAN); + return err; + } + + scan_dev_found_cb = cb; + + return 0; +} + +int bt_le_scan_stop(void) +{ + /* Return if active scanning is already disabled */ + if (!atomic_test_and_clear_bit(bt_dev.flags, BT_DEV_EXPLICIT_SCAN)) { + return -EALREADY; + } + + scan_dev_found_cb = NULL; + + return bt_le_scan_update(false); +} + +struct net_buf *bt_buf_get_rx(int32_t timeout) +{ + struct net_buf *buf; + + buf = net_buf_alloc(&hci_rx_pool, timeout); + if (buf) { + net_buf_reserve(buf, CONFIG_BLUETOOTH_HCI_RESERVE); + } + + return buf; +} + +struct net_buf *bt_buf_get_cmd_complete(int32_t timeout) +{ + struct net_buf *buf; + unsigned int key; + + key = irq_lock(); + buf = bt_dev.sent_cmd; + bt_dev.sent_cmd = NULL; + irq_unlock(key); + + BT_DBG("sent_cmd %p", buf); + + if (buf) { + bt_buf_set_type(buf, BT_BUF_EVT); + buf->len = 0; + net_buf_reserve(buf, CONFIG_BLUETOOTH_HCI_RESERVE); + + return buf; + } + + buf = bt_buf_get_rx(timeout); + if (buf) { + bt_buf_set_type(buf, BT_BUF_EVT); + } + + return buf; +} + +#if defined(CONFIG_BLUETOOTH_BREDR) +static int br_start_inquiry(const struct bt_br_discovery_param *param) +{ + const uint8_t iac[3] = { 0x33, 0x8b, 0x9e }; + struct bt_hci_op_inquiry *cp; + struct net_buf *buf; + + buf = bt_hci_cmd_create(BT_HCI_OP_INQUIRY, sizeof(*cp)); + if (!buf) { + return -ENOBUFS; + } + + cp = net_buf_add(buf, sizeof(*cp)); + + cp->length = param->length; + cp->num_rsp = 0xff; /* we limit discovery only by time */ + + memcpy(cp->lap, iac, 3); + if (param->limited) { + cp->lap[0] = 0x00; + } + + return bt_hci_cmd_send_sync(BT_HCI_OP_INQUIRY, buf, NULL); +} + +static bool valid_br_discov_param(const struct bt_br_discovery_param *param, + size_t num_results) +{ + if (!num_results || num_results > 255) { + return false; + } + + if (!param->length || param->length > 0x30) { + return false; + } + + return true; +} + +int bt_br_discovery_start(const struct bt_br_discovery_param *param, + struct bt_br_discovery_result *results, size_t cnt, + bt_br_discovery_cb_t cb) +{ + int err; + + BT_DBG(""); + + if (!valid_br_discov_param(param, cnt)) { + return -EINVAL; + } + + if (atomic_test_bit(bt_dev.flags, BT_DEV_INQUIRY)) { + return -EALREADY; + } + + err = br_start_inquiry(param); + if (err) { + return err; + } + + atomic_set_bit(bt_dev.flags, BT_DEV_INQUIRY); + + memset(results, 0, sizeof(*results) * cnt); + + discovery_cb = cb; + discovery_results = results; + discovery_results_size = cnt; + discovery_results_count = 0; + + return 0; +} + +int bt_br_discovery_stop(void) +{ + int err; + int i; + + BT_DBG(""); + + if (!atomic_test_bit(bt_dev.flags, BT_DEV_INQUIRY)) { + return -EALREADY; + } + + err = bt_hci_cmd_send_sync(BT_HCI_OP_INQUIRY_CANCEL, NULL, NULL); + if (err) { + return err; + } + + for (i = 0; i < discovery_results_count; i++) { + struct discovery_priv *priv; + struct bt_hci_cp_remote_name_cancel *cp; + struct net_buf *buf; + + priv = (struct discovery_priv *)&discovery_results[i]._priv; + + if (!priv->resolving) { + continue; + } + + buf = bt_hci_cmd_create(BT_HCI_OP_REMOTE_NAME_CANCEL, + sizeof(*cp)); + if (!buf) { + continue; + } + + cp = net_buf_add(buf, sizeof(*cp)); + bt_addr_copy(&cp->bdaddr, &discovery_results[i].addr); + + bt_hci_cmd_send_sync(BT_HCI_OP_REMOTE_NAME_CANCEL, buf, NULL); + } + + atomic_clear_bit(bt_dev.flags, BT_DEV_INQUIRY); + + discovery_cb = NULL; + discovery_results = NULL; + discovery_results_size = 0; + discovery_results_count = 0; + + return 0; +} + +static int write_scan_enable(uint8_t scan) +{ + struct net_buf *buf; + int err; + + BT_DBG("type %u", scan); + + buf = bt_hci_cmd_create(BT_HCI_OP_WRITE_SCAN_ENABLE, 1); + if (!buf) { + return -ENOBUFS; + } + + net_buf_add_u8(buf, scan); + err = bt_hci_cmd_send_sync(BT_HCI_OP_WRITE_SCAN_ENABLE, buf, NULL); + if (err) { + return err; + } + + if (scan & BT_BREDR_SCAN_INQUIRY) { + atomic_set_bit(bt_dev.flags, BT_DEV_ISCAN); + } else { + atomic_clear_bit(bt_dev.flags, BT_DEV_ISCAN); + } + + if (scan & BT_BREDR_SCAN_PAGE) { + atomic_set_bit(bt_dev.flags, BT_DEV_PSCAN); + } else { + atomic_clear_bit(bt_dev.flags, BT_DEV_PSCAN); + } + + return 0; +} + +int bt_br_set_connectable(bool enable) +{ + if (enable) { + if (atomic_test_bit(bt_dev.flags, BT_DEV_PSCAN)) { + return -EALREADY; + } else { + return write_scan_enable(BT_BREDR_SCAN_PAGE); + } + } else { + if (!atomic_test_bit(bt_dev.flags, BT_DEV_PSCAN)) { + return -EALREADY; + } else { + return write_scan_enable(BT_BREDR_SCAN_DISABLED); + } + } +} + +int bt_br_set_discoverable(bool enable) +{ + if (enable) { + if (atomic_test_bit(bt_dev.flags, BT_DEV_ISCAN)) { + return -EALREADY; + } + + if (!atomic_test_bit(bt_dev.flags, BT_DEV_PSCAN)) { + return -EPERM; + } + + return write_scan_enable(BT_BREDR_SCAN_INQUIRY | + BT_BREDR_SCAN_PAGE); + } else { + if (!atomic_test_bit(bt_dev.flags, BT_DEV_ISCAN)) { + return -EALREADY; + } + + return write_scan_enable(BT_BREDR_SCAN_PAGE); + } +} +#endif /* CONFIG_BLUETOOTH_BREDR */ + +void bt_storage_register(const struct bt_storage *storage) +{ + bt_storage = storage; +} + +static int bt_storage_clear_all(void) +{ + if (IS_ENABLED(CONFIG_BLUETOOTH_CONN)) { + bt_conn_disconnect_all(); + } + + if (IS_ENABLED(CONFIG_BLUETOOTH_SMP)) { + bt_keys_clear_all(); + } + + if (IS_ENABLED(CONFIG_BLUETOOTH_BREDR)) { + bt_keys_link_key_clear_addr(NULL); + } + + if (bt_storage) { + return bt_storage->clear(NULL); + } + + return 0; +} + +int bt_storage_clear(const bt_addr_le_t *addr) +{ + if (!addr) { + return bt_storage_clear_all(); + } + + if (IS_ENABLED(CONFIG_BLUETOOTH_CONN)) { + struct bt_conn *conn = bt_conn_lookup_addr_le(addr); + if (conn) { + bt_conn_disconnect(conn, + BT_HCI_ERR_REMOTE_USER_TERM_CONN); + bt_conn_unref(conn); + } + } + + if (IS_ENABLED(CONFIG_BLUETOOTH_BREDR)) { + /* LE Public may indicate BR/EDR as well */ + if (addr->type == BT_ADDR_LE_PUBLIC) { + bt_keys_link_key_clear_addr(&addr->a); + } + } + + if (IS_ENABLED(CONFIG_BLUETOOTH_SMP)) { + struct bt_keys *keys = bt_keys_find_addr(addr); + if (keys) { + bt_keys_clear(keys); + } + } + + if (bt_storage) { + return bt_storage->clear(addr); + } + + return 0; +} + +uint16_t bt_hci_get_cmd_opcode(struct net_buf *buf) +{ + return cmd(buf)->opcode; +} + +int bt_pub_key_gen(struct bt_pub_key_cb *new_cb) +{ + struct bt_pub_key_cb *cb; + int err; + + /* + * We check for both "LE Read Local P-256 Public Key" and + * "LE Generate DH Key" support here since both commands are needed for + * ECC support. If "LE Generate DH Key" is not supported then there + * is no point in reading local public key. + */ + if (!(bt_dev.supported_commands[34] & 0x02) || + !(bt_dev.supported_commands[34] & 0x04)) { + BT_WARN("ECC HCI commands not available"); + return -ENOTSUP; + } + + new_cb->_next = pub_key_cb; + pub_key_cb = new_cb; + + if (atomic_test_and_set_bit(bt_dev.flags, BT_DEV_PUB_KEY_BUSY)) { + return 0; + } + + atomic_clear_bit(bt_dev.flags, BT_DEV_HAS_PUB_KEY); + + err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_P256_PUBLIC_KEY, NULL, NULL); + if (err) { + BT_ERR("Sending LE P256 Public Key command failed"); + atomic_clear_bit(bt_dev.flags, BT_DEV_PUB_KEY_BUSY); + pub_key_cb = NULL; + return err; + } + + for (cb = pub_key_cb; cb; cb = cb->_next) { + if (cb != new_cb) { + cb->func(NULL); + } + } + + return 0; +} + +const uint8_t *bt_pub_key_get(void) +{ + if (atomic_test_bit(bt_dev.flags, BT_DEV_HAS_PUB_KEY)) { + return pub_key; + } + + return NULL; +} + +int bt_dh_key_gen(const uint8_t remote_pk[64], bt_dh_key_cb_t cb) +{ + struct bt_hci_cp_le_generate_dhkey *cp; + struct net_buf *buf; + int err; + + if (dh_key_cb || atomic_test_bit(bt_dev.flags, BT_DEV_PUB_KEY_BUSY)) { + return -EBUSY; + } + + if (!atomic_test_bit(bt_dev.flags, BT_DEV_HAS_PUB_KEY)) { + return -EADDRNOTAVAIL; + } + + dh_key_cb = cb; + + buf = bt_hci_cmd_create(BT_HCI_OP_LE_GENERATE_DHKEY, sizeof(*cp)); + if (!buf) { + dh_key_cb = NULL; + return -ENOBUFS; + } + + cp = net_buf_add(buf, sizeof(*cp)); + memcpy(cp->key, remote_pk, sizeof(cp->key)); + + err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_GENERATE_DHKEY, buf, NULL); + if (err) { + dh_key_cb = NULL; + return err; + } + + return 0; +} + +#if defined(CONFIG_BLUETOOTH_BREDR) +int bt_br_oob_get_local(struct bt_br_oob *oob) +{ + bt_addr_copy(&oob->addr, &bt_dev.id_addr.a); + + return 0; +} +#endif /* CONFIG_BLUETOOTH_BREDR */ + +int bt_le_oob_get_local(struct bt_le_oob *oob) +{ + if (IS_ENABLED(CONFIG_BLUETOOTH_PRIVACY)) { + int err; + + /* Invalidate RPA so a new one is generated */ + atomic_clear_bit(bt_dev.flags, BT_DEV_RPA_VALID); + + err = le_set_private_addr(); + if (err) { + return err; + } + + bt_addr_le_copy(&oob->addr, &bt_dev.random_addr); + } else { + bt_addr_le_copy(&oob->addr, &bt_dev.id_addr); + } + + return 0; +} diff --git a/kernel/protocols/bluetooth/host/hci_core.h b/kernel/protocols/bluetooth/host/hci_core.h new file mode 100644 index 0000000000..e12c968c44 --- /dev/null +++ b/kernel/protocols/bluetooth/host/hci_core.h @@ -0,0 +1,170 @@ +/* hci_core.h - Bluetooth HCI core access */ + +/* + * Copyright (c) 2015-2016 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* LL connection parameters */ +#define LE_CONN_LATENCY 0x0000 +#define LE_CONN_TIMEOUT 0x002a + +#if defined(CONFIG_BLUETOOTH_BREDR) +#define LMP_FEAT_PAGES_COUNT 3 +#else +#define LMP_FEAT_PAGES_COUNT 1 +#endif + +/* SCO settings */ +#define BT_VOICE_CVSD_16BIT 0x0060 + +enum { + BT_EVENT_CMD_TX, + BT_EVENT_CONN_TX, + BT_EVENT_CONN_CHANGE, +}; + + +/* bt_dev flags: the flags defined here represent BT controller state */ +enum { + BT_DEV_ENABLE, + BT_DEV_READY, + BT_DEV_ID_STATIC_RANDOM, + BT_DEV_HAS_PUB_KEY, + BT_DEV_PUB_KEY_BUSY, + + BT_DEV_ADVERTISING, + BT_DEV_KEEP_ADVERTISING, + BT_DEV_SCANNING, + BT_DEV_EXPLICIT_SCAN, + BT_DEV_ACTIVE_SCAN, + + BT_DEV_RPA_VALID, + +#if defined(CONFIG_BLUETOOTH_BREDR) + BT_DEV_ISCAN, + BT_DEV_PSCAN, + BT_DEV_INQUIRY, +#endif /* CONFIG_BLUETOOTH_BREDR */ + + /* Total number of flags - must be at the end of the enum */ + BT_DEV_NUM_FLAGS, +}; + +struct bt_dev_le { + /* LE features */ + uint8_t features[1][8]; + /* LE states */ + uint64_t states; + + /* Controller buffer information */ + uint16_t mtu; + struct k_sem pkts; +}; + +#if defined(CONFIG_BLUETOOTH_BREDR) +struct bt_dev_esco { + uint16_t pkt_type; +}; + +struct bt_dev_br { + /* Max controller's acceptable ACL packet length */ + uint16_t mtu; + struct k_sem pkts; +}; +#endif + +/* State tracking for the local Bluetooth controller */ +struct bt_dev { + /* Local Identity Address */ + bt_addr_le_t id_addr; + + /* Current local Random Address */ + bt_addr_le_t random_addr; + + /* Controller version & manufacturer information */ + uint8_t hci_version; + uint8_t lmp_version; + uint16_t hci_revision; + uint16_t lmp_subversion; + uint16_t manufacturer; + + /* LMP features (pages 0, 1, 2) */ + uint8_t features[LMP_FEAT_PAGES_COUNT][8]; + + /* Supported commands */ + uint8_t supported_commands[64]; + + struct k_work init; + + ATOMIC_DEFINE(flags, BT_DEV_NUM_FLAGS); + + /* LE controller specific features */ + struct bt_dev_le le; + +#if defined(CONFIG_BLUETOOTH_BREDR) + /* BR/EDR controller specific features */ + struct bt_dev_br br; + struct bt_dev_esco esco; +#endif + + /* Number of commands controller can accept */ + struct k_sem ncmd_sem; + + /* Last sent HCI command */ + struct net_buf *sent_cmd; + +#if !defined(CONFIG_BLUETOOTH_RECV_IS_RX_THREAD) + /* Queue for incoming HCI events & ACL data */ + struct k_fifo rx_queue; +#endif + + /* Queue for high priority HCI events which may unlock waiters + * in other threads. Such events include Number of Completed + * Packets, as well as the Command Complete/Status events. + */ + struct k_fifo rx_prio_queue; + + /* Queue for outgoing HCI commands */ + struct k_fifo cmd_tx_queue; + + struct k_fifo tx_event; + /* Registered HCI driver */ + struct bt_hci_driver *drv; + +#if defined(CONFIG_BLUETOOTH_PRIVACY) + /* Local Identity Resolving Key */ + uint8_t irk[16]; + + /* Work used for RPA rotation */ + struct k_delayed_work rpa_update; +#endif +}; + +extern struct bt_dev bt_dev; +extern const struct bt_storage *bt_storage; +#if defined(CONFIG_BLUETOOTH_SMP) || defined(CONFIG_BLUETOOTH_BREDR) +extern const struct bt_conn_auth_cb *bt_auth; +#endif /* CONFIG_BLUETOOTH_SMP || CONFIG_BLUETOOTH_BREDR */ + +bool bt_le_conn_params_valid(const struct bt_le_conn_param *param); + +struct net_buf *bt_hci_cmd_create(uint16_t opcode, uint8_t param_len); +int bt_hci_cmd_send(uint16_t opcode, struct net_buf *buf); +int bt_hci_cmd_send_sync(uint16_t opcode, struct net_buf *buf, + struct net_buf **rsp); + +/* The helper is only safe to be called from internal threads as it's + * not multi-threading safe + */ +const char *bt_addr_str(const bt_addr_t *addr); +const char *bt_addr_le_str(const bt_addr_le_t *addr); + +int bt_le_scan_update(bool fast_scan); + +bool bt_addr_le_is_bonded(const bt_addr_le_t *addr); + +int bt_send(struct net_buf *buf); + +uint16_t bt_hci_get_cmd_opcode(struct net_buf *buf); diff --git a/kernel/protocols/bluetooth/host/hci_ecc.c b/kernel/protocols/bluetooth/host/hci_ecc.c new file mode 100644 index 0000000000..bb19f8facb --- /dev/null +++ b/kernel/protocols/bluetooth/host/hci_ecc.c @@ -0,0 +1,272 @@ +/** + * @file hci_ecc.c + * HCI ECC emulation + */ + +/* + * Copyright (c) 2016 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HCI_CORE) +#include +#include +#include +#include +#include + +#include "hci_ecc.h" +#include "hci_core.h" + +static BT_STACK_NOINIT(ecc_thread_stack, 1280); + +/* based on Core Specification 4.2 Vol 3. Part H 2.3.5.6.1 */ +static const uint32_t debug_private_key[8] = { + 0xcd3c1abd, 0x5899b8a6, 0xeb40b799, 0x4aff607b, 0xd2103f50, 0x74c9b3e3, + 0xa3c55f38, 0x3f49f6d4 +}; + +#if defined(CONFIG_BLUETOOTH_USE_DEBUG_KEYS) +static const uint8_t debug_public_key[64] = { + 0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc, 0xdb, 0xfd, 0xf4, 0xac, + 0x11, 0x91, 0xf4, 0xef, 0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e, + 0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20, 0x8b, 0xd2, 0x89, 0x15, + 0xd0, 0x8e, 0x1c, 0x74, 0x24, 0x30, 0xed, 0x8f, 0xc2, 0x45, 0x63, 0x76, + 0x5c, 0x15, 0x52, 0x5a, 0xbf, 0x9a, 0x32, 0x63, 0x6d, 0xeb, 0x2a, 0x65, + 0x49, 0x9c, 0x80, 0xdc +}; +#endif + +static struct k_fifo ecc_queue; +static int (*drv_send)(struct net_buf *buf); +static uint32_t private_key[8]; + +static void send_cmd_status(uint16_t opcode, uint8_t status) +{ + struct bt_hci_evt_cmd_status *evt; + struct bt_hci_evt_hdr *hdr; + struct net_buf *buf; + + BT_DBG("opcode %x status %x", opcode, status); + + buf = bt_buf_get_cmd_complete(K_FOREVER); + bt_buf_set_type(buf, BT_BUF_EVT); + + hdr = net_buf_add(buf, sizeof(*hdr)); + hdr->evt = BT_HCI_EVT_CMD_STATUS; + hdr->len = sizeof(*evt); + + evt = net_buf_add(buf, sizeof(*evt)); + evt->ncmd = 1; + evt->opcode = sys_cpu_to_le16(opcode); + evt->status = status; + + bt_recv_prio(buf); +} + +static uint8_t generate_keys(EccPoint *pkey, uint32_t private_key[8]) +{ +#if !defined(CONFIG_BLUETOOTH_USE_DEBUG_KEYS) + do { + uint32_t random[8]; + int rc; + + if (bt_rand((uint8_t *)random, sizeof(random))) { + BT_ERR("Failed to get random bytes for ECC keys"); + return BT_HCI_ERR_UNSPECIFIED; + } + + rc = ecc_make_key(pkey, private_key, random); + if (rc == TC_CRYPTO_FAIL) { + BT_ERR("Failed to create ECC public/private pair"); + return BT_HCI_ERR_UNSPECIFIED; + } + + /* make sure generated key isn't debug key */ + } while (memcmp(private_key, debug_private_key, 32) == 0); +#else + memcpy(pkey, debug_public_key, 64); + memcpy(private_key, debug_private_key, 32); +#endif + return 0; +} + +static void emulate_le_p256_public_key_cmd(struct net_buf *buf) +{ + struct bt_hci_evt_le_p256_public_key_complete *evt; + struct bt_hci_evt_le_meta_event *meta; + struct bt_hci_evt_hdr *hdr; + uint8_t status; + EccPoint pkey; + + BT_DBG(""); + + net_buf_unref(buf); + + send_cmd_status(BT_HCI_OP_LE_P256_PUBLIC_KEY, 0); + + status = generate_keys(&pkey, private_key); + + buf = bt_buf_get_rx(K_FOREVER); + bt_buf_set_type(buf, BT_BUF_EVT); + + hdr = net_buf_add(buf, sizeof(*hdr)); + hdr->evt = BT_HCI_EVT_LE_META_EVENT; + hdr->len = sizeof(*meta) + sizeof(*evt); + + meta = net_buf_add(buf, sizeof(*meta)); + meta->subevent = BT_HCI_EVT_LE_P256_PUBLIC_KEY_COMPLETE; + + evt = net_buf_add(buf, sizeof(*evt)); + evt->status = status; + + if (status) { + memset(evt->key, 0, sizeof(evt->key)); + } else { + memcpy(evt->key, pkey.x, 32); + memcpy(&evt->key[32], pkey.y, 32); + } + + bt_recv(buf); +} + +static void emulate_le_generate_dhkey(struct net_buf *buf) +{ + struct bt_hci_evt_le_generate_dhkey_complete *evt; + struct bt_hci_cp_le_generate_dhkey *cmd; + struct bt_hci_evt_le_meta_event *meta; + struct bt_hci_evt_hdr *hdr; + int32_t ret; + /* The following large stack variables are never needed at the same + * time, so we save some stack space by putting them in a union. + */ + union { + EccPoint pk; + uint32_t dhkey[8]; + } ecc; + + if (buf->len < sizeof(*cmd)) { + send_cmd_status(BT_HCI_OP_LE_GENERATE_DHKEY, + BT_HCI_ERR_INVALID_PARAMS); + return; + } + + cmd = (void *)buf->data + sizeof(struct bt_hci_cmd_hdr); + + memcpy(ecc.pk.x, cmd->key, 32); + memcpy(ecc.pk.y, &cmd->key[32], 32); + + send_cmd_status(BT_HCI_OP_LE_GENERATE_DHKEY, 0); + + net_buf_unref(buf); + + if (ecc_valid_public_key(&ecc.pk) < 0) { + ret = TC_CRYPTO_FAIL; + } else { + ret = ecdh_shared_secret(ecc.dhkey, &ecc.pk, private_key); + } + + buf = bt_buf_get_rx(K_FOREVER); + bt_buf_set_type(buf, BT_BUF_EVT); + + hdr = net_buf_add(buf, sizeof(*hdr)); + hdr->evt = BT_HCI_EVT_LE_META_EVENT; + hdr->len = sizeof(*meta) + sizeof(*evt); + + meta = net_buf_add(buf, sizeof(*meta)); + meta->subevent = BT_HCI_EVT_LE_GENERATE_DHKEY_COMPLETE; + + evt = net_buf_add(buf, sizeof(*evt)); + + if (ret == TC_CRYPTO_FAIL) { + evt->status = BT_HCI_ERR_UNSPECIFIED; + memset(evt->dhkey, 0, sizeof(evt->dhkey)); + } else { + evt->status = 0; + memcpy(evt->dhkey, ecc.dhkey, sizeof(ecc.dhkey)); + } + + bt_recv(buf); +} + +static void ecc_thread(void *args) +{ + while (true) { + struct net_buf *buf; + struct bt_hci_cmd_hdr *chdr; + uint16_t opcode; + + buf = k_fifo_get(&ecc_queue, K_FOREVER); + chdr = (void *)buf->data; + opcode = sys_le16_to_cpu(chdr->opcode); + switch (opcode) { + case BT_HCI_OP_LE_P256_PUBLIC_KEY: + emulate_le_p256_public_key_cmd(buf); + break; + case BT_HCI_OP_LE_GENERATE_DHKEY: + emulate_le_generate_dhkey(buf); + break; + default: + BT_ERR("Unhandled command for ECC task (opcode %x)", + opcode); + net_buf_unref(buf); + break; + } + } +} + +static void clear_ecc_events(struct net_buf *buf) +{ + struct bt_hci_cp_le_set_event_mask *cmd; + + cmd = (void *)buf->data + sizeof(struct bt_hci_cmd_hdr); + + /* + * don't enable controller ECC events as those will be generated from + * emulation code + */ + cmd->events[0] &= ~0x80; /* LE Read Local P-256 PKey Compl */ + cmd->events[1] &= ~0x01; /* LE Generate DHKey Compl Event */ +} + +static int ecc_send(struct net_buf *buf) +{ + if (bt_buf_get_type(buf) == BT_BUF_CMD) { + + struct bt_hci_cmd_hdr *chdr = (void *)buf->data; + + switch (sys_le16_to_cpu(chdr->opcode)) { + case BT_HCI_OP_LE_P256_PUBLIC_KEY: + case BT_HCI_OP_LE_GENERATE_DHKEY: + net_buf_put(&ecc_queue, buf); + return 0; + case BT_HCI_OP_LE_SET_EVENT_MASK: + clear_ecc_events(buf); + break; + default: + break; + } + } + + return drv_send(buf); +} + +void bt_hci_ecc_init(void) +{ + k_fifo_init(&ecc_queue, "ecc queue",NULL, CONFIG_BLUETOOTH_HCI_CMD_COUNT); + k_thread_spawn("hci ecc",ecc_thread_stack, sizeof(ecc_thread_stack),\ + ecc_thread, NULL, 45); + + /* set wrapper for driver send function */ + drv_send = bt_dev.drv->send; + bt_dev.drv->send = ecc_send; +} diff --git a/kernel/protocols/bluetooth/host/hci_ecc.h b/kernel/protocols/bluetooth/host/hci_ecc.h new file mode 100644 index 0000000000..fd7bcf6777 --- /dev/null +++ b/kernel/protocols/bluetooth/host/hci_ecc.h @@ -0,0 +1,13 @@ +/* hci_ecc.h - HCI ECC emulation */ + +/* + * Copyright (c) 2016 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#if defined(CONFIG_BLUETOOTH_TINYCRYPT_ECC) +void bt_hci_ecc_init(void); +#else +#define bt_hci_ecc_init() +#endif /* CONFIG_BLUETOOTH_TINYCRYPT_ECC */ diff --git a/kernel/protocols/bluetooth/host/keys.c b/kernel/protocols/bluetooth/host/keys.c new file mode 100644 index 0000000000..bc68161139 --- /dev/null +++ b/kernel/protocols/bluetooth/host/keys.c @@ -0,0 +1,162 @@ +/* keys.c - Bluetooth key handling */ + +/* + * Copyright (c) 2015-2016 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_KEYS) +#include +#include +#include +#include + +#include "hci_core.h" +#include "smp.h" +#include "keys.h" + +static struct bt_keys key_pool[CONFIG_BLUETOOTH_MAX_PAIRED]; + +struct bt_keys *bt_keys_get_addr(const bt_addr_le_t *addr) +{ + struct bt_keys *keys; + int i; + + BT_DBG("%s", bt_addr_le_str(addr)); + + for (i = 0; i < ARRAY_SIZE(key_pool); i++) { + keys = &key_pool[i]; + + if (!bt_addr_le_cmp(&keys->addr, addr)) { + return keys; + } + + if (!bt_addr_le_cmp(&keys->addr, BT_ADDR_LE_ANY)) { + bt_addr_le_copy(&keys->addr, addr); + BT_DBG("created %p for %s", keys, bt_addr_le_str(addr)); + return keys; + } + } + + BT_DBG("unable to create keys for %s", bt_addr_le_str(addr)); + + return NULL; +} +struct bt_keys *bt_keys_find(int type, const bt_addr_le_t *addr) +{ + int i; + + BT_DBG("type %d %s", type, bt_addr_le_str(addr)); + + for (i = 0; i < ARRAY_SIZE(key_pool); i++) { + if ((key_pool[i].keys & type) && + !bt_addr_le_cmp(&key_pool[i].addr, addr)) { + return &key_pool[i]; + } + } + + return NULL; +} + +struct bt_keys *bt_keys_get_type(int type, const bt_addr_le_t *addr) +{ + struct bt_keys *keys; + + BT_DBG("type %d %s", type, bt_addr_le_str(addr)); + + keys = bt_keys_find(type, addr); + if (keys) { + return keys; + } + + keys = bt_keys_get_addr(addr); + if (!keys) { + return NULL; + } + + bt_keys_add_type(keys, type); + + return keys; +} + +struct bt_keys *bt_keys_find_irk(const bt_addr_le_t *addr) +{ + int i; + + BT_DBG("%s", bt_addr_le_str(addr)); + + if (!bt_addr_le_is_rpa(addr)) { + return NULL; + } + + for (i = 0; i < ARRAY_SIZE(key_pool); i++) { + if (!(key_pool[i].keys & BT_KEYS_IRK)) { + continue; + } + + if (!bt_addr_cmp(&addr->a, &key_pool[i].irk.rpa)) { + BT_DBG("cached RPA %s for %s", + bt_addr_str(&key_pool[i].irk.rpa), + bt_addr_le_str(&key_pool[i].addr)); + return &key_pool[i]; + } + } + + for (i = 0; i < ARRAY_SIZE(key_pool); i++) { + if (!(key_pool[i].keys & BT_KEYS_IRK)) { + continue; + } + + if (bt_smp_irk_matches(key_pool[i].irk.val, &addr->a)) { + BT_DBG("RPA %s matches %s", + bt_addr_str(&key_pool[i].irk.rpa), + bt_addr_le_str(&key_pool[i].addr)); + + bt_addr_copy(&key_pool[i].irk.rpa, &addr->a); + + return &key_pool[i]; + } + } + + BT_DBG("No IRK for %s", bt_addr_le_str(addr)); + + return NULL; +} + +struct bt_keys *bt_keys_find_addr(const bt_addr_le_t *addr) +{ + int i; + + BT_DBG("%s", bt_addr_le_str(addr)); + + for (i = 0; i < ARRAY_SIZE(key_pool); i++) { + if (!bt_addr_le_cmp(&key_pool[i].addr, addr)) { + return &key_pool[i]; + } + } + + return NULL; +} + +void bt_keys_add_type(struct bt_keys *keys, int type) +{ + keys->keys |= type; +} + +void bt_keys_clear(struct bt_keys *keys) +{ + BT_DBG("keys for %s", bt_addr_le_str(&keys->addr)); + + memset(keys, 0, sizeof(*keys)); +} + +void bt_keys_clear_all(void) +{ + memset(key_pool, 0, sizeof(key_pool)); +} diff --git a/kernel/protocols/bluetooth/host/keys.h b/kernel/protocols/bluetooth/host/keys.h new file mode 100644 index 0000000000..6a7e72df1a --- /dev/null +++ b/kernel/protocols/bluetooth/host/keys.h @@ -0,0 +1,90 @@ +/* keys.h - Bluetooth key handling */ + +/* + * Copyright (c) 2015-2016 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +enum { + BT_KEYS_SLAVE_LTK = BIT(0), + BT_KEYS_IRK = BIT(1), + BT_KEYS_LTK = BIT(2), + BT_KEYS_LOCAL_CSRK = BIT(3), + BT_KEYS_REMOTE_CSRK = BIT(4), + BT_KEYS_LTK_P256 = BIT(5), + + BT_KEYS_ALL = (BT_KEYS_SLAVE_LTK | BT_KEYS_IRK | \ + BT_KEYS_LTK | BT_KEYS_LOCAL_CSRK | \ + BT_KEYS_REMOTE_CSRK | BT_KEYS_LTK_P256), +}; + +enum { + BT_KEYS_AUTHENTICATED, + BT_KEYS_DEBUG, + + /* Total number of flags - must be at the end of the enum */ + BT_KEYS_NUM_FLAGS, +}; + +struct bt_ltk { + uint64_t rand; + uint16_t ediv; + uint8_t val[16]; +}; + +struct bt_irk { + uint8_t val[16]; + bt_addr_t rpa; +}; + +struct bt_csrk { + uint8_t val[16]; + uint32_t cnt; +}; + +struct bt_keys { + bt_addr_le_t addr; + uint8_t enc_size; + ATOMIC_DEFINE(flags, BT_KEYS_NUM_FLAGS); + uint16_t keys; + struct bt_ltk ltk; + struct bt_irk irk; +#if defined(CONFIG_BLUETOOTH_SIGNING) + struct bt_csrk local_csrk; + struct bt_csrk remote_csrk; +#endif /* BLUETOOTH_SIGNING */ +#if !defined(CONFIG_BLUETOOTH_SMP_SC_ONLY) + struct bt_ltk slave_ltk; +#endif /* CONFIG_BLUETOOTH_SMP_SC_ONLY */ +}; + +struct bt_keys *bt_keys_get_addr(const bt_addr_le_t *addr); +struct bt_keys *bt_keys_get_type(int type, const bt_addr_le_t *addr); +struct bt_keys *bt_keys_find(int type, const bt_addr_le_t *addr); +struct bt_keys *bt_keys_find_irk(const bt_addr_le_t *addr); +struct bt_keys *bt_keys_find_addr(const bt_addr_le_t *addr); + +void bt_keys_add_type(struct bt_keys *keys, int type); +void bt_keys_clear(struct bt_keys *keys); +void bt_keys_clear_all(void); + +enum { + BT_LINK_KEY_AUTHENTICATED, + BT_LINK_KEY_DEBUG, + BT_LINK_KEY_SC, + + /* Total number of flags - must be at the end of the enum */ + BT_LINK_KEY_NUM_FLAGS, +}; + +struct bt_keys_link_key { + bt_addr_t addr; + ATOMIC_DEFINE(flags, BT_LINK_KEY_NUM_FLAGS); + uint8_t val[16]; +}; + +struct bt_keys_link_key *bt_keys_get_link_key(const bt_addr_t *addr); +struct bt_keys_link_key *bt_keys_find_link_key(const bt_addr_t *addr); +void bt_keys_link_key_clear(struct bt_keys_link_key *link_key); +void bt_keys_link_key_clear_addr(const bt_addr_t *addr); diff --git a/kernel/protocols/bluetooth/host/l2cap.c b/kernel/protocols/bluetooth/host/l2cap.c new file mode 100644 index 0000000000..962c253486 --- /dev/null +++ b/kernel/protocols/bluetooth/host/l2cap.c @@ -0,0 +1,1718 @@ +/* l2cap.c - L2CAP handling */ + +/* + * Copyright (c) 2015-2016 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_L2CAP) +#include +#include +#include +#include +#include + +#include "hci_core.h" +#include "conn_internal.h" +#include "l2cap_internal.h" +#undef accept +#undef recv + +#define LE_CHAN_RTX(_w) CONTAINER_OF(_w, struct bt_l2cap_le_chan, chan.rtx_work) + +#define L2CAP_LE_MIN_MTU 23 +#define L2CAP_LE_MAX_CREDITS (CONFIG_BLUETOOTH_RX_BUF_COUNT - 1) +#define L2CAP_LE_CREDITS_THRESHOLD(_creds) (_creds / 2) + +#define L2CAP_LE_CID_DYN_START 0x0040 +#define L2CAP_LE_CID_DYN_END 0x007f +#define L2CAP_LE_CID_IS_DYN(_cid) \ + (_cid >= L2CAP_LE_CID_DYN_START && _cid <= L2CAP_LE_CID_DYN_END) + +#define L2CAP_LE_PSM_START 0x0001 +#define L2CAP_LE_PSM_END 0x00ff + +#define L2CAP_CONN_TIMEOUT K_SECONDS(40) +#define L2CAP_DISC_TIMEOUT K_SECONDS(1) + +/* Size of MTU is based on the maximum amount of data the buffer can hold + * excluding ACL and driver headers. + */ +#define BT_L2CAP_MAX_LE_MPS BT_L2CAP_RX_MTU +/* For now use MPS - SDU length to disable segmentation */ +#define BT_L2CAP_MAX_LE_MTU (BT_L2CAP_MAX_LE_MPS - 2) + +#if defined(CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL) +#define l2cap_lookup_ident(conn, ident) __l2cap_lookup_ident(conn, ident, false) +#define l2cap_remove_ident(conn, ident) __l2cap_lookup_ident(conn, ident, true) +#endif /* CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL */ + +/* Wrapper macros making action on channel's list assigned to connection */ +#define l2cap_lookup_chan(conn, chan) \ + __l2cap_chan(conn, chan, BT_L2CAP_CHAN_LOOKUP) +#define l2cap_detach_chan(conn, chan) \ + __l2cap_chan(conn, chan, BT_L2CAP_CHAN_DETACH) + +static struct bt_l2cap_fixed_chan *le_channels; +#if defined(CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL) +static struct bt_l2cap_server *servers; +#endif /* CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL */ + +#if defined(CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL) +/* Pool for outgoing LE data packets, MTU is 23 */ +NET_BUF_POOL_DEFINE(le_data_pool, CONFIG_BLUETOOTH_MAX_CONN, + BT_L2CAP_BUF_SIZE(BT_L2CAP_MAX_LE_MPS), + BT_BUF_USER_DATA_MIN, NULL); +#endif /* CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL */ + +/* L2CAP signalling channel specific context */ +struct bt_l2cap { + /* The channel this context is associated with */ + struct bt_l2cap_le_chan chan; +}; + +static struct bt_l2cap bt_l2cap_pool[CONFIG_BLUETOOTH_MAX_CONN]; + +static uint8_t get_ident(void) +{ + static uint8_t ident; + + ident++; + /* handle integer overflow (0 is not valid) */ + if (!ident) { + ident++; + } + + return ident; +} + +void bt_l2cap_le_fixed_chan_register(struct bt_l2cap_fixed_chan *chan) +{ + BT_DBG("CID 0x%04x", chan->cid); + + chan->_next = le_channels; + le_channels = chan; +} + +static struct bt_l2cap_le_chan *l2cap_chan_alloc_cid(struct bt_conn *conn, + struct bt_l2cap_chan *chan) +{ + struct bt_l2cap_le_chan *ch = BT_L2CAP_LE_CHAN(chan); + uint16_t cid; + + /* + * No action needed if there's already a CID allocated, e.g. in + * the case of a fixed channel. + */ + if (ch && ch->rx.cid > 0) { + return ch; + } + + for (cid = L2CAP_LE_CID_DYN_START; cid <= L2CAP_LE_CID_DYN_END; cid++) { + if (ch && !bt_l2cap_le_lookup_rx_cid(conn, cid)) { + ch->rx.cid = cid; + return ch; + } + } + + return NULL; +} + +#if defined(CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL) +static struct bt_l2cap_le_chan * +__l2cap_lookup_ident(struct bt_conn *conn, uint16_t ident, bool remove) +{ + struct bt_l2cap_chan *chan, *prev; + + for (chan = conn->channels, prev = NULL; chan; + prev = chan, chan = chan->_next) { + if (chan->ident != ident) { + continue; + } + + if (!remove) { + return BT_L2CAP_LE_CHAN(chan); + } + + if (!prev) { + conn->channels = chan->_next; + } else { + prev->_next = chan->_next; + } + + return BT_L2CAP_LE_CHAN(chan); + } + + return NULL; +} +#endif /* CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL */ + +static struct bt_l2cap_le_chan *__l2cap_chan(struct bt_conn *conn, + struct bt_l2cap_chan *ch, + enum l2cap_conn_list_action action) +{ + struct bt_l2cap_chan *chan, *prev; + + for (chan = conn->channels, prev = NULL; chan; + prev = chan, chan = chan->_next) { + if (chan != ch) { + continue; + } + + switch (action) { + case BT_L2CAP_CHAN_DETACH: + if (!prev) { + conn->channels = chan->_next; + } else { + prev->_next = chan->_next; + } + + return BT_L2CAP_LE_CHAN(chan); + case BT_L2CAP_CHAN_LOOKUP: + default: + return BT_L2CAP_LE_CHAN(chan); + } + } + + return NULL; +} + +#if defined(CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL) +#if defined(CONFIG_BLUETOOTH_DEBUG_L2CAP) +const char *bt_l2cap_chan_state_str(bt_l2cap_chan_state_t state) +{ + switch (state) { + case BT_L2CAP_DISCONNECTED: + return "disconnected"; + case BT_L2CAP_CONNECT: + return "connect"; + case BT_L2CAP_CONFIG: + return "config"; + case BT_L2CAP_CONNECTED: + return "connected"; + case BT_L2CAP_DISCONNECT: + return "disconnect"; + default: + return "unknown"; + } +} + +void bt_l2cap_chan_set_state_debug(struct bt_l2cap_chan *chan, + bt_l2cap_chan_state_t state, + const char *func, int line) +{ + BT_DBG("chan %p psm 0x%04x %s -> %s", chan, chan->psm, + bt_l2cap_chan_state_str(chan->state), + bt_l2cap_chan_state_str(state)); + + /* check transitions validness */ + switch (state) { + case BT_L2CAP_DISCONNECTED: + /* regardless of old state always allows this state */ + break; + case BT_L2CAP_CONNECT: + if (chan->state != BT_L2CAP_DISCONNECTED) { + BT_WARN("%s()%d: invalid transition", func, line); + } + break; + case BT_L2CAP_CONFIG: + if (chan->state != BT_L2CAP_CONNECT) { + BT_WARN("%s()%d: invalid transition", func, line); + } + break; + case BT_L2CAP_CONNECTED: + if (chan->state != BT_L2CAP_CONFIG && + chan->state != BT_L2CAP_CONNECT) { + BT_WARN("%s()%d: invalid transition", func, line); + } + break; + case BT_L2CAP_DISCONNECT: + if (chan->state != BT_L2CAP_CONFIG && + chan->state != BT_L2CAP_CONNECTED) { + BT_WARN("%s()%d: invalid transition", func, line); + } + break; + default: + BT_ERR("%s()%d: unknown (%u) state was set", func, line, state); + return; + } + + chan->state = state; +} +#else +void bt_l2cap_chan_set_state(struct bt_l2cap_chan *chan, + bt_l2cap_chan_state_t state) +{ + chan->state = state; +} +#endif /* CONFIG_BLUETOOTH_DEBUG_L2CAP */ +#endif /* CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL */ + +void bt_l2cap_chan_del(struct bt_l2cap_chan *chan) +{ + BT_DBG("conn %p chan %p", chan->conn, chan); + + if (!chan->conn) { + goto destroy; + } + + if (chan->ops && chan->ops->disconnected) { + chan->ops->disconnected(chan); + } + + chan->conn = NULL; + +destroy: +#if defined(CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL) + /* Reset internal members of common channel */ + bt_l2cap_chan_set_state(chan, BT_L2CAP_DISCONNECTED); + chan->psm = 0; +#endif + + if (chan->destroy) { + chan->destroy(chan); + } +} + +static void l2cap_rtx_timeout(struct k_work *work) +{ + struct bt_l2cap_le_chan *chan = LE_CHAN_RTX(work); + + BT_ERR("chan %p timeout", chan); + + l2cap_detach_chan(chan->chan.conn, &chan->chan); + bt_l2cap_chan_del(&chan->chan); +} + +void bt_l2cap_chan_add(struct bt_conn *conn, struct bt_l2cap_chan *chan, + bt_l2cap_chan_destroy_t destroy) +{ + /* Attach channel to the connection */ + chan->_next = conn->channels; + conn->channels = chan; + chan->conn = conn; + chan->destroy = destroy; + + BT_DBG("conn %p chan %p", conn, chan); +} + +static bool l2cap_chan_add(struct bt_conn *conn, struct bt_l2cap_chan *chan, + bt_l2cap_chan_destroy_t destroy) +{ + struct bt_l2cap_le_chan *ch = l2cap_chan_alloc_cid(conn, chan); + + if (!ch) { + BT_ERR("Unable to allocate L2CAP CID"); + return false; + } + + k_delayed_work_init(&chan->rtx_work, l2cap_rtx_timeout); + + bt_l2cap_chan_add(conn, chan, destroy); + + if (IS_ENABLED(CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL) && + L2CAP_LE_CID_IS_DYN(ch->rx.cid)) { + bt_l2cap_chan_set_state(chan, BT_L2CAP_CONNECT); + } + + return true; +} + +void bt_l2cap_connected(struct bt_conn *conn) +{ + struct bt_l2cap_fixed_chan *fchan; + struct bt_l2cap_chan *chan; + + if (IS_ENABLED(CONFIG_BLUETOOTH_BREDR) && + conn->type == BT_CONN_TYPE_BR) { + bt_l2cap_br_connected(conn); + return; + } + + fchan = le_channels; + + for (; fchan; fchan = fchan->_next) { + struct bt_l2cap_le_chan *ch; + + if (fchan->accept(conn, &chan) < 0) { + continue; + } + + ch = BT_L2CAP_LE_CHAN(chan); + + /* Fill up remaining fixed channel context attached in + * fchan->accept() + */ + ch->rx.cid = fchan->cid; + ch->tx.cid = fchan->cid; + + if (!l2cap_chan_add(conn, chan, NULL)) { + return; + } + + if (chan->ops->connected) { + chan->ops->connected(chan); + } + } +} + +void bt_l2cap_disconnected(struct bt_conn *conn) +{ + struct bt_l2cap_chan *chan; + + for (chan = conn->channels; chan;) { + struct bt_l2cap_chan *next; + + /* prefetch since disconnected callback may cleanup */ + next = chan->_next; + + bt_l2cap_chan_del(chan); + + chan = next; + } + + conn->channels = NULL; +} + +static struct net_buf *l2cap_create_le_sig_pdu(uint8_t code, uint8_t ident, + uint16_t len) +{ + struct net_buf *buf; + struct bt_l2cap_sig_hdr *hdr; + + buf = bt_l2cap_create_pdu(NULL, 0); + + hdr = net_buf_add(buf, sizeof(*hdr)); + hdr->code = code; + hdr->ident = ident; + hdr->len = sys_cpu_to_le16(len); + + return buf; +} + +#if defined(CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL) +static void l2cap_chan_send_req(struct bt_l2cap_le_chan *chan, + struct net_buf *buf, int32_t timeout) +{ + /* BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part A] page 126: + * + * The value of this timer is implementation-dependent but the minimum + * initial value is 1 second and the maximum initial value is 60 + * seconds. One RTX timer shall exist for each outstanding signaling + * request, including each Echo Request. The timer disappears on the + * final expiration, when the response is received, or the physical + * link is lost. + */ + if (timeout) { + k_delayed_work_submit(&chan->chan.rtx_work, timeout); + } else { + k_delayed_work_cancel(&chan->chan.rtx_work); + } + + bt_l2cap_send(chan->chan.conn, BT_L2CAP_CID_LE_SIG, buf); +} + +static int l2cap_le_conn_req(struct bt_l2cap_le_chan *ch) +{ + struct net_buf *buf; + struct bt_l2cap_le_conn_req *req; + + ch->chan.ident = get_ident(); + + buf = l2cap_create_le_sig_pdu(BT_L2CAP_LE_CONN_REQ, ch->chan.ident, + sizeof(*req)); + + req = net_buf_add(buf, sizeof(*req)); + req->psm = sys_cpu_to_le16(ch->chan.psm); + req->scid = sys_cpu_to_le16(ch->rx.cid); + req->mtu = sys_cpu_to_le16(ch->rx.mtu); + req->mps = sys_cpu_to_le16(ch->rx.mps); + req->credits = sys_cpu_to_le16(ch->rx.init_credits); + + l2cap_chan_send_req(ch, buf, L2CAP_CONN_TIMEOUT); + + return 0; +} + +static void l2cap_le_encrypt_change(struct bt_l2cap_chan *chan, uint8_t status) +{ + /* Skip channels already connected or with a pending request */ + if (chan->state != BT_L2CAP_CONNECT || chan->ident) { + return; + } + + if (status) { + l2cap_detach_chan(chan->conn, chan); + bt_l2cap_chan_del(chan); + return; + } + + /* Retry to connect */ + l2cap_le_conn_req(BT_L2CAP_LE_CHAN(chan)); +} +#endif /* CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL */ + +void bt_l2cap_encrypt_change(struct bt_conn *conn, uint8_t hci_status) +{ + struct bt_l2cap_chan *chan; + + if (IS_ENABLED(CONFIG_BLUETOOTH_BREDR) && + conn->type == BT_CONN_TYPE_BR) { + l2cap_br_encrypt_change(conn, hci_status); + return; + } + + for (chan = conn->channels; chan; chan = chan->_next) { +#if defined(CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL) + l2cap_le_encrypt_change(chan, hci_status); +#endif + + if (chan->ops->encrypt_change) { + chan->ops->encrypt_change(chan, hci_status); + } + } +} + +struct net_buf *bt_l2cap_create_pdu(struct net_buf_pool *pool, size_t reserve) +{ + return bt_conn_create_pdu(pool, sizeof(struct bt_l2cap_hdr) + reserve); +} + +void bt_l2cap_send(struct bt_conn *conn, uint16_t cid, struct net_buf *buf) +{ + struct bt_l2cap_hdr *hdr; + + hdr = net_buf_push(buf, sizeof(*hdr)); + hdr->len = sys_cpu_to_le16(buf->len - sizeof(*hdr)); + hdr->cid = sys_cpu_to_le16(cid); + + bt_conn_send(conn, buf); +} + +static void l2cap_send_reject(struct bt_conn *conn, uint8_t ident, + uint16_t reason, void *data, uint8_t data_len) +{ + struct bt_l2cap_cmd_reject *rej; + struct net_buf *buf; + + buf = l2cap_create_le_sig_pdu(BT_L2CAP_CMD_REJECT, ident, + sizeof(*rej) + data_len); + + rej = net_buf_add(buf, sizeof(*rej)); + rej->reason = sys_cpu_to_le16(reason); + + if (data) { + net_buf_add_mem(buf, data, data_len); + } + + bt_l2cap_send(conn, BT_L2CAP_CID_LE_SIG, buf); +} + +static void le_conn_param_rsp(struct bt_l2cap *l2cap, struct net_buf *buf) +{ + struct bt_l2cap_conn_param_rsp *rsp = (void *)buf->data; + + if (buf->len < sizeof(*rsp)) { + BT_ERR("Too small LE conn param rsp"); + return; + } + + BT_DBG("LE conn param rsp result %u", sys_le16_to_cpu(rsp->result)); +} + +#if defined(CONFIG_BLUETOOTH_CENTRAL) +static void le_conn_param_update_req(struct bt_l2cap *l2cap, uint8_t ident, + struct net_buf *buf) +{ + struct bt_conn *conn = l2cap->chan.chan.conn; + struct bt_le_conn_param param; + struct bt_l2cap_conn_param_rsp *rsp; + struct bt_l2cap_conn_param_req *req = (void *)buf->data; + bool accepted; + + if (buf->len < sizeof(*req)) { + BT_ERR("Too small LE conn update param req"); + return; + } + + if (conn->role != BT_HCI_ROLE_MASTER) { + l2cap_send_reject(conn, ident, BT_L2CAP_REJ_NOT_UNDERSTOOD, + NULL, 0); + return; + } + + param.interval_min = sys_le16_to_cpu(req->min_interval); + param.interval_max = sys_le16_to_cpu(req->max_interval); + param.latency = sys_le16_to_cpu(req->latency); + param.timeout = sys_le16_to_cpu(req->timeout); + + BT_DBG("min 0x%04x max 0x%04x latency: 0x%04x timeout: 0x%04x", + param.interval_min, param.interval_max, param.latency, + param.timeout); + + buf = l2cap_create_le_sig_pdu(BT_L2CAP_CONN_PARAM_RSP, ident, + sizeof(*rsp)); + + accepted = le_param_req(conn, ¶m); + + rsp = net_buf_add(buf, sizeof(*rsp)); + if (accepted) { + rsp->result = sys_cpu_to_le16(BT_L2CAP_CONN_PARAM_ACCEPTED); + } else { + rsp->result = sys_cpu_to_le16(BT_L2CAP_CONN_PARAM_REJECTED); + } + + bt_l2cap_send(conn, BT_L2CAP_CID_LE_SIG, buf); + + if (accepted) { + bt_conn_le_conn_update(conn, ¶m); + } +} +#endif /* CONFIG_BLUETOOTH_CENTRAL */ + +#if defined(CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL) +static struct bt_l2cap_server *l2cap_server_lookup_psm(uint16_t psm) +{ + struct bt_l2cap_server *server; + + for (server = servers; server; server = server->_next) { + if (server->psm == psm) { + return server; + } + } + + return NULL; +} + +int bt_l2cap_server_register(struct bt_l2cap_server *server) +{ + if (server->psm < L2CAP_LE_PSM_START || + server->psm > L2CAP_LE_PSM_END || !server->accept) { + return -EINVAL; + } + + if (server->sec_level > BT_SECURITY_FIPS) { + return -EINVAL; + } else if (server->sec_level < BT_SECURITY_LOW) { + /* Level 0 is only applicable for BR/EDR */ + server->sec_level = BT_SECURITY_LOW; + } + + /* Check if given PSM is already in use */ + if (l2cap_server_lookup_psm(server->psm)) { + BT_DBG("PSM already registered"); + return -EADDRINUSE; + } + + BT_DBG("PSM 0x%04x", server->psm); + + server->_next = servers; + servers = server; + + return 0; +} + +static void l2cap_chan_rx_init(struct bt_l2cap_le_chan *chan) +{ + BT_DBG("chan %p", chan); + + /* Use existing MTU if defined */ + if (!chan->rx.mtu) { + chan->rx.mtu = BT_L2CAP_MAX_LE_MTU; + } + + /* Use existing credits if defined */ + if (!chan->rx.init_credits) { + if (chan->chan.ops->alloc_buf) { + /* Auto tune credits to receive a full packet */ + chan->rx.init_credits = chan->rx.mtu / + BT_L2CAP_MAX_LE_MPS; + } else { + chan->rx.init_credits = L2CAP_LE_MAX_CREDITS; + } + } + + chan->rx.mps = BT_L2CAP_MAX_LE_MPS; + k_sem_init(&chan->rx.credits, 0, UINT_MAX); +} + +static void l2cap_chan_tx_init(struct bt_l2cap_le_chan *chan) +{ + BT_DBG("chan %p", chan); + + memset(&chan->tx, 0, sizeof(chan->tx)); + k_sem_init(&chan->tx.credits, 0, UINT_MAX); + k_fifo_init(&chan->tx_queue,"",NULL,10); +} + +static void l2cap_chan_tx_give_credits(struct bt_l2cap_le_chan *chan, + uint16_t credits) +{ + BT_DBG("chan %p credits %u", chan, credits); + + while (credits--) { + k_sem_give(&chan->tx.credits); + } +} + +static void l2cap_chan_rx_give_credits(struct bt_l2cap_le_chan *chan, + uint16_t credits) +{ + BT_DBG("chan %p credits %u", chan, credits); + + while (credits--) { + k_sem_give(&chan->rx.credits); + } +} + +static void l2cap_chan_destroy(struct bt_l2cap_chan *chan) +{ + struct bt_l2cap_le_chan *ch = BT_L2CAP_LE_CHAN(chan); + struct net_buf *buf; + + BT_DBG("chan %p cid 0x%04x", ch, ch->rx.cid); + + /* Cancel ongoing work */ + k_delayed_work_cancel(&chan->rtx_work); + + /* Remove buffers on the TX queue */ + while ((buf = net_buf_get(&ch->tx_queue, K_NO_WAIT))) { + net_buf_unref(buf); + } + + /* Destroy segmented SDU if it exists */ + if (ch->_sdu) { + net_buf_unref(ch->_sdu); + ch->_sdu = NULL; + ch->_sdu_len = 0; + } +} + +static void le_conn_req(struct bt_l2cap *l2cap, uint8_t ident, + struct net_buf *buf) +{ + struct bt_conn *conn = l2cap->chan.chan.conn; + struct bt_l2cap_chan *chan; + struct bt_l2cap_server *server; + struct bt_l2cap_le_conn_req *req = (void *)buf->data; + struct bt_l2cap_le_conn_rsp *rsp; + uint16_t psm, scid, mtu, mps, credits; + + if (buf->len < sizeof(*req)) { + BT_ERR("Too small LE conn req packet size"); + return; + } + + psm = sys_le16_to_cpu(req->psm); + scid = sys_le16_to_cpu(req->scid); + mtu = sys_le16_to_cpu(req->mtu); + mps = sys_le16_to_cpu(req->mps); + credits = sys_le16_to_cpu(req->credits); + + BT_DBG("psm 0x%02x scid 0x%04x mtu %u mps %u credits %u", psm, scid, + mtu, mps, credits); + + if (mtu < L2CAP_LE_MIN_MTU || mps < L2CAP_LE_MIN_MTU) { + BT_ERR("Invalid LE-Conn Req params"); + return; + } + + buf = l2cap_create_le_sig_pdu(BT_L2CAP_LE_CONN_RSP, ident, + sizeof(*rsp)); + + rsp = net_buf_add(buf, sizeof(*rsp)); + memset(rsp, 0, sizeof(*rsp)); + + /* Check if there is a server registered */ + server = l2cap_server_lookup_psm(psm); + if (!server) { + rsp->result = sys_cpu_to_le16(BT_L2CAP_ERR_PSM_NOT_SUPP); + goto rsp; + } + + /* Check if connection has minimum required security level */ + if (conn->sec_level < server->sec_level) { + rsp->result = sys_cpu_to_le16(BT_L2CAP_ERR_AUTHENTICATION); + goto rsp; + } + + if (!L2CAP_LE_CID_IS_DYN(scid)) { + rsp->result = sys_cpu_to_le16(BT_L2CAP_ERR_INVALID_SCID); + goto rsp; + } + + chan = bt_l2cap_le_lookup_tx_cid(conn, scid); + if (chan) { + rsp->result = sys_cpu_to_le16(BT_L2CAP_ERR_SCID_IN_USE); + goto rsp; + } + + /* Request server to accept the new connection and allocate the + * channel. + * + * TODO: Handle different errors, it may be required to respond async. + */ + if (server->accept(conn, &chan) < 0) { + rsp->result = sys_cpu_to_le16(BT_L2CAP_ERR_NO_RESOURCES); + goto rsp; + } + + chan->required_sec_level = server->sec_level; + + if (l2cap_chan_add(conn, chan, l2cap_chan_destroy)) { + struct bt_l2cap_le_chan *ch = BT_L2CAP_LE_CHAN(chan); + + /* Init TX parameters */ + l2cap_chan_tx_init(ch); + ch->tx.cid = scid; + ch->tx.mps = mps; + ch->tx.mtu = mtu; + ch->tx.init_credits = credits; + l2cap_chan_tx_give_credits(ch, credits); + + /* Init RX parameters */ + l2cap_chan_rx_init(ch); + l2cap_chan_rx_give_credits(ch, ch->rx.init_credits); + + /* Set channel PSM */ + chan->psm = server->psm; + + /* Update state */ + bt_l2cap_chan_set_state(chan, BT_L2CAP_CONNECTED); + + if (chan->ops && chan->ops->connected) { + chan->ops->connected(chan); + } + + /* Prepare response protocol data */ + rsp->dcid = sys_cpu_to_le16(ch->rx.cid); + rsp->mps = sys_cpu_to_le16(ch->rx.mps); + rsp->mtu = sys_cpu_to_le16(ch->rx.mtu); + rsp->credits = sys_cpu_to_le16(ch->rx.init_credits); + rsp->result = BT_L2CAP_SUCCESS; + } else { + rsp->result = sys_cpu_to_le16(BT_L2CAP_ERR_NO_RESOURCES); + } +rsp: + bt_l2cap_send(conn, BT_L2CAP_CID_LE_SIG, buf); +} + +static struct bt_l2cap_le_chan *l2cap_remove_tx_cid(struct bt_conn *conn, + uint16_t cid) +{ + struct bt_l2cap_chan *chan, *prev; + + /* Protect fixed channels against accidental removal */ + if (!L2CAP_LE_CID_IS_DYN(cid)) { + return NULL; + } + + for (chan = conn->channels, prev = NULL; chan; + prev = chan, chan = chan->_next) { + /* get the app's l2cap object wherein this chan is contained */ + struct bt_l2cap_le_chan *ch = BT_L2CAP_LE_CHAN(chan); + + if (ch->tx.cid != cid) { + continue; + } + + if (!prev) { + conn->channels = chan->_next; + } else { + prev->_next = chan->_next; + } + + return ch; + } + + return NULL; +} + +static void le_disconn_req(struct bt_l2cap *l2cap, uint8_t ident, + struct net_buf *buf) +{ + struct bt_conn *conn = l2cap->chan.chan.conn; + struct bt_l2cap_le_chan *chan; + struct bt_l2cap_disconn_req *req = (void *)buf->data; + struct bt_l2cap_disconn_rsp *rsp; + uint16_t scid; + + if (buf->len < sizeof(*req)) { + BT_ERR("Too small LE conn req packet size"); + return; + } + + scid = sys_le16_to_cpu(req->scid); + + BT_DBG("scid 0x%04x dcid 0x%04x", scid, sys_le16_to_cpu(req->dcid)); + + chan = l2cap_remove_tx_cid(conn, scid); + if (!chan) { + struct bt_l2cap_cmd_reject_cid_data data; + + data.scid = req->scid; + data.dcid = req->dcid; + + l2cap_send_reject(conn, ident, BT_L2CAP_REJ_INVALID_CID, &data, + sizeof(data)); + return; + } + + buf = l2cap_create_le_sig_pdu(BT_L2CAP_DISCONN_RSP, ident, + sizeof(*rsp)); + + rsp = net_buf_add(buf, sizeof(*rsp)); + rsp->dcid = sys_cpu_to_le16(chan->rx.cid); + rsp->scid = sys_cpu_to_le16(chan->tx.cid); + + bt_l2cap_chan_del(&chan->chan); + + bt_l2cap_send(conn, BT_L2CAP_CID_LE_SIG, buf); +} + +static int l2cap_change_security(struct bt_l2cap_le_chan *chan, uint16_t err) +{ + switch (err) { + case BT_L2CAP_ERR_ENCRYPTION: + if (chan->chan.required_sec_level >= BT_SECURITY_MEDIUM) { + return -EALREADY; + } + chan->chan.required_sec_level = BT_SECURITY_MEDIUM; + break; + case BT_L2CAP_ERR_AUTHENTICATION: + if (chan->chan.required_sec_level < BT_SECURITY_MEDIUM) { + chan->chan.required_sec_level = BT_SECURITY_MEDIUM; + } else if (chan->chan.required_sec_level < BT_SECURITY_HIGH) { + chan->chan.required_sec_level = BT_SECURITY_HIGH; + } else if (chan->chan.required_sec_level < BT_SECURITY_FIPS) { + chan->chan.required_sec_level = BT_SECURITY_FIPS; + } else { + return -EALREADY; + } + break; + default: + return -EINVAL; + } + + return bt_conn_security(chan->chan.conn, chan->chan.required_sec_level); +} + +static void le_conn_rsp(struct bt_l2cap *l2cap, uint8_t ident, + struct net_buf *buf) +{ + struct bt_conn *conn = l2cap->chan.chan.conn; + struct bt_l2cap_le_chan *chan; + struct bt_l2cap_le_conn_rsp *rsp = (void *)buf->data; + uint16_t dcid, mtu, mps, credits, result; + + if (buf->len < sizeof(*rsp)) { + BT_ERR("Too small LE conn rsp packet size"); + return; + } + + dcid = sys_le16_to_cpu(rsp->dcid); + mtu = sys_le16_to_cpu(rsp->mtu); + mps = sys_le16_to_cpu(rsp->mps); + credits = sys_le16_to_cpu(rsp->credits); + result = sys_le16_to_cpu(rsp->result); + + BT_DBG("dcid 0x%04x mtu %u mps %u credits %u result 0x%04x", dcid, + mtu, mps, credits, result); + + /* Keep the channel in case of security errors */ + if (result == BT_L2CAP_SUCCESS || + result == BT_L2CAP_ERR_AUTHENTICATION || + result == BT_L2CAP_ERR_ENCRYPTION) { + chan = l2cap_lookup_ident(conn, ident); + } else { + chan = l2cap_remove_ident(conn, ident); + } + + if (!chan) { + BT_ERR("Cannot find channel for ident %u", ident); + return; + } + + /* Cancel RTX work */ + k_delayed_work_cancel(&chan->chan.rtx_work); + + /* Reset ident since it got a response */ + chan->chan.ident = 0; + + switch (result) { + case BT_L2CAP_SUCCESS: + chan->tx.cid = dcid; + chan->tx.mtu = mtu; + chan->tx.mps = mps; + + /* Update state */ + bt_l2cap_chan_set_state(&chan->chan, BT_L2CAP_CONNECTED); + + if (chan->chan.ops && chan->chan.ops->connected) { + chan->chan.ops->connected(&chan->chan); + } + + /* Give credits */ + l2cap_chan_tx_give_credits(chan, credits); + l2cap_chan_rx_give_credits(chan, chan->rx.init_credits); + + break; + case BT_L2CAP_ERR_AUTHENTICATION: + case BT_L2CAP_ERR_ENCRYPTION: + /* If security needs changing wait it to be completed */ + if (l2cap_change_security(chan, result) == 0) { + return; + } + l2cap_detach_chan(conn, &chan->chan); + default: + bt_l2cap_chan_del(&chan->chan); + } +} + +static void le_disconn_rsp(struct bt_l2cap *l2cap, uint8_t ident, + struct net_buf *buf) +{ + struct bt_conn *conn = l2cap->chan.chan.conn; + struct bt_l2cap_le_chan *chan; + struct bt_l2cap_disconn_rsp *rsp = (void *)buf->data; + uint16_t dcid; + + if (buf->len < sizeof(*rsp)) { + BT_ERR("Too small LE disconn rsp packet size"); + return; + } + + dcid = sys_le16_to_cpu(rsp->dcid); + + BT_DBG("dcid 0x%04x scid 0x%04x", dcid, sys_le16_to_cpu(rsp->scid)); + + chan = l2cap_remove_tx_cid(conn, dcid); + if (!chan) { + return; + } + + bt_l2cap_chan_del(&chan->chan); +} + +static struct net_buf *l2cap_chan_create_seg(struct bt_l2cap_le_chan *ch, + struct net_buf *buf, + size_t sdu_hdr_len) +{ + struct net_buf *seg; + uint16_t headroom; + uint16_t len; + + /* Segment if data (+ data headroom) is bigger than MPS */ + if (buf->len + sdu_hdr_len > ch->tx.mps) { + goto segment; + } + + /* Segment if there is no space in the user_data */ + if (buf->pool->user_data_size < BT_BUF_USER_DATA_MIN) { + BT_WARN("Too small buffer user_data_size %u", + buf->pool->user_data_size); + goto segment; + } + + headroom = sizeof(struct bt_hci_acl_hdr) + + sizeof(struct bt_l2cap_hdr) + sdu_hdr_len; + + /* Check if original buffer has enough headroom and don't have any + * fragments. + */ + if (net_buf_headroom(buf) >= headroom && !buf->frags) { + if (sdu_hdr_len) { + /* Push SDU length if set */ + net_buf_push_le16(buf, net_buf_frags_len(buf)); + } + return net_buf_ref(buf); + } + +segment: + seg = bt_l2cap_create_pdu(&le_data_pool, 0); + + if (sdu_hdr_len) { + net_buf_add_le16(seg, net_buf_frags_len(buf)); + } + + /* Don't send more that TX MPS including SDU length */ + len = min(net_buf_tailroom(seg), ch->tx.mps - sdu_hdr_len); + /* Limit if original buffer is smaller than the segment */ + len = min(buf->len, len); + net_buf_add_mem(seg, buf->data, len); + net_buf_pull(buf, len); + + BT_DBG("ch %p seg %p len %u", ch, seg, seg->len); + + return seg; +} + +static int l2cap_chan_le_send(struct bt_l2cap_le_chan *ch, struct net_buf *buf, + uint16_t sdu_hdr_len) +{ + int len; + + /* Wait for credits */ + if (k_sem_take(&ch->tx.credits, K_NO_WAIT)) { + BT_DBG("No credits to transmit packet"); + return -EAGAIN; + } + + buf = l2cap_chan_create_seg(ch, buf, sdu_hdr_len); + if (!buf) { + return -ENOMEM; + } + + /* Channel may have been disconnected while waiting for credits */ + if (!ch->chan.conn) { + net_buf_unref(buf); + return -ECONNRESET; + } + + BT_DBG("ch %p cid 0x%04x len %u credits %u", ch, ch->tx.cid, + buf->len, k_sem_count_get(&ch->tx.credits)); + + len = buf->len; + + bt_l2cap_send(ch->chan.conn, ch->tx.cid, buf); + + return len; +} + +static int l2cap_chan_le_send_sdu(struct bt_l2cap_le_chan *ch, + struct net_buf *buf, int sent) +{ + int ret, total_len; + struct net_buf *frag; + + total_len = net_buf_frags_len(buf) + sent; + + if (total_len > ch->tx.mtu) { + return -EMSGSIZE; + } + + frag = buf; + if (!frag->len && frag->frags) { + frag = frag->frags; + } + + if (!sent) { + /* Add SDU length for the first segment */ + sent = l2cap_chan_le_send(ch, frag, BT_L2CAP_SDU_HDR_LEN); + if (sent < 0) { + if (sent == -EAGAIN) { + sent = 0; + /* Store sent data into user_data */ + memcpy(net_buf_user_data(buf), &sent, + sizeof(sent)); + } + return sent; + } + } + + /* Send remaining segments */ + for (ret = 0; sent < total_len; sent += ret) { + /* Proceed to next fragment */ + if (!frag->len) { + frag = net_buf_frag_del(buf, frag); + } + + ret = l2cap_chan_le_send(ch, frag, 0); + if (ret < 0) { + if (ret == -EAGAIN) { + /* Store sent data into user_data */ + memcpy(net_buf_user_data(buf), &sent, + sizeof(sent)); + } + return ret; + } + } + + BT_DBG("ch %p cid 0x%04x sent %u", ch, ch->tx.cid, sent); + + net_buf_unref(buf); + + return ret; +} + +static struct net_buf *l2cap_chan_le_get_tx_buf(struct bt_l2cap_le_chan *ch) +{ + struct net_buf *buf; + + /* Return current buffer */ + if (ch->tx_buf) { + buf = ch->tx_buf; + ch->tx_buf = NULL; + return buf; + } + + return net_buf_get(&ch->tx_queue, K_NO_WAIT); +} + +static void l2cap_chan_le_send_resume(struct bt_l2cap_le_chan *ch) +{ + struct net_buf *buf; + + /* Resume tx in case there are buffers in the queue */ + while ((buf = l2cap_chan_le_get_tx_buf(ch))) { + int sent = *((int *)net_buf_user_data(buf)); + + BT_DBG("buf %p sent %u", buf, sent); + + sent = l2cap_chan_le_send_sdu(ch, buf, sent); + if (sent < 0) { + if (sent == -EAGAIN) { + ch->tx_buf = buf; + } + break; + } + } +} + +static void le_credits(struct bt_l2cap *l2cap, uint8_t ident, + struct net_buf *buf) +{ + struct bt_conn *conn = l2cap->chan.chan.conn; + struct bt_l2cap_chan *chan; + struct bt_l2cap_le_credits *ev = (void *)buf->data; + struct bt_l2cap_le_chan *ch; + uint16_t credits, cid; + + if (buf->len < sizeof(*ev)) { + BT_ERR("Too small LE Credits packet size"); + return; + } + + cid = sys_le16_to_cpu(ev->cid); + credits = sys_le16_to_cpu(ev->credits); + + BT_DBG("cid 0x%04x credits %u", cid, credits); + + chan = bt_l2cap_le_lookup_tx_cid(conn, cid); + if (!chan) { + BT_ERR("Unable to find channel of LE Credits packet"); + return; + } + + ch = BT_L2CAP_LE_CHAN(chan); + + if (k_sem_count_get(&ch->tx.credits) + credits > UINT16_MAX) { + BT_ERR("Credits overflow"); + bt_l2cap_chan_disconnect(chan); + return; + } + + l2cap_chan_tx_give_credits(ch, credits); + + BT_DBG("chan %p total credits %u", ch, + k_sem_count_get(&ch->tx.credits)); + + l2cap_chan_le_send_resume(ch); +} + +static void reject_cmd(struct bt_l2cap *l2cap, uint8_t ident, + struct net_buf *buf) +{ + struct bt_conn *conn = l2cap->chan.chan.conn; + struct bt_l2cap_le_chan *chan; + + /* Check if there is a outstanding channel */ + chan = l2cap_remove_ident(conn, ident); + if (!chan) { + return; + } + + bt_l2cap_chan_del(&chan->chan); +} +#endif /* CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL */ + +static void l2cap_recv(struct bt_l2cap_chan *chan, struct net_buf *buf) +{ + struct bt_l2cap *l2cap = CONTAINER_OF(chan, struct bt_l2cap, chan); + struct bt_l2cap_sig_hdr *hdr = (void *)buf->data; + uint16_t len; + + if (buf->len < sizeof(*hdr)) { + BT_ERR("Too small L2CAP signaling PDU"); + return; + } + + len = sys_le16_to_cpu(hdr->len); + net_buf_pull(buf, sizeof(*hdr)); + + BT_DBG("Signaling code 0x%02x ident %u len %u", hdr->code, + hdr->ident, len); + + if (buf->len != len) { + BT_ERR("L2CAP length mismatch (%u != %u)", buf->len, len); + return; + } + + if (!hdr->ident) { + BT_ERR("Invalid ident value in L2CAP PDU"); + return; + } + + switch (hdr->code) { + case BT_L2CAP_CONN_PARAM_RSP: + le_conn_param_rsp(l2cap, buf); + break; +#if defined(CONFIG_BLUETOOTH_CENTRAL) + case BT_L2CAP_CONN_PARAM_REQ: + le_conn_param_update_req(l2cap, hdr->ident, buf); + break; +#endif /* CONFIG_BLUETOOTH_CENTRAL */ +#if defined(CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL) + case BT_L2CAP_LE_CONN_REQ: + le_conn_req(l2cap, hdr->ident, buf); + break; + case BT_L2CAP_LE_CONN_RSP: + le_conn_rsp(l2cap, hdr->ident, buf); + break; + case BT_L2CAP_DISCONN_REQ: + le_disconn_req(l2cap, hdr->ident, buf); + break; + case BT_L2CAP_DISCONN_RSP: + le_disconn_rsp(l2cap, hdr->ident, buf); + break; + case BT_L2CAP_LE_CREDITS: + le_credits(l2cap, hdr->ident, buf); + break; + case BT_L2CAP_CMD_REJECT: + reject_cmd(l2cap, hdr->ident, buf); + break; +#else + case BT_L2CAP_CMD_REJECT: + /* Ignored */ + break; +#endif /* CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL */ + default: + BT_WARN("Unknown L2CAP PDU code 0x%02x", hdr->code); + l2cap_send_reject(chan->conn, hdr->ident, + BT_L2CAP_REJ_NOT_UNDERSTOOD, NULL, 0); + break; + } +} + +#if defined(CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL) +static void l2cap_chan_update_credits(struct bt_l2cap_le_chan *chan) +{ + struct net_buf *buf; + struct bt_l2cap_le_credits *ev; + uint16_t credits; + + /* Only give more credits if it went bellow the defined threshold */ + if (k_sem_count_get(&chan->rx.credits) > + L2CAP_LE_CREDITS_THRESHOLD(chan->rx.init_credits)) { + goto done; + } + + /* Restore credits */ + credits = chan->rx.init_credits - k_sem_count_get(&chan->rx.credits); + l2cap_chan_rx_give_credits(chan, credits); + + buf = l2cap_create_le_sig_pdu(BT_L2CAP_LE_CREDITS, get_ident(), + sizeof(*ev)); + + ev = net_buf_add(buf, sizeof(*ev)); + ev->cid = sys_cpu_to_le16(chan->rx.cid); + ev->credits = sys_cpu_to_le16(credits); + + bt_l2cap_send(chan->chan.conn, BT_L2CAP_CID_LE_SIG, buf); + +done: + BT_DBG("chan %p credits %u", chan, k_sem_count_get(&chan->rx.credits)); +} + +static struct net_buf *l2cap_alloc_frag(struct bt_l2cap_le_chan *chan) +{ + struct net_buf *frag = NULL; + + frag = chan->chan.ops->alloc_buf(&chan->chan); + if (!frag) { + return NULL; + } + + BT_DBG("frag %p tailroom %zu", frag, net_buf_tailroom(frag)); + + net_buf_frag_add(chan->_sdu, frag); + + return frag; +} + +static void l2cap_chan_le_recv_sdu(struct bt_l2cap_le_chan *chan, + struct net_buf *buf) +{ + struct net_buf *frag; + uint16_t len; + + BT_DBG("chan %p len %u sdu %zu", chan, buf->len, + net_buf_frags_len(chan->_sdu)); + + if (net_buf_frags_len(chan->_sdu) + buf->len > chan->_sdu_len) { + BT_ERR("SDU length mismatch"); + bt_l2cap_chan_disconnect(&chan->chan); + return; + } + + /* Jump to last fragment */ + frag = net_buf_frag_last(chan->_sdu); + + while (buf->len) { + /* Check if there is any space left in the current fragment */ + if (!net_buf_tailroom(frag)) { + frag = l2cap_alloc_frag(chan); + if (!frag) { + BT_ERR("Unable to store SDU"); + bt_l2cap_chan_disconnect(&chan->chan); + return; + } + } + + len = min(net_buf_tailroom(frag), buf->len); + net_buf_add_mem(frag, buf->data, len); + net_buf_pull(buf, len); + + BT_DBG("frag %p len %u", frag, frag->len); + } + + if (net_buf_frags_len(chan->_sdu) == chan->_sdu_len) { + /* Receiving complete SDU, notify channel and reset SDU buf */ + chan->chan.ops->recv(&chan->chan, chan->_sdu); + net_buf_unref(chan->_sdu); + chan->_sdu = NULL; + chan->_sdu_len = 0; + } + + l2cap_chan_update_credits(chan); +} + +static void l2cap_chan_le_recv(struct bt_l2cap_le_chan *chan, + struct net_buf *buf) +{ + uint16_t sdu_len; + + if (k_sem_take(&chan->rx.credits, K_NO_WAIT)) { + BT_ERR("No credits to receive packet"); + bt_l2cap_chan_disconnect(&chan->chan); + return; + } + + /* Check if segments already exist */ + if (chan->_sdu) { + l2cap_chan_le_recv_sdu(chan, buf); + return; + } + + sdu_len = net_buf_pull_le16(buf); + + BT_DBG("chan %p len %u sdu_len %u", chan, buf->len, sdu_len); + + if (sdu_len > chan->rx.mtu) { + BT_ERR("Invalid SDU length"); + bt_l2cap_chan_disconnect(&chan->chan); + return; + } + + /* Always allocate buffer from the channel if supported. */ + if (chan->chan.ops && chan->chan.ops->alloc_buf) { + chan->_sdu = chan->chan.ops->alloc_buf(&chan->chan); + if (!chan->_sdu) { + BT_ERR("Unable to allocate buffer for SDU"); + bt_l2cap_chan_disconnect(&chan->chan); + return; + } + chan->_sdu_len = sdu_len; + l2cap_chan_le_recv_sdu(chan, buf); + return; + } + + chan->chan.ops->recv(&chan->chan, buf); + + l2cap_chan_update_credits(chan); +} +#endif /* CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL */ + +static void l2cap_chan_recv(struct bt_l2cap_chan *chan, struct net_buf *buf) +{ +#if defined(CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL) + struct bt_l2cap_le_chan *ch = BT_L2CAP_LE_CHAN(chan); + + if (L2CAP_LE_CID_IS_DYN(ch->rx.cid)) { + l2cap_chan_le_recv(ch, buf); + return; + } +#endif /* CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL */ + + BT_DBG("chan %p len %u", chan, buf->len); + + chan->ops->recv(chan, buf); +} + +void bt_l2cap_recv(struct bt_conn *conn, struct net_buf *buf) +{ + struct bt_l2cap_hdr *hdr = (void *)buf->data; + struct bt_l2cap_chan *chan; + uint16_t cid; + + if (IS_ENABLED(CONFIG_BLUETOOTH_BREDR) && + conn->type == BT_CONN_TYPE_BR) { + bt_l2cap_br_recv(conn, buf); + return; + } + + if (buf->len < sizeof(*hdr)) { + BT_ERR("Too small L2CAP PDU received"); + net_buf_unref(buf); + return; + } + + cid = sys_le16_to_cpu(hdr->cid); + net_buf_pull(buf, sizeof(*hdr)); + + BT_DBG("Packet for CID %u len %u", cid, buf->len); + + chan = bt_l2cap_le_lookup_rx_cid(conn, cid); + if (!chan) { + BT_WARN("Ignoring data for unknown CID 0x%04x", cid); + net_buf_unref(buf); + return; + } + + l2cap_chan_recv(chan, buf); + net_buf_unref(buf); +} + +int bt_l2cap_update_conn_param(struct bt_conn *conn, + const struct bt_le_conn_param *param) +{ + struct bt_l2cap_conn_param_req *req; + struct net_buf *buf; + + buf = l2cap_create_le_sig_pdu(BT_L2CAP_CONN_PARAM_REQ, get_ident(), + sizeof(*req)); + + req = net_buf_add(buf, sizeof(*req)); + req->min_interval = sys_cpu_to_le16(param->interval_min); + req->max_interval = sys_cpu_to_le16(param->interval_max); + req->latency = sys_cpu_to_le16(param->latency); + req->timeout = sys_cpu_to_le16(param->timeout); + + bt_l2cap_send(conn, BT_L2CAP_CID_LE_SIG, buf); + + return 0; +} + +static void l2cap_connected(struct bt_l2cap_chan *chan) +{ + BT_DBG("ch %p cid 0x%04x", BT_L2CAP_LE_CHAN(chan), + BT_L2CAP_LE_CHAN(chan)->rx.cid); +} + +static void l2cap_disconnected(struct bt_l2cap_chan *chan) +{ + BT_DBG("ch %p cid 0x%04x", BT_L2CAP_LE_CHAN(chan), + BT_L2CAP_LE_CHAN(chan)->rx.cid); +} + +static int l2cap_accept(struct bt_conn *conn, struct bt_l2cap_chan **chan) +{ + int i; + static struct bt_l2cap_chan_ops ops = { + .connected = l2cap_connected, + .disconnected = l2cap_disconnected, + .recv = l2cap_recv, + }; + + BT_DBG("conn %p handle %u", conn, conn->handle); + + for (i = 0; i < ARRAY_SIZE(bt_l2cap_pool); i++) { + struct bt_l2cap *l2cap = &bt_l2cap_pool[i]; + + if (l2cap->chan.chan.conn) { + continue; + } + + l2cap->chan.chan.ops = &ops; + *chan = &l2cap->chan.chan; + + return 0; + } + + BT_ERR("No available L2CAP context for conn %p", conn); + + return -ENOMEM; +} + +void bt_l2cap_init(void) +{ + static struct bt_l2cap_fixed_chan chan = { + .cid = BT_L2CAP_CID_LE_SIG, + .accept = l2cap_accept, + }; + + bt_l2cap_le_fixed_chan_register(&chan); + + if (IS_ENABLED(CONFIG_BLUETOOTH_BREDR)) { + bt_l2cap_br_init(); + } + +#if defined(CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL) + NET_BUF_POOL_INIT(le_data_pool); +#endif +} + +struct bt_l2cap_chan *bt_l2cap_le_lookup_tx_cid(struct bt_conn *conn, + uint16_t cid) +{ + struct bt_l2cap_chan *chan; + + for (chan = conn->channels; chan; chan = chan->_next) { + struct bt_l2cap_le_chan *ch = BT_L2CAP_LE_CHAN(chan); + + if (ch->tx.cid == cid) + return chan; + } + + return NULL; +} + +struct bt_l2cap_chan *bt_l2cap_le_lookup_rx_cid(struct bt_conn *conn, + uint16_t cid) +{ + struct bt_l2cap_chan *chan; + + for (chan = conn->channels; chan; chan = chan->_next) { + struct bt_l2cap_le_chan *ch = BT_L2CAP_LE_CHAN(chan); + + if (ch->rx.cid == cid) { + return chan; + } + } + + return NULL; +} + +#if defined(CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL) +static int l2cap_le_connect(struct bt_conn *conn, struct bt_l2cap_le_chan *ch, + uint16_t psm) +{ + if (psm < L2CAP_LE_PSM_START || psm > L2CAP_LE_PSM_END) { + return -EINVAL; + } + + l2cap_chan_tx_init(ch); + l2cap_chan_rx_init(ch); + + if (!l2cap_chan_add(conn, &ch->chan, l2cap_chan_destroy)) { + return -ENOMEM; + } + + ch->chan.psm = psm; + + return l2cap_le_conn_req(ch); +} + +int bt_l2cap_chan_connect(struct bt_conn *conn, struct bt_l2cap_chan *chan, + uint16_t psm) +{ + BT_DBG("conn %p chan %p psm 0x%04x", conn, chan, psm); + + if (!conn || conn->state != BT_CONN_CONNECTED) { + return -ENOTCONN; + } + + if (!chan) { + return -EINVAL; + } + + if (IS_ENABLED(CONFIG_BLUETOOTH_BREDR) && + conn->type == BT_CONN_TYPE_BR) { + return bt_l2cap_br_chan_connect(conn, chan, psm); + } + + if (chan->required_sec_level > BT_SECURITY_FIPS) { + return -EINVAL; + } else if (chan->required_sec_level == BT_SECURITY_NONE) { + chan->required_sec_level = BT_SECURITY_LOW; + } + + return l2cap_le_connect(conn, BT_L2CAP_LE_CHAN(chan), psm); +} + +int bt_l2cap_chan_disconnect(struct bt_l2cap_chan *chan) +{ + struct bt_conn *conn = chan->conn; + struct net_buf *buf; + struct bt_l2cap_disconn_req *req; + struct bt_l2cap_le_chan *ch; + + if (!conn) { + return -ENOTCONN; + } + + if (IS_ENABLED(CONFIG_BLUETOOTH_BREDR) && + conn->type == BT_CONN_TYPE_BR) { + return bt_l2cap_br_chan_disconnect(chan); + } + + ch = BT_L2CAP_LE_CHAN(chan); + + BT_DBG("chan %p scid 0x%04x dcid 0x%04x", chan, ch->rx.cid, + ch->tx.cid); + + ch->chan.ident = get_ident(); + + buf = l2cap_create_le_sig_pdu(BT_L2CAP_DISCONN_REQ, ch->chan.ident, + sizeof(*req)); + + req = net_buf_add(buf, sizeof(*req)); + req->dcid = sys_cpu_to_le16(ch->tx.cid); + req->scid = sys_cpu_to_le16(ch->rx.cid); + + l2cap_chan_send_req(ch, buf, L2CAP_DISC_TIMEOUT); + bt_l2cap_chan_set_state(chan, BT_L2CAP_DISCONNECT); + + return 0; +} + +int bt_l2cap_chan_send(struct bt_l2cap_chan *chan, struct net_buf *buf) +{ + int err; + + if (!buf) { + return -EINVAL; + } + + BT_DBG("chan %p buf %p len %u", chan, buf, buf->len); + + if (!chan->conn || chan->conn->state != BT_CONN_CONNECTED) { + return -ENOTCONN; + } + + if (IS_ENABLED(CONFIG_BLUETOOTH_BREDR) && + chan->conn->type == BT_CONN_TYPE_BR) { + return bt_l2cap_br_chan_send(chan, buf); + } + + err = l2cap_chan_le_send_sdu(BT_L2CAP_LE_CHAN(chan), buf, 0); + if (err < 0) { + if (err == -EAGAIN) { + /* Queue buffer to be sent later */ + net_buf_put(&(BT_L2CAP_LE_CHAN(chan))->tx_queue, buf); + return *((int *)net_buf_user_data(buf)); + } + BT_ERR("failed to send message %d", err); + } + + return err; +} +#endif /* CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL */ diff --git a/kernel/protocols/bluetooth/host/l2cap_internal.h b/kernel/protocols/bluetooth/host/l2cap_internal.h new file mode 100644 index 0000000000..7f2426ee14 --- /dev/null +++ b/kernel/protocols/bluetooth/host/l2cap_internal.h @@ -0,0 +1,294 @@ +/** @file + * @brief Internal APIs for Bluetooth L2CAP handling. + */ + +/* + * Copyright (c) 2015-2016 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +enum l2cap_conn_list_action { + BT_L2CAP_CHAN_LOOKUP, + BT_L2CAP_CHAN_DETACH, +}; + +#define BT_L2CAP_CID_BR_SIG 0x0001 +#define BT_L2CAP_CID_ATT 0x0004 +#define BT_L2CAP_CID_LE_SIG 0x0005 +#define BT_L2CAP_CID_SMP 0x0006 +#define BT_L2CAP_CID_BR_SMP 0x0007 + +#define BT_L2CAP_PSM_RFCOMM 0x0003 + +struct bt_l2cap_hdr { + uint16_t len; + uint16_t cid; +} __packed; + +struct bt_l2cap_sig_hdr { + uint8_t code; + uint8_t ident; + uint16_t len; +} __packed; + +#define BT_L2CAP_REJ_NOT_UNDERSTOOD 0x0000 +#define BT_L2CAP_REJ_MTU_EXCEEDED 0x0001 +#define BT_L2CAP_REJ_INVALID_CID 0x0002 + +#define BT_L2CAP_CMD_REJECT 0x01 +struct bt_l2cap_cmd_reject { + uint16_t reason; + uint8_t data[0]; +} __packed; + +struct bt_l2cap_cmd_reject_cid_data { + uint16_t scid; + uint16_t dcid; +} __packed; + +#define BT_L2CAP_CONN_REQ 0x02 +struct bt_l2cap_conn_req { + uint16_t psm; + uint16_t scid; +} __packed; + +/* command statuses in reposnse */ +#define BT_L2CAP_CS_NO_INFO 0x0000 +#define BT_L2CAP_CS_AUTHEN_PEND 0x0001 + +/* valid results in conn response on BR/EDR */ +#define BT_L2CAP_BR_SUCCESS 0x0000 +#define BT_L2CAP_BR_PENDING 0x0001 +#define BT_L2CAP_BR_ERR_PSM_NOT_SUPP 0x0002 +#define BT_L2CAP_BR_ERR_SEC_BLOCK 0x0003 +#define BT_L2CAP_BR_ERR_NO_RESOURCES 0x0004 +#define BT_L2CAP_BR_ERR_INVALID_SCID 0x0006 +#define BT_L2CAP_BR_ERR_SCID_IN_USE 0x0007 + +#define BT_L2CAP_CONN_RSP 0x03 +struct bt_l2cap_conn_rsp { + uint16_t dcid; + uint16_t scid; + uint16_t result; + uint16_t status; +} __packed; + +#define BT_L2CAP_CONF_SUCCESS 0x0000 +#define BT_L2CAP_CONF_UNACCEPT 0x0001 +#define BT_L2CAP_CONF_REJECT 0x0002 + +#define BT_L2CAP_CONF_REQ 0x04 +struct bt_l2cap_conf_req { + uint16_t dcid; + uint16_t flags; + uint8_t data[0]; +} __packed; + +#define BT_L2CAP_CONF_RSP 0x05 +struct bt_l2cap_conf_rsp { + uint16_t scid; + uint16_t flags; + uint16_t result; + uint8_t data[0]; +} __packed; + +/* Option type used by MTU config request data */ +#define BT_L2CAP_CONF_OPT_MTU 0x01 +/* Options bits selecting most significant bit (hint) in type field */ +#define BT_L2CAP_CONF_HINT 0x80 +#define BT_L2CAP_CONF_MASK 0x7f + +struct bt_l2cap_conf_opt { + uint8_t type; + uint8_t len; + uint8_t data[0]; +} __packed; + +#define BT_L2CAP_DISCONN_REQ 0x06 +struct bt_l2cap_disconn_req { + uint16_t dcid; + uint16_t scid; +} __packed; + +#define BT_L2CAP_DISCONN_RSP 0x07 +struct bt_l2cap_disconn_rsp { + uint16_t dcid; + uint16_t scid; +} __packed; + +#define BT_L2CAP_INFO_FEAT_MASK 0x0002 +#define BT_L2CAP_INFO_FIXED_CHAN 0x0003 + +#define BT_L2CAP_INFO_REQ 0x0a +struct bt_l2cap_info_req { + uint16_t type; +} __packed; + +/* info result */ +#define BT_L2CAP_INFO_SUCCESS 0x0000 +#define BT_L2CAP_INFO_NOTSUPP 0x0001 + +#define BT_L2CAP_INFO_RSP 0x0b +struct bt_l2cap_info_rsp { + uint16_t type; + uint16_t result; + uint8_t data[0]; +} __packed; + +#define BT_L2CAP_CONN_PARAM_REQ 0x12 +struct bt_l2cap_conn_param_req { + uint16_t min_interval; + uint16_t max_interval; + uint16_t latency; + uint16_t timeout; +} __packed; + +#define BT_L2CAP_CONN_PARAM_ACCEPTED 0x0000 +#define BT_L2CAP_CONN_PARAM_REJECTED 0x0001 + +#define BT_L2CAP_CONN_PARAM_RSP 0x13 +struct bt_l2cap_conn_param_rsp { + uint16_t result; +} __packed; + +#define BT_L2CAP_LE_CONN_REQ 0x14 +struct bt_l2cap_le_conn_req { + uint16_t psm; + uint16_t scid; + uint16_t mtu; + uint16_t mps; + uint16_t credits; +} __packed; + +#define BT_L2CAP_SUCCESS 0x0000 +#define BT_L2CAP_PENDING 0x0001 +#define BT_L2CAP_ERR_PSM_NOT_SUPP 0x0002 +#define BT_L2CAP_ERR_SEC_BLOCK 0x0003 +#define BT_L2CAP_ERR_NO_RESOURCES 0x0004 +#define BT_L2CAP_ERR_AUTHENTICATION 0x0005 +#define BT_L2CAP_ERR_AUTHORIZATION 0x0006 +#define BT_L2CAP_ERR_KEY_SIZE 0x0007 +#define BT_L2CAP_ERR_ENCRYPTION 0x0008 +#define BT_L2CAP_ERR_INVALID_SCID 0x0009 +#define BT_L2CAP_ERR_SCID_IN_USE 0x000A + +#define BT_L2CAP_LE_CONN_RSP 0x15 +struct bt_l2cap_le_conn_rsp { + uint16_t dcid; + uint16_t mtu; + uint16_t mps; + uint16_t credits; + uint16_t result; +}; + +#define BT_L2CAP_LE_CREDITS 0x16 +struct bt_l2cap_le_credits { + uint16_t cid; + uint16_t credits; +} __packed; + +#define BT_L2CAP_SDU_HDR_LEN 2 + +#define BT_L2CAP_RX_MTU (CONFIG_BLUETOOTH_RX_BUF_LEN - \ + BT_HCI_ACL_HDR_SIZE - BT_L2CAP_HDR_SIZE) + +struct bt_l2cap_fixed_chan { + uint16_t cid; + int (*accept)(struct bt_conn *conn, struct bt_l2cap_chan **chan); + + struct bt_l2cap_fixed_chan *_next; +}; + +/* Register a fixed L2CAP channel for L2CAP */ +void bt_l2cap_le_fixed_chan_register(struct bt_l2cap_fixed_chan *chan); + +/* Notify L2CAP channels of a new connection */ +void bt_l2cap_connected(struct bt_conn *conn); + +/* Notify L2CAP channels of a disconnect event */ +void bt_l2cap_disconnected(struct bt_conn *conn); + +/* Add channel to the connection */ +void bt_l2cap_chan_add(struct bt_conn *conn, struct bt_l2cap_chan *chan, + bt_l2cap_chan_destroy_t destroy); + +/* Delete channel */ +void bt_l2cap_chan_del(struct bt_l2cap_chan *chan); + +const char *bt_l2cap_chan_state_str(bt_l2cap_chan_state_t state); + +#if defined(CONFIG_BLUETOOTH_DEBUG_L2CAP) +void bt_l2cap_chan_set_state_debug(struct bt_l2cap_chan *chan, + bt_l2cap_chan_state_t state, + const char *func, int line); +#define bt_l2cap_chan_set_state(_chan, _state) \ + bt_l2cap_chan_set_state_debug(_chan, _state, __func__, __LINE__) +#else +void bt_l2cap_chan_set_state(struct bt_l2cap_chan *chan, + bt_l2cap_chan_state_t state); +#endif /* CONFIG_BLUETOOTH_DEBUG_L2CAP */ + +/* + * Notify L2CAP channels of a change in encryption state passing additionally + * HCI status of performed security procedure. + */ +void bt_l2cap_encrypt_change(struct bt_conn *conn, uint8_t hci_status); + +/* Prepare an L2CAP PDU to be sent over a connection */ +struct net_buf *bt_l2cap_create_pdu(struct net_buf_pool *pool, size_t reserve); + +/* Send L2CAP PDU over a connection */ +void bt_l2cap_send(struct bt_conn *conn, uint16_t cid, struct net_buf *buf); + +/* Receive a new L2CAP PDU from a connection */ +void bt_l2cap_recv(struct bt_conn *conn, struct net_buf *buf); + +/* Perform connection parameter update request */ +int bt_l2cap_update_conn_param(struct bt_conn *conn, + const struct bt_le_conn_param *param); + +/* Initialize L2CAP and supported channels */ +void bt_l2cap_init(void); + +/* Lookup channel by Transmission CID */ +struct bt_l2cap_chan *bt_l2cap_le_lookup_tx_cid(struct bt_conn *conn, + uint16_t cid); + +/* Lookup channel by Receiver CID */ +struct bt_l2cap_chan *bt_l2cap_le_lookup_rx_cid(struct bt_conn *conn, + uint16_t cid); + +/* Initialize BR/EDR L2CAP signal layer */ +void bt_l2cap_br_init(void); + +/* Register fixed channel */ +void bt_l2cap_br_fixed_chan_register(struct bt_l2cap_fixed_chan *chan); + +/* Notify BR/EDR L2CAP channels about established new ACL connection */ +void bt_l2cap_br_connected(struct bt_conn *conn); + +/* Lookup BR/EDR L2CAP channel by Receiver CID */ +struct bt_l2cap_chan *bt_l2cap_br_lookup_rx_cid(struct bt_conn *conn, + uint16_t cid); + +/* Disconnects dynamic channel */ +int bt_l2cap_br_chan_disconnect(struct bt_l2cap_chan *chan); + +/* Make connection to peer psm server */ +int bt_l2cap_br_chan_connect(struct bt_conn *conn, struct bt_l2cap_chan *chan, + uint16_t psm); + +/* Send packet data to connected peer */ +int bt_l2cap_br_chan_send(struct bt_l2cap_chan *chan, struct net_buf *buf); + +/* + * Handle security level changed on link passing HCI status of performed + * security procedure. + */ +void l2cap_br_encrypt_change(struct bt_conn *conn, uint8_t hci_status); + +/* Handle received data */ +void bt_l2cap_br_recv(struct bt_conn *conn, struct net_buf *buf); diff --git a/kernel/protocols/bluetooth/host/log.c b/kernel/protocols/bluetooth/host/log.c new file mode 100644 index 0000000000..db3a50e552 --- /dev/null +++ b/kernel/protocols/bluetooth/host/log.c @@ -0,0 +1,44 @@ +/* log.c - logging helpers */ + +/* + * Copyright (c) 2016 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Helper for printk parameters to convert from binary to hex. + * We declare multiple buffers so the helper can be used multiple times + * in a single printk call. + */ + +#include +#include +#include +#include + +const char *bt_hex(const void *buf, size_t len) +{ + static const char hex[] = "0123456789abcdef"; + static char hexbufs[4][129]; + static uint8_t curbuf; + const uint8_t *b = buf; + unsigned int mask; + char *str; + int i; + + mask = irq_lock(); + str = hexbufs[curbuf++]; + curbuf %= ARRAY_SIZE(hexbufs); + irq_unlock(mask); + + len = min(len, (sizeof(hexbufs[0]) - 1) / 2); + + for (i = 0; i < len; i++) { + str[i * 2] = hex[b[i] >> 4]; + str[i * 2 + 1] = hex[b[i] & 0xf]; + } + + str[i * 2] = '\0'; + + return str; +} diff --git a/kernel/protocols/bluetooth/host/monitor.c b/kernel/protocols/bluetooth/host/monitor.c new file mode 100644 index 0000000000..e1e040b703 --- /dev/null +++ b/kernel/protocols/bluetooth/host/monitor.c @@ -0,0 +1,183 @@ +/** @file + * @brief Custom logging over UART + */ + +/* + * Copyright (c) 2016 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "monitor.h" + +/* This is the same default priority as for other console handlers, + * except that we're not exporting it as a Kconfig variable until a + * clear need arises. + */ +#define MONITOR_INIT_PRIORITY 60 + +static struct device *monitor_dev; + +extern int _prf(int (*func)(), void *dest, + const char *format, va_list vargs); + +static void monitor_send(const void *data, size_t len) +{ + const uint8_t *buf = data; + + while (len--) { + uart_poll_out(monitor_dev, *buf++); + } +} + +static inline void encode_hdr(struct bt_monitor_hdr *hdr, uint16_t opcode, + uint16_t len) +{ + uint32_t ts32; + + hdr->hdr_len = sizeof(hdr->type) + sizeof(hdr->ts32); + hdr->data_len = sys_cpu_to_le16(4 + hdr->hdr_len + len); + hdr->opcode = sys_cpu_to_le16(opcode); + hdr->flags = 0; + + /* Extended header */ + hdr->type = BT_MONITOR_TS32; + ts32 = k_uptime_get() * 10; + hdr->ts32 = sys_cpu_to_le32(ts32); +} + +static int log_out(int c, void *unused) +{ + uart_poll_out(monitor_dev, c); + return 0; +} + +void bt_log(int prio, const char *fmt, ...) +{ + struct bt_monitor_user_logging log; + struct bt_monitor_hdr hdr; + const char id[] = "bt"; + va_list ap; + int len, key; + + va_start(ap, fmt); + len = vsnprintk(NULL, 0, fmt, ap); + va_end(ap); + + if (len < 0) { + return; + } + + log.priority = prio; + log.ident_len = sizeof(id); + + encode_hdr(&hdr, BT_MONITOR_USER_LOGGING, + sizeof(log) + sizeof(id) + len + 1); + + key = irq_lock(); + + monitor_send(&hdr, sizeof(hdr)); + monitor_send(&log, sizeof(log)); + monitor_send(id, sizeof(id)); + + va_start(ap, fmt); + _vprintk(log_out, NULL, fmt, ap); + va_end(ap); + + /* Terminate the string with null */ + uart_poll_out(monitor_dev, '\0'); + + irq_unlock(key); +} + +void bt_monitor_send(uint16_t opcode, const void *data, size_t len) +{ + struct bt_monitor_hdr hdr; + int key; + + encode_hdr(&hdr, opcode, len); + + key = irq_lock(); + + monitor_send(&hdr, sizeof(hdr)); + monitor_send(data, len); + + irq_unlock(key); +} + +void bt_monitor_new_index(uint8_t type, uint8_t bus, bt_addr_t *addr, + const char *name) +{ + struct bt_monitor_new_index pkt; + + pkt.type = type; + pkt.bus = bus; + memcpy(pkt.bdaddr, addr, 6); + strncpy(pkt.name, name, sizeof(pkt.name) - 1); + pkt.name[sizeof(pkt.name) - 1] = '\0'; + + bt_monitor_send(BT_MONITOR_NEW_INDEX, &pkt, sizeof(pkt)); +} + +#if !defined(CONFIG_UART_CONSOLE) +static int monitor_console_out(int c) +{ + static char buf[128]; + static size_t len; + int key; + + key = irq_lock(); + + if (c != '\n' && len < sizeof(buf) - 1) { + buf[len++] = c; + irq_unlock(key); + return c; + } + + buf[len++] = '\0'; + + bt_monitor_send(BT_MONITOR_SYSTEM_NOTE, buf, len); + len = 0; + + irq_unlock(key); + + return c; +} + +extern void __printk_hook_install(int (*fn)(int)); +extern void __stdout_hook_install(int (*fn)(int)); +#endif /* !CONFIG_UART_CONSOLE */ + +static int bt_monitor_init(struct device *d) +{ + ARG_UNUSED(d); + + monitor_dev = device_get_binding(CONFIG_BLUETOOTH_MONITOR_ON_DEV_NAME); + +#if defined(CONFIG_UART_INTERRUPT_DRIVEN) + uart_irq_rx_disable(monitor_dev); + uart_irq_tx_disable(monitor_dev); +#endif + +#if !defined(CONFIG_UART_CONSOLE) + __printk_hook_install(monitor_console_out); + __stdout_hook_install(monitor_console_out); +#endif + + return 0; +} + +SYS_INIT(bt_monitor_init, PRE_KERNEL_1, MONITOR_INIT_PRIORITY); diff --git a/kernel/protocols/bluetooth/host/monitor.h b/kernel/protocols/bluetooth/host/monitor.h new file mode 100644 index 0000000000..9faaee2d07 --- /dev/null +++ b/kernel/protocols/bluetooth/host/monitor.h @@ -0,0 +1,91 @@ +/** @file + * @brief Custom monitor protocol logging over UART + */ + +/* + * Copyright (c) 2016 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#if defined(CONFIG_BLUETOOTH_DEBUG_MONITOR) + +#define BT_MONITOR_NEW_INDEX 0 +#define BT_MONITOR_DEL_INDEX 1 +#define BT_MONITOR_COMMAND_PKT 2 +#define BT_MONITOR_EVENT_PKT 3 +#define BT_MONITOR_ACL_TX_PKT 4 +#define BT_MONITOR_ACL_RX_PKT 5 +#define BT_MONITOR_SCO_TX_PKT 6 +#define BT_MONITOR_SCO_RX_PKT 7 +#define BT_MONITOR_OPEN_INDEX 8 +#define BT_MONITOR_CLOSE_INDEX 9 +#define BT_MONITOR_INDEX_INFO 10 +#define BT_MONITOR_VENDOR_DIAG 11 +#define BT_MONITOR_SYSTEM_NOTE 12 +#define BT_MONITOR_USER_LOGGING 13 +#define BT_MONITOR_NOP 255 + +#define BT_MONITOR_TYPE_PRIMARY 0 +#define BT_MONITOR_TYPE_AMP 1 + +/* Extended header types */ +#define BT_MONITOR_COMMAND_DROPS 1 +#define BT_MONITOR_EVENT_DROPS 2 +#define BT_MONITOR_ACL_RX_DROPS 3 +#define BT_MONITOR_ACL_TX_DROPS 4 +#define BT_MONITOR_SCO_RX_DROPS 5 +#define BT_MONITOR_SCO_TX_DROPS 6 +#define BT_MONITOR_OTHER_DROPS 7 +#define BT_MONITOR_TS32 8 + +struct bt_monitor_hdr { + uint16_t data_len; + uint16_t opcode; + uint8_t flags; + uint8_t hdr_len; + + /* Extended header */ + uint8_t type; + uint32_t ts32; +} __packed; + +struct bt_monitor_new_index { + uint8_t type; + uint8_t bus; + uint8_t bdaddr[6]; + char name[8]; +} __packed; + +struct bt_monitor_user_logging { + uint8_t priority; + uint8_t ident_len; +} __packed; + +static inline uint8_t bt_monitor_opcode(struct net_buf *buf) +{ + switch (bt_buf_get_type(buf)) { + case BT_BUF_CMD: + return BT_MONITOR_COMMAND_PKT; + case BT_BUF_EVT: + return BT_MONITOR_EVENT_PKT; + case BT_BUF_ACL_OUT: + return BT_MONITOR_ACL_TX_PKT; + case BT_BUF_ACL_IN: + return BT_MONITOR_ACL_RX_PKT; + default: + return BT_MONITOR_NOP; + } +} + +void bt_monitor_send(uint16_t opcode, const void *data, size_t len); + +void bt_monitor_new_index(uint8_t type, uint8_t bus, bt_addr_t *addr, + const char *name); + +#else /* !CONFIG_BLUETOOTH_DEBUG_MONITOR */ + +#define bt_monitor_send(opcode, data, len) +#define bt_monitor_new_index(type, bus, addr, name) + +#endif diff --git a/kernel/protocols/bluetooth/host/rfcomm.c b/kernel/protocols/bluetooth/host/rfcomm.c new file mode 100644 index 0000000000..7e4f73683a --- /dev/null +++ b/kernel/protocols/bluetooth/host/rfcomm.c @@ -0,0 +1,1720 @@ +/* rfcomm.c - RFCOMM handling */ + +/* + * Copyright (c) 2016 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_RFCOMM) +#include +#include +#include +#include +#include +#include +#include + +#include "hci_core.h" +#include "conn_internal.h" +#include "l2cap_internal.h" +#include "rfcomm_internal.h" + +#define RFCOMM_CHANNEL_START 0x01 +#define RFCOMM_CHANNEL_END 0x1e + +#define RFCOMM_MIN_MTU BT_RFCOMM_SIG_MIN_MTU +#define RFCOMM_DEFAULT_MTU 127 + +#define RFCOMM_MAX_CREDITS (CONFIG_BLUETOOTH_RX_BUF_COUNT - 1) +#define RFCOMM_CREDITS_THRESHOLD (RFCOMM_MAX_CREDITS / 2) +#define RFCOMM_DEFAULT_CREDIT RFCOMM_MAX_CREDITS + +#define RFCOMM_CONN_TIMEOUT K_SECONDS(60) +#define RFCOMM_DISC_TIMEOUT K_SECONDS(20) +#define RFCOMM_IDLE_TIMEOUT K_SECONDS(2) + +#define DLC_RTX(_w) CONTAINER_OF(_w, struct bt_rfcomm_dlc, rtx_work) + +#define SESSION_RTX(_w) CONTAINER_OF(_w, struct bt_rfcomm_session, rtx_work) + +static struct bt_rfcomm_server *servers; + +/* Pool for dummy buffers to wake up the tx threads */ +NET_BUF_POOL_DEFINE(dummy_pool, CONFIG_BLUETOOTH_MAX_CONN, 0, 0, NULL); + +#define RFCOMM_SESSION(_ch) CONTAINER_OF(_ch, \ + struct bt_rfcomm_session, br_chan.chan) + +static struct bt_rfcomm_session bt_rfcomm_pool[CONFIG_BLUETOOTH_MAX_CONN]; + +/* reversed, 8-bit, poly=0x07 */ +static const uint8_t rfcomm_crc_table[256] = { + 0x00, 0x91, 0xe3, 0x72, 0x07, 0x96, 0xe4, 0x75, + 0x0e, 0x9f, 0xed, 0x7c, 0x09, 0x98, 0xea, 0x7b, + 0x1c, 0x8d, 0xff, 0x6e, 0x1b, 0x8a, 0xf8, 0x69, + 0x12, 0x83, 0xf1, 0x60, 0x15, 0x84, 0xf6, 0x67, + + 0x38, 0xa9, 0xdb, 0x4a, 0x3f, 0xae, 0xdc, 0x4d, + 0x36, 0xa7, 0xd5, 0x44, 0x31, 0xa0, 0xd2, 0x43, + 0x24, 0xb5, 0xc7, 0x56, 0x23, 0xb2, 0xc0, 0x51, + 0x2a, 0xbb, 0xc9, 0x58, 0x2d, 0xbc, 0xce, 0x5f, + + 0x70, 0xe1, 0x93, 0x02, 0x77, 0xe6, 0x94, 0x05, + 0x7e, 0xef, 0x9d, 0x0c, 0x79, 0xe8, 0x9a, 0x0b, + 0x6c, 0xfd, 0x8f, 0x1e, 0x6b, 0xfa, 0x88, 0x19, + 0x62, 0xf3, 0x81, 0x10, 0x65, 0xf4, 0x86, 0x17, + + 0x48, 0xd9, 0xab, 0x3a, 0x4f, 0xde, 0xac, 0x3d, + 0x46, 0xd7, 0xa5, 0x34, 0x41, 0xd0, 0xa2, 0x33, + 0x54, 0xc5, 0xb7, 0x26, 0x53, 0xc2, 0xb0, 0x21, + 0x5a, 0xcb, 0xb9, 0x28, 0x5d, 0xcc, 0xbe, 0x2f, + + 0xe0, 0x71, 0x03, 0x92, 0xe7, 0x76, 0x04, 0x95, + 0xee, 0x7f, 0x0d, 0x9c, 0xe9, 0x78, 0x0a, 0x9b, + 0xfc, 0x6d, 0x1f, 0x8e, 0xfb, 0x6a, 0x18, 0x89, + 0xf2, 0x63, 0x11, 0x80, 0xf5, 0x64, 0x16, 0x87, + + 0xd8, 0x49, 0x3b, 0xaa, 0xdf, 0x4e, 0x3c, 0xad, + 0xd6, 0x47, 0x35, 0xa4, 0xd1, 0x40, 0x32, 0xa3, + 0xc4, 0x55, 0x27, 0xb6, 0xc3, 0x52, 0x20, 0xb1, + 0xca, 0x5b, 0x29, 0xb8, 0xcd, 0x5c, 0x2e, 0xbf, + + 0x90, 0x01, 0x73, 0xe2, 0x97, 0x06, 0x74, 0xe5, + 0x9e, 0x0f, 0x7d, 0xec, 0x99, 0x08, 0x7a, 0xeb, + 0x8c, 0x1d, 0x6f, 0xfe, 0x8b, 0x1a, 0x68, 0xf9, + 0x82, 0x13, 0x61, 0xf0, 0x85, 0x14, 0x66, 0xf7, + + 0xa8, 0x39, 0x4b, 0xda, 0xaf, 0x3e, 0x4c, 0xdd, + 0xa6, 0x37, 0x45, 0xd4, 0xa1, 0x30, 0x42, 0xd3, + 0xb4, 0x25, 0x57, 0xc6, 0xb3, 0x22, 0x50, 0xc1, + 0xba, 0x2b, 0x59, 0xc8, 0xbd, 0x2c, 0x5e, 0xcf +}; + +static uint8_t rfcomm_calc_fcs(uint16_t len, const uint8_t *data) +{ + uint8_t fcs = 0xff; + + while (len--) { + fcs = rfcomm_crc_table[fcs ^ *data++]; + } + + /* Ones compliment */ + return (0xff - fcs); +} + +static bool rfcomm_check_fcs(uint16_t len, const uint8_t *data, + uint8_t recvd_fcs) +{ + uint8_t fcs = 0xff; + + while (len--) { + fcs = rfcomm_crc_table[fcs ^ *data++]; + } + + /* Ones compliment */ + fcs = rfcomm_crc_table[fcs ^ recvd_fcs]; + + /*0xCF is the reversed order of 11110011.*/ + return (fcs == 0xcf); +} + +static struct bt_rfcomm_dlc *rfcomm_dlcs_lookup_dlci(struct bt_rfcomm_dlc *dlcs, + uint8_t dlci) +{ + for (; dlcs; dlcs = dlcs->_next) { + if (dlcs->dlci == dlci) { + return dlcs; + } + } + + return NULL; +} + +static struct bt_rfcomm_dlc *rfcomm_dlcs_remove_dlci(struct bt_rfcomm_dlc *dlcs, + uint8_t dlci) +{ + struct bt_rfcomm_dlc *tmp; + + if (!dlcs) { + return NULL; + } + + /* If first node is the one to be removed */ + if (dlcs->dlci == dlci) { + dlcs->session->dlcs = dlcs->_next; + return dlcs; + } + + for (tmp = dlcs, dlcs = dlcs->_next; dlcs; dlcs = dlcs->_next) { + if (dlcs->dlci == dlci) { + tmp->_next = dlcs->_next; + return dlcs; + } + tmp = dlcs; + } + + return NULL; +} + +static struct bt_rfcomm_server *rfcomm_server_lookup_channel(uint8_t channel) +{ + struct bt_rfcomm_server *server; + + for (server = servers; server; server = server->_next) { + if (server->channel == channel) { + return server; + } + } + + return NULL; +} + +static struct bt_rfcomm_session * +rfcomm_sessions_lookup_bt_conn(struct bt_conn *conn) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(bt_rfcomm_pool); i++) { + struct bt_rfcomm_session *session = &bt_rfcomm_pool[i]; + + if (session->br_chan.chan.conn == conn) { + return session; + } + } + + return NULL; +} + +int bt_rfcomm_server_register(struct bt_rfcomm_server *server) +{ + if (server->channel < RFCOMM_CHANNEL_START || + server->channel > RFCOMM_CHANNEL_END || !server->accept) { + return -EINVAL; + } + + /* Check if given channel is already in use */ + if (rfcomm_server_lookup_channel(server->channel)) { + BT_DBG("Channel already registered"); + return -EADDRINUSE; + } + + BT_DBG("Channel 0x%02x", server->channel); + + server->_next = servers; + servers = server; + + return 0; +} + +static void rfcomm_dlc_tx_give_credits(struct bt_rfcomm_dlc *dlc, + uint8_t credits) +{ + BT_DBG("dlc %p credits %u", dlc, credits); + + while (credits--) { + k_sem_give(&dlc->tx_credits); + } + + BT_DBG("dlc %p updated credits %u", dlc, + k_sem_count_get(&dlc->tx_credits)); +} + +static void rfcomm_dlc_destroy(struct bt_rfcomm_dlc *dlc) +{ + BT_DBG("dlc %p", dlc); + + k_delayed_work_cancel(&dlc->rtx_work); + dlc->state = BT_RFCOMM_STATE_IDLE; + dlc->session = NULL; + + stack_analyze("dlc stack", dlc->stack, sizeof(dlc->stack)); + + if (dlc->ops && dlc->ops->disconnected) { + dlc->ops->disconnected(dlc); + } +} + +static void rfcomm_dlc_disconnect(struct bt_rfcomm_dlc *dlc) +{ + uint8_t old_state = dlc->state; + + BT_DBG("dlc %p", dlc); + + if (dlc->state == BT_RFCOMM_STATE_DISCONNECTED) { + return; + } + + dlc->state = BT_RFCOMM_STATE_DISCONNECTED; + + switch (old_state) { + case BT_RFCOMM_STATE_CONNECTED: + /* Queue a dummy buffer to wake up and stop the + * tx thread for states where it was running. + */ + net_buf_put(&dlc->tx_queue, + net_buf_alloc(&dummy_pool, K_NO_WAIT)); + + /* There could be a writer waiting for credits so return a + * dummy credit to wake it up. + */ + rfcomm_dlc_tx_give_credits(dlc, 1); + k_sem_give(&dlc->session->fc); + break; + default: + rfcomm_dlc_destroy(dlc); + break; + } +} + +static void rfcomm_session_disconnected(struct bt_rfcomm_session *session) +{ + struct bt_rfcomm_dlc *dlc; + + BT_DBG("Session %p", session); + + if (session->state == BT_RFCOMM_STATE_DISCONNECTED) { + return; + } + + for (dlc = session->dlcs; dlc;) { + struct bt_rfcomm_dlc *next; + + /* prefetch since disconnected callback may cleanup */ + next = dlc->_next; + dlc->_next = NULL; + + rfcomm_dlc_disconnect(dlc); + + dlc = next; + } + + session->state = BT_RFCOMM_STATE_DISCONNECTED; + session->dlcs = NULL; +} + +struct net_buf *bt_rfcomm_create_pdu(struct net_buf_pool *pool) +{ + /* Length in RFCOMM header can be 2 bytes depending on length of user + * data + */ + return bt_conn_create_pdu(pool, + sizeof(struct bt_l2cap_hdr) + + sizeof(struct bt_rfcomm_hdr) + 1); +} + +static int rfcomm_send_sabm(struct bt_rfcomm_session *session, uint8_t dlci) +{ + struct bt_rfcomm_hdr *hdr; + struct net_buf *buf; + uint8_t cr, fcs; + + buf = bt_l2cap_create_pdu(NULL, 0); + + hdr = net_buf_add(buf, sizeof(*hdr)); + cr = BT_RFCOMM_CMD_CR(session->role); + hdr->address = BT_RFCOMM_SET_ADDR(dlci, cr); + hdr->control = BT_RFCOMM_SET_CTRL(BT_RFCOMM_SABM, BT_RFCOMM_PF_NON_UIH); + hdr->length = BT_RFCOMM_SET_LEN_8(0); + + fcs = rfcomm_calc_fcs(BT_RFCOMM_FCS_LEN_NON_UIH, buf->data); + net_buf_add_u8(buf, fcs); + + return bt_l2cap_chan_send(&session->br_chan.chan, buf); +} + +static int rfcomm_send_disc(struct bt_rfcomm_session *session, uint8_t dlci) +{ + struct bt_rfcomm_hdr *hdr; + struct net_buf *buf; + uint8_t fcs, cr; + + BT_DBG("dlci %d", dlci); + + buf = bt_l2cap_create_pdu(NULL, 0); + + hdr = net_buf_add(buf, sizeof(*hdr)); + cr = BT_RFCOMM_RESP_CR(session->role); + hdr->address = BT_RFCOMM_SET_ADDR(dlci, cr); + hdr->control = BT_RFCOMM_SET_CTRL(BT_RFCOMM_DISC, BT_RFCOMM_PF_NON_UIH); + hdr->length = BT_RFCOMM_SET_LEN_8(0); + fcs = rfcomm_calc_fcs(BT_RFCOMM_FCS_LEN_NON_UIH, buf->data); + net_buf_add_u8(buf, fcs); + + return bt_l2cap_chan_send(&session->br_chan.chan, buf); +} + +static void rfcomm_session_disconnect(struct bt_rfcomm_session *session) +{ + if (session->dlcs) { + return; + } + + session->state = BT_RFCOMM_STATE_DISCONNECTING; + rfcomm_send_disc(session, 0); + k_delayed_work_submit(&session->rtx_work, RFCOMM_DISC_TIMEOUT); +} + +static struct net_buf *rfcomm_make_uih_msg(struct bt_rfcomm_session *session, + uint8_t cr, uint8_t type, + uint8_t len) +{ + struct bt_rfcomm_hdr *hdr; + struct bt_rfcomm_msg_hdr *msg_hdr; + struct net_buf *buf; + uint8_t hdr_cr; + + buf = bt_l2cap_create_pdu(NULL, 0); + + hdr = net_buf_add(buf, sizeof(*hdr)); + hdr_cr = BT_RFCOMM_UIH_CR(session->role); + hdr->address = BT_RFCOMM_SET_ADDR(0, hdr_cr); + hdr->control = BT_RFCOMM_SET_CTRL(BT_RFCOMM_UIH, BT_RFCOMM_PF_UIH); + hdr->length = BT_RFCOMM_SET_LEN_8(sizeof(*msg_hdr) + len); + + msg_hdr = net_buf_add(buf, sizeof(*msg_hdr)); + msg_hdr->type = BT_RFCOMM_SET_MSG_TYPE(type, cr); + msg_hdr->len = BT_RFCOMM_SET_LEN_8(len); + + return buf; +} + +static void rfcomm_connected(struct bt_l2cap_chan *chan) +{ + struct bt_rfcomm_session *session = RFCOMM_SESSION(chan); + + BT_DBG("Session %p", session); + + /* Need to include UIH header and FCS*/ + session->mtu = min(session->br_chan.rx.mtu, + session->br_chan.tx.mtu) - + BT_RFCOMM_HDR_SIZE + BT_RFCOMM_FCS_SIZE; + + if (session->state == BT_RFCOMM_STATE_CONNECTING) { + rfcomm_send_sabm(session, 0); + } +} + +static void rfcomm_disconnected(struct bt_l2cap_chan *chan) +{ + struct bt_rfcomm_session *session = RFCOMM_SESSION(chan); + + BT_DBG("Session %p", session); + + k_delayed_work_cancel(&session->rtx_work); + rfcomm_session_disconnected(session); + session->state = BT_RFCOMM_STATE_IDLE; +} + +static void rfcomm_dlc_rtx_timeout(struct k_work *work) +{ + struct bt_rfcomm_dlc *dlc = DLC_RTX(work); + struct bt_rfcomm_session *session = dlc->session; + + BT_WARN("dlc %p state %d timeout", dlc, dlc->state); + + rfcomm_dlcs_remove_dlci(session->dlcs, dlc->dlci); + rfcomm_dlc_disconnect(dlc); + rfcomm_session_disconnect(session); +} + +static void rfcomm_dlc_init(struct bt_rfcomm_dlc *dlc, + struct bt_rfcomm_session *session, + uint8_t dlci, + bt_rfcomm_role_t role) +{ + BT_DBG("dlc %p", dlc); + + dlc->dlci = dlci; + dlc->session = session; + dlc->rx_credit = RFCOMM_DEFAULT_CREDIT; + dlc->state = BT_RFCOMM_STATE_INIT; + dlc->role = role; + k_delayed_work_init(&dlc->rtx_work, rfcomm_dlc_rtx_timeout); + + /* Start a conn timer which includes auth as well */ + k_delayed_work_submit(&dlc->rtx_work, RFCOMM_CONN_TIMEOUT); + + dlc->_next = session->dlcs; + session->dlcs = dlc; +} + +static struct bt_rfcomm_dlc *rfcomm_dlc_accept(struct bt_rfcomm_session *session, + uint8_t dlci) +{ + struct bt_rfcomm_server *server; + struct bt_rfcomm_dlc *dlc; + uint8_t channel; + + channel = BT_RFCOMM_GET_CHANNEL(dlci); + server = rfcomm_server_lookup_channel(channel); + if (!server) { + BT_ERR("Server Channel not registered"); + return NULL; + } + + if (server->accept(session->br_chan.chan.conn, &dlc) < 0) { + BT_DBG("Incoming connection rejected"); + return NULL; + } + + if (!BT_RFCOMM_CHECK_MTU(dlc->mtu)) { + rfcomm_dlc_destroy(dlc); + return NULL; + } + + rfcomm_dlc_init(dlc, session, dlci, BT_RFCOMM_ROLE_ACCEPTOR); + dlc->mtu = min(dlc->mtu, session->mtu); + + return dlc; +} + +static int rfcomm_send_dm(struct bt_rfcomm_session *session, uint8_t dlci) +{ + struct bt_rfcomm_hdr *hdr; + struct net_buf *buf; + uint8_t fcs, cr; + + BT_DBG("dlci %d", dlci); + + buf = bt_l2cap_create_pdu(NULL, 0); + + hdr = net_buf_add(buf, sizeof(*hdr)); + cr = BT_RFCOMM_RESP_CR(session->role); + hdr->address = BT_RFCOMM_SET_ADDR(dlci, cr); + /* For DM PF bit is not relevant, we set it 1 */ + hdr->control = BT_RFCOMM_SET_CTRL(BT_RFCOMM_DM, BT_RFCOMM_PF_NON_UIH); + hdr->length = BT_RFCOMM_SET_LEN_8(0); + fcs = rfcomm_calc_fcs(BT_RFCOMM_FCS_LEN_NON_UIH, buf->data); + net_buf_add_u8(buf, fcs); + + return bt_l2cap_chan_send(&session->br_chan.chan, buf); +} + +static void rfcomm_check_fc(struct bt_rfcomm_dlc *dlc) +{ + BT_DBG("%p", dlc); + + BT_DBG("Wait for credits or MSC FC %p", dlc); + /* Wait for credits or MSC FC */ + k_sem_take(&dlc->tx_credits, K_FOREVER); + + if (dlc->session->cfc == BT_RFCOMM_CFC_SUPPORTED) { + return; + } + + k_sem_take(&dlc->session->fc, K_FOREVER); + + /* Give the sems immediately so that sem will be available for all + * the bufs in the queue. It will be blocked only once all the bufs + * are sent (which will preempt this thread) and FCOFF / FC bit + * with 1, is received. + */ + k_sem_give(&dlc->session->fc); + k_sem_give(&dlc->tx_credits); +} + +static void rfcomm_dlc_tx_thread(void *p1, void *p2, void *p3) +{ + struct bt_rfcomm_dlc *dlc = p1; + int32_t timeout = K_FOREVER; + struct net_buf *buf; + + BT_DBG("Started for dlc %p", dlc); + + while (dlc->state == BT_RFCOMM_STATE_CONNECTED || + dlc->state == BT_RFCOMM_STATE_USER_DISCONNECT) { + /* Get next packet for dlc */ + BT_DBG("Wait for buf %p", dlc); + buf = net_buf_get(&dlc->tx_queue, timeout); + /* If its dummy buffer or non user disconnect then break */ + if ((dlc->state != BT_RFCOMM_STATE_CONNECTED && + dlc->state != BT_RFCOMM_STATE_USER_DISCONNECT) || + !buf || !buf->len) { + if (buf) { + net_buf_unref(buf); + } + break; + } + + rfcomm_check_fc(dlc); + if (dlc->state != BT_RFCOMM_STATE_CONNECTED && + dlc->state != BT_RFCOMM_STATE_USER_DISCONNECT) { + net_buf_unref(buf); + break; + } + + if (bt_l2cap_chan_send(&dlc->session->br_chan.chan, buf) < 0) { + /* This fails only if channel is disconnected */ + dlc->state = BT_RFCOMM_STATE_DISCONNECTED; + net_buf_unref(buf); + break; + } + + if (dlc->state == BT_RFCOMM_STATE_USER_DISCONNECT) { + timeout = K_NO_WAIT; + } + } + + BT_DBG("dlc %p disconnected - cleaning up", dlc); + + /* Give back any allocated buffers */ + while ((buf = net_buf_get(&dlc->tx_queue, K_NO_WAIT))) { + net_buf_unref(buf); + } + + if (dlc->state == BT_RFCOMM_STATE_USER_DISCONNECT) { + dlc->state = BT_RFCOMM_STATE_DISCONNECTING; + } + + if (dlc->state == BT_RFCOMM_STATE_DISCONNECTING) { + rfcomm_send_disc(dlc->session, dlc->dlci); + k_delayed_work_submit(&dlc->rtx_work, RFCOMM_DISC_TIMEOUT); + } else { + rfcomm_dlc_destroy(dlc); + } + + BT_DBG("dlc %p exiting", dlc); +} + +static int rfcomm_send_ua(struct bt_rfcomm_session *session, uint8_t dlci) +{ + struct bt_rfcomm_hdr *hdr; + struct net_buf *buf; + uint8_t cr, fcs; + + buf = bt_l2cap_create_pdu(NULL, 0); + + hdr = net_buf_add(buf, sizeof(*hdr)); + cr = BT_RFCOMM_RESP_CR(session->role); + hdr->address = BT_RFCOMM_SET_ADDR(dlci, cr); + hdr->control = BT_RFCOMM_SET_CTRL(BT_RFCOMM_UA, BT_RFCOMM_PF_NON_UIH); + hdr->length = BT_RFCOMM_SET_LEN_8(0); + + fcs = rfcomm_calc_fcs(BT_RFCOMM_FCS_LEN_NON_UIH, buf->data); + net_buf_add_u8(buf, fcs); + + return bt_l2cap_chan_send(&session->br_chan.chan, buf); +} + +static int rfcomm_send_msc(struct bt_rfcomm_dlc *dlc, uint8_t cr, + uint8_t v24_signal) +{ + struct bt_rfcomm_msc *msc; + struct net_buf *buf; + uint8_t fcs; + + buf = rfcomm_make_uih_msg(dlc->session, cr, BT_RFCOMM_MSC, + sizeof(*msc)); + + msc = net_buf_add(buf, sizeof(*msc)); + /* cr bit should be always 1 in MSC */ + msc->dlci = BT_RFCOMM_SET_ADDR(dlc->dlci, 1); + msc->v24_signal = v24_signal; + + fcs = rfcomm_calc_fcs(BT_RFCOMM_FCS_LEN_UIH, buf->data); + net_buf_add_u8(buf, fcs); + + return bt_l2cap_chan_send(&dlc->session->br_chan.chan, buf); +} + +static int rfcomm_send_rls(struct bt_rfcomm_dlc *dlc, uint8_t cr, + uint8_t line_status) +{ + struct bt_rfcomm_rls *rls; + struct net_buf *buf; + uint8_t fcs; + + buf = rfcomm_make_uih_msg(dlc->session, cr, BT_RFCOMM_RLS, + sizeof(*rls)); + + rls = net_buf_add(buf, sizeof(*rls)); + /* cr bit should be always 1 in RLS */ + rls->dlci = BT_RFCOMM_SET_ADDR(dlc->dlci, 1); + rls->line_status = line_status; + + fcs = rfcomm_calc_fcs(BT_RFCOMM_FCS_LEN_UIH, buf->data); + net_buf_add_u8(buf, fcs); + + return bt_l2cap_chan_send(&dlc->session->br_chan.chan, buf); +} + +static int rfcomm_send_rpn(struct bt_rfcomm_session *session, uint8_t cr, + struct bt_rfcomm_rpn *rpn) +{ + struct net_buf *buf; + uint8_t fcs; + + buf = rfcomm_make_uih_msg(session, cr, BT_RFCOMM_RPN, sizeof(*rpn)); + + net_buf_add_mem(buf, rpn, sizeof(*rpn)); + + fcs = rfcomm_calc_fcs(BT_RFCOMM_FCS_LEN_UIH, buf->data); + net_buf_add_u8(buf, fcs); + + return bt_l2cap_chan_send(&session->br_chan.chan, buf); +} + +static int rfcomm_send_test(struct bt_rfcomm_session *session, uint8_t cr, + uint8_t *pattern, uint8_t len) +{ + struct net_buf *buf; + uint8_t fcs; + + buf = rfcomm_make_uih_msg(session, cr, BT_RFCOMM_TEST, len); + + net_buf_add_mem(buf, pattern, len); + + fcs = rfcomm_calc_fcs(BT_RFCOMM_FCS_LEN_UIH, buf->data); + net_buf_add_u8(buf, fcs); + + return bt_l2cap_chan_send(&session->br_chan.chan, buf); +} + +static int rfcomm_send_nsc(struct bt_rfcomm_session *session, uint8_t cmd_type) +{ + struct net_buf *buf; + uint8_t fcs; + + buf = rfcomm_make_uih_msg(session, BT_RFCOMM_MSG_RESP_CR, + BT_RFCOMM_NSC, sizeof(cmd_type)); + + net_buf_add_u8(buf, cmd_type); + + fcs = rfcomm_calc_fcs(BT_RFCOMM_FCS_LEN_UIH, buf->data); + net_buf_add_u8(buf, fcs); + + return bt_l2cap_chan_send(&session->br_chan.chan, buf); +} + +static int rfcomm_send_fcon(struct bt_rfcomm_session *session, uint8_t cr) +{ + struct net_buf *buf; + uint8_t fcs; + + buf = rfcomm_make_uih_msg(session, cr, BT_RFCOMM_FCON, 0); + + fcs = rfcomm_calc_fcs(BT_RFCOMM_FCS_LEN_UIH, buf->data); + net_buf_add_u8(buf, fcs); + + return bt_l2cap_chan_send(&session->br_chan.chan, buf); +} + +static int rfcomm_send_fcoff(struct bt_rfcomm_session *session, uint8_t cr) +{ + struct net_buf *buf; + uint8_t fcs; + + buf = rfcomm_make_uih_msg(session, cr, BT_RFCOMM_FCOFF, 0); + + fcs = rfcomm_calc_fcs(BT_RFCOMM_FCS_LEN_UIH, buf->data); + net_buf_add_u8(buf, fcs); + + return bt_l2cap_chan_send(&session->br_chan.chan, buf); +} + +static void rfcomm_dlc_connected(struct bt_rfcomm_dlc *dlc) +{ + dlc->state = BT_RFCOMM_STATE_CONNECTED; + + rfcomm_send_msc(dlc, BT_RFCOMM_MSG_CMD_CR, BT_RFCOMM_DEFAULT_V24_SIG); + + if (dlc->session->cfc == BT_RFCOMM_CFC_UNKNOWN) { + /* This means PN negotiation is not done for this session and + * can happen only for 1.0b device. + */ + dlc->session->cfc = BT_RFCOMM_CFC_NOT_SUPPORTED; + } + + if (dlc->session->cfc == BT_RFCOMM_CFC_NOT_SUPPORTED) { + BT_DBG("CFC not supported %p", dlc); + rfcomm_send_fcon(dlc->session, BT_RFCOMM_MSG_CMD_CR); + /* Use tx_credits as binary sem for MSC FC */ + k_sem_init(&dlc->tx_credits, 0, 1); + } + + /* Cancel conn timer */ + k_delayed_work_cancel(&dlc->rtx_work); + + k_fifo_init(&dlc->tx_queue); + k_thread_spawn(dlc->stack, sizeof(dlc->stack), rfcomm_dlc_tx_thread, + dlc, NULL, NULL, K_PRIO_COOP(7), 0, K_NO_WAIT); + + if (dlc->ops && dlc->ops->connected) { + dlc->ops->connected(dlc); + } +} + +enum security_result { + RFCOMM_SECURITY_PASSED, + RFCOMM_SECURITY_REJECT, + RFCOMM_SECURITY_PENDING +}; + +static enum security_result rfcomm_dlc_security(struct bt_rfcomm_dlc *dlc) +{ + struct bt_conn *conn = dlc->session->br_chan.chan.conn; + + BT_DBG("dlc %p", dlc); + + /* If current security level is greater than or equal to required + * security level then return SUCCESS. + * For SSP devices the current security will be atleast MEDIUM + * since L2CAP is enforcing it + */ + if (conn->sec_level >= dlc->required_sec_level) { + return RFCOMM_SECURITY_PASSED; + } + + if (!bt_conn_security(conn, dlc->required_sec_level)) { + /* If Security elevation is initiated or in progress */ + return RFCOMM_SECURITY_PENDING; + } + + /* Security request failed */ + return RFCOMM_SECURITY_REJECT; +} + +static void rfcomm_dlc_drop(struct bt_rfcomm_dlc *dlc) +{ + BT_DBG("dlc %p", dlc); + + rfcomm_dlcs_remove_dlci(dlc->session->dlcs, dlc->dlci); + rfcomm_dlc_destroy(dlc); +} + +static int rfcomm_dlc_close(struct bt_rfcomm_dlc *dlc) +{ + BT_DBG("dlc %p", dlc); + + switch (dlc->state) { + case BT_RFCOMM_STATE_SECURITY_PENDING: + if (dlc->role == BT_RFCOMM_ROLE_ACCEPTOR) { + rfcomm_send_dm(dlc->session, dlc->dlci); + } + /* Fall Through */ + case BT_RFCOMM_STATE_INIT: + rfcomm_dlc_drop(dlc); + break; + case BT_RFCOMM_STATE_CONNECTING: + case BT_RFCOMM_STATE_CONFIG: + dlc->state = BT_RFCOMM_STATE_DISCONNECTING; + rfcomm_send_disc(dlc->session, dlc->dlci); + k_delayed_work_submit(&dlc->rtx_work, RFCOMM_DISC_TIMEOUT); + break; + case BT_RFCOMM_STATE_CONNECTED: + dlc->state = BT_RFCOMM_STATE_DISCONNECTING; + + /* Queue a dummy buffer to wake up and stop the + * tx thread. + */ + net_buf_put(&dlc->tx_queue, + net_buf_alloc(&dummy_pool, K_NO_WAIT)); + + /* There could be a writer waiting for credits so return a + * dummy credit to wake it up. + */ + rfcomm_dlc_tx_give_credits(dlc, 1); + break; + case BT_RFCOMM_STATE_DISCONNECTING: + case BT_RFCOMM_STATE_DISCONNECTED: + break; + case BT_RFCOMM_STATE_IDLE: + default: + return -EINVAL; + } + + return 0; +} + +static void rfcomm_handle_sabm(struct bt_rfcomm_session *session, uint8_t dlci) +{ + if (!dlci) { + if (rfcomm_send_ua(session, dlci) < 0) { + return; + } + + session->state = BT_RFCOMM_STATE_CONNECTED; + } else { + struct bt_rfcomm_dlc *dlc; + enum security_result result; + + dlc = rfcomm_dlcs_lookup_dlci(session->dlcs, dlci); + if (!dlc) { + dlc = rfcomm_dlc_accept(session, dlci); + if (!dlc) { + rfcomm_send_dm(session, dlci); + return; + } + } + + result = rfcomm_dlc_security(dlc); + switch (result) { + case RFCOMM_SECURITY_PENDING: + dlc->state = BT_RFCOMM_STATE_SECURITY_PENDING; + return; + case RFCOMM_SECURITY_PASSED: + break; + case RFCOMM_SECURITY_REJECT: + default: + rfcomm_send_dm(session, dlci); + rfcomm_dlc_drop(dlc); + return; + } + + if (rfcomm_send_ua(session, dlci) < 0) { + return; + } + + /* Cancel idle timer if any */ + k_delayed_work_cancel(&session->rtx_work); + + rfcomm_dlc_connected(dlc); + } +} + +static int rfcomm_send_pn(struct bt_rfcomm_dlc *dlc, uint8_t cr) +{ + struct bt_rfcomm_pn *pn; + struct net_buf *buf; + uint8_t fcs; + + buf = rfcomm_make_uih_msg(dlc->session, cr, BT_RFCOMM_PN, sizeof(*pn)); + + BT_DBG("mtu %x", dlc->mtu); + + pn = net_buf_add(buf, sizeof(*pn)); + pn->dlci = dlc->dlci; + pn->mtu = sys_cpu_to_le16(dlc->mtu); + if (dlc->state == BT_RFCOMM_STATE_CONFIG && + (dlc->session->cfc == BT_RFCOMM_CFC_UNKNOWN || + dlc->session->cfc == BT_RFCOMM_CFC_SUPPORTED)) { + pn->credits = dlc->rx_credit; + if (cr) { + pn->flow_ctrl = BT_RFCOMM_PN_CFC_CMD; + } else { + pn->flow_ctrl = BT_RFCOMM_PN_CFC_RESP; + } + } else { + /* If PN comes in already opened dlc or cfc not supported + * these should be 0 + */ + pn->credits = 0; + pn->flow_ctrl = 0; + } + pn->max_retrans = 0; + pn->ack_timer = 0; + pn->priority = 0; + + fcs = rfcomm_calc_fcs(BT_RFCOMM_FCS_LEN_UIH, buf->data); + net_buf_add_u8(buf, fcs); + + return bt_l2cap_chan_send(&dlc->session->br_chan.chan, buf); +} + +static int rfcomm_send_credit(struct bt_rfcomm_dlc *dlc, uint8_t credits) +{ + struct bt_rfcomm_hdr *hdr; + struct net_buf *buf; + uint8_t fcs, cr; + + BT_DBG("Dlc %p credits %d", dlc, credits); + + buf = bt_l2cap_create_pdu(NULL, 0); + + hdr = net_buf_add(buf, sizeof(*hdr)); + cr = BT_RFCOMM_UIH_CR(dlc->session->role); + hdr->address = BT_RFCOMM_SET_ADDR(dlc->dlci, cr); + hdr->control = BT_RFCOMM_SET_CTRL(BT_RFCOMM_UIH, + BT_RFCOMM_PF_UIH_CREDIT); + hdr->length = BT_RFCOMM_SET_LEN_8(0); + net_buf_add_u8(buf, credits); + fcs = rfcomm_calc_fcs(BT_RFCOMM_FCS_LEN_UIH, buf->data); + net_buf_add_u8(buf, fcs); + + return bt_l2cap_chan_send(&dlc->session->br_chan.chan, buf); +} + +static int rfcomm_dlc_start(struct bt_rfcomm_dlc *dlc) +{ + enum security_result result; + + BT_DBG("dlc %p", dlc); + + result = rfcomm_dlc_security(dlc); + switch (result) { + case RFCOMM_SECURITY_PASSED: + dlc->mtu = min(dlc->mtu, dlc->session->mtu); + dlc->state = BT_RFCOMM_STATE_CONFIG; + rfcomm_send_pn(dlc, BT_RFCOMM_MSG_CMD_CR); + break; + case RFCOMM_SECURITY_PENDING: + dlc->state = BT_RFCOMM_STATE_SECURITY_PENDING; + break; + case RFCOMM_SECURITY_REJECT: + default: + return -EIO; + } + + return 0; +} + +static void rfcomm_handle_ua(struct bt_rfcomm_session *session, uint8_t dlci) +{ + struct bt_rfcomm_dlc *dlc, *next; + int err; + + if (!dlci) { + switch (session->state) { + case BT_RFCOMM_STATE_CONNECTING: + session->state = BT_RFCOMM_STATE_CONNECTED; + for (dlc = session->dlcs; dlc; dlc = next) { + next = dlc->_next; + if (dlc->role == BT_RFCOMM_ROLE_INITIATOR && + dlc->state == BT_RFCOMM_STATE_INIT) { + if (rfcomm_dlc_start(dlc) < 0) { + rfcomm_dlc_drop(dlc); + } + } + } + /* Disconnect session if there is no dlcs left */ + rfcomm_session_disconnect(session); + break; + case BT_RFCOMM_STATE_DISCONNECTING: + session->state = BT_RFCOMM_STATE_DISCONNECTED; + /* Cancel disc timer */ + k_delayed_work_cancel(&session->rtx_work); + err = bt_l2cap_chan_disconnect(&session->br_chan.chan); + if (err < 0) { + session->state = BT_RFCOMM_STATE_IDLE; + } + break; + default: + break; + } + } else { + dlc = rfcomm_dlcs_lookup_dlci(session->dlcs, dlci); + if (!dlc) { + return; + } + + switch (dlc->state) { + case BT_RFCOMM_STATE_CONNECTING: + rfcomm_dlc_connected(dlc); + break; + case BT_RFCOMM_STATE_DISCONNECTING: + rfcomm_dlc_drop(dlc); + rfcomm_session_disconnect(session); + break; + default: + break; + } + } +} + +static void rfcomm_handle_dm(struct bt_rfcomm_session *session, uint8_t dlci) +{ + struct bt_rfcomm_dlc *dlc; + + BT_DBG("dlci %d", dlci); + + dlc = rfcomm_dlcs_remove_dlci(session->dlcs, dlci); + if (!dlc) { + return; + } + + rfcomm_dlc_disconnect(dlc); + rfcomm_session_disconnect(session); +} + +static void rfcomm_handle_msc(struct bt_rfcomm_session *session, + struct net_buf *buf, uint8_t cr) +{ + struct bt_rfcomm_msc *msc = (void *)buf->data; + struct bt_rfcomm_dlc *dlc; + uint8_t dlci = BT_RFCOMM_GET_DLCI(msc->dlci); + + BT_DBG("dlci %d", dlci); + + dlc = rfcomm_dlcs_lookup_dlci(session->dlcs, dlci); + if (!dlc) { + return; + } + + if (cr == BT_RFCOMM_MSG_RESP_CR) { + return; + } + + if (dlc->session->cfc == BT_RFCOMM_CFC_NOT_SUPPORTED) { + /* Only FC bit affects the flow on RFCOMM level */ + if (BT_RFCOMM_GET_FC(msc->v24_signal)) { + /* If FC bit is 1 the device is unable to accept frames. + * Take the semaphore with timeout K_NO_WAIT so that + * dlc thread will be blocked when it tries sem_take + * before sending the data. K_NO_WAIT timeout will make + * sure that RX thread will not be blocked while taking + * the semaphore. + */ + k_sem_take(&dlc->tx_credits, K_NO_WAIT); + } else { + /* Give the sem so that it will unblock the waiting dlc + * thread in sem_take(). + */ + k_sem_give(&dlc->tx_credits); + } + } + + rfcomm_send_msc(dlc, BT_RFCOMM_MSG_RESP_CR, msc->v24_signal); +} + +static void rfcomm_handle_rls(struct bt_rfcomm_session *session, + struct net_buf *buf, uint8_t cr) +{ + struct bt_rfcomm_rls *rls = (void *)buf->data; + uint8_t dlci = BT_RFCOMM_GET_DLCI(rls->dlci); + struct bt_rfcomm_dlc *dlc; + + BT_DBG("dlci %d", dlci); + + if (!cr) { + /* Ignore if its a response */ + return; + } + + dlc = rfcomm_dlcs_lookup_dlci(session->dlcs, dlci); + if (!dlc) { + return; + } + + /* As per the ETSI same line status has to returned in the response */ + rfcomm_send_rls(dlc, BT_RFCOMM_MSG_RESP_CR, rls->line_status); +} + +static void rfcomm_handle_rpn(struct bt_rfcomm_session *session, + struct net_buf *buf, uint8_t cr) +{ + struct bt_rfcomm_rpn default_rpn, *rpn = (void *)buf->data; + uint8_t dlci = BT_RFCOMM_GET_DLCI(rpn->dlci); + uint8_t data_bits, stop_bits, parity_bits; + /* Exclude fcs to get number of value bytes */ + uint8_t value_len = buf->len - 1; + + BT_DBG("dlci %d", dlci); + + if (!cr) { + /* Ignore if its a response */ + return; + } + + if (value_len == sizeof(*rpn)) { + /* Accept all the values proposed by the sender */ + rpn->param_mask = sys_cpu_to_le16(BT_RFCOMM_RPN_PARAM_MASK_ALL); + rfcomm_send_rpn(session, BT_RFCOMM_MSG_RESP_CR, rpn); + return; + } + + if (value_len != 1) { + return; + } + + /* If only one value byte then current port settings has to be returned + * We will send default values + */ + default_rpn.dlci = BT_RFCOMM_SET_ADDR(dlci, 1); + default_rpn.baud_rate = BT_RFCOMM_RPN_BAUD_RATE_9600; + default_rpn.flow_control = BT_RFCOMM_RPN_FLOW_NONE; + default_rpn.xoff_char = BT_RFCOMM_RPN_XOFF_CHAR; + default_rpn.xon_char = BT_RFCOMM_RPN_XON_CHAR; + data_bits = BT_RFCOMM_RPN_DATA_BITS_8; + stop_bits = BT_RFCOMM_RPN_STOP_BITS_1; + parity_bits = BT_RFCOMM_RPN_PARITY_NONE; + default_rpn.line_settings = BT_RFCOMM_SET_LINE_SETTINGS(data_bits, + stop_bits, + parity_bits); + default_rpn.param_mask = sys_cpu_to_le16(BT_RFCOMM_RPN_PARAM_MASK_ALL); + + rfcomm_send_rpn(session, BT_RFCOMM_MSG_RESP_CR, &default_rpn); +} + +static void rfcomm_handle_pn(struct bt_rfcomm_session *session, + struct net_buf *buf, uint8_t cr) +{ + struct bt_rfcomm_pn *pn = (void *)buf->data; + struct bt_rfcomm_dlc *dlc; + + dlc = rfcomm_dlcs_lookup_dlci(session->dlcs, pn->dlci); + if (!dlc) { + /* Ignore if it is a response */ + if (!cr) { + return; + } + + if (!BT_RFCOMM_CHECK_MTU(pn->mtu)) { + BT_ERR("Invalid mtu %d", pn->mtu); + rfcomm_send_dm(session, pn->dlci); + return; + } + + dlc = rfcomm_dlc_accept(session, pn->dlci); + if (!dlc) { + rfcomm_send_dm(session, pn->dlci); + return; + } + + BT_DBG("Incoming connection accepted dlc %p", dlc); + + dlc->mtu = min(dlc->mtu, sys_le16_to_cpu(pn->mtu)); + + if (pn->flow_ctrl == BT_RFCOMM_PN_CFC_CMD) { + if (session->cfc == BT_RFCOMM_CFC_UNKNOWN) { + session->cfc = BT_RFCOMM_CFC_SUPPORTED; + } + k_sem_init(&dlc->tx_credits, 0, UINT32_MAX); + rfcomm_dlc_tx_give_credits(dlc, pn->credits); + } else { + session->cfc = BT_RFCOMM_CFC_NOT_SUPPORTED; + } + + dlc->state = BT_RFCOMM_STATE_CONFIG; + rfcomm_send_pn(dlc, BT_RFCOMM_MSG_RESP_CR); + /* Cancel idle timer if any */ + k_delayed_work_cancel(&session->rtx_work); + } else { + /* If its a command */ + if (cr) { + if (!BT_RFCOMM_CHECK_MTU(pn->mtu)) { + BT_ERR("Invalid mtu %d", pn->mtu); + rfcomm_dlc_close(dlc); + return; + } + dlc->mtu = min(dlc->mtu, sys_le16_to_cpu(pn->mtu)); + rfcomm_send_pn(dlc, BT_RFCOMM_MSG_RESP_CR); + } else { + if (dlc->state != BT_RFCOMM_STATE_CONFIG) { + return; + } + + dlc->mtu = min(dlc->mtu, sys_le16_to_cpu(pn->mtu)); + if (pn->flow_ctrl == BT_RFCOMM_PN_CFC_RESP) { + if (session->cfc == BT_RFCOMM_CFC_UNKNOWN) { + session->cfc = BT_RFCOMM_CFC_SUPPORTED; + } + k_sem_init(&dlc->tx_credits, 0, UINT32_MAX); + rfcomm_dlc_tx_give_credits(dlc, pn->credits); + } else { + session->cfc = BT_RFCOMM_CFC_NOT_SUPPORTED; + } + + dlc->state = BT_RFCOMM_STATE_CONNECTING; + rfcomm_send_sabm(session, dlc->dlci); + } + } +} + +static void rfcomm_handle_disc(struct bt_rfcomm_session *session, uint8_t dlci) +{ + struct bt_rfcomm_dlc *dlc; + + BT_DBG("Dlci %d", dlci); + + if (dlci) { + dlc = rfcomm_dlcs_remove_dlci(session->dlcs, dlci); + if (!dlc) { + rfcomm_send_dm(session, dlci); + return; + } + + rfcomm_send_ua(session, dlci); + rfcomm_dlc_disconnect(dlc); + + if (!session->dlcs) { + /* Start a session idle timer */ + k_delayed_work_submit(&dlc->session->rtx_work, + RFCOMM_IDLE_TIMEOUT); + } + } else { + /* Cancel idle timer */ + k_delayed_work_cancel(&session->rtx_work); + rfcomm_send_ua(session, 0); + rfcomm_session_disconnected(session); + } +} + +static void rfcomm_handle_msg(struct bt_rfcomm_session *session, + struct net_buf *buf) +{ + struct bt_rfcomm_msg_hdr *hdr = (void *)buf->data; + uint8_t msg_type, len, cr; + + msg_type = BT_RFCOMM_GET_MSG_TYPE(hdr->type); + cr = BT_RFCOMM_GET_MSG_CR(hdr->type); + len = BT_RFCOMM_GET_LEN(hdr->len); + + BT_DBG("msg type %x cr %x", msg_type, cr); + + net_buf_pull(buf, sizeof(*hdr)); + + switch (msg_type) { + case BT_RFCOMM_PN: + rfcomm_handle_pn(session, buf, cr); + break; + case BT_RFCOMM_MSC: + rfcomm_handle_msc(session, buf, cr); + break; + case BT_RFCOMM_RLS: + rfcomm_handle_rls(session, buf, cr); + break; + case BT_RFCOMM_RPN: + rfcomm_handle_rpn(session, buf, cr); + break; + case BT_RFCOMM_TEST: + if (!cr) { + break; + } + rfcomm_send_test(session, BT_RFCOMM_MSG_RESP_CR, buf->data, + buf->len - 1); + break; + case BT_RFCOMM_FCON: + if (session->cfc == BT_RFCOMM_CFC_SUPPORTED) { + BT_ERR("FCON received when CFC is supported "); + return; + } + + if (!cr) { + break; + } + + /* Give the sem so that it will unblock the waiting dlc threads + * of this session in sem_take(). + */ + k_sem_give(&session->fc); + rfcomm_send_fcon(session, BT_RFCOMM_MSG_RESP_CR); + break; + case BT_RFCOMM_FCOFF: + if (session->cfc == BT_RFCOMM_CFC_SUPPORTED) { + BT_ERR("FCOFF received when CFC is supported "); + return; + } + + if (!cr) { + break; + } + + /* Take the semaphore with timeout K_NO_WAIT so that all the + * dlc threads in this session will be blocked when it tries + * sem_take before sending the data. K_NO_WAIT timeout will + * make sure that RX thread will not be blocked while taking + * the semaphore. + */ + k_sem_take(&session->fc, K_NO_WAIT); + rfcomm_send_fcoff(session, BT_RFCOMM_MSG_RESP_CR); + break; + default: + BT_WARN("Unknown/Unsupported RFCOMM Msg type 0x%02x", msg_type); + rfcomm_send_nsc(session, hdr->type); + break; + } +} + +static void rfcomm_dlc_update_credits(struct bt_rfcomm_dlc *dlc) +{ + uint8_t credits; + + if (dlc->session->cfc == BT_RFCOMM_CFC_NOT_SUPPORTED) { + return; + } + + BT_DBG("dlc %p credits %u", dlc, dlc->rx_credit); + + /* Only give more credits if it went below the defined threshold */ + if (dlc->rx_credit > RFCOMM_CREDITS_THRESHOLD) { + return; + } + + /* Restore credits */ + credits = RFCOMM_MAX_CREDITS - dlc->rx_credit; + dlc->rx_credit += credits; + + rfcomm_send_credit(dlc, credits); +} + +static void rfcomm_handle_data(struct bt_rfcomm_session *session, + struct net_buf *buf, uint8_t dlci, uint8_t pf) + +{ + struct bt_rfcomm_dlc *dlc; + + BT_DBG("dlci %d, pf %d", dlci, pf); + + dlc = rfcomm_dlcs_lookup_dlci(session->dlcs, dlci); + if (!dlc) { + BT_ERR("Data recvd in non existing DLC"); + rfcomm_send_dm(session, dlci); + return; + } + + BT_DBG("dlc %p rx credit %d", dlc, dlc->rx_credit); + + if (dlc->state != BT_RFCOMM_STATE_CONNECTED) { + return; + } + + if (pf == BT_RFCOMM_PF_UIH_CREDIT) { + rfcomm_dlc_tx_give_credits(dlc, net_buf_pull_u8(buf)); + } + + if (buf->len > BT_RFCOMM_FCS_SIZE) { + if (dlc->session->cfc == BT_RFCOMM_CFC_SUPPORTED && + !dlc->rx_credit) { + BT_ERR("Data recvd when rx credit is 0"); + rfcomm_dlc_close(dlc); + return; + } + + /* Remove FCS */ + buf->len -= BT_RFCOMM_FCS_SIZE; + if (dlc->ops && dlc->ops->recv) { + dlc->ops->recv(dlc, buf); + } + + dlc->rx_credit--; + rfcomm_dlc_update_credits(dlc); + } +} + +int bt_rfcomm_dlc_send(struct bt_rfcomm_dlc *dlc, struct net_buf *buf) +{ + struct bt_rfcomm_hdr *hdr; + uint8_t fcs, cr; + + if (!buf) { + return -EINVAL; + } + + BT_DBG("dlc %p tx credit %d", dlc, k_sem_count_get(&dlc->tx_credits)); + + if (dlc->state != BT_RFCOMM_STATE_CONNECTED) { + return -ENOTCONN; + } + + if (buf->len > dlc->mtu) { + return -EMSGSIZE; + } + + if (buf->len > BT_RFCOMM_MAX_LEN_8) { + uint16_t *len; + + /* Length is 2 byte */ + hdr = net_buf_push(buf, sizeof(*hdr) + 1); + len = (uint16_t *)&hdr->length; + *len = BT_RFCOMM_SET_LEN_16(sys_cpu_to_le16(buf->len - + sizeof(*hdr) + 1)); + } else { + hdr = net_buf_push(buf, sizeof(*hdr)); + hdr->length = BT_RFCOMM_SET_LEN_8(buf->len - sizeof(*hdr)); + } + + cr = BT_RFCOMM_UIH_CR(dlc->session->role); + hdr->address = BT_RFCOMM_SET_ADDR(dlc->dlci, cr); + hdr->control = BT_RFCOMM_SET_CTRL(BT_RFCOMM_UIH, + BT_RFCOMM_PF_UIH_NO_CREDIT); + + fcs = rfcomm_calc_fcs(BT_RFCOMM_FCS_LEN_UIH, buf->data); + net_buf_add_u8(buf, fcs); + + net_buf_put(&dlc->tx_queue, buf); + + return buf->len; +} + +static void rfcomm_recv(struct bt_l2cap_chan *chan, struct net_buf *buf) +{ + struct bt_rfcomm_session *session = RFCOMM_SESSION(chan); + struct bt_rfcomm_hdr *hdr = (void *)buf->data; + uint8_t dlci, frame_type, fcs, fcs_len; + + /* Need to consider FCS also*/ + if (buf->len < (sizeof(*hdr) + 1)) { + BT_ERR("Too small RFCOMM Frame"); + return; + } + + dlci = BT_RFCOMM_GET_DLCI(hdr->address); + frame_type = BT_RFCOMM_GET_FRAME_TYPE(hdr->control); + + BT_DBG("session %p dlci %x type %x", session, dlci, frame_type); + + fcs_len = (frame_type == BT_RFCOMM_UIH) ? BT_RFCOMM_FCS_LEN_UIH : + BT_RFCOMM_FCS_LEN_NON_UIH; + fcs = *(net_buf_tail(buf) - 1); + if (!rfcomm_check_fcs(fcs_len, buf->data, fcs)) { + BT_ERR("FCS check failed"); + return; + } + + if (BT_RFCOMM_LEN_EXTENDED(hdr->length)) { + net_buf_pull(buf, sizeof(*hdr) + 1); + } else { + net_buf_pull(buf, sizeof(*hdr)); + } + + switch (frame_type) { + case BT_RFCOMM_SABM: + rfcomm_handle_sabm(session, dlci); + break; + case BT_RFCOMM_UIH: + if (!dlci) { + rfcomm_handle_msg(session, buf); + } else { + rfcomm_handle_data(session, buf, dlci, + BT_RFCOMM_GET_PF(hdr->control)); + } + break; + case BT_RFCOMM_DISC: + rfcomm_handle_disc(session, dlci); + break; + case BT_RFCOMM_UA: + rfcomm_handle_ua(session, dlci); + break; + case BT_RFCOMM_DM: + rfcomm_handle_dm(session, dlci); + break; + default: + BT_WARN("Unknown/Unsupported RFCOMM Frame type 0x%02x", + frame_type); + break; + } +} + +static void rfcomm_encrypt_change(struct bt_l2cap_chan *chan, + uint8_t hci_status) +{ + struct bt_rfcomm_session *session = RFCOMM_SESSION(chan); + struct bt_conn *conn = chan->conn; + struct bt_rfcomm_dlc *dlc, *next; + + BT_DBG("session %p status 0x%02x encr 0x%02x", session, hci_status, + conn->encrypt); + + for (dlc = session->dlcs; dlc; dlc = next) { + next = dlc->_next; + + if (dlc->state != BT_RFCOMM_STATE_SECURITY_PENDING) { + continue; + } + + if (hci_status || !conn->encrypt || + conn->sec_level < dlc->required_sec_level) { + rfcomm_dlc_close(dlc); + continue; + } + + if (dlc->role == BT_RFCOMM_ROLE_ACCEPTOR) { + rfcomm_send_ua(session, dlc->dlci); + rfcomm_dlc_connected(dlc); + } else { + dlc->mtu = min(dlc->mtu, session->mtu); + dlc->state = BT_RFCOMM_STATE_CONFIG; + rfcomm_send_pn(dlc, BT_RFCOMM_MSG_CMD_CR); + } + } +} + +static void rfcomm_session_rtx_timeout(struct k_work *work) +{ + struct bt_rfcomm_session *session = SESSION_RTX(work); + + BT_WARN("session %p state %d timeout", session, session->state); + + switch (session->state) { + case BT_RFCOMM_STATE_CONNECTED: + rfcomm_session_disconnect(session); + break; + case BT_RFCOMM_STATE_DISCONNECTING: + session->state = BT_RFCOMM_STATE_DISCONNECTED; + if (bt_l2cap_chan_disconnect(&session->br_chan.chan) < 0) { + session->state = BT_RFCOMM_STATE_IDLE; + } + break; + } +} + +static struct bt_rfcomm_session *rfcomm_session_new(bt_rfcomm_role_t role) +{ + int i; + static struct bt_l2cap_chan_ops ops = { + .connected = rfcomm_connected, + .disconnected = rfcomm_disconnected, + .recv = rfcomm_recv, + .encrypt_change = rfcomm_encrypt_change, + }; + + for (i = 0; i < ARRAY_SIZE(bt_rfcomm_pool); i++) { + struct bt_rfcomm_session *session = &bt_rfcomm_pool[i]; + + if (session->br_chan.chan.conn) { + continue; + } + + BT_DBG("session %p initialized", session); + + session->br_chan.chan.ops = &ops; + session->br_chan.rx.mtu = CONFIG_BLUETOOTH_RFCOMM_L2CAP_MTU; + session->state = BT_RFCOMM_STATE_INIT; + session->role = role; + session->cfc = BT_RFCOMM_CFC_UNKNOWN; + k_delayed_work_init(&session->rtx_work, + rfcomm_session_rtx_timeout); + k_sem_init(&session->fc, 0, 1); + + return session; + } + + return NULL; +} + +int bt_rfcomm_dlc_connect(struct bt_conn *conn, struct bt_rfcomm_dlc *dlc, + uint8_t channel) +{ + struct bt_rfcomm_session *session; + struct bt_l2cap_chan *chan; + uint8_t dlci; + int ret; + + BT_DBG("conn %p dlc %p channel %d", conn, dlc, channel); + + if (!dlc) { + return -EINVAL; + } + + if (!conn || conn->state != BT_CONN_CONNECTED) { + return -ENOTCONN; + } + + if (channel < RFCOMM_CHANNEL_START || channel > RFCOMM_CHANNEL_END) { + return -EINVAL; + } + + if (!BT_RFCOMM_CHECK_MTU(dlc->mtu)) { + return -EINVAL; + } + + session = rfcomm_sessions_lookup_bt_conn(conn); + if (!session) { + session = rfcomm_session_new(BT_RFCOMM_ROLE_INITIATOR); + if (!session) { + return -ENOMEM; + } + } + + dlci = BT_RFCOMM_DLCI(session->role, channel); + + if (rfcomm_dlcs_lookup_dlci(session->dlcs, dlci)) { + return -EBUSY; + } + + rfcomm_dlc_init(dlc, session, dlci, BT_RFCOMM_ROLE_INITIATOR); + + switch (session->state) { + case BT_RFCOMM_STATE_INIT: + if (session->role == BT_RFCOMM_ROLE_ACCEPTOR) { + /* There is an ongoing incoming conn */ + break; + } + chan = &session->br_chan.chan; + chan->required_sec_level = dlc->required_sec_level; + ret = bt_l2cap_chan_connect(conn, chan, BT_L2CAP_PSM_RFCOMM); + if (ret < 0) { + session->state = BT_RFCOMM_STATE_IDLE; + goto fail; + } + session->state = BT_RFCOMM_STATE_CONNECTING; + break; + case BT_RFCOMM_STATE_CONNECTING: + break; + case BT_RFCOMM_STATE_CONNECTED: + ret = rfcomm_dlc_start(dlc); + if (ret < 0) { + goto fail; + } + /* Cancel idle timer if any */ + k_delayed_work_cancel(&session->rtx_work); + break; + default: + BT_ERR("Invalid session state %d", session->state); + ret = -EINVAL; + goto fail; + } + + return 0; + +fail: + rfcomm_dlcs_remove_dlci(session->dlcs, dlc->dlci); + dlc->state = BT_RFCOMM_STATE_IDLE; + dlc->session = NULL; + return ret; +} + +int bt_rfcomm_dlc_disconnect(struct bt_rfcomm_dlc *dlc) +{ + BT_DBG("dlc %p", dlc); + + if (!dlc) { + return -EINVAL; + } + + if (dlc->state == BT_RFCOMM_STATE_CONNECTED) { + /* This is to handle user initiated disconnect to send pending + * bufs in the queue before disconnecting + * Queue a dummy buffer (in case if queue is empty) to wake up + * and stop the tx thread. + */ + dlc->state = BT_RFCOMM_STATE_USER_DISCONNECT; + net_buf_put(&dlc->tx_queue, + net_buf_alloc(&dummy_pool, K_NO_WAIT)); + + k_delayed_work_submit(&dlc->rtx_work, RFCOMM_DISC_TIMEOUT); + + return 0; + } + + return rfcomm_dlc_close(dlc); +} + +static int rfcomm_accept(struct bt_conn *conn, struct bt_l2cap_chan **chan) +{ + struct bt_rfcomm_session *session; + + BT_DBG("conn %p", conn); + + session = rfcomm_session_new(BT_RFCOMM_ROLE_ACCEPTOR); + if (session) { + *chan = &session->br_chan.chan; + return 0; + } + + BT_ERR("No available RFCOMM context for conn %p", conn); + + return -ENOMEM; +} + +void bt_rfcomm_init(void) +{ + static struct bt_l2cap_server server = { + .psm = BT_L2CAP_PSM_RFCOMM, + .accept = rfcomm_accept, + .sec_level = BT_SECURITY_LOW, + }; + + bt_l2cap_br_server_register(&server); + + NET_BUF_POOL_INIT(dummy_pool); +} diff --git a/kernel/protocols/bluetooth/host/rfcomm_internal.h b/kernel/protocols/bluetooth/host/rfcomm_internal.h new file mode 100644 index 0000000000..73c1dcc643 --- /dev/null +++ b/kernel/protocols/bluetooth/host/rfcomm_internal.h @@ -0,0 +1,213 @@ +/** @file + * @brief Internal APIs for Bluetooth RFCOMM handling. + */ + +/* + * Copyright (c) 2015-2016 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +typedef enum { + BT_RFCOMM_CFC_UNKNOWN, + BT_RFCOMM_CFC_NOT_SUPPORTED, + BT_RFCOMM_CFC_SUPPORTED, +} __packed bt_rfcomm_cfc_t; + +/* RFCOMM signalling connection specific context */ +struct bt_rfcomm_session { + /* L2CAP channel this context is associated with */ + struct bt_l2cap_br_chan br_chan; + /* Response Timeout eXpired (RTX) timer */ + struct k_delayed_work rtx_work; + /* Binary sem for aggregate fc */ + struct k_sem fc; + struct bt_rfcomm_dlc *dlcs; + uint16_t mtu; + uint8_t state; + bt_rfcomm_role_t role; + bt_rfcomm_cfc_t cfc; +}; + +enum { + BT_RFCOMM_STATE_IDLE, + BT_RFCOMM_STATE_INIT, + BT_RFCOMM_STATE_SECURITY_PENDING, + BT_RFCOMM_STATE_CONNECTING, + BT_RFCOMM_STATE_CONNECTED, + BT_RFCOMM_STATE_CONFIG, + BT_RFCOMM_STATE_USER_DISCONNECT, + BT_RFCOMM_STATE_DISCONNECTING, + BT_RFCOMM_STATE_DISCONNECTED, +}; + +struct bt_rfcomm_hdr { + uint8_t address; + uint8_t control; + uint8_t length; +} __packed; + +#define BT_RFCOMM_SABM 0x2f +#define BT_RFCOMM_UA 0x63 +#define BT_RFCOMM_UIH 0xef + +struct bt_rfcomm_msg_hdr { + uint8_t type; + uint8_t len; +} __packed; + +#define BT_RFCOMM_PN 0x20 +struct bt_rfcomm_pn { + uint8_t dlci; + uint8_t flow_ctrl; + uint8_t priority; + uint8_t ack_timer; + uint16_t mtu; + uint8_t max_retrans; + uint8_t credits; +} __packed; + +#define BT_RFCOMM_MSC 0x38 +struct bt_rfcomm_msc { + uint8_t dlci; + uint8_t v24_signal; +} __packed; + +#define BT_RFCOMM_DISC 0x43 +#define BT_RFCOMM_DM 0x0f + +#define BT_RFCOMM_RLS 0x14 +struct bt_rfcomm_rls { + uint8_t dlci; + uint8_t line_status; +} __packed; + +#define BT_RFCOMM_RPN 0x24 +struct bt_rfcomm_rpn { + uint8_t dlci; + uint8_t baud_rate; + uint8_t line_settings; + uint8_t flow_control; + uint8_t xon_char; + uint8_t xoff_char; + uint16_t param_mask; +} __packed; + +#define BT_RFCOMM_TEST 0x08 +#define BT_RFCOMM_NSC 0x04 + +#define BT_RFCOMM_FCON 0x28 +#define BT_RFCOMM_FCOFF 0x18 + +/* Default RPN Settings */ +#define BT_RFCOMM_RPN_BAUD_RATE_9600 0x03 +#define BT_RFCOMM_RPN_DATA_BITS_8 0x03 +#define BT_RFCOMM_RPN_STOP_BITS_1 0x00 +#define BT_RFCOMM_RPN_PARITY_NONE 0x00 +#define BT_RFCOMM_RPN_FLOW_NONE 0x00 +#define BT_RFCOMM_RPN_XON_CHAR 0x11 +#define BT_RFCOMM_RPN_XOFF_CHAR 0x13 + +/* Set 1 to all the param mask except reserved */ +#define BT_RFCOMM_RPN_PARAM_MASK_ALL 0x3f7f + +#define BT_RFCOMM_SET_LINE_SETTINGS(data, stop, parity) ((data & 0x3) | \ + ((stop & 0x1) << 2) | \ + ((parity & 0x7) << 3)) + +/* DV = 1 IC = 0 RTR = 1 RTC = 1 FC = 0 EXT = 0 */ +#define BT_RFCOMM_DEFAULT_V24_SIG 0x8d + +#define BT_RFCOMM_GET_FC(v24_signal) (((v24_signal) & 0x02) >> 1) + +#define BT_RFCOMM_SIG_MIN_MTU 23 +#define BT_RFCOMM_SIG_MAX_MTU 32767 + +#define BT_RFCOMM_CHECK_MTU(mtu) (!!((mtu) >= BT_RFCOMM_SIG_MIN_MTU && \ + (mtu) <= BT_RFCOMM_SIG_MAX_MTU)) + +/* Helper to calculate needed outgoing buffer size. + * Length in rfcomm header can be two bytes depending on user data length. + * One byte in the tail should be reserved for FCS. + */ +#define BT_RFCOMM_BUF_SIZE(mtu) (CONFIG_BLUETOOTH_HCI_RESERVE + \ + BT_HCI_ACL_HDR_SIZE + BT_L2CAP_HDR_SIZE + \ + sizeof(struct bt_rfcomm_hdr) + 1 + (mtu) + \ + BT_RFCOMM_FCS_SIZE) + +#define BT_RFCOMM_GET_DLCI(addr) (((addr) & 0xfc) >> 2) +#define BT_RFCOMM_GET_FRAME_TYPE(ctrl) ((ctrl) & 0xef) +#define BT_RFCOMM_GET_MSG_TYPE(type) (((type) & 0xfc) >> 2) +#define BT_RFCOMM_GET_MSG_CR(type) (((type) & 0x02) >> 1) +#define BT_RFCOMM_GET_LEN(len) (((len) & 0xfe) >> 1) +#define BT_RFCOMM_GET_CHANNEL(dlci) ((dlci) >> 1) +#define BT_RFCOMM_GET_PF(ctrl) (((ctrl) & 0x10) >> 4) + +#define BT_RFCOMM_SET_ADDR(dlci, cr) ((((dlci) & 0x3f) << 2) | \ + ((cr) << 1) | 0x01) +#define BT_RFCOMM_SET_CTRL(type, pf) (((type) & 0xef) | ((pf) << 4)) +#define BT_RFCOMM_SET_LEN_8(len) (((len) << 1) | 1) +#define BT_RFCOMM_SET_LEN_16(len) ((len) << 1) +#define BT_RFCOMM_SET_MSG_TYPE(type, cr) (((type) << 2) | (cr << 1) | 0x01) + +#define BT_RFCOMM_LEN_EXTENDED(len) (!((len) & 0x01)) + +/* For CR in UIH Packet header + * Initiating station have the C/R bit set to 1 and those sent by the + * responding station have the C/R bit set to 0 + */ +#define BT_RFCOMM_UIH_CR(role) ((role) == BT_RFCOMM_ROLE_INITIATOR) + +/* For CR in Non UIH Packet header + * Command + * Initiator --> Responder 1 + * Responder --> Initiator 0 + * Response + * Initiator --> Responder 0 + * Responder --> Initiator 1 + */ +#define BT_RFCOMM_CMD_CR(role) ((role) == BT_RFCOMM_ROLE_INITIATOR) +#define BT_RFCOMM_RESP_CR(role) ((role) == BT_RFCOMM_ROLE_ACCEPTOR) + +/* For CR in MSG header + * If the C/R bit is set to 1 the message is a command, + * if it is set to 0 the message is a response. + */ +#define BT_RFCOMM_MSG_CMD_CR 1 +#define BT_RFCOMM_MSG_RESP_CR 0 + +#define BT_RFCOMM_DLCI(role, channel) ((((channel) & 0x1f) << 1) | \ + ((role) == BT_RFCOMM_ROLE_ACCEPTOR)) + +/* Excluding ext bit */ +#define BT_RFCOMM_MAX_LEN_8 127 + +/* Length can be 2 bytes depending on data size */ +#define BT_RFCOMM_HDR_SIZE (sizeof(struct bt_rfcomm_hdr) + 1) +#define BT_RFCOMM_FCS_SIZE 1 + +#define BT_RFCOMM_FCS_LEN_UIH 2 +#define BT_RFCOMM_FCS_LEN_NON_UIH 3 + +/* For non UIH packets + * The P bit set to 1 shall be used to solicit a response frame with the + * F bit set to 1 from the other station. + */ +#define BT_RFCOMM_PF_NON_UIH 1 + +/* For UIH packets + * Both stations set the P-bit to 0 + * If credit based flow control is used, If P/F is 1 then one credit byte + * will be there after control in the frame else no credit byte. + */ +#define BT_RFCOMM_PF_UIH 0 +#define BT_RFCOMM_PF_UIH_CREDIT 1 +#define BT_RFCOMM_PF_UIH_NO_CREDIT 0 + +#define BT_RFCOMM_PN_CFC_CMD 0xf0 +#define BT_RFCOMM_PN_CFC_RESP 0xe0 + +/* Initialize RFCOMM signal layer */ +void bt_rfcomm_init(void); diff --git a/kernel/protocols/bluetooth/host/smp.c b/kernel/protocols/bluetooth/host/smp.c new file mode 100644 index 0000000000..f376817591 --- /dev/null +++ b/kernel/protocols/bluetooth/host/smp.c @@ -0,0 +1,4516 @@ +/** + * @file smp.c + * Security Manager Protocol implementation + */ + +/* + * Copyright (c) 2015-2016 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_SMP) +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "hci_core.h" +#include "ecc.h" +#include "keys.h" +#include "conn_internal.h" +#include "l2cap_internal.h" +#include "smp.h" + +#define SMP_TIMEOUT K_SECONDS(30) + +#if defined(CONFIG_BLUETOOTH_SIGNING) +#define SIGN_DIST BT_SMP_DIST_SIGN +#else +#define SIGN_DIST 0 +#endif + +#if defined(CONFIG_BLUETOOTH_PRIVACY) +#define ID_DIST BT_SMP_DIST_ID_KEY +#else +#define ID_DIST 0 +#endif + +#if defined(CONFIG_BLUETOOTH_BREDR) +#define LINK_DIST BT_SMP_DIST_LINK_KEY +#else +#define LINK_DIST 0 +#endif + +#define RECV_KEYS (BT_SMP_DIST_ENC_KEY | BT_SMP_DIST_ID_KEY | SIGN_DIST |\ + LINK_DIST) +#define SEND_KEYS (BT_SMP_DIST_ENC_KEY | ID_DIST | SIGN_DIST | LINK_DIST) + +#define RECV_KEYS_SC (RECV_KEYS & ~(BT_SMP_DIST_ENC_KEY)) +#define SEND_KEYS_SC (SEND_KEYS & ~(BT_SMP_DIST_ENC_KEY)) + +#define BR_RECV_KEYS_SC (RECV_KEYS & ~(LINK_DIST)) +#define BR_SEND_KEYS_SC (SEND_KEYS & ~(LINK_DIST)) + +#define BT_SMP_AUTH_MASK 0x07 + +#if defined(CONFIG_BLUETOOTH_BREDR) +#define BT_SMP_AUTH_MASK_SC 0x2f +#define BT_SMP_AUTH_DEFAULT (BT_SMP_AUTH_BONDING | BT_SMP_AUTH_SC |\ + BT_SMP_AUTH_CT2) +#else +#define BT_SMP_AUTH_MASK_SC 0x0f +#define BT_SMP_AUTH_DEFAULT (BT_SMP_AUTH_BONDING | BT_SMP_AUTH_SC) +#endif + +enum pairing_method { + JUST_WORKS, /* JustWorks pairing */ + PASSKEY_INPUT, /* Passkey Entry input */ + PASSKEY_DISPLAY, /* Passkey Entry display */ + PASSKEY_CONFIRM, /* Passkey confirm */ + PASSKEY_ROLE, /* Passkey Entry depends on role */ +}; + +enum { + SMP_FLAG_CFM_DELAYED, /* if confirm should be send when TK is valid */ + SMP_FLAG_ENC_PENDING, /* if waiting for an encryption change event */ + SMP_FLAG_KEYS_DISTR, /* if keys distribution phase is in progress */ + SMP_FLAG_PAIRING, /* if pairing is in progress */ + SMP_FLAG_TIMEOUT, /* if SMP timeout occurred */ + SMP_FLAG_SC, /* if LE Secure Connections is used */ + SMP_FLAG_PKEY_SEND, /* if should send Public Key when available */ + SMP_FLAG_DHKEY_PENDING, /* if waiting for local DHKey */ + SMP_FLAG_DHKEY_SEND, /* if should generate and send DHKey Check */ + SMP_FLAG_USER, /* if waiting for user input */ + SMP_FLAG_BOND, /* if bonding */ + SMP_FLAG_SC_DEBUG_KEY, /* if Secure Connection are using debug key */ + SMP_FLAG_SEC_REQ, /* if Security Request was sent/received */ + SMP_FLAG_DHCHECK_WAIT, /* if waiting for remote DHCheck (as slave) */ + SMP_FLAG_DERIVE_LK, /* if Link Key should be derived */ + SMP_FLAG_BR_CONNECTED, /* if BR/EDR channel is connected */ + SMP_FLAG_BR_PAIR, /* if should start BR/EDR pairing */ + SMP_FLAG_CT2, /* if should use H7 for keys derivation */ + + /* Total number of flags - must be at the end */ + SMP_NUM_FLAGS, +}; + +/* SMP channel specific context */ +struct bt_smp { + /* The channel this context is associated with */ + struct bt_l2cap_le_chan chan; + + /* Commands that remote is allowed to send */ + atomic_t allowed_cmds; + + /* Flags for SMP state machine */ + ATOMIC_DEFINE(flags, SMP_NUM_FLAGS); + + /* Type of method used for pairing */ + uint8_t method; + + /* Pairing Request PDU */ + uint8_t preq[7]; + + /* Pairing Response PDU */ + uint8_t prsp[7]; + + /* Pairing Confirm PDU */ + uint8_t pcnf[16]; + + /* Local random number */ + uint8_t prnd[16]; + + /* Remote random number */ + uint8_t rrnd[16]; + + /* Temporary key */ + uint8_t tk[16]; + + /* Remote Public Key for LE SC */ + uint8_t pkey[64]; + + /* DHKey */ + uint8_t dhkey[32]; + + /* Remote DHKey check */ + uint8_t e[16]; + + /* MacKey */ + uint8_t mackey[16]; + + /* LE SC passkey */ + uint32_t passkey; + + /* LE SC passkey round */ + uint8_t passkey_round; + + /* Local key distribution */ + uint8_t local_dist; + + /* Remote key distribution */ + uint8_t remote_dist; + + /* Delayed work for timeout handling */ + struct k_delayed_work work; +}; + +#if !defined(CONFIG_BLUETOOTH_SMP_SC_ONLY) +/* based on table 2.8 Core Spec 2.3.5.1 Vol. 3 Part H */ +static const uint8_t gen_method_legacy[5 /* remote */][5 /* local */] = { + { JUST_WORKS, JUST_WORKS, PASSKEY_INPUT, JUST_WORKS, PASSKEY_INPUT }, + { JUST_WORKS, JUST_WORKS, PASSKEY_INPUT, JUST_WORKS, PASSKEY_INPUT }, + { PASSKEY_DISPLAY, PASSKEY_DISPLAY, PASSKEY_INPUT, JUST_WORKS, + PASSKEY_DISPLAY }, + { JUST_WORKS, JUST_WORKS, JUST_WORKS, JUST_WORKS, JUST_WORKS }, + { PASSKEY_DISPLAY, PASSKEY_DISPLAY, PASSKEY_INPUT, JUST_WORKS, + PASSKEY_ROLE }, +}; +#endif /* CONFIG_BLUETOOTH_SMP_SC_ONLY */ + +/* based on table 2.8 Core Spec 2.3.5.1 Vol. 3 Part H */ +static const uint8_t gen_method_sc[5 /* remote */][5 /* local */] = { + { JUST_WORKS, JUST_WORKS, PASSKEY_INPUT, JUST_WORKS, PASSKEY_INPUT }, + { JUST_WORKS, PASSKEY_CONFIRM, PASSKEY_INPUT, JUST_WORKS, + PASSKEY_CONFIRM }, + { PASSKEY_DISPLAY, PASSKEY_DISPLAY, PASSKEY_INPUT, JUST_WORKS, + PASSKEY_DISPLAY }, + { JUST_WORKS, JUST_WORKS, JUST_WORKS, JUST_WORKS, JUST_WORKS }, + { PASSKEY_DISPLAY, PASSKEY_CONFIRM, PASSKEY_INPUT, JUST_WORKS, + PASSKEY_CONFIRM }, +}; + +static const uint8_t sc_debug_public_key[64] = { + 0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc, 0xdb, 0xfd, 0xf4, 0xac, + 0x11, 0x91, 0xf4, 0xef, 0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e, + 0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20, 0x8b, 0xd2, 0x89, 0x15, + 0xd0, 0x8e, 0x1c, 0x74, 0x24, 0x30, 0xed, 0x8f, 0xc2, 0x45, 0x63, 0x76, + 0x5c, 0x15, 0x52, 0x5a, 0xbf, 0x9a, 0x32, 0x63, 0x6d, 0xeb, 0x2a, 0x65, + 0x49, 0x9c, 0x80, 0xdc +}; + +#if defined(CONFIG_BLUETOOTH_BREDR) +/* SMP over BR/EDR channel specific context */ +struct bt_smp_br { + /* The channel this context is associated with */ + struct bt_l2cap_br_chan chan; + + /* Commands that remote is allowed to send */ + atomic_t allowed_cmds; + + /* Flags for SMP state machine */ + ATOMIC_DEFINE(flags, SMP_NUM_FLAGS); + + /* Local key distribution */ + uint8_t local_dist; + + /* Remote key distribution */ + uint8_t remote_dist; + + /* Encryption Key Size used for connection */ + uint8_t enc_key_size; + + /* Delayed work for timeout handling */ + struct k_delayed_work work; +}; + +static struct bt_smp_br bt_smp_br_pool[CONFIG_BLUETOOTH_MAX_CONN]; +#endif /* CONFIG_BLUETOOTH_BREDR */ + +static struct bt_smp bt_smp_pool[CONFIG_BLUETOOTH_MAX_CONN]; +static bool sc_supported; +static bool sc_local_pkey_valid; +static uint8_t sc_public_key[64]; + +static uint8_t get_io_capa(void) +{ + if (!bt_auth) { + return BT_SMP_IO_NO_INPUT_OUTPUT; + } + + /* Passkey Confirmation is valid only for LE SC */ + if (bt_auth->passkey_display && bt_auth->passkey_entry && + (bt_auth->passkey_confirm || !sc_supported)) { + return BT_SMP_IO_KEYBOARD_DISPLAY; + } + + /* DisplayYesNo is useful only for LE SC */ + if (sc_supported && bt_auth->passkey_display && + bt_auth->passkey_confirm) { + return BT_SMP_IO_DISPLAY_YESNO; + } + + if (bt_auth->passkey_entry) { + return BT_SMP_IO_KEYBOARD_ONLY; + } + + if (bt_auth->passkey_display) { + return BT_SMP_IO_DISPLAY_ONLY; + } + + return BT_SMP_IO_NO_INPUT_OUTPUT; +} + +static uint8_t get_pair_method(struct bt_smp *smp, uint8_t remote_io) +{ + struct bt_smp_pairing *req, *rsp; + + if (remote_io > BT_SMP_IO_KEYBOARD_DISPLAY) + return JUST_WORKS; + + req = (struct bt_smp_pairing *)&smp->preq[1]; + rsp = (struct bt_smp_pairing *)&smp->prsp[1]; + + /* if none side requires MITM use JustWorks */ + if (!((req->auth_req | rsp->auth_req) & BT_SMP_AUTH_MITM)) { + return JUST_WORKS; + } + + return gen_method_sc[remote_io][get_io_capa()]; +} + +static int le_encrypt(const uint8_t key[16], const uint8_t plaintext[16], + uint8_t enc_data[16]) +{ + struct tc_aes_key_sched_struct s; + uint8_t tmp[16]; + + BT_DBG("key %s plaintext %s", bt_hex(key, 16), bt_hex(plaintext, 16)); + + sys_memcpy_swap(tmp, key, 16); + + if (tc_aes128_set_encrypt_key(&s, tmp) == TC_CRYPTO_FAIL) { + return -EINVAL; + } + + sys_memcpy_swap(tmp, plaintext, 16); + + if (tc_aes_encrypt(enc_data, tmp, &s) == TC_CRYPTO_FAIL) { + return -EINVAL; + } + + sys_mem_swap(enc_data, 16); + + BT_DBG("enc_data %s", bt_hex(enc_data, 16)); + + return 0; +} + +static struct net_buf *smp_create_pdu(struct bt_conn *conn, uint8_t op, + size_t len) +{ + struct bt_smp_hdr *hdr; + struct net_buf *buf; + + buf = bt_l2cap_create_pdu(NULL, 0); + /* NULL is not a possible return due to K_FOREVER */ + + hdr = net_buf_add(buf, sizeof(*hdr)); + hdr->code = op; + + return buf; +} + +static int smp_ah(const uint8_t irk[16], const uint8_t r[3], uint8_t out[3]) +{ + uint8_t res[16]; + int err; + + BT_DBG("irk %s, r %s", bt_hex(irk, 16), bt_hex(r, 3)); + + /* r' = padding || r */ + memcpy(res, r, 3); + memset(res + 3, 0, 13); + + err = le_encrypt(irk, res, res); + if (err) { + return err; + } + + /* The output of the random address function ah is: + * ah(h, r) = e(k, r') mod 2^24 + * The output of the security function e is then truncated to 24 bits + * by taking the least significant 24 bits of the output of e as the + * result of ah. + */ + memcpy(out, res, 3); + + return 0; +} + +/* Cypher based Message Authentication Code (CMAC) with AES 128 bit + * + * Input : key ( 128-bit key ) + * : in ( message to be authenticated ) + * : len ( length of the message in octets ) + * Output : out ( message authentication code ) + */ +static int bt_smp_aes_cmac(const uint8_t *key, const uint8_t *in, size_t len, + uint8_t *out) +{ + struct tc_aes_key_sched_struct sched; + struct tc_cmac_struct state; + + if (tc_cmac_setup(&state, key, &sched) == TC_CRYPTO_FAIL) { + return -EIO; + } + + if (tc_cmac_update(&state, in, len) == TC_CRYPTO_FAIL) { + return -EIO; + } + + if (tc_cmac_final(out, &state) == TC_CRYPTO_FAIL) { + return -EIO; + } + + return 0; +} + +static int smp_f4(const uint8_t *u, const uint8_t *v, const uint8_t *x, + uint8_t z, uint8_t res[16]) +{ + uint8_t xs[16]; + uint8_t m[65]; + int err; + + BT_DBG("u %s", bt_hex(u, 32)); + BT_DBG("v %s", bt_hex(v, 32)); + BT_DBG("x %s z 0x%x", bt_hex(x, 16), z); + + /* + * U, V and Z are concatenated and used as input m to the function + * AES-CMAC and X is used as the key k. + * + * Core Spec 4.2 Vol 3 Part H 2.2.5 + * + * note: + * bt_smp_aes_cmac uses BE data and smp_f4 accept LE so we swap + */ + sys_memcpy_swap(m, u, 32); + sys_memcpy_swap(m + 32, v, 32); + m[64] = z; + + sys_memcpy_swap(xs, x, 16); + + err = bt_smp_aes_cmac(xs, m, sizeof(m), res); + if (err) { + return err; + } + + sys_mem_swap(res, 16); + + BT_DBG("res %s", bt_hex(res, 16)); + + return err; +} + +static int smp_f5(const uint8_t *w, const uint8_t *n1, const uint8_t *n2, + const bt_addr_le_t *a1, const bt_addr_le_t *a2, uint8_t *mackey, + uint8_t *ltk) +{ + static const uint8_t salt[16] = { 0x6c, 0x88, 0x83, 0x91, 0xaa, 0xf5, + 0xa5, 0x38, 0x60, 0x37, 0x0b, 0xdb, + 0x5a, 0x60, 0x83, 0xbe }; + uint8_t m[53] = { 0x00, /* counter */ + 0x62, 0x74, 0x6c, 0x65, /* keyID */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*n1*/ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*2*/ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a1 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a2 */ + 0x01, 0x00 /* length */ }; + uint8_t t[16], ws[32]; + int err; + + BT_DBG("w %s", bt_hex(w, 32)); + BT_DBG("n1 %s n2 %s", bt_hex(n1, 16), bt_hex(n2, 16)); + + sys_memcpy_swap(ws, w, 32); + + err = bt_smp_aes_cmac(salt, ws, 32, t); + if (err) { + return err; + } + + BT_DBG("t %s", bt_hex(t, 16)); + + sys_memcpy_swap(m + 5, n1, 16); + sys_memcpy_swap(m + 21, n2, 16); + m[37] = a1->type; + sys_memcpy_swap(m + 38, a1->a.val, 6); + m[44] = a2->type; + sys_memcpy_swap(m + 45, a2->a.val, 6); + + err = bt_smp_aes_cmac(t, m, sizeof(m), mackey); + if (err) { + return err; + } + + BT_DBG("mackey %1s", bt_hex(mackey, 16)); + + sys_mem_swap(mackey, 16); + + /* counter for ltk is 1 */ + m[0] = 0x01; + + err = bt_smp_aes_cmac(t, m, sizeof(m), ltk); + if (err) { + return err; + } + + BT_DBG("ltk %s", bt_hex(ltk, 16)); + + sys_mem_swap(ltk, 16); + + return 0; +} + +static int smp_f6(const uint8_t *w, const uint8_t *n1, const uint8_t *n2, + const uint8_t *r, const uint8_t *iocap, const bt_addr_le_t *a1, + const bt_addr_le_t *a2, uint8_t *check) +{ + uint8_t ws[16]; + uint8_t m[65]; + int err; + + BT_DBG("w %s", bt_hex(w, 16)); + BT_DBG("n1 %s n2 %s", bt_hex(n1, 16), bt_hex(n2, 16)); + BT_DBG("r %s io_cap %s", bt_hex(r, 16), bt_hex(iocap, 3)); + BT_DBG("a1 %s a2 %s", bt_hex(a1, 7), bt_hex(a2, 7)); + + sys_memcpy_swap(m, n1, 16); + sys_memcpy_swap(m + 16, n2, 16); + sys_memcpy_swap(m + 32, r, 16); + sys_memcpy_swap(m + 48, iocap, 3); + + m[51] = a1->type; + memcpy(m + 52, a1->a.val, 6); + sys_memcpy_swap(m + 52, a1->a.val, 6); + + m[58] = a2->type; + memcpy(m + 59, a2->a.val, 6); + sys_memcpy_swap(m + 59, a2->a.val, 6); + + sys_memcpy_swap(ws, w, 16); + + err = bt_smp_aes_cmac(ws, m, sizeof(m), check); + if (err) { + return err; + } + + BT_DBG("res %s", bt_hex(check, 16)); + + sys_mem_swap(check, 16); + + return 0; +} + +static int smp_g2(const uint8_t u[32], const uint8_t v[32], + const uint8_t x[16], const uint8_t y[16], uint32_t *passkey) +{ + uint8_t m[80], xs[16]; + int err; + + BT_DBG("u %s", bt_hex(u, 32)); + BT_DBG("v %s", bt_hex(v, 32)); + BT_DBG("x %s y %s", bt_hex(x, 16), bt_hex(y, 16)); + + sys_memcpy_swap(m, u, 32); + sys_memcpy_swap(m + 32, v, 32); + sys_memcpy_swap(m + 64, y, 16); + + sys_memcpy_swap(xs, x, 16); + + /* reuse xs (key) as buffer for result */ + err = bt_smp_aes_cmac(xs, m, sizeof(m), xs); + if (err) { + return err; + } + BT_DBG("res %s", bt_hex(xs, 16)); + + memcpy(passkey, xs + 12, 4); + *passkey = sys_be32_to_cpu(*passkey) % 1000000; + + BT_DBG("passkey %u", *passkey); + + return 0; +} + +static uint8_t get_encryption_key_size(struct bt_smp *smp) +{ + struct bt_smp_pairing *req, *rsp; + + req = (struct bt_smp_pairing *)&smp->preq[1]; + rsp = (struct bt_smp_pairing *)&smp->prsp[1]; + + /* + * The smaller value of the initiating and responding devices maximum + * encryption key length parameters shall be used as the encryption key + * size. + */ + return min(req->max_key_size, rsp->max_key_size); +} + +#if defined(CONFIG_BLUETOOTH_BREDR) +static int smp_h6(const uint8_t w[16], const uint8_t key_id[4], uint8_t res[16]) +{ + uint8_t ws[16]; + uint8_t key_id_s[4]; + int err; + + BT_DBG("w %s", bt_hex(w, 16)); + BT_DBG("key_id %s", bt_hex(key_id, 4)); + + sys_memcpy_swap(ws, w, 16); + sys_memcpy_swap(key_id_s, key_id, 4); + + err = bt_smp_aes_cmac(ws, key_id_s, 4, res); + if (err) { + return err; + } + + BT_DBG("res %s", bt_hex(res, 16)); + + sys_mem_swap(res, 16); + + return 0; +} + +static int smp_h7(const uint8_t salt[16], const uint8_t w[16], uint8_t res[16]) +{ + uint8_t ws[16]; + uint8_t salt_s[16]; + int err; + + BT_DBG("w %s", bt_hex(w, 16)); + BT_DBG("salt %s", bt_hex(salt, 16)); + + sys_memcpy_swap(ws, w, 16); + sys_memcpy_swap(salt_s, salt, 16); + + err = bt_smp_aes_cmac(salt_s, ws, 16, res); + if (err) { + return err; + } + + BT_DBG("res %s", bt_hex(res, 16)); + + sys_mem_swap(res, 16); + + return 0; +} + +static void sc_derive_link_key(struct bt_smp *smp) +{ + /* constants as specified in Core Spec Vol.3 Part H 2.4.2.4 */ + static const uint8_t lebr[4] = { 0x72, 0x62, 0x65, 0x6c }; + struct bt_conn *conn = smp->chan.chan.conn; + struct bt_keys_link_key *link_key; + uint8_t ilk[16]; + + BT_DBG(""); + + /* TODO handle errors? */ + + /* + * At this point remote device identity is known so we can use + * destination address here + */ + link_key = bt_keys_get_link_key(&conn->le.dst.a); + if (!link_key) { + return; + } + + if (atomic_test_bit(smp->flags, SMP_FLAG_CT2)) { + /* constants as specified in Core Spec Vol.3 Part H 2.4.2.4 */ + static const uint8_t salt[16] = { 0x31, 0x70, 0x6d, 0x74, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 }; + + if (smp_h7(salt, conn->le.keys->ltk.val, ilk)) { + bt_keys_link_key_clear(link_key); + return; + } + } else { + /* constants as specified in Core Spec Vol.3 Part H 2.4.2.4 */ + static const uint8_t tmp1[4] = { 0x31, 0x70, 0x6d, 0x74 }; + + if (smp_h6(conn->le.keys->ltk.val, tmp1, ilk)) { + bt_keys_link_key_clear(link_key); + return; + } + } + + if (smp_h6(ilk, lebr, link_key->val)) { + bt_keys_link_key_clear(link_key); + } + + atomic_set_bit(link_key->flags, BT_LINK_KEY_SC); + + if (atomic_test_bit(conn->le.keys->flags, BT_KEYS_AUTHENTICATED)) { + atomic_set_bit(link_key->flags, BT_LINK_KEY_AUTHENTICATED); + } else { + atomic_clear_bit(link_key->flags, BT_LINK_KEY_AUTHENTICATED); + } +} + +static void smp_br_reset(struct bt_smp_br *smp) +{ + k_delayed_work_cancel(&smp->work); + + atomic_set(smp->flags, 0); + atomic_set(&smp->allowed_cmds, 0); + + atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_PAIRING_REQ); +} + +static void smp_pairing_br_complete(struct bt_smp_br *smp, uint8_t status) +{ + BT_DBG("status 0x%x", status); + + if (status) { + struct bt_conn *conn = smp->chan.chan.conn; + struct bt_keys *keys; + bt_addr_le_t addr; + + /* + * For dualmode devices LE address is same as BR/EDR address + * and is of public type. + */ + bt_addr_copy(&addr.a, &conn->br.dst); + addr.type = BT_ADDR_LE_PUBLIC; + + keys = bt_keys_find_addr(&addr); + if (keys) { + bt_keys_clear(keys); + } + } + + smp_br_reset(smp); +} + +static void smp_br_timeout(struct k_work *work) +{ + struct bt_smp_br *smp = CONTAINER_OF(work, struct bt_smp_br, work); + + BT_ERR("SMP Timeout"); + + smp_pairing_br_complete(smp, BT_SMP_ERR_UNSPECIFIED); + atomic_set_bit(smp->flags, SMP_FLAG_TIMEOUT); +} + +static void smp_br_send(struct bt_smp_br *smp, struct net_buf *buf) +{ + bt_l2cap_send(smp->chan.chan.conn, BT_L2CAP_CID_BR_SMP, buf); + k_delayed_work_submit(&smp->work, SMP_TIMEOUT); +} + +static void bt_smp_br_connected(struct bt_l2cap_chan *chan) +{ + struct bt_smp_br *smp = CONTAINER_OF(chan, struct bt_smp_br, chan); + + BT_DBG("chan %p cid 0x%04x", chan, + CONTAINER_OF(chan, struct bt_l2cap_br_chan, chan)->tx.cid); + + atomic_set_bit(smp->flags, SMP_FLAG_BR_CONNECTED); + + /* + * if this flag is set it means pairing was requested before channel + * was connected + */ + if (atomic_test_bit(smp->flags, SMP_FLAG_BR_PAIR)) { + bt_smp_br_send_pairing_req(chan->conn); + } +} + +static void bt_smp_br_disconnected(struct bt_l2cap_chan *chan) +{ + struct bt_smp_br *smp = CONTAINER_OF(chan, struct bt_smp_br, chan); + + BT_DBG("chan %p cid 0x%04x", chan, + CONTAINER_OF(chan, struct bt_l2cap_br_chan, chan)->tx.cid); + + k_delayed_work_cancel(&smp->work); + + memset(smp, 0, sizeof(*smp)); +} + +static void smp_br_init(struct bt_smp_br *smp) +{ + /* Initialize SMP context without clearing L2CAP channel context */ + memset((uint8_t *)smp + sizeof(smp->chan), 0, + sizeof(*smp) - (sizeof(smp->chan) + sizeof(smp->work))); + + atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_PAIRING_FAIL); +} + +static void smp_br_derive_ltk(struct bt_smp_br *smp) +{ + /* constants as specified in Core Spec Vol.3 Part H 2.4.2.5 */ + static const uint8_t brle[4] = { 0x65, 0x6c, 0x72, 0x62 }; + struct bt_conn *conn = smp->chan.chan.conn; + struct bt_keys_link_key *link_key = conn->br.link_key; + struct bt_keys *keys; + bt_addr_le_t addr; + uint8_t ilk[16]; + + BT_DBG(""); + + if (!link_key) { + return; + } + + if (IS_ENABLED(CONFIG_BLUETOOTH_SMP_FORCE_BREDR) && + conn->encrypt != 0x02) { + BT_WARN("Using P192 Link Key for P256 LTK derivation"); + } + + /* + * For dualmode devices LE address is same as BR/EDR address and is of + * public type. + */ + bt_addr_copy(&addr.a, &conn->br.dst); + addr.type = BT_ADDR_LE_PUBLIC; + + keys = bt_keys_get_type(BT_KEYS_LTK_P256, &addr); + if (!keys) { + BT_ERR("No keys space for %s", bt_addr_le_str(&addr)); + return; + } + + if (atomic_test_bit(smp->flags, SMP_FLAG_CT2)) { + /* constants as specified in Core Spec Vol.3 Part H 2.4.2.5 */ + static const uint8_t salt[16] = { 0x32, 0x70, 0x6d, 0x74, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 }; + + if (smp_h7(salt, link_key->val, ilk)) { + bt_keys_link_key_clear(link_key); + return; + } + } else { + /* constants as specified in Core Spec Vol.3 Part H 2.4.2.5 */ + static const uint8_t tmp2[4] = { 0x32, 0x70, 0x6d, 0x74 }; + + if (smp_h6(link_key->val, tmp2, ilk)) { + bt_keys_clear(keys); + return; + } + } + + if (smp_h6(ilk, brle, keys->ltk.val)) { + bt_keys_clear(keys); + return; + } + + keys->ltk.ediv = 0; + keys->ltk.rand = 0; + keys->enc_size = smp->enc_key_size; + + if (atomic_test_bit(link_key->flags, BT_LINK_KEY_AUTHENTICATED)) { + atomic_set_bit(keys->flags, BT_KEYS_AUTHENTICATED); + } else { + atomic_clear_bit(keys->flags, BT_KEYS_AUTHENTICATED); + } + + BT_DBG("LTK derived from LinkKey"); +} + +static void smp_br_distribute_keys(struct bt_smp_br *smp) +{ + struct bt_conn *conn = smp->chan.chan.conn; + struct bt_keys *keys; + bt_addr_le_t addr; + + /* + * For dualmode devices LE address is same as BR/EDR address and is of + * public type. + */ + bt_addr_copy(&addr.a, &conn->br.dst); + addr.type = BT_ADDR_LE_PUBLIC; + + keys = bt_keys_get_addr(&addr); + if (!keys) { + BT_ERR("No keys space for %s", bt_addr_le_str(&addr)); + return; + } + +#if defined(CONFIG_BLUETOOTH_PRIVACY) + if (smp->local_dist & BT_SMP_DIST_ID_KEY) { + struct bt_smp_ident_info *id_info; + struct bt_smp_ident_addr_info *id_addr_info; + struct net_buf *buf; + + smp->local_dist &= ~BT_SMP_DIST_ID_KEY; + + buf = smp_create_pdu(conn, BT_SMP_CMD_IDENT_INFO, + sizeof(*id_info)); + if (!buf) { + BT_ERR("Unable to allocate Ident Info buffer"); + return; + } + + id_info = net_buf_add(buf, sizeof(*id_info)); + memcpy(id_info->irk, bt_dev.irk, 16); + + smp_br_send(smp, buf); + + buf = smp_create_pdu(conn, BT_SMP_CMD_IDENT_ADDR_INFO, + sizeof(*id_addr_info)); + if (!buf) { + BT_ERR("Unable to allocate Ident Addr Info buffer"); + return; + } + + id_addr_info = net_buf_add(buf, sizeof(*id_addr_info)); + bt_addr_le_copy(&id_addr_info->addr, &bt_dev.id_addr); + + smp_br_send(smp, buf); + } +#endif /* CONFIG_BLUETOOTH_PRIVACY */ + +#if defined(CONFIG_BLUETOOTH_SIGNING) + if (smp->local_dist & BT_SMP_DIST_SIGN) { + struct bt_smp_signing_info *info; + struct net_buf *buf; + + smp->local_dist &= ~BT_SMP_DIST_SIGN; + + buf = smp_create_pdu(conn, BT_SMP_CMD_SIGNING_INFO, + sizeof(*info)); + if (!buf) { + BT_ERR("Unable to allocate Signing Info buffer"); + return; + } + + info = net_buf_add(buf, sizeof(*info)); + + bt_rand(info->csrk, sizeof(info->csrk)); + + if (atomic_test_bit(smp->flags, SMP_FLAG_BOND)) { + bt_keys_add_type(keys, BT_KEYS_LOCAL_CSRK); + memcpy(keys->local_csrk.val, info->csrk, 16); + keys->local_csrk.cnt = 0; + } + + smp_br_send(smp, buf); + } +#endif /* CONFIG_BLUETOOTH_SIGNING */ +} + +static bool smp_br_pairing_allowed(struct bt_smp_br *smp) +{ + if (smp->chan.chan.conn->encrypt == 0x02) { + return true; + } + + if (IS_ENABLED(CONFIG_BLUETOOTH_SMP_FORCE_BREDR) && + smp->chan.chan.conn->encrypt == 0x01) { + BT_WARN("Allowing BR/EDR SMP with P-192 key"); + return true; + } + + return false; +} + +static uint8_t smp_br_pairing_req(struct bt_smp_br *smp, struct net_buf *buf) +{ + struct bt_smp_pairing *req = (void *)buf->data; + struct bt_conn *conn = smp->chan.chan.conn; + struct bt_smp_pairing *rsp; + struct net_buf *rsp_buf; + uint8_t max_key_size; + + BT_DBG(""); + + /* + * If a Pairing Request is received over the BR/EDR transport when + * either cross-transport key derivation/generation is not supported or + * the BR/EDR transport is not encrypted using a Link Key generated + * using P256, a Pairing Failed shall be sent with the error code + * "Cross-transport Key Derivation/Generation not allowed" (0x0E)." + */ + if (!smp_br_pairing_allowed(smp)) { + return BT_SMP_ERR_CROSS_TRANSP_NOT_ALLOWED; + } + + max_key_size = bt_conn_enc_key_size(conn); + if (!max_key_size) { + return BT_SMP_ERR_UNSPECIFIED; + } + + if (req->max_key_size != max_key_size) { + return BT_SMP_ERR_ENC_KEY_SIZE; + } + + rsp_buf = smp_create_pdu(conn, BT_SMP_CMD_PAIRING_RSP, sizeof(*rsp)); + if (!rsp_buf) { + return BT_SMP_ERR_UNSPECIFIED; + } + + smp_br_init(smp); + smp->enc_key_size = max_key_size; + + /* + * If Secure Connections pairing has been initiated over BR/EDR, the IO + * Capability, OOB data flag and Auth Req fields of the SM Pairing + * Request/Response PDU shall be set to zero on transmission, and + * ignored on reception. + */ + rsp = net_buf_add(rsp_buf, sizeof(*rsp)); + + rsp->auth_req = 0x00; + rsp->io_capability = 0x00; + rsp->oob_flag = 0x00; + rsp->max_key_size = max_key_size; + rsp->init_key_dist = (req->init_key_dist & BR_RECV_KEYS_SC); + rsp->resp_key_dist = (req->resp_key_dist & BR_RECV_KEYS_SC); + + smp->local_dist = rsp->resp_key_dist; + smp->remote_dist = rsp->init_key_dist; + + smp_br_send(smp, rsp_buf); + + atomic_set_bit(smp->flags, SMP_FLAG_PAIRING); + + /* derive LTK if requested and clear distribution bits */ + if ((smp->local_dist & BT_SMP_DIST_ENC_KEY) && + (smp->remote_dist & BT_SMP_DIST_ENC_KEY)) { + smp_br_derive_ltk(smp); + } + smp->local_dist &= ~BT_SMP_DIST_ENC_KEY; + smp->remote_dist &= ~BT_SMP_DIST_ENC_KEY; + + /* BR/EDR acceptor is like LE Slave and distributes keys first */ + smp_br_distribute_keys(smp); + + if (smp->remote_dist & BT_SMP_DIST_ID_KEY) { + atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_IDENT_INFO); + } else if (smp->remote_dist & BT_SMP_DIST_SIGN) { + atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_SIGNING_INFO); + } + + /* if all keys were distributed, pairing is done */ + if (!smp->local_dist && !smp->remote_dist) { + smp_pairing_br_complete(smp, 0); + } + + return 0; +} + +static uint8_t smp_br_pairing_rsp(struct bt_smp_br *smp, struct net_buf *buf) +{ + struct bt_smp_pairing *rsp = (void *)buf->data; + struct bt_conn *conn = smp->chan.chan.conn; + uint8_t max_key_size; + + BT_DBG(""); + + max_key_size = bt_conn_enc_key_size(conn); + if (!max_key_size) { + return BT_SMP_ERR_UNSPECIFIED; + } + + if (rsp->max_key_size != max_key_size) { + return BT_SMP_ERR_ENC_KEY_SIZE; + } + + smp->local_dist &= rsp->init_key_dist; + smp->remote_dist &= rsp->resp_key_dist; + + smp->local_dist &= SEND_KEYS_SC; + smp->remote_dist &= RECV_KEYS_SC; + + /* slave distributes its keys first */ + + if (smp->remote_dist & BT_SMP_DIST_ID_KEY) { + atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_IDENT_INFO); + } else if (smp->remote_dist & BT_SMP_DIST_SIGN) { + atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_SIGNING_INFO); + } + + /* derive LTK if requested and clear distribution bits */ + if ((smp->local_dist & BT_SMP_DIST_ENC_KEY) && + (smp->remote_dist & BT_SMP_DIST_ENC_KEY)) { + smp_br_derive_ltk(smp); + } + smp->local_dist &= ~BT_SMP_DIST_ENC_KEY; + smp->remote_dist &= ~BT_SMP_DIST_ENC_KEY; + + /* Pairing acceptor distributes it's keys first */ + if (smp->remote_dist) { + return 0; + } + + smp_br_distribute_keys(smp); + + /* if all keys were distributed, pairing is done */ + if (!smp->local_dist && !smp->remote_dist) { + smp_pairing_br_complete(smp, 0); + } + + return 0; +} + +static uint8_t smp_br_pairing_failed(struct bt_smp_br *smp, struct net_buf *buf) +{ + struct bt_smp_pairing_fail *req = (void *)buf->data; + + BT_ERR("reason 0x%x", req->reason); + + smp_pairing_br_complete(smp, req->reason); + smp_br_reset(smp); + + /* return no error to avoid sending Pairing Failed in response */ + return 0; +} + +static uint8_t smp_br_ident_info(struct bt_smp_br *smp, struct net_buf *buf) +{ + struct bt_smp_ident_info *req = (void *)buf->data; + struct bt_conn *conn = smp->chan.chan.conn; + struct bt_keys *keys; + bt_addr_le_t addr; + + BT_DBG(""); + + /* TODO should we resolve LE address if matching RPA is connected? */ + + /* + * For dualmode devices LE address is same as BR/EDR address and is of + * public type. + */ + bt_addr_copy(&addr.a, &conn->br.dst); + addr.type = BT_ADDR_LE_PUBLIC; + + keys = bt_keys_get_type(BT_KEYS_IRK, &addr); + if (!keys) { + BT_ERR("Unable to get keys for %s", bt_addr_le_str(&addr)); + return BT_SMP_ERR_UNSPECIFIED; + } + + memcpy(keys->irk.val, req->irk, sizeof(keys->irk.val)); + + atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_IDENT_ADDR_INFO); + + return 0; +} + +static uint8_t smp_br_ident_addr_info(struct bt_smp_br *smp, + struct net_buf *buf) +{ + struct bt_conn *conn = smp->chan.chan.conn; + struct bt_smp_ident_addr_info *req = (void *)buf->data; + bt_addr_le_t addr; + + BT_DBG("identity %s", bt_addr_le_str(&req->addr)); + + /* + * For dual mode device identity address must be same as BR/EDR address + * and be of public type. So if received one doesn't match BR/EDR + * address we fail. + */ + + bt_addr_copy(&addr.a, &conn->br.dst); + addr.type = BT_ADDR_LE_PUBLIC; + + if (bt_addr_le_cmp(&addr, &req->addr)) { + return BT_SMP_ERR_UNSPECIFIED; + } + + smp->remote_dist &= ~BT_SMP_DIST_ID_KEY; + + if (smp->remote_dist & BT_SMP_DIST_SIGN) { + atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_SIGNING_INFO); + } + + if (conn->role == BT_CONN_ROLE_MASTER && !smp->remote_dist) { + smp_br_distribute_keys(smp); + } + + /* if all keys were distributed, pairing is done */ + if (!smp->local_dist && !smp->remote_dist) { + smp_pairing_br_complete(smp, 0); + } + + return 0; +} + +#if defined(CONFIG_BLUETOOTH_SIGNING) +static uint8_t smp_br_signing_info(struct bt_smp_br *smp, struct net_buf *buf) +{ + struct bt_smp_signing_info *req = (void *)buf->data; + struct bt_conn *conn = smp->chan.chan.conn; + struct bt_keys *keys; + bt_addr_le_t addr; + + BT_DBG(""); + + /* + * For dualmode devices LE address is same as BR/EDR address and is of + * public type. + */ + bt_addr_copy(&addr.a, &conn->br.dst); + addr.type = BT_ADDR_LE_PUBLIC; + + keys = bt_keys_get_type(BT_KEYS_REMOTE_CSRK, &addr); + if (!keys) { + BT_ERR("Unable to get keys for %s", bt_addr_le_str(&addr)); + return BT_SMP_ERR_UNSPECIFIED; + } + + memcpy(keys->remote_csrk.val, req->csrk, sizeof(keys->remote_csrk.val)); + + smp->remote_dist &= ~BT_SMP_DIST_SIGN; + + if (conn->role == BT_CONN_ROLE_MASTER && !smp->remote_dist) { + smp_br_distribute_keys(smp); + } + + /* if all keys were distributed, pairing is done */ + if (!smp->local_dist && !smp->remote_dist) { + smp_pairing_br_complete(smp, 0); + } + + return 0; +} +#else +static uint8_t smp_br_signing_info(struct bt_smp_br *smp, struct net_buf *buf) +{ + return BT_SMP_ERR_CMD_NOTSUPP; +} +#endif /* CONFIG_BLUETOOTH_SIGNING */ + +static const struct { + uint8_t (*func)(struct bt_smp_br *smp, struct net_buf *buf); + uint8_t expect_len; +} br_handlers[] = { + { }, /* No op-code defined for 0x00 */ + { smp_br_pairing_req, sizeof(struct bt_smp_pairing) }, + { smp_br_pairing_rsp, sizeof(struct bt_smp_pairing) }, + { }, /* pairing confirm not used over BR/EDR */ + { }, /* pairing random not used over BR/EDR */ + { smp_br_pairing_failed, sizeof(struct bt_smp_pairing_fail) }, + { }, /* encrypt info not used over BR/EDR */ + { }, /* master ident not used over BR/EDR */ + { smp_br_ident_info, sizeof(struct bt_smp_ident_info) }, + { smp_br_ident_addr_info, sizeof(struct bt_smp_ident_addr_info) }, + { smp_br_signing_info, sizeof(struct bt_smp_signing_info) }, + /* security request not used over BR/EDR */ + /* public key not used over BR/EDR */ + /* DHKey check not used over BR/EDR */ +}; + +static int smp_br_error(struct bt_smp_br *smp, uint8_t reason) +{ + struct bt_smp_pairing_fail *rsp; + struct net_buf *buf; + + /* reset context and report */ + smp_br_reset(smp); + + buf = smp_create_pdu(smp->chan.chan.conn, BT_SMP_CMD_PAIRING_FAIL, + sizeof(*rsp)); + if (!buf) { + return -ENOBUFS; + } + + rsp = net_buf_add(buf, sizeof(*rsp)); + rsp->reason = reason; + + /* + * SMP timer is not restarted for PairingFailed so don't use + * smp_br_send + */ + bt_l2cap_send(smp->chan.chan.conn, BT_L2CAP_CID_SMP, buf); + + return 0; +} + +static void bt_smp_br_recv(struct bt_l2cap_chan *chan, struct net_buf *buf) +{ + struct bt_smp_br *smp = CONTAINER_OF(chan, struct bt_smp_br, chan); + struct bt_smp_hdr *hdr = (void *)buf->data; + uint8_t err; + + if (buf->len < sizeof(*hdr)) { + BT_ERR("Too small SMP PDU received"); + return; + } + + BT_DBG("Received SMP code 0x%02x len %u", hdr->code, buf->len); + + net_buf_pull(buf, sizeof(*hdr)); + + /* + * If SMP timeout occurred "no further SMP commands shall be sent over + * the L2CAP Security Manager Channel. A new SM procedure shall only be + * performed when a new physical link has been established." + */ + if (atomic_test_bit(smp->flags, SMP_FLAG_TIMEOUT)) { + BT_WARN("SMP command (code 0x%02x) received after timeout", + hdr->code); + return; + } + + if (hdr->code >= ARRAY_SIZE(br_handlers) || + !br_handlers[hdr->code].func) { + BT_WARN("Unhandled SMP code 0x%02x", hdr->code); + smp_br_error(smp, BT_SMP_ERR_CMD_NOTSUPP); + return; + } + + if (!atomic_test_and_clear_bit(&smp->allowed_cmds, hdr->code)) { + BT_WARN("Unexpected SMP code 0x%02x", hdr->code); + smp_br_error(smp, BT_SMP_ERR_UNSPECIFIED); + return; + } + + if (buf->len != br_handlers[hdr->code].expect_len) { + BT_ERR("Invalid len %u for code 0x%02x", buf->len, hdr->code); + smp_br_error(smp, BT_SMP_ERR_INVALID_PARAMS); + return; + } + + err = br_handlers[hdr->code].func(smp, buf); + if (err) { + smp_br_error(smp, err); + } +} + +static int bt_smp_br_accept(struct bt_conn *conn, struct bt_l2cap_chan **chan) +{ + static struct bt_l2cap_chan_ops ops = { + .connected = bt_smp_br_connected, + .disconnected = bt_smp_br_disconnected, + .recv = bt_smp_br_recv, + }; + int i; + + BT_DBG("conn %p handle %u", conn, conn->handle); + + for (i = 0; i < ARRAY_SIZE(bt_smp_pool); i++) { + struct bt_smp_br *smp = &bt_smp_br_pool[i]; + + if (smp->chan.chan.conn) { + continue; + } + + smp->chan.chan.ops = &ops; + + *chan = &smp->chan.chan; + + k_delayed_work_init(&smp->work, smp_br_timeout); + smp_br_reset(smp); + + return 0; + } + + BT_ERR("No available SMP context for conn %p", conn); + + return -ENOMEM; +} + +static struct bt_smp_br *smp_br_chan_get(struct bt_conn *conn) +{ + struct bt_l2cap_chan *chan; + + chan = bt_l2cap_br_lookup_rx_cid(conn, BT_L2CAP_CID_BR_SMP); + if (!chan) { + BT_ERR("Unable to find SMP channel"); + return NULL; + } + + return CONTAINER_OF(chan, struct bt_smp_br, chan); +} + +int bt_smp_br_send_pairing_req(struct bt_conn *conn) +{ + struct bt_smp_pairing *req; + struct net_buf *req_buf; + uint8_t max_key_size; + struct bt_smp_br *smp; + + smp = smp_br_chan_get(conn); + if (!smp) { + return -ENOTCONN; + } + + /* SMP Timeout */ + if (atomic_test_bit(smp->flags, SMP_FLAG_TIMEOUT)) { + return -EIO; + } + + /* pairing is in progress */ + if (atomic_test_bit(smp->flags, SMP_FLAG_PAIRING)) { + return -EBUSY; + } + + /* check if we are allowed to start SMP over BR/EDR */ + if (!smp_br_pairing_allowed(smp)) { + return 0; + } + + /* Channel not yet connected, will start pairing once connected */ + if (!atomic_test_bit(smp->flags, SMP_FLAG_BR_CONNECTED)) { + atomic_set_bit(smp->flags, SMP_FLAG_BR_PAIR); + return 0; + } + + max_key_size = bt_conn_enc_key_size(conn); + if (!max_key_size) { + return -EIO; + } + + smp_br_init(smp); + smp->enc_key_size = max_key_size; + + req_buf = smp_create_pdu(conn, BT_SMP_CMD_PAIRING_REQ, sizeof(*req)); + if (!req_buf) { + return -ENOBUFS; + } + + req = net_buf_add(req_buf, sizeof(*req)); + + /* + * If Secure Connections pairing has been initiated over BR/EDR, the IO + * Capability, OOB data flag and Auth Req fields of the SM Pairing + * Request/Response PDU shall be set to zero on transmission, and + * ignored on reception. + */ + + req->auth_req = 0x00; + req->io_capability = 0x00; + req->oob_flag = 0x00; + req->max_key_size = max_key_size; + req->init_key_dist = BR_SEND_KEYS_SC; + req->resp_key_dist = BR_RECV_KEYS_SC; + + smp_br_send(smp, req_buf); + + smp->local_dist = BR_SEND_KEYS_SC; + smp->remote_dist = BR_RECV_KEYS_SC; + + atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_PAIRING_RSP); + + atomic_set_bit(smp->flags, SMP_FLAG_PAIRING); + + return 0; +} + +static bool br_sc_supported(void) +{ + if (IS_ENABLED(CONFIG_BLUETOOTH_SMP_FORCE_BREDR)) { + BT_WARN("Enabling BR/EDR SMP without BR/EDR SC support"); + return true; + } + + return BT_FEAT_SC(bt_dev.features); +} +#endif /* CONFIG_BLUETOOTH_BREDR */ + +static void smp_reset(struct bt_smp *smp) +{ + struct bt_conn *conn = smp->chan.chan.conn; + + k_delayed_work_cancel(&smp->work); + + smp->method = JUST_WORKS; + atomic_set(&smp->allowed_cmds, 0); + atomic_set(smp->flags, 0); + + if (conn->required_sec_level != conn->sec_level) { + /* TODO report error */ + /* reset required security level in case of error */ + conn->required_sec_level = conn->sec_level; + } + + if (IS_ENABLED(CONFIG_BLUETOOTH_CENTRAL) && + conn->role == BT_HCI_ROLE_MASTER) { + atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_SECURITY_REQUEST); + return; + } + + if (IS_ENABLED(CONFIG_BLUETOOTH_PERIPHERAL)) { + atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_PAIRING_REQ); + } +} + +static void smp_pairing_complete(struct bt_smp *smp, uint8_t status) +{ + BT_DBG("status 0x%x", status); + +#if defined(CONFIG_BLUETOOTH_BREDR) + if (!status) { + /* + * Don't derive if Debug Keys are used. + * TODO should we allow this if BR/EDR is already connected? + */ + if (atomic_test_bit(smp->flags, SMP_FLAG_DERIVE_LK) && + !atomic_test_bit(smp->flags, SMP_FLAG_SC_DEBUG_KEY)) { + sc_derive_link_key(smp); + } + } +#endif /* CONFIG_BLUETOOTH_BREDR */ + + smp_reset(smp); +} + +static void smp_timeout(struct k_work *work) +{ + struct bt_smp *smp = CONTAINER_OF(work, struct bt_smp, work); + + BT_ERR("SMP Timeout"); + + /* + * If SMP timeout occurred during key distribution we should assume + * pairing failed and don't store any keys from this pairing. + */ + if (atomic_test_bit(smp->flags, SMP_FLAG_KEYS_DISTR) && + smp->chan.chan.conn->le.keys) { + bt_keys_clear(smp->chan.chan.conn->le.keys); + } + + smp_pairing_complete(smp, BT_SMP_ERR_UNSPECIFIED); + + atomic_set_bit(smp->flags, SMP_FLAG_TIMEOUT); +} + +static void smp_send(struct bt_smp *smp, struct net_buf *buf) +{ + bt_l2cap_send(smp->chan.chan.conn, BT_L2CAP_CID_SMP, buf); + k_delayed_work_submit(&smp->work, SMP_TIMEOUT); +} + +static int smp_error(struct bt_smp *smp, uint8_t reason) +{ + struct bt_smp_pairing_fail *rsp; + struct net_buf *buf; + + /* reset context and report */ + smp_pairing_complete(smp, reason); + + buf = smp_create_pdu(smp->chan.chan.conn, BT_SMP_CMD_PAIRING_FAIL, + sizeof(*rsp)); + if (!buf) { + return -ENOBUFS; + } + + rsp = net_buf_add(buf, sizeof(*rsp)); + rsp->reason = reason; + + /* SMP timer is not restarted for PairingFailed so don't use smp_send */ + bt_l2cap_send(smp->chan.chan.conn, BT_L2CAP_CID_SMP, buf); + + return 0; +} + +static uint8_t smp_send_pairing_random(struct bt_smp *smp) +{ + struct bt_conn *conn = smp->chan.chan.conn; + struct bt_smp_pairing_random *req; + struct net_buf *rsp_buf; + + rsp_buf = smp_create_pdu(conn, BT_SMP_CMD_PAIRING_RANDOM, sizeof(*req)); + if (!rsp_buf) { + return BT_SMP_ERR_UNSPECIFIED; + } + + req = net_buf_add(rsp_buf, sizeof(*req)); + memcpy(req->val, smp->prnd, sizeof(req->val)); + + smp_send(smp, rsp_buf); + + return 0; +} + +#if !defined(CONFIG_BLUETOOTH_SMP_SC_ONLY) +static void xor_128(const uint8_t p[16], const uint8_t q[16], uint8_t r[16]) +{ + size_t len = 16; + + while (len--) { + *r++ = *p++ ^ *q++; + } +} + +static int smp_c1(const uint8_t k[16], const uint8_t r[16], + const uint8_t preq[7], const uint8_t pres[7], + const bt_addr_le_t *ia, const bt_addr_le_t *ra, + uint8_t enc_data[16]) +{ + uint8_t p1[16], p2[16]; + int err; + + BT_DBG("k %s r %s", bt_hex(k, 16), bt_hex(r, 16)); + BT_DBG("ia %s ra %s", bt_addr_le_str(ia), bt_addr_le_str(ra)); + BT_DBG("preq %s pres %s", bt_hex(preq, 7), bt_hex(pres, 7)); + + /* pres, preq, rat and iat are concatenated to generate p1 */ + p1[0] = ia->type; + p1[1] = ra->type; + memcpy(p1 + 2, preq, 7); + memcpy(p1 + 9, pres, 7); + + BT_DBG("p1 %s", bt_hex(p1, 16)); + + /* c1 = e(k, e(k, r XOR p1) XOR p2) */ + + /* Using enc_data as temporary output buffer */ + xor_128(r, p1, enc_data); + + err = le_encrypt(k, enc_data, enc_data); + if (err) { + return err; + } + + /* ra is concatenated with ia and padding to generate p2 */ + memcpy(p2, ra->a.val, 6); + memcpy(p2 + 6, ia->a.val, 6); + memset(p2 + 12, 0, 4); + + BT_DBG("p2 %s", bt_hex(p2, 16)); + + xor_128(enc_data, p2, enc_data); + + return le_encrypt(k, enc_data, enc_data); +} +#endif /* !CONFIG_BLUETOOTH_SMP_SC_ONLY */ + +static uint8_t smp_send_pairing_confirm(struct bt_smp *smp) +{ + struct bt_conn *conn = smp->chan.chan.conn; + struct bt_smp_pairing_confirm *req; + struct net_buf *buf; + uint8_t r; + + switch (smp->method) { + case PASSKEY_CONFIRM: + case JUST_WORKS: + r = 0; + break; + case PASSKEY_DISPLAY: + case PASSKEY_INPUT: + /* + * In the Passkey Entry protocol, the most significant + * bit of Z is set equal to one and the least + * significant bit is made up from one bit of the + * passkey e.g. if the passkey bit is 1, then Z = 0x81 + * and if the passkey bit is 0, then Z = 0x80. + */ + r = (smp->passkey >> smp->passkey_round) & 0x01; + r |= 0x80; + break; + default: + return BT_SMP_ERR_UNSPECIFIED; + } + + buf = smp_create_pdu(conn, BT_SMP_CMD_PAIRING_CONFIRM, sizeof(*req)); + if (!buf) { + return BT_SMP_ERR_UNSPECIFIED; + } + + req = net_buf_add(buf, sizeof(*req)); + + if (smp_f4(sc_public_key, smp->pkey, smp->prnd, r, req->val)) { + net_buf_unref(buf); + return BT_SMP_ERR_UNSPECIFIED; + } + + smp_send(smp, buf); + + atomic_clear_bit(smp->flags, SMP_FLAG_CFM_DELAYED); + + return 0; +} + +#if !defined(CONFIG_BLUETOOTH_SMP_SC_ONLY) +static void legacy_distribute_keys(struct bt_smp *smp) +{ + struct bt_conn *conn = smp->chan.chan.conn; + struct bt_keys *keys = conn->le.keys; + + if (smp->local_dist & BT_SMP_DIST_ENC_KEY) { + struct bt_smp_encrypt_info *info; + struct bt_smp_master_ident *ident; + struct net_buf *buf; + uint8_t key[16]; + uint64_t rand; + uint16_t ediv; + + smp->local_dist &= ~BT_SMP_DIST_ENC_KEY; + + bt_rand(key, sizeof(key)); + bt_rand(&rand, sizeof(rand)); + bt_rand(&ediv, sizeof(ediv)); + + buf = smp_create_pdu(conn, BT_SMP_CMD_ENCRYPT_INFO, + sizeof(*info)); + if (!buf) { + BT_ERR("Unable to allocate Encrypt Info buffer"); + return; + } + + info = net_buf_add(buf, sizeof(*info)); + + /* distributed only enc_size bytes of key */ + memcpy(info->ltk, key, keys->enc_size); + if (keys->enc_size < sizeof(info->ltk)) { + memset(info->ltk + keys->enc_size, 0, + sizeof(info->ltk) - keys->enc_size); + } + + smp_send(smp, buf); + + buf = smp_create_pdu(conn, BT_SMP_CMD_MASTER_IDENT, + sizeof(*ident)); + if (!buf) { + BT_ERR("Unable to allocate Master Ident buffer"); + return; + } + + ident = net_buf_add(buf, sizeof(*ident)); + ident->rand = rand; + ident->ediv = ediv; + + smp_send(smp, buf); + + if (atomic_test_bit(smp->flags, SMP_FLAG_BOND)) { + bt_keys_add_type(keys, BT_KEYS_SLAVE_LTK); + + memcpy(keys->slave_ltk.val, key, + sizeof(keys->slave_ltk.val)); + keys->slave_ltk.rand = rand; + keys->slave_ltk.ediv = ediv; + } + } +} +#endif /* !CONFIG_BLUETOOTH_SMP_SC_ONLY */ + +static void bt_smp_distribute_keys(struct bt_smp *smp) +{ + struct bt_conn *conn = smp->chan.chan.conn; + struct bt_keys *keys = conn->le.keys; + + if (!keys) { + BT_ERR("No keys space for %s", bt_addr_le_str(&conn->le.dst)); + return; + } + +#if !defined(CONFIG_BLUETOOTH_SMP_SC_ONLY) + /* Distribute legacy pairing specific keys */ + if (!atomic_test_bit(smp->flags, SMP_FLAG_SC)) { + legacy_distribute_keys(smp); + } +#endif /* !CONFIG_BLUETOOTH_SMP_SC_ONLY */ + +#if defined(CONFIG_BLUETOOTH_PRIVACY) + if (smp->local_dist & BT_SMP_DIST_ID_KEY) { + struct bt_smp_ident_info *id_info; + struct bt_smp_ident_addr_info *id_addr_info; + struct net_buf *buf; + + smp->local_dist &= ~BT_SMP_DIST_ID_KEY; + + buf = smp_create_pdu(conn, BT_SMP_CMD_IDENT_INFO, + sizeof(*id_info)); + if (!buf) { + BT_ERR("Unable to allocate Ident Info buffer"); + return; + } + + id_info = net_buf_add(buf, sizeof(*id_info)); + memcpy(id_info->irk, bt_dev.irk, 16); + + smp_send(smp, buf); + + buf = smp_create_pdu(conn, BT_SMP_CMD_IDENT_ADDR_INFO, + sizeof(*id_addr_info)); + if (!buf) { + BT_ERR("Unable to allocate Ident Addr Info buffer"); + return; + } + + id_addr_info = net_buf_add(buf, sizeof(*id_addr_info)); + bt_addr_le_copy(&id_addr_info->addr, &bt_dev.id_addr); + + smp_send(smp, buf); + } +#endif /* CONFIG_BLUETOOTH_PRIVACY */ + +#if defined(CONFIG_BLUETOOTH_SIGNING) + if (smp->local_dist & BT_SMP_DIST_SIGN) { + struct bt_smp_signing_info *info; + struct net_buf *buf; + + smp->local_dist &= ~BT_SMP_DIST_SIGN; + + buf = smp_create_pdu(conn, BT_SMP_CMD_SIGNING_INFO, + sizeof(*info)); + if (!buf) { + BT_ERR("Unable to allocate Signing Info buffer"); + return; + } + + info = net_buf_add(buf, sizeof(*info)); + + bt_rand(info->csrk, sizeof(info->csrk)); + + if (atomic_test_bit(smp->flags, SMP_FLAG_BOND)) { + bt_keys_add_type(keys, BT_KEYS_LOCAL_CSRK); + memcpy(keys->local_csrk.val, info->csrk, 16); + keys->local_csrk.cnt = 0; + } + + smp_send(smp, buf); + } +#endif /* CONFIG_BLUETOOTH_SIGNING */ +} + +#if defined(CONFIG_BLUETOOTH_PERIPHERAL) +static uint8_t send_pairing_rsp(struct bt_smp *smp) +{ + struct bt_conn *conn = smp->chan.chan.conn; + struct bt_smp_pairing *rsp; + struct net_buf *rsp_buf; + + rsp_buf = smp_create_pdu(conn, BT_SMP_CMD_PAIRING_RSP, sizeof(*rsp)); + if (!rsp_buf) { + return BT_SMP_ERR_UNSPECIFIED; + } + + rsp = net_buf_add(rsp_buf, sizeof(*rsp)); + memcpy(rsp, smp->prsp + 1, sizeof(*rsp)); + + smp_send(smp, rsp_buf); + + return 0; +} +#endif /* CONFIG_BLUETOOTH_PERIPHERAL */ + +#if !defined(CONFIG_BLUETOOTH_SMP_SC_ONLY) +static int smp_s1(const uint8_t k[16], const uint8_t r1[16], + const uint8_t r2[16], uint8_t out[16]) +{ + /* The most significant 64-bits of r1 are discarded to generate + * r1' and the most significant 64-bits of r2 are discarded to + * generate r2'. + * r1' is concatenated with r2' to generate r' which is used as + * the 128-bit input parameter plaintextData to security function e: + * + * r' = r1' || r2' + */ + memcpy(out, r2, 8); + memcpy(out + 8, r1, 8); + + /* s1(k, r1 , r2) = e(k, r') */ + return le_encrypt(k, out, out); +} + +static uint8_t legacy_get_pair_method(struct bt_smp *smp, uint8_t remote_io) +{ + struct bt_smp_pairing *req, *rsp; + uint8_t method; + + if (remote_io > BT_SMP_IO_KEYBOARD_DISPLAY) + return JUST_WORKS; + + req = (struct bt_smp_pairing *)&smp->preq[1]; + rsp = (struct bt_smp_pairing *)&smp->prsp[1]; + + /* if none side requires MITM use JustWorks */ + if (!((req->auth_req | rsp->auth_req) & BT_SMP_AUTH_MITM)) { + return JUST_WORKS; + } + + method = gen_method_legacy[remote_io][get_io_capa()]; + + /* if both sides have KeyboardDisplay capabilities, initiator displays + * and responder inputs + */ + if (method == PASSKEY_ROLE) { + if (smp->chan.chan.conn->role == BT_HCI_ROLE_MASTER) { + method = PASSKEY_DISPLAY; + } else { + method = PASSKEY_INPUT; + } + } + + return method; +} + +static uint8_t legacy_request_tk(struct bt_smp *smp) +{ + struct bt_conn *conn = smp->chan.chan.conn; + struct bt_keys *keys; + uint32_t passkey; + + /* + * Fail if we have keys that are stronger than keys that will be + * distributed in new pairing. This is to avoid replacing authenticated + * keys with unauthenticated ones. + */ + keys = bt_keys_find_addr(&conn->le.dst); + if (keys && atomic_test_bit(keys->flags, BT_KEYS_AUTHENTICATED) && + smp->method == JUST_WORKS) { + BT_ERR("JustWorks failed, authenticated keys present"); + return BT_SMP_ERR_UNSPECIFIED; + } + + switch (smp->method) { + case PASSKEY_DISPLAY: + if (bt_rand(&passkey, sizeof(passkey))) { + return BT_SMP_ERR_UNSPECIFIED; + } + + passkey %= 1000000; + + bt_auth->passkey_display(conn, passkey); + + passkey = sys_cpu_to_le32(passkey); + memcpy(smp->tk, &passkey, sizeof(passkey)); + + break; + case PASSKEY_INPUT: + atomic_set_bit(smp->flags, SMP_FLAG_USER); + bt_auth->passkey_entry(conn); + break; + case JUST_WORKS: + break; + default: + BT_ERR("Unknown pairing method (%u)", smp->method); + return BT_SMP_ERR_UNSPECIFIED; + } + + return 0; +} + +static uint8_t legacy_send_pairing_confirm(struct bt_smp *smp) +{ + struct bt_conn *conn = smp->chan.chan.conn; + struct bt_smp_pairing_confirm *req; + struct net_buf *buf; + + buf = smp_create_pdu(conn, BT_SMP_CMD_PAIRING_CONFIRM, sizeof(*req)); + if (!buf) { + return BT_SMP_ERR_UNSPECIFIED; + } + + req = net_buf_add(buf, sizeof(*req)); + + if (smp_c1(smp->tk, smp->prnd, smp->preq, smp->prsp, + &conn->le.init_addr, &conn->le.resp_addr, req->val)) { + net_buf_unref(buf); + return BT_SMP_ERR_UNSPECIFIED; + } + + smp_send(smp, buf); + + atomic_clear_bit(smp->flags, SMP_FLAG_CFM_DELAYED); + + return 0; +} + +#if defined(CONFIG_BLUETOOTH_PERIPHERAL) +static uint8_t legacy_pairing_req(struct bt_smp *smp, uint8_t remote_io) +{ + uint8_t ret; + + BT_DBG(""); + + smp->method = legacy_get_pair_method(smp, remote_io); + + /* ask for consent if pairing is not due to sending SecReq*/ + if (smp->method == JUST_WORKS && + !atomic_test_bit(smp->flags, SMP_FLAG_SEC_REQ) && + bt_auth && bt_auth->pairing_confirm) { + atomic_set_bit(smp->flags, SMP_FLAG_USER); + bt_auth->pairing_confirm(smp->chan.chan.conn); + return 0; + } + + ret = send_pairing_rsp(smp); + if (ret) { + return ret; + } + + atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_PAIRING_CONFIRM); + + return legacy_request_tk(smp); +} +#endif /* CONFIG_BLUETOOTH_PERIPHERAL */ + +static uint8_t legacy_pairing_random(struct bt_smp *smp) +{ + struct bt_conn *conn = smp->chan.chan.conn; + uint8_t tmp[16]; + int err; + + BT_DBG(""); + + /* calculate confirmation */ + err = smp_c1(smp->tk, smp->rrnd, smp->preq, smp->prsp, + &conn->le.init_addr, &conn->le.resp_addr, tmp); + if (err) { + return BT_SMP_ERR_UNSPECIFIED; + } + + BT_DBG("pcnf %s cfm %s", bt_hex(smp->pcnf, 16), bt_hex(tmp, 16)); + + if (memcmp(smp->pcnf, tmp, sizeof(smp->pcnf))) { + return BT_SMP_ERR_CONFIRM_FAILED; + } + + if (IS_ENABLED(CONFIG_BLUETOOTH_CENTRAL) && + conn->role == BT_HCI_ROLE_MASTER) { + /* No need to store master STK */ + err = smp_s1(smp->tk, smp->rrnd, smp->prnd, tmp); + if (err) { + return BT_SMP_ERR_UNSPECIFIED; + } + + /* Rand and EDiv are 0 for the STK */ + if (bt_conn_le_start_encryption(conn, 0, 0, tmp, + get_encryption_key_size(smp))) { + BT_ERR("Failed to start encryption"); + return BT_SMP_ERR_UNSPECIFIED; + } + + atomic_set_bit(smp->flags, SMP_FLAG_ENC_PENDING); + + return 0; + } + + if (IS_ENABLED(CONFIG_BLUETOOTH_PERIPHERAL)) { + err = smp_s1(smp->tk, smp->prnd, smp->rrnd, tmp); + if (err) { + return BT_SMP_ERR_UNSPECIFIED; + } + + memcpy(smp->tk, tmp, sizeof(smp->tk)); + BT_DBG("generated STK %s", bt_hex(smp->tk, 16)); + + atomic_set_bit(smp->flags, SMP_FLAG_ENC_PENDING); + + smp_send_pairing_random(smp); + } + + return 0; +} + +static uint8_t legacy_pairing_confirm(struct bt_smp *smp) +{ + BT_DBG(""); + + if (IS_ENABLED(CONFIG_BLUETOOTH_CENTRAL) && + smp->chan.chan.conn->role == BT_HCI_ROLE_MASTER) { + atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_PAIRING_CONFIRM); + return legacy_send_pairing_confirm(smp); + } + + if (IS_ENABLED(CONFIG_BLUETOOTH_PERIPHERAL)) { + if (!atomic_test_bit(smp->flags, SMP_FLAG_USER)) { + atomic_set_bit(&smp->allowed_cmds, + BT_SMP_CMD_PAIRING_RANDOM); + return legacy_send_pairing_confirm(smp); + } + + atomic_set_bit(smp->flags, SMP_FLAG_CFM_DELAYED); + } + + return 0; +} + +static void legacy_passkey_entry(struct bt_smp *smp, unsigned int passkey) +{ + passkey = sys_cpu_to_le32(passkey); + memcpy(smp->tk, &passkey, sizeof(passkey)); + + if (!atomic_test_and_clear_bit(smp->flags, SMP_FLAG_CFM_DELAYED)) { + return; + } + + /* if confirm failed ie. due to invalid passkey, cancel pairing */ + if (legacy_pairing_confirm(smp)) { + smp_error(smp, BT_SMP_ERR_PASSKEY_ENTRY_FAILED); + return; + } + + if (IS_ENABLED(CONFIG_BLUETOOTH_CENTRAL) && + smp->chan.chan.conn->role == BT_HCI_ROLE_MASTER) { + atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_PAIRING_CONFIRM); + return; + } + + if (IS_ENABLED(CONFIG_BLUETOOTH_PERIPHERAL)) { + atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_PAIRING_RANDOM); + } +} + +static uint8_t smp_encrypt_info(struct bt_smp *smp, struct net_buf *buf) +{ + BT_DBG(""); + + if (atomic_test_bit(smp->flags, SMP_FLAG_BOND)) { + struct bt_smp_encrypt_info *req = (void *)buf->data; + struct bt_conn *conn = smp->chan.chan.conn; + struct bt_keys *keys; + + keys = bt_keys_get_type(BT_KEYS_LTK, &conn->le.dst); + if (!keys) { + BT_ERR("Unable to get keys for %s", + bt_addr_le_str(&conn->le.dst)); + return BT_SMP_ERR_UNSPECIFIED; + } + + memcpy(keys->ltk.val, req->ltk, 16); + } + + atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_MASTER_IDENT); + + return 0; +} + +static uint8_t smp_master_ident(struct bt_smp *smp, struct net_buf *buf) +{ + struct bt_conn *conn = smp->chan.chan.conn; + + BT_DBG(""); + + if (atomic_test_bit(smp->flags, SMP_FLAG_BOND)) { + struct bt_smp_master_ident *req = (void *)buf->data; + struct bt_keys *keys; + + keys = bt_keys_get_type(BT_KEYS_LTK, &conn->le.dst); + if (!keys) { + BT_ERR("Unable to get keys for %s", + bt_addr_le_str(&conn->le.dst)); + return BT_SMP_ERR_UNSPECIFIED; + } + + keys->ltk.ediv = req->ediv; + keys->ltk.rand = req->rand; + + smp->remote_dist &= ~BT_SMP_DIST_ENC_KEY; + } + + if (smp->remote_dist & BT_SMP_DIST_ID_KEY) { + atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_IDENT_INFO); + } else if (smp->remote_dist & BT_SMP_DIST_SIGN) { + atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_SIGNING_INFO); + } + + if (IS_ENABLED(CONFIG_BLUETOOTH_CENTRAL) && + conn->role == BT_HCI_ROLE_MASTER && !smp->remote_dist) { + bt_smp_distribute_keys(smp); + } + + /* if all keys were distributed, pairing is done */ + if (!smp->local_dist && !smp->remote_dist) { + smp_pairing_complete(smp, 0); + } + + return 0; +} + +#if defined(CONFIG_BLUETOOTH_CENTRAL) +static uint8_t legacy_pairing_rsp(struct bt_smp *smp, uint8_t remote_io) +{ + uint8_t ret; + + BT_DBG(""); + + smp->method = legacy_get_pair_method(smp, remote_io); + + /* ask for consent if this is due to received SecReq */ + if (smp->method == JUST_WORKS && + atomic_test_bit(smp->flags, SMP_FLAG_SEC_REQ) && + bt_auth && bt_auth->pairing_confirm) { + atomic_set_bit(smp->flags, SMP_FLAG_USER); + bt_auth->pairing_confirm(smp->chan.chan.conn); + return 0; + } + + ret = legacy_request_tk(smp); + if (ret) { + return ret; + } + + if (!atomic_test_bit(smp->flags, SMP_FLAG_USER)) { + atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_PAIRING_CONFIRM); + return legacy_send_pairing_confirm(smp); + } + + atomic_set_bit(smp->flags, SMP_FLAG_CFM_DELAYED); + + return 0; +} +#endif /* CONFIG_BLUETOOTH_CENTRAL */ +#else +static uint8_t smp_encrypt_info(struct bt_smp *smp, struct net_buf *buf) +{ + return BT_SMP_ERR_CMD_NOTSUPP; +} + +static uint8_t smp_master_ident(struct bt_smp *smp, struct net_buf *buf) +{ + return BT_SMP_ERR_CMD_NOTSUPP; +} +#endif /* !CONFIG_BLUETOOTH_SMP_SC_ONLY */ + +static int smp_init(struct bt_smp *smp) +{ + /* Initialize SMP context without clearing L2CAP channel context */ + memset((uint8_t *)smp + sizeof(smp->chan), 0, + sizeof(*smp) - (sizeof(smp->chan) + sizeof(smp->work))); + + /* Generate local random number */ + if (bt_rand(smp->prnd, 16)) { + return BT_SMP_ERR_UNSPECIFIED; + } + + BT_DBG("prnd %s", bt_hex(smp->prnd, 16)); + + atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_PAIRING_FAIL); + + return 0; +} + +static uint8_t get_auth(uint8_t auth) +{ + if (sc_supported) { + auth &= BT_SMP_AUTH_MASK_SC; + } else { + auth &= BT_SMP_AUTH_MASK; + } + + if (get_io_capa() == BT_SMP_IO_NO_INPUT_OUTPUT) { + auth &= ~(BT_SMP_AUTH_MITM); + } else { + auth |= BT_SMP_AUTH_MITM; + } + + return auth; +} + +static bool sec_level_reachable(struct bt_conn *conn) +{ + switch (conn->required_sec_level) { + case BT_SECURITY_LOW: + case BT_SECURITY_MEDIUM: + return true; + case BT_SECURITY_HIGH: + return get_io_capa() != BT_SMP_IO_NO_INPUT_OUTPUT; + case BT_SECURITY_FIPS: + return get_io_capa() != BT_SMP_IO_NO_INPUT_OUTPUT && + sc_supported; + default: + return false; + } +} + +static struct bt_smp *smp_chan_get(struct bt_conn *conn) +{ + struct bt_l2cap_chan *chan; + + chan = bt_l2cap_le_lookup_rx_cid(conn, BT_L2CAP_CID_SMP); + if (!chan) { + BT_ERR("Unable to find SMP channel"); + return NULL; + } + + return CONTAINER_OF(chan, struct bt_smp, chan); +} + +#if defined(CONFIG_BLUETOOTH_PERIPHERAL) +int bt_smp_send_security_req(struct bt_conn *conn) +{ + struct bt_smp *smp; + struct bt_smp_security_request *req; + struct net_buf *req_buf; + + BT_DBG(""); + smp = smp_chan_get(conn); + if (!smp) { + return -ENOTCONN; + } + + /* SMP Timeout */ + if (atomic_test_bit(smp->flags, SMP_FLAG_TIMEOUT)) { + return -EIO; + } + + /* pairing is in progress */ + if (atomic_test_bit(smp->flags, SMP_FLAG_PAIRING)) { + return -EBUSY; + } + + /* early verify if required sec level if reachable */ + if (!sec_level_reachable(conn)) { + return -EINVAL; + } + + req_buf = smp_create_pdu(conn, BT_SMP_CMD_SECURITY_REQUEST, + sizeof(*req)); + if (!req_buf) { + return -ENOBUFS; + } + + req = net_buf_add(req_buf, sizeof(*req)); + req->auth_req = get_auth(BT_SMP_AUTH_DEFAULT); + + /* SMP timer is not restarted for SecRequest so don't use smp_send */ + bt_l2cap_send(conn, BT_L2CAP_CID_SMP, req_buf); + + atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_PAIRING_FAIL); + + return 0; +} + +static uint8_t smp_pairing_req(struct bt_smp *smp, struct net_buf *buf) +{ + struct bt_smp_pairing *req = (void *)buf->data; + struct bt_smp_pairing *rsp; + int ret; + + BT_DBG(""); + + if ((req->max_key_size > BT_SMP_MAX_ENC_KEY_SIZE) || + (req->max_key_size < BT_SMP_MIN_ENC_KEY_SIZE)) { + return BT_SMP_ERR_ENC_KEY_SIZE; + } + + ret = smp_init(smp); + if (ret) { + return ret; + } + + /* Store req for later use */ + smp->preq[0] = BT_SMP_CMD_PAIRING_REQ; + memcpy(smp->preq + 1, req, sizeof(*req)); + + /* create rsp, it will be used later on */ + smp->prsp[0] = BT_SMP_CMD_PAIRING_RSP; + rsp = (struct bt_smp_pairing *)&smp->prsp[1]; + + rsp->auth_req = get_auth(req->auth_req); + rsp->io_capability = get_io_capa(); + rsp->oob_flag = BT_SMP_OOB_NOT_PRESENT; + rsp->max_key_size = BT_SMP_MAX_ENC_KEY_SIZE; + rsp->init_key_dist = (req->init_key_dist & RECV_KEYS); + rsp->resp_key_dist = (req->resp_key_dist & SEND_KEYS); + + if ((rsp->auth_req & BT_SMP_AUTH_SC) && + (req->auth_req & BT_SMP_AUTH_SC)) { + atomic_set_bit(smp->flags, SMP_FLAG_SC); + + rsp->init_key_dist &= RECV_KEYS_SC; + rsp->resp_key_dist &= SEND_KEYS_SC; + } + + if ((rsp->auth_req & BT_SMP_AUTH_CT2) && + (req->auth_req & BT_SMP_AUTH_CT2)) { + atomic_set_bit(smp->flags, SMP_FLAG_CT2); + } + + smp->local_dist = rsp->resp_key_dist; + smp->remote_dist = rsp->init_key_dist; + + if ((rsp->auth_req & BT_SMP_AUTH_BONDING) && + (req->auth_req & BT_SMP_AUTH_BONDING)) { + atomic_set_bit(smp->flags, SMP_FLAG_BOND); + } + + atomic_set_bit(smp->flags, SMP_FLAG_PAIRING); + + if (!atomic_test_bit(smp->flags, SMP_FLAG_SC)) { +#if defined(CONFIG_BLUETOOTH_SMP_SC_ONLY) + return BT_SMP_ERR_AUTH_REQUIREMENTS; +#else + return legacy_pairing_req(smp, req->io_capability); +#endif /* CONFIG_BLUETOOTH_SMP_SC_ONLY */ + } + + smp->method = get_pair_method(smp, req->io_capability); + + if (IS_ENABLED(CONFIG_BLUETOOTH_SMP_SC_ONLY) && + smp->method == JUST_WORKS) { + return BT_SMP_ERR_AUTH_REQUIREMENTS; + } + + if (smp->method == JUST_WORKS) { + if (IS_ENABLED(CONFIG_BLUETOOTH_SMP_SC_ONLY)) { + return BT_SMP_ERR_AUTH_REQUIREMENTS; + } + + /* ask for consent if pairing is not due to sending SecReq*/ + if (!atomic_test_bit(smp->flags, SMP_FLAG_SEC_REQ) && + bt_auth && bt_auth->pairing_confirm) { + atomic_set_bit(smp->flags, SMP_FLAG_USER); + bt_auth->pairing_confirm(smp->chan.chan.conn); + return 0; + } + } + + atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_PUBLIC_KEY); + return send_pairing_rsp(smp); +} +#else +static uint8_t smp_pairing_req(struct bt_smp *smp, struct net_buf *buf) +{ + return BT_SMP_ERR_CMD_NOTSUPP; +} +#endif /* CONFIG_BLUETOOTH_PERIPHERAL */ + +static uint8_t sc_send_public_key(struct bt_smp *smp) +{ + struct bt_smp_public_key *req; + struct net_buf *req_buf; + + req_buf = smp_create_pdu(smp->chan.chan.conn, BT_SMP_CMD_PUBLIC_KEY, + sizeof(*req)); + if (!req_buf) { + return BT_SMP_ERR_UNSPECIFIED; + } + + req = net_buf_add(req_buf, sizeof(*req)); + + memcpy(req->x, sc_public_key, sizeof(req->x)); + memcpy(req->y, &sc_public_key[32], sizeof(req->y)); + + smp_send(smp, req_buf); + + if (IS_ENABLED(CONFIG_BLUETOOTH_USE_DEBUG_KEYS)) { + atomic_set_bit(smp->flags, SMP_FLAG_SC_DEBUG_KEY); + } + + return 0; +} + +#if defined(CONFIG_BLUETOOTH_CENTRAL) +int bt_smp_send_pairing_req(struct bt_conn *conn) +{ + struct bt_smp *smp; + struct bt_smp_pairing *req; + struct net_buf *req_buf; + + BT_DBG(""); + + smp = smp_chan_get(conn); + if (!smp) { + return -ENOTCONN; + } + + /* SMP Timeout */ + if (atomic_test_bit(smp->flags, SMP_FLAG_TIMEOUT)) { + return -EIO; + } + + /* pairing is in progress */ + if (atomic_test_bit(smp->flags, SMP_FLAG_PAIRING)) { + return -EBUSY; + } + + /* early verify if required sec level if reachable */ + if (!sec_level_reachable(conn)) { + return -EINVAL; + } + + if (smp_init(smp)) { + return -ENOBUFS; + } + + req_buf = smp_create_pdu(conn, BT_SMP_CMD_PAIRING_REQ, sizeof(*req)); + if (!req_buf) { + return -ENOBUFS; + } + + req = net_buf_add(req_buf, sizeof(*req)); + + req->auth_req = get_auth(BT_SMP_AUTH_DEFAULT); + req->io_capability = get_io_capa(); + req->oob_flag = BT_SMP_OOB_NOT_PRESENT; + req->max_key_size = BT_SMP_MAX_ENC_KEY_SIZE; + req->init_key_dist = SEND_KEYS; + req->resp_key_dist = RECV_KEYS; + + smp->local_dist = SEND_KEYS; + smp->remote_dist = RECV_KEYS; + + /* Store req for later use */ + smp->preq[0] = BT_SMP_CMD_PAIRING_REQ; + memcpy(smp->preq + 1, req, sizeof(*req)); + + smp_send(smp, req_buf); + + atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_PAIRING_RSP); + atomic_set_bit(smp->flags, SMP_FLAG_PAIRING); + + return 0; +} + +static uint8_t smp_pairing_rsp(struct bt_smp *smp, struct net_buf *buf) +{ + struct bt_smp_pairing *rsp = (void *)buf->data; + struct bt_smp_pairing *req = (struct bt_smp_pairing *)&smp->preq[1]; + + BT_DBG(""); + + if ((rsp->max_key_size > BT_SMP_MAX_ENC_KEY_SIZE) || + (rsp->max_key_size < BT_SMP_MIN_ENC_KEY_SIZE)) { + return BT_SMP_ERR_ENC_KEY_SIZE; + } + + smp->local_dist &= rsp->init_key_dist; + smp->remote_dist &= rsp->resp_key_dist; + + /* Store rsp for later use */ + smp->prsp[0] = BT_SMP_CMD_PAIRING_RSP; + memcpy(smp->prsp + 1, rsp, sizeof(*rsp)); + + if ((rsp->auth_req & BT_SMP_AUTH_SC) && + (req->auth_req & BT_SMP_AUTH_SC)) { + atomic_set_bit(smp->flags, SMP_FLAG_SC); + } + + if ((rsp->auth_req & BT_SMP_AUTH_CT2) && + (req->auth_req & BT_SMP_AUTH_CT2)) { + atomic_set_bit(smp->flags, SMP_FLAG_CT2); + } + + if ((rsp->auth_req & BT_SMP_AUTH_BONDING) && + (req->auth_req & BT_SMP_AUTH_BONDING)) { + atomic_set_bit(smp->flags, SMP_FLAG_BOND); + } + + if (!atomic_test_bit(smp->flags, SMP_FLAG_SC)) { +#if defined(CONFIG_BLUETOOTH_SMP_SC_ONLY) + return BT_SMP_ERR_AUTH_REQUIREMENTS; +#else + return legacy_pairing_rsp(smp, rsp->io_capability); +#endif /* CONFIG_BLUETOOTH_SMP_SC_ONLY */ + } + + smp->method = get_pair_method(smp, rsp->io_capability); + + smp->local_dist &= SEND_KEYS_SC; + smp->remote_dist &= RECV_KEYS_SC; + + if (smp->method == JUST_WORKS) { + if (IS_ENABLED(CONFIG_BLUETOOTH_SMP_SC_ONLY)) { + return BT_SMP_ERR_AUTH_REQUIREMENTS; + } + + /* ask for consent if this is due to received SecReq */ + if (atomic_test_bit(smp->flags, SMP_FLAG_SEC_REQ) && + bt_auth && bt_auth->pairing_confirm) { + atomic_set_bit(smp->flags, SMP_FLAG_USER); + bt_auth->pairing_confirm(smp->chan.chan.conn); + return 0; + } + } + + if (!sc_local_pkey_valid) { + atomic_set_bit(smp->flags, SMP_FLAG_PKEY_SEND); + return 0; + } + + atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_PUBLIC_KEY); + return sc_send_public_key(smp); +} +#else +static uint8_t smp_pairing_rsp(struct bt_smp *smp, struct net_buf *buf) +{ + return BT_SMP_ERR_CMD_NOTSUPP; +} +#endif /* CONFIG_BLUETOOTH_CENTRAL */ + +static uint8_t smp_pairing_confirm(struct bt_smp *smp, struct net_buf *buf) +{ + struct bt_smp_pairing_confirm *req = (void *)buf->data; + + BT_DBG(""); + + memcpy(smp->pcnf, req->val, sizeof(smp->pcnf)); + + if (IS_ENABLED(CONFIG_BLUETOOTH_CENTRAL) && + smp->chan.chan.conn->role == BT_HCI_ROLE_MASTER) { + atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_PAIRING_RANDOM); + return smp_send_pairing_random(smp); + } + + if (!IS_ENABLED(CONFIG_BLUETOOTH_PERIPHERAL)) { + return 0; + } + +#if !defined(CONFIG_BLUETOOTH_SMP_SC_ONLY) + if (!atomic_test_bit(smp->flags, SMP_FLAG_SC)) { + return legacy_pairing_confirm(smp); + } +#endif /* !CONFIG_BLUETOOTH_SMP_SC_ONLY */ + + switch (smp->method) { + case PASSKEY_DISPLAY: + atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_PAIRING_RANDOM); + return smp_send_pairing_confirm(smp); + case PASSKEY_INPUT: + if (atomic_test_bit(smp->flags, SMP_FLAG_USER)) { + atomic_set_bit(smp->flags, SMP_FLAG_CFM_DELAYED); + return 0; + } + + atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_PAIRING_RANDOM); + return smp_send_pairing_confirm(smp); + case JUST_WORKS: + case PASSKEY_CONFIRM: + default: + return BT_SMP_ERR_UNSPECIFIED; + } +} + +static uint8_t sc_smp_send_dhkey_check(struct bt_smp *smp, const uint8_t *e) +{ + struct bt_smp_dhkey_check *req; + struct net_buf *buf; + + BT_DBG(""); + + buf = smp_create_pdu(smp->chan.chan.conn, BT_SMP_DHKEY_CHECK, + sizeof(*req)); + if (!buf) { + return BT_SMP_ERR_UNSPECIFIED; + } + + req = net_buf_add(buf, sizeof(*req)); + memcpy(req->e, e, sizeof(req->e)); + + smp_send(smp, buf); + + return 0; +} + +#if defined(CONFIG_BLUETOOTH_CENTRAL) +static uint8_t compute_and_send_master_dhcheck(struct bt_smp *smp) +{ + uint8_t e[16], r[16]; + + memset(r, 0, sizeof(r)); + + switch (smp->method) { + case JUST_WORKS: + case PASSKEY_CONFIRM: + break; + case PASSKEY_DISPLAY: + case PASSKEY_INPUT: + memcpy(r, &smp->passkey, sizeof(smp->passkey)); + break; + default: + return BT_SMP_ERR_UNSPECIFIED; + } + + /* calculate LTK and mackey */ + if (smp_f5(smp->dhkey, smp->prnd, smp->rrnd, + &smp->chan.chan.conn->le.init_addr, + &smp->chan.chan.conn->le.resp_addr, smp->mackey, + smp->tk)) { + return BT_SMP_ERR_UNSPECIFIED; + } + /* calculate local DHKey check */ + if (smp_f6(smp->mackey, smp->prnd, smp->rrnd, r, &smp->preq[1], + &smp->chan.chan.conn->le.init_addr, + &smp->chan.chan.conn->le.resp_addr, e)) { + return BT_SMP_ERR_UNSPECIFIED; + } + + atomic_set_bit(&smp->allowed_cmds, BT_SMP_DHKEY_CHECK); + sc_smp_send_dhkey_check(smp, e); + return 0; +} +#endif /* CONFIG_BLUETOOTH_CENTRAL */ + +#if defined(CONFIG_BLUETOOTH_PERIPHERAL) +static uint8_t compute_and_check_and_send_slave_dhcheck(struct bt_smp *smp) +{ + uint8_t re[16], e[16], r[16]; + + memset(r, 0, sizeof(r)); + + switch (smp->method) { + case JUST_WORKS: + case PASSKEY_CONFIRM: + break; + case PASSKEY_DISPLAY: + case PASSKEY_INPUT: + memcpy(r, &smp->passkey, sizeof(smp->passkey)); + break; + default: + return BT_SMP_ERR_UNSPECIFIED; + } + + /* calculate LTK and mackey */ + if (smp_f5(smp->dhkey, smp->rrnd, smp->prnd, + &smp->chan.chan.conn->le.init_addr, + &smp->chan.chan.conn->le.resp_addr, smp->mackey, + smp->tk)) { + return BT_SMP_ERR_UNSPECIFIED; + } + + /* calculate local DHKey check */ + if (smp_f6(smp->mackey, smp->prnd, smp->rrnd, r, &smp->prsp[1], + &smp->chan.chan.conn->le.resp_addr, + &smp->chan.chan.conn->le.init_addr, e)) { + return BT_SMP_ERR_UNSPECIFIED; + } + + /* calculate remote DHKey check */ + if (smp_f6(smp->mackey, smp->rrnd, smp->prnd, r, &smp->preq[1], + &smp->chan.chan.conn->le.init_addr, + &smp->chan.chan.conn->le.resp_addr, re)) { + return BT_SMP_ERR_UNSPECIFIED; + } + + /* compare received E with calculated remote */ + if (memcmp(smp->e, re, 16)) { + return BT_SMP_ERR_DHKEY_CHECK_FAILED; + } + + /* send local e */ + sc_smp_send_dhkey_check(smp, e); + + atomic_set_bit(smp->flags, SMP_FLAG_ENC_PENDING); + return 0; +} +#endif /* CONFIG_BLUETOOTH_PERIPHERAL */ + +static void bt_smp_dhkey_ready(const uint8_t *dhkey) +{ + struct bt_smp *smp = NULL; + int i; + + BT_DBG("%p", dhkey); + + for (i = 0; i < ARRAY_SIZE(bt_smp_pool); i++) { + if (atomic_test_and_clear_bit(bt_smp_pool[i].flags, + SMP_FLAG_DHKEY_PENDING)) { + smp = &bt_smp_pool[i]; + break; + } + } + + if (!smp) { + return; + } + + if (!dhkey) { + smp_error(smp, BT_SMP_ERR_DHKEY_CHECK_FAILED); + return; + } + + memcpy(smp->dhkey, dhkey, 32); + + /* wait for user passkey confirmation */ + if (atomic_test_bit(smp->flags, SMP_FLAG_USER)) { + atomic_set_bit(smp->flags, SMP_FLAG_DHKEY_SEND); + return; + } + + /* wait for remote DHKey Check */ + if (atomic_test_bit(smp->flags, SMP_FLAG_DHCHECK_WAIT)) { + atomic_set_bit(smp->flags, SMP_FLAG_DHKEY_SEND); + return; + } + + if (atomic_test_bit(smp->flags, SMP_FLAG_DHKEY_SEND)) { + uint8_t err; + +#if defined(CONFIG_BLUETOOTH_CENTRAL) + if (smp->chan.chan.conn->role == BT_HCI_ROLE_MASTER) { + err = compute_and_send_master_dhcheck(smp); + if (err) { + smp_error(smp, err); + } + + return; + } +#endif /* CONFIG_BLUETOOTH_CENTRAL */ + +#if defined(CONFIG_BLUETOOTH_PERIPHERAL) + err = compute_and_check_and_send_slave_dhcheck(smp); + if (err) { + smp_error(smp, err); + } +#endif /* CONFIG_BLUETOOTH_PERIPHERAL */ + } +} + +static uint8_t sc_smp_check_confirm(struct bt_smp *smp) +{ + uint8_t cfm[16]; + uint8_t r; + + switch (smp->method) { + case PASSKEY_CONFIRM: + case JUST_WORKS: + r = 0; + break; + case PASSKEY_DISPLAY: + case PASSKEY_INPUT: + /* + * In the Passkey Entry protocol, the most significant + * bit of Z is set equal to one and the least + * significant bit is made up from one bit of the + * passkey e.g. if the passkey bit is 1, then Z = 0x81 + * and if the passkey bit is 0, then Z = 0x80. + */ + r = (smp->passkey >> smp->passkey_round) & 0x01; + r |= 0x80; + break; + default: + return BT_SMP_ERR_UNSPECIFIED; + } + + if (smp_f4(smp->pkey, sc_public_key, smp->rrnd, r, cfm)) { + return BT_SMP_ERR_UNSPECIFIED; + } + + BT_DBG("pcnf %s cfm %s", bt_hex(smp->pcnf, 16), bt_hex(cfm, 16)); + + if (memcmp(smp->pcnf, cfm, 16)) { + return BT_SMP_ERR_CONFIRM_FAILED; + } + + return 0; +} + +static uint8_t smp_pairing_random(struct bt_smp *smp, struct net_buf *buf) +{ + struct bt_smp_pairing_random *req = (void *)buf->data; + uint32_t passkey; + uint8_t err; + + BT_DBG(""); + + memcpy(smp->rrnd, req->val, sizeof(smp->rrnd)); + +#if !defined(CONFIG_BLUETOOTH_SMP_SC_ONLY) + if (!atomic_test_bit(smp->flags, SMP_FLAG_SC)) { + return legacy_pairing_random(smp); + } +#endif /* !CONFIG_BLUETOOTH_SMP_SC_ONLY */ + +#if defined(CONFIG_BLUETOOTH_CENTRAL) + if (smp->chan.chan.conn->role == BT_HCI_ROLE_MASTER) { + err = sc_smp_check_confirm(smp); + if (err) { + return err; + } + + switch (smp->method) { + case PASSKEY_CONFIRM: + /* compare passkey before calculating LTK */ + if (smp_g2(sc_public_key, smp->pkey, smp->prnd, + smp->rrnd, &passkey)) { + return BT_SMP_ERR_UNSPECIFIED; + } + + atomic_set_bit(smp->flags, SMP_FLAG_USER); + atomic_set_bit(smp->flags, SMP_FLAG_DHKEY_SEND); + bt_auth->passkey_confirm(smp->chan.chan.conn, passkey); + return 0; + case JUST_WORKS: + break; + case PASSKEY_DISPLAY: + case PASSKEY_INPUT: + smp->passkey_round++; + if (smp->passkey_round == 20) { + break; + } + + if (bt_rand(smp->prnd, 16)) { + return BT_SMP_ERR_UNSPECIFIED; + } + + atomic_set_bit(&smp->allowed_cmds, + BT_SMP_CMD_PAIRING_CONFIRM); + smp_send_pairing_confirm(smp); + return 0; + default: + return BT_SMP_ERR_UNSPECIFIED; + } + + /* wait for DHKey being generated */ + if (atomic_test_bit(smp->flags, SMP_FLAG_DHKEY_PENDING)) { + atomic_set_bit(smp->flags, SMP_FLAG_DHKEY_SEND); + return 0; + } + + return compute_and_send_master_dhcheck(smp); + } +#endif /* CONFIG_BLUETOOTH_CENTRAL */ + +#if defined(CONFIG_BLUETOOTH_PERIPHERAL) + switch (smp->method) { + case PASSKEY_CONFIRM: + if (smp_g2(smp->pkey, sc_public_key, smp->rrnd, smp->prnd, + &passkey)) { + return BT_SMP_ERR_UNSPECIFIED; + } + + atomic_set_bit(smp->flags, SMP_FLAG_USER); + bt_auth->passkey_confirm(smp->chan.chan.conn, passkey); + break; + case JUST_WORKS: + break; + case PASSKEY_DISPLAY: + case PASSKEY_INPUT: + err = sc_smp_check_confirm(smp); + if (err) { + return err; + } + + atomic_set_bit(&smp->allowed_cmds, + BT_SMP_CMD_PAIRING_CONFIRM); + smp_send_pairing_random(smp); + + smp->passkey_round++; + if (smp->passkey_round == 20) { + atomic_set_bit(&smp->allowed_cmds, BT_SMP_DHKEY_CHECK); + atomic_set_bit(smp->flags, SMP_FLAG_DHCHECK_WAIT); + return 0; + } + + if (bt_rand(smp->prnd, 16)) { + return BT_SMP_ERR_UNSPECIFIED; + } + + return 0; + default: + return BT_SMP_ERR_UNSPECIFIED; + } + + atomic_set_bit(&smp->allowed_cmds, BT_SMP_DHKEY_CHECK); + atomic_set_bit(smp->flags, SMP_FLAG_DHCHECK_WAIT); + smp_send_pairing_random(smp); +#endif /* CONFIG_BLUETOOTH_PERIPHERAL */ + + return 0; +} + +static uint8_t smp_pairing_failed(struct bt_smp *smp, struct net_buf *buf) +{ + struct bt_conn *conn = smp->chan.chan.conn; + struct bt_smp_pairing_fail *req = (void *)buf->data; + + BT_ERR("reason 0x%x", req->reason); + + /* TODO report error + * for now this to avoid warning about unused variable when debugs are + * disabled + */ + ARG_UNUSED(req); + + switch (smp->method) { + case PASSKEY_INPUT: + case PASSKEY_DISPLAY: + case PASSKEY_CONFIRM: + bt_auth->cancel(conn); + break; + default: + break; + } + + /* + * Pairing Failed command may be sent at any time during the pairing, + * so if there are any keys distributed, shall be cleared. + */ + if (atomic_test_bit(smp->flags, SMP_FLAG_KEYS_DISTR) && + smp->chan.chan.conn->le.keys) { + bt_keys_clear(smp->chan.chan.conn->le.keys); + } + + smp_pairing_complete(smp, req->reason); + + /* return no error to avoid sending Pairing Failed in response */ + return 0; +} + +static uint8_t smp_ident_info(struct bt_smp *smp, struct net_buf *buf) +{ + BT_DBG(""); + + if (atomic_test_bit(smp->flags, SMP_FLAG_BOND)) { + struct bt_smp_ident_info *req = (void *)buf->data; + struct bt_conn *conn = smp->chan.chan.conn; + struct bt_keys *keys; + + keys = bt_keys_get_type(BT_KEYS_IRK, &conn->le.dst); + if (!keys) { + BT_ERR("Unable to get keys for %s", + bt_addr_le_str(&conn->le.dst)); + return BT_SMP_ERR_UNSPECIFIED; + } + + memcpy(keys->irk.val, req->irk, 16); + } + + atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_IDENT_ADDR_INFO); + + return 0; +} + +static uint8_t smp_ident_addr_info(struct bt_smp *smp, struct net_buf *buf) +{ + struct bt_conn *conn = smp->chan.chan.conn; + struct bt_smp_ident_addr_info *req = (void *)buf->data; + + BT_DBG("identity %s", bt_addr_le_str(&req->addr)); + + if (!bt_addr_le_is_identity(&req->addr)) { + BT_ERR("Invalid identity %s for %s", + bt_addr_le_str(&req->addr), bt_addr_le_str(&conn->le.dst)); + return BT_SMP_ERR_INVALID_PARAMS; + } + + if (atomic_test_bit(smp->flags, SMP_FLAG_BOND)) { + const bt_addr_le_t *dst; + struct bt_keys *keys; + + keys = bt_keys_get_type(BT_KEYS_IRK, &conn->le.dst); + if (!keys) { + BT_ERR("Unable to get keys for %s", + bt_addr_le_str(&conn->le.dst)); + return BT_SMP_ERR_UNSPECIFIED; + } + + /* + * We can't use conn->dst here as this might already contain + * identity address known from previous pairing. Since all keys + * are cleared on re-pairing we wouldn't store IRK distributed + * in new pairing. + */ + if (conn->role == BT_HCI_ROLE_MASTER) { + dst = &conn->le.resp_addr; + } else { + dst = &conn->le.init_addr; + } + + if (bt_addr_le_is_rpa(dst)) { + /* always update last use RPA */ + bt_addr_copy(&keys->irk.rpa, &dst->a); + + /* + * Update connection address and notify about identity + * resolved only if connection wasn't already reported + * with identity address. This may happen if IRK was + * present before ie. due to re-pairing. + */ + if (!bt_addr_le_is_identity(&conn->le.dst)) { + bt_addr_le_copy(&keys->addr, &req->addr); + bt_addr_le_copy(&conn->le.dst, &req->addr); + + bt_conn_identity_resolved(conn); + } + } + } + + smp->remote_dist &= ~BT_SMP_DIST_ID_KEY; + + if (smp->remote_dist & BT_SMP_DIST_SIGN) { + atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_SIGNING_INFO); + } + + if (IS_ENABLED(CONFIG_BLUETOOTH_CENTRAL) && + conn->role == BT_HCI_ROLE_MASTER && !smp->remote_dist) { + bt_smp_distribute_keys(smp); + } + + /* if all keys were distributed, pairing is done */ + if (!smp->local_dist && !smp->remote_dist) { + smp_pairing_complete(smp, 0); + } + + return 0; +} + +#if defined(CONFIG_BLUETOOTH_SIGNING) +static uint8_t smp_signing_info(struct bt_smp *smp, struct net_buf *buf) +{ + struct bt_conn *conn = smp->chan.chan.conn; + + BT_DBG(""); + + if (atomic_test_bit(smp->flags, SMP_FLAG_BOND)) { + struct bt_smp_signing_info *req = (void *)buf->data; + struct bt_keys *keys; + + keys = bt_keys_get_type(BT_KEYS_REMOTE_CSRK, &conn->le.dst); + if (!keys) { + BT_ERR("Unable to get keys for %s", + bt_addr_le_str(&conn->le.dst)); + return BT_SMP_ERR_UNSPECIFIED; + } + + memcpy(keys->remote_csrk.val, req->csrk, + sizeof(keys->remote_csrk.val)); + } + + smp->remote_dist &= ~BT_SMP_DIST_SIGN; + + if (IS_ENABLED(CONFIG_BLUETOOTH_CENTRAL) && + conn->role == BT_HCI_ROLE_MASTER && !smp->remote_dist) { + bt_smp_distribute_keys(smp); + } + + /* if all keys were distributed, pairing is done */ + if (!smp->local_dist && !smp->remote_dist) { + smp_pairing_complete(smp, 0); + } + + return 0; +} +#else +static uint8_t smp_signing_info(struct bt_smp *smp, struct net_buf *buf) +{ + return BT_SMP_ERR_CMD_NOTSUPP; +} +#endif /* CONFIG_BLUETOOTH_SIGNING */ + +#if defined(CONFIG_BLUETOOTH_CENTRAL) +static uint8_t smp_security_request(struct bt_smp *smp, struct net_buf *buf) +{ + struct bt_conn *conn = smp->chan.chan.conn; + struct bt_smp_security_request *req = (void *)buf->data; + uint8_t auth; + + BT_DBG(""); + + if (sc_supported) { + auth = req->auth_req & BT_SMP_AUTH_MASK_SC; + } else { + auth = req->auth_req & BT_SMP_AUTH_MASK; + } + + if (!conn->le.keys) { + conn->le.keys = bt_keys_find(BT_KEYS_LTK_P256, &conn->le.dst); + if (!conn->le.keys) { + conn->le.keys = bt_keys_find(BT_KEYS_LTK, + &conn->le.dst); + } + } + + if (!conn->le.keys) { + goto pair; + } + + /* if MITM required key must be authenticated */ + if ((auth & BT_SMP_AUTH_MITM) && + !atomic_test_bit(conn->le.keys->flags, BT_KEYS_AUTHENTICATED)) { + if (get_io_capa() != BT_SMP_IO_NO_INPUT_OUTPUT) { + BT_INFO("New auth requirements: 0x%x, repairing", + auth); + goto pair; + } + + BT_WARN("Unsupported auth requirements: 0x%x, repairing", + auth); + goto pair; + } + + /* if LE SC required and no p256 key present repair */ + if ((auth & BT_SMP_AUTH_SC) && + !(conn->le.keys->keys & BT_KEYS_LTK_P256)) { + BT_INFO("New auth requirements: 0x%x, repairing", auth); + goto pair; + } + + if (bt_conn_le_start_encryption(conn, conn->le.keys->ltk.rand, + conn->le.keys->ltk.ediv, + conn->le.keys->ltk.val, + conn->le.keys->enc_size) < 0) { + return BT_SMP_ERR_UNSPECIFIED; + } + + atomic_set_bit(smp->flags, SMP_FLAG_ENC_PENDING); + + return 0; +pair: + if (bt_smp_send_pairing_req(conn) < 0) { + return BT_SMP_ERR_UNSPECIFIED; + } + + atomic_set_bit(smp->flags, SMP_FLAG_SEC_REQ); + + return 0; +} +#else +static uint8_t smp_security_request(struct bt_smp *smp, struct net_buf *buf) +{ + return BT_SMP_ERR_CMD_NOTSUPP; +} +#endif /* CONFIG_BLUETOOTH_CENTRAL */ + +static uint8_t generate_dhkey(struct bt_smp *smp) +{ + if (bt_dh_key_gen(smp->pkey, bt_smp_dhkey_ready)) { + return BT_SMP_ERR_UNSPECIFIED; + } + + atomic_set_bit(smp->flags, SMP_FLAG_DHKEY_PENDING); + return 0; +} + +static uint8_t display_passkey(struct bt_smp *smp) +{ + if (bt_rand(&smp->passkey, sizeof(smp->passkey))) { + return BT_SMP_ERR_UNSPECIFIED; + } + + smp->passkey %= 1000000; + smp->passkey_round = 0; + + bt_auth->passkey_display(smp->chan.chan.conn, smp->passkey); + smp->passkey = sys_cpu_to_le32(smp->passkey); + + return 0; +} + +#if defined(CONFIG_BLUETOOTH_PERIPHERAL) +static uint8_t smp_public_key_slave(struct bt_smp *smp) +{ + uint8_t err; + + err = sc_send_public_key(smp); + if (err) { + return err; + } + + switch (smp->method) { + case PASSKEY_CONFIRM: + case JUST_WORKS: + atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_PAIRING_RANDOM); + + err = smp_send_pairing_confirm(smp); + if (err) { + return err; + } + break; + case PASSKEY_DISPLAY: + err = display_passkey(smp); + if (err) { + return err; + } + + atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_PAIRING_CONFIRM); + break; + case PASSKEY_INPUT: + atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_PAIRING_CONFIRM); + atomic_set_bit(smp->flags, SMP_FLAG_USER); + bt_auth->passkey_entry(smp->chan.chan.conn); + break; + default: + return BT_SMP_ERR_UNSPECIFIED; + } + + return generate_dhkey(smp); +} +#endif /* CONFIG_BLUETOOTH_PERIPHERAL */ + +static uint8_t smp_public_key(struct bt_smp *smp, struct net_buf *buf) +{ + struct bt_smp_public_key *req = (void *)buf->data; + uint8_t err; + + BT_DBG(""); + + memcpy(smp->pkey, req->x, 32); + memcpy(&smp->pkey[32], req->y, 32); + + /* mark key as debug if remote is using it */ + if (memcmp(smp->pkey, sc_debug_public_key, 64) == 0) { + BT_INFO("Remote is using Debug Public key"); + atomic_set_bit(smp->flags, SMP_FLAG_SC_DEBUG_KEY); + } + + if (IS_ENABLED(CONFIG_BLUETOOTH_CENTRAL) && + smp->chan.chan.conn->role == BT_HCI_ROLE_MASTER) { + switch (smp->method) { + case PASSKEY_CONFIRM: + case JUST_WORKS: + atomic_set_bit(&smp->allowed_cmds, + BT_SMP_CMD_PAIRING_CONFIRM); + break; + case PASSKEY_DISPLAY: + err = display_passkey(smp); + if (err) { + return err; + } + + atomic_set_bit(&smp->allowed_cmds, + BT_SMP_CMD_PAIRING_CONFIRM); + + err = smp_send_pairing_confirm(smp); + if (err) { + return err; + } + break; + case PASSKEY_INPUT: + atomic_set_bit(smp->flags, SMP_FLAG_USER); + bt_auth->passkey_entry(smp->chan.chan.conn); + break; + default: + return BT_SMP_ERR_UNSPECIFIED; + } + + return generate_dhkey(smp); + } + +#if defined(CONFIG_BLUETOOTH_PERIPHERAL) + if (!sc_local_pkey_valid) { + atomic_set_bit(smp->flags, SMP_FLAG_PKEY_SEND); + return 0; + } + + err = smp_public_key_slave(smp); + if (err) { + return err; + } +#endif /* CONFIG_BLUETOOTH_PERIPHERAL */ + + return 0; +} + +static uint8_t smp_dhkey_check(struct bt_smp *smp, struct net_buf *buf) +{ + struct bt_smp_dhkey_check *req = (void *)buf->data; + + BT_DBG(""); + + if (IS_ENABLED(CONFIG_BLUETOOTH_CENTRAL) && + smp->chan.chan.conn->role == BT_HCI_ROLE_MASTER) { + uint8_t e[16], r[16], enc_size; + + memset(r, 0, sizeof(r)); + + switch (smp->method) { + case JUST_WORKS: + case PASSKEY_CONFIRM: + break; + case PASSKEY_DISPLAY: + case PASSKEY_INPUT: + memcpy(r, &smp->passkey, sizeof(smp->passkey)); + break; + default: + return BT_SMP_ERR_UNSPECIFIED; + } + + /* calculate remote DHKey check for comparison */ + if (smp_f6(smp->mackey, smp->rrnd, smp->prnd, r, &smp->prsp[1], + &smp->chan.chan.conn->le.resp_addr, + &smp->chan.chan.conn->le.init_addr, e)) { + return BT_SMP_ERR_UNSPECIFIED; + } + + if (memcmp(e, req->e, 16)) { + return BT_SMP_ERR_DHKEY_CHECK_FAILED; + } + + enc_size = get_encryption_key_size(smp); + + if (bt_conn_le_start_encryption(smp->chan.chan.conn, 0, 0, + smp->tk, enc_size) < 0) { + return BT_SMP_ERR_UNSPECIFIED; + } + + atomic_set_bit(smp->flags, SMP_FLAG_ENC_PENDING); + return 0; + } + +#if defined(CONFIG_BLUETOOTH_PERIPHERAL) + if (smp->chan.chan.conn->role == BT_HCI_ROLE_SLAVE) { + atomic_clear_bit(smp->flags, SMP_FLAG_DHCHECK_WAIT); + memcpy(smp->e, req->e, sizeof(smp->e)); + + /* wait for DHKey being generated */ + if (atomic_test_bit(smp->flags, SMP_FLAG_DHKEY_PENDING)) { + atomic_set_bit(smp->flags, SMP_FLAG_DHKEY_SEND); + return 0; + } + + /* waiting for user to confirm passkey */ + if (atomic_test_bit(smp->flags, SMP_FLAG_USER)) { + atomic_set_bit(smp->flags, SMP_FLAG_DHKEY_SEND); + return 0; + } + + return compute_and_check_and_send_slave_dhcheck(smp); + } +#endif /* CONFIG_BLUETOOTH_PERIPHERAL */ + + return 0; +} + +static const struct { + uint8_t (*func)(struct bt_smp *smp, struct net_buf *buf); + uint8_t expect_len; +} handlers[] = { + { }, /* No op-code defined for 0x00 */ + { smp_pairing_req, sizeof(struct bt_smp_pairing) }, + { smp_pairing_rsp, sizeof(struct bt_smp_pairing) }, + { smp_pairing_confirm, sizeof(struct bt_smp_pairing_confirm) }, + { smp_pairing_random, sizeof(struct bt_smp_pairing_random) }, + { smp_pairing_failed, sizeof(struct bt_smp_pairing_fail) }, + { smp_encrypt_info, sizeof(struct bt_smp_encrypt_info) }, + { smp_master_ident, sizeof(struct bt_smp_master_ident) }, + { smp_ident_info, sizeof(struct bt_smp_ident_info) }, + { smp_ident_addr_info, sizeof(struct bt_smp_ident_addr_info) }, + { smp_signing_info, sizeof(struct bt_smp_signing_info) }, + { smp_security_request, sizeof(struct bt_smp_security_request) }, + { smp_public_key, sizeof(struct bt_smp_public_key) }, + { smp_dhkey_check, sizeof(struct bt_smp_dhkey_check) }, +}; + +static void bt_smp_recv(struct bt_l2cap_chan *chan, struct net_buf *buf) +{ + struct bt_smp *smp = CONTAINER_OF(chan, struct bt_smp, chan); + struct bt_smp_hdr *hdr = (void *)buf->data; + uint8_t err; + + if (buf->len < sizeof(*hdr)) { + BT_ERR("Too small SMP PDU received"); + return; + } + + BT_DBG("Received SMP code 0x%02x len %u", hdr->code, buf->len); + + net_buf_pull(buf, sizeof(*hdr)); + + /* + * If SMP timeout occurred "no further SMP commands shall be sent over + * the L2CAP Security Manager Channel. A new SM procedure shall only be + * performed when a new physical link has been established." + */ + if (atomic_test_bit(smp->flags, SMP_FLAG_TIMEOUT)) { + BT_WARN("SMP command (code 0x%02x) received after timeout", + hdr->code); + return; + } + + if (hdr->code >= ARRAY_SIZE(handlers) || !handlers[hdr->code].func) { + BT_WARN("Unhandled SMP code 0x%02x", hdr->code); + smp_error(smp, BT_SMP_ERR_CMD_NOTSUPP); + return; + } + + if (!atomic_test_and_clear_bit(&smp->allowed_cmds, hdr->code)) { + BT_WARN("Unexpected SMP code 0x%02x", hdr->code); + smp_error(smp, BT_SMP_ERR_UNSPECIFIED); + return; + } + + if (buf->len != handlers[hdr->code].expect_len) { + BT_ERR("Invalid len %u for code 0x%02x", buf->len, hdr->code); + smp_error(smp, BT_SMP_ERR_INVALID_PARAMS); + return; + } + + err = handlers[hdr->code].func(smp, buf); + if (err) { + smp_error(smp, err); + } +} + +static void bt_smp_pkey_ready(const uint8_t *pkey) +{ + int i; + + BT_DBG(""); + + if (!pkey) { + BT_WARN("Public key not available"); + sc_local_pkey_valid = false; + return; + } + + memcpy(sc_public_key, pkey, 64); + sc_local_pkey_valid = true; + + for (i = 0; i < ARRAY_SIZE(bt_smp_pool); i++) { + struct bt_smp *smp = &bt_smp_pool[i]; + uint8_t err; + + if (!atomic_test_bit(smp->flags, SMP_FLAG_PKEY_SEND)) { + continue; + } + + if (IS_ENABLED(CONFIG_BLUETOOTH_CENTRAL) && + smp->chan.chan.conn->role == BT_HCI_ROLE_MASTER) { + err = sc_send_public_key(smp); + if (err) { + smp_error(smp, err); + } + + atomic_set_bit(&smp->allowed_cmds, + BT_SMP_CMD_PUBLIC_KEY); + continue; + } + +#if defined(CONFIG_BLUETOOTH_PERIPHERAL) + err = smp_public_key_slave(smp); + if (err) { + smp_error(smp, err); + } +#endif /* CONFIG_BLUETOOTH_PERIPHERAL */ + } +} + +static void bt_smp_connected(struct bt_l2cap_chan *chan) +{ + struct bt_smp *smp = CONTAINER_OF(chan, struct bt_smp, chan); + + BT_DBG("chan %p cid 0x%04x", chan, + CONTAINER_OF(chan, struct bt_l2cap_le_chan, chan)->tx.cid); + + k_delayed_work_init(&smp->work, smp_timeout); + smp_reset(smp); +} + +static void bt_smp_disconnected(struct bt_l2cap_chan *chan) +{ + struct bt_smp *smp = CONTAINER_OF(chan, struct bt_smp, chan); + struct bt_keys *keys = chan->conn->le.keys; + + BT_DBG("chan %p cid 0x%04x", chan, + CONTAINER_OF(chan, struct bt_l2cap_le_chan, chan)->tx.cid); + + k_delayed_work_cancel(&smp->work); + + if (keys) { + /* + * If debug keys were used for pairing remove them. + * No keys indicate no bonding so free keys storage. + */ + if (!keys->keys || + atomic_test_bit(keys->flags, BT_KEYS_DEBUG)) { + bt_keys_clear(keys); + } + } + + memset(smp, 0, sizeof(*smp)); +} + +static void bt_smp_encrypt_change(struct bt_l2cap_chan *chan, + uint8_t hci_status) +{ + struct bt_smp *smp = CONTAINER_OF(chan, struct bt_smp, chan); + struct bt_conn *conn = chan->conn; + + BT_DBG("chan %p conn %p handle %u encrypt 0x%02x hci status 0x%02x", + chan, conn, conn->handle, conn->encrypt, hci_status); + + if (hci_status) { + return; + } + + if (!smp || !conn->encrypt) { + return; + } + + if (!atomic_test_and_clear_bit(smp->flags, SMP_FLAG_ENC_PENDING)) { + return; + } + + /* We were waiting for encryption but with no pairing in progress. + * This can happen if paired slave sent Security Request and we + * enabled encryption. + * + * Since it is possible that slave might sent another Security Request + * eg with different AuthReq we should allow it. + */ + if (!atomic_test_bit(smp->flags, SMP_FLAG_PAIRING)) { + atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_SECURITY_REQUEST); + return; + } + + /* derive BR/EDR LinkKey if supported by both sides */ + if (atomic_test_bit(smp->flags, SMP_FLAG_SC)) { + if ((smp->local_dist & BT_SMP_DIST_LINK_KEY) && + (smp->remote_dist & BT_SMP_DIST_LINK_KEY)) { + /* + * Link Key will be derived after key distribution to + * make sure remote device identity is known + */ + atomic_set_bit(smp->flags, SMP_FLAG_DERIVE_LK); + } + /* + * Those are used as pairing finished indicator so generated + * but not distributed keys must be cleared here. + */ + smp->local_dist &= ~BT_SMP_DIST_LINK_KEY; + smp->remote_dist &= ~BT_SMP_DIST_LINK_KEY; + } + + if (smp->remote_dist & BT_SMP_DIST_ENC_KEY) { + atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_ENCRYPT_INFO); + } else if (smp->remote_dist & BT_SMP_DIST_ID_KEY) { + atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_IDENT_INFO); + } else if (smp->remote_dist & BT_SMP_DIST_SIGN) { + atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_SIGNING_INFO); + } + + atomic_set_bit(smp->flags, SMP_FLAG_KEYS_DISTR); + + /* Slave distributes it's keys first */ + if (IS_ENABLED(CONFIG_BLUETOOTH_CENTRAL) && + conn->role == BT_HCI_ROLE_MASTER && smp->remote_dist) { + return; + } + + bt_smp_distribute_keys(smp); + + /* if all keys were distributed, pairing is done */ + if (!smp->local_dist && !smp->remote_dist) { + smp_pairing_complete(smp, 0); + } +} + +bool bt_smp_irk_matches(const uint8_t irk[16], const bt_addr_t *addr) +{ + uint8_t hash[3]; + int err; + + BT_DBG("IRK %s bdaddr %s", bt_hex(irk, 16), bt_addr_str(addr)); + + err = smp_ah(irk, addr->val + 3, hash); + if (err) { + return false; + } + + return !memcmp(addr->val, hash, 3); +} + +#if defined(CONFIG_BLUETOOTH_PRIVACY) +int bt_smp_create_rpa(const uint8_t irk[16], bt_addr_t *rpa) +{ + int err; + + err = bt_rand(rpa->val + 3, 3); + if (err) { + return err; + } + + BT_ADDR_SET_RPA(rpa); + + err = smp_ah(irk, rpa->val + 3, rpa->val); + if (err) { + return err; + } + + BT_DBG("Created RPA %s", bt_addr_str((bt_addr_t *)rpa->val)); + + return 0; +} +#else +int bt_smp_create_rpa(const uint8_t irk[16], bt_addr_t *rpa) +{ + return -ENOTSUP; +} +#endif /* CONFIG_BLUETOOTH_PRIVACY */ + + +#if defined(CONFIG_BLUETOOTH_SIGNING) +/* Sign message using msg as a buffer, len is a size of the message, + * msg buffer contains message itself, 32 bit count and signature, + * so total buffer size is len + 4 + 8 octets. + * API is Little Endian to make it suitable for Bluetooth. + */ +static int smp_sign_buf(const uint8_t *key, uint8_t *msg, uint16_t len) +{ + uint8_t *m = msg; + uint32_t cnt = UNALIGNED_GET((uint32_t *)&msg[len]); + uint8_t *sig = msg + len; + uint8_t key_s[16], tmp[16]; + int err; + + BT_DBG("Signing msg %s len %u key %s", bt_hex(msg, len), len, + bt_hex(key, 16)); + + sys_mem_swap(m, len + sizeof(cnt)); + sys_memcpy_swap(key_s, key, 16); + + err = bt_smp_aes_cmac(key_s, m, len + sizeof(cnt), tmp); + if (err) { + BT_ERR("Data signing failed"); + return err; + } + + sys_mem_swap(tmp, sizeof(tmp)); + memcpy(tmp + 4, &cnt, sizeof(cnt)); + + /* Swap original message back */ + sys_mem_swap(m, len + sizeof(cnt)); + + memcpy(sig, tmp + 4, 12); + + BT_DBG("sig %s", bt_hex(sig, 12)); + + return 0; +} + +int bt_smp_sign_verify(struct bt_conn *conn, struct net_buf *buf) +{ + struct bt_keys *keys; + uint8_t sig[12]; + uint32_t cnt; + int err; + + /* Store signature incl. count */ + memcpy(sig, net_buf_tail(buf) - sizeof(sig), sizeof(sig)); + + keys = bt_keys_find(BT_KEYS_REMOTE_CSRK, &conn->le.dst); + if (!keys) { + BT_ERR("Unable to find Remote CSRK for %s", + bt_addr_le_str(&conn->le.dst)); + return -ENOENT; + } + + /* Copy signing count */ + cnt = sys_cpu_to_le32(keys->remote_csrk.cnt); + memcpy(net_buf_tail(buf) - sizeof(sig), &cnt, sizeof(cnt)); + + BT_DBG("Sign data len %zu key %s count %u", buf->len - sizeof(sig), + bt_hex(keys->remote_csrk.val, 16), keys->remote_csrk.cnt); + + err = smp_sign_buf(keys->remote_csrk.val, buf->data, + buf->len - sizeof(sig)); + if (err) { + BT_ERR("Unable to create signature for %s", + bt_addr_le_str(&conn->le.dst)); + return -EIO; + }; + + if (memcmp(sig, net_buf_tail(buf) - sizeof(sig), sizeof(sig))) { + BT_ERR("Unable to verify signature for %s", + bt_addr_le_str(&conn->le.dst)); + return -EBADMSG; + }; + + keys->remote_csrk.cnt++; + + return 0; +} + +int bt_smp_sign(struct bt_conn *conn, struct net_buf *buf) +{ + struct bt_keys *keys; + uint32_t cnt; + int err; + + keys = bt_keys_find(BT_KEYS_LOCAL_CSRK, &conn->le.dst); + if (!keys) { + BT_ERR("Unable to find local CSRK for %s", + bt_addr_le_str(&conn->le.dst)); + return -ENOENT; + } + + /* Reserve space for data signature */ + net_buf_add(buf, 12); + + /* Copy signing count */ + cnt = sys_cpu_to_le32(keys->local_csrk.cnt); + memcpy(net_buf_tail(buf) - 12, &cnt, sizeof(cnt)); + + BT_DBG("Sign data len %u key %s count %u", buf->len, + bt_hex(keys->local_csrk.val, 16), keys->local_csrk.cnt); + + err = smp_sign_buf(keys->local_csrk.val, buf->data, buf->len - 12); + if (err) { + BT_ERR("Unable to create signature for %s", + bt_addr_le_str(&conn->le.dst)); + return -EIO; + }; + + keys->local_csrk.cnt++; + + return 0; +} +#else +int bt_smp_sign_verify(struct bt_conn *conn, struct net_buf *buf) +{ + return -ENOTSUP; +} + +int bt_smp_sign(struct bt_conn *conn, struct net_buf *buf) +{ + return -ENOTSUP; +} +#endif /* CONFIG_BLUETOOTH_SIGNING */ + +#if defined(CONFIG_BLUETOOTH_SMP_SELFTEST) +/* Test vectors are taken from RFC 4493 + * https://tools.ietf.org/html/rfc4493 + * Same mentioned in the Bluetooth Spec. + */ +static const uint8_t key[] = { + 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c +}; + +static const uint8_t M[] = { + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, + 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, + 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, + 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, + 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 +}; + +static int aes_test(const char *prefix, const uint8_t *key, const uint8_t *m, + uint16_t len, const uint8_t *mac) +{ + uint8_t out[16]; + + BT_DBG("%s: AES CMAC of message with len %u", prefix, len); + + bt_smp_aes_cmac(key, m, len, out); + if (!memcmp(out, mac, 16)) { + BT_DBG("%s: Success", prefix); + } else { + BT_ERR("%s: Failed", prefix); + return -1; + } + + return 0; +} + +static int smp_aes_cmac_test(void) +{ + uint8_t mac1[] = { + 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28, + 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46 + }; + uint8_t mac2[] = { + 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44, + 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c + }; + uint8_t mac3[] = { + 0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6, 0x30, + 0x30, 0xca, 0x32, 0x61, 0x14, 0x97, 0xc8, 0x27 + }; + uint8_t mac4[] = { + 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92, + 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe + }; + int err; + + err = aes_test("Test aes-cmac0", key, M, 0, mac1); + if (err) { + return err; + } + + err = aes_test("Test aes-cmac16", key, M, 16, mac2); + if (err) { + return err; + } + + err = aes_test("Test aes-cmac40", key, M, 40, mac3); + if (err) { + return err; + } + + err = aes_test("Test aes-cmac64", key, M, 64, mac4); + if (err) { + return err; + } + + return 0; +} + +static int sign_test(const char *prefix, const uint8_t *key, const uint8_t *m, + uint16_t len, const uint8_t *sig) +{ + uint8_t msg[len + sizeof(uint32_t) + 8]; + uint8_t orig[len + sizeof(uint32_t) + 8]; + uint8_t *out = msg + len; + int err; + + BT_DBG("%s: Sign message with len %u", prefix, len); + + memset(msg, 0, sizeof(msg)); + memcpy(msg, m, len); + memset(msg + len, 0, sizeof(uint32_t)); + + memcpy(orig, msg, sizeof(msg)); + + err = smp_sign_buf(key, msg, len); + if (err) { + return err; + } + + /* Check original message */ + if (!memcmp(msg, orig, len + sizeof(uint32_t))) { + BT_DBG("%s: Original message intact", prefix); + } else { + BT_ERR("%s: Original message modified", prefix); + BT_DBG("%s: orig %s", prefix, bt_hex(orig, sizeof(orig))); + BT_DBG("%s: msg %s", prefix, bt_hex(msg, sizeof(msg))); + return -1; + } + + if (!memcmp(out, sig, 12)) { + BT_DBG("%s: Success", prefix); + } else { + BT_ERR("%s: Failed", prefix); + return -1; + } + + return 0; +} + +static int smp_sign_test(void) +{ + const uint8_t sig1[] = { + 0x00, 0x00, 0x00, 0x00, 0xb3, 0xa8, 0x59, 0x41, + 0x27, 0xeb, 0xc2, 0xc0 + }; + const uint8_t sig2[] = { + 0x00, 0x00, 0x00, 0x00, 0x27, 0x39, 0x74, 0xf4, + 0x39, 0x2a, 0x23, 0x2a + }; + const uint8_t sig3[] = { + 0x00, 0x00, 0x00, 0x00, 0xb7, 0xca, 0x94, 0xab, + 0x87, 0xc7, 0x82, 0x18 + }; + const uint8_t sig4[] = { + 0x00, 0x00, 0x00, 0x00, 0x44, 0xe1, 0xe6, 0xce, + 0x1d, 0xf5, 0x13, 0x68 + }; + uint8_t key_s[16]; + int err; + + /* Use the same key as aes-cmac but swap bytes */ + sys_memcpy_swap(key_s, key, 16); + + err = sign_test("Test sign0", key_s, M, 0, sig1); + if (err) { + return err; + } + + err = sign_test("Test sign16", key_s, M, 16, sig2); + if (err) { + return err; + } + + err = sign_test("Test sign40", key_s, M, 40, sig3); + if (err) { + return err; + } + + err = sign_test("Test sign64", key_s, M, 64, sig4); + if (err) { + return err; + } + + return 0; +} + +static int smp_f4_test(void) +{ + uint8_t u[32] = { 0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc, + 0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef, + 0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e, + 0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20 }; + uint8_t v[32] = { 0xfd, 0xc5, 0x7f, 0xf4, 0x49, 0xdd, 0x4f, 0x6b, + 0xfb, 0x7c, 0x9d, 0xf1, 0xc2, 0x9a, 0xcb, 0x59, + 0x2a, 0xe7, 0xd4, 0xee, 0xfb, 0xfc, 0x0a, 0x90, + 0x9a, 0xbb, 0xf6, 0x32, 0x3d, 0x8b, 0x18, 0x55 }; + uint8_t x[16] = { 0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff, + 0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5 }; + uint8_t z = 0x00; + uint8_t exp[16] = { 0x2d, 0x87, 0x74, 0xa9, 0xbe, 0xa1, 0xed, 0xf1, + 0x1c, 0xbd, 0xa9, 0x07, 0xf1, 0x16, 0xc9, 0xf2 }; + uint8_t res[16]; + int err; + + err = smp_f4(u, v, x, z, res); + if (err) { + return err; + } + + if (memcmp(res, exp, 16)) { + return -EINVAL; + } + + return 0; +} + +static int smp_f5_test(void) +{ + uint8_t w[32] = { 0x98, 0xa6, 0xbf, 0x73, 0xf3, 0x34, 0x8d, 0x86, + 0xf1, 0x66, 0xf8, 0xb4, 0x13, 0x6b, 0x79, 0x99, + 0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34, + 0x05, 0xad, 0xc8, 0x57, 0xa3, 0x34, 0x02, 0xec }; + uint8_t n1[16] = { 0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff, + 0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5 }; + uint8_t n2[16] = { 0xcf, 0xc4, 0x3d, 0xff, 0xf7, 0x83, 0x65, 0x21, + 0x6e, 0x5f, 0xa7, 0x25, 0xcc, 0xe7, 0xe8, 0xa6 }; + bt_addr_le_t a1 = { .type = 0x00, + .a.val = { 0xce, 0xbf, 0x37, 0x37, 0x12, 0x56 } }; + bt_addr_le_t a2 = { .type = 0x00, + .a.val = {0xc1, 0xcf, 0x2d, 0x70, 0x13, 0xa7 } }; + uint8_t exp_ltk[16] = { 0x38, 0x0a, 0x75, 0x94, 0xb5, 0x22, 0x05, + 0x98, 0x23, 0xcd, 0xd7, 0x69, 0x11, 0x79, + 0x86, 0x69 }; + uint8_t exp_mackey[16] = { 0x20, 0x6e, 0x63, 0xce, 0x20, 0x6a, 0x3f, + 0xfd, 0x02, 0x4a, 0x08, 0xa1, 0x76, 0xf1, + 0x65, 0x29 }; + uint8_t mackey[16], ltk[16]; + int err; + + err = smp_f5(w, n1, n2, &a1, &a2, mackey, ltk); + if (err) { + return err; + } + + if (memcmp(mackey, exp_mackey, 16) || memcmp(ltk, exp_ltk, 16)) { + return -EINVAL; + } + + return 0; +} + +static int smp_f6_test(void) +{ + uint8_t w[16] = { 0x20, 0x6e, 0x63, 0xce, 0x20, 0x6a, 0x3f, 0xfd, + 0x02, 0x4a, 0x08, 0xa1, 0x76, 0xf1, 0x65, 0x29 }; + uint8_t n1[16] = { 0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff, + 0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5 }; + uint8_t n2[16] = { 0xcf, 0xc4, 0x3d, 0xff, 0xf7, 0x83, 0x65, 0x21, + 0x6e, 0x5f, 0xa7, 0x25, 0xcc, 0xe7, 0xe8, 0xa6 }; + uint8_t r[16] = { 0xc8, 0x0f, 0x2d, 0x0c, 0xd2, 0x42, 0xda, 0x08, + 0x54, 0xbb, 0x53, 0xb4, 0x3b, 0x34, 0xa3, 0x12 }; + uint8_t io_cap[3] = { 0x02, 0x01, 0x01 }; + bt_addr_le_t a1 = { .type = 0x00, + .a.val = { 0xce, 0xbf, 0x37, 0x37, 0x12, 0x56 } }; + bt_addr_le_t a2 = { .type = 0x00, + .a.val = {0xc1, 0xcf, 0x2d, 0x70, 0x13, 0xa7 } }; + uint8_t exp[16] = { 0x61, 0x8f, 0x95, 0xda, 0x09, 0x0b, 0x6c, 0xd2, + 0xc5, 0xe8, 0xd0, 0x9c, 0x98, 0x73, 0xc4, 0xe3 }; + uint8_t res[16]; + int err; + + err = smp_f6(w, n1, n2, r, io_cap, &a1, &a2, res); + if (err) + return err; + + if (memcmp(res, exp, 16)) + return -EINVAL; + + return 0; +} + +static int smp_g2_test(void) +{ + uint8_t u[32] = { 0xe6, 0x9d, 0x35, 0x0e, 0x48, 0x01, 0x03, 0xcc, + 0xdb, 0xfd, 0xf4, 0xac, 0x11, 0x91, 0xf4, 0xef, + 0xb9, 0xa5, 0xf9, 0xe9, 0xa7, 0x83, 0x2c, 0x5e, + 0x2c, 0xbe, 0x97, 0xf2, 0xd2, 0x03, 0xb0, 0x20 }; + uint8_t v[32] = { 0xfd, 0xc5, 0x7f, 0xf4, 0x49, 0xdd, 0x4f, 0x6b, + 0xfb, 0x7c, 0x9d, 0xf1, 0xc2, 0x9a, 0xcb, 0x59, + 0x2a, 0xe7, 0xd4, 0xee, 0xfb, 0xfc, 0x0a, 0x90, + 0x9a, 0xbb, 0xf6, 0x32, 0x3d, 0x8b, 0x18, 0x55 }; + uint8_t x[16] = { 0xab, 0xae, 0x2b, 0x71, 0xec, 0xb2, 0xff, 0xff, + 0x3e, 0x73, 0x77, 0xd1, 0x54, 0x84, 0xcb, 0xd5 }; + uint8_t y[16] = { 0xcf, 0xc4, 0x3d, 0xff, 0xf7, 0x83, 0x65, 0x21, + 0x6e, 0x5f, 0xa7, 0x25, 0xcc, 0xe7, 0xe8, 0xa6 }; + uint32_t exp_val = 0x2f9ed5ba % 1000000; + uint32_t val; + int err; + + err = smp_g2(u, v, x, y, &val); + if (err) { + return err; + } + + if (val != exp_val) { + return -EINVAL; + } + + return 0; +} + +#if defined(CONFIG_BLUETOOTH_BREDR) +static int smp_h6_test(void) +{ + uint8_t w[16] = { 0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34, + 0x05, 0xad, 0xc8, 0x57, 0xa3, 0x34, 0x02, 0xec }; + uint8_t key_id[4] = { 0x72, 0x62, 0x65, 0x6c }; + uint8_t exp_res[16] = { 0x99, 0x63, 0xb1, 0x80, 0xe2, 0xa9, 0xd3, 0xe8, + 0x1c, 0xc9, 0x6d, 0xe7, 0x02, 0xe1, 0x9a, 0x2d}; + uint8_t res[16]; + int err; + + err = smp_h6(w, key_id, res); + if (err) { + return err; + } + + if (memcmp(res, exp_res, 16)) { + return -EINVAL; + } + + return 0; +} + +static int smp_h7_test(void) +{ + uint8_t salt[16] = { 0x31, 0x70, 0x6d, 0x74, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + uint8_t w[16] = { 0x9b, 0x7d, 0x39, 0x0a, 0xa6, 0x10, 0x10, 0x34, + 0x05, 0xad, 0xc8, 0x57, 0xa3, 0x34, 0x02, 0xec }; + uint8_t exp_res[16] = { 0x11, 0x70, 0xa5, 0x75, 0x2a, 0x8c, 0x99, 0xd2, + 0xec, 0xc0, 0xa3, 0xc6, 0x97, 0x35, 0x17, 0xfb}; + uint8_t res[16]; + int err; + + err = smp_h7(salt, w, res); + if (err) { + return err; + } + + if (memcmp(res, exp_res, 16)) { + return -EINVAL; + } + + return 0; +} +#endif /* CONFIG_BLUETOOTH_BREDR */ + +static int smp_self_test(void) +{ + int err; + + err = smp_aes_cmac_test(); + if (err) { + BT_ERR("SMP AES-CMAC self tests failed"); + return err; + } + + err = smp_sign_test(); + if (err) { + BT_ERR("SMP signing self tests failed"); + return err; + } + + err = smp_f4_test(); + if (err) { + BT_ERR("SMP f4 self test failed"); + return err; + } + + err = smp_f5_test(); + if (err) { + BT_ERR("SMP f5 self test failed"); + return err; + } + + err = smp_f6_test(); + if (err) { + BT_ERR("SMP f6 self test failed"); + return err; + } + + err = smp_g2_test(); + if (err) { + BT_ERR("SMP g2 self test failed"); + return err; + } + +#if defined(CONFIG_BLUETOOTH_BREDR) + err = smp_h6_test(); + if (err) { + BT_ERR("SMP h6 self test failed"); + return err; + } + + err = smp_h7_test(); + if (err) { + BT_ERR("SMP h7 self test failed"); + return err; + } +#endif /* CONFIG_BLUETOOTH_BREDR */ + + return 0; +} +#else +static inline int smp_self_test(void) +{ + return 0; +} +#endif + +int bt_smp_auth_passkey_entry(struct bt_conn *conn, unsigned int passkey) +{ + struct bt_smp *smp; + + smp = smp_chan_get(conn); + if (!smp) { + return -EINVAL; + } + + if (!atomic_test_and_clear_bit(smp->flags, SMP_FLAG_USER)) { + return -EINVAL; + } + +#if !defined(CONFIG_BLUETOOTH_SMP_SC_ONLY) + if (!atomic_test_bit(smp->flags, SMP_FLAG_SC)) { + legacy_passkey_entry(smp, passkey); + return 0; + } +#endif /* !CONFIG_BLUETOOTH_SMP_SC_ONLY */ + + smp->passkey = sys_cpu_to_le32(passkey); + + if (IS_ENABLED(CONFIG_BLUETOOTH_CENTRAL) && + smp->chan.chan.conn->role == BT_HCI_ROLE_MASTER) { + if (smp_send_pairing_confirm(smp)) { + smp_error(smp, BT_SMP_ERR_PASSKEY_ENTRY_FAILED); + return 0; + } + atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_PAIRING_CONFIRM); + return 0; + } + + if (IS_ENABLED(CONFIG_BLUETOOTH_PERIPHERAL) && + atomic_test_bit(smp->flags, SMP_FLAG_CFM_DELAYED)) { + if (smp_send_pairing_confirm(smp)) { + smp_error(smp, BT_SMP_ERR_PASSKEY_ENTRY_FAILED); + return 0; + } + atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_PAIRING_RANDOM); + } + + return 0; +} + +int bt_smp_auth_passkey_confirm(struct bt_conn *conn) +{ + struct bt_smp *smp; + + smp = smp_chan_get(conn); + if (!smp) { + return -EINVAL; + } + + if (!atomic_test_and_clear_bit(smp->flags, SMP_FLAG_USER)) { + return -EINVAL; + } + + /* wait for DHKey being generated */ + if (atomic_test_bit(smp->flags, SMP_FLAG_DHKEY_PENDING)) { + atomic_set_bit(smp->flags, SMP_FLAG_DHKEY_SEND); + return 0; + } + + /* wait for remote DHKey Check */ + if (atomic_test_bit(smp->flags, SMP_FLAG_DHCHECK_WAIT)) { + atomic_set_bit(smp->flags, SMP_FLAG_DHKEY_SEND); + return 0; + } + + if (atomic_test_bit(smp->flags, SMP_FLAG_DHKEY_SEND)) { + uint8_t err; + +#if defined(CONFIG_BLUETOOTH_CENTRAL) + if (smp->chan.chan.conn->role == BT_HCI_ROLE_MASTER) { + err = compute_and_send_master_dhcheck(smp); + if (err) { + smp_error(smp, err); + } + return 0; + } +#endif /* CONFIG_BLUETOOTH_CENTRAL */ + +#if defined(CONFIG_BLUETOOTH_PERIPHERAL) + err = compute_and_check_and_send_slave_dhcheck(smp); + if (err) { + smp_error(smp, err); + } +#endif /* CONFIG_BLUETOOTH_PERIPHERAL */ + } + + return 0; +} + +int bt_smp_auth_cancel(struct bt_conn *conn) +{ + struct bt_smp *smp; + + smp = smp_chan_get(conn); + if (!smp) { + return -EINVAL; + } + + if (!atomic_test_and_clear_bit(smp->flags, SMP_FLAG_USER)) { + return -EINVAL; + } + + switch (smp->method) { + case PASSKEY_INPUT: + case PASSKEY_DISPLAY: + return smp_error(smp, BT_SMP_ERR_PASSKEY_ENTRY_FAILED); + case PASSKEY_CONFIRM: + return smp_error(smp, BT_SMP_ERR_CONFIRM_FAILED); + case JUST_WORKS: + return smp_error(smp, BT_SMP_ERR_UNSPECIFIED); + default: + return 0; + } +} + +#if !defined(CONFIG_BLUETOOTH_SMP_SC_ONLY) +int bt_smp_auth_pairing_confirm(struct bt_conn *conn) +{ + struct bt_smp *smp; + + smp = smp_chan_get(conn); + if (!smp) { + return -EINVAL; + } + + if (!atomic_test_and_clear_bit(smp->flags, SMP_FLAG_USER)) { + return -EINVAL; + } + + if (IS_ENABLED(CONFIG_BLUETOOTH_CENTRAL) && + conn->role == BT_CONN_ROLE_MASTER) { + if (!atomic_test_bit(smp->flags, SMP_FLAG_SC)) { + atomic_set_bit(&smp->allowed_cmds, + BT_SMP_CMD_PAIRING_CONFIRM); + return legacy_send_pairing_confirm(smp); + } + + if (!sc_local_pkey_valid) { + atomic_set_bit(smp->flags, SMP_FLAG_PKEY_SEND); + return 0; + } + + atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_PUBLIC_KEY); + return sc_send_public_key(smp); + } + +#if defined(CONFIG_BLUETOOTH_PERIPHERAL) + if (!atomic_test_bit(smp->flags, SMP_FLAG_SC)) { + atomic_set_bit(&smp->allowed_cmds, + BT_SMP_CMD_PAIRING_CONFIRM); + return send_pairing_rsp(smp); + } + + atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_PUBLIC_KEY); + if (send_pairing_rsp(smp)) { + return -EIO; + } +#endif /* CONFIG_BLUETOOTH_PERIPHERAL */ + + return 0; +} +#else +int bt_smp_auth_pairing_confirm(struct bt_conn *conn) +{ + /* confirm_pairing will never be called in LE SC only mode */ + return -EINVAL; +} +#endif /* !CONFIG_BLUETOOTH_SMP_SC_ONLY */ + +void bt_smp_update_keys(struct bt_conn *conn) +{ + struct bt_smp *smp; + + smp = smp_chan_get(conn); + if (!smp) { + return; + } + + if (!atomic_test_bit(smp->flags, SMP_FLAG_PAIRING)) { + return; + } + + /* + * If link was successfully encrypted cleanup old keys as from now on + * only keys distributed in this pairing or LTK from LE SC will be used. + */ + if (conn->le.keys) { + bt_keys_clear(conn->le.keys); + } + + conn->le.keys = bt_keys_get_addr(&conn->le.dst); + if (!conn->le.keys) { + BT_ERR("Unable to get keys for %s", + bt_addr_le_str(&conn->le.dst)); + return; + } + + /* mark keys as debug */ + if (atomic_test_bit(smp->flags, SMP_FLAG_SC_DEBUG_KEY)) { + atomic_set_bit(conn->le.keys->flags, BT_KEYS_DEBUG); + } + + /* + * store key type deducted from pairing method used + * it is important to store it since type is used to determine + * security level upon encryption + */ + switch (smp->method) { + case PASSKEY_DISPLAY: + case PASSKEY_INPUT: + case PASSKEY_CONFIRM: + atomic_set_bit(conn->le.keys->flags, BT_KEYS_AUTHENTICATED); + break; + case JUST_WORKS: + default: + /* unauthenticated key, clear it */ + atomic_clear_bit(conn->le.keys->flags, BT_KEYS_AUTHENTICATED); + break; + } + + conn->le.keys->enc_size = get_encryption_key_size(smp); + + /* + * Store LTK if LE SC is used, this is safe since LE SC is mutually + * exclusive with legacy pairing. Other keys are added on keys + * distribution. + */ + if (atomic_test_bit(smp->flags, SMP_FLAG_SC) && + atomic_test_bit(smp->flags, SMP_FLAG_BOND)) { + bt_keys_add_type(conn->le.keys, BT_KEYS_LTK_P256); + memcpy(conn->le.keys->ltk.val, smp->tk, + sizeof(conn->le.keys->ltk.val)); + conn->le.keys->ltk.rand = 0; + conn->le.keys->ltk.ediv = 0; + } +} + +bool bt_smp_get_tk(struct bt_conn *conn, uint8_t *tk) +{ + struct bt_smp *smp; + uint8_t enc_size; + + smp = smp_chan_get(conn); + if (!smp) { + return false; + } + + if (!atomic_test_bit(smp->flags, SMP_FLAG_PAIRING)) { + return false; + } + + enc_size = get_encryption_key_size(smp); + + /* + * We keep both legacy STK and LE SC LTK in TK. + * Also use only enc_size bytes of key for encryption. + */ + memcpy(tk, smp->tk, enc_size); + if (enc_size < sizeof(smp->tk)) { + memset(tk + enc_size, 0, sizeof(smp->tk) - enc_size); + } + + return true; +} + +static int bt_smp_accept(struct bt_conn *conn, struct bt_l2cap_chan **chan) +{ + int i; + static struct bt_l2cap_chan_ops ops = { + .connected = bt_smp_connected, + .disconnected = bt_smp_disconnected, + .encrypt_change = bt_smp_encrypt_change, + .recv = bt_smp_recv, + }; + + BT_DBG("conn %p handle %u", conn, conn->handle); + + for (i = 0; i < ARRAY_SIZE(bt_smp_pool); i++) { + struct bt_smp *smp = &bt_smp_pool[i]; + + if (smp->chan.chan.conn) { + continue; + } + + smp->chan.chan.ops = &ops; + + *chan = &smp->chan.chan; + + return 0; + } + + BT_ERR("No available SMP context for conn %p", conn); + + return -ENOMEM; +} + +static bool le_sc_supported(void) +{ + /* + * If controller based ECC is to be used it must support + * "LE Read Local P-256 Public Key" and "LE Generate DH Key" commands. + * Otherwise LE SC are not supported. + */ + return (bt_dev.supported_commands[34] & 0x02) && + (bt_dev.supported_commands[34] & 0x04); +} + +int bt_smp_init(void) +{ + static struct bt_l2cap_fixed_chan chan = { + .cid = BT_L2CAP_CID_SMP, + .accept = bt_smp_accept, + }; + static struct bt_pub_key_cb pub_key_cb = { + .func = bt_smp_pkey_ready, + }; + + sc_supported = le_sc_supported(); + if (IS_ENABLED(CONFIG_BLUETOOTH_SMP_SC_ONLY) && !sc_supported) { + BT_ERR("SC Only Mode selected but LE SC not supported"); + return -ENOENT; + } + + bt_l2cap_le_fixed_chan_register(&chan); +#if defined(CONFIG_BLUETOOTH_BREDR) + /* Register BR/EDR channel only if BR/EDR SC is supported */ + if (br_sc_supported()) { + static struct bt_l2cap_fixed_chan br_chan = { + .cid = BT_L2CAP_CID_BR_SMP, + .accept = bt_smp_br_accept, + }; + + bt_l2cap_br_fixed_chan_register(&br_chan); + } +#endif + + BT_DBG("LE SC %s", sc_supported ? "enabled" : "disabled"); + + bt_pub_key_gen(&pub_key_cb); + + return smp_self_test(); +} diff --git a/kernel/protocols/bluetooth/host/smp.h b/kernel/protocols/bluetooth/host/smp.h new file mode 100644 index 0000000000..a4fe98f98f --- /dev/null +++ b/kernel/protocols/bluetooth/host/smp.h @@ -0,0 +1,157 @@ +/** + * @file smp.h + * Security Manager Protocol implementation header + */ + +/* + * Copyright (c) 2015-2016 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +struct bt_smp_hdr { + uint8_t code; +} __packed; + +#define BT_SMP_ERR_PASSKEY_ENTRY_FAILED 0x01 +#define BT_SMP_ERR_OOB_NOT_AVAIL 0x02 +#define BT_SMP_ERR_AUTH_REQUIREMENTS 0x03 +#define BT_SMP_ERR_CONFIRM_FAILED 0x04 +#define BT_SMP_ERR_PAIRING_NOTSUPP 0x05 +#define BT_SMP_ERR_ENC_KEY_SIZE 0x06 +#define BT_SMP_ERR_CMD_NOTSUPP 0x07 +#define BT_SMP_ERR_UNSPECIFIED 0x08 +#define BT_SMP_ERR_REPEATED_ATTEMPTS 0x09 +#define BT_SMP_ERR_INVALID_PARAMS 0x0a +#define BT_SMP_ERR_DHKEY_CHECK_FAILED 0x0b +#define BT_SMP_ERR_NUMERIC_COMP_FAILED 0x0c +#define BT_SMP_ERR_BREDR_PAIRING_IN_PROGRESS 0x0d +#define BT_SMP_ERR_CROSS_TRANSP_NOT_ALLOWED 0x0e + +#define BT_SMP_IO_DISPLAY_ONLY 0x00 +#define BT_SMP_IO_DISPLAY_YESNO 0x01 +#define BT_SMP_IO_KEYBOARD_ONLY 0x02 +#define BT_SMP_IO_NO_INPUT_OUTPUT 0x03 +#define BT_SMP_IO_KEYBOARD_DISPLAY 0x04 + +#define BT_SMP_OOB_NOT_PRESENT 0x00 +#define BT_SMP_OOB_PRESENT 0x01 + +#define BT_SMP_MIN_ENC_KEY_SIZE 7 +#define BT_SMP_MAX_ENC_KEY_SIZE 16 + +#define BT_SMP_DIST_ENC_KEY 0x01 +#define BT_SMP_DIST_ID_KEY 0x02 +#define BT_SMP_DIST_SIGN 0x04 +#define BT_SMP_DIST_LINK_KEY 0x08 + +#define BT_SMP_DIST_MASK 0x0f + +#define BT_SMP_AUTH_NONE 0x00 +#define BT_SMP_AUTH_BONDING 0x01 +#define BT_SMP_AUTH_MITM 0x04 +#define BT_SMP_AUTH_SC 0x08 +#define BT_SMP_AUTH_KEYPRESS 0x10 +#define BT_SMP_AUTH_CT2 0x20 + +#define BT_SMP_CMD_PAIRING_REQ 0x01 +#define BT_SMP_CMD_PAIRING_RSP 0x02 +struct bt_smp_pairing { + uint8_t io_capability; + uint8_t oob_flag; + uint8_t auth_req; + uint8_t max_key_size; + uint8_t init_key_dist; + uint8_t resp_key_dist; +} __packed; + +#define BT_SMP_CMD_PAIRING_CONFIRM 0x03 +struct bt_smp_pairing_confirm { + uint8_t val[16]; +} __packed; + +#define BT_SMP_CMD_PAIRING_RANDOM 0x04 +struct bt_smp_pairing_random { + uint8_t val[16]; +} __packed; + +#define BT_SMP_CMD_PAIRING_FAIL 0x05 +struct bt_smp_pairing_fail { + uint8_t reason; +} __packed; + +#define BT_SMP_CMD_ENCRYPT_INFO 0x06 +struct bt_smp_encrypt_info { + uint8_t ltk[16]; +} __packed; + +#define BT_SMP_CMD_MASTER_IDENT 0x07 +struct bt_smp_master_ident { + uint16_t ediv; + uint64_t rand; +} __packed; + +#define BT_SMP_CMD_IDENT_INFO 0x08 +struct bt_smp_ident_info { + uint8_t irk[16]; +} __packed; + +#define BT_SMP_CMD_IDENT_ADDR_INFO 0x09 +struct bt_smp_ident_addr_info { + bt_addr_le_t addr; +} __packed; + +#define BT_SMP_CMD_SIGNING_INFO 0x0a +struct bt_smp_signing_info { + uint8_t csrk[16]; +} __packed; + +#define BT_SMP_CMD_SECURITY_REQUEST 0x0b +struct bt_smp_security_request { + uint8_t auth_req; +} __packed; + +#define BT_SMP_CMD_PUBLIC_KEY 0x0c +struct bt_smp_public_key { + uint8_t x[32]; + uint8_t y[32]; +} __packed; + +#define BT_SMP_DHKEY_CHECK 0x0d +struct bt_smp_dhkey_check { + uint8_t e[16]; +} __packed; + +bool bt_smp_irk_matches(const uint8_t irk[16], const bt_addr_t *addr); +int bt_smp_create_rpa(const uint8_t irk[16], bt_addr_t *rpa); +int bt_smp_send_pairing_req(struct bt_conn *conn); +int bt_smp_send_security_req(struct bt_conn *conn); +void bt_smp_update_keys(struct bt_conn *conn); +bool bt_smp_get_tk(struct bt_conn *conn, uint8_t *tk); + +int bt_smp_br_send_pairing_req(struct bt_conn *conn); + +int bt_smp_init(void); + +int bt_smp_auth_passkey_entry(struct bt_conn *conn, unsigned int passkey); +int bt_smp_auth_passkey_confirm(struct bt_conn *conn); +int bt_smp_auth_pairing_confirm(struct bt_conn *conn); +int bt_smp_auth_cancel(struct bt_conn *conn); + +/** brief Verify signed message + * + * @param conn Bluetooth connection + * @param buf received packet buffer with message and signature + * + * @return 0 in success, error code otherwise + */ +int bt_smp_sign_verify(struct bt_conn *conn, struct net_buf *buf); + +/** brief Sign message + * + * @param conn Bluetooth connection + * @param buf message buffer + * + * @return 0 in success, error code otherwise + */ +int bt_smp_sign(struct bt_conn *conn, struct net_buf *buf); diff --git a/kernel/protocols/bluetooth/host/smp_null.c b/kernel/protocols/bluetooth/host/smp_null.c new file mode 100644 index 0000000000..fdce300168 --- /dev/null +++ b/kernel/protocols/bluetooth/host/smp_null.c @@ -0,0 +1,102 @@ +/** + * @file smp_null.c + * Security Manager Protocol stub + */ + +/* + * Copyright (c) 2015-2016 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HCI_CORE) +#include +#include +#include +#include + +#include "hci_core.h" +#include "conn_internal.h" +#include "l2cap_internal.h" +#include "smp.h" + +static struct bt_l2cap_le_chan bt_smp_pool[CONFIG_BLUETOOTH_MAX_CONN]; + +int bt_smp_sign_verify(struct bt_conn *conn, struct net_buf *buf) +{ + return -ENOTSUP; +} + +int bt_smp_sign(struct bt_conn *conn, struct net_buf *buf) +{ + return -ENOTSUP; +} + +static void bt_smp_recv(struct bt_l2cap_chan *chan, struct net_buf *buf) +{ + struct bt_conn *conn = chan->conn; + struct bt_smp_pairing_fail *rsp; + struct bt_smp_hdr *hdr; + + /* If a device does not support pairing then it shall respond with + * a Pairing Failed command with the reason set to "Pairing Not + * Supported" when any command is received. + * Core Specification Vol. 3, Part H, 3.3 + */ + + buf = bt_l2cap_create_pdu(NULL, 0); + /* NULL is not a possible return due to K_FOREVER */ + + hdr = net_buf_add(buf, sizeof(*hdr)); + hdr->code = BT_SMP_CMD_PAIRING_FAIL; + + rsp = net_buf_add(buf, sizeof(*rsp)); + rsp->reason = BT_SMP_ERR_PAIRING_NOTSUPP; + + bt_l2cap_send(conn, BT_L2CAP_CID_SMP, buf); +} + +static int bt_smp_accept(struct bt_conn *conn, struct bt_l2cap_chan **chan) +{ + int i; + static struct bt_l2cap_chan_ops ops = { + .recv = bt_smp_recv, + }; + + BT_DBG("conn %p handle %u", conn, conn->handle); + + for (i = 0; i < ARRAY_SIZE(bt_smp_pool); i++) { + struct bt_l2cap_le_chan *smp = &bt_smp_pool[i]; + + if (smp->chan.conn) { + continue; + } + + smp->chan.ops = &ops; + + *chan = &smp->chan; + + return 0; + } + + BT_ERR("No available SMP context for conn %p", conn); + + return -ENOMEM; +} + +int bt_smp_init(void) +{ + static struct bt_l2cap_fixed_chan chan = { + .cid = BT_L2CAP_CID_SMP, + .accept = bt_smp_accept, + }; + + bt_l2cap_le_fixed_chan_register(&chan); + + return 0; +} diff --git a/kernel/protocols/bluetooth/host/storage.c b/kernel/protocols/bluetooth/host/storage.c new file mode 100644 index 0000000000..89224cab9e --- /dev/null +++ b/kernel/protocols/bluetooth/host/storage.c @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2016 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include +#include +#include + +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HCI_CORE) +#include +#include +#include + +#define STORAGE_ROOT "/bt" + +/* Required file name length for full storage support. If the maximum + * file name length supported by the chosen file system is less than + * this value, then only local keys are supported (/bt/abcd). + */ +#define STORAGE_FILE_NAME_LEN 13 + +#if MAX_FILE_NAME >= STORAGE_FILE_NAME_LEN +/* /bt/aabbccddeeff0/abcd */ +#define STORAGE_PATH_MAX 23 +#else +/* /bt/abcd */ +#define STORAGE_PATH_MAX 9 +#endif + +enum storage_access { + STORAGE_READ, + STORAGE_WRITE +}; + +static int storage_open(const bt_addr_le_t *addr, uint16_t key, + enum storage_access access, fs_file_t *file) +{ + char path[STORAGE_PATH_MAX]; + + if (addr) { +#if MAX_FILE_NAME >= STORAGE_FILE_NAME_LEN + int len; + + len = snprintk(path, sizeof(path), + STORAGE_ROOT "/%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X%u", + addr->a.val[5], addr->a.val[4], addr->a.val[3], + addr->a.val[2], addr->a.val[1], addr->a.val[0], + addr->type); + + /* Create the subdirectory if necessary */ + if (access == STORAGE_WRITE) { + struct fs_dirent entry; + int err; + + err = fs_stat(path, &entry); + if (err) { + err = fs_mkdir(path); + if (err) { + return err; + } + } + } + + snprintk(path + len, sizeof(path) - len, "/%04x", key); +#else + return -ENAMETOOLONG; +#endif + } else { + snprintk(path, sizeof(path), STORAGE_ROOT "/%04x", key); + } + + return fs_open(file, path); +} + +static ssize_t storage_read(const bt_addr_le_t *addr, uint16_t key, void *data, + size_t length) +{ + fs_file_t file; + ssize_t ret; + + ret = storage_open(addr, key, STORAGE_READ, &file); + if (ret) { + return ret; + } + + ret = fs_read(&file, data, length); + fs_close(&file); + + return ret; +} + +static ssize_t storage_write(const bt_addr_le_t *addr, uint16_t key, + const void *data, size_t length) +{ + fs_file_t file; + ssize_t ret; + + ret = storage_open(addr, key, STORAGE_WRITE, &file); + if (ret) { + return ret; + } + + ret = fs_write(&file, data, length); + fs_close(&file); + + return ret; +} + +static int unlink_recursive(char path[STORAGE_PATH_MAX]) +{ + size_t path_len; + fs_dir_t dir; + int err; + + err = fs_opendir(&dir, path); + if (err) { + return err; + } + + /* We calculate this up-front so we can keep reusing the same + * buffer for the path when recursing. + */ + path_len = strlen(path); + + while (1) { + struct fs_dirent entry; + + err = fs_readdir(&dir, &entry); + if (err) { + break; + } + + if (entry.name[0] == '\0') { + break; + } + + snprintk(path + path_len, STORAGE_PATH_MAX - path_len, "/%s", + entry.name); + + if (entry.type == FS_DIR_ENTRY_DIR) { + err = unlink_recursive(path); + } else { + err = fs_unlink(path); + } + + if (err) { + break; + } + } + + fs_closedir(&dir); + + /* Return to the original value */ + path[path_len] = '\0'; + + fs_unlink(path); + + return err; +} + +static int storage_clear(const bt_addr_le_t *addr) +{ + char path[STORAGE_PATH_MAX]; + int err; + + if (addr) { +#if MAX_FILE_NAME >= STORAGE_FILE_NAME_LEN + snprintk(path, STORAGE_PATH_MAX, + STORAGE_ROOT "/%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X%u", + addr->a.val[5], addr->a.val[4], addr->a.val[3], + addr->a.val[2], addr->a.val[1], addr->a.val[0], + addr->type); + + return unlink_recursive(path); +#else + return -ENAMETOOLONG; +#endif + } + + /* unlink_recursive() uses the given path as a buffer for + * constructing sub-paths, so we can't give it a string literal + * such as STORAGE_ROOT directly. + */ + strcpy(path, STORAGE_ROOT); + + err = unlink_recursive(path); + if (err) { + return err; + } + + return fs_mkdir(STORAGE_ROOT); +} + +static int storage_init(struct device *unused) +{ + static const struct bt_storage storage = { + .read = storage_read, + .write = storage_write, + .clear = storage_clear + }; + struct fs_dirent entry; + int err; + + err = fs_stat(STORAGE_ROOT, &entry); + if (err) { + BT_WARN("%s doesn't seem to exist (err %d). Creating it.", + STORAGE_ROOT, err); + + err = fs_mkdir(STORAGE_ROOT); + if (err) { + BT_ERR("Unable to create %s (err %d)", + STORAGE_ROOT, err); + return err; + } + } + + bt_storage_register(&storage); + + return 0; +} + +SYS_INIT(storage_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); diff --git a/kernel/protocols/bluetooth/host/uuid.c b/kernel/protocols/bluetooth/host/uuid.c new file mode 100644 index 0000000000..52e12b987d --- /dev/null +++ b/kernel/protocols/bluetooth/host/uuid.c @@ -0,0 +1,120 @@ +/* uuid.c - Bluetooth UUID handling */ + +/* + * Copyright (c) 2015-2016 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#include + +#define UUID_16_BASE_OFFSET 12 + +/* TODO: Decide whether to continue using BLE format or switch to RFC 4122 */ + +/* Base UUID : 0000[0000]-0000-1000-8000-00805F9B34FB -> + * { 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, + * 0x00, 0x10, 0x00, 0x00, [0x00, 0x00], 0x00, 0x00 } + * 0x2800 : 0000[2800]-0000-1000-8000-00805F9B34FB -> + * { 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, + * 0x00, 0x10, 0x00, 0x00, [0x00, 0x28], 0x00, 0x00 } + * little endian 0x2800 : [00 28] -> no swapping required + * big endian 0x2800 : [28 00] -> swapping required + */ +static const struct bt_uuid_128 uuid128_base = { + .uuid.type = BT_UUID_TYPE_128, + .val = { 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, +}; + +static void uuid_to_uuid128(const struct bt_uuid *src, struct bt_uuid_128 *dst) +{ + switch (src->type) { + case BT_UUID_TYPE_16: + *dst = uuid128_base; + sys_put_le16(BT_UUID_16(src)->val, + &dst->val[UUID_16_BASE_OFFSET]); + return; + case BT_UUID_TYPE_32: + *dst = uuid128_base; + sys_put_le32(BT_UUID_32(src)->val, + &dst->val[UUID_16_BASE_OFFSET]); + return; + case BT_UUID_TYPE_128: + memcpy(dst, src, sizeof(*dst)); + return; + } +} + +static int uuid128_cmp(const struct bt_uuid *u1, const struct bt_uuid *u2) +{ + struct bt_uuid_128 uuid1, uuid2; + + uuid_to_uuid128(u1, &uuid1); + uuid_to_uuid128(u2, &uuid2); + + return memcmp(uuid1.val, uuid2.val, 16); +} + +int bt_uuid_cmp(const struct bt_uuid *u1, const struct bt_uuid *u2) +{ + /* Convert to 128 bit if types don't match */ + if (u1->type != u2->type) + return uuid128_cmp(u1, u2); + + switch (u1->type) { + case BT_UUID_TYPE_16: + return (int)BT_UUID_16(u1)->val - (int)BT_UUID_16(u2)->val; + case BT_UUID_TYPE_32: + return (int)BT_UUID_32(u1)->val - (int)BT_UUID_32(u2)->val; + case BT_UUID_TYPE_128: + return memcmp(BT_UUID_128(u1)->val, BT_UUID_128(u2)->val, 16); + } + + return -EINVAL; +} + +#if defined(CONFIG_BLUETOOTH_DEBUG) +void bt_uuid_to_str(const struct bt_uuid *uuid, char *str, size_t len) +{ + uint32_t tmp1, tmp5; + uint16_t tmp0, tmp2, tmp3, tmp4; + + switch (uuid->type) { + case BT_UUID_TYPE_16: + snprintk(str, len, "%04x", BT_UUID_16(uuid)->val); + break; + case BT_UUID_TYPE_32: + snprintk(str, len, "%04x", BT_UUID_32(uuid)->val); + break; + case BT_UUID_TYPE_128: + memcpy(&tmp0, &BT_UUID_128(uuid)->val[0], sizeof(tmp0)); + memcpy(&tmp1, &BT_UUID_128(uuid)->val[2], sizeof(tmp1)); + memcpy(&tmp2, &BT_UUID_128(uuid)->val[6], sizeof(tmp2)); + memcpy(&tmp3, &BT_UUID_128(uuid)->val[8], sizeof(tmp3)); + memcpy(&tmp4, &BT_UUID_128(uuid)->val[10], sizeof(tmp4)); + memcpy(&tmp5, &BT_UUID_128(uuid)->val[12], sizeof(tmp5)); + + snprintk(str, len, "%08x-%04x-%04x-%04x-%08x%04x", + tmp5, tmp4, tmp3, tmp2, tmp1, tmp0); + break; + default: + memset(str, 0, len); + return; + } +} + +const char *bt_uuid_str(const struct bt_uuid *uuid) +{ + static char str[37]; + + bt_uuid_to_str(uuid, str, sizeof(str)); + + return str; +} +#endif /* CONFIG_BLUETOOTH_DEBUG */ diff --git a/kernel/protocols/bluetooth/include/aos_bt_ble.h b/kernel/protocols/bluetooth/include/aos_bt_ble.h deleted file mode 100644 index a0cf204576..0000000000 --- a/kernel/protocols/bluetooth/include/aos_bt_ble.h +++ /dev/null @@ -1,706 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#ifndef _AOS_BT_BLE_H_ -#define _AOS_BT_BLE_H_ - -#include -#include "aos_bt_dev.h" - -#define CHNL_MAP_LEN 5 -typedef uint8_t aos_bt_ble_chnl_map_t[CHNL_MAP_LEN]; - -/* Scan modes */ -enum aos_bt_ble_scan_mode_e { - BTM_BLE_SCAN_MODE_PASSIVE = 0, /* Passive scan mode */ - BTM_BLE_SCAN_MODE_ACTIVE = 1, /* Active scan mode */ - BTM_BLE_SCAN_MODE_NONE = 0xff /* None */ -}; - -/* scan mode (see #aos_bt_ble_scan_mode_e) */ -typedef uint8_t aos_bt_ble_scan_mode_t; - -/* Scan filter policy */ -enum aos_bt_ble_scan_filter_policy_e { - /* Not use White List for Scanning Procedure. */ - BTM_BLE_SCAN_FILTER_POLICY_NONE = 0, - /* Use White List for Scanning Procedure. */ - BTM_BLE_SCAN_FILTER_POLICY_WHITE_LIST = 1, -}; - -/* scan filter policy (see #aos_bt_ble_scan_filter_policy_e) */ -typedef uint8_t aos_bt_ble_scan_filter_policy_t; - -/* advertising channel map */ -enum aos_bt_ble_advert_chnl_map_e { - BTM_BLE_ADVERT_CHNL_37 = (0x01 << 0), /* ADV channel */ - BTM_BLE_ADVERT_CHNL_38 = (0x01 << 1), /* ADV channel */ - BTM_BLE_ADVERT_CHNL_39 = (0x01 << 2) /* ADV channel */ -}; - -/* BLE advertisement channel map (see #aos_bt_ble_advert_chnl_map_e) */ -typedef uint8_t aos_bt_ble_advert_chnl_map_t; - -/* default advertising channel map */ -#ifndef BTM_BLE_DEFAULT_ADVERT_CHNL_MAP -#define BTM_BLE_DEFAULT_ADVERT_CHNL_MAP (BTM_BLE_ADVERT_CHNL_37| \ - BTM_BLE_ADVERT_CHNL_38| \ - BTM_BLE_ADVERT_CHNL_39) -#endif - -/* Advertising filter policy */ -enum aos_bt_ble_advert_filter_policy_e { - /* - * Process scan and connection requests from all devices - * (i.e., the White List is not in use) (default). - */ - BTM_BLE_ADVERT_FILTER_ALL_CONNECTION_REQ_ALL_SCAN_REQ = 0x00, - /* - * Process connection requests from all devices and only scan - * requests from devices that are in the White List. - */ - BTM_BLE_ADVERT_FILTER_ALL_CONNECTION_REQ_WHITELIST_SCAN_REQ = 0x01, - /* - * Process scan requests from all devices and only connection - * requests from devices that are in the White List. - */ - BTM_BLE_ADVERT_FILTER_WHITELIST_CONNECTION_REQ_ALL_SCAN_REQ = 0x02, - /* - * Process scan and connection requests only from devices - * in the White List. - */ - BTM_BLE_ADVERT_FILTER_WHITELIST_CONNECTION_REQ_WHITELIST_SCAN_REQ = 0x03, - BTM_BLE_ADVERT_FILTER_MAX -}; - -/* Advertising filter policy (see #aos_bt_ble_advert_filter_policy_e) */ -typedef uint8_t aos_bt_ble_advert_filter_policy_t; - -/* default advertising filter policy */ -#define BTM_BLE_ADVERT_FILTER_DEFAULT BTM_BLE_ADVERT_FILTER_ALL_CONNECTION_REQ_ALL_SCAN_REQ - -/* adv parameter boundary values */ -#define BTM_BLE_ADVERT_INTERVAL_MIN 0x0020 -#define BTM_BLE_ADVERT_INTERVAL_MAX 0x4000 - -/* connection parameter boundary values */ -#define BTM_BLE_SCAN_INTERVAL_MIN 0x0004 -#define BTM_BLE_SCAN_INTERVAL_MAX 0x4000 -#define BTM_BLE_SCAN_WINDOW_MIN 0x0004 -#define BTM_BLE_SCAN_WINDOW_MAX 0x4000 -#define BTM_BLE_CONN_INTERVAL_MIN 0x0006 -#define BTM_BLE_CONN_INTERVAL_MAX 0x0C80 -#define BTM_BLE_CONN_LATENCY_MAX 500 -#define BTM_BLE_CONN_SUP_TOUT_MIN 0x000A -#define BTM_BLE_CONN_SUP_TOUT_MAX 0x0C80 -#define BTM_BLE_CONN_PARAM_UNDEF 0xffff -#define BTM_BLE_CONN_SUP_TOUT_DEF 700 - -/* - * Default connection parameters if not configured, - * use GAP recommend value for auto/selective connection. - */ - -/* default scan interval */ -#define BTM_BLE_SCAN_FAST_INTERVAL 96 /* 30 ~ 60 ms (use 60) = 96 *0.625 */ - -/* - * Default scan window for background connection, - * applicable for auto connection or selective conenction. - */ -#define BTM_BLE_SCAN_FAST_WINDOW 48 /* 30 ms = 48 *0.625 */ - -/* default scan paramter used in reduced power cycle (background scanning) */ -#define BTM_BLE_SCAN_SLOW_INTERVAL_1 2048 /* 1.28 s = 2048 *0.625 */ - -#define BTM_BLE_SCAN_SLOW_WINDOW_1 18 /* 11.25 ms = 18 *0.625 */ - -/* default scan paramter used in reduced power cycle (background scanning) */ -#define BTM_BLE_SCAN_SLOW_INTERVAL_2 4096 /* 2.56 s = 4096 *0.625 */ - -#define BTM_BLE_SCAN_SLOW_WINDOW_2 36 /* 22.5 ms = 36 *0.625 */ - -/* default connection interval min */ -#define BTM_BLE_CONN_INTERVAL_MIN_DEF 24 /* recommended min: 30ms = 24 * 1.25 */ - -/* default connectino interval max */ -#define BTM_BLE_CONN_INTERVAL_MAX_DEF 40 /* recommended max: 50 ms = 56 * 1.25 */ - -/* default slave latency */ -#define BTM_BLE_CONN_SLAVE_LATENCY_DEF 0 /* 0 */ - -/* default supervision timeout */ -#define BTM_BLE_CONN_TIMEOUT_DEF 2000 - -#define BTM_BLE_DIR_CONN_FALLBACK_UNDIR 1 -#define BTM_BLE_DIR_CONN_FALLBACK_NO_ADV 2 - -#define BTM_BLE_DIR_CONN_FALLBACK BTM_BLE_DIR_CONN_FALLBACK_UNDIR - -/* BLE Signature */ -/* BLE data signature length 8 Bytes + 4 bytes counter*/ -#define BTM_BLE_AUTH_SIGNATURE_SIZE 12 -/* Device address (see #BTM_BLE_AUTH_SIGNATURE_SIZE) */ -typedef uint8_t aos_dev_ble_signature_t[BTM_BLE_AUTH_SIGNATURE_SIZE]; - -#define BTM_BLE_POLICY_BLACK_ALL 0x00 /* relevant to both */ -#define BTM_BLE_POLICY_ALLOW_SCAN 0x01 /* relevant to advertiser */ -#define BTM_BLE_POLICY_ALLOW_CONN 0x02 /* relevant to advertiser */ -#define BTM_BLE_POLICY_WHITE_ALL 0x03 /* relevant to both */ - -/* ADV data flag bit definition used for BTM_BLE_ADVERT_TYPE_FLAG */ -#define BTM_BLE_LIMITED_DISCOVERABLE_FLAG (0x01 << 0) -#define BTM_BLE_GENERAL_DISCOVERABLE_FLAG (0x01 << 1) -#define BTM_BLE_BREDR_NOT_SUPPORTED (0x01 << 2) - -/* 4.1 spec adv flag for simultaneous BR/EDR+LE connection support (see) */ -/* Simultaneous LE and BR/EDR to Same Device Capable (Controller). */ -#define BTM_BLE_SIMULTANEOUS_DUAL_MODE_TO_SAME_DEVICE_CONTROLLER_SUPPORTED (0x01 << 3) -/* Simultaneous LE and BR/EDR to Same Device Capable (Host). */ -#define BTM_BLE_SIMULTANEOUS_DUAL_MODE_TO_SAME_DEVICE_HOST_SUPPORTED (0x01 << 4) - /* lowest bit unset */ -#define BTM_BLE_NON_LIMITED_DISCOVERABLE_FLAG (0x00 ) -#define BTM_BLE_ADVERT_FLAG_MASK (BTM_BLE_LIMITED_DISCOVERABLE_FLAG | \ - BTM_BLE_BREDR_NOT_SUPPORTED | \ - BTM_BLE_GENERAL_DISCOVERABLE_FLAG) -#define BTM_BLE_LIMITED_DISCOVERABLE_MASK (BTM_BLE_LIMITED_DISCOVERABLE_FLAG) - -/* Advertisement Data bit masks */ -enum aos_bt_ble_advert_mask_e { - BTM_BLE_ADVERT_BIT_DEV_NAME = (0x00000001 << 0), /* Device Name */ - BTM_BLE_ADVERT_BIT_FLAGS = (0x00000001 << 1), /* Flags */ - BTM_BLE_ADVERT_BIT_MANUFACTURER = (0x00000001 << 2), /* Manufacturer Specific Data */ - BTM_BLE_ADVERT_BIT_TX_POWER = (0x00000001 << 3), /* Transmit Power Level */ - BTM_BLE_ADVERT_BIT_INTERVAL_RANGE = (0x00000001 << 5), /* Slave preferred connection interval range */ - BTM_BLE_ADVERT_BIT_SERVICE = (0x00000001 << 6), /* Service UUID (16-bit) */ - BTM_BLE_ADVERT_BIT_SERVICE_SOLICITATION = (0x00000001 << 7), /* Service Solicitation (16-bit) */ - BTM_BLE_ADVERT_BIT_SERVICE_DATA = (0x00000001 << 8), /* Service Data */ - BTM_BLE_ADVERT_BIT_SIGN_DATA = (0x00000001 << 9), /* Signed data */ - BTM_BLE_ADVERT_BIT_SERVICE_128SOLICITATION = (0x00000001 << 10), /* Service Solicitation (128-bit) */ - BTM_BLE_ADVERT_BIT_APPEARANCE = (0x00000001 << 11), /* Appearance */ - BTM_BLE_ADVERT_BIT_PUBLIC_ADDR = (0x00000001 << 12), /* Public Target Address */ - BTM_BLE_ADVERT_BIT_RANDOM_ADDR = (0x00000001 << 13), /* Random Target Address */ - BTM_BLE_ADVERT_BIT_SERVICE_32 = (0x00000001 << 4), /* Service UUIDs (32-bit) */ - BTM_BLE_ADVERT_BIT_SERVICE_32SOLICITATION = (0x00000001 << 14), /* Service Solicitation (32-bit) */ - BTM_BLE_ADVERT_BIT_PROPRIETARY = (0x00000001 << 15), /* Priorpietary */ - BTM_BLE_ADVERT_BIT_SERVICE_128 = (0x00000001 << 16) /* Service UUIDs (128-bit) */ -}; -typedef uint32_t aos_bt_ble_advert_mask_t; /* BLE advertisement mask (see #aos_bt_ble_advert_mask_e) */ - -/* Advertisement data types */ -enum aos_bt_ble_advert_type_e { - BTM_BLE_ADVERT_TYPE_FLAG = 0x01, /* Advertisement flags */ - BTM_BLE_ADVERT_TYPE_16SRV_PARTIAL = 0x02, /* List of supported services - 16 bit UUIDs (partial) */ - BTM_BLE_ADVERT_TYPE_16SRV_COMPLETE = 0x03, /* List of supported services - 16 bit UUIDs (complete) */ - BTM_BLE_ADVERT_TYPE_32SRV_PARTIAL = 0x04, /* List of supported services - 32 bit UUIDs (partial) */ - BTM_BLE_ADVERT_TYPE_32SRV_COMPLETE = 0x05, /* List of supported services - 32 bit UUIDs (complete) */ - BTM_BLE_ADVERT_TYPE_128SRV_PARTIAL = 0x06, /* List of supported services - 128 bit UUIDs (partial) */ - BTM_BLE_ADVERT_TYPE_128SRV_COMPLETE = 0x07, /* List of supported services - 128 bit UUIDs (complete) */ - BTM_BLE_ADVERT_TYPE_NAME_SHORT = 0x08, /* Short name */ - BTM_BLE_ADVERT_TYPE_NAME_COMPLETE = 0x09, /* Complete name */ - BTM_BLE_ADVERT_TYPE_TX_POWER = 0x0A, /* TX Power level */ - BTM_BLE_ADVERT_TYPE_DEV_CLASS = 0x0D, /* Device Class */ - BTM_BLE_ADVERT_TYPE_SM_TK = 0x10, /* Security manager TK value */ - BTM_BLE_ADVERT_TYPE_SM_OOB_FLAG = 0x11, /* Security manager Out-of-Band data */ - BTM_BLE_ADVERT_TYPE_INTERVAL_RANGE = 0x12, /* Slave connection interval range */ - BTM_BLE_ADVERT_TYPE_SOLICITATION_SRV_UUID = 0x14, /* List of solicitated services - 16 bit UUIDs */ - BTM_BLE_ADVERT_TYPE_128SOLICITATION_SRV_UUID = 0x15, /* List of solicitated services - 128 bit UUIDs */ - BTM_BLE_ADVERT_TYPE_SERVICE_DATA = 0x16, /* Service data - 16 bit UUID */ - BTM_BLE_ADVERT_TYPE_PUBLIC_TARGET = 0x17, /* Public target address */ - BTM_BLE_ADVERT_TYPE_RANDOM_TARGET = 0x18, /* Random target address */ - BTM_BLE_ADVERT_TYPE_APPEARANCE = 0x19, /* Appearance */ - BTM_BLE_ADVERT_TYPE_ADVERT_INTERVAL = 0x1a, /* Advertising interval */ - BTM_BLE_ADVERT_TYPE_32SOLICITATION_SRV_UUID = 0x1b, /* List of solicitated services - 32 bit UUIDs */ - BTM_BLE_ADVERT_TYPE_32SERVICE_DATA = 0x1c, /* Service data - 32 bit UUID */ - BTM_BLE_ADVERT_TYPE_128SERVICE_DATA = 0x1d, /* Service data - 128 bit UUID */ - BTM_BLE_ADVERT_TYPE_MANUFACTURER = 0xFF /* Manufacturer data */ -}; -typedef uint8_t aos_bt_ble_advert_type_t; /* BLE advertisement data type (see #aos_bt_ble_advert_type_e) */ - -/* security settings used with L2CAP LE COC */ -enum aos_bt_ble_sec_flags_e { - BTM_SEC_LE_LINK_ENCRYPTED = 0x01, /* Link encrypted */ - BTM_SEC_LE_LINK_PAIRED_WITHOUT_MITM = 0x02, /* Paired without man-in-the-middle protection */ - BTM_SEC_LE_LINK_PAIRED_WITH_MITM = 0x04 /* Link with man-in-the-middle protection */ -}; - -/* Slave preferred connection interval range */ -typedef struct { - uint16_t low; /* Preferred low connection interval */ - uint16_t hi; /* Preferred high connection interval */ -} aos_bt_ble_int_range_t; - -/* Service tag supported in the device */ -typedef struct { - uint8_t num_service; /* Number of services */ - aos_bool_t list_cmpl; /* Complete list or not */ - uint16_t *p_uuid; /* 16-bit UUID data */ -} aos_bt_ble_service_t; - -/* 32 bits Service supported in the device */ -typedef struct { - uint8_t num_service; /* Number of services */ - aos_bool_t list_cmpl; /* Complete list or not */ - uint32_t *p_uuid; /* 32-bit UUID data */ -} aos_bt_ble_32service_t; - -/* 128 bits Service supported in the device */ -typedef struct { - aos_bool_t list_cmpl; /* Complete list or not */ - uint8_t uuid128[MAX_UUID_SIZE]; /* 128-bit UUID data */ -} aos_bt_ble_128service_t; - -/* Manufacturer data supported in the device */ -typedef struct { - uint8_t len; /* Length of manufacturer data */ - uint8_t *p_val; /* Manufacturer data */ -} aos_bt_ble_manu_t; - -/* Service data supported in the device */ -typedef struct { - aos_bt_uuid_t service_uuid; /* Service UUID data */ - uint8_t len; /* Service UUID length */ - uint8_t *p_val; /* Service data value */ -} aos_bt_ble_service_data_t; - -/* Proprietary data element supported in the device */ -typedef struct { - uint8_t advert_type; /* Advertisement type */ - uint8_t len; /* Advertisement length */ - uint8_t *p_val; /* Element data */ -} aos_bt_ble_prop_elem_t; - -/* Proprietary data elements structure supported in the device */ -typedef struct { - uint8_t num_elem; /* Number of elements */ - aos_bt_ble_prop_elem_t *p_elem; /* Proprietary elements */ -} aos_bt_ble_proprietary_t; - -/* Advertising data */ -typedef struct { - /* slave preferred connection interval range (BTM_BLE_ADVERT_BIT_INTERVAL_RANGE) */ - aos_bt_ble_int_range_t int_range; - /* manufacturer data (BTM_BLE_ADVERT_BIT_MANUFACTURER) */ - aos_bt_ble_manu_t *p_manu; - /* list of supported services - 16 bit UUIDs (BTM_BLE_ADVERT_BIT_SERVICE) */ - aos_bt_ble_service_t *p_services; - /* list of supported services - 128 bit UUIDs (BTM_BLE_ADVERT_BIT_SERVICE_128) */ - aos_bt_ble_128service_t *p_services_128b; - /* list of supported services - 32 bit UUIDs (BTM_BLE_ADVERT_BIT_SERVICE_32) */ - aos_bt_ble_32service_t *p_service_32b; - /* list of solicited services - 16 bit UUIDs (BTM_BLE_ADVERT_BIT_SERVICE_SOLICITATION) */ - aos_bt_ble_service_t *p_sol_services; - /* list of solicited services - 32 bit UUIDs (BTM_BLE_ADVERT_BIT_SERVICE_32SOLICITATION) */ - aos_bt_ble_32service_t *p_sol_service_32b; - /* list of solicited services - 128 bit UUIDs (BTM_BLE_ADVERT_BIT_SERVICE_128SOLICITATION) */ - aos_bt_ble_128service_t *p_sol_service_128b; - /* list of proprietary data elements (BTM_BLE_ADVERT_BIT_PROPRIETARY) */ - aos_bt_ble_proprietary_t *p_proprietary; - /* service data (BTM_BLE_ADVERT_BIT_SERVICE_DATA) */ - aos_bt_ble_service_data_t *p_service_data; - /* appearance (BTM_BLE_ADVERT_BIT_APPEARANCE) */ - uint16_t appearance; - /* flag (BTM_BLE_ADVERT_BIT_FLAGS) */ - uint8_t flag; - /* transmit power (BTM_BLE_ADVERT_BIT_TX_POWER) */ - uint8_t tx_power; -} aos_bt_ble_advert_data_t; - -/* Scan result event type */ -enum aos_bt_dev_ble_evt_type_e { - BTM_BLE_EVT_CONNECTABLE_ADVERTISEMENT = 0x00, /* Connectable advertisement */ - BTM_BLE_EVT_CONNECTABLE_DIRECTED_ADVERTISEMENT = 0x01, /* Connectable Directed advertisement */ - BTM_BLE_EVT_SCANNABLE_ADVERTISEMENT = 0x02, /* Scannable advertisement */ - BTM_BLE_EVT_NON_CONNECTABLE_ADVERTISEMENT = 0x03, /* Non connectable advertisement */ - BTM_BLE_EVT_SCAN_RSP = 0x04 /* Scan response */ -}; -/* Scan result event value (see #aos_bt_dev_ble_evt_type_e) */ -typedef uint8_t aos_bt_dev_ble_evt_type_t; - -/* Background connection type */ -enum aos_bt_ble_conn_type_e { - BTM_BLE_CONN_NONE, /* No background connection */ - BTM_BLE_CONN_AUTO, /* Auto connection */ - BTM_BLE_CONN_SELECTIVE /* Selective connection */ -}; -/* Connection type (see #aos_bt_ble_conn_type_e) */ -typedef uint8_t aos_bt_ble_conn_type_t; - -/* LE inquiry result type */ -typedef struct { - aos_bt_device_address_t remote_bd_addr; /* Device address */ - uint8_t ble_addr_type; /* LE Address type */ - aos_bt_dev_ble_evt_type_t ble_evt_type; /* Scan result event type */ - int8_t rssi; /* Set to #BTM_INQ_RES_IGNORE_RSSI, if not valid */ - uint8_t flag; - uint8_t length; -} aos_bt_ble_scan_results_t; - -/* - * Callback aos_bt_ble_selective_conn_cback_t - * - * Selective connection callback (registered with #aos_bt_ble_set_background_connection_type) - * - * @param remote_bda : remote device - * @param p_remote_name : remote device name - * - * @return - */ -typedef bool (aos_bt_ble_selective_conn_cback_t)(aos_bt_device_address_t remote_bda, uint8_t *p_remote_name, - const uint8_t *p_data, uint8_t length); - - -/* - * Callback aos_bt_ble_scan_result_cback_t - * - * Scan result callback (from calling #aos_bt_ble_scan) - * - * @param p_scan_result : scan result data (NULL indicates end of scanning) - * @param p_adv_data : Advertisement data (parse using #aos_bt_ble_check_advertising_data) - * - * @return Nothing - */ -typedef void (aos_bt_ble_scan_result_cback_t) (aos_bt_ble_scan_results_t *p_scan_result, uint8_t *p_adv_data); - -/****************************************************** - * Function Declarations - * - ******************************************************/ -#ifdef __cplusplus -extern "C" { -#endif - -/* - * - * Function aos_bt_start_advertisements - * - * Start advertising. - * - * Use #aos_bt_ble_set_advertisement_data to configure advertising data - * prior to starting avertisements. - * - * The advert_mode parameter determines what advertising parameters and durations - * to use (as specified by the application configuration). - * - * @param[in] advert_mode : advertisement mode - * @param[in] directed_advertisement_bdaddr_type : BLE_ADDR_PUBLIC or BLE_ADDR_RANDOM (if using directed advertisement mode) - * @param[in] directed_advertisement_bdaddr_ptr : Directed advertisement address (NULL if not using directed advertisement) - * - * @return status - * - */ -aos_bt_result_t aos_bt_start_advertisements(aos_bt_ble_advert_mode_t advert_mode, - aos_bt_ble_address_type_t directed_advertisement_bdaddr_type, - aos_bt_device_address_ptr_t directed_advertisement_bdaddr_ptr); - -/* - * - * Function aos_bt_ble_get_current_advert_mode - * - * Get current advertising mode - * - * @return Current advertising mode - * - */ -aos_bt_ble_advert_mode_t aos_bt_ble_get_current_advert_mode(void); - - -/* - * - * Function aos_bt_ble_set_advertisement_data - * - * Set advertisement data. - * - * @param[in] data_mask : mask of data types to include in the advertisement data - * @param[in] p_data : advertisement data - * - * @return void - * - */ -aos_bt_result_t aos_bt_ble_set_advertisement_data(aos_bt_ble_advert_mask_t data_mask, - aos_bt_ble_advert_data_t *p_data); - -/* - * - * Function aos_bt_ble_set_scan_response_data - * - * Set scan response data - * - * @param[in] data_mask : mask of data types to include in the scan response data - * @param[in] p_data : scan response data - * - * @return status of the operation - * - */ -aos_bt_dev_status_t aos_bt_ble_set_scan_response_data(aos_bt_ble_advert_mask_t data_mask, - aos_bt_ble_advert_data_t *p_data); - -/* - * - * Function aos_bt_ble_scan - * - * Start LE scanning - * - * The scan_type parameter determines what scanning parameters and durations - * to use (as specified by the application configuration). - * - * Scan results are notified using p_scan_result_cback - * - * @param[in] scan_type : BTM_BLE_SCAN_TYPE_NONE, BTM_BLE_SCAN_TYPE_HIGH_DUTY, BTM_BLE_SCAN_TYPE_LOW_DUTY - * @param[in] duplicate_filter_enable : TRUE or FALSE to enable or disable duplicate filtering - * - * @param[in] p_scan_result_cback : scan result callback - * - * @return aos_bt_result_t - * - * AOS_BT_PENDING if successfully initiated - * AOS_BT_BUSY if already in progress - * AOS_BT_ILLEGAL_VALUE if parameter(s) are out of range - * AOS_BT_NO_RESOURCES if could not allocate resources to start the command - * AOS_BT_WRONG_MODE if the device is not up. - */ -aos_bt_result_t aos_bt_ble_scan (aos_bt_ble_scan_type_t scan_type, aos_bool_t duplicate_filter_enable, - aos_bt_ble_scan_result_cback_t *p_scan_result_cback); - -/* - * - * Function aos_bt_ble_get_current_scan_state - * - * Get current scan state - * - * @return aos_bt_ble_scan_type_t - * - * BTM_BLE_SCAN_TYPE_NONE Not scanning - * BTM_BLE_SCAN_TYPE_HIGH_DUTY High duty cycle scan - * BTM_BLE_SCAN_TYPE_LOW_DUTY Low duty cycle scan - */ -aos_bt_ble_scan_type_t aos_bt_ble_get_current_scan_state(void); - - -/* - * - * Function aos_bt_ble_security_grant - * - * Grant or deny access. Used in response to an BTM_SECURITY_REQUEST_EVT event. - * - * @param[in] bd_addr : peer device bd address. - * @param[in] res : BTM_SUCCESS to grant access; BTM_REPEATED_ATTEMPTS otherwise - * - * @return None - * - */ -void aos_bt_ble_security_grant(aos_bt_device_address_t bd_addr, uint8_t res); - -/* - * - * Function aos_bt_ble_data_signature - * - * Sign the data using AES128 CMAC algorith. - * - * @param[in] bd_addr: target device the data to be signed for. - * @param[in] p_text: signing data - * @param[in] len: length of the signing data - * @param[in] signature: output parameter where data signature is going to be stored - * - * @return TRUE if signing successful, otherwise FALSE. - * - */ -aos_bool_t aos_bt_ble_data_signature (aos_bt_device_address_t bd_addr, uint8_t *p_text, uint16_t len, - aos_dev_ble_signature_t signature); - -/* - * - * Function aos_bt_ble_verify_signature - * - * Verify the data signature - * - * @param[in] bd_addr: target device the data to be signed for. - * @param[in] p_orig: original data before signature. - * @param[in] len: length of the signing data - * @param[in] counter: counter used when doing data signing - * @param[in] p_comp: signature to be compared against. - * - * @return TRUE if signature verified correctly; otherwise FALSE. - * - */ -aos_bool_t aos_bt_ble_verify_signature (aos_bt_device_address_t bd_addr, uint8_t *p_orig, - uint16_t len, uint32_t counter, - uint8_t *p_comp); - -/* - * - * Function aos_bt_ble_set_background_connection_type - * - * Set BLE background connection procedure type. - * - * @param[in] conn_type: BTM_BLE_CONN_NONE, BTM_BLE_CONN_AUTO, or BTM_BLE_CONN_SELECTIVE - * @param[in] p_select_cback: callback for BTM_BLE_CONN_SELECTIVE - * - * @return TRUE if background connection set - * - */ -aos_bool_t aos_bt_ble_set_background_connection_type (aos_bt_ble_conn_type_t conn_type, - aos_bt_ble_selective_conn_cback_t *p_select_cback); - -/* - * - * Function aos_bt_ble_update_background_connection_device - * - * This function is called to add or remove a device into/from - * background connection procedure. The background connection - * procedure is decided by the background connection type, it can be - * auto connection, or selective connection. - * - * @param[in] add_remove: TRUE to add; FALSE to remove. - * @param[in] remote_bda: device address to add/remove. - * - * @return TRUE if successful - * - */ -aos_bool_t aos_bt_ble_update_background_connection_device(aos_bool_t add_remove, aos_bt_device_address_t remote_bda); - - -/* - * - * Function aos_bt_ble_get_background_connection_device_size - * - * Get a size of white list for the AUTO or SELECTIVE Connection Procedure. - * - * @param[out] size: white list size - * - * @return AOS_TRUE or AOS_FALSE - */ -aos_bool_t aos_bt_ble_get_background_connection_device_size(uint8_t *size); - - -/* - * - * Function aos_bt_ble_check_advertising_data - * - * Parse advertising data (returned from scan results callback #aos_bt_ble_scan_result_cback_t). - * Look for specified advertisement data type. - * - * @param[in] p_adv : pointer to advertisement data - * @param[in] type : advertisement data type to look for - * @param[out] p_length : length of advertisement data (if found) - * - * @return pointer to start of requested advertisement data (if found). NULL if requested data type not found. - * - */ -uint8_t *aos_bt_ble_check_advertising_data( uint8_t *p_adv, aos_bt_ble_advert_type_t type, uint8_t *p_length); - -/* - * - * Function aos_bt_ble_enable_privacy - * - * This function is called to enable or disable the privacy in - * the local device. - * - * @param[in] enable: TRUE to enable it; FALSE to disable it. - * - * @return void - * - */ -void aos_bt_ble_enable_privacy (aos_bool_t enable); - -/* - * - * Function aos_bt_ble_enable_mixed_privacy_mode - * - * This function is called to enabled Mixed mode if privacy 1.2 - * is applicable in controller. - * - * @param[in] mixed_on: mixed mode to be used or not. - * - * @return void - * - */ -void aos_bt_ble_enable_mixed_privacy_mode(aos_bool_t mixed_on); - - -/* - * - * Function aos_bt_ble_get_security_state - * - * Get security mode 1 flags and encryption key size for LE peer. - * - * @param[in] bd_addr : peer address - * @param[out] p_le_sec_flags : security flags (see #aos_bt_ble_sec_flags_e) - * @param[out] p_le_key_size : encryption key size - * - * @return TRUE if successful - * - */ -aos_bool_t aos_bt_ble_get_security_state (aos_bt_device_address_t bd_addr, uint8_t *p_le_sec_flags, - uint8_t *p_le_key_size); - -/* - * - * Function aos_bt_ble_update_advertising_white_list - * - * Add or remove device from advertising white list - * - * @param[in] add: TRUE to add; FALSE to remove - * @param[in] remote_bda: remote device address. - * - * @return void - * - */ -aos_bool_t aos_bt_ble_update_advertising_white_list(aos_bool_t add, const aos_bt_device_address_t remote_bda); - -/* - * - * Function aos_bt_ble_update_advertisement_filter_policy - * - * Update the filter policy of advertiser. - * - * @param[in] advertising_policy: advertising filter policy - * - * @return void - */ -aos_bool_t aos_bt_ble_update_advertisement_filter_policy(aos_bt_ble_advert_filter_policy_t advertising_policy); - - -/* - * - * Function aos_bt_ble_get_advertisement_white_list_size - * - * Get advertisement white list size. - * - * @param[out] size: white list size - * - * @return AOS_TRUE or AOS_FALSE - */ -aos_bool_t aos_bt_ble_get_advertisement_white_list_size(uint8_t *size); - - -/* - * - * Function aos_bt_ble_get_white_list_capability - * - * Get All white list size. - * - * @param[out] size: white list size - * - * @return AOS_TRUE or AOS_FALSE - */ -aos_bool_t aos_bt_ble_get_white_list_capability(uint8_t *size); - -/* - * - * Function aos_bt_ble_clear_white_list - * - * Clear white list (Advertisement & background connection). - * - * @param none - * - * @return AOS_TRUE or AOS_FALSE - */ -aos_bool_t aos_bt_ble_clear_white_list(void); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/kernel/protocols/bluetooth/include/aos_bt_constants.h b/kernel/protocols/bluetooth/include/aos_bt_constants.h deleted file mode 100644 index a566696d1c..0000000000 --- a/kernel/protocols/bluetooth/include/aos_bt_constants.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -/* @file - * Defines common constants and types for the MBLE Bluetooth Framework - */ - -#ifndef _AOS_BT_CONSTANTS_H_ -#define _AOS_BT_CONSTANTS_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef RESULT_ENUM -#define RESULT_ENUM( prefix, name, value ) prefix ## name = (value) -#endif /* ifndef RESULT_ENUM */ - -#define BT_RESULT_LIST( prefix ) \ - RESULT_ENUM( prefix, SUCCESS, 0 ), /* Success */ \ - RESULT_ENUM( prefix, PARTIAL_RESULTS, 3 ), /* Partial results */ \ - RESULT_ENUM( prefix, BADARG, 5 ), /* Bad Arguments */ \ - RESULT_ENUM( prefix, BADOPTION, 6 ), /* Mode not supported */ \ - RESULT_ENUM( prefix, OUT_OF_HEAP_SPACE, 8 ), /* Dynamic memory space exhausted */ \ - RESULT_ENUM( prefix, UNKNOWN_EVENT, 8029 ), /* Unknown event is received */ \ - RESULT_ENUM( prefix, LIST_EMPTY, 8010 ), /* List is empty */ \ - RESULT_ENUM( prefix, ITEM_NOT_IN_LIST, 8011 ), /* Item not found in the list */ \ - RESULT_ENUM( prefix, PACKET_DATA_OVERFLOW, 8012 ), /* Data overflow beyond the packet end */ \ - RESULT_ENUM( prefix, PACKET_POOL_EXHAUSTED, 8013 ), /* All packets in the pool is in use */ \ - RESULT_ENUM( prefix, PACKET_POOL_FATAL_ERROR, 8014 ), /* Packet pool fatal error such as permanent packet leak */ \ - RESULT_ENUM( prefix, UNKNOWN_PACKET, 8015 ), /* Unknown packet */ \ - RESULT_ENUM( prefix, PACKET_WRONG_OWNER, 8016 ), /* Packet is owned by another entity */ \ - RESULT_ENUM( prefix, BUS_UNINITIALISED, 8017 ), /* Bluetooth bus isn't initialised */ \ - RESULT_ENUM( prefix, MPAF_UNINITIALISED, 8018 ), /* MPAF framework isn't initialised */ \ - RESULT_ENUM( prefix, RFCOMM_UNINITIALISED, 8019 ), /* RFCOMM protocol isn't initialised */ \ - RESULT_ENUM( prefix, STACK_UNINITIALISED, 8020 ), /* SmartBridge isn't initialised */ \ - RESULT_ENUM( prefix, SMART_APPL_UNINITIALISED, 8021 ), /* Bluetooth stack isn't initialised */ \ - RESULT_ENUM( prefix, ATT_CACHE_UNINITIALISED, 8022 ), /* Attribute cache isn't initialised */ \ - RESULT_ENUM( prefix, MAX_CONNECTIONS_REACHED, 8023 ), /* Maximum number of connections is reached */ \ - RESULT_ENUM( prefix, SOCKET_IN_USE, 8024 ), /* Socket specified is in use */ \ - RESULT_ENUM( prefix, SOCKET_NOT_CONNECTED, 8025 ), /* Socket is not connected or connection failed */ \ - RESULT_ENUM( prefix, ENCRYPTION_FAILED, 8026 ), /* Encryption failed */ \ - RESULT_ENUM( prefix, SCAN_IN_PROGRESS, 8027 ), /* Scan is in progress */ \ - RESULT_ENUM( prefix, CONNECT_IN_PROGRESS, 8028 ), /* Connect is in progress */ \ - RESULT_ENUM( prefix, DISCONNECT_IN_PROGRESS, 8029 ), /* Disconnect is in progress */ \ - RESULT_ENUM( prefix, DISCOVER_IN_PROGRESS, 8030 ), /* Discovery is in progress */ \ - RESULT_ENUM( prefix, GATT_TIMEOUT, 8031 ), /* GATT timeout occured*/ \ - RESULT_ENUM( prefix, ATTRIBUTE_VALUE_TOO_LONG, 8032 ), /* Attribute value too long */ \ - RESULT_ENUM( prefix, PENDING, 8100 ), /* Pending */ \ - RESULT_ENUM( prefix, BUSY, 8101 ), /* Device busy with another command */ \ - RESULT_ENUM( prefix, NO_RESOURCES, 8102 ), /* No resources to issue command */ \ - RESULT_ENUM( prefix, UNSUPPORTED, 8103 ), /* Unsupported function */ \ - RESULT_ENUM( prefix, ILLEGAL_VALUE, 8104 ), /* Illegal parameter value */ \ - RESULT_ENUM( prefix, WRONG_MODE, 8105 ), /* Device in wrong mode for request */ \ - RESULT_ENUM( prefix, UNKNOWN_ADDR, 8106 ), /* Unknown remote BD address */ \ - RESULT_ENUM( prefix, TIMEOUT, 8107 ), /* Timeout */ \ - RESULT_ENUM( prefix, BAD_VALUE_RET, 8108 ), /* A bad value was received from HCI */ \ - RESULT_ENUM( prefix, ERROR, 8109 ), /* Error */ \ - RESULT_ENUM( prefix, NOT_AUTHORIZED, 8110 ), /* Authorization failed */ \ - RESULT_ENUM( prefix, DEV_RESET, 8111 ), /* Device has been reset */ \ - RESULT_ENUM( prefix, CMD_STORED, 8112 ), /* request is stored in control block */ \ - RESULT_ENUM( prefix, ILLEGAL_ACTION, 8113 ), /* state machine gets illegal command */ \ - RESULT_ENUM( prefix, DELAY_CHECK, 8114 ), /* delay the check on encryption */ \ - RESULT_ENUM( prefix, SCO_BAD_LENGTH, 8115 ), /* Bad SCO over HCI data length */ \ - RESULT_ENUM( prefix, SUCCESS_NO_SECURITY, 8116 ), /* security passed, no security set */ \ - RESULT_ENUM( prefix, FAILED_ON_SECURITY, 8117 ), /* security failed */ \ - RESULT_ENUM( prefix, REPEATED_ATTEMPTS, 8118 ), /* repeated attempts for LE security requests */ \ - RESULT_ENUM( prefix, MODE4_LEVEL4_NOT_SUPPORTED,8119 ), /* Connections Only Mode can't be supported */ \ - RESULT_ENUM( prefix, USE_DEFAULT_SECURITY, 8120 ), /* Use default security*/ - -#define MBLE_ADDRESS_BYTE_SIZE 6 - -/* - * AOS Result Type - */ -typedef enum { - BT_RESULT_LIST ( AOS_BT_ ) -} aos_bt_result_t; - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif diff --git a/kernel/protocols/bluetooth/include/aos_bt_dev.h b/kernel/protocols/bluetooth/include/aos_bt_dev.h deleted file mode 100644 index aadbff8392..0000000000 --- a/kernel/protocols/bluetooth/include/aos_bt_dev.h +++ /dev/null @@ -1,1669 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -/* @file - * - * Bluetooth Management (BTM) Application Programming Interface - * - * The BTM consists of several management entities: - * 1. Device Control - controls the local device - * 2. Device Discovery - manages inquiries, discover database - * 3. ACL Channels - manages ACL connections (BR/EDR and LE) - * 4. SCO Channels - manages SCO connections - * 5. Security - manages all security functionality - * 6. Power Management - manages park, sniff, hold, etc. - * - * @defgroup aosbt Bluetooth - * - * AOS Bluetooth Framework Functions - */ -#ifndef _AOS_BT_DEV_H_ -#define _AOS_BT_DEV_H_ - -#include "buildcfg.h" -#include "aos_bt_types.h" -#include "aos_bt_constants.h" -#include "hcidefs.h" -#include "bt_types.h" - -/* Result/Status for aos_bt_dev */ -typedef aos_bt_result_t aos_bt_dev_status_t; /*< Result/Status for aos_bt_dev */ - -/* Structure returned with Vendor Specific Command complete callback */ -typedef struct { - uint16_t opcode; /*< Vendor specific command opcode */ - uint16_t param_len; /*< Return parameter length */ - uint8_t *p_param_buf; /*< Return parameter buffer */ -} aos_bt_dev_vendor_specific_command_complete_params_t; - -#ifndef aos_bool_t -typedef uint8_t aos_bool_t; -#endif - -/**************************************************************************** - * DEVICE DISCOVERY - Inquiry, Remote Name, Discovery, Class of Device - *****************************************************************************/ -/* BR/EDR Discoverable modes */ -#ifndef BTM_DISCOVERABILITY_MODE -#define BTM_DISCOVERABILITY_MODE -enum aos_bt_discoverability_mode_e { - BTM_NON_DISCOVERABLE = 0, /*< Non discoverable */ - BTM_LIMITED_DISCOVERABLE = 1, /*< Limited BR/EDR discoverable */ - BTM_GENERAL_DISCOVERABLE = 2 /*< General BR/EDR discoverable */ -}; -#define BTM_DISCOVERABLE_MASK (BTM_LIMITED_DISCOVERABLE|BTM_GENERAL_DISCOVERABLE) -#define BTM_MAX_DISCOVERABLE BTM_GENERAL_DISCOVERABLE -#endif /* BTM_DISCOVERABILITY_MODE */ - -/* BR/EDR Connectable modes */ -#ifndef BTM_CONNECTABILITY_MODE -#define BTM_CONNECTABILITY_MODE -enum aos_bt_connectability_mode_e { - BTM_NON_CONNECTABLE = 0, /*< Not connectable */ - BTM_CONNECTABLE = 1 /*< BR/EDR connectable */ -}; -#define BTM_CONNECTABLE_MASK (BTM_NON_CONNECTABLE | BTM_CONNECTABLE) -#endif /* BTM_CONNECTABILITY_MODE */ - -/* - * Inquiry modes - * Note: These modes are associated with the inquiry active values (BTM_*ACTIVE) - */ -#ifndef BTM_INQUIRY_MODE /* To avoid redefintions when including aos_bt_dev.h */ -#define BTM_INQUIRY_MODE -enum aos_bt_inquiry_mode_e { - BTM_INQUIRY_NONE = 0, /*< Stop inquiry */ - BTM_GENERAL_INQUIRY = 0x01, /*< General inquiry */ - BTM_LIMITED_INQUIRY = 0x02, /*< Limited inquiry */ - BTM_BR_INQUIRY_MASK = (BTM_GENERAL_INQUIRY | BTM_LIMITED_INQUIRY) -}; -#endif /* BTM_INQUIRY_MODE */ - -/* Define scan types */ -#define BTM_SCAN_TYPE_STANDARD 0 -#define BTM_SCAN_TYPE_INTERLACED 1 - -/* Inquiry results mode */ -#define BTM_INQ_RESULT 0 -#define BTM_INQ_RESULT_WITH_RSSI 1 -#define BTM_INQ_RESULT_EXTENDED 2 - -#define BTM_INQ_RES_IGNORE_RSSI 0x7f /*< RSSI value not supplied (ignore it) */ -#define BTM_SCAN_PARAM_IGNORE 0 /* Passed to BTM_SetScanConfig() to ignore */ - -/* Inquiry Filter Condition types (see aos_bt_dev_inq_parms_t) */ -#ifndef BTM_INQUIRY_FILTER -#define BTM_INQUIRY_FILTER -enum aos_bt_dev_filter_cond_e { - BTM_CLR_INQUIRY_FILTER = 0, /*< No inquiry filter */ - BTM_FILTER_COND_DEVICE_CLASS = HCI_FILTER_COND_DEVICE_CLASS, /*< Filter on device class */ - BTM_FILTER_COND_BD_ADDR = HCI_FILTER_COND_BD_ADDR, /*< Filter on device addr */ -}; -#endif /* BTM_INQUIRY_FILTER */ - -/* - * State of the remote name retrieval during inquiry operations. - * Used in the aos_bt_dev_inq_info_t structure, and returned in the - * BTM_InqDbRead, BTM_InqDbFirst, and BTM_InqDbNext functions. - * The name field is valid when the state returned is - * BTM_INQ_RMT_NAME_DONE - */ -#define BTM_INQ_RMT_NAME_EMPTY 0 -#define BTM_INQ_RMT_NAME_PENDING 1 -#define BTM_INQ_RMT_NAME_DONE 2 -#define BTM_INQ_RMT_NAME_FAILED 3 - -/* BTM service definitions (used for storing EIR data to bit mask */ -#ifndef BTM_EIR_UUID_ENUM -#define BTM_EIR_UUID_ENUM -enum { - BTM_EIR_UUID_SERVCLASS_SERVICE_DISCOVERY_SERVER, - BTM_EIR_UUID_SERVCLASS_SERIAL_PORT, - BTM_EIR_UUID_SERVCLASS_LAN_ACCESS_USING_PPP, - BTM_EIR_UUID_SERVCLASS_DIALUP_NETWORKING, - BTM_EIR_UUID_SERVCLASS_IRMC_SYNC, - BTM_EIR_UUID_SERVCLASS_OBEX_OBJECT_PUSH, - BTM_EIR_UUID_SERVCLASS_OBEX_FILE_TRANSFER, - BTM_EIR_UUID_SERVCLASS_IRMC_SYNC_COMMAND, - BTM_EIR_UUID_SERVCLASS_HEADSET, - BTM_EIR_UUID_SERVCLASS_CORDLESS_TELEPHONY, - BTM_EIR_UUID_SERVCLASS_AUDIO_SOURCE, - BTM_EIR_UUID_SERVCLASS_AUDIO_SINK, - BTM_EIR_UUID_SERVCLASS_AV_REM_CTRL_TARGET, - BTM_EIR_UUID_SERVCLASS_AV_REMOTE_CONTROL, - BTM_EIR_UUID_SERVCLASS_INTERCOM, - BTM_EIR_UUID_SERVCLASS_FAX, - BTM_EIR_UUID_SERVCLASS_HEADSET_AUDIO_GATEWAY, - BTM_EIR_UUID_SERVCLASS_PANU, - BTM_EIR_UUID_SERVCLASS_NAP, - BTM_EIR_UUID_SERVCLASS_GN, - BTM_EIR_UUID_SERVCLASS_DIRECT_PRINTING, - BTM_EIR_UUID_SERVCLASS_IMAGING, - BTM_EIR_UUID_SERVCLASS_IMAGING_RESPONDER, - BTM_EIR_UUID_SERVCLASS_IMAGING_AUTO_ARCHIVE, - BTM_EIR_UUID_SERVCLASS_IMAGING_REF_OBJECTS, - BTM_EIR_UUID_SERVCLASS_HF_HANDSFREE, - BTM_EIR_UUID_SERVCLASS_AG_HANDSFREE, - BTM_EIR_UUID_SERVCLASS_DIR_PRT_REF_OBJ_SERVICE, - BTM_EIR_UUID_SERVCLASS_BASIC_PRINTING, - BTM_EIR_UUID_SERVCLASS_PRINTING_STATUS, - BTM_EIR_UUID_SERVCLASS_HUMAN_INTERFACE, - BTM_EIR_UUID_SERVCLASS_CABLE_REPLACEMENT, - BTM_EIR_UUID_SERVCLASS_HCRP_PRINT, - BTM_EIR_UUID_SERVCLASS_HCRP_SCAN, - BTM_EIR_UUID_SERVCLASS_SAP, - BTM_EIR_UUID_SERVCLASS_PBAP_PCE, - BTM_EIR_UUID_SERVCLASS_PBAP_PSE, - BTM_EIR_UUID_SERVCLASS_PHONE_ACCESS, - BTM_EIR_UUID_SERVCLASS_HEADSET_HS, - BTM_EIR_UUID_SERVCLASS_PNP_INFORMATION, - BTM_EIR_UUID_SERVCLASS_VIDEO_SOURCE, - BTM_EIR_UUID_SERVCLASS_VIDEO_SINK, - BTM_EIR_UUID_SERVCLASS_MESSAGE_ACCESS, - BTM_EIR_UUID_SERVCLASS_MESSAGE_NOTIFICATION, - BTM_EIR_UUID_SERVCLASS_HDP_SOURCE, - BTM_EIR_UUID_SERVCLASS_HDP_SINK, - BTM_EIR_MAX_SERVICES -}; -#endif /* BTM_EIR_UUID_ENUM */ - -/*********************************************************************************************** - * BTM Services MACROS handle array of uint32_t bits for more than 32 services - ************************************************************************************************/ -/* Determine the number of uint32_t's necessary for services */ -#define BTM_EIR_ARRAY_BITS 32 /* Number of bits in each array element */ -#ifndef BTM_EIR_SERVICE_ARRAY_SIZE -#define BTM_EIR_SERVICE_ARRAY_SIZE (((uint32_t)BTM_EIR_MAX_SERVICES / BTM_EIR_ARRAY_BITS) + \ - (((uint32_t)BTM_EIR_MAX_SERVICES % BTM_EIR_ARRAY_BITS) ? 1 : 0)) -#endif - -/************************** - * Device Discovery Types - ****************************/ -/* Class of Device inquiry filter */ -typedef struct { - aos_bt_dev_class_t dev_class; /*< class of device */ - aos_bt_dev_class_t dev_class_mask; /*< class of device filter mask */ -} aos_bt_dev_cod_cond_t; - -/* Inquiry filter */ -typedef union { - aos_bt_device_address_t bdaddr_cond; /*< bluetooth address filter */ - aos_bt_dev_cod_cond_t cod_cond; /*< class of device filter */ -} aos_bt_dev_inq_filt_cond_t; - -/* Inquiry Parameters */ -typedef struct { - uint8_t mode; /*< Inquiry mode (see #aos_bt_inquiry_mode_e) */ - uint8_t duration; /*< Inquiry duration (1.28 sec increments) */ - uint8_t filter_cond_type; /*< Inquiry filter type (see #aos_bt_dev_filter_cond_e) */ - aos_bt_dev_inq_filt_cond_t filter_cond; /*< Inquiry filter */ -} aos_bt_dev_inq_parms_t; - -/* Inquiry Results */ -typedef struct { - uint16_t clock_offset; /*< Clock offset */ - aos_bt_device_address_t remote_bd_addr; /*< Device address */ - aos_bt_dev_class_t dev_class; /*< Class of device */ - uint8_t page_scan_rep_mode; /*< Page scan repetition mode */ - uint8_t page_scan_per_mode; /*< Page scan per mode */ - uint8_t page_scan_mode; /*< Page scan mode */ - int8_t - rssi; /*< Receive signal strength index (#BTM_INQ_RES_IGNORE_RSSI, if not available) */ - uint32_t eir_uuid[BTM_EIR_SERVICE_ARRAY_SIZE]; /*< Array or EIR UUIDs */ - uint8_t eir_complete_list; /*< TRUE if EIR array is complete */ -} aos_bt_dev_inquiry_scan_result_t; - -/* RSSI Result (in response to #aos_bt_dev_read_rssi) */ -typedef struct { - aos_bt_result_t status; /*< Status of the operation */ - uint8_t hci_status; /*< Status from controller */ - int8_t rssi; /*< RSSI */ - aos_bt_device_address_t rem_bda; /*< Remote BD address */ -} aos_bt_dev_rssi_result_t; - -/* TX Power Result (in response to #aos_bt_dev_read_tx_power) */ -typedef struct { - aos_bt_result_t status; /*< Status of the operation */ - uint8_t hci_status; /*< Status from controller */ - int8_t tx_power; /*< TX power */ - aos_bt_device_address_t rem_bda; /*< Remote BD address */ -} aos_bt_tx_power_result_t; - -/**************************************************************************** - * SECURITY MANAGEMENT - *****************************************************************************/ - -/* Security Service Levels [bit mask]. Encryption should not be used without authentication. */ -#ifndef BTM_SEC_LEVEL -#define BTM_SEC_LEVEL -enum aos_bt_sec_level_e { - BTM_SEC_NONE = 0x0000, /*< Nothing required */ - BTM_SEC_IN_AUTHENTICATE = 0x0002, /*< Inbound call requires authentication */ - BTM_SEC_OUT_AUTHENTICATE = 0x0010, /*< Outbound call requires authentication */ - BTM_SEC_ENCRYPT = 0x0024, /*< Requires encryption (inbound and outbound) */ - BTM_SEC_SECURE_CONNECTION = 0x0040 /*< Secure Connections Mode (P-256 based Secure Simple Pairing and Authentication) */ -}; -#endif /* BTM_SEC_LEVEL */ - -/* PIN types */ -#define BTM_PIN_TYPE_VARIABLE HCI_PIN_TYPE_VARIABLE -#define BTM_PIN_TYPE_FIXED HCI_PIN_TYPE_FIXED - -/* Size of security keys */ -#ifndef BTM_SECURITY_KEY_DATA_LEN -#define BTM_SECURITY_KEY_DATA_LEN 132 /*< Security key data length (used by aos_bt_device_link_keys_t structure) */ -#endif - -#ifndef BTM_SECURITY_LOCAL_KEY_DATA_LEN -#define BTM_SECURITY_LOCAL_KEY_DATA_LEN 65 /*< Local security key data length (used by aos_bt_local_identity_keys_t structure) */ -#endif - -/* Pairing IO Capabilities */ -enum aos_bt_dev_io_cap_e { - BTM_IO_CAPABILITIES_DISPLAY_ONLY, /*< Display Only */ - BTM_IO_CAPABILITIES_DISPLAY_AND_KEYBOARD, /*< Display Yes/No */ - BTM_IO_CAPABILITIES_KEYBOARD_ONLY, /*< Keyboard Only */ - BTM_IO_CAPABILITIES_NONE, /*< No Input, No Output */ - BTM_IO_CAPABILITIES_KEYBOARD_DISPLAY, /*< Keyboard display */ - BTM_IO_CAPABILITIES_MAX -}; -typedef uint8_t aos_bt_dev_io_cap_t; /*< IO capabilities (see #aos_bt_dev_io_cap_e) */ - -/* BR/EDR Authentication requirement */ -enum aos_bt_dev_auth_req_e { - BTM_AUTH_SINGLE_PROFILE_NO = 0, /*< MITM Protection Not Required - Single Profile/non-bonding. Numeric comparison with automatic accept allowed */ - BTM_AUTH_SINGLE_PROFILE_YES = 1, /*< MITM Protection Required - Single Profile/non-bonding. Use IO Capabilities to determine authentication procedure */ - BTM_AUTH_ALL_PROFILES_NO = 2, /*< MITM Protection Not Required - All Profiles/dedicated bonding. Numeric comparison with automatic accept allowed */ - BTM_AUTH_ALL_PROFILES_YES = 3, /*< MITM Protection Required - All Profiles/dedicated bonding. Use IO Capabilities to determine authentication procedure */ - BTM_AUTH_SINGLE_PROFILE_GENERAL_BONDING_NO = 4, /*< MITM Protection Not Required - Single Profiles/general bonding. Numeric comparison with automatic accept allowed */ - BTM_AUTH_SINGLE_PROFILE_GENERAL_BONDING_YES = 5, /*< MITM Protection Required - Single Profiles/general bonding. Use IO Capabilities to determine authentication procedure */ -}; -typedef uint8_t -aos_bt_dev_auth_req_t; /*< BR/EDR authentication requirement (see #aos_bt_dev_auth_req_e) */ - -/* Device Security Mode */ -enum aos_bt_security_mode_e { - BTM_SEC_MODE_UNDEFINED = 0, - BTM_SEC_MODE_NONE = 1, - BTM_SEC_MODE_SERVICE = 2, - BTM_SEC_MODE_LINK = 3, - BTM_SEC_MODE_SP = 4, - BTM_SEC_MODE_SP_DEBUG = 5, - BTM_SEC_MODE_SC = 6, -}; -typedef uint8_t aos_bt_security_mode_t; - -/* LE Authentication requirement */ -enum aos_bt_dev_le_auth_req_e { - BTM_LE_AUTH_REQ_NO_BOND = 0x00, /*< Not required - No Bond */ - BTM_LE_AUTH_REQ_BOND = 0x01, /*< Required - General Bond */ - BTM_LE_AUTH_REQ_MITM = 0x04, /*< MITM required - Auth Y/N*/ - BTM_LE_AUTH_REQ_SC_ONLY = 0x08, /*< LE Secure Connection, no MITM, no Bonding */ - BTM_LE_AUTH_REQ_SC_BOND = (BTM_LE_AUTH_REQ_SC_ONLY | BTM_LE_AUTH_REQ_BOND), /*< LE Secure Connection, no MITM, Bonding */ - BTM_LE_AUTH_REQ_SC_MITM = (BTM_LE_AUTH_REQ_SC_ONLY | BTM_LE_AUTH_REQ_MITM), /*< LE Secure Connection, MITM, no Bonding */ - BTM_LE_AUTH_REQ_SC_MITM_BOND = (BTM_LE_AUTH_REQ_SC_ONLY | BTM_LE_AUTH_REQ_MITM | BTM_LE_AUTH_REQ_BOND), /*< LE Secure Connection, MITM, Bonding */ - BTM_LE_AUTH_REQ_MASK = 0x1D -}; -typedef uint8_t -aos_bt_dev_le_auth_req_t; /*< BLE authentication requirement (see #aos_bt_dev_le_auth_req_e) */ - -/* OOB Data status */ -#ifndef BTM_OOB_STATE -#define BTM_OOB_STATE -enum aos_bt_dev_oob_data_e { - BTM_OOB_NONE, /*< No OOB data */ - BTM_OOB_PRESENT_192, /*< OOB data present (from the P-192 public key) */ - BTM_OOB_PRESENT_256, /*< OOB data present (from the P-256 public key) */ - BTM_OOB_PRESENT_192_256, /*< OOB data present (from the P-192 and P-256 public keys) */ - BTM_OOB_UNKNOWN /*< OOB data unknown */ -}; -#endif -typedef uint8_t aos_bt_dev_oob_data_t; /*< OOB data (see #aos_bt_dev_oob_data_e) */ - -/* Data type for IO capabalities response (BTM_PAIRING_IO_CAPABILITIES_BR_EDR_RESPONSE_EVT) */ -typedef struct { - aos_bt_device_address_t bd_addr; /*< Peer address */ - aos_bt_dev_io_cap_t io_cap; /*< Peer IO capabilities */ - aos_bt_dev_oob_data_t oob_data; /*< OOB data present at peer device for the local device */ - aos_bt_dev_auth_req_t auth_req; /*< Authentication required for peer device */ -} aos_bt_dev_bredr_io_caps_rsp_t; - -/* Data for pairing confirmation request (BTM_USER_CONFIRMATION_REQUEST_EVT event data type) */ -typedef struct { - aos_bt_device_address_t bd_addr; /*< peer address */ - uint32_t - numeric_value; /*< numeric value for comparison (if "just_works", do not show this number to UI) */ - aos_bool_t just_works; /*< TRUE, if using "just works" association model */ - aos_bt_dev_auth_req_t local_authentication_requirements; /*< Authentication requirement for local device */ - aos_bt_dev_auth_req_t remote_authentication_requirements; /*< Authentication requirement for peer device */ -} aos_bt_dev_user_cfm_req_t; - -/* Pairing user passkey request (BTM_USER_PASSKEY_REQUEST_EVT event data type) */ -typedef struct { - aos_bt_device_address_t bd_addr; /*< peer address */ -} aos_bt_dev_user_key_req_t; - -/* Data for pairing passkey notification (BTM_USER_PASSKEY_NOTIFICATION_EVT event data type) */ -typedef struct { - aos_bt_device_address_t bd_addr; /*< peer address */ - uint32_t passkey; /*< passkey */ -} aos_bt_dev_user_key_notif_t; - - -/* Pairing keypress types */ -enum aos_bt_dev_passkey_entry_type_e { - BTM_PASSKEY_ENTRY_STARTED, /*< passkey entry started */ - BTM_PASSKEY_DIGIT_ENTERED, /*< passkey digit entered */ - BTM_PASSKEY_DIGIT_ERASED, /*< passkey digit erased */ - BTM_PASSKEY_DIGIT_CLEARED, /*< passkey cleared */ - BTM_PASSKEY_ENTRY_COMPLETED /*< passkey entry completed */ -}; -typedef uint8_t -aos_bt_dev_passkey_entry_type_t; /*< Bluetooth pairing keypress value (see #aos_bt_dev_passkey_entry_type_e) */ - -/* Pairing keypress notification (BTM_USER_KEYPRESS_NOTIFICATION_EVT event data type) */ -typedef struct { - aos_bt_device_address_t bd_addr; /*< peer address */ - aos_bt_dev_passkey_entry_type_t keypress_type; /*< type of keypress */ -} aos_bt_dev_user_keypress_t; - -/* BR/EDR pairing complete infomation */ -typedef struct { - uint8_t - status; /*< status of the simple pairing process (see defintions for HCI status codes) */ -} aos_bt_dev_br_edr_pairing_info_t; - -/* BLE pairing complete infomation */ -typedef struct { - aos_bt_result_t status; /*< status of the simple pairing process */ - uint8_t reason; /*< failure reason (see #aos_bt_smp_status_t) */ - uint8_t sec_level; /*< 0 - None, 1- Unauthenticated Key, 4-Authenticated Key */ - aos_bool_t privacy_supported; /*< True if privacy supported, False if not */ - aos_bool_t is_pair_cancel; /*< True if cancelled, else False */ - aos_bt_device_address_t - resolved_bd_addr; /*< Resolved address (if remote device using private address) */ - aos_bt_ble_address_type_t resolved_bd_addr_type; /*< Resolved addr type of bonded device */ -} aos_bt_dev_ble_pairing_info_t; - -/* Transport dependent pairing complete infomation */ -typedef union { - aos_bt_dev_br_edr_pairing_info_t br_edr; /*< BR/EDR pairing complete infomation */ - aos_bt_dev_ble_pairing_info_t ble; /*< BLE pairing complete infomation */ -} aos_bt_dev_pairing_info_t; - -/* Pairing complete notification (BTM_PAIRING_COMPLETE_EVT event data type) */ -typedef struct { - uint8_t *bd_addr; /*< peer address */ - aos_bt_transport_t transport; /*< BT_TRANSPORT_BR_EDR or BT_TRANSPORT_LE */ - aos_bt_dev_pairing_info_t pairing_complete_info; /*< Transport dependent pairing complete infomation */ - aos_bt_result_t - bonding_status; /*< current status of bonding process to notify app of completion status of storing keys */ -} aos_bt_dev_pairing_cplt_t; - -/* Check if application wishes to upgrade security (BTM_SECURITY_UPGRADE_EVT event data type) */ -typedef struct { - aos_bt_device_address_t bd_addr; /*< [in] Peer address */ - aos_bool_t upgrade; /*< [out] Set to TRUE to request security upgrade */ -} aos_bt_dev_security_upgrade_t; - -/* Security request (BTM_SECURITY_REQUEST_EVT event data type) */ -typedef struct { - aos_bt_device_address_t bd_addr; /*< peer address */ -} aos_bt_dev_security_request_t; - -/* LE Key type */ -#ifndef BTM_LE_KEY_TYPES -#define BTM_LE_KEY_TYPES -enum aos_bt_dev_le_key_type_e { - BTM_LE_KEY_PENC = (1 << 0), /*< encryption information of peer device */ - BTM_LE_KEY_PID = (1 << 1), /*< identity key of the peer device */ - BTM_LE_KEY_PCSRK = (1 << 2), /*< peer SRK */ -#if SMP_LE_SC_INCLUDED == TRUE - BTM_LE_KEY_PLK = (1 << 3), - BTM_LE_KEY_LENC = (1 << 4), /*< master role security information:div */ - BTM_LE_KEY_LID = (1 << 5), /*< master device ID key */ - BTM_LE_KEY_LCSRK = (1 << 6), /*< local CSRK has been deliver to peer */ - BTM_LE_KEY_LLK = (1 << 7), -#else - BTM_LE_KEY_LENC = (1 << 3), /*< master role security information:div */ - BTM_LE_KEY_LID = (1 << 4), /*< master device ID key */ - BTM_LE_KEY_LCSRK = (1 << 5), /*< local CSRK has been deliver to peer */ -#endif - BTM_BR_EDR_LKEY = 0xFF -}; -#endif /* BTM_LE_KEY_TYPES */ -typedef uint8_t aos_bt_dev_le_key_type_t; /*< LE key type (see #aos_bt_dev_le_key_type_e) */ - - -enum aos_bt_dev_link_key_type_e { - BTM_LKEY_TYPE_COMBINATION, - BTM_LKEY_TYPE_LOCAL_UNIT, - BTM_LKEY_TYPE_REMOTE_UNIT, - BTM_LKEY_TYPE_DEBUG_COMB, - BTM_LKEY_TYPE_UNAUTH_COMB, - BTM_LKEY_TYPE_AUTH_COMB, - BTM_LKEY_TYPE_CHANGED_COMB, - BTM_LKEY_TYPE_UNAUTH_COMB_P_256, - BTM_LKEY_TYPE_AUTH_COMB_P_256, -}; -typedef uint8_t LINK_KEY_TYPE; - -/* LE security level */ -#define BTM_LE_SEC_NONE 0 -#define BTM_LE_SEC_UNAUTHENTICATE 1 -#define BTM_LE_SEC_AUTHENTICATED 4 -typedef uint8_t aos_bt_security_level; - - -/* BLE encryption keys */ -typedef struct { - BT_OCTET16 ltk; - BT_OCTET8 rand; - UINT16 ediv; - aos_bt_security_level sec_level; - UINT8 key_size; -} tBTM_LE_PENC_KEYS; - -/* BLE CSRK keys */ -typedef struct { - UINT32 counter; - BT_OCTET16 csrk; - aos_bt_security_level sec_level; -} tBTM_LE_PCSRK_KEYS; - -/* BLE Encryption reproduction keys */ -typedef struct { -#if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE && SMP_LE_SC_INCLUDED == TRUE - BT_OCTET16 ltk; -#endif - UINT16 div; - UINT8 key_size; - aos_bt_security_level sec_level; -} tBTM_LE_LENC_KEYS; - -/* BLE SRK keys */ -typedef struct { - UINT32 counter; - UINT16 div; - aos_bt_security_level sec_level; -#if BLE_INCLUDED == TRUE && SMP_INCLUDED == TRUE && SMP_LE_SC_INCLUDED == TRUE - BT_OCTET16 csrk; -#endif -} tBTM_LE_LCSRK_KEYS; - -typedef struct { - BT_OCTET16 irk; - aos_bt_ble_address_type_t addr_type; - aos_bt_device_address_t static_addr; -} tBTM_LE_PID_KEYS; - -typedef union { - tBTM_LE_PENC_KEYS penc_key; /* received peer encryption key */ - tBTM_LE_PCSRK_KEYS pcsrk_key; /* received peer device SRK */ - tBTM_LE_PID_KEYS pid_key; /* peer device ID key */ - tBTM_LE_LENC_KEYS lenc_key; /* local encryption reproduction keys LTK = = d1(ER,DIV,0)*/ - tBTM_LE_LCSRK_KEYS lcsrk_key; /* local device CSRK = d1(ER,DIV,1)*/ -} tBTM_LE_KEY_VALUE; - -typedef struct { - /* BR/EDR key */ - LINK_KEY_TYPE br_edr_key_type; /* BR/EDR Link Key type */ - LINK_KEY br_edr_key; /* BR/EDR Link Key */ -} tBTM_BR_EDR_KEY; - - -typedef union { - tBTM_LE_KEY_VALUE le_keys; - tBTM_BR_EDR_KEY br_edr_key; -} aos_bt_security_key_value_t; - - -/* Scan duty cycle (used for BTM_BLE_SCAN_STATE_CHANGED_EVT and aos_bt_dev_create_connection) */ -#ifndef BTM_BLE_SCAN_TYPE -#define BTM_BLE_SCAN_TYPE -enum aos_bt_ble_scan_type_e { - BTM_BLE_SCAN_TYPE_NONE, /*< Stop scanning */ - BTM_BLE_SCAN_TYPE_HIGH_DUTY, /*< High duty cycle scan */ - BTM_BLE_SCAN_TYPE_LOW_DUTY /*< Low duty cycle scan */ -}; -#endif -typedef uint8_t aos_bt_ble_scan_type_t; /*< scan type (see #aos_bt_ble_scan_type_e) */ - - -/* bonding device information from aos_bt_dev_get_bonded_devices */ -typedef struct { - aos_bt_device_address_t bd_addr; /*< peer address */ - aos_bt_ble_address_type_t addr_type; /*< peer address type : BLE_ADDR_PUBLIC/BLE_ADDR_RANDOM */ - aos_bt_device_type_t - device_type; /*< peer device type : BT_DEVICE_TYPE_BREDR/BT_DEVICE_TYPE_BLE/BT_DEVICE_TYPE_BREDR_BLE */ -} aos_bt_dev_bonded_device_info_t; - -/* LE Secure connection event data */ -/* Type of OOB data required */ -#ifndef BTM_OOB_REQ_TYPE -#define BTM_OOB_REQ_TYPE -enum aos_bt_dev_oob_data_req_type_e { - BTM_OOB_INVALID_TYPE, - BTM_OOB_PEER, /*< Peer OOB data requested */ - BTM_OOB_LOCAL, /*< Local OOB data requested */ - BTM_OOB_BOTH /*< Both local and peer OOB data requested */ -}; -#endif -typedef UINT8 -aos_bt_dev_oob_data_req_type_t; /*< OOB data type requested (see #aos_bt_dev_oob_data_req_type_t) */ - -/* SMP Pairing status codes */ -enum aos_bt_smp_status_e { - SMP_SUCCESS = 0, /*< Success */ - SMP_PASSKEY_ENTRY_FAIL = 0x01, /*< Passkey entry failed */ - SMP_OOB_FAIL = 0x02, /*< OOB failed */ - SMP_PAIR_AUTH_FAIL = 0x03, /*< Authentication failed */ - SMP_CONFIRM_VALUE_ERR = 0x04, /*< Value confirmation failed */ - SMP_PAIR_NOT_SUPPORT = 0x05, /*< Not supported */ - SMP_ENC_KEY_SIZE = 0x06, /*< Encryption key size failure */ - SMP_INVALID_CMD = 0x07, /*< Invalid command */ - SMP_PAIR_FAIL_UNKNOWN = 0x08, /*< Unknown failure */ - SMP_REPEATED_ATTEMPTS = 0x09, /*< Repeated attempts */ - SMP_INVALID_PARAMETERS = 0x0A, /*< Invalid parameters */ - SMP_DHKEY_CHK_FAIL = 0x0B, /*< DH Key check failed */ - SMP_NUMERIC_COMPAR_FAIL = 0x0C, /*< Numeric comparison failed */ - SMP_BR_PAIRING_IN_PROGR = 0x0D, /*< BR paIring in progress */ - SMP_XTRANS_DERIVE_NOT_ALLOW = 0x0E, /*< Cross transport key derivation not allowed */ - SMP_MAX_FAIL_RSN_PER_SPEC = SMP_XTRANS_DERIVE_NOT_ALLOW, - - /* bte smp status codes */ - SMP_PAIR_INTERNAL_ERR = (SMP_MAX_FAIL_RSN_PER_SPEC + 0x01), /*< Internal error */ - SMP_UNKNOWN_IO_CAP = (SMP_MAX_FAIL_RSN_PER_SPEC + 0x02), /*< unknown IO capability, unable to decide associatino model */ - SMP_INIT_FAIL = (SMP_MAX_FAIL_RSN_PER_SPEC + 0x03), /*< Initialization failed */ - SMP_CONFIRM_FAIL = (SMP_MAX_FAIL_RSN_PER_SPEC + 0x04), /*< Confirmation failed */ - SMP_BUSY = (SMP_MAX_FAIL_RSN_PER_SPEC + 0x05), /*< Busy */ - SMP_ENC_FAIL = (SMP_MAX_FAIL_RSN_PER_SPEC + 0x06), /*< Encryption failed */ - SMP_STARTED = (SMP_MAX_FAIL_RSN_PER_SPEC + 0x07), /*< Started */ - SMP_RSP_TIMEOUT = (SMP_MAX_FAIL_RSN_PER_SPEC + 0x08), /*< Response timeout */ - SMP_FAIL = (SMP_MAX_FAIL_RSN_PER_SPEC + 0x09), /*< Generic failure */ - SMP_CONN_TOUT = (SMP_MAX_FAIL_RSN_PER_SPEC + 0x0A), /*< Connection timeout */ -}; -typedef uint8_t aos_bt_smp_status_t; /*< SMP Pairing status (see #aos_bt_smp_status_e) */ - -/* data type for BTM_SMP_REMOTE_OOB_DATA_REQUEST_EVT */ -typedef struct { - aos_bt_device_address_t bd_addr; /* peer address */ -} aos_bt_smp_remote_oob_req_t; - -/* data type for BTM_SMP_SC_REMOTE_OOB_DATA_REQUEST_EVT */ -typedef struct { - aos_bt_device_address_t bd_addr; /* peer address */ - aos_bt_dev_oob_data_req_type_t - oob_type; /* requested oob data types (BTM_OOB_PEER, BTM_OOB_LOCAL, or BTM_OOB_BOTH) */ -} aos_bt_smp_sc_remote_oob_req_t; - -/* Public key */ -typedef struct { - BT_OCTET32 x; - BT_OCTET32 y; -} aos_bt_public_key_t; - -/*< Data for BTM_SMP_SC_LOCAL_OOB_DATA_NOTIFICATION_EVT */ -typedef struct { - aos_bool_t present; /*< TRUE if local oob is present */ - BT_OCTET16 randomizer; /*< randomizer */ - BT_OCTET16 commitment; /*< commitment */ - - aos_bt_ble_address_t addr_sent_to; /*< peer address sent to */ - BT_OCTET32 private_key_used; /*< private key */ - aos_bt_public_key_t public_key_used; /*< public key */ -} aos_bt_smp_sc_local_oob_t; - - -/* SCO link type */ -#define BTM_LINK_TYPE_SCO HCI_LINK_TYPE_SCO /*< Link type SCO */ -#define BTM_LINK_TYPE_ESCO HCI_LINK_TYPE_ESCO /*< Link type eSCO */ -typedef uint8_t aos_bt_sco_type_t; - - -/* LE identity key for local device (used by BTM_LE_LOCAL_IDENTITY_KEYS_UPDATE_EVT and BTM_LE_LOCAL_KEYS_REQUEST_EVT notification) */ -typedef struct { - uint8_t local_key_data[BTM_SECURITY_LOCAL_KEY_DATA_LEN]; /*< [in/out] Local security key */ -} aos_bt_local_identity_keys_t; - -/* SCO connected event related data */ -typedef struct { - uint16_t sco_index; /*< SCO index */ -} aos_bt_sco_connected_t; - -/* SCO disconnected event related data */ -typedef struct { - uint16_t sco_index; /*< SCO index */ -} aos_bt_sco_disconnected_t; - -/* SCO connect request event related data */ -typedef struct { - uint16_t sco_index; /*< SCO index */ - aos_bt_device_address_t bd_addr; /*< Peer bd address */ - aos_bt_dev_class_t dev_class; /*< Peer device class */ - aos_bt_sco_type_t link_type; /*< SCO link type */ -} aos_bt_sco_connection_request_t; - -/* SCO connection change event related data */ -typedef struct { - uint16_t sco_index; /*< SCO index */ - uint16_t rx_pkt_len; /*< RX packet length */ - uint16_t tx_pkt_len; /*< TX packet length */ - aos_bt_device_address_t bd_addr; /*< Peer bd address */ - uint8_t hci_status; /*< HCI status */ - uint8_t tx_interval; /*< TX interval */ - uint8_t retrans_windows; /*< Retransmission windows */ -} aos_bt_sco_connection_change_t; - - -/* Power Management status codes */ -#ifndef BTM_PM_STATUS_CODES -#define BTM_PM_STATUS_CODES -enum aos_bt_dev_power_mgmt_status_e { - BTM_PM_STS_ACTIVE = HCI_MODE_ACTIVE, /*< Active */ - BTM_PM_STS_HOLD = HCI_MODE_HOLD, /*< Hold */ - BTM_PM_STS_SNIFF = HCI_MODE_SNIFF, /*< Sniff */ - BTM_PM_STS_PARK = HCI_MODE_PARK, /*< Park */ - BTM_PM_STS_SSR, /*< Sniff subrating notification */ - BTM_PM_STS_PENDING, /*< Pending (waiting for status from controller) */ - BTM_PM_STS_ERROR /*< Error (controller returned error) */ -}; -#endif -typedef uint8_t aos_bt_dev_power_mgmt_status_t; /*< Power management status (see #aos_bt_dev_power_mgmt_status_e) */ - -/* Bluetooth application tracing macro */ -#ifndef WPRINT_BT_APP_INFO -//extern aos_mutex_t global_trace_mutex; -/* -#define WPRINT_BT_APP_INFO(info) { \ - aos_rtos_lock_mutex(&global_trace_mutex); \ - WPRINT_APP_INFO(info); \ - aos_rtos_unlock_mutex(&global_trace_mutex); \ - } -*/ -#endif - - -#ifndef BTM_MANAGEMENT_EVT -#define BTM_MANAGEMENT_EVT -/* Bluetooth Management events */ -enum aos_bt_management_evt_e { - /* Bluetooth status events */ - BTM_ENABLED_EVT, /*< Bluetooth controller and host stack enabled. Event data: aos_bt_dev_enabled_t */ - BTM_DISABLED_EVT, /*< Bluetooth controller and host stack disabled. Event data: NULL */ - BTM_POWER_MANAGEMENT_STATUS_EVT, /*< Power management status change. Event data: aos_bt_power_mgmt_notification_t */ - - /* Security events */ - BTM_PIN_REQUEST_EVT, /*< PIN request (used only with legacy devices). Event data: #aos_bt_dev_name_and_class_t */ - BTM_USER_CONFIRMATION_REQUEST_EVT, /*< received USER_CONFIRMATION_REQUEST event (respond using #aos_bt_dev_confirm_req_reply). Event data: #aos_bt_dev_user_cfm_req_t */ - BTM_PASSKEY_NOTIFICATION_EVT, /*< received USER_PASSKEY_NOTIFY event. Event data: #aos_bt_dev_user_key_notif_t */ - BTM_PASSKEY_REQUEST_EVT, /*< received USER_PASSKEY_REQUEST event (respond using #aos_bt_dev_pass_key_req_reply). Event data: #aos_bt_dev_user_key_req_t */ - BTM_KEYPRESS_NOTIFICATION_EVT, /*< received KEYPRESS_NOTIFY event. Event data: #aos_bt_dev_user_keypress_t */ - BTM_PAIRING_IO_CAPABILITIES_BR_EDR_REQUEST_EVT, /*< Requesting IO capabilities for BR/EDR pairing. Event data: #aos_bt_dev_bredr_io_caps_req_t */ - BTM_PAIRING_IO_CAPABILITIES_BR_EDR_RESPONSE_EVT,/*< Received IO capabilities response for BR/EDR pairing. Event data: #aos_bt_dev_bredr_io_caps_rsp_t */ - BTM_PAIRING_IO_CAPABILITIES_BLE_REQUEST_EVT, /*< Requesting IO capabilities for BLE pairing. Event data: #aos_bt_dev_ble_io_caps_req_t */ - BTM_PAIRING_COMPLETE_EVT, /*< received SIMPLE_PAIRING_COMPLETE event. Event data: #aos_bt_dev_pairing_cplt_t */ - BTM_ENCRYPTION_STATUS_EVT, /*< Encryption status change. Event data: #aos_bt_dev_encryption_status_t */ - BTM_SECURITY_REQUEST_EVT, /*< Security request (respond using #aos_bt_ble_security_grant). Event data: #aos_bt_dev_security_request_t */ - BTM_SECURITY_UPGRADE_EVT, /*< Check if the application wants to upgrade the link key. Event data: #aos_bt_dev_security_upgrade_t */ - BTM_SECURITY_ABORTED_EVT, /*< Security procedure aborted locally, or unexpected link drop. Event data: #aos_bt_dev_name_and_class_t */ - - BTM_READ_LOCAL_OOB_DATA_COMPLETE_EVT, /*< Result of reading local OOB data (aos_bt_dev_read_local_oob_data). Event data: #aos_bt_dev_local_oob_t */ - BTM_REMOTE_OOB_DATA_REQUEST_EVT, /*< OOB data from remote device (respond using #aos_bt_dev_remote_oob_data_reply). Event data: #aos_bt_dev_remote_oob_t */ - - BTM_PAIRED_DEVICE_LINK_KEYS_UPDATE_EVT, /*< Updated remote device link keys (store device_link_keys to NV memory). Event data: #aos_bt_device_link_keys_t */ - BTM_PAIRED_DEVICE_LINK_KEYS_REQUEST_EVT, /*< Request for stored remote device link keys (restore device_link_keys from NV memory). If successful, return AOS_BT_SUCCESS. Event data: #aos_bt_device_link_keys_t */ - - BTM_LOCAL_IDENTITY_KEYS_UPDATE_EVT, /*< Update local identity key (stored local_identity_keys NV memory). Event data: #aos_bt_local_identity_keys_t */ - BTM_LOCAL_IDENTITY_KEYS_REQUEST_EVT, /*< Request local identity key (get local_identity_keys from NV memory). If successful, return AOS_BT_SUCCESS. Event data: #aos_bt_local_identity_keys_t */ - - BTM_BLE_SCAN_STATE_CHANGED_EVT, /*< BLE scan state change. Event data: #aos_bt_ble_scan_type_t */ - BTM_BLE_ADVERT_STATE_CHANGED_EVT, /*< BLE advertisement state change. Event data: #aos_bt_ble_advert_mode_t */ - - /* BLE Secure Connection events */ - BTM_SMP_REMOTE_OOB_DATA_REQUEST_EVT, /*< SMP remote oob data request. Reply using aos_bt_smp_oob_data_reply. Event data: aos_bt_smp_remote_oob_req_t */ - BTM_SMP_SC_REMOTE_OOB_DATA_REQUEST_EVT, /*< LE secure connection remote oob data request. Reply using aos_bt_smp_sc_oob_reply. Event data: #aos_bt_smp_sc_remote_oob_req_t */ - BTM_SMP_SC_LOCAL_OOB_DATA_NOTIFICATION_EVT, /*< LE secure connection local OOB data (aos_bt_smp_create_local_sc_oob_data). Event data: #aos_bt_smp_sc_local_oob_t*/ - - BTM_SCO_CONNECTED_EVT, /*< SCO connected event. Event data: #aos_bt_sco_connected_t */ - BTM_SCO_DISCONNECTED_EVT, /*< SCO disconnected event. Event data: #aos_bt_sco_disconnected_t */ - BTM_SCO_CONNECTION_REQUEST_EVT, /*< SCO connection request event. Event data: #aos_bt_sco_connection_request_t */ - BTM_SCO_CONNECTION_CHANGE_EVT /*< SCO connection change event. Event data: #aos_bt_sco_connection_change_t */ -}; -#endif -typedef uint8_t aos_bt_management_evt_t; /*< Bluetooth management events (see #aos_bt_management_evt_e) */ - -/* Device enabled (used by BTM_ENABLED_EVT) */ -typedef struct { - aos_bt_result_t status; /*< Status */ -} aos_bt_dev_enabled_t; - -/* Remote device information (used by BTM_PIN_REQUEST_EVT, BTM_SECURITY_ABORTED_EVT) */ -typedef struct { - aos_bt_device_address_t *bd_addr; /*< BD Address of remote */ - aos_bt_dev_class_t *dev_class; /*< peer class of device */ - uint8_t *bd_name; /*< BD Name of remote */ -} aos_bt_dev_name_and_class_t; - -/* Change in power management status (used by BTM_POWER_MANAGEMENT_STATUS_EVT notication) */ -typedef struct { - aos_bt_device_address_t bd_addr; /*< BD Address of remote */ - aos_bt_dev_power_mgmt_status_t status; /*< PM status */ - uint16_t value; /*< Additional mode data */ - uint8_t hci_status; /*< HCI status */ -} aos_bt_power_mgmt_notification_t; - -/* Encryption status change (used by BTM_ENCRYPTION_STATUS_EVT) */ -typedef struct { - uint8_t *bd_addr; /*< BD Address of remote */ - aos_bt_transport_t transport; /*< BT_TRANSPORT_BR_EDR or BT_TRANSPORT_LE */ - void *p_ref_data; /*< Optional data passed in by aos_bt_dev_set_encryption */ - aos_bt_result_t result; /*< Result of the operation */ -} aos_bt_dev_encryption_status_t; - -/* Local OOB data BTM_READ_LOCAL_OOB_DATA_COMPLETE_EVT */ -typedef struct { - aos_bt_result_t status; /*< Status */ - aos_bool_t is_extended_oob_data; /*< TRUE if extended OOB data */ - - BT_OCTET16 c_192; /*< Simple Pairing Hash C derived from the P-192 public key */ - BT_OCTET16 - r_192; /*< Simple Pairing Randomnizer R associated with the P-192 public key */ - BT_OCTET16 - c_256; /*< Simple Pairing Hash C derived from the P-256 public key (valid only if is_extended_oob_data=TRUE) */ - BT_OCTET16 - r_256; /*< Simple Pairing Randomnizer R associated with the P-256 public key (valid only if is_extended_oob_data=TRUE) */ -} aos_bt_dev_local_oob_t; - -/* BTM_REMOTE_OOB_DATA_REQUEST_EVT */ -typedef struct { - aos_bt_device_address_t bd_addr; /*< BD Address of remote */ - aos_bool_t extended_oob_data; /*< TRUE if requesting extended OOB (P-256) */ -} aos_bt_dev_remote_oob_t; - -/* BR/EDR Pairing IO Capabilities (to be filled by application callback on BTM_PAIRING_IO_CAPABILITIES_REQUEST_EVT) */ -typedef struct { - aos_bt_device_address_t bd_addr; /*< [in] BD Address of remote */ - aos_bt_dev_io_cap_t local_io_cap; /*< local IO capabilities (to be filled by application callback) */ - aos_bt_dev_oob_data_t oob_data; /*< OOB data present at peer device for the local device */ - aos_bt_dev_auth_req_t auth_req; /*< Authentication required for peer device */ - aos_bool_t is_orig; /*< TRUE, if local device initiated the pairing process */ -} aos_bt_dev_bredr_io_caps_req_t; - -/* BLE Pairing IO Capabilities (to be filled by application callback on BTM_PAIRING_IO_CAPABILITIES_REQUEST_EVT) */ -typedef struct { - aos_bt_device_address_t bd_addr; /*< [in] BD Address of remote */ - aos_bt_dev_io_cap_t local_io_cap; /*< local IO capabilities (to be filled by application callback) */ - uint8_t - oob_data; /*< OOB data present (locally) for the peer device */ - aos_bt_dev_le_auth_req_t - auth_req; /*< Authentication request (for local device) contain bonding and MITM info */ - uint8_t - max_key_size; /*< Max encryption key size */ - aos_bt_dev_le_key_type_t - init_keys; /*< Keys to be distributed, bit mask */ - aos_bt_dev_le_key_type_t - resp_keys; /*< keys to be distributed, bit mask */ -} aos_bt_dev_ble_io_caps_req_t; - - -typedef struct { - BT_OCTET16 irk; /*< peer diverified identity root */ -#if SMP_INCLUDED == TRUE && SMP_LE_SC_INCLUDED == TRUE - BT_OCTET16 pltk; /*< peer long term key */ - BT_OCTET16 pcsrk; /*< peer SRK peer device used to secured sign local data */ - - BT_OCTET16 lltk; /*< local long term key */ - BT_OCTET16 lcsrk; /*< local SRK peer device used to secured sign local data */ -#else - BT_OCTET16 ltk; /*< peer long term key */ - BT_OCTET16 csrk; /*< peer SRK peer device used to secured sign local data */ -#endif - - BT_OCTET8 rand; /*< random vector for LTK generation */ - UINT16 ediv; /*< LTK diversifier of this slave device */ - UINT16 div; /*< local DIV to generate local LTK=d1(ER,DIV,0) and CSRK=d1(ER,DIV,1) */ - uint8_t sec_level; /*< local pairing security level */ - uint8_t key_size; /*< key size of the LTK delivered to peer device */ - uint8_t srk_sec_level; /*< security property of peer SRK for this device */ - uint8_t local_csrk_sec_level; /*< security property of local CSRK for this device */ - - UINT32 counter; /*< peer sign counter for verifying rcv signed cmd */ - UINT32 local_counter; /*< local sign counter for sending signed write cmd*/ -} aos_bt_ble_keys_t; - - -typedef struct { - /* BR/EDR key */ - uint8_t br_edr_key_type; /*< BR/EDR Link Key type */ - aos_bt_link_key_t br_edr_key; /*< BR/EDR Link Key */ - - /* LE Keys */ - aos_bt_dev_le_key_type_t le_keys_available_mask; /*< Mask of available BLE keys */ - aos_bt_ble_address_type_t ble_addr_type; /*< LE device type: public or random address */ - aos_bt_ble_address_type_t static_addr_type; /*< static address type */ - aos_bt_device_address_t static_addr; /*< static address */ - aos_bt_ble_keys_t le_keys; /*< LE keys */ -} aos_bt_device_sec_keys_t; - -/* Paired device link key notification (used by BTM_PAIRED_DEVICE_LINK_KEYS_UPDATE_EVT notication) */ -typedef struct { - aos_bt_device_address_t bd_addr; /*< [in] BD Address of remote */ - aos_bt_device_sec_keys_t key_data; /*< [in/out] Key data */ -} aos_bt_device_link_keys_t; - -/* advertisement type (used when calling aos_bt_start_advertisements) */ -#ifndef BTM_BLE_ADVERT_MODE -#define BTM_BLE_ADVERT_MODE -enum aos_bt_ble_advert_mode_e { - BTM_BLE_ADVERT_OFF, /*< Stop advertising */ - BTM_BLE_ADVERT_DIRECTED_HIGH, /*< Directed advertisement (high duty cycle) */ - BTM_BLE_ADVERT_DIRECTED_LOW, /*< Directed advertisement (low duty cycle) */ - BTM_BLE_ADVERT_UNDIRECTED_HIGH, /*< Undirected advertisement (high duty cycle) */ - BTM_BLE_ADVERT_UNDIRECTED_LOW, /*< Undirected advertisement (low duty cycle) */ - BTM_BLE_ADVERT_NONCONN_HIGH, /*< Non-connectable advertisement (high duty cycle) */ - BTM_BLE_ADVERT_NONCONN_LOW, /*< Non-connectable advertisement (low duty cycle) */ - BTM_BLE_ADVERT_DISCOVERABLE_HIGH, /*< discoverable advertisement (high duty cycle) */ - BTM_BLE_ADVERT_DISCOVERABLE_LOW /*< discoverable advertisement (low duty cycle) */ -}; -#endif -typedef uint8_t aos_bt_ble_advert_mode_t; /*< Advertisement type (see #aos_bt_ble_advert_mode_e) */ - -/* scan mode used in initiating */ -#ifndef BTM_BLE_CONN_MODE -#define BTM_BLE_CONN_MODE -enum aos_bt_ble_conn_mode_e { - BLE_CONN_MODE_OFF, /*< Stop initiating */ - BLE_CONN_MODE_LOW_DUTY, /*< slow connection scan parameter */ - BLE_CONN_MODE_HIGH_DUTY /*< fast connection scan parameter */ -}; -#endif -typedef uint8_t aos_bt_ble_conn_mode_t; /*< Conn mode (see #aos_bt_ble_conn_mode_e) */ - -/* Structure definitions for Bluetooth Management (aos_bt_management_cback_t) event notifications */ -typedef union { - /* Bluetooth status event data types*/ - aos_bt_dev_enabled_t enabled; /*< Data for BTM_ENABLED_EVT */ - aos_bt_power_mgmt_notification_t power_mgmt_notification; /*< Data for BTM_POWER_MANAGEMENT_STATUS_EVT */ - - /* Security event data types */ - aos_bt_dev_name_and_class_t pin_request; /*< Data for BTM_PIN_REQUEST_EVT */ - aos_bt_dev_user_cfm_req_t user_confirmation_request; /*< Data for BTM_USER_CONFIRMATION_REQUEST_EVT */ - aos_bt_dev_user_key_notif_t user_passkey_notification; /*< Data for BTM_USER_PASSKEY_NOTIFICATION_EVT */ - aos_bt_dev_user_key_req_t user_passkey_request; /*< Data for BTM_USER_PASSKEY_REQUEST_EVT */ - aos_bt_dev_user_keypress_t - user_keypress_notification; /*< Data for BTM_USER_KEYPRESS_NOTIFICATION_EVT - See #aos_bt_dev_user_keypress_t */ - aos_bt_dev_bredr_io_caps_req_t - pairing_io_capabilities_br_edr_request; /*< Data for BTM_PAIRING_IO_CAPABILITIES_BR_EDR_REQUEST_EVT */ - aos_bt_dev_bredr_io_caps_rsp_t - pairing_io_capabilities_br_edr_response;/*< Data for BTM_PAIRING_IO_CAPABILITIES_BR_EDR_RESPONSE_EVT */ - aos_bt_dev_ble_io_caps_req_t - pairing_io_capabilities_ble_request; /*< Data for BTM_PAIRING_IO_CAPABILITIES_BLE_REQUEST_EVT */ - aos_bt_dev_pairing_cplt_t pairing_complete; /*< Data for BTM_PAIRING_COMPLETE_EVT */ - aos_bt_dev_encryption_status_t encryption_status; /*< Data for BTM_ENCRYPTION_STATUS_EVT */ - aos_bt_dev_security_request_t security_request; /*< Data for BTM_SECURITY_REQUEST_EVT */ - aos_bt_dev_security_upgrade_t - security_upgrade; /*< Data for BTM_SECURITY_UPGRADE_EVT See #aos_bt_dev_security_upgrade_t */ - aos_bt_dev_name_and_class_t security_aborted; /*< Data for BTM_SECURITY_ABORTED_EVT */ - - aos_bt_dev_local_oob_t - read_local_oob_data_complete; /*< Data for BTM_READ_LOCAL_OOB_DATA_COMPLETE_EVT */ - aos_bt_dev_remote_oob_t remote_oob_data_request; /*< Data for BTM_REMOTE_OOB_DATA_REQUEST_EVT */ - - aos_bt_device_link_keys_t - paired_device_link_keys_update; /*< Data for BTM_PAIRED_DEVICE_LINK_KEYS_UPDATE_EVT */ - aos_bt_device_link_keys_t - paired_device_link_keys_request; /*< Data for BTM_PAIRED_DEVICE_LINK_KEYS_REQUEST_EVT */ - aos_bt_local_identity_keys_t - local_identity_keys_update; /*< Data for BTM_LOCAL_IDENTITY_KEYS_UPDATE_EVT */ - aos_bt_local_identity_keys_t - local_identity_keys_request; /*< Data for BTM_LOCAL_IDENTITY_KEYS_REQUEST_EVT */ - - aos_bt_ble_scan_type_t ble_scan_state_changed; /*< Data for BTM_BLE_SCAN_STATE_CHANGED_EVT */ - aos_bt_ble_advert_mode_t ble_advert_state_changed; /*< Data for BTM_BLE_ADVERT_STATE_CHANGED_EVT */ - - aos_bt_smp_remote_oob_req_t - smp_remote_oob_data_request; /*< Data for BTM_SMP_REMOTE_OOB_DATA_REQUEST_EVT */ - aos_bt_smp_sc_remote_oob_req_t - smp_sc_remote_oob_data_request; /*< Data for BTM_SMP_SC_REMOTE_OOB_DATA_REQUEST_EVT */ - aos_bt_smp_sc_local_oob_t - *p_smp_sc_local_oob_data; /*< Data for BTM_SMP_SC_LOCAL_OOB_DATA_NOTIFICATION_EVT */ - - aos_bt_sco_connected_t sco_connected; /*< Data for BTM_SCO_CONNECTED_EVT */ - aos_bt_sco_disconnected_t sco_disconnected; /*< Data for BTM_SCO_DISCONNECTED_EVT */ - aos_bt_sco_connection_request_t sco_connection_request; /*< Data for BTM_SCO_CONNECTION_REQUEST_EVT */ - aos_bt_sco_connection_change_t sco_connection_change; /*< Data for BTM_SCO_CONNECTION_CHANGE_EVT */ - -} aos_bt_management_evt_data_t; - -/* - * Bluetooth Management callback - * - * Callback for Bluetooth Management event notifications. - * Registered using aos_bt_stack_init() - * - * @param event : Event ID - * @param p_event_data : Event data - * - * @return Status of event handling - */ -typedef aos_bt_result_t (aos_bt_management_cback_t) (aos_bt_management_evt_t event, - aos_bt_management_evt_data_t *p_event_data); - -/* - * Connection status change callback - * - * Callback for Bluetooth Management event notifications. - * Registered using aos_bt_register_connection_status_change() - * - * @param[in] bd_addr : BD Address of remote - * @param[in] p_features - * @param[in] is_connected : TRUE if connected - * @param[in] handle : Connection handle - * @param[in] transport : BT_TRANSPORT_BR_EDR or BT_TRANSPORT_LE - * - * @return void - */ -typedef void (aos_bt_connection_status_change_cback_t) (aos_bt_device_address_t bd_addr, uint8_t *p_features, - aos_bool_t is_connected, uint16_t handle, aos_bt_transport_t transport); /*< connection status change callback */ - - -/* - * Inquiry result callback. - * - * @param p_inquiry_result : Inquiry result data (NULL if inquiry is complete) - * @param p_eir_data : Extended inquiry response data - * - * @return Nothing - */ -typedef void (aos_bt_inquiry_result_cback_t) (aos_bt_dev_inquiry_scan_result_t *p_inquiry_result, - uint8_t *p_eir_data); /*< inquiry result callback */ - -/* - * Synchronous BTM operation is complete. - * - * @param p_data : Operation dependent data - * - * @return Nothing - */ -typedef void (aos_bt_dev_cmpl_cback_t) (void *p_data); - -/* - * Vendor specific command complete - * - * @param p_command_complete_params : Command complete parameters - * - * @return Nothing - */ -typedef void (aos_bt_dev_vendor_specific_command_complete_cback_t) (aos_bt_dev_vendor_specific_command_complete_params_t - *p_command_complete_params); - -/***************************************************** - * Function Declarations - ******************************************************/ -#ifdef __cplusplus -extern "C" { -#endif - -/***************************************************************************/ -/* - * Device Management Functions - * - * @addtogroup aosbt_DeviceManagement Device Management - * @ingroup aosbt - * - * @{ - */ -/***************************************************************************/ - - -/***************************************************************************/ -/* - * Bluetooth Basic Rate / Enhanced Data Rate Functions - * - * @addtogroup aosbt_bredr BR/EDR (Bluetooth Basic Rate / Enhanced Data Rate) - * @ingroup aosbt_DeviceManagement - * - * @{ - */ -/***************************************************************************/ - -/* - * Function aos_bt_start_inquiry - * - * Begin BR/EDR inquiry for peer devices. - * - * @param[in] p_inqparms : inquiry parameters - * @param[in] p_inquiry_result_cback : inquiry results callback - * - * @return aos_bt_result_t - * - * AOS_BT_PENDING if successfully initiated - * AOS_BT_BUSY if already in progress - * AOS_BT_ILLEGAL_VALUE if parameter(s) are out of range - * AOS_BT_NO_RESOURCES if could not allocate resources to start the command - * AOS_BT_WRONG_MODE if the device is not up. - */ -aos_bt_result_t aos_bt_start_inquiry (aos_bt_dev_inq_parms_t *p_inqparms, - aos_bt_inquiry_result_cback_t *p_inquiry_result_cback); - -/* - * Function aos_bt_cancel_inquiry - * - * Cancel inquiry - * - * @return - * - * AOS_BT_SUCCESS if successful - * AOS_BT_NO_RESOURCES if could not allocate a message buffer - * AOS_BT_WRONG_MODE if the device is not up. - */ -aos_bt_result_t aos_bt_cancel_inquiry(void); - -/* - * Function aos_bt_dev_read_local_addr - * - * Read the local device address - * - * @param[out] bd_addr : Local bd address - * - * @return void - * - */ -void aos_bt_dev_read_local_addr (aos_bt_device_address_t bd_addr); - - -/* - * Function aos_bt_dev_set_advanced_connection_params - * - * Set advanced connection parameters for subsequent BR/EDR connections - * (remote clock offset, page scan mode, and other information obtained during inquiry) - * - * If not called, then default connection parameters will be used. - * - * @param[in] p_inquiry_scan_result : Inquiry scan result (from #aos_bt_inquiry_result_cback_t) - * - * @return aos_bt_result_t - * - * AOS_BT_SUCCESS : on success; - * AOS_BT_FAILED : if an error occurred - */ -aos_bt_result_t aos_bt_dev_set_advanced_connection_params (aos_bt_dev_inquiry_scan_result_t *p_inquiry_scan_result); - - -/* - * Function aos_bt_dev_set_local_device_address - * - * - * Set local Bluetooth Device Address. - * - * @param[in] bdaddr : Bluetooth Device Address - * @param[in] p_cback : Callback for command complete - * - * @return - * - * AOS_BT_SUCCESS : Command sent. Does not expect command complete event. (command complete callback param is NULL) - * AOS_BT_NO_RESOURCES: Failure and no resources. - * - */ -aos_bt_result_t aos_bt_dev_set_local_device_address(aos_bt_device_address_t bdaddr, - aos_bt_dev_cmpl_cback_t *p_cback); - -/* - * Function aos_bt_dev_vendor_specific_command - * - * Send a vendor specific HCI command to the controller. - * - * @param[in] opcode : Opcode of vendor specific command - * @param[in] param_len : Length of parameter buffer - * @param[in] p_param_buf : Parameters - * @param[in] p_cback : Callback for command complete - * - * @return - * - * AOS_BT_SUCCESS : Command sent. Does not expect command complete event. (command complete callback param is NULL) - * AOS_BT_PENDING : Command sent. Waiting for command complete event. - * AOS_BT_BUSY : Command not sent. Waiting for command complete event for prior command. - * - */ -aos_bt_result_t aos_bt_dev_vendor_specific_command (uint16_t opcode, uint8_t param_len, uint8_t *p_param_buf, - aos_bt_dev_vendor_specific_command_complete_cback_t *p_cback); - -/* - * Function aos_bt_dev_set_discoverability - * - * Set discoverability - * - * @note The duration must be less than or equal to the interval. - * - * @param[in] inq_mode : Discoverability mode (see #aos_bt_discoverability_mode_e) - * @param[in] duration : Duration (in 0.625 msec intervals). BTM_DEFAULT_DISC_WINDOW, or range: 0x0012 ~ 0x1000 (11.25 ~ 2560 msecs) - * @param[in] interval : Interval (in 0.625 msec intervals). BTM_DEFAULT_DISC_INTERVAL, or range: 0x0012 ~ 0x1000 (11.25 ~ 2560 msecs) - * - * @return - * - * AOS_BT_SUCCESS: If successful - * AOS_BT_BUSY: If a setting of the filter is already in progress - * AOS_BT_NO_RESOURCES: If couldn't get a memory pool buffer - * AOS_BT_ILLEGAL_VALUE: If a bad parameter was detected - * AOS_BT_WRONG_MODE: If the device is not up - */ -aos_bt_result_t aos_bt_dev_set_discoverability (uint8_t inq_mode, uint16_t duration, - uint16_t interval); - -/* - * Function aos_bt_dev_set_connectability - * - * Set connectablilty - * - * @note The duration (window parameter) must be less than or equal to the interval. - * - * @param[in] page_mode : Connectability mode (see #aos_bt_connectability_mode_e) - * @param[in] window : Duration (in 0.625 msec intervals). BTM_DEFAULT_CONN_WINDOW, or range: 0x0012 ~ 0x1000 (11.25 ~ 2560 msecs) - * @param[in] interval : Interval (in 0.625 msec intervals). BTM_DEFAULT_CONN_INTERVAL, or range: 0x0012 ~ 0x1000 (11.25 ~ 2560 msecs) - * - * @return - * - * AOS_BT_SUCCESS: If successful - * AOS_BT_ILLEGAL_VALUE: If a bad parameter is detected - * AOS_BT_NO_RESOURCES: If could not allocate a message buffer - * AOS_BT_WRONG_MODE: If the device is not up - */ -aos_bt_result_t aos_bt_dev_set_connectability (uint8_t page_mode, uint16_t window, - uint16_t interval); -/* - * Function aos_bt_dev_register_connection_status_change - * - * Register callback for connection status change - * - * - * @param[in] p_aos_bt_connection_status_change_cback - Callback for connection status change - * - * @return aos_bt_result_t - * - * AOS_BT_SUCCESS : on success; - * AOS_BT_FAILED : if an error occurred - */ -aos_bt_result_t aos_bt_dev_register_connection_status_change(aos_bt_connection_status_change_cback_t - *p_aos_bt_connection_status_change_cback); - -/* - * Function aos_bt_dev_set_sniff_mode - * - * Set a connection into sniff mode. - * - * @param[in] remote_bda : Link for which to put into sniff mode - * @param[in] min_period : Minimum sniff period - * @param[in] max_period : Maximum sniff period - * @param[in] attempt : Number of attempts for switching to sniff mode - * @param[in] timeout : Timeout for attempting to switch to sniff mode - * - * @return AOS_BT_PENDING if successfully initiated, otherwise error - */ -aos_bt_result_t aos_bt_dev_set_sniff_mode (aos_bt_device_address_t remote_bda, uint16_t min_period, - uint16_t max_period, uint16_t attempt, - uint16_t timeout); - - -/* - * Function aos_bt_dev_cancel_sniff_mode - * - * Take a connection out of sniff mode. - * A check is made if the connection is already in sniff mode, - * and if not, the cancel sniff mode is ignored. - * - * @return AOS_BT_PENDING if successfully initiated, otherwise error - * - */ -aos_bt_result_t aos_bt_dev_cancel_sniff_mode (aos_bt_device_address_t remote_bda); - - -/* - * - * Function aos_bt_dev_set_sniff_subrating - * - * Set sniff subrating parameters for an active connection - * - * @param[in] remote_bda : device address of desired ACL connection - * @param[in] max_latency : maximum latency (in 0.625ms units) (range: 0x0002-0xFFFE) - * @param[in] min_remote_timeout : minimum remote timeout - * @param[in] min_local_timeout : minimum local timeout - * - * @return - * - * AOS_BT_SUCCESS : on success; - * AOS_BT_ILLEGAL_ACTION : if an error occurred - */ -aos_bt_result_t aos_bt_dev_set_sniff_subrating (aos_bt_device_address_t remote_bda, uint16_t max_latency, - uint16_t min_remote_timeout, uint16_t min_local_timeout); - -/* - * Function aos_bt_dev_read_rssi - * - * Get Receive Signal Strenth Index (RSSI) for the requested link - * - * @param[in] remote_bda : BD address of connection to read rssi - * @param[in] transport : Transport type - * @param[in] p_cback : Result callback (aos_bt_dev_rssi_result_t will be passed to the callback) - * - * @return - * - * AOS_BT_PENDING if command issued to controller. - * AOS_BT_NO_RESOURCES if couldn't allocate memory to issue command - * AOS_BT_UNKNOWN_ADDR if no active link with bd addr specified - * AOS_BT_BUSY if command is already in progress - * - */ -aos_bt_result_t aos_bt_dev_read_rssi (aos_bt_device_address_t remote_bda, aos_bt_transport_t transport, - aos_bt_dev_cmpl_cback_t *p_cback); - -/* - * Function aos_bt_dev_read_tx_power - * - * Read the transmit power for the requested link - * - * @param[in] remote_bda : BD address of connection to read tx power - * @param[in] transport : Transport type - * @param[in] p_cback : Result callback (aos_bt_tx_power_result_t will be passed to the callback) - * - * @return - * - * AOS_BT_PENDING if command issued to controller. - * AOS_BT_NO_RESOURCES if couldn't allocate memory to issue command - * AOS_BT_UNKNOWN_ADDR if no active link with bd addr specified - * AOS_BT_BUSY if command is already in progress - * - */ -aos_bt_result_t aos_bt_dev_read_tx_power (aos_bt_device_address_t remote_bda, aos_bt_transport_t transport, - aos_bt_dev_cmpl_cback_t *p_cback); - - -/* - * - * Function aos_bt_dev_write_eir - * - * Write EIR data to controller. - * - * @param[in] p_buff : EIR data - * @param[in] len : Length of EIR data - * - * @return AOS_BT_SUCCESS if successful - * AOS_BT_NO_RESOURCES if couldn't allocate memory to issue command - * AOS_BT_UNSUPPORTED if local device cannot support request - * - */ -aos_bt_result_t aos_bt_dev_write_eir (uint8_t *p_buff, uint16_t len); - -/*@} aosbt_bredr */ - -/**************************************************************************** - * SECURITY MANAGEMENT FUNCTIONS - ****************************************************************************/ -/***************************************************************************/ -/* - * Bluetooth Security Functions - * - * @addtogroup btm_sec_api_functions Security - * @ingroup aosbt_DeviceManagement - * - * @{ - */ - - -/* - * Function aos_bt_dev_set_pin_code_only - * - * Set the latency pairing mode. - * - * @param[in] enable : Pin Code Only Mode is enable or not. - * - * @return aos_bt_result_t - */ -aos_bt_result_t aos_bt_dev_set_pin_code_only(aos_bool_t enable); - -/* - * Function aos_bt_dev_set_security_mode - * - * Set PIN type for the device. - * - * @param[in] fixed_pin : fixed pin if TRUE or variable pin. - * @param[in] pin_code : this arguement must be set if pin type is fixed. - * @param[in] pin_code_len: length of pin code. - * - */ -void aos_bt_dev_set_pin_type(aos_bool_t fixed_pin, uint8_t *pin_code, uint8_t pin_code_len); - - -/* - * Function aos_bt_dev_pin_code_reply - * - * PIN code reply (use in response to BTM_PIN_REQUEST_EVT in #aos_bt_management_cback_t) - * - * @param[in] bd_addr : Address of the device for which PIN was requested - * @param[in] res : result of the operation AOS_BT_SUCCESS if success - * @param[in] pin_len : length in bytes of the PIN Code - * @param[in] p_pin : pointer to array with the PIN Code - * - * @return void - */ -void aos_bt_dev_pin_code_reply (aos_bt_device_address_t bd_addr, aos_bt_result_t res, uint8_t pin_len, uint8_t *p_pin); - -/* - * Function aos_bt_dev_sec_bond - * - * Bond with peer device. If the connection is already up, but not secure, pairing is attempted. - * - * @note PIN parameters are only needed when bonding with legacy devices (pre-2.1 Core Spec) - * - * @param[in] bd_addr : Peer device bd address to pair with. - * @param[in] bd_addr_type : BLE_ADDR_PUBLIC or BLE_ADDR_RANDOM (applies to LE devices only) - * @param[in] transport : BT_TRANSPORT_BR_EDR or BT_TRANSPORT_LE - * @param[in] pin_len : Length of input parameter p_pin (0 if not used). - * @param[in] p_pin : Pointer to Pin Code to use (NULL if not used). - * - * @return - * - * AOS_BT_PENDING if successfully initiated, - * AOS_BT_SUCCESS if already paired to the device, else - * error code - */ -aos_bt_result_t aos_bt_dev_sec_bond (aos_bt_device_address_t bd_addr, aos_bt_ble_address_type_t bd_addr_type, - aos_bt_transport_t transport, uint8_t pin_len, uint8_t *p_pin); - - -/* - * Function aos_bt_dev_sec_bond_cancel - * - * Cancel an ongoing bonding process with peer device. - * - * @param[in] bd_addr : Peer device bd address to pair with. - * - * @return - * - * AOS_BT_PENDING if cancel initiated, - * AOS_BT_SUCCESS if cancel has completed already, else error code. - */ -aos_bt_result_t aos_bt_dev_sec_bond_cancel (aos_bt_device_address_t bd_addr); - - -/* - * Function aos_bt_dev_set_encryption - * - * Encrypt the specified connection. - * Status is notified using BTM_ENCRYPTION_STATUS_EVT of #aos_bt_management_cback_t. - * - * @param[in] bd_addr : Address of peer device - * @param[in] transport : BT_TRANSPORT_BR_EDR or BT_TRANSPORT_LE - * @param[in] p_ref_data : pointer to reference data to be passed upon completion (NULL if no data) - * - * @return - * - * AOS_BT_SUCCESS : already encrypted - * AOS_BT_PENDING : command will be returned in the callback - * AOS_BT_WRONG_MODE : connection not up. - * AOS_BT_BUSY : security procedures are currently active - */ -aos_bt_result_t aos_bt_dev_set_encryption (aos_bt_device_address_t bd_addr, aos_bt_transport_t transport, - void *p_ref_data); - - -/* - * Function aos_bt_dev_confirm_req_reply - * - * Confirm the numeric value for pairing (in response to BTM_USER_CONFIRMATION_REQUEST_EVT of #aos_bt_management_cback_t) - * - * @param[in] res : result of the operation AOS_BT_SUCCESS if success - * @param[in] bd_addr : Address of the peer device - * - * @return void - */ -void aos_bt_dev_confirm_req_reply(aos_bt_result_t res, aos_bt_device_address_t bd_addr); - -/* - * Function aos_bt_dev_pass_key_req_reply - * - * Provide the pairing passkey (in response to BTM_PASSKEY_REQUEST_EVT of #aos_bt_management_cback_t) - * - * @param[in] res : result of the operation AOS_BT_SUCCESS if success - * @param[in] bd_addr : Address of the peer device - * @param[in] passkey : numeric value in the range of 0 - 999999(0xF423F). - * - * @return void - */ -void aos_bt_dev_pass_key_req_reply(aos_bt_result_t res, aos_bt_device_address_t bd_addr, uint32_t passkey); - -/* - * Function aos_bt_dev_send_key_press_notif - * - * Inform remote device of keypress during pairing. - * - * Used during the passkey entry by a device with KeyboardOnly IO capabilities - * (typically a HID keyboard device). - * - * @param[in] bd_addr : Address of the peer device - * @param[in] type : notification type - * - */ -void aos_bt_dev_send_key_press_notif(aos_bt_device_address_t bd_addr, aos_bt_dev_passkey_entry_type_t type); - -/* - * - * Function aos_bt_dev_read_local_oob_data - * - * Read the local OOB data from controller (for sending - * to peer device over oob message). When - * operation is completed, local OOB data will be - * provided via BTM_READ_LOCAL_OOB_DATA_COMPLETE_EVT. - * - */ -aos_bt_result_t aos_bt_dev_read_local_oob_data(void); - -/* - * Function aos_bt_dev_remote_oob_data_reply - * - * Provide the remote OOB extended data for Simple Pairing - * in response to BTM_REMOTE_OOB_DATA_REQUEST_EVT - * - * @param[in] bd_addr : Address of the peer device - * @param[in] is_extended_oob_data : TRUE if extended OOB data (set according to BTM_REMOTE_OOB_DATA_REQUEST_EVT request) - * @param[in] c_192 : simple pairing Hash C derived from the P-192 public key. - * @param[in] r_192 : simple pairing Randomizer R associated with the P-192 public key. - * @param[in] c_256 : simple pairing Hash C derived from the P-256 public key (if is_extended_oob_data=TRUE) - * @param[in] r_256 : simple pairing Randomizer R associated with the P-256 public key (if is_extended_oob_data=TRUE) - * - */ -void aos_bt_dev_remote_oob_data_reply (aos_bt_result_t res, aos_bt_device_address_t bd_addr, - aos_bool_t is_extended_oob_data, - BT_OCTET16 c_192, BT_OCTET16 r_192, - BT_OCTET16 c_256, BT_OCTET16 r_256); - -/* - * - * Function aos_bt_dev_build_oob_data - * - * Build the OOB data block to be used to send OOB extended - * data over OOB (non-Bluetooth) link. - * - * @param[out] p_data : OOB data block location - * @param[in] max_len : OOB data block size - * @param[in] is_extended_oob_data : TRUE if extended OOB data (for Secure Connections) - * @param[in] c_192 : simple pairing Hash C derived from the P-192 public key. - * @param[in] r_192 : simple pairing Randomizer R associated with the P-192 public key. - * @param[in] c_256 : simple pairing Hash C derived from the P-256 public key (if is_extended_oob_data=TRUE) - * @param[in] r_256 : simple pairing Randomizer R associated with the P-256 public key (if is_extended_oob_data=TRUE) - * - * @return Number of bytes put into OOB data block. - * - */ -uint16_t aos_bt_dev_build_oob_data(uint8_t *p_data, uint16_t max_len, - aos_bool_t is_extended_oob_data, - BT_OCTET16 c_192, BT_OCTET16 r_192, - BT_OCTET16 c_256, BT_OCTET16 r_256); - -/* - * - * Function aos_bt_smp_oob_data_reply - * - * This function is called to provide the OOB data for - * SMP in response to BTM_SMP_REMOTE_OOB_DATA_REQUEST_EVT - * - * @param[in] bd_addr - Address of the peer device - * @param[in] res - result of the operation AOS_BT_SUCCESS if success - * @param[in] len - oob data length - * @param[in] p_data - oob data - * - */ -void aos_bt_smp_oob_data_reply(aos_bt_device_address_t bd_addr, aos_bt_result_t res, uint8_t len, uint8_t *p_data); - -/* - * Function aos_bt_smp_create_local_sc_oob_data - * - * Create local BLE SC (secure connection) OOB data. When - * operation is completed, local OOB data will be - * provided via BTM_SMP_SC_LOCAL_OOB_DATA_NOTIFICATION_EVT. - * - * @param[in] bd_addr : intended remote address for the OOB data - * @param[in] bd_addr_type : BLE_ADDR_PUBLIC or BLE_ADDR_PUBLIC - * - * @return TRUE: creation of local SC OOB data set started. - * - */ -aos_bool_t aos_bt_smp_create_local_sc_oob_data (aos_bt_device_address_t bd_addr, - aos_bt_ble_address_type_t bd_addr_type); - -/* - * - * Function aos_bt_smp_sc_oob_reply - * - * Description Provide the SC OOB data for SMP in response to - * BTM_SMP_SC_REMOTE_OOB_DATA_REQUEST_EVT - * - * @param[in] p_oob_data : oob data - * - */ -void aos_bt_smp_sc_oob_reply (uint8_t *p_oob_data); - -/*@} btm_sec_api_functions */ - - -/*@} aosbt_DeviceManagement */ - - -/* HCI trace types */ -typedef enum { - HCI_TRACE_EVENT, /*< HCI event data from controller to the host */ - HCI_TRACE_COMMAND, /*< HCI command data from host to controller */ - HCI_TRACE_INCOMING_ACL_DATA,/*< HCI incoming acl data */ - HCI_TRACE_OUTGOING_ACL_DATA/*< HCI outgoing acl data */ -} aos_bt_hci_trace_type_t; - -/* - * HCI trace callback - * - * Callback for HCI traces - * Registered using aos_bt_dev_register_hci_trace() - * - * @param[in] type : Trace type - * @param[in] length : Length of the trace data - * @param[in] p_data : Pointer to the data - * - * @return void - */ -typedef void ( aos_bt_hci_trace_cback_t )( aos_bt_hci_trace_type_t type, uint16_t length, uint8_t *p_data ); - -/* - * Function aos_bt_dev_register_hci_trace - * - * Register to get the hci traces - * - * @param[in] p_cback : Callback for hci traces - * - * @return void - * - */ -void aos_bt_dev_register_hci_trace( aos_bt_hci_trace_cback_t *p_cback ); - -/* - * Function aos_bt_dev_get_bonded_devices - * - * get bonded device list - * - * @param[out] p_paired_device_list : array for getting bd address of bonded devices - * @param[in/out] p_num_devices : list size of p_pared_device_list total number of bonded devices stored - * - * @return aos_bt_result_t - * - */ -aos_bt_result_t aos_bt_dev_get_bonded_devices(aos_bt_dev_bonded_device_info_t *p_paired_device_list, - uint16_t *p_num_devices); - -/* - * Function aos_bt_dev_find_bonded_device - * - * check a device is bonded or not - * - * @param[in] bd_addr : Address of the peer device - * - * @return aos_bool_t - * - */ -aos_bool_t aos_bt_dev_find_bonded_device( aos_bt_device_address_t bd_addr); - -/* - * Function aos_bt_dev_get_key_by_keytype - * - * get security key from a bonded device - * - * @param[in] bd_addr : Address of the peer device - * @param[in] key_type : The achieved key type - * @param[out] p_sec_keys : The memory to hold the achieved key value - * - * @return aos_bt_result_t - * - */ -aos_bt_result_t aos_bt_dev_get_key_by_keytype(aos_bt_device_address_t bd_addr, aos_bt_dev_le_key_type_t key_type, - aos_bt_security_key_value_t *p_sec_keys); - -/* - * Function aos_bt_dev_delete_bonded_device - * - * remove bonding with remote device with assigned bd_addr - * - * @param[in] bd_addr : bd_addr of remote device to be removed from bonding list - * - * @return aos_bt_result_t - * - */ -aos_bt_result_t aos_bt_dev_delete_bonded_device(aos_bt_device_address_t bd_addr); - -/* - * Function aos_bt_dev_add_device_to_address_resolution_db - * - * add link key information to internal address resolution db - * - * @param[in] p_link_keys : link keys information stored in application side - * - * @return aos_bt_result_t - * - */ -aos_bt_result_t aos_bt_dev_add_device_to_address_resolution_db(aos_bt_device_link_keys_t *p_link_keys); - -/* - * Function aos_bt_dev_remove_device_from_address_resolution_db - * - * remove link key information from internal address resolution db - * - * @param[in] p_link_keys : link keys information stored in application side - * - * @return aos_bt_result_t - * - */ -aos_bt_result_t aos_bt_dev_remove_device_from_address_resolution_db(aos_bt_device_link_keys_t *p_link_keys); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/kernel/protocols/bluetooth/include/aos_bt_gatt.h b/kernel/protocols/bluetooth/include/aos_bt_gatt.h deleted file mode 100644 index 2a88874bde..0000000000 --- a/kernel/protocols/bluetooth/include/aos_bt_gatt.h +++ /dev/null @@ -1,968 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -/* @file - * - * AOS Generic Attribute (GATT) Application Programming Interface - */ - -#ifndef _AOS_BT_GATT_H_ -#define _AOS_BT_GATT_H_ - -#include "gattdefs.h" -#include "aos_bt_dev.h" -#include "l2cdefs.h" -#include "aos_bt_types.h" - -/* GATT Status Codes*/ -enum aos_bt_gatt_status_e { - AOS_BT_GATT_SUCCESS = 0x00, /* Success */ - AOS_BT_GATT_INVALID_HANDLE = 0x01, /* Invalid Handle */ - AOS_BT_GATT_READ_NOT_PERMIT = 0x02, /* Read Not Permitted */ - AOS_BT_GATT_WRITE_NOT_PERMIT = 0x03, /* Write Not permitted */ - AOS_BT_GATT_INVALID_PDU = 0x04, /* Invalid PDU */ - AOS_BT_GATT_INSUF_AUTHENTICATION = 0x05, /* Insufficient Authentication */ - AOS_BT_GATT_REQ_NOT_SUPPORTED = 0x06, /* Request Not Supported */ - AOS_BT_GATT_INVALID_OFFSET = 0x07, /* Invalid Offset */ - AOS_BT_GATT_INSUF_AUTHORIZATION = 0x08, /* Insufficient Authorization */ - AOS_BT_GATT_PREPARE_Q_FULL = 0x09, /* Prepare Queue Full */ - AOS_BT_GATT_NOT_FOUND = 0x0a, /* Not Found */ - AOS_BT_GATT_NOT_LONG = 0x0b, /* Not Long Size */ - AOS_BT_GATT_INSUF_KEY_SIZE = 0x0c, /* Insufficient Key Size */ - AOS_BT_GATT_INVALID_ATTR_LEN = 0x0d, /* Invalid Attribute Length */ - AOS_BT_GATT_ERR_UNLIKELY = 0x0e, /* Error Unlikely */ - AOS_BT_GATT_INSUF_ENCRYPTION = 0x0f, /* Insufficient Encryption */ - AOS_BT_GATT_UNSUPPORT_GRP_TYPE = 0x10, /* Unsupported Group Type */ - AOS_BT_GATT_INSUF_RESOURCE = 0x11, /* Insufficient Resource */ - - AOS_BT_GATT_ILLEGAL_PARAMETER = 0x87, /* Illegal Parameter */ - AOS_BT_GATT_NO_RESOURCES = 0x80, /* No Resources */ - AOS_BT_GATT_INTERNAL_ERROR = 0x81, /* Internal Error */ - AOS_BT_GATT_WRONG_STATE = 0x82, /* Wrong State */ - AOS_BT_GATT_DB_FULL = 0x83, /* DB Full */ - AOS_BT_GATT_BUSY = 0x84, /* Busy */ - AOS_BT_GATT_ERROR = 0x85, /* Error */ - AOS_BT_GATT_CMD_STARTED = 0x86, /* Command Started */ - AOS_BT_GATT_PENDING = 0x88, /* Pending */ - AOS_BT_GATT_AUTH_FAIL = 0x89, /* Authentication Fail */ - AOS_BT_GATT_MORE = 0x8a, /* More */ - AOS_BT_GATT_INVALID_CFG = 0x8b, /* Invalid Configuration */ - AOS_BT_GATT_SERVICE_STARTED = 0x8c, /* Service Started */ - AOS_BT_GATT_ENCRYPED_MITM = AOS_BT_GATT_SUCCESS, /* Encrypted MITM */ - AOS_BT_GATT_ENCRYPED_NO_MITM = 0x8d, /* Encrypted No MITM */ - AOS_BT_GATT_NOT_ENCRYPTED = 0x8e, /* Not Encrypted */ - AOS_BT_GATT_CONGESTED = 0x8f, /* Congested */ - - /* 0xE0 ~ 0xFC reserved for future use */ - AOS_BT_GATT_CCC_CFG_ERR = 0xFD, /* Improper Client Char Configuration */ - AOS_BT_GATT_PRC_IN_PROGRESS = 0xFE, /* Procedure Already in Progress */ - AOS_BT_GATT_OUT_OF_RANGE = 0xFF, /* Value Out of Range */ -}; -typedef uint8_t aos_bt_gatt_status_t; /* GATT status (see #aos_bt_gatt_status_e) */ - - -/* GATT Status Codes*/ -enum aos_bt_gatt_app_interface_e { - GATT_IF_FIXED_DB_GAP = 0x01, - GATT_IF_FIXED_DB_APP = 0x02, - GATT_IF_CLIENT = 0x03, -}; -typedef uint8_t aos_bt_gatt_app_interface_t; /* GATT status (see #aos_bt_gatt_status_e) */ - - -/* GATT Operation Codes */ -#define GATT_RSP_ERROR 0x01 /* Error Response */ -#define GATT_REQ_MTU 0x02 /* Exchange MTU Request */ -#define GATT_RSP_MTU 0x03 /* Exchange MTU Response */ -#define GATT_REQ_FIND_INFO 0x04 /* Find Information Request */ -#define GATT_RSP_FIND_INFO 0x05 /* Find Information Response */ -#define GATT_REQ_FIND_TYPE_VALUE 0x06 /* Find By Type Value Request */ -#define GATT_RSP_FIND_TYPE_VALUE 0x07 /* Find By Type Value Response */ -#define GATT_REQ_READ_BY_TYPE 0x08 /* Read By Type Request */ -#define GATT_RSP_READ_BY_TYPE 0x09 /* Read By Type Response */ -#define GATT_REQ_READ 0x0A /* Read Request */ -#define GATT_RSP_READ 0x0B /* Read Response */ -#define GATT_REQ_READ_BLOB 0x0C /* Read Blob Request */ -#define GATT_RSP_READ_BLOB 0x0D /* Read Blob Response */ -#define GATT_REQ_READ_MULTI 0x0E /* Read Multiple Request */ -#define GATT_RSP_READ_MULTI 0x0F /* Read Multiple Response */ -#define GATT_REQ_READ_BY_GRP_TYPE 0x10 /* Read By Group Type Request */ -#define GATT_RSP_READ_BY_GRP_TYPE 0x11 /* Read By Group Type Response */ -#define GATT_REQ_WRITE 0x12 /* Write Request */ -#define GATT_RSP_WRITE 0x13 /* Write Request */ -#define GATT_CMD_WRITE 0x52 /* Write Command */ -#define GATT_REQ_PREPARE_WRITE 0x16 /* Prepare Write Request */ -#define GATT_RSP_PREPARE_WRITE 0x17 /* Prepare Write Response */ -#define GATT_REQ_EXEC_WRITE 0x18 /* Execute Write Request */ -#define GATT_RSP_EXEC_WRITE 0x19 /* Execute Write Response */ -#define GATT_HANDLE_VALUE_NOTIF 0x1B /* Handle Value Notification */ -#define GATT_HANDLE_VALUE_IND 0x1D /* Handle Value Indication */ -#define GATT_HANDLE_VALUE_CONF 0x1E /* Handle Value Confirmation */ -#define GATT_OP_CODE_MAX (GATT_HANDLE_VALUE_CONF + 1) /* Maximum opcode value */ -#define GATT_SIGN_CMD_WRITE 0xD2 /* changed in V4.0 1101-0010 (signed write) see write cmd above*/ - -/* GATT Disconnection reason */ -enum aos_bt_gatt_disconn_reason_e { - GATT_CONN_UNKNOWN = 0, /* Unknown reason */ - GATT_CONN_L2C_FAILURE = 1, /* General L2cap failure */ - GATT_CONN_TIMEOUT = HCI_ERR_CONNECTION_TOUT, /* Connection timeout */ - GATT_CONN_TERMINATE_PEER_USER = HCI_ERR_PEER_USER, /* Connection terminated by peer user */ - GATT_CONN_TERMINATE_LOCAL_HOST = HCI_ERR_CONN_CAUSE_LOCAL_HOST, /* Connection terminated by local host */ - GATT_CONN_FAIL_ESTABLISH = HCI_ERR_CONN_FAILED_ESTABLISHMENT, /* Connection fail to establish */ - GATT_CONN_LMP_TIMEOUT = HCI_ERR_LMP_RESPONSE_TIMEOUT, /* Connection fail due to LMP response tout */ - GATT_CONN_CANCEL = L2CAP_CONN_CANCEL /* L2CAP connection cancelled */ -}; -typedef uint16_t aos_bt_gatt_disconn_reason_t; /* GATT disconnection reason (see #aos_bt_gatt_disconn_reason_e) */ - -/* default GATT MTU size over LE link -*/ -#define GATT_DEF_BLE_MTU_SIZE 23 - -/* invalid connection ID -*/ -#define GATT_INVALID_CONN_ID 0xFFFF - - -/* characteristic descriptor: client configuration value */ -enum aos_bt_gatt_client_char_config_e { - GATT_CLIENT_CONFIG_NONE = 0x0000, /* Does not allow both notifications and indications */ - GATT_CLIENT_CONFIG_NOTIFICATION = 0x0001, /* Allows notifications */ - GATT_CLIENT_CONFIG_INDICATION = 0x0002 /* Allows indications */ -}; -typedef uint16_t -aos_bt_gatt_client_char_config_t; /* GATT client config (see #aos_bt_gatt_client_char_config_e) */ - -/* characteristic descriptor: server configuration value */ -#define GATT_SERVER_CONFIG_NONE 0x0000 /* No broadcast */ -#define GATT_SERVER_CONFIG_BROADCAST 0x0001 /* Broadcast */ -typedef uint16_t -aos_bt_gatt_server_char_config_t; /* GATT server config (see #aos_bt_gatt_server_char_config_e) */ - - -/* GATT Characteristic Properties Mask */ -enum aos_bt_gatt_char_properties_e { - GATT_CHAR_PROPERTIES_BIT_BROADCAST = (1 << 0), /* bit 0: Broadcast */ - GATT_CHAR_PROPERTIES_BIT_READ = (1 << 1), /* bit 1: Read */ - GATT_CHAR_PROPERTIES_BIT_WRITE_NR = (1 << 2), /* bit 2: Write (No Response) */ - GATT_CHAR_PROPERTIES_BIT_WRITE = (1 << 3), /* bit 3: Write */ - GATT_CHAR_PROPERTIES_BIT_NOTIFY = (1 << 4), /* bit 4: Notify */ - GATT_CHAR_PROPERTIES_BIT_INDICATE = (1 << 5), /* bit 5: Indicate */ - GATT_CHAR_PROPERTIES_BIT_AUTH = (1 << 6), /* bit 6: Authenticate */ - GATT_CHAR_PROPERTIES_BIT_EXT_PROP = (1 << 7) /* bit 7: Extended Properties */ -}; -typedef uint8_t -aos_bt_gatt_char_properties_t; /* GATT characteristic properties mask (see #aos_bt_gatt_char_properties_e) */ - -/************************************************************************ - * Macros for parsing results GATT discovery results - * (while handling GATT_DISCOVERY_RESULT_EVT) - ****************************************************************************/ -/* Discovery type: GATT_DISCOVER_SERVICES_ALL or GATT_DISCOVER_SERVICES_BY_UUID */ -#define GATT_DISCOVERY_RESULT_SERVICE_START_HANDLE(p_event_data) (p_event_data->discovery_result.discovery_data.group_value.s_handle) -#define GATT_DISCOVERY_RESULT_SERVICE_END_HANDLE(p_event_data) (p_event_data->discovery_result.discovery_data.group_value.e_handle) -#define GATT_DISCOVERY_RESULT_SERVICE_UUID_LEN(p_event_data) (p_event_data->discovery_result.discovery_data.group_value.service_type.len) -#define GATT_DISCOVERY_RESULT_SERVICE_UUID16(p_event_data) (p_event_data->discovery_result.discovery_data.group_value.service_type.uu.uuid16) -#define GATT_DISCOVERY_RESULT_SERVICE_UUID32(p_event_data) (p_event_data->discovery_result.discovery_data.group_value.service_type.uu.uuid32) -#define GATT_DISCOVERY_RESULT_SERVICE_UUID128(p_event_data) (p_event_data->discovery_result.discovery_data.group_value.service_type.uu.uuid128) - -/* Discovery type: GATT_DISCOVER_CHARACTERISTIC_DESCRIPTORS */ -#define GATT_DISCOVERY_RESULT_CHARACTERISTIC_DESCRIPTOR_UUID_LEN(p_event_data) (p_event_data->discovery_result.discovery_data.char_descr_info.type.len) -#define GATT_DISCOVERY_RESULT_CHARACTERISTIC_DESCRIPTOR_UUID16(p_event_data) (p_event_data->discovery_result.discovery_data.char_descr_info.type.uu.uuid16) -#define GATT_DISCOVERY_RESULT_CHARACTERISTIC_DESCRIPTOR_UUID32(p_event_data) (p_event_data->discovery_result.discovery_data.char_descr_info.type.uu.uuid32) -#define GATT_DISCOVERY_RESULT_CHARACTERISTIC_DESCRIPTOR_UUID128(p_event_data) (p_event_data->discovery_result.discovery_data.char_descr_info.type.uu.uuid128) -#define GATT_DISCOVERY_RESULT_CHARACTERISTIC_DESCRIPTOR_VALUE_HANDLE(p_event_data) (p_event_data->discovery_result.discovery_data.char_descr_info.handle) - -/* Discovery type: GATT_DISCOVER_CHARACTERISTICS */ -#define GATT_DISCOVERY_RESULT_CHARACTERISTIC_VALUE_HANDLE(p_event_data) (p_event_data->discovery_result.discovery_data.characteristic_declaration.val_handle) -#define GATT_DISCOVERY_RESULT_CHARACTERISTIC_UUID_LEN(p_event_data) (p_event_data->discovery_result.discovery_data.characteristic_declaration.char_uuid.len) -#define GATT_DISCOVERY_RESULT_CHARACTERISTIC_UUID16(p_event_data) (p_event_data->discovery_result.discovery_data.characteristic_declaration.char_uuid.uu.uuid16) -#define GATT_DISCOVERY_RESULT_CHARACTERISTIC_UUID32(p_event_data) (p_event_data->discovery_result.discovery_data.characteristic_declaration.char_uuid.uu.uuid32) -#define GATT_DISCOVERY_RESULT_CHARACTERISTIC_UUID128(p_event_data) (p_event_data->discovery_result.discovery_data.characteristic_declaration.char_uuid.uu.uuid128) - -/* Authentication requirement */ -enum aos_bt_gatt_auth_req_e { - GATT_AUTH_REQ_NONE = 0, /* No Authentication Required */ - GATT_AUTH_REQ_NO_MITM = 1, /* Unauthenticated encryption (No MITM) */ - GATT_AUTH_REQ_MITM = 2, /* Authenticated encryption (MITM) */ - GATT_AUTH_REQ_SIGNED_NO_MITM = 3, /* Signed Data (No MITM) */ - GATT_AUTH_REQ_SIGNED_MITM = 4 /* Signed Data (MITM) */ -}; -typedef uint8_t aos_bt_gatt_auth_req_t; /* GATT authentication requirement (see #aos_bt_gatt_auth_req_e)*/ - -/* Attribute value, used for GATT write operations, and read response callbacks */ -typedef struct { - uint16_t handle; /* Attribute handle */ - uint16_t - offset; /* Attribute value offset, ignored if not needed for a command */ - uint16_t len; /* Length of attribute value */ - aos_bt_gatt_auth_req_t - auth_req; /* Authentication requirement (see @link aos_bt_gatt_auth_req_e aos_bt_gatt_auth_req_t @endlink) */ - uint8_t - value[1]; /* The attribute value (actual length is specified by 'len') */ -} aos_bt_gatt_value_t; - -/* GATT Write Execute request flags */ -enum aos_bt_gatt_exec_flag_e { - GATT_PREP_WRITE_CANCEL = 0x00, /* GATT_PREP_WRITE_CANCEL */ - GATT_PREP_WRITE_EXEC = 0x01 /* GATT_PREP_WRITE_EXEC */ -}; -typedef uint8_t aos_bt_gatt_exec_flag_t; /* GATT execute flag (see #aos_bt_gatt_exec_flag_e) */ - -/* Attribute read request */ -typedef struct { - uint16_t handle; /* Handle of attribute to read */ - uint16_t offset; /* Offset to read */ - aos_bool_t is_long; /* TRUE if long read */ - uint16_t *p_val_len; /* input and output parameter for value length */ - uint8_t *p_val; /* Value pointer */ -} aos_bt_gatt_read_t; - -/* Attribute write request */ -typedef struct { - uint16_t handle; /* Handle of attribute to read */ - aos_bool_t is_prep; /* TRUE if this is a prepare write request */ - uint16_t offset; /* Offset to write */ - uint16_t val_len; /* Value length */ - uint8_t *p_val; /* Value pointer */ -} aos_bt_gatt_write_t; - -/* Attribute information for GATT attribute requests */ -typedef union { - aos_bt_gatt_read_t read_req; /* Parameters for GATTS_REQ_TYPE_READ */ - aos_bt_gatt_write_t write_req; /* Parameters for GATTS_REQ_TYPE_WRITE */ - uint16_t handle; /* Parameters for GATTS_REQ_TYPE_CONF */ - uint16_t mtu; /* Parameters for GATTS_REQ_TYPE_MTU */ - aos_bt_gatt_exec_flag_t exec_write; /* Parameters for GATTS_REQ_TYPE_WRITE_EXEC */ -} aos_bt_gatt_request_data_t; - -/* GATT Attribute Request Type */ -enum aos_bt_gatt_request_type_e { - GATTS_REQ_TYPE_READ = 1, /* Attribute read notification (attribute value internally read from GATT database) */ - GATTS_REQ_TYPE_WRITE, /* Attribute write notification (attribute value internally written to GATT database) */ - GATTS_REQ_TYPE_PREP_WRITE, /* Attribute Prepare Write Notification (Suspending write request before triggering actual execute write ) */ - GATTS_REQ_TYPE_WRITE_EXEC, /* Execute write request */ - GATTS_REQ_TYPE_MTU, /* MTU exchange information */ - GATTS_REQ_TYPE_CONF, /* Value confirmation */ -}; -typedef uint8_t aos_bt_gatt_request_type_t; /* GATT Attribute Request Type (see #aos_bt_gatt_request_type_e) */ - -/* Discovery types */ -enum aos_bt_gatt_discovery_type_e { - GATT_DISCOVER_SERVICES_ALL = 1, /* discover all services */ - GATT_DISCOVER_SERVICES_BY_UUID, /* discover service by UUID */ - GATT_DISCOVER_INCLUDED_SERVICES, /* discover an included service within a service */ - GATT_DISCOVER_CHARACTERISTICS, /* discover characteristics of a service with/without type requirement */ - GATT_DISCOVER_CHARACTERISTIC_DESCRIPTORS, /* discover characteristic descriptors of a character */ - GATT_DISCOVER_MAX /* maximum discovery types */ -}; -typedef uint8_t aos_bt_gatt_discovery_type_t; /* GATT Discovery type (see #aos_bt_gatt_discovery_type_e) */ - -/* Parameters used in a GATT Discovery */ -typedef struct { - aos_bt_uuid_t uuid; /* Service or Characteristic UUID */ - uint16_t s_handle; /* Start handle for range to search */ - uint16_t e_handle; /* End handle for range to search */ -} aos_bt_gatt_discovery_param_t; - -/* GATT Read Types */ -enum aos_bt_gatt_read_type_e { - GATT_READ_BY_TYPE = 1, /* Read by Type (service or characteristic UUIDs) */ - GATT_READ_BY_HANDLE, /* Read by Handle */ - GATT_READ_MULTIPLE, /* Read Multiple (array of handles) */ - GATT_READ_CHAR_VALUE, /* Read Characteristic Value */ - GATT_READ_PARTIAL, /* Read Partial */ - GATT_READ_MAX -}; -typedef uint8_t aos_bt_gatt_read_type_t; /* GATT read type (see #aos_bt_gatt_read_type_e) */ - -/* Parameters for GATT_READ_BY_TYPE and GATT_READ_CHAR_VALUE */ -typedef struct { - aos_bt_gatt_auth_req_t - auth_req; /* Authentication requirement (see @link aos_bt_gatt_auth_req_e aos_bt_gatt_auth_req_t @endlink) */ - uint16_t s_handle; /* Starting handle */ - uint16_t e_handle; /* Ending handle */ - aos_bt_uuid_t uuid; /* uuid */ -} aos_bt_gatt_read_by_type_t; - -#define GATT_MAX_READ_MULTI_HANDLES 10 /* Max attributes allowed in one GATT_READ_MULTIPLE request */ -/* Parameters for GATT_READ_MULTIPLE */ -typedef struct { - aos_bt_gatt_auth_req_t - auth_req; /* authentication requirement (see @link aos_bt_gatt_auth_req_e aos_bt_gatt_auth_req_t @endlink) */ - uint16_t num_handles; /* number of handles to read */ - uint16_t handles[GATT_MAX_READ_MULTI_HANDLES]; /* handles list to be read */ -} aos_bt_gatt_read_multi_t; - -/* Parameters for GATT_READ_BY_HANDLE */ -typedef struct { - aos_bt_gatt_auth_req_t - auth_req; /* authentication requirement (see @link aos_bt_gatt_auth_req_e aos_bt_gatt_auth_req_t @endlink) */ - uint16_t handle; /* handle */ -} aos_bt_gatt_read_by_handle_t; - -/* Parameters for GATT_READ_PARTIAL */ -typedef struct { - aos_bt_gatt_auth_req_t - auth_req; /* authentication requirement (see @link aos_bt_gatt_auth_req_e aos_bt_gatt_auth_req_t @endlink) */ - uint16_t handle; /* handle */ - uint16_t offset; /* offset */ -} aos_bt_gatt_read_partial_t; - -/* Read request parameters - used when calling #aos_bt_gatt_send_read */ -typedef union { - aos_bt_gatt_read_by_type_t service; /* Parameters for GATT_READ_BY_TYPE */ - aos_bt_gatt_read_by_type_t char_type; /* Parameters for GATT_READ_CHAR_VALUE */ - aos_bt_gatt_read_multi_t read_multiple; /* Parameters for GATT_READ_MULTIPLE */ - aos_bt_gatt_read_by_handle_t by_handle; /* Parameters for GATT_READ_BY_HANDLE */ - aos_bt_gatt_read_partial_t partial; /* Parameters for GATT_READ_PARTIAL */ -} aos_bt_gatt_read_param_t; - -/* Write request types - used when calling #aos_bt_gatt_send_write */ -enum aos_bt_gatt_write_type_e { - GATT_WRITE_NO_RSP = 1, /* Write without response */ - GATT_WRITE, /* Write with response */ - GATT_WRITE_PREPARE /* Prepare to write (call #aos_bt_gatt_send_execute_write to execute the write) */ -}; -typedef uint8_t aos_bt_gatt_write_type_t; /* GATT write type (see #aos_bt_gatt_write_type_e) */ - -/* Response data for read operations */ -typedef struct { - uint16_t handle; /* handle */ - uint16_t len; /* length of response data */ - uint16_t offset; /* offset */ - uint8_t *p_data; /* attribute data */ -} aos_bt_gatt_data_t; - -/* Client Operation Complete response data (dependent on operation completed) */ -typedef union { - aos_bt_gatt_data_t att_value; /* Response data for read operations (initiated using #aos_bt_gatt_send_read) */ - uint16_t mtu; /* Response data for configuration operations */ - uint16_t - handle; /* Response data for write operations (initiated using #aos_bt_gatt_send_write) */ -} aos_bt_gatt_operation_complete_rsp_t; /* GATT operation complete response type */ - -/* GATT client operation type, used in client callback function -*/ -enum aos_bt_gatt_optype_e { - GATTC_OPTYPE_NONE = 0, /* None */ - GATTC_OPTYPE_DISCOVERY = 1, /* Discovery */ - GATTC_OPTYPE_READ = 2, /* Read */ - GATTC_OPTYPE_WRITE = 3, /* Write */ - GATTC_OPTYPE_EXE_WRITE = 4, /* Execute Write */ - GATTC_OPTYPE_CONFIG = 5, /* Configure */ - GATTC_OPTYPE_NOTIFICATION = 6, /* Notification */ - GATTC_OPTYPE_INDICATION = 7 /* Indication */ -}; - -/* GATT Client Operation Codes */ -typedef uint8_t aos_bt_gatt_optype_t; /* GATT operation type (see #aos_bt_gatt_optype_e) */ - -/* characteristic declaration */ -typedef struct { - aos_bt_gatt_char_properties_t - characteristic_properties; /* characteristic properties (see @link aos_bt_gatt_char_properties_e aos_bt_gatt_char_properties_t @endlink) */ - uint16_t val_handle; /* characteristic value attribute handle */ - uint16_t handle; /* characteristic declaration handle */ - aos_bt_uuid_t char_uuid; /* characteristic UUID type */ -} aos_bt_gatt_char_declaration_t; - -/* GATT group value */ -typedef struct { - aos_bt_uuid_t service_type; /* group type */ - uint16_t s_handle; /* starting handle of the group */ - uint16_t e_handle; /* ending handle of the group */ -} aos_bt_gatt_group_value_t; - - -/* included service attribute value */ -typedef struct { - aos_bt_uuid_t service_type; /* included service UUID */ - uint16_t handle; /* included service handle */ - uint16_t s_handle; /* starting handle */ - uint16_t e_handle; /* ending handle */ -} aos_bt_gatt_included_service_t; - -/* characteristic descriptor information */ -typedef struct { - aos_bt_uuid_t type; /* descriptor UUID type */ - uint16_t handle; /* descriptor attribute handle */ -} aos_bt_gatt_char_descr_info_t; - - -/* - * Discovery result data - * Use GATT_DISCOVERY_RESULT_SERVICE_* or GATT_DISCOVERY_RESULT_CHARACTERISTIC_* macros to parse discovery data) - */ -typedef union { - aos_bt_gatt_included_service_t included_service; /* Result for GATT_DISCOVER_INCLUDED_SERVICES */ - aos_bt_gatt_group_value_t - group_value; /* Result for GATT_DISCOVER_SERVICES_ALL or GATT_DISCOVER_SERVICES_BY_UUID */ - aos_bt_gatt_char_declaration_t characteristic_declaration; /* Result for GATT_DISCOVER_CHARACTERISTICS */ - aos_bt_gatt_char_descr_info_t - char_descr_info; /* Result for GATT_DISCOVER_CHARACTERISTIC_DESCRIPTORS */ -} aos_bt_gatt_discovery_data_t; - -#define GATT_LINK_IDLE_TIMEOUT_WHEN_NO_APP 0 /* start a idle timer for this duration when no application need to use the link */ -#define GATT_LINK_NO_IDLE_TIMEOUT 0xFFFF -#define GATT_INVALID_ACL_HANDLE 0xFFFF -#define GATT_HANDLE_IS_VALID(x) ((x) != 0) - -typedef uint16_t aos_bt_gatt_appearance_t; /* GATT appearance (see #gatt_appearance_e) */ - -/**************************************************************************** - * GATT Database Defintions - *****************************************************************************/ -/* The permission bits (see Vol 3, Part F, 3.3.1.1) */ -#define LEGATTDB_PERM_NONE (0x00) -#define LEGATTDB_PERM_VARIABLE_LENGTH (0x1 << 0) -#define LEGATTDB_PERM_READABLE (0x1 << 1) -#define LEGATTDB_PERM_WRITE_CMD (0x1 << 2) -#define LEGATTDB_PERM_WRITE_REQ (0x1 << 3) -#define LEGATTDB_PERM_AUTH_READABLE (0x1 << 4) -#define LEGATTDB_PERM_RELIABLE_WRITE (0x1 << 5) -#define LEGATTDB_PERM_AUTH_WRITABLE (0x1 << 6) - -#define LEGATTDB_PERM_WRITABLE (LEGATTDB_PERM_WRITE_CMD | LEGATTDB_PERM_WRITE_REQ| LEGATTDB_PERM_AUTH_WRITABLE) -#define LEGATTDB_PERM_MASK (0x7f) /* All the permission bits. */ -#define LEGATTDB_PERM_SERVICE_UUID_128 (0x1 << 7) - - -/* GATT Characteristic Properties */ -#define LEGATTDB_CHAR_PROP_BROADCAST (0x1 << 0) -#define LEGATTDB_CHAR_PROP_READ (0x1 << 1) -#define LEGATTDB_CHAR_PROP_WRITE_NO_RESPONSE (0x1 << 2) -#define LEGATTDB_CHAR_PROP_WRITE (0x1 << 3) -#define LEGATTDB_CHAR_PROP_NOTIFY (0x1 << 4) -#define LEGATTDB_CHAR_PROP_INDICATE (0x1 << 5) -#define LEGATTDB_CHAR_PROP_AUTHD_WRITES (0x1 << 6) -#define LEGATTDB_CHAR_PROP_EXTENDED (0x1 << 7) - -/* Conversion macros */ -#define BIT16_TO_8( val ) \ - (uint8_t)( (val) & 0xff),/* LSB */ \ - (uint8_t)(( (val) >> 8 ) & 0xff) /* MSB */ - -/* UUID lengths */ -#define LEGATTDB_UUID16_SIZE 2 -#define LEGATTDB_UUID128_SIZE 16 - - -/* Service and Characteristic macros */ -#define ATTRIBUTE16( handle, permission, datalen, uuid ) \ - BIT16_TO_8(handle), \ - (uint8_t)(permission), \ - (uint8_t)(datalen + 2), \ - BIT16_TO_8(uuid) - -#define PRIMARY_SERVICE_UUID16(handle, service) \ - BIT16_TO_8((uint16_t)(handle)), \ - LEGATTDB_PERM_READABLE, \ - 4, \ - BIT16_TO_8((GATT_UUID_PRI_SERVICE)), \ - BIT16_TO_8((service)) - -#define PRIMARY_SERVICE_UUID128(handle, service) \ - BIT16_TO_8((uint16_t)(handle)), \ - LEGATTDB_PERM_READABLE, \ - 18, \ - BIT16_TO_8(GATT_UUID_PRI_SERVICE), \ - service - -#define SECONDARY_SERVICE_UUID16(handle, service) \ - BIT16_TO_8((uint16_t)(handle)), \ - LEGATTDB_PERM_READABLE, \ - 4, \ - BIT16_TO_8((GATT_UUID_SEC_SERVICE)), \ - BIT16_TO_8((service)) - -#define SECONDARY_SERVICE_UUID128(handle, service) \ - BIT16_TO_8((uint16_t)(handle)), \ - LEGATTDB_PERM_READABLE, \ - 18, \ - BIT16_TO_8(GATT_UUID_SEC_SERVICE), \ - service - -#define INCLUDE_SERVICE_UUID16(handle, service_handle, end_group_handle, service) \ - BIT16_TO_8((uint16_t)(handle)), \ - LEGATTDB_PERM_READABLE, \ - 8, \ - BIT16_TO_8(GATT_UUID_INCLUDE_SERVICE), \ - BIT16_TO_8(service_handle), \ - BIT16_TO_8(end_group_handle), \ - BIT16_TO_8(service) - - -#define INCLUDE_SERVICE_UUID128(handle, service_handle, end_group_handle)\ - BIT16_TO_8((uint16_t)(handle)), \ - LEGATTDB_PERM_READABLE, \ - 6, \ - BIT16_TO_8(GATT_UUID_INCLUDE_SERVICE), \ - BIT16_TO_8(service_handle), \ - BIT16_TO_8(end_group_handle) - - -#define CHARACTERISTIC_UUID16(handle, handle_value, uuid, properties, permission) \ - BIT16_TO_8((uint16_t)(handle)), \ - LEGATTDB_PERM_READABLE, \ - 0x07, \ - BIT16_TO_8(GATT_UUID_CHAR_DECLARE), \ - (uint8_t)(properties), \ - BIT16_TO_8((uint16_t)(handle_value)), \ - BIT16_TO_8(uuid), \ - BIT16_TO_8((uint16_t)(handle_value)), \ - (uint8_t)(permission), \ - (uint8_t)(LEGATTDB_UUID16_SIZE), \ - BIT16_TO_8(uuid) - -#define CHARACTERISTIC_UUID128(handle, handle_value, uuid, properties, permission) \ - BIT16_TO_8((uint16_t)(handle)), \ - LEGATTDB_PERM_READABLE, \ - 21, \ - BIT16_TO_8(GATT_UUID_CHAR_DECLARE), \ - (uint8_t)(properties), \ - BIT16_TO_8((uint16_t)(handle_value)), \ - uuid, \ - BIT16_TO_8((uint16_t)(handle_value)), \ - (uint8_t)(permission | LEGATTDB_PERM_SERVICE_UUID_128), \ - (uint8_t)(LEGATTDB_UUID128_SIZE), \ - uuid - -#define CHARACTERISTIC_UUID16_WRITABLE(handle, handle_value, uuid, properties, permission) \ - BIT16_TO_8((uint16_t)(handle)), \ - LEGATTDB_PERM_READABLE, \ - 0x07, \ - BIT16_TO_8(GATT_UUID_CHAR_DECLARE), \ - (uint8_t)(properties), \ - BIT16_TO_8((uint16_t)(handle_value)), \ - BIT16_TO_8(uuid), \ - BIT16_TO_8((uint16_t)(handle_value)), \ - (uint8_t)(permission), \ - (uint8_t)(LEGATTDB_UUID16_SIZE), \ - (uint8_t)(0), \ - BIT16_TO_8(uuid) - -#define CHARACTERISTIC_UUID128_WRITABLE(handle, handle_value, uuid, properties, permission) \ - BIT16_TO_8((uint16_t)(handle)), \ - LEGATTDB_PERM_READABLE, \ - 21, \ - BIT16_TO_8(GATT_UUID_CHAR_DECLARE), \ - (uint8_t)(properties), \ - BIT16_TO_8((uint16_t)(handle_value)), \ - uuid, \ - BIT16_TO_8((uint16_t)(handle_value)), \ - (uint8_t)(permission | LEGATTDB_PERM_SERVICE_UUID_128), \ - (uint8_t)(LEGATTDB_UUID128_SIZE), \ - (uint8_t)(0), \ - uuid - -#define CHAR_DESCRIPTOR_UUID16_WRITABLE(handle, uuid, permission) \ - BIT16_TO_8((uint16_t)(handle)), \ - (uint8_t)(permission), \ - (uint8_t)(LEGATTDB_UUID16_SIZE), \ - (uint8_t)(0), \ - BIT16_TO_8(uuid) - -#define CHAR_DESCRIPTOR_UUID16(handle, uuid, permission) \ - BIT16_TO_8((uint16_t)(handle)), \ - (uint8_t)(permission), \ - (uint8_t)(LEGATTDB_UUID16_SIZE), \ - BIT16_TO_8(uuid) - -/* GATT events */ -typedef enum { - GATT_CONNECTION_STATUS_EVT, /* GATT connection status change. Event data: #aos_bt_gatt_connection_status_t */ - GATT_OPERATION_CPLT_EVT, /* GATT operation complete. Event data: #aos_bt_gatt_event_data_t */ - GATT_DISCOVERY_RESULT_EVT, /* GATT attribute discovery result. Event data: #aos_bt_gatt_discovery_result_t */ - GATT_DISCOVERY_CPLT_EVT, /* GATT attribute discovery complete. Event data: #aos_bt_gatt_event_data_t */ - GATT_ATTRIBUTE_REQUEST_EVT /* GATT attribute request (from remote client). Event data: #aos_bt_gatt_attribute_request_t */ -} aos_bt_gatt_evt_t; - -/* Discovery result (used by GATT_DISCOVERY_RESULT_EVT notification) */ -typedef struct { - uint16_t conn_id; /* ID of the connection */ - aos_bt_gatt_discovery_type_t - discovery_type; /* Discovery type (see @link aos_bt_gatt_discovery_type_e aos_bt_gatt_discovery_type_t @endlink) */ - aos_bt_gatt_discovery_data_t discovery_data; /* Discovery data */ -} aos_bt_gatt_discovery_result_t; - -/* Discovery Complete (used by GATT_DISCOVERY_CPLT_EVT notification) */ -typedef struct { - uint16_t conn_id; /* ID of the connection */ - aos_bt_gatt_discovery_type_t - disc_type; /* Discovery type (see @link aos_bt_gatt_discovery_type_e aos_bt_gatt_discovery_type_t @endlink) */ - aos_bt_gatt_status_t status; /* Status of operation */ -} aos_bt_gatt_discovery_complete_t; - -/* Response to read/write/disc/config operations (used by GATT_OPERATION_CPLT_EVT notification) */ -typedef struct { - uint16_t conn_id; /* ID of the connection */ - aos_bt_gatt_optype_t - op; /* Type of operation completed (see @link aos_bt_gatt_optype_e aos_bt_gatt_optype_t @endlink) */ - aos_bt_gatt_status_t status; /* Status of operation */ - aos_bt_gatt_operation_complete_rsp_t response_data; /* Response data (dependent on optype) */ -} aos_bt_gatt_operation_complete_t; - -/* GATT connection status (used by GATT_CONNECTION_STATUS_EVT notification) */ -typedef struct { - uint8_t *bd_addr; /* Remote device address */ - aos_bt_ble_address_type_t addr_type; /* Remmote device address type */ - uint16_t conn_id; /* ID of the connection */ - aos_bool_t connected; /* TRUE if connected, FALSE if disconnected */ - aos_bt_gatt_disconn_reason_t - reason; /* Reason code (see @link aos_bt_gatt_disconn_reason_e aos_bt_gatt_disconn_reason_t @endlink) */ - aos_bt_transport_t transport; /* Transport type of the connection */ - uint8_t link_role; /* Link role on this connection */ -} aos_bt_gatt_connection_status_t; - -/* GATT attribute request (used by GATT_ATTRIBUTE_REQUEST_EVT notification) */ -typedef struct { - uint16_t conn_id; /* ID of the connection */ - aos_bt_gatt_request_type_t - request_type; /* Request type (see @link aos_bt_gatt_request_type_e aos_bt_gatt_request_type_t) */ - aos_bt_gatt_request_data_t - data; /* Information about attribute being request (dependent on request type) */ -} aos_bt_gatt_attribute_request_t; - -/* Stuctures for GATT event notifications */ -typedef union { - aos_bt_gatt_discovery_result_t discovery_result; /* Data for GATT_DISCOVERY_RESULT_EVT */ - aos_bt_gatt_discovery_complete_t discovery_complete; /* Data for GATT_DISCOVERY_CPLT_EVT */ - aos_bt_gatt_operation_complete_t operation_complete; /* Data for GATT_OPERATION_CPLT_EVT */ - aos_bt_gatt_connection_status_t connection_status; /* Data for GATT_CONNECTION_STATUS_EVT */ - aos_bt_gatt_attribute_request_t attribute_request; /* Data for GATT_ATTRIBUTE_REQUEST_EVT */ -} aos_bt_gatt_event_data_t; - -/* - * GATT event notification callback - * - * Callback for GATT event notifications - * Registered using aos_bt_gatt_register() - * - * @param event : Event ID - * @param p_event_data : Event data - * - * @return Status of event handling -*/ -typedef aos_bt_gatt_status_t aos_bt_gatt_cback_t(aos_bt_gatt_evt_t event, aos_bt_gatt_event_data_t *p_event_data); - -/**************************************************************************** - * External Function Declarations - ****************************************************************************/ -#ifdef __cplusplus -extern "C" -{ -#endif - -/* - * @addtogroup aosbt_gatt Generic Attribute (GATT) - * @ingroup aosbt - * - * Generic Attribute (GATT) Functions. - * - * @{ - */ -/***************************************************************************/ -/* - * GATT Profile Server Functions - * - * @addtogroup server_api_functions Server - * @ingroup aosbt_gatt - * - * Server API Functions sub module for @b GATT. - * - * @{ - */ -/***************************************************************************/ - -/* - * Function aos_bt_gatt_db_init - * - * Initialize the GATT database - * - * @param[in] p_gatt_db : First element in GATT database array - * @param[in] gatt_db_size : Size (in bytes) of GATT database - * - * @return @link aos_bt_gatt_status_e aos_bt_gatt_status_t @endlink - * - */ -aos_bt_gatt_status_t aos_bt_gatt_db_init (const uint8_t *p_gatt_db, uint16_t gatt_db_size); - -/* - * - * Function aos_bt_gatt_send_indication - * - * Send a handle value indication to a client - * - * @param[in] conn_id : connection identifier. - * @param[in] attr_handle : Attribute handle of this handle value indication. - * @param[in] val_len : Length of notification value passed, and return the length actually. - * @param[in] p_val : Notification Value. - * - * @return @link aos_bt_gatt_status_e aos_bt_gatt_status_t @endlink - * - */ -aos_bt_gatt_status_t aos_bt_gatt_send_indication (uint16_t conn_id, uint16_t attr_handle, uint16_t *val_len, - uint8_t *p_val ); - -/* - * Function aos_bt_gatt_send_notification - * - * Send a handle value notification to a client. - * - * @param[in] conn_id : connection identifier. - * @param[in] attr_handle : Attribute handle of this handle value indication. - * @param[in] val_len : Length of notification value passed, and return the length actually. - * @param[in] p_val : Notification Value. - * - * @return @link aos_bt_gatt_status_e aos_bt_gatt_status_t @endlink - * - */ -aos_bt_gatt_status_t aos_bt_gatt_send_notification (uint16_t conn_id, uint16_t attr_handle, uint16_t *val_len, - uint8_t *p_val ); - -/* -* Function aos_bt_gatt_send_response -* -* When application receives a Read Request, Write Request or Indication from the -* peer it can reply synchronously or return a AOS_BT_GATT_PENDING result code -* indicating to the stack that the message is not processed yet. In that case -* application should call this function to send data or just a confirmation to -* the peer. -* -* @param[in] status : Status of the operation to be send to the peer -* @param[in] conn_id : Connection handle -* @param[in] attr_handle : Attribute handle -* @param[in] attr_len : Length of the attribute to send -* @param[in] offset : Attribute value offset -* @param[in] p_attr : Attribute Value -* -* @return @link aos_bt_gatt_status_e aos_bt_gatt_status_t @endlink -*/ -aos_bt_gatt_status_t aos_bt_gatt_send_response(aos_bt_gatt_status_t status, uint16_t conn_id, - uint16_t attr_handle, uint16_t attr_len, uint16_t offset, uint8_t *p_attr); - -/*@} server_api_functions */ - -/****************************************************************************/ -/* - * GATT Profile Client Functions - * - * @addtogroup client_api_functions Client - * @ingroup aosbt_gatt - * - * @{ - */ -/****************************************************************************/ - -/* - * Function aos_bt_gatt_configure_mtu - * - * Configure the ATT MTU size for a connection on an LE - * transport. - * - * @param[in] conn_id : GATT connection handle - * @param[in] mtu : New MTU size - * - * @return @link aos_bt_gatt_status_e aos_bt_gatt_status_t @endlink -*/ -aos_bt_gatt_status_t aos_bt_gatt_configure_mtu (uint16_t conn_id, uint16_t mtu); - -/* - * Function aos_bt_gatt_send_discover - * - * Start an attribute discovery on an ATT server. - * Discovery results are notified using GATT_DISCOVERY_RESULT_EVT ; - * completion is notified using GATT_DISCOVERY_CPLT_EVT of #aos_bt_gatt_cback_t. - * - * @param[in] conn_id : GATT connection handle - * @param[in] discovery_type : Discover type - * @param[in] p_discovery_param : Discover parameter - * - * @return @link aos_bt_gatt_status_e aos_bt_gatt_status_t @endlink -*/ -aos_bt_gatt_status_t aos_bt_gatt_send_discover (uint16_t conn_id, - aos_bt_gatt_discovery_type_t discovery_type, - aos_bt_gatt_discovery_param_t *p_discovery_param ); - -/* - * Function aos_bt_gatt_send_read - * - * Read from remote ATT server. - * Result is notified using GATT_OPERATION_CPLT_EVT of #aos_bt_gatt_cback_t. - * - * @param[in] conn_id : Connection handle - * @param[in] type : Type of the read - * @param[in] p_read : Pointer to the read request parameters - * - * @return @link aos_bt_gatt_status_e aos_bt_gatt_status_t @endlink - * - */ -aos_bt_gatt_status_t aos_bt_gatt_send_read (uint16_t conn_id, aos_bt_gatt_read_type_t type, - aos_bt_gatt_read_param_t *p_read); - -/* - * Function aos_bt_gatt_send_write - * - * Write to remote ATT server. - * Result is notified using GATT_OPERATION_CPLT_EVT of #aos_bt_gatt_cback_t. - * - * @param[in] conn_id : Connection handle - * @param[in] type : Type of write - * @param[in] p_write : Pointer to the write parameters - * - * @return @link aos_bt_gatt_status_e aos_bt_gatt_status_t @endlink - */ -aos_bt_gatt_status_t aos_bt_gatt_send_write (uint16_t conn_id, aos_bt_gatt_write_type_t type, - aos_bt_gatt_value_t *p_write); - -/* - * Function aos_bt_gatt_send_execute_write - * - * Send Execute Write request to remote ATT server. - * - * @param[in] conn_id : Connection handle - * @param[in] is_execute : AOS_BT_TRUE to execute, AOS_BT_FALSE to cancel - * - * @return @link aos_bt_gatt_status_e aos_bt_gatt_status_t @endlink - * - */ -aos_bt_gatt_status_t aos_bt_gatt_send_execute_write (uint16_t conn_id, aos_bool_t is_execute); - -/* - * Function aos_bt_gatt_send_indication_confirm - * - * Send a handle value confirmation to remote ATT server. - * (in response to GATTC_OPTYPE_INDICATION of #aos_bt_gatt_cback_t) - * - * @param[in] conn_id : Connection handle - * @param[in] handle : Attribute handle - * - * @return @link aos_bt_gatt_status_e aos_bt_gatt_status_t @endlink -*/ -aos_bt_gatt_status_t aos_bt_gatt_send_indication_confirm (uint16_t conn_id, uint16_t handle); - -/*@} client_api_functions */ - -/****************************************************************************/ -/* - * GATT Profile Common Functions - * - * @addtogroup common_api_functions Common - * @ingroup aosbt_gatt - * - * @{ - */ -/****************************************************************************/ - -/* - * Function aos_bt_gatt_register - * - * Register an application callback for GATT. - * - * @param[in] gatt_if : The GATT application interface - * @param[in] p_gatt_cback : The GATT notification callback - * - * @return @link aos_bt_gatt_status_e aos_bt_gatt_status_t @endlink - * - */ -aos_bt_gatt_status_t aos_bt_gatt_register (aos_bt_gatt_app_interface_t gatt_if, aos_bt_gatt_cback_t *p_gatt_cback); - -/* - * Function aos_bt_gatt_deregister - * - * Deregister an application callback for GATT. - * - * @param[in] gatt_if : The GATT application interface - * - * @return @link aos_bt_gatt_status_e aos_bt_gatt_status_t @endlink - * - */ -aos_bt_gatt_status_t aos_bt_gatt_deregister (aos_bt_gatt_app_interface_t gatt_if); - - -/* - * Function aos_bt_gatt_le_connect - * - * Open GATT over LE connection to a remote device - * Result is notified using GATT_CONNECTION_STATUS_EVT of #aos_bt_gatt_cback_t. - * - * @param[in] bd_addr : Remote device address - * @param[in] bd_addr_type: Public or random address - * @param[in] conn_mode : connection scan mode - * @param[in] is_direct : Is direct connection or not - * - * @return TRUE : If connection started - * FALSE : If connection start failure - * - */ -aos_bool_t aos_bt_gatt_le_connect (aos_bt_device_address_t bd_addr, - aos_bt_ble_address_type_t bd_addr_type, - aos_bt_ble_conn_mode_t conn_mode, - aos_bool_t is_direct); - -/* - * Function aos_bt_gatt_bredr_connect - * - * Open GATT over BR/EDR connection to a remote device - * Result is notified using GATT_CONNECTION_STATUS_EVT of #aos_bt_gatt_cback_t. - * - * @param[in] bd_addr : Remote device address - * - * @return TRUE : If connection started - * FALSE : If connection start failure - * - */ -aos_bool_t aos_bt_gatt_bredr_connect (aos_bt_device_address_t bd_addr); - -/* - * Function aos_bt_gatt_cancel_connect - * - * Cancel initiating GATT connecton - * - * @param[in] bd_addr : Remote device addresss - * @param[in] is_direct : Is direct connection or not - * - * @return TRUE : If connection started - * FALSE : If connection start failure - * - */ -aos_bool_t aos_bt_gatt_cancel_connect (aos_bt_device_address_t bd_addr, aos_bool_t is_direct); - -/* - * Function aos_bt_gatt_disconnect - * - * Close the specified GATT connection. - * Result is notified using GATT_CONNECTION_STATUS_EVT of #aos_bt_gatt_cback_t. - * - * @param[in] conn_id : GATT connection ID - * - * @return @link aos_bt_gatt_status_e aos_bt_gatt_status_t @endlink - * - */ -aos_bt_gatt_status_t aos_bt_gatt_disconnect (uint16_t conn_id); - - -/* - * Function aos_bt_gatt_listen - * - * Start or stop LE advertisement and listen for connection. - * - * @param[in] start : TRUE to add device to whitelist / FALSE to remove - * @param[in] bd_addr : Device to add/remove from whitelist - * - * @return TRUE : Success - * FALSE : Failure - * - */ -aos_bool_t aos_bt_gatt_listen (aos_bool_t start, aos_bt_device_address_t bd_addr); - -/*@} common_api_functions*/ - -#ifdef __cplusplus -} -#endif - -#endif - -/*@} aosbt_gatt */ diff --git a/kernel/protocols/bluetooth/include/aos_bt_hidd_ble.h b/kernel/protocols/bluetooth/include/aos_bt_hidd_ble.h deleted file mode 100644 index 51ea753e37..0000000000 --- a/kernel/protocols/bluetooth/include/aos_bt_hidd_ble.h +++ /dev/null @@ -1,311 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -/* @file - * - * Human Interface Device Profile (HID) Device over BLE - * - */ - -#ifndef _AOS_BT_HIDD_BLE_H_ -#define _AOS_BT_HIDD_BLE_H_ - -#include "aos_bt_dev.h" -#include "hiddefs.h" - -/***************************************************** - * Constants - ******************************************************/ - -/* HID-LE-Device Callback Events */ -enum aos_bt_hidd_ble_cback_event_e { - AOS_BT_HIDD_BLE_DEV_EVT_OPEN, /* Connected to host with Interrupt and Control Data = 1 if Virtual Cable - Channels in OPEN state. pdata = Host BD-Addr.*/ - - AOS_BT_HIDD_BLE_DEV_EVT_CLOSE, /* Connection with host is closed. Data=Reason Code. */ - AOS_BT_HIDD_BLE_DEV_EVT_GET_REPORT, /* Host sent GET_REPORT Data=Length pdata=structure - having details of get-report. */ - AOS_BT_HIDD_BLE_DEV_EVT_SET_REPORT, /* Host sent SET_REPORT Data=Length pdata=details. */ - AOS_BT_HIDD_BLE_DEV_EVT_GET_PROTO, /* Host sent GET_PROTOCOL Data=NA */ - AOS_BT_HIDD_BLE_DEV_EVT_SET_PROTO, /* Host sent SET_PROTOCOL Data=1 for Report, 0 for Boot */ - AOS_BT_HIDD_BLE_DEV_EVT_DATA /* General event data */ -}; -typedef uint8_t aos_bt_hidd_ble_cback_event_t; /* HIDD BLE callback events */ - -/* GATT application error code for HID profile */ -#define HIDD_LE_RPT_NOT_SUPT 0x8F /* Report not supported */ - -/* HIDD type */ -#define HIDD_LE_KB_TYPE 0x01 /* bit 0 */ -#define HIDD_LE_MICE_TYPE 0x02 /* bit 1 */ -#define HIDD_LE_OTHER_TYPE 0x80 /* bit 7 */ -typedef uint8_t aos_bt_hidd_ble_dev_t; /* HIDD BLE device types */ - -#define HIDD_LE_PROTO_MODE_RPT 0x00 /* Report protocol */ -#define HIDD_LE_PROTO_MODE_BOOT 0x01 /* Boot protocol */ -typedef uint8_t aos_bt_hidd_ble_proto_t; /* HIDD BLE protocol types */ - -/* LE HIDD report type */ -#define HID_LE_RPT_TYPE_INPUT 0x01 /* Input reports */ -#define HID_LE_RPT_TYPE_OUTPUT 0x02 /* Output reports */ -#define HID_LE_RPT_TYPE_FEATURE 0x03 /* Feature reports */ -#define HID_LE_RPT_TYPE_KB_INPUT 0x04 /* Keyboard input */ -#define HID_LE_RPT_TYPE_KB_OUTPUT 0x05 /* Keyboard output */ -#define HID_LE_RPT_TYPE_MI_INPUT 0x06 /* Mouse input */ -typedef uint8_t aos_bt_hidd_ble_rpt_t; /* HIDD BLE report types */ - -#define HID_LE_RPT_TYPE_MAX HID_LE_RPT_TYPE_FEATURE /* Maximun report type */ - -/***************************************************** - * Type Definitions - ******************************************************/ -enum aos_bt_hidd_ble_status { - AOS_BT_HIDD_BLE_SUCCESS, /* Success */ - AOS_BT_HIDD_BLE_ERR_NOT_REGISTERED, /* Not registered */ - AOS_BT_HIDD_BLE_ERR_ALREADY_REGISTERED, /* Alreadu registered */ - AOS_BT_HIDD_BLE_ERR_NO_RESOURCES, /* No resources */ - AOS_BT_HIDD_BLE_ERR_NO_CONNECTION, /* Not connection */ - AOS_BT_HIDD_BLE_ERR_INVALID_PARAM, /* Invalid parameter */ - AOS_BT_HIDD_BLE_ERR_UNSUPPORTED, /* Not supported */ - AOS_BT_HIDD_BLE_ERR_UNKNOWN_COMMAND, /* Unknown command */ - AOS_BT_HIDD_BLE_ERR_CONGESTED, /* Congested */ - AOS_BT_HIDD_BLE_ERR_CONN_IN_PROCESS, /* Connection in process */ - AOS_BT_HIDD_BLE_ERR_ALREADY_CONN, /* Already connected */ - AOS_BT_HIDD_BLE_ERR_DISCONNECTING, /* Disconnecting is process */ - AOS_BT_HIDD_BLE_ERR_SET_CONNABLE_FAIL, /* Set connectable failiure */ - /* Device specific error codes */ - AOS_BT_HIDD_BLE_ERR_HOST_UNKNOWN, /* Host unknown */ - AOS_BT_HIDD_BLE_ERR_L2CAP_FAILED, /* L2CAP failed */ - AOS_BT_HIDD_BLE_ERR_AUTH_FAILED, /* Authentication failed */ - AOS_BT_HIDD_BLE_ERR_SDP_BUSY, /* SDP busy */ - AOS_BT_HIDD_BLE_ERR_GATT, /* GATT */ - - AOS_BT_HIDD_BLE_ERR_INVALID = 0xFF /* Invalid */ -}; -typedef uint8_t aos_bt_hidd_ble_status_t; /* HIDD BLE status codes */ - -/* report reference descriptor value */ -typedef struct { - uint8_t rpt_id; /* Report ID */ - aos_bt_hidd_ble_rpt_t rpt_type; /* Report type */ -} aos_bt_hidd_ble_rpt_ref_t; /* HIDD BLE report reference */ - -/* LE HIDD registration information */ -typedef struct { - aos_bt_hidd_ble_dev_t dev_type; /* Device type */ - uint8_t num_rpt; /* Number of reports */ - uint16_t battery_handle; /* Battery handle */ - aos_bt_hidd_ble_rpt_ref_t *p_rpt_lst; /* Pointer to the report reference */ - aos_bt_hidd_ble_proto_t proto_cap; /* Protocol capability */ - -} aos_bt_hidd_ble_dev_info_t; /* HIDD BLE device info */ - -#define HIDD_LE_REMOTE_WAKE 0x01 /* Remote wake */ -#define HIDD_LE_NORMAL_CONN 0x02 /* Normally connectable */ - -typedef struct { - uint16_t dl_len; /* Description length */ - uint8_t *dsc_list; /* Pointer to the description */ -} aos_bt_hidd_ble_dscp_info_t; /* HIDD BLE description info */ - -/* LE HIDD report map info */ -typedef struct { - uint16_t bcdHID; /* HID info in BCD format */ - uint8_t contry_code; /* Country code */ - uint8_t flags; /* HID info in BCD format */ - aos_bt_hidd_ble_dscp_info_t rpt_map; /* Report map */ -} aos_bt_hidd_ble_rpt_map_info_t; /* HIDD BLE report map info */ - -#define HIDD_REPT_ID_BOOT_KB 1 -#define HIDD_REPT_ID_BOOT_MOUSE 2 - -typedef struct { - uint16_t event; /* event */ - uint16_t len; /* length */ - uint16_t offset; /* offset */ - uint16_t layer_specific; /* lay_specific */ -} aos_bt_hidd_bt_hdr_t; /* General data in BT_HDR type */ - -/* LE HIDD report data */ -typedef struct { - aos_bt_hidd_bt_hdr_t hdr; /* report data, assuming the first byte of data is report ID */ - uint8_t rpt_id; /* report ID */ -} aos_bt_hidd_ble_rpt_data_t; /* HIDD BLE report data */ - -/* LE HIDD get report data */ -typedef struct { - uint8_t rep_type; /* HIDD BLE report type */ - uint8_t rep_id; /* HIDD BLE report ID */ -} aos_bt_hidd_ble_get_rpt_data_t; /* HIDD BLE get report data */ - -/* LE HIDD cback data */ -typedef union { - aos_bt_device_address_t host_bdaddr; /* Host BD-ADDR */ - aos_bt_hidd_ble_get_rpt_data_t get_rpt; /* Get report */ - aos_bt_hidd_ble_rpt_data_t *p_buffer; /* General report data */ -} aos_bt_hidd_ble_cback_data_t; /* HIDD BLE callback data */ - -/* - * HIDD LE callback - * - * Callback for Human Interface Device Profile Device (HIDD) - * - * @param[in] event : Callback event - * @param[in] data : Integer data corresponding to the event - * @param[in] p_data : Callback data - * - * @return void - */ -typedef void (aos_bt_hidd_ble_cback_t) (uint8_t event, - uint32_t data, - aos_bt_hidd_ble_cback_data_t *p_data ); -/* HIDD LE registration info */ -typedef struct { - aos_bt_device_address_t host_addr; /* Host BD-ADDR */ - aos_bt_hidd_ble_dev_info_t dev_info; /* Device info */ - aos_bt_hidd_ble_cback_t *app_cback; /* Callback function */ -} aos_bt_hidd_ble_reg_info_t; /* HIDD BLE registration info */ - - -/* - * @addtogroup hidd_le_api_functions HIDD over BLE - * @ingroup aosbt - * - * HIDD LE Functions - * - * @{ - */ - -/***************************************************** - * Function Declarations - ******************************************************/ -#ifdef __cplusplus -extern "C" -{ -#endif - -/* - * Function aos_bt_hidd_ble_init - * - * Initialize HIDD LE control block and trace variable. - * - * @param[in] None - * @param[out] None - * - * @return None - */ -void aos_bt_hidd_ble_init (void); - -/* - * Function aos_bt_hidd_ble_register - * - * This function must be called at startup to register info related - * to HIDD over LE. - * - * - * @param[in] p_reg_info : SCO index to remove - * @param[out] None - * - * @return status code (see #aos_bt_hidd_ble_status_t) - */ -aos_bt_hidd_ble_status_t aos_bt_hidd_ble_register(aos_bt_hidd_ble_reg_info_t *p_reg_info); - -/* - * Function aos_bt_hidd_ble_deregister - * - * Disable HIDD service. - * - * @param[in] None - * @param[out] None - * - * @return status code (see #aos_bt_hidd_ble_status_t) - */ -aos_bt_hidd_ble_status_t aos_bt_hidd_ble_deregister(void); - -/* - * Function aos_bt_hidd_ble_connect - * - * Initiates a connection to the host. - * - * @param[in] None - * @param[out] None - * - * @return status code (see #aos_bt_hidd_ble_status_t) - */ -aos_bt_hidd_ble_status_t aos_bt_hidd_ble_connect(void); - -/* - * Function aos_bt_hidd_ble_disconnect - * - * Disconnects from the host. - * - * @param[in] None - * @param[out] None - * - * @return status code (see #aos_bt_hidd_ble_status_t) - */ -aos_bt_hidd_ble_status_t aos_bt_hidd_ble_disconnect(void); - -/* - * Function aos_bt_hidd_ble_send_report - * - * Sends report data to the host. - * - * @param[in] rep_type : Report type - * @param[in] rep_id : Report ID - * @param[in] len : Length of the data - * @param[in] offset : Offset of the data - * @param[in] p_rpt : Pointer to the report data - * @param[out] None - * - * @return status code (see #aos_bt_hidd_ble_status_t) - */ -aos_bt_hidd_ble_status_t aos_bt_hidd_ble_send_report(uint8_t rep_type, uint8_t rpt_id, - uint16_t len, uint16_t offset, uint8_t *p_rpt); - -/* - * Function aos_bt_hidd_ble_hand_shake - * - * Acks a set report request - * - * @param[in] status code (see #aos_bt_hidd_ble_status_t) - * @param[out] None - * - * @return status code (see #aos_bt_hidd_ble_status_t) - */ -aos_bt_hidd_ble_status_t aos_bt_hidd_ble_hand_shake(aos_bt_hidd_ble_status_t status); - -/* - * Function aos_bt_hidd_ble_rsp_get_protocol - * - * Responds to a get protocol mode request - * - * @param[in] cur_mode : Current protocol - * @param[out] None - * - * @return status code (see #aos_bt_hidd_ble_status_t) - */ -aos_bt_hidd_ble_status_t aos_bt_hidd_ble_rsp_get_protocol(aos_bt_hidd_ble_proto_t cur_mode); - -/* - * Function aos_bt_hidd_ble_set_rsp_map_info - * - * This function shall be called at startup to configure the - * device HID information and report map - * - * - * @param[in] p_dev_info : Device map info - * @param[out] None - * - * @return status code (see #aos_bt_hidd_ble_status_t) - */ -aos_bt_hidd_ble_status_t aos_bt_hidd_ble_set_rsp_map_info(aos_bt_hidd_ble_rpt_map_info_t *p_dev_info); - -#ifdef __cplusplus -} -#endif - -#endif - -/* @} aosbt_hidd_ble */ diff --git a/kernel/protocols/bluetooth/include/aos_bt_int.h b/kernel/protocols/bluetooth/include/aos_bt_int.h deleted file mode 100644 index e4d32fa5f1..0000000000 --- a/kernel/protocols/bluetooth/include/aos_bt_int.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#ifndef _AOS_BT_INT_H_ -#define _AOS_BT_INT_H_ - -/* AOS -> BTE Conversion */ -#define int8_t INT8 -#define int16_t INT16 -#define int32_t INT32 -#define uint8_t UINT8 -#define uint16_t UINT16 -#define uint32_t UINT32 -#define aos_bool_t BOOLEAN - -#define aos_bt_dev_status_t tBTM_STATUS -#define aos_bt_management_evt_t tBTM_EVENT -#define aos_bt_dev_class_t DEV_CLASS -#define aos_bt_device_address_t BD_ADDR -#define aos_bt_device_address_ptr_t BD_ADDR_PTR -#define aos_bt_dev_io_cap_t tBTM_IO_CAP -#define aos_bt_dev_oob_data_t tBTM_OOB_DATA -#define aos_bt_dev_le_auth_req_t tBTM_LE_AUTH_REQ -#define aos_bt_dev_le_key_type_t tBTM_LE_KEY_TYPE -#define aos_bt_dev_auth_req_t tBTM_AUTH_REQ -#define aos_bt_device_type_t tBT_DEVICE_TYPE -#define aos_bt_dev_bonded_device_info_t tBT_BONDED_DEVICE_INFO_TYPE -#define aos_bt_security_key_value_t tBTM_SEC_KEY_VALUE -#define aos_bt_transport_t tBT_TRANSPORT -#define aos_bt_ble_address_t tBLE_BD_ADDR -#define aos_bt_ble_address_type_t tBLE_ADDR_TYPE -#define aos_bt_ble_conn_mode_t tBLE_CONN_MODE -#define aos_bt_dev_passkey_entry_type_t tBTM_SP_KEY_TYPE -#define aos_bt_connection_status_change_cback_t tBTM_ACL_DB_CHANGE_CB /* modified from bte */ -#define aos_bt_dev_inq_parms_t tBTM_INQ_PARMS /* modified from bte */ -#define aos_bt_dev_inquiry_scan_result_t tBTM_INQ_RESULTS /* modified from bte */ -#define aos_bt_inquiry_result_cback_t tBTM_INQ_RESULTS_CB -#define aos_bt_dev_vendor_specific_command_complete_cback_t tBTM_VSC_CMPL_CB -#ifndef aos_bt_dev_vendor_specific_command_complete_params_t -#define aos_bt_dev_vendor_specific_command_complete_params_t tBTM_VSC_CMPL -#endif -#define aos_bt_ble_advert_mask_t tBTM_BLE_AD_MASK -#define aos_bt_ble_advert_data_t tBTM_BLE_ADV_DATA -#define aos_bt_ble_conn_type_t tBTM_BLE_CONN_TYPE -#define aos_bt_ble_selective_conn_cback_t tBTM_BLE_SEL_CBACK -#define aos_bt_ble_scan_type_t tBTM_BLE_SCAN_TYPE /* new */ -#define aos_bt_ble_advert_mode_t tBTM_BLE_AVERT_MODE /* new */ -#define aos_bt_ble_scan_result_cback_t tBTM_BLE_SCAN_RESULT_CBACK /* new */ -#define aos_bt_ble_scan_results_t tBTM_BLE_SCAN_RESULT /* new */ -#define aos_bt_ble_scan_mode_t tBTM_BLE_SCAN_MODE -#define aos_bt_ble_advert_chnl_map_t tBTM_BLE_ADV_CHNL_MAP -#define aos_dev_ble_signature_t BLE_SIGNATURE -#define aos_bt_ble_advert_filter_policy_t tBTM_BLE_AFP -#define aos_bt_device_link_keys_t tBTM_PAIRED_DEVICE_LINK_KEYS -#define aos_bt_local_identity_keys_t tBTM_LOCAL_IDENTITY_KEYS - -/* l2cap aos-to-bte translation */ -#define aos_bt_l2c_appl_info_t tL2CAP_APPL_INFO -#define aos_bt_l2c_fixed_chnl_reg_t tL2CAP_FIXED_CHNL_REG -#define aos_bt_l2cap_le_appl_information_t tL2CAP_LE_APPL_INFO -#define aos_bt_l2c_cfg_info_t tL2CAP_CFG_INFO -#define aos_bt_l2c_ch_cfg_bits_t tL2CAP_CH_CFG_BITS -#define aos_bt_l2cap_ertm_information_t tL2CAP_ERTM_INFO -#define aos_bt_l2cap_chnl_priority_t tL2CAP_CHNL_PRIORITY -#define aos_bt_l2cap_nocp_cback_t tL2CA_NOCP_CB -#define aos_bt_l2cap_chnl_data_rate_t tL2CAP_CHNL_DATA_RATE - -#define aos_bt_gatt_appearance_t tGATT_APPEARANCE -#define aos_bt_gatt_status_t tGATT_STATUS -#define aos_bt_gatt_write_t tGATT_WRITE_REQ -#define aos_bt_gatt_read_t tGATT_READ_REQ -#define aos_bt_gatt_exec_flag_t tGATT_EXEC_FLAG - -#define aos_bt_hidd_status_t tHID_STATUS -#define aos_bt_hidd_reg_info_t tHID_DEV_REG_INFO -#define aos_bt_hidd_callback_t tHID_DEV_CBACK_DATA - -#define aos_bt_sco_enh_esco_params_t tBTM_ENH_ESCO_PARAMS - -#endif diff --git a/kernel/protocols/bluetooth/include/aos_bt_nvram_access.h b/kernel/protocols/bluetooth/include/aos_bt_nvram_access.h deleted file mode 100644 index 0176513da2..0000000000 --- a/kernel/protocols/bluetooth/include/aos_bt_nvram_access.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -/* @file - * - * AOS Bluetooth Low Energy (BLE) Functions - * - */ - -#ifndef _AOS_BT_NVRAM_ACCESS_H_ -#define _AOS_BT_NVRAM_ACCESS_H_ - -#ifndef OFFSETOF -#define OFFSETOF( type, member ) ( (uintptr_t)&((type *)0)->member ) -#endif /* OFFSETOF */ - -#define AOS_BT_PARA_LOCAL_KEY_DATA 65 /* BTM_SECURITY_LOCAL_KEY_DATA_LEN */ - -#define AOS_BT_DCT_NAME 249 -#define AOS_BT_DCT_MAX_KEYBLOBS 146 /* Maximum size of key blobs to be stored := size of BR-EDR link keys + size of BLE keys*/ -#define AOS_BT_DCT_ADDR_FIELD 6 -#define AOS_BT_DCT_LENGTH_FIELD 2 -#ifndef AOS_BT_DCT_MAX_DEVICES -#define AOS_BT_DCT_MAX_DEVICES 10 /* Maximum number of device records stored in nvram */ -#endif -#define AOS_BT_DCT_ADDR_TYPE 1 -#define AOS_BT_DCT_DEVICE_TYPE 1 - -/* Length of BD_ADDR + 2bytes length field */ -#define AOS_BT_DCT_ENTRY_HDR_LENGTH (AOS_BT_DCT_ADDR_FIELD + AOS_BT_DCT_LENGTH_FIELD + AOS_BT_DCT_ADDR_TYPE + AOS_BT_DCT_DEVICE_TYPE) - -#define AOS_BT_DCT_LOCAL_KEY_OFFSET OFFSETOF( aos_bt_config_t, bluetooth_local_key ) -#define AOS_BT_DCT_REMOTE_KEY_OFFSET OFFSETOF( aos_bt_config_t, bluetooth_remote_key ) - -#endif diff --git a/kernel/protocols/bluetooth/include/aos_bt_rfcomm.h b/kernel/protocols/bluetooth/include/aos_bt_rfcomm.h deleted file mode 100644 index ed4b7d6fc7..0000000000 --- a/kernel/protocols/bluetooth/include/aos_bt_rfcomm.h +++ /dev/null @@ -1,322 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -/* @file - * - * Bluetooth RFCOMM Application Programming Interface - * - */ - -#ifndef _AOS_BT_RFCOMM_H_ -#define _AOS_BT_RFCOMM_H_ - -#include "aos.h" - -/***************************************************** - * Constants and Type definitions - ******************************************************/ - -/* RFCOMM Port Event Masks */ -typedef enum aos_bt_rfcomm_port_event_e { - AOS_BT_RFCOMM_EV_RXCHAR = 0x00000001, /* Any Character received */ - AOS_BT_RFCOMM_EV_RXFLAG = 0x00000002, /* Received certain character */ - AOS_BT_RFCOMM_EV_TXEMPTY = 0x00000004, /* Transmitt Queue Empty */ - AOS_BT_RFCOMM_EV_CTS = 0x00000008, /* CTS changed state */ - AOS_BT_RFCOMM_EV_DSR = 0x00000010, /* DSR changed state */ - AOS_BT_RFCOMM_EV_RLSD = 0x00000020, /* RLSD changed state */ - AOS_BT_RFCOMM_EV_BREAK = 0x00000040, /* BREAK received */ - AOS_BT_RFCOMM_EV_ERR = 0x00000080, /* Line status error occurred */ - AOS_BT_RFCOMM_EV_RING = 0x00000100, /* Ring signal detected */ - AOS_BT_RFCOMM_EV_CTSS = 0x00000400, /* CTS state */ - AOS_BT_RFCOMM_EV_DSRS = 0x00000800, /* DSR state */ - AOS_BT_RFCOMM_EV_RLSDS = 0x00001000, /* RLSD state */ - AOS_BT_RFCOMM_EV_OVERRUN = 0x00002000, /* receiver buffer overrun */ - AOS_BT_RFCOMM_EV_TXCHAR = 0x00004000, /* Any character transmitted */ - AOS_BT_RFCOMM_EV_CONNECTED = 0x00000200, /* RFCOMM connection established */ - AOS_BT_RFCOMM_EV_CONNECT_ERR = 0x00008000, /* Was not able to establish connection or disconnected */ - AOS_BT_RFCOMM_EV_FC = 0x00010000, /* data flow enabled flag changed by remote */ - AOS_BT_RFCOMM_EV_FCS = 0x00020000, /* data flow enable status true = enabled */ -} aos_bt_rfcomm_port_event_t; - -#define AOS_BT_RFCOMM_MASK_ALL (AOS_BT_RFCOMM_EV_RXCHAR | AOS_BT_RFCOMM_EV_TXEMPTY | AOS_BT_RFCOMM_EV_CTS | \ - AOS_BT_RFCOMM_EV_DSR | AOS_BT_RFCOMM_EV_RLSD | AOS_BT_RFCOMM_EV_BREAK | \ - AOS_BT_RFCOMM_EV_ERR | AOS_BT_RFCOMM_EV_RING | AOS_BT_RFCOMM_EV_CONNECT_ERR | \ - AOS_BT_RFCOMM_EV_DSRS | AOS_BT_RFCOMM_EV_CTSS | AOS_BT_RFCOMM_EV_RLSDS | \ - AOS_BT_RFCOMM_EV_RXFLAG | AOS_BT_RFCOMM_EV_TXCHAR | AOS_BT_RFCOMM_EV_OVERRUN | \ - AOS_BT_RFCOMM_EV_FC | AOS_BT_RFCOMM_EV_FCS | AOS_BT_RFCOMM_EV_CONNECTED) - - - -/* RFCOMM Result Codes */ -enum aos_bt_rfcomm_result_e { - AOS_BT_RFCOMM_SUCCESS, /* Success */ - AOS_BT_RFCOMM_ERROR, /* Error */ - AOS_BT_RFCOMM_ALREADY_OPENED, /* Already Opened */ - AOS_BT_RFCOMM_CMD_PENDING, /* Command Pending */ - AOS_BT_RFCOMM_APP_NOT_REGISTERED, /* App Not Registered */ - AOS_BT_RFCOMM_NO_MEM, /* No Memory */ - AOS_BT_RFCOMM_NO_RESOURCES, /* No Resources */ - AOS_BT_RFCOMM_BAD_BD_ADDR, /* Bad BD Address */ - AOS_BT_RFCOMM_RESULT_RESERVED0, - AOS_BT_RFCOMM_BAD_HANDLE, /* Bad Handle */ - AOS_BT_RFCOMM_NOT_OPENED, /* Not Opened */ - AOS_BT_RFCOMM_LINE_ERR, /* Line Error */ - AOS_BT_RFCOMM_START_FAILED, /* Start Failed */ - AOS_BT_RFCOMM_PAR_NEG_FAILED, - AOS_BT_RFCOMM_RFCOMM_NEG_FAILED, - AOS_BT_RFCOMM_SEC_FAILED, - AOS_BT_RFCOMM_PEER_CONNECTION_FAILED, /* Peer Connection Failed */ - AOS_BT_RFCOMM_PEER_FAILED, /* Peer Failed */ - AOS_BT_RFCOMM_PEER_TIMEOUT, /* Peer Timeout */ - AOS_BT_RFCOMM_CLOSED, /* Closed */ - AOS_BT_RFCOMM_TX_FULL, - AOS_BT_RFCOMM_LOCAL_CLOSED, /* Local Closed */ - AOS_BT_RFCOMM_LOCAL_TIMEOUT, /* Local Timeout */ - AOS_BT_RFCOMM_TX_QUEUE_DISABLED, - AOS_BT_RFCOMM_PAGE_TIMEOUT, /* Page Timeout */ - AOS_BT_RFCOMM_INVALID_SCN /* Invalid SCN */ -}; -typedef int aos_bt_rfcomm_result_t; /* RFCOMM result code (see #aos_bt_rfcomm_result_e) */ - -/* RFCOMM Signals */ -enum aos_bt_rfcomm_signal_e { - AOS_BT_RFCOMM_SET_DTRDSR = 0x01, /* DTRDSR set */ - AOS_BT_RFCOMM_CLR_DTRDSR, /* DTRDSR clear */ - AOS_BT_RFCOMM_SET_CTSRTS, /* CTSRTS set */ - AOS_BT_RFCOMM_CLR_CTSRTS, /* CTSRTS clear */ - AOS_BT_RFCOMM_SET_RI, /* RI set (DCE only) */ - AOS_BT_RFCOMM_CLR_RI, /* RI clear (DCE only) */ - AOS_BT_RFCOMM_SET_DCD, /* DCD set (DCE only) */ - AOS_BT_RFCOMM_CLR_DCD, /* DCD clear (DCE only) */ - AOS_BT_RFCOMM_BREAK, /* BRK */ -}; -typedef uint8_t aos_bt_rfcomm_signal_t; /* RFCOMM Signals (see #aos_bt_rfcomm_signal_e) */ - -/* - * Define the callback function prototypes for aos_bt_rfcomm_data_cback_t - * - * @param port_handle : A 16-bit unsigned integer returned by @link aos_bt_rfcomm_create_connection aos_bt_rfcomm_create_connection @endlink. - * @param *p_data : A pointer to the array of bytes received from the peer device. - * @param len : The length of the data received. - */ -typedef int (aos_bt_rfcomm_data_cback_t) (uint16_t port_handle, void *p_data, uint16_t len); - -/* - * Port management callback - * - * @param code : Result code - * @param port_handle : Port handle from @link aos_bt_rfcomm_create_connection aos_bt_rfcomm_create_connection @endlink. - */ -typedef void (aos_bt_port_mgmt_cback_t) (aos_bt_rfcomm_result_t code, uint16_t port_handle); - -/* - * Port event callback - * - * @param event : A 32-bit event code that contains a bit-mask of one or more events the caller would like to register. - * @param port_handle : Port handle from @link aos_bt_rfcomm_create_connection aos_bt_rfcomm_create_connection @endlink. - */ -typedef void (aos_bt_port_event_cback_t) (aos_bt_rfcomm_port_event_t event, uint16_t port_handle); - -/* - * @addtogroup rfcomm_api_functions RFCOMM - * @ingroup aosbt - * - * RFCOMM Functions - * - * @{ - */ -/***************************************************** - * Function Declarations - ******************************************************/ -#ifdef __cplusplus -extern "C" -{ -#endif - -/* - * Establish serial port connection to the peer device, or allow - * RFCOMM to accept a connection from peer devices. - * - * @note - * Server can call this function with the same scn parameter multiple times if - * it is ready to accept multiple simulteneous connections. - * - * DLCI for the connection is (scn * 2 + 1) if client originates connection on - * existing none initiator multiplexer channel. Otherwise it is (scn * 2). - * For the server DLCI can be changed later if client will be calling it using - * (scn * 2 + 1) dlci. - * - * @param[in] uuid : The Universal Unique Identifier (UUID) of the - * Class ID of the service being opened - * @param[in] scn : The Service Channel Number(SCN) as registered - * with the SDP (server) or obtained using SDP from - * the peer device (client) - * @param[in] is_server : TRUE if requesting application is a server - * @param[in] mtu : The maximum number of bytes transferred per frame - * If 0, a default size of L2CAP_MTU_SIZE minus - * 5 bytes is used - * @param[in] bd_addr : BD_ADDR of the peer (if client), NULL if server - * @param[in] p_mgmt_cb : Pointer to callback function to receive connection - * up/down events - * @param[out] p_handle : A pointer to the handle set by RFCOMM to be used in - * consecutive calls for this connection - * - * @return AOS_BT_RFCOMM_SUCCESS : If successful - * AOS_BT_RFCOMM_ALREADY_OPENED : If the client tries to establish a connection to the same BD_ADDR - * AOS_BT_RFCOMM_NO_RESOURCES : If there is not enough memory to allocate a control block structure - * AOS_BT_RFCOMM_INVALID_SCN : If Server Channel Number(SCN) is out of in range 1...30 - */ -aos_bt_rfcomm_result_t aos_bt_rfcomm_create_connection (uint16_t uuid, uint8_t scn, - aos_bool_t is_server, uint16_t mtu, - aos_bt_device_address_t bd_addr, - uint16_t *p_handle, - aos_bt_port_mgmt_cback_t *p_mgmt_cb); - -/* - * Close the specified connection. - * - * @param[in] handle : The connection handle returned by - * @link aos_bt_rfcomm_create_connection aos_bt_rfcomm_create_connection @endlink. - * @param[in] remove_server : (for server only) If TRUE, then also remove server; otherwise server remains enabled - * after connection is closed. - * - * @return AOS_BT_RFCOMM_SUCCESS : If successful - * AOS_BT_RFCOMM_BAD_HANDLE : If the handle is out of range - * AOS_BT_RFCOMM_NOT_OPENED : If the connection is not opened - */ -aos_bt_rfcomm_result_t aos_bt_rfcomm_remove_connection (uint16_t handle, aos_bool_t remove_server); - - -/* - * Set event callback the specified connection. - * - * @param[in] port_handle : A 16-bit unsigned integer returned by - * @link aos_bt_rfcomm_create_connection aos_bt_rfcomm_create_connection @endlink - * @param[in] p_port_cb : Address of the callback function which should - * be called from the RFCOMM when an event - * specified in the mask occurs - * - * @return AOS_BT_RFCOMM_SUCCESS : If successful - * AOS_BT_RFCOMM_BAD_HANDLE : If the handle is out of range - * AOS_BT_RFCOMM_NOT_OPENED : If the connection is not opened - */ -aos_bt_rfcomm_result_t aos_bt_rfcomm_set_event_callback (uint16_t port_handle, aos_bt_port_event_cback_t *p_port_cb); - -/* - * Set event data callback the specified connection. - * - * @param[in] port_handle : A 16-bit unsigned integer returned by - * @link aos_bt_rfcomm_create_connection aos_bt_rfcomm_create_connection @endlink - * @param[in] p_cb : Address of the callback function which should - * be called from the RFCOMM when a data - * packet is received - * - * @return AOS_BT_RFCOMM_SUCCESS : If successful - * AOS_BT_RFCOMM_BAD_HANDLE : If the handle is out of range - * AOS_BT_RFCOMM_NOT_OPENED : If the connection is not opened - */ -aos_bt_rfcomm_result_t aos_bt_rfcomm_set_data_callback (uint16_t port_handle, aos_bt_rfcomm_data_cback_t *p_cb); - - -/* - * Set events for which to be notified - * - * @param[in] port_handle : A 16-bit unsigned integer returned by - * @link aos_bt_rfcomm_create_connection aos_bt_rfcomm_create_connection @endlink - * @param[in] mask : Event mask - * - * @return AOS_BT_RFCOMM_SUCCESS : If successful - * AOS_BT_RFCOMM_BAD_HANDLE : If the handle is out of range - * AOS_BT_RFCOMM_NOT_OPENED : If the connection is not opened - */ -aos_bt_rfcomm_result_t aos_bt_rfcomm_set_event_mask (uint16_t port_handle, aos_bt_rfcomm_port_event_t mask); - -/* - * Send control signal to the peer device. - * - * @param[in] handle : The connection handle returned by - * @link aos_bt_rfcomm_create_connection aos_bt_rfcomm_create_connection @endlink - * @param[in] signal : Signal to send (see #aos_bt_rfcomm_signal_e) - * - * @return AOS_BT_RFCOMM_SUCCESS : If successful - * AOS_BT_RFCOMM_BAD_HANDLE : If the handle is out of range - * AOS_BT_RFCOMM_NOT_OPENED : If the connection is not opened - */ -aos_bt_rfcomm_result_t aos_bt_rfcomm_control (uint16_t handle, aos_bt_rfcomm_signal_t signal); - -/* - * This function directs a specified connection to pass flow control message to the peer device. - * Enable flag passed shows if port can accept more data. - * - * @param[in] handle : The connection handle returned by - * @link aos_bt_rfcomm_create_connection aos_bt_rfcomm_create_connection @endlink - * @param[in] enable : Flow control setting - * TRUE Enable data flow - * FALSE Disable data flow - * - * @return AOS_BT_RFCOMM_SUCCESS : If successful - * AOS_BT_RFCOMM_BAD_HANDLE : If the handle is out of range - * AOS_BT_RFCOMM_NOT_OPENED : If the connection is not opened - */ -aos_bt_rfcomm_result_t aos_bt_rfcomm_flow_control (uint16_t handle, aos_bool_t enable); - -/* - * This function directs a specified connection to pass flow control message to the peer device. - * Enable flag passed shows if port can accept more data. - * - * @param[in] handle : The connection handle returned by - * @link aos_bt_rfcomm_create_connection aos_bt_rfcomm_create_connection @endlink - * @param[in] p_data : Data to write - * @param[in] max_len : Byte count to write - * @param[out] p_len : Bytes written - * - * @return AOS_BT_RFCOMM_SUCCESS : If successful - * AOS_BT_RFCOMM_BAD_HANDLE : If the handle is out of range - * AOS_BT_RFCOMM_NOT_OPENED : If the connection is not opened - */ -aos_bt_rfcomm_result_t aos_bt_rfcomm_write_data (uint16_t handle, char *p_data, uint16_t max_len, uint16_t *p_len); - -/* - * This function checks connection referenced by handle is up and running. - * - * @param[in] handle : The connection handle returned by - * @link aos_bt_rfcomm_create_connection aos_bt_rfcomm_create_connection @endlink - * @param[out] bd_addr : Peer BD Address - * @param[out] p_lcid : L2CAP's LCID - * - * @return AOS_BT_RFCOMM_SUCCESS : If successful - * AOS_BT_RFCOMM_LINE_ERR : If connection is not up and running - */ -//aos_bt_rfcomm_result_t aos_bt_rfcomm_check_connection (UINT16 handle, BD_ADDR bd_addr, UINT16 *p_lcid); - -#ifdef MPAF_CUSTOM_STACK -/* - * This function allocates private pool to be used by RFCOMM. - * - * @param[in] buffer_size : size of buffer - * @param[out] buffer_cnt : buffers - * - * @return AOS_BT_RFCOMM_SUCCESS : If successful - * AOS_BT_RFCOMM_ERROR : If pool allocation fails - */ -aos_bt_rfcomm_result_t aos_bt_rfcomm_init(uint32_t buffer_size, uint32_t buffer_cnt); - -/* - * This function enables flow control based on ACL buffer availability - * - * @param[in] peer_addr : Peer BD Address - * - * @return AOS_TRUE : If successful - * AOS_FALSE : If fails - */ -aos_bool_t aos_bt_rfcomm_control_data_flow(BD_ADDR peer_bda); -#endif - -#ifdef __cplusplus -} -#endif - -#endif - -/*@} */ diff --git a/kernel/protocols/bluetooth/include/aos_bt_stack.h b/kernel/protocols/bluetooth/include/aos_bt_stack.h deleted file mode 100644 index 4cec56b0a4..0000000000 --- a/kernel/protocols/bluetooth/include/aos_bt_stack.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#ifndef _AOS_BT_STACK_H_ -#define _AOS_BT_STACK_H_ - -#include "aos_bt_dev.h" -#include "smartbt_cfg.h" - -/***************************************************** - * Function Declarations - ******************************************************/ -#ifdef __cplusplus -extern "C" { -#endif - -/***************************************************************************/ -/* - * Framework Management Functions - * - * @addtogroup aosbt_Framework Framework - * @ingroup aosbt - * - * @{ - */ -/***************************************************************************/ - -/* - * Function aos_bt_stack_init - * - * Initialize the Bluetooth controller and stack; register - * callback for Bluetooth event notification. - * - * @param[in] p_bt_management_cback : Callback for receiving Bluetooth management events - * @param[in] p_bt_cfg_settings : Bluetooth stack configuration - * @param[in] aos_bt_cfg_buf_pools : Buffer pool configuration - * - * @return AOS_BT_SUCCESS : on success; - * AOS_BT_FAILED : if an error occurred - */ -aos_bt_result_t aos_bt_stack_init(aos_bt_management_cback_t *p_bt_management_cback, - const aos_bt_cfg_settings_t *p_bt_cfg_settings, - const aos_bt_cfg_buf_pool_t aos_bt_cfg_buf_pools[AOS_BT_CFG_NUM_BUF_POOLS]); - - - -/* - * Function aos_bt_stack_deinit - * - * De-initialize the Bluetooth controller and stack. - * - * @return AOS_BT_SUCCESS : on success; - * AOS_BT_ERROR : if an error occurred - */ -aos_bt_result_t aos_bt_stack_deinit(void); - - -/*@} aosbt_Framework */ - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/kernel/protocols/bluetooth/include/aos_bt_types.h b/kernel/protocols/bluetooth/include/aos_bt_types.h deleted file mode 100644 index c0b12cec6f..0000000000 --- a/kernel/protocols/bluetooth/include/aos_bt_types.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -/* @file - * - * Generic types - * - */ -#ifndef _AOS_BT_TYPES_H_ -#define _AOS_BT_TYPES_H_ - -#include "data_types.h" -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define BD_ADDR_LEN 6 -typedef uint8_t aos_bt_device_address_t[BD_ADDR_LEN]; /* Device address length */ - -typedef uint8_t *aos_bt_device_address_ptr_t; /* Device address Pointer */ - -#define DEV_CLASS_LEN 3 -typedef uint8_t aos_bt_dev_class_t[DEV_CLASS_LEN]; /* Device class */ - -#define MAX_UUID_SIZE 16 /* Maximum UUID size - 16 bytes, and structure to hold any type of UUID. */ - -/* UUID Type */ -typedef struct { -#define LEN_UUID_16 2 -#define LEN_UUID_32 4 -#define LEN_UUID_128 16 - - uint16_t len; /* UUID length */ - - union { - uint16_t uuid16; /* 16-bit UUID */ - uint32_t uuid32; /* 32-bit UUID */ - uint8_t uuid128[MAX_UUID_SIZE]; /* 128-bit UUID */ - } uu; - -} aos_bt_uuid_t; - -#define BT_OCTET16_LEN 16 /* length: 16 */ -typedef uint8_t BT_OCTET16[BT_OCTET16_LEN]; /* octet array: size 16 */ - -#define BT_OCTET32_LEN 32 -typedef uint8_t BT_OCTET32[BT_OCTET32_LEN]; /* octet array: size 32 */ - -/* Bluetooth QoS defintions */ -typedef struct { - uint8_t qos_flags; /* TBD */ - uint8_t service_type; /* service type (NO_TRAFFIC, BEST_EFFORT, or GUARANTEED) */ - uint32_t token_rate; /* token rate (bytes/second) */ - uint32_t token_bucket_size; /* token bucket size (bytes) */ - uint32_t peak_bandwidth; /* peak bandwidth (bytes/second) */ - uint32_t latency; /* latency (microseconds) */ - uint32_t delay_variation; /* delay variation (microseconds) */ -} aos_bt_flow_spec_t; - -/* Values for saos_bt_flow_spec_t service_type */ -#define NO_TRAFFIC 0 -#define BEST_EFFORT 1 -#define GUARANTEED 2 - -/* - * @anchor AOS_BT_TRANSPORT_TYPE - * @name Transport types - * @{ - */ -#define BT_TRANSPORT_BR_EDR 1 /* BR/EDR transport */ -#define BT_TRANSPORT_LE 2 /* BLE transport */ -typedef uint8_t aos_bt_transport_t; /* Transport type (see @ref AOS_BT_TRANSPORT_TYPE "BT Transport Types") */ - -/* - * @anchor AOS_BT_DEVICE_TYPE - * @name Device Types - * @{ - */ -#define BT_DEVICE_TYPE_BREDR 0x01 /* BR/EDR device */ -#define BT_DEVICE_TYPE_BLE 0x02 /* LE device */ -#define BT_DEVICE_TYPE_BREDR_BLE 0x03 /* Dual Mode device */ -typedef uint8_t aos_bt_device_type_t; /* Bluetooth device type (see @ref AOS_BT_DEVICE_TYPE "BT Device Types") */ -/* @} AOS_BT_DEVICE_TYPE */ - -/* - * @anchor AOS_BT_ADDR_TYPE - * @name Address Types - * @{ - */ -#define BLE_ADDR_PUBLIC 0x00 /* Public address */ -#define BLE_ADDR_RANDOM 0x01 /* Random address */ -#define BLE_ADDR_PUBLIC_ID 0x02 /* Public ID */ -#define BLE_ADDR_RANDOM_ID 0x03 /* Random ID */ -typedef uint8_t -aos_bt_ble_address_type_t; /* BLE device address type (see @ref AOS_BT_ADDR_TYPE "BT Address Types")*/ -#define BLE_ADDR_TYPE_MASK (BLE_ADDR_RANDOM | BLE_ADDR_PUBLIC) -/* @} AOS_BT_ADDR_TYPE */ - -typedef struct { - aos_bt_ble_address_type_t type; - aos_bt_device_address_t bda; -} aos_bt_ble_address_t; - -#define LINK_KEY_LEN 16 -typedef uint8_t aos_bt_link_key_t[LINK_KEY_LEN]; - -#define BT_ROLE_MASTER 0x00 -#define BT_ROLE_SLAVE 0x01 -typedef uint8_t aos_bt_ble_link_role_t; - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/kernel/protocols/bluetooth/include/bluetooth/att.h b/kernel/protocols/bluetooth/include/bluetooth/att.h new file mode 100644 index 0000000000..45155f3134 --- /dev/null +++ b/kernel/protocols/bluetooth/include/bluetooth/att.h @@ -0,0 +1,65 @@ +/** @file + * @brief Attribute Protocol handling. + */ + +/* + * Copyright (c) 2016 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef __BT_ATT_H +#define __BT_ATT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* Error codes for Error response PDU */ +#define BT_ATT_ERR_INVALID_HANDLE 0x01 +#define BT_ATT_ERR_READ_NOT_PERMITTED 0x02 +#define BT_ATT_ERR_WRITE_NOT_PERMITTED 0x03 +#define BT_ATT_ERR_INVALID_PDU 0x04 +#define BT_ATT_ERR_AUTHENTICATION 0x05 +#define BT_ATT_ERR_NOT_SUPPORTED 0x06 +#define BT_ATT_ERR_INVALID_OFFSET 0x07 +#define BT_ATT_ERR_AUTHORIZATION 0x08 +#define BT_ATT_ERR_PREPARE_QUEUE_FULL 0x09 +#define BT_ATT_ERR_ATTRIBUTE_NOT_FOUND 0x0a +#define BT_ATT_ERR_ATTRIBUTE_NOT_LONG 0x0b +#define BT_ATT_ERR_ENCRYPTION_KEY_SIZE 0x0c +#define BT_ATT_ERR_INVALID_ATTRIBUTE_LEN 0x0d +#define BT_ATT_ERR_UNLIKELY 0x0e +#define BT_ATT_ERR_INSUFFICIENT_ENCRYPTION 0x0f +#define BT_ATT_ERR_UNSUPPORTED_GROUP_TYPE 0x10 +#define BT_ATT_ERR_INSUFFICIENT_RESOURCES 0x11 + +/* Common Profile Error Codes (from CSS) */ +#define BT_ATT_ERR_WRITE_REQ_REJECTED 0xfc +#define BT_ATT_ERR_CCC_IMPROPER_CONF 0xfd +#define BT_ATT_ERR_PROCEDURE_IN_PROGRESS 0xfe +#define BT_ATT_ERR_OUT_OF_RANGE 0xff + +typedef void (*bt_att_func_t)(struct bt_conn *conn, uint8_t err, + const void *pdu, uint16_t length, + void *user_data); +typedef void (*bt_att_destroy_t)(void *user_data); + +/* ATT request context */ +struct bt_att_req { + sys_snode_t node; + bt_att_func_t func; + bt_att_destroy_t destroy; + struct net_buf_simple_state state; + struct net_buf *buf; +#if defined(CONFIG_BLUETOOTH_SMP) + bool retrying; +#endif /* CONFIG_BLUETOOTH_SMP */ +}; + +#ifdef __cplusplus +} +#endif + +#endif /* __BT_ATT_H */ diff --git a/kernel/protocols/bluetooth/include/bluetooth/bluetooth.h b/kernel/protocols/bluetooth/include/bluetooth/bluetooth.h new file mode 100644 index 0000000000..af46c59c83 --- /dev/null +++ b/kernel/protocols/bluetooth/include/bluetooth/bluetooth.h @@ -0,0 +1,495 @@ +/** @file + * @brief Bluetooth subsystem core APIs. + */ + +/* + * Copyright (c) 2015-2016 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef __BT_BLUETOOTH_H +#define __BT_BLUETOOTH_H + +/** + * @brief Bluetooth APIs + * @defgroup bluetooth Bluetooth APIs + * @{ + */ + +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Generic Access Profile + * @defgroup bt_gap Generic Access Profile + * @ingroup bluetooth + * @{ + */ + +/** + * @typedef bt_ready_cb_t + * @brief Callback for notifying that Bluetooth has been enabled. + * + * @param err zero on success or (negative) error code otherwise. + */ +typedef void (*bt_ready_cb_t)(int err); + +/** @brief Enable Bluetooth + * + * Enable Bluetooth. Must be the called before any calls that + * require communication with the local Bluetooth hardware. + * + * @param cb Callback to notify completion or NULL to perform the + * enabling synchronously. + * + * @return Zero on success or (negative) error code otherwise. + */ +int bt_enable(bt_ready_cb_t cb); + +/* Advertising API */ + +/** Description of different data types that can be encoded into + * advertising data. Used to form arrays that are passed to the + * bt_le_adv_start() function. + */ +struct bt_data { + uint8_t type; + uint8_t data_len; + const uint8_t *data; +}; + +/** @brief Helper to declare elements of bt_data arrays + * + * This macro is mainly for creating an array of struct bt_data + * elements which is then passed to bt_le_adv_start(). + * + * @param _type Type of advertising data field + * @param _data Pointer to the data field payload + * @param _data_len Number of bytes behind the _data pointer + */ +#define BT_DATA(_type, _data, _data_len) \ + { \ + .type = (_type), \ + .data_len = (_data_len), \ + .data = (const uint8_t *)(_data), \ + } + +/** @brief Helper to declare elements of bt_data arrays + * + * This macro is mainly for creating an array of struct bt_data + * elements which is then passed to bt_le_adv_start(). + * + * @param _type Type of advertising data field + * @param _bytes Variable number of single-byte parameters + */ +#define BT_DATA_BYTES(_type, _bytes...) \ + BT_DATA(_type, ((uint8_t []) { _bytes }), \ + sizeof((uint8_t []) { _bytes })) + +/** Advertising options */ +enum { + /** Convenience value when no options are specified. */ + BT_LE_ADV_OPT_NONE = 0, + + /** Advertise as connectable. Type of advertising is determined by + * providing SCAN_RSP data and/or enabling local privacy support. + */ + BT_LE_ADV_OPT_CONNECTABLE = BIT(0), + + BT_LE_ADV_OPT_DIRECT = BIT(1), +}; + +/** LE Advertising Parameters. */ +struct bt_le_adv_param { + /** Bit-field of advertising options */ + uint8_t options; + + /** Minimum Advertising Interval (N * 0.625) */ + uint16_t interval_min; + + /** Maximum Advertising Interval (N * 0.625) */ + uint16_t interval_max; + + /** Optional pre-defined (random) own address. Currently + * the only permitted use of this is for NRPA with + * non-connectable advertising. + */ + const bt_addr_t *own_addr; + + const bt_addr_le_t *peer_addr; +}; + +/** Helper to declare advertising parameters inline + * + * @param _options Advertising Options + * @param _int_min Minimum advertising interval + * @param _int_max Maximum advertising interval + */ +#define BT_LE_ADV_PARAM(_options, _int_min, _int_max, _peer) \ + (&(struct bt_le_adv_param) { \ + .options = (_options), \ + .interval_min = (_int_min), \ + .interval_max = (_int_max), \ + .peer_addr = (_peer), \ + }) + +#define BT_LE_ADV_CONN BT_LE_ADV_PARAM(BT_LE_ADV_OPT_CONNECTABLE, \ + BT_GAP_ADV_FAST_INT_MIN_2, \ + BT_GAP_ADV_FAST_INT_MAX_2,NULL) + +#define BT_LE_ADV_DIRECT_CONN(_peer) BT_LE_ADV_PARAM(BT_LE_ADV_OPT_CONNECTABLE|BT_LE_ADV_OPT_DIRECT, \ + BT_GAP_ADV_FAST_INT_MIN_1, \ + BT_GAP_ADV_FAST_INT_MAX_1, \ + _peer) + +#define BT_LE_ADV_NCONN BT_LE_ADV_PARAM(0, BT_GAP_ADV_FAST_INT_MIN_2, \ + BT_GAP_ADV_FAST_INT_MAX_2,NULL) + + + +/** @brief Start advertising + * + * Set advertisement data, scan response data, advertisement parameters + * and start advertising. + * + * @param param Advertising parameters. + * @param ad Data to be used in advertisement packets. + * @param ad_len Number of elements in ad + * @param sd Data to be used in scan response packets. + * @param sd_len Number of elements in sd + * + * @return Zero on success or (negative) error code otherwise. + */ +int bt_le_adv_start(const struct bt_le_adv_param *param, + const struct bt_data *ad, size_t ad_len, + const struct bt_data *sd, size_t sd_len); + +/** @brief Stop advertising + * + * Stops ongoing advertising. + * + * @return Zero on success or (negative) error code otherwise. + */ +int bt_le_adv_stop(void); + +/** @typedef bt_le_scan_cb_t + * @brief Callback type for reporting LE scan results. + * + * A function of this type is given to the bt_le_scan_start() function + * and will be called for any discovered LE device. + * + * @param addr Advertiser LE address and type. + * @param rssi Strength of advertiser signal. + * @param adv_type Type of advertising response from advertiser. + * @param data Buffer containig advertiser data. + */ +typedef void bt_le_scan_cb_t(const bt_addr_le_t *addr, int8_t rssi, + uint8_t adv_type, struct net_buf_simple *buf); + +/** LE scan parameters */ +struct bt_le_scan_param { + /** Scan type (BT_HCI_LE_SCAN_ACTIVE or BT_HCI_LE_SCAN_PASSIVE) */ + uint8_t type; + + /** Duplicate filtering (BT_HCI_LE_SCAN_FILTER_DUP_ENABLE or + * BT_HCI_LE_SCAN_FILTER_DUP_DISABLE) + */ + uint8_t filter_dup; + + /** Scan interval (N * 0.625 ms) */ + uint16_t interval; + + /** Scan window (N * 0.625 ms) */ + uint16_t window; +}; + +/** Helper to declare scan parameters inline + * + * @param _type Scan Type (BT_HCI_LE_SCAN_ACTIVE/BT_HCI_LE_SCAN_PASSIVE) + * @param _filter Filter Duplicates + * @param _interval Scan Interval (N * 0.625 ms) + * @param _window Scan Window (N * 0.625 ms) + */ +#define BT_LE_SCAN_PARAM(_type, _filter, _interval, _window) \ + (&(struct bt_le_scan_param) { \ + .type = (_type), \ + .filter_dup = (_filter), \ + .interval = (_interval), \ + .window = (_window), \ + }) + +/** Helper macro to enable active scanning to discover new devices. */ +#define BT_LE_SCAN_ACTIVE BT_LE_SCAN_PARAM(BT_HCI_LE_SCAN_ACTIVE, \ + BT_HCI_LE_SCAN_FILTER_DUP_ENABLE, \ + BT_GAP_SCAN_FAST_INTERVAL, \ + BT_GAP_SCAN_FAST_WINDOW) + +/** Helper macro to enable passive scanning to discover new devices. + * + * This macro should be used if information required for device identification + * (eg UUID) are known to be placed in Advertising Data. + */ +#define BT_LE_SCAN_PASSIVE BT_LE_SCAN_PARAM(BT_HCI_LE_SCAN_PASSIVE, \ + BT_HCI_LE_SCAN_FILTER_DUP_ENABLE, \ + BT_GAP_SCAN_FAST_INTERVAL, \ + BT_GAP_SCAN_FAST_WINDOW) + +/** @brief Start (LE) scanning + * + * Start LE scanning with given parameters and provide results through + * the specified callback. + * + * @param param Scan parameters. + * @param cb Callback to notify scan results. + * + * @return Zero on success or error code otherwise, positive in case + * of protocol error or negative (POSIX) in case of stack internal error + */ +int bt_le_scan_start(const struct bt_le_scan_param *param, bt_le_scan_cb_t cb); + +/** @brief Stop (LE) scanning. + * + * Stops ongoing LE scanning. + * + * @return Zero on success or error code otherwise, positive in case + * of protocol error or negative (POSIX) in case of stack internal error + */ +int bt_le_scan_stop(void); + +struct bt_le_oob { + /** LE address. If local privacy is enabled this is Resolvable Private + * Address. + */ + bt_addr_le_t addr; +}; + +/** + * @brief Get LE local Out Of Band information + * + * This function allows to get local information that are useful for Out Of Band + * pairing or connection creation process. + * + * If privacy is enabled this will result in generating new Resolvable Private + * Address that is valid for CONFIG_BLUETOOTH_RPA_TIMEOUT seconds. This address + * will be used for advertising, active scanning and connection creation. + * + * @param oob LE related information + */ +int bt_le_oob_get_local(struct bt_le_oob *oob); + +/** @brief BR/EDR discovery result structure */ +struct bt_br_discovery_result { + /** private */ + uint8_t _priv[4]; + + /** Remote device address */ + bt_addr_t addr; + + /** RSSI from inquiry */ + int8_t rssi; + + /** Class of Device */ + uint8_t cod[3]; + + /** Extended Inquiry Response */ + uint8_t eir[240]; +}; + +/** @typedef bt_br_discovery_cb_t + * @brief Callback type for reporting BR/EDR discovery (inquiry) + * results. + * + * A callback of this type is given to the bt_br_discovery_start() + * function and will be called at the end of the discovery with + * information about found devices populated in the results array. + * + * @param results Storage used for discovery results + * @param count Number of valid discovery results. + */ +typedef void bt_br_discovery_cb_t(struct bt_br_discovery_result *results, + size_t count); + +/** BR/EDR discovery parameters */ +struct bt_br_discovery_param { + /** Maximum length of the discovery in units of 1.28 seconds. + * Valid range is 0x01 - 0x30. + */ + uint8_t length; + + /** True if limited discovery procedure is to be used. */ + bool limited; +}; + +/** @brief Start BR/EDR discovery + * + * Start BR/EDR discovery (inquiry) and provide results through the specified + * callback. When bt_br_discovery_cb_t is called it indicates that discovery + * has completed. If more inquiry results were received during session than + * fits in provided result storage, only ones with highest RSSI will be + * reported. + * + * @param param Discovery parameters. + * @param results Storage for discovery results. + * @param count Number of results in storage. Valid range: 1-255. + * @param cb Callback to notify discovery results. + * + * @return Zero on success or error code otherwise, positive in case + * of protocol error or negative (POSIX) in case of stack internal error + */ +int bt_br_discovery_start(const struct bt_br_discovery_param *param, + struct bt_br_discovery_result *results, size_t count, + bt_br_discovery_cb_t cb); + +/** @brief Stop BR/EDR discovery. + * + * Stops ongoing BR/EDR discovery. If discovery was stopped by this call + * results won't be reported + * + * @return Zero on success or error code otherwise, positive in case + * of protocol error or negative (POSIX) in case of stack internal error + */ +int bt_br_discovery_stop(void); + +struct bt_br_oob { + /** BR/EDR address. */ + bt_addr_t addr; +}; + +/** + * @brief Get BR/EDR local Out Of Band information + * + * This function allows to get local controller information that are useful + * for Out Of Band pairing or connection creation process. + * + * @param oob Out Of Band information + */ +int bt_br_oob_get_local(struct bt_br_oob *oob); + +/** @def BT_ADDR_STR_LEN + * + * @brief Recommended length of user string buffer for Bluetooth address + * + * @details The recommended length guarantee the output of address + * conversion will not lose valuable information about address being + * processed. + */ +#define BT_ADDR_STR_LEN 18 + +/** @def BT_ADDR_LE_STR_LEN + * + * @brief Recommended length of user string buffer for Bluetooth LE address + * + * @details The recommended length guarantee the output of address + * conversion will not lose valuable information about address being + * processed. + */ +#define BT_ADDR_LE_STR_LEN 27 + +/** @brief Converts binary Bluetooth address to string. + * + * @param addr Address of buffer containing binary Bluetooth address. + * @param str Address of user buffer with enough room to store formatted + * string containing binary address. + * @param len Length of data to be copied to user string buffer. Refer to + * BT_ADDR_STR_LEN about recommended value. + * + * @return Number of successfully formatted bytes from binary address. + */ +static inline int bt_addr_to_str(const bt_addr_t *addr, char *str, size_t len) +{ + return snprintk(str, len, "%02X:%02X:%02X:%02X:%02X:%02X", + addr->val[5], addr->val[4], addr->val[3], + addr->val[2], addr->val[1], addr->val[0]); +} + +/** @brief Converts binary LE Bluetooth address to string. + * + * @param addr Address of buffer containing binary LE Bluetooth address. + * @param str Address of user buffer with enough room to store + * formatted string containing binary LE address. + * @param len Length of data to be copied to user string buffer. Refer to + * BT_ADDR_LE_STR_LEN about recommended value. + * + * @return Number of successfully formatted bytes from binary address. + */ +static inline int bt_addr_le_to_str(const bt_addr_le_t *addr, char *str, + size_t len) +{ + char type[7]; + + switch (addr->type) { + case BT_ADDR_LE_PUBLIC: + strcpy(type, "public"); + break; + case BT_ADDR_LE_RANDOM: + strcpy(type, "random"); + break; + default: + snprintk(type, sizeof(type), "0x%02x", addr->type); + break; + } + + return snprintk(str, len, "%02X:%02X:%02X:%02X:%02X:%02X (%s)", + addr->a.val[5], addr->a.val[4], addr->a.val[3], + addr->a.val[2], addr->a.val[1], addr->a.val[0], type); +} + +/** @brief Enable/disable set controller in discoverable state. + * + * Allows make local controller to listen on INQUIRY SCAN channel and responds + * to devices making general inquiry. To enable this state it's mandatory + * to first be in connectable state. + * + * @param enable Value allowing/disallowing controller to become discoverable. + * + * @return Negative if fail set to requested state or requested state has been + * already set. Zero if done successfully. + */ +int bt_br_set_discoverable(bool enable); + +/** @brief Enable/disable set controller in connectable state. + * + * Allows make local controller to be connectable. It means the controller + * start listen to devices requests on PAGE SCAN channel. If disabled also + * resets discoverability if was set. + * + * @param enable Value allowing/disallowing controller to be connectable. + * + * @return Negative if fail set to requested state or requested state has been + * already set. Zero if done successfully. + */ +int bt_br_set_connectable(bool enable); + +/** @brief Generate random data. + * + * A random number generation helper which utilizes the Bluetooth + * controller's own RNG. + * + * @param buf Buffer to insert the random data + * @param len Length of random data to generate + * + * @return Zero on success or error code otherwise, positive in case + * of protocol error or negative (POSIX) in case of stack internal error + */ +int bt_rand(void *buf, size_t len); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif +/** + * @} + */ + +#endif /* __BT_BLUETOOTH_H */ diff --git a/kernel/protocols/bluetooth/include/bluetooth/buf.h b/kernel/protocols/bluetooth/include/bluetooth/buf.h new file mode 100644 index 0000000000..899c3a6c81 --- /dev/null +++ b/kernel/protocols/bluetooth/include/bluetooth/buf.h @@ -0,0 +1,91 @@ +/** @file + * @brief Bluetooth data buffer API + */ + +/* + * Copyright (c) 2016 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __BT_BUF_H +#define __BT_BUF_H + +/** + * @brief Data buffers + * @defgroup bt_buf Data buffers + * @ingroup bluetooth + * @{ + */ + +#include +#include +#include + +/** Possible types of buffers passed around the Bluetooth stack */ +enum bt_buf_type { + /** HCI command */ + BT_BUF_CMD, + /** HCI event */ + BT_BUF_EVT, + /** Outgoing ACL data */ + BT_BUF_ACL_OUT, + /** Incoming ACL data */ + BT_BUF_ACL_IN, +}; + +/** Minimum amount of user data size for buffers passed to the stack. */ +#define BT_BUF_USER_DATA_MIN 4 + +/** Data size neeed for HCI RX buffers */ +#define BT_BUF_RX_SIZE (CONFIG_BLUETOOTH_HCI_RESERVE + \ + CONFIG_BLUETOOTH_RX_BUF_LEN) + +/** Allocate a buffer for incoming data + * + * This will not set the buffer type so bt_buf_set_type() needs to be called + * before bt_recv(). + * + * @param timeout Timeout in milliseconds, or one of the special values + * K_NO_WAIT and K_FOREVER. + * @return A new buffer. + */ +struct net_buf *bt_buf_get_rx(int32_t timeout); + +/** Allocate a buffer for an HCI Command Complete/Status Event + * + * This will set the buffer type so bt_buf_set_type() does not need to + * be explicitly called before bt_recv_prio(). + * + * @param timeout Timeout in milliseconds, or one of the special values + * K_NO_WAIT and K_FOREVER. + * @return A new buffer. + */ +struct net_buf *bt_buf_get_cmd_complete(int32_t timeout); + +/** Set the buffer type + * + * @param buf Bluetooth buffer + * @param type The BT_* type to set the buffer to + */ +static inline void bt_buf_set_type(struct net_buf *buf, enum bt_buf_type type) +{ + *(uint8_t *)net_buf_user_data(buf) = type; +} + +/** Get the buffer type + * + * @param buf Bluetooth buffer + * + * @return The BT_* type to of the buffer + */ +static inline enum bt_buf_type bt_buf_get_type(struct net_buf *buf) +{ + return *(uint8_t *)net_buf_user_data(buf); +} + +/** + * @} + */ + +#endif /* __BT_BUF_H */ diff --git a/kernel/protocols/bluetooth/include/bluetooth/conn.h b/kernel/protocols/bluetooth/include/bluetooth/conn.h new file mode 100644 index 0000000000..2aa0623c8a --- /dev/null +++ b/kernel/protocols/bluetooth/include/bluetooth/conn.h @@ -0,0 +1,505 @@ +/** @file + * @brief Bluetooth connection handling + */ + +/* + * Copyright (c) 2015-2016 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef __BT_CONN_H +#define __BT_CONN_H + +/** + * @brief Connection management + * @defgroup bt_conn Connection management + * @ingroup bluetooth + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include +#include + +/** Opaque type representing a connection to a remote device */ +struct bt_conn; + +/** Connection parameters for LE connections */ +struct bt_le_conn_param { + uint16_t interval_min; + uint16_t interval_max; + uint16_t latency; + uint16_t timeout; +}; + +/** Helper to declare connection parameters inline + * + * @param int_min Minimum Connection Interval (N * 1.25 ms) + * @param int_max Maximum Connection Interval (N * 1.25 ms) + * @param lat Connection Latency + * @param to Supervision Timeout (N * 10 ms) + */ +#define BT_LE_CONN_PARAM(int_min, int_max, lat, to) \ + (&(struct bt_le_conn_param) { \ + .interval_min = (int_min), \ + .interval_max = (int_max), \ + .latency = (lat), \ + .timeout = (to), \ + }) + +/** Default LE connection parameters: + * Connection Interval: 30-50 ms + * Latency: 0 + * Timeout: 4 s + */ +#define BT_LE_CONN_PARAM_DEFAULT BT_LE_CONN_PARAM(BT_GAP_INIT_CONN_INT_MIN, \ + BT_GAP_INIT_CONN_INT_MAX, \ + 0, 400) + +/** @brief Increment a connection's reference count. + * + * Increment the reference count of a connection object. + * + * @param conn Connection object. + * + * @return Connection object with incremented reference count. + */ +struct bt_conn *bt_conn_ref(struct bt_conn *conn); + +/** @brief Decrement a connection's reference count. + * + * Decrement the reference count of a connection object. + * + * @param conn Connection object. + */ +void bt_conn_unref(struct bt_conn *conn); + +/** @brief Look up an existing connection by address. + * + * Look up an existing connection based on the remote address. + * + * @param peer Remote address. + * + * @return Connection object or NULL if not found. The caller gets a + * new reference to the connection object which must be released with + * bt_conn_unref() once done using the object. + */ +struct bt_conn *bt_conn_lookup_addr_le(const bt_addr_le_t *peer); + +/** @brief Get destination (peer) address of a connection. + * + * @param conn Connection object. + * + * @return Destination address. + */ +const bt_addr_le_t *bt_conn_get_dst(const struct bt_conn *conn); + +/** Connection Type */ +enum { + /** LE Connection Type */ + BT_CONN_TYPE_LE, + /** BR/EDR Connection Type */ + BT_CONN_TYPE_BR, + /** SCO Connection Type */ + BT_CONN_TYPE_SCO, +}; + +/** LE Connection Info Structure */ +struct bt_conn_le_info { + const bt_addr_le_t *src; /** Source Address */ + const bt_addr_le_t *dst; /** Destination Address */ + uint16_t interval; /** Connection interval */ + uint16_t latency; /** Connection slave latency */ + uint16_t timeout; /** Connection supervision timeout */ +}; + +/** BR/EDR Connection Info Structure */ +struct bt_conn_br_info { + const bt_addr_t *dst; /** Destination BR/EDR address */ +}; + +/** Connection role (master or slave) */ +enum { + BT_CONN_ROLE_MASTER, + BT_CONN_ROLE_SLAVE, +}; + +/** @brief Connection Info Structure + * + * + * @param type Connection Type + * @param role Connection Role + * @param le LE Connection specific Info + * @param br BR/EDR Connection specific Info + */ +struct bt_conn_info { + uint8_t type; + + uint8_t role; + + union { + struct bt_conn_le_info le; + + struct bt_conn_br_info br; + }; +}; + +/** @brief Get connection info + * + * @param conn Connection object. + * @param info Connection info object. + * + * @return Zero on success or (negative) error code on failure. + */ +int bt_conn_get_info(const struct bt_conn *conn, struct bt_conn_info *info); + +/** @brief Update the connection parameters. + * + * @param conn Connection object. + * @param param Updated connection parameters. + * + * @return Zero on success or (negative) error code on failure. + */ +int bt_conn_le_param_update(struct bt_conn *conn, + const struct bt_le_conn_param *param); + +/** @brief Disconnect from a remote device or cancel pending connection. + * + * Disconnect an active connection with the specified reason code or cancel + * pending outgoing connection. + * + * @param conn Connection to disconnect. + * @param reason Reason code for the disconnection. + * + * @return Zero on success or (negative) error code on failure. + */ +int bt_conn_disconnect(struct bt_conn *conn, uint8_t reason); + +/** @brief Initiate an LE connection to a remote device. + * + * Allows initiate new LE link to remote peer using its address. + * Returns a new reference that the the caller is responsible for managing. + * + * @param peer Remote address. + * @param param Initial connection parameters. + * + * @return Valid connection object on success or NULL otherwise. + */ +struct bt_conn *bt_conn_create_le(const bt_addr_le_t *peer, + const struct bt_le_conn_param *param); + +/** @brief Automatically connect to remote device if it's in range. + * + * This function enables/disables automatic connection initiation. + * Everytime the device looses the connection with peer, this connection + * will be re-established if connectable advertisement from peer is received. + * + * @param addr Remote Bluetooth address. + * @param param If non-NULL, auto connect is enabled with the given + * parameters. If NULL, auto connect is disabled. + * + * @return Zero on success or error code otherwise. + */ +int bt_le_set_auto_conn(bt_addr_le_t *addr, + const struct bt_le_conn_param *param); + +/** @brief Initiate directed advertising to a remote device + * + * Allows initiating a new LE connection to remote peer with the remote + * acting in central role and the local device in peripheral role. + * + * The advertising type must be either BT_LE_ADV_DIRECT_IND or + * BT_LE_ADV_DIRECT_IND_LOW_DUTY. + * + * In case of high duty cycle this will result in a callback with + * connected() with a new connection or with an error. + * + * The advertising may be cancelled with bt_conn_disconnect(). + * + * Returns a new reference that the the caller is responsible for managing. + * + * @param peer Remote address. + * @param param Directed advertising parameters. + * + * @return Valid connection object on success or NULL otherwise. + */ +struct bt_conn *bt_conn_create_slave_le(const bt_addr_le_t *peer, + const struct bt_le_adv_param *param); + +/** Security level. */ +typedef enum __packed { + /** Only for BR/EDR special cases, like SDP */ + BT_SECURITY_NONE, + /** No encryption and no authentication. */ + BT_SECURITY_LOW, + /** Encryption and no authentication (no MITM). */ + BT_SECURITY_MEDIUM, + /** Encryption and authentication (MITM). */ + BT_SECURITY_HIGH, + /** Authenticated Secure Connections */ + BT_SECURITY_FIPS, +} bt_security_t; + +/** @brief Set security level for a connection. + * + * This function enable security (encryption) for a connection. If device is + * already paired with sufficiently strong key encryption will be enabled. If + * link is already encrypted with sufficiently strong key this function does + * nothing. + * + * If device is not paired pairing will be initiated. If device is paired and + * keys are too weak but input output capabilities allow for strong enough keys + * pairing will be initiated. + * + * This function may return error if required level of security is not possible + * to achieve due to local or remote device limitation (eg input output + * capabilities). + * + * @param conn Connection object. + * @param sec Requested security level. + * + * @return 0 on success or negative error + */ +int bt_conn_security(struct bt_conn *conn, bt_security_t sec); + +/** @brief Get encryption key size. + * + * This function gets encryption key size. + * If there is no security (encryption) enabled 0 will be returned. + * + * @param conn Existing connection object. + * + * @return Encryption key size. + */ +uint8_t bt_conn_enc_key_size(struct bt_conn *conn); + +/** @brief Connection callback structure. + * + * This structure is used for tracking the state of a connection. + * It is registered with the help of the bt_conn_cb_register() API. + * It's premissible to register multiple instances of this @ref bt_conn_cb + * type, in case different modules of an application are interested in + * tracking the connection state. If a callback is not of interest for + * an instance, it may be set to NULL and will as a consequence not be + * used for that instance. + */ +struct bt_conn_cb { + /** @brief A new connection has been established. + * + * This callback notifies the application of a new connection. + * In case the err parameter is non-zero it means that the + * connection establishment failed. + * + * @param conn New connection object. + * @param err HCI error. Zero for success, non-zero otherwise. + */ + void (*connected)(struct bt_conn *conn, uint8_t err); + + /** @brief A connection has been disconnected. + * + * This callback notifies the application that a connection + * has been disconnected. + * + * @param conn Connection object. + * @param reason HCI reason for the disconnection. + */ + void (*disconnected)(struct bt_conn *conn, uint8_t reason); + + /** @brief LE connection parameter update request. + * + * This callback notifies the application that a remote device + * is requesting to update the connection parameters. The + * application accepts the parameters by returning true, or + * rejects them by returning false. Before accepting, the + * application may also adjust the parameters to better suit + * its needs. + * + * It is recommended for an application to have just one of these + * callbacks for simplicity. However, if an application registers + * multiple it needs to manage the potentially different + * requirements for each callback. Each callback gets the + * parameters as returned by previous callbacks, i.e. they are not + * necessarily the same ones as the remote originally sent. + * + * @param conn Connection object. + * @param param Proposed connection parameters. + * + * @return true to accept the parameters, or false to reject them. + */ + bool (*le_param_req)(struct bt_conn *conn, + struct bt_le_conn_param *param); + + /** @brief The parameters for an LE connection have been updated. + * + * This callback notifies the application that the connection + * parameters for an LE connection have been updated. + * + * @param conn Connection object. + * @param interval Connection interval. + * @param latency Connection latency. + * @param timeout Connection supervision timeout. + */ + void (*le_param_updated)(struct bt_conn *conn, uint16_t interval, + uint16_t latency, uint16_t timeout); +#if defined(CONFIG_BLUETOOTH_SMP) + /** @brief Remote Identity Address has been resolved. + * + * This callback notifies the application that a remote + * Identity Address has been resolved + * + * @param conn Connection object. + * @param rpa Resolvable Private Address. + * @param identity Identity Address. + */ + void (*identity_resolved)(struct bt_conn *conn, + const bt_addr_le_t *rpa, + const bt_addr_le_t *identity); +#endif /* CONFIG_BLUETOOTH_SMP */ +#if defined(CONFIG_BLUETOOTH_SMP) || defined(CONFIG_BLUETOOTH_BREDR) + /** @brief The security level of a connection has changed. + * + * This callback notifies the application that the security level + * of a connection has changed. + * + * @param conn Connection object. + * @param level New security level of the connection. + */ + void (*security_changed)(struct bt_conn *conn, bt_security_t level); +#endif /* defined(CONFIG_BLUETOOTH_SMP) || defined(CONFIG_BLUETOOTH_BREDR) */ + struct bt_conn_cb *_next; +}; + +/** @brief Register connection callbacks. + * + * Register callbacks to monitor the state of connections. + * + * @param cb Callback struct. + */ +void bt_conn_cb_register(struct bt_conn_cb *cb); + +/** Authenticated pairing callback structure */ +struct bt_conn_auth_cb { + void (*passkey_display)(struct bt_conn *conn, unsigned int passkey); + void (*passkey_entry)(struct bt_conn *conn); + void (*passkey_confirm)(struct bt_conn *conn, unsigned int passkey); + void (*cancel)(struct bt_conn *conn); + void (*pairing_confirm)(struct bt_conn *conn); +#if defined(CONFIG_BLUETOOTH_BREDR) + void (*pincode_entry)(struct bt_conn *conn, bool highsec); +#endif +}; + +/** @brief Register authentication callbacks. + * + * Register callbacks to handle authenticated pairing. Passing NULL unregisters + * previous callbacks structure. + * + * @param cb Callback struct. + * + * @return Zero on success or negative error code otherwise + */ +int bt_conn_auth_cb_register(const struct bt_conn_auth_cb *cb); + +/** @brief Reply with entered passkey. + * + * This function should be called only after passkey_entry callback from + * bt_conn_auth_cb structure was called. + * + * @param conn Connection object. + * @param passkey Entered passkey. + * + * @return Zero on success or negative error code otherwise + */ +int bt_conn_auth_passkey_entry(struct bt_conn *conn, unsigned int passkey); + +/** @brief Cancel ongoing authenticated pairing. + * + * This function allows to cancel ongoing authenticated pairing. + * + * @param conn Connection object. + * + * @return Zero on success or negative error code otherwise + */ +int bt_conn_auth_cancel(struct bt_conn *conn); + +/** @brief Reply if passkey was confirmed to match by user. + * + * This function should be called only after passkey_confirm callback from + * bt_conn_auth_cb structure was called. + * + * @param conn Connection object. + * + * @return Zero on success or negative error code otherwise + */ +int bt_conn_auth_passkey_confirm(struct bt_conn *conn); + +/** @brief Reply if incoming pairing was confirmed by user. + * + * This function should be called only after pairing_confirm callback from + * bt_conn_auth_cb structure was called if user confirmed incoming pairing. + * + * @param conn Connection object. + * + * @return Zero on success or negative error code otherwise + */ +int bt_conn_auth_pairing_confirm(struct bt_conn *conn); + +/** @brief Reply with entered PIN code. + * + * This function should be called only after PIN code callback from + * bt_conn_auth_cb structure was called. It's for legacy 2.0 devices. + * + * @param conn Connection object. + * @param pin Entered PIN code. + * + * @return Zero on success or negative error code otherwise + */ +int bt_conn_auth_pincode_entry(struct bt_conn *conn, const char *pin); + +/** Connection parameters for BR/EDR connections */ +struct bt_br_conn_param { + bool allow_role_switch; +}; + +/** Helper to declare BR/EDR connection parameters inline + * + * @param role_switch True if role switch is allowed + */ +#define BT_BR_CONN_PARAM(role_switch) \ + (&(struct bt_br_conn_param) { \ + .allow_role_switch = (role_switch), \ + }) + +/** Default BR/EDR connection parameters: + * Role switch allowed + */ +#define BT_BR_CONN_PARAM_DEFAULT BT_BR_CONN_PARAM(true) + + +/** @brief Initiate an BR/EDR connection to a remote device. + * + * Allows initiate new BR/EDR link to remote peer using its address. + * Returns a new reference that the the caller is responsible for managing. + * + * @param peer Remote address. + * @param param Initial connection parameters. + * + * @return Valid connection object on success or NULL otherwise. + */ +struct bt_conn *bt_conn_create_br(const bt_addr_t *peer, + const struct bt_br_conn_param *param); + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* __BT_CONN_H */ diff --git a/kernel/protocols/bluetooth/include/bluetooth/gatt.h b/kernel/protocols/bluetooth/include/bluetooth/gatt.h new file mode 100644 index 0000000000..c0df10a115 --- /dev/null +++ b/kernel/protocols/bluetooth/include/bluetooth/gatt.h @@ -0,0 +1,1054 @@ +/** @file + * @brief Generic Attribute Profile handling. + */ + +/* + * Copyright (c) 2015-2016 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef __BT_GATT_H +#define __BT_GATT_H + +/** + * @brief Generic Attribute Profile (GATT) + * @defgroup bt_gatt Generic Attribute Profile (GATT) + * @ingroup bluetooth + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include +#include + +/* GATT attribute permission bit field values */ +enum { + /** No operations supported, e.g. for notify-only */ + BT_GATT_PERM_NONE = 0, + + /** Attribute read permission. */ + BT_GATT_PERM_READ = BIT(0), + + /** Attribute write permission. */ + BT_GATT_PERM_WRITE = BIT(1), + + /** Attribute read permission with encryption. + * + * If set, requires encryption for read access. + */ + BT_GATT_PERM_READ_ENCRYPT = BIT(2), + + /** Attribute write permission with encryption. + * + * If set, requires encryption for write access. + */ + BT_GATT_PERM_WRITE_ENCRYPT = BIT(3), + + /** Attribute read permission with authentication. + * + * If set, requires encryption using authenticated link-key for read + * access. + */ + BT_GATT_PERM_READ_AUTHEN = BIT(4), + + /** Attribute write permission with authentication. + * + * If set, requires encryption using authenticated link-key for write + * access. + */ + BT_GATT_PERM_WRITE_AUTHEN = BIT(5), + + /** Attribute prepare write permission. + * + * If set, allows prepare writes with use of BT_GATT_WRITE_FLAG_PREPARE + * passed to write callback. + */ + BT_GATT_PERM_PREPARE_WRITE = BIT(6), +}; + +/** @def BT_GATT_ERR + * @brief Construct error return value for attribute read and write callbacks. + * + * @param _att_err ATT error code + * + * @return Appropriate error code for the attribute callbacks. + * + */ +#define BT_GATT_ERR(_att_err) (-(_att_err)) + +/* GATT attribute write flags */ +enum { + /** Attribute prepare write flag + * + * If set, write callback should only check if the device is + * authorized but no data shall be written. + */ + BT_GATT_WRITE_FLAG_PREPARE = BIT(0), +}; + +/** @brief GATT Attribute structure. */ +struct bt_gatt_attr { + /** Attribute UUID */ + const struct bt_uuid *uuid; + + /** Attribute read callback + * + * @param conn The connection that is requesting to read + * @param attr The attribute that's being read + * @param buf Buffer to place the read result in + * @param len Length of data to read + * @param offset Offset to start reading from + * + * @return Number fo bytes read, or in case of an error + * BT_GATT_ERR() with a specific ATT error code. + */ + ssize_t (*read)(struct bt_conn *conn, + const struct bt_gatt_attr *attr, + void *buf, uint16_t len, + uint16_t offset); + + /** Attribute write callback + * + * @param conn The connection that is requesting to write + * @param attr The attribute that's being written + * @param buf Buffer with the data to write + * @param len Number of bytes in the buffer + * @param offset Offset to start writing from + * @param flags Flags (BT_GATT_WRITE_*) + * + * @return Number of bytes written, or in case of an error + * BT_GATT_ERR() with a specific ATT error code. + */ + ssize_t (*write)(struct bt_conn *conn, + const struct bt_gatt_attr *attr, + const void *buf, uint16_t len, + uint16_t offset, uint8_t flags); + + /** Attribute user data */ + void *user_data; + /** Attribute handle */ + uint16_t handle; + /** Attribute permissions */ + uint8_t perm; +#if defined(CONFIG_BLUETOOTH_GATT_DYNAMIC_DB) + struct bt_gatt_attr *_next; +#endif /* CONFIG_BLUETOOTH_GATT_DYNAMIC_DB */ +}; + +/** @brief Service Attribute Value. */ +struct bt_gatt_service { + /** Service UUID. */ + const struct bt_uuid *uuid; + /** Service end handle. */ + uint16_t end_handle; +}; + +/** @brief Include Attribute Value. */ +struct bt_gatt_include { + /** Service UUID. */ + const struct bt_uuid *uuid; + /** Service start handle. */ + uint16_t start_handle; + /** Service end handle. */ + uint16_t end_handle; +}; + +/* Characteristic Properties Bit field values */ + +/** @def BT_GATT_CHRC_BROADCAST + * @brief Characteristic broadcast property. + * + * If set, permits broadcasts of the Characteristic Value using Server + * Characteristic Configuration Descriptor. + */ +#define BT_GATT_CHRC_BROADCAST 0x01 +/** @def BT_GATT_CHRC_READ + * @brief Characteristic read property. + * + * If set, permits reads of the Characteristic Value. + */ +#define BT_GATT_CHRC_READ 0x02 +/** @def BT_GATT_CHRC_WRITE_WITHOUT_RESP + * @brief Characteristic write without response property. + * + * If set, permits write of the Characteristic Value without response. + */ +#define BT_GATT_CHRC_WRITE_WITHOUT_RESP 0x04 +/** @def BT_GATT_CHRC_WRITE + * @brief Characteristic write with response property. + * + * If set, permits write of the Characteristic Value with response. + */ +#define BT_GATT_CHRC_WRITE 0x08 +/** @def BT_GATT_CHRC_NOTIFY + * @brief Characteristic notify property. + * + * If set, permits notifications of a Characteristic Value without + * acknowledgment. + */ +#define BT_GATT_CHRC_NOTIFY 0x10 +/** @def BT_GATT_CHRC_INDICATE + * @brief Characteristic indicate property. + * + * If set, permits indications of a Characteristic Value with acknowledgment. + */ +#define BT_GATT_CHRC_INDICATE 0x20 +/** @def BT_GATT_CHRC_AUTH + * @brief Characteristic Authenticated Signed Writes property. + * + * If set, permits signed writes to the Characteristic Value. + */ +#define BT_GATT_CHRC_AUTH 0x40 +/** @def BT_GATT_CHRC_EXT_PROP + * @brief Characteristic Extended Properties property. + * + * If set, additional characteristic properties are defined in the + * Characteristic Extended Properties Descriptor. + */ +#define BT_GATT_CHRC_EXT_PROP 0x80 + +/** @brief Characteristic Attribute Value. */ +struct bt_gatt_chrc { + /** Characteristic UUID. */ + const struct bt_uuid *uuid; + /** Characteristic properties. */ + uint8_t properties; +}; + +/* Characteristic Extended Properties Bit field values */ +#define BT_GATT_CEP_RELIABLE_WRITE 0x0001 +#define BT_GATT_CEP_WRITABLE_AUX 0x0002 + +/** @brief Characteristic Extended Properties Attribute Value. */ +struct bt_gatt_cep { + /** Characteristic Extended properties */ + uint16_t properties; +}; + +/* Client Characteristic Configuration Values */ + +/** @def BT_GATT_CCC_NOTIFY + * @brief Client Characteristic Configuration Notification. + * + * If set, changes to Characteristic Value shall be notified. + */ +#define BT_GATT_CCC_NOTIFY 0x0001 +/** @def BT_GATT_CCC_INDICATE + * @brief Client Characteristic Configuration Indication. + * + * If set, changes to Characteristic Value shall be indicated. + */ +#define BT_GATT_CCC_INDICATE 0x0002 + +/* Client Characteristic Configuration Attribute Value */ +struct bt_gatt_ccc { + /** Client Characteristic Configuration flags */ + uint16_t flags; +}; + +/** @brief GATT Characteristic Presentation Format Attribute Value. */ +struct bt_gatt_cpf { + /** Format of the value of the characteristic */ + uint8_t format; + /** Exponent field to determine how the value of this characteristic is further formatted */ + int8_t exponent; + /** Unit of the characteristic */ + uint16_t unit; + /** Name space of the description */ + uint8_t name_space; + /** Description of the characteristic as defined in a higher layer profile */ + uint16_t description; +} __packed; + +/* Server API */ + +/** @brief Register attribute database. + * + * Register GATT attribute database table. Applications can make use of + * macros such as BT_GATT_PRIMARY_SERVICE, BT_GATT_CHARACTERISTIC, + * BT_GATT_DESCRIPTOR, etc. + * + * @param attrs Database table containing the available attributes. + * @param count Size of the database table. + * + * @return 0 in case of success or negative value in case of error. + */ +int bt_gatt_register(struct bt_gatt_attr *attrs, size_t count); + +enum { + BT_GATT_ITER_STOP = 0, + BT_GATT_ITER_CONTINUE, +}; + +/** @typedef bt_gatt_attr_func_t + * @brief Attribute iterator callback. + * + * @param attr Attribute found. + * @param user_data Data given. + * + * @return BT_GATT_ITER_CONTINUE if should continue to the next attribute + * or BT_GATT_ITER_STOP to stop. + */ +typedef uint8_t (*bt_gatt_attr_func_t)(const struct bt_gatt_attr *attr, + void *user_data); + +/** @brief Attribute iterator. + * + * Iterate attributes in the given range. + * + * @param start_handle Start handle. + * @param end_handle End handle. + * @param func Callback function. + * @param user_data Data to pass to the callback. + */ +void bt_gatt_foreach_attr(uint16_t start_handle, uint16_t end_handle, + bt_gatt_attr_func_t func, void *user_data); + +/** @brief Iterate to the next attribute + * + * Iterate to the next attribute following a given attribute. + * + * @param attr Current Attribute. + * + * @return The next attribute or NULL if it cannot be found. + */ +struct bt_gatt_attr *bt_gatt_attr_next(const struct bt_gatt_attr *attr); + +/** @brief Generic Read Attribute value helper. + * + * Read attribute value storing the result into buffer. + * + * @param conn Connection object. + * @param attr Attribute to read. + * @param buf Buffer to store the value. + * @param buf_len Buffer length. + * @param offset Start offset. + * @param value Attribute value. + * @param value_len Length of the attribute value. + * + * @return int number of bytes read in case of success or negative values in + * case of error. + */ +ssize_t bt_gatt_attr_read(struct bt_conn *conn, const struct bt_gatt_attr *attr, + void *buf, uint16_t buf_len, uint16_t offset, + const void *value, uint16_t value_len); + +/** @brief Read Service Attribute helper. + * + * Read service attribute value storing the result into buffer after + * enconding it. + * NOTE: Only use this with attributes which user_data is a bt_uuid. + * + * @param conn Connection object. + * @param attr Attribute to read. + * @param buf Buffer to store the value read. + * @param len Buffer length. + * @param offset Start offset. + * + * @return int number of bytes read in case of success or negative values in + * case of error. + */ +ssize_t bt_gatt_attr_read_service(struct bt_conn *conn, + const struct bt_gatt_attr *attr, + void *buf, uint16_t len, uint16_t offset); + +/** @def BT_GATT_SERVICE + * @brief Generic Service Declaration Macro. + * + * Helper macro to declare a service attribute. + * + * @param _uuid Service attribute type. + * @param _service Service attribute value. + */ +#define BT_GATT_SERVICE(_uuid, _service) \ +{ \ + .uuid = _uuid, \ + .perm = BT_GATT_PERM_READ, \ + .read = bt_gatt_attr_read_service, \ + .user_data = _service, \ +} + +/** @def BT_GATT_PRIMARY_SERVICE + * @brief Primary Service Declaration Macro. + * + * Helper macro to declare a primary service attribute. + * + * @param _service Service attribute value. + */ +#define BT_GATT_PRIMARY_SERVICE(_service) \ +{ \ + .uuid = BT_UUID_GATT_PRIMARY, \ + .perm = BT_GATT_PERM_READ, \ + .read = bt_gatt_attr_read_service, \ + .user_data = _service, \ +} + +/** @def BT_GATT_SECONDARY_SERVICE + * @brief Secondary Service Declaration Macro. + * + * Helper macro to declare a secondary service attribute. + * + * @param _service Service attribute value. + */ +#define BT_GATT_SECONDARY_SERVICE(_service) \ +{ \ + .uuid = BT_UUID_GATT_SECONDARY, \ + .perm = BT_GATT_PERM_READ, \ + .read = bt_gatt_attr_read_service, \ + .user_data = _service, \ +} + +/** @brief Read Include Attribute helper. + * + * Read include service attribute value storing the result into buffer after + * enconding it. + * NOTE: Only use this with attributes which user_data is a bt_gatt_include. + * + * @param conn Connection object. + * @param attr Attribute to read. + * @param buf Buffer to store the value read. + * @param len Buffer length. + * @param offset Start offset. + * + * @return int number of bytes read in case of success or negative values in + * case of error. + */ +ssize_t bt_gatt_attr_read_included(struct bt_conn *conn, + const struct bt_gatt_attr *attr, + void *buf, uint16_t len, uint16_t offset); + +/** @def BT_GATT_INCLUDE_SERVICE + * @brief Include Service Declaration Macro. + * + * Helper macro to declare database internal include service attribute. + * + * @param _service_incl the first service attribute of service to include + */ +#define BT_GATT_INCLUDE_SERVICE(_service_incl) \ +{ \ + .uuid = BT_UUID_GATT_INCLUDE, \ + .perm = BT_GATT_PERM_READ, \ + .read = bt_gatt_attr_read_included, \ + .user_data = _service_incl, \ +} + +/** @brief Read Characteristic Attribute helper. + * + * Read characteristic attribute value storing the result into buffer after + * enconding it. + * NOTE: Only use this with attributes which user_data is a bt_gatt_chrc. + * + * @param conn Connection object. + * @param attr Attribute to read. + * @param buf Buffer to store the value read. + * @param len Buffer length. + * @param offset Start offset. + * + * @return number of bytes read in case of success or negative values in + * case of error. + */ +ssize_t bt_gatt_attr_read_chrc(struct bt_conn *conn, + const struct bt_gatt_attr *attr, void *buf, + uint16_t len, uint16_t offset); + +/** @def BT_GATT_CHARACTERISTIC + * @brief Characteristic Declaration Macro. + * + * Helper macro to declare a characteristic attribute. + * + * @param _uuid Characteristic attribute uuid. + * @param _props Characteristic attribute properties. + */ +#define BT_GATT_CHARACTERISTIC(_uuid, _props) \ +{ \ + .uuid = BT_UUID_GATT_CHRC, \ + .perm = BT_GATT_PERM_READ, \ + .read = bt_gatt_attr_read_chrc, \ + .user_data = (&(struct bt_gatt_chrc) { .uuid = _uuid, \ + .properties = _props, }),\ +} + +/** @brief GATT CCC configuration entry. */ +struct bt_gatt_ccc_cfg { + /** Config peer address. */ + bt_addr_le_t peer; + /** Config peer value. */ + uint16_t value; + /** Config valid flag. */ + uint8_t valid; +}; + +/* Internal representation of CCC value */ +struct _bt_gatt_ccc { + struct bt_gatt_ccc_cfg *cfg; + size_t cfg_len; + uint16_t value; + void (*cfg_changed)(const struct bt_gatt_attr *attr, + uint16_t value); +}; + +/** @brief Read Client Characteristic Configuration Attribute helper. + * + * Read CCC attribute value storing the result into buffer after + * enconding it. + * NOTE: Only use this with attributes which user_data is a _bt_gatt_ccc. + * + * @param conn Connection object. + * @param attr Attribute to read. + * @param buf Buffer to store the value read. + * @param len Buffer length. + * @param offset Start offset. + * + * @return number of bytes read in case of success or negative values in + * case of error. + */ +ssize_t bt_gatt_attr_read_ccc(struct bt_conn *conn, + const struct bt_gatt_attr *attr, void *buf, + uint16_t len, uint16_t offset); + +/** @brief Write Client Characteristic Configuration Attribute helper. + * + * Write value in the buffer into CCC attribute. + * NOTE: Only use this with attributes which user_data is a _bt_gatt_ccc. + * + * @param conn Connection object. + * @param attr Attribute to read. + * @param buf Buffer to store the value read. + * @param len Buffer length. + * @param offset Start offset. + * @param flags Write flags. + * + * @return number of bytes written in case of success or negative values in + * case of error. + */ +ssize_t bt_gatt_attr_write_ccc(struct bt_conn *conn, + const struct bt_gatt_attr *attr, const void *buf, + uint16_t len, uint16_t offset, uint8_t flags); + +/** @def BT_GATT_CCC + * @brief Client Characteristic Configuration Declaration Macro. + * + * Helper macro to declare a CCC attribute. + * + * @param _cfg Initial configuration. + * @param _cfg_changed Configuration changed callback. + */ +#define BT_GATT_CCC(_cfg, _cfg_changed) \ +{ \ + .uuid = BT_UUID_GATT_CCC, \ + .perm = BT_GATT_PERM_READ | BT_GATT_PERM_WRITE, \ + .read = bt_gatt_attr_read_ccc, \ + .write = bt_gatt_attr_write_ccc, \ + .user_data = (&(struct _bt_gatt_ccc) { .cfg = _cfg, \ + .cfg_len = ARRAY_SIZE(_cfg), \ + .cfg_changed = _cfg_changed, }),\ +} + +/** @brief Read Characteristic Extended Properties Attribute helper + * + * Read CEP attribute value storing the result into buffer after + * encoding it. + * NOTE: Only use this with attributes which user_data is a bt_gatt_cep. + * + * @param conn Connection object + * @param attr Attribute to read + * @param buf Buffer to store the value read + * @param len Buffer length + * @param offset Start offset + * + * @return number of bytes read in case of success or negative values in + * case of error. + */ +ssize_t bt_gatt_attr_read_cep(struct bt_conn *conn, + const struct bt_gatt_attr *attr, void *buf, + uint16_t len, uint16_t offset); + +/** @def BT_GATT_CEP + * @brief Characteristic Extended Properties Declaration Macro. + * + * Helper macro to declare a CEP attribute. + * + * @param _value Descriptor attribute value. + */ +#define BT_GATT_CEP(_value) \ +{ \ + .uuid = BT_UUID_GATT_CEP, \ + .perm = BT_GATT_PERM_READ, \ + .read = bt_gatt_attr_read_cep, \ + .user_data = _value, \ +} + +/** @brief Read Characteristic User Description Descriptor Attribute helper + * + * Read CUD attribute value storing the result into buffer after + * encoding it. + * NOTE: Only use this with attributes which user_data is a NULL-terminated C string. + * + * @param conn Connection object + * @param attr Attribute to read + * @param buf Buffer to store the value read + * @param len Buffer length + * @param offset Start offset + * + * @return number of bytes read in case of success or negative values in + * case of error. + */ +ssize_t bt_gatt_attr_read_cud(struct bt_conn *conn, + const struct bt_gatt_attr *attr, void *buf, + uint16_t len, uint16_t offset); + +/** @def BT_GATT_CUD + * @brief Characteristic User Format Descriptor Declaration Macro. + * + * Helper macro to declare a CUD attribute. + * + * @param _value User description NULL-terminated C string. + * @param _perm Descriptor attribute access permissions. + */ +#define BT_GATT_CUD(_value, _perm) \ +{ \ + .uuid = BT_UUID_GATT_CUD, \ + .perm = _perm, \ + .read = bt_gatt_attr_read_cud, \ + .user_data = _value, \ +} + +/** @brief Read Characteristic Presentation format Descriptor Attribute helper + * + * Read CPF attribute value storing the result into buffer after + * encoding it. + * NOTE: Only use this with attributes which user_data is a bt_gatt_pf. + * + * @param conn Connection object + * @param attr Attribute to read + * @param buf Buffer to store the value read + * @param len Buffer length + * @param offset Start offset + * + * @return number of bytes read in case of success or negative values in + * case of error. + */ +ssize_t bt_gatt_attr_read_cpf(struct bt_conn *conn, + const struct bt_gatt_attr *attr, void *buf, + uint16_t len, uint16_t offset); + +/** @def BT_GATT_CPF + * @brief Characteristic Presentation Format Descriptor Declaration Macro. + * + * Helper macro to declare a CPF attribute. + * + * @param _value Descriptor attribute value. + */ +#define BT_GATT_CPF(_value) \ +{ \ + .uuid = BT_UUID_GATT_CPF, \ + .perm = BT_GATT_PERM_READ, \ + .read = bt_gatt_attr_read_cpf, \ + .user_data = _value, \ +} + +/** @def BT_GATT_DESCRIPTOR + * @brief Descriptor Declaration Macro. + * + * Helper macro to declare a descriptor attribute. + * + * @param _uuid Descriptor attribute uuid. + * @param _perm Descriptor attribute access permissions. + * @param _read Descriptor attribute read callback. + * @param _write Descriptor attribute write callback. + * @param _value Descriptor attribute value. + */ +#define BT_GATT_DESCRIPTOR(_uuid, _perm, _read, _write, _value) \ +{ \ + .uuid = _uuid, \ + .perm = _perm, \ + .read = _read, \ + .write = _write, \ + .user_data = _value, \ +} + +/** @brief Notify attribute value change. + * + * Send notification of attribute value change, if connection is NULL notify + * all peer that have notification enabled via CCC otherwise do a direct + * notification only the given connection. + * + * @param conn Connection object. + * @param attr Attribute object. + * @param data Pointer to Attribute data. + * @param len Attribute value length. + */ +int bt_gatt_notify(struct bt_conn *conn, const struct bt_gatt_attr *attr, + const void *data, uint16_t len); + +/** @typedef bt_gatt_indicate_func_t + * @brief Indication complete result callback. + * + * @param conn Connection object. + * @param attr Attribute object. + * @param err ATT error code + */ +typedef void (*bt_gatt_indicate_func_t)(struct bt_conn *conn, + const struct bt_gatt_attr *attr, + uint8_t err); + +/** @brief GATT Indicate Value parameters */ +struct bt_gatt_indicate_params { + struct bt_att_req _req; + /** Indicate Attribute object*/ + const struct bt_gatt_attr *attr; + /** Indicate Value callback */ + bt_gatt_indicate_func_t func; + /** Indicate Value data*/ + const void *data; + /** Indicate Value length*/ + uint16_t len; +}; + +/** @brief Indicate attribute value change. + * + * Send an indication of attribute value change. + * Note: This function should only be called if CCC is declared with + * BT_GATT_CCC otherwise it cannot find a valid peer configuration. + * + * Note: This procedure is asynchronous therefore the parameters need to + * remains valid while it is active. + * + * @param conn Connection object. + * @param params Indicate parameters. + * + * @return 0 in case of success or negative value in case of error. + */ +int bt_gatt_indicate(struct bt_conn *conn, + struct bt_gatt_indicate_params *params); + +/** @brief Get ATT MTU for a connection + * + * Get negotiated ATT connection MTU, note that this does not equal the largest + * amount of attribute data that can be transferred within a single packet. + * + * @param conn Connection object. + * + * @return MTU in bytes + */ +uint16_t bt_gatt_get_mtu(struct bt_conn *conn); + +/* Client API */ + +/** @brief GATT Exchange MTU parameters */ +struct bt_gatt_exchange_params { + struct bt_att_req _req; + /** Response callback */ + void (*func)(struct bt_conn *conn, uint8_t err, + struct bt_gatt_exchange_params *params); +}; + +/** @brief Exchange MTU + * + * This client procedure can be used to set the MTU to the maximum possible + * size the buffers can hold. + * + * NOTE: Shall only be used once per connection. + * + * @param conn Connection object. + * @param params Exchange MTU parameters. + * + * @return 0 in case of success or negative value in case of error. + */ +int bt_gatt_exchange_mtu(struct bt_conn *conn, + struct bt_gatt_exchange_params *params); + +struct bt_gatt_discover_params; + +/** @typedef bt_gatt_discover_func_t + * @brief Discover attribute callback function. + * + * @param conn Connection object. + * @param attr Attribute found. + * @param params Discovery parameters given. + * + * If discovery procedure has completed this callback will be called with + * attr set to NULL. This will not happen if procedure was stopped by returning + * BT_GATT_ITER_STOP. The attribute is read-only and cannot be cached without + * copying its contents. + * + * @return BT_GATT_ITER_CONTINUE if should continue attribute discovery + * or BT_GATT_ITER_STOP to stop discovery procedure. + */ +typedef uint8_t (*bt_gatt_discover_func_t)(struct bt_conn *conn, + const struct bt_gatt_attr *attr, + struct bt_gatt_discover_params *params); + +enum { + BT_GATT_DISCOVER_PRIMARY, + BT_GATT_DISCOVER_SECONDARY, + BT_GATT_DISCOVER_INCLUDE, + BT_GATT_DISCOVER_CHARACTERISTIC, + BT_GATT_DISCOVER_DESCRIPTOR, +}; + +/** @brief GATT Discover Attributes parameters */ +struct bt_gatt_discover_params { + struct bt_att_req _req; + /** Discover UUID type */ + struct bt_uuid *uuid; + /** Discover attribute callback */ + bt_gatt_discover_func_t func; + union { + struct { + /** Include service attribute declaration handle */ + uint16_t attr_handle; + /** Included service start handle */ + uint16_t start_handle; + /** Included service end handle */ + uint16_t end_handle; + } _included; + /** Discover start handle */ + uint16_t start_handle; + }; + /** Discover end handle */ + uint16_t end_handle; + /** Discover type */ + uint8_t type; +}; + +/** @brief GATT Discover function + * + * This procedure is used by a client to discover attributes on a server. + * + * Primary Service Discovery: Procedure allows to discover specific Primary + * Service based on UUID. + * Include Service Discovery: Procedure allows to discover all Include Services + * within specified range. + * Characteristic Discovery: Procedure allows to discover all characteristics + * within specified handle range as well as + * discover characteristics with specified UUID. + * Descriptors Discovery: Procedure allows to discover all characteristic + * descriptors within specified range. + * + * For each attribute found the callback is called which can then decide + * whether to continue discovering or stop. + * + * Note: This procedure is asynchronous therefore the parameters need to + * remains valid while it is active. + * + * @param conn Connection object. + * @param params Discover parameters. + * + * @return 0 in case of success or negative value in case of error. + */ +int bt_gatt_discover(struct bt_conn *conn, + struct bt_gatt_discover_params *params); + +struct bt_gatt_read_params; + +/** @typedef bt_gatt_read_func_t + * @brief Read callback function + * + * @param conn Connection object. + * @param err ATT error code. + * @param params Read parameters used. + * @param data Attribute value data. NULL means read has completed. + * @param length Attribute value length. + */ +typedef uint8_t (*bt_gatt_read_func_t)(struct bt_conn *conn, uint8_t err, + struct bt_gatt_read_params *params, + const void *data, uint16_t length); + +/** @brief GATT Read parameters + * @param func Read attribute callback + * @param handle_count If equals to 1 single.handle and single.offset + * are used. If >1 Read Multiple Characteristic + * Values is performed and handles are used. + * @param handle Attribute handle + * @param offset Attribute data offset + * @param handles Handles to read in Read Multiple Characteristic Values + */ +struct bt_gatt_read_params { + struct bt_att_req _req; + bt_gatt_read_func_t func; + size_t handle_count; + union { + struct __single { + uint16_t handle; + uint16_t offset; + } single; + uint16_t *handles; + }; +}; + +/** @brief Read Attribute Value by handle + * + * This procedure read the attribute value and return it to the callback. + * + * Note: This procedure is asynchronous therefore the parameters need to + * remains valid while it is active. + * + * @param conn Connection object. + * @param params Read parameters. + * + * @return 0 in case of success or negative value in case of error. + */ +int bt_gatt_read(struct bt_conn *conn, struct bt_gatt_read_params *params); + +struct bt_gatt_write_params; + +/** @typedef bt_gatt_write_func_t + * @brief Write callback function + * + * @param conn Connection object. + * @param err ATT error code. + * @param params Write parameters used. + */ +typedef void (*bt_gatt_write_func_t)(struct bt_conn *conn, uint8_t err, + struct bt_gatt_write_params *params); + +/** @brief GATT Write parameters */ +struct bt_gatt_write_params { + struct bt_att_req _req; + /** Response callback */ + bt_gatt_write_func_t func; + /** Attribute handle */ + uint16_t handle; + /** Attribute data offset */ + uint16_t offset; + /** Data to be written */ + const void *data; + /** Length of the data */ + uint16_t length; +}; + +/** @brief Write Attribute Value by handle + * + * This procedure write the attribute value and return the result in the + * callback. + * + * Note: This procedure is asynchronous therefore the parameters need to + * remains valid while it is active. + * + * @param conn Connection object. + * @param params Write parameters. + * + * @return 0 in case of success or negative value in case of error. + */ +int bt_gatt_write(struct bt_conn *conn, struct bt_gatt_write_params *params); + +/** @brief Write Attribute Value by handle without response + * + * This procedure write the attribute value without requiring an + * acknowledgement that the write was successfully performed + * + * @param conn Connection object. + * @param handle Attribute handle. + * @param data Data to be written. + * @param length Data length. + * @param sign Whether to sign data + * + * @return 0 in case of success or negative value in case of error. + */ +int bt_gatt_write_without_response(struct bt_conn *conn, uint16_t handle, + const void *data, uint16_t length, + bool sign); + +struct bt_gatt_subscribe_params; + +/** @typedef bt_gatt_notify_func_t + * @brief Notification callback function + * + * @param conn Connection object. + * @param params Subscription parameters. + * @param data Attribute value data. If NULL then subscription was removed. + * @param length Attribute value length. + */ +typedef uint8_t (*bt_gatt_notify_func_t)(struct bt_conn *conn, + struct bt_gatt_subscribe_params *params, + const void *data, uint16_t length); + +/* Subscription flags */ +enum { + /** Persistence flag + * + * If set, indicates that the subscription is not saved + * on the GATT server side. Therefore, upon disconnection, + * the subscription will be automatically removed + * from the client's subscriptions list and + * when the client reconnects, it will have to + * issue a new subscription. + */ + BT_GATT_SUBSCRIBE_FLAG_VOLATILE = BIT(0), +}; + +/** @brief GATT Subscribe parameters */ +struct bt_gatt_subscribe_params { + struct bt_att_req _req; + bt_addr_le_t _peer; + /** Notification value callback */ + bt_gatt_notify_func_t notify; + /** Subscribe value handle */ + uint16_t value_handle; + /** Subscribe CCC handle */ + uint16_t ccc_handle; + /** Subscribe value */ + uint16_t value; + /** Subscription flags */ + uint8_t flags; + sys_snode_t node; +}; + +/** @brief Subscribe Attribute Value Notification + * + * This procedure subscribe to value notification using the Client + * Characteristic Configuration handle. + * If notification received subscribe value callback is called to return + * notified value. One may then decide whether to unsubscribe directly from + * this callback. Notification callback with NULL data will not be called if + * subscription was removed by this method. + * + * Note: This procedure is asynchronous therefore the parameters need to + * remains valid while it is active. + * + * @param conn Connection object. + * @param params Subscribe parameters. + * + * @return 0 in case of success or negative value in case of error. + */ +int bt_gatt_subscribe(struct bt_conn *conn, + struct bt_gatt_subscribe_params *params); + +/** @brief Unsubscribe Attribute Value Notification + * + * This procedure unsubscribe to value notification using the Client + * Characteristic Configuration handle. Notification callback with NULL data + * will not be called if subscription was removed by this call. + * + * @param conn Connection object. + * @param params Subscribe parameters. + * + * @return 0 in case of success or negative value in case of error. + */ +int bt_gatt_unsubscribe(struct bt_conn *conn, + struct bt_gatt_subscribe_params *params); + +/** @brief Cancel GATT pending request + * + * @param conn Connection object. + * @param params Requested params address. + */ +void bt_gatt_cancel(struct bt_conn *conn, void *params); + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* __BT_GATT_H */ diff --git a/kernel/protocols/bluetooth/include/bluetooth/hci.h b/kernel/protocols/bluetooth/include/bluetooth/hci.h new file mode 100644 index 0000000000..d683eb0844 --- /dev/null +++ b/kernel/protocols/bluetooth/include/bluetooth/hci.h @@ -0,0 +1,1254 @@ +/* hci.h - Bluetooth Host Control Interface definitions */ + +/* + * Copyright (c) 2015-2016 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef __BT_HCI_H +#define __BT_HCI_H + +#include +#include +#include +#include + +#ifndef __packed +#define __packed __attribute__((__packed__)) +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#define BT_ADDR_LE_PUBLIC 0x00 +#define BT_ADDR_LE_RANDOM 0x01 +#define BT_ADDR_LE_PUBLIC_ID 0x02 +#define BT_ADDR_LE_RANDOM_ID 0x03 + +typedef struct { + uint8_t val[6]; +} bt_addr_t; + +typedef struct { + uint8_t type; + bt_addr_t a; +} bt_addr_le_t; + +#define BT_ADDR_ANY (&(bt_addr_t) {{0, 0, 0, 0, 0, 0} }) +#define BT_ADDR_LE_ANY (&(bt_addr_le_t) { 0, { {0, 0, 0, 0, 0, 0} } }) +#define BT_ADDR_LE_NONE (&(bt_addr_le_t) { 0, \ + { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } } }) + +static inline int bt_addr_cmp(const bt_addr_t *a, const bt_addr_t *b) +{ + return memcmp(a, b, sizeof(*a)); +} + +static inline int bt_addr_le_cmp(const bt_addr_le_t *a, const bt_addr_le_t *b) +{ + return memcmp(a, b, sizeof(*a)); +} + +static inline void bt_addr_copy(bt_addr_t *dst, const bt_addr_t *src) +{ + memcpy(dst, src, sizeof(*dst)); +} + +static inline void bt_addr_le_copy(bt_addr_le_t *dst, const bt_addr_le_t *src) +{ + memcpy(dst, src, sizeof(*dst)); +} + +#define BT_ADDR_IS_RPA(addr) (((addr)->val[5] & 0xc0) == 0x40) +#define BT_ADDR_IS_NRPA(addr) (((addr)->val[5] & 0xc0) == 0x00) +#define BT_ADDR_IS_STATIC(addr) (((addr)->val[5] & 0xc0) == 0xc0) + +#define BT_ADDR_SET_RPA(addr) ((addr)->val[5] = \ + (((addr)->val[5] & 0x3f) | 0x40)) +#define BT_ADDR_SET_NRPA(addr) ((addr)->val[5] &= 0x3f) +#define BT_ADDR_SET_STATIC(addr) ((addr)->val[5] |= 0xc0) + +int bt_addr_le_create_nrpa(bt_addr_le_t *addr); +int bt_addr_le_create_static(bt_addr_le_t *addr); + +static inline bool bt_addr_le_is_rpa(const bt_addr_le_t *addr) +{ + if (addr->type != BT_ADDR_LE_RANDOM) { + return false; + } + + return BT_ADDR_IS_RPA(&addr->a); +} + +static inline bool bt_addr_le_is_identity(const bt_addr_le_t *addr) +{ + if (addr->type == BT_ADDR_LE_PUBLIC) { + return true; + } + + return BT_ADDR_IS_STATIC(&addr->a); +} + +/* HCI Error Codes */ +#define BT_HCI_ERR_UNKNOWN_CMD 0x01 +#define BT_HCI_ERR_UNKNOWN_CONN_ID 0x02 +#define BT_HCI_ERR_AUTHENTICATION_FAIL 0x05 +#define BT_HCI_ERR_PIN_OR_KEY_MISSING 0x06 +#define BT_HCI_ERR_MEM_CAPACITY_EXCEEDED 0x07 +#define BT_HCI_ERR_CMD_DISALLOWED 0x0c +#define BT_HCI_ERR_INSUFFICIENT_RESOURCES 0x0d +#define BT_HCI_ERR_UNSUPP_FEATURE_PARAMS_VAL 0x11 +#define BT_HCI_ERR_INVALID_PARAMS 0x12 +#define BT_HCI_ERR_REMOTE_USER_TERM_CONN 0x13 +#define BT_HCI_ERR_PAIRING_NOT_ALLOWED 0x18 +#define BT_HCI_ERR_UNSUPP_REMOTE_FEATURE 0x1a +#define BT_HCI_ERR_INVALID_LL_PARAMS 0x1e +#define BT_HCI_ERR_UNSPECIFIED 0x1f +#define BT_HCI_ERR_PAIRING_NOT_SUPPORTED 0x29 +#define BT_HCI_ERR_UNACCEPT_CONN_PARAMS 0x3b + +/* EIR/AD data type definitions */ +#define BT_DATA_FLAGS 0x01 /* AD flags */ +#define BT_DATA_UUID16_SOME 0x02 /* 16-bit UUID, more available */ +#define BT_DATA_UUID16_ALL 0x03 /* 16-bit UUID, all listed */ +#define BT_DATA_UUID32_SOME 0x04 /* 32-bit UUID, more available */ +#define BT_DATA_UUID32_ALL 0x05 /* 32-bit UUID, all listed */ +#define BT_DATA_UUID128_SOME 0x06 /* 128-bit UUID, more available */ +#define BT_DATA_UUID128_ALL 0x07 /* 128-bit UUID, all listed */ +#define BT_DATA_NAME_SHORTENED 0x08 /* Shortened name */ +#define BT_DATA_NAME_COMPLETE 0x09 /* Complete name */ +#define BT_DATA_TX_POWER 0x0a /* Tx Power */ +#define BT_DATA_SOLICIT16 0x14 /* Solicit UUIDs, 16-bit */ +#define BT_DATA_SOLICIT128 0x15 /* Solicit UUIDs, 128-bit */ +#define BT_DATA_SVC_DATA16 0x16 /* Service data, 16-bit UUID */ +#define BT_DATA_GAP_APPEARANCE 0x19 /* GAP appearance */ +#define BT_DATA_SOLICIT32 0x1f /* Solicit UUIDs, 32-bit */ +#define BT_DATA_SVC_DATA32 0x20 /* Service data, 32-bit UUID */ +#define BT_DATA_SVC_DATA128 0x21 /* Service data, 128-bit UUID */ +#define BT_DATA_MANUFACTURER_DATA 0xff /* Manufacturer Specific Data */ + +#define BT_LE_AD_LIMITED 0x01 /* Limited Discoverable */ +#define BT_LE_AD_GENERAL 0x02 /* General Discoverable */ +#define BT_LE_AD_NO_BREDR 0x04 /* BR/EDR not supported */ + +struct bt_hci_evt_hdr { + uint8_t evt; + uint8_t len; +} __packed; +#define BT_HCI_EVT_HDR_SIZE 2 + +#define BT_ACL_START_NO_FLUSH 0x00 +#define BT_ACL_CONT 0x01 +#define BT_ACL_START 0x02 + +#define bt_acl_handle(h) ((h) & 0x0fff) +#define bt_acl_flags(h) ((h) >> 12) +#define bt_acl_handle_pack(h, f) ((h) | ((f) << 12)) + +struct bt_hci_acl_hdr { + uint16_t handle; + uint16_t len; +} __packed; +#define BT_HCI_ACL_HDR_SIZE 4 + +struct bt_hci_cmd_hdr { + uint16_t opcode; + uint8_t param_len; +} __packed; +#define BT_HCI_CMD_HDR_SIZE 3 + +/* Supported Commands */ +#define BT_CMD_TEST(cmd, octet, bit) (cmd[octet] & BIT(bit)) +#define BT_CMD_LE_STATES(cmd) BT_CMD_TEST(cmd, 28, 3) + +#define BT_FEAT_TEST(feat, page, octet, bit) (feat[page][octet] & BIT(bit)) + +#define BT_FEAT_BREDR(feat) !BT_FEAT_TEST(feat, 0, 4, 5) +#define BT_FEAT_LE(feat) BT_FEAT_TEST(feat, 0, 4, 6) +#define BT_FEAT_EXT_FEATURES(feat) BT_FEAT_TEST(feat, 0, 7, 7) +#define BT_FEAT_HOST_SSP(feat) BT_FEAT_TEST(feat, 1, 0, 0) +#define BT_FEAT_SC(feat) BT_FEAT_TEST(feat, 2, 1, 0) + +#define BT_FEAT_LMP_ESCO_CAPABLE(feat) BT_FEAT_TEST(feat, 0, 3, 7) +#define BT_FEAT_HV2_PKT(feat) BT_FEAT_TEST(feat, 0, 1, 4) +#define BT_FEAT_HV3_PKT(feat) BT_FEAT_TEST(feat, 0, 1, 5) +#define BT_FEAT_EV4_PKT(feat) BT_FEAT_TEST(feat, 0, 4, 0) +#define BT_FEAT_EV5_PKT(feat) BT_FEAT_TEST(feat, 0, 4, 1) +#define BT_FEAT_2EV3_PKT(feat) BT_FEAT_TEST(feat, 0, 5, 5) +#define BT_FEAT_3EV3_PKT(feat) BT_FEAT_TEST(feat, 0, 5, 6) +#define BT_FEAT_3SLOT_PKT(feat) BT_FEAT_TEST(feat, 0, 5, 7) + +/* LE features */ +#define BT_LE_FEAT_BIT_ENC 0 +#define BT_LE_FEAT_BIT_CONN_PARAM_REQ 1 +#define BT_LE_FEAT_BIT_EXT_REJ_IND 2 +#define BT_LE_FEAT_BIT_SLAVE_FEAT_REQ 3 +#define BT_LE_FEAT_BIT_PING 4 +#define BT_LE_FEAT_BIT_DLE 5 +#define BT_LE_FEAT_BIT_PRIVACY 6 +#define BT_LE_FEAT_BIT_EXT_SCAN 7 + +#define BT_FEAT_LE_ENCR(feat) BT_FEAT_TEST(feat, 0, 0, \ + BT_LE_FEAT_BIT_ENC) +#define BT_FEAT_LE_CONN_PARAM_REQ_PROC(feat) BT_FEAT_TEST(feat, 0, 0, \ + BT_LE_FEAT_BIT_CONN_PARAM_REQ) +#define BT_FEAT_LE_SLAVE_FEATURE_XCHG(feat) BT_FEAT_TEST(feat, 0, 0, \ + BT_LE_FEAT_BIT_SLAVE_FEAT_REQ) +#define BT_FEAT_LE_DLE(feat) BT_FEAT_TEST(feat, 0, 0, \ + BT_LE_FEAT_BIT_DLE) + +/* LE States */ +#define BT_LE_STATES_SLAVE_CONN_ADV(states) (states & 0x0000004000000000) + +/* Bonding/authentication types */ +#define BT_HCI_NO_BONDING 0x00 +#define BT_HCI_NO_BONDING_MITM 0x01 +#define BT_HCI_DEDICATED_BONDING 0x02 +#define BT_HCI_DEDICATED_BONDING_MITM 0x03 +#define BT_HCI_GENERAL_BONDING 0x04 +#define BT_HCI_GENERAL_BONDING_MITM 0x05 + +/* + * MITM protection is enabled in SSP authentication requirements octet when + * LSB bit is set. + */ +#define BT_MITM 0x01 + +/* I/O capabilities */ +#define BT_IO_DISPLAY_ONLY 0x00 +#define BT_IO_DISPLAY_YESNO 0x01 +#define BT_IO_KEYBOARD_ONLY 0x02 +#define BT_IO_NO_INPUT_OUTPUT 0x03 + +/* Defined GAP timers */ +#define BT_GAP_SCAN_FAST_INTERVAL 0x0060 /* 60 ms */ +#define BT_GAP_SCAN_FAST_WINDOW 0x0030 /* 30 ms */ +#define BT_GAP_SCAN_SLOW_INTERVAL_1 0x0800 /* 1.28 s */ +#define BT_GAP_SCAN_SLOW_WINDOW_1 0x0012 /* 11.25 ms */ +#define BT_GAP_SCAN_SLOW_INTERVAL_2 0x1000 /* 2.56 s */ +#define BT_GAP_SCAN_SLOW_WINDOW_2 0x0012 /* 11.25 ms */ +#define BT_GAP_ADV_FAST_INT_MIN_1 0x0030 /* 30 ms */ +#define BT_GAP_ADV_FAST_INT_MAX_1 0x0060 /* 60 ms */ +#define BT_GAP_ADV_FAST_INT_MIN_2 0x00a0 /* 100 ms */ +#define BT_GAP_ADV_FAST_INT_MAX_2 0x00f0 /* 150 ms */ +#define BT_GAP_ADV_SLOW_INT_MIN 0x0640 /* 1 s */ +#define BT_GAP_ADV_SLOW_INT_MAX 0x0780 /* 1.2 s */ +#define BT_GAP_INIT_CONN_INT_MIN 0x0018 /* 30 ms */ +#define BT_GAP_INIT_CONN_INT_MAX 0x0028 /* 50 ms */ + +/* SCO packet types */ +#define HCI_PKT_TYPE_HV1 0x0020 +#define HCI_PKT_TYPE_HV2 0x0040 +#define HCI_PKT_TYPE_HV3 0x0080 + +/* eSCO packet types */ +#define HCI_PKT_TYPE_ESCO_HV1 0x0001 +#define HCI_PKT_TYPE_ESCO_HV2 0x0002 +#define HCI_PKT_TYPE_ESCO_HV3 0x0004 +#define HCI_PKT_TYPE_ESCO_EV3 0x0008 +#define HCI_PKT_TYPE_ESCO_EV4 0x0010 +#define HCI_PKT_TYPE_ESCO_EV5 0x0020 +#define HCI_PKT_TYPE_ESCO_2EV3 0x0040 +#define HCI_PKT_TYPE_ESCO_3EV3 0x0080 +#define HCI_PKT_TYPE_ESCO_2EV5 0x0100 +#define HCI_PKT_TYPE_ESCO_3EV5 0x0200 + + +#define ESCO_PKT_MASK (HCI_PKT_TYPE_ESCO_HV1 | \ + HCI_PKT_TYPE_ESCO_HV2 | \ + HCI_PKT_TYPE_ESCO_HV3) +#define SCO_PKT_MASK (HCI_PKT_TYPE_HV1 | \ + HCI_PKT_TYPE_HV2 | \ + HCI_PKT_TYPE_HV3) +#define EDR_ESCO_PKT_MASK (HCI_PKT_TYPE_ESCO_2EV3 | \ + HCI_PKT_TYPE_ESCO_3EV3 | \ + HCI_PKT_TYPE_ESCO_2EV5 | \ + HCI_PKT_TYPE_ESCO_3EV5) + +/* HCI BR/EDR link types */ +#define BT_HCI_SCO 0x00 +#define BT_HCI_ACL 0x01 +#define BT_HCI_ESCO 0x02 + +/* OpCode Group Fields */ +#define BT_OGF_LINK_CTRL 0x01 +#define BT_OGF_BASEBAND 0x03 +#define BT_OGF_INFO 0x04 +#define BT_OGF_STATUS 0x05 +#define BT_OGF_LE 0x08 +#define BT_OGF_VS 0x3f + +/* Construct OpCode from OGF and OCF */ +#define BT_OP(ogf, ocf) ((ocf) | ((ogf) << 10)) + +/* Obtain OGF from OpCode */ +#define BT_OGF(opcode) (((opcode) >> 10) & BIT_MASK(6)) +/* Obtain OCF from OpCode */ +#define BT_OCF(opcode) ((opcode) & BIT_MASK(10)) + +#define BT_HCI_OP_INQUIRY BT_OP(BT_OGF_LINK_CTRL, 0x0001) +struct bt_hci_op_inquiry { + uint8_t lap[3]; + uint8_t length; + uint8_t num_rsp; +} __packed; + +#define BT_HCI_OP_INQUIRY_CANCEL BT_OP(BT_OGF_LINK_CTRL, 0x0002) + +#define BT_HCI_OP_CONNECT BT_OP(BT_OGF_LINK_CTRL, 0x0005) +struct bt_hci_cp_connect { + bt_addr_t bdaddr; + uint16_t packet_type; + uint8_t pscan_rep_mode; + uint8_t reserved; + uint16_t clock_offset; + uint8_t allow_role_switch; +} __packed; + +#define BT_HCI_OP_DISCONNECT BT_OP(BT_OGF_LINK_CTRL, 0x0006) +struct bt_hci_cp_disconnect { + uint16_t handle; + uint8_t reason; +} __packed; + +#define BT_HCI_OP_CONNECT_CANCEL BT_OP(BT_OGF_LINK_CTRL, 0x0008) +struct bt_hci_cp_connect_cancel { + bt_addr_t bdaddr; +} __packed; +struct bt_hci_rp_connect_cancel { + uint8_t status; + bt_addr_t bdaddr; +} __packed; + +#define BT_HCI_OP_ACCEPT_CONN_REQ BT_OP(BT_OGF_LINK_CTRL, 0x0009) +struct bt_hci_cp_accept_conn_req { + bt_addr_t bdaddr; + uint8_t role; +} __packed; + +#define BT_HCI_OP_ACCEPT_SYNC_CONN_REQ BT_OP(BT_OGF_LINK_CTRL, 0x0029) +struct bt_hci_cp_accept_sync_conn_req { + bt_addr_t bdaddr; + uint32_t tx_bandwidth; + uint32_t rx_bandwidth; + uint16_t max_latency; + uint16_t content_format; + uint8_t retrans_effort; + uint16_t pkt_type; +} __packed; + +#define BT_HCI_OP_REJECT_CONN_REQ BT_OP(BT_OGF_LINK_CTRL, 0x000a) +struct bt_hci_cp_reject_conn_req { + bt_addr_t bdaddr; + uint8_t reason; +} __packed; + +#define BT_HCI_OP_LINK_KEY_REPLY BT_OP(BT_OGF_LINK_CTRL, 0x000b) +struct bt_hci_cp_link_key_reply { + bt_addr_t bdaddr; + uint8_t link_key[16]; +} __packed; + +#define BT_HCI_OP_LINK_KEY_NEG_REPLY BT_OP(BT_OGF_LINK_CTRL, 0x000c) +struct bt_hci_cp_link_key_neg_reply { + bt_addr_t bdaddr; +} __packed; + +#define BT_HCI_OP_PIN_CODE_REPLY BT_OP(BT_OGF_LINK_CTRL, 0x000d) +struct bt_hci_cp_pin_code_reply { + bt_addr_t bdaddr; + uint8_t pin_len; + uint8_t pin_code[16]; +} __packed; +struct bt_hci_rp_pin_code_reply { + uint8_t status; + bt_addr_t bdaddr; +} __packed; + +#define BT_HCI_OP_PIN_CODE_NEG_REPLY BT_OP(BT_OGF_LINK_CTRL, 0x000e) +struct bt_hci_cp_pin_code_neg_reply { + bt_addr_t bdaddr; +} __packed; +struct bt_hci_rp_pin_code_neg_reply { + uint8_t status; + bt_addr_t bdaddr; +} __packed; + +#define BT_HCI_OP_AUTH_REQUESTED BT_OP(BT_OGF_LINK_CTRL, 0x0011) +struct bt_hci_cp_auth_requested { + uint16_t handle; +} __packed; + +#define BT_HCI_OP_SET_CONN_ENCRYPT BT_OP(BT_OGF_LINK_CTRL, 0x0013) +struct bt_hci_cp_set_conn_encrypt { + uint16_t handle; + uint8_t encrypt; +} __packed; + +#define BT_HCI_OP_REMOTE_NAME_REQUEST BT_OP(BT_OGF_LINK_CTRL, 0x0019) +struct bt_hci_cp_remote_name_request { + bt_addr_t bdaddr; + uint8_t pscan_rep_mode; + uint8_t reserved; + uint16_t clock_offset; +} __packed; + +#define BT_HCI_OP_REMOTE_NAME_CANCEL BT_OP(BT_OGF_LINK_CTRL, 0x001a) +struct bt_hci_cp_remote_name_cancel { + bt_addr_t bdaddr; +} __packed; +struct bt_hci_rp_remote_name_cancel { + uint8_t status; + bt_addr_t bdaddr; +} __packed; + +#define BT_HCI_OP_READ_REMOTE_FEATURES BT_OP(BT_OGF_LINK_CTRL, 0x001b) +struct bt_hci_cp_read_remote_features { + uint16_t handle; +} __packed; + +#define BT_HCI_OP_READ_REMOTE_EXT_FEATURES BT_OP(BT_OGF_LINK_CTRL, 0x001c) +struct bt_hci_cp_read_remote_ext_features { + uint16_t handle; + uint8_t page; +} __packed; + +#define BT_HCI_OP_READ_REMOTE_VERSION_INFO BT_OP(BT_OGF_LINK_CTRL, 0x001d) +struct bt_hci_cp_read_remote_version_info { + uint16_t handle; +} __packed; + +#define BT_HCI_OP_IO_CAPABILITY_REPLY BT_OP(BT_OGF_LINK_CTRL, 0x002b) +struct bt_hci_cp_io_capability_reply { + bt_addr_t bdaddr; + uint8_t capability; + uint8_t oob_data; + uint8_t authentication; +} __packed; + +#define BT_HCI_OP_USER_CONFIRM_REPLY BT_OP(BT_OGF_LINK_CTRL, 0x002c) +#define BT_HCI_OP_USER_CONFIRM_NEG_REPLY BT_OP(BT_OGF_LINK_CTRL, 0x002d) +struct bt_hci_cp_user_confirm_reply { + bt_addr_t bdaddr; +} __packed; +struct bt_hci_rp_user_confirm_reply { + uint8_t status; + bt_addr_t bdaddr; +} __packed; + +#define BT_HCI_OP_USER_PASSKEY_REPLY BT_OP(BT_OGF_LINK_CTRL, 0x002e) +struct bt_hci_cp_user_passkey_reply { + bt_addr_t bdaddr; + uint32_t passkey; +} __packed; + +#define BT_HCI_OP_USER_PASSKEY_NEG_REPLY BT_OP(BT_OGF_LINK_CTRL, 0x002f) +struct bt_hci_cp_user_passkey_neg_reply { + bt_addr_t bdaddr; +} __packed; + +#define BT_HCI_OP_IO_CAPABILITY_NEG_REPLY BT_OP(BT_OGF_LINK_CTRL, 0x0034) +struct bt_hci_cp_io_capability_neg_reply { + bt_addr_t bdaddr; + uint8_t reason; +} __packed; + +#define BT_HCI_OP_SET_EVENT_MASK BT_OP(BT_OGF_BASEBAND, 0x0001) +struct bt_hci_cp_set_event_mask { + uint8_t events[8]; +} __packed; + +#define BT_HCI_OP_RESET BT_OP(BT_OGF_BASEBAND, 0x0003) + +#define BT_HCI_OP_WRITE_LOCAL_NAME BT_OP(BT_OGF_BASEBAND, 0x0013) +struct bt_hci_write_local_name { + uint8_t local_name[248]; +} __packed; + +#define BT_HCI_OP_WRITE_PAGE_TIMEOUT BT_OP(BT_OGF_BASEBAND, 0x0018) + +#define BT_HCI_OP_WRITE_SCAN_ENABLE BT_OP(BT_OGF_BASEBAND, 0x001a) +#define BT_BREDR_SCAN_DISABLED 0x00 +#define BT_BREDR_SCAN_INQUIRY 0x01 +#define BT_BREDR_SCAN_PAGE 0x02 + +#define BT_HCI_CTL_TO_HOST_FLOW_ENABLE 0x01 +#define BT_HCI_OP_SET_CTL_TO_HOST_FLOW BT_OP(BT_OGF_BASEBAND, 0x0031) + +#define BT_HCI_OP_HOST_BUFFER_SIZE BT_OP(BT_OGF_BASEBAND, 0x0033) +struct bt_hci_cp_host_buffer_size { + uint16_t acl_mtu; + uint8_t sco_mtu; + uint16_t acl_pkts; + uint16_t sco_pkts; +} __packed; + +struct bt_hci_handle_count { + uint16_t handle; + uint16_t count; +} __packed; + +#define BT_HCI_OP_HOST_NUM_COMPLETED_PACKETS BT_OP(BT_OGF_BASEBAND, 0x0035) +struct bt_hci_cp_host_num_completed_packets { + uint8_t num_handles; + struct bt_hci_handle_count h[0]; +} __packed; + +#define BT_HCI_OP_WRITE_INQUIRY_MODE BT_OP(BT_OGF_BASEBAND, 0x0045) +struct bt_hci_cp_write_inquiry_mode { + uint8_t mode; +} __packed; + +#define BT_HCI_OP_WRITE_SSP_MODE BT_OP(BT_OGF_BASEBAND, 0x0056) +struct bt_hci_cp_write_ssp_mode { + uint8_t mode; +} __packed; + +#define BT_HCI_OP_LE_WRITE_LE_HOST_SUPP BT_OP(BT_OGF_BASEBAND, 0x006d) +struct bt_hci_cp_write_le_host_supp { + uint8_t le; + uint8_t simul; +} __packed; + +#define BT_HCI_OP_WRITE_SC_HOST_SUPP BT_OP(BT_OGF_BASEBAND, 0x007a) +struct bt_hci_cp_write_sc_host_supp { + uint8_t sc_support; +} __packed; + +/* HCI version from Assigned Numbers */ +#define BT_HCI_VERSION_1_0B 0 +#define BT_HCI_VERSION_1_1 1 +#define BT_HCI_VERSION_1_2 2 +#define BT_HCI_VERSION_2_0 3 +#define BT_HCI_VERSION_2_1 4 +#define BT_HCI_VERSION_3_0 5 +#define BT_HCI_VERSION_4_0 6 +#define BT_HCI_VERSION_4_1 7 +#define BT_HCI_VERSION_4_2 8 +#define BT_HCI_VERSION_5_0 9 + +#define BT_HCI_OP_READ_LOCAL_VERSION_INFO BT_OP(BT_OGF_INFO, 0x0001) +struct bt_hci_rp_read_local_version_info { + uint8_t status; + uint8_t hci_version; + uint16_t hci_revision; + uint8_t lmp_version; + uint16_t manufacturer; + uint16_t lmp_subversion; +} __packed; + +#define BT_HCI_OP_READ_SUPPORTED_COMMANDS BT_OP(BT_OGF_INFO, 0x0002) +struct bt_hci_rp_read_supported_commands { + uint8_t status; + uint8_t commands[64]; +} __packed; + +#define BT_HCI_OP_READ_LOCAL_EXT_FEATURES BT_OP(BT_OGF_INFO, 0x0004) +struct bt_hci_cp_read_local_ext_features { + uint8_t page; +}; +struct bt_hci_rp_read_local_ext_features { + uint8_t status; + uint8_t page; + uint8_t max_page; + uint8_t ext_features[8]; +} __packed; + +#define BT_HCI_OP_READ_LOCAL_FEATURES BT_OP(BT_OGF_INFO, 0x0003) +struct bt_hci_rp_read_local_features { + uint8_t status; + uint8_t features[8]; +} __packed; + +#define BT_HCI_OP_READ_BUFFER_SIZE BT_OP(BT_OGF_INFO, 0x0005) +struct bt_hci_rp_read_buffer_size { + uint8_t status; + uint16_t acl_max_len; + uint8_t sco_max_len; + uint16_t acl_max_num; + uint16_t sco_max_num; +} __packed; + +#define BT_HCI_OP_READ_BD_ADDR BT_OP(BT_OGF_INFO, 0x0009) +struct bt_hci_rp_read_bd_addr { + uint8_t status; + bt_addr_t bdaddr; +} __packed; + +#define BT_HCI_OP_READ_ENCRYPTION_KEY_SIZE BT_OP(BT_OGF_STATUS, 0x0008) +struct bt_hci_cp_read_encryption_key_size { + uint16_t handle; +} __packed; +struct bt_hci_rp_read_encryption_key_size { + uint8_t status; + uint16_t handle; + uint8_t key_size; +} __packed; + +/* BLE */ + +#define BT_HCI_OP_LE_SET_EVENT_MASK BT_OP(BT_OGF_LE, 0x0001) +struct bt_hci_cp_le_set_event_mask { + uint8_t events[8]; +} __packed; + +#define BT_HCI_OP_LE_READ_BUFFER_SIZE BT_OP(BT_OGF_LE, 0x0002) +struct bt_hci_rp_le_read_buffer_size { + uint8_t status; + uint16_t le_max_len; + uint8_t le_max_num; +} __packed; + +#define BT_HCI_OP_LE_READ_LOCAL_FEATURES BT_OP(BT_OGF_LE, 0x0003) +struct bt_hci_rp_le_read_local_features { + uint8_t status; + uint8_t features[8]; +} __packed; + +#define BT_HCI_OP_LE_SET_RANDOM_ADDRESS BT_OP(BT_OGF_LE, 0x0005) +struct bt_hci_cp_le_set_random_address { + bt_addr_t bdaddr; +} __packed; + +/* Advertising types */ +#define BT_LE_ADV_IND 0x00 +#define BT_LE_ADV_DIRECT_IND 0x01 +#define BT_LE_ADV_SCAN_IND 0x02 +#define BT_LE_ADV_NONCONN_IND 0x03 +#define BT_LE_ADV_DIRECT_IND_LOW_DUTY 0x04 +/* Needed in advertising reports when getting info about */ +#define BT_LE_ADV_SCAN_RSP 0x04 + +#define BT_HCI_OP_LE_SET_ADV_PARAM BT_OP(BT_OGF_LE, 0x0006) +struct bt_hci_cp_le_set_adv_param { + uint16_t min_interval; + uint16_t max_interval; + uint8_t type; + uint8_t own_addr_type; + bt_addr_le_t direct_addr; + uint8_t channel_map; + uint8_t filter_policy; +} __packed; + +#define BT_HCI_OP_LE_READ_ADV_CH_TX_POWER BT_OP(BT_OGF_LE, 0x0007) +struct bt_hci_rp_le_read_ch_tx_power { + uint8_t status; + int8_t tx_power_level; +} __packed; + +#define BT_HCI_OP_LE_SET_ADV_DATA BT_OP(BT_OGF_LE, 0x0008) +struct bt_hci_cp_le_set_adv_data { + uint8_t len; + uint8_t data[31]; +} __packed; + +#define BT_HCI_OP_LE_SET_SCAN_RSP_DATA BT_OP(BT_OGF_LE, 0x0009) +struct bt_hci_cp_le_set_scan_rsp_data { + uint8_t len; + uint8_t data[31]; +} __packed; + +#define BT_HCI_LE_ADV_DISABLE 0x00 +#define BT_HCI_LE_ADV_ENABLE 0x01 + +#define BT_HCI_OP_LE_SET_ADV_ENABLE BT_OP(BT_OGF_LE, 0x000a) +struct bt_hci_cp_le_set_adv_enable { + uint8_t enable; +} __packed; + +/* Scan types */ +#define BT_HCI_OP_LE_SET_SCAN_PARAMS BT_OP(BT_OGF_LE, 0x000b) +#define BT_HCI_LE_SCAN_PASSIVE 0x00 +#define BT_HCI_LE_SCAN_ACTIVE 0x01 + +struct bt_hci_cp_le_set_scan_params { + uint8_t scan_type; + uint16_t interval; + uint16_t window; + uint8_t addr_type; + uint8_t filter_policy; +} __packed; + +#define BT_HCI_OP_LE_SET_SCAN_ENABLE BT_OP(BT_OGF_LE, 0x000c) + +#define BT_HCI_LE_SCAN_DISABLE 0x00 +#define BT_HCI_LE_SCAN_ENABLE 0x01 + +#define BT_HCI_LE_SCAN_FILTER_DUP_DISABLE 0x00 +#define BT_HCI_LE_SCAN_FILTER_DUP_ENABLE 0x01 + +struct bt_hci_cp_le_set_scan_enable { + uint8_t enable; + uint8_t filter_dup; +} __packed; + +#define BT_HCI_OP_LE_CREATE_CONN BT_OP(BT_OGF_LE, 0x000d) +struct bt_hci_cp_le_create_conn { + uint16_t scan_interval; + uint16_t scan_window; + uint8_t filter_policy; + bt_addr_le_t peer_addr; + uint8_t own_addr_type; + uint16_t conn_interval_min; + uint16_t conn_interval_max; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint16_t min_ce_len; + uint16_t max_ce_len; +} __packed; + +#define BT_HCI_OP_LE_CREATE_CONN_CANCEL BT_OP(BT_OGF_LE, 0x000e) + +#define BT_HCI_OP_LE_READ_WL_SIZE BT_OP(BT_OGF_LE, 0x000f) +struct bt_hci_rp_le_read_wl_size { + uint8_t status; + uint8_t wl_size; +} __packed; + +#define BT_HCI_OP_LE_CLEAR_WL BT_OP(BT_OGF_LE, 0x0010) + +#define BT_HCI_OP_LE_ADD_DEV_TO_WL BT_OP(BT_OGF_LE, 0x0011) +struct bt_hci_cp_le_add_dev_to_wl { + bt_addr_le_t addr; +} __packed; + +#define BT_HCI_OP_LE_REM_DEV_FROM_WL BT_OP(BT_OGF_LE, 0x0012) +struct bt_hci_cp_le_rem_dev_from_wl { + bt_addr_le_t addr; +} __packed; + +#define BT_HCI_OP_LE_CONN_UPDATE BT_OP(BT_OGF_LE, 0x0013) +struct hci_cp_le_conn_update { + uint16_t handle; + uint16_t conn_interval_min; + uint16_t conn_interval_max; + uint16_t conn_latency; + uint16_t supervision_timeout; + uint16_t min_ce_len; + uint16_t max_ce_len; +} __packed; + +#define BT_HCI_OP_LE_SET_HOST_CH_CLASSIF BT_OP(BT_OGF_LE, 0x0014) +struct bt_hci_cp_le_set_host_ch_classif { + uint8_t ch_map[5]; +} __packed; + +#define BT_HCI_OP_LE_READ_CH_MAP BT_OP(BT_OGF_LE, 0x0015) +struct bt_hci_cp_le_read_ch_map { + uint16_t handle; +} __packed; +struct bt_hci_rp_le_read_ch_map { + uint8_t status; + uint16_t handle; + uint8_t ch_map[5]; +} __packed; + +#define BT_HCI_OP_LE_READ_REMOTE_FEATURES BT_OP(BT_OGF_LE, 0x0016) +struct bt_hci_cp_le_read_remote_features { + uint16_t handle; +} __packed; + +#define BT_HCI_OP_LE_ENCRYPT BT_OP(BT_OGF_LE, 0x0017) +struct bt_hci_cp_le_encrypt { + uint8_t key[16]; + uint8_t plaintext[16]; +} __packed; +struct bt_hci_rp_le_encrypt { + uint8_t status; + uint8_t enc_data[16]; +} __packed; + +#define BT_HCI_OP_LE_RAND BT_OP(BT_OGF_LE, 0x0018) +struct bt_hci_rp_le_rand { + uint8_t status; + uint8_t rand[8]; +} __packed; + +#define BT_HCI_OP_LE_START_ENCRYPTION BT_OP(BT_OGF_LE, 0x0019) +struct bt_hci_cp_le_start_encryption { + uint16_t handle; + uint64_t rand; + uint16_t ediv; + uint8_t ltk[16]; +} __packed; + +#define BT_HCI_OP_LE_LTK_REQ_REPLY BT_OP(BT_OGF_LE, 0x001a) +struct bt_hci_cp_le_ltk_req_reply { + uint16_t handle; + uint8_t ltk[16]; +} __packed; +struct bt_hci_rp_le_ltk_req_reply { + uint8_t status; + uint16_t handle; +} __packed; + +#define BT_HCI_OP_LE_LTK_REQ_NEG_REPLY BT_OP(BT_OGF_LE, 0x001b) +struct bt_hci_cp_le_ltk_req_neg_reply { + uint16_t handle; +} __packed; +struct bt_hci_rp_le_ltk_req_neg_reply { + uint8_t status; + uint16_t handle; +} __packed; + +#define BT_HCI_OP_LE_READ_SUPP_STATES BT_OP(BT_OGF_LE, 0x001c) +struct bt_hci_rp_le_read_supp_states { + uint8_t status; + uint8_t le_states[8]; +} __packed; + +#define BT_HCI_OP_LE_RX_TEST BT_OP(BT_OGF_LE, 0x001d) +struct bt_hci_cp_le_rx_test { + uint8_t rx_ch; +} __packed; + +#define BT_HCI_OP_LE_TX_TEST BT_OP(BT_OGF_LE, 0x001e) +struct bt_hci_cp_le_tx_test { + uint8_t tx_ch; + uint8_t test_data_len; + uint8_t pkt_payload; +} __packed; + +#define BT_HCI_OP_LE_TEST_END BT_OP(BT_OGF_LE, 0x001f) +struct bt_hci_rp_le_test_end { + uint8_t status; + uint16_t rx_pkt_count; +} __packed; + +#define BT_HCI_OP_LE_CONN_PARAM_REQ_REPLY BT_OP(BT_OGF_LE, 0x0020) +struct bt_hci_cp_le_conn_param_req_reply { + uint16_t handle; + uint16_t interval_min; + uint16_t interval_max; + uint16_t latency; + uint16_t timeout; + uint16_t min_ce_len; + uint16_t max_ce_len; +} __packed; +struct bt_hci_rp_le_conn_param_req_reply { + uint8_t status; + uint16_t handle; +} __packed; + +#define BT_HCI_OP_LE_CONN_PARAM_REQ_NEG_REPLY BT_OP(BT_OGF_LE, 0x0021) +struct bt_hci_cp_le_conn_param_req_neg_reply { + uint16_t handle; + uint8_t reason; +} __packed; +struct bt_hci_rp_le_conn_param_req_neg_reply { + uint8_t status; + uint16_t handle; +} __packed; + +#define BT_HCI_OP_LE_SET_DATA_LEN BT_OP(BT_OGF_LE, 0x0022) +struct bt_hci_cp_le_set_data_len { + uint16_t handle; + uint16_t tx_octets; + uint16_t tx_time; +} __packed; +struct bt_hci_rp_le_set_data_len { + uint8_t status; + uint16_t handle; +} __packed; + +#define BT_HCI_OP_LE_READ_DEFAULT_DATA_LEN BT_OP(BT_OGF_LE, 0x0023) +struct bt_hci_rp_le_read_default_data_len { + uint8_t status; + uint16_t max_tx_octets; + uint16_t max_tx_time; +} __packed; + +#define BT_HCI_OP_LE_WRITE_DEFAULT_DATA_LEN BT_OP(BT_OGF_LE, 0x0024) +struct bt_hci_cp_le_write_default_data_len { + uint16_t max_tx_octets; + uint16_t max_tx_time; +} __packed; + +#define BT_HCI_OP_LE_P256_PUBLIC_KEY BT_OP(BT_OGF_LE, 0x0025) + +#define BT_HCI_OP_LE_GENERATE_DHKEY BT_OP(BT_OGF_LE, 0x0026) +struct bt_hci_cp_le_generate_dhkey { + uint8_t key[64]; +} __packed; + +#define BT_HCI_OP_LE_ADD_DEV_TO_RL BT_OP(BT_OGF_LE, 0x0027) +struct bt_hci_cp_le_add_dev_to_rl { + bt_addr_le_t peer_id_addr; + uint8_t peer_irk[16]; + uint8_t local_irk[16]; +} __packed; + +#define BT_HCI_OP_LE_REM_DEV_FROM_RL BT_OP(BT_OGF_LE, 0x0028) +struct bt_hci_cp_le_rem_dev_from_rl { + bt_addr_le_t peer_id_addr; +} __packed; + +#define BT_HCI_OP_LE_CLEAR_RL BT_OP(BT_OGF_LE, 0x0029) + +#define BT_HCI_OP_LE_READ_RL_SIZE BT_OP(BT_OGF_LE, 0x002a) +struct bt_hci_rp_le_read_rl_size { + uint8_t status; + uint8_t rl_size; +} __packed; + +#define BT_HCI_OP_LE_READ_PEER_RPA BT_OP(BT_OGF_LE, 0x002b) +struct bt_hci_cp_le_read_peer_rpa { + bt_addr_le_t peer_id_addr; +} __packed; +struct bt_hci_rp_le_read_peer_rpa { + uint8_t status; + bt_addr_t peer_rpa; +} __packed; + +#define BT_HCI_OP_LE_READ_LOCAL_RPA BT_OP(BT_OGF_LE, 0x002c) +struct bt_hci_cp_le_read_local_rpa { + bt_addr_le_t peer_id_addr; +} __packed; +struct bt_hci_rp_le_read_local_rpa { + uint8_t status; + bt_addr_t local_rpa; +} __packed; + +#define BT_HCI_ADDR_RES_DISABLE 0x00 +#define BT_HCI_ADDR_RES_ENABLE 0x01 + +#define BT_HCI_OP_LE_SET_ADDR_RES_ENABLE BT_OP(BT_OGF_LE, 0x002d) +struct bt_hci_cp_le_set_addr_res_enable { + uint8_t enable; +} __packed; + +#define BT_HCI_OP_LE_SET_RPA_TIMEOUT BT_OP(BT_OGF_LE, 0x002e) +struct bt_hci_cp_le_set_rpa_timeout { + uint8_t rpa_timeout; +} __packed; + +#define BT_HCI_OP_LE_READ_MAX_DATA_LEN BT_OP(BT_OGF_LE, 0x002f) +struct bt_hci_rp_le_read_max_data_len { + uint8_t status; + uint16_t max_tx_octets; + uint16_t max_tx_time; + uint16_t max_rx_octets; + uint16_t max_rx_time; +} __packed; + +/* Event definitions */ + +#define BT_HCI_EVT_VENDOR 0xff + +#define BT_HCI_EVT_INQUIRY_COMPLETE 0x01 +struct bt_hci_evt_inquiry_complete { + uint8_t status; +} __packed; + +#define BT_HCI_EVT_CONN_COMPLETE 0x03 +struct bt_hci_evt_conn_complete { + uint8_t status; + uint16_t handle; + bt_addr_t bdaddr; + uint8_t link_type; + uint8_t encr_enabled; +} __packed; + +#define BT_HCI_EVT_CONN_REQUEST 0x04 +struct bt_hci_evt_conn_request { + bt_addr_t bdaddr; + uint8_t dev_class[3]; + uint8_t link_type; +} __packed; + +#define BT_HCI_EVT_DISCONN_COMPLETE 0x05 +struct bt_hci_evt_disconn_complete { + uint8_t status; + uint16_t handle; + uint8_t reason; +} __packed; + +#define BT_HCI_EVT_AUTH_COMPLETE 0x06 +struct bt_hci_evt_auth_complete { + uint8_t status; + uint16_t handle; +} __packed; + +#define BT_HCI_EVT_REMOTE_NAME_REQ_COMPLETE 0x07 +struct bt_hci_evt_remote_name_req_complete { + uint8_t status; + bt_addr_t bdaddr; + uint8_t name[248]; +} __packed; + +#define BT_HCI_EVT_ENCRYPT_CHANGE 0x08 +struct bt_hci_evt_encrypt_change { + uint8_t status; + uint16_t handle; + uint8_t encrypt; +} __packed; + +#define BT_HCI_EVT_REMOTE_FEATURES 0x0b +struct bt_hci_evt_remote_features { + uint8_t status; + uint16_t handle; + uint8_t features[8]; +} __packed; + +#define BT_HCI_EVT_REMOTE_VERSION_INFO 0x0c +struct bt_hci_evt_remote_version_info { + uint8_t status; + uint16_t handle; + uint8_t version; + uint16_t manufacturer; + uint8_t subversion; +} __packed; + +#define BT_HCI_EVT_CMD_COMPLETE 0x0e +struct bt_hci_evt_cmd_complete { + uint8_t ncmd; + uint16_t opcode; +} __packed; + +struct bt_hci_evt_cc_status { + uint8_t status; +} __packed; + +#define BT_HCI_EVT_CMD_STATUS 0x0f +struct bt_hci_evt_cmd_status { + uint8_t status; + uint8_t ncmd; + uint16_t opcode; +} __packed; + +#define BT_HCI_EVT_ROLE_CHANGE 0x12 +struct bt_hci_evt_role_change { + uint8_t status; + bt_addr_t bdaddr; + uint8_t role; +} __packed; + +#define BT_HCI_EVT_NUM_COMPLETED_PACKETS 0x13 +struct bt_hci_evt_num_completed_packets { + uint8_t num_handles; + struct bt_hci_handle_count h[0]; +} __packed; + +#define BT_HCI_EVT_PIN_CODE_REQ 0x16 +struct bt_hci_evt_pin_code_req { + bt_addr_t bdaddr; +} __packed; + +#define BT_HCI_EVT_LINK_KEY_REQ 0x17 +struct bt_hci_evt_link_key_req { + bt_addr_t bdaddr; +} __packed; + +/* Link Key types */ +#define BT_LK_COMBINATION 0x00 +#define BT_LK_LOCAL_UNIT 0x01 +#define BT_LK_REMOTE_UNIT 0x02 +#define BT_LK_DEBUG_COMBINATION 0x03 +#define BT_LK_UNAUTH_COMBINATION_P192 0x04 +#define BT_LK_AUTH_COMBINATION_P192 0x05 +#define BT_LK_CHANGED_COMBINATION 0x06 +#define BT_LK_UNAUTH_COMBINATION_P256 0x07 +#define BT_LK_AUTH_COMBINATION_P256 0x08 + +#define BT_HCI_EVT_LINK_KEY_NOTIFY 0x18 +struct bt_hci_ev_link_key_notify { + bt_addr_t bdaddr; + uint8_t link_key[16]; + uint8_t key_type; +} __packed; + +#define BT_HCI_EVT_INQUIRY_RESULT_WITH_RSSI 0x22 +struct bt_hci_evt_inquiry_result_with_rssi { + bt_addr_t addr; + uint8_t pscan_rep_mode; + uint8_t reserved; + uint8_t cod[3]; + uint16_t clock_offset; + int8_t rssi; +} __packed; + +#define BT_HCI_EVT_REMOTE_EXT_FEATURES 0x23 +struct bt_hci_evt_remote_ext_features { + uint8_t status; + uint16_t handle; + uint8_t page; + uint8_t max_page; + uint8_t features[8]; +} __packed; + +#define BT_HCI_EVT_EXTENDED_INQUIRY_RESULT 0x2f +struct bt_hci_evt_extended_inquiry_result { + uint8_t num_reports; + bt_addr_t addr; + uint8_t pscan_rep_mode; + uint8_t reserved; + uint8_t cod[3]; + uint16_t clock_offset; + int8_t rssi; + uint8_t eir[240]; +} __packed; + +#define BT_HCI_EVT_ENCRYPT_KEY_REFRESH_COMPLETE 0x30 +struct bt_hci_evt_encrypt_key_refresh_complete { + uint8_t status; + uint16_t handle; +} __packed; + +#define BT_HCI_EVT_IO_CAPA_REQ 0x31 +struct bt_hci_evt_io_capa_req { + bt_addr_t bdaddr; +} __packed; + +#define BT_HCI_EVT_IO_CAPA_RESP 0x32 +struct bt_hci_evt_io_capa_resp { + bt_addr_t bdaddr; + uint8_t capability; + uint8_t oob_data; + uint8_t authentication; +} __packed; + +#define BT_HCI_EVT_USER_CONFIRM_REQ 0x33 +struct bt_hci_evt_user_confirm_req { + bt_addr_t bdaddr; + uint32_t passkey; +} __packed; + +#define BT_HCI_EVT_USER_PASSKEY_REQ 0x34 +struct bt_hci_evt_user_passkey_req { + bt_addr_t bdaddr; +} __packed; + +#define BT_HCI_EVT_SSP_COMPLETE 0x36 +struct bt_hci_evt_ssp_complete { + uint8_t status; + bt_addr_t bdaddr; +} __packed; + +#define BT_HCI_EVT_USER_PASSKEY_NOTIFY 0x3b +struct bt_hci_evt_user_passkey_notify { + bt_addr_t bdaddr; + uint32_t passkey; +} __packed; + +#define BT_HCI_EVT_LE_META_EVENT 0x3e +struct bt_hci_evt_le_meta_event { + uint8_t subevent; +} __packed; + +#define BT_HCI_EVT_AUTH_PAYLOAD_TIMEOUT_EXP 0x57 +struct bt_hci_evt_auth_payload_timeout_exp { + uint16_t handle; +} __packed; + +#define BT_HCI_ROLE_MASTER 0x00 +#define BT_HCI_ROLE_SLAVE 0x01 + +#define BT_HCI_EVT_LE_CONN_COMPLETE 0x01 +struct bt_hci_evt_le_conn_complete { + uint8_t status; + uint16_t handle; + uint8_t role; + bt_addr_le_t peer_addr; + uint16_t interval; + uint16_t latency; + uint16_t supv_timeout; + uint8_t clock_accuracy; +} __packed; + +#define BT_HCI_EVT_LE_ADVERTISING_REPORT 0x02 +struct bt_hci_ev_le_advertising_info { + uint8_t evt_type; + bt_addr_le_t addr; + uint8_t length; + uint8_t data[0]; +} __packed; +struct bt_hci_ev_le_advertising_report { + uint8_t num_reports; + struct bt_hci_ev_le_advertising_info adv_info[0]; +} __packed; + +#define BT_HCI_EVT_LE_CONN_UPDATE_COMPLETE 0x03 +struct bt_hci_evt_le_conn_update_complete { + uint8_t status; + uint16_t handle; + uint16_t interval; + uint16_t latency; + uint16_t supv_timeout; +} __packed; + +#define BT_HCI_EV_LE_REMOTE_FEAT_COMPLETE 0x04 +struct bt_hci_ev_le_remote_feat_complete { + uint8_t status; + uint16_t handle; + uint8_t features[8]; +} __packed; + +#define BT_HCI_EVT_LE_LTK_REQUEST 0x05 +struct bt_hci_evt_le_ltk_request { + uint16_t handle; + uint64_t rand; + uint16_t ediv; +} __packed; + +#define BT_HCI_EVT_LE_CONN_PARAM_REQ 0x06 +struct bt_hci_evt_le_conn_param_req { + uint16_t handle; + uint16_t interval_min; + uint16_t interval_max; + uint16_t latency; + uint16_t timeout; +} __packed; + +#define BT_HCI_EVT_LE_DATA_LEN_CHANGE 0x07 +struct bt_hci_evt_le_data_len_change { + uint16_t handle; + uint16_t max_tx_octets; + uint16_t max_tx_time; + uint16_t max_rx_octets; + uint16_t max_rx_time; +} __packed; + +#define BT_HCI_EVT_LE_P256_PUBLIC_KEY_COMPLETE 0x08 +struct bt_hci_evt_le_p256_public_key_complete { + uint8_t status; + uint8_t key[64]; +} __packed; + +#define BT_HCI_EVT_LE_GENERATE_DHKEY_COMPLETE 0x09 +struct bt_hci_evt_le_generate_dhkey_complete { + uint8_t status; + uint8_t dhkey[32]; +} __packed; + +#define BT_HCI_EVT_LE_ENH_CONN_COMPLETE 0x0a +struct bt_hci_evt_le_enh_conn_complete { + uint8_t status; + uint16_t handle; + uint8_t role; + bt_addr_le_t peer_addr; + bt_addr_t local_rpa; + bt_addr_t peer_rpa; + uint16_t interval; + uint16_t latency; + uint16_t supv_timeout; + uint8_t clock_accuracy; +} __packed; + +#define BT_HCI_EVT_LE_DIRECT_ADV_REPORT 0x0b +struct bt_hci_ev_le_direct_adv_info { + uint8_t evt_type; + bt_addr_le_t dir_addr; + bt_addr_le_t addr; + int8_t rssi; +} __packed; +struct bt_hci_ev_le_direct_adv_report { + uint8_t num_reports; + struct bt_hci_ev_le_direct_adv_info direct_adv_info[0]; +} __packed; + +#ifdef __cplusplus +} +#endif + +#endif /* __BT_HCI_H */ diff --git a/kernel/protocols/bluetooth/include/bluetooth/hci_raw.h b/kernel/protocols/bluetooth/include/bluetooth/hci_raw.h new file mode 100644 index 0000000000..6b51981e52 --- /dev/null +++ b/kernel/protocols/bluetooth/include/bluetooth/hci_raw.h @@ -0,0 +1,54 @@ +/** @file + * @brief Bluetooth HCI RAW channel handling + */ + +/* + * Copyright (c) 2016 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef __BT_HCI_RAW_H +#define __BT_HCI_RAW_H + +/** + * @brief HCI RAW channel + * @defgroup hci_raw HCI RAW channel + * @ingroup bluetooth + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief Send packet to the Bluetooth controller + * + * Send packet to the Bluetooth controller. Caller needs to + * implement netbuf pool. + * + * @param buf netbuf packet to be send + * + * @return Zero on success or (negative) error code otherwise. + */ +int bt_send(struct net_buf *buf); + +/** @brief Enable Bluetooth RAW channel + * + * Enable Bluetooth RAW HCI channel. + * + * @param rx_queue netbuf queue where HCI packets received from the Bluetooth + * controller are to be queued. The queue is defined in the caller while + * the available buffers pools are handled in the stack. + * + * @return Zero on success or (negative) error code otherwise. + */ +int bt_enable_raw(struct k_fifo *rx_queue); + +#ifdef __cplusplus +} +#endif +/** + * @} + */ + +#endif /* __BT_HCI_RAW_H */ diff --git a/kernel/protocols/bluetooth/include/bluetooth/l2cap.h b/kernel/protocols/bluetooth/include/bluetooth/l2cap.h new file mode 100644 index 0000000000..343a13f5be --- /dev/null +++ b/kernel/protocols/bluetooth/include/bluetooth/l2cap.h @@ -0,0 +1,316 @@ +/** @file + * @brief Bluetooth L2CAP handling + */ + +/* + * Copyright (c) 2015-2016 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef __BT_L2CAP_H +#define __BT_L2CAP_H + +/** + * @brief L2CAP + * @defgroup bt_l2cap L2CAP + * @ingroup bluetooth + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include + +/* L2CAP header size, used for buffer size calculations */ +#define BT_L2CAP_HDR_SIZE 4 + +/** @def BT_L2CAP_BUF_SIZE + * + * Helper to calculate needed outgoing buffer size, useful e.g. for + * creating buffer pools. + * + * @param mtu Needed L2CAP MTU. + * + * @return Needed buffer size to match the requested L2CAP MTU. + */ +#define BT_L2CAP_BUF_SIZE(mtu) (CONFIG_BLUETOOTH_HCI_RESERVE + \ + BT_HCI_ACL_HDR_SIZE + BT_L2CAP_HDR_SIZE + \ + (mtu)) + +struct bt_l2cap_chan; + +/** @typedef bt_l2cap_chan_destroy_t + * @brief Channel destroy callback + * + * @param chan Channel object. + */ +typedef void (*bt_l2cap_chan_destroy_t)(struct bt_l2cap_chan *chan); + +/** @brief Life-span states of L2CAP CoC channel. Used only by internal APIs + * dealing with setting channel to proper state depending on operational + * context. + */ +typedef enum bt_l2cap_chan_state { + /** Channel disconnected */ + BT_L2CAP_DISCONNECTED, + /** Channel in connecting state */ + BT_L2CAP_CONNECT, + /** Channel in config state, BR/EDR specific */ + BT_L2CAP_CONFIG, + /** Channel ready for upper layer traffic on it */ + BT_L2CAP_CONNECTED, + /** Channel in disconnecting state */ + BT_L2CAP_DISCONNECT, +} __packed bt_l2cap_chan_state_t; + +/** @brief L2CAP Channel structure. */ +struct bt_l2cap_chan { + /** Channel connection reference */ + struct bt_conn *conn; + /** Channel operations reference */ + struct bt_l2cap_chan_ops *ops; + struct bt_l2cap_chan *_next; + bt_l2cap_chan_destroy_t destroy; + /* Response Timeout eXpired (RTX) timer */ + struct k_delayed_work rtx_work; +#if defined(CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL) + bt_l2cap_chan_state_t state; + /** Remote PSM to be connected */ + uint16_t psm; + /** Helps match request context during CoC */ + uint8_t ident; + bt_security_t required_sec_level; +#endif /* CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL */ +}; + +/** @brief LE L2CAP Endpoint structure. */ +struct bt_l2cap_le_endpoint { + /** Endpoint CID */ + uint16_t cid; + /** Endpoint Maximum Transmission Unit */ + uint16_t mtu; + /** Endpoint Maximum PDU payload Size */ + uint16_t mps; + /** Endpoint initial credits */ + uint16_t init_credits; + /** Endpoint credits */ + struct k_sem credits; +}; + +/** @brief LE L2CAP Channel structure. */ +struct bt_l2cap_le_chan { + /** Common L2CAP channel reference object */ + struct bt_l2cap_chan chan; + /** Channel Receiving Endpoint */ + struct bt_l2cap_le_endpoint rx; + /** Channel Transmission Endpoint */ + struct bt_l2cap_le_endpoint tx; + /** Channel Transmission queue */ + struct k_fifo tx_queue; + /** Channel Pending Transmission buffer */ + struct net_buf *tx_buf; + /** Segment SDU packet from upper layer */ + struct net_buf *_sdu; + uint16_t _sdu_len; +}; + +/** @def BT_L2CAP_LE_CHAN(_ch) + * @brief Helper macro getting container object of type bt_l2cap_le_chan + * address having the same container chan member address as object in question. + * + * @param _ch Address of object of bt_l2cap_chan type + * + * @return Address of in memory bt_l2cap_le_chan object type containing + * the address of in question object. + */ +#define BT_L2CAP_LE_CHAN(_ch) CONTAINER_OF(_ch, struct bt_l2cap_le_chan, chan) + +/** @brief BREDR L2CAP Endpoint structure. */ +struct bt_l2cap_br_endpoint { + /** Endpoint CID */ + uint16_t cid; + /** Endpoint Maximum Transmission Unit */ + uint16_t mtu; +}; + +/** @brief BREDR L2CAP Channel structure. */ +struct bt_l2cap_br_chan { + /** Common L2CAP channel reference object */ + struct bt_l2cap_chan chan; + /** Channel Receiving Endpoint */ + struct bt_l2cap_br_endpoint rx; + /** Channel Transmission Endpoint */ + struct bt_l2cap_br_endpoint tx; + /* For internal use only */ + atomic_t flags[1]; +}; + +/** @brief L2CAP Channel operations structure. */ +struct bt_l2cap_chan_ops { + /** Channel connected callback + * + * If this callback is provided it will be called whenever the + * connection completes. + * + * @param chan The channel that has been connected + */ + void (*connected)(struct bt_l2cap_chan *chan); + + /** Channel disconnected callback + * + * If this callback is provided it will be called whenever the + * channel is disconnected, including when a connection gets + * rejected. + * + * @param chan The channel that has been Disconnected + */ + void (*disconnected)(struct bt_l2cap_chan *chan); + + /** Channel encrypt_change callback + * + * If this callback is provided it will be called whenever the + * security level changed (indirectly link encryption done) or + * authentication procedure fails. In both cases security initiator + * and responder got the final status (HCI status) passed by + * related to encryption and authentication events from local host's + * controller. + * + * @param chan The channel which has made encryption status changed. + * @param status HCI status of performed security procedure caused + * by channel security requirements. The value is populated + * by HCI layer and set to 0 when success and to non-zero (reference to + * HCI Error Codes) when security/authentication failed. + */ + void (*encrypt_change)(struct bt_l2cap_chan *chan, uint8_t hci_status); + + /** Channel alloc_buf callback + * + * If this callback is provided the channel will use it to allocate + * buffers to store incoming data. + * + * @param chan The channel requesting a buffer. + * + * @return Allocated buffer. + */ + struct net_buf *(*alloc_buf)(struct bt_l2cap_chan *chan); + + /** Channel recv callback + * + * @param chan The channel receiving data. + * @param buf Buffer containing incoming data. + */ + void (*recv)(struct bt_l2cap_chan *chan, struct net_buf *buf); +}; + +/** @def BT_L2CAP_CHAN_SEND_RESERVE + * @brief Headroom needed for outgoing buffers + */ +#define BT_L2CAP_CHAN_SEND_RESERVE (CONFIG_BLUETOOTH_HCI_RESERVE + 4 + 4 + 2) + +/** @brief L2CAP Server structure. */ +struct bt_l2cap_server { + /** Server PSM */ + uint16_t psm; + + /** Required minimim security level */ + bt_security_t sec_level; + + /** Server accept callback + * + * This callback is called whenever a new incoming connection requires + * authorization. + * + * @param conn The connection that is requesting authorization + * @param chan Pointer to received the allocated channel + * + * @return 0 in case of success or negative value in case of error. + */ + int (*accept)(struct bt_conn *conn, struct bt_l2cap_chan **chan); + + struct bt_l2cap_server *_next; +}; + +/** @brief Register L2CAP server. + * + * Register L2CAP server for a PSM, each new connection is authorized using + * the accept() callback which in case of success shall allocate the channel + * structure to be used by the new connection. + * + * @param server Server structure. + * + * @return 0 in case of success or negative value in case of error. + */ +int bt_l2cap_server_register(struct bt_l2cap_server *server); + +/** @brief Register L2CAP server on BR/EDR oriented connection. + * + * Register L2CAP server for a PSM, each new connection is authorized using + * the accept() callback which in case of success shall allocate the channel + * structure to be used by the new connection. + * + * @param server Server structure. + * + * @return 0 in case of success or negative value in case of error. + */ +int bt_l2cap_br_server_register(struct bt_l2cap_server *server); + +/** @brief Connect L2CAP channel + * + * Connect L2CAP channel by PSM, once the connection is completed channel + * connected() callback will be called. If the connection is rejected + * disconnected() callback is called instead. + * Channel object passed (over an address of it) as second parameter shouldn't + * be instantiated in application as standalone. Instead of, application should + * create transport dedicated L2CAP objects, i.e. type of bt_l2cap_le_chan for + * LE and/or type of bt_l2cap_br_chan for BR/EDR. Then pass to this API + * the location (address) of bt_l2cap_chan type object which is a member + * of both transport dedicated objects. + * + * @param conn Connection object. + * @param chan Channel object. + * @param psm Channel PSM to connect to. + * + * @return 0 in case of success or negative value in case of error. + */ +int bt_l2cap_chan_connect(struct bt_conn *conn, struct bt_l2cap_chan *chan, + uint16_t psm); + +/** @brief Disconnect L2CAP channel + * + * Disconnect L2CAP channel, if the connection is pending it will be + * canceled and as a result the channel disconnected() callback is called. + * Regarding to input parameter, to get details see reference description + * to bt_l2cap_chan_connect() API above. + * + * @param chan Channel object. + * + * @return 0 in case of success or negative value in case of error. + */ +int bt_l2cap_chan_disconnect(struct bt_l2cap_chan *chan); + +/** @brief Send data to L2CAP channel + * + * Send data from buffer to the channel. This procedure may block waiting for + * credits to send data therefore it shall be used from a fiber to be able to + * receive credits when necessary. + * Regarding to first input parameter, to get details see reference description + * to bt_l2cap_chan_connect() API above. + * + * @return Bytes sent in case of success or negative value in case of error. + */ +int bt_l2cap_chan_send(struct bt_l2cap_chan *chan, struct net_buf *buf); + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* __BT_L2CAP_H */ diff --git a/kernel/protocols/bluetooth/include/bluetooth/log.h b/kernel/protocols/bluetooth/include/bluetooth/log.h new file mode 100644 index 0000000000..f5cc6ec954 --- /dev/null +++ b/kernel/protocols/bluetooth/include/bluetooth/log.h @@ -0,0 +1,89 @@ +/** @file + * @brief Bluetooth subsystem logging helpers. + */ + +/* + * Copyright (c) 2015-2016 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef __BT_LOG_H +#define __BT_LOG_H +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(BT_DBG_ENABLED) +#define BT_DBG_ENABLED 1 +#endif +#include + +#if defined(CONFIG_BLUETOOTH_DEBUG_MONITOR) +#include + +/* These defines follow the values used by syslog(2) */ +#define BT_LOG_ERR 3 +#define BT_LOG_WARN 4 +#define BT_LOG_INFO 6 +#define BT_LOG_DBG 7 + +__printf_like(2, 3) void bt_log(int prio, const char *fmt, ...); + +#define BT_DBG(fmt, ...) \ + if (BT_DBG_ENABLED) { \ + bt_log(BT_LOG_DBG, "%s (%p): " fmt, \ + __func__, k_current_get(), ##__VA_ARGS__); \ + } + +#define BT_ERR(fmt, ...) bt_log(BT_LOG_ERR, "%s: " fmt, \ + __func__, ##__VA_ARGS__) +#define BT_WARN(fmt, ...) bt_log(BT_LOG_WARN, "%s: " fmt, \ + __func__, ##__VA_ARGS__) +#define BT_INFO(fmt, ...) bt_log(BT_LOG_INFO, fmt, ##__VA_ARGS__) + +/* Enabling debug increases stack size requirement */ +#define BT_STACK_DEBUG_EXTRA 300 + +#elif defined(CONFIG_BLUETOOTH_DEBUG_LOG) + +#define SYS_LOG_DOMAIN "bt" +#define SYS_LOG_LEVEL SYS_LOG_LEVEL_DEBUG + +#define BT_DBG(fmt, ...) \ + if (BT_DBG_ENABLED) { \ + SYS_LOG_DBG(fmt, ##__VA_ARGS__);\ + } + +#define BT_ERR(fmt, ...) SYS_LOG_ERR(fmt, ##__VA_ARGS__) +#define BT_WARN(fmt, ...) SYS_LOG_WRN(fmt, ##__VA_ARGS__) +#define BT_INFO(fmt, ...) SYS_LOG_INF(fmt, ##__VA_ARGS__) + +/* Enabling debug increases stack size requirement considerably */ +#define BT_STACK_DEBUG_EXTRA 300 + +#else + +static inline __printf_like(1, 2) void _bt_log_dummy(const char *fmt, ...) {}; + +#define BT_DBG(fmt, ...) +#define BT_ERR BT_DBG +#define BT_WARN BT_DBG +#define BT_INFO BT_DBG + +#define BT_STACK_DEBUG_EXTRA 0 + +#endif + +#define BT_ASSERT(cond) if (!(cond)) { \ + BT_ERR("assert: '" #cond "' failed"); \ + } + + +/* This helper is only available when BLUETOOTH_DEBUG is enabled */ +const char *bt_hex(const void *buf, size_t len); + +#ifdef __cplusplus +} +#endif + +#endif /* __BT_LOG_H */ diff --git a/kernel/protocols/bluetooth/include/bluetooth/rfcomm.h b/kernel/protocols/bluetooth/include/bluetooth/rfcomm.h new file mode 100644 index 0000000000..3da79574a8 --- /dev/null +++ b/kernel/protocols/bluetooth/include/bluetooth/rfcomm.h @@ -0,0 +1,188 @@ +/** @file + * @brief Bluetooth RFCOMM handling + */ + +/* + * Copyright (c) 2015-2016 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef __BT_RFCOMM_H +#define __BT_RFCOMM_H + +/** + * @brief RFCOMM + * @defgroup bt_rfcomm RFCOMM + * @ingroup bluetooth + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +/* RFCOMM channels (1-30): pre-allocated for profiles to avoid conflicts */ +enum { + BT_RFCOMM_CHAN_HFP_HF = 1, + BT_RFCOMM_CHAN_HFP_AG, + BT_RFCOMM_CHAN_HSP_AG, + BT_RFCOMM_CHAN_HSP_HS, + BT_RFCOMM_CHAN_SPP, +}; + +struct bt_rfcomm_dlc; + +/** @brief RFCOMM DLC operations structure. */ +struct bt_rfcomm_dlc_ops { + /** DLC connected callback + * + * If this callback is provided it will be called whenever the + * connection completes. + * + * @param dlc The dlc that has been connected + */ + void (*connected)(struct bt_rfcomm_dlc *dlc); + + /** DLC disconnected callback + * + * If this callback is provided it will be called whenever the + * dlc is disconnected, including when a connection gets + * rejected or cancelled (both incoming and outgoing) + * + * @param dlc The dlc that has been Disconnected + */ + void (*disconnected)(struct bt_rfcomm_dlc *dlc); + + /** DLC recv callback + * + * @param dlc The dlc receiving data. + * @param buf Buffer containing incoming data. + */ + void (*recv)(struct bt_rfcomm_dlc *dlc, struct net_buf *buf); +}; + +/** @brief Role of RFCOMM session and dlc. Used only by internal APIs + */ +typedef enum bt_rfcomm_role { + BT_RFCOMM_ROLE_ACCEPTOR, + BT_RFCOMM_ROLE_INITIATOR +} __packed bt_rfcomm_role_t; + +/** @brief RFCOMM DLC structure. */ +struct bt_rfcomm_dlc { + /* Response Timeout eXpired (RTX) timer */ + struct k_delayed_work rtx_work; + + /* Queue for outgoing data */ + struct k_fifo tx_queue; + + /* TX credits, Reuse as a binary sem for MSC FC if CFC is not enabled */ + struct k_sem tx_credits; + + struct bt_rfcomm_session *session; + struct bt_rfcomm_dlc_ops *ops; + struct bt_rfcomm_dlc *_next; + + bt_security_t required_sec_level; + bt_rfcomm_role_t role; + + uint16_t mtu; + uint8_t dlci; + uint8_t state; + uint8_t rx_credit; + + /* Stack for TX fiber */ + BT_STACK(stack, 256); +}; + +struct bt_rfcomm_server { + /** Server Channel */ + uint8_t channel; + + /** Server accept callback + * + * This callback is called whenever a new incoming connection requires + * authorization. + * + * @param conn The connection that is requesting authorization + * @param dlc Pointer to received the allocated dlc + * + * @return 0 in case of success or negative value in case of error. + */ + int (*accept)(struct bt_conn *conn, struct bt_rfcomm_dlc **dlc); + + struct bt_rfcomm_server *_next; +}; + +/** @brief Register RFCOMM server + * + * Register RFCOMM server for a channel, each new connection is authorized + * using the accept() callback which in case of success shall allocate the dlc + * structure to be used by the new connection. + * + * @param server Server structure. + * + * @return 0 in case of success or negative value in case of error. + */ +int bt_rfcomm_server_register(struct bt_rfcomm_server *server); + +/** @brief Connect RFCOMM channel + * + * Connect RFCOMM dlc by channel, once the connection is completed dlc + * connected() callback will be called. If the connection is rejected + * disconnected() callback is called instead. + * + * @param conn Connection object. + * @param dlc Dlc object. + * @param channel Server channel to connect to. + * + * @return 0 in case of success or negative value in case of error. + */ +int bt_rfcomm_dlc_connect(struct bt_conn *conn, struct bt_rfcomm_dlc *dlc, + uint8_t channel); + +/** @brief Send data to RFCOMM + * + * Send data from buffer to the dlc. Length should be less than or equal to + * mtu. + * + * @param dlc Dlc object. + * @param buf Data buffer. + * + * @return Bytes sent in case of success or negative value in case of error. + */ +int bt_rfcomm_dlc_send(struct bt_rfcomm_dlc *dlc, struct net_buf *buf); + +/** @brief Disconnect RFCOMM dlc + * + * Disconnect RFCOMM dlc, if the connection is pending it will be + * canceled and as a result the dlc disconnected() callback is called. + * + * @param dlc Dlc object. + * + * @return 0 in case of success or negative value in case of error. + */ +int bt_rfcomm_dlc_disconnect(struct bt_rfcomm_dlc *dlc); + +/** @brief Allocate the buffer from pool after reserving head room for RFCOMM, + * L2CAP and ACL headers. + * + * @param pool Which pool to take the buffer from. + * + * @return New buffer. + */ +struct net_buf *bt_rfcomm_create_pdu(struct net_buf_pool *pool); + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* __BT_RFCOMM_H */ diff --git a/kernel/protocols/bluetooth/include/bluetooth/storage.h b/kernel/protocols/bluetooth/include/bluetooth/storage.h new file mode 100644 index 0000000000..dd8c132585 --- /dev/null +++ b/kernel/protocols/bluetooth/include/bluetooth/storage.h @@ -0,0 +1,146 @@ +/** @file + * @brief Bluetooth subsystem persistent storage APIs. + */ + +/* + * Copyright (c) 2016 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef __BT_STORAGE_H +#define __BT_STORAGE_H + +/** + * @brief Persistent Storage + * @defgroup bt_storage Persistent Storage + * @ingroup bluetooth + * @{ + */ + +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** Well known storage keys */ +enum { + /** Identity Address. + * Type: bt_addr_le_t (7 bytes) + */ + BT_STORAGE_ID_ADDR, + + /** Local Identity Resolving Key. + * Type: uint8_t key[16] + */ + BT_STORAGE_LOCAL_IRK, + + /** List of addresses of remote devices. + * Type: bt_addr_le_t addrs[n] (length is variable). + * + * This is only used for reading. Modification of the list happens + * implicitly by writing entries for each remote device. This value + * is only used with the local storage, i.e. NULL as the target + * bt_addr_le_t passed to the read callback. + */ + BT_STORAGE_ADDRESSES, + + /** Slave Long Term Key for legacy pairing. + * Type: struct bt_storage_ltk + */ + BT_STORAGE_SLAVE_LTK, + + /** Long Term Key for legacy pairing. + * Type: struct bt_storage_ltk + */ + BT_STORAGE_LTK, + + /** Identity Resolving Key + * Type: uint8_t key[16] + */ + BT_STORAGE_IRK, +}; + +/** LTK key flags */ +enum { + /* Key has been generated with MITM protection */ + BT_STORAGE_LTK_AUTHENTICATED = BIT(0), + + /* Key has been generated using the LE Secure Connection pairing */ + BT_STORAGE_LTK_SC = BIT(1), +}; + +struct bt_storage_ltk { + uint8_t flags; + /* Encryption key size used to generate key */ + uint8_t size; + uint16_t ediv; + uint8_t rand[8]; + uint8_t val[16]; +}; + +struct bt_storage { + /** Read the value of a key from storage. + * + * @param addr Remote address or NULL for local storage + * @param key BT_STORAGE_* key to read + * @param data Memory location to place the data + * @param length Maximum number of bytes to read + * + * @return Number of bytes read or negative error value on + * failure. + */ + ssize_t (*read)(const bt_addr_le_t *addr, uint16_t key, + void *data, size_t length); + + /** Write the value of a key to storage. + * + * @param addr Remote address or NULL for local storage + * @param key BT_STORAGE_* key to write + * @param data Memory location of the data + * @param length Number of bytes to write + * + * @return Number of bytes written or negative error value on + * failure. + */ + ssize_t (*write)(const bt_addr_le_t *addr, uint16_t key, + const void *data, size_t length); + + /** Clear all keys for a specific address + * + * @param addr Remote address, BT_ADDR_LE_ANY for all + * remote devices, or NULL for local storage. + * + * @return 0 on success or negative error value on failure. + */ + int (*clear)(const bt_addr_le_t *addr); + +}; + +/** Register callbacks for storage handling. + * + * @param storage Callback struct. + */ +void bt_storage_register(const struct bt_storage *storage); + +/** Clear all storage keys for a specific address + * + * @param addr Remote address, NULL for local storage or + * BT_ADDR_LE_ANY to clear all remote devices. + * + * @return 0 on success or negative error value on failure. + */ +int bt_storage_clear(const bt_addr_le_t *addr); + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* __BT_STORAGE_H */ diff --git a/kernel/protocols/bluetooth/include/bluetooth/uuid.h b/kernel/protocols/bluetooth/include/bluetooth/uuid.h new file mode 100644 index 0000000000..56d7633d2c --- /dev/null +++ b/kernel/protocols/bluetooth/include/bluetooth/uuid.h @@ -0,0 +1,545 @@ +/** @file + * @brief Bluetooth UUID handling + */ + +/* + * Copyright (c) 2015-2016 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef __BT_UUID_H +#define __BT_UUID_H + +/** + * @brief UUIDs + * @defgroup bt_uuid UUIDs + * @ingroup bluetooth + * @{ + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** @brief Bluetooth UUID types */ +enum { + BT_UUID_TYPE_16, + BT_UUID_TYPE_32, + BT_UUID_TYPE_128, +}; + +/** @brief This is a 'tentative' type and should be used as a pointer only */ +struct bt_uuid { + uint8_t type; +}; + +struct bt_uuid_16 { + struct bt_uuid uuid; + uint16_t val; +}; + +struct bt_uuid_32 { + struct bt_uuid uuid; + uint32_t val; +}; + +struct bt_uuid_128 { + struct bt_uuid uuid; + uint8_t val[16]; +}; + +#define BT_UUID_INIT_16(value) \ +{ \ + .uuid.type = BT_UUID_TYPE_16, \ + .val = (value), \ +} + +#define BT_UUID_INIT_32(value) \ +{ \ + .uuid.type = BT_UUID_TYPE_32, \ + .val = (value), \ +} + +#define BT_UUID_INIT_128(value...) \ +{ \ + .uuid.type = BT_UUID_TYPE_128, \ + .val = { value }, \ +} + +#define BT_UUID_DECLARE_16(value) \ + ((struct bt_uuid *) (&(struct bt_uuid_16) BT_UUID_INIT_16(value))) +#define BT_UUID_DECLARE_32(value) \ + ((struct bt_uuid *) (&(struct bt_uuid_32) BT_UUID_INIT_32(value))) +#define BT_UUID_DECLARE_128(value...) \ + ((struct bt_uuid *) (&(struct bt_uuid_128) BT_UUID_INIT_128(value))) + +#define BT_UUID_16(__u) CONTAINER_OF(__u, struct bt_uuid_16, uuid) +#define BT_UUID_32(__u) CONTAINER_OF(__u, struct bt_uuid_32, uuid) +#define BT_UUID_128(__u) CONTAINER_OF(__u, struct bt_uuid_128, uuid) + +/** @def BT_UUID_GAP + * @brief Generic Access + */ +#define BT_UUID_GAP BT_UUID_DECLARE_16(0x1800) +#define BT_UUID_GAP_VAL 0x1800 +/** @def BT_UUID_GATT + * @brief Generic Attribute + */ +#define BT_UUID_GATT BT_UUID_DECLARE_16(0x1801) +#define BT_UUID_GATT_VAL 0x1801 +/** @def BT_UUID_CTS + * @brief Current Time Service + */ +#define BT_UUID_CTS BT_UUID_DECLARE_16(0x1805) +#define BT_UUID_CTS_VAL 0x1805 +/** @def BT_UUID_DIS + * @brief Device Information Service + */ +#define BT_UUID_DIS BT_UUID_DECLARE_16(0x180a) +#define BT_UUID_DIS_VAL 0x180a +/** @def BT_UUID_HRS + * @brief Heart Rate Service + */ +#define BT_UUID_HRS BT_UUID_DECLARE_16(0x180d) +#define BT_UUID_HRS_VAL 0x180d +/** @def BT_UUID_BAS + * @brief Battery Service + */ +#define BT_UUID_BAS BT_UUID_DECLARE_16(0x180f) +#define BT_UUID_BAS_VAL 0x180f +/** @def BT_UUID_HIDS + * @brief HID Service + */ +#define BT_UUID_HIDS BT_UUID_DECLARE_16(0x1812) +#define BT_UUID_HIDS_VAL 0x1812 +/** @def BT_UUID_CSC + * @brief Cycling Speed and Cadence Service + */ +#define BT_UUID_CSC BT_UUID_DECLARE_16(0x1816) +#define BT_UUID_CSC_VAL 0x1816 +/** @def BT_UUID_ESS + * @brief Environmental Sensing Service + */ +#define BT_UUID_ESS BT_UUID_DECLARE_16(0x181a) +#define BT_UUID_ESS_VAL 0x181a +/** @def BT_UUID_IPSS + * @brief IP Support Service + */ +#define BT_UUID_IPSS BT_UUID_DECLARE_16(0x1820) +#define BT_UUID_IPSS_VAL 0x1820 +/** @def BT_UUID_GATT_PRIMARY + * @brief GATT Primary Service + */ +#define BT_UUID_GATT_PRIMARY BT_UUID_DECLARE_16(0x2800) +#define BT_UUID_GATT_PRIMARY_VAL 0x2800 +/** @def BT_UUID_GATT_SECONDARY + * @brief GATT Secondary Service + */ +#define BT_UUID_GATT_SECONDARY BT_UUID_DECLARE_16(0x2801) +#define BT_UUID_GATT_SECONDARY_VAL 0x2801 +/** @def BT_UUID_GATT_INCLUDE + * @brief GATT Include Service + */ +#define BT_UUID_GATT_INCLUDE BT_UUID_DECLARE_16(0x2802) +#define BT_UUID_GATT_INCLUDE_VAL 0x2802 +/** @def BT_UUID_GATT_CHRC + * @brief GATT Characteristic + */ +#define BT_UUID_GATT_CHRC BT_UUID_DECLARE_16(0x2803) +#define BT_UUID_GATT_CHRC_VAL 0x2803 +/** @def BT_UUID_GATT_CEP + * @brief GATT Characteristic Extended Properties + */ +#define BT_UUID_GATT_CEP BT_UUID_DECLARE_16(0x2900) +#define BT_UUID_GATT_CEP_VAL 0x2900 +/** @def BT_UUID_GATT_CUD + * @brief GATT Characteristic User Description + */ +#define BT_UUID_GATT_CUD BT_UUID_DECLARE_16(0x2901) +#define BT_UUID_GATT_CUD_VAL 0x2901 +/** @def BT_UUID_GATT_CCC + * @brief GATT Client Characteristic Configuration + */ +#define BT_UUID_GATT_CCC BT_UUID_DECLARE_16(0x2902) +#define BT_UUID_GATT_CCC_VAL 0x2902 +/** @def BT_UUID_GATT_SCC + * @brief GATT Server Characteristic Configuration + */ +#define BT_UUID_GATT_SCC BT_UUID_DECLARE_16(0x2903) +#define BT_UUID_GATT_SCC_VAL 0x2903 +/** @def BT_UUID_GATT_CPF + * @brief GATT Characteristic Presentation Format + */ +#define BT_UUID_GATT_CPF BT_UUID_DECLARE_16(0x2904) +#define BT_UUID_GATT_CPF_VAL 0x2904 +/** @def BT_UUID_VALID_RANGE + * @brief Valid Range Descriptor + */ +#define BT_UUID_VALID_RANGE BT_UUID_DECLARE_16(0x2906) +#define BT_UUID_VALID_RANGE_VAL 0x2906 +/** @def BT_UUID_HIDS_EXT_REPORT + * @brief HID External Report Descriptor + */ +#define BT_UUID_HIDS_EXT_REPORT BT_UUID_DECLARE_16(0x2907) +#define BT_UUID_HIDS_EXT_REPORT_VAL 0x2907 +/** @def BT_UUID_HIDS_REPORT_REF + * @brief HID Report Reference Descriptor + */ +#define BT_UUID_HIDS_REPORT_REF BT_UUID_DECLARE_16(0x2908) +#define BT_UUID_HIDS_REPORT_REF_VAL 0x2908 +/** @def BT_UUID_ES_CONFIGURATION + * @brief Environmental Sensing Configuration Descriptor + */ +#define BT_UUID_ES_CONFIGURATION BT_UUID_DECLARE_16(0x290b) +#define BT_UUID_ES_CONFIGURATION_VAL 0x290b +/** @def BT_UUID_ES_MEASUREMENT + * @brief Environmental Sensing Measurement Descriptor + */ +#define BT_UUID_ES_MEASUREMENT BT_UUID_DECLARE_16(0x290c) +#define BT_UUID_ES_MEASUREMENT_VAL 0x290c +/** @def BT_UUID_ES_TRIGGER_SETTING + * @brief Environmental Sensing Trigger Setting Descriptor + */ +#define BT_UUID_ES_TRIGGER_SETTING BT_UUID_DECLARE_16(0x290d) +#define BT_UUID_ES_TRIGGER_SETTING_VAL 0x290d +/** @def BT_UUID_GAP_DEVICE_NAME + * @brief GAP Characteristic Device Name + */ +#define BT_UUID_GAP_DEVICE_NAME BT_UUID_DECLARE_16(0x2a00) +#define BT_UUID_GAP_DEVICE_NAME_VAL 0x2a00 +/** @def BT_UUID_GAP_APPEARANCE + * @brief GAP Characteristic Appearance + */ +#define BT_UUID_GAP_APPEARANCE BT_UUID_DECLARE_16(0x2a01) +#define BT_UUID_GAP_APPEARANCE_VAL 0x2a01 +/** @def BT_UUID_GAP_PPCP + * @brief GAP Characteristic Peripheral Preferred Connection Parameters + */ +#define BT_UUID_GAP_PPCP BT_UUID_DECLARE_16(0x2a04) +#define BT_UUID_GAP_PPCP_VAL 0x2a04 +/** @def BT_UUID_BAS_BATTERY_LEVEL + * @brief BAS Characteristic Battery Level + */ +#define BT_UUID_BAS_BATTERY_LEVEL BT_UUID_DECLARE_16(0x2a19) +#define BT_UUID_BAS_BATTERY_LEVEL_VAL 0x2a19 +/** @def BT_UUID_DIS_SYSTEM_ID + * @brief DIS Characteristic System ID + */ +#define BT_UUID_DIS_SYSTEM_ID BT_UUID_DECLARE_16(0x2a23) +#define BT_UUID_DIS_SYSTEM_ID_VAL 0x2a23 +/** @def BT_UUID_DIS_MODEL_NUMBER + * @brief DIS Characteristic Model Number String + */ +#define BT_UUID_DIS_MODEL_NUMBER BT_UUID_DECLARE_16(0x2a24) +#define BT_UUID_DIS_MODEL_NUMBER_VAL 0x2a24 +/** @def BT_UUID_DIS_SERIAL_NUMBER + * @brief DIS Characteristic Serial Number String + */ +#define BT_UUID_DIS_SERIAL_NUMBER BT_UUID_DECLARE_16(0x2a25) +#define BT_UUID_DIS_SERIAL_NUMBER_VAL 0x2a25 +/** @def BT_UUID_DIS_FIRMWARE_REVISION + * @brief DIS Characteristic Firmware Revision String + */ +#define BT_UUID_DIS_FIRMWARE_REVISION BT_UUID_DECLARE_16(0x2a26) +#define BT_UUID_DIS_FIRMWARE_REVISION_VAL 0x2a26 +/** @def BT_UUID_DIS_HARDWARE_REVISION + * @brief DIS Characteristic Hardware Revision String + */ +#define BT_UUID_DIS_HARDWARE_REVISION BT_UUID_DECLARE_16(0x2a27) +#define BT_UUID_DIS_HARDWARE_REVISION_VAL 0x2a27 +/** @def BT_UUID_DIS_SOFTWARE_REVISION + * @brief DIS Characteristic Software Revision String + */ +#define BT_UUID_DIS_SOFTWARE_REVISION BT_UUID_DECLARE_16(0x2a28) +#define BT_UUID_DIS_SOFTWARE_REVISION_VAL 0x2a28 +/** @def BT_UUID_DIS_MANUFACTURER_NAME + * @brief DIS Characteristic Manufacturer Name String + */ +#define BT_UUID_DIS_MANUFACTURER_NAME BT_UUID_DECLARE_16(0x2a29) +#define BT_UUID_DIS_MANUFACTURER_NAME_VAL 0x2a29 +/** @def BT_UUID_DIS_PNP_ID + * @brief DIS Characteristic PnP ID + */ +#define BT_UUID_DIS_PNP_ID BT_UUID_DECLARE_16(0x2a50) +#define BT_UUID_DIS_PNP_ID_VAL 0x2a50 +/** @def BT_UUID_CTS_CURRENT_TIME + * @brief CTS Characteristic Current Time + */ +#define BT_UUID_CTS_CURRENT_TIME BT_UUID_DECLARE_16(0x2a2b) +#define BT_UUID_CTS_CURRENT_TIME_VAL 0x2a2b +/** @def BT_UUID_MAGN_DECLINATION + * @brief Magnetic Declination Characteristic + */ +#define BT_UUID_MAGN_DECLINATION BT_UUID_DECLARE_16(0x2a2c) +#define BT_UUID_MAGN_DECLINATION_VAL 0x2a2c +/** @def BT_UUID_HRS_MEASUREMENT + * @brief HRS Characteristic Measurement Interval + */ +#define BT_UUID_HRS_MEASUREMENT BT_UUID_DECLARE_16(0x2a37) +#define BT_UUID_HRS_MEASUREMENT_VAL 0x2a37 +/** @def BT_UUID_HRS_BODY_SENSOR + * @brief HRS Characteristic Body Sensor Location + */ +#define BT_UUID_HRS_BODY_SENSOR BT_UUID_DECLARE_16(0x2a38) +#define BT_UUID_HRS_BODY_SENSOR_VAL 0x2a38 +/** @def BT_UUID_HRS_CONTROL_POINT + * @brief HRS Characteristic Control Point + */ +#define BT_UUID_HRS_CONTROL_POINT BT_UUID_DECLARE_16(0x2a39) +#define BT_UUID_HRS_CONTROL_POINT_VAL 0x2a39 +/** @def BT_UUID_HIDS_INFO + * @brief HID Information Characteristic + */ +#define BT_UUID_HIDS_INFO BT_UUID_DECLARE_16(0x2a4a) +#define BT_UUID_HIDS_INFO_VAL 0x2a4a +/** @def BT_UUID_HIDS_REPORT_MAP + * @brief HID Report Map Characteristic + */ +#define BT_UUID_HIDS_REPORT_MAP BT_UUID_DECLARE_16(0x2a4b) +#define BT_UUID_HIDS_REPORT_MAP_VAL 0x2a4b +/** @def BT_UUID_HIDS_CTRL_POINT + * @brief HID Control Point Characteristic + */ +#define BT_UUID_HIDS_CTRL_POINT BT_UUID_DECLARE_16(0x2a4c) +#define BT_UUID_HIDS_CTRL_POINT_VAL 0x2a4c +/** @def BT_UUID_HIDS_REPORT + * @brief HID Report Characteristic + */ +#define BT_UUID_HIDS_REPORT BT_UUID_DECLARE_16(0x2a4d) +#define BT_UUID_HIDS_REPORT_VAL 0x2a4d +/** @def BT_UUID_CSC_MEASUREMENT + * @brief CSC Measurement Characteristic + */ +#define BT_UUID_CSC_MEASUREMENT BT_UUID_DECLARE_16(0x2a5b) +#define BT_UUID_CSC_MEASUREMENT_VAL 0x2a5b +/** @def BT_UUID_CSC_FEATURE + * @brief CSC Feature Characteristic + */ +#define BT_UUID_CSC_FEATURE BT_UUID_DECLARE_16(0x2a5c) +#define BT_UUID_CSC_FEATURE_VAL 0x2a5c +/** @def BT_UUID_SENSOR_LOCATION + * @brief Sensor Location Characteristic + */ +#define BT_UUID_SENSOR_LOCATION BT_UUID_DECLARE_16(0x2a5d) +#define BT_UUID_SENSOR_LOCATION_VAL 0x2a5d +/** @def BT_UUID_SC_CONTROL_POINT + * @brief SC Control Point Characteristic + */ +#define BT_UUID_SC_CONTROL_POINT BT_UUID_DECLARE_16(0x2a55) +#define BT_UUID_SC_CONTROL_POINT_VAl 0x2a55 +/** @def BT_UUID_ELEVATION + * @brief Elevation Characteristic + */ +#define BT_UUID_ELEVATION BT_UUID_DECLARE_16(0x2a6c) +#define BT_UUID_ELEVATION_VAL 0x2a6c +/** @def BT_UUID_PRESSURE + * @brief Pressure Characteristic + */ +#define BT_UUID_PRESSURE BT_UUID_DECLARE_16(0x2a6d) +#define BT_UUID_PRESSURE_VAL 0x2a6d +/** @def BT_UUID_TEMPERATURE + * @brief Temperature Characteristic + */ +#define BT_UUID_TEMPERATURE BT_UUID_DECLARE_16(0x2a6e) +#define BT_UUID_TEMPERATURE_VAL 0x2a6e +/** @def BT_UUID_HUMIDITY + * @brief Humidity Characteristic + */ +#define BT_UUID_HUMIDITY BT_UUID_DECLARE_16(0x2a6f) +#define BT_UUID_HUMIDITY_VAL 0x2a6f +/** @def BT_UUID_TRUE_WIND_SPEED + * @brief True Wind Speed Characteristic + */ +#define BT_UUID_TRUE_WIND_SPEED BT_UUID_DECLARE_16(0x2a70) +#define BT_UUID_TRUE_WIND_SPEED_VAL 0x2a70 +/** @def BT_UUID_TRUE_WIND_DIR + * @brief True Wind Direction Characteristic + */ +#define BT_UUID_TRUE_WIND_DIR BT_UUID_DECLARE_16(0x2a71) +#define BT_UUID_TRUE_WIND_DIR_VAL 0x2a71 +/** @def BT_UUID_APPARENT_WIND_SPEED + * @brief Apparent Wind Speed Characteristic + */ +#define BT_UUID_APPARENT_WIND_SPEED BT_UUID_DECLARE_16(0x2a72) +#define BT_UUID_APPARENT_WIND_SPEED_VAL 0x2a72 +/** @def BT_UUID_APPARENT_WIND_DIR + * @brief Apparent Wind Direction Characteristic + */ +#define BT_UUID_APPARENT_WIND_DIR BT_UUID_DECLARE_16(0x2a73) +#define BT_UUID_APPARENT_WIND_DIR_VAL 0x2a73 +/** @def BT_UUID_GUST_FACTOR + * @brief Gust Factor Characteristic + */ +#define BT_UUID_GUST_FACTOR BT_UUID_DECLARE_16(0x2a74) +#define BT_UUID_GUST_FACTOR_VAL 0x2a74 +/** @def BT_UUID_POLLEN_CONCENTRATION + * @brief Pollen Concentration Characteristic + */ +#define BT_UUID_POLLEN_CONCENTRATION BT_UUID_DECLARE_16(0x2a75) +#define BT_UUID_POLLEN_CONCENTRATION_VAL 0x2a75 +/** @def BT_UUID_UV_INDEX + * @brief UV Index Characteristic + */ +#define BT_UUID_UV_INDEX BT_UUID_DECLARE_16(0x2a76) +#define BT_UUID_UV_INDEX_VAL 0x2a76 +/** @def BT_UUID_IRRADIANCE + * @brief Irradiance Characteristic + */ +#define BT_UUID_IRRADIANCE BT_UUID_DECLARE_16(0x2a77) +#define BT_UUID_IRRADIANCE_VAL 0x2a77 +/** @def BT_UUID_RAINFALL + * @brief Rainfall Characteristic + */ +#define BT_UUID_RAINFALL BT_UUID_DECLARE_16(0x2a78) +#define BT_UUID_RAINFALL_VAL 0x2a78 +/** @def BT_UUID_WIND_CHILL + * @brief Wind Chill Characteristic + */ +#define BT_UUID_WIND_CHILL BT_UUID_DECLARE_16(0x2a79) +#define BT_UUID_WIND_CHILL_VAL 0x2a79 +/** @def BT_UUID_HEAT_INDEX + * @brief Heat Index Characteristic + */ +#define BT_UUID_HEAT_INDEX BT_UUID_DECLARE_16(0x2a7a) +#define BT_UUID_HEAT_INDEX_VAL 0x2a7a +/** @def BT_UUID_DEW_POINT + * @brief Dew Point Characteristic + */ +#define BT_UUID_DEW_POINT BT_UUID_DECLARE_16(0x2a7b) +#define BT_UUID_DEW_POINT_VAL 0x2a7b +/** @def BT_UUID_DESC_VALUE_CHANGED + * @brief Descriptor Value Changed Characteristic + */ +#define BT_UUID_DESC_VALUE_CHANGED BT_UUID_DECLARE_16(0x2a7d) +#define BT_UUID_DESC_VALUE_CHANGED_VAL 0x2a7d +/** @def BT_UUID_MAGN_FLUX_DENSITY_2D + * @brief Magnetic Flux Density - 2D Characteristic + */ +#define BT_UUID_MAGN_FLUX_DENSITY_2D BT_UUID_DECLARE_16(0x2aa0) +#define BT_UUID_MAGN_FLUX_DENSITY_2D_VAL 0x2aa0 +/** @def BT_UUID_MAGN_FLUX_DENSITY_3D + * @brief Magnetic Flux Density - 3D Characteristic + */ +#define BT_UUID_MAGN_FLUX_DENSITY_3D BT_UUID_DECLARE_16(0x2aa1) +#define BT_UUID_MAGN_FLUX_DENSITY_3D_VAL 0x2aa1 +/** @def BT_UUID_BAR_PRESSURE_TREND + * @brief Barometric Pressure Trend Characteristic + */ +#define BT_UUID_BAR_PRESSURE_TREND BT_UUID_DECLARE_16(0x2aa3) +#define BT_UUID_BAR_PRESSURE_TREND_VAL 0x2aa3 + +/* + * Protocol UUIDs + */ +#define BT_UUID_SDP BT_UUID_DECLARE_16(0x0001) +#define BT_UUID_SDP_VAL 0x0001 +#define BT_UUID_UDP BT_UUID_DECLARE_16(0x0002) +#define BT_UUID_UDP_VAL 0x0002 +#define BT_UUID_RFCOMM BT_UUID_DECLARE_16(0x0003) +#define BT_UUID_RFCOMM_VAL 0x0003 +#define BT_UUID_TCP BT_UUID_DECLARE_16(0x0004) +#define BT_UUID_TCP_VAL 0x0004 +#define BT_UUID_TCS_BIN BT_UUID_DECLARE_16(0x0005) +#define BT_UUID_TCS_BIN_VAL 0x0005 +#define BT_UUID_TCS_AT BT_UUID_DECLARE_16(0x0006) +#define BT_UUID_TCS_AT_VAL 0x0006 +#define BT_UUID_ATT BT_UUID_DECLARE_16(0x0007) +#define BT_UUID_ATT_VAL 0x0007 +#define BT_UUID_OBEX BT_UUID_DECLARE_16(0x0008) +#define BT_UUID_OBEX_VAL 0x0008 +#define BT_UUID_IP BT_UUID_DECLARE_16(0x0009) +#define BT_UUID_IP_VAL 0x0009 +#define BT_UUID_FTP BT_UUID_DECLARE_16(0x000a) +#define BT_UUID_FTP_VAL 0x000a +#define BT_UUID_HTTP BT_UUID_DECLARE_16(0x000c) +#define BT_UUID_HTTP_VAL 0x000c +#define BT_UUID_BNEP BT_UUID_DECLARE_16(0x000f) +#define BT_UUID_BNEP_VAL 0x000f +#define BT_UUID_UPNP BT_UUID_DECLARE_16(0x0010) +#define BT_UUID_UPNP_VAL 0x0010 +#define BT_UUID_HIDP BT_UUID_DECLARE_16(0x0011) +#define BT_UUID_HIDP_VAL 0x0011 +#define BT_UUID_HCRP_CTRL BT_UUID_DECLARE_16(0x0012) +#define BT_UUID_HCRP_CTRL_VAL 0x0012 +#define BT_UUID_HCRP_DATA BT_UUID_DECLARE_16(0x0014) +#define BT_UUID_HCRP_DATA_VAL 0x0014 +#define BT_UUID_HCRP_NOTE BT_UUID_DECLARE_16(0x0016) +#define BT_UUID_HCRP_NOTE_VAL 0x0016 +#define BT_UUID_AVCTP BT_UUID_DECLARE_16(0x0017) +#define BT_UUID_AVCTP_VAL 0x0017 +#define BT_UUID_AVDTP BT_UUID_DECLARE_16(0x0019) +#define BT_UUID_AVDTP_VAL 0x0019 +#define BT_UUID_CMTP BT_UUID_DECLARE_16(0x001b) +#define BT_UUID_CMTP_VAL 0x001b +#define BT_UUID_UDI BT_UUID_DECLARE_16(0x001d) +#define BT_UUID_UDI_VAL 0x001d +#define BT_UUID_MCAP_CTRL BT_UUID_DECLARE_16(0x001e) +#define BT_UUID_MCAP_CTRL_VAL 0x001e +#define BT_UUID_MCAP_DATA BT_UUID_DECLARE_16(0x001f) +#define BT_UUID_MCAP_DATA_VAL 0x001f +#define BT_UUID_L2CAP BT_UUID_DECLARE_16(0x0100) +#define BT_UUID_L2CAP_VAL 0x0100 + + +/** @brief Compare Bluetooth UUIDs. + * + * Compares 2 Bluetooth UUIDs, if the types are different both UUIDs are + * first converted to 128 bits format before comparing. + * + * @param u1 First Bluetooth UUID to compare + * @param u2 Second Bluetooth UUID to compare + * + * @return negative value if @a u1 < @a u2, 0 if @a u1 == @a u2, else positive + */ +int bt_uuid_cmp(const struct bt_uuid *u1, const struct bt_uuid *u2); + +#if defined(CONFIG_BLUETOOTH_DEBUG) +/** @brief Convert Bluetooth UUID to string. + * + * Converts Bluetooth UUID to string. UUID has to be in 16 bits or 128 bits + * format. + * + * @param uuid Bluetooth UUID + * @param str pointer where to put converted string + * @param len length of str + * + * @return N/A + */ +void bt_uuid_to_str(const struct bt_uuid *uuid, char *str, size_t len); + +/** @brief Convert Bluetooth UUID to string in place. + * + * Converts Bluetooth UUID to string in place. UUID has to be in 16 bits or + * 128 bits format. + * + * @param uuid Bluetooth UUID + * + * @return String representation of the UUID given + */ +const char *bt_uuid_str(const struct bt_uuid *uuid); +#else +static inline void bt_uuid_to_str(const struct bt_uuid *uuid, char *str, + size_t len) +{ + if (len > 0) { + str[0] = '\0'; + } +} + +static inline const char *bt_uuid_str(const struct bt_uuid *uuid) +{ + return ""; +} +#endif /* CONFIG_BLUETOOTH_DEBUG */ + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* __BT_UUID_H */ diff --git a/kernel/protocols/bluetooth/include/drivers/bluetooth/hci_driver.h b/kernel/protocols/bluetooth/include/drivers/bluetooth/hci_driver.h new file mode 100644 index 0000000000..45733d5149 --- /dev/null +++ b/kernel/protocols/bluetooth/include/drivers/bluetooth/hci_driver.h @@ -0,0 +1,164 @@ +/** @file + * @brief Bluetooth HCI driver API. + */ + +/* + * Copyright (c) 2015-2016 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef __BT_HCI_DRIVER_H +#define __BT_HCI_DRIVER_H + +/** + * @brief HCI drivers + * @defgroup bt_hci_driver HCI drivers + * @ingroup bluetooth + * @{ + */ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Check if an HCI event is high priority or not. + * + * Helper for the HCI driver to know which events are ok to be passed + * through the RX thread and which must be given to bt_recv_prio() from + * another context (e.g. ISR). If this function returns true it's safe + * to pass the event through the RX thread, however if it returns false + * then this risks a deadlock. + * + * @param evt HCI event code. + * + * @return true if the event can be processed in the RX thread, false + * if it cannot. + */ +static inline bool bt_hci_evt_is_prio(uint8_t evt) +{ + switch (evt) { + case BT_HCI_EVT_CMD_COMPLETE: + case BT_HCI_EVT_CMD_STATUS: +#if defined(CONFIG_BLUETOOTH_CONN) + case BT_HCI_EVT_NUM_COMPLETED_PACKETS: +#endif + return true; + default: + return false; + } +} + +/** + * @brief Receive data from the controller/HCI driver. + * + * This is the main function through which the HCI driver provides the + * host with data from the controller. The buffer needs to have its type + * set with the help of bt_buf_set_type() before calling this API. This API + * should not be used for so-called high priority HCI events, which should + * instead be delivered to the host stack through bt_recv_prio(). + * + * @param buf Network buffer containing data from the controller. + * + * @return 0 on success or negative error number on failure. + */ +int bt_recv(struct net_buf *buf); + +/** + * @brief Receive high priority data from the controller/HCI driver. + * + * This is the same as bt_recv(), except that it should be used for + * so-called high priority HCI events. There's a separate + * bt_hci_evt_is_prio() helper that can be used to identify which events + * are high priority. + * + * As with bt_recv(), the buffer needs to have its type set with the help of + * bt_buf_set_type() before calling this API. The only exception is so called + * high priority HCI events which should be delivered to the host stack through + * bt_recv_prio() instead. + * + * @param buf Network buffer containing data from the controller. + * + * @return 0 on success or negative error number on failure. + */ +int bt_recv_prio(struct net_buf *buf); + +/** Possible values for the 'bus' member of the bt_hci_driver struct */ +enum bt_hci_driver_bus { + BT_HCI_DRIVER_BUS_VIRTUAL = 0, + BT_HCI_DRIVER_BUS_USB = 1, + BT_HCI_DRIVER_BUS_PCCARD = 2, + BT_HCI_DRIVER_BUS_UART = 3, + BT_HCI_DRIVER_BUS_RS232 = 4, + BT_HCI_DRIVER_BUS_PCI = 5, + BT_HCI_DRIVER_BUS_SDIO = 6, + BT_HCI_DRIVER_BUS_SPI = 7, + BT_HCI_DRIVER_BUS_I2C = 8, +}; + +/** + * @brief Abstraction which represents the HCI transport to the controller. + * + * This struct is used to represent the HCI transport to the Bluetooth + * controller. + */ +struct bt_hci_driver { + /** Name of the driver */ + const char *name; + + /** Bus of the transport (BT_HCI_DRIVER_BUS_*) */ + enum bt_hci_driver_bus bus; + + /** + * @brief Open the HCI transport. + * + * Opens the HCI transport for operation. This function must not + * return until the transport is ready for operation, meaning it + * is safe to start calling the send() handler. + * + * If the driver uses its own RX thread, i.e. + * CONFIG_BLUETOOTH_RECV_IS_RX_THREAD is set, then this + * function is expected to start that thread. + * + * @return 0 on success or negative error number on failure. + */ + int (*open)(void); + + /** + * @brief Send HCI buffer to controller. + * + * Send an HCI command or ACL data to the controller. The exact + * type of the data can be checked with the help of bt_buf_get_type(). + * + * @param buf Buffer containing data to be sent to the controller. + * + * @return 0 on success or negative error number on failure. + */ + int (*send)(struct net_buf *buf); +}; + +/** + * @brief Register a new HCI driver to the Bluetooth stack. + * + * This needs to be called before any application code runs. The bt_enable() + * API will fail if there is no driver registered. + * + * @param drv A bt_hci_driver struct representing the driver. + * + * @return 0 on success or negative error number on failure. + */ +int bt_hci_driver_register(struct bt_hci_driver *drv); + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* __BT_HCI_DRIVER_H */ diff --git a/kernel/protocols/bluetooth/port/csp_port.c b/kernel/protocols/bluetooth/port/csp_port.c new file mode 100644 index 0000000000..b9bbd05925 --- /dev/null +++ b/kernel/protocols/bluetooth/port/csp_port.c @@ -0,0 +1,248 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#include +#include +#include + +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_CORE) + +#include +#include "csp.h" +#include "freertos/timers.h" + +#if defined(__cplusplus) +extern "C" +{ +#endif + +void k_lifo_init(struct k_lifo *lifo, const char *name, void **start, size_t msg_num) +{ + k_mbox_t *mbox; + UNUSED(name); + UNUSED(start); + k_mbox_new(&mbox, msg_num); + lifo->_queue = mbox; + BT_DBG("lifo %p,lifo->_queue %p\n", lifo, lifo->_queue); +} + +void k_lifo_put(struct k_lifo *lifo, void *data) +{ + BT_DBG("lifo %p,lifo->_queue %p,data %p\n", lifo, lifo->_queue, data); + k_mbox_post((k_mbox_t *)lifo->_queue, data); +} + +void *k_lifo_get(struct k_lifo *lifo, uint32_t timeout) +{ + void *msg = NULL; + BT_DBG("lifo %p,lifo->_queue %p\n", lifo, lifo->_queue); + + if (K_FOREVER == timeout) { + k_mbox_fetch((k_mbox_t *)lifo->_queue, &msg, 0); + } else if (K_NO_WAIT == timeout) { + k_mbox_tryfetch((k_mbox_t *)lifo->_queue, &msg); + } else { + k_mbox_fetch((k_mbox_t *)lifo->_queue, &msg, timeout); + } + + return msg; +} + +void k_fifo_init(struct k_fifo *fifo, const char *name, void **start, size_t msg_num) +{ + k_mbox_t *mbox; + UNUSED(name); + UNUSED(start); + BT_DBG(""); + k_mbox_new(&mbox, msg_num); + fifo->_queue = mbox; + BT_DBG("fifo %p,fifo->_queue %p\n", fifo, fifo->_queue); +} + +void *k_fifo_get(struct k_fifo *fifo, uint32_t timeout) +{ + void *msg = NULL; + BT_DBG("fifo %p,fifo->_queue %p\n", fifo, fifo->_queue); + + if (K_FOREVER == timeout) { + k_mbox_fetch((k_mbox_t *)fifo->_queue, &msg, 0); + } else if (K_NO_WAIT == timeout) { + k_mbox_tryfetch((k_mbox_t *)fifo->_queue, &msg); + } else { + k_mbox_fetch((k_mbox_t *)fifo->_queue, &msg, timeout); + } + + return msg; +} + +void k_fifo_put(struct k_fifo *fifo, void *msg) +{ + BT_DBG("fifo %p,fifo->_queue %p,msg %p\n", fifo, fifo->_queue, msg); + k_mbox_post((k_mbox_t *)fifo->_queue, msg); +} + +int k_sem_init(struct k_sem *sem, unsigned int initial_count, unsigned int limit) +{ + int ret; + csp_sem_t *psem = (csp_sem_t *)malloc(sizeof(csp_sem_t)); + + if (NULL == sem || NULL == psem) { + BT_ERR("sem init fail\n"); + return -EINVAL; + } + + ret = csp_sem_new(psem, initial_count); + + if (ret) { + BT_ERR("sem init fail\n"); + return ret; + } + + sem->sem = psem; + BT_DBG("sem->hdl %p,count %d", psem->hdl, initial_count); + return 0; +} + +int k_sem_take(struct k_sem *sem, uint32_t timeout) +{ + csp_sem_t *psem; + + if (NULL == sem || NULL == sem->sem) { + BT_ERR("sem give fail\n"); + return -EINVAL; + } + + psem = (csp_sem_t *)sem->sem; + BT_DBG("sem->hdl %p,timeout %d", psem->hdl, timeout); + + if (timeout == K_FOREVER) { + timeout = 0; + } else if (K_NO_WAIT == timeout) { + timeout = 1; + } + + return csp_sem_wait(*psem, timeout); +} + +int k_sem_give(struct k_sem *sem) +{ + csp_sem_t *psem; + + if (NULL == sem || NULL == sem->sem) { + BT_ERR("sem give fail\n"); + return -EINVAL; + } + + psem = (csp_sem_t *)sem->sem; + BT_DBG("sem->hdl %p", psem->hdl); + csp_sem_signal(*psem); + return 0; +} + +int k_sem_delete(struct k_sem *sem) +{ + if (NULL == sem) { + BT_ERR("sem is NULL\n"); + return -EINVAL; + } + + csp_sem_free(sem->sem); + free(sem->sem); + sem->sem = NULL; + return 0; +} + +int64_t k_uptime_get() +{ + return csp_now(); +} + +int k_thread_spawn(const char *name, uint32_t *stack, uint32_t stack_size, \ + k_thread_entry_t fn, void *arg, int prio) + +{ + int ret; + ret = csp_task_new_ext(name, fn, arg, stack_size * sizeof(int), prio); + + if (ret) { + BT_ERR("creat task %s fail\n", name); + } + + return ret; +} + +int k_yield() +{ + return 0; +} + + +unsigned int irq_lock() +{ + return 0; +} + +void irq_unlock(unsigned int key) +{ +} + +void vTimerCallback(TimerHandle_t pxTimer) +{ + k_timer_t *timer = pvTimerGetTimerID(pxTimer); + BT_INFO("px timer %p,timer %p,timer handler %p", pxTimer, timer, timer->handler); + + if (timer && timer->handler) { + timer->handler(timer->args); + } +} + +void k_timer_init(k_timer_t *timer, k_timer_handler_t handle, void *args) +{ + TimerHandle_t timer_handle; + ASSERT(timer, "timer is NULL"); + + timer_handle = xTimerCreate("", 1000 / portTICK_RATE_MS, 0, (void *)timer, vTimerCallback); + + if (!timer_handle) { + BT_ERR("timer init fail"); + return; + } + + timer->handler = handle; + timer->args = args; + timer->timer = timer_handle; +} +void k_timer_start(k_timer_t *timer, uint32_t timeout) +{ + ASSERT(timer, "timer is NULL"); + + if (timer->timer) { + BT_INFO("px timer %p,timer %p,timer handler %p", timer->timer, timer, timer->handler); + + if (xTimerIsTimerActive(timer->timer)) { + xTimerStop(timer->timer, 0); + } + + if (xTimerChangePeriod(timer->timer, timeout / portTICK_PERIOD_MS, 100) != pdPASS) { + BT_ERR("timer start fail"); + return; + } + } else { + BT_ERR("timer creat fail"); + } +} +void k_timer_stop(k_timer_t *timer) +{ + ASSERT(timer, "timer is NULL"); + + if (timer->timer) { + BT_INFO("px timer %p,timer %p", timer->timer, timer); + xTimerStop(timer->timer, 0); + } +} + + +#if defined(__cplusplus) +} +#endif diff --git a/kernel/protocols/bluetooth/port/include/config.h b/kernel/protocols/bluetooth/port/include/config.h new file mode 100644 index 0000000000..8c2b74ae2c --- /dev/null +++ b/kernel/protocols/bluetooth/port/include/config.h @@ -0,0 +1,387 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#ifndef CONFIG_H +#define CONFIG_H + +/** + * CONFIG_BLUETOOTH: Enable the bluetooh stack + */ +#ifndef CONFIG_BLUETOOTH +#error "CONFIG_BLUETOOTH not defined,this header shoudn't include" +#endif + +/** + * CONFIG_BLUETOOTH_HCI_RX_STACK_SIZE: rx thread stack size + */ +#ifndef CONFIG_BLUETOOTH_HCI_RX_STACK_SIZE +#define CONFIG_BLUETOOTH_HCI_RX_STACK_SIZE 1024 +#endif +/** + * CONFIG_BLUETOOTH_HCI_RX_PRIO: rx thread priority + */ +#ifndef CONFIG_BLUETOOTH_HCI_RX_PRIO +#define CONFIG_BLUETOOTH_HCI_RX_PRIO 41 +#endif +/** + * CONFIG_BLUETOOTH_HCI_RX_NAME: rx thread name + */ +#ifndef CONFIG_BLUETOOTH_HCI_RX_NAME +#define CONFIG_BLUETOOTH_HCI_RX_NAME "rx thread" +#endif +/** + * CONFIG_BLUETOOTH: Tx thread stack size + */ +#ifndef CONFIG_BLUETOOTH_HCI_TX_STACK_SIZE +#define CONFIG_BLUETOOTH_HCI_TX_STACK_SIZE 640 +#endif +/** + * CONFIG_BLUETOOTH_HCI_TX_PRIO: tx thread priority + */ +#ifndef CONFIG_BLUETOOTH_HCI_TX_PRIO +#define CONFIG_BLUETOOTH_HCI_TX_PRIO 40 +#endif +/** + * CONFIG_BLUETOOTH_HCI_TX_NAME: tx thread name + */ +#ifndef CONFIG_BLUETOOTH_HCI_TX_NAME +#define CONFIG_BLUETOOTH_HCI_TX_NAME "tx thread" +#endif + +/** +* CONFIG_BLUETOOTH_HCI_CMD_COUNT: hci cmd buffer count,range 2 to 64 +*/ +#ifndef CONFIG_BLUETOOTH_HCI_CMD_COUNT +#define CONFIG_BLUETOOTH_HCI_CMD_COUNT 2 +#endif + +/** +* CONFIG_BLUETOOTH_RX_BUF_COUNT: number of buffer for incoming ACL packages or HCI +* events,range 2 to 255 +*/ +#ifndef CONFIG_BLUETOOTH_RX_BUF_COUNT +#define CONFIG_BLUETOOTH_RX_BUF_COUNT 10 +#endif + +/** +* CONFIG_BLUETOOTH_RX_BUF_LEN: the max length for rx buffer +* range 73 to 2000 +*/ +#ifndef CONFIG_BLUETOOTH_RX_BUF_LEN +#define CONFIG_BLUETOOTH_RX_BUF_LEN 76 +#endif + +/** +* CONFIG_BLUETOOTH_CENTRAL: Enable central Role +*/ +#ifdef CONFIG_BLUETOOTH_CENTRAL +#undef CONFIG_BLUETOOTH_CENTRAL +#define CONFIG_BLUETOOTH_CENTRAL 1 +#endif + +/** +* CONFIG_BLUETOOTH_PERIPHERAL: Enable peripheral Role +*/ +#ifdef CONFIG_BLUETOOTH_PERIPHERAL +#undef CONFIG_BLUETOOTH_PERIPHERAL +#define CONFIG_BLUETOOTH_PERIPHERAL 1 +#endif + +#if defined(CONFIG_BLUETOOTH_CENTRAL) || defined(CONFIG_BLUETOOTH_PERIPHERAL) +#undef CONFIG_BLUETOOTH_CONN +#define CONFIG_BLUETOOTH_CONN 1 +#endif + +#ifdef CONFIG_BLUETOOTH_CONN + +/** +* CONFIG_BLUETOOTH_L2CAP_TX_BUF_COUNT: number of buffer for outgoing L2CAP packages +* range 2 to 255 +*/ +#ifndef CONFIG_BLUETOOTH_L2CAP_TX_BUF_COUNT +#define CONFIG_BLUETOOTH_L2CAP_TX_BUF_COUNT 3 +#endif + +/** +* CONFIG_BLUETOOTH_L2CAP_TX_MTU: Max L2CAP MTU for L2CAP tx buffer +* range 65 to 2000 if SMP enabled,otherwise range 23 to 2000 +*/ +#ifndef CONFIG_BLUETOOTH_L2CAP_TX_MTU +#ifdef CONFIG_BLUETOOTH_SMP +#define CONFIG_BLUETOOTH_L2CAP_TX_MTU 65 +#else +#define CONFIG_BLUETOOTH_L2CAP_TX_MTU 23 +#endif +#endif + +/** +* CONFIG_BLUETOOTH_L2CAP_TX_USER_DATA_SIZE: the max length for L2CAP tx buffer user data size +* range 4 to 65535 +*/ +#ifndef CONFIG_BLUETOOTH_L2CAP_TX_USER_DATA_SIZE +#define CONFIG_BLUETOOTH_L2CAP_TX_USER_DATA_SIZE 4 +#endif + +/** +* CONFIG_BLUETOOTH_ATT_PREPARE_COUNT: Number of buffers available for ATT prepare write, setting +* this to 0 disables GATT long/reliable writes. +* range 0 to 64 +*/ +#ifndef CONFIG_BLUETOOTH_ATT_PREPARE_COUNT +#define CONFIG_BLUETOOTH_ATT_PREPARE_COUNT 0 +#endif + +/** +* CONFIG_BLUETOOTH_SMP:Eable the Security Manager Protocol +* (SMP), making it possible to pair devices over LE +*/ +#ifdef CONFIG_BLUETOOTH_SMP +#undef CONFIG_BLUETOOTH_SMP +#define CONFIG_BLUETOOTH_SMP 1 + +/** +* CONFIG_BLUETOOTH_SIGNING:enables data signing which is used for transferring +* authenticated data in an unencrypted connection +*/ +#ifdef CONFIG_BLUETOOTH_SIGNING +#undef CONFIG_BLUETOOTH_SIGNING +#define CONFIG_BLUETOOTH_SIGNING 1 +#endif + +/** +* CONFIG_BLUETOOTH_SMP_SC_ONLY:enables support for Secure Connection Only Mode. In this +* mode device shall only use Security Mode 1 Level 4 with exception +* for services that only require Security Mode 1 Level 1 (no security). +* Security Mode 1 Level 4 stands for authenticated LE Secure Connections +* pairing with encryption. Enabling this option disables legacy pairing +*/ +#ifdef CONFIG_BLUETOOTH_SMP_SC_ONLY +#undef CONFIG_BLUETOOTH_SMP_SC_ONLY +#define CONFIG_BLUETOOTH_SMP_SC_ONLY 1 +#endif + +/** +* CONFIG_BLUETOOTH_USE_DEBUG_KEYS:This option places Security Manager in +* a Debug Mode. In this mode predefined +* Diffie-Hellman private/public key pair is used as described +* in Core Specification Vol. 3, Part H, 2.3.5.6.1. This option should +* only be enabled for debugging and should never be used in production. +* If this option is enabled anyone is able to decipher encrypted air +* traffic. +*/ +#ifdef CONFIG_BLUETOOTH_USE_DEBUG_KEYS +#ifndef CONFIG_BLUETOOTH_TINYCRYPT_ECC +#error "CONFIG_BLUETOOTH_USE_DEBUG_KEYS depends on CONFIG_BLUETOOTH_TINYCRYPT_ECC" +#endif +#undef CONFIG_BLUETOOTH_USE_DEBUG_KEYS +#define CONFIG_BLUETOOTH_USE_DEBUG_KEYS 1 +#endif + +/** +* CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL:enables support for LE Connection +* oriented Channels,allowing the creation of dynamic L2CAP Channels +*/ +#ifdef CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL +#undef CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL +#define CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL 1 +#endif + +#endif + +/** +* CONFIG_BLUETOOTH_PRIVACY:Enable local Privacy Feature support. This makes it possible +* to use Resolvable Private Addresses (RPAs). +*/ +#ifdef CONFIG_BLUETOOTH_PRIVACY +#ifndef CONFIG_BLUETOOTH_SMP +#error "CONFIG_BLUETOOTH_PRIVACY depends on CONFIG_BLUETOOTH_SMP" +#endif +#undef CONFIG_BLUETOOTH_PRIVACY +#define CONFIG_BLUETOOTH_PRIVACY 1 + +/** +* CONFIG_BLUETOOTH_RPA_TIMEOUT:Resolvable Private Address timeout +* range 1 to 65535,seconds +*/ +#ifndef CONFIG_BLUETOOTH_RPA_TIMEOUT +#define CONFIG_BLUETOOTH_RPA_TIMEOUT 900 +#endif +#endif + +/** +* CONFIG_BLUETOOTH_GATT_DYNAMIC_DB:enables GATT services to be added dynamically to database +*/ +#ifdef CONFIG_BLUETOOTH_GATT_DYNAMIC_DB +#undef CONFIG_BLUETOOTH_GATT_DYNAMIC_DB +#define CONFIG_BLUETOOTH_GATT_DYNAMIC_DB 1 +#endif + +/** +* CONFIG_BLUETOOTH_GATT_CLIENT:GATT client role support +*/ +#ifdef CONFIG_BLUETOOTH_GATT_CLIENT +#undef CONFIG_BLUETOOTH_GATT_CLIENT +#define CONFIG_BLUETOOTH_GATT_CLIENT 1 +#endif + +/** +* CONFIG_BLUETOOTH_MAX_PAIRED:Maximum number of paired devices +* range 1 to 128 +*/ +#ifndef CONFIG_BLUETOOTH_MAX_PAIRED +#define CONFIG_BLUETOOTH_MAX_PAIRED 1 +#endif +#endif + +/** +* If this option is set TinyCrypt library is used for emulating the +* ECDH HCI commands and events needed by e.g. LE Secure Connections. +* In builds including the BLE Host, if not set the controller crypto is +* used for ECDH and if the controller doesn't support the required HCI +* commands the LE Secure Connections support will be disabled. +* In builds including the HCI Raw interface and the BLE Controller, this +* option injects support for the 2 HCI commands required for LE Secure +* Connections so that Hosts can make use of those +*/ +#ifdef CONFIG_BLUETOOTH_TINYCRYPT_ECC +#undef CONFIG_BLUETOOTH_TINYCRYPT_ECC +#define CONFIG_BLUETOOTH_TINYCRYPT_ECC 1 +#endif +/** +* CONFIG_BLUETOOTH_MAX_CONN:Maximum number of connections +* range 1 to 128 +*/ +#ifndef CONFIG_BLUETOOTH_MAX_CONN +#define CONFIG_BLUETOOTH_MAX_CONN 1 +#endif + +/** +* CONFIG_BLUETOOTH_DEVICE_NAME:Bluetooth device name. Name can be up +* to 248 bytes long (excluding NULL termination). Can be empty string +*/ +#ifndef CONFIG_BLUETOOTH_DEVICE_NAME +#define CONFIG_BLUETOOTH_DEVICE_NAME "AOS Device" +#endif + +/** +* CONFIG_BLUETOOTH_CONTROLLER_NAME:Bluetooth controller name. default support ESP32. +*/ +#ifndef CONFIG_BLUETOOTH_CONTROLLER_NAME +#define CONFIG_BLUETOOTH_CONTROLLER_NAME "ESP32" +#endif + +/** +* CONFIG_BLUETOOTH_MAX_SCO_CONN:Maximum number of simultaneous SCO connections. +*/ +#ifndef CONFIG_BLUETOOTH_MAX_SCO_CONN +#define CONFIG_BLUETOOTH_MAX_SCO_CONN 1 +#endif + +/** +* CONFIG_BLUETOOTH_WORK_QUEUE_STACK_SIZE:Work queue stack size. +*/ +#ifndef CONFIG_BLUETOOTH_WORK_QUEUE_STACK_SIZE +#define CONFIG_BLUETOOTH_WORK_QUEUE_STACK_SIZE 512 +#endif + +/** +* CONFIG_BLUETOOTH_WORK_QUEUE_PRIO:Work queue priority. +*/ +#ifndef CONFIG_BLUETOOTH_WORK_QUEUE_PRIO +#define CONFIG_BLUETOOTH_WORK_QUEUE_PRIO 42 +#endif + +/** +* CONFIG_BLUETOOTH_HCI_RESERVE:Headroom that the driver needs for sending and receiving buffers. +*/ +#ifndef CONFIG_BLUETOOTH_HCI_RESERVE +#ifdef CONFIG_BLUETOOTH_H4 +#define CONFIG_BLUETOOTH_HCI_RESERVE 0 +#elif defined(CONFIG_BLUETOOTH_H5) || defined(CONFIG_BLUETOOTH_SPI) +#define CONFIG_BLUETOOTH_HCI_RESERVE 1 +#else +#define CONFIG_BLUETOOTH_HCI_RESERVE 1 +#endif +#endif + +/** +* CONFIG_BLUETOOTH_DEBUG_LOG:Enable bluetooth debug log. +*/ +#ifdef CONFIG_BLUETOOTH_DEBUG_LOG +#undef CONFIG_BLUETOOTH_DEBUG_LOG +#define CONFIG_BLUETOOTH_DEBUG_LOG 1 +#undef CONFIG_BLUETOOTH_DEBUG +#define CONFIG_BLUETOOTH_DEBUG 1 +#endif + +/** +* CONFIG_BLUETOOTH_DEBUG_L2CAP:Enable bluetooth l2cap debug log. +*/ +#ifdef CONFIG_BLUETOOTH_DEBUG_L2CAP +#undef CONFIG_BLUETOOTH_DEBUG_L2CAP +#define CONFIG_BLUETOOTH_DEBUG_L2CAP 1 +#endif + +/** +* CONFIG_BLUETOOTH_DEBUG_CONN:Enable bluetooth conn debug log. +*/ +#ifdef CONFIG_BLUETOOTH_DEBUG_CONN +#undef CONFIG_BLUETOOTH_DEBUG_CONN +#define CONFIG_BLUETOOTH_DEBUG_CONN 1 +#endif + +/** +* CONFIG_BLUETOOTH_DEBUG_ATT:Enable bluetooth att debug log. +*/ +#ifdef CONFIG_BLUETOOTH_DEBUG_ATT +#undef CONFIG_BLUETOOTH_DEBUG_ATT +#define CONFIG_BLUETOOTH_DEBUG_ATT 1 +#endif + +/** +* CONFIG_BLUETOOTH_DEBUG_GATT:Enable bluetooth gatt debug log. +*/ +#ifdef CONFIG_BLUETOOTH_DEBUG_GATT +#undef CONFIG_BLUETOOTH_DEBUG_GATT +#define CONFIG_BLUETOOTH_DEBUG_GATT 1 +#endif + +/** +* CONFIG_BLUETOOTH_DEBUG_HCI_CORE:Enable bluetooth hci core debug log. +*/ +#ifdef CONFIG_BLUETOOTH_DEBUG_HCI_CORE +#undef CONFIG_BLUETOOTH_DEBUG_HCI_CORE +#define CONFIG_BLUETOOTH_DEBUG_HCI_CORE 1 +#endif + +/** +* CONFIG_BLUETOOTH_DEBUG_HCI_DRIVER:Enable bluetooth hci driver debug log. +*/ +#ifdef CONFIG_BLUETOOTH_DEBUG_HCI_DRIVER +#undef CONFIG_BLUETOOTH_DEBUG_HCI_DRIVER +#define CONFIG_BLUETOOTH_DEBUG_HCI_DRIVER 1 +#endif + +/** +* CONFIG_BLUETOOTH_TEST:Enable bluetooth test. +*/ +#ifdef CONFIG_BLUETOOTH_TEST +#undef CONFIG_BLUETOOTH_TEST +#define CONFIG_BLUETOOTH_TEST 1 +#endif + +/** +* CONFIG_BLUETOOTH_DEBUG_CORE:Enable bluetooth core debug log. +*/ +#ifdef CONFIG_BLUETOOTH_DEBUG_CORE +#undef CONFIG_BLUETOOTH_DEBUG_CORE +#define CONFIG_BLUETOOTH_DEBUG_CORE 1 +#endif + +#if defined(__cplusplus) +} +#endif + +#endif /* CONFIG_H */ + diff --git a/kernel/protocols/bluetooth/port/include/kport.h b/kernel/protocols/bluetooth/port/include/kport.h new file mode 100644 index 0000000000..4503a49b08 --- /dev/null +++ b/kernel/protocols/bluetooth/port/include/kport.h @@ -0,0 +1,373 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#ifndef PORT_H +#define PORT_H +#include +#include +#include "config.h" +#include "aos/log.h" + +#include "esp_log.h" + +#ifdef CONFIG_AOS_RHINO +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif + +#if defined(__cplusplus) +extern "C" +{ +#endif + +#ifdef CONFIG_AOS_RHINO +typedef kqueue_t _queue_t; +typedef ksem_t _sem_t; +#else +typedef void* _queue_t; +typedef void* _sem_t +#endif + +/* Log define*/ +enum { + LOG_LEVEL_NONE = 0, + LOG_LEVEL_FATAL, + LOG_LEVEL_ERROR, + LOG_LEVEL_WARN, + LOG_LEVEL_INFO, + LOG_LEVEL_DEBUG, + LOG_LEVEL_MAX_BIT +}; +#define BT_MOD "ZEPHYRBT" + +#define SYS_LOG_DBG(...) LOGD(BT_MOD,##__VA_ARGS__) +#define SYS_LOG_INF(...) LOGI(BT_MOD,##__VA_ARGS__) +#define SYS_LOG_WRN(...) LOGW(BT_MOD,##__VA_ARGS__) +#define SYS_LOG_ERR(...) LOGE(BT_MOD,##__VA_ARGS__) +#define SYS_LOG_FAT(...) LOGF(BT_MOD,##__VA_ARGS__) + +#define LIFO_DEBUG 0 +#define FIFO_DEBUG 0 + +/* lifo define*/ +struct k_lifo { + _queue_t *_queue; +#if LIFO_DEBUG + uint32_t total_count; + int32_t count; +#endif +}; + +/** + * @brief Initialize a lifo. + * + * This routine initializes a lifo object, prior to its first use. + * + * @param lifo Address of the lifo. + * @param name lifo name. + * @param start Address of static assgin memery.if NULL ,alloc memery dynamically + * @param msg_num message numbers of the lifo. + * + * @return N/A + */ +void k_lifo_init(struct k_lifo *lifo, const char *name,void **start,size_t msg_num); + +/** + * @brief Add an element to a lifo. + * + * This routine adds a data item to @a lifo. A lifo data item must be + * aligned on a 4-byte boundary + * + * @param lifo Address of the lifo. + * @param data Address of the data item. + * + * @return N/A + */ +void k_lifo_put(struct k_lifo *lifo, void *data); + +/** + * @brief Get an element from a lifo. + * + * This routine removes a data item from @a lifo in a "last in, first out" + * manner. + * + * @note Can be called by ISRs, but @a timeout must be set to K_NO_WAIT. + * + * @param lifo Address of the lifo. + * @param timeout Waiting period to obtain a data item (in milliseconds), + * or one of the special values K_NO_WAIT and K_FOREVER. + * + * @return Address of the data item if successful; NULL if returned + * without waiting, or waiting period timed out. + */ +void *k_lifo_get(struct k_lifo *lifo, tick_t timeout); + +/* fifo define*/ +struct k_fifo { + _queue_t* _queue; +#if FIFO_DEBUG + uint32_t total_count; + int32_t count; +#endif +}; + +/** + * @brief Initialize a fifo. + * + * This routine initializes a fifo object, prior to its first use. + * + * @param fifo Address of the fifo. + * @param name lifo name. + * @param start Address of static assgin memery.if NULL ,alloc memery dynamically + * @param msg_num message numbers of the lifo. + * + * @return N/A + */ +void k_fifo_init(struct k_fifo *fifo, const char *name, void **start, size_t msg_len); + +/** + * @brief Add an element to a fifo. + * + * This routine adds a data item to @a fifo. A fifo data item must be + * aligned on a 4-byte boundary + * + * @param fifo Address of the fifo. + * @param data Address of the data item. + * + * @return N/A + */ +void k_fifo_put(struct k_fifo *fifo, void *msg); + +/** + * @brief Get an element from a fifo. + * + * This routine removes a data item from @a fifo in a "first in, first out" + * manner. The first 32 bits of the data item are reserved for the kernel's use. + * + * @note Can be called by ISRs, but @a timeout must be set to K_NO_WAIT. + * + * @param fifo Address of the fifo. + * @param timeout Waiting period to obtain a data item (in milliseconds), + * or one of the special values K_NO_WAIT and K_FOREVER. + * + * @return Address of the data item if successful; NULL if returned + * without waiting, or waiting period timed out. + */ +void *k_fifo_get(struct k_fifo *fifo, tick_t timeout); + +/* sem define*/ +struct k_sem { + _sem_t *sem; +}; + +/** + * @brief Initialize a semaphore. + * + * This routine initializes a semaphore object, prior to its first use. + * + * @param sem Address of the semaphore. + * @param initial_count Initial semaphore count. + * @param limit Maximum permitted semaphore count. + * + * @return 0 Creat a semaphore succcess + */ +int k_sem_init(struct k_sem *sem, unsigned int initial_count, unsigned int limit); + +/** + * @brief Take a semaphore. + * + * This routine takes @a sem. + * + * @note Can be called by ISRs, but @a timeout must be set to K_NO_WAIT. + * + * @param sem Address of the semaphore. + * @param timeout Waiting period to take the semaphore (in milliseconds), + * or one of the special values K_NO_WAIT and K_FOREVER. + * + * @note When porting code from the nanokernel legacy API to the new API, be + * careful with the return value of this function. The return value is the + * reverse of the one of nano_sem_take family of APIs: 0 means success, and + * non-zero means failure, while the nano_sem_take family returns 1 for success + * and 0 for failure. + * + * @retval 0 Semaphore taken. + * @retval -EBUSY Returned without waiting. + * @retval -EAGAIN Waiting period timed out. + */ +int k_sem_take(struct k_sem *sem, uint32_t timeout); + +/** + * @brief Give a semaphore. + * + * This routine gives @a sem, unless the semaphore is already at its maximum + * permitted count. + * + * @note Can be called by ISRs. + * + * @param sem Address of the semaphore. + * + * @return 0 Give semaphore success + */ +int k_sem_give(struct k_sem *sem); + +/** + * @brief Delete a semaphore. + * + * This routine delete @a sem, + * + * @note Can be called by ISRs. + * + * @param sem Address of the semaphore. + * + * @return 0 delete semaphore success + */ +int k_sem_delete(struct k_sem *sem); + +typedef void (*k_timer_handler_t)(void *arg); +typedef struct k_timer { + void *timer; + k_timer_handler_t handler; + void *args; + uint32_t timeout; +} k_timer_t; + +/** + * @brief Initialize a timer. + * + * This routine initializes a timer, prior to its first use. + * + * @param timer Address of timer. + * @param handle Function to invoke each time the timer expires. + * @param args Arguments sent to handle. + * + * @return N/A + */ +void k_timer_init(k_timer_t *timer, k_timer_handler_t handle, void *args); + +/** + * @brief Start a timer. + * + * @param timer Address of timer. + * @param timeout time before timeout happen(in milliseconds). + * + * @return N/A + */ +void k_timer_start(k_timer_t *timer, uint32_t timeout); + +/** + * @brief Stop a timer. + * + * @param timer Address of timer. + * + * @return N/A + */ +void k_timer_stop(k_timer_t *timer); + +/*time define*/ +#define MSEC_PER_SEC 1000 +#define K_MSEC(ms) (ms) +#define K_SECONDS(s) K_MSEC((s) * MSEC_PER_SEC) + +/** + * @brief Get time now. + * + * @return time(in milliseconds) + */ +int64_t k_uptime_get(); + +typedef void (*k_thread_entry_t)(void *args); +/** + * @brief Spawn a thread. + * + * This routine initializes a thread, then schedules it for execution. + * + * @param name Thread name + * @param stack Pointer to the stack space. + * @param stack_size Stack size in bytes. + * @param fn Thread entry function. + * @param arg entry point parameter. + * @param prio Thread priority. + * + * @return 0 success. + */ +int k_thread_spawn(const char *name, uint32_t *stack, uint32_t stack_size, \ + k_thread_entry_t fn, void *arg, int prio); + +/** + * @brief Yield the current thread. + * + * This routine causes the current thread to yield execution to another + * thread of the same or higher priority. If there are no other ready threads + * of the same or higher priority, the routine returns immediately. + * + * @return N/A + */ +int k_yield(); + +/** + * @brief Lock interrupts. + * + * This routine disables all interrupts on the CPU. It returns an unsigned + * integer "lock-out key", which is an architecture-dependent indicator of + * whether interrupts were locked prior to the call. The lock-out key must be + * passed to irq_unlock() to re-enable interrupts. + * + * @return Lock-out key. + */ +unsigned int irq_lock(); + +/** + * @brief Unlock interrupts. + * + * This routine reverses the effect of a previous call to irq_lock() using + * the associated lock-out key. The caller must call the routine once for + * each time it called irq_lock(), supplying the keys in the reverse order + * they were acquired, before interrupts are enabled. + * + * @param key Lock-out key generated by irq_lock(). + * + * @return N/A + */ +void irq_unlock(unsigned int key); + +#if defined(__cplusplus) +} +#endif + +#endif /* PORT_H */ + diff --git a/kernel/protocols/bluetooth/port/include/zephyr.h b/kernel/protocols/bluetooth/port/include/zephyr.h new file mode 100644 index 0000000000..f0045fe85b --- /dev/null +++ b/kernel/protocols/bluetooth/port/include/zephyr.h @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#ifndef ZEPHYR_H +#define ZEPHYR_H +#include +#include + +#include "kport.h" +#include "mbox.h" +#include "work.h" +#include "timer.h" + +#if defined(__cplusplus) +extern "C" +{ +#endif + +#define _STRINGIFY(x) #x + +#define ___in_section(a, b, c) \ + __attribute__((section("." _STRINGIFY(a) \ + "." _STRINGIFY(b) \ + "." _STRINGIFY(c)))) + +//#define __in_section(a, b, c) ___in_section(a, b, c) + +#define __in_section_unique(seg) ___in_section(seg, _FILE_PATH_HASH, \ + __COUNTER__) + + +#define ARG_UNUSED(x) (void)(x) + +#ifndef __aligned +#define __aligned(x) __attribute__((__aligned__(x))) +#endif + +#ifndef __printf_like +#define __printf_like(f, a) __attribute__((format (printf, f, a))) +#endif +#define STACK_ALIGN 4 +#define __stack __aligned(STACK_ALIGN) + +#define __noinit + + +#define __ASSERT_NO_MSG(test) +#define ASSERT(test, fmt, ...) + +#define K_FOREVER -1 +#define K_NO_WAIT 0 + +/* Unaligned access */ +#define UNALIGNED_GET(p) \ + __extension__ ({ \ + struct __attribute__((__packed__)) { \ + __typeof__(*(p)) __v; \ + } *__p = (__typeof__(__p)) (p); \ + __p->__v; \ + }) + +#ifndef BIT +#define BIT(nr) (1UL << (nr)) +#endif + +#ifndef UNUSED +#define UNUSED(x) (void)x +#endif + +struct k_poll_event { + uint8_t tag; + uint8_t state; + union { + void *obj; + struct k_fifo *fifo; + struct k_poll_signal *signal; + }; +}; + +struct k_poll_signal { + struct k_poll_event *poll_event; + + unsigned int signaled; + + int result; +}; + +#define K_POLL_SIGNAL_INITIALIZER() \ + { \ + .poll_event = NULL, \ + .signaled = 0, \ + .result = 0, \ + } + +#define K_POLL_STATIC_INITIALIZER(event_obj, event_tag) \ + {\ + .tag = event_tag, \ + .obj = event_obj, \ + .state = K_POLL_STATE_NOT_READY,\ + } + +#define K_POLL_STATE_NOT_READY 0 +#define K_POLL_STATE_EADDRINUSE 1 +#define K_POLL_STATE_SIGNALED 2 +#define K_POLL_STATE_SEM_AVAILABLE 3 +#define K_POLL_STATE_DATA_AVAILABLE 4 +#define K_POLL_STATE_FIFO_DATA_AVAILABLE K_POLL_STATE_DATA_AVAILABLE + +#define K_POLL_TYPE_IGNORE 0 +#define K_POLL_TYPE_SIGNAL 1 +#define K_POLL_TYPE_SEM_AVAILABLE 2 +#define K_POLL_TYPE_DATA_AVAILABLE 3 +#define K_POLL_TYPE_FIFO_DATA_AVAILABLE K_POLL_TYPE_DATA_AVAILABLE + +static inline void k_poll_event_init(struct k_poll_event *event, void *obj, uint32_t tag) +{ + event->state = K_POLL_STATE_NOT_READY; + event->obj = obj; + event->tag = tag; +} + +#define BT_STACK(name, size) \ + uint32_t name[(size)];\ + +#define BT_STACK_NOINIT(name, size) \ + uint32_t name[(size)];\ + +#if defined(__cplusplus) + } +#endif + +#endif /* ZEPHYR_H */ + diff --git a/kernel/protocols/bluetooth/port/rhino_port.c b/kernel/protocols/bluetooth/port/rhino_port.c new file mode 100644 index 0000000000..c2eabb2f37 --- /dev/null +++ b/kernel/protocols/bluetooth/port/rhino_port.c @@ -0,0 +1,356 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#include +#include +#include + +#include +#include "k_sys.h" +#include "k_task.h" +#include "k_stats.h" +#include "k_sem.h" +#include "k_queue.h" + +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_CORE) + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "atomic.h" + +extern kstat_t krhino_queue_dyn_create(kqueue_t **queue, const name_t *name, size_t msg_num); +extern kstat_t krhino_sem_dyn_create(ksem_t **sem, const name_t *name, sem_count_t count); +extern kstat_t krhino_sem_dyn_del(ksem_t *sem); +extern kstat_t krhino_task_dyn_create(ktask_t **task, const name_t *name, void *arg, + uint8_t pri, tick_t ticks, size_t stack, + task_entry_t entry, uint8_t autorun); + +#if defined(__cplusplus) +extern "C" +{ +#endif + +void k_lifo_init(struct k_lifo *lifo, const char *name, void **start, size_t msg_num) +{ + kstat_t ret; + UNUSED(start); + + if (NULL == lifo) { + BT_ERR("lifo is NULL"); + return; + } + + BT_DBG("lifo %p,name %s,start %p,msg_num %d",lifo,name,start,msg_num); + ret = krhino_queue_dyn_create(&lifo->_queue, name, msg_num); + + if (RHINO_SUCCESS != ret) { + BT_ERR("lifo %s %p creat fail,%d\n",name, lifo, ret); + } + +#if LIFO_DEBUG + lifo->total_count = msg_num; + lifo->count = 0; +#endif +} + +void k_lifo_put(struct k_lifo *lifo, void *data) +{ + kstat_t ret; + + if (NULL == lifo) { + BT_ERR("lifo is NULL"); + return; + } + + ret = krhino_queue_front_send(lifo->_queue, data); + + if (RHINO_SUCCESS != ret) { +#if LIFO_DEBUG + BT_ERR("send msg to lifo %p count %d,total_count %d,fail,%d", + lifo, lifo->count, lifo->total_count, ret); +#else + BT_ERR("send msg to lifo %p fail,%d",lifo, ret); +#endif + return; + } +#if LIFO_DEBUG + lifo->count++; +#endif +} + +void *k_lifo_get(struct k_lifo *lifo, tick_t timeout) +{ + void *msg; + tick_t t; + + if (NULL == lifo) { + BT_ERR("lifo is NULL"); + return NULL; + } + + if (timeout == K_FOREVER) { + t = RHINO_WAIT_FOREVER; + } else if (timeout == K_NO_WAIT) { + t = RHINO_NO_WAIT; + } else { + t = krhino_ms_to_ticks(timeout); + } + + krhino_queue_recv(lifo->_queue, t, &msg); + +#if LIFO_DEBUG + if (msg) + { + lifo->count--; + } +#endif + return msg; +} + +void k_fifo_init(struct k_fifo *fifo, const char *name, void **start, size_t msg_len) +{ + kstat_t ret; + + if (NULL == fifo) { + BT_ERR("fifo is NULL"); + return; + } + BT_DBG("fifo %p,name %s,start %p,msg_num %d",fifo,name,start,msg_len); + ret = krhino_queue_dyn_create(&fifo->_queue, name, msg_len); + + if (ret) { + BT_ERR("fifo %s %p creat fail,%d\n", name, fifo, ret); + return; + } + +#if FIFO_DEBUG + fifo->total_count = msg_len; + fifo->count = 0; +#endif +} + +void *k_fifo_get(struct k_fifo *fifo, tick_t timeout) +{ + void *msg = NULL; + tick_t t; + + if (NULL == fifo) { + BT_ERR("fifo is NULL"); + return NULL; + } + + if (timeout == K_FOREVER) { + t = RHINO_WAIT_FOREVER; + } else if (timeout == K_NO_WAIT) { + t = RHINO_NO_WAIT; + } else { + t = krhino_ms_to_ticks(timeout); + } + + krhino_queue_recv(fifo->_queue, t, &msg); + +#if FIFO_DEBUG + if (msg) + { + fifo->count--; + } +#endif + return msg; +} + +void k_fifo_put(struct k_fifo *fifo, void *msg) +{ + kstat_t ret; + + if (NULL == fifo) { + BT_ERR("fifo is NULL"); + return; + } + + ret = krhino_queue_back_send(fifo->_queue, msg); + + if (RHINO_SUCCESS != ret) { +#if LIFO_DEBUG + BT_ERR("send msg to fifo %p count %d,total_count %d,fail,%d", + fifo, fifo->count, fifo->total_count, ret); +#else + BT_ERR("send msg to fifo %p fail,%d", fifo, ret); +#endif + return; + } +#if LIFO_DEBUG + fifo->count++; +#endif +} + +int k_sem_init(struct k_sem *sem, unsigned int initial_count, unsigned int limit) +{ + kstat_t ret; + + if (NULL == sem) { + BT_ERR("sem is NULL\n"); + return -EINVAL; + } + + ret = krhino_sem_dyn_create(&sem->sem, "", limit); + + if (RHINO_SUCCESS == ret && initial_count != limit) { + ret = krhino_sem_count_set(sem->sem, (sem_count_t)initial_count); + } + + return ret; +} + +int k_sem_take(struct k_sem *sem, uint32_t timeout) +{ + tick_t t; + + if (timeout == K_FOREVER) { + t = RHINO_WAIT_FOREVER; + } else if (timeout == K_NO_WAIT) { + t = RHINO_NO_WAIT; + } else { + t = krhino_ms_to_ticks(timeout); + } + + return krhino_sem_take(sem->sem, t); +} + +int k_sem_give(struct k_sem *sem) +{ + if (NULL == sem) { + BT_ERR("sem is NULL\n"); + return -EINVAL; + } + + return krhino_sem_give(sem->sem); +} + +int k_sem_delete(struct k_sem *sem) +{ + kstat_t ret = 0; + + if (NULL == sem) { + BT_ERR("sem is NULL\n"); + return -EINVAL; + } + + ret = krhino_sem_dyn_del(sem->sem); + + if (RHINO_SUCCESS != ret) { + BT_ERR("delete sem fail,%d", ret); + } + + return ret; +} + + +int64_t k_uptime_get() +{ + return krhino_ticks_to_ms(krhino_sys_tick_get()); +} + +int k_thread_spawn(const char *name, uint32_t *stack, uint32_t stack_size, \ + k_thread_entry_t fn, void *arg, int prio) + +{ + ktask_t *task; + kstat_t ret; + ret = krhino_task_dyn_create(&task, name, arg, prio, 0, stack_size, fn, 1); + + if (ret) { + SYS_LOG_ERR("creat task %s fail\n", name); + return ret; + } + + return ret; +} + +int k_yield() +{ + return krhino_task_yield(); +} + + +unsigned int irq_lock() +{ + CPSR_ALLOC(); + RHINO_CPU_INTRPT_DISABLE(); + return cpsr; +} + +void irq_unlock(unsigned int key) +{ + CPSR_ALLOC(); + cpsr = key; + RHINO_CPU_INTRPT_ENABLE(); +} + +void _SysFatalErrorHandler(unsigned int reason, + const void *pEsf) +{ +}; + +void k_timer_init(k_timer_t *timer, k_timer_handler_t handle, void *args) +{ + ASSERT(timer, "timer is NULL"); + BT_DBG("timer %p,handle %p,args %p", timer, handle, args); + timer->handler = handle; + timer->args = args; + timer->timer = NULL; +} + +void k_timer_start(k_timer_t *timer, uint32_t timeout) +{ + ASSERT(timer, "timer is NULL"); + BT_DBG("timer %p,timeout %u", timer, timeout); + timer->timeout = timeout; + aos_post_delayed_action(timeout, timer->handler, timer->args); +} + +void k_timer_stop(k_timer_t *timer) +{ + ASSERT(timer, "timer is NULL"); + BT_DBG("timer %p", timer); + aos_cancel_delayed_action(timer->timeout,timer->handler, timer->args); +} + +#if defined(__cplusplus) +} +#endif diff --git a/kernel/protocols/mesh/include/umesh.h b/kernel/protocols/mesh/include/umesh.h index bb6bc0ede2..a89686d259 100644 --- a/kernel/protocols/mesh/include/umesh.h +++ b/kernel/protocols/mesh/include/umesh.h @@ -9,6 +9,7 @@ extern "C" { #endif +#include "umesh_config.h" #include "umesh_types.h" ur_error_t umesh_output_sid(struct pbuf *buf, uint16_t netid, uint16_t sid); diff --git a/kernel/protocols/mesh/include/umesh_config.h b/kernel/protocols/mesh/include/umesh_config.h new file mode 100644 index 0000000000..5a7c0649cb --- /dev/null +++ b/kernel/protocols/mesh/include/umesh_config.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#ifndef UMESH_CONFIG_H +#define UMESH_CONFIG_H + +#define MAX_NEIGHBORS_NUM 32 + +#define ATTACH_REQUEST_RETRY_TIMES 2 +#define ATTACH_REQUEST_INTERVAL 1000 + +#ifdef CONFIG_AOS_MESH_LOWPOWER +#define SCHEDULE_SLOTS_SIZE 3 +#define SCHEDULE_SLOT_INTERVAL 6000 +#endif + +#ifdef CONFIG_AOS_MESH_AUTH +#define AUTH_REQUEST_RETRY_TIMES 2 +#define AUTH_RELAY_RETRY_TIMES 2 +#endif + +#endif diff --git a/kernel/protocols/mesh/include/umesh_hal.h b/kernel/protocols/mesh/include/umesh_hal.h index b5d7d8a534..bbea226ac7 100644 --- a/kernel/protocols/mesh/include/umesh_hal.h +++ b/kernel/protocols/mesh/include/umesh_hal.h @@ -57,10 +57,10 @@ typedef void (*umesh_cli_input_t)(const uint8_t *buf, uint16_t length); typedef struct umesh_hal_module_s { struct { - dlist_t list; - int magic; + dlist_t list; + int magic; const char *name; - void *priv_dev; /* Driver may want to describe it */ + void *priv_dev; /* Driver may want to describe it */ } base; media_type_t type; umesh_handle_received_frame_t receiver; diff --git a/kernel/protocols/mesh/include/umesh_types.h b/kernel/protocols/mesh/include/umesh_types.h index 5a1fa1012d..5ac1535159 100644 --- a/kernel/protocols/mesh/include/umesh_types.h +++ b/kernel/protocols/mesh/include/umesh_types.h @@ -27,11 +27,11 @@ typedef enum ur_error_s { UR_ERROR_ROUTE = 5, UR_ERROR_PARSE = 6, UR_ERROR_ADDRESS_QUERY = 7, - UR_ERROR_BUFFER = 8, + UR_ERROR_BUFFER = 8, } ur_error_t; typedef enum media_type_s { - MEDIA_TYPE_DFL = 0, + MEDIA_TYPE_DFL = 0, MEDIA_TYPE_WIFI = 1, MEDIA_TYPE_BLE = 2, MEDIA_TYPE_15_4 = 3, @@ -49,12 +49,12 @@ enum { enum { SHORT_ADDR_SIZE = 2, EXT_ADDR_SIZE = 8, - EXT_NETID_SIZE = 6, + EXT_NETID_SIZE = 6, }; typedef struct ur_ip6_addr_s { union { - uint8_t m8[UR_IP6_ADDR_SIZE]; + uint8_t m8[UR_IP6_ADDR_SIZE]; uint16_t m16[UR_IP6_ADDR_SIZE / sizeof(uint16_t)]; uint32_t m32[UR_IP6_ADDR_SIZE / sizeof(uint32_t)]; }; @@ -62,7 +62,7 @@ typedef struct ur_ip6_addr_s { typedef struct ur_ip4_addr_s { union { - uint8_t m8[MESH_IP4_ADDR_SIZE]; + uint8_t m8[MESH_IP4_ADDR_SIZE]; uint16_t m16[MESH_IP4_ADDR_SIZE / sizeof(uint16_t)]; uint32_t m32; }; @@ -70,20 +70,20 @@ typedef struct ur_ip4_addr_s { typedef struct ur_ip6_prefix_s { ur_ip6_addr_t prefix; - uint8_t length; + uint8_t length; } __attribute__((packed)) ur_ip6_prefix_t; enum { - UR_IP6_HLEN = 40, + UR_IP6_HLEN = 40, MESH_IP4_HLEN = 20, - UR_UDP_HLEN = 8, + UR_UDP_HLEN = 8, }; typedef struct mac_address_s { union { uint64_t value; uint16_t short_addr; - uint8_t addr[EXT_ADDR_SIZE]; + uint8_t addr[EXT_ADDR_SIZE]; }; uint8_t len; } mac_address_t; @@ -98,30 +98,17 @@ typedef struct umesh_extnetid_s { uint8_t len; } umesh_extnetid_t; -enum { - KEY_SIZE = 16, // bytes - - INVALID_KEY_INDEX = 0xff, - ONE_TIME_KEY_INDEX = 0, - GROUP_KEY1_INDEX = 1, -}; - -typedef struct mesh_key_s { - uint8_t len; - uint8_t key[KEY_SIZE]; -} mesh_key_t; - typedef struct frame_s { - uint8_t *data; + uint8_t *data; uint16_t len; uint8_t key_index; } frame_t; typedef struct frame_info_s { mac_address_t peer; - uint8_t channel; - int8_t rssi; - int8_t key_index; + uint8_t channel; + int8_t rssi; + int8_t key_index; } frame_info_t; typedef struct channel_s { @@ -164,38 +151,38 @@ typedef struct ur_link_stats_s { uint16_t send_queue_size; uint16_t recv_queue_size; - bool sending; + bool sending; uint16_t sending_timeouts; } ur_link_stats_t; enum { - UMESH_1 = 0, // 0 - MESH_FORWARDER_1, // 1 - MESH_FORWARDER_2, // 2 - MESH_FORWARDER_3, // 3 - MESH_MGMT_1, // 4 - MESH_MGMT_2, // 5 - MESH_MGMT_3, // 6 - MESH_MGMT_4, // 7 - MESH_MGMT_5, // 8 - MESH_MGMT_6, // 9 - MESH_MGMT_7, // 10 - ADDRESS_MGMT_1, // 11 - ADDRESS_MGMT_2, // 12 - ADDRESS_MGMT_3, // 13 - ADDRESS_MGMT_4, // 14 - NETWORK_MGMT_1, // 15 - NETWORK_MGMT_2, // 16 - LOWPAN6_2, // 18 - LINK_MGMT_1, // 19 - LINK_MGMT_2, // 20 - LINK_MGMT_3, // 21 - ROUTER_MGR_1, // 22 - DIAGS_1, // 23 - DIAGS_2, // 24 - UT_MSG, // 25 - UMESH_2, - MSG_DEBUG_INFO_SIZE, + UMESH_1, // 0 + MESH_FORWARDER_1, // 1 + MESH_FORWARDER_2, // 2 + MESH_FORWARDER_3, // 3 + MESH_MGMT_1, // 4 + MESH_MGMT_2, // 5 + MESH_MGMT_3, // 6 + MESH_MGMT_4, // 7 + MESH_MGMT_5, // 8 + MESH_MGMT_6, // 9 + MESH_MGMT_7, // 10 + ADDRESS_MGMT_1, // 11 + ADDRESS_MGMT_2, // 12 + ADDRESS_MGMT_3, // 13 + ADDRESS_MGMT_4, // 14 + NETWORK_MGMT_1, // 15 + NETWORK_MGMT_2, // 16 + LOWPAN6_2, // 18 + LINK_MGMT_1, // 19 + LINK_MGMT_2, // 20 + LINK_MGMT_3, // 21 + ROUTER_MGR_1, // 22 + DIAGS_1, // 23 + DIAGS_2, // 24 + UT_MSG, // 25 + UMESH_2, // 26 + MSG_DEBUG_INFO_SIZE, // 27 }; typedef struct ur_message_stats_s { @@ -217,13 +204,13 @@ enum { }; typedef enum node_mode_s { - MODE_NONE = 0x00, // this is for testing that not joining net - MODE_MOBILE = 0x01, + MODE_NONE = 0x00, // this is for testing that not joining net + MODE_MOBILE = 0x01, MODE_LOW_MASK = 0x0f, - MODE_RX_ON = 0x10, - MODE_SUPER = 0x20, - MODE_LEADER = 0x40, - MODE_HI_MASK = 0xf0, + MODE_RX_ON = 0x10, + MODE_SUPER = 0x20, + MODE_LEADER = 0x40, + MODE_HI_MASK = 0xf0, } node_mode_t; typedef enum node_state_s { @@ -238,18 +225,21 @@ typedef enum node_state_s { typedef struct whitelist_entry_s { mac_address_t address; - int8_t rssi; - bool valid; - bool constant_rssi; + int8_t rssi; + bool valid; + bool constant_rssi; } whitelist_entry_t; /* mesh events code */ -#define CODE_MESH_STARTED 1 -#define CODE_MESH_ATTACHED 2 -#define CODE_MESH_DETACHED 3 -#define CODE_MESH_CONNECTED 4 -#define CODE_MESH_DISCONNECTED 5 -#define CODE_MESH_DATA_RECV 6 +#define CODE_MESH_STARTED 1 +#define CODE_MESH_ATTACHED 2 +#define CODE_MESH_DETACHED 3 +#define CODE_MESH_CONNECTED 4 +#define CODE_MESH_DISCONNECTED 5 +#define CODE_MESH_DATA_RECV 6 +#define CODE_MESH_PSCHED_UP 7 +#define CODE_MESH_ASCHED_UP 8 +#define CODE_MESH_SCHED_DOWN 9 #ifdef __cplusplus } diff --git a/kernel/protocols/mesh/lib/arm968es/libmesh.a b/kernel/protocols/mesh/lib/arm968es/libmesh.a index df616667f5..f70a022a42 100644 Binary files a/kernel/protocols/mesh/lib/arm968es/libmesh.a and b/kernel/protocols/mesh/lib/arm968es/libmesh.a differ diff --git a/kernel/protocols/mesh/lib/linux/libmesh.a b/kernel/protocols/mesh/lib/linux/libmesh.a index f6af7a4ac0..78e95d0af2 100644 Binary files a/kernel/protocols/mesh/lib/linux/libmesh.a and b/kernel/protocols/mesh/lib/linux/libmesh.a differ diff --git a/kernel/protocols/mesh/lib/xtensa/libmesh.a b/kernel/protocols/mesh/lib/xtensa/libmesh.a index 843e8d6c8a..4a02d7b96a 100644 Binary files a/kernel/protocols/mesh/lib/xtensa/libmesh.a and b/kernel/protocols/mesh/lib/xtensa/libmesh.a differ diff --git a/kernel/protocols/net/apps/lwiperf/iperf_cli.c b/kernel/protocols/net/apps/lwiperf/iperf_cli.c new file mode 100755 index 0000000000..53db16a6c0 --- /dev/null +++ b/kernel/protocols/net/apps/lwiperf/iperf_cli.c @@ -0,0 +1,253 @@ + +#include "mico.h" +//#include "platform_assert.h" +#include "iperf_debug.h" +#include "iperf_task.h" + +/****************************************************** + * Macros + ******************************************************/ + +/****************************************************** + * Constants + ******************************************************/ + + +/****************************************************** + * Enumerations + ******************************************************/ + +/****************************************************** + * Type Definitions + ******************************************************/ + +/****************************************************** + * Structures + ******************************************************/ +void iperf_Command( char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv ); + +struct cli_command iperf_test_message_cmd[] = { + { "iperf", "iperf test", iperf_Command }, +}; + +/****************************************************** + * Function Declarations + ******************************************************/ +static void iperf_udp_run_server_thread( mico_thread_arg_t arg ); +static void iperf_tcp_run_server_thread( mico_thread_arg_t arg ); +static void iperf_udp_run_client_thread( mico_thread_arg_t arg ); +static void iperf_tcp_run_client_thread( mico_thread_arg_t arg ); + +static void _cli_iperf_server_Command( int argc, char **argv ); +static void _cli_iperf_client_Command( int argc, char **argv ); +static void _cli_iperf_help_Command( int argc, char **argv ); + +/****************************************************** + * Variables Definitions + ******************************************************/ + +/****************************************************** + * Function Definitions + ******************************************************/ + +static void iperf_udp_run_server_thread( mico_thread_arg_t arg ) +{ + iperf_udp_run_server( (char **) arg ); +} + +static void iperf_tcp_run_server_thread( mico_thread_arg_t arg ) +{ + iperf_tcp_run_server( (char **) arg ); +} + +static void iperf_udp_run_client_thread( mico_thread_arg_t arg ) +{ + iperf_udp_run_client( (char **) arg ); +} + +static void iperf_tcp_run_client_thread( mico_thread_arg_t arg ) +{ + iperf_tcp_run_client( (char **) arg ); +} + +static void _cli_iperf_server_Command( int argc, char **argv ) +{ + int i; + char **g_iperf_param = NULL; + int is_create_task = 0; + int offset = IPERF_COMMAND_BUFFER_SIZE / sizeof(char *); + g_iperf_param = malloc( IPERF_COMMAND_BUFFER_NUM * IPERF_COMMAND_BUFFER_SIZE ); + if ( g_iperf_param == NULL ) + { + printf( "Warning: No enough memory to running iperf.\r\n" ); + } + memset( g_iperf_param, 0, IPERF_COMMAND_BUFFER_NUM * IPERF_COMMAND_BUFFER_SIZE ); + + for ( i = 0; i < argc; i++ ) + { + strcpy( (char *) &g_iperf_param[i * offset], argv[i] ); +#if defined(IPERF_DEBUG_INTERNAL) + printf("_cli_iperf_client, g_iperf_param[%d] is \"%s\"\r\n", i, (char *)&g_iperf_param[i * offset]); +#endif + } + + for ( i = 0; i < argc; i++ ) + { + if ( strcmp( argv[i], "-u" ) == 0 ) + { + printf( "Iperf UDP Server: Start!\r\n" ); + printf( "Iperf UDP Server Receive Timeout = 20 (secs)\r\n" ); + mico_rtos_create_thread( NULL, IPERF_PRIO, IPERF_NAME, iperf_udp_run_server_thread, IPERF_STACKSIZE, + (mico_thread_arg_t) g_iperf_param ); + is_create_task = 1; + break; + } + } + if ( strcmp( argv[i], "-u" ) != 0 ) + { + printf( "Iperf TCP Server: Start!\r\n" ); + printf( "Iperf TCP Server Receive Timeout = 20 (secs)\r\n" ); + mico_rtos_create_thread( NULL, IPERF_PRIO, IPERF_NAME, iperf_tcp_run_server_thread, IPERF_STACKSIZE, + (mico_thread_arg_t) g_iperf_param ); + is_create_task = 1; + } + + if ( is_create_task == 0 ) + { + free( g_iperf_param ); + } +} + +static void _cli_iperf_client_Command( int argc, char **argv ) +{ + int i; + char **g_iperf_param = NULL; + int is_create_task = 0; + int offset = IPERF_COMMAND_BUFFER_SIZE / sizeof(char *); + + g_iperf_param = malloc( IPERF_COMMAND_BUFFER_NUM * IPERF_COMMAND_BUFFER_SIZE ); + if ( g_iperf_param == NULL ) + { + printf( "Warning: No enough memory to running iperf.\r\n" ); + } + memset( g_iperf_param, 0, IPERF_COMMAND_BUFFER_NUM * IPERF_COMMAND_BUFFER_SIZE ); + for ( i = 0; i < argc; i++ ) + { + strcpy( (char *) &g_iperf_param[i * offset], argv[i] ); +#if defined(IPERF_DEBUG_INTERNAL) + printf("_cli_iperf_client, g_iperf_param[%d] is \"%s\"\r\n", i, (char *)&g_iperf_param[i * offset]); +#endif + } + + for ( i = 0; i < argc; i++ ) + { + if ( strcmp( argv[i], "-u" ) == 0 ) + { + printf( "Iperf UDP Client: Start!\r\n" ); + mico_rtos_create_thread( NULL, IPERF_PRIO, IPERF_NAME, iperf_udp_run_client_thread, IPERF_STACKSIZE, + (mico_thread_arg_t) g_iperf_param ); + is_create_task = 1; + break; + } + } + + if ( strcmp( argv[i], "-u" ) != 0 ) + { + printf( "Iperf TCP Client: Start!\r\n" ); + mico_rtos_create_thread( NULL, IPERF_PRIO, IPERF_NAME, iperf_tcp_run_client_thread, IPERF_STACKSIZE, + (mico_thread_arg_t) g_iperf_param ); + is_create_task = 1; + } + + if ( is_create_task == 0 ) + { + free( g_iperf_param ); + } +} + +static void _cli_iperf_help_Command( int argc, char **argv ) +{ + printf( "Usage: iperf [-s|-c] [options]\r\n" ); + printf( " iperf [-h]\r\n\n" ); + printf( "Client/Server:\r\n" ); + printf( " -u, use UDP rather than TCP\r\n" ); + printf( " -p, #server port to listen on/connect to (default 5001)\r\n" ); + printf( " -n, #[kmKM] number of bytes to transmit \r\n" ); + printf( " -b, #[kmKM] for UDP, bandwidth to send at in bits/sec\r\n" ); + printf( " -i, 10 seconds between periodic bandwidth reports \r\n\n" ); + printf( "Server specific:\r\n" ); + printf( " -s, run in server mode\r\n" ); + printf( " -B, bind to , and join to a multicast group (only Support UDP)\r\n" ); + printf( " -r, for UDP, run iperf in tradeoff testing mode, connecting back to client\r\n\n" ); + printf( "Client specific:\r\n" ); + printf( " -c, run in client mode, connecting to \r\n" ); + printf( " -w, #[kmKM] TCP window size\r\n" ); + printf( " -l, #[kmKM] UDP datagram size\r\n" ); + printf( " -t, #time in seconds to transmit for (default 10 secs)\r\n" ); + printf( " -S, #the type-of-service of outgoing packets\r\n\n" ); + printf( "Miscellaneous:\r\n" ); + printf( " -h, print this message and quit\r\n\n" ); + printf( "[kmKM] Indicates options that support a k/K or m/M suffix for kilo- or mega-\r\n\n" ); + printf( "TOS options for -S parameter:\r\n" ); + printf( "BE: -S 0\r\n" ); + printf( "BK: -S 32\r\n" ); + printf( "VI: -S 160\r\n" ); + printf( "VO: -S 224\r\n\n" ); + printf( "Tradeoff Testing Mode:\r\n" ); + printf( "Command: iperf -s -u -n -r \r\n\n" ); + printf( "Example:\r\n" ); + printf( "Iperf TCP Server: iperf -s\r\n" ); + printf( "Iperf UDP Server: iperf -s -u\r\n" ); + printf( "Iperf TCP Client: iperf -c -w -t -p \r\n" ); + printf( "Iperf UDP Client: iperf -c -u -l -t -p \r\n" ); +} + +#if defined(MICO_IPERF_DEBUG_ENABLE) +static uint8_t _cli_iperf_debug(int argc, char **argv) +{ + int debug; + debug = atoi(argv[0]); + printf("Set iperf debug to %d(0x%x)\r\n", debug, debug); + iperf_set_debug_mode(debug); + return 0; +} +#endif + +void iperf_Command( char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv ) +{ + if ( argc < 2 ) + { + printf( "Invalid command\r\n" ); + } + if ( strcmp( argv[1], "-s" ) == 0 ) + { + _cli_iperf_server_Command( argc - 2, &argv[2] ); + } + else + if ( strcmp( argv[1], "-c" ) == 0 ) + { + _cli_iperf_client_Command( argc - 2, &argv[2] ); + } + else + if ( strcmp( argv[1], "-h" ) == 0 ) + { + _cli_iperf_help_Command( argc - 2, &argv[2] ); + } +#if defined(MICO_IPERF_DEBUG_ENABLE) + else + if ( strcmp( argv[1], "-d" ) == 0 ) + { + _cli_iperf_debug( argc - 2, &argv[2] ); + } +#endif +} + + +OSStatus iperf_cli_register( void ) +{ + if( 0 == cli_register_commands( iperf_test_message_cmd, 1 ) ) + return kNoErr; + else + return kGeneralErr; +} + diff --git a/kernel/protocols/net/apps/lwiperf/iperf_task.c b/kernel/protocols/net/apps/lwiperf/iperf_task.c new file mode 100755 index 0000000000..af4452fcdd --- /dev/null +++ b/kernel/protocols/net/apps/lwiperf/iperf_task.c @@ -0,0 +1,1270 @@ + +//#include "mico.h" +#include "mico_socket.h" +#include "iperf_task.h" +#include "iperf_debug.h" + +/****************************************************** + * Macros + ******************************************************/ + +//#define IPERF_DEBUG_INTERNAL +#define DBGPRINT_IPERF(FEATURE, _Fmt) \ + { \ + if (g_iperf_debug_feature & FEATURE) \ + { \ + printf _Fmt; \ + } \ + } + +/****************************************************** + * Constants + ******************************************************/ + +#define MAX_WIN_SIZE (20*1024) + +/* Private macro */ +#define IPERF_DEFAULT_PORT 5001 //Port to listen + +#define IPERF_HEADER_VERSION1 0x80000000 +#define IPERF_DEFAULT_UDP_RATE (1024 * 1024) +#define IPERF_TEST_BUFFER_SIZE (2048) + +#define IPERF_DEBUG_RECEIVE (1<<0) +#define IPERF_DEBUG_SEND (1<<1) +#define IPERF_DEBUG_REPORT (1<<2) + +/****************************************************** + * Enumerations + ******************************************************/ + +/****************************************************** + * Type Definitions + ******************************************************/ + +// Private typedef ------------------------------------------------------------- +typedef struct count_s +{ + unsigned Bytes; + unsigned KBytes; + unsigned MBytes; + unsigned GBytes; + unsigned times; +} count_t; + +// used to reference the 4 byte ID number we place in UDP datagrams +// use int32_t if possible, otherwise a 32 bit bitfield (e.g. on J90) +typedef struct UDP_datagram +{ + int32_t id; + unsigned int tv_sec; + unsigned int tv_usec; +} UDP_datagram; + +/* + * The client_hdr structure is sent from clients + * to servers to alert them of things that need + * to happen. Order must be perserved in all + * future releases for backward compatibility. + * 1.7 has flags, num_threads, port, and buffer_len + */ +typedef struct client_hdr +{ + /* + * flags is a bitmap for different options + * the most significant bits are for determining + * which information is available. So 1.7 uses + * 0x80000000 and the next time information is added + * the 1.7 bit will be set and 0x40000000 will be + * set signifying additional information. If no + * information bits are set then the header is ignored. + * The lowest order diferentiates between dualtest and + * tradeoff modes, wheither the speaker needs to start + * immediately or after the audience finishes. + */ + int32_t flags; + int32_t num_threads; + int32_t port; + int32_t buffer_len; + int32_t win_band; + int32_t amount; +} client_hdr; + +/* + * The server_hdr structure facilitates the server + * report of jitter and loss on the client side. + * It piggy_backs on the existing clear to close + * packet. + */ +typedef struct server_hdr +{ + /* + * flags is a bitmap for different options + * the most significant bits are for determining + * which information is available. So 1.7 uses + * 0x80000000 and the next time information is added + * the 1.7 bit will be set and 0x40000000 will be + * set signifying additional information. If no + * information bits are set then the header is ignored. + */ + int32_t flags; + int32_t total_len1; + int32_t total_len2; + int32_t stop_sec; + int32_t stop_usec; + int32_t error_cnt; + int32_t outorder_cnt; + int32_t datagrams; + int32_t jitter1; + int32_t jitter2; +} server_hdr; + +/****************************************************** + * Structures + ******************************************************/ + +/****************************************************** + * Function Declarations + ******************************************************/ + +count_t iperf_calculate_result( int pkt_size, count_t pkt_count, int need_to_convert ); +void iperf_display_report( char *report_title, unsigned time, unsigned h_ms_time, count_t pkt_count ); +count_t iperf_reset_count( count_t pkt_count ); +count_t iperf_copy_count( count_t pkt_count, count_t tmp_count ); +count_t iperf_diff_count( count_t pkt_count, count_t tmp_count ); +int iperf_format_transform( char *param ); + +/****************************************************** + * Variables Definitions + ******************************************************/ + +uint32_t g_iperf_debug_feature = 0; +int g_iperf_is_tradeoff_test_client = 0; +int g_iperf_is_tradeoff_test_server = 0; +uint32_t g_iperf_server_addr = 0; + +/****************************************************** + * Function Definitions + ******************************************************/ +/* members are in network byte order */ +void iperf_udp_run_server( char *parameters[] ) +{ + + int sockfd; + struct sockaddr_in servaddr; + struct sockaddr_in cliaddr; + int cli_len; + struct ip_mreq group; + int server_port; + int i; + count_t pkt_count; + count_t tmp_count; + int nbytes = 0; /* the number of read */ + int total_send = 0; /* the total number of send */ + int mcast_tag = 0; /* the tag of parameter "-B" */ + int interval_tag = 0; /* the tag of parameter "-i" */ + char *mcast; +#if defined(MICO_IPERF_DEBUG_ENABLE) + int send_bytes = 0; /* the number of send */ + int tmp = 0; +#endif + char *buffer = (char*) malloc( IPERF_TEST_BUFFER_SIZE ); + + uint32_t t1, t2, curr_t, curr_h_ms, t2_h_ms, t1_h_ms, tmp_t, tmp_h_ms, offset_t1, offset_t2, offset_time; + UDP_datagram *udp_h; + client_hdr *client_h; + client_hdr client_h_trans; + uint32_t timeout; + timeout = 20 * 1000; //set recvive timeout = 20(sec) + int is_test_started = 0; + int udp_h_id = 0; + + memset( buffer, 0, IPERF_TEST_BUFFER_SIZE ); + //Statistics init + pkt_count = iperf_reset_count( pkt_count ); + tmp_count = iperf_reset_count( tmp_count ); + server_port = 0; + t1 = 0; + t2 = 0; + int offset = IPERF_COMMAND_BUFFER_SIZE / sizeof(char *); + + //Handle input parameters + if ( g_iperf_is_tradeoff_test_client == 0 ) { + for ( i = 0; i < 13; i++ ) { + if ( strcmp( (char *) ¶meters[i * offset], "-p" ) == 0 ) { + i++; + server_port = atoi( (char *) ¶meters[i * offset] ); + } else if ( strcmp( (char *) ¶meters[i * offset], "-n" ) == 0 ) { + i++; + total_send = iperf_format_transform( (char *) ¶meters[i * offset] ); + printf( "Set number to transmit = %d Bytes\r\n", total_send ); + } else if ( strcmp( (char *) ¶meters[i * offset], "-B" ) == 0 ) { + i++; + mcast = (char *) ¶meters[i * offset]; + mcast_tag = 1; + printf( "Join Multicast %s \r\n", mcast ); + } else if ( strcmp( (char *) ¶meters[i * offset], "-i" ) == 0 ) { + interval_tag = 1; + printf( "Set 10 seconds between periodic bandwidth reports\r\n" ); + } + } + } + + // Create a new UDP connection handle + if ( (sockfd = socket( AF_INET, SOCK_DGRAM, 0 )) < 0 ) { + printf( "[%s:%d] sockfd = %d\r\n", __FUNCTION__, __LINE__, sockfd ); + if ( parameters ) { + free( parameters ); + } + mico_rtos_delete_thread( NULL ); + } + + socklen_t len = sizeof(timeout); + if ( setsockopt( sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *) &timeout, len ) < 0 ) { + printf( "Setsockopt failed - cancel receive timeout\r\n" ); + } + + // Bind to port and any IP address + memset( &servaddr, 0, sizeof(servaddr) ); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl( INADDR_ANY ); + if ( server_port == 0 ) { + servaddr.sin_port = htons( IPERF_DEFAULT_PORT ); + printf( "Default server port = %d \r\n", IPERF_DEFAULT_PORT ); + } else { + servaddr.sin_port = htons( server_port ); + printf( "Set server port = %d \r\n", server_port ); + } + + //Multicast settings + if ( mcast_tag == 1 ) { + group.imr_multiaddr.s_addr = inet_addr( mcast ); + group.imr_interface.s_addr = htonl( INADDR_ANY ); + + if ( setsockopt( sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *) &group, sizeof(struct ip_mreq) ) < 0 ) { + printf( "Setsockopt failed - multicast settings\r\n" ); + } + } + + if ( (bind( sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr) )) < 0 ) { + printf( "[%s:%d]\r\n", __FUNCTION__, __LINE__ ); + if ( parameters ) { + free( parameters ); + } + mico_rtos_delete_thread( NULL ); + } + + cli_len = sizeof(cliaddr); + + // Wait and check the request + do { + // Handles request + do { + iperf_get_current_time( &offset_t1, 0 ); + nbytes = recvfrom( sockfd, buffer, IPERF_TEST_BUFFER_SIZE, 0, (struct sockaddr *) &cliaddr, + (socklen_t *) &cli_len ); + iperf_get_current_time( &offset_t2, 0 ); + + //if connected to iperf v2.0.1, there is no end package sent from client side + if ( (offset_t2 > (offset_t1 + 2)) && (nbytes <= 0) && (pkt_count.times >= 1) ) { + offset_time = offset_t2 - offset_t1; + } else if ( offset_time != 0 ) { + offset_time = 0; + } + + udp_h = (UDP_datagram *) buffer; + udp_h_id = (int) ntohl( udp_h->id ); + +#if defined(IPERF_DEBUG_INTERNAL) + client_h = (client_hdr *)&buffer[12]; + client_h_trans.flags = (int32_t)(ntohl(client_h->flags)); + client_h_trans.num_threads = (int32_t)(ntohl(client_h->num_threads)); + client_h_trans.port = (int32_t)(ntohl(client_h->port)); + client_h_trans.buffer_len = (int32_t)(ntohl(client_h->buffer_len)); + client_h_trans.win_band = (int32_t)(ntohl(client_h->win_band)); + client_h_trans.amount = (int32_t)(ntohl(client_h->amount)); + + DBGPRINT_IPERF(IPERF_DEBUG_RECEIVE, ("UDP server, receive from sockfd \"%d\", id is \"%d\", tv_sec is \"%d\", tv_usec is \"%d\", nbytes is \"%d\"\r\n", + sockfd, udp_h_id, ntohl(udp_h->tv_sec), ntohl(udp_h->tv_usec), nbytes)); + DBGPRINT_IPERF(IPERF_DEBUG_RECEIVE, ("UDP server, receive from sin_len = %d, sin_family = %d , port = %d, s_addr = 0x%x\n", cliaddr.sin_len, cliaddr.sin_family, + cliaddr.sin_port, cliaddr.sin_addr.s_addr)); + DBGPRINT_IPERF(IPERF_DEBUG_RECEIVE, ("[%s:%d] t1 = %d, t2 = %d\n", __FUNCTION__, __LINE__, t1, t2)); + + DBGPRINT_IPERF(IPERF_DEBUG_RECEIVE, ("[%s:%d], client_h_trans.flag = %d, num_threads = %d, port = %d, buffer_len = %d, win_band = %d, amount = %d\n" + , __FUNCTION__, __LINE__, client_h_trans.flags, client_h_trans.num_threads, client_h_trans.port, client_h_trans.buffer_len, client_h_trans.win_band, client_h_trans.amount)); +#endif + +#if defined(MICO_IPERF_DEBUG_ENABLE) + if (tmp != nbytes) { + DBGPRINT_IPERF(IPERF_DEBUG_RECEIVE, ("\r\n[%s:%d] nbytes=%d \r\n", __FUNCTION__, __LINE__, nbytes)); + } else { + DBGPRINT_IPERF(IPERF_DEBUG_RECEIVE, (".")); + } + tmp = nbytes; +#endif + + pkt_count = iperf_calculate_result( nbytes, pkt_count, 0 ); + + if ( pkt_count.times == 1 ) { + iperf_get_current_time( &t1, &t1_h_ms ); + t1_h_ms = (t1_h_ms / 100) % 10; + } + + // Report by second + if ( (pkt_count.times >= 1 && interval_tag > 0) ) { + iperf_get_current_time( &curr_t, &curr_h_ms ); + curr_h_ms = (curr_h_ms / 100) % 10; + + if ( offset_time > 0 ) { + curr_t -= offset_time; + } + + if ( curr_h_ms >= t1_h_ms ) { + tmp_h_ms = curr_h_ms - t1_h_ms; + tmp_t = curr_t - t1; + } else { + tmp_h_ms = curr_h_ms + 10 - t1_h_ms; + tmp_t = curr_t - t1 - 1; + } + + if ( (((int)(curr_t - t1) / 10) == interval_tag) && ((curr_h_ms >= t1_h_ms) || ((curr_t - t1) % 10) >= 1) ) { + printf( "\r\nInterval: %d.0 - %d.0 sec ", (int) (curr_t - t1) / 10 * 10 - 10, + (int) (curr_t - t1) / 10 * 10 ); + iperf_display_report( "UDP Server", 10, 0, iperf_diff_count( pkt_count, tmp_count ) ); + tmp_count = iperf_copy_count( pkt_count, tmp_count ); + interval_tag++; + } else if ( ((udp_h_id < 0) || (nbytes <= 0)) && + (((tmp_t) % 10) != 0) + && + (is_test_started == 1) ) { + printf( "\r\nInterval: %d.0 - %d.%d sec ", (int) (curr_t - t1 + 1) / 10 * 10 - 10, (int) tmp_t, + (int) tmp_h_ms ); + iperf_display_report( "UDP Server", (tmp_t - ((curr_t - t1 + 1) / 10 * 10 - 10)), tmp_h_ms, + iperf_diff_count( pkt_count, tmp_count ) ); + tmp_count = iperf_copy_count( pkt_count, tmp_count ); + interval_tag++; + } + } + + if ( (is_test_started == 0) && (udp_h_id > 0) && (nbytes > 0) ) { + is_test_started = 1; + } else if ( ((udp_h_id < 0) || (nbytes <= 0)) && (is_test_started == 1) ) { // the last package + int32_t old_flag = 0; + + // test end, save the current time to "t2" + if ( pkt_count.times >= 1 ) { + /* sync the time if report by second */ + if ( interval_tag > 0 ) { + t2 = curr_t; + t2_h_ms = curr_h_ms; + } else { + iperf_get_current_time( &t2, &t2_h_ms ); + t2_h_ms = (t2_h_ms / 100) % 10; + if ( offset_time > 0 ) { + t2 -= offset_time; + } + } + } + + // Calculate time: second + if ( t2_h_ms >= t1_h_ms ) { + t2_h_ms = t2_h_ms - t1_h_ms; + t2 = t2 - t1; + } else { + t2_h_ms = t2_h_ms + 10 - t1_h_ms; + t2 = t2 - t1 - 1; + } + // print out result + iperf_display_report( "[Total]UDP Server", t2, t2_h_ms, pkt_count ); + + //TODO: need to send the correct report to client-side, flag = 0 means the report is ignored. + if ( udp_h_id < 0 ) { + old_flag = client_h_trans.flags; + client_h_trans.flags = (int32_t) 0; + + // send the server report to client-side +#if defined(MICO_IPERF_DEBUG_ENABLE) + send_bytes = +#endif + sendto( sockfd, buffer, nbytes, 0, (struct sockaddr *) &cliaddr, cli_len ); + client_h_trans.flags = old_flag; + } + +#if defined(MICO_IPERF_DEBUG_ENABLE) + DBGPRINT_IPERF(IPERF_DEBUG_RECEIVE, ("[%s:%d]send_bytes = %d, nbytes = %d,\r\n", __FUNCTION__, __LINE__, send_bytes, nbytes)); +#endif + + client_h = (client_hdr *) &buffer[12]; + client_h_trans.flags = (int32_t) (ntohl( client_h->flags )); + + // Tradeoff mode + if ( IPERF_HEADER_VERSION1 & client_h_trans.flags ) { + printf( "Tradeoff mode, client-side start.\r\n" ); + + g_iperf_is_tradeoff_test_server = 1; + g_iperf_server_addr = cliaddr.sin_addr.s_addr; + iperf_udp_run_client( NULL ); + g_iperf_is_tradeoff_test_server = 0; + + } + + printf( "Data transfer is finished.\r\n" ); + //TODO: send report to other side + break; + } + } while ( nbytes > 0 ); + +#if defined(MICO_IPERF_DEBUG_ENABLE) + DBGPRINT_IPERF(IPERF_DEBUG_RECEIVE, ("[%s:%d] Interval = %d.%d (secs)\r\n", __FUNCTION__, __LINE__, t2, t2_h_ms)); //sec. +#endif + + } while ( 0 ); + + printf( "\r\n UDP server close socket!\r\n" ); + close( sockfd ); + + printf( "If you want to execute iperf server again, please enter \"iperf -s -u\".\r\n" ); + + if ( parameters ) { + free( parameters ); + } + free( buffer ); + // For tradeoff mode, task will be deleted in iperf_udp_run_client + if ( g_iperf_is_tradeoff_test_client == 0 ) { + mico_rtos_delete_thread( NULL ); + } +} + +void iperf_tcp_run_server( char *parameters[] ) +{ + int listenfd, connfd; + struct sockaddr_in servaddr, cliaddr; + socklen_t clilen; + int server_port; + int i; + count_t pkt_count; + count_t tmp_count; + int nbytes = 0; /* the number of read */ + int total_rcv = 0; /* the total number of receive */ + int num_tag = 0; /* the tag of parameter "-n" */ + int interval_tag = 0; /* the tag of parameter "-i" */ +#if defined(MICO_IPERF_DEBUG_ENABLE) + int tmp = 0; +#endif + uint32_t t1, t2, curr_t; + int offset = IPERF_COMMAND_BUFFER_SIZE / sizeof(char *); + char *buffer = (char*) malloc( IPERF_TEST_BUFFER_SIZE ); + uint32_t timeout; + timeout = 20 * 1000; //set recvive timeout = 20(sec) + + memset( buffer, 0, IPERF_TEST_BUFFER_SIZE ); + //Statistics init + pkt_count = iperf_reset_count( pkt_count ); + tmp_count = iperf_reset_count( tmp_count ); + server_port = 0; + + //Handle input parameters + for ( i = 0; i < 9; i++ ) { + if ( strcmp( (char *) ¶meters[i * offset], "-p" ) == 0 ) { + i++; + server_port = atoi( (char *) ¶meters[i * offset] ); + } else if ( strcmp( (char *) ¶meters[i * offset], "-n" ) == 0 ) { + i++; + total_rcv = iperf_format_transform( (char *) ¶meters[i * offset] ); + num_tag = 1; + printf( "Set number to receive = %d Bytes \r\n", total_rcv ); + } else + if ( strcmp( (char *) ¶meters[i * offset], "-i" ) == 0 ) + { + interval_tag = 1; + printf( "Set 10 seconds between periodic bandwidth reports \r\n" ); + } + } + + // Create a new TCP connection handle + if ( (listenfd = socket( AF_INET, SOCK_STREAM, 0 )) < 0 ) { + printf( "[%s:%d] listenfd = %d \r\n", __FUNCTION__, __LINE__, listenfd ); + if ( parameters ) { + free( parameters ); + } + mico_rtos_delete_thread( NULL ); + } + + socklen_t len = sizeof(timeout); + if ( setsockopt( listenfd, SOL_SOCKET, SO_RCVTIMEO, (char *) &timeout, len ) < 0 ) { + printf( "Setsockopt failed - cancel receive timeout \r\n" ); + } + + do { + // Bind to port and any IP address + memset( &servaddr, 0, sizeof(servaddr) ); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl( INADDR_ANY ); + if ( server_port == 0 ) + { + servaddr.sin_port = htons( IPERF_DEFAULT_PORT ); + printf( "Default server port = %d \r\n", IPERF_DEFAULT_PORT ); + } + else + { + servaddr.sin_port = htons( server_port ); + printf( "Set server port = %d \r\n", server_port ); + } + + if ( (bind( listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr) )) < 0 ) { + printf( "[%s:%d] \r\n", __FUNCTION__, __LINE__ ); + break; + } + + // Put the connection into LISTEN state + if ( (listen( listenfd, 1024 )) < 0 ) { + printf( "[%s:%d] \r\n", __FUNCTION__, __LINE__ ); + break; + } + + do { + if ( server_port != 0 ) { + printf( "Listen...(port = %d) \r\n", server_port ); + } else { + printf( "Listen...(port = %d) \r\n", IPERF_DEFAULT_PORT ); + } + // Block and wait for an incoming connection + if ( (connfd = accept( listenfd, (struct sockaddr *) &cliaddr, &clilen )) != -1 ) + { + printf( "[%s:%d] Accept... (sockfd=%d) \r\n", __FUNCTION__, __LINE__, connfd ); + + //Connection + do { + nbytes = recv( connfd, buffer, IPERF_TEST_BUFFER_SIZE, 0 ); + pkt_count = iperf_calculate_result( nbytes, pkt_count, 0 ); + if ( pkt_count.times == 1 ) { + iperf_get_current_time( &t1, 0 ); + } +#if defined(MICO_IPERF_DEBUG_ENABLE) + if (tmp != nbytes) { + DBGPRINT_IPERF(IPERF_DEBUG_RECEIVE, ("\r\n[%s:%d] nbytes=%d \r\n", __FUNCTION__, __LINE__, nbytes)); + } else { + DBGPRINT_IPERF(IPERF_DEBUG_RECEIVE, (".")); + } + tmp = nbytes; +#endif + if ( num_tag == 1 ) { + total_rcv -= nbytes; + } + + //Reach total receive number "-n" + if ( total_rcv < 0 ) { + printf( "Finish Receiving \r\n" ); + break; + } + if ( pkt_count.times >= 1 && interval_tag > 0 ) { + iperf_get_current_time( &curr_t, 0 ); + if ( ((int)(curr_t - t1) / 10) == interval_tag ) { + printf( "\r\nInterval: %d - %d sec ", (int) (curr_t - t1) / 10 * 10 - 10, + (int) (curr_t - t1) / 10 * 10 ); + iperf_display_report( "TCP Server", 10, 0, iperf_diff_count( pkt_count, tmp_count ) ); + tmp_count = iperf_copy_count( pkt_count, tmp_count ); + interval_tag++; + } + } + } while ( nbytes > 0 ); + + if ( pkt_count.times >= 1 ) { + iperf_get_current_time( &t2, 0 ); + } + + printf( "\r\nClose socket!\r\n" ); + //Get report + iperf_display_report( "[Total]TCP Server", t2 - t1, 0, pkt_count ); + + //Statistics init + pkt_count = iperf_reset_count( pkt_count ); + tmp_count = iperf_reset_count( tmp_count ); + if ( interval_tag > 0 ) { + interval_tag = 1; + } else { + interval_tag = 0; + } + close( connfd ); + } + } while ( connfd != -1 && num_tag == 0 ); + + close( listenfd ); + if ( num_tag == 0 ) { + printf( "\r\nClose socket!\r\n" ); + iperf_display_report( "[Total]TCP Server ", t2 - t1, 0, pkt_count ); + } + } while ( 0 ); //Loop just once + printf( "If you want to execute iperf server again, please enter \"iperf -s\".\r\n" ); + + if ( parameters ) + { + free( parameters ); + } + free( buffer ); + mico_rtos_delete_thread( NULL ); + +} + +void iperf_tcp_run_client( char *parameters[] ) +{ + int sockfd; + struct sockaddr_in servaddr; + char *Server_IP; + count_t pkt_count; + count_t tmp_count; + int nbytes = 0; /* the number of send */ + int total_send = 0; /* the total number of transmit */ + int num_tag = 0; /* the tag of parameter "-n" */ + int interval_tag = 0; /* the tag of parameter "-i" */ + int i; + int win_size, send_time, server_port, pkt_delay, tos; + uint32_t t1, t2, curr_t; + int offset = IPERF_COMMAND_BUFFER_SIZE / sizeof(char *); + char *buffer = (char*) malloc( IPERF_TEST_BUFFER_SIZE ); + pkt_count = iperf_reset_count( pkt_count ); + tmp_count = iperf_reset_count( tmp_count ); + win_size = 0; + send_time = 0; + server_port = 0; + pkt_delay = 0; + tos = 0; + memset( buffer, 0, IPERF_TEST_BUFFER_SIZE ); + //Handle input parameters + Server_IP = (char *) ¶meters[0]; + printf( "Servr IP %s \r\n", Server_IP ); + for ( i = 1; i < 18; i++ ) + { + if ( strcmp( (char *) ¶meters[i * offset], "-w" ) == 0 ) + { + i++; + win_size = iperf_format_transform( (char *) ¶meters[i * offset] ); + if ( win_size > MAX_WIN_SIZE ) + { + printf( "Win size too big, set to %d \r\n", MAX_WIN_SIZE ); + win_size = MAX_WIN_SIZE; + } + printf( "Set window size = %d Bytes\n", win_size ); + } + + else if ( strcmp( (char *) ¶meters[i * offset], "-t" ) == 0 ) + { + i++; + send_time = atoi( (char *) ¶meters[i * offset] ); + printf( "Set send times = %d (secs)\r\n", atoi( (char *) ¶meters[i * offset] ) ); + + } + + else if ( strcmp( (char *) ¶meters[i * offset], "-p" ) == 0 ) + { + i++; + server_port = atoi( (char *) ¶meters[i * offset] ); + + } + + else if ( strcmp( (char *) ¶meters[i * offset], "-d" ) == 0 ) + { + i++; + pkt_delay = atoi( (char *) ¶meters[i * offset] ); + printf( "Set packet delay = %d (ms)\r\n", atoi( (char *) ¶meters[i * offset] ) ); + + } else if ( strcmp( (char *) ¶meters[i * offset], "-n" ) == 0 ) + { + i++; + total_send = iperf_format_transform( (char *) ¶meters[i * offset] ); + num_tag = 1; + printf( "Set number to transmit = %d Bytes\r\n", total_send ); + } else if ( strcmp( (char *) ¶meters[i * offset], "-S" ) == 0 ) + { + i++; + tos = atoi( (char *) ¶meters[i * offset] ); + printf( "Set TOS = %d \r\n", atoi( (char *) ¶meters[i * offset] ) ); + } else if ( strcmp( (char *) ¶meters[i * offset], "-i" ) == 0 ) + { + interval_tag = 1; + printf( "Set 10 seconds between periodic bandwidth reports\r\n" ); + } + } + + if ( win_size == 0 ) + { + win_size = 1460; + printf( "Default window size = %d Bytes\r\n", win_size ); + } + if ( send_time == 0 ) + { + if ( num_tag == 1 ) + { + send_time = 999999; + } + else + { + send_time = 10; + printf( "Default send times = %d (secs)\r\n", send_time ); + } + } + + // Create a new TCP connection handle + if ( (sockfd = socket( AF_INET, SOCK_STREAM, 0 )) < 0 ) + { + printf( "[%s:%d] sockfd = %d\r\n", __FUNCTION__, __LINE__, sockfd ); + if ( parameters ) { + free( parameters ); + } + mico_rtos_delete_thread( NULL ); + } + + if ( setsockopt( sockfd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos) ) < 0 ) + { + printf( "Set TOS: fail!\r\n" ); + } + // Bind to port and IP + memset( &servaddr, 0, sizeof(servaddr) ); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = inet_addr( Server_IP ); + if ( server_port == 0 ) { + servaddr.sin_port = htons( IPERF_DEFAULT_PORT ); + printf( "Default server port = %d \r\n", IPERF_DEFAULT_PORT ); + } else { + servaddr.sin_port = htons( server_port ); + printf( "Set server port = %d \r\n", server_port ); + } + + if ( (connect( sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr) )) < 0 ) { + printf( "Connect failed, sockfd is %d, addr is \"%s\"\r\n", (int) sockfd, + ((struct sockaddr *) &servaddr)->sa_data ); + close( sockfd ); + if ( parameters ) { + free( parameters ); + } + mico_rtos_delete_thread( NULL ); + } + + iperf_get_current_time( &t1, 0 ); + + do { + nbytes = send( sockfd, buffer, win_size, 0 ); + pkt_count = iperf_calculate_result( nbytes, pkt_count, 0 ); +#if defined(MICO_IPERF_DEBUG_ENABLE) + DBGPRINT_IPERF(IPERF_DEBUG_SEND, ("\r\n[%s:%d] nbytes=%d \r\n", __FUNCTION__, __LINE__, nbytes)); +#endif + mico_thread_msleep( pkt_delay ); + + if ( num_tag == 1 ) + { + total_send -= nbytes; + } + //Reach total receive number "-n" + if ( total_send < 0 ) { + printf( "Finish Sending \r\n" ); + break; + } + + if ( interval_tag > 0 ) { + iperf_get_current_time( &curr_t, 0 ); + + if ( ((int)(curr_t - t1) / 10) == interval_tag ) { + printf( "\r\nInterval: %d - %d sec ", (int) (curr_t - t1) / 10 * 10 - 10, + (int) (curr_t - t1) / 10 * 10 ); + iperf_display_report( "TCP Client", 10, 0, iperf_diff_count( pkt_count, tmp_count ) ); + tmp_count = iperf_copy_count( pkt_count, tmp_count ); + interval_tag++; + } + } + + iperf_get_current_time( &curr_t, 0 ); + } while ( (int)(curr_t - t1) < send_time ); + + iperf_get_current_time( &t2, 0 ); + + close( sockfd ); + printf( "\r\nClose socket!\r\n" ); + free( buffer ); + iperf_display_report( "[Total]TCP Client", t2 - t1, 0, pkt_count ); + + if ( parameters ) + { + free( parameters ); + } + mico_rtos_delete_thread( NULL ); + +} + +void iperf_udp_run_client( char *parameters[] ) +{ + int sockfd; + struct sockaddr_in servaddr; + char *Server_IP = 0; + count_t pkt_count; + count_t tmp_count; + int nbytes = 0; /* the number of send */ + int total_send = 0; /* the total number of transmit */ + int num_tag = 0; /* the tag of parameter "-n" */ + int interval_tag = 0; /* the tag of parameter "-i" */ + int tradeoff_tag = 0; /* the tag of parameter "-r" */ + int i; + int data_size, send_time, server_port, pkt_delay, pkt_delay_offset, tos, bw; + uint32_t t1, t2, curr_t, t1_ms, last_tick, current_tick, last_sleep, current_sleep; + UDP_datagram *udp_h; + client_hdr *client_h; + int udp_h_id = 0; + int offset = IPERF_COMMAND_BUFFER_SIZE / sizeof(char *); + char *buffer = (char*) malloc( IPERF_TEST_BUFFER_SIZE ); + // test data init + for ( i = 0; i < IPERF_TEST_BUFFER_SIZE; i++ ) { + buffer[i] = (i % 10 + '0'); + } + memset( buffer, 0, IPERF_TEST_BUFFER_SIZE ); + //Statistics init + pkt_count = iperf_reset_count( pkt_count ); + tmp_count = iperf_reset_count( tmp_count ); + data_size = 0; + send_time = 0; + server_port = 0; + pkt_delay = 0; + pkt_delay_offset = 0; + tos = 0; + bw = 2621440; + + //Handle input parameters + if ( g_iperf_is_tradeoff_test_server == 0 ) { + Server_IP = (char *) ¶meters[0]; + for ( i = 1; i < 18; i++ ) { + if ( strcmp( (char *) ¶meters[i * offset], "-l" ) == 0 ) { + i++; + data_size = iperf_format_transform( (char *) ¶meters[i * offset] ); + printf( "Set datagram size = %d Bytes\r\n", data_size ); + } else if ( strcmp( (char *) ¶meters[i * offset], "-t" ) == 0 ) { + i++; + send_time = atoi( (char *) ¶meters[i * offset] ); + printf( "Set send times = %d (secs)\r\n", atoi( (char *) ¶meters[i * offset] ) ); + } else if ( strcmp( (char *) ¶meters[i * offset], "-p" ) == 0 ) { + i++; + server_port = atoi( (char *) ¶meters[i * offset] ); + } else if ( strcmp( (char *) ¶meters[i * offset], "-d" ) == 0 ) { + i++; + pkt_delay = atoi( (char *) ¶meters[i * offset] ); + printf( "Set packet delay = %d (ms)\r\n", atoi( (char *) ¶meters[i * offset] ) ); + } else if ( strcmp( (char *) ¶meters[i * offset], "-n" ) == 0 ) { + i++; + total_send = iperf_format_transform( (char *) ¶meters[i * offset] ); + num_tag = 1; + printf( "Set number to transmit = %d Bytes\r\n", total_send ); + } else if ( strcmp( (char *) ¶meters[i * offset], "-S" ) == 0 ) { + i++; + tos = atoi( (char *) ¶meters[i * offset] ); + printf( "Set TOS = %d \r\n", atoi( (char *) ¶meters[i * offset] ) ); + } else if ( strcmp( (char *) ¶meters[i * offset], "-b" ) == 0 ) { + i++; + printf( "Set bandwidth = %s\r\n", (char *) ¶meters[i * offset] ); + bw = iperf_format_transform( (char *) ¶meters[i * offset] ); + if ( bw > 2621440 || bw <= 0 ) { + bw = 2621440; + printf( "Upper limit of bandwith setting = 10Mbits/sec\r\n" ); + } + printf( "bandwidth = %d\r\n", bw ); + } else if ( strcmp( (char *) ¶meters[i * offset], "-i" ) == 0 ) { + interval_tag = 1; + printf( "Set 10 seconds between periodic bandwidth reports\r\n" ); + } else if ( strcmp( (char *) ¶meters[i * offset], "-r" ) == 0 ) { + tradeoff_tag = 1; + printf( "Set to tradeoff mode\r\n" ); + } + } + } + + if ( data_size == 0 ) { + data_size = 1460; + printf( "Default datagram size = %d Bytes\r\n", data_size ); + } + + if ( bw > 0 ) { + pkt_delay = (1000 * data_size) / bw; + + // pkt_dalay add 1ms regularly to reduce the offset + pkt_delay_offset = (((1000 * data_size) % bw) * 10 / bw); + if ( pkt_delay_offset ) { + pkt_delay_offset = 10 / pkt_delay_offset; + } + } + + if ( send_time == 0 ) { + if ( num_tag == 1 ) { + send_time = 999999; + } else { + send_time = 10; + printf( "Default send times = %d (secs)\r\n", send_time ); + } + } + + // Create a new TCP connection handle + if ( (sockfd = socket( AF_INET, SOCK_DGRAM, 0 )) < 0 ) { + printf( "[%s:%d] sockfd = %d\r\n", __FUNCTION__, __LINE__, sockfd ); + if ( parameters ) { + free( parameters ); + } + mico_rtos_delete_thread( NULL ); + } + + if ( setsockopt( sockfd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos) ) < 0 ) { + printf( "Set TOS: fail!\r\n" ); + } + + // Bind to port and IP + memset( &servaddr, 0, sizeof(servaddr) ); + servaddr.sin_family = AF_INET; + + if ( g_iperf_is_tradeoff_test_server == 0 ) { + servaddr.sin_addr.s_addr = inet_addr( Server_IP ); + } else { + servaddr.sin_addr.s_addr = g_iperf_server_addr; + } + printf( "Server address = %x \r\n", (unsigned int) servaddr.sin_addr.s_addr ); + + if ( server_port == 0 ) { + servaddr.sin_port = htons( IPERF_DEFAULT_PORT ); + printf( "\r\nDefault server port = %d \r\n", IPERF_DEFAULT_PORT ); + } else { + servaddr.sin_port = htons( server_port ); + printf( "\r\nSet server port = %d \r\n", server_port ); + } + + if ( (connect( sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr) )) < 0 ) { + printf( "Connect failed\r\n" ); + close( sockfd ); + if ( parameters ) { + free( parameters ); + } + mico_rtos_delete_thread( NULL ); + } + + // Init UDP data header + udp_h = (UDP_datagram *) &buffer[0]; + client_h = (client_hdr *) &buffer[12]; + if ( tradeoff_tag == 1 ) { + client_h->flags = htonl( IPERF_HEADER_VERSION1 ); + } else { + client_h->flags = 0; + } + client_h->num_threads = htonl( 1 ); + client_h->port = htonl( IPERF_DEFAULT_PORT ); + client_h->buffer_len = 0; + client_h->win_band = htonl( IPERF_DEFAULT_UDP_RATE ); + if ( num_tag != 1 ) { // time mode + client_h->amount = htonl( ~(long )(send_time * 100) ); + } else { + client_h->amount = htonl( (long )(send_time * 100) ); + client_h->amount &= htonl( 0x7FFFFFFF ); + } + + iperf_get_current_time( &t1, &t1_ms ); + last_tick = t1_ms; + last_sleep = 0; + + do { + udp_h->id = htonl( udp_h_id ); + udp_h->tv_sec = htonl( (last_tick + last_sleep) / 1000 ); + udp_h->tv_usec = htonl( last_tick + last_sleep ); + + udp_h_id++; + + nbytes = send( sockfd, buffer, data_size, 0 ); + pkt_count = iperf_calculate_result( nbytes, pkt_count, 0 ); + + iperf_get_current_time( &curr_t, ¤t_tick ); + + if ( (udp_h_id % pkt_delay_offset) == 0 ) { + current_sleep = pkt_delay - (current_tick - last_tick - last_sleep) + 1; + } else { + current_sleep = pkt_delay - (current_tick - last_tick - last_sleep); + } + + if ( (int) current_sleep > 0 ) { + mico_thread_msleep( current_sleep ); + } else { + current_sleep = 0; + } + + last_tick = current_tick; + last_sleep = current_sleep; + +#if defined(IPERF_DEBUG_INTERNAL) + // show the debug info per second + if (((bw == 0) && ((udp_h_id % 5000 == 0))) || (udp_h_id % (bw / nbytes) == 0)) { + DBGPRINT_IPERF(IPERF_DEBUG_SEND, ("\r\n[%s:%d] nbytes = %d, udp_h_id = %d, pkt_delay = %d, current_tick = %d, current_sleep = %d\n", + __FUNCTION__, __LINE__, nbytes, udp_h_id, pkt_delay, current_tick, current_sleep)); + } +#endif + + if ( num_tag == 1 ) { + total_send -= nbytes; + } + + //Reach total receive number "-n" + if ( total_send < 0 ) { + printf( "Finish Sending \r\n" ); + break; + } + + if ( interval_tag > 0 ) { + if ( ((int)(current_tick - t1_ms) / 10000) == interval_tag ) { + printf( "\r\nInterval: %d - %d sec ", (int) (current_tick - t1_ms) / 10000 * 10 - 10, + (int) (current_tick - t1_ms) / 10000 * 10 ); + iperf_display_report( "UDP Client", 10, 0, iperf_diff_count( pkt_count, tmp_count ) ); + tmp_count = iperf_copy_count( pkt_count, tmp_count ); + interval_tag++; + } + iperf_get_current_time( &curr_t, ¤t_tick ); + } + } while ( (int)(current_tick + (uint32_t)pkt_delay - t1_ms) < send_time * 1000 ); + + iperf_get_current_time( &t2, 0 ); + iperf_display_report( "[Total]UDP Client", t2 - t1, 0, pkt_count ); + + // send the last datagram + udp_h_id = (-udp_h_id); + udp_h->id = htonl( udp_h_id ); + iperf_get_current_time( &curr_t, 0 ); + udp_h->tv_sec = htonl( curr_t ); + udp_h->tv_usec = htonl( curr_t * 1000 ); + + nbytes = send( sockfd, buffer, data_size, 0 ); + + //TODO: receive the report from server side and print out + + printf( "\r\nUDP Client close socket!\r\n" ); + close( sockfd ); + + // tradeoff testing + if ( tradeoff_tag == 1 ) { + printf( "Tradoff test, start server-side.\r\n" ); + g_iperf_is_tradeoff_test_client = 1; + iperf_udp_run_server( NULL ); + g_iperf_is_tradeoff_test_client = 0; + } + + if ( parameters ) { + free( parameters ); + } + + free( buffer ); + // For tradeoff mode, task will be deleted in iperf_udp_run_server + if ( g_iperf_is_tradeoff_test_server == 0 ) { + mico_rtos_delete_thread( NULL ); + } +} + +count_t iperf_calculate_result( int pkt_size, count_t pkt_count, int need_to_convert ) +{ + if ( pkt_size > 0 ) { + pkt_count.Bytes += pkt_size; + pkt_count.times++; + } + + if ( need_to_convert == 1 ) { + if ( pkt_count.Bytes >= 1024 ) { + pkt_count.KBytes += (pkt_count.Bytes / 1024); + pkt_count.Bytes = pkt_count.Bytes % 1024; + } + + if ( pkt_count.KBytes >= 1024 ) { + pkt_count.MBytes += (pkt_count.KBytes / 1024); + pkt_count.KBytes = pkt_count.KBytes % 1024; + } + + if ( pkt_count.MBytes >= 1024 ) { + pkt_count.GBytes += (pkt_count.MBytes / 1024); + pkt_count.MBytes = pkt_count.MBytes % 1024; + } + } + + return pkt_count; +} + +void iperf_display_report( char *report_title, unsigned time, unsigned h_ms_time, count_t pkt_count ) +{ + unsigned tmp_time = (time * 10) + h_ms_time; + +#if defined(MICO_IPERF_DEBUG_ENABLE) + DBGPRINT_IPERF(IPERF_DEBUG_REPORT, ("\nTransfer in %d.%d seconds: ", time, h_ms_time)); + if (pkt_count.GBytes != 0) { + DBGPRINT_IPERF(IPERF_DEBUG_REPORT, ("%d GBytes ", pkt_count.GBytes)); + } + + if (pkt_count.MBytes != 0) { + DBGPRINT_IPERF(IPERF_DEBUG_REPORT, ("%d MBytes ", pkt_count.MBytes)); + } + + if (pkt_count.KBytes != 0) { + DBGPRINT_IPERF(IPERF_DEBUG_REPORT, ("%d KBytes ", pkt_count.KBytes)); + } + + DBGPRINT_IPERF(IPERF_DEBUG_REPORT, ("[%s:%d], time = %d, h_ms_time = %d, GBytes = %d, MBytes = %d, KBytes= %d, Bytes= %d \r\n", __FUNCTION__, __LINE__, + time, h_ms_time, pkt_count.GBytes, pkt_count.MBytes, pkt_count.KBytes, pkt_count.Bytes)); +#endif + + printf( "%s Bandwidth: ", report_title ); + + if ( tmp_time != 0 ) { + //Calculate Bandwidth + pkt_count.Bytes = (((pkt_count.KBytes * 8 * 10) % tmp_time) * 1024 + pkt_count.Bytes * 8 * 10) / tmp_time; + pkt_count.KBytes = (((pkt_count.MBytes * 8 * 10) % tmp_time) * 1024 + pkt_count.KBytes * 8 * 10) / tmp_time; + pkt_count.MBytes = (((pkt_count.GBytes * 8 * 10) % tmp_time) * 1024 + pkt_count.MBytes * 8 * 10) / tmp_time; + pkt_count.GBytes = pkt_count.GBytes * 8 * 10 / tmp_time; + } else { + pkt_count.Bytes = 0; + pkt_count.KBytes = 0; + pkt_count.MBytes = 0; + pkt_count.GBytes = 0; + } + + pkt_count = iperf_calculate_result( 0, pkt_count, 1 ); + + if ( pkt_count.GBytes != 0 ) { + printf( "%d Gbits ", pkt_count.GBytes ); + } + + if ( pkt_count.MBytes != 0 ) { + printf( "%d Mbits ", pkt_count.MBytes ); + } + + if ( pkt_count.KBytes != 0 ) { + printf( "%d Kbits ", pkt_count.KBytes ); + } + printf( "%d bits/sec \r\n\r\n", pkt_count.Bytes ); + +#if defined(MICO_IPERF_DEBUG_ENABLE) + DBGPRINT_IPERF(IPERF_DEBUG_REPORT, ("Receive times: %d\n", pkt_count.times)); +#endif + +} + +count_t iperf_reset_count( count_t pkt_count ) +{ + pkt_count.Bytes = 0; + pkt_count.KBytes = 0; + pkt_count.MBytes = 0; + pkt_count.GBytes = 0; + pkt_count.times = 0; + + return pkt_count; +} + +count_t iperf_copy_count( count_t pkt_count, count_t tmp_count ) +{ + + tmp_count.Bytes = pkt_count.Bytes; + tmp_count.KBytes = pkt_count.KBytes; + tmp_count.MBytes = pkt_count.MBytes; + tmp_count.GBytes = pkt_count.GBytes; + tmp_count.times = pkt_count.times; + + return tmp_count; +} + +count_t iperf_diff_count( count_t pkt_count, count_t tmp_count ) +{ + /* pkt_count > tmp_count */ + tmp_count.times = pkt_count.times - tmp_count.times; + + if ( pkt_count.Bytes >= tmp_count.Bytes ) { + tmp_count.Bytes = pkt_count.Bytes - tmp_count.Bytes; + } else { + tmp_count.Bytes = pkt_count.Bytes + 1024 - tmp_count.Bytes; + if ( pkt_count.KBytes > 0 ) { + pkt_count.KBytes--; + } else if ( pkt_count.MBytes > 0 ) { + pkt_count.MBytes--; + pkt_count.KBytes = 1023; + } else if ( pkt_count.GBytes > 0 ) { + pkt_count.GBytes--; + pkt_count.MBytes = 1023; + pkt_count.KBytes = 1023; + } else { + printf( "Warning: Diff data is wrong." ); + } + } + + if ( pkt_count.KBytes >= tmp_count.KBytes ) { + tmp_count.KBytes = pkt_count.KBytes - tmp_count.KBytes; + } else { + tmp_count.KBytes = pkt_count.KBytes + 1024 - tmp_count.KBytes; + if ( pkt_count.MBytes > 0 ) { + pkt_count.MBytes--; + } else if ( pkt_count.GBytes > 0 ) { + pkt_count.GBytes--; + pkt_count.MBytes = 1023; + } else { + printf( "Warning: Diff data is wrong." ); + } + } + + if ( pkt_count.MBytes >= tmp_count.MBytes ) { + tmp_count.MBytes = pkt_count.MBytes - tmp_count.MBytes; + } else { + tmp_count.MBytes = pkt_count.MBytes + 1024 - tmp_count.MBytes; + if ( pkt_count.GBytes > 0 ) { + pkt_count.GBytes--; + } else { + printf( "Warning: Diff data is wrong." ); + } + } + +#if defined(IPERF_DEBUG_INTERNAL) + DBGPRINT_IPERF(IPERF_DEBUG_REPORT, ("\niperf_diff_count: ret.times = %d, ret.GBytes = %d, ret.MBytes = %d, ret.KBytes = %d, ret.Bytes = %d\n", + tmp_count.times, tmp_count.GBytes, tmp_count.MBytes, tmp_count.KBytes, tmp_count.Bytes)); +#endif + + return tmp_count; +} + +void iperf_get_current_time( uint32_t *s, uint32_t *ms ) +{ + uint32_t time_ms; + mico_time_get_time( &time_ms ); + + if ( s ) + { + *s = time_ms / 1000; + } + + if ( ms ) + { + *ms = time_ms; + } +} + +void iperf_set_debug_mode( uint32_t debug ) +{ + g_iperf_debug_feature = debug; +} + +int iperf_format_transform( char *param ) +{ + char *temp; + int win_size = 0; + int i; + + temp = param; + + for ( i = 0; temp[i] != '\0'; i++ ) { + if ( temp[i] == 'k' ) { + temp[i] = '\0'; + win_size = (1000 * atoi( temp )); + } else if ( temp[i] == 'm' ) { + temp[i] = '\0'; + win_size = (1000 * 1000 * atoi( temp )); + } else if ( temp[i] == 'K' ) { + temp[i] = '\0'; + win_size = 1024 * atoi( temp ); + } else if ( temp[i] == 'M' ) { + temp[i] = '\0'; + win_size = 1024 * 1024 * atoi( temp ); + } else { + win_size = atoi( param ); + } + } + + return win_size; +} + diff --git a/kernel/protocols/net/include/lwip/apps/iperf_cli.h b/kernel/protocols/net/include/lwip/apps/iperf_cli.h new file mode 100755 index 0000000000..230e8e8d9b --- /dev/null +++ b/kernel/protocols/net/include/lwip/apps/iperf_cli.h @@ -0,0 +1,21 @@ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************** + * Function Declarations + ******************************************************/ + +/** + * @brief Add iperf command lines to MiCO CLI. + * @param none. + * @retval kNoErr is returned on success, otherwise, kXXXErr is returned. + */ +OSStatus iperf_cli_register( void ); + +#ifdef __cplusplus +} /*extern "C" */ +#endif diff --git a/kernel/protocols/net/include/lwip/apps/iperf_debug.h b/kernel/protocols/net/include/lwip/apps/iperf_debug.h new file mode 100755 index 0000000000..ac57a35f2b --- /dev/null +++ b/kernel/protocols/net/include/lwip/apps/iperf_debug.h @@ -0,0 +1,10 @@ + +#pragma once + +/****************************************************** + * Constants + ******************************************************/ + +//#define MICO_IPERF_DEBUG_ENABLE + + diff --git a/kernel/protocols/net/include/lwip/apps/iperf_task.h b/kernel/protocols/net/include/lwip/apps/iperf_task.h new file mode 100755 index 0000000000..ff1de895c9 --- /dev/null +++ b/kernel/protocols/net/include/lwip/apps/iperf_task.h @@ -0,0 +1,43 @@ + +#pragma once + +/****************************************************** + * Macros + ******************************************************/ + +/****************************************************** + * Constants + ******************************************************/ + +/* for iperf task */ +#define IPERF_NAME "iperf" +#define IPERF_STACKSIZE 1536 +#define IPERF_PRIO 6 + +#define IPERF_COMMAND_BUFFER_NUM (18) +#define IPERF_COMMAND_BUFFER_SIZE (20) // 4 bytes align + + +/****************************************************** + * Enumerations + ******************************************************/ + +/****************************************************** + * Type Definitions + ******************************************************/ + +/****************************************************** + * Structures + ******************************************************/ + +/****************************************************** + * Function Declarations + ******************************************************/ + +void iperf_udp_run_server(char *parameters[]); +void iperf_tcp_run_server(char *parameters[]); +void iperf_udp_run_client(char *parameters[]); +void iperf_tcp_run_client(char *parameters[]); + +void iperf_get_current_time(uint32_t *s, uint32_t *ms); + diff --git a/kernel/protocols/net/net.mk b/kernel/protocols/net/net.mk index fb7252cf84..41bbd01d0a 100644 --- a/kernel/protocols/net/net.mk +++ b/kernel/protocols/net/net.mk @@ -3,6 +3,7 @@ NAME := net $(NAME)_TYPE := kernel include kernel/protocols/net/Filelists.mk GLOBAL_INCLUDES += include port/include + ifneq ($(no_with_lwip),1) GLOBAL_DEFINES += WITH_LWIP with_lwip := 1 diff --git a/kernel/rhino/common/k_atomic.c b/kernel/rhino/common/k_atomic.c new file mode 100644 index 0000000000..6cbc4604e7 --- /dev/null +++ b/kernel/rhino/common/k_atomic.c @@ -0,0 +1,340 @@ +/* + * Copyright (C) 2017 Alibaba Group Holding Limited + */ + +/* +modification history +-------------------- +2017_12_27,WangMin(Rocky) created. +*/ + +/* + * DESCRIPTION + * This library is used to provide the atomic operators for CPU + * which do not support native atomic operations. + * + * The design principle is disable the interrupt when execute the + * atomic operations and enable the interrupt after finish the + * operation. + * + * This library can be added into system by defining + * RHINO_CONFIG_ATOMIC_GENERIC. + */ + +#include "k_api.h" +#include "k_atomic.h" + +#ifdef RHINO_CONFIG_ATOMIC_GENERIC + +/** + * This routine atomically adds <*target> and , placing the result in + * <*target>. The operation is done using unsigned integer arithmetic. + * + * This routine can be used from both task and interrupt context. + * + * @param target memory location to add to + * @param value the value to add + * + * @return The previous value from + */ + +atomic_val_t rhino_atomic_add(atomic_t *target, atomic_val_t value) +{ + CPSR_ALLOC(); + atomic_val_t old_value; + + RHINO_CPU_INTRPT_DISABLE(); + + old_value = *target; + *target += value; + + RHINO_CPU_INTRPT_ENABLE(); + + return old_value; +} + +/** + * This routine atomically subtracts from <*target>, result is placed + * in <*target>. The operation is done using unsigned integer arithmetic. + * + * This routine can be used from both task and interrupt context. + * + * @param target the memory location to subtract from + * @param value the value to subtract + * + * @return The previous value from + */ + +atomic_val_t rhino_atomic_sub(atomic_t *target, atomic_val_t value) +{ + CPSR_ALLOC(); + atomic_val_t old_value; + + RHINO_CPU_INTRPT_DISABLE(); + + old_value = *target; + *target -= value; + + RHINO_CPU_INTRPT_ENABLE(); + + return old_value; +} + +/** + * This routine atomically increments the value in <*target>. The operation is + * done using unsigned integer arithmetic. + * + * This routine can be used from both task and interrupt context. + * + * @return The value from before the increment + */ + +atomic_val_t rhino_atomic_inc(atomic_t *target) +{ + CPSR_ALLOC(); + atomic_val_t old_value; + + RHINO_CPU_INTRPT_DISABLE(); + + old_value = *target; + (*target)++; + + RHINO_CPU_INTRPT_ENABLE(); + + return old_value; +} + +/** + * This routine atomically decrement the value in <*target>. The operation is + * done using unsigned integer arithmetic. + * + * This routine can be used from both task and interrupt context. + * + * @return The value from before the increment + */ + +atomic_val_t rhino_atomic_dec(atomic_t *target) +{ + CPSR_ALLOC(); + atomic_val_t old_value; + + RHINO_CPU_INTRPT_DISABLE(); + + old_value = *target; + (*target)--; + + RHINO_CPU_INTRPT_ENABLE(); + + return old_value; +} + +/** + * This routine atomically sets <*target> to and returns the old value + * that was in <*target>. Normally all CPU architectures can atomically write + * to a variable of size atomic_t without the help of this routine. + * This routine is intended for software that needs to atomically fetch and + * replace the value of a memory location. + * + * This routine can be used from both task and interrupt context. + * + * @param target the memory location to write to + * @param value the value to write + * + * @return The previous value from + */ + +atomic_val_t rhino_atomic_set(atomic_t *target, atomic_val_t value) +{ + CPSR_ALLOC(); + atomic_val_t old_value; + + RHINO_CPU_INTRPT_DISABLE(); + + old_value = *target; + *target = value; + + RHINO_CPU_INTRPT_ENABLE(); + + return old_value; +} + +/** + * This routine atomically read a value from . + * This routine can be used from both task and interrupt context. + * + * @return The value read from + */ + +atomic_val_t rhino_atomic_get(const atomic_t *target) +{ + return *target; +} + +/** + * This routine atomically performs a bitwise OR operation of <*target> + * and , placing the result in <*target>. + * + * This routine can be used from both task and interrupt context. + * + * @param target the memory location to be modified + * @param value the value to OR + * + * @return The previous value from + */ + +atomic_val_t rhino_atomic_or(atomic_t *target, atomic_val_t value) +{ + CPSR_ALLOC(); + atomic_val_t old_value; + + RHINO_CPU_INTRPT_DISABLE(); + + old_value = *target; + *target |= value; + + RHINO_CPU_INTRPT_ENABLE(); + + return old_value; +} + +/** + * This routine atomically performs a bitwise XOR operation of <*target> and + * , placing the result in <*target>. + * + * This routine can be used from both task and interrupt context. + * + * @param target the memory location to be modified + * @param value the value to XOR + * + * @return The previous value from + */ + +atomic_val_t rhino_atomic_xor(atomic_t *target, atomic_val_t value) +{ + CPSR_ALLOC(); + atomic_val_t old_value; + + RHINO_CPU_INTRPT_DISABLE(); + + old_value = *target; + *target ^= value; + + RHINO_CPU_INTRPT_ENABLE(); + + return old_value; +} + +/** + * This routine atomically performs a bitwise AND operation of <*target> and + * , placing the result in <*target>. + * + * This routine can be used from both task and interrupt context. + * + * @param target the memory location to be modified + * @param value the value to AND + * + * @return The previous value from + */ + +atomic_val_t rhino_atomic_and(atomic_t *target, atomic_val_t value) +{ + CPSR_ALLOC(); + atomic_val_t old_value; + + RHINO_CPU_INTRPT_DISABLE(); + + old_value = *target; + *target &= value; + + RHINO_CPU_INTRPT_ENABLE(); + + return old_value; +} + +/** + * This routine atomically performs a bitwise NAND operation of <*target> and + * , placing the result in <*target>. + * + * This routine can be used from both task and interrupt context. + * + * @param target the memory location to be modified + * @param value the value to NAND + * + * @return The previous value from + */ + +atomic_val_t rhino_atomic_nand(atomic_t *target, atomic_val_t value) +{ + CPSR_ALLOC(); + atomic_val_t old_value; + + RHINO_CPU_INTRPT_DISABLE(); + + old_value = *target; + *target = ~(*target & value); + + RHINO_CPU_INTRPT_ENABLE(); + + return old_value; +} + +/** + * This routine provides the atomic clear operator. The value of 0 is atomically + * written at and the previous value at is returned. + * + * This routine can be used from both task and interrupt context. + * + * @param target the memory location to write + * + * @return The previous value from + */ + +atomic_val_t rhino_atomic_clear(atomic_t *target) +{ + CPSR_ALLOC(); + atomic_val_t old_value; + + RHINO_CPU_INTRPT_DISABLE(); + + old_value = *target; + *target = 0; + + RHINO_CPU_INTRPT_ENABLE(); + + return old_value; +} + +/** + * This routine performs an atomic compare-and-swap, it test that whether + * <*target> equal to , and if TRUE, setting the value of <*target> + * to and return 1. + * + * If the original value at does not equal , then the target + * will not be updated and return 0. + * + * @param target address to be tested + * @param old_value value to compare against + * @param new_value value to compare against + * @return Returns 1 if is written, 0 otherwise. + */ + +int rhino_atomic_cas(atomic_t *target, atomic_val_t old_value, + atomic_val_t new_value) +{ + CPSR_ALLOC(); + int ret = 0; + + RHINO_CPU_INTRPT_DISABLE(); + + if (*target == old_value) + { + *target = new_value; + ret = 1; + } + + RHINO_CPU_INTRPT_ENABLE(); + + return ret; +} + +#endif /* RHINO_CONFIG_ATOMIC_GENERIC */ diff --git a/kernel/rhino/common/k_atomic.h b/kernel/rhino/common/k_atomic.h new file mode 100644 index 0000000000..e49b50b010 --- /dev/null +++ b/kernel/rhino/common/k_atomic.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2017 Alibaba Group Holding Limited + */ + +/* +modification history +-------------------- +2017_12_27,WangMin(Rocky) created. +*/ + +#ifndef K_ATOMIC_H +#define K_ATOMIC_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef unsigned int atomic_t; +typedef atomic_t atomic_val_t; + +extern atomic_val_t rhino_atomic_add(atomic_t *target, atomic_val_t value); +extern atomic_val_t rhino_atomic_sub(atomic_t *target, atomic_val_t value); +extern atomic_val_t rhino_atomic_inc(atomic_t *target); +extern atomic_val_t rhino_atomic_dec(atomic_t *target); +extern atomic_val_t rhino_atomic_set(atomic_t *target, atomic_val_t value); +extern atomic_val_t rhino_atomic_get(const atomic_t *target); +extern atomic_val_t rhino_atomic_or(atomic_t *target, atomic_val_t value); +extern atomic_val_t rhino_atomic_xor(atomic_t *target, atomic_val_t value); +extern atomic_val_t rhino_atomic_and(atomic_t *target, atomic_val_t value); +extern atomic_val_t rhino_atomic_nand(atomic_t *target, atomic_val_t value); +extern atomic_val_t rhino_atomic_clear(atomic_t *target); +extern int rhino_atomic_cas(atomic_t *target, atomic_val_t old_value, + atomic_val_t new_value); + +#ifdef __cplusplus +} +#endif + +#endif /* K_ATOMIC_H */ + diff --git a/kernel/rhino/core/k_fifo.c b/kernel/rhino/common/k_fifo.c old mode 100644 new mode 100755 similarity index 100% rename from kernel/rhino/core/k_fifo.c rename to kernel/rhino/common/k_fifo.c diff --git a/kernel/rhino/core/k_trace.c b/kernel/rhino/common/k_trace.c old mode 100644 new mode 100755 similarity index 100% rename from kernel/rhino/core/k_trace.c rename to kernel/rhino/common/k_trace.c diff --git a/kernel/rhino/core/include/k_bitmap.h b/kernel/rhino/core/include/k_bitmap.h old mode 100644 new mode 100755 index 7e131fa630..06fce824af --- a/kernel/rhino/core/include/k_bitmap.h +++ b/kernel/rhino/core/include/k_bitmap.h @@ -12,6 +12,12 @@ #define BITMAP_MASK(nr) (1UL << (BITMAP_UNIT_SIZE - 1U - ((nr) & BITMAP_UNIT_MASK))) #define BITMAP_WORD(nr) ((nr) >> BITMAP_UNIT_BITS) + +#define LITTLE_TO_BIG_ENDIAN(x) ((uint32_t)(((x) & 0x000000ffUL) << 24u) | \ + (((x) & 0x0000ff00UL) << 8u) | \ + (((x) & 0x00ff0000UL) >> 8u) | \ + (((x) & 0xff000000UL) >> 24u)) + /** ** This MACRO will declare a bitmap ** @param[in] name the name of the bitmap to declare @@ -63,6 +69,10 @@ RHINO_INLINE int krhino_find_first_bit(uint32_t *bitmap) tmp = *bitmap; +#if (RHINO_CONFIG_LITTLE_ENDIAN == 0) + tmp = LITTLE_TO_BIG_ENDIAN(tmp); +#endif + #if (RHINO_CONFIG_BITMAP_HW == 0) if (!(tmp & 0XFFFF0000)) { tmp <<= 16; diff --git a/kernel/rhino/core/include/k_buf_queue.h b/kernel/rhino/core/include/k_buf_queue.h index ebe2d1f8e1..cd9851fee2 100644 --- a/kernel/rhino/core/include/k_buf_queue.h +++ b/kernel/rhino/core/include/k_buf_queue.h @@ -41,6 +41,18 @@ kstat_t krhino_buf_queue_create(kbuf_queue_t *queue, const name_t *name, void *buf, size_t size, size_t max_msg); +/** + * This function will create a fix buf-queue + * @param[in] queue pointer to the queue(the space is provided by user) + * @param[in] name name of the queue + * @param[in] buf pointer to the buf + * @param[in] msg_size size of the msg + * @param[in] msg_num number of msg + * @return the operation status, RHINO_SUCCESS is OK, others is error + */ +kstat_t krhino_fix_buf_queue_create(kbuf_queue_t *queue, const name_t *name, + void *buf, size_t msg_size, size_t msg_num); + /** * This function will delete a queue * @param[in] queue pointer to the queue diff --git a/kernel/rhino/core/include/k_default_config.h b/kernel/rhino/core/include/k_default_config.h old mode 100644 new mode 100755 index 830feb20bf..50a279c11f --- a/kernel/rhino/core/include/k_default_config.h +++ b/kernel/rhino/core/include/k_default_config.h @@ -5,6 +5,11 @@ #ifndef K_DEFAULT_CONFIG_H #define K_DEFAULT_CONFIG_H +/* leave this option as default unless your compiler does not support 64 bit data such as uint64_t */ +#ifndef RHINO_CONFIG_64_BIT_TYPE +#define RHINO_CONFIG_64_BIT_TYPE 1 +#endif + /* chip level conf */ #ifndef RHINO_CONFIG_LITTLE_ENDIAN #define RHINO_CONFIG_LITTLE_ENDIAN 1 @@ -175,7 +180,7 @@ #endif #ifndef RHINO_CONFIG_TIMER_MSG_NUM -#define RHINO_CONFIG_TIMER_MSG_NUM 40 +#define RHINO_CONFIG_TIMER_MSG_NUM 20 #endif /* kernel intrpt conf */ @@ -269,6 +274,10 @@ #define RHINO_CONFIG_CPU_NUM 1 #endif +#if ((RHINO_CONFIG_TIMER >= 1) && (RHINO_CONFIG_BUF_QUEUE == 0)) +#error "RHINO_CONFIG_BUF_QUEUE should be 1 when RHINO_CONFIG_TIMER is enabled." +#endif + #if ((RHINO_CONFIG_DYNTICKLESS >= 1) && (RHINO_CONFIG_SCHED_RR != 0)) #error "RHINO_CONFIG_SCHED_RR should be 0 when RHINO_CONFIG_DYNTICKLESS is enabled." #endif diff --git a/kernel/rhino/core/include/k_internal.h b/kernel/rhino/core/include/k_internal.h index 72fcae3fc6..874df3bad7 100755 --- a/kernel/rhino/core/include/k_internal.h +++ b/kernel/rhino/core/include/k_internal.h @@ -39,9 +39,7 @@ extern klist_t g_timer_head; extern sys_time_t g_timer_count; extern ktask_t g_timer_task; extern cpu_stack_t g_timer_task_stack[RHINO_CONFIG_TIMER_TASK_STACK_SIZE]; -extern kqueue_t g_timer_queue; -extern void *g_timer_msg[RHINO_CONFIG_TIMER_MSG_NUM]; -extern mblk_pool_t g_timer_pool; +extern kbuf_queue_t g_timer_queue; extern k_timer_queue_cb timer_queue_cb[RHINO_CONFIG_TIMER_MSG_NUM]; #endif @@ -87,6 +85,8 @@ extern klist_t g_res_list; #if (RHINO_CONFIG_WORKQUEUE > 0) extern klist_t g_workqueue_list_head; extern kmutex_t g_workqueue_mutex; +extern kworkqueue_t g_workqueue_default; +extern cpu_stack_t g_workqueue_stack[RHINO_CONFIG_WORKQUEUE_STACK_SIZE]; #endif #if (RHINO_CONFIG_MM_TLF > 0) diff --git a/kernel/rhino/core/include/k_mm.h b/kernel/rhino/core/include/k_mm.h old mode 100644 new mode 100755 index c6b95ce5f7..3f4cf37ba6 --- a/kernel/rhino/core/include/k_mm.h +++ b/kernel/rhino/core/include/k_mm.h @@ -21,10 +21,6 @@ /*use two level bit map to find free memory block*/ #if (RHINO_CONFIG_MM_TLF > 0) - -#define RHINO_MM_CORRUPT_DYE 0xFEFEFEFE -#define RHINO_MM_FREE_DYE 0xABABABAB - #define MAX_MM_BIT RHINO_CONFIG_MM_MAXMSIZEBIT #define MAX_MM_SIZE (1<> 1) + +#if (RHINO_CONFIG_64_BIT_TYPE > 0) +#define RHINO_WAIT_FOREVER ((uint64_t)-1) +typedef uint64_t sys_time_t; +typedef int64_t sys_time_i_t; +typedef uint64_t idle_count_t; +typedef uint64_t tick_t; +typedef int64_t tick_i_t; +#else +#define RHINO_WAIT_FOREVER ((uint32_t)-1) +typedef uint32_t sys_time_t; +typedef int32_t sys_time_i_t; +typedef uint32_t idle_count_t; +typedef uint32_t tick_t; +typedef int32_t tick_i_t; +#endif #if (RHINO_CONFIG_INTRPT_STACK_OVF_CHECK > 0) #if (RHINO_CONFIG_CPU_STACK_DOWN > 0) diff --git a/kernel/rhino/core/k_buf_queue.c b/kernel/rhino/core/k_buf_queue.c index 2fcc4ae3fe..13b49aea71 100755 --- a/kernel/rhino/core/k_buf_queue.c +++ b/kernel/rhino/core/k_buf_queue.c @@ -7,7 +7,7 @@ #if (RHINO_CONFIG_BUF_QUEUE > 0) static kstat_t buf_queue_create(kbuf_queue_t *queue, const name_t *name, - void *buf, size_t size, size_t max_msg, uint8_t mm_alloc_flag) + void *buf, size_t size, size_t max_msg, uint8_t mm_alloc_flag, size_t type) { CPSR_ALLOC(); @@ -45,7 +45,7 @@ static kstat_t buf_queue_create(kbuf_queue_t *queue, const name_t *name, queue->blk_obj.obj_type = RHINO_BUF_QUEUE_OBJ_TYPE; - ringbuf_init(&(queue->ringbuf), buf, size, RINGBUF_TYPE_DYN, 0); + ringbuf_init(&(queue->ringbuf), buf, size, type, max_msg); queue->min_free_buf_size = queue->ringbuf.freesize; TRACE_BUF_QUEUE_CREATE(krhino_cur_task_get(), queue); @@ -53,10 +53,15 @@ static kstat_t buf_queue_create(kbuf_queue_t *queue, const name_t *name, } kstat_t krhino_buf_queue_create(kbuf_queue_t *queue, const name_t *name, - void *buf, - size_t size, size_t max_msg) + void *buf, size_t size, size_t max_msg) { - return buf_queue_create(queue, name, buf, size, max_msg, K_OBJ_STATIC_ALLOC); + return buf_queue_create(queue, name, buf, size, max_msg, K_OBJ_STATIC_ALLOC, RINGBUF_TYPE_DYN); +} + +kstat_t krhino_fix_buf_queue_create(kbuf_queue_t *queue, const name_t *name, + void *buf, size_t msg_size, size_t msg_num) +{ + return buf_queue_create(queue, name, buf, msg_size * msg_num, msg_size, K_OBJ_STATIC_ALLOC, RINGBUF_TYPE_FIX); } kstat_t krhino_buf_queue_del(kbuf_queue_t *queue) @@ -129,7 +134,7 @@ kstat_t krhino_buf_queue_dyn_create(kbuf_queue_t **queue, const name_t *name, } stat = buf_queue_create(queue_obj, name, queue_obj->buf, size, max_msg, - K_OBJ_DYN_ALLOC); + K_OBJ_DYN_ALLOC, RINGBUF_TYPE_DYN); if (stat != RHINO_SUCCESS) { krhino_mm_free(queue_obj->buf); diff --git a/kernel/rhino/core/k_obj.c b/kernel/rhino/core/k_obj.c index a712c670bd..aa728e1b47 100644 --- a/kernel/rhino/core/k_obj.c +++ b/kernel/rhino/core/k_obj.c @@ -34,13 +34,11 @@ kobj_list_t g_kobj_list; #endif #if (RHINO_CONFIG_TIMER > 0) -klist_t g_timer_head; -sys_time_t g_timer_count; -ktask_t g_timer_task; -cpu_stack_t g_timer_task_stack[RHINO_CONFIG_TIMER_TASK_STACK_SIZE]; -kqueue_t g_timer_queue; -void *g_timer_msg[RHINO_CONFIG_TIMER_MSG_NUM]; -mblk_pool_t g_timer_pool; +klist_t g_timer_head; +sys_time_t g_timer_count; +ktask_t g_timer_task; +cpu_stack_t g_timer_task_stack[RHINO_CONFIG_TIMER_TASK_STACK_SIZE]; +kbuf_queue_t g_timer_queue; k_timer_queue_cb timer_queue_cb[RHINO_CONFIG_TIMER_MSG_NUM]; #endif diff --git a/kernel/rhino/core/k_ringbuf.c b/kernel/rhino/core/k_ringbuf.c old mode 100644 new mode 100755 index fff88a30f4..609b4c27dd --- a/kernel/rhino/core/k_ringbuf.c +++ b/kernel/rhino/core/k_ringbuf.c @@ -19,9 +19,9 @@ kstat_t ringbuf_init(k_ringbuf_t *p_ringbuf, void *buf, size_t len, size_t type, } static size_t ringbuf_headlen_compress(size_t head_len, uint8_t *cmp_buf) { - size_t len_bytes = 0; + size_t len_bytes = 0; uint8_t *p_len = NULL; - size_t be_len = 0; + uint32_t be_len = 0; be_len = krhino_ntohl(head_len); p_len = (uint8_t *)&be_len; @@ -44,13 +44,13 @@ static size_t ringbuf_headlen_compress(size_t head_len, uint8_t *cmp_buf) static size_t ringbuf_headlen_decompress(size_t buf_len, uint8_t *cmp_buf) { size_t data_len = 0; - size_t be_len = 0; + uint32_t be_len = 0; uint8_t *len_buf = (uint8_t *)&be_len; - memcpy(&len_buf[sizeof(size_t) - buf_len], cmp_buf, buf_len); + memcpy(&len_buf[sizeof(uint32_t) - buf_len], cmp_buf, buf_len); if (buf_len > 1) { - len_buf[sizeof(size_t) - buf_len] &= RINGBUF_LEN_MASK_CLEAN_TWOBIT; + len_buf[sizeof(uint32_t) - buf_len] &= RINGBUF_LEN_MASK_CLEAN_TWOBIT; } data_len = krhino_ntohl(be_len); @@ -73,9 +73,9 @@ kstat_t ringbuf_push(k_ringbuf_t *p_ringbuf, void *data, size_t len) p_ringbuf->tail = p_ringbuf->buf; } - memcpy(p_ringbuf->tail, data, len); - p_ringbuf->tail += len; - p_ringbuf->freesize -= len; + memcpy(p_ringbuf->tail, data, p_ringbuf->blk_size); + p_ringbuf->tail += p_ringbuf->blk_size; + p_ringbuf->freesize -= p_ringbuf->blk_size; } else { len_bytes = ringbuf_headlen_compress(len, c_len); if (len_bytes == 0 || len_bytes > RINGBUF_LEN_MAX_SIZE ) { @@ -456,7 +456,7 @@ uint8_t krhino_ringbuf_is_full(k_ringbuf_t *p_ringbuf) NULL_PARA_CHK(p_ringbuf); RHINO_CRITICAL_ENTER(); - full = ringbuf_is_empty(p_ringbuf); + full = ringbuf_is_full(p_ringbuf); RHINO_CRITICAL_EXIT(); return full; diff --git a/kernel/rhino/core/k_sched.c b/kernel/rhino/core/k_sched.c old mode 100644 new mode 100755 index adc35ee225..6feee2121a --- a/kernel/rhino/core/k_sched.c +++ b/kernel/rhino/core/k_sched.c @@ -207,8 +207,10 @@ RHINO_INLINE void _ready_list_add_head(runqueue_t *rq, ktask_t *task) #if (RHINO_CONFIG_CPU_NUM > 1) static void task_sched_to_cpu(runqueue_t *rq, ktask_t *task, uint8_t cur_cpu_num) { - (void)rq; uint8_t i; + uint8_t low_pri; + + (void)rq; if (g_sys_stat == RHINO_RUNNING) { if (task->cpu_binded == 1) { @@ -218,18 +220,27 @@ static void task_sched_to_cpu(runqueue_t *rq, ktask_t *task, uint8_t cur_cpu_num } } } else { + /* if other cpu is in idle state just notify it */ for (i = 0; i < RHINO_CONFIG_CPU_NUM; i++) { if (g_active_task[i]->prio == RHINO_IDLE_PRI) { if (i != cur_cpu_num) { cpu_signal(i); } - return; } } + /* find the lowest pri */ + low_pri = g_active_task[0]->prio; + for (i = 0; i < RHINO_CONFIG_CPU_NUM - 1; i++) { + if (low_pri < g_active_task[i + 1]->prio) { + low_pri = g_active_task[i + 1]->prio; + } + } + + /* which cpu run the lowest pri, just notify it */ for (i = 0; i < RHINO_CONFIG_CPU_NUM; i++) { - if (task->prio <= g_active_task[i]->prio) { + if (low_pri == g_active_task[i]->prio) { if (i != cur_cpu_num) { cpu_signal(i); } diff --git a/kernel/rhino/core/k_sys.c b/kernel/rhino/core/k_sys.c old mode 100644 new mode 100755 index 9c917b862c..f58f9dad15 --- a/kernel/rhino/core/k_sys.c +++ b/kernel/rhino/core/k_sys.c @@ -57,6 +57,10 @@ kstat_t krhino_init(void) idle_task, 1u); #endif +#if (RHINO_CONFIG_WORKQUEUE > 0) + workqueue_init(); +#endif + #if (RHINO_CONFIG_TIMER > 0) ktimer_init(); #endif @@ -83,9 +87,6 @@ kstat_t krhino_start(void) preferred_cpu_ready_task_get(&g_ready_queue, 0); g_active_task[0] = g_preferred_ready_task[0]; #endif -#if( RHINO_CONFIG_WORKQUEUE > 0) - workqueue_init(); -#endif #if (RHINO_CONFIG_USER_HOOK > 0) krhino_start_hook(); @@ -199,19 +200,20 @@ size_t krhino_global_space_get(void) mem = sizeof(g_sys_stat) + sizeof(g_idle_task_spawned) + sizeof(g_ready_queue) + sizeof(g_sched_lock) + sizeof(g_intrpt_nested_level) + sizeof(g_preferred_ready_task) + sizeof(g_active_task) + sizeof(g_idle_task) + sizeof(g_idle_task_stack) - + sizeof(g_tick_head) + sizeof(g_idle_count) + sizeof(g_sys_time_tick); + + sizeof(g_tick_head) + sizeof(g_tick_count) + sizeof(g_idle_count) + sizeof(g_sys_time_tick); #if (RHINO_CONFIG_TIMER > 0) mem += sizeof(g_timer_head) + sizeof(g_timer_count) + sizeof(g_timer_task) + sizeof(g_timer_task_stack) - + sizeof(g_timer_queue) + sizeof(g_timer_msg) - + sizeof(g_timer_pool) + sizeof(timer_queue_cb); + + sizeof(g_timer_queue) + sizeof(timer_queue_cb); #endif #if (RHINO_CONFIG_SYSTEM_STATS > 0) mem += sizeof(g_kobj_list); #endif + mem += sizeof(g_sys_lock); + return mem; } diff --git a/kernel/rhino/core/k_task.c b/kernel/rhino/core/k_task.c index 4883de2284..fdfcbe62c1 100755 --- a/kernel/rhino/core/k_task.c +++ b/kernel/rhino/core/k_task.c @@ -758,7 +758,7 @@ kstat_t krhino_task_del(ktask_t *task) #if (RHINO_CONFIG_CPU_STACK_DOWN > 0) res_free = (res_free_t *)(task->task_stack_base + 1u); #else - (res_free_t *) = (res_free_t *)(task->task_stack_base + task->stack_size - 2u); + res_free = (res_free_t *)(task->task_stack_base + task->stack_size - (sizeof(res_free_t) / sizeof(cpu_stack_t)) - 1u); #endif res_free->cnt = 0; krhino_task_del_hook(task, res_free); @@ -822,9 +822,9 @@ kstat_t krhino_task_dyn_del(ktask_t *task) } #if (RHINO_CONFIG_CPU_STACK_DOWN > 0) - res_free = (res_free_t *)(task->task_stack_base + 1u); + res_free = (res_free_t *)(task->task_stack_base + 1u); #else - res_free = (res_free_t *)(task->task_stack_base + task->stack_size - 2u); + res_free = (res_free_t *)(task->task_stack_base + task->stack_size - (sizeof(res_free_t) / sizeof(cpu_stack_t)) - 1u); #endif res_free->cnt = 0; g_sched_lock[cpu_cur_get()]++; diff --git a/kernel/rhino/core/k_tick.c b/kernel/rhino/core/k_tick.c index 2268aee248..c93b09ad8d 100644 --- a/kernel/rhino/core/k_tick.c +++ b/kernel/rhino/core/k_tick.c @@ -75,12 +75,12 @@ void tick_list_update(void) ktask_t *p_tcb; klist_t *iter; klist_t *iter_temp; + tick_i_t delta; RHINO_CRITICAL_ENTER(); #if (RHINO_CONFIG_DYNTICKLESS > 0) soc_dyntick_proc(); - g_tick_count += g_pend_intrpt_ticks; g_sys_time_tick += g_pend_intrpt_ticks; #else @@ -96,9 +96,9 @@ void tick_list_update(void) if (iter != tick_head_ptr) { iter_temp = iter->next; p_tcb = krhino_list_entry(iter, ktask_t, tick_list); - + delta = (tick_i_t)p_tcb->tick_match - (tick_i_t)g_tick_count; /* since time list is sorted by remain time, so just campare the absolute time */ - if (g_tick_count == p_tcb->tick_match) { + if (delta <= 0) { switch (p_tcb->task_state) { case K_SLEEP: p_tcb->blk_state = BLK_FINISH; diff --git a/kernel/rhino/core/k_timer.c b/kernel/rhino/core/k_timer.c index 427bb53f54..001d1487be 100755 --- a/kernel/rhino/core/k_timer.c +++ b/kernel/rhino/core/k_timer.c @@ -51,11 +51,11 @@ static kstat_t timer_create(ktimer_t *timer, const name_t *name, timer_cb_t cb, return RHINO_INV_PARAM; } - if (first >= (tick_t)-1) { + if (first >= MAX_TIMER_TICKS) { return RHINO_INV_PARAM; } - if (round >= (tick_t)-1) { + if (round >= MAX_TIMER_TICKS) { return RHINO_INV_PARAM; } @@ -95,25 +95,15 @@ kstat_t krhino_timer_create(ktimer_t *timer, const name_t *name, timer_cb_t cb, kstat_t krhino_timer_del(ktimer_t *timer) { - k_timer_queue_cb *cb; + k_timer_queue_cb cb; kstat_t err; NULL_PARA_CHK(timer); - err = krhino_mblk_alloc(&g_timer_pool, (void **)&cb); - if (err != RHINO_SUCCESS) { - return err; - } - - cb->timer = timer; - cb->cb_num = TIMER_CMD_DEL; - err = krhino_queue_back_send(&g_timer_queue, (void *)cb); - if (err != RHINO_SUCCESS) { - krhino_mblk_free(&g_timer_pool, cb); - return err; - } - - return RHINO_SUCCESS; + cb.timer = timer; + cb.cb_num = TIMER_CMD_DEL; + err = krhino_buf_queue_send(&g_timer_queue, &cb, sizeof(k_timer_queue_cb)); + return err; } #if (RHINO_CONFIG_KOBJ_DYN_ALLOC > 0) @@ -126,11 +116,11 @@ kstat_t krhino_timer_dyn_create(ktimer_t **timer, const name_t *name, NULL_PARA_CHK(timer); - if (first >= (tick_t)-1) { + if (first >= MAX_TIMER_TICKS) { return RHINO_INV_PARAM; } - if (round >= (tick_t)-1) { + if (round >= MAX_TIMER_TICKS) { return RHINO_INV_PARAM; } @@ -154,78 +144,48 @@ kstat_t krhino_timer_dyn_create(ktimer_t **timer, const name_t *name, kstat_t krhino_timer_dyn_del(ktimer_t *timer) { - k_timer_queue_cb *cb; + k_timer_queue_cb cb; kstat_t err; NULL_PARA_CHK(timer); - err = krhino_mblk_alloc(&g_timer_pool, (void **)&cb); - if (err != RHINO_SUCCESS) { - return err; - } - - cb->timer = timer; - cb->cb_num = TIMER_CMD_DYN_DEL; - err = krhino_queue_back_send(&g_timer_queue, (void *)cb); - - if (err != RHINO_SUCCESS) { - krhino_mblk_free(&g_timer_pool, cb); - return err; - } + cb.timer = timer; + cb.cb_num = TIMER_CMD_DYN_DEL; + err = krhino_buf_queue_send(&g_timer_queue, &cb, sizeof(k_timer_queue_cb)); - return RHINO_SUCCESS; + return err; } #endif kstat_t krhino_timer_start(ktimer_t *timer) { - k_timer_queue_cb *cb; + k_timer_queue_cb cb; kstat_t err; NULL_PARA_CHK(timer); - err = krhino_mblk_alloc(&g_timer_pool, (void **)&cb); - if (err != RHINO_SUCCESS) { - return err; - } - - cb->timer = timer; - cb->cb_num = TIMER_CMD_START; - err = krhino_queue_back_send(&g_timer_queue, (void *)cb); - if (err != RHINO_SUCCESS) { - krhino_mblk_free(&g_timer_pool, cb); - return err; - } - - return RHINO_SUCCESS; + cb.timer = timer; + cb.cb_num = TIMER_CMD_START; + err = krhino_buf_queue_send(&g_timer_queue, &cb, sizeof(k_timer_queue_cb)); + return err; } kstat_t krhino_timer_stop(ktimer_t *timer) { - k_timer_queue_cb *cb; + k_timer_queue_cb cb; kstat_t err; NULL_PARA_CHK(timer); - err = krhino_mblk_alloc(&g_timer_pool, (void **)&cb); - if (err != RHINO_SUCCESS) { - return err; - } - - cb->timer = timer; - cb->cb_num = TIMER_CMD_STOP; - err = krhino_queue_back_send(&g_timer_queue, (void *)cb); - if (err != RHINO_SUCCESS) { - krhino_mblk_free(&g_timer_pool, cb); - return err; - } - - return RHINO_SUCCESS; + cb.timer = timer; + cb.cb_num = TIMER_CMD_STOP; + err = krhino_buf_queue_send(&g_timer_queue, &cb, sizeof(k_timer_queue_cb)); + return err; } kstat_t krhino_timer_change(ktimer_t *timer, sys_time_t first, sys_time_t round) { - k_timer_queue_cb *cb; + k_timer_queue_cb cb; kstat_t err; NULL_PARA_CHK(timer); @@ -238,62 +198,56 @@ kstat_t krhino_timer_change(ktimer_t *timer, sys_time_t first, sys_time_t round) return RHINO_INV_PARAM; } - err = krhino_mblk_alloc(&g_timer_pool, (void **)&cb); - if (err != RHINO_SUCCESS) { - return err; - } - - cb->timer = timer; - cb->first = first; - cb->u.round = round; - cb->cb_num = TIMER_CMD_CHG; - err = krhino_queue_back_send(&g_timer_queue, (void *)cb); - if (err != RHINO_SUCCESS) { - krhino_mblk_free(&g_timer_pool, cb); - return err; - } - - return RHINO_SUCCESS; + cb.timer = timer; + cb.first = first; + cb.u.round = round; + cb.cb_num = TIMER_CMD_CHG; + err = krhino_buf_queue_send(&g_timer_queue, &cb, sizeof(k_timer_queue_cb)); + return err; } kstat_t krhino_timer_arg_change(ktimer_t *timer, void *arg) { - k_timer_queue_cb *cb; + k_timer_queue_cb cb; kstat_t err; NULL_PARA_CHK(timer); - err = krhino_mblk_alloc(&g_timer_pool, (void **)&cb); - if (err != RHINO_SUCCESS) { - return err; - } + cb.timer = timer; + cb.u.arg = arg; + cb.cb_num = TIMER_ARG_CHG; + err = krhino_buf_queue_send(&g_timer_queue, &cb, sizeof(k_timer_queue_cb)); + return err; +} - cb->timer = timer; - cb->u.arg = arg; - cb->cb_num = TIMER_ARG_CHG; +kstat_t krhino_timer_arg_change_auto(ktimer_t *timer, void *arg) +{ + k_timer_queue_cb cb; + kstat_t err; - err = krhino_queue_back_send(&g_timer_queue, (void *)cb); - if (err != RHINO_SUCCESS) { - krhino_mblk_free(&g_timer_pool, cb); - return err; - } + NULL_PARA_CHK(timer); - return RHINO_SUCCESS; + cb.timer = timer; + cb.u.arg = arg; + cb.cb_num = TIMER_ARG_CHG_AUTO; + + err = krhino_buf_queue_send(&g_timer_queue, &cb, sizeof(k_timer_queue_cb)); + return err; } static void timer_cb_proc(void) { - klist_t *q; - klist_t *start; - klist_t *end; - ktimer_t *timer; - int64_t delta; + klist_t *q; + klist_t *start; + klist_t *end; + ktimer_t *timer; + sys_time_i_t delta; start = end = &g_timer_head; for (q = start->next; q != end; q = q->next) { timer = krhino_list_entry(q, ktimer_t, timer_list); - delta = (int64_t)timer->match - (int64_t)g_timer_count; + delta = (sys_time_i_t)timer->match - (sys_time_i_t)g_timer_count; if (delta <= 0) { timer->cb(timer, timer->timer_cb_arg); @@ -314,31 +268,6 @@ static void timer_cb_proc(void) } } -kstat_t krhino_timer_arg_change_auto(ktimer_t *timer, void *arg) -{ - k_timer_queue_cb *cb; - kstat_t err; - - NULL_PARA_CHK(timer); - - err = krhino_mblk_alloc(&g_timer_pool, (void **)&cb); - if (err != RHINO_SUCCESS) { - return err; - } - - cb->timer = timer; - cb->u.arg = arg; - cb->cb_num = TIMER_ARG_CHG_AUTO; - - err = krhino_queue_back_send(&g_timer_queue, (void *)cb); - if (err != RHINO_SUCCESS) { - krhino_mblk_free(&g_timer_pool, cb); - return err; - } - - return RHINO_SUCCESS; -} - static void cmd_proc(k_timer_queue_cb *cb, uint8_t cmd) { ktimer_t *timer; @@ -416,6 +345,7 @@ static void cmd_proc(k_timer_queue_cb *cb, uint8_t cmd) timer->obj_type = RHINO_OBJ_TYPE_NONE; TRACE_TIMER_DEL(krhino_cur_task_get(), timer); break; +#if (RHINO_CONFIG_KOBJ_DYN_ALLOC > 0) case TIMER_CMD_DYN_DEL: if (timer->obj_type != RHINO_TIMER_OBJ_TYPE) { break; @@ -433,6 +363,7 @@ static void cmd_proc(k_timer_queue_cb *cb, uint8_t cmd) TRACE_TIMER_DEL(krhino_cur_task_get(), timer); krhino_mm_free(timer); break; +#endif default: k_err_proc(RHINO_SYS_FATAL_ERR); break; @@ -455,18 +386,16 @@ static void timer_cmd_proc(k_timer_queue_cb *cb) static void timer_task(void *pa) { ktimer_t *timer; - void *msg; - k_timer_queue_cb *cb; k_timer_queue_cb cb_msg; kstat_t err; sys_time_t tick_start; sys_time_t tick_end; - int64_t delta; - + sys_time_i_t delta; + size_t msg_size; (void)pa; while (RHINO_TRUE) { - err = krhino_queue_recv(&g_timer_queue, RHINO_CONFIG_NEXT_INTRPT_TICKS, &msg); + err = krhino_buf_queue_recv(&g_timer_queue, RHINO_CONFIG_NEXT_INTRPT_TICKS, &cb_msg, &msg_size); tick_end = krhino_sys_tick_get(); if (err == RHINO_BLK_TIMEOUT) { @@ -474,35 +403,27 @@ static void timer_task(void *pa) continue; } else if (err == RHINO_SUCCESS) { - g_timer_count = tick_end;; + g_timer_count = tick_end; } else { k_err_proc(RHINO_SYS_FATAL_ERR); } - memcpy(&cb_msg, msg, sizeof(k_timer_queue_cb)); - krhino_mblk_free(&g_timer_pool, msg); - cb = &cb_msg; - timer_cmd_proc(cb); + timer_cmd_proc(&cb_msg); while (!is_klist_empty(&g_timer_head)) { timer = krhino_list_entry(g_timer_head.next, ktimer_t, timer_list); tick_start = krhino_sys_tick_get(); - - delta = (int64_t)timer->match - (int64_t)tick_start; + delta = (sys_time_i_t)timer->match - (sys_time_i_t)tick_start; if (delta > 0) { - err = krhino_queue_recv(&g_timer_queue, (tick_t)delta, &msg); - + err = krhino_buf_queue_recv(&g_timer_queue, (tick_t)delta, &cb_msg, &msg_size); tick_end = krhino_sys_tick_get(); if (err == RHINO_BLK_TIMEOUT) { g_timer_count = tick_end; } else if (err == RHINO_SUCCESS) { g_timer_count = tick_end; - memcpy(&cb_msg, msg, sizeof(k_timer_queue_cb)); - krhino_mblk_free(&g_timer_pool, msg); - cb = &cb_msg; - timer_cmd_proc(cb); + timer_cmd_proc(&cb_msg); } else { k_err_proc(RHINO_SYS_FATAL_ERR); @@ -520,10 +441,8 @@ void ktimer_init(void) { klist_init(&g_timer_head); - krhino_queue_create(&g_timer_queue, "timer_queue", (void **)&g_timer_msg, RHINO_CONFIG_TIMER_MSG_NUM); - - krhino_mblk_pool_init(&g_timer_pool, "timer_blk_pool", timer_queue_cb, sizeof(k_timer_queue_cb), sizeof(timer_queue_cb)); - + krhino_fix_buf_queue_create(&g_timer_queue, "timer_queue", + timer_queue_cb, sizeof(k_timer_queue_cb), RHINO_CONFIG_TIMER_MSG_NUM); krhino_task_create(&g_timer_task, "timer_task", NULL, RHINO_CONFIG_TIMER_TASK_PRI, 0u, g_timer_task_stack, RHINO_CONFIG_TIMER_TASK_STACK_SIZE, timer_task, 1u); diff --git a/kernel/rhino/core/k_workqueue.c b/kernel/rhino/core/k_workqueue.c index 670d99129b..4b97d8e9fc 100755 --- a/kernel/rhino/core/k_workqueue.c +++ b/kernel/rhino/core/k_workqueue.c @@ -5,9 +5,6 @@ #include #if (RHINO_CONFIG_WORKQUEUE > 0) -extern kworkqueue_t g_workqueue_default; -extern cpu_stack_t g_workqueue_stack[RHINO_CONFIG_WORKQUEUE_STACK_SIZE]; - static kstat_t workqueue_is_exist(kworkqueue_t *workqueue) { CPSR_ALLOC(); @@ -96,19 +93,17 @@ kstat_t krhino_workqueue_create(kworkqueue_t *workqueue, const name_t *name, return ret; } - ret = krhino_task_create(&(workqueue->worker), name, (void *)workqueue, pri, - 0, stack_buf, stack_size, worker_task, 0); - if (ret != RHINO_SUCCESS) { - krhino_sem_del(&(workqueue->sem)); - return ret; - } - RHINO_CRITICAL_ENTER(); klist_insert(&g_workqueue_list_head, &(workqueue->workqueue_node)); RHINO_CRITICAL_EXIT(); - ret = krhino_task_resume(&(workqueue->worker)); + ret = krhino_task_create(&(workqueue->worker), name, (void *)workqueue, pri, + 0, stack_buf, stack_size, worker_task, 1); if (ret != RHINO_SUCCESS) { + RHINO_CRITICAL_ENTER(); + klist_rm_init(&(workqueue->workqueue_node)); + RHINO_CRITICAL_EXIT(); + krhino_sem_del(&(workqueue->sem)); return ret; } diff --git a/kernel/rhino/rhino.mk b/kernel/rhino/rhino.mk old mode 100644 new mode 100755 index 0dc472c362..9de9790706 --- a/kernel/rhino/rhino.mk +++ b/kernel/rhino/rhino.mk @@ -12,7 +12,7 @@ else ifeq ($(COMPILER),gcc) $(NAME)_CFLAGS += -Wall -Werror endif -CONFIG_SYSINFO_KERNEL_VERSION = AOS-R-1.1.2 +CONFIG_SYSINFO_KERNEL_VERSION = AOS-R-1.2.0 GLOBAL_CFLAGS += -DSYSINFO_KERNEL_VERSION=\"$(CONFIG_SYSINFO_KERNEL_VERSION)\" $(info kernel_version:${CONFIG_SYSINFO_KERNEL_VERSION}) @@ -40,6 +40,6 @@ $(NAME)_SOURCES := core/k_err.c \ core/k_sem.c \ core/k_task.c \ core/k_time.c \ - core/k_fifo.c \ - core/k_trace.c + common/k_fifo.c \ + common/k_trace.c diff --git a/kernel/rhino/test/core/buf_queue/buf_queue_recv.c b/kernel/rhino/test/core/buf_queue/buf_queue_recv.c index bc04404f65..8cec642ca7 100644 --- a/kernel/rhino/test/core/buf_queue/buf_queue_recv.c +++ b/kernel/rhino/test/core/buf_queue/buf_queue_recv.c @@ -27,7 +27,10 @@ static char g_test_send_msg0[TEST_BUFQUEUE_MSG0_SIZE] = {0}; static char g_test_send_msg1[TEST_BUFQUEUE_MSG0_SIZE] = {0}; static char g_test_recv_msg0[TEST_BUFQUEUE_MSG0_SIZE] = {0}; static char g_test_bufqueue_buf0[TEST_BUFQUEUE_BUF0_SIZE] = {0}; +static size_t g_test_bufqueue_buf1[2] = {0}; + static kbuf_queue_t g_test_bufqueue0; +static kbuf_queue_t g_test_bufqueue1; static void buf_queue_recv_param_test(void) { @@ -158,6 +161,7 @@ static void task_queue0_entry(void *arg) kstat_t ret; size_t size; int count = 0; + size_t msg; /* err param test */ ret = krhino_buf_queue_create(&g_test_bufqueue0, "test_bufqueue0", @@ -172,6 +176,27 @@ static void task_queue0_entry(void *arg) BUFQUEUE_VAL_CHK(ret == RHINO_SUCCESS); + ret = krhino_fix_buf_queue_create(&g_test_bufqueue1, "test_bufqueue1", + (void *)g_test_bufqueue_buf1, sizeof(size_t), 2); + + BUFQUEUE_VAL_CHK(ret == RHINO_SUCCESS); + + msg = 0x11; + ret = krhino_buf_queue_send(&g_test_bufqueue1, &msg, sizeof(size_t)); + BUFQUEUE_VAL_CHK(ret == RHINO_SUCCESS); + + ret = krhino_buf_queue_send(&g_test_bufqueue1, &msg, sizeof(size_t)); + BUFQUEUE_VAL_CHK(ret == RHINO_SUCCESS); + + ret = krhino_buf_queue_send(&g_test_bufqueue1, &msg, sizeof(size_t)); + BUFQUEUE_VAL_CHK(ret == RHINO_BUF_QUEUE_FULL); + + krhino_buf_queue_recv(&g_test_bufqueue1, RHINO_NO_WAIT, &msg, &size); + krhino_buf_queue_recv(&g_test_bufqueue1, RHINO_NO_WAIT, &msg, &size); + + ret = krhino_buf_queue_recv(&g_test_bufqueue1, 1, &msg, &size); + BUFQUEUE_VAL_CHK(ret == RHINO_BLK_TIMEOUT); + /* check krhino_buf_queue_recv */ buf_queue_recv_param_test(); diff --git a/kernel/rhino/test/core/mm/mm_break.c b/kernel/rhino/test/core/mm/mm_break.c index 566237e15a..2dda4534c9 100644 --- a/kernel/rhino/test/core/mm/mm_break.c +++ b/kernel/rhino/test/core/mm/mm_break.c @@ -86,7 +86,7 @@ static uint8_t mm_break_case1(void) k_mm_free(pmmhead, ptr); for (i = 0; i < 10; i++) { - ptrarray[i] = k_mm_alloc(pmmhead, (i + 1) * 32); + ptrarray[i] = k_mm_alloc(pmmhead, (i + 1) * 2); MYASSERT(ptrarray[i]); } @@ -98,7 +98,7 @@ static uint8_t mm_break_case1(void) for (i = 0; i < 10; i++) { if (i % 2 != 0) { - ptrarray[i] = k_mm_realloc(pmmhead, ptrarray[i], (i + 1) * 96); + ptrarray[i] = k_mm_realloc(pmmhead, ptrarray[i], (i + 1) * 3); } MYASSERT(ptrarray[i]); } diff --git a/kernel/rhino/test/core/mm/mm_opr.c b/kernel/rhino/test/core/mm/mm_opr.c index 2bf02cd04f..3c4c403bcc 100644 --- a/kernel/rhino/test/core/mm/mm_opr.c +++ b/kernel/rhino/test/core/mm/mm_opr.c @@ -50,7 +50,7 @@ static uint8_t mm_opr_case2(void) /* alloc out of mm pools then free all */ cnt = 0; for (cnt = 0; cnt < 16; ++cnt) { - r_ptr[cnt] = k_mm_alloc(pmmhead, 1023); + r_ptr[cnt] = k_mm_alloc(pmmhead, cnt + 26); if (r_ptr[cnt] == NULL) { break; } @@ -98,50 +98,28 @@ static void task_mm_co1_entry(void *arg) return; } - while (1) { - co_ptr = k_mm_alloc(pmmhead, 16); - krhino_task_sleep(5); - co_ptr = k_mm_alloc(pmmhead, 18); - krhino_task_sleep(5); - co_ptr = k_mm_alloc(pmmhead, 32); - krhino_task_sleep(5); - co_ptr = k_mm_alloc(pmmhead, 65); - krhino_task_sleep(5); - co_ptr = k_mm_alloc(pmmhead, 178); - krhino_task_sleep(5); - co_ptr = k_mm_alloc(pmmhead, 333); - krhino_task_sleep(5); - break; - } + co_ptr = k_mm_alloc(pmmhead, 16); + k_mm_free(pmmhead, co_ptr); - krhino_task_dyn_del(krhino_cur_task_get()); -} + co_ptr = k_mm_alloc(pmmhead, 18); + k_mm_free(pmmhead, co_ptr); -static void task_mm_co2_entry(void *arg) -{ - while (1) { - k_mm_free(pmmhead, co_ptr); - krhino_task_sleep(5); - k_mm_free(pmmhead, co_ptr); - krhino_task_sleep(5); - k_mm_free(pmmhead, co_ptr); - krhino_task_sleep(5); - k_mm_free(pmmhead, co_ptr); - krhino_task_sleep(5); - k_mm_free(pmmhead, co_ptr); - krhino_task_sleep(5); - k_mm_free(pmmhead, co_ptr); - krhino_task_sleep(5); - break; - } + co_ptr = k_mm_alloc(pmmhead, 32); + k_mm_free(pmmhead, co_ptr); - test_case_success++; - PRINT_RESULT(MODULE_NAME_CO, PASS); + co_ptr = k_mm_alloc(pmmhead, 65); + k_mm_free(pmmhead, co_ptr); - next_test_case_notify(); - krhino_task_dyn_del(krhino_cur_task_get()); + co_ptr = k_mm_alloc(pmmhead, 178); + k_mm_free(pmmhead, co_ptr); + + co_ptr = k_mm_alloc(pmmhead, 333); + k_mm_free(pmmhead, co_ptr); krhino_deinit_mm_head(pmmhead); + + next_test_case_notify(); + krhino_task_dyn_del(krhino_cur_task_get()); } void mm_coopr_test(void) @@ -162,12 +140,6 @@ void mm_coopr_test(void) PRINT_RESULT(MODULE_NAME_CO, FAIL); } - ret = krhino_task_dyn_create(&task_mm_co, MODULE_NAME, 0, TASK_MM_PRI + 1, - 0, TASK_TEST_STACK_SIZE, task_mm_co2_entry, 1); - if ((ret != RHINO_SUCCESS) && (ret != RHINO_STOPPED)) { - test_case_fail++; - PRINT_RESULT(MODULE_NAME_CO, FAIL); - } } #endif diff --git a/kernel/rhino/test/core/mm/mm_param.c b/kernel/rhino/test/core/mm/mm_param.c index 0de81f98f7..2e5557226d 100644 --- a/kernel/rhino/test/core/mm/mm_param.c +++ b/kernel/rhino/test/core/mm/mm_param.c @@ -20,54 +20,11 @@ static uint8_t mm_param_case1(void) ret = krhino_init_mm_head(&pmmhead, NULL, MM_POOL_SIZE); MYASSERT(ret == RHINO_NULL_PTR); - ret = krhino_init_mm_head(&pmmhead, (void *)mm_pool, - MIN_FREE_MEMORY_SIZE + RHINO_CONFIG_MM_TLF_BLK_SIZE - 4); + ret = krhino_init_mm_head(&pmmhead, (void *)mm_pool, MIN_FREE_MEMORY_SIZE + RHINO_CONFIG_MM_TLF_BLK_SIZE - 1); MYASSERT(ret == RHINO_MM_POOL_SIZE_ERR); - ret = krhino_init_mm_head(&pmmhead, (void *)(mm_pool + 1), MM_POOL_SIZE); - MYASSERT(ret == RHINO_SUCCESS); - - ret = krhino_deinit_mm_head(pmmhead); - MYASSERT(ret == RHINO_SUCCESS); - - ret = krhino_init_mm_head(&pmmhead, (void *)mm_pool, MM_POOL_SIZE - 1); - MYASSERT(ret == RHINO_SUCCESS); - - ret = krhino_deinit_mm_head(pmmhead); - MYASSERT(ret == RHINO_SUCCESS); - ret = krhino_init_mm_head(&pmmhead, (void *)mm_pool, MM_POOL_SIZE); MYASSERT(ret == RHINO_SUCCESS); - - ret = krhino_add_mm_region(NULL, (void *)&mm_pool[MM_POOL_SIZE], MM_POOL_SIZE); - MYASSERT(ret == RHINO_NULL_PTR); - - ret = krhino_add_mm_region(pmmhead, NULL, MM_POOL_SIZE); - MYASSERT(ret == RHINO_NULL_PTR); - - ret = krhino_add_mm_region(pmmhead, (void *)&mm_pool[MM_POOL_SIZE], 4); - MYASSERT(ret == RHINO_MM_POOL_SIZE_ERR); - - ret = krhino_add_mm_region(pmmhead, (void *)(&mm_pool[MM_POOL_SIZE] + 1), - MM_POOL_SIZE); - MYASSERT(ret == RHINO_INV_ALIGN); - - ret = krhino_add_mm_region(pmmhead, (void *)&mm_pool[MM_POOL_SIZE], - MM_POOL_SIZE - 1); - MYASSERT(ret == RHINO_INV_ALIGN); - - ret = krhino_add_mm_region(pmmhead, (void *)&mm_pool[MM_POOL_SIZE], - MM_POOL_SIZE); - MYASSERT(ret == RHINO_SUCCESS); - - ret = krhino_add_mm_region(pmmhead, (void *)&mm_pool[MM_POOL_SIZE * 3], - MM_POOL_SIZE); - MYASSERT(ret == RHINO_SUCCESS); - - ret = krhino_add_mm_region(pmmhead, (void *)&mm_pool[MM_POOL_SIZE * 2], - MM_POOL_SIZE); - MYASSERT(ret == RHINO_SUCCESS); - ret = krhino_deinit_mm_head(pmmhead); MYASSERT(ret == RHINO_SUCCESS); @@ -78,8 +35,10 @@ static uint8_t mm_param_case2(void) { void *ptr; void *tmp; + kstat_t ret; - krhino_init_mm_head(&pmmhead, (void *)mm_pool, MM_POOL_SIZE); + ret = krhino_init_mm_head(&pmmhead, (void *)mm_pool, MM_POOL_SIZE); + MYASSERT(ret == RHINO_SUCCESS); ptr = k_mm_alloc( NULL, 64); MYASSERT(ptr == NULL); @@ -88,22 +47,14 @@ static uint8_t mm_param_case2(void) MYASSERT(ptr == NULL); ptr = k_mm_alloc(pmmhead, 64); - - MYASSERT((ptr > (void *)mm_pool && ptr < (void *)mm_pool + MM_POOL_SIZE) - || (ptr > (void *)&mm_pool[MM_POOL_SIZE] && - ptr < (void *)&mm_pool[MM_POOL_SIZE * 2] )); - + MYASSERT((ptr > (void *)mm_pool) && (ptr < ((void *)mm_pool + MM_POOL_SIZE))); k_mm_free(pmmhead, ptr); ptr = k_mm_alloc(pmmhead, 16); - VGF(VALGRIND_MAKE_MEM_DEFINED(pmmhead, sizeof(k_mm_head))); - VGF(VALGRIND_MAKE_MEM_DEFINED(pmmhead->fixedmblk, MMLIST_HEAD_SIZE)); tmp = pmmhead->fixedmblk->mbinfo.buffer; MYASSERT((ptr > (void *)pmmhead->fixedmblk->mbinfo.buffer) && (ptr < ((void *)tmp + (pmmhead->fixedmblk->size & RHINO_MM_BLKSIZE_MASK)))); - VGF(VALGRIND_MAKE_MEM_NOACCESS(pmmhead->fixedmblk, MMLIST_HEAD_SIZE)); - VGF(VALGRIND_MAKE_MEM_NOACCESS(pmmhead, sizeof(k_mm_head))); k_mm_free(pmmhead, ptr); diff --git a/kernel/rhino/test/core/mm/mm_test.c b/kernel/rhino/test/core/mm/mm_test.c index e22ea0f20f..1f81eac671 100644 --- a/kernel/rhino/test/core/mm/mm_test.c +++ b/kernel/rhino/test/core/mm/mm_test.c @@ -11,19 +11,17 @@ ktask_t *task_mm; ktask_t *task_mm_co; k_mm_head *pmmhead; -char mm_pool[MM_POOL_SIZE * 4] = {0}; - +char mm_pool[MM_POOL_SIZE] = {0}; static test_func_t *module_runner; static const char *module_name; static uint8_t module_casenum; static const test_case_t mm_case_runner[] = { - //mm_param_test, - /*mm_reinit_test,*/ - //mm_break_test, - //mm_opr_test, - //mm_coopr_test, + mm_param_test, + mm_break_test, + mm_opr_test, + mm_coopr_test, NULL }; diff --git a/kernel/rhino/test/core/mm/mm_test.h b/kernel/rhino/test/core/mm/mm_test.h index 1a903d94a4..c0bac3ed9a 100644 --- a/kernel/rhino/test/core/mm/mm_test.h +++ b/kernel/rhino/test/core/mm/mm_test.h @@ -7,7 +7,7 @@ #define TASK_MM_PRI 16 #define TASK_TEST_STACK_SIZE 1024 -#define MM_POOL_SIZE (1024 * 4) +#define MM_POOL_SIZE (1024 * 11) #define MYASSERT(value) do {if ((int)(value) == 0) { printf("%s:%d\n", __FUNCTION__, __LINE__);return 1; }} while (0) @@ -15,7 +15,7 @@ extern ktask_t *task_mm; extern ktask_t *task_mm_co; extern k_mm_head *pmmhead; -extern char mm_pool[MM_POOL_SIZE * 4]; +extern char mm_pool[MM_POOL_SIZE]; typedef uint8_t (*test_func_t)(void); diff --git a/kernel/vcall/aos/aos_rhino.c b/kernel/vcall/aos/aos_rhino.c index 4404bcf198..3b94e91089 100755 --- a/kernel/vcall/aos/aos_rhino.c +++ b/kernel/vcall/aos/aos_rhino.c @@ -322,6 +322,73 @@ void aos_sem_signal_all(aos_sem_t *sem) krhino_sem_give_all(sem->hdl); } +int aos_event_new(aos_event_t *event, unsigned int flags) +{ + int ret; + ret = (int)krhino_event_dyn_create((kevent_t **)(&(event->hdl)), "AOS", flags); + if (ret == RHINO_SUCCESS) { + return 0; + } + + ERRNO_MAPPING(ret); +} + +void aos_event_free(aos_event_t *event) +{ + if (event == NULL) { + return; + } + + krhino_event_dyn_del(event->hdl); + + event->hdl = NULL; +} + +int aos_event_get + ( + aos_event_t *event, + unsigned int flags, + unsigned char opt, + unsigned int *actl_flags, + unsigned int timeout + ) +{ + kstat_t ret; + + if (event == NULL) { + return -EINVAL; + } + + if (timeout == AOS_WAIT_FOREVER) { + ret = krhino_event_get(event->hdl, flags, opt, actl_flags, RHINO_WAIT_FOREVER); + } else { + ret = krhino_event_get(event->hdl, flags, opt, actl_flags, MS2TICK(timeout)); + } + + if (ret == RHINO_SUCCESS) { + return 0; + } + + ERRNO_MAPPING(ret); +} + +int aos_event_set(aos_event_t *event, unsigned int flags, unsigned char opt) +{ + kstat_t ret; + + if (event == NULL) { + return -EINVAL; + } + + ret = krhino_event_set(event->hdl, flags, opt); + + if (ret == RHINO_SUCCESS) { + return 0; + } + + ERRNO_MAPPING(ret); +} + int aos_queue_new(aos_queue_t *queue, void *buf, unsigned int size, int max_msg) { kstat_t ret; diff --git a/kernel/vfs/vfs.c b/kernel/vfs/vfs.c index 0bef20b242..dc33a25067 100644 --- a/kernel/vfs/vfs.c +++ b/kernel/vfs/vfs.c @@ -697,7 +697,7 @@ AOS_EXPORT(int, aos_mkdir, const char *); #if (AOS_CONFIG_VFS_POLL_SUPPORT>0) -#if !defined(WITH_LWIP) && defined(VCALL_RHINO) +#if !defined(WITH_LWIP) && !defined(WITH_SAL)&& defined(VCALL_RHINO) #define NEED_WAIT_IO #endif diff --git a/kernel/vfs/vfs.mk b/kernel/vfs/vfs.mk index 75b652a492..5d8f0acce4 100644 --- a/kernel/vfs/vfs.mk +++ b/kernel/vfs/vfs.mk @@ -6,7 +6,10 @@ $(NAME)_SOURCES += device.c $(NAME)_SOURCES += vfs_inode.c $(NAME)_SOURCES += vfs_register.c +ifeq ($(HOST_ARCH),linux) $(NAME)_DEFINES += IO_NEED_TRAP +endif + #default gcc ifeq ($(COMPILER),) $(NAME)_CFLAGS += -Wall -Werror diff --git a/platform/arch/arm/armv5/k_types.h b/platform/arch/arm/armv5/k_types.h old mode 100644 new mode 100755 index 0e608d5957..130cf4616c --- a/platform/arch/arm/armv5/k_types.h +++ b/platform/arch/arm/armv5/k_types.h @@ -5,23 +5,17 @@ #ifndef TYPES_H #define TYPES_H -#define RHINO_NO_WAIT 0u -#define RHINO_WAIT_FOREVER 0xffffffffu /* 32 bit value, if tick type is 64 bit, you need change it to 64 bit */ #define RHINO_TASK_STACK_OVF_MAGIC 0xdeadbeafu /* 32 bit or 64 bit stack overflow magic value */ #define RHINO_INTRPT_STACK_OVF_MAGIC 0xdeaddeadu /* 32 bit or 64 bit stack overflow magic value */ -#define RHINO_MM_FRAG_ALLOCATED 0xabcddcabu /* 32 bit value, if 64 bit system, you need change it to 64 bit */ -#define RHINO_MM_FRAG_FREE 0xfefdecdbu /* 32 bit value, if 64 bit system, you need change it to 64 bit */ +#define RHINO_MM_CORRUPT_DYE 0xFEFEFEFE +#define RHINO_MM_FREE_DYE 0xABABABAB #define RHINO_INLINE static __inline /* inline keyword, it may change under different compilers */ typedef char name_t; typedef uint32_t sem_count_t; typedef uint32_t cpu_stack_t; - typedef uint32_t hr_timer_t; typedef uint32_t lr_timer_t; - -typedef uint32_t tick_t; -typedef uint64_t idle_count_t; typedef uint32_t mutex_nested_t; typedef uint8_t suspend_nested_t; diff --git a/platform/arch/arm/armv6m/armcc/m0plus/k_types.h b/platform/arch/arm/armv6m/armcc/m0plus/k_types.h old mode 100644 new mode 100755 index e0da6783bb..de2eaf3b59 --- a/platform/arch/arm/armv6m/armcc/m0plus/k_types.h +++ b/platform/arch/arm/armv6m/armcc/m0plus/k_types.h @@ -5,24 +5,17 @@ #ifndef TYPES_H #define TYPES_H -#define RHINO_NO_WAIT 0u -#define RHINO_WAIT_FOREVER 0xffffffffu /* 32 bit value, if tick type is 64 bit, you need change it to 64 bit */ #define RHINO_TASK_STACK_OVF_MAGIC 0xdeadbeafu /* 32 bit or 64 bit stack overflow magic value */ #define RHINO_INTRPT_STACK_OVF_MAGIC 0xdeaddeadu /* 32 bit or 64 bit stack overflow magic value */ -#define RHINO_MM_FRAG_ALLOCATED 0xabcddcabu /* 32 bit value, if 64 bit system, you need change it to 64 bit */ -#define RHINO_MM_FRAG_FREE 0xfefdecdbu /* 32 bit value, if 64 bit system, you need change it to 64 bit */ +#define RHINO_MM_CORRUPT_DYE 0xFEFEFEFE +#define RHINO_MM_FREE_DYE 0xABABABAB #define RHINO_INLINE static __inline /* inline keyword, it may change under different compilers */ typedef char name_t; typedef uint32_t sem_count_t; typedef uint32_t cpu_stack_t; - typedef uint32_t hr_timer_t; typedef uint32_t lr_timer_t; - -typedef uint32_t tick_t; -typedef uint64_t idle_count_t; -typedef uint64_t sys_time_t; typedef uint32_t mutex_nested_t; typedef uint8_t suspend_nested_t; diff --git a/platform/arch/arm/armv6m/gcc/m0plus/k_types.h b/platform/arch/arm/armv6m/gcc/m0plus/k_types.h old mode 100644 new mode 100755 index a2078dc606..60a39ce417 --- a/platform/arch/arm/armv6m/gcc/m0plus/k_types.h +++ b/platform/arch/arm/armv6m/gcc/m0plus/k_types.h @@ -5,24 +5,18 @@ #ifndef TYPES_H #define TYPES_H -#define RHINO_NO_WAIT 0u -#define RHINO_WAIT_FOREVER 0xffffffffu /* 32 bit value, if tick type is 64 bit, you need change it to 64 bit */ #define RHINO_TASK_STACK_OVF_MAGIC 0xdeadbeafu /* 32 bit or 64 bit stack overflow magic value */ #define RHINO_INTRPT_STACK_OVF_MAGIC 0xdeaddeadu /* 32 bit or 64 bit stack overflow magic value */ -#define RHINO_MM_FRAG_ALLOCATED 0xabcddcabu /* 32 bit value, if 64 bit system, you need change it to 64 bit */ -#define RHINO_MM_FRAG_FREE 0xfefdecdbu /* 32 bit value, if 64 bit system, you need change it to 64 bit */ +#define RHINO_MM_CORRUPT_DYE 0xFEFEFEFE +#define RHINO_MM_FREE_DYE 0xABABABAB + #define RHINO_INLINE static __inline /* inline keyword, it may change under different compilers */ typedef char name_t; typedef uint32_t sem_count_t; typedef uint32_t cpu_stack_t; - typedef uint32_t hr_timer_t; typedef uint32_t lr_timer_t; - -typedef uint32_t tick_t; -typedef uint64_t idle_count_t; -typedef uint64_t sys_time_t; typedef uint32_t mutex_nested_t; typedef uint8_t suspend_nested_t; diff --git a/platform/arch/arm/armv7m/EWARM/m4/k_types.h b/platform/arch/arm/armv7m/EWARM/m4/k_types.h old mode 100644 new mode 100755 index a97fe96549..50f99c3f41 --- a/platform/arch/arm/armv7m/EWARM/m4/k_types.h +++ b/platform/arch/arm/armv7m/EWARM/m4/k_types.h @@ -5,12 +5,11 @@ #ifndef TYPES_H #define TYPES_H -#define RHINO_NO_WAIT 0u -#define RHINO_WAIT_FOREVER 0xffffffffu /* 32 bit value, if tick type is 64 bit, you need change it to 64 bit */ #define RHINO_TASK_STACK_OVF_MAGIC 0xdeadbeafu /* 32 bit or 64 bit stack overflow magic value */ #define RHINO_INTRPT_STACK_OVF_MAGIC 0xdeaddeadu /* 32 bit or 64 bit stack overflow magic value */ -#define RHINO_MM_FRAG_ALLOCATED 0xabcddcabu /* 32 bit value, if 64 bit system, you need change it to 64 bit */ -#define RHINO_MM_FRAG_FREE 0xfefdecdbu /* 32 bit value, if 64 bit system, you need change it to 64 bit */ +#define RHINO_MM_CORRUPT_DYE 0xFEFEFEFE +#define RHINO_MM_FREE_DYE 0xABABABAB + #ifdef __ICCARM__ #define RHINO_INLINE static inline #else @@ -20,15 +19,10 @@ typedef char name_t; typedef uint32_t sem_count_t; typedef uint32_t cpu_stack_t; - typedef uint32_t hr_timer_t; typedef uint32_t lr_timer_t; - -typedef uint32_t tick_t; -typedef uint64_t idle_count_t; typedef uint32_t mutex_nested_t; typedef uint8_t suspend_nested_t; - typedef uint64_t ctx_switch_t; /* keil compiler not define ssize_t */ diff --git a/platform/arch/arm/armv7m/armcc/m4/k_types.h b/platform/arch/arm/armv7m/armcc/m4/k_types.h old mode 100644 new mode 100755 index 242c243d16..de2eaf3b59 --- a/platform/arch/arm/armv7m/armcc/m4/k_types.h +++ b/platform/arch/arm/armv7m/armcc/m4/k_types.h @@ -5,23 +5,17 @@ #ifndef TYPES_H #define TYPES_H -#define RHINO_NO_WAIT 0u -#define RHINO_WAIT_FOREVER 0xffffffffu /* 32 bit value, if tick type is 64 bit, you need change it to 64 bit */ #define RHINO_TASK_STACK_OVF_MAGIC 0xdeadbeafu /* 32 bit or 64 bit stack overflow magic value */ #define RHINO_INTRPT_STACK_OVF_MAGIC 0xdeaddeadu /* 32 bit or 64 bit stack overflow magic value */ -#define RHINO_MM_FRAG_ALLOCATED 0xabcddcabu /* 32 bit value, if 64 bit system, you need change it to 64 bit */ -#define RHINO_MM_FRAG_FREE 0xfefdecdbu /* 32 bit value, if 64 bit system, you need change it to 64 bit */ +#define RHINO_MM_CORRUPT_DYE 0xFEFEFEFE +#define RHINO_MM_FREE_DYE 0xABABABAB #define RHINO_INLINE static __inline /* inline keyword, it may change under different compilers */ typedef char name_t; typedef uint32_t sem_count_t; typedef uint32_t cpu_stack_t; - typedef uint32_t hr_timer_t; typedef uint32_t lr_timer_t; - -typedef uint32_t tick_t; -typedef uint64_t idle_count_t; typedef uint32_t mutex_nested_t; typedef uint8_t suspend_nested_t; diff --git a/platform/arch/arm/armv7m/armcc/m4/port_c.s b/platform/arch/arm/armv7m/armcc/m4/port_s.s similarity index 100% rename from platform/arch/arm/armv7m/armcc/m4/port_c.s rename to platform/arch/arm/armv7m/armcc/m4/port_s.s diff --git a/platform/arch/arm/armv7m/armv7m.mk b/platform/arch/arm/armv7m/armv7m.mk index 476cf3e312..5f1e90e34f 100644 --- a/platform/arch/arm/armv7m/armv7m.mk +++ b/platform/arch/arm/armv7m/armv7m.mk @@ -2,7 +2,7 @@ NAME := armv7m ifeq ($(COMPILER),armcc) $(NAME)_SOURCES := armcc/m4/port_c.c -$(NAME)_SOURCES += armcc/m4/port_c.s +$(NAME)_SOURCES += armcc/m4/port_s.s GLOBAL_INCLUDES += armcc/m4/ else ifeq ($(COMPILER),iar) $(NAME)_SOURCES := EWARM/m4/port_c.c diff --git a/platform/arch/arm/armv7m/gcc/m4/k_types.h b/platform/arch/arm/armv7m/gcc/m4/k_types.h old mode 100644 new mode 100755 index 0e608d5957..d60d75909a --- a/platform/arch/arm/armv7m/gcc/m4/k_types.h +++ b/platform/arch/arm/armv7m/gcc/m4/k_types.h @@ -5,26 +5,19 @@ #ifndef TYPES_H #define TYPES_H -#define RHINO_NO_WAIT 0u -#define RHINO_WAIT_FOREVER 0xffffffffu /* 32 bit value, if tick type is 64 bit, you need change it to 64 bit */ #define RHINO_TASK_STACK_OVF_MAGIC 0xdeadbeafu /* 32 bit or 64 bit stack overflow magic value */ #define RHINO_INTRPT_STACK_OVF_MAGIC 0xdeaddeadu /* 32 bit or 64 bit stack overflow magic value */ -#define RHINO_MM_FRAG_ALLOCATED 0xabcddcabu /* 32 bit value, if 64 bit system, you need change it to 64 bit */ -#define RHINO_MM_FRAG_FREE 0xfefdecdbu /* 32 bit value, if 64 bit system, you need change it to 64 bit */ +#define RHINO_MM_CORRUPT_DYE 0xFEFEFEFE +#define RHINO_MM_FREE_DYE 0xABABABAB #define RHINO_INLINE static __inline /* inline keyword, it may change under different compilers */ typedef char name_t; typedef uint32_t sem_count_t; typedef uint32_t cpu_stack_t; - typedef uint32_t hr_timer_t; typedef uint32_t lr_timer_t; - -typedef uint32_t tick_t; -typedef uint64_t idle_count_t; typedef uint32_t mutex_nested_t; typedef uint8_t suspend_nested_t; - typedef uint64_t ctx_switch_t; #endif /* TYPES_H */ diff --git a/platform/arch/csky/cskyv2-l/k_types.h b/platform/arch/csky/cskyv2-l/k_types.h old mode 100644 new mode 100755 index feea95dd24..3e03c57ea8 --- a/platform/arch/csky/cskyv2-l/k_types.h +++ b/platform/arch/csky/cskyv2-l/k_types.h @@ -5,29 +5,21 @@ #ifndef TYPES_H #define TYPES_H -#define RHINO_NO_WAIT 0u -#define RHINO_WAIT_FOREVER 0xffffffffu /* 32 bit value, if tick type is 64 bit, you need change it to 64 bit */ #define RHINO_TASK_STACK_OVF_MAGIC 0xdeadbeafu /* 32 bit or 64 bit stack overflow magic value */ #define RHINO_INTRPT_STACK_OVF_MAGIC 0xdeaddeadu /* 32 bit or 64 bit stack overflow magic value */ -#define RHINO_MM_FRAG_ALLOCATED 0xabcddcabu /* 32 bit value, if 64 bit system, you need change it to 64 bit */ -#define RHINO_MM_FRAG_FREE 0xfefdecdbu /* 32 bit value, if 64 bit system, you need change it to 64 bit */ +#define RHINO_MM_CORRUPT_DYE 0xFEFEFEFE +#define RHINO_MM_FREE_DYE 0xABABABAB #define RHINO_INLINE static __inline /* inline keyword, it may change under different compilers */ typedef char name_t; typedef uint32_t sem_count_t; typedef uint32_t cpu_stack_t; - /* you may change here depend on your hardware timer */ typedef uint32_t hr_timer_t; /* 32 bit or 64 bit unsigned value */ typedef uint32_t lr_timer_t; /* 32 bit or 64 bit unsigned value */ - -typedef uint32_t tick_t; /* 32 bit or 64 bit unsigned value */ -typedef uint64_t idle_count_t; /* 64 bit unsigned value */ typedef uint32_t mutex_nested_t; /* 8 bit or 16bit or 32bit unsigned value */ typedef uint8_t suspend_nested_t; /* 8 bit normally */ - typedef uint64_t ctx_switch_t; /* 32 bit or 64 bit unsigned value */ - typedef int32_t ssize_t; #endif /* TYPES_H */ diff --git a/platform/arch/linux/k_types.h b/platform/arch/linux/k_types.h old mode 100644 new mode 100755 index 631807b9e3..73855b1d97 --- a/platform/arch/linux/k_types.h +++ b/platform/arch/linux/k_types.h @@ -8,27 +8,20 @@ #include /* Be very careful here, you can modyfy the following code, if only you understand what yor are doing! */ -#define RHINO_NO_WAIT 0u -#define RHINO_WAIT_FOREVER 0xffffffffu /* 32 bit value, if tick type is 64 bit, you need change it to 64 bit */ #define RHINO_TASK_STACK_OVF_MAGIC 0xdeadbeafu /* 32 bit or 64 bit stack overflow magic value */ #define RHINO_INTRPT_STACK_OVF_MAGIC 0xdeaddeadu /* 32 bit or 64 bit stack overflow magic value */ -#define RHINO_MM_FRAG_ALLOCATED 0xabcddcabu /* 32 bit value, if 64 bit system , you need change it to 64 bit */ -#define RHINO_MM_FRAG_FREE 0xfefdecdbu /* 32 bit value, if 64 bit system , you need change it to 64 bit */ +#define RHINO_MM_CORRUPT_DYE 0xFEFEFEFE +#define RHINO_MM_FREE_DYE 0xABABABAB #define RHINO_INLINE static __inline /* inline keyword, it may change under different compilers */ typedef char name_t; typedef uint32_t sem_count_t; typedef uint32_t cpu_stack_t; - /* you may change here depend on your hardware timer */ typedef uint32_t hr_timer_t; /* 32 bit or 64 bit unsigned value */ typedef uint32_t lr_timer_t; /* 32 bit or 64 bit unsigned value */ - -typedef uint32_t tick_t; /* 32 bit or 64 bit unsigned value */ -typedef uint64_t idle_count_t; /* 64 bit unsigned value */ typedef uint32_t mutex_nested_t; /* 8 bit or 16bit or 32bit unsigned value */ typedef uint8_t suspend_nested_t; /* 8 bit normally */ - typedef uint64_t ctx_switch_t; /* 32 bit or 64 bit unsigned value */ #if (RHINO_CONFIG_CPU_NUM > 1) diff --git a/platform/arch/linux/linux.mk b/platform/arch/linux/linux.mk new file mode 100755 index 0000000000..176a91b204 --- /dev/null +++ b/platform/arch/linux/linux.mk @@ -0,0 +1,12 @@ +NAME := arch_linux + +$(NAME)_SOURCES:= + +ifneq ($(vcall),posix) +$(NAME)_SOURCES += cpu_impl.c +ifeq ($(PLATFORM),linuxhost) +$(NAME)_SOURCES += swap.S +endif +endif + +GLOBAL_INCLUDES += . diff --git a/platform/arch/xtensa/k_types.h b/platform/arch/xtensa/k_types.h old mode 100644 new mode 100755 index 44fd70ae71..b9fab751c7 --- a/platform/arch/xtensa/k_types.h +++ b/platform/arch/xtensa/k_types.h @@ -5,26 +5,19 @@ #ifndef TYPES_H #define TYPES_H -#define RHINO_NO_WAIT 0u -#define RHINO_WAIT_FOREVER 0xffffffffu /* 32 bit value, if tick type is 64 bit, you need change it to 64 bit */ #define RHINO_TASK_STACK_OVF_MAGIC 0xdeadbeafu /* 32 bit or 64 bit stack overflow magic value */ #define RHINO_INTRPT_STACK_OVF_MAGIC 0xdeaddeadu /* 32 bit or 64 bit stack overflow magic value */ -#define RHINO_MM_FRAG_ALLOCATED 0xabcddcabu /* 32 bit value, if 64 bit system, you need change it to 64 bit */ -#define RHINO_MM_FRAG_FREE 0xfefdecdbu /* 32 bit value, if 64 bit system, you need change it to 64 bit */ +#define RHINO_MM_CORRUPT_DYE 0xFEFEFEFE +#define RHINO_MM_FREE_DYE 0xABABABAB #define RHINO_INLINE static __inline /* inline keyword, it may change under different compilers */ typedef char name_t; typedef uint32_t sem_count_t; typedef uint32_t cpu_stack_t; - typedef uint32_t hr_timer_t; typedef uint32_t lr_timer_t; - -typedef uint32_t tick_t; -typedef uint64_t idle_count_t; typedef uint32_t mutex_nested_t; typedef uint8_t suspend_nested_t; - typedef uint64_t ctx_switch_t; #endif /* TYPES_H */ diff --git a/platform/arch/xtensa/lx6/k_types.h b/platform/arch/xtensa/lx6/k_types.h index 44fd70ae71..d2adde4261 100644 --- a/platform/arch/xtensa/lx6/k_types.h +++ b/platform/arch/xtensa/lx6/k_types.h @@ -6,12 +6,13 @@ #define TYPES_H #define RHINO_NO_WAIT 0u -#define RHINO_WAIT_FOREVER 0xffffffffu /* 32 bit value, if tick type is 64 bit, you need change it to 64 bit */ #define RHINO_TASK_STACK_OVF_MAGIC 0xdeadbeafu /* 32 bit or 64 bit stack overflow magic value */ #define RHINO_INTRPT_STACK_OVF_MAGIC 0xdeaddeadu /* 32 bit or 64 bit stack overflow magic value */ #define RHINO_MM_FRAG_ALLOCATED 0xabcddcabu /* 32 bit value, if 64 bit system, you need change it to 64 bit */ #define RHINO_MM_FRAG_FREE 0xfefdecdbu /* 32 bit value, if 64 bit system, you need change it to 64 bit */ #define RHINO_INLINE static __inline /* inline keyword, it may change under different compilers */ +#define RHINO_MM_FREE_DYE 0xABABABAB +#define RHINO_MM_CORRUPT_DYE 0xFEFEFEFE typedef char name_t; typedef uint32_t sem_count_t; @@ -20,7 +21,6 @@ typedef uint32_t cpu_stack_t; typedef uint32_t hr_timer_t; typedef uint32_t lr_timer_t; -typedef uint32_t tick_t; typedef uint64_t idle_count_t; typedef uint32_t mutex_nested_t; typedef uint8_t suspend_nested_t; diff --git a/platform/mcu/.DS_Store b/platform/mcu/.DS_Store new file mode 100644 index 0000000000..106264c1e4 Binary files /dev/null and b/platform/mcu/.DS_Store differ diff --git a/platform/mcu/csky/csky.mk b/platform/mcu/csky/csky.mk index ff56877a29..938ce9567e 100644 --- a/platform/mcu/csky/csky.mk +++ b/platform/mcu/csky/csky.mk @@ -1,11 +1,3 @@ -# -# UNPUBLISHED PROPRIETARY SOURCE CODE -# Copyright (c) 2016 MXCHIP Inc. -# -# The contents of this file may not be disclosed to third parties, copied or -# duplicated in any form, in whole or in part, without the prior written -# permission of MXCHIP Corporation. -# NAME := csky @@ -80,6 +72,7 @@ $(NAME)_SOURCES += csi_core/csi_core_dummy.c \ csi_driver/csky/hobbit1_2/lib.c \ csi_driver/csky/hobbit1_2/pinmux.c \ csi_kernel/driver/systick.c \ - hal/ringbuffer.c + hal/ringbuffer.c \ + hal/i2c.c #../../arch/csky/cskyv2-l/csky_sched.c \ diff --git a/platform/mcu/csky/hal/i2c.c b/platform/mcu/csky/hal/i2c.c new file mode 100644 index 0000000000..57e46de44f --- /dev/null +++ b/platform/mcu/csky/hal/i2c.c @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#include +#include "hal/soc/soc.h" + +int32_t hal_i2c_init(i2c_dev_t *i2c) +{ + int32_t ret = 0; + + return ret; +} + +int32_t hal_i2c_master_send(i2c_dev_t *i2c, uint16_t dev_addr, const uint8_t *data, + uint16_t size, uint32_t timeout) +{ + int32_t ret = 0; + + return ret; +} + +int32_t hal_i2c_master_recv(i2c_dev_t *i2c, uint16_t dev_addr, uint8_t *data, + uint16_t size, uint32_t timeout) +{ + int32_t ret = 0; + + return ret; +} + +int32_t hal_i2c_slave_send(i2c_dev_t *i2c, const uint8_t *data, uint16_t size, uint32_t timeout) +{ + int32_t ret = 0; + + return ret; +} + +int32_t hal_i2c_slave_recv(i2c_dev_t *i2c, uint8_t *data, uint16_t size, uint32_t timeout) +{ + int32_t ret = 0; + + return ret; +} + +int32_t hal_i2c_mem_write(i2c_dev_t *i2c, uint16_t dev_addr, uint16_t mem_addr, + uint16_t mem_addr_size, const uint8_t *data, uint16_t size, + uint32_t timeout) +{ + int32_t ret = 0; + + return ret; +}; + +int32_t hal_i2c_mem_read(i2c_dev_t *i2c, uint16_t dev_addr, uint16_t mem_addr, + uint16_t mem_addr_size, uint8_t *data, uint16_t size, + uint32_t timeout) +{ + int32_t ret = 0; + + return ret; +}; + +int32_t hal_i2c_finalize(i2c_dev_t *i2c) +{ + int32_t ret = 0; + + return ret; +} diff --git a/platform/mcu/csky/hal_init/hal_init.mk b/platform/mcu/csky/hal_init/hal_init.mk index 5e13a7f445..c47a85eacf 100644 --- a/platform/mcu/csky/hal_init/hal_init.mk +++ b/platform/mcu/csky/hal_init/hal_init.mk @@ -1,11 +1,3 @@ -# -# UNPUBLISHED PROPRIETARY SOURCE CODE -# Copyright (c) 2016 MXCHIP Inc. -# -# The contents of this file may not be disclosed to third parties, copied or -# duplicated in any form, in whole or in part, without the prior written -# permission of MXCHIP Corporation. -# NAME := hal_init diff --git a/platform/mcu/esp32/ble_hci_driver/h4.c b/platform/mcu/esp32/ble_hci_driver/h4.c new file mode 100644 index 0000000000..fb871665fa --- /dev/null +++ b/platform/mcu/esp32/ble_hci_driver/h4.c @@ -0,0 +1,497 @@ +/* + * Copyright (C) 2016 YunOS Project. All rights reserved. + * + * 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include + +#include + +#include +#include +#include + +#ifndef BT_DBG_ENABLED +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HCI_DRIVER) +#endif +#include +#include +#include +#include + + +#if defined(CONFIG_BLUETOOTH_NRF51_PM) +#include "../nrf51_pm.h" +#endif + +#define H4_NONE 0x00 +#define H4_CMD 0x01 +#define H4_ACL 0x02 +#define H4_SCO 0x03 +#define H4_EVT 0x04 + +static BT_STACK_NOINIT(rx_thread_stack, CONFIG_BLUETOOTH_HCI_RX_STACK_SIZE); + +static struct { + struct net_buf *buf; + struct k_fifo fifo; + + uint16_t remaining; + uint16_t discard; + + bool have_hdr; + bool discardable; + + uint8_t hdr_len; + + uint8_t type; + union { + struct bt_hci_evt_hdr evt; + struct bt_hci_acl_hdr acl; + uint8_t hdr[4]; + }; +} rx; +static struct { + uint8_t type; + struct net_buf *buf; + struct k_fifo fifo; +} tx; + +typedef uint32_t uart_port_t; +typedef uint32_t TickType_t; +//extern int uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_buffer_size, int queue_size, int uart_intr_num, void *uart_queue); +extern int uart_driver_install(uart_port_t uart_num, int rx_buffer_size, int tx_buffer_size, int queue_size, void *uart_queue, int intr_alloc_flags); +extern int uart_write_bytes(uart_port_t uart_num, const char *src, size_t size); +extern int uart_read_bytes(uart_port_t uart_num, uint8_t *buf, uint32_t length, TickType_t ticks_to_wait); + +static uart_port_t h4_dev = 1; + +static inline void h4_get_type(void) +{ + /* Get packet type */ + if (uart_read_bytes(h4_dev, &rx.type, 1, -1) != 1) { + BT_WARN("Unable to read H:4 packet type"); + rx.type = H4_NONE; + return; + } + + switch (rx.type) { + case H4_EVT: + rx.remaining = sizeof(rx.evt); + rx.hdr_len = rx.remaining; + break; + + case H4_ACL: + rx.remaining = sizeof(rx.acl); + rx.hdr_len = rx.remaining; + break; + + default: + BT_ERR("Unknown H:4 type 0x%02x", rx.type); + rx.type = H4_NONE; + } +} + +static inline void get_acl_hdr(void) +{ + struct bt_hci_acl_hdr *hdr = &rx.acl; + int to_read = sizeof(*hdr) - rx.remaining; + + rx.remaining -= uart_read_bytes(h4_dev, (uint8_t *)hdr + to_read, + rx.remaining, -1); + + if (!rx.remaining) { + rx.remaining = sys_le16_to_cpu(hdr->len); + BT_DBG("Got ACL header. Payload %u bytes", rx.remaining); + rx.have_hdr = true; + } +} + +static inline void get_evt_hdr(void) +{ + struct bt_hci_evt_hdr *hdr = &rx.evt; + int to_read = rx.hdr_len - rx.remaining; + + rx.remaining -= uart_read_bytes(h4_dev, (uint8_t *)hdr + to_read, + rx.remaining, -1); + + if (rx.hdr_len == sizeof(*hdr) && rx.remaining < sizeof(*hdr)) { + switch (rx.evt.evt) { + case BT_HCI_EVT_LE_META_EVENT: + rx.remaining++; + rx.hdr_len++; + break; +#if defined(CONFIG_BLUETOOTH_BREDR) + + case BT_HCI_EVT_INQUIRY_RESULT_WITH_RSSI: + case BT_HCI_EVT_EXTENDED_INQUIRY_RESULT: + rx.discardable = true; + break; +#endif + } + } + + if (!rx.remaining) { + if (rx.evt.evt == BT_HCI_EVT_LE_META_EVENT && + rx.hdr[sizeof(*hdr)] == BT_HCI_EVT_LE_ADVERTISING_REPORT) { + BT_DBG("Marking adv report as discardable"); + rx.discardable = true; + } + + rx.remaining = hdr->len - (rx.hdr_len - sizeof(*hdr)); + BT_DBG("Got event header. Payload %u bytes", hdr->len); + rx.have_hdr = true; + } +} + + +static inline void copy_hdr(struct net_buf *buf) +{ + net_buf_add_mem(buf, rx.hdr, rx.hdr_len); +} + +static void reset_rx(void) +{ + rx.type = H4_NONE; + rx.remaining = 0; + rx.have_hdr = false; + rx.hdr_len = 0; + rx.discardable = false; +} + +static struct net_buf *get_rx(int timeout) +{ + BT_DBG("type 0x%02x, evt 0x%02x", rx.type, rx.evt.evt); + + if (rx.type == H4_EVT && (rx.evt.evt == BT_HCI_EVT_CMD_COMPLETE || + rx.evt.evt == BT_HCI_EVT_CMD_STATUS)) { + return bt_buf_get_cmd_complete(timeout); + } + + return bt_buf_get_rx(timeout); +} + +static size_t h4_discard(uart_port_t uart, size_t len) +{ + uint8_t buf[33]; + + return uart_read_bytes(uart, buf, min(len, sizeof(buf)), 0); +} + +static inline void read_payload(void) +{ + struct net_buf *buf; + bool prio; + int read; + + if (!rx.buf) { + rx.buf = get_rx(K_NO_WAIT); + + if (!rx.buf) { + if (rx.discardable) { + BT_WARN("Discarding event 0x%02x", rx.evt.evt); + rx.discard = rx.remaining; + reset_rx(); + return; + } + + BT_WARN("Failed to allocate, deferring to rx_thread"); + return; + } + + BT_DBG("Allocated rx.buf %p", rx.buf); + + if (rx.remaining > net_buf_tailroom(rx.buf)) { + BT_ERR("Not enough space in buffer"); + rx.discard = rx.remaining; + reset_rx(); + return; + } + + copy_hdr(rx.buf); + } + + read = uart_read_bytes(h4_dev, net_buf_tail(rx.buf), rx.remaining, -1); + net_buf_add(rx.buf, read); + rx.remaining -= read; + + BT_DBG("got %d bytes, remaining %u", read, rx.remaining); + BT_DBG("Payload (len %u): %s", rx.buf->len, + bt_hex(rx.buf->data, rx.buf->len)); + + if (rx.remaining) { + return; + } + + prio = (rx.type == H4_EVT && bt_hci_evt_is_prio(rx.evt.evt)); + + buf = rx.buf; + rx.buf = NULL; + + if (rx.type == H4_EVT) { + bt_buf_set_type(buf, BT_BUF_EVT); + } else { + bt_buf_set_type(buf, BT_BUF_ACL_IN); + } + + reset_rx(); + + if (prio) { + BT_DBG("Calling bt_recv_prio(%p)", buf); + bt_recv_prio(buf); + } else { + BT_DBG("Putting buf %p to rx fifo", buf); + net_buf_put(&rx.fifo, buf); + } +} + +static inline void read_header(void) +{ + switch (rx.type) { + case H4_NONE: + h4_get_type(); + return; + + case H4_EVT: + get_evt_hdr(); + break; + + case H4_ACL: + get_acl_hdr(); + break; + + default: + return; + } + + if (rx.have_hdr && rx.buf) { + if (rx.remaining > net_buf_tailroom(rx.buf)) { + BT_ERR("Not enough space in buffer"); + rx.discard = rx.remaining; + reset_rx(); + } else { + copy_hdr(rx.buf); + } + } +} + +static inline void process_tx(void) +{ + int bytes; + + if (!tx.buf) { + tx.buf = net_buf_get(&tx.fifo, K_NO_WAIT); + + if (!tx.buf) { + BT_ERR("TX interrupt but no pending buffer!"); + return; + } + } + + if (!tx.type) { + switch (bt_buf_get_type(tx.buf)) { + case BT_BUF_ACL_OUT: + tx.type = H4_ACL; + break; + + case BT_BUF_CMD: + tx.type = H4_CMD; + break; + + default: + BT_ERR("Unknown buffer type"); + goto done; + } + + BT_DBG("write type %d", tx.type); + bytes = uart_write_bytes(h4_dev, (char *)&tx.type, 1); + + if (bytes != 1) { + BT_WARN("Unable to send H:4 type"); + tx.type = H4_NONE; + return; + } + } + + BT_DBG("write data %s", bt_hex(tx.buf->data, tx.buf->len)); + bytes = uart_write_bytes(h4_dev, (char *)(tx.buf->data), tx.buf->len); + net_buf_pull(tx.buf, bytes); + + if (tx.buf->len) { + return; + } + +done: + tx.type = H4_NONE; + net_buf_unref(tx.buf); + tx.buf = net_buf_get(&tx.fifo, K_NO_WAIT); +} + +static inline void process_rx(void) +{ + BT_DBG("remaining %u discard %u have_hdr %u rx.buf %p len %u", + rx.remaining, rx.discard, rx.have_hdr, rx.buf, + rx.buf ? rx.buf->len : 0); + + if (rx.discard) { + rx.discard -= h4_discard(h4_dev, rx.discard); + return; + } + + if (rx.have_hdr) { + read_payload(); + } else { + read_header(); + } +} + +static void rx_thread(void *p1) +{ + struct net_buf *buf; + + ARG_UNUSED(p1); + + BT_DBG("started"); + + while (1) { + BT_DBG("rx.buf %p", rx.buf); + process_rx(); + + /* We can only do the allocation if we know the initial + * header, since Command Complete/Status events must use the + * original command buffer (if available). + */ + if (rx.have_hdr && !rx.buf) { + rx.buf = get_rx(K_FOREVER); + BT_DBG("Got rx.buf %p", rx.buf); + + if (rx.remaining > net_buf_tailroom(rx.buf)) { + BT_ERR("Not enough space in buffer"); + rx.discard = rx.remaining; + reset_rx(); + } else { + copy_hdr(rx.buf); + } + } + + buf = net_buf_get(&rx.fifo, K_NO_WAIT); + + while (buf) { + + BT_DBG("Calling bt_recv(%p)", buf); + bt_recv(buf); + + /* Give other threads a chance to run if the ISR + * is receiving data so fast that rx.fifo never + * or very rarely goes empty. + */ + k_yield(); + + buf = net_buf_get(&rx.fifo, K_NO_WAIT); + }; + + k_yield(); + } +} + +static int h4_send(struct net_buf *buf) +{ + BT_DBG("buf %p type %u len %u", buf, bt_buf_get_type(buf), buf->len); + + net_buf_put(&tx.fifo, buf); + process_tx(); + return 0; +} +typedef enum { + UART_PARITY_DISABLE = 0x0, /*!< Disable UART parity*/ + UART_PARITY_EVEN = 0x2, /*!< Enable UART even parity*/ + UART_PARITY_ODD = 0x3 /*!< Enable UART odd parity*/ +} uart_parity_t; + +typedef enum { + UART_STOP_BITS_1 = 0x1, /*!< stop bit: 1bit*/ + UART_STOP_BITS_1_5 = 0x2, /*!< stop bit: 1.5bits*/ + UART_STOP_BITS_2 = 0x3, /*!< stop bit: 2bits*/ + UART_STOP_BITS_MAX = 0x4, +} uart_stop_bits_t; + +typedef enum { + UART_HW_FLOWCTRL_DISABLE = 0x0, /*!< disable hardware flow control*/ + UART_HW_FLOWCTRL_RTS = 0x1, /*!< enable RX hardware flow control (rts)*/ + UART_HW_FLOWCTRL_CTS = 0x2, /*!< enable TX hardware flow control (cts)*/ + UART_HW_FLOWCTRL_CTS_RTS = 0x3, /*!< enable hardware flow control*/ + UART_HW_FLOWCTRL_MAX = 0x4, +} uart_hw_flowcontrol_t; +typedef enum { + UART_DATA_5_BITS = 0x0, /*!< word length: 5bits*/ + UART_DATA_6_BITS = 0x1, /*!< word length: 6bits*/ + UART_DATA_7_BITS = 0x2, /*!< word length: 7bits*/ + UART_DATA_8_BITS = 0x3, /*!< word length: 8bits*/ + UART_DATA_BITS_MAX = 0X4, +} uart_word_length_t; + +typedef struct { + int baud_rate; /*!< UART baudrate*/ + uart_word_length_t data_bits; /*!< UART byte size*/ + uart_parity_t parity; /*!< UART parity mode*/ + uart_stop_bits_t stop_bits; /*!< UART stop bits*/ + uart_hw_flowcontrol_t flow_ctrl; /*!< UART HW flow control mode(cts/rts)*/ + uint8_t rx_flow_ctrl_thresh ; /*!< UART HW RTS threshold*/ +} uart_config_t; + +extern int32_t uart_param_config(uart_port_t uart_num, const uart_config_t *uart_config); +extern int32_t uart_set_pin(uart_port_t uart_num, int tx_io_num, int rx_io_num, int rts_io_num, int cts_io_num); + +static int h4_open(void) +{ + BT_INFO(""); + uart_config_t uart_config = { + .baud_rate = 115200, + .data_bits = UART_DATA_8_BITS, + .parity = UART_PARITY_DISABLE, + .stop_bits = UART_STOP_BITS_1, + .flow_ctrl = UART_HW_FLOWCTRL_CTS_RTS, + .rx_flow_ctrl_thresh = 122, + }; + uart_param_config(h4_dev, &uart_config); + uart_set_pin(h4_dev, 4, 5, 18, 19); + //uart_driver_install(h4_dev, 1024 * 2, 1024 * 4, 0, 18, NULL); + uart_driver_install(h4_dev, 1024 * 2, 1024 * 2, 0, NULL, 0); + + h4_discard(h4_dev, 32); + + k_thread_spawn("hci rx thread", rx_thread_stack, sizeof(rx_thread_stack), rx_thread, + NULL, 46); + + k_fifo_init(&tx.fifo, "tx fifo", NULL, CONFIG_BLUETOOTH_RX_BUF_COUNT); + k_fifo_init(&rx.fifo, "rx fifo", NULL, CONFIG_BLUETOOTH_RX_BUF_COUNT); + + return 0; +} + +static struct bt_hci_driver drv = { + .name = "H:4", + .bus = BT_HCI_DRIVER_BUS_UART, + .open = h4_open, + .send = h4_send, +}; + +int hci_driver_init() +{ + BT_INFO(""); + bt_hci_driver_register(&drv); + return 0; +} + + diff --git a/platform/mcu/esp32/ble_hci_driver/hci_driver.c b/platform/mcu/esp32/ble_hci_driver/hci_driver.c new file mode 100644 index 0000000000..b16d9067f7 --- /dev/null +++ b/platform/mcu/esp32/ble_hci_driver/hci_driver.c @@ -0,0 +1,263 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#include +#include "errno.h" + +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HCI_DRIVER) + +#include +#include +#include +#include + +#include "bt.h" +#include "nvs_flash.h" + +#define HCI_NONE 0x00 +#define HCI_CMD 0x01 +#define HCI_ACL 0x02 +#define HCI_SCO 0x03 +#define HCI_EVT 0x04 +#define MIN_HCI_LEN 4 +struct hci_cmd_send_t { + struct k_sem send_sem; + uint8_t cmd_buf[BT_BUF_RX_SIZE]; +} g_esp32_hci_send; + +struct hci_cmd_recv_t { + struct net_buf *buf; + uint16_t remaining; + bool discardable; + uint8_t hdr_len; + uint8_t type; + union { + struct bt_hci_evt_hdr evt; + struct bt_hci_acl_hdr acl; + uint8_t hdr[4]; + }; +} g_esp32_hci_recv; + +/* VHCI function interface */ +typedef struct vhci_host_callback { + void (*notify_host_send_available)(void); /*!< callback used to notify that the host can send packet to controller */ + int (*notify_host_recv)(uint8_t *data, uint16_t len); /*!< callback used to notify that the controller has a packet to send to the host*/ +} vhci_host_callback_t; + +static void controller_rcv_pkt_ready(void) +{ + k_sem_give(&g_esp32_hci_send.send_sem); +} + +static inline void copy_hdr(struct net_buf *buf) +{ + net_buf_add_mem(buf, g_esp32_hci_recv.hdr, g_esp32_hci_recv.hdr_len); +} + +static void reset_rx(void) +{ + g_esp32_hci_recv.type = HCI_NONE; + g_esp32_hci_recv.remaining = 0; + g_esp32_hci_recv.hdr_len = 0; + g_esp32_hci_recv.discardable = false; +} + +static int get_hci_evt_hdr(uint8_t *data, uint16_t len) +{ + struct bt_hci_evt_hdr *hdr = &g_esp32_hci_recv.evt; + g_esp32_hci_recv.hdr_len = sizeof(struct bt_hci_evt_hdr); + memcpy((uint8_t *)hdr, data, g_esp32_hci_recv.hdr_len); + + if (hdr->evt == BT_HCI_EVT_LE_META_EVENT) { + memcpy((uint8_t *)hdr + g_esp32_hci_recv.hdr_len, data \ + + g_esp32_hci_recv.hdr_len, 1); + g_esp32_hci_recv.hdr_len++; + } + + if (hdr->evt == BT_HCI_EVT_LE_META_EVENT && + g_esp32_hci_recv.hdr[sizeof(*hdr)] == BT_HCI_EVT_LE_ADVERTISING_REPORT) { + BT_DBG("Marking adv report as discardable"); + g_esp32_hci_recv.discardable = true; + } + + g_esp32_hci_recv.remaining = hdr->len - (g_esp32_hci_recv.hdr_len \ + - sizeof(struct bt_hci_evt_hdr)); + return g_esp32_hci_recv.hdr_len; +} + + +static int get_hci_acl_hdr(uint8_t *data, uint16_t len) +{ + struct bt_hci_acl_hdr *hdr = &g_esp32_hci_recv.acl; + g_esp32_hci_recv.hdr_len = sizeof(struct bt_hci_acl_hdr); + memcpy((uint8_t *)hdr, data, g_esp32_hci_recv.hdr_len); + g_esp32_hci_recv.remaining = sys_le16_to_cpu(hdr->len); + return g_esp32_hci_recv.hdr_len; +} + +static struct net_buf *get_rx(int timeout) +{ + BT_DBG("type 0x%02x, evt 0x%02x", g_esp32_hci_recv.type, g_esp32_hci_recv.evt.evt); + + if (g_esp32_hci_recv.type == HCI_EVT && (g_esp32_hci_recv.evt.evt == BT_HCI_EVT_CMD_COMPLETE || + g_esp32_hci_recv.evt.evt == BT_HCI_EVT_CMD_STATUS)) { + return bt_buf_get_cmd_complete(timeout); + } + + return bt_buf_get_rx(timeout); +} + +static int host_rcv_pkt(uint8_t *data, uint16_t len) +{ + uint8_t *pdata = data; + uint16_t length = len; + bool prio; + struct net_buf *buf; + + BT_DBG("%s", bt_hex(data, len)); + + if (NULL == pdata || length < MIN_HCI_LEN) { + BT_ERR("wrong hci data len,%d\n", len); + return -EINVAL; + } + + g_esp32_hci_recv.type = *pdata++; + length--; + + switch (g_esp32_hci_recv.type) { + case HCI_EVT: + pdata += get_hci_evt_hdr(pdata, length); + break; + + case HCI_ACL: + pdata += get_hci_acl_hdr(pdata, length); + break; + + default: + BT_ERR("Unknown H:4 type 0x%02x", g_esp32_hci_recv.type); + g_esp32_hci_recv.type = HCI_NONE; + return -EINVAL; + } + + if (!g_esp32_hci_recv.buf) { + g_esp32_hci_recv.buf = get_rx(K_NO_WAIT); + + if (!g_esp32_hci_recv.buf) { + if (g_esp32_hci_recv.discardable) { + BT_WARN("Discarding event 0x%02x", g_esp32_hci_recv.evt.evt); + reset_rx(); + return 0; + } + + BT_WARN("Failed to allocate, deferring to rx_thread"); + return -ENOMEM; + } + + copy_hdr(g_esp32_hci_recv.buf); + } + + net_buf_add_mem(g_esp32_hci_recv.buf, pdata, g_esp32_hci_recv.remaining); + + buf = g_esp32_hci_recv.buf; + g_esp32_hci_recv.buf = NULL; + + if (g_esp32_hci_recv.type == HCI_EVT) { + bt_buf_set_type(buf, BT_BUF_EVT); + } else { + bt_buf_set_type(buf, BT_BUF_ACL_IN); + } + + prio = (g_esp32_hci_recv.type == HCI_EVT && bt_hci_evt_is_prio(g_esp32_hci_recv.evt.evt)); + + reset_rx(); + + if (prio) { + BT_DBG("Calling bt_recv_prio(%p)", buf); + bt_recv_prio(buf); + } else { + BT_DBG("Putting buf %p to rx fifo", buf); + bt_recv(buf); + } + + return 0; +} + +static const esp_vhci_host_callback_t vhci_host_cb = { + .notify_host_send_available = controller_rcv_pkt_ready, + .notify_host_recv = host_rcv_pkt, +}; + +static int esp32_hci_driver_send(struct net_buf *buf) +{ + if (NULL == buf) { + return -EINVAL; + } + + switch (bt_buf_get_type(buf)) { + case BT_BUF_ACL_OUT: + g_esp32_hci_send.cmd_buf[0] = HCI_ACL; + break; + + case BT_BUF_CMD: + g_esp32_hci_send.cmd_buf[0] = HCI_CMD; + break; + + default: + BT_ERR("Unknown buffer type"); + return -EINVAL; + } + + memcpy(g_esp32_hci_send.cmd_buf + 1, buf->data, buf->len); + + net_buf_unref(buf); + + BT_DBG("%s", bt_hex(buf->data, buf->len)); + + if (esp_vhci_host_check_send_available()) { + k_sem_take(&g_esp32_hci_send.send_sem, K_FOREVER); + esp_vhci_host_send_packet(g_esp32_hci_send.cmd_buf, buf->len + 1); + } + + return 0; +} + +static int esp32_hci_driver_open(void) +{ + esp_vhci_host_register_callback(&vhci_host_cb); + return 0; +} + +static struct bt_hci_driver drv = { + .name = "esp32 Controller", + .bus = BT_HCI_DRIVER_BUS_VIRTUAL, + .open = esp32_hci_driver_open, + .send = esp32_hci_driver_send, +}; + +int hci_driver_init() +{ + esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); + esp_err_t ret = nvs_flash_init(); + + if (ret == ESP_ERR_NVS_NO_FREE_PAGES) { + ESP_ERROR_CHECK(nvs_flash_erase()); + ret = nvs_flash_init(); + } + ESP_ERROR_CHECK( ret ); + + if (esp_bt_controller_init(&bt_cfg) != ESP_OK) { + printf("Bluetooth controller initialize failed\r\n"); + return -1; + } + + if (esp_bt_controller_enable(ESP_BT_MODE_BTDM) != ESP_OK) { + printf("Bluetooth controller enable failed\r\n"); + return -1; + } + + bt_hci_driver_register(&drv); + k_sem_init(&g_esp32_hci_send.send_sem, 1, 1); + memset(g_esp32_hci_send.cmd_buf, 0, sizeof(g_esp32_hci_send.cmd_buf)); + return 0; +} diff --git a/platform/mcu/esp32/bsp/entry.c b/platform/mcu/esp32/bsp/entry.c index 38b37654a5..8ee4fc3fd8 100644 --- a/platform/mcu/esp32/bsp/entry.c +++ b/platform/mcu/esp32/bsp/entry.c @@ -6,9 +6,6 @@ #include #include #include -#ifdef CONFIG_AOS_MESH -#include -#endif uart_dev_t uart_0 = { .port = CONFIG_CONSOLE_UART_NUM, @@ -34,13 +31,13 @@ int __attribute__((weak)) eventfd(unsigned int initval, int flags) extern void tcpip_adapter_init(void); extern hal_wifi_module_t sim_aos_wifi_eps32; +extern void esp32_wifi_mesh_register(void); static void initialise_wifi(void) { tcpip_adapter_init(); hal_wifi_register_module(&sim_aos_wifi_eps32); #ifdef CONFIG_AOS_MESH - extern umesh_hal_module_t esp32_wifi_mesh_module; - hal_umesh_register_module(&esp32_wifi_mesh_module); + esp32_wifi_mesh_register(); #endif hal_wifi_init(); } @@ -59,4 +56,4 @@ void app_main(void) hal_uart_init(&uart_0); hal_ota_register_module(&esp32_yos_ota_module); aos_task_new("main", app_entry, 0, 8192); -} \ No newline at end of file +} diff --git a/platform/mcu/esp32/esp32.mk b/platform/mcu/esp32/esp32.mk index 73bc48e2f3..209e33dfc0 100644 --- a/platform/mcu/esp32/esp32.mk +++ b/platform/mcu/esp32/esp32.mk @@ -4,7 +4,7 @@ NAME := esp32 $(NAME)_TYPE := kernel -$(NAME)_COMPONENTS := framework.common modules.fs.kv cli +$(NAME)_COMPONENTS := hal modules.fs.kv $(NAME)_COMPONENTS += protocols.net alicrypto ESP_INC_PATH := bsp/include @@ -41,6 +41,7 @@ $(NAME)_SOURCES += hal/flash.c $(NAME)_SOURCES += hal/wifi_port.c $(NAME)_SOURCES += hal/ota_port.c $(NAME)_SOURCES += hal/misc.c +$(NAME)_SOURCES += hal/i2c.c $(NAME)_SOURCES += bsp/tcpip_adapter_lwip.c bsp/wlanif.c bsp/ethernetif.c $(NAME)_CFLAGS := -std=gnu99 @@ -97,12 +98,18 @@ endif ifneq ($(mesh),0) $(NAME)_COMPONENTS += protocols.mesh -$(NAME)_SOURCES += hal/mesh.c endif ble := 0 ifneq ($(ble),0) +$(NAME)_COMPONENTS += protocols.bluetooth GLOBAL_INCLUDES += $(ESP_INC_PATH)/bt/include +$(NAME)_INCLUDES += ../../../kernel/protocols/bluetooth/core/include +ifeq ($(hci_h4),1) +$(NAME)_SOURCES += ble_hci_driver/h4.c +else +$(NAME)_SOURCES += ble_hci_driver/hci_driver.c +endif $(NAME)_PREBUILT_LIBRARY += lib/libbt.a $(NAME)_PREBUILT_LIBRARY += lib/libbtdm_app.a GLOBAL_DEFINES += CONFIG_ESP32_WITH_BLE diff --git a/platform/mcu/esp32/hal/i2c.c b/platform/mcu/esp32/hal/i2c.c new file mode 100644 index 0000000000..57e46de44f --- /dev/null +++ b/platform/mcu/esp32/hal/i2c.c @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#include +#include "hal/soc/soc.h" + +int32_t hal_i2c_init(i2c_dev_t *i2c) +{ + int32_t ret = 0; + + return ret; +} + +int32_t hal_i2c_master_send(i2c_dev_t *i2c, uint16_t dev_addr, const uint8_t *data, + uint16_t size, uint32_t timeout) +{ + int32_t ret = 0; + + return ret; +} + +int32_t hal_i2c_master_recv(i2c_dev_t *i2c, uint16_t dev_addr, uint8_t *data, + uint16_t size, uint32_t timeout) +{ + int32_t ret = 0; + + return ret; +} + +int32_t hal_i2c_slave_send(i2c_dev_t *i2c, const uint8_t *data, uint16_t size, uint32_t timeout) +{ + int32_t ret = 0; + + return ret; +} + +int32_t hal_i2c_slave_recv(i2c_dev_t *i2c, uint8_t *data, uint16_t size, uint32_t timeout) +{ + int32_t ret = 0; + + return ret; +} + +int32_t hal_i2c_mem_write(i2c_dev_t *i2c, uint16_t dev_addr, uint16_t mem_addr, + uint16_t mem_addr_size, const uint8_t *data, uint16_t size, + uint32_t timeout) +{ + int32_t ret = 0; + + return ret; +}; + +int32_t hal_i2c_mem_read(i2c_dev_t *i2c, uint16_t dev_addr, uint16_t mem_addr, + uint16_t mem_addr_size, uint8_t *data, uint16_t size, + uint32_t timeout) +{ + int32_t ret = 0; + + return ret; +}; + +int32_t hal_i2c_finalize(i2c_dev_t *i2c) +{ + int32_t ret = 0; + + return ret; +} diff --git a/platform/mcu/esp32/hal/mesh.c b/platform/mcu/esp32/hal/mesh.c deleted file mode 100644 index 6768b52fd0..0000000000 --- a/platform/mcu/esp32/hal/mesh.c +++ /dev/null @@ -1,384 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#include -#include -#include - -#include - -#include "hal/wifi.h" -#include "umesh_hal.h" -#include "umesh_80211.h" - -#include "esp_wifi.h" -#include "esp_wifi_types.h" -#include "esp_wifi_internal.h" -#include "esp_event_loop.h" - -enum { - WIFI_MESH_OFFSET = 32, - WIFI_DST_OFFSET = 4, - WIFI_SRC_OFFSET = 10, - WIFI_BSSID_OFFSET = 16, - WIFI_MAC_ADDR_SIZE = 6, - WIFI_FCS_SIZE = 4, - - DEFAULT_MTU_SIZE = 512, -}; - -typedef struct { - uint32_t u_mtu; - uint32_t b_mtu; - uint8_t channel; - uint8_t chn_num; - const uint8_t *channels; - umesh_handle_received_frame_t rxcb; - - void *context; - umesh_hal_module_t *module; - mesh_key_t keys[2]; - unsigned char bssid[WIFI_MAC_ADDR_SIZE]; - unsigned char macaddr[WIFI_MAC_ADDR_SIZE]; - - frame_stats_t stats; -} mesh_hal_priv_t; - -umesh_hal_module_t esp32_wifi_mesh_module; -static mesh_hal_priv_t *g_hal_priv; - -typedef struct send_ext_s { - void *context; - void *sent; - frame_t *frame; -} send_cxt_t; - -static send_cxt_t g_send_ucast_cxt; -static send_cxt_t g_send_bcast_cxt; - -typedef struct { - frame_t frm; - frame_info_t fino; - mesh_hal_priv_t *priv; -} compound_msg_t; - -/* WiFi HAL */ -static int esp32_wifi_mesh_init(umesh_hal_module_t *module, void *config) -{ - mesh_hal_priv_t *priv = module->base.priv_dev; - wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); - esp_err_t esp_err; - bool enable; - - g_hal_priv = priv; - esp_err = esp_wifi_get_promiscuous(&enable); - if (esp_err != ESP_OK) { - ESP_ERROR_CHECK( esp_wifi_init(&cfg) ); - } - ESP_ERROR_CHECK(esp_wifi_get_mac(WIFI_IF_STA, priv->macaddr)); - return 0; -} - -static void pass_to_umesh(void* arg) -{ - compound_msg_t *cmsg = (compound_msg_t *)arg; - frame_t *frm = &cmsg->frm; - frame_info_t *fino = &cmsg->fino; - mesh_hal_priv_t *priv = cmsg->priv; - - if (priv->rxcb) { - priv->rxcb(priv->context, frm, fino, 0); - } - - aos_free(cmsg); -} - -bool esp32_is_mesh_pkt(void *buf, wifi_promiscuous_pkt_type_t type) -{ - wifi_promiscuous_pkt_t *pkt = (wifi_promiscuous_pkt_t *)buf; - mesh_hal_priv_t *priv = g_hal_priv; - umesh_hal_module_t *module = priv->module; - - if (type != WIFI_PKT_DATA) - return false; - - if (pkt->rx_ctrl.sig_len < 40) { - return false; - } - - if (umesh_80211_filter_frame(module, pkt->payload, pkt->rx_ctrl.sig_len)) { - return false; - } - return true; -} - -void mesh_promiscuous_rx_cb(void *buf, wifi_promiscuous_pkt_type_t type) -{ - compound_msg_t *pf; - wifi_promiscuous_pkt_t *pkt = (wifi_promiscuous_pkt_t *)buf; - mesh_hal_priv_t *priv = g_hal_priv; - umesh_hal_module_t *module = priv->module; - - if (type != WIFI_PKT_DATA) - return; - - if (umesh_80211_filter_frame(module, pkt->payload, pkt->rx_ctrl.sig_len)) { - return; - } - - pf = aos_malloc(sizeof(*pf) + pkt->rx_ctrl.sig_len - WIFI_MESH_OFFSET - WIFI_FCS_SIZE); - bzero(pf, sizeof(*pf)); - pf->frm.len = pkt->rx_ctrl.sig_len - WIFI_MESH_OFFSET - WIFI_FCS_SIZE; - pf->frm.data = (void *)(pf + 1); - memcpy(pf->fino.peer.addr, pkt->payload + WIFI_SRC_OFFSET, WIFI_MAC_ADDR_SIZE); - pf->fino.peer.len = 8; - - module = hal_umesh_get_default_module(); - pf->fino.channel = hal_umesh_get_channel(module); - pf->fino.rssi = pkt->rx_ctrl.rssi; - - pf->priv = priv; - memcpy(pf->frm.data, pkt->payload + WIFI_MESH_OFFSET, pf->frm.len); - - priv->stats.in_frames++; - aos_schedule_call(pass_to_umesh, pf); -} - -static int esp32_wifi_mesh_enable(umesh_hal_module_t *module) -{ - bool enable; - esp_err_t esp_err; - uint8_t mac[6]; - - esp_err = esp_wifi_get_promiscuous(&enable); - if (enable == false) { - ESP_ERROR_CHECK(esp_wifi_get_mac(WIFI_IF_STA, mac)); - ESP_ERROR_CHECK(esp_wifi_set_promiscous_autoack(true, mac)); - ESP_ERROR_CHECK(esp_wifi_set_promiscuous(1)); - ESP_ERROR_CHECK(esp_wifi_set_promiscuous_rx_cb(mesh_promiscuous_rx_cb)); - } - return 0; -} - -static int esp32_wifi_mesh_disable(umesh_hal_module_t *module) -{ - return 0; -} - - -static int send_frame(umesh_hal_module_t *module, frame_t *frame, - mac_address_t *dest, send_cxt_t *cxt) -{ - mesh_hal_priv_t *priv = module->base.priv_dev; - uint8_t *pkt; - int len = frame->len + WIFI_MESH_OFFSET; - umesh_handle_sent_ucast_t sent; - int result = 0; - esp_err_t esp_err; - - pkt = aos_malloc(len); - if (pkt == NULL) { - result = 1; - goto tx_exit; - } - umesh_80211_make_frame(module, frame, dest, pkt); - - extern esp_err_t esp_wifi_80211_tx(wifi_interface_t ifx, const void *buffer, int len); - esp_err = esp_wifi_80211_tx(ESP_IF_WIFI_STA, pkt, len); - - if (esp_err != ESP_OK) { - result = 1; - } else { - priv->stats.out_frames++; - } - aos_free(pkt); - -tx_exit: - if (cxt) { - sent = cxt->sent; - (*sent)(cxt->context, cxt->frame, result); - } - - return 0; -} - -static int esp32_wifi_mesh_send_ucast(umesh_hal_module_t *module, - frame_t *frame, mac_address_t *dest, - umesh_handle_sent_ucast_t sent, - void *context) -{ - int error; - mesh_hal_priv_t *priv = module->base.priv_dev; - - if(frame == NULL) { - return -1; - } - - if(frame->len > priv->u_mtu) { - return -2; - } - - g_send_ucast_cxt.context = context; - g_send_ucast_cxt.sent = sent; - g_send_ucast_cxt.frame = frame; - error = send_frame(module, frame, dest, &g_send_ucast_cxt); - return error; -} - -static int esp32_wifi_mesh_send_bcast(umesh_hal_module_t *module, - frame_t *frame, - umesh_handle_sent_bcast_t sent, - void *context) -{ - int error; - mesh_hal_priv_t *priv = module->base.priv_dev; - mac_address_t dest; - - if(frame == NULL) { - return -1; - } - - if(frame->len > priv->b_mtu) { - return -2; - } - - g_send_bcast_cxt.context = context; - g_send_bcast_cxt.sent = sent; - g_send_bcast_cxt.frame = frame; - - dest.len = 8; - memset(dest.addr, 0xff, sizeof(dest.addr)); - error = send_frame(module, frame, &dest, &g_send_bcast_cxt); - return error; -} - -static int esp32_wifi_mesh_register_receiver(umesh_hal_module_t *module, - umesh_handle_received_frame_t received, - void *context) -{ - mesh_hal_priv_t *priv = module->base.priv_dev; - - if(received == NULL) { - return -1; - } - - priv->rxcb = received; - priv->context = context; - return 0; -} - -static int esp32_wifi_mesh_get_mtu(umesh_hal_module_t *module) -{ - return DEFAULT_MTU_SIZE; -} - -static const mac_address_t *esp32_wifi_mesh_get_mac_address(umesh_hal_module_t *module) -{ - static mac_address_t addr; - mesh_hal_priv_t *priv = module->base.priv_dev; - - ESP_ERROR_CHECK(esp_wifi_get_mac(WIFI_IF_STA, priv->macaddr)); - memcpy(addr.addr, priv->macaddr, WIFI_MAC_ADDR_SIZE); - addr.len = 8; - return &addr; -} - -static int esp32_wifi_mesh_get_channel(umesh_hal_module_t *module) -{ - uint8_t primary; - wifi_second_chan_t second; - - esp_wifi_get_channel(&primary, &second); - return (int)primary; -} - -static int esp32_wifi_mesh_set_channel(umesh_hal_module_t *module, - uint8_t channel) -{ - if (channel < 1 || channel > 13) { - return -1; - } - - ESP_ERROR_CHECK(esp_wifi_set_channel(channel, 0)); - return 0; -} - -static int esp32_wifi_mesh_get_channel_list(umesh_hal_module_t *module, - const uint8_t **chnlist) -{ - mesh_hal_priv_t *priv = module->base.priv_dev; - if (chnlist == NULL) { - return -1; - } - - *chnlist = priv->channels; - return priv->chn_num; -} - -static int esp32_wifi_mesh_set_extnetid(umesh_hal_module_t *module, - const umesh_extnetid_t *extnetid) -{ - mesh_hal_priv_t *priv = module->base.priv_dev; - - if (extnetid == NULL) { - return -1; - } - memcpy(priv->bssid, extnetid->netid, WIFI_MAC_ADDR_SIZE); - return 0; -} - -void esp32_wifi_mesh_get_extnetid(umesh_hal_module_t *module, - umesh_extnetid_t *extnetid) -{ - mesh_hal_priv_t *priv = module->base.priv_dev; - - if (extnetid == NULL) { - return; - } - extnetid->len = WIFI_MAC_ADDR_SIZE; - memcpy(extnetid->netid, priv->bssid, extnetid->len); -} - -static const frame_stats_t *esp32_wifi_mesh_get_stats(umesh_hal_module_t *module) -{ - mesh_hal_priv_t *priv = module->base.priv_dev; - return &priv->stats; -} - -static const uint8_t g_wifi_channels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}; -static mesh_hal_priv_t g_wifi_priv = { - .u_mtu = DEFAULT_MTU_SIZE, - .b_mtu = DEFAULT_MTU_SIZE, - .channel = 0, - .chn_num = sizeof(g_wifi_channels), - .channels = g_wifi_channels, - .module = &esp32_wifi_mesh_module, - .bssid = {0xb0, 0xf8, 0x93, 0x00, 0x00, 0x07}, -}; - -umesh_hal_module_t esp32_wifi_mesh_module = { - .base.name = "esp32_mesh_wifi_module", - .base.priv_dev = &g_wifi_priv, - .type = MEDIA_TYPE_WIFI, - .umesh_hal_init = esp32_wifi_mesh_init, - .umesh_hal_enable = esp32_wifi_mesh_enable, - .umesh_hal_disable = esp32_wifi_mesh_disable, - .umesh_hal_send_ucast_request = esp32_wifi_mesh_send_ucast, - .umesh_hal_send_bcast_request = esp32_wifi_mesh_send_bcast, - .umesh_hal_register_receiver = esp32_wifi_mesh_register_receiver, - .umesh_hal_get_bcast_mtu = esp32_wifi_mesh_get_mtu, - .umesh_hal_get_ucast_mtu = esp32_wifi_mesh_get_mtu, - .umesh_hal_get_mac_address = esp32_wifi_mesh_get_mac_address, - .umesh_hal_get_channel = esp32_wifi_mesh_get_channel, - .umesh_hal_set_channel = esp32_wifi_mesh_set_channel, - .umesh_hal_set_extnetid = esp32_wifi_mesh_set_extnetid, - .umesh_hal_get_extnetid = esp32_wifi_mesh_get_extnetid, - .umesh_hal_get_stats = esp32_wifi_mesh_get_stats, - .umesh_hal_get_chnlist = esp32_wifi_mesh_get_channel_list, -}; - -void esp32_wifi_mesh_register(void) -{ - hal_umesh_register_module(&esp32_wifi_mesh_module); -} diff --git a/platform/mcu/esp32/hal/wifi_port.c b/platform/mcu/esp32/hal/wifi_port.c index 0a1de147d9..32234e142a 100644 --- a/platform/mcu/esp32/hal/wifi_port.c +++ b/platform/mcu/esp32/hal/wifi_port.c @@ -99,34 +99,29 @@ static void scan_done(hal_wifi_module_t *m, scan_type_t t) static monitor_data_cb_t data_cb = NULL; static monitor_data_cb_t mngt_data_cb = NULL; +static monitor_data_cb_t mesh_data_cb = NULL; /** @brief Data RX Callback when in promiscuous mode */ -#ifdef CONFIG_AOS_MESH -extern bool esp32_is_mesh_pkt(void *buf, wifi_promiscuous_pkt_type_t type); -extern void mesh_promiscuous_rx_cb(void *buf, wifi_promiscuous_pkt_type_t type); -#endif static void promiscuous_rx_cb(void *buf, wifi_promiscuous_pkt_type_t type) { hal_wifi_module_t *m = hal_wifi_get_default_module(); wifi_promiscuous_pkt_t *pkt = (wifi_promiscuous_pkt_t *)buf; + hal_wifi_link_info_t info; if (type != WIFI_PKT_DATA && type != WIFI_PKT_MGMT) return; -#ifdef CONFIG_AOS_MESH - if (esp32_is_mesh_pkt(buf, type)) { - mesh_promiscuous_rx_cb(buf, type); - return; - } -#endif + info.rssi = pkt->rx_ctrl.rssi; + if (mesh_data_cb) + mesh_data_cb(pkt->payload, pkt->rx_ctrl.sig_len, &info); if (data_cb) - data_cb(pkt->payload, pkt->rx_ctrl.sig_len - 4, NULL); // exclude wifi fcs + data_cb(pkt->payload, pkt->rx_ctrl.sig_len - 4, &info); // exclude wifi fcs if (type == WIFI_PKT_MGMT && mngt_data_cb) - mngt_data_cb(pkt->payload, pkt->rx_ctrl.sig_len, NULL); + mngt_data_cb(pkt->payload, pkt->rx_ctrl.sig_len, &info); } static void esp_reconnect_wifi_helper(void *arg) @@ -267,7 +262,6 @@ typedef enum { static int wifi_getset_ops(hal_wifi_module_t *m, hal_wifi_getset_cmd_t cmd, ...) { - printf("%s cmd: %d\r\n", __func__, cmd); switch (cmd) { case HAL_WIFI_GET_CHANNEL: { uint8_t channel; @@ -342,6 +336,11 @@ static int wifi_getset_ops(hal_wifi_module_t *m, hal_wifi_getset_cmd_t cmd, ...) static int wifi_init(hal_wifi_module_t *m) { + static int inited; + if (inited) + return 0; + inited = 1; + /* Hook Event */ int ret = esp_event_loop_init(handle_event_cb, NULL); printf("%s:%d %d\n", __func__, __LINE__, ret); @@ -455,6 +454,11 @@ static int set_channel(hal_wifi_module_t *m, int ch) return 0; } +static int get_channel(hal_wifi_module_t *m) +{ + return wifi_getset_ops(m, HAL_WIFI_GET_CHANNEL); +} + static void start_monitor(hal_wifi_module_t *m) { wifi_getset_ops(m, HAL_WIFI_PROMISCUOUS_START); @@ -470,6 +474,11 @@ static void register_monitor_cb(hal_wifi_module_t *m, monitor_data_cb_t fn) data_cb = fn; } +static void register_mesh_cb(hal_wifi_module_t *m, monitor_data_cb_t fn) +{ + mesh_data_cb = fn; +} + static void register_wlan_mgnt_monitor_cb(hal_wifi_module_t *m, monitor_data_cb_t fn) { @@ -488,6 +497,27 @@ static int wlan_send_80211_raw_frame(hal_wifi_module_t *m, return 0; } +static int mesh_enable(hal_wifi_module_t *module) +{ + bool enable; + esp_err_t esp_err; + uint8_t mac[6]; + + esp_err = esp_wifi_get_promiscuous(&enable); + if (enable == false) { + ESP_ERROR_CHECK(esp_wifi_get_mac(WIFI_IF_STA, mac)); + ESP_ERROR_CHECK(esp_wifi_set_promiscous_autoack(true, mac)); + ESP_ERROR_CHECK(esp_wifi_set_promiscuous(1)); + ESP_ERROR_CHECK(esp_wifi_set_promiscuous_rx_cb(promiscuous_rx_cb)); + } + return 0; +} + +static int mesh_disable(hal_wifi_module_t *module) +{ + return 0; +} + hal_wifi_module_t sim_aos_wifi_eps32 = { .base.name = "sim_aos_wifi_esp32", .init = wifi_init, @@ -504,9 +534,20 @@ hal_wifi_module_t sim_aos_wifi_eps32 = { .suspend_station = suspend_station, .suspend_soft_ap = suspend_soft_ap, .set_channel = set_channel, + .get_channel = get_channel, .start_monitor = start_monitor, .stop_monitor = stop_monitor, .register_monitor_cb = register_monitor_cb, .register_wlan_mgnt_monitor_cb = register_wlan_mgnt_monitor_cb, .wlan_send_80211_raw_frame = wlan_send_80211_raw_frame, + + /* mesh related */ + .mesh_register_cb = register_mesh_cb, + .mesh_enable = mesh_enable, + .mesh_disable = mesh_disable, }; + +void esp32_wifi_mesh_register(void) +{ + hal_umesh_register_wifi(&sim_aos_wifi_eps32); +} diff --git a/platform/mcu/linux/main/hw.c b/platform/mcu/linux/main/hw.c index 071b8ff8ea..7e7e78150a 100644 --- a/platform/mcu/linux/main/hw.c +++ b/platform/mcu/linux/main/hw.c @@ -161,32 +161,28 @@ void hal_reboot(void) static void _timer_cb(void *timer, void *arg) { - hal_timer_t *tmr = arg; - tmr->cb(tmr->arg); + timer_dev_t *tmr = arg; + tmr->config.cb(tmr->config.arg); } -void hal_timer_init(hal_timer_t *tmr, unsigned int period, unsigned char auto_reload, unsigned char ch, hal_timer_cb_t cb, void *arg) +int32_t hal_timer_init(timer_dev_t *tim) { - (void)ch; - memset(tmr, 0, sizeof(*tmr)); - tmr->cb = cb; - tmr->arg = arg; - if (auto_reload > 0u) { - krhino_timer_dyn_create((ktimer_t **)&tmr->priv, "hwtmr", _timer_cb, - us2tick(period), us2tick(period), tmr, 0); + if (tim->config.reload_mode == TIMER_RELOAD_AUTO) { + krhino_timer_dyn_create((ktimer_t **)&tim->priv, "hwtmr", _timer_cb, + us2tick(tim->config.period), us2tick(tim->config.period), tim, 0); } else { - krhino_timer_dyn_create((ktimer_t **)&tmr->priv, "hwtmr", _timer_cb, - us2tick(period), 0, tmr, 0); + krhino_timer_dyn_create((ktimer_t **)&tim->priv, "hwtmr", _timer_cb, + us2tick(tim->config.period), 0, tim, 0); } } -int hal_timer_start(hal_timer_t *tmr) +int hal_timer_start(timer_dev_t *tmr) { return krhino_timer_start(tmr->priv); } -void hal_timer_stop(hal_timer_t *tmr) +void hal_timer_stop(timer_dev_t *tmr) { krhino_timer_stop(tmr->priv); krhino_timer_dyn_del(tmr->priv); @@ -228,7 +224,11 @@ int csp_printf(const char *fmt, ...) } #endif +#if defined(DEV_SAL_MK3060) +extern hal_wifi_module_t aos_wifi_module_mk3060; +#else extern hal_wifi_module_t sim_aos_wifi_linux; +#endif extern struct hal_ota_module_s linuxhost_ota_module; uart_dev_t uart_0; @@ -250,7 +250,11 @@ void hw_start_hal(options_t *poptions) #endif #ifdef AOS_HAL +#if defined(DEV_SAL_MK3060) + hal_wifi_register_module(&aos_wifi_module_mk3060); +#else hal_wifi_register_module(&sim_aos_wifi_linux); +#endif hal_ota_register_module(&linuxhost_ota_module); #endif diff --git a/platform/mcu/lpc54102/.DS_Store b/platform/mcu/lpc54102/.DS_Store new file mode 100644 index 0000000000..cd5a48219e Binary files /dev/null and b/platform/mcu/lpc54102/.DS_Store differ diff --git a/platform/mcu/lpc54102/CMSIS/CMSIS_END_USER_LICENCE_AGREEMENT.pdf b/platform/mcu/lpc54102/CMSIS/CMSIS_END_USER_LICENCE_AGREEMENT.pdf new file mode 100644 index 0000000000..c67c8672db Binary files /dev/null and b/platform/mcu/lpc54102/CMSIS/CMSIS_END_USER_LICENCE_AGREEMENT.pdf differ diff --git a/platform/mcu/lpc54102/CMSIS/CMSIS_END_USER_LICENCE_AGREEMENT.rtf b/platform/mcu/lpc54102/CMSIS/CMSIS_END_USER_LICENCE_AGREEMENT.rtf new file mode 100644 index 0000000000..e18d125ccf --- /dev/null +++ b/platform/mcu/lpc54102/CMSIS/CMSIS_END_USER_LICENCE_AGREEMENT.rtf @@ -0,0 +1,911 @@ +{\rtf1\adeflang1025\ansi\ansicpg1252\uc1\adeff0\deff0\stshfdbch37\stshfloch37\stshfhich37\stshfbi0\deflang2057\deflangfe2057\themelang2057\themelangfe0\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f1\fbidi \fswiss\fcharset0\fprq2{\*\panose 020b0604020202020204}Arial;} +{\f2\fbidi \fmodern\fcharset0\fprq1{\*\panose 02070309020205020404}Courier New;}{\f3\fbidi \froman\fcharset2\fprq2{\*\panose 05050102010706020507}Symbol;}{\f10\fbidi \fnil\fcharset2\fprq2{\*\panose 05000000000000000000}Wingdings;} +{\f14\fbidi \froman\fcharset136\fprq2{\*\panose 02020500000000000000}PMingLiU{\*\falt \'b7\'73\'b2\'d3\'a9\'fa\'c5\'e9};}{\f34\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria Math;} +{\f37\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}{\f38\fbidi \fswiss\fcharset0\fprq2{\*\panose 020b0604030504040204}Tahoma;}{\f39\fbidi \fmodern\fcharset0\fprq1{\*\panose 020b0609020204030204}Consolas;} +{\f40\fbidi \froman\fcharset136\fprq2{\*\panose 02020500000000000000}@PMingLiU;}{\flomajor\f31500\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} +{\fdbmajor\f31501\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhimajor\f31502\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria;} +{\fbimajor\f31503\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\flominor\f31504\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;} +{\fdbminor\f31505\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\fhiminor\f31506\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;} +{\fbiminor\f31507\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f41\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\f42\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} +{\f44\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\f45\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\f46\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f47\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} +{\f48\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\f49\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f51\fbidi \fswiss\fcharset238\fprq2 Arial CE;}{\f52\fbidi \fswiss\fcharset204\fprq2 Arial Cyr;} +{\f54\fbidi \fswiss\fcharset161\fprq2 Arial Greek;}{\f55\fbidi \fswiss\fcharset162\fprq2 Arial Tur;}{\f56\fbidi \fswiss\fcharset177\fprq2 Arial (Hebrew);}{\f57\fbidi \fswiss\fcharset178\fprq2 Arial (Arabic);} +{\f58\fbidi \fswiss\fcharset186\fprq2 Arial Baltic;}{\f59\fbidi \fswiss\fcharset163\fprq2 Arial (Vietnamese);}{\f61\fbidi \fmodern\fcharset238\fprq1 Courier New CE;}{\f62\fbidi \fmodern\fcharset204\fprq1 Courier New Cyr;} +{\f64\fbidi \fmodern\fcharset161\fprq1 Courier New Greek;}{\f65\fbidi \fmodern\fcharset162\fprq1 Courier New Tur;}{\f66\fbidi \fmodern\fcharset177\fprq1 Courier New (Hebrew);}{\f67\fbidi \fmodern\fcharset178\fprq1 Courier New (Arabic);} +{\f68\fbidi \fmodern\fcharset186\fprq1 Courier New Baltic;}{\f69\fbidi \fmodern\fcharset163\fprq1 Courier New (Vietnamese);}{\f183\fbidi \froman\fcharset0\fprq2 PMingLiU Western{\*\falt \'b7\'73\'b2\'d3\'a9\'fa\'c5\'e9};} +{\f381\fbidi \froman\fcharset238\fprq2 Cambria Math CE;}{\f382\fbidi \froman\fcharset204\fprq2 Cambria Math Cyr;}{\f384\fbidi \froman\fcharset161\fprq2 Cambria Math Greek;}{\f385\fbidi \froman\fcharset162\fprq2 Cambria Math Tur;} +{\f388\fbidi \froman\fcharset186\fprq2 Cambria Math Baltic;}{\f389\fbidi \froman\fcharset163\fprq2 Cambria Math (Vietnamese);}{\f411\fbidi \fswiss\fcharset238\fprq2 Calibri CE;}{\f412\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;} +{\f414\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\f415\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;}{\f418\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;}{\f419\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);} +{\f421\fbidi \fswiss\fcharset238\fprq2 Tahoma CE;}{\f422\fbidi \fswiss\fcharset204\fprq2 Tahoma Cyr;}{\f424\fbidi \fswiss\fcharset161\fprq2 Tahoma Greek;}{\f425\fbidi \fswiss\fcharset162\fprq2 Tahoma Tur;} +{\f426\fbidi \fswiss\fcharset177\fprq2 Tahoma (Hebrew);}{\f427\fbidi \fswiss\fcharset178\fprq2 Tahoma (Arabic);}{\f428\fbidi \fswiss\fcharset186\fprq2 Tahoma Baltic;}{\f429\fbidi \fswiss\fcharset163\fprq2 Tahoma (Vietnamese);} +{\f430\fbidi \fswiss\fcharset222\fprq2 Tahoma (Thai);}{\f431\fbidi \fmodern\fcharset238\fprq1 Consolas CE;}{\f432\fbidi \fmodern\fcharset204\fprq1 Consolas Cyr;}{\f434\fbidi \fmodern\fcharset161\fprq1 Consolas Greek;} +{\f435\fbidi \fmodern\fcharset162\fprq1 Consolas Tur;}{\f438\fbidi \fmodern\fcharset186\fprq1 Consolas Baltic;}{\f439\fbidi \fmodern\fcharset163\fprq1 Consolas (Vietnamese);}{\f443\fbidi \froman\fcharset0\fprq2 @PMingLiU Western;} +{\flomajor\f31508\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flomajor\f31509\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\flomajor\f31511\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} +{\flomajor\f31512\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flomajor\f31513\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flomajor\f31514\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} +{\flomajor\f31515\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flomajor\f31516\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbmajor\f31518\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} +{\fdbmajor\f31519\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbmajor\f31521\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fdbmajor\f31522\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} +{\fdbmajor\f31523\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbmajor\f31524\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fdbmajor\f31525\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} +{\fdbmajor\f31526\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhimajor\f31528\fbidi \froman\fcharset238\fprq2 Cambria CE;}{\fhimajor\f31529\fbidi \froman\fcharset204\fprq2 Cambria Cyr;} +{\fhimajor\f31531\fbidi \froman\fcharset161\fprq2 Cambria Greek;}{\fhimajor\f31532\fbidi \froman\fcharset162\fprq2 Cambria Tur;}{\fhimajor\f31535\fbidi \froman\fcharset186\fprq2 Cambria Baltic;} +{\fhimajor\f31536\fbidi \froman\fcharset163\fprq2 Cambria (Vietnamese);}{\fbimajor\f31538\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbimajor\f31539\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} +{\fbimajor\f31541\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbimajor\f31542\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbimajor\f31543\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} +{\fbimajor\f31544\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbimajor\f31545\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbimajor\f31546\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);} +{\flominor\f31548\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\flominor\f31549\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\flominor\f31551\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;} +{\flominor\f31552\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\flominor\f31553\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\flominor\f31554\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);} +{\flominor\f31555\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\flominor\f31556\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fdbminor\f31558\fbidi \froman\fcharset238\fprq2 Times New Roman CE;} +{\fdbminor\f31559\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;}{\fdbminor\f31561\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fdbminor\f31562\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;} +{\fdbminor\f31563\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\fdbminor\f31564\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fdbminor\f31565\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;} +{\fdbminor\f31566\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\fhiminor\f31568\fbidi \fswiss\fcharset238\fprq2 Calibri CE;}{\fhiminor\f31569\fbidi \fswiss\fcharset204\fprq2 Calibri Cyr;} +{\fhiminor\f31571\fbidi \fswiss\fcharset161\fprq2 Calibri Greek;}{\fhiminor\f31572\fbidi \fswiss\fcharset162\fprq2 Calibri Tur;}{\fhiminor\f31575\fbidi \fswiss\fcharset186\fprq2 Calibri Baltic;} +{\fhiminor\f31576\fbidi \fswiss\fcharset163\fprq2 Calibri (Vietnamese);}{\fbiminor\f31578\fbidi \froman\fcharset238\fprq2 Times New Roman CE;}{\fbiminor\f31579\fbidi \froman\fcharset204\fprq2 Times New Roman Cyr;} +{\fbiminor\f31581\fbidi \froman\fcharset161\fprq2 Times New Roman Greek;}{\fbiminor\f31582\fbidi \froman\fcharset162\fprq2 Times New Roman Tur;}{\fbiminor\f31583\fbidi \froman\fcharset177\fprq2 Times New Roman (Hebrew);} +{\fbiminor\f31584\fbidi \froman\fcharset178\fprq2 Times New Roman (Arabic);}{\fbiminor\f31585\fbidi \froman\fcharset186\fprq2 Times New Roman Baltic;}{\fbiminor\f31586\fbidi \froman\fcharset163\fprq2 Times New Roman (Vietnamese);}} +{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0; +\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;\red34\green34\blue34;}{\*\defchp \loch\af37\hich\af37\dbch\af37 }{\*\defpap +\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 }\noqfpromote {\stylesheet{\ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025 +\ltrch\fcs0 \fs22\lang2057\langfe1033\loch\f37\hich\af37\dbch\af37\cgrid\langnp2057\langfenp1033 \snext0 \sqformat \spriority0 Normal;}{\*\cs10 \additive \ssemihidden \sunhideused \spriority1 Default Paragraph Font;}{\* +\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\tblind0\tblindtype3\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv +\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 \fs20\lang2057\langfe2057\loch\f37\hich\af37\dbch\af37\cgrid\langnp2057\langfenp2057 +\snext11 \ssemihidden \sunhideused \sqformat Normal Table;}{\s15\ql \li0\ri0\widctlpar +\tx916\tx1832\tx2748\tx3664\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af2\afs20\alang1025 \ltrch\fcs0 +\f2\fs20\lang2057\langfe2057\cgrid\langnp2057\langfenp2057 \sbasedon0 \snext15 \slink16 \ssemihidden \sunhideused HTML Preformatted;}{\*\cs16 \additive \f2\fs20\lang0\langfe2057\langfenp2057 \slink15 \slocked \ssemihidden HTML Preformatted Char;}{\*\cs17 +\additive \ul\cf2 \sunhideused Hyperlink;}{\*\cs18 \additive \fs16 \ssemihidden \sunhideused annotation reference;}{\s19\ql \li0\ri0\sa200\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs20\alang1025 +\ltrch\fcs0 \fs20\lang2057\langfe1033\loch\f37\hich\af37\dbch\af37\cgrid\langnp2057\langfenp1033 \sbasedon0 \snext19 \slink20 \ssemihidden \sunhideused annotation text;}{\*\cs20 \additive \fs20 \slink19 \slocked \ssemihidden Comment Text Char;}{ +\s21\ql \li0\ri0\sa200\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \ab\af0\afs20\alang1025 \ltrch\fcs0 \b\fs20\lang2057\langfe1033\loch\f37\hich\af37\dbch\af37\cgrid\langnp2057\langfenp1033 +\sbasedon19 \snext19 \slink22 \ssemihidden \sunhideused annotation subject;}{\*\cs22 \additive \b\fs20 \slink21 \slocked \ssemihidden Comment Subject Char;}{\s23\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 +\rtlch\fcs1 \af38\afs16\alang1025 \ltrch\fcs0 \fs16\lang2057\langfe1033\loch\f38\hich\af38\dbch\af37\cgrid\langnp2057\langfenp1033 \sbasedon0 \snext23 \slink24 \ssemihidden \sunhideused Balloon Text;}{\*\cs24 \additive \f38\fs16 +\slink23 \slocked \ssemihidden Balloon Text Char;}{\s25\ql \li0\ri0\sa200\sl276\slmult1\widctlpar\tqc\tx4680\tqr\tx9360\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 +\fs22\lang2057\langfe1033\loch\f37\hich\af37\dbch\af37\cgrid\langnp2057\langfenp1033 \sbasedon0 \snext25 \slink26 \sunhideused header;}{\*\cs26 \additive \fs22\lang2057\langfe0\langnp2057 \slink25 \slocked Header Char;}{ +\s27\ql \li0\ri0\sa200\sl276\slmult1\widctlpar\tqc\tx4680\tqr\tx9360\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 +\fs22\lang2057\langfe1033\loch\f37\hich\af37\dbch\af37\cgrid\langnp2057\langfenp1033 \sbasedon0 \snext27 \slink28 \sunhideused \spriority0 footer;}{\*\cs28 \additive \fs22\lang2057\langfe0\langnp2057 \slink27 \slocked \ssemihidden Footer Char;}{\*\cs29 +\additive \rtlch\fcs1 \af0 \ltrch\fcs0 \sbasedon10 \spriority0 page number;}{\s30\ql \fi-425\li1134\ri0\sb120\sa120\widctlpar\tx1134\tqr\tx7920\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin1134\itap0 \rtlch\fcs1 \af0\afs20\alang1025 \ltrch\fcs0 +\fs18\lang2057\langfe1033\loch\f1\hich\af1\dbch\af14\cgrid\langnp2057\langfenp1033 \sbasedon0 \snext30 \spriority0 Indent;}{\s31\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 \af0\afs22\alang1025 +\ltrch\fcs0 \fs22\lang2057\langfe1033\loch\f37\hich\af37\dbch\af37\cgrid\langnp2057\langfenp1033 \snext31 \shidden \ssemihidden Revision;}{\s32\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \rtlch\fcs1 +\af0\afs21\alang1025 \ltrch\fcs0 \f39\fs21\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 \sbasedon0 \snext32 \slink33 \sunhideused Plain Text;}{\*\cs33 \additive \f39\fs21\lang0\langfe1033\langfenp1033 \slink32 \slocked Plain Text Char;}{ +\s34\ql \li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin720\itap0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 \fs22\lang2057\langfe1033\loch\f37\hich\af37\dbch\af37\cgrid\langnp2057\langfenp1033 +\sbasedon0 \snext34 \sqformat \spriority34 List Paragraph;}}{\*\listtable{\*\listpicture{\pict{\*\picprop\shplid1025{\sp{\sn shapeType}{\sv 75}}{\sp{\sn fFlipH}{\sv 0}}{\sp{\sn fFlipV}{\sv 0}}{\sp{\sn fLine}{\sv 0}}{\sp{\sn borderTopColor}{\sv -16777216}} +{\sp{\sn borderLeftColor}{\sv -16777216}}{\sp{\sn borderBottomColor}{\sv -16777216}}{\sp{\sn borderRightColor}{\sv -16777216}}{\sp{\sn fIsBullet}{\sv 1}}{\sp{\sn fLayoutInCell}{\sv 1}}}\picscalex100\picscaley100\piccropl0\piccropr0\piccropt0\piccropb0 +\picw7620\pich7620\picwgoal4320\pichgoal4320\wmetafile8\bliptag1621848657\blipupi-183{\*\blipuid 60ab72513f0584938171c3e04d1ffcc4} +0100090000039100000002001c00000000000400000003010800050000000b0200000000050000000c0209070507040000002e0118001c000000fb02a4ff0000 +000000009001000000000440002243616c6962726900000000000000000000000000000000000000000000000000040000002d010000040000002d0100000400 +00002d010000040000002d010000040000002d010000040000002d0100000400000002010100050000000902000000020d000000320a57000000010004000000 +00000807080720003600050000000902000000021c000000fb021000070000000000bc02000000000102022253797374656d0076d0e132092cfb3d00d9e4497680014e76a4f2530a38fb3d00040000002d010100040000002d010100030000000000}}{\list\listtemplateid-492936738\listhybrid{\listlevel +\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'00.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li720\lin720 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0 +\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'01.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li1440\lin1440 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext +\'02\'02.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-180\li2160\lin2160 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'03.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 +\ltrch\fcs0 \fi-360\li2880\lin2880 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'04.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li3600\lin3600 }{\listlevel\levelnfc2 +\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'05.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-180\li4320\lin4320 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1 +\levelspace0\levelindent0{\leveltext\'02\'06.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li5040\lin5040 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext +\'02\'07.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li5760\lin5760 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'08.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 +\ltrch\fcs0 \fi-180\li6480\lin6480 }{\listname ;}\listid39328222}{\list\listtemplateid-917765150\listhybrid{\listlevel\levelnfc2\levelnfcn2\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'03(\'00);}{\levelnumbers\'02;} +\rtlch\fcs1 \af0 \ltrch\fcs0 \fbias0 \fi-720\li1080\lin1080 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'01.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 +\fi-360\li1440\lin1440 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'02.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-180\li2160\lin2160 }{\listlevel +\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'03.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li2880\lin2880 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0 +\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'04.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li3600\lin3600 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\lvltentative +\levelspace0\levelindent0{\leveltext\'02\'05.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-180\li4320\lin4320 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext +\'02\'06.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li5040\lin5040 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'07.;}{\levelnumbers\'01;}\rtlch\fcs1 +\af0 \ltrch\fcs0 \fi-360\li5760\lin5760 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'08.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-180\li6480\lin6480 } +{\listname ;}\listid144588935}{\list\listtemplateid-1026387870{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'01\'00;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fbias0 +\fi-360\li360\lin360 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat2\levelspace0\levelindent0{\leveltext\'03\'00.\'01;}{\levelnumbers\'01\'03;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fbias0 \fi-360\li360\lin360 }{\listlevel\levelnfc0 +\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'05\'00.\'01.\'02;}{\levelnumbers\'01\'03\'05;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fbias0 \fi-720\li720\lin720 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0 +\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'07\'00.\'01.\'02.\'03;}{\levelnumbers\'01\'03\'05\'07;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fbias0 \fi-720\li720\lin720 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0 +\levelstartat1\levelspace0\levelindent0{\leveltext\'09\'00.\'01.\'02.\'03.\'04;}{\levelnumbers\'01\'03\'05\'07\'09;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fbias0 \fi-720\li720\lin720 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1 +\levelspace0\levelindent0{\leveltext\'0b\'00.\'01.\'02.\'03.\'04.\'05;}{\levelnumbers\'01\'03\'05\'07\'09\'0b;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fbias0 \fi-1080\li1080\lin1080 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1 +\levelspace0\levelindent0{\leveltext\'0d\'00.\'01.\'02.\'03.\'04.\'05.\'06;}{\levelnumbers\'01\'03\'05\'07\'09\'0b\'0d;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fbias0 \fi-1080\li1080\lin1080 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0 +\levelstartat1\levelspace0\levelindent0{\leveltext\'0f\'00.\'01.\'02.\'03.\'04.\'05.\'06.\'07;}{\levelnumbers\'01\'03\'05\'07\'09\'0b\'0d\'0f;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fbias0 \fi-1440\li1440\lin1440 }{\listlevel\levelnfc0\levelnfcn0\leveljc0 +\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'11\'00.\'01.\'02.\'03.\'04.\'05.\'06.\'07.\'08;}{\levelnumbers\'01\'03\'05\'07\'09\'0b\'0d\'0f\'11;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fbias0 \fi-1440\li1440\lin1440 }{\listname +;}\listid155655221}{\list\listtemplateid466939434\listhybrid{\listlevel\levelnfc3\levelnfcn3\leveljc0\leveljcn0\levelfollow0\levelstartat6\levelspace0\levelindent0{\leveltext\'03(\'00);}{\levelnumbers\'02;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fbias0 +\fi-360\li1080\lin1080 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'01.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li1800\lin1800 }{\listlevel +\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'02.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-180\li2520\lin2520 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0 +\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'03.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li3240\lin3240 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative +\levelspace0\levelindent0{\leveltext\'02\'04.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li3960\lin3960 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext +\'02\'05.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-180\li4680\lin4680 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'06.;}{\levelnumbers\'01;}\rtlch\fcs1 +\af0 \ltrch\fcs0 \fi-360\li5400\lin5400 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'07.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li6120\lin6120 } +{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'08.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-180\li6840\lin6840 }{\listname ;}\listid207642902} +{\list\listtemplateid-868587660\listhybrid{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'03(\'00);}{\levelnumbers\'02;}\rtlch\fcs1 \af0 \ltrch\fcs0 \cf1\dbch\af0\fbias0 +\fi-360\li720\lin720 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'01.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li1440\lin1440 }{\listlevel\levelnfc2 +\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'02.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-180\li2160\lin2160 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0 +\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'03.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li2880\lin2880 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0 +\levelindent0{\leveltext\'02\'04.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li3600\lin3600 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext +\'02\'05.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-180\li4320\lin4320 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'06.;}{\levelnumbers\'01;}\rtlch\fcs1 +\af0 \ltrch\fcs0 \fi-360\li5040\lin5040 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'07.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li5760\lin5760 } +{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'08.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-180\li6480\lin6480 }{\listname ;}\listid244075828} +{\list\listtemplateid-301287646\listhybrid{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'03(\'00);}{\levelnumbers\'02;}\rtlch\fcs1 \af0 \ltrch\fcs0 \cf1\dbch\af0\fbias0 +\fi-360\li720\lin720 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'01.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li1440\lin1440 }{\listlevel\levelnfc2 +\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'02.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-180\li2160\lin2160 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0 +\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'03.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li2880\lin2880 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0 +\levelindent0{\leveltext\'02\'04.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li3600\lin3600 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext +\'02\'05.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-180\li4320\lin4320 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'06.;}{\levelnumbers\'01;}\rtlch\fcs1 +\af0 \ltrch\fcs0 \fi-360\li5040\lin5040 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'07.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li5760\lin5760 } +{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'08.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-180\li6480\lin6480 }{\listname ;}\listid358317280} +{\list\listtemplateid572415416\listhybrid{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'03(\'00);}{\levelnumbers\'02;}\rtlch\fcs1 \af0 \ltrch\fcs0 \cf0\dbch\af37\fbias0 +\fi-360\li786\lin786 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'01.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li1506\lin1506 }{\listlevel\levelnfc2 +\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'02.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-180\li2226\lin2226 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0 +\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'03.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li2946\lin2946 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0 +\levelindent0{\leveltext\'02\'04.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li3666\lin3666 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext +\'02\'05.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-180\li4386\lin4386 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'06.;}{\levelnumbers\'01;}\rtlch\fcs1 +\af0 \ltrch\fcs0 \fi-360\li5106\lin5106 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'07.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li5826\lin5826 } +{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'08.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-180\li6546\lin6546 }{\listname ;}\listid423112302} +{\list\listtemplateid-1459612926\listhybrid{\listlevel\levelnfc3\levelnfcn3\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'00.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fbias0 \fi-360\li1275\lin1275 } +{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'01.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li1995\lin1995 }{\listlevel\levelnfc2\levelnfcn2\leveljc2 +\leveljcn2\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'02.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-180\li2715\lin2715 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1 +\lvltentative\levelspace0\levelindent0{\leveltext\'02\'03.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li3435\lin3435 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0 +{\leveltext\'02\'04.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li4155\lin4155 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'05.;}{\levelnumbers\'01;} +\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-180\li4875\lin4875 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'06.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 +\fi-360\li5595\lin5595 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'07.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li6315\lin6315 }{\listlevel +\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'08.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-180\li7035\lin7035 }{\listname ;}\listid454718230} +{\list\listtemplateid-551514274\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat2\levelspace0\levelindent0{\leveltext\'01-;}{\levelnumbers;}\loch\af1\hich\af1\dbch\af0\fbias0 \fi-360\li1080\lin1080 }{\listlevel +\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'01o;}{\levelnumbers;}\f2\fbias0 \fi-360\li1800\lin1800 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0 +\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'01\u-3929 ?;}{\levelnumbers;}\f10\fbias0 \fi-360\li2520\lin2520 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0 +{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li3240\lin3240 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'01o;}{\levelnumbers;}\f2\fbias0 +\fi-360\li3960\lin3960 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'01\u-3929 ?;}{\levelnumbers;}\f10\fbias0 \fi-360\li4680\lin4680 }{\listlevel\levelnfc23\levelnfcn23 +\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li5400\lin5400 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative +\levelspace0\levelindent0{\leveltext\'01o;}{\levelnumbers;}\f2\fbias0 \fi-360\li6120\lin6120 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'01\u-3929 ?;}{\levelnumbers;} +\f10\fbias0 \fi-360\li6840\lin6840 }{\listname ;}\listid474840100}{\list\listtemplateid-1601537400{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'01\u-3913 ?;}{\levelnumbers;} +\f3\fs20\fbias0 \fi-360\li720\jclisttab\tx720\lin720 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'01o;}{\levelnumbers;}\f2\fs20\fbias0 \levelpicture0\fi-360\li1440 +\jclisttab\tx1440\lin1440 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'01\u-3929 ?;}{\levelnumbers;}\f10\fs20\fbias0 \fi-360\li2160\jclisttab\tx2160\lin2160 } +{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'01\u-3929 ?;}{\levelnumbers;}\f10\fs20\fbias0 \fi-360\li2880\jclisttab\tx2880\lin2880 }{\listlevel\levelnfc23\levelnfcn23 +\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'01\u-3929 ?;}{\levelnumbers;}\f10\fs20\fbias0 \fi-360\li3600\jclisttab\tx3600\lin3600 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0 +\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'01\u-3929 ?;}{\levelnumbers;}\f10\fs20\fbias0 \fi-360\li4320\jclisttab\tx4320\lin4320 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative +\levelspace0\levelindent0{\leveltext\'01\u-3929 ?;}{\levelnumbers;}\f10\fs20\fbias0 \fi-360\li5040\jclisttab\tx5040\lin5040 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext +\'01\u-3929 ?;}{\levelnumbers;}\f10\fs20\fbias0 \fi-360\li5760\jclisttab\tx5760\lin5760 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'01\u-3929 ?;}{\levelnumbers;} +\f10\fs20\fbias0 \fi-360\li6480\jclisttab\tx6480\lin6480 }{\listname ;}\listid891499942}{\list\listtemplateid-2106560774\listhybrid{\listlevel\levelnfc3\levelnfcn3\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext +\'02\'00.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fbias0 \fi-360\li720\lin720 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'01.;}{\levelnumbers\'01;} +\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li1440\lin1440 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'02.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 +\fi-180\li2160\lin2160 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'03.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li2880\lin2880 }{\listlevel +\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'04.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li3600\lin3600 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2 +\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'05.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-180\li4320\lin4320 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative +\levelspace0\levelindent0{\leveltext\'02\'06.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li5040\lin5040 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext +\'02\'07.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li5760\lin5760 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'08.;}{\levelnumbers\'01;}\rtlch\fcs1 +\af0 \ltrch\fcs0 \fi-180\li6480\lin6480 }{\listname ;}\listid939029968}{\list\listtemplateid1475657882\listhybrid{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat2\levelspace0\levelindent0{\leveltext\'01-;}{\levelnumbers;} +\loch\af1\hich\af1\dbch\af0\fbias0 \fi-360\li1440\lin1440 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'01o;}{\levelnumbers;}\f2\fbias0 \fi-360\li2160\lin2160 }{\listlevel\levelnfc23 +\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'01\u-3929 ?;}{\levelnumbers;}\f10\fbias0 \fi-360\li2880\lin2880 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1 +\lvltentative\levelspace0\levelindent0{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li3600\lin3600 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext +\'01o;}{\levelnumbers;}\f2\fbias0 \fi-360\li4320\lin4320 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'01\u-3929 ?;}{\levelnumbers;}\f10\fbias0 \fi-360\li5040\lin5040 } +{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li5760\lin5760 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0 +\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'01o;}{\levelnumbers;}\f2\fbias0 \fi-360\li6480\lin6480 }{\listlevel\levelnfc23\levelnfcn23\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0 +{\leveltext\'01\u-3929 ?;}{\levelnumbers;}\f10\fbias0 \fi-360\li7200\lin7200 }{\listname ;}\listid1080055287}{\list\listtemplateid345380616\listhybrid{\listlevel\levelnfc2\levelnfcn2\leveljc0\leveljcn0\levelfollow0\levelstartat2\levelspace0\levelindent0 +{\leveltext\'03(\'00);}{\levelnumbers\'02;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fbias0 \fi-720\li1864\lin1864 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext +\'02\'01.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li2224\lin2224 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'02.;}{\levelnumbers\'01;}\rtlch\fcs1 +\af0 \ltrch\fcs0 \fi-180\li2944\lin2944 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'03.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li3664\lin3664 } +{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'04.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li4384\lin4384 }{\listlevel\levelnfc2\levelnfcn2\leveljc2 +\leveljcn2\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'05.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-180\li5104\lin5104 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1 +\lvltentative\levelspace0\levelindent0{\leveltext\'02\'06.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li5824\lin5824 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0 +{\leveltext\'02\'07.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li6544\lin6544 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'08.;}{\levelnumbers\'01;} +\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-180\li7264\lin7264 }{\listname ;}\listid1198470673}{\list\listtemplateid-1488150726\listhybrid{\listlevel\levelnfc2\levelnfcn2\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext +\'03(\'00);}{\levelnumbers\'02;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fbias0 \fi-720\li1080\lin1080 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'01.;}{\levelnumbers\'01;} +\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li1440\lin1440 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'02.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 +\fi-180\li2160\lin2160 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'03.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li2880\lin2880 }{\listlevel +\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'04.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li3600\lin3600 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2 +\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'05.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-180\li4320\lin4320 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative +\levelspace0\levelindent0{\leveltext\'02\'06.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li5040\lin5040 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext +\'02\'07.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li5760\lin5760 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'08.;}{\levelnumbers\'01;}\rtlch\fcs1 +\af0 \ltrch\fcs0 \fi-180\li6480\lin6480 }{\listname ;}\listid1264800667}{\list\listtemplateid1709371634{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'01\'00;}{\levelnumbers\'01;} +\rtlch\fcs1 \af0 \ltrch\fcs0 \fbias0 \fi-360\li360\lin360 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat2\levelspace0\levelindent0{\leveltext\'03\'00.\'01;}{\levelnumbers\'01\'03;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fbias0 +\fi-360\li360\lin360 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'05\'00.\'01.\'02;}{\levelnumbers\'01\'03\'05;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fbias0 \fi-720\li720\lin720 }{\listlevel +\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'07\'00.\'01.\'02.\'03;}{\levelnumbers\'01\'03\'05\'07;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fbias0 \fi-720\li720\lin720 }{\listlevel\levelnfc0\levelnfcn0 +\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'09\'00.\'01.\'02.\'03.\'04;}{\levelnumbers\'01\'03\'05\'07\'09;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fbias0 \fi-720\li720\lin720 }{\listlevel\levelnfc0\levelnfcn0\leveljc0 +\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'0b\'00.\'01.\'02.\'03.\'04.\'05;}{\levelnumbers\'01\'03\'05\'07\'09\'0b;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fbias0 \fi-1080\li1080\lin1080 }{\listlevel\levelnfc0\levelnfcn0\leveljc0 +\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'0d\'00.\'01.\'02.\'03.\'04.\'05.\'06;}{\levelnumbers\'01\'03\'05\'07\'09\'0b\'0d;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fbias0 \fi-1080\li1080\lin1080 }{\listlevel\levelnfc0\levelnfcn0 +\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'0f\'00.\'01.\'02.\'03.\'04.\'05.\'06.\'07;}{\levelnumbers\'01\'03\'05\'07\'09\'0b\'0d\'0f;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fbias0 \fi-1440\li1440\lin1440 }{\listlevel +\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'11\'00.\'01.\'02.\'03.\'04.\'05.\'06.\'07.\'08;}{\levelnumbers\'01\'03\'05\'07\'09\'0b\'0d\'0f\'11;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fbias0 +\fi-1440\li1440\lin1440 }{\listname ;}\listid1335182434}{\list\listtemplateid-1861725538\listhybrid{\listlevel\levelnfc3\levelnfcn3\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'00.;}{\levelnumbers\'01;} +\rtlch\fcs1 \af0 \ltrch\fcs0 \fbias0 \fi-360\li720\lin720 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'01.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 +\fi-360\li1440\lin1440 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'02.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-180\li2160\lin2160 }{\listlevel +\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'03.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li2880\lin2880 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0 +\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'04.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li3600\lin3600 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\lvltentative +\levelspace0\levelindent0{\leveltext\'02\'05.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-180\li4320\lin4320 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext +\'02\'06.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li5040\lin5040 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'07.;}{\levelnumbers\'01;}\rtlch\fcs1 +\af0 \ltrch\fcs0 \fi-360\li5760\lin5760 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'08.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-180\li6480\lin6480 } +{\listname ;}\listid1556695208}{\list\listtemplateid-301287646\listhybrid{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'03(\'00);}{\levelnumbers\'02;}\rtlch\fcs1 \af0 \ltrch\fcs0 +\cf1\dbch\af0\fbias0 \fi-360\li720\lin720 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'01.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li1440\lin1440 } +{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'02.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-180\li2160\lin2160 }{\listlevel\levelnfc0\levelnfcn0\leveljc0 +\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'03.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li2880\lin2880 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1 +\lvltentative\levelspace0\levelindent0{\leveltext\'02\'04.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li3600\lin3600 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0 +{\leveltext\'02\'05.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-180\li4320\lin4320 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'06.;}{\levelnumbers\'01;} +\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li5040\lin5040 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'07.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 +\fi-360\li5760\lin5760 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'08.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-180\li6480\lin6480 }{\listname +;}\listid1583906200}{\list\listtemplateid1806592008\listhybrid{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'03(\'00);}{\levelnumbers\'02;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fbias0 +\fi-360\li720\lin720 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'01.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li1440\lin1440 }{\listlevel\levelnfc2 +\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'02.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-180\li2160\lin2160 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0 +\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'03.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li2880\lin2880 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0 +\levelindent0{\leveltext\'02\'04.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li3600\lin3600 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext +\'02\'05.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-180\li4320\lin4320 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'06.;}{\levelnumbers\'01;}\rtlch\fcs1 +\af0 \ltrch\fcs0 \fi-360\li5040\lin5040 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'07.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li5760\lin5760 } +{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'08.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-180\li6480\lin6480 }{\listname ;}\listid1801338294} +{\list\listtemplateid-1056679890\listhybrid{\listlevel\levelnfc2\levelnfcn2\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'03(\'00);}{\levelnumbers\'02;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fbias0 \fi-720\li1429 +\jclisttab\tx1429\lin1429 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'01.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li1789\jclisttab\tx1789\lin1789 } +{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'02.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-180\li2509\jclisttab\tx2509\lin2509 }{\listlevel\levelnfc0 +\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'03.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li3229\jclisttab\tx3229\lin3229 }{\listlevel\levelnfc4\levelnfcn4\leveljc0 +\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'04.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li3949\jclisttab\tx3949\lin3949 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0 +\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'05.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-180\li4669\jclisttab\tx4669\lin4669 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative +\levelspace0\levelindent0{\leveltext\'02\'06.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li5389\jclisttab\tx5389\lin5389 }{\listlevel\levelnfc4\levelnfcn4\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0 +{\leveltext\'02\'07.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li6109\jclisttab\tx6109\lin6109 }{\listlevel\levelnfc2\levelnfcn2\leveljc2\leveljcn2\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext +\'02\'08.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-180\li6829\jclisttab\tx6829\lin6829 }{\listname ;}\listid1872956500}{\list\listtemplateid2052502928{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0 +\levelindent0{\leveltext\'02\'00.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li720\jclisttab\tx720\lin720 }{\listlevel\levelnfc3\levelnfcn3\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext +\'02\'01.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li1440\jclisttab\tx1440\lin1440 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'02.;}{\levelnumbers +\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li2160\jclisttab\tx2160\lin2160 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'03.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 +\ltrch\fcs0 \fi-360\li2880\jclisttab\tx2880\lin2880 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'04.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li3600 +\jclisttab\tx3600\lin3600 }{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'05.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li4320\jclisttab\tx4320\lin4320 } +{\listlevel\levelnfc0\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'06.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li5040\jclisttab\tx5040\lin5040 }{\listlevel\levelnfc0 +\levelnfcn0\leveljc0\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'07.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li5760\jclisttab\tx5760\lin5760 }{\listlevel\levelnfc0\levelnfcn0\leveljc0 +\leveljcn0\levelfollow0\levelstartat1\lvltentative\levelspace0\levelindent0{\leveltext\'02\'08.;}{\levelnumbers\'01;}\rtlch\fcs1 \af0 \ltrch\fcs0 \fi-360\li6480\jclisttab\tx6480\lin6480 }{\listname ;}\listid1950702225}}{\*\listoverridetable +{\listoverride\listid474840100\listoverridecount0\ls1}{\listoverride\listid1080055287\listoverridecount0\ls2}{\listoverride\listid1872956500\listoverridecount0\ls3}{\listoverride\listid1198470673\listoverridecount0\ls4}{\listoverride\listid1950702225 +\listoverridecount0\ls5}{\listoverride\listid1556695208\listoverridecount0\ls6}{\listoverride\listid454718230\listoverridecount0\ls7}{\listoverride\listid939029968\listoverridecount0\ls8}{\listoverride\listid1264800667\listoverridecount0\ls9} +{\listoverride\listid244075828\listoverridecount0\ls10}{\listoverride\listid423112302\listoverridecount0\ls11}{\listoverride\listid1801338294\listoverridecount0\ls12}{\listoverride\listid155655221\listoverridecount0\ls13}{\listoverride\listid1335182434 +\listoverridecount0\ls14}{\listoverride\listid144588935\listoverridecount0\ls15}{\listoverride\listid1583906200\listoverridecount0\ls16}{\listoverride\listid891499942\listoverridecount0\ls17}{\listoverride\listid358317280\listoverridecount0\ls18} +{\listoverride\listid207642902\listoverridecount0\ls19}{\listoverride\listid39328222\listoverridecount9{\lfolevel\listoverridestartat\levelstartat1}{\lfolevel\listoverridestartat\levelstartat1}{\lfolevel\listoverridestartat\levelstartat1}{\lfolevel +\listoverridestartat\levelstartat1}{\lfolevel\listoverridestartat\levelstartat1}{\lfolevel\listoverridestartat\levelstartat1}{\lfolevel\listoverridestartat\levelstartat1}{\lfolevel\listoverridestartat\levelstartat1}{\lfolevel\listoverridestartat +\levelstartat1}\ls20}}{\*\rsidtbl \rsid2044820\rsid10637227\rsid11554224\rsid14553496}{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0\mdispDef1\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim1}{\info +{\title LEC-PRE-00489 ~ EULA for CMSIS Deliverables}{\author Emily Drea}{\operator Joachim Krech}{\creatim\yr2015\mo8\dy27\hr7\min15}{\revtim\yr2015\mo8\dy27\hr7\min15}{\printim\yr2015\mo8\dy18\hr8\min33}{\version2}{\edmins1}{\nofpages5}{\nofwords2395} +{\nofchars13654}{\*\company ARM Ltd}{\nofcharsws16017}{\vern49167}}{\*\userprops {\propname Check In Comment}\proptype30{\staticval Major Version Publish}{\propname ComputedCompany}\proptype30{\staticval ARM/}{\propname ComputedLR}\proptype30{\staticval A +P/}{\propname ComputedNumber}\proptype30{\staticval LEC-PRE-00489-V6.0}{\propname Created}\proptype30{\staticval 2014-06-01T22:01:00Z}{\propname Description}\proptype30{\staticval }{\propname display_urn:schemas-microsoft-com:office:office#Author} +\proptype30{\staticval Emily Drea}{\propname display_urn:schemas-microsoft-com:office:office#Editor}\proptype30{\staticval Emily Drea}{\propname EMAIL_OWNER_ADDRESS}\proptype30{\staticval sAAAUYtyAkeNWR4c/hyv83djDdgT//SlfRfj0yul0Nymu58=}{\propname FileLea +fRef}\proptype30{\staticval LEC-PRE-00489}{\propname HiddenDelete}\proptype30{\staticval }{\propname HiddenUpload}\proptype30{\staticval }{\propname MAIL_MSG_ID1}\proptype30{\staticval ABAAVOAfoSrQoywVz+n89RkH8vckJh2hX9X1LeIJRLXpkh+XCtJmzNRfIdvcDdtCC+CW} +{\propname MAIL_MSG_ID2}\proptype30{\staticval c5CxtGnFSJrNPiFAS7uBa/Md4M/GKbLGzLnuTUVlLUhYPGbMRhOa5RG4vn7\'0d\'0aRvdHkjT0j+KBwUyX0J0TijfAeRM/c9+3kWygmQ==}{\propname Modified}\proptype30{\staticval 2015-08-18T10:13:43Z}{\propname Modified By}\proptype30 +{\staticval 62\'3b#Emily Drea,#EMEA\'5cemidre01,#Emily.Drea@arm.com,#,#Emily Drea}{\propname Name}\proptype30{\staticval LEC-PRE-00489.doc}{\propname Order}\proptype30{\staticval 672300}{\propname Property Bag}\proptype30{\staticval vti_contentversionisdi +rty:BW|false\'0d\'0avti_parserversion:SR|14.0.0.6029\'0d\'0aEXT:SW|doc\'0d\'0aOrder:IW|672300\'0d\'0avti_contenttag:SW|\'7b7AA67540-4642-44E7-8CB5-11C47CDC1B3E\'7d,137,51\'0d\'0a_Category:SW|\'0d\'0aRESPONSE_SENDER_NAME:SW|gAAAdya76B99d4hLGUR1rQ+8TxTv0GGE +Pdix\'0d\'0avti_author:SR|}{\propname RESPONSE_SENDER_NAME}\proptype30{\staticval gAAAdya76B99d4hLGUR1rQ+8TxTv0GGEPdix}{\propname Title}\proptype30{\staticval LEC-PRE-00489 ~ EULA for CMSIS Deliverables}}{\*\xmlnstbl {\xmlns1 http://schemas.microsoft.com/ +office/word/2003/wordml}}\paperw11906\paperh16838\margl1440\margr1440\margt1440\margb1440\gutter0\ltrsect +\widowctrl\ftnbj\aenddoc\revisions\trackmoves0\trackformatting1\donotembedsysfont1\relyonvml0\donotembedlingdata1\grfdocevents0\validatexml1\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0\showxmlerrors1 +\noxlattoyen\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\formshade\horzdoc\dgmargin\dghspace180\dgvspace180\dghorigin1440\dgvorigin1440\dghshow1\dgvshow1 +\jexpand\viewkind1\viewscale110\pgbrdrhead\pgbrdrfoot\splytwnine\ftnlytwnine\htmautsp\nolnhtadjtbl\useltbaln\alntblind\lytcalctblwd\lyttblrtgr\lnbrkrule\nobrkwrptbl\snaptogridincell\allowfieldendsel\wrppunct +\asianbrkrule\rsidroot2688764\newtblstyruls\nogrowautofit\utinl \fet0{\*\wgrffmtfilter 2450}\ilfomacatclnup0{\*\ftnsep \ltrpar \pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14553496 +\rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 \fs22\lang2057\langfe1033\loch\af37\hich\af37\dbch\af37\cgrid\langnp2057\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid10637227 \chftnsep +\par }}{\*\ftnsepc \ltrpar \pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14553496 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 +\fs22\lang2057\langfe1033\loch\af37\hich\af37\dbch\af37\cgrid\langnp2057\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid10637227 \chftnsepc +\par }}{\*\aftnsep \ltrpar \pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14553496 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 +\fs22\lang2057\langfe1033\loch\af37\hich\af37\dbch\af37\cgrid\langnp2057\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid10637227 \chftnsep +\par }}{\*\aftnsepc \ltrpar \pard\plain \ltrpar\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14553496 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 +\fs22\lang2057\langfe1033\loch\af37\hich\af37\dbch\af37\cgrid\langnp2057\langfenp1033 {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid10637227 \chftnsepc +\par }}\ltrpar \sectd \ltrsect\linex0\headery400\footery708\colsx708\endnhere\sectlinegrid360\sectdefaultcl\sectrsid14553496\sftnbj {\headerr \ltrpar \ltrrow\trowd \irow0\irowband0\ltrrow +\ts11\trgaph108\trrh240\trleft-108\trftsWidth1\trautofit1\trpaddl108\trpaddr108\trpaddfl3\trpaddfr3\tblind0\tblindtype3 \clvertalt\clbrdrt\brdrtbl \clbrdrl\brdrtbl \clbrdrb\brdrtbl \clbrdrr\brdrtbl \cltxlrtb\clftsWidth3\clwWidth3009\clshdrawnil \cellx2901 +\clvertalt\clbrdrt\brdrtbl \clbrdrl\brdrtbl \clbrdrb\brdrtbl \clbrdrr\brdrtbl \cltxlrtb\clftsWidth3\clwWidth3009\clshdrawnil \cellx5910\clvertalt\clbrdrt\brdrtbl \clbrdrl\brdrtbl \clbrdrb\brdrtbl \clbrdrr\brdrtbl +\cltxlrtb\clftsWidth3\clwWidth3009\clshdrawnil \cellx8919\pard\plain \ltrpar\ql \li0\ri0\sa200\sl276\slmult1\widctlpar\intbl\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 +\fs22\lang2057\langfe1033\loch\af37\hich\af37\dbch\af37\cgrid\langnp2057\langfenp1033 {\rtlch\fcs1 \af1 \ltrch\fcs0 \fs18\loch\af1\hich\af1\dbch\af1\insrsid14553496 \hich\af1\dbch\af1\loch\f1 18 August 2015\cell }\pard \ltrpar +\qc \li0\ri0\sa200\sl276\slmult1\widctlpar\intbl\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0 {\rtlch\fcs1 \af1 \ltrch\fcs0 \fs18\loch\af1\hich\af1\dbch\af1\insrsid14553496 \hich\af1\dbch\af1\loch\f1 CONFIDENTIAL\cell }\pard \ltrpar +\qr \li0\ri0\sa200\sl276\slmult1\widctlpar\intbl\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0 {\rtlch\fcs1 \af1 \ltrch\fcs0 \fs18\loch\af1\hich\af1\dbch\af1\insrsid14553496 \hich\af1\dbch\af1\loch\f1 LEC-PRE-00489\cell }\pard \ltrpar +\ql \li0\ri0\widctlpar\intbl\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0 {\rtlch\fcs1 \af1 \ltrch\fcs0 \fs18\loch\af1\hich\af1\dbch\af1\insrsid14553496 \trowd \irow0\irowband0\ltrrow +\ts11\trgaph108\trrh240\trleft-108\trftsWidth1\trautofit1\trpaddl108\trpaddr108\trpaddfl3\trpaddfr3\tblind0\tblindtype3 \clvertalt\clbrdrt\brdrtbl \clbrdrl\brdrtbl \clbrdrb\brdrtbl \clbrdrr\brdrtbl \cltxlrtb\clftsWidth3\clwWidth3009\clshdrawnil \cellx2901 +\clvertalt\clbrdrt\brdrtbl \clbrdrl\brdrtbl \clbrdrb\brdrtbl \clbrdrr\brdrtbl \cltxlrtb\clftsWidth3\clwWidth3009\clshdrawnil \cellx5910\clvertalt\clbrdrt\brdrtbl \clbrdrl\brdrtbl \clbrdrb\brdrtbl \clbrdrr\brdrtbl +\cltxlrtb\clftsWidth3\clwWidth3009\clshdrawnil \cellx8919\row \ltrrow}\trowd \irow1\irowband1\lastrow \ltrrow\ts11\trgaph108\trrh240\trleft-108\trftsWidth1\trautofit1\trpaddl108\trpaddr108\trpaddfl3\trpaddfr3\tblind0\tblindtype3 \clvertalt\clbrdrt +\brdrtbl \clbrdrl\brdrtbl \clbrdrb\brdrtbl \clbrdrr\brdrtbl \cltxlrtb\clftsWidth3\clwWidth9026\clshdrawnil \cellx8919\pard \ltrpar\qr \li0\ri0\sa200\sl276\slmult1\widctlpar\intbl\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0 {\rtlch\fcs1 \af1 +\ltrch\fcs0 \fs18\loch\af1\hich\af1\dbch\af1\insrsid14553496 \hich\af1\dbch\af1\loch\f1 SP-Version: 4.0\cell }\pard \ltrpar\ql \li0\ri0\widctlpar\intbl\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0 {\rtlch\fcs1 \af1 \ltrch\fcs0 +\fs18\loch\af1\hich\af1\dbch\af1\insrsid14553496 \trowd \irow1\irowband1\lastrow \ltrrow\ts11\trgaph108\trrh240\trleft-108\trftsWidth1\trautofit1\trpaddl108\trpaddr108\trpaddfl3\trpaddfr3\tblind0\tblindtype3 \clvertalt\clbrdrt\brdrtbl \clbrdrl\brdrtbl +\clbrdrb\brdrtbl \clbrdrr\brdrtbl \cltxlrtb\clftsWidth3\clwWidth9026\clshdrawnil \cellx8919\row }\pard \ltrpar\ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 +\insrsid14553496 +\par }}{\footerr \ltrpar \ltrrow\trowd \irow0\irowband0\lastrow \ltrrow\ts11\trgaph108\trrh240\trleft-108\trftsWidth1\trautofit1\trpaddl108\trpaddr108\trpaddfl3\trpaddfr3\tblind0\tblindtype3 \clvertalt\clbrdrt\brdrtbl \clbrdrl\brdrtbl \clbrdrb\brdrtbl \clbrdrr +\brdrtbl \cltxlrtb\clftsWidth3\clwWidth4513\clshdrawnil \cellx4405\clvertalt\clbrdrt\brdrtbl \clbrdrl\brdrtbl \clbrdrb\brdrtbl \clbrdrr\brdrtbl \cltxlrtb\clftsWidth3\clwWidth4513\clshdrawnil \cellx8918\pard\plain \ltrpar\qr \li0\ri0\sa200\sl276\slmult1 +\widctlpar\intbl\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 \fs22\lang2057\langfe1033\loch\af37\hich\af37\dbch\af37\cgrid\langnp2057\langfenp1033 {\field{\*\fldinst {\rtlch\fcs1 \af1 \ltrch\fcs0 +\fs18\loch\af1\hich\af1\dbch\af1\insrsid14553496 \hich\af1\dbch\af1\loch\f1 PAG\hich\af1\dbch\af1\loch\f1 E}}{\fldrslt {\rtlch\fcs1 \af1 \ltrch\fcs0 \fs18\lang1024\langfe1024\loch\af1\hich\af1\dbch\af1\noproof\insrsid2044820 \hich\af1\dbch\af1\loch\f1 1} +}}\sectd \ltrsect\linex0\endnhere\sectdefaultcl\sftnbj {\rtlch\fcs1 \af1 \ltrch\fcs0 \fs18\loch\af1\hich\af1\dbch\af1\insrsid14553496 \hich\af1\dbch\af1\loch\f1 of }{\field{\*\fldinst {\rtlch\fcs1 \af1 \ltrch\fcs0 +\fs18\loch\af1\hich\af1\dbch\af1\insrsid14553496 \hich\af1\dbch\af1\loch\f1 NUMPAGES}}{\fldrslt {\rtlch\fcs1 \af1 \ltrch\fcs0 \fs18\lang1024\langfe1024\loch\af1\hich\af1\dbch\af1\noproof\insrsid2044820 \hich\af1\dbch\af1\loch\f1 5}}}\sectd \ltrsect +\linex0\endnhere\sectdefaultcl\sftnbj {\rtlch\fcs1 \af1 \ltrch\fcs0 \fs18\loch\af1\hich\af1\dbch\af1\insrsid14553496 \cell \cell }\pard \ltrpar\ql \li0\ri0\widctlpar\intbl\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0 {\rtlch\fcs1 \af1 +\ltrch\fcs0 \fs18\loch\af1\hich\af1\dbch\af1\insrsid14553496 \trowd \irow0\irowband0\lastrow \ltrrow\ts11\trgaph108\trrh240\trleft-108\trftsWidth1\trautofit1\trpaddl108\trpaddr108\trpaddfl3\trpaddfr3\tblind0\tblindtype3 \clvertalt\clbrdrt\brdrtbl \clbrdrl +\brdrtbl \clbrdrb\brdrtbl \clbrdrr\brdrtbl \cltxlrtb\clftsWidth3\clwWidth4513\clshdrawnil \cellx4405\clvertalt\clbrdrt\brdrtbl \clbrdrl\brdrtbl \clbrdrb\brdrtbl \clbrdrr\brdrtbl \cltxlrtb\clftsWidth3\clwWidth4513\clshdrawnil \cellx8918\row }\pard \ltrpar +\ql \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 {\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid14553496 +\par }}{\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}} +{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8 +\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}\pard\plain \ltrpar\qj \li0\ri0\sa240\widctlpar +\tx916\tx1832\tx2748\tx3664\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14553496 \cbpat8 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 +\fs22\lang2057\langfe1033\loch\af37\hich\af37\dbch\af37\cgrid\langnp2057\langfenp1033 {\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15280636 END USER LICENCE AGREEMENT FOR THE }{\rtlch\fcs1 +\af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 CORTEX MICROCONTROLLER SOFTWARE INTERFACE STANDARD (CMSIS) DELIVERABLES }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15280636 +\par THIS END USER LICENCE AGREEMENT ("LICENCE") IS A LEGAL AGREEMENT BETWEEN YOU (EITHER A }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid5861575 +SINGLE INDIVIDUAL, OR SINGLE LEGAL ENTITY) AND ARM LIMITED ("ARM") FOR THE USE OF THE CMSIS }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 DELIVERABLES}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid5861575 . ARM IS ONLY WILLING TO LICENSE THE }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 CMSIS DELIVERABLES }{\rtlch\fcs1 +\af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid5861575 TO YOU ON CONDITION THAT YOU ACCEPT ALL OF THE}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15280636 TERMS IN THIS LICENCE. BY CLICKING "I AGREE", OR BY INSTALLING OR OTHERWISE USING OR COPYING THE }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 CMSIS DELIVERABLES }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15280636 +YOU INDICATE THAT YOU AGREE TO BE BOUND BY ALL THE TERMS OF THIS LICENCE. IF YOU DO NOT AGREE TO THE TERMS OF THIS LICENCE, ARM IS UNWILLING TO LICENSE YOU TO USE }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 OF }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15280636 THE }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 CMSIS DELIVERABLES}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15280636 AND YOU MAY NOT INSTALL, USE OR COPY THE }{\rtlch\fcs1 +\af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 CMSIS DELIVERABLES}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15280636 . +\par }\pard \ltrpar\qj \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14553496 {\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 \'93Deliverables\'94 + means (i) the CMSIS Deliverables; (ii) CMSIS-DAP Specification; (iii) CMSIS-DAP Firmware; and (iv) RDDI DLL. +\par \'93CMSIS-DAP Specification\'94 means any documentation defining the application programming interface, naming and coding conventions of the Cortex Microcontroller Software Interface Standard Debug Access Port (\'93CMSIS-DAP\'94). }{\rtlch\fcs1 +\af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496\charrsid4029239 \hich\af1\dbch\af37\loch\f1 \hich\f1 Notwithstanding the foregoing, \'93}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496 \hich\af1\dbch\af37\loch\f1 CMSIS-DAP }{\rtlch\fcs1 +\af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496\charrsid4029239 \hich\af1\dbch\af37\loch\f1 \hich\f1 Specification\'94\loch\f1 shall not include}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496 \hich\af1\dbch\af37\loch\f1 :}{\rtlch\fcs1 +\af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496\charrsid4029239 \hich\af1\dbch\af37\loch\f1 (i) the implementation of other published specifications referenced in th}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496 +\hich\af1\dbch\af37\loch\f1 e}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496\charrsid4029239 \hich\af1\dbch\af37\loch\f1 }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496 \hich\af1\dbch\af37\loch\f1 CMSIS-DAP }{\rtlch\fcs1 +\af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496\charrsid4029239 \hich\af1\dbch\af37\loch\f1 Specific\hich\af1\dbch\af37\loch\f1 ation; }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496 \hich\af1\dbch\af37\loch\f1 and }{\rtlch\fcs1 \af1\afs18 +\ltrch\fcs0 \f1\fs18\insrsid14553496\charrsid4029239 \hich\af1\dbch\af37\loch\f1 (ii) any enabling technologies that may be necessary to make or use any product or portion}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496 +\hich\af1\dbch\af37\loch\f1 s}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496\charrsid4029239 \hich\af1\dbch\af37\loch\f1 thereof that complies with the }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496 +\hich\af1\dbch\af37\loch\f1 CMSIS-DAP }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496\charrsid4029239 \hich\af1\dbch\af37\loch\f1 Specification, but are not themselves expressly set forth in th}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\insrsid14553496 \hich\af1\dbch\af37\loch\f1 e}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496\charrsid4029239 \hich\af1\dbch\af37\loch\f1 }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496 \hich\af1\dbch\af37\loch\f1 +CMSIS-DAP }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496\charrsid4029239 \hich\af1\dbch\af37\loch\f1 Specification (e.g. compiler front en\hich\af1\dbch\af37\loch\f1 +ds, code generators, back ends, libraries or other compiler, assembler or linker technologies; validation or debug software or hardware; applications, operating system or driver software; RISC architecture; }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\insrsid14553496 \hich\af1\dbch\af37\loch\f1 and }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496\charrsid4029239 \hich\af1\dbch\af37\loch\f1 processor microarchitecture)}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496 +\hich\af1\dbch\af37\loch\f1 . }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496\charrsid4029239 \hich\af1\dbch\af37\loch\f1 }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496 +\par }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 \'93}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496\charrsid11929640 \hich\af1\dbch\af37\loch\f1 CMSIS-DAP Fi\hich\af1\dbch\af37\loch\f1 +rmware}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 \'94 + means the C programming language source code accompanying this Licence which implements the functionality of the application programming interface as defined in the CMSIS-DAP Specification and any updates, patches and modifications ARM may make ava +ilable under the terms of this Licence. +\par \'93CMSIS Deliverables\'94 means the following components: (i) CMSIS-CORE; (ii) CMSIS-DRIVER; (iii) CMSIS-DSP; (iv) CMSIS-PACK; (v) CMSIS-RTOS API; and (vi) CMSIS-SVD . +\par }\pard \ltrpar\qj \li0\ri0\sa200\sl276\slmult1\widctlpar\tx0\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14553496 {\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 \'93CMSIS-CORE +\'94 means the specification defining the application programming interface, naming and coding conventions for the Cortex-M processor cores. +\par \'94}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496\charrsid488451 \hich\af1\dbch\af37\loch\f1 CMSIS-DRIVER}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 \'94}{\rtlch\fcs1 \af0 \ltrch\fcs0 +\insrsid14553496 \hich\af37\dbch\af37\loch\f37 }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496\charrsid488451 \hich\af1\dbch\af37\loch\f1 means the specification defining }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496 +\hich\af1\dbch\af37\loch\f1 a generic}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496\charrsid488451 \hich\af1\dbch\af37\loch\f1 }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496 \hich\af1\dbch\af37\loch\f1 p}{\rtlch\fcs1 +\af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496\charrsid488451 \hich\af1\dbch\af37\loch\f1 eripheral }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496 \hich\af1\dbch\af37\loch\f1 d}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\insrsid14553496\charrsid488451 \hich\af1\dbch\af37\loch\f1 river application programming interface, naming and coding conventions}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid14553496 . +\par }\pard \ltrpar\qj \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14553496 {\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 \'93CMSIS-DSP\'94 + means the digital signal process (DSP) library specification defining the application programming interface of a DSP library implementation}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15023647 .}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 +\par }\pard \ltrpar\qj \li0\ri0\sa200\sl276\slmult1\widctlpar\tx0\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14553496 {\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 \'93}{ +\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496\charrsid13240697 \hich\af1\dbch\af37\loch\f1 CMSIS-PACK}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 \'94}{\rtlch\fcs1 \af0 \ltrch\fcs0 +\insrsid14553496\charrsid13240697 \hich\af37\dbch\af37\loch\f37 }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496\charrsid13240697 \hich\af1\dbch\af37\loch\f1 means the specification defining a software pack file format}{\rtlch\fcs1 +\af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496 \hich\af1\dbch\af37\loch\f1 , verification utility, }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496\charrsid13240697 \hich\af1\dbch\af37\loch\f1 and the associated XML +\hich\af1\dbch\af37\loch\f1 schema file}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid14553496\charrsid13240697 .}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid14553496 +\par }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 \'93CMSIS-RTOS API\'94 + means the real-time operating system (RTOS) specification defining a generic application programming interface layer for a RTOS system}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15023647 .}{ +\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 +\par }\pard \ltrpar\qj \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14553496 {\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 \'93CMSIS-SVD\'94 }{ +\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid9306407 means }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 +the specification defining the System View Description (SVD), verification utility, }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf17\lang1033\langfe2057\langnp1033\langfenp2057\insrsid14553496\charrsid9306407 and associated XML}{\rtlch\fcs1 \af1\afs18 +\ltrch\fcs0 \f1\fs18\cf17\lang1033\langfe2057\langnp1033\langfenp2057\insrsid14553496 schema}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf17\lang1033\langfe2057\langnp1033\langfenp2057\insrsid14553496\charrsid9306407 files. }{\rtlch\fcs1 \af1\afs18 +\ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid9306407 +\par }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 \'93Firmware\'94 means firmware that complies with the CMSIS-DAP Specification. +\par \'93RDDI DLL\'94 means the reference implementation of a device driver }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid6236778 accompanying this Licence}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 in object code form and any updates, patch +es and modifications ARM may agree to make available under the terms of this Licence and is used with targets containing microprocessors manufactured or simulated under licence from ARM. +\par \'93Separate Files\'94 means the components }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid10227990 identified}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 in the Schedule.}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid3618484 .}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 +\par \'93Target Connection Product\'94 means a target connection product that complies with the CMSIS-DAP Specification and is used on or with a target containing microprocessors manufactured or simulated under licence from ARM. +\par }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496\charrsid5577184 \hich\af1\dbch\af37\loch\f1 +Notwithstanding the foregoing, the Deliverables shall not include: (i) the implementation of other published specifications referenced in the Deliverables; (ii) any enabling technologies that may be necessary to make or use any product or portion thereof +\hich\af1\dbch\af37\loch\f1 +that complies with the Deliverables, but are not themselves expressly set forth in the Deliverables (e.g. compiler front ends, code generators, back ends, libraries or other compiler, assembler or linker technologies; validation or debug software or hard +\hich\af1\dbch\af37\loch\f1 w\hich\af1\dbch\af37\loch\f1 +are; applications, operating system or driver software; RISC architecture; processor microarchitecture); (iii) maskworks and physical layouts of integrated circuit designs; or (iv) RTL or other high level representations of integrated circuit designs.}{ +\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496 +\par }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 +\par }\pard \ltrpar\qj \li0\ri0\sa240\widctlpar\tx916\tx1832\tx2748\tx3664\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14553496 \cbpat8 { +\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15280636 1. LICENCE GRANTS. +\par }\pard \ltrpar\qj \li0\ri0\widctlpar\tx916\tx1832\tx2748\tx3664\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14553496 \cbpat8 {\rtlch\fcs1 +\af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 1.1}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15280636 }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 CMSIS DELIVERABLES +\par }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid6756135 ARM hereby grants to you, subject to the terms and conditions of this Licence, a non-exclusive, non-transferable }{\rtlch\fcs1 \af1\afs18 +\ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid1317547 licence, to use and copy the }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 CMSIS D}{\rtlch\fcs1 \af1\afs18 +\ltrch\fcs0 \f1\fs18\insrsid14553496 \hich\af1\dbch\af37\loch\f1 eliverables}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid6756135 for the purpose of: }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 +\par }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid6756135 +\par }\pard \ltrpar\qj \li0\ri0\sa200\sl276\slmult1\widctlpar +\tx426\tx916\tx1832\tx2748\tx3664\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14553496 \cbpat8 {\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid6756135 (i) subject to clause 1.}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 5(i)}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid6756135 , developing, having developed, manufacturing, having manufactured, offering to sell, selling, supplying or otherwise distributing products that comply with the }{\rtlch\fcs1 +\af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 CMSIS D}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496 \hich\af1\dbch\af37\loch\f1 eliverables}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid6756135 ; and +\par }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid1317547 (ii) distributing and having distributed (directly or through your customers and authorised distributors) the CMSIS-D}{\rtlch\fcs1 +\af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496 \hich\af1\dbch\af37\loch\f1 eliverables}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid1317547 unmodified, with the products}{\rtlch\fcs1 +\af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid6756135 you have developed under }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 Clause 1.1 (i) }{\rtlch\fcs1 +\af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid6756135 provided you preserve any copyright notices which are included with the CMSIS}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 D}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496 \hich\af1\dbch\af37\loch\f1 eliverables}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid6756135 . }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 +\par 1.2 CMSIS-DAP SPECIFICATION +\par }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15280636 ARM hereby grants to you, subject to the terms and conditions of this Licence, a non-exclusive, non-transferable licence, to }{\rtlch\fcs1 +\af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid3605578 use and copy the CMSIS}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 -DAP }{\rtlch\fcs1 \af1\afs18 +\ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid6386005 Specification}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 for the purposes of: +\par }\pard \ltrpar\qj \fi-567\li567\ri0\sl276\slmult1\widctlpar\tx567\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin567\itap0\pararsid14553496 \cbpat8 {\rtlch\fcs1 +\af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 (a)\tab }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid11225765 +developing, having developed, manufacturing, having manufactured, offering to sell, selling, supplying}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 +, distributing or having distributed a Target Connection Product}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\lang1024\langfe1024\noproof\insrsid14553496 \hich\af1\dbch\af37\loch\f1 ;}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 +\par }\pard \ltrpar\qj \fi-567\li567\ri0\sl276\slmult1\widctlpar\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin567\itap0\pararsid14553496 \cbpat8 {\rtlch\fcs1 +\af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 (b)\tab }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid11225765 developing, having developed, }{\rtlch\fcs1 +\af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 subject to clause 1.5(ii) }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid11225765 +offering to sell, selling, supplying}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 , }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid11225765 +distributing}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 or having distributed }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\lang1024\langfe1024\noproof\insrsid14553496 \hich\af1\dbch\af37\loch\f1 +(directly or through your cus\hich\af1\dbch\af37\loch\f1 tomers and authorised distributors) }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 Firmware to run on a Target Connection Product; and +\par }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid4549827 (c)}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 \tab subject to clause 1.5(ii), }{ +\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid4549827 distributing }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 and }{\rtlch\fcs1 \af1\afs18 +\ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid4549827 having distributed }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\lang1024\langfe1024\noproof\insrsid14553496 \hich\af1\dbch\af37\loch\f1 +(directly or through your customers and authorised distributors) }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid4549827 the CMSIS}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 -}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid4549827 DAP }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid14559761 Specification unmodified}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 ,}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid14559761 with}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid4549827 }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 either or both the}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid4549827 Target Connection Products and Firmware}{\rtlch\fcs1 +\af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 , developed under the licences granted in this Clause 1.2}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid4549827 .}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 +\par }\pard \ltrpar\qj \li0\ri0\sa200\sl276\slmult1\widctlpar +\tx426\tx916\tx1832\tx2748\tx3664\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14553496 \cbpat8 {\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 +\par 1.3 CMSIS-DAP FIRMWARE +\par }\pard \ltrpar\qj \li0\ri0\sl276\slmult1\widctlpar\tx916\tx1832\tx2748\tx3664\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14553496 +\cbpat8 {\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496 \hich\af1\dbch\af37\loch\f1 ARM hereby grants to you, subject to the terms and conditions of this Licence, a non-exclusive, non-trans\hich\af1\dbch\af37\loch\f1 ferable licence, to: + +\par }\pard \ltrpar\qj \fi-567\li567\ri0\sl276\slmult1\widctlpar +\tx916\tx1832\tx2748\tx3664\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin567\itap0\pararsid14553496 \cbpat8 {\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\insrsid14553496 \hich\af1\dbch\af37\loch\f1 (a)\tab }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496\charrsid10356267 \hich\af1\dbch\af37\loch\f1 use, copy}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496\charrsid2558325 +\hich\af1\dbch\af37\loch\f1 , and modify the }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496 \hich\af1\dbch\af37\loch\f1 CMSIS-DAP Firmware }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 +for the purposes of developing and having developed }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid8745136 firmware to run on}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 a Target Connection Product; and +\par (b)\tab subject to clause 1.5(ii), offer to sell, selling, }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid5058240 supply}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 , supplying, }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid8745136 distributing}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 or having distributed }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\lang1024\langfe1024\noproof\insrsid14553496 \hich\af1\dbch\af37\loch\f1 +(directly or through your customers and authorised distributors)}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 CMSIS-DAP Firmware or any modified version created under Clause 1.3 (a) }{\rtlch\fcs1 +\af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid8745136 in}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid6192099 object code form only }{\rtlch\fcs1 +\af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 to run on a Target Connection Product. }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid9913780 }{\rtlch\fcs1 +\af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 +\par +\par }\pard \ltrpar\qj \li0\ri0\sa200\sl276\slmult1\widctlpar +\tx426\tx916\tx1832\tx2748\tx3664\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14553496 \cbpat8 {\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 1.4 RDDI DLL +\par }\pard \ltrpar\qj \li0\ri0\sl276\slmult1\widctlpar\tx916\tx1832\tx2748\tx3664\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14553496 +\cbpat8 {\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 ARM hereby grants to you, subject to the terms and conditions of this Licence, a non-exclusive, non-transferable licence, to: +\par }\pard \ltrpar\qj \fi-567\li567\ri0\sl276\slmult1\widctlpar +\tx916\tx1832\tx2748\tx3664\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin567\itap0\pararsid14553496 \cbpat8 {\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 (a)\tab use and copy the RDDI DLL for the purpose }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid13793259 of connecting }{ +\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 a Target Connection Product }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid11805076 +running CMSIS-DAP compatible firmware }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 (either the Firmware or the firmware created pursuant to Clause 1.3) }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid11805076 to }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 software debug tools installed on }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid11805076 a host }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 computer running a Windows platform}{\rtlch\fcs1 \af1\afs18 +\ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid11805076 ; and}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 +\par (b)\tab subject to clause 1.5(ii), offer to sell, selling, supplying, distributing or having distributed }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\lang1024\langfe1024\noproof\insrsid14553496 \hich\af1\dbch\af37\loch\f1 (directly or +\hich\af1\dbch\af37\loch\f1 through your customers and authorised distributors) }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 the RDDI DLL in object code form only. +\par }\pard \ltrpar\qj \li0\ri0\sa200\sl276\slmult1\widctlpar +\tx426\tx916\tx1832\tx2748\tx3664\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14553496 \cbpat8 {\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid6756135 +\par }\pard \ltrpar\qj \li0\ri0\widctlpar\tx916\tx1832\tx2748\tx3664\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14553496 \cbpat8 {\rtlch\fcs1 +\af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 1.5}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15280636 CONDITIONS ON REDISTRIBUTION}{\rtlch\fcs1 +\af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 .}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15280636 }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 +\par +\par }\pard \ltrpar\qj \li0\ri0\sa200\sl276\slmult1\widctlpar\tx916\tx1832\tx2748\tx3664\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14553496 +\cbpat8 {\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\lang1024\langfe1024\noproof\insrsid14553496 \hich\af1\dbch\af37\loch\f1 (i) }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\lang1024\langfe1024\noproof\insrsid14553496\charrsid1928237 +\hich\af1\dbch\af37\loch\f1 If you distribute (directly or through your customers and authorised distributors) the products you have created pursuant \hich\af1\dbch\af37\loch\f1 to Clause 1.1}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\lang1024\langfe1024\noproof\insrsid14553496 \hich\af1\dbch\af37\loch\f1 }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\lang1024\langfe1024\noproof\insrsid14553496\charrsid1928237 \hich\af1\dbch\af37\loch\f1 (i) you agree: (a) not to use ARM +\hich\f1 \rquote \loch\f1 s name, logo or trademarks to market any or all of the }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid1928237 products created under Clause 1.1 (i); }{\rtlch\fcs1 +\af1\afs18 \ltrch\fcs0 \f1\fs18\lang1024\langfe1024\noproof\insrsid14553496\charrsid1928237 \hich\af1\dbch\af37\loch\f1 (b) }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\lang1024\langfe1024\noproof\insrsid14553496 \hich\af1\dbch\af37\loch\f1 to }{ +\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\lang1024\langfe1024\noproof\insrsid14553496\charrsid1928237 \hich\af1\dbch\af37\loch\f1 pr}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\lang1024\langfe1024\noproof\insrsid14553496 \hich\af1\dbch\af37\loch\f1 e}{ +\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\lang1024\langfe1024\noproof\insrsid14553496\charrsid1928237 \hich\af1\dbch\af37\loch\f1 serve any copyright notices included in the }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\lang1024\langfe1024\noproof\insrsid14553496 \hich\af1\dbch\af37\loch\f1 CMSIS D}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496 \hich\af1\dbch\af37\loch\f1 eliverables}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\lang1024\langfe1024\noproof\insrsid14553496\charrsid1928237 \hich\af1\dbch\af37\loch\f1 ; and (c) to ensure your customers and aut\hich\af1\dbch\af37\loch\f1 horised distributors comply with this Clause 1.}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\lang1024\langfe1024\noproof\insrsid14553496 \hich\af1\dbch\af37\loch\f1 5(i)}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\lang1024\langfe1024\noproof\insrsid14553496\charrsid1928237 .}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\lang1024\langfe1024\noproof\insrsid14553496 \hich\af1\dbch\af37\loch\f1 +\par }\pard \ltrpar\qj \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14553496 {\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\lang1024\langfe1024\noproof\insrsid14553496 \hich\af1\dbch\af37\loch\f1 +(ii) If you are authorised and choose to distribute (directly or through your customers and authorised distributors) the }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid4549827 CMSIS}{\rtlch\fcs1 +\af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 -}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid4549827 DAP }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid14559761 Specification}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 , }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\lang1024\langfe1024\noproof\insrsid14553496 \hich\af1\dbch\af37\loch\f1 Firmware, CMSIS-DAP Firmware or any modified version \hich\af1\dbch\af37\loch\f1 +thereof, or the RDDI DLL, you agree; (a) to ensure that they are licensed for use with targets containing microprocessors manufactured or simulated under licence from ARM; (b) to preserve any copyright notices which are included with the }{\rtlch\fcs1 +\af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid4549827 CMSIS}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 -}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid4549827 DAP }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid14559761 Specification}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 , CMSIS-DAP Firmware}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\lang1024\langfe1024\noproof\insrsid14553496 \hich\af1\dbch\af37\loch\f1 +, and include valid copyright notices in; (i) any modified version of the }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 CMSIS-DAP Firmware}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\lang1024\langfe1024\noproof\insrsid14553496 \hich\af1\dbch\af37\loch\f1 ; and (ii) the Firmware; (c) not to use ARM\hich\f1 \rquote \loch\f1 s name, logo or trademarks to market -any or all of the }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid4549827 CMSIS}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 -}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid4549827 DAP }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid14559761 Specification}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 , Firmware,}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\lang1024\langfe1024\noproof\insrsid14553496 \hich\af1\dbch\af37\loch\f1 CMSI\hich\af1\dbch\af37\loch\f1 +S-DAP Firmware or any modified version therof, the RDDI DLL or the Target Connection Products; and (d) to ensure your customers and authorised distributors comply with this Clause 1.5(ii). +\par }\pard \ltrpar\qj \li0\ri0\sa200\sl276\slmult1\widctlpar\tx916\tx1832\tx2748\tx3664\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14553496 +\cbpat8 {\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 +\par }\pard \ltrpar\qj \li0\ri0\sa240\widctlpar\tx916\tx1832\tx2748\tx3664\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14553496 \cbpat8 { +\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15280636 2. RESTRICTIONS ON USE OF THE}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 DELIVERABLES +}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15280636 . +\par }\pard \ltrpar\qj \li0\ri0\sa200\sl276\slmult1\widctlpar\tx916\tx1832\tx2748\tx3664\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14553496 +\cbpat8 {\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15280636 PERMITTED USERS: The }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 +Deliverables }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15280636 shall be used only by you (either a single individual, or single legal entity) your employees, or by your }{\rtlch\fcs1 +\af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 on-site }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15280636 +bona fide sub-contractors for whose acts and omissions you hereby agree to be responsible to ARM}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 for}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15280636 to the same extent as }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 you are for }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15280636 your employees, and provided always that such sub-contractors}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 :}{\rtlch\fcs1 +\af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15280636 (i) are contractually obligated to use the }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 +Deliverables }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15280636 only for your benefit}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 ;}{ +\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15280636 and (i}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 i}{\rtlch\fcs1 \af1\afs18 +\ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15280636 ) agree to assign all their work product and any rights they create therein in the supply of such work to you. +\par COPYRIGHT AND RESERVATION OF RIGHTS}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid14488502 : The }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 Deliverables}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid14488502 + are owned by ARM or its licensors and are protected by copyright and other intellectual property laws and international treaties. The }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 Deliverables}{ +\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid14488502 are licensed not sold. Except as expressly licensed herein, you acquire no right, title or interest in the }{\rtlch\fcs1 \af1\afs18 +\ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 Deliverables}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid14488502 + or any intellectual property therein. In no event shall the licences granted herein be construed as granting you, expressly or by implication, estoppels or otherwise, a licence to use any ARM technology except the }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 Deliverables}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid14488502 .}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15280636 +\par }\pard \ltrpar\qj \li0\ri0\sa240\widctlpar\tx916\tx1832\tx2748\tx3664\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14553496 \cbpat8 { +\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15280636 }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 3}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15280636 . SUPPORT. +\par ARM is not obligated to support the }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 Deliverables but}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15280636 may do so entirely at ARM's discretion. +\par }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 4}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15280636 . }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 NO }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15280636 WARRANT}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 Y.}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15280636 +\par YOU AGREE THAT THE }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 DELIVERABLES ARE}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15280636 + LICENSED "AS IS", AND THAT ARM EXPRESSLY DISCLA +IMS ALL REPRESENTATIONS, WARRANTIES, CONDITIONS OR OTHER TERMS, EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, SATISFACTORY QUALITY, AND FITNESS FOR A PARTICULAR PURPOSE.}{\rtlch\fcs1 \af1\afs18 +\ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 THE DELIVERABLES MAY CONTAIN ERRORS. }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496 +\par }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 5}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15280636 . LIMITATION OF LIABILITY. +\par THE MAXIMUM LIABILITY OF ARM TO YOU IN AGGREGATE FOR ALL CLAIMS MADE AGAINST ARM IN CONTRACT}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 ,}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15280636 TORT OR OTHERWISE UNDER OR IN CONNECTION WITH THE SUBJECT MATTER OF THIS LICENCE SHALL NOT EXCEED }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 THE GREATER OF (I) }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15280636 THE TO +TAL OF SUMS PAID BY YOU TO ARM (IF ANY) FOR THIS LICENCE}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 AND (II) US$10.00}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15280636 .}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 + THE LIMITATIONS, EXCLUSIONS AND DISCLAIMERS IN THIS LICENCE SHALL APPLY TO THE MAXIMUM EXTENT ALLOWED BY APPLICABLE LAW. +\par }\pard \ltrpar\qj \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14553496 {\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\lang1024\langfe1024\noproof\insrsid14553496 \hich\af1\dbch\af37\loch\f1 6 +}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\lang1024\langfe1024\noproof\insrsid14553496\charrsid13830602 \hich\af1\dbch\af37\loch\f1 . THIRD PARTY RIGHTS.}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496\charrsid13830602 +\par }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\lang1024\langfe1024\noproof\insrsid14553496\charrsid13830602 \hich\af1\dbch\af37\loch\f1 The Separate Files are delivered su\hich\af1\dbch\af37\loch\f1 \hich\f1 +bject to and your use is governed by their own separate licence agreements. This Licence does not apply to such Separate Files and they are not included in the term \'93}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\lang1024\langfe1024\noproof\insrsid14553496 \hich\af1\dbch\af37\loch\f1 Deliverables}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\lang1024\langfe1024\noproof\insrsid14553496\charrsid13830602 \loch\af1\dbch\af37\hich\f1 \'94\loch\f1 + under this Licence. You agree to comply with all terms and conditions impose\hich\af1\dbch\af37\loch\f1 \hich\f1 d on you in respect of such Separate Files including those identified in the Schedule (\'93\loch\f1 \hich\f1 Third Party Terms\'94\loch\f1 +). +\par \hich\af1\dbch\af37\loch\f1 ARM HEREBY DISCLAIMS ANY AND ALL WARRANTIES EXPRESS OR IMPLIED FROM ANY THIRD PARTIES REGARDING ANY SEPARATE FILES, ANY THIRD PARTY MATERIALS INC\hich\af1\dbch\af37\loch\f1 \hich\f1 +LUDED IN THE SOFTWARE, ANY THIRD PARTY MATERIALS FROM WHICH THE SOFTWARE IS DERIVED (COLLECTIVELY \'93\loch\f1 \hich\f1 OTHER CODE\'94\loch\f1 +), AND THE USE OF ANY OR ALL THE OTHER CODE IN CONNECTION WITH THE SOFTWARE, INCLUDING (WITHOUT LIMITATION) ANY WARRANTIES OF SATISFACTORY QUALIT\hich\af1\dbch\af37\loch\f1 Y\hich\af1\dbch\af37\loch\f1 OR FITNESS FOR A PARTICULAR PURPOSE. +\par \hich\af1\dbch\af37\loch\f1 NO THIRD PARTY LICENSORS OF OTHER CODE SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND WHETHER +\hich\af1\dbch\af37\loch\f1 + MADE UNDER CONTRACT, TORT OR OTHER LEGAL THEORY, ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE OTHER CODE OR THE EXERCISE OF ANY RIGHTS GRANTED UNDER EITHER OR BOTH THIS LICENCE AND THE LEGAL TERMS APPLICABLE TO ANY SEPARATE FILES, EVEN IF ADV +\hich\af1\dbch\af37\loch\f1 I\hich\af1\dbch\af37\loch\f1 SED OF THE POSSIBILITY OF SUCH DAMAGES. +\par }\pard \ltrpar\qj \li0\ri0\sa240\widctlpar\tx916\tx1832\tx2748\tx3664\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14553496 \cbpat8 { +\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 7}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15280636 . U.S. GOVERNMENT END USERS. +\par US Government Restrictions: Use, duplication, reproduction, release, modification, disclosure or transfer of this commercial product and accompanying documentation is restricted in accordance with the terms of this Licence. +\par }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 8}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15280636 . TERM AND TERMINATION. +\par }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 8.1 }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15280636 +This Licence shall remain in force until terminated }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 in accordance with the terms of Clause 8.2 or Clause 8.3 below}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15280636 . }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 +\par 8.2 }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15280636 Without prejudice to any of its other rights if you are in breach of + any of the terms and conditions of this Licence then ARM may terminate this Licence immediately upon giving written notice to you}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid7630822 +. You may terminate this Licence at any time. }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 +\par }\pard \ltrpar\qj \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14553496 {\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496\charrsid7106724 \hich\af1\dbch\af37\loch\f1 +8.3 This Licence shall immediately terminate and shall be unavailable to you i\hich\af1\dbch\af37\loch\f1 +f you or any party affiliated to you asserts any patents against ARM, ARM affiliates, third parties who have a valid licence from ARM for the Deliverables, or any customers or distributors of any of them based upon a claim that your (or your affiliate) pa +\hich\af1\dbch\af37\loch\f1 t\hich\af1\dbch\af37\loch\f1 ent is Necessary to implement the }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496 \hich\af1\dbch\af37\loch\f1 Deliverables}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\insrsid14553496\charrsid7106724 \hich\af1\dbch\af37\loch\f1 . In this Licence}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496 \hich\af1\dbch\af37\loch\f1 :}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496\charrsid7106724 +\hich\af1\dbch\af37\loch\f1 (i) "affiliate" means any entity controlling, controlled by or under common control with a party (in fact or in law, via voting securities, management control or otherwise) and "affiliated" s\hich\af1\dbch\af37\loch\f1 +hall be construed accordingly; (ii) "assert" means to allege infringement in legal or administrative proceedings, or proceedings before any other competent trade, arbitral or international authority; }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\insrsid14553496 \hich\af1\dbch\af37\loch\f1 and }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496\charrsid7106724 \hich\af1\dbch\af37\loch\f1 \hich\f1 (iii) \'93\loch\f1 \hich\f1 Necessary\'94\loch\f1 + means with respect to any claims o\hich\af1\dbch\af37\loch\f1 f any patent, those claims which, without the appropriate permission of the patent owner, will be infringed when implementing the }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496 +\hich\af1\dbch\af37\loch\f1 Deliverables }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496\charrsid7106724 \hich\af1\dbch\af37\loch\f1 because no alternative, commercially reasonable, non-infringing way of implementing the }{\rtlch\fcs1 +\af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496 \hich\af1\dbch\af37\loch\f1 Deliverables }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496\charrsid7106724 \hich\af1\dbch\af37\loch\f1 is known.}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\insrsid14553496\charrsid5900444 \hich\af1\dbch\af37\loch\f1 }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496 +\par }\pard \ltrpar\qj \li0\ri0\sa240\widctlpar\tx916\tx1832\tx2748\tx3664\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14553496 \cbpat8 { +\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 8.4 }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid7630822 Upon termination of this Licence,}{ +\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15280636 you shall stop }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15098396 +using the }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 Deliverables}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15098396 + and destroy all copies of the }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 Deliverables}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15098396 in your possession. The provisions of clauses 5, 6, 7, 8 and 9 shall survive termination of this Licence.}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15280636 +\par }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 9}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15280636 . GENERAL. +\par This Licence is governed by English Law. Except where ARM agrees otherwise in a written contract signed by you and ARM, this is the only agreement between you and ARM relating to the }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 Deliverables}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15280636 + and it may only be modified by written agreement between you and ARM. Except a +s expressly agreed in writing, this Licence may not be modified by purchase orders, advertising or other representation by any person. If any clause or sentence in this Licence is held by a court of law to be illegal or unenforceable the remaining provisi +o +ns of this Licence shall not be affected thereby. The failure by ARM to enforce any of the provisions of this Licence, unless waived in writing, shall not constitute a waiver of ARM's rights to enforce such provision or any other provision of this Licence + in the future.}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 This Licence may not be assigned without the prior written consent of ARM. +\par }\pard \ltrpar\qc \li0\ri0\sa240\widctlpar\tx916\tx1832\tx2748\tx3664\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14553496 \cbpat8 { +\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 \page SCHEDULE +\par }\pard \ltrpar\qj \li0\ri0\sa240\widctlpar\tx916\tx1832\tx2748\tx3664\tx4580\tx5496\tx6412\tx7328\tx8244\tx9160\tx10076\tx10992\tx11908\tx12824\tx13740\tx14656\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14553496 \cbpat8 { +\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 Separate Files +\par }\pard \ltrpar\qj \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14553496 {\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 The }{\rtlch\fcs1 +\af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15098396 package }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 also }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15098396 includes the components}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 contained in the following directories}{\rtlch\fcs1 +\af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15098396 :}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 +\par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\insrsid14553496 \hich\af1\dbch\af0\loch\f1 (a)\tab}}\pard \ltrpar +\qj \fi-360\li720\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\ls16\adjustright\rin0\lin720\itap0\pararsid14553496 {\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 ./}{\rtlch\fcs1 \af1\afs18 +\ltrch\fcs0 \f1\fs18\insrsid14553496\charrsid7090778 \hich\af1\dbch\af37\loch\f1 CMSIS}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496 \hich\af1\dbch\af37\loch\f1 /}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496\charrsid7090778 +\hich\af1\dbch\af37\loch\f1 DSP_Lib}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496 \hich\af1\dbch\af37\loch\f1 - }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496\charrsid15098396 +DSP Library sources and examples}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496 \hich\af1\dbch\af37\loch\f1 ; +\par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\insrsid14553496 \hich\af1\dbch\af0\loch\f1 (b)\tab}}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 ./}{\rtlch\fcs1 \af1\afs18 +\ltrch\fcs0 \f1\fs18\insrsid14553496\charrsid7090778 \hich\af1\dbch\af37\loch\f1 CMS\hich\af1\dbch\af37\loch\f1 IS}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496 \hich\af1\dbch\af37\loch\f1 /}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\insrsid14553496\charrsid7090778 \hich\af1\dbch\af37\loch\f1 Include}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496 \hich\af1\dbch\af37\loch\f1 - Header files; +\par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\insrsid14553496 \hich\af1\dbch\af0\loch\f1 (c)\tab}}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 ./}{\rtlch\fcs1 \af1\afs18 +\ltrch\fcs0 \f1\fs18\insrsid14553496\charrsid7090778 \hich\af1\dbch\af37\loch\f1 CMSIS}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496 \hich\af1\dbch\af37\loch\f1 /}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496\charrsid7090778 +\hich\af1\dbch\af37\loch\f1 Lib}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496 \hich\af1\dbch\af37\loch\f1 - }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496\charrsid7090778 \hich\af1\dbch\af37\loch\f1 +DSP Library build for various toolchains}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496 \hich\af1\dbch\af37\loch\f1 ; +\par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\insrsid14553496 \hich\af1\dbch\af0\loch\f1 (d)\tab}}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 ./}{\rtlch\fcs1 \af1\afs18 +\ltrch\fcs0 \f1\fs18\insrsid14553496\charrsid7090778 \hich\af1\dbch\af37\loch\f1 CMSIS}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496 \hich\af1\dbch\af37\loch\f1 /}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496\charrsid7090778 +\hich\af1\dbch\af37\loch\f1 RTOS}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496 \hich\af1\dbch\af37\loch\f1 - }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496\charrsid7090778 \hich\af1\dbch\af37\loch\f1 +Header file template for CMSIS-RTOS implementation}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496 \hich\af1\dbch\af37\loch\f1 ; and +\par {\listtext\pard\plain\ltrpar \rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\insrsid14553496 \hich\af1\dbch\af0\loch\f1 (e)\tab}}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf1\lang2057\langfe2057\langfenp2057\insrsid14553496 .}{\rtlch\fcs1 \af1\afs18 +\ltrch\fcs0 \f1\fs18\insrsid14553496 \hich\af1\dbch\af37\loch\f1 /Device - T}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496\charrsid14488502 \hich\af1\dbch\af37\loch\f1 emplate files and implementations for Cortex-M class processors}{ +\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496 \hich\af1\dbch\af37\loch\f1 . +\par }\pard \ltrpar\qj \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14553496 {\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496 +\par \hich\af1\dbch\af37\loch\f1 All of the above com\hich\af1\dbch\af37\loch\f1 ponents (a\hich\f1 \endash \loch\f1 e) are licensed to you under the terms of the BSD licence, which is incorporated within or alongside the above components. +\par }\pard \ltrpar\qj \li284\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin284\itap0\pararsid14553496 {\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496 \hich\af1\dbch\af37\loch\f1 }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 +\f1\fs18\insrsid14553496\charrsid13975144 \hich\af1\dbch\af37\loch\f1 (f)}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496 \hich\af1\dbch\af37\loch\f1 }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496\charrsid13975144 +\hich\af1\dbch\af37\loch\f1 ./CMSIS/Driver \hich\f1 \endash \loch\f1 CMSIS-Driver header files}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496 +\par }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496\charrsid13975144 \hich\af1\dbch\af37\loch\f1 (g)}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496 \hich\af1\dbch\af37\loch\f1 }{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid14553496 +\hich\af37\dbch\af37\loch\f37 }{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496 \hich\af1\dbch\af37\loch\f1 ./CMSIS/Pack \hich\f1 \endash \loch\f1 Example Device Family Pack}{\rtlch\fcs1 \af0 \ltrch\fcs0 \insrsid14553496\charrsid13975144 + +\par }\pard\plain \ltrpar\s32\ql \li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14553496 \rtlch\fcs1 \af0\afs21\alang1025 \ltrch\fcs0 \f39\fs21\lang2057\langfe1033\cgrid\langnp2057\langfenp1033 {\rtlch\fcs1 +\af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496 +\par The above components (f \endash g) are licensed to you under the terms of the zlib licence, which is incorporated within or alongside the above components. +\par +\par +\par }\pard\plain \ltrpar\qj \li0\ri0\sa200\sl276\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid14553496 \rtlch\fcs1 \af0\afs22\alang1025 \ltrch\fcs0 +\fs22\lang2057\langfe1033\loch\af37\hich\af37\dbch\af37\cgrid\langnp2057\langfenp1033 {\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496\charrsid2958685 \hich\af1\dbch\af37\loch\f1 ARM contract reference LEC-PRE-00489}{\rtlch\fcs1 \af1\afs18 +\ltrch\fcs0 \f1\fs18\insrsid14553496 \hich\af1\dbch\af37\loch\f1 - v4.0}{\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\insrsid14553496\charrsid2958685 +\par }{\*\themedata 504b030414000600080000002100e9de0fbfff0000001c020000130000005b436f6e74656e745f54797065735d2e786d6cac91cb4ec3301045f748fc83e52d4a +9cb2400825e982c78ec7a27cc0c8992416c9d8b2a755fbf74cd25442a820166c2cd933f79e3be372bd1f07b5c3989ca74aaff2422b24eb1b475da5df374fd9ad +5689811a183c61a50f98f4babebc2837878049899a52a57be670674cb23d8e90721f90a4d2fa3802cb35762680fd800ecd7551dc18eb899138e3c943d7e503b6 +b01d583deee5f99824e290b4ba3f364eac4a430883b3c092d4eca8f946c916422ecab927f52ea42b89a1cd59c254f919b0e85e6535d135a8de20f20b8c12c3b0 +0c895fcf6720192de6bf3b9e89ecdbd6596cbcdd8eb28e7c365ecc4ec1ff1460f53fe813d3cc7f5b7f020000ffff0300504b030414000600080000002100a5d6 +a7e7c0000000360100000b0000005f72656c732f2e72656c73848fcf6ac3300c87ef85bd83d17d51d2c31825762fa590432fa37d00e1287f68221bdb1bebdb4f +c7060abb0884a4eff7a93dfeae8bf9e194e720169aaa06c3e2433fcb68e1763dbf7f82c985a4a725085b787086a37bdbb55fbc50d1a33ccd311ba548b6309512 +0f88d94fbc52ae4264d1c910d24a45db3462247fa791715fd71f989e19e0364cd3f51652d73760ae8fa8c9ffb3c330cc9e4fc17faf2ce545046e37944c69e462 +a1a82fe353bd90a865aad41ed0b5b8f9d6fd010000ffff0300504b0304140006000800000021006b799616830000008a0000001c0000007468656d652f746865 +6d652f7468656d654d616e616765722e786d6c0ccc4d0ac3201040e17da17790d93763bb284562b2cbaebbf600439c1a41c7a0d29fdbd7e5e38337cedf14d59b +4b0d592c9c070d8a65cd2e88b7f07c2ca71ba8da481cc52c6ce1c715e6e97818c9b48d13df49c873517d23d59085adb5dd20d6b52bd521ef2cdd5eb9246a3d8b +4757e8d3f729e245eb2b260a0238fd010000ffff0300504b03041400060008000000210030dd4329a8060000a41b0000160000007468656d652f7468656d652f +7468656d65312e786d6cec594f6fdb3614bf0fd87720746f6327761a07758ad8b19b2d4d1bc46e871e698996d850a240d2497d1bdae38001c3ba618715d86d87 +615b8116d8a5fb34d93a6c1dd0afb0475292c5585e9236d88aad3e2412f9e3fbff1e1fa9abd7eec70c1d1221294fda5efd72cd4324f1794093b0eddd1ef62fad +79482a9c0498f184b4bd2991deb58df7dfbb8ad755446282607d22d771db8b944ad79796a40fc3585ee62949606ecc458c15bc8a702910f808e8c66c69b9565b +5d8a314d3c94e018c8de1a8fa94fd05093f43672e23d06af89927ac06762a049136785c10607758d9053d965021d62d6f6804fc08f86e4bef210c352c144dbab +999fb7b4717509af678b985ab0b6b4ae6f7ed9ba6c4170b06c788a705430adf71bad2b5b057d03606a1ed7ebf5babd7a41cf00b0ef83a6569632cd467faddec9 +699640f6719e76b7d6ac355c7c89feca9cccad4ea7d36c65b258a206641f1b73f8b5da6a6373d9c11b90c537e7f08dce66b7bbeae00dc8e257e7f0fd2badd586 +8b37a088d1e4600ead1ddaef67d40bc898b3ed4af81ac0d76a197c86826828a24bb318f3442d8ab518dfe3a20f000d6458d104a9694ac6d88728eee2782428d6 +0cf03ac1a5193be4cbb921cd0b495fd054b5bd0f530c1931a3f7eaf9f7af9e3f45c70f9e1d3ff8e9f8e1c3e3073f5a42ceaa6d9c84e5552fbffdeccfc71fa33f +9e7ef3f2d117d57859c6fffac327bffcfc793510d26726ce8b2f9ffcf6ecc98baf3efdfdbb4715f04d814765f890c644a29be408edf3181433567125272371be +15c308d3f28acd249438c19a4b05fd9e8a1cf4cd296699771c393ac4b5e01d01e5a30a787d72cf1178108989a2159c77a2d801ee72ce3a5c545a6147f32a9979 +3849c26ae66252c6ed637c58c5bb8b13c7bfbd490a75330f4b47f16e441c31f7184e140e494214d273fc80900aedee52ead87597fa824b3e56e82e451d4c2b4d +32a423279a668bb6690c7e9956e90cfe766cb37b077538abd27a8b1cba48c80acc2a841f12e698f13a9e281c57911ce298950d7e03aba84ac8c154f8655c4f2a +f074481847bd804859b5e696007d4b4edfc150b12addbecba6b18b148a1e54d1bc81392f23b7f84137c2715a851dd0242a633f900710a218ed715505dfe56e86 +e877f0034e16bafb0e258ebb4faf06b769e888340b103d331115bebc4eb813bf83291b63624a0d1475a756c734f9bbc2cd28546ecbe1e20a3794ca175f3fae90 +fb6d2dd99bb07b55e5ccf68942bd0877b23c77b908e8db5f9db7f024d9239010f35bd4bbe2fcae387bfff9e2bc289f2fbe24cfaa301468dd8bd846dbb4ddf1c2 +ae7b4c191ba8292337a469bc25ec3d411f06f53a73e224c5292c8de0516732307070a1c0660d125c7d44553488700a4d7bddd3444299910e254ab984c3a219ae +a4adf1d0f82b7bd46cea4388ad1c12ab5d1ed8e1153d9c9f350a3246aad01c6873462b9ac05999ad5cc988826eafc3acae853a33b7ba11cd1445875ba1b236b1 +399483c90bd560b0b0263435085a21b0f22a9cf9356b38ec6046026d77eba3dc2dc60b17e92219e180643ed27acffba86e9c94c7ca9c225a0f1b0cfae0788ad5 +4adc5a9aec1b703b8b93caec1a0bd8e5de7b132fe5113cf312503b998e2c2927274bd051db6b35979b1ef271daf6c6704e86c73805af4bdd476216c26593af84 +0dfb5393d964f9cc9bad5c313709ea70f561ed3ea7b053075221d51696910d0d339585004b34272bff7213cc7a510a5454a3b349b1b206c1f0af490176745d4b +c663e2abb2b34b23da76f6352ba57ca2881844c1111ab189d8c7e07e1daaa04f40255c77988aa05fe06e4e5bdb4cb9c5394bbaf28d98c1d971ccd20867e556a7 +689ec9166e0a522183792b8907ba55ca6e943bbf2a26e52f48957218ffcf54d1fb09dc3eac04da033e5c0d0b8c74a6b43d2e54c4a10aa511f5fb021a07533b20 +5ae07e17a621a8e082dafc17e450ffb739676998b48643a4daa7211214f623150942f6a02c99e83b85583ddbbb2c4996113211551257a656ec1139246ca86be0 +aadedb3d1441a89b6a929501833b197fee7b9641a3503739e57c732a59b1f7da1cf8a73b1f9bcca0945b874d4393dbbf10b1680f66bbaa5d6f96e77b6f59113d +316bb31a795600b3d256d0cad2fe354538e7566b2bd69cc6cbcd5c38f0e2bcc63058344429dc2121fd07f63f2a7c66bf76e80d75c8f7a1b622f878a18941d840 +545fb28d07d205d20e8ea071b283369834296bdaac75d256cb37eb0bee740bbe278cad253b8bbfcf69eca23973d939b97891c6ce2cecd8da8e2d343578f6648a +c2d0383fc818c798cf64e52f597c740f1cbd05df0c264c49134cf09d4a60e8a107260f20f92d47b374e32f000000ffff0300504b030414000600080000002100 +0dd1909fb60000001b010000270000007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73848f4d0ac2301484f7 +8277086f6fd3ba109126dd88d0add40384e4350d363f2451eced0dae2c082e8761be9969bb979dc9136332de3168aa1a083ae995719ac16db8ec8e4052164e89 +d93b64b060828e6f37ed1567914b284d262452282e3198720e274a939cd08a54f980ae38a38f56e422a3a641c8bbd048f7757da0f19b017cc524bd62107bd500 +1996509affb3fd381a89672f1f165dfe514173d9850528a2c6cce0239baa4c04ca5bbabac4df000000ffff0300504b01022d0014000600080000002100e9de0f +bfff0000001c0200001300000000000000000000000000000000005b436f6e74656e745f54797065735d2e786d6c504b01022d0014000600080000002100a5d6 +a7e7c0000000360100000b00000000000000000000000000300100005f72656c732f2e72656c73504b01022d00140006000800000021006b799616830000008a +0000001c00000000000000000000000000190200007468656d652f7468656d652f7468656d654d616e616765722e786d6c504b01022d00140006000800000021 +0030dd4329a8060000a41b00001600000000000000000000000000d60200007468656d652f7468656d652f7468656d65312e786d6c504b01022d001400060008 +00000021000dd1909fb60000001b0100002700000000000000000000000000b20900007468656d652f7468656d652f5f72656c732f7468656d654d616e616765722e786d6c2e72656c73504b050600000000050005005d010000ad0a00000000} +{\*\colorschememapping 3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d22796573223f3e0d0a3c613a636c724d +617020786d6c6e733a613d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f64726177696e676d6c2f323030362f6d6169 +6e22206267313d226c743122207478313d22646b3122206267323d226c743222207478323d22646b322220616363656e74313d22616363656e74312220616363 +656e74323d22616363656e74322220616363656e74333d22616363656e74332220616363656e74343d22616363656e74342220616363656e74353d22616363656e74352220616363656e74363d22616363656e74362220686c696e6b3d22686c696e6b2220666f6c486c696e6b3d22666f6c486c696e6b222f3e} +{\*\latentstyles\lsdstimax267\lsdlockeddef0\lsdsemihiddendef1\lsdunhideuseddef1\lsdqformatdef0\lsdprioritydef99{\lsdlockedexcept \lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority0 \lsdlocked0 Normal; +\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority9 \lsdlocked0 heading 1;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 2;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 3;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 4; +\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 5;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 6;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 7;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 8;\lsdqformat1 \lsdpriority9 \lsdlocked0 heading 9; +\lsdpriority39 \lsdlocked0 toc 1;\lsdpriority39 \lsdlocked0 toc 2;\lsdpriority39 \lsdlocked0 toc 3;\lsdpriority39 \lsdlocked0 toc 4;\lsdpriority39 \lsdlocked0 toc 5;\lsdpriority39 \lsdlocked0 toc 6;\lsdpriority39 \lsdlocked0 toc 7; +\lsdpriority39 \lsdlocked0 toc 8;\lsdpriority39 \lsdlocked0 toc 9;\lsdpriority0 \lsdlocked0 footer;\lsdqformat1 \lsdpriority35 \lsdlocked0 caption;\lsdpriority0 \lsdlocked0 page number; +\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority10 \lsdlocked0 Title;\lsdpriority1 \lsdlocked0 Default Paragraph Font;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority11 \lsdlocked0 Subtitle; +\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority22 \lsdlocked0 Strong;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority20 \lsdlocked0 Emphasis;\lsdsemihidden0 \lsdunhideused0 \lsdpriority59 \lsdlocked0 Table Grid; +\lsdunhideused0 \lsdlocked0 Placeholder Text;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority1 \lsdlocked0 No Spacing;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 1; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 1; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 1;\lsdunhideused0 \lsdlocked0 Revision;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority34 \lsdlocked0 List Paragraph; +\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority29 \lsdlocked0 Quote;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority30 \lsdlocked0 Intense Quote;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 1; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 1; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 1; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 1;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 2; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 2; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 2; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 2; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 2;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 2; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 3; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 3; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 3; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 3; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 3;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 4; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 4; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 4; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 4; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 4; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 4;\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 5; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 5; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 5; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 5; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 5;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 5; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority60 \lsdlocked0 Light Shading Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority61 \lsdlocked0 Light List Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority62 \lsdlocked0 Light Grid Accent 6; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority63 \lsdlocked0 Medium Shading 1 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority64 \lsdlocked0 Medium Shading 2 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority65 \lsdlocked0 Medium List 1 Accent 6; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority66 \lsdlocked0 Medium List 2 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority67 \lsdlocked0 Medium Grid 1 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority68 \lsdlocked0 Medium Grid 2 Accent 6; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority69 \lsdlocked0 Medium Grid 3 Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority70 \lsdlocked0 Dark List Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority71 \lsdlocked0 Colorful Shading Accent 6; +\lsdsemihidden0 \lsdunhideused0 \lsdpriority72 \lsdlocked0 Colorful List Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdpriority73 \lsdlocked0 Colorful Grid Accent 6;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority19 \lsdlocked0 Subtle Emphasis; +\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority21 \lsdlocked0 Intense Emphasis;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority31 \lsdlocked0 Subtle Reference; +\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority32 \lsdlocked0 Intense Reference;\lsdsemihidden0 \lsdunhideused0 \lsdqformat1 \lsdpriority33 \lsdlocked0 Book Title;\lsdpriority37 \lsdlocked0 Bibliography; +\lsdqformat1 \lsdpriority39 \lsdlocked0 TOC Heading;}}{\*\datastore 0105000002000000180000004d73786d6c322e534158584d4c5265616465722e362e3000000000000000000000600000 +d0cf11e0a1b11ae1000000000000000000000000000000003e000300feff0900060000000000000000000000010000000100000000000000001000000200000001000000feffffff0000000000000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +fffffffffffffffffdffffff0a000000feffffff0400000005000000060000000700000008000000090000000b0000000d0000000c0000000e000000110000000f00000010000000120000002c0000002d0000001400000015000000160000001700000018000000190000001a0000001b0000001c0000001d0000001e00 +00001f000000200000002100000022000000230000002400000025000000260000002700000028000000290000002a0000002b000000fefffffffeffffff2e000000feffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffff52006f006f007400200045006e00740072007900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000500ffffffffffffffff010000000c6ad98892f1d411a65f0040963251e5000000000000000000000000a07a +5e7487e0d00103000000c01d0000000000004d0073006f004400610074006100530074006f0072006500000000000000000000000000000000000000000000000000000000000000000000000000000000001a000101ffffffffffffffff05000000000000000000000000000000000000000000000090535e7487e0d001 +a07a5e7487e0d0010000000000000000000000004400d200c90032004f00510032003400d8004500c2005900de004d00cf004f00d300c200c100c0004b0041003d003d000000000000000000000000000000000032000101ffffffffffffffff03000000000000000000000000000000000000000000000090535e7487e0 +d001a07a5e7487e0d0010000000000000000000000004900740065006d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000201ffffffff04000000ffffffff000000000000000000000000000000000000000000000000 +000000000000000000000000000000000a0c0000000000000100000002000000030000000400000005000000060000000700000008000000090000000a0000000b0000000c0000000d0000000e0000000f000000100000001100000012000000130000001400000015000000160000001700000018000000190000001a00 +00001b0000001c0000001d0000001e0000001f000000200000002100000022000000230000002400000025000000260000002700000028000000290000002a0000002b0000002c0000002d0000002e0000002f00000030000000feffffff3200000033000000340000003500000036000000feffffff3800000039000000 +3a000000feffffff3c0000003d0000003e0000003f00000040000000feffffff42000000430000004400000045000000460000004700000048000000490000004a0000004b0000004c0000004d0000004e0000004f00000050000000510000005200000053000000feffffff550000005600000057000000580000005900 +00005a0000005b000000feffffff5d0000005e0000005f000000feffffff6100000062000000630000006400000065000000feffffff6700000068000000690000006a0000006b0000006c0000006d0000006e0000006f00000070000000710000007200000073000000740000007500000076000000feffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d227574662d38223f3e3c4c6f6e6750726f7065727469657320786d6c6e733d22687474703a2f2f736368656d61732e6d6963726f736f66742e636f6d2f6f666669 +63652f323030362f6d657461646174612f6c6f6e6750726f70657274696573223e3c4c6f6e6750726f7020786d6c6e733d2222206e616d653d2250726f70657274795f78303032305f426167223e3c215b43444154415b7674695f636f6e74656e7476657273696f6e697364697274793a42577c66616c73650d0a767469 +5f70617273657276657273696f6e3a53527c31342e302e302e363032390d0a4558543a53577c646f630d0a4f726465723a49577c3637323330300d0a7674695f636f6e74656e747461673a53577c7b37414136373534302d343634322d343445372d384342352d3131433437434443314233457d2c3133372c35310d0a5f +43617465676f72793a53577c0d0a524553504f4e53455f53454e4445525f4e414d453a53577c6741414164796137364239396434684c4755523172512b385478547630474745506469780d0a7674695f617574686f723a53527c454d45415c5c656d6964726530310d0a4e6f746573506172743a53577c4c45432d505245 +2d30303438392e646f630d0a53696465204c6574746572733a49577c300d0a7674695f63617465676f726965733a56577c0d0a48696464656e55706c6f61643a53577c0d0a50726f7065727479204261673a53577c7674695f636f6e74656e7476657273696f6e697364697274793a42577c66616c73655c725c6e767469 +5f70617273657276657273696f6e3a53527c31342e302e302e363032395c725c6e4558543a53577c646f635c725c6e4f726465723a49577c3637323330305c725c6e7674695f636f6e74656e747461673a53577c7b45443045303635312d303831342d344533382d423741412d3834373844334342463538467d2c313233 +2c34385c725c6e5f43617465676f72793a53577c5c725c6e524553504f4e53455f53454e4445525f4e414d453a53577c6741414164796137364239396434684c4755523172512b385478547630474745506469785c725c6e7674695f617574686f723a53527c0d0a5469746c653a53577c4c45432d5052452d3030343839 +207e2045554c4120666f7220434d5349532044656c6976657261626c65730d0a7674695f6d6f64696669656462793a53527c454d45415c5c656d6964726530310d0a7674695f61737369676e6564746f3a53527c0d0a4b6579776f7264733a53577c0d0a436f6d7075746564436f6d70616e793a53577c41524d2f0d0a43 +6f6d70757465644c523a53577c41502f0d0a437265617465643a53577c323031342d30322d31395431333a32363a34385a0d0a436f6e74656e745479706549643a53577c307830313031303030394135453436413142414235363438423443423131314343384143453237440d0a5f417574686f723a53577c0d0a436865 +636b20496e20436f6d6d656e743a53577c4d616a6f722056657273696f6e205075626c6973680d0a4e616d653a53577c4c45432d5052452d30303438390d0a5f436f6d6d656e74733a53577c0d0a436f6d6d656e74733a53577c0d0a446f634e756d6265723a53577c4c45432d5052452d30303438390d0a446f6d696e6f +20417574686f723a53577c0d0a4d41494c5f4d53475f4944323a53577c6335437874476e46534a724e5069464153377542612f4d64344d2f474b624c477a4c6e755455566c4c5568595047624d52684f6135524734766e375c725c6e527664486b6a54306a2b4b4277557958304a3054696a664165524d2f63392b336b57 +79676d513d3d0d0a7674695f73796e6375706461746568696464656e76657273696f6e3a49577c3133330d0a5375626a6563743a53577c0d0a646973706c61795f75726e5c3a736368656d61732d6d6963726f736f66742d636f6d5c3a6f66666963655c3a6f666669636523456469746f723a53577c456d696c79204472 +65610d0a437265617465642042793a53577c36323b23456d696c7920447265612c23454d45415c5c656d6964726530312c23456d696c792e447265614061726d2e636f6d2c232c23456d696c7920447265610d0a7674695f666f6c6465726974656d636f756e743a49527c300d0a4d41494c5f4d53475f4944313a53577c +41424141564f41666f5372516f7977567a2b6e3839526b483876636b4a683268583958314c65494a524c58706b682b5843744a6d7a4e52664964766344647443432b43570d0a4d6f6469666965643a53577c323031342d30362d30315432323a30303a35375a0d0a436f6d70757465644e756d6265723a53577c4c45432d +5052452d30303438392d56362e300d0a4d6f6469666965642042793a53577c36323b23456d696c7920447265612c23454d45415c5c656d6964726530312c23456d696c792e447265614061726d2e636f6d2c232c23456d696c7920447265610d0a7674695f617070726f76616c6c6576656c3a53527c0d0a446976697369 +6f6e3a53577c445347202870726576696f75736c79206b6e6f776e20617320534444290d0a48696464656e44656c6574653a53577c0d0a4e6f746573554e49443a53577c32383939374630443531443738304644383032353736433630303736363041310d0a7674695f666f6c646572737562666f6c6465726974656d63 +6f756e743a49527c300d0a5f5374617475733a53577c0d0a646973706c61795f75726e5c3a736368656d61732d6d6963726f736f66742d636f6d5c3a6f66666963655c3a6f666669636523417574686f723a53577c456d696c7920447265610d0a446f63547970653a53577c507265636564656e740d0a446f6d696e6f20 +56657273696f6e3a53577c0d0a454d41494c5f4f574e45525f414444524553533a53577c7341414155597479416b654e575234632f6879763833646a446467542f2f536c6652666a3079756c304e796d7535383d0d0a7674695f636163686564637573746f6d70726f70733a56587c5375626a65637420646973706c6179 +5f75726e3a736368656d61732d6d6963726f736f66742d636f6d3a6f66666963653a6f666669636523456469746f7220455854204d41494c5f4d53475f494431204f72646572205f43617465676f727920524553504f4e53455f53454e4445525f4e414d45204d6f64696669656420436f6d70757465644e756d62657220 +4e6f7465735061727420536964655c5c204c657474657273207674695f617070726f76616c6c6576656c207674695f63617465676f72696573204469766973696f6e2048696464656e44656c6574652048696464656e55706c6f6164204e6f746573554e49442050726f70657274795c5c20426167207674695f61737369 +676e6564746f204b6579776f726473205f53746174757320436f6d7075746564436f6d70616e7920436f6d70757465644c52204372656174656420646973706c61795f75726e3a736368656d61732d6d6963726f736f66742d636f6d3a6f66666963653a6f666669636523417574686f7220446f635479706520446f6d69 +6e6f5c5c2056657273696f6e20454d41494c5f4f574e45525f41444452455353207674695f7469746c65205f417574686f7220436865636b5c5c20496e5c5c20436f6d6d656e742046696c654c656166526566204e6f74657354696d655374616d70205f436f6d6d656e7473204e616d6520436f6d6d656e747320446f63 +4e756d62657220446f6d696e6f5c5c20417574686f72204d41494c5f4d53475f4944320d0a7674695f646f6373746f726576657273696f6e3a49527c3133370d0a7674695f6d657461696e666f76657273696f6e3a49577c3139350d0a7674695f636f6e74656e746368616e6765756e69743a53577c0d0a7674695f6361 +636865647469746c653a53527c4c45432d5052452d3030343839207e2045554c4120666f7220434d5349532044656c6976657261626c65730d0a7674695f7469746c653a53527c4c45432d5052452d3030343839207e2045554c4120666f7220434d5349532044656c6976657261626c65730d0a46696c654c6561665265 +663a53577c4c45432d5052452d30303438390d0a4e6f74657354696d655374616d703a53577c30332f31322f323031302032323a34303a33360d0a5d5d3e3c2f4c6f6e6750726f703e3c2f4c6f6e6750726f706572746965733e000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000003c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d226e6f223f3e0d0a3c64733a6461746173746f72654974656d2064733a6974656d49443d227b33393543324130462d314530372d343845302d393846 +382d4342434543453238363032387d2220786d6c6e733a64733d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f6f6666696365446f63756d656e742f323030362f637573746f6d586d6c223e3c64733a736368656d61526566733e3c64733a736368656d615265662064733a7572 +693d22687474703a2f2f736368656d61732e6d6963726f736f66742e636f6d2f6f66666963652f323030362f6d657461646174612f6c6f6e6750726f70657274696573222f3e3c64733a736368656d615265662064733a7572693d22222f3e3c2f64733a736368656d61526566733e3c2f64733a6461746173746f726549 +74656d3e00000000000000000000000000000000000000003c3f6d736f2d636f6e74656e74547970653f3e3c637573746f6d58736e20786d6c6e733d22687474703a2f2f736368656d61732e6d6963726f736f66742e636f500072006f007000650072007400690065007300000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000016000200ffffffffffffffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000310000006c01000000000000c000d300c4004100c600d300da00da00c60055003400df00c5004100da00d100d000d300 +48005600d700d0003d003d000000000000000000000000000000000032000101020000000b000000060000000000000000000000000000000000000000000000a07a5e7487e0d001a07a5e7487e0d0010000000000000000000000004900740065006d000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000a000201ffffffff07000000ffffffff00000000000000000000000000000000000000000000000000000000000000000000000037000000d700000000000000500072006f007000650072007400690065007300000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000016000200ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000000000003b0000004e010000000000006d2f6f66666963652f323030362f6d657461646174612f637573746f6d58 +736e223e3c78736e4c6f636174696f6e3e3c2f78736e4c6f636174696f6e3e3c6361636865643e547275653c2f6361636865643e3c6f70656e427944656661756c743e46616c73653c2f6f70656e427944656661756c743e3c78736e53636f70653e3c2f78736e53636f70653e3c2f637573746f6d58736e3e0000000000 +0000000000000000000000000000000000000000000000000000000000000000000000003c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d226e6f223f3e0d0a3c64733a6461746173746f72654974656d2064733a6974656d49443d227b39423030 +333938332d424133452d343739392d424639342d3045423143333331443544467d2220786d6c6e733a64733d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f6f6666696365446f63756d656e742f323030362f637573746f6d586d6c223e3c64733a736368656d61526566733e3c +64733a736368656d615265662064733a7572693d22687474703a2f2f736368656d61732e6d6963726f736f66742e636f6d2f6f66666963652f323030362f6d657461646174612f637573746f6d58736e222f3e3c2f64733a736368656d61526566733e3c2f64733a6461746173746f72654974656d3e0000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000003c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d227574662d38223f3e3c703a70726f7065727469657320786d6c6e733a703d22687474703a2f2f736368656d61732e6d6963726f736f66 +742e636f6d2f6f66666963652f323030362f6d657461646174612f70726f706572746965732220786d6c6e733a7873693d22687474703a2f2f7777772e77332e6f72672f323030312f584d4c536368656d612d696e7374616e63652220786d6c6e733a70633d22687474703a2f2f736368656d61732e6d6963726f736f66 +742e636f6d2f6f66666963652f696e666f706174682f323030372f506172746e6572436f6e74726f6c73223e3c646f63756d656e744d616e6167656d656e743e3c446f634e756d62657220786d6c6e733d2232656334313736362d353237652d346338342d623438342d646633663235393966643061223e4c45432d5052 +452d30303438393c2f446f634e756d6265723e3c446f6d696e6f5f78303032305f56657273696f6e20786d6c6e733d2232656334313736362d353237652d346338342d623438342d64663366323539396664306122207873693a6e696c3d2274727565222f3e3c4e6f74657354696d65c000dc00d800c1004300c500c700 +c400d100c40053003200df004e004e005100d200ca004500cc00560051003d003d000000000000000000000000000000000032000100ffffffffffffffff090000000000000000000000000000000000000000000000a07a5e7487e0d001a07a5e7487e0d0010000000000000000000000004900740065006d0000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000201ffffffff0a000000ffffffff00000000000000000000000000000000000000000000000000000000000000000000000041000000b304000000000000500072006f0070006500 +72007400690065007300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000200ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000000000000000054000000e601000000000000cb004600ce003200 +49004200d3005900ca005500ca0030003000d000c00054003400d200c100db00dd00d0003d003d000000000000000000000000000000000032000101080000000e0000000c0000000000000000000000000000000000000000000000a07a5e7487e0d001a07a5e7487e0d0010000000000000000000000005374616d7020 +786d6c6e733d2232656334313736362d353237652d346338342d623438342d64663366323539396664306122207873693a6e696c3d2274727565222f3e3c4e6f7465735061727420786d6c6e733d2232656334313736362d353237652d346338342d623438342d646633663235393966643061223e4c45432d5052452d30 +303438392e646f633c2f4e6f746573506172743e3c45585420786d6c6e733d2232656334313736362d353237652d346338342d623438342d646633663235393966643061223e646f633c2f4558543e3c4469766973696f6e20786d6c6e733d2232656334313736362d353237652d346338342d623438342d646633663235 +393966643061223e445347202870726576696f75736c79206b6e6f776e20617320534444293c2f4469766973696f6e3e3c536964655f78303032305f4c65747465727320786d6c6e733d2232656334313736362d353237652d346338342d623438342d646633663235393966643061223e303c2f536964655f7830303230 +5f4c6574746572733e3c436f6d6d656e747320786d6c6e733d2232656334313736362d353237652d346338342d623438342d64663366323539396664306122207873693a6e696c3d2274727565222f3e3c4e6f746573554e494420786d6c6e733d2232656334313736362d353237652d346338342d623438342d64663366 +3235393966643061223e32383939374630443531443738304644383032353736433630303736363041313c2f4e6f746573554e49443e3c446f6d696e6f5f78303032305f417574686f7220786d6c6e733d2232656334313736362d353237652d346338342d623438342d64663366323539396664306122207873693a6e69 +6c3d2274727565222f3e3c446f635479706520786d6c6e733d2232656334313736362d353237652d346338342d623438342d646633663235393966643061223e507265636564656e743c2f446f63547970653e3c2f646f63756d656e744d616e6167656d656e743e3c2f703a70726f706572746965733e00000000000000 +0000000000003c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d226e6f223f3e0d0a3c64733a6461746173746f72654974656d2064733a6974656d49443d227b30413231434538332d453435392d343443362d394346432d44333530434141313243 +35357d2220786d6c6e733a64733d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f6f6666696365446f63756d656e742f323030362f637573746f6d586d6c223e3c64733a736368656d61526566733e3c64733a736368656d615265662064733a7572693d22687474703a2f2f7363 +68656d61732e6d6963726f736f66742e636f6d2f6f66666963652f323030362f6d657461646174612f70726f70657274696573222f3e3c64733a736368656d615265662064733a7572693d22687474703a2f2f736368656d61732e6d6963726f736f66742e636f6d2f6f66666963652f696e666f706174682f323030372f +506172746e6572436f6e74726f6c73222f3e3c64733a736368656d615265662064733a7572693d2232656334313736362d353237652d346338342d623438342d646633663235393966643061222f3e3c2f64733a736368656d61526566733e3c2f64733a6461746173746f72654974656d3e000000000000000000000000 +00000000000000000000000000003c3f6d736f2d636f6e74656e74547970653f3e3c466f726d54656d706c6174657320786d6c6e733d22687474703a2f2f736368656d61732e6d6963726f736f66742e636f6d2f7368617265706f696e742f76332f636f6e74656e74747970652f666f726d73223e3c446973706c61793e +446f63756d656e744c696272617279466f726d3c2f446973706c61793e3c456469743e446f63756d656e744c696272617279466f726d3c2f456469743e3c4e65773e446f63756d656e744c696272617279466f726d3c2f4e65773e3c2f466f726d54656d706c617465733e00000000000000000000000000000000000000 +0000000000000000000000000000000000004900740065006d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000201ffffffff0d000000ffffffff00000000000000000000000000000000000000000000000000000000 +00000000000000005c000000db00000000000000500072006f007000650072007400690065007300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000200ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000 +00000000000000000000600000004f01000000000000dd00df0050004500ce003200cf004d00d600d4004300df00c800c9004300cb003300dd00c6004f00cd00c0003d003d000000000000000000000000000000000032000100ffffffffffffffff0f0000000000000000000000000000000000000000000000a07a5e74 +87e0d001a07a5e7487e0d0010000000000000000000000004900740065006d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000201ffffffff10000000ffffffff00000000000000000000000000000000000000000000 +00000000000000000000000000001300000016310000000000003c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d226e6f223f3e0d0a3c64733a6461746173746f72654974656d2064733a6974656d49443d227b32303943354241432d443831432d +344141392d394136422d3038313337423238374246377d2220786d6c6e733a64733d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f6f6666696365446f63756d656e742f323030362f637573746f6d586d6c223e3c64733a736368656d61526566733e3c64733a736368656d6152 +65662064733a7572693d22687474703a2f2f736368656d61732e6d6963726f736f66742e636f6d2f7368617265706f696e742f76332f636f6e74656e74747970652f666f726d73222f3e3c2f64733a736368656d61526566733e3c2f64733a6461746173746f72654974656d3e0000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000003c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d225554462d3822207374616e64616c6f6e653d226e6f223f3e0d0a3c64733a6461746173746f72654974656d2064733a6974656d49443d227b4239433446334637 +2d434343422d343044422d424641322d3930414237374439384542367d2220786d6c3c3f786d6c2076657273696f6e3d22312e302220656e636f64696e673d227574662d38223f3e3c63743a636f6e74656e7454797065536368656d612063743a5f3d2222206d613a5f3d2222206d613a636f6e74656e74547970654e61 +6d653d22446f63756d656e7422206d613a636f6e74656e745479706549443d223078303130313030303941354534364131424142353634384234434231313143433841434532374422206d613a636f6e74656e745479706556657273696f6e3d22343122206d613a636f6e74656e74547970654465736372697074696f6e +3d224372656174652061206e657720646f63756d656e742e22206d613a636f6e74656e745479706553636f70653d2222206d613a76657273696f6e49443d2239626433656238363438633235356336303133626362616536616239636236612220786d6c6e733a63743d22687474703a2f2f736368656d61732e6d696372 +6f736f66742e636f6d2f6f66666963652f323030362f6d657461646174612f636f6e74656e74547970652220786d6c6e733a6d613d22687474703a2f2f736368656d61732e6d6963726f736f66742e636f6d2f6f66666963652f323030362f6d657461646174612f70726f706572746965732f6d65746141747472696275 +746573223e0d0a3c7873643a736368656d61207461726765744e616d6573706163653d22687474703a2f2f736368656d61732e6d6963726f736f66742e636f6d2f6f66666963652f323030362f6d657461646174612f70726f7065727469657322206d613a726f6f743d227472756522206d613a6669656c647349443d22 +393637663537656361366533626638633435623136343161643237363161636522206e73323a5f3d222220786d6c6e733a7873643d22687474703a2f2f7777772e77332e6f72672f323030312f584d4c536368656d612220786d6c6e733a78733d22687474703a2f2f7777772e77332e6f72672f323030312f584d4c5363 +68656d612220786d6c6e733a703d22687474703a2f2f736368656d61732e6d6963726f736f66742e636f6d2f6f66666963652f323030362f6d657461646174612f70726f706572746965732220786d6c6e733a6e73323d2232656334313736362d353237652d346338342d623438342d646633663235393966643061223e +0d0a3c7873643a696d706f7274206e616d6573706163653d2232656334313736362d353237652d346338342d623438342d646633663235393966643061222f3e0d0a3c7873643a656c656d656e74206e616d653d2270726f70657274696573223e0d0a3c7873643a636f6d706c6578547970653e0d0a3c7873643a736571 +75656e63653e0d0a3c7873643a656c656d656e74206e616d653d22646f63756d656e744d616e6167656d656e74223e0d0a3c7873643a636f6d706c6578547970653e0d0a3c7873643a616c6c3e0d0a3c7873643a656c656d656e74207265663d226e73323a45585422206d696e4f63637572733d2230222f3e0d0a3c7873 +643a656c656d656e74207265663d226e73323a446f635479706522206d696e4f63637572733d2230222f3e0d0a3c7873643a656c656d656e74207265663d226e73323a4469766973696f6e22206d696e4f63637572733d2230222f3e0d0a3c7873643a656c656d656e74207265663d226e73323a436f6d6d656e74732220 +6d696e4f63637572733d2230222f3e0d0a3c7873643a656c656d656e74207265663d226e73323a446f6d696e6f5f78303032305f56657273696f6e22206d696e4f63637572733d2230222f3e0d0a3c7873643a656c656d656e74207265663d226e73323a446f6d696e6f5f78303032305f417574686f7222206d696e4f63 +637572733d2230222f3e0d0a3c7873643a656c656d656e74207265663d226e73323a446f634e756d62657222206d696e4f63637572733d2230222f3e0d0a3c7873643a656c656d656e74207265663d226e73323a4e6f746573554e494422206d696e4f63637572733d2230222f3e0d0a3c7873643a656c656d656e742072 +65663d226e73323a4e6f74657354696d655374616d7022206d696e4f63637572733d2230222f3e0d0a3c7873643a656c656d656e74207265663d226e73323a4e6f7465735061727422206d696e4f63637572733d2230222f3e0d0a3c7873643a656c656d656e74207265663d226e73323a536964655f78303032305f4c65 +747465727322206d696e4f63637572733d2230222f3e0d0a3c2f7873643a616c6c3e0d0a3c2f7873643a636f6d706c6578547970653e0d0a3c2f7873643a656c656d656e743e0d0a3c2f7873643a73657175656e63653e0d0a3c2f7873643a636f6d706c6578547970653e0d0a3c2f7873643a656c656d656e743e0d0a3c +2f7873643a736368656d613e0d0a3c7873643a736368656d61207461726765744e616d6573706163653d2232656334313736362d353237652d346338342d623438342d6466336632353939666430612220656c656d656e74466f726d44656661756c743d227175616c69666965642220786d6c6e733a7873643d22687474 +703a2f2f7777772e77332e6f72672f323030312f584d4c536368656d612220786d6c6e733a78733d22687474703a2f2f7777772e77332e6f72672f323030312f584d4c536368656d612220786d6c6e733a646d733d22687474703a2f2f736368656d61732e6d6963726f736f66742e636f6d2f6f66666963652f32303036 +2f646f63756d656e744d616e6167656d656e742f74797065732220786d6c6e733a70633d22687474703a2f2f736368656d61732e6d6963726f736f66742e636f6d2f6f66666963652f696e666f706174682f323030372f506172746e6572436f6e74726f6c73223e0d0a3c7873643a696d706f7274206e616d6573706163 +653d22687474703a2f2f736368656d61732e6d6963726f736f66742e636f6d2f6f66666963652f323030362f646f63756d656e744d616e6167656d656e742f7479706573222f3e0d0a3c7873643a696d706f7274206e616d6573706163653d22687474703a2f2f736368656d61732e6d6963726f736f66742e636f6d2f6f +66666963652f696e666f706174682f323030372f506172746e6572436f6e74726f6c73222f3e0d0a3c7873643a656c656d656e74206e616d653d2245585422206d613a696e6465783d223122206e696c6c61626c653d227472756522206d613a646973706c61794e616d653d2245585422206d613a646573637269707469 +6f6e3d2246696c6520457874656e73696f6e22206d613a68696464656e3d227472756522206d613a696e7465726e616c4e616d653d2245585422206d613a726561644f6e6c793d2266616c7365223e0d0a3c7873643a73696d706c65547970653e0d0a3c7873643a7265737472696374696f6e20626173653d22646d733a +54657874223e0d0a3c7873643a6d61784c656e6774682076616c75653d223130222f3e0d0a3c2f7873643a7265737472696374696f6e3e0d0a3c2f7873643a73696d706c65547970653e0d0a3c2f7873643a656c656d656e743e0d0a3c7873643a656c656d656e74206e616d653d22446f635479706522206d613a696e64 +65783d223222206e696c6c61626c653d227472756522206d613a646973706c61794e616d653d22446f635479706522206d613a64656661756c743d22507265636564656e7422206d613a666f726d61743d2244726f70646f776e22206d613a68696464656e3d227472756522206d613a696e7465726e616c4e616d653d22 +446f635479706522206d613a726561644f6e6c793d2266616c7365223e0d0a3c7873643a73696d706c65547970653e0d0a3c7873643a7265737472696374696f6e20626173653d22646d733a43686f696365223e0d0a3c7873643a656e756d65726174696f6e2076616c75653d22507265636564656e74222f3e0d0a3c78 +73643a656e756d65726174696f6e2076616c75653d2253696465204c6574746572202d20537562222f3e0d0a3c2f7873643a7265737472696374696f6e3e0d0a3c2f7873643a73696d706c65547970653e0d0a3c2f7873643a656c656d656e743e0d0a3c7873643a656c656d656e74206e616d653d224469766973696f6e +22206d613a696e6465783d223422206e696c6c61626c653d227472756522206d613a646973706c61794e616d653d224469766973696f6e22206d613a666f726d61743d2244726f70646f776e22206d613a696e7465726e616c4e616d653d224469766973696f6e223e0d0a3c7873643a73696d706c65547970653e0d0a3c +7873643a7265737472696374696f6e20626173653d22646d733a43686f696365223e0d0a3c7873643a656e756d65726174696f6e2076616c75653d2241726368697665222f3e0d0a3c7873643a656e756d65726174696f6e2076616c75653d22415344222f3e0d0a3c7873643a656e756d65726174696f6e2076616c7565 +3d22415550222f3e0d0a3c7873643a656e756d65726174696f6e2076616c75653d22436f6d70616e792041646d696e222f3e0d0a3c7873643a656e756d65726174696f6e2076616c75653d22436f72706f72617465222f3e0d0a3c7873643a656e756d65726174696f6e2076616c75653d22446174612050726f74656374 +696f6e222f3e0d0a3c7873643a656e756d65726174696f6e2076616c75653d22446576656c6f706d656e742053797374656d73222f3e0d0a3c7873643a656e756d65726174696f6e2076616c75653d22454441222f3e0d0a3c7873643a656e756d65726174696f6e2076616c75653d22466163696c6974696573222f3e0d +0a3c7873643a656e756d65726174696f6e2076616c75653d224852222f3e0d0a3c7873643a656e756d65726174696f6e2076616c75653d2248522032222f3e0d0a3c7873643a656e756d65726174696f6e2076616c75653d224954222f3e0d0a3c7873643a656e756d65726174696f6e2076616c75653d22496e74657263 +6f6d70616e79204d617474657273222f3e0d0a3c7873643a656e756d65726174696f6e2076616c75653d224c6567616c204f7065726174696f6e73222f3e0d0a3c7873643a656e756d65726174696f6e2076616c75653d224d26616d703b41222f3e0d0a3c7873643a656e756d65726174696f6e2076616c75653d225061 +74656e7473222f3e0d0a3c7873643a656e756d65726174696f6e2076616c75653d225044202d20417263686974656374757265222f3e0d0a3c7873643a656e756d65726174696f6e2076616c75653d225044202d20436f726573222f3e0d0a3c7873643a656e756d65726174696f6e2076616c75653d22504420e2809320 +435353222f3e0d0a3c7873643a656e756d65726174696f6e2076616c75653d225044202d204d5044222f3e0d0a3c7873643a656e756d65726174696f6e2076616c75653d2250444547222f3e0d0a3c7873643a656e756d65726174696f6e2076616c75653d22504445472046726565204c69627261727920416e6e657865 +73222f3e0d0a3c7873643a656e756d65726174696f6e2076616c75653d22504445472046726565204c69627261727920436f6e747261637473222f3e0d0a3c7873643a656e756d65726174696f6e2076616c75653d2250495044222f3e0d0a3c7873643a656e756d65726174696f6e2076616c75653d2250495044204672 +6565204c69627261727920416e6e65786573222f3e0d0a3c7873643a656e756d65726174696f6e2076616c75653d22504950442046726565204c69627261727920436f6e747261637473222f3e0d0a3c7873643a656e756d65726174696f6e2076616c75653d22534444222f3e0d0a3c7873643a656e756d65726174696f +6e2076616c75653d22535344222f3e0d0a3c7873643a656e756d65726174696f6e2076616c75653d224d61726b6574696e67222f3e0d0a3c7873643a656e756d65726174696f6e2076616c75653d225044202d204661627269632028617070726f76616c20726571756972656420627920436f6e74726163742d61707072 +6f76616c2d504429222f3e0d0a3c7873643a656e756d65726174696f6e2076616c75653d225374616e6461726473222f3e0d0a3c7873643a656e756d65726174696f6e2076616c75653d225275737369616e207472616e73616374696f6e73222f3e0d0a3c7873643a656e756d65726174696f6e2076616c75653d225765 +627369746520506f6c6963696573222f3e0d0a3c7873643a656e756d65726174696f6e2076616c75653d225472616465204d61726b73222f3e0d0a3c7873643a656e756d65726174696f6e2076616c75653d22496f54204255222f3e0d0a3c7873643a656e756d65726174696f6e2076616c75653d225045472028707265 +76696f75736c792041534429222f3e0d0a3c7873643a656e756d65726174696f6e2076616c75653d224d5047202870726576696f75736c79206b6e6f776e206173205044202d204d504429222f3e0d0a3c7873643a656e756d65726174696f6e2076616c75653d22435047202870726576696f75736c79206b6e6f776e20 +617320e2809c5044202d20436f72657329222f3e0d0a3c7873643a656e756d65726174696f6e2076616c75653d22445347202870726576696f75736c79206b6e6f776e2061732053444429222f3e0d0a3c7873643a656e756d65726174696f6e2076616c75653d22415447202870726576696f75736c79206b6e6f776e20 +6173205044202d2041726368697465637475726529222f3e0d0a3c7873643a656e756d65726174696f6e2076616c75653d22535347202d2053797374656d20495020616e6420436f72655369676874202870726576696f75736c79206b6e6f776e206173205044202d2046616272696329222f3e0d0a3c7873643a656e75 +6d65726174696f6e2076616c75653d22535347222f3e0d0a3c7873643a656e756d65726174696f6e2076616c75653d225226616d703b44222f3e0d0a3c2f7873643a7265737472696374696f6e3e0d0a3c2f7873643a73696d706c65547970653e0d0a3c2f7873643a656c656d656e743e0d0a3c7873643a656c656d656e +74206e616d653d22436f6d6d656e747322206d613a696e6465783d223522206e696c6c61626c653d227472756522206d613a646973706c61794e616d653d22436f6d6d656e747322206d613a696e7465726e616c4e616d653d22436f6d6d656e7473223e0d0a3c7873643a73696d706c65547970653e0d0a3c7873643a72 +65737472696374696f6e20626173653d22646d733a4e6f7465223e0d0a3c7873643a6d61784c656e6774682076616c75653d22323535222f3e0d0a3c2f7873643a7265737472696374696f6e3e0d0a3c2f7873643a73696d706c65547970653e0d0a3c2f7873643a656c656d656e743e0d0a3c7873643a656c656d656e74 +206e616d653d22446f6d696e6f5f78303032305f56657273696f6e22206d613a696e6465783d223622206e696c6c61626c653d227472756522206d613a646973706c61794e616d653d22446f6d696e6f2056657273696f6e22206d613a68696464656e3d227472756522206d613a696e7465726e616c4e616d653d22446f +6d696e6f5f78303032305f56657273696f6e22206d613a726561644f6e6c793d2266616c7365223e0d0a3c7873643a73696d706c65547970653e0d0a3c7873643a7265737472696374696f6e20626173653d22646d733a54657874222f3e0d0a3c2f7873643a73696d706c65547970653e0d0a3c2f7873643a656c656d65 +6e743e0d0a3c7873643a656c656d656e74206e616d653d22446f6d696e6f5f78303032305f417574686f7222206d613a696e6465783d223722206e696c6c61626c653d227472756522206d613a646973706c61794e616d653d22446f6d696e6f20417574686f7222206d613a68696464656e3d227472756522206d613a69 +6e7465726e616c4e616d653d22446f6d696e6f5f78303032305f417574686f7222206d613a726561644f6e6c793d2266616c7365223e0d0a3c7873643a73696d706c65547970653e0d0a3c7873643a7265737472696374696f6e20626173653d22646d733a54657874222f3e0d0a3c2f7873643a73696d706c6554797065 +3e0d0a3c2f7873643a656c656d656e743e0d0a3c7873643a656c656d656e74206e616d653d22446f634e756d62657222206d613a696e6465783d223822206e696c6c61626c653d227472756522206d613a646973706c61794e616d653d22446f634e756d62657222206d613a68696464656e3d227472756522206d613a69 +6e7465726e616c4e616d653d22446f634e756d62657222206d613a726561644f6e6c793d2266616c7365223e0d0a3c7873643a73696d706c65547970653e0d0a3c7873643a7265737472696374696f6e20626173653d22646d733a54657874222f3e0d0a3c2f7873643a73696d706c65547970653e0d0a3c2f7873643a65 +6c656d656e743e0d0a3c7873643a656c656d656e74206e616d653d224e6f746573554e494422206d613a696e6465783d22313422206e696c6c61626c653d227472756522206d613a646973706c61794e616d653d224e6f746573554e494422206d613a68696464656e3d227472756522206d613a696e7465726e616c4e61 +6d653d224e6f746573554e4944223e0d0a3c7873643a73696d706c65547970653e0d0a3c7873643a7265737472696374696f6e20626173653d22646d733a54657874222f3e0d0a3c2f7873643a73696d706c65547970653e0d0a3c2f7873643a656c656d656e743e0d0a3c7873643a656c656d656e74206e616d653d224e +6f74657354696d655374616d7022206d613a696e6465783d22313522206e696c6c61626c653d227472756522206d613a646973706c61794e616d653d224e6f74657354696d655374616d7022206d613a68696464656e3d227472756522206d613a696e7465726e616c4e616d653d224e6f74657354696d655374616d7022 +3e0d0a3c7873643a73696d706c65547970653e0d0a3c7873643a7265737472696374696f6e20626173653d22646d733a4461746554696d65222f3e0d0a3c2f7873643a73696d706c65547970653e0d0a3c2f7873643a656c656d656e743e0d0a3c7873643a656c656d656e74206e616d653d224e6f746573506172742220 +6d613a696e6465783d22313622206e696c6c61626c653d227472756522206d613a646973706c61794e616d653d224e6f7465735061727422206d613a68696464656e3d227472756522206d613a696e7465726e616c4e616d653d224e6f74657350617274223e0d0a3c7873643a73696d706c65547970653e0d0a3c787364 +3a7265737472696374696f6e20626173653d22646d733a54657874222f3e0d0a3c2f7873643a73696d706c65547970653e0d0a3c2f7873643a656c656d656e743e0d0a3c7873643a656c656d656e74206e616d653d22536964655f78303032305f4c65747465727322206d613a696e6465783d22313822206e696c6c6162 +6c653d227472756522206d613a646973706c61794e616d653d2253696465204c65747465727322206d613a64656661756c743d223022206d613a68696464656e3d227472756522206d613a696e7465726e616c4e616d653d22536964655f78303032305f4c65747465727322206d613a726561644f6e6c793d2266616c73 +6522206d613a70657263656e746167653d2246414c5345223e0d0a3c7873643a73696d706c65547970653e0d0a3c7873643a7265737472696374696f6e20626173653d22646d733a4e756d626572222f3e0d0a3c2f7873643a73696d706c65547970653e0d0a3c2f7873643a656c656d656e743e0d0a3c2f7873643a7363 +68656d613e0d0a3c7873643a736368656d61207461726765744e616d6573706163653d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f7061636b6167652f323030362f6d657461646174612f636f72652d70726f706572746965732220656c656d656e74466f726d44656661756c +743d227175616c69666965642220617474726962757465466f726d44656661756c743d22756e7175616c69666965642220626c6f636b44656661756c743d2223616c6c2220786d6c6e733d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f7061636b6167652f323030362f6d6574 +61646174612f636f72652d70726f706572746965732220786d6c6e733a7873643d22687474703a2f2f7777772e77332e6f72672f323030312f584d4c536368656d612220786d6c6e733a7873693d22687474703a2f2f7777772e77332e6f72672f323030312f584d4c536368656d612d696e7374616e63652220786d6c6e +733a64633d22687474703a2f2f7075726c2e6f72672f64632f656c656d656e74732f312e312f2220786d6c6e733a64637465726d733d22687474703a2f2f7075726c2e6f72672f64632f7465726d732f2220786d6c6e733a6f646f633d22687474703a2f2f736368656d61732e6d6963726f736f66742e636f6d2f696e74 +65726e616c2f6f6264223e0d0a3c7873643a696d706f7274206e616d6573706163653d22687474703a2f2f7075726c2e6f72672f64632f656c656d656e74732f312e312f2220736368656d614c6f636174696f6e3d22687474703a2f2f6475626c696e636f72652e6f72672f736368656d61732f786d6c732f7164632f32 +3030332f30342f30322f64632e787364222f3e0d0a3c7873643a696d706f7274206e616d6573706163653d22687474703a2f2f7075726c2e6f72672f64632f7465726d732f2220736368656d614c6f636174696f6e3d22687474703a2f2f6475626c696e636f72652e6f72672f736368656d61732f786d6c732f7164632f +323030332f30342f30322f64637465726d732e787364222f3e0d0a3c7873643a656c656d656e74206e616d653d22636f726550726f706572746965732220747970653d2243545f636f726550726f70657274696573222f3e0d0a3c7873643a636f6d706c657854797065206e616d653d2243545f636f726550726f706572 +74696573223e0d0a3c7873643a616c6c3e0d0a3c7873643a656c656d656e74207265663d2264633a63726561746f7222206d696e4f63637572733d223022206d61784f63637572733d2231222f3e0d0a3c7873643a656c656d656e74207265663d2264637465726d733a6372656174656422206d696e4f63637572733d22 +3022206d61784f63637572733d2231222f3e0d0a3c7873643a656c656d656e74207265663d2264633a6964656e74696669657222206d696e4f63637572733d223022206d61784f63637572733d2231222f3e0d0a3c7873643a656c656d656e74206e616d653d22636f6e74656e745479706522206d696e4f63637572733d +223022206d61784f63637572733d22312220747970653d227873643a737472696e6722206d613a696e6465783d223922206d613a646973706c61794e616d653d22436f6e74656e742054797065222f3e0d0a3c7873643a656c656d656e74207265663d2264633a7469746c6522206d696e4f63637572733d223022206d61 +784f63637572733d223122206d613a696e6465783d223322206d613a646973706c61794e616d653d225469746c65222f3e0d0a3c7873643a656c656d656e74207265663d2264633a7375626a65637422206d696e4f63637572733d223022206d61784f63637572733d2231222f3e0d0a3c7873643a656c656d656e742072 +65663d2264633a6465736372697074696f6e22206d696e4f63637572733d223022206d61784f63637572733d2231222f3e0d0a3c7873643a656c656d656e74206e616d653d226b6579776f72647322206d696e4f63637572733d223022206d61784f63637572733d22312220747970653d227873643a737472696e67222f +3e0d0a3c7873643a656c656d656e74207265663d2264633a6c616e677561676522206d696e4f63637572733d223022206d61784f63637572733d2231222f3e0d0a3c7873643a656c656d656e74206e616d653d2263617465676f727922206d696e4f63637572733d223022206d61784f63637572733d2231222074797065 +3d227873643a737472696e67222f3e0d0a3c7873643a656c656d656e74206e616d653d2276657273696f6e22206d696e4f63637572733d223022206d61784f63637572733d22312220747970653d227873643a737472696e67222f3e0d0a3c7873643a656c656d656e74206e616d653d227265766973696f6e22206d696e +4f63637572733d223022206d61784f63637572733d22312220747970653d227873643a737472696e67223e0d0a3c7873643a616e6e6f746174696f6e3e0d0a3c7873643a646f63756d656e746174696f6e3e0d0a202020202020202020202020202020202020202020202020546869732076616c756520696e6469636174 +657320746865206e756d626572206f66207361766573206f72207265766973696f6e732e20546865206170706c69636174696f6e20697320726573706f6e7369626c6520666f72207570646174696e6720746869732076616c75652061667465722065616368207265766973696f6e2e0d0a202020202020202020202020 +20202020202020203c2f7873643a646f63756d656e746174696f6e3e0d0a3c2f7873643a616e6e6f746174696f6e3e0d0a3c2f7873643a656c656d656e743e0d0a3c7873643a656c656d656e74206e616d653d226c6173744d6f646966696564427922206d696e4f63637572733d223022206d61784f63637572733d2231 +2220747970653d227873643a737472696e67222f3e0d0a3c7873643a656c656d656e74207265663d2264637465726d733a6d6f64696669656422206d696e4f63637572733d223022206d61784f63637572733d2231222f3e0d0a3c7873643a656c656d656e74206e616d653d22636f6e74656e7453746174757322206d69 +6e4f63637572733d223022206d61784f63637572733d22312220747970653d227873643a737472696e67222f3e0d0a3c2f7873643a616c6c3e0d0a3c2f7873643a636f6d706c6578547970653e0d0a3c2f7873643a736368656d613e0d0a3c78733a736368656d61207461726765744e616d6573706163653d2268747470 +3a2f2f736368656d61732e6d6963726f736f66742e636f6d2f6f66666963652f696e666f706174682f323030372f506172746e6572436f6e74726f6c732220656c656d656e74466f726d44656661756c743d227175616c69666965642220617474726962757465466f726d44656661756c743d22756e7175616c69666965 +642220786d6c6e733a70633d22687474703a2f2f736368656d61732e6d6963726f736f66742e636f6d2f6f66666963652f696e666f706174682f323030372f506172746e6572436f6e74726f6c732220786d6c6e733a78733d22687474703a2f2f7777772e77332e6f72672f323030312f584d4c536368656d61223e0d0a +3c78733a656c656d656e74206e616d653d22506572736f6e223e0d0a3c78733a636f6d706c6578547970653e0d0a3c78733a73657175656e63653e0d0a3c78733a656c656d656e74207265663d2270633a446973706c61794e616d6522206d696e4f63637572733d2230223e3c2f78733a656c656d656e743e0d0a3c7873 +3a656c656d656e74207265663d2270633a4163636f756e74496422206d696e4f63637572733d2230223e3c2f78733a656c656d656e743e0d0a3c78733a656c656d656e74207265663d2270633a4163636f756e745479706522206d696e4f63637572733d2230223e3c2f78733a656c656d656e743e0d0a3c2f78733a7365 +7175656e63653e0d0a3c2f78733a636f6d706c6578547970653e0d0a3c2f78733a656c656d656e743e0d0a3c78733a656c656d656e74206e616d653d22446973706c61794e616d652220747970653d2278733a737472696e67223e3c2f78733a656c656d656e743e0d0a3c78733a656c656d656e74206e616d653d224163 +636f756e7449642220747970653d2278733a737472696e67223e3c2f78733a656c656d656e743e0d0a3c78733a656c656d656e74206e616d653d224163636f756e74547970652220747970653d2278733a737472696e67223e3c2f78733a656c656d656e743e0d0a3c78733a656c656d656e74206e616d653d2242444341 +73736f636961746564456e74697479223e0d0a3c78733a636f6d706c6578547970653e0d0a3c78733a73657175656e63653e0d0a3c78733a656c656d656e74207265663d2270633a424443456e7469747922206d696e4f63637572733d223022206d61784f63637572733d22756e626f756e646564223e3c2f78733a656c +656d656e743e0d0a3c2f78733a73657175656e63653e0d0a3c78733a617474726962757465207265663d2270633a456e746974794e616d657370616365223e3c2f78733a6174747269627574653e0d0a3c78733a617474726962757465207265663d2270633a456e746974794e616d65223e3c2f78733a61747472696275 +74653e0d0a3c78733a617474726962757465207265663d2270633a53797374656d496e7374616e63654e616d65223e3c2f78733a6174747269627574653e0d0a3c78733a617474726962757465207265663d2270633a4173736f63696174696f6e4e616d65223e3c2f78733a6174747269627574653e0d0a3c2f78733a63 +6f6d706c6578547970653e0d0a3c2f78733a656c656d656e743e0d0a3c78733a617474726962757465206e616d653d22456e746974794e616d6573706163652220747970653d2278733a737472696e67223e3c2f78733a6174747269627574653e0d0a3c78733a617474726962757465206e616d653d22456e746974794e +616d652220747970653d2278733a737472696e67223e3c2f78733a6174747269627574653e0d0a3c78733a617474726962757465206e616d653d2253797374656d496e7374616e63654e616d652220747970653d2278733a737472696e67223e3c2f78733a6174747269627574653e0d0a3c78733a617474726962757465 +206e616d653d224173736f63696174696f6e4e616d652220747970653d2278733a737472696e67223e3c2f78733a6174747269627574653e0d0a3c78733a656c656d656e74206e616d653d22424443456e74697479223e0d0a3c78733a636f6d706c6578547970653e0d0a3c78733a73657175656e63653e0d0a3c78733a +656c656d656e74207265663d2270633a456e74697479446973706c61794e616d6522206d696e4f63637572733d2230223e3c2f78733a656c656d656e743e0d0a3c78733a656c656d656e74207265663d2270633a456e74697479496e7374616e63655265666572656e636522206d696e4f63637572733d2230223e3c2f78 +733a656c656d656e743e0d0a3c78733a656c656d656e74207265663d2270633a456e7469747949643122206d696e4f63637572733d2230223e3c2f78733a656c656d656e743e0d0a3c78733a656c656d656e74207265663d2270633a456e7469747949643222206d696e4f63637572733d2230223e3c2f78733a656c656d +656e743e0d0a3c78733a656c656d656e74207265663d2270633a456e7469747949643322206d696e4f63637572733d2230223e3c2f78733a656c656d656e743e0d0a3c78733a656c656d656e74207265663d2270633a456e7469747949643422206d696e4f63637572733d2230223e3c2f78733a656c656d656e743e0d0a +3c78733a656c656d656e74207265663d2270633a456e7469747949643522206d696e4f63637572733d2230223e3c2f78733a656c656d656e743e0d0a3c2f78733a73657175656e63653e0d0a3c2f78733a636f6d706c6578547970653e0d0a3c2f78733a656c656d656e743e0d0a3c78733a656c656d656e74206e616d65 +3d22456e74697479446973706c61794e616d652220747970653d2278733a737472696e67223e3c2f78733a656c656d656e743e0d0a3c78733a656c656d656e74206e616d653d22456e74697479496e7374616e63655265666572656e63652220747970653d2278733a737472696e67223e3c2f78733a656c656d656e743e +0d0a3c78733a656c656d656e74206e616d653d22456e746974794964312220747970653d2278733a737472696e67223e3c2f78733a656c656d656e743e0d0a3c78733a656c656d656e74206e616d653d22456e746974794964322220747970653d2278733a737472696e67223e3c2f78733a656c656d656e743e0d0a3c78 +733a656c656d656e74206e616d653d22456e746974794964332220747970653d2278733a737472696e67223e3c2f78733a656c656d656e743e0d0a3c78733a656c656d656e74206e616d653d22456e746974794964342220747970653d2278733a737472696e67223e3c2f78733a656c656d656e743e0d0a3c78733a656c +656d656e74206e616d653d22456e746974794964352220747970653d2278733a737472696e67223e3c2f78733a656c656d656e743e0d0a3c78733a656c656d656e74206e616d653d225465726d73223e0d0a3c78733a636f6d706c6578547970653e0d0a3c78733a73657175656e63653e0d0a3c78733a656c656d656e74 +207265663d2270633a5465726d496e666f22206d696e4f63637572733d223022206d61784f63637572733d22756e626f756e646564223e3c2f78733a656c656d656e743e0d0a3c2f78733a73657175656e63653e0d0a3c2f78733a636f6d706c6578547970653e0d0a3c2f78733a656c656d656e743e0d0a3c78733a656c +656d656e74206e616d653d225465726d496e666f223e0d0a3c78733a636f6d706c6578547970653e0d0a3c78733a73657175656e63653e0d0a3c78733a656c656d656e74207265663d2270633a5465726d4e616d6522206d696e4f63637572733d2230223e3c2f78733a656c656d656e743e0d0a3c78733a656c656d656e +74207265663d2270633a5465726d496422206d696e4f63637572733d2230223e3c2f78733a656c656d656e743e0d0a3c2f78733a73657175656e63653e0d0a3c2f78733a636f6d706c6578547970653e0d0a3c2f78733a656c656d656e743e0d0a3c78733a656c656d656e74206e616d653d225465726d4e616d65222074 +7970653d2278733a737472696e67223e3c2f78733a656c656d656e743e0d0a3c78733a656c656d656e74206e616d653d225465726d49642220747970653d2278733a737472696e67223e3c2f78733a656c656d656e743e0d0a3c2f78733a736368656d613e0d0a3c2f63743a636f6e74656e7454797065536368656d613e +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000500072006f00700065007200740069006500 +7300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016000200ffffffffffffffffffffffff00000000000000000000000000000000000000000000000000000000000000000000000066000000400400000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e733a64733d22687474 +703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f6f6666696365446f63756d656e742f323030362f637573746f6d586d6c223e3c64733a736368656d61526566733e3c64733a736368656d615265662064733a7572693d22687474703a2f2f736368656d61732e6d6963726f736f66742e636f +6d2f6f66666963652f323030362f6d657461646174612f636f6e74656e7454797065222f3e3c64733a736368656d615265662064733a7572693d22687474703a2f2f736368656d61732e6d6963726f736f66742e636f6d2f6f66666963652f323030362f6d657461646174612f70726f706572746965732f6d6574614174 +7472696275746573222f3e3c64733a736368656d615265662064733a7572693d22687474703a2f2f7777772e77332e6f72672f323030312f584d4c536368656d61222f3e3c64733a736368656d615265662064733a7572693d22687474703a2f2f736368656d61732e6d6963726f736f66742e636f6d2f6f66666963652f +323030362f6d657461646174612f70726f70657274696573222f3e3c64733a736368656d615265662064733a7572693d2232656334313736362d353237652d346338342d623438342d646633663235393966643061222f3e3c64733a736368656d615265662064733a7572693d22687474703a2f2f736368656d61732e6d +6963726f736f66742e636f6d2f6f66666963652f323030362f646f63756d656e744d616e6167656d656e742f7479706573222f3e3c64733a736368656d615265662064733a7572693d22687474703a2f2f736368656d61732e6d6963726f736f66742e636f6d2f6f66666963652f696e666f706174682f323030372f5061 +72746e6572436f6e74726f6c73222f3e3c64733a736368656d615265662064733a7572693d22687474703a2f2f736368656d61732e6f70656e786d6c666f726d6174732e6f72672f7061636b6167652f323030362f6d657461646174612f636f72652d70726f70657274696573222f3e3c64733a736368656d6152656620 +64733a7572693d22687474703a2f2f7075726c2e6f72672f64632f656c656d656e74732f312e312f222f3e3c64733a736368656d615265662064733a7572693d22687474703a2f2f7075726c2e6f72672f64632f7465726d732f222f3e3c64733a736368656d615265662064733a7572693d22687474703a2f2f73636865 +6d61732e6d6963726f736f66742e636f6d2f696e7465726e616c2f6f6264222f3e3c2f64733a736368656d61526566733e3c2f64733a6461746173746f72654974656d3e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000105000000000000}} \ No newline at end of file diff --git a/platform/mcu/lpc54102/CMSIS/Include/arm_common_tables.h b/platform/mcu/lpc54102/CMSIS/Include/arm_common_tables.h new file mode 100644 index 0000000000..8742a56991 --- /dev/null +++ b/platform/mcu/lpc54102/CMSIS/Include/arm_common_tables.h @@ -0,0 +1,136 @@ +/* ---------------------------------------------------------------------- +* Copyright (C) 2010-2014 ARM Limited. All rights reserved. +* +* $Date: 19. October 2015 +* $Revision: V.1.4.5 a +* +* Project: CMSIS DSP Library +* Title: arm_common_tables.h +* +* Description: This file has extern declaration for common tables like Bitreverse, reciprocal etc which are used across different functions +* +* Target Processor: Cortex-M4/Cortex-M3 +* +* 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 LIMITED 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 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +* -------------------------------------------------------------------- */ + +#ifndef _ARM_COMMON_TABLES_H +#define _ARM_COMMON_TABLES_H + +#include "arm_math.h" + +extern const uint16_t armBitRevTable[1024]; +extern const q15_t armRecipTableQ15[64]; +extern const q31_t armRecipTableQ31[64]; +/* extern const q31_t realCoefAQ31[1024]; */ +/* extern const q31_t realCoefBQ31[1024]; */ +extern const float32_t twiddleCoef_16[32]; +extern const float32_t twiddleCoef_32[64]; +extern const float32_t twiddleCoef_64[128]; +extern const float32_t twiddleCoef_128[256]; +extern const float32_t twiddleCoef_256[512]; +extern const float32_t twiddleCoef_512[1024]; +extern const float32_t twiddleCoef_1024[2048]; +extern const float32_t twiddleCoef_2048[4096]; +extern const float32_t twiddleCoef_4096[8192]; +#define twiddleCoef twiddleCoef_4096 +extern const q31_t twiddleCoef_16_q31[24]; +extern const q31_t twiddleCoef_32_q31[48]; +extern const q31_t twiddleCoef_64_q31[96]; +extern const q31_t twiddleCoef_128_q31[192]; +extern const q31_t twiddleCoef_256_q31[384]; +extern const q31_t twiddleCoef_512_q31[768]; +extern const q31_t twiddleCoef_1024_q31[1536]; +extern const q31_t twiddleCoef_2048_q31[3072]; +extern const q31_t twiddleCoef_4096_q31[6144]; +extern const q15_t twiddleCoef_16_q15[24]; +extern const q15_t twiddleCoef_32_q15[48]; +extern const q15_t twiddleCoef_64_q15[96]; +extern const q15_t twiddleCoef_128_q15[192]; +extern const q15_t twiddleCoef_256_q15[384]; +extern const q15_t twiddleCoef_512_q15[768]; +extern const q15_t twiddleCoef_1024_q15[1536]; +extern const q15_t twiddleCoef_2048_q15[3072]; +extern const q15_t twiddleCoef_4096_q15[6144]; +extern const float32_t twiddleCoef_rfft_32[32]; +extern const float32_t twiddleCoef_rfft_64[64]; +extern const float32_t twiddleCoef_rfft_128[128]; +extern const float32_t twiddleCoef_rfft_256[256]; +extern const float32_t twiddleCoef_rfft_512[512]; +extern const float32_t twiddleCoef_rfft_1024[1024]; +extern const float32_t twiddleCoef_rfft_2048[2048]; +extern const float32_t twiddleCoef_rfft_4096[4096]; + + +/* floating-point bit reversal tables */ +#define ARMBITREVINDEXTABLE__16_TABLE_LENGTH ((uint16_t)20 ) +#define ARMBITREVINDEXTABLE__32_TABLE_LENGTH ((uint16_t)48 ) +#define ARMBITREVINDEXTABLE__64_TABLE_LENGTH ((uint16_t)56 ) +#define ARMBITREVINDEXTABLE_128_TABLE_LENGTH ((uint16_t)208 ) +#define ARMBITREVINDEXTABLE_256_TABLE_LENGTH ((uint16_t)440 ) +#define ARMBITREVINDEXTABLE_512_TABLE_LENGTH ((uint16_t)448 ) +#define ARMBITREVINDEXTABLE1024_TABLE_LENGTH ((uint16_t)1800) +#define ARMBITREVINDEXTABLE2048_TABLE_LENGTH ((uint16_t)3808) +#define ARMBITREVINDEXTABLE4096_TABLE_LENGTH ((uint16_t)4032) + +extern const uint16_t armBitRevIndexTable16[ARMBITREVINDEXTABLE__16_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable32[ARMBITREVINDEXTABLE__32_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable64[ARMBITREVINDEXTABLE__64_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable128[ARMBITREVINDEXTABLE_128_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable256[ARMBITREVINDEXTABLE_256_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable512[ARMBITREVINDEXTABLE_512_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable1024[ARMBITREVINDEXTABLE1024_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable2048[ARMBITREVINDEXTABLE2048_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable4096[ARMBITREVINDEXTABLE4096_TABLE_LENGTH]; + +/* fixed-point bit reversal tables */ +#define ARMBITREVINDEXTABLE_FIXED___16_TABLE_LENGTH ((uint16_t)12 ) +#define ARMBITREVINDEXTABLE_FIXED___32_TABLE_LENGTH ((uint16_t)24 ) +#define ARMBITREVINDEXTABLE_FIXED___64_TABLE_LENGTH ((uint16_t)56 ) +#define ARMBITREVINDEXTABLE_FIXED__128_TABLE_LENGTH ((uint16_t)112 ) +#define ARMBITREVINDEXTABLE_FIXED__256_TABLE_LENGTH ((uint16_t)240 ) +#define ARMBITREVINDEXTABLE_FIXED__512_TABLE_LENGTH ((uint16_t)480 ) +#define ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH ((uint16_t)992 ) +#define ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH ((uint16_t)1984) +#define ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH ((uint16_t)4032) + +extern const uint16_t armBitRevIndexTable_fixed_16[ARMBITREVINDEXTABLE_FIXED___16_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_32[ARMBITREVINDEXTABLE_FIXED___32_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_64[ARMBITREVINDEXTABLE_FIXED___64_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_128[ARMBITREVINDEXTABLE_FIXED__128_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_256[ARMBITREVINDEXTABLE_FIXED__256_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_512[ARMBITREVINDEXTABLE_FIXED__512_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_1024[ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_2048[ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH]; +extern const uint16_t armBitRevIndexTable_fixed_4096[ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH]; + +/* Tables for Fast Math Sine and Cosine */ +extern const float32_t sinTable_f32[FAST_MATH_TABLE_SIZE + 1]; +extern const q31_t sinTable_q31[FAST_MATH_TABLE_SIZE + 1]; +extern const q15_t sinTable_q15[FAST_MATH_TABLE_SIZE + 1]; + +#endif /* ARM_COMMON_TABLES_H */ diff --git a/platform/mcu/lpc54102/CMSIS/Include/arm_const_structs.h b/platform/mcu/lpc54102/CMSIS/Include/arm_const_structs.h new file mode 100644 index 0000000000..726d06eb69 --- /dev/null +++ b/platform/mcu/lpc54102/CMSIS/Include/arm_const_structs.h @@ -0,0 +1,79 @@ +/* ---------------------------------------------------------------------- +* Copyright (C) 2010-2014 ARM Limited. All rights reserved. +* +* $Date: 19. March 2015 +* $Revision: V.1.4.5 +* +* Project: CMSIS DSP Library +* Title: arm_const_structs.h +* +* Description: This file has constant structs that are initialized for +* user convenience. For example, some can be given as +* arguments to the arm_cfft_f32() function. +* +* Target Processor: Cortex-M4/Cortex-M3 +* +* 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 LIMITED 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 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +* -------------------------------------------------------------------- */ + +#ifndef _ARM_CONST_STRUCTS_H +#define _ARM_CONST_STRUCTS_H + +#include "arm_math.h" +#include "arm_common_tables.h" + + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len16; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len32; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len64; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len128; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len256; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len512; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len1024; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len2048; + extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len4096; + + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len16; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len32; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len64; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len128; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len256; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len512; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len1024; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len2048; + extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len4096; + + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len16; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len32; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len64; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len128; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len256; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len512; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len1024; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len2048; + extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len4096; + +#endif diff --git a/platform/mcu/lpc54102/CMSIS/Include/arm_math.h b/platform/mcu/lpc54102/CMSIS/Include/arm_math.h new file mode 100644 index 0000000000..d33f8a9b3b --- /dev/null +++ b/platform/mcu/lpc54102/CMSIS/Include/arm_math.h @@ -0,0 +1,7154 @@ +/* ---------------------------------------------------------------------- +* Copyright (C) 2010-2015 ARM Limited. All rights reserved. +* +* $Date: 20. October 2015 +* $Revision: V1.4.5 b +* +* Project: CMSIS DSP Library +* Title: arm_math.h +* +* Description: Public header file for CMSIS DSP Library +* +* Target Processor: Cortex-M7/Cortex-M4/Cortex-M3/Cortex-M0 +* +* 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 LIMITED 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 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* 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 + */ + +/** + * @defgroup groupFastMath Fast Math Functions + * This set of functions provides a fast approximation to sine, cosine, and square root. + * As compared to most of the other functions in the CMSIS math library, the fast math functions + * operate on individual values and not arrays. + * There are separate functions for Q15, Q31, and floating-point data. + * + */ + +/** + * @defgroup groupCmplxMath Complex Math Functions + * This set of functions operates on complex data vectors. + * The data in the complex arrays is stored in an interleaved fashion + * (real, imag, real, imag, ...). + * In the API functions, the number of samples in a complex array refers + * to the number of complex values; the array contains twice this number of + * real values. + */ + +/** + * @defgroup groupFilters Filtering Functions + */ + +/** + * @defgroup groupMatrix Matrix Functions + * + * This set of functions provides basic matrix math operations. + * The functions operate on matrix data structures. For example, + * the type + * definition for the floating-point matrix structure is shown + * below: + *
+ *     typedef struct
+ *     {
+ *       uint16_t numRows;     // number of rows of the matrix.
+ *       uint16_t numCols;     // number of columns of the matrix.
+ *       float32_t *pData;     // points to the data of the matrix.
+ *     } arm_matrix_instance_f32;
+ * 
+ * There are similar definitions for Q15 and Q31 data types. + * + * The structure specifies the size of the matrix and then points to + * an array of data. The array is of size numRows X numCols + * and the values are arranged in row order. That is, the + * matrix element (i, j) is stored at: + *
+ *     pData[i*numCols + j]
+ * 
+ * + * \par Init Functions + * There is an associated initialization function for each type of matrix + * data structure. + * The initialization function sets the values of the internal structure fields. + * Refer to the function arm_mat_init_f32(), arm_mat_init_q31() + * and arm_mat_init_q15() for floating-point, Q31 and Q15 types, respectively. + * + * \par + * Use of the initialization function is optional. However, if initialization function is used + * then the instance structure cannot be placed into a const data section. + * To place the instance structure in a const data + * section, manually initialize the data structure. For example: + *
+ * arm_matrix_instance_f32 S = {nRows, nColumns, pData};
+ * arm_matrix_instance_q31 S = {nRows, nColumns, pData};
+ * arm_matrix_instance_q15 S = {nRows, nColumns, pData};
+ * 
+ * where nRows specifies the number of rows, nColumns + * specifies the number of columns, and pData points to the + * data array. + * + * \par Size Checking + * By default all of the matrix functions perform size checking on the input and + * output matrices. For example, the matrix addition function verifies that the + * two input matrices and the output matrix all have the same number of rows and + * columns. If the size check fails the functions return: + *
+ *     ARM_MATH_SIZE_MISMATCH
+ * 
+ * Otherwise the functions return + *
+ *     ARM_MATH_SUCCESS
+ * 
+ * There is some overhead associated with this matrix size checking. + * The matrix size checking is enabled via the \#define + *
+ *     ARM_MATH_MATRIX_CHECK
+ * 
+ * within the library project settings. By default this macro is defined + * and size checking is enabled. By changing the project settings and + * undefining this macro size checking is eliminated and the functions + * run a bit faster. With size checking disabled the functions always + * return ARM_MATH_SUCCESS. + */ + +/** + * @defgroup groupTransforms Transform Functions + */ + +/** + * @defgroup groupController Controller Functions + */ + +/** + * @defgroup groupStats Statistics Functions + */ +/** + * @defgroup groupSupport Support Functions + */ + +/** + * @defgroup groupInterpolation Interpolation Functions + * These functions perform 1- and 2-dimensional interpolation of data. + * Linear interpolation is used for 1-dimensional data and + * bilinear interpolation is used for 2-dimensional data. + */ + +/** + * @defgroup groupExamples Examples + */ +#ifndef _ARM_MATH_H +#define _ARM_MATH_H + +/* ignore some GCC warnings */ +#if defined ( __GNUC__ ) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-conversion" +#pragma GCC diagnostic ignored "-Wconversion" +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + +#define __CMSIS_GENERIC /* disable NVIC and Systick functions */ + +#if defined(ARM_MATH_CM7) + #include "core_cm7.h" +#elif defined (ARM_MATH_CM4) + #include "core_cm4.h" +#elif defined (ARM_MATH_CM3) + #include "core_cm3.h" +#elif defined (ARM_MATH_CM0) + #include "core_cm0.h" + #define ARM_MATH_CM0_FAMILY +#elif defined (ARM_MATH_CM0PLUS) + #include "core_cm0plus.h" + #define ARM_MATH_CM0_FAMILY +#else + #error "Define according the used Cortex core ARM_MATH_CM7, ARM_MATH_CM4, ARM_MATH_CM3, ARM_MATH_CM0PLUS or ARM_MATH_CM0" +#endif + +#undef __CMSIS_GENERIC /* enable NVIC and Systick functions */ +#include "string.h" +#include "math.h" +#ifdef __cplusplus +extern "C" +{ +#endif + + + /** + * @brief Macros required for reciprocal calculation in Normalized LMS + */ + +#define DELTA_Q31 (0x100) +#define DELTA_Q15 0x5 +#define INDEX_MASK 0x0000003F +#ifndef PI +#define PI 3.14159265358979f +#endif + + /** + * @brief Macros required for SINE and COSINE Fast math approximations + */ + +#define FAST_MATH_TABLE_SIZE 512 +#define FAST_MATH_Q31_SHIFT (32 - 10) +#define FAST_MATH_Q15_SHIFT (16 - 10) +#define CONTROLLER_Q31_SHIFT (32 - 9) +#define TABLE_SIZE 256 +#define TABLE_SPACING_Q31 0x400000 +#define TABLE_SPACING_Q15 0x80 + + /** + * @brief Macros required for SINE and COSINE Controller functions + */ + /* 1.31(q31) Fixed value of 2/360 */ + /* -1 to +1 is divided into 360 values so total spacing is (2/360) */ +#define INPUT_SPACING 0xB60B61 + + /** + * @brief Macro for Unaligned Support + */ +#ifndef UNALIGNED_SUPPORT_DISABLE + #define ALIGN4 +#else + #if defined (__GNUC__) + #define ALIGN4 __attribute__((aligned(4))) + #else + #define ALIGN4 __align(4) + #endif +#endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */ + + /** + * @brief Error status returned by some functions in the library. + */ + + typedef enum + { + ARM_MATH_SUCCESS = 0, /**< No error */ + ARM_MATH_ARGUMENT_ERROR = -1, /**< One or more arguments are incorrect */ + ARM_MATH_LENGTH_ERROR = -2, /**< Length of data buffer is incorrect */ + ARM_MATH_SIZE_MISMATCH = -3, /**< Size of matrices is not compatible with the operation. */ + ARM_MATH_NANINF = -4, /**< Not-a-number (NaN) or infinity is generated */ + ARM_MATH_SINGULAR = -5, /**< Generated by matrix inversion if the input matrix is singular and cannot be inverted. */ + ARM_MATH_TEST_FAILURE = -6 /**< Test Failed */ + } arm_status; + + /** + * @brief 8-bit fractional data type in 1.7 format. + */ + typedef int8_t q7_t; + + /** + * @brief 16-bit fractional data type in 1.15 format. + */ + typedef int16_t q15_t; + + /** + * @brief 32-bit fractional data type in 1.31 format. + */ + typedef int32_t q31_t; + + /** + * @brief 64-bit fractional data type in 1.63 format. + */ + typedef int64_t q63_t; + + /** + * @brief 32-bit floating-point type definition. + */ + typedef float float32_t; + + /** + * @brief 64-bit floating-point type definition. + */ + typedef double float64_t; + + /** + * @brief definition to read/write two 16 bit values. + */ +#if defined __CC_ARM + #define __SIMD32_TYPE int32_t __packed + #define CMSIS_UNUSED __attribute__((unused)) + +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #define __SIMD32_TYPE int32_t + #define CMSIS_UNUSED __attribute__((unused)) + +#elif defined __GNUC__ + #define __SIMD32_TYPE int32_t + #define CMSIS_UNUSED __attribute__((unused)) + +#elif defined __ICCARM__ + #define __SIMD32_TYPE int32_t __packed + #define CMSIS_UNUSED + +#elif defined __CSMC__ + #define __SIMD32_TYPE int32_t + #define CMSIS_UNUSED + +#elif defined __TASKING__ + #define __SIMD32_TYPE __unaligned int32_t + #define CMSIS_UNUSED + +#else + #error Unknown compiler +#endif + +#define __SIMD32(addr) (*(__SIMD32_TYPE **) & (addr)) +#define __SIMD32_CONST(addr) ((__SIMD32_TYPE *)(addr)) +#define _SIMD32_OFFSET(addr) (*(__SIMD32_TYPE *) (addr)) +#define __SIMD64(addr) (*(int64_t **) & (addr)) + +#if defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY) + /** + * @brief definition to pack two 16 bit values. + */ +#define __PKHBT(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0x0000FFFF) | \ + (((int32_t)(ARG2) << ARG3) & (int32_t)0xFFFF0000) ) +#define __PKHTB(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0xFFFF0000) | \ + (((int32_t)(ARG2) >> ARG3) & (int32_t)0x0000FFFF) ) + +#endif + + + /** + * @brief definition to pack four 8 bit values. + */ +#ifndef ARM_MATH_BIG_ENDIAN + +#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v0) << 0) & (int32_t)0x000000FF) | \ + (((int32_t)(v1) << 8) & (int32_t)0x0000FF00) | \ + (((int32_t)(v2) << 16) & (int32_t)0x00FF0000) | \ + (((int32_t)(v3) << 24) & (int32_t)0xFF000000) ) +#else + +#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v3) << 0) & (int32_t)0x000000FF) | \ + (((int32_t)(v2) << 8) & (int32_t)0x0000FF00) | \ + (((int32_t)(v1) << 16) & (int32_t)0x00FF0000) | \ + (((int32_t)(v0) << 24) & (int32_t)0xFF000000) ) + +#endif + + + /** + * @brief Clips Q63 to Q31 values. + */ + static __INLINE q31_t clip_q63_to_q31( + q63_t x) + { + return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ? + ((0x7FFFFFFF ^ ((q31_t) (x >> 63)))) : (q31_t) x; + } + + /** + * @brief Clips Q63 to Q15 values. + */ + static __INLINE q15_t clip_q63_to_q15( + q63_t x) + { + return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ? + ((0x7FFF ^ ((q15_t) (x >> 63)))) : (q15_t) (x >> 15); + } + + /** + * @brief Clips Q31 to Q7 values. + */ + static __INLINE q7_t clip_q31_to_q7( + q31_t x) + { + return ((q31_t) (x >> 24) != ((q31_t) x >> 23)) ? + ((0x7F ^ ((q7_t) (x >> 31)))) : (q7_t) x; + } + + /** + * @brief Clips Q31 to Q15 values. + */ + static __INLINE q15_t clip_q31_to_q15( + q31_t x) + { + return ((q31_t) (x >> 16) != ((q31_t) x >> 15)) ? + ((0x7FFF ^ ((q15_t) (x >> 31)))) : (q15_t) x; + } + + /** + * @brief Multiplies 32 X 64 and returns 32 bit result in 2.30 format. + */ + + static __INLINE q63_t mult32x64( + q63_t x, + q31_t y) + { + return ((((q63_t) (x & 0x00000000FFFFFFFF) * y) >> 32) + + (((q63_t) (x >> 32) * y))); + } + +/* + #if defined (ARM_MATH_CM0_FAMILY) && defined ( __CC_ARM ) + #define __CLZ __clz + #endif + */ +/* note: function can be removed when all toolchain support __CLZ for Cortex-M0 */ +#if defined (ARM_MATH_CM0_FAMILY) && ((defined (__ICCARM__)) ) + static __INLINE uint32_t __CLZ( + q31_t data); + + static __INLINE uint32_t __CLZ( + q31_t data) + { + uint32_t count = 0; + uint32_t mask = 0x80000000; + + while((data & mask) == 0) + { + count += 1u; + mask = mask >> 1u; + } + + return (count); + } +#endif + + /** + * @brief Function to Calculates 1/in (reciprocal) value of Q31 Data type. + */ + + static __INLINE uint32_t arm_recip_q31( + q31_t in, + q31_t * dst, + q31_t * pRecipTable) + { + q31_t out; + uint32_t tempVal; + uint32_t index, i; + uint32_t signBits; + + if(in > 0) + { + signBits = ((uint32_t) (__CLZ( in) - 1)); + } + else + { + signBits = ((uint32_t) (__CLZ(-in) - 1)); + } + + /* Convert input sample to 1.31 format */ + in = (in << signBits); + + /* calculation of index for initial approximated Val */ + index = (uint32_t)(in >> 24); + index = (index & INDEX_MASK); + + /* 1.31 with exp 1 */ + out = pRecipTable[index]; + + /* calculation of reciprocal value */ + /* running approximation for two iterations */ + for (i = 0u; i < 2u; i++) + { + tempVal = (uint32_t) (((q63_t) in * out) >> 31); + tempVal = 0x7FFFFFFFu - tempVal; + /* 1.31 with exp 1 */ + /* out = (q31_t) (((q63_t) out * tempVal) >> 30); */ + out = clip_q63_to_q31(((q63_t) out * tempVal) >> 30); + } + + /* write output */ + *dst = out; + + /* return num of signbits of out = 1/in value */ + return (signBits + 1u); + } + + + /** + * @brief Function to Calculates 1/in (reciprocal) value of Q15 Data type. + */ + static __INLINE uint32_t arm_recip_q15( + q15_t in, + q15_t * dst, + q15_t * pRecipTable) + { + q15_t out = 0; + uint32_t tempVal = 0; + uint32_t index = 0, i = 0; + uint32_t signBits = 0; + + if(in > 0) + { + signBits = ((uint32_t)(__CLZ( in) - 17)); + } + else + { + signBits = ((uint32_t)(__CLZ(-in) - 17)); + } + + /* Convert input sample to 1.15 format */ + in = (in << signBits); + + /* calculation of index for initial approximated Val */ + index = (uint32_t)(in >> 8); + index = (index & INDEX_MASK); + + /* 1.15 with exp 1 */ + out = pRecipTable[index]; + + /* calculation of reciprocal value */ + /* running approximation for two iterations */ + for (i = 0u; i < 2u; i++) + { + tempVal = (uint32_t) (((q31_t) in * out) >> 15); + tempVal = 0x7FFFu - tempVal; + /* 1.15 with exp 1 */ + out = (q15_t) (((q31_t) out * tempVal) >> 14); + /* out = clip_q31_to_q15(((q31_t) out * tempVal) >> 14); */ + } + + /* write output */ + *dst = out; + + /* return num of signbits of out = 1/in value */ + return (signBits + 1); + } + + + /* + * @brief C custom defined intrinisic function for only M0 processors + */ +#if defined(ARM_MATH_CM0_FAMILY) + static __INLINE q31_t __SSAT( + q31_t x, + uint32_t y) + { + int32_t posMax, negMin; + uint32_t i; + + posMax = 1; + for (i = 0; i < (y - 1); i++) + { + posMax = posMax * 2; + } + + if(x > 0) + { + posMax = (posMax - 1); + + if(x > posMax) + { + x = posMax; + } + } + else + { + negMin = -posMax; + + if(x < negMin) + { + x = negMin; + } + } + return (x); + } +#endif /* end of ARM_MATH_CM0_FAMILY */ + + + /* + * @brief C custom defined intrinsic function for M3 and M0 processors + */ +#if defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY) + + /* + * @brief C custom defined QADD8 for M3 and M0 processors + */ + static __INLINE uint32_t __QADD8( + uint32_t x, + uint32_t y) + { + q31_t r, s, t, u; + + r = __SSAT(((((q31_t)x << 24) >> 24) + (((q31_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF; + s = __SSAT(((((q31_t)x << 16) >> 24) + (((q31_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF; + t = __SSAT(((((q31_t)x << 8) >> 24) + (((q31_t)y << 8) >> 24)), 8) & (int32_t)0x000000FF; + u = __SSAT(((((q31_t)x ) >> 24) + (((q31_t)y ) >> 24)), 8) & (int32_t)0x000000FF; + + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r ))); + } + + + /* + * @brief C custom defined QSUB8 for M3 and M0 processors + */ + static __INLINE uint32_t __QSUB8( + uint32_t x, + uint32_t y) + { + q31_t r, s, t, u; + + r = __SSAT(((((q31_t)x << 24) >> 24) - (((q31_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF; + s = __SSAT(((((q31_t)x << 16) >> 24) - (((q31_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF; + t = __SSAT(((((q31_t)x << 8) >> 24) - (((q31_t)y << 8) >> 24)), 8) & (int32_t)0x000000FF; + u = __SSAT(((((q31_t)x ) >> 24) - (((q31_t)y ) >> 24)), 8) & (int32_t)0x000000FF; + + return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r ))); + } + + + /* + * @brief C custom defined QADD16 for M3 and M0 processors + */ + static __INLINE uint32_t __QADD16( + uint32_t x, + uint32_t y) + { +/* q31_t r, s; without initialisation 'arm_offset_q15 test' fails but 'intrinsic' tests pass! for armCC */ + q31_t r = 0, s = 0; + + r = __SSAT(((((q31_t)x << 16) >> 16) + (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) + (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SHADD16 for M3 and M0 processors + */ + static __INLINE uint32_t __SHADD16( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = (((((q31_t)x << 16) >> 16) + (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) + (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined QSUB16 for M3 and M0 processors + */ + static __INLINE uint32_t __QSUB16( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = __SSAT(((((q31_t)x << 16) >> 16) - (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) - (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SHSUB16 for M3 and M0 processors + */ + static __INLINE uint32_t __SHSUB16( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = (((((q31_t)x << 16) >> 16) - (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) - (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined QASX for M3 and M0 processors + */ + static __INLINE uint32_t __QASX( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = __SSAT(((((q31_t)x << 16) >> 16) - (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) + (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SHASX for M3 and M0 processors + */ + static __INLINE uint32_t __SHASX( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = (((((q31_t)x << 16) >> 16) - (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) + (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined QSAX for M3 and M0 processors + */ + static __INLINE uint32_t __QSAX( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = __SSAT(((((q31_t)x << 16) >> 16) + (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF; + s = __SSAT(((((q31_t)x ) >> 16) - (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SHSAX for M3 and M0 processors + */ + static __INLINE uint32_t __SHSAX( + uint32_t x, + uint32_t y) + { + q31_t r, s; + + r = (((((q31_t)x << 16) >> 16) + (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF; + s = (((((q31_t)x ) >> 16) - (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF; + + return ((uint32_t)((s << 16) | (r ))); + } + + + /* + * @brief C custom defined SMUSDX for M3 and M0 processors + */ + static __INLINE uint32_t __SMUSDX( + uint32_t x, + uint32_t y) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) - + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) )); + } + + /* + * @brief C custom defined SMUADX for M3 and M0 processors + */ + static __INLINE uint32_t __SMUADX( + uint32_t x, + uint32_t y) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) )); + } + + + /* + * @brief C custom defined QADD for M3 and M0 processors + */ + static __INLINE int32_t __QADD( + int32_t x, + int32_t y) + { + return ((int32_t)(clip_q63_to_q31((q63_t)x + (q31_t)y))); + } + + + /* + * @brief C custom defined QSUB for M3 and M0 processors + */ + static __INLINE int32_t __QSUB( + int32_t x, + int32_t y) + { + return ((int32_t)(clip_q63_to_q31((q63_t)x - (q31_t)y))); + } + + + /* + * @brief C custom defined SMLAD for M3 and M0 processors + */ + static __INLINE uint32_t __SMLAD( + uint32_t x, + uint32_t y, + uint32_t sum) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) + + ( ((q31_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMLADX for M3 and M0 processors + */ + static __INLINE uint32_t __SMLADX( + uint32_t x, + uint32_t y, + uint32_t sum) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) + + ( ((q31_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMLSDX for M3 and M0 processors + */ + static __INLINE uint32_t __SMLSDX( + uint32_t x, + uint32_t y, + uint32_t sum) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) - + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) + + ( ((q31_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMLALD for M3 and M0 processors + */ + static __INLINE uint64_t __SMLALD( + uint32_t x, + uint32_t y, + uint64_t sum) + { +/* return (sum + ((q15_t) (x >> 16) * (q15_t) (y >> 16)) + ((q15_t) x * (q15_t) y)); */ + return ((uint64_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) + + ( ((q63_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMLALDX for M3 and M0 processors + */ + static __INLINE uint64_t __SMLALDX( + uint32_t x, + uint32_t y, + uint64_t sum) + { +/* return (sum + ((q15_t) (x >> 16) * (q15_t) y)) + ((q15_t) x * (q15_t) (y >> 16)); */ + return ((uint64_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) + + ( ((q63_t)sum ) ) )); + } + + + /* + * @brief C custom defined SMUAD for M3 and M0 processors + */ + static __INLINE uint32_t __SMUAD( + uint32_t x, + uint32_t y) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) + + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) )); + } + + + /* + * @brief C custom defined SMUSD for M3 and M0 processors + */ + static __INLINE uint32_t __SMUSD( + uint32_t x, + uint32_t y) + { + return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) - + ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) )); + } + + + /* + * @brief C custom defined SXTB16 for M3 and M0 processors + */ + static __INLINE uint32_t __SXTB16( + uint32_t x) + { + return ((uint32_t)(((((q31_t)x << 24) >> 24) & (q31_t)0x0000FFFF) | + ((((q31_t)x << 8) >> 8) & (q31_t)0xFFFF0000) )); + } + +#endif /* defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY) */ + + + /** + * @brief Instance structure for the Q7 FIR filter. + */ + 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 *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + } arm_fir_instance_q7; + + /** + * @brief Instance structure for the Q15 FIR filter. + */ + 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 *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + } arm_fir_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR filter. + */ + 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 *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + } arm_fir_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR filter. + */ + 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 *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + } arm_fir_instance_f32; + + + /** + * @brief Processing function for the Q7 FIR filter. + * @param[in] S points to an instance of the Q7 FIR filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_q7( + const arm_fir_instance_q7 * S, + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q7 FIR filter. + * @param[in,out] S points to an instance of the Q7 FIR structure. + * @param[in] numTaps Number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of samples that are processed. + */ + void arm_fir_init_q7( + arm_fir_instance_q7 * S, + uint16_t numTaps, + q7_t * pCoeffs, + q7_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 FIR filter. + * @param[in] S points to an instance of the Q15 FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_q15( + const arm_fir_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the fast Q15 FIR filter for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q15 FIR filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_fast_q15( + const arm_fir_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 FIR filter. + * @param[in,out] S points to an instance of the Q15 FIR filter structure. + * @param[in] numTaps Number of filter coefficients in the filter. Must be even and greater than or equal to 4. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of samples that are processed at a time. + * @return The function returns ARM_MATH_SUCCESS if initialization was successful or ARM_MATH_ARGUMENT_ERROR if + * numTaps is not a supported value. + */ + arm_status arm_fir_init_q15( + arm_fir_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 FIR filter. + * @param[in] S points to an instance of the Q31 FIR filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_q31( + const arm_fir_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the fast Q31 FIR filter for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q31 FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_fast_q31( + const arm_fir_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 FIR filter. + * @param[in,out] S points to an instance of the Q31 FIR structure. + * @param[in] numTaps Number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of samples that are processed at a time. + */ + void arm_fir_init_q31( + arm_fir_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the floating-point FIR filter. + * @param[in] S points to an instance of the floating-point FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_f32( + const arm_fir_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point FIR filter. + * @param[in,out] S points to an instance of the floating-point FIR filter structure. + * @param[in] numTaps Number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of samples that are processed at a time. + */ + void arm_fir_init_f32( + arm_fir_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 Biquad cascade filter. + */ + typedef struct + { + int8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q15_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + q15_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + int8_t postShift; /**< Additional shift, in bits, applied to each output sample. */ + } arm_biquad_casd_df1_inst_q15; + + /** + * @brief Instance structure for the Q31 Biquad cascade filter. + */ + typedef struct + { + uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q31_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + q31_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + uint8_t postShift; /**< Additional shift, in bits, applied to each output sample. */ + } arm_biquad_casd_df1_inst_q31; + + /** + * @brief Instance structure for the floating-point Biquad cascade filter. + */ + typedef struct + { + uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + float32_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_casd_df1_inst_f32; + + + /** + * @brief Processing function for the Q15 Biquad cascade filter. + * @param[in] S points to an instance of the Q15 Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_q15( + const arm_biquad_casd_df1_inst_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 Biquad cascade filter. + * @param[in,out] S points to an instance of the Q15 Biquad cascade structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format + */ + void arm_biquad_cascade_df1_init_q15( + arm_biquad_casd_df1_inst_q15 * S, + uint8_t numStages, + q15_t * pCoeffs, + q15_t * pState, + int8_t postShift); + + + /** + * @brief Fast but less precise processing function for the Q15 Biquad cascade filter for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q15 Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_fast_q15( + const arm_biquad_casd_df1_inst_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 Biquad cascade filter + * @param[in] S points to an instance of the Q31 Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_q31( + const arm_biquad_casd_df1_inst_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fast but less precise processing function for the Q31 Biquad cascade filter for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q31 Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_fast_q31( + const arm_biquad_casd_df1_inst_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 Biquad cascade filter. + * @param[in,out] S points to an instance of the Q31 Biquad cascade structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format + */ + void arm_biquad_cascade_df1_init_q31( + arm_biquad_casd_df1_inst_q31 * S, + uint8_t numStages, + q31_t * pCoeffs, + q31_t * pState, + int8_t postShift); + + + /** + * @brief Processing function for the floating-point Biquad cascade filter. + * @param[in] S points to an instance of the floating-point Biquad cascade structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df1_f32( + const arm_biquad_casd_df1_inst_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point Biquad cascade filter. + * @param[in,out] S points to an instance of the floating-point Biquad cascade structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + */ + void arm_biquad_cascade_df1_init_f32( + arm_biquad_casd_df1_inst_f32 * S, + uint8_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Instance structure for the floating-point matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + float32_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_f32; + + + /** + * @brief Instance structure for the floating-point matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + float64_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_f64; + + /** + * @brief Instance structure for the Q15 matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + q15_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_q15; + + /** + * @brief Instance structure for the Q31 matrix structure. + */ + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + q31_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_q31; + + + /** + * @brief Floating-point matrix addition. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_add_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15 matrix addition. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_add_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst); + + + /** + * @brief Q31 matrix addition. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_add_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point, complex, matrix multiplication. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_cmplx_mult_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15, complex, matrix multiplication. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_cmplx_mult_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst, + q15_t * pScratch); + + + /** + * @brief Q31, complex, matrix multiplication. + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_cmplx_mult_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point matrix transpose. + * @param[in] pSrc points to the input matrix + * @param[out] pDst points to the output matrix + * @return The function returns either ARM_MATH_SIZE_MISMATCH + * or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_trans_f32( + const arm_matrix_instance_f32 * pSrc, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15 matrix transpose. + * @param[in] pSrc points to the input matrix + * @param[out] pDst points to the output matrix + * @return The function returns either ARM_MATH_SIZE_MISMATCH + * or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_trans_q15( + const arm_matrix_instance_q15 * pSrc, + arm_matrix_instance_q15 * pDst); + + + /** + * @brief Q31 matrix transpose. + * @param[in] pSrc points to the input matrix + * @param[out] pDst points to the output matrix + * @return The function returns either ARM_MATH_SIZE_MISMATCH + * or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_trans_q31( + const arm_matrix_instance_q31 * pSrc, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point matrix multiplication + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_mult_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15 matrix multiplication + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @param[in] pState points to the array for storing intermediate results + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_mult_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst, + q15_t * pState); + + + /** + * @brief Q15 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @param[in] pState points to the array for storing intermediate results + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_mult_fast_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst, + q15_t * pState); + + + /** + * @brief Q31 matrix multiplication + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_mult_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Q31 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_mult_fast_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point matrix subtraction + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_sub_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15 matrix subtraction + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_sub_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst); + + + /** + * @brief Q31 matrix subtraction + * @param[in] pSrcA points to the first input matrix structure + * @param[in] pSrcB points to the second input matrix structure + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_sub_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point matrix scaling. + * @param[in] pSrc points to the input matrix + * @param[in] scale scale factor + * @param[out] pDst points to the output matrix + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_scale_f32( + const arm_matrix_instance_f32 * pSrc, + float32_t scale, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15 matrix scaling. + * @param[in] pSrc points to input matrix + * @param[in] scaleFract fractional portion of the scale factor + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to output matrix + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_scale_q15( + const arm_matrix_instance_q15 * pSrc, + q15_t scaleFract, + int32_t shift, + arm_matrix_instance_q15 * pDst); + + + /** + * @brief Q31 matrix scaling. + * @param[in] pSrc points to input matrix + * @param[in] scaleFract fractional portion of the scale factor + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + arm_status arm_mat_scale_q31( + const arm_matrix_instance_q31 * pSrc, + q31_t scaleFract, + int32_t shift, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Q31 matrix initialization. + * @param[in,out] S points to an instance of the floating-point matrix structure. + * @param[in] nRows number of rows in the matrix. + * @param[in] nColumns number of columns in the matrix. + * @param[in] pData points to the matrix data array. + */ + void arm_mat_init_q31( + arm_matrix_instance_q31 * S, + uint16_t nRows, + uint16_t nColumns, + q31_t * pData); + + + /** + * @brief Q15 matrix initialization. + * @param[in,out] S points to an instance of the floating-point matrix structure. + * @param[in] nRows number of rows in the matrix. + * @param[in] nColumns number of columns in the matrix. + * @param[in] pData points to the matrix data array. + */ + void arm_mat_init_q15( + arm_matrix_instance_q15 * S, + uint16_t nRows, + uint16_t nColumns, + q15_t * pData); + + + /** + * @brief Floating-point matrix initialization. + * @param[in,out] S points to an instance of the floating-point matrix structure. + * @param[in] nRows number of rows in the matrix. + * @param[in] nColumns number of columns in the matrix. + * @param[in] pData points to the matrix data array. + */ + void arm_mat_init_f32( + arm_matrix_instance_f32 * S, + uint16_t nRows, + uint16_t nColumns, + float32_t * pData); + + + + /** + * @brief Instance structure for the Q15 PID Control. + */ + typedef struct + { + q15_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ +#ifdef ARM_MATH_CM0_FAMILY + q15_t A1; + q15_t A2; +#else + q31_t A1; /**< The derived gain A1 = -Kp - 2Kd | Kd.*/ +#endif + q15_t state[3]; /**< The state array of length 3. */ + q15_t Kp; /**< The proportional gain. */ + q15_t Ki; /**< The integral gain. */ + q15_t Kd; /**< The derivative gain. */ + } arm_pid_instance_q15; + + /** + * @brief Instance structure for the Q31 PID Control. + */ + typedef struct + { + q31_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ + q31_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */ + q31_t A2; /**< The derived gain, A2 = Kd . */ + q31_t state[3]; /**< The state array of length 3. */ + q31_t Kp; /**< The proportional gain. */ + q31_t Ki; /**< The integral gain. */ + q31_t Kd; /**< The derivative gain. */ + } arm_pid_instance_q31; + + /** + * @brief Instance structure for the floating-point PID Control. + */ + typedef struct + { + float32_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ + float32_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */ + float32_t A2; /**< The derived gain, A2 = Kd . */ + float32_t state[3]; /**< The state array of length 3. */ + float32_t Kp; /**< The proportional gain. */ + float32_t Ki; /**< The integral gain. */ + float32_t Kd; /**< The derivative gain. */ + } arm_pid_instance_f32; + + + + /** + * @brief Initialization function for the floating-point PID Control. + * @param[in,out] S points to an instance of the PID structure. + * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. + */ + void arm_pid_init_f32( + arm_pid_instance_f32 * S, + int32_t resetStateFlag); + + + /** + * @brief Reset function for the floating-point PID Control. + * @param[in,out] S is an instance of the floating-point PID Control structure + */ + void arm_pid_reset_f32( + arm_pid_instance_f32 * S); + + + /** + * @brief Initialization function for the Q31 PID Control. + * @param[in,out] S points to an instance of the Q15 PID structure. + * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. + */ + void arm_pid_init_q31( + arm_pid_instance_q31 * S, + int32_t resetStateFlag); + + + /** + * @brief Reset function for the Q31 PID Control. + * @param[in,out] S points to an instance of the Q31 PID Control structure + */ + + void arm_pid_reset_q31( + arm_pid_instance_q31 * S); + + + /** + * @brief Initialization function for the Q15 PID Control. + * @param[in,out] S points to an instance of the Q15 PID structure. + * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. + */ + void arm_pid_init_q15( + arm_pid_instance_q15 * S, + int32_t resetStateFlag); + + + /** + * @brief Reset function for the Q15 PID Control. + * @param[in,out] S points to an instance of the q15 PID Control structure + */ + void arm_pid_reset_q15( + arm_pid_instance_q15 * S); + + + /** + * @brief Instance structure for the floating-point Linear Interpolate function. + */ + typedef struct + { + uint32_t nValues; /**< nValues */ + float32_t x1; /**< x1 */ + float32_t xSpacing; /**< xSpacing */ + float32_t *pYData; /**< pointer to the table of Y values */ + } arm_linear_interp_instance_f32; + + /** + * @brief Instance structure for the floating-point bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + float32_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_f32; + + /** + * @brief Instance structure for the Q31 bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q31_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_q31; + + /** + * @brief Instance structure for the Q15 bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q15_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_q15; + + /** + * @brief Instance structure for the Q15 bilinear interpolation function. + */ + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q7_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_q7; + + + /** + * @brief Q7 vector multiplication. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_mult_q7( + q7_t * pSrcA, + q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q15 vector multiplication. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_mult_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q31 vector multiplication. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_mult_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Floating-point vector multiplication. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_mult_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q15_t *pTwiddle; /**< points to the Sin twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix2_instance_q15; + +/* Deprecated */ + arm_status arm_cfft_radix2_init_q15( + arm_cfft_radix2_instance_q15 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix2_q15( + const arm_cfft_radix2_instance_q15 * S, + q15_t * pSrc); + + + /** + * @brief Instance structure for the Q15 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q15_t *pTwiddle; /**< points to the twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix4_instance_q15; + +/* Deprecated */ + arm_status arm_cfft_radix4_init_q15( + arm_cfft_radix4_instance_q15 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix4_q15( + const arm_cfft_radix4_instance_q15 * S, + q15_t * pSrc); + + /** + * @brief Instance structure for the Radix-2 Q31 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q31_t *pTwiddle; /**< points to the Twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix2_instance_q31; + +/* Deprecated */ + arm_status arm_cfft_radix2_init_q31( + arm_cfft_radix2_instance_q31 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix2_q31( + const arm_cfft_radix2_instance_q31 * S, + q31_t * pSrc); + + /** + * @brief Instance structure for the Q31 CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q31_t *pTwiddle; /**< points to the twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix4_instance_q31; + +/* Deprecated */ + void arm_cfft_radix4_q31( + const arm_cfft_radix4_instance_q31 * S, + q31_t * pSrc); + +/* Deprecated */ + arm_status arm_cfft_radix4_init_q31( + arm_cfft_radix4_instance_q31 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + float32_t onebyfftLen; /**< value of 1/fftLen. */ + } arm_cfft_radix2_instance_f32; + +/* Deprecated */ + arm_status arm_cfft_radix2_init_f32( + arm_cfft_radix2_instance_f32 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix2_f32( + const arm_cfft_radix2_instance_f32 * S, + float32_t * pSrc); + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + float32_t onebyfftLen; /**< value of 1/fftLen. */ + } arm_cfft_radix4_instance_f32; + +/* Deprecated */ + arm_status arm_cfft_radix4_init_f32( + arm_cfft_radix4_instance_f32 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + +/* Deprecated */ + void arm_cfft_radix4_f32( + const arm_cfft_radix4_instance_f32 * S, + float32_t * pSrc); + + /** + * @brief Instance structure for the fixed-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + const q15_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ + } arm_cfft_instance_q15; + +void arm_cfft_q15( + const arm_cfft_instance_q15 * S, + q15_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the fixed-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + const q31_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ + } arm_cfft_instance_q31; + +void arm_cfft_q31( + const arm_cfft_instance_q31 * S, + q31_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + const float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + const uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t bitRevLength; /**< bit reversal table length. */ + } arm_cfft_instance_f32; + + void arm_cfft_f32( + const arm_cfft_instance_f32 * S, + float32_t * p1, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Instance structure for the Q15 RFFT/RIFFT function. + */ + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + q15_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + q15_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ + const arm_cfft_instance_q15 *pCfft; /**< points to the complex FFT instance. */ + } arm_rfft_instance_q15; + + arm_status arm_rfft_init_q15( + arm_rfft_instance_q15 * S, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + void arm_rfft_q15( + const arm_rfft_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst); + + /** + * @brief Instance structure for the Q31 RFFT/RIFFT function. + */ + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + q31_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + q31_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ + const arm_cfft_instance_q31 *pCfft; /**< points to the complex FFT instance. */ + } arm_rfft_instance_q31; + + arm_status arm_rfft_init_q31( + arm_rfft_instance_q31 * S, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + void arm_rfft_q31( + const arm_rfft_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst); + + /** + * @brief Instance structure for the floating-point RFFT/RIFFT function. + */ + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint16_t fftLenBy2; /**< length of the complex FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + float32_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + float32_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ + arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */ + } arm_rfft_instance_f32; + + arm_status arm_rfft_init_f32( + arm_rfft_instance_f32 * S, + arm_cfft_radix4_instance_f32 * S_CFFT, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + void arm_rfft_f32( + const arm_rfft_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst); + + /** + * @brief Instance structure for the floating-point RFFT/RIFFT function. + */ +typedef struct + { + arm_cfft_instance_f32 Sint; /**< Internal CFFT structure. */ + uint16_t fftLenRFFT; /**< length of the real sequence */ + float32_t * pTwiddleRFFT; /**< Twiddle factors real stage */ + } arm_rfft_fast_instance_f32 ; + +arm_status arm_rfft_fast_init_f32 ( + arm_rfft_fast_instance_f32 * S, + uint16_t fftLen); + +void arm_rfft_fast_f32( + arm_rfft_fast_instance_f32 * S, + float32_t * p, float32_t * pOut, + uint8_t ifftFlag); + + /** + * @brief Instance structure for the floating-point DCT4/IDCT4 function. + */ + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + float32_t normalize; /**< normalizing factor. */ + float32_t *pTwiddle; /**< points to the twiddle factor table. */ + float32_t *pCosFactor; /**< points to the cosFactor table. */ + arm_rfft_instance_f32 *pRfft; /**< points to the real FFT instance. */ + arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */ + } arm_dct4_instance_f32; + + + /** + * @brief Initialization function for the floating-point DCT4/IDCT4. + * @param[in,out] S points to an instance of floating-point DCT4/IDCT4 structure. + * @param[in] S_RFFT points to an instance of floating-point RFFT/RIFFT structure. + * @param[in] S_CFFT points to an instance of floating-point CFFT/CIFFT structure. + * @param[in] N length of the DCT4. + * @param[in] Nby2 half of the length of the DCT4. + * @param[in] normalize normalizing factor. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLenReal is not a supported transform length. + */ + arm_status arm_dct4_init_f32( + arm_dct4_instance_f32 * S, + arm_rfft_instance_f32 * S_RFFT, + arm_cfft_radix4_instance_f32 * S_CFFT, + uint16_t N, + uint16_t Nby2, + float32_t normalize); + + + /** + * @brief Processing function for the floating-point DCT4/IDCT4. + * @param[in] S points to an instance of the floating-point DCT4/IDCT4 structure. + * @param[in] pState points to state buffer. + * @param[in,out] pInlineBuffer points to the in-place input and output buffer. + */ + void arm_dct4_f32( + const arm_dct4_instance_f32 * S, + float32_t * pState, + float32_t * pInlineBuffer); + + + /** + * @brief Instance structure for the Q31 DCT4/IDCT4 function. + */ + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + q31_t normalize; /**< normalizing factor. */ + q31_t *pTwiddle; /**< points to the twiddle factor table. */ + q31_t *pCosFactor; /**< points to the cosFactor table. */ + arm_rfft_instance_q31 *pRfft; /**< points to the real FFT instance. */ + arm_cfft_radix4_instance_q31 *pCfft; /**< points to the complex FFT instance. */ + } arm_dct4_instance_q31; + + + /** + * @brief Initialization function for the Q31 DCT4/IDCT4. + * @param[in,out] S points to an instance of Q31 DCT4/IDCT4 structure. + * @param[in] S_RFFT points to an instance of Q31 RFFT/RIFFT structure + * @param[in] S_CFFT points to an instance of Q31 CFFT/CIFFT structure + * @param[in] N length of the DCT4. + * @param[in] Nby2 half of the length of the DCT4. + * @param[in] normalize normalizing factor. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if N is not a supported transform length. + */ + arm_status arm_dct4_init_q31( + arm_dct4_instance_q31 * S, + arm_rfft_instance_q31 * S_RFFT, + arm_cfft_radix4_instance_q31 * S_CFFT, + uint16_t N, + uint16_t Nby2, + q31_t normalize); + + + /** + * @brief Processing function for the Q31 DCT4/IDCT4. + * @param[in] S points to an instance of the Q31 DCT4 structure. + * @param[in] pState points to state buffer. + * @param[in,out] pInlineBuffer points to the in-place input and output buffer. + */ + void arm_dct4_q31( + const arm_dct4_instance_q31 * S, + q31_t * pState, + q31_t * pInlineBuffer); + + + /** + * @brief Instance structure for the Q15 DCT4/IDCT4 function. + */ + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + q15_t normalize; /**< normalizing factor. */ + q15_t *pTwiddle; /**< points to the twiddle factor table. */ + q15_t *pCosFactor; /**< points to the cosFactor table. */ + arm_rfft_instance_q15 *pRfft; /**< points to the real FFT instance. */ + arm_cfft_radix4_instance_q15 *pCfft; /**< points to the complex FFT instance. */ + } arm_dct4_instance_q15; + + + /** + * @brief Initialization function for the Q15 DCT4/IDCT4. + * @param[in,out] S points to an instance of Q15 DCT4/IDCT4 structure. + * @param[in] S_RFFT points to an instance of Q15 RFFT/RIFFT structure. + * @param[in] S_CFFT points to an instance of Q15 CFFT/CIFFT structure. + * @param[in] N length of the DCT4. + * @param[in] Nby2 half of the length of the DCT4. + * @param[in] normalize normalizing factor. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if N is not a supported transform length. + */ + arm_status arm_dct4_init_q15( + arm_dct4_instance_q15 * S, + arm_rfft_instance_q15 * S_RFFT, + arm_cfft_radix4_instance_q15 * S_CFFT, + uint16_t N, + uint16_t Nby2, + q15_t normalize); + + + /** + * @brief Processing function for the Q15 DCT4/IDCT4. + * @param[in] S points to an instance of the Q15 DCT4 structure. + * @param[in] pState points to state buffer. + * @param[in,out] pInlineBuffer points to the in-place input and output buffer. + */ + void arm_dct4_q15( + const arm_dct4_instance_q15 * S, + q15_t * pState, + q15_t * pInlineBuffer); + + + /** + * @brief Floating-point vector addition. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_add_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q7 vector addition. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_add_q7( + q7_t * pSrcA, + q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q15 vector addition. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_add_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q31 vector addition. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_add_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Floating-point vector subtraction. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_sub_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q7 vector subtraction. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_sub_q7( + q7_t * pSrcA, + q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q15 vector subtraction. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_sub_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q31 vector subtraction. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in each vector + */ + void arm_sub_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Multiplies a floating-point vector by a scalar. + * @param[in] pSrc points to the input vector + * @param[in] scale scale factor to be applied + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_scale_f32( + float32_t * pSrc, + float32_t scale, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Multiplies a Q7 vector by a scalar. + * @param[in] pSrc points to the input vector + * @param[in] scaleFract fractional portion of the scale value + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_scale_q7( + q7_t * pSrc, + q7_t scaleFract, + int8_t shift, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Multiplies a Q15 vector by a scalar. + * @param[in] pSrc points to the input vector + * @param[in] scaleFract fractional portion of the scale value + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_scale_q15( + q15_t * pSrc, + q15_t scaleFract, + int8_t shift, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Multiplies a Q31 vector by a scalar. + * @param[in] pSrc points to the input vector + * @param[in] scaleFract fractional portion of the scale value + * @param[in] shift number of bits to shift the result by + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_scale_q31( + q31_t * pSrc, + q31_t scaleFract, + int8_t shift, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q7 vector absolute value. + * @param[in] pSrc points to the input buffer + * @param[out] pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + */ + void arm_abs_q7( + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Floating-point vector absolute value. + * @param[in] pSrc points to the input buffer + * @param[out] pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + */ + void arm_abs_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q15 vector absolute value. + * @param[in] pSrc points to the input buffer + * @param[out] pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + */ + void arm_abs_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Q31 vector absolute value. + * @param[in] pSrc points to the input buffer + * @param[out] pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + */ + void arm_abs_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Dot product of floating-point vectors. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] result output result returned here + */ + void arm_dot_prod_f32( + float32_t * pSrcA, + float32_t * pSrcB, + uint32_t blockSize, + float32_t * result); + + + /** + * @brief Dot product of Q7 vectors. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] result output result returned here + */ + void arm_dot_prod_q7( + q7_t * pSrcA, + q7_t * pSrcB, + uint32_t blockSize, + q31_t * result); + + + /** + * @brief Dot product of Q15 vectors. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] result output result returned here + */ + void arm_dot_prod_q15( + q15_t * pSrcA, + q15_t * pSrcB, + uint32_t blockSize, + q63_t * result); + + + /** + * @brief Dot product of Q31 vectors. + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] result output result returned here + */ + void arm_dot_prod_q31( + q31_t * pSrcA, + q31_t * pSrcB, + uint32_t blockSize, + q63_t * result); + + + /** + * @brief Shifts the elements of a Q7 vector a specified number of bits. + * @param[in] pSrc points to the input vector + * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_shift_q7( + q7_t * pSrc, + int8_t shiftBits, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Shifts the elements of a Q15 vector a specified number of bits. + * @param[in] pSrc points to the input vector + * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_shift_q15( + q15_t * pSrc, + int8_t shiftBits, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Shifts the elements of a Q31 vector a specified number of bits. + * @param[in] pSrc points to the input vector + * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_shift_q31( + q31_t * pSrc, + int8_t shiftBits, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Adds a constant offset to a floating-point vector. + * @param[in] pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_offset_f32( + float32_t * pSrc, + float32_t offset, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Adds a constant offset to a Q7 vector. + * @param[in] pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_offset_q7( + q7_t * pSrc, + q7_t offset, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Adds a constant offset to a Q15 vector. + * @param[in] pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_offset_q15( + q15_t * pSrc, + q15_t offset, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Adds a constant offset to a Q31 vector. + * @param[in] pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_offset_q31( + q31_t * pSrc, + q31_t offset, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Negates the elements of a floating-point vector. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_negate_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Negates the elements of a Q7 vector. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_negate_q7( + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Negates the elements of a Q15 vector. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_negate_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Negates the elements of a Q31 vector. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] blockSize number of samples in the vector + */ + void arm_negate_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Copies the elements of a floating-point vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_copy_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Copies the elements of a Q7 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_copy_q7( + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Copies the elements of a Q15 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_copy_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Copies the elements of a Q31 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_copy_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fills a constant value into a floating-point vector. + * @param[in] value input value to be filled + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_fill_f32( + float32_t value, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fills a constant value into a Q7 vector. + * @param[in] value input value to be filled + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_fill_q7( + q7_t value, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fills a constant value into a Q15 vector. + * @param[in] value input value to be filled + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_fill_q15( + q15_t value, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Fills a constant value into a Q31 vector. + * @param[in] value input value to be filled + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_fill_q31( + q31_t value, + q31_t * pDst, + uint32_t blockSize); + + +/** + * @brief Convolution of floating-point sequences. + * @param[in] pSrcA points to the first input sequence. + * @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. + */ + void arm_conv_f32( + float32_t * pSrcA, + uint32_t srcALen, + float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst); + + + /** + * @brief Convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @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[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). + */ + void arm_conv_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + +/** + * @brief Convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @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. + */ + void arm_conv_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + + /** + * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @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. + */ + void arm_conv_fast_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + + /** + * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @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[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). + */ + void arm_conv_fast_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Convolution of Q31 sequences. + * @param[in] pSrcA points to the first input sequence. + * @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. + */ + void arm_conv_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + + /** + * @brief Convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @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. + */ + void arm_conv_fast_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + + /** + * @brief Convolution of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @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[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). + */ + void arm_conv_opt_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Convolution of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @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. + */ + void arm_conv_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst); + + + /** + * @brief Partial convolution of floating-point sequences. + * @param[in] pSrcA points to the first input sequence. + * @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 + * @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]. + */ + arm_status arm_conv_partial_f32( + float32_t * pSrcA, + uint32_t srcALen, + float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @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 + * @param[in] firstIndex is the first output sample to start with. + * @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]. + */ + arm_status arm_conv_partial_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Partial convolution of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @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 + * @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]. + */ + arm_status arm_conv_partial_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @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 + * @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]. + */ + arm_status arm_conv_partial_fast_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @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 + * @param[in] firstIndex is the first output sample to start with. + * @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]. + */ + arm_status arm_conv_partial_fast_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Partial convolution of Q31 sequences. + * @param[in] pSrcA points to the first input sequence. + * @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 + * @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]. + */ + arm_status arm_conv_partial_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @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 + * @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]. + */ + arm_status arm_conv_partial_fast_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q7 sequences + * @param[in] pSrcA points to the first input sequence. + * @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 + * @param[in] firstIndex is the first output sample to start with. + * @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]. + */ + arm_status arm_conv_partial_opt_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + +/** + * @brief Partial convolution of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @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 + * @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]. + */ + arm_status arm_conv_partial_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Instance structure for the Q15 FIR decimator. + */ + typedef struct + { + 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. */ + } arm_fir_decimate_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR decimator. + */ + typedef struct + { + 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. */ + } arm_fir_decimate_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR decimator. + */ + typedef struct + { + 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. */ + } arm_fir_decimate_instance_f32; + + + /** + * @brief Processing function for the floating-point FIR decimator. + * @param[in] S points to an instance of the floating-point FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_f32( + const arm_fir_decimate_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point FIR decimator. + * @param[in,out] S points to an instance of the floating-point FIR decimator structure. + * @param[in] numTaps number of coefficients in the filter. + * @param[in] M decimation factor. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * blockSize is not a multiple of M. + */ + arm_status arm_fir_decimate_init_f32( + arm_fir_decimate_instance_f32 * S, + uint16_t numTaps, + uint8_t M, + float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 FIR decimator. + * @param[in] S points to an instance of the Q15 FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_q15( + const arm_fir_decimate_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q15 FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_fast_q15( + const arm_fir_decimate_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 FIR decimator. + * @param[in,out] S points to an instance of the Q15 FIR decimator structure. + * @param[in] numTaps number of coefficients in the filter. + * @param[in] M decimation factor. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * blockSize is not a multiple of M. + */ + arm_status arm_fir_decimate_init_q15( + arm_fir_decimate_instance_q15 * S, + uint16_t numTaps, + uint8_t M, + q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 FIR decimator. + * @param[in] S points to an instance of the Q31 FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_q31( + const arm_fir_decimate_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Processing function for the Q31 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4. + * @param[in] S points to an instance of the Q31 FIR decimator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_decimate_fast_q31( + arm_fir_decimate_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 FIR decimator. + * @param[in,out] S points to an instance of the Q31 FIR decimator structure. + * @param[in] numTaps number of coefficients in the filter. + * @param[in] M decimation factor. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * blockSize is not a multiple of M. + */ + arm_status arm_fir_decimate_init_q31( + arm_fir_decimate_instance_q31 * S, + uint16_t numTaps, + uint8_t M, + q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 FIR interpolator. + */ + typedef struct + { + 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. */ + } arm_fir_interpolate_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR interpolator. + */ + typedef struct + { + 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. */ + } arm_fir_interpolate_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR interpolator. + */ + typedef struct + { + 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. */ + } arm_fir_interpolate_instance_f32; + + + /** + * @brief Processing function for the Q15 FIR interpolator. + * @param[in] S points to an instance of the Q15 FIR interpolator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_interpolate_q15( + const arm_fir_interpolate_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 FIR interpolator. + * @param[in,out] S points to an instance of the Q15 FIR interpolator structure. + * @param[in] L upsample factor. + * @param[in] numTaps number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficient buffer. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * the filter length numTaps is not a multiple of the interpolation factor L. + */ + arm_status arm_fir_interpolate_init_q15( + arm_fir_interpolate_instance_q15 * S, + uint8_t L, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 FIR interpolator. + * @param[in] S points to an instance of the Q15 FIR interpolator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_interpolate_q31( + const arm_fir_interpolate_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 FIR interpolator. + * @param[in,out] S points to an instance of the Q31 FIR interpolator structure. + * @param[in] L upsample factor. + * @param[in] numTaps number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficient buffer. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * the filter length numTaps is not a multiple of the interpolation factor L. + */ + arm_status arm_fir_interpolate_init_q31( + arm_fir_interpolate_instance_q31 * S, + uint8_t L, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the floating-point FIR interpolator. + * @param[in] S points to an instance of the floating-point FIR interpolator structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_interpolate_f32( + const arm_fir_interpolate_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point FIR interpolator. + * @param[in,out] S points to an instance of the floating-point FIR interpolator structure. + * @param[in] L upsample factor. + * @param[in] numTaps number of filter coefficients in the filter. + * @param[in] pCoeffs points to the filter coefficient buffer. + * @param[in] pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * the filter length numTaps is not a multiple of the interpolation factor L. + */ + arm_status arm_fir_interpolate_init_f32( + arm_fir_interpolate_instance_f32 * S, + uint8_t L, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the high precision Q31 Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q63_t *pState; /**< points to the array of state coefficients. The array is of length 4*numStages. */ + q31_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + uint8_t postShift; /**< additional shift, in bits, applied to each output sample. */ + } arm_biquad_cas_df1_32x64_ins_q31; + + + /** + * @param[in] S points to an instance of the high precision Q31 Biquad cascade filter structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cas_df1_32x64_q31( + const arm_biquad_cas_df1_32x64_ins_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @param[in,out] S points to an instance of the high precision Q31 Biquad cascade filter structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] postShift shift to be applied to the output. Varies according to the coefficients format + */ + void arm_biquad_cas_df1_32x64_init_q31( + arm_biquad_cas_df1_32x64_ins_q31 * S, + uint8_t numStages, + q31_t * pCoeffs, + q63_t * pState, + uint8_t postShift); + + + /** + * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< points to the array of state coefficients. The array is of length 2*numStages. */ + float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_cascade_df2T_instance_f32; + + /** + * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< points to the array of state coefficients. The array is of length 4*numStages. */ + float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_cascade_stereo_df2T_instance_f32; + + /** + * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. + */ + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float64_t *pState; /**< points to the array of state coefficients. The array is of length 2*numStages. */ + float64_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_cascade_df2T_instance_f64; + + + /** + * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in] S points to an instance of the filter data structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df2T_f32( + const arm_biquad_cascade_df2T_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. 2 channels + * @param[in] S points to an instance of the filter data structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_stereo_df2T_f32( + const arm_biquad_cascade_stereo_df2T_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in] S points to an instance of the filter data structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_biquad_cascade_df2T_f64( + const arm_biquad_cascade_df2T_instance_f64 * S, + float64_t * pSrc, + float64_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in,out] S points to an instance of the filter data structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + */ + void arm_biquad_cascade_df2T_init_f32( + arm_biquad_cascade_df2T_instance_f32 * S, + uint8_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in,out] S points to an instance of the filter data structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + */ + void arm_biquad_cascade_stereo_df2T_init_f32( + arm_biquad_cascade_stereo_df2T_instance_f32 * S, + uint8_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in,out] S points to an instance of the filter data structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] pCoeffs points to the filter coefficients. + * @param[in] pState points to the state buffer. + */ + void arm_biquad_cascade_df2T_init_f64( + arm_biquad_cascade_df2T_instance_f64 * S, + uint8_t numStages, + float64_t * pCoeffs, + float64_t * pState); + + + /** + * @brief Instance structure for the Q15 FIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + q15_t *pState; /**< points to the state variable array. The array is of length numStages. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } arm_fir_lattice_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + q31_t *pState; /**< points to the state variable array. The array is of length numStages. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } arm_fir_lattice_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + float32_t *pState; /**< points to the state variable array. The array is of length numStages. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } arm_fir_lattice_instance_f32; + + + /** + * @brief Initialization function for the Q15 FIR lattice filter. + * @param[in] S points to an instance of the Q15 FIR lattice structure. + * @param[in] numStages number of filter stages. + * @param[in] pCoeffs points to the coefficient buffer. The array is of length numStages. + * @param[in] pState points to the state buffer. The array is of length numStages. + */ + void arm_fir_lattice_init_q15( + arm_fir_lattice_instance_q15 * S, + uint16_t numStages, + q15_t * pCoeffs, + q15_t * pState); + + + /** + * @brief Processing function for the Q15 FIR lattice filter. + * @param[in] S points to an instance of the Q15 FIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_fir_lattice_q15( + const arm_fir_lattice_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 FIR lattice filter. + * @param[in] S points to an instance of the Q31 FIR lattice structure. + * @param[in] numStages number of filter stages. + * @param[in] pCoeffs points to the coefficient buffer. The array is of length numStages. + * @param[in] pState points to the state buffer. The array is of length numStages. + */ + void arm_fir_lattice_init_q31( + arm_fir_lattice_instance_q31 * S, + uint16_t numStages, + q31_t * pCoeffs, + q31_t * pState); + + + /** + * @brief Processing function for the Q31 FIR lattice filter. + * @param[in] S points to an instance of the Q31 FIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_fir_lattice_q31( + const arm_fir_lattice_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + +/** + * @brief Initialization function for the floating-point FIR lattice filter. + * @param[in] S points to an instance of the floating-point FIR lattice structure. + * @param[in] numStages number of filter stages. + * @param[in] pCoeffs points to the coefficient buffer. The array is of length numStages. + * @param[in] pState points to the state buffer. The array is of length numStages. + */ + void arm_fir_lattice_init_f32( + arm_fir_lattice_instance_f32 * S, + uint16_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Processing function for the floating-point FIR lattice filter. + * @param[in] S points to an instance of the floating-point FIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] blockSize number of samples to process. + */ + void arm_fir_lattice_f32( + const arm_fir_lattice_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 IIR lattice filter. + */ + 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 *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. */ + } arm_iir_lattice_instance_q15; + + /** + * @brief Instance structure for the Q31 IIR lattice filter. + */ + 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 *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. */ + } arm_iir_lattice_instance_q31; + + /** + * @brief Instance structure for the floating-point IIR lattice filter. + */ + 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 *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. */ + } arm_iir_lattice_instance_f32; + + + /** + * @brief Processing function for the floating-point IIR lattice filter. + * @param[in] S points to an instance of the floating-point IIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_f32( + const arm_iir_lattice_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point IIR lattice filter. + * @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] blockSize number of samples to process. + */ + void arm_iir_lattice_init_f32( + arm_iir_lattice_instance_f32 * S, + uint16_t numStages, + float32_t * pkCoeffs, + float32_t * pvCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 IIR lattice filter. + * @param[in] S points to an instance of the Q31 IIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_q31( + const arm_iir_lattice_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 IIR lattice filter. + * @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] blockSize number of samples to process. + */ + void arm_iir_lattice_init_q31( + arm_iir_lattice_instance_q31 * S, + uint16_t numStages, + q31_t * pkCoeffs, + q31_t * pvCoeffs, + q31_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 IIR lattice filter. + * @param[in] S points to an instance of the Q15 IIR lattice structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + */ + void arm_iir_lattice_q15( + const arm_iir_lattice_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + +/** + * @brief Initialization function for the Q15 IIR lattice filter. + * @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] blockSize number of samples to process per call. + */ + void arm_iir_lattice_init_q15( + arm_iir_lattice_instance_q15 * S, + uint16_t numStages, + q15_t * pkCoeffs, + q15_t * pvCoeffs, + q15_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the floating-point LMS filter. + */ + 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 *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; + + + /** + * @brief Processing function for floating-point LMS filter. + * @param[in] S points to an instance of the floating-point LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_f32( + const arm_lms_instance_f32 * S, + float32_t * pSrc, + float32_t * pRef, + float32_t * pOut, + float32_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for floating-point LMS filter. + * @param[in] S points to an instance of the floating-point LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to the coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_init_f32( + arm_lms_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + float32_t mu, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 LMS filter. + */ + 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 *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. */ + } arm_lms_instance_q15; + + + /** + * @brief Initialization function for the Q15 LMS filter. + * @param[in] S points to an instance of the Q15 LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to the coefficient buffer. + * @param[in] pState points to the state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + */ + void arm_lms_init_q15( + arm_lms_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + q15_t mu, + uint32_t blockSize, + uint32_t postShift); + + + /** + * @brief Processing function for Q15 LMS filter. + * @param[in] S points to an instance of the Q15 LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_q15( + const arm_lms_instance_q15 * S, + q15_t * pSrc, + q15_t * pRef, + q15_t * pOut, + q15_t * pErr, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q31 LMS filter. + */ + 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 *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. */ + } arm_lms_instance_q31; + + + /** + * @brief Processing function for Q31 LMS filter. + * @param[in] S points to an instance of the Q15 LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_q31( + const arm_lms_instance_q31 * S, + q31_t * pSrc, + q31_t * pRef, + q31_t * pOut, + q31_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for Q31 LMS filter. + * @param[in] S points to an instance of the Q31 LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + */ + void arm_lms_init_q31( + arm_lms_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + q31_t mu, + uint32_t blockSize, + uint32_t postShift); + + + /** + * @brief Instance structure for the floating-point normalized LMS filter. + */ + 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 *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. */ + float32_t x0; /**< saves previous input sample. */ + } arm_lms_norm_instance_f32; + + + /** + * @brief Processing function for floating-point normalized LMS filter. + * @param[in] S points to an instance of the floating-point normalized LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_norm_f32( + arm_lms_norm_instance_f32 * S, + float32_t * pSrc, + float32_t * pRef, + float32_t * pOut, + float32_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for floating-point normalized LMS filter. + * @param[in] S points to an instance of the floating-point LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_norm_init_f32( + arm_lms_norm_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + float32_t mu, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q31 normalized LMS filter. + */ + 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 *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. */ + q31_t *recipTable; /**< points to the reciprocal initial value table. */ + q31_t energy; /**< saves previous frame energy. */ + q31_t x0; /**< saves previous input sample. */ + } arm_lms_norm_instance_q31; + + + /** + * @brief Processing function for Q31 normalized LMS filter. + * @param[in] S points to an instance of the Q31 normalized LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_norm_q31( + arm_lms_norm_instance_q31 * S, + q31_t * pSrc, + q31_t * pRef, + q31_t * pOut, + q31_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for Q31 normalized LMS filter. + * @param[in] S points to an instance of the Q31 normalized LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + */ + void arm_lms_norm_init_q31( + arm_lms_norm_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + q31_t mu, + uint32_t blockSize, + uint8_t postShift); + + + /** + * @brief Instance structure for the Q15 normalized LMS filter. + */ + 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 *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. */ + q15_t *recipTable; /**< Points to the reciprocal initial value table. */ + q15_t energy; /**< saves previous frame energy. */ + q15_t x0; /**< saves previous input sample. */ + } arm_lms_norm_instance_q15; + + + /** + * @brief Processing function for Q15 normalized LMS filter. + * @param[in] S points to an instance of the Q15 normalized LMS filter structure. + * @param[in] pSrc points to the block of input data. + * @param[in] pRef points to the block of reference data. + * @param[out] pOut points to the block of output data. + * @param[out] pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + */ + void arm_lms_norm_q15( + arm_lms_norm_instance_q15 * S, + q15_t * pSrc, + q15_t * pRef, + q15_t * pOut, + q15_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for Q15 normalized LMS filter. + * @param[in] S points to an instance of the Q15 normalized LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] pCoeffs points to coefficient buffer. + * @param[in] pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + */ + void arm_lms_norm_init_q15( + arm_lms_norm_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + q15_t mu, + uint32_t blockSize, + uint8_t postShift); + + + /** + * @brief Correlation of floating-point sequences. + * @param[in] pSrcA points to the first input sequence. + * @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 2 * max(srcALen, srcBLen) - 1. + */ + void arm_correlate_f32( + float32_t * pSrcA, + uint32_t srcALen, + float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst); + + + /** + * @brief Correlation of Q15 sequences + * @param[in] pSrcA points to the first input sequence. + * @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 2 * max(srcALen, srcBLen) - 1. + * @param[in] pScratch points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + */ + void arm_correlate_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch); + + + /** + * @brief Correlation of Q15 sequences. + * @param[in] pSrcA points to the first input sequence. + * @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 2 * max(srcALen, srcBLen) - 1. + */ + + void arm_correlate_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + + /** + * @brief Correlation of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4. + * @param[in] pSrcA points to the first input sequence. + * @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 2 * max(srcALen, srcBLen) - 1. + */ + + void arm_correlate_fast_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + + /** + * @brief Correlation of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4. + * @param[in] pSrcA points to the first input sequence. + * @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 2 * max(srcALen, srcBLen) - 1. + * @param[in] pScratch points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + */ + void arm_correlate_fast_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch); + + + /** + * @brief Correlation of Q31 sequences. + * @param[in] pSrcA points to the first input sequence. + * @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 2 * max(srcALen, srcBLen) - 1. + */ + void arm_correlate_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + + /** + * @brief Correlation of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] pSrcA points to the first input sequence. + * @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 2 * max(srcALen, srcBLen) - 1. + */ + void arm_correlate_fast_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + + /** + * @brief Correlation of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @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 2 * max(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). + */ + void arm_correlate_opt_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Correlation of Q7 sequences. + * @param[in] pSrcA points to the first input sequence. + * @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 2 * max(srcALen, srcBLen) - 1. + */ + void arm_correlate_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst); + + + /** + * @brief Instance structure for the floating-point sparse FIR filter. + */ + typedef struct + { + 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 *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. */ + } arm_fir_sparse_instance_f32; + + /** + * @brief Instance structure for the Q31 sparse FIR filter. + */ + typedef struct + { + 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 *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. */ + } arm_fir_sparse_instance_q31; + + /** + * @brief Instance structure for the Q15 sparse FIR filter. + */ + typedef struct + { + 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 *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. */ + } arm_fir_sparse_instance_q15; + + /** + * @brief Instance structure for the Q7 sparse FIR filter. + */ + typedef struct + { + 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 *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. */ + } arm_fir_sparse_instance_q7; + + + /** + * @brief Processing function for the floating-point sparse FIR filter. + * @param[in] S points to an instance of the floating-point sparse FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] pScratchIn points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_sparse_f32( + arm_fir_sparse_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + float32_t * pScratchIn, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point sparse FIR filter. + * @param[in,out] S points to an instance of the floating-point sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] pCoeffs points to the array of filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + */ + void arm_fir_sparse_init_f32( + arm_fir_sparse_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 sparse FIR filter. + * @param[in] S points to an instance of the Q31 sparse FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] pScratchIn points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_sparse_q31( + arm_fir_sparse_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + q31_t * pScratchIn, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 sparse FIR filter. + * @param[in,out] S points to an instance of the Q31 sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] pCoeffs points to the array of filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + */ + void arm_fir_sparse_init_q31( + arm_fir_sparse_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 sparse FIR filter. + * @param[in] S points to an instance of the Q15 sparse FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] pScratchIn points to a temporary buffer of size blockSize. + * @param[in] pScratchOut points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_sparse_q15( + arm_fir_sparse_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + q15_t * pScratchIn, + q31_t * pScratchOut, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 sparse FIR filter. + * @param[in,out] S points to an instance of the Q15 sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] pCoeffs points to the array of filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + */ + void arm_fir_sparse_init_q15( + arm_fir_sparse_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q7 sparse FIR filter. + * @param[in] S points to an instance of the Q7 sparse FIR structure. + * @param[in] pSrc points to the block of input data. + * @param[out] pDst points to the block of output data + * @param[in] pScratchIn points to a temporary buffer of size blockSize. + * @param[in] pScratchOut points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + */ + void arm_fir_sparse_q7( + arm_fir_sparse_instance_q7 * S, + q7_t * pSrc, + q7_t * pDst, + q7_t * pScratchIn, + q31_t * pScratchOut, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q7 sparse FIR filter. + * @param[in,out] S points to an instance of the Q7 sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] pCoeffs points to the array of filter coefficients. + * @param[in] pState points to the state buffer. + * @param[in] pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + */ + void arm_fir_sparse_init_q7( + arm_fir_sparse_instance_q7 * S, + uint16_t numTaps, + q7_t * pCoeffs, + q7_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + + /** + * @brief Floating-point sin_cos function. + * @param[in] theta input value in degrees + * @param[out] pSinVal points to the processed sine output. + * @param[out] pCosVal points to the processed cos output. + */ + void arm_sin_cos_f32( + float32_t theta, + float32_t * pSinVal, + float32_t * pCosVal); + + + /** + * @brief Q31 sin_cos function. + * @param[in] theta scaled input value in degrees + * @param[out] pSinVal points to the processed sine output. + * @param[out] pCosVal points to the processed cosine output. + */ + void arm_sin_cos_q31( + q31_t theta, + q31_t * pSinVal, + q31_t * pCosVal); + + + /** + * @brief Floating-point complex conjugate. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_conj_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + /** + * @brief Q31 complex conjugate. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_conj_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q15 complex conjugate. + * @param[in] pSrc points to the input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_conj_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + + /** + * @brief Floating-point complex magnitude squared + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_squared_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q31 complex magnitude squared + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_squared_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q15 complex magnitude squared + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_squared_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + + /** + * @ingroup groupController + */ + + /** + * @defgroup PID PID Motor Control + * + * A Proportional Integral Derivative (PID) controller is a generic feedback control + * loop mechanism widely used in industrial control systems. + * A PID controller is the most commonly used type of feedback controller. + * + * This set of functions implements (PID) controllers + * for Q15, Q31, and floating-point data types. The functions operate on a single sample + * of data and each call to the function returns a single processed value. + * S points to an instance of the PID control data structure. in + * is the input sample value. The functions return the output value. + * + * \par Algorithm: + *
+   *    y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2]
+   *    A0 = Kp + Ki + Kd
+   *    A1 = (-Kp ) - (2 * Kd )
+   *    A2 = Kd  
+ * + * \par + * where \c Kp is proportional constant, \c Ki is Integral constant and \c Kd is Derivative constant + * + * \par + * \image html PID.gif "Proportional Integral Derivative Controller" + * + * \par + * The PID controller calculates an "error" value as the difference between + * the measured output and the reference input. + * The controller attempts to minimize the error by adjusting the process control inputs. + * The proportional value determines the reaction to the current error, + * the integral value determines the reaction based on the sum of recent errors, + * and the derivative value determines the reaction based on the rate at which the error has been changing. + * + * \par Instance Structure + * The Gains A0, A1, A2 and state variables for a PID controller are stored together in an instance data structure. + * A separate instance structure must be defined for each PID Controller. + * There are separate instance structure declarations for each of the 3 supported data types. + * + * \par Reset Functions + * There is also an associated reset function for each data type which clears the state array. + * + * \par Initialization Functions + * There is also an associated initialization function for each data type. + * The initialization function performs the following operations: + * - Initializes the Gains A0, A1, A2 from Kp,Ki, Kd gains. + * - Zeros out the values in the state buffer. + * + * \par + * Instance structure cannot be placed into a const data section and it is recommended to use the initialization function. + * + * \par Fixed-Point Behavior + * Care must be taken when using the fixed-point versions of the PID Controller functions. + * In particular, the overflow and saturation behavior of the accumulator used in each function must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup PID + * @{ + */ + + /** + * @brief Process function for the floating-point PID Control. + * @param[in,out] S is an instance of the floating-point PID Control structure + * @param[in] in input sample to process + * @return out processed output sample. + */ + static __INLINE float32_t arm_pid_f32( + arm_pid_instance_f32 * S, + float32_t in) + { + float32_t out; + + /* y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2] */ + out = (S->A0 * in) + + (S->A1 * S->state[0]) + (S->A2 * S->state[1]) + (S->state[2]); + + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + + /* return to application */ + return (out); + + } + + /** + * @brief Process function for the Q31 PID Control. + * @param[in,out] S points to an instance of the Q31 PID Control structure + * @param[in] in input sample to process + * @return out processed output sample. + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 64-bit accumulator. + * The accumulator has a 2.62 format and maintains full precision of the intermediate multiplication results but provides only a single guard bit. + * Thus, if the accumulator result overflows it wraps around rather than clip. + * In order to avoid overflows completely the input signal must be scaled down by 2 bits as there are four additions. + * After all multiply-accumulates are performed, the 2.62 accumulator is truncated to 1.32 format and then saturated to 1.31 format. + */ + static __INLINE q31_t arm_pid_q31( + arm_pid_instance_q31 * S, + q31_t in) + { + q63_t acc; + q31_t out; + + /* acc = A0 * x[n] */ + acc = (q63_t) S->A0 * in; + + /* acc += A1 * x[n-1] */ + acc += (q63_t) S->A1 * S->state[0]; + + /* acc += A2 * x[n-2] */ + acc += (q63_t) S->A2 * S->state[1]; + + /* convert output to 1.31 format to add y[n-1] */ + out = (q31_t) (acc >> 31u); + + /* out += y[n-1] */ + out += S->state[2]; + + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + + /* return to application */ + return (out); + } + + + /** + * @brief Process function for the Q15 PID Control. + * @param[in,out] S points to an instance of the Q15 PID Control structure + * @param[in] in input sample to process + * @return out processed output sample. + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using a 64-bit internal accumulator. + * Both Gains and state variables are represented in 1.15 format and multiplications yield a 2.30 result. + * The 2.30 intermediate results are accumulated in a 64-bit accumulator in 34.30 format. + * There is no risk of internal overflow with this approach and the full precision of intermediate multiplications is preserved. + * After all additions have been performed, the accumulator is truncated to 34.15 format by discarding low 15 bits. + * Lastly, the accumulator is saturated to yield a result in 1.15 format. + */ + static __INLINE q15_t arm_pid_q15( + arm_pid_instance_q15 * S, + q15_t in) + { + q63_t acc; + q15_t out; + +#ifndef ARM_MATH_CM0_FAMILY + __SIMD32_TYPE *vstate; + + /* Implementation of PID controller */ + + /* acc = A0 * x[n] */ + acc = (q31_t) __SMUAD((uint32_t)S->A0, (uint32_t)in); + + /* acc += A1 * x[n-1] + A2 * x[n-2] */ + vstate = __SIMD32_CONST(S->state); + acc = (q63_t)__SMLALD((uint32_t)S->A1, (uint32_t)*vstate, (uint64_t)acc); +#else + /* acc = A0 * x[n] */ + acc = ((q31_t) S->A0) * in; + + /* acc += A1 * x[n-1] + A2 * x[n-2] */ + acc += (q31_t) S->A1 * S->state[0]; + acc += (q31_t) S->A2 * S->state[1]; +#endif + + /* acc += y[n-1] */ + acc += (q31_t) S->state[2] << 15; + + /* saturate the output */ + out = (q15_t) (__SSAT((acc >> 15), 16)); + + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + + /* return to application */ + return (out); + } + + /** + * @} end of PID group + */ + + + /** + * @brief Floating-point matrix inverse. + * @param[in] src points to the instance of the input floating-point matrix structure. + * @param[out] dst points to the instance of the output floating-point matrix structure. + * @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match. + * If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR. + */ + arm_status arm_mat_inverse_f32( + const arm_matrix_instance_f32 * src, + arm_matrix_instance_f32 * dst); + + + /** + * @brief Floating-point matrix inverse. + * @param[in] src points to the instance of the input floating-point matrix structure. + * @param[out] dst points to the instance of the output floating-point matrix structure. + * @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match. + * If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR. + */ + arm_status arm_mat_inverse_f64( + const arm_matrix_instance_f64 * src, + arm_matrix_instance_f64 * dst); + + + + /** + * @ingroup groupController + */ + + /** + * @defgroup clarke Vector Clarke Transform + * Forward Clarke transform converts the instantaneous stator phases into a two-coordinate time invariant vector. + * Generally the Clarke transform uses three-phase currents Ia, Ib and Ic to calculate currents + * in the two-phase orthogonal stator axis Ialpha and Ibeta. + * When Ialpha is superposed with Ia as shown in the figure below + * \image html clarke.gif Stator current space vector and its components in (a,b). + * and Ia + Ib + Ic = 0, in this condition Ialpha and Ibeta + * can be calculated using only Ia and Ib. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html clarkeFormula.gif + * where Ia and Ib are the instantaneous stator phases and + * pIalpha and pIbeta are the two coordinates of time invariant vector. + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Clarke transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup clarke + * @{ + */ + + /** + * + * @brief Floating-point Clarke transform + * @param[in] Ia input three-phase coordinate a + * @param[in] Ib input three-phase coordinate b + * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] pIbeta points to output two-phase orthogonal vector axis beta + */ + static __INLINE void arm_clarke_f32( + float32_t Ia, + float32_t Ib, + float32_t * pIalpha, + float32_t * pIbeta) + { + /* Calculate pIalpha using the equation, pIalpha = Ia */ + *pIalpha = Ia; + + /* Calculate pIbeta using the equation, pIbeta = (1/sqrt(3)) * Ia + (2/sqrt(3)) * Ib */ + *pIbeta = ((float32_t) 0.57735026919 * Ia + (float32_t) 1.15470053838 * Ib); + } + + + /** + * @brief Clarke transform for Q31 version + * @param[in] Ia input three-phase coordinate a + * @param[in] Ib input three-phase coordinate b + * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] pIbeta points to output two-phase orthogonal vector axis beta + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 32-bit accumulator. + * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + * There is saturation on the addition, hence there is no risk of overflow. + */ + static __INLINE void arm_clarke_q31( + q31_t Ia, + q31_t Ib, + q31_t * pIalpha, + q31_t * pIbeta) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + + /* Calculating pIalpha from Ia by equation pIalpha = Ia */ + *pIalpha = Ia; + + /* Intermediate product is calculated by (1/(sqrt(3)) * Ia) */ + product1 = (q31_t) (((q63_t) Ia * 0x24F34E8B) >> 30); + + /* Intermediate product is calculated by (2/sqrt(3) * Ib) */ + product2 = (q31_t) (((q63_t) Ib * 0x49E69D16) >> 30); + + /* pIbeta is calculated by adding the intermediate products */ + *pIbeta = __QADD(product1, product2); + } + + /** + * @} end of clarke group + */ + + /** + * @brief Converts the elements of the Q7 vector to Q31 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_q7_to_q31( + q7_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + + /** + * @ingroup groupController + */ + + /** + * @defgroup inv_clarke Vector Inverse Clarke Transform + * Inverse Clarke transform converts the two-coordinate time invariant vector into instantaneous stator phases. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html clarkeInvFormula.gif + * where pIa and pIb are the instantaneous stator phases and + * Ialpha and Ibeta are the two coordinates of time invariant vector. + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Clarke transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup inv_clarke + * @{ + */ + + /** + * @brief Floating-point Inverse Clarke transform + * @param[in] Ialpha input two-phase orthogonal vector axis alpha + * @param[in] Ibeta input two-phase orthogonal vector axis beta + * @param[out] pIa points to output three-phase coordinate a + * @param[out] pIb points to output three-phase coordinate b + */ + static __INLINE void arm_inv_clarke_f32( + float32_t Ialpha, + float32_t Ibeta, + float32_t * pIa, + float32_t * pIb) + { + /* Calculating pIa from Ialpha by equation pIa = Ialpha */ + *pIa = Ialpha; + + /* Calculating pIb from Ialpha and Ibeta by equation pIb = -(1/2) * Ialpha + (sqrt(3)/2) * Ibeta */ + *pIb = -0.5f * Ialpha + 0.8660254039f * Ibeta; + } + + + /** + * @brief Inverse Clarke transform for Q31 version + * @param[in] Ialpha input two-phase orthogonal vector axis alpha + * @param[in] Ibeta input two-phase orthogonal vector axis beta + * @param[out] pIa points to output three-phase coordinate a + * @param[out] pIb points to output three-phase coordinate b + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 32-bit accumulator. + * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + * There is saturation on the subtraction, hence there is no risk of overflow. + */ + static __INLINE void arm_inv_clarke_q31( + q31_t Ialpha, + q31_t Ibeta, + q31_t * pIa, + q31_t * pIb) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + + /* Calculating pIa from Ialpha by equation pIa = Ialpha */ + *pIa = Ialpha; + + /* Intermediate product is calculated by (1/(2*sqrt(3)) * Ia) */ + product1 = (q31_t) (((q63_t) (Ialpha) * (0x40000000)) >> 31); + + /* Intermediate product is calculated by (1/sqrt(3) * pIb) */ + product2 = (q31_t) (((q63_t) (Ibeta) * (0x6ED9EBA1)) >> 31); + + /* pIb is calculated by subtracting the products */ + *pIb = __QSUB(product2, product1); + } + + /** + * @} end of inv_clarke group + */ + + /** + * @brief Converts the elements of the Q7 vector to Q15 vector. + * @param[in] pSrc input pointer + * @param[out] pDst output pointer + * @param[in] blockSize number of samples to process + */ + void arm_q7_to_q15( + q7_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + + /** + * @ingroup groupController + */ + + /** + * @defgroup park Vector Park Transform + * + * Forward Park transform converts the input two-coordinate vector to flux and torque components. + * The Park transform can be used to realize the transformation of the Ialpha and the Ibeta currents + * from the stationary to the moving reference frame and control the spatial relationship between + * the stator vector current and rotor flux vector. + * If we consider the d axis aligned with the rotor flux, the diagram below shows the + * current vector and the relationship from the two reference frames: + * \image html park.gif "Stator current space vector and its component in (a,b) and in the d,q rotating reference frame" + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html parkFormula.gif + * where Ialpha and Ibeta are the stator vector components, + * pId and pIq are rotor vector components and cosVal and sinVal are the + * cosine and sine values of theta (rotor flux position). + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Park transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup park + * @{ + */ + + /** + * @brief Floating-point Park transform + * @param[in] Ialpha input two-phase vector coordinate alpha + * @param[in] Ibeta input two-phase vector coordinate beta + * @param[out] pId points to output rotor reference frame d + * @param[out] pIq points to output rotor reference frame q + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + * + * The function implements the forward Park transform. + * + */ + static __INLINE void arm_park_f32( + float32_t Ialpha, + float32_t Ibeta, + float32_t * pId, + float32_t * pIq, + float32_t sinVal, + float32_t cosVal) + { + /* Calculate pId using the equation, pId = Ialpha * cosVal + Ibeta * sinVal */ + *pId = Ialpha * cosVal + Ibeta * sinVal; + + /* Calculate pIq using the equation, pIq = - Ialpha * sinVal + Ibeta * cosVal */ + *pIq = -Ialpha * sinVal + Ibeta * cosVal; + } + + + /** + * @brief Park transform for Q31 version + * @param[in] Ialpha input two-phase vector coordinate alpha + * @param[in] Ibeta input two-phase vector coordinate beta + * @param[out] pId points to output rotor reference frame d + * @param[out] pIq points to output rotor reference frame q + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 32-bit accumulator. + * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + * There is saturation on the addition and subtraction, hence there is no risk of overflow. + */ + static __INLINE void arm_park_q31( + q31_t Ialpha, + q31_t Ibeta, + q31_t * pId, + q31_t * pIq, + q31_t sinVal, + q31_t cosVal) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + q31_t product3, product4; /* Temporary variables used to store intermediate results */ + + /* Intermediate product is calculated by (Ialpha * cosVal) */ + product1 = (q31_t) (((q63_t) (Ialpha) * (cosVal)) >> 31); + + /* Intermediate product is calculated by (Ibeta * sinVal) */ + product2 = (q31_t) (((q63_t) (Ibeta) * (sinVal)) >> 31); + + + /* Intermediate product is calculated by (Ialpha * sinVal) */ + product3 = (q31_t) (((q63_t) (Ialpha) * (sinVal)) >> 31); + + /* Intermediate product is calculated by (Ibeta * cosVal) */ + product4 = (q31_t) (((q63_t) (Ibeta) * (cosVal)) >> 31); + + /* Calculate pId by adding the two intermediate products 1 and 2 */ + *pId = __QADD(product1, product2); + + /* Calculate pIq by subtracting the two intermediate products 3 from 4 */ + *pIq = __QSUB(product4, product3); + } + + /** + * @} end of park group + */ + + /** + * @brief Converts the elements of the Q7 vector to floating-point vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q7_to_float( + q7_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @ingroup groupController + */ + + /** + * @defgroup inv_park Vector Inverse Park transform + * Inverse Park transform converts the input flux and torque components to two-coordinate vector. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html parkInvFormula.gif + * where pIalpha and pIbeta are the stator vector components, + * Id and Iq are rotor vector components and cosVal and sinVal are the + * cosine and sine values of theta (rotor flux position). + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Park transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup inv_park + * @{ + */ + + /** + * @brief Floating-point Inverse Park transform + * @param[in] Id input coordinate of rotor reference frame d + * @param[in] Iq input coordinate of rotor reference frame q + * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] pIbeta points to output two-phase orthogonal vector axis beta + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + */ + static __INLINE void arm_inv_park_f32( + float32_t Id, + float32_t Iq, + float32_t * pIalpha, + float32_t * pIbeta, + float32_t sinVal, + float32_t cosVal) + { + /* Calculate pIalpha using the equation, pIalpha = Id * cosVal - Iq * sinVal */ + *pIalpha = Id * cosVal - Iq * sinVal; + + /* Calculate pIbeta using the equation, pIbeta = Id * sinVal + Iq * cosVal */ + *pIbeta = Id * sinVal + Iq * cosVal; + } + + + /** + * @brief Inverse Park transform for Q31 version + * @param[in] Id input coordinate of rotor reference frame d + * @param[in] Iq input coordinate of rotor reference frame q + * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] pIbeta points to output two-phase orthogonal vector axis beta + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 32-bit accumulator. + * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + * There is saturation on the addition, hence there is no risk of overflow. + */ + static __INLINE void arm_inv_park_q31( + q31_t Id, + q31_t Iq, + q31_t * pIalpha, + q31_t * pIbeta, + q31_t sinVal, + q31_t cosVal) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + q31_t product3, product4; /* Temporary variables used to store intermediate results */ + + /* Intermediate product is calculated by (Id * cosVal) */ + product1 = (q31_t) (((q63_t) (Id) * (cosVal)) >> 31); + + /* Intermediate product is calculated by (Iq * sinVal) */ + product2 = (q31_t) (((q63_t) (Iq) * (sinVal)) >> 31); + + + /* Intermediate product is calculated by (Id * sinVal) */ + product3 = (q31_t) (((q63_t) (Id) * (sinVal)) >> 31); + + /* Intermediate product is calculated by (Iq * cosVal) */ + product4 = (q31_t) (((q63_t) (Iq) * (cosVal)) >> 31); + + /* Calculate pIalpha by using the two intermediate products 1 and 2 */ + *pIalpha = __QSUB(product1, product2); + + /* Calculate pIbeta by using the two intermediate products 3 and 4 */ + *pIbeta = __QADD(product4, product3); + } + + /** + * @} end of Inverse park group + */ + + + /** + * @brief Converts the elements of the Q31 vector to floating-point vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q31_to_float( + q31_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @ingroup groupInterpolation + */ + + /** + * @defgroup LinearInterpolate Linear Interpolation + * + * Linear interpolation is a method of curve fitting using linear polynomials. + * Linear interpolation works by effectively drawing a straight line between two neighboring samples and returning the appropriate point along that line + * + * \par + * \image html LinearInterp.gif "Linear interpolation" + * + * \par + * A Linear Interpolate function calculates an output value(y), for the input(x) + * using linear interpolation of the input values x0, x1( nearest input values) and the output values y0 and y1(nearest output values) + * + * \par Algorithm: + *
+   *       y = y0 + (x - x0) * ((y1 - y0)/(x1-x0))
+   *       where x0, x1 are nearest values of input x
+   *             y0, y1 are nearest values to output y
+   * 
+ * + * \par + * This set of functions implements Linear interpolation process + * for Q7, Q15, Q31, and floating-point data types. The functions operate on a single + * sample of data and each call to the function returns a single processed value. + * S points to an instance of the Linear Interpolate function data structure. + * x is the input sample value. The functions returns the output value. + * + * \par + * if x is outside of the table boundary, Linear interpolation returns first value of the table + * if x is below input range and returns last value of table if x is above range. + */ + + /** + * @addtogroup LinearInterpolate + * @{ + */ + + /** + * @brief Process function for the floating-point Linear Interpolation Function. + * @param[in,out] S is an instance of the floating-point Linear Interpolation structure + * @param[in] x input sample to process + * @return y processed output sample. + * + */ + static __INLINE float32_t arm_linear_interp_f32( + arm_linear_interp_instance_f32 * S, + float32_t x) + { + float32_t y; + float32_t x0, x1; /* Nearest input values */ + float32_t y0, y1; /* Nearest output values */ + float32_t xSpacing = S->xSpacing; /* spacing between input values */ + int32_t i; /* Index variable */ + float32_t *pYData = S->pYData; /* pointer to output table */ + + /* Calculation of index */ + i = (int32_t) ((x - S->x1) / xSpacing); + + 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) + { + /* Iniatilize output for above specified range as last output value of table */ + y = pYData[S->nValues - 1]; + } + else + { + /* Calculation of nearest input values */ + x0 = S->x1 + i * xSpacing; + x1 = S->x1 + (i + 1) * xSpacing; + + /* Read of nearest output values */ + y0 = pYData[i]; + y1 = pYData[i + 1]; + + /* Calculation of output */ + y = y0 + (x - x0) * ((y1 - y0) / (x1 - x0)); + + } + + /* returns output value */ + return (y); + } + + + /** + * + * @brief Process function for the Q31 Linear Interpolation Function. + * @param[in] pYData pointer to Q31 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + * + */ + static __INLINE q31_t arm_linear_interp_q31( + q31_t * pYData, + q31_t x, + uint32_t nValues) + { + q31_t y; /* output */ + q31_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + int32_t index; /* Index to read nearest output values */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + index = ((x & (q31_t)0xFFF00000) >> 20); + + if(index >= (int32_t)(nValues - 1)) + { + return (pYData[nValues - 1]); + } + else if(index < 0) + { + return (pYData[0]); + } + else + { + /* 20 bits for the fractional part */ + /* shift left by 11 to keep fract in 1.31 format */ + fract = (x & 0x000FFFFF) << 11; + + /* Read two nearest output values from the index in 1.31(q31) format */ + y0 = pYData[index]; + y1 = pYData[index + 1]; + + /* Calculation of y0 * (1-fract) and y is in 2.30 format */ + y = ((q31_t) ((q63_t) y0 * (0x7FFFFFFF - fract) >> 32)); + + /* Calculation of y0 * (1-fract) + y1 *fract and y is in 2.30 format */ + y += ((q31_t) (((q63_t) y1 * fract) >> 32)); + + /* Convert y to 1.31 format */ + return (y << 1u); + } + } + + + /** + * + * @brief Process function for the Q15 Linear Interpolation Function. + * @param[in] pYData pointer to Q15 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + * + */ + static __INLINE q15_t arm_linear_interp_q15( + q15_t * pYData, + q31_t x, + uint32_t nValues) + { + q63_t y; /* output */ + q15_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + int32_t index; /* Index to read nearest output values */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + index = ((x & (int32_t)0xFFF00000) >> 20); + + if(index >= (int32_t)(nValues - 1)) + { + return (pYData[nValues - 1]); + } + else if(index < 0) + { + return (pYData[0]); + } + else + { + /* 20 bits for the fractional part */ + /* fract is in 12.20 format */ + fract = (x & 0x000FFFFF); + + /* Read two nearest output values from the index */ + y0 = pYData[index]; + y1 = pYData[index + 1]; + + /* Calculation of y0 * (1-fract) and y is in 13.35 format */ + y = ((q63_t) y0 * (0xFFFFF - fract)); + + /* Calculation of (y0 * (1-fract) + y1 * fract) and y is in 13.35 format */ + y += ((q63_t) y1 * (fract)); + + /* convert y to 1.15 format */ + return (q15_t) (y >> 20); + } + } + + + /** + * + * @brief Process function for the Q7 Linear Interpolation Function. + * @param[in] pYData pointer to Q7 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + */ + static __INLINE q7_t arm_linear_interp_q7( + q7_t * pYData, + q31_t x, + uint32_t nValues) + { + q31_t y; /* output */ + q7_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + uint32_t index; /* Index to read nearest output values */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + if (x < 0) + { + return (pYData[0]); + } + index = (x >> 20) & 0xfff; + + if(index >= (nValues - 1)) + { + return (pYData[nValues - 1]); + } + else + { + /* 20 bits for the fractional part */ + /* fract is in 12.20 format */ + fract = (x & 0x000FFFFF); + + /* Read two nearest output values from the index and are in 1.7(q7) format */ + y0 = pYData[index]; + y1 = pYData[index + 1]; + + /* Calculation of y0 * (1-fract ) and y is in 13.27(q27) format */ + y = ((y0 * (0xFFFFF - fract))); + + /* Calculation of y1 * fract + y0 * (1-fract) and y is in 13.27(q27) format */ + y += (y1 * fract); + + /* convert y to 1.7(q7) format */ + return (q7_t) (y >> 20); + } + } + + /** + * @} end of LinearInterpolate group + */ + + /** + * @brief Fast approximation to the trigonometric sine function for floating-point data. + * @param[in] x input value in radians. + * @return sin(x). + */ + float32_t arm_sin_f32( + float32_t x); + + + /** + * @brief Fast approximation to the trigonometric sine function for Q31 data. + * @param[in] x Scaled input value in radians. + * @return sin(x). + */ + q31_t arm_sin_q31( + q31_t x); + + + /** + * @brief Fast approximation to the trigonometric sine function for Q15 data. + * @param[in] x Scaled input value in radians. + * @return sin(x). + */ + q15_t arm_sin_q15( + q15_t x); + + + /** + * @brief Fast approximation to the trigonometric cosine function for floating-point data. + * @param[in] x input value in radians. + * @return cos(x). + */ + float32_t arm_cos_f32( + float32_t x); + + + /** + * @brief Fast approximation to the trigonometric cosine function for Q31 data. + * @param[in] x Scaled input value in radians. + * @return cos(x). + */ + q31_t arm_cos_q31( + q31_t x); + + + /** + * @brief Fast approximation to the trigonometric cosine function for Q15 data. + * @param[in] x Scaled input value in radians. + * @return cos(x). + */ + q15_t arm_cos_q15( + q15_t x); + + + /** + * @ingroup groupFastMath + */ + + + /** + * @defgroup SQRT Square Root + * + * Computes the square root of a number. + * There are separate functions for Q15, Q31, and floating-point data types. + * The square root function is computed using the Newton-Raphson algorithm. + * This is an iterative algorithm of the form: + *
+   *      x1 = x0 - f(x0)/f'(x0)
+   * 
+ * where x1 is the current estimate, + * x0 is the previous estimate, and + * f'(x0) is the derivative of f() evaluated at x0. + * For the square root function, the algorithm reduces to: + *
+   *     x0 = in/2                         [initial guess]
+   *     x1 = 1/2 * ( x0 + in / x0)        [each iteration]
+   * 
+ */ + + + /** + * @addtogroup SQRT + * @{ + */ + + /** + * @brief Floating-point square root function. + * @param[in] in input value. + * @param[out] pOut square root of input value. + * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if + * in is negative value and returns zero output for negative values. + */ + static __INLINE arm_status arm_sqrt_f32( + float32_t in, + float32_t * pOut) + { + if(in >= 0.0f) + { + +#if (__FPU_USED == 1) && defined ( __CC_ARM ) + *pOut = __sqrtf(in); +#elif (__FPU_USED == 1) && (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)) + *pOut = __builtin_sqrtf(in); +#elif (__FPU_USED == 1) && defined(__GNUC__) + *pOut = __builtin_sqrtf(in); +#elif (__FPU_USED == 1) && defined ( __ICCARM__ ) && (__VER__ >= 6040000) + __ASM("VSQRT.F32 %0,%1" : "=t"(*pOut) : "t"(in)); +#else + *pOut = sqrtf(in); +#endif + + return (ARM_MATH_SUCCESS); + } + else + { + *pOut = 0.0f; + return (ARM_MATH_ARGUMENT_ERROR); + } + } + + + /** + * @brief Q31 square root function. + * @param[in] in input value. The range of the input value is [0 +1) or 0x00000000 to 0x7FFFFFFF. + * @param[out] pOut square root of input value. + * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if + * in is negative value and returns zero output for negative values. + */ + arm_status arm_sqrt_q31( + q31_t in, + q31_t * pOut); + + + /** + * @brief Q15 square root function. + * @param[in] in input value. The range of the input value is [0 +1) or 0x0000 to 0x7FFF. + * @param[out] pOut square root of input value. + * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if + * in is negative value and returns zero output for negative values. + */ + arm_status arm_sqrt_q15( + q15_t in, + q15_t * pOut); + + /** + * @} end of SQRT group + */ + + + /** + * @brief floating-point Circular write function. + */ + static __INLINE void arm_circularWrite_f32( + int32_t * circBuffer, + int32_t L, + uint16_t * writeOffset, + int32_t bufferInc, + const int32_t * src, + int32_t srcInc, + uint32_t blockSize) + { + uint32_t i = 0u; + int32_t wOffset; + + /* Copy the value of Index pointer that points + * to the current location where the input samples to be copied */ + wOffset = *writeOffset; + + /* Loop over the blockSize */ + i = blockSize; + + while(i > 0u) + { + /* copy the input sample to the circular buffer */ + circBuffer[wOffset] = *src; + + /* Update the input pointer */ + src += srcInc; + + /* Circularly update wOffset. Watch out for positive and negative value */ + wOffset += bufferInc; + if(wOffset >= L) + wOffset -= L; + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *writeOffset = (uint16_t)wOffset; + } + + + + /** + * @brief floating-point Circular Read function. + */ + static __INLINE void arm_circularRead_f32( + int32_t * circBuffer, + int32_t L, + int32_t * readOffset, + int32_t bufferInc, + int32_t * dst, + int32_t * dst_base, + int32_t dst_length, + int32_t dstInc, + uint32_t blockSize) + { + uint32_t i = 0u; + int32_t rOffset, dst_end; + + /* Copy the value of Index pointer that points + * to the current location from where the input samples to be read */ + rOffset = *readOffset; + dst_end = (int32_t) (dst_base + dst_length); + + /* Loop over the blockSize */ + i = blockSize; + + while(i > 0u) + { + /* copy the sample from the circular buffer to the destination buffer */ + *dst = circBuffer[rOffset]; + + /* Update the input pointer */ + dst += dstInc; + + if(dst == (int32_t *) dst_end) + { + dst = dst_base; + } + + /* Circularly update rOffset. Watch out for positive and negative value */ + rOffset += bufferInc; + + if(rOffset >= L) + { + rOffset -= L; + } + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *readOffset = rOffset; + } + + + /** + * @brief Q15 Circular write function. + */ + static __INLINE void arm_circularWrite_q15( + q15_t * circBuffer, + int32_t L, + uint16_t * writeOffset, + int32_t bufferInc, + const q15_t * src, + int32_t srcInc, + uint32_t blockSize) + { + uint32_t i = 0u; + int32_t wOffset; + + /* Copy the value of Index pointer that points + * to the current location where the input samples to be copied */ + wOffset = *writeOffset; + + /* Loop over the blockSize */ + i = blockSize; + + while(i > 0u) + { + /* copy the input sample to the circular buffer */ + circBuffer[wOffset] = *src; + + /* Update the input pointer */ + src += srcInc; + + /* Circularly update wOffset. Watch out for positive and negative value */ + wOffset += bufferInc; + if(wOffset >= L) + wOffset -= L; + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *writeOffset = (uint16_t)wOffset; + } + + + /** + * @brief Q15 Circular Read function. + */ + static __INLINE void arm_circularRead_q15( + q15_t * circBuffer, + int32_t L, + int32_t * readOffset, + int32_t bufferInc, + q15_t * dst, + q15_t * dst_base, + int32_t dst_length, + int32_t dstInc, + uint32_t blockSize) + { + uint32_t i = 0; + int32_t rOffset, dst_end; + + /* Copy the value of Index pointer that points + * to the current location from where the input samples to be read */ + rOffset = *readOffset; + + dst_end = (int32_t) (dst_base + dst_length); + + /* Loop over the blockSize */ + i = blockSize; + + while(i > 0u) + { + /* copy the sample from the circular buffer to the destination buffer */ + *dst = circBuffer[rOffset]; + + /* Update the input pointer */ + dst += dstInc; + + if(dst == (q15_t *) dst_end) + { + dst = dst_base; + } + + /* Circularly update wOffset. Watch out for positive and negative value */ + rOffset += bufferInc; + + if(rOffset >= L) + { + rOffset -= L; + } + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *readOffset = rOffset; + } + + + /** + * @brief Q7 Circular write function. + */ + static __INLINE void arm_circularWrite_q7( + q7_t * circBuffer, + int32_t L, + uint16_t * writeOffset, + int32_t bufferInc, + const q7_t * src, + int32_t srcInc, + uint32_t blockSize) + { + uint32_t i = 0u; + int32_t wOffset; + + /* Copy the value of Index pointer that points + * to the current location where the input samples to be copied */ + wOffset = *writeOffset; + + /* Loop over the blockSize */ + i = blockSize; + + while(i > 0u) + { + /* copy the input sample to the circular buffer */ + circBuffer[wOffset] = *src; + + /* Update the input pointer */ + src += srcInc; + + /* Circularly update wOffset. Watch out for positive and negative value */ + wOffset += bufferInc; + if(wOffset >= L) + wOffset -= L; + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *writeOffset = (uint16_t)wOffset; + } + + + /** + * @brief Q7 Circular Read function. + */ + static __INLINE void arm_circularRead_q7( + q7_t * circBuffer, + int32_t L, + int32_t * readOffset, + int32_t bufferInc, + q7_t * dst, + q7_t * dst_base, + int32_t dst_length, + int32_t dstInc, + uint32_t blockSize) + { + uint32_t i = 0; + int32_t rOffset, dst_end; + + /* Copy the value of Index pointer that points + * to the current location from where the input samples to be read */ + rOffset = *readOffset; + + dst_end = (int32_t) (dst_base + dst_length); + + /* Loop over the blockSize */ + i = blockSize; + + while(i > 0u) + { + /* copy the sample from the circular buffer to the destination buffer */ + *dst = circBuffer[rOffset]; + + /* Update the input pointer */ + dst += dstInc; + + if(dst == (q7_t *) dst_end) + { + dst = dst_base; + } + + /* Circularly update rOffset. Watch out for positive and negative value */ + rOffset += bufferInc; + + if(rOffset >= L) + { + rOffset -= L; + } + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *readOffset = rOffset; + } + + + /** + * @brief Sum of the squares of the elements of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_power_q31( + q31_t * pSrc, + uint32_t blockSize, + q63_t * pResult); + + + /** + * @brief Sum of the squares of the elements of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_power_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Sum of the squares of the elements of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_power_q15( + q15_t * pSrc, + uint32_t blockSize, + q63_t * pResult); + + + /** + * @brief Sum of the squares of the elements of a Q7 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_power_q7( + q7_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Mean value of a Q7 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_mean_q7( + q7_t * pSrc, + uint32_t blockSize, + q7_t * pResult); + + + /** + * @brief Mean value of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_mean_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + + /** + * @brief Mean value of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_mean_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Mean value of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_mean_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Variance of the elements of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_var_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Variance of the elements of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_var_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Variance of the elements of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_var_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + + /** + * @brief Root Mean Square of the elements of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_rms_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Root Mean Square of the elements of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_rms_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Root Mean Square of the elements of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_rms_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + + /** + * @brief Standard deviation of the elements of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_std_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + + /** + * @brief Standard deviation of the elements of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_std_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + + /** + * @brief Standard deviation of the elements of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output value. + */ + void arm_std_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + + /** + * @brief Floating-point complex magnitude + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q31 complex magnitude + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q15 complex magnitude + * @param[in] pSrc points to the complex input vector + * @param[out] pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + */ + void arm_cmplx_mag_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q15 complex dot product + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] numSamples number of complex samples in each vector + * @param[out] realResult real part of the result returned here + * @param[out] imagResult imaginary part of the result returned here + */ + void arm_cmplx_dot_prod_q15( + q15_t * pSrcA, + q15_t * pSrcB, + uint32_t numSamples, + q31_t * realResult, + q31_t * imagResult); + + + /** + * @brief Q31 complex dot product + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] numSamples number of complex samples in each vector + * @param[out] realResult real part of the result returned here + * @param[out] imagResult imaginary part of the result returned here + */ + void arm_cmplx_dot_prod_q31( + q31_t * pSrcA, + q31_t * pSrcB, + uint32_t numSamples, + q63_t * realResult, + q63_t * imagResult); + + + /** + * @brief Floating-point complex dot product + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[in] numSamples number of complex samples in each vector + * @param[out] realResult real part of the result returned here + * @param[out] imagResult imaginary part of the result returned here + */ + void arm_cmplx_dot_prod_f32( + float32_t * pSrcA, + float32_t * pSrcB, + uint32_t numSamples, + float32_t * realResult, + float32_t * imagResult); + + + /** + * @brief Q15 complex-by-real multiplication + * @param[in] pSrcCmplx points to the complex input vector + * @param[in] pSrcReal points to the real input vector + * @param[out] pCmplxDst points to the complex output vector + * @param[in] numSamples number of samples in each vector + */ + void arm_cmplx_mult_real_q15( + q15_t * pSrcCmplx, + q15_t * pSrcReal, + q15_t * pCmplxDst, + uint32_t numSamples); + + + /** + * @brief Q31 complex-by-real multiplication + * @param[in] pSrcCmplx points to the complex input vector + * @param[in] pSrcReal points to the real input vector + * @param[out] pCmplxDst points to the complex output vector + * @param[in] numSamples number of samples in each vector + */ + void arm_cmplx_mult_real_q31( + q31_t * pSrcCmplx, + q31_t * pSrcReal, + q31_t * pCmplxDst, + uint32_t numSamples); + + + /** + * @brief Floating-point complex-by-real multiplication + * @param[in] pSrcCmplx points to the complex input vector + * @param[in] pSrcReal points to the real input vector + * @param[out] pCmplxDst points to the complex output vector + * @param[in] numSamples number of samples in each vector + */ + void arm_cmplx_mult_real_f32( + float32_t * pSrcCmplx, + float32_t * pSrcReal, + float32_t * pCmplxDst, + uint32_t numSamples); + + + /** + * @brief Minimum value of a Q7 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] result is output pointer + * @param[in] index is the array index of the minimum value in the input buffer. + */ + void arm_min_q7( + q7_t * pSrc, + uint32_t blockSize, + q7_t * result, + uint32_t * index); + + + /** + * @brief Minimum value of a Q15 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output pointer + * @param[in] pIndex is the array index of the minimum value in the input buffer. + */ + void arm_min_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult, + uint32_t * pIndex); + + + /** + * @brief Minimum value of a Q31 vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output pointer + * @param[out] pIndex is the array index of the minimum value in the input buffer. + */ + void arm_min_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult, + uint32_t * pIndex); + + + /** + * @brief Minimum value of a floating-point vector. + * @param[in] pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] pResult is output pointer + * @param[out] pIndex is the array index of the minimum value in the input buffer. + */ + void arm_min_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult, + uint32_t * pIndex); + + +/** + * @brief Maximum value of a Q7 vector. + * @param[in] pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] pResult maximum value returned here + * @param[out] pIndex index of maximum value returned here + */ + void arm_max_q7( + q7_t * pSrc, + uint32_t blockSize, + q7_t * pResult, + uint32_t * pIndex); + + +/** + * @brief Maximum value of a Q15 vector. + * @param[in] pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] pResult maximum value returned here + * @param[out] pIndex index of maximum value returned here + */ + void arm_max_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult, + uint32_t * pIndex); + + +/** + * @brief Maximum value of a Q31 vector. + * @param[in] pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] pResult maximum value returned here + * @param[out] pIndex index of maximum value returned here + */ + void arm_max_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult, + uint32_t * pIndex); + + +/** + * @brief Maximum value of a floating-point vector. + * @param[in] pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] pResult maximum value returned here + * @param[out] pIndex index of maximum value returned here + */ + void arm_max_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult, + uint32_t * pIndex); + + + /** + * @brief Q15 complex-by-complex multiplication + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_mult_cmplx_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t numSamples); + + + /** + * @brief Q31 complex-by-complex multiplication + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_mult_cmplx_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t numSamples); + + + /** + * @brief Floating-point complex-by-complex multiplication + * @param[in] pSrcA points to the first input vector + * @param[in] pSrcB points to the second input vector + * @param[out] pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + */ + void arm_cmplx_mult_cmplx_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t numSamples); + + + /** + * @brief Converts the elements of the floating-point vector to Q31 vector. + * @param[in] pSrc points to the floating-point input vector + * @param[out] pDst points to the Q31 output vector + * @param[in] blockSize length of the input vector + */ + void arm_float_to_q31( + float32_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the floating-point vector to Q15 vector. + * @param[in] pSrc points to the floating-point input vector + * @param[out] pDst points to the Q15 output vector + * @param[in] blockSize length of the input vector + */ + void arm_float_to_q15( + float32_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the floating-point vector to Q7 vector. + * @param[in] pSrc points to the floating-point input vector + * @param[out] pDst points to the Q7 output vector + * @param[in] blockSize length of the input vector + */ + void arm_float_to_q7( + float32_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q31 vector to Q15 vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q31_to_q15( + q31_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q31 vector to Q7 vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q31_to_q7( + q31_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q15 vector to floating-point vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q15_to_float( + q15_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q15 vector to Q31 vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q15_to_q31( + q15_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q15 vector to Q7 vector. + * @param[in] pSrc is input pointer + * @param[out] pDst is output pointer + * @param[in] blockSize is the number of samples to process + */ + void arm_q15_to_q7( + q15_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @ingroup groupInterpolation + */ + + /** + * @defgroup BilinearInterpolate Bilinear Interpolation + * + * Bilinear interpolation is an extension of linear interpolation applied to a two dimensional grid. + * The underlying function f(x, y) is sampled on a regular grid and the interpolation process + * determines values between the grid points. + * Bilinear interpolation is equivalent to two step linear interpolation, first in the x-dimension and then in the y-dimension. + * Bilinear interpolation is often used in image processing to rescale images. + * The CMSIS DSP library provides bilinear interpolation functions for Q7, Q15, Q31, and floating-point data types. + * + * Algorithm + * \par + * The instance structure used by the bilinear interpolation functions describes a two dimensional data table. + * For floating-point, the instance structure is defined as: + *
+   *   typedef struct
+   *   {
+   *     uint16_t numRows;
+   *     uint16_t numCols;
+   *     float32_t *pData;
+   * } arm_bilinear_interp_instance_f32;
+   * 
+ * + * \par + * where numRows specifies the number of rows in the table; + * numCols specifies the number of columns in the table; + * and pData points to an array of size numRows*numCols values. + * The data table pTable is organized in row order and the supplied data values fall on integer indexes. + * That is, table element (x,y) is located at pTable[x + y*numCols] where x and y are integers. + * + * \par + * Let (x, y) specify the desired interpolation point. Then define: + *
+   *     XF = floor(x)
+   *     YF = floor(y)
+   * 
+ * \par + * 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)
+   * 
+ * Note that the coordinates (x, y) contain integer and fractional components. + * The integer components specify which portion of the table to use while the + * fractional components control the interpolation processor. + * + * \par + * if (x,y) are outside of the table boundary, Bilinear interpolation returns zero output. + */ + + /** + * @addtogroup BilinearInterpolate + * @{ + */ + + + /** + * + * @brief Floating-point bilinear interpolation. + * @param[in,out] S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate. + * @param[in] Y interpolation coordinate. + * @return out interpolated value. + */ + static __INLINE float32_t arm_bilinear_interp_f32( + const arm_bilinear_interp_instance_f32 * S, + float32_t X, + float32_t Y) + { + float32_t out; + float32_t f00, f01, f10, f11; + float32_t *pData = S->pData; + int32_t xIndex, yIndex, index; + float32_t xdiff, ydiff; + float32_t b1, b2, b3, b4; + + xIndex = (int32_t) X; + yIndex = (int32_t) Y; + + /* 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)) + { + return (0); + } + + /* Calculation of index for two nearest points in X-direction */ + index = (xIndex - 1) + (yIndex - 1) * S->numCols; + + + /* Read two nearest points in X-direction */ + f00 = pData[index]; + f01 = pData[index + 1]; + + /* Calculation of index for two nearest points in Y-direction */ + index = (xIndex - 1) + (yIndex) * S->numCols; + + + /* Read two nearest points in Y-direction */ + f10 = pData[index]; + f11 = pData[index + 1]; + + /* Calculation of intermediate values */ + b1 = f00; + b2 = f01 - f00; + b3 = f10 - f00; + b4 = f00 - f01 - f10 + f11; + + /* Calculation of fractional part in X */ + xdiff = X - xIndex; + + /* Calculation of fractional part in Y */ + ydiff = Y - yIndex; + + /* Calculation of bi-linear interpolated output */ + out = b1 + b2 * xdiff + b3 * ydiff + b4 * xdiff * ydiff; + + /* return to application */ + return (out); + } + + + /** + * + * @brief Q31 bilinear interpolation. + * @param[in,out] S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate in 12.20 format. + * @param[in] Y interpolation coordinate in 12.20 format. + * @return out interpolated value. + */ + static __INLINE q31_t arm_bilinear_interp_q31( + arm_bilinear_interp_instance_q31 * S, + q31_t X, + q31_t Y) + { + q31_t out; /* Temporary output */ + q31_t acc = 0; /* output */ + q31_t xfract, yfract; /* X, Y fractional parts */ + q31_t x1, x2, y1, y2; /* Nearest output values */ + int32_t rI, cI; /* Row and column indices */ + q31_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & (q31_t)0xFFF00000) >> 20); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & (q31_t)0xFFF00000) >> 20); + + /* 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)) + { + return (0); + } + + /* 20 bits for the fractional part */ + /* shift left xfract by 11 to keep 1.31 format */ + xfract = (X & 0x000FFFFF) << 11u; + + /* Read two nearest output values from the index */ + x1 = pYData[(rI) + (int32_t)nCols * (cI) ]; + x2 = pYData[(rI) + (int32_t)nCols * (cI) + 1]; + + /* 20 bits for the fractional part */ + /* shift left yfract by 11 to keep 1.31 format */ + yfract = (Y & 0x000FFFFF) << 11u; + + /* Read two nearest output values from the index */ + y1 = pYData[(rI) + (int32_t)nCols * (cI + 1) ]; + y2 = pYData[(rI) + (int32_t)nCols * (cI + 1) + 1]; + + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 3.29(q29) format */ + out = ((q31_t) (((q63_t) x1 * (0x7FFFFFFF - xfract)) >> 32)); + acc = ((q31_t) (((q63_t) out * (0x7FFFFFFF - yfract)) >> 32)); + + /* x2 * (xfract) * (1-yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) x2 * (0x7FFFFFFF - yfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (xfract) >> 32)); + + /* y1 * (1 - xfract) * (yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) y1 * (0x7FFFFFFF - xfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (yfract) >> 32)); + + /* y2 * (xfract) * (yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) y2 * (xfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (yfract) >> 32)); + + /* Convert acc to 1.31(q31) format */ + return ((q31_t)(acc << 2)); + } + + + /** + * @brief Q15 bilinear interpolation. + * @param[in,out] S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate in 12.20 format. + * @param[in] Y interpolation coordinate in 12.20 format. + * @return out interpolated value. + */ + static __INLINE q15_t arm_bilinear_interp_q15( + arm_bilinear_interp_instance_q15 * S, + q31_t X, + q31_t Y) + { + q63_t acc = 0; /* output */ + q31_t out; /* Temporary output */ + q15_t x1, x2, y1, y2; /* Nearest output values */ + q31_t xfract, yfract; /* X, Y fractional parts */ + int32_t rI, cI; /* Row and column indices */ + q15_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & (q31_t)0xFFF00000) >> 20); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & (q31_t)0xFFF00000) >> 20); + + /* 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)) + { + return (0); + } + + /* 20 bits for the fractional part */ + /* xfract should be in 12.20 format */ + xfract = (X & 0x000FFFFF); + + /* Read two nearest output values from the index */ + x1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) ]; + x2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) + 1]; + + /* 20 bits for the fractional part */ + /* yfract should be in 12.20 format */ + yfract = (Y & 0x000FFFFF); + + /* Read two nearest output values from the index */ + y1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) ]; + y2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) + 1]; + + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 13.51 format */ + + /* x1 is in 1.15(q15), xfract in 12.20 format and out is in 13.35 format */ + /* convert 13.35 to 13.31 by right shifting and out is in 1.31 */ + out = (q31_t) (((q63_t) x1 * (0xFFFFF - xfract)) >> 4u); + acc = ((q63_t) out * (0xFFFFF - yfract)); + + /* x2 * (xfract) * (1-yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) x2 * (0xFFFFF - yfract)) >> 4u); + acc += ((q63_t) out * (xfract)); + + /* y1 * (1 - xfract) * (yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) y1 * (0xFFFFF - xfract)) >> 4u); + acc += ((q63_t) out * (yfract)); + + /* y2 * (xfract) * (yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) y2 * (xfract)) >> 4u); + acc += ((q63_t) out * (yfract)); + + /* acc is in 13.51 format and down shift acc by 36 times */ + /* Convert out to 1.15 format */ + return ((q15_t)(acc >> 36)); + } + + + /** + * @brief Q7 bilinear interpolation. + * @param[in,out] S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate in 12.20 format. + * @param[in] Y interpolation coordinate in 12.20 format. + * @return out interpolated value. + */ + static __INLINE q7_t arm_bilinear_interp_q7( + arm_bilinear_interp_instance_q7 * S, + q31_t X, + q31_t Y) + { + q63_t acc = 0; /* output */ + q31_t out; /* Temporary output */ + q31_t xfract, yfract; /* X, Y fractional parts */ + q7_t x1, x2, y1, y2; /* Nearest output values */ + int32_t rI, cI; /* Row and column indices */ + q7_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & (q31_t)0xFFF00000) >> 20); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & (q31_t)0xFFF00000) >> 20); + + /* 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)) + { + return (0); + } + + /* 20 bits for the fractional part */ + /* xfract should be in 12.20 format */ + xfract = (X & (q31_t)0x000FFFFF); + + /* Read two nearest output values from the index */ + x1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) ]; + x2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) + 1]; + + /* 20 bits for the fractional part */ + /* yfract should be in 12.20 format */ + yfract = (Y & (q31_t)0x000FFFFF); + + /* Read two nearest output values from the index */ + y1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) ]; + y2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) + 1]; + + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 16.47 format */ + out = ((x1 * (0xFFFFF - xfract))); + acc = (((q63_t) out * (0xFFFFF - yfract))); + + /* x2 * (xfract) * (1-yfract) in 2.22 and adding to acc */ + out = ((x2 * (0xFFFFF - yfract))); + acc += (((q63_t) out * (xfract))); + + /* y1 * (1 - xfract) * (yfract) in 2.22 and adding to acc */ + out = ((y1 * (0xFFFFF - xfract))); + acc += (((q63_t) out * (yfract))); + + /* y2 * (xfract) * (yfract) in 2.22 and adding to acc */ + out = ((y2 * (yfract))); + acc += (((q63_t) out * (xfract))); + + /* acc in 16.47 format and down shift by 40 to convert to 1.7 format */ + return ((q7_t)(acc >> 40)); + } + + /** + * @} end of BilinearInterpolate group + */ + + +/* SMMLAR */ +#define multAcc_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((((q63_t) a) << 32) + ((q63_t) x * y) + 0x80000000LL ) >> 32) + +/* SMMLSR */ +#define multSub_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((((q63_t) a) << 32) - ((q63_t) x * y) + 0x80000000LL ) >> 32) + +/* SMMULR */ +#define mult_32x32_keep32_R(a, x, y) \ + a = (q31_t) (((q63_t) x * y + 0x80000000LL ) >> 32) + +/* SMMLA */ +#define multAcc_32x32_keep32(a, x, y) \ + a += (q31_t) (((q63_t) x * y) >> 32) + +/* SMMLS */ +#define multSub_32x32_keep32(a, x, y) \ + a -= (q31_t) (((q63_t) x * y) >> 32) + +/* SMMUL */ +#define mult_32x32_keep32(a, x, y) \ + a = (q31_t) (((q63_t) x * y ) >> 32) + + +#if defined ( __CC_ARM ) + /* Enter low optimization region - place directly above function definition */ + #if defined( ARM_MATH_CM4 ) || defined( ARM_MATH_CM7) + #define LOW_OPTIMIZATION_ENTER \ + _Pragma ("push") \ + _Pragma ("O1") + #else + #define LOW_OPTIMIZATION_ENTER + #endif + + /* Exit low optimization region - place directly after end of function definition */ + #if defined( ARM_MATH_CM4 ) || defined( ARM_MATH_CM7) + #define LOW_OPTIMIZATION_EXIT \ + _Pragma ("pop") + #else + #define LOW_OPTIMIZATION_EXIT + #endif + + /* Enter low optimization region - place directly above function definition */ + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + + /* Exit low optimization region - place directly after end of function definition */ + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #define LOW_OPTIMIZATION_ENTER + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined(__GNUC__) + #define LOW_OPTIMIZATION_ENTER __attribute__(( optimize("-O1") )) + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined(__ICCARM__) + /* Enter low optimization region - place directly above function definition */ + #if defined( ARM_MATH_CM4 ) || defined( ARM_MATH_CM7) + #define LOW_OPTIMIZATION_ENTER \ + _Pragma ("optimize=low") + #else + #define LOW_OPTIMIZATION_ENTER + #endif + + /* Exit low optimization region - place directly after end of function definition */ + #define LOW_OPTIMIZATION_EXIT + + /* Enter low optimization region - place directly above function definition */ + #if defined( ARM_MATH_CM4 ) || defined( ARM_MATH_CM7) + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER \ + _Pragma ("optimize=low") + #else + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #endif + + /* Exit low optimization region - place directly after end of function definition */ + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined(__CSMC__) + #define LOW_OPTIMIZATION_ENTER + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#elif defined(__TASKING__) + #define LOW_OPTIMIZATION_ENTER + #define LOW_OPTIMIZATION_EXIT + #define IAR_ONLY_LOW_OPTIMIZATION_ENTER + #define IAR_ONLY_LOW_OPTIMIZATION_EXIT + +#endif + + +#ifdef __cplusplus +} +#endif + + +#if defined ( __GNUC__ ) +#pragma GCC diagnostic pop +#endif + +#endif /* _ARM_MATH_H */ + +/** + * + * End of file. + */ diff --git a/platform/mcu/lpc54102/CMSIS/Include/cmsis_armcc.h b/platform/mcu/lpc54102/CMSIS/Include/cmsis_armcc.h new file mode 100644 index 0000000000..74c49c67de --- /dev/null +++ b/platform/mcu/lpc54102/CMSIS/Include/cmsis_armcc.h @@ -0,0 +1,734 @@ +/**************************************************************************//** + * @file cmsis_armcc.h + * @brief CMSIS Cortex-M Core Function/Instruction Header File + * @version V4.30 + * @date 20. October 2015 + ******************************************************************************/ +/* Copyright (c) 2009 - 2015 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. + ---------------------------------------------------------------------------*/ + + +#ifndef __CMSIS_ARMCC_H +#define __CMSIS_ARMCC_H + + +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677) + #error "Please use ARM Compiler Toolchain V4.0.677 or later!" +#endif + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/* intrinsic void __enable_irq(); */ +/* intrinsic void __disable_irq(); */ + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_INLINE uint32_t __get_CONTROL(void) +{ + register uint32_t __regControl __ASM("control"); + return(__regControl); +} + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_INLINE void __set_CONTROL(uint32_t control) +{ + register uint32_t __regControl __ASM("control"); + __regControl = control; +} + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_INLINE uint32_t __get_IPSR(void) +{ + register uint32_t __regIPSR __ASM("ipsr"); + return(__regIPSR); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_INLINE uint32_t __get_APSR(void) +{ + register uint32_t __regAPSR __ASM("apsr"); + return(__regAPSR); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_INLINE uint32_t __get_xPSR(void) +{ + register uint32_t __regXPSR __ASM("xpsr"); + return(__regXPSR); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_INLINE uint32_t __get_PSP(void) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + return(__regProcessStackPointer); +} + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + __regProcessStackPointer = topOfProcStack; +} + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_INLINE uint32_t __get_MSP(void) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + return(__regMainStackPointer); +} + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + __regMainStackPointer = topOfMainStack; +} + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_INLINE uint32_t __get_PRIMASK(void) +{ + register uint32_t __regPriMask __ASM("primask"); + return(__regPriMask); +} + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_INLINE void __set_PRIMASK(uint32_t priMask) +{ + register uint32_t __regPriMask __ASM("primask"); + __regPriMask = (priMask); +} + + +#if (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U) + +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __enable_fault_irq __enable_fiq + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __disable_fault_irq __disable_fiq + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_INLINE uint32_t __get_BASEPRI(void) +{ + register uint32_t __regBasePri __ASM("basepri"); + return(__regBasePri); +} + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_INLINE void __set_BASEPRI(uint32_t basePri) +{ + register uint32_t __regBasePri __ASM("basepri"); + __regBasePri = (basePri & 0xFFU); +} + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + register uint32_t __regBasePriMax __ASM("basepri_max"); + __regBasePriMax = (basePri & 0xFFU); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_INLINE uint32_t __get_FAULTMASK(void) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + return(__regFaultMask); +} + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + __regFaultMask = (faultMask & (uint32_t)1); +} + +#endif /* (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U) */ + + +#if (__CORTEX_M == 0x04U) || (__CORTEX_M == 0x07U) + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +__STATIC_INLINE uint32_t __get_FPSCR(void) +{ +#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U) + register uint32_t __regfpscr __ASM("fpscr"); + return(__regfpscr); +#else + return(0U); +#endif +} + + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U) + register uint32_t __regfpscr __ASM("fpscr"); + __regfpscr = (fpscr); +#endif +} + +#endif /* (__CORTEX_M == 0x04U) || (__CORTEX_M == 0x07U) */ + + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __nop + + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI __wfi + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE __wfe + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __sev + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +#define __ISB() do {\ + __schedule_barrier();\ + __isb(0xF);\ + __schedule_barrier();\ + } while (0U) + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() do {\ + __schedule_barrier();\ + __dsb(0xF);\ + __schedule_barrier();\ + } while (0U) + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() do {\ + __schedule_barrier();\ + __dmb(0xF);\ + __schedule_barrier();\ + } while (0U) + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in integer value. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV __rev + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in two unsigned short values. + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value) +{ + rev16 r0, r0 + bx lr +} +#endif + +/** + \brief Reverse byte order in signed short value + \details Reverses the byte order in a signed short value with sign extension to integer. + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value) +{ + revsh r0, r0 + bx lr +} +#endif + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] value Value to rotate + \param [in] value Number of Bits to rotate + \return Rotated value + */ +#define __ROR __ror + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __breakpoint(value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +#if (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U) + #define __RBIT __rbit +#else +__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + int32_t s = 4 /*sizeof(v)*/ * 8 - 1; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + for (value >>= 1U; value; value >>= 1U) + { + result <<= 1U; + result |= value & 1U; + s--; + } + result <<= s; /* shift when v's highest bits are zero */ + return(result); +} +#endif + + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ __clz + + +#if (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U) + +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr)) +#else + #define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXH(ptr) ((uint16_t) __ldrex(ptr)) +#else + #define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr)) +#else + #define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXB(value, ptr) __strex(value, ptr) +#else + #define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXH(value, ptr) __strex(value, ptr) +#else + #define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXW(value, ptr) __strex(value, ptr) +#else + #define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __clrex + + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __ssat + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __usat + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value) +{ + rrx r0, r0 + bx lr +} +#endif + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr)) + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr)) + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr)) + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRBT(value, ptr) __strt(value, ptr) + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRHT(value, ptr) __strt(value, ptr) + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRT(value, ptr) __strt(value, ptr) + +#endif /* (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (__CORTEX_M >= 0x04U) /* only for Cortex-M4 and above */ + +#define __SADD8 __sadd8 +#define __QADD8 __qadd8 +#define __SHADD8 __shadd8 +#define __UADD8 __uadd8 +#define __UQADD8 __uqadd8 +#define __UHADD8 __uhadd8 +#define __SSUB8 __ssub8 +#define __QSUB8 __qsub8 +#define __SHSUB8 __shsub8 +#define __USUB8 __usub8 +#define __UQSUB8 __uqsub8 +#define __UHSUB8 __uhsub8 +#define __SADD16 __sadd16 +#define __QADD16 __qadd16 +#define __SHADD16 __shadd16 +#define __UADD16 __uadd16 +#define __UQADD16 __uqadd16 +#define __UHADD16 __uhadd16 +#define __SSUB16 __ssub16 +#define __QSUB16 __qsub16 +#define __SHSUB16 __shsub16 +#define __USUB16 __usub16 +#define __UQSUB16 __uqsub16 +#define __UHSUB16 __uhsub16 +#define __SASX __sasx +#define __QASX __qasx +#define __SHASX __shasx +#define __UASX __uasx +#define __UQASX __uqasx +#define __UHASX __uhasx +#define __SSAX __ssax +#define __QSAX __qsax +#define __SHSAX __shsax +#define __USAX __usax +#define __UQSAX __uqsax +#define __UHSAX __uhsax +#define __USAD8 __usad8 +#define __USADA8 __usada8 +#define __SSAT16 __ssat16 +#define __USAT16 __usat16 +#define __UXTB16 __uxtb16 +#define __UXTAB16 __uxtab16 +#define __SXTB16 __sxtb16 +#define __SXTAB16 __sxtab16 +#define __SMUAD __smuad +#define __SMUADX __smuadx +#define __SMLAD __smlad +#define __SMLADX __smladx +#define __SMLALD __smlald +#define __SMLALDX __smlaldx +#define __SMUSD __smusd +#define __SMUSDX __smusdx +#define __SMLSD __smlsd +#define __SMLSDX __smlsdx +#define __SMLSLD __smlsld +#define __SMLSLDX __smlsldx +#define __SEL __sel +#define __QADD __qadd +#define __QSUB __qsub + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + +#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \ + ((int64_t)(ARG3) << 32U) ) >> 32U)) + +#endif /* (__CORTEX_M >= 0x04) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#endif /* __CMSIS_ARMCC_H */ diff --git a/platform/mcu/lpc54102/CMSIS/Include/cmsis_armcc_V6.h b/platform/mcu/lpc54102/CMSIS/Include/cmsis_armcc_V6.h new file mode 100644 index 0000000000..cd13240ce3 --- /dev/null +++ b/platform/mcu/lpc54102/CMSIS/Include/cmsis_armcc_V6.h @@ -0,0 +1,1800 @@ +/**************************************************************************//** + * @file cmsis_armcc_V6.h + * @brief CMSIS Cortex-M Core Function/Instruction Header File + * @version V4.30 + * @date 20. October 2015 + ******************************************************************************/ +/* Copyright (c) 2009 - 2015 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. + ---------------------------------------------------------------------------*/ + + +#ifndef __CMSIS_ARMCC_V6_H +#define __CMSIS_ARMCC_V6_H + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__((always_inline)) __STATIC_INLINE void __enable_irq(void) +{ + __ASM volatile ("cpsie i" : : : "memory"); +} + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__((always_inline)) __STATIC_INLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i" : : : "memory"); +} + + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Control Register (non-secure) + \details Returns the content of the non-secure Control Register when in secure mode. + \return non-secure Control Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_CONTROL_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); +} + + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Control Register (non-secure) + \details Writes the given value to the non-secure Control Register when in secure state. + \param [in] control Control Register value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); +} +#endif + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get IPSR Register (non-secure) + \details Returns the content of the non-secure IPSR Register when in secure state. + \return IPSR Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_IPSR_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get APSR Register (non-secure) + \details Returns the content of the non-secure APSR Register when in secure state. + \return APSR Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_APSR_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get xPSR Register (non-secure) + \details Returns the content of the non-secure xPSR Register when in secure state. + \return xPSR Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_xPSR_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_PSP(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, psp" : "=r" (result) ); + return(result); +} + + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Process Stack Pointer (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. + \return PSP Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_PSP_NS(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : "sp"); +} + + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : "sp"); +} +#endif + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_MSP(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, msp" : "=r" (result) ); + return(result); +} + + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Main Stack Pointer (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. + \return MSP Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_MSP_NS(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : "sp"); +} + + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Main Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : "sp"); +} +#endif + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Priority Mask (non-secure) + \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. + \return Priority Mask value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_PRIMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__attribute__((always_inline)) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Priority Mask (non-secure) + \details Assigns the given value to the non-secure Priority Mask Register when in secure state. + \param [in] priMask Priority Mask + */ +__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) +{ + __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); +} +#endif + + +#if ((__ARM_ARCH_7M__ == 1U) || (__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M__ == 1U)) /* ToDo: ARMCC_V6: check if this is ok for cortex >=3 */ + +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__((always_inline)) __STATIC_INLINE void __enable_fault_irq(void) +{ + __ASM volatile ("cpsie f" : : : "memory"); +} + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__((always_inline)) __STATIC_INLINE void __disable_fault_irq(void) +{ + __ASM volatile ("cpsid f" : : : "memory"); +} + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri" : "=r" (result) ); + return(result); +} + + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Base Priority (non-secure) + \details Returns the current value of the non-secure Base Priority register when in secure state. + \return Base Priority register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_BASEPRI_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __set_BASEPRI(uint32_t value) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (value) : "memory"); +} + + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Base Priority (non-secure) + \details Assigns the given value to the non-secure Base Priority register when in secure state. + \param [in] basePri Base Priority value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_BASEPRI_NS(uint32_t value) +{ + __ASM volatile ("MSR basepri_ns, %0" : : "r" (value) : "memory"); +} +#endif + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __set_BASEPRI_MAX(uint32_t value) +{ + __ASM volatile ("MSR basepri_max, %0" : : "r" (value) : "memory"); +} + + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Base Priority with condition (non_secure) + \details Assigns the given value to the non-secure Base Priority register when in secure state only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_BASEPRI_MAX_NS(uint32_t value) +{ + __ASM volatile ("MSR basepri_max_ns, %0" : : "r" (value) : "memory"); +} +#endif + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get Fault Mask (non-secure) + \details Returns the current value of the non-secure Fault Mask register when in secure state. + \return Fault Mask register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_FAULTMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set Fault Mask (non-secure) + \details Assigns the given value to the non-secure Fault Mask register when in secure state. + \param [in] faultMask Fault Mask value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); +} +#endif + + +#endif /* ((__ARM_ARCH_7M__ == 1U) || (__ARM_ARCH_8M__ == 1U)) */ + + +#if (__ARM_ARCH_8M__ == 1U) + +/** + \brief Get Process Stack Pointer Limit + \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). + \return PSPLIM Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_PSPLIM(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, psplim" : "=r" (result) ); + return(result); +} + + +#if (__ARM_FEATURE_CMSE == 3U) && (__ARM_ARCH_PROFILE == 'M') /* ToDo: ARMCC_V6: check predefined macro for mainline */ +/** + \brief Get Process Stack Pointer Limit (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \return PSPLIM Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_PSPLIM_NS(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Process Stack Pointer Limit + \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) +{ + __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); +} + + +#if (__ARM_FEATURE_CMSE == 3U) && (__ARM_ARCH_PROFILE == 'M') /* ToDo: ARMCC_V6: check predefined macro for mainline */ +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) +{ + __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); +} +#endif + + +/** + \brief Get Main Stack Pointer Limit + \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). + \return MSPLIM Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_MSPLIM(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, msplim" : "=r" (result) ); + + return(result); +} + + +#if (__ARM_FEATURE_CMSE == 3U) && (__ARM_ARCH_PROFILE == 'M') /* ToDo: ARMCC_V6: check predefined macro for mainline */ +/** + \brief Get Main Stack Pointer Limit (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. + \return MSPLIM Register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_MSPLIM_NS(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Main Stack Pointer Limit + \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). + \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) +{ + __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); +} + + +#if (__ARM_FEATURE_CMSE == 3U) && (__ARM_ARCH_PROFILE == 'M') /* ToDo: ARMCC_V6: check predefined macro for mainline */ +/** + \brief Set Main Stack Pointer Limit (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. + \param [in] MainStackPtrLimit Main Stack Pointer value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) +{ + __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); +} +#endif + +#endif /* (__ARM_ARCH_8M__ == 1U) */ + + +#if ((__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M__ == 1U)) /* ToDo: ARMCC_V6: check if this is ok for cortex >=4 */ + +/** + \brief Get FPSCR + \details eturns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +#define __get_FPSCR __builtin_arm_get_fpscr +#if 0 +__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_FPSCR(void) +{ +#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U) + uint32_t result; + + __ASM volatile (""); /* Empty asm statement works as a scheduling barrier */ + __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); + __ASM volatile (""); + return(result); +#else + return(0); +#endif +} +#endif + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \brief Get FPSCR (non-secure) + \details Returns the current value of the non-secure Floating Point Status/Control register when in secure state. + \return Floating Point Status/Control register value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_FPSCR_NS(void) +{ +#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U) + uint32_t result; + + __ASM volatile (""); /* Empty asm statement works as a scheduling barrier */ + __ASM volatile ("VMRS %0, fpscr_ns" : "=r" (result) ); + __ASM volatile (""); + return(result); +#else + return(0); +#endif +} +#endif + + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +#define __set_FPSCR __builtin_arm_set_fpscr +#if 0 +__attribute__((always_inline)) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U) + __ASM volatile (""); /* Empty asm statement works as a scheduling barrier */ + __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc"); + __ASM volatile (""); +#endif +} +#endif + +#if (__ARM_FEATURE_CMSE == 3U) +/** + \brief Set FPSCR (non-secure) + \details Assigns the given value to the non-secure Floating Point Status/Control register when in secure state. + \param [in] fpscr Floating Point Status/Control value to set + */ +__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_FPSCR_NS(uint32_t fpscr) +{ +#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U) + __ASM volatile (""); /* Empty asm statement works as a scheduling barrier */ + __ASM volatile ("VMSR fpscr_ns, %0" : : "r" (fpscr) : "vfpcc"); + __ASM volatile (""); +#endif +} +#endif + +#endif /* ((__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M__ == 1U)) */ + + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constraint "l" + * Otherwise, use general registers, specified by constraint "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __builtin_arm_nop + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI __builtin_arm_wfi + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE __builtin_arm_wfe + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __builtin_arm_sev + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +#define __ISB() __builtin_arm_isb(0xF); + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() __builtin_arm_dsb(0xF); + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() __builtin_arm_dmb(0xF); + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in integer value. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV __builtin_bswap32 + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in two unsigned short values. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV16 __builtin_bswap16 /* ToDo: ARMCC_V6: check if __builtin_bswap16 could be used */ +#if 0 +__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV16(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} +#endif + + +/** + \brief Reverse byte order in signed short value + \details Reverses the byte order in a signed short value with sign extension to integer. + \param [in] value Value to reverse + \return Reversed value + */ + /* ToDo: ARMCC_V6: check if __builtin_bswap16 could be used */ +__attribute__((always_inline)) __STATIC_INLINE int32_t __REVSH(int32_t value) +{ + int32_t result; + + __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ + /* ToDo: ARMCC_V6: check if __builtin_arm_rbit is supported */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + +#if ((__ARM_ARCH_7M__ == 1U) || (__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M__ == 1U)) /* ToDo: ARMCC_V6: check if this is ok for cortex >=3 */ + __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); +#else + int32_t s = 4 /*sizeof(v)*/ * 8 - 1; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + for (value >>= 1U; value; value >>= 1U) + { + result <<= 1U; + result |= value & 1U; + s--; + } + result <<= s; /* shift when v's highest bits are zero */ +#endif + return(result); +} + + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ __builtin_clz + + +#if ((__ARM_ARCH_7M__ == 1U) || (__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M__ == 1U)) /* ToDo: ARMCC_V6: check if this is ok for cortex >=3 */ + +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDREXB (uint8_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDREXH (uint16_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDREXW (uint32_t)__builtin_arm_ldrex + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXB (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXH (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXW (uint32_t)__builtin_arm_strex + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __builtin_arm_clrex + + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +/*#define __SSAT __builtin_arm_ssat*/ +#define __SSAT(ARG1,ARG2) \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __builtin_arm_usat +#if 0 +#define __USAT(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) +#endif + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDRBT(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDRHT(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDRT(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__attribute__((always_inline)) __STATIC_INLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__attribute__((always_inline)) __STATIC_INLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__attribute__((always_inline)) __STATIC_INLINE void __STRT(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); +} + +#endif /* ((__ARM_ARCH_7M__ == 1U) || (__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M__ == 1U)) */ + + +#if (__ARM_ARCH_8M__ == 1U) + +/** + \brief Load-Acquire (8 bit) + \details Executes a LDAB instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDAB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire (16 bit) + \details Executes a LDAH instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDAH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire (32 bit) + \details Executes a LDA instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDA(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief Store-Release (8 bit) + \details Executes a STLB instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__attribute__((always_inline)) __STATIC_INLINE void __STLB(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (16 bit) + \details Executes a STLH instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__attribute__((always_inline)) __STATIC_INLINE void __STLH(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (32 bit) + \details Executes a STL instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__attribute__((always_inline)) __STATIC_INLINE void __STL(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Load-Acquire Exclusive (8 bit) + \details Executes a LDAB exclusive instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDAEXB (uint8_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (16 bit) + \details Executes a LDAH exclusive instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDAEXH (uint16_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (32 bit) + \details Executes a LDA exclusive instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDAEX (uint32_t)__builtin_arm_ldaex + + +/** + \brief Store-Release Exclusive (8 bit) + \details Executes a STLB exclusive instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEXB (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (16 bit) + \details Executes a STLH exclusive instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEXH (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (32 bit) + \details Executes a STL exclusive instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STLEX (uint32_t)__builtin_arm_stlex + +#endif /* (__ARM_ARCH_8M__ == 1U) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (__ARM_FEATURE_DSP == 1U) /* ToDo: ARMCC_V6: This should be ARCH >= ARMv7-M + SIMD */ + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __SASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __QASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __UASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __USAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#define __SSAT16(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +#define __USAT16(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __UXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __SXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __SEL (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE int32_t __QADD( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__((always_inline)) __STATIC_INLINE int32_t __QSUB( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +#define __PKHBT(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) + +#define __PKHTB(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + if (ARG3 == 0) \ + __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \ + else \ + __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) + +__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__ARM_FEATURE_DSP == 1U) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#endif /* __CMSIS_ARMCC_V6_H */ diff --git a/platform/mcu/lpc54102/CMSIS/Include/cmsis_gcc.h b/platform/mcu/lpc54102/CMSIS/Include/cmsis_gcc.h new file mode 100644 index 0000000000..bb89fbba9e --- /dev/null +++ b/platform/mcu/lpc54102/CMSIS/Include/cmsis_gcc.h @@ -0,0 +1,1373 @@ +/**************************************************************************//** + * @file cmsis_gcc.h + * @brief CMSIS Cortex-M Core Function/Instruction Header File + * @version V4.30 + * @date 20. October 2015 + ******************************************************************************/ +/* Copyright (c) 2009 - 2015 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. + ---------------------------------------------------------------------------*/ + + +#ifndef __CMSIS_GCC_H +#define __CMSIS_GCC_H + +/* ignore some GCC warnings */ +#if defined ( __GNUC__ ) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-conversion" +#pragma GCC diagnostic ignored "-Wconversion" +#pragma GCC diagnostic ignored "-Wunused-parameter" +#endif + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void) +{ + __ASM volatile ("cpsie i" : : : "memory"); +} + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i" : : : "memory"); +} + + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); +} + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + + \return xPSR Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PSP(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, psp\n" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) : "sp"); +} + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_MSP(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, msp\n" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) : "sp"); +} + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (__CORTEX_M >= 0x03U) + +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_fault_irq(void) +{ + __ASM volatile ("cpsie f" : : : "memory"); +} + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_fault_irq(void) +{ + __ASM volatile ("cpsid f" : : : "memory"); +} + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI(uint32_t value) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (value) : "memory"); +} + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI_MAX(uint32_t value) +{ + __ASM volatile ("MSR basepri_max, %0" : : "r" (value) : "memory"); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + +#endif /* (__CORTEX_M >= 0x03U) */ + + +#if (__CORTEX_M == 0x04U) || (__CORTEX_M == 0x07U) + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void) +{ +#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U) + uint32_t result; + + /* Empty asm statement works as a scheduling barrier */ + __ASM volatile (""); + __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); + __ASM volatile (""); + return(result); +#else + return(0); +#endif +} + + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U) + /* Empty asm statement works as a scheduling barrier */ + __ASM volatile (""); + __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc"); + __ASM volatile (""); +#endif +} + +#endif /* (__CORTEX_M == 0x04U) || (__CORTEX_M == 0x07U) */ + + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constraint "l" + * Otherwise, use general registers, specified by constraint "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +__attribute__((always_inline)) __STATIC_INLINE void __NOP(void) +{ + __ASM volatile ("nop"); +} + + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +__attribute__((always_inline)) __STATIC_INLINE void __WFI(void) +{ + __ASM volatile ("wfi"); +} + + +/** + \brief Wait For Event + \details Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +__attribute__((always_inline)) __STATIC_INLINE void __WFE(void) +{ + __ASM volatile ("wfe"); +} + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +__attribute__((always_inline)) __STATIC_INLINE void __SEV(void) +{ + __ASM volatile ("sev"); +} + + +/** + \brief Instruction Synchronization Barrier + \details Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or memory, + after the instruction has been completed. + */ +__attribute__((always_inline)) __STATIC_INLINE void __ISB(void) +{ + __ASM volatile ("isb 0xF":::"memory"); +} + + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +__attribute__((always_inline)) __STATIC_INLINE void __DSB(void) +{ + __ASM volatile ("dsb 0xF":::"memory"); +} + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +__attribute__((always_inline)) __STATIC_INLINE void __DMB(void) +{ + __ASM volatile ("dmb 0xF":::"memory"); +} + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in integer value. + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV(uint32_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) + return __builtin_bswap32(value); +#else + uint32_t result; + + __ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +#endif +} + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in two unsigned short values. + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV16(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief Reverse byte order in signed short value + \details Reverses the byte order in a signed short value with sign extension to integer. + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__((always_inline)) __STATIC_INLINE int32_t __REVSH(int32_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + return (short)__builtin_bswap16(value); +#else + int32_t result; + + __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +#endif +} + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] value Value to rotate + \param [in] value Number of Bits to rotate + \return Rotated value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + +#if (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U) + __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); +#else + int32_t s = 4 /*sizeof(v)*/ * 8 - 1; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + for (value >>= 1U; value; value >>= 1U) + { + result <<= 1U; + result |= value & 1U; + s--; + } + result <<= s; /* shift when v's highest bits are zero */ +#endif + return(result); +} + + +/** + \brief Count leading zeros + \details Counts the number of leading zeros of a data value. + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ __builtin_clz + + +#if (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U) + +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) ); + return(result); +} + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) ); + return(result); +} + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +__attribute__((always_inline)) __STATIC_INLINE void __CLREX(void) +{ + __ASM volatile ("clrex" ::: "memory"); +} + + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDRBT(volatile uint8_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrbt %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDRHT(volatile uint16_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrht %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDRT(volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*addr) ); + return(result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__attribute__((always_inline)) __STATIC_INLINE void __STRBT(uint8_t value, volatile uint8_t *addr) +{ + __ASM volatile ("strbt %1, %0" : "=Q" (*addr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__attribute__((always_inline)) __STATIC_INLINE void __STRHT(uint16_t value, volatile uint16_t *addr) +{ + __ASM volatile ("strht %1, %0" : "=Q" (*addr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__attribute__((always_inline)) __STATIC_INLINE void __STRT(uint32_t value, volatile uint32_t *addr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*addr) : "r" (value) ); +} + +#endif /* (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (__CORTEX_M >= 0x04U) /* only for Cortex-M4 and above */ + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#define __SSAT16(ARG1,ARG2) \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +#define __USAT16(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SEL (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE int32_t __QADD( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE int32_t __QSUB( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +#define __PKHBT(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) + +#define __PKHTB(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + if (ARG3 == 0) \ + __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \ + else \ + __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__CORTEX_M >= 0x04) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#if defined ( __GNUC__ ) +#pragma GCC diagnostic pop +#endif + +#endif /* __CMSIS_GCC_H */ diff --git a/platform/mcu/lpc54102/CMSIS/Include/core_cm0.h b/platform/mcu/lpc54102/CMSIS/Include/core_cm0.h new file mode 100644 index 0000000000..711dad5517 --- /dev/null +++ b/platform/mcu/lpc54102/CMSIS/Include/core_cm0.h @@ -0,0 +1,798 @@ +/**************************************************************************//** + * @file core_cm0.h + * @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File + * @version V4.30 + * @date 20. October 2015 + ******************************************************************************/ +/* Copyright (c) 2009 - 2015 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. + ---------------------------------------------------------------------------*/ + + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM0_H_GENERIC +#define __CORE_CM0_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M0 + @{ + */ + +/* CMSIS CM0 definitions */ +#define __CM0_CMSIS_VERSION_MAIN (0x04U) /*!< [31:16] CMSIS HAL main version */ +#define __CM0_CMSIS_VERSION_SUB (0x1EU) /*!< [15:0] CMSIS HAL sub version */ +#define __CM0_CMSIS_VERSION ((__CM0_CMSIS_VERSION_MAIN << 16U) | \ + __CM0_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + +#define __CORTEX_M (0x00U) /*!< Cortex-M Core */ + + +#if defined ( __CC_ARM ) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + #define __STATIC_INLINE static __inline + +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + #define __STATIC_INLINE static __inline + +#elif defined ( __GNUC__ ) + #define __ASM __asm /*!< asm keyword for GNU Compiler */ + #define __INLINE inline /*!< inline keyword for GNU Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __ICCARM__ ) + #define __ASM __asm /*!< asm keyword for IAR Compiler */ + #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ + #define __STATIC_INLINE static inline + +#elif defined ( __TMS470__ ) + #define __ASM __asm /*!< asm keyword for TI CCS Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __TASKING__ ) + #define __ASM __asm /*!< asm keyword for TASKING Compiler */ + #define __INLINE inline /*!< inline keyword for TASKING Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __CSMC__ ) + #define __packed + #define __ASM _asm /*!< asm keyword for COSMIC Compiler */ + #define __INLINE inline /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */ + #define __STATIC_INLINE static inline + +#else + #error Unknown compiler +#endif + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TMS470__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "core_cmInstr.h" /* Core Instruction Access */ +#include "core_cmFunc.h" /* Core Function Access */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM0_H_DEPENDANT +#define __CORE_CM0_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM0_REV + #define __CM0_REV 0x0000U + #warning "__CM0_REV not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M0 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t _reserved0:1; /*!< bit: 0 Reserved */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31U]; + __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[31U]; + __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31U]; + __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31U]; + uint32_t RESERVED4[64U]; + __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + uint32_t RESERVED0; + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED1; + __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Cortex-M0 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor. + Therefore they are not covered by the Cortex-M0 header file. + @{ + */ +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Cortex-M0 Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +/* Interrupt Priorities are WORD accessible only under ARMv6M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + + +/** + \brief Enable External Interrupt + \details Enables a device-specific interrupt in the NVIC interrupt controller. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) +{ + NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Disable External Interrupt + \details Disables a device-specific interrupt in the NVIC interrupt controller. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) +{ + NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Get Pending Interrupt + \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt. + \param [in] IRQn Interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + */ +__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of an external interrupt. + \param [in] IRQn Interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of an external interrupt. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of an interrupt. + \note The priority cannot be set for every core interrupt. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + */ +__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) < 0) + { + SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of an interrupt. + The interrupt number can be positive to specify an external (device specific) interrupt, + or negative to specify an internal (core) interrupt. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) < 0) + { + return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/platform/mcu/lpc54102/CMSIS/Include/core_cm0plus.h b/platform/mcu/lpc54102/CMSIS/Include/core_cm0plus.h new file mode 100644 index 0000000000..b04aa39053 --- /dev/null +++ b/platform/mcu/lpc54102/CMSIS/Include/core_cm0plus.h @@ -0,0 +1,914 @@ +/**************************************************************************//** + * @file core_cm0plus.h + * @brief CMSIS Cortex-M0+ Core Peripheral Access Layer Header File + * @version V4.30 + * @date 20. October 2015 + ******************************************************************************/ +/* Copyright (c) 2009 - 2015 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. + ---------------------------------------------------------------------------*/ + + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM0PLUS_H_GENERIC +#define __CORE_CM0PLUS_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex-M0+ + @{ + */ + +/* CMSIS CM0+ definitions */ +#define __CM0PLUS_CMSIS_VERSION_MAIN (0x04U) /*!< [31:16] CMSIS HAL main version */ +#define __CM0PLUS_CMSIS_VERSION_SUB (0x1EU) /*!< [15:0] CMSIS HAL sub version */ +#define __CM0PLUS_CMSIS_VERSION ((__CM0PLUS_CMSIS_VERSION_MAIN << 16U) | \ + __CM0PLUS_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + +#define __CORTEX_M (0x00U) /*!< Cortex-M Core */ + + +#if defined ( __CC_ARM ) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + #define __STATIC_INLINE static __inline + +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + #define __STATIC_INLINE static __inline + +#elif defined ( __GNUC__ ) + #define __ASM __asm /*!< asm keyword for GNU Compiler */ + #define __INLINE inline /*!< inline keyword for GNU Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __ICCARM__ ) + #define __ASM __asm /*!< asm keyword for IAR Compiler */ + #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ + #define __STATIC_INLINE static inline + +#elif defined ( __TMS470__ ) + #define __ASM __asm /*!< asm keyword for TI CCS Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __TASKING__ ) + #define __ASM __asm /*!< asm keyword for TASKING Compiler */ + #define __INLINE inline /*!< inline keyword for TASKING Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __CSMC__ ) + #define __packed + #define __ASM _asm /*!< asm keyword for COSMIC Compiler */ + #define __INLINE inline /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */ + #define __STATIC_INLINE static inline + +#else + #error Unknown compiler +#endif + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TMS470__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "core_cmInstr.h" /* Core Instruction Access */ +#include "core_cmFunc.h" /* Core Function Access */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0PLUS_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM0PLUS_H_DEPENDANT +#define __CORE_CM0PLUS_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM0PLUS_REV + #define __CM0PLUS_REV 0x0000U + #warning "__CM0PLUS_REV not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 0U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex-M0+ */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core MPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31U]; + __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[31U]; + __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31U]; + __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31U]; + uint32_t RESERVED4[64U]; + __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ +#if (__VTOR_PRESENT == 1U) + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ +#else + uint32_t RESERVED0; +#endif + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED1; + __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +#if (__VTOR_PRESENT == 1U) +/* SCB Interrupt Control State Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 8U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0xFFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#endif + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + +#if (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 8U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Cortex-M0+ Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor. + Therefore they are not covered by the Cortex-M0+ header file. + @{ + */ +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Cortex-M0+ Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + +#if (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +/* Interrupt Priorities are WORD accessible only under ARMv6M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + + +/** + \brief Enable External Interrupt + \details Enables a device-specific interrupt in the NVIC interrupt controller. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) +{ + NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Disable External Interrupt + \details Disables a device-specific interrupt in the NVIC interrupt controller. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) +{ + NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Get Pending Interrupt + \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt. + \param [in] IRQn Interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + */ +__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of an external interrupt. + \param [in] IRQn Interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of an external interrupt. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of an interrupt. + \note The priority cannot be set for every core interrupt. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + */ +__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) < 0) + { + SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of an interrupt. + The interrupt number can be positive to specify an external (device specific) interrupt, + or negative to specify an internal (core) interrupt. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) < 0) + { + return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0PLUS_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/platform/mcu/lpc54102/CMSIS/Include/core_cm3.h b/platform/mcu/lpc54102/CMSIS/Include/core_cm3.h new file mode 100644 index 0000000000..b4ac4c7b05 --- /dev/null +++ b/platform/mcu/lpc54102/CMSIS/Include/core_cm3.h @@ -0,0 +1,1763 @@ +/**************************************************************************//** + * @file core_cm3.h + * @brief CMSIS Cortex-M3 Core Peripheral Access Layer Header File + * @version V4.30 + * @date 20. October 2015 + ******************************************************************************/ +/* Copyright (c) 2009 - 2015 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. + ---------------------------------------------------------------------------*/ + + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM3_H_GENERIC +#define __CORE_CM3_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M3 + @{ + */ + +/* CMSIS CM3 definitions */ +#define __CM3_CMSIS_VERSION_MAIN (0x04U) /*!< [31:16] CMSIS HAL main version */ +#define __CM3_CMSIS_VERSION_SUB (0x1EU) /*!< [15:0] CMSIS HAL sub version */ +#define __CM3_CMSIS_VERSION ((__CM3_CMSIS_VERSION_MAIN << 16U) | \ + __CM3_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + +#define __CORTEX_M (0x03U) /*!< Cortex-M Core */ + + +#if defined ( __CC_ARM ) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + #define __STATIC_INLINE static __inline + +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + #define __STATIC_INLINE static __inline + +#elif defined ( __GNUC__ ) + #define __ASM __asm /*!< asm keyword for GNU Compiler */ + #define __INLINE inline /*!< inline keyword for GNU Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __ICCARM__ ) + #define __ASM __asm /*!< asm keyword for IAR Compiler */ + #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ + #define __STATIC_INLINE static inline + +#elif defined ( __TMS470__ ) + #define __ASM __asm /*!< asm keyword for TI CCS Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __TASKING__ ) + #define __ASM __asm /*!< asm keyword for TASKING Compiler */ + #define __INLINE inline /*!< inline keyword for TASKING Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __CSMC__ ) + #define __packed + #define __ASM _asm /*!< asm keyword for COSMIC Compiler */ + #define __INLINE inline /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */ + #define __STATIC_INLINE static inline + +#else + #error Unknown compiler +#endif + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TMS470__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "core_cmInstr.h" /* Core Instruction Access */ +#include "core_cmFunc.h" /* Core Function Access */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM3_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM3_H_DEPENDANT +#define __CORE_CM3_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM3_REV + #define __CM3_REV 0x0200U + #warning "__CM3_REV not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 4U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M3 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_IT_Pos 25U /*!< xPSR: IT Position */ +#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24U]; + __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[24U]; + __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24U]; + __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24U]; + __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56U]; + __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHP[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5U]; + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#if (__CM3_REV < 0x0201U) /* core r2p1 */ +#define SCB_VTOR_TBLBASE_Pos 29U /*!< SCB VTOR: TBLBASE Position */ +#define SCB_VTOR_TBLBASE_Msk (1UL << SCB_VTOR_TBLBASE_Pos) /*!< SCB VTOR: TBLBASE Mask */ + +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x3FFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#else +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#endif + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ +#if ((defined __CM3_REV) && (__CM3_REV >= 0x200U)) + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +#else + uint32_t RESERVED1[1U]; +#endif +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1U /*!< ACTLR: DISDEFWBUF Position */ +#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[29U]; + __OM uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ + __IM uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ + __IOM uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Integration Write Register Definitions */ +#define ITM_IWR_ATVALIDM_Pos 0U /*!< ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1UL /*<< ITM_IWR_ATVALIDM_Pos*/) /*!< ITM IWR: ATVALIDM Mask */ + +/* ITM Integration Read Register Definitions */ +#define ITM_IRR_ATREADYM_Pos 0U /*!< ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1UL /*<< ITM_IRR_ATREADYM_Pos*/) /*!< ITM IRR: ATREADYM Mask */ + +/* ITM Integration Mode Control Register Definitions */ +#define ITM_IMCR_INTEGRATION_Pos 0U /*!< ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/) /*!< ITM IMCR: INTEGRATION Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IOM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY_Pos 0U /*!< TPI ITATBCTR2: ATREADY Position */ +#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY_Pos 0U /*!< TPI ITATBCTR0: ATREADY Position */ +#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_MajorType_Pos 4U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +#define TPI_DEVTYPE_SubType_Pos 0U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Cortex-M3 Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << 8U) ); /* Insert write key and priorty group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable External Interrupt + \details Enables a device-specific interrupt in the NVIC interrupt controller. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) +{ + NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Disable External Interrupt + \details Disables a device-specific interrupt in the NVIC interrupt controller. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) +{ + NVIC->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Get Pending Interrupt + \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt. + \param [in] IRQn Interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + */ +__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + return((uint32_t)(((NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of an external interrupt. + \param [in] IRQn Interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of an external interrupt. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in NVIC and returns the active bit. + \param [in] IRQn Interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + */ +__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) +{ + return((uint32_t)(((NVIC->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of an interrupt. + \note The priority cannot be set for every core interrupt. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + */ +__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) < 0) + { + SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + NVIC->IP[((uint32_t)(int32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of an interrupt. + The interrupt number can be positive to specify an external (device specific) interrupt, + or negative to specify an internal (core) interrupt. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) < 0) + { + return(((uint32_t)SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)NVIC->IP[((uint32_t)(int32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY 0x5AA55AA5U /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM3_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/platform/mcu/lpc54102/CMSIS/Include/core_cm4.h b/platform/mcu/lpc54102/CMSIS/Include/core_cm4.h new file mode 100644 index 0000000000..dc840ebf22 --- /dev/null +++ b/platform/mcu/lpc54102/CMSIS/Include/core_cm4.h @@ -0,0 +1,1937 @@ +/**************************************************************************//** + * @file core_cm4.h + * @brief CMSIS Cortex-M4 Core Peripheral Access Layer Header File + * @version V4.30 + * @date 20. October 2015 + ******************************************************************************/ +/* Copyright (c) 2009 - 2015 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. + ---------------------------------------------------------------------------*/ + + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM4_H_GENERIC +#define __CORE_CM4_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M4 + @{ + */ + +/* CMSIS CM4 definitions */ +#define __CM4_CMSIS_VERSION_MAIN (0x04U) /*!< [31:16] CMSIS HAL main version */ +#define __CM4_CMSIS_VERSION_SUB (0x1EU) /*!< [15:0] CMSIS HAL sub version */ +#define __CM4_CMSIS_VERSION ((__CM4_CMSIS_VERSION_MAIN << 16U) | \ + __CM4_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + +#define __CORTEX_M (0x04U) /*!< Cortex-M Core */ + + +#if defined ( __CC_ARM ) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + #define __STATIC_INLINE static __inline + +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + #define __STATIC_INLINE static __inline + +#elif defined ( __GNUC__ ) + #define __ASM __asm /*!< asm keyword for GNU Compiler */ + #define __INLINE inline /*!< inline keyword for GNU Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __ICCARM__ ) + #define __ASM __asm /*!< asm keyword for IAR Compiler */ + #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ + #define __STATIC_INLINE static inline + +#elif defined ( __TMS470__ ) + #define __ASM __asm /*!< asm keyword for TI CCS Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __TASKING__ ) + #define __ASM __asm /*!< asm keyword for TASKING Compiler */ + #define __INLINE inline /*!< inline keyword for TASKING Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __CSMC__ ) + #define __packed + #define __ASM _asm /*!< asm keyword for COSMIC Compiler */ + #define __INLINE inline /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */ + #define __STATIC_INLINE static inline + +#else + #error Unknown compiler +#endif + +/** __FPU_USED indicates whether an FPU is used or not. + For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #if (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TMS470__ ) + #if defined __TI_VFP_SUPPORT__ + #if (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "core_cmInstr.h" /* Core Instruction Access */ +#include "core_cmFunc.h" /* Core Function Access */ +#include "core_cmSimd.h" /* Compiler specific SIMD Intrinsics */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM4_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM4_H_DEPENDANT +#define __CORE_CM4_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM4_REV + #define __CM4_REV 0x0000U + #warning "__CM4_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 4U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M4 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_IT_Pos 25U /*!< xPSR: IT Position */ +#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ + uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24U]; + __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[24U]; + __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24U]; + __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24U]; + __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56U]; + __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHP[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5U]; + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_DISOOFP_Pos 9U /*!< ACTLR: DISOOFP Position */ +#define SCnSCB_ACTLR_DISOOFP_Msk (1UL << SCnSCB_ACTLR_DISOOFP_Pos) /*!< ACTLR: DISOOFP Mask */ + +#define SCnSCB_ACTLR_DISFPCA_Pos 8U /*!< ACTLR: DISFPCA Position */ +#define SCnSCB_ACTLR_DISFPCA_Msk (1UL << SCnSCB_ACTLR_DISFPCA_Pos) /*!< ACTLR: DISFPCA Mask */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1U /*!< ACTLR: DISDEFWBUF Position */ +#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[29U]; + __OM uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ + __IM uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ + __IOM uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Integration Write Register Definitions */ +#define ITM_IWR_ATVALIDM_Pos 0U /*!< ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1UL /*<< ITM_IWR_ATVALIDM_Pos*/) /*!< ITM IWR: ATVALIDM Mask */ + +/* ITM Integration Read Register Definitions */ +#define ITM_IRR_ATREADYM_Pos 0U /*!< ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1UL /*<< ITM_IRR_ATREADYM_Pos*/) /*!< ITM IRR: ATREADYM Mask */ + +/* ITM Integration Mode Control Register Definitions */ +#define ITM_IMCR_INTEGRATION_Pos 0U /*!< ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/) /*!< ITM IMCR: INTEGRATION Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IOM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY_Pos 0U /*!< TPI ITATBCTR2: ATREADY Position */ +#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY_Pos 0U /*!< TPI ITATBCTR0: ATREADY Position */ +#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_MajorType_Pos 4U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +#define TPI_DEVTYPE_SubType_Pos 0U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if (__FPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and FP Feature Register 0 Definitions */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */ +#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ + +#define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */ +#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ + +#define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */ +#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ + +#define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */ +#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */ +#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ + +#define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */ +#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ + +#define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */ +#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ + +#define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */ +#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */ + +/* Media and FP Feature Register 1 Definitions */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */ +#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ + +#define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */ +#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ + +#define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */ +#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ + +#define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ + +/*@} end of group CMSIS_FPU */ +#endif + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Cortex-M4 Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +#if (__FPU_PRESENT == 1U) + #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ + #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << 8U) ); /* Insert write key and priorty group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable External Interrupt + \details Enables a device-specific interrupt in the NVIC interrupt controller. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) +{ + NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Disable External Interrupt + \details Disables a device-specific interrupt in the NVIC interrupt controller. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) +{ + NVIC->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Get Pending Interrupt + \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt. + \param [in] IRQn Interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + */ +__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + return((uint32_t)(((NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of an external interrupt. + \param [in] IRQn Interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of an external interrupt. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in NVIC and returns the active bit. + \param [in] IRQn Interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + */ +__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) +{ + return((uint32_t)(((NVIC->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of an interrupt. + \note The priority cannot be set for every core interrupt. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + */ +__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) < 0) + { + SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + NVIC->IP[((uint32_t)(int32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of an interrupt. + The interrupt number can be positive to specify an external (device specific) interrupt, + or negative to specify an internal (core) interrupt. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) < 0) + { + return(((uint32_t)SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)NVIC->IP[((uint32_t)(int32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY 0x5AA55AA5U /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM4_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/platform/mcu/lpc54102/CMSIS/Include/core_cm7.h b/platform/mcu/lpc54102/CMSIS/Include/core_cm7.h new file mode 100644 index 0000000000..3b7530ad50 --- /dev/null +++ b/platform/mcu/lpc54102/CMSIS/Include/core_cm7.h @@ -0,0 +1,2512 @@ +/**************************************************************************//** + * @file core_cm7.h + * @brief CMSIS Cortex-M7 Core Peripheral Access Layer Header File + * @version V4.30 + * @date 20. October 2015 + ******************************************************************************/ +/* Copyright (c) 2009 - 2015 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. + ---------------------------------------------------------------------------*/ + + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM7_H_GENERIC +#define __CORE_CM7_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex_M7 + @{ + */ + +/* CMSIS CM7 definitions */ +#define __CM7_CMSIS_VERSION_MAIN (0x04U) /*!< [31:16] CMSIS HAL main version */ +#define __CM7_CMSIS_VERSION_SUB (0x1EU) /*!< [15:0] CMSIS HAL sub version */ +#define __CM7_CMSIS_VERSION ((__CM7_CMSIS_VERSION_MAIN << 16U) | \ + __CM7_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + +#define __CORTEX_M (0x07U) /*!< Cortex-M Core */ + + +#if defined ( __CC_ARM ) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + #define __STATIC_INLINE static __inline + +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + #define __STATIC_INLINE static __inline + +#elif defined ( __GNUC__ ) + #define __ASM __asm /*!< asm keyword for GNU Compiler */ + #define __INLINE inline /*!< inline keyword for GNU Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __ICCARM__ ) + #define __ASM __asm /*!< asm keyword for IAR Compiler */ + #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ + #define __STATIC_INLINE static inline + +#elif defined ( __TMS470__ ) + #define __ASM __asm /*!< asm keyword for TI CCS Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __TASKING__ ) + #define __ASM __asm /*!< asm keyword for TASKING Compiler */ + #define __INLINE inline /*!< inline keyword for TASKING Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __CSMC__ ) + #define __packed + #define __ASM _asm /*!< asm keyword for COSMIC Compiler */ + #define __INLINE inline /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */ + #define __STATIC_INLINE static inline + +#else + #error Unknown compiler +#endif + +/** __FPU_USED indicates whether an FPU is used or not. + For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #if (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TMS470__ ) + #if defined __TI_VFP_SUPPORT__ + #if (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #if (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#endif + +#include "core_cmInstr.h" /* Core Instruction Access */ +#include "core_cmFunc.h" /* Core Function Access */ +#include "core_cmSimd.h" /* Compiler specific SIMD Intrinsics */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM7_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM7_H_DEPENDANT +#define __CORE_CM7_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM7_REV + #define __CM7_REV 0x0000U + #warning "__CM7_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __ICACHE_PRESENT + #define __ICACHE_PRESENT 0U + #warning "__ICACHE_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DCACHE_PRESENT + #define __DCACHE_PRESENT 0U + #warning "__DCACHE_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __DTCM_PRESENT + #define __DTCM_PRESENT 0U + #warning "__DTCM_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 3U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex_M7 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core FPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + +#define APSR_GE_Pos 16U /*!< APSR: GE Position */ +#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_IT_Pos 25U /*!< xPSR: IT Position */ +#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */ +#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ + uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */ +#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */ + +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24U]; + __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[24U]; + __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24U]; + __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24U]; + __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56U]; + __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHPR[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ID_AFR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t ID_MFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ID_ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[1U]; + __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */ + __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */ + __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */ + __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */ + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + uint32_t RESERVED3[93U]; + __OM uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */ + uint32_t RESERVED4[15U]; + __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 1 */ + uint32_t RESERVED5[1U]; + __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */ + uint32_t RESERVED6[1U]; + __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */ + __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */ + __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */ + __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */ + __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */ + __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */ + __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */ + __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */ + uint32_t RESERVED7[6U]; + __IOM uint32_t ITCMCR; /*!< Offset: 0x290 (R/W) Instruction Tightly-Coupled Memory Control Register */ + __IOM uint32_t DTCMCR; /*!< Offset: 0x294 (R/W) Data Tightly-Coupled Memory Control Registers */ + __IOM uint32_t AHBPCR; /*!< Offset: 0x298 (R/W) AHBP Control Register */ + __IOM uint32_t CACR; /*!< Offset: 0x29C (R/W) L1 Cache Control Register */ + __IOM uint32_t AHBSCR; /*!< Offset: 0x2A0 (R/W) AHB Slave Control Register */ + uint32_t RESERVED8[1U]; + __IOM uint32_t ABFSR; /*!< Offset: 0x2A8 (R/W) Auxiliary Bus Fault Status Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: Branch prediction enable bit Position */ +#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: Branch prediction enable bit Mask */ + +#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: Instruction cache enable bit Position */ +#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: Instruction cache enable bit Mask */ + +#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: Cache enable bit Position */ +#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: Cache enable bit Mask */ + +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/* SCB Cache Level ID Register Definitions */ +#define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */ +#define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */ + +#define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */ +#define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */ + +/* SCB Cache Type Register Definitions */ +#define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */ +#define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */ + +#define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */ +#define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */ + +#define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */ +#define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */ + +#define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */ +#define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */ + +#define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */ +#define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */ + +/* SCB Cache Size ID Register Definitions */ +#define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */ +#define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */ + +#define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */ +#define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */ + +#define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */ +#define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */ + +#define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */ +#define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */ + +#define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */ +#define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */ + +#define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */ +#define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */ + +#define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */ +#define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */ + +/* SCB Cache Size Selection Register Definitions */ +#define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */ +#define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */ + +#define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */ +#define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */ + +/* SCB Software Triggered Interrupt Register Definitions */ +#define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */ +#define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */ + +/* SCB D-Cache Invalidate by Set-way Register Definitions */ +#define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */ +#define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */ + +#define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */ +#define SCB_DCISW_SET_Msk (0x1FFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */ + +/* SCB D-Cache Clean by Set-way Register Definitions */ +#define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */ +#define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */ + +#define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */ +#define SCB_DCCSW_SET_Msk (0x1FFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */ + +/* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */ +#define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */ +#define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */ + +#define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */ +#define SCB_DCCISW_SET_Msk (0x1FFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set Mask */ + +/* Instruction Tightly-Coupled Memory Control Register Definitions */ +#define SCB_ITCMCR_SZ_Pos 3U /*!< SCB ITCMCR: SZ Position */ +#define SCB_ITCMCR_SZ_Msk (0xFUL << SCB_ITCMCR_SZ_Pos) /*!< SCB ITCMCR: SZ Mask */ + +#define SCB_ITCMCR_RETEN_Pos 2U /*!< SCB ITCMCR: RETEN Position */ +#define SCB_ITCMCR_RETEN_Msk (1UL << SCB_ITCMCR_RETEN_Pos) /*!< SCB ITCMCR: RETEN Mask */ + +#define SCB_ITCMCR_RMW_Pos 1U /*!< SCB ITCMCR: RMW Position */ +#define SCB_ITCMCR_RMW_Msk (1UL << SCB_ITCMCR_RMW_Pos) /*!< SCB ITCMCR: RMW Mask */ + +#define SCB_ITCMCR_EN_Pos 0U /*!< SCB ITCMCR: EN Position */ +#define SCB_ITCMCR_EN_Msk (1UL /*<< SCB_ITCMCR_EN_Pos*/) /*!< SCB ITCMCR: EN Mask */ + +/* Data Tightly-Coupled Memory Control Register Definitions */ +#define SCB_DTCMCR_SZ_Pos 3U /*!< SCB DTCMCR: SZ Position */ +#define SCB_DTCMCR_SZ_Msk (0xFUL << SCB_DTCMCR_SZ_Pos) /*!< SCB DTCMCR: SZ Mask */ + +#define SCB_DTCMCR_RETEN_Pos 2U /*!< SCB DTCMCR: RETEN Position */ +#define SCB_DTCMCR_RETEN_Msk (1UL << SCB_DTCMCR_RETEN_Pos) /*!< SCB DTCMCR: RETEN Mask */ + +#define SCB_DTCMCR_RMW_Pos 1U /*!< SCB DTCMCR: RMW Position */ +#define SCB_DTCMCR_RMW_Msk (1UL << SCB_DTCMCR_RMW_Pos) /*!< SCB DTCMCR: RMW Mask */ + +#define SCB_DTCMCR_EN_Pos 0U /*!< SCB DTCMCR: EN Position */ +#define SCB_DTCMCR_EN_Msk (1UL /*<< SCB_DTCMCR_EN_Pos*/) /*!< SCB DTCMCR: EN Mask */ + +/* AHBP Control Register Definitions */ +#define SCB_AHBPCR_SZ_Pos 1U /*!< SCB AHBPCR: SZ Position */ +#define SCB_AHBPCR_SZ_Msk (7UL << SCB_AHBPCR_SZ_Pos) /*!< SCB AHBPCR: SZ Mask */ + +#define SCB_AHBPCR_EN_Pos 0U /*!< SCB AHBPCR: EN Position */ +#define SCB_AHBPCR_EN_Msk (1UL /*<< SCB_AHBPCR_EN_Pos*/) /*!< SCB AHBPCR: EN Mask */ + +/* L1 Cache Control Register Definitions */ +#define SCB_CACR_FORCEWT_Pos 2U /*!< SCB CACR: FORCEWT Position */ +#define SCB_CACR_FORCEWT_Msk (1UL << SCB_CACR_FORCEWT_Pos) /*!< SCB CACR: FORCEWT Mask */ + +#define SCB_CACR_ECCEN_Pos 1U /*!< SCB CACR: ECCEN Position */ +#define SCB_CACR_ECCEN_Msk (1UL << SCB_CACR_ECCEN_Pos) /*!< SCB CACR: ECCEN Mask */ + +#define SCB_CACR_SIWT_Pos 0U /*!< SCB CACR: SIWT Position */ +#define SCB_CACR_SIWT_Msk (1UL /*<< SCB_CACR_SIWT_Pos*/) /*!< SCB CACR: SIWT Mask */ + +/* AHBS Control Register Definitions */ +#define SCB_AHBSCR_INITCOUNT_Pos 11U /*!< SCB AHBSCR: INITCOUNT Position */ +#define SCB_AHBSCR_INITCOUNT_Msk (0x1FUL << SCB_AHBPCR_INITCOUNT_Pos) /*!< SCB AHBSCR: INITCOUNT Mask */ + +#define SCB_AHBSCR_TPRI_Pos 2U /*!< SCB AHBSCR: TPRI Position */ +#define SCB_AHBSCR_TPRI_Msk (0x1FFUL << SCB_AHBPCR_TPRI_Pos) /*!< SCB AHBSCR: TPRI Mask */ + +#define SCB_AHBSCR_CTL_Pos 0U /*!< SCB AHBSCR: CTL Position*/ +#define SCB_AHBSCR_CTL_Msk (3UL /*<< SCB_AHBPCR_CTL_Pos*/) /*!< SCB AHBSCR: CTL Mask */ + +/* Auxiliary Bus Fault Status Register Definitions */ +#define SCB_ABFSR_AXIMTYPE_Pos 8U /*!< SCB ABFSR: AXIMTYPE Position*/ +#define SCB_ABFSR_AXIMTYPE_Msk (3UL << SCB_ABFSR_AXIMTYPE_Pos) /*!< SCB ABFSR: AXIMTYPE Mask */ + +#define SCB_ABFSR_EPPB_Pos 4U /*!< SCB ABFSR: EPPB Position*/ +#define SCB_ABFSR_EPPB_Msk (1UL << SCB_ABFSR_EPPB_Pos) /*!< SCB ABFSR: EPPB Mask */ + +#define SCB_ABFSR_AXIM_Pos 3U /*!< SCB ABFSR: AXIM Position*/ +#define SCB_ABFSR_AXIM_Msk (1UL << SCB_ABFSR_AXIM_Pos) /*!< SCB ABFSR: AXIM Mask */ + +#define SCB_ABFSR_AHBP_Pos 2U /*!< SCB ABFSR: AHBP Position*/ +#define SCB_ABFSR_AHBP_Msk (1UL << SCB_ABFSR_AHBP_Pos) /*!< SCB ABFSR: AHBP Mask */ + +#define SCB_ABFSR_DTCM_Pos 1U /*!< SCB ABFSR: DTCM Position*/ +#define SCB_ABFSR_DTCM_Msk (1UL << SCB_ABFSR_DTCM_Pos) /*!< SCB ABFSR: DTCM Mask */ + +#define SCB_ABFSR_ITCM_Pos 0U /*!< SCB ABFSR: ITCM Position*/ +#define SCB_ABFSR_ITCM_Msk (1UL /*<< SCB_ABFSR_ITCM_Pos*/) /*!< SCB ABFSR: ITCM Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_DISITMATBFLUSH_Pos 12U /*!< ACTLR: DISITMATBFLUSH Position */ +#define SCnSCB_ACTLR_DISITMATBFLUSH_Msk (1UL << SCnSCB_ACTLR_DISITMATBFLUSH_Pos) /*!< ACTLR: DISITMATBFLUSH Mask */ + +#define SCnSCB_ACTLR_DISRAMODE_Pos 11U /*!< ACTLR: DISRAMODE Position */ +#define SCnSCB_ACTLR_DISRAMODE_Msk (1UL << SCnSCB_ACTLR_DISRAMODE_Pos) /*!< ACTLR: DISRAMODE Mask */ + +#define SCnSCB_ACTLR_FPEXCODIS_Pos 10U /*!< ACTLR: FPEXCODIS Position */ +#define SCnSCB_ACTLR_FPEXCODIS_Msk (1UL << SCnSCB_ACTLR_FPEXCODIS_Pos) /*!< ACTLR: FPEXCODIS Mask */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[29U]; + __OM uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ + __IM uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ + __IOM uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Integration Write Register Definitions */ +#define ITM_IWR_ATVALIDM_Pos 0U /*!< ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1UL /*<< ITM_IWR_ATVALIDM_Pos*/) /*!< ITM IWR: ATVALIDM Mask */ + +/* ITM Integration Read Register Definitions */ +#define ITM_IRR_ATREADYM_Pos 0U /*!< ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1UL /*<< ITM_IRR_ATREADYM_Pos*/) /*!< ITM IRR: ATREADYM Mask */ + +/* ITM Integration Mode Control Register Definitions */ +#define ITM_IMCR_INTEGRATION_Pos 0U /*!< ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/) /*!< ITM IMCR: INTEGRATION Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ + uint32_t RESERVED3[981U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( W) Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IOM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY_Pos 0U /*!< TPI ITATBCTR2: ATREADY Position */ +#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY_Pos 0U /*!< TPI ITATBCTR0: ATREADY Position */ +#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_MajorType_Pos 4U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +#define TPI_DEVTYPE_SubType_Pos 0U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if (__FPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** + \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ + __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ + __IM uint32_t MVFR2; /*!< Offset: 0x018 (R/ ) Media and FP Feature Register 2 */ +} FPU_Type; + +/* Floating-Point Context Control Register Definitions */ +#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register Definitions */ +#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register Definitions */ +#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and FP Feature Register 0 Definitions */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */ +#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ + +#define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */ +#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ + +#define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */ +#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ + +#define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */ +#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */ +#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ + +#define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */ +#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ + +#define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */ +#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ + +#define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */ +#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */ + +/* Media and FP Feature Register 1 Definitions */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */ +#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ + +#define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */ +#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ + +#define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */ +#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ + +#define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */ + +/* Media and FP Feature Register 2 Definitions */ + +/*@} end of group CMSIS_FPU */ +#endif + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Cortex-M4 Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +#if (__FPU_PRESENT == 1U) + #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ + #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << 8U) ); /* Insert write key and priorty group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable External Interrupt + \details Enables a device-specific interrupt in the NVIC interrupt controller. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) +{ + NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Disable External Interrupt + \details Disables a device-specific interrupt in the NVIC interrupt controller. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) +{ + NVIC->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Get Pending Interrupt + \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt. + \param [in] IRQn Interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + */ +__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + return((uint32_t)(((NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of an external interrupt. + \param [in] IRQn Interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of an external interrupt. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in NVIC and returns the active bit. + \param [in] IRQn Interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + */ +__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) +{ + return((uint32_t)(((NVIC->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of an interrupt. + \note The priority cannot be set for every core interrupt. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + */ +__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) < 0) + { + SCB->SHPR[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + NVIC->IP[((uint32_t)(int32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of an interrupt. + The interrupt number can be positive to specify an external (device specific) interrupt, + or negative to specify an internal (core) interrupt. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) < 0) + { + return(((uint32_t)SCB->SHPR[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)NVIC->IP[((uint32_t)(int32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + uint32_t mvfr0; + + mvfr0 = SCB->MVFR0; + if ((mvfr0 & 0x00000FF0UL) == 0x220UL) + { + return 2UL; /* Double + Single precision FPU */ + } + else if ((mvfr0 & 0x00000FF0UL) == 0x020UL) + { + return 1UL; /* Single precision FPU */ + } + else + { + return 0UL; /* No FPU */ + } +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ########################## Cache functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_CacheFunctions Cache Functions + \brief Functions that configure Instruction and Data cache. + @{ + */ + +/* Cache Size ID Register Macros */ +#define CCSIDR_WAYS(x) (((x) & SCB_CCSIDR_ASSOCIATIVITY_Msk) >> SCB_CCSIDR_ASSOCIATIVITY_Pos) +#define CCSIDR_SETS(x) (((x) & SCB_CCSIDR_NUMSETS_Msk ) >> SCB_CCSIDR_NUMSETS_Pos ) + + +/** + \brief Enable I-Cache + \details Turns on I-Cache + */ +__STATIC_INLINE void SCB_EnableICache (void) +{ + #if (__ICACHE_PRESENT == 1U) + __DSB(); + __ISB(); + SCB->ICIALLU = 0UL; /* invalidate I-Cache */ + SCB->CCR |= (uint32_t)SCB_CCR_IC_Msk; /* enable I-Cache */ + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Disable I-Cache + \details Turns off I-Cache + */ +__STATIC_INLINE void SCB_DisableICache (void) +{ + #if (__ICACHE_PRESENT == 1U) + __DSB(); + __ISB(); + SCB->CCR &= ~(uint32_t)SCB_CCR_IC_Msk; /* disable I-Cache */ + SCB->ICIALLU = 0UL; /* invalidate I-Cache */ + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Invalidate I-Cache + \details Invalidates I-Cache + */ +__STATIC_INLINE void SCB_InvalidateICache (void) +{ + #if (__ICACHE_PRESENT == 1U) + __DSB(); + __ISB(); + SCB->ICIALLU = 0UL; + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Enable D-Cache + \details Turns on D-Cache + */ +__STATIC_INLINE void SCB_EnableDCache (void) +{ + #if (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = (0U << 1U) | 0U; /* Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) | + ((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways--); + } while(sets--); + __DSB(); + + SCB->CCR |= (uint32_t)SCB_CCR_DC_Msk; /* enable D-Cache */ + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Disable D-Cache + \details Turns off D-Cache + */ +__STATIC_INLINE void SCB_DisableDCache (void) +{ + #if (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = (0U << 1U) | 0U; /* Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + SCB->CCR &= ~(uint32_t)SCB_CCR_DC_Msk; /* disable D-Cache */ + + /* clean & invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCCISW = (((sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) | + ((ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways--); + } while(sets--); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Invalidate D-Cache + \details Invalidates D-Cache + */ +__STATIC_INLINE void SCB_InvalidateDCache (void) +{ + #if (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = (0U << 1U) | 0U; /* Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) | + ((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways--); + } while(sets--); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Clean D-Cache + \details Cleans D-Cache + */ +__STATIC_INLINE void SCB_CleanDCache (void) +{ + #if (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = (0U << 1U) | 0U; /* Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* clean D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCCSW = (((sets << SCB_DCCSW_SET_Pos) & SCB_DCCSW_SET_Msk) | + ((ways << SCB_DCCSW_WAY_Pos) & SCB_DCCSW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways--); + } while(sets--); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief Clean & Invalidate D-Cache + \details Cleans and Invalidates D-Cache + */ +__STATIC_INLINE void SCB_CleanInvalidateDCache (void) +{ + #if (__DCACHE_PRESENT == 1U) + uint32_t ccsidr; + uint32_t sets; + uint32_t ways; + + SCB->CSSELR = (0U << 1U) | 0U; /* Level 1 data cache */ + __DSB(); + + ccsidr = SCB->CCSIDR; + + /* clean & invalidate D-Cache */ + sets = (uint32_t)(CCSIDR_SETS(ccsidr)); + do { + ways = (uint32_t)(CCSIDR_WAYS(ccsidr)); + do { + SCB->DCCISW = (((sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) | + ((ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk) ); + #if defined ( __CC_ARM ) + __schedule_barrier(); + #endif + } while (ways--); + } while(sets--); + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief D-Cache Invalidate by address + \details Invalidates D-Cache for the given address + \param[in] addr address (aligned to 32-byte boundary) + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_INLINE void SCB_InvalidateDCache_by_Addr (uint32_t *addr, int32_t dsize) +{ + #if (__DCACHE_PRESENT == 1U) + int32_t op_size = dsize; + uint32_t op_addr = (uint32_t)addr; + int32_t linesize = 32U; /* in Cortex-M7 size of cache line is fixed to 8 words (32 bytes) */ + + __DSB(); + + while (op_size > 0) { + SCB->DCIMVAC = op_addr; + op_addr += linesize; + op_size -= linesize; + } + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief D-Cache Clean by address + \details Cleans D-Cache for the given address + \param[in] addr address (aligned to 32-byte boundary) + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_INLINE void SCB_CleanDCache_by_Addr (uint32_t *addr, int32_t dsize) +{ + #if (__DCACHE_PRESENT == 1) + int32_t op_size = dsize; + uint32_t op_addr = (uint32_t) addr; + int32_t linesize = 32U; /* in Cortex-M7 size of cache line is fixed to 8 words (32 bytes) */ + + __DSB(); + + while (op_size > 0) { + SCB->DCCMVAC = op_addr; + op_addr += linesize; + op_size -= linesize; + } + + __DSB(); + __ISB(); + #endif +} + + +/** + \brief D-Cache Clean and Invalidate by address + \details Cleans and invalidates D_Cache for the given address + \param[in] addr address (aligned to 32-byte boundary) + \param[in] dsize size of memory block (in number of bytes) +*/ +__STATIC_INLINE void SCB_CleanInvalidateDCache_by_Addr (uint32_t *addr, int32_t dsize) +{ + #if (__DCACHE_PRESENT == 1U) + int32_t op_size = dsize; + uint32_t op_addr = (uint32_t) addr; + int32_t linesize = 32U; /* in Cortex-M7 size of cache line is fixed to 8 words (32 bytes) */ + + __DSB(); + + while (op_size > 0) { + SCB->DCCIMVAC = op_addr; + op_addr += linesize; + op_size -= linesize; + } + + __DSB(); + __ISB(); + #endif +} + + +/*@} end of CMSIS_Core_CacheFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY 0x5AA55AA5U /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM7_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/platform/mcu/lpc54102/CMSIS/Include/core_cmFunc.h b/platform/mcu/lpc54102/CMSIS/Include/core_cmFunc.h new file mode 100644 index 0000000000..652a48af07 --- /dev/null +++ b/platform/mcu/lpc54102/CMSIS/Include/core_cmFunc.h @@ -0,0 +1,87 @@ +/**************************************************************************//** + * @file core_cmFunc.h + * @brief CMSIS Cortex-M Core Function Access Header File + * @version V4.30 + * @date 20. October 2015 + ******************************************************************************/ +/* Copyright (c) 2009 - 2015 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. + ---------------------------------------------------------------------------*/ + + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CMFUNC_H +#define __CORE_CMFUNC_H + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ +*/ + +/*------------------ RealView Compiler -----------------*/ +#if defined ( __CC_ARM ) + #include "cmsis_armcc.h" + +/*------------------ ARM Compiler V6 -------------------*/ +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #include "cmsis_armcc_V6.h" + +/*------------------ GNU Compiler ----------------------*/ +#elif defined ( __GNUC__ ) + #include "cmsis_gcc.h" + +/*------------------ ICC Compiler ----------------------*/ +#elif defined ( __ICCARM__ ) + #include + +/*------------------ TI CCS Compiler -------------------*/ +#elif defined ( __TMS470__ ) + #include + +/*------------------ TASKING Compiler ------------------*/ +#elif defined ( __TASKING__ ) + /* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all intrinsics, + * Including the CMSIS ones. + */ + +/*------------------ COSMIC Compiler -------------------*/ +#elif defined ( __CSMC__ ) + #include + +#endif + +/*@} end of CMSIS_Core_RegAccFunctions */ + +#endif /* __CORE_CMFUNC_H */ diff --git a/platform/mcu/lpc54102/CMSIS/Include/core_cmInstr.h b/platform/mcu/lpc54102/CMSIS/Include/core_cmInstr.h new file mode 100644 index 0000000000..f474b0e6f3 --- /dev/null +++ b/platform/mcu/lpc54102/CMSIS/Include/core_cmInstr.h @@ -0,0 +1,87 @@ +/**************************************************************************//** + * @file core_cmInstr.h + * @brief CMSIS Cortex-M Core Instruction Access Header File + * @version V4.30 + * @date 20. October 2015 + ******************************************************************************/ +/* Copyright (c) 2009 - 2015 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. + ---------------------------------------------------------------------------*/ + + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CMINSTR_H +#define __CORE_CMINSTR_H + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/*------------------ RealView Compiler -----------------*/ +#if defined ( __CC_ARM ) + #include "cmsis_armcc.h" + +/*------------------ ARM Compiler V6 -------------------*/ +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #include "cmsis_armcc_V6.h" + +/*------------------ GNU Compiler ----------------------*/ +#elif defined ( __GNUC__ ) + #include "cmsis_gcc.h" + +/*------------------ ICC Compiler ----------------------*/ +#elif defined ( __ICCARM__ ) + #include + +/*------------------ TI CCS Compiler -------------------*/ +#elif defined ( __TMS470__ ) + #include + +/*------------------ TASKING Compiler ------------------*/ +#elif defined ( __TASKING__ ) + /* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all intrinsics, + * Including the CMSIS ones. + */ + +/*------------------ COSMIC Compiler -------------------*/ +#elif defined ( __CSMC__ ) + #include + +#endif + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + +#endif /* __CORE_CMINSTR_H */ diff --git a/platform/mcu/lpc54102/CMSIS/Include/core_cmSimd.h b/platform/mcu/lpc54102/CMSIS/Include/core_cmSimd.h new file mode 100644 index 0000000000..66bf5c2a72 --- /dev/null +++ b/platform/mcu/lpc54102/CMSIS/Include/core_cmSimd.h @@ -0,0 +1,96 @@ +/**************************************************************************//** + * @file core_cmSimd.h + * @brief CMSIS Cortex-M SIMD Header File + * @version V4.30 + * @date 20. October 2015 + ******************************************************************************/ +/* Copyright (c) 2009 - 2015 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. + ---------------------------------------------------------------------------*/ + + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CMSIMD_H +#define __CORE_CMSIMD_H + +#ifdef __cplusplus + extern "C" { +#endif + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +/*------------------ RealView Compiler -----------------*/ +#if defined ( __CC_ARM ) + #include "cmsis_armcc.h" + +/*------------------ ARM Compiler V6 -------------------*/ +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #include "cmsis_armcc_V6.h" + +/*------------------ GNU Compiler ----------------------*/ +#elif defined ( __GNUC__ ) + #include "cmsis_gcc.h" + +/*------------------ ICC Compiler ----------------------*/ +#elif defined ( __ICCARM__ ) + #include + +/*------------------ TI CCS Compiler -------------------*/ +#elif defined ( __TMS470__ ) + #include + +/*------------------ TASKING Compiler ------------------*/ +#elif defined ( __TASKING__ ) + /* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all intrinsics, + * Including the CMSIS ones. + */ + +/*------------------ COSMIC Compiler -------------------*/ +#elif defined ( __CSMC__ ) + #include + +#endif + +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CMSIMD_H */ diff --git a/platform/mcu/lpc54102/CMSIS/Include/core_sc000.h b/platform/mcu/lpc54102/CMSIS/Include/core_sc000.h new file mode 100644 index 0000000000..514dbd81b9 --- /dev/null +++ b/platform/mcu/lpc54102/CMSIS/Include/core_sc000.h @@ -0,0 +1,926 @@ +/**************************************************************************//** + * @file core_sc000.h + * @brief CMSIS SC000 Core Peripheral Access Layer Header File + * @version V4.30 + * @date 20. October 2015 + ******************************************************************************/ +/* Copyright (c) 2009 - 2015 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. + ---------------------------------------------------------------------------*/ + + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_SC000_H_GENERIC +#define __CORE_SC000_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup SC000 + @{ + */ + +/* CMSIS SC000 definitions */ +#define __SC000_CMSIS_VERSION_MAIN (0x04U) /*!< [31:16] CMSIS HAL main version */ +#define __SC000_CMSIS_VERSION_SUB (0x1EU) /*!< [15:0] CMSIS HAL sub version */ +#define __SC000_CMSIS_VERSION ((__SC000_CMSIS_VERSION_MAIN << 16U) | \ + __SC000_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + +#define __CORTEX_SC (000U) /*!< Cortex secure core */ + + +#if defined ( __CC_ARM ) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + #define __STATIC_INLINE static __inline + +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + #define __STATIC_INLINE static __inline + +#elif defined ( __GNUC__ ) + #define __ASM __asm /*!< asm keyword for GNU Compiler */ + #define __INLINE inline /*!< inline keyword for GNU Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __ICCARM__ ) + #define __ASM __asm /*!< asm keyword for IAR Compiler */ + #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ + #define __STATIC_INLINE static inline + +#elif defined ( __TMS470__ ) + #define __ASM __asm /*!< asm keyword for TI CCS Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __TASKING__ ) + #define __ASM __asm /*!< asm keyword for TASKING Compiler */ + #define __INLINE inline /*!< inline keyword for TASKING Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __CSMC__ ) + #define __packed + #define __ASM _asm /*!< asm keyword for COSMIC Compiler */ + #define __INLINE inline /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */ + #define __STATIC_INLINE static inline + +#else + #error Unknown compiler +#endif + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TMS470__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "core_cmInstr.h" /* Core Instruction Access */ +#include "core_cmFunc.h" /* Core Function Access */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_SC000_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_SC000_H_DEPENDANT +#define __CORE_SC000_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __SC000_REV + #define __SC000_REV 0x0000U + #warning "__SC000_REV not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group SC000 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core MPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t _reserved0:1; /*!< bit: 0 Reserved */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31U]; + __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[31U]; + __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31U]; + __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31U]; + uint32_t RESERVED4[64U]; + __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED0[1U]; + __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + uint32_t RESERVED1[154U]; + __IOM uint32_t SFCR; /*!< Offset: 0x290 (R/W) Security Features Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + +#if (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 8U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief SC000 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor. + Therefore they are not covered by the SC000 header file. + @{ + */ +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of SC000 Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + +#if (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +/* Interrupt Priorities are WORD accessible only under ARMv6M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + + +/** + \brief Enable External Interrupt + \details Enables a device-specific interrupt in the NVIC interrupt controller. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) +{ + NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Disable External Interrupt + \details Disables a device-specific interrupt in the NVIC interrupt controller. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) +{ + NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Get Pending Interrupt + \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt. + \param [in] IRQn Interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + */ +__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of an external interrupt. + \param [in] IRQn Interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of an external interrupt. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of an interrupt. + \note The priority cannot be set for every core interrupt. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + */ +__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) < 0) + { + SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of an interrupt. + The interrupt number can be positive to specify an external (device specific) interrupt, + or negative to specify an internal (core) interrupt. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) < 0) + { + return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_SC000_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/platform/mcu/lpc54102/CMSIS/Include/core_sc300.h b/platform/mcu/lpc54102/CMSIS/Include/core_sc300.h new file mode 100644 index 0000000000..8bd18aa318 --- /dev/null +++ b/platform/mcu/lpc54102/CMSIS/Include/core_sc300.h @@ -0,0 +1,1745 @@ +/**************************************************************************//** + * @file core_sc300.h + * @brief CMSIS SC300 Core Peripheral Access Layer Header File + * @version V4.30 + * @date 20. October 2015 + ******************************************************************************/ +/* Copyright (c) 2009 - 2015 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. + ---------------------------------------------------------------------------*/ + + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_SC300_H_GENERIC +#define __CORE_SC300_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup SC3000 + @{ + */ + +/* CMSIS SC300 definitions */ +#define __SC300_CMSIS_VERSION_MAIN (0x04U) /*!< [31:16] CMSIS HAL main version */ +#define __SC300_CMSIS_VERSION_SUB (0x1EU) /*!< [15:0] CMSIS HAL sub version */ +#define __SC300_CMSIS_VERSION ((__SC300_CMSIS_VERSION_MAIN << 16U) | \ + __SC300_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + +#define __CORTEX_SC (300U) /*!< Cortex secure core */ + + +#if defined ( __CC_ARM ) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + #define __STATIC_INLINE static __inline + +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + #define __STATIC_INLINE static __inline + +#elif defined ( __GNUC__ ) + #define __ASM __asm /*!< asm keyword for GNU Compiler */ + #define __INLINE inline /*!< inline keyword for GNU Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __ICCARM__ ) + #define __ASM __asm /*!< asm keyword for IAR Compiler */ + #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ + #define __STATIC_INLINE static inline + +#elif defined ( __TMS470__ ) + #define __ASM __asm /*!< asm keyword for TI CCS Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __TASKING__ ) + #define __ASM __asm /*!< asm keyword for TASKING Compiler */ + #define __INLINE inline /*!< inline keyword for TASKING Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __CSMC__ ) + #define __packed + #define __ASM _asm /*!< asm keyword for COSMIC Compiler */ + #define __INLINE inline /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */ + #define __STATIC_INLINE static inline + +#else + #error Unknown compiler +#endif + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TMS470__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "core_cmInstr.h" /* Core Instruction Access */ +#include "core_cmFunc.h" /* Core Function Access */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_SC300_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_SC300_H_DEPENDANT +#define __CORE_SC300_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __SC300_REV + #define __SC300_REV 0x0000U + #warning "__SC300_REV not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 4U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group SC300 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + +#define APSR_Q_Pos 27U /*!< APSR: Q Position */ +#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */ + + +/** + \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */ +#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */ + +#define xPSR_IT_Pos 25U /*!< xPSR: IT Position */ +#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} end of group CMSIS_CORE */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** + \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24U]; + __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[24U]; + __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24U]; + __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24U]; + __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56U]; + __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644U]; + __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IOM uint8_t SHP[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __IM uint32_t PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __IM uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __IM uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __IM uint32_t MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __IM uint32_t ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5U]; + __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + uint32_t RESERVED1[129U]; + __IOM uint32_t SFCR; /*!< Offset: 0x290 (R/W) Security Features Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLBASE_Pos 29U /*!< SCB VTOR: TBLBASE Position */ +#define SCB_VTOR_TBLBASE_Msk (1UL << SCB_VTOR_TBLBASE_Pos) /*!< SCB VTOR: TBLBASE Mask */ + +#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x3FFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Register Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* SCB Hard Fault Status Register Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** + \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1U]; + __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + uint32_t RESERVED1[1U]; +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** + \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __OM union + { + __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864U]; + __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15U]; + __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15U]; + __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[29U]; + __OM uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ + __IM uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ + __IOM uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + uint32_t RESERVED4[43U]; + __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6U]; + __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Integration Write Register Definitions */ +#define ITM_IWR_ATVALIDM_Pos 0U /*!< ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1UL /*<< ITM_IWR_ATVALIDM_Pos*/) /*!< ITM IWR: ATVALIDM Mask */ + +/* ITM Integration Read Register Definitions */ +#define ITM_IRR_ATREADYM_Pos 0U /*!< ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1UL /*<< ITM_IRR_ATREADYM_Pos*/) /*!< ITM IRR: ATREADYM Mask */ + +/* ITM Integration Mode Control Register Definitions */ +#define ITM_IMCR_INTEGRATION_Pos 0U /*!< ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/) /*!< ITM IMCR: INTEGRATION Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** + \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1U]; + __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1U]; + __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1U]; + __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** + \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IOM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2U]; + __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55U]; + __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131U]; + __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759U]; + __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ + __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1U]; + __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39U]; + __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8U]; + __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY_Pos 0U /*!< TPI ITATBCTR2: ATREADY Position */ +#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY_Pos 0U /*!< TPI ITATBCTR0: ATREADY Position */ +#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_MajorType_Pos 4U /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +#define TPI_DEVTYPE_SubType_Pos 0U /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if (__MPU_PRESENT == 1U) +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** + \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** + \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register Definitions */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register Definitions */ +#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register Definitions */ +#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Cortex-M3 Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +/** + \brief Set Priority Grouping + \details Sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << 8U) ); /* Insert write key and priorty group */ + SCB->AIRCR = reg_value; +} + + +/** + \brief Get Priority Grouping + \details Reads the priority grouping field from the NVIC Interrupt Controller. + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void) +{ + return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos)); +} + + +/** + \brief Enable External Interrupt + \details Enables a device-specific interrupt in the NVIC interrupt controller. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) +{ + NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Disable External Interrupt + \details Disables a device-specific interrupt in the NVIC interrupt controller. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) +{ + NVIC->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Get Pending Interrupt + \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt. + \param [in] IRQn Interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + */ +__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + return((uint32_t)(((NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of an external interrupt. + \param [in] IRQn Interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of an external interrupt. + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL)); +} + + +/** + \brief Get Active Interrupt + \details Reads the active register in NVIC and returns the active bit. + \param [in] IRQn Interrupt number. + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + */ +__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) +{ + return((uint32_t)(((NVIC->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of an interrupt. + \note The priority cannot be set for every core interrupt. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + */ +__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) < 0) + { + SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } + else + { + NVIC->IP[((uint32_t)(int32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of an interrupt. + The interrupt number can be positive to specify an external (device specific) interrupt, + or negative to specify an internal (core) interrupt. + \param [in] IRQn Interrupt number. + \return Interrupt Priority. + Value is aligned automatically to the implemented priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) +{ + + if ((int32_t)(IRQn) < 0) + { + return(((uint32_t)SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return(((uint32_t)NVIC->IP[((uint32_t)(int32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details Encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details Decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set. + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details Initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + \param [in] ticks Number of ticks between two interrupts. + \return 0 Function succeeded. + \return 1 Function failed. + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY 0x5AA55AA5U /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** + \brief ITM Send Character + \details Transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + \param [in] ch Character to transmit. + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */ + ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0U].u32 == 0UL) + { + __NOP(); + } + ITM->PORT[0U].u8 = (uint8_t)ch; + } + return (ch); +} + + +/** + \brief ITM Receive Character + \details Inputs a character via the external variable \ref ITM_RxBuffer. + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) +{ + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) + { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** + \brief ITM Check Character + \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) +{ + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) + { + return (0); /* no character available */ + } + else + { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_SC300_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/platform/mcu/lpc54102/CMSIS/Lib/GCC/libarm_cortexM0l_math.a b/platform/mcu/lpc54102/CMSIS/Lib/GCC/libarm_cortexM0l_math.a new file mode 100644 index 0000000000..b1159d7360 Binary files /dev/null and b/platform/mcu/lpc54102/CMSIS/Lib/GCC/libarm_cortexM0l_math.a differ diff --git a/platform/mcu/lpc54102/CMSIS/Lib/GCC/libarm_cortexM4lf_math.a b/platform/mcu/lpc54102/CMSIS/Lib/GCC/libarm_cortexM4lf_math.a new file mode 100644 index 0000000000..1ad5280915 Binary files /dev/null and b/platform/mcu/lpc54102/CMSIS/Lib/GCC/libarm_cortexM4lf_math.a differ diff --git a/platform/mcu/lpc54102/CMSIS/Lib/license.txt b/platform/mcu/lpc54102/CMSIS/Lib/license.txt new file mode 100644 index 0000000000..139c1ff8d4 --- /dev/null +++ b/platform/mcu/lpc54102/CMSIS/Lib/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/platform/mcu/lpc54102/CMSIS/index.html b/platform/mcu/lpc54102/CMSIS/index.html new file mode 100644 index 0000000000..c6da0802b4 --- /dev/null +++ b/platform/mcu/lpc54102/CMSIS/index.html @@ -0,0 +1,14 @@ + + + +Redirect to the CMSIS main page after 0 seconds + + + + + + +If the automatic redirection is failing, click open CMSIS Documentation. + + + diff --git a/platform/mcu/lpc54102/LPC54102_cm0plus.h b/platform/mcu/lpc54102/LPC54102_cm0plus.h new file mode 100644 index 0000000000..b1e3e93668 --- /dev/null +++ b/platform/mcu/lpc54102/LPC54102_cm0plus.h @@ -0,0 +1,5558 @@ +/* +** ################################################################### +** Processors: LPC54102J256BD64_cm0plus +** LPC54102J256UK49_cm0plus +** LPC54102J512BD64_cm0plus +** LPC54102J512UK49_cm0plus +** +** Compilers: Keil ARM C/C++ Compiler +** IAR ANSI C/C++ Compiler for ARM +** MCUXpresso Compiler +** +** Reference manual: LPC5410x User manual Rev. 2.4 25 May 2016 +** Version: rev. 1.0, 2016-04-29 +** Build: b170504 +** +** Abstract: +** CMSIS Peripheral Access Layer for LPC54102_cm0plus +** +** Copyright 1997-2016 Freescale Semiconductor, Inc. +** Copyright 2016-2017 NXP +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o 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. +** +** o Neither the name of the copyright holder nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.nxp.com +** mail: support@nxp.com +** +** Revisions: +** - rev. 1.0 (2016-04-29) +** Initial version. +** +** ################################################################### +*/ + +/*! + * @file LPC54102_cm0plus.h + * @version 1.0 + * @date 2016-04-29 + * @brief CMSIS Peripheral Access Layer for LPC54102_cm0plus + * + * CMSIS Peripheral Access Layer for LPC54102_cm0plus + */ + +#ifndef _LPC54102_CM0PLUS_H_ +#define _LPC54102_CM0PLUS_H_ /**< Symbol preventing repeated inclusion */ + +/** Memory map major version (memory maps with equal major version number are + * compatible) */ +#define MCU_MEM_MAP_VERSION 0x0100U +/** Memory map minor version */ +#define MCU_MEM_MAP_VERSION_MINOR 0x0000U + + +/* ---------------------------------------------------------------------------- + -- Interrupt vector numbers + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup Interrupt_vector_numbers Interrupt vector numbers + * @{ + */ + +/** Interrupt Number Definitions */ +#define NUMBER_OF_INT_VECTORS 48 /**< Number of interrupts in the Vector table */ + +typedef enum IRQn { + /* Auxiliary constants */ + NotAvail_IRQn = -128, /**< Not available device specific interrupt */ + + /* Core interrupts */ + NonMaskableInt_IRQn = -14, /**< Non Maskable Interrupt */ + HardFault_IRQn = -13, /**< Cortex-M0 SV Hard Fault Interrupt */ + SVCall_IRQn = -5, /**< Cortex-M0 SV Call Interrupt */ + PendSV_IRQn = -2, /**< Cortex-M0 Pend SV Interrupt */ + SysTick_IRQn = -1, /**< Cortex-M0 System Tick Interrupt */ + + /* Device specific interrupts */ + WDT_IRQn = 0, /**< Windowed watchdog timer, Brownout detect */ + BOD_IRQn = 1, /**< BOD interrupt */ + Reserved18_IRQn = 2, /**< Reserved interrupt */ + DMA0_IRQn = 3, /**< DMA controller */ + GINT0_IRQn = 4, /**< GPIO group 0 */ + PIN_INT0_IRQn = 5, /**< Pin interrupt 0 or pattern match engine slice 0 */ + PIN_INT1_IRQn = 6, /**< Pin interrupt 1or pattern match engine slice 1 */ + PIN_INT2_IRQn = 7, /**< Pin interrupt 2 or pattern match engine slice 2 */ + PIN_INT3_IRQn = 8, /**< Pin interrupt 3 or pattern match engine slice 3 */ + UTICK0_IRQn = 9, /**< Micro-tick Timer */ + MRT0_IRQn = 10, /**< Multi-rate timer */ + CTIMER0_IRQn = 11, /**< Standard counter/timer CTIMER0 */ + CTIMER1_IRQn = 12, /**< Standard counter/timer CTIMER1 */ + CTIMER2_IRQn = 13, /**< Standard counter/timer CTIMER2 */ + CTIMER3_IRQn = 14, /**< Standard counter/timer CTIMER3 */ + CTIMER4_IRQn = 15, /**< Standard counter/timer CTIMER4 */ + SCT0_IRQn = 16, /**< SCTimer/PWM */ + USART0_IRQn = 17, /**< USART0 */ + USART1_IRQn = 18, /**< USART1 */ + USART2_IRQn = 19, /**< USART2 */ + USART3_IRQn = 20, /**< USART3 */ + I2C0_IRQn = 21, /**< I2C0 */ + I2C1_IRQn = 22, /**< I2C1 */ + I2C2_IRQn = 23, /**< I2C2 */ + SPI0_IRQn = 24, /**< SPI0 */ + SPI1_IRQn = 25, /**< SPI1 */ + ADC0_SEQA_IRQn = 26, /**< ADC0 sequence A completion. */ + ADC0_SEQB_IRQn = 27, /**< ADC0 sequence B completion. */ + ADC0_THCMP_IRQn = 28, /**< ADC0 threshold compare and error. */ + RTC_IRQn = 29, /**< RTC alarm and wake-up interrupts */ + Reserved46_IRQn = 30, /**< Reserved interrupt */ + MAILBOX_IRQn = 31 /**< Mailbox interrupt (present on selected devices) */ +} IRQn_Type; + +/*! + * @} + */ /* end of group Interrupt_vector_numbers */ + + +/* ---------------------------------------------------------------------------- + -- Cortex M0 Core Configuration + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup Cortex_Core_Configuration Cortex M0 Core Configuration + * @{ + */ + +#define __CM0PLUS_REV 0x0000 /**< Core revision r0p0 */ +#define __MPU_PRESENT 0 /**< Defines if an MPU is present or not */ +#define __VTOR_PRESENT 1 /**< Defines if VTOR is present or not */ +#define __NVIC_PRIO_BITS 2 /**< Number of priority bits implemented in the NVIC */ +#define __Vendor_SysTickConfig 0 /**< Vendor specific implementation of SysTickConfig is defined */ + +#include "core_cm0plus.h" /* Core Peripheral Access Layer */ +#include "system_LPC54102_cm0plus.h" /* Device specific configuration file */ + +/*! + * @} + */ /* end of group Cortex_Core_Configuration */ + + +/* ---------------------------------------------------------------------------- + -- Device Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup Peripheral_access_layer Device Peripheral Access Layer + * @{ + */ + + +/* +** Start of section using anonymous unions +*/ + +#if defined(__ARMCC_VERSION) + #pragma push + #pragma anon_unions +#elif defined(__IAR_SYSTEMS_ICC__) + #pragma language=extended +#elif defined(__GNUC__) + /* anonymous unions are enabled by default */ +#else + #error Not supported compiler type +#endif + +/* ---------------------------------------------------------------------------- + -- ADC Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup ADC_Peripheral_Access_Layer ADC Peripheral Access Layer + * @{ + */ + +/** ADC - Register Layout Typedef */ +typedef struct { + __IO uint32_t CTRL; /**< ADC Control register. Contains the clock divide value, resolution selection, sampling time selection, and mode controls., offset: 0x0 */ + uint8_t RESERVED_0[4]; + __IO uint32_t SEQ_CTRL[2]; /**< ADC Conversion Sequence-n control register: Controls triggering and channel selection for conversion sequence-n. Also specifies interrupt mode for sequence-n., array offset: 0x8, array step: 0x4 */ + __I uint32_t SEQ_GDAT[2]; /**< ADC Sequence-n Global Data register. This register contains the result of the most recent ADC conversion performed under sequence-n., array offset: 0x10, array step: 0x4 */ + uint8_t RESERVED_1[8]; + __I uint32_t DAT[12]; /**< ADC Channel 0 Data register. This register contains the result of the most recent conversion completed on channel 0., array offset: 0x20, array step: 0x4 */ + __IO uint32_t THR0_LOW; /**< ADC Low Compare Threshold register 0: Contains the lower threshold level for automatic threshold comparison for any channels linked to threshold pair 0., offset: 0x50 */ + __IO uint32_t THR1_LOW; /**< ADC Low Compare Threshold register 1: Contains the lower threshold level for automatic threshold comparison for any channels linked to threshold pair 1., offset: 0x54 */ + __IO uint32_t THR0_HIGH; /**< ADC High Compare Threshold register 0: Contains the upper threshold level for automatic threshold comparison for any channels linked to threshold pair 0., offset: 0x58 */ + __IO uint32_t THR1_HIGH; /**< ADC High Compare Threshold register 1: Contains the upper threshold level for automatic threshold comparison for any channels linked to threshold pair 1., offset: 0x5C */ + __IO uint32_t CHAN_THRSEL; /**< ADC Channel-Threshold Select register. Specifies which set of threshold compare registers are to be used for each channel, offset: 0x60 */ + __IO uint32_t INTEN; /**< ADC Interrupt Enable register. This register contains enable bits that enable the sequence-A, sequence-B, threshold compare and data overrun interrupts to be generated., offset: 0x64 */ + __IO uint32_t FLAGS; /**< ADC Flags register. Contains the four interrupt/DMA trigger flags and the individual component overrun and threshold-compare flags. (The overrun bits replicate information stored in the result registers)., offset: 0x68 */ + __IO uint32_t STARTUP; /**< ADC Startup register., offset: 0x6C */ + __IO uint32_t CALIB; /**< ADC Calibration register., offset: 0x70 */ +} ADC_Type; + +/* ---------------------------------------------------------------------------- + -- ADC Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup ADC_Register_Masks ADC Register Masks + * @{ + */ + +/*! @name CTRL - ADC Control register. Contains the clock divide value, resolution selection, sampling time selection, and mode controls. */ +#define ADC_CTRL_CLKDIV_MASK (0xFFU) +#define ADC_CTRL_CLKDIV_SHIFT (0U) +#define ADC_CTRL_CLKDIV(x) (((uint32_t)(((uint32_t)(x)) << ADC_CTRL_CLKDIV_SHIFT)) & ADC_CTRL_CLKDIV_MASK) +#define ADC_CTRL_ASYNMODE_MASK (0x100U) +#define ADC_CTRL_ASYNMODE_SHIFT (8U) +#define ADC_CTRL_ASYNMODE(x) (((uint32_t)(((uint32_t)(x)) << ADC_CTRL_ASYNMODE_SHIFT)) & ADC_CTRL_ASYNMODE_MASK) +#define ADC_CTRL_RESOL_MASK (0x600U) +#define ADC_CTRL_RESOL_SHIFT (9U) +#define ADC_CTRL_RESOL(x) (((uint32_t)(((uint32_t)(x)) << ADC_CTRL_RESOL_SHIFT)) & ADC_CTRL_RESOL_MASK) +#define ADC_CTRL_BYPASSCAL_MASK (0x800U) +#define ADC_CTRL_BYPASSCAL_SHIFT (11U) +#define ADC_CTRL_BYPASSCAL(x) (((uint32_t)(((uint32_t)(x)) << ADC_CTRL_BYPASSCAL_SHIFT)) & ADC_CTRL_BYPASSCAL_MASK) +#define ADC_CTRL_TSAMP_MASK (0x7000U) +#define ADC_CTRL_TSAMP_SHIFT (12U) +#define ADC_CTRL_TSAMP(x) (((uint32_t)(((uint32_t)(x)) << ADC_CTRL_TSAMP_SHIFT)) & ADC_CTRL_TSAMP_MASK) + +/*! @name SEQ_CTRL - ADC Conversion Sequence-n control register: Controls triggering and channel selection for conversion sequence-n. Also specifies interrupt mode for sequence-n. */ +#define ADC_SEQ_CTRL_CHANNELS_MASK (0xFFFU) +#define ADC_SEQ_CTRL_CHANNELS_SHIFT (0U) +#define ADC_SEQ_CTRL_CHANNELS(x) (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_CHANNELS_SHIFT)) & ADC_SEQ_CTRL_CHANNELS_MASK) +#define ADC_SEQ_CTRL_TRIGGER_MASK (0x3F000U) +#define ADC_SEQ_CTRL_TRIGGER_SHIFT (12U) +#define ADC_SEQ_CTRL_TRIGGER(x) (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_TRIGGER_SHIFT)) & ADC_SEQ_CTRL_TRIGGER_MASK) +#define ADC_SEQ_CTRL_TRIGPOL_MASK (0x40000U) +#define ADC_SEQ_CTRL_TRIGPOL_SHIFT (18U) +#define ADC_SEQ_CTRL_TRIGPOL(x) (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_TRIGPOL_SHIFT)) & ADC_SEQ_CTRL_TRIGPOL_MASK) +#define ADC_SEQ_CTRL_SYNCBYPASS_MASK (0x80000U) +#define ADC_SEQ_CTRL_SYNCBYPASS_SHIFT (19U) +#define ADC_SEQ_CTRL_SYNCBYPASS(x) (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_SYNCBYPASS_SHIFT)) & ADC_SEQ_CTRL_SYNCBYPASS_MASK) +#define ADC_SEQ_CTRL_START_MASK (0x4000000U) +#define ADC_SEQ_CTRL_START_SHIFT (26U) +#define ADC_SEQ_CTRL_START(x) (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_START_SHIFT)) & ADC_SEQ_CTRL_START_MASK) +#define ADC_SEQ_CTRL_BURST_MASK (0x8000000U) +#define ADC_SEQ_CTRL_BURST_SHIFT (27U) +#define ADC_SEQ_CTRL_BURST(x) (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_BURST_SHIFT)) & ADC_SEQ_CTRL_BURST_MASK) +#define ADC_SEQ_CTRL_SINGLESTEP_MASK (0x10000000U) +#define ADC_SEQ_CTRL_SINGLESTEP_SHIFT (28U) +#define ADC_SEQ_CTRL_SINGLESTEP(x) (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_SINGLESTEP_SHIFT)) & ADC_SEQ_CTRL_SINGLESTEP_MASK) +#define ADC_SEQ_CTRL_LOWPRIO_MASK (0x20000000U) +#define ADC_SEQ_CTRL_LOWPRIO_SHIFT (29U) +#define ADC_SEQ_CTRL_LOWPRIO(x) (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_LOWPRIO_SHIFT)) & ADC_SEQ_CTRL_LOWPRIO_MASK) +#define ADC_SEQ_CTRL_MODE_MASK (0x40000000U) +#define ADC_SEQ_CTRL_MODE_SHIFT (30U) +#define ADC_SEQ_CTRL_MODE(x) (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_MODE_SHIFT)) & ADC_SEQ_CTRL_MODE_MASK) +#define ADC_SEQ_CTRL_SEQ_ENA_MASK (0x80000000U) +#define ADC_SEQ_CTRL_SEQ_ENA_SHIFT (31U) +#define ADC_SEQ_CTRL_SEQ_ENA(x) (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_SEQ_ENA_SHIFT)) & ADC_SEQ_CTRL_SEQ_ENA_MASK) + +/* The count of ADC_SEQ_CTRL */ +#define ADC_SEQ_CTRL_COUNT (2U) + +/*! @name SEQ_GDAT - ADC Sequence-n Global Data register. This register contains the result of the most recent ADC conversion performed under sequence-n. */ +#define ADC_SEQ_GDAT_RESULT_MASK (0xFFF0U) +#define ADC_SEQ_GDAT_RESULT_SHIFT (4U) +#define ADC_SEQ_GDAT_RESULT(x) (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_GDAT_RESULT_SHIFT)) & ADC_SEQ_GDAT_RESULT_MASK) +#define ADC_SEQ_GDAT_THCMPRANGE_MASK (0x30000U) +#define ADC_SEQ_GDAT_THCMPRANGE_SHIFT (16U) +#define ADC_SEQ_GDAT_THCMPRANGE(x) (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_GDAT_THCMPRANGE_SHIFT)) & ADC_SEQ_GDAT_THCMPRANGE_MASK) +#define ADC_SEQ_GDAT_THCMPCROSS_MASK (0xC0000U) +#define ADC_SEQ_GDAT_THCMPCROSS_SHIFT (18U) +#define ADC_SEQ_GDAT_THCMPCROSS(x) (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_GDAT_THCMPCROSS_SHIFT)) & ADC_SEQ_GDAT_THCMPCROSS_MASK) +#define ADC_SEQ_GDAT_CHN_MASK (0x3C000000U) +#define ADC_SEQ_GDAT_CHN_SHIFT (26U) +#define ADC_SEQ_GDAT_CHN(x) (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_GDAT_CHN_SHIFT)) & ADC_SEQ_GDAT_CHN_MASK) +#define ADC_SEQ_GDAT_OVERRUN_MASK (0x40000000U) +#define ADC_SEQ_GDAT_OVERRUN_SHIFT (30U) +#define ADC_SEQ_GDAT_OVERRUN(x) (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_GDAT_OVERRUN_SHIFT)) & ADC_SEQ_GDAT_OVERRUN_MASK) +#define ADC_SEQ_GDAT_DATAVALID_MASK (0x80000000U) +#define ADC_SEQ_GDAT_DATAVALID_SHIFT (31U) +#define ADC_SEQ_GDAT_DATAVALID(x) (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_GDAT_DATAVALID_SHIFT)) & ADC_SEQ_GDAT_DATAVALID_MASK) + +/* The count of ADC_SEQ_GDAT */ +#define ADC_SEQ_GDAT_COUNT (2U) + +/*! @name DAT - ADC Channel 0 Data register. This register contains the result of the most recent conversion completed on channel 0. */ +#define ADC_DAT_RESULT_MASK (0xFFF0U) +#define ADC_DAT_RESULT_SHIFT (4U) +#define ADC_DAT_RESULT(x) (((uint32_t)(((uint32_t)(x)) << ADC_DAT_RESULT_SHIFT)) & ADC_DAT_RESULT_MASK) +#define ADC_DAT_THCMPRANGE_MASK (0x30000U) +#define ADC_DAT_THCMPRANGE_SHIFT (16U) +#define ADC_DAT_THCMPRANGE(x) (((uint32_t)(((uint32_t)(x)) << ADC_DAT_THCMPRANGE_SHIFT)) & ADC_DAT_THCMPRANGE_MASK) +#define ADC_DAT_THCMPCROSS_MASK (0xC0000U) +#define ADC_DAT_THCMPCROSS_SHIFT (18U) +#define ADC_DAT_THCMPCROSS(x) (((uint32_t)(((uint32_t)(x)) << ADC_DAT_THCMPCROSS_SHIFT)) & ADC_DAT_THCMPCROSS_MASK) +#define ADC_DAT_CHANNEL_MASK (0x3C000000U) +#define ADC_DAT_CHANNEL_SHIFT (26U) +#define ADC_DAT_CHANNEL(x) (((uint32_t)(((uint32_t)(x)) << ADC_DAT_CHANNEL_SHIFT)) & ADC_DAT_CHANNEL_MASK) +#define ADC_DAT_OVERRUN_MASK (0x40000000U) +#define ADC_DAT_OVERRUN_SHIFT (30U) +#define ADC_DAT_OVERRUN(x) (((uint32_t)(((uint32_t)(x)) << ADC_DAT_OVERRUN_SHIFT)) & ADC_DAT_OVERRUN_MASK) +#define ADC_DAT_DATAVALID_MASK (0x80000000U) +#define ADC_DAT_DATAVALID_SHIFT (31U) +#define ADC_DAT_DATAVALID(x) (((uint32_t)(((uint32_t)(x)) << ADC_DAT_DATAVALID_SHIFT)) & ADC_DAT_DATAVALID_MASK) + +/* The count of ADC_DAT */ +#define ADC_DAT_COUNT (12U) + +/*! @name THR0_LOW - ADC Low Compare Threshold register 0: Contains the lower threshold level for automatic threshold comparison for any channels linked to threshold pair 0. */ +#define ADC_THR0_LOW_THRLOW_MASK (0xFFF0U) +#define ADC_THR0_LOW_THRLOW_SHIFT (4U) +#define ADC_THR0_LOW_THRLOW(x) (((uint32_t)(((uint32_t)(x)) << ADC_THR0_LOW_THRLOW_SHIFT)) & ADC_THR0_LOW_THRLOW_MASK) + +/*! @name THR1_LOW - ADC Low Compare Threshold register 1: Contains the lower threshold level for automatic threshold comparison for any channels linked to threshold pair 1. */ +#define ADC_THR1_LOW_THRLOW_MASK (0xFFF0U) +#define ADC_THR1_LOW_THRLOW_SHIFT (4U) +#define ADC_THR1_LOW_THRLOW(x) (((uint32_t)(((uint32_t)(x)) << ADC_THR1_LOW_THRLOW_SHIFT)) & ADC_THR1_LOW_THRLOW_MASK) + +/*! @name THR0_HIGH - ADC High Compare Threshold register 0: Contains the upper threshold level for automatic threshold comparison for any channels linked to threshold pair 0. */ +#define ADC_THR0_HIGH_THRHIGH_MASK (0xFFF0U) +#define ADC_THR0_HIGH_THRHIGH_SHIFT (4U) +#define ADC_THR0_HIGH_THRHIGH(x) (((uint32_t)(((uint32_t)(x)) << ADC_THR0_HIGH_THRHIGH_SHIFT)) & ADC_THR0_HIGH_THRHIGH_MASK) + +/*! @name THR1_HIGH - ADC High Compare Threshold register 1: Contains the upper threshold level for automatic threshold comparison for any channels linked to threshold pair 1. */ +#define ADC_THR1_HIGH_THRHIGH_MASK (0xFFF0U) +#define ADC_THR1_HIGH_THRHIGH_SHIFT (4U) +#define ADC_THR1_HIGH_THRHIGH(x) (((uint32_t)(((uint32_t)(x)) << ADC_THR1_HIGH_THRHIGH_SHIFT)) & ADC_THR1_HIGH_THRHIGH_MASK) + +/*! @name CHAN_THRSEL - ADC Channel-Threshold Select register. Specifies which set of threshold compare registers are to be used for each channel */ +#define ADC_CHAN_THRSEL_CH0_THRSEL_MASK (0x1U) +#define ADC_CHAN_THRSEL_CH0_THRSEL_SHIFT (0U) +#define ADC_CHAN_THRSEL_CH0_THRSEL(x) (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH0_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH0_THRSEL_MASK) +#define ADC_CHAN_THRSEL_CH1_THRSEL_MASK (0x2U) +#define ADC_CHAN_THRSEL_CH1_THRSEL_SHIFT (1U) +#define ADC_CHAN_THRSEL_CH1_THRSEL(x) (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH1_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH1_THRSEL_MASK) +#define ADC_CHAN_THRSEL_CH2_THRSEL_MASK (0x4U) +#define ADC_CHAN_THRSEL_CH2_THRSEL_SHIFT (2U) +#define ADC_CHAN_THRSEL_CH2_THRSEL(x) (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH2_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH2_THRSEL_MASK) +#define ADC_CHAN_THRSEL_CH3_THRSEL_MASK (0x8U) +#define ADC_CHAN_THRSEL_CH3_THRSEL_SHIFT (3U) +#define ADC_CHAN_THRSEL_CH3_THRSEL(x) (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH3_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH3_THRSEL_MASK) +#define ADC_CHAN_THRSEL_CH4_THRSEL_MASK (0x10U) +#define ADC_CHAN_THRSEL_CH4_THRSEL_SHIFT (4U) +#define ADC_CHAN_THRSEL_CH4_THRSEL(x) (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH4_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH4_THRSEL_MASK) +#define ADC_CHAN_THRSEL_CH5_THRSEL_MASK (0x20U) +#define ADC_CHAN_THRSEL_CH5_THRSEL_SHIFT (5U) +#define ADC_CHAN_THRSEL_CH5_THRSEL(x) (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH5_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH5_THRSEL_MASK) +#define ADC_CHAN_THRSEL_CH6_THRSEL_MASK (0x40U) +#define ADC_CHAN_THRSEL_CH6_THRSEL_SHIFT (6U) +#define ADC_CHAN_THRSEL_CH6_THRSEL(x) (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH6_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH6_THRSEL_MASK) +#define ADC_CHAN_THRSEL_CH7_THRSEL_MASK (0x80U) +#define ADC_CHAN_THRSEL_CH7_THRSEL_SHIFT (7U) +#define ADC_CHAN_THRSEL_CH7_THRSEL(x) (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH7_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH7_THRSEL_MASK) +#define ADC_CHAN_THRSEL_CH8_THRSEL_MASK (0x100U) +#define ADC_CHAN_THRSEL_CH8_THRSEL_SHIFT (8U) +#define ADC_CHAN_THRSEL_CH8_THRSEL(x) (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH8_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH8_THRSEL_MASK) +#define ADC_CHAN_THRSEL_CH9_THRSEL_MASK (0x200U) +#define ADC_CHAN_THRSEL_CH9_THRSEL_SHIFT (9U) +#define ADC_CHAN_THRSEL_CH9_THRSEL(x) (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH9_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH9_THRSEL_MASK) +#define ADC_CHAN_THRSEL_CH10_THRSEL_MASK (0x400U) +#define ADC_CHAN_THRSEL_CH10_THRSEL_SHIFT (10U) +#define ADC_CHAN_THRSEL_CH10_THRSEL(x) (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH10_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH10_THRSEL_MASK) +#define ADC_CHAN_THRSEL_CH11_THRSEL_MASK (0x800U) +#define ADC_CHAN_THRSEL_CH11_THRSEL_SHIFT (11U) +#define ADC_CHAN_THRSEL_CH11_THRSEL(x) (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH11_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH11_THRSEL_MASK) + +/*! @name INTEN - ADC Interrupt Enable register. This register contains enable bits that enable the sequence-A, sequence-B, threshold compare and data overrun interrupts to be generated. */ +#define ADC_INTEN_SEQA_INTEN_MASK (0x1U) +#define ADC_INTEN_SEQA_INTEN_SHIFT (0U) +#define ADC_INTEN_SEQA_INTEN(x) (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_SEQA_INTEN_SHIFT)) & ADC_INTEN_SEQA_INTEN_MASK) +#define ADC_INTEN_SEQB_INTEN_MASK (0x2U) +#define ADC_INTEN_SEQB_INTEN_SHIFT (1U) +#define ADC_INTEN_SEQB_INTEN(x) (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_SEQB_INTEN_SHIFT)) & ADC_INTEN_SEQB_INTEN_MASK) +#define ADC_INTEN_OVR_INTEN_MASK (0x4U) +#define ADC_INTEN_OVR_INTEN_SHIFT (2U) +#define ADC_INTEN_OVR_INTEN(x) (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_OVR_INTEN_SHIFT)) & ADC_INTEN_OVR_INTEN_MASK) +#define ADC_INTEN_ADCMPINTEN0_MASK (0x18U) +#define ADC_INTEN_ADCMPINTEN0_SHIFT (3U) +#define ADC_INTEN_ADCMPINTEN0(x) (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN0_SHIFT)) & ADC_INTEN_ADCMPINTEN0_MASK) +#define ADC_INTEN_ADCMPINTEN1_MASK (0x60U) +#define ADC_INTEN_ADCMPINTEN1_SHIFT (5U) +#define ADC_INTEN_ADCMPINTEN1(x) (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN1_SHIFT)) & ADC_INTEN_ADCMPINTEN1_MASK) +#define ADC_INTEN_ADCMPINTEN2_MASK (0x180U) +#define ADC_INTEN_ADCMPINTEN2_SHIFT (7U) +#define ADC_INTEN_ADCMPINTEN2(x) (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN2_SHIFT)) & ADC_INTEN_ADCMPINTEN2_MASK) +#define ADC_INTEN_ADCMPINTEN3_MASK (0x600U) +#define ADC_INTEN_ADCMPINTEN3_SHIFT (9U) +#define ADC_INTEN_ADCMPINTEN3(x) (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN3_SHIFT)) & ADC_INTEN_ADCMPINTEN3_MASK) +#define ADC_INTEN_ADCMPINTEN4_MASK (0x1800U) +#define ADC_INTEN_ADCMPINTEN4_SHIFT (11U) +#define ADC_INTEN_ADCMPINTEN4(x) (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN4_SHIFT)) & ADC_INTEN_ADCMPINTEN4_MASK) +#define ADC_INTEN_ADCMPINTEN5_MASK (0x6000U) +#define ADC_INTEN_ADCMPINTEN5_SHIFT (13U) +#define ADC_INTEN_ADCMPINTEN5(x) (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN5_SHIFT)) & ADC_INTEN_ADCMPINTEN5_MASK) +#define ADC_INTEN_ADCMPINTEN6_MASK (0x18000U) +#define ADC_INTEN_ADCMPINTEN6_SHIFT (15U) +#define ADC_INTEN_ADCMPINTEN6(x) (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN6_SHIFT)) & ADC_INTEN_ADCMPINTEN6_MASK) +#define ADC_INTEN_ADCMPINTEN7_MASK (0x60000U) +#define ADC_INTEN_ADCMPINTEN7_SHIFT (17U) +#define ADC_INTEN_ADCMPINTEN7(x) (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN7_SHIFT)) & ADC_INTEN_ADCMPINTEN7_MASK) +#define ADC_INTEN_ADCMPINTEN8_MASK (0x180000U) +#define ADC_INTEN_ADCMPINTEN8_SHIFT (19U) +#define ADC_INTEN_ADCMPINTEN8(x) (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN8_SHIFT)) & ADC_INTEN_ADCMPINTEN8_MASK) +#define ADC_INTEN_ADCMPINTEN9_MASK (0x600000U) +#define ADC_INTEN_ADCMPINTEN9_SHIFT (21U) +#define ADC_INTEN_ADCMPINTEN9(x) (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN9_SHIFT)) & ADC_INTEN_ADCMPINTEN9_MASK) +#define ADC_INTEN_ADCMPINTEN10_MASK (0x1800000U) +#define ADC_INTEN_ADCMPINTEN10_SHIFT (23U) +#define ADC_INTEN_ADCMPINTEN10(x) (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN10_SHIFT)) & ADC_INTEN_ADCMPINTEN10_MASK) +#define ADC_INTEN_ADCMPINTEN11_MASK (0x6000000U) +#define ADC_INTEN_ADCMPINTEN11_SHIFT (25U) +#define ADC_INTEN_ADCMPINTEN11(x) (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN11_SHIFT)) & ADC_INTEN_ADCMPINTEN11_MASK) + +/*! @name FLAGS - ADC Flags register. Contains the four interrupt/DMA trigger flags and the individual component overrun and threshold-compare flags. (The overrun bits replicate information stored in the result registers). */ +#define ADC_FLAGS_THCMP0_MASK (0x1U) +#define ADC_FLAGS_THCMP0_SHIFT (0U) +#define ADC_FLAGS_THCMP0(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP0_SHIFT)) & ADC_FLAGS_THCMP0_MASK) +#define ADC_FLAGS_THCMP1_MASK (0x2U) +#define ADC_FLAGS_THCMP1_SHIFT (1U) +#define ADC_FLAGS_THCMP1(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP1_SHIFT)) & ADC_FLAGS_THCMP1_MASK) +#define ADC_FLAGS_THCMP2_MASK (0x4U) +#define ADC_FLAGS_THCMP2_SHIFT (2U) +#define ADC_FLAGS_THCMP2(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP2_SHIFT)) & ADC_FLAGS_THCMP2_MASK) +#define ADC_FLAGS_THCMP3_MASK (0x8U) +#define ADC_FLAGS_THCMP3_SHIFT (3U) +#define ADC_FLAGS_THCMP3(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP3_SHIFT)) & ADC_FLAGS_THCMP3_MASK) +#define ADC_FLAGS_THCMP4_MASK (0x10U) +#define ADC_FLAGS_THCMP4_SHIFT (4U) +#define ADC_FLAGS_THCMP4(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP4_SHIFT)) & ADC_FLAGS_THCMP4_MASK) +#define ADC_FLAGS_THCMP5_MASK (0x20U) +#define ADC_FLAGS_THCMP5_SHIFT (5U) +#define ADC_FLAGS_THCMP5(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP5_SHIFT)) & ADC_FLAGS_THCMP5_MASK) +#define ADC_FLAGS_THCMP6_MASK (0x40U) +#define ADC_FLAGS_THCMP6_SHIFT (6U) +#define ADC_FLAGS_THCMP6(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP6_SHIFT)) & ADC_FLAGS_THCMP6_MASK) +#define ADC_FLAGS_THCMP7_MASK (0x80U) +#define ADC_FLAGS_THCMP7_SHIFT (7U) +#define ADC_FLAGS_THCMP7(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP7_SHIFT)) & ADC_FLAGS_THCMP7_MASK) +#define ADC_FLAGS_THCMP8_MASK (0x100U) +#define ADC_FLAGS_THCMP8_SHIFT (8U) +#define ADC_FLAGS_THCMP8(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP8_SHIFT)) & ADC_FLAGS_THCMP8_MASK) +#define ADC_FLAGS_THCMP9_MASK (0x200U) +#define ADC_FLAGS_THCMP9_SHIFT (9U) +#define ADC_FLAGS_THCMP9(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP9_SHIFT)) & ADC_FLAGS_THCMP9_MASK) +#define ADC_FLAGS_THCMP10_MASK (0x400U) +#define ADC_FLAGS_THCMP10_SHIFT (10U) +#define ADC_FLAGS_THCMP10(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP10_SHIFT)) & ADC_FLAGS_THCMP10_MASK) +#define ADC_FLAGS_THCMP11_MASK (0x800U) +#define ADC_FLAGS_THCMP11_SHIFT (11U) +#define ADC_FLAGS_THCMP11(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP11_SHIFT)) & ADC_FLAGS_THCMP11_MASK) +#define ADC_FLAGS_OVERRUN0_MASK (0x1000U) +#define ADC_FLAGS_OVERRUN0_SHIFT (12U) +#define ADC_FLAGS_OVERRUN0(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN0_SHIFT)) & ADC_FLAGS_OVERRUN0_MASK) +#define ADC_FLAGS_OVERRUN1_MASK (0x2000U) +#define ADC_FLAGS_OVERRUN1_SHIFT (13U) +#define ADC_FLAGS_OVERRUN1(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN1_SHIFT)) & ADC_FLAGS_OVERRUN1_MASK) +#define ADC_FLAGS_OVERRUN2_MASK (0x4000U) +#define ADC_FLAGS_OVERRUN2_SHIFT (14U) +#define ADC_FLAGS_OVERRUN2(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN2_SHIFT)) & ADC_FLAGS_OVERRUN2_MASK) +#define ADC_FLAGS_OVERRUN3_MASK (0x8000U) +#define ADC_FLAGS_OVERRUN3_SHIFT (15U) +#define ADC_FLAGS_OVERRUN3(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN3_SHIFT)) & ADC_FLAGS_OVERRUN3_MASK) +#define ADC_FLAGS_OVERRUN4_MASK (0x10000U) +#define ADC_FLAGS_OVERRUN4_SHIFT (16U) +#define ADC_FLAGS_OVERRUN4(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN4_SHIFT)) & ADC_FLAGS_OVERRUN4_MASK) +#define ADC_FLAGS_OVERRUN5_MASK (0x20000U) +#define ADC_FLAGS_OVERRUN5_SHIFT (17U) +#define ADC_FLAGS_OVERRUN5(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN5_SHIFT)) & ADC_FLAGS_OVERRUN5_MASK) +#define ADC_FLAGS_OVERRUN6_MASK (0x40000U) +#define ADC_FLAGS_OVERRUN6_SHIFT (18U) +#define ADC_FLAGS_OVERRUN6(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN6_SHIFT)) & ADC_FLAGS_OVERRUN6_MASK) +#define ADC_FLAGS_OVERRUN7_MASK (0x80000U) +#define ADC_FLAGS_OVERRUN7_SHIFT (19U) +#define ADC_FLAGS_OVERRUN7(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN7_SHIFT)) & ADC_FLAGS_OVERRUN7_MASK) +#define ADC_FLAGS_OVERRUN8_MASK (0x100000U) +#define ADC_FLAGS_OVERRUN8_SHIFT (20U) +#define ADC_FLAGS_OVERRUN8(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN8_SHIFT)) & ADC_FLAGS_OVERRUN8_MASK) +#define ADC_FLAGS_OVERRUN9_MASK (0x200000U) +#define ADC_FLAGS_OVERRUN9_SHIFT (21U) +#define ADC_FLAGS_OVERRUN9(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN9_SHIFT)) & ADC_FLAGS_OVERRUN9_MASK) +#define ADC_FLAGS_OVERRUN10_MASK (0x400000U) +#define ADC_FLAGS_OVERRUN10_SHIFT (22U) +#define ADC_FLAGS_OVERRUN10(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN10_SHIFT)) & ADC_FLAGS_OVERRUN10_MASK) +#define ADC_FLAGS_OVERRUN11_MASK (0x800000U) +#define ADC_FLAGS_OVERRUN11_SHIFT (23U) +#define ADC_FLAGS_OVERRUN11(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN11_SHIFT)) & ADC_FLAGS_OVERRUN11_MASK) +#define ADC_FLAGS_SEQA_OVR_MASK (0x1000000U) +#define ADC_FLAGS_SEQA_OVR_SHIFT (24U) +#define ADC_FLAGS_SEQA_OVR(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_SEQA_OVR_SHIFT)) & ADC_FLAGS_SEQA_OVR_MASK) +#define ADC_FLAGS_SEQB_OVR_MASK (0x2000000U) +#define ADC_FLAGS_SEQB_OVR_SHIFT (25U) +#define ADC_FLAGS_SEQB_OVR(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_SEQB_OVR_SHIFT)) & ADC_FLAGS_SEQB_OVR_MASK) +#define ADC_FLAGS_SEQA_INT_MASK (0x10000000U) +#define ADC_FLAGS_SEQA_INT_SHIFT (28U) +#define ADC_FLAGS_SEQA_INT(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_SEQA_INT_SHIFT)) & ADC_FLAGS_SEQA_INT_MASK) +#define ADC_FLAGS_SEQB_INT_MASK (0x20000000U) +#define ADC_FLAGS_SEQB_INT_SHIFT (29U) +#define ADC_FLAGS_SEQB_INT(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_SEQB_INT_SHIFT)) & ADC_FLAGS_SEQB_INT_MASK) +#define ADC_FLAGS_THCMP_INT_MASK (0x40000000U) +#define ADC_FLAGS_THCMP_INT_SHIFT (30U) +#define ADC_FLAGS_THCMP_INT(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP_INT_SHIFT)) & ADC_FLAGS_THCMP_INT_MASK) +#define ADC_FLAGS_OVR_INT_MASK (0x80000000U) +#define ADC_FLAGS_OVR_INT_SHIFT (31U) +#define ADC_FLAGS_OVR_INT(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVR_INT_SHIFT)) & ADC_FLAGS_OVR_INT_MASK) + +/*! @name STARTUP - ADC Startup register. */ +#define ADC_STARTUP_ADC_ENA_MASK (0x1U) +#define ADC_STARTUP_ADC_ENA_SHIFT (0U) +#define ADC_STARTUP_ADC_ENA(x) (((uint32_t)(((uint32_t)(x)) << ADC_STARTUP_ADC_ENA_SHIFT)) & ADC_STARTUP_ADC_ENA_MASK) +#define ADC_STARTUP_ADC_INIT_MASK (0x2U) +#define ADC_STARTUP_ADC_INIT_SHIFT (1U) +#define ADC_STARTUP_ADC_INIT(x) (((uint32_t)(((uint32_t)(x)) << ADC_STARTUP_ADC_INIT_SHIFT)) & ADC_STARTUP_ADC_INIT_MASK) + +/*! @name CALIB - ADC Calibration register. */ +#define ADC_CALIB_CALIB_MASK (0x1U) +#define ADC_CALIB_CALIB_SHIFT (0U) +#define ADC_CALIB_CALIB(x) (((uint32_t)(((uint32_t)(x)) << ADC_CALIB_CALIB_SHIFT)) & ADC_CALIB_CALIB_MASK) +#define ADC_CALIB_CALREQD_MASK (0x2U) +#define ADC_CALIB_CALREQD_SHIFT (1U) +#define ADC_CALIB_CALREQD(x) (((uint32_t)(((uint32_t)(x)) << ADC_CALIB_CALREQD_SHIFT)) & ADC_CALIB_CALREQD_MASK) +#define ADC_CALIB_CALVALUE_MASK (0x1FCU) +#define ADC_CALIB_CALVALUE_SHIFT (2U) +#define ADC_CALIB_CALVALUE(x) (((uint32_t)(((uint32_t)(x)) << ADC_CALIB_CALVALUE_SHIFT)) & ADC_CALIB_CALVALUE_MASK) + + +/*! + * @} + */ /* end of group ADC_Register_Masks */ + + +/* ADC - Peripheral instance base addresses */ +/** Peripheral ADC0 base address */ +#define ADC0_BASE (0x1C034000u) +/** Peripheral ADC0 base pointer */ +#define ADC0 ((ADC_Type *)ADC0_BASE) +/** Array initializer of ADC peripheral base addresses */ +#define ADC_BASE_ADDRS { ADC0_BASE } +/** Array initializer of ADC peripheral base pointers */ +#define ADC_BASE_PTRS { ADC0 } +/** Interrupt vectors for the ADC peripheral type */ +#define ADC_SEQ_IRQS { ADC0_SEQA_IRQn, ADC0_SEQB_IRQn } +#define ADC_THCMP_IRQS { ADC0_THCMP_IRQn } + +/*! + * @} + */ /* end of group ADC_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- ASYNC_SYSCON Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup ASYNC_SYSCON_Peripheral_Access_Layer ASYNC_SYSCON Peripheral Access Layer + * @{ + */ + +/** ASYNC_SYSCON - Register Layout Typedef */ +typedef struct { + __IO uint32_t ASYNCPRESETCTRL; /**< Async peripheral reset control, offset: 0x0 */ + __O uint32_t ASYNCPRESETCTRLSET; /**< Set bits in ASYNCPRESETCTRL, offset: 0x4 */ + __O uint32_t ASYNCPRESETCTRLCLR; /**< Clear bits in ASYNCPRESETCTRL, offset: 0x8 */ + uint8_t RESERVED_0[4]; + __IO uint32_t ASYNCAPBCLKCTRL; /**< Async peripheral clock control, offset: 0x10 */ + __O uint32_t ASYNCAPBCLKCTRLSET; /**< Set bits in ASYNCAPBCLKCTRL, offset: 0x14 */ + __O uint32_t ASYNCAPBCLKCTRLCLR; /**< Clear bits in ASYNCAPBCLKCTRL, offset: 0x18 */ + uint8_t RESERVED_1[4]; + __IO uint32_t ASYNCAPBCLKSELA; /**< Async APB clock source select A, offset: 0x20 */ + __IO uint32_t ASYNCAPBCLKSELB; /**< Async APB clock source select B, offset: 0x24 */ + __IO uint32_t ASYNCCLKDIV; /**< Async APB clock divider, offset: 0x28 */ + uint8_t RESERVED_2[4]; + __IO uint32_t FRGCTRL; /**< USART fractional rate generator control, offset: 0x30 */ +} ASYNC_SYSCON_Type; + +/* ---------------------------------------------------------------------------- + -- ASYNC_SYSCON Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup ASYNC_SYSCON_Register_Masks ASYNC_SYSCON Register Masks + * @{ + */ + +/*! @name ASYNCPRESETCTRL - Async peripheral reset control */ +#define ASYNC_SYSCON_ASYNCPRESETCTRL_USART0_MASK (0x2U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_USART0_SHIFT (1U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_USART0(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCPRESETCTRL_USART0_SHIFT)) & ASYNC_SYSCON_ASYNCPRESETCTRL_USART0_MASK) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_USART1_MASK (0x4U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_USART1_SHIFT (2U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_USART1(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCPRESETCTRL_USART1_SHIFT)) & ASYNC_SYSCON_ASYNCPRESETCTRL_USART1_MASK) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_USART2_MASK (0x8U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_USART2_SHIFT (3U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_USART2(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCPRESETCTRL_USART2_SHIFT)) & ASYNC_SYSCON_ASYNCPRESETCTRL_USART2_MASK) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_USART3_MASK (0x10U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_USART3_SHIFT (4U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_USART3(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCPRESETCTRL_USART3_SHIFT)) & ASYNC_SYSCON_ASYNCPRESETCTRL_USART3_MASK) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_I2C0_MASK (0x20U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_I2C0_SHIFT (5U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_I2C0(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCPRESETCTRL_I2C0_SHIFT)) & ASYNC_SYSCON_ASYNCPRESETCTRL_I2C0_MASK) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_I2C1_MASK (0x40U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_I2C1_SHIFT (6U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_I2C1(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCPRESETCTRL_I2C1_SHIFT)) & ASYNC_SYSCON_ASYNCPRESETCTRL_I2C1_MASK) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_I2C2_MASK (0x80U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_I2C2_SHIFT (7U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_I2C2(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCPRESETCTRL_I2C2_SHIFT)) & ASYNC_SYSCON_ASYNCPRESETCTRL_I2C2_MASK) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_SPI0_MASK (0x200U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_SPI0_SHIFT (9U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_SPI0(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCPRESETCTRL_SPI0_SHIFT)) & ASYNC_SYSCON_ASYNCPRESETCTRL_SPI0_MASK) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_SPI1_MASK (0x400U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_SPI1_SHIFT (10U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_SPI1(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCPRESETCTRL_SPI1_SHIFT)) & ASYNC_SYSCON_ASYNCPRESETCTRL_SPI1_MASK) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_CT32B0_MASK (0x2000U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_CT32B0_SHIFT (13U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_CT32B0(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCPRESETCTRL_CT32B0_SHIFT)) & ASYNC_SYSCON_ASYNCPRESETCTRL_CT32B0_MASK) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_CT32B1_MASK (0x4000U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_CT32B1_SHIFT (14U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_CT32B1(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCPRESETCTRL_CT32B1_SHIFT)) & ASYNC_SYSCON_ASYNCPRESETCTRL_CT32B1_MASK) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_FRG0_MASK (0x8000U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_FRG0_SHIFT (15U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_FRG0(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCPRESETCTRL_FRG0_SHIFT)) & ASYNC_SYSCON_ASYNCPRESETCTRL_FRG0_MASK) + +/*! @name ASYNCPRESETCTRLSET - Set bits in ASYNCPRESETCTRL */ +#define ASYNC_SYSCON_ASYNCPRESETCTRLSET_ARST_SET_MASK (0xFFFFFFFFU) +#define ASYNC_SYSCON_ASYNCPRESETCTRLSET_ARST_SET_SHIFT (0U) +#define ASYNC_SYSCON_ASYNCPRESETCTRLSET_ARST_SET(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCPRESETCTRLSET_ARST_SET_SHIFT)) & ASYNC_SYSCON_ASYNCPRESETCTRLSET_ARST_SET_MASK) + +/*! @name ASYNCPRESETCTRLCLR - Clear bits in ASYNCPRESETCTRL */ +#define ASYNC_SYSCON_ASYNCPRESETCTRLCLR_ARST_CLR_MASK (0xFFFFFFFFU) +#define ASYNC_SYSCON_ASYNCPRESETCTRLCLR_ARST_CLR_SHIFT (0U) +#define ASYNC_SYSCON_ASYNCPRESETCTRLCLR_ARST_CLR(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCPRESETCTRLCLR_ARST_CLR_SHIFT)) & ASYNC_SYSCON_ASYNCPRESETCTRLCLR_ARST_CLR_MASK) + +/*! @name ASYNCAPBCLKCTRL - Async peripheral clock control */ +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_USART0_MASK (0x2U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_USART0_SHIFT (1U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_USART0(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKCTRL_USART0_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKCTRL_USART0_MASK) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_USART1_MASK (0x4U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_USART1_SHIFT (2U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_USART1(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKCTRL_USART1_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKCTRL_USART1_MASK) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_USART2_MASK (0x8U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_USART2_SHIFT (3U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_USART2(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKCTRL_USART2_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKCTRL_USART2_MASK) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_USART3_MASK (0x10U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_USART3_SHIFT (4U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_USART3(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKCTRL_USART3_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKCTRL_USART3_MASK) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_I2C0_MASK (0x20U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_I2C0_SHIFT (5U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_I2C0(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKCTRL_I2C0_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKCTRL_I2C0_MASK) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_I2C1_MASK (0x40U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_I2C1_SHIFT (6U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_I2C1(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKCTRL_I2C1_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKCTRL_I2C1_MASK) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_I2C2_MASK (0x80U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_I2C2_SHIFT (7U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_I2C2(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKCTRL_I2C2_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKCTRL_I2C2_MASK) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_SPI0_MASK (0x200U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_SPI0_SHIFT (9U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_SPI0(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKCTRL_SPI0_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKCTRL_SPI0_MASK) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_SPI1_MASK (0x400U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_SPI1_SHIFT (10U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_SPI1(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKCTRL_SPI1_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKCTRL_SPI1_MASK) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_CT32B0_MASK (0x2000U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_CT32B0_SHIFT (13U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_CT32B0(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKCTRL_CT32B0_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKCTRL_CT32B0_MASK) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_CT32B1_MASK (0x4000U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_CT32B1_SHIFT (14U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_CT32B1(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKCTRL_CT32B1_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKCTRL_CT32B1_MASK) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_FRG0_MASK (0x8000U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_FRG0_SHIFT (15U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_FRG0(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKCTRL_FRG0_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKCTRL_FRG0_MASK) + +/*! @name ASYNCAPBCLKCTRLSET - Set bits in ASYNCAPBCLKCTRL */ +#define ASYNC_SYSCON_ASYNCAPBCLKCTRLSET_ACLK_SET_MASK (0xFFFFFFFFU) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRLSET_ACLK_SET_SHIFT (0U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRLSET_ACLK_SET(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKCTRLSET_ACLK_SET_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKCTRLSET_ACLK_SET_MASK) + +/*! @name ASYNCAPBCLKCTRLCLR - Clear bits in ASYNCAPBCLKCTRL */ +#define ASYNC_SYSCON_ASYNCAPBCLKCTRLCLR_ACLK_CLR_MASK (0xFFFFFFFFU) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRLCLR_ACLK_CLR_SHIFT (0U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRLCLR_ACLK_CLR(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKCTRLCLR_ACLK_CLR_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKCTRLCLR_ACLK_CLR_MASK) + +/*! @name ASYNCAPBCLKSELA - Async APB clock source select A */ +#define ASYNC_SYSCON_ASYNCAPBCLKSELA_SEL_MASK (0x3U) +#define ASYNC_SYSCON_ASYNCAPBCLKSELA_SEL_SHIFT (0U) +#define ASYNC_SYSCON_ASYNCAPBCLKSELA_SEL(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKSELA_SEL_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKSELA_SEL_MASK) + +/*! @name ASYNCAPBCLKSELB - Async APB clock source select B */ +#define ASYNC_SYSCON_ASYNCAPBCLKSELB_SEL_MASK (0x3U) +#define ASYNC_SYSCON_ASYNCAPBCLKSELB_SEL_SHIFT (0U) +#define ASYNC_SYSCON_ASYNCAPBCLKSELB_SEL(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKSELB_SEL_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKSELB_SEL_MASK) + +/*! @name ASYNCCLKDIV - Async APB clock divider */ +#define ASYNC_SYSCON_ASYNCCLKDIV_DIV_MASK (0xFFU) +#define ASYNC_SYSCON_ASYNCCLKDIV_DIV_SHIFT (0U) +#define ASYNC_SYSCON_ASYNCCLKDIV_DIV(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCCLKDIV_DIV_SHIFT)) & ASYNC_SYSCON_ASYNCCLKDIV_DIV_MASK) + +/*! @name FRGCTRL - USART fractional rate generator control */ +#define ASYNC_SYSCON_FRGCTRL_DIV_MASK (0xFFU) +#define ASYNC_SYSCON_FRGCTRL_DIV_SHIFT (0U) +#define ASYNC_SYSCON_FRGCTRL_DIV(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_FRGCTRL_DIV_SHIFT)) & ASYNC_SYSCON_FRGCTRL_DIV_MASK) +#define ASYNC_SYSCON_FRGCTRL_MULT_MASK (0xFF00U) +#define ASYNC_SYSCON_FRGCTRL_MULT_SHIFT (8U) +#define ASYNC_SYSCON_FRGCTRL_MULT(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_FRGCTRL_MULT_SHIFT)) & ASYNC_SYSCON_FRGCTRL_MULT_MASK) + + +/*! + * @} + */ /* end of group ASYNC_SYSCON_Register_Masks */ + + +/* ASYNC_SYSCON - Peripheral instance base addresses */ +/** Peripheral ASYNC_SYSCON base address */ +#define ASYNC_SYSCON_BASE (0x40080000u) +/** Peripheral ASYNC_SYSCON base pointer */ +#define ASYNC_SYSCON ((ASYNC_SYSCON_Type *)ASYNC_SYSCON_BASE) +/** Array initializer of ASYNC_SYSCON peripheral base addresses */ +#define ASYNC_SYSCON_BASE_ADDRS { ASYNC_SYSCON_BASE } +/** Array initializer of ASYNC_SYSCON peripheral base pointers */ +#define ASYNC_SYSCON_BASE_PTRS { ASYNC_SYSCON } + +/*! + * @} + */ /* end of group ASYNC_SYSCON_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- CRC Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup CRC_Peripheral_Access_Layer CRC Peripheral Access Layer + * @{ + */ + +/** CRC - Register Layout Typedef */ +typedef struct { + __IO uint32_t MODE; /**< CRC mode register, offset: 0x0 */ + __IO uint32_t SEED; /**< CRC seed register, offset: 0x4 */ + union { /* offset: 0x8 */ + __I uint32_t SUM; /**< CRC checksum register, offset: 0x8 */ + __O uint32_t WR_DATA; /**< CRC data register, offset: 0x8 */ + }; +} CRC_Type; + +/* ---------------------------------------------------------------------------- + -- CRC Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup CRC_Register_Masks CRC Register Masks + * @{ + */ + +/*! @name MODE - CRC mode register */ +#define CRC_MODE_CRC_POLY_MASK (0x3U) +#define CRC_MODE_CRC_POLY_SHIFT (0U) +#define CRC_MODE_CRC_POLY(x) (((uint32_t)(((uint32_t)(x)) << CRC_MODE_CRC_POLY_SHIFT)) & CRC_MODE_CRC_POLY_MASK) +#define CRC_MODE_BIT_RVS_WR_MASK (0x4U) +#define CRC_MODE_BIT_RVS_WR_SHIFT (2U) +#define CRC_MODE_BIT_RVS_WR(x) (((uint32_t)(((uint32_t)(x)) << CRC_MODE_BIT_RVS_WR_SHIFT)) & CRC_MODE_BIT_RVS_WR_MASK) +#define CRC_MODE_CMPL_WR_MASK (0x8U) +#define CRC_MODE_CMPL_WR_SHIFT (3U) +#define CRC_MODE_CMPL_WR(x) (((uint32_t)(((uint32_t)(x)) << CRC_MODE_CMPL_WR_SHIFT)) & CRC_MODE_CMPL_WR_MASK) +#define CRC_MODE_BIT_RVS_SUM_MASK (0x10U) +#define CRC_MODE_BIT_RVS_SUM_SHIFT (4U) +#define CRC_MODE_BIT_RVS_SUM(x) (((uint32_t)(((uint32_t)(x)) << CRC_MODE_BIT_RVS_SUM_SHIFT)) & CRC_MODE_BIT_RVS_SUM_MASK) +#define CRC_MODE_CMPL_SUM_MASK (0x20U) +#define CRC_MODE_CMPL_SUM_SHIFT (5U) +#define CRC_MODE_CMPL_SUM(x) (((uint32_t)(((uint32_t)(x)) << CRC_MODE_CMPL_SUM_SHIFT)) & CRC_MODE_CMPL_SUM_MASK) + +/*! @name SEED - CRC seed register */ +#define CRC_SEED_CRC_SEED_MASK (0xFFFFFFFFU) +#define CRC_SEED_CRC_SEED_SHIFT (0U) +#define CRC_SEED_CRC_SEED(x) (((uint32_t)(((uint32_t)(x)) << CRC_SEED_CRC_SEED_SHIFT)) & CRC_SEED_CRC_SEED_MASK) + +/*! @name SUM - CRC checksum register */ +#define CRC_SUM_CRC_SUM_MASK (0xFFFFFFFFU) +#define CRC_SUM_CRC_SUM_SHIFT (0U) +#define CRC_SUM_CRC_SUM(x) (((uint32_t)(((uint32_t)(x)) << CRC_SUM_CRC_SUM_SHIFT)) & CRC_SUM_CRC_SUM_MASK) + +/*! @name WR_DATA - CRC data register */ +#define CRC_WR_DATA_CRC_WR_DATA_MASK (0xFFFFFFFFU) +#define CRC_WR_DATA_CRC_WR_DATA_SHIFT (0U) +#define CRC_WR_DATA_CRC_WR_DATA(x) (((uint32_t)(((uint32_t)(x)) << CRC_WR_DATA_CRC_WR_DATA_SHIFT)) & CRC_WR_DATA_CRC_WR_DATA_MASK) + + +/*! + * @} + */ /* end of group CRC_Register_Masks */ + + +/* CRC - Peripheral instance base addresses */ +/** Peripheral CRC_ENGINE base address */ +#define CRC_ENGINE_BASE (0x1C010000u) +/** Peripheral CRC_ENGINE base pointer */ +#define CRC_ENGINE ((CRC_Type *)CRC_ENGINE_BASE) +/** Array initializer of CRC peripheral base addresses */ +#define CRC_BASE_ADDRS { CRC_ENGINE_BASE } +/** Array initializer of CRC peripheral base pointers */ +#define CRC_BASE_PTRS { CRC_ENGINE } + +/*! + * @} + */ /* end of group CRC_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- CTIMER Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup CTIMER_Peripheral_Access_Layer CTIMER Peripheral Access Layer + * @{ + */ + +/** CTIMER - Register Layout Typedef */ +typedef struct { + __IO uint32_t IR; /**< Interrupt Register. The IR can be written to clear interrupts. The IR can be read to identify which of eight possible interrupt sources are pending., offset: 0x0 */ + __IO uint32_t TCR; /**< Timer Control Register. The TCR is used to control the Timer Counter functions. The Timer Counter can be disabled or reset through the TCR., offset: 0x4 */ + __IO uint32_t TC; /**< Timer Counter. The 32 bit TC is incremented every PR+1 cycles of the APB bus clock. The TC is controlled through the TCR., offset: 0x8 */ + __IO uint32_t PR; /**< Prescale Register. When the Prescale Counter (PC) is equal to this value, the next clock increments the TC and clears the PC., offset: 0xC */ + __IO uint32_t PC; /**< Prescale Counter. The 32 bit PC is a counter which is incremented to the value stored in PR. When the value in PR is reached, the TC is incremented and the PC is cleared. The PC is observable and controllable through the bus interface., offset: 0x10 */ + __IO uint32_t MCR; /**< Match Control Register. The MCR is used to control if an interrupt is generated and if the TC is reset when a Match occurs., offset: 0x14 */ + __IO uint32_t MR[4]; /**< Match Register . MR can be enabled through the MCR to reset the TC, stop both the TC and PC, and/or generate an interrupt every time MR matches the TC., array offset: 0x18, array step: 0x4 */ + __IO uint32_t CCR; /**< Capture Control Register. The CCR controls which edges of the capture inputs are used to load the Capture Registers and whether or not an interrupt is generated when a capture takes place., offset: 0x28 */ + __I uint32_t CR[4]; /**< Capture Register . CR is loaded with the value of TC when there is an event on the CAPn. input., array offset: 0x2C, array step: 0x4 */ + __IO uint32_t EMR; /**< External Match Register. The EMR controls the match function and the external match pins., offset: 0x3C */ + uint8_t RESERVED_0[48]; + __IO uint32_t CTCR; /**< Count Control Register. The CTCR selects between Timer and Counter mode, and in Counter mode selects the signal and edge(s) for counting., offset: 0x70 */ + __IO uint32_t PWMC; /**< PWM Control Register. The PWMCON enables PWM mode for the external match pins., offset: 0x74 */ +} CTIMER_Type; + +/* ---------------------------------------------------------------------------- + -- CTIMER Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup CTIMER_Register_Masks CTIMER Register Masks + * @{ + */ + +/*! @name IR - Interrupt Register. The IR can be written to clear interrupts. The IR can be read to identify which of eight possible interrupt sources are pending. */ +#define CTIMER_IR_MR0INT_MASK (0x1U) +#define CTIMER_IR_MR0INT_SHIFT (0U) +#define CTIMER_IR_MR0INT(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_IR_MR0INT_SHIFT)) & CTIMER_IR_MR0INT_MASK) +#define CTIMER_IR_MR1INT_MASK (0x2U) +#define CTIMER_IR_MR1INT_SHIFT (1U) +#define CTIMER_IR_MR1INT(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_IR_MR1INT_SHIFT)) & CTIMER_IR_MR1INT_MASK) +#define CTIMER_IR_MR2INT_MASK (0x4U) +#define CTIMER_IR_MR2INT_SHIFT (2U) +#define CTIMER_IR_MR2INT(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_IR_MR2INT_SHIFT)) & CTIMER_IR_MR2INT_MASK) +#define CTIMER_IR_MR3INT_MASK (0x8U) +#define CTIMER_IR_MR3INT_SHIFT (3U) +#define CTIMER_IR_MR3INT(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_IR_MR3INT_SHIFT)) & CTIMER_IR_MR3INT_MASK) +#define CTIMER_IR_CR0INT_MASK (0x10U) +#define CTIMER_IR_CR0INT_SHIFT (4U) +#define CTIMER_IR_CR0INT(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_IR_CR0INT_SHIFT)) & CTIMER_IR_CR0INT_MASK) +#define CTIMER_IR_CR1INT_MASK (0x20U) +#define CTIMER_IR_CR1INT_SHIFT (5U) +#define CTIMER_IR_CR1INT(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_IR_CR1INT_SHIFT)) & CTIMER_IR_CR1INT_MASK) +#define CTIMER_IR_CR2INT_MASK (0x40U) +#define CTIMER_IR_CR2INT_SHIFT (6U) +#define CTIMER_IR_CR2INT(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_IR_CR2INT_SHIFT)) & CTIMER_IR_CR2INT_MASK) +#define CTIMER_IR_CR3INT_MASK (0x80U) +#define CTIMER_IR_CR3INT_SHIFT (7U) +#define CTIMER_IR_CR3INT(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_IR_CR3INT_SHIFT)) & CTIMER_IR_CR3INT_MASK) + +/*! @name TCR - Timer Control Register. The TCR is used to control the Timer Counter functions. The Timer Counter can be disabled or reset through the TCR. */ +#define CTIMER_TCR_CEN_MASK (0x1U) +#define CTIMER_TCR_CEN_SHIFT (0U) +#define CTIMER_TCR_CEN(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_TCR_CEN_SHIFT)) & CTIMER_TCR_CEN_MASK) +#define CTIMER_TCR_CRST_MASK (0x2U) +#define CTIMER_TCR_CRST_SHIFT (1U) +#define CTIMER_TCR_CRST(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_TCR_CRST_SHIFT)) & CTIMER_TCR_CRST_MASK) + +/*! @name TC - Timer Counter. The 32 bit TC is incremented every PR+1 cycles of the APB bus clock. The TC is controlled through the TCR. */ +#define CTIMER_TC_TCVAL_MASK (0xFFFFFFFFU) +#define CTIMER_TC_TCVAL_SHIFT (0U) +#define CTIMER_TC_TCVAL(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_TC_TCVAL_SHIFT)) & CTIMER_TC_TCVAL_MASK) + +/*! @name PR - Prescale Register. When the Prescale Counter (PC) is equal to this value, the next clock increments the TC and clears the PC. */ +#define CTIMER_PR_PRVAL_MASK (0xFFFFFFFFU) +#define CTIMER_PR_PRVAL_SHIFT (0U) +#define CTIMER_PR_PRVAL(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_PR_PRVAL_SHIFT)) & CTIMER_PR_PRVAL_MASK) + +/*! @name PC - Prescale Counter. The 32 bit PC is a counter which is incremented to the value stored in PR. When the value in PR is reached, the TC is incremented and the PC is cleared. The PC is observable and controllable through the bus interface. */ +#define CTIMER_PC_PCVAL_MASK (0xFFFFFFFFU) +#define CTIMER_PC_PCVAL_SHIFT (0U) +#define CTIMER_PC_PCVAL(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_PC_PCVAL_SHIFT)) & CTIMER_PC_PCVAL_MASK) + +/*! @name MCR - Match Control Register. The MCR is used to control if an interrupt is generated and if the TC is reset when a Match occurs. */ +#define CTIMER_MCR_MR0I_MASK (0x1U) +#define CTIMER_MCR_MR0I_SHIFT (0U) +#define CTIMER_MCR_MR0I(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR0I_SHIFT)) & CTIMER_MCR_MR0I_MASK) +#define CTIMER_MCR_MR0R_MASK (0x2U) +#define CTIMER_MCR_MR0R_SHIFT (1U) +#define CTIMER_MCR_MR0R(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR0R_SHIFT)) & CTIMER_MCR_MR0R_MASK) +#define CTIMER_MCR_MR0S_MASK (0x4U) +#define CTIMER_MCR_MR0S_SHIFT (2U) +#define CTIMER_MCR_MR0S(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR0S_SHIFT)) & CTIMER_MCR_MR0S_MASK) +#define CTIMER_MCR_MR1I_MASK (0x8U) +#define CTIMER_MCR_MR1I_SHIFT (3U) +#define CTIMER_MCR_MR1I(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR1I_SHIFT)) & CTIMER_MCR_MR1I_MASK) +#define CTIMER_MCR_MR1R_MASK (0x10U) +#define CTIMER_MCR_MR1R_SHIFT (4U) +#define CTIMER_MCR_MR1R(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR1R_SHIFT)) & CTIMER_MCR_MR1R_MASK) +#define CTIMER_MCR_MR1S_MASK (0x20U) +#define CTIMER_MCR_MR1S_SHIFT (5U) +#define CTIMER_MCR_MR1S(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR1S_SHIFT)) & CTIMER_MCR_MR1S_MASK) +#define CTIMER_MCR_MR2I_MASK (0x40U) +#define CTIMER_MCR_MR2I_SHIFT (6U) +#define CTIMER_MCR_MR2I(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR2I_SHIFT)) & CTIMER_MCR_MR2I_MASK) +#define CTIMER_MCR_MR2R_MASK (0x80U) +#define CTIMER_MCR_MR2R_SHIFT (7U) +#define CTIMER_MCR_MR2R(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR2R_SHIFT)) & CTIMER_MCR_MR2R_MASK) +#define CTIMER_MCR_MR2S_MASK (0x100U) +#define CTIMER_MCR_MR2S_SHIFT (8U) +#define CTIMER_MCR_MR2S(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR2S_SHIFT)) & CTIMER_MCR_MR2S_MASK) +#define CTIMER_MCR_MR3I_MASK (0x200U) +#define CTIMER_MCR_MR3I_SHIFT (9U) +#define CTIMER_MCR_MR3I(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR3I_SHIFT)) & CTIMER_MCR_MR3I_MASK) +#define CTIMER_MCR_MR3R_MASK (0x400U) +#define CTIMER_MCR_MR3R_SHIFT (10U) +#define CTIMER_MCR_MR3R(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR3R_SHIFT)) & CTIMER_MCR_MR3R_MASK) +#define CTIMER_MCR_MR3S_MASK (0x800U) +#define CTIMER_MCR_MR3S_SHIFT (11U) +#define CTIMER_MCR_MR3S(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR3S_SHIFT)) & CTIMER_MCR_MR3S_MASK) + +/*! @name MR - Match Register . MR can be enabled through the MCR to reset the TC, stop both the TC and PC, and/or generate an interrupt every time MR matches the TC. */ +#define CTIMER_MR_MATCH_MASK (0xFFFFFFFFU) +#define CTIMER_MR_MATCH_SHIFT (0U) +#define CTIMER_MR_MATCH(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_MR_MATCH_SHIFT)) & CTIMER_MR_MATCH_MASK) + +/* The count of CTIMER_MR */ +#define CTIMER_MR_COUNT (4U) + +/*! @name CCR - Capture Control Register. The CCR controls which edges of the capture inputs are used to load the Capture Registers and whether or not an interrupt is generated when a capture takes place. */ +#define CTIMER_CCR_CAP0RE_MASK (0x1U) +#define CTIMER_CCR_CAP0RE_SHIFT (0U) +#define CTIMER_CCR_CAP0RE(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CCR_CAP0RE_SHIFT)) & CTIMER_CCR_CAP0RE_MASK) +#define CTIMER_CCR_CAP0FE_MASK (0x2U) +#define CTIMER_CCR_CAP0FE_SHIFT (1U) +#define CTIMER_CCR_CAP0FE(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CCR_CAP0FE_SHIFT)) & CTIMER_CCR_CAP0FE_MASK) +#define CTIMER_CCR_CAP0I_MASK (0x4U) +#define CTIMER_CCR_CAP0I_SHIFT (2U) +#define CTIMER_CCR_CAP0I(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CCR_CAP0I_SHIFT)) & CTIMER_CCR_CAP0I_MASK) +#define CTIMER_CCR_CAP1RE_MASK (0x8U) +#define CTIMER_CCR_CAP1RE_SHIFT (3U) +#define CTIMER_CCR_CAP1RE(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CCR_CAP1RE_SHIFT)) & CTIMER_CCR_CAP1RE_MASK) +#define CTIMER_CCR_CAP1FE_MASK (0x10U) +#define CTIMER_CCR_CAP1FE_SHIFT (4U) +#define CTIMER_CCR_CAP1FE(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CCR_CAP1FE_SHIFT)) & CTIMER_CCR_CAP1FE_MASK) +#define CTIMER_CCR_CAP1I_MASK (0x20U) +#define CTIMER_CCR_CAP1I_SHIFT (5U) +#define CTIMER_CCR_CAP1I(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CCR_CAP1I_SHIFT)) & CTIMER_CCR_CAP1I_MASK) +#define CTIMER_CCR_CAP2RE_MASK (0x40U) +#define CTIMER_CCR_CAP2RE_SHIFT (6U) +#define CTIMER_CCR_CAP2RE(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CCR_CAP2RE_SHIFT)) & CTIMER_CCR_CAP2RE_MASK) +#define CTIMER_CCR_CAP2FE_MASK (0x80U) +#define CTIMER_CCR_CAP2FE_SHIFT (7U) +#define CTIMER_CCR_CAP2FE(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CCR_CAP2FE_SHIFT)) & CTIMER_CCR_CAP2FE_MASK) +#define CTIMER_CCR_CAP2I_MASK (0x100U) +#define CTIMER_CCR_CAP2I_SHIFT (8U) +#define CTIMER_CCR_CAP2I(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CCR_CAP2I_SHIFT)) & CTIMER_CCR_CAP2I_MASK) +#define CTIMER_CCR_CAP3RE_MASK (0x200U) +#define CTIMER_CCR_CAP3RE_SHIFT (9U) +#define CTIMER_CCR_CAP3RE(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CCR_CAP3RE_SHIFT)) & CTIMER_CCR_CAP3RE_MASK) +#define CTIMER_CCR_CAP3FE_MASK (0x400U) +#define CTIMER_CCR_CAP3FE_SHIFT (10U) +#define CTIMER_CCR_CAP3FE(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CCR_CAP3FE_SHIFT)) & CTIMER_CCR_CAP3FE_MASK) +#define CTIMER_CCR_CAP3I_MASK (0x800U) +#define CTIMER_CCR_CAP3I_SHIFT (11U) +#define CTIMER_CCR_CAP3I(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CCR_CAP3I_SHIFT)) & CTIMER_CCR_CAP3I_MASK) + +/*! @name CR - Capture Register . CR is loaded with the value of TC when there is an event on the CAPn. input. */ +#define CTIMER_CR_CAP_MASK (0xFFFFFFFFU) +#define CTIMER_CR_CAP_SHIFT (0U) +#define CTIMER_CR_CAP(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CR_CAP_SHIFT)) & CTIMER_CR_CAP_MASK) + +/* The count of CTIMER_CR */ +#define CTIMER_CR_COUNT (4U) + +/*! @name EMR - External Match Register. The EMR controls the match function and the external match pins. */ +#define CTIMER_EMR_EM0_MASK (0x1U) +#define CTIMER_EMR_EM0_SHIFT (0U) +#define CTIMER_EMR_EM0(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_EMR_EM0_SHIFT)) & CTIMER_EMR_EM0_MASK) +#define CTIMER_EMR_EM1_MASK (0x2U) +#define CTIMER_EMR_EM1_SHIFT (1U) +#define CTIMER_EMR_EM1(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_EMR_EM1_SHIFT)) & CTIMER_EMR_EM1_MASK) +#define CTIMER_EMR_EM2_MASK (0x4U) +#define CTIMER_EMR_EM2_SHIFT (2U) +#define CTIMER_EMR_EM2(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_EMR_EM2_SHIFT)) & CTIMER_EMR_EM2_MASK) +#define CTIMER_EMR_EM3_MASK (0x8U) +#define CTIMER_EMR_EM3_SHIFT (3U) +#define CTIMER_EMR_EM3(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_EMR_EM3_SHIFT)) & CTIMER_EMR_EM3_MASK) +#define CTIMER_EMR_EMC0_MASK (0x30U) +#define CTIMER_EMR_EMC0_SHIFT (4U) +#define CTIMER_EMR_EMC0(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_EMR_EMC0_SHIFT)) & CTIMER_EMR_EMC0_MASK) +#define CTIMER_EMR_EMC1_MASK (0xC0U) +#define CTIMER_EMR_EMC1_SHIFT (6U) +#define CTIMER_EMR_EMC1(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_EMR_EMC1_SHIFT)) & CTIMER_EMR_EMC1_MASK) +#define CTIMER_EMR_EMC2_MASK (0x300U) +#define CTIMER_EMR_EMC2_SHIFT (8U) +#define CTIMER_EMR_EMC2(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_EMR_EMC2_SHIFT)) & CTIMER_EMR_EMC2_MASK) +#define CTIMER_EMR_EMC3_MASK (0xC00U) +#define CTIMER_EMR_EMC3_SHIFT (10U) +#define CTIMER_EMR_EMC3(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_EMR_EMC3_SHIFT)) & CTIMER_EMR_EMC3_MASK) + +/*! @name CTCR - Count Control Register. The CTCR selects between Timer and Counter mode, and in Counter mode selects the signal and edge(s) for counting. */ +#define CTIMER_CTCR_CTMODE_MASK (0x3U) +#define CTIMER_CTCR_CTMODE_SHIFT (0U) +#define CTIMER_CTCR_CTMODE(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CTCR_CTMODE_SHIFT)) & CTIMER_CTCR_CTMODE_MASK) +#define CTIMER_CTCR_CINSEL_MASK (0xCU) +#define CTIMER_CTCR_CINSEL_SHIFT (2U) +#define CTIMER_CTCR_CINSEL(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CTCR_CINSEL_SHIFT)) & CTIMER_CTCR_CINSEL_MASK) +#define CTIMER_CTCR_ENCC_MASK (0x10U) +#define CTIMER_CTCR_ENCC_SHIFT (4U) +#define CTIMER_CTCR_ENCC(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CTCR_ENCC_SHIFT)) & CTIMER_CTCR_ENCC_MASK) +#define CTIMER_CTCR_SELCC_MASK (0xE0U) +#define CTIMER_CTCR_SELCC_SHIFT (5U) +#define CTIMER_CTCR_SELCC(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CTCR_SELCC_SHIFT)) & CTIMER_CTCR_SELCC_MASK) + +/*! @name PWMC - PWM Control Register. The PWMCON enables PWM mode for the external match pins. */ +#define CTIMER_PWMC_PWMEN0_MASK (0x1U) +#define CTIMER_PWMC_PWMEN0_SHIFT (0U) +#define CTIMER_PWMC_PWMEN0(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_PWMC_PWMEN0_SHIFT)) & CTIMER_PWMC_PWMEN0_MASK) +#define CTIMER_PWMC_PWMEN1_MASK (0x2U) +#define CTIMER_PWMC_PWMEN1_SHIFT (1U) +#define CTIMER_PWMC_PWMEN1(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_PWMC_PWMEN1_SHIFT)) & CTIMER_PWMC_PWMEN1_MASK) +#define CTIMER_PWMC_PWMEN2_MASK (0x4U) +#define CTIMER_PWMC_PWMEN2_SHIFT (2U) +#define CTIMER_PWMC_PWMEN2(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_PWMC_PWMEN2_SHIFT)) & CTIMER_PWMC_PWMEN2_MASK) +#define CTIMER_PWMC_PWMEN3_MASK (0x8U) +#define CTIMER_PWMC_PWMEN3_SHIFT (3U) +#define CTIMER_PWMC_PWMEN3(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_PWMC_PWMEN3_SHIFT)) & CTIMER_PWMC_PWMEN3_MASK) + + +/*! + * @} + */ /* end of group CTIMER_Register_Masks */ + + +/* CTIMER - Peripheral instance base addresses */ +/** Peripheral CTIMER0 base address */ +#define CTIMER0_BASE (0x400B4000u) +/** Peripheral CTIMER0 base pointer */ +#define CTIMER0 ((CTIMER_Type *)CTIMER0_BASE) +/** Peripheral CTIMER1 base address */ +#define CTIMER1_BASE (0x400B8000u) +/** Peripheral CTIMER1 base pointer */ +#define CTIMER1 ((CTIMER_Type *)CTIMER1_BASE) +/** Peripheral CTIMER2 base address */ +#define CTIMER2_BASE (0x40004000u) +/** Peripheral CTIMER2 base pointer */ +#define CTIMER2 ((CTIMER_Type *)CTIMER2_BASE) +/** Peripheral CTIMER3 base address */ +#define CTIMER3_BASE (0x40008000u) +/** Peripheral CTIMER3 base pointer */ +#define CTIMER3 ((CTIMER_Type *)CTIMER3_BASE) +/** Peripheral CTIMER4 base address */ +#define CTIMER4_BASE (0x4000C000u) +/** Peripheral CTIMER4 base pointer */ +#define CTIMER4 ((CTIMER_Type *)CTIMER4_BASE) +/** Array initializer of CTIMER peripheral base addresses */ +#define CTIMER_BASE_ADDRS { CTIMER0_BASE, CTIMER1_BASE, CTIMER2_BASE, CTIMER3_BASE, CTIMER4_BASE } +/** Array initializer of CTIMER peripheral base pointers */ +#define CTIMER_BASE_PTRS { CTIMER0, CTIMER1, CTIMER2, CTIMER3, CTIMER4 } +/** Interrupt vectors for the CTIMER peripheral type */ +#define CTIMER_IRQS { CTIMER0_IRQn, CTIMER1_IRQn, CTIMER2_IRQn, CTIMER3_IRQn, CTIMER4_IRQn } + +/*! + * @} + */ /* end of group CTIMER_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- DMA Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup DMA_Peripheral_Access_Layer DMA Peripheral Access Layer + * @{ + */ + +/** DMA - Register Layout Typedef */ +typedef struct { + __IO uint32_t CTRL; /**< DMA control., offset: 0x0 */ + __I uint32_t INTSTAT; /**< Interrupt status., offset: 0x4 */ + __IO uint32_t SRAMBASE; /**< SRAM address of the channel configuration table., offset: 0x8 */ + uint8_t RESERVED_0[20]; + struct { /* offset: 0x20, array step: 0x5C */ + __IO uint32_t ENABLESET; /**< Channel Enable read and Set for all DMA channels., array offset: 0x20, array step: 0x5C */ + uint8_t RESERVED_0[4]; + __O uint32_t ENABLECLR; /**< Channel Enable Clear for all DMA channels., array offset: 0x28, array step: 0x5C */ + uint8_t RESERVED_1[4]; + __IO uint32_t ACTIVE; /**< Channel Active status for all DMA channels., array offset: 0x30, array step: 0x5C */ + uint8_t RESERVED_2[4]; + __IO uint32_t BUSY; /**< Channel Busy status for all DMA channels., array offset: 0x38, array step: 0x5C */ + uint8_t RESERVED_3[4]; + __IO uint32_t ERRINT; /**< Error Interrupt status for all DMA channels., array offset: 0x40, array step: 0x5C */ + uint8_t RESERVED_4[4]; + __IO uint32_t INTENSET; /**< Interrupt Enable read and Set for all DMA channels., array offset: 0x48, array step: 0x5C */ + uint8_t RESERVED_5[4]; + __O uint32_t INTENCLR; /**< Interrupt Enable Clear for all DMA channels., array offset: 0x50, array step: 0x5C */ + uint8_t RESERVED_6[4]; + __IO uint32_t INTA; /**< Interrupt A status for all DMA channels., array offset: 0x58, array step: 0x5C */ + uint8_t RESERVED_7[4]; + __IO uint32_t INTB; /**< Interrupt B status for all DMA channels., array offset: 0x60, array step: 0x5C */ + uint8_t RESERVED_8[4]; + __O uint32_t SETVALID; /**< Set ValidPending control bits for all DMA channels., array offset: 0x68, array step: 0x5C */ + uint8_t RESERVED_9[4]; + __O uint32_t SETTRIG; /**< Set Trigger control bits for all DMA channels., array offset: 0x70, array step: 0x5C */ + uint8_t RESERVED_10[4]; + __O uint32_t ABORT; /**< Channel Abort control for all DMA channels., array offset: 0x78, array step: 0x5C */ + } COMMON[1]; + uint8_t RESERVED_1[900]; + struct { /* offset: 0x400, array step: 0x10 */ + __IO uint32_t CFG; /**< Configuration register for DMA channel ., array offset: 0x400, array step: 0x10 */ + __I uint32_t CTLSTAT; /**< Control and status register for DMA channel ., array offset: 0x404, array step: 0x10 */ + __IO uint32_t XFERCFG; /**< Transfer configuration register for DMA channel ., array offset: 0x408, array step: 0x10 */ + uint8_t RESERVED_0[4]; + } CHANNEL[22]; +} DMA_Type; + +/* ---------------------------------------------------------------------------- + -- DMA Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup DMA_Register_Masks DMA Register Masks + * @{ + */ + +/*! @name CTRL - DMA control. */ +#define DMA_CTRL_ENABLE_MASK (0x1U) +#define DMA_CTRL_ENABLE_SHIFT (0U) +#define DMA_CTRL_ENABLE(x) (((uint32_t)(((uint32_t)(x)) << DMA_CTRL_ENABLE_SHIFT)) & DMA_CTRL_ENABLE_MASK) + +/*! @name INTSTAT - Interrupt status. */ +#define DMA_INTSTAT_ACTIVEINT_MASK (0x2U) +#define DMA_INTSTAT_ACTIVEINT_SHIFT (1U) +#define DMA_INTSTAT_ACTIVEINT(x) (((uint32_t)(((uint32_t)(x)) << DMA_INTSTAT_ACTIVEINT_SHIFT)) & DMA_INTSTAT_ACTIVEINT_MASK) +#define DMA_INTSTAT_ACTIVEERRINT_MASK (0x4U) +#define DMA_INTSTAT_ACTIVEERRINT_SHIFT (2U) +#define DMA_INTSTAT_ACTIVEERRINT(x) (((uint32_t)(((uint32_t)(x)) << DMA_INTSTAT_ACTIVEERRINT_SHIFT)) & DMA_INTSTAT_ACTIVEERRINT_MASK) + +/*! @name SRAMBASE - SRAM address of the channel configuration table. */ +#define DMA_SRAMBASE_OFFSET_MASK (0xFFFFFE00U) +#define DMA_SRAMBASE_OFFSET_SHIFT (9U) +#define DMA_SRAMBASE_OFFSET(x) (((uint32_t)(((uint32_t)(x)) << DMA_SRAMBASE_OFFSET_SHIFT)) & DMA_SRAMBASE_OFFSET_MASK) + +/*! @name COMMON_ENABLESET - Channel Enable read and Set for all DMA channels. */ +#define DMA_COMMON_ENABLESET_ENA_MASK (0x3FFFFFU) +#define DMA_COMMON_ENABLESET_ENA_SHIFT (0U) +#define DMA_COMMON_ENABLESET_ENA(x) (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_ENABLESET_ENA_SHIFT)) & DMA_COMMON_ENABLESET_ENA_MASK) + +/* The count of DMA_COMMON_ENABLESET */ +#define DMA_COMMON_ENABLESET_COUNT (1U) + +/*! @name COMMON_ENABLECLR - Channel Enable Clear for all DMA channels. */ +#define DMA_COMMON_ENABLECLR_CLR_MASK (0x3FFFFFU) +#define DMA_COMMON_ENABLECLR_CLR_SHIFT (0U) +#define DMA_COMMON_ENABLECLR_CLR(x) (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_ENABLECLR_CLR_SHIFT)) & DMA_COMMON_ENABLECLR_CLR_MASK) + +/* The count of DMA_COMMON_ENABLECLR */ +#define DMA_COMMON_ENABLECLR_COUNT (1U) + +/*! @name COMMON_ACTIVE - Channel Active status for all DMA channels. */ +#define DMA_COMMON_ACTIVE_ACT_MASK (0x3FFFFFU) +#define DMA_COMMON_ACTIVE_ACT_SHIFT (0U) +#define DMA_COMMON_ACTIVE_ACT(x) (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_ACTIVE_ACT_SHIFT)) & DMA_COMMON_ACTIVE_ACT_MASK) + +/* The count of DMA_COMMON_ACTIVE */ +#define DMA_COMMON_ACTIVE_COUNT (1U) + +/*! @name COMMON_BUSY - Channel Busy status for all DMA channels. */ +#define DMA_COMMON_BUSY_BSY_MASK (0x3FFFFFU) +#define DMA_COMMON_BUSY_BSY_SHIFT (0U) +#define DMA_COMMON_BUSY_BSY(x) (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_BUSY_BSY_SHIFT)) & DMA_COMMON_BUSY_BSY_MASK) + +/* The count of DMA_COMMON_BUSY */ +#define DMA_COMMON_BUSY_COUNT (1U) + +/*! @name COMMON_ERRINT - Error Interrupt status for all DMA channels. */ +#define DMA_COMMON_ERRINT_ERR_MASK (0x3FFFFFU) +#define DMA_COMMON_ERRINT_ERR_SHIFT (0U) +#define DMA_COMMON_ERRINT_ERR(x) (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_ERRINT_ERR_SHIFT)) & DMA_COMMON_ERRINT_ERR_MASK) + +/* The count of DMA_COMMON_ERRINT */ +#define DMA_COMMON_ERRINT_COUNT (1U) + +/*! @name COMMON_INTENSET - Interrupt Enable read and Set for all DMA channels. */ +#define DMA_COMMON_INTENSET_INTEN_MASK (0x3FFFFFU) +#define DMA_COMMON_INTENSET_INTEN_SHIFT (0U) +#define DMA_COMMON_INTENSET_INTEN(x) (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_INTENSET_INTEN_SHIFT)) & DMA_COMMON_INTENSET_INTEN_MASK) + +/* The count of DMA_COMMON_INTENSET */ +#define DMA_COMMON_INTENSET_COUNT (1U) + +/*! @name COMMON_INTENCLR - Interrupt Enable Clear for all DMA channels. */ +#define DMA_COMMON_INTENCLR_CLR_MASK (0x3FFFFFU) +#define DMA_COMMON_INTENCLR_CLR_SHIFT (0U) +#define DMA_COMMON_INTENCLR_CLR(x) (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_INTENCLR_CLR_SHIFT)) & DMA_COMMON_INTENCLR_CLR_MASK) + +/* The count of DMA_COMMON_INTENCLR */ +#define DMA_COMMON_INTENCLR_COUNT (1U) + +/*! @name COMMON_INTA - Interrupt A status for all DMA channels. */ +#define DMA_COMMON_INTA_IA_MASK (0x3FFFFFU) +#define DMA_COMMON_INTA_IA_SHIFT (0U) +#define DMA_COMMON_INTA_IA(x) (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_INTA_IA_SHIFT)) & DMA_COMMON_INTA_IA_MASK) + +/* The count of DMA_COMMON_INTA */ +#define DMA_COMMON_INTA_COUNT (1U) + +/*! @name COMMON_INTB - Interrupt B status for all DMA channels. */ +#define DMA_COMMON_INTB_IB_MASK (0x3FFFFFU) +#define DMA_COMMON_INTB_IB_SHIFT (0U) +#define DMA_COMMON_INTB_IB(x) (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_INTB_IB_SHIFT)) & DMA_COMMON_INTB_IB_MASK) + +/* The count of DMA_COMMON_INTB */ +#define DMA_COMMON_INTB_COUNT (1U) + +/*! @name COMMON_SETVALID - Set ValidPending control bits for all DMA channels. */ +#define DMA_COMMON_SETVALID_SV_MASK (0x3FFFFFU) +#define DMA_COMMON_SETVALID_SV_SHIFT (0U) +#define DMA_COMMON_SETVALID_SV(x) (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_SETVALID_SV_SHIFT)) & DMA_COMMON_SETVALID_SV_MASK) + +/* The count of DMA_COMMON_SETVALID */ +#define DMA_COMMON_SETVALID_COUNT (1U) + +/*! @name COMMON_SETTRIG - Set Trigger control bits for all DMA channels. */ +#define DMA_COMMON_SETTRIG_TRIG_MASK (0x3FFFFFU) +#define DMA_COMMON_SETTRIG_TRIG_SHIFT (0U) +#define DMA_COMMON_SETTRIG_TRIG(x) (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_SETTRIG_TRIG_SHIFT)) & DMA_COMMON_SETTRIG_TRIG_MASK) + +/* The count of DMA_COMMON_SETTRIG */ +#define DMA_COMMON_SETTRIG_COUNT (1U) + +/*! @name COMMON_ABORT - Channel Abort control for all DMA channels. */ +#define DMA_COMMON_ABORT_ABORTCTRL_MASK (0x3FFFFFU) +#define DMA_COMMON_ABORT_ABORTCTRL_SHIFT (0U) +#define DMA_COMMON_ABORT_ABORTCTRL(x) (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_ABORT_ABORTCTRL_SHIFT)) & DMA_COMMON_ABORT_ABORTCTRL_MASK) + +/* The count of DMA_COMMON_ABORT */ +#define DMA_COMMON_ABORT_COUNT (1U) + +/*! @name CHANNEL_CFG - Configuration register for DMA channel . */ +#define DMA_CHANNEL_CFG_PERIPHREQEN_MASK (0x1U) +#define DMA_CHANNEL_CFG_PERIPHREQEN_SHIFT (0U) +#define DMA_CHANNEL_CFG_PERIPHREQEN(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CFG_PERIPHREQEN_SHIFT)) & DMA_CHANNEL_CFG_PERIPHREQEN_MASK) +#define DMA_CHANNEL_CFG_HWTRIGEN_MASK (0x2U) +#define DMA_CHANNEL_CFG_HWTRIGEN_SHIFT (1U) +#define DMA_CHANNEL_CFG_HWTRIGEN(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CFG_HWTRIGEN_SHIFT)) & DMA_CHANNEL_CFG_HWTRIGEN_MASK) +#define DMA_CHANNEL_CFG_TRIGPOL_MASK (0x10U) +#define DMA_CHANNEL_CFG_TRIGPOL_SHIFT (4U) +#define DMA_CHANNEL_CFG_TRIGPOL(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CFG_TRIGPOL_SHIFT)) & DMA_CHANNEL_CFG_TRIGPOL_MASK) +#define DMA_CHANNEL_CFG_TRIGTYPE_MASK (0x20U) +#define DMA_CHANNEL_CFG_TRIGTYPE_SHIFT (5U) +#define DMA_CHANNEL_CFG_TRIGTYPE(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CFG_TRIGTYPE_SHIFT)) & DMA_CHANNEL_CFG_TRIGTYPE_MASK) +#define DMA_CHANNEL_CFG_TRIGBURST_MASK (0x40U) +#define DMA_CHANNEL_CFG_TRIGBURST_SHIFT (6U) +#define DMA_CHANNEL_CFG_TRIGBURST(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CFG_TRIGBURST_SHIFT)) & DMA_CHANNEL_CFG_TRIGBURST_MASK) +#define DMA_CHANNEL_CFG_BURSTPOWER_MASK (0xF00U) +#define DMA_CHANNEL_CFG_BURSTPOWER_SHIFT (8U) +#define DMA_CHANNEL_CFG_BURSTPOWER(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CFG_BURSTPOWER_SHIFT)) & DMA_CHANNEL_CFG_BURSTPOWER_MASK) +#define DMA_CHANNEL_CFG_SRCBURSTWRAP_MASK (0x4000U) +#define DMA_CHANNEL_CFG_SRCBURSTWRAP_SHIFT (14U) +#define DMA_CHANNEL_CFG_SRCBURSTWRAP(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CFG_SRCBURSTWRAP_SHIFT)) & DMA_CHANNEL_CFG_SRCBURSTWRAP_MASK) +#define DMA_CHANNEL_CFG_DSTBURSTWRAP_MASK (0x8000U) +#define DMA_CHANNEL_CFG_DSTBURSTWRAP_SHIFT (15U) +#define DMA_CHANNEL_CFG_DSTBURSTWRAP(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CFG_DSTBURSTWRAP_SHIFT)) & DMA_CHANNEL_CFG_DSTBURSTWRAP_MASK) +#define DMA_CHANNEL_CFG_CHPRIORITY_MASK (0x70000U) +#define DMA_CHANNEL_CFG_CHPRIORITY_SHIFT (16U) +#define DMA_CHANNEL_CFG_CHPRIORITY(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CFG_CHPRIORITY_SHIFT)) & DMA_CHANNEL_CFG_CHPRIORITY_MASK) + +/* The count of DMA_CHANNEL_CFG */ +#define DMA_CHANNEL_CFG_COUNT (22U) + +/*! @name CHANNEL_CTLSTAT - Control and status register for DMA channel . */ +#define DMA_CHANNEL_CTLSTAT_VALIDPENDING_MASK (0x1U) +#define DMA_CHANNEL_CTLSTAT_VALIDPENDING_SHIFT (0U) +#define DMA_CHANNEL_CTLSTAT_VALIDPENDING(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CTLSTAT_VALIDPENDING_SHIFT)) & DMA_CHANNEL_CTLSTAT_VALIDPENDING_MASK) +#define DMA_CHANNEL_CTLSTAT_TRIG_MASK (0x4U) +#define DMA_CHANNEL_CTLSTAT_TRIG_SHIFT (2U) +#define DMA_CHANNEL_CTLSTAT_TRIG(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CTLSTAT_TRIG_SHIFT)) & DMA_CHANNEL_CTLSTAT_TRIG_MASK) + +/* The count of DMA_CHANNEL_CTLSTAT */ +#define DMA_CHANNEL_CTLSTAT_COUNT (22U) + +/*! @name CHANNEL_XFERCFG - Transfer configuration register for DMA channel . */ +#define DMA_CHANNEL_XFERCFG_CFGVALID_MASK (0x1U) +#define DMA_CHANNEL_XFERCFG_CFGVALID_SHIFT (0U) +#define DMA_CHANNEL_XFERCFG_CFGVALID(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_CFGVALID_SHIFT)) & DMA_CHANNEL_XFERCFG_CFGVALID_MASK) +#define DMA_CHANNEL_XFERCFG_RELOAD_MASK (0x2U) +#define DMA_CHANNEL_XFERCFG_RELOAD_SHIFT (1U) +#define DMA_CHANNEL_XFERCFG_RELOAD(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_RELOAD_SHIFT)) & DMA_CHANNEL_XFERCFG_RELOAD_MASK) +#define DMA_CHANNEL_XFERCFG_SWTRIG_MASK (0x4U) +#define DMA_CHANNEL_XFERCFG_SWTRIG_SHIFT (2U) +#define DMA_CHANNEL_XFERCFG_SWTRIG(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_SWTRIG_SHIFT)) & DMA_CHANNEL_XFERCFG_SWTRIG_MASK) +#define DMA_CHANNEL_XFERCFG_CLRTRIG_MASK (0x8U) +#define DMA_CHANNEL_XFERCFG_CLRTRIG_SHIFT (3U) +#define DMA_CHANNEL_XFERCFG_CLRTRIG(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_CLRTRIG_SHIFT)) & DMA_CHANNEL_XFERCFG_CLRTRIG_MASK) +#define DMA_CHANNEL_XFERCFG_SETINTA_MASK (0x10U) +#define DMA_CHANNEL_XFERCFG_SETINTA_SHIFT (4U) +#define DMA_CHANNEL_XFERCFG_SETINTA(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_SETINTA_SHIFT)) & DMA_CHANNEL_XFERCFG_SETINTA_MASK) +#define DMA_CHANNEL_XFERCFG_SETINTB_MASK (0x20U) +#define DMA_CHANNEL_XFERCFG_SETINTB_SHIFT (5U) +#define DMA_CHANNEL_XFERCFG_SETINTB(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_SETINTB_SHIFT)) & DMA_CHANNEL_XFERCFG_SETINTB_MASK) +#define DMA_CHANNEL_XFERCFG_WIDTH_MASK (0x300U) +#define DMA_CHANNEL_XFERCFG_WIDTH_SHIFT (8U) +#define DMA_CHANNEL_XFERCFG_WIDTH(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_WIDTH_SHIFT)) & DMA_CHANNEL_XFERCFG_WIDTH_MASK) +#define DMA_CHANNEL_XFERCFG_SRCINC_MASK (0x3000U) +#define DMA_CHANNEL_XFERCFG_SRCINC_SHIFT (12U) +#define DMA_CHANNEL_XFERCFG_SRCINC(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_SRCINC_SHIFT)) & DMA_CHANNEL_XFERCFG_SRCINC_MASK) +#define DMA_CHANNEL_XFERCFG_DSTINC_MASK (0xC000U) +#define DMA_CHANNEL_XFERCFG_DSTINC_SHIFT (14U) +#define DMA_CHANNEL_XFERCFG_DSTINC(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_DSTINC_SHIFT)) & DMA_CHANNEL_XFERCFG_DSTINC_MASK) +#define DMA_CHANNEL_XFERCFG_XFERCOUNT_MASK (0x3FF0000U) +#define DMA_CHANNEL_XFERCFG_XFERCOUNT_SHIFT (16U) +#define DMA_CHANNEL_XFERCFG_XFERCOUNT(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_XFERCOUNT_SHIFT)) & DMA_CHANNEL_XFERCFG_XFERCOUNT_MASK) + +/* The count of DMA_CHANNEL_XFERCFG */ +#define DMA_CHANNEL_XFERCFG_COUNT (22U) + + +/*! + * @} + */ /* end of group DMA_Register_Masks */ + + +/* DMA - Peripheral instance base addresses */ +/** Peripheral DMA0 base address */ +#define DMA0_BASE (0x1C004000u) +/** Peripheral DMA0 base pointer */ +#define DMA0 ((DMA_Type *)DMA0_BASE) +/** Array initializer of DMA peripheral base addresses */ +#define DMA_BASE_ADDRS { DMA0_BASE } +/** Array initializer of DMA peripheral base pointers */ +#define DMA_BASE_PTRS { DMA0 } +/** Interrupt vectors for the DMA peripheral type */ +#define DMA_IRQS { DMA0_IRQn } + +/*! + * @} + */ /* end of group DMA_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- GINT Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup GINT_Peripheral_Access_Layer GINT Peripheral Access Layer + * @{ + */ + +/** GINT - Register Layout Typedef */ +typedef struct { + __IO uint32_t CTRL; /**< GPIO grouped interrupt control register, offset: 0x0 */ + uint8_t RESERVED_0[28]; + __IO uint32_t PORT_POL[2]; /**< GPIO grouped interrupt port 0 polarity register, array offset: 0x20, array step: 0x4 */ + uint8_t RESERVED_1[24]; + __IO uint32_t PORT_ENA[2]; /**< GPIO grouped interrupt port 0 enable register, array offset: 0x40, array step: 0x4 */ +} GINT_Type; + +/* ---------------------------------------------------------------------------- + -- GINT Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup GINT_Register_Masks GINT Register Masks + * @{ + */ + +/*! @name CTRL - GPIO grouped interrupt control register */ +#define GINT_CTRL_INT_MASK (0x1U) +#define GINT_CTRL_INT_SHIFT (0U) +#define GINT_CTRL_INT(x) (((uint32_t)(((uint32_t)(x)) << GINT_CTRL_INT_SHIFT)) & GINT_CTRL_INT_MASK) +#define GINT_CTRL_COMB_MASK (0x2U) +#define GINT_CTRL_COMB_SHIFT (1U) +#define GINT_CTRL_COMB(x) (((uint32_t)(((uint32_t)(x)) << GINT_CTRL_COMB_SHIFT)) & GINT_CTRL_COMB_MASK) +#define GINT_CTRL_TRIG_MASK (0x4U) +#define GINT_CTRL_TRIG_SHIFT (2U) +#define GINT_CTRL_TRIG(x) (((uint32_t)(((uint32_t)(x)) << GINT_CTRL_TRIG_SHIFT)) & GINT_CTRL_TRIG_MASK) + +/*! @name PORT_POL - GPIO grouped interrupt port 0 polarity register */ +#define GINT_PORT_POL_POL_MASK (0xFFFFFFFFU) +#define GINT_PORT_POL_POL_SHIFT (0U) +#define GINT_PORT_POL_POL(x) (((uint32_t)(((uint32_t)(x)) << GINT_PORT_POL_POL_SHIFT)) & GINT_PORT_POL_POL_MASK) + +/* The count of GINT_PORT_POL */ +#define GINT_PORT_POL_COUNT (2U) + +/*! @name PORT_ENA - GPIO grouped interrupt port 0 enable register */ +#define GINT_PORT_ENA_ENA_MASK (0xFFFFFFFFU) +#define GINT_PORT_ENA_ENA_SHIFT (0U) +#define GINT_PORT_ENA_ENA(x) (((uint32_t)(((uint32_t)(x)) << GINT_PORT_ENA_ENA_SHIFT)) & GINT_PORT_ENA_ENA_MASK) + +/* The count of GINT_PORT_ENA */ +#define GINT_PORT_ENA_COUNT (2U) + + +/*! + * @} + */ /* end of group GINT_Register_Masks */ + + +/* GINT - Peripheral instance base addresses */ +/** Peripheral GINT0 base address */ +#define GINT0_BASE (0x40010000u) +/** Peripheral GINT0 base pointer */ +#define GINT0 ((GINT_Type *)GINT0_BASE) +/** Peripheral GINT1 base address */ +#define GINT1_BASE (0x40014000u) +/** Peripheral GINT1 base pointer */ +#define GINT1 ((GINT_Type *)GINT1_BASE) +/** Array initializer of GINT peripheral base addresses */ +#define GINT_BASE_ADDRS { GINT0_BASE, GINT1_BASE } +/** Array initializer of GINT peripheral base pointers */ +#define GINT_BASE_PTRS { GINT0, GINT1 } +/** Interrupt vectors for the GINT peripheral type */ +#define GINT_IRQS { GINT0_IRQn, NotAvail_IRQn } + +/*! + * @} + */ /* end of group GINT_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- GPIO Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup GPIO_Peripheral_Access_Layer GPIO Peripheral Access Layer + * @{ + */ + +/** GPIO - Register Layout Typedef */ +typedef struct { + __IO uint8_t B[2][32]; /**< Byte pin registers for all port 0 and 1 GPIO pins, array offset: 0x0, array step: index*0x20, index2*0x1 */ + uint8_t RESERVED_0[4032]; + __IO uint32_t W[2][32]; /**< Word pin registers for all port 0 and 1 GPIO pins, array offset: 0x1000, array step: index*0x80, index2*0x4 */ + uint8_t RESERVED_1[3840]; + __IO uint32_t DIR[2]; /**< Direction registers, array offset: 0x2000, array step: 0x4 */ + uint8_t RESERVED_2[120]; + __IO uint32_t MASK[2]; /**< Mask register, array offset: 0x2080, array step: 0x4 */ + uint8_t RESERVED_3[120]; + __IO uint32_t PIN[2]; /**< Port pin register, array offset: 0x2100, array step: 0x4 */ + uint8_t RESERVED_4[120]; + __IO uint32_t MPIN[2]; /**< Masked port register, array offset: 0x2180, array step: 0x4 */ + uint8_t RESERVED_5[120]; + __IO uint32_t SET[2]; /**< Write: Set register for port Read: output bits for port, array offset: 0x2200, array step: 0x4 */ + uint8_t RESERVED_6[120]; + __O uint32_t CLR[2]; /**< Clear port, array offset: 0x2280, array step: 0x4 */ + uint8_t RESERVED_7[120]; + __O uint32_t NOT[2]; /**< Toggle port, array offset: 0x2300, array step: 0x4 */ + uint8_t RESERVED_8[120]; + __O uint32_t DIRSET[2]; /**< Set pin direction bits for port, array offset: 0x2380, array step: 0x4 */ + uint8_t RESERVED_9[120]; + __O uint32_t DIRCLR[2]; /**< Clear pin direction bits for port, array offset: 0x2400, array step: 0x4 */ + uint8_t RESERVED_10[120]; + __O uint32_t DIRNOT[2]; /**< Toggle pin direction bits for port, array offset: 0x2480, array step: 0x4 */ +} GPIO_Type; + +/* ---------------------------------------------------------------------------- + -- GPIO Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup GPIO_Register_Masks GPIO Register Masks + * @{ + */ + +/*! @name B - Byte pin registers for all port 0 and 1 GPIO pins */ +#define GPIO_B_PBYTE_MASK (0x1U) +#define GPIO_B_PBYTE_SHIFT (0U) +#define GPIO_B_PBYTE(x) (((uint8_t)(((uint8_t)(x)) << GPIO_B_PBYTE_SHIFT)) & GPIO_B_PBYTE_MASK) + +/* The count of GPIO_B */ +#define GPIO_B_COUNT (2U) + +/* The count of GPIO_B */ +#define GPIO_B_COUNT2 (32U) + +/*! @name W - Word pin registers for all port 0 and 1 GPIO pins */ +#define GPIO_W_PWORD_MASK (0xFFFFFFFFU) +#define GPIO_W_PWORD_SHIFT (0U) +#define GPIO_W_PWORD(x) (((uint32_t)(((uint32_t)(x)) << GPIO_W_PWORD_SHIFT)) & GPIO_W_PWORD_MASK) + +/* The count of GPIO_W */ +#define GPIO_W_COUNT (2U) + +/* The count of GPIO_W */ +#define GPIO_W_COUNT2 (32U) + +/*! @name DIR - Direction registers */ +#define GPIO_DIR_DIRP_MASK (0xFFFFFFFFU) +#define GPIO_DIR_DIRP_SHIFT (0U) +#define GPIO_DIR_DIRP(x) (((uint32_t)(((uint32_t)(x)) << GPIO_DIR_DIRP_SHIFT)) & GPIO_DIR_DIRP_MASK) + +/* The count of GPIO_DIR */ +#define GPIO_DIR_COUNT (2U) + +/*! @name MASK - Mask register */ +#define GPIO_MASK_MASKP_MASK (0xFFFFFFFFU) +#define GPIO_MASK_MASKP_SHIFT (0U) +#define GPIO_MASK_MASKP(x) (((uint32_t)(((uint32_t)(x)) << GPIO_MASK_MASKP_SHIFT)) & GPIO_MASK_MASKP_MASK) + +/* The count of GPIO_MASK */ +#define GPIO_MASK_COUNT (2U) + +/*! @name PIN - Port pin register */ +#define GPIO_PIN_PORT_MASK (0xFFFFFFFFU) +#define GPIO_PIN_PORT_SHIFT (0U) +#define GPIO_PIN_PORT(x) (((uint32_t)(((uint32_t)(x)) << GPIO_PIN_PORT_SHIFT)) & GPIO_PIN_PORT_MASK) + +/* The count of GPIO_PIN */ +#define GPIO_PIN_COUNT (2U) + +/*! @name MPIN - Masked port register */ +#define GPIO_MPIN_MPORTP_MASK (0xFFFFFFFFU) +#define GPIO_MPIN_MPORTP_SHIFT (0U) +#define GPIO_MPIN_MPORTP(x) (((uint32_t)(((uint32_t)(x)) << GPIO_MPIN_MPORTP_SHIFT)) & GPIO_MPIN_MPORTP_MASK) + +/* The count of GPIO_MPIN */ +#define GPIO_MPIN_COUNT (2U) + +/*! @name SET - Write: Set register for port Read: output bits for port */ +#define GPIO_SET_SETP_MASK (0xFFFFFFFFU) +#define GPIO_SET_SETP_SHIFT (0U) +#define GPIO_SET_SETP(x) (((uint32_t)(((uint32_t)(x)) << GPIO_SET_SETP_SHIFT)) & GPIO_SET_SETP_MASK) + +/* The count of GPIO_SET */ +#define GPIO_SET_COUNT (2U) + +/*! @name CLR - Clear port */ +#define GPIO_CLR_CLRP_MASK (0xFFFFFFFFU) +#define GPIO_CLR_CLRP_SHIFT (0U) +#define GPIO_CLR_CLRP(x) (((uint32_t)(((uint32_t)(x)) << GPIO_CLR_CLRP_SHIFT)) & GPIO_CLR_CLRP_MASK) + +/* The count of GPIO_CLR */ +#define GPIO_CLR_COUNT (2U) + +/*! @name NOT - Toggle port */ +#define GPIO_NOT_NOTP_MASK (0xFFFFFFFFU) +#define GPIO_NOT_NOTP_SHIFT (0U) +#define GPIO_NOT_NOTP(x) (((uint32_t)(((uint32_t)(x)) << GPIO_NOT_NOTP_SHIFT)) & GPIO_NOT_NOTP_MASK) + +/* The count of GPIO_NOT */ +#define GPIO_NOT_COUNT (2U) + +/*! @name DIRSET - Set pin direction bits for port */ +#define GPIO_DIRSET_DIRSETP_MASK (0x1FFFFFFFU) +#define GPIO_DIRSET_DIRSETP_SHIFT (0U) +#define GPIO_DIRSET_DIRSETP(x) (((uint32_t)(((uint32_t)(x)) << GPIO_DIRSET_DIRSETP_SHIFT)) & GPIO_DIRSET_DIRSETP_MASK) + +/* The count of GPIO_DIRSET */ +#define GPIO_DIRSET_COUNT (2U) + +/*! @name DIRCLR - Clear pin direction bits for port */ +#define GPIO_DIRCLR_DIRCLRP_MASK (0x1FFFFFFFU) +#define GPIO_DIRCLR_DIRCLRP_SHIFT (0U) +#define GPIO_DIRCLR_DIRCLRP(x) (((uint32_t)(((uint32_t)(x)) << GPIO_DIRCLR_DIRCLRP_SHIFT)) & GPIO_DIRCLR_DIRCLRP_MASK) + +/* The count of GPIO_DIRCLR */ +#define GPIO_DIRCLR_COUNT (2U) + +/*! @name DIRNOT - Toggle pin direction bits for port */ +#define GPIO_DIRNOT_DIRNOTP_MASK (0x1FFFFFFFU) +#define GPIO_DIRNOT_DIRNOTP_SHIFT (0U) +#define GPIO_DIRNOT_DIRNOTP(x) (((uint32_t)(((uint32_t)(x)) << GPIO_DIRNOT_DIRNOTP_SHIFT)) & GPIO_DIRNOT_DIRNOTP_MASK) + +/* The count of GPIO_DIRNOT */ +#define GPIO_DIRNOT_COUNT (2U) + + +/*! + * @} + */ /* end of group GPIO_Register_Masks */ + + +/* GPIO - Peripheral instance base addresses */ +/** Peripheral GPIO base address */ +#define GPIO_BASE (0x1C000000u) +/** Peripheral GPIO base pointer */ +#define GPIO ((GPIO_Type *)GPIO_BASE) +/** Array initializer of GPIO peripheral base addresses */ +#define GPIO_BASE_ADDRS { GPIO_BASE } +/** Array initializer of GPIO peripheral base pointers */ +#define GPIO_BASE_PTRS { GPIO } + +/*! + * @} + */ /* end of group GPIO_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- I2C Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup I2C_Peripheral_Access_Layer I2C Peripheral Access Layer + * @{ + */ + +/** I2C - Register Layout Typedef */ +typedef struct { + __IO uint32_t CFG; /**< Configuration for shared functions., offset: 0x0 */ + __IO uint32_t STAT; /**< Status register for Master, Slave, and Monitor functions., offset: 0x4 */ + __IO uint32_t INTENSET; /**< Interrupt Enable Set and read register., offset: 0x8 */ + __IO uint32_t INTENCLR; /**< Interrupt Enable Clear register., offset: 0xC */ + __IO uint32_t TIMEOUT; /**< Time-out value register., offset: 0x10 */ + __IO uint32_t CLKDIV; /**< Clock pre-divider for the entire I2C block. This determines what time increments are used for the MSTTIME register, and controls some timing of the Slave function., offset: 0x14 */ + __IO uint32_t INTSTAT; /**< Interrupt Status register for Master, Slave, and Monitor functions., offset: 0x18 */ + uint8_t RESERVED_0[4]; + __IO uint32_t MSTCTL; /**< Master control register., offset: 0x20 */ + __IO uint32_t MSTTIME; /**< Master timing configuration., offset: 0x24 */ + __IO uint32_t MSTDAT; /**< Combined Master receiver and transmitter data register., offset: 0x28 */ + uint8_t RESERVED_1[20]; + __IO uint32_t SLVCTL; /**< Slave control register., offset: 0x40 */ + __IO uint32_t SLVDAT; /**< Combined Slave receiver and transmitter data register., offset: 0x44 */ + __IO uint32_t SLVADR[4]; /**< Slave address 0., array offset: 0x48, array step: 0x4 */ + __IO uint32_t SLVQUAL0; /**< Slave Qualification for address 0., offset: 0x58 */ + uint8_t RESERVED_2[36]; + __IO uint32_t MONRXDAT; /**< Monitor receiver data register., offset: 0x80 */ +} I2C_Type; + +/* ---------------------------------------------------------------------------- + -- I2C Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup I2C_Register_Masks I2C Register Masks + * @{ + */ + +/*! @name CFG - Configuration for shared functions. */ +#define I2C_CFG_MSTEN_MASK (0x1U) +#define I2C_CFG_MSTEN_SHIFT (0U) +#define I2C_CFG_MSTEN(x) (((uint32_t)(((uint32_t)(x)) << I2C_CFG_MSTEN_SHIFT)) & I2C_CFG_MSTEN_MASK) +#define I2C_CFG_SLVEN_MASK (0x2U) +#define I2C_CFG_SLVEN_SHIFT (1U) +#define I2C_CFG_SLVEN(x) (((uint32_t)(((uint32_t)(x)) << I2C_CFG_SLVEN_SHIFT)) & I2C_CFG_SLVEN_MASK) +#define I2C_CFG_MONEN_MASK (0x4U) +#define I2C_CFG_MONEN_SHIFT (2U) +#define I2C_CFG_MONEN(x) (((uint32_t)(((uint32_t)(x)) << I2C_CFG_MONEN_SHIFT)) & I2C_CFG_MONEN_MASK) +#define I2C_CFG_TIMEOUTEN_MASK (0x8U) +#define I2C_CFG_TIMEOUTEN_SHIFT (3U) +#define I2C_CFG_TIMEOUTEN(x) (((uint32_t)(((uint32_t)(x)) << I2C_CFG_TIMEOUTEN_SHIFT)) & I2C_CFG_TIMEOUTEN_MASK) +#define I2C_CFG_MONCLKSTR_MASK (0x10U) +#define I2C_CFG_MONCLKSTR_SHIFT (4U) +#define I2C_CFG_MONCLKSTR(x) (((uint32_t)(((uint32_t)(x)) << I2C_CFG_MONCLKSTR_SHIFT)) & I2C_CFG_MONCLKSTR_MASK) +#define I2C_CFG_HSCAPABLE_MASK (0x20U) +#define I2C_CFG_HSCAPABLE_SHIFT (5U) +#define I2C_CFG_HSCAPABLE(x) (((uint32_t)(((uint32_t)(x)) << I2C_CFG_HSCAPABLE_SHIFT)) & I2C_CFG_HSCAPABLE_MASK) + +/*! @name STAT - Status register for Master, Slave, and Monitor functions. */ +#define I2C_STAT_MSTPENDING_MASK (0x1U) +#define I2C_STAT_MSTPENDING_SHIFT (0U) +#define I2C_STAT_MSTPENDING(x) (((uint32_t)(((uint32_t)(x)) << I2C_STAT_MSTPENDING_SHIFT)) & I2C_STAT_MSTPENDING_MASK) +#define I2C_STAT_MSTSTATE_MASK (0xEU) +#define I2C_STAT_MSTSTATE_SHIFT (1U) +#define I2C_STAT_MSTSTATE(x) (((uint32_t)(((uint32_t)(x)) << I2C_STAT_MSTSTATE_SHIFT)) & I2C_STAT_MSTSTATE_MASK) +#define I2C_STAT_MSTARBLOSS_MASK (0x10U) +#define I2C_STAT_MSTARBLOSS_SHIFT (4U) +#define I2C_STAT_MSTARBLOSS(x) (((uint32_t)(((uint32_t)(x)) << I2C_STAT_MSTARBLOSS_SHIFT)) & I2C_STAT_MSTARBLOSS_MASK) +#define I2C_STAT_MSTSTSTPERR_MASK (0x40U) +#define I2C_STAT_MSTSTSTPERR_SHIFT (6U) +#define I2C_STAT_MSTSTSTPERR(x) (((uint32_t)(((uint32_t)(x)) << I2C_STAT_MSTSTSTPERR_SHIFT)) & I2C_STAT_MSTSTSTPERR_MASK) +#define I2C_STAT_SLVPENDING_MASK (0x100U) +#define I2C_STAT_SLVPENDING_SHIFT (8U) +#define I2C_STAT_SLVPENDING(x) (((uint32_t)(((uint32_t)(x)) << I2C_STAT_SLVPENDING_SHIFT)) & I2C_STAT_SLVPENDING_MASK) +#define I2C_STAT_SLVSTATE_MASK (0x600U) +#define I2C_STAT_SLVSTATE_SHIFT (9U) +#define I2C_STAT_SLVSTATE(x) (((uint32_t)(((uint32_t)(x)) << I2C_STAT_SLVSTATE_SHIFT)) & I2C_STAT_SLVSTATE_MASK) +#define I2C_STAT_SLVNOTSTR_MASK (0x800U) +#define I2C_STAT_SLVNOTSTR_SHIFT (11U) +#define I2C_STAT_SLVNOTSTR(x) (((uint32_t)(((uint32_t)(x)) << I2C_STAT_SLVNOTSTR_SHIFT)) & I2C_STAT_SLVNOTSTR_MASK) +#define I2C_STAT_SLVIDX_MASK (0x3000U) +#define I2C_STAT_SLVIDX_SHIFT (12U) +#define I2C_STAT_SLVIDX(x) (((uint32_t)(((uint32_t)(x)) << I2C_STAT_SLVIDX_SHIFT)) & I2C_STAT_SLVIDX_MASK) +#define I2C_STAT_SLVSEL_MASK (0x4000U) +#define I2C_STAT_SLVSEL_SHIFT (14U) +#define I2C_STAT_SLVSEL(x) (((uint32_t)(((uint32_t)(x)) << I2C_STAT_SLVSEL_SHIFT)) & I2C_STAT_SLVSEL_MASK) +#define I2C_STAT_SLVDESEL_MASK (0x8000U) +#define I2C_STAT_SLVDESEL_SHIFT (15U) +#define I2C_STAT_SLVDESEL(x) (((uint32_t)(((uint32_t)(x)) << I2C_STAT_SLVDESEL_SHIFT)) & I2C_STAT_SLVDESEL_MASK) +#define I2C_STAT_MONRDY_MASK (0x10000U) +#define I2C_STAT_MONRDY_SHIFT (16U) +#define I2C_STAT_MONRDY(x) (((uint32_t)(((uint32_t)(x)) << I2C_STAT_MONRDY_SHIFT)) & I2C_STAT_MONRDY_MASK) +#define I2C_STAT_MONOV_MASK (0x20000U) +#define I2C_STAT_MONOV_SHIFT (17U) +#define I2C_STAT_MONOV(x) (((uint32_t)(((uint32_t)(x)) << I2C_STAT_MONOV_SHIFT)) & I2C_STAT_MONOV_MASK) +#define I2C_STAT_MONACTIVE_MASK (0x40000U) +#define I2C_STAT_MONACTIVE_SHIFT (18U) +#define I2C_STAT_MONACTIVE(x) (((uint32_t)(((uint32_t)(x)) << I2C_STAT_MONACTIVE_SHIFT)) & I2C_STAT_MONACTIVE_MASK) +#define I2C_STAT_MONIDLE_MASK (0x80000U) +#define I2C_STAT_MONIDLE_SHIFT (19U) +#define I2C_STAT_MONIDLE(x) (((uint32_t)(((uint32_t)(x)) << I2C_STAT_MONIDLE_SHIFT)) & I2C_STAT_MONIDLE_MASK) +#define I2C_STAT_EVENTTIMEOUT_MASK (0x1000000U) +#define I2C_STAT_EVENTTIMEOUT_SHIFT (24U) +#define I2C_STAT_EVENTTIMEOUT(x) (((uint32_t)(((uint32_t)(x)) << I2C_STAT_EVENTTIMEOUT_SHIFT)) & I2C_STAT_EVENTTIMEOUT_MASK) +#define I2C_STAT_SCLTIMEOUT_MASK (0x2000000U) +#define I2C_STAT_SCLTIMEOUT_SHIFT (25U) +#define I2C_STAT_SCLTIMEOUT(x) (((uint32_t)(((uint32_t)(x)) << I2C_STAT_SCLTIMEOUT_SHIFT)) & I2C_STAT_SCLTIMEOUT_MASK) + +/*! @name INTENSET - Interrupt Enable Set and read register. */ +#define I2C_INTENSET_MSTPENDINGEN_MASK (0x1U) +#define I2C_INTENSET_MSTPENDINGEN_SHIFT (0U) +#define I2C_INTENSET_MSTPENDINGEN(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_MSTPENDINGEN_SHIFT)) & I2C_INTENSET_MSTPENDINGEN_MASK) +#define I2C_INTENSET_MSTARBLOSSEN_MASK (0x10U) +#define I2C_INTENSET_MSTARBLOSSEN_SHIFT (4U) +#define I2C_INTENSET_MSTARBLOSSEN(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_MSTARBLOSSEN_SHIFT)) & I2C_INTENSET_MSTARBLOSSEN_MASK) +#define I2C_INTENSET_MSTSTSTPERREN_MASK (0x40U) +#define I2C_INTENSET_MSTSTSTPERREN_SHIFT (6U) +#define I2C_INTENSET_MSTSTSTPERREN(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_MSTSTSTPERREN_SHIFT)) & I2C_INTENSET_MSTSTSTPERREN_MASK) +#define I2C_INTENSET_SLVPENDINGEN_MASK (0x100U) +#define I2C_INTENSET_SLVPENDINGEN_SHIFT (8U) +#define I2C_INTENSET_SLVPENDINGEN(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_SLVPENDINGEN_SHIFT)) & I2C_INTENSET_SLVPENDINGEN_MASK) +#define I2C_INTENSET_SLVNOTSTREN_MASK (0x800U) +#define I2C_INTENSET_SLVNOTSTREN_SHIFT (11U) +#define I2C_INTENSET_SLVNOTSTREN(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_SLVNOTSTREN_SHIFT)) & I2C_INTENSET_SLVNOTSTREN_MASK) +#define I2C_INTENSET_SLVDESELEN_MASK (0x8000U) +#define I2C_INTENSET_SLVDESELEN_SHIFT (15U) +#define I2C_INTENSET_SLVDESELEN(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_SLVDESELEN_SHIFT)) & I2C_INTENSET_SLVDESELEN_MASK) +#define I2C_INTENSET_MONRDYEN_MASK (0x10000U) +#define I2C_INTENSET_MONRDYEN_SHIFT (16U) +#define I2C_INTENSET_MONRDYEN(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_MONRDYEN_SHIFT)) & I2C_INTENSET_MONRDYEN_MASK) +#define I2C_INTENSET_MONOVEN_MASK (0x20000U) +#define I2C_INTENSET_MONOVEN_SHIFT (17U) +#define I2C_INTENSET_MONOVEN(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_MONOVEN_SHIFT)) & I2C_INTENSET_MONOVEN_MASK) +#define I2C_INTENSET_MONIDLEEN_MASK (0x80000U) +#define I2C_INTENSET_MONIDLEEN_SHIFT (19U) +#define I2C_INTENSET_MONIDLEEN(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_MONIDLEEN_SHIFT)) & I2C_INTENSET_MONIDLEEN_MASK) +#define I2C_INTENSET_EVENTTIMEOUTEN_MASK (0x1000000U) +#define I2C_INTENSET_EVENTTIMEOUTEN_SHIFT (24U) +#define I2C_INTENSET_EVENTTIMEOUTEN(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_EVENTTIMEOUTEN_SHIFT)) & I2C_INTENSET_EVENTTIMEOUTEN_MASK) +#define I2C_INTENSET_SCLTIMEOUTEN_MASK (0x2000000U) +#define I2C_INTENSET_SCLTIMEOUTEN_SHIFT (25U) +#define I2C_INTENSET_SCLTIMEOUTEN(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_SCLTIMEOUTEN_SHIFT)) & I2C_INTENSET_SCLTIMEOUTEN_MASK) + +/*! @name INTENCLR - Interrupt Enable Clear register. */ +#define I2C_INTENCLR_MSTPENDINGCLR_MASK (0x1U) +#define I2C_INTENCLR_MSTPENDINGCLR_SHIFT (0U) +#define I2C_INTENCLR_MSTPENDINGCLR(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_MSTPENDINGCLR_SHIFT)) & I2C_INTENCLR_MSTPENDINGCLR_MASK) +#define I2C_INTENCLR_MSTARBLOSSCLR_MASK (0x10U) +#define I2C_INTENCLR_MSTARBLOSSCLR_SHIFT (4U) +#define I2C_INTENCLR_MSTARBLOSSCLR(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_MSTARBLOSSCLR_SHIFT)) & I2C_INTENCLR_MSTARBLOSSCLR_MASK) +#define I2C_INTENCLR_MSTSTSTPERRCLR_MASK (0x40U) +#define I2C_INTENCLR_MSTSTSTPERRCLR_SHIFT (6U) +#define I2C_INTENCLR_MSTSTSTPERRCLR(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_MSTSTSTPERRCLR_SHIFT)) & I2C_INTENCLR_MSTSTSTPERRCLR_MASK) +#define I2C_INTENCLR_SLVPENDINGCLR_MASK (0x100U) +#define I2C_INTENCLR_SLVPENDINGCLR_SHIFT (8U) +#define I2C_INTENCLR_SLVPENDINGCLR(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_SLVPENDINGCLR_SHIFT)) & I2C_INTENCLR_SLVPENDINGCLR_MASK) +#define I2C_INTENCLR_SLVNOTSTRCLR_MASK (0x800U) +#define I2C_INTENCLR_SLVNOTSTRCLR_SHIFT (11U) +#define I2C_INTENCLR_SLVNOTSTRCLR(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_SLVNOTSTRCLR_SHIFT)) & I2C_INTENCLR_SLVNOTSTRCLR_MASK) +#define I2C_INTENCLR_SLVDESELCLR_MASK (0x8000U) +#define I2C_INTENCLR_SLVDESELCLR_SHIFT (15U) +#define I2C_INTENCLR_SLVDESELCLR(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_SLVDESELCLR_SHIFT)) & I2C_INTENCLR_SLVDESELCLR_MASK) +#define I2C_INTENCLR_MONRDYCLR_MASK (0x10000U) +#define I2C_INTENCLR_MONRDYCLR_SHIFT (16U) +#define I2C_INTENCLR_MONRDYCLR(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_MONRDYCLR_SHIFT)) & I2C_INTENCLR_MONRDYCLR_MASK) +#define I2C_INTENCLR_MONOVCLR_MASK (0x20000U) +#define I2C_INTENCLR_MONOVCLR_SHIFT (17U) +#define I2C_INTENCLR_MONOVCLR(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_MONOVCLR_SHIFT)) & I2C_INTENCLR_MONOVCLR_MASK) +#define I2C_INTENCLR_MONIDLECLR_MASK (0x80000U) +#define I2C_INTENCLR_MONIDLECLR_SHIFT (19U) +#define I2C_INTENCLR_MONIDLECLR(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_MONIDLECLR_SHIFT)) & I2C_INTENCLR_MONIDLECLR_MASK) +#define I2C_INTENCLR_EVENTTIMEOUTCLR_MASK (0x1000000U) +#define I2C_INTENCLR_EVENTTIMEOUTCLR_SHIFT (24U) +#define I2C_INTENCLR_EVENTTIMEOUTCLR(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_EVENTTIMEOUTCLR_SHIFT)) & I2C_INTENCLR_EVENTTIMEOUTCLR_MASK) +#define I2C_INTENCLR_SCLTIMEOUTCLR_MASK (0x2000000U) +#define I2C_INTENCLR_SCLTIMEOUTCLR_SHIFT (25U) +#define I2C_INTENCLR_SCLTIMEOUTCLR(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_SCLTIMEOUTCLR_SHIFT)) & I2C_INTENCLR_SCLTIMEOUTCLR_MASK) + +/*! @name TIMEOUT - Time-out value register. */ +#define I2C_TIMEOUT_TOMIN_MASK (0xFU) +#define I2C_TIMEOUT_TOMIN_SHIFT (0U) +#define I2C_TIMEOUT_TOMIN(x) (((uint32_t)(((uint32_t)(x)) << I2C_TIMEOUT_TOMIN_SHIFT)) & I2C_TIMEOUT_TOMIN_MASK) +#define I2C_TIMEOUT_TO_MASK (0xFFF0U) +#define I2C_TIMEOUT_TO_SHIFT (4U) +#define I2C_TIMEOUT_TO(x) (((uint32_t)(((uint32_t)(x)) << I2C_TIMEOUT_TO_SHIFT)) & I2C_TIMEOUT_TO_MASK) + +/*! @name CLKDIV - Clock pre-divider for the entire I2C block. This determines what time increments are used for the MSTTIME register, and controls some timing of the Slave function. */ +#define I2C_CLKDIV_DIVVAL_MASK (0xFFFFU) +#define I2C_CLKDIV_DIVVAL_SHIFT (0U) +#define I2C_CLKDIV_DIVVAL(x) (((uint32_t)(((uint32_t)(x)) << I2C_CLKDIV_DIVVAL_SHIFT)) & I2C_CLKDIV_DIVVAL_MASK) + +/*! @name INTSTAT - Interrupt Status register for Master, Slave, and Monitor functions. */ +#define I2C_INTSTAT_MSTPENDING_MASK (0x1U) +#define I2C_INTSTAT_MSTPENDING_SHIFT (0U) +#define I2C_INTSTAT_MSTPENDING(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_MSTPENDING_SHIFT)) & I2C_INTSTAT_MSTPENDING_MASK) +#define I2C_INTSTAT_MSTARBLOSS_MASK (0x10U) +#define I2C_INTSTAT_MSTARBLOSS_SHIFT (4U) +#define I2C_INTSTAT_MSTARBLOSS(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_MSTARBLOSS_SHIFT)) & I2C_INTSTAT_MSTARBLOSS_MASK) +#define I2C_INTSTAT_MSTSTSTPERR_MASK (0x40U) +#define I2C_INTSTAT_MSTSTSTPERR_SHIFT (6U) +#define I2C_INTSTAT_MSTSTSTPERR(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_MSTSTSTPERR_SHIFT)) & I2C_INTSTAT_MSTSTSTPERR_MASK) +#define I2C_INTSTAT_SLVPENDING_MASK (0x100U) +#define I2C_INTSTAT_SLVPENDING_SHIFT (8U) +#define I2C_INTSTAT_SLVPENDING(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_SLVPENDING_SHIFT)) & I2C_INTSTAT_SLVPENDING_MASK) +#define I2C_INTSTAT_SLVNOTSTR_MASK (0x800U) +#define I2C_INTSTAT_SLVNOTSTR_SHIFT (11U) +#define I2C_INTSTAT_SLVNOTSTR(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_SLVNOTSTR_SHIFT)) & I2C_INTSTAT_SLVNOTSTR_MASK) +#define I2C_INTSTAT_SLVDESEL_MASK (0x8000U) +#define I2C_INTSTAT_SLVDESEL_SHIFT (15U) +#define I2C_INTSTAT_SLVDESEL(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_SLVDESEL_SHIFT)) & I2C_INTSTAT_SLVDESEL_MASK) +#define I2C_INTSTAT_MONRDY_MASK (0x10000U) +#define I2C_INTSTAT_MONRDY_SHIFT (16U) +#define I2C_INTSTAT_MONRDY(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_MONRDY_SHIFT)) & I2C_INTSTAT_MONRDY_MASK) +#define I2C_INTSTAT_MONOV_MASK (0x20000U) +#define I2C_INTSTAT_MONOV_SHIFT (17U) +#define I2C_INTSTAT_MONOV(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_MONOV_SHIFT)) & I2C_INTSTAT_MONOV_MASK) +#define I2C_INTSTAT_MONIDLE_MASK (0x80000U) +#define I2C_INTSTAT_MONIDLE_SHIFT (19U) +#define I2C_INTSTAT_MONIDLE(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_MONIDLE_SHIFT)) & I2C_INTSTAT_MONIDLE_MASK) +#define I2C_INTSTAT_EVENTTIMEOUT_MASK (0x1000000U) +#define I2C_INTSTAT_EVENTTIMEOUT_SHIFT (24U) +#define I2C_INTSTAT_EVENTTIMEOUT(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_EVENTTIMEOUT_SHIFT)) & I2C_INTSTAT_EVENTTIMEOUT_MASK) +#define I2C_INTSTAT_SCLTIMEOUT_MASK (0x2000000U) +#define I2C_INTSTAT_SCLTIMEOUT_SHIFT (25U) +#define I2C_INTSTAT_SCLTIMEOUT(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_SCLTIMEOUT_SHIFT)) & I2C_INTSTAT_SCLTIMEOUT_MASK) + +/*! @name MSTCTL - Master control register. */ +#define I2C_MSTCTL_MSTCONTINUE_MASK (0x1U) +#define I2C_MSTCTL_MSTCONTINUE_SHIFT (0U) +#define I2C_MSTCTL_MSTCONTINUE(x) (((uint32_t)(((uint32_t)(x)) << I2C_MSTCTL_MSTCONTINUE_SHIFT)) & I2C_MSTCTL_MSTCONTINUE_MASK) +#define I2C_MSTCTL_MSTSTART_MASK (0x2U) +#define I2C_MSTCTL_MSTSTART_SHIFT (1U) +#define I2C_MSTCTL_MSTSTART(x) (((uint32_t)(((uint32_t)(x)) << I2C_MSTCTL_MSTSTART_SHIFT)) & I2C_MSTCTL_MSTSTART_MASK) +#define I2C_MSTCTL_MSTSTOP_MASK (0x4U) +#define I2C_MSTCTL_MSTSTOP_SHIFT (2U) +#define I2C_MSTCTL_MSTSTOP(x) (((uint32_t)(((uint32_t)(x)) << I2C_MSTCTL_MSTSTOP_SHIFT)) & I2C_MSTCTL_MSTSTOP_MASK) +#define I2C_MSTCTL_MSTDMA_MASK (0x8U) +#define I2C_MSTCTL_MSTDMA_SHIFT (3U) +#define I2C_MSTCTL_MSTDMA(x) (((uint32_t)(((uint32_t)(x)) << I2C_MSTCTL_MSTDMA_SHIFT)) & I2C_MSTCTL_MSTDMA_MASK) + +/*! @name MSTTIME - Master timing configuration. */ +#define I2C_MSTTIME_MSTSCLLOW_MASK (0x7U) +#define I2C_MSTTIME_MSTSCLLOW_SHIFT (0U) +#define I2C_MSTTIME_MSTSCLLOW(x) (((uint32_t)(((uint32_t)(x)) << I2C_MSTTIME_MSTSCLLOW_SHIFT)) & I2C_MSTTIME_MSTSCLLOW_MASK) +#define I2C_MSTTIME_MSTSCLHIGH_MASK (0x70U) +#define I2C_MSTTIME_MSTSCLHIGH_SHIFT (4U) +#define I2C_MSTTIME_MSTSCLHIGH(x) (((uint32_t)(((uint32_t)(x)) << I2C_MSTTIME_MSTSCLHIGH_SHIFT)) & I2C_MSTTIME_MSTSCLHIGH_MASK) + +/*! @name MSTDAT - Combined Master receiver and transmitter data register. */ +#define I2C_MSTDAT_DATA_MASK (0xFFU) +#define I2C_MSTDAT_DATA_SHIFT (0U) +#define I2C_MSTDAT_DATA(x) (((uint32_t)(((uint32_t)(x)) << I2C_MSTDAT_DATA_SHIFT)) & I2C_MSTDAT_DATA_MASK) + +/*! @name SLVCTL - Slave control register. */ +#define I2C_SLVCTL_SLVCONTINUE_MASK (0x1U) +#define I2C_SLVCTL_SLVCONTINUE_SHIFT (0U) +#define I2C_SLVCTL_SLVCONTINUE(x) (((uint32_t)(((uint32_t)(x)) << I2C_SLVCTL_SLVCONTINUE_SHIFT)) & I2C_SLVCTL_SLVCONTINUE_MASK) +#define I2C_SLVCTL_SLVNACK_MASK (0x2U) +#define I2C_SLVCTL_SLVNACK_SHIFT (1U) +#define I2C_SLVCTL_SLVNACK(x) (((uint32_t)(((uint32_t)(x)) << I2C_SLVCTL_SLVNACK_SHIFT)) & I2C_SLVCTL_SLVNACK_MASK) +#define I2C_SLVCTL_SLVDMA_MASK (0x8U) +#define I2C_SLVCTL_SLVDMA_SHIFT (3U) +#define I2C_SLVCTL_SLVDMA(x) (((uint32_t)(((uint32_t)(x)) << I2C_SLVCTL_SLVDMA_SHIFT)) & I2C_SLVCTL_SLVDMA_MASK) + +/*! @name SLVDAT - Combined Slave receiver and transmitter data register. */ +#define I2C_SLVDAT_DATA_MASK (0xFFU) +#define I2C_SLVDAT_DATA_SHIFT (0U) +#define I2C_SLVDAT_DATA(x) (((uint32_t)(((uint32_t)(x)) << I2C_SLVDAT_DATA_SHIFT)) & I2C_SLVDAT_DATA_MASK) + +/*! @name SLVADR - Slave address 0. */ +#define I2C_SLVADR_SADISABLE_MASK (0x1U) +#define I2C_SLVADR_SADISABLE_SHIFT (0U) +#define I2C_SLVADR_SADISABLE(x) (((uint32_t)(((uint32_t)(x)) << I2C_SLVADR_SADISABLE_SHIFT)) & I2C_SLVADR_SADISABLE_MASK) +#define I2C_SLVADR_SLVADR_MASK (0xFEU) +#define I2C_SLVADR_SLVADR_SHIFT (1U) +#define I2C_SLVADR_SLVADR(x) (((uint32_t)(((uint32_t)(x)) << I2C_SLVADR_SLVADR_SHIFT)) & I2C_SLVADR_SLVADR_MASK) + +/* The count of I2C_SLVADR */ +#define I2C_SLVADR_COUNT (4U) + +/*! @name SLVQUAL0 - Slave Qualification for address 0. */ +#define I2C_SLVQUAL0_QUALMODE0_MASK (0x1U) +#define I2C_SLVQUAL0_QUALMODE0_SHIFT (0U) +#define I2C_SLVQUAL0_QUALMODE0(x) (((uint32_t)(((uint32_t)(x)) << I2C_SLVQUAL0_QUALMODE0_SHIFT)) & I2C_SLVQUAL0_QUALMODE0_MASK) +#define I2C_SLVQUAL0_SLVQUAL0_MASK (0xFEU) +#define I2C_SLVQUAL0_SLVQUAL0_SHIFT (1U) +#define I2C_SLVQUAL0_SLVQUAL0(x) (((uint32_t)(((uint32_t)(x)) << I2C_SLVQUAL0_SLVQUAL0_SHIFT)) & I2C_SLVQUAL0_SLVQUAL0_MASK) + +/*! @name MONRXDAT - Monitor receiver data register. */ +#define I2C_MONRXDAT_MONRXDAT_MASK (0xFFU) +#define I2C_MONRXDAT_MONRXDAT_SHIFT (0U) +#define I2C_MONRXDAT_MONRXDAT(x) (((uint32_t)(((uint32_t)(x)) << I2C_MONRXDAT_MONRXDAT_SHIFT)) & I2C_MONRXDAT_MONRXDAT_MASK) +#define I2C_MONRXDAT_MONSTART_MASK (0x100U) +#define I2C_MONRXDAT_MONSTART_SHIFT (8U) +#define I2C_MONRXDAT_MONSTART(x) (((uint32_t)(((uint32_t)(x)) << I2C_MONRXDAT_MONSTART_SHIFT)) & I2C_MONRXDAT_MONSTART_MASK) +#define I2C_MONRXDAT_MONRESTART_MASK (0x200U) +#define I2C_MONRXDAT_MONRESTART_SHIFT (9U) +#define I2C_MONRXDAT_MONRESTART(x) (((uint32_t)(((uint32_t)(x)) << I2C_MONRXDAT_MONRESTART_SHIFT)) & I2C_MONRXDAT_MONRESTART_MASK) +#define I2C_MONRXDAT_MONNACK_MASK (0x400U) +#define I2C_MONRXDAT_MONNACK_SHIFT (10U) +#define I2C_MONRXDAT_MONNACK(x) (((uint32_t)(((uint32_t)(x)) << I2C_MONRXDAT_MONNACK_SHIFT)) & I2C_MONRXDAT_MONNACK_MASK) + + +/*! + * @} + */ /* end of group I2C_Register_Masks */ + + +/* I2C - Peripheral instance base addresses */ +/** Peripheral I2C0 base address */ +#define I2C0_BASE (0x40094000u) +/** Peripheral I2C0 base pointer */ +#define I2C0 ((I2C_Type *)I2C0_BASE) +/** Peripheral I2C1 base address */ +#define I2C1_BASE (0x40098000u) +/** Peripheral I2C1 base pointer */ +#define I2C1 ((I2C_Type *)I2C1_BASE) +/** Peripheral I2C2 base address */ +#define I2C2_BASE (0x4009C000u) +/** Peripheral I2C2 base pointer */ +#define I2C2 ((I2C_Type *)I2C2_BASE) +/** Array initializer of I2C peripheral base addresses */ +#define I2C_BASE_ADDRS { I2C0_BASE, I2C1_BASE, I2C2_BASE } +/** Array initializer of I2C peripheral base pointers */ +#define I2C_BASE_PTRS { I2C0, I2C1, I2C2 } +/** Interrupt vectors for the I2C peripheral type */ +#define I2C_IRQS { I2C0_IRQn, I2C1_IRQn, I2C2_IRQn } + +/*! + * @} + */ /* end of group I2C_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- INPUTMUX Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup INPUTMUX_Peripheral_Access_Layer INPUTMUX Peripheral Access Layer + * @{ + */ + +/** INPUTMUX - Register Layout Typedef */ +typedef struct { + uint8_t RESERVED_0[192]; + __IO uint32_t PINTSEL[8]; /**< Pin interrupt select register, array offset: 0xC0, array step: 0x4 */ + __IO uint32_t DMA_ITRIG_INMUX[22]; /**< Trigger select register for DMA channel, array offset: 0xE0, array step: 0x4 */ + uint8_t RESERVED_1[8]; + __IO uint32_t DMA_OTRIG_INMUX[4]; /**< DMA output trigger selection to become DMA trigger, array offset: 0x140, array step: 0x4 */ + uint8_t RESERVED_2[16]; + __IO uint32_t FREQMEAS_REF; /**< Selection for frequency measurement reference clock, offset: 0x160 */ + __IO uint32_t FREQMEAS_TARGET; /**< Selection for frequency measurement target clock, offset: 0x164 */ +} INPUTMUX_Type; + +/* ---------------------------------------------------------------------------- + -- INPUTMUX Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup INPUTMUX_Register_Masks INPUTMUX Register Masks + * @{ + */ + +/*! @name PINTSEL - Pin interrupt select register */ +#define INPUTMUX_PINTSEL_INTPIN_MASK (0xFFU) +#define INPUTMUX_PINTSEL_INTPIN_SHIFT (0U) +#define INPUTMUX_PINTSEL_INTPIN(x) (((uint32_t)(((uint32_t)(x)) << INPUTMUX_PINTSEL_INTPIN_SHIFT)) & INPUTMUX_PINTSEL_INTPIN_MASK) + +/* The count of INPUTMUX_PINTSEL */ +#define INPUTMUX_PINTSEL_COUNT (8U) + +/*! @name DMA_ITRIG_INMUX - Trigger select register for DMA channel */ +#define INPUTMUX_DMA_ITRIG_INMUX_INP_MASK (0x1FU) +#define INPUTMUX_DMA_ITRIG_INMUX_INP_SHIFT (0U) +#define INPUTMUX_DMA_ITRIG_INMUX_INP(x) (((uint32_t)(((uint32_t)(x)) << INPUTMUX_DMA_ITRIG_INMUX_INP_SHIFT)) & INPUTMUX_DMA_ITRIG_INMUX_INP_MASK) + +/* The count of INPUTMUX_DMA_ITRIG_INMUX */ +#define INPUTMUX_DMA_ITRIG_INMUX_COUNT (22U) + +/*! @name DMA_OTRIG_INMUX - DMA output trigger selection to become DMA trigger */ +#define INPUTMUX_DMA_OTRIG_INMUX_INP_MASK (0x1FU) +#define INPUTMUX_DMA_OTRIG_INMUX_INP_SHIFT (0U) +#define INPUTMUX_DMA_OTRIG_INMUX_INP(x) (((uint32_t)(((uint32_t)(x)) << INPUTMUX_DMA_OTRIG_INMUX_INP_SHIFT)) & INPUTMUX_DMA_OTRIG_INMUX_INP_MASK) + +/* The count of INPUTMUX_DMA_OTRIG_INMUX */ +#define INPUTMUX_DMA_OTRIG_INMUX_COUNT (4U) + +/*! @name FREQMEAS_REF - Selection for frequency measurement reference clock */ +#define INPUTMUX_FREQMEAS_REF_CLKIN_MASK (0x1FU) +#define INPUTMUX_FREQMEAS_REF_CLKIN_SHIFT (0U) +#define INPUTMUX_FREQMEAS_REF_CLKIN(x) (((uint32_t)(((uint32_t)(x)) << INPUTMUX_FREQMEAS_REF_CLKIN_SHIFT)) & INPUTMUX_FREQMEAS_REF_CLKIN_MASK) + +/*! @name FREQMEAS_TARGET - Selection for frequency measurement target clock */ +#define INPUTMUX_FREQMEAS_TARGET_CLKIN_MASK (0x1FU) +#define INPUTMUX_FREQMEAS_TARGET_CLKIN_SHIFT (0U) +#define INPUTMUX_FREQMEAS_TARGET_CLKIN(x) (((uint32_t)(((uint32_t)(x)) << INPUTMUX_FREQMEAS_TARGET_CLKIN_SHIFT)) & INPUTMUX_FREQMEAS_TARGET_CLKIN_MASK) + + +/*! + * @} + */ /* end of group INPUTMUX_Register_Masks */ + + +/* INPUTMUX - Peripheral instance base addresses */ +/** Peripheral INPUTMUX base address */ +#define INPUTMUX_BASE (0x40050000u) +/** Peripheral INPUTMUX base pointer */ +#define INPUTMUX ((INPUTMUX_Type *)INPUTMUX_BASE) +/** Array initializer of INPUTMUX peripheral base addresses */ +#define INPUTMUX_BASE_ADDRS { INPUTMUX_BASE } +/** Array initializer of INPUTMUX peripheral base pointers */ +#define INPUTMUX_BASE_PTRS { INPUTMUX } + +/*! + * @} + */ /* end of group INPUTMUX_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- IOCON Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup IOCON_Peripheral_Access_Layer IOCON Peripheral Access Layer + * @{ + */ + +/** IOCON - Register Layout Typedef */ +typedef struct { + __IO uint32_t PIO[2][32]; /**< Digital I/O control for port 0 pins PIO0_0..Digital I/O control for port 1 pins PIO1_31, array offset: 0x0, array step: index*0x80, index2*0x4 */ +} IOCON_Type; + +/* ---------------------------------------------------------------------------- + -- IOCON Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup IOCON_Register_Masks IOCON Register Masks + * @{ + */ + +/*! @name PIO - Digital I/O control for port 0 pins PIO0_0..Digital I/O control for port 1 pins PIO1_31 */ +#define IOCON_PIO_FUNC_MASK (0x7U) +#define IOCON_PIO_FUNC_SHIFT (0U) +#define IOCON_PIO_FUNC(x) (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_FUNC_SHIFT)) & IOCON_PIO_FUNC_MASK) +#define IOCON_PIO_MODE_MASK (0x18U) +#define IOCON_PIO_MODE_SHIFT (3U) +#define IOCON_PIO_MODE(x) (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_MODE_SHIFT)) & IOCON_PIO_MODE_MASK) +#define IOCON_PIO_I2CSLEW_MASK (0x20U) +#define IOCON_PIO_I2CSLEW_SHIFT (5U) +#define IOCON_PIO_I2CSLEW(x) (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_I2CSLEW_SHIFT)) & IOCON_PIO_I2CSLEW_MASK) +#define IOCON_PIO_INVERT_MASK (0x40U) +#define IOCON_PIO_INVERT_SHIFT (6U) +#define IOCON_PIO_INVERT(x) (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_INVERT_SHIFT)) & IOCON_PIO_INVERT_MASK) +#define IOCON_PIO_DIGIMODE_MASK (0x80U) +#define IOCON_PIO_DIGIMODE_SHIFT (7U) +#define IOCON_PIO_DIGIMODE(x) (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_DIGIMODE_SHIFT)) & IOCON_PIO_DIGIMODE_MASK) +#define IOCON_PIO_FILTEROFF_MASK (0x100U) +#define IOCON_PIO_FILTEROFF_SHIFT (8U) +#define IOCON_PIO_FILTEROFF(x) (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_FILTEROFF_SHIFT)) & IOCON_PIO_FILTEROFF_MASK) +#define IOCON_PIO_I2CDRIVE_MASK (0x200U) +#define IOCON_PIO_I2CDRIVE_SHIFT (9U) +#define IOCON_PIO_I2CDRIVE(x) (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_I2CDRIVE_SHIFT)) & IOCON_PIO_I2CDRIVE_MASK) +#define IOCON_PIO_SLEW_MASK (0x200U) +#define IOCON_PIO_SLEW_SHIFT (9U) +#define IOCON_PIO_SLEW(x) (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_SLEW_SHIFT)) & IOCON_PIO_SLEW_MASK) +#define IOCON_PIO_OD_MASK (0x400U) +#define IOCON_PIO_OD_SHIFT (10U) +#define IOCON_PIO_OD(x) (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_OD_SHIFT)) & IOCON_PIO_OD_MASK) +#define IOCON_PIO_I2CFILTER_MASK (0x400U) +#define IOCON_PIO_I2CFILTER_SHIFT (10U) +#define IOCON_PIO_I2CFILTER(x) (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_I2CFILTER_SHIFT)) & IOCON_PIO_I2CFILTER_MASK) + +/* The count of IOCON_PIO */ +#define IOCON_PIO_COUNT (2U) + +/* The count of IOCON_PIO */ +#define IOCON_PIO_COUNT2 (32U) + + +/*! + * @} + */ /* end of group IOCON_Register_Masks */ + + +/* IOCON - Peripheral instance base addresses */ +/** Peripheral IOCON base address */ +#define IOCON_BASE (0x4001C000u) +/** Peripheral IOCON base pointer */ +#define IOCON ((IOCON_Type *)IOCON_BASE) +/** Array initializer of IOCON peripheral base addresses */ +#define IOCON_BASE_ADDRS { IOCON_BASE } +/** Array initializer of IOCON peripheral base pointers */ +#define IOCON_BASE_PTRS { IOCON } + +/*! + * @} + */ /* end of group IOCON_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- MAILBOX Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup MAILBOX_Peripheral_Access_Layer MAILBOX Peripheral Access Layer + * @{ + */ + +/** MAILBOX - Register Layout Typedef */ +typedef struct { + struct { /* offset: 0x0, array step: 0x10 */ + __IO uint32_t IRQ; /**< Interrupt request register for the Cortex-M0+ CPU., array offset: 0x0, array step: 0x10 */ + __O uint32_t IRQSET; /**< Set bits in IRQ0, array offset: 0x4, array step: 0x10 */ + __O uint32_t IRQCLR; /**< Clear bits in IRQ0, array offset: 0x8, array step: 0x10 */ + uint8_t RESERVED_0[4]; + } MBOXIRQ[2]; + uint8_t RESERVED_0[216]; + __IO uint32_t MUTEX; /**< Mutual exclusion register[1], offset: 0xF8 */ +} MAILBOX_Type; + +/* ---------------------------------------------------------------------------- + -- MAILBOX Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup MAILBOX_Register_Masks MAILBOX Register Masks + * @{ + */ + +/*! @name MBOXIRQ_IRQ - Interrupt request register for the Cortex-M0+ CPU. */ +#define MAILBOX_MBOXIRQ_IRQ_INTREQ_MASK (0xFFFFFFFFU) +#define MAILBOX_MBOXIRQ_IRQ_INTREQ_SHIFT (0U) +#define MAILBOX_MBOXIRQ_IRQ_INTREQ(x) (((uint32_t)(((uint32_t)(x)) << MAILBOX_MBOXIRQ_IRQ_INTREQ_SHIFT)) & MAILBOX_MBOXIRQ_IRQ_INTREQ_MASK) + +/* The count of MAILBOX_MBOXIRQ_IRQ */ +#define MAILBOX_MBOXIRQ_IRQ_COUNT (2U) + +/*! @name MBOXIRQ_IRQSET - Set bits in IRQ0 */ +#define MAILBOX_MBOXIRQ_IRQSET_INTREQSET_MASK (0xFFFFFFFFU) +#define MAILBOX_MBOXIRQ_IRQSET_INTREQSET_SHIFT (0U) +#define MAILBOX_MBOXIRQ_IRQSET_INTREQSET(x) (((uint32_t)(((uint32_t)(x)) << MAILBOX_MBOXIRQ_IRQSET_INTREQSET_SHIFT)) & MAILBOX_MBOXIRQ_IRQSET_INTREQSET_MASK) + +/* The count of MAILBOX_MBOXIRQ_IRQSET */ +#define MAILBOX_MBOXIRQ_IRQSET_COUNT (2U) + +/*! @name MBOXIRQ_IRQCLR - Clear bits in IRQ0 */ +#define MAILBOX_MBOXIRQ_IRQCLR_INTREQCLR_MASK (0xFFFFFFFFU) +#define MAILBOX_MBOXIRQ_IRQCLR_INTREQCLR_SHIFT (0U) +#define MAILBOX_MBOXIRQ_IRQCLR_INTREQCLR(x) (((uint32_t)(((uint32_t)(x)) << MAILBOX_MBOXIRQ_IRQCLR_INTREQCLR_SHIFT)) & MAILBOX_MBOXIRQ_IRQCLR_INTREQCLR_MASK) + +/* The count of MAILBOX_MBOXIRQ_IRQCLR */ +#define MAILBOX_MBOXIRQ_IRQCLR_COUNT (2U) + +/*! @name MUTEX - Mutual exclusion register[1] */ +#define MAILBOX_MUTEX_EX_MASK (0x1U) +#define MAILBOX_MUTEX_EX_SHIFT (0U) +#define MAILBOX_MUTEX_EX(x) (((uint32_t)(((uint32_t)(x)) << MAILBOX_MUTEX_EX_SHIFT)) & MAILBOX_MUTEX_EX_MASK) + + +/*! + * @} + */ /* end of group MAILBOX_Register_Masks */ + + +/* MAILBOX - Peripheral instance base addresses */ +/** Peripheral MAILBOX base address */ +#define MAILBOX_BASE (0x1C02C000u) +/** Peripheral MAILBOX base pointer */ +#define MAILBOX ((MAILBOX_Type *)MAILBOX_BASE) +/** Array initializer of MAILBOX peripheral base addresses */ +#define MAILBOX_BASE_ADDRS { MAILBOX_BASE } +/** Array initializer of MAILBOX peripheral base pointers */ +#define MAILBOX_BASE_PTRS { MAILBOX } +/** Interrupt vectors for the MAILBOX peripheral type */ +#define MAILBOX_IRQS { MAILBOX_IRQn } + +/*! + * @} + */ /* end of group MAILBOX_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- MRT Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup MRT_Peripheral_Access_Layer MRT Peripheral Access Layer + * @{ + */ + +/** MRT - Register Layout Typedef */ +typedef struct { + struct { /* offset: 0x0, array step: 0x10 */ + __IO uint32_t INTVAL; /**< MRT Time interval value register. This value is loaded into the TIMER register., array offset: 0x0, array step: 0x10 */ + __I uint32_t TIMER; /**< MRT Timer register. This register reads the value of the down-counter., array offset: 0x4, array step: 0x10 */ + __IO uint32_t CTRL; /**< MRT Control register. This register controls the MRT modes., array offset: 0x8, array step: 0x10 */ + __IO uint32_t STAT; /**< MRT Status register., array offset: 0xC, array step: 0x10 */ + } CHANNEL[4]; + uint8_t RESERVED_0[176]; + __IO uint32_t MODCFG; /**< Module Configuration register. This register provides information about this particular MRT instance, and allows choosing an overall mode for the idle channel feature., offset: 0xF0 */ + __I uint32_t IDLE_CH; /**< Idle channel register. This register returns the number of the first idle channel., offset: 0xF4 */ + __IO uint32_t IRQ_FLAG; /**< Global interrupt flag register, offset: 0xF8 */ +} MRT_Type; + +/* ---------------------------------------------------------------------------- + -- MRT Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup MRT_Register_Masks MRT Register Masks + * @{ + */ + +/*! @name CHANNEL_INTVAL - MRT Time interval value register. This value is loaded into the TIMER register. */ +#define MRT_CHANNEL_INTVAL_IVALUE_MASK (0xFFFFFFU) +#define MRT_CHANNEL_INTVAL_IVALUE_SHIFT (0U) +#define MRT_CHANNEL_INTVAL_IVALUE(x) (((uint32_t)(((uint32_t)(x)) << MRT_CHANNEL_INTVAL_IVALUE_SHIFT)) & MRT_CHANNEL_INTVAL_IVALUE_MASK) +#define MRT_CHANNEL_INTVAL_LOAD_MASK (0x80000000U) +#define MRT_CHANNEL_INTVAL_LOAD_SHIFT (31U) +#define MRT_CHANNEL_INTVAL_LOAD(x) (((uint32_t)(((uint32_t)(x)) << MRT_CHANNEL_INTVAL_LOAD_SHIFT)) & MRT_CHANNEL_INTVAL_LOAD_MASK) + +/* The count of MRT_CHANNEL_INTVAL */ +#define MRT_CHANNEL_INTVAL_COUNT (4U) + +/*! @name CHANNEL_TIMER - MRT Timer register. This register reads the value of the down-counter. */ +#define MRT_CHANNEL_TIMER_VALUE_MASK (0xFFFFFFU) +#define MRT_CHANNEL_TIMER_VALUE_SHIFT (0U) +#define MRT_CHANNEL_TIMER_VALUE(x) (((uint32_t)(((uint32_t)(x)) << MRT_CHANNEL_TIMER_VALUE_SHIFT)) & MRT_CHANNEL_TIMER_VALUE_MASK) + +/* The count of MRT_CHANNEL_TIMER */ +#define MRT_CHANNEL_TIMER_COUNT (4U) + +/*! @name CHANNEL_CTRL - MRT Control register. This register controls the MRT modes. */ +#define MRT_CHANNEL_CTRL_INTEN_MASK (0x1U) +#define MRT_CHANNEL_CTRL_INTEN_SHIFT (0U) +#define MRT_CHANNEL_CTRL_INTEN(x) (((uint32_t)(((uint32_t)(x)) << MRT_CHANNEL_CTRL_INTEN_SHIFT)) & MRT_CHANNEL_CTRL_INTEN_MASK) +#define MRT_CHANNEL_CTRL_MODE_MASK (0x6U) +#define MRT_CHANNEL_CTRL_MODE_SHIFT (1U) +#define MRT_CHANNEL_CTRL_MODE(x) (((uint32_t)(((uint32_t)(x)) << MRT_CHANNEL_CTRL_MODE_SHIFT)) & MRT_CHANNEL_CTRL_MODE_MASK) + +/* The count of MRT_CHANNEL_CTRL */ +#define MRT_CHANNEL_CTRL_COUNT (4U) + +/*! @name CHANNEL_STAT - MRT Status register. */ +#define MRT_CHANNEL_STAT_INTFLAG_MASK (0x1U) +#define MRT_CHANNEL_STAT_INTFLAG_SHIFT (0U) +#define MRT_CHANNEL_STAT_INTFLAG(x) (((uint32_t)(((uint32_t)(x)) << MRT_CHANNEL_STAT_INTFLAG_SHIFT)) & MRT_CHANNEL_STAT_INTFLAG_MASK) +#define MRT_CHANNEL_STAT_RUN_MASK (0x2U) +#define MRT_CHANNEL_STAT_RUN_SHIFT (1U) +#define MRT_CHANNEL_STAT_RUN(x) (((uint32_t)(((uint32_t)(x)) << MRT_CHANNEL_STAT_RUN_SHIFT)) & MRT_CHANNEL_STAT_RUN_MASK) +#define MRT_CHANNEL_STAT_INUSE_MASK (0x4U) +#define MRT_CHANNEL_STAT_INUSE_SHIFT (2U) +#define MRT_CHANNEL_STAT_INUSE(x) (((uint32_t)(((uint32_t)(x)) << MRT_CHANNEL_STAT_INUSE_SHIFT)) & MRT_CHANNEL_STAT_INUSE_MASK) + +/* The count of MRT_CHANNEL_STAT */ +#define MRT_CHANNEL_STAT_COUNT (4U) + +/*! @name MODCFG - Module Configuration register. This register provides information about this particular MRT instance, and allows choosing an overall mode for the idle channel feature. */ +#define MRT_MODCFG_NOC_MASK (0xFU) +#define MRT_MODCFG_NOC_SHIFT (0U) +#define MRT_MODCFG_NOC(x) (((uint32_t)(((uint32_t)(x)) << MRT_MODCFG_NOC_SHIFT)) & MRT_MODCFG_NOC_MASK) +#define MRT_MODCFG_NOB_MASK (0x1F0U) +#define MRT_MODCFG_NOB_SHIFT (4U) +#define MRT_MODCFG_NOB(x) (((uint32_t)(((uint32_t)(x)) << MRT_MODCFG_NOB_SHIFT)) & MRT_MODCFG_NOB_MASK) +#define MRT_MODCFG_MULTITASK_MASK (0x80000000U) +#define MRT_MODCFG_MULTITASK_SHIFT (31U) +#define MRT_MODCFG_MULTITASK(x) (((uint32_t)(((uint32_t)(x)) << MRT_MODCFG_MULTITASK_SHIFT)) & MRT_MODCFG_MULTITASK_MASK) + +/*! @name IDLE_CH - Idle channel register. This register returns the number of the first idle channel. */ +#define MRT_IDLE_CH_CHAN_MASK (0xF0U) +#define MRT_IDLE_CH_CHAN_SHIFT (4U) +#define MRT_IDLE_CH_CHAN(x) (((uint32_t)(((uint32_t)(x)) << MRT_IDLE_CH_CHAN_SHIFT)) & MRT_IDLE_CH_CHAN_MASK) + +/*! @name IRQ_FLAG - Global interrupt flag register */ +#define MRT_IRQ_FLAG_GFLAG0_MASK (0x1U) +#define MRT_IRQ_FLAG_GFLAG0_SHIFT (0U) +#define MRT_IRQ_FLAG_GFLAG0(x) (((uint32_t)(((uint32_t)(x)) << MRT_IRQ_FLAG_GFLAG0_SHIFT)) & MRT_IRQ_FLAG_GFLAG0_MASK) +#define MRT_IRQ_FLAG_GFLAG1_MASK (0x2U) +#define MRT_IRQ_FLAG_GFLAG1_SHIFT (1U) +#define MRT_IRQ_FLAG_GFLAG1(x) (((uint32_t)(((uint32_t)(x)) << MRT_IRQ_FLAG_GFLAG1_SHIFT)) & MRT_IRQ_FLAG_GFLAG1_MASK) +#define MRT_IRQ_FLAG_GFLAG2_MASK (0x4U) +#define MRT_IRQ_FLAG_GFLAG2_SHIFT (2U) +#define MRT_IRQ_FLAG_GFLAG2(x) (((uint32_t)(((uint32_t)(x)) << MRT_IRQ_FLAG_GFLAG2_SHIFT)) & MRT_IRQ_FLAG_GFLAG2_MASK) +#define MRT_IRQ_FLAG_GFLAG3_MASK (0x8U) +#define MRT_IRQ_FLAG_GFLAG3_SHIFT (3U) +#define MRT_IRQ_FLAG_GFLAG3(x) (((uint32_t)(((uint32_t)(x)) << MRT_IRQ_FLAG_GFLAG3_SHIFT)) & MRT_IRQ_FLAG_GFLAG3_MASK) + + +/*! + * @} + */ /* end of group MRT_Register_Masks */ + + +/* MRT - Peripheral instance base addresses */ +/** Peripheral MRT0 base address */ +#define MRT0_BASE (0x40074000u) +/** Peripheral MRT0 base pointer */ +#define MRT0 ((MRT_Type *)MRT0_BASE) +/** Array initializer of MRT peripheral base addresses */ +#define MRT_BASE_ADDRS { MRT0_BASE } +/** Array initializer of MRT peripheral base pointers */ +#define MRT_BASE_PTRS { MRT0 } +/** Interrupt vectors for the MRT peripheral type */ +#define MRT_IRQS { MRT0_IRQn } + +/*! + * @} + */ /* end of group MRT_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- PINT Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup PINT_Peripheral_Access_Layer PINT Peripheral Access Layer + * @{ + */ + +/** PINT - Register Layout Typedef */ +typedef struct { + __IO uint32_t ISEL; /**< Pin Interrupt Mode register, offset: 0x0 */ + __IO uint32_t IENR; /**< Pin interrupt level or rising edge interrupt enable register, offset: 0x4 */ + __O uint32_t SIENR; /**< Pin interrupt level or rising edge interrupt set register, offset: 0x8 */ + __O uint32_t CIENR; /**< Pin interrupt level (rising edge interrupt) clear register, offset: 0xC */ + __IO uint32_t IENF; /**< Pin interrupt active level or falling edge interrupt enable register, offset: 0x10 */ + __O uint32_t SIENF; /**< Pin interrupt active level or falling edge interrupt set register, offset: 0x14 */ + __O uint32_t CIENF; /**< Pin interrupt active level or falling edge interrupt clear register, offset: 0x18 */ + __IO uint32_t RISE; /**< Pin interrupt rising edge register, offset: 0x1C */ + __IO uint32_t FALL; /**< Pin interrupt falling edge register, offset: 0x20 */ + __IO uint32_t IST; /**< Pin interrupt status register, offset: 0x24 */ + __IO uint32_t PMCTRL; /**< Pattern match interrupt control register, offset: 0x28 */ + __IO uint32_t PMSRC; /**< Pattern match interrupt bit-slice source register, offset: 0x2C */ + __IO uint32_t PMCFG; /**< Pattern match interrupt bit slice configuration register, offset: 0x30 */ +} PINT_Type; + +/* ---------------------------------------------------------------------------- + -- PINT Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup PINT_Register_Masks PINT Register Masks + * @{ + */ + +/*! @name ISEL - Pin Interrupt Mode register */ +#define PINT_ISEL_PMODE_MASK (0xFFU) +#define PINT_ISEL_PMODE_SHIFT (0U) +#define PINT_ISEL_PMODE(x) (((uint32_t)(((uint32_t)(x)) << PINT_ISEL_PMODE_SHIFT)) & PINT_ISEL_PMODE_MASK) + +/*! @name IENR - Pin interrupt level or rising edge interrupt enable register */ +#define PINT_IENR_ENRL_MASK (0xFFU) +#define PINT_IENR_ENRL_SHIFT (0U) +#define PINT_IENR_ENRL(x) (((uint32_t)(((uint32_t)(x)) << PINT_IENR_ENRL_SHIFT)) & PINT_IENR_ENRL_MASK) + +/*! @name SIENR - Pin interrupt level or rising edge interrupt set register */ +#define PINT_SIENR_SETENRL_MASK (0xFFU) +#define PINT_SIENR_SETENRL_SHIFT (0U) +#define PINT_SIENR_SETENRL(x) (((uint32_t)(((uint32_t)(x)) << PINT_SIENR_SETENRL_SHIFT)) & PINT_SIENR_SETENRL_MASK) + +/*! @name CIENR - Pin interrupt level (rising edge interrupt) clear register */ +#define PINT_CIENR_CENRL_MASK (0xFFU) +#define PINT_CIENR_CENRL_SHIFT (0U) +#define PINT_CIENR_CENRL(x) (((uint32_t)(((uint32_t)(x)) << PINT_CIENR_CENRL_SHIFT)) & PINT_CIENR_CENRL_MASK) + +/*! @name IENF - Pin interrupt active level or falling edge interrupt enable register */ +#define PINT_IENF_ENAF_MASK (0xFFU) +#define PINT_IENF_ENAF_SHIFT (0U) +#define PINT_IENF_ENAF(x) (((uint32_t)(((uint32_t)(x)) << PINT_IENF_ENAF_SHIFT)) & PINT_IENF_ENAF_MASK) + +/*! @name SIENF - Pin interrupt active level or falling edge interrupt set register */ +#define PINT_SIENF_SETENAF_MASK (0xFFU) +#define PINT_SIENF_SETENAF_SHIFT (0U) +#define PINT_SIENF_SETENAF(x) (((uint32_t)(((uint32_t)(x)) << PINT_SIENF_SETENAF_SHIFT)) & PINT_SIENF_SETENAF_MASK) + +/*! @name CIENF - Pin interrupt active level or falling edge interrupt clear register */ +#define PINT_CIENF_CENAF_MASK (0xFFU) +#define PINT_CIENF_CENAF_SHIFT (0U) +#define PINT_CIENF_CENAF(x) (((uint32_t)(((uint32_t)(x)) << PINT_CIENF_CENAF_SHIFT)) & PINT_CIENF_CENAF_MASK) + +/*! @name RISE - Pin interrupt rising edge register */ +#define PINT_RISE_RDET_MASK (0xFFU) +#define PINT_RISE_RDET_SHIFT (0U) +#define PINT_RISE_RDET(x) (((uint32_t)(((uint32_t)(x)) << PINT_RISE_RDET_SHIFT)) & PINT_RISE_RDET_MASK) + +/*! @name FALL - Pin interrupt falling edge register */ +#define PINT_FALL_FDET_MASK (0xFFU) +#define PINT_FALL_FDET_SHIFT (0U) +#define PINT_FALL_FDET(x) (((uint32_t)(((uint32_t)(x)) << PINT_FALL_FDET_SHIFT)) & PINT_FALL_FDET_MASK) + +/*! @name IST - Pin interrupt status register */ +#define PINT_IST_PSTAT_MASK (0xFFU) +#define PINT_IST_PSTAT_SHIFT (0U) +#define PINT_IST_PSTAT(x) (((uint32_t)(((uint32_t)(x)) << PINT_IST_PSTAT_SHIFT)) & PINT_IST_PSTAT_MASK) + +/*! @name PMCTRL - Pattern match interrupt control register */ +#define PINT_PMCTRL_SEL_PMATCH_MASK (0x1U) +#define PINT_PMCTRL_SEL_PMATCH_SHIFT (0U) +#define PINT_PMCTRL_SEL_PMATCH(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCTRL_SEL_PMATCH_SHIFT)) & PINT_PMCTRL_SEL_PMATCH_MASK) +#define PINT_PMCTRL_ENA_RXEV_MASK (0x2U) +#define PINT_PMCTRL_ENA_RXEV_SHIFT (1U) +#define PINT_PMCTRL_ENA_RXEV(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCTRL_ENA_RXEV_SHIFT)) & PINT_PMCTRL_ENA_RXEV_MASK) +#define PINT_PMCTRL_PMAT_MASK (0xFF000000U) +#define PINT_PMCTRL_PMAT_SHIFT (24U) +#define PINT_PMCTRL_PMAT(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCTRL_PMAT_SHIFT)) & PINT_PMCTRL_PMAT_MASK) + +/*! @name PMSRC - Pattern match interrupt bit-slice source register */ +#define PINT_PMSRC_SRC0_MASK (0x700U) +#define PINT_PMSRC_SRC0_SHIFT (8U) +#define PINT_PMSRC_SRC0(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMSRC_SRC0_SHIFT)) & PINT_PMSRC_SRC0_MASK) +#define PINT_PMSRC_SRC1_MASK (0x3800U) +#define PINT_PMSRC_SRC1_SHIFT (11U) +#define PINT_PMSRC_SRC1(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMSRC_SRC1_SHIFT)) & PINT_PMSRC_SRC1_MASK) +#define PINT_PMSRC_SRC2_MASK (0x1C000U) +#define PINT_PMSRC_SRC2_SHIFT (14U) +#define PINT_PMSRC_SRC2(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMSRC_SRC2_SHIFT)) & PINT_PMSRC_SRC2_MASK) +#define PINT_PMSRC_SRC3_MASK (0xE0000U) +#define PINT_PMSRC_SRC3_SHIFT (17U) +#define PINT_PMSRC_SRC3(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMSRC_SRC3_SHIFT)) & PINT_PMSRC_SRC3_MASK) +#define PINT_PMSRC_SRC4_MASK (0x700000U) +#define PINT_PMSRC_SRC4_SHIFT (20U) +#define PINT_PMSRC_SRC4(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMSRC_SRC4_SHIFT)) & PINT_PMSRC_SRC4_MASK) +#define PINT_PMSRC_SRC5_MASK (0x3800000U) +#define PINT_PMSRC_SRC5_SHIFT (23U) +#define PINT_PMSRC_SRC5(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMSRC_SRC5_SHIFT)) & PINT_PMSRC_SRC5_MASK) +#define PINT_PMSRC_SRC6_MASK (0x1C000000U) +#define PINT_PMSRC_SRC6_SHIFT (26U) +#define PINT_PMSRC_SRC6(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMSRC_SRC6_SHIFT)) & PINT_PMSRC_SRC6_MASK) +#define PINT_PMSRC_SRC7_MASK (0xE0000000U) +#define PINT_PMSRC_SRC7_SHIFT (29U) +#define PINT_PMSRC_SRC7(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMSRC_SRC7_SHIFT)) & PINT_PMSRC_SRC7_MASK) + +/*! @name PMCFG - Pattern match interrupt bit slice configuration register */ +#define PINT_PMCFG_PROD_ENDPTS0_MASK (0x1U) +#define PINT_PMCFG_PROD_ENDPTS0_SHIFT (0U) +#define PINT_PMCFG_PROD_ENDPTS0(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_PROD_ENDPTS0_SHIFT)) & PINT_PMCFG_PROD_ENDPTS0_MASK) +#define PINT_PMCFG_PROD_ENDPTS1_MASK (0x2U) +#define PINT_PMCFG_PROD_ENDPTS1_SHIFT (1U) +#define PINT_PMCFG_PROD_ENDPTS1(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_PROD_ENDPTS1_SHIFT)) & PINT_PMCFG_PROD_ENDPTS1_MASK) +#define PINT_PMCFG_PROD_ENDPTS2_MASK (0x4U) +#define PINT_PMCFG_PROD_ENDPTS2_SHIFT (2U) +#define PINT_PMCFG_PROD_ENDPTS2(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_PROD_ENDPTS2_SHIFT)) & PINT_PMCFG_PROD_ENDPTS2_MASK) +#define PINT_PMCFG_PROD_ENDPTS3_MASK (0x8U) +#define PINT_PMCFG_PROD_ENDPTS3_SHIFT (3U) +#define PINT_PMCFG_PROD_ENDPTS3(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_PROD_ENDPTS3_SHIFT)) & PINT_PMCFG_PROD_ENDPTS3_MASK) +#define PINT_PMCFG_PROD_ENDPTS4_MASK (0x10U) +#define PINT_PMCFG_PROD_ENDPTS4_SHIFT (4U) +#define PINT_PMCFG_PROD_ENDPTS4(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_PROD_ENDPTS4_SHIFT)) & PINT_PMCFG_PROD_ENDPTS4_MASK) +#define PINT_PMCFG_PROD_ENDPTS5_MASK (0x20U) +#define PINT_PMCFG_PROD_ENDPTS5_SHIFT (5U) +#define PINT_PMCFG_PROD_ENDPTS5(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_PROD_ENDPTS5_SHIFT)) & PINT_PMCFG_PROD_ENDPTS5_MASK) +#define PINT_PMCFG_PROD_ENDPTS6_MASK (0x40U) +#define PINT_PMCFG_PROD_ENDPTS6_SHIFT (6U) +#define PINT_PMCFG_PROD_ENDPTS6(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_PROD_ENDPTS6_SHIFT)) & PINT_PMCFG_PROD_ENDPTS6_MASK) +#define PINT_PMCFG_CFG0_MASK (0x700U) +#define PINT_PMCFG_CFG0_SHIFT (8U) +#define PINT_PMCFG_CFG0(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_CFG0_SHIFT)) & PINT_PMCFG_CFG0_MASK) +#define PINT_PMCFG_CFG1_MASK (0x3800U) +#define PINT_PMCFG_CFG1_SHIFT (11U) +#define PINT_PMCFG_CFG1(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_CFG1_SHIFT)) & PINT_PMCFG_CFG1_MASK) +#define PINT_PMCFG_CFG2_MASK (0x1C000U) +#define PINT_PMCFG_CFG2_SHIFT (14U) +#define PINT_PMCFG_CFG2(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_CFG2_SHIFT)) & PINT_PMCFG_CFG2_MASK) +#define PINT_PMCFG_CFG3_MASK (0xE0000U) +#define PINT_PMCFG_CFG3_SHIFT (17U) +#define PINT_PMCFG_CFG3(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_CFG3_SHIFT)) & PINT_PMCFG_CFG3_MASK) +#define PINT_PMCFG_CFG4_MASK (0x700000U) +#define PINT_PMCFG_CFG4_SHIFT (20U) +#define PINT_PMCFG_CFG4(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_CFG4_SHIFT)) & PINT_PMCFG_CFG4_MASK) +#define PINT_PMCFG_CFG5_MASK (0x3800000U) +#define PINT_PMCFG_CFG5_SHIFT (23U) +#define PINT_PMCFG_CFG5(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_CFG5_SHIFT)) & PINT_PMCFG_CFG5_MASK) +#define PINT_PMCFG_CFG6_MASK (0x1C000000U) +#define PINT_PMCFG_CFG6_SHIFT (26U) +#define PINT_PMCFG_CFG6(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_CFG6_SHIFT)) & PINT_PMCFG_CFG6_MASK) +#define PINT_PMCFG_CFG7_MASK (0xE0000000U) +#define PINT_PMCFG_CFG7_SHIFT (29U) +#define PINT_PMCFG_CFG7(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_CFG7_SHIFT)) & PINT_PMCFG_CFG7_MASK) + + +/*! + * @} + */ /* end of group PINT_Register_Masks */ + + +/* PINT - Peripheral instance base addresses */ +/** Peripheral PINT base address */ +#define PINT_BASE (0x40018000u) +/** Peripheral PINT base pointer */ +#define PINT ((PINT_Type *)PINT_BASE) +/** Array initializer of PINT peripheral base addresses */ +#define PINT_BASE_ADDRS { PINT_BASE } +/** Array initializer of PINT peripheral base pointers */ +#define PINT_BASE_PTRS { PINT } +/** Interrupt vectors for the PINT peripheral type */ +#define PINT_IRQS { PIN_INT0_IRQn, PIN_INT1_IRQn, PIN_INT2_IRQn, PIN_INT3_IRQn } + +/*! + * @} + */ /* end of group PINT_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- RIT Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup RIT_Peripheral_Access_Layer RIT Peripheral Access Layer + * @{ + */ + +/** RIT - Register Layout Typedef */ +typedef struct { + __IO uint32_t COMPVAL; /**< Compare value LSB register. Holds the 32 LSBs of the compare value., offset: 0x0 */ + __IO uint32_t MASK; /**< Mask LSB register. This register holds the 32 LSB s of the mask value. A 1 written to any bit will force the compare to be true for the corresponding bit of the counter and compare register., offset: 0x4 */ + __IO uint32_t CTRL; /**< Control register., offset: 0x8 */ + __IO uint32_t COUNTER; /**< Counter LSB register. 32 LSBs of the counter., offset: 0xC */ + __IO uint32_t COMPVAL_H; /**< Compare value MSB register. Holds the 16 MSBs of the compare value., offset: 0x10 */ + __IO uint32_t MASK_H; /**< Mask MSB register. This register holds the 16 MSBs of the mask value. A 1 written to any bit will force a compare on the corresponding bit of the counter and compare register., offset: 0x14 */ + uint8_t RESERVED_0[4]; + __IO uint32_t COUNTER_H; /**< Counter MSB register. 16 MSBs of the counter., offset: 0x1C */ +} RIT_Type; + +/* ---------------------------------------------------------------------------- + -- RIT Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup RIT_Register_Masks RIT Register Masks + * @{ + */ + +/*! @name COMPVAL - Compare value LSB register. Holds the 32 LSBs of the compare value. */ +#define RIT_COMPVAL_RICOMP_MASK (0xFFFFFFFFU) +#define RIT_COMPVAL_RICOMP_SHIFT (0U) +#define RIT_COMPVAL_RICOMP(x) (((uint32_t)(((uint32_t)(x)) << RIT_COMPVAL_RICOMP_SHIFT)) & RIT_COMPVAL_RICOMP_MASK) + +/*! @name MASK - Mask LSB register. This register holds the 32 LSB s of the mask value. A 1 written to any bit will force the compare to be true for the corresponding bit of the counter and compare register. */ +#define RIT_MASK_RIMASK_MASK (0xFFFFFFFFU) +#define RIT_MASK_RIMASK_SHIFT (0U) +#define RIT_MASK_RIMASK(x) (((uint32_t)(((uint32_t)(x)) << RIT_MASK_RIMASK_SHIFT)) & RIT_MASK_RIMASK_MASK) + +/*! @name CTRL - Control register. */ +#define RIT_CTRL_RITINT_MASK (0x1U) +#define RIT_CTRL_RITINT_SHIFT (0U) +#define RIT_CTRL_RITINT(x) (((uint32_t)(((uint32_t)(x)) << RIT_CTRL_RITINT_SHIFT)) & RIT_CTRL_RITINT_MASK) +#define RIT_CTRL_RITENCLR_MASK (0x2U) +#define RIT_CTRL_RITENCLR_SHIFT (1U) +#define RIT_CTRL_RITENCLR(x) (((uint32_t)(((uint32_t)(x)) << RIT_CTRL_RITENCLR_SHIFT)) & RIT_CTRL_RITENCLR_MASK) +#define RIT_CTRL_RITENBR_MASK (0x4U) +#define RIT_CTRL_RITENBR_SHIFT (2U) +#define RIT_CTRL_RITENBR(x) (((uint32_t)(((uint32_t)(x)) << RIT_CTRL_RITENBR_SHIFT)) & RIT_CTRL_RITENBR_MASK) +#define RIT_CTRL_RITEN_MASK (0x8U) +#define RIT_CTRL_RITEN_SHIFT (3U) +#define RIT_CTRL_RITEN(x) (((uint32_t)(((uint32_t)(x)) << RIT_CTRL_RITEN_SHIFT)) & RIT_CTRL_RITEN_MASK) + +/*! @name COUNTER - Counter LSB register. 32 LSBs of the counter. */ +#define RIT_COUNTER_RICOUNTER_MASK (0xFFFFFFFFU) +#define RIT_COUNTER_RICOUNTER_SHIFT (0U) +#define RIT_COUNTER_RICOUNTER(x) (((uint32_t)(((uint32_t)(x)) << RIT_COUNTER_RICOUNTER_SHIFT)) & RIT_COUNTER_RICOUNTER_MASK) + +/*! @name COMPVAL_H - Compare value MSB register. Holds the 16 MSBs of the compare value. */ +#define RIT_COMPVAL_H_RICOMP_MASK (0xFFFFU) +#define RIT_COMPVAL_H_RICOMP_SHIFT (0U) +#define RIT_COMPVAL_H_RICOMP(x) (((uint32_t)(((uint32_t)(x)) << RIT_COMPVAL_H_RICOMP_SHIFT)) & RIT_COMPVAL_H_RICOMP_MASK) + +/*! @name MASK_H - Mask MSB register. This register holds the 16 MSBs of the mask value. A 1 written to any bit will force a compare on the corresponding bit of the counter and compare register. */ +#define RIT_MASK_H_RIMASK_MASK (0xFFFFU) +#define RIT_MASK_H_RIMASK_SHIFT (0U) +#define RIT_MASK_H_RIMASK(x) (((uint32_t)(((uint32_t)(x)) << RIT_MASK_H_RIMASK_SHIFT)) & RIT_MASK_H_RIMASK_MASK) + +/*! @name COUNTER_H - Counter MSB register. 16 MSBs of the counter. */ +#define RIT_COUNTER_H_RICOUNTER_MASK (0xFFFFU) +#define RIT_COUNTER_H_RICOUNTER_SHIFT (0U) +#define RIT_COUNTER_H_RICOUNTER(x) (((uint32_t)(((uint32_t)(x)) << RIT_COUNTER_H_RICOUNTER_SHIFT)) & RIT_COUNTER_H_RICOUNTER_MASK) + + +/*! + * @} + */ /* end of group RIT_Register_Masks */ + + +/* RIT - Peripheral instance base addresses */ +/** Peripheral RIT base address */ +#define RIT_BASE (0x40070000u) +/** Peripheral RIT base pointer */ +#define RIT ((RIT_Type *)RIT_BASE) +/** Array initializer of RIT peripheral base addresses */ +#define RIT_BASE_ADDRS { RIT_BASE } +/** Array initializer of RIT peripheral base pointers */ +#define RIT_BASE_PTRS { RIT } + +/*! + * @} + */ /* end of group RIT_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- RTC Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup RTC_Peripheral_Access_Layer RTC Peripheral Access Layer + * @{ + */ + +/** RTC - Register Layout Typedef */ +typedef struct { + __IO uint32_t CTRL; /**< RTC control register, offset: 0x0 */ + __IO uint32_t MATCH; /**< RTC match register, offset: 0x4 */ + __IO uint32_t COUNT; /**< RTC counter register, offset: 0x8 */ + __IO uint32_t WAKE; /**< High-resolution/wake-up timer control register, offset: 0xC */ +} RTC_Type; + +/* ---------------------------------------------------------------------------- + -- RTC Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup RTC_Register_Masks RTC Register Masks + * @{ + */ + +/*! @name CTRL - RTC control register */ +#define RTC_CTRL_SWRESET_MASK (0x1U) +#define RTC_CTRL_SWRESET_SHIFT (0U) +#define RTC_CTRL_SWRESET(x) (((uint32_t)(((uint32_t)(x)) << RTC_CTRL_SWRESET_SHIFT)) & RTC_CTRL_SWRESET_MASK) +#define RTC_CTRL_OFD_MASK (0x2U) +#define RTC_CTRL_OFD_SHIFT (1U) +#define RTC_CTRL_OFD(x) (((uint32_t)(((uint32_t)(x)) << RTC_CTRL_OFD_SHIFT)) & RTC_CTRL_OFD_MASK) +#define RTC_CTRL_ALARM1HZ_MASK (0x4U) +#define RTC_CTRL_ALARM1HZ_SHIFT (2U) +#define RTC_CTRL_ALARM1HZ(x) (((uint32_t)(((uint32_t)(x)) << RTC_CTRL_ALARM1HZ_SHIFT)) & RTC_CTRL_ALARM1HZ_MASK) +#define RTC_CTRL_WAKE1KHZ_MASK (0x8U) +#define RTC_CTRL_WAKE1KHZ_SHIFT (3U) +#define RTC_CTRL_WAKE1KHZ(x) (((uint32_t)(((uint32_t)(x)) << RTC_CTRL_WAKE1KHZ_SHIFT)) & RTC_CTRL_WAKE1KHZ_MASK) +#define RTC_CTRL_ALARMDPD_EN_MASK (0x10U) +#define RTC_CTRL_ALARMDPD_EN_SHIFT (4U) +#define RTC_CTRL_ALARMDPD_EN(x) (((uint32_t)(((uint32_t)(x)) << RTC_CTRL_ALARMDPD_EN_SHIFT)) & RTC_CTRL_ALARMDPD_EN_MASK) +#define RTC_CTRL_WAKEDPD_EN_MASK (0x20U) +#define RTC_CTRL_WAKEDPD_EN_SHIFT (5U) +#define RTC_CTRL_WAKEDPD_EN(x) (((uint32_t)(((uint32_t)(x)) << RTC_CTRL_WAKEDPD_EN_SHIFT)) & RTC_CTRL_WAKEDPD_EN_MASK) +#define RTC_CTRL_RTC1KHZ_EN_MASK (0x40U) +#define RTC_CTRL_RTC1KHZ_EN_SHIFT (6U) +#define RTC_CTRL_RTC1KHZ_EN(x) (((uint32_t)(((uint32_t)(x)) << RTC_CTRL_RTC1KHZ_EN_SHIFT)) & RTC_CTRL_RTC1KHZ_EN_MASK) +#define RTC_CTRL_RTC_EN_MASK (0x80U) +#define RTC_CTRL_RTC_EN_SHIFT (7U) +#define RTC_CTRL_RTC_EN(x) (((uint32_t)(((uint32_t)(x)) << RTC_CTRL_RTC_EN_SHIFT)) & RTC_CTRL_RTC_EN_MASK) + +/*! @name MATCH - RTC match register */ +#define RTC_MATCH_MATVAL_MASK (0xFFFFFFFFU) +#define RTC_MATCH_MATVAL_SHIFT (0U) +#define RTC_MATCH_MATVAL(x) (((uint32_t)(((uint32_t)(x)) << RTC_MATCH_MATVAL_SHIFT)) & RTC_MATCH_MATVAL_MASK) + +/*! @name COUNT - RTC counter register */ +#define RTC_COUNT_VAL_MASK (0xFFFFFFFFU) +#define RTC_COUNT_VAL_SHIFT (0U) +#define RTC_COUNT_VAL(x) (((uint32_t)(((uint32_t)(x)) << RTC_COUNT_VAL_SHIFT)) & RTC_COUNT_VAL_MASK) + +/*! @name WAKE - High-resolution/wake-up timer control register */ +#define RTC_WAKE_VAL_MASK (0xFFFFU) +#define RTC_WAKE_VAL_SHIFT (0U) +#define RTC_WAKE_VAL(x) (((uint32_t)(((uint32_t)(x)) << RTC_WAKE_VAL_SHIFT)) & RTC_WAKE_VAL_MASK) + + +/*! + * @} + */ /* end of group RTC_Register_Masks */ + + +/* RTC - Peripheral instance base addresses */ +/** Peripheral RTC base address */ +#define RTC_BASE (0x4003C000u) +/** Peripheral RTC base pointer */ +#define RTC ((RTC_Type *)RTC_BASE) +/** Array initializer of RTC peripheral base addresses */ +#define RTC_BASE_ADDRS { RTC_BASE } +/** Array initializer of RTC peripheral base pointers */ +#define RTC_BASE_PTRS { RTC } +/** Interrupt vectors for the RTC peripheral type */ +#define RTC_IRQS { RTC_IRQn } + +/*! + * @} + */ /* end of group RTC_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- SCT Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SCT_Peripheral_Access_Layer SCT Peripheral Access Layer + * @{ + */ + +/** SCT - Register Layout Typedef */ +typedef struct { + __IO uint32_t CONFIG; /**< SCT configuration register, offset: 0x0 */ + __IO uint32_t CTRL; /**< SCT control register, offset: 0x4 */ + __IO uint32_t LIMIT; /**< SCT limit event select register, offset: 0x8 */ + __IO uint32_t HALT; /**< SCT halt event select register, offset: 0xC */ + __IO uint32_t STOP; /**< SCT stop event select register, offset: 0x10 */ + __IO uint32_t START; /**< SCT start event select register, offset: 0x14 */ + uint8_t RESERVED_0[40]; + __IO uint32_t COUNT; /**< SCT counter register, offset: 0x40 */ + __IO uint32_t STATE; /**< SCT state register, offset: 0x44 */ + __I uint32_t INPUT; /**< SCT input register, offset: 0x48 */ + __IO uint32_t REGMODE; /**< SCT match/capture mode register, offset: 0x4C */ + __IO uint32_t OUTPUT; /**< SCT output register, offset: 0x50 */ + __IO uint32_t OUTPUTDIRCTRL; /**< SCT output counter direction control register, offset: 0x54 */ + __IO uint32_t RES; /**< SCT conflict resolution register, offset: 0x58 */ + __IO uint32_t DMA0REQUEST; /**< SCT DMA request 0 register, offset: 0x5C */ + __IO uint32_t DMA1REQUEST; /**< SCT DMA request 1 register, offset: 0x60 */ + uint8_t RESERVED_1[140]; + __IO uint32_t EVEN; /**< SCT event interrupt enable register, offset: 0xF0 */ + __IO uint32_t EVFLAG; /**< SCT event flag register, offset: 0xF4 */ + __IO uint32_t CONEN; /**< SCT conflict interrupt enable register, offset: 0xF8 */ + __IO uint32_t CONFLAG; /**< SCT conflict flag register, offset: 0xFC */ + union { /* offset: 0x100 */ + __IO uint32_t SCTCAP[13]; /**< SCT capture register of capture channel, array offset: 0x100, array step: 0x4 */ + __IO uint32_t SCTMATCH[13]; /**< SCT match value register of match channels, array offset: 0x100, array step: 0x4 */ + }; + uint8_t RESERVED_2[204]; + union { /* offset: 0x200 */ + __IO uint32_t SCTCAPCTRL[13]; /**< SCT capture control register, array offset: 0x200, array step: 0x4 */ + __IO uint32_t SCTMATCHREL[13]; /**< SCT match reload value register, array offset: 0x200, array step: 0x4 */ + }; + uint8_t RESERVED_3[204]; + struct { /* offset: 0x300, array step: 0x8 */ + __IO uint32_t STATE; /**< SCT event state register 0, array offset: 0x300, array step: 0x8 */ + __IO uint32_t CTRL; /**< SCT event control register 0, array offset: 0x304, array step: 0x8 */ + } EVENT[13]; + uint8_t RESERVED_4[408]; + struct { /* offset: 0x500, array step: 0x8 */ + __IO uint32_t SET; /**< SCT output 0 set register, array offset: 0x500, array step: 0x8 */ + __IO uint32_t CLR; /**< SCT output 0 clear register, array offset: 0x504, array step: 0x8 */ + } OUT[8]; +} SCT_Type; + +/* ---------------------------------------------------------------------------- + -- SCT Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SCT_Register_Masks SCT Register Masks + * @{ + */ + +/*! @name CONFIG - SCT configuration register */ +#define SCT_CONFIG_UNIFY_MASK (0x1U) +#define SCT_CONFIG_UNIFY_SHIFT (0U) +#define SCT_CONFIG_UNIFY(x) (((uint32_t)(((uint32_t)(x)) << SCT_CONFIG_UNIFY_SHIFT)) & SCT_CONFIG_UNIFY_MASK) +#define SCT_CONFIG_CLKMODE_MASK (0x6U) +#define SCT_CONFIG_CLKMODE_SHIFT (1U) +#define SCT_CONFIG_CLKMODE(x) (((uint32_t)(((uint32_t)(x)) << SCT_CONFIG_CLKMODE_SHIFT)) & SCT_CONFIG_CLKMODE_MASK) +#define SCT_CONFIG_CKSEL_MASK (0x78U) +#define SCT_CONFIG_CKSEL_SHIFT (3U) +#define SCT_CONFIG_CKSEL(x) (((uint32_t)(((uint32_t)(x)) << SCT_CONFIG_CKSEL_SHIFT)) & SCT_CONFIG_CKSEL_MASK) +#define SCT_CONFIG_NORELAOD_L_MASK (0x80U) +#define SCT_CONFIG_NORELAOD_L_SHIFT (7U) +#define SCT_CONFIG_NORELAOD_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_CONFIG_NORELAOD_L_SHIFT)) & SCT_CONFIG_NORELAOD_L_MASK) +#define SCT_CONFIG_NORELOAD_H_MASK (0x100U) +#define SCT_CONFIG_NORELOAD_H_SHIFT (8U) +#define SCT_CONFIG_NORELOAD_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_CONFIG_NORELOAD_H_SHIFT)) & SCT_CONFIG_NORELOAD_H_MASK) +#define SCT_CONFIG_INSYNC_MASK (0x1E00U) +#define SCT_CONFIG_INSYNC_SHIFT (9U) +#define SCT_CONFIG_INSYNC(x) (((uint32_t)(((uint32_t)(x)) << SCT_CONFIG_INSYNC_SHIFT)) & SCT_CONFIG_INSYNC_MASK) +#define SCT_CONFIG_AUTOLIMIT_L_MASK (0x20000U) +#define SCT_CONFIG_AUTOLIMIT_L_SHIFT (17U) +#define SCT_CONFIG_AUTOLIMIT_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_CONFIG_AUTOLIMIT_L_SHIFT)) & SCT_CONFIG_AUTOLIMIT_L_MASK) +#define SCT_CONFIG_AUTOLIMIT_H_MASK (0x40000U) +#define SCT_CONFIG_AUTOLIMIT_H_SHIFT (18U) +#define SCT_CONFIG_AUTOLIMIT_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_CONFIG_AUTOLIMIT_H_SHIFT)) & SCT_CONFIG_AUTOLIMIT_H_MASK) + +/*! @name CTRL - SCT control register */ +#define SCT_CTRL_DOWN_L_MASK (0x1U) +#define SCT_CTRL_DOWN_L_SHIFT (0U) +#define SCT_CTRL_DOWN_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_CTRL_DOWN_L_SHIFT)) & SCT_CTRL_DOWN_L_MASK) +#define SCT_CTRL_STOP_L_MASK (0x2U) +#define SCT_CTRL_STOP_L_SHIFT (1U) +#define SCT_CTRL_STOP_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_CTRL_STOP_L_SHIFT)) & SCT_CTRL_STOP_L_MASK) +#define SCT_CTRL_HALT_L_MASK (0x4U) +#define SCT_CTRL_HALT_L_SHIFT (2U) +#define SCT_CTRL_HALT_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_CTRL_HALT_L_SHIFT)) & SCT_CTRL_HALT_L_MASK) +#define SCT_CTRL_CLRCTR_L_MASK (0x8U) +#define SCT_CTRL_CLRCTR_L_SHIFT (3U) +#define SCT_CTRL_CLRCTR_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_CTRL_CLRCTR_L_SHIFT)) & SCT_CTRL_CLRCTR_L_MASK) +#define SCT_CTRL_BIDIR_L_MASK (0x10U) +#define SCT_CTRL_BIDIR_L_SHIFT (4U) +#define SCT_CTRL_BIDIR_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_CTRL_BIDIR_L_SHIFT)) & SCT_CTRL_BIDIR_L_MASK) +#define SCT_CTRL_PRE_L_MASK (0x1FE0U) +#define SCT_CTRL_PRE_L_SHIFT (5U) +#define SCT_CTRL_PRE_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_CTRL_PRE_L_SHIFT)) & SCT_CTRL_PRE_L_MASK) +#define SCT_CTRL_DOWN_H_MASK (0x10000U) +#define SCT_CTRL_DOWN_H_SHIFT (16U) +#define SCT_CTRL_DOWN_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_CTRL_DOWN_H_SHIFT)) & SCT_CTRL_DOWN_H_MASK) +#define SCT_CTRL_STOP_H_MASK (0x20000U) +#define SCT_CTRL_STOP_H_SHIFT (17U) +#define SCT_CTRL_STOP_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_CTRL_STOP_H_SHIFT)) & SCT_CTRL_STOP_H_MASK) +#define SCT_CTRL_HALT_H_MASK (0x40000U) +#define SCT_CTRL_HALT_H_SHIFT (18U) +#define SCT_CTRL_HALT_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_CTRL_HALT_H_SHIFT)) & SCT_CTRL_HALT_H_MASK) +#define SCT_CTRL_CLRCTR_H_MASK (0x80000U) +#define SCT_CTRL_CLRCTR_H_SHIFT (19U) +#define SCT_CTRL_CLRCTR_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_CTRL_CLRCTR_H_SHIFT)) & SCT_CTRL_CLRCTR_H_MASK) +#define SCT_CTRL_BIDIR_H_MASK (0x100000U) +#define SCT_CTRL_BIDIR_H_SHIFT (20U) +#define SCT_CTRL_BIDIR_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_CTRL_BIDIR_H_SHIFT)) & SCT_CTRL_BIDIR_H_MASK) +#define SCT_CTRL_PRE_H_MASK (0x1FE00000U) +#define SCT_CTRL_PRE_H_SHIFT (21U) +#define SCT_CTRL_PRE_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_CTRL_PRE_H_SHIFT)) & SCT_CTRL_PRE_H_MASK) + +/*! @name LIMIT - SCT limit event select register */ +#define SCT_LIMIT_LIMMSK_L_MASK (0xFFFFU) +#define SCT_LIMIT_LIMMSK_L_SHIFT (0U) +#define SCT_LIMIT_LIMMSK_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_LIMIT_LIMMSK_L_SHIFT)) & SCT_LIMIT_LIMMSK_L_MASK) +#define SCT_LIMIT_LIMMSK_H_MASK (0xFFFF0000U) +#define SCT_LIMIT_LIMMSK_H_SHIFT (16U) +#define SCT_LIMIT_LIMMSK_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_LIMIT_LIMMSK_H_SHIFT)) & SCT_LIMIT_LIMMSK_H_MASK) + +/*! @name HALT - SCT halt event select register */ +#define SCT_HALT_HALTMSK_L_MASK (0xFFFFU) +#define SCT_HALT_HALTMSK_L_SHIFT (0U) +#define SCT_HALT_HALTMSK_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_HALT_HALTMSK_L_SHIFT)) & SCT_HALT_HALTMSK_L_MASK) +#define SCT_HALT_HALTMSK_H_MASK (0xFFFF0000U) +#define SCT_HALT_HALTMSK_H_SHIFT (16U) +#define SCT_HALT_HALTMSK_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_HALT_HALTMSK_H_SHIFT)) & SCT_HALT_HALTMSK_H_MASK) + +/*! @name STOP - SCT stop event select register */ +#define SCT_STOP_STOPMSK_L_MASK (0xFFFFU) +#define SCT_STOP_STOPMSK_L_SHIFT (0U) +#define SCT_STOP_STOPMSK_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_STOP_STOPMSK_L_SHIFT)) & SCT_STOP_STOPMSK_L_MASK) +#define SCT_STOP_STOPMSK_H_MASK (0xFFFF0000U) +#define SCT_STOP_STOPMSK_H_SHIFT (16U) +#define SCT_STOP_STOPMSK_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_STOP_STOPMSK_H_SHIFT)) & SCT_STOP_STOPMSK_H_MASK) + +/*! @name START - SCT start event select register */ +#define SCT_START_STARTMSK_L_MASK (0xFFFFU) +#define SCT_START_STARTMSK_L_SHIFT (0U) +#define SCT_START_STARTMSK_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_START_STARTMSK_L_SHIFT)) & SCT_START_STARTMSK_L_MASK) +#define SCT_START_STARTMSK_H_MASK (0xFFFF0000U) +#define SCT_START_STARTMSK_H_SHIFT (16U) +#define SCT_START_STARTMSK_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_START_STARTMSK_H_SHIFT)) & SCT_START_STARTMSK_H_MASK) + +/*! @name COUNT - SCT counter register */ +#define SCT_COUNT_CTR_L_MASK (0xFFFFU) +#define SCT_COUNT_CTR_L_SHIFT (0U) +#define SCT_COUNT_CTR_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_COUNT_CTR_L_SHIFT)) & SCT_COUNT_CTR_L_MASK) +#define SCT_COUNT_CTR_H_MASK (0xFFFF0000U) +#define SCT_COUNT_CTR_H_SHIFT (16U) +#define SCT_COUNT_CTR_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_COUNT_CTR_H_SHIFT)) & SCT_COUNT_CTR_H_MASK) + +/*! @name STATE - SCT state register */ +#define SCT_STATE_STATE_L_MASK (0x1FU) +#define SCT_STATE_STATE_L_SHIFT (0U) +#define SCT_STATE_STATE_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_STATE_STATE_L_SHIFT)) & SCT_STATE_STATE_L_MASK) +#define SCT_STATE_STATE_H_MASK (0x1F0000U) +#define SCT_STATE_STATE_H_SHIFT (16U) +#define SCT_STATE_STATE_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_STATE_STATE_H_SHIFT)) & SCT_STATE_STATE_H_MASK) + +/*! @name INPUT - SCT input register */ +#define SCT_INPUT_AIN0_MASK (0x1U) +#define SCT_INPUT_AIN0_SHIFT (0U) +#define SCT_INPUT_AIN0(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_AIN0_SHIFT)) & SCT_INPUT_AIN0_MASK) +#define SCT_INPUT_AIN1_MASK (0x2U) +#define SCT_INPUT_AIN1_SHIFT (1U) +#define SCT_INPUT_AIN1(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_AIN1_SHIFT)) & SCT_INPUT_AIN1_MASK) +#define SCT_INPUT_AIN2_MASK (0x4U) +#define SCT_INPUT_AIN2_SHIFT (2U) +#define SCT_INPUT_AIN2(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_AIN2_SHIFT)) & SCT_INPUT_AIN2_MASK) +#define SCT_INPUT_AIN3_MASK (0x8U) +#define SCT_INPUT_AIN3_SHIFT (3U) +#define SCT_INPUT_AIN3(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_AIN3_SHIFT)) & SCT_INPUT_AIN3_MASK) +#define SCT_INPUT_AIN4_MASK (0x10U) +#define SCT_INPUT_AIN4_SHIFT (4U) +#define SCT_INPUT_AIN4(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_AIN4_SHIFT)) & SCT_INPUT_AIN4_MASK) +#define SCT_INPUT_AIN5_MASK (0x20U) +#define SCT_INPUT_AIN5_SHIFT (5U) +#define SCT_INPUT_AIN5(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_AIN5_SHIFT)) & SCT_INPUT_AIN5_MASK) +#define SCT_INPUT_AIN6_MASK (0x40U) +#define SCT_INPUT_AIN6_SHIFT (6U) +#define SCT_INPUT_AIN6(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_AIN6_SHIFT)) & SCT_INPUT_AIN6_MASK) +#define SCT_INPUT_AIN7_MASK (0x80U) +#define SCT_INPUT_AIN7_SHIFT (7U) +#define SCT_INPUT_AIN7(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_AIN7_SHIFT)) & SCT_INPUT_AIN7_MASK) +#define SCT_INPUT_AIN8_MASK (0x100U) +#define SCT_INPUT_AIN8_SHIFT (8U) +#define SCT_INPUT_AIN8(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_AIN8_SHIFT)) & SCT_INPUT_AIN8_MASK) +#define SCT_INPUT_AIN9_MASK (0x200U) +#define SCT_INPUT_AIN9_SHIFT (9U) +#define SCT_INPUT_AIN9(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_AIN9_SHIFT)) & SCT_INPUT_AIN9_MASK) +#define SCT_INPUT_AIN10_MASK (0x400U) +#define SCT_INPUT_AIN10_SHIFT (10U) +#define SCT_INPUT_AIN10(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_AIN10_SHIFT)) & SCT_INPUT_AIN10_MASK) +#define SCT_INPUT_AIN11_MASK (0x800U) +#define SCT_INPUT_AIN11_SHIFT (11U) +#define SCT_INPUT_AIN11(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_AIN11_SHIFT)) & SCT_INPUT_AIN11_MASK) +#define SCT_INPUT_AIN12_MASK (0x1000U) +#define SCT_INPUT_AIN12_SHIFT (12U) +#define SCT_INPUT_AIN12(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_AIN12_SHIFT)) & SCT_INPUT_AIN12_MASK) +#define SCT_INPUT_AIN13_MASK (0x2000U) +#define SCT_INPUT_AIN13_SHIFT (13U) +#define SCT_INPUT_AIN13(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_AIN13_SHIFT)) & SCT_INPUT_AIN13_MASK) +#define SCT_INPUT_AIN14_MASK (0x4000U) +#define SCT_INPUT_AIN14_SHIFT (14U) +#define SCT_INPUT_AIN14(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_AIN14_SHIFT)) & SCT_INPUT_AIN14_MASK) +#define SCT_INPUT_AIN15_MASK (0x8000U) +#define SCT_INPUT_AIN15_SHIFT (15U) +#define SCT_INPUT_AIN15(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_AIN15_SHIFT)) & SCT_INPUT_AIN15_MASK) +#define SCT_INPUT_SIN0_MASK (0x10000U) +#define SCT_INPUT_SIN0_SHIFT (16U) +#define SCT_INPUT_SIN0(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_SIN0_SHIFT)) & SCT_INPUT_SIN0_MASK) +#define SCT_INPUT_SIN1_MASK (0x20000U) +#define SCT_INPUT_SIN1_SHIFT (17U) +#define SCT_INPUT_SIN1(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_SIN1_SHIFT)) & SCT_INPUT_SIN1_MASK) +#define SCT_INPUT_SIN2_MASK (0x40000U) +#define SCT_INPUT_SIN2_SHIFT (18U) +#define SCT_INPUT_SIN2(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_SIN2_SHIFT)) & SCT_INPUT_SIN2_MASK) +#define SCT_INPUT_SIN3_MASK (0x80000U) +#define SCT_INPUT_SIN3_SHIFT (19U) +#define SCT_INPUT_SIN3(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_SIN3_SHIFT)) & SCT_INPUT_SIN3_MASK) +#define SCT_INPUT_SIN4_MASK (0x100000U) +#define SCT_INPUT_SIN4_SHIFT (20U) +#define SCT_INPUT_SIN4(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_SIN4_SHIFT)) & SCT_INPUT_SIN4_MASK) +#define SCT_INPUT_SIN5_MASK (0x200000U) +#define SCT_INPUT_SIN5_SHIFT (21U) +#define SCT_INPUT_SIN5(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_SIN5_SHIFT)) & SCT_INPUT_SIN5_MASK) +#define SCT_INPUT_SIN6_MASK (0x400000U) +#define SCT_INPUT_SIN6_SHIFT (22U) +#define SCT_INPUT_SIN6(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_SIN6_SHIFT)) & SCT_INPUT_SIN6_MASK) +#define SCT_INPUT_SIN7_MASK (0x800000U) +#define SCT_INPUT_SIN7_SHIFT (23U) +#define SCT_INPUT_SIN7(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_SIN7_SHIFT)) & SCT_INPUT_SIN7_MASK) +#define SCT_INPUT_SIN8_MASK (0x1000000U) +#define SCT_INPUT_SIN8_SHIFT (24U) +#define SCT_INPUT_SIN8(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_SIN8_SHIFT)) & SCT_INPUT_SIN8_MASK) +#define SCT_INPUT_SIN9_MASK (0x2000000U) +#define SCT_INPUT_SIN9_SHIFT (25U) +#define SCT_INPUT_SIN9(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_SIN9_SHIFT)) & SCT_INPUT_SIN9_MASK) +#define SCT_INPUT_SIN10_MASK (0x4000000U) +#define SCT_INPUT_SIN10_SHIFT (26U) +#define SCT_INPUT_SIN10(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_SIN10_SHIFT)) & SCT_INPUT_SIN10_MASK) +#define SCT_INPUT_SIN11_MASK (0x8000000U) +#define SCT_INPUT_SIN11_SHIFT (27U) +#define SCT_INPUT_SIN11(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_SIN11_SHIFT)) & SCT_INPUT_SIN11_MASK) +#define SCT_INPUT_SIN12_MASK (0x10000000U) +#define SCT_INPUT_SIN12_SHIFT (28U) +#define SCT_INPUT_SIN12(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_SIN12_SHIFT)) & SCT_INPUT_SIN12_MASK) +#define SCT_INPUT_SIN13_MASK (0x20000000U) +#define SCT_INPUT_SIN13_SHIFT (29U) +#define SCT_INPUT_SIN13(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_SIN13_SHIFT)) & SCT_INPUT_SIN13_MASK) +#define SCT_INPUT_SIN14_MASK (0x40000000U) +#define SCT_INPUT_SIN14_SHIFT (30U) +#define SCT_INPUT_SIN14(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_SIN14_SHIFT)) & SCT_INPUT_SIN14_MASK) +#define SCT_INPUT_SIN15_MASK (0x80000000U) +#define SCT_INPUT_SIN15_SHIFT (31U) +#define SCT_INPUT_SIN15(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_SIN15_SHIFT)) & SCT_INPUT_SIN15_MASK) + +/*! @name REGMODE - SCT match/capture mode register */ +#define SCT_REGMODE_REGMOD_L_MASK (0xFFFFU) +#define SCT_REGMODE_REGMOD_L_SHIFT (0U) +#define SCT_REGMODE_REGMOD_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_REGMODE_REGMOD_L_SHIFT)) & SCT_REGMODE_REGMOD_L_MASK) +#define SCT_REGMODE_REGMOD_H_MASK (0xFFFF0000U) +#define SCT_REGMODE_REGMOD_H_SHIFT (16U) +#define SCT_REGMODE_REGMOD_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_REGMODE_REGMOD_H_SHIFT)) & SCT_REGMODE_REGMOD_H_MASK) + +/*! @name OUTPUT - SCT output register */ +#define SCT_OUTPUT_OUT_MASK (0xFFFFU) +#define SCT_OUTPUT_OUT_SHIFT (0U) +#define SCT_OUTPUT_OUT(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUT_OUT_SHIFT)) & SCT_OUTPUT_OUT_MASK) + +/*! @name OUTPUTDIRCTRL - SCT output counter direction control register */ +#define SCT_OUTPUTDIRCTRL_SETCLR0_MASK (0x3U) +#define SCT_OUTPUTDIRCTRL_SETCLR0_SHIFT (0U) +#define SCT_OUTPUTDIRCTRL_SETCLR0(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUTDIRCTRL_SETCLR0_SHIFT)) & SCT_OUTPUTDIRCTRL_SETCLR0_MASK) +#define SCT_OUTPUTDIRCTRL_SETCLR1_MASK (0xCU) +#define SCT_OUTPUTDIRCTRL_SETCLR1_SHIFT (2U) +#define SCT_OUTPUTDIRCTRL_SETCLR1(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUTDIRCTRL_SETCLR1_SHIFT)) & SCT_OUTPUTDIRCTRL_SETCLR1_MASK) +#define SCT_OUTPUTDIRCTRL_SETCLR2_MASK (0x30U) +#define SCT_OUTPUTDIRCTRL_SETCLR2_SHIFT (4U) +#define SCT_OUTPUTDIRCTRL_SETCLR2(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUTDIRCTRL_SETCLR2_SHIFT)) & SCT_OUTPUTDIRCTRL_SETCLR2_MASK) +#define SCT_OUTPUTDIRCTRL_SETCLR3_MASK (0xC0U) +#define SCT_OUTPUTDIRCTRL_SETCLR3_SHIFT (6U) +#define SCT_OUTPUTDIRCTRL_SETCLR3(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUTDIRCTRL_SETCLR3_SHIFT)) & SCT_OUTPUTDIRCTRL_SETCLR3_MASK) +#define SCT_OUTPUTDIRCTRL_SETCLR4_MASK (0x300U) +#define SCT_OUTPUTDIRCTRL_SETCLR4_SHIFT (8U) +#define SCT_OUTPUTDIRCTRL_SETCLR4(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUTDIRCTRL_SETCLR4_SHIFT)) & SCT_OUTPUTDIRCTRL_SETCLR4_MASK) +#define SCT_OUTPUTDIRCTRL_SETCLR5_MASK (0xC00U) +#define SCT_OUTPUTDIRCTRL_SETCLR5_SHIFT (10U) +#define SCT_OUTPUTDIRCTRL_SETCLR5(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUTDIRCTRL_SETCLR5_SHIFT)) & SCT_OUTPUTDIRCTRL_SETCLR5_MASK) +#define SCT_OUTPUTDIRCTRL_SETCLR6_MASK (0x3000U) +#define SCT_OUTPUTDIRCTRL_SETCLR6_SHIFT (12U) +#define SCT_OUTPUTDIRCTRL_SETCLR6(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUTDIRCTRL_SETCLR6_SHIFT)) & SCT_OUTPUTDIRCTRL_SETCLR6_MASK) +#define SCT_OUTPUTDIRCTRL_SETCLR7_MASK (0xC000U) +#define SCT_OUTPUTDIRCTRL_SETCLR7_SHIFT (14U) +#define SCT_OUTPUTDIRCTRL_SETCLR7(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUTDIRCTRL_SETCLR7_SHIFT)) & SCT_OUTPUTDIRCTRL_SETCLR7_MASK) +#define SCT_OUTPUTDIRCTRL_SETCLR8_MASK (0x30000U) +#define SCT_OUTPUTDIRCTRL_SETCLR8_SHIFT (16U) +#define SCT_OUTPUTDIRCTRL_SETCLR8(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUTDIRCTRL_SETCLR8_SHIFT)) & SCT_OUTPUTDIRCTRL_SETCLR8_MASK) +#define SCT_OUTPUTDIRCTRL_SETCLR9_MASK (0xC0000U) +#define SCT_OUTPUTDIRCTRL_SETCLR9_SHIFT (18U) +#define SCT_OUTPUTDIRCTRL_SETCLR9(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUTDIRCTRL_SETCLR9_SHIFT)) & SCT_OUTPUTDIRCTRL_SETCLR9_MASK) +#define SCT_OUTPUTDIRCTRL_SETCLR10_MASK (0x300000U) +#define SCT_OUTPUTDIRCTRL_SETCLR10_SHIFT (20U) +#define SCT_OUTPUTDIRCTRL_SETCLR10(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUTDIRCTRL_SETCLR10_SHIFT)) & SCT_OUTPUTDIRCTRL_SETCLR10_MASK) +#define SCT_OUTPUTDIRCTRL_SETCLR11_MASK (0xC00000U) +#define SCT_OUTPUTDIRCTRL_SETCLR11_SHIFT (22U) +#define SCT_OUTPUTDIRCTRL_SETCLR11(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUTDIRCTRL_SETCLR11_SHIFT)) & SCT_OUTPUTDIRCTRL_SETCLR11_MASK) +#define SCT_OUTPUTDIRCTRL_SETCLR12_MASK (0x3000000U) +#define SCT_OUTPUTDIRCTRL_SETCLR12_SHIFT (24U) +#define SCT_OUTPUTDIRCTRL_SETCLR12(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUTDIRCTRL_SETCLR12_SHIFT)) & SCT_OUTPUTDIRCTRL_SETCLR12_MASK) +#define SCT_OUTPUTDIRCTRL_SETCLR13_MASK (0xC000000U) +#define SCT_OUTPUTDIRCTRL_SETCLR13_SHIFT (26U) +#define SCT_OUTPUTDIRCTRL_SETCLR13(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUTDIRCTRL_SETCLR13_SHIFT)) & SCT_OUTPUTDIRCTRL_SETCLR13_MASK) +#define SCT_OUTPUTDIRCTRL_SETCLR14_MASK (0x30000000U) +#define SCT_OUTPUTDIRCTRL_SETCLR14_SHIFT (28U) +#define SCT_OUTPUTDIRCTRL_SETCLR14(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUTDIRCTRL_SETCLR14_SHIFT)) & SCT_OUTPUTDIRCTRL_SETCLR14_MASK) +#define SCT_OUTPUTDIRCTRL_SETCLR15_MASK (0xC0000000U) +#define SCT_OUTPUTDIRCTRL_SETCLR15_SHIFT (30U) +#define SCT_OUTPUTDIRCTRL_SETCLR15(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUTDIRCTRL_SETCLR15_SHIFT)) & SCT_OUTPUTDIRCTRL_SETCLR15_MASK) + +/*! @name RES - SCT conflict resolution register */ +#define SCT_RES_O0RES_MASK (0x3U) +#define SCT_RES_O0RES_SHIFT (0U) +#define SCT_RES_O0RES(x) (((uint32_t)(((uint32_t)(x)) << SCT_RES_O0RES_SHIFT)) & SCT_RES_O0RES_MASK) +#define SCT_RES_O1RES_MASK (0xCU) +#define SCT_RES_O1RES_SHIFT (2U) +#define SCT_RES_O1RES(x) (((uint32_t)(((uint32_t)(x)) << SCT_RES_O1RES_SHIFT)) & SCT_RES_O1RES_MASK) +#define SCT_RES_O2RES_MASK (0x30U) +#define SCT_RES_O2RES_SHIFT (4U) +#define SCT_RES_O2RES(x) (((uint32_t)(((uint32_t)(x)) << SCT_RES_O2RES_SHIFT)) & SCT_RES_O2RES_MASK) +#define SCT_RES_O3RES_MASK (0xC0U) +#define SCT_RES_O3RES_SHIFT (6U) +#define SCT_RES_O3RES(x) (((uint32_t)(((uint32_t)(x)) << SCT_RES_O3RES_SHIFT)) & SCT_RES_O3RES_MASK) +#define SCT_RES_O4RES_MASK (0x300U) +#define SCT_RES_O4RES_SHIFT (8U) +#define SCT_RES_O4RES(x) (((uint32_t)(((uint32_t)(x)) << SCT_RES_O4RES_SHIFT)) & SCT_RES_O4RES_MASK) +#define SCT_RES_O5RES_MASK (0xC00U) +#define SCT_RES_O5RES_SHIFT (10U) +#define SCT_RES_O5RES(x) (((uint32_t)(((uint32_t)(x)) << SCT_RES_O5RES_SHIFT)) & SCT_RES_O5RES_MASK) +#define SCT_RES_O6RES_MASK (0x3000U) +#define SCT_RES_O6RES_SHIFT (12U) +#define SCT_RES_O6RES(x) (((uint32_t)(((uint32_t)(x)) << SCT_RES_O6RES_SHIFT)) & SCT_RES_O6RES_MASK) +#define SCT_RES_O7RES_MASK (0xC000U) +#define SCT_RES_O7RES_SHIFT (14U) +#define SCT_RES_O7RES(x) (((uint32_t)(((uint32_t)(x)) << SCT_RES_O7RES_SHIFT)) & SCT_RES_O7RES_MASK) +#define SCT_RES_O8RES_MASK (0x30000U) +#define SCT_RES_O8RES_SHIFT (16U) +#define SCT_RES_O8RES(x) (((uint32_t)(((uint32_t)(x)) << SCT_RES_O8RES_SHIFT)) & SCT_RES_O8RES_MASK) +#define SCT_RES_O9RES_MASK (0xC0000U) +#define SCT_RES_O9RES_SHIFT (18U) +#define SCT_RES_O9RES(x) (((uint32_t)(((uint32_t)(x)) << SCT_RES_O9RES_SHIFT)) & SCT_RES_O9RES_MASK) +#define SCT_RES_O10RES_MASK (0x300000U) +#define SCT_RES_O10RES_SHIFT (20U) +#define SCT_RES_O10RES(x) (((uint32_t)(((uint32_t)(x)) << SCT_RES_O10RES_SHIFT)) & SCT_RES_O10RES_MASK) +#define SCT_RES_O11RES_MASK (0xC00000U) +#define SCT_RES_O11RES_SHIFT (22U) +#define SCT_RES_O11RES(x) (((uint32_t)(((uint32_t)(x)) << SCT_RES_O11RES_SHIFT)) & SCT_RES_O11RES_MASK) +#define SCT_RES_O12RES_MASK (0x3000000U) +#define SCT_RES_O12RES_SHIFT (24U) +#define SCT_RES_O12RES(x) (((uint32_t)(((uint32_t)(x)) << SCT_RES_O12RES_SHIFT)) & SCT_RES_O12RES_MASK) +#define SCT_RES_O13RES_MASK (0xC000000U) +#define SCT_RES_O13RES_SHIFT (26U) +#define SCT_RES_O13RES(x) (((uint32_t)(((uint32_t)(x)) << SCT_RES_O13RES_SHIFT)) & SCT_RES_O13RES_MASK) +#define SCT_RES_O14RES_MASK (0x30000000U) +#define SCT_RES_O14RES_SHIFT (28U) +#define SCT_RES_O14RES(x) (((uint32_t)(((uint32_t)(x)) << SCT_RES_O14RES_SHIFT)) & SCT_RES_O14RES_MASK) +#define SCT_RES_O15RES_MASK (0xC0000000U) +#define SCT_RES_O15RES_SHIFT (30U) +#define SCT_RES_O15RES(x) (((uint32_t)(((uint32_t)(x)) << SCT_RES_O15RES_SHIFT)) & SCT_RES_O15RES_MASK) + +/*! @name DMA0REQUEST - SCT DMA request 0 register */ +#define SCT_DMA0REQUEST_DEV_0_MASK (0xFFFFU) +#define SCT_DMA0REQUEST_DEV_0_SHIFT (0U) +#define SCT_DMA0REQUEST_DEV_0(x) (((uint32_t)(((uint32_t)(x)) << SCT_DMA0REQUEST_DEV_0_SHIFT)) & SCT_DMA0REQUEST_DEV_0_MASK) +#define SCT_DMA0REQUEST_DRL0_MASK (0x40000000U) +#define SCT_DMA0REQUEST_DRL0_SHIFT (30U) +#define SCT_DMA0REQUEST_DRL0(x) (((uint32_t)(((uint32_t)(x)) << SCT_DMA0REQUEST_DRL0_SHIFT)) & SCT_DMA0REQUEST_DRL0_MASK) +#define SCT_DMA0REQUEST_DRQ0_MASK (0x80000000U) +#define SCT_DMA0REQUEST_DRQ0_SHIFT (31U) +#define SCT_DMA0REQUEST_DRQ0(x) (((uint32_t)(((uint32_t)(x)) << SCT_DMA0REQUEST_DRQ0_SHIFT)) & SCT_DMA0REQUEST_DRQ0_MASK) + +/*! @name DMA1REQUEST - SCT DMA request 1 register */ +#define SCT_DMA1REQUEST_DEV_1_MASK (0xFFFFU) +#define SCT_DMA1REQUEST_DEV_1_SHIFT (0U) +#define SCT_DMA1REQUEST_DEV_1(x) (((uint32_t)(((uint32_t)(x)) << SCT_DMA1REQUEST_DEV_1_SHIFT)) & SCT_DMA1REQUEST_DEV_1_MASK) +#define SCT_DMA1REQUEST_DRL1_MASK (0x40000000U) +#define SCT_DMA1REQUEST_DRL1_SHIFT (30U) +#define SCT_DMA1REQUEST_DRL1(x) (((uint32_t)(((uint32_t)(x)) << SCT_DMA1REQUEST_DRL1_SHIFT)) & SCT_DMA1REQUEST_DRL1_MASK) +#define SCT_DMA1REQUEST_DRQ1_MASK (0x80000000U) +#define SCT_DMA1REQUEST_DRQ1_SHIFT (31U) +#define SCT_DMA1REQUEST_DRQ1(x) (((uint32_t)(((uint32_t)(x)) << SCT_DMA1REQUEST_DRQ1_SHIFT)) & SCT_DMA1REQUEST_DRQ1_MASK) + +/*! @name EVEN - SCT event interrupt enable register */ +#define SCT_EVEN_IEN_MASK (0xFFFFU) +#define SCT_EVEN_IEN_SHIFT (0U) +#define SCT_EVEN_IEN(x) (((uint32_t)(((uint32_t)(x)) << SCT_EVEN_IEN_SHIFT)) & SCT_EVEN_IEN_MASK) + +/*! @name EVFLAG - SCT event flag register */ +#define SCT_EVFLAG_FLAG_MASK (0xFFFFU) +#define SCT_EVFLAG_FLAG_SHIFT (0U) +#define SCT_EVFLAG_FLAG(x) (((uint32_t)(((uint32_t)(x)) << SCT_EVFLAG_FLAG_SHIFT)) & SCT_EVFLAG_FLAG_MASK) + +/*! @name CONEN - SCT conflict interrupt enable register */ +#define SCT_CONEN_NCEN_MASK (0xFFFFU) +#define SCT_CONEN_NCEN_SHIFT (0U) +#define SCT_CONEN_NCEN(x) (((uint32_t)(((uint32_t)(x)) << SCT_CONEN_NCEN_SHIFT)) & SCT_CONEN_NCEN_MASK) + +/*! @name CONFLAG - SCT conflict flag register */ +#define SCT_CONFLAG_NCFLAG_MASK (0xFFFFU) +#define SCT_CONFLAG_NCFLAG_SHIFT (0U) +#define SCT_CONFLAG_NCFLAG(x) (((uint32_t)(((uint32_t)(x)) << SCT_CONFLAG_NCFLAG_SHIFT)) & SCT_CONFLAG_NCFLAG_MASK) +#define SCT_CONFLAG_BUSERRL_MASK (0x40000000U) +#define SCT_CONFLAG_BUSERRL_SHIFT (30U) +#define SCT_CONFLAG_BUSERRL(x) (((uint32_t)(((uint32_t)(x)) << SCT_CONFLAG_BUSERRL_SHIFT)) & SCT_CONFLAG_BUSERRL_MASK) +#define SCT_CONFLAG_BUSERRH_MASK (0x80000000U) +#define SCT_CONFLAG_BUSERRH_SHIFT (31U) +#define SCT_CONFLAG_BUSERRH(x) (((uint32_t)(((uint32_t)(x)) << SCT_CONFLAG_BUSERRH_SHIFT)) & SCT_CONFLAG_BUSERRH_MASK) + +/*! @name SCTCAP - SCT capture register of capture channel */ +#define SCT_SCTCAP_CAPn_L_MASK (0xFFFFU) +#define SCT_SCTCAP_CAPn_L_SHIFT (0U) +#define SCT_SCTCAP_CAPn_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_SCTCAP_CAPn_L_SHIFT)) & SCT_SCTCAP_CAPn_L_MASK) +#define SCT_SCTCAP_CAPn_H_MASK (0xFFFF0000U) +#define SCT_SCTCAP_CAPn_H_SHIFT (16U) +#define SCT_SCTCAP_CAPn_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_SCTCAP_CAPn_H_SHIFT)) & SCT_SCTCAP_CAPn_H_MASK) + +/* The count of SCT_SCTCAP */ +#define SCT_SCTCAP_COUNT (13U) + +/*! @name SCTMATCH - SCT match value register of match channels */ +#define SCT_SCTMATCH_MATCHn_L_MASK (0xFFFFU) +#define SCT_SCTMATCH_MATCHn_L_SHIFT (0U) +#define SCT_SCTMATCH_MATCHn_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_SCTMATCH_MATCHn_L_SHIFT)) & SCT_SCTMATCH_MATCHn_L_MASK) +#define SCT_SCTMATCH_MATCHn_H_MASK (0xFFFF0000U) +#define SCT_SCTMATCH_MATCHn_H_SHIFT (16U) +#define SCT_SCTMATCH_MATCHn_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_SCTMATCH_MATCHn_H_SHIFT)) & SCT_SCTMATCH_MATCHn_H_MASK) + +/* The count of SCT_SCTMATCH */ +#define SCT_SCTMATCH_COUNT (13U) + +/*! @name SCTCAPCTRL - SCT capture control register */ +#define SCT_SCTCAPCTRL_CAPCONn_L_MASK (0xFFFFU) +#define SCT_SCTCAPCTRL_CAPCONn_L_SHIFT (0U) +#define SCT_SCTCAPCTRL_CAPCONn_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_SCTCAPCTRL_CAPCONn_L_SHIFT)) & SCT_SCTCAPCTRL_CAPCONn_L_MASK) +#define SCT_SCTCAPCTRL_CAPCONn_H_MASK (0xFFFF0000U) +#define SCT_SCTCAPCTRL_CAPCONn_H_SHIFT (16U) +#define SCT_SCTCAPCTRL_CAPCONn_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_SCTCAPCTRL_CAPCONn_H_SHIFT)) & SCT_SCTCAPCTRL_CAPCONn_H_MASK) + +/* The count of SCT_SCTCAPCTRL */ +#define SCT_SCTCAPCTRL_COUNT (13U) + +/*! @name SCTMATCHREL - SCT match reload value register */ +#define SCT_SCTMATCHREL_RELOADn_L_MASK (0xFFFFU) +#define SCT_SCTMATCHREL_RELOADn_L_SHIFT (0U) +#define SCT_SCTMATCHREL_RELOADn_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_SCTMATCHREL_RELOADn_L_SHIFT)) & SCT_SCTMATCHREL_RELOADn_L_MASK) +#define SCT_SCTMATCHREL_RELOADn_H_MASK (0xFFFF0000U) +#define SCT_SCTMATCHREL_RELOADn_H_SHIFT (16U) +#define SCT_SCTMATCHREL_RELOADn_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_SCTMATCHREL_RELOADn_H_SHIFT)) & SCT_SCTMATCHREL_RELOADn_H_MASK) + +/* The count of SCT_SCTMATCHREL */ +#define SCT_SCTMATCHREL_COUNT (13U) + +/*! @name EVENT_STATE - SCT event state register 0 */ +#define SCT_EVENT_STATE_STATEMSKn_MASK (0xFFFFU) +#define SCT_EVENT_STATE_STATEMSKn_SHIFT (0U) +#define SCT_EVENT_STATE_STATEMSKn(x) (((uint32_t)(((uint32_t)(x)) << SCT_EVENT_STATE_STATEMSKn_SHIFT)) & SCT_EVENT_STATE_STATEMSKn_MASK) + +/* The count of SCT_EVENT_STATE */ +#define SCT_EVENT_STATE_COUNT (13U) + +/*! @name EVENT_CTRL - SCT event control register 0 */ +#define SCT_EVENT_CTRL_MATCHSEL_MASK (0xFU) +#define SCT_EVENT_CTRL_MATCHSEL_SHIFT (0U) +#define SCT_EVENT_CTRL_MATCHSEL(x) (((uint32_t)(((uint32_t)(x)) << SCT_EVENT_CTRL_MATCHSEL_SHIFT)) & SCT_EVENT_CTRL_MATCHSEL_MASK) +#define SCT_EVENT_CTRL_HEVENT_MASK (0x10U) +#define SCT_EVENT_CTRL_HEVENT_SHIFT (4U) +#define SCT_EVENT_CTRL_HEVENT(x) (((uint32_t)(((uint32_t)(x)) << SCT_EVENT_CTRL_HEVENT_SHIFT)) & SCT_EVENT_CTRL_HEVENT_MASK) +#define SCT_EVENT_CTRL_OUTSEL_MASK (0x20U) +#define SCT_EVENT_CTRL_OUTSEL_SHIFT (5U) +#define SCT_EVENT_CTRL_OUTSEL(x) (((uint32_t)(((uint32_t)(x)) << SCT_EVENT_CTRL_OUTSEL_SHIFT)) & SCT_EVENT_CTRL_OUTSEL_MASK) +#define SCT_EVENT_CTRL_IOSEL_MASK (0x3C0U) +#define SCT_EVENT_CTRL_IOSEL_SHIFT (6U) +#define SCT_EVENT_CTRL_IOSEL(x) (((uint32_t)(((uint32_t)(x)) << SCT_EVENT_CTRL_IOSEL_SHIFT)) & SCT_EVENT_CTRL_IOSEL_MASK) +#define SCT_EVENT_CTRL_IOCOND_MASK (0xC00U) +#define SCT_EVENT_CTRL_IOCOND_SHIFT (10U) +#define SCT_EVENT_CTRL_IOCOND(x) (((uint32_t)(((uint32_t)(x)) << SCT_EVENT_CTRL_IOCOND_SHIFT)) & SCT_EVENT_CTRL_IOCOND_MASK) +#define SCT_EVENT_CTRL_COMBMODE_MASK (0x3000U) +#define SCT_EVENT_CTRL_COMBMODE_SHIFT (12U) +#define SCT_EVENT_CTRL_COMBMODE(x) (((uint32_t)(((uint32_t)(x)) << SCT_EVENT_CTRL_COMBMODE_SHIFT)) & SCT_EVENT_CTRL_COMBMODE_MASK) +#define SCT_EVENT_CTRL_STATELD_MASK (0x4000U) +#define SCT_EVENT_CTRL_STATELD_SHIFT (14U) +#define SCT_EVENT_CTRL_STATELD(x) (((uint32_t)(((uint32_t)(x)) << SCT_EVENT_CTRL_STATELD_SHIFT)) & SCT_EVENT_CTRL_STATELD_MASK) +#define SCT_EVENT_CTRL_STATEV_MASK (0xF8000U) +#define SCT_EVENT_CTRL_STATEV_SHIFT (15U) +#define SCT_EVENT_CTRL_STATEV(x) (((uint32_t)(((uint32_t)(x)) << SCT_EVENT_CTRL_STATEV_SHIFT)) & SCT_EVENT_CTRL_STATEV_MASK) +#define SCT_EVENT_CTRL_MATCHMEM_MASK (0x100000U) +#define SCT_EVENT_CTRL_MATCHMEM_SHIFT (20U) +#define SCT_EVENT_CTRL_MATCHMEM(x) (((uint32_t)(((uint32_t)(x)) << SCT_EVENT_CTRL_MATCHMEM_SHIFT)) & SCT_EVENT_CTRL_MATCHMEM_MASK) +#define SCT_EVENT_CTRL_DIRECTION_MASK (0x600000U) +#define SCT_EVENT_CTRL_DIRECTION_SHIFT (21U) +#define SCT_EVENT_CTRL_DIRECTION(x) (((uint32_t)(((uint32_t)(x)) << SCT_EVENT_CTRL_DIRECTION_SHIFT)) & SCT_EVENT_CTRL_DIRECTION_MASK) + +/* The count of SCT_EVENT_CTRL */ +#define SCT_EVENT_CTRL_COUNT (13U) + +/*! @name OUT_SET - SCT output 0 set register */ +#define SCT_OUT_SET_SET_MASK (0xFFFFU) +#define SCT_OUT_SET_SET_SHIFT (0U) +#define SCT_OUT_SET_SET(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUT_SET_SET_SHIFT)) & SCT_OUT_SET_SET_MASK) + +/* The count of SCT_OUT_SET */ +#define SCT_OUT_SET_COUNT (8U) + +/*! @name OUT_CLR - SCT output 0 clear register */ +#define SCT_OUT_CLR_CLR_MASK (0xFFFFU) +#define SCT_OUT_CLR_CLR_SHIFT (0U) +#define SCT_OUT_CLR_CLR(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUT_CLR_CLR_SHIFT)) & SCT_OUT_CLR_CLR_MASK) + +/* The count of SCT_OUT_CLR */ +#define SCT_OUT_CLR_COUNT (8U) + + +/*! + * @} + */ /* end of group SCT_Register_Masks */ + + +/* SCT - Peripheral instance base addresses */ +/** Peripheral SCT0 base address */ +#define SCT0_BASE (0x1C018000u) +/** Peripheral SCT0 base pointer */ +#define SCT0 ((SCT_Type *)SCT0_BASE) +/** Array initializer of SCT peripheral base addresses */ +#define SCT_BASE_ADDRS { SCT0_BASE } +/** Array initializer of SCT peripheral base pointers */ +#define SCT_BASE_PTRS { SCT0 } +/** Interrupt vectors for the SCT peripheral type */ +#define SCT_IRQS { SCT0_IRQn } + +/*! + * @} + */ /* end of group SCT_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- SPI Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SPI_Peripheral_Access_Layer SPI Peripheral Access Layer + * @{ + */ + +/** SPI - Register Layout Typedef */ +typedef struct { + __IO uint32_t CFG; /**< SPI Configuration register, offset: 0x0 */ + __IO uint32_t DLY; /**< SPI Delay register, offset: 0x4 */ + __IO uint32_t STAT; /**< SPI Status. Some status flags can be cleared by writing a 1 to that bit position, offset: 0x8 */ + __IO uint32_t INTENSET; /**< SPI Interrupt Enable read and Set. A complete value may be read from this register. Writing a 1 to any implemented bit position causes that bit to be set., offset: 0xC */ + __IO uint32_t INTENCLR; /**< SPI Interrupt Enable Clear. Writing a 1 to any implemented bit position causes the corresponding bit in INTENSET to be cleared., offset: 0x10 */ + __IO uint32_t RXDAT; /**< SPI Receive Data, offset: 0x14 */ + __IO uint32_t TXDATCTL; /**< SPI Transmit Data with Control, offset: 0x18 */ + __IO uint32_t TXDAT; /**< SPI Transmit Data, offset: 0x1C */ + __IO uint32_t TXCTL; /**< SPI Transmit Control, offset: 0x20 */ + __IO uint32_t DIV; /**< SPI clock Divider, offset: 0x24 */ + __IO uint32_t INTSTAT; /**< SPI Interrupt Status, offset: 0x28 */ +} SPI_Type; + +/* ---------------------------------------------------------------------------- + -- SPI Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SPI_Register_Masks SPI Register Masks + * @{ + */ + +/*! @name CFG - SPI Configuration register */ +#define SPI_CFG_ENABLE_MASK (0x1U) +#define SPI_CFG_ENABLE_SHIFT (0U) +#define SPI_CFG_ENABLE(x) (((uint32_t)(((uint32_t)(x)) << SPI_CFG_ENABLE_SHIFT)) & SPI_CFG_ENABLE_MASK) +#define SPI_CFG_MASTER_MASK (0x4U) +#define SPI_CFG_MASTER_SHIFT (2U) +#define SPI_CFG_MASTER(x) (((uint32_t)(((uint32_t)(x)) << SPI_CFG_MASTER_SHIFT)) & SPI_CFG_MASTER_MASK) +#define SPI_CFG_LSBF_MASK (0x8U) +#define SPI_CFG_LSBF_SHIFT (3U) +#define SPI_CFG_LSBF(x) (((uint32_t)(((uint32_t)(x)) << SPI_CFG_LSBF_SHIFT)) & SPI_CFG_LSBF_MASK) +#define SPI_CFG_CPHA_MASK (0x10U) +#define SPI_CFG_CPHA_SHIFT (4U) +#define SPI_CFG_CPHA(x) (((uint32_t)(((uint32_t)(x)) << SPI_CFG_CPHA_SHIFT)) & SPI_CFG_CPHA_MASK) +#define SPI_CFG_CPOL_MASK (0x20U) +#define SPI_CFG_CPOL_SHIFT (5U) +#define SPI_CFG_CPOL(x) (((uint32_t)(((uint32_t)(x)) << SPI_CFG_CPOL_SHIFT)) & SPI_CFG_CPOL_MASK) +#define SPI_CFG_LOOP_MASK (0x80U) +#define SPI_CFG_LOOP_SHIFT (7U) +#define SPI_CFG_LOOP(x) (((uint32_t)(((uint32_t)(x)) << SPI_CFG_LOOP_SHIFT)) & SPI_CFG_LOOP_MASK) +#define SPI_CFG_SPOL0_MASK (0x100U) +#define SPI_CFG_SPOL0_SHIFT (8U) +#define SPI_CFG_SPOL0(x) (((uint32_t)(((uint32_t)(x)) << SPI_CFG_SPOL0_SHIFT)) & SPI_CFG_SPOL0_MASK) +#define SPI_CFG_SPOL1_MASK (0x200U) +#define SPI_CFG_SPOL1_SHIFT (9U) +#define SPI_CFG_SPOL1(x) (((uint32_t)(((uint32_t)(x)) << SPI_CFG_SPOL1_SHIFT)) & SPI_CFG_SPOL1_MASK) +#define SPI_CFG_SPOL2_MASK (0x400U) +#define SPI_CFG_SPOL2_SHIFT (10U) +#define SPI_CFG_SPOL2(x) (((uint32_t)(((uint32_t)(x)) << SPI_CFG_SPOL2_SHIFT)) & SPI_CFG_SPOL2_MASK) +#define SPI_CFG_SPOL3_MASK (0x800U) +#define SPI_CFG_SPOL3_SHIFT (11U) +#define SPI_CFG_SPOL3(x) (((uint32_t)(((uint32_t)(x)) << SPI_CFG_SPOL3_SHIFT)) & SPI_CFG_SPOL3_MASK) + +/*! @name DLY - SPI Delay register */ +#define SPI_DLY_PRE_DELAY_MASK (0xFU) +#define SPI_DLY_PRE_DELAY_SHIFT (0U) +#define SPI_DLY_PRE_DELAY(x) (((uint32_t)(((uint32_t)(x)) << SPI_DLY_PRE_DELAY_SHIFT)) & SPI_DLY_PRE_DELAY_MASK) +#define SPI_DLY_POST_DELAY_MASK (0xF0U) +#define SPI_DLY_POST_DELAY_SHIFT (4U) +#define SPI_DLY_POST_DELAY(x) (((uint32_t)(((uint32_t)(x)) << SPI_DLY_POST_DELAY_SHIFT)) & SPI_DLY_POST_DELAY_MASK) +#define SPI_DLY_FRAME_DELAY_MASK (0xF00U) +#define SPI_DLY_FRAME_DELAY_SHIFT (8U) +#define SPI_DLY_FRAME_DELAY(x) (((uint32_t)(((uint32_t)(x)) << SPI_DLY_FRAME_DELAY_SHIFT)) & SPI_DLY_FRAME_DELAY_MASK) +#define SPI_DLY_TRANSFER_DELAY_MASK (0xF000U) +#define SPI_DLY_TRANSFER_DELAY_SHIFT (12U) +#define SPI_DLY_TRANSFER_DELAY(x) (((uint32_t)(((uint32_t)(x)) << SPI_DLY_TRANSFER_DELAY_SHIFT)) & SPI_DLY_TRANSFER_DELAY_MASK) + +/*! @name STAT - SPI Status. Some status flags can be cleared by writing a 1 to that bit position */ +#define SPI_STAT_RXRDY_MASK (0x1U) +#define SPI_STAT_RXRDY_SHIFT (0U) +#define SPI_STAT_RXRDY(x) (((uint32_t)(((uint32_t)(x)) << SPI_STAT_RXRDY_SHIFT)) & SPI_STAT_RXRDY_MASK) +#define SPI_STAT_TXRDY_MASK (0x2U) +#define SPI_STAT_TXRDY_SHIFT (1U) +#define SPI_STAT_TXRDY(x) (((uint32_t)(((uint32_t)(x)) << SPI_STAT_TXRDY_SHIFT)) & SPI_STAT_TXRDY_MASK) +#define SPI_STAT_RXOV_MASK (0x4U) +#define SPI_STAT_RXOV_SHIFT (2U) +#define SPI_STAT_RXOV(x) (((uint32_t)(((uint32_t)(x)) << SPI_STAT_RXOV_SHIFT)) & SPI_STAT_RXOV_MASK) +#define SPI_STAT_TXUR_MASK (0x8U) +#define SPI_STAT_TXUR_SHIFT (3U) +#define SPI_STAT_TXUR(x) (((uint32_t)(((uint32_t)(x)) << SPI_STAT_TXUR_SHIFT)) & SPI_STAT_TXUR_MASK) +#define SPI_STAT_SSA_MASK (0x10U) +#define SPI_STAT_SSA_SHIFT (4U) +#define SPI_STAT_SSA(x) (((uint32_t)(((uint32_t)(x)) << SPI_STAT_SSA_SHIFT)) & SPI_STAT_SSA_MASK) +#define SPI_STAT_SSD_MASK (0x20U) +#define SPI_STAT_SSD_SHIFT (5U) +#define SPI_STAT_SSD(x) (((uint32_t)(((uint32_t)(x)) << SPI_STAT_SSD_SHIFT)) & SPI_STAT_SSD_MASK) +#define SPI_STAT_STALLED_MASK (0x40U) +#define SPI_STAT_STALLED_SHIFT (6U) +#define SPI_STAT_STALLED(x) (((uint32_t)(((uint32_t)(x)) << SPI_STAT_STALLED_SHIFT)) & SPI_STAT_STALLED_MASK) +#define SPI_STAT_ENDTRANSFER_MASK (0x80U) +#define SPI_STAT_ENDTRANSFER_SHIFT (7U) +#define SPI_STAT_ENDTRANSFER(x) (((uint32_t)(((uint32_t)(x)) << SPI_STAT_ENDTRANSFER_SHIFT)) & SPI_STAT_ENDTRANSFER_MASK) +#define SPI_STAT_MSTIDLE_MASK (0x100U) +#define SPI_STAT_MSTIDLE_SHIFT (8U) +#define SPI_STAT_MSTIDLE(x) (((uint32_t)(((uint32_t)(x)) << SPI_STAT_MSTIDLE_SHIFT)) & SPI_STAT_MSTIDLE_MASK) + +/*! @name INTENSET - SPI Interrupt Enable read and Set. A complete value may be read from this register. Writing a 1 to any implemented bit position causes that bit to be set. */ +#define SPI_INTENSET_RXRDYEN_MASK (0x1U) +#define SPI_INTENSET_RXRDYEN_SHIFT (0U) +#define SPI_INTENSET_RXRDYEN(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTENSET_RXRDYEN_SHIFT)) & SPI_INTENSET_RXRDYEN_MASK) +#define SPI_INTENSET_TXRDYEN_MASK (0x2U) +#define SPI_INTENSET_TXRDYEN_SHIFT (1U) +#define SPI_INTENSET_TXRDYEN(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTENSET_TXRDYEN_SHIFT)) & SPI_INTENSET_TXRDYEN_MASK) +#define SPI_INTENSET_RXOVEN_MASK (0x4U) +#define SPI_INTENSET_RXOVEN_SHIFT (2U) +#define SPI_INTENSET_RXOVEN(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTENSET_RXOVEN_SHIFT)) & SPI_INTENSET_RXOVEN_MASK) +#define SPI_INTENSET_TXUREN_MASK (0x8U) +#define SPI_INTENSET_TXUREN_SHIFT (3U) +#define SPI_INTENSET_TXUREN(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTENSET_TXUREN_SHIFT)) & SPI_INTENSET_TXUREN_MASK) +#define SPI_INTENSET_SSAEN_MASK (0x10U) +#define SPI_INTENSET_SSAEN_SHIFT (4U) +#define SPI_INTENSET_SSAEN(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTENSET_SSAEN_SHIFT)) & SPI_INTENSET_SSAEN_MASK) +#define SPI_INTENSET_SSDEN_MASK (0x20U) +#define SPI_INTENSET_SSDEN_SHIFT (5U) +#define SPI_INTENSET_SSDEN(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTENSET_SSDEN_SHIFT)) & SPI_INTENSET_SSDEN_MASK) +#define SPI_INTENSET_MSTIDLEEN_MASK (0x100U) +#define SPI_INTENSET_MSTIDLEEN_SHIFT (8U) +#define SPI_INTENSET_MSTIDLEEN(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTENSET_MSTIDLEEN_SHIFT)) & SPI_INTENSET_MSTIDLEEN_MASK) + +/*! @name INTENCLR - SPI Interrupt Enable Clear. Writing a 1 to any implemented bit position causes the corresponding bit in INTENSET to be cleared. */ +#define SPI_INTENCLR_RXRDYEN_MASK (0x1U) +#define SPI_INTENCLR_RXRDYEN_SHIFT (0U) +#define SPI_INTENCLR_RXRDYEN(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTENCLR_RXRDYEN_SHIFT)) & SPI_INTENCLR_RXRDYEN_MASK) +#define SPI_INTENCLR_TXRDYEN_MASK (0x2U) +#define SPI_INTENCLR_TXRDYEN_SHIFT (1U) +#define SPI_INTENCLR_TXRDYEN(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTENCLR_TXRDYEN_SHIFT)) & SPI_INTENCLR_TXRDYEN_MASK) +#define SPI_INTENCLR_RXOVEN_MASK (0x4U) +#define SPI_INTENCLR_RXOVEN_SHIFT (2U) +#define SPI_INTENCLR_RXOVEN(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTENCLR_RXOVEN_SHIFT)) & SPI_INTENCLR_RXOVEN_MASK) +#define SPI_INTENCLR_TXUREN_MASK (0x8U) +#define SPI_INTENCLR_TXUREN_SHIFT (3U) +#define SPI_INTENCLR_TXUREN(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTENCLR_TXUREN_SHIFT)) & SPI_INTENCLR_TXUREN_MASK) +#define SPI_INTENCLR_SSAEN_MASK (0x10U) +#define SPI_INTENCLR_SSAEN_SHIFT (4U) +#define SPI_INTENCLR_SSAEN(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTENCLR_SSAEN_SHIFT)) & SPI_INTENCLR_SSAEN_MASK) +#define SPI_INTENCLR_SSDEN_MASK (0x20U) +#define SPI_INTENCLR_SSDEN_SHIFT (5U) +#define SPI_INTENCLR_SSDEN(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTENCLR_SSDEN_SHIFT)) & SPI_INTENCLR_SSDEN_MASK) +#define SPI_INTENCLR_MSTIDLE_MASK (0x100U) +#define SPI_INTENCLR_MSTIDLE_SHIFT (8U) +#define SPI_INTENCLR_MSTIDLE(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTENCLR_MSTIDLE_SHIFT)) & SPI_INTENCLR_MSTIDLE_MASK) + +/*! @name RXDAT - SPI Receive Data */ +#define SPI_RXDAT_RXDAT_MASK (0xFFFFU) +#define SPI_RXDAT_RXDAT_SHIFT (0U) +#define SPI_RXDAT_RXDAT(x) (((uint32_t)(((uint32_t)(x)) << SPI_RXDAT_RXDAT_SHIFT)) & SPI_RXDAT_RXDAT_MASK) +#define SPI_RXDAT_RXSSEL0_N_MASK (0x10000U) +#define SPI_RXDAT_RXSSEL0_N_SHIFT (16U) +#define SPI_RXDAT_RXSSEL0_N(x) (((uint32_t)(((uint32_t)(x)) << SPI_RXDAT_RXSSEL0_N_SHIFT)) & SPI_RXDAT_RXSSEL0_N_MASK) +#define SPI_RXDAT_RXSSEL1_N_MASK (0x20000U) +#define SPI_RXDAT_RXSSEL1_N_SHIFT (17U) +#define SPI_RXDAT_RXSSEL1_N(x) (((uint32_t)(((uint32_t)(x)) << SPI_RXDAT_RXSSEL1_N_SHIFT)) & SPI_RXDAT_RXSSEL1_N_MASK) +#define SPI_RXDAT_RXSSEL2_N_MASK (0x40000U) +#define SPI_RXDAT_RXSSEL2_N_SHIFT (18U) +#define SPI_RXDAT_RXSSEL2_N(x) (((uint32_t)(((uint32_t)(x)) << SPI_RXDAT_RXSSEL2_N_SHIFT)) & SPI_RXDAT_RXSSEL2_N_MASK) +#define SPI_RXDAT_RXSSEL3_N_MASK (0x80000U) +#define SPI_RXDAT_RXSSEL3_N_SHIFT (19U) +#define SPI_RXDAT_RXSSEL3_N(x) (((uint32_t)(((uint32_t)(x)) << SPI_RXDAT_RXSSEL3_N_SHIFT)) & SPI_RXDAT_RXSSEL3_N_MASK) +#define SPI_RXDAT_SOT_MASK (0x100000U) +#define SPI_RXDAT_SOT_SHIFT (20U) +#define SPI_RXDAT_SOT(x) (((uint32_t)(((uint32_t)(x)) << SPI_RXDAT_SOT_SHIFT)) & SPI_RXDAT_SOT_MASK) + +/*! @name TXDATCTL - SPI Transmit Data with Control */ +#define SPI_TXDATCTL_TXDAT_MASK (0xFFFFU) +#define SPI_TXDATCTL_TXDAT_SHIFT (0U) +#define SPI_TXDATCTL_TXDAT(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXDATCTL_TXDAT_SHIFT)) & SPI_TXDATCTL_TXDAT_MASK) +#define SPI_TXDATCTL_TXSSEL0_N_MASK (0x10000U) +#define SPI_TXDATCTL_TXSSEL0_N_SHIFT (16U) +#define SPI_TXDATCTL_TXSSEL0_N(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXDATCTL_TXSSEL0_N_SHIFT)) & SPI_TXDATCTL_TXSSEL0_N_MASK) +#define SPI_TXDATCTL_TXSSEL1_N_MASK (0x20000U) +#define SPI_TXDATCTL_TXSSEL1_N_SHIFT (17U) +#define SPI_TXDATCTL_TXSSEL1_N(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXDATCTL_TXSSEL1_N_SHIFT)) & SPI_TXDATCTL_TXSSEL1_N_MASK) +#define SPI_TXDATCTL_TXSSEL2_N_MASK (0x40000U) +#define SPI_TXDATCTL_TXSSEL2_N_SHIFT (18U) +#define SPI_TXDATCTL_TXSSEL2_N(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXDATCTL_TXSSEL2_N_SHIFT)) & SPI_TXDATCTL_TXSSEL2_N_MASK) +#define SPI_TXDATCTL_TXSSEL3_N_MASK (0x80000U) +#define SPI_TXDATCTL_TXSSEL3_N_SHIFT (19U) +#define SPI_TXDATCTL_TXSSEL3_N(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXDATCTL_TXSSEL3_N_SHIFT)) & SPI_TXDATCTL_TXSSEL3_N_MASK) +#define SPI_TXDATCTL_EOT_MASK (0x100000U) +#define SPI_TXDATCTL_EOT_SHIFT (20U) +#define SPI_TXDATCTL_EOT(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXDATCTL_EOT_SHIFT)) & SPI_TXDATCTL_EOT_MASK) +#define SPI_TXDATCTL_EOF_MASK (0x200000U) +#define SPI_TXDATCTL_EOF_SHIFT (21U) +#define SPI_TXDATCTL_EOF(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXDATCTL_EOF_SHIFT)) & SPI_TXDATCTL_EOF_MASK) +#define SPI_TXDATCTL_RXIGNORE_MASK (0x400000U) +#define SPI_TXDATCTL_RXIGNORE_SHIFT (22U) +#define SPI_TXDATCTL_RXIGNORE(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXDATCTL_RXIGNORE_SHIFT)) & SPI_TXDATCTL_RXIGNORE_MASK) +#define SPI_TXDATCTL_LEN_MASK (0xF000000U) +#define SPI_TXDATCTL_LEN_SHIFT (24U) +#define SPI_TXDATCTL_LEN(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXDATCTL_LEN_SHIFT)) & SPI_TXDATCTL_LEN_MASK) + +/*! @name TXDAT - SPI Transmit Data */ +#define SPI_TXDAT_DATA_MASK (0xFFFFU) +#define SPI_TXDAT_DATA_SHIFT (0U) +#define SPI_TXDAT_DATA(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXDAT_DATA_SHIFT)) & SPI_TXDAT_DATA_MASK) + +/*! @name TXCTL - SPI Transmit Control */ +#define SPI_TXCTL_TXSSEL0_N_MASK (0x10000U) +#define SPI_TXCTL_TXSSEL0_N_SHIFT (16U) +#define SPI_TXCTL_TXSSEL0_N(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXCTL_TXSSEL0_N_SHIFT)) & SPI_TXCTL_TXSSEL0_N_MASK) +#define SPI_TXCTL_TXSSEL1_N_MASK (0x20000U) +#define SPI_TXCTL_TXSSEL1_N_SHIFT (17U) +#define SPI_TXCTL_TXSSEL1_N(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXCTL_TXSSEL1_N_SHIFT)) & SPI_TXCTL_TXSSEL1_N_MASK) +#define SPI_TXCTL_TXSSEL2_N_MASK (0x40000U) +#define SPI_TXCTL_TXSSEL2_N_SHIFT (18U) +#define SPI_TXCTL_TXSSEL2_N(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXCTL_TXSSEL2_N_SHIFT)) & SPI_TXCTL_TXSSEL2_N_MASK) +#define SPI_TXCTL_TXSSEL3_n_MASK (0x80000U) +#define SPI_TXCTL_TXSSEL3_n_SHIFT (19U) +#define SPI_TXCTL_TXSSEL3_n(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXCTL_TXSSEL3_n_SHIFT)) & SPI_TXCTL_TXSSEL3_n_MASK) +#define SPI_TXCTL_EOT_MASK (0x100000U) +#define SPI_TXCTL_EOT_SHIFT (20U) +#define SPI_TXCTL_EOT(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXCTL_EOT_SHIFT)) & SPI_TXCTL_EOT_MASK) +#define SPI_TXCTL_EOF_MASK (0x200000U) +#define SPI_TXCTL_EOF_SHIFT (21U) +#define SPI_TXCTL_EOF(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXCTL_EOF_SHIFT)) & SPI_TXCTL_EOF_MASK) +#define SPI_TXCTL_RXIGNORE_MASK (0x400000U) +#define SPI_TXCTL_RXIGNORE_SHIFT (22U) +#define SPI_TXCTL_RXIGNORE(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXCTL_RXIGNORE_SHIFT)) & SPI_TXCTL_RXIGNORE_MASK) +#define SPI_TXCTL_LEN_MASK (0xF000000U) +#define SPI_TXCTL_LEN_SHIFT (24U) +#define SPI_TXCTL_LEN(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXCTL_LEN_SHIFT)) & SPI_TXCTL_LEN_MASK) + +/*! @name DIV - SPI clock Divider */ +#define SPI_DIV_DIVVAL_MASK (0xFFFFU) +#define SPI_DIV_DIVVAL_SHIFT (0U) +#define SPI_DIV_DIVVAL(x) (((uint32_t)(((uint32_t)(x)) << SPI_DIV_DIVVAL_SHIFT)) & SPI_DIV_DIVVAL_MASK) + +/*! @name INTSTAT - SPI Interrupt Status */ +#define SPI_INTSTAT_RXRDY_MASK (0x1U) +#define SPI_INTSTAT_RXRDY_SHIFT (0U) +#define SPI_INTSTAT_RXRDY(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTSTAT_RXRDY_SHIFT)) & SPI_INTSTAT_RXRDY_MASK) +#define SPI_INTSTAT_TXRDY_MASK (0x2U) +#define SPI_INTSTAT_TXRDY_SHIFT (1U) +#define SPI_INTSTAT_TXRDY(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTSTAT_TXRDY_SHIFT)) & SPI_INTSTAT_TXRDY_MASK) +#define SPI_INTSTAT_RXOV_MASK (0x4U) +#define SPI_INTSTAT_RXOV_SHIFT (2U) +#define SPI_INTSTAT_RXOV(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTSTAT_RXOV_SHIFT)) & SPI_INTSTAT_RXOV_MASK) +#define SPI_INTSTAT_TXUR_MASK (0x8U) +#define SPI_INTSTAT_TXUR_SHIFT (3U) +#define SPI_INTSTAT_TXUR(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTSTAT_TXUR_SHIFT)) & SPI_INTSTAT_TXUR_MASK) +#define SPI_INTSTAT_SSA_MASK (0x10U) +#define SPI_INTSTAT_SSA_SHIFT (4U) +#define SPI_INTSTAT_SSA(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTSTAT_SSA_SHIFT)) & SPI_INTSTAT_SSA_MASK) +#define SPI_INTSTAT_SSD_MASK (0x20U) +#define SPI_INTSTAT_SSD_SHIFT (5U) +#define SPI_INTSTAT_SSD(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTSTAT_SSD_SHIFT)) & SPI_INTSTAT_SSD_MASK) +#define SPI_INTSTAT_MSTIDLE_MASK (0x100U) +#define SPI_INTSTAT_MSTIDLE_SHIFT (8U) +#define SPI_INTSTAT_MSTIDLE(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTSTAT_MSTIDLE_SHIFT)) & SPI_INTSTAT_MSTIDLE_MASK) + + +/*! + * @} + */ /* end of group SPI_Register_Masks */ + + +/* SPI - Peripheral instance base addresses */ +/** Peripheral SPI0 base address */ +#define SPI0_BASE (0x400A4000u) +/** Peripheral SPI0 base pointer */ +#define SPI0 ((SPI_Type *)SPI0_BASE) +/** Peripheral SPI1 base address */ +#define SPI1_BASE (0x400A8000u) +/** Peripheral SPI1 base pointer */ +#define SPI1 ((SPI_Type *)SPI1_BASE) +/** Array initializer of SPI peripheral base addresses */ +#define SPI_BASE_ADDRS { SPI0_BASE, SPI1_BASE } +/** Array initializer of SPI peripheral base pointers */ +#define SPI_BASE_PTRS { SPI0, SPI1 } +/** Interrupt vectors for the SPI peripheral type */ +#define SPI_IRQS { SPI0_IRQn, SPI1_IRQn } + +/*! + * @} + */ /* end of group SPI_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- SYSCON Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SYSCON_Peripheral_Access_Layer SYSCON Peripheral Access Layer + * @{ + */ + +/** SYSCON - Register Layout Typedef */ +typedef struct { + __IO uint32_t SYSMEMREMAP; /**< System memory remap, offset: 0x0 */ + __IO uint32_t AHBMATPRIO; /**< AHB multilayer matrix priority control, offset: 0x4 */ + uint8_t RESERVED_0[12]; + __IO uint32_t SYSTCKCAL; /**< System tick counter calibration, offset: 0x14 */ + uint8_t RESERVED_1[4]; + __IO uint32_t NMISRC; /**< NMI Source Select, offset: 0x1C */ + __IO uint32_t ASYNCAPBCTRL; /**< Asynchronous APB Control, offset: 0x20 */ + uint8_t RESERVED_2[28]; + __IO uint32_t SYSRSTSTAT; /**< System reset status register, offset: 0x40 */ + __IO uint32_t PRESETCTRL[2]; /**< Peripheral reset control n, array offset: 0x44, array step: 0x4 */ + __IO uint32_t PRESETCTRLSET[2]; /**< Set bits in PRESETCTRL n, array offset: 0x4C, array step: 0x4 */ + __IO uint32_t PRESETCTRLCLR[2]; /**< Clear bits in PRESETCTRL n, array offset: 0x54, array step: 0x4 */ + __IO uint32_t PIOPORCAP0; /**< POR captured PIO status 0, offset: 0x5C */ + __IO uint32_t PIOPORCAP1; /**< POR captured PIO status 1, offset: 0x60 */ + uint8_t RESERVED_3[4]; + __IO uint32_t PIORESCAP0; /**< Reset captured PIO status 0, offset: 0x68 */ + __IO uint32_t PIORESCAP1; /**< Reset captured PIO status 1, offset: 0x6C */ + uint8_t RESERVED_4[16]; + __IO uint32_t MAINCLKSELA; /**< Main clock source select A, offset: 0x80 */ + __IO uint32_t MAINCLKSELB; /**< Main clock source select B, offset: 0x84 */ + uint8_t RESERVED_5[4]; + __IO uint32_t ADCCLKSEL; /**< ADC clock source select, offset: 0x8C */ + uint8_t RESERVED_6[4]; + __IO uint32_t CLKOUTSELA; /**< CLKOUT clock source select A, offset: 0x94 */ + __IO uint32_t CLKOUTSELB; /**< CLKOUT clock source select B, offset: 0x98 */ + uint8_t RESERVED_7[4]; + __IO uint32_t SYSPLLCLKSEL; /**< PLL clock source select, offset: 0xA0 */ + uint8_t RESERVED_8[28]; + __IO uint32_t AHBCLKCTRL[2]; /**< AHB Clock control n, array offset: 0xC0, array step: 0x4 */ + __IO uint32_t AHBCLKCTRLSET[2]; /**< Set bits in AHBCLKCTRL n, array offset: 0xC8, array step: 0x4 */ + __IO uint32_t AHBCLKCTRLCLR[2]; /**< Clear bits in AHBCLKCTRL n, array offset: 0xD0, array step: 0x4 */ + uint8_t RESERVED_9[8]; + __IO uint32_t SYSTICKCLKDIV; /**< SYSTICK clock divider, offset: 0xE0 */ + uint8_t RESERVED_10[28]; + __IO uint32_t AHBCLKDIV; /**< System clock divider, offset: 0x100 */ + uint8_t RESERVED_11[4]; + __IO uint32_t ADCCLKDIV; /**< ADC clock divider, offset: 0x108 */ + __IO uint32_t CLKOUTDIV; /**< CLKOUT clock divider, offset: 0x10C */ + uint8_t RESERVED_12[16]; + __IO uint32_t FREQMECTRL; /**< Frequency measure register, offset: 0x120 */ + __IO uint32_t FLASHCFG; /**< Flash wait states configuration, offset: 0x124 */ + uint8_t RESERVED_13[32]; + __IO uint32_t FIFOCTRL; /**< Serial interface FIFO enables, offset: 0x148 */ + uint8_t RESERVED_14[56]; + __IO uint32_t IRCCTRL; /**< IRC oscillator control, offset: 0x184 */ + uint8_t RESERVED_15[8]; + __IO uint32_t RTCOSCCTRL; /**< RTC oscillator 32 kHz output control, offset: 0x190 */ + uint8_t RESERVED_16[28]; + __IO uint32_t SYSPLLCTRL; /**< PLL control, offset: 0x1B0 */ + __IO uint32_t SYSPLLSTAT; /**< PLL status, offset: 0x1B4 */ + __IO uint32_t SYSPLLNDEC; /**< PLL N decoder, offset: 0x1B8 */ + __IO uint32_t SYSPLLPDEC; /**< PLL P decoder, offset: 0x1BC */ + __IO uint32_t SYSPLLSSCTRL0; /**< PLL spread spectrum control 0, offset: 0x1C0 */ + __IO uint32_t SYSPLLSSCTRL1; /**< PLL spread spectrum control 1, offset: 0x1C4 */ + uint8_t RESERVED_17[72]; + __IO uint32_t PDRUNCFG; /**< Power configuration register, offset: 0x210 */ + __IO uint32_t PDRUNCFGSET; /**< Set bits in PDRUNCFG, offset: 0x214 */ + __IO uint32_t PDRUNCFGCLR; /**< Clear bits in PDRUNCFG, offset: 0x218 */ + uint8_t RESERVED_18[36]; + __IO uint32_t STARTER[2]; /**< Start logic n wake-up enable register, array offset: 0x240, array step: 0x4 */ + __IO uint32_t STARTERSET[2]; /**< Set bits in STARTERP n, array offset: 0x248, array step: 0x4 */ + __IO uint32_t STARTERCLR[2]; /**< Clear bits in STARTER n, array offset: 0x250, array step: 0x4 */ + uint8_t RESERVED_19[168]; + __IO uint32_t CPUCTRL; /**< CPU Control for multiple processors, offset: 0x300 */ + __IO uint32_t CPBOOT; /**< Coprocessor Boot Address, offset: 0x304 */ + __IO uint32_t CPSTACK; /**< Coprocessor Stack Address, offset: 0x308 */ + __IO uint32_t CPSTAT; /**< Coprocessor Status, offset: 0x30C */ + uint8_t RESERVED_20[228]; + __IO uint32_t JTAGIDCODE; /**< JTAG ID code register, offset: 0x3F4 */ + __IO uint32_t DEVICE_ID[2]; /**< Part ID register, array offset: 0x3F8, array step: 0x4 */ + uint8_t RESERVED_21[179268]; + __IO uint32_t BODCTRL; /**< Brown-Out Detect control, offset: 0x2C044 */ +} SYSCON_Type; + +/* ---------------------------------------------------------------------------- + -- SYSCON Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SYSCON_Register_Masks SYSCON Register Masks + * @{ + */ + +/*! @name SYSMEMREMAP - System memory remap */ +#define SYSCON_SYSMEMREMAP_MAP_MASK (0x3U) +#define SYSCON_SYSMEMREMAP_MAP_SHIFT (0U) +#define SYSCON_SYSMEMREMAP_MAP(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSMEMREMAP_MAP_SHIFT)) & SYSCON_SYSMEMREMAP_MAP_MASK) + +/*! @name AHBMATPRIO - AHB multilayer matrix priority control */ +#define SYSCON_AHBMATPRIO_PRI_ICODE_MASK (0x3U) +#define SYSCON_AHBMATPRIO_PRI_ICODE_SHIFT (0U) +#define SYSCON_AHBMATPRIO_PRI_ICODE(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBMATPRIO_PRI_ICODE_SHIFT)) & SYSCON_AHBMATPRIO_PRI_ICODE_MASK) +#define SYSCON_AHBMATPRIO_PRI_DCODE_MASK (0xCU) +#define SYSCON_AHBMATPRIO_PRI_DCODE_SHIFT (2U) +#define SYSCON_AHBMATPRIO_PRI_DCODE(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBMATPRIO_PRI_DCODE_SHIFT)) & SYSCON_AHBMATPRIO_PRI_DCODE_MASK) +#define SYSCON_AHBMATPRIO_PRI_SYS_MASK (0x30U) +#define SYSCON_AHBMATPRIO_PRI_SYS_SHIFT (4U) +#define SYSCON_AHBMATPRIO_PRI_SYS(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBMATPRIO_PRI_SYS_SHIFT)) & SYSCON_AHBMATPRIO_PRI_SYS_MASK) +#define SYSCON_AHBMATPRIO_PRI_DMA_MASK (0x300U) +#define SYSCON_AHBMATPRIO_PRI_DMA_SHIFT (8U) +#define SYSCON_AHBMATPRIO_PRI_DMA(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBMATPRIO_PRI_DMA_SHIFT)) & SYSCON_AHBMATPRIO_PRI_DMA_MASK) +#define SYSCON_AHBMATPRIO_PRI_FIFO_MASK (0xC000U) +#define SYSCON_AHBMATPRIO_PRI_FIFO_SHIFT (14U) +#define SYSCON_AHBMATPRIO_PRI_FIFO(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBMATPRIO_PRI_FIFO_SHIFT)) & SYSCON_AHBMATPRIO_PRI_FIFO_MASK) +#define SYSCON_AHBMATPRIO_PRI_M0_MASK (0x30000U) +#define SYSCON_AHBMATPRIO_PRI_M0_SHIFT (16U) +#define SYSCON_AHBMATPRIO_PRI_M0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBMATPRIO_PRI_M0_SHIFT)) & SYSCON_AHBMATPRIO_PRI_M0_MASK) + +/*! @name SYSTCKCAL - System tick counter calibration */ +#define SYSCON_SYSTCKCAL_CAL_MASK (0xFFFFFFU) +#define SYSCON_SYSTCKCAL_CAL_SHIFT (0U) +#define SYSCON_SYSTCKCAL_CAL(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSTCKCAL_CAL_SHIFT)) & SYSCON_SYSTCKCAL_CAL_MASK) +#define SYSCON_SYSTCKCAL_SKEW_MASK (0x1000000U) +#define SYSCON_SYSTCKCAL_SKEW_SHIFT (24U) +#define SYSCON_SYSTCKCAL_SKEW(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSTCKCAL_SKEW_SHIFT)) & SYSCON_SYSTCKCAL_SKEW_MASK) +#define SYSCON_SYSTCKCAL_NOREF_MASK (0x2000000U) +#define SYSCON_SYSTCKCAL_NOREF_SHIFT (25U) +#define SYSCON_SYSTCKCAL_NOREF(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSTCKCAL_NOREF_SHIFT)) & SYSCON_SYSTCKCAL_NOREF_MASK) + +/*! @name NMISRC - NMI Source Select */ +#define SYSCON_NMISRC_IRQM4_MASK (0x3FU) +#define SYSCON_NMISRC_IRQM4_SHIFT (0U) +#define SYSCON_NMISRC_IRQM4(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_NMISRC_IRQM4_SHIFT)) & SYSCON_NMISRC_IRQM4_MASK) +#define SYSCON_NMISRC_IRQM0_MASK (0x3F00U) +#define SYSCON_NMISRC_IRQM0_SHIFT (8U) +#define SYSCON_NMISRC_IRQM0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_NMISRC_IRQM0_SHIFT)) & SYSCON_NMISRC_IRQM0_MASK) +#define SYSCON_NMISRC_NMIENM0_MASK (0x40000000U) +#define SYSCON_NMISRC_NMIENM0_SHIFT (30U) +#define SYSCON_NMISRC_NMIENM0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_NMISRC_NMIENM0_SHIFT)) & SYSCON_NMISRC_NMIENM0_MASK) +#define SYSCON_NMISRC_NMIENM4_MASK (0x80000000U) +#define SYSCON_NMISRC_NMIENM4_SHIFT (31U) +#define SYSCON_NMISRC_NMIENM4(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_NMISRC_NMIENM4_SHIFT)) & SYSCON_NMISRC_NMIENM4_MASK) + +/*! @name ASYNCAPBCTRL - Asynchronous APB Control */ +#define SYSCON_ASYNCAPBCTRL_ENABLE_MASK (0x1U) +#define SYSCON_ASYNCAPBCTRL_ENABLE_SHIFT (0U) +#define SYSCON_ASYNCAPBCTRL_ENABLE(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_ASYNCAPBCTRL_ENABLE_SHIFT)) & SYSCON_ASYNCAPBCTRL_ENABLE_MASK) + +/*! @name SYSRSTSTAT - System reset status register */ +#define SYSCON_SYSRSTSTAT_POR_MASK (0x1U) +#define SYSCON_SYSRSTSTAT_POR_SHIFT (0U) +#define SYSCON_SYSRSTSTAT_POR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSRSTSTAT_POR_SHIFT)) & SYSCON_SYSRSTSTAT_POR_MASK) +#define SYSCON_SYSRSTSTAT_EXTRST_MASK (0x2U) +#define SYSCON_SYSRSTSTAT_EXTRST_SHIFT (1U) +#define SYSCON_SYSRSTSTAT_EXTRST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSRSTSTAT_EXTRST_SHIFT)) & SYSCON_SYSRSTSTAT_EXTRST_MASK) +#define SYSCON_SYSRSTSTAT_WDT_MASK (0x4U) +#define SYSCON_SYSRSTSTAT_WDT_SHIFT (2U) +#define SYSCON_SYSRSTSTAT_WDT(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSRSTSTAT_WDT_SHIFT)) & SYSCON_SYSRSTSTAT_WDT_MASK) +#define SYSCON_SYSRSTSTAT_BOD_MASK (0x8U) +#define SYSCON_SYSRSTSTAT_BOD_SHIFT (3U) +#define SYSCON_SYSRSTSTAT_BOD(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSRSTSTAT_BOD_SHIFT)) & SYSCON_SYSRSTSTAT_BOD_MASK) +#define SYSCON_SYSRSTSTAT_SYSRST_MASK (0x10U) +#define SYSCON_SYSRSTSTAT_SYSRST_SHIFT (4U) +#define SYSCON_SYSRSTSTAT_SYSRST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSRSTSTAT_SYSRST_SHIFT)) & SYSCON_SYSRSTSTAT_SYSRST_MASK) + +/*! @name PRESETCTRL - Peripheral reset control n */ +#define SYSCON_PRESETCTRL_MRT_RST_MASK (0x1U) +#define SYSCON_PRESETCTRL_MRT_RST_SHIFT (0U) +#define SYSCON_PRESETCTRL_MRT_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_MRT_RST_SHIFT)) & SYSCON_PRESETCTRL_MRT_RST_MASK) +#define SYSCON_PRESETCTRL_RIT_RST_MASK (0x2U) +#define SYSCON_PRESETCTRL_RIT_RST_SHIFT (1U) +#define SYSCON_PRESETCTRL_RIT_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_RIT_RST_SHIFT)) & SYSCON_PRESETCTRL_RIT_RST_MASK) +#define SYSCON_PRESETCTRL_SCT0_RST_MASK (0x4U) +#define SYSCON_PRESETCTRL_SCT0_RST_SHIFT (2U) +#define SYSCON_PRESETCTRL_SCT0_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_SCT0_RST_SHIFT)) & SYSCON_PRESETCTRL_SCT0_RST_MASK) +#define SYSCON_PRESETCTRL_FLASH_RST_MASK (0x80U) +#define SYSCON_PRESETCTRL_FLASH_RST_SHIFT (7U) +#define SYSCON_PRESETCTRL_FLASH_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_FLASH_RST_SHIFT)) & SYSCON_PRESETCTRL_FLASH_RST_MASK) +#define SYSCON_PRESETCTRL_FMC_RST_MASK (0x100U) +#define SYSCON_PRESETCTRL_FMC_RST_SHIFT (8U) +#define SYSCON_PRESETCTRL_FMC_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_FMC_RST_SHIFT)) & SYSCON_PRESETCTRL_FMC_RST_MASK) +#define SYSCON_PRESETCTRL_FIFO_RST_MASK (0x200U) +#define SYSCON_PRESETCTRL_FIFO_RST_SHIFT (9U) +#define SYSCON_PRESETCTRL_FIFO_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_FIFO_RST_SHIFT)) & SYSCON_PRESETCTRL_FIFO_RST_MASK) +#define SYSCON_PRESETCTRL_UTICK_RST_MASK (0x400U) +#define SYSCON_PRESETCTRL_UTICK_RST_SHIFT (10U) +#define SYSCON_PRESETCTRL_UTICK_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_UTICK_RST_SHIFT)) & SYSCON_PRESETCTRL_UTICK_RST_MASK) +#define SYSCON_PRESETCTRL_MUX_RST_MASK (0x800U) +#define SYSCON_PRESETCTRL_MUX_RST_SHIFT (11U) +#define SYSCON_PRESETCTRL_MUX_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_MUX_RST_SHIFT)) & SYSCON_PRESETCTRL_MUX_RST_MASK) +#define SYSCON_PRESETCTRL_IOCON_RST_MASK (0x2000U) +#define SYSCON_PRESETCTRL_IOCON_RST_SHIFT (13U) +#define SYSCON_PRESETCTRL_IOCON_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_IOCON_RST_SHIFT)) & SYSCON_PRESETCTRL_IOCON_RST_MASK) +#define SYSCON_PRESETCTRL_GPIO0_RST_MASK (0x4000U) +#define SYSCON_PRESETCTRL_GPIO0_RST_SHIFT (14U) +#define SYSCON_PRESETCTRL_GPIO0_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_GPIO0_RST_SHIFT)) & SYSCON_PRESETCTRL_GPIO0_RST_MASK) +#define SYSCON_PRESETCTRL_GPIO1_RST_MASK (0x8000U) +#define SYSCON_PRESETCTRL_GPIO1_RST_SHIFT (15U) +#define SYSCON_PRESETCTRL_GPIO1_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_GPIO1_RST_SHIFT)) & SYSCON_PRESETCTRL_GPIO1_RST_MASK) +#define SYSCON_PRESETCTRL_PINT_RST_MASK (0x40000U) +#define SYSCON_PRESETCTRL_PINT_RST_SHIFT (18U) +#define SYSCON_PRESETCTRL_PINT_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_PINT_RST_SHIFT)) & SYSCON_PRESETCTRL_PINT_RST_MASK) +#define SYSCON_PRESETCTRL_GINT_RST_MASK (0x80000U) +#define SYSCON_PRESETCTRL_GINT_RST_SHIFT (19U) +#define SYSCON_PRESETCTRL_GINT_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_GINT_RST_SHIFT)) & SYSCON_PRESETCTRL_GINT_RST_MASK) +#define SYSCON_PRESETCTRL_DMA_RST_MASK (0x100000U) +#define SYSCON_PRESETCTRL_DMA_RST_SHIFT (20U) +#define SYSCON_PRESETCTRL_DMA_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_DMA_RST_SHIFT)) & SYSCON_PRESETCTRL_DMA_RST_MASK) +#define SYSCON_PRESETCTRL_CRC_RST_MASK (0x200000U) +#define SYSCON_PRESETCTRL_CRC_RST_SHIFT (21U) +#define SYSCON_PRESETCTRL_CRC_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_CRC_RST_SHIFT)) & SYSCON_PRESETCTRL_CRC_RST_MASK) +#define SYSCON_PRESETCTRL_CT32B2_RST_MASK (0x400000U) +#define SYSCON_PRESETCTRL_CT32B2_RST_SHIFT (22U) +#define SYSCON_PRESETCTRL_CT32B2_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_CT32B2_RST_SHIFT)) & SYSCON_PRESETCTRL_CT32B2_RST_MASK) +#define SYSCON_PRESETCTRL_WWDT_RST_MASK (0x400000U) +#define SYSCON_PRESETCTRL_WWDT_RST_SHIFT (22U) +#define SYSCON_PRESETCTRL_WWDT_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_WWDT_RST_SHIFT)) & SYSCON_PRESETCTRL_WWDT_RST_MASK) +#define SYSCON_PRESETCTRL_CT32B3_RST_MASK (0x4000000U) +#define SYSCON_PRESETCTRL_CT32B3_RST_SHIFT (26U) +#define SYSCON_PRESETCTRL_CT32B3_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_CT32B3_RST_SHIFT)) & SYSCON_PRESETCTRL_CT32B3_RST_MASK) +#define SYSCON_PRESETCTRL_ADC0_RST_MASK (0x8000000U) +#define SYSCON_PRESETCTRL_ADC0_RST_SHIFT (27U) +#define SYSCON_PRESETCTRL_ADC0_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_ADC0_RST_SHIFT)) & SYSCON_PRESETCTRL_ADC0_RST_MASK) +#define SYSCON_PRESETCTRL_CT32B4_RST_MASK (0x8000000U) +#define SYSCON_PRESETCTRL_CT32B4_RST_SHIFT (27U) +#define SYSCON_PRESETCTRL_CT32B4_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_CT32B4_RST_SHIFT)) & SYSCON_PRESETCTRL_CT32B4_RST_MASK) + +/* The count of SYSCON_PRESETCTRL */ +#define SYSCON_PRESETCTRL_COUNT (2U) + +/*! @name PRESETCTRLSET - Set bits in PRESETCTRL n */ +#define SYSCON_PRESETCTRLSET_RST_SET_MASK (0xFFFFFFFFU) +#define SYSCON_PRESETCTRLSET_RST_SET_SHIFT (0U) +#define SYSCON_PRESETCTRLSET_RST_SET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET_RST_SET_MASK) + +/* The count of SYSCON_PRESETCTRLSET */ +#define SYSCON_PRESETCTRLSET_COUNT (2U) + +/*! @name PRESETCTRLCLR - Clear bits in PRESETCTRL n */ +#define SYSCON_PRESETCTRLCLR_RST_CLR_MASK (0xFFFFFFFFU) +#define SYSCON_PRESETCTRLCLR_RST_CLR_SHIFT (0U) +#define SYSCON_PRESETCTRLCLR_RST_CLR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR_RST_CLR_MASK) + +/* The count of SYSCON_PRESETCTRLCLR */ +#define SYSCON_PRESETCTRLCLR_COUNT (2U) + +/*! @name PIOPORCAP0 - POR captured PIO status 0 */ +#define SYSCON_PIOPORCAP0_PIOPORSTAT_MASK (0xFFFFFFFFU) +#define SYSCON_PIOPORCAP0_PIOPORSTAT_SHIFT (0U) +#define SYSCON_PIOPORCAP0_PIOPORSTAT(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PIOPORCAP0_PIOPORSTAT_SHIFT)) & SYSCON_PIOPORCAP0_PIOPORSTAT_MASK) + +/*! @name PIOPORCAP1 - POR captured PIO status 1 */ +#define SYSCON_PIOPORCAP1_PIOPORSTAT_MASK (0xFFFFFFFFU) +#define SYSCON_PIOPORCAP1_PIOPORSTAT_SHIFT (0U) +#define SYSCON_PIOPORCAP1_PIOPORSTAT(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PIOPORCAP1_PIOPORSTAT_SHIFT)) & SYSCON_PIOPORCAP1_PIOPORSTAT_MASK) + +/*! @name PIORESCAP0 - Reset captured PIO status 0 */ +#define SYSCON_PIORESCAP0_PIORESSTAT_MASK (0xFFFFFFFFU) +#define SYSCON_PIORESCAP0_PIORESSTAT_SHIFT (0U) +#define SYSCON_PIORESCAP0_PIORESSTAT(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PIORESCAP0_PIORESSTAT_SHIFT)) & SYSCON_PIORESCAP0_PIORESSTAT_MASK) + +/*! @name PIORESCAP1 - Reset captured PIO status 1 */ +#define SYSCON_PIORESCAP1_PIORESSTAT_MASK (0xFFFFFFFFU) +#define SYSCON_PIORESCAP1_PIORESSTAT_SHIFT (0U) +#define SYSCON_PIORESCAP1_PIORESSTAT(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PIORESCAP1_PIORESSTAT_SHIFT)) & SYSCON_PIORESCAP1_PIORESSTAT_MASK) + +/*! @name MAINCLKSELA - Main clock source select A */ +#define SYSCON_MAINCLKSELA_SEL_MASK (0x3U) +#define SYSCON_MAINCLKSELA_SEL_SHIFT (0U) +#define SYSCON_MAINCLKSELA_SEL(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_MAINCLKSELA_SEL_SHIFT)) & SYSCON_MAINCLKSELA_SEL_MASK) + +/*! @name MAINCLKSELB - Main clock source select B */ +#define SYSCON_MAINCLKSELB_SEL_MASK (0x3U) +#define SYSCON_MAINCLKSELB_SEL_SHIFT (0U) +#define SYSCON_MAINCLKSELB_SEL(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_MAINCLKSELB_SEL_SHIFT)) & SYSCON_MAINCLKSELB_SEL_MASK) + +/*! @name ADCCLKSEL - ADC clock source select */ +#define SYSCON_ADCCLKSEL_SEL_MASK (0x3U) +#define SYSCON_ADCCLKSEL_SEL_SHIFT (0U) +#define SYSCON_ADCCLKSEL_SEL(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_ADCCLKSEL_SEL_SHIFT)) & SYSCON_ADCCLKSEL_SEL_MASK) + +/*! @name CLKOUTSELA - CLKOUT clock source select A */ +#define SYSCON_CLKOUTSELA_SEL_MASK (0x3U) +#define SYSCON_CLKOUTSELA_SEL_SHIFT (0U) +#define SYSCON_CLKOUTSELA_SEL(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_CLKOUTSELA_SEL_SHIFT)) & SYSCON_CLKOUTSELA_SEL_MASK) + +/*! @name CLKOUTSELB - CLKOUT clock source select B */ +#define SYSCON_CLKOUTSELB_SEL_MASK (0x3U) +#define SYSCON_CLKOUTSELB_SEL_SHIFT (0U) +#define SYSCON_CLKOUTSELB_SEL(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_CLKOUTSELB_SEL_SHIFT)) & SYSCON_CLKOUTSELB_SEL_MASK) + +/*! @name SYSPLLCLKSEL - PLL clock source select */ +#define SYSCON_SYSPLLCLKSEL_SEL_MASK (0x3U) +#define SYSCON_SYSPLLCLKSEL_SEL_SHIFT (0U) +#define SYSCON_SYSPLLCLKSEL_SEL(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLCLKSEL_SEL_SHIFT)) & SYSCON_SYSPLLCLKSEL_SEL_MASK) + +/*! @name AHBCLKCTRL - AHB Clock control n */ +#define SYSCON_AHBCLKCTRL_MRT_MASK (0x1U) +#define SYSCON_AHBCLKCTRL_MRT_SHIFT (0U) +#define SYSCON_AHBCLKCTRL_MRT(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_MRT_SHIFT)) & SYSCON_AHBCLKCTRL_MRT_MASK) +#define SYSCON_AHBCLKCTRL_ROM_MASK (0x2U) +#define SYSCON_AHBCLKCTRL_ROM_SHIFT (1U) +#define SYSCON_AHBCLKCTRL_ROM(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_ROM_SHIFT)) & SYSCON_AHBCLKCTRL_ROM_MASK) +#define SYSCON_AHBCLKCTRL_RIT_MASK (0x2U) +#define SYSCON_AHBCLKCTRL_RIT_SHIFT (1U) +#define SYSCON_AHBCLKCTRL_RIT(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_RIT_SHIFT)) & SYSCON_AHBCLKCTRL_RIT_MASK) +#define SYSCON_AHBCLKCTRL_SCT0_MASK (0x4U) +#define SYSCON_AHBCLKCTRL_SCT0_SHIFT (2U) +#define SYSCON_AHBCLKCTRL_SCT0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_SCT0_SHIFT)) & SYSCON_AHBCLKCTRL_SCT0_MASK) +#define SYSCON_AHBCLKCTRL_SRAM1_MASK (0x8U) +#define SYSCON_AHBCLKCTRL_SRAM1_SHIFT (3U) +#define SYSCON_AHBCLKCTRL_SRAM1(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_SRAM1_SHIFT)) & SYSCON_AHBCLKCTRL_SRAM1_MASK) +#define SYSCON_AHBCLKCTRL_SRAM2_MASK (0x10U) +#define SYSCON_AHBCLKCTRL_SRAM2_SHIFT (4U) +#define SYSCON_AHBCLKCTRL_SRAM2(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_SRAM2_SHIFT)) & SYSCON_AHBCLKCTRL_SRAM2_MASK) +#define SYSCON_AHBCLKCTRL_FLASH_MASK (0x80U) +#define SYSCON_AHBCLKCTRL_FLASH_SHIFT (7U) +#define SYSCON_AHBCLKCTRL_FLASH(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_FLASH_SHIFT)) & SYSCON_AHBCLKCTRL_FLASH_MASK) +#define SYSCON_AHBCLKCTRL_FMC_MASK (0x100U) +#define SYSCON_AHBCLKCTRL_FMC_SHIFT (8U) +#define SYSCON_AHBCLKCTRL_FMC(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_FMC_SHIFT)) & SYSCON_AHBCLKCTRL_FMC_MASK) +#define SYSCON_AHBCLKCTRL_FIFO_MASK (0x200U) +#define SYSCON_AHBCLKCTRL_FIFO_SHIFT (9U) +#define SYSCON_AHBCLKCTRL_FIFO(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_FIFO_SHIFT)) & SYSCON_AHBCLKCTRL_FIFO_MASK) +#define SYSCON_AHBCLKCTRL_UTICK_MASK (0x400U) +#define SYSCON_AHBCLKCTRL_UTICK_SHIFT (10U) +#define SYSCON_AHBCLKCTRL_UTICK(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_UTICK_SHIFT)) & SYSCON_AHBCLKCTRL_UTICK_MASK) +#define SYSCON_AHBCLKCTRL_INPUTMUX_MASK (0x800U) +#define SYSCON_AHBCLKCTRL_INPUTMUX_SHIFT (11U) +#define SYSCON_AHBCLKCTRL_INPUTMUX(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_INPUTMUX_SHIFT)) & SYSCON_AHBCLKCTRL_INPUTMUX_MASK) +#define SYSCON_AHBCLKCTRL_IOCON_MASK (0x2000U) +#define SYSCON_AHBCLKCTRL_IOCON_SHIFT (13U) +#define SYSCON_AHBCLKCTRL_IOCON(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_IOCON_SHIFT)) & SYSCON_AHBCLKCTRL_IOCON_MASK) +#define SYSCON_AHBCLKCTRL_GPIO0_MASK (0x4000U) +#define SYSCON_AHBCLKCTRL_GPIO0_SHIFT (14U) +#define SYSCON_AHBCLKCTRL_GPIO0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_GPIO0_SHIFT)) & SYSCON_AHBCLKCTRL_GPIO0_MASK) +#define SYSCON_AHBCLKCTRL_GPIO1_MASK (0x8000U) +#define SYSCON_AHBCLKCTRL_GPIO1_SHIFT (15U) +#define SYSCON_AHBCLKCTRL_GPIO1(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_GPIO1_SHIFT)) & SYSCON_AHBCLKCTRL_GPIO1_MASK) +#define SYSCON_AHBCLKCTRL_PINT_MASK (0x40000U) +#define SYSCON_AHBCLKCTRL_PINT_SHIFT (18U) +#define SYSCON_AHBCLKCTRL_PINT(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_PINT_SHIFT)) & SYSCON_AHBCLKCTRL_PINT_MASK) +#define SYSCON_AHBCLKCTRL_GINT_MASK (0x80000U) +#define SYSCON_AHBCLKCTRL_GINT_SHIFT (19U) +#define SYSCON_AHBCLKCTRL_GINT(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_GINT_SHIFT)) & SYSCON_AHBCLKCTRL_GINT_MASK) +#define SYSCON_AHBCLKCTRL_DMA_MASK (0x100000U) +#define SYSCON_AHBCLKCTRL_DMA_SHIFT (20U) +#define SYSCON_AHBCLKCTRL_DMA(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_DMA_SHIFT)) & SYSCON_AHBCLKCTRL_DMA_MASK) +#define SYSCON_AHBCLKCTRL_CRC_MASK (0x200000U) +#define SYSCON_AHBCLKCTRL_CRC_SHIFT (21U) +#define SYSCON_AHBCLKCTRL_CRC(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_CRC_SHIFT)) & SYSCON_AHBCLKCTRL_CRC_MASK) +#define SYSCON_AHBCLKCTRL_CT32B2_MASK (0x400000U) +#define SYSCON_AHBCLKCTRL_CT32B2_SHIFT (22U) +#define SYSCON_AHBCLKCTRL_CT32B2(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_CT32B2_SHIFT)) & SYSCON_AHBCLKCTRL_CT32B2_MASK) +#define SYSCON_AHBCLKCTRL_WWDT_MASK (0x400000U) +#define SYSCON_AHBCLKCTRL_WWDT_SHIFT (22U) +#define SYSCON_AHBCLKCTRL_WWDT(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_WWDT_SHIFT)) & SYSCON_AHBCLKCTRL_WWDT_MASK) +#define SYSCON_AHBCLKCTRL_RTC_MASK (0x800000U) +#define SYSCON_AHBCLKCTRL_RTC_SHIFT (23U) +#define SYSCON_AHBCLKCTRL_RTC(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_RTC_SHIFT)) & SYSCON_AHBCLKCTRL_RTC_MASK) +#define SYSCON_AHBCLKCTRL_CT32B3_MASK (0x4000000U) +#define SYSCON_AHBCLKCTRL_CT32B3_SHIFT (26U) +#define SYSCON_AHBCLKCTRL_CT32B3(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_CT32B3_SHIFT)) & SYSCON_AHBCLKCTRL_CT32B3_MASK) +#define SYSCON_AHBCLKCTRL_MAILBOX_MASK (0x4000000U) +#define SYSCON_AHBCLKCTRL_MAILBOX_SHIFT (26U) +#define SYSCON_AHBCLKCTRL_MAILBOX(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_MAILBOX_SHIFT)) & SYSCON_AHBCLKCTRL_MAILBOX_MASK) +#define SYSCON_AHBCLKCTRL_CT32B4_MASK (0x8000000U) +#define SYSCON_AHBCLKCTRL_CT32B4_SHIFT (27U) +#define SYSCON_AHBCLKCTRL_CT32B4(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_CT32B4_SHIFT)) & SYSCON_AHBCLKCTRL_CT32B4_MASK) +#define SYSCON_AHBCLKCTRL_ADC0_MASK (0x8000000U) +#define SYSCON_AHBCLKCTRL_ADC0_SHIFT (27U) +#define SYSCON_AHBCLKCTRL_ADC0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_ADC0_SHIFT)) & SYSCON_AHBCLKCTRL_ADC0_MASK) + +/* The count of SYSCON_AHBCLKCTRL */ +#define SYSCON_AHBCLKCTRL_COUNT (2U) + +/*! @name AHBCLKCTRLSET - Set bits in AHBCLKCTRL n */ +#define SYSCON_AHBCLKCTRLSET_CLK_SET_MASK (0xFFFFFFFFU) +#define SYSCON_AHBCLKCTRLSET_CLK_SET_SHIFT (0U) +#define SYSCON_AHBCLKCTRLSET_CLK_SET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET_CLK_SET_MASK) + +/* The count of SYSCON_AHBCLKCTRLSET */ +#define SYSCON_AHBCLKCTRLSET_COUNT (2U) + +/*! @name AHBCLKCTRLCLR - Clear bits in AHBCLKCTRL n */ +#define SYSCON_AHBCLKCTRLCLR_CLK_CLR_MASK (0xFFFFFFFFU) +#define SYSCON_AHBCLKCTRLCLR_CLK_CLR_SHIFT (0U) +#define SYSCON_AHBCLKCTRLCLR_CLK_CLR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR_CLK_CLR_MASK) + +/* The count of SYSCON_AHBCLKCTRLCLR */ +#define SYSCON_AHBCLKCTRLCLR_COUNT (2U) + +/*! @name SYSTICKCLKDIV - SYSTICK clock divider */ +#define SYSCON_SYSTICKCLKDIV_DIV_MASK (0xFFU) +#define SYSCON_SYSTICKCLKDIV_DIV_SHIFT (0U) +#define SYSCON_SYSTICKCLKDIV_DIV(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSTICKCLKDIV_DIV_SHIFT)) & SYSCON_SYSTICKCLKDIV_DIV_MASK) + +/*! @name AHBCLKDIV - System clock divider */ +#define SYSCON_AHBCLKDIV_DIV_MASK (0xFFU) +#define SYSCON_AHBCLKDIV_DIV_SHIFT (0U) +#define SYSCON_AHBCLKDIV_DIV(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKDIV_DIV_SHIFT)) & SYSCON_AHBCLKDIV_DIV_MASK) + +/*! @name ADCCLKDIV - ADC clock divider */ +#define SYSCON_ADCCLKDIV_DIV_MASK (0xFFU) +#define SYSCON_ADCCLKDIV_DIV_SHIFT (0U) +#define SYSCON_ADCCLKDIV_DIV(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_ADCCLKDIV_DIV_SHIFT)) & SYSCON_ADCCLKDIV_DIV_MASK) + +/*! @name CLKOUTDIV - CLKOUT clock divider */ +#define SYSCON_CLKOUTDIV_DIV_MASK (0xFFU) +#define SYSCON_CLKOUTDIV_DIV_SHIFT (0U) +#define SYSCON_CLKOUTDIV_DIV(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_CLKOUTDIV_DIV_SHIFT)) & SYSCON_CLKOUTDIV_DIV_MASK) + +/*! @name FREQMECTRL - Frequency measure register */ +#define SYSCON_FREQMECTRL_CAPVAL_MASK (0x3FFFU) +#define SYSCON_FREQMECTRL_CAPVAL_SHIFT (0U) +#define SYSCON_FREQMECTRL_CAPVAL(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FREQMECTRL_CAPVAL_SHIFT)) & SYSCON_FREQMECTRL_CAPVAL_MASK) +#define SYSCON_FREQMECTRL_PROG_MASK (0x80000000U) +#define SYSCON_FREQMECTRL_PROG_SHIFT (31U) +#define SYSCON_FREQMECTRL_PROG(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FREQMECTRL_PROG_SHIFT)) & SYSCON_FREQMECTRL_PROG_MASK) + +/*! @name FLASHCFG - Flash wait states configuration */ +#define SYSCON_FLASHCFG_FETCHCFG_MASK (0x3U) +#define SYSCON_FLASHCFG_FETCHCFG_SHIFT (0U) +#define SYSCON_FLASHCFG_FETCHCFG(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FLASHCFG_FETCHCFG_SHIFT)) & SYSCON_FLASHCFG_FETCHCFG_MASK) +#define SYSCON_FLASHCFG_DATACFG_MASK (0xCU) +#define SYSCON_FLASHCFG_DATACFG_SHIFT (2U) +#define SYSCON_FLASHCFG_DATACFG(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FLASHCFG_DATACFG_SHIFT)) & SYSCON_FLASHCFG_DATACFG_MASK) +#define SYSCON_FLASHCFG_ACCEL_MASK (0x10U) +#define SYSCON_FLASHCFG_ACCEL_SHIFT (4U) +#define SYSCON_FLASHCFG_ACCEL(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FLASHCFG_ACCEL_SHIFT)) & SYSCON_FLASHCFG_ACCEL_MASK) +#define SYSCON_FLASHCFG_PREFEN_MASK (0x20U) +#define SYSCON_FLASHCFG_PREFEN_SHIFT (5U) +#define SYSCON_FLASHCFG_PREFEN(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FLASHCFG_PREFEN_SHIFT)) & SYSCON_FLASHCFG_PREFEN_MASK) +#define SYSCON_FLASHCFG_PREFOVR_MASK (0x40U) +#define SYSCON_FLASHCFG_PREFOVR_SHIFT (6U) +#define SYSCON_FLASHCFG_PREFOVR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FLASHCFG_PREFOVR_SHIFT)) & SYSCON_FLASHCFG_PREFOVR_MASK) +#define SYSCON_FLASHCFG_FLASHTIM_MASK (0xF000U) +#define SYSCON_FLASHCFG_FLASHTIM_SHIFT (12U) +#define SYSCON_FLASHCFG_FLASHTIM(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FLASHCFG_FLASHTIM_SHIFT)) & SYSCON_FLASHCFG_FLASHTIM_MASK) + +/*! @name FIFOCTRL - Serial interface FIFO enables */ +#define SYSCON_FIFOCTRL_U0TXFIFOEN_MASK (0x1U) +#define SYSCON_FIFOCTRL_U0TXFIFOEN_SHIFT (0U) +#define SYSCON_FIFOCTRL_U0TXFIFOEN(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FIFOCTRL_U0TXFIFOEN_SHIFT)) & SYSCON_FIFOCTRL_U0TXFIFOEN_MASK) +#define SYSCON_FIFOCTRL_U1TXFIFOEN_MASK (0x2U) +#define SYSCON_FIFOCTRL_U1TXFIFOEN_SHIFT (1U) +#define SYSCON_FIFOCTRL_U1TXFIFOEN(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FIFOCTRL_U1TXFIFOEN_SHIFT)) & SYSCON_FIFOCTRL_U1TXFIFOEN_MASK) +#define SYSCON_FIFOCTRL_U2TXFIFOEN_MASK (0x4U) +#define SYSCON_FIFOCTRL_U2TXFIFOEN_SHIFT (2U) +#define SYSCON_FIFOCTRL_U2TXFIFOEN(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FIFOCTRL_U2TXFIFOEN_SHIFT)) & SYSCON_FIFOCTRL_U2TXFIFOEN_MASK) +#define SYSCON_FIFOCTRL_U3TXFIFOEN_MASK (0x8U) +#define SYSCON_FIFOCTRL_U3TXFIFOEN_SHIFT (3U) +#define SYSCON_FIFOCTRL_U3TXFIFOEN(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FIFOCTRL_U3TXFIFOEN_SHIFT)) & SYSCON_FIFOCTRL_U3TXFIFOEN_MASK) +#define SYSCON_FIFOCTRL_SPI0TXFIFOEN_MASK (0x10U) +#define SYSCON_FIFOCTRL_SPI0TXFIFOEN_SHIFT (4U) +#define SYSCON_FIFOCTRL_SPI0TXFIFOEN(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FIFOCTRL_SPI0TXFIFOEN_SHIFT)) & SYSCON_FIFOCTRL_SPI0TXFIFOEN_MASK) +#define SYSCON_FIFOCTRL_SPI1TXFIFOEN_MASK (0x20U) +#define SYSCON_FIFOCTRL_SPI1TXFIFOEN_SHIFT (5U) +#define SYSCON_FIFOCTRL_SPI1TXFIFOEN(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FIFOCTRL_SPI1TXFIFOEN_SHIFT)) & SYSCON_FIFOCTRL_SPI1TXFIFOEN_MASK) +#define SYSCON_FIFOCTRL_U0RXFIFOEN_MASK (0x100U) +#define SYSCON_FIFOCTRL_U0RXFIFOEN_SHIFT (8U) +#define SYSCON_FIFOCTRL_U0RXFIFOEN(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FIFOCTRL_U0RXFIFOEN_SHIFT)) & SYSCON_FIFOCTRL_U0RXFIFOEN_MASK) +#define SYSCON_FIFOCTRL_U1RXFIFOEN_MASK (0x200U) +#define SYSCON_FIFOCTRL_U1RXFIFOEN_SHIFT (9U) +#define SYSCON_FIFOCTRL_U1RXFIFOEN(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FIFOCTRL_U1RXFIFOEN_SHIFT)) & SYSCON_FIFOCTRL_U1RXFIFOEN_MASK) +#define SYSCON_FIFOCTRL_U2RXFIFOEN_MASK (0x400U) +#define SYSCON_FIFOCTRL_U2RXFIFOEN_SHIFT (10U) +#define SYSCON_FIFOCTRL_U2RXFIFOEN(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FIFOCTRL_U2RXFIFOEN_SHIFT)) & SYSCON_FIFOCTRL_U2RXFIFOEN_MASK) +#define SYSCON_FIFOCTRL_U3RXFIFOEN_MASK (0x800U) +#define SYSCON_FIFOCTRL_U3RXFIFOEN_SHIFT (11U) +#define SYSCON_FIFOCTRL_U3RXFIFOEN(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FIFOCTRL_U3RXFIFOEN_SHIFT)) & SYSCON_FIFOCTRL_U3RXFIFOEN_MASK) +#define SYSCON_FIFOCTRL_SPI0RXFIFOEN_MASK (0x1000U) +#define SYSCON_FIFOCTRL_SPI0RXFIFOEN_SHIFT (12U) +#define SYSCON_FIFOCTRL_SPI0RXFIFOEN(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FIFOCTRL_SPI0RXFIFOEN_SHIFT)) & SYSCON_FIFOCTRL_SPI0RXFIFOEN_MASK) +#define SYSCON_FIFOCTRL_SPI1RXFIFOEN_MASK (0x2000U) +#define SYSCON_FIFOCTRL_SPI1RXFIFOEN_SHIFT (13U) +#define SYSCON_FIFOCTRL_SPI1RXFIFOEN(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FIFOCTRL_SPI1RXFIFOEN_SHIFT)) & SYSCON_FIFOCTRL_SPI1RXFIFOEN_MASK) + +/*! @name IRCCTRL - IRC oscillator control */ +#define SYSCON_IRCCTRL_TRIM_MASK (0xFFU) +#define SYSCON_IRCCTRL_TRIM_SHIFT (0U) +#define SYSCON_IRCCTRL_TRIM(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_IRCCTRL_TRIM_SHIFT)) & SYSCON_IRCCTRL_TRIM_MASK) + +/*! @name RTCOSCCTRL - RTC oscillator 32 kHz output control */ +#define SYSCON_RTCOSCCTRL_EN_MASK (0x1U) +#define SYSCON_RTCOSCCTRL_EN_SHIFT (0U) +#define SYSCON_RTCOSCCTRL_EN(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_RTCOSCCTRL_EN_SHIFT)) & SYSCON_RTCOSCCTRL_EN_MASK) + +/*! @name SYSPLLCTRL - PLL control */ +#define SYSCON_SYSPLLCTRL_SELR_MASK (0xFU) +#define SYSCON_SYSPLLCTRL_SELR_SHIFT (0U) +#define SYSCON_SYSPLLCTRL_SELR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLCTRL_SELR_SHIFT)) & SYSCON_SYSPLLCTRL_SELR_MASK) +#define SYSCON_SYSPLLCTRL_SELI_MASK (0x3F0U) +#define SYSCON_SYSPLLCTRL_SELI_SHIFT (4U) +#define SYSCON_SYSPLLCTRL_SELI(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLCTRL_SELI_SHIFT)) & SYSCON_SYSPLLCTRL_SELI_MASK) +#define SYSCON_SYSPLLCTRL_SELP_MASK (0x7C00U) +#define SYSCON_SYSPLLCTRL_SELP_SHIFT (10U) +#define SYSCON_SYSPLLCTRL_SELP(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLCTRL_SELP_SHIFT)) & SYSCON_SYSPLLCTRL_SELP_MASK) +#define SYSCON_SYSPLLCTRL_BYPASS_MASK (0x8000U) +#define SYSCON_SYSPLLCTRL_BYPASS_SHIFT (15U) +#define SYSCON_SYSPLLCTRL_BYPASS(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLCTRL_BYPASS_SHIFT)) & SYSCON_SYSPLLCTRL_BYPASS_MASK) +#define SYSCON_SYSPLLCTRL_BYPASSCCODIV2_MASK (0x10000U) +#define SYSCON_SYSPLLCTRL_BYPASSCCODIV2_SHIFT (16U) +#define SYSCON_SYSPLLCTRL_BYPASSCCODIV2(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLCTRL_BYPASSCCODIV2_SHIFT)) & SYSCON_SYSPLLCTRL_BYPASSCCODIV2_MASK) +#define SYSCON_SYSPLLCTRL_UPLIMOFF_MASK (0x20000U) +#define SYSCON_SYSPLLCTRL_UPLIMOFF_SHIFT (17U) +#define SYSCON_SYSPLLCTRL_UPLIMOFF(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLCTRL_UPLIMOFF_SHIFT)) & SYSCON_SYSPLLCTRL_UPLIMOFF_MASK) +#define SYSCON_SYSPLLCTRL_BANDSEL_MASK (0x40000U) +#define SYSCON_SYSPLLCTRL_BANDSEL_SHIFT (18U) +#define SYSCON_SYSPLLCTRL_BANDSEL(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLCTRL_BANDSEL_SHIFT)) & SYSCON_SYSPLLCTRL_BANDSEL_MASK) +#define SYSCON_SYSPLLCTRL_DIRECTI_MASK (0x80000U) +#define SYSCON_SYSPLLCTRL_DIRECTI_SHIFT (19U) +#define SYSCON_SYSPLLCTRL_DIRECTI(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLCTRL_DIRECTI_SHIFT)) & SYSCON_SYSPLLCTRL_DIRECTI_MASK) +#define SYSCON_SYSPLLCTRL_DIRECTO_MASK (0x100000U) +#define SYSCON_SYSPLLCTRL_DIRECTO_SHIFT (20U) +#define SYSCON_SYSPLLCTRL_DIRECTO(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLCTRL_DIRECTO_SHIFT)) & SYSCON_SYSPLLCTRL_DIRECTO_MASK) + +/*! @name SYSPLLSTAT - PLL status */ +#define SYSCON_SYSPLLSTAT_LOCK_MASK (0x1U) +#define SYSCON_SYSPLLSTAT_LOCK_SHIFT (0U) +#define SYSCON_SYSPLLSTAT_LOCK(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLSTAT_LOCK_SHIFT)) & SYSCON_SYSPLLSTAT_LOCK_MASK) + +/*! @name SYSPLLNDEC - PLL N decoder */ +#define SYSCON_SYSPLLNDEC_NDEC_MASK (0x3FFU) +#define SYSCON_SYSPLLNDEC_NDEC_SHIFT (0U) +#define SYSCON_SYSPLLNDEC_NDEC(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLNDEC_NDEC_SHIFT)) & SYSCON_SYSPLLNDEC_NDEC_MASK) +#define SYSCON_SYSPLLNDEC_NREQ_MASK (0x400U) +#define SYSCON_SYSPLLNDEC_NREQ_SHIFT (10U) +#define SYSCON_SYSPLLNDEC_NREQ(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLNDEC_NREQ_SHIFT)) & SYSCON_SYSPLLNDEC_NREQ_MASK) + +/*! @name SYSPLLPDEC - PLL P decoder */ +#define SYSCON_SYSPLLPDEC_PDEC_MASK (0x7FU) +#define SYSCON_SYSPLLPDEC_PDEC_SHIFT (0U) +#define SYSCON_SYSPLLPDEC_PDEC(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLPDEC_PDEC_SHIFT)) & SYSCON_SYSPLLPDEC_PDEC_MASK) +#define SYSCON_SYSPLLPDEC_PREQ_MASK (0x80U) +#define SYSCON_SYSPLLPDEC_PREQ_SHIFT (7U) +#define SYSCON_SYSPLLPDEC_PREQ(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLPDEC_PREQ_SHIFT)) & SYSCON_SYSPLLPDEC_PREQ_MASK) + +/*! @name SYSPLLSSCTRL0 - PLL spread spectrum control 0 */ +#define SYSCON_SYSPLLSSCTRL0_MDEC_MASK (0x1FFFFU) +#define SYSCON_SYSPLLSSCTRL0_MDEC_SHIFT (0U) +#define SYSCON_SYSPLLSSCTRL0_MDEC(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLSSCTRL0_MDEC_SHIFT)) & SYSCON_SYSPLLSSCTRL0_MDEC_MASK) +#define SYSCON_SYSPLLSSCTRL0_MREQ_MASK (0x20000U) +#define SYSCON_SYSPLLSSCTRL0_MREQ_SHIFT (17U) +#define SYSCON_SYSPLLSSCTRL0_MREQ(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLSSCTRL0_MREQ_SHIFT)) & SYSCON_SYSPLLSSCTRL0_MREQ_MASK) +#define SYSCON_SYSPLLSSCTRL0_SEL_EXT_MASK (0x40000U) +#define SYSCON_SYSPLLSSCTRL0_SEL_EXT_SHIFT (18U) +#define SYSCON_SYSPLLSSCTRL0_SEL_EXT(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLSSCTRL0_SEL_EXT_SHIFT)) & SYSCON_SYSPLLSSCTRL0_SEL_EXT_MASK) + +/*! @name SYSPLLSSCTRL1 - PLL spread spectrum control 1 */ +#define SYSCON_SYSPLLSSCTRL1_MD_MASK (0x7FFFFU) +#define SYSCON_SYSPLLSSCTRL1_MD_SHIFT (0U) +#define SYSCON_SYSPLLSSCTRL1_MD(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLSSCTRL1_MD_SHIFT)) & SYSCON_SYSPLLSSCTRL1_MD_MASK) +#define SYSCON_SYSPLLSSCTRL1_MDREQ_MASK (0x80000U) +#define SYSCON_SYSPLLSSCTRL1_MDREQ_SHIFT (19U) +#define SYSCON_SYSPLLSSCTRL1_MDREQ(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLSSCTRL1_MDREQ_SHIFT)) & SYSCON_SYSPLLSSCTRL1_MDREQ_MASK) +#define SYSCON_SYSPLLSSCTRL1_MF_MASK (0x700000U) +#define SYSCON_SYSPLLSSCTRL1_MF_SHIFT (20U) +#define SYSCON_SYSPLLSSCTRL1_MF(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLSSCTRL1_MF_SHIFT)) & SYSCON_SYSPLLSSCTRL1_MF_MASK) +#define SYSCON_SYSPLLSSCTRL1_MR_MASK (0x3800000U) +#define SYSCON_SYSPLLSSCTRL1_MR_SHIFT (23U) +#define SYSCON_SYSPLLSSCTRL1_MR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLSSCTRL1_MR_SHIFT)) & SYSCON_SYSPLLSSCTRL1_MR_MASK) +#define SYSCON_SYSPLLSSCTRL1_MC_MASK (0xC000000U) +#define SYSCON_SYSPLLSSCTRL1_MC_SHIFT (26U) +#define SYSCON_SYSPLLSSCTRL1_MC(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLSSCTRL1_MC_SHIFT)) & SYSCON_SYSPLLSSCTRL1_MC_MASK) +#define SYSCON_SYSPLLSSCTRL1_PD_MASK (0x10000000U) +#define SYSCON_SYSPLLSSCTRL1_PD_SHIFT (28U) +#define SYSCON_SYSPLLSSCTRL1_PD(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLSSCTRL1_PD_SHIFT)) & SYSCON_SYSPLLSSCTRL1_PD_MASK) +#define SYSCON_SYSPLLSSCTRL1_DITHER_MASK (0x20000000U) +#define SYSCON_SYSPLLSSCTRL1_DITHER_SHIFT (29U) +#define SYSCON_SYSPLLSSCTRL1_DITHER(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLSSCTRL1_DITHER_SHIFT)) & SYSCON_SYSPLLSSCTRL1_DITHER_MASK) + +/*! @name PDRUNCFG - Power configuration register */ +#define SYSCON_PDRUNCFG_PDEN_IRC_OSC_MASK (0x8U) +#define SYSCON_PDRUNCFG_PDEN_IRC_OSC_SHIFT (3U) +#define SYSCON_PDRUNCFG_PDEN_IRC_OSC(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PDEN_IRC_OSC_SHIFT)) & SYSCON_PDRUNCFG_PDEN_IRC_OSC_MASK) +#define SYSCON_PDRUNCFG_PDEN_IRC_MASK (0x10U) +#define SYSCON_PDRUNCFG_PDEN_IRC_SHIFT (4U) +#define SYSCON_PDRUNCFG_PDEN_IRC(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PDEN_IRC_SHIFT)) & SYSCON_PDRUNCFG_PDEN_IRC_MASK) +#define SYSCON_PDRUNCFG_PDEN_FLASH_MASK (0x20U) +#define SYSCON_PDRUNCFG_PDEN_FLASH_SHIFT (5U) +#define SYSCON_PDRUNCFG_PDEN_FLASH(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PDEN_FLASH_SHIFT)) & SYSCON_PDRUNCFG_PDEN_FLASH_MASK) +#define SYSCON_PDRUNCFG_PDEN_BOD_RST_MASK (0x80U) +#define SYSCON_PDRUNCFG_PDEN_BOD_RST_SHIFT (7U) +#define SYSCON_PDRUNCFG_PDEN_BOD_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PDEN_BOD_RST_SHIFT)) & SYSCON_PDRUNCFG_PDEN_BOD_RST_MASK) +#define SYSCON_PDRUNCFG_PDEN_BOD_INTR_MASK (0x100U) +#define SYSCON_PDRUNCFG_PDEN_BOD_INTR_SHIFT (8U) +#define SYSCON_PDRUNCFG_PDEN_BOD_INTR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PDEN_BOD_INTR_SHIFT)) & SYSCON_PDRUNCFG_PDEN_BOD_INTR_MASK) +#define SYSCON_PDRUNCFG_PDEN_ADC0_MASK (0x400U) +#define SYSCON_PDRUNCFG_PDEN_ADC0_SHIFT (10U) +#define SYSCON_PDRUNCFG_PDEN_ADC0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PDEN_ADC0_SHIFT)) & SYSCON_PDRUNCFG_PDEN_ADC0_MASK) +#define SYSCON_PDRUNCFG_PDEN_SRAM0A_MASK (0x2000U) +#define SYSCON_PDRUNCFG_PDEN_SRAM0A_SHIFT (13U) +#define SYSCON_PDRUNCFG_PDEN_SRAM0A(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PDEN_SRAM0A_SHIFT)) & SYSCON_PDRUNCFG_PDEN_SRAM0A_MASK) +#define SYSCON_PDRUNCFG_PDEN_SRAM0B_MASK (0x4000U) +#define SYSCON_PDRUNCFG_PDEN_SRAM0B_SHIFT (14U) +#define SYSCON_PDRUNCFG_PDEN_SRAM0B(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PDEN_SRAM0B_SHIFT)) & SYSCON_PDRUNCFG_PDEN_SRAM0B_MASK) +#define SYSCON_PDRUNCFG_PDEN_SRAM1_MASK (0x8000U) +#define SYSCON_PDRUNCFG_PDEN_SRAM1_SHIFT (15U) +#define SYSCON_PDRUNCFG_PDEN_SRAM1(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PDEN_SRAM1_SHIFT)) & SYSCON_PDRUNCFG_PDEN_SRAM1_MASK) +#define SYSCON_PDRUNCFG_PDEN_SRAM2_MASK (0x10000U) +#define SYSCON_PDRUNCFG_PDEN_SRAM2_SHIFT (16U) +#define SYSCON_PDRUNCFG_PDEN_SRAM2(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PDEN_SRAM2_SHIFT)) & SYSCON_PDRUNCFG_PDEN_SRAM2_MASK) +#define SYSCON_PDRUNCFG_PDEN_ROM_MASK (0x20000U) +#define SYSCON_PDRUNCFG_PDEN_ROM_SHIFT (17U) +#define SYSCON_PDRUNCFG_PDEN_ROM(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PDEN_ROM_SHIFT)) & SYSCON_PDRUNCFG_PDEN_ROM_MASK) +#define SYSCON_PDRUNCFG_PDEN_VDDA_MASK (0x80000U) +#define SYSCON_PDRUNCFG_PDEN_VDDA_SHIFT (19U) +#define SYSCON_PDRUNCFG_PDEN_VDDA(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PDEN_VDDA_SHIFT)) & SYSCON_PDRUNCFG_PDEN_VDDA_MASK) +#define SYSCON_PDRUNCFG_PDEN_WDT_OSC_MASK (0x100000U) +#define SYSCON_PDRUNCFG_PDEN_WDT_OSC_SHIFT (20U) +#define SYSCON_PDRUNCFG_PDEN_WDT_OSC(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PDEN_WDT_OSC_SHIFT)) & SYSCON_PDRUNCFG_PDEN_WDT_OSC_MASK) +#define SYSCON_PDRUNCFG_PDEN_SYS_PLL_MASK (0x400000U) +#define SYSCON_PDRUNCFG_PDEN_SYS_PLL_SHIFT (22U) +#define SYSCON_PDRUNCFG_PDEN_SYS_PLL(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PDEN_SYS_PLL_SHIFT)) & SYSCON_PDRUNCFG_PDEN_SYS_PLL_MASK) +#define SYSCON_PDRUNCFG_PDEN_VREFP_MASK (0x800000U) +#define SYSCON_PDRUNCFG_PDEN_VREFP_SHIFT (23U) +#define SYSCON_PDRUNCFG_PDEN_VREFP(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PDEN_VREFP_SHIFT)) & SYSCON_PDRUNCFG_PDEN_VREFP_MASK) +#define SYSCON_PDRUNCFG_PDEN_32K_OSC_MASK (0x1000000U) +#define SYSCON_PDRUNCFG_PDEN_32K_OSC_SHIFT (24U) +#define SYSCON_PDRUNCFG_PDEN_32K_OSC(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PDEN_32K_OSC_SHIFT)) & SYSCON_PDRUNCFG_PDEN_32K_OSC_MASK) + +/*! @name PDRUNCFGSET - Set bits in PDRUNCFG */ +#define SYSCON_PDRUNCFGSET_PD_SET_MASK (0xFFFFFFFFU) +#define SYSCON_PDRUNCFGSET_PD_SET_SHIFT (0U) +#define SYSCON_PDRUNCFGSET_PD_SET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFGSET_PD_SET_SHIFT)) & SYSCON_PDRUNCFGSET_PD_SET_MASK) + +/*! @name PDRUNCFGCLR - Clear bits in PDRUNCFG */ +#define SYSCON_PDRUNCFGCLR_PD_CLR_MASK (0xFFFFFFFFU) +#define SYSCON_PDRUNCFGCLR_PD_CLR_SHIFT (0U) +#define SYSCON_PDRUNCFGCLR_PD_CLR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFGCLR_PD_CLR_SHIFT)) & SYSCON_PDRUNCFGCLR_PD_CLR_MASK) + +/*! @name STARTER - Start logic n wake-up enable register */ +#define SYSCON_STARTER_WWDT_MASK (0x1U) +#define SYSCON_STARTER_WWDT_SHIFT (0U) +#define SYSCON_STARTER_WWDT(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_WWDT_SHIFT)) & SYSCON_STARTER_WWDT_MASK) +#define SYSCON_STARTER_GINT1_MASK (0x1U) +#define SYSCON_STARTER_GINT1_SHIFT (0U) +#define SYSCON_STARTER_GINT1(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_GINT1_SHIFT)) & SYSCON_STARTER_GINT1_MASK) +#define SYSCON_STARTER_BOD_MASK (0x2U) +#define SYSCON_STARTER_BOD_SHIFT (1U) +#define SYSCON_STARTER_BOD(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_BOD_SHIFT)) & SYSCON_STARTER_BOD_MASK) +#define SYSCON_STARTER_PINT4_MASK (0x2U) +#define SYSCON_STARTER_PINT4_SHIFT (1U) +#define SYSCON_STARTER_PINT4(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_PINT4_SHIFT)) & SYSCON_STARTER_PINT4_MASK) +#define SYSCON_STARTER_PINT5_MASK (0x4U) +#define SYSCON_STARTER_PINT5_SHIFT (2U) +#define SYSCON_STARTER_PINT5(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_PINT5_SHIFT)) & SYSCON_STARTER_PINT5_MASK) +#define SYSCON_STARTER_DMA_MASK (0x8U) +#define SYSCON_STARTER_DMA_SHIFT (3U) +#define SYSCON_STARTER_DMA(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_DMA_SHIFT)) & SYSCON_STARTER_DMA_MASK) +#define SYSCON_STARTER_PINT6_MASK (0x8U) +#define SYSCON_STARTER_PINT6_SHIFT (3U) +#define SYSCON_STARTER_PINT6(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_PINT6_SHIFT)) & SYSCON_STARTER_PINT6_MASK) +#define SYSCON_STARTER_PINT7_MASK (0x10U) +#define SYSCON_STARTER_PINT7_SHIFT (4U) +#define SYSCON_STARTER_PINT7(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_PINT7_SHIFT)) & SYSCON_STARTER_PINT7_MASK) +#define SYSCON_STARTER_GINT0_MASK (0x10U) +#define SYSCON_STARTER_GINT0_SHIFT (4U) +#define SYSCON_STARTER_GINT0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_GINT0_SHIFT)) & SYSCON_STARTER_GINT0_MASK) +#define SYSCON_STARTER_PINT0_MASK (0x20U) +#define SYSCON_STARTER_PINT0_SHIFT (5U) +#define SYSCON_STARTER_PINT0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_PINT0_SHIFT)) & SYSCON_STARTER_PINT0_MASK) +#define SYSCON_STARTER_PINT1_MASK (0x40U) +#define SYSCON_STARTER_PINT1_SHIFT (6U) +#define SYSCON_STARTER_PINT1(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_PINT1_SHIFT)) & SYSCON_STARTER_PINT1_MASK) +#define SYSCON_STARTER_PINT2_MASK (0x80U) +#define SYSCON_STARTER_PINT2_SHIFT (7U) +#define SYSCON_STARTER_PINT2(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_PINT2_SHIFT)) & SYSCON_STARTER_PINT2_MASK) +#define SYSCON_STARTER_PINT3_MASK (0x100U) +#define SYSCON_STARTER_PINT3_SHIFT (8U) +#define SYSCON_STARTER_PINT3(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_PINT3_SHIFT)) & SYSCON_STARTER_PINT3_MASK) +#define SYSCON_STARTER_RIT_MASK (0x100U) +#define SYSCON_STARTER_RIT_SHIFT (8U) +#define SYSCON_STARTER_RIT(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_RIT_SHIFT)) & SYSCON_STARTER_RIT_MASK) +#define SYSCON_STARTER_UTICK_MASK (0x200U) +#define SYSCON_STARTER_UTICK_SHIFT (9U) +#define SYSCON_STARTER_UTICK(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_UTICK_SHIFT)) & SYSCON_STARTER_UTICK_MASK) +#define SYSCON_STARTER_MRT_MASK (0x400U) +#define SYSCON_STARTER_MRT_SHIFT (10U) +#define SYSCON_STARTER_MRT(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_MRT_SHIFT)) & SYSCON_STARTER_MRT_MASK) +#define SYSCON_STARTER_CT32B0_MASK (0x800U) +#define SYSCON_STARTER_CT32B0_SHIFT (11U) +#define SYSCON_STARTER_CT32B0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_CT32B0_SHIFT)) & SYSCON_STARTER_CT32B0_MASK) +#define SYSCON_STARTER_CT32B1_MASK (0x1000U) +#define SYSCON_STARTER_CT32B1_SHIFT (12U) +#define SYSCON_STARTER_CT32B1(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_CT32B1_SHIFT)) & SYSCON_STARTER_CT32B1_MASK) +#define SYSCON_STARTER_CT32B2_MASK (0x2000U) +#define SYSCON_STARTER_CT32B2_SHIFT (13U) +#define SYSCON_STARTER_CT32B2(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_CT32B2_SHIFT)) & SYSCON_STARTER_CT32B2_MASK) +#define SYSCON_STARTER_CT32B3_MASK (0x4000U) +#define SYSCON_STARTER_CT32B3_SHIFT (14U) +#define SYSCON_STARTER_CT32B3(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_CT32B3_SHIFT)) & SYSCON_STARTER_CT32B3_MASK) +#define SYSCON_STARTER_CT32B4_MASK (0x8000U) +#define SYSCON_STARTER_CT32B4_SHIFT (15U) +#define SYSCON_STARTER_CT32B4(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_CT32B4_SHIFT)) & SYSCON_STARTER_CT32B4_MASK) +#define SYSCON_STARTER_SCT0_MASK (0x10000U) +#define SYSCON_STARTER_SCT0_SHIFT (16U) +#define SYSCON_STARTER_SCT0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_SCT0_SHIFT)) & SYSCON_STARTER_SCT0_MASK) +#define SYSCON_STARTER_USART0_MASK (0x20000U) +#define SYSCON_STARTER_USART0_SHIFT (17U) +#define SYSCON_STARTER_USART0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_USART0_SHIFT)) & SYSCON_STARTER_USART0_MASK) +#define SYSCON_STARTER_USART1_MASK (0x40000U) +#define SYSCON_STARTER_USART1_SHIFT (18U) +#define SYSCON_STARTER_USART1(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_USART1_SHIFT)) & SYSCON_STARTER_USART1_MASK) +#define SYSCON_STARTER_USART2_MASK (0x80000U) +#define SYSCON_STARTER_USART2_SHIFT (19U) +#define SYSCON_STARTER_USART2(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_USART2_SHIFT)) & SYSCON_STARTER_USART2_MASK) +#define SYSCON_STARTER_USART3_MASK (0x100000U) +#define SYSCON_STARTER_USART3_SHIFT (20U) +#define SYSCON_STARTER_USART3(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_USART3_SHIFT)) & SYSCON_STARTER_USART3_MASK) +#define SYSCON_STARTER_I2C0_MASK (0x200000U) +#define SYSCON_STARTER_I2C0_SHIFT (21U) +#define SYSCON_STARTER_I2C0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_I2C0_SHIFT)) & SYSCON_STARTER_I2C0_MASK) +#define SYSCON_STARTER_I2C1_MASK (0x400000U) +#define SYSCON_STARTER_I2C1_SHIFT (22U) +#define SYSCON_STARTER_I2C1(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_I2C1_SHIFT)) & SYSCON_STARTER_I2C1_MASK) +#define SYSCON_STARTER_I2C2_MASK (0x800000U) +#define SYSCON_STARTER_I2C2_SHIFT (23U) +#define SYSCON_STARTER_I2C2(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_I2C2_SHIFT)) & SYSCON_STARTER_I2C2_MASK) +#define SYSCON_STARTER_SPI0_MASK (0x1000000U) +#define SYSCON_STARTER_SPI0_SHIFT (24U) +#define SYSCON_STARTER_SPI0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_SPI0_SHIFT)) & SYSCON_STARTER_SPI0_MASK) +#define SYSCON_STARTER_SPI1_MASK (0x2000000U) +#define SYSCON_STARTER_SPI1_SHIFT (25U) +#define SYSCON_STARTER_SPI1(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_SPI1_SHIFT)) & SYSCON_STARTER_SPI1_MASK) +#define SYSCON_STARTER_ADC0_SEQA_MASK (0x4000000U) +#define SYSCON_STARTER_ADC0_SEQA_SHIFT (26U) +#define SYSCON_STARTER_ADC0_SEQA(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_ADC0_SEQA_SHIFT)) & SYSCON_STARTER_ADC0_SEQA_MASK) +#define SYSCON_STARTER_ADC0_SEQB_MASK (0x8000000U) +#define SYSCON_STARTER_ADC0_SEQB_SHIFT (27U) +#define SYSCON_STARTER_ADC0_SEQB(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_ADC0_SEQB_SHIFT)) & SYSCON_STARTER_ADC0_SEQB_MASK) +#define SYSCON_STARTER_ADC0_THCMP_MASK (0x10000000U) +#define SYSCON_STARTER_ADC0_THCMP_SHIFT (28U) +#define SYSCON_STARTER_ADC0_THCMP(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_ADC0_THCMP_SHIFT)) & SYSCON_STARTER_ADC0_THCMP_MASK) +#define SYSCON_STARTER_RTC_MASK (0x20000000U) +#define SYSCON_STARTER_RTC_SHIFT (29U) +#define SYSCON_STARTER_RTC(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_RTC_SHIFT)) & SYSCON_STARTER_RTC_MASK) +#define SYSCON_STARTER_MAILBOX_MASK (0x80000000U) +#define SYSCON_STARTER_MAILBOX_SHIFT (31U) +#define SYSCON_STARTER_MAILBOX(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_MAILBOX_SHIFT)) & SYSCON_STARTER_MAILBOX_MASK) + +/* The count of SYSCON_STARTER */ +#define SYSCON_STARTER_COUNT (2U) + +/*! @name STARTERSET - Set bits in STARTERP n */ +#define SYSCON_STARTERSET_START_SET_MASK (0xFFFFFFFFU) +#define SYSCON_STARTERSET_START_SET_SHIFT (0U) +#define SYSCON_STARTERSET_START_SET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET_START_SET_SHIFT)) & SYSCON_STARTERSET_START_SET_MASK) + +/* The count of SYSCON_STARTERSET */ +#define SYSCON_STARTERSET_COUNT (2U) + +/*! @name STARTERCLR - Clear bits in STARTER n */ +#define SYSCON_STARTERCLR_START_CLR_MASK (0xFFFFFFFFU) +#define SYSCON_STARTERCLR_START_CLR_SHIFT (0U) +#define SYSCON_STARTERCLR_START_CLR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR_START_CLR_SHIFT)) & SYSCON_STARTERCLR_START_CLR_MASK) + +/* The count of SYSCON_STARTERCLR */ +#define SYSCON_STARTERCLR_COUNT (2U) + +/*! @name CPUCTRL - CPU Control for multiple processors */ +#define SYSCON_CPUCTRL_MASTERCPU_MASK (0x1U) +#define SYSCON_CPUCTRL_MASTERCPU_SHIFT (0U) +#define SYSCON_CPUCTRL_MASTERCPU(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_CPUCTRL_MASTERCPU_SHIFT)) & SYSCON_CPUCTRL_MASTERCPU_MASK) +#define SYSCON_CPUCTRL_CM4CLKEN_MASK (0x4U) +#define SYSCON_CPUCTRL_CM4CLKEN_SHIFT (2U) +#define SYSCON_CPUCTRL_CM4CLKEN(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_CPUCTRL_CM4CLKEN_SHIFT)) & SYSCON_CPUCTRL_CM4CLKEN_MASK) +#define SYSCON_CPUCTRL_CM0CLKEN_MASK (0x8U) +#define SYSCON_CPUCTRL_CM0CLKEN_SHIFT (3U) +#define SYSCON_CPUCTRL_CM0CLKEN(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_CPUCTRL_CM0CLKEN_SHIFT)) & SYSCON_CPUCTRL_CM0CLKEN_MASK) +#define SYSCON_CPUCTRL_CM4RSTEN_MASK (0x10U) +#define SYSCON_CPUCTRL_CM4RSTEN_SHIFT (4U) +#define SYSCON_CPUCTRL_CM4RSTEN(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_CPUCTRL_CM4RSTEN_SHIFT)) & SYSCON_CPUCTRL_CM4RSTEN_MASK) +#define SYSCON_CPUCTRL_CM0RSTEN_MASK (0x20U) +#define SYSCON_CPUCTRL_CM0RSTEN_SHIFT (5U) +#define SYSCON_CPUCTRL_CM0RSTEN(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_CPUCTRL_CM0RSTEN_SHIFT)) & SYSCON_CPUCTRL_CM0RSTEN_MASK) +#define SYSCON_CPUCTRL_POWERCPU_MASK (0x40U) +#define SYSCON_CPUCTRL_POWERCPU_SHIFT (6U) +#define SYSCON_CPUCTRL_POWERCPU(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_CPUCTRL_POWERCPU_SHIFT)) & SYSCON_CPUCTRL_POWERCPU_MASK) + +/*! @name CPBOOT - Coprocessor Boot Address */ +#define SYSCON_CPBOOT_BOOTADDR_MASK (0xFFFFFFFFU) +#define SYSCON_CPBOOT_BOOTADDR_SHIFT (0U) +#define SYSCON_CPBOOT_BOOTADDR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_CPBOOT_BOOTADDR_SHIFT)) & SYSCON_CPBOOT_BOOTADDR_MASK) + +/*! @name CPSTACK - Coprocessor Stack Address */ +#define SYSCON_CPSTACK_STACKADDR_MASK (0xFFFFFFFFU) +#define SYSCON_CPSTACK_STACKADDR_SHIFT (0U) +#define SYSCON_CPSTACK_STACKADDR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_CPSTACK_STACKADDR_SHIFT)) & SYSCON_CPSTACK_STACKADDR_MASK) + +/*! @name CPSTAT - Coprocessor Status */ +#define SYSCON_CPSTAT_CM4SLEEPING_MASK (0x1U) +#define SYSCON_CPSTAT_CM4SLEEPING_SHIFT (0U) +#define SYSCON_CPSTAT_CM4SLEEPING(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_CPSTAT_CM4SLEEPING_SHIFT)) & SYSCON_CPSTAT_CM4SLEEPING_MASK) +#define SYSCON_CPSTAT_CM0SLEEPING_MASK (0x2U) +#define SYSCON_CPSTAT_CM0SLEEPING_SHIFT (1U) +#define SYSCON_CPSTAT_CM0SLEEPING(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_CPSTAT_CM0SLEEPING_SHIFT)) & SYSCON_CPSTAT_CM0SLEEPING_MASK) +#define SYSCON_CPSTAT_CM4LOCKUP_MASK (0x4U) +#define SYSCON_CPSTAT_CM4LOCKUP_SHIFT (2U) +#define SYSCON_CPSTAT_CM4LOCKUP(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_CPSTAT_CM4LOCKUP_SHIFT)) & SYSCON_CPSTAT_CM4LOCKUP_MASK) +#define SYSCON_CPSTAT_CM0LOCKUP_MASK (0x8U) +#define SYSCON_CPSTAT_CM0LOCKUP_SHIFT (3U) +#define SYSCON_CPSTAT_CM0LOCKUP(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_CPSTAT_CM0LOCKUP_SHIFT)) & SYSCON_CPSTAT_CM0LOCKUP_MASK) + +/*! @name JTAGIDCODE - JTAG ID code register */ +#define SYSCON_JTAGIDCODE_JTAGID_MASK (0xFFFFFFFFU) +#define SYSCON_JTAGIDCODE_JTAGID_SHIFT (0U) +#define SYSCON_JTAGIDCODE_JTAGID(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_JTAGIDCODE_JTAGID_SHIFT)) & SYSCON_JTAGIDCODE_JTAGID_MASK) + +/*! @name DEVICE_ID - Part ID register */ +#define SYSCON_DEVICE_ID_PARTID_MASK (0xFFFFFFFFU) +#define SYSCON_DEVICE_ID_PARTID_SHIFT (0U) +#define SYSCON_DEVICE_ID_PARTID(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_DEVICE_ID_PARTID_SHIFT)) & SYSCON_DEVICE_ID_PARTID_MASK) +#define SYSCON_DEVICE_ID_REVID_MASK (0xFFFFFFFFU) +#define SYSCON_DEVICE_ID_REVID_SHIFT (0U) +#define SYSCON_DEVICE_ID_REVID(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_DEVICE_ID_REVID_SHIFT)) & SYSCON_DEVICE_ID_REVID_MASK) + +/* The count of SYSCON_DEVICE_ID */ +#define SYSCON_DEVICE_ID_COUNT (2U) + +/*! @name BODCTRL - Brown-Out Detect control */ +#define SYSCON_BODCTRL_BODRSTLEV_MASK (0x3U) +#define SYSCON_BODCTRL_BODRSTLEV_SHIFT (0U) +#define SYSCON_BODCTRL_BODRSTLEV(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_BODCTRL_BODRSTLEV_SHIFT)) & SYSCON_BODCTRL_BODRSTLEV_MASK) +#define SYSCON_BODCTRL_BODRSTENA_MASK (0x4U) +#define SYSCON_BODCTRL_BODRSTENA_SHIFT (2U) +#define SYSCON_BODCTRL_BODRSTENA(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_BODCTRL_BODRSTENA_SHIFT)) & SYSCON_BODCTRL_BODRSTENA_MASK) +#define SYSCON_BODCTRL_BODINTLEV_MASK (0x18U) +#define SYSCON_BODCTRL_BODINTLEV_SHIFT (3U) +#define SYSCON_BODCTRL_BODINTLEV(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_BODCTRL_BODINTLEV_SHIFT)) & SYSCON_BODCTRL_BODINTLEV_MASK) +#define SYSCON_BODCTRL_BODINTENA_MASK (0x20U) +#define SYSCON_BODCTRL_BODINTENA_SHIFT (5U) +#define SYSCON_BODCTRL_BODINTENA(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_BODCTRL_BODINTENA_SHIFT)) & SYSCON_BODCTRL_BODINTENA_MASK) +#define SYSCON_BODCTRL_BODRSTSTAT_MASK (0x40U) +#define SYSCON_BODCTRL_BODRSTSTAT_SHIFT (6U) +#define SYSCON_BODCTRL_BODRSTSTAT(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_BODCTRL_BODRSTSTAT_SHIFT)) & SYSCON_BODCTRL_BODRSTSTAT_MASK) +#define SYSCON_BODCTRL_BODINTSTAT_MASK (0x80U) +#define SYSCON_BODCTRL_BODINTSTAT_SHIFT (7U) +#define SYSCON_BODCTRL_BODINTSTAT(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_BODCTRL_BODINTSTAT_SHIFT)) & SYSCON_BODCTRL_BODINTSTAT_MASK) + + +/*! + * @} + */ /* end of group SYSCON_Register_Masks */ + + +/* SYSCON - Peripheral instance base addresses */ +/** Peripheral SYSCON base address */ +#define SYSCON_BASE (0x40000000u) +/** Peripheral SYSCON base pointer */ +#define SYSCON ((SYSCON_Type *)SYSCON_BASE) +/** Array initializer of SYSCON peripheral base addresses */ +#define SYSCON_BASE_ADDRS { SYSCON_BASE } +/** Array initializer of SYSCON peripheral base pointers */ +#define SYSCON_BASE_PTRS { SYSCON } + +/*! + * @} + */ /* end of group SYSCON_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- USART Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup USART_Peripheral_Access_Layer USART Peripheral Access Layer + * @{ + */ + +/** USART - Register Layout Typedef */ +typedef struct { + __IO uint32_t CFG; /**< USART Configuration register. Basic USART configuration settings that typically are not changed during operation., offset: 0x0 */ + __IO uint32_t CTL; /**< USART Control register. USART control settings that are more likely to change during operation., offset: 0x4 */ + __IO uint32_t STAT; /**< USART Status register. The complete status value can be read here. Writing ones clears some bits in the register. Some bits can be cleared by writing a 1 to them., offset: 0x8 */ + __IO uint32_t INTENSET; /**< Interrupt Enable read and Set register. Contains an individual interrupt enable bit for each potential USART interrupt. A complete value may be read from this register. Writing a 1 to any implemented bit position causes that bit to be set., offset: 0xC */ + __IO uint32_t INTENCLR; /**< Interrupt Enable Clear register. Allows clearing any combination of bits in the INTENSET register. Writing a 1 to any implemented bit position causes the corresponding bit to be cleared., offset: 0x10 */ + __IO uint32_t RXDAT; /**< Receiver Data register. Contains the last character received., offset: 0x14 */ + __IO uint32_t RXDATSTAT; /**< Receiver Data with Status register. Combines the last character received with the current USART receive status. Allows DMA or software to recover incoming data and status together., offset: 0x18 */ + __IO uint32_t TXDAT; /**< Transmit Data register. Data to be transmitted is written here., offset: 0x1C */ + __IO uint32_t BRG; /**< Baud Rate Generator register. 16-bit integer baud rate divisor value., offset: 0x20 */ + __IO uint32_t INTSTAT; /**< Interrupt status register. Reflects interrupts that are currently enabled., offset: 0x24 */ + __IO uint32_t OSR; /**< Oversample selection register for asynchronous communication., offset: 0x28 */ + __IO uint32_t ADDR; /**< Address register for automatic address matching., offset: 0x2C */ +} USART_Type; + +/* ---------------------------------------------------------------------------- + -- USART Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup USART_Register_Masks USART Register Masks + * @{ + */ + +/*! @name CFG - USART Configuration register. Basic USART configuration settings that typically are not changed during operation. */ +#define USART_CFG_ENABLE_MASK (0x1U) +#define USART_CFG_ENABLE_SHIFT (0U) +#define USART_CFG_ENABLE(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_ENABLE_SHIFT)) & USART_CFG_ENABLE_MASK) +#define USART_CFG_DATALEN_MASK (0xCU) +#define USART_CFG_DATALEN_SHIFT (2U) +#define USART_CFG_DATALEN(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_DATALEN_SHIFT)) & USART_CFG_DATALEN_MASK) +#define USART_CFG_PARITYSEL_MASK (0x30U) +#define USART_CFG_PARITYSEL_SHIFT (4U) +#define USART_CFG_PARITYSEL(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_PARITYSEL_SHIFT)) & USART_CFG_PARITYSEL_MASK) +#define USART_CFG_STOPLEN_MASK (0x40U) +#define USART_CFG_STOPLEN_SHIFT (6U) +#define USART_CFG_STOPLEN(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_STOPLEN_SHIFT)) & USART_CFG_STOPLEN_MASK) +#define USART_CFG_MODE32K_MASK (0x80U) +#define USART_CFG_MODE32K_SHIFT (7U) +#define USART_CFG_MODE32K(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_MODE32K_SHIFT)) & USART_CFG_MODE32K_MASK) +#define USART_CFG_LINMODE_MASK (0x100U) +#define USART_CFG_LINMODE_SHIFT (8U) +#define USART_CFG_LINMODE(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_LINMODE_SHIFT)) & USART_CFG_LINMODE_MASK) +#define USART_CFG_CTSEN_MASK (0x200U) +#define USART_CFG_CTSEN_SHIFT (9U) +#define USART_CFG_CTSEN(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_CTSEN_SHIFT)) & USART_CFG_CTSEN_MASK) +#define USART_CFG_SYNCEN_MASK (0x800U) +#define USART_CFG_SYNCEN_SHIFT (11U) +#define USART_CFG_SYNCEN(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_SYNCEN_SHIFT)) & USART_CFG_SYNCEN_MASK) +#define USART_CFG_CLKPOL_MASK (0x1000U) +#define USART_CFG_CLKPOL_SHIFT (12U) +#define USART_CFG_CLKPOL(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_CLKPOL_SHIFT)) & USART_CFG_CLKPOL_MASK) +#define USART_CFG_SYNCMST_MASK (0x4000U) +#define USART_CFG_SYNCMST_SHIFT (14U) +#define USART_CFG_SYNCMST(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_SYNCMST_SHIFT)) & USART_CFG_SYNCMST_MASK) +#define USART_CFG_LOOP_MASK (0x8000U) +#define USART_CFG_LOOP_SHIFT (15U) +#define USART_CFG_LOOP(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_LOOP_SHIFT)) & USART_CFG_LOOP_MASK) +#define USART_CFG_OETA_MASK (0x40000U) +#define USART_CFG_OETA_SHIFT (18U) +#define USART_CFG_OETA(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_OETA_SHIFT)) & USART_CFG_OETA_MASK) +#define USART_CFG_AUTOADDR_MASK (0x80000U) +#define USART_CFG_AUTOADDR_SHIFT (19U) +#define USART_CFG_AUTOADDR(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_AUTOADDR_SHIFT)) & USART_CFG_AUTOADDR_MASK) +#define USART_CFG_OESEL_MASK (0x100000U) +#define USART_CFG_OESEL_SHIFT (20U) +#define USART_CFG_OESEL(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_OESEL_SHIFT)) & USART_CFG_OESEL_MASK) +#define USART_CFG_OEPOL_MASK (0x200000U) +#define USART_CFG_OEPOL_SHIFT (21U) +#define USART_CFG_OEPOL(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_OEPOL_SHIFT)) & USART_CFG_OEPOL_MASK) +#define USART_CFG_RXPOL_MASK (0x400000U) +#define USART_CFG_RXPOL_SHIFT (22U) +#define USART_CFG_RXPOL(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_RXPOL_SHIFT)) & USART_CFG_RXPOL_MASK) +#define USART_CFG_TXPOL_MASK (0x800000U) +#define USART_CFG_TXPOL_SHIFT (23U) +#define USART_CFG_TXPOL(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_TXPOL_SHIFT)) & USART_CFG_TXPOL_MASK) + +/*! @name CTL - USART Control register. USART control settings that are more likely to change during operation. */ +#define USART_CTL_TXBRKEN_MASK (0x2U) +#define USART_CTL_TXBRKEN_SHIFT (1U) +#define USART_CTL_TXBRKEN(x) (((uint32_t)(((uint32_t)(x)) << USART_CTL_TXBRKEN_SHIFT)) & USART_CTL_TXBRKEN_MASK) +#define USART_CTL_ADDRDET_MASK (0x4U) +#define USART_CTL_ADDRDET_SHIFT (2U) +#define USART_CTL_ADDRDET(x) (((uint32_t)(((uint32_t)(x)) << USART_CTL_ADDRDET_SHIFT)) & USART_CTL_ADDRDET_MASK) +#define USART_CTL_TXDIS_MASK (0x40U) +#define USART_CTL_TXDIS_SHIFT (6U) +#define USART_CTL_TXDIS(x) (((uint32_t)(((uint32_t)(x)) << USART_CTL_TXDIS_SHIFT)) & USART_CTL_TXDIS_MASK) +#define USART_CTL_CC_MASK (0x100U) +#define USART_CTL_CC_SHIFT (8U) +#define USART_CTL_CC(x) (((uint32_t)(((uint32_t)(x)) << USART_CTL_CC_SHIFT)) & USART_CTL_CC_MASK) +#define USART_CTL_CLRCCONRX_MASK (0x200U) +#define USART_CTL_CLRCCONRX_SHIFT (9U) +#define USART_CTL_CLRCCONRX(x) (((uint32_t)(((uint32_t)(x)) << USART_CTL_CLRCCONRX_SHIFT)) & USART_CTL_CLRCCONRX_MASK) +#define USART_CTL_AUTOBAUD_MASK (0x10000U) +#define USART_CTL_AUTOBAUD_SHIFT (16U) +#define USART_CTL_AUTOBAUD(x) (((uint32_t)(((uint32_t)(x)) << USART_CTL_AUTOBAUD_SHIFT)) & USART_CTL_AUTOBAUD_MASK) + +/*! @name STAT - USART Status register. The complete status value can be read here. Writing ones clears some bits in the register. Some bits can be cleared by writing a 1 to them. */ +#define USART_STAT_RXRDY_MASK (0x1U) +#define USART_STAT_RXRDY_SHIFT (0U) +#define USART_STAT_RXRDY(x) (((uint32_t)(((uint32_t)(x)) << USART_STAT_RXRDY_SHIFT)) & USART_STAT_RXRDY_MASK) +#define USART_STAT_RXIDLE_MASK (0x2U) +#define USART_STAT_RXIDLE_SHIFT (1U) +#define USART_STAT_RXIDLE(x) (((uint32_t)(((uint32_t)(x)) << USART_STAT_RXIDLE_SHIFT)) & USART_STAT_RXIDLE_MASK) +#define USART_STAT_TXRDY_MASK (0x4U) +#define USART_STAT_TXRDY_SHIFT (2U) +#define USART_STAT_TXRDY(x) (((uint32_t)(((uint32_t)(x)) << USART_STAT_TXRDY_SHIFT)) & USART_STAT_TXRDY_MASK) +#define USART_STAT_TXIDLE_MASK (0x8U) +#define USART_STAT_TXIDLE_SHIFT (3U) +#define USART_STAT_TXIDLE(x) (((uint32_t)(((uint32_t)(x)) << USART_STAT_TXIDLE_SHIFT)) & USART_STAT_TXIDLE_MASK) +#define USART_STAT_CTS_MASK (0x10U) +#define USART_STAT_CTS_SHIFT (4U) +#define USART_STAT_CTS(x) (((uint32_t)(((uint32_t)(x)) << USART_STAT_CTS_SHIFT)) & USART_STAT_CTS_MASK) +#define USART_STAT_DELTACTS_MASK (0x20U) +#define USART_STAT_DELTACTS_SHIFT (5U) +#define USART_STAT_DELTACTS(x) (((uint32_t)(((uint32_t)(x)) << USART_STAT_DELTACTS_SHIFT)) & USART_STAT_DELTACTS_MASK) +#define USART_STAT_TXDISSTAT_MASK (0x40U) +#define USART_STAT_TXDISSTAT_SHIFT (6U) +#define USART_STAT_TXDISSTAT(x) (((uint32_t)(((uint32_t)(x)) << USART_STAT_TXDISSTAT_SHIFT)) & USART_STAT_TXDISSTAT_MASK) +#define USART_STAT_OVERRUNINT_MASK (0x100U) +#define USART_STAT_OVERRUNINT_SHIFT (8U) +#define USART_STAT_OVERRUNINT(x) (((uint32_t)(((uint32_t)(x)) << USART_STAT_OVERRUNINT_SHIFT)) & USART_STAT_OVERRUNINT_MASK) +#define USART_STAT_RXBRK_MASK (0x400U) +#define USART_STAT_RXBRK_SHIFT (10U) +#define USART_STAT_RXBRK(x) (((uint32_t)(((uint32_t)(x)) << USART_STAT_RXBRK_SHIFT)) & USART_STAT_RXBRK_MASK) +#define USART_STAT_DELTARXBRK_MASK (0x800U) +#define USART_STAT_DELTARXBRK_SHIFT (11U) +#define USART_STAT_DELTARXBRK(x) (((uint32_t)(((uint32_t)(x)) << USART_STAT_DELTARXBRK_SHIFT)) & USART_STAT_DELTARXBRK_MASK) +#define USART_STAT_START_MASK (0x1000U) +#define USART_STAT_START_SHIFT (12U) +#define USART_STAT_START(x) (((uint32_t)(((uint32_t)(x)) << USART_STAT_START_SHIFT)) & USART_STAT_START_MASK) +#define USART_STAT_FRAMERRINT_MASK (0x2000U) +#define USART_STAT_FRAMERRINT_SHIFT (13U) +#define USART_STAT_FRAMERRINT(x) (((uint32_t)(((uint32_t)(x)) << USART_STAT_FRAMERRINT_SHIFT)) & USART_STAT_FRAMERRINT_MASK) +#define USART_STAT_PARITYERRINT_MASK (0x4000U) +#define USART_STAT_PARITYERRINT_SHIFT (14U) +#define USART_STAT_PARITYERRINT(x) (((uint32_t)(((uint32_t)(x)) << USART_STAT_PARITYERRINT_SHIFT)) & USART_STAT_PARITYERRINT_MASK) +#define USART_STAT_RXNOISEINT_MASK (0x8000U) +#define USART_STAT_RXNOISEINT_SHIFT (15U) +#define USART_STAT_RXNOISEINT(x) (((uint32_t)(((uint32_t)(x)) << USART_STAT_RXNOISEINT_SHIFT)) & USART_STAT_RXNOISEINT_MASK) +#define USART_STAT_ABERR_MASK (0x10000U) +#define USART_STAT_ABERR_SHIFT (16U) +#define USART_STAT_ABERR(x) (((uint32_t)(((uint32_t)(x)) << USART_STAT_ABERR_SHIFT)) & USART_STAT_ABERR_MASK) + +/*! @name INTENSET - Interrupt Enable read and Set register. Contains an individual interrupt enable bit for each potential USART interrupt. A complete value may be read from this register. Writing a 1 to any implemented bit position causes that bit to be set. */ +#define USART_INTENSET_RXRDYEN_MASK (0x1U) +#define USART_INTENSET_RXRDYEN_SHIFT (0U) +#define USART_INTENSET_RXRDYEN(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_RXRDYEN_SHIFT)) & USART_INTENSET_RXRDYEN_MASK) +#define USART_INTENSET_TXRDYEN_MASK (0x4U) +#define USART_INTENSET_TXRDYEN_SHIFT (2U) +#define USART_INTENSET_TXRDYEN(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_TXRDYEN_SHIFT)) & USART_INTENSET_TXRDYEN_MASK) +#define USART_INTENSET_TXIDLEEN_MASK (0x8U) +#define USART_INTENSET_TXIDLEEN_SHIFT (3U) +#define USART_INTENSET_TXIDLEEN(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_TXIDLEEN_SHIFT)) & USART_INTENSET_TXIDLEEN_MASK) +#define USART_INTENSET_DELTACTSEN_MASK (0x20U) +#define USART_INTENSET_DELTACTSEN_SHIFT (5U) +#define USART_INTENSET_DELTACTSEN(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_DELTACTSEN_SHIFT)) & USART_INTENSET_DELTACTSEN_MASK) +#define USART_INTENSET_TXDISEN_MASK (0x40U) +#define USART_INTENSET_TXDISEN_SHIFT (6U) +#define USART_INTENSET_TXDISEN(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_TXDISEN_SHIFT)) & USART_INTENSET_TXDISEN_MASK) +#define USART_INTENSET_OVERRUNEN_MASK (0x100U) +#define USART_INTENSET_OVERRUNEN_SHIFT (8U) +#define USART_INTENSET_OVERRUNEN(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_OVERRUNEN_SHIFT)) & USART_INTENSET_OVERRUNEN_MASK) +#define USART_INTENSET_DELTARXBRKEN_MASK (0x800U) +#define USART_INTENSET_DELTARXBRKEN_SHIFT (11U) +#define USART_INTENSET_DELTARXBRKEN(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_DELTARXBRKEN_SHIFT)) & USART_INTENSET_DELTARXBRKEN_MASK) +#define USART_INTENSET_STARTEN_MASK (0x1000U) +#define USART_INTENSET_STARTEN_SHIFT (12U) +#define USART_INTENSET_STARTEN(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_STARTEN_SHIFT)) & USART_INTENSET_STARTEN_MASK) +#define USART_INTENSET_FRAMERREN_MASK (0x2000U) +#define USART_INTENSET_FRAMERREN_SHIFT (13U) +#define USART_INTENSET_FRAMERREN(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_FRAMERREN_SHIFT)) & USART_INTENSET_FRAMERREN_MASK) +#define USART_INTENSET_PARITYERREN_MASK (0x4000U) +#define USART_INTENSET_PARITYERREN_SHIFT (14U) +#define USART_INTENSET_PARITYERREN(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_PARITYERREN_SHIFT)) & USART_INTENSET_PARITYERREN_MASK) +#define USART_INTENSET_RXNOISEEN_MASK (0x8000U) +#define USART_INTENSET_RXNOISEEN_SHIFT (15U) +#define USART_INTENSET_RXNOISEEN(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_RXNOISEEN_SHIFT)) & USART_INTENSET_RXNOISEEN_MASK) +#define USART_INTENSET_ABERREN_MASK (0x10000U) +#define USART_INTENSET_ABERREN_SHIFT (16U) +#define USART_INTENSET_ABERREN(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_ABERREN_SHIFT)) & USART_INTENSET_ABERREN_MASK) + +/*! @name INTENCLR - Interrupt Enable Clear register. Allows clearing any combination of bits in the INTENSET register. Writing a 1 to any implemented bit position causes the corresponding bit to be cleared. */ +#define USART_INTENCLR_RXRDYCLR_MASK (0x1U) +#define USART_INTENCLR_RXRDYCLR_SHIFT (0U) +#define USART_INTENCLR_RXRDYCLR(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_RXRDYCLR_SHIFT)) & USART_INTENCLR_RXRDYCLR_MASK) +#define USART_INTENCLR_TXRDYCLR_MASK (0x4U) +#define USART_INTENCLR_TXRDYCLR_SHIFT (2U) +#define USART_INTENCLR_TXRDYCLR(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_TXRDYCLR_SHIFT)) & USART_INTENCLR_TXRDYCLR_MASK) +#define USART_INTENCLR_TXIDLECLR_MASK (0x8U) +#define USART_INTENCLR_TXIDLECLR_SHIFT (3U) +#define USART_INTENCLR_TXIDLECLR(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_TXIDLECLR_SHIFT)) & USART_INTENCLR_TXIDLECLR_MASK) +#define USART_INTENCLR_DELTACTSCLR_MASK (0x20U) +#define USART_INTENCLR_DELTACTSCLR_SHIFT (5U) +#define USART_INTENCLR_DELTACTSCLR(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_DELTACTSCLR_SHIFT)) & USART_INTENCLR_DELTACTSCLR_MASK) +#define USART_INTENCLR_TXDISCLR_MASK (0x40U) +#define USART_INTENCLR_TXDISCLR_SHIFT (6U) +#define USART_INTENCLR_TXDISCLR(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_TXDISCLR_SHIFT)) & USART_INTENCLR_TXDISCLR_MASK) +#define USART_INTENCLR_OVERRUNCLR_MASK (0x100U) +#define USART_INTENCLR_OVERRUNCLR_SHIFT (8U) +#define USART_INTENCLR_OVERRUNCLR(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_OVERRUNCLR_SHIFT)) & USART_INTENCLR_OVERRUNCLR_MASK) +#define USART_INTENCLR_DELTARXBRKCLR_MASK (0x800U) +#define USART_INTENCLR_DELTARXBRKCLR_SHIFT (11U) +#define USART_INTENCLR_DELTARXBRKCLR(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_DELTARXBRKCLR_SHIFT)) & USART_INTENCLR_DELTARXBRKCLR_MASK) +#define USART_INTENCLR_STARTCLR_MASK (0x1000U) +#define USART_INTENCLR_STARTCLR_SHIFT (12U) +#define USART_INTENCLR_STARTCLR(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_STARTCLR_SHIFT)) & USART_INTENCLR_STARTCLR_MASK) +#define USART_INTENCLR_FRAMERRCLR_MASK (0x2000U) +#define USART_INTENCLR_FRAMERRCLR_SHIFT (13U) +#define USART_INTENCLR_FRAMERRCLR(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_FRAMERRCLR_SHIFT)) & USART_INTENCLR_FRAMERRCLR_MASK) +#define USART_INTENCLR_PARITYERRCLR_MASK (0x4000U) +#define USART_INTENCLR_PARITYERRCLR_SHIFT (14U) +#define USART_INTENCLR_PARITYERRCLR(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_PARITYERRCLR_SHIFT)) & USART_INTENCLR_PARITYERRCLR_MASK) +#define USART_INTENCLR_RXNOISECLR_MASK (0x8000U) +#define USART_INTENCLR_RXNOISECLR_SHIFT (15U) +#define USART_INTENCLR_RXNOISECLR(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_RXNOISECLR_SHIFT)) & USART_INTENCLR_RXNOISECLR_MASK) +#define USART_INTENCLR_ABERRCLR_MASK (0x10000U) +#define USART_INTENCLR_ABERRCLR_SHIFT (16U) +#define USART_INTENCLR_ABERRCLR(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_ABERRCLR_SHIFT)) & USART_INTENCLR_ABERRCLR_MASK) + +/*! @name RXDAT - Receiver Data register. Contains the last character received. */ +#define USART_RXDAT_DATA_MASK (0x1FFU) +#define USART_RXDAT_DATA_SHIFT (0U) +#define USART_RXDAT_DATA(x) (((uint32_t)(((uint32_t)(x)) << USART_RXDAT_DATA_SHIFT)) & USART_RXDAT_DATA_MASK) + +/*! @name RXDATSTAT - Receiver Data with Status register. Combines the last character received with the current USART receive status. Allows DMA or software to recover incoming data and status together. */ +#define USART_RXDATSTAT_RXDATA_MASK (0x1FFU) +#define USART_RXDATSTAT_RXDATA_SHIFT (0U) +#define USART_RXDATSTAT_RXDATA(x) (((uint32_t)(((uint32_t)(x)) << USART_RXDATSTAT_RXDATA_SHIFT)) & USART_RXDATSTAT_RXDATA_MASK) +#define USART_RXDATSTAT_FRAMERR_MASK (0x2000U) +#define USART_RXDATSTAT_FRAMERR_SHIFT (13U) +#define USART_RXDATSTAT_FRAMERR(x) (((uint32_t)(((uint32_t)(x)) << USART_RXDATSTAT_FRAMERR_SHIFT)) & USART_RXDATSTAT_FRAMERR_MASK) +#define USART_RXDATSTAT_PARITYERR_MASK (0x4000U) +#define USART_RXDATSTAT_PARITYERR_SHIFT (14U) +#define USART_RXDATSTAT_PARITYERR(x) (((uint32_t)(((uint32_t)(x)) << USART_RXDATSTAT_PARITYERR_SHIFT)) & USART_RXDATSTAT_PARITYERR_MASK) +#define USART_RXDATSTAT_RXNOISE_MASK (0x8000U) +#define USART_RXDATSTAT_RXNOISE_SHIFT (15U) +#define USART_RXDATSTAT_RXNOISE(x) (((uint32_t)(((uint32_t)(x)) << USART_RXDATSTAT_RXNOISE_SHIFT)) & USART_RXDATSTAT_RXNOISE_MASK) + +/*! @name TXDAT - Transmit Data register. Data to be transmitted is written here. */ +#define USART_TXDAT_TXDATA_MASK (0x1FFU) +#define USART_TXDAT_TXDATA_SHIFT (0U) +#define USART_TXDAT_TXDATA(x) (((uint32_t)(((uint32_t)(x)) << USART_TXDAT_TXDATA_SHIFT)) & USART_TXDAT_TXDATA_MASK) + +/*! @name BRG - Baud Rate Generator register. 16-bit integer baud rate divisor value. */ +#define USART_BRG_BRGVAL_MASK (0xFFFFU) +#define USART_BRG_BRGVAL_SHIFT (0U) +#define USART_BRG_BRGVAL(x) (((uint32_t)(((uint32_t)(x)) << USART_BRG_BRGVAL_SHIFT)) & USART_BRG_BRGVAL_MASK) + +/*! @name INTSTAT - Interrupt status register. Reflects interrupts that are currently enabled. */ +#define USART_INTSTAT_RXRDY_MASK (0x1U) +#define USART_INTSTAT_RXRDY_SHIFT (0U) +#define USART_INTSTAT_RXRDY(x) (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_RXRDY_SHIFT)) & USART_INTSTAT_RXRDY_MASK) +#define USART_INTSTAT_TXRDY_MASK (0x4U) +#define USART_INTSTAT_TXRDY_SHIFT (2U) +#define USART_INTSTAT_TXRDY(x) (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_TXRDY_SHIFT)) & USART_INTSTAT_TXRDY_MASK) +#define USART_INTSTAT_TXIDLE_MASK (0x8U) +#define USART_INTSTAT_TXIDLE_SHIFT (3U) +#define USART_INTSTAT_TXIDLE(x) (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_TXIDLE_SHIFT)) & USART_INTSTAT_TXIDLE_MASK) +#define USART_INTSTAT_DELTACTS_MASK (0x20U) +#define USART_INTSTAT_DELTACTS_SHIFT (5U) +#define USART_INTSTAT_DELTACTS(x) (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_DELTACTS_SHIFT)) & USART_INTSTAT_DELTACTS_MASK) +#define USART_INTSTAT_TXDISINT_MASK (0x40U) +#define USART_INTSTAT_TXDISINT_SHIFT (6U) +#define USART_INTSTAT_TXDISINT(x) (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_TXDISINT_SHIFT)) & USART_INTSTAT_TXDISINT_MASK) +#define USART_INTSTAT_OVERRUNINT_MASK (0x100U) +#define USART_INTSTAT_OVERRUNINT_SHIFT (8U) +#define USART_INTSTAT_OVERRUNINT(x) (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_OVERRUNINT_SHIFT)) & USART_INTSTAT_OVERRUNINT_MASK) +#define USART_INTSTAT_DELTARXBRK_MASK (0x800U) +#define USART_INTSTAT_DELTARXBRK_SHIFT (11U) +#define USART_INTSTAT_DELTARXBRK(x) (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_DELTARXBRK_SHIFT)) & USART_INTSTAT_DELTARXBRK_MASK) +#define USART_INTSTAT_START_MASK (0x1000U) +#define USART_INTSTAT_START_SHIFT (12U) +#define USART_INTSTAT_START(x) (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_START_SHIFT)) & USART_INTSTAT_START_MASK) +#define USART_INTSTAT_FRAMERRINT_MASK (0x2000U) +#define USART_INTSTAT_FRAMERRINT_SHIFT (13U) +#define USART_INTSTAT_FRAMERRINT(x) (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_FRAMERRINT_SHIFT)) & USART_INTSTAT_FRAMERRINT_MASK) +#define USART_INTSTAT_PARITYERRINT_MASK (0x4000U) +#define USART_INTSTAT_PARITYERRINT_SHIFT (14U) +#define USART_INTSTAT_PARITYERRINT(x) (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_PARITYERRINT_SHIFT)) & USART_INTSTAT_PARITYERRINT_MASK) +#define USART_INTSTAT_RXNOISEINT_MASK (0x8000U) +#define USART_INTSTAT_RXNOISEINT_SHIFT (15U) +#define USART_INTSTAT_RXNOISEINT(x) (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_RXNOISEINT_SHIFT)) & USART_INTSTAT_RXNOISEINT_MASK) +#define USART_INTSTAT_ABERRINT_MASK (0x10000U) +#define USART_INTSTAT_ABERRINT_SHIFT (16U) +#define USART_INTSTAT_ABERRINT(x) (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_ABERRINT_SHIFT)) & USART_INTSTAT_ABERRINT_MASK) + +/*! @name OSR - Oversample selection register for asynchronous communication. */ +#define USART_OSR_OSRVAL_MASK (0xFU) +#define USART_OSR_OSRVAL_SHIFT (0U) +#define USART_OSR_OSRVAL(x) (((uint32_t)(((uint32_t)(x)) << USART_OSR_OSRVAL_SHIFT)) & USART_OSR_OSRVAL_MASK) + +/*! @name ADDR - Address register for automatic address matching. */ +#define USART_ADDR_ADDRESS_MASK (0xFFU) +#define USART_ADDR_ADDRESS_SHIFT (0U) +#define USART_ADDR_ADDRESS(x) (((uint32_t)(((uint32_t)(x)) << USART_ADDR_ADDRESS_SHIFT)) & USART_ADDR_ADDRESS_MASK) + + +/*! + * @} + */ /* end of group USART_Register_Masks */ + + +/* USART - Peripheral instance base addresses */ +/** Peripheral USART0 base address */ +#define USART0_BASE (0x40084000u) +/** Peripheral USART0 base pointer */ +#define USART0 ((USART_Type *)USART0_BASE) +/** Peripheral USART1 base address */ +#define USART1_BASE (0x40088000u) +/** Peripheral USART1 base pointer */ +#define USART1 ((USART_Type *)USART1_BASE) +/** Peripheral USART2 base address */ +#define USART2_BASE (0x4008C000u) +/** Peripheral USART2 base pointer */ +#define USART2 ((USART_Type *)USART2_BASE) +/** Peripheral USART3 base address */ +#define USART3_BASE (0x40090000u) +/** Peripheral USART3 base pointer */ +#define USART3 ((USART_Type *)USART3_BASE) +/** Array initializer of USART peripheral base addresses */ +#define USART_BASE_ADDRS { USART0_BASE, USART1_BASE, USART2_BASE, USART3_BASE } +/** Array initializer of USART peripheral base pointers */ +#define USART_BASE_PTRS { USART0, USART1, USART2, USART3 } +/** Interrupt vectors for the USART peripheral type */ +#define USART_IRQS { USART0_IRQn, USART1_IRQn, USART2_IRQn, USART3_IRQn } + +/*! + * @} + */ /* end of group USART_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- UTICK Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup UTICK_Peripheral_Access_Layer UTICK Peripheral Access Layer + * @{ + */ + +/** UTICK - Register Layout Typedef */ +typedef struct { + __IO uint32_t CTRL; /**< Control register., offset: 0x0 */ + __IO uint32_t STAT; /**< Status register., offset: 0x4 */ + __IO uint32_t CFG; /**< Capture configuration register., offset: 0x8 */ + __O uint32_t CAPCLR; /**< Capture clear register., offset: 0xC */ + __I uint32_t CAP[4]; /**< Capture register ., array offset: 0x10, array step: 0x4 */ +} UTICK_Type; + +/* ---------------------------------------------------------------------------- + -- UTICK Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup UTICK_Register_Masks UTICK Register Masks + * @{ + */ + +/*! @name CTRL - Control register. */ +#define UTICK_CTRL_DELAYVAL_MASK (0x7FFFFFFFU) +#define UTICK_CTRL_DELAYVAL_SHIFT (0U) +#define UTICK_CTRL_DELAYVAL(x) (((uint32_t)(((uint32_t)(x)) << UTICK_CTRL_DELAYVAL_SHIFT)) & UTICK_CTRL_DELAYVAL_MASK) +#define UTICK_CTRL_REPEAT_MASK (0x80000000U) +#define UTICK_CTRL_REPEAT_SHIFT (31U) +#define UTICK_CTRL_REPEAT(x) (((uint32_t)(((uint32_t)(x)) << UTICK_CTRL_REPEAT_SHIFT)) & UTICK_CTRL_REPEAT_MASK) + +/*! @name STAT - Status register. */ +#define UTICK_STAT_INTR_MASK (0x1U) +#define UTICK_STAT_INTR_SHIFT (0U) +#define UTICK_STAT_INTR(x) (((uint32_t)(((uint32_t)(x)) << UTICK_STAT_INTR_SHIFT)) & UTICK_STAT_INTR_MASK) +#define UTICK_STAT_ACTIVE_MASK (0x2U) +#define UTICK_STAT_ACTIVE_SHIFT (1U) +#define UTICK_STAT_ACTIVE(x) (((uint32_t)(((uint32_t)(x)) << UTICK_STAT_ACTIVE_SHIFT)) & UTICK_STAT_ACTIVE_MASK) + +/*! @name CFG - Capture configuration register. */ +#define UTICK_CFG_CAPEN0_MASK (0x1U) +#define UTICK_CFG_CAPEN0_SHIFT (0U) +#define UTICK_CFG_CAPEN0(x) (((uint32_t)(((uint32_t)(x)) << UTICK_CFG_CAPEN0_SHIFT)) & UTICK_CFG_CAPEN0_MASK) +#define UTICK_CFG_CAPEN1_MASK (0x2U) +#define UTICK_CFG_CAPEN1_SHIFT (1U) +#define UTICK_CFG_CAPEN1(x) (((uint32_t)(((uint32_t)(x)) << UTICK_CFG_CAPEN1_SHIFT)) & UTICK_CFG_CAPEN1_MASK) +#define UTICK_CFG_CAPEN2_MASK (0x4U) +#define UTICK_CFG_CAPEN2_SHIFT (2U) +#define UTICK_CFG_CAPEN2(x) (((uint32_t)(((uint32_t)(x)) << UTICK_CFG_CAPEN2_SHIFT)) & UTICK_CFG_CAPEN2_MASK) +#define UTICK_CFG_CAPEN3_MASK (0x8U) +#define UTICK_CFG_CAPEN3_SHIFT (3U) +#define UTICK_CFG_CAPEN3(x) (((uint32_t)(((uint32_t)(x)) << UTICK_CFG_CAPEN3_SHIFT)) & UTICK_CFG_CAPEN3_MASK) +#define UTICK_CFG_CAPPOL0_MASK (0x100U) +#define UTICK_CFG_CAPPOL0_SHIFT (8U) +#define UTICK_CFG_CAPPOL0(x) (((uint32_t)(((uint32_t)(x)) << UTICK_CFG_CAPPOL0_SHIFT)) & UTICK_CFG_CAPPOL0_MASK) +#define UTICK_CFG_CAPPOL1_MASK (0x200U) +#define UTICK_CFG_CAPPOL1_SHIFT (9U) +#define UTICK_CFG_CAPPOL1(x) (((uint32_t)(((uint32_t)(x)) << UTICK_CFG_CAPPOL1_SHIFT)) & UTICK_CFG_CAPPOL1_MASK) +#define UTICK_CFG_CAPPOL2_MASK (0x400U) +#define UTICK_CFG_CAPPOL2_SHIFT (10U) +#define UTICK_CFG_CAPPOL2(x) (((uint32_t)(((uint32_t)(x)) << UTICK_CFG_CAPPOL2_SHIFT)) & UTICK_CFG_CAPPOL2_MASK) +#define UTICK_CFG_CAPPOL3_MASK (0x800U) +#define UTICK_CFG_CAPPOL3_SHIFT (11U) +#define UTICK_CFG_CAPPOL3(x) (((uint32_t)(((uint32_t)(x)) << UTICK_CFG_CAPPOL3_SHIFT)) & UTICK_CFG_CAPPOL3_MASK) + +/*! @name CAPCLR - Capture clear register. */ +#define UTICK_CAPCLR_CAPCLR0_MASK (0x1U) +#define UTICK_CAPCLR_CAPCLR0_SHIFT (0U) +#define UTICK_CAPCLR_CAPCLR0(x) (((uint32_t)(((uint32_t)(x)) << UTICK_CAPCLR_CAPCLR0_SHIFT)) & UTICK_CAPCLR_CAPCLR0_MASK) +#define UTICK_CAPCLR_CAPCLR1_MASK (0x2U) +#define UTICK_CAPCLR_CAPCLR1_SHIFT (1U) +#define UTICK_CAPCLR_CAPCLR1(x) (((uint32_t)(((uint32_t)(x)) << UTICK_CAPCLR_CAPCLR1_SHIFT)) & UTICK_CAPCLR_CAPCLR1_MASK) +#define UTICK_CAPCLR_CAPCLR2_MASK (0x4U) +#define UTICK_CAPCLR_CAPCLR2_SHIFT (2U) +#define UTICK_CAPCLR_CAPCLR2(x) (((uint32_t)(((uint32_t)(x)) << UTICK_CAPCLR_CAPCLR2_SHIFT)) & UTICK_CAPCLR_CAPCLR2_MASK) +#define UTICK_CAPCLR_CAPCLR3_MASK (0x8U) +#define UTICK_CAPCLR_CAPCLR3_SHIFT (3U) +#define UTICK_CAPCLR_CAPCLR3(x) (((uint32_t)(((uint32_t)(x)) << UTICK_CAPCLR_CAPCLR3_SHIFT)) & UTICK_CAPCLR_CAPCLR3_MASK) + +/*! @name CAP - Capture register . */ +#define UTICK_CAP_CAP_VALUE_MASK (0x7FFFFFFFU) +#define UTICK_CAP_CAP_VALUE_SHIFT (0U) +#define UTICK_CAP_CAP_VALUE(x) (((uint32_t)(((uint32_t)(x)) << UTICK_CAP_CAP_VALUE_SHIFT)) & UTICK_CAP_CAP_VALUE_MASK) +#define UTICK_CAP_VALID_MASK (0x80000000U) +#define UTICK_CAP_VALID_SHIFT (31U) +#define UTICK_CAP_VALID(x) (((uint32_t)(((uint32_t)(x)) << UTICK_CAP_VALID_SHIFT)) & UTICK_CAP_VALID_MASK) + +/* The count of UTICK_CAP */ +#define UTICK_CAP_COUNT (4U) + + +/*! + * @} + */ /* end of group UTICK_Register_Masks */ + + +/* UTICK - Peripheral instance base addresses */ +/** Peripheral UTICK0 base address */ +#define UTICK0_BASE (0x40020000u) +/** Peripheral UTICK0 base pointer */ +#define UTICK0 ((UTICK_Type *)UTICK0_BASE) +/** Array initializer of UTICK peripheral base addresses */ +#define UTICK_BASE_ADDRS { UTICK0_BASE } +/** Array initializer of UTICK peripheral base pointers */ +#define UTICK_BASE_PTRS { UTICK0 } +/** Interrupt vectors for the UTICK peripheral type */ +#define UTICK_IRQS { UTICK0_IRQn } + +/*! + * @} + */ /* end of group UTICK_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- VFIFO Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup VFIFO_Peripheral_Access_Layer VFIFO Peripheral Access Layer + * @{ + */ + +/** VFIFO - Register Layout Typedef */ +typedef struct { + uint8_t RESERVED_0[256]; + __IO uint32_t FIFOCTLUSART; /**< USART FIFO global control register. These registers are byte, halfword, and word addressable.The upper 16 bits of these registers provide information about the System FIFO configuration, and are specific to each device type., offset: 0x100 */ + __IO uint32_t FIFOUPDATEUSART; /**< USART FIFO global update register, offset: 0x104 */ + uint8_t RESERVED_1[8]; + __IO uint32_t FIFOCFGUSART[4]; /**< FIFO configuration register for USART0, array offset: 0x110, array step: 0x4 */ + uint8_t RESERVED_2[224]; + __IO uint32_t FIFOCTLSPI; /**< SPI FIFO global control register. These registers are byte, halfword, and word addressable. The upper 16 bits of these registers provide information about the System FIFO configuration, and are specific to each device type., offset: 0x200 */ + __IO uint32_t FIFOUPDATESPI; /**< SPI FIFO global update register, offset: 0x204 */ + uint8_t RESERVED_3[8]; + __IO uint32_t FIFOCFGSPI[2]; /**< FIFO configuration register for SPI0, array offset: 0x210, array step: 0x4 */ + uint8_t RESERVED_4[3560]; + struct { /* offset: 0x1000, array step: 0x100 */ + __IO uint32_t CFGUSART; /**< USART0 configuration, array offset: 0x1000, array step: 0x100 */ + __IO uint32_t STATUSART; /**< USART0 status, array offset: 0x1004, array step: 0x100 */ + __IO uint32_t INTSTATUSART; /**< USART0 interrupt status, array offset: 0x1008, array step: 0x100 */ + __IO uint32_t CTLSETUSART; /**< USART0 control read and set register. A complete value may be read from this register. Writing a 1 to any implemented bit position causes that bit to be set., array offset: 0x100C, array step: 0x100 */ + __IO uint32_t CTLCLRUSART; /**< USART0 control clear register. Writing a 1 to any implemented bit position causes the corresponding bit in the related CTLSET register to be cleared., array offset: 0x1010, array step: 0x100 */ + __IO uint32_t RXDATUSART; /**< USART0 received data, array offset: 0x1014, array step: 0x100 */ + __IO uint32_t RXDATSTATUSART; /**< USART0 received data with status, array offset: 0x1018, array step: 0x100 */ + __IO uint32_t TXDATUSART; /**< USART0 transmit data, array offset: 0x101C, array step: 0x100 */ + uint8_t RESERVED_0[224]; + } USART[4]; + uint8_t RESERVED_5[3072]; + struct { /* offset: 0x2000, array step: 0x100 */ + __IO uint32_t CFGSPI; /**< SPI0 configuration, array offset: 0x2000, array step: 0x100 */ + __IO uint32_t STATSPI; /**< SPI0 status, array offset: 0x2004, array step: 0x100 */ + __IO uint32_t INTSTATSPI; /**< SPI0 interrupt status, array offset: 0x2008, array step: 0x100 */ + __IO uint32_t CTLSETSPI; /**< SPI0 control read and set register. A complete value may be read from this register. Writing a 1 to any implemented bit position causes that bit to be set., array offset: 0x200C, array step: 0x100 */ + __IO uint32_t CTLCLRSPI; /**< SPI0 control clear register. Writing a 1 to any implemented bit position causes the corresponding bit in the related CTLSET register to be cleared., array offset: 0x2010, array step: 0x100 */ + __IO uint32_t RXDATSPI; /**< SPI0 received data. These registers are half word addressable., array offset: 0x2014, array step: 0x100 */ + __IO uint32_t TXDATSPI; /**< SPI0 transmit data. These registers are half word addressable., array offset: 0x2018, array step: 0x100 */ + uint8_t RESERVED_0[228]; + } SPI[2]; +} VFIFO_Type; + +/* ---------------------------------------------------------------------------- + -- VFIFO Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup VFIFO_Register_Masks VFIFO Register Masks + * @{ + */ + +/*! @name FIFOCTLUSART - USART FIFO global control register. These registers are byte, halfword, and word addressable.The upper 16 bits of these registers provide information about the System FIFO configuration, and are specific to each device type. */ +#define VFIFO_FIFOCTLUSART_RXPAUSE_MASK (0x1U) +#define VFIFO_FIFOCTLUSART_RXPAUSE_SHIFT (0U) +#define VFIFO_FIFOCTLUSART_RXPAUSE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOCTLUSART_RXPAUSE_SHIFT)) & VFIFO_FIFOCTLUSART_RXPAUSE_MASK) +#define VFIFO_FIFOCTLUSART_RXPAUSED_MASK (0x2U) +#define VFIFO_FIFOCTLUSART_RXPAUSED_SHIFT (1U) +#define VFIFO_FIFOCTLUSART_RXPAUSED(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOCTLUSART_RXPAUSED_SHIFT)) & VFIFO_FIFOCTLUSART_RXPAUSED_MASK) +#define VFIFO_FIFOCTLUSART_RXEMPTY_MASK (0x4U) +#define VFIFO_FIFOCTLUSART_RXEMPTY_SHIFT (2U) +#define VFIFO_FIFOCTLUSART_RXEMPTY(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOCTLUSART_RXEMPTY_SHIFT)) & VFIFO_FIFOCTLUSART_RXEMPTY_MASK) +#define VFIFO_FIFOCTLUSART_TXPAUSE_MASK (0x100U) +#define VFIFO_FIFOCTLUSART_TXPAUSE_SHIFT (8U) +#define VFIFO_FIFOCTLUSART_TXPAUSE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOCTLUSART_TXPAUSE_SHIFT)) & VFIFO_FIFOCTLUSART_TXPAUSE_MASK) +#define VFIFO_FIFOCTLUSART_TXPAUSED_MASK (0x200U) +#define VFIFO_FIFOCTLUSART_TXPAUSED_SHIFT (9U) +#define VFIFO_FIFOCTLUSART_TXPAUSED(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOCTLUSART_TXPAUSED_SHIFT)) & VFIFO_FIFOCTLUSART_TXPAUSED_MASK) +#define VFIFO_FIFOCTLUSART_TXEMPTY_MASK (0x400U) +#define VFIFO_FIFOCTLUSART_TXEMPTY_SHIFT (10U) +#define VFIFO_FIFOCTLUSART_TXEMPTY(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOCTLUSART_TXEMPTY_SHIFT)) & VFIFO_FIFOCTLUSART_TXEMPTY_MASK) +#define VFIFO_FIFOCTLUSART_RXFIFOTOTAL_MASK (0xFF0000U) +#define VFIFO_FIFOCTLUSART_RXFIFOTOTAL_SHIFT (16U) +#define VFIFO_FIFOCTLUSART_RXFIFOTOTAL(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOCTLUSART_RXFIFOTOTAL_SHIFT)) & VFIFO_FIFOCTLUSART_RXFIFOTOTAL_MASK) +#define VFIFO_FIFOCTLUSART_TXFIFOTOTAL_MASK (0xFF000000U) +#define VFIFO_FIFOCTLUSART_TXFIFOTOTAL_SHIFT (24U) +#define VFIFO_FIFOCTLUSART_TXFIFOTOTAL(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOCTLUSART_TXFIFOTOTAL_SHIFT)) & VFIFO_FIFOCTLUSART_TXFIFOTOTAL_MASK) + +/*! @name FIFOUPDATEUSART - USART FIFO global update register */ +#define VFIFO_FIFOUPDATEUSART_USART0RXUPDATESIZE_MASK (0x1U) +#define VFIFO_FIFOUPDATEUSART_USART0RXUPDATESIZE_SHIFT (0U) +#define VFIFO_FIFOUPDATEUSART_USART0RXUPDATESIZE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOUPDATEUSART_USART0RXUPDATESIZE_SHIFT)) & VFIFO_FIFOUPDATEUSART_USART0RXUPDATESIZE_MASK) +#define VFIFO_FIFOUPDATEUSART_USART1RXUPDATESIZE_MASK (0x2U) +#define VFIFO_FIFOUPDATEUSART_USART1RXUPDATESIZE_SHIFT (1U) +#define VFIFO_FIFOUPDATEUSART_USART1RXUPDATESIZE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOUPDATEUSART_USART1RXUPDATESIZE_SHIFT)) & VFIFO_FIFOUPDATEUSART_USART1RXUPDATESIZE_MASK) +#define VFIFO_FIFOUPDATEUSART_USART2RXUPDATESIZE_MASK (0x4U) +#define VFIFO_FIFOUPDATEUSART_USART2RXUPDATESIZE_SHIFT (2U) +#define VFIFO_FIFOUPDATEUSART_USART2RXUPDATESIZE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOUPDATEUSART_USART2RXUPDATESIZE_SHIFT)) & VFIFO_FIFOUPDATEUSART_USART2RXUPDATESIZE_MASK) +#define VFIFO_FIFOUPDATEUSART_USART3RXUPDATESIZE_MASK (0x8U) +#define VFIFO_FIFOUPDATEUSART_USART3RXUPDATESIZE_SHIFT (3U) +#define VFIFO_FIFOUPDATEUSART_USART3RXUPDATESIZE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOUPDATEUSART_USART3RXUPDATESIZE_SHIFT)) & VFIFO_FIFOUPDATEUSART_USART3RXUPDATESIZE_MASK) +#define VFIFO_FIFOUPDATEUSART_USART0TXUPDATESIZE_MASK (0x10000U) +#define VFIFO_FIFOUPDATEUSART_USART0TXUPDATESIZE_SHIFT (16U) +#define VFIFO_FIFOUPDATEUSART_USART0TXUPDATESIZE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOUPDATEUSART_USART0TXUPDATESIZE_SHIFT)) & VFIFO_FIFOUPDATEUSART_USART0TXUPDATESIZE_MASK) +#define VFIFO_FIFOUPDATEUSART_USART1TXUPDATESIZE_MASK (0x20000U) +#define VFIFO_FIFOUPDATEUSART_USART1TXUPDATESIZE_SHIFT (17U) +#define VFIFO_FIFOUPDATEUSART_USART1TXUPDATESIZE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOUPDATEUSART_USART1TXUPDATESIZE_SHIFT)) & VFIFO_FIFOUPDATEUSART_USART1TXUPDATESIZE_MASK) +#define VFIFO_FIFOUPDATEUSART_USART2TXUPDATESIZE_MASK (0x40000U) +#define VFIFO_FIFOUPDATEUSART_USART2TXUPDATESIZE_SHIFT (18U) +#define VFIFO_FIFOUPDATEUSART_USART2TXUPDATESIZE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOUPDATEUSART_USART2TXUPDATESIZE_SHIFT)) & VFIFO_FIFOUPDATEUSART_USART2TXUPDATESIZE_MASK) +#define VFIFO_FIFOUPDATEUSART_USART3TXUPDATESIZE_MASK (0x80000U) +#define VFIFO_FIFOUPDATEUSART_USART3TXUPDATESIZE_SHIFT (19U) +#define VFIFO_FIFOUPDATEUSART_USART3TXUPDATESIZE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOUPDATEUSART_USART3TXUPDATESIZE_SHIFT)) & VFIFO_FIFOUPDATEUSART_USART3TXUPDATESIZE_MASK) + +/*! @name FIFOCFGUSART - FIFO configuration register for USART0 */ +#define VFIFO_FIFOCFGUSART_RXSIZE_MASK (0xFFU) +#define VFIFO_FIFOCFGUSART_RXSIZE_SHIFT (0U) +#define VFIFO_FIFOCFGUSART_RXSIZE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOCFGUSART_RXSIZE_SHIFT)) & VFIFO_FIFOCFGUSART_RXSIZE_MASK) +#define VFIFO_FIFOCFGUSART_TXSIZE_MASK (0xFF00U) +#define VFIFO_FIFOCFGUSART_TXSIZE_SHIFT (8U) +#define VFIFO_FIFOCFGUSART_TXSIZE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOCFGUSART_TXSIZE_SHIFT)) & VFIFO_FIFOCFGUSART_TXSIZE_MASK) + +/* The count of VFIFO_FIFOCFGUSART */ +#define VFIFO_FIFOCFGUSART_COUNT (4U) + +/*! @name FIFOCTLSPI - SPI FIFO global control register. These registers are byte, halfword, and word addressable. The upper 16 bits of these registers provide information about the System FIFO configuration, and are specific to each device type. */ +#define VFIFO_FIFOCTLSPI_RXPAUSE_MASK (0x1U) +#define VFIFO_FIFOCTLSPI_RXPAUSE_SHIFT (0U) +#define VFIFO_FIFOCTLSPI_RXPAUSE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOCTLSPI_RXPAUSE_SHIFT)) & VFIFO_FIFOCTLSPI_RXPAUSE_MASK) +#define VFIFO_FIFOCTLSPI_RXPAUSED_MASK (0x2U) +#define VFIFO_FIFOCTLSPI_RXPAUSED_SHIFT (1U) +#define VFIFO_FIFOCTLSPI_RXPAUSED(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOCTLSPI_RXPAUSED_SHIFT)) & VFIFO_FIFOCTLSPI_RXPAUSED_MASK) +#define VFIFO_FIFOCTLSPI_RXEMPTY_MASK (0x4U) +#define VFIFO_FIFOCTLSPI_RXEMPTY_SHIFT (2U) +#define VFIFO_FIFOCTLSPI_RXEMPTY(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOCTLSPI_RXEMPTY_SHIFT)) & VFIFO_FIFOCTLSPI_RXEMPTY_MASK) +#define VFIFO_FIFOCTLSPI_TXPAUSE_MASK (0x100U) +#define VFIFO_FIFOCTLSPI_TXPAUSE_SHIFT (8U) +#define VFIFO_FIFOCTLSPI_TXPAUSE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOCTLSPI_TXPAUSE_SHIFT)) & VFIFO_FIFOCTLSPI_TXPAUSE_MASK) +#define VFIFO_FIFOCTLSPI_TXPAUSED_MASK (0x200U) +#define VFIFO_FIFOCTLSPI_TXPAUSED_SHIFT (9U) +#define VFIFO_FIFOCTLSPI_TXPAUSED(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOCTLSPI_TXPAUSED_SHIFT)) & VFIFO_FIFOCTLSPI_TXPAUSED_MASK) +#define VFIFO_FIFOCTLSPI_TXEMPTY_MASK (0x400U) +#define VFIFO_FIFOCTLSPI_TXEMPTY_SHIFT (10U) +#define VFIFO_FIFOCTLSPI_TXEMPTY(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOCTLSPI_TXEMPTY_SHIFT)) & VFIFO_FIFOCTLSPI_TXEMPTY_MASK) +#define VFIFO_FIFOCTLSPI_RXFIFOTOTAL_MASK (0xFF0000U) +#define VFIFO_FIFOCTLSPI_RXFIFOTOTAL_SHIFT (16U) +#define VFIFO_FIFOCTLSPI_RXFIFOTOTAL(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOCTLSPI_RXFIFOTOTAL_SHIFT)) & VFIFO_FIFOCTLSPI_RXFIFOTOTAL_MASK) +#define VFIFO_FIFOCTLSPI_TXFIFOTOTAL_MASK (0xFF000000U) +#define VFIFO_FIFOCTLSPI_TXFIFOTOTAL_SHIFT (24U) +#define VFIFO_FIFOCTLSPI_TXFIFOTOTAL(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOCTLSPI_TXFIFOTOTAL_SHIFT)) & VFIFO_FIFOCTLSPI_TXFIFOTOTAL_MASK) + +/*! @name FIFOUPDATESPI - SPI FIFO global update register */ +#define VFIFO_FIFOUPDATESPI_SPI0RXUPDATESIZE_MASK (0x1U) +#define VFIFO_FIFOUPDATESPI_SPI0RXUPDATESIZE_SHIFT (0U) +#define VFIFO_FIFOUPDATESPI_SPI0RXUPDATESIZE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOUPDATESPI_SPI0RXUPDATESIZE_SHIFT)) & VFIFO_FIFOUPDATESPI_SPI0RXUPDATESIZE_MASK) +#define VFIFO_FIFOUPDATESPI_SPI1RXUPDATESIZE_MASK (0x2U) +#define VFIFO_FIFOUPDATESPI_SPI1RXUPDATESIZE_SHIFT (1U) +#define VFIFO_FIFOUPDATESPI_SPI1RXUPDATESIZE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOUPDATESPI_SPI1RXUPDATESIZE_SHIFT)) & VFIFO_FIFOUPDATESPI_SPI1RXUPDATESIZE_MASK) +#define VFIFO_FIFOUPDATESPI_SPI0TXUPDATESIZE_MASK (0x10000U) +#define VFIFO_FIFOUPDATESPI_SPI0TXUPDATESIZE_SHIFT (16U) +#define VFIFO_FIFOUPDATESPI_SPI0TXUPDATESIZE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOUPDATESPI_SPI0TXUPDATESIZE_SHIFT)) & VFIFO_FIFOUPDATESPI_SPI0TXUPDATESIZE_MASK) +#define VFIFO_FIFOUPDATESPI_SPI1TXUPDATESIZE_MASK (0x20000U) +#define VFIFO_FIFOUPDATESPI_SPI1TXUPDATESIZE_SHIFT (17U) +#define VFIFO_FIFOUPDATESPI_SPI1TXUPDATESIZE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOUPDATESPI_SPI1TXUPDATESIZE_SHIFT)) & VFIFO_FIFOUPDATESPI_SPI1TXUPDATESIZE_MASK) + +/*! @name FIFOCFGSPI - FIFO configuration register for SPI0 */ +#define VFIFO_FIFOCFGSPI_RXSIZE_MASK (0xFFU) +#define VFIFO_FIFOCFGSPI_RXSIZE_SHIFT (0U) +#define VFIFO_FIFOCFGSPI_RXSIZE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOCFGSPI_RXSIZE_SHIFT)) & VFIFO_FIFOCFGSPI_RXSIZE_MASK) +#define VFIFO_FIFOCFGSPI_TXSIZE_MASK (0xFF00U) +#define VFIFO_FIFOCFGSPI_TXSIZE_SHIFT (8U) +#define VFIFO_FIFOCFGSPI_TXSIZE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOCFGSPI_TXSIZE_SHIFT)) & VFIFO_FIFOCFGSPI_TXSIZE_MASK) + +/* The count of VFIFO_FIFOCFGSPI */ +#define VFIFO_FIFOCFGSPI_COUNT (2U) + +/*! @name USART_CFGUSART - USART0 configuration */ +#define VFIFO_USART_CFGUSART_TIMEOUTCONTONWRITE_MASK (0x10U) +#define VFIFO_USART_CFGUSART_TIMEOUTCONTONWRITE_SHIFT (4U) +#define VFIFO_USART_CFGUSART_TIMEOUTCONTONWRITE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_CFGUSART_TIMEOUTCONTONWRITE_SHIFT)) & VFIFO_USART_CFGUSART_TIMEOUTCONTONWRITE_MASK) +#define VFIFO_USART_CFGUSART_TIMEOUTCONTONEMPTY_MASK (0x20U) +#define VFIFO_USART_CFGUSART_TIMEOUTCONTONEMPTY_SHIFT (5U) +#define VFIFO_USART_CFGUSART_TIMEOUTCONTONEMPTY(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_CFGUSART_TIMEOUTCONTONEMPTY_SHIFT)) & VFIFO_USART_CFGUSART_TIMEOUTCONTONEMPTY_MASK) +#define VFIFO_USART_CFGUSART_TIMEOUTBASE_MASK (0xF00U) +#define VFIFO_USART_CFGUSART_TIMEOUTBASE_SHIFT (8U) +#define VFIFO_USART_CFGUSART_TIMEOUTBASE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_CFGUSART_TIMEOUTBASE_SHIFT)) & VFIFO_USART_CFGUSART_TIMEOUTBASE_MASK) +#define VFIFO_USART_CFGUSART_TIMEOUTVALUE_MASK (0xF000U) +#define VFIFO_USART_CFGUSART_TIMEOUTVALUE_SHIFT (12U) +#define VFIFO_USART_CFGUSART_TIMEOUTVALUE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_CFGUSART_TIMEOUTVALUE_SHIFT)) & VFIFO_USART_CFGUSART_TIMEOUTVALUE_MASK) +#define VFIFO_USART_CFGUSART_RXTHRESHOLD_MASK (0xFF0000U) +#define VFIFO_USART_CFGUSART_RXTHRESHOLD_SHIFT (16U) +#define VFIFO_USART_CFGUSART_RXTHRESHOLD(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_CFGUSART_RXTHRESHOLD_SHIFT)) & VFIFO_USART_CFGUSART_RXTHRESHOLD_MASK) +#define VFIFO_USART_CFGUSART_TXTHRESHOLD_MASK (0xFF000000U) +#define VFIFO_USART_CFGUSART_TXTHRESHOLD_SHIFT (24U) +#define VFIFO_USART_CFGUSART_TXTHRESHOLD(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_CFGUSART_TXTHRESHOLD_SHIFT)) & VFIFO_USART_CFGUSART_TXTHRESHOLD_MASK) + +/* The count of VFIFO_USART_CFGUSART */ +#define VFIFO_USART_CFGUSART_COUNT (4U) + +/*! @name USART_STATUSART - USART0 status */ +#define VFIFO_USART_STATUSART_RXTH_MASK (0x1U) +#define VFIFO_USART_STATUSART_RXTH_SHIFT (0U) +#define VFIFO_USART_STATUSART_RXTH(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_STATUSART_RXTH_SHIFT)) & VFIFO_USART_STATUSART_RXTH_MASK) +#define VFIFO_USART_STATUSART_TXTH_MASK (0x2U) +#define VFIFO_USART_STATUSART_TXTH_SHIFT (1U) +#define VFIFO_USART_STATUSART_TXTH(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_STATUSART_TXTH_SHIFT)) & VFIFO_USART_STATUSART_TXTH_MASK) +#define VFIFO_USART_STATUSART_RXTIMEOUT_MASK (0x10U) +#define VFIFO_USART_STATUSART_RXTIMEOUT_SHIFT (4U) +#define VFIFO_USART_STATUSART_RXTIMEOUT(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_STATUSART_RXTIMEOUT_SHIFT)) & VFIFO_USART_STATUSART_RXTIMEOUT_MASK) +#define VFIFO_USART_STATUSART_BUSERR_MASK (0x80U) +#define VFIFO_USART_STATUSART_BUSERR_SHIFT (7U) +#define VFIFO_USART_STATUSART_BUSERR(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_STATUSART_BUSERR_SHIFT)) & VFIFO_USART_STATUSART_BUSERR_MASK) +#define VFIFO_USART_STATUSART_RXEMPTY_MASK (0x100U) +#define VFIFO_USART_STATUSART_RXEMPTY_SHIFT (8U) +#define VFIFO_USART_STATUSART_RXEMPTY(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_STATUSART_RXEMPTY_SHIFT)) & VFIFO_USART_STATUSART_RXEMPTY_MASK) +#define VFIFO_USART_STATUSART_TXEMPTY_MASK (0x200U) +#define VFIFO_USART_STATUSART_TXEMPTY_SHIFT (9U) +#define VFIFO_USART_STATUSART_TXEMPTY(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_STATUSART_TXEMPTY_SHIFT)) & VFIFO_USART_STATUSART_TXEMPTY_MASK) +#define VFIFO_USART_STATUSART_RXCOUNT_MASK (0xFF0000U) +#define VFIFO_USART_STATUSART_RXCOUNT_SHIFT (16U) +#define VFIFO_USART_STATUSART_RXCOUNT(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_STATUSART_RXCOUNT_SHIFT)) & VFIFO_USART_STATUSART_RXCOUNT_MASK) +#define VFIFO_USART_STATUSART_TXCOUNT_MASK (0xFF000000U) +#define VFIFO_USART_STATUSART_TXCOUNT_SHIFT (24U) +#define VFIFO_USART_STATUSART_TXCOUNT(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_STATUSART_TXCOUNT_SHIFT)) & VFIFO_USART_STATUSART_TXCOUNT_MASK) + +/* The count of VFIFO_USART_STATUSART */ +#define VFIFO_USART_STATUSART_COUNT (4U) + +/*! @name USART_INTSTATUSART - USART0 interrupt status */ +#define VFIFO_USART_INTSTATUSART_RXTH_MASK (0x1U) +#define VFIFO_USART_INTSTATUSART_RXTH_SHIFT (0U) +#define VFIFO_USART_INTSTATUSART_RXTH(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_INTSTATUSART_RXTH_SHIFT)) & VFIFO_USART_INTSTATUSART_RXTH_MASK) +#define VFIFO_USART_INTSTATUSART_TXTH_MASK (0x2U) +#define VFIFO_USART_INTSTATUSART_TXTH_SHIFT (1U) +#define VFIFO_USART_INTSTATUSART_TXTH(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_INTSTATUSART_TXTH_SHIFT)) & VFIFO_USART_INTSTATUSART_TXTH_MASK) +#define VFIFO_USART_INTSTATUSART_RXTIMEOUT_MASK (0x10U) +#define VFIFO_USART_INTSTATUSART_RXTIMEOUT_SHIFT (4U) +#define VFIFO_USART_INTSTATUSART_RXTIMEOUT(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_INTSTATUSART_RXTIMEOUT_SHIFT)) & VFIFO_USART_INTSTATUSART_RXTIMEOUT_MASK) +#define VFIFO_USART_INTSTATUSART_BUSERR_MASK (0x80U) +#define VFIFO_USART_INTSTATUSART_BUSERR_SHIFT (7U) +#define VFIFO_USART_INTSTATUSART_BUSERR(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_INTSTATUSART_BUSERR_SHIFT)) & VFIFO_USART_INTSTATUSART_BUSERR_MASK) +#define VFIFO_USART_INTSTATUSART_RXEMPTY_MASK (0x100U) +#define VFIFO_USART_INTSTATUSART_RXEMPTY_SHIFT (8U) +#define VFIFO_USART_INTSTATUSART_RXEMPTY(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_INTSTATUSART_RXEMPTY_SHIFT)) & VFIFO_USART_INTSTATUSART_RXEMPTY_MASK) +#define VFIFO_USART_INTSTATUSART_TXEMPTY_MASK (0x200U) +#define VFIFO_USART_INTSTATUSART_TXEMPTY_SHIFT (9U) +#define VFIFO_USART_INTSTATUSART_TXEMPTY(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_INTSTATUSART_TXEMPTY_SHIFT)) & VFIFO_USART_INTSTATUSART_TXEMPTY_MASK) +#define VFIFO_USART_INTSTATUSART_RXCOUNT_MASK (0xFF0000U) +#define VFIFO_USART_INTSTATUSART_RXCOUNT_SHIFT (16U) +#define VFIFO_USART_INTSTATUSART_RXCOUNT(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_INTSTATUSART_RXCOUNT_SHIFT)) & VFIFO_USART_INTSTATUSART_RXCOUNT_MASK) +#define VFIFO_USART_INTSTATUSART_TXCOUNT_MASK (0xFF000000U) +#define VFIFO_USART_INTSTATUSART_TXCOUNT_SHIFT (24U) +#define VFIFO_USART_INTSTATUSART_TXCOUNT(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_INTSTATUSART_TXCOUNT_SHIFT)) & VFIFO_USART_INTSTATUSART_TXCOUNT_MASK) + +/* The count of VFIFO_USART_INTSTATUSART */ +#define VFIFO_USART_INTSTATUSART_COUNT (4U) + +/*! @name USART_CTLSETUSART - USART0 control read and set register. A complete value may be read from this register. Writing a 1 to any implemented bit position causes that bit to be set. */ +#define VFIFO_USART_CTLSETUSART_RXTHINTEN_MASK (0x1U) +#define VFIFO_USART_CTLSETUSART_RXTHINTEN_SHIFT (0U) +#define VFIFO_USART_CTLSETUSART_RXTHINTEN(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_CTLSETUSART_RXTHINTEN_SHIFT)) & VFIFO_USART_CTLSETUSART_RXTHINTEN_MASK) +#define VFIFO_USART_CTLSETUSART_TXTHINTEN_MASK (0x2U) +#define VFIFO_USART_CTLSETUSART_TXTHINTEN_SHIFT (1U) +#define VFIFO_USART_CTLSETUSART_TXTHINTEN(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_CTLSETUSART_TXTHINTEN_SHIFT)) & VFIFO_USART_CTLSETUSART_TXTHINTEN_MASK) +#define VFIFO_USART_CTLSETUSART_RXTIMEOUTINTEN_MASK (0x10U) +#define VFIFO_USART_CTLSETUSART_RXTIMEOUTINTEN_SHIFT (4U) +#define VFIFO_USART_CTLSETUSART_RXTIMEOUTINTEN(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_CTLSETUSART_RXTIMEOUTINTEN_SHIFT)) & VFIFO_USART_CTLSETUSART_RXTIMEOUTINTEN_MASK) +#define VFIFO_USART_CTLSETUSART_RXFLUSH_MASK (0x100U) +#define VFIFO_USART_CTLSETUSART_RXFLUSH_SHIFT (8U) +#define VFIFO_USART_CTLSETUSART_RXFLUSH(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_CTLSETUSART_RXFLUSH_SHIFT)) & VFIFO_USART_CTLSETUSART_RXFLUSH_MASK) +#define VFIFO_USART_CTLSETUSART_TXFLUSH_MASK (0x200U) +#define VFIFO_USART_CTLSETUSART_TXFLUSH_SHIFT (9U) +#define VFIFO_USART_CTLSETUSART_TXFLUSH(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_CTLSETUSART_TXFLUSH_SHIFT)) & VFIFO_USART_CTLSETUSART_TXFLUSH_MASK) + +/* The count of VFIFO_USART_CTLSETUSART */ +#define VFIFO_USART_CTLSETUSART_COUNT (4U) + +/*! @name USART_CTLCLRUSART - USART0 control clear register. Writing a 1 to any implemented bit position causes the corresponding bit in the related CTLSET register to be cleared. */ +#define VFIFO_USART_CTLCLRUSART_RXTHINTCLR_MASK (0x1U) +#define VFIFO_USART_CTLCLRUSART_RXTHINTCLR_SHIFT (0U) +#define VFIFO_USART_CTLCLRUSART_RXTHINTCLR(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_CTLCLRUSART_RXTHINTCLR_SHIFT)) & VFIFO_USART_CTLCLRUSART_RXTHINTCLR_MASK) +#define VFIFO_USART_CTLCLRUSART_TXTHINTCLR_MASK (0x2U) +#define VFIFO_USART_CTLCLRUSART_TXTHINTCLR_SHIFT (1U) +#define VFIFO_USART_CTLCLRUSART_TXTHINTCLR(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_CTLCLRUSART_TXTHINTCLR_SHIFT)) & VFIFO_USART_CTLCLRUSART_TXTHINTCLR_MASK) +#define VFIFO_USART_CTLCLRUSART_RXTIMEOUTINTCLR_MASK (0x10U) +#define VFIFO_USART_CTLCLRUSART_RXTIMEOUTINTCLR_SHIFT (4U) +#define VFIFO_USART_CTLCLRUSART_RXTIMEOUTINTCLR(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_CTLCLRUSART_RXTIMEOUTINTCLR_SHIFT)) & VFIFO_USART_CTLCLRUSART_RXTIMEOUTINTCLR_MASK) +#define VFIFO_USART_CTLCLRUSART_RXFLUSHCLR_MASK (0x100U) +#define VFIFO_USART_CTLCLRUSART_RXFLUSHCLR_SHIFT (8U) +#define VFIFO_USART_CTLCLRUSART_RXFLUSHCLR(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_CTLCLRUSART_RXFLUSHCLR_SHIFT)) & VFIFO_USART_CTLCLRUSART_RXFLUSHCLR_MASK) +#define VFIFO_USART_CTLCLRUSART_TXFLUSHCLR_MASK (0x200U) +#define VFIFO_USART_CTLCLRUSART_TXFLUSHCLR_SHIFT (9U) +#define VFIFO_USART_CTLCLRUSART_TXFLUSHCLR(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_CTLCLRUSART_TXFLUSHCLR_SHIFT)) & VFIFO_USART_CTLCLRUSART_TXFLUSHCLR_MASK) + +/* The count of VFIFO_USART_CTLCLRUSART */ +#define VFIFO_USART_CTLCLRUSART_COUNT (4U) + +/*! @name USART_RXDATUSART - USART0 received data */ +#define VFIFO_USART_RXDATUSART_RXDAT_MASK (0x1FFU) +#define VFIFO_USART_RXDATUSART_RXDAT_SHIFT (0U) +#define VFIFO_USART_RXDATUSART_RXDAT(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_RXDATUSART_RXDAT_SHIFT)) & VFIFO_USART_RXDATUSART_RXDAT_MASK) + +/* The count of VFIFO_USART_RXDATUSART */ +#define VFIFO_USART_RXDATUSART_COUNT (4U) + +/*! @name USART_RXDATSTATUSART - USART0 received data with status */ +#define VFIFO_USART_RXDATSTATUSART_RXDAT_MASK (0x1FFU) +#define VFIFO_USART_RXDATSTATUSART_RXDAT_SHIFT (0U) +#define VFIFO_USART_RXDATSTATUSART_RXDAT(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_RXDATSTATUSART_RXDAT_SHIFT)) & VFIFO_USART_RXDATSTATUSART_RXDAT_MASK) +#define VFIFO_USART_RXDATSTATUSART_FRAMERR_MASK (0x2000U) +#define VFIFO_USART_RXDATSTATUSART_FRAMERR_SHIFT (13U) +#define VFIFO_USART_RXDATSTATUSART_FRAMERR(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_RXDATSTATUSART_FRAMERR_SHIFT)) & VFIFO_USART_RXDATSTATUSART_FRAMERR_MASK) +#define VFIFO_USART_RXDATSTATUSART_PARITYERR_MASK (0x4000U) +#define VFIFO_USART_RXDATSTATUSART_PARITYERR_SHIFT (14U) +#define VFIFO_USART_RXDATSTATUSART_PARITYERR(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_RXDATSTATUSART_PARITYERR_SHIFT)) & VFIFO_USART_RXDATSTATUSART_PARITYERR_MASK) +#define VFIFO_USART_RXDATSTATUSART_RXNOISE_MASK (0x8000U) +#define VFIFO_USART_RXDATSTATUSART_RXNOISE_SHIFT (15U) +#define VFIFO_USART_RXDATSTATUSART_RXNOISE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_RXDATSTATUSART_RXNOISE_SHIFT)) & VFIFO_USART_RXDATSTATUSART_RXNOISE_MASK) + +/* The count of VFIFO_USART_RXDATSTATUSART */ +#define VFIFO_USART_RXDATSTATUSART_COUNT (4U) + +/*! @name USART_TXDATUSART - USART0 transmit data */ +#define VFIFO_USART_TXDATUSART_TXDAT_MASK (0x1FFU) +#define VFIFO_USART_TXDATUSART_TXDAT_SHIFT (0U) +#define VFIFO_USART_TXDATUSART_TXDAT(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_TXDATUSART_TXDAT_SHIFT)) & VFIFO_USART_TXDATUSART_TXDAT_MASK) + +/* The count of VFIFO_USART_TXDATUSART */ +#define VFIFO_USART_TXDATUSART_COUNT (4U) + +/*! @name SPI_CFGSPI - SPI0 configuration */ +#define VFIFO_SPI_CFGSPI_TIMEOUTCONTONWRITE_MASK (0x10U) +#define VFIFO_SPI_CFGSPI_TIMEOUTCONTONWRITE_SHIFT (4U) +#define VFIFO_SPI_CFGSPI_TIMEOUTCONTONWRITE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_CFGSPI_TIMEOUTCONTONWRITE_SHIFT)) & VFIFO_SPI_CFGSPI_TIMEOUTCONTONWRITE_MASK) +#define VFIFO_SPI_CFGSPI_TIMEOUTCONTONEMPTY_MASK (0x20U) +#define VFIFO_SPI_CFGSPI_TIMEOUTCONTONEMPTY_SHIFT (5U) +#define VFIFO_SPI_CFGSPI_TIMEOUTCONTONEMPTY(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_CFGSPI_TIMEOUTCONTONEMPTY_SHIFT)) & VFIFO_SPI_CFGSPI_TIMEOUTCONTONEMPTY_MASK) +#define VFIFO_SPI_CFGSPI_TIMEOUTBASE_MASK (0xF00U) +#define VFIFO_SPI_CFGSPI_TIMEOUTBASE_SHIFT (8U) +#define VFIFO_SPI_CFGSPI_TIMEOUTBASE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_CFGSPI_TIMEOUTBASE_SHIFT)) & VFIFO_SPI_CFGSPI_TIMEOUTBASE_MASK) +#define VFIFO_SPI_CFGSPI_TIMEOUTVALUE_MASK (0xF000U) +#define VFIFO_SPI_CFGSPI_TIMEOUTVALUE_SHIFT (12U) +#define VFIFO_SPI_CFGSPI_TIMEOUTVALUE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_CFGSPI_TIMEOUTVALUE_SHIFT)) & VFIFO_SPI_CFGSPI_TIMEOUTVALUE_MASK) +#define VFIFO_SPI_CFGSPI_RXTHRESHOLD_MASK (0xFF0000U) +#define VFIFO_SPI_CFGSPI_RXTHRESHOLD_SHIFT (16U) +#define VFIFO_SPI_CFGSPI_RXTHRESHOLD(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_CFGSPI_RXTHRESHOLD_SHIFT)) & VFIFO_SPI_CFGSPI_RXTHRESHOLD_MASK) +#define VFIFO_SPI_CFGSPI_TXTHRESHOLD_MASK (0xFF000000U) +#define VFIFO_SPI_CFGSPI_TXTHRESHOLD_SHIFT (24U) +#define VFIFO_SPI_CFGSPI_TXTHRESHOLD(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_CFGSPI_TXTHRESHOLD_SHIFT)) & VFIFO_SPI_CFGSPI_TXTHRESHOLD_MASK) + +/* The count of VFIFO_SPI_CFGSPI */ +#define VFIFO_SPI_CFGSPI_COUNT (2U) + +/*! @name SPI_STATSPI - SPI0 status */ +#define VFIFO_SPI_STATSPI_RXTH_MASK (0x1U) +#define VFIFO_SPI_STATSPI_RXTH_SHIFT (0U) +#define VFIFO_SPI_STATSPI_RXTH(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_STATSPI_RXTH_SHIFT)) & VFIFO_SPI_STATSPI_RXTH_MASK) +#define VFIFO_SPI_STATSPI_TXTH_MASK (0x2U) +#define VFIFO_SPI_STATSPI_TXTH_SHIFT (1U) +#define VFIFO_SPI_STATSPI_TXTH(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_STATSPI_TXTH_SHIFT)) & VFIFO_SPI_STATSPI_TXTH_MASK) +#define VFIFO_SPI_STATSPI_RXTIMEOUT_MASK (0x10U) +#define VFIFO_SPI_STATSPI_RXTIMEOUT_SHIFT (4U) +#define VFIFO_SPI_STATSPI_RXTIMEOUT(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_STATSPI_RXTIMEOUT_SHIFT)) & VFIFO_SPI_STATSPI_RXTIMEOUT_MASK) +#define VFIFO_SPI_STATSPI_BUSERR_MASK (0x80U) +#define VFIFO_SPI_STATSPI_BUSERR_SHIFT (7U) +#define VFIFO_SPI_STATSPI_BUSERR(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_STATSPI_BUSERR_SHIFT)) & VFIFO_SPI_STATSPI_BUSERR_MASK) +#define VFIFO_SPI_STATSPI_RXEMPTY_MASK (0x100U) +#define VFIFO_SPI_STATSPI_RXEMPTY_SHIFT (8U) +#define VFIFO_SPI_STATSPI_RXEMPTY(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_STATSPI_RXEMPTY_SHIFT)) & VFIFO_SPI_STATSPI_RXEMPTY_MASK) +#define VFIFO_SPI_STATSPI_TXEMPTY_MASK (0x200U) +#define VFIFO_SPI_STATSPI_TXEMPTY_SHIFT (9U) +#define VFIFO_SPI_STATSPI_TXEMPTY(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_STATSPI_TXEMPTY_SHIFT)) & VFIFO_SPI_STATSPI_TXEMPTY_MASK) +#define VFIFO_SPI_STATSPI_RXCOUNT_MASK (0xFF0000U) +#define VFIFO_SPI_STATSPI_RXCOUNT_SHIFT (16U) +#define VFIFO_SPI_STATSPI_RXCOUNT(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_STATSPI_RXCOUNT_SHIFT)) & VFIFO_SPI_STATSPI_RXCOUNT_MASK) +#define VFIFO_SPI_STATSPI_TXCOUNT_MASK (0xFF000000U) +#define VFIFO_SPI_STATSPI_TXCOUNT_SHIFT (24U) +#define VFIFO_SPI_STATSPI_TXCOUNT(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_STATSPI_TXCOUNT_SHIFT)) & VFIFO_SPI_STATSPI_TXCOUNT_MASK) + +/* The count of VFIFO_SPI_STATSPI */ +#define VFIFO_SPI_STATSPI_COUNT (2U) + +/*! @name SPI_INTSTATSPI - SPI0 interrupt status */ +#define VFIFO_SPI_INTSTATSPI_RXTH_MASK (0x1U) +#define VFIFO_SPI_INTSTATSPI_RXTH_SHIFT (0U) +#define VFIFO_SPI_INTSTATSPI_RXTH(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_INTSTATSPI_RXTH_SHIFT)) & VFIFO_SPI_INTSTATSPI_RXTH_MASK) +#define VFIFO_SPI_INTSTATSPI_TXTH_MASK (0x2U) +#define VFIFO_SPI_INTSTATSPI_TXTH_SHIFT (1U) +#define VFIFO_SPI_INTSTATSPI_TXTH(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_INTSTATSPI_TXTH_SHIFT)) & VFIFO_SPI_INTSTATSPI_TXTH_MASK) +#define VFIFO_SPI_INTSTATSPI_RXTIMEOUT_MASK (0x10U) +#define VFIFO_SPI_INTSTATSPI_RXTIMEOUT_SHIFT (4U) +#define VFIFO_SPI_INTSTATSPI_RXTIMEOUT(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_INTSTATSPI_RXTIMEOUT_SHIFT)) & VFIFO_SPI_INTSTATSPI_RXTIMEOUT_MASK) +#define VFIFO_SPI_INTSTATSPI_BUSERR_MASK (0x80U) +#define VFIFO_SPI_INTSTATSPI_BUSERR_SHIFT (7U) +#define VFIFO_SPI_INTSTATSPI_BUSERR(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_INTSTATSPI_BUSERR_SHIFT)) & VFIFO_SPI_INTSTATSPI_BUSERR_MASK) +#define VFIFO_SPI_INTSTATSPI_RXEMPTY_MASK (0x100U) +#define VFIFO_SPI_INTSTATSPI_RXEMPTY_SHIFT (8U) +#define VFIFO_SPI_INTSTATSPI_RXEMPTY(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_INTSTATSPI_RXEMPTY_SHIFT)) & VFIFO_SPI_INTSTATSPI_RXEMPTY_MASK) +#define VFIFO_SPI_INTSTATSPI_TXEMPTY_MASK (0x200U) +#define VFIFO_SPI_INTSTATSPI_TXEMPTY_SHIFT (9U) +#define VFIFO_SPI_INTSTATSPI_TXEMPTY(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_INTSTATSPI_TXEMPTY_SHIFT)) & VFIFO_SPI_INTSTATSPI_TXEMPTY_MASK) +#define VFIFO_SPI_INTSTATSPI_RXCOUNT_MASK (0xFF0000U) +#define VFIFO_SPI_INTSTATSPI_RXCOUNT_SHIFT (16U) +#define VFIFO_SPI_INTSTATSPI_RXCOUNT(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_INTSTATSPI_RXCOUNT_SHIFT)) & VFIFO_SPI_INTSTATSPI_RXCOUNT_MASK) +#define VFIFO_SPI_INTSTATSPI_TXCOUNT_MASK (0xFF000000U) +#define VFIFO_SPI_INTSTATSPI_TXCOUNT_SHIFT (24U) +#define VFIFO_SPI_INTSTATSPI_TXCOUNT(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_INTSTATSPI_TXCOUNT_SHIFT)) & VFIFO_SPI_INTSTATSPI_TXCOUNT_MASK) + +/* The count of VFIFO_SPI_INTSTATSPI */ +#define VFIFO_SPI_INTSTATSPI_COUNT (2U) + +/*! @name SPI_CTLSETSPI - SPI0 control read and set register. A complete value may be read from this register. Writing a 1 to any implemented bit position causes that bit to be set. */ +#define VFIFO_SPI_CTLSETSPI_RXTHINTEN_MASK (0x1U) +#define VFIFO_SPI_CTLSETSPI_RXTHINTEN_SHIFT (0U) +#define VFIFO_SPI_CTLSETSPI_RXTHINTEN(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_CTLSETSPI_RXTHINTEN_SHIFT)) & VFIFO_SPI_CTLSETSPI_RXTHINTEN_MASK) +#define VFIFO_SPI_CTLSETSPI_TXTHINTEN_MASK (0x2U) +#define VFIFO_SPI_CTLSETSPI_TXTHINTEN_SHIFT (1U) +#define VFIFO_SPI_CTLSETSPI_TXTHINTEN(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_CTLSETSPI_TXTHINTEN_SHIFT)) & VFIFO_SPI_CTLSETSPI_TXTHINTEN_MASK) +#define VFIFO_SPI_CTLSETSPI_RXTIMEOUTINTEN_MASK (0x10U) +#define VFIFO_SPI_CTLSETSPI_RXTIMEOUTINTEN_SHIFT (4U) +#define VFIFO_SPI_CTLSETSPI_RXTIMEOUTINTEN(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_CTLSETSPI_RXTIMEOUTINTEN_SHIFT)) & VFIFO_SPI_CTLSETSPI_RXTIMEOUTINTEN_MASK) +#define VFIFO_SPI_CTLSETSPI_RXFLUSH_MASK (0x100U) +#define VFIFO_SPI_CTLSETSPI_RXFLUSH_SHIFT (8U) +#define VFIFO_SPI_CTLSETSPI_RXFLUSH(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_CTLSETSPI_RXFLUSH_SHIFT)) & VFIFO_SPI_CTLSETSPI_RXFLUSH_MASK) +#define VFIFO_SPI_CTLSETSPI_TXFLUSH_MASK (0x200U) +#define VFIFO_SPI_CTLSETSPI_TXFLUSH_SHIFT (9U) +#define VFIFO_SPI_CTLSETSPI_TXFLUSH(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_CTLSETSPI_TXFLUSH_SHIFT)) & VFIFO_SPI_CTLSETSPI_TXFLUSH_MASK) + +/* The count of VFIFO_SPI_CTLSETSPI */ +#define VFIFO_SPI_CTLSETSPI_COUNT (2U) + +/*! @name SPI_CTLCLRSPI - SPI0 control clear register. Writing a 1 to any implemented bit position causes the corresponding bit in the related CTLSET register to be cleared. */ +#define VFIFO_SPI_CTLCLRSPI_RXTHINTCLR_MASK (0x1U) +#define VFIFO_SPI_CTLCLRSPI_RXTHINTCLR_SHIFT (0U) +#define VFIFO_SPI_CTLCLRSPI_RXTHINTCLR(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_CTLCLRSPI_RXTHINTCLR_SHIFT)) & VFIFO_SPI_CTLCLRSPI_RXTHINTCLR_MASK) +#define VFIFO_SPI_CTLCLRSPI_TXTHINTCLR_MASK (0x2U) +#define VFIFO_SPI_CTLCLRSPI_TXTHINTCLR_SHIFT (1U) +#define VFIFO_SPI_CTLCLRSPI_TXTHINTCLR(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_CTLCLRSPI_TXTHINTCLR_SHIFT)) & VFIFO_SPI_CTLCLRSPI_TXTHINTCLR_MASK) +#define VFIFO_SPI_CTLCLRSPI_RXTIMEOUTINTCLR_MASK (0x10U) +#define VFIFO_SPI_CTLCLRSPI_RXTIMEOUTINTCLR_SHIFT (4U) +#define VFIFO_SPI_CTLCLRSPI_RXTIMEOUTINTCLR(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_CTLCLRSPI_RXTIMEOUTINTCLR_SHIFT)) & VFIFO_SPI_CTLCLRSPI_RXTIMEOUTINTCLR_MASK) +#define VFIFO_SPI_CTLCLRSPI_RXFLUSHCLR_MASK (0x100U) +#define VFIFO_SPI_CTLCLRSPI_RXFLUSHCLR_SHIFT (8U) +#define VFIFO_SPI_CTLCLRSPI_RXFLUSHCLR(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_CTLCLRSPI_RXFLUSHCLR_SHIFT)) & VFIFO_SPI_CTLCLRSPI_RXFLUSHCLR_MASK) +#define VFIFO_SPI_CTLCLRSPI_TXFLUSHCLR_MASK (0x200U) +#define VFIFO_SPI_CTLCLRSPI_TXFLUSHCLR_SHIFT (9U) +#define VFIFO_SPI_CTLCLRSPI_TXFLUSHCLR(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_CTLCLRSPI_TXFLUSHCLR_SHIFT)) & VFIFO_SPI_CTLCLRSPI_TXFLUSHCLR_MASK) + +/* The count of VFIFO_SPI_CTLCLRSPI */ +#define VFIFO_SPI_CTLCLRSPI_COUNT (2U) + +/*! @name SPI_RXDATSPI - SPI0 received data. These registers are half word addressable. */ +#define VFIFO_SPI_RXDATSPI_RXDAT_MASK (0xFFFFU) +#define VFIFO_SPI_RXDATSPI_RXDAT_SHIFT (0U) +#define VFIFO_SPI_RXDATSPI_RXDAT(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_RXDATSPI_RXDAT_SHIFT)) & VFIFO_SPI_RXDATSPI_RXDAT_MASK) +#define VFIFO_SPI_RXDATSPI_RXSSEL0_N_MASK (0x10000U) +#define VFIFO_SPI_RXDATSPI_RXSSEL0_N_SHIFT (16U) +#define VFIFO_SPI_RXDATSPI_RXSSEL0_N(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_RXDATSPI_RXSSEL0_N_SHIFT)) & VFIFO_SPI_RXDATSPI_RXSSEL0_N_MASK) +#define VFIFO_SPI_RXDATSPI_RXSSEL1_N_MASK (0x20000U) +#define VFIFO_SPI_RXDATSPI_RXSSEL1_N_SHIFT (17U) +#define VFIFO_SPI_RXDATSPI_RXSSEL1_N(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_RXDATSPI_RXSSEL1_N_SHIFT)) & VFIFO_SPI_RXDATSPI_RXSSEL1_N_MASK) +#define VFIFO_SPI_RXDATSPI_RXSSEL2_N_MASK (0x40000U) +#define VFIFO_SPI_RXDATSPI_RXSSEL2_N_SHIFT (18U) +#define VFIFO_SPI_RXDATSPI_RXSSEL2_N(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_RXDATSPI_RXSSEL2_N_SHIFT)) & VFIFO_SPI_RXDATSPI_RXSSEL2_N_MASK) +#define VFIFO_SPI_RXDATSPI_RXSSEL3_N_MASK (0x80000U) +#define VFIFO_SPI_RXDATSPI_RXSSEL3_N_SHIFT (19U) +#define VFIFO_SPI_RXDATSPI_RXSSEL3_N(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_RXDATSPI_RXSSEL3_N_SHIFT)) & VFIFO_SPI_RXDATSPI_RXSSEL3_N_MASK) +#define VFIFO_SPI_RXDATSPI_SOT_MASK (0x100000U) +#define VFIFO_SPI_RXDATSPI_SOT_SHIFT (20U) +#define VFIFO_SPI_RXDATSPI_SOT(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_RXDATSPI_SOT_SHIFT)) & VFIFO_SPI_RXDATSPI_SOT_MASK) + +/* The count of VFIFO_SPI_RXDATSPI */ +#define VFIFO_SPI_RXDATSPI_COUNT (2U) + +/*! @name SPI_TXDATSPI - SPI0 transmit data. These registers are half word addressable. */ +#define VFIFO_SPI_TXDATSPI_TXDAT_MASK (0xFFFFU) +#define VFIFO_SPI_TXDATSPI_TXDAT_SHIFT (0U) +#define VFIFO_SPI_TXDATSPI_TXDAT(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_TXDATSPI_TXDAT_SHIFT)) & VFIFO_SPI_TXDATSPI_TXDAT_MASK) +#define VFIFO_SPI_TXDATSPI_TXSSEL0_N_MASK (0x10000U) +#define VFIFO_SPI_TXDATSPI_TXSSEL0_N_SHIFT (16U) +#define VFIFO_SPI_TXDATSPI_TXSSEL0_N(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_TXDATSPI_TXSSEL0_N_SHIFT)) & VFIFO_SPI_TXDATSPI_TXSSEL0_N_MASK) +#define VFIFO_SPI_TXDATSPI_TXSSEL1_N_MASK (0x20000U) +#define VFIFO_SPI_TXDATSPI_TXSSEL1_N_SHIFT (17U) +#define VFIFO_SPI_TXDATSPI_TXSSEL1_N(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_TXDATSPI_TXSSEL1_N_SHIFT)) & VFIFO_SPI_TXDATSPI_TXSSEL1_N_MASK) +#define VFIFO_SPI_TXDATSPI_TXSSEL2_N_MASK (0x40000U) +#define VFIFO_SPI_TXDATSPI_TXSSEL2_N_SHIFT (18U) +#define VFIFO_SPI_TXDATSPI_TXSSEL2_N(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_TXDATSPI_TXSSEL2_N_SHIFT)) & VFIFO_SPI_TXDATSPI_TXSSEL2_N_MASK) +#define VFIFO_SPI_TXDATSPI_TXSSEL3_N_MASK (0x80000U) +#define VFIFO_SPI_TXDATSPI_TXSSEL3_N_SHIFT (19U) +#define VFIFO_SPI_TXDATSPI_TXSSEL3_N(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_TXDATSPI_TXSSEL3_N_SHIFT)) & VFIFO_SPI_TXDATSPI_TXSSEL3_N_MASK) +#define VFIFO_SPI_TXDATSPI_EOT_MASK (0x100000U) +#define VFIFO_SPI_TXDATSPI_EOT_SHIFT (20U) +#define VFIFO_SPI_TXDATSPI_EOT(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_TXDATSPI_EOT_SHIFT)) & VFIFO_SPI_TXDATSPI_EOT_MASK) +#define VFIFO_SPI_TXDATSPI_EOF_MASK (0x200000U) +#define VFIFO_SPI_TXDATSPI_EOF_SHIFT (21U) +#define VFIFO_SPI_TXDATSPI_EOF(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_TXDATSPI_EOF_SHIFT)) & VFIFO_SPI_TXDATSPI_EOF_MASK) +#define VFIFO_SPI_TXDATSPI_RXIGNORE_MASK (0x400000U) +#define VFIFO_SPI_TXDATSPI_RXIGNORE_SHIFT (22U) +#define VFIFO_SPI_TXDATSPI_RXIGNORE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_TXDATSPI_RXIGNORE_SHIFT)) & VFIFO_SPI_TXDATSPI_RXIGNORE_MASK) +#define VFIFO_SPI_TXDATSPI_LEN_MASK (0xF000000U) +#define VFIFO_SPI_TXDATSPI_LEN_SHIFT (24U) +#define VFIFO_SPI_TXDATSPI_LEN(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_TXDATSPI_LEN_SHIFT)) & VFIFO_SPI_TXDATSPI_LEN_MASK) + +/* The count of VFIFO_SPI_TXDATSPI */ +#define VFIFO_SPI_TXDATSPI_COUNT (2U) + + +/*! + * @} + */ /* end of group VFIFO_Register_Masks */ + + +/* VFIFO - Peripheral instance base addresses */ +/** Peripheral VFIFO base address */ +#define VFIFO_BASE (0x1C038000u) +/** Peripheral VFIFO base pointer */ +#define VFIFO ((VFIFO_Type *)VFIFO_BASE) +/** Array initializer of VFIFO peripheral base addresses */ +#define VFIFO_BASE_ADDRS { VFIFO_BASE } +/** Array initializer of VFIFO peripheral base pointers */ +#define VFIFO_BASE_PTRS { VFIFO } + +/*! + * @} + */ /* end of group VFIFO_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- WWDT Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup WWDT_Peripheral_Access_Layer WWDT Peripheral Access Layer + * @{ + */ + +/** WWDT - Register Layout Typedef */ +typedef struct { + __IO uint32_t MOD; /**< Watchdog mode register. This register contains the basic mode and status of the Watchdog Timer., offset: 0x0 */ + __IO uint32_t TC; /**< Watchdog timer constant register. This 24-bit register determines the time-out value., offset: 0x4 */ + __O uint32_t FEED; /**< Watchdog feed sequence register. Writing 0xAA followed by 0x55 to this register reloads the Watchdog timer with the value contained in WDTC., offset: 0x8 */ + __I uint32_t TV; /**< Watchdog timer value register. This 24-bit register reads out the current value of the Watchdog timer., offset: 0xC */ + uint8_t RESERVED_0[4]; + __IO uint32_t WARNINT; /**< Watchdog Warning Interrupt compare value., offset: 0x14 */ + __IO uint32_t WINDOW; /**< Watchdog Window compare value., offset: 0x18 */ +} WWDT_Type; + +/* ---------------------------------------------------------------------------- + -- WWDT Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup WWDT_Register_Masks WWDT Register Masks + * @{ + */ + +/*! @name MOD - Watchdog mode register. This register contains the basic mode and status of the Watchdog Timer. */ +#define WWDT_MOD_WDEN_MASK (0x1U) +#define WWDT_MOD_WDEN_SHIFT (0U) +#define WWDT_MOD_WDEN(x) (((uint32_t)(((uint32_t)(x)) << WWDT_MOD_WDEN_SHIFT)) & WWDT_MOD_WDEN_MASK) +#define WWDT_MOD_WDRESET_MASK (0x2U) +#define WWDT_MOD_WDRESET_SHIFT (1U) +#define WWDT_MOD_WDRESET(x) (((uint32_t)(((uint32_t)(x)) << WWDT_MOD_WDRESET_SHIFT)) & WWDT_MOD_WDRESET_MASK) +#define WWDT_MOD_WDTOF_MASK (0x4U) +#define WWDT_MOD_WDTOF_SHIFT (2U) +#define WWDT_MOD_WDTOF(x) (((uint32_t)(((uint32_t)(x)) << WWDT_MOD_WDTOF_SHIFT)) & WWDT_MOD_WDTOF_MASK) +#define WWDT_MOD_WDINT_MASK (0x8U) +#define WWDT_MOD_WDINT_SHIFT (3U) +#define WWDT_MOD_WDINT(x) (((uint32_t)(((uint32_t)(x)) << WWDT_MOD_WDINT_SHIFT)) & WWDT_MOD_WDINT_MASK) +#define WWDT_MOD_WDPROTECT_MASK (0x10U) +#define WWDT_MOD_WDPROTECT_SHIFT (4U) +#define WWDT_MOD_WDPROTECT(x) (((uint32_t)(((uint32_t)(x)) << WWDT_MOD_WDPROTECT_SHIFT)) & WWDT_MOD_WDPROTECT_MASK) +#define WWDT_MOD_LOCK_MASK (0x20U) +#define WWDT_MOD_LOCK_SHIFT (5U) +#define WWDT_MOD_LOCK(x) (((uint32_t)(((uint32_t)(x)) << WWDT_MOD_LOCK_SHIFT)) & WWDT_MOD_LOCK_MASK) + +/*! @name TC - Watchdog timer constant register. This 24-bit register determines the time-out value. */ +#define WWDT_TC_COUNT_MASK (0xFFFFFFU) +#define WWDT_TC_COUNT_SHIFT (0U) +#define WWDT_TC_COUNT(x) (((uint32_t)(((uint32_t)(x)) << WWDT_TC_COUNT_SHIFT)) & WWDT_TC_COUNT_MASK) + +/*! @name FEED - Watchdog feed sequence register. Writing 0xAA followed by 0x55 to this register reloads the Watchdog timer with the value contained in WDTC. */ +#define WWDT_FEED_FEED_MASK (0xFFU) +#define WWDT_FEED_FEED_SHIFT (0U) +#define WWDT_FEED_FEED(x) (((uint32_t)(((uint32_t)(x)) << WWDT_FEED_FEED_SHIFT)) & WWDT_FEED_FEED_MASK) + +/*! @name TV - Watchdog timer value register. This 24-bit register reads out the current value of the Watchdog timer. */ +#define WWDT_TV_COUNT_MASK (0xFFFFFFU) +#define WWDT_TV_COUNT_SHIFT (0U) +#define WWDT_TV_COUNT(x) (((uint32_t)(((uint32_t)(x)) << WWDT_TV_COUNT_SHIFT)) & WWDT_TV_COUNT_MASK) + +/*! @name WARNINT - Watchdog Warning Interrupt compare value. */ +#define WWDT_WARNINT_WARNINT_MASK (0x3FFU) +#define WWDT_WARNINT_WARNINT_SHIFT (0U) +#define WWDT_WARNINT_WARNINT(x) (((uint32_t)(((uint32_t)(x)) << WWDT_WARNINT_WARNINT_SHIFT)) & WWDT_WARNINT_WARNINT_MASK) + +/*! @name WINDOW - Watchdog Window compare value. */ +#define WWDT_WINDOW_WINDOW_MASK (0xFFFFFFU) +#define WWDT_WINDOW_WINDOW_SHIFT (0U) +#define WWDT_WINDOW_WINDOW(x) (((uint32_t)(((uint32_t)(x)) << WWDT_WINDOW_WINDOW_SHIFT)) & WWDT_WINDOW_WINDOW_MASK) + + +/*! + * @} + */ /* end of group WWDT_Register_Masks */ + + +/* WWDT - Peripheral instance base addresses */ +/** Peripheral WWDT base address */ +#define WWDT_BASE (0x40038000u) +/** Peripheral WWDT base pointer */ +#define WWDT ((WWDT_Type *)WWDT_BASE) +/** Array initializer of WWDT peripheral base addresses */ +#define WWDT_BASE_ADDRS { WWDT_BASE } +/** Array initializer of WWDT peripheral base pointers */ +#define WWDT_BASE_PTRS { WWDT } +/** Interrupt vectors for the WWDT peripheral type */ +#define WWDT_IRQS { WDT_IRQn } + +/*! + * @} + */ /* end of group WWDT_Peripheral_Access_Layer */ + + +/* +** End of section using anonymous unions +*/ + +#if defined(__ARMCC_VERSION) + #pragma pop +#elif defined(__IAR_SYSTEMS_ICC__) + #pragma language=default +#elif defined(__GNUC__) + /* leave anonymous unions enabled */ +#else + #error Not supported compiler type +#endif + +/*! + * @} + */ /* end of group Peripheral_access_layer */ + + +/* ---------------------------------------------------------------------------- + -- Macros for use with bit field definitions (xxx_SHIFT, xxx_MASK). + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup Bit_Field_Generic_Macros Macros for use with bit field definitions (xxx_SHIFT, xxx_MASK). + * @{ + */ + +#if defined(__ARMCC_VERSION) + #if (__ARMCC_VERSION >= 6010050) + #pragma clang system_header + #endif +#elif defined(__IAR_SYSTEMS_ICC__) + #pragma system_include +#endif + +/** + * @brief Mask and left-shift a bit field value for use in a register bit range. + * @param field Name of the register bit field. + * @param value Value of the bit field. + * @return Masked and shifted value. + */ +#define NXP_VAL2FLD(field, value) (((value) << (field ## _SHIFT)) & (field ## _MASK)) +/** + * @brief Mask and right-shift a register value to extract a bit field value. + * @param field Name of the register bit field. + * @param value Value of the register. + * @return Masked and shifted bit field value. + */ +#define NXP_FLD2VAL(field, value) (((value) & (field ## _MASK)) >> (field ## _SHIFT)) + +/*! + * @} + */ /* end of group Bit_Field_Generic_Macros */ + + +/* ---------------------------------------------------------------------------- + -- SDK Compatibility + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SDK_Compatibility_Symbols SDK Compatibility + * @{ + */ + +/* No SDK compatibility issues. */ + +/*! + * @} + */ /* end of group SDK_Compatibility_Symbols */ + + +#endif /* _LPC54102_CM0PLUS_H_ */ + diff --git a/platform/mcu/lpc54102/LPC54102_cm0plus_features.h b/platform/mcu/lpc54102/LPC54102_cm0plus_features.h new file mode 100644 index 0000000000..d3b28758b6 --- /dev/null +++ b/platform/mcu/lpc54102/LPC54102_cm0plus_features.h @@ -0,0 +1,600 @@ +/* +** ################################################################### +** Version: rev. 1.0, 2016-05-09 +** Build: b170512 +** +** Abstract: +** Chip specific module features. +** +** Copyright 2016 Freescale Semiconductor, Inc. +** Copyright 2016-2017 NXP +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o 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. +** +** o Neither the name of the copyright holder nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.nxp.com +** mail: support@nxp.com +** +** Revisions: +** - rev. 1.0 (2016-05-09) +** Initial version. +** +** ################################################################### +*/ + +#ifndef _LPC54102_cm0plus_FEATURES_H_ +#define _LPC54102_cm0plus_FEATURES_H_ + +/* SOC module features */ + +/* @brief ACMP availability on the SoC. */ +#define FSL_FEATURE_SOC_ACMP_COUNT (0) +/* @brief ADC availability on the SoC. */ +#define FSL_FEATURE_SOC_ADC_COUNT (1) +/* @brief ADC12 availability on the SoC. */ +#define FSL_FEATURE_SOC_ADC12_COUNT (0) +/* @brief ADC16 availability on the SoC. */ +#define FSL_FEATURE_SOC_ADC16_COUNT (0) +/* @brief ADC_5HC availability on the SoC. */ +#define FSL_FEATURE_SOC_ADC_5HC_COUNT (0) +/* @brief AES availability on the SoC. */ +#define FSL_FEATURE_SOC_AES_COUNT (0) +/* @brief AFE availability on the SoC. */ +#define FSL_FEATURE_SOC_AFE_COUNT (0) +/* @brief AGC availability on the SoC. */ +#define FSL_FEATURE_SOC_AGC_COUNT (0) +/* @brief AIPS availability on the SoC. */ +#define FSL_FEATURE_SOC_AIPS_COUNT (0) +/* @brief AIPSTZ availability on the SoC. */ +#define FSL_FEATURE_SOC_AIPSTZ_COUNT (0) +/* @brief ANATOP availability on the SoC. */ +#define FSL_FEATURE_SOC_ANATOP_COUNT (0) +/* @brief AOI availability on the SoC. */ +#define FSL_FEATURE_SOC_AOI_COUNT (0) +/* @brief APBH availability on the SoC. */ +#define FSL_FEATURE_SOC_APBH_COUNT (0) +/* @brief ASMC availability on the SoC. */ +#define FSL_FEATURE_SOC_ASMC_COUNT (0) +/* @brief ASRC availability on the SoC. */ +#define FSL_FEATURE_SOC_ASRC_COUNT (0) +/* @brief ASYNC_SYSCON availability on the SoC. */ +#define FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT (1) +/* @brief ATX availability on the SoC. */ +#define FSL_FEATURE_SOC_ATX_COUNT (0) +/* @brief AXBS availability on the SoC. */ +#define FSL_FEATURE_SOC_AXBS_COUNT (0) +/* @brief BCH availability on the SoC. */ +#define FSL_FEATURE_SOC_BCH_COUNT (0) +/* @brief BLEDP availability on the SoC. */ +#define FSL_FEATURE_SOC_BLEDP_COUNT (0) +/* @brief BOD availability on the SoC. */ +#define FSL_FEATURE_SOC_BOD_COUNT (0) +/* @brief CAAM availability on the SoC. */ +#define FSL_FEATURE_SOC_CAAM_COUNT (0) +/* @brief CADC availability on the SoC. */ +#define FSL_FEATURE_SOC_CADC_COUNT (0) +/* @brief CALIB availability on the SoC. */ +#define FSL_FEATURE_SOC_CALIB_COUNT (0) +/* @brief CAN availability on the SoC. */ +#define FSL_FEATURE_SOC_LPC_CAN_COUNT (0) +/* @brief CAU availability on the SoC. */ +#define FSL_FEATURE_SOC_CAU_COUNT (0) +/* @brief CAU3 availability on the SoC. */ +#define FSL_FEATURE_SOC_CAU3_COUNT (0) +/* @brief CCM availability on the SoC. */ +#define FSL_FEATURE_SOC_CCM_COUNT (0) +/* @brief CCM_ANALOG availability on the SoC. */ +#define FSL_FEATURE_SOC_CCM_ANALOG_COUNT (0) +/* @brief CHRG availability on the SoC. */ +#define FSL_FEATURE_SOC_CHRG_COUNT (0) +/* @brief CMP availability on the SoC. */ +#define FSL_FEATURE_SOC_CMP_COUNT (0) +/* @brief CMT availability on the SoC. */ +#define FSL_FEATURE_SOC_CMT_COUNT (0) +/* @brief CNC availability on the SoC. */ +#define FSL_FEATURE_SOC_CNC_COUNT (0) +/* @brief COP availability on the SoC. */ +#define FSL_FEATURE_SOC_COP_COUNT (0) +/* @brief CRC availability on the SoC. */ +#define FSL_FEATURE_SOC_CRC_COUNT (1) +/* @brief CS availability on the SoC. */ +#define FSL_FEATURE_SOC_CS_COUNT (0) +/* @brief CSI availability on the SoC. */ +#define FSL_FEATURE_SOC_CSI_COUNT (0) +/* @brief CT32B availability on the SoC. */ +#define FSL_FEATURE_SOC_CT32B_COUNT (0) +/* @brief CTI availability on the SoC. */ +#define FSL_FEATURE_SOC_CTI_COUNT (0) +/* @brief CTIMER availability on the SoC. */ +#define FSL_FEATURE_SOC_CTIMER_COUNT (5) +/* @brief DAC availability on the SoC. */ +#define FSL_FEATURE_SOC_DAC_COUNT (0) +/* @brief DAC32 availability on the SoC. */ +#define FSL_FEATURE_SOC_DAC32_COUNT (0) +/* @brief DCDC availability on the SoC. */ +#define FSL_FEATURE_SOC_DCDC_COUNT (0) +/* @brief DCP availability on the SoC. */ +#define FSL_FEATURE_SOC_DCP_COUNT (0) +/* @brief DDR availability on the SoC. */ +#define FSL_FEATURE_SOC_DDR_COUNT (0) +/* @brief DDRC availability on the SoC. */ +#define FSL_FEATURE_SOC_DDRC_COUNT (0) +/* @brief DDRC_MP availability on the SoC. */ +#define FSL_FEATURE_SOC_DDRC_MP_COUNT (0) +/* @brief DDR_PHY availability on the SoC. */ +#define FSL_FEATURE_SOC_DDR_PHY_COUNT (0) +/* @brief DMA availability on the SoC. */ +#define FSL_FEATURE_SOC_DMA_COUNT (1) +/* @brief DMAMUX availability on the SoC. */ +#define FSL_FEATURE_SOC_DMAMUX_COUNT (0) +/* @brief DMIC availability on the SoC. */ +#define FSL_FEATURE_SOC_DMIC_COUNT (0) +/* @brief DRY availability on the SoC. */ +#define FSL_FEATURE_SOC_DRY_COUNT (0) +/* @brief DSPI availability on the SoC. */ +#define FSL_FEATURE_SOC_DSPI_COUNT (0) +/* @brief ECSPI availability on the SoC. */ +#define FSL_FEATURE_SOC_ECSPI_COUNT (0) +/* @brief EDMA availability on the SoC. */ +#define FSL_FEATURE_SOC_EDMA_COUNT (0) +/* @brief EEPROM availability on the SoC. */ +#define FSL_FEATURE_SOC_EEPROM_COUNT (0) +/* @brief EIM availability on the SoC. */ +#define FSL_FEATURE_SOC_EIM_COUNT (0) +/* @brief EMC availability on the SoC. */ +#define FSL_FEATURE_SOC_EMC_COUNT (0) +/* @brief EMVSIM availability on the SoC. */ +#define FSL_FEATURE_SOC_EMVSIM_COUNT (0) +/* @brief ENC availability on the SoC. */ +#define FSL_FEATURE_SOC_ENC_COUNT (0) +/* @brief ENET availability on the SoC. */ +#define FSL_FEATURE_SOC_LPC_ENET_COUNT (0) +/* @brief EPDC availability on the SoC. */ +#define FSL_FEATURE_SOC_EPDC_COUNT (0) +/* @brief EPIT availability on the SoC. */ +#define FSL_FEATURE_SOC_EPIT_COUNT (0) +/* @brief ESAI availability on the SoC. */ +#define FSL_FEATURE_SOC_ESAI_COUNT (0) +/* @brief EWM availability on the SoC. */ +#define FSL_FEATURE_SOC_EWM_COUNT (0) +/* @brief FB availability on the SoC. */ +#define FSL_FEATURE_SOC_FB_COUNT (0) +/* @brief FGPIO availability on the SoC. */ +#define FSL_FEATURE_SOC_FGPIO_COUNT (0) +/* @brief FLASH availability on the SoC. */ +#define FSL_FEATURE_SOC_FLASH_COUNT (0) +/* @brief FLEXCAN availability on the SoC. */ +#define FSL_FEATURE_SOC_FLEXCAN_COUNT (0) +/* @brief FLEXCOMM availability on the SoC. */ +#define FSL_FEATURE_SOC_FLEXCOMM_COUNT (0) +/* @brief FLEXIO availability on the SoC. */ +#define FSL_FEATURE_SOC_FLEXIO_COUNT (0) +/* @brief FLEXRAM availability on the SoC. */ +#define FSL_FEATURE_SOC_FLEXRAM_COUNT (0) +/* @brief FLEXSPI availability on the SoC. */ +#define FSL_FEATURE_SOC_FLEXSPI_COUNT (0) +/* @brief FMC availability on the SoC. */ +#define FSL_FEATURE_SOC_FMC_COUNT (0) +/* @brief FSKDT availability on the SoC. */ +#define FSL_FEATURE_SOC_FSKDT_COUNT (0) +/* @brief FSP availability on the SoC. */ +#define FSL_FEATURE_SOC_FSP_COUNT (0) +/* @brief FTFA availability on the SoC. */ +#define FSL_FEATURE_SOC_FTFA_COUNT (0) +/* @brief FTFE availability on the SoC. */ +#define FSL_FEATURE_SOC_FTFE_COUNT (0) +/* @brief FTFL availability on the SoC. */ +#define FSL_FEATURE_SOC_FTFL_COUNT (0) +/* @brief FTM availability on the SoC. */ +#define FSL_FEATURE_SOC_FTM_COUNT (0) +/* @brief FTMRA availability on the SoC. */ +#define FSL_FEATURE_SOC_FTMRA_COUNT (0) +/* @brief FTMRE availability on the SoC. */ +#define FSL_FEATURE_SOC_FTMRE_COUNT (0) +/* @brief FTMRH availability on the SoC. */ +#define FSL_FEATURE_SOC_FTMRH_COUNT (0) +/* @brief GINT availability on the SoC. */ +#define FSL_FEATURE_SOC_GINT_COUNT (2) +/* @brief GPC availability on the SoC. */ +#define FSL_FEATURE_SOC_GPC_COUNT (0) +/* @brief GPC_PGC availability on the SoC. */ +#define FSL_FEATURE_SOC_GPC_PGC_COUNT (0) +/* @brief GPIO availability on the SoC. */ +#define FSL_FEATURE_SOC_GPIO_COUNT (1) +/* @brief GPMI availability on the SoC. */ +#define FSL_FEATURE_SOC_GPMI_COUNT (0) +/* @brief GPT availability on the SoC. */ +#define FSL_FEATURE_SOC_GPT_COUNT (0) +/* @brief HSADC availability on the SoC. */ +#define FSL_FEATURE_SOC_HSADC_COUNT (0) +/* @brief I2C availability on the SoC. */ +#define FSL_FEATURE_SOC_I2C_COUNT (3) +/* @brief I2S availability on the SoC. */ +#define FSL_FEATURE_SOC_I2S_COUNT (0) +/* @brief ICS availability on the SoC. */ +#define FSL_FEATURE_SOC_ICS_COUNT (0) +/* @brief IEE availability on the SoC. */ +#define FSL_FEATURE_SOC_IEE_COUNT (0) +/* @brief IEER availability on the SoC. */ +#define FSL_FEATURE_SOC_IEER_COUNT (0) +/* @brief IGPIO availability on the SoC. */ +#define FSL_FEATURE_SOC_IGPIO_COUNT (0) +/* @brief II2C availability on the SoC. */ +#define FSL_FEATURE_SOC_II2C_COUNT (0) +/* @brief INPUTMUX availability on the SoC. */ +#define FSL_FEATURE_SOC_INPUTMUX_COUNT (1) +/* @brief INTMUX availability on the SoC. */ +#define FSL_FEATURE_SOC_INTMUX_COUNT (0) +/* @brief IOCON availability on the SoC. */ +#define FSL_FEATURE_SOC_IOCON_COUNT (1) +/* @brief IOMUXC availability on the SoC. */ +#define FSL_FEATURE_SOC_IOMUXC_COUNT (0) +/* @brief IOMUXC_GPR availability on the SoC. */ +#define FSL_FEATURE_SOC_IOMUXC_GPR_COUNT (0) +/* @brief IOMUXC_LPSR availability on the SoC. */ +#define FSL_FEATURE_SOC_IOMUXC_LPSR_COUNT (0) +/* @brief IOMUXC_LPSR_GPR availability on the SoC. */ +#define FSL_FEATURE_SOC_IOMUXC_LPSR_GPR_COUNT (0) +/* @brief IOMUXC_SNVS availability on the SoC. */ +#define FSL_FEATURE_SOC_IOMUXC_SNVS_COUNT (0) +/* @brief IPWM availability on the SoC. */ +#define FSL_FEATURE_SOC_IPWM_COUNT (0) +/* @brief IRQ availability on the SoC. */ +#define FSL_FEATURE_SOC_IRQ_COUNT (0) +/* @brief IUART availability on the SoC. */ +#define FSL_FEATURE_SOC_IUART_COUNT (0) +/* @brief KBI availability on the SoC. */ +#define FSL_FEATURE_SOC_KBI_COUNT (0) +/* @brief KPP availability on the SoC. */ +#define FSL_FEATURE_SOC_KPP_COUNT (0) +/* @brief L2CACHEC availability on the SoC. */ +#define FSL_FEATURE_SOC_L2CACHEC_COUNT (0) +/* @brief LCD availability on the SoC. */ +#define FSL_FEATURE_SOC_LCD_COUNT (0) +/* @brief LCDC availability on the SoC. */ +#define FSL_FEATURE_SOC_LCDC_COUNT (0) +/* @brief LCDIF availability on the SoC. */ +#define FSL_FEATURE_SOC_LCDIF_COUNT (0) +/* @brief LDO availability on the SoC. */ +#define FSL_FEATURE_SOC_LDO_COUNT (0) +/* @brief LLWU availability on the SoC. */ +#define FSL_FEATURE_SOC_LLWU_COUNT (0) +/* @brief LMEM availability on the SoC. */ +#define FSL_FEATURE_SOC_LMEM_COUNT (0) +/* @brief LPADC availability on the SoC. */ +#define FSL_FEATURE_SOC_LPADC_COUNT (0) +/* @brief LPCMP availability on the SoC. */ +#define FSL_FEATURE_SOC_LPCMP_COUNT (0) +/* @brief LPDAC availability on the SoC. */ +#define FSL_FEATURE_SOC_LPDAC_COUNT (0) +/* @brief LPI2C availability on the SoC. */ +#define FSL_FEATURE_SOC_LPI2C_COUNT (0) +/* @brief LPIT availability on the SoC. */ +#define FSL_FEATURE_SOC_LPIT_COUNT (0) +/* @brief LPSCI availability on the SoC. */ +#define FSL_FEATURE_SOC_LPSCI_COUNT (0) +/* @brief LPSPI availability on the SoC. */ +#define FSL_FEATURE_SOC_LPSPI_COUNT (0) +/* @brief LPTMR availability on the SoC. */ +#define FSL_FEATURE_SOC_LPTMR_COUNT (0) +/* @brief LPTPM availability on the SoC. */ +#define FSL_FEATURE_SOC_LPTPM_COUNT (0) +/* @brief LPUART availability on the SoC. */ +#define FSL_FEATURE_SOC_LPUART_COUNT (0) +/* @brief LTC availability on the SoC. */ +#define FSL_FEATURE_SOC_LTC_COUNT (0) +/* @brief MAILBOX availability on the SoC. */ +#define FSL_FEATURE_SOC_MAILBOX_COUNT (1) +/* @brief MC availability on the SoC. */ +#define FSL_FEATURE_SOC_MC_COUNT (0) +/* @brief MCG availability on the SoC. */ +#define FSL_FEATURE_SOC_MCG_COUNT (0) +/* @brief MCGLITE availability on the SoC. */ +#define FSL_FEATURE_SOC_MCGLITE_COUNT (0) +/* @brief MCM availability on the SoC. */ +#define FSL_FEATURE_SOC_MCM_COUNT (0) +/* @brief MIPI_CSI2 availability on the SoC. */ +#define FSL_FEATURE_SOC_MIPI_CSI2_COUNT (0) +/* @brief MIPI_DSI availability on the SoC. */ +#define FSL_FEATURE_SOC_MIPI_DSI_COUNT (0) +/* @brief MIPI_DSI_HOST availability on the SoC. */ +#define FSL_FEATURE_SOC_MIPI_DSI_HOST_COUNT (0) +/* @brief MMAU availability on the SoC. */ +#define FSL_FEATURE_SOC_MMAU_COUNT (0) +/* @brief MMCAU availability on the SoC. */ +#define FSL_FEATURE_SOC_MMCAU_COUNT (0) +/* @brief MMDC availability on the SoC. */ +#define FSL_FEATURE_SOC_MMDC_COUNT (0) +/* @brief MMDVSQ availability on the SoC. */ +#define FSL_FEATURE_SOC_MMDVSQ_COUNT (0) +/* @brief MPU availability on the SoC. */ +#define FSL_FEATURE_SOC_MPU_COUNT (0) +/* @brief MRT availability on the SoC. */ +#define FSL_FEATURE_SOC_MRT_COUNT (1) +/* @brief MSCAN availability on the SoC. */ +#define FSL_FEATURE_SOC_MSCAN_COUNT (0) +/* @brief MSCM availability on the SoC. */ +#define FSL_FEATURE_SOC_MSCM_COUNT (0) +/* @brief MTB availability on the SoC. */ +#define FSL_FEATURE_SOC_MTB_COUNT (0) +/* @brief MTBDWT availability on the SoC. */ +#define FSL_FEATURE_SOC_MTBDWT_COUNT (0) +/* @brief MU availability on the SoC. */ +#define FSL_FEATURE_SOC_MU_COUNT (0) +/* @brief NFC availability on the SoC. */ +#define FSL_FEATURE_SOC_NFC_COUNT (0) +/* @brief OCOTP availability on the SoC. */ +#define FSL_FEATURE_SOC_OCOTP_COUNT (0) +/* @brief OPAMP availability on the SoC. */ +#define FSL_FEATURE_SOC_OPAMP_COUNT (0) +/* @brief OSC availability on the SoC. */ +#define FSL_FEATURE_SOC_OSC_COUNT (0) +/* @brief OSC32 availability on the SoC. */ +#define FSL_FEATURE_SOC_OSC32_COUNT (0) +/* @brief OTFAD availability on the SoC. */ +#define FSL_FEATURE_SOC_OTFAD_COUNT (0) +/* @brief PCC availability on the SoC. */ +#define FSL_FEATURE_SOC_PCC_COUNT (0) +/* @brief PCIE_PHY_CMN availability on the SoC. */ +#define FSL_FEATURE_SOC_PCIE_PHY_CMN_COUNT (0) +/* @brief PCIE_PHY_TRSV availability on the SoC. */ +#define FSL_FEATURE_SOC_PCIE_PHY_TRSV_COUNT (0) +/* @brief PDB availability on the SoC. */ +#define FSL_FEATURE_SOC_PDB_COUNT (0) +/* @brief PGA availability on the SoC. */ +#define FSL_FEATURE_SOC_PGA_COUNT (0) +/* @brief PINT availability on the SoC. */ +#define FSL_FEATURE_SOC_PINT_COUNT (1) +/* @brief PIT availability on the SoC. */ +#define FSL_FEATURE_SOC_PIT_COUNT (0) +/* @brief PMC availability on the SoC. */ +#define FSL_FEATURE_SOC_PMC_COUNT (0) +/* @brief PMU availability on the SoC. */ +#define FSL_FEATURE_SOC_PMU_COUNT (0) +/* @brief PORT availability on the SoC. */ +#define FSL_FEATURE_SOC_PORT_COUNT (0) +/* @brief PROP availability on the SoC. */ +#define FSL_FEATURE_SOC_PROP_COUNT (0) +/* @brief PWM availability on the SoC. */ +#define FSL_FEATURE_SOC_PWM_COUNT (0) +/* @brief PWT availability on the SoC. */ +#define FSL_FEATURE_SOC_PWT_COUNT (0) +/* @brief PXP availability on the SoC. */ +#define FSL_FEATURE_SOC_PXP_COUNT (0) +/* @brief QDEC availability on the SoC. */ +#define FSL_FEATURE_SOC_QDEC_COUNT (0) +/* @brief QuadSPI availability on the SoC. */ +#define FSL_FEATURE_SOC_QuadSPI_COUNT (0) +/* @brief RCM availability on the SoC. */ +#define FSL_FEATURE_SOC_RCM_COUNT (0) +/* @brief RDC availability on the SoC. */ +#define FSL_FEATURE_SOC_RDC_COUNT (0) +/* @brief RDC_SEMAPHORE availability on the SoC. */ +#define FSL_FEATURE_SOC_RDC_SEMAPHORE_COUNT (0) +/* @brief RFSYS availability on the SoC. */ +#define FSL_FEATURE_SOC_RFSYS_COUNT (0) +/* @brief RFVBAT availability on the SoC. */ +#define FSL_FEATURE_SOC_RFVBAT_COUNT (0) +/* @brief RIT availability on the SoC. */ +#define FSL_FEATURE_SOC_RIT_COUNT (1) +/* @brief RNG availability on the SoC. */ +#define FSL_FEATURE_SOC_LPC_RNG_COUNT (0) +/* @brief RNGB availability on the SoC. */ +#define FSL_FEATURE_SOC_RNGB_COUNT (0) +/* @brief ROM availability on the SoC. */ +#define FSL_FEATURE_SOC_ROM_COUNT (0) +/* @brief ROMC availability on the SoC. */ +#define FSL_FEATURE_SOC_ROMC_COUNT (0) +/* @brief RSIM availability on the SoC. */ +#define FSL_FEATURE_SOC_RSIM_COUNT (0) +/* @brief RTC availability on the SoC. */ +#define FSL_FEATURE_SOC_RTC_COUNT (1) +/* @brief SCG availability on the SoC. */ +#define FSL_FEATURE_SOC_SCG_COUNT (0) +/* @brief SCI availability on the SoC. */ +#define FSL_FEATURE_SOC_SCI_COUNT (0) +/* @brief SCT availability on the SoC. */ +#define FSL_FEATURE_SOC_SCT_COUNT (1) +/* @brief SDHC availability on the SoC. */ +#define FSL_FEATURE_SOC_SDHC_COUNT (0) +/* @brief SDIF availability on the SoC. */ +#define FSL_FEATURE_SOC_SDIF_COUNT (0) +/* @brief SDIO availability on the SoC. */ +#define FSL_FEATURE_SOC_SDIO_COUNT (0) +/* @brief SDMA availability on the SoC. */ +#define FSL_FEATURE_SOC_SDMA_COUNT (0) +/* @brief SDMAARM availability on the SoC. */ +#define FSL_FEATURE_SOC_SDMAARM_COUNT (0) +/* @brief SDMABP availability on the SoC. */ +#define FSL_FEATURE_SOC_SDMABP_COUNT (0) +/* @brief SDMACORE availability on the SoC. */ +#define FSL_FEATURE_SOC_SDMACORE_COUNT (0) +/* @brief SDMCORE availability on the SoC. */ +#define FSL_FEATURE_SOC_SDMCORE_COUNT (0) +/* @brief SDRAM availability on the SoC. */ +#define FSL_FEATURE_SOC_SDRAM_COUNT (0) +/* @brief SEMA4 availability on the SoC. */ +#define FSL_FEATURE_SOC_SEMA4_COUNT (0) +/* @brief SEMA42 availability on the SoC. */ +#define FSL_FEATURE_SOC_SEMA42_COUNT (0) +/* @brief SHA availability on the SoC. */ +#define FSL_FEATURE_SOC_SHA_COUNT (0) +/* @brief SIM availability on the SoC. */ +#define FSL_FEATURE_SOC_SIM_COUNT (0) +/* @brief SIMDGO availability on the SoC. */ +#define FSL_FEATURE_SOC_SIMDGO_COUNT (0) +/* @brief SJC availability on the SoC. */ +#define FSL_FEATURE_SOC_SJC_COUNT (0) +/* @brief SLCD availability on the SoC. */ +#define FSL_FEATURE_SOC_SLCD_COUNT (0) +/* @brief SMARTCARD availability on the SoC. */ +#define FSL_FEATURE_SOC_SMARTCARD_COUNT (0) +/* @brief SMC availability on the SoC. */ +#define FSL_FEATURE_SOC_SMC_COUNT (0) +/* @brief SNVS availability on the SoC. */ +#define FSL_FEATURE_SOC_SNVS_COUNT (0) +/* @brief SPBA availability on the SoC. */ +#define FSL_FEATURE_SOC_SPBA_COUNT (0) +/* @brief SPDIF availability on the SoC. */ +#define FSL_FEATURE_SOC_SPDIF_COUNT (0) +/* @brief SPI availability on the SoC. */ +#define FSL_FEATURE_SOC_SPI_COUNT (2) +/* @brief SPIFI availability on the SoC. */ +#define FSL_FEATURE_SOC_SPIFI_COUNT (0) +/* @brief SPM availability on the SoC. */ +#define FSL_FEATURE_SOC_SPM_COUNT (0) +/* @brief SRC availability on the SoC. */ +#define FSL_FEATURE_SOC_SRC_COUNT (0) +/* @brief SYSCON availability on the SoC. */ +#define FSL_FEATURE_SOC_SYSCON_COUNT (1) +/* @brief TEMPMON availability on the SoC. */ +#define FSL_FEATURE_SOC_TEMPMON_COUNT (0) +/* @brief TMR availability on the SoC. */ +#define FSL_FEATURE_SOC_TMR_COUNT (0) +/* @brief TPM availability on the SoC. */ +#define FSL_FEATURE_SOC_TPM_COUNT (0) +/* @brief TRGMUX availability on the SoC. */ +#define FSL_FEATURE_SOC_TRGMUX_COUNT (0) +/* @brief TRIAMP availability on the SoC. */ +#define FSL_FEATURE_SOC_TRIAMP_COUNT (0) +/* @brief TRNG availability on the SoC. */ +#define FSL_FEATURE_SOC_TRNG_COUNT (0) +/* @brief TSC availability on the SoC. */ +#define FSL_FEATURE_SOC_TSC_COUNT (0) +/* @brief TSI availability on the SoC. */ +#define FSL_FEATURE_SOC_TSI_COUNT (0) +/* @brief TSTMR availability on the SoC. */ +#define FSL_FEATURE_SOC_TSTMR_COUNT (0) +/* @brief UART availability on the SoC. */ +#define FSL_FEATURE_SOC_UART_COUNT (0) +/* @brief USART availability on the SoC. */ +#define FSL_FEATURE_SOC_USART_COUNT (4) +/* @brief USB availability on the SoC. */ +#define FSL_FEATURE_SOC_USB_COUNT (0) +/* @brief USBHS availability on the SoC. */ +#define FSL_FEATURE_SOC_USBHS_COUNT (0) +/* @brief USBDCD availability on the SoC. */ +#define FSL_FEATURE_SOC_USBDCD_COUNT (0) +/* @brief USBFSH availability on the SoC. */ +#define FSL_FEATURE_SOC_USBFSH_COUNT (0) +/* @brief USBHSD availability on the SoC. */ +#define FSL_FEATURE_SOC_USBHSD_COUNT (0) +/* @brief USBHSDCD availability on the SoC. */ +#define FSL_FEATURE_SOC_USBHSDCD_COUNT (0) +/* @brief USBHSH availability on the SoC. */ +#define FSL_FEATURE_SOC_USBHSH_COUNT (0) +/* @brief USBNC availability on the SoC. */ +#define FSL_FEATURE_SOC_USBNC_COUNT (0) +/* @brief USBPHY availability on the SoC. */ +#define FSL_FEATURE_SOC_USBPHY_COUNT (0) +/* @brief USB_HSIC availability on the SoC. */ +#define FSL_FEATURE_SOC_USB_HSIC_COUNT (0) +/* @brief USB_OTG availability on the SoC. */ +#define FSL_FEATURE_SOC_USB_OTG_COUNT (0) +/* @brief USDHC availability on the SoC. */ +#define FSL_FEATURE_SOC_USDHC_COUNT (0) +/* @brief UTICK availability on the SoC. */ +#define FSL_FEATURE_SOC_UTICK_COUNT (1) +/* @brief VIU availability on the SoC. */ +#define FSL_FEATURE_SOC_VIU_COUNT (0) +/* @brief VREF availability on the SoC. */ +#define FSL_FEATURE_SOC_VREF_COUNT (0) +/* @brief VFIFO availability on the SoC. */ +#define FSL_FEATURE_SOC_VFIFO_COUNT (1) +/* @brief WDOG availability on the SoC. */ +#define FSL_FEATURE_SOC_WDOG_COUNT (0) +/* @brief WKPU availability on the SoC. */ +#define FSL_FEATURE_SOC_WKPU_COUNT (0) +/* @brief WWDT availability on the SoC. */ +#define FSL_FEATURE_SOC_WWDT_COUNT (1) +/* @brief XBAR availability on the SoC. */ +#define FSL_FEATURE_SOC_XBAR_COUNT (0) +/* @brief XBARA availability on the SoC. */ +#define FSL_FEATURE_SOC_XBARA_COUNT (0) +/* @brief XBARB availability on the SoC. */ +#define FSL_FEATURE_SOC_XBARB_COUNT (0) +/* @brief XCVR availability on the SoC. */ +#define FSL_FEATURE_SOC_XCVR_COUNT (0) +/* @brief XRDC availability on the SoC. */ +#define FSL_FEATURE_SOC_XRDC_COUNT (0) +/* @brief XTALOSC availability on the SoC. */ +#define FSL_FEATURE_SOC_XTALOSC_COUNT (0) +/* @brief XTALOSC24M availability on the SoC. */ +#define FSL_FEATURE_SOC_XTALOSC24M_COUNT (0) +/* @brief ZLL availability on the SoC. */ +#define FSL_FEATURE_SOC_ZLL_COUNT (0) + +/* ADC module features */ + +/* @brief Has input select (register INSEL). */ +#define FSL_FEATURE_ADC_HAS_NO_INSEL (1) + +/* DMA module features */ + +/* @brief Number of channels */ +#define FSL_FEATURE_DMA_NUMBER_OF_CHANNELS (22) + +/* PINT module features */ + +/* @brief Number of connected outputs */ +#define FSL_FEATURE_PINT_NUMBER_OF_CONNECTED_OUTPUTS (4) + +/* RTC module features */ + +/* @brief Has CTRL:RTC_OSC_PD Bit */ +#define FSL_FEATURE_RTC_HAS_NO_OSC_PD (1) + +/* SCT module features */ + +/* @brief Number of events */ +#define FSL_FEATURE_SCT_NUMBER_OF_EVENTS (13) +/* @brief Number of states */ +#define FSL_FEATURE_SCT_NUMBER_OF_STATES (13) +/* @brief Number of match capture */ +#define FSL_FEATURE_SCT_NUMBER_OF_MATCH_CAPTURE (13) + +/* SYSCON module features */ + +#if defined(CPU_LPC54102J256BD64_cm0plus) || defined(CPU_LPC54102J256UK49_cm0plus) + /* @brief Pointer to ROM IAP entry functions */ + #define FSL_FEATURE_SYSCON_IAP_ENTRY_LOCATION (0x03000205) + /* @brief Flash page size in bytes */ + #define FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES (256) + /* @brief Flash sector size in bytes */ + #define FSL_FEATURE_SYSCON_FLASH_SECTOR_SIZE_BYTES (32768) + /* @brief Flash size in bytes */ + #define FSL_FEATURE_SYSCON_FLASH_SIZE_BYTES (262144) +#elif defined(CPU_LPC54102J512BD64_cm0plus) || defined(CPU_LPC54102J512UK49_cm0plus) + /* @brief Pointer to ROM IAP entry functions */ + #define FSL_FEATURE_SYSCON_IAP_ENTRY_LOCATION (0x03000205) + /* @brief Flash page size in bytes */ + #define FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES (256) + /* @brief Flash sector size in bytes */ + #define FSL_FEATURE_SYSCON_FLASH_SECTOR_SIZE_BYTES (32768) + /* @brief Flash size in bytes */ + #define FSL_FEATURE_SYSCON_FLASH_SIZE_BYTES (524288) +#endif /* defined(CPU_LPC54102J256BD64) || defined(CPU_LPC54102J256UK49) */ + +#endif /* _LPC54102_cm0plus_FEATURES_H_ */ + diff --git a/platform/mcu/lpc54102/LPC54102_cm4.h b/platform/mcu/lpc54102/LPC54102_cm4.h new file mode 100644 index 0000000000..c5a6b48cba --- /dev/null +++ b/platform/mcu/lpc54102/LPC54102_cm4.h @@ -0,0 +1,5572 @@ +/* +** ################################################################### +** Processors: LPC54102J256BD64_cm4 +** LPC54102J256UK49_cm4 +** LPC54102J512BD64_cm4 +** LPC54102J512UK49_cm4 +** +** Compilers: Keil ARM C/C++ Compiler +** IAR ANSI C/C++ Compiler for ARM +** MCUXpresso Compiler +** +** Reference manual: LPC5410x User manual Rev. 2.4 25 May 2016 +** Version: rev. 1.0, 2016-04-29 +** Build: b170504 +** +** Abstract: +** CMSIS Peripheral Access Layer for LPC54102_cm4 +** +** Copyright 1997-2016 Freescale Semiconductor, Inc. +** Copyright 2016-2017 NXP +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o 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. +** +** o Neither the name of the copyright holder nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.nxp.com +** mail: support@nxp.com +** +** Revisions: +** - rev. 1.0 (2016-04-29) +** Initial version. +** +** ################################################################### +*/ + +/*! + * @file LPC54102_cm4.h + * @version 1.0 + * @date 2016-04-29 + * @brief CMSIS Peripheral Access Layer for LPC54102_cm4 + * + * CMSIS Peripheral Access Layer for LPC54102_cm4 + */ + +#ifndef _LPC54102_CM4_H_ +#define _LPC54102_CM4_H_ /**< Symbol preventing repeated inclusion */ + +/** Memory map major version (memory maps with equal major version number are + * compatible) */ +#define MCU_MEM_MAP_VERSION 0x0100U +/** Memory map minor version */ +#define MCU_MEM_MAP_VERSION_MINOR 0x0000U + + +/* ---------------------------------------------------------------------------- + -- Interrupt vector numbers + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup Interrupt_vector_numbers Interrupt vector numbers + * @{ + */ + +/** Interrupt Number Definitions */ +#define NUMBER_OF_INT_VECTORS 57 /**< Number of interrupts in the Vector table */ + +typedef enum IRQn { + /* Auxiliary constants */ + NotAvail_IRQn = -128, /**< Not available device specific interrupt */ + + /* Core interrupts */ + NonMaskableInt_IRQn = -14, /**< Non Maskable Interrupt */ + HardFault_IRQn = -13, /**< Cortex-M4 SV Hard Fault Interrupt */ + MemoryManagement_IRQn = -12, /**< Cortex-M4 Memory Management Interrupt */ + BusFault_IRQn = -11, /**< Cortex-M4 Bus Fault Interrupt */ + UsageFault_IRQn = -10, /**< Cortex-M4 Usage Fault Interrupt */ + SVCall_IRQn = -5, /**< Cortex-M4 SV Call Interrupt */ + DebugMonitor_IRQn = -4, /**< Cortex-M4 Debug Monitor Interrupt */ + PendSV_IRQn = -2, /**< Cortex-M4 Pend SV Interrupt */ + SysTick_IRQn = -1, /**< Cortex-M4 System Tick Interrupt */ + + /* Device specific interrupts */ + WDT_IRQn = 0, /**< Windowed watchdog timer, Brownout detect */ + BOD_IRQn = 1, /**< BOD interrupt */ + Reserved18_IRQn = 2, /**< Reserved interrupt */ + DMA0_IRQn = 3, /**< DMA controller */ + GINT0_IRQn = 4, /**< GPIO group 0 */ + PIN_INT0_IRQn = 5, /**< Pin interrupt 0 or pattern match engine slice 0 */ + PIN_INT1_IRQn = 6, /**< Pin interrupt 1or pattern match engine slice 1 */ + PIN_INT2_IRQn = 7, /**< Pin interrupt 2 or pattern match engine slice 2 */ + PIN_INT3_IRQn = 8, /**< Pin interrupt 3 or pattern match engine slice 3 */ + UTICK0_IRQn = 9, /**< Micro-tick Timer */ + MRT0_IRQn = 10, /**< Multi-rate timer */ + CTIMER0_IRQn = 11, /**< Standard counter/timer CTIMER0 */ + CTIMER1_IRQn = 12, /**< Standard counter/timer CTIMER1 */ + CTIMER2_IRQn = 13, /**< Standard counter/timer CTIMER2 */ + CTIMER3_IRQn = 14, /**< Standard counter/timer CTIMER3 */ + CTIMER4_IRQn = 15, /**< Standard counter/timer CTIMER4 */ + SCT0_IRQn = 16, /**< SCTimer/PWM */ + USART0_IRQn = 17, /**< USART0 */ + USART1_IRQn = 18, /**< USART1 */ + USART2_IRQn = 19, /**< USART2 */ + USART3_IRQn = 20, /**< USART3 */ + I2C0_IRQn = 21, /**< I2C0 */ + I2C1_IRQn = 22, /**< I2C1 */ + I2C2_IRQn = 23, /**< I2C2 */ + SPI0_IRQn = 24, /**< SPI0 */ + SPI1_IRQn = 25, /**< SPI1 */ + ADC0_SEQA_IRQn = 26, /**< ADC0 sequence A completion. */ + ADC0_SEQB_IRQn = 27, /**< ADC0 sequence B completion. */ + ADC0_THCMP_IRQn = 28, /**< ADC0 threshold compare and error. */ + RTC_IRQn = 29, /**< RTC alarm and wake-up interrupts */ + Reserved46_IRQn = 30, /**< Reserved interrupt */ + MAILBOX_IRQn = 31, /**< Mailbox interrupt (present on selected devices) */ + GINT1_IRQn = 32, /**< GPIO group 1 */ + PIN_INT4_IRQn = 33, /**< Pin interrupt 4 or pattern match engine slice 4 int */ + PIN_INT5_IRQn = 34, /**< Pin interrupt 5 or pattern match engine slice 5 int */ + PIN_INT6_IRQn = 35, /**< Pin interrupt 6 or pattern match engine slice 6 int */ + PIN_INT7_IRQn = 36, /**< Pin interrupt 7 or pattern match engine slice 7 int */ + Reserved53_IRQn = 37, /**< Reserved interrupt */ + Reserved54_IRQn = 38, /**< Reserved interrupt */ + Reserved55_IRQn = 39, /**< Reserved interrupt */ + RIT_IRQn = 40 /**< Repetitive Interrupt Timer */ +} IRQn_Type; + +/*! + * @} + */ /* end of group Interrupt_vector_numbers */ + + +/* ---------------------------------------------------------------------------- + -- Cortex M4 Core Configuration + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup Cortex_Core_Configuration Cortex M4 Core Configuration + * @{ + */ + +#define __MPU_PRESENT 1 /**< Defines if an MPU is present or not */ +#define __NVIC_PRIO_BITS 3 /**< Number of priority bits implemented in the NVIC */ +#define __Vendor_SysTickConfig 0 /**< Vendor specific implementation of SysTickConfig is defined */ +#define __FPU_PRESENT 1 /**< Defines if an FPU is present or not */ + +#include "core_cm4.h" /* Core Peripheral Access Layer */ +#include "system_LPC54102_cm4.h" /* Device specific configuration file */ + +/*! + * @} + */ /* end of group Cortex_Core_Configuration */ + + +/* ---------------------------------------------------------------------------- + -- Device Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup Peripheral_access_layer Device Peripheral Access Layer + * @{ + */ + + +/* +** Start of section using anonymous unions +*/ + +#if defined(__ARMCC_VERSION) + #pragma push + #pragma anon_unions +#elif defined(__IAR_SYSTEMS_ICC__) + #pragma language=extended +#elif defined(__GNUC__) + /* anonymous unions are enabled by default */ +#else + #error Not supported compiler type +#endif + +/* ---------------------------------------------------------------------------- + -- ADC Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup ADC_Peripheral_Access_Layer ADC Peripheral Access Layer + * @{ + */ + +/** ADC - Register Layout Typedef */ +typedef struct { + __IO uint32_t CTRL; /**< ADC Control register. Contains the clock divide value, resolution selection, sampling time selection, and mode controls., offset: 0x0 */ + uint8_t RESERVED_0[4]; + __IO uint32_t SEQ_CTRL[2]; /**< ADC Conversion Sequence-n control register: Controls triggering and channel selection for conversion sequence-n. Also specifies interrupt mode for sequence-n., array offset: 0x8, array step: 0x4 */ + __I uint32_t SEQ_GDAT[2]; /**< ADC Sequence-n Global Data register. This register contains the result of the most recent ADC conversion performed under sequence-n., array offset: 0x10, array step: 0x4 */ + uint8_t RESERVED_1[8]; + __I uint32_t DAT[12]; /**< ADC Channel 0 Data register. This register contains the result of the most recent conversion completed on channel 0., array offset: 0x20, array step: 0x4 */ + __IO uint32_t THR0_LOW; /**< ADC Low Compare Threshold register 0: Contains the lower threshold level for automatic threshold comparison for any channels linked to threshold pair 0., offset: 0x50 */ + __IO uint32_t THR1_LOW; /**< ADC Low Compare Threshold register 1: Contains the lower threshold level for automatic threshold comparison for any channels linked to threshold pair 1., offset: 0x54 */ + __IO uint32_t THR0_HIGH; /**< ADC High Compare Threshold register 0: Contains the upper threshold level for automatic threshold comparison for any channels linked to threshold pair 0., offset: 0x58 */ + __IO uint32_t THR1_HIGH; /**< ADC High Compare Threshold register 1: Contains the upper threshold level for automatic threshold comparison for any channels linked to threshold pair 1., offset: 0x5C */ + __IO uint32_t CHAN_THRSEL; /**< ADC Channel-Threshold Select register. Specifies which set of threshold compare registers are to be used for each channel, offset: 0x60 */ + __IO uint32_t INTEN; /**< ADC Interrupt Enable register. This register contains enable bits that enable the sequence-A, sequence-B, threshold compare and data overrun interrupts to be generated., offset: 0x64 */ + __IO uint32_t FLAGS; /**< ADC Flags register. Contains the four interrupt/DMA trigger flags and the individual component overrun and threshold-compare flags. (The overrun bits replicate information stored in the result registers)., offset: 0x68 */ + __IO uint32_t STARTUP; /**< ADC Startup register., offset: 0x6C */ + __IO uint32_t CALIB; /**< ADC Calibration register., offset: 0x70 */ +} ADC_Type; + +/* ---------------------------------------------------------------------------- + -- ADC Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup ADC_Register_Masks ADC Register Masks + * @{ + */ + +/*! @name CTRL - ADC Control register. Contains the clock divide value, resolution selection, sampling time selection, and mode controls. */ +#define ADC_CTRL_CLKDIV_MASK (0xFFU) +#define ADC_CTRL_CLKDIV_SHIFT (0U) +#define ADC_CTRL_CLKDIV(x) (((uint32_t)(((uint32_t)(x)) << ADC_CTRL_CLKDIV_SHIFT)) & ADC_CTRL_CLKDIV_MASK) +#define ADC_CTRL_ASYNMODE_MASK (0x100U) +#define ADC_CTRL_ASYNMODE_SHIFT (8U) +#define ADC_CTRL_ASYNMODE(x) (((uint32_t)(((uint32_t)(x)) << ADC_CTRL_ASYNMODE_SHIFT)) & ADC_CTRL_ASYNMODE_MASK) +#define ADC_CTRL_RESOL_MASK (0x600U) +#define ADC_CTRL_RESOL_SHIFT (9U) +#define ADC_CTRL_RESOL(x) (((uint32_t)(((uint32_t)(x)) << ADC_CTRL_RESOL_SHIFT)) & ADC_CTRL_RESOL_MASK) +#define ADC_CTRL_BYPASSCAL_MASK (0x800U) +#define ADC_CTRL_BYPASSCAL_SHIFT (11U) +#define ADC_CTRL_BYPASSCAL(x) (((uint32_t)(((uint32_t)(x)) << ADC_CTRL_BYPASSCAL_SHIFT)) & ADC_CTRL_BYPASSCAL_MASK) +#define ADC_CTRL_TSAMP_MASK (0x7000U) +#define ADC_CTRL_TSAMP_SHIFT (12U) +#define ADC_CTRL_TSAMP(x) (((uint32_t)(((uint32_t)(x)) << ADC_CTRL_TSAMP_SHIFT)) & ADC_CTRL_TSAMP_MASK) + +/*! @name SEQ_CTRL - ADC Conversion Sequence-n control register: Controls triggering and channel selection for conversion sequence-n. Also specifies interrupt mode for sequence-n. */ +#define ADC_SEQ_CTRL_CHANNELS_MASK (0xFFFU) +#define ADC_SEQ_CTRL_CHANNELS_SHIFT (0U) +#define ADC_SEQ_CTRL_CHANNELS(x) (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_CHANNELS_SHIFT)) & ADC_SEQ_CTRL_CHANNELS_MASK) +#define ADC_SEQ_CTRL_TRIGGER_MASK (0x3F000U) +#define ADC_SEQ_CTRL_TRIGGER_SHIFT (12U) +#define ADC_SEQ_CTRL_TRIGGER(x) (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_TRIGGER_SHIFT)) & ADC_SEQ_CTRL_TRIGGER_MASK) +#define ADC_SEQ_CTRL_TRIGPOL_MASK (0x40000U) +#define ADC_SEQ_CTRL_TRIGPOL_SHIFT (18U) +#define ADC_SEQ_CTRL_TRIGPOL(x) (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_TRIGPOL_SHIFT)) & ADC_SEQ_CTRL_TRIGPOL_MASK) +#define ADC_SEQ_CTRL_SYNCBYPASS_MASK (0x80000U) +#define ADC_SEQ_CTRL_SYNCBYPASS_SHIFT (19U) +#define ADC_SEQ_CTRL_SYNCBYPASS(x) (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_SYNCBYPASS_SHIFT)) & ADC_SEQ_CTRL_SYNCBYPASS_MASK) +#define ADC_SEQ_CTRL_START_MASK (0x4000000U) +#define ADC_SEQ_CTRL_START_SHIFT (26U) +#define ADC_SEQ_CTRL_START(x) (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_START_SHIFT)) & ADC_SEQ_CTRL_START_MASK) +#define ADC_SEQ_CTRL_BURST_MASK (0x8000000U) +#define ADC_SEQ_CTRL_BURST_SHIFT (27U) +#define ADC_SEQ_CTRL_BURST(x) (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_BURST_SHIFT)) & ADC_SEQ_CTRL_BURST_MASK) +#define ADC_SEQ_CTRL_SINGLESTEP_MASK (0x10000000U) +#define ADC_SEQ_CTRL_SINGLESTEP_SHIFT (28U) +#define ADC_SEQ_CTRL_SINGLESTEP(x) (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_SINGLESTEP_SHIFT)) & ADC_SEQ_CTRL_SINGLESTEP_MASK) +#define ADC_SEQ_CTRL_LOWPRIO_MASK (0x20000000U) +#define ADC_SEQ_CTRL_LOWPRIO_SHIFT (29U) +#define ADC_SEQ_CTRL_LOWPRIO(x) (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_LOWPRIO_SHIFT)) & ADC_SEQ_CTRL_LOWPRIO_MASK) +#define ADC_SEQ_CTRL_MODE_MASK (0x40000000U) +#define ADC_SEQ_CTRL_MODE_SHIFT (30U) +#define ADC_SEQ_CTRL_MODE(x) (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_MODE_SHIFT)) & ADC_SEQ_CTRL_MODE_MASK) +#define ADC_SEQ_CTRL_SEQ_ENA_MASK (0x80000000U) +#define ADC_SEQ_CTRL_SEQ_ENA_SHIFT (31U) +#define ADC_SEQ_CTRL_SEQ_ENA(x) (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_CTRL_SEQ_ENA_SHIFT)) & ADC_SEQ_CTRL_SEQ_ENA_MASK) + +/* The count of ADC_SEQ_CTRL */ +#define ADC_SEQ_CTRL_COUNT (2U) + +/*! @name SEQ_GDAT - ADC Sequence-n Global Data register. This register contains the result of the most recent ADC conversion performed under sequence-n. */ +#define ADC_SEQ_GDAT_RESULT_MASK (0xFFF0U) +#define ADC_SEQ_GDAT_RESULT_SHIFT (4U) +#define ADC_SEQ_GDAT_RESULT(x) (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_GDAT_RESULT_SHIFT)) & ADC_SEQ_GDAT_RESULT_MASK) +#define ADC_SEQ_GDAT_THCMPRANGE_MASK (0x30000U) +#define ADC_SEQ_GDAT_THCMPRANGE_SHIFT (16U) +#define ADC_SEQ_GDAT_THCMPRANGE(x) (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_GDAT_THCMPRANGE_SHIFT)) & ADC_SEQ_GDAT_THCMPRANGE_MASK) +#define ADC_SEQ_GDAT_THCMPCROSS_MASK (0xC0000U) +#define ADC_SEQ_GDAT_THCMPCROSS_SHIFT (18U) +#define ADC_SEQ_GDAT_THCMPCROSS(x) (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_GDAT_THCMPCROSS_SHIFT)) & ADC_SEQ_GDAT_THCMPCROSS_MASK) +#define ADC_SEQ_GDAT_CHN_MASK (0x3C000000U) +#define ADC_SEQ_GDAT_CHN_SHIFT (26U) +#define ADC_SEQ_GDAT_CHN(x) (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_GDAT_CHN_SHIFT)) & ADC_SEQ_GDAT_CHN_MASK) +#define ADC_SEQ_GDAT_OVERRUN_MASK (0x40000000U) +#define ADC_SEQ_GDAT_OVERRUN_SHIFT (30U) +#define ADC_SEQ_GDAT_OVERRUN(x) (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_GDAT_OVERRUN_SHIFT)) & ADC_SEQ_GDAT_OVERRUN_MASK) +#define ADC_SEQ_GDAT_DATAVALID_MASK (0x80000000U) +#define ADC_SEQ_GDAT_DATAVALID_SHIFT (31U) +#define ADC_SEQ_GDAT_DATAVALID(x) (((uint32_t)(((uint32_t)(x)) << ADC_SEQ_GDAT_DATAVALID_SHIFT)) & ADC_SEQ_GDAT_DATAVALID_MASK) + +/* The count of ADC_SEQ_GDAT */ +#define ADC_SEQ_GDAT_COUNT (2U) + +/*! @name DAT - ADC Channel 0 Data register. This register contains the result of the most recent conversion completed on channel 0. */ +#define ADC_DAT_RESULT_MASK (0xFFF0U) +#define ADC_DAT_RESULT_SHIFT (4U) +#define ADC_DAT_RESULT(x) (((uint32_t)(((uint32_t)(x)) << ADC_DAT_RESULT_SHIFT)) & ADC_DAT_RESULT_MASK) +#define ADC_DAT_THCMPRANGE_MASK (0x30000U) +#define ADC_DAT_THCMPRANGE_SHIFT (16U) +#define ADC_DAT_THCMPRANGE(x) (((uint32_t)(((uint32_t)(x)) << ADC_DAT_THCMPRANGE_SHIFT)) & ADC_DAT_THCMPRANGE_MASK) +#define ADC_DAT_THCMPCROSS_MASK (0xC0000U) +#define ADC_DAT_THCMPCROSS_SHIFT (18U) +#define ADC_DAT_THCMPCROSS(x) (((uint32_t)(((uint32_t)(x)) << ADC_DAT_THCMPCROSS_SHIFT)) & ADC_DAT_THCMPCROSS_MASK) +#define ADC_DAT_CHANNEL_MASK (0x3C000000U) +#define ADC_DAT_CHANNEL_SHIFT (26U) +#define ADC_DAT_CHANNEL(x) (((uint32_t)(((uint32_t)(x)) << ADC_DAT_CHANNEL_SHIFT)) & ADC_DAT_CHANNEL_MASK) +#define ADC_DAT_OVERRUN_MASK (0x40000000U) +#define ADC_DAT_OVERRUN_SHIFT (30U) +#define ADC_DAT_OVERRUN(x) (((uint32_t)(((uint32_t)(x)) << ADC_DAT_OVERRUN_SHIFT)) & ADC_DAT_OVERRUN_MASK) +#define ADC_DAT_DATAVALID_MASK (0x80000000U) +#define ADC_DAT_DATAVALID_SHIFT (31U) +#define ADC_DAT_DATAVALID(x) (((uint32_t)(((uint32_t)(x)) << ADC_DAT_DATAVALID_SHIFT)) & ADC_DAT_DATAVALID_MASK) + +/* The count of ADC_DAT */ +#define ADC_DAT_COUNT (12U) + +/*! @name THR0_LOW - ADC Low Compare Threshold register 0: Contains the lower threshold level for automatic threshold comparison for any channels linked to threshold pair 0. */ +#define ADC_THR0_LOW_THRLOW_MASK (0xFFF0U) +#define ADC_THR0_LOW_THRLOW_SHIFT (4U) +#define ADC_THR0_LOW_THRLOW(x) (((uint32_t)(((uint32_t)(x)) << ADC_THR0_LOW_THRLOW_SHIFT)) & ADC_THR0_LOW_THRLOW_MASK) + +/*! @name THR1_LOW - ADC Low Compare Threshold register 1: Contains the lower threshold level for automatic threshold comparison for any channels linked to threshold pair 1. */ +#define ADC_THR1_LOW_THRLOW_MASK (0xFFF0U) +#define ADC_THR1_LOW_THRLOW_SHIFT (4U) +#define ADC_THR1_LOW_THRLOW(x) (((uint32_t)(((uint32_t)(x)) << ADC_THR1_LOW_THRLOW_SHIFT)) & ADC_THR1_LOW_THRLOW_MASK) + +/*! @name THR0_HIGH - ADC High Compare Threshold register 0: Contains the upper threshold level for automatic threshold comparison for any channels linked to threshold pair 0. */ +#define ADC_THR0_HIGH_THRHIGH_MASK (0xFFF0U) +#define ADC_THR0_HIGH_THRHIGH_SHIFT (4U) +#define ADC_THR0_HIGH_THRHIGH(x) (((uint32_t)(((uint32_t)(x)) << ADC_THR0_HIGH_THRHIGH_SHIFT)) & ADC_THR0_HIGH_THRHIGH_MASK) + +/*! @name THR1_HIGH - ADC High Compare Threshold register 1: Contains the upper threshold level for automatic threshold comparison for any channels linked to threshold pair 1. */ +#define ADC_THR1_HIGH_THRHIGH_MASK (0xFFF0U) +#define ADC_THR1_HIGH_THRHIGH_SHIFT (4U) +#define ADC_THR1_HIGH_THRHIGH(x) (((uint32_t)(((uint32_t)(x)) << ADC_THR1_HIGH_THRHIGH_SHIFT)) & ADC_THR1_HIGH_THRHIGH_MASK) + +/*! @name CHAN_THRSEL - ADC Channel-Threshold Select register. Specifies which set of threshold compare registers are to be used for each channel */ +#define ADC_CHAN_THRSEL_CH0_THRSEL_MASK (0x1U) +#define ADC_CHAN_THRSEL_CH0_THRSEL_SHIFT (0U) +#define ADC_CHAN_THRSEL_CH0_THRSEL(x) (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH0_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH0_THRSEL_MASK) +#define ADC_CHAN_THRSEL_CH1_THRSEL_MASK (0x2U) +#define ADC_CHAN_THRSEL_CH1_THRSEL_SHIFT (1U) +#define ADC_CHAN_THRSEL_CH1_THRSEL(x) (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH1_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH1_THRSEL_MASK) +#define ADC_CHAN_THRSEL_CH2_THRSEL_MASK (0x4U) +#define ADC_CHAN_THRSEL_CH2_THRSEL_SHIFT (2U) +#define ADC_CHAN_THRSEL_CH2_THRSEL(x) (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH2_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH2_THRSEL_MASK) +#define ADC_CHAN_THRSEL_CH3_THRSEL_MASK (0x8U) +#define ADC_CHAN_THRSEL_CH3_THRSEL_SHIFT (3U) +#define ADC_CHAN_THRSEL_CH3_THRSEL(x) (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH3_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH3_THRSEL_MASK) +#define ADC_CHAN_THRSEL_CH4_THRSEL_MASK (0x10U) +#define ADC_CHAN_THRSEL_CH4_THRSEL_SHIFT (4U) +#define ADC_CHAN_THRSEL_CH4_THRSEL(x) (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH4_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH4_THRSEL_MASK) +#define ADC_CHAN_THRSEL_CH5_THRSEL_MASK (0x20U) +#define ADC_CHAN_THRSEL_CH5_THRSEL_SHIFT (5U) +#define ADC_CHAN_THRSEL_CH5_THRSEL(x) (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH5_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH5_THRSEL_MASK) +#define ADC_CHAN_THRSEL_CH6_THRSEL_MASK (0x40U) +#define ADC_CHAN_THRSEL_CH6_THRSEL_SHIFT (6U) +#define ADC_CHAN_THRSEL_CH6_THRSEL(x) (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH6_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH6_THRSEL_MASK) +#define ADC_CHAN_THRSEL_CH7_THRSEL_MASK (0x80U) +#define ADC_CHAN_THRSEL_CH7_THRSEL_SHIFT (7U) +#define ADC_CHAN_THRSEL_CH7_THRSEL(x) (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH7_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH7_THRSEL_MASK) +#define ADC_CHAN_THRSEL_CH8_THRSEL_MASK (0x100U) +#define ADC_CHAN_THRSEL_CH8_THRSEL_SHIFT (8U) +#define ADC_CHAN_THRSEL_CH8_THRSEL(x) (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH8_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH8_THRSEL_MASK) +#define ADC_CHAN_THRSEL_CH9_THRSEL_MASK (0x200U) +#define ADC_CHAN_THRSEL_CH9_THRSEL_SHIFT (9U) +#define ADC_CHAN_THRSEL_CH9_THRSEL(x) (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH9_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH9_THRSEL_MASK) +#define ADC_CHAN_THRSEL_CH10_THRSEL_MASK (0x400U) +#define ADC_CHAN_THRSEL_CH10_THRSEL_SHIFT (10U) +#define ADC_CHAN_THRSEL_CH10_THRSEL(x) (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH10_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH10_THRSEL_MASK) +#define ADC_CHAN_THRSEL_CH11_THRSEL_MASK (0x800U) +#define ADC_CHAN_THRSEL_CH11_THRSEL_SHIFT (11U) +#define ADC_CHAN_THRSEL_CH11_THRSEL(x) (((uint32_t)(((uint32_t)(x)) << ADC_CHAN_THRSEL_CH11_THRSEL_SHIFT)) & ADC_CHAN_THRSEL_CH11_THRSEL_MASK) + +/*! @name INTEN - ADC Interrupt Enable register. This register contains enable bits that enable the sequence-A, sequence-B, threshold compare and data overrun interrupts to be generated. */ +#define ADC_INTEN_SEQA_INTEN_MASK (0x1U) +#define ADC_INTEN_SEQA_INTEN_SHIFT (0U) +#define ADC_INTEN_SEQA_INTEN(x) (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_SEQA_INTEN_SHIFT)) & ADC_INTEN_SEQA_INTEN_MASK) +#define ADC_INTEN_SEQB_INTEN_MASK (0x2U) +#define ADC_INTEN_SEQB_INTEN_SHIFT (1U) +#define ADC_INTEN_SEQB_INTEN(x) (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_SEQB_INTEN_SHIFT)) & ADC_INTEN_SEQB_INTEN_MASK) +#define ADC_INTEN_OVR_INTEN_MASK (0x4U) +#define ADC_INTEN_OVR_INTEN_SHIFT (2U) +#define ADC_INTEN_OVR_INTEN(x) (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_OVR_INTEN_SHIFT)) & ADC_INTEN_OVR_INTEN_MASK) +#define ADC_INTEN_ADCMPINTEN0_MASK (0x18U) +#define ADC_INTEN_ADCMPINTEN0_SHIFT (3U) +#define ADC_INTEN_ADCMPINTEN0(x) (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN0_SHIFT)) & ADC_INTEN_ADCMPINTEN0_MASK) +#define ADC_INTEN_ADCMPINTEN1_MASK (0x60U) +#define ADC_INTEN_ADCMPINTEN1_SHIFT (5U) +#define ADC_INTEN_ADCMPINTEN1(x) (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN1_SHIFT)) & ADC_INTEN_ADCMPINTEN1_MASK) +#define ADC_INTEN_ADCMPINTEN2_MASK (0x180U) +#define ADC_INTEN_ADCMPINTEN2_SHIFT (7U) +#define ADC_INTEN_ADCMPINTEN2(x) (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN2_SHIFT)) & ADC_INTEN_ADCMPINTEN2_MASK) +#define ADC_INTEN_ADCMPINTEN3_MASK (0x600U) +#define ADC_INTEN_ADCMPINTEN3_SHIFT (9U) +#define ADC_INTEN_ADCMPINTEN3(x) (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN3_SHIFT)) & ADC_INTEN_ADCMPINTEN3_MASK) +#define ADC_INTEN_ADCMPINTEN4_MASK (0x1800U) +#define ADC_INTEN_ADCMPINTEN4_SHIFT (11U) +#define ADC_INTEN_ADCMPINTEN4(x) (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN4_SHIFT)) & ADC_INTEN_ADCMPINTEN4_MASK) +#define ADC_INTEN_ADCMPINTEN5_MASK (0x6000U) +#define ADC_INTEN_ADCMPINTEN5_SHIFT (13U) +#define ADC_INTEN_ADCMPINTEN5(x) (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN5_SHIFT)) & ADC_INTEN_ADCMPINTEN5_MASK) +#define ADC_INTEN_ADCMPINTEN6_MASK (0x18000U) +#define ADC_INTEN_ADCMPINTEN6_SHIFT (15U) +#define ADC_INTEN_ADCMPINTEN6(x) (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN6_SHIFT)) & ADC_INTEN_ADCMPINTEN6_MASK) +#define ADC_INTEN_ADCMPINTEN7_MASK (0x60000U) +#define ADC_INTEN_ADCMPINTEN7_SHIFT (17U) +#define ADC_INTEN_ADCMPINTEN7(x) (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN7_SHIFT)) & ADC_INTEN_ADCMPINTEN7_MASK) +#define ADC_INTEN_ADCMPINTEN8_MASK (0x180000U) +#define ADC_INTEN_ADCMPINTEN8_SHIFT (19U) +#define ADC_INTEN_ADCMPINTEN8(x) (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN8_SHIFT)) & ADC_INTEN_ADCMPINTEN8_MASK) +#define ADC_INTEN_ADCMPINTEN9_MASK (0x600000U) +#define ADC_INTEN_ADCMPINTEN9_SHIFT (21U) +#define ADC_INTEN_ADCMPINTEN9(x) (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN9_SHIFT)) & ADC_INTEN_ADCMPINTEN9_MASK) +#define ADC_INTEN_ADCMPINTEN10_MASK (0x1800000U) +#define ADC_INTEN_ADCMPINTEN10_SHIFT (23U) +#define ADC_INTEN_ADCMPINTEN10(x) (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN10_SHIFT)) & ADC_INTEN_ADCMPINTEN10_MASK) +#define ADC_INTEN_ADCMPINTEN11_MASK (0x6000000U) +#define ADC_INTEN_ADCMPINTEN11_SHIFT (25U) +#define ADC_INTEN_ADCMPINTEN11(x) (((uint32_t)(((uint32_t)(x)) << ADC_INTEN_ADCMPINTEN11_SHIFT)) & ADC_INTEN_ADCMPINTEN11_MASK) + +/*! @name FLAGS - ADC Flags register. Contains the four interrupt/DMA trigger flags and the individual component overrun and threshold-compare flags. (The overrun bits replicate information stored in the result registers). */ +#define ADC_FLAGS_THCMP0_MASK (0x1U) +#define ADC_FLAGS_THCMP0_SHIFT (0U) +#define ADC_FLAGS_THCMP0(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP0_SHIFT)) & ADC_FLAGS_THCMP0_MASK) +#define ADC_FLAGS_THCMP1_MASK (0x2U) +#define ADC_FLAGS_THCMP1_SHIFT (1U) +#define ADC_FLAGS_THCMP1(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP1_SHIFT)) & ADC_FLAGS_THCMP1_MASK) +#define ADC_FLAGS_THCMP2_MASK (0x4U) +#define ADC_FLAGS_THCMP2_SHIFT (2U) +#define ADC_FLAGS_THCMP2(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP2_SHIFT)) & ADC_FLAGS_THCMP2_MASK) +#define ADC_FLAGS_THCMP3_MASK (0x8U) +#define ADC_FLAGS_THCMP3_SHIFT (3U) +#define ADC_FLAGS_THCMP3(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP3_SHIFT)) & ADC_FLAGS_THCMP3_MASK) +#define ADC_FLAGS_THCMP4_MASK (0x10U) +#define ADC_FLAGS_THCMP4_SHIFT (4U) +#define ADC_FLAGS_THCMP4(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP4_SHIFT)) & ADC_FLAGS_THCMP4_MASK) +#define ADC_FLAGS_THCMP5_MASK (0x20U) +#define ADC_FLAGS_THCMP5_SHIFT (5U) +#define ADC_FLAGS_THCMP5(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP5_SHIFT)) & ADC_FLAGS_THCMP5_MASK) +#define ADC_FLAGS_THCMP6_MASK (0x40U) +#define ADC_FLAGS_THCMP6_SHIFT (6U) +#define ADC_FLAGS_THCMP6(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP6_SHIFT)) & ADC_FLAGS_THCMP6_MASK) +#define ADC_FLAGS_THCMP7_MASK (0x80U) +#define ADC_FLAGS_THCMP7_SHIFT (7U) +#define ADC_FLAGS_THCMP7(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP7_SHIFT)) & ADC_FLAGS_THCMP7_MASK) +#define ADC_FLAGS_THCMP8_MASK (0x100U) +#define ADC_FLAGS_THCMP8_SHIFT (8U) +#define ADC_FLAGS_THCMP8(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP8_SHIFT)) & ADC_FLAGS_THCMP8_MASK) +#define ADC_FLAGS_THCMP9_MASK (0x200U) +#define ADC_FLAGS_THCMP9_SHIFT (9U) +#define ADC_FLAGS_THCMP9(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP9_SHIFT)) & ADC_FLAGS_THCMP9_MASK) +#define ADC_FLAGS_THCMP10_MASK (0x400U) +#define ADC_FLAGS_THCMP10_SHIFT (10U) +#define ADC_FLAGS_THCMP10(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP10_SHIFT)) & ADC_FLAGS_THCMP10_MASK) +#define ADC_FLAGS_THCMP11_MASK (0x800U) +#define ADC_FLAGS_THCMP11_SHIFT (11U) +#define ADC_FLAGS_THCMP11(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP11_SHIFT)) & ADC_FLAGS_THCMP11_MASK) +#define ADC_FLAGS_OVERRUN0_MASK (0x1000U) +#define ADC_FLAGS_OVERRUN0_SHIFT (12U) +#define ADC_FLAGS_OVERRUN0(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN0_SHIFT)) & ADC_FLAGS_OVERRUN0_MASK) +#define ADC_FLAGS_OVERRUN1_MASK (0x2000U) +#define ADC_FLAGS_OVERRUN1_SHIFT (13U) +#define ADC_FLAGS_OVERRUN1(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN1_SHIFT)) & ADC_FLAGS_OVERRUN1_MASK) +#define ADC_FLAGS_OVERRUN2_MASK (0x4000U) +#define ADC_FLAGS_OVERRUN2_SHIFT (14U) +#define ADC_FLAGS_OVERRUN2(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN2_SHIFT)) & ADC_FLAGS_OVERRUN2_MASK) +#define ADC_FLAGS_OVERRUN3_MASK (0x8000U) +#define ADC_FLAGS_OVERRUN3_SHIFT (15U) +#define ADC_FLAGS_OVERRUN3(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN3_SHIFT)) & ADC_FLAGS_OVERRUN3_MASK) +#define ADC_FLAGS_OVERRUN4_MASK (0x10000U) +#define ADC_FLAGS_OVERRUN4_SHIFT (16U) +#define ADC_FLAGS_OVERRUN4(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN4_SHIFT)) & ADC_FLAGS_OVERRUN4_MASK) +#define ADC_FLAGS_OVERRUN5_MASK (0x20000U) +#define ADC_FLAGS_OVERRUN5_SHIFT (17U) +#define ADC_FLAGS_OVERRUN5(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN5_SHIFT)) & ADC_FLAGS_OVERRUN5_MASK) +#define ADC_FLAGS_OVERRUN6_MASK (0x40000U) +#define ADC_FLAGS_OVERRUN6_SHIFT (18U) +#define ADC_FLAGS_OVERRUN6(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN6_SHIFT)) & ADC_FLAGS_OVERRUN6_MASK) +#define ADC_FLAGS_OVERRUN7_MASK (0x80000U) +#define ADC_FLAGS_OVERRUN7_SHIFT (19U) +#define ADC_FLAGS_OVERRUN7(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN7_SHIFT)) & ADC_FLAGS_OVERRUN7_MASK) +#define ADC_FLAGS_OVERRUN8_MASK (0x100000U) +#define ADC_FLAGS_OVERRUN8_SHIFT (20U) +#define ADC_FLAGS_OVERRUN8(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN8_SHIFT)) & ADC_FLAGS_OVERRUN8_MASK) +#define ADC_FLAGS_OVERRUN9_MASK (0x200000U) +#define ADC_FLAGS_OVERRUN9_SHIFT (21U) +#define ADC_FLAGS_OVERRUN9(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN9_SHIFT)) & ADC_FLAGS_OVERRUN9_MASK) +#define ADC_FLAGS_OVERRUN10_MASK (0x400000U) +#define ADC_FLAGS_OVERRUN10_SHIFT (22U) +#define ADC_FLAGS_OVERRUN10(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN10_SHIFT)) & ADC_FLAGS_OVERRUN10_MASK) +#define ADC_FLAGS_OVERRUN11_MASK (0x800000U) +#define ADC_FLAGS_OVERRUN11_SHIFT (23U) +#define ADC_FLAGS_OVERRUN11(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVERRUN11_SHIFT)) & ADC_FLAGS_OVERRUN11_MASK) +#define ADC_FLAGS_SEQA_OVR_MASK (0x1000000U) +#define ADC_FLAGS_SEQA_OVR_SHIFT (24U) +#define ADC_FLAGS_SEQA_OVR(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_SEQA_OVR_SHIFT)) & ADC_FLAGS_SEQA_OVR_MASK) +#define ADC_FLAGS_SEQB_OVR_MASK (0x2000000U) +#define ADC_FLAGS_SEQB_OVR_SHIFT (25U) +#define ADC_FLAGS_SEQB_OVR(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_SEQB_OVR_SHIFT)) & ADC_FLAGS_SEQB_OVR_MASK) +#define ADC_FLAGS_SEQA_INT_MASK (0x10000000U) +#define ADC_FLAGS_SEQA_INT_SHIFT (28U) +#define ADC_FLAGS_SEQA_INT(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_SEQA_INT_SHIFT)) & ADC_FLAGS_SEQA_INT_MASK) +#define ADC_FLAGS_SEQB_INT_MASK (0x20000000U) +#define ADC_FLAGS_SEQB_INT_SHIFT (29U) +#define ADC_FLAGS_SEQB_INT(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_SEQB_INT_SHIFT)) & ADC_FLAGS_SEQB_INT_MASK) +#define ADC_FLAGS_THCMP_INT_MASK (0x40000000U) +#define ADC_FLAGS_THCMP_INT_SHIFT (30U) +#define ADC_FLAGS_THCMP_INT(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_THCMP_INT_SHIFT)) & ADC_FLAGS_THCMP_INT_MASK) +#define ADC_FLAGS_OVR_INT_MASK (0x80000000U) +#define ADC_FLAGS_OVR_INT_SHIFT (31U) +#define ADC_FLAGS_OVR_INT(x) (((uint32_t)(((uint32_t)(x)) << ADC_FLAGS_OVR_INT_SHIFT)) & ADC_FLAGS_OVR_INT_MASK) + +/*! @name STARTUP - ADC Startup register. */ +#define ADC_STARTUP_ADC_ENA_MASK (0x1U) +#define ADC_STARTUP_ADC_ENA_SHIFT (0U) +#define ADC_STARTUP_ADC_ENA(x) (((uint32_t)(((uint32_t)(x)) << ADC_STARTUP_ADC_ENA_SHIFT)) & ADC_STARTUP_ADC_ENA_MASK) +#define ADC_STARTUP_ADC_INIT_MASK (0x2U) +#define ADC_STARTUP_ADC_INIT_SHIFT (1U) +#define ADC_STARTUP_ADC_INIT(x) (((uint32_t)(((uint32_t)(x)) << ADC_STARTUP_ADC_INIT_SHIFT)) & ADC_STARTUP_ADC_INIT_MASK) + +/*! @name CALIB - ADC Calibration register. */ +#define ADC_CALIB_CALIB_MASK (0x1U) +#define ADC_CALIB_CALIB_SHIFT (0U) +#define ADC_CALIB_CALIB(x) (((uint32_t)(((uint32_t)(x)) << ADC_CALIB_CALIB_SHIFT)) & ADC_CALIB_CALIB_MASK) +#define ADC_CALIB_CALREQD_MASK (0x2U) +#define ADC_CALIB_CALREQD_SHIFT (1U) +#define ADC_CALIB_CALREQD(x) (((uint32_t)(((uint32_t)(x)) << ADC_CALIB_CALREQD_SHIFT)) & ADC_CALIB_CALREQD_MASK) +#define ADC_CALIB_CALVALUE_MASK (0x1FCU) +#define ADC_CALIB_CALVALUE_SHIFT (2U) +#define ADC_CALIB_CALVALUE(x) (((uint32_t)(((uint32_t)(x)) << ADC_CALIB_CALVALUE_SHIFT)) & ADC_CALIB_CALVALUE_MASK) + + +/*! + * @} + */ /* end of group ADC_Register_Masks */ + + +/* ADC - Peripheral instance base addresses */ +/** Peripheral ADC0 base address */ +#define ADC0_BASE (0x1C034000u) +/** Peripheral ADC0 base pointer */ +#define ADC0 ((ADC_Type *)ADC0_BASE) +/** Array initializer of ADC peripheral base addresses */ +#define ADC_BASE_ADDRS { ADC0_BASE } +/** Array initializer of ADC peripheral base pointers */ +#define ADC_BASE_PTRS { ADC0 } +/** Interrupt vectors for the ADC peripheral type */ +#define ADC_SEQ_IRQS { ADC0_SEQA_IRQn, ADC0_SEQB_IRQn } +#define ADC_THCMP_IRQS { ADC0_THCMP_IRQn } + +/*! + * @} + */ /* end of group ADC_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- ASYNC_SYSCON Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup ASYNC_SYSCON_Peripheral_Access_Layer ASYNC_SYSCON Peripheral Access Layer + * @{ + */ + +/** ASYNC_SYSCON - Register Layout Typedef */ +typedef struct { + __IO uint32_t ASYNCPRESETCTRL; /**< Async peripheral reset control, offset: 0x0 */ + __O uint32_t ASYNCPRESETCTRLSET; /**< Set bits in ASYNCPRESETCTRL, offset: 0x4 */ + __O uint32_t ASYNCPRESETCTRLCLR; /**< Clear bits in ASYNCPRESETCTRL, offset: 0x8 */ + uint8_t RESERVED_0[4]; + __IO uint32_t ASYNCAPBCLKCTRL; /**< Async peripheral clock control, offset: 0x10 */ + __O uint32_t ASYNCAPBCLKCTRLSET; /**< Set bits in ASYNCAPBCLKCTRL, offset: 0x14 */ + __O uint32_t ASYNCAPBCLKCTRLCLR; /**< Clear bits in ASYNCAPBCLKCTRL, offset: 0x18 */ + uint8_t RESERVED_1[4]; + __IO uint32_t ASYNCAPBCLKSELA; /**< Async APB clock source select A, offset: 0x20 */ + __IO uint32_t ASYNCAPBCLKSELB; /**< Async APB clock source select B, offset: 0x24 */ + __IO uint32_t ASYNCCLKDIV; /**< Async APB clock divider, offset: 0x28 */ + uint8_t RESERVED_2[4]; + __IO uint32_t FRGCTRL; /**< USART fractional rate generator control, offset: 0x30 */ +} ASYNC_SYSCON_Type; + +/* ---------------------------------------------------------------------------- + -- ASYNC_SYSCON Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup ASYNC_SYSCON_Register_Masks ASYNC_SYSCON Register Masks + * @{ + */ + +/*! @name ASYNCPRESETCTRL - Async peripheral reset control */ +#define ASYNC_SYSCON_ASYNCPRESETCTRL_USART0_MASK (0x2U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_USART0_SHIFT (1U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_USART0(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCPRESETCTRL_USART0_SHIFT)) & ASYNC_SYSCON_ASYNCPRESETCTRL_USART0_MASK) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_USART1_MASK (0x4U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_USART1_SHIFT (2U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_USART1(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCPRESETCTRL_USART1_SHIFT)) & ASYNC_SYSCON_ASYNCPRESETCTRL_USART1_MASK) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_USART2_MASK (0x8U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_USART2_SHIFT (3U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_USART2(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCPRESETCTRL_USART2_SHIFT)) & ASYNC_SYSCON_ASYNCPRESETCTRL_USART2_MASK) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_USART3_MASK (0x10U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_USART3_SHIFT (4U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_USART3(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCPRESETCTRL_USART3_SHIFT)) & ASYNC_SYSCON_ASYNCPRESETCTRL_USART3_MASK) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_I2C0_MASK (0x20U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_I2C0_SHIFT (5U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_I2C0(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCPRESETCTRL_I2C0_SHIFT)) & ASYNC_SYSCON_ASYNCPRESETCTRL_I2C0_MASK) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_I2C1_MASK (0x40U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_I2C1_SHIFT (6U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_I2C1(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCPRESETCTRL_I2C1_SHIFT)) & ASYNC_SYSCON_ASYNCPRESETCTRL_I2C1_MASK) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_I2C2_MASK (0x80U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_I2C2_SHIFT (7U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_I2C2(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCPRESETCTRL_I2C2_SHIFT)) & ASYNC_SYSCON_ASYNCPRESETCTRL_I2C2_MASK) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_SPI0_MASK (0x200U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_SPI0_SHIFT (9U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_SPI0(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCPRESETCTRL_SPI0_SHIFT)) & ASYNC_SYSCON_ASYNCPRESETCTRL_SPI0_MASK) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_SPI1_MASK (0x400U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_SPI1_SHIFT (10U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_SPI1(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCPRESETCTRL_SPI1_SHIFT)) & ASYNC_SYSCON_ASYNCPRESETCTRL_SPI1_MASK) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_CT32B0_MASK (0x2000U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_CT32B0_SHIFT (13U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_CT32B0(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCPRESETCTRL_CT32B0_SHIFT)) & ASYNC_SYSCON_ASYNCPRESETCTRL_CT32B0_MASK) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_CT32B1_MASK (0x4000U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_CT32B1_SHIFT (14U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_CT32B1(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCPRESETCTRL_CT32B1_SHIFT)) & ASYNC_SYSCON_ASYNCPRESETCTRL_CT32B1_MASK) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_FRG0_MASK (0x8000U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_FRG0_SHIFT (15U) +#define ASYNC_SYSCON_ASYNCPRESETCTRL_FRG0(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCPRESETCTRL_FRG0_SHIFT)) & ASYNC_SYSCON_ASYNCPRESETCTRL_FRG0_MASK) + +/*! @name ASYNCPRESETCTRLSET - Set bits in ASYNCPRESETCTRL */ +#define ASYNC_SYSCON_ASYNCPRESETCTRLSET_ARST_SET_MASK (0xFFFFFFFFU) +#define ASYNC_SYSCON_ASYNCPRESETCTRLSET_ARST_SET_SHIFT (0U) +#define ASYNC_SYSCON_ASYNCPRESETCTRLSET_ARST_SET(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCPRESETCTRLSET_ARST_SET_SHIFT)) & ASYNC_SYSCON_ASYNCPRESETCTRLSET_ARST_SET_MASK) + +/*! @name ASYNCPRESETCTRLCLR - Clear bits in ASYNCPRESETCTRL */ +#define ASYNC_SYSCON_ASYNCPRESETCTRLCLR_ARST_CLR_MASK (0xFFFFFFFFU) +#define ASYNC_SYSCON_ASYNCPRESETCTRLCLR_ARST_CLR_SHIFT (0U) +#define ASYNC_SYSCON_ASYNCPRESETCTRLCLR_ARST_CLR(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCPRESETCTRLCLR_ARST_CLR_SHIFT)) & ASYNC_SYSCON_ASYNCPRESETCTRLCLR_ARST_CLR_MASK) + +/*! @name ASYNCAPBCLKCTRL - Async peripheral clock control */ +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_USART0_MASK (0x2U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_USART0_SHIFT (1U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_USART0(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKCTRL_USART0_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKCTRL_USART0_MASK) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_USART1_MASK (0x4U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_USART1_SHIFT (2U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_USART1(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKCTRL_USART1_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKCTRL_USART1_MASK) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_USART2_MASK (0x8U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_USART2_SHIFT (3U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_USART2(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKCTRL_USART2_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKCTRL_USART2_MASK) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_USART3_MASK (0x10U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_USART3_SHIFT (4U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_USART3(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKCTRL_USART3_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKCTRL_USART3_MASK) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_I2C0_MASK (0x20U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_I2C0_SHIFT (5U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_I2C0(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKCTRL_I2C0_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKCTRL_I2C0_MASK) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_I2C1_MASK (0x40U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_I2C1_SHIFT (6U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_I2C1(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKCTRL_I2C1_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKCTRL_I2C1_MASK) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_I2C2_MASK (0x80U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_I2C2_SHIFT (7U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_I2C2(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKCTRL_I2C2_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKCTRL_I2C2_MASK) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_SPI0_MASK (0x200U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_SPI0_SHIFT (9U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_SPI0(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKCTRL_SPI0_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKCTRL_SPI0_MASK) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_SPI1_MASK (0x400U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_SPI1_SHIFT (10U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_SPI1(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKCTRL_SPI1_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKCTRL_SPI1_MASK) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_CT32B0_MASK (0x2000U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_CT32B0_SHIFT (13U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_CT32B0(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKCTRL_CT32B0_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKCTRL_CT32B0_MASK) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_CT32B1_MASK (0x4000U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_CT32B1_SHIFT (14U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_CT32B1(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKCTRL_CT32B1_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKCTRL_CT32B1_MASK) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_FRG0_MASK (0x8000U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_FRG0_SHIFT (15U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRL_FRG0(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKCTRL_FRG0_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKCTRL_FRG0_MASK) + +/*! @name ASYNCAPBCLKCTRLSET - Set bits in ASYNCAPBCLKCTRL */ +#define ASYNC_SYSCON_ASYNCAPBCLKCTRLSET_ACLK_SET_MASK (0xFFFFFFFFU) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRLSET_ACLK_SET_SHIFT (0U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRLSET_ACLK_SET(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKCTRLSET_ACLK_SET_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKCTRLSET_ACLK_SET_MASK) + +/*! @name ASYNCAPBCLKCTRLCLR - Clear bits in ASYNCAPBCLKCTRL */ +#define ASYNC_SYSCON_ASYNCAPBCLKCTRLCLR_ACLK_CLR_MASK (0xFFFFFFFFU) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRLCLR_ACLK_CLR_SHIFT (0U) +#define ASYNC_SYSCON_ASYNCAPBCLKCTRLCLR_ACLK_CLR(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKCTRLCLR_ACLK_CLR_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKCTRLCLR_ACLK_CLR_MASK) + +/*! @name ASYNCAPBCLKSELA - Async APB clock source select A */ +#define ASYNC_SYSCON_ASYNCAPBCLKSELA_SEL_MASK (0x3U) +#define ASYNC_SYSCON_ASYNCAPBCLKSELA_SEL_SHIFT (0U) +#define ASYNC_SYSCON_ASYNCAPBCLKSELA_SEL(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKSELA_SEL_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKSELA_SEL_MASK) + +/*! @name ASYNCAPBCLKSELB - Async APB clock source select B */ +#define ASYNC_SYSCON_ASYNCAPBCLKSELB_SEL_MASK (0x3U) +#define ASYNC_SYSCON_ASYNCAPBCLKSELB_SEL_SHIFT (0U) +#define ASYNC_SYSCON_ASYNCAPBCLKSELB_SEL(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCAPBCLKSELB_SEL_SHIFT)) & ASYNC_SYSCON_ASYNCAPBCLKSELB_SEL_MASK) + +/*! @name ASYNCCLKDIV - Async APB clock divider */ +#define ASYNC_SYSCON_ASYNCCLKDIV_DIV_MASK (0xFFU) +#define ASYNC_SYSCON_ASYNCCLKDIV_DIV_SHIFT (0U) +#define ASYNC_SYSCON_ASYNCCLKDIV_DIV(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_ASYNCCLKDIV_DIV_SHIFT)) & ASYNC_SYSCON_ASYNCCLKDIV_DIV_MASK) + +/*! @name FRGCTRL - USART fractional rate generator control */ +#define ASYNC_SYSCON_FRGCTRL_DIV_MASK (0xFFU) +#define ASYNC_SYSCON_FRGCTRL_DIV_SHIFT (0U) +#define ASYNC_SYSCON_FRGCTRL_DIV(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_FRGCTRL_DIV_SHIFT)) & ASYNC_SYSCON_FRGCTRL_DIV_MASK) +#define ASYNC_SYSCON_FRGCTRL_MULT_MASK (0xFF00U) +#define ASYNC_SYSCON_FRGCTRL_MULT_SHIFT (8U) +#define ASYNC_SYSCON_FRGCTRL_MULT(x) (((uint32_t)(((uint32_t)(x)) << ASYNC_SYSCON_FRGCTRL_MULT_SHIFT)) & ASYNC_SYSCON_FRGCTRL_MULT_MASK) + + +/*! + * @} + */ /* end of group ASYNC_SYSCON_Register_Masks */ + + +/* ASYNC_SYSCON - Peripheral instance base addresses */ +/** Peripheral ASYNC_SYSCON base address */ +#define ASYNC_SYSCON_BASE (0x40080000u) +/** Peripheral ASYNC_SYSCON base pointer */ +#define ASYNC_SYSCON ((ASYNC_SYSCON_Type *)ASYNC_SYSCON_BASE) +/** Array initializer of ASYNC_SYSCON peripheral base addresses */ +#define ASYNC_SYSCON_BASE_ADDRS { ASYNC_SYSCON_BASE } +/** Array initializer of ASYNC_SYSCON peripheral base pointers */ +#define ASYNC_SYSCON_BASE_PTRS { ASYNC_SYSCON } + +/*! + * @} + */ /* end of group ASYNC_SYSCON_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- CRC Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup CRC_Peripheral_Access_Layer CRC Peripheral Access Layer + * @{ + */ + +/** CRC - Register Layout Typedef */ +typedef struct { + __IO uint32_t MODE; /**< CRC mode register, offset: 0x0 */ + __IO uint32_t SEED; /**< CRC seed register, offset: 0x4 */ + union { /* offset: 0x8 */ + __I uint32_t SUM; /**< CRC checksum register, offset: 0x8 */ + __O uint32_t WR_DATA; /**< CRC data register, offset: 0x8 */ + }; +} CRC_Type; + +/* ---------------------------------------------------------------------------- + -- CRC Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup CRC_Register_Masks CRC Register Masks + * @{ + */ + +/*! @name MODE - CRC mode register */ +#define CRC_MODE_CRC_POLY_MASK (0x3U) +#define CRC_MODE_CRC_POLY_SHIFT (0U) +#define CRC_MODE_CRC_POLY(x) (((uint32_t)(((uint32_t)(x)) << CRC_MODE_CRC_POLY_SHIFT)) & CRC_MODE_CRC_POLY_MASK) +#define CRC_MODE_BIT_RVS_WR_MASK (0x4U) +#define CRC_MODE_BIT_RVS_WR_SHIFT (2U) +#define CRC_MODE_BIT_RVS_WR(x) (((uint32_t)(((uint32_t)(x)) << CRC_MODE_BIT_RVS_WR_SHIFT)) & CRC_MODE_BIT_RVS_WR_MASK) +#define CRC_MODE_CMPL_WR_MASK (0x8U) +#define CRC_MODE_CMPL_WR_SHIFT (3U) +#define CRC_MODE_CMPL_WR(x) (((uint32_t)(((uint32_t)(x)) << CRC_MODE_CMPL_WR_SHIFT)) & CRC_MODE_CMPL_WR_MASK) +#define CRC_MODE_BIT_RVS_SUM_MASK (0x10U) +#define CRC_MODE_BIT_RVS_SUM_SHIFT (4U) +#define CRC_MODE_BIT_RVS_SUM(x) (((uint32_t)(((uint32_t)(x)) << CRC_MODE_BIT_RVS_SUM_SHIFT)) & CRC_MODE_BIT_RVS_SUM_MASK) +#define CRC_MODE_CMPL_SUM_MASK (0x20U) +#define CRC_MODE_CMPL_SUM_SHIFT (5U) +#define CRC_MODE_CMPL_SUM(x) (((uint32_t)(((uint32_t)(x)) << CRC_MODE_CMPL_SUM_SHIFT)) & CRC_MODE_CMPL_SUM_MASK) + +/*! @name SEED - CRC seed register */ +#define CRC_SEED_CRC_SEED_MASK (0xFFFFFFFFU) +#define CRC_SEED_CRC_SEED_SHIFT (0U) +#define CRC_SEED_CRC_SEED(x) (((uint32_t)(((uint32_t)(x)) << CRC_SEED_CRC_SEED_SHIFT)) & CRC_SEED_CRC_SEED_MASK) + +/*! @name SUM - CRC checksum register */ +#define CRC_SUM_CRC_SUM_MASK (0xFFFFFFFFU) +#define CRC_SUM_CRC_SUM_SHIFT (0U) +#define CRC_SUM_CRC_SUM(x) (((uint32_t)(((uint32_t)(x)) << CRC_SUM_CRC_SUM_SHIFT)) & CRC_SUM_CRC_SUM_MASK) + +/*! @name WR_DATA - CRC data register */ +#define CRC_WR_DATA_CRC_WR_DATA_MASK (0xFFFFFFFFU) +#define CRC_WR_DATA_CRC_WR_DATA_SHIFT (0U) +#define CRC_WR_DATA_CRC_WR_DATA(x) (((uint32_t)(((uint32_t)(x)) << CRC_WR_DATA_CRC_WR_DATA_SHIFT)) & CRC_WR_DATA_CRC_WR_DATA_MASK) + + +/*! + * @} + */ /* end of group CRC_Register_Masks */ + + +/* CRC - Peripheral instance base addresses */ +/** Peripheral CRC_ENGINE base address */ +#define CRC_ENGINE_BASE (0x1C010000u) +/** Peripheral CRC_ENGINE base pointer */ +#define CRC_ENGINE ((CRC_Type *)CRC_ENGINE_BASE) +/** Array initializer of CRC peripheral base addresses */ +#define CRC_BASE_ADDRS { CRC_ENGINE_BASE } +/** Array initializer of CRC peripheral base pointers */ +#define CRC_BASE_PTRS { CRC_ENGINE } + +/*! + * @} + */ /* end of group CRC_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- CTIMER Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup CTIMER_Peripheral_Access_Layer CTIMER Peripheral Access Layer + * @{ + */ + +/** CTIMER - Register Layout Typedef */ +typedef struct { + __IO uint32_t IR; /**< Interrupt Register. The IR can be written to clear interrupts. The IR can be read to identify which of eight possible interrupt sources are pending., offset: 0x0 */ + __IO uint32_t TCR; /**< Timer Control Register. The TCR is used to control the Timer Counter functions. The Timer Counter can be disabled or reset through the TCR., offset: 0x4 */ + __IO uint32_t TC; /**< Timer Counter. The 32 bit TC is incremented every PR+1 cycles of the APB bus clock. The TC is controlled through the TCR., offset: 0x8 */ + __IO uint32_t PR; /**< Prescale Register. When the Prescale Counter (PC) is equal to this value, the next clock increments the TC and clears the PC., offset: 0xC */ + __IO uint32_t PC; /**< Prescale Counter. The 32 bit PC is a counter which is incremented to the value stored in PR. When the value in PR is reached, the TC is incremented and the PC is cleared. The PC is observable and controllable through the bus interface., offset: 0x10 */ + __IO uint32_t MCR; /**< Match Control Register. The MCR is used to control if an interrupt is generated and if the TC is reset when a Match occurs., offset: 0x14 */ + __IO uint32_t MR[4]; /**< Match Register . MR can be enabled through the MCR to reset the TC, stop both the TC and PC, and/or generate an interrupt every time MR matches the TC., array offset: 0x18, array step: 0x4 */ + __IO uint32_t CCR; /**< Capture Control Register. The CCR controls which edges of the capture inputs are used to load the Capture Registers and whether or not an interrupt is generated when a capture takes place., offset: 0x28 */ + __I uint32_t CR[4]; /**< Capture Register . CR is loaded with the value of TC when there is an event on the CAPn. input., array offset: 0x2C, array step: 0x4 */ + __IO uint32_t EMR; /**< External Match Register. The EMR controls the match function and the external match pins., offset: 0x3C */ + uint8_t RESERVED_0[48]; + __IO uint32_t CTCR; /**< Count Control Register. The CTCR selects between Timer and Counter mode, and in Counter mode selects the signal and edge(s) for counting., offset: 0x70 */ + __IO uint32_t PWMC; /**< PWM Control Register. The PWMCON enables PWM mode for the external match pins., offset: 0x74 */ +} CTIMER_Type; + +/* ---------------------------------------------------------------------------- + -- CTIMER Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup CTIMER_Register_Masks CTIMER Register Masks + * @{ + */ + +/*! @name IR - Interrupt Register. The IR can be written to clear interrupts. The IR can be read to identify which of eight possible interrupt sources are pending. */ +#define CTIMER_IR_MR0INT_MASK (0x1U) +#define CTIMER_IR_MR0INT_SHIFT (0U) +#define CTIMER_IR_MR0INT(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_IR_MR0INT_SHIFT)) & CTIMER_IR_MR0INT_MASK) +#define CTIMER_IR_MR1INT_MASK (0x2U) +#define CTIMER_IR_MR1INT_SHIFT (1U) +#define CTIMER_IR_MR1INT(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_IR_MR1INT_SHIFT)) & CTIMER_IR_MR1INT_MASK) +#define CTIMER_IR_MR2INT_MASK (0x4U) +#define CTIMER_IR_MR2INT_SHIFT (2U) +#define CTIMER_IR_MR2INT(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_IR_MR2INT_SHIFT)) & CTIMER_IR_MR2INT_MASK) +#define CTIMER_IR_MR3INT_MASK (0x8U) +#define CTIMER_IR_MR3INT_SHIFT (3U) +#define CTIMER_IR_MR3INT(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_IR_MR3INT_SHIFT)) & CTIMER_IR_MR3INT_MASK) +#define CTIMER_IR_CR0INT_MASK (0x10U) +#define CTIMER_IR_CR0INT_SHIFT (4U) +#define CTIMER_IR_CR0INT(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_IR_CR0INT_SHIFT)) & CTIMER_IR_CR0INT_MASK) +#define CTIMER_IR_CR1INT_MASK (0x20U) +#define CTIMER_IR_CR1INT_SHIFT (5U) +#define CTIMER_IR_CR1INT(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_IR_CR1INT_SHIFT)) & CTIMER_IR_CR1INT_MASK) +#define CTIMER_IR_CR2INT_MASK (0x40U) +#define CTIMER_IR_CR2INT_SHIFT (6U) +#define CTIMER_IR_CR2INT(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_IR_CR2INT_SHIFT)) & CTIMER_IR_CR2INT_MASK) +#define CTIMER_IR_CR3INT_MASK (0x80U) +#define CTIMER_IR_CR3INT_SHIFT (7U) +#define CTIMER_IR_CR3INT(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_IR_CR3INT_SHIFT)) & CTIMER_IR_CR3INT_MASK) + +/*! @name TCR - Timer Control Register. The TCR is used to control the Timer Counter functions. The Timer Counter can be disabled or reset through the TCR. */ +#define CTIMER_TCR_CEN_MASK (0x1U) +#define CTIMER_TCR_CEN_SHIFT (0U) +#define CTIMER_TCR_CEN(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_TCR_CEN_SHIFT)) & CTIMER_TCR_CEN_MASK) +#define CTIMER_TCR_CRST_MASK (0x2U) +#define CTIMER_TCR_CRST_SHIFT (1U) +#define CTIMER_TCR_CRST(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_TCR_CRST_SHIFT)) & CTIMER_TCR_CRST_MASK) + +/*! @name TC - Timer Counter. The 32 bit TC is incremented every PR+1 cycles of the APB bus clock. The TC is controlled through the TCR. */ +#define CTIMER_TC_TCVAL_MASK (0xFFFFFFFFU) +#define CTIMER_TC_TCVAL_SHIFT (0U) +#define CTIMER_TC_TCVAL(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_TC_TCVAL_SHIFT)) & CTIMER_TC_TCVAL_MASK) + +/*! @name PR - Prescale Register. When the Prescale Counter (PC) is equal to this value, the next clock increments the TC and clears the PC. */ +#define CTIMER_PR_PRVAL_MASK (0xFFFFFFFFU) +#define CTIMER_PR_PRVAL_SHIFT (0U) +#define CTIMER_PR_PRVAL(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_PR_PRVAL_SHIFT)) & CTIMER_PR_PRVAL_MASK) + +/*! @name PC - Prescale Counter. The 32 bit PC is a counter which is incremented to the value stored in PR. When the value in PR is reached, the TC is incremented and the PC is cleared. The PC is observable and controllable through the bus interface. */ +#define CTIMER_PC_PCVAL_MASK (0xFFFFFFFFU) +#define CTIMER_PC_PCVAL_SHIFT (0U) +#define CTIMER_PC_PCVAL(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_PC_PCVAL_SHIFT)) & CTIMER_PC_PCVAL_MASK) + +/*! @name MCR - Match Control Register. The MCR is used to control if an interrupt is generated and if the TC is reset when a Match occurs. */ +#define CTIMER_MCR_MR0I_MASK (0x1U) +#define CTIMER_MCR_MR0I_SHIFT (0U) +#define CTIMER_MCR_MR0I(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR0I_SHIFT)) & CTIMER_MCR_MR0I_MASK) +#define CTIMER_MCR_MR0R_MASK (0x2U) +#define CTIMER_MCR_MR0R_SHIFT (1U) +#define CTIMER_MCR_MR0R(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR0R_SHIFT)) & CTIMER_MCR_MR0R_MASK) +#define CTIMER_MCR_MR0S_MASK (0x4U) +#define CTIMER_MCR_MR0S_SHIFT (2U) +#define CTIMER_MCR_MR0S(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR0S_SHIFT)) & CTIMER_MCR_MR0S_MASK) +#define CTIMER_MCR_MR1I_MASK (0x8U) +#define CTIMER_MCR_MR1I_SHIFT (3U) +#define CTIMER_MCR_MR1I(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR1I_SHIFT)) & CTIMER_MCR_MR1I_MASK) +#define CTIMER_MCR_MR1R_MASK (0x10U) +#define CTIMER_MCR_MR1R_SHIFT (4U) +#define CTIMER_MCR_MR1R(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR1R_SHIFT)) & CTIMER_MCR_MR1R_MASK) +#define CTIMER_MCR_MR1S_MASK (0x20U) +#define CTIMER_MCR_MR1S_SHIFT (5U) +#define CTIMER_MCR_MR1S(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR1S_SHIFT)) & CTIMER_MCR_MR1S_MASK) +#define CTIMER_MCR_MR2I_MASK (0x40U) +#define CTIMER_MCR_MR2I_SHIFT (6U) +#define CTIMER_MCR_MR2I(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR2I_SHIFT)) & CTIMER_MCR_MR2I_MASK) +#define CTIMER_MCR_MR2R_MASK (0x80U) +#define CTIMER_MCR_MR2R_SHIFT (7U) +#define CTIMER_MCR_MR2R(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR2R_SHIFT)) & CTIMER_MCR_MR2R_MASK) +#define CTIMER_MCR_MR2S_MASK (0x100U) +#define CTIMER_MCR_MR2S_SHIFT (8U) +#define CTIMER_MCR_MR2S(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR2S_SHIFT)) & CTIMER_MCR_MR2S_MASK) +#define CTIMER_MCR_MR3I_MASK (0x200U) +#define CTIMER_MCR_MR3I_SHIFT (9U) +#define CTIMER_MCR_MR3I(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR3I_SHIFT)) & CTIMER_MCR_MR3I_MASK) +#define CTIMER_MCR_MR3R_MASK (0x400U) +#define CTIMER_MCR_MR3R_SHIFT (10U) +#define CTIMER_MCR_MR3R(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR3R_SHIFT)) & CTIMER_MCR_MR3R_MASK) +#define CTIMER_MCR_MR3S_MASK (0x800U) +#define CTIMER_MCR_MR3S_SHIFT (11U) +#define CTIMER_MCR_MR3S(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_MCR_MR3S_SHIFT)) & CTIMER_MCR_MR3S_MASK) + +/*! @name MR - Match Register . MR can be enabled through the MCR to reset the TC, stop both the TC and PC, and/or generate an interrupt every time MR matches the TC. */ +#define CTIMER_MR_MATCH_MASK (0xFFFFFFFFU) +#define CTIMER_MR_MATCH_SHIFT (0U) +#define CTIMER_MR_MATCH(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_MR_MATCH_SHIFT)) & CTIMER_MR_MATCH_MASK) + +/* The count of CTIMER_MR */ +#define CTIMER_MR_COUNT (4U) + +/*! @name CCR - Capture Control Register. The CCR controls which edges of the capture inputs are used to load the Capture Registers and whether or not an interrupt is generated when a capture takes place. */ +#define CTIMER_CCR_CAP0RE_MASK (0x1U) +#define CTIMER_CCR_CAP0RE_SHIFT (0U) +#define CTIMER_CCR_CAP0RE(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CCR_CAP0RE_SHIFT)) & CTIMER_CCR_CAP0RE_MASK) +#define CTIMER_CCR_CAP0FE_MASK (0x2U) +#define CTIMER_CCR_CAP0FE_SHIFT (1U) +#define CTIMER_CCR_CAP0FE(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CCR_CAP0FE_SHIFT)) & CTIMER_CCR_CAP0FE_MASK) +#define CTIMER_CCR_CAP0I_MASK (0x4U) +#define CTIMER_CCR_CAP0I_SHIFT (2U) +#define CTIMER_CCR_CAP0I(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CCR_CAP0I_SHIFT)) & CTIMER_CCR_CAP0I_MASK) +#define CTIMER_CCR_CAP1RE_MASK (0x8U) +#define CTIMER_CCR_CAP1RE_SHIFT (3U) +#define CTIMER_CCR_CAP1RE(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CCR_CAP1RE_SHIFT)) & CTIMER_CCR_CAP1RE_MASK) +#define CTIMER_CCR_CAP1FE_MASK (0x10U) +#define CTIMER_CCR_CAP1FE_SHIFT (4U) +#define CTIMER_CCR_CAP1FE(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CCR_CAP1FE_SHIFT)) & CTIMER_CCR_CAP1FE_MASK) +#define CTIMER_CCR_CAP1I_MASK (0x20U) +#define CTIMER_CCR_CAP1I_SHIFT (5U) +#define CTIMER_CCR_CAP1I(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CCR_CAP1I_SHIFT)) & CTIMER_CCR_CAP1I_MASK) +#define CTIMER_CCR_CAP2RE_MASK (0x40U) +#define CTIMER_CCR_CAP2RE_SHIFT (6U) +#define CTIMER_CCR_CAP2RE(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CCR_CAP2RE_SHIFT)) & CTIMER_CCR_CAP2RE_MASK) +#define CTIMER_CCR_CAP2FE_MASK (0x80U) +#define CTIMER_CCR_CAP2FE_SHIFT (7U) +#define CTIMER_CCR_CAP2FE(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CCR_CAP2FE_SHIFT)) & CTIMER_CCR_CAP2FE_MASK) +#define CTIMER_CCR_CAP2I_MASK (0x100U) +#define CTIMER_CCR_CAP2I_SHIFT (8U) +#define CTIMER_CCR_CAP2I(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CCR_CAP2I_SHIFT)) & CTIMER_CCR_CAP2I_MASK) +#define CTIMER_CCR_CAP3RE_MASK (0x200U) +#define CTIMER_CCR_CAP3RE_SHIFT (9U) +#define CTIMER_CCR_CAP3RE(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CCR_CAP3RE_SHIFT)) & CTIMER_CCR_CAP3RE_MASK) +#define CTIMER_CCR_CAP3FE_MASK (0x400U) +#define CTIMER_CCR_CAP3FE_SHIFT (10U) +#define CTIMER_CCR_CAP3FE(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CCR_CAP3FE_SHIFT)) & CTIMER_CCR_CAP3FE_MASK) +#define CTIMER_CCR_CAP3I_MASK (0x800U) +#define CTIMER_CCR_CAP3I_SHIFT (11U) +#define CTIMER_CCR_CAP3I(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CCR_CAP3I_SHIFT)) & CTIMER_CCR_CAP3I_MASK) + +/*! @name CR - Capture Register . CR is loaded with the value of TC when there is an event on the CAPn. input. */ +#define CTIMER_CR_CAP_MASK (0xFFFFFFFFU) +#define CTIMER_CR_CAP_SHIFT (0U) +#define CTIMER_CR_CAP(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CR_CAP_SHIFT)) & CTIMER_CR_CAP_MASK) + +/* The count of CTIMER_CR */ +#define CTIMER_CR_COUNT (4U) + +/*! @name EMR - External Match Register. The EMR controls the match function and the external match pins. */ +#define CTIMER_EMR_EM0_MASK (0x1U) +#define CTIMER_EMR_EM0_SHIFT (0U) +#define CTIMER_EMR_EM0(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_EMR_EM0_SHIFT)) & CTIMER_EMR_EM0_MASK) +#define CTIMER_EMR_EM1_MASK (0x2U) +#define CTIMER_EMR_EM1_SHIFT (1U) +#define CTIMER_EMR_EM1(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_EMR_EM1_SHIFT)) & CTIMER_EMR_EM1_MASK) +#define CTIMER_EMR_EM2_MASK (0x4U) +#define CTIMER_EMR_EM2_SHIFT (2U) +#define CTIMER_EMR_EM2(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_EMR_EM2_SHIFT)) & CTIMER_EMR_EM2_MASK) +#define CTIMER_EMR_EM3_MASK (0x8U) +#define CTIMER_EMR_EM3_SHIFT (3U) +#define CTIMER_EMR_EM3(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_EMR_EM3_SHIFT)) & CTIMER_EMR_EM3_MASK) +#define CTIMER_EMR_EMC0_MASK (0x30U) +#define CTIMER_EMR_EMC0_SHIFT (4U) +#define CTIMER_EMR_EMC0(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_EMR_EMC0_SHIFT)) & CTIMER_EMR_EMC0_MASK) +#define CTIMER_EMR_EMC1_MASK (0xC0U) +#define CTIMER_EMR_EMC1_SHIFT (6U) +#define CTIMER_EMR_EMC1(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_EMR_EMC1_SHIFT)) & CTIMER_EMR_EMC1_MASK) +#define CTIMER_EMR_EMC2_MASK (0x300U) +#define CTIMER_EMR_EMC2_SHIFT (8U) +#define CTIMER_EMR_EMC2(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_EMR_EMC2_SHIFT)) & CTIMER_EMR_EMC2_MASK) +#define CTIMER_EMR_EMC3_MASK (0xC00U) +#define CTIMER_EMR_EMC3_SHIFT (10U) +#define CTIMER_EMR_EMC3(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_EMR_EMC3_SHIFT)) & CTIMER_EMR_EMC3_MASK) + +/*! @name CTCR - Count Control Register. The CTCR selects between Timer and Counter mode, and in Counter mode selects the signal and edge(s) for counting. */ +#define CTIMER_CTCR_CTMODE_MASK (0x3U) +#define CTIMER_CTCR_CTMODE_SHIFT (0U) +#define CTIMER_CTCR_CTMODE(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CTCR_CTMODE_SHIFT)) & CTIMER_CTCR_CTMODE_MASK) +#define CTIMER_CTCR_CINSEL_MASK (0xCU) +#define CTIMER_CTCR_CINSEL_SHIFT (2U) +#define CTIMER_CTCR_CINSEL(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CTCR_CINSEL_SHIFT)) & CTIMER_CTCR_CINSEL_MASK) +#define CTIMER_CTCR_ENCC_MASK (0x10U) +#define CTIMER_CTCR_ENCC_SHIFT (4U) +#define CTIMER_CTCR_ENCC(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CTCR_ENCC_SHIFT)) & CTIMER_CTCR_ENCC_MASK) +#define CTIMER_CTCR_SELCC_MASK (0xE0U) +#define CTIMER_CTCR_SELCC_SHIFT (5U) +#define CTIMER_CTCR_SELCC(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_CTCR_SELCC_SHIFT)) & CTIMER_CTCR_SELCC_MASK) + +/*! @name PWMC - PWM Control Register. The PWMCON enables PWM mode for the external match pins. */ +#define CTIMER_PWMC_PWMEN0_MASK (0x1U) +#define CTIMER_PWMC_PWMEN0_SHIFT (0U) +#define CTIMER_PWMC_PWMEN0(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_PWMC_PWMEN0_SHIFT)) & CTIMER_PWMC_PWMEN0_MASK) +#define CTIMER_PWMC_PWMEN1_MASK (0x2U) +#define CTIMER_PWMC_PWMEN1_SHIFT (1U) +#define CTIMER_PWMC_PWMEN1(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_PWMC_PWMEN1_SHIFT)) & CTIMER_PWMC_PWMEN1_MASK) +#define CTIMER_PWMC_PWMEN2_MASK (0x4U) +#define CTIMER_PWMC_PWMEN2_SHIFT (2U) +#define CTIMER_PWMC_PWMEN2(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_PWMC_PWMEN2_SHIFT)) & CTIMER_PWMC_PWMEN2_MASK) +#define CTIMER_PWMC_PWMEN3_MASK (0x8U) +#define CTIMER_PWMC_PWMEN3_SHIFT (3U) +#define CTIMER_PWMC_PWMEN3(x) (((uint32_t)(((uint32_t)(x)) << CTIMER_PWMC_PWMEN3_SHIFT)) & CTIMER_PWMC_PWMEN3_MASK) + + +/*! + * @} + */ /* end of group CTIMER_Register_Masks */ + + +/* CTIMER - Peripheral instance base addresses */ +/** Peripheral CTIMER0 base address */ +#define CTIMER0_BASE (0x400B4000u) +/** Peripheral CTIMER0 base pointer */ +#define CTIMER0 ((CTIMER_Type *)CTIMER0_BASE) +/** Peripheral CTIMER1 base address */ +#define CTIMER1_BASE (0x400B8000u) +/** Peripheral CTIMER1 base pointer */ +#define CTIMER1 ((CTIMER_Type *)CTIMER1_BASE) +/** Peripheral CTIMER2 base address */ +#define CTIMER2_BASE (0x40004000u) +/** Peripheral CTIMER2 base pointer */ +#define CTIMER2 ((CTIMER_Type *)CTIMER2_BASE) +/** Peripheral CTIMER3 base address */ +#define CTIMER3_BASE (0x40008000u) +/** Peripheral CTIMER3 base pointer */ +#define CTIMER3 ((CTIMER_Type *)CTIMER3_BASE) +/** Peripheral CTIMER4 base address */ +#define CTIMER4_BASE (0x4000C000u) +/** Peripheral CTIMER4 base pointer */ +#define CTIMER4 ((CTIMER_Type *)CTIMER4_BASE) +/** Array initializer of CTIMER peripheral base addresses */ +#define CTIMER_BASE_ADDRS { CTIMER0_BASE, CTIMER1_BASE, CTIMER2_BASE, CTIMER3_BASE, CTIMER4_BASE } +/** Array initializer of CTIMER peripheral base pointers */ +#define CTIMER_BASE_PTRS { CTIMER0, CTIMER1, CTIMER2, CTIMER3, CTIMER4 } +/** Interrupt vectors for the CTIMER peripheral type */ +#define CTIMER_IRQS { CTIMER0_IRQn, CTIMER1_IRQn, CTIMER2_IRQn, CTIMER3_IRQn, CTIMER4_IRQn } + +/*! + * @} + */ /* end of group CTIMER_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- DMA Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup DMA_Peripheral_Access_Layer DMA Peripheral Access Layer + * @{ + */ + +/** DMA - Register Layout Typedef */ +typedef struct { + __IO uint32_t CTRL; /**< DMA control., offset: 0x0 */ + __I uint32_t INTSTAT; /**< Interrupt status., offset: 0x4 */ + __IO uint32_t SRAMBASE; /**< SRAM address of the channel configuration table., offset: 0x8 */ + uint8_t RESERVED_0[20]; + struct { /* offset: 0x20, array step: 0x5C */ + __IO uint32_t ENABLESET; /**< Channel Enable read and Set for all DMA channels., array offset: 0x20, array step: 0x5C */ + uint8_t RESERVED_0[4]; + __O uint32_t ENABLECLR; /**< Channel Enable Clear for all DMA channels., array offset: 0x28, array step: 0x5C */ + uint8_t RESERVED_1[4]; + __IO uint32_t ACTIVE; /**< Channel Active status for all DMA channels., array offset: 0x30, array step: 0x5C */ + uint8_t RESERVED_2[4]; + __IO uint32_t BUSY; /**< Channel Busy status for all DMA channels., array offset: 0x38, array step: 0x5C */ + uint8_t RESERVED_3[4]; + __IO uint32_t ERRINT; /**< Error Interrupt status for all DMA channels., array offset: 0x40, array step: 0x5C */ + uint8_t RESERVED_4[4]; + __IO uint32_t INTENSET; /**< Interrupt Enable read and Set for all DMA channels., array offset: 0x48, array step: 0x5C */ + uint8_t RESERVED_5[4]; + __O uint32_t INTENCLR; /**< Interrupt Enable Clear for all DMA channels., array offset: 0x50, array step: 0x5C */ + uint8_t RESERVED_6[4]; + __IO uint32_t INTA; /**< Interrupt A status for all DMA channels., array offset: 0x58, array step: 0x5C */ + uint8_t RESERVED_7[4]; + __IO uint32_t INTB; /**< Interrupt B status for all DMA channels., array offset: 0x60, array step: 0x5C */ + uint8_t RESERVED_8[4]; + __O uint32_t SETVALID; /**< Set ValidPending control bits for all DMA channels., array offset: 0x68, array step: 0x5C */ + uint8_t RESERVED_9[4]; + __O uint32_t SETTRIG; /**< Set Trigger control bits for all DMA channels., array offset: 0x70, array step: 0x5C */ + uint8_t RESERVED_10[4]; + __O uint32_t ABORT; /**< Channel Abort control for all DMA channels., array offset: 0x78, array step: 0x5C */ + } COMMON[1]; + uint8_t RESERVED_1[900]; + struct { /* offset: 0x400, array step: 0x10 */ + __IO uint32_t CFG; /**< Configuration register for DMA channel ., array offset: 0x400, array step: 0x10 */ + __I uint32_t CTLSTAT; /**< Control and status register for DMA channel ., array offset: 0x404, array step: 0x10 */ + __IO uint32_t XFERCFG; /**< Transfer configuration register for DMA channel ., array offset: 0x408, array step: 0x10 */ + uint8_t RESERVED_0[4]; + } CHANNEL[22]; +} DMA_Type; + +/* ---------------------------------------------------------------------------- + -- DMA Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup DMA_Register_Masks DMA Register Masks + * @{ + */ + +/*! @name CTRL - DMA control. */ +#define DMA_CTRL_ENABLE_MASK (0x1U) +#define DMA_CTRL_ENABLE_SHIFT (0U) +#define DMA_CTRL_ENABLE(x) (((uint32_t)(((uint32_t)(x)) << DMA_CTRL_ENABLE_SHIFT)) & DMA_CTRL_ENABLE_MASK) + +/*! @name INTSTAT - Interrupt status. */ +#define DMA_INTSTAT_ACTIVEINT_MASK (0x2U) +#define DMA_INTSTAT_ACTIVEINT_SHIFT (1U) +#define DMA_INTSTAT_ACTIVEINT(x) (((uint32_t)(((uint32_t)(x)) << DMA_INTSTAT_ACTIVEINT_SHIFT)) & DMA_INTSTAT_ACTIVEINT_MASK) +#define DMA_INTSTAT_ACTIVEERRINT_MASK (0x4U) +#define DMA_INTSTAT_ACTIVEERRINT_SHIFT (2U) +#define DMA_INTSTAT_ACTIVEERRINT(x) (((uint32_t)(((uint32_t)(x)) << DMA_INTSTAT_ACTIVEERRINT_SHIFT)) & DMA_INTSTAT_ACTIVEERRINT_MASK) + +/*! @name SRAMBASE - SRAM address of the channel configuration table. */ +#define DMA_SRAMBASE_OFFSET_MASK (0xFFFFFE00U) +#define DMA_SRAMBASE_OFFSET_SHIFT (9U) +#define DMA_SRAMBASE_OFFSET(x) (((uint32_t)(((uint32_t)(x)) << DMA_SRAMBASE_OFFSET_SHIFT)) & DMA_SRAMBASE_OFFSET_MASK) + +/*! @name COMMON_ENABLESET - Channel Enable read and Set for all DMA channels. */ +#define DMA_COMMON_ENABLESET_ENA_MASK (0x3FFFFFU) +#define DMA_COMMON_ENABLESET_ENA_SHIFT (0U) +#define DMA_COMMON_ENABLESET_ENA(x) (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_ENABLESET_ENA_SHIFT)) & DMA_COMMON_ENABLESET_ENA_MASK) + +/* The count of DMA_COMMON_ENABLESET */ +#define DMA_COMMON_ENABLESET_COUNT (1U) + +/*! @name COMMON_ENABLECLR - Channel Enable Clear for all DMA channels. */ +#define DMA_COMMON_ENABLECLR_CLR_MASK (0x3FFFFFU) +#define DMA_COMMON_ENABLECLR_CLR_SHIFT (0U) +#define DMA_COMMON_ENABLECLR_CLR(x) (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_ENABLECLR_CLR_SHIFT)) & DMA_COMMON_ENABLECLR_CLR_MASK) + +/* The count of DMA_COMMON_ENABLECLR */ +#define DMA_COMMON_ENABLECLR_COUNT (1U) + +/*! @name COMMON_ACTIVE - Channel Active status for all DMA channels. */ +#define DMA_COMMON_ACTIVE_ACT_MASK (0x3FFFFFU) +#define DMA_COMMON_ACTIVE_ACT_SHIFT (0U) +#define DMA_COMMON_ACTIVE_ACT(x) (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_ACTIVE_ACT_SHIFT)) & DMA_COMMON_ACTIVE_ACT_MASK) + +/* The count of DMA_COMMON_ACTIVE */ +#define DMA_COMMON_ACTIVE_COUNT (1U) + +/*! @name COMMON_BUSY - Channel Busy status for all DMA channels. */ +#define DMA_COMMON_BUSY_BSY_MASK (0x3FFFFFU) +#define DMA_COMMON_BUSY_BSY_SHIFT (0U) +#define DMA_COMMON_BUSY_BSY(x) (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_BUSY_BSY_SHIFT)) & DMA_COMMON_BUSY_BSY_MASK) + +/* The count of DMA_COMMON_BUSY */ +#define DMA_COMMON_BUSY_COUNT (1U) + +/*! @name COMMON_ERRINT - Error Interrupt status for all DMA channels. */ +#define DMA_COMMON_ERRINT_ERR_MASK (0x3FFFFFU) +#define DMA_COMMON_ERRINT_ERR_SHIFT (0U) +#define DMA_COMMON_ERRINT_ERR(x) (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_ERRINT_ERR_SHIFT)) & DMA_COMMON_ERRINT_ERR_MASK) + +/* The count of DMA_COMMON_ERRINT */ +#define DMA_COMMON_ERRINT_COUNT (1U) + +/*! @name COMMON_INTENSET - Interrupt Enable read and Set for all DMA channels. */ +#define DMA_COMMON_INTENSET_INTEN_MASK (0x3FFFFFU) +#define DMA_COMMON_INTENSET_INTEN_SHIFT (0U) +#define DMA_COMMON_INTENSET_INTEN(x) (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_INTENSET_INTEN_SHIFT)) & DMA_COMMON_INTENSET_INTEN_MASK) + +/* The count of DMA_COMMON_INTENSET */ +#define DMA_COMMON_INTENSET_COUNT (1U) + +/*! @name COMMON_INTENCLR - Interrupt Enable Clear for all DMA channels. */ +#define DMA_COMMON_INTENCLR_CLR_MASK (0x3FFFFFU) +#define DMA_COMMON_INTENCLR_CLR_SHIFT (0U) +#define DMA_COMMON_INTENCLR_CLR(x) (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_INTENCLR_CLR_SHIFT)) & DMA_COMMON_INTENCLR_CLR_MASK) + +/* The count of DMA_COMMON_INTENCLR */ +#define DMA_COMMON_INTENCLR_COUNT (1U) + +/*! @name COMMON_INTA - Interrupt A status for all DMA channels. */ +#define DMA_COMMON_INTA_IA_MASK (0x3FFFFFU) +#define DMA_COMMON_INTA_IA_SHIFT (0U) +#define DMA_COMMON_INTA_IA(x) (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_INTA_IA_SHIFT)) & DMA_COMMON_INTA_IA_MASK) + +/* The count of DMA_COMMON_INTA */ +#define DMA_COMMON_INTA_COUNT (1U) + +/*! @name COMMON_INTB - Interrupt B status for all DMA channels. */ +#define DMA_COMMON_INTB_IB_MASK (0x3FFFFFU) +#define DMA_COMMON_INTB_IB_SHIFT (0U) +#define DMA_COMMON_INTB_IB(x) (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_INTB_IB_SHIFT)) & DMA_COMMON_INTB_IB_MASK) + +/* The count of DMA_COMMON_INTB */ +#define DMA_COMMON_INTB_COUNT (1U) + +/*! @name COMMON_SETVALID - Set ValidPending control bits for all DMA channels. */ +#define DMA_COMMON_SETVALID_SV_MASK (0x3FFFFFU) +#define DMA_COMMON_SETVALID_SV_SHIFT (0U) +#define DMA_COMMON_SETVALID_SV(x) (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_SETVALID_SV_SHIFT)) & DMA_COMMON_SETVALID_SV_MASK) + +/* The count of DMA_COMMON_SETVALID */ +#define DMA_COMMON_SETVALID_COUNT (1U) + +/*! @name COMMON_SETTRIG - Set Trigger control bits for all DMA channels. */ +#define DMA_COMMON_SETTRIG_TRIG_MASK (0x3FFFFFU) +#define DMA_COMMON_SETTRIG_TRIG_SHIFT (0U) +#define DMA_COMMON_SETTRIG_TRIG(x) (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_SETTRIG_TRIG_SHIFT)) & DMA_COMMON_SETTRIG_TRIG_MASK) + +/* The count of DMA_COMMON_SETTRIG */ +#define DMA_COMMON_SETTRIG_COUNT (1U) + +/*! @name COMMON_ABORT - Channel Abort control for all DMA channels. */ +#define DMA_COMMON_ABORT_ABORTCTRL_MASK (0x3FFFFFU) +#define DMA_COMMON_ABORT_ABORTCTRL_SHIFT (0U) +#define DMA_COMMON_ABORT_ABORTCTRL(x) (((uint32_t)(((uint32_t)(x)) << DMA_COMMON_ABORT_ABORTCTRL_SHIFT)) & DMA_COMMON_ABORT_ABORTCTRL_MASK) + +/* The count of DMA_COMMON_ABORT */ +#define DMA_COMMON_ABORT_COUNT (1U) + +/*! @name CHANNEL_CFG - Configuration register for DMA channel . */ +#define DMA_CHANNEL_CFG_PERIPHREQEN_MASK (0x1U) +#define DMA_CHANNEL_CFG_PERIPHREQEN_SHIFT (0U) +#define DMA_CHANNEL_CFG_PERIPHREQEN(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CFG_PERIPHREQEN_SHIFT)) & DMA_CHANNEL_CFG_PERIPHREQEN_MASK) +#define DMA_CHANNEL_CFG_HWTRIGEN_MASK (0x2U) +#define DMA_CHANNEL_CFG_HWTRIGEN_SHIFT (1U) +#define DMA_CHANNEL_CFG_HWTRIGEN(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CFG_HWTRIGEN_SHIFT)) & DMA_CHANNEL_CFG_HWTRIGEN_MASK) +#define DMA_CHANNEL_CFG_TRIGPOL_MASK (0x10U) +#define DMA_CHANNEL_CFG_TRIGPOL_SHIFT (4U) +#define DMA_CHANNEL_CFG_TRIGPOL(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CFG_TRIGPOL_SHIFT)) & DMA_CHANNEL_CFG_TRIGPOL_MASK) +#define DMA_CHANNEL_CFG_TRIGTYPE_MASK (0x20U) +#define DMA_CHANNEL_CFG_TRIGTYPE_SHIFT (5U) +#define DMA_CHANNEL_CFG_TRIGTYPE(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CFG_TRIGTYPE_SHIFT)) & DMA_CHANNEL_CFG_TRIGTYPE_MASK) +#define DMA_CHANNEL_CFG_TRIGBURST_MASK (0x40U) +#define DMA_CHANNEL_CFG_TRIGBURST_SHIFT (6U) +#define DMA_CHANNEL_CFG_TRIGBURST(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CFG_TRIGBURST_SHIFT)) & DMA_CHANNEL_CFG_TRIGBURST_MASK) +#define DMA_CHANNEL_CFG_BURSTPOWER_MASK (0xF00U) +#define DMA_CHANNEL_CFG_BURSTPOWER_SHIFT (8U) +#define DMA_CHANNEL_CFG_BURSTPOWER(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CFG_BURSTPOWER_SHIFT)) & DMA_CHANNEL_CFG_BURSTPOWER_MASK) +#define DMA_CHANNEL_CFG_SRCBURSTWRAP_MASK (0x4000U) +#define DMA_CHANNEL_CFG_SRCBURSTWRAP_SHIFT (14U) +#define DMA_CHANNEL_CFG_SRCBURSTWRAP(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CFG_SRCBURSTWRAP_SHIFT)) & DMA_CHANNEL_CFG_SRCBURSTWRAP_MASK) +#define DMA_CHANNEL_CFG_DSTBURSTWRAP_MASK (0x8000U) +#define DMA_CHANNEL_CFG_DSTBURSTWRAP_SHIFT (15U) +#define DMA_CHANNEL_CFG_DSTBURSTWRAP(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CFG_DSTBURSTWRAP_SHIFT)) & DMA_CHANNEL_CFG_DSTBURSTWRAP_MASK) +#define DMA_CHANNEL_CFG_CHPRIORITY_MASK (0x70000U) +#define DMA_CHANNEL_CFG_CHPRIORITY_SHIFT (16U) +#define DMA_CHANNEL_CFG_CHPRIORITY(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CFG_CHPRIORITY_SHIFT)) & DMA_CHANNEL_CFG_CHPRIORITY_MASK) + +/* The count of DMA_CHANNEL_CFG */ +#define DMA_CHANNEL_CFG_COUNT (22U) + +/*! @name CHANNEL_CTLSTAT - Control and status register for DMA channel . */ +#define DMA_CHANNEL_CTLSTAT_VALIDPENDING_MASK (0x1U) +#define DMA_CHANNEL_CTLSTAT_VALIDPENDING_SHIFT (0U) +#define DMA_CHANNEL_CTLSTAT_VALIDPENDING(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CTLSTAT_VALIDPENDING_SHIFT)) & DMA_CHANNEL_CTLSTAT_VALIDPENDING_MASK) +#define DMA_CHANNEL_CTLSTAT_TRIG_MASK (0x4U) +#define DMA_CHANNEL_CTLSTAT_TRIG_SHIFT (2U) +#define DMA_CHANNEL_CTLSTAT_TRIG(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_CTLSTAT_TRIG_SHIFT)) & DMA_CHANNEL_CTLSTAT_TRIG_MASK) + +/* The count of DMA_CHANNEL_CTLSTAT */ +#define DMA_CHANNEL_CTLSTAT_COUNT (22U) + +/*! @name CHANNEL_XFERCFG - Transfer configuration register for DMA channel . */ +#define DMA_CHANNEL_XFERCFG_CFGVALID_MASK (0x1U) +#define DMA_CHANNEL_XFERCFG_CFGVALID_SHIFT (0U) +#define DMA_CHANNEL_XFERCFG_CFGVALID(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_CFGVALID_SHIFT)) & DMA_CHANNEL_XFERCFG_CFGVALID_MASK) +#define DMA_CHANNEL_XFERCFG_RELOAD_MASK (0x2U) +#define DMA_CHANNEL_XFERCFG_RELOAD_SHIFT (1U) +#define DMA_CHANNEL_XFERCFG_RELOAD(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_RELOAD_SHIFT)) & DMA_CHANNEL_XFERCFG_RELOAD_MASK) +#define DMA_CHANNEL_XFERCFG_SWTRIG_MASK (0x4U) +#define DMA_CHANNEL_XFERCFG_SWTRIG_SHIFT (2U) +#define DMA_CHANNEL_XFERCFG_SWTRIG(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_SWTRIG_SHIFT)) & DMA_CHANNEL_XFERCFG_SWTRIG_MASK) +#define DMA_CHANNEL_XFERCFG_CLRTRIG_MASK (0x8U) +#define DMA_CHANNEL_XFERCFG_CLRTRIG_SHIFT (3U) +#define DMA_CHANNEL_XFERCFG_CLRTRIG(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_CLRTRIG_SHIFT)) & DMA_CHANNEL_XFERCFG_CLRTRIG_MASK) +#define DMA_CHANNEL_XFERCFG_SETINTA_MASK (0x10U) +#define DMA_CHANNEL_XFERCFG_SETINTA_SHIFT (4U) +#define DMA_CHANNEL_XFERCFG_SETINTA(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_SETINTA_SHIFT)) & DMA_CHANNEL_XFERCFG_SETINTA_MASK) +#define DMA_CHANNEL_XFERCFG_SETINTB_MASK (0x20U) +#define DMA_CHANNEL_XFERCFG_SETINTB_SHIFT (5U) +#define DMA_CHANNEL_XFERCFG_SETINTB(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_SETINTB_SHIFT)) & DMA_CHANNEL_XFERCFG_SETINTB_MASK) +#define DMA_CHANNEL_XFERCFG_WIDTH_MASK (0x300U) +#define DMA_CHANNEL_XFERCFG_WIDTH_SHIFT (8U) +#define DMA_CHANNEL_XFERCFG_WIDTH(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_WIDTH_SHIFT)) & DMA_CHANNEL_XFERCFG_WIDTH_MASK) +#define DMA_CHANNEL_XFERCFG_SRCINC_MASK (0x3000U) +#define DMA_CHANNEL_XFERCFG_SRCINC_SHIFT (12U) +#define DMA_CHANNEL_XFERCFG_SRCINC(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_SRCINC_SHIFT)) & DMA_CHANNEL_XFERCFG_SRCINC_MASK) +#define DMA_CHANNEL_XFERCFG_DSTINC_MASK (0xC000U) +#define DMA_CHANNEL_XFERCFG_DSTINC_SHIFT (14U) +#define DMA_CHANNEL_XFERCFG_DSTINC(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_DSTINC_SHIFT)) & DMA_CHANNEL_XFERCFG_DSTINC_MASK) +#define DMA_CHANNEL_XFERCFG_XFERCOUNT_MASK (0x3FF0000U) +#define DMA_CHANNEL_XFERCFG_XFERCOUNT_SHIFT (16U) +#define DMA_CHANNEL_XFERCFG_XFERCOUNT(x) (((uint32_t)(((uint32_t)(x)) << DMA_CHANNEL_XFERCFG_XFERCOUNT_SHIFT)) & DMA_CHANNEL_XFERCFG_XFERCOUNT_MASK) + +/* The count of DMA_CHANNEL_XFERCFG */ +#define DMA_CHANNEL_XFERCFG_COUNT (22U) + + +/*! + * @} + */ /* end of group DMA_Register_Masks */ + + +/* DMA - Peripheral instance base addresses */ +/** Peripheral DMA0 base address */ +#define DMA0_BASE (0x1C004000u) +/** Peripheral DMA0 base pointer */ +#define DMA0 ((DMA_Type *)DMA0_BASE) +/** Array initializer of DMA peripheral base addresses */ +#define DMA_BASE_ADDRS { DMA0_BASE } +/** Array initializer of DMA peripheral base pointers */ +#define DMA_BASE_PTRS { DMA0 } +/** Interrupt vectors for the DMA peripheral type */ +#define DMA_IRQS { DMA0_IRQn } + +/*! + * @} + */ /* end of group DMA_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- GINT Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup GINT_Peripheral_Access_Layer GINT Peripheral Access Layer + * @{ + */ + +/** GINT - Register Layout Typedef */ +typedef struct { + __IO uint32_t CTRL; /**< GPIO grouped interrupt control register, offset: 0x0 */ + uint8_t RESERVED_0[28]; + __IO uint32_t PORT_POL[2]; /**< GPIO grouped interrupt port 0 polarity register, array offset: 0x20, array step: 0x4 */ + uint8_t RESERVED_1[24]; + __IO uint32_t PORT_ENA[2]; /**< GPIO grouped interrupt port 0 enable register, array offset: 0x40, array step: 0x4 */ +} GINT_Type; + +/* ---------------------------------------------------------------------------- + -- GINT Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup GINT_Register_Masks GINT Register Masks + * @{ + */ + +/*! @name CTRL - GPIO grouped interrupt control register */ +#define GINT_CTRL_INT_MASK (0x1U) +#define GINT_CTRL_INT_SHIFT (0U) +#define GINT_CTRL_INT(x) (((uint32_t)(((uint32_t)(x)) << GINT_CTRL_INT_SHIFT)) & GINT_CTRL_INT_MASK) +#define GINT_CTRL_COMB_MASK (0x2U) +#define GINT_CTRL_COMB_SHIFT (1U) +#define GINT_CTRL_COMB(x) (((uint32_t)(((uint32_t)(x)) << GINT_CTRL_COMB_SHIFT)) & GINT_CTRL_COMB_MASK) +#define GINT_CTRL_TRIG_MASK (0x4U) +#define GINT_CTRL_TRIG_SHIFT (2U) +#define GINT_CTRL_TRIG(x) (((uint32_t)(((uint32_t)(x)) << GINT_CTRL_TRIG_SHIFT)) & GINT_CTRL_TRIG_MASK) + +/*! @name PORT_POL - GPIO grouped interrupt port 0 polarity register */ +#define GINT_PORT_POL_POL_MASK (0xFFFFFFFFU) +#define GINT_PORT_POL_POL_SHIFT (0U) +#define GINT_PORT_POL_POL(x) (((uint32_t)(((uint32_t)(x)) << GINT_PORT_POL_POL_SHIFT)) & GINT_PORT_POL_POL_MASK) + +/* The count of GINT_PORT_POL */ +#define GINT_PORT_POL_COUNT (2U) + +/*! @name PORT_ENA - GPIO grouped interrupt port 0 enable register */ +#define GINT_PORT_ENA_ENA_MASK (0xFFFFFFFFU) +#define GINT_PORT_ENA_ENA_SHIFT (0U) +#define GINT_PORT_ENA_ENA(x) (((uint32_t)(((uint32_t)(x)) << GINT_PORT_ENA_ENA_SHIFT)) & GINT_PORT_ENA_ENA_MASK) + +/* The count of GINT_PORT_ENA */ +#define GINT_PORT_ENA_COUNT (2U) + + +/*! + * @} + */ /* end of group GINT_Register_Masks */ + + +/* GINT - Peripheral instance base addresses */ +/** Peripheral GINT0 base address */ +#define GINT0_BASE (0x40010000u) +/** Peripheral GINT0 base pointer */ +#define GINT0 ((GINT_Type *)GINT0_BASE) +/** Peripheral GINT1 base address */ +#define GINT1_BASE (0x40014000u) +/** Peripheral GINT1 base pointer */ +#define GINT1 ((GINT_Type *)GINT1_BASE) +/** Array initializer of GINT peripheral base addresses */ +#define GINT_BASE_ADDRS { GINT0_BASE, GINT1_BASE } +/** Array initializer of GINT peripheral base pointers */ +#define GINT_BASE_PTRS { GINT0, GINT1 } +/** Interrupt vectors for the GINT peripheral type */ +#define GINT_IRQS { GINT0_IRQn, GINT1_IRQn } + +/*! + * @} + */ /* end of group GINT_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- GPIO Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup GPIO_Peripheral_Access_Layer GPIO Peripheral Access Layer + * @{ + */ + +/** GPIO - Register Layout Typedef */ +typedef struct { + __IO uint8_t B[2][32]; /**< Byte pin registers for all port 0 and 1 GPIO pins, array offset: 0x0, array step: index*0x20, index2*0x1 */ + uint8_t RESERVED_0[4032]; + __IO uint32_t W[2][32]; /**< Word pin registers for all port 0 and 1 GPIO pins, array offset: 0x1000, array step: index*0x80, index2*0x4 */ + uint8_t RESERVED_1[3840]; + __IO uint32_t DIR[2]; /**< Direction registers, array offset: 0x2000, array step: 0x4 */ + uint8_t RESERVED_2[120]; + __IO uint32_t MASK[2]; /**< Mask register, array offset: 0x2080, array step: 0x4 */ + uint8_t RESERVED_3[120]; + __IO uint32_t PIN[2]; /**< Port pin register, array offset: 0x2100, array step: 0x4 */ + uint8_t RESERVED_4[120]; + __IO uint32_t MPIN[2]; /**< Masked port register, array offset: 0x2180, array step: 0x4 */ + uint8_t RESERVED_5[120]; + __IO uint32_t SET[2]; /**< Write: Set register for port Read: output bits for port, array offset: 0x2200, array step: 0x4 */ + uint8_t RESERVED_6[120]; + __O uint32_t CLR[2]; /**< Clear port, array offset: 0x2280, array step: 0x4 */ + uint8_t RESERVED_7[120]; + __O uint32_t NOT[2]; /**< Toggle port, array offset: 0x2300, array step: 0x4 */ + uint8_t RESERVED_8[120]; + __O uint32_t DIRSET[2]; /**< Set pin direction bits for port, array offset: 0x2380, array step: 0x4 */ + uint8_t RESERVED_9[120]; + __O uint32_t DIRCLR[2]; /**< Clear pin direction bits for port, array offset: 0x2400, array step: 0x4 */ + uint8_t RESERVED_10[120]; + __O uint32_t DIRNOT[2]; /**< Toggle pin direction bits for port, array offset: 0x2480, array step: 0x4 */ +} GPIO_Type; + +/* ---------------------------------------------------------------------------- + -- GPIO Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup GPIO_Register_Masks GPIO Register Masks + * @{ + */ + +/*! @name B - Byte pin registers for all port 0 and 1 GPIO pins */ +#define GPIO_B_PBYTE_MASK (0x1U) +#define GPIO_B_PBYTE_SHIFT (0U) +#define GPIO_B_PBYTE(x) (((uint8_t)(((uint8_t)(x)) << GPIO_B_PBYTE_SHIFT)) & GPIO_B_PBYTE_MASK) + +/* The count of GPIO_B */ +#define GPIO_B_COUNT (2U) + +/* The count of GPIO_B */ +#define GPIO_B_COUNT2 (32U) + +/*! @name W - Word pin registers for all port 0 and 1 GPIO pins */ +#define GPIO_W_PWORD_MASK (0xFFFFFFFFU) +#define GPIO_W_PWORD_SHIFT (0U) +#define GPIO_W_PWORD(x) (((uint32_t)(((uint32_t)(x)) << GPIO_W_PWORD_SHIFT)) & GPIO_W_PWORD_MASK) + +/* The count of GPIO_W */ +#define GPIO_W_COUNT (2U) + +/* The count of GPIO_W */ +#define GPIO_W_COUNT2 (32U) + +/*! @name DIR - Direction registers */ +#define GPIO_DIR_DIRP_MASK (0xFFFFFFFFU) +#define GPIO_DIR_DIRP_SHIFT (0U) +#define GPIO_DIR_DIRP(x) (((uint32_t)(((uint32_t)(x)) << GPIO_DIR_DIRP_SHIFT)) & GPIO_DIR_DIRP_MASK) + +/* The count of GPIO_DIR */ +#define GPIO_DIR_COUNT (2U) + +/*! @name MASK - Mask register */ +#define GPIO_MASK_MASKP_MASK (0xFFFFFFFFU) +#define GPIO_MASK_MASKP_SHIFT (0U) +#define GPIO_MASK_MASKP(x) (((uint32_t)(((uint32_t)(x)) << GPIO_MASK_MASKP_SHIFT)) & GPIO_MASK_MASKP_MASK) + +/* The count of GPIO_MASK */ +#define GPIO_MASK_COUNT (2U) + +/*! @name PIN - Port pin register */ +#define GPIO_PIN_PORT_MASK (0xFFFFFFFFU) +#define GPIO_PIN_PORT_SHIFT (0U) +#define GPIO_PIN_PORT(x) (((uint32_t)(((uint32_t)(x)) << GPIO_PIN_PORT_SHIFT)) & GPIO_PIN_PORT_MASK) + +/* The count of GPIO_PIN */ +#define GPIO_PIN_COUNT (2U) + +/*! @name MPIN - Masked port register */ +#define GPIO_MPIN_MPORTP_MASK (0xFFFFFFFFU) +#define GPIO_MPIN_MPORTP_SHIFT (0U) +#define GPIO_MPIN_MPORTP(x) (((uint32_t)(((uint32_t)(x)) << GPIO_MPIN_MPORTP_SHIFT)) & GPIO_MPIN_MPORTP_MASK) + +/* The count of GPIO_MPIN */ +#define GPIO_MPIN_COUNT (2U) + +/*! @name SET - Write: Set register for port Read: output bits for port */ +#define GPIO_SET_SETP_MASK (0xFFFFFFFFU) +#define GPIO_SET_SETP_SHIFT (0U) +#define GPIO_SET_SETP(x) (((uint32_t)(((uint32_t)(x)) << GPIO_SET_SETP_SHIFT)) & GPIO_SET_SETP_MASK) + +/* The count of GPIO_SET */ +#define GPIO_SET_COUNT (2U) + +/*! @name CLR - Clear port */ +#define GPIO_CLR_CLRP_MASK (0xFFFFFFFFU) +#define GPIO_CLR_CLRP_SHIFT (0U) +#define GPIO_CLR_CLRP(x) (((uint32_t)(((uint32_t)(x)) << GPIO_CLR_CLRP_SHIFT)) & GPIO_CLR_CLRP_MASK) + +/* The count of GPIO_CLR */ +#define GPIO_CLR_COUNT (2U) + +/*! @name NOT - Toggle port */ +#define GPIO_NOT_NOTP_MASK (0xFFFFFFFFU) +#define GPIO_NOT_NOTP_SHIFT (0U) +#define GPIO_NOT_NOTP(x) (((uint32_t)(((uint32_t)(x)) << GPIO_NOT_NOTP_SHIFT)) & GPIO_NOT_NOTP_MASK) + +/* The count of GPIO_NOT */ +#define GPIO_NOT_COUNT (2U) + +/*! @name DIRSET - Set pin direction bits for port */ +#define GPIO_DIRSET_DIRSETP_MASK (0x1FFFFFFFU) +#define GPIO_DIRSET_DIRSETP_SHIFT (0U) +#define GPIO_DIRSET_DIRSETP(x) (((uint32_t)(((uint32_t)(x)) << GPIO_DIRSET_DIRSETP_SHIFT)) & GPIO_DIRSET_DIRSETP_MASK) + +/* The count of GPIO_DIRSET */ +#define GPIO_DIRSET_COUNT (2U) + +/*! @name DIRCLR - Clear pin direction bits for port */ +#define GPIO_DIRCLR_DIRCLRP_MASK (0x1FFFFFFFU) +#define GPIO_DIRCLR_DIRCLRP_SHIFT (0U) +#define GPIO_DIRCLR_DIRCLRP(x) (((uint32_t)(((uint32_t)(x)) << GPIO_DIRCLR_DIRCLRP_SHIFT)) & GPIO_DIRCLR_DIRCLRP_MASK) + +/* The count of GPIO_DIRCLR */ +#define GPIO_DIRCLR_COUNT (2U) + +/*! @name DIRNOT - Toggle pin direction bits for port */ +#define GPIO_DIRNOT_DIRNOTP_MASK (0x1FFFFFFFU) +#define GPIO_DIRNOT_DIRNOTP_SHIFT (0U) +#define GPIO_DIRNOT_DIRNOTP(x) (((uint32_t)(((uint32_t)(x)) << GPIO_DIRNOT_DIRNOTP_SHIFT)) & GPIO_DIRNOT_DIRNOTP_MASK) + +/* The count of GPIO_DIRNOT */ +#define GPIO_DIRNOT_COUNT (2U) + + +/*! + * @} + */ /* end of group GPIO_Register_Masks */ + + +/* GPIO - Peripheral instance base addresses */ +/** Peripheral GPIO base address */ +#define GPIO_BASE (0x1C000000u) +/** Peripheral GPIO base pointer */ +#define GPIO ((GPIO_Type *)GPIO_BASE) +/** Array initializer of GPIO peripheral base addresses */ +#define GPIO_BASE_ADDRS { GPIO_BASE } +/** Array initializer of GPIO peripheral base pointers */ +#define GPIO_BASE_PTRS { GPIO } + +/*! + * @} + */ /* end of group GPIO_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- I2C Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup I2C_Peripheral_Access_Layer I2C Peripheral Access Layer + * @{ + */ + +/** I2C - Register Layout Typedef */ +typedef struct { + __IO uint32_t CFG; /**< Configuration for shared functions., offset: 0x0 */ + __IO uint32_t STAT; /**< Status register for Master, Slave, and Monitor functions., offset: 0x4 */ + __IO uint32_t INTENSET; /**< Interrupt Enable Set and read register., offset: 0x8 */ + __IO uint32_t INTENCLR; /**< Interrupt Enable Clear register., offset: 0xC */ + __IO uint32_t TIMEOUT; /**< Time-out value register., offset: 0x10 */ + __IO uint32_t CLKDIV; /**< Clock pre-divider for the entire I2C block. This determines what time increments are used for the MSTTIME register, and controls some timing of the Slave function., offset: 0x14 */ + __IO uint32_t INTSTAT; /**< Interrupt Status register for Master, Slave, and Monitor functions., offset: 0x18 */ + uint8_t RESERVED_0[4]; + __IO uint32_t MSTCTL; /**< Master control register., offset: 0x20 */ + __IO uint32_t MSTTIME; /**< Master timing configuration., offset: 0x24 */ + __IO uint32_t MSTDAT; /**< Combined Master receiver and transmitter data register., offset: 0x28 */ + uint8_t RESERVED_1[20]; + __IO uint32_t SLVCTL; /**< Slave control register., offset: 0x40 */ + __IO uint32_t SLVDAT; /**< Combined Slave receiver and transmitter data register., offset: 0x44 */ + __IO uint32_t SLVADR[4]; /**< Slave address 0., array offset: 0x48, array step: 0x4 */ + __IO uint32_t SLVQUAL0; /**< Slave Qualification for address 0., offset: 0x58 */ + uint8_t RESERVED_2[36]; + __IO uint32_t MONRXDAT; /**< Monitor receiver data register., offset: 0x80 */ +} I2C_Type; + +/* ---------------------------------------------------------------------------- + -- I2C Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup I2C_Register_Masks I2C Register Masks + * @{ + */ + +/*! @name CFG - Configuration for shared functions. */ +#define I2C_CFG_MSTEN_MASK (0x1U) +#define I2C_CFG_MSTEN_SHIFT (0U) +#define I2C_CFG_MSTEN(x) (((uint32_t)(((uint32_t)(x)) << I2C_CFG_MSTEN_SHIFT)) & I2C_CFG_MSTEN_MASK) +#define I2C_CFG_SLVEN_MASK (0x2U) +#define I2C_CFG_SLVEN_SHIFT (1U) +#define I2C_CFG_SLVEN(x) (((uint32_t)(((uint32_t)(x)) << I2C_CFG_SLVEN_SHIFT)) & I2C_CFG_SLVEN_MASK) +#define I2C_CFG_MONEN_MASK (0x4U) +#define I2C_CFG_MONEN_SHIFT (2U) +#define I2C_CFG_MONEN(x) (((uint32_t)(((uint32_t)(x)) << I2C_CFG_MONEN_SHIFT)) & I2C_CFG_MONEN_MASK) +#define I2C_CFG_TIMEOUTEN_MASK (0x8U) +#define I2C_CFG_TIMEOUTEN_SHIFT (3U) +#define I2C_CFG_TIMEOUTEN(x) (((uint32_t)(((uint32_t)(x)) << I2C_CFG_TIMEOUTEN_SHIFT)) & I2C_CFG_TIMEOUTEN_MASK) +#define I2C_CFG_MONCLKSTR_MASK (0x10U) +#define I2C_CFG_MONCLKSTR_SHIFT (4U) +#define I2C_CFG_MONCLKSTR(x) (((uint32_t)(((uint32_t)(x)) << I2C_CFG_MONCLKSTR_SHIFT)) & I2C_CFG_MONCLKSTR_MASK) +#define I2C_CFG_HSCAPABLE_MASK (0x20U) +#define I2C_CFG_HSCAPABLE_SHIFT (5U) +#define I2C_CFG_HSCAPABLE(x) (((uint32_t)(((uint32_t)(x)) << I2C_CFG_HSCAPABLE_SHIFT)) & I2C_CFG_HSCAPABLE_MASK) + +/*! @name STAT - Status register for Master, Slave, and Monitor functions. */ +#define I2C_STAT_MSTPENDING_MASK (0x1U) +#define I2C_STAT_MSTPENDING_SHIFT (0U) +#define I2C_STAT_MSTPENDING(x) (((uint32_t)(((uint32_t)(x)) << I2C_STAT_MSTPENDING_SHIFT)) & I2C_STAT_MSTPENDING_MASK) +#define I2C_STAT_MSTSTATE_MASK (0xEU) +#define I2C_STAT_MSTSTATE_SHIFT (1U) +#define I2C_STAT_MSTSTATE(x) (((uint32_t)(((uint32_t)(x)) << I2C_STAT_MSTSTATE_SHIFT)) & I2C_STAT_MSTSTATE_MASK) +#define I2C_STAT_MSTARBLOSS_MASK (0x10U) +#define I2C_STAT_MSTARBLOSS_SHIFT (4U) +#define I2C_STAT_MSTARBLOSS(x) (((uint32_t)(((uint32_t)(x)) << I2C_STAT_MSTARBLOSS_SHIFT)) & I2C_STAT_MSTARBLOSS_MASK) +#define I2C_STAT_MSTSTSTPERR_MASK (0x40U) +#define I2C_STAT_MSTSTSTPERR_SHIFT (6U) +#define I2C_STAT_MSTSTSTPERR(x) (((uint32_t)(((uint32_t)(x)) << I2C_STAT_MSTSTSTPERR_SHIFT)) & I2C_STAT_MSTSTSTPERR_MASK) +#define I2C_STAT_SLVPENDING_MASK (0x100U) +#define I2C_STAT_SLVPENDING_SHIFT (8U) +#define I2C_STAT_SLVPENDING(x) (((uint32_t)(((uint32_t)(x)) << I2C_STAT_SLVPENDING_SHIFT)) & I2C_STAT_SLVPENDING_MASK) +#define I2C_STAT_SLVSTATE_MASK (0x600U) +#define I2C_STAT_SLVSTATE_SHIFT (9U) +#define I2C_STAT_SLVSTATE(x) (((uint32_t)(((uint32_t)(x)) << I2C_STAT_SLVSTATE_SHIFT)) & I2C_STAT_SLVSTATE_MASK) +#define I2C_STAT_SLVNOTSTR_MASK (0x800U) +#define I2C_STAT_SLVNOTSTR_SHIFT (11U) +#define I2C_STAT_SLVNOTSTR(x) (((uint32_t)(((uint32_t)(x)) << I2C_STAT_SLVNOTSTR_SHIFT)) & I2C_STAT_SLVNOTSTR_MASK) +#define I2C_STAT_SLVIDX_MASK (0x3000U) +#define I2C_STAT_SLVIDX_SHIFT (12U) +#define I2C_STAT_SLVIDX(x) (((uint32_t)(((uint32_t)(x)) << I2C_STAT_SLVIDX_SHIFT)) & I2C_STAT_SLVIDX_MASK) +#define I2C_STAT_SLVSEL_MASK (0x4000U) +#define I2C_STAT_SLVSEL_SHIFT (14U) +#define I2C_STAT_SLVSEL(x) (((uint32_t)(((uint32_t)(x)) << I2C_STAT_SLVSEL_SHIFT)) & I2C_STAT_SLVSEL_MASK) +#define I2C_STAT_SLVDESEL_MASK (0x8000U) +#define I2C_STAT_SLVDESEL_SHIFT (15U) +#define I2C_STAT_SLVDESEL(x) (((uint32_t)(((uint32_t)(x)) << I2C_STAT_SLVDESEL_SHIFT)) & I2C_STAT_SLVDESEL_MASK) +#define I2C_STAT_MONRDY_MASK (0x10000U) +#define I2C_STAT_MONRDY_SHIFT (16U) +#define I2C_STAT_MONRDY(x) (((uint32_t)(((uint32_t)(x)) << I2C_STAT_MONRDY_SHIFT)) & I2C_STAT_MONRDY_MASK) +#define I2C_STAT_MONOV_MASK (0x20000U) +#define I2C_STAT_MONOV_SHIFT (17U) +#define I2C_STAT_MONOV(x) (((uint32_t)(((uint32_t)(x)) << I2C_STAT_MONOV_SHIFT)) & I2C_STAT_MONOV_MASK) +#define I2C_STAT_MONACTIVE_MASK (0x40000U) +#define I2C_STAT_MONACTIVE_SHIFT (18U) +#define I2C_STAT_MONACTIVE(x) (((uint32_t)(((uint32_t)(x)) << I2C_STAT_MONACTIVE_SHIFT)) & I2C_STAT_MONACTIVE_MASK) +#define I2C_STAT_MONIDLE_MASK (0x80000U) +#define I2C_STAT_MONIDLE_SHIFT (19U) +#define I2C_STAT_MONIDLE(x) (((uint32_t)(((uint32_t)(x)) << I2C_STAT_MONIDLE_SHIFT)) & I2C_STAT_MONIDLE_MASK) +#define I2C_STAT_EVENTTIMEOUT_MASK (0x1000000U) +#define I2C_STAT_EVENTTIMEOUT_SHIFT (24U) +#define I2C_STAT_EVENTTIMEOUT(x) (((uint32_t)(((uint32_t)(x)) << I2C_STAT_EVENTTIMEOUT_SHIFT)) & I2C_STAT_EVENTTIMEOUT_MASK) +#define I2C_STAT_SCLTIMEOUT_MASK (0x2000000U) +#define I2C_STAT_SCLTIMEOUT_SHIFT (25U) +#define I2C_STAT_SCLTIMEOUT(x) (((uint32_t)(((uint32_t)(x)) << I2C_STAT_SCLTIMEOUT_SHIFT)) & I2C_STAT_SCLTIMEOUT_MASK) + +/*! @name INTENSET - Interrupt Enable Set and read register. */ +#define I2C_INTENSET_MSTPENDINGEN_MASK (0x1U) +#define I2C_INTENSET_MSTPENDINGEN_SHIFT (0U) +#define I2C_INTENSET_MSTPENDINGEN(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_MSTPENDINGEN_SHIFT)) & I2C_INTENSET_MSTPENDINGEN_MASK) +#define I2C_INTENSET_MSTARBLOSSEN_MASK (0x10U) +#define I2C_INTENSET_MSTARBLOSSEN_SHIFT (4U) +#define I2C_INTENSET_MSTARBLOSSEN(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_MSTARBLOSSEN_SHIFT)) & I2C_INTENSET_MSTARBLOSSEN_MASK) +#define I2C_INTENSET_MSTSTSTPERREN_MASK (0x40U) +#define I2C_INTENSET_MSTSTSTPERREN_SHIFT (6U) +#define I2C_INTENSET_MSTSTSTPERREN(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_MSTSTSTPERREN_SHIFT)) & I2C_INTENSET_MSTSTSTPERREN_MASK) +#define I2C_INTENSET_SLVPENDINGEN_MASK (0x100U) +#define I2C_INTENSET_SLVPENDINGEN_SHIFT (8U) +#define I2C_INTENSET_SLVPENDINGEN(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_SLVPENDINGEN_SHIFT)) & I2C_INTENSET_SLVPENDINGEN_MASK) +#define I2C_INTENSET_SLVNOTSTREN_MASK (0x800U) +#define I2C_INTENSET_SLVNOTSTREN_SHIFT (11U) +#define I2C_INTENSET_SLVNOTSTREN(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_SLVNOTSTREN_SHIFT)) & I2C_INTENSET_SLVNOTSTREN_MASK) +#define I2C_INTENSET_SLVDESELEN_MASK (0x8000U) +#define I2C_INTENSET_SLVDESELEN_SHIFT (15U) +#define I2C_INTENSET_SLVDESELEN(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_SLVDESELEN_SHIFT)) & I2C_INTENSET_SLVDESELEN_MASK) +#define I2C_INTENSET_MONRDYEN_MASK (0x10000U) +#define I2C_INTENSET_MONRDYEN_SHIFT (16U) +#define I2C_INTENSET_MONRDYEN(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_MONRDYEN_SHIFT)) & I2C_INTENSET_MONRDYEN_MASK) +#define I2C_INTENSET_MONOVEN_MASK (0x20000U) +#define I2C_INTENSET_MONOVEN_SHIFT (17U) +#define I2C_INTENSET_MONOVEN(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_MONOVEN_SHIFT)) & I2C_INTENSET_MONOVEN_MASK) +#define I2C_INTENSET_MONIDLEEN_MASK (0x80000U) +#define I2C_INTENSET_MONIDLEEN_SHIFT (19U) +#define I2C_INTENSET_MONIDLEEN(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_MONIDLEEN_SHIFT)) & I2C_INTENSET_MONIDLEEN_MASK) +#define I2C_INTENSET_EVENTTIMEOUTEN_MASK (0x1000000U) +#define I2C_INTENSET_EVENTTIMEOUTEN_SHIFT (24U) +#define I2C_INTENSET_EVENTTIMEOUTEN(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_EVENTTIMEOUTEN_SHIFT)) & I2C_INTENSET_EVENTTIMEOUTEN_MASK) +#define I2C_INTENSET_SCLTIMEOUTEN_MASK (0x2000000U) +#define I2C_INTENSET_SCLTIMEOUTEN_SHIFT (25U) +#define I2C_INTENSET_SCLTIMEOUTEN(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENSET_SCLTIMEOUTEN_SHIFT)) & I2C_INTENSET_SCLTIMEOUTEN_MASK) + +/*! @name INTENCLR - Interrupt Enable Clear register. */ +#define I2C_INTENCLR_MSTPENDINGCLR_MASK (0x1U) +#define I2C_INTENCLR_MSTPENDINGCLR_SHIFT (0U) +#define I2C_INTENCLR_MSTPENDINGCLR(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_MSTPENDINGCLR_SHIFT)) & I2C_INTENCLR_MSTPENDINGCLR_MASK) +#define I2C_INTENCLR_MSTARBLOSSCLR_MASK (0x10U) +#define I2C_INTENCLR_MSTARBLOSSCLR_SHIFT (4U) +#define I2C_INTENCLR_MSTARBLOSSCLR(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_MSTARBLOSSCLR_SHIFT)) & I2C_INTENCLR_MSTARBLOSSCLR_MASK) +#define I2C_INTENCLR_MSTSTSTPERRCLR_MASK (0x40U) +#define I2C_INTENCLR_MSTSTSTPERRCLR_SHIFT (6U) +#define I2C_INTENCLR_MSTSTSTPERRCLR(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_MSTSTSTPERRCLR_SHIFT)) & I2C_INTENCLR_MSTSTSTPERRCLR_MASK) +#define I2C_INTENCLR_SLVPENDINGCLR_MASK (0x100U) +#define I2C_INTENCLR_SLVPENDINGCLR_SHIFT (8U) +#define I2C_INTENCLR_SLVPENDINGCLR(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_SLVPENDINGCLR_SHIFT)) & I2C_INTENCLR_SLVPENDINGCLR_MASK) +#define I2C_INTENCLR_SLVNOTSTRCLR_MASK (0x800U) +#define I2C_INTENCLR_SLVNOTSTRCLR_SHIFT (11U) +#define I2C_INTENCLR_SLVNOTSTRCLR(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_SLVNOTSTRCLR_SHIFT)) & I2C_INTENCLR_SLVNOTSTRCLR_MASK) +#define I2C_INTENCLR_SLVDESELCLR_MASK (0x8000U) +#define I2C_INTENCLR_SLVDESELCLR_SHIFT (15U) +#define I2C_INTENCLR_SLVDESELCLR(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_SLVDESELCLR_SHIFT)) & I2C_INTENCLR_SLVDESELCLR_MASK) +#define I2C_INTENCLR_MONRDYCLR_MASK (0x10000U) +#define I2C_INTENCLR_MONRDYCLR_SHIFT (16U) +#define I2C_INTENCLR_MONRDYCLR(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_MONRDYCLR_SHIFT)) & I2C_INTENCLR_MONRDYCLR_MASK) +#define I2C_INTENCLR_MONOVCLR_MASK (0x20000U) +#define I2C_INTENCLR_MONOVCLR_SHIFT (17U) +#define I2C_INTENCLR_MONOVCLR(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_MONOVCLR_SHIFT)) & I2C_INTENCLR_MONOVCLR_MASK) +#define I2C_INTENCLR_MONIDLECLR_MASK (0x80000U) +#define I2C_INTENCLR_MONIDLECLR_SHIFT (19U) +#define I2C_INTENCLR_MONIDLECLR(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_MONIDLECLR_SHIFT)) & I2C_INTENCLR_MONIDLECLR_MASK) +#define I2C_INTENCLR_EVENTTIMEOUTCLR_MASK (0x1000000U) +#define I2C_INTENCLR_EVENTTIMEOUTCLR_SHIFT (24U) +#define I2C_INTENCLR_EVENTTIMEOUTCLR(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_EVENTTIMEOUTCLR_SHIFT)) & I2C_INTENCLR_EVENTTIMEOUTCLR_MASK) +#define I2C_INTENCLR_SCLTIMEOUTCLR_MASK (0x2000000U) +#define I2C_INTENCLR_SCLTIMEOUTCLR_SHIFT (25U) +#define I2C_INTENCLR_SCLTIMEOUTCLR(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTENCLR_SCLTIMEOUTCLR_SHIFT)) & I2C_INTENCLR_SCLTIMEOUTCLR_MASK) + +/*! @name TIMEOUT - Time-out value register. */ +#define I2C_TIMEOUT_TOMIN_MASK (0xFU) +#define I2C_TIMEOUT_TOMIN_SHIFT (0U) +#define I2C_TIMEOUT_TOMIN(x) (((uint32_t)(((uint32_t)(x)) << I2C_TIMEOUT_TOMIN_SHIFT)) & I2C_TIMEOUT_TOMIN_MASK) +#define I2C_TIMEOUT_TO_MASK (0xFFF0U) +#define I2C_TIMEOUT_TO_SHIFT (4U) +#define I2C_TIMEOUT_TO(x) (((uint32_t)(((uint32_t)(x)) << I2C_TIMEOUT_TO_SHIFT)) & I2C_TIMEOUT_TO_MASK) + +/*! @name CLKDIV - Clock pre-divider for the entire I2C block. This determines what time increments are used for the MSTTIME register, and controls some timing of the Slave function. */ +#define I2C_CLKDIV_DIVVAL_MASK (0xFFFFU) +#define I2C_CLKDIV_DIVVAL_SHIFT (0U) +#define I2C_CLKDIV_DIVVAL(x) (((uint32_t)(((uint32_t)(x)) << I2C_CLKDIV_DIVVAL_SHIFT)) & I2C_CLKDIV_DIVVAL_MASK) + +/*! @name INTSTAT - Interrupt Status register for Master, Slave, and Monitor functions. */ +#define I2C_INTSTAT_MSTPENDING_MASK (0x1U) +#define I2C_INTSTAT_MSTPENDING_SHIFT (0U) +#define I2C_INTSTAT_MSTPENDING(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_MSTPENDING_SHIFT)) & I2C_INTSTAT_MSTPENDING_MASK) +#define I2C_INTSTAT_MSTARBLOSS_MASK (0x10U) +#define I2C_INTSTAT_MSTARBLOSS_SHIFT (4U) +#define I2C_INTSTAT_MSTARBLOSS(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_MSTARBLOSS_SHIFT)) & I2C_INTSTAT_MSTARBLOSS_MASK) +#define I2C_INTSTAT_MSTSTSTPERR_MASK (0x40U) +#define I2C_INTSTAT_MSTSTSTPERR_SHIFT (6U) +#define I2C_INTSTAT_MSTSTSTPERR(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_MSTSTSTPERR_SHIFT)) & I2C_INTSTAT_MSTSTSTPERR_MASK) +#define I2C_INTSTAT_SLVPENDING_MASK (0x100U) +#define I2C_INTSTAT_SLVPENDING_SHIFT (8U) +#define I2C_INTSTAT_SLVPENDING(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_SLVPENDING_SHIFT)) & I2C_INTSTAT_SLVPENDING_MASK) +#define I2C_INTSTAT_SLVNOTSTR_MASK (0x800U) +#define I2C_INTSTAT_SLVNOTSTR_SHIFT (11U) +#define I2C_INTSTAT_SLVNOTSTR(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_SLVNOTSTR_SHIFT)) & I2C_INTSTAT_SLVNOTSTR_MASK) +#define I2C_INTSTAT_SLVDESEL_MASK (0x8000U) +#define I2C_INTSTAT_SLVDESEL_SHIFT (15U) +#define I2C_INTSTAT_SLVDESEL(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_SLVDESEL_SHIFT)) & I2C_INTSTAT_SLVDESEL_MASK) +#define I2C_INTSTAT_MONRDY_MASK (0x10000U) +#define I2C_INTSTAT_MONRDY_SHIFT (16U) +#define I2C_INTSTAT_MONRDY(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_MONRDY_SHIFT)) & I2C_INTSTAT_MONRDY_MASK) +#define I2C_INTSTAT_MONOV_MASK (0x20000U) +#define I2C_INTSTAT_MONOV_SHIFT (17U) +#define I2C_INTSTAT_MONOV(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_MONOV_SHIFT)) & I2C_INTSTAT_MONOV_MASK) +#define I2C_INTSTAT_MONIDLE_MASK (0x80000U) +#define I2C_INTSTAT_MONIDLE_SHIFT (19U) +#define I2C_INTSTAT_MONIDLE(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_MONIDLE_SHIFT)) & I2C_INTSTAT_MONIDLE_MASK) +#define I2C_INTSTAT_EVENTTIMEOUT_MASK (0x1000000U) +#define I2C_INTSTAT_EVENTTIMEOUT_SHIFT (24U) +#define I2C_INTSTAT_EVENTTIMEOUT(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_EVENTTIMEOUT_SHIFT)) & I2C_INTSTAT_EVENTTIMEOUT_MASK) +#define I2C_INTSTAT_SCLTIMEOUT_MASK (0x2000000U) +#define I2C_INTSTAT_SCLTIMEOUT_SHIFT (25U) +#define I2C_INTSTAT_SCLTIMEOUT(x) (((uint32_t)(((uint32_t)(x)) << I2C_INTSTAT_SCLTIMEOUT_SHIFT)) & I2C_INTSTAT_SCLTIMEOUT_MASK) + +/*! @name MSTCTL - Master control register. */ +#define I2C_MSTCTL_MSTCONTINUE_MASK (0x1U) +#define I2C_MSTCTL_MSTCONTINUE_SHIFT (0U) +#define I2C_MSTCTL_MSTCONTINUE(x) (((uint32_t)(((uint32_t)(x)) << I2C_MSTCTL_MSTCONTINUE_SHIFT)) & I2C_MSTCTL_MSTCONTINUE_MASK) +#define I2C_MSTCTL_MSTSTART_MASK (0x2U) +#define I2C_MSTCTL_MSTSTART_SHIFT (1U) +#define I2C_MSTCTL_MSTSTART(x) (((uint32_t)(((uint32_t)(x)) << I2C_MSTCTL_MSTSTART_SHIFT)) & I2C_MSTCTL_MSTSTART_MASK) +#define I2C_MSTCTL_MSTSTOP_MASK (0x4U) +#define I2C_MSTCTL_MSTSTOP_SHIFT (2U) +#define I2C_MSTCTL_MSTSTOP(x) (((uint32_t)(((uint32_t)(x)) << I2C_MSTCTL_MSTSTOP_SHIFT)) & I2C_MSTCTL_MSTSTOP_MASK) +#define I2C_MSTCTL_MSTDMA_MASK (0x8U) +#define I2C_MSTCTL_MSTDMA_SHIFT (3U) +#define I2C_MSTCTL_MSTDMA(x) (((uint32_t)(((uint32_t)(x)) << I2C_MSTCTL_MSTDMA_SHIFT)) & I2C_MSTCTL_MSTDMA_MASK) + +/*! @name MSTTIME - Master timing configuration. */ +#define I2C_MSTTIME_MSTSCLLOW_MASK (0x7U) +#define I2C_MSTTIME_MSTSCLLOW_SHIFT (0U) +#define I2C_MSTTIME_MSTSCLLOW(x) (((uint32_t)(((uint32_t)(x)) << I2C_MSTTIME_MSTSCLLOW_SHIFT)) & I2C_MSTTIME_MSTSCLLOW_MASK) +#define I2C_MSTTIME_MSTSCLHIGH_MASK (0x70U) +#define I2C_MSTTIME_MSTSCLHIGH_SHIFT (4U) +#define I2C_MSTTIME_MSTSCLHIGH(x) (((uint32_t)(((uint32_t)(x)) << I2C_MSTTIME_MSTSCLHIGH_SHIFT)) & I2C_MSTTIME_MSTSCLHIGH_MASK) + +/*! @name MSTDAT - Combined Master receiver and transmitter data register. */ +#define I2C_MSTDAT_DATA_MASK (0xFFU) +#define I2C_MSTDAT_DATA_SHIFT (0U) +#define I2C_MSTDAT_DATA(x) (((uint32_t)(((uint32_t)(x)) << I2C_MSTDAT_DATA_SHIFT)) & I2C_MSTDAT_DATA_MASK) + +/*! @name SLVCTL - Slave control register. */ +#define I2C_SLVCTL_SLVCONTINUE_MASK (0x1U) +#define I2C_SLVCTL_SLVCONTINUE_SHIFT (0U) +#define I2C_SLVCTL_SLVCONTINUE(x) (((uint32_t)(((uint32_t)(x)) << I2C_SLVCTL_SLVCONTINUE_SHIFT)) & I2C_SLVCTL_SLVCONTINUE_MASK) +#define I2C_SLVCTL_SLVNACK_MASK (0x2U) +#define I2C_SLVCTL_SLVNACK_SHIFT (1U) +#define I2C_SLVCTL_SLVNACK(x) (((uint32_t)(((uint32_t)(x)) << I2C_SLVCTL_SLVNACK_SHIFT)) & I2C_SLVCTL_SLVNACK_MASK) +#define I2C_SLVCTL_SLVDMA_MASK (0x8U) +#define I2C_SLVCTL_SLVDMA_SHIFT (3U) +#define I2C_SLVCTL_SLVDMA(x) (((uint32_t)(((uint32_t)(x)) << I2C_SLVCTL_SLVDMA_SHIFT)) & I2C_SLVCTL_SLVDMA_MASK) + +/*! @name SLVDAT - Combined Slave receiver and transmitter data register. */ +#define I2C_SLVDAT_DATA_MASK (0xFFU) +#define I2C_SLVDAT_DATA_SHIFT (0U) +#define I2C_SLVDAT_DATA(x) (((uint32_t)(((uint32_t)(x)) << I2C_SLVDAT_DATA_SHIFT)) & I2C_SLVDAT_DATA_MASK) + +/*! @name SLVADR - Slave address 0. */ +#define I2C_SLVADR_SADISABLE_MASK (0x1U) +#define I2C_SLVADR_SADISABLE_SHIFT (0U) +#define I2C_SLVADR_SADISABLE(x) (((uint32_t)(((uint32_t)(x)) << I2C_SLVADR_SADISABLE_SHIFT)) & I2C_SLVADR_SADISABLE_MASK) +#define I2C_SLVADR_SLVADR_MASK (0xFEU) +#define I2C_SLVADR_SLVADR_SHIFT (1U) +#define I2C_SLVADR_SLVADR(x) (((uint32_t)(((uint32_t)(x)) << I2C_SLVADR_SLVADR_SHIFT)) & I2C_SLVADR_SLVADR_MASK) + +/* The count of I2C_SLVADR */ +#define I2C_SLVADR_COUNT (4U) + +/*! @name SLVQUAL0 - Slave Qualification for address 0. */ +#define I2C_SLVQUAL0_QUALMODE0_MASK (0x1U) +#define I2C_SLVQUAL0_QUALMODE0_SHIFT (0U) +#define I2C_SLVQUAL0_QUALMODE0(x) (((uint32_t)(((uint32_t)(x)) << I2C_SLVQUAL0_QUALMODE0_SHIFT)) & I2C_SLVQUAL0_QUALMODE0_MASK) +#define I2C_SLVQUAL0_SLVQUAL0_MASK (0xFEU) +#define I2C_SLVQUAL0_SLVQUAL0_SHIFT (1U) +#define I2C_SLVQUAL0_SLVQUAL0(x) (((uint32_t)(((uint32_t)(x)) << I2C_SLVQUAL0_SLVQUAL0_SHIFT)) & I2C_SLVQUAL0_SLVQUAL0_MASK) + +/*! @name MONRXDAT - Monitor receiver data register. */ +#define I2C_MONRXDAT_MONRXDAT_MASK (0xFFU) +#define I2C_MONRXDAT_MONRXDAT_SHIFT (0U) +#define I2C_MONRXDAT_MONRXDAT(x) (((uint32_t)(((uint32_t)(x)) << I2C_MONRXDAT_MONRXDAT_SHIFT)) & I2C_MONRXDAT_MONRXDAT_MASK) +#define I2C_MONRXDAT_MONSTART_MASK (0x100U) +#define I2C_MONRXDAT_MONSTART_SHIFT (8U) +#define I2C_MONRXDAT_MONSTART(x) (((uint32_t)(((uint32_t)(x)) << I2C_MONRXDAT_MONSTART_SHIFT)) & I2C_MONRXDAT_MONSTART_MASK) +#define I2C_MONRXDAT_MONRESTART_MASK (0x200U) +#define I2C_MONRXDAT_MONRESTART_SHIFT (9U) +#define I2C_MONRXDAT_MONRESTART(x) (((uint32_t)(((uint32_t)(x)) << I2C_MONRXDAT_MONRESTART_SHIFT)) & I2C_MONRXDAT_MONRESTART_MASK) +#define I2C_MONRXDAT_MONNACK_MASK (0x400U) +#define I2C_MONRXDAT_MONNACK_SHIFT (10U) +#define I2C_MONRXDAT_MONNACK(x) (((uint32_t)(((uint32_t)(x)) << I2C_MONRXDAT_MONNACK_SHIFT)) & I2C_MONRXDAT_MONNACK_MASK) + + +/*! + * @} + */ /* end of group I2C_Register_Masks */ + + +/* I2C - Peripheral instance base addresses */ +/** Peripheral I2C0 base address */ +#define I2C0_BASE (0x40094000u) +/** Peripheral I2C0 base pointer */ +#define I2C0 ((I2C_Type *)I2C0_BASE) +/** Peripheral I2C1 base address */ +#define I2C1_BASE (0x40098000u) +/** Peripheral I2C1 base pointer */ +#define I2C1 ((I2C_Type *)I2C1_BASE) +/** Peripheral I2C2 base address */ +#define I2C2_BASE (0x4009C000u) +/** Peripheral I2C2 base pointer */ +#define I2C2 ((I2C_Type *)I2C2_BASE) +/** Array initializer of I2C peripheral base addresses */ +#define I2C_BASE_ADDRS { I2C0_BASE, I2C1_BASE, I2C2_BASE } +/** Array initializer of I2C peripheral base pointers */ +#define I2C_BASE_PTRS { I2C0, I2C1, I2C2 } +/** Interrupt vectors for the I2C peripheral type */ +#define I2C_IRQS { I2C0_IRQn, I2C1_IRQn, I2C2_IRQn } + +/*! + * @} + */ /* end of group I2C_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- INPUTMUX Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup INPUTMUX_Peripheral_Access_Layer INPUTMUX Peripheral Access Layer + * @{ + */ + +/** INPUTMUX - Register Layout Typedef */ +typedef struct { + uint8_t RESERVED_0[192]; + __IO uint32_t PINTSEL[8]; /**< Pin interrupt select register, array offset: 0xC0, array step: 0x4 */ + __IO uint32_t DMA_ITRIG_INMUX[22]; /**< Trigger select register for DMA channel, array offset: 0xE0, array step: 0x4 */ + uint8_t RESERVED_1[8]; + __IO uint32_t DMA_OTRIG_INMUX[4]; /**< DMA output trigger selection to become DMA trigger, array offset: 0x140, array step: 0x4 */ + uint8_t RESERVED_2[16]; + __IO uint32_t FREQMEAS_REF; /**< Selection for frequency measurement reference clock, offset: 0x160 */ + __IO uint32_t FREQMEAS_TARGET; /**< Selection for frequency measurement target clock, offset: 0x164 */ +} INPUTMUX_Type; + +/* ---------------------------------------------------------------------------- + -- INPUTMUX Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup INPUTMUX_Register_Masks INPUTMUX Register Masks + * @{ + */ + +/*! @name PINTSEL - Pin interrupt select register */ +#define INPUTMUX_PINTSEL_INTPIN_MASK (0xFFU) +#define INPUTMUX_PINTSEL_INTPIN_SHIFT (0U) +#define INPUTMUX_PINTSEL_INTPIN(x) (((uint32_t)(((uint32_t)(x)) << INPUTMUX_PINTSEL_INTPIN_SHIFT)) & INPUTMUX_PINTSEL_INTPIN_MASK) + +/* The count of INPUTMUX_PINTSEL */ +#define INPUTMUX_PINTSEL_COUNT (8U) + +/*! @name DMA_ITRIG_INMUX - Trigger select register for DMA channel */ +#define INPUTMUX_DMA_ITRIG_INMUX_INP_MASK (0x1FU) +#define INPUTMUX_DMA_ITRIG_INMUX_INP_SHIFT (0U) +#define INPUTMUX_DMA_ITRIG_INMUX_INP(x) (((uint32_t)(((uint32_t)(x)) << INPUTMUX_DMA_ITRIG_INMUX_INP_SHIFT)) & INPUTMUX_DMA_ITRIG_INMUX_INP_MASK) + +/* The count of INPUTMUX_DMA_ITRIG_INMUX */ +#define INPUTMUX_DMA_ITRIG_INMUX_COUNT (22U) + +/*! @name DMA_OTRIG_INMUX - DMA output trigger selection to become DMA trigger */ +#define INPUTMUX_DMA_OTRIG_INMUX_INP_MASK (0x1FU) +#define INPUTMUX_DMA_OTRIG_INMUX_INP_SHIFT (0U) +#define INPUTMUX_DMA_OTRIG_INMUX_INP(x) (((uint32_t)(((uint32_t)(x)) << INPUTMUX_DMA_OTRIG_INMUX_INP_SHIFT)) & INPUTMUX_DMA_OTRIG_INMUX_INP_MASK) + +/* The count of INPUTMUX_DMA_OTRIG_INMUX */ +#define INPUTMUX_DMA_OTRIG_INMUX_COUNT (4U) + +/*! @name FREQMEAS_REF - Selection for frequency measurement reference clock */ +#define INPUTMUX_FREQMEAS_REF_CLKIN_MASK (0x1FU) +#define INPUTMUX_FREQMEAS_REF_CLKIN_SHIFT (0U) +#define INPUTMUX_FREQMEAS_REF_CLKIN(x) (((uint32_t)(((uint32_t)(x)) << INPUTMUX_FREQMEAS_REF_CLKIN_SHIFT)) & INPUTMUX_FREQMEAS_REF_CLKIN_MASK) + +/*! @name FREQMEAS_TARGET - Selection for frequency measurement target clock */ +#define INPUTMUX_FREQMEAS_TARGET_CLKIN_MASK (0x1FU) +#define INPUTMUX_FREQMEAS_TARGET_CLKIN_SHIFT (0U) +#define INPUTMUX_FREQMEAS_TARGET_CLKIN(x) (((uint32_t)(((uint32_t)(x)) << INPUTMUX_FREQMEAS_TARGET_CLKIN_SHIFT)) & INPUTMUX_FREQMEAS_TARGET_CLKIN_MASK) + + +/*! + * @} + */ /* end of group INPUTMUX_Register_Masks */ + + +/* INPUTMUX - Peripheral instance base addresses */ +/** Peripheral INPUTMUX base address */ +#define INPUTMUX_BASE (0x40050000u) +/** Peripheral INPUTMUX base pointer */ +#define INPUTMUX ((INPUTMUX_Type *)INPUTMUX_BASE) +/** Array initializer of INPUTMUX peripheral base addresses */ +#define INPUTMUX_BASE_ADDRS { INPUTMUX_BASE } +/** Array initializer of INPUTMUX peripheral base pointers */ +#define INPUTMUX_BASE_PTRS { INPUTMUX } + +/*! + * @} + */ /* end of group INPUTMUX_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- IOCON Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup IOCON_Peripheral_Access_Layer IOCON Peripheral Access Layer + * @{ + */ + +/** IOCON - Register Layout Typedef */ +typedef struct { + __IO uint32_t PIO[2][32]; /**< Digital I/O control for port 0 pins PIO0_0..Digital I/O control for port 1 pins PIO1_31, array offset: 0x0, array step: index*0x80, index2*0x4 */ +} IOCON_Type; + +/* ---------------------------------------------------------------------------- + -- IOCON Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup IOCON_Register_Masks IOCON Register Masks + * @{ + */ + +/*! @name PIO - Digital I/O control for port 0 pins PIO0_0..Digital I/O control for port 1 pins PIO1_31 */ +#define IOCON_PIO_FUNC_MASK (0x7U) +#define IOCON_PIO_FUNC_SHIFT (0U) +#define IOCON_PIO_FUNC(x) (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_FUNC_SHIFT)) & IOCON_PIO_FUNC_MASK) +#define IOCON_PIO_MODE_MASK (0x18U) +#define IOCON_PIO_MODE_SHIFT (3U) +#define IOCON_PIO_MODE(x) (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_MODE_SHIFT)) & IOCON_PIO_MODE_MASK) +#define IOCON_PIO_I2CSLEW_MASK (0x20U) +#define IOCON_PIO_I2CSLEW_SHIFT (5U) +#define IOCON_PIO_I2CSLEW(x) (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_I2CSLEW_SHIFT)) & IOCON_PIO_I2CSLEW_MASK) +#define IOCON_PIO_INVERT_MASK (0x40U) +#define IOCON_PIO_INVERT_SHIFT (6U) +#define IOCON_PIO_INVERT(x) (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_INVERT_SHIFT)) & IOCON_PIO_INVERT_MASK) +#define IOCON_PIO_DIGIMODE_MASK (0x80U) +#define IOCON_PIO_DIGIMODE_SHIFT (7U) +#define IOCON_PIO_DIGIMODE(x) (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_DIGIMODE_SHIFT)) & IOCON_PIO_DIGIMODE_MASK) +#define IOCON_PIO_FILTEROFF_MASK (0x100U) +#define IOCON_PIO_FILTEROFF_SHIFT (8U) +#define IOCON_PIO_FILTEROFF(x) (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_FILTEROFF_SHIFT)) & IOCON_PIO_FILTEROFF_MASK) +#define IOCON_PIO_I2CDRIVE_MASK (0x200U) +#define IOCON_PIO_I2CDRIVE_SHIFT (9U) +#define IOCON_PIO_I2CDRIVE(x) (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_I2CDRIVE_SHIFT)) & IOCON_PIO_I2CDRIVE_MASK) +#define IOCON_PIO_SLEW_MASK (0x200U) +#define IOCON_PIO_SLEW_SHIFT (9U) +#define IOCON_PIO_SLEW(x) (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_SLEW_SHIFT)) & IOCON_PIO_SLEW_MASK) +#define IOCON_PIO_OD_MASK (0x400U) +#define IOCON_PIO_OD_SHIFT (10U) +#define IOCON_PIO_OD(x) (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_OD_SHIFT)) & IOCON_PIO_OD_MASK) +#define IOCON_PIO_I2CFILTER_MASK (0x400U) +#define IOCON_PIO_I2CFILTER_SHIFT (10U) +#define IOCON_PIO_I2CFILTER(x) (((uint32_t)(((uint32_t)(x)) << IOCON_PIO_I2CFILTER_SHIFT)) & IOCON_PIO_I2CFILTER_MASK) + +/* The count of IOCON_PIO */ +#define IOCON_PIO_COUNT (2U) + +/* The count of IOCON_PIO */ +#define IOCON_PIO_COUNT2 (32U) + + +/*! + * @} + */ /* end of group IOCON_Register_Masks */ + + +/* IOCON - Peripheral instance base addresses */ +/** Peripheral IOCON base address */ +#define IOCON_BASE (0x4001C000u) +/** Peripheral IOCON base pointer */ +#define IOCON ((IOCON_Type *)IOCON_BASE) +/** Array initializer of IOCON peripheral base addresses */ +#define IOCON_BASE_ADDRS { IOCON_BASE } +/** Array initializer of IOCON peripheral base pointers */ +#define IOCON_BASE_PTRS { IOCON } + +/*! + * @} + */ /* end of group IOCON_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- MAILBOX Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup MAILBOX_Peripheral_Access_Layer MAILBOX Peripheral Access Layer + * @{ + */ + +/** MAILBOX - Register Layout Typedef */ +typedef struct { + struct { /* offset: 0x0, array step: 0x10 */ + __IO uint32_t IRQ; /**< Interrupt request register for the Cortex-M0+ CPU., array offset: 0x0, array step: 0x10 */ + __O uint32_t IRQSET; /**< Set bits in IRQ0, array offset: 0x4, array step: 0x10 */ + __O uint32_t IRQCLR; /**< Clear bits in IRQ0, array offset: 0x8, array step: 0x10 */ + uint8_t RESERVED_0[4]; + } MBOXIRQ[2]; + uint8_t RESERVED_0[216]; + __IO uint32_t MUTEX; /**< Mutual exclusion register[1], offset: 0xF8 */ +} MAILBOX_Type; + +/* ---------------------------------------------------------------------------- + -- MAILBOX Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup MAILBOX_Register_Masks MAILBOX Register Masks + * @{ + */ + +/*! @name MBOXIRQ_IRQ - Interrupt request register for the Cortex-M0+ CPU. */ +#define MAILBOX_MBOXIRQ_IRQ_INTREQ_MASK (0xFFFFFFFFU) +#define MAILBOX_MBOXIRQ_IRQ_INTREQ_SHIFT (0U) +#define MAILBOX_MBOXIRQ_IRQ_INTREQ(x) (((uint32_t)(((uint32_t)(x)) << MAILBOX_MBOXIRQ_IRQ_INTREQ_SHIFT)) & MAILBOX_MBOXIRQ_IRQ_INTREQ_MASK) + +/* The count of MAILBOX_MBOXIRQ_IRQ */ +#define MAILBOX_MBOXIRQ_IRQ_COUNT (2U) + +/*! @name MBOXIRQ_IRQSET - Set bits in IRQ0 */ +#define MAILBOX_MBOXIRQ_IRQSET_INTREQSET_MASK (0xFFFFFFFFU) +#define MAILBOX_MBOXIRQ_IRQSET_INTREQSET_SHIFT (0U) +#define MAILBOX_MBOXIRQ_IRQSET_INTREQSET(x) (((uint32_t)(((uint32_t)(x)) << MAILBOX_MBOXIRQ_IRQSET_INTREQSET_SHIFT)) & MAILBOX_MBOXIRQ_IRQSET_INTREQSET_MASK) + +/* The count of MAILBOX_MBOXIRQ_IRQSET */ +#define MAILBOX_MBOXIRQ_IRQSET_COUNT (2U) + +/*! @name MBOXIRQ_IRQCLR - Clear bits in IRQ0 */ +#define MAILBOX_MBOXIRQ_IRQCLR_INTREQCLR_MASK (0xFFFFFFFFU) +#define MAILBOX_MBOXIRQ_IRQCLR_INTREQCLR_SHIFT (0U) +#define MAILBOX_MBOXIRQ_IRQCLR_INTREQCLR(x) (((uint32_t)(((uint32_t)(x)) << MAILBOX_MBOXIRQ_IRQCLR_INTREQCLR_SHIFT)) & MAILBOX_MBOXIRQ_IRQCLR_INTREQCLR_MASK) + +/* The count of MAILBOX_MBOXIRQ_IRQCLR */ +#define MAILBOX_MBOXIRQ_IRQCLR_COUNT (2U) + +/*! @name MUTEX - Mutual exclusion register[1] */ +#define MAILBOX_MUTEX_EX_MASK (0x1U) +#define MAILBOX_MUTEX_EX_SHIFT (0U) +#define MAILBOX_MUTEX_EX(x) (((uint32_t)(((uint32_t)(x)) << MAILBOX_MUTEX_EX_SHIFT)) & MAILBOX_MUTEX_EX_MASK) + + +/*! + * @} + */ /* end of group MAILBOX_Register_Masks */ + + +/* MAILBOX - Peripheral instance base addresses */ +/** Peripheral MAILBOX base address */ +#define MAILBOX_BASE (0x1C02C000u) +/** Peripheral MAILBOX base pointer */ +#define MAILBOX ((MAILBOX_Type *)MAILBOX_BASE) +/** Array initializer of MAILBOX peripheral base addresses */ +#define MAILBOX_BASE_ADDRS { MAILBOX_BASE } +/** Array initializer of MAILBOX peripheral base pointers */ +#define MAILBOX_BASE_PTRS { MAILBOX } +/** Interrupt vectors for the MAILBOX peripheral type */ +#define MAILBOX_IRQS { MAILBOX_IRQn } + +/*! + * @} + */ /* end of group MAILBOX_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- MRT Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup MRT_Peripheral_Access_Layer MRT Peripheral Access Layer + * @{ + */ + +/** MRT - Register Layout Typedef */ +typedef struct { + struct { /* offset: 0x0, array step: 0x10 */ + __IO uint32_t INTVAL; /**< MRT Time interval value register. This value is loaded into the TIMER register., array offset: 0x0, array step: 0x10 */ + __I uint32_t TIMER; /**< MRT Timer register. This register reads the value of the down-counter., array offset: 0x4, array step: 0x10 */ + __IO uint32_t CTRL; /**< MRT Control register. This register controls the MRT modes., array offset: 0x8, array step: 0x10 */ + __IO uint32_t STAT; /**< MRT Status register., array offset: 0xC, array step: 0x10 */ + } CHANNEL[4]; + uint8_t RESERVED_0[176]; + __IO uint32_t MODCFG; /**< Module Configuration register. This register provides information about this particular MRT instance, and allows choosing an overall mode for the idle channel feature., offset: 0xF0 */ + __I uint32_t IDLE_CH; /**< Idle channel register. This register returns the number of the first idle channel., offset: 0xF4 */ + __IO uint32_t IRQ_FLAG; /**< Global interrupt flag register, offset: 0xF8 */ +} MRT_Type; + +/* ---------------------------------------------------------------------------- + -- MRT Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup MRT_Register_Masks MRT Register Masks + * @{ + */ + +/*! @name CHANNEL_INTVAL - MRT Time interval value register. This value is loaded into the TIMER register. */ +#define MRT_CHANNEL_INTVAL_IVALUE_MASK (0xFFFFFFU) +#define MRT_CHANNEL_INTVAL_IVALUE_SHIFT (0U) +#define MRT_CHANNEL_INTVAL_IVALUE(x) (((uint32_t)(((uint32_t)(x)) << MRT_CHANNEL_INTVAL_IVALUE_SHIFT)) & MRT_CHANNEL_INTVAL_IVALUE_MASK) +#define MRT_CHANNEL_INTVAL_LOAD_MASK (0x80000000U) +#define MRT_CHANNEL_INTVAL_LOAD_SHIFT (31U) +#define MRT_CHANNEL_INTVAL_LOAD(x) (((uint32_t)(((uint32_t)(x)) << MRT_CHANNEL_INTVAL_LOAD_SHIFT)) & MRT_CHANNEL_INTVAL_LOAD_MASK) + +/* The count of MRT_CHANNEL_INTVAL */ +#define MRT_CHANNEL_INTVAL_COUNT (4U) + +/*! @name CHANNEL_TIMER - MRT Timer register. This register reads the value of the down-counter. */ +#define MRT_CHANNEL_TIMER_VALUE_MASK (0xFFFFFFU) +#define MRT_CHANNEL_TIMER_VALUE_SHIFT (0U) +#define MRT_CHANNEL_TIMER_VALUE(x) (((uint32_t)(((uint32_t)(x)) << MRT_CHANNEL_TIMER_VALUE_SHIFT)) & MRT_CHANNEL_TIMER_VALUE_MASK) + +/* The count of MRT_CHANNEL_TIMER */ +#define MRT_CHANNEL_TIMER_COUNT (4U) + +/*! @name CHANNEL_CTRL - MRT Control register. This register controls the MRT modes. */ +#define MRT_CHANNEL_CTRL_INTEN_MASK (0x1U) +#define MRT_CHANNEL_CTRL_INTEN_SHIFT (0U) +#define MRT_CHANNEL_CTRL_INTEN(x) (((uint32_t)(((uint32_t)(x)) << MRT_CHANNEL_CTRL_INTEN_SHIFT)) & MRT_CHANNEL_CTRL_INTEN_MASK) +#define MRT_CHANNEL_CTRL_MODE_MASK (0x6U) +#define MRT_CHANNEL_CTRL_MODE_SHIFT (1U) +#define MRT_CHANNEL_CTRL_MODE(x) (((uint32_t)(((uint32_t)(x)) << MRT_CHANNEL_CTRL_MODE_SHIFT)) & MRT_CHANNEL_CTRL_MODE_MASK) + +/* The count of MRT_CHANNEL_CTRL */ +#define MRT_CHANNEL_CTRL_COUNT (4U) + +/*! @name CHANNEL_STAT - MRT Status register. */ +#define MRT_CHANNEL_STAT_INTFLAG_MASK (0x1U) +#define MRT_CHANNEL_STAT_INTFLAG_SHIFT (0U) +#define MRT_CHANNEL_STAT_INTFLAG(x) (((uint32_t)(((uint32_t)(x)) << MRT_CHANNEL_STAT_INTFLAG_SHIFT)) & MRT_CHANNEL_STAT_INTFLAG_MASK) +#define MRT_CHANNEL_STAT_RUN_MASK (0x2U) +#define MRT_CHANNEL_STAT_RUN_SHIFT (1U) +#define MRT_CHANNEL_STAT_RUN(x) (((uint32_t)(((uint32_t)(x)) << MRT_CHANNEL_STAT_RUN_SHIFT)) & MRT_CHANNEL_STAT_RUN_MASK) +#define MRT_CHANNEL_STAT_INUSE_MASK (0x4U) +#define MRT_CHANNEL_STAT_INUSE_SHIFT (2U) +#define MRT_CHANNEL_STAT_INUSE(x) (((uint32_t)(((uint32_t)(x)) << MRT_CHANNEL_STAT_INUSE_SHIFT)) & MRT_CHANNEL_STAT_INUSE_MASK) + +/* The count of MRT_CHANNEL_STAT */ +#define MRT_CHANNEL_STAT_COUNT (4U) + +/*! @name MODCFG - Module Configuration register. This register provides information about this particular MRT instance, and allows choosing an overall mode for the idle channel feature. */ +#define MRT_MODCFG_NOC_MASK (0xFU) +#define MRT_MODCFG_NOC_SHIFT (0U) +#define MRT_MODCFG_NOC(x) (((uint32_t)(((uint32_t)(x)) << MRT_MODCFG_NOC_SHIFT)) & MRT_MODCFG_NOC_MASK) +#define MRT_MODCFG_NOB_MASK (0x1F0U) +#define MRT_MODCFG_NOB_SHIFT (4U) +#define MRT_MODCFG_NOB(x) (((uint32_t)(((uint32_t)(x)) << MRT_MODCFG_NOB_SHIFT)) & MRT_MODCFG_NOB_MASK) +#define MRT_MODCFG_MULTITASK_MASK (0x80000000U) +#define MRT_MODCFG_MULTITASK_SHIFT (31U) +#define MRT_MODCFG_MULTITASK(x) (((uint32_t)(((uint32_t)(x)) << MRT_MODCFG_MULTITASK_SHIFT)) & MRT_MODCFG_MULTITASK_MASK) + +/*! @name IDLE_CH - Idle channel register. This register returns the number of the first idle channel. */ +#define MRT_IDLE_CH_CHAN_MASK (0xF0U) +#define MRT_IDLE_CH_CHAN_SHIFT (4U) +#define MRT_IDLE_CH_CHAN(x) (((uint32_t)(((uint32_t)(x)) << MRT_IDLE_CH_CHAN_SHIFT)) & MRT_IDLE_CH_CHAN_MASK) + +/*! @name IRQ_FLAG - Global interrupt flag register */ +#define MRT_IRQ_FLAG_GFLAG0_MASK (0x1U) +#define MRT_IRQ_FLAG_GFLAG0_SHIFT (0U) +#define MRT_IRQ_FLAG_GFLAG0(x) (((uint32_t)(((uint32_t)(x)) << MRT_IRQ_FLAG_GFLAG0_SHIFT)) & MRT_IRQ_FLAG_GFLAG0_MASK) +#define MRT_IRQ_FLAG_GFLAG1_MASK (0x2U) +#define MRT_IRQ_FLAG_GFLAG1_SHIFT (1U) +#define MRT_IRQ_FLAG_GFLAG1(x) (((uint32_t)(((uint32_t)(x)) << MRT_IRQ_FLAG_GFLAG1_SHIFT)) & MRT_IRQ_FLAG_GFLAG1_MASK) +#define MRT_IRQ_FLAG_GFLAG2_MASK (0x4U) +#define MRT_IRQ_FLAG_GFLAG2_SHIFT (2U) +#define MRT_IRQ_FLAG_GFLAG2(x) (((uint32_t)(((uint32_t)(x)) << MRT_IRQ_FLAG_GFLAG2_SHIFT)) & MRT_IRQ_FLAG_GFLAG2_MASK) +#define MRT_IRQ_FLAG_GFLAG3_MASK (0x8U) +#define MRT_IRQ_FLAG_GFLAG3_SHIFT (3U) +#define MRT_IRQ_FLAG_GFLAG3(x) (((uint32_t)(((uint32_t)(x)) << MRT_IRQ_FLAG_GFLAG3_SHIFT)) & MRT_IRQ_FLAG_GFLAG3_MASK) + + +/*! + * @} + */ /* end of group MRT_Register_Masks */ + + +/* MRT - Peripheral instance base addresses */ +/** Peripheral MRT0 base address */ +#define MRT0_BASE (0x40074000u) +/** Peripheral MRT0 base pointer */ +#define MRT0 ((MRT_Type *)MRT0_BASE) +/** Array initializer of MRT peripheral base addresses */ +#define MRT_BASE_ADDRS { MRT0_BASE } +/** Array initializer of MRT peripheral base pointers */ +#define MRT_BASE_PTRS { MRT0 } +/** Interrupt vectors for the MRT peripheral type */ +#define MRT_IRQS { MRT0_IRQn } + +/*! + * @} + */ /* end of group MRT_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- PINT Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup PINT_Peripheral_Access_Layer PINT Peripheral Access Layer + * @{ + */ + +/** PINT - Register Layout Typedef */ +typedef struct { + __IO uint32_t ISEL; /**< Pin Interrupt Mode register, offset: 0x0 */ + __IO uint32_t IENR; /**< Pin interrupt level or rising edge interrupt enable register, offset: 0x4 */ + __O uint32_t SIENR; /**< Pin interrupt level or rising edge interrupt set register, offset: 0x8 */ + __O uint32_t CIENR; /**< Pin interrupt level (rising edge interrupt) clear register, offset: 0xC */ + __IO uint32_t IENF; /**< Pin interrupt active level or falling edge interrupt enable register, offset: 0x10 */ + __O uint32_t SIENF; /**< Pin interrupt active level or falling edge interrupt set register, offset: 0x14 */ + __O uint32_t CIENF; /**< Pin interrupt active level or falling edge interrupt clear register, offset: 0x18 */ + __IO uint32_t RISE; /**< Pin interrupt rising edge register, offset: 0x1C */ + __IO uint32_t FALL; /**< Pin interrupt falling edge register, offset: 0x20 */ + __IO uint32_t IST; /**< Pin interrupt status register, offset: 0x24 */ + __IO uint32_t PMCTRL; /**< Pattern match interrupt control register, offset: 0x28 */ + __IO uint32_t PMSRC; /**< Pattern match interrupt bit-slice source register, offset: 0x2C */ + __IO uint32_t PMCFG; /**< Pattern match interrupt bit slice configuration register, offset: 0x30 */ +} PINT_Type; + +/* ---------------------------------------------------------------------------- + -- PINT Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup PINT_Register_Masks PINT Register Masks + * @{ + */ + +/*! @name ISEL - Pin Interrupt Mode register */ +#define PINT_ISEL_PMODE_MASK (0xFFU) +#define PINT_ISEL_PMODE_SHIFT (0U) +#define PINT_ISEL_PMODE(x) (((uint32_t)(((uint32_t)(x)) << PINT_ISEL_PMODE_SHIFT)) & PINT_ISEL_PMODE_MASK) + +/*! @name IENR - Pin interrupt level or rising edge interrupt enable register */ +#define PINT_IENR_ENRL_MASK (0xFFU) +#define PINT_IENR_ENRL_SHIFT (0U) +#define PINT_IENR_ENRL(x) (((uint32_t)(((uint32_t)(x)) << PINT_IENR_ENRL_SHIFT)) & PINT_IENR_ENRL_MASK) + +/*! @name SIENR - Pin interrupt level or rising edge interrupt set register */ +#define PINT_SIENR_SETENRL_MASK (0xFFU) +#define PINT_SIENR_SETENRL_SHIFT (0U) +#define PINT_SIENR_SETENRL(x) (((uint32_t)(((uint32_t)(x)) << PINT_SIENR_SETENRL_SHIFT)) & PINT_SIENR_SETENRL_MASK) + +/*! @name CIENR - Pin interrupt level (rising edge interrupt) clear register */ +#define PINT_CIENR_CENRL_MASK (0xFFU) +#define PINT_CIENR_CENRL_SHIFT (0U) +#define PINT_CIENR_CENRL(x) (((uint32_t)(((uint32_t)(x)) << PINT_CIENR_CENRL_SHIFT)) & PINT_CIENR_CENRL_MASK) + +/*! @name IENF - Pin interrupt active level or falling edge interrupt enable register */ +#define PINT_IENF_ENAF_MASK (0xFFU) +#define PINT_IENF_ENAF_SHIFT (0U) +#define PINT_IENF_ENAF(x) (((uint32_t)(((uint32_t)(x)) << PINT_IENF_ENAF_SHIFT)) & PINT_IENF_ENAF_MASK) + +/*! @name SIENF - Pin interrupt active level or falling edge interrupt set register */ +#define PINT_SIENF_SETENAF_MASK (0xFFU) +#define PINT_SIENF_SETENAF_SHIFT (0U) +#define PINT_SIENF_SETENAF(x) (((uint32_t)(((uint32_t)(x)) << PINT_SIENF_SETENAF_SHIFT)) & PINT_SIENF_SETENAF_MASK) + +/*! @name CIENF - Pin interrupt active level or falling edge interrupt clear register */ +#define PINT_CIENF_CENAF_MASK (0xFFU) +#define PINT_CIENF_CENAF_SHIFT (0U) +#define PINT_CIENF_CENAF(x) (((uint32_t)(((uint32_t)(x)) << PINT_CIENF_CENAF_SHIFT)) & PINT_CIENF_CENAF_MASK) + +/*! @name RISE - Pin interrupt rising edge register */ +#define PINT_RISE_RDET_MASK (0xFFU) +#define PINT_RISE_RDET_SHIFT (0U) +#define PINT_RISE_RDET(x) (((uint32_t)(((uint32_t)(x)) << PINT_RISE_RDET_SHIFT)) & PINT_RISE_RDET_MASK) + +/*! @name FALL - Pin interrupt falling edge register */ +#define PINT_FALL_FDET_MASK (0xFFU) +#define PINT_FALL_FDET_SHIFT (0U) +#define PINT_FALL_FDET(x) (((uint32_t)(((uint32_t)(x)) << PINT_FALL_FDET_SHIFT)) & PINT_FALL_FDET_MASK) + +/*! @name IST - Pin interrupt status register */ +#define PINT_IST_PSTAT_MASK (0xFFU) +#define PINT_IST_PSTAT_SHIFT (0U) +#define PINT_IST_PSTAT(x) (((uint32_t)(((uint32_t)(x)) << PINT_IST_PSTAT_SHIFT)) & PINT_IST_PSTAT_MASK) + +/*! @name PMCTRL - Pattern match interrupt control register */ +#define PINT_PMCTRL_SEL_PMATCH_MASK (0x1U) +#define PINT_PMCTRL_SEL_PMATCH_SHIFT (0U) +#define PINT_PMCTRL_SEL_PMATCH(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCTRL_SEL_PMATCH_SHIFT)) & PINT_PMCTRL_SEL_PMATCH_MASK) +#define PINT_PMCTRL_ENA_RXEV_MASK (0x2U) +#define PINT_PMCTRL_ENA_RXEV_SHIFT (1U) +#define PINT_PMCTRL_ENA_RXEV(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCTRL_ENA_RXEV_SHIFT)) & PINT_PMCTRL_ENA_RXEV_MASK) +#define PINT_PMCTRL_PMAT_MASK (0xFF000000U) +#define PINT_PMCTRL_PMAT_SHIFT (24U) +#define PINT_PMCTRL_PMAT(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCTRL_PMAT_SHIFT)) & PINT_PMCTRL_PMAT_MASK) + +/*! @name PMSRC - Pattern match interrupt bit-slice source register */ +#define PINT_PMSRC_SRC0_MASK (0x700U) +#define PINT_PMSRC_SRC0_SHIFT (8U) +#define PINT_PMSRC_SRC0(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMSRC_SRC0_SHIFT)) & PINT_PMSRC_SRC0_MASK) +#define PINT_PMSRC_SRC1_MASK (0x3800U) +#define PINT_PMSRC_SRC1_SHIFT (11U) +#define PINT_PMSRC_SRC1(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMSRC_SRC1_SHIFT)) & PINT_PMSRC_SRC1_MASK) +#define PINT_PMSRC_SRC2_MASK (0x1C000U) +#define PINT_PMSRC_SRC2_SHIFT (14U) +#define PINT_PMSRC_SRC2(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMSRC_SRC2_SHIFT)) & PINT_PMSRC_SRC2_MASK) +#define PINT_PMSRC_SRC3_MASK (0xE0000U) +#define PINT_PMSRC_SRC3_SHIFT (17U) +#define PINT_PMSRC_SRC3(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMSRC_SRC3_SHIFT)) & PINT_PMSRC_SRC3_MASK) +#define PINT_PMSRC_SRC4_MASK (0x700000U) +#define PINT_PMSRC_SRC4_SHIFT (20U) +#define PINT_PMSRC_SRC4(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMSRC_SRC4_SHIFT)) & PINT_PMSRC_SRC4_MASK) +#define PINT_PMSRC_SRC5_MASK (0x3800000U) +#define PINT_PMSRC_SRC5_SHIFT (23U) +#define PINT_PMSRC_SRC5(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMSRC_SRC5_SHIFT)) & PINT_PMSRC_SRC5_MASK) +#define PINT_PMSRC_SRC6_MASK (0x1C000000U) +#define PINT_PMSRC_SRC6_SHIFT (26U) +#define PINT_PMSRC_SRC6(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMSRC_SRC6_SHIFT)) & PINT_PMSRC_SRC6_MASK) +#define PINT_PMSRC_SRC7_MASK (0xE0000000U) +#define PINT_PMSRC_SRC7_SHIFT (29U) +#define PINT_PMSRC_SRC7(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMSRC_SRC7_SHIFT)) & PINT_PMSRC_SRC7_MASK) + +/*! @name PMCFG - Pattern match interrupt bit slice configuration register */ +#define PINT_PMCFG_PROD_ENDPTS0_MASK (0x1U) +#define PINT_PMCFG_PROD_ENDPTS0_SHIFT (0U) +#define PINT_PMCFG_PROD_ENDPTS0(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_PROD_ENDPTS0_SHIFT)) & PINT_PMCFG_PROD_ENDPTS0_MASK) +#define PINT_PMCFG_PROD_ENDPTS1_MASK (0x2U) +#define PINT_PMCFG_PROD_ENDPTS1_SHIFT (1U) +#define PINT_PMCFG_PROD_ENDPTS1(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_PROD_ENDPTS1_SHIFT)) & PINT_PMCFG_PROD_ENDPTS1_MASK) +#define PINT_PMCFG_PROD_ENDPTS2_MASK (0x4U) +#define PINT_PMCFG_PROD_ENDPTS2_SHIFT (2U) +#define PINT_PMCFG_PROD_ENDPTS2(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_PROD_ENDPTS2_SHIFT)) & PINT_PMCFG_PROD_ENDPTS2_MASK) +#define PINT_PMCFG_PROD_ENDPTS3_MASK (0x8U) +#define PINT_PMCFG_PROD_ENDPTS3_SHIFT (3U) +#define PINT_PMCFG_PROD_ENDPTS3(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_PROD_ENDPTS3_SHIFT)) & PINT_PMCFG_PROD_ENDPTS3_MASK) +#define PINT_PMCFG_PROD_ENDPTS4_MASK (0x10U) +#define PINT_PMCFG_PROD_ENDPTS4_SHIFT (4U) +#define PINT_PMCFG_PROD_ENDPTS4(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_PROD_ENDPTS4_SHIFT)) & PINT_PMCFG_PROD_ENDPTS4_MASK) +#define PINT_PMCFG_PROD_ENDPTS5_MASK (0x20U) +#define PINT_PMCFG_PROD_ENDPTS5_SHIFT (5U) +#define PINT_PMCFG_PROD_ENDPTS5(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_PROD_ENDPTS5_SHIFT)) & PINT_PMCFG_PROD_ENDPTS5_MASK) +#define PINT_PMCFG_PROD_ENDPTS6_MASK (0x40U) +#define PINT_PMCFG_PROD_ENDPTS6_SHIFT (6U) +#define PINT_PMCFG_PROD_ENDPTS6(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_PROD_ENDPTS6_SHIFT)) & PINT_PMCFG_PROD_ENDPTS6_MASK) +#define PINT_PMCFG_CFG0_MASK (0x700U) +#define PINT_PMCFG_CFG0_SHIFT (8U) +#define PINT_PMCFG_CFG0(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_CFG0_SHIFT)) & PINT_PMCFG_CFG0_MASK) +#define PINT_PMCFG_CFG1_MASK (0x3800U) +#define PINT_PMCFG_CFG1_SHIFT (11U) +#define PINT_PMCFG_CFG1(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_CFG1_SHIFT)) & PINT_PMCFG_CFG1_MASK) +#define PINT_PMCFG_CFG2_MASK (0x1C000U) +#define PINT_PMCFG_CFG2_SHIFT (14U) +#define PINT_PMCFG_CFG2(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_CFG2_SHIFT)) & PINT_PMCFG_CFG2_MASK) +#define PINT_PMCFG_CFG3_MASK (0xE0000U) +#define PINT_PMCFG_CFG3_SHIFT (17U) +#define PINT_PMCFG_CFG3(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_CFG3_SHIFT)) & PINT_PMCFG_CFG3_MASK) +#define PINT_PMCFG_CFG4_MASK (0x700000U) +#define PINT_PMCFG_CFG4_SHIFT (20U) +#define PINT_PMCFG_CFG4(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_CFG4_SHIFT)) & PINT_PMCFG_CFG4_MASK) +#define PINT_PMCFG_CFG5_MASK (0x3800000U) +#define PINT_PMCFG_CFG5_SHIFT (23U) +#define PINT_PMCFG_CFG5(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_CFG5_SHIFT)) & PINT_PMCFG_CFG5_MASK) +#define PINT_PMCFG_CFG6_MASK (0x1C000000U) +#define PINT_PMCFG_CFG6_SHIFT (26U) +#define PINT_PMCFG_CFG6(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_CFG6_SHIFT)) & PINT_PMCFG_CFG6_MASK) +#define PINT_PMCFG_CFG7_MASK (0xE0000000U) +#define PINT_PMCFG_CFG7_SHIFT (29U) +#define PINT_PMCFG_CFG7(x) (((uint32_t)(((uint32_t)(x)) << PINT_PMCFG_CFG7_SHIFT)) & PINT_PMCFG_CFG7_MASK) + + +/*! + * @} + */ /* end of group PINT_Register_Masks */ + + +/* PINT - Peripheral instance base addresses */ +/** Peripheral PINT base address */ +#define PINT_BASE (0x40018000u) +/** Peripheral PINT base pointer */ +#define PINT ((PINT_Type *)PINT_BASE) +/** Array initializer of PINT peripheral base addresses */ +#define PINT_BASE_ADDRS { PINT_BASE } +/** Array initializer of PINT peripheral base pointers */ +#define PINT_BASE_PTRS { PINT } +/** Interrupt vectors for the PINT peripheral type */ +#define PINT_IRQS { PIN_INT0_IRQn, PIN_INT1_IRQn, PIN_INT2_IRQn, PIN_INT3_IRQn, PIN_INT4_IRQn, PIN_INT5_IRQn, PIN_INT6_IRQn, PIN_INT7_IRQn } + +/*! + * @} + */ /* end of group PINT_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- RIT Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup RIT_Peripheral_Access_Layer RIT Peripheral Access Layer + * @{ + */ + +/** RIT - Register Layout Typedef */ +typedef struct { + __IO uint32_t COMPVAL; /**< Compare value LSB register. Holds the 32 LSBs of the compare value., offset: 0x0 */ + __IO uint32_t MASK; /**< Mask LSB register. This register holds the 32 LSB s of the mask value. A 1 written to any bit will force the compare to be true for the corresponding bit of the counter and compare register., offset: 0x4 */ + __IO uint32_t CTRL; /**< Control register., offset: 0x8 */ + __IO uint32_t COUNTER; /**< Counter LSB register. 32 LSBs of the counter., offset: 0xC */ + __IO uint32_t COMPVAL_H; /**< Compare value MSB register. Holds the 16 MSBs of the compare value., offset: 0x10 */ + __IO uint32_t MASK_H; /**< Mask MSB register. This register holds the 16 MSBs of the mask value. A 1 written to any bit will force a compare on the corresponding bit of the counter and compare register., offset: 0x14 */ + uint8_t RESERVED_0[4]; + __IO uint32_t COUNTER_H; /**< Counter MSB register. 16 MSBs of the counter., offset: 0x1C */ +} RIT_Type; + +/* ---------------------------------------------------------------------------- + -- RIT Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup RIT_Register_Masks RIT Register Masks + * @{ + */ + +/*! @name COMPVAL - Compare value LSB register. Holds the 32 LSBs of the compare value. */ +#define RIT_COMPVAL_RICOMP_MASK (0xFFFFFFFFU) +#define RIT_COMPVAL_RICOMP_SHIFT (0U) +#define RIT_COMPVAL_RICOMP(x) (((uint32_t)(((uint32_t)(x)) << RIT_COMPVAL_RICOMP_SHIFT)) & RIT_COMPVAL_RICOMP_MASK) + +/*! @name MASK - Mask LSB register. This register holds the 32 LSB s of the mask value. A 1 written to any bit will force the compare to be true for the corresponding bit of the counter and compare register. */ +#define RIT_MASK_RIMASK_MASK (0xFFFFFFFFU) +#define RIT_MASK_RIMASK_SHIFT (0U) +#define RIT_MASK_RIMASK(x) (((uint32_t)(((uint32_t)(x)) << RIT_MASK_RIMASK_SHIFT)) & RIT_MASK_RIMASK_MASK) + +/*! @name CTRL - Control register. */ +#define RIT_CTRL_RITINT_MASK (0x1U) +#define RIT_CTRL_RITINT_SHIFT (0U) +#define RIT_CTRL_RITINT(x) (((uint32_t)(((uint32_t)(x)) << RIT_CTRL_RITINT_SHIFT)) & RIT_CTRL_RITINT_MASK) +#define RIT_CTRL_RITENCLR_MASK (0x2U) +#define RIT_CTRL_RITENCLR_SHIFT (1U) +#define RIT_CTRL_RITENCLR(x) (((uint32_t)(((uint32_t)(x)) << RIT_CTRL_RITENCLR_SHIFT)) & RIT_CTRL_RITENCLR_MASK) +#define RIT_CTRL_RITENBR_MASK (0x4U) +#define RIT_CTRL_RITENBR_SHIFT (2U) +#define RIT_CTRL_RITENBR(x) (((uint32_t)(((uint32_t)(x)) << RIT_CTRL_RITENBR_SHIFT)) & RIT_CTRL_RITENBR_MASK) +#define RIT_CTRL_RITEN_MASK (0x8U) +#define RIT_CTRL_RITEN_SHIFT (3U) +#define RIT_CTRL_RITEN(x) (((uint32_t)(((uint32_t)(x)) << RIT_CTRL_RITEN_SHIFT)) & RIT_CTRL_RITEN_MASK) + +/*! @name COUNTER - Counter LSB register. 32 LSBs of the counter. */ +#define RIT_COUNTER_RICOUNTER_MASK (0xFFFFFFFFU) +#define RIT_COUNTER_RICOUNTER_SHIFT (0U) +#define RIT_COUNTER_RICOUNTER(x) (((uint32_t)(((uint32_t)(x)) << RIT_COUNTER_RICOUNTER_SHIFT)) & RIT_COUNTER_RICOUNTER_MASK) + +/*! @name COMPVAL_H - Compare value MSB register. Holds the 16 MSBs of the compare value. */ +#define RIT_COMPVAL_H_RICOMP_MASK (0xFFFFU) +#define RIT_COMPVAL_H_RICOMP_SHIFT (0U) +#define RIT_COMPVAL_H_RICOMP(x) (((uint32_t)(((uint32_t)(x)) << RIT_COMPVAL_H_RICOMP_SHIFT)) & RIT_COMPVAL_H_RICOMP_MASK) + +/*! @name MASK_H - Mask MSB register. This register holds the 16 MSBs of the mask value. A 1 written to any bit will force a compare on the corresponding bit of the counter and compare register. */ +#define RIT_MASK_H_RIMASK_MASK (0xFFFFU) +#define RIT_MASK_H_RIMASK_SHIFT (0U) +#define RIT_MASK_H_RIMASK(x) (((uint32_t)(((uint32_t)(x)) << RIT_MASK_H_RIMASK_SHIFT)) & RIT_MASK_H_RIMASK_MASK) + +/*! @name COUNTER_H - Counter MSB register. 16 MSBs of the counter. */ +#define RIT_COUNTER_H_RICOUNTER_MASK (0xFFFFU) +#define RIT_COUNTER_H_RICOUNTER_SHIFT (0U) +#define RIT_COUNTER_H_RICOUNTER(x) (((uint32_t)(((uint32_t)(x)) << RIT_COUNTER_H_RICOUNTER_SHIFT)) & RIT_COUNTER_H_RICOUNTER_MASK) + + +/*! + * @} + */ /* end of group RIT_Register_Masks */ + + +/* RIT - Peripheral instance base addresses */ +/** Peripheral RIT base address */ +#define RIT_BASE (0x40070000u) +/** Peripheral RIT base pointer */ +#define RIT ((RIT_Type *)RIT_BASE) +/** Array initializer of RIT peripheral base addresses */ +#define RIT_BASE_ADDRS { RIT_BASE } +/** Array initializer of RIT peripheral base pointers */ +#define RIT_BASE_PTRS { RIT } +/** Interrupt vectors for the RIT peripheral type */ +#define RIT_IRQS { RIT_IRQn } + +/*! + * @} + */ /* end of group RIT_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- RTC Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup RTC_Peripheral_Access_Layer RTC Peripheral Access Layer + * @{ + */ + +/** RTC - Register Layout Typedef */ +typedef struct { + __IO uint32_t CTRL; /**< RTC control register, offset: 0x0 */ + __IO uint32_t MATCH; /**< RTC match register, offset: 0x4 */ + __IO uint32_t COUNT; /**< RTC counter register, offset: 0x8 */ + __IO uint32_t WAKE; /**< High-resolution/wake-up timer control register, offset: 0xC */ +} RTC_Type; + +/* ---------------------------------------------------------------------------- + -- RTC Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup RTC_Register_Masks RTC Register Masks + * @{ + */ + +/*! @name CTRL - RTC control register */ +#define RTC_CTRL_SWRESET_MASK (0x1U) +#define RTC_CTRL_SWRESET_SHIFT (0U) +#define RTC_CTRL_SWRESET(x) (((uint32_t)(((uint32_t)(x)) << RTC_CTRL_SWRESET_SHIFT)) & RTC_CTRL_SWRESET_MASK) +#define RTC_CTRL_OFD_MASK (0x2U) +#define RTC_CTRL_OFD_SHIFT (1U) +#define RTC_CTRL_OFD(x) (((uint32_t)(((uint32_t)(x)) << RTC_CTRL_OFD_SHIFT)) & RTC_CTRL_OFD_MASK) +#define RTC_CTRL_ALARM1HZ_MASK (0x4U) +#define RTC_CTRL_ALARM1HZ_SHIFT (2U) +#define RTC_CTRL_ALARM1HZ(x) (((uint32_t)(((uint32_t)(x)) << RTC_CTRL_ALARM1HZ_SHIFT)) & RTC_CTRL_ALARM1HZ_MASK) +#define RTC_CTRL_WAKE1KHZ_MASK (0x8U) +#define RTC_CTRL_WAKE1KHZ_SHIFT (3U) +#define RTC_CTRL_WAKE1KHZ(x) (((uint32_t)(((uint32_t)(x)) << RTC_CTRL_WAKE1KHZ_SHIFT)) & RTC_CTRL_WAKE1KHZ_MASK) +#define RTC_CTRL_ALARMDPD_EN_MASK (0x10U) +#define RTC_CTRL_ALARMDPD_EN_SHIFT (4U) +#define RTC_CTRL_ALARMDPD_EN(x) (((uint32_t)(((uint32_t)(x)) << RTC_CTRL_ALARMDPD_EN_SHIFT)) & RTC_CTRL_ALARMDPD_EN_MASK) +#define RTC_CTRL_WAKEDPD_EN_MASK (0x20U) +#define RTC_CTRL_WAKEDPD_EN_SHIFT (5U) +#define RTC_CTRL_WAKEDPD_EN(x) (((uint32_t)(((uint32_t)(x)) << RTC_CTRL_WAKEDPD_EN_SHIFT)) & RTC_CTRL_WAKEDPD_EN_MASK) +#define RTC_CTRL_RTC1KHZ_EN_MASK (0x40U) +#define RTC_CTRL_RTC1KHZ_EN_SHIFT (6U) +#define RTC_CTRL_RTC1KHZ_EN(x) (((uint32_t)(((uint32_t)(x)) << RTC_CTRL_RTC1KHZ_EN_SHIFT)) & RTC_CTRL_RTC1KHZ_EN_MASK) +#define RTC_CTRL_RTC_EN_MASK (0x80U) +#define RTC_CTRL_RTC_EN_SHIFT (7U) +#define RTC_CTRL_RTC_EN(x) (((uint32_t)(((uint32_t)(x)) << RTC_CTRL_RTC_EN_SHIFT)) & RTC_CTRL_RTC_EN_MASK) + +/*! @name MATCH - RTC match register */ +#define RTC_MATCH_MATVAL_MASK (0xFFFFFFFFU) +#define RTC_MATCH_MATVAL_SHIFT (0U) +#define RTC_MATCH_MATVAL(x) (((uint32_t)(((uint32_t)(x)) << RTC_MATCH_MATVAL_SHIFT)) & RTC_MATCH_MATVAL_MASK) + +/*! @name COUNT - RTC counter register */ +#define RTC_COUNT_VAL_MASK (0xFFFFFFFFU) +#define RTC_COUNT_VAL_SHIFT (0U) +#define RTC_COUNT_VAL(x) (((uint32_t)(((uint32_t)(x)) << RTC_COUNT_VAL_SHIFT)) & RTC_COUNT_VAL_MASK) + +/*! @name WAKE - High-resolution/wake-up timer control register */ +#define RTC_WAKE_VAL_MASK (0xFFFFU) +#define RTC_WAKE_VAL_SHIFT (0U) +#define RTC_WAKE_VAL(x) (((uint32_t)(((uint32_t)(x)) << RTC_WAKE_VAL_SHIFT)) & RTC_WAKE_VAL_MASK) + + +/*! + * @} + */ /* end of group RTC_Register_Masks */ + + +/* RTC - Peripheral instance base addresses */ +/** Peripheral RTC base address */ +#define RTC_BASE (0x4003C000u) +/** Peripheral RTC base pointer */ +#define RTC ((RTC_Type *)RTC_BASE) +/** Array initializer of RTC peripheral base addresses */ +#define RTC_BASE_ADDRS { RTC_BASE } +/** Array initializer of RTC peripheral base pointers */ +#define RTC_BASE_PTRS { RTC } +/** Interrupt vectors for the RTC peripheral type */ +#define RTC_IRQS { RTC_IRQn } + +/*! + * @} + */ /* end of group RTC_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- SCT Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SCT_Peripheral_Access_Layer SCT Peripheral Access Layer + * @{ + */ + +/** SCT - Register Layout Typedef */ +typedef struct { + __IO uint32_t CONFIG; /**< SCT configuration register, offset: 0x0 */ + __IO uint32_t CTRL; /**< SCT control register, offset: 0x4 */ + __IO uint32_t LIMIT; /**< SCT limit event select register, offset: 0x8 */ + __IO uint32_t HALT; /**< SCT halt event select register, offset: 0xC */ + __IO uint32_t STOP; /**< SCT stop event select register, offset: 0x10 */ + __IO uint32_t START; /**< SCT start event select register, offset: 0x14 */ + uint8_t RESERVED_0[40]; + __IO uint32_t COUNT; /**< SCT counter register, offset: 0x40 */ + __IO uint32_t STATE; /**< SCT state register, offset: 0x44 */ + __I uint32_t INPUT; /**< SCT input register, offset: 0x48 */ + __IO uint32_t REGMODE; /**< SCT match/capture mode register, offset: 0x4C */ + __IO uint32_t OUTPUT; /**< SCT output register, offset: 0x50 */ + __IO uint32_t OUTPUTDIRCTRL; /**< SCT output counter direction control register, offset: 0x54 */ + __IO uint32_t RES; /**< SCT conflict resolution register, offset: 0x58 */ + __IO uint32_t DMA0REQUEST; /**< SCT DMA request 0 register, offset: 0x5C */ + __IO uint32_t DMA1REQUEST; /**< SCT DMA request 1 register, offset: 0x60 */ + uint8_t RESERVED_1[140]; + __IO uint32_t EVEN; /**< SCT event interrupt enable register, offset: 0xF0 */ + __IO uint32_t EVFLAG; /**< SCT event flag register, offset: 0xF4 */ + __IO uint32_t CONEN; /**< SCT conflict interrupt enable register, offset: 0xF8 */ + __IO uint32_t CONFLAG; /**< SCT conflict flag register, offset: 0xFC */ + union { /* offset: 0x100 */ + __IO uint32_t SCTCAP[13]; /**< SCT capture register of capture channel, array offset: 0x100, array step: 0x4 */ + __IO uint32_t SCTMATCH[13]; /**< SCT match value register of match channels, array offset: 0x100, array step: 0x4 */ + }; + uint8_t RESERVED_2[204]; + union { /* offset: 0x200 */ + __IO uint32_t SCTCAPCTRL[13]; /**< SCT capture control register, array offset: 0x200, array step: 0x4 */ + __IO uint32_t SCTMATCHREL[13]; /**< SCT match reload value register, array offset: 0x200, array step: 0x4 */ + }; + uint8_t RESERVED_3[204]; + struct { /* offset: 0x300, array step: 0x8 */ + __IO uint32_t STATE; /**< SCT event state register 0, array offset: 0x300, array step: 0x8 */ + __IO uint32_t CTRL; /**< SCT event control register 0, array offset: 0x304, array step: 0x8 */ + } EVENT[13]; + uint8_t RESERVED_4[408]; + struct { /* offset: 0x500, array step: 0x8 */ + __IO uint32_t SET; /**< SCT output 0 set register, array offset: 0x500, array step: 0x8 */ + __IO uint32_t CLR; /**< SCT output 0 clear register, array offset: 0x504, array step: 0x8 */ + } OUT[8]; +} SCT_Type; + +/* ---------------------------------------------------------------------------- + -- SCT Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SCT_Register_Masks SCT Register Masks + * @{ + */ + +/*! @name CONFIG - SCT configuration register */ +#define SCT_CONFIG_UNIFY_MASK (0x1U) +#define SCT_CONFIG_UNIFY_SHIFT (0U) +#define SCT_CONFIG_UNIFY(x) (((uint32_t)(((uint32_t)(x)) << SCT_CONFIG_UNIFY_SHIFT)) & SCT_CONFIG_UNIFY_MASK) +#define SCT_CONFIG_CLKMODE_MASK (0x6U) +#define SCT_CONFIG_CLKMODE_SHIFT (1U) +#define SCT_CONFIG_CLKMODE(x) (((uint32_t)(((uint32_t)(x)) << SCT_CONFIG_CLKMODE_SHIFT)) & SCT_CONFIG_CLKMODE_MASK) +#define SCT_CONFIG_CKSEL_MASK (0x78U) +#define SCT_CONFIG_CKSEL_SHIFT (3U) +#define SCT_CONFIG_CKSEL(x) (((uint32_t)(((uint32_t)(x)) << SCT_CONFIG_CKSEL_SHIFT)) & SCT_CONFIG_CKSEL_MASK) +#define SCT_CONFIG_NORELAOD_L_MASK (0x80U) +#define SCT_CONFIG_NORELAOD_L_SHIFT (7U) +#define SCT_CONFIG_NORELAOD_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_CONFIG_NORELAOD_L_SHIFT)) & SCT_CONFIG_NORELAOD_L_MASK) +#define SCT_CONFIG_NORELOAD_H_MASK (0x100U) +#define SCT_CONFIG_NORELOAD_H_SHIFT (8U) +#define SCT_CONFIG_NORELOAD_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_CONFIG_NORELOAD_H_SHIFT)) & SCT_CONFIG_NORELOAD_H_MASK) +#define SCT_CONFIG_INSYNC_MASK (0x1E00U) +#define SCT_CONFIG_INSYNC_SHIFT (9U) +#define SCT_CONFIG_INSYNC(x) (((uint32_t)(((uint32_t)(x)) << SCT_CONFIG_INSYNC_SHIFT)) & SCT_CONFIG_INSYNC_MASK) +#define SCT_CONFIG_AUTOLIMIT_L_MASK (0x20000U) +#define SCT_CONFIG_AUTOLIMIT_L_SHIFT (17U) +#define SCT_CONFIG_AUTOLIMIT_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_CONFIG_AUTOLIMIT_L_SHIFT)) & SCT_CONFIG_AUTOLIMIT_L_MASK) +#define SCT_CONFIG_AUTOLIMIT_H_MASK (0x40000U) +#define SCT_CONFIG_AUTOLIMIT_H_SHIFT (18U) +#define SCT_CONFIG_AUTOLIMIT_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_CONFIG_AUTOLIMIT_H_SHIFT)) & SCT_CONFIG_AUTOLIMIT_H_MASK) + +/*! @name CTRL - SCT control register */ +#define SCT_CTRL_DOWN_L_MASK (0x1U) +#define SCT_CTRL_DOWN_L_SHIFT (0U) +#define SCT_CTRL_DOWN_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_CTRL_DOWN_L_SHIFT)) & SCT_CTRL_DOWN_L_MASK) +#define SCT_CTRL_STOP_L_MASK (0x2U) +#define SCT_CTRL_STOP_L_SHIFT (1U) +#define SCT_CTRL_STOP_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_CTRL_STOP_L_SHIFT)) & SCT_CTRL_STOP_L_MASK) +#define SCT_CTRL_HALT_L_MASK (0x4U) +#define SCT_CTRL_HALT_L_SHIFT (2U) +#define SCT_CTRL_HALT_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_CTRL_HALT_L_SHIFT)) & SCT_CTRL_HALT_L_MASK) +#define SCT_CTRL_CLRCTR_L_MASK (0x8U) +#define SCT_CTRL_CLRCTR_L_SHIFT (3U) +#define SCT_CTRL_CLRCTR_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_CTRL_CLRCTR_L_SHIFT)) & SCT_CTRL_CLRCTR_L_MASK) +#define SCT_CTRL_BIDIR_L_MASK (0x10U) +#define SCT_CTRL_BIDIR_L_SHIFT (4U) +#define SCT_CTRL_BIDIR_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_CTRL_BIDIR_L_SHIFT)) & SCT_CTRL_BIDIR_L_MASK) +#define SCT_CTRL_PRE_L_MASK (0x1FE0U) +#define SCT_CTRL_PRE_L_SHIFT (5U) +#define SCT_CTRL_PRE_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_CTRL_PRE_L_SHIFT)) & SCT_CTRL_PRE_L_MASK) +#define SCT_CTRL_DOWN_H_MASK (0x10000U) +#define SCT_CTRL_DOWN_H_SHIFT (16U) +#define SCT_CTRL_DOWN_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_CTRL_DOWN_H_SHIFT)) & SCT_CTRL_DOWN_H_MASK) +#define SCT_CTRL_STOP_H_MASK (0x20000U) +#define SCT_CTRL_STOP_H_SHIFT (17U) +#define SCT_CTRL_STOP_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_CTRL_STOP_H_SHIFT)) & SCT_CTRL_STOP_H_MASK) +#define SCT_CTRL_HALT_H_MASK (0x40000U) +#define SCT_CTRL_HALT_H_SHIFT (18U) +#define SCT_CTRL_HALT_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_CTRL_HALT_H_SHIFT)) & SCT_CTRL_HALT_H_MASK) +#define SCT_CTRL_CLRCTR_H_MASK (0x80000U) +#define SCT_CTRL_CLRCTR_H_SHIFT (19U) +#define SCT_CTRL_CLRCTR_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_CTRL_CLRCTR_H_SHIFT)) & SCT_CTRL_CLRCTR_H_MASK) +#define SCT_CTRL_BIDIR_H_MASK (0x100000U) +#define SCT_CTRL_BIDIR_H_SHIFT (20U) +#define SCT_CTRL_BIDIR_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_CTRL_BIDIR_H_SHIFT)) & SCT_CTRL_BIDIR_H_MASK) +#define SCT_CTRL_PRE_H_MASK (0x1FE00000U) +#define SCT_CTRL_PRE_H_SHIFT (21U) +#define SCT_CTRL_PRE_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_CTRL_PRE_H_SHIFT)) & SCT_CTRL_PRE_H_MASK) + +/*! @name LIMIT - SCT limit event select register */ +#define SCT_LIMIT_LIMMSK_L_MASK (0xFFFFU) +#define SCT_LIMIT_LIMMSK_L_SHIFT (0U) +#define SCT_LIMIT_LIMMSK_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_LIMIT_LIMMSK_L_SHIFT)) & SCT_LIMIT_LIMMSK_L_MASK) +#define SCT_LIMIT_LIMMSK_H_MASK (0xFFFF0000U) +#define SCT_LIMIT_LIMMSK_H_SHIFT (16U) +#define SCT_LIMIT_LIMMSK_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_LIMIT_LIMMSK_H_SHIFT)) & SCT_LIMIT_LIMMSK_H_MASK) + +/*! @name HALT - SCT halt event select register */ +#define SCT_HALT_HALTMSK_L_MASK (0xFFFFU) +#define SCT_HALT_HALTMSK_L_SHIFT (0U) +#define SCT_HALT_HALTMSK_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_HALT_HALTMSK_L_SHIFT)) & SCT_HALT_HALTMSK_L_MASK) +#define SCT_HALT_HALTMSK_H_MASK (0xFFFF0000U) +#define SCT_HALT_HALTMSK_H_SHIFT (16U) +#define SCT_HALT_HALTMSK_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_HALT_HALTMSK_H_SHIFT)) & SCT_HALT_HALTMSK_H_MASK) + +/*! @name STOP - SCT stop event select register */ +#define SCT_STOP_STOPMSK_L_MASK (0xFFFFU) +#define SCT_STOP_STOPMSK_L_SHIFT (0U) +#define SCT_STOP_STOPMSK_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_STOP_STOPMSK_L_SHIFT)) & SCT_STOP_STOPMSK_L_MASK) +#define SCT_STOP_STOPMSK_H_MASK (0xFFFF0000U) +#define SCT_STOP_STOPMSK_H_SHIFT (16U) +#define SCT_STOP_STOPMSK_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_STOP_STOPMSK_H_SHIFT)) & SCT_STOP_STOPMSK_H_MASK) + +/*! @name START - SCT start event select register */ +#define SCT_START_STARTMSK_L_MASK (0xFFFFU) +#define SCT_START_STARTMSK_L_SHIFT (0U) +#define SCT_START_STARTMSK_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_START_STARTMSK_L_SHIFT)) & SCT_START_STARTMSK_L_MASK) +#define SCT_START_STARTMSK_H_MASK (0xFFFF0000U) +#define SCT_START_STARTMSK_H_SHIFT (16U) +#define SCT_START_STARTMSK_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_START_STARTMSK_H_SHIFT)) & SCT_START_STARTMSK_H_MASK) + +/*! @name COUNT - SCT counter register */ +#define SCT_COUNT_CTR_L_MASK (0xFFFFU) +#define SCT_COUNT_CTR_L_SHIFT (0U) +#define SCT_COUNT_CTR_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_COUNT_CTR_L_SHIFT)) & SCT_COUNT_CTR_L_MASK) +#define SCT_COUNT_CTR_H_MASK (0xFFFF0000U) +#define SCT_COUNT_CTR_H_SHIFT (16U) +#define SCT_COUNT_CTR_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_COUNT_CTR_H_SHIFT)) & SCT_COUNT_CTR_H_MASK) + +/*! @name STATE - SCT state register */ +#define SCT_STATE_STATE_L_MASK (0x1FU) +#define SCT_STATE_STATE_L_SHIFT (0U) +#define SCT_STATE_STATE_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_STATE_STATE_L_SHIFT)) & SCT_STATE_STATE_L_MASK) +#define SCT_STATE_STATE_H_MASK (0x1F0000U) +#define SCT_STATE_STATE_H_SHIFT (16U) +#define SCT_STATE_STATE_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_STATE_STATE_H_SHIFT)) & SCT_STATE_STATE_H_MASK) + +/*! @name INPUT - SCT input register */ +#define SCT_INPUT_AIN0_MASK (0x1U) +#define SCT_INPUT_AIN0_SHIFT (0U) +#define SCT_INPUT_AIN0(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_AIN0_SHIFT)) & SCT_INPUT_AIN0_MASK) +#define SCT_INPUT_AIN1_MASK (0x2U) +#define SCT_INPUT_AIN1_SHIFT (1U) +#define SCT_INPUT_AIN1(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_AIN1_SHIFT)) & SCT_INPUT_AIN1_MASK) +#define SCT_INPUT_AIN2_MASK (0x4U) +#define SCT_INPUT_AIN2_SHIFT (2U) +#define SCT_INPUT_AIN2(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_AIN2_SHIFT)) & SCT_INPUT_AIN2_MASK) +#define SCT_INPUT_AIN3_MASK (0x8U) +#define SCT_INPUT_AIN3_SHIFT (3U) +#define SCT_INPUT_AIN3(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_AIN3_SHIFT)) & SCT_INPUT_AIN3_MASK) +#define SCT_INPUT_AIN4_MASK (0x10U) +#define SCT_INPUT_AIN4_SHIFT (4U) +#define SCT_INPUT_AIN4(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_AIN4_SHIFT)) & SCT_INPUT_AIN4_MASK) +#define SCT_INPUT_AIN5_MASK (0x20U) +#define SCT_INPUT_AIN5_SHIFT (5U) +#define SCT_INPUT_AIN5(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_AIN5_SHIFT)) & SCT_INPUT_AIN5_MASK) +#define SCT_INPUT_AIN6_MASK (0x40U) +#define SCT_INPUT_AIN6_SHIFT (6U) +#define SCT_INPUT_AIN6(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_AIN6_SHIFT)) & SCT_INPUT_AIN6_MASK) +#define SCT_INPUT_AIN7_MASK (0x80U) +#define SCT_INPUT_AIN7_SHIFT (7U) +#define SCT_INPUT_AIN7(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_AIN7_SHIFT)) & SCT_INPUT_AIN7_MASK) +#define SCT_INPUT_AIN8_MASK (0x100U) +#define SCT_INPUT_AIN8_SHIFT (8U) +#define SCT_INPUT_AIN8(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_AIN8_SHIFT)) & SCT_INPUT_AIN8_MASK) +#define SCT_INPUT_AIN9_MASK (0x200U) +#define SCT_INPUT_AIN9_SHIFT (9U) +#define SCT_INPUT_AIN9(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_AIN9_SHIFT)) & SCT_INPUT_AIN9_MASK) +#define SCT_INPUT_AIN10_MASK (0x400U) +#define SCT_INPUT_AIN10_SHIFT (10U) +#define SCT_INPUT_AIN10(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_AIN10_SHIFT)) & SCT_INPUT_AIN10_MASK) +#define SCT_INPUT_AIN11_MASK (0x800U) +#define SCT_INPUT_AIN11_SHIFT (11U) +#define SCT_INPUT_AIN11(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_AIN11_SHIFT)) & SCT_INPUT_AIN11_MASK) +#define SCT_INPUT_AIN12_MASK (0x1000U) +#define SCT_INPUT_AIN12_SHIFT (12U) +#define SCT_INPUT_AIN12(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_AIN12_SHIFT)) & SCT_INPUT_AIN12_MASK) +#define SCT_INPUT_AIN13_MASK (0x2000U) +#define SCT_INPUT_AIN13_SHIFT (13U) +#define SCT_INPUT_AIN13(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_AIN13_SHIFT)) & SCT_INPUT_AIN13_MASK) +#define SCT_INPUT_AIN14_MASK (0x4000U) +#define SCT_INPUT_AIN14_SHIFT (14U) +#define SCT_INPUT_AIN14(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_AIN14_SHIFT)) & SCT_INPUT_AIN14_MASK) +#define SCT_INPUT_AIN15_MASK (0x8000U) +#define SCT_INPUT_AIN15_SHIFT (15U) +#define SCT_INPUT_AIN15(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_AIN15_SHIFT)) & SCT_INPUT_AIN15_MASK) +#define SCT_INPUT_SIN0_MASK (0x10000U) +#define SCT_INPUT_SIN0_SHIFT (16U) +#define SCT_INPUT_SIN0(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_SIN0_SHIFT)) & SCT_INPUT_SIN0_MASK) +#define SCT_INPUT_SIN1_MASK (0x20000U) +#define SCT_INPUT_SIN1_SHIFT (17U) +#define SCT_INPUT_SIN1(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_SIN1_SHIFT)) & SCT_INPUT_SIN1_MASK) +#define SCT_INPUT_SIN2_MASK (0x40000U) +#define SCT_INPUT_SIN2_SHIFT (18U) +#define SCT_INPUT_SIN2(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_SIN2_SHIFT)) & SCT_INPUT_SIN2_MASK) +#define SCT_INPUT_SIN3_MASK (0x80000U) +#define SCT_INPUT_SIN3_SHIFT (19U) +#define SCT_INPUT_SIN3(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_SIN3_SHIFT)) & SCT_INPUT_SIN3_MASK) +#define SCT_INPUT_SIN4_MASK (0x100000U) +#define SCT_INPUT_SIN4_SHIFT (20U) +#define SCT_INPUT_SIN4(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_SIN4_SHIFT)) & SCT_INPUT_SIN4_MASK) +#define SCT_INPUT_SIN5_MASK (0x200000U) +#define SCT_INPUT_SIN5_SHIFT (21U) +#define SCT_INPUT_SIN5(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_SIN5_SHIFT)) & SCT_INPUT_SIN5_MASK) +#define SCT_INPUT_SIN6_MASK (0x400000U) +#define SCT_INPUT_SIN6_SHIFT (22U) +#define SCT_INPUT_SIN6(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_SIN6_SHIFT)) & SCT_INPUT_SIN6_MASK) +#define SCT_INPUT_SIN7_MASK (0x800000U) +#define SCT_INPUT_SIN7_SHIFT (23U) +#define SCT_INPUT_SIN7(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_SIN7_SHIFT)) & SCT_INPUT_SIN7_MASK) +#define SCT_INPUT_SIN8_MASK (0x1000000U) +#define SCT_INPUT_SIN8_SHIFT (24U) +#define SCT_INPUT_SIN8(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_SIN8_SHIFT)) & SCT_INPUT_SIN8_MASK) +#define SCT_INPUT_SIN9_MASK (0x2000000U) +#define SCT_INPUT_SIN9_SHIFT (25U) +#define SCT_INPUT_SIN9(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_SIN9_SHIFT)) & SCT_INPUT_SIN9_MASK) +#define SCT_INPUT_SIN10_MASK (0x4000000U) +#define SCT_INPUT_SIN10_SHIFT (26U) +#define SCT_INPUT_SIN10(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_SIN10_SHIFT)) & SCT_INPUT_SIN10_MASK) +#define SCT_INPUT_SIN11_MASK (0x8000000U) +#define SCT_INPUT_SIN11_SHIFT (27U) +#define SCT_INPUT_SIN11(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_SIN11_SHIFT)) & SCT_INPUT_SIN11_MASK) +#define SCT_INPUT_SIN12_MASK (0x10000000U) +#define SCT_INPUT_SIN12_SHIFT (28U) +#define SCT_INPUT_SIN12(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_SIN12_SHIFT)) & SCT_INPUT_SIN12_MASK) +#define SCT_INPUT_SIN13_MASK (0x20000000U) +#define SCT_INPUT_SIN13_SHIFT (29U) +#define SCT_INPUT_SIN13(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_SIN13_SHIFT)) & SCT_INPUT_SIN13_MASK) +#define SCT_INPUT_SIN14_MASK (0x40000000U) +#define SCT_INPUT_SIN14_SHIFT (30U) +#define SCT_INPUT_SIN14(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_SIN14_SHIFT)) & SCT_INPUT_SIN14_MASK) +#define SCT_INPUT_SIN15_MASK (0x80000000U) +#define SCT_INPUT_SIN15_SHIFT (31U) +#define SCT_INPUT_SIN15(x) (((uint32_t)(((uint32_t)(x)) << SCT_INPUT_SIN15_SHIFT)) & SCT_INPUT_SIN15_MASK) + +/*! @name REGMODE - SCT match/capture mode register */ +#define SCT_REGMODE_REGMOD_L_MASK (0xFFFFU) +#define SCT_REGMODE_REGMOD_L_SHIFT (0U) +#define SCT_REGMODE_REGMOD_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_REGMODE_REGMOD_L_SHIFT)) & SCT_REGMODE_REGMOD_L_MASK) +#define SCT_REGMODE_REGMOD_H_MASK (0xFFFF0000U) +#define SCT_REGMODE_REGMOD_H_SHIFT (16U) +#define SCT_REGMODE_REGMOD_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_REGMODE_REGMOD_H_SHIFT)) & SCT_REGMODE_REGMOD_H_MASK) + +/*! @name OUTPUT - SCT output register */ +#define SCT_OUTPUT_OUT_MASK (0xFFFFU) +#define SCT_OUTPUT_OUT_SHIFT (0U) +#define SCT_OUTPUT_OUT(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUT_OUT_SHIFT)) & SCT_OUTPUT_OUT_MASK) + +/*! @name OUTPUTDIRCTRL - SCT output counter direction control register */ +#define SCT_OUTPUTDIRCTRL_SETCLR0_MASK (0x3U) +#define SCT_OUTPUTDIRCTRL_SETCLR0_SHIFT (0U) +#define SCT_OUTPUTDIRCTRL_SETCLR0(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUTDIRCTRL_SETCLR0_SHIFT)) & SCT_OUTPUTDIRCTRL_SETCLR0_MASK) +#define SCT_OUTPUTDIRCTRL_SETCLR1_MASK (0xCU) +#define SCT_OUTPUTDIRCTRL_SETCLR1_SHIFT (2U) +#define SCT_OUTPUTDIRCTRL_SETCLR1(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUTDIRCTRL_SETCLR1_SHIFT)) & SCT_OUTPUTDIRCTRL_SETCLR1_MASK) +#define SCT_OUTPUTDIRCTRL_SETCLR2_MASK (0x30U) +#define SCT_OUTPUTDIRCTRL_SETCLR2_SHIFT (4U) +#define SCT_OUTPUTDIRCTRL_SETCLR2(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUTDIRCTRL_SETCLR2_SHIFT)) & SCT_OUTPUTDIRCTRL_SETCLR2_MASK) +#define SCT_OUTPUTDIRCTRL_SETCLR3_MASK (0xC0U) +#define SCT_OUTPUTDIRCTRL_SETCLR3_SHIFT (6U) +#define SCT_OUTPUTDIRCTRL_SETCLR3(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUTDIRCTRL_SETCLR3_SHIFT)) & SCT_OUTPUTDIRCTRL_SETCLR3_MASK) +#define SCT_OUTPUTDIRCTRL_SETCLR4_MASK (0x300U) +#define SCT_OUTPUTDIRCTRL_SETCLR4_SHIFT (8U) +#define SCT_OUTPUTDIRCTRL_SETCLR4(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUTDIRCTRL_SETCLR4_SHIFT)) & SCT_OUTPUTDIRCTRL_SETCLR4_MASK) +#define SCT_OUTPUTDIRCTRL_SETCLR5_MASK (0xC00U) +#define SCT_OUTPUTDIRCTRL_SETCLR5_SHIFT (10U) +#define SCT_OUTPUTDIRCTRL_SETCLR5(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUTDIRCTRL_SETCLR5_SHIFT)) & SCT_OUTPUTDIRCTRL_SETCLR5_MASK) +#define SCT_OUTPUTDIRCTRL_SETCLR6_MASK (0x3000U) +#define SCT_OUTPUTDIRCTRL_SETCLR6_SHIFT (12U) +#define SCT_OUTPUTDIRCTRL_SETCLR6(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUTDIRCTRL_SETCLR6_SHIFT)) & SCT_OUTPUTDIRCTRL_SETCLR6_MASK) +#define SCT_OUTPUTDIRCTRL_SETCLR7_MASK (0xC000U) +#define SCT_OUTPUTDIRCTRL_SETCLR7_SHIFT (14U) +#define SCT_OUTPUTDIRCTRL_SETCLR7(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUTDIRCTRL_SETCLR7_SHIFT)) & SCT_OUTPUTDIRCTRL_SETCLR7_MASK) +#define SCT_OUTPUTDIRCTRL_SETCLR8_MASK (0x30000U) +#define SCT_OUTPUTDIRCTRL_SETCLR8_SHIFT (16U) +#define SCT_OUTPUTDIRCTRL_SETCLR8(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUTDIRCTRL_SETCLR8_SHIFT)) & SCT_OUTPUTDIRCTRL_SETCLR8_MASK) +#define SCT_OUTPUTDIRCTRL_SETCLR9_MASK (0xC0000U) +#define SCT_OUTPUTDIRCTRL_SETCLR9_SHIFT (18U) +#define SCT_OUTPUTDIRCTRL_SETCLR9(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUTDIRCTRL_SETCLR9_SHIFT)) & SCT_OUTPUTDIRCTRL_SETCLR9_MASK) +#define SCT_OUTPUTDIRCTRL_SETCLR10_MASK (0x300000U) +#define SCT_OUTPUTDIRCTRL_SETCLR10_SHIFT (20U) +#define SCT_OUTPUTDIRCTRL_SETCLR10(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUTDIRCTRL_SETCLR10_SHIFT)) & SCT_OUTPUTDIRCTRL_SETCLR10_MASK) +#define SCT_OUTPUTDIRCTRL_SETCLR11_MASK (0xC00000U) +#define SCT_OUTPUTDIRCTRL_SETCLR11_SHIFT (22U) +#define SCT_OUTPUTDIRCTRL_SETCLR11(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUTDIRCTRL_SETCLR11_SHIFT)) & SCT_OUTPUTDIRCTRL_SETCLR11_MASK) +#define SCT_OUTPUTDIRCTRL_SETCLR12_MASK (0x3000000U) +#define SCT_OUTPUTDIRCTRL_SETCLR12_SHIFT (24U) +#define SCT_OUTPUTDIRCTRL_SETCLR12(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUTDIRCTRL_SETCLR12_SHIFT)) & SCT_OUTPUTDIRCTRL_SETCLR12_MASK) +#define SCT_OUTPUTDIRCTRL_SETCLR13_MASK (0xC000000U) +#define SCT_OUTPUTDIRCTRL_SETCLR13_SHIFT (26U) +#define SCT_OUTPUTDIRCTRL_SETCLR13(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUTDIRCTRL_SETCLR13_SHIFT)) & SCT_OUTPUTDIRCTRL_SETCLR13_MASK) +#define SCT_OUTPUTDIRCTRL_SETCLR14_MASK (0x30000000U) +#define SCT_OUTPUTDIRCTRL_SETCLR14_SHIFT (28U) +#define SCT_OUTPUTDIRCTRL_SETCLR14(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUTDIRCTRL_SETCLR14_SHIFT)) & SCT_OUTPUTDIRCTRL_SETCLR14_MASK) +#define SCT_OUTPUTDIRCTRL_SETCLR15_MASK (0xC0000000U) +#define SCT_OUTPUTDIRCTRL_SETCLR15_SHIFT (30U) +#define SCT_OUTPUTDIRCTRL_SETCLR15(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUTPUTDIRCTRL_SETCLR15_SHIFT)) & SCT_OUTPUTDIRCTRL_SETCLR15_MASK) + +/*! @name RES - SCT conflict resolution register */ +#define SCT_RES_O0RES_MASK (0x3U) +#define SCT_RES_O0RES_SHIFT (0U) +#define SCT_RES_O0RES(x) (((uint32_t)(((uint32_t)(x)) << SCT_RES_O0RES_SHIFT)) & SCT_RES_O0RES_MASK) +#define SCT_RES_O1RES_MASK (0xCU) +#define SCT_RES_O1RES_SHIFT (2U) +#define SCT_RES_O1RES(x) (((uint32_t)(((uint32_t)(x)) << SCT_RES_O1RES_SHIFT)) & SCT_RES_O1RES_MASK) +#define SCT_RES_O2RES_MASK (0x30U) +#define SCT_RES_O2RES_SHIFT (4U) +#define SCT_RES_O2RES(x) (((uint32_t)(((uint32_t)(x)) << SCT_RES_O2RES_SHIFT)) & SCT_RES_O2RES_MASK) +#define SCT_RES_O3RES_MASK (0xC0U) +#define SCT_RES_O3RES_SHIFT (6U) +#define SCT_RES_O3RES(x) (((uint32_t)(((uint32_t)(x)) << SCT_RES_O3RES_SHIFT)) & SCT_RES_O3RES_MASK) +#define SCT_RES_O4RES_MASK (0x300U) +#define SCT_RES_O4RES_SHIFT (8U) +#define SCT_RES_O4RES(x) (((uint32_t)(((uint32_t)(x)) << SCT_RES_O4RES_SHIFT)) & SCT_RES_O4RES_MASK) +#define SCT_RES_O5RES_MASK (0xC00U) +#define SCT_RES_O5RES_SHIFT (10U) +#define SCT_RES_O5RES(x) (((uint32_t)(((uint32_t)(x)) << SCT_RES_O5RES_SHIFT)) & SCT_RES_O5RES_MASK) +#define SCT_RES_O6RES_MASK (0x3000U) +#define SCT_RES_O6RES_SHIFT (12U) +#define SCT_RES_O6RES(x) (((uint32_t)(((uint32_t)(x)) << SCT_RES_O6RES_SHIFT)) & SCT_RES_O6RES_MASK) +#define SCT_RES_O7RES_MASK (0xC000U) +#define SCT_RES_O7RES_SHIFT (14U) +#define SCT_RES_O7RES(x) (((uint32_t)(((uint32_t)(x)) << SCT_RES_O7RES_SHIFT)) & SCT_RES_O7RES_MASK) +#define SCT_RES_O8RES_MASK (0x30000U) +#define SCT_RES_O8RES_SHIFT (16U) +#define SCT_RES_O8RES(x) (((uint32_t)(((uint32_t)(x)) << SCT_RES_O8RES_SHIFT)) & SCT_RES_O8RES_MASK) +#define SCT_RES_O9RES_MASK (0xC0000U) +#define SCT_RES_O9RES_SHIFT (18U) +#define SCT_RES_O9RES(x) (((uint32_t)(((uint32_t)(x)) << SCT_RES_O9RES_SHIFT)) & SCT_RES_O9RES_MASK) +#define SCT_RES_O10RES_MASK (0x300000U) +#define SCT_RES_O10RES_SHIFT (20U) +#define SCT_RES_O10RES(x) (((uint32_t)(((uint32_t)(x)) << SCT_RES_O10RES_SHIFT)) & SCT_RES_O10RES_MASK) +#define SCT_RES_O11RES_MASK (0xC00000U) +#define SCT_RES_O11RES_SHIFT (22U) +#define SCT_RES_O11RES(x) (((uint32_t)(((uint32_t)(x)) << SCT_RES_O11RES_SHIFT)) & SCT_RES_O11RES_MASK) +#define SCT_RES_O12RES_MASK (0x3000000U) +#define SCT_RES_O12RES_SHIFT (24U) +#define SCT_RES_O12RES(x) (((uint32_t)(((uint32_t)(x)) << SCT_RES_O12RES_SHIFT)) & SCT_RES_O12RES_MASK) +#define SCT_RES_O13RES_MASK (0xC000000U) +#define SCT_RES_O13RES_SHIFT (26U) +#define SCT_RES_O13RES(x) (((uint32_t)(((uint32_t)(x)) << SCT_RES_O13RES_SHIFT)) & SCT_RES_O13RES_MASK) +#define SCT_RES_O14RES_MASK (0x30000000U) +#define SCT_RES_O14RES_SHIFT (28U) +#define SCT_RES_O14RES(x) (((uint32_t)(((uint32_t)(x)) << SCT_RES_O14RES_SHIFT)) & SCT_RES_O14RES_MASK) +#define SCT_RES_O15RES_MASK (0xC0000000U) +#define SCT_RES_O15RES_SHIFT (30U) +#define SCT_RES_O15RES(x) (((uint32_t)(((uint32_t)(x)) << SCT_RES_O15RES_SHIFT)) & SCT_RES_O15RES_MASK) + +/*! @name DMA0REQUEST - SCT DMA request 0 register */ +#define SCT_DMA0REQUEST_DEV_0_MASK (0xFFFFU) +#define SCT_DMA0REQUEST_DEV_0_SHIFT (0U) +#define SCT_DMA0REQUEST_DEV_0(x) (((uint32_t)(((uint32_t)(x)) << SCT_DMA0REQUEST_DEV_0_SHIFT)) & SCT_DMA0REQUEST_DEV_0_MASK) +#define SCT_DMA0REQUEST_DRL0_MASK (0x40000000U) +#define SCT_DMA0REQUEST_DRL0_SHIFT (30U) +#define SCT_DMA0REQUEST_DRL0(x) (((uint32_t)(((uint32_t)(x)) << SCT_DMA0REQUEST_DRL0_SHIFT)) & SCT_DMA0REQUEST_DRL0_MASK) +#define SCT_DMA0REQUEST_DRQ0_MASK (0x80000000U) +#define SCT_DMA0REQUEST_DRQ0_SHIFT (31U) +#define SCT_DMA0REQUEST_DRQ0(x) (((uint32_t)(((uint32_t)(x)) << SCT_DMA0REQUEST_DRQ0_SHIFT)) & SCT_DMA0REQUEST_DRQ0_MASK) + +/*! @name DMA1REQUEST - SCT DMA request 1 register */ +#define SCT_DMA1REQUEST_DEV_1_MASK (0xFFFFU) +#define SCT_DMA1REQUEST_DEV_1_SHIFT (0U) +#define SCT_DMA1REQUEST_DEV_1(x) (((uint32_t)(((uint32_t)(x)) << SCT_DMA1REQUEST_DEV_1_SHIFT)) & SCT_DMA1REQUEST_DEV_1_MASK) +#define SCT_DMA1REQUEST_DRL1_MASK (0x40000000U) +#define SCT_DMA1REQUEST_DRL1_SHIFT (30U) +#define SCT_DMA1REQUEST_DRL1(x) (((uint32_t)(((uint32_t)(x)) << SCT_DMA1REQUEST_DRL1_SHIFT)) & SCT_DMA1REQUEST_DRL1_MASK) +#define SCT_DMA1REQUEST_DRQ1_MASK (0x80000000U) +#define SCT_DMA1REQUEST_DRQ1_SHIFT (31U) +#define SCT_DMA1REQUEST_DRQ1(x) (((uint32_t)(((uint32_t)(x)) << SCT_DMA1REQUEST_DRQ1_SHIFT)) & SCT_DMA1REQUEST_DRQ1_MASK) + +/*! @name EVEN - SCT event interrupt enable register */ +#define SCT_EVEN_IEN_MASK (0xFFFFU) +#define SCT_EVEN_IEN_SHIFT (0U) +#define SCT_EVEN_IEN(x) (((uint32_t)(((uint32_t)(x)) << SCT_EVEN_IEN_SHIFT)) & SCT_EVEN_IEN_MASK) + +/*! @name EVFLAG - SCT event flag register */ +#define SCT_EVFLAG_FLAG_MASK (0xFFFFU) +#define SCT_EVFLAG_FLAG_SHIFT (0U) +#define SCT_EVFLAG_FLAG(x) (((uint32_t)(((uint32_t)(x)) << SCT_EVFLAG_FLAG_SHIFT)) & SCT_EVFLAG_FLAG_MASK) + +/*! @name CONEN - SCT conflict interrupt enable register */ +#define SCT_CONEN_NCEN_MASK (0xFFFFU) +#define SCT_CONEN_NCEN_SHIFT (0U) +#define SCT_CONEN_NCEN(x) (((uint32_t)(((uint32_t)(x)) << SCT_CONEN_NCEN_SHIFT)) & SCT_CONEN_NCEN_MASK) + +/*! @name CONFLAG - SCT conflict flag register */ +#define SCT_CONFLAG_NCFLAG_MASK (0xFFFFU) +#define SCT_CONFLAG_NCFLAG_SHIFT (0U) +#define SCT_CONFLAG_NCFLAG(x) (((uint32_t)(((uint32_t)(x)) << SCT_CONFLAG_NCFLAG_SHIFT)) & SCT_CONFLAG_NCFLAG_MASK) +#define SCT_CONFLAG_BUSERRL_MASK (0x40000000U) +#define SCT_CONFLAG_BUSERRL_SHIFT (30U) +#define SCT_CONFLAG_BUSERRL(x) (((uint32_t)(((uint32_t)(x)) << SCT_CONFLAG_BUSERRL_SHIFT)) & SCT_CONFLAG_BUSERRL_MASK) +#define SCT_CONFLAG_BUSERRH_MASK (0x80000000U) +#define SCT_CONFLAG_BUSERRH_SHIFT (31U) +#define SCT_CONFLAG_BUSERRH(x) (((uint32_t)(((uint32_t)(x)) << SCT_CONFLAG_BUSERRH_SHIFT)) & SCT_CONFLAG_BUSERRH_MASK) + +/*! @name SCTCAP - SCT capture register of capture channel */ +#define SCT_SCTCAP_CAPn_L_MASK (0xFFFFU) +#define SCT_SCTCAP_CAPn_L_SHIFT (0U) +#define SCT_SCTCAP_CAPn_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_SCTCAP_CAPn_L_SHIFT)) & SCT_SCTCAP_CAPn_L_MASK) +#define SCT_SCTCAP_CAPn_H_MASK (0xFFFF0000U) +#define SCT_SCTCAP_CAPn_H_SHIFT (16U) +#define SCT_SCTCAP_CAPn_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_SCTCAP_CAPn_H_SHIFT)) & SCT_SCTCAP_CAPn_H_MASK) + +/* The count of SCT_SCTCAP */ +#define SCT_SCTCAP_COUNT (13U) + +/*! @name SCTMATCH - SCT match value register of match channels */ +#define SCT_SCTMATCH_MATCHn_L_MASK (0xFFFFU) +#define SCT_SCTMATCH_MATCHn_L_SHIFT (0U) +#define SCT_SCTMATCH_MATCHn_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_SCTMATCH_MATCHn_L_SHIFT)) & SCT_SCTMATCH_MATCHn_L_MASK) +#define SCT_SCTMATCH_MATCHn_H_MASK (0xFFFF0000U) +#define SCT_SCTMATCH_MATCHn_H_SHIFT (16U) +#define SCT_SCTMATCH_MATCHn_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_SCTMATCH_MATCHn_H_SHIFT)) & SCT_SCTMATCH_MATCHn_H_MASK) + +/* The count of SCT_SCTMATCH */ +#define SCT_SCTMATCH_COUNT (13U) + +/*! @name SCTCAPCTRL - SCT capture control register */ +#define SCT_SCTCAPCTRL_CAPCONn_L_MASK (0xFFFFU) +#define SCT_SCTCAPCTRL_CAPCONn_L_SHIFT (0U) +#define SCT_SCTCAPCTRL_CAPCONn_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_SCTCAPCTRL_CAPCONn_L_SHIFT)) & SCT_SCTCAPCTRL_CAPCONn_L_MASK) +#define SCT_SCTCAPCTRL_CAPCONn_H_MASK (0xFFFF0000U) +#define SCT_SCTCAPCTRL_CAPCONn_H_SHIFT (16U) +#define SCT_SCTCAPCTRL_CAPCONn_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_SCTCAPCTRL_CAPCONn_H_SHIFT)) & SCT_SCTCAPCTRL_CAPCONn_H_MASK) + +/* The count of SCT_SCTCAPCTRL */ +#define SCT_SCTCAPCTRL_COUNT (13U) + +/*! @name SCTMATCHREL - SCT match reload value register */ +#define SCT_SCTMATCHREL_RELOADn_L_MASK (0xFFFFU) +#define SCT_SCTMATCHREL_RELOADn_L_SHIFT (0U) +#define SCT_SCTMATCHREL_RELOADn_L(x) (((uint32_t)(((uint32_t)(x)) << SCT_SCTMATCHREL_RELOADn_L_SHIFT)) & SCT_SCTMATCHREL_RELOADn_L_MASK) +#define SCT_SCTMATCHREL_RELOADn_H_MASK (0xFFFF0000U) +#define SCT_SCTMATCHREL_RELOADn_H_SHIFT (16U) +#define SCT_SCTMATCHREL_RELOADn_H(x) (((uint32_t)(((uint32_t)(x)) << SCT_SCTMATCHREL_RELOADn_H_SHIFT)) & SCT_SCTMATCHREL_RELOADn_H_MASK) + +/* The count of SCT_SCTMATCHREL */ +#define SCT_SCTMATCHREL_COUNT (13U) + +/*! @name EVENT_STATE - SCT event state register 0 */ +#define SCT_EVENT_STATE_STATEMSKn_MASK (0xFFFFU) +#define SCT_EVENT_STATE_STATEMSKn_SHIFT (0U) +#define SCT_EVENT_STATE_STATEMSKn(x) (((uint32_t)(((uint32_t)(x)) << SCT_EVENT_STATE_STATEMSKn_SHIFT)) & SCT_EVENT_STATE_STATEMSKn_MASK) + +/* The count of SCT_EVENT_STATE */ +#define SCT_EVENT_STATE_COUNT (13U) + +/*! @name EVENT_CTRL - SCT event control register 0 */ +#define SCT_EVENT_CTRL_MATCHSEL_MASK (0xFU) +#define SCT_EVENT_CTRL_MATCHSEL_SHIFT (0U) +#define SCT_EVENT_CTRL_MATCHSEL(x) (((uint32_t)(((uint32_t)(x)) << SCT_EVENT_CTRL_MATCHSEL_SHIFT)) & SCT_EVENT_CTRL_MATCHSEL_MASK) +#define SCT_EVENT_CTRL_HEVENT_MASK (0x10U) +#define SCT_EVENT_CTRL_HEVENT_SHIFT (4U) +#define SCT_EVENT_CTRL_HEVENT(x) (((uint32_t)(((uint32_t)(x)) << SCT_EVENT_CTRL_HEVENT_SHIFT)) & SCT_EVENT_CTRL_HEVENT_MASK) +#define SCT_EVENT_CTRL_OUTSEL_MASK (0x20U) +#define SCT_EVENT_CTRL_OUTSEL_SHIFT (5U) +#define SCT_EVENT_CTRL_OUTSEL(x) (((uint32_t)(((uint32_t)(x)) << SCT_EVENT_CTRL_OUTSEL_SHIFT)) & SCT_EVENT_CTRL_OUTSEL_MASK) +#define SCT_EVENT_CTRL_IOSEL_MASK (0x3C0U) +#define SCT_EVENT_CTRL_IOSEL_SHIFT (6U) +#define SCT_EVENT_CTRL_IOSEL(x) (((uint32_t)(((uint32_t)(x)) << SCT_EVENT_CTRL_IOSEL_SHIFT)) & SCT_EVENT_CTRL_IOSEL_MASK) +#define SCT_EVENT_CTRL_IOCOND_MASK (0xC00U) +#define SCT_EVENT_CTRL_IOCOND_SHIFT (10U) +#define SCT_EVENT_CTRL_IOCOND(x) (((uint32_t)(((uint32_t)(x)) << SCT_EVENT_CTRL_IOCOND_SHIFT)) & SCT_EVENT_CTRL_IOCOND_MASK) +#define SCT_EVENT_CTRL_COMBMODE_MASK (0x3000U) +#define SCT_EVENT_CTRL_COMBMODE_SHIFT (12U) +#define SCT_EVENT_CTRL_COMBMODE(x) (((uint32_t)(((uint32_t)(x)) << SCT_EVENT_CTRL_COMBMODE_SHIFT)) & SCT_EVENT_CTRL_COMBMODE_MASK) +#define SCT_EVENT_CTRL_STATELD_MASK (0x4000U) +#define SCT_EVENT_CTRL_STATELD_SHIFT (14U) +#define SCT_EVENT_CTRL_STATELD(x) (((uint32_t)(((uint32_t)(x)) << SCT_EVENT_CTRL_STATELD_SHIFT)) & SCT_EVENT_CTRL_STATELD_MASK) +#define SCT_EVENT_CTRL_STATEV_MASK (0xF8000U) +#define SCT_EVENT_CTRL_STATEV_SHIFT (15U) +#define SCT_EVENT_CTRL_STATEV(x) (((uint32_t)(((uint32_t)(x)) << SCT_EVENT_CTRL_STATEV_SHIFT)) & SCT_EVENT_CTRL_STATEV_MASK) +#define SCT_EVENT_CTRL_MATCHMEM_MASK (0x100000U) +#define SCT_EVENT_CTRL_MATCHMEM_SHIFT (20U) +#define SCT_EVENT_CTRL_MATCHMEM(x) (((uint32_t)(((uint32_t)(x)) << SCT_EVENT_CTRL_MATCHMEM_SHIFT)) & SCT_EVENT_CTRL_MATCHMEM_MASK) +#define SCT_EVENT_CTRL_DIRECTION_MASK (0x600000U) +#define SCT_EVENT_CTRL_DIRECTION_SHIFT (21U) +#define SCT_EVENT_CTRL_DIRECTION(x) (((uint32_t)(((uint32_t)(x)) << SCT_EVENT_CTRL_DIRECTION_SHIFT)) & SCT_EVENT_CTRL_DIRECTION_MASK) + +/* The count of SCT_EVENT_CTRL */ +#define SCT_EVENT_CTRL_COUNT (13U) + +/*! @name OUT_SET - SCT output 0 set register */ +#define SCT_OUT_SET_SET_MASK (0xFFFFU) +#define SCT_OUT_SET_SET_SHIFT (0U) +#define SCT_OUT_SET_SET(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUT_SET_SET_SHIFT)) & SCT_OUT_SET_SET_MASK) + +/* The count of SCT_OUT_SET */ +#define SCT_OUT_SET_COUNT (8U) + +/*! @name OUT_CLR - SCT output 0 clear register */ +#define SCT_OUT_CLR_CLR_MASK (0xFFFFU) +#define SCT_OUT_CLR_CLR_SHIFT (0U) +#define SCT_OUT_CLR_CLR(x) (((uint32_t)(((uint32_t)(x)) << SCT_OUT_CLR_CLR_SHIFT)) & SCT_OUT_CLR_CLR_MASK) + +/* The count of SCT_OUT_CLR */ +#define SCT_OUT_CLR_COUNT (8U) + + +/*! + * @} + */ /* end of group SCT_Register_Masks */ + + +/* SCT - Peripheral instance base addresses */ +/** Peripheral SCT0 base address */ +#define SCT0_BASE (0x1C018000u) +/** Peripheral SCT0 base pointer */ +#define SCT0 ((SCT_Type *)SCT0_BASE) +/** Array initializer of SCT peripheral base addresses */ +#define SCT_BASE_ADDRS { SCT0_BASE } +/** Array initializer of SCT peripheral base pointers */ +#define SCT_BASE_PTRS { SCT0 } +/** Interrupt vectors for the SCT peripheral type */ +#define SCT_IRQS { SCT0_IRQn } + +/*! + * @} + */ /* end of group SCT_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- SPI Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SPI_Peripheral_Access_Layer SPI Peripheral Access Layer + * @{ + */ + +/** SPI - Register Layout Typedef */ +typedef struct { + __IO uint32_t CFG; /**< SPI Configuration register, offset: 0x0 */ + __IO uint32_t DLY; /**< SPI Delay register, offset: 0x4 */ + __IO uint32_t STAT; /**< SPI Status. Some status flags can be cleared by writing a 1 to that bit position, offset: 0x8 */ + __IO uint32_t INTENSET; /**< SPI Interrupt Enable read and Set. A complete value may be read from this register. Writing a 1 to any implemented bit position causes that bit to be set., offset: 0xC */ + __IO uint32_t INTENCLR; /**< SPI Interrupt Enable Clear. Writing a 1 to any implemented bit position causes the corresponding bit in INTENSET to be cleared., offset: 0x10 */ + __IO uint32_t RXDAT; /**< SPI Receive Data, offset: 0x14 */ + __IO uint32_t TXDATCTL; /**< SPI Transmit Data with Control, offset: 0x18 */ + __IO uint32_t TXDAT; /**< SPI Transmit Data, offset: 0x1C */ + __IO uint32_t TXCTL; /**< SPI Transmit Control, offset: 0x20 */ + __IO uint32_t DIV; /**< SPI clock Divider, offset: 0x24 */ + __IO uint32_t INTSTAT; /**< SPI Interrupt Status, offset: 0x28 */ +} SPI_Type; + +/* ---------------------------------------------------------------------------- + -- SPI Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SPI_Register_Masks SPI Register Masks + * @{ + */ + +/*! @name CFG - SPI Configuration register */ +#define SPI_CFG_ENABLE_MASK (0x1U) +#define SPI_CFG_ENABLE_SHIFT (0U) +#define SPI_CFG_ENABLE(x) (((uint32_t)(((uint32_t)(x)) << SPI_CFG_ENABLE_SHIFT)) & SPI_CFG_ENABLE_MASK) +#define SPI_CFG_MASTER_MASK (0x4U) +#define SPI_CFG_MASTER_SHIFT (2U) +#define SPI_CFG_MASTER(x) (((uint32_t)(((uint32_t)(x)) << SPI_CFG_MASTER_SHIFT)) & SPI_CFG_MASTER_MASK) +#define SPI_CFG_LSBF_MASK (0x8U) +#define SPI_CFG_LSBF_SHIFT (3U) +#define SPI_CFG_LSBF(x) (((uint32_t)(((uint32_t)(x)) << SPI_CFG_LSBF_SHIFT)) & SPI_CFG_LSBF_MASK) +#define SPI_CFG_CPHA_MASK (0x10U) +#define SPI_CFG_CPHA_SHIFT (4U) +#define SPI_CFG_CPHA(x) (((uint32_t)(((uint32_t)(x)) << SPI_CFG_CPHA_SHIFT)) & SPI_CFG_CPHA_MASK) +#define SPI_CFG_CPOL_MASK (0x20U) +#define SPI_CFG_CPOL_SHIFT (5U) +#define SPI_CFG_CPOL(x) (((uint32_t)(((uint32_t)(x)) << SPI_CFG_CPOL_SHIFT)) & SPI_CFG_CPOL_MASK) +#define SPI_CFG_LOOP_MASK (0x80U) +#define SPI_CFG_LOOP_SHIFT (7U) +#define SPI_CFG_LOOP(x) (((uint32_t)(((uint32_t)(x)) << SPI_CFG_LOOP_SHIFT)) & SPI_CFG_LOOP_MASK) +#define SPI_CFG_SPOL0_MASK (0x100U) +#define SPI_CFG_SPOL0_SHIFT (8U) +#define SPI_CFG_SPOL0(x) (((uint32_t)(((uint32_t)(x)) << SPI_CFG_SPOL0_SHIFT)) & SPI_CFG_SPOL0_MASK) +#define SPI_CFG_SPOL1_MASK (0x200U) +#define SPI_CFG_SPOL1_SHIFT (9U) +#define SPI_CFG_SPOL1(x) (((uint32_t)(((uint32_t)(x)) << SPI_CFG_SPOL1_SHIFT)) & SPI_CFG_SPOL1_MASK) +#define SPI_CFG_SPOL2_MASK (0x400U) +#define SPI_CFG_SPOL2_SHIFT (10U) +#define SPI_CFG_SPOL2(x) (((uint32_t)(((uint32_t)(x)) << SPI_CFG_SPOL2_SHIFT)) & SPI_CFG_SPOL2_MASK) +#define SPI_CFG_SPOL3_MASK (0x800U) +#define SPI_CFG_SPOL3_SHIFT (11U) +#define SPI_CFG_SPOL3(x) (((uint32_t)(((uint32_t)(x)) << SPI_CFG_SPOL3_SHIFT)) & SPI_CFG_SPOL3_MASK) + +/*! @name DLY - SPI Delay register */ +#define SPI_DLY_PRE_DELAY_MASK (0xFU) +#define SPI_DLY_PRE_DELAY_SHIFT (0U) +#define SPI_DLY_PRE_DELAY(x) (((uint32_t)(((uint32_t)(x)) << SPI_DLY_PRE_DELAY_SHIFT)) & SPI_DLY_PRE_DELAY_MASK) +#define SPI_DLY_POST_DELAY_MASK (0xF0U) +#define SPI_DLY_POST_DELAY_SHIFT (4U) +#define SPI_DLY_POST_DELAY(x) (((uint32_t)(((uint32_t)(x)) << SPI_DLY_POST_DELAY_SHIFT)) & SPI_DLY_POST_DELAY_MASK) +#define SPI_DLY_FRAME_DELAY_MASK (0xF00U) +#define SPI_DLY_FRAME_DELAY_SHIFT (8U) +#define SPI_DLY_FRAME_DELAY(x) (((uint32_t)(((uint32_t)(x)) << SPI_DLY_FRAME_DELAY_SHIFT)) & SPI_DLY_FRAME_DELAY_MASK) +#define SPI_DLY_TRANSFER_DELAY_MASK (0xF000U) +#define SPI_DLY_TRANSFER_DELAY_SHIFT (12U) +#define SPI_DLY_TRANSFER_DELAY(x) (((uint32_t)(((uint32_t)(x)) << SPI_DLY_TRANSFER_DELAY_SHIFT)) & SPI_DLY_TRANSFER_DELAY_MASK) + +/*! @name STAT - SPI Status. Some status flags can be cleared by writing a 1 to that bit position */ +#define SPI_STAT_RXRDY_MASK (0x1U) +#define SPI_STAT_RXRDY_SHIFT (0U) +#define SPI_STAT_RXRDY(x) (((uint32_t)(((uint32_t)(x)) << SPI_STAT_RXRDY_SHIFT)) & SPI_STAT_RXRDY_MASK) +#define SPI_STAT_TXRDY_MASK (0x2U) +#define SPI_STAT_TXRDY_SHIFT (1U) +#define SPI_STAT_TXRDY(x) (((uint32_t)(((uint32_t)(x)) << SPI_STAT_TXRDY_SHIFT)) & SPI_STAT_TXRDY_MASK) +#define SPI_STAT_RXOV_MASK (0x4U) +#define SPI_STAT_RXOV_SHIFT (2U) +#define SPI_STAT_RXOV(x) (((uint32_t)(((uint32_t)(x)) << SPI_STAT_RXOV_SHIFT)) & SPI_STAT_RXOV_MASK) +#define SPI_STAT_TXUR_MASK (0x8U) +#define SPI_STAT_TXUR_SHIFT (3U) +#define SPI_STAT_TXUR(x) (((uint32_t)(((uint32_t)(x)) << SPI_STAT_TXUR_SHIFT)) & SPI_STAT_TXUR_MASK) +#define SPI_STAT_SSA_MASK (0x10U) +#define SPI_STAT_SSA_SHIFT (4U) +#define SPI_STAT_SSA(x) (((uint32_t)(((uint32_t)(x)) << SPI_STAT_SSA_SHIFT)) & SPI_STAT_SSA_MASK) +#define SPI_STAT_SSD_MASK (0x20U) +#define SPI_STAT_SSD_SHIFT (5U) +#define SPI_STAT_SSD(x) (((uint32_t)(((uint32_t)(x)) << SPI_STAT_SSD_SHIFT)) & SPI_STAT_SSD_MASK) +#define SPI_STAT_STALLED_MASK (0x40U) +#define SPI_STAT_STALLED_SHIFT (6U) +#define SPI_STAT_STALLED(x) (((uint32_t)(((uint32_t)(x)) << SPI_STAT_STALLED_SHIFT)) & SPI_STAT_STALLED_MASK) +#define SPI_STAT_ENDTRANSFER_MASK (0x80U) +#define SPI_STAT_ENDTRANSFER_SHIFT (7U) +#define SPI_STAT_ENDTRANSFER(x) (((uint32_t)(((uint32_t)(x)) << SPI_STAT_ENDTRANSFER_SHIFT)) & SPI_STAT_ENDTRANSFER_MASK) +#define SPI_STAT_MSTIDLE_MASK (0x100U) +#define SPI_STAT_MSTIDLE_SHIFT (8U) +#define SPI_STAT_MSTIDLE(x) (((uint32_t)(((uint32_t)(x)) << SPI_STAT_MSTIDLE_SHIFT)) & SPI_STAT_MSTIDLE_MASK) + +/*! @name INTENSET - SPI Interrupt Enable read and Set. A complete value may be read from this register. Writing a 1 to any implemented bit position causes that bit to be set. */ +#define SPI_INTENSET_RXRDYEN_MASK (0x1U) +#define SPI_INTENSET_RXRDYEN_SHIFT (0U) +#define SPI_INTENSET_RXRDYEN(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTENSET_RXRDYEN_SHIFT)) & SPI_INTENSET_RXRDYEN_MASK) +#define SPI_INTENSET_TXRDYEN_MASK (0x2U) +#define SPI_INTENSET_TXRDYEN_SHIFT (1U) +#define SPI_INTENSET_TXRDYEN(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTENSET_TXRDYEN_SHIFT)) & SPI_INTENSET_TXRDYEN_MASK) +#define SPI_INTENSET_RXOVEN_MASK (0x4U) +#define SPI_INTENSET_RXOVEN_SHIFT (2U) +#define SPI_INTENSET_RXOVEN(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTENSET_RXOVEN_SHIFT)) & SPI_INTENSET_RXOVEN_MASK) +#define SPI_INTENSET_TXUREN_MASK (0x8U) +#define SPI_INTENSET_TXUREN_SHIFT (3U) +#define SPI_INTENSET_TXUREN(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTENSET_TXUREN_SHIFT)) & SPI_INTENSET_TXUREN_MASK) +#define SPI_INTENSET_SSAEN_MASK (0x10U) +#define SPI_INTENSET_SSAEN_SHIFT (4U) +#define SPI_INTENSET_SSAEN(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTENSET_SSAEN_SHIFT)) & SPI_INTENSET_SSAEN_MASK) +#define SPI_INTENSET_SSDEN_MASK (0x20U) +#define SPI_INTENSET_SSDEN_SHIFT (5U) +#define SPI_INTENSET_SSDEN(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTENSET_SSDEN_SHIFT)) & SPI_INTENSET_SSDEN_MASK) +#define SPI_INTENSET_MSTIDLEEN_MASK (0x100U) +#define SPI_INTENSET_MSTIDLEEN_SHIFT (8U) +#define SPI_INTENSET_MSTIDLEEN(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTENSET_MSTIDLEEN_SHIFT)) & SPI_INTENSET_MSTIDLEEN_MASK) + +/*! @name INTENCLR - SPI Interrupt Enable Clear. Writing a 1 to any implemented bit position causes the corresponding bit in INTENSET to be cleared. */ +#define SPI_INTENCLR_RXRDYEN_MASK (0x1U) +#define SPI_INTENCLR_RXRDYEN_SHIFT (0U) +#define SPI_INTENCLR_RXRDYEN(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTENCLR_RXRDYEN_SHIFT)) & SPI_INTENCLR_RXRDYEN_MASK) +#define SPI_INTENCLR_TXRDYEN_MASK (0x2U) +#define SPI_INTENCLR_TXRDYEN_SHIFT (1U) +#define SPI_INTENCLR_TXRDYEN(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTENCLR_TXRDYEN_SHIFT)) & SPI_INTENCLR_TXRDYEN_MASK) +#define SPI_INTENCLR_RXOVEN_MASK (0x4U) +#define SPI_INTENCLR_RXOVEN_SHIFT (2U) +#define SPI_INTENCLR_RXOVEN(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTENCLR_RXOVEN_SHIFT)) & SPI_INTENCLR_RXOVEN_MASK) +#define SPI_INTENCLR_TXUREN_MASK (0x8U) +#define SPI_INTENCLR_TXUREN_SHIFT (3U) +#define SPI_INTENCLR_TXUREN(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTENCLR_TXUREN_SHIFT)) & SPI_INTENCLR_TXUREN_MASK) +#define SPI_INTENCLR_SSAEN_MASK (0x10U) +#define SPI_INTENCLR_SSAEN_SHIFT (4U) +#define SPI_INTENCLR_SSAEN(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTENCLR_SSAEN_SHIFT)) & SPI_INTENCLR_SSAEN_MASK) +#define SPI_INTENCLR_SSDEN_MASK (0x20U) +#define SPI_INTENCLR_SSDEN_SHIFT (5U) +#define SPI_INTENCLR_SSDEN(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTENCLR_SSDEN_SHIFT)) & SPI_INTENCLR_SSDEN_MASK) +#define SPI_INTENCLR_MSTIDLE_MASK (0x100U) +#define SPI_INTENCLR_MSTIDLE_SHIFT (8U) +#define SPI_INTENCLR_MSTIDLE(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTENCLR_MSTIDLE_SHIFT)) & SPI_INTENCLR_MSTIDLE_MASK) + +/*! @name RXDAT - SPI Receive Data */ +#define SPI_RXDAT_RXDAT_MASK (0xFFFFU) +#define SPI_RXDAT_RXDAT_SHIFT (0U) +#define SPI_RXDAT_RXDAT(x) (((uint32_t)(((uint32_t)(x)) << SPI_RXDAT_RXDAT_SHIFT)) & SPI_RXDAT_RXDAT_MASK) +#define SPI_RXDAT_RXSSEL0_N_MASK (0x10000U) +#define SPI_RXDAT_RXSSEL0_N_SHIFT (16U) +#define SPI_RXDAT_RXSSEL0_N(x) (((uint32_t)(((uint32_t)(x)) << SPI_RXDAT_RXSSEL0_N_SHIFT)) & SPI_RXDAT_RXSSEL0_N_MASK) +#define SPI_RXDAT_RXSSEL1_N_MASK (0x20000U) +#define SPI_RXDAT_RXSSEL1_N_SHIFT (17U) +#define SPI_RXDAT_RXSSEL1_N(x) (((uint32_t)(((uint32_t)(x)) << SPI_RXDAT_RXSSEL1_N_SHIFT)) & SPI_RXDAT_RXSSEL1_N_MASK) +#define SPI_RXDAT_RXSSEL2_N_MASK (0x40000U) +#define SPI_RXDAT_RXSSEL2_N_SHIFT (18U) +#define SPI_RXDAT_RXSSEL2_N(x) (((uint32_t)(((uint32_t)(x)) << SPI_RXDAT_RXSSEL2_N_SHIFT)) & SPI_RXDAT_RXSSEL2_N_MASK) +#define SPI_RXDAT_RXSSEL3_N_MASK (0x80000U) +#define SPI_RXDAT_RXSSEL3_N_SHIFT (19U) +#define SPI_RXDAT_RXSSEL3_N(x) (((uint32_t)(((uint32_t)(x)) << SPI_RXDAT_RXSSEL3_N_SHIFT)) & SPI_RXDAT_RXSSEL3_N_MASK) +#define SPI_RXDAT_SOT_MASK (0x100000U) +#define SPI_RXDAT_SOT_SHIFT (20U) +#define SPI_RXDAT_SOT(x) (((uint32_t)(((uint32_t)(x)) << SPI_RXDAT_SOT_SHIFT)) & SPI_RXDAT_SOT_MASK) + +/*! @name TXDATCTL - SPI Transmit Data with Control */ +#define SPI_TXDATCTL_TXDAT_MASK (0xFFFFU) +#define SPI_TXDATCTL_TXDAT_SHIFT (0U) +#define SPI_TXDATCTL_TXDAT(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXDATCTL_TXDAT_SHIFT)) & SPI_TXDATCTL_TXDAT_MASK) +#define SPI_TXDATCTL_TXSSEL0_N_MASK (0x10000U) +#define SPI_TXDATCTL_TXSSEL0_N_SHIFT (16U) +#define SPI_TXDATCTL_TXSSEL0_N(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXDATCTL_TXSSEL0_N_SHIFT)) & SPI_TXDATCTL_TXSSEL0_N_MASK) +#define SPI_TXDATCTL_TXSSEL1_N_MASK (0x20000U) +#define SPI_TXDATCTL_TXSSEL1_N_SHIFT (17U) +#define SPI_TXDATCTL_TXSSEL1_N(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXDATCTL_TXSSEL1_N_SHIFT)) & SPI_TXDATCTL_TXSSEL1_N_MASK) +#define SPI_TXDATCTL_TXSSEL2_N_MASK (0x40000U) +#define SPI_TXDATCTL_TXSSEL2_N_SHIFT (18U) +#define SPI_TXDATCTL_TXSSEL2_N(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXDATCTL_TXSSEL2_N_SHIFT)) & SPI_TXDATCTL_TXSSEL2_N_MASK) +#define SPI_TXDATCTL_TXSSEL3_N_MASK (0x80000U) +#define SPI_TXDATCTL_TXSSEL3_N_SHIFT (19U) +#define SPI_TXDATCTL_TXSSEL3_N(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXDATCTL_TXSSEL3_N_SHIFT)) & SPI_TXDATCTL_TXSSEL3_N_MASK) +#define SPI_TXDATCTL_EOT_MASK (0x100000U) +#define SPI_TXDATCTL_EOT_SHIFT (20U) +#define SPI_TXDATCTL_EOT(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXDATCTL_EOT_SHIFT)) & SPI_TXDATCTL_EOT_MASK) +#define SPI_TXDATCTL_EOF_MASK (0x200000U) +#define SPI_TXDATCTL_EOF_SHIFT (21U) +#define SPI_TXDATCTL_EOF(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXDATCTL_EOF_SHIFT)) & SPI_TXDATCTL_EOF_MASK) +#define SPI_TXDATCTL_RXIGNORE_MASK (0x400000U) +#define SPI_TXDATCTL_RXIGNORE_SHIFT (22U) +#define SPI_TXDATCTL_RXIGNORE(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXDATCTL_RXIGNORE_SHIFT)) & SPI_TXDATCTL_RXIGNORE_MASK) +#define SPI_TXDATCTL_LEN_MASK (0xF000000U) +#define SPI_TXDATCTL_LEN_SHIFT (24U) +#define SPI_TXDATCTL_LEN(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXDATCTL_LEN_SHIFT)) & SPI_TXDATCTL_LEN_MASK) + +/*! @name TXDAT - SPI Transmit Data */ +#define SPI_TXDAT_DATA_MASK (0xFFFFU) +#define SPI_TXDAT_DATA_SHIFT (0U) +#define SPI_TXDAT_DATA(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXDAT_DATA_SHIFT)) & SPI_TXDAT_DATA_MASK) + +/*! @name TXCTL - SPI Transmit Control */ +#define SPI_TXCTL_TXSSEL0_N_MASK (0x10000U) +#define SPI_TXCTL_TXSSEL0_N_SHIFT (16U) +#define SPI_TXCTL_TXSSEL0_N(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXCTL_TXSSEL0_N_SHIFT)) & SPI_TXCTL_TXSSEL0_N_MASK) +#define SPI_TXCTL_TXSSEL1_N_MASK (0x20000U) +#define SPI_TXCTL_TXSSEL1_N_SHIFT (17U) +#define SPI_TXCTL_TXSSEL1_N(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXCTL_TXSSEL1_N_SHIFT)) & SPI_TXCTL_TXSSEL1_N_MASK) +#define SPI_TXCTL_TXSSEL2_N_MASK (0x40000U) +#define SPI_TXCTL_TXSSEL2_N_SHIFT (18U) +#define SPI_TXCTL_TXSSEL2_N(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXCTL_TXSSEL2_N_SHIFT)) & SPI_TXCTL_TXSSEL2_N_MASK) +#define SPI_TXCTL_TXSSEL3_n_MASK (0x80000U) +#define SPI_TXCTL_TXSSEL3_n_SHIFT (19U) +#define SPI_TXCTL_TXSSEL3_n(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXCTL_TXSSEL3_n_SHIFT)) & SPI_TXCTL_TXSSEL3_n_MASK) +#define SPI_TXCTL_EOT_MASK (0x100000U) +#define SPI_TXCTL_EOT_SHIFT (20U) +#define SPI_TXCTL_EOT(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXCTL_EOT_SHIFT)) & SPI_TXCTL_EOT_MASK) +#define SPI_TXCTL_EOF_MASK (0x200000U) +#define SPI_TXCTL_EOF_SHIFT (21U) +#define SPI_TXCTL_EOF(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXCTL_EOF_SHIFT)) & SPI_TXCTL_EOF_MASK) +#define SPI_TXCTL_RXIGNORE_MASK (0x400000U) +#define SPI_TXCTL_RXIGNORE_SHIFT (22U) +#define SPI_TXCTL_RXIGNORE(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXCTL_RXIGNORE_SHIFT)) & SPI_TXCTL_RXIGNORE_MASK) +#define SPI_TXCTL_LEN_MASK (0xF000000U) +#define SPI_TXCTL_LEN_SHIFT (24U) +#define SPI_TXCTL_LEN(x) (((uint32_t)(((uint32_t)(x)) << SPI_TXCTL_LEN_SHIFT)) & SPI_TXCTL_LEN_MASK) + +/*! @name DIV - SPI clock Divider */ +#define SPI_DIV_DIVVAL_MASK (0xFFFFU) +#define SPI_DIV_DIVVAL_SHIFT (0U) +#define SPI_DIV_DIVVAL(x) (((uint32_t)(((uint32_t)(x)) << SPI_DIV_DIVVAL_SHIFT)) & SPI_DIV_DIVVAL_MASK) + +/*! @name INTSTAT - SPI Interrupt Status */ +#define SPI_INTSTAT_RXRDY_MASK (0x1U) +#define SPI_INTSTAT_RXRDY_SHIFT (0U) +#define SPI_INTSTAT_RXRDY(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTSTAT_RXRDY_SHIFT)) & SPI_INTSTAT_RXRDY_MASK) +#define SPI_INTSTAT_TXRDY_MASK (0x2U) +#define SPI_INTSTAT_TXRDY_SHIFT (1U) +#define SPI_INTSTAT_TXRDY(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTSTAT_TXRDY_SHIFT)) & SPI_INTSTAT_TXRDY_MASK) +#define SPI_INTSTAT_RXOV_MASK (0x4U) +#define SPI_INTSTAT_RXOV_SHIFT (2U) +#define SPI_INTSTAT_RXOV(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTSTAT_RXOV_SHIFT)) & SPI_INTSTAT_RXOV_MASK) +#define SPI_INTSTAT_TXUR_MASK (0x8U) +#define SPI_INTSTAT_TXUR_SHIFT (3U) +#define SPI_INTSTAT_TXUR(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTSTAT_TXUR_SHIFT)) & SPI_INTSTAT_TXUR_MASK) +#define SPI_INTSTAT_SSA_MASK (0x10U) +#define SPI_INTSTAT_SSA_SHIFT (4U) +#define SPI_INTSTAT_SSA(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTSTAT_SSA_SHIFT)) & SPI_INTSTAT_SSA_MASK) +#define SPI_INTSTAT_SSD_MASK (0x20U) +#define SPI_INTSTAT_SSD_SHIFT (5U) +#define SPI_INTSTAT_SSD(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTSTAT_SSD_SHIFT)) & SPI_INTSTAT_SSD_MASK) +#define SPI_INTSTAT_MSTIDLE_MASK (0x100U) +#define SPI_INTSTAT_MSTIDLE_SHIFT (8U) +#define SPI_INTSTAT_MSTIDLE(x) (((uint32_t)(((uint32_t)(x)) << SPI_INTSTAT_MSTIDLE_SHIFT)) & SPI_INTSTAT_MSTIDLE_MASK) + + +/*! + * @} + */ /* end of group SPI_Register_Masks */ + + +/* SPI - Peripheral instance base addresses */ +/** Peripheral SPI0 base address */ +#define SPI0_BASE (0x400A4000u) +/** Peripheral SPI0 base pointer */ +#define SPI0 ((SPI_Type *)SPI0_BASE) +/** Peripheral SPI1 base address */ +#define SPI1_BASE (0x400A8000u) +/** Peripheral SPI1 base pointer */ +#define SPI1 ((SPI_Type *)SPI1_BASE) +/** Array initializer of SPI peripheral base addresses */ +#define SPI_BASE_ADDRS { SPI0_BASE, SPI1_BASE } +/** Array initializer of SPI peripheral base pointers */ +#define SPI_BASE_PTRS { SPI0, SPI1 } +/** Interrupt vectors for the SPI peripheral type */ +#define SPI_IRQS { SPI0_IRQn, SPI1_IRQn } + +/*! + * @} + */ /* end of group SPI_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- SYSCON Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SYSCON_Peripheral_Access_Layer SYSCON Peripheral Access Layer + * @{ + */ + +/** SYSCON - Register Layout Typedef */ +typedef struct { + __IO uint32_t SYSMEMREMAP; /**< System memory remap, offset: 0x0 */ + __IO uint32_t AHBMATPRIO; /**< AHB multilayer matrix priority control, offset: 0x4 */ + uint8_t RESERVED_0[12]; + __IO uint32_t SYSTCKCAL; /**< System tick counter calibration, offset: 0x14 */ + uint8_t RESERVED_1[4]; + __IO uint32_t NMISRC; /**< NMI Source Select, offset: 0x1C */ + __IO uint32_t ASYNCAPBCTRL; /**< Asynchronous APB Control, offset: 0x20 */ + uint8_t RESERVED_2[28]; + __IO uint32_t SYSRSTSTAT; /**< System reset status register, offset: 0x40 */ + __IO uint32_t PRESETCTRL[2]; /**< Peripheral reset control n, array offset: 0x44, array step: 0x4 */ + __IO uint32_t PRESETCTRLSET[2]; /**< Set bits in PRESETCTRL n, array offset: 0x4C, array step: 0x4 */ + __IO uint32_t PRESETCTRLCLR[2]; /**< Clear bits in PRESETCTRL n, array offset: 0x54, array step: 0x4 */ + __IO uint32_t PIOPORCAP0; /**< POR captured PIO status 0, offset: 0x5C */ + __IO uint32_t PIOPORCAP1; /**< POR captured PIO status 1, offset: 0x60 */ + uint8_t RESERVED_3[4]; + __IO uint32_t PIORESCAP0; /**< Reset captured PIO status 0, offset: 0x68 */ + __IO uint32_t PIORESCAP1; /**< Reset captured PIO status 1, offset: 0x6C */ + uint8_t RESERVED_4[16]; + __IO uint32_t MAINCLKSELA; /**< Main clock source select A, offset: 0x80 */ + __IO uint32_t MAINCLKSELB; /**< Main clock source select B, offset: 0x84 */ + uint8_t RESERVED_5[4]; + __IO uint32_t ADCCLKSEL; /**< ADC clock source select, offset: 0x8C */ + uint8_t RESERVED_6[4]; + __IO uint32_t CLKOUTSELA; /**< CLKOUT clock source select A, offset: 0x94 */ + __IO uint32_t CLKOUTSELB; /**< CLKOUT clock source select B, offset: 0x98 */ + uint8_t RESERVED_7[4]; + __IO uint32_t SYSPLLCLKSEL; /**< PLL clock source select, offset: 0xA0 */ + uint8_t RESERVED_8[28]; + __IO uint32_t AHBCLKCTRL[2]; /**< AHB Clock control n, array offset: 0xC0, array step: 0x4 */ + __IO uint32_t AHBCLKCTRLSET[2]; /**< Set bits in AHBCLKCTRL n, array offset: 0xC8, array step: 0x4 */ + __IO uint32_t AHBCLKCTRLCLR[2]; /**< Clear bits in AHBCLKCTRL n, array offset: 0xD0, array step: 0x4 */ + uint8_t RESERVED_9[8]; + __IO uint32_t SYSTICKCLKDIV; /**< SYSTICK clock divider, offset: 0xE0 */ + uint8_t RESERVED_10[28]; + __IO uint32_t AHBCLKDIV; /**< System clock divider, offset: 0x100 */ + uint8_t RESERVED_11[4]; + __IO uint32_t ADCCLKDIV; /**< ADC clock divider, offset: 0x108 */ + __IO uint32_t CLKOUTDIV; /**< CLKOUT clock divider, offset: 0x10C */ + uint8_t RESERVED_12[16]; + __IO uint32_t FREQMECTRL; /**< Frequency measure register, offset: 0x120 */ + __IO uint32_t FLASHCFG; /**< Flash wait states configuration, offset: 0x124 */ + uint8_t RESERVED_13[32]; + __IO uint32_t FIFOCTRL; /**< Serial interface FIFO enables, offset: 0x148 */ + uint8_t RESERVED_14[56]; + __IO uint32_t IRCCTRL; /**< IRC oscillator control, offset: 0x184 */ + uint8_t RESERVED_15[8]; + __IO uint32_t RTCOSCCTRL; /**< RTC oscillator 32 kHz output control, offset: 0x190 */ + uint8_t RESERVED_16[28]; + __IO uint32_t SYSPLLCTRL; /**< PLL control, offset: 0x1B0 */ + __IO uint32_t SYSPLLSTAT; /**< PLL status, offset: 0x1B4 */ + __IO uint32_t SYSPLLNDEC; /**< PLL N decoder, offset: 0x1B8 */ + __IO uint32_t SYSPLLPDEC; /**< PLL P decoder, offset: 0x1BC */ + __IO uint32_t SYSPLLSSCTRL0; /**< PLL spread spectrum control 0, offset: 0x1C0 */ + __IO uint32_t SYSPLLSSCTRL1; /**< PLL spread spectrum control 1, offset: 0x1C4 */ + uint8_t RESERVED_17[72]; + __IO uint32_t PDRUNCFG; /**< Power configuration register, offset: 0x210 */ + __IO uint32_t PDRUNCFGSET; /**< Set bits in PDRUNCFG, offset: 0x214 */ + __IO uint32_t PDRUNCFGCLR; /**< Clear bits in PDRUNCFG, offset: 0x218 */ + uint8_t RESERVED_18[36]; + __IO uint32_t STARTER[2]; /**< Start logic n wake-up enable register, array offset: 0x240, array step: 0x4 */ + __IO uint32_t STARTERSET[2]; /**< Set bits in STARTERP n, array offset: 0x248, array step: 0x4 */ + __IO uint32_t STARTERCLR[2]; /**< Clear bits in STARTER n, array offset: 0x250, array step: 0x4 */ + uint8_t RESERVED_19[168]; + __IO uint32_t CPUCTRL; /**< CPU Control for multiple processors, offset: 0x300 */ + __IO uint32_t CPBOOT; /**< Coprocessor Boot Address, offset: 0x304 */ + __IO uint32_t CPSTACK; /**< Coprocessor Stack Address, offset: 0x308 */ + __IO uint32_t CPSTAT; /**< Coprocessor Status, offset: 0x30C */ + uint8_t RESERVED_20[228]; + __IO uint32_t JTAGIDCODE; /**< JTAG ID code register, offset: 0x3F4 */ + __IO uint32_t DEVICE_ID[2]; /**< Part ID register, array offset: 0x3F8, array step: 0x4 */ + uint8_t RESERVED_21[179268]; + __IO uint32_t BODCTRL; /**< Brown-Out Detect control, offset: 0x2C044 */ +} SYSCON_Type; + +/* ---------------------------------------------------------------------------- + -- SYSCON Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SYSCON_Register_Masks SYSCON Register Masks + * @{ + */ + +/*! @name SYSMEMREMAP - System memory remap */ +#define SYSCON_SYSMEMREMAP_MAP_MASK (0x3U) +#define SYSCON_SYSMEMREMAP_MAP_SHIFT (0U) +#define SYSCON_SYSMEMREMAP_MAP(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSMEMREMAP_MAP_SHIFT)) & SYSCON_SYSMEMREMAP_MAP_MASK) + +/*! @name AHBMATPRIO - AHB multilayer matrix priority control */ +#define SYSCON_AHBMATPRIO_PRI_ICODE_MASK (0x3U) +#define SYSCON_AHBMATPRIO_PRI_ICODE_SHIFT (0U) +#define SYSCON_AHBMATPRIO_PRI_ICODE(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBMATPRIO_PRI_ICODE_SHIFT)) & SYSCON_AHBMATPRIO_PRI_ICODE_MASK) +#define SYSCON_AHBMATPRIO_PRI_DCODE_MASK (0xCU) +#define SYSCON_AHBMATPRIO_PRI_DCODE_SHIFT (2U) +#define SYSCON_AHBMATPRIO_PRI_DCODE(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBMATPRIO_PRI_DCODE_SHIFT)) & SYSCON_AHBMATPRIO_PRI_DCODE_MASK) +#define SYSCON_AHBMATPRIO_PRI_SYS_MASK (0x30U) +#define SYSCON_AHBMATPRIO_PRI_SYS_SHIFT (4U) +#define SYSCON_AHBMATPRIO_PRI_SYS(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBMATPRIO_PRI_SYS_SHIFT)) & SYSCON_AHBMATPRIO_PRI_SYS_MASK) +#define SYSCON_AHBMATPRIO_PRI_DMA_MASK (0x300U) +#define SYSCON_AHBMATPRIO_PRI_DMA_SHIFT (8U) +#define SYSCON_AHBMATPRIO_PRI_DMA(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBMATPRIO_PRI_DMA_SHIFT)) & SYSCON_AHBMATPRIO_PRI_DMA_MASK) +#define SYSCON_AHBMATPRIO_PRI_FIFO_MASK (0xC000U) +#define SYSCON_AHBMATPRIO_PRI_FIFO_SHIFT (14U) +#define SYSCON_AHBMATPRIO_PRI_FIFO(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBMATPRIO_PRI_FIFO_SHIFT)) & SYSCON_AHBMATPRIO_PRI_FIFO_MASK) +#define SYSCON_AHBMATPRIO_PRI_M0_MASK (0x30000U) +#define SYSCON_AHBMATPRIO_PRI_M0_SHIFT (16U) +#define SYSCON_AHBMATPRIO_PRI_M0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBMATPRIO_PRI_M0_SHIFT)) & SYSCON_AHBMATPRIO_PRI_M0_MASK) + +/*! @name SYSTCKCAL - System tick counter calibration */ +#define SYSCON_SYSTCKCAL_CAL_MASK (0xFFFFFFU) +#define SYSCON_SYSTCKCAL_CAL_SHIFT (0U) +#define SYSCON_SYSTCKCAL_CAL(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSTCKCAL_CAL_SHIFT)) & SYSCON_SYSTCKCAL_CAL_MASK) +#define SYSCON_SYSTCKCAL_SKEW_MASK (0x1000000U) +#define SYSCON_SYSTCKCAL_SKEW_SHIFT (24U) +#define SYSCON_SYSTCKCAL_SKEW(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSTCKCAL_SKEW_SHIFT)) & SYSCON_SYSTCKCAL_SKEW_MASK) +#define SYSCON_SYSTCKCAL_NOREF_MASK (0x2000000U) +#define SYSCON_SYSTCKCAL_NOREF_SHIFT (25U) +#define SYSCON_SYSTCKCAL_NOREF(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSTCKCAL_NOREF_SHIFT)) & SYSCON_SYSTCKCAL_NOREF_MASK) + +/*! @name NMISRC - NMI Source Select */ +#define SYSCON_NMISRC_IRQM4_MASK (0x3FU) +#define SYSCON_NMISRC_IRQM4_SHIFT (0U) +#define SYSCON_NMISRC_IRQM4(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_NMISRC_IRQM4_SHIFT)) & SYSCON_NMISRC_IRQM4_MASK) +#define SYSCON_NMISRC_IRQM0_MASK (0x3F00U) +#define SYSCON_NMISRC_IRQM0_SHIFT (8U) +#define SYSCON_NMISRC_IRQM0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_NMISRC_IRQM0_SHIFT)) & SYSCON_NMISRC_IRQM0_MASK) +#define SYSCON_NMISRC_NMIENM0_MASK (0x40000000U) +#define SYSCON_NMISRC_NMIENM0_SHIFT (30U) +#define SYSCON_NMISRC_NMIENM0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_NMISRC_NMIENM0_SHIFT)) & SYSCON_NMISRC_NMIENM0_MASK) +#define SYSCON_NMISRC_NMIENM4_MASK (0x80000000U) +#define SYSCON_NMISRC_NMIENM4_SHIFT (31U) +#define SYSCON_NMISRC_NMIENM4(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_NMISRC_NMIENM4_SHIFT)) & SYSCON_NMISRC_NMIENM4_MASK) + +/*! @name ASYNCAPBCTRL - Asynchronous APB Control */ +#define SYSCON_ASYNCAPBCTRL_ENABLE_MASK (0x1U) +#define SYSCON_ASYNCAPBCTRL_ENABLE_SHIFT (0U) +#define SYSCON_ASYNCAPBCTRL_ENABLE(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_ASYNCAPBCTRL_ENABLE_SHIFT)) & SYSCON_ASYNCAPBCTRL_ENABLE_MASK) + +/*! @name SYSRSTSTAT - System reset status register */ +#define SYSCON_SYSRSTSTAT_POR_MASK (0x1U) +#define SYSCON_SYSRSTSTAT_POR_SHIFT (0U) +#define SYSCON_SYSRSTSTAT_POR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSRSTSTAT_POR_SHIFT)) & SYSCON_SYSRSTSTAT_POR_MASK) +#define SYSCON_SYSRSTSTAT_EXTRST_MASK (0x2U) +#define SYSCON_SYSRSTSTAT_EXTRST_SHIFT (1U) +#define SYSCON_SYSRSTSTAT_EXTRST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSRSTSTAT_EXTRST_SHIFT)) & SYSCON_SYSRSTSTAT_EXTRST_MASK) +#define SYSCON_SYSRSTSTAT_WDT_MASK (0x4U) +#define SYSCON_SYSRSTSTAT_WDT_SHIFT (2U) +#define SYSCON_SYSRSTSTAT_WDT(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSRSTSTAT_WDT_SHIFT)) & SYSCON_SYSRSTSTAT_WDT_MASK) +#define SYSCON_SYSRSTSTAT_BOD_MASK (0x8U) +#define SYSCON_SYSRSTSTAT_BOD_SHIFT (3U) +#define SYSCON_SYSRSTSTAT_BOD(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSRSTSTAT_BOD_SHIFT)) & SYSCON_SYSRSTSTAT_BOD_MASK) +#define SYSCON_SYSRSTSTAT_SYSRST_MASK (0x10U) +#define SYSCON_SYSRSTSTAT_SYSRST_SHIFT (4U) +#define SYSCON_SYSRSTSTAT_SYSRST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSRSTSTAT_SYSRST_SHIFT)) & SYSCON_SYSRSTSTAT_SYSRST_MASK) + +/*! @name PRESETCTRL - Peripheral reset control n */ +#define SYSCON_PRESETCTRL_MRT_RST_MASK (0x1U) +#define SYSCON_PRESETCTRL_MRT_RST_SHIFT (0U) +#define SYSCON_PRESETCTRL_MRT_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_MRT_RST_SHIFT)) & SYSCON_PRESETCTRL_MRT_RST_MASK) +#define SYSCON_PRESETCTRL_RIT_RST_MASK (0x2U) +#define SYSCON_PRESETCTRL_RIT_RST_SHIFT (1U) +#define SYSCON_PRESETCTRL_RIT_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_RIT_RST_SHIFT)) & SYSCON_PRESETCTRL_RIT_RST_MASK) +#define SYSCON_PRESETCTRL_SCT0_RST_MASK (0x4U) +#define SYSCON_PRESETCTRL_SCT0_RST_SHIFT (2U) +#define SYSCON_PRESETCTRL_SCT0_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_SCT0_RST_SHIFT)) & SYSCON_PRESETCTRL_SCT0_RST_MASK) +#define SYSCON_PRESETCTRL_FLASH_RST_MASK (0x80U) +#define SYSCON_PRESETCTRL_FLASH_RST_SHIFT (7U) +#define SYSCON_PRESETCTRL_FLASH_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_FLASH_RST_SHIFT)) & SYSCON_PRESETCTRL_FLASH_RST_MASK) +#define SYSCON_PRESETCTRL_FMC_RST_MASK (0x100U) +#define SYSCON_PRESETCTRL_FMC_RST_SHIFT (8U) +#define SYSCON_PRESETCTRL_FMC_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_FMC_RST_SHIFT)) & SYSCON_PRESETCTRL_FMC_RST_MASK) +#define SYSCON_PRESETCTRL_FIFO_RST_MASK (0x200U) +#define SYSCON_PRESETCTRL_FIFO_RST_SHIFT (9U) +#define SYSCON_PRESETCTRL_FIFO_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_FIFO_RST_SHIFT)) & SYSCON_PRESETCTRL_FIFO_RST_MASK) +#define SYSCON_PRESETCTRL_UTICK_RST_MASK (0x400U) +#define SYSCON_PRESETCTRL_UTICK_RST_SHIFT (10U) +#define SYSCON_PRESETCTRL_UTICK_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_UTICK_RST_SHIFT)) & SYSCON_PRESETCTRL_UTICK_RST_MASK) +#define SYSCON_PRESETCTRL_MUX_RST_MASK (0x800U) +#define SYSCON_PRESETCTRL_MUX_RST_SHIFT (11U) +#define SYSCON_PRESETCTRL_MUX_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_MUX_RST_SHIFT)) & SYSCON_PRESETCTRL_MUX_RST_MASK) +#define SYSCON_PRESETCTRL_IOCON_RST_MASK (0x2000U) +#define SYSCON_PRESETCTRL_IOCON_RST_SHIFT (13U) +#define SYSCON_PRESETCTRL_IOCON_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_IOCON_RST_SHIFT)) & SYSCON_PRESETCTRL_IOCON_RST_MASK) +#define SYSCON_PRESETCTRL_GPIO0_RST_MASK (0x4000U) +#define SYSCON_PRESETCTRL_GPIO0_RST_SHIFT (14U) +#define SYSCON_PRESETCTRL_GPIO0_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_GPIO0_RST_SHIFT)) & SYSCON_PRESETCTRL_GPIO0_RST_MASK) +#define SYSCON_PRESETCTRL_GPIO1_RST_MASK (0x8000U) +#define SYSCON_PRESETCTRL_GPIO1_RST_SHIFT (15U) +#define SYSCON_PRESETCTRL_GPIO1_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_GPIO1_RST_SHIFT)) & SYSCON_PRESETCTRL_GPIO1_RST_MASK) +#define SYSCON_PRESETCTRL_PINT_RST_MASK (0x40000U) +#define SYSCON_PRESETCTRL_PINT_RST_SHIFT (18U) +#define SYSCON_PRESETCTRL_PINT_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_PINT_RST_SHIFT)) & SYSCON_PRESETCTRL_PINT_RST_MASK) +#define SYSCON_PRESETCTRL_GINT_RST_MASK (0x80000U) +#define SYSCON_PRESETCTRL_GINT_RST_SHIFT (19U) +#define SYSCON_PRESETCTRL_GINT_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_GINT_RST_SHIFT)) & SYSCON_PRESETCTRL_GINT_RST_MASK) +#define SYSCON_PRESETCTRL_DMA_RST_MASK (0x100000U) +#define SYSCON_PRESETCTRL_DMA_RST_SHIFT (20U) +#define SYSCON_PRESETCTRL_DMA_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_DMA_RST_SHIFT)) & SYSCON_PRESETCTRL_DMA_RST_MASK) +#define SYSCON_PRESETCTRL_CRC_RST_MASK (0x200000U) +#define SYSCON_PRESETCTRL_CRC_RST_SHIFT (21U) +#define SYSCON_PRESETCTRL_CRC_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_CRC_RST_SHIFT)) & SYSCON_PRESETCTRL_CRC_RST_MASK) +#define SYSCON_PRESETCTRL_CT32B2_RST_MASK (0x400000U) +#define SYSCON_PRESETCTRL_CT32B2_RST_SHIFT (22U) +#define SYSCON_PRESETCTRL_CT32B2_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_CT32B2_RST_SHIFT)) & SYSCON_PRESETCTRL_CT32B2_RST_MASK) +#define SYSCON_PRESETCTRL_WWDT_RST_MASK (0x400000U) +#define SYSCON_PRESETCTRL_WWDT_RST_SHIFT (22U) +#define SYSCON_PRESETCTRL_WWDT_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_WWDT_RST_SHIFT)) & SYSCON_PRESETCTRL_WWDT_RST_MASK) +#define SYSCON_PRESETCTRL_CT32B3_RST_MASK (0x4000000U) +#define SYSCON_PRESETCTRL_CT32B3_RST_SHIFT (26U) +#define SYSCON_PRESETCTRL_CT32B3_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_CT32B3_RST_SHIFT)) & SYSCON_PRESETCTRL_CT32B3_RST_MASK) +#define SYSCON_PRESETCTRL_ADC0_RST_MASK (0x8000000U) +#define SYSCON_PRESETCTRL_ADC0_RST_SHIFT (27U) +#define SYSCON_PRESETCTRL_ADC0_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_ADC0_RST_SHIFT)) & SYSCON_PRESETCTRL_ADC0_RST_MASK) +#define SYSCON_PRESETCTRL_CT32B4_RST_MASK (0x8000000U) +#define SYSCON_PRESETCTRL_CT32B4_RST_SHIFT (27U) +#define SYSCON_PRESETCTRL_CT32B4_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRL_CT32B4_RST_SHIFT)) & SYSCON_PRESETCTRL_CT32B4_RST_MASK) + +/* The count of SYSCON_PRESETCTRL */ +#define SYSCON_PRESETCTRL_COUNT (2U) + +/*! @name PRESETCTRLSET - Set bits in PRESETCTRL n */ +#define SYSCON_PRESETCTRLSET_RST_SET_MASK (0xFFFFFFFFU) +#define SYSCON_PRESETCTRLSET_RST_SET_SHIFT (0U) +#define SYSCON_PRESETCTRLSET_RST_SET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLSET_RST_SET_SHIFT)) & SYSCON_PRESETCTRLSET_RST_SET_MASK) + +/* The count of SYSCON_PRESETCTRLSET */ +#define SYSCON_PRESETCTRLSET_COUNT (2U) + +/*! @name PRESETCTRLCLR - Clear bits in PRESETCTRL n */ +#define SYSCON_PRESETCTRLCLR_RST_CLR_MASK (0xFFFFFFFFU) +#define SYSCON_PRESETCTRLCLR_RST_CLR_SHIFT (0U) +#define SYSCON_PRESETCTRLCLR_RST_CLR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PRESETCTRLCLR_RST_CLR_SHIFT)) & SYSCON_PRESETCTRLCLR_RST_CLR_MASK) + +/* The count of SYSCON_PRESETCTRLCLR */ +#define SYSCON_PRESETCTRLCLR_COUNT (2U) + +/*! @name PIOPORCAP0 - POR captured PIO status 0 */ +#define SYSCON_PIOPORCAP0_PIOPORSTAT_MASK (0xFFFFFFFFU) +#define SYSCON_PIOPORCAP0_PIOPORSTAT_SHIFT (0U) +#define SYSCON_PIOPORCAP0_PIOPORSTAT(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PIOPORCAP0_PIOPORSTAT_SHIFT)) & SYSCON_PIOPORCAP0_PIOPORSTAT_MASK) + +/*! @name PIOPORCAP1 - POR captured PIO status 1 */ +#define SYSCON_PIOPORCAP1_PIOPORSTAT_MASK (0xFFFFFFFFU) +#define SYSCON_PIOPORCAP1_PIOPORSTAT_SHIFT (0U) +#define SYSCON_PIOPORCAP1_PIOPORSTAT(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PIOPORCAP1_PIOPORSTAT_SHIFT)) & SYSCON_PIOPORCAP1_PIOPORSTAT_MASK) + +/*! @name PIORESCAP0 - Reset captured PIO status 0 */ +#define SYSCON_PIORESCAP0_PIORESSTAT_MASK (0xFFFFFFFFU) +#define SYSCON_PIORESCAP0_PIORESSTAT_SHIFT (0U) +#define SYSCON_PIORESCAP0_PIORESSTAT(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PIORESCAP0_PIORESSTAT_SHIFT)) & SYSCON_PIORESCAP0_PIORESSTAT_MASK) + +/*! @name PIORESCAP1 - Reset captured PIO status 1 */ +#define SYSCON_PIORESCAP1_PIORESSTAT_MASK (0xFFFFFFFFU) +#define SYSCON_PIORESCAP1_PIORESSTAT_SHIFT (0U) +#define SYSCON_PIORESCAP1_PIORESSTAT(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PIORESCAP1_PIORESSTAT_SHIFT)) & SYSCON_PIORESCAP1_PIORESSTAT_MASK) + +/*! @name MAINCLKSELA - Main clock source select A */ +#define SYSCON_MAINCLKSELA_SEL_MASK (0x3U) +#define SYSCON_MAINCLKSELA_SEL_SHIFT (0U) +#define SYSCON_MAINCLKSELA_SEL(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_MAINCLKSELA_SEL_SHIFT)) & SYSCON_MAINCLKSELA_SEL_MASK) + +/*! @name MAINCLKSELB - Main clock source select B */ +#define SYSCON_MAINCLKSELB_SEL_MASK (0x3U) +#define SYSCON_MAINCLKSELB_SEL_SHIFT (0U) +#define SYSCON_MAINCLKSELB_SEL(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_MAINCLKSELB_SEL_SHIFT)) & SYSCON_MAINCLKSELB_SEL_MASK) + +/*! @name ADCCLKSEL - ADC clock source select */ +#define SYSCON_ADCCLKSEL_SEL_MASK (0x3U) +#define SYSCON_ADCCLKSEL_SEL_SHIFT (0U) +#define SYSCON_ADCCLKSEL_SEL(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_ADCCLKSEL_SEL_SHIFT)) & SYSCON_ADCCLKSEL_SEL_MASK) + +/*! @name CLKOUTSELA - CLKOUT clock source select A */ +#define SYSCON_CLKOUTSELA_SEL_MASK (0x3U) +#define SYSCON_CLKOUTSELA_SEL_SHIFT (0U) +#define SYSCON_CLKOUTSELA_SEL(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_CLKOUTSELA_SEL_SHIFT)) & SYSCON_CLKOUTSELA_SEL_MASK) + +/*! @name CLKOUTSELB - CLKOUT clock source select B */ +#define SYSCON_CLKOUTSELB_SEL_MASK (0x3U) +#define SYSCON_CLKOUTSELB_SEL_SHIFT (0U) +#define SYSCON_CLKOUTSELB_SEL(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_CLKOUTSELB_SEL_SHIFT)) & SYSCON_CLKOUTSELB_SEL_MASK) + +/*! @name SYSPLLCLKSEL - PLL clock source select */ +#define SYSCON_SYSPLLCLKSEL_SEL_MASK (0x3U) +#define SYSCON_SYSPLLCLKSEL_SEL_SHIFT (0U) +#define SYSCON_SYSPLLCLKSEL_SEL(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLCLKSEL_SEL_SHIFT)) & SYSCON_SYSPLLCLKSEL_SEL_MASK) + +/*! @name AHBCLKCTRL - AHB Clock control n */ +#define SYSCON_AHBCLKCTRL_MRT_MASK (0x1U) +#define SYSCON_AHBCLKCTRL_MRT_SHIFT (0U) +#define SYSCON_AHBCLKCTRL_MRT(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_MRT_SHIFT)) & SYSCON_AHBCLKCTRL_MRT_MASK) +#define SYSCON_AHBCLKCTRL_ROM_MASK (0x2U) +#define SYSCON_AHBCLKCTRL_ROM_SHIFT (1U) +#define SYSCON_AHBCLKCTRL_ROM(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_ROM_SHIFT)) & SYSCON_AHBCLKCTRL_ROM_MASK) +#define SYSCON_AHBCLKCTRL_RIT_MASK (0x2U) +#define SYSCON_AHBCLKCTRL_RIT_SHIFT (1U) +#define SYSCON_AHBCLKCTRL_RIT(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_RIT_SHIFT)) & SYSCON_AHBCLKCTRL_RIT_MASK) +#define SYSCON_AHBCLKCTRL_SCT0_MASK (0x4U) +#define SYSCON_AHBCLKCTRL_SCT0_SHIFT (2U) +#define SYSCON_AHBCLKCTRL_SCT0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_SCT0_SHIFT)) & SYSCON_AHBCLKCTRL_SCT0_MASK) +#define SYSCON_AHBCLKCTRL_SRAM1_MASK (0x8U) +#define SYSCON_AHBCLKCTRL_SRAM1_SHIFT (3U) +#define SYSCON_AHBCLKCTRL_SRAM1(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_SRAM1_SHIFT)) & SYSCON_AHBCLKCTRL_SRAM1_MASK) +#define SYSCON_AHBCLKCTRL_SRAM2_MASK (0x10U) +#define SYSCON_AHBCLKCTRL_SRAM2_SHIFT (4U) +#define SYSCON_AHBCLKCTRL_SRAM2(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_SRAM2_SHIFT)) & SYSCON_AHBCLKCTRL_SRAM2_MASK) +#define SYSCON_AHBCLKCTRL_FLASH_MASK (0x80U) +#define SYSCON_AHBCLKCTRL_FLASH_SHIFT (7U) +#define SYSCON_AHBCLKCTRL_FLASH(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_FLASH_SHIFT)) & SYSCON_AHBCLKCTRL_FLASH_MASK) +#define SYSCON_AHBCLKCTRL_FMC_MASK (0x100U) +#define SYSCON_AHBCLKCTRL_FMC_SHIFT (8U) +#define SYSCON_AHBCLKCTRL_FMC(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_FMC_SHIFT)) & SYSCON_AHBCLKCTRL_FMC_MASK) +#define SYSCON_AHBCLKCTRL_FIFO_MASK (0x200U) +#define SYSCON_AHBCLKCTRL_FIFO_SHIFT (9U) +#define SYSCON_AHBCLKCTRL_FIFO(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_FIFO_SHIFT)) & SYSCON_AHBCLKCTRL_FIFO_MASK) +#define SYSCON_AHBCLKCTRL_UTICK_MASK (0x400U) +#define SYSCON_AHBCLKCTRL_UTICK_SHIFT (10U) +#define SYSCON_AHBCLKCTRL_UTICK(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_UTICK_SHIFT)) & SYSCON_AHBCLKCTRL_UTICK_MASK) +#define SYSCON_AHBCLKCTRL_INPUTMUX_MASK (0x800U) +#define SYSCON_AHBCLKCTRL_INPUTMUX_SHIFT (11U) +#define SYSCON_AHBCLKCTRL_INPUTMUX(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_INPUTMUX_SHIFT)) & SYSCON_AHBCLKCTRL_INPUTMUX_MASK) +#define SYSCON_AHBCLKCTRL_IOCON_MASK (0x2000U) +#define SYSCON_AHBCLKCTRL_IOCON_SHIFT (13U) +#define SYSCON_AHBCLKCTRL_IOCON(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_IOCON_SHIFT)) & SYSCON_AHBCLKCTRL_IOCON_MASK) +#define SYSCON_AHBCLKCTRL_GPIO0_MASK (0x4000U) +#define SYSCON_AHBCLKCTRL_GPIO0_SHIFT (14U) +#define SYSCON_AHBCLKCTRL_GPIO0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_GPIO0_SHIFT)) & SYSCON_AHBCLKCTRL_GPIO0_MASK) +#define SYSCON_AHBCLKCTRL_GPIO1_MASK (0x8000U) +#define SYSCON_AHBCLKCTRL_GPIO1_SHIFT (15U) +#define SYSCON_AHBCLKCTRL_GPIO1(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_GPIO1_SHIFT)) & SYSCON_AHBCLKCTRL_GPIO1_MASK) +#define SYSCON_AHBCLKCTRL_PINT_MASK (0x40000U) +#define SYSCON_AHBCLKCTRL_PINT_SHIFT (18U) +#define SYSCON_AHBCLKCTRL_PINT(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_PINT_SHIFT)) & SYSCON_AHBCLKCTRL_PINT_MASK) +#define SYSCON_AHBCLKCTRL_GINT_MASK (0x80000U) +#define SYSCON_AHBCLKCTRL_GINT_SHIFT (19U) +#define SYSCON_AHBCLKCTRL_GINT(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_GINT_SHIFT)) & SYSCON_AHBCLKCTRL_GINT_MASK) +#define SYSCON_AHBCLKCTRL_DMA_MASK (0x100000U) +#define SYSCON_AHBCLKCTRL_DMA_SHIFT (20U) +#define SYSCON_AHBCLKCTRL_DMA(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_DMA_SHIFT)) & SYSCON_AHBCLKCTRL_DMA_MASK) +#define SYSCON_AHBCLKCTRL_CRC_MASK (0x200000U) +#define SYSCON_AHBCLKCTRL_CRC_SHIFT (21U) +#define SYSCON_AHBCLKCTRL_CRC(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_CRC_SHIFT)) & SYSCON_AHBCLKCTRL_CRC_MASK) +#define SYSCON_AHBCLKCTRL_CT32B2_MASK (0x400000U) +#define SYSCON_AHBCLKCTRL_CT32B2_SHIFT (22U) +#define SYSCON_AHBCLKCTRL_CT32B2(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_CT32B2_SHIFT)) & SYSCON_AHBCLKCTRL_CT32B2_MASK) +#define SYSCON_AHBCLKCTRL_WWDT_MASK (0x400000U) +#define SYSCON_AHBCLKCTRL_WWDT_SHIFT (22U) +#define SYSCON_AHBCLKCTRL_WWDT(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_WWDT_SHIFT)) & SYSCON_AHBCLKCTRL_WWDT_MASK) +#define SYSCON_AHBCLKCTRL_RTC_MASK (0x800000U) +#define SYSCON_AHBCLKCTRL_RTC_SHIFT (23U) +#define SYSCON_AHBCLKCTRL_RTC(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_RTC_SHIFT)) & SYSCON_AHBCLKCTRL_RTC_MASK) +#define SYSCON_AHBCLKCTRL_CT32B3_MASK (0x4000000U) +#define SYSCON_AHBCLKCTRL_CT32B3_SHIFT (26U) +#define SYSCON_AHBCLKCTRL_CT32B3(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_CT32B3_SHIFT)) & SYSCON_AHBCLKCTRL_CT32B3_MASK) +#define SYSCON_AHBCLKCTRL_MAILBOX_MASK (0x4000000U) +#define SYSCON_AHBCLKCTRL_MAILBOX_SHIFT (26U) +#define SYSCON_AHBCLKCTRL_MAILBOX(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_MAILBOX_SHIFT)) & SYSCON_AHBCLKCTRL_MAILBOX_MASK) +#define SYSCON_AHBCLKCTRL_CT32B4_MASK (0x8000000U) +#define SYSCON_AHBCLKCTRL_CT32B4_SHIFT (27U) +#define SYSCON_AHBCLKCTRL_CT32B4(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_CT32B4_SHIFT)) & SYSCON_AHBCLKCTRL_CT32B4_MASK) +#define SYSCON_AHBCLKCTRL_ADC0_MASK (0x8000000U) +#define SYSCON_AHBCLKCTRL_ADC0_SHIFT (27U) +#define SYSCON_AHBCLKCTRL_ADC0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRL_ADC0_SHIFT)) & SYSCON_AHBCLKCTRL_ADC0_MASK) + +/* The count of SYSCON_AHBCLKCTRL */ +#define SYSCON_AHBCLKCTRL_COUNT (2U) + +/*! @name AHBCLKCTRLSET - Set bits in AHBCLKCTRL n */ +#define SYSCON_AHBCLKCTRLSET_CLK_SET_MASK (0xFFFFFFFFU) +#define SYSCON_AHBCLKCTRLSET_CLK_SET_SHIFT (0U) +#define SYSCON_AHBCLKCTRLSET_CLK_SET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLSET_CLK_SET_SHIFT)) & SYSCON_AHBCLKCTRLSET_CLK_SET_MASK) + +/* The count of SYSCON_AHBCLKCTRLSET */ +#define SYSCON_AHBCLKCTRLSET_COUNT (2U) + +/*! @name AHBCLKCTRLCLR - Clear bits in AHBCLKCTRL n */ +#define SYSCON_AHBCLKCTRLCLR_CLK_CLR_MASK (0xFFFFFFFFU) +#define SYSCON_AHBCLKCTRLCLR_CLK_CLR_SHIFT (0U) +#define SYSCON_AHBCLKCTRLCLR_CLK_CLR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKCTRLCLR_CLK_CLR_SHIFT)) & SYSCON_AHBCLKCTRLCLR_CLK_CLR_MASK) + +/* The count of SYSCON_AHBCLKCTRLCLR */ +#define SYSCON_AHBCLKCTRLCLR_COUNT (2U) + +/*! @name SYSTICKCLKDIV - SYSTICK clock divider */ +#define SYSCON_SYSTICKCLKDIV_DIV_MASK (0xFFU) +#define SYSCON_SYSTICKCLKDIV_DIV_SHIFT (0U) +#define SYSCON_SYSTICKCLKDIV_DIV(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSTICKCLKDIV_DIV_SHIFT)) & SYSCON_SYSTICKCLKDIV_DIV_MASK) + +/*! @name AHBCLKDIV - System clock divider */ +#define SYSCON_AHBCLKDIV_DIV_MASK (0xFFU) +#define SYSCON_AHBCLKDIV_DIV_SHIFT (0U) +#define SYSCON_AHBCLKDIV_DIV(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_AHBCLKDIV_DIV_SHIFT)) & SYSCON_AHBCLKDIV_DIV_MASK) + +/*! @name ADCCLKDIV - ADC clock divider */ +#define SYSCON_ADCCLKDIV_DIV_MASK (0xFFU) +#define SYSCON_ADCCLKDIV_DIV_SHIFT (0U) +#define SYSCON_ADCCLKDIV_DIV(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_ADCCLKDIV_DIV_SHIFT)) & SYSCON_ADCCLKDIV_DIV_MASK) + +/*! @name CLKOUTDIV - CLKOUT clock divider */ +#define SYSCON_CLKOUTDIV_DIV_MASK (0xFFU) +#define SYSCON_CLKOUTDIV_DIV_SHIFT (0U) +#define SYSCON_CLKOUTDIV_DIV(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_CLKOUTDIV_DIV_SHIFT)) & SYSCON_CLKOUTDIV_DIV_MASK) + +/*! @name FREQMECTRL - Frequency measure register */ +#define SYSCON_FREQMECTRL_CAPVAL_MASK (0x3FFFU) +#define SYSCON_FREQMECTRL_CAPVAL_SHIFT (0U) +#define SYSCON_FREQMECTRL_CAPVAL(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FREQMECTRL_CAPVAL_SHIFT)) & SYSCON_FREQMECTRL_CAPVAL_MASK) +#define SYSCON_FREQMECTRL_PROG_MASK (0x80000000U) +#define SYSCON_FREQMECTRL_PROG_SHIFT (31U) +#define SYSCON_FREQMECTRL_PROG(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FREQMECTRL_PROG_SHIFT)) & SYSCON_FREQMECTRL_PROG_MASK) + +/*! @name FLASHCFG - Flash wait states configuration */ +#define SYSCON_FLASHCFG_FETCHCFG_MASK (0x3U) +#define SYSCON_FLASHCFG_FETCHCFG_SHIFT (0U) +#define SYSCON_FLASHCFG_FETCHCFG(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FLASHCFG_FETCHCFG_SHIFT)) & SYSCON_FLASHCFG_FETCHCFG_MASK) +#define SYSCON_FLASHCFG_DATACFG_MASK (0xCU) +#define SYSCON_FLASHCFG_DATACFG_SHIFT (2U) +#define SYSCON_FLASHCFG_DATACFG(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FLASHCFG_DATACFG_SHIFT)) & SYSCON_FLASHCFG_DATACFG_MASK) +#define SYSCON_FLASHCFG_ACCEL_MASK (0x10U) +#define SYSCON_FLASHCFG_ACCEL_SHIFT (4U) +#define SYSCON_FLASHCFG_ACCEL(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FLASHCFG_ACCEL_SHIFT)) & SYSCON_FLASHCFG_ACCEL_MASK) +#define SYSCON_FLASHCFG_PREFEN_MASK (0x20U) +#define SYSCON_FLASHCFG_PREFEN_SHIFT (5U) +#define SYSCON_FLASHCFG_PREFEN(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FLASHCFG_PREFEN_SHIFT)) & SYSCON_FLASHCFG_PREFEN_MASK) +#define SYSCON_FLASHCFG_PREFOVR_MASK (0x40U) +#define SYSCON_FLASHCFG_PREFOVR_SHIFT (6U) +#define SYSCON_FLASHCFG_PREFOVR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FLASHCFG_PREFOVR_SHIFT)) & SYSCON_FLASHCFG_PREFOVR_MASK) +#define SYSCON_FLASHCFG_FLASHTIM_MASK (0xF000U) +#define SYSCON_FLASHCFG_FLASHTIM_SHIFT (12U) +#define SYSCON_FLASHCFG_FLASHTIM(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FLASHCFG_FLASHTIM_SHIFT)) & SYSCON_FLASHCFG_FLASHTIM_MASK) + +/*! @name FIFOCTRL - Serial interface FIFO enables */ +#define SYSCON_FIFOCTRL_U0TXFIFOEN_MASK (0x1U) +#define SYSCON_FIFOCTRL_U0TXFIFOEN_SHIFT (0U) +#define SYSCON_FIFOCTRL_U0TXFIFOEN(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FIFOCTRL_U0TXFIFOEN_SHIFT)) & SYSCON_FIFOCTRL_U0TXFIFOEN_MASK) +#define SYSCON_FIFOCTRL_U1TXFIFOEN_MASK (0x2U) +#define SYSCON_FIFOCTRL_U1TXFIFOEN_SHIFT (1U) +#define SYSCON_FIFOCTRL_U1TXFIFOEN(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FIFOCTRL_U1TXFIFOEN_SHIFT)) & SYSCON_FIFOCTRL_U1TXFIFOEN_MASK) +#define SYSCON_FIFOCTRL_U2TXFIFOEN_MASK (0x4U) +#define SYSCON_FIFOCTRL_U2TXFIFOEN_SHIFT (2U) +#define SYSCON_FIFOCTRL_U2TXFIFOEN(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FIFOCTRL_U2TXFIFOEN_SHIFT)) & SYSCON_FIFOCTRL_U2TXFIFOEN_MASK) +#define SYSCON_FIFOCTRL_U3TXFIFOEN_MASK (0x8U) +#define SYSCON_FIFOCTRL_U3TXFIFOEN_SHIFT (3U) +#define SYSCON_FIFOCTRL_U3TXFIFOEN(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FIFOCTRL_U3TXFIFOEN_SHIFT)) & SYSCON_FIFOCTRL_U3TXFIFOEN_MASK) +#define SYSCON_FIFOCTRL_SPI0TXFIFOEN_MASK (0x10U) +#define SYSCON_FIFOCTRL_SPI0TXFIFOEN_SHIFT (4U) +#define SYSCON_FIFOCTRL_SPI0TXFIFOEN(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FIFOCTRL_SPI0TXFIFOEN_SHIFT)) & SYSCON_FIFOCTRL_SPI0TXFIFOEN_MASK) +#define SYSCON_FIFOCTRL_SPI1TXFIFOEN_MASK (0x20U) +#define SYSCON_FIFOCTRL_SPI1TXFIFOEN_SHIFT (5U) +#define SYSCON_FIFOCTRL_SPI1TXFIFOEN(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FIFOCTRL_SPI1TXFIFOEN_SHIFT)) & SYSCON_FIFOCTRL_SPI1TXFIFOEN_MASK) +#define SYSCON_FIFOCTRL_U0RXFIFOEN_MASK (0x100U) +#define SYSCON_FIFOCTRL_U0RXFIFOEN_SHIFT (8U) +#define SYSCON_FIFOCTRL_U0RXFIFOEN(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FIFOCTRL_U0RXFIFOEN_SHIFT)) & SYSCON_FIFOCTRL_U0RXFIFOEN_MASK) +#define SYSCON_FIFOCTRL_U1RXFIFOEN_MASK (0x200U) +#define SYSCON_FIFOCTRL_U1RXFIFOEN_SHIFT (9U) +#define SYSCON_FIFOCTRL_U1RXFIFOEN(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FIFOCTRL_U1RXFIFOEN_SHIFT)) & SYSCON_FIFOCTRL_U1RXFIFOEN_MASK) +#define SYSCON_FIFOCTRL_U2RXFIFOEN_MASK (0x400U) +#define SYSCON_FIFOCTRL_U2RXFIFOEN_SHIFT (10U) +#define SYSCON_FIFOCTRL_U2RXFIFOEN(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FIFOCTRL_U2RXFIFOEN_SHIFT)) & SYSCON_FIFOCTRL_U2RXFIFOEN_MASK) +#define SYSCON_FIFOCTRL_U3RXFIFOEN_MASK (0x800U) +#define SYSCON_FIFOCTRL_U3RXFIFOEN_SHIFT (11U) +#define SYSCON_FIFOCTRL_U3RXFIFOEN(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FIFOCTRL_U3RXFIFOEN_SHIFT)) & SYSCON_FIFOCTRL_U3RXFIFOEN_MASK) +#define SYSCON_FIFOCTRL_SPI0RXFIFOEN_MASK (0x1000U) +#define SYSCON_FIFOCTRL_SPI0RXFIFOEN_SHIFT (12U) +#define SYSCON_FIFOCTRL_SPI0RXFIFOEN(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FIFOCTRL_SPI0RXFIFOEN_SHIFT)) & SYSCON_FIFOCTRL_SPI0RXFIFOEN_MASK) +#define SYSCON_FIFOCTRL_SPI1RXFIFOEN_MASK (0x2000U) +#define SYSCON_FIFOCTRL_SPI1RXFIFOEN_SHIFT (13U) +#define SYSCON_FIFOCTRL_SPI1RXFIFOEN(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_FIFOCTRL_SPI1RXFIFOEN_SHIFT)) & SYSCON_FIFOCTRL_SPI1RXFIFOEN_MASK) + +/*! @name IRCCTRL - IRC oscillator control */ +#define SYSCON_IRCCTRL_TRIM_MASK (0xFFU) +#define SYSCON_IRCCTRL_TRIM_SHIFT (0U) +#define SYSCON_IRCCTRL_TRIM(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_IRCCTRL_TRIM_SHIFT)) & SYSCON_IRCCTRL_TRIM_MASK) + +/*! @name RTCOSCCTRL - RTC oscillator 32 kHz output control */ +#define SYSCON_RTCOSCCTRL_EN_MASK (0x1U) +#define SYSCON_RTCOSCCTRL_EN_SHIFT (0U) +#define SYSCON_RTCOSCCTRL_EN(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_RTCOSCCTRL_EN_SHIFT)) & SYSCON_RTCOSCCTRL_EN_MASK) + +/*! @name SYSPLLCTRL - PLL control */ +#define SYSCON_SYSPLLCTRL_SELR_MASK (0xFU) +#define SYSCON_SYSPLLCTRL_SELR_SHIFT (0U) +#define SYSCON_SYSPLLCTRL_SELR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLCTRL_SELR_SHIFT)) & SYSCON_SYSPLLCTRL_SELR_MASK) +#define SYSCON_SYSPLLCTRL_SELI_MASK (0x3F0U) +#define SYSCON_SYSPLLCTRL_SELI_SHIFT (4U) +#define SYSCON_SYSPLLCTRL_SELI(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLCTRL_SELI_SHIFT)) & SYSCON_SYSPLLCTRL_SELI_MASK) +#define SYSCON_SYSPLLCTRL_SELP_MASK (0x7C00U) +#define SYSCON_SYSPLLCTRL_SELP_SHIFT (10U) +#define SYSCON_SYSPLLCTRL_SELP(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLCTRL_SELP_SHIFT)) & SYSCON_SYSPLLCTRL_SELP_MASK) +#define SYSCON_SYSPLLCTRL_BYPASS_MASK (0x8000U) +#define SYSCON_SYSPLLCTRL_BYPASS_SHIFT (15U) +#define SYSCON_SYSPLLCTRL_BYPASS(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLCTRL_BYPASS_SHIFT)) & SYSCON_SYSPLLCTRL_BYPASS_MASK) +#define SYSCON_SYSPLLCTRL_BYPASSCCODIV2_MASK (0x10000U) +#define SYSCON_SYSPLLCTRL_BYPASSCCODIV2_SHIFT (16U) +#define SYSCON_SYSPLLCTRL_BYPASSCCODIV2(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLCTRL_BYPASSCCODIV2_SHIFT)) & SYSCON_SYSPLLCTRL_BYPASSCCODIV2_MASK) +#define SYSCON_SYSPLLCTRL_UPLIMOFF_MASK (0x20000U) +#define SYSCON_SYSPLLCTRL_UPLIMOFF_SHIFT (17U) +#define SYSCON_SYSPLLCTRL_UPLIMOFF(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLCTRL_UPLIMOFF_SHIFT)) & SYSCON_SYSPLLCTRL_UPLIMOFF_MASK) +#define SYSCON_SYSPLLCTRL_BANDSEL_MASK (0x40000U) +#define SYSCON_SYSPLLCTRL_BANDSEL_SHIFT (18U) +#define SYSCON_SYSPLLCTRL_BANDSEL(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLCTRL_BANDSEL_SHIFT)) & SYSCON_SYSPLLCTRL_BANDSEL_MASK) +#define SYSCON_SYSPLLCTRL_DIRECTI_MASK (0x80000U) +#define SYSCON_SYSPLLCTRL_DIRECTI_SHIFT (19U) +#define SYSCON_SYSPLLCTRL_DIRECTI(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLCTRL_DIRECTI_SHIFT)) & SYSCON_SYSPLLCTRL_DIRECTI_MASK) +#define SYSCON_SYSPLLCTRL_DIRECTO_MASK (0x100000U) +#define SYSCON_SYSPLLCTRL_DIRECTO_SHIFT (20U) +#define SYSCON_SYSPLLCTRL_DIRECTO(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLCTRL_DIRECTO_SHIFT)) & SYSCON_SYSPLLCTRL_DIRECTO_MASK) + +/*! @name SYSPLLSTAT - PLL status */ +#define SYSCON_SYSPLLSTAT_LOCK_MASK (0x1U) +#define SYSCON_SYSPLLSTAT_LOCK_SHIFT (0U) +#define SYSCON_SYSPLLSTAT_LOCK(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLSTAT_LOCK_SHIFT)) & SYSCON_SYSPLLSTAT_LOCK_MASK) + +/*! @name SYSPLLNDEC - PLL N decoder */ +#define SYSCON_SYSPLLNDEC_NDEC_MASK (0x3FFU) +#define SYSCON_SYSPLLNDEC_NDEC_SHIFT (0U) +#define SYSCON_SYSPLLNDEC_NDEC(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLNDEC_NDEC_SHIFT)) & SYSCON_SYSPLLNDEC_NDEC_MASK) +#define SYSCON_SYSPLLNDEC_NREQ_MASK (0x400U) +#define SYSCON_SYSPLLNDEC_NREQ_SHIFT (10U) +#define SYSCON_SYSPLLNDEC_NREQ(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLNDEC_NREQ_SHIFT)) & SYSCON_SYSPLLNDEC_NREQ_MASK) + +/*! @name SYSPLLPDEC - PLL P decoder */ +#define SYSCON_SYSPLLPDEC_PDEC_MASK (0x7FU) +#define SYSCON_SYSPLLPDEC_PDEC_SHIFT (0U) +#define SYSCON_SYSPLLPDEC_PDEC(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLPDEC_PDEC_SHIFT)) & SYSCON_SYSPLLPDEC_PDEC_MASK) +#define SYSCON_SYSPLLPDEC_PREQ_MASK (0x80U) +#define SYSCON_SYSPLLPDEC_PREQ_SHIFT (7U) +#define SYSCON_SYSPLLPDEC_PREQ(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLPDEC_PREQ_SHIFT)) & SYSCON_SYSPLLPDEC_PREQ_MASK) + +/*! @name SYSPLLSSCTRL0 - PLL spread spectrum control 0 */ +#define SYSCON_SYSPLLSSCTRL0_MDEC_MASK (0x1FFFFU) +#define SYSCON_SYSPLLSSCTRL0_MDEC_SHIFT (0U) +#define SYSCON_SYSPLLSSCTRL0_MDEC(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLSSCTRL0_MDEC_SHIFT)) & SYSCON_SYSPLLSSCTRL0_MDEC_MASK) +#define SYSCON_SYSPLLSSCTRL0_MREQ_MASK (0x20000U) +#define SYSCON_SYSPLLSSCTRL0_MREQ_SHIFT (17U) +#define SYSCON_SYSPLLSSCTRL0_MREQ(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLSSCTRL0_MREQ_SHIFT)) & SYSCON_SYSPLLSSCTRL0_MREQ_MASK) +#define SYSCON_SYSPLLSSCTRL0_SEL_EXT_MASK (0x40000U) +#define SYSCON_SYSPLLSSCTRL0_SEL_EXT_SHIFT (18U) +#define SYSCON_SYSPLLSSCTRL0_SEL_EXT(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLSSCTRL0_SEL_EXT_SHIFT)) & SYSCON_SYSPLLSSCTRL0_SEL_EXT_MASK) + +/*! @name SYSPLLSSCTRL1 - PLL spread spectrum control 1 */ +#define SYSCON_SYSPLLSSCTRL1_MD_MASK (0x7FFFFU) +#define SYSCON_SYSPLLSSCTRL1_MD_SHIFT (0U) +#define SYSCON_SYSPLLSSCTRL1_MD(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLSSCTRL1_MD_SHIFT)) & SYSCON_SYSPLLSSCTRL1_MD_MASK) +#define SYSCON_SYSPLLSSCTRL1_MDREQ_MASK (0x80000U) +#define SYSCON_SYSPLLSSCTRL1_MDREQ_SHIFT (19U) +#define SYSCON_SYSPLLSSCTRL1_MDREQ(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLSSCTRL1_MDREQ_SHIFT)) & SYSCON_SYSPLLSSCTRL1_MDREQ_MASK) +#define SYSCON_SYSPLLSSCTRL1_MF_MASK (0x700000U) +#define SYSCON_SYSPLLSSCTRL1_MF_SHIFT (20U) +#define SYSCON_SYSPLLSSCTRL1_MF(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLSSCTRL1_MF_SHIFT)) & SYSCON_SYSPLLSSCTRL1_MF_MASK) +#define SYSCON_SYSPLLSSCTRL1_MR_MASK (0x3800000U) +#define SYSCON_SYSPLLSSCTRL1_MR_SHIFT (23U) +#define SYSCON_SYSPLLSSCTRL1_MR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLSSCTRL1_MR_SHIFT)) & SYSCON_SYSPLLSSCTRL1_MR_MASK) +#define SYSCON_SYSPLLSSCTRL1_MC_MASK (0xC000000U) +#define SYSCON_SYSPLLSSCTRL1_MC_SHIFT (26U) +#define SYSCON_SYSPLLSSCTRL1_MC(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLSSCTRL1_MC_SHIFT)) & SYSCON_SYSPLLSSCTRL1_MC_MASK) +#define SYSCON_SYSPLLSSCTRL1_PD_MASK (0x10000000U) +#define SYSCON_SYSPLLSSCTRL1_PD_SHIFT (28U) +#define SYSCON_SYSPLLSSCTRL1_PD(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLSSCTRL1_PD_SHIFT)) & SYSCON_SYSPLLSSCTRL1_PD_MASK) +#define SYSCON_SYSPLLSSCTRL1_DITHER_MASK (0x20000000U) +#define SYSCON_SYSPLLSSCTRL1_DITHER_SHIFT (29U) +#define SYSCON_SYSPLLSSCTRL1_DITHER(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_SYSPLLSSCTRL1_DITHER_SHIFT)) & SYSCON_SYSPLLSSCTRL1_DITHER_MASK) + +/*! @name PDRUNCFG - Power configuration register */ +#define SYSCON_PDRUNCFG_PDEN_IRC_OSC_MASK (0x8U) +#define SYSCON_PDRUNCFG_PDEN_IRC_OSC_SHIFT (3U) +#define SYSCON_PDRUNCFG_PDEN_IRC_OSC(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PDEN_IRC_OSC_SHIFT)) & SYSCON_PDRUNCFG_PDEN_IRC_OSC_MASK) +#define SYSCON_PDRUNCFG_PDEN_IRC_MASK (0x10U) +#define SYSCON_PDRUNCFG_PDEN_IRC_SHIFT (4U) +#define SYSCON_PDRUNCFG_PDEN_IRC(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PDEN_IRC_SHIFT)) & SYSCON_PDRUNCFG_PDEN_IRC_MASK) +#define SYSCON_PDRUNCFG_PDEN_FLASH_MASK (0x20U) +#define SYSCON_PDRUNCFG_PDEN_FLASH_SHIFT (5U) +#define SYSCON_PDRUNCFG_PDEN_FLASH(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PDEN_FLASH_SHIFT)) & SYSCON_PDRUNCFG_PDEN_FLASH_MASK) +#define SYSCON_PDRUNCFG_PDEN_BOD_RST_MASK (0x80U) +#define SYSCON_PDRUNCFG_PDEN_BOD_RST_SHIFT (7U) +#define SYSCON_PDRUNCFG_PDEN_BOD_RST(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PDEN_BOD_RST_SHIFT)) & SYSCON_PDRUNCFG_PDEN_BOD_RST_MASK) +#define SYSCON_PDRUNCFG_PDEN_BOD_INTR_MASK (0x100U) +#define SYSCON_PDRUNCFG_PDEN_BOD_INTR_SHIFT (8U) +#define SYSCON_PDRUNCFG_PDEN_BOD_INTR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PDEN_BOD_INTR_SHIFT)) & SYSCON_PDRUNCFG_PDEN_BOD_INTR_MASK) +#define SYSCON_PDRUNCFG_PDEN_ADC0_MASK (0x400U) +#define SYSCON_PDRUNCFG_PDEN_ADC0_SHIFT (10U) +#define SYSCON_PDRUNCFG_PDEN_ADC0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PDEN_ADC0_SHIFT)) & SYSCON_PDRUNCFG_PDEN_ADC0_MASK) +#define SYSCON_PDRUNCFG_PDEN_SRAM0A_MASK (0x2000U) +#define SYSCON_PDRUNCFG_PDEN_SRAM0A_SHIFT (13U) +#define SYSCON_PDRUNCFG_PDEN_SRAM0A(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PDEN_SRAM0A_SHIFT)) & SYSCON_PDRUNCFG_PDEN_SRAM0A_MASK) +#define SYSCON_PDRUNCFG_PDEN_SRAM0B_MASK (0x4000U) +#define SYSCON_PDRUNCFG_PDEN_SRAM0B_SHIFT (14U) +#define SYSCON_PDRUNCFG_PDEN_SRAM0B(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PDEN_SRAM0B_SHIFT)) & SYSCON_PDRUNCFG_PDEN_SRAM0B_MASK) +#define SYSCON_PDRUNCFG_PDEN_SRAM1_MASK (0x8000U) +#define SYSCON_PDRUNCFG_PDEN_SRAM1_SHIFT (15U) +#define SYSCON_PDRUNCFG_PDEN_SRAM1(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PDEN_SRAM1_SHIFT)) & SYSCON_PDRUNCFG_PDEN_SRAM1_MASK) +#define SYSCON_PDRUNCFG_PDEN_SRAM2_MASK (0x10000U) +#define SYSCON_PDRUNCFG_PDEN_SRAM2_SHIFT (16U) +#define SYSCON_PDRUNCFG_PDEN_SRAM2(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PDEN_SRAM2_SHIFT)) & SYSCON_PDRUNCFG_PDEN_SRAM2_MASK) +#define SYSCON_PDRUNCFG_PDEN_ROM_MASK (0x20000U) +#define SYSCON_PDRUNCFG_PDEN_ROM_SHIFT (17U) +#define SYSCON_PDRUNCFG_PDEN_ROM(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PDEN_ROM_SHIFT)) & SYSCON_PDRUNCFG_PDEN_ROM_MASK) +#define SYSCON_PDRUNCFG_PDEN_VDDA_MASK (0x80000U) +#define SYSCON_PDRUNCFG_PDEN_VDDA_SHIFT (19U) +#define SYSCON_PDRUNCFG_PDEN_VDDA(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PDEN_VDDA_SHIFT)) & SYSCON_PDRUNCFG_PDEN_VDDA_MASK) +#define SYSCON_PDRUNCFG_PDEN_WDT_OSC_MASK (0x100000U) +#define SYSCON_PDRUNCFG_PDEN_WDT_OSC_SHIFT (20U) +#define SYSCON_PDRUNCFG_PDEN_WDT_OSC(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PDEN_WDT_OSC_SHIFT)) & SYSCON_PDRUNCFG_PDEN_WDT_OSC_MASK) +#define SYSCON_PDRUNCFG_PDEN_SYS_PLL_MASK (0x400000U) +#define SYSCON_PDRUNCFG_PDEN_SYS_PLL_SHIFT (22U) +#define SYSCON_PDRUNCFG_PDEN_SYS_PLL(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PDEN_SYS_PLL_SHIFT)) & SYSCON_PDRUNCFG_PDEN_SYS_PLL_MASK) +#define SYSCON_PDRUNCFG_PDEN_VREFP_MASK (0x800000U) +#define SYSCON_PDRUNCFG_PDEN_VREFP_SHIFT (23U) +#define SYSCON_PDRUNCFG_PDEN_VREFP(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PDEN_VREFP_SHIFT)) & SYSCON_PDRUNCFG_PDEN_VREFP_MASK) +#define SYSCON_PDRUNCFG_PDEN_32K_OSC_MASK (0x1000000U) +#define SYSCON_PDRUNCFG_PDEN_32K_OSC_SHIFT (24U) +#define SYSCON_PDRUNCFG_PDEN_32K_OSC(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFG_PDEN_32K_OSC_SHIFT)) & SYSCON_PDRUNCFG_PDEN_32K_OSC_MASK) + +/*! @name PDRUNCFGSET - Set bits in PDRUNCFG */ +#define SYSCON_PDRUNCFGSET_PD_SET_MASK (0xFFFFFFFFU) +#define SYSCON_PDRUNCFGSET_PD_SET_SHIFT (0U) +#define SYSCON_PDRUNCFGSET_PD_SET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFGSET_PD_SET_SHIFT)) & SYSCON_PDRUNCFGSET_PD_SET_MASK) + +/*! @name PDRUNCFGCLR - Clear bits in PDRUNCFG */ +#define SYSCON_PDRUNCFGCLR_PD_CLR_MASK (0xFFFFFFFFU) +#define SYSCON_PDRUNCFGCLR_PD_CLR_SHIFT (0U) +#define SYSCON_PDRUNCFGCLR_PD_CLR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_PDRUNCFGCLR_PD_CLR_SHIFT)) & SYSCON_PDRUNCFGCLR_PD_CLR_MASK) + +/*! @name STARTER - Start logic n wake-up enable register */ +#define SYSCON_STARTER_WWDT_MASK (0x1U) +#define SYSCON_STARTER_WWDT_SHIFT (0U) +#define SYSCON_STARTER_WWDT(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_WWDT_SHIFT)) & SYSCON_STARTER_WWDT_MASK) +#define SYSCON_STARTER_GINT1_MASK (0x1U) +#define SYSCON_STARTER_GINT1_SHIFT (0U) +#define SYSCON_STARTER_GINT1(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_GINT1_SHIFT)) & SYSCON_STARTER_GINT1_MASK) +#define SYSCON_STARTER_BOD_MASK (0x2U) +#define SYSCON_STARTER_BOD_SHIFT (1U) +#define SYSCON_STARTER_BOD(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_BOD_SHIFT)) & SYSCON_STARTER_BOD_MASK) +#define SYSCON_STARTER_PINT4_MASK (0x2U) +#define SYSCON_STARTER_PINT4_SHIFT (1U) +#define SYSCON_STARTER_PINT4(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_PINT4_SHIFT)) & SYSCON_STARTER_PINT4_MASK) +#define SYSCON_STARTER_PINT5_MASK (0x4U) +#define SYSCON_STARTER_PINT5_SHIFT (2U) +#define SYSCON_STARTER_PINT5(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_PINT5_SHIFT)) & SYSCON_STARTER_PINT5_MASK) +#define SYSCON_STARTER_DMA_MASK (0x8U) +#define SYSCON_STARTER_DMA_SHIFT (3U) +#define SYSCON_STARTER_DMA(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_DMA_SHIFT)) & SYSCON_STARTER_DMA_MASK) +#define SYSCON_STARTER_PINT6_MASK (0x8U) +#define SYSCON_STARTER_PINT6_SHIFT (3U) +#define SYSCON_STARTER_PINT6(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_PINT6_SHIFT)) & SYSCON_STARTER_PINT6_MASK) +#define SYSCON_STARTER_PINT7_MASK (0x10U) +#define SYSCON_STARTER_PINT7_SHIFT (4U) +#define SYSCON_STARTER_PINT7(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_PINT7_SHIFT)) & SYSCON_STARTER_PINT7_MASK) +#define SYSCON_STARTER_GINT0_MASK (0x10U) +#define SYSCON_STARTER_GINT0_SHIFT (4U) +#define SYSCON_STARTER_GINT0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_GINT0_SHIFT)) & SYSCON_STARTER_GINT0_MASK) +#define SYSCON_STARTER_PINT0_MASK (0x20U) +#define SYSCON_STARTER_PINT0_SHIFT (5U) +#define SYSCON_STARTER_PINT0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_PINT0_SHIFT)) & SYSCON_STARTER_PINT0_MASK) +#define SYSCON_STARTER_PINT1_MASK (0x40U) +#define SYSCON_STARTER_PINT1_SHIFT (6U) +#define SYSCON_STARTER_PINT1(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_PINT1_SHIFT)) & SYSCON_STARTER_PINT1_MASK) +#define SYSCON_STARTER_PINT2_MASK (0x80U) +#define SYSCON_STARTER_PINT2_SHIFT (7U) +#define SYSCON_STARTER_PINT2(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_PINT2_SHIFT)) & SYSCON_STARTER_PINT2_MASK) +#define SYSCON_STARTER_PINT3_MASK (0x100U) +#define SYSCON_STARTER_PINT3_SHIFT (8U) +#define SYSCON_STARTER_PINT3(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_PINT3_SHIFT)) & SYSCON_STARTER_PINT3_MASK) +#define SYSCON_STARTER_RIT_MASK (0x100U) +#define SYSCON_STARTER_RIT_SHIFT (8U) +#define SYSCON_STARTER_RIT(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_RIT_SHIFT)) & SYSCON_STARTER_RIT_MASK) +#define SYSCON_STARTER_UTICK_MASK (0x200U) +#define SYSCON_STARTER_UTICK_SHIFT (9U) +#define SYSCON_STARTER_UTICK(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_UTICK_SHIFT)) & SYSCON_STARTER_UTICK_MASK) +#define SYSCON_STARTER_MRT_MASK (0x400U) +#define SYSCON_STARTER_MRT_SHIFT (10U) +#define SYSCON_STARTER_MRT(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_MRT_SHIFT)) & SYSCON_STARTER_MRT_MASK) +#define SYSCON_STARTER_CT32B0_MASK (0x800U) +#define SYSCON_STARTER_CT32B0_SHIFT (11U) +#define SYSCON_STARTER_CT32B0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_CT32B0_SHIFT)) & SYSCON_STARTER_CT32B0_MASK) +#define SYSCON_STARTER_CT32B1_MASK (0x1000U) +#define SYSCON_STARTER_CT32B1_SHIFT (12U) +#define SYSCON_STARTER_CT32B1(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_CT32B1_SHIFT)) & SYSCON_STARTER_CT32B1_MASK) +#define SYSCON_STARTER_CT32B2_MASK (0x2000U) +#define SYSCON_STARTER_CT32B2_SHIFT (13U) +#define SYSCON_STARTER_CT32B2(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_CT32B2_SHIFT)) & SYSCON_STARTER_CT32B2_MASK) +#define SYSCON_STARTER_CT32B3_MASK (0x4000U) +#define SYSCON_STARTER_CT32B3_SHIFT (14U) +#define SYSCON_STARTER_CT32B3(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_CT32B3_SHIFT)) & SYSCON_STARTER_CT32B3_MASK) +#define SYSCON_STARTER_CT32B4_MASK (0x8000U) +#define SYSCON_STARTER_CT32B4_SHIFT (15U) +#define SYSCON_STARTER_CT32B4(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_CT32B4_SHIFT)) & SYSCON_STARTER_CT32B4_MASK) +#define SYSCON_STARTER_SCT0_MASK (0x10000U) +#define SYSCON_STARTER_SCT0_SHIFT (16U) +#define SYSCON_STARTER_SCT0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_SCT0_SHIFT)) & SYSCON_STARTER_SCT0_MASK) +#define SYSCON_STARTER_USART0_MASK (0x20000U) +#define SYSCON_STARTER_USART0_SHIFT (17U) +#define SYSCON_STARTER_USART0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_USART0_SHIFT)) & SYSCON_STARTER_USART0_MASK) +#define SYSCON_STARTER_USART1_MASK (0x40000U) +#define SYSCON_STARTER_USART1_SHIFT (18U) +#define SYSCON_STARTER_USART1(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_USART1_SHIFT)) & SYSCON_STARTER_USART1_MASK) +#define SYSCON_STARTER_USART2_MASK (0x80000U) +#define SYSCON_STARTER_USART2_SHIFT (19U) +#define SYSCON_STARTER_USART2(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_USART2_SHIFT)) & SYSCON_STARTER_USART2_MASK) +#define SYSCON_STARTER_USART3_MASK (0x100000U) +#define SYSCON_STARTER_USART3_SHIFT (20U) +#define SYSCON_STARTER_USART3(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_USART3_SHIFT)) & SYSCON_STARTER_USART3_MASK) +#define SYSCON_STARTER_I2C0_MASK (0x200000U) +#define SYSCON_STARTER_I2C0_SHIFT (21U) +#define SYSCON_STARTER_I2C0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_I2C0_SHIFT)) & SYSCON_STARTER_I2C0_MASK) +#define SYSCON_STARTER_I2C1_MASK (0x400000U) +#define SYSCON_STARTER_I2C1_SHIFT (22U) +#define SYSCON_STARTER_I2C1(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_I2C1_SHIFT)) & SYSCON_STARTER_I2C1_MASK) +#define SYSCON_STARTER_I2C2_MASK (0x800000U) +#define SYSCON_STARTER_I2C2_SHIFT (23U) +#define SYSCON_STARTER_I2C2(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_I2C2_SHIFT)) & SYSCON_STARTER_I2C2_MASK) +#define SYSCON_STARTER_SPI0_MASK (0x1000000U) +#define SYSCON_STARTER_SPI0_SHIFT (24U) +#define SYSCON_STARTER_SPI0(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_SPI0_SHIFT)) & SYSCON_STARTER_SPI0_MASK) +#define SYSCON_STARTER_SPI1_MASK (0x2000000U) +#define SYSCON_STARTER_SPI1_SHIFT (25U) +#define SYSCON_STARTER_SPI1(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_SPI1_SHIFT)) & SYSCON_STARTER_SPI1_MASK) +#define SYSCON_STARTER_ADC0_SEQA_MASK (0x4000000U) +#define SYSCON_STARTER_ADC0_SEQA_SHIFT (26U) +#define SYSCON_STARTER_ADC0_SEQA(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_ADC0_SEQA_SHIFT)) & SYSCON_STARTER_ADC0_SEQA_MASK) +#define SYSCON_STARTER_ADC0_SEQB_MASK (0x8000000U) +#define SYSCON_STARTER_ADC0_SEQB_SHIFT (27U) +#define SYSCON_STARTER_ADC0_SEQB(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_ADC0_SEQB_SHIFT)) & SYSCON_STARTER_ADC0_SEQB_MASK) +#define SYSCON_STARTER_ADC0_THCMP_MASK (0x10000000U) +#define SYSCON_STARTER_ADC0_THCMP_SHIFT (28U) +#define SYSCON_STARTER_ADC0_THCMP(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_ADC0_THCMP_SHIFT)) & SYSCON_STARTER_ADC0_THCMP_MASK) +#define SYSCON_STARTER_RTC_MASK (0x20000000U) +#define SYSCON_STARTER_RTC_SHIFT (29U) +#define SYSCON_STARTER_RTC(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_RTC_SHIFT)) & SYSCON_STARTER_RTC_MASK) +#define SYSCON_STARTER_MAILBOX_MASK (0x80000000U) +#define SYSCON_STARTER_MAILBOX_SHIFT (31U) +#define SYSCON_STARTER_MAILBOX(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTER_MAILBOX_SHIFT)) & SYSCON_STARTER_MAILBOX_MASK) + +/* The count of SYSCON_STARTER */ +#define SYSCON_STARTER_COUNT (2U) + +/*! @name STARTERSET - Set bits in STARTERP n */ +#define SYSCON_STARTERSET_START_SET_MASK (0xFFFFFFFFU) +#define SYSCON_STARTERSET_START_SET_SHIFT (0U) +#define SYSCON_STARTERSET_START_SET(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERSET_START_SET_SHIFT)) & SYSCON_STARTERSET_START_SET_MASK) + +/* The count of SYSCON_STARTERSET */ +#define SYSCON_STARTERSET_COUNT (2U) + +/*! @name STARTERCLR - Clear bits in STARTER n */ +#define SYSCON_STARTERCLR_START_CLR_MASK (0xFFFFFFFFU) +#define SYSCON_STARTERCLR_START_CLR_SHIFT (0U) +#define SYSCON_STARTERCLR_START_CLR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_STARTERCLR_START_CLR_SHIFT)) & SYSCON_STARTERCLR_START_CLR_MASK) + +/* The count of SYSCON_STARTERCLR */ +#define SYSCON_STARTERCLR_COUNT (2U) + +/*! @name CPUCTRL - CPU Control for multiple processors */ +#define SYSCON_CPUCTRL_MASTERCPU_MASK (0x1U) +#define SYSCON_CPUCTRL_MASTERCPU_SHIFT (0U) +#define SYSCON_CPUCTRL_MASTERCPU(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_CPUCTRL_MASTERCPU_SHIFT)) & SYSCON_CPUCTRL_MASTERCPU_MASK) +#define SYSCON_CPUCTRL_CM4CLKEN_MASK (0x4U) +#define SYSCON_CPUCTRL_CM4CLKEN_SHIFT (2U) +#define SYSCON_CPUCTRL_CM4CLKEN(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_CPUCTRL_CM4CLKEN_SHIFT)) & SYSCON_CPUCTRL_CM4CLKEN_MASK) +#define SYSCON_CPUCTRL_CM0CLKEN_MASK (0x8U) +#define SYSCON_CPUCTRL_CM0CLKEN_SHIFT (3U) +#define SYSCON_CPUCTRL_CM0CLKEN(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_CPUCTRL_CM0CLKEN_SHIFT)) & SYSCON_CPUCTRL_CM0CLKEN_MASK) +#define SYSCON_CPUCTRL_CM4RSTEN_MASK (0x10U) +#define SYSCON_CPUCTRL_CM4RSTEN_SHIFT (4U) +#define SYSCON_CPUCTRL_CM4RSTEN(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_CPUCTRL_CM4RSTEN_SHIFT)) & SYSCON_CPUCTRL_CM4RSTEN_MASK) +#define SYSCON_CPUCTRL_CM0RSTEN_MASK (0x20U) +#define SYSCON_CPUCTRL_CM0RSTEN_SHIFT (5U) +#define SYSCON_CPUCTRL_CM0RSTEN(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_CPUCTRL_CM0RSTEN_SHIFT)) & SYSCON_CPUCTRL_CM0RSTEN_MASK) +#define SYSCON_CPUCTRL_POWERCPU_MASK (0x40U) +#define SYSCON_CPUCTRL_POWERCPU_SHIFT (6U) +#define SYSCON_CPUCTRL_POWERCPU(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_CPUCTRL_POWERCPU_SHIFT)) & SYSCON_CPUCTRL_POWERCPU_MASK) + +/*! @name CPBOOT - Coprocessor Boot Address */ +#define SYSCON_CPBOOT_BOOTADDR_MASK (0xFFFFFFFFU) +#define SYSCON_CPBOOT_BOOTADDR_SHIFT (0U) +#define SYSCON_CPBOOT_BOOTADDR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_CPBOOT_BOOTADDR_SHIFT)) & SYSCON_CPBOOT_BOOTADDR_MASK) + +/*! @name CPSTACK - Coprocessor Stack Address */ +#define SYSCON_CPSTACK_STACKADDR_MASK (0xFFFFFFFFU) +#define SYSCON_CPSTACK_STACKADDR_SHIFT (0U) +#define SYSCON_CPSTACK_STACKADDR(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_CPSTACK_STACKADDR_SHIFT)) & SYSCON_CPSTACK_STACKADDR_MASK) + +/*! @name CPSTAT - Coprocessor Status */ +#define SYSCON_CPSTAT_CM4SLEEPING_MASK (0x1U) +#define SYSCON_CPSTAT_CM4SLEEPING_SHIFT (0U) +#define SYSCON_CPSTAT_CM4SLEEPING(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_CPSTAT_CM4SLEEPING_SHIFT)) & SYSCON_CPSTAT_CM4SLEEPING_MASK) +#define SYSCON_CPSTAT_CM0SLEEPING_MASK (0x2U) +#define SYSCON_CPSTAT_CM0SLEEPING_SHIFT (1U) +#define SYSCON_CPSTAT_CM0SLEEPING(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_CPSTAT_CM0SLEEPING_SHIFT)) & SYSCON_CPSTAT_CM0SLEEPING_MASK) +#define SYSCON_CPSTAT_CM4LOCKUP_MASK (0x4U) +#define SYSCON_CPSTAT_CM4LOCKUP_SHIFT (2U) +#define SYSCON_CPSTAT_CM4LOCKUP(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_CPSTAT_CM4LOCKUP_SHIFT)) & SYSCON_CPSTAT_CM4LOCKUP_MASK) +#define SYSCON_CPSTAT_CM0LOCKUP_MASK (0x8U) +#define SYSCON_CPSTAT_CM0LOCKUP_SHIFT (3U) +#define SYSCON_CPSTAT_CM0LOCKUP(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_CPSTAT_CM0LOCKUP_SHIFT)) & SYSCON_CPSTAT_CM0LOCKUP_MASK) + +/*! @name JTAGIDCODE - JTAG ID code register */ +#define SYSCON_JTAGIDCODE_JTAGID_MASK (0xFFFFFFFFU) +#define SYSCON_JTAGIDCODE_JTAGID_SHIFT (0U) +#define SYSCON_JTAGIDCODE_JTAGID(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_JTAGIDCODE_JTAGID_SHIFT)) & SYSCON_JTAGIDCODE_JTAGID_MASK) + +/*! @name DEVICE_ID - Part ID register */ +#define SYSCON_DEVICE_ID_PARTID_MASK (0xFFFFFFFFU) +#define SYSCON_DEVICE_ID_PARTID_SHIFT (0U) +#define SYSCON_DEVICE_ID_PARTID(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_DEVICE_ID_PARTID_SHIFT)) & SYSCON_DEVICE_ID_PARTID_MASK) +#define SYSCON_DEVICE_ID_REVID_MASK (0xFFFFFFFFU) +#define SYSCON_DEVICE_ID_REVID_SHIFT (0U) +#define SYSCON_DEVICE_ID_REVID(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_DEVICE_ID_REVID_SHIFT)) & SYSCON_DEVICE_ID_REVID_MASK) + +/* The count of SYSCON_DEVICE_ID */ +#define SYSCON_DEVICE_ID_COUNT (2U) + +/*! @name BODCTRL - Brown-Out Detect control */ +#define SYSCON_BODCTRL_BODRSTLEV_MASK (0x3U) +#define SYSCON_BODCTRL_BODRSTLEV_SHIFT (0U) +#define SYSCON_BODCTRL_BODRSTLEV(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_BODCTRL_BODRSTLEV_SHIFT)) & SYSCON_BODCTRL_BODRSTLEV_MASK) +#define SYSCON_BODCTRL_BODRSTENA_MASK (0x4U) +#define SYSCON_BODCTRL_BODRSTENA_SHIFT (2U) +#define SYSCON_BODCTRL_BODRSTENA(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_BODCTRL_BODRSTENA_SHIFT)) & SYSCON_BODCTRL_BODRSTENA_MASK) +#define SYSCON_BODCTRL_BODINTLEV_MASK (0x18U) +#define SYSCON_BODCTRL_BODINTLEV_SHIFT (3U) +#define SYSCON_BODCTRL_BODINTLEV(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_BODCTRL_BODINTLEV_SHIFT)) & SYSCON_BODCTRL_BODINTLEV_MASK) +#define SYSCON_BODCTRL_BODINTENA_MASK (0x20U) +#define SYSCON_BODCTRL_BODINTENA_SHIFT (5U) +#define SYSCON_BODCTRL_BODINTENA(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_BODCTRL_BODINTENA_SHIFT)) & SYSCON_BODCTRL_BODINTENA_MASK) +#define SYSCON_BODCTRL_BODRSTSTAT_MASK (0x40U) +#define SYSCON_BODCTRL_BODRSTSTAT_SHIFT (6U) +#define SYSCON_BODCTRL_BODRSTSTAT(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_BODCTRL_BODRSTSTAT_SHIFT)) & SYSCON_BODCTRL_BODRSTSTAT_MASK) +#define SYSCON_BODCTRL_BODINTSTAT_MASK (0x80U) +#define SYSCON_BODCTRL_BODINTSTAT_SHIFT (7U) +#define SYSCON_BODCTRL_BODINTSTAT(x) (((uint32_t)(((uint32_t)(x)) << SYSCON_BODCTRL_BODINTSTAT_SHIFT)) & SYSCON_BODCTRL_BODINTSTAT_MASK) + + +/*! + * @} + */ /* end of group SYSCON_Register_Masks */ + + +/* SYSCON - Peripheral instance base addresses */ +/** Peripheral SYSCON base address */ +#define SYSCON_BASE (0x40000000u) +/** Peripheral SYSCON base pointer */ +#define SYSCON ((SYSCON_Type *)SYSCON_BASE) +/** Array initializer of SYSCON peripheral base addresses */ +#define SYSCON_BASE_ADDRS { SYSCON_BASE } +/** Array initializer of SYSCON peripheral base pointers */ +#define SYSCON_BASE_PTRS { SYSCON } + +/*! + * @} + */ /* end of group SYSCON_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- USART Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup USART_Peripheral_Access_Layer USART Peripheral Access Layer + * @{ + */ + +/** USART - Register Layout Typedef */ +typedef struct { + __IO uint32_t CFG; /**< USART Configuration register. Basic USART configuration settings that typically are not changed during operation., offset: 0x0 */ + __IO uint32_t CTL; /**< USART Control register. USART control settings that are more likely to change during operation., offset: 0x4 */ + __IO uint32_t STAT; /**< USART Status register. The complete status value can be read here. Writing ones clears some bits in the register. Some bits can be cleared by writing a 1 to them., offset: 0x8 */ + __IO uint32_t INTENSET; /**< Interrupt Enable read and Set register. Contains an individual interrupt enable bit for each potential USART interrupt. A complete value may be read from this register. Writing a 1 to any implemented bit position causes that bit to be set., offset: 0xC */ + __IO uint32_t INTENCLR; /**< Interrupt Enable Clear register. Allows clearing any combination of bits in the INTENSET register. Writing a 1 to any implemented bit position causes the corresponding bit to be cleared., offset: 0x10 */ + __IO uint32_t RXDAT; /**< Receiver Data register. Contains the last character received., offset: 0x14 */ + __IO uint32_t RXDATSTAT; /**< Receiver Data with Status register. Combines the last character received with the current USART receive status. Allows DMA or software to recover incoming data and status together., offset: 0x18 */ + __IO uint32_t TXDAT; /**< Transmit Data register. Data to be transmitted is written here., offset: 0x1C */ + __IO uint32_t BRG; /**< Baud Rate Generator register. 16-bit integer baud rate divisor value., offset: 0x20 */ + __IO uint32_t INTSTAT; /**< Interrupt status register. Reflects interrupts that are currently enabled., offset: 0x24 */ + __IO uint32_t OSR; /**< Oversample selection register for asynchronous communication., offset: 0x28 */ + __IO uint32_t ADDR; /**< Address register for automatic address matching., offset: 0x2C */ +} USART_Type; + +/* ---------------------------------------------------------------------------- + -- USART Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup USART_Register_Masks USART Register Masks + * @{ + */ + +/*! @name CFG - USART Configuration register. Basic USART configuration settings that typically are not changed during operation. */ +#define USART_CFG_ENABLE_MASK (0x1U) +#define USART_CFG_ENABLE_SHIFT (0U) +#define USART_CFG_ENABLE(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_ENABLE_SHIFT)) & USART_CFG_ENABLE_MASK) +#define USART_CFG_DATALEN_MASK (0xCU) +#define USART_CFG_DATALEN_SHIFT (2U) +#define USART_CFG_DATALEN(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_DATALEN_SHIFT)) & USART_CFG_DATALEN_MASK) +#define USART_CFG_PARITYSEL_MASK (0x30U) +#define USART_CFG_PARITYSEL_SHIFT (4U) +#define USART_CFG_PARITYSEL(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_PARITYSEL_SHIFT)) & USART_CFG_PARITYSEL_MASK) +#define USART_CFG_STOPLEN_MASK (0x40U) +#define USART_CFG_STOPLEN_SHIFT (6U) +#define USART_CFG_STOPLEN(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_STOPLEN_SHIFT)) & USART_CFG_STOPLEN_MASK) +#define USART_CFG_MODE32K_MASK (0x80U) +#define USART_CFG_MODE32K_SHIFT (7U) +#define USART_CFG_MODE32K(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_MODE32K_SHIFT)) & USART_CFG_MODE32K_MASK) +#define USART_CFG_LINMODE_MASK (0x100U) +#define USART_CFG_LINMODE_SHIFT (8U) +#define USART_CFG_LINMODE(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_LINMODE_SHIFT)) & USART_CFG_LINMODE_MASK) +#define USART_CFG_CTSEN_MASK (0x200U) +#define USART_CFG_CTSEN_SHIFT (9U) +#define USART_CFG_CTSEN(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_CTSEN_SHIFT)) & USART_CFG_CTSEN_MASK) +#define USART_CFG_SYNCEN_MASK (0x800U) +#define USART_CFG_SYNCEN_SHIFT (11U) +#define USART_CFG_SYNCEN(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_SYNCEN_SHIFT)) & USART_CFG_SYNCEN_MASK) +#define USART_CFG_CLKPOL_MASK (0x1000U) +#define USART_CFG_CLKPOL_SHIFT (12U) +#define USART_CFG_CLKPOL(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_CLKPOL_SHIFT)) & USART_CFG_CLKPOL_MASK) +#define USART_CFG_SYNCMST_MASK (0x4000U) +#define USART_CFG_SYNCMST_SHIFT (14U) +#define USART_CFG_SYNCMST(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_SYNCMST_SHIFT)) & USART_CFG_SYNCMST_MASK) +#define USART_CFG_LOOP_MASK (0x8000U) +#define USART_CFG_LOOP_SHIFT (15U) +#define USART_CFG_LOOP(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_LOOP_SHIFT)) & USART_CFG_LOOP_MASK) +#define USART_CFG_OETA_MASK (0x40000U) +#define USART_CFG_OETA_SHIFT (18U) +#define USART_CFG_OETA(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_OETA_SHIFT)) & USART_CFG_OETA_MASK) +#define USART_CFG_AUTOADDR_MASK (0x80000U) +#define USART_CFG_AUTOADDR_SHIFT (19U) +#define USART_CFG_AUTOADDR(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_AUTOADDR_SHIFT)) & USART_CFG_AUTOADDR_MASK) +#define USART_CFG_OESEL_MASK (0x100000U) +#define USART_CFG_OESEL_SHIFT (20U) +#define USART_CFG_OESEL(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_OESEL_SHIFT)) & USART_CFG_OESEL_MASK) +#define USART_CFG_OEPOL_MASK (0x200000U) +#define USART_CFG_OEPOL_SHIFT (21U) +#define USART_CFG_OEPOL(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_OEPOL_SHIFT)) & USART_CFG_OEPOL_MASK) +#define USART_CFG_RXPOL_MASK (0x400000U) +#define USART_CFG_RXPOL_SHIFT (22U) +#define USART_CFG_RXPOL(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_RXPOL_SHIFT)) & USART_CFG_RXPOL_MASK) +#define USART_CFG_TXPOL_MASK (0x800000U) +#define USART_CFG_TXPOL_SHIFT (23U) +#define USART_CFG_TXPOL(x) (((uint32_t)(((uint32_t)(x)) << USART_CFG_TXPOL_SHIFT)) & USART_CFG_TXPOL_MASK) + +/*! @name CTL - USART Control register. USART control settings that are more likely to change during operation. */ +#define USART_CTL_TXBRKEN_MASK (0x2U) +#define USART_CTL_TXBRKEN_SHIFT (1U) +#define USART_CTL_TXBRKEN(x) (((uint32_t)(((uint32_t)(x)) << USART_CTL_TXBRKEN_SHIFT)) & USART_CTL_TXBRKEN_MASK) +#define USART_CTL_ADDRDET_MASK (0x4U) +#define USART_CTL_ADDRDET_SHIFT (2U) +#define USART_CTL_ADDRDET(x) (((uint32_t)(((uint32_t)(x)) << USART_CTL_ADDRDET_SHIFT)) & USART_CTL_ADDRDET_MASK) +#define USART_CTL_TXDIS_MASK (0x40U) +#define USART_CTL_TXDIS_SHIFT (6U) +#define USART_CTL_TXDIS(x) (((uint32_t)(((uint32_t)(x)) << USART_CTL_TXDIS_SHIFT)) & USART_CTL_TXDIS_MASK) +#define USART_CTL_CC_MASK (0x100U) +#define USART_CTL_CC_SHIFT (8U) +#define USART_CTL_CC(x) (((uint32_t)(((uint32_t)(x)) << USART_CTL_CC_SHIFT)) & USART_CTL_CC_MASK) +#define USART_CTL_CLRCCONRX_MASK (0x200U) +#define USART_CTL_CLRCCONRX_SHIFT (9U) +#define USART_CTL_CLRCCONRX(x) (((uint32_t)(((uint32_t)(x)) << USART_CTL_CLRCCONRX_SHIFT)) & USART_CTL_CLRCCONRX_MASK) +#define USART_CTL_AUTOBAUD_MASK (0x10000U) +#define USART_CTL_AUTOBAUD_SHIFT (16U) +#define USART_CTL_AUTOBAUD(x) (((uint32_t)(((uint32_t)(x)) << USART_CTL_AUTOBAUD_SHIFT)) & USART_CTL_AUTOBAUD_MASK) + +/*! @name STAT - USART Status register. The complete status value can be read here. Writing ones clears some bits in the register. Some bits can be cleared by writing a 1 to them. */ +#define USART_STAT_RXRDY_MASK (0x1U) +#define USART_STAT_RXRDY_SHIFT (0U) +#define USART_STAT_RXRDY(x) (((uint32_t)(((uint32_t)(x)) << USART_STAT_RXRDY_SHIFT)) & USART_STAT_RXRDY_MASK) +#define USART_STAT_RXIDLE_MASK (0x2U) +#define USART_STAT_RXIDLE_SHIFT (1U) +#define USART_STAT_RXIDLE(x) (((uint32_t)(((uint32_t)(x)) << USART_STAT_RXIDLE_SHIFT)) & USART_STAT_RXIDLE_MASK) +#define USART_STAT_TXRDY_MASK (0x4U) +#define USART_STAT_TXRDY_SHIFT (2U) +#define USART_STAT_TXRDY(x) (((uint32_t)(((uint32_t)(x)) << USART_STAT_TXRDY_SHIFT)) & USART_STAT_TXRDY_MASK) +#define USART_STAT_TXIDLE_MASK (0x8U) +#define USART_STAT_TXIDLE_SHIFT (3U) +#define USART_STAT_TXIDLE(x) (((uint32_t)(((uint32_t)(x)) << USART_STAT_TXIDLE_SHIFT)) & USART_STAT_TXIDLE_MASK) +#define USART_STAT_CTS_MASK (0x10U) +#define USART_STAT_CTS_SHIFT (4U) +#define USART_STAT_CTS(x) (((uint32_t)(((uint32_t)(x)) << USART_STAT_CTS_SHIFT)) & USART_STAT_CTS_MASK) +#define USART_STAT_DELTACTS_MASK (0x20U) +#define USART_STAT_DELTACTS_SHIFT (5U) +#define USART_STAT_DELTACTS(x) (((uint32_t)(((uint32_t)(x)) << USART_STAT_DELTACTS_SHIFT)) & USART_STAT_DELTACTS_MASK) +#define USART_STAT_TXDISSTAT_MASK (0x40U) +#define USART_STAT_TXDISSTAT_SHIFT (6U) +#define USART_STAT_TXDISSTAT(x) (((uint32_t)(((uint32_t)(x)) << USART_STAT_TXDISSTAT_SHIFT)) & USART_STAT_TXDISSTAT_MASK) +#define USART_STAT_OVERRUNINT_MASK (0x100U) +#define USART_STAT_OVERRUNINT_SHIFT (8U) +#define USART_STAT_OVERRUNINT(x) (((uint32_t)(((uint32_t)(x)) << USART_STAT_OVERRUNINT_SHIFT)) & USART_STAT_OVERRUNINT_MASK) +#define USART_STAT_RXBRK_MASK (0x400U) +#define USART_STAT_RXBRK_SHIFT (10U) +#define USART_STAT_RXBRK(x) (((uint32_t)(((uint32_t)(x)) << USART_STAT_RXBRK_SHIFT)) & USART_STAT_RXBRK_MASK) +#define USART_STAT_DELTARXBRK_MASK (0x800U) +#define USART_STAT_DELTARXBRK_SHIFT (11U) +#define USART_STAT_DELTARXBRK(x) (((uint32_t)(((uint32_t)(x)) << USART_STAT_DELTARXBRK_SHIFT)) & USART_STAT_DELTARXBRK_MASK) +#define USART_STAT_START_MASK (0x1000U) +#define USART_STAT_START_SHIFT (12U) +#define USART_STAT_START(x) (((uint32_t)(((uint32_t)(x)) << USART_STAT_START_SHIFT)) & USART_STAT_START_MASK) +#define USART_STAT_FRAMERRINT_MASK (0x2000U) +#define USART_STAT_FRAMERRINT_SHIFT (13U) +#define USART_STAT_FRAMERRINT(x) (((uint32_t)(((uint32_t)(x)) << USART_STAT_FRAMERRINT_SHIFT)) & USART_STAT_FRAMERRINT_MASK) +#define USART_STAT_PARITYERRINT_MASK (0x4000U) +#define USART_STAT_PARITYERRINT_SHIFT (14U) +#define USART_STAT_PARITYERRINT(x) (((uint32_t)(((uint32_t)(x)) << USART_STAT_PARITYERRINT_SHIFT)) & USART_STAT_PARITYERRINT_MASK) +#define USART_STAT_RXNOISEINT_MASK (0x8000U) +#define USART_STAT_RXNOISEINT_SHIFT (15U) +#define USART_STAT_RXNOISEINT(x) (((uint32_t)(((uint32_t)(x)) << USART_STAT_RXNOISEINT_SHIFT)) & USART_STAT_RXNOISEINT_MASK) +#define USART_STAT_ABERR_MASK (0x10000U) +#define USART_STAT_ABERR_SHIFT (16U) +#define USART_STAT_ABERR(x) (((uint32_t)(((uint32_t)(x)) << USART_STAT_ABERR_SHIFT)) & USART_STAT_ABERR_MASK) + +/*! @name INTENSET - Interrupt Enable read and Set register. Contains an individual interrupt enable bit for each potential USART interrupt. A complete value may be read from this register. Writing a 1 to any implemented bit position causes that bit to be set. */ +#define USART_INTENSET_RXRDYEN_MASK (0x1U) +#define USART_INTENSET_RXRDYEN_SHIFT (0U) +#define USART_INTENSET_RXRDYEN(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_RXRDYEN_SHIFT)) & USART_INTENSET_RXRDYEN_MASK) +#define USART_INTENSET_TXRDYEN_MASK (0x4U) +#define USART_INTENSET_TXRDYEN_SHIFT (2U) +#define USART_INTENSET_TXRDYEN(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_TXRDYEN_SHIFT)) & USART_INTENSET_TXRDYEN_MASK) +#define USART_INTENSET_TXIDLEEN_MASK (0x8U) +#define USART_INTENSET_TXIDLEEN_SHIFT (3U) +#define USART_INTENSET_TXIDLEEN(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_TXIDLEEN_SHIFT)) & USART_INTENSET_TXIDLEEN_MASK) +#define USART_INTENSET_DELTACTSEN_MASK (0x20U) +#define USART_INTENSET_DELTACTSEN_SHIFT (5U) +#define USART_INTENSET_DELTACTSEN(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_DELTACTSEN_SHIFT)) & USART_INTENSET_DELTACTSEN_MASK) +#define USART_INTENSET_TXDISEN_MASK (0x40U) +#define USART_INTENSET_TXDISEN_SHIFT (6U) +#define USART_INTENSET_TXDISEN(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_TXDISEN_SHIFT)) & USART_INTENSET_TXDISEN_MASK) +#define USART_INTENSET_OVERRUNEN_MASK (0x100U) +#define USART_INTENSET_OVERRUNEN_SHIFT (8U) +#define USART_INTENSET_OVERRUNEN(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_OVERRUNEN_SHIFT)) & USART_INTENSET_OVERRUNEN_MASK) +#define USART_INTENSET_DELTARXBRKEN_MASK (0x800U) +#define USART_INTENSET_DELTARXBRKEN_SHIFT (11U) +#define USART_INTENSET_DELTARXBRKEN(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_DELTARXBRKEN_SHIFT)) & USART_INTENSET_DELTARXBRKEN_MASK) +#define USART_INTENSET_STARTEN_MASK (0x1000U) +#define USART_INTENSET_STARTEN_SHIFT (12U) +#define USART_INTENSET_STARTEN(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_STARTEN_SHIFT)) & USART_INTENSET_STARTEN_MASK) +#define USART_INTENSET_FRAMERREN_MASK (0x2000U) +#define USART_INTENSET_FRAMERREN_SHIFT (13U) +#define USART_INTENSET_FRAMERREN(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_FRAMERREN_SHIFT)) & USART_INTENSET_FRAMERREN_MASK) +#define USART_INTENSET_PARITYERREN_MASK (0x4000U) +#define USART_INTENSET_PARITYERREN_SHIFT (14U) +#define USART_INTENSET_PARITYERREN(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_PARITYERREN_SHIFT)) & USART_INTENSET_PARITYERREN_MASK) +#define USART_INTENSET_RXNOISEEN_MASK (0x8000U) +#define USART_INTENSET_RXNOISEEN_SHIFT (15U) +#define USART_INTENSET_RXNOISEEN(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_RXNOISEEN_SHIFT)) & USART_INTENSET_RXNOISEEN_MASK) +#define USART_INTENSET_ABERREN_MASK (0x10000U) +#define USART_INTENSET_ABERREN_SHIFT (16U) +#define USART_INTENSET_ABERREN(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENSET_ABERREN_SHIFT)) & USART_INTENSET_ABERREN_MASK) + +/*! @name INTENCLR - Interrupt Enable Clear register. Allows clearing any combination of bits in the INTENSET register. Writing a 1 to any implemented bit position causes the corresponding bit to be cleared. */ +#define USART_INTENCLR_RXRDYCLR_MASK (0x1U) +#define USART_INTENCLR_RXRDYCLR_SHIFT (0U) +#define USART_INTENCLR_RXRDYCLR(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_RXRDYCLR_SHIFT)) & USART_INTENCLR_RXRDYCLR_MASK) +#define USART_INTENCLR_TXRDYCLR_MASK (0x4U) +#define USART_INTENCLR_TXRDYCLR_SHIFT (2U) +#define USART_INTENCLR_TXRDYCLR(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_TXRDYCLR_SHIFT)) & USART_INTENCLR_TXRDYCLR_MASK) +#define USART_INTENCLR_TXIDLECLR_MASK (0x8U) +#define USART_INTENCLR_TXIDLECLR_SHIFT (3U) +#define USART_INTENCLR_TXIDLECLR(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_TXIDLECLR_SHIFT)) & USART_INTENCLR_TXIDLECLR_MASK) +#define USART_INTENCLR_DELTACTSCLR_MASK (0x20U) +#define USART_INTENCLR_DELTACTSCLR_SHIFT (5U) +#define USART_INTENCLR_DELTACTSCLR(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_DELTACTSCLR_SHIFT)) & USART_INTENCLR_DELTACTSCLR_MASK) +#define USART_INTENCLR_TXDISCLR_MASK (0x40U) +#define USART_INTENCLR_TXDISCLR_SHIFT (6U) +#define USART_INTENCLR_TXDISCLR(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_TXDISCLR_SHIFT)) & USART_INTENCLR_TXDISCLR_MASK) +#define USART_INTENCLR_OVERRUNCLR_MASK (0x100U) +#define USART_INTENCLR_OVERRUNCLR_SHIFT (8U) +#define USART_INTENCLR_OVERRUNCLR(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_OVERRUNCLR_SHIFT)) & USART_INTENCLR_OVERRUNCLR_MASK) +#define USART_INTENCLR_DELTARXBRKCLR_MASK (0x800U) +#define USART_INTENCLR_DELTARXBRKCLR_SHIFT (11U) +#define USART_INTENCLR_DELTARXBRKCLR(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_DELTARXBRKCLR_SHIFT)) & USART_INTENCLR_DELTARXBRKCLR_MASK) +#define USART_INTENCLR_STARTCLR_MASK (0x1000U) +#define USART_INTENCLR_STARTCLR_SHIFT (12U) +#define USART_INTENCLR_STARTCLR(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_STARTCLR_SHIFT)) & USART_INTENCLR_STARTCLR_MASK) +#define USART_INTENCLR_FRAMERRCLR_MASK (0x2000U) +#define USART_INTENCLR_FRAMERRCLR_SHIFT (13U) +#define USART_INTENCLR_FRAMERRCLR(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_FRAMERRCLR_SHIFT)) & USART_INTENCLR_FRAMERRCLR_MASK) +#define USART_INTENCLR_PARITYERRCLR_MASK (0x4000U) +#define USART_INTENCLR_PARITYERRCLR_SHIFT (14U) +#define USART_INTENCLR_PARITYERRCLR(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_PARITYERRCLR_SHIFT)) & USART_INTENCLR_PARITYERRCLR_MASK) +#define USART_INTENCLR_RXNOISECLR_MASK (0x8000U) +#define USART_INTENCLR_RXNOISECLR_SHIFT (15U) +#define USART_INTENCLR_RXNOISECLR(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_RXNOISECLR_SHIFT)) & USART_INTENCLR_RXNOISECLR_MASK) +#define USART_INTENCLR_ABERRCLR_MASK (0x10000U) +#define USART_INTENCLR_ABERRCLR_SHIFT (16U) +#define USART_INTENCLR_ABERRCLR(x) (((uint32_t)(((uint32_t)(x)) << USART_INTENCLR_ABERRCLR_SHIFT)) & USART_INTENCLR_ABERRCLR_MASK) + +/*! @name RXDAT - Receiver Data register. Contains the last character received. */ +#define USART_RXDAT_DATA_MASK (0x1FFU) +#define USART_RXDAT_DATA_SHIFT (0U) +#define USART_RXDAT_DATA(x) (((uint32_t)(((uint32_t)(x)) << USART_RXDAT_DATA_SHIFT)) & USART_RXDAT_DATA_MASK) + +/*! @name RXDATSTAT - Receiver Data with Status register. Combines the last character received with the current USART receive status. Allows DMA or software to recover incoming data and status together. */ +#define USART_RXDATSTAT_RXDATA_MASK (0x1FFU) +#define USART_RXDATSTAT_RXDATA_SHIFT (0U) +#define USART_RXDATSTAT_RXDATA(x) (((uint32_t)(((uint32_t)(x)) << USART_RXDATSTAT_RXDATA_SHIFT)) & USART_RXDATSTAT_RXDATA_MASK) +#define USART_RXDATSTAT_FRAMERR_MASK (0x2000U) +#define USART_RXDATSTAT_FRAMERR_SHIFT (13U) +#define USART_RXDATSTAT_FRAMERR(x) (((uint32_t)(((uint32_t)(x)) << USART_RXDATSTAT_FRAMERR_SHIFT)) & USART_RXDATSTAT_FRAMERR_MASK) +#define USART_RXDATSTAT_PARITYERR_MASK (0x4000U) +#define USART_RXDATSTAT_PARITYERR_SHIFT (14U) +#define USART_RXDATSTAT_PARITYERR(x) (((uint32_t)(((uint32_t)(x)) << USART_RXDATSTAT_PARITYERR_SHIFT)) & USART_RXDATSTAT_PARITYERR_MASK) +#define USART_RXDATSTAT_RXNOISE_MASK (0x8000U) +#define USART_RXDATSTAT_RXNOISE_SHIFT (15U) +#define USART_RXDATSTAT_RXNOISE(x) (((uint32_t)(((uint32_t)(x)) << USART_RXDATSTAT_RXNOISE_SHIFT)) & USART_RXDATSTAT_RXNOISE_MASK) + +/*! @name TXDAT - Transmit Data register. Data to be transmitted is written here. */ +#define USART_TXDAT_TXDATA_MASK (0x1FFU) +#define USART_TXDAT_TXDATA_SHIFT (0U) +#define USART_TXDAT_TXDATA(x) (((uint32_t)(((uint32_t)(x)) << USART_TXDAT_TXDATA_SHIFT)) & USART_TXDAT_TXDATA_MASK) + +/*! @name BRG - Baud Rate Generator register. 16-bit integer baud rate divisor value. */ +#define USART_BRG_BRGVAL_MASK (0xFFFFU) +#define USART_BRG_BRGVAL_SHIFT (0U) +#define USART_BRG_BRGVAL(x) (((uint32_t)(((uint32_t)(x)) << USART_BRG_BRGVAL_SHIFT)) & USART_BRG_BRGVAL_MASK) + +/*! @name INTSTAT - Interrupt status register. Reflects interrupts that are currently enabled. */ +#define USART_INTSTAT_RXRDY_MASK (0x1U) +#define USART_INTSTAT_RXRDY_SHIFT (0U) +#define USART_INTSTAT_RXRDY(x) (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_RXRDY_SHIFT)) & USART_INTSTAT_RXRDY_MASK) +#define USART_INTSTAT_TXRDY_MASK (0x4U) +#define USART_INTSTAT_TXRDY_SHIFT (2U) +#define USART_INTSTAT_TXRDY(x) (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_TXRDY_SHIFT)) & USART_INTSTAT_TXRDY_MASK) +#define USART_INTSTAT_TXIDLE_MASK (0x8U) +#define USART_INTSTAT_TXIDLE_SHIFT (3U) +#define USART_INTSTAT_TXIDLE(x) (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_TXIDLE_SHIFT)) & USART_INTSTAT_TXIDLE_MASK) +#define USART_INTSTAT_DELTACTS_MASK (0x20U) +#define USART_INTSTAT_DELTACTS_SHIFT (5U) +#define USART_INTSTAT_DELTACTS(x) (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_DELTACTS_SHIFT)) & USART_INTSTAT_DELTACTS_MASK) +#define USART_INTSTAT_TXDISINT_MASK (0x40U) +#define USART_INTSTAT_TXDISINT_SHIFT (6U) +#define USART_INTSTAT_TXDISINT(x) (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_TXDISINT_SHIFT)) & USART_INTSTAT_TXDISINT_MASK) +#define USART_INTSTAT_OVERRUNINT_MASK (0x100U) +#define USART_INTSTAT_OVERRUNINT_SHIFT (8U) +#define USART_INTSTAT_OVERRUNINT(x) (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_OVERRUNINT_SHIFT)) & USART_INTSTAT_OVERRUNINT_MASK) +#define USART_INTSTAT_DELTARXBRK_MASK (0x800U) +#define USART_INTSTAT_DELTARXBRK_SHIFT (11U) +#define USART_INTSTAT_DELTARXBRK(x) (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_DELTARXBRK_SHIFT)) & USART_INTSTAT_DELTARXBRK_MASK) +#define USART_INTSTAT_START_MASK (0x1000U) +#define USART_INTSTAT_START_SHIFT (12U) +#define USART_INTSTAT_START(x) (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_START_SHIFT)) & USART_INTSTAT_START_MASK) +#define USART_INTSTAT_FRAMERRINT_MASK (0x2000U) +#define USART_INTSTAT_FRAMERRINT_SHIFT (13U) +#define USART_INTSTAT_FRAMERRINT(x) (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_FRAMERRINT_SHIFT)) & USART_INTSTAT_FRAMERRINT_MASK) +#define USART_INTSTAT_PARITYERRINT_MASK (0x4000U) +#define USART_INTSTAT_PARITYERRINT_SHIFT (14U) +#define USART_INTSTAT_PARITYERRINT(x) (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_PARITYERRINT_SHIFT)) & USART_INTSTAT_PARITYERRINT_MASK) +#define USART_INTSTAT_RXNOISEINT_MASK (0x8000U) +#define USART_INTSTAT_RXNOISEINT_SHIFT (15U) +#define USART_INTSTAT_RXNOISEINT(x) (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_RXNOISEINT_SHIFT)) & USART_INTSTAT_RXNOISEINT_MASK) +#define USART_INTSTAT_ABERRINT_MASK (0x10000U) +#define USART_INTSTAT_ABERRINT_SHIFT (16U) +#define USART_INTSTAT_ABERRINT(x) (((uint32_t)(((uint32_t)(x)) << USART_INTSTAT_ABERRINT_SHIFT)) & USART_INTSTAT_ABERRINT_MASK) + +/*! @name OSR - Oversample selection register for asynchronous communication. */ +#define USART_OSR_OSRVAL_MASK (0xFU) +#define USART_OSR_OSRVAL_SHIFT (0U) +#define USART_OSR_OSRVAL(x) (((uint32_t)(((uint32_t)(x)) << USART_OSR_OSRVAL_SHIFT)) & USART_OSR_OSRVAL_MASK) + +/*! @name ADDR - Address register for automatic address matching. */ +#define USART_ADDR_ADDRESS_MASK (0xFFU) +#define USART_ADDR_ADDRESS_SHIFT (0U) +#define USART_ADDR_ADDRESS(x) (((uint32_t)(((uint32_t)(x)) << USART_ADDR_ADDRESS_SHIFT)) & USART_ADDR_ADDRESS_MASK) + + +/*! + * @} + */ /* end of group USART_Register_Masks */ + + +/* USART - Peripheral instance base addresses */ +/** Peripheral USART0 base address */ +#define USART0_BASE (0x40084000u) +/** Peripheral USART0 base pointer */ +#define USART0 ((USART_Type *)USART0_BASE) +/** Peripheral USART1 base address */ +#define USART1_BASE (0x40088000u) +/** Peripheral USART1 base pointer */ +#define USART1 ((USART_Type *)USART1_BASE) +/** Peripheral USART2 base address */ +#define USART2_BASE (0x4008C000u) +/** Peripheral USART2 base pointer */ +#define USART2 ((USART_Type *)USART2_BASE) +/** Peripheral USART3 base address */ +#define USART3_BASE (0x40090000u) +/** Peripheral USART3 base pointer */ +#define USART3 ((USART_Type *)USART3_BASE) +/** Array initializer of USART peripheral base addresses */ +#define USART_BASE_ADDRS { USART0_BASE, USART1_BASE, USART2_BASE, USART3_BASE } +/** Array initializer of USART peripheral base pointers */ +#define USART_BASE_PTRS { USART0, USART1, USART2, USART3 } +/** Interrupt vectors for the USART peripheral type */ +#define USART_IRQS { USART0_IRQn, USART1_IRQn, USART2_IRQn, USART3_IRQn } + +/*! + * @} + */ /* end of group USART_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- UTICK Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup UTICK_Peripheral_Access_Layer UTICK Peripheral Access Layer + * @{ + */ + +/** UTICK - Register Layout Typedef */ +typedef struct { + __IO uint32_t CTRL; /**< Control register., offset: 0x0 */ + __IO uint32_t STAT; /**< Status register., offset: 0x4 */ + __IO uint32_t CFG; /**< Capture configuration register., offset: 0x8 */ + __O uint32_t CAPCLR; /**< Capture clear register., offset: 0xC */ + __I uint32_t CAP[4]; /**< Capture register ., array offset: 0x10, array step: 0x4 */ +} UTICK_Type; + +/* ---------------------------------------------------------------------------- + -- UTICK Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup UTICK_Register_Masks UTICK Register Masks + * @{ + */ + +/*! @name CTRL - Control register. */ +#define UTICK_CTRL_DELAYVAL_MASK (0x7FFFFFFFU) +#define UTICK_CTRL_DELAYVAL_SHIFT (0U) +#define UTICK_CTRL_DELAYVAL(x) (((uint32_t)(((uint32_t)(x)) << UTICK_CTRL_DELAYVAL_SHIFT)) & UTICK_CTRL_DELAYVAL_MASK) +#define UTICK_CTRL_REPEAT_MASK (0x80000000U) +#define UTICK_CTRL_REPEAT_SHIFT (31U) +#define UTICK_CTRL_REPEAT(x) (((uint32_t)(((uint32_t)(x)) << UTICK_CTRL_REPEAT_SHIFT)) & UTICK_CTRL_REPEAT_MASK) + +/*! @name STAT - Status register. */ +#define UTICK_STAT_INTR_MASK (0x1U) +#define UTICK_STAT_INTR_SHIFT (0U) +#define UTICK_STAT_INTR(x) (((uint32_t)(((uint32_t)(x)) << UTICK_STAT_INTR_SHIFT)) & UTICK_STAT_INTR_MASK) +#define UTICK_STAT_ACTIVE_MASK (0x2U) +#define UTICK_STAT_ACTIVE_SHIFT (1U) +#define UTICK_STAT_ACTIVE(x) (((uint32_t)(((uint32_t)(x)) << UTICK_STAT_ACTIVE_SHIFT)) & UTICK_STAT_ACTIVE_MASK) + +/*! @name CFG - Capture configuration register. */ +#define UTICK_CFG_CAPEN0_MASK (0x1U) +#define UTICK_CFG_CAPEN0_SHIFT (0U) +#define UTICK_CFG_CAPEN0(x) (((uint32_t)(((uint32_t)(x)) << UTICK_CFG_CAPEN0_SHIFT)) & UTICK_CFG_CAPEN0_MASK) +#define UTICK_CFG_CAPEN1_MASK (0x2U) +#define UTICK_CFG_CAPEN1_SHIFT (1U) +#define UTICK_CFG_CAPEN1(x) (((uint32_t)(((uint32_t)(x)) << UTICK_CFG_CAPEN1_SHIFT)) & UTICK_CFG_CAPEN1_MASK) +#define UTICK_CFG_CAPEN2_MASK (0x4U) +#define UTICK_CFG_CAPEN2_SHIFT (2U) +#define UTICK_CFG_CAPEN2(x) (((uint32_t)(((uint32_t)(x)) << UTICK_CFG_CAPEN2_SHIFT)) & UTICK_CFG_CAPEN2_MASK) +#define UTICK_CFG_CAPEN3_MASK (0x8U) +#define UTICK_CFG_CAPEN3_SHIFT (3U) +#define UTICK_CFG_CAPEN3(x) (((uint32_t)(((uint32_t)(x)) << UTICK_CFG_CAPEN3_SHIFT)) & UTICK_CFG_CAPEN3_MASK) +#define UTICK_CFG_CAPPOL0_MASK (0x100U) +#define UTICK_CFG_CAPPOL0_SHIFT (8U) +#define UTICK_CFG_CAPPOL0(x) (((uint32_t)(((uint32_t)(x)) << UTICK_CFG_CAPPOL0_SHIFT)) & UTICK_CFG_CAPPOL0_MASK) +#define UTICK_CFG_CAPPOL1_MASK (0x200U) +#define UTICK_CFG_CAPPOL1_SHIFT (9U) +#define UTICK_CFG_CAPPOL1(x) (((uint32_t)(((uint32_t)(x)) << UTICK_CFG_CAPPOL1_SHIFT)) & UTICK_CFG_CAPPOL1_MASK) +#define UTICK_CFG_CAPPOL2_MASK (0x400U) +#define UTICK_CFG_CAPPOL2_SHIFT (10U) +#define UTICK_CFG_CAPPOL2(x) (((uint32_t)(((uint32_t)(x)) << UTICK_CFG_CAPPOL2_SHIFT)) & UTICK_CFG_CAPPOL2_MASK) +#define UTICK_CFG_CAPPOL3_MASK (0x800U) +#define UTICK_CFG_CAPPOL3_SHIFT (11U) +#define UTICK_CFG_CAPPOL3(x) (((uint32_t)(((uint32_t)(x)) << UTICK_CFG_CAPPOL3_SHIFT)) & UTICK_CFG_CAPPOL3_MASK) + +/*! @name CAPCLR - Capture clear register. */ +#define UTICK_CAPCLR_CAPCLR0_MASK (0x1U) +#define UTICK_CAPCLR_CAPCLR0_SHIFT (0U) +#define UTICK_CAPCLR_CAPCLR0(x) (((uint32_t)(((uint32_t)(x)) << UTICK_CAPCLR_CAPCLR0_SHIFT)) & UTICK_CAPCLR_CAPCLR0_MASK) +#define UTICK_CAPCLR_CAPCLR1_MASK (0x2U) +#define UTICK_CAPCLR_CAPCLR1_SHIFT (1U) +#define UTICK_CAPCLR_CAPCLR1(x) (((uint32_t)(((uint32_t)(x)) << UTICK_CAPCLR_CAPCLR1_SHIFT)) & UTICK_CAPCLR_CAPCLR1_MASK) +#define UTICK_CAPCLR_CAPCLR2_MASK (0x4U) +#define UTICK_CAPCLR_CAPCLR2_SHIFT (2U) +#define UTICK_CAPCLR_CAPCLR2(x) (((uint32_t)(((uint32_t)(x)) << UTICK_CAPCLR_CAPCLR2_SHIFT)) & UTICK_CAPCLR_CAPCLR2_MASK) +#define UTICK_CAPCLR_CAPCLR3_MASK (0x8U) +#define UTICK_CAPCLR_CAPCLR3_SHIFT (3U) +#define UTICK_CAPCLR_CAPCLR3(x) (((uint32_t)(((uint32_t)(x)) << UTICK_CAPCLR_CAPCLR3_SHIFT)) & UTICK_CAPCLR_CAPCLR3_MASK) + +/*! @name CAP - Capture register . */ +#define UTICK_CAP_CAP_VALUE_MASK (0x7FFFFFFFU) +#define UTICK_CAP_CAP_VALUE_SHIFT (0U) +#define UTICK_CAP_CAP_VALUE(x) (((uint32_t)(((uint32_t)(x)) << UTICK_CAP_CAP_VALUE_SHIFT)) & UTICK_CAP_CAP_VALUE_MASK) +#define UTICK_CAP_VALID_MASK (0x80000000U) +#define UTICK_CAP_VALID_SHIFT (31U) +#define UTICK_CAP_VALID(x) (((uint32_t)(((uint32_t)(x)) << UTICK_CAP_VALID_SHIFT)) & UTICK_CAP_VALID_MASK) + +/* The count of UTICK_CAP */ +#define UTICK_CAP_COUNT (4U) + + +/*! + * @} + */ /* end of group UTICK_Register_Masks */ + + +/* UTICK - Peripheral instance base addresses */ +/** Peripheral UTICK0 base address */ +#define UTICK0_BASE (0x40020000u) +/** Peripheral UTICK0 base pointer */ +#define UTICK0 ((UTICK_Type *)UTICK0_BASE) +/** Array initializer of UTICK peripheral base addresses */ +#define UTICK_BASE_ADDRS { UTICK0_BASE } +/** Array initializer of UTICK peripheral base pointers */ +#define UTICK_BASE_PTRS { UTICK0 } +/** Interrupt vectors for the UTICK peripheral type */ +#define UTICK_IRQS { UTICK0_IRQn } + +/*! + * @} + */ /* end of group UTICK_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- VFIFO Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup VFIFO_Peripheral_Access_Layer VFIFO Peripheral Access Layer + * @{ + */ + +/** VFIFO - Register Layout Typedef */ +typedef struct { + uint8_t RESERVED_0[256]; + __IO uint32_t FIFOCTLUSART; /**< USART FIFO global control register. These registers are byte, halfword, and word addressable.The upper 16 bits of these registers provide information about the System FIFO configuration, and are specific to each device type., offset: 0x100 */ + __IO uint32_t FIFOUPDATEUSART; /**< USART FIFO global update register, offset: 0x104 */ + uint8_t RESERVED_1[8]; + __IO uint32_t FIFOCFGUSART[4]; /**< FIFO configuration register for USART0, array offset: 0x110, array step: 0x4 */ + uint8_t RESERVED_2[224]; + __IO uint32_t FIFOCTLSPI; /**< SPI FIFO global control register. These registers are byte, halfword, and word addressable. The upper 16 bits of these registers provide information about the System FIFO configuration, and are specific to each device type., offset: 0x200 */ + __IO uint32_t FIFOUPDATESPI; /**< SPI FIFO global update register, offset: 0x204 */ + uint8_t RESERVED_3[8]; + __IO uint32_t FIFOCFGSPI[2]; /**< FIFO configuration register for SPI0, array offset: 0x210, array step: 0x4 */ + uint8_t RESERVED_4[3560]; + struct { /* offset: 0x1000, array step: 0x100 */ + __IO uint32_t CFGUSART; /**< USART0 configuration, array offset: 0x1000, array step: 0x100 */ + __IO uint32_t STATUSART; /**< USART0 status, array offset: 0x1004, array step: 0x100 */ + __IO uint32_t INTSTATUSART; /**< USART0 interrupt status, array offset: 0x1008, array step: 0x100 */ + __IO uint32_t CTLSETUSART; /**< USART0 control read and set register. A complete value may be read from this register. Writing a 1 to any implemented bit position causes that bit to be set., array offset: 0x100C, array step: 0x100 */ + __IO uint32_t CTLCLRUSART; /**< USART0 control clear register. Writing a 1 to any implemented bit position causes the corresponding bit in the related CTLSET register to be cleared., array offset: 0x1010, array step: 0x100 */ + __IO uint32_t RXDATUSART; /**< USART0 received data, array offset: 0x1014, array step: 0x100 */ + __IO uint32_t RXDATSTATUSART; /**< USART0 received data with status, array offset: 0x1018, array step: 0x100 */ + __IO uint32_t TXDATUSART; /**< USART0 transmit data, array offset: 0x101C, array step: 0x100 */ + uint8_t RESERVED_0[224]; + } USART[4]; + uint8_t RESERVED_5[3072]; + struct { /* offset: 0x2000, array step: 0x100 */ + __IO uint32_t CFGSPI; /**< SPI0 configuration, array offset: 0x2000, array step: 0x100 */ + __IO uint32_t STATSPI; /**< SPI0 status, array offset: 0x2004, array step: 0x100 */ + __IO uint32_t INTSTATSPI; /**< SPI0 interrupt status, array offset: 0x2008, array step: 0x100 */ + __IO uint32_t CTLSETSPI; /**< SPI0 control read and set register. A complete value may be read from this register. Writing a 1 to any implemented bit position causes that bit to be set., array offset: 0x200C, array step: 0x100 */ + __IO uint32_t CTLCLRSPI; /**< SPI0 control clear register. Writing a 1 to any implemented bit position causes the corresponding bit in the related CTLSET register to be cleared., array offset: 0x2010, array step: 0x100 */ + __IO uint32_t RXDATSPI; /**< SPI0 received data. These registers are half word addressable., array offset: 0x2014, array step: 0x100 */ + __IO uint32_t TXDATSPI; /**< SPI0 transmit data. These registers are half word addressable., array offset: 0x2018, array step: 0x100 */ + uint8_t RESERVED_0[228]; + } SPI[2]; +} VFIFO_Type; + +/* ---------------------------------------------------------------------------- + -- VFIFO Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup VFIFO_Register_Masks VFIFO Register Masks + * @{ + */ + +/*! @name FIFOCTLUSART - USART FIFO global control register. These registers are byte, halfword, and word addressable.The upper 16 bits of these registers provide information about the System FIFO configuration, and are specific to each device type. */ +#define VFIFO_FIFOCTLUSART_RXPAUSE_MASK (0x1U) +#define VFIFO_FIFOCTLUSART_RXPAUSE_SHIFT (0U) +#define VFIFO_FIFOCTLUSART_RXPAUSE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOCTLUSART_RXPAUSE_SHIFT)) & VFIFO_FIFOCTLUSART_RXPAUSE_MASK) +#define VFIFO_FIFOCTLUSART_RXPAUSED_MASK (0x2U) +#define VFIFO_FIFOCTLUSART_RXPAUSED_SHIFT (1U) +#define VFIFO_FIFOCTLUSART_RXPAUSED(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOCTLUSART_RXPAUSED_SHIFT)) & VFIFO_FIFOCTLUSART_RXPAUSED_MASK) +#define VFIFO_FIFOCTLUSART_RXEMPTY_MASK (0x4U) +#define VFIFO_FIFOCTLUSART_RXEMPTY_SHIFT (2U) +#define VFIFO_FIFOCTLUSART_RXEMPTY(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOCTLUSART_RXEMPTY_SHIFT)) & VFIFO_FIFOCTLUSART_RXEMPTY_MASK) +#define VFIFO_FIFOCTLUSART_TXPAUSE_MASK (0x100U) +#define VFIFO_FIFOCTLUSART_TXPAUSE_SHIFT (8U) +#define VFIFO_FIFOCTLUSART_TXPAUSE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOCTLUSART_TXPAUSE_SHIFT)) & VFIFO_FIFOCTLUSART_TXPAUSE_MASK) +#define VFIFO_FIFOCTLUSART_TXPAUSED_MASK (0x200U) +#define VFIFO_FIFOCTLUSART_TXPAUSED_SHIFT (9U) +#define VFIFO_FIFOCTLUSART_TXPAUSED(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOCTLUSART_TXPAUSED_SHIFT)) & VFIFO_FIFOCTLUSART_TXPAUSED_MASK) +#define VFIFO_FIFOCTLUSART_TXEMPTY_MASK (0x400U) +#define VFIFO_FIFOCTLUSART_TXEMPTY_SHIFT (10U) +#define VFIFO_FIFOCTLUSART_TXEMPTY(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOCTLUSART_TXEMPTY_SHIFT)) & VFIFO_FIFOCTLUSART_TXEMPTY_MASK) +#define VFIFO_FIFOCTLUSART_RXFIFOTOTAL_MASK (0xFF0000U) +#define VFIFO_FIFOCTLUSART_RXFIFOTOTAL_SHIFT (16U) +#define VFIFO_FIFOCTLUSART_RXFIFOTOTAL(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOCTLUSART_RXFIFOTOTAL_SHIFT)) & VFIFO_FIFOCTLUSART_RXFIFOTOTAL_MASK) +#define VFIFO_FIFOCTLUSART_TXFIFOTOTAL_MASK (0xFF000000U) +#define VFIFO_FIFOCTLUSART_TXFIFOTOTAL_SHIFT (24U) +#define VFIFO_FIFOCTLUSART_TXFIFOTOTAL(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOCTLUSART_TXFIFOTOTAL_SHIFT)) & VFIFO_FIFOCTLUSART_TXFIFOTOTAL_MASK) + +/*! @name FIFOUPDATEUSART - USART FIFO global update register */ +#define VFIFO_FIFOUPDATEUSART_USART0RXUPDATESIZE_MASK (0x1U) +#define VFIFO_FIFOUPDATEUSART_USART0RXUPDATESIZE_SHIFT (0U) +#define VFIFO_FIFOUPDATEUSART_USART0RXUPDATESIZE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOUPDATEUSART_USART0RXUPDATESIZE_SHIFT)) & VFIFO_FIFOUPDATEUSART_USART0RXUPDATESIZE_MASK) +#define VFIFO_FIFOUPDATEUSART_USART1RXUPDATESIZE_MASK (0x2U) +#define VFIFO_FIFOUPDATEUSART_USART1RXUPDATESIZE_SHIFT (1U) +#define VFIFO_FIFOUPDATEUSART_USART1RXUPDATESIZE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOUPDATEUSART_USART1RXUPDATESIZE_SHIFT)) & VFIFO_FIFOUPDATEUSART_USART1RXUPDATESIZE_MASK) +#define VFIFO_FIFOUPDATEUSART_USART2RXUPDATESIZE_MASK (0x4U) +#define VFIFO_FIFOUPDATEUSART_USART2RXUPDATESIZE_SHIFT (2U) +#define VFIFO_FIFOUPDATEUSART_USART2RXUPDATESIZE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOUPDATEUSART_USART2RXUPDATESIZE_SHIFT)) & VFIFO_FIFOUPDATEUSART_USART2RXUPDATESIZE_MASK) +#define VFIFO_FIFOUPDATEUSART_USART3RXUPDATESIZE_MASK (0x8U) +#define VFIFO_FIFOUPDATEUSART_USART3RXUPDATESIZE_SHIFT (3U) +#define VFIFO_FIFOUPDATEUSART_USART3RXUPDATESIZE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOUPDATEUSART_USART3RXUPDATESIZE_SHIFT)) & VFIFO_FIFOUPDATEUSART_USART3RXUPDATESIZE_MASK) +#define VFIFO_FIFOUPDATEUSART_USART0TXUPDATESIZE_MASK (0x10000U) +#define VFIFO_FIFOUPDATEUSART_USART0TXUPDATESIZE_SHIFT (16U) +#define VFIFO_FIFOUPDATEUSART_USART0TXUPDATESIZE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOUPDATEUSART_USART0TXUPDATESIZE_SHIFT)) & VFIFO_FIFOUPDATEUSART_USART0TXUPDATESIZE_MASK) +#define VFIFO_FIFOUPDATEUSART_USART1TXUPDATESIZE_MASK (0x20000U) +#define VFIFO_FIFOUPDATEUSART_USART1TXUPDATESIZE_SHIFT (17U) +#define VFIFO_FIFOUPDATEUSART_USART1TXUPDATESIZE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOUPDATEUSART_USART1TXUPDATESIZE_SHIFT)) & VFIFO_FIFOUPDATEUSART_USART1TXUPDATESIZE_MASK) +#define VFIFO_FIFOUPDATEUSART_USART2TXUPDATESIZE_MASK (0x40000U) +#define VFIFO_FIFOUPDATEUSART_USART2TXUPDATESIZE_SHIFT (18U) +#define VFIFO_FIFOUPDATEUSART_USART2TXUPDATESIZE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOUPDATEUSART_USART2TXUPDATESIZE_SHIFT)) & VFIFO_FIFOUPDATEUSART_USART2TXUPDATESIZE_MASK) +#define VFIFO_FIFOUPDATEUSART_USART3TXUPDATESIZE_MASK (0x80000U) +#define VFIFO_FIFOUPDATEUSART_USART3TXUPDATESIZE_SHIFT (19U) +#define VFIFO_FIFOUPDATEUSART_USART3TXUPDATESIZE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOUPDATEUSART_USART3TXUPDATESIZE_SHIFT)) & VFIFO_FIFOUPDATEUSART_USART3TXUPDATESIZE_MASK) + +/*! @name FIFOCFGUSART - FIFO configuration register for USART0 */ +#define VFIFO_FIFOCFGUSART_RXSIZE_MASK (0xFFU) +#define VFIFO_FIFOCFGUSART_RXSIZE_SHIFT (0U) +#define VFIFO_FIFOCFGUSART_RXSIZE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOCFGUSART_RXSIZE_SHIFT)) & VFIFO_FIFOCFGUSART_RXSIZE_MASK) +#define VFIFO_FIFOCFGUSART_TXSIZE_MASK (0xFF00U) +#define VFIFO_FIFOCFGUSART_TXSIZE_SHIFT (8U) +#define VFIFO_FIFOCFGUSART_TXSIZE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOCFGUSART_TXSIZE_SHIFT)) & VFIFO_FIFOCFGUSART_TXSIZE_MASK) + +/* The count of VFIFO_FIFOCFGUSART */ +#define VFIFO_FIFOCFGUSART_COUNT (4U) + +/*! @name FIFOCTLSPI - SPI FIFO global control register. These registers are byte, halfword, and word addressable. The upper 16 bits of these registers provide information about the System FIFO configuration, and are specific to each device type. */ +#define VFIFO_FIFOCTLSPI_RXPAUSE_MASK (0x1U) +#define VFIFO_FIFOCTLSPI_RXPAUSE_SHIFT (0U) +#define VFIFO_FIFOCTLSPI_RXPAUSE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOCTLSPI_RXPAUSE_SHIFT)) & VFIFO_FIFOCTLSPI_RXPAUSE_MASK) +#define VFIFO_FIFOCTLSPI_RXPAUSED_MASK (0x2U) +#define VFIFO_FIFOCTLSPI_RXPAUSED_SHIFT (1U) +#define VFIFO_FIFOCTLSPI_RXPAUSED(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOCTLSPI_RXPAUSED_SHIFT)) & VFIFO_FIFOCTLSPI_RXPAUSED_MASK) +#define VFIFO_FIFOCTLSPI_RXEMPTY_MASK (0x4U) +#define VFIFO_FIFOCTLSPI_RXEMPTY_SHIFT (2U) +#define VFIFO_FIFOCTLSPI_RXEMPTY(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOCTLSPI_RXEMPTY_SHIFT)) & VFIFO_FIFOCTLSPI_RXEMPTY_MASK) +#define VFIFO_FIFOCTLSPI_TXPAUSE_MASK (0x100U) +#define VFIFO_FIFOCTLSPI_TXPAUSE_SHIFT (8U) +#define VFIFO_FIFOCTLSPI_TXPAUSE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOCTLSPI_TXPAUSE_SHIFT)) & VFIFO_FIFOCTLSPI_TXPAUSE_MASK) +#define VFIFO_FIFOCTLSPI_TXPAUSED_MASK (0x200U) +#define VFIFO_FIFOCTLSPI_TXPAUSED_SHIFT (9U) +#define VFIFO_FIFOCTLSPI_TXPAUSED(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOCTLSPI_TXPAUSED_SHIFT)) & VFIFO_FIFOCTLSPI_TXPAUSED_MASK) +#define VFIFO_FIFOCTLSPI_TXEMPTY_MASK (0x400U) +#define VFIFO_FIFOCTLSPI_TXEMPTY_SHIFT (10U) +#define VFIFO_FIFOCTLSPI_TXEMPTY(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOCTLSPI_TXEMPTY_SHIFT)) & VFIFO_FIFOCTLSPI_TXEMPTY_MASK) +#define VFIFO_FIFOCTLSPI_RXFIFOTOTAL_MASK (0xFF0000U) +#define VFIFO_FIFOCTLSPI_RXFIFOTOTAL_SHIFT (16U) +#define VFIFO_FIFOCTLSPI_RXFIFOTOTAL(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOCTLSPI_RXFIFOTOTAL_SHIFT)) & VFIFO_FIFOCTLSPI_RXFIFOTOTAL_MASK) +#define VFIFO_FIFOCTLSPI_TXFIFOTOTAL_MASK (0xFF000000U) +#define VFIFO_FIFOCTLSPI_TXFIFOTOTAL_SHIFT (24U) +#define VFIFO_FIFOCTLSPI_TXFIFOTOTAL(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOCTLSPI_TXFIFOTOTAL_SHIFT)) & VFIFO_FIFOCTLSPI_TXFIFOTOTAL_MASK) + +/*! @name FIFOUPDATESPI - SPI FIFO global update register */ +#define VFIFO_FIFOUPDATESPI_SPI0RXUPDATESIZE_MASK (0x1U) +#define VFIFO_FIFOUPDATESPI_SPI0RXUPDATESIZE_SHIFT (0U) +#define VFIFO_FIFOUPDATESPI_SPI0RXUPDATESIZE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOUPDATESPI_SPI0RXUPDATESIZE_SHIFT)) & VFIFO_FIFOUPDATESPI_SPI0RXUPDATESIZE_MASK) +#define VFIFO_FIFOUPDATESPI_SPI1RXUPDATESIZE_MASK (0x2U) +#define VFIFO_FIFOUPDATESPI_SPI1RXUPDATESIZE_SHIFT (1U) +#define VFIFO_FIFOUPDATESPI_SPI1RXUPDATESIZE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOUPDATESPI_SPI1RXUPDATESIZE_SHIFT)) & VFIFO_FIFOUPDATESPI_SPI1RXUPDATESIZE_MASK) +#define VFIFO_FIFOUPDATESPI_SPI0TXUPDATESIZE_MASK (0x10000U) +#define VFIFO_FIFOUPDATESPI_SPI0TXUPDATESIZE_SHIFT (16U) +#define VFIFO_FIFOUPDATESPI_SPI0TXUPDATESIZE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOUPDATESPI_SPI0TXUPDATESIZE_SHIFT)) & VFIFO_FIFOUPDATESPI_SPI0TXUPDATESIZE_MASK) +#define VFIFO_FIFOUPDATESPI_SPI1TXUPDATESIZE_MASK (0x20000U) +#define VFIFO_FIFOUPDATESPI_SPI1TXUPDATESIZE_SHIFT (17U) +#define VFIFO_FIFOUPDATESPI_SPI1TXUPDATESIZE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOUPDATESPI_SPI1TXUPDATESIZE_SHIFT)) & VFIFO_FIFOUPDATESPI_SPI1TXUPDATESIZE_MASK) + +/*! @name FIFOCFGSPI - FIFO configuration register for SPI0 */ +#define VFIFO_FIFOCFGSPI_RXSIZE_MASK (0xFFU) +#define VFIFO_FIFOCFGSPI_RXSIZE_SHIFT (0U) +#define VFIFO_FIFOCFGSPI_RXSIZE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOCFGSPI_RXSIZE_SHIFT)) & VFIFO_FIFOCFGSPI_RXSIZE_MASK) +#define VFIFO_FIFOCFGSPI_TXSIZE_MASK (0xFF00U) +#define VFIFO_FIFOCFGSPI_TXSIZE_SHIFT (8U) +#define VFIFO_FIFOCFGSPI_TXSIZE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_FIFOCFGSPI_TXSIZE_SHIFT)) & VFIFO_FIFOCFGSPI_TXSIZE_MASK) + +/* The count of VFIFO_FIFOCFGSPI */ +#define VFIFO_FIFOCFGSPI_COUNT (2U) + +/*! @name USART_CFGUSART - USART0 configuration */ +#define VFIFO_USART_CFGUSART_TIMEOUTCONTONWRITE_MASK (0x10U) +#define VFIFO_USART_CFGUSART_TIMEOUTCONTONWRITE_SHIFT (4U) +#define VFIFO_USART_CFGUSART_TIMEOUTCONTONWRITE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_CFGUSART_TIMEOUTCONTONWRITE_SHIFT)) & VFIFO_USART_CFGUSART_TIMEOUTCONTONWRITE_MASK) +#define VFIFO_USART_CFGUSART_TIMEOUTCONTONEMPTY_MASK (0x20U) +#define VFIFO_USART_CFGUSART_TIMEOUTCONTONEMPTY_SHIFT (5U) +#define VFIFO_USART_CFGUSART_TIMEOUTCONTONEMPTY(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_CFGUSART_TIMEOUTCONTONEMPTY_SHIFT)) & VFIFO_USART_CFGUSART_TIMEOUTCONTONEMPTY_MASK) +#define VFIFO_USART_CFGUSART_TIMEOUTBASE_MASK (0xF00U) +#define VFIFO_USART_CFGUSART_TIMEOUTBASE_SHIFT (8U) +#define VFIFO_USART_CFGUSART_TIMEOUTBASE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_CFGUSART_TIMEOUTBASE_SHIFT)) & VFIFO_USART_CFGUSART_TIMEOUTBASE_MASK) +#define VFIFO_USART_CFGUSART_TIMEOUTVALUE_MASK (0xF000U) +#define VFIFO_USART_CFGUSART_TIMEOUTVALUE_SHIFT (12U) +#define VFIFO_USART_CFGUSART_TIMEOUTVALUE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_CFGUSART_TIMEOUTVALUE_SHIFT)) & VFIFO_USART_CFGUSART_TIMEOUTVALUE_MASK) +#define VFIFO_USART_CFGUSART_RXTHRESHOLD_MASK (0xFF0000U) +#define VFIFO_USART_CFGUSART_RXTHRESHOLD_SHIFT (16U) +#define VFIFO_USART_CFGUSART_RXTHRESHOLD(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_CFGUSART_RXTHRESHOLD_SHIFT)) & VFIFO_USART_CFGUSART_RXTHRESHOLD_MASK) +#define VFIFO_USART_CFGUSART_TXTHRESHOLD_MASK (0xFF000000U) +#define VFIFO_USART_CFGUSART_TXTHRESHOLD_SHIFT (24U) +#define VFIFO_USART_CFGUSART_TXTHRESHOLD(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_CFGUSART_TXTHRESHOLD_SHIFT)) & VFIFO_USART_CFGUSART_TXTHRESHOLD_MASK) + +/* The count of VFIFO_USART_CFGUSART */ +#define VFIFO_USART_CFGUSART_COUNT (4U) + +/*! @name USART_STATUSART - USART0 status */ +#define VFIFO_USART_STATUSART_RXTH_MASK (0x1U) +#define VFIFO_USART_STATUSART_RXTH_SHIFT (0U) +#define VFIFO_USART_STATUSART_RXTH(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_STATUSART_RXTH_SHIFT)) & VFIFO_USART_STATUSART_RXTH_MASK) +#define VFIFO_USART_STATUSART_TXTH_MASK (0x2U) +#define VFIFO_USART_STATUSART_TXTH_SHIFT (1U) +#define VFIFO_USART_STATUSART_TXTH(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_STATUSART_TXTH_SHIFT)) & VFIFO_USART_STATUSART_TXTH_MASK) +#define VFIFO_USART_STATUSART_RXTIMEOUT_MASK (0x10U) +#define VFIFO_USART_STATUSART_RXTIMEOUT_SHIFT (4U) +#define VFIFO_USART_STATUSART_RXTIMEOUT(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_STATUSART_RXTIMEOUT_SHIFT)) & VFIFO_USART_STATUSART_RXTIMEOUT_MASK) +#define VFIFO_USART_STATUSART_BUSERR_MASK (0x80U) +#define VFIFO_USART_STATUSART_BUSERR_SHIFT (7U) +#define VFIFO_USART_STATUSART_BUSERR(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_STATUSART_BUSERR_SHIFT)) & VFIFO_USART_STATUSART_BUSERR_MASK) +#define VFIFO_USART_STATUSART_RXEMPTY_MASK (0x100U) +#define VFIFO_USART_STATUSART_RXEMPTY_SHIFT (8U) +#define VFIFO_USART_STATUSART_RXEMPTY(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_STATUSART_RXEMPTY_SHIFT)) & VFIFO_USART_STATUSART_RXEMPTY_MASK) +#define VFIFO_USART_STATUSART_TXEMPTY_MASK (0x200U) +#define VFIFO_USART_STATUSART_TXEMPTY_SHIFT (9U) +#define VFIFO_USART_STATUSART_TXEMPTY(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_STATUSART_TXEMPTY_SHIFT)) & VFIFO_USART_STATUSART_TXEMPTY_MASK) +#define VFIFO_USART_STATUSART_RXCOUNT_MASK (0xFF0000U) +#define VFIFO_USART_STATUSART_RXCOUNT_SHIFT (16U) +#define VFIFO_USART_STATUSART_RXCOUNT(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_STATUSART_RXCOUNT_SHIFT)) & VFIFO_USART_STATUSART_RXCOUNT_MASK) +#define VFIFO_USART_STATUSART_TXCOUNT_MASK (0xFF000000U) +#define VFIFO_USART_STATUSART_TXCOUNT_SHIFT (24U) +#define VFIFO_USART_STATUSART_TXCOUNT(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_STATUSART_TXCOUNT_SHIFT)) & VFIFO_USART_STATUSART_TXCOUNT_MASK) + +/* The count of VFIFO_USART_STATUSART */ +#define VFIFO_USART_STATUSART_COUNT (4U) + +/*! @name USART_INTSTATUSART - USART0 interrupt status */ +#define VFIFO_USART_INTSTATUSART_RXTH_MASK (0x1U) +#define VFIFO_USART_INTSTATUSART_RXTH_SHIFT (0U) +#define VFIFO_USART_INTSTATUSART_RXTH(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_INTSTATUSART_RXTH_SHIFT)) & VFIFO_USART_INTSTATUSART_RXTH_MASK) +#define VFIFO_USART_INTSTATUSART_TXTH_MASK (0x2U) +#define VFIFO_USART_INTSTATUSART_TXTH_SHIFT (1U) +#define VFIFO_USART_INTSTATUSART_TXTH(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_INTSTATUSART_TXTH_SHIFT)) & VFIFO_USART_INTSTATUSART_TXTH_MASK) +#define VFIFO_USART_INTSTATUSART_RXTIMEOUT_MASK (0x10U) +#define VFIFO_USART_INTSTATUSART_RXTIMEOUT_SHIFT (4U) +#define VFIFO_USART_INTSTATUSART_RXTIMEOUT(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_INTSTATUSART_RXTIMEOUT_SHIFT)) & VFIFO_USART_INTSTATUSART_RXTIMEOUT_MASK) +#define VFIFO_USART_INTSTATUSART_BUSERR_MASK (0x80U) +#define VFIFO_USART_INTSTATUSART_BUSERR_SHIFT (7U) +#define VFIFO_USART_INTSTATUSART_BUSERR(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_INTSTATUSART_BUSERR_SHIFT)) & VFIFO_USART_INTSTATUSART_BUSERR_MASK) +#define VFIFO_USART_INTSTATUSART_RXEMPTY_MASK (0x100U) +#define VFIFO_USART_INTSTATUSART_RXEMPTY_SHIFT (8U) +#define VFIFO_USART_INTSTATUSART_RXEMPTY(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_INTSTATUSART_RXEMPTY_SHIFT)) & VFIFO_USART_INTSTATUSART_RXEMPTY_MASK) +#define VFIFO_USART_INTSTATUSART_TXEMPTY_MASK (0x200U) +#define VFIFO_USART_INTSTATUSART_TXEMPTY_SHIFT (9U) +#define VFIFO_USART_INTSTATUSART_TXEMPTY(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_INTSTATUSART_TXEMPTY_SHIFT)) & VFIFO_USART_INTSTATUSART_TXEMPTY_MASK) +#define VFIFO_USART_INTSTATUSART_RXCOUNT_MASK (0xFF0000U) +#define VFIFO_USART_INTSTATUSART_RXCOUNT_SHIFT (16U) +#define VFIFO_USART_INTSTATUSART_RXCOUNT(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_INTSTATUSART_RXCOUNT_SHIFT)) & VFIFO_USART_INTSTATUSART_RXCOUNT_MASK) +#define VFIFO_USART_INTSTATUSART_TXCOUNT_MASK (0xFF000000U) +#define VFIFO_USART_INTSTATUSART_TXCOUNT_SHIFT (24U) +#define VFIFO_USART_INTSTATUSART_TXCOUNT(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_INTSTATUSART_TXCOUNT_SHIFT)) & VFIFO_USART_INTSTATUSART_TXCOUNT_MASK) + +/* The count of VFIFO_USART_INTSTATUSART */ +#define VFIFO_USART_INTSTATUSART_COUNT (4U) + +/*! @name USART_CTLSETUSART - USART0 control read and set register. A complete value may be read from this register. Writing a 1 to any implemented bit position causes that bit to be set. */ +#define VFIFO_USART_CTLSETUSART_RXTHINTEN_MASK (0x1U) +#define VFIFO_USART_CTLSETUSART_RXTHINTEN_SHIFT (0U) +#define VFIFO_USART_CTLSETUSART_RXTHINTEN(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_CTLSETUSART_RXTHINTEN_SHIFT)) & VFIFO_USART_CTLSETUSART_RXTHINTEN_MASK) +#define VFIFO_USART_CTLSETUSART_TXTHINTEN_MASK (0x2U) +#define VFIFO_USART_CTLSETUSART_TXTHINTEN_SHIFT (1U) +#define VFIFO_USART_CTLSETUSART_TXTHINTEN(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_CTLSETUSART_TXTHINTEN_SHIFT)) & VFIFO_USART_CTLSETUSART_TXTHINTEN_MASK) +#define VFIFO_USART_CTLSETUSART_RXTIMEOUTINTEN_MASK (0x10U) +#define VFIFO_USART_CTLSETUSART_RXTIMEOUTINTEN_SHIFT (4U) +#define VFIFO_USART_CTLSETUSART_RXTIMEOUTINTEN(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_CTLSETUSART_RXTIMEOUTINTEN_SHIFT)) & VFIFO_USART_CTLSETUSART_RXTIMEOUTINTEN_MASK) +#define VFIFO_USART_CTLSETUSART_RXFLUSH_MASK (0x100U) +#define VFIFO_USART_CTLSETUSART_RXFLUSH_SHIFT (8U) +#define VFIFO_USART_CTLSETUSART_RXFLUSH(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_CTLSETUSART_RXFLUSH_SHIFT)) & VFIFO_USART_CTLSETUSART_RXFLUSH_MASK) +#define VFIFO_USART_CTLSETUSART_TXFLUSH_MASK (0x200U) +#define VFIFO_USART_CTLSETUSART_TXFLUSH_SHIFT (9U) +#define VFIFO_USART_CTLSETUSART_TXFLUSH(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_CTLSETUSART_TXFLUSH_SHIFT)) & VFIFO_USART_CTLSETUSART_TXFLUSH_MASK) + +/* The count of VFIFO_USART_CTLSETUSART */ +#define VFIFO_USART_CTLSETUSART_COUNT (4U) + +/*! @name USART_CTLCLRUSART - USART0 control clear register. Writing a 1 to any implemented bit position causes the corresponding bit in the related CTLSET register to be cleared. */ +#define VFIFO_USART_CTLCLRUSART_RXTHINTCLR_MASK (0x1U) +#define VFIFO_USART_CTLCLRUSART_RXTHINTCLR_SHIFT (0U) +#define VFIFO_USART_CTLCLRUSART_RXTHINTCLR(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_CTLCLRUSART_RXTHINTCLR_SHIFT)) & VFIFO_USART_CTLCLRUSART_RXTHINTCLR_MASK) +#define VFIFO_USART_CTLCLRUSART_TXTHINTCLR_MASK (0x2U) +#define VFIFO_USART_CTLCLRUSART_TXTHINTCLR_SHIFT (1U) +#define VFIFO_USART_CTLCLRUSART_TXTHINTCLR(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_CTLCLRUSART_TXTHINTCLR_SHIFT)) & VFIFO_USART_CTLCLRUSART_TXTHINTCLR_MASK) +#define VFIFO_USART_CTLCLRUSART_RXTIMEOUTINTCLR_MASK (0x10U) +#define VFIFO_USART_CTLCLRUSART_RXTIMEOUTINTCLR_SHIFT (4U) +#define VFIFO_USART_CTLCLRUSART_RXTIMEOUTINTCLR(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_CTLCLRUSART_RXTIMEOUTINTCLR_SHIFT)) & VFIFO_USART_CTLCLRUSART_RXTIMEOUTINTCLR_MASK) +#define VFIFO_USART_CTLCLRUSART_RXFLUSHCLR_MASK (0x100U) +#define VFIFO_USART_CTLCLRUSART_RXFLUSHCLR_SHIFT (8U) +#define VFIFO_USART_CTLCLRUSART_RXFLUSHCLR(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_CTLCLRUSART_RXFLUSHCLR_SHIFT)) & VFIFO_USART_CTLCLRUSART_RXFLUSHCLR_MASK) +#define VFIFO_USART_CTLCLRUSART_TXFLUSHCLR_MASK (0x200U) +#define VFIFO_USART_CTLCLRUSART_TXFLUSHCLR_SHIFT (9U) +#define VFIFO_USART_CTLCLRUSART_TXFLUSHCLR(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_CTLCLRUSART_TXFLUSHCLR_SHIFT)) & VFIFO_USART_CTLCLRUSART_TXFLUSHCLR_MASK) + +/* The count of VFIFO_USART_CTLCLRUSART */ +#define VFIFO_USART_CTLCLRUSART_COUNT (4U) + +/*! @name USART_RXDATUSART - USART0 received data */ +#define VFIFO_USART_RXDATUSART_RXDAT_MASK (0x1FFU) +#define VFIFO_USART_RXDATUSART_RXDAT_SHIFT (0U) +#define VFIFO_USART_RXDATUSART_RXDAT(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_RXDATUSART_RXDAT_SHIFT)) & VFIFO_USART_RXDATUSART_RXDAT_MASK) + +/* The count of VFIFO_USART_RXDATUSART */ +#define VFIFO_USART_RXDATUSART_COUNT (4U) + +/*! @name USART_RXDATSTATUSART - USART0 received data with status */ +#define VFIFO_USART_RXDATSTATUSART_RXDAT_MASK (0x1FFU) +#define VFIFO_USART_RXDATSTATUSART_RXDAT_SHIFT (0U) +#define VFIFO_USART_RXDATSTATUSART_RXDAT(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_RXDATSTATUSART_RXDAT_SHIFT)) & VFIFO_USART_RXDATSTATUSART_RXDAT_MASK) +#define VFIFO_USART_RXDATSTATUSART_FRAMERR_MASK (0x2000U) +#define VFIFO_USART_RXDATSTATUSART_FRAMERR_SHIFT (13U) +#define VFIFO_USART_RXDATSTATUSART_FRAMERR(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_RXDATSTATUSART_FRAMERR_SHIFT)) & VFIFO_USART_RXDATSTATUSART_FRAMERR_MASK) +#define VFIFO_USART_RXDATSTATUSART_PARITYERR_MASK (0x4000U) +#define VFIFO_USART_RXDATSTATUSART_PARITYERR_SHIFT (14U) +#define VFIFO_USART_RXDATSTATUSART_PARITYERR(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_RXDATSTATUSART_PARITYERR_SHIFT)) & VFIFO_USART_RXDATSTATUSART_PARITYERR_MASK) +#define VFIFO_USART_RXDATSTATUSART_RXNOISE_MASK (0x8000U) +#define VFIFO_USART_RXDATSTATUSART_RXNOISE_SHIFT (15U) +#define VFIFO_USART_RXDATSTATUSART_RXNOISE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_RXDATSTATUSART_RXNOISE_SHIFT)) & VFIFO_USART_RXDATSTATUSART_RXNOISE_MASK) + +/* The count of VFIFO_USART_RXDATSTATUSART */ +#define VFIFO_USART_RXDATSTATUSART_COUNT (4U) + +/*! @name USART_TXDATUSART - USART0 transmit data */ +#define VFIFO_USART_TXDATUSART_TXDAT_MASK (0x1FFU) +#define VFIFO_USART_TXDATUSART_TXDAT_SHIFT (0U) +#define VFIFO_USART_TXDATUSART_TXDAT(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_USART_TXDATUSART_TXDAT_SHIFT)) & VFIFO_USART_TXDATUSART_TXDAT_MASK) + +/* The count of VFIFO_USART_TXDATUSART */ +#define VFIFO_USART_TXDATUSART_COUNT (4U) + +/*! @name SPI_CFGSPI - SPI0 configuration */ +#define VFIFO_SPI_CFGSPI_TIMEOUTCONTONWRITE_MASK (0x10U) +#define VFIFO_SPI_CFGSPI_TIMEOUTCONTONWRITE_SHIFT (4U) +#define VFIFO_SPI_CFGSPI_TIMEOUTCONTONWRITE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_CFGSPI_TIMEOUTCONTONWRITE_SHIFT)) & VFIFO_SPI_CFGSPI_TIMEOUTCONTONWRITE_MASK) +#define VFIFO_SPI_CFGSPI_TIMEOUTCONTONEMPTY_MASK (0x20U) +#define VFIFO_SPI_CFGSPI_TIMEOUTCONTONEMPTY_SHIFT (5U) +#define VFIFO_SPI_CFGSPI_TIMEOUTCONTONEMPTY(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_CFGSPI_TIMEOUTCONTONEMPTY_SHIFT)) & VFIFO_SPI_CFGSPI_TIMEOUTCONTONEMPTY_MASK) +#define VFIFO_SPI_CFGSPI_TIMEOUTBASE_MASK (0xF00U) +#define VFIFO_SPI_CFGSPI_TIMEOUTBASE_SHIFT (8U) +#define VFIFO_SPI_CFGSPI_TIMEOUTBASE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_CFGSPI_TIMEOUTBASE_SHIFT)) & VFIFO_SPI_CFGSPI_TIMEOUTBASE_MASK) +#define VFIFO_SPI_CFGSPI_TIMEOUTVALUE_MASK (0xF000U) +#define VFIFO_SPI_CFGSPI_TIMEOUTVALUE_SHIFT (12U) +#define VFIFO_SPI_CFGSPI_TIMEOUTVALUE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_CFGSPI_TIMEOUTVALUE_SHIFT)) & VFIFO_SPI_CFGSPI_TIMEOUTVALUE_MASK) +#define VFIFO_SPI_CFGSPI_RXTHRESHOLD_MASK (0xFF0000U) +#define VFIFO_SPI_CFGSPI_RXTHRESHOLD_SHIFT (16U) +#define VFIFO_SPI_CFGSPI_RXTHRESHOLD(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_CFGSPI_RXTHRESHOLD_SHIFT)) & VFIFO_SPI_CFGSPI_RXTHRESHOLD_MASK) +#define VFIFO_SPI_CFGSPI_TXTHRESHOLD_MASK (0xFF000000U) +#define VFIFO_SPI_CFGSPI_TXTHRESHOLD_SHIFT (24U) +#define VFIFO_SPI_CFGSPI_TXTHRESHOLD(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_CFGSPI_TXTHRESHOLD_SHIFT)) & VFIFO_SPI_CFGSPI_TXTHRESHOLD_MASK) + +/* The count of VFIFO_SPI_CFGSPI */ +#define VFIFO_SPI_CFGSPI_COUNT (2U) + +/*! @name SPI_STATSPI - SPI0 status */ +#define VFIFO_SPI_STATSPI_RXTH_MASK (0x1U) +#define VFIFO_SPI_STATSPI_RXTH_SHIFT (0U) +#define VFIFO_SPI_STATSPI_RXTH(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_STATSPI_RXTH_SHIFT)) & VFIFO_SPI_STATSPI_RXTH_MASK) +#define VFIFO_SPI_STATSPI_TXTH_MASK (0x2U) +#define VFIFO_SPI_STATSPI_TXTH_SHIFT (1U) +#define VFIFO_SPI_STATSPI_TXTH(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_STATSPI_TXTH_SHIFT)) & VFIFO_SPI_STATSPI_TXTH_MASK) +#define VFIFO_SPI_STATSPI_RXTIMEOUT_MASK (0x10U) +#define VFIFO_SPI_STATSPI_RXTIMEOUT_SHIFT (4U) +#define VFIFO_SPI_STATSPI_RXTIMEOUT(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_STATSPI_RXTIMEOUT_SHIFT)) & VFIFO_SPI_STATSPI_RXTIMEOUT_MASK) +#define VFIFO_SPI_STATSPI_BUSERR_MASK (0x80U) +#define VFIFO_SPI_STATSPI_BUSERR_SHIFT (7U) +#define VFIFO_SPI_STATSPI_BUSERR(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_STATSPI_BUSERR_SHIFT)) & VFIFO_SPI_STATSPI_BUSERR_MASK) +#define VFIFO_SPI_STATSPI_RXEMPTY_MASK (0x100U) +#define VFIFO_SPI_STATSPI_RXEMPTY_SHIFT (8U) +#define VFIFO_SPI_STATSPI_RXEMPTY(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_STATSPI_RXEMPTY_SHIFT)) & VFIFO_SPI_STATSPI_RXEMPTY_MASK) +#define VFIFO_SPI_STATSPI_TXEMPTY_MASK (0x200U) +#define VFIFO_SPI_STATSPI_TXEMPTY_SHIFT (9U) +#define VFIFO_SPI_STATSPI_TXEMPTY(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_STATSPI_TXEMPTY_SHIFT)) & VFIFO_SPI_STATSPI_TXEMPTY_MASK) +#define VFIFO_SPI_STATSPI_RXCOUNT_MASK (0xFF0000U) +#define VFIFO_SPI_STATSPI_RXCOUNT_SHIFT (16U) +#define VFIFO_SPI_STATSPI_RXCOUNT(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_STATSPI_RXCOUNT_SHIFT)) & VFIFO_SPI_STATSPI_RXCOUNT_MASK) +#define VFIFO_SPI_STATSPI_TXCOUNT_MASK (0xFF000000U) +#define VFIFO_SPI_STATSPI_TXCOUNT_SHIFT (24U) +#define VFIFO_SPI_STATSPI_TXCOUNT(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_STATSPI_TXCOUNT_SHIFT)) & VFIFO_SPI_STATSPI_TXCOUNT_MASK) + +/* The count of VFIFO_SPI_STATSPI */ +#define VFIFO_SPI_STATSPI_COUNT (2U) + +/*! @name SPI_INTSTATSPI - SPI0 interrupt status */ +#define VFIFO_SPI_INTSTATSPI_RXTH_MASK (0x1U) +#define VFIFO_SPI_INTSTATSPI_RXTH_SHIFT (0U) +#define VFIFO_SPI_INTSTATSPI_RXTH(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_INTSTATSPI_RXTH_SHIFT)) & VFIFO_SPI_INTSTATSPI_RXTH_MASK) +#define VFIFO_SPI_INTSTATSPI_TXTH_MASK (0x2U) +#define VFIFO_SPI_INTSTATSPI_TXTH_SHIFT (1U) +#define VFIFO_SPI_INTSTATSPI_TXTH(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_INTSTATSPI_TXTH_SHIFT)) & VFIFO_SPI_INTSTATSPI_TXTH_MASK) +#define VFIFO_SPI_INTSTATSPI_RXTIMEOUT_MASK (0x10U) +#define VFIFO_SPI_INTSTATSPI_RXTIMEOUT_SHIFT (4U) +#define VFIFO_SPI_INTSTATSPI_RXTIMEOUT(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_INTSTATSPI_RXTIMEOUT_SHIFT)) & VFIFO_SPI_INTSTATSPI_RXTIMEOUT_MASK) +#define VFIFO_SPI_INTSTATSPI_BUSERR_MASK (0x80U) +#define VFIFO_SPI_INTSTATSPI_BUSERR_SHIFT (7U) +#define VFIFO_SPI_INTSTATSPI_BUSERR(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_INTSTATSPI_BUSERR_SHIFT)) & VFIFO_SPI_INTSTATSPI_BUSERR_MASK) +#define VFIFO_SPI_INTSTATSPI_RXEMPTY_MASK (0x100U) +#define VFIFO_SPI_INTSTATSPI_RXEMPTY_SHIFT (8U) +#define VFIFO_SPI_INTSTATSPI_RXEMPTY(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_INTSTATSPI_RXEMPTY_SHIFT)) & VFIFO_SPI_INTSTATSPI_RXEMPTY_MASK) +#define VFIFO_SPI_INTSTATSPI_TXEMPTY_MASK (0x200U) +#define VFIFO_SPI_INTSTATSPI_TXEMPTY_SHIFT (9U) +#define VFIFO_SPI_INTSTATSPI_TXEMPTY(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_INTSTATSPI_TXEMPTY_SHIFT)) & VFIFO_SPI_INTSTATSPI_TXEMPTY_MASK) +#define VFIFO_SPI_INTSTATSPI_RXCOUNT_MASK (0xFF0000U) +#define VFIFO_SPI_INTSTATSPI_RXCOUNT_SHIFT (16U) +#define VFIFO_SPI_INTSTATSPI_RXCOUNT(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_INTSTATSPI_RXCOUNT_SHIFT)) & VFIFO_SPI_INTSTATSPI_RXCOUNT_MASK) +#define VFIFO_SPI_INTSTATSPI_TXCOUNT_MASK (0xFF000000U) +#define VFIFO_SPI_INTSTATSPI_TXCOUNT_SHIFT (24U) +#define VFIFO_SPI_INTSTATSPI_TXCOUNT(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_INTSTATSPI_TXCOUNT_SHIFT)) & VFIFO_SPI_INTSTATSPI_TXCOUNT_MASK) + +/* The count of VFIFO_SPI_INTSTATSPI */ +#define VFIFO_SPI_INTSTATSPI_COUNT (2U) + +/*! @name SPI_CTLSETSPI - SPI0 control read and set register. A complete value may be read from this register. Writing a 1 to any implemented bit position causes that bit to be set. */ +#define VFIFO_SPI_CTLSETSPI_RXTHINTEN_MASK (0x1U) +#define VFIFO_SPI_CTLSETSPI_RXTHINTEN_SHIFT (0U) +#define VFIFO_SPI_CTLSETSPI_RXTHINTEN(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_CTLSETSPI_RXTHINTEN_SHIFT)) & VFIFO_SPI_CTLSETSPI_RXTHINTEN_MASK) +#define VFIFO_SPI_CTLSETSPI_TXTHINTEN_MASK (0x2U) +#define VFIFO_SPI_CTLSETSPI_TXTHINTEN_SHIFT (1U) +#define VFIFO_SPI_CTLSETSPI_TXTHINTEN(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_CTLSETSPI_TXTHINTEN_SHIFT)) & VFIFO_SPI_CTLSETSPI_TXTHINTEN_MASK) +#define VFIFO_SPI_CTLSETSPI_RXTIMEOUTINTEN_MASK (0x10U) +#define VFIFO_SPI_CTLSETSPI_RXTIMEOUTINTEN_SHIFT (4U) +#define VFIFO_SPI_CTLSETSPI_RXTIMEOUTINTEN(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_CTLSETSPI_RXTIMEOUTINTEN_SHIFT)) & VFIFO_SPI_CTLSETSPI_RXTIMEOUTINTEN_MASK) +#define VFIFO_SPI_CTLSETSPI_RXFLUSH_MASK (0x100U) +#define VFIFO_SPI_CTLSETSPI_RXFLUSH_SHIFT (8U) +#define VFIFO_SPI_CTLSETSPI_RXFLUSH(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_CTLSETSPI_RXFLUSH_SHIFT)) & VFIFO_SPI_CTLSETSPI_RXFLUSH_MASK) +#define VFIFO_SPI_CTLSETSPI_TXFLUSH_MASK (0x200U) +#define VFIFO_SPI_CTLSETSPI_TXFLUSH_SHIFT (9U) +#define VFIFO_SPI_CTLSETSPI_TXFLUSH(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_CTLSETSPI_TXFLUSH_SHIFT)) & VFIFO_SPI_CTLSETSPI_TXFLUSH_MASK) + +/* The count of VFIFO_SPI_CTLSETSPI */ +#define VFIFO_SPI_CTLSETSPI_COUNT (2U) + +/*! @name SPI_CTLCLRSPI - SPI0 control clear register. Writing a 1 to any implemented bit position causes the corresponding bit in the related CTLSET register to be cleared. */ +#define VFIFO_SPI_CTLCLRSPI_RXTHINTCLR_MASK (0x1U) +#define VFIFO_SPI_CTLCLRSPI_RXTHINTCLR_SHIFT (0U) +#define VFIFO_SPI_CTLCLRSPI_RXTHINTCLR(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_CTLCLRSPI_RXTHINTCLR_SHIFT)) & VFIFO_SPI_CTLCLRSPI_RXTHINTCLR_MASK) +#define VFIFO_SPI_CTLCLRSPI_TXTHINTCLR_MASK (0x2U) +#define VFIFO_SPI_CTLCLRSPI_TXTHINTCLR_SHIFT (1U) +#define VFIFO_SPI_CTLCLRSPI_TXTHINTCLR(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_CTLCLRSPI_TXTHINTCLR_SHIFT)) & VFIFO_SPI_CTLCLRSPI_TXTHINTCLR_MASK) +#define VFIFO_SPI_CTLCLRSPI_RXTIMEOUTINTCLR_MASK (0x10U) +#define VFIFO_SPI_CTLCLRSPI_RXTIMEOUTINTCLR_SHIFT (4U) +#define VFIFO_SPI_CTLCLRSPI_RXTIMEOUTINTCLR(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_CTLCLRSPI_RXTIMEOUTINTCLR_SHIFT)) & VFIFO_SPI_CTLCLRSPI_RXTIMEOUTINTCLR_MASK) +#define VFIFO_SPI_CTLCLRSPI_RXFLUSHCLR_MASK (0x100U) +#define VFIFO_SPI_CTLCLRSPI_RXFLUSHCLR_SHIFT (8U) +#define VFIFO_SPI_CTLCLRSPI_RXFLUSHCLR(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_CTLCLRSPI_RXFLUSHCLR_SHIFT)) & VFIFO_SPI_CTLCLRSPI_RXFLUSHCLR_MASK) +#define VFIFO_SPI_CTLCLRSPI_TXFLUSHCLR_MASK (0x200U) +#define VFIFO_SPI_CTLCLRSPI_TXFLUSHCLR_SHIFT (9U) +#define VFIFO_SPI_CTLCLRSPI_TXFLUSHCLR(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_CTLCLRSPI_TXFLUSHCLR_SHIFT)) & VFIFO_SPI_CTLCLRSPI_TXFLUSHCLR_MASK) + +/* The count of VFIFO_SPI_CTLCLRSPI */ +#define VFIFO_SPI_CTLCLRSPI_COUNT (2U) + +/*! @name SPI_RXDATSPI - SPI0 received data. These registers are half word addressable. */ +#define VFIFO_SPI_RXDATSPI_RXDAT_MASK (0xFFFFU) +#define VFIFO_SPI_RXDATSPI_RXDAT_SHIFT (0U) +#define VFIFO_SPI_RXDATSPI_RXDAT(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_RXDATSPI_RXDAT_SHIFT)) & VFIFO_SPI_RXDATSPI_RXDAT_MASK) +#define VFIFO_SPI_RXDATSPI_RXSSEL0_N_MASK (0x10000U) +#define VFIFO_SPI_RXDATSPI_RXSSEL0_N_SHIFT (16U) +#define VFIFO_SPI_RXDATSPI_RXSSEL0_N(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_RXDATSPI_RXSSEL0_N_SHIFT)) & VFIFO_SPI_RXDATSPI_RXSSEL0_N_MASK) +#define VFIFO_SPI_RXDATSPI_RXSSEL1_N_MASK (0x20000U) +#define VFIFO_SPI_RXDATSPI_RXSSEL1_N_SHIFT (17U) +#define VFIFO_SPI_RXDATSPI_RXSSEL1_N(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_RXDATSPI_RXSSEL1_N_SHIFT)) & VFIFO_SPI_RXDATSPI_RXSSEL1_N_MASK) +#define VFIFO_SPI_RXDATSPI_RXSSEL2_N_MASK (0x40000U) +#define VFIFO_SPI_RXDATSPI_RXSSEL2_N_SHIFT (18U) +#define VFIFO_SPI_RXDATSPI_RXSSEL2_N(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_RXDATSPI_RXSSEL2_N_SHIFT)) & VFIFO_SPI_RXDATSPI_RXSSEL2_N_MASK) +#define VFIFO_SPI_RXDATSPI_RXSSEL3_N_MASK (0x80000U) +#define VFIFO_SPI_RXDATSPI_RXSSEL3_N_SHIFT (19U) +#define VFIFO_SPI_RXDATSPI_RXSSEL3_N(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_RXDATSPI_RXSSEL3_N_SHIFT)) & VFIFO_SPI_RXDATSPI_RXSSEL3_N_MASK) +#define VFIFO_SPI_RXDATSPI_SOT_MASK (0x100000U) +#define VFIFO_SPI_RXDATSPI_SOT_SHIFT (20U) +#define VFIFO_SPI_RXDATSPI_SOT(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_RXDATSPI_SOT_SHIFT)) & VFIFO_SPI_RXDATSPI_SOT_MASK) + +/* The count of VFIFO_SPI_RXDATSPI */ +#define VFIFO_SPI_RXDATSPI_COUNT (2U) + +/*! @name SPI_TXDATSPI - SPI0 transmit data. These registers are half word addressable. */ +#define VFIFO_SPI_TXDATSPI_TXDAT_MASK (0xFFFFU) +#define VFIFO_SPI_TXDATSPI_TXDAT_SHIFT (0U) +#define VFIFO_SPI_TXDATSPI_TXDAT(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_TXDATSPI_TXDAT_SHIFT)) & VFIFO_SPI_TXDATSPI_TXDAT_MASK) +#define VFIFO_SPI_TXDATSPI_TXSSEL0_N_MASK (0x10000U) +#define VFIFO_SPI_TXDATSPI_TXSSEL0_N_SHIFT (16U) +#define VFIFO_SPI_TXDATSPI_TXSSEL0_N(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_TXDATSPI_TXSSEL0_N_SHIFT)) & VFIFO_SPI_TXDATSPI_TXSSEL0_N_MASK) +#define VFIFO_SPI_TXDATSPI_TXSSEL1_N_MASK (0x20000U) +#define VFIFO_SPI_TXDATSPI_TXSSEL1_N_SHIFT (17U) +#define VFIFO_SPI_TXDATSPI_TXSSEL1_N(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_TXDATSPI_TXSSEL1_N_SHIFT)) & VFIFO_SPI_TXDATSPI_TXSSEL1_N_MASK) +#define VFIFO_SPI_TXDATSPI_TXSSEL2_N_MASK (0x40000U) +#define VFIFO_SPI_TXDATSPI_TXSSEL2_N_SHIFT (18U) +#define VFIFO_SPI_TXDATSPI_TXSSEL2_N(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_TXDATSPI_TXSSEL2_N_SHIFT)) & VFIFO_SPI_TXDATSPI_TXSSEL2_N_MASK) +#define VFIFO_SPI_TXDATSPI_TXSSEL3_N_MASK (0x80000U) +#define VFIFO_SPI_TXDATSPI_TXSSEL3_N_SHIFT (19U) +#define VFIFO_SPI_TXDATSPI_TXSSEL3_N(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_TXDATSPI_TXSSEL3_N_SHIFT)) & VFIFO_SPI_TXDATSPI_TXSSEL3_N_MASK) +#define VFIFO_SPI_TXDATSPI_EOT_MASK (0x100000U) +#define VFIFO_SPI_TXDATSPI_EOT_SHIFT (20U) +#define VFIFO_SPI_TXDATSPI_EOT(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_TXDATSPI_EOT_SHIFT)) & VFIFO_SPI_TXDATSPI_EOT_MASK) +#define VFIFO_SPI_TXDATSPI_EOF_MASK (0x200000U) +#define VFIFO_SPI_TXDATSPI_EOF_SHIFT (21U) +#define VFIFO_SPI_TXDATSPI_EOF(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_TXDATSPI_EOF_SHIFT)) & VFIFO_SPI_TXDATSPI_EOF_MASK) +#define VFIFO_SPI_TXDATSPI_RXIGNORE_MASK (0x400000U) +#define VFIFO_SPI_TXDATSPI_RXIGNORE_SHIFT (22U) +#define VFIFO_SPI_TXDATSPI_RXIGNORE(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_TXDATSPI_RXIGNORE_SHIFT)) & VFIFO_SPI_TXDATSPI_RXIGNORE_MASK) +#define VFIFO_SPI_TXDATSPI_LEN_MASK (0xF000000U) +#define VFIFO_SPI_TXDATSPI_LEN_SHIFT (24U) +#define VFIFO_SPI_TXDATSPI_LEN(x) (((uint32_t)(((uint32_t)(x)) << VFIFO_SPI_TXDATSPI_LEN_SHIFT)) & VFIFO_SPI_TXDATSPI_LEN_MASK) + +/* The count of VFIFO_SPI_TXDATSPI */ +#define VFIFO_SPI_TXDATSPI_COUNT (2U) + + +/*! + * @} + */ /* end of group VFIFO_Register_Masks */ + + +/* VFIFO - Peripheral instance base addresses */ +/** Peripheral VFIFO base address */ +#define VFIFO_BASE (0x1C038000u) +/** Peripheral VFIFO base pointer */ +#define VFIFO ((VFIFO_Type *)VFIFO_BASE) +/** Array initializer of VFIFO peripheral base addresses */ +#define VFIFO_BASE_ADDRS { VFIFO_BASE } +/** Array initializer of VFIFO peripheral base pointers */ +#define VFIFO_BASE_PTRS { VFIFO } + +/*! + * @} + */ /* end of group VFIFO_Peripheral_Access_Layer */ + + +/* ---------------------------------------------------------------------------- + -- WWDT Peripheral Access Layer + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup WWDT_Peripheral_Access_Layer WWDT Peripheral Access Layer + * @{ + */ + +/** WWDT - Register Layout Typedef */ +typedef struct { + __IO uint32_t MOD; /**< Watchdog mode register. This register contains the basic mode and status of the Watchdog Timer., offset: 0x0 */ + __IO uint32_t TC; /**< Watchdog timer constant register. This 24-bit register determines the time-out value., offset: 0x4 */ + __O uint32_t FEED; /**< Watchdog feed sequence register. Writing 0xAA followed by 0x55 to this register reloads the Watchdog timer with the value contained in WDTC., offset: 0x8 */ + __I uint32_t TV; /**< Watchdog timer value register. This 24-bit register reads out the current value of the Watchdog timer., offset: 0xC */ + uint8_t RESERVED_0[4]; + __IO uint32_t WARNINT; /**< Watchdog Warning Interrupt compare value., offset: 0x14 */ + __IO uint32_t WINDOW; /**< Watchdog Window compare value., offset: 0x18 */ +} WWDT_Type; + +/* ---------------------------------------------------------------------------- + -- WWDT Register Masks + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup WWDT_Register_Masks WWDT Register Masks + * @{ + */ + +/*! @name MOD - Watchdog mode register. This register contains the basic mode and status of the Watchdog Timer. */ +#define WWDT_MOD_WDEN_MASK (0x1U) +#define WWDT_MOD_WDEN_SHIFT (0U) +#define WWDT_MOD_WDEN(x) (((uint32_t)(((uint32_t)(x)) << WWDT_MOD_WDEN_SHIFT)) & WWDT_MOD_WDEN_MASK) +#define WWDT_MOD_WDRESET_MASK (0x2U) +#define WWDT_MOD_WDRESET_SHIFT (1U) +#define WWDT_MOD_WDRESET(x) (((uint32_t)(((uint32_t)(x)) << WWDT_MOD_WDRESET_SHIFT)) & WWDT_MOD_WDRESET_MASK) +#define WWDT_MOD_WDTOF_MASK (0x4U) +#define WWDT_MOD_WDTOF_SHIFT (2U) +#define WWDT_MOD_WDTOF(x) (((uint32_t)(((uint32_t)(x)) << WWDT_MOD_WDTOF_SHIFT)) & WWDT_MOD_WDTOF_MASK) +#define WWDT_MOD_WDINT_MASK (0x8U) +#define WWDT_MOD_WDINT_SHIFT (3U) +#define WWDT_MOD_WDINT(x) (((uint32_t)(((uint32_t)(x)) << WWDT_MOD_WDINT_SHIFT)) & WWDT_MOD_WDINT_MASK) +#define WWDT_MOD_WDPROTECT_MASK (0x10U) +#define WWDT_MOD_WDPROTECT_SHIFT (4U) +#define WWDT_MOD_WDPROTECT(x) (((uint32_t)(((uint32_t)(x)) << WWDT_MOD_WDPROTECT_SHIFT)) & WWDT_MOD_WDPROTECT_MASK) +#define WWDT_MOD_LOCK_MASK (0x20U) +#define WWDT_MOD_LOCK_SHIFT (5U) +#define WWDT_MOD_LOCK(x) (((uint32_t)(((uint32_t)(x)) << WWDT_MOD_LOCK_SHIFT)) & WWDT_MOD_LOCK_MASK) + +/*! @name TC - Watchdog timer constant register. This 24-bit register determines the time-out value. */ +#define WWDT_TC_COUNT_MASK (0xFFFFFFU) +#define WWDT_TC_COUNT_SHIFT (0U) +#define WWDT_TC_COUNT(x) (((uint32_t)(((uint32_t)(x)) << WWDT_TC_COUNT_SHIFT)) & WWDT_TC_COUNT_MASK) + +/*! @name FEED - Watchdog feed sequence register. Writing 0xAA followed by 0x55 to this register reloads the Watchdog timer with the value contained in WDTC. */ +#define WWDT_FEED_FEED_MASK (0xFFU) +#define WWDT_FEED_FEED_SHIFT (0U) +#define WWDT_FEED_FEED(x) (((uint32_t)(((uint32_t)(x)) << WWDT_FEED_FEED_SHIFT)) & WWDT_FEED_FEED_MASK) + +/*! @name TV - Watchdog timer value register. This 24-bit register reads out the current value of the Watchdog timer. */ +#define WWDT_TV_COUNT_MASK (0xFFFFFFU) +#define WWDT_TV_COUNT_SHIFT (0U) +#define WWDT_TV_COUNT(x) (((uint32_t)(((uint32_t)(x)) << WWDT_TV_COUNT_SHIFT)) & WWDT_TV_COUNT_MASK) + +/*! @name WARNINT - Watchdog Warning Interrupt compare value. */ +#define WWDT_WARNINT_WARNINT_MASK (0x3FFU) +#define WWDT_WARNINT_WARNINT_SHIFT (0U) +#define WWDT_WARNINT_WARNINT(x) (((uint32_t)(((uint32_t)(x)) << WWDT_WARNINT_WARNINT_SHIFT)) & WWDT_WARNINT_WARNINT_MASK) + +/*! @name WINDOW - Watchdog Window compare value. */ +#define WWDT_WINDOW_WINDOW_MASK (0xFFFFFFU) +#define WWDT_WINDOW_WINDOW_SHIFT (0U) +#define WWDT_WINDOW_WINDOW(x) (((uint32_t)(((uint32_t)(x)) << WWDT_WINDOW_WINDOW_SHIFT)) & WWDT_WINDOW_WINDOW_MASK) + + +/*! + * @} + */ /* end of group WWDT_Register_Masks */ + + +/* WWDT - Peripheral instance base addresses */ +/** Peripheral WWDT base address */ +#define WWDT_BASE (0x40038000u) +/** Peripheral WWDT base pointer */ +#define WWDT ((WWDT_Type *)WWDT_BASE) +/** Array initializer of WWDT peripheral base addresses */ +#define WWDT_BASE_ADDRS { WWDT_BASE } +/** Array initializer of WWDT peripheral base pointers */ +#define WWDT_BASE_PTRS { WWDT } +/** Interrupt vectors for the WWDT peripheral type */ +#define WWDT_IRQS { WDT_IRQn } + +/*! + * @} + */ /* end of group WWDT_Peripheral_Access_Layer */ + + +/* +** End of section using anonymous unions +*/ + +#if defined(__ARMCC_VERSION) + #pragma pop +#elif defined(__IAR_SYSTEMS_ICC__) + #pragma language=default +#elif defined(__GNUC__) + /* leave anonymous unions enabled */ +#else + #error Not supported compiler type +#endif + +/*! + * @} + */ /* end of group Peripheral_access_layer */ + + +/* ---------------------------------------------------------------------------- + -- Macros for use with bit field definitions (xxx_SHIFT, xxx_MASK). + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup Bit_Field_Generic_Macros Macros for use with bit field definitions (xxx_SHIFT, xxx_MASK). + * @{ + */ + +#if defined(__ARMCC_VERSION) + #if (__ARMCC_VERSION >= 6010050) + #pragma clang system_header + #endif +#elif defined(__IAR_SYSTEMS_ICC__) + #pragma system_include +#endif + +/** + * @brief Mask and left-shift a bit field value for use in a register bit range. + * @param field Name of the register bit field. + * @param value Value of the bit field. + * @return Masked and shifted value. + */ +#define NXP_VAL2FLD(field, value) (((value) << (field ## _SHIFT)) & (field ## _MASK)) +/** + * @brief Mask and right-shift a register value to extract a bit field value. + * @param field Name of the register bit field. + * @param value Value of the register. + * @return Masked and shifted bit field value. + */ +#define NXP_FLD2VAL(field, value) (((value) & (field ## _MASK)) >> (field ## _SHIFT)) + +/*! + * @} + */ /* end of group Bit_Field_Generic_Macros */ + + +/* ---------------------------------------------------------------------------- + -- SDK Compatibility + ---------------------------------------------------------------------------- */ + +/*! + * @addtogroup SDK_Compatibility_Symbols SDK Compatibility + * @{ + */ + +/* No SDK compatibility issues. */ + +/*! + * @} + */ /* end of group SDK_Compatibility_Symbols */ + + +#endif /* _LPC54102_CM4_H_ */ + diff --git a/platform/mcu/lpc54102/LPC54102_cm4_features.h b/platform/mcu/lpc54102/LPC54102_cm4_features.h new file mode 100644 index 0000000000..305e0e2c62 --- /dev/null +++ b/platform/mcu/lpc54102/LPC54102_cm4_features.h @@ -0,0 +1,600 @@ +/* +** ################################################################### +** Version: rev. 1.0, 2016-05-09 +** Build: b170512 +** +** Abstract: +** Chip specific module features. +** +** Copyright 2016 Freescale Semiconductor, Inc. +** Copyright 2016-2017 NXP +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o 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. +** +** o Neither the name of the copyright holder nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.nxp.com +** mail: support@nxp.com +** +** Revisions: +** - rev. 1.0 (2016-05-09) +** Initial version. +** +** ################################################################### +*/ + +#ifndef _LPC54102_cm4_FEATURES_H_ +#define _LPC54102_cm4_FEATURES_H_ + +/* SOC module features */ + +/* @brief ACMP availability on the SoC. */ +#define FSL_FEATURE_SOC_ACMP_COUNT (0) +/* @brief ADC availability on the SoC. */ +#define FSL_FEATURE_SOC_ADC_COUNT (1) +/* @brief ADC12 availability on the SoC. */ +#define FSL_FEATURE_SOC_ADC12_COUNT (0) +/* @brief ADC16 availability on the SoC. */ +#define FSL_FEATURE_SOC_ADC16_COUNT (0) +/* @brief ADC_5HC availability on the SoC. */ +#define FSL_FEATURE_SOC_ADC_5HC_COUNT (0) +/* @brief AES availability on the SoC. */ +#define FSL_FEATURE_SOC_AES_COUNT (0) +/* @brief AFE availability on the SoC. */ +#define FSL_FEATURE_SOC_AFE_COUNT (0) +/* @brief AGC availability on the SoC. */ +#define FSL_FEATURE_SOC_AGC_COUNT (0) +/* @brief AIPS availability on the SoC. */ +#define FSL_FEATURE_SOC_AIPS_COUNT (0) +/* @brief AIPSTZ availability on the SoC. */ +#define FSL_FEATURE_SOC_AIPSTZ_COUNT (0) +/* @brief ANATOP availability on the SoC. */ +#define FSL_FEATURE_SOC_ANATOP_COUNT (0) +/* @brief AOI availability on the SoC. */ +#define FSL_FEATURE_SOC_AOI_COUNT (0) +/* @brief APBH availability on the SoC. */ +#define FSL_FEATURE_SOC_APBH_COUNT (0) +/* @brief ASMC availability on the SoC. */ +#define FSL_FEATURE_SOC_ASMC_COUNT (0) +/* @brief ASRC availability on the SoC. */ +#define FSL_FEATURE_SOC_ASRC_COUNT (0) +/* @brief ASYNC_SYSCON availability on the SoC. */ +#define FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT (1) +/* @brief ATX availability on the SoC. */ +#define FSL_FEATURE_SOC_ATX_COUNT (0) +/* @brief AXBS availability on the SoC. */ +#define FSL_FEATURE_SOC_AXBS_COUNT (0) +/* @brief BCH availability on the SoC. */ +#define FSL_FEATURE_SOC_BCH_COUNT (0) +/* @brief BLEDP availability on the SoC. */ +#define FSL_FEATURE_SOC_BLEDP_COUNT (0) +/* @brief BOD availability on the SoC. */ +#define FSL_FEATURE_SOC_BOD_COUNT (0) +/* @brief CAAM availability on the SoC. */ +#define FSL_FEATURE_SOC_CAAM_COUNT (0) +/* @brief CADC availability on the SoC. */ +#define FSL_FEATURE_SOC_CADC_COUNT (0) +/* @brief CALIB availability on the SoC. */ +#define FSL_FEATURE_SOC_CALIB_COUNT (0) +/* @brief CAN availability on the SoC. */ +#define FSL_FEATURE_SOC_LPC_CAN_COUNT (0) +/* @brief CAU availability on the SoC. */ +#define FSL_FEATURE_SOC_CAU_COUNT (0) +/* @brief CAU3 availability on the SoC. */ +#define FSL_FEATURE_SOC_CAU3_COUNT (0) +/* @brief CCM availability on the SoC. */ +#define FSL_FEATURE_SOC_CCM_COUNT (0) +/* @brief CCM_ANALOG availability on the SoC. */ +#define FSL_FEATURE_SOC_CCM_ANALOG_COUNT (0) +/* @brief CHRG availability on the SoC. */ +#define FSL_FEATURE_SOC_CHRG_COUNT (0) +/* @brief CMP availability on the SoC. */ +#define FSL_FEATURE_SOC_CMP_COUNT (0) +/* @brief CMT availability on the SoC. */ +#define FSL_FEATURE_SOC_CMT_COUNT (0) +/* @brief CNC availability on the SoC. */ +#define FSL_FEATURE_SOC_CNC_COUNT (0) +/* @brief COP availability on the SoC. */ +#define FSL_FEATURE_SOC_COP_COUNT (0) +/* @brief CRC availability on the SoC. */ +#define FSL_FEATURE_SOC_CRC_COUNT (1) +/* @brief CS availability on the SoC. */ +#define FSL_FEATURE_SOC_CS_COUNT (0) +/* @brief CSI availability on the SoC. */ +#define FSL_FEATURE_SOC_CSI_COUNT (0) +/* @brief CT32B availability on the SoC. */ +#define FSL_FEATURE_SOC_CT32B_COUNT (0) +/* @brief CTI availability on the SoC. */ +#define FSL_FEATURE_SOC_CTI_COUNT (0) +/* @brief CTIMER availability on the SoC. */ +#define FSL_FEATURE_SOC_CTIMER_COUNT (5) +/* @brief DAC availability on the SoC. */ +#define FSL_FEATURE_SOC_DAC_COUNT (0) +/* @brief DAC32 availability on the SoC. */ +#define FSL_FEATURE_SOC_DAC32_COUNT (0) +/* @brief DCDC availability on the SoC. */ +#define FSL_FEATURE_SOC_DCDC_COUNT (0) +/* @brief DCP availability on the SoC. */ +#define FSL_FEATURE_SOC_DCP_COUNT (0) +/* @brief DDR availability on the SoC. */ +#define FSL_FEATURE_SOC_DDR_COUNT (0) +/* @brief DDRC availability on the SoC. */ +#define FSL_FEATURE_SOC_DDRC_COUNT (0) +/* @brief DDRC_MP availability on the SoC. */ +#define FSL_FEATURE_SOC_DDRC_MP_COUNT (0) +/* @brief DDR_PHY availability on the SoC. */ +#define FSL_FEATURE_SOC_DDR_PHY_COUNT (0) +/* @brief DMA availability on the SoC. */ +#define FSL_FEATURE_SOC_DMA_COUNT (1) +/* @brief DMAMUX availability on the SoC. */ +#define FSL_FEATURE_SOC_DMAMUX_COUNT (0) +/* @brief DMIC availability on the SoC. */ +#define FSL_FEATURE_SOC_DMIC_COUNT (0) +/* @brief DRY availability on the SoC. */ +#define FSL_FEATURE_SOC_DRY_COUNT (0) +/* @brief DSPI availability on the SoC. */ +#define FSL_FEATURE_SOC_DSPI_COUNT (0) +/* @brief ECSPI availability on the SoC. */ +#define FSL_FEATURE_SOC_ECSPI_COUNT (0) +/* @brief EDMA availability on the SoC. */ +#define FSL_FEATURE_SOC_EDMA_COUNT (0) +/* @brief EEPROM availability on the SoC. */ +#define FSL_FEATURE_SOC_EEPROM_COUNT (0) +/* @brief EIM availability on the SoC. */ +#define FSL_FEATURE_SOC_EIM_COUNT (0) +/* @brief EMC availability on the SoC. */ +#define FSL_FEATURE_SOC_EMC_COUNT (0) +/* @brief EMVSIM availability on the SoC. */ +#define FSL_FEATURE_SOC_EMVSIM_COUNT (0) +/* @brief ENC availability on the SoC. */ +#define FSL_FEATURE_SOC_ENC_COUNT (0) +/* @brief ENET availability on the SoC. */ +#define FSL_FEATURE_SOC_LPC_ENET_COUNT (0) +/* @brief EPDC availability on the SoC. */ +#define FSL_FEATURE_SOC_EPDC_COUNT (0) +/* @brief EPIT availability on the SoC. */ +#define FSL_FEATURE_SOC_EPIT_COUNT (0) +/* @brief ESAI availability on the SoC. */ +#define FSL_FEATURE_SOC_ESAI_COUNT (0) +/* @brief EWM availability on the SoC. */ +#define FSL_FEATURE_SOC_EWM_COUNT (0) +/* @brief FB availability on the SoC. */ +#define FSL_FEATURE_SOC_FB_COUNT (0) +/* @brief FGPIO availability on the SoC. */ +#define FSL_FEATURE_SOC_FGPIO_COUNT (0) +/* @brief FLASH availability on the SoC. */ +#define FSL_FEATURE_SOC_FLASH_COUNT (0) +/* @brief FLEXCAN availability on the SoC. */ +#define FSL_FEATURE_SOC_FLEXCAN_COUNT (0) +/* @brief FLEXCOMM availability on the SoC. */ +#define FSL_FEATURE_SOC_FLEXCOMM_COUNT (0) +/* @brief FLEXIO availability on the SoC. */ +#define FSL_FEATURE_SOC_FLEXIO_COUNT (0) +/* @brief FLEXRAM availability on the SoC. */ +#define FSL_FEATURE_SOC_FLEXRAM_COUNT (0) +/* @brief FLEXSPI availability on the SoC. */ +#define FSL_FEATURE_SOC_FLEXSPI_COUNT (0) +/* @brief FMC availability on the SoC. */ +#define FSL_FEATURE_SOC_FMC_COUNT (0) +/* @brief FSKDT availability on the SoC. */ +#define FSL_FEATURE_SOC_FSKDT_COUNT (0) +/* @brief FSP availability on the SoC. */ +#define FSL_FEATURE_SOC_FSP_COUNT (0) +/* @brief FTFA availability on the SoC. */ +#define FSL_FEATURE_SOC_FTFA_COUNT (0) +/* @brief FTFE availability on the SoC. */ +#define FSL_FEATURE_SOC_FTFE_COUNT (0) +/* @brief FTFL availability on the SoC. */ +#define FSL_FEATURE_SOC_FTFL_COUNT (0) +/* @brief FTM availability on the SoC. */ +#define FSL_FEATURE_SOC_FTM_COUNT (0) +/* @brief FTMRA availability on the SoC. */ +#define FSL_FEATURE_SOC_FTMRA_COUNT (0) +/* @brief FTMRE availability on the SoC. */ +#define FSL_FEATURE_SOC_FTMRE_COUNT (0) +/* @brief FTMRH availability on the SoC. */ +#define FSL_FEATURE_SOC_FTMRH_COUNT (0) +/* @brief GINT availability on the SoC. */ +#define FSL_FEATURE_SOC_GINT_COUNT (2) +/* @brief GPC availability on the SoC. */ +#define FSL_FEATURE_SOC_GPC_COUNT (0) +/* @brief GPC_PGC availability on the SoC. */ +#define FSL_FEATURE_SOC_GPC_PGC_COUNT (0) +/* @brief GPIO availability on the SoC. */ +#define FSL_FEATURE_SOC_GPIO_COUNT (1) +/* @brief GPMI availability on the SoC. */ +#define FSL_FEATURE_SOC_GPMI_COUNT (0) +/* @brief GPT availability on the SoC. */ +#define FSL_FEATURE_SOC_GPT_COUNT (0) +/* @brief HSADC availability on the SoC. */ +#define FSL_FEATURE_SOC_HSADC_COUNT (0) +/* @brief I2C availability on the SoC. */ +#define FSL_FEATURE_SOC_I2C_COUNT (3) +/* @brief I2S availability on the SoC. */ +#define FSL_FEATURE_SOC_I2S_COUNT (0) +/* @brief ICS availability on the SoC. */ +#define FSL_FEATURE_SOC_ICS_COUNT (0) +/* @brief IEE availability on the SoC. */ +#define FSL_FEATURE_SOC_IEE_COUNT (0) +/* @brief IEER availability on the SoC. */ +#define FSL_FEATURE_SOC_IEER_COUNT (0) +/* @brief IGPIO availability on the SoC. */ +#define FSL_FEATURE_SOC_IGPIO_COUNT (0) +/* @brief II2C availability on the SoC. */ +#define FSL_FEATURE_SOC_II2C_COUNT (0) +/* @brief INPUTMUX availability on the SoC. */ +#define FSL_FEATURE_SOC_INPUTMUX_COUNT (1) +/* @brief INTMUX availability on the SoC. */ +#define FSL_FEATURE_SOC_INTMUX_COUNT (0) +/* @brief IOCON availability on the SoC. */ +#define FSL_FEATURE_SOC_IOCON_COUNT (1) +/* @brief IOMUXC availability on the SoC. */ +#define FSL_FEATURE_SOC_IOMUXC_COUNT (0) +/* @brief IOMUXC_GPR availability on the SoC. */ +#define FSL_FEATURE_SOC_IOMUXC_GPR_COUNT (0) +/* @brief IOMUXC_LPSR availability on the SoC. */ +#define FSL_FEATURE_SOC_IOMUXC_LPSR_COUNT (0) +/* @brief IOMUXC_LPSR_GPR availability on the SoC. */ +#define FSL_FEATURE_SOC_IOMUXC_LPSR_GPR_COUNT (0) +/* @brief IOMUXC_SNVS availability on the SoC. */ +#define FSL_FEATURE_SOC_IOMUXC_SNVS_COUNT (0) +/* @brief IPWM availability on the SoC. */ +#define FSL_FEATURE_SOC_IPWM_COUNT (0) +/* @brief IRQ availability on the SoC. */ +#define FSL_FEATURE_SOC_IRQ_COUNT (0) +/* @brief IUART availability on the SoC. */ +#define FSL_FEATURE_SOC_IUART_COUNT (0) +/* @brief KBI availability on the SoC. */ +#define FSL_FEATURE_SOC_KBI_COUNT (0) +/* @brief KPP availability on the SoC. */ +#define FSL_FEATURE_SOC_KPP_COUNT (0) +/* @brief L2CACHEC availability on the SoC. */ +#define FSL_FEATURE_SOC_L2CACHEC_COUNT (0) +/* @brief LCD availability on the SoC. */ +#define FSL_FEATURE_SOC_LCD_COUNT (0) +/* @brief LCDC availability on the SoC. */ +#define FSL_FEATURE_SOC_LCDC_COUNT (0) +/* @brief LCDIF availability on the SoC. */ +#define FSL_FEATURE_SOC_LCDIF_COUNT (0) +/* @brief LDO availability on the SoC. */ +#define FSL_FEATURE_SOC_LDO_COUNT (0) +/* @brief LLWU availability on the SoC. */ +#define FSL_FEATURE_SOC_LLWU_COUNT (0) +/* @brief LMEM availability on the SoC. */ +#define FSL_FEATURE_SOC_LMEM_COUNT (0) +/* @brief LPADC availability on the SoC. */ +#define FSL_FEATURE_SOC_LPADC_COUNT (0) +/* @brief LPCMP availability on the SoC. */ +#define FSL_FEATURE_SOC_LPCMP_COUNT (0) +/* @brief LPDAC availability on the SoC. */ +#define FSL_FEATURE_SOC_LPDAC_COUNT (0) +/* @brief LPI2C availability on the SoC. */ +#define FSL_FEATURE_SOC_LPI2C_COUNT (0) +/* @brief LPIT availability on the SoC. */ +#define FSL_FEATURE_SOC_LPIT_COUNT (0) +/* @brief LPSCI availability on the SoC. */ +#define FSL_FEATURE_SOC_LPSCI_COUNT (0) +/* @brief LPSPI availability on the SoC. */ +#define FSL_FEATURE_SOC_LPSPI_COUNT (0) +/* @brief LPTMR availability on the SoC. */ +#define FSL_FEATURE_SOC_LPTMR_COUNT (0) +/* @brief LPTPM availability on the SoC. */ +#define FSL_FEATURE_SOC_LPTPM_COUNT (0) +/* @brief LPUART availability on the SoC. */ +#define FSL_FEATURE_SOC_LPUART_COUNT (0) +/* @brief LTC availability on the SoC. */ +#define FSL_FEATURE_SOC_LTC_COUNT (0) +/* @brief MAILBOX availability on the SoC. */ +#define FSL_FEATURE_SOC_MAILBOX_COUNT (1) +/* @brief MC availability on the SoC. */ +#define FSL_FEATURE_SOC_MC_COUNT (0) +/* @brief MCG availability on the SoC. */ +#define FSL_FEATURE_SOC_MCG_COUNT (0) +/* @brief MCGLITE availability on the SoC. */ +#define FSL_FEATURE_SOC_MCGLITE_COUNT (0) +/* @brief MCM availability on the SoC. */ +#define FSL_FEATURE_SOC_MCM_COUNT (0) +/* @brief MIPI_CSI2 availability on the SoC. */ +#define FSL_FEATURE_SOC_MIPI_CSI2_COUNT (0) +/* @brief MIPI_DSI availability on the SoC. */ +#define FSL_FEATURE_SOC_MIPI_DSI_COUNT (0) +/* @brief MIPI_DSI_HOST availability on the SoC. */ +#define FSL_FEATURE_SOC_MIPI_DSI_HOST_COUNT (0) +/* @brief MMAU availability on the SoC. */ +#define FSL_FEATURE_SOC_MMAU_COUNT (0) +/* @brief MMCAU availability on the SoC. */ +#define FSL_FEATURE_SOC_MMCAU_COUNT (0) +/* @brief MMDC availability on the SoC. */ +#define FSL_FEATURE_SOC_MMDC_COUNT (0) +/* @brief MMDVSQ availability on the SoC. */ +#define FSL_FEATURE_SOC_MMDVSQ_COUNT (0) +/* @brief MPU availability on the SoC. */ +#define FSL_FEATURE_SOC_MPU_COUNT (0) +/* @brief MRT availability on the SoC. */ +#define FSL_FEATURE_SOC_MRT_COUNT (1) +/* @brief MSCAN availability on the SoC. */ +#define FSL_FEATURE_SOC_MSCAN_COUNT (0) +/* @brief MSCM availability on the SoC. */ +#define FSL_FEATURE_SOC_MSCM_COUNT (0) +/* @brief MTB availability on the SoC. */ +#define FSL_FEATURE_SOC_MTB_COUNT (0) +/* @brief MTBDWT availability on the SoC. */ +#define FSL_FEATURE_SOC_MTBDWT_COUNT (0) +/* @brief MU availability on the SoC. */ +#define FSL_FEATURE_SOC_MU_COUNT (0) +/* @brief NFC availability on the SoC. */ +#define FSL_FEATURE_SOC_NFC_COUNT (0) +/* @brief OCOTP availability on the SoC. */ +#define FSL_FEATURE_SOC_OCOTP_COUNT (0) +/* @brief OPAMP availability on the SoC. */ +#define FSL_FEATURE_SOC_OPAMP_COUNT (0) +/* @brief OSC availability on the SoC. */ +#define FSL_FEATURE_SOC_OSC_COUNT (0) +/* @brief OSC32 availability on the SoC. */ +#define FSL_FEATURE_SOC_OSC32_COUNT (0) +/* @brief OTFAD availability on the SoC. */ +#define FSL_FEATURE_SOC_OTFAD_COUNT (0) +/* @brief PCC availability on the SoC. */ +#define FSL_FEATURE_SOC_PCC_COUNT (0) +/* @brief PCIE_PHY_CMN availability on the SoC. */ +#define FSL_FEATURE_SOC_PCIE_PHY_CMN_COUNT (0) +/* @brief PCIE_PHY_TRSV availability on the SoC. */ +#define FSL_FEATURE_SOC_PCIE_PHY_TRSV_COUNT (0) +/* @brief PDB availability on the SoC. */ +#define FSL_FEATURE_SOC_PDB_COUNT (0) +/* @brief PGA availability on the SoC. */ +#define FSL_FEATURE_SOC_PGA_COUNT (0) +/* @brief PINT availability on the SoC. */ +#define FSL_FEATURE_SOC_PINT_COUNT (1) +/* @brief PIT availability on the SoC. */ +#define FSL_FEATURE_SOC_PIT_COUNT (0) +/* @brief PMC availability on the SoC. */ +#define FSL_FEATURE_SOC_PMC_COUNT (0) +/* @brief PMU availability on the SoC. */ +#define FSL_FEATURE_SOC_PMU_COUNT (0) +/* @brief PORT availability on the SoC. */ +#define FSL_FEATURE_SOC_PORT_COUNT (0) +/* @brief PROP availability on the SoC. */ +#define FSL_FEATURE_SOC_PROP_COUNT (0) +/* @brief PWM availability on the SoC. */ +#define FSL_FEATURE_SOC_PWM_COUNT (0) +/* @brief PWT availability on the SoC. */ +#define FSL_FEATURE_SOC_PWT_COUNT (0) +/* @brief PXP availability on the SoC. */ +#define FSL_FEATURE_SOC_PXP_COUNT (0) +/* @brief QDEC availability on the SoC. */ +#define FSL_FEATURE_SOC_QDEC_COUNT (0) +/* @brief QuadSPI availability on the SoC. */ +#define FSL_FEATURE_SOC_QuadSPI_COUNT (0) +/* @brief RCM availability on the SoC. */ +#define FSL_FEATURE_SOC_RCM_COUNT (0) +/* @brief RDC availability on the SoC. */ +#define FSL_FEATURE_SOC_RDC_COUNT (0) +/* @brief RDC_SEMAPHORE availability on the SoC. */ +#define FSL_FEATURE_SOC_RDC_SEMAPHORE_COUNT (0) +/* @brief RFSYS availability on the SoC. */ +#define FSL_FEATURE_SOC_RFSYS_COUNT (0) +/* @brief RFVBAT availability on the SoC. */ +#define FSL_FEATURE_SOC_RFVBAT_COUNT (0) +/* @brief RIT availability on the SoC. */ +#define FSL_FEATURE_SOC_RIT_COUNT (1) +/* @brief RNG availability on the SoC. */ +#define FSL_FEATURE_SOC_LPC_RNG_COUNT (0) +/* @brief RNGB availability on the SoC. */ +#define FSL_FEATURE_SOC_RNGB_COUNT (0) +/* @brief ROM availability on the SoC. */ +#define FSL_FEATURE_SOC_ROM_COUNT (0) +/* @brief ROMC availability on the SoC. */ +#define FSL_FEATURE_SOC_ROMC_COUNT (0) +/* @brief RSIM availability on the SoC. */ +#define FSL_FEATURE_SOC_RSIM_COUNT (0) +/* @brief RTC availability on the SoC. */ +#define FSL_FEATURE_SOC_RTC_COUNT (1) +/* @brief SCG availability on the SoC. */ +#define FSL_FEATURE_SOC_SCG_COUNT (0) +/* @brief SCI availability on the SoC. */ +#define FSL_FEATURE_SOC_SCI_COUNT (0) +/* @brief SCT availability on the SoC. */ +#define FSL_FEATURE_SOC_SCT_COUNT (1) +/* @brief SDHC availability on the SoC. */ +#define FSL_FEATURE_SOC_SDHC_COUNT (0) +/* @brief SDIF availability on the SoC. */ +#define FSL_FEATURE_SOC_SDIF_COUNT (0) +/* @brief SDIO availability on the SoC. */ +#define FSL_FEATURE_SOC_SDIO_COUNT (0) +/* @brief SDMA availability on the SoC. */ +#define FSL_FEATURE_SOC_SDMA_COUNT (0) +/* @brief SDMAARM availability on the SoC. */ +#define FSL_FEATURE_SOC_SDMAARM_COUNT (0) +/* @brief SDMABP availability on the SoC. */ +#define FSL_FEATURE_SOC_SDMABP_COUNT (0) +/* @brief SDMACORE availability on the SoC. */ +#define FSL_FEATURE_SOC_SDMACORE_COUNT (0) +/* @brief SDMCORE availability on the SoC. */ +#define FSL_FEATURE_SOC_SDMCORE_COUNT (0) +/* @brief SDRAM availability on the SoC. */ +#define FSL_FEATURE_SOC_SDRAM_COUNT (0) +/* @brief SEMA4 availability on the SoC. */ +#define FSL_FEATURE_SOC_SEMA4_COUNT (0) +/* @brief SEMA42 availability on the SoC. */ +#define FSL_FEATURE_SOC_SEMA42_COUNT (0) +/* @brief SHA availability on the SoC. */ +#define FSL_FEATURE_SOC_SHA_COUNT (0) +/* @brief SIM availability on the SoC. */ +#define FSL_FEATURE_SOC_SIM_COUNT (0) +/* @brief SIMDGO availability on the SoC. */ +#define FSL_FEATURE_SOC_SIMDGO_COUNT (0) +/* @brief SJC availability on the SoC. */ +#define FSL_FEATURE_SOC_SJC_COUNT (0) +/* @brief SLCD availability on the SoC. */ +#define FSL_FEATURE_SOC_SLCD_COUNT (0) +/* @brief SMARTCARD availability on the SoC. */ +#define FSL_FEATURE_SOC_SMARTCARD_COUNT (0) +/* @brief SMC availability on the SoC. */ +#define FSL_FEATURE_SOC_SMC_COUNT (0) +/* @brief SNVS availability on the SoC. */ +#define FSL_FEATURE_SOC_SNVS_COUNT (0) +/* @brief SPBA availability on the SoC. */ +#define FSL_FEATURE_SOC_SPBA_COUNT (0) +/* @brief SPDIF availability on the SoC. */ +#define FSL_FEATURE_SOC_SPDIF_COUNT (0) +/* @brief SPI availability on the SoC. */ +#define FSL_FEATURE_SOC_SPI_COUNT (2) +/* @brief SPIFI availability on the SoC. */ +#define FSL_FEATURE_SOC_SPIFI_COUNT (0) +/* @brief SPM availability on the SoC. */ +#define FSL_FEATURE_SOC_SPM_COUNT (0) +/* @brief SRC availability on the SoC. */ +#define FSL_FEATURE_SOC_SRC_COUNT (0) +/* @brief SYSCON availability on the SoC. */ +#define FSL_FEATURE_SOC_SYSCON_COUNT (1) +/* @brief TEMPMON availability on the SoC. */ +#define FSL_FEATURE_SOC_TEMPMON_COUNT (0) +/* @brief TMR availability on the SoC. */ +#define FSL_FEATURE_SOC_TMR_COUNT (0) +/* @brief TPM availability on the SoC. */ +#define FSL_FEATURE_SOC_TPM_COUNT (0) +/* @brief TRGMUX availability on the SoC. */ +#define FSL_FEATURE_SOC_TRGMUX_COUNT (0) +/* @brief TRIAMP availability on the SoC. */ +#define FSL_FEATURE_SOC_TRIAMP_COUNT (0) +/* @brief TRNG availability on the SoC. */ +#define FSL_FEATURE_SOC_TRNG_COUNT (0) +/* @brief TSC availability on the SoC. */ +#define FSL_FEATURE_SOC_TSC_COUNT (0) +/* @brief TSI availability on the SoC. */ +#define FSL_FEATURE_SOC_TSI_COUNT (0) +/* @brief TSTMR availability on the SoC. */ +#define FSL_FEATURE_SOC_TSTMR_COUNT (0) +/* @brief UART availability on the SoC. */ +#define FSL_FEATURE_SOC_UART_COUNT (0) +/* @brief USART availability on the SoC. */ +#define FSL_FEATURE_SOC_USART_COUNT (4) +/* @brief USB availability on the SoC. */ +#define FSL_FEATURE_SOC_USB_COUNT (0) +/* @brief USBHS availability on the SoC. */ +#define FSL_FEATURE_SOC_USBHS_COUNT (0) +/* @brief USBDCD availability on the SoC. */ +#define FSL_FEATURE_SOC_USBDCD_COUNT (0) +/* @brief USBFSH availability on the SoC. */ +#define FSL_FEATURE_SOC_USBFSH_COUNT (0) +/* @brief USBHSD availability on the SoC. */ +#define FSL_FEATURE_SOC_USBHSD_COUNT (0) +/* @brief USBHSDCD availability on the SoC. */ +#define FSL_FEATURE_SOC_USBHSDCD_COUNT (0) +/* @brief USBHSH availability on the SoC. */ +#define FSL_FEATURE_SOC_USBHSH_COUNT (0) +/* @brief USBNC availability on the SoC. */ +#define FSL_FEATURE_SOC_USBNC_COUNT (0) +/* @brief USBPHY availability on the SoC. */ +#define FSL_FEATURE_SOC_USBPHY_COUNT (0) +/* @brief USB_HSIC availability on the SoC. */ +#define FSL_FEATURE_SOC_USB_HSIC_COUNT (0) +/* @brief USB_OTG availability on the SoC. */ +#define FSL_FEATURE_SOC_USB_OTG_COUNT (0) +/* @brief USDHC availability on the SoC. */ +#define FSL_FEATURE_SOC_USDHC_COUNT (0) +/* @brief UTICK availability on the SoC. */ +#define FSL_FEATURE_SOC_UTICK_COUNT (1) +/* @brief VIU availability on the SoC. */ +#define FSL_FEATURE_SOC_VIU_COUNT (0) +/* @brief VREF availability on the SoC. */ +#define FSL_FEATURE_SOC_VREF_COUNT (0) +/* @brief VFIFO availability on the SoC. */ +#define FSL_FEATURE_SOC_VFIFO_COUNT (1) +/* @brief WDOG availability on the SoC. */ +#define FSL_FEATURE_SOC_WDOG_COUNT (0) +/* @brief WKPU availability on the SoC. */ +#define FSL_FEATURE_SOC_WKPU_COUNT (0) +/* @brief WWDT availability on the SoC. */ +#define FSL_FEATURE_SOC_WWDT_COUNT (1) +/* @brief XBAR availability on the SoC. */ +#define FSL_FEATURE_SOC_XBAR_COUNT (0) +/* @brief XBARA availability on the SoC. */ +#define FSL_FEATURE_SOC_XBARA_COUNT (0) +/* @brief XBARB availability on the SoC. */ +#define FSL_FEATURE_SOC_XBARB_COUNT (0) +/* @brief XCVR availability on the SoC. */ +#define FSL_FEATURE_SOC_XCVR_COUNT (0) +/* @brief XRDC availability on the SoC. */ +#define FSL_FEATURE_SOC_XRDC_COUNT (0) +/* @brief XTALOSC availability on the SoC. */ +#define FSL_FEATURE_SOC_XTALOSC_COUNT (0) +/* @brief XTALOSC24M availability on the SoC. */ +#define FSL_FEATURE_SOC_XTALOSC24M_COUNT (0) +/* @brief ZLL availability on the SoC. */ +#define FSL_FEATURE_SOC_ZLL_COUNT (0) + +/* ADC module features */ + +/* @brief Has input select (register INSEL). */ +#define FSL_FEATURE_ADC_HAS_NO_INSEL (1) + +/* DMA module features */ + +/* @brief Number of channels */ +#define FSL_FEATURE_DMA_NUMBER_OF_CHANNELS (22) + +/* PINT module features */ + +/* @brief Number of connected outputs */ +#define FSL_FEATURE_PINT_NUMBER_OF_CONNECTED_OUTPUTS (8) + +/* RTC module features */ + +/* @brief Has CTRL:RTC_OSC_PD Bit */ +#define FSL_FEATURE_RTC_HAS_NO_OSC_PD (1) + +/* SCT module features */ + +/* @brief Number of events */ +#define FSL_FEATURE_SCT_NUMBER_OF_EVENTS (13) +/* @brief Number of states */ +#define FSL_FEATURE_SCT_NUMBER_OF_STATES (13) +/* @brief Number of match capture */ +#define FSL_FEATURE_SCT_NUMBER_OF_MATCH_CAPTURE (13) + +/* SYSCON module features */ + +#if defined(CPU_LPC54102J256BD64_cm4) || defined(CPU_LPC54102J256UK49_cm4) + /* @brief Pointer to ROM IAP entry functions */ + #define FSL_FEATURE_SYSCON_IAP_ENTRY_LOCATION (0x03000205) + /* @brief Flash page size in bytes */ + #define FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES (256) + /* @brief Flash sector size in bytes */ + #define FSL_FEATURE_SYSCON_FLASH_SECTOR_SIZE_BYTES (32768) + /* @brief Flash size in bytes */ + #define FSL_FEATURE_SYSCON_FLASH_SIZE_BYTES (262144) +#elif defined(CPU_LPC54102J512BD64_cm4) || defined(CPU_LPC54102J512UK49_cm4) + /* @brief Pointer to ROM IAP entry functions */ + #define FSL_FEATURE_SYSCON_IAP_ENTRY_LOCATION (0x03000205) + /* @brief Flash page size in bytes */ + #define FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES (256) + /* @brief Flash sector size in bytes */ + #define FSL_FEATURE_SYSCON_FLASH_SECTOR_SIZE_BYTES (32768) + /* @brief Flash size in bytes */ + #define FSL_FEATURE_SYSCON_FLASH_SIZE_BYTES (524288) +#endif /* defined(CPU_LPC54102J256BD64) || defined(CPU_LPC54102J256UK49) */ + +#endif /* _LPC54102_cm4_FEATURES_H_ */ + diff --git a/platform/mcu/lpc54102/RTE_Device.h b/platform/mcu/lpc54102/RTE_Device.h new file mode 100644 index 0000000000..b540ff3861 --- /dev/null +++ b/platform/mcu/lpc54102/RTE_Device.h @@ -0,0 +1,218 @@ +/* + * Copyright 2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __RTE_DEVICE_H +#define __RTE_DEVICE_H + +/* UART Select, UART0-UART7. */ +/* User needs to provide the implementation for XXX_GetFreq/XXX_InitPins/XXX_DeinitPins +in the application for enabling according instance. */ +#define RTE_USART0 0 +#define RTE_USART0_DMA_EN 0 +#define RTE_USART1 0 +#define RTE_USART1_DMA_EN 0 +#define RTE_USART2 0 +#define RTE_USART2_DMA_EN 0 +#define RTE_USART3 0 +#define RTE_USART3_DMA_EN 0 +#define RTE_USART4 0 +#define RTE_USART4_DMA_EN 0 +#define RTE_USART5 0 +#define RTE_USART5_DMA_EN 0 +#define RTE_USART6 0 +#define RTE_USART6_DMA_EN 0 +#define RTE_USART7 0 +#define RTE_USART7_DMA_EN 0 + +/* USART configuration. */ +#define USART_RX_BUFFER_LEN 64 +#define USART0_RX_BUFFER_ENABLE 0 +#define USART1_RX_BUFFER_ENABLE 0 +#define USART2_RX_BUFFER_ENABLE 0 +#define USART3_RX_BUFFER_ENABLE 0 +#define USART4_RX_BUFFER_ENABLE 0 +#define USART5_RX_BUFFER_ENABLE 0 +#define USART6_RX_BUFFER_ENABLE 0 +#define USART7_RX_BUFFER_ENABLE 0 + +#define RTE_USART0_DMA_TX_CH 1 +#define RTE_USART0_DMA_TX_DMA_BASE DMA0 +#define RTE_USART0_DMA_RX_CH 0 +#define RTE_USART0_DMA_RX_DMA_BASE DMA0 + +#define RTE_USART1_DMA_TX_CH 3 +#define RTE_USART1_DMA_TX_DMA_BASE DMA0 +#define RTE_USART1_DMA_RX_CH 2 +#define RTE_USART1_DMA_RX_DMA_BASE DMA0 + +#define RTE_USART2_DMA_TX_CH 5 +#define RTE_USART2_DMA_TX_DMA_BASE DMA0 +#define RTE_USART2_DMA_RX_CH 4 +#define RTE_USART2_DMA_RX_DMA_BASE DMA0 + +#define RTE_USART3_DMA_TX_CH 7 +#define RTE_USART3_DMA_TX_DMA_BASE DMA0 +#define RTE_USART3_DMA_RX_CH 6 +#define RTE_USART3_DMA_RX_DMA_BASE DMA0 + +#define RTE_USART4_DMA_TX_CH 9 +#define RTE_USART4_DMA_TX_DMA_BASE DMA0 +#define RTE_USART4_DMA_RX_CH 8 +#define RTE_USART4_DMA_RX_DMA_BASE DMA0 + +#define RTE_USART5_DMA_TX_CH 11 +#define RTE_USART5_DMA_TX_DMA_BASE DMA0 +#define RTE_USART5_DMA_RX_CH 10 +#define RTE_USART5_DMA_RX_DMA_BASE DMA0 + +#define RTE_USART6_DMA_TX_CH 13 +#define RTE_USART6_DMA_TX_DMA_BASE DMA0 +#define RTE_USART6_DMA_RX_CH 12 +#define RTE_USART6_DMA_RX_DMA_BASE DMA0 + +#define RTE_USART7_DMA_TX_CH 15 +#define RTE_USART7_DMA_TX_DMA_BASE DMA0 +#define RTE_USART7_DMA_RX_CH 14 +#define RTE_USART7_DMA_RX_DMA_BASE DMA0 + +/* I2C Select, I2C0 -I2C7*/ +/* User needs to provide the implementation for XXX_GetFreq/XXX_InitPins/XXX_DeinitPins +in the application for enabling according instance. */ +#define RTE_I2C0 0 +#define RTE_I2C0_DMA_EN 0 +#define RTE_I2C1 0 +#define RTE_I2C1_DMA_EN 0 +#define RTE_I2C2 0 +#define RTE_I2C2_DMA_EN 0 +#define RTE_I2C3 0 +#define RTE_I2C3_DMA_EN 0 +#define RTE_I2C4 0 +#define RTE_I2C4_DMA_EN 0 +#define RTE_I2C5 0 +#define RTE_I2C5_DMA_EN 0 +#define RTE_I2C6 0 +#define RTE_I2C6_DMA_EN 0 +#define RTE_I2C7 0 +#define RTE_I2C7_DMA_EN 0 + +/*I2C configuration*/ +#define RTE_I2C0_Master_DMA_BASE DMA0 +#define RTE_I2C0_Master_DMA_CH 1 + +#define RTE_I2C1_Master_DMA_BASE DMA0 +#define RTE_I2C1_Master_DMA_CH 3 + +#define RTE_I2C2_Master_DMA_BASE DMA0 +#define RTE_I2C2_Master_DMA_CH 5 + +#define RTE_I2C3_Master_DMA_BASE DMA0 +#define RTE_I2C3_Master_DMA_CH 7 + +#define RTE_I2C4_Master_DMA_BASE DMA0 +#define RTE_I2C4_Master_DMA_CH 9 + +#define RTE_I2C5_Master_DMA_BASE DMA0 +#define RTE_I2C5_Master_DMA_CH 11 + +#define RTE_I2C6_Master_DMA_BASE DMA0 +#define RTE_I2C6_Master_DMA_CH 13 + +#define RTE_I2C7_Master_DMA_BASE DMA0 +#define RTE_I2C7_Master_DMA_CH 15 + +/* SPI select, SPI0 - SPI7.*/ +/* User needs to provide the implementation for XXX_GetFreq/XXX_InitPins/XXX_DeinitPins +in the application for enabling according instance. */ +#define RTE_SPI0 0 +#define RTE_SPI0_DMA_EN 0 +#define RTE_SPI1 0 +#define RTE_SPI1_DMA_EN 0 +#define RTE_SPI2 0 +#define RTE_SPI2_DMA_EN 0 +#define RTE_SPI3 0 +#define RTE_SPI3_DMA_EN 0 +#define RTE_SPI4 0 +#define RTE_SPI4_DMA_EN 0 +#define RTE_SPI5 0 +#define RTE_SPI5_DMA_EN 0 +#define RTE_SPI6 0 +#define RTE_SPI6_DMA_EN 0 +#define RTE_SPI7 0 +#define RTE_SPI7_DMA_EN 0 + +/* SPI configuration. */ +#define RTE_SPI0_SSEL_NUM kSPI_Ssel0 +#define RTE_SPI0_DMA_TX_CH 1 +#define RTE_SPI0_DMA_TX_DMA_BASE DMA0 +#define RTE_SPI0_DMA_RX_CH 0 +#define RTE_SPI0_DMA_RX_DMA_BASE DMA0 + +#define RTE_SPI1_SSEL_NUM kSPI_Ssel0 +#define RTE_SPI1_DMA_TX_CH 3 +#define RTE_SPI1_DMA_TX_DMA_BASE DMA0 +#define RTE_SPI1_DMA_RX_CH 2 +#define RTE_SPI1_DMA_RX_DMA_BASE DMA0 + +#define RTE_SPI2_SSEL_NUM kSPI_Ssel0 +#define RTE_SPI2_DMA_TX_CH 5 +#define RTE_SPI2_DMA_TX_DMA_BASE DMA0 +#define RTE_SPI2_DMA_RX_CH 4 +#define RTE_SPI2_DMA_RX_DMA_BASE DMA0 + +#define RTE_SPI3_SSEL_NUM kSPI_Ssel0 +#define RTE_SPI3_DMA_TX_CH 7 +#define RTE_SPI3_DMA_TX_DMA_BASE DMA0 +#define RTE_SPI3_DMA_RX_CH 6 +#define RTE_SPI3_DMA_RX_DMA_BASE DMA0 + +#define RTE_SPI4_SSEL_NUM kSPI_Ssel0 +#define RTE_SPI4_DMA_TX_CH 9 +#define RTE_SPI4_DMA_TX_DMA_BASE DMA0 +#define RTE_SPI4_DMA_RX_CH 8 +#define RTE_SPI4_DMA_RX_DMA_BASE DMA0 + +#define RTE_SPI5_SSEL_NUM kSPI_Ssel0 +#define RTE_SPI5_DMA_TX_CH 11 +#define RTE_SPI5_DMA_TX_DMA_BASE DMA0 +#define RTE_SPI5_DMA_RX_CH 10 +#define RTE_SPI5_DMA_RX_DMA_BASE DMA0 + +#define RTE_SPI6_SSEL_NUM kSPI_Ssel0 +#define RTE_SPI6_DMA_TX_CH 13 +#define RTE_SPI6_DMA_TX_DMA_BASE DMA0 +#define RTE_SPI6_DMA_RX_CH 12 +#define RTE_SPI6_DMA_RX_DMA_BASE DMA0 + +#define RTE_SPI7_SSEL_NUM kSPI_Ssel0 +#define RTE_SPI7_DMA_TX_CH 15 +#define RTE_SPI7_DMA_TX_DMA_BASE DMA0 +#define RTE_SPI7_DMA_RX_CH 14 +#define RTE_SPI7_DMA_RX_DMA_BASE DMA0 + +#endif /* __RTE_DEVICE_H */ diff --git a/platform/mcu/lpc54102/aos/aos.c b/platform/mcu/lpc54102/aos/aos.c new file mode 100644 index 0000000000..1672c8ed1e --- /dev/null +++ b/platform/mcu/lpc54102/aos/aos.c @@ -0,0 +1,195 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#include "board.h" +#include "fsl_debug_console.h" +#include "fsl_gpio.h" + +#include "pin_mux.h" + +#include +#include +#include +#include +#include +#include +#include "hal/wifi.h" +#include "hal/ota.h" + +#define AOS_START_STACK 1536 + +#define WIFI_PRODUCT_INFO_SIZE ES_WIFI_MAX_SSID_NAME_SIZE + +ktask_t *g_aos_init; +ktask_t *g_aos_app = NULL; +extern int application_start(int argc, char **argv); +extern int aos_framework_init(void); + +extern hal_wifi_module_t qca_4002_wmi; + +static int init_wifi() +{ + int ret; + PRINTF("Register WMI Wifi 0x%x", &qca_4002_wmi); + hal_wifi_register_module(&qca_4002_wmi); + ret = hal_wifi_init(); + PRINTF("hal_wifi_init return %d", ret); +} + + +extern void hw_start_hal(void); + +static void sys_init(void) +{ + int i = 0; + + init_wifi(); + +#ifdef BOOTLOADER + +#else +#ifdef AOS_VFS + vfs_init(); + vfs_device_init(); +#endif + +#ifdef CONFIG_AOS_CLI +// aos_cli_init(); +#endif + +#ifdef AOS_KV + aos_kv_init(); +#endif + +#ifdef WITH_SAL + sal_device_init(); +#endif + +#ifdef AOS_LOOP + aos_loop_init(); +#endif + +#ifdef AOS_FOTA + ota_service_init(); +#endif + + aos_framework_init(); + application_start(0, NULL); +#endif +} +extern struct hal_ota_module_s hal_lpc54102_ota_module; +static void platform_init(void) +{ + uint32_t port_state = 0; + + /* Define the init structure for the output LED pin*/ + gpio_pin_config_t led_config = { + kGPIO_DigitalOutput, 0, + }; + + /* Board pin, clock, debug console init */ + /* attach 12 MHz clock to USART0 (debug console) */ + CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH); + /* enable clock for GPIO*/ + CLOCK_EnableClock(kCLOCK_Gpio0); + CLOCK_EnableClock(kCLOCK_Gpio1); + CLOCK_EnableClock(kCLOCK_Sram1); + CLOCK_EnableClock(kCLOCK_Sram2); + + + BOARD_InitPins(); + BOARD_BootClockPLL96M(); /* Rev B device can only support max core frequency to 96Mhz. + Rev C device can support 100Mhz,use BOARD_BootClockPLL100M() to boot core to 100Mhz. + DEVICE_ID1 register in SYSCON shows the device version. + More details please refer to user manual and errata. */ + BOARD_InitDebugConsole(); + +#ifdef AOS_FOTA + hal_ota_register_module(&hal_lpc54102_ota_module); +#endif + +} + + +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define TAG "hw" + +#define us2tick(us) \ + ((us * RHINO_CONFIG_TICKS_PER_SECOND + 999999) / 1000000) + + +void hal_reboot(void) +{ + NVIC_SystemReset(); +} + +static void _timer_cb(void *timer, void *arg) +{ + timer_dev_t *tmr = arg; + tmr->config.cb(tmr->config.arg); +} + +int32_t hal_timer_init(timer_dev_t *tim) +{ + if (tim->config.reload_mode == TIMER_RELOAD_AUTO) { + krhino_timer_dyn_create((ktimer_t **)&tim->priv, "hwtmr", _timer_cb, + us2tick(tim->config.period), us2tick(tim->config.period), tim, 0); + } + else { + krhino_timer_dyn_create((ktimer_t **)&tim->priv, "hwtmr", _timer_cb, + us2tick(tim->config.period), 0, tim, 0); + } +} + +int32_t hal_timer_start(timer_dev_t *tmr) +{ + return krhino_timer_start(tmr->priv); +} + + +void hal_timer_stop(timer_dev_t *tmr) +{ + krhino_timer_stop(tmr->priv); + krhino_timer_dyn_del(tmr->priv); + tmr->priv = NULL; +} + + +void hw_start_hal(void) +{ + PRINTF("start-----------hal\n"); +} + + +int main(void) +{ + uint32_t core_frequency = 0; + platform_init(); + + aos_init(); + krhino_task_dyn_create(&g_aos_app, "aos-init", 0, AOS_DEFAULT_APP_PRI, 0, AOS_START_STACK, (task_entry_t)sys_init, 1); + core_frequency = CLOCK_GetCoreClkFreq(); + + SysTick_Config(core_frequency / 100); //10ms + aos_start(); + return 0; +} + + diff --git a/platform/mcu/lpc54102/aos/soc_impl.c b/platform/mcu/lpc54102/aos/soc_impl.c new file mode 100644 index 0000000000..46123fc602 --- /dev/null +++ b/platform/mcu/lpc54102/aos/soc_impl.c @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#include +#include + +#if (RHINO_CONFIG_HW_COUNT > 0) +void soc_hw_timer_init(void) +{ +} + +hr_timer_t soc_hr_hw_cnt_get(void) +{ + return 0; + //return *(volatile uint64_t *)0xc0000120; +} + +lr_timer_t soc_lr_hw_cnt_get(void) +{ + return 0; +} +#endif /* RHINO_CONFIG_HW_COUNT */ + +#if (RHINO_CONFIG_INTRPT_GUARD > 0) +void soc_intrpt_guard(void) +{ +} +#endif + +#if (RHINO_CONFIG_INTRPT_STACK_REMAIN_GET > 0) +size_t soc_intrpt_stack_remain_get(void) +{ + return 0; +} +#endif + +#if (RHINO_CONFIG_INTRPT_STACK_OVF_CHECK > 0) +void soc_intrpt_stack_ovf_check(void) +{ +} +#endif + +#if (RHINO_CONFIG_DYNTICKLESS > 0) +void soc_tick_interrupt_set(tick_t next_ticks,tick_t elapsed_ticks) +{ +} + +tick_t soc_elapsed_ticks_get(void) +{ + return 0; +} +#endif + +#if (RHINO_CONFIG_MM_LEAKCHECK > 0 ) + +extern int __bss_start__, __bss_end__, _sdata, _edata; + +void aos_mm_leak_region_init(void) +{ +#if (RHINO_CONFIG_MM_DEBUG > 0) + krhino_mm_leak_region_init(&__bss_start__, &__bss_end__); + krhino_mm_leak_region_init(&_sdata, &_edata); +#endif +} + +#endif + +#if (RHINO_CONFIG_TASK_STACK_CUR_CHECK > 0) +size_t soc_get_cur_sp() +{ + size_t sp = 0; + asm volatile( + "mov %0,sp\n" + :"=r"(sp)); + return sp; +} +#endif +static void soc_print_stack() +{ + + uint32_t offset = 0; + kstat_t rst = RHINO_SUCCESS; + void *cur, *end; + int i=0; + int *p; + + end = krhino_cur_task_get()->task_stack_base + krhino_cur_task_get()->stack_size; + cur = (void*)soc_get_cur_sp(); + p = (int*)cur; + while(p < (int*)end) { + if(i%4==0) { + printf("\r\n%08x:",(uint32_t)p); + } + printf("%08x ", *p); + i++; + p++; + } + printf("\r\n"); + return; +} +void soc_err_proc(kstat_t err) +{ + (void)err; + soc_print_stack(); + assert(0); +} + +krhino_err_proc_t g_err_proc = soc_err_proc; + +#include "k_api.h" +extern void *_pvHeapStart; +extern void *_pvHeapLimit; +extern uint8_t _vHeap2Base[]; +k_mm_region_t g_mm_region[] = { +{ + (uint8_t *)&_pvHeapStart, (uint32_t)0xE800}, + {_vHeap2Base, 0x1800,}, +}; + +int g_region_num = sizeof(g_mm_region)/sizeof(k_mm_region_t); + +void SysTick_Handler(void) +{ + krhino_intrpt_enter(); + krhino_tick_proc(); + krhino_intrpt_exit(); +} diff --git a/platform/mcu/lpc54102/drivers/fsl_adc.c b/platform/mcu/lpc54102/drivers/fsl_adc.c new file mode 100644 index 0000000000..2c8b2cb111 --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_adc.c @@ -0,0 +1,316 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_adc.h" +#include "fsl_clock.h" + +static ADC_Type *const s_adcBases[] = ADC_BASE_PTRS; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +static const clock_ip_name_t s_adcClocks[] = ADC_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +static uint32_t ADC_GetInstance(ADC_Type *base) +{ + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < ARRAY_SIZE(s_adcBases); instance++) + { + if (s_adcBases[instance] == base) + { + break; + } + } + + assert(instance < ARRAY_SIZE(s_adcBases)); + + return instance; +} + +void ADC_Init(ADC_Type *base, const adc_config_t *config) +{ + assert(config != NULL); + + uint32_t tmp32 = 0U; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Enable clock. */ + CLOCK_EnableClock(s_adcClocks[ADC_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + + /* Disable the interrupts. */ + base->INTEN = 0U; /* Quickly disable all the interrupts. */ + + /* Configure the ADC block. */ + tmp32 = ADC_CTRL_CLKDIV(config->clockDividerNumber); + + /* Async or Sync clock mode. */ + switch (config->clockMode) + { + case kADC_ClockAsynchronousMode: + tmp32 |= ADC_CTRL_ASYNMODE_MASK; + break; + default: /* kADC_ClockSynchronousMode */ + break; + } + + /* Resolution. */ + tmp32 |= ADC_CTRL_RESOL(config->resolution); + + /* Bypass calibration. */ + if (config->enableBypassCalibration) + { + tmp32 |= ADC_CTRL_BYPASSCAL_MASK; + } + + /* Sample time clock count. */ + tmp32 |= ADC_CTRL_TSAMP(config->sampleTimeNumber); + + base->CTRL = tmp32; +} + +void ADC_GetDefaultConfig(adc_config_t *config) +{ + config->clockMode = kADC_ClockSynchronousMode; + config->clockDividerNumber = 0U; + config->resolution = kADC_Resolution12bit; + config->enableBypassCalibration = false; + config->sampleTimeNumber = 0U; +} + +void ADC_Deinit(ADC_Type *base) +{ +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Disable the clock. */ + CLOCK_DisableClock(s_adcClocks[ADC_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +bool ADC_DoSelfCalibration(ADC_Type *base) +{ + uint32_t i; + + /* Enable the converter. */ + /* This bit acn only be set 1 by software. It is cleared automatically whenever the ADC is powered down. + This bit should be set after at least 10 ms after the ADC is powered on. */ + base->STARTUP = ADC_STARTUP_ADC_ENA_MASK; + for (i = 0U; i < 0x10; i++) /* Wait a few clocks to startup up. */ + { + __ASM("NOP"); + } + if (!(base->STARTUP & ADC_STARTUP_ADC_ENA_MASK)) + { + return false; /* ADC is not powered up. */ + } + + /* If not in by-pass mode, do the calibration. */ + if ((ADC_CALIB_CALREQD_MASK == (base->CALIB & ADC_CALIB_CALREQD_MASK)) && + (0U == (base->CTRL & ADC_CTRL_BYPASSCAL_MASK))) + { + /* Calibration is needed, do it now. */ + base->CALIB = ADC_CALIB_CALIB_MASK; + i = 0xF0000; + while ((ADC_CALIB_CALIB_MASK == (base->CALIB & ADC_CALIB_CALIB_MASK)) && (--i)) + { + } + if (i == 0U) + { + return false; /* Calibration timeout. */ + } + } + + /* A dummy conversion cycle will be performed. */ + base->STARTUP |= ADC_STARTUP_ADC_INIT_MASK; + i = 0x7FFFF; + while ((ADC_STARTUP_ADC_INIT_MASK == (base->STARTUP & ADC_STARTUP_ADC_INIT_MASK)) && (--i)) + { + } + if (i == 0U) + { + return false; + } + + return true; +} + +void ADC_SetConvSeqAConfig(ADC_Type *base, const adc_conv_seq_config_t *config) +{ + assert(config != NULL); + + uint32_t tmp32; + + tmp32 = ADC_SEQ_CTRL_CHANNELS(config->channelMask) /* Channel mask. */ + | ADC_SEQ_CTRL_TRIGGER(config->triggerMask); /* Trigger mask. */ + + /* Polarity for tirgger signal. */ + switch (config->triggerPolarity) + { + case kADC_TriggerPolarityPositiveEdge: + tmp32 |= ADC_SEQ_CTRL_TRIGPOL_MASK; + break; + default: /* kADC_TriggerPolarityNegativeEdge */ + break; + } + + /* Bypass the clock Sync. */ + if (config->enableSyncBypass) + { + tmp32 |= ADC_SEQ_CTRL_SYNCBYPASS_MASK; + } + + /* Interrupt point. */ + switch (config->interruptMode) + { + case kADC_InterruptForEachSequence: + tmp32 |= ADC_SEQ_CTRL_MODE_MASK; + break; + default: /* kADC_InterruptForEachConversion */ + break; + } + + /* One trigger for a conversion, or for a sequence. */ + if (config->enableSingleStep) + { + tmp32 |= ADC_SEQ_CTRL_SINGLESTEP_MASK; + } + + base->SEQ_CTRL[0] = tmp32; +} + +void ADC_SetConvSeqBConfig(ADC_Type *base, const adc_conv_seq_config_t *config) +{ + assert(config != NULL); + + uint32_t tmp32; + + tmp32 = ADC_SEQ_CTRL_CHANNELS(config->channelMask) /* Channel mask. */ + | ADC_SEQ_CTRL_TRIGGER(config->triggerMask); /* Trigger mask. */ + + /* Polarity for tirgger signal. */ + switch (config->triggerPolarity) + { + case kADC_TriggerPolarityPositiveEdge: + tmp32 |= ADC_SEQ_CTRL_TRIGPOL_MASK; + break; + default: /* kADC_TriggerPolarityPositiveEdge */ + break; + } + + /* Bypass the clock Sync. */ + if (config->enableSyncBypass) + { + tmp32 |= ADC_SEQ_CTRL_SYNCBYPASS_MASK; + } + + /* Interrupt point. */ + switch (config->interruptMode) + { + case kADC_InterruptForEachSequence: + tmp32 |= ADC_SEQ_CTRL_MODE_MASK; + break; + default: /* kADC_InterruptForEachConversion */ + break; + } + + /* One trigger for a conversion, or for a sequence. */ + if (config->enableSingleStep) + { + tmp32 |= ADC_SEQ_CTRL_SINGLESTEP_MASK; + } + + base->SEQ_CTRL[1] = tmp32; +} + +bool ADC_GetConvSeqAGlobalConversionResult(ADC_Type *base, adc_result_info_t *info) +{ + assert(info != NULL); + + uint32_t tmp32 = base->SEQ_GDAT[0]; /* Read to clear the status. */ + + if (0U == (ADC_SEQ_GDAT_DATAVALID_MASK & tmp32)) + { + return false; + } + + info->result = (tmp32 & ADC_SEQ_GDAT_RESULT_MASK) >> ADC_SEQ_GDAT_RESULT_SHIFT; + info->thresholdCompareStatus = + (adc_threshold_compare_status_t)((tmp32 & ADC_SEQ_GDAT_THCMPRANGE_MASK) >> ADC_SEQ_GDAT_THCMPRANGE_SHIFT); + info->thresholdCorssingStatus = + (adc_threshold_crossing_status_t)((tmp32 & ADC_SEQ_GDAT_THCMPCROSS_MASK) >> ADC_SEQ_GDAT_THCMPCROSS_SHIFT); + info->channelNumber = (tmp32 & ADC_SEQ_GDAT_CHN_MASK) >> ADC_SEQ_GDAT_CHN_SHIFT; + info->overrunFlag = ((tmp32 & ADC_SEQ_GDAT_OVERRUN_MASK) == ADC_SEQ_GDAT_OVERRUN_MASK); + + return true; +} + +bool ADC_GetConvSeqBGlobalConversionResult(ADC_Type *base, adc_result_info_t *info) +{ + assert(info != NULL); + + uint32_t tmp32 = base->SEQ_GDAT[1]; /* Read to clear the status. */ + + if (0U == (ADC_SEQ_GDAT_DATAVALID_MASK & tmp32)) + { + return false; + } + + info->result = (tmp32 & ADC_SEQ_GDAT_RESULT_MASK) >> ADC_SEQ_GDAT_RESULT_SHIFT; + info->thresholdCompareStatus = + (adc_threshold_compare_status_t)((tmp32 & ADC_SEQ_GDAT_THCMPRANGE_MASK) >> ADC_SEQ_GDAT_THCMPRANGE_SHIFT); + info->thresholdCorssingStatus = + (adc_threshold_crossing_status_t)((tmp32 & ADC_SEQ_GDAT_THCMPCROSS_MASK) >> ADC_SEQ_GDAT_THCMPCROSS_SHIFT); + info->channelNumber = (tmp32 & ADC_SEQ_GDAT_CHN_MASK) >> ADC_SEQ_GDAT_CHN_SHIFT; + info->overrunFlag = ((tmp32 & ADC_SEQ_GDAT_OVERRUN_MASK) == ADC_SEQ_GDAT_OVERRUN_MASK); + + return true; +} + +bool ADC_GetChannelConversionResult(ADC_Type *base, uint32_t channel, adc_result_info_t *info) +{ + assert(info != NULL); + assert(channel < ADC_DAT_COUNT); + + uint32_t tmp32 = base->DAT[channel]; /* Read to clear the status. */ + + if (0U == (ADC_DAT_DATAVALID_MASK & tmp32)) + { + return false; + } + + info->result = (tmp32 & ADC_DAT_RESULT_MASK) >> ADC_DAT_RESULT_SHIFT; + info->thresholdCompareStatus = + (adc_threshold_compare_status_t)((tmp32 & ADC_DAT_THCMPRANGE_MASK) >> ADC_DAT_THCMPRANGE_SHIFT); + info->thresholdCorssingStatus = + (adc_threshold_crossing_status_t)((tmp32 & ADC_DAT_THCMPCROSS_MASK) >> ADC_DAT_THCMPCROSS_SHIFT); + info->channelNumber = (tmp32 & ADC_DAT_CHANNEL_MASK) >> ADC_DAT_CHANNEL_SHIFT; + info->overrunFlag = ((tmp32 & ADC_DAT_OVERRUN_MASK) == ADC_DAT_OVERRUN_MASK); + + return true; +} diff --git a/platform/mcu/lpc54102/drivers/fsl_adc.h b/platform/mcu/lpc54102/drivers/fsl_adc.h new file mode 100644 index 0000000000..f1f173d163 --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_adc.h @@ -0,0 +1,676 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __FSL_ADC_H__ +#define __FSL_ADC_H__ + +#include "fsl_common.h" + +/*! + * @addtogroup lpc_adc + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief ADC driver version 2.1.0. */ +#define LPC_ADC_DRIVER_VERSION (MAKE_VERSION(2, 1, 0)) +/*@}*/ + +/*! + * @brief Flags + */ +enum _adc_status_flags +{ + kADC_ThresholdCompareFlagOnChn0 = 1U << 0U, /*!< Threshold comparison event on Channel 0. */ + kADC_ThresholdCompareFlagOnChn1 = 1U << 1U, /*!< Threshold comparison event on Channel 1. */ + kADC_ThresholdCompareFlagOnChn2 = 1U << 2U, /*!< Threshold comparison event on Channel 2. */ + kADC_ThresholdCompareFlagOnChn3 = 1U << 3U, /*!< Threshold comparison event on Channel 3. */ + kADC_ThresholdCompareFlagOnChn4 = 1U << 4U, /*!< Threshold comparison event on Channel 4. */ + kADC_ThresholdCompareFlagOnChn5 = 1U << 5U, /*!< Threshold comparison event on Channel 5. */ + kADC_ThresholdCompareFlagOnChn6 = 1U << 6U, /*!< Threshold comparison event on Channel 6. */ + kADC_ThresholdCompareFlagOnChn7 = 1U << 7U, /*!< Threshold comparison event on Channel 7. */ + kADC_ThresholdCompareFlagOnChn8 = 1U << 8U, /*!< Threshold comparison event on Channel 8. */ + kADC_ThresholdCompareFlagOnChn9 = 1U << 9U, /*!< Threshold comparison event on Channel 9. */ + kADC_ThresholdCompareFlagOnChn10 = 1U << 10U, /*!< Threshold comparison event on Channel 10. */ + kADC_ThresholdCompareFlagOnChn11 = 1U << 11U, /*!< Threshold comparison event on Channel 11. */ + kADC_OverrunFlagForChn0 = + 1U << 12U, /*!< Mirror the OVERRUN status flag from the result register for ADC channel 0. */ + kADC_OverrunFlagForChn1 = + 1U << 13U, /*!< Mirror the OVERRUN status flag from the result register for ADC channel 1. */ + kADC_OverrunFlagForChn2 = + 1U << 14U, /*!< Mirror the OVERRUN status flag from the result register for ADC channel 2. */ + kADC_OverrunFlagForChn3 = + 1U << 15U, /*!< Mirror the OVERRUN status flag from the result register for ADC channel 3. */ + kADC_OverrunFlagForChn4 = + 1U << 16U, /*!< Mirror the OVERRUN status flag from the result register for ADC channel 4. */ + kADC_OverrunFlagForChn5 = + 1U << 17U, /*!< Mirror the OVERRUN status flag from the result register for ADC channel 5. */ + kADC_OverrunFlagForChn6 = + 1U << 18U, /*!< Mirror the OVERRUN status flag from the result register for ADC channel 6. */ + kADC_OverrunFlagForChn7 = + 1U << 19U, /*!< Mirror the OVERRUN status flag from the result register for ADC channel 7. */ + kADC_OverrunFlagForChn8 = + 1U << 20U, /*!< Mirror the OVERRUN status flag from the result register for ADC channel 8. */ + kADC_OverrunFlagForChn9 = + 1U << 21U, /*!< Mirror the OVERRUN status flag from the result register for ADC channel 9. */ + kADC_OverrunFlagForChn10 = + 1U << 22U, /*!< Mirror the OVERRUN status flag from the result register for ADC channel 10. */ + kADC_OverrunFlagForChn11 = + 1U << 23U, /*!< Mirror the OVERRUN status flag from the result register for ADC channel 11. */ + kADC_GlobalOverrunFlagForSeqA = 1U << 24U, /*!< Mirror the glabal OVERRUN status flag for conversion sequence A. */ + kADC_GlobalOverrunFlagForSeqB = 1U << 25U, /*!< Mirror the global OVERRUN status flag for conversion sequence B. */ + kADC_ConvSeqAInterruptFlag = 1U << 28U, /*!< Sequence A interrupt/DMA trigger. */ + kADC_ConvSeqBInterruptFlag = 1U << 29U, /*!< Sequence B interrupt/DMA trigger. */ + kADC_ThresholdCompareInterruptFlag = 1U << 30U, /*!< Threshold comparision interrupt flag. */ + kADC_OverrunInterruptFlag = 1U << 31U, /*!< Overrun interrupt flag. */ +}; + +/*! + * @brief Interrupts + * @note Not all the interrupt options are listed here + */ +enum _adc_interrupt_enable +{ + kADC_ConvSeqAInterruptEnable = ADC_INTEN_SEQA_INTEN_MASK, /*!< Enable interrupt upon completion of each individual + conversion in sequence A, or entire sequence. */ + kADC_ConvSeqBInterruptEnable = ADC_INTEN_SEQB_INTEN_MASK, /*!< Enable interrupt upon completion of each individual + conversion in sequence B, or entire sequence. */ + kADC_OverrunInterruptEnable = ADC_INTEN_OVR_INTEN_MASK, /*!< Enable the detection of an overrun condition on any of + the channel data registers will cause an overrun + interrupt/DMA trigger. */ +}; + +/*! + * @brief Define selection of clock mode. + */ +typedef enum _adc_clock_mode +{ + kADC_ClockSynchronousMode = + 0U, /*!< The ADC clock would be derived from the system clock based on "clockDividerNumber". */ + kADC_ClockAsynchronousMode = 1U, /*!< The ADC clock would be based on the SYSCON block's divider. */ +} adc_clock_mode_t; + +/*! + * @brief Define selection of resolution. + */ +typedef enum _adc_resolution +{ + kADC_Resolution6bit = 0U, /*!< 6-bit resolution. */ + kADC_Resolution8bit = 1U, /*!< 8-bit resolution. */ + kADC_Resolution10bit = 2U, /*!< 10-bit resolution. */ + kADC_Resolution12bit = 3U, /*!< 12-bit resolution. */ +} adc_resolution_t; + +/*! + * @brief Define selection of polarity of selected input trigger for conversion sequence. + */ +typedef enum _adc_trigger_polarity +{ + kADC_TriggerPolarityNegativeEdge = 0U, /*!< A negative edge launches the conversion sequence on the trigger(s). */ + kADC_TriggerPolarityPositiveEdge = 1U, /*!< A positive edge launches the conversion sequence on the trigger(s). */ +} adc_trigger_polarity_t; + +/*! + * @brief Define selection of conversion sequence's priority. + */ +typedef enum _adc_priority +{ + kADC_PriorityLow = 0U, /*!< This sequence would be preempted when another sequence is started. */ + kADC_PriorityHigh = 1U, /*!< This sequence would preempt other sequence even when it is started. */ +} adc_priority_t; + +/*! + * @brief Define selection of conversion sequence's interrupt. + */ +typedef enum _adc_seq_interrupt_mode +{ + kADC_InterruptForEachConversion = 0U, /*!< The sequence interrupt/DMA trigger will be set at the end of each + individual ADC conversion inside this conversion sequence. */ + kADC_InterruptForEachSequence = 1U, /*!< The sequence interrupt/DMA trigger will be set when the entire set of + this sequence conversions completes. */ +} adc_seq_interrupt_mode_t; + +/*! + * @brief Define status of threshold compare result. + */ +typedef enum _adc_threshold_compare_status +{ + kADC_ThresholdCompareInRange = 0U, /*!< LOW threshold <= conversion value <= HIGH threshold. */ + kADC_ThresholdCompareBelowRange = 1U, /*!< conversion value < LOW threshold. */ + kADC_ThresholdCompareAboveRange = 2U, /*!< conversion value > HIGH threshold. */ +} adc_threshold_compare_status_t; + +/*! + * @brief Define status of threshold crossing detection result. + */ +typedef enum _adc_threshold_crossing_status +{ + /* The conversion on this channel had the same relationship (above or below) to the threshold value established by + * the designated LOW threshold value as did the previous conversion on this channel. */ + kADC_ThresholdCrossingNoDetected = 0U, /*!< No threshold Crossing detected. */ + + /* Indicates that a threshold crossing in the downward direction has occurred - i.e. the previous sample on this + * channel was above the threshold value established by the designated LOW threshold value and the current sample is + * below that threshold. */ + kADC_ThresholdCrossingDownward = 2U, /*!< Downward Threshold Crossing detected. */ + + /* Indicates that a thre shold crossing in the upward direction has occurred - i.e. the previous sample on this + * channel was below the threshold value established by the designated LOW threshold value and the current sample is + * above that threshold. */ + kADC_ThresholdCrossingUpward = 3U, /*!< Upward Threshold Crossing Detected. */ +} adc_threshold_crossing_status_t; + +/*! + * @brief Define interrupt mode for threshold compare event. + */ +typedef enum _adc_threshold_interrupt_mode +{ + kADC_ThresholdInterruptDisabled = 0U, /*!< Threshold comparison interrupt is disabled. */ + kADC_ThresholdInterruptOnOutside = 1U, /*!< Threshold comparison interrupt is enabled on outside threshold. */ + kADC_ThresholdInterruptOnCrossing = 2U, /*!< Threshold comparison interrupt is enabled on crossing threshold. */ +} adc_threshold_interrupt_mode_t; + +/*! + * @brief Define structure for configuring the block. + */ +typedef struct _adc_config +{ + adc_clock_mode_t clockMode; /*!< Select the clock mode for ADC converter. */ + uint32_t clockDividerNumber; /*!< This field is only available when using kADC_ClockSynchronousMode for "clockMode" + field. The divider would be plused by 1 based on the value in this field. The + available range is in 8 bits. */ + adc_resolution_t resolution; /*!< Select the conversion bits. */ + bool enableBypassCalibration; /*!< By default, a calibration cycle must be performed each time the chip is + powered-up. Re-calibration may be warranted periodically - especially if + operating conditions have changed. To enable this option would avoid the need to + calibrate if offset error is not a concern in the application. */ + uint32_t sampleTimeNumber; /*!< By default, with value as "0U", the sample period would be 2.5 ADC clocks. Then, + to plus the "sampleTimeNumber" value here. The available value range is in 3 bits.*/ +} adc_config_t; + +/*! + * @brief Define structure for configuring conversion sequence. + */ +typedef struct _adc_conv_seq_config +{ + uint32_t channelMask; /*!< Selects which one or more of the ADC channels will be sampled and converted when this + sequence is launched. The masked channels would be involved in current conversion + sequence, beginning with the lowest-order. The available range is in 12-bit. */ + uint32_t triggerMask; /*!< Selects which one or more of the available hardware trigger sources will cause this + conversion sequence to be initiated. The available range is 6-bit.*/ + adc_trigger_polarity_t triggerPolarity; /*!< Select the trigger to lauch conversion sequence. */ + bool enableSyncBypass; /*!< To enable this feature allows the hardware trigger input to bypass synchronization + flip-flop stages and therefore shorten the time between the trigger input signal and the + start of a conversion. */ + bool enableSingleStep; /*!< When enabling this feature, a trigger will launch a single conversion on the next + channel in the sequence instead of the default response of launching an entire sequence + of conversions. */ + adc_seq_interrupt_mode_t interruptMode; /*!< Select the interrpt/DMA trigger mode. */ +} adc_conv_seq_config_t; + +/*! + * @brief Define structure of keeping conversion result information. + */ +typedef struct _adc_result_info +{ + uint32_t result; /*!< Keep the conversion data value. */ + adc_threshold_compare_status_t thresholdCompareStatus; /*!< Keep the threshold compare status. */ + adc_threshold_crossing_status_t thresholdCorssingStatus; /*!< Keep the threshold crossing status. */ + uint32_t channelNumber; /*!< Keep the channel number for this conversion. */ + bool overrunFlag; /*!< Keep the status whether the conversion is overrun or not. */ + /* The data available flag would be returned by the reading result API. */ +} adc_result_info_t; + +#if defined(__cplusplus) +extern "C" { +#endif + +/******************************************************************************* + * API + ******************************************************************************/ + +/*! + * @name Initialization and Deinitialization + * @{ + */ + +/*! + * @brief Initialize the ADC module. + * + * @param base ADC peripheral base address. + * @param config Pointer to configuration structure, see to #adc_config_t. + */ +void ADC_Init(ADC_Type *base, const adc_config_t *config); + +/*! + * @brief Deinitialize the ADC module. + * + * @param base ADC peripheral base address. + */ +void ADC_Deinit(ADC_Type *base); + +/*! + * @brief Gets an available pre-defined settings for initial configuration. + * + * This function initializes the initial configuration structure with an available settings. The default values are: + * @code + * config->clockMode = kADC_ClockSynchronousMode; + * config->clockDividerNumber = 0U; + * config->resolution = kADC_Resolution12bit; + * config->enableBypassCalibration = false; + * config->sampleTimeNumber = 0U; + * @endcode + * @param config Pointer to configuration structure. + */ +void ADC_GetDefaultConfig(adc_config_t *config); + +/*! + * @brief Do the self hardware calibration. + * + * @param base ADC peripheral base address. + * @retval true Calibration succeed. + * @retval false Calibration failed. + */ +bool ADC_DoSelfCalibration(ADC_Type *base); + +#if !(defined(FSL_FEATURE_ADC_HAS_NO_INSEL) && FSL_FEATURE_ADC_HAS_NO_INSEL) +/*! + * @brief Enable the internal temperature sensor measurement. + * + * When enabling the internal temperature sensor measurement, the channel 0 would be connected to internal sensor + * instead of external pin. + * + * @param base ADC peripheral base address. + * @param enable Switcher to enable the feature or not. + */ +static inline void ADC_EnableTemperatureSensor(ADC_Type *base, bool enable) +{ + if (enable) + { + base->INSEL = (base->INSEL & ~ADC_INSEL_SEL_MASK) | ADC_INSEL_SEL(0x3); + } + else + { + base->INSEL = (base->INSEL & ~ADC_INSEL_SEL_MASK) | ADC_INSEL_SEL(0); + } +} +#endif /* FSL_FEATURE_ADC_HAS_NO_INSEL. */ +/* @} */ + +/*! + * @name Control conversion sequence A. + * @{ + */ + +/*! + * @brief Enable the conversion sequence A. + * + * In order to avoid spuriously triggering the sequence, the trigger to conversion sequence should be ready before the + * sequence is ready. when the sequence is disabled, the trigger would be ignored. Also, it is suggested to disable the + * sequence during changing the sequence's setting. + * + * @param base ADC peripheral base address. + * @param enable Switcher to enable the feature or not. + */ +static inline void ADC_EnableConvSeqA(ADC_Type *base, bool enable) +{ + if (enable) + { + base->SEQ_CTRL[0] |= ADC_SEQ_CTRL_SEQ_ENA_MASK; + } + else + { + base->SEQ_CTRL[0] &= ~ADC_SEQ_CTRL_SEQ_ENA_MASK; + } +} + +/*! + * @brief Configure the conversion sequence A. + * + * @param base ADC peripheral base address. + * @param config Pointer to configuration structure, see to #adc_conv_seq_config_t. + */ +void ADC_SetConvSeqAConfig(ADC_Type *base, const adc_conv_seq_config_t *config); + +/*! + * @brief Do trigger the sequence's conversion by software. + * + * @param base ADC peripheral base address. + */ +static inline void ADC_DoSoftwareTriggerConvSeqA(ADC_Type *base) +{ + base->SEQ_CTRL[0] |= ADC_SEQ_CTRL_START_MASK; +} + +/*! + * @brief Enable the burst conversion of sequence A. + * + * Enable the burst mode would cause the conversion sequence to be cntinuously cycled through. Other triggers would be + * ignored while this mode is enabled. Repeated conversions could be halted by disabling this mode. And the sequence + * currently in process will be completed before cnversions are terminated. + * Note that a new sequence could begin just before the burst mode is disabled. + * + * @param base ADC peripheral base address. + * @param enable Switcher to enable this feature. + */ +static inline void ADC_EnableConvSeqABurstMode(ADC_Type *base, bool enable) +{ + if (enable) + { + base->SEQ_CTRL[0] |= ADC_SEQ_CTRL_BURST_MASK; + } + else + { + base->SEQ_CTRL[0] &= ~ADC_SEQ_CTRL_BURST_MASK; + } +} + +/*! + * @brief Set the high priority for conversion sequence A. + * + * @param base ADC peripheral bass address. + */ +static inline void ADC_SetConvSeqAHighPriority(ADC_Type *base) +{ + base->SEQ_CTRL[0] |= ADC_SEQ_CTRL_LOWPRIO_MASK; +} + +/* @} */ + +/*! + * @name Control conversion sequence B. + * @{ + */ + +/*! + * @brief Enable the conversion sequence B. + * + * In order to avoid spuriously triggering the sequence, the trigger to conversion sequence should be ready before the + * sequence is ready. when the sequence is disabled, the trigger would be ignored. Also, it is suggested to disable the + * sequence during changing the sequence's setting. + * + * @param base ADC peripheral base address. + * @param enable Switcher to enable the feature or not. + */ +static inline void ADC_EnableConvSeqB(ADC_Type *base, bool enable) +{ + if (enable) + { + base->SEQ_CTRL[1] |= ADC_SEQ_CTRL_SEQ_ENA_MASK; + } + else + { + base->SEQ_CTRL[1] &= ~ADC_SEQ_CTRL_SEQ_ENA_MASK; + } +} + +/*! + * @brief Configure the conversion sequence B. + * + * @param base ADC peripheral base address. + * @param config Pointer to configuration structure, see to #adc_conv_seq_config_t. + */ +void ADC_SetConvSeqBConfig(ADC_Type *base, const adc_conv_seq_config_t *config); + +/*! + * @brief Do trigger the sequence's conversion by software. + * + * @param base ADC peripheral base address. + */ +static inline void ADC_DoSoftwareTriggerConvSeqB(ADC_Type *base) +{ + base->SEQ_CTRL[1] |= ADC_SEQ_CTRL_START_MASK; +} + +/*! + * @brief Enable the burst conversion of sequence B. + * + * Enable the burst mode would cause the conversion sequence to be continuously cycled through. Other triggers would be + * ignored while this mode is enabled. Repeated conversions could be halted by disabling this mode. And the sequence + * currently in process will be completed before cnversions are terminated. + * Note that a new sequence could begin just before the burst mode is disabled. + * + * @param base ADC peripheral base address. + * @param enable Switcher to enable this feature. + */ +static inline void ADC_EnableConvSeqBBurstMode(ADC_Type *base, bool enable) +{ + if (enable) + { + base->SEQ_CTRL[1] |= ADC_SEQ_CTRL_BURST_MASK; + } + else + { + base->SEQ_CTRL[1] &= ~ADC_SEQ_CTRL_BURST_MASK; + } +} + +/*! + * @brief Set the high priority for conversion sequence B. + * + * @param base ADC peripheral bass address. + */ +static inline void ADC_SetConvSeqBHighPriority(ADC_Type *base) +{ + base->SEQ_CTRL[0] &= ~ADC_SEQ_CTRL_LOWPRIO_MASK; +} + +/* @} */ + +/*! + * @name Data result. + * @{ + */ + +/*! + * @brief Get the global ADC conversion infomation of sequence A. + * + * @param base ADC peripheral base address. + * @param info Pointer to information structure, see to #adc_result_info_t; + * @retval true The conversion result is ready. + * @retval false The conversion result is not ready yet. + */ +bool ADC_GetConvSeqAGlobalConversionResult(ADC_Type *base, adc_result_info_t *info); + +/*! + * @brief Get the global ADC conversion infomation of sequence B. + * + * @param base ADC peripheral base address. + * @param info Pointer to information structure, see to #adc_result_info_t; + * @retval true The conversion result is ready. + * @retval false The conversion result is not ready yet. + */ +bool ADC_GetConvSeqBGlobalConversionResult(ADC_Type *base, adc_result_info_t *info); + +/*! + * @brief Get the channel's ADC conversion completed under each conversion sequence. + * + * @param base ADC peripheral base address. + * @param channel The indicated channel number. + * @param info Pointer to information structure, see to #adc_result_info_t; + * @retval true The conversion result is ready. + * @retval false The conversion result is not ready yet. + */ +bool ADC_GetChannelConversionResult(ADC_Type *base, uint32_t channel, adc_result_info_t *info); + +/* @} */ + +/*! + * @name Threshold function. + * @{ + */ + +/*! + * @brief Set the threshhold pair 0 with low and high value. + * + * @param base ADC peripheral base address. + * @param lowValue LOW threshold value. + * @param highValue HIGH threshold value. + */ +static inline void ADC_SetThresholdPair0(ADC_Type *base, uint32_t lowValue, uint32_t highValue) +{ + base->THR0_LOW = ADC_THR0_LOW_THRLOW(lowValue); + base->THR0_HIGH = ADC_THR0_HIGH_THRHIGH(highValue); +} + +/*! + * @brief Set the threshhold pair 1 with low and high value. + * + * @param base ADC peripheral base address. + * @param lowValue LOW threshold value. The available value is with 12-bit. + * @param highValue HIGH threshold value. The available value is with 12-bit. + */ +static inline void ADC_SetThresholdPair1(ADC_Type *base, uint32_t lowValue, uint32_t highValue) +{ + base->THR1_LOW = ADC_THR1_LOW_THRLOW(lowValue); + base->THR1_HIGH = ADC_THR1_HIGH_THRHIGH(highValue); +} + +/*! + * @brief Set given channels to apply the threshold pare 0. + * + * @param base ADC peripheral base address. + * @param channelMask Indicated channels' mask. + */ +static inline void ADC_SetChannelWithThresholdPair0(ADC_Type *base, uint32_t channelMask) +{ + base->CHAN_THRSEL &= ~(channelMask); +} + +/*! + * @brief Set given channels to apply the threshold pare 1. + * + * @param base ADC peripheral base address. + * @param channelMask Indicated channels' mask. + */ +static inline void ADC_SetChannelWithThresholdPair1(ADC_Type *base, uint32_t channelMask) +{ + base->CHAN_THRSEL |= channelMask; +} + +/* @} */ + +/*! + * @name Interrupts. + * @{ + */ + +/*! + * @brief Enable interrupts for conversion sequences. + * + * @param base ADC peripheral base address. + * @param mask Mask of interrupt mask value for global block except each channal, see to #_adc_interrupt_enable. + */ +static inline void ADC_EnableInterrupts(ADC_Type *base, uint32_t mask) +{ + base->INTEN |= (0x7 & mask); +} + +/*! + * @brief Disable interrupts for conversion sequence. + * + * @param base ADC peripheral base address. + * @param mask Mask of interrupt mask value for global block except each channel, see to #_adc_interrupt_enable. + */ +static inline void ADC_DisableInterrupts(ADC_Type *base, uint32_t mask) +{ + base->INTEN &= ~(0x7 & mask); +} + +/*! + * @brief Enable the interrupt of threshold compare event for each channel. + * @deprecated Do not use this function. It has been superceded by @ADC_EnableThresholdCompareInterrupt + */ +static inline void ADC_EnableShresholdCompareInterrupt(ADC_Type *base, + uint32_t channel, + adc_threshold_interrupt_mode_t mode) +{ + base->INTEN = (base->INTEN & ~(0x3U << ((channel << 1U) + 3U))) | ((uint32_t)(mode) << ((channel << 1U) + 3U)); +} + +/*! + * @brief Enable the interrupt of threshold compare event for each channel. + * + * @param base ADC peripheral base address. + * @param channel Channel number. + * @param mode Interrupt mode for threshold compare event, see to #adc_threshold_interrupt_mode_t. + */ +static inline void ADC_EnableThresholdCompareInterrupt(ADC_Type *base, + uint32_t channel, + adc_threshold_interrupt_mode_t mode) +{ + base->INTEN = (base->INTEN & ~(0x3U << ((channel << 1U) + 3U))) | ((uint32_t)(mode) << ((channel << 1U) + 3U)); +} + +/* @} */ + +/*! + * @name Status. + * @{ + */ + +/*! + * @brief Get status flags of ADC module. + * + * @param base ADC peripheral base address. + * @return Mask of status flags of module, see to #_adc_status_flags. + */ +static inline uint32_t ADC_GetStatusFlags(ADC_Type *base) +{ + return base->FLAGS; +} + +/*! + * @brief Clear status flags of ADC module. + * + * @param base ADC peripheral base address. + * @param mask Mask of status flags of module, see to #_adc_status_flags. + */ +static inline void ADC_ClearStatusFlags(ADC_Type *base, uint32_t mask) +{ + base->FLAGS = mask; /* Write 1 to clear. */ +} + +/* @} */ + +#if defined(__cplusplus) +} +#endif + +/* @} */ + +#endif /* __FSL_ADC_H__ */ diff --git a/platform/mcu/lpc54102/drivers/fsl_clock.c b/platform/mcu/lpc54102/drivers/fsl_clock.c new file mode 100644 index 0000000000..7be2c4f5d5 --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_clock.c @@ -0,0 +1,1480 @@ +/* + * Copyright 2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_common.h" +#include "fsl_clock.h" +#include "fsl_power.h" +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define NVALMAX (0x100U) +#define PVALMAX (0x20U) +#define MVALMAX (0x8000U) + +#define PLL_MAX_N_DIV 0x100U + +#define PLL_SSCG0_MDEC_VAL_P (0U) /* MDEC is in bits 16 downto 0 */ +#define PLL_SSCG0_MDEC_VAL_M (0x1FFFFUL << PLL_SSCG0_MDEC_VAL_P) +#define PLL_NDEC_VAL_P (0U) /* NDEC is in bits 9:0 */ +#define PLL_NDEC_VAL_M (0x3FFUL << PLL_NDEC_VAL_P) + +#define PLL_PDEC_VAL_P (0U) /* PDEC is in bits 6:0 */ +#define PLL_PDEC_VAL_M (0x7FUL << PLL_PDEC_VAL_P) + +#define PLL_MIN_CCO_FREQ_MHZ (75000000U) +#define PLL_MAX_CCO_FREQ_MHZ (150000000U) + +#define PLL_LOWER_IN_LIMIT (4000U) /*!< Min PLL input rate */ + +#define PLL_MIN_IN_SSMODE (2000000U) /*!< Min PLL input rate in Spread spectrum mode */ +#define PLL_MAX_IN_SSMODE (4000000U) /*!< Max PLL input rate in Spread spectrum mode */ + +/* Middle of the range values for spread-spectrum */ +#define PLL_SSCG_MF_FREQ_VALUE 4U +#define PLL_SSCG_MC_COMP_VALUE 2U +#define PLL_SSCG_MR_DEPTH_VALUE 4U +#define PLL_SSCG_DITHER_VALUE 0U + +/* PLL NDEC reg */ +#define PLL_NDEC_VAL_SET(value) (((unsigned long)(value) << PLL_NDEC_VAL_P) & PLL_NDEC_VAL_M) +/* PLL PDEC reg */ +#define PLL_PDEC_VAL_SET(value) (((unsigned long)(value) << PLL_PDEC_VAL_P) & PLL_PDEC_VAL_M) +/* SSCG control0 */ +#define PLL_SSCG0_MDEC_VAL_SET(value) (((unsigned long)(value) << PLL_SSCG0_MDEC_VAL_P) & PLL_SSCG0_MDEC_VAL_M) + +/* SSCG control1 */ +#define PLL_SSCG1_MD_FRACT_P 0U +#define PLL_SSCG1_MD_INT_P 11U + +#define PLL_SSCG1_MD_FRACT_M (0x7FFUL << PLL_SSCG1_MD_FRACT_P) +#define PLL_SSCG1_MD_INT_M (0xFFUL << PLL_SSCG1_MD_INT_P) + +#define PLL_SSCG1_MD_FRACT_SET(value) (((unsigned long)(value) << PLL_SSCG1_MD_FRACT_P) & PLL_SSCG1_MD_FRACT_M) +#define PLL_SSCG1_MD_INT_SET(value) (((unsigned long)(value) << PLL_SSCG1_MD_INT_P) & PLL_SSCG1_MD_INT_M) + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/* Saved value of PLL output rate, computed whenever needed to save run-time + computation on each call to retrive the PLL rate. */ +static uint32_t s_Pll_Freq; + +/** External clock rate on the CLKIN pin in Hz. If not used, + set this to 0. Otherwise, set it to the exact rate in Hz this pin is + being driven at. */ +const uint32_t g_Ext_Freq = 0U; + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +/* Find encoded NDEC value for raw N value, max N = NVALMAX */ +static uint32_t pllEncodeN(uint32_t N); +/* Find decoded N value for raw NDEC value */ +static uint32_t pllDecodeN(uint32_t NDEC); +/* Find encoded PDEC value for raw P value, max P = PVALMAX */ +static uint32_t pllEncodeP(uint32_t P); +/* Find decoded P value for raw PDEC value */ +static uint32_t pllDecodeP(uint32_t PDEC); +/* Find encoded MDEC value for raw M value, max M = MVALMAX */ +static uint32_t pllEncodeM(uint32_t M); +/* Find decoded M value for raw MDEC value */ +static uint32_t pllDecodeM(uint32_t MDEC); +/* Find SELP, SELI, and SELR values for raw M value, max M = MVALMAX */ +static void pllFindSel(uint32_t M, bool bypassFBDIV2, uint32_t *pSelP, uint32_t *pSelI, uint32_t *pSelR); +/* Get predivider (N) from PLL NDEC setting */ +static uint32_t findPllPreDiv(uint32_t ctrlReg, uint32_t nDecReg); +/* Get postdivider (P) from PLL PDEC setting */ +static uint32_t findPllPostDiv(uint32_t ctrlReg, uint32_t pDecReg); +/* Get multiplier (M) from PLL MDEC and BYPASS_FBDIV2 settings */ +static uint32_t findPllMMult(uint32_t ctrlReg, uint32_t mDecReg); +/* Get the greatest common divisor */ +static uint32_t FindGreatestCommonDivisor(uint32_t m, uint32_t n); +/* Set PLL output based on desired output rate */ +static pll_error_t CLOCK_GetPllConfig( + uint32_t finHz, uint32_t foutHz, pll_setup_t *pSetup, bool useFeedbackDiv2, bool useSS); +/* Update local PLL rate variable */ +static void CLOCK_GetSystemPLLOutFromSetupUpdate(pll_setup_t *pSetup); + +/******************************************************************************* + * Code + ******************************************************************************/ + +void CLOCK_AttachClk(clock_attach_id_t connection) +{ + bool final_descriptor = false; + uint8_t mux; + uint8_t pos; + uint32_t i; + volatile uint32_t *pClkSel; + + pClkSel = &(SYSCON->MAINCLKSELA); + + for (i = 0U; (i <= 2U) && (!final_descriptor); i++) + { + connection = (clock_attach_id_t)(connection >> (i * 12U)); /* pick up next descriptor */ + mux = (uint8_t)connection; + if (connection) + { + pos = ((connection & 0xf00U) >> 8U) - 1U; + if (mux == CM_ASYNCAPA) + { + SYSCON->ASYNCAPBCTRL = SYSCON_ASYNCAPBCTRL_ENABLE_MASK; + ASYNC_SYSCON->ASYNCAPBCLKSELA = pos; + } + else if (mux == CM_ASYNCAPB) + { + pos = ((connection & 0xf00U) >> 8U) - 1U; + ASYNC_SYSCON->ASYNCAPBCLKSELB = pos; + final_descriptor = true; + } + else + { + pClkSel[mux] = pos; + } + } + else + { + final_descriptor = true; + } + } +} + +void CLOCK_SetClkDiv(clock_div_name_t div_name, uint32_t divided_by_value, bool reset) +{ + /* param reset is not used, to align with other LPC series*/ + volatile uint32_t *pClkDiv; + pClkDiv = &(SYSCON->SYSTICKCLKDIV); + /* if divided_by_value is 0, clock will be disable */ + pClkDiv[div_name] = divided_by_value; +} + +uint32_t CLOCK_GetExtClkFreq(void) +{ + return g_Ext_Freq; +} + +uint32_t CLOCK_GetWdtOscFreq(void) +{ + if (SYSCON->PDRUNCFG & (1UL << (kPDRUNCFG_PD_WDT_OSC & 0xffU))) + { + return 0U; + } + else + { + return 500000U; + } +} + +uint32_t CLOCK_GetPllOutFreq(void) +{ + return s_Pll_Freq; +} + +uint32_t CLOCK_GetOsc32KFreq(void) +{ + if (SYSCON->RTCOSCCTRL & SYSCON_RTCOSCCTRL_EN_MASK) + { + return CLK_RTC_32K_CLK; + } + else + { + return 0U; + } +} + +/* Get ADC Clk */ +uint32_t CLOCK_GetAdcClkFreq(void) +{ + uint32_t freq; + if ((SYSCON->ADCCLKDIV & SYSCON_ADCCLKDIV_DIV_MASK) == 0U) + { + return 0U; + } + else + { + freq = ((SYSCON->ADCCLKSEL & SYSCON_ADCCLKSEL_SEL_MASK) == 0U) ? + CLOCK_GetMainClkFreq() : + ((SYSCON->ADCCLKSEL & SYSCON_ADCCLKSEL_SEL_MASK) == 1U) ? + CLOCK_GetPllOutFreq() : + ((SYSCON->ADCCLKSEL & SYSCON_ADCCLKSEL_SEL_MASK) == 2U) ? CLOCK_GetIrc12MFreq() : 0U; + freq = freq / (SYSCON->ADCCLKDIV & SYSCON_ADCCLKDIV_DIV_MASK); + return freq; + } +} + +/* Get CLOCK OUT Clk */ +uint32_t CLOCK_GetClockOutClkFreq(void) +{ + uint32_t freq; + if ((SYSCON->CLKOUTDIV & SYSCON_CLKOUTDIV_DIV_MASK) == 0U) + { + return 0U; + } + else + { + freq = (((SYSCON->CLKOUTSELB & SYSCON_CLKOUTSELB_SEL_MASK) == 0U) && + ((SYSCON->CLKOUTSELA & SYSCON_CLKOUTSELA_SEL_MASK) == 0U)) ? + CLOCK_GetMainClkFreq() : + (((SYSCON->CLKOUTSELB & SYSCON_CLKOUTSELB_SEL_MASK) == 0U) && + ((SYSCON->CLKOUTSELA & SYSCON_CLKOUTSELA_SEL_MASK) == 1U)) ? + CLOCK_GetExtClkFreq() : + (((SYSCON->CLKOUTSELB & SYSCON_CLKOUTSELB_SEL_MASK) == 0U) && + ((SYSCON->CLKOUTSELA & SYSCON_CLKOUTSELA_SEL_MASK) == 2U)) ? + CLOCK_GetWdtOscFreq() : + (((SYSCON->CLKOUTSELB & SYSCON_CLKOUTSELB_SEL_MASK) == 0U) && + ((SYSCON->CLKOUTSELA & SYSCON_CLKOUTSELA_SEL_MASK) == 3U)) ? + CLOCK_GetIrc12MFreq() : + ((SYSCON->CLKOUTSELB & SYSCON_CLKOUTSELB_SEL_MASK) == 3U) ? CLOCK_GetOsc32KFreq() : 0U; + freq = freq / (SYSCON->CLKOUTDIV & SYSCON_CLKOUTDIV_DIV_MASK); + + return freq; + } +} + +uint32_t CLOCK_GetIrc12MFreq(void) +{ + if ((!(SYSCON->PDRUNCFG & SYSCON_PDRUNCFG_PDEN_IRC_OSC_MASK)) && + (!(SYSCON->PDRUNCFG & SYSCON_PDRUNCFG_PDEN_IRC_MASK))) + { + return 12000000U; + } + else + { + return 0U; + } +} + +uint32_t CLOCK_GetPllInFreq(void) +{ + uint32_t freq; + uint32_t sel = (uint32_t)(SYSCON->SYSPLLCLKSEL & SYSCON_SYSPLLCLKSEL_SEL_MASK); + switch (sel) + { + case 0U: + freq = CLOCK_GetIrc12MFreq(); + break; + case 1U: + freq = CLOCK_GetExtClkFreq(); + break; + case 3U: + freq = CLOCK_GetOsc32KFreq(); + break; + default: + freq = 0U; + break; + } + return freq; +} + +uint32_t CLOCK_GetMainClkFreq(void) +{ + return ((((SYSCON->MAINCLKSELB & SYSCON_MAINCLKSELB_SEL_MASK) == 0U) && + ((SYSCON->MAINCLKSELA & SYSCON_MAINCLKSELA_SEL_MASK) == 0U)) ? + CLOCK_GetIrc12MFreq() : + (((SYSCON->MAINCLKSELB & SYSCON_MAINCLKSELB_SEL_MASK) == 0U) && + ((SYSCON->MAINCLKSELA & SYSCON_MAINCLKSELA_SEL_MASK) == 1U)) ? + CLOCK_GetExtClkFreq() : + (((SYSCON->MAINCLKSELB & SYSCON_MAINCLKSELB_SEL_MASK) == 0U) && + ((SYSCON->MAINCLKSELA & SYSCON_MAINCLKSELA_SEL_MASK) == 2U)) ? + CLOCK_GetWdtOscFreq() : + ((SYSCON->MAINCLKSELB & SYSCON_MAINCLKSELB_SEL_MASK) == 1U) ? + CLOCK_GetPllInFreq() : + ((SYSCON->MAINCLKSELB & SYSCON_MAINCLKSELB_SEL_MASK) == 2U) ? + CLOCK_GetPllOutFreq() : + ((SYSCON->MAINCLKSELB & SYSCON_MAINCLKSELB_SEL_MASK) == 3U) ? CLOCK_GetOsc32KFreq() : 0U); +} + +uint32_t CLOCK_GetAsyncApbClkFreq(void) +{ + if ((ASYNC_SYSCON->ASYNCCLKDIV & ASYNC_SYSCON_FRGCTRL_DIV_MASK) == 0U) + { + return 0U; + } + else + { + return (((((ASYNC_SYSCON->ASYNCAPBCLKSELB & ASYNC_SYSCON_ASYNCAPBCLKSELB_SEL_MASK) == 3U) && + ((ASYNC_SYSCON->ASYNCAPBCLKSELA & ASYNC_SYSCON_ASYNCAPBCLKSELA_SEL_MASK) == 0U)) ? + CLOCK_GetIrc12MFreq() : + (((ASYNC_SYSCON->ASYNCAPBCLKSELB & ASYNC_SYSCON_ASYNCAPBCLKSELB_SEL_MASK) == 3U) && + ((ASYNC_SYSCON->ASYNCAPBCLKSELA & ASYNC_SYSCON_ASYNCAPBCLKSELA_SEL_MASK) == 1U)) ? + CLOCK_GetWdtOscFreq() : + ((ASYNC_SYSCON->ASYNCAPBCLKSELB & ASYNC_SYSCON_ASYNCAPBCLKSELB_SEL_MASK) == 0U) ? + CLOCK_GetMainClkFreq() : + ((ASYNC_SYSCON->ASYNCAPBCLKSELB & ASYNC_SYSCON_ASYNCAPBCLKSELB_SEL_MASK) == 1U) ? + CLOCK_GetExtClkFreq() : + ((ASYNC_SYSCON->ASYNCAPBCLKSELB & ASYNC_SYSCON_ASYNCAPBCLKSELB_SEL_MASK) == 2U) ? + CLOCK_GetPllOutFreq() : + 0U)) / + (ASYNC_SYSCON->ASYNCCLKDIV); + } +} + +bool CLOCK_SetFRGClock(uint32_t freq) +{ + uint32_t input = CLOCK_GetAsyncApbClkFreq(); + uint32_t mul; + assert(freq); + if (freq > input) + { + return false; + } + else + { + mul = (uint32_t)(((uint64_t)(input - freq) * 256) / ((uint64_t)freq)); + ASYNC_SYSCON->FRGCTRL = (mul << ASYNC_SYSCON_FRGCTRL_MULT_SHIFT) | ASYNC_SYSCON_FRGCTRL_DIV_MASK; + return true; + } +} + +uint32_t CLOCK_GetCoreClkFreq(void) +{ + if ((SYSCON->AHBCLKDIV & SYSCON_AHBCLKDIV_DIV_MASK) == 0U) + { + return 0U; + } + else + { + return (CLOCK_GetMainClkFreq() / (SYSCON->AHBCLKDIV & SYSCON_AHBCLKDIV_DIV_MASK)); + } +} + +uint32_t CLOCK_GetBusClFreq(void) +{ + if ((SYSCON->AHBCLKDIV & SYSCON_AHBCLKDIV_DIV_MASK) == 0U) + { + return 0U; + } + else + { + return (CLOCK_GetMainClkFreq() / (SYSCON->AHBCLKDIV & SYSCON_AHBCLKDIV_DIV_MASK)); + } +} + +uint32_t CLOCK_GetUsartClkFreq(void) +{ + if ((ASYNC_SYSCON->ASYNCCLKDIV & ASYNC_SYSCON_FRGCTRL_DIV_MASK) == 0U) + { + return 0U; + } + else + { + return CLOCK_GetAsyncApbClkFreq() / + (1U + ((((ASYNC_SYSCON->FRGCTRL & ASYNC_SYSCON_FRGCTRL_MULT_MASK) >> 8U)) / 256U)); + } +} + +uint32_t CLOCK_GetSpiClkFreq(void) +{ + if ((ASYNC_SYSCON->ASYNCCLKDIV & ASYNC_SYSCON_FRGCTRL_DIV_MASK) == 0U) + { + return 0U; + } + else + { + return CLOCK_GetAsyncApbClkFreq() / + (1U + ((((ASYNC_SYSCON->FRGCTRL & ASYNC_SYSCON_FRGCTRL_MULT_MASK) >> 8U)) / 256U)); + } +} + +uint32_t CLOCK_GetI2cClkFreq(void) +{ + if ((ASYNC_SYSCON->ASYNCCLKDIV & ASYNC_SYSCON_FRGCTRL_DIV_MASK) == 0U) + { + return 0U; + } + else + { + return CLOCK_GetAsyncApbClkFreq() / + (1U + ((((ASYNC_SYSCON->FRGCTRL & ASYNC_SYSCON_FRGCTRL_MULT_MASK) >> 8U)) / 256U)); + } +} + +uint32_t CLOCK_GetFreq(clock_name_t clockName) +{ + uint32_t freq; + switch (clockName) + { + case kCLOCK_MainClk: + freq = CLOCK_GetMainClkFreq(); + break; + case kCLOCK_CoreSysClk: + freq = CLOCK_GetCoreClkFreq(); + break; + case kCLOCK_BusClk: + freq = CLOCK_GetBusClFreq(); + break; + case kCLOCK_PllOut: + freq = CLOCK_GetPllOutFreq(); + break; + case kClock_WdtOsc: + freq = CLOCK_GetWdtOscFreq(); + break; + case kCLOCK_FRG: + freq = ((ASYNC_SYSCON->FRGCTRL & ASYNC_SYSCON_FRGCTRL_DIV_MASK) == ASYNC_SYSCON_FRGCTRL_DIV_MASK) ? + ((uint64_t)CLOCK_GetAsyncApbClkFreq() * (ASYNC_SYSCON_FRGCTRL_DIV_MASK + 1)) / + ((ASYNC_SYSCON_FRGCTRL_DIV_MASK + 1) + + ((ASYNC_SYSCON->FRGCTRL & ASYNC_SYSCON_FRGCTRL_MULT_MASK) >> + ASYNC_SYSCON_FRGCTRL_MULT_SHIFT)) : + 0U; + break; + case kCLOCK_AsyncApbClk: + freq = CLOCK_GetAsyncApbClkFreq(); + break; + case kCLOCK_Irc: + freq = CLOCK_GetIrc12MFreq(); + break; + case kCLOCK_Adc: + freq = CLOCK_GetAdcClkFreq(); + break; + case kCLOCK_ClockOut: + freq = CLOCK_GetClockOutClkFreq(); + break; + case kCLOCK_Usart: + freq = CLOCK_GetUsartClkFreq(); + break; + case kCLOCK_Spi: + freq = CLOCK_GetSpiClkFreq(); + break; + case kCLOCK_I2c: + freq = CLOCK_GetI2cClkFreq(); + break; + default: + freq = 0U; + break; + } + + return freq; +} + +/* Set the FLASH wait states for the passed frequency */ +void CLOCK_SetFLASHAccessCyclesForFreq(uint32_t iFreq) +{ + if (iFreq <= 12000000U) + { + CLOCK_SetFLASHAccessCycles(kCLOCK_Flash1Cycle); + } + else if (iFreq <= 24000000U) + { + CLOCK_SetFLASHAccessCycles(kCLOCK_Flash2Cycle); + } + else if (iFreq <= 48000000U) + { + CLOCK_SetFLASHAccessCycles(kCLOCK_Flash3Cycle); + } + else if (iFreq <= 72000000U) + { + CLOCK_SetFLASHAccessCycles(kCLOCK_Flash4Cycle); + } + else if (iFreq <= 84000000U) + { + CLOCK_SetFLASHAccessCycles(kCLOCK_Flash5Cycle); + } + else + { + CLOCK_SetFLASHAccessCycles(kCLOCK_Flash6Cycle); + } +} + +/* Find encoded NDEC value for raw N value, max N = NVALMAX */ +static uint32_t pllEncodeN(uint32_t N) +{ + uint32_t x, i; + + /* Find NDec */ + switch (N) + { + case 0U: + x = 0x3FFU; + break; + + case 1U: + x = 0x302U; + break; + + case 2U: + x = 0x202U; + break; + + default: + x = 0x080U; + for (i = N; i <= NVALMAX; i++) + { + x = (((x ^ (x >> 2U) ^ (x >> 3U) ^ (x >> 4U)) & 1U) << 7U) | ((x >> 1U) & 0x7FU); + } + break; + } + + return x & (PLL_NDEC_VAL_M >> PLL_NDEC_VAL_P); +} + +/* Find decoded N value for raw NDEC value */ +static uint32_t pllDecodeN(uint32_t NDEC) +{ + uint32_t n, x, i; + + /* Find NDec */ + switch (NDEC) + { + case 0x3FFU: + n = 0U; + break; + + case 0x302U: + n = 1U; + break; + + case 0x202U: + n = 2U; + break; + + default: + x = 0x080U; + n = 0xFFFFFFFFU; + for (i = NVALMAX; ((i >= 3U) && (n == 0xFFFFFFFFU)); i--) + { + x = (((x ^ (x >> 2U) ^ (x >> 3U) ^ (x >> 4U)) & 1U) << 7U) | ((x >> 1U) & 0x7FU); + if ((x & (PLL_NDEC_VAL_M >> PLL_NDEC_VAL_P)) == NDEC) + { + /* Decoded value of NDEC */ + n = i; + } + } + break; + } + + return n; +} + +/* Find encoded PDEC value for raw P value, max P = PVALMAX */ +static uint32_t pllEncodeP(uint32_t P) +{ + uint32_t x, i; + + /* Find PDec */ + switch (P) + { + case 0U: + x = 0x7FU; + break; + + case 1U: + x = 0x62U; + break; + + case 2U: + x = 0x42U; + break; + + default: + x = 0x10U; + for (i = P; i <= PVALMAX; i++) + { + x = (((x ^ (x >> 2U)) & 1U) << 4U) | ((x >> 1U) & 0xFU); + } + break; + } + + return x & (PLL_PDEC_VAL_M >> PLL_PDEC_VAL_P); +} + +/* Find decoded P value for raw PDEC value */ +static uint32_t pllDecodeP(uint32_t PDEC) +{ + uint32_t p, x, i; + + /* Find PDec */ + switch (PDEC) + { + case 0x7FU: + p = 0U; + break; + + case 0x62U: + p = 1U; + break; + + case 0x42U: + p = 2U; + break; + + default: + x = 0x10U; + p = 0xFFFFFFFFU; + for (i = PVALMAX; ((i >= 3U) && (p == 0xFFFFFFFFU)); i--) + { + x = (((x ^ (x >> 2U)) & 1U) << 4U) | ((x >> 1U) & 0xFU); + if ((x & (PLL_PDEC_VAL_M >> PLL_PDEC_VAL_P)) == PDEC) + { + /* Decoded value of PDEC */ + p = i; + } + } + break; + } + + return p; +} + +/* Find encoded MDEC value for raw M value, max M = MVALMAX */ +static uint32_t pllEncodeM(uint32_t M) +{ + uint32_t i, x; + + /* Find MDec */ + switch (M) + { + case 0U: + x = 0x1FFFFU; + break; + + case 1U: + x = 0x18003U; + break; + + case 2U: + x = 0x10003U; + break; + + default: + x = 0x04000U; + for (i = M; i <= MVALMAX; i++) + { + x = (((x ^ (x >> 1U)) & 1U) << 14U) | ((x >> 1U) & 0x3FFFU); + } + break; + } + + return x & (PLL_SSCG0_MDEC_VAL_M >> PLL_SSCG0_MDEC_VAL_P); +} + +/* Find decoded M value for raw MDEC value */ +static uint32_t pllDecodeM(uint32_t MDEC) +{ + uint32_t m, i, x; + + /* Find MDec */ + switch (MDEC) + { + case 0x1FFFFU: + m = 0U; + break; + + case 0x18003U: + m = 1U; + break; + + case 0x10003U: + m = 2U; + break; + + default: + x = 0x04000U; + m = 0xFFFFFFFFU; + for (i = MVALMAX; ((i >= 3U) && (m == 0xFFFFFFFFU)); i--) + { + x = (((x ^ (x >> 1U)) & 1) << 14U) | ((x >> 1U) & 0x3FFFU); + if ((x & (PLL_SSCG0_MDEC_VAL_M >> PLL_SSCG0_MDEC_VAL_P)) == MDEC) + { + /* Decoded value of MDEC */ + m = i; + } + } + break; + } + + return m; +} + +/* Find SELP, SELI, and SELR values for raw M value, max M = MVALMAX */ +static void pllFindSel(uint32_t M, bool bypassFBDIV2, uint32_t *pSelP, uint32_t *pSelI, uint32_t *pSelR) +{ + /* bandwidth: compute selP from Multiplier */ + if (M < 60U) + { + *pSelP = (M >> 1U) + 1U; + } + else + { + *pSelP = PVALMAX - 1U; + } + + /* bandwidth: compute selI from Multiplier */ + if (M > 16384U) + { + *pSelI = 1U; + } + else if (M > 8192U) + { + *pSelI = 2U; + } + else if (M > 2048U) + { + *pSelI = 4U; + } + else if (M >= 501U) + { + *pSelI = 8U; + } + else if (M >= 60U) + { + *pSelI = 4U * (1024U / (M + 9U)); + } + else + { + *pSelI = (M & 0x3CU) + 4U; + } + + if (*pSelI > ((0x3FUL << SYSCON_SYSPLLCTRL_SELI_SHIFT) >> SYSCON_SYSPLLCTRL_SELI_SHIFT)) + { + *pSelI = ((0x3FUL << SYSCON_SYSPLLCTRL_SELI_SHIFT) >> SYSCON_SYSPLLCTRL_SELI_SHIFT); + } + + *pSelR = 0U; +} + +/* Get predivider (N) from PLL NDEC setting */ +static uint32_t findPllPreDiv(uint32_t ctrlReg, uint32_t nDecReg) +{ + uint32_t preDiv = 1; + + /* Direct input is not used? */ + if ((ctrlReg & (1UL << SYSCON_SYSPLLCTRL_DIRECTI_SHIFT)) == 0U) + { + /* Decode NDEC value to get (N) pre divider */ + preDiv = pllDecodeN(nDecReg & 0x3FFU); + if (preDiv == 0U) + { + preDiv = 1U; + } + } + + /* Adjusted by 1, directi is used to bypass */ + return preDiv; +} + +/* Get postdivider (P) from PLL PDEC setting */ +static uint32_t findPllPostDiv(uint32_t ctrlReg, uint32_t pDecReg) +{ + uint32_t postDiv = 1U; + + /* Direct input is not used? */ + if ((ctrlReg & SYSCON_SYSPLLCTRL_DIRECTO_MASK) == 0U) + { + /* Decode PDEC value to get (P) post divider */ + postDiv = 2U * pllDecodeP(pDecReg & 0x7FU); + if (postDiv == 0U) + { + postDiv = 2U; + } + } + + /* Adjusted by 1, directo is used to bypass */ + return postDiv; +} + +/* Get multiplier (M) from PLL MDEC and BYPASS_FBDIV2 settings */ +static uint32_t findPllMMult(uint32_t ctrlReg, uint32_t mDecReg) +{ + uint32_t mMult = 1U; + + /* Decode MDEC value to get (M) multiplier */ + mMult = pllDecodeM(mDecReg & 0x1FFFFU); + + /* Extra multiply by 2 needed? */ + if ((ctrlReg & (SYSCON_SYSPLLCTRL_BYPASSCCODIV2_MASK)) == 0U) + { + mMult = mMult << 1U; + } + + if (mMult == 0U) + { + mMult = 1U; + } + + return mMult; +} + +static uint32_t FindGreatestCommonDivisor(uint32_t m, uint32_t n) +{ + uint32_t tmp; + + while (n != 0U) + { + tmp = n; + n = m % n; + m = tmp; + } + + return m; +} + +/* + * Set PLL output based on desired output rate. + * In this function, the it calculates the PLL setting for output frequency from input clock + * frequency. The calculation would cost a few time. So it is not recommaned to use it frequently. + * the "pllctrl", "pllndec", "pllpdec", "pllmdec" would updated in this function. + */ +static pll_error_t CLOCK_GetPllConfigInternal( + uint32_t finHz, uint32_t foutHz, pll_setup_t *pSetup, bool useFeedbackDiv2, bool useSS) +{ + uint32_t nDivOutHz, fccoHz, multFccoDiv; + uint32_t pllPreDivider, pllMultiplier, pllBypassFBDIV2, pllPostDivider; + uint32_t pllDirectInput, pllDirectOutput; + uint32_t pllSelP, pllSelI, pllSelR, bandsel, uplimoff; + + /* Baseline parameters (no input or output dividers) */ + pllPreDivider = 1U; /* 1 implies pre-divider will be disabled */ + pllPostDivider = 0U; /* 0 implies post-divider will be disabled */ + pllDirectOutput = 1U; + if (useFeedbackDiv2) + { + /* Using feedback divider for M, so disable bypass */ + pllBypassFBDIV2 = 0U; + } + else + { + pllBypassFBDIV2 = 1U; + } + multFccoDiv = (2U - pllBypassFBDIV2); + + /* Verify output rate parameter */ + if (foutHz > PLL_MAX_CCO_FREQ_MHZ) + { + /* Maximum PLL output with post divider=1 cannot go above this frequency */ + return kStatus_PLL_OutputTooHigh; + } + if (foutHz < (PLL_MIN_CCO_FREQ_MHZ / (PVALMAX << 1U))) + { + /* Minmum PLL output with maximum post divider cannot go below this frequency */ + return kStatus_PLL_OutputTooLow; + } + + /* If using SS mode, input clock needs to be between 2MHz and 4MHz */ + if (useSS) + { + /* Verify input rate parameter */ + if (finHz < PLL_MIN_IN_SSMODE) + { + /* Input clock into the PLL cannot be lower than this */ + return kStatus_PLL_InputTooLow; + } + /* PLL input in SS mode must be under 4MHz */ + pllPreDivider = finHz / ((PLL_MIN_IN_SSMODE + PLL_MAX_IN_SSMODE) / 2); + if (pllPreDivider > NVALMAX) + { + return kStatus_PLL_InputTooHigh; + } + } + else + { + /* Verify input rate parameter */ + if (finHz < PLL_LOWER_IN_LIMIT) + { + /* Input clock into the PLL cannot be lower than this */ + return kStatus_PLL_InputTooLow; + } + } + + /* Find the optimal CCO frequency for the output and input that + will keep it inside the PLL CCO range. This may require + tweaking the post-divider for the PLL. */ + fccoHz = foutHz; + while (fccoHz < PLL_MIN_CCO_FREQ_MHZ) + { + /* CCO output is less than minimum CCO range, so the CCO output + needs to be bumped up and the post-divider is used to bring + the PLL output back down. */ + pllPostDivider++; + if (pllPostDivider > PVALMAX) + { + return kStatus_PLL_OutsideIntLimit; + } + + /* Target CCO goes up, PLL output goes down */ + fccoHz = foutHz * (pllPostDivider * 2U); + pllDirectOutput = 0U; + } + + /* Determine if a pre-divider is needed to get the best frequency */ + if ((finHz > PLL_LOWER_IN_LIMIT) && (fccoHz >= finHz) && (useSS == false)) + { + uint32_t a = FindGreatestCommonDivisor(fccoHz, (multFccoDiv * finHz)); + + if (a > 20000U) + { + a = (multFccoDiv * finHz) / a; + if ((a != 0U) && (a < PLL_MAX_N_DIV)) + { + pllPreDivider = a; + } + } + } + + /* Bypass pre-divider hardware if pre-divider is 1 */ + if (pllPreDivider > 1U) + { + pllDirectInput = 0U; + } + else + { + pllDirectInput = 1U; + } + + /* Determine PLL multipler */ + nDivOutHz = (finHz / pllPreDivider); + pllMultiplier = (fccoHz / nDivOutHz) / multFccoDiv; + + /* Find optimal values for filter */ + if (useSS == false) + { + /* Will bumping up M by 1 get us closer to the desired CCO frequency? */ + if ((nDivOutHz * ((multFccoDiv * pllMultiplier * 2U) + 1U)) < (fccoHz * 2U)) + { + pllMultiplier++; + } + + /* Setup filtering */ + pllFindSel(pllMultiplier, pllBypassFBDIV2, &pllSelP, &pllSelI, &pllSelR); + bandsel = 1U; + uplimoff = 0U; + + /* Get encoded value for M (mult) and use manual filter, disable SS mode */ + pSetup->syspllssctrl[0] = + (PLL_SSCG0_MDEC_VAL_SET(pllEncodeM(pllMultiplier)) | (1U << SYSCON_SYSPLLSSCTRL0_SEL_EXT_SHIFT)); + + /* Power down SSC, not used */ + pSetup->syspllssctrl[1] = (1U << SYSCON_SYSPLLSSCTRL1_PD_SHIFT); + } + else + { + uint64_t fc; + + /* Filtering will be handled by SSC */ + pllSelR = pllSelI = pllSelP = 0U; + bandsel = 0U; + uplimoff = 1U; + + /* The PLL multiplier will get very close and slightly under the + desired target frequency. A small fractional component can be + added to fine tune the frequency upwards to the target. */ + /* useFeedbackDiv2 = true: Fcco = 2 * (MD[18:11] + MD[10:0] * 2-11) * Fref */ + /* useFeedbackDiv2 = false: Fcco = (MD[18:11] + MD[10:0] * 2-11) * Fref */ + + fc = ((uint64_t)(fccoHz % (multFccoDiv * nDivOutHz)) << 11U) / (multFccoDiv * nDivOutHz); + + /* MDEC set by SSC */ + pSetup->syspllssctrl[0U] = 0U; + + /* Set multiplier */ + pSetup->syspllssctrl[1] = PLL_SSCG1_MD_INT_SET(pllMultiplier) | PLL_SSCG1_MD_FRACT_SET((uint32_t)fc); + } + + /* Get encoded values for N (prediv) and P (postdiv) */ + pSetup->syspllndec = PLL_NDEC_VAL_SET(pllEncodeN(pllPreDivider)); + pSetup->syspllpdec = PLL_PDEC_VAL_SET(pllEncodeP(pllPostDivider)); + + /* PLL control */ + pSetup->syspllctrl = (pllSelR << SYSCON_SYSPLLCTRL_SELR_SHIFT) | /* Filter coefficient */ + (pllSelI << SYSCON_SYSPLLCTRL_SELI_SHIFT) | /* Filter coefficient */ + (pllSelP << SYSCON_SYSPLLCTRL_SELP_SHIFT) | /* Filter coefficient */ + (0 << SYSCON_SYSPLLCTRL_BYPASS_SHIFT) | /* PLL bypass mode disabled */ + (pllBypassFBDIV2 << SYSCON_SYSPLLCTRL_BYPASSCCODIV2_SHIFT) | /* Extra M / 2 divider? */ + (uplimoff << SYSCON_SYSPLLCTRL_UPLIMOFF_SHIFT) | /* SS/fractional mode disabled */ + (bandsel << SYSCON_SYSPLLCTRL_BANDSEL_SHIFT) | /* Manual bandwidth selection enabled */ + (pllDirectInput << SYSCON_SYSPLLCTRL_DIRECTI_SHIFT) | /* Bypass pre-divider? */ + (pllDirectOutput << SYSCON_SYSPLLCTRL_DIRECTO_SHIFT); /* Bypass post-divider? */ + + return kStatus_PLL_Success; +} + +#if (defined(CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT) && CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT) +/* Alloct the static buffer for cache. */ +pll_setup_t gPllSetupCacheStruct[CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT]; +uint32_t gFinHzCache[CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT] = {0}; +uint32_t gFoutHzCache[CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT] = {0}; +bool gUseFeedbackDiv2Cache[CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT] = {false}; +bool gUseSSCache[CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT] = {false}; +uint32_t gPllSetupCacheIdx = 0U; +#endif /* CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT */ + +/* + * Calculate the PLL setting values from input clock freq to output freq. + */ +static pll_error_t CLOCK_GetPllConfig( + uint32_t finHz, uint32_t foutHz, pll_setup_t *pSetup, bool useFeedbackDiv2, bool useSS) +{ + pll_error_t retErr; +#if (defined(CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT) && CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT) + uint32_t i; + + for (i = 0U; i < CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT; i++) + { + if ((finHz == gFinHzCache[i]) && (foutHz == gFoutHzCache[i]) && (useFeedbackDiv2 == gUseFeedbackDiv2Cache[i]) && + (useSS == gUseSSCache[i])) + { + /* Hit the target in cache buffer. */ + pSetup->syspllctrl = gPllSetupCacheStruct[i].syspllctrl; + pSetup->syspllndec = gPllSetupCacheStruct[i].syspllndec; + pSetup->syspllpdec = gPllSetupCacheStruct[i].syspllpdec; + pSetup->syspllssctrl[0] = gPllSetupCacheStruct[i].syspllssctrl[0]; + pSetup->syspllssctrl[1] = gPllSetupCacheStruct[i].syspllssctrl[1]; + retErr = kStatus_PLL_Success; + break; + } + } + + if (i < CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT) + { + return retErr; + } +#endif /* CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT */ + + retErr = CLOCK_GetPllConfigInternal(finHz, foutHz, pSetup, useFeedbackDiv2, useSS); + +#if (defined(CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT) && CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT) + /* Cache the most recent calulation result into buffer. */ + gFinHzCache[gPllSetupCacheIdx] = finHz; + gFoutHzCache[gPllSetupCacheIdx] = foutHz; + gUseFeedbackDiv2Cache[gPllSetupCacheIdx] = useFeedbackDiv2; + gUseSSCache[gPllSetupCacheIdx] = useSS; + + gPllSetupCacheStruct[gPllSetupCacheIdx].syspllctrl = pSetup->syspllctrl; + gPllSetupCacheStruct[gPllSetupCacheIdx].syspllndec = pSetup->syspllndec; + gPllSetupCacheStruct[gPllSetupCacheIdx].syspllpdec = pSetup->syspllpdec; + gPllSetupCacheStruct[gPllSetupCacheIdx].syspllssctrl[0] = pSetup->syspllssctrl[0]; + gPllSetupCacheStruct[gPllSetupCacheIdx].syspllssctrl[1] = pSetup->syspllssctrl[1]; + /* Update the index for next available buffer. */ + gPllSetupCacheIdx = (gPllSetupCacheIdx + 1U) % CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT; +#endif /* CLOCK_USR_CFG_PLL_CONFIG_CACHE_COUNT */ + + return retErr; +} + +/* Update local PLL rate variable */ +static void CLOCK_GetSystemPLLOutFromSetupUpdate(pll_setup_t *pSetup) +{ + s_Pll_Freq = CLOCK_GetSystemPLLOutFromSetup(pSetup); +} + +/* Return System PLL input clock rate */ +uint32_t CLOCK_GetSystemPLLInClockRate(void) +{ + uint32_t clkRate = 0U; + + switch ((SYSCON->SYSPLLCLKSEL & SYSCON_SYSPLLCLKSEL_SEL_MASK)) + { + case 0x00U: + clkRate = CLK_IRC_12MHZ; + break; + + case 0x01U: + clkRate = CLOCK_GetExtClkFreq(); + break; + + case 0x02U: + clkRate = CLOCK_GetWdtOscFreq(); + break; + + case 0x03U: + clkRate = CLOCK_GetOsc32KFreq(); + break; + + default: + clkRate = 0U; + break; + } + + return clkRate; +} + +/* Return System PLL output clock rate from setup structure */ +uint32_t CLOCK_GetSystemPLLOutFromSetup(pll_setup_t *pSetup) +{ + uint32_t prediv, postdiv, mMult, inPllRate; + uint64_t workRate; + + /* Get the input clock frequency of PLL. */ + inPllRate = CLOCK_GetSystemPLLInClockRate(); + + /* + * If the PLL is bypassed, PLL would not be used and the output of PLL module would just be the input clock. + */ + if ((pSetup->syspllctrl & (SYSCON_SYSPLLCTRL_BYPASS_MASK)) == 0U) + { + /* PLL is not in bypass mode, get pre-divider, and M divider, post-divider. */ + /* + * 1. Pre-divider + * Pre-divider is only available when the DIRECTI is disabled. + */ + if (0U == (pSetup->syspllctrl & SYSCON_SYSPLLCTRL_DIRECTI_MASK)) + { + prediv = findPllPreDiv(pSetup->syspllctrl, pSetup->syspllndec); + } + else + { + prediv = 1U; /* The pre-divider is bypassed. */ + } + /* Adjust input clock */ + inPllRate = inPllRate / prediv; + + /* + * 2. M divider + * If using the SS, use the multiplier. + */ + if (pSetup->syspllssctrl[1] & (SYSCON_SYSPLLSSCTRL1_PD_MASK)) + { + /* MDEC used for rate */ + mMult = findPllMMult(pSetup->syspllctrl, pSetup->syspllssctrl[0]); + workRate = (uint64_t)inPllRate * (uint64_t)mMult; + } + else + { + uint64_t fract; + + /* SS multipler used for rate */ + mMult = (pSetup->syspllssctrl[1] & PLL_SSCG1_MD_INT_M) >> PLL_SSCG1_MD_INT_P; + workRate = (uint64_t)inPllRate * (uint64_t)mMult; + + /* Adjust by fractional */ + fract = (uint64_t)(pSetup->syspllssctrl[1] & PLL_SSCG1_MD_FRACT_M) >> PLL_SSCG1_MD_FRACT_P; + workRate = workRate + ((inPllRate * fract) / 0x800U); + } + + /* + * 3. Post-divider + * Post-divider is only available when the DIRECTO is disabled. + */ + if (0U == (pSetup->syspllctrl & SYSCON_SYSPLLCTRL_DIRECTO_MASK)) + { + postdiv = findPllPostDiv(pSetup->syspllctrl, pSetup->syspllpdec); + } + else + { + postdiv = 1U; /* The post-divider is bypassed. */ + } + workRate = workRate / ((uint64_t)postdiv); + } + else + { + /* In bypass mode */ + workRate = (uint64_t)inPllRate; + } + + return (uint32_t)workRate; +} + +/* Set the current PLL Rate */ +void CLOCK_SetStoredPLLClockRate(uint32_t rate) +{ + s_Pll_Freq = rate; +} + +/* Return System PLL output clock rate */ +uint32_t CLOCK_GetSystemPLLOutClockRate(bool recompute) +{ + pll_setup_t Setup; + uint32_t rate; + + if ((recompute) || (s_Pll_Freq == 0U)) + { + Setup.syspllctrl = SYSCON->SYSPLLCTRL; + Setup.syspllndec = SYSCON->SYSPLLNDEC; + Setup.syspllpdec = SYSCON->SYSPLLPDEC; + Setup.syspllssctrl[0] = SYSCON->SYSPLLSSCTRL0; + Setup.syspllssctrl[1] = SYSCON->SYSPLLSSCTRL1; + + CLOCK_GetSystemPLLOutFromSetupUpdate(&Setup); + } + + rate = s_Pll_Freq; + + return rate; +} + +/* Set PLL output based on the passed PLL setup data */ +pll_error_t CLOCK_SetupPLLData(pll_config_t *pControl, pll_setup_t *pSetup) +{ + uint32_t inRate; + bool useSS = (bool)((pControl->flags & PLL_CONFIGFLAG_FORCENOFRACT) == 0U); + bool useFbDiv2; + + pll_error_t pllError; + + /* Determine input rate for the PLL */ + if ((pControl->flags & PLL_CONFIGFLAG_USEINRATE) != 0U) + { + inRate = pControl->inputRate; + } + else + { + inRate = CLOCK_GetSystemPLLInClockRate(); + } + + if ((pSetup->flags & PLL_SETUPFLAG_USEFEEDBACKDIV2) != 0U) + { + useFbDiv2 = true; + } + else + { + useFbDiv2 = false; + } + + /* PLL flag options */ + pllError = CLOCK_GetPllConfig(inRate, pControl->desiredRate, pSetup, useFbDiv2, useSS); + if ((useSS) && (pllError == kStatus_PLL_Success)) + { + /* If using SS mode, then some tweaks are made to the generated setup */ + pSetup->syspllssctrl[1] |= (uint32_t)pControl->ss_mf | (uint32_t)pControl->ss_mr | (uint32_t)pControl->ss_mc; + if (pControl->mfDither) + { + pSetup->syspllssctrl[1] |= (1U << SYSCON_SYSPLLSSCTRL1_DITHER_SHIFT); + } + } + + return pllError; +} + +/* Set PLL output from PLL setup structure */ +pll_error_t CLOCK_SetupSystemPLLPrec(pll_setup_t *pSetup, uint32_t flagcfg) +{ + /* Power off PLL during setup changes */ + POWER_EnablePD(kPDRUNCFG_PD_SYS_PLL); + + pSetup->flags = flagcfg; + + /* Write PLL setup data */ + SYSCON->SYSPLLCTRL = pSetup->syspllctrl; + SYSCON->SYSPLLNDEC = pSetup->syspllndec; + SYSCON->SYSPLLNDEC = pSetup->syspllndec | (1U << SYSCON_SYSPLLNDEC_NREQ_SHIFT); /* latch */ + SYSCON->SYSPLLPDEC = pSetup->syspllpdec; + SYSCON->SYSPLLPDEC = pSetup->syspllpdec | (1U << SYSCON_SYSPLLPDEC_PREQ_SHIFT); /* latch */ + SYSCON->SYSPLLSSCTRL0 = pSetup->syspllssctrl[0]; + SYSCON->SYSPLLSSCTRL0 = pSetup->syspllssctrl[0] | (1U << SYSCON_SYSPLLSSCTRL0_MREQ_SHIFT); /* latch */ + SYSCON->SYSPLLSSCTRL1 = pSetup->syspllssctrl[1]; + SYSCON->SYSPLLSSCTRL1 = pSetup->syspllssctrl[1] | (1U << SYSCON_SYSPLLSSCTRL1_MDREQ_SHIFT); /* latch */ + + /* Flags for lock or power on */ + if ((pSetup->flags & (PLL_SETUPFLAG_POWERUP | PLL_SETUPFLAG_WAITLOCK)) != 0U) + { + /* If turning the PLL back on, perform the following sequence to accelerate PLL lock */ + volatile uint32_t delayX; + uint32_t maxCCO = (1U << 18U) | 0x5dd2U; /* CCO = 1.6Ghz + MDEC enabled*/ + uint32_t curSSCTRL = SYSCON->SYSPLLSSCTRL0 & ~(1U << 17U); + + /* Initialize and power up PLL */ + SYSCON->SYSPLLSSCTRL0 = maxCCO; + POWER_DisablePD(kPDRUNCFG_PD_SYS_PLL); + + /* Set mreq to activate */ + SYSCON->SYSPLLSSCTRL0 = maxCCO | (1U << 17U); + + /* Delay for 72 uSec @ 12Mhz */ + for (delayX = 0U; delayX < 172U; ++delayX) + { + } + + /* clear mreq to prepare for restoring mreq */ + SYSCON->SYSPLLSSCTRL0 = curSSCTRL; + + /* set original value back and activate */ + SYSCON->SYSPLLSSCTRL0 = curSSCTRL | (1U << 17U); + + /* Enable peripheral states by setting low */ + POWER_DisablePD(kPDRUNCFG_PD_SYS_PLL); + } + if ((pSetup->flags & PLL_SETUPFLAG_WAITLOCK) != 0U) + { + while (CLOCK_IsSystemPLLLocked() == false) + { + } + } + + /* Update current programmed PLL rate var */ + CLOCK_GetSystemPLLOutFromSetupUpdate(pSetup); + + /* System voltage adjustment, occurs prior to setting main system clock */ + if ((pSetup->flags & PLL_SETUPFLAG_ADGVOLT) != 0U) + { + POWER_SetVoltageForFreq(s_Pll_Freq); + } + + return kStatus_PLL_Success; +} + +/* Setup PLL Frequency from pre-calculated value */ +pll_error_t CLOCK_SetPLLFreq(const pll_setup_t *pSetup) +{ + /* Power off PLL during setup changes */ + POWER_EnablePD(kPDRUNCFG_PD_SYS_PLL); + + /* Write PLL setup data */ + SYSCON->SYSPLLCTRL = pSetup->syspllctrl; + SYSCON->SYSPLLNDEC = pSetup->syspllndec; + SYSCON->SYSPLLNDEC = pSetup->syspllndec | (1U << SYSCON_SYSPLLNDEC_NREQ_SHIFT); /* latch */ + SYSCON->SYSPLLPDEC = pSetup->syspllpdec; + SYSCON->SYSPLLPDEC = pSetup->syspllpdec | (1U << SYSCON_SYSPLLPDEC_PREQ_SHIFT); /* latch */ + SYSCON->SYSPLLSSCTRL0 = pSetup->syspllssctrl[0]; + SYSCON->SYSPLLSSCTRL0 = pSetup->syspllssctrl[0] | (1U << SYSCON_SYSPLLSSCTRL0_MREQ_SHIFT); /* latch */ + SYSCON->SYSPLLSSCTRL1 = pSetup->syspllssctrl[1]; + SYSCON->SYSPLLSSCTRL1 = pSetup->syspllssctrl[1] | (1U << SYSCON_SYSPLLSSCTRL1_MDREQ_SHIFT); /* latch */ + + /* Flags for lock or power on */ + if ((pSetup->flags & (PLL_SETUPFLAG_POWERUP | PLL_SETUPFLAG_WAITLOCK)) != 0) + { + /* If turning the PLL back on, perform the following sequence to accelerate PLL lock */ + volatile uint32_t delayX; + uint32_t maxCCO = (1U << 18U) | 0x5dd2U; /* CCO = 1.6Ghz + MDEC enabled*/ + uint32_t curSSCTRL = SYSCON->SYSPLLSSCTRL0 & ~(1U << 17U); + + /* Initialize and power up PLL */ + SYSCON->SYSPLLSSCTRL0 = maxCCO; + POWER_DisablePD(kPDRUNCFG_PD_SYS_PLL); + + /* Set mreq to activate */ + SYSCON->SYSPLLSSCTRL0 = maxCCO | (1U << 17U); + + /* Delay for 72 uSec @ 12Mhz */ + for (delayX = 0U; delayX < 172U; ++delayX) + { + } + + /* clear mreq to prepare for restoring mreq */ + SYSCON->SYSPLLSSCTRL0 = curSSCTRL; + + /* set original value back and activate */ + SYSCON->SYSPLLSSCTRL0 = curSSCTRL | (1U << 17U); + + /* Enable peripheral states by setting low */ + POWER_DisablePD(kPDRUNCFG_PD_SYS_PLL); + } + if ((pSetup->flags & PLL_SETUPFLAG_WAITLOCK) != 0U) + { + while (CLOCK_IsSystemPLLLocked() == false) + { + } + } + + /* Update current programmed PLL rate var */ + s_Pll_Freq = pSetup->pllRate; + + return kStatus_PLL_Success; +} + +/* Set System PLL clock based on the input frequency and multiplier */ +void CLOCK_SetupSystemPLLMult(uint32_t multiply_by, uint32_t input_freq) +{ + uint32_t cco_freq = input_freq * multiply_by; + uint32_t pdec = 1U; + uint32_t selr; + uint32_t seli; + uint32_t selp; + uint32_t mdec, ndec; + + uint32_t directo = SYSCON_SYSPLLCTRL_DIRECTO(1); + + while (cco_freq < 75000000U) + { + multiply_by <<= 1U; /* double value in each iteration */ + pdec <<= 1U; /* correspondingly double pdec to cancel effect of double msel */ + cco_freq = input_freq * multiply_by; + } + selr = 0U; + if (multiply_by < 60U) + { + seli = (multiply_by & 0x3cU) + 4U; + selp = (multiply_by >> 1U) + 1U; + } + else + { + selp = 31U; + if (multiply_by > 16384U) + { + seli = 1U; + } + else if (multiply_by > 8192U) + { + seli = 2U; + } + else if (multiply_by > 2048U) + { + seli = 4U; + } + else if (multiply_by >= 501U) + { + seli = 8U; + } + else + { + seli = 4U * (1024U / (multiply_by + 9U)); + } + } + + if (pdec > 1U) + { + directo = 0U; /* use post divider */ + pdec = pdec / 2U; /* Account for minus 1 encoding */ + /* Translate P value */ + switch (pdec) + { + case 1U: + pdec = 0x62U; /* 1 * 2 */ + break; + case 2U: + pdec = 0x42U; /* 2 * 2 */ + break; + case 4U: + pdec = 0x02U; /* 4 * 2 */ + break; + case 8U: + pdec = 0x0bU; /* 8 * 2 */ + break; + case 16U: + pdec = 0x11U; /* 16 * 2 */ + break; + case 32U: + pdec = 0x08U; /* 32 * 2 */ + break; + default: + pdec = 0x08U; + break; + } + } + + mdec = PLL_SSCG0_MDEC_VAL_SET(pllEncodeM(multiply_by)); + ndec = 0x302U; /* pre divide by 1 (hardcoded) */ + + SYSCON->SYSPLLCTRL = SYSCON_SYSPLLCTRL_BANDSEL(1) | directo | SYSCON_SYSPLLCTRL_BYPASSCCODIV2(1) | + (selr << SYSCON_SYSPLLCTRL_SELR_SHIFT) | (seli << SYSCON_SYSPLLCTRL_SELI_SHIFT) | + (selp << SYSCON_SYSPLLCTRL_SELP_SHIFT); + SYSCON->SYSPLLPDEC = pdec | (1U << 7U); /* set Pdec value and assert preq */ + SYSCON->SYSPLLNDEC = ndec | (1U << 10U); /* set Pdec value and assert preq */ + SYSCON->SYSPLLSSCTRL0 = + (1U << 18U) | (1U << 17U) | mdec; /* select non sscg MDEC value, assert mreq and select mdec value */ +} diff --git a/platform/mcu/lpc54102/drivers/fsl_clock.h b/platform/mcu/lpc54102/drivers/fsl_clock.h new file mode 100644 index 0000000000..a80a4ceb2b --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_clock.h @@ -0,0 +1,771 @@ +/* + * Copyright 2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_CLOCK_H_ +#define _FSL_CLOCK_H_ + +#include "fsl_device_registers.h" +#include +#include +#include + +/*! @addtogroup clock */ +/*! @{ */ + +/*! @file */ + +/******************************************************************************* + * Definitions + *****************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief CLOCK driver version 2.0.1. */ +#define FSL_CLOCK_DRIVER_VERSION (MAKE_VERSION(2, 0, 1)) +/*@}*/ + +/*! + * @brief User-defined the size of cache for CLOCK_PllGetConfig() function. + * + * Once define this MACRO to be non-zero value, CLOCK_PllGetConfig() function + * would cache the recent calulation and accelerate the execution to get the + * right settings. + */ + +/*! @brief Clock ip name array for ROM. */ +#define ROM_CLOCKS \ + { \ + kCLOCK_Rom, \ + } + +/*! @brief Clock ip name array for SRAM. */ +#define SRAM_CLOCKS \ + { \ + kCLOCK_Sram1, kCLOCK_Sram2, \ + } + +/*! @brief Clock ip name array for FLASH. */ +#define FLASH_CLOCKS \ + { \ + kCLOCK_Flash, \ + } + +/*! @brief Clock ip name array for FMC. */ +#define FMC_CLOCKS \ + { \ + kCLOCK_Fmc, \ + } + +/*! @brief Clock ip name array for INPUTMUX. */ +#define INPUTMUX_CLOCKS \ + { \ + kCLOCK_InputMux, \ + } + +/*! @brief Clock ip name array for IOCON. */ +#define IOCON_CLOCKS \ + { \ + kCLOCK_Iocon, \ + } + +/*! @brief Clock ip name array for GPIO. */ +#define GPIO_CLOCKS \ + { \ + kCLOCK_Gpio0, kCLOCK_Gpio1, \ + } + +/*! @brief Clock ip name array for PINT. */ +#define PINT_CLOCKS \ + { \ + kCLOCK_Pint, \ + } + +/*! @brief Clock ip name array for GINT. */ +#define GINT_CLOCKS \ + { \ + kCLOCK_Gint,kCLOCK_Gint \ + } + +/*! @brief Clock ip name array for DMA. */ +#define DMA_CLOCKS \ + { \ + kCLOCK_Dma, \ + } + +/*! @brief Clock ip name array for CRC. */ +#define CRC_CLOCKS \ + { \ + kCLOCK_Crc, \ + } + +/*! @brief Clock ip name array for WWDT. */ +#define WWDT_CLOCKS \ + { \ + kCLOCK_Wwdt, \ + } + +/*! @brief Clock ip name array for RTC. */ +#define RTC_CLOCKS \ + { \ + kCLOCK_Rtc, \ + } + +/*! @brief Clock ip name array for MAILBOX. */ +#define MAILBOX_CLOCKS \ + { \ + kCLOCK_Mailbox, \ + } + +/*! @brief Clock ip name array for ADC. */ +#define ADC_CLOCKS \ + { \ + kCLOCK_Adc0, \ + } + +/*! @brief Clock ip name array for MRT. */ +#define MRT_CLOCKS \ + { \ + kCLOCK_Mrt, \ + } + +/*! @brief Clock ip name array for RIT. */ +#define RIT_CLOCKS \ + { \ + kCLOCK_Rit, \ + } + +/*! @brief Clock ip name array for SCT. */ +#define SCT_CLOCKS \ + { \ + kCLOCK_Sct0, \ + } + +/*! @brief Clock ip name array for FIFO. */ +#define FIFO_CLOCKS \ + { \ + kCLOCK_Fifo, \ + } + +/*! @brief Clock ip name array for UTICK. */ +#define UTICK_CLOCKS \ + { \ + kCLOCK_Utick, \ + } + +/*! @brief Clock ip name array for CT32B. */ +#define CTIMER_CLOCKS \ + { \ + kCLOCK_Ct32b0, kCLOCK_Ct32b1, kCLOCK_Ct32b2, kCLOCK_Ct32b3, kCLOCK_Ct32b4 \ + } + +/*! @brief Clock ip name array for USART. */ +#define USART_CLOCKS \ + { \ + kCLOCK_Usart0, kCLOCK_Usart1, kCLOCK_Usart2, kCLOCK_Usart3, \ + } + +/*! @brief Clock ip name array for I2C. */ +#define I2C_CLOCKS \ + { \ + kCLOCK_I2c0, kCLOCK_I2c1, kCLOCK_I2c2, \ + } + +/*! @brief Clock ip name array for SPI. */ +#define SPI_CLOCKS \ + { \ + kCLOCK_Spi0, kCLOCK_Spi1, \ + } + +/*! @brief Clock ip name array for FRG. */ +#define FRG_CLOCKS \ + { \ + kCLOCK_Frg, \ + } + +/*! @brief Clock gate name used for CLOCK_EnableClock/CLOCK_DisableClock. */ +/*------------------------------------------------------------------------------ + clock_ip_name_t definition: +------------------------------------------------------------------------------*/ + +#define CLK_GATE_REG_OFFSET_SHIFT 8U +#define CLK_GATE_REG_OFFSET_MASK 0xFFFFFF00U +#define CLK_GATE_BIT_SHIFT_SHIFT 0U +#define CLK_GATE_BIT_SHIFT_MASK 0x000000FFU + +#define CLK_GATE_DEFINE(reg_offset, bit_shift) \ + ((((reg_offset) << CLK_GATE_REG_OFFSET_SHIFT) & CLK_GATE_REG_OFFSET_MASK) | \ + (((bit_shift) << CLK_GATE_BIT_SHIFT_SHIFT) & CLK_GATE_BIT_SHIFT_MASK)) + +#define CLK_GATE_ABSTRACT_REG_OFFSET(x) (((uint32_t)(x)&CLK_GATE_REG_OFFSET_MASK) >> CLK_GATE_REG_OFFSET_SHIFT) +#define CLK_GATE_ABSTRACT_BITS_SHIFT(x) (((uint32_t)(x)&CLK_GATE_BIT_SHIFT_MASK) >> CLK_GATE_BIT_SHIFT_SHIFT) + +#define AHB_CLK_CTRL0 0 +#define AHB_CLK_CTRL1 1 +#define ASYNC_CLK_CTRL0 2 + +/*! @brief Clock gate name used for CLOCK_EnableClock/CLOCK_DisableClock. */ +typedef enum _clock_ip_name +{ + /* AHBCLKCTRL0 */ + kCLOCK_IpInvalid = 0U, + kCLOCK_Rom = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 1), + kCLOCK_Sram1 = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 3), + kCLOCK_Sram2 = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 4), + kCLOCK_Flash = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 7), + kCLOCK_Fmc = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 8), + kCLOCK_InputMux = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 11), + kCLOCK_Iocon = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 13), + kCLOCK_Gpio0 = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 14), + kCLOCK_Gpio1 = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 15), + kCLOCK_Pint = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 18), + kCLOCK_Gint = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 19), + kCLOCK_Dma = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 20), + kCLOCK_Crc = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 21), + kCLOCK_Wwdt = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 22), + kCLOCK_Rtc = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 23), + kCLOCK_Mailbox = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 26), + kCLOCK_Adc0 = CLK_GATE_DEFINE(AHB_CLK_CTRL0, 27), + /* AHBCLKCTRL1 */ + kCLOCK_Mrt = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 0), + kCLOCK_Rit = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 1), + kCLOCK_Sct0 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 2), + kCLOCK_Fifo = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 9), + kCLOCK_Utick = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 10), + kCLOCK_Ct32b2 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 22), + kCLOCK_Ct32b3 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 26), + kCLOCK_Ct32b4 = CLK_GATE_DEFINE(AHB_CLK_CTRL1, 27), + /* ASYNCPRESETCTRL */ + kCLOCK_Usart0 = CLK_GATE_DEFINE(ASYNC_CLK_CTRL0, 1), + kCLOCK_Usart1 = CLK_GATE_DEFINE(ASYNC_CLK_CTRL0, 2), + kCLOCK_Usart2 = CLK_GATE_DEFINE(ASYNC_CLK_CTRL0, 3), + kCLOCK_Usart3 = CLK_GATE_DEFINE(ASYNC_CLK_CTRL0, 4), + kCLOCK_I2c0 = CLK_GATE_DEFINE(ASYNC_CLK_CTRL0, 5), + kCLOCK_I2c1 = CLK_GATE_DEFINE(ASYNC_CLK_CTRL0, 6), + kCLOCK_I2c2 = CLK_GATE_DEFINE(ASYNC_CLK_CTRL0, 7), + kCLOCK_Spi0 = CLK_GATE_DEFINE(ASYNC_CLK_CTRL0, 9), + kCLOCK_Spi1 = CLK_GATE_DEFINE(ASYNC_CLK_CTRL0, 10), + kCLOCK_Ct32b0 = CLK_GATE_DEFINE(ASYNC_CLK_CTRL0, 13), + kCLOCK_Ct32b1 = CLK_GATE_DEFINE(ASYNC_CLK_CTRL0, 14), + kCLOCK_Frg = CLK_GATE_DEFINE(ASYNC_CLK_CTRL0, 15), +} clock_ip_name_t; + +/*! @brief Clock name used to get clock frequency. */ +typedef enum _clock_name +{ + kCLOCK_MainClk, /*!< Main clock */ + kCLOCK_CoreSysClk, /*!< Core/system clock */ + kCLOCK_BusClk, /*!< Bus clock (AHB clock) */ + kCLOCK_Irc, /*!< Internal IRC */ + kCLOCK_ExtClk, /*!< External Clock */ + kCLOCK_PllOut, /*!< PLL Output */ + kClock_WdtOsc, /*!< Watchdog Oscillator */ + kCLOCK_FRG, /*!< Frg Clock */ + kCLOCK_AsyncApbClk, /*!< Async APB clock */ + kCLOCK_Adc, /*!< ADC clock */ + kCLOCK_ClockOut, /*!< Clockout clock */ + kCLOCK_Usart, /*!< USART clock */ + kCLOCK_Spi, /*!< SPI clock */ + kCLOCK_I2c, /*!< I2C clock */ +} clock_name_t; + +/*! @brief Clock Mux Switches +* The encoding is as follows each connection identified is 64bits wide +* starting from LSB upwards +* +* [4 bits for choice, where 1 is A, 2 is B, 3 is C and 4 is D, 0 means end of descriptor] [8 bits mux ID]* +* +*/ + +#define MUX_A(m, choice) (((m) << 0) | ((choice + 1) << 8)) +#define MUX_B(m, choice) (((m) << 12) | ((choice + 1) << 20)) +#define MUX_C(m, choice) (((m) << 24) | ((choice + 1) << 32)) +#define MUX_D(m, choice) (((m) << 36) | ((choice + 1) << 44)) +#define MUX_E(m, choice) (((m) << 48) | ((choice + 1) << 56)) + +#define CM_MAINCLKSELA 0 +#define CM_MAINCLKSELB 1 +#define CM_ADCCLKSEL 3 +#define CM_CLKOUTCLKSELA 5 +#define CM_CLKOUTCLKSELB 6 +#define CM_SYSPLLCLKSEL 8 + +#define CM_ASYNCAPA 30 +#define CM_ASYNCAPB 31 + +typedef enum _clock_attach_id +{ + kIRC12M_to_MAIN_CLK = MUX_A(CM_MAINCLKSELA, 0) | MUX_B(CM_MAINCLKSELB, 0), + kCLKIN_to_MAIN_CLK = MUX_A(CM_MAINCLKSELA, 1) | MUX_B(CM_MAINCLKSELB, 0), + kWDT_OSC_to_MAIN_CLK = MUX_A(CM_MAINCLKSELA, 2) | MUX_B(CM_MAINCLKSELB, 0), + kSYS_PLL_IN_to_MAIN_CLK = MUX_A(CM_MAINCLKSELB, 1), + kSYS_PLL_OUT_to_MAIN_CLK = MUX_A(CM_MAINCLKSELB, 2), + kRTC_OSC_to_MAIN_CLK = MUX_A(CM_MAINCLKSELB, 3), + + kMAIN_CLK_to_ADC_CLK = MUX_A(CM_ADCCLKSEL, 0), + kSYS_PLL_OUT_to_ADC_CLK = MUX_A(CM_ADCCLKSEL, 1), + kIRC12M_to_ADC_CLK = MUX_A(CM_ADCCLKSEL, 2), + + kMAIN_CLK_to_CLKOUT = MUX_A(CM_CLKOUTCLKSELA, 0) | MUX_B(CM_CLKOUTCLKSELB, 0), + kCLKIN_to_CLKOUT = MUX_A(CM_CLKOUTCLKSELA, 1) | MUX_B(CM_CLKOUTCLKSELB, 0), + kWDT_OSC_to_CLKOUT = MUX_A(CM_CLKOUTCLKSELA, 2) | MUX_B(CM_CLKOUTCLKSELB, 0), + kIRC12M_to_CLKOUT = MUX_A(CM_CLKOUTCLKSELA, 3) | MUX_B(CM_CLKOUTCLKSELB, 0), + kRTC_OSC_to_CLKOUT = MUX_A(CM_CLKOUTCLKSELB, 3), + + kIRC12M_to_SYS_PLL = MUX_A(CM_SYSPLLCLKSEL, 0), + kCLKIN_to_SYS_PLL = MUX_A(CM_SYSPLLCLKSEL, 1), + kRTC_OSC_to_SYS_PLL = MUX_A(CM_SYSPLLCLKSEL, 3), + + kIRC12M_to_ASYNC_APB = MUX_A(CM_ASYNCAPA, 0) | MUX_B(CM_ASYNCAPB, 3), + kWDT_OSC_to_ASYNC_APB = MUX_A(CM_ASYNCAPA, 1) | MUX_B(CM_ASYNCAPB, 3), + kMAIN_CLK_OUT_to_ASYNC_APB = MUX_A(CM_ASYNCAPB, 0), + kCLKIN_to_ASYNC_APB = MUX_A(CM_ASYNCAPB, 1), + kSYS_PLL_OUT_to_ASYNC_APB = MUX_A(CM_ASYNCAPB, 2), + + kIRC12M_to_USART = MUX_A(CM_ASYNCAPA, 0) | MUX_B(CM_ASYNCAPB, 3), + kWDT_OSC_to_USART = MUX_A(CM_ASYNCAPA, 1) | MUX_B(CM_ASYNCAPB, 3), + kMAIN_CLK_OUT_to_USART = MUX_A(CM_ASYNCAPB, 0), + kCLKIN_to_USART = MUX_A(CM_ASYNCAPB, 1), + kSYS_PLL_OUT_to_USART = MUX_A(CM_ASYNCAPB, 2), + + kIRC12M_to_SPI = MUX_A(CM_ASYNCAPA, 0) | MUX_B(CM_ASYNCAPB, 3), + kWDT_OSC_to_SPI = MUX_A(CM_ASYNCAPA, 1) | MUX_B(CM_ASYNCAPB, 3), + kMAIN_CLK_OUT_to_SPI = MUX_A(CM_ASYNCAPB, 0), + kCLKIN_to_SPI = MUX_A(CM_ASYNCAPB, 1), + kSYS_PLL_OUT_to_SPI = MUX_A(CM_ASYNCAPB, 2), + + kIRC12M_to_I2C = MUX_A(CM_ASYNCAPA, 0) | MUX_B(CM_ASYNCAPB, 3), + kWDT_OSC_to_I2C = MUX_A(CM_ASYNCAPA, 1) | MUX_B(CM_ASYNCAPB, 3), + kMAIN_CLK_OUT_to_I2C = MUX_A(CM_ASYNCAPB, 0), + kCLKIN_to_I2C = MUX_A(CM_ASYNCAPB, 1), + kSYS_PLL_OUT_to_I2C = MUX_A(CM_ASYNCAPB, 2), + + kNONE_to_NONE = 0x80000000U, +} clock_attach_id_t; + +/* Clock dividers */ +typedef enum _clock_div_name +{ + kCLOCK_DivSystickClk = 0, + kCLOCK_DivAhbClk = 8, + kCLOCK_DivAdcClk = 10, + kCLOCK_DivClkOut = 11, +} clock_div_name_t; + +/** + * @brief FLASH Access time definitions + */ +typedef enum _clock_flashtim +{ + kCLOCK_Flash1Cycle = 0, /*!< Flash accesses use 1 CPU clock */ + kCLOCK_Flash2Cycle, /*!< Flash accesses use 2 CPU clocks */ + kCLOCK_Flash3Cycle, /*!< Flash accesses use 3 CPU clocks */ + kCLOCK_Flash4Cycle, /*!< Flash accesses use 4 CPU clocks */ + kCLOCK_Flash5Cycle, /*!< Flash accesses use 5 CPU clocks */ + kCLOCK_Flash6Cycle, /*!< Flash accesses use 6 CPU clocks */ +} clock_flashtim_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + +/*! @brief Set Asyc clock divider + * @param divided_by_value : Asyc clock divider + */ +static inline void Clock_SetAsyncClkDiv(uint32_t divided_by_value) +{ + ASYNC_SYSCON->ASYNCCLKDIV = divided_by_value; /* if divided_by_value is 0, clock will be disable*/ +} + +/* @brief Enable the clock for specific IP. + * @param name Which clock to enable, see clock_ip_name_t. + */ +static inline void CLOCK_EnableClock(clock_ip_name_t clk) +{ + uint32_t index = CLK_GATE_ABSTRACT_REG_OFFSET(clk); + if (index < 2) + { + SYSCON->AHBCLKCTRLSET[index] = (1U << CLK_GATE_ABSTRACT_BITS_SHIFT(clk)); + } + else + { + ASYNC_SYSCON->ASYNCAPBCLKCTRLSET = (1U << CLK_GATE_ABSTRACT_BITS_SHIFT(clk)); + } +} + +/* @brief Disable the clock for specific IP. + * @param name Which clock to enable, see clock_ip_name_t. + */ +static inline void CLOCK_DisableClock(clock_ip_name_t clk) +{ + uint32_t index = CLK_GATE_ABSTRACT_REG_OFFSET(clk); + if (index < 2) + { + SYSCON->AHBCLKCTRLCLR[index] = (1U << CLK_GATE_ABSTRACT_BITS_SHIFT(clk)); + } + else + { + ASYNC_SYSCON->ASYNCAPBCLKCTRLCLR = (1U << CLK_GATE_ABSTRACT_BITS_SHIFT(clk)); + } +} + +/*! @brief Enables and disables PLL bypass mode + * @brief bypass : true to bypass PLL (PLL output = PLL input, false to disable bypass + * @return System PLL output clock rate + */ +static inline void CLOCK_SetBypassPLL(bool bypass) +{ + if (bypass) + { + SYSCON->SYSPLLCTRL |= (1UL << SYSCON_SYSPLLCTRL_BYPASS_SHIFT); + } + else + { + SYSCON->SYSPLLCTRL &= ~(1UL << SYSCON_SYSPLLCTRL_BYPASS_SHIFT); + } +} + +/*! @brief Check if PLL is locked or not + * @return true if the PLL is locked, false if not locked + */ +static inline bool CLOCK_IsSystemPLLLocked(void) +{ + return (bool)((SYSCON->SYSPLLSTAT & SYSCON_SYSPLLSTAT_LOCK_MASK) != 0U); +} + +/** + * @brief Set FLASH memory access time in clocks + * @param clks : Clock cycles for FLASH access + * @return Nothing + */ +static inline void CLOCK_SetFLASHAccessCycles(clock_flashtim_t clks) +{ + uint32_t tmp; + tmp = SYSCON->FLASHCFG & ~(SYSCON_FLASHCFG_FLASHTIM_MASK); + /* Don't alter lower bits */ + SYSCON->FLASHCFG = tmp | ((uint32_t)clks << SYSCON_FLASHCFG_FLASHTIM_SHIFT); +} + +/** + * @brief Configure the clock selection muxes. + * @param connection : Clock to be configured. + * @return Nothing + */ +void CLOCK_AttachClk(clock_attach_id_t connection); + +/** + * @brief Setup peripheral clock dividers. + * @param div_name : Clock divider name + * @param divided_by_value: Value to be divided + @param reset, not used + * @return Nothing + */ +void CLOCK_SetClkDiv(clock_div_name_t div_name, uint32_t divided_by_value, bool reset); + +/** + * @brief Set the flash wait states for the input freuqency. + * @param iFreq : Input frequency + * @return Nothing + */ +void CLOCK_SetFLASHAccessCyclesForFreq(uint32_t iFreq); + +/*! @brief Return Frequency of Core clock + * @return Frequency of Core clock + */ +uint32_t CLOCK_GetCoreClkFreq(void); + +/*! @brief Return Frequency of Bus clock + * @return Frequency of Bus clock + */ +uint32_t CLOCK_GetBusClkFreq(void); + +/*! @brief Return Frequency of selected clock + * @return Frequency of selected clock + */ +uint32_t CLOCK_GetFreq(clock_name_t clockName); + +/*! @brief Return Frequency of External Clock + * @return Frequency of External Clock. If no external clock is used returns 0. + */ +uint32_t CLOCK_GetExtClkFreq(void); + +/*! @brief Return Frequency of Watchdog Oscillator + * @return Frequency of Watchdog Oscillator + */ +uint32_t CLOCK_GetWdtOscFreq(void); + +/*! @brief Return Frequency of PLL + * @return Frequency of PLL + */ +uint32_t CLOCK_GetPllOutFreq(void); + +/*! @brief Return Frequency of 32kHz osc + * @return Frequency of 32kHz osc + */ +uint32_t CLOCK_GetOsc32KFreq(void); + +/*! @brief Return Frequency of ADC + * @return Frequency of ADC + */ +uint32_t CLOCK_GetAdcClkFreq(void); + +/*! @brief Return Frequency of clock out + * @return Frequency of clock out + */ +uint32_t CLOCK_GetClockOutClkFreq(void); + +/*! @brief Return Frequency of IRC + * @return Frequency of IRC + */ +uint32_t CLOCK_GetIrc12MFreq(void); + +/*! @brief Return Frequency of PLL input + * @return Frequency of PLL input + */ +uint32_t CLOCK_GetPllInFreq(void); + +/*! @brief Return Frequency of Core System + * @return Frequency of Core System + */ +uint32_t CLOCK_GetMainClkFreq(void); + +/*! @brief Return Frequency of Asynchronous APB Clock + * @return Frequency of Asynchronous APB Clock Clock + */ +uint32_t CLOCK_GetAsyncApbClkFreq(void); + +/*! @brief Set Frequency of FRG + * @return status of the setting, true: setting successful, false: setting fail + */ +bool CLOCK_SetFRGClock(uint32_t freq); + +/*! @brief Return System PLL input clock rate + * @return System PLL input clock rate + */ +uint32_t CLOCK_GetSystemPLLInClockRate(void); + +/*! @brief Return System PLL output clock rate + * @param recompute : Forces a PLL rate recomputation if true + * @return System PLL output clock rate + * @note The PLL rate is cached in the driver in a variable as + * the rate computation function can take some time to perform. It + * is recommended to use 'false' with the 'recompute' parameter. + */ +uint32_t CLOCK_GetSystemPLLOutClockRate(bool recompute); + +/*! @brief Store the current PLL rate + * @param rate: Current rate of the PLL + * @return Nothing + **/ +void CLOCK_SetStoredPLLClockRate(uint32_t rate); + +/*! @brief PLL configuration structure flags for 'flags' field + * These flags control how the PLL configuration function sets up the PLL setup structure. + * + * When the PLL_CONFIGFLAG_USEINRATE flag is selected, the 'InputRate' field in the + * configuration structure must be assigned with the expected PLL frequency. If the + * PLL_CONFIGFLAG_USEINRATE is not used, 'InputRate' is ignored in the configuration + * function and the driver will determine the PLL rate from the currently selected + * PLL source. This flag might be used to configure the PLL input clock more accurately + * when using the WDT oscillator or a more dyanmic CLKIN source. + * + * When the PLL_CONFIGFLAG_FORCENOFRACT flag is selected, the PLL hardware for the + * automatic bandwidth selection, Spread Spectrum (SS) support, and fractional M-divider + * are not used + */ +#define PLL_CONFIGFLAG_USEINRATE (1U << 0U) /*!< Flag to use InputRate in PLL configuration structure for setup */ +#define PLL_CONFIGFLAG_FORCENOFRACT \ + (1U << 2U) /*!< Force non-fractional output mode, PLL output will not use the fractional, automatic bandwidth, or \ + \ \ \ + \ \ \ \ \ + \ \ \ \ \ \ \ \ + SS hardware */ + +/*! @brief PLL Spread Spectrum (SS) Programmable modulation frequency + * See (MF) field in the SYSPLLSSCTRL1 register in the UM. + */ +typedef enum _ss_progmodfm +{ + kSS_MF_512 = (0U << 20U), /*!< Nss = 512 (fm ?= 3.9 - 7.8 kHz) */ + kSS_MF_384 = (1U << 20U), /*!< Nss = 384 (fm ?= 5.2 - 10.4 kHz) */ + kSS_MF_256 = (2U << 20U), /*!< Nss = 256 (fm ?= 7.8 - 15.6 kHz) */ + kSS_MF_128 = (3U << 20U), /*!< Nss = 128 (fm ?= 15.6 - 31.3 kHz) */ + kSS_MF_64 = (4U << 20U), /*!< Nss = 64 (fm ?= 32.3 - 64.5 kHz) */ + kSS_MF_32 = (5U << 20U), /*!< Nss = 32 (fm ?= 62.5- 125 kHz) */ + kSS_MF_24 = (6U << 20U), /*!< Nss = 24 (fm ?= 83.3- 166.6 kHz) */ + kSS_MF_16 = (7U << 20U) /*!< Nss = 16 (fm ?= 125- 250 kHz) */ +} ss_progmodfm_t; + +/*! @brief PLL Spread Spectrum (SS) Programmable frequency modulation depth + * See (MR) field in the SYSPLLSSCTRL1 register in the UM. + */ +typedef enum _ss_progmoddp +{ + kSS_MR_K0 = (0U << 23U), /*!< k = 0 (no spread spectrum) */ + kSS_MR_K1 = (1U << 23U), /*!< k = 1 */ + kSS_MR_K1_5 = (2U << 23U), /*!< k = 1.5 */ + kSS_MR_K2 = (3U << 23U), /*!< k = 2 */ + kSS_MR_K3 = (4U << 23U), /*!< k = 3 */ + kSS_MR_K4 = (5U << 23U), /*!< k = 4 */ + kSS_MR_K6 = (6U << 23U), /*!< k = 6 */ + kSS_MR_K8 = (7U << 23U) /*!< k = 8 */ +} ss_progmoddp_t; + +/*! @brief PLL Spread Spectrum (SS) Modulation waveform control + * See (MC) field in the SYSPLLSSCTRL1 register in the UM.
+ * Compensation for low pass filtering of the PLL to get a triangular + * modulation at the output of the PLL, giving a flat frequency spectrum. + */ +typedef enum _ss_modwvctrl +{ + kSS_MC_NOC = (0U << 26U), /*!< no compensation */ + kSS_MC_RECC = (2U << 26U), /*!< recommended setting */ + kSS_MC_MAXC = (3U << 26U), /*!< max. compensation */ +} ss_modwvctrl_t; + +/*! @brief PLL configuration structure + * + * This structure can be used to configure the settings for a PLL + * setup structure. Fill in the desired configuration for the PLL + * and call the PLL setup function to fill in a PLL setup structure. + */ +typedef struct _pll_config +{ + uint32_t desiredRate; /*!< Desired PLL rate in Hz */ + uint32_t inputRate; /*!< PLL input clock in Hz, only used if PLL_CONFIGFLAG_USEINRATE flag is set */ + uint32_t flags; /*!< PLL configuration flags, Or'ed value of PLL_CONFIGFLAG_* definitions */ + ss_progmodfm_t ss_mf; /*!< SS Programmable modulation frequency, only applicable when not using + PLL_CONFIGFLAG_FORCENOFRACT flag */ + ss_progmoddp_t ss_mr; /*!< SS Programmable frequency modulation depth, only applicable when not using + PLL_CONFIGFLAG_FORCENOFRACT flag */ + ss_modwvctrl_t + ss_mc; /*!< SS Modulation waveform control, only applicable when not using PLL_CONFIGFLAG_FORCENOFRACT flag */ + bool mfDither; /*!< false for fixed modulation frequency or true for dithering, only applicable when not using + PLL_CONFIGFLAG_FORCENOFRACT flag */ + +} pll_config_t; + +/*! @brief PLL setup structure flags for 'flags' field +* These flags control how the PLL setup function sets up the PLL +*/ +#define PLL_SETUPFLAG_POWERUP (1U << 0U) /*!< Setup will power on the PLL after setup */ +#define PLL_SETUPFLAG_WAITLOCK (1U << 1U) /*!< Setup will wait for PLL lock, implies the PLL will be pwoered on */ +#define PLL_SETUPFLAG_ADGVOLT (1U << 2U) /*!< Optimize system voltage for the new PLL rate */ +#define PLL_SETUPFLAG_USEFEEDBACKDIV2 (1U << 3U) /*!< Use feedback divider by 2 in divider path */ + +/*! @brief PLL setup structure +* This structure can be used to pre-build a PLL setup configuration +* at run-time and quickly set the PLL to the configuration. It can be +* populated with the PLL setup function. If powering up or waiting +* for PLL lock, the PLL input clock source should be configured prior +* to PLL setup. +*/ +typedef struct _pll_setup +{ + uint32_t syspllctrl; /*!< PLL control register SYSPLLCTRL */ + uint32_t syspllndec; /*!< PLL NDEC register SYSPLLNDEC */ + uint32_t syspllpdec; /*!< PLL PDEC register SYSPLLPDEC */ + uint32_t syspllssctrl[2]; /*!< PLL SSCTL registers SYSPLLSSCTRL */ + uint32_t pllRate; /*!< Acutal PLL rate */ + uint32_t flags; /*!< PLL setup flags, Or'ed value of PLL_SETUPFLAG_* definitions */ +} pll_setup_t; + +/*! @brief PLL status definitions + */ +typedef enum _pll_error +{ + kStatus_PLL_Success = MAKE_STATUS(kStatusGroup_Generic, 0), /*!< PLL operation was successful */ + kStatus_PLL_OutputTooLow = MAKE_STATUS(kStatusGroup_Generic, 1), /*!< PLL output rate request was too low */ + kStatus_PLL_OutputTooHigh = MAKE_STATUS(kStatusGroup_Generic, 2), /*!< PLL output rate request was too high */ + kStatus_PLL_InputTooLow = MAKE_STATUS(kStatusGroup_Generic, 3), /*!< PLL input rate is too low */ + kStatus_PLL_InputTooHigh = MAKE_STATUS(kStatusGroup_Generic, 4), /*!< PLL input rate is too high */ + kStatus_PLL_OutsideIntLimit = MAKE_STATUS(kStatusGroup_Generic, 5) /*!< Requested output rate isn't possible */ +} pll_error_t; + +/*! @brief Return System PLL output clock rate from setup structure + * @param pSetup : Pointer to a PLL setup structure + * @return System PLL output clock rate calculated from the setup structure + */ +uint32_t CLOCK_GetSystemPLLOutFromSetup(pll_setup_t *pSetup); + +/*! @brief Set PLL output based on the passed PLL setup data + * @param pControl : Pointer to populated PLL control structure to generate setup with + * @param pSetup : Pointer to PLL setup structure to be filled + * @return PLL_ERROR_SUCCESS on success, or PLL setup error code + * @note Actual frequency for setup may vary from the desired frequency based on the + * accuracy of input clocks, rounding, non-fractional PLL mode, etc. + */ +pll_error_t CLOCK_SetupPLLData(pll_config_t *pControl, pll_setup_t *pSetup); + +/*! @brief Set PLL output from PLL setup structure (precise frequency) + * @param pSetup : Pointer to populated PLL setup structure + * @param flagcfg : Flag configuration for PLL config structure + * @return PLL_ERROR_SUCCESS on success, or PLL setup error code + * @note This function will power off the PLL, setup the PLL with the + * new setup data, and then optionally powerup the PLL, wait for PLL lock, + * and adjust system voltages to the new PLL rate. The function will not + * alter any source clocks (ie, main systen clock) that may use the PLL, + * so these should be setup prior to and after exiting the function. + */ +pll_error_t CLOCK_SetupSystemPLLPrec(pll_setup_t *pSetup, uint32_t flagcfg); + +/*! @brief Set PLL output from PLL setup structure (precise frequency) + * @param pSetup : Pointer to populated PLL setup structure + * @return kStatus_PLL_Success on success, or PLL setup error code + * @note This function will power off the PLL, setup the PLL with the + * new setup data, and then optionally powerup the PLL, wait for PLL lock, + * and adjust system voltages to the new PLL rate. The function will not + * alter any source clocks (ie, main systen clock) that may use the PLL, + * so these should be setup prior to and after exiting the function. + */ +pll_error_t CLOCK_SetPLLFreq(const pll_setup_t *pSetup); + +/*! @brief Set PLL output based on the multiplier and input frequency + * @param multiply_by : multiplier + * @param input_freq : Clock input frequency of the PLL + * @return Nothing + * @note Unlike the Chip_Clock_SetupSystemPLLPrec() function, this + * function does not disable or enable PLL power, wait for PLL lock, + * or adjust system voltages. These must be done in the application. + * The function will not alter any source clocks (ie, main systen clock) + * that may use the PLL, so these should be setup prior to and after + * exiting the function. + */ +void CLOCK_SetupSystemPLLMult(uint32_t multiply_by, uint32_t input_freq); + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + +/*! @} */ + +#endif /* _FSL_CLOCK_H_ */ diff --git a/platform/mcu/lpc54102/drivers/fsl_common.c b/platform/mcu/lpc54102/drivers/fsl_common.c new file mode 100644 index 0000000000..fa44abc005 --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_common.c @@ -0,0 +1,122 @@ +/* +* Copyright (c) 2015-2016, Freescale Semiconductor, Inc. + * Copyright 2016 NXP +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, +* are permitted provided that the following conditions are met: +* +* o Redistributions of source code must retain the above copyright notice, this list +* of conditions and the following disclaimer. +* +* o 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. +* +* o Neither the name of the copyright holder nor the names of its +* contributors may be used to endorse or promote products derived from this +* software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "fsl_common.h" + +#ifndef __GIC_PRIO_BITS +#if defined(ENABLE_RAM_VECTOR_TABLE) +uint32_t InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler) +{ +/* Addresses for VECTOR_TABLE and VECTOR_RAM come from the linker file */ +#if defined(__CC_ARM) + extern uint32_t Image$$VECTOR_ROM$$Base[]; + extern uint32_t Image$$VECTOR_RAM$$Base[]; + extern uint32_t Image$$RW_m_data$$Base[]; + +#define __VECTOR_TABLE Image$$VECTOR_ROM$$Base +#define __VECTOR_RAM Image$$VECTOR_RAM$$Base +#define __RAM_VECTOR_TABLE_SIZE (((uint32_t)Image$$RW_m_data$$Base - (uint32_t)Image$$VECTOR_RAM$$Base)) +#elif defined(__ICCARM__) + extern uint32_t __RAM_VECTOR_TABLE_SIZE[]; + extern uint32_t __VECTOR_TABLE[]; + extern uint32_t __VECTOR_RAM[]; +#elif defined(__GNUC__) + extern uint32_t __VECTOR_TABLE[]; + extern uint32_t __VECTOR_RAM[]; + extern uint32_t __RAM_VECTOR_TABLE_SIZE_BYTES[]; + uint32_t __RAM_VECTOR_TABLE_SIZE = (uint32_t)(__RAM_VECTOR_TABLE_SIZE_BYTES); +#endif /* defined(__CC_ARM) */ + uint32_t n; + uint32_t ret; + uint32_t irqMaskValue; + + irqMaskValue = DisableGlobalIRQ(); + if (SCB->VTOR != (uint32_t)__VECTOR_RAM) + { + /* Copy the vector table from ROM to RAM */ + for (n = 0; n < ((uint32_t)__RAM_VECTOR_TABLE_SIZE) / sizeof(uint32_t); n++) + { + __VECTOR_RAM[n] = __VECTOR_TABLE[n]; + } + /* Point the VTOR to the position of vector table */ + SCB->VTOR = (uint32_t)__VECTOR_RAM; + } + + ret = __VECTOR_RAM[irq + 16]; + /* make sure the __VECTOR_RAM is noncachable */ + __VECTOR_RAM[irq + 16] = irqHandler; + + EnableGlobalIRQ(irqMaskValue); + +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif + + return ret; +} +#endif /* ENABLE_RAM_VECTOR_TABLE. */ +#endif /* __GIC_PRIO_BITS. */ + +#ifndef QN908XC_SERIES +#if (defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0)) + +void EnableDeepSleepIRQ(IRQn_Type interrupt) +{ + uint32_t index = 0; + uint32_t intNumber = (uint32_t)interrupt; + while (intNumber >= 32u) + { + index++; + intNumber -= 32u; + } + + SYSCON->STARTERSET[index] = 1u << intNumber; + EnableIRQ(interrupt); /* also enable interrupt at NVIC */ +} + +void DisableDeepSleepIRQ(IRQn_Type interrupt) +{ + uint32_t index = 0; + uint32_t intNumber = (uint32_t)interrupt; + while (intNumber >= 32u) + { + index++; + intNumber -= 32u; + } + + DisableIRQ(interrupt); /* also disable interrupt at NVIC */ + SYSCON->STARTERCLR[index] = 1u << intNumber; +} +#endif /* FSL_FEATURE_SOC_SYSCON_COUNT */ + +#endif /* QN908XC_SERIES */ diff --git a/platform/mcu/lpc54102/drivers/fsl_common.h b/platform/mcu/lpc54102/drivers/fsl_common.h new file mode 100644 index 0000000000..bd3eaaa589 --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_common.h @@ -0,0 +1,512 @@ +/* + * Copyright (c) 2015-2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_COMMON_H_ +#define _FSL_COMMON_H_ + +#include +#include +#include +#include + +#if defined(__ICCARM__) +#include +#endif + +#include "fsl_device_registers.h" + +/*! + * @addtogroup ksdk_common + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief Construct a status code value from a group and code number. */ +#define MAKE_STATUS(group, code) ((((group)*100) + (code))) + +/*! @brief Construct the version number for drivers. */ +#define MAKE_VERSION(major, minor, bugfix) (((major) << 16) | ((minor) << 8) | (bugfix)) + +/*! @name Driver version */ +/*@{*/ +/*! @brief common driver version 2.0.0. */ +#define FSL_COMMON_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*@}*/ + +/* Debug console type definition. */ +#define DEBUG_CONSOLE_DEVICE_TYPE_NONE 0U /*!< No debug console. */ +#define DEBUG_CONSOLE_DEVICE_TYPE_UART 1U /*!< Debug console base on UART. */ +#define DEBUG_CONSOLE_DEVICE_TYPE_LPUART 2U /*!< Debug console base on LPUART. */ +#define DEBUG_CONSOLE_DEVICE_TYPE_LPSCI 3U /*!< Debug console base on LPSCI. */ +#define DEBUG_CONSOLE_DEVICE_TYPE_USBCDC 4U /*!< Debug console base on USBCDC. */ +#define DEBUG_CONSOLE_DEVICE_TYPE_FLEXCOMM 5U /*!< Debug console base on USBCDC. */ +#define DEBUG_CONSOLE_DEVICE_TYPE_IUART 6U /*!< Debug console base on i.MX UART. */ +#define DEBUG_CONSOLE_DEVICE_TYPE_VUSART 7U /*!< Debug console base on LPC_USART. */ + +/*! @brief Status group numbers. */ +enum _status_groups +{ + kStatusGroup_Generic = 0, /*!< Group number for generic status codes. */ + kStatusGroup_FLASH = 1, /*!< Group number for FLASH status codes. */ + kStatusGroup_LPSPI = 4, /*!< Group number for LPSPI status codes. */ + kStatusGroup_FLEXIO_SPI = 5, /*!< Group number for FLEXIO SPI status codes. */ + kStatusGroup_DSPI = 6, /*!< Group number for DSPI status codes. */ + kStatusGroup_FLEXIO_UART = 7, /*!< Group number for FLEXIO UART status codes. */ + kStatusGroup_FLEXIO_I2C = 8, /*!< Group number for FLEXIO I2C status codes. */ + kStatusGroup_LPI2C = 9, /*!< Group number for LPI2C status codes. */ + kStatusGroup_UART = 10, /*!< Group number for UART status codes. */ + kStatusGroup_I2C = 11, /*!< Group number for UART status codes. */ + kStatusGroup_LPSCI = 12, /*!< Group number for LPSCI status codes. */ + kStatusGroup_LPUART = 13, /*!< Group number for LPUART status codes. */ + kStatusGroup_SPI = 14, /*!< Group number for SPI status code.*/ + kStatusGroup_XRDC = 15, /*!< Group number for XRDC status code.*/ + kStatusGroup_SEMA42 = 16, /*!< Group number for SEMA42 status code.*/ + kStatusGroup_SDHC = 17, /*!< Group number for SDHC status code */ + kStatusGroup_SDMMC = 18, /*!< Group number for SDMMC status code */ + kStatusGroup_SAI = 19, /*!< Group number for SAI status code */ + kStatusGroup_MCG = 20, /*!< Group number for MCG status codes. */ + kStatusGroup_SCG = 21, /*!< Group number for SCG status codes. */ + kStatusGroup_SDSPI = 22, /*!< Group number for SDSPI status codes. */ + kStatusGroup_FLEXIO_I2S = 23, /*!< Group number for FLEXIO I2S status codes */ + kStatusGroup_FLEXIO_MCULCD = 24, /*!< Group number for FLEXIO LCD status codes */ + kStatusGroup_FLASHIAP = 25, /*!< Group number for FLASHIAP status codes */ + kStatusGroup_FLEXCOMM_I2C = 26, /*!< Group number for FLEXCOMM I2C status codes */ + kStatusGroup_I2S = 27, /*!< Group number for I2S status codes */ + kStatusGroup_IUART = 28, /*!< Group number for IUART status codes */ + kStatusGroup_CSI = 29, /*!< Group number for CSI status codes */ + kStatusGroup_MIPI_DSI = 30, /*!< Group number for MIPI DSI status codes */ + kStatusGroup_SDRAMC = 35, /*!< Group number for SDRAMC status codes. */ + kStatusGroup_POWER = 39, /*!< Group number for POWER status codes. */ + kStatusGroup_ENET = 40, /*!< Group number for ENET status codes. */ + kStatusGroup_PHY = 41, /*!< Group number for PHY status codes. */ + kStatusGroup_TRGMUX = 42, /*!< Group number for TRGMUX status codes. */ + kStatusGroup_SMARTCARD = 43, /*!< Group number for SMARTCARD status codes. */ + kStatusGroup_LMEM = 44, /*!< Group number for LMEM status codes. */ + kStatusGroup_QSPI = 45, /*!< Group number for QSPI status codes. */ + kStatusGroup_DMA = 50, /*!< Group number for DMA status codes. */ + kStatusGroup_EDMA = 51, /*!< Group number for EDMA status codes. */ + kStatusGroup_DMAMGR = 52, /*!< Group number for DMAMGR status codes. */ + kStatusGroup_FLEXCAN = 53, /*!< Group number for FlexCAN status codes. */ + kStatusGroup_LTC = 54, /*!< Group number for LTC status codes. */ + kStatusGroup_FLEXIO_CAMERA = 55, /*!< Group number for FLEXIO CAMERA status codes. */ + kStatusGroup_LPC_SPI = 56, /*!< Group number for LPC_SPI status codes. */ + kStatusGroup_LPC_USART = 57, /*!< Group number for LPC_USART status codes. */ + kStatusGroup_DMIC = 58, /*!< Group number for DMIC status codes. */ + kStatusGroup_SDIF = 59, /*!< Group number for SDIF status codes.*/ + kStatusGroup_SPIFI = 60, /*!< Group number for SPIFI status codes. */ + kStatusGroup_OTP = 61, /*!< Group number for OTP status codes. */ + kStatusGroup_MCAN = 62, /*!< Group number for MCAN status codes. */ + kStatusGroup_CAAM = 63, /*!< Group number for CAAM status codes. */ + kStatusGroup_ECSPI = 64, /*!< Group number for ECSPI status codes. */ + kStatusGroup_USDHC = 65, /*!< Group number for USDHC status codes.*/ + kStatusGroup_LPC_I2C = 66, /*!< Group number for LPC_I2C status codes.*/ + kStatusGroup_DCP = 67, /*!< Group number for DCP status codes.*/ + kStatusGroup_MSCAN = 68, /*!< Group number for MSCAN status codes.*/ + kStatusGroup_ESAI = 69, /*!< Group number for ESAI status codes. */ + kStatusGroup_FLEXSPI = 70, /*!< Group number for FLEXSPI status codes. */ + kStatusGroup_MMDC = 71, /*!< Group number for MMDC status codes. */ + kStatusGroup_MICFIL = 72, /*!< Group number for MIC status codes. */ + kStatusGroup_SDMA = 73, /*!< Group number for SDMA status codes. */ + kStatusGroup_ICS = 74, /*!< Group number for ICS status codes. */ + kStatusGroup_SPDIF = 75, /*!< Group number for SPDIF status codes. */ + kStatusGroup_NOTIFIER = 98, /*!< Group number for NOTIFIER status codes. */ + kStatusGroup_DebugConsole = 99, /*!< Group number for debug console status codes. */ + kStatusGroup_SEMC = 100, /*!< Group number for SEMC status codes. */ + kStatusGroup_ApplicationRangeStart = 101, /*!< Starting number for application groups. */ +}; + +/*! @brief Generic status return codes. */ +enum _generic_status +{ + kStatus_Success = MAKE_STATUS(kStatusGroup_Generic, 0), + kStatus_Fail = MAKE_STATUS(kStatusGroup_Generic, 1), + kStatus_ReadOnly = MAKE_STATUS(kStatusGroup_Generic, 2), + kStatus_OutOfRange = MAKE_STATUS(kStatusGroup_Generic, 3), + kStatus_InvalidArgument = MAKE_STATUS(kStatusGroup_Generic, 4), + kStatus_Timeout = MAKE_STATUS(kStatusGroup_Generic, 5), + kStatus_NoTransferInProgress = MAKE_STATUS(kStatusGroup_Generic, 6), +}; + +/*! @brief Type used for all status and error return values. */ +typedef int32_t status_t; + +/* + * The fsl_clock.h is included here because it needs MAKE_VERSION/MAKE_STATUS/status_t + * defined in previous of this file. + */ +#include "fsl_clock.h" + +/* + * Chip level peripheral reset API, for MCUs that implement peripheral reset control external to a peripheral + */ +#if ((defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0)) || \ + (defined(FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT) && (FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT > 0))) +#include "fsl_reset.h" +#endif + +/*! @name Min/max macros */ +/* @{ */ +#if !defined(MIN) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#endif + +#if !defined(MAX) +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#endif +/* @} */ + +/*! @brief Computes the number of elements in an array. */ +#if !defined(ARRAY_SIZE) +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#endif + +/*! @name UINT16_MAX/UINT32_MAX value */ +/* @{ */ +#if !defined(UINT16_MAX) +#define UINT16_MAX ((uint16_t)-1) +#endif + +#if !defined(UINT32_MAX) +#define UINT32_MAX ((uint32_t)-1) +#endif +/* @} */ + +/*! @name Timer utilities */ +/* @{ */ +/*! Macro to convert a microsecond period to raw count value */ +#define USEC_TO_COUNT(us, clockFreqInHz) (uint64_t)((uint64_t)us * clockFreqInHz / 1000000U) +/*! Macro to convert a raw count value to microsecond */ +#define COUNT_TO_USEC(count, clockFreqInHz) (uint64_t)((uint64_t)count * 1000000U / clockFreqInHz) + +/*! Macro to convert a millisecond period to raw count value */ +#define MSEC_TO_COUNT(ms, clockFreqInHz) (uint64_t)((uint64_t)ms * clockFreqInHz / 1000U) +/*! Macro to convert a raw count value to millisecond */ +#define COUNT_TO_MSEC(count, clockFreqInHz) (uint64_t)((uint64_t)count * 1000U / clockFreqInHz) +/* @} */ + +/*! @name Alignment variable definition macros */ +/* @{ */ +#if (defined(__ICCARM__)) +/** + * Workaround to disable MISRA C message suppress warnings for IAR compiler. + * http://supp.iar.com/Support/?note=24725 + */ +_Pragma("diag_suppress=Pm120") +#define SDK_PRAGMA(x) _Pragma(#x) + _Pragma("diag_error=Pm120") +/*! Macro to define a variable with alignbytes alignment */ +#define SDK_ALIGN(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var +/*! Macro to define a variable with L1 d-cache line size alignment */ +#if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) +#define SDK_L1DCACHE_ALIGN(var) SDK_PRAGMA(data_alignment = FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) var +#endif +/*! Macro to define a variable with L2 cache line size alignment */ +#if defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) +#define SDK_L2CACHE_ALIGN(var) SDK_PRAGMA(data_alignment = FSL_FEATURE_L2CACHE_LINESIZE_BYTE) var +#endif +#elif defined(__ARMCC_VERSION) +/*! Macro to define a variable with alignbytes alignment */ +#define SDK_ALIGN(var, alignbytes) __align(alignbytes) var +/*! Macro to define a variable with L1 d-cache line size alignment */ +#if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) +#define SDK_L1DCACHE_ALIGN(var) __align(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) var +#endif +/*! Macro to define a variable with L2 cache line size alignment */ +#if defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) +#define SDK_L2CACHE_ALIGN(var) __align(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) var +#endif +#elif defined(__GNUC__) +/*! Macro to define a variable with alignbytes alignment */ +#define SDK_ALIGN(var, alignbytes) var __attribute__((aligned(alignbytes))) +/*! Macro to define a variable with L1 d-cache line size alignment */ +#if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) +#define SDK_L1DCACHE_ALIGN(var) var __attribute__((aligned(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE))) +#endif +/*! Macro to define a variable with L2 cache line size alignment */ +#if defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) +#define SDK_L2CACHE_ALIGN(var) var __attribute__((aligned(FSL_FEATURE_L2CACHE_LINESIZE_BYTE))) +#endif +#else +#error Toolchain not supported +#define SDK_ALIGN(var, alignbytes) var +#if defined(FSL_FEATURE_L1DCACHE_LINESIZE_BYTE) +#define SDK_L1DCACHE_ALIGN(var) var +#endif +#if defined(FSL_FEATURE_L2CACHE_LINESIZE_BYTE) +#define SDK_L2CACHE_ALIGN(var) var +#endif +#endif + +/*! Macro to change a value to a given size aligned value */ +#define SDK_SIZEALIGN(var, alignbytes) \ + ((unsigned int)((var) + ((alignbytes)-1)) & (unsigned int)(~(unsigned int)((alignbytes)-1))) +/* @} */ + +/*! @name Non-cacheable region definition macros */ +/* For initialized non-zero non-cacheable variables, please using "AT_NONCACHEABLE_SECTION_INIT(var) ={xx};" or + * "AT_NONCACHEABLE_SECTION_ALIGN_INIT(var) ={xx};" in your projects to define them, for zero-inited non-cacheable variables, + * please using "AT_NONCACHEABLE_SECTION(var);" or "AT_NONCACHEABLE_SECTION_ALIGN(var);" to define them, these zero-inited variables + * will be initialized to zero in system startup. + */ +/* @{ */ +#if (defined(__ICCARM__)) +#if defined(FSL_FEATURE_L1ICACHE_LINESIZE_BYTE) +#define AT_NONCACHEABLE_SECTION(var) var @"NonCacheable" +#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var @"NonCacheable" +#define AT_NONCACHEABLE_SECTION_INIT(var) var @"NonCacheable.init" +#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var @"NonCacheable.init" +#else +#define AT_NONCACHEABLE_SECTION(var) var +#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var +#define AT_NONCACHEABLE_SECTION_INIT(var) var +#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) SDK_PRAGMA(data_alignment = alignbytes) var +#endif +#elif(defined(__ARMCC_VERSION)) +#if defined(FSL_FEATURE_L1ICACHE_LINESIZE_BYTE) +#define AT_NONCACHEABLE_SECTION(var) __attribute__((section("NonCacheable"), zero_init)) var +#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) \ + __attribute__((section("NonCacheable"), zero_init)) __align(alignbytes) var +#define AT_NONCACHEABLE_SECTION_INIT(var) __attribute__((section("NonCacheable.init"))) var +#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) \ + __attribute__((section("NonCacheable.init"))) __align(alignbytes) var +#else +#define AT_NONCACHEABLE_SECTION(var) var +#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) __align(alignbytes) var +#define AT_NONCACHEABLE_SECTION_INIT(var) var +#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) __align(alignbytes) var +#endif +#elif(defined(__GNUC__)) +/* For GCC, when the non-cacheable section is required, please define "__STARTUP_INITIALIZE_NONCACHEDATA" + * in your projects to make sure the non-cacheable section variables will be initialized in system startup. + */ +#if defined(FSL_FEATURE_L1ICACHE_LINESIZE_BYTE) +#define AT_NONCACHEABLE_SECTION_INIT(var) __attribute__((section("NonCacheable.init"))) var +#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) \ + __attribute__((section("NonCacheable.init"))) var __attribute__((aligned(alignbytes))) +#define AT_NONCACHEABLE_SECTION(var) __attribute__((section("NonCacheable,\"aw\",%nobits @"))) var +#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) \ + __attribute__((section("NonCacheable,\"aw\",%nobits @"))) var __attribute__((aligned(alignbytes))) +#else +#define AT_NONCACHEABLE_SECTION(var) var +#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) var __attribute__((aligned(alignbytes))) +#define AT_NONCACHEABLE_SECTION_INIT(var) var +#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) var __attribute__((aligned(alignbytes))) +#endif +#else +#error Toolchain not supported. +#define AT_NONCACHEABLE_SECTION(var) var +#define AT_NONCACHEABLE_SECTION_ALIGN(var, alignbytes) var +#define AT_NONCACHEABLE_SECTION_INIT(var) var +#define AT_NONCACHEABLE_SECTION_ALIGN_INIT(var, alignbytes) var +#endif +/* @} */ + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) + extern "C" +{ +#endif + + /*! + * @brief Enable specific interrupt. + * + * Enable LEVEL1 interrupt. For some devices, there might be multiple interrupt + * levels. For example, there are NVIC and intmux. Here the interrupts connected + * to NVIC are the LEVEL1 interrupts, because they are routed to the core directly. + * The interrupts connected to intmux are the LEVEL2 interrupts, they are routed + * to NVIC first then routed to core. + * + * This function only enables the LEVEL1 interrupts. The number of LEVEL1 interrupts + * is indicated by the feature macro FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS. + * + * @param interrupt The IRQ number. + * @retval kStatus_Success Interrupt enabled successfully + * @retval kStatus_Fail Failed to enable the interrupt + */ + static inline status_t EnableIRQ(IRQn_Type interrupt) + { + if (NotAvail_IRQn == interrupt) + { + return kStatus_Fail; + } + +#if defined(FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS) && (FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS > 0) + if (interrupt >= FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS) + { + return kStatus_Fail; + } +#endif + +#if defined(__GIC_PRIO_BITS) + GIC_EnableIRQ(interrupt); +#else + NVIC_EnableIRQ(interrupt); +#endif + return kStatus_Success; + } + + /*! + * @brief Disable specific interrupt. + * + * Disable LEVEL1 interrupt. For some devices, there might be multiple interrupt + * levels. For example, there are NVIC and intmux. Here the interrupts connected + * to NVIC are the LEVEL1 interrupts, because they are routed to the core directly. + * The interrupts connected to intmux are the LEVEL2 interrupts, they are routed + * to NVIC first then routed to core. + * + * This function only disables the LEVEL1 interrupts. The number of LEVEL1 interrupts + * is indicated by the feature macro FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS. + * + * @param interrupt The IRQ number. + * @retval kStatus_Success Interrupt disabled successfully + * @retval kStatus_Fail Failed to disable the interrupt + */ + static inline status_t DisableIRQ(IRQn_Type interrupt) + { + if (NotAvail_IRQn == interrupt) + { + return kStatus_Fail; + } + +#if defined(FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS) && (FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS > 0) + if (interrupt >= FSL_FEATURE_NUMBER_OF_LEVEL1_INT_VECTORS) + { + return kStatus_Fail; + } +#endif + +#if defined(__GIC_PRIO_BITS) + GIC_DisableIRQ(interrupt); +#else + NVIC_DisableIRQ(interrupt); +#endif + return kStatus_Success; + } + + /*! + * @brief Disable the global IRQ + * + * Disable the global interrupt and return the current primask register. User is required to provided the primask + * register for the EnableGlobalIRQ(). + * + * @return Current primask value. + */ + static inline uint32_t DisableGlobalIRQ(void) + { +#if defined(CPSR_I_Msk) + uint32_t cpsr = __get_CPSR() & CPSR_I_Msk; + + __disable_irq(); + + return cpsr; +#else + uint32_t regPrimask = __get_PRIMASK(); + + __disable_irq(); + + return regPrimask; +#endif + } + + /*! + * @brief Enaable the global IRQ + * + * Set the primask register with the provided primask value but not just enable the primask. The idea is for the + * convinience of integration of RTOS. some RTOS get its own management mechanism of primask. User is required to + * use the EnableGlobalIRQ() and DisableGlobalIRQ() in pair. + * + * @param primask value of primask register to be restored. The primask value is supposed to be provided by the + * DisableGlobalIRQ(). + */ + static inline void EnableGlobalIRQ(uint32_t primask) + { +#if defined(CPSR_I_Msk) + __set_CPSR((__get_CPSR() & ~CPSR_I_Msk) | primask); +#else + __set_PRIMASK(primask); +#endif + } + +#if defined(ENABLE_RAM_VECTOR_TABLE) + /*! + * @brief install IRQ handler + * + * @param irq IRQ number + * @param irqHandler IRQ handler address + * @return The old IRQ handler address + */ + uint32_t InstallIRQHandler(IRQn_Type irq, uint32_t irqHandler); +#endif /* ENABLE_RAM_VECTOR_TABLE. */ + +#if (defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0)) + /*! + * @brief Enable specific interrupt for wake-up from deep-sleep mode. + * + * Enable the interrupt for wake-up from deep sleep mode. + * Some interrupts are typically used in sleep mode only and will not occur during + * deep-sleep mode because relevant clocks are stopped. However, it is possible to enable + * those clocks (significantly increasing power consumption in the reduced power mode), + * making these wake-ups possible. + * + * @note This function also enables the interrupt in the NVIC (EnableIRQ() is called internally). + * + * @param interrupt The IRQ number. + */ + void EnableDeepSleepIRQ(IRQn_Type interrupt); + + /*! + * @brief Disable specific interrupt for wake-up from deep-sleep mode. + * + * Disable the interrupt for wake-up from deep sleep mode. + * Some interrupts are typically used in sleep mode only and will not occur during + * deep-sleep mode because relevant clocks are stopped. However, it is possible to enable + * those clocks (significantly increasing power consumption in the reduced power mode), + * making these wake-ups possible. + * + * @note This function also disables the interrupt in the NVIC (DisableIRQ() is called internally). + * + * @param interrupt The IRQ number. + */ + void DisableDeepSleepIRQ(IRQn_Type interrupt); +#endif /* FSL_FEATURE_SOC_SYSCON_COUNT */ + +#if defined(__cplusplus) +} +#endif + +/*! @} */ + +#endif /* _FSL_COMMON_H_ */ diff --git a/platform/mcu/lpc54102/drivers/fsl_crc.c b/platform/mcu/lpc54102/drivers/fsl_crc.c new file mode 100644 index 0000000000..e413222dec --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_crc.c @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2015-2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "fsl_crc.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +#if defined(CRC_DRIVER_USE_CRC16_CCITT_FALSE_AS_DEFAULT) && CRC_DRIVER_USE_CRC16_CCITT_FALSE_AS_DEFAULT +/* @brief Default user configuration structure for CRC-CCITT */ +#define CRC_DRIVER_DEFAULT_POLYNOMIAL kCRC_Polynomial_CRC_CCITT +/*< CRC-CCIT polynomial x^16 + x^12 + x^5 + x^0 */ +#define CRC_DRIVER_DEFAULT_REVERSE_IN false +/*< Default is no bit reverse */ +#define CRC_DRIVER_DEFAULT_COMPLEMENT_IN false +/*< Default is without complement of written data */ +#define CRC_DRIVER_DEFAULT_REVERSE_OUT false +/*< Default is no bit reverse */ +#define CRC_DRIVER_DEFAULT_COMPLEMENT_OUT false +/*< Default is without complement of CRC data register read data */ +#define CRC_DRIVER_DEFAULT_SEED 0xFFFFU +/*< Default initial checksum */ +#endif /* CRC_DRIVER_USE_CRC16_CCITT_FALSE_AS_DEFAULT */ + +/******************************************************************************* + * Code + ******************************************************************************/ + +void CRC_Init(CRC_Type *base, const crc_config_t *config) +{ +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* enable clock to CRC */ + CLOCK_EnableClock(kCLOCK_Crc); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + + /* configure CRC module and write the seed */ + base->MODE = 0 | CRC_MODE_CRC_POLY(config->polynomial) | CRC_MODE_BIT_RVS_WR(config->reverseIn) | + CRC_MODE_CMPL_WR(config->complementIn) | CRC_MODE_BIT_RVS_SUM(config->reverseOut) | + CRC_MODE_CMPL_SUM(config->complementOut); + base->SEED = config->seed; +} + +void CRC_GetDefaultConfig(crc_config_t *config) +{ + static const crc_config_t default_config = {CRC_DRIVER_DEFAULT_POLYNOMIAL, CRC_DRIVER_DEFAULT_REVERSE_IN, + CRC_DRIVER_DEFAULT_COMPLEMENT_IN, CRC_DRIVER_DEFAULT_REVERSE_OUT, + CRC_DRIVER_DEFAULT_COMPLEMENT_OUT, CRC_DRIVER_DEFAULT_SEED}; + + *config = default_config; +} + +void CRC_Reset(CRC_Type *base) +{ + crc_config_t config; + CRC_GetDefaultConfig(&config); + CRC_Init(base, &config); +} + +void CRC_GetConfig(CRC_Type *base, crc_config_t *config) +{ + /* extract CRC mode settings */ + uint32_t mode = base->MODE; + config->polynomial = (crc_polynomial_t)((mode & CRC_MODE_CRC_POLY_MASK) >> CRC_MODE_CRC_POLY_SHIFT); + config->reverseIn = (bool)(mode & CRC_MODE_BIT_RVS_WR_MASK); + config->complementIn = (bool)(mode & CRC_MODE_CMPL_WR_MASK); + config->reverseOut = (bool)(mode & CRC_MODE_BIT_RVS_SUM_MASK); + config->complementOut = (bool)(mode & CRC_MODE_CMPL_SUM_MASK); + + /* reset CRC sum bit reverse and 1's complement setting, so its value can be used as a seed */ + base->MODE = mode & ~((1U << CRC_MODE_BIT_RVS_SUM_SHIFT) | (1U << CRC_MODE_CMPL_SUM_SHIFT)); + + /* now we can obtain intermediate raw CRC sum value */ + config->seed = base->SUM; + + /* restore original CRC sum bit reverse and 1's complement setting */ + base->MODE = mode; +} + +void CRC_WriteData(CRC_Type *base, const uint8_t *data, size_t dataSize) +{ + const uint32_t *data32; + + /* 8-bit reads and writes till source address is aligned 4 bytes */ + while ((dataSize) && ((uint32_t)data & 3U)) + { + *((__O uint8_t *)&(base->WR_DATA)) = *data; + data++; + dataSize--; + } + + /* use 32-bit reads and writes as long as possible */ + data32 = (const uint32_t *)data; + while (dataSize >= sizeof(uint32_t)) + { + *((__O uint32_t *)&(base->WR_DATA)) = *data32; + data32++; + dataSize -= sizeof(uint32_t); + } + + data = (const uint8_t *)data32; + + /* 8-bit reads and writes till end of data buffer */ + while (dataSize) + { + *((__O uint8_t *)&(base->WR_DATA)) = *data; + data++; + dataSize--; + } +} diff --git a/platform/mcu/lpc54102/drivers/fsl_crc.h b/platform/mcu/lpc54102/drivers/fsl_crc.h new file mode 100644 index 0000000000..5b1338d9b1 --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_crc.h @@ -0,0 +1,203 @@ +/* + * Copyright (c) 2015-2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_CRC_H_ +#define _FSL_CRC_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup crc + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief CRC driver version. Version 2.0.1. + * + * Current version: 2.0.1 + * + * Change log: + * - Version 2.0.0 + * - initial version + * - Version 2.0.1 + * - add explicit type cast when writing to WR_DATA + */ +#define FSL_CRC_DRIVER_VERSION (MAKE_VERSION(2, 0, 1)) +/*@}*/ + +#ifndef CRC_DRIVER_CUSTOM_DEFAULTS +/*! @brief Default configuration structure filled by CRC_GetDefaultConfig(). Uses CRC-16/CCITT-FALSE as default. */ +#define CRC_DRIVER_USE_CRC16_CCITT_FALSE_AS_DEFAULT 1 +#endif + +/*! @brief CRC polynomials to use. */ +typedef enum _crc_polynomial +{ + kCRC_Polynomial_CRC_CCITT = 0U, /*!< x^16+x^12+x^5+1 */ + kCRC_Polynomial_CRC_16 = 1U, /*!< x^16+x^15+x^2+1 */ + kCRC_Polynomial_CRC_32 = 2U /*!< x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1 */ +} crc_polynomial_t; + +/*! +* @brief CRC protocol configuration. +* +* This structure holds the configuration for the CRC protocol. +* +*/ +typedef struct _crc_config +{ + crc_polynomial_t polynomial; /*!< CRC polynomial. */ + bool reverseIn; /*!< Reverse bits on input. */ + bool complementIn; /*!< Perform 1's complement on input. */ + bool reverseOut; /*!< Reverse bits on output. */ + bool complementOut; /*!< Perform 1's complement on output. */ + uint32_t seed; /*!< Starting checksum value. */ +} crc_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Enables and configures the CRC peripheral module. + * + * This functions enables the CRC peripheral clock in the LPC SYSCON block. + * It also configures the CRC engine and starts checksum computation by writing the seed. + * + * @param base CRC peripheral address. + * @param config CRC module configuration structure. + */ +void CRC_Init(CRC_Type *base, const crc_config_t *config); + +/*! + * @brief Disables the CRC peripheral module. + * + * This functions disables the CRC peripheral clock in the LPC SYSCON block. + * + * @param base CRC peripheral address. + */ +static inline void CRC_Deinit(CRC_Type *base) +{ +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* disable clock to CRC */ + CLOCK_DisableClock(kCLOCK_Crc); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +/*! + * @brief resets CRC peripheral module. + * + * @param base CRC peripheral address. + */ +void CRC_Reset(CRC_Type *base); + +/*! + * @brief Loads default values to CRC protocol configuration structure. + * + * Loads default values to CRC protocol configuration structure. The default values are: + * @code + * config->polynomial = kCRC_Polynomial_CRC_CCITT; + * config->reverseIn = false; + * config->complementIn = false; + * config->reverseOut = false; + * config->complementOut = false; + * config->seed = 0xFFFFU; + * @endcode + * + * @param config CRC protocol configuration structure + */ +void CRC_GetDefaultConfig(crc_config_t *config); + +/*! + * @brief Loads actual values configured in CRC peripheral to CRC protocol configuration structure. + * + * The values, including seed, can be used to resume CRC calculation later. + + * @param base CRC peripheral address. + * @param config CRC protocol configuration structure + */ +void CRC_GetConfig(CRC_Type *base, crc_config_t *config); + +/*! + * @brief Writes data to the CRC module. + * + * Writes input data buffer bytes to CRC data register. + * + * @param base CRC peripheral address. + * @param data Input data stream, MSByte in data[0]. + * @param dataSize Size of the input data buffer in bytes. + */ +void CRC_WriteData(CRC_Type *base, const uint8_t *data, size_t dataSize); + +/*! + * @brief Reads 32-bit checksum from the CRC module. + * + * Reads CRC data register. + * + * @param base CRC peripheral address. + * @return final 32-bit checksum, after configured bit reverse and complement operations. + */ +static inline uint32_t CRC_Get32bitResult(CRC_Type *base) +{ + return base->SUM; +} + +/*! + * @brief Reads 16-bit checksum from the CRC module. + * + * Reads CRC data register. + * + * @param base CRC peripheral address. + * @return final 16-bit checksum, after configured bit reverse and complement operations. + */ +static inline uint16_t CRC_Get16bitResult(CRC_Type *base) +{ + return (uint16_t)base->SUM; +} + +#if defined(__cplusplus) +} +#endif + +/*! + *@} + */ + +#endif /* _FSL_CRC_H_ */ diff --git a/platform/mcu/lpc54102/drivers/fsl_ctimer.c b/platform/mcu/lpc54102/drivers/fsl_ctimer.c new file mode 100644 index 0000000000..09583bdc11 --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_ctimer.c @@ -0,0 +1,386 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_ctimer.h" + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +/*! + * @brief Gets the instance from the base address + * + * @param base Ctimer peripheral base address + * + * @return The Timer instance + */ +static uint32_t CTIMER_GetInstance(CTIMER_Type *base); + +/******************************************************************************* + * Variables + ******************************************************************************/ +/*! @brief Pointers to Timer bases for each instance. */ +static CTIMER_Type *const s_ctimerBases[] = CTIMER_BASE_PTRS; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +/*! @brief Pointers to Timer clocks for each instance. */ +static const clock_ip_name_t s_ctimerClocks[] = CTIMER_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +/*! @brief Pointers to Timer resets for each instance. */ +static const reset_ip_name_t s_ctimerResets[] = CTIMER_RSTS; + +/*! @brief Pointers real ISRs installed by drivers for each instance. */ +static ctimer_callback_t *s_ctimerCallback[FSL_FEATURE_SOC_CTIMER_COUNT] = {0}; + +/*! @brief Callback type installed by drivers for each instance. */ +static ctimer_callback_type_t ctimerCallbackType[FSL_FEATURE_SOC_CTIMER_COUNT] = {kCTIMER_SingleCallback}; + +/*! @brief Array to map timer instance to IRQ number. */ +static const IRQn_Type s_ctimerIRQ[] = CTIMER_IRQS; + +/******************************************************************************* + * Code + ******************************************************************************/ +static uint32_t CTIMER_GetInstance(CTIMER_Type *base) +{ + uint32_t instance; + uint32_t ctimerArrayCount = (sizeof(s_ctimerBases) / sizeof(s_ctimerBases[0])); + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < ctimerArrayCount; instance++) + { + if (s_ctimerBases[instance] == base) + { + break; + } + } + + assert(instance < ctimerArrayCount); + + return instance; +} + +void CTIMER_Init(CTIMER_Type *base, const ctimer_config_t *config) +{ + assert(config); + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Enable the timer clock*/ + CLOCK_EnableClock(s_ctimerClocks[CTIMER_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + + /* Reset the module */ + RESET_PeripheralReset(s_ctimerResets[CTIMER_GetInstance(base)]); + + /* Setup the cimer mode and count select */ + base->CTCR = CTIMER_CTCR_CTMODE(config->mode) | CTIMER_CTCR_CINSEL(config->input); + + /* Setup the timer prescale value */ + base->PR = CTIMER_PR_PRVAL(config->prescale); +} + +void CTIMER_Deinit(CTIMER_Type *base) +{ + uint32_t index = CTIMER_GetInstance(base); + /* Stop the timer */ + base->TCR &= ~CTIMER_TCR_CEN_MASK; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Disable the timer clock*/ + CLOCK_DisableClock(s_ctimerClocks[index]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + + /* Disable IRQ at NVIC Level */ + DisableIRQ(s_ctimerIRQ[index]); +} + +void CTIMER_GetDefaultConfig(ctimer_config_t *config) +{ + assert(config); + + /* Run as a timer */ + config->mode = kCTIMER_TimerMode; + /* This field is ignored when mode is timer */ + config->input = kCTIMER_Capture_0; + /* Timer counter is incremented on every APB bus clock */ + config->prescale = 0; +} + +status_t CTIMER_SetupPwm(CTIMER_Type *base, + ctimer_match_t matchChannel, + uint8_t dutyCyclePercent, + uint32_t pwmFreq_Hz, + uint32_t srcClock_Hz, + bool enableInt) +{ + assert(pwmFreq_Hz > 0); + + uint32_t reg; + uint32_t period, pulsePeriod = 0; + uint32_t timerClock = srcClock_Hz / (base->PR + 1); + uint32_t index = CTIMER_GetInstance(base); + + if (matchChannel == kCTIMER_Match_3) + { + return kStatus_Fail; + } + + /* Enable PWM mode on the channel */ + base->PWMC |= (1U << matchChannel); + + /* Clear the stop, reset and interrupt bits for this channel */ + reg = base->MCR; + reg &= ~((CTIMER_MCR_MR0R_MASK | CTIMER_MCR_MR0S_MASK | CTIMER_MCR_MR0I_MASK) << (matchChannel * 3)); + + /* If call back function is valid then enable match interrupt for the channel */ + if (enableInt) + { + reg |= (CTIMER_MCR_MR0I_MASK << (CTIMER_MCR_MR0I_SHIFT + (matchChannel * 3))); + } + + /* Reset the counter when match on channel 3 */ + reg |= CTIMER_MCR_MR3R_MASK; + + base->MCR = reg; + + /* Calculate PWM period match value */ + period = (timerClock / pwmFreq_Hz) - 1; + + /* Calculate pulse width match value */ + if (dutyCyclePercent == 0) + { + pulsePeriod = period + 1; + } + else + { + pulsePeriod = (period * (100 - dutyCyclePercent)) / 100; + } + + /* Match on channel 3 will define the PWM period */ + base->MR[kCTIMER_Match_3] = period; + + /* This will define the PWM pulse period */ + base->MR[matchChannel] = pulsePeriod; + /* Clear status flags */ + CTIMER_ClearStatusFlags(base, CTIMER_IR_MR0INT_MASK << matchChannel); + /* If call back function is valid then enable interrupt and update the call back function */ + if (enableInt) + { + EnableIRQ(s_ctimerIRQ[index]); + } + + return kStatus_Success; +} + +void CTIMER_UpdatePwmDutycycle(CTIMER_Type *base, ctimer_match_t matchChannel, uint8_t dutyCyclePercent) +{ + uint32_t pulsePeriod = 0, period; + + /* Match channel 3 defines the PWM period */ + period = base->MR[kCTIMER_Match_3]; + + /* Calculate pulse width match value */ + pulsePeriod = (period * dutyCyclePercent) / 100; + + /* For 0% dutycyle, make pulse period greater than period so the event will never occur */ + if (dutyCyclePercent == 0) + { + pulsePeriod = period + 1; + } + else + { + pulsePeriod = (period * (100 - dutyCyclePercent)) / 100; + } + + /* Update dutycycle */ + base->MR[matchChannel] = pulsePeriod; +} + +void CTIMER_SetupMatch(CTIMER_Type *base, ctimer_match_t matchChannel, const ctimer_match_config_t *config) +{ + uint32_t reg; + uint32_t index = CTIMER_GetInstance(base); + + /* Set the counter operation when a match on this channel occurs */ + reg = base->MCR; + reg &= ~((CTIMER_MCR_MR0R_MASK | CTIMER_MCR_MR0S_MASK | CTIMER_MCR_MR0I_MASK) << (matchChannel * 3)); + reg |= (uint32_t)((uint32_t)(config->enableCounterReset) << (CTIMER_MCR_MR0R_SHIFT + (matchChannel * 3))); + reg |= (uint32_t)((uint32_t)(config->enableCounterStop) << (CTIMER_MCR_MR0S_SHIFT + (matchChannel * 3))); + reg |= (uint32_t)((uint32_t)(config->enableInterrupt) << (CTIMER_MCR_MR0I_SHIFT + (matchChannel * 3))); + base->MCR = reg; + + reg = base->EMR; + /* Set the match output operation when a match on this channel occurs */ + reg &= ~(CTIMER_EMR_EMC0_MASK << (matchChannel * 2)); + reg |= (uint32_t)config->outControl << (CTIMER_EMR_EMC0_SHIFT + (matchChannel * 2)); + + /* Set the initial state of the EM bit/output */ + reg &= ~(CTIMER_EMR_EM0_MASK << matchChannel); + reg |= (uint32_t)config->outPinInitState << matchChannel; + base->EMR = reg; + + /* Set the match value */ + base->MR[matchChannel] = config->matchValue; + /* Clear status flags */ + CTIMER_ClearStatusFlags(base, CTIMER_IR_MR0INT_MASK << matchChannel); + /* If interrupt is enabled then enable interrupt and update the call back function */ + if (config->enableInterrupt) + { + EnableIRQ(s_ctimerIRQ[index]); + } +} + +void CTIMER_SetupCapture(CTIMER_Type *base, + ctimer_capture_channel_t capture, + ctimer_capture_edge_t edge, + bool enableInt) +{ + uint32_t reg = base->CCR; + uint32_t index = CTIMER_GetInstance(base); + + /* Set the capture edge */ + reg &= ~((CTIMER_CCR_CAP0RE_MASK | CTIMER_CCR_CAP0FE_MASK | CTIMER_CCR_CAP0I_MASK) << (capture * 3)); + reg |= (uint32_t)edge << (CTIMER_CCR_CAP0RE_SHIFT + (capture * 3)); + /* Clear status flags */ + CTIMER_ClearStatusFlags(base, (kCTIMER_Capture0Flag << capture)); + /* If call back function is valid then enable capture interrupt for the channel and update the call back function */ + if (enableInt) + { + reg |= CTIMER_CCR_CAP0I_MASK << (capture * 3); + EnableIRQ(s_ctimerIRQ[index]); + } + base->CCR = reg; +} + +void CTIMER_RegisterCallBack(CTIMER_Type *base, ctimer_callback_t *cb_func, ctimer_callback_type_t cb_type) +{ + uint32_t index = CTIMER_GetInstance(base); + s_ctimerCallback[index] = cb_func; + ctimerCallbackType[index] = cb_type; +} + +void CTIMER_GenericIRQHandler(uint32_t index) +{ + uint32_t int_stat, i, mask; + /* Get Interrupt status flags */ + int_stat = CTIMER_GetStatusFlags(s_ctimerBases[index]); + /* Clear the status flags that were set */ + CTIMER_ClearStatusFlags(s_ctimerBases[index], int_stat); + if (ctimerCallbackType[index] == kCTIMER_SingleCallback) + { + if (s_ctimerCallback[index][0]) + { + s_ctimerCallback[index][0](int_stat); + } + } + else + { +#if defined(FSL_FEATURE_CTIMER_HAS_IR_CR3INT) && FSL_FEATURE_CTIMER_HAS_IR_CR3INT + for (i = 0; i <= CTIMER_IR_CR3INT_SHIFT; i++) +#else + for (i = 0; i <= CTIMER_IR_CR2INT_SHIFT; i++) +#endif /* FSL_FEATURE_CTIMER_HAS_IR_CR3INT */ + { + mask = 0x01 << i; + /* For each status flag bit that was set call the callback function if it is valid */ + if ((int_stat & mask) && (s_ctimerCallback[index][i])) + { + s_ctimerCallback[index][i](int_stat); + } + } + } + /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +/* IRQ handler functions overloading weak symbols in the startup */ +#if defined(CTIMER0) +void CTIMER0_DriverIRQHandler(void) +{ + CTIMER_GenericIRQHandler(0); + /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif + +#if defined(CTIMER1) +void CTIMER1_DriverIRQHandler(void) +{ + CTIMER_GenericIRQHandler(1); + /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif + +#if defined(CTIMER2) +void CTIMER2_DriverIRQHandler(void) +{ + CTIMER_GenericIRQHandler(2); + /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif + +#if defined(CTIMER3) +void CTIMER3_DriverIRQHandler(void) +{ + CTIMER_GenericIRQHandler(3); + /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif + +#if defined(CTIMER4) +void CTIMER4_DriverIRQHandler(void) +{ + CTIMER_GenericIRQHandler(4); + /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +#endif diff --git a/platform/mcu/lpc54102/drivers/fsl_ctimer.h b/platform/mcu/lpc54102/drivers/fsl_ctimer.h new file mode 100644 index 0000000000..118fc4c8c9 --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_ctimer.h @@ -0,0 +1,451 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_CTIMER_H_ +#define _FSL_CTIMER_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup ctimer + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +#define FSL_CTIMER_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0 */ +/*@}*/ + +/*! @brief List of Timer capture channels */ +typedef enum _ctimer_capture_channel +{ + kCTIMER_Capture_0 = 0U, /*!< Timer capture channel 0 */ + kCTIMER_Capture_1, /*!< Timer capture channel 1 */ + kCTIMER_Capture_2, /*!< Timer capture channel 2 */ +#if defined(FSL_FEATURE_CTIMER_HAS_CCR_CAP3) && FSL_FEATURE_CTIMER_HAS_CCR_CAP3 + kCTIMER_Capture_3 /*!< Timer capture channel 3 */ +#endif /* FSL_FEATURE_CTIMER_HAS_IR_CR3INT */ +} ctimer_capture_channel_t; + +/*! @brief List of capture edge options */ +typedef enum _ctimer_capture_edge +{ + kCTIMER_Capture_RiseEdge = 1U, /*!< Capture on rising edge */ + kCTIMER_Capture_FallEdge = 2U, /*!< Capture on falling edge */ + kCTIMER_Capture_BothEdge = 3U, /*!< Capture on rising and falling edge */ +} ctimer_capture_edge_t; + +/*! @brief List of Timer match registers */ +typedef enum _ctimer_match +{ + kCTIMER_Match_0 = 0U, /*!< Timer match register 0 */ + kCTIMER_Match_1, /*!< Timer match register 1 */ + kCTIMER_Match_2, /*!< Timer match register 2 */ + kCTIMER_Match_3 /*!< Timer match register 3 */ +} ctimer_match_t; + +/*! @brief List of output control options */ +typedef enum _ctimer_match_output_control +{ + kCTIMER_Output_NoAction = 0U, /*!< No action is taken */ + kCTIMER_Output_Clear, /*!< Clear the EM bit/output to 0 */ + kCTIMER_Output_Set, /*!< Set the EM bit/output to 1 */ + kCTIMER_Output_Toggle /*!< Toggle the EM bit/output */ +} ctimer_match_output_control_t; + +/*! @brief List of Timer modes */ +typedef enum _ctimer_timer_mode +{ + kCTIMER_TimerMode = 0U, /* TC is incremented every rising APB bus clock edge */ + kCTIMER_IncreaseOnRiseEdge, /* TC is incremented on rising edge of input signal */ + kCTIMER_IncreaseOnFallEdge, /* TC is incremented on falling edge of input signal */ + kCTIMER_IncreaseOnBothEdge /* TC is incremented on both edges of input signal */ +} ctimer_timer_mode_t; + +/*! @brief List of Timer interrupts */ +typedef enum _ctimer_interrupt_enable +{ + kCTIMER_Match0InterruptEnable = CTIMER_MCR_MR0I_MASK, /*!< Match 0 interrupt */ + kCTIMER_Match1InterruptEnable = CTIMER_MCR_MR1I_MASK, /*!< Match 1 interrupt */ + kCTIMER_Match2InterruptEnable = CTIMER_MCR_MR2I_MASK, /*!< Match 2 interrupt */ + kCTIMER_Match3InterruptEnable = CTIMER_MCR_MR3I_MASK, /*!< Match 3 interrupt */ + kCTIMER_Capture0InterruptEnable = CTIMER_CCR_CAP0I_MASK, /*!< Capture 0 interrupt */ + kCTIMER_Capture1InterruptEnable = CTIMER_CCR_CAP1I_MASK, /*!< Capture 1 interrupt */ + kCTIMER_Capture2InterruptEnable = CTIMER_CCR_CAP2I_MASK, /*!< Capture 2 interrupt */ +#if defined(FSL_FEATURE_CTIMER_HAS_CCR_CAP3) && FSL_FEATURE_CTIMER_HAS_CCR_CAP3 + kCTIMER_Capture3InterruptEnable = CTIMER_CCR_CAP3I_MASK, /*!< Capture 3 interrupt */ +#endif /* FSL_FEATURE_CTIMER_HAS_CCR_CAP3 */ +} ctimer_interrupt_enable_t; + +/*! @brief List of Timer flags */ +typedef enum _ctimer_status_flags +{ + kCTIMER_Match0Flag = CTIMER_IR_MR0INT_MASK, /*!< Match 0 interrupt flag */ + kCTIMER_Match1Flag = CTIMER_IR_MR1INT_MASK, /*!< Match 1 interrupt flag */ + kCTIMER_Match2Flag = CTIMER_IR_MR2INT_MASK, /*!< Match 2 interrupt flag */ + kCTIMER_Match3Flag = CTIMER_IR_MR3INT_MASK, /*!< Match 3 interrupt flag */ + kCTIMER_Capture0Flag = CTIMER_IR_CR0INT_MASK, /*!< Capture 0 interrupt flag */ + kCTIMER_Capture1Flag = CTIMER_IR_CR1INT_MASK, /*!< Capture 1 interrupt flag */ + kCTIMER_Capture2Flag = CTIMER_IR_CR2INT_MASK, /*!< Capture 2 interrupt flag */ +#if defined(FSL_FEATURE_CTIMER_HAS_IR_CR3INT) && FSL_FEATURE_CTIMER_HAS_IR_CR3INT + kCTIMER_Capture3Flag = CTIMER_IR_CR3INT_MASK, /*!< Capture 3 interrupt flag */ +#endif /* FSL_FEATURE_CTIMER_HAS_IR_CR3INT */ +} ctimer_status_flags_t; + +typedef void (*ctimer_callback_t)(uint32_t flags); + +/*! @brief Callback type when registering for a callback. When registering a callback + * an array of function pointers is passed the size could be 1 or 8, the callback + * type will tell that. + */ +typedef enum +{ + kCTIMER_SingleCallback, /*!< Single Callback type where there is only one callback for the timer. + based on the status flags different channels needs to be handled differently */ + kCTIMER_MultipleCallback /*!< Multiple Callback type where there can be 8 valid callbacks, one per channel. + for both match/capture */ +} ctimer_callback_type_t; + +/*! + * @brief Match configuration + * + * This structure holds the configuration settings for each match register. + */ +typedef struct _ctimer_match_config +{ + uint32_t matchValue; /*!< This is stored in the match register */ + bool enableCounterReset; /*!< true: Match will reset the counter + false: Match will not reser the counter */ + bool enableCounterStop; /*!< true: Match will stop the counter + false: Match will not stop the counter */ + ctimer_match_output_control_t outControl; /*!< Action to be taken on a match on the EM bit/output */ + bool outPinInitState; /*!< Initial value of the EM bit/output */ + bool enableInterrupt; /*!< true: Generate interrupt upon match + false: Do not generate interrupt on match */ + +} ctimer_match_config_t; + +/*! + * @brief Timer configuration structure + * + * This structure holds the configuration settings for the Timer peripheral. To initialize this + * structure to reasonable defaults, call the CTIMER_GetDefaultConfig() function and pass a + * pointer to the configuration structure instance. + * + * The configuration structure can be made constant so as to reside in flash. + */ +typedef struct _ctimer_config +{ + ctimer_timer_mode_t mode; /*!< Timer mode */ + ctimer_capture_channel_t input; /*!< Input channel to increment the timer, used only in timer + modes that rely on this input signal to increment TC */ + uint32_t prescale; /*!< Prescale value */ +} ctimer_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name Initialization and deinitialization + * @{ + */ + +/*! + * @brief Ungates the clock and configures the peripheral for basic operation. + * + * @note This API should be called at the beginning of the application before using the driver. + * + * @param base Ctimer peripheral base address + * @param config Pointer to the user configuration structure. + */ +void CTIMER_Init(CTIMER_Type *base, const ctimer_config_t *config); + +/*! + * @brief Gates the timer clock. + * + * @param base Ctimer peripheral base address + */ +void CTIMER_Deinit(CTIMER_Type *base); + +/*! + * @brief Fills in the timers configuration structure with the default settings. + * + * The default values are: + * @code + * config->mode = kCTIMER_TimerMode; + * config->input = kCTIMER_Capture_0; + * config->prescale = 0; + * @endcode + * @param config Pointer to the user configuration structure. + */ +void CTIMER_GetDefaultConfig(ctimer_config_t *config); + +/*! @}*/ + +/*! + * @name PWM setup operations + * @{ + */ + +/*! + * @brief Configures the PWM signal parameters. + * + * Enables PWM mode on the match channel passed in and will then setup the match value + * and other match parameters to generate a PWM signal. + * This function will assign match channel 3 to set the PWM cycle. + * + * @note When setting PWM output from multiple output pins, all should use the same PWM + * frequency + * + * @param base Ctimer peripheral base address + * @param matchChannel Match pin to be used to output the PWM signal + * @param dutyCyclePercent PWM pulse width; the value should be between 0 to 100 + * @param pwmFreq_Hz PWM signal frequency in Hz + * @param srcClock_Hz Timer counter clock in Hz + * @param enableInt Enable interrupt when the timer value reaches the match value of the PWM pulse, + * if it is 0 then no interrupt is generated + * + * @return kStatus_Success on success + * kStatus_Fail If matchChannel passed in is 3; this channel is reserved to set the PWM cycle + */ +status_t CTIMER_SetupPwm(CTIMER_Type *base, + ctimer_match_t matchChannel, + uint8_t dutyCyclePercent, + uint32_t pwmFreq_Hz, + uint32_t srcClock_Hz, + bool enableInt); + +/*! + * @brief Updates the duty cycle of an active PWM signal. + * + * @param base Ctimer peripheral base address + * @param matchChannel Match pin to be used to output the PWM signal + * @param dutyCyclePercent New PWM pulse width; the value should be between 0 to 100 + */ +void CTIMER_UpdatePwmDutycycle(CTIMER_Type *base, ctimer_match_t matchChannel, uint8_t dutyCyclePercent); + +/*! @}*/ + +/*! + * @brief Setup the match register. + * + * User configuration is used to setup the match value and action to be taken when a match occurs. + * + * @param base Ctimer peripheral base address + * @param matchChannel Match register to configure + * @param config Pointer to the match configuration structure + */ +void CTIMER_SetupMatch(CTIMER_Type *base, ctimer_match_t matchChannel, const ctimer_match_config_t *config); + +/*! + * @brief Setup the capture. + * + * @param base Ctimer peripheral base address + * @param capture Capture channel to configure + * @param edge Edge on the channel that will trigger a capture + * @param enableInt Flag to enable channel interrupts, if enabled then the registered call back + * is called upon capture + */ +void CTIMER_SetupCapture(CTIMER_Type *base, + ctimer_capture_channel_t capture, + ctimer_capture_edge_t edge, + bool enableInt); + +/*! + * @brief Register callback. + * + * @param base Ctimer peripheral base address + * @param cb_func callback function + * @param cb_type callback function type, singular or multiple + */ +void CTIMER_RegisterCallBack(CTIMER_Type *base, ctimer_callback_t *cb_func, ctimer_callback_type_t cb_type); + +/*! + * @name Interrupt Interface + * @{ + */ + +/*! + * @brief Enables the selected Timer interrupts. + * + * @param base Ctimer peripheral base address + * @param mask The interrupts to enable. This is a logical OR of members of the + * enumeration ::ctimer_interrupt_enable_t + */ +static inline void CTIMER_EnableInterrupts(CTIMER_Type *base, uint32_t mask) +{ + /* Enable match interrupts */ + base->MCR |= mask & (CTIMER_MCR_MR0I_MASK | CTIMER_MCR_MR1I_MASK | CTIMER_MCR_MR2I_MASK | CTIMER_MCR_MR3I_MASK); + + /* Enable capture interrupts */ + base->CCR |= mask & (CTIMER_CCR_CAP0I_MASK | CTIMER_CCR_CAP1I_MASK | CTIMER_CCR_CAP2I_MASK +#if defined(FSL_FEATURE_CTIMER_HAS_CCR_CAP3) && FSL_FEATURE_CTIMER_HAS_CCR_CAP3 + | CTIMER_CCR_CAP3I_MASK +#endif /* FSL_FEATURE_CTIMER_HAS_CCR_CAP3 */ + ); +} + +/*! + * @brief Disables the selected Timer interrupts. + * + * @param base Ctimer peripheral base address + * @param mask The interrupts to enable. This is a logical OR of members of the + * enumeration ::ctimer_interrupt_enable_t + */ +static inline void CTIMER_DisableInterrupts(CTIMER_Type *base, uint32_t mask) +{ + /* Disable match interrupts */ + base->MCR &= ~(mask & (CTIMER_MCR_MR0I_MASK | CTIMER_MCR_MR1I_MASK | CTIMER_MCR_MR2I_MASK | CTIMER_MCR_MR3I_MASK)); + + /* Disable capture interrupts */ + base->CCR &= ~(mask & (CTIMER_CCR_CAP0I_MASK | CTIMER_CCR_CAP1I_MASK | CTIMER_CCR_CAP2I_MASK +#if defined(FSL_FEATURE_CTIMER_HAS_CCR_CAP3) && FSL_FEATURE_CTIMER_HAS_CCR_CAP3 + | CTIMER_CCR_CAP3I_MASK +#endif /* FSL_FEATURE_CTIMER_HAS_CCR_CAP3 */ + )); +} + +/*! + * @brief Gets the enabled Timer interrupts. + * + * @param base Ctimer peripheral base address + * + * @return The enabled interrupts. This is the logical OR of members of the + * enumeration ::ctimer_interrupt_enable_t + */ +static inline uint32_t CTIMER_GetEnabledInterrupts(CTIMER_Type *base) +{ + uint32_t enabledIntrs = 0; + + /* Get all the match interrupts enabled */ + enabledIntrs = + base->MCR & (CTIMER_MCR_MR0I_MASK | CTIMER_MCR_MR1I_MASK | CTIMER_MCR_MR2I_MASK | CTIMER_MCR_MR3I_MASK); + + /* Get all the capture interrupts enabled */ + enabledIntrs |= base->CCR & (CTIMER_CCR_CAP0I_MASK | CTIMER_CCR_CAP1I_MASK | CTIMER_CCR_CAP2I_MASK +#if defined(FSL_FEATURE_CTIMER_HAS_CCR_CAP3) && FSL_FEATURE_CTIMER_HAS_CCR_CAP3 + | CTIMER_CCR_CAP3I_MASK +#endif /* FSL_FEATURE_CTIMER_HAS_CCR_CAP3 */ + ); + + return enabledIntrs; +} + +/*! @}*/ + +/*! + * @name Status Interface + * @{ + */ + +/*! + * @brief Gets the Timer status flags. + * + * @param base Ctimer peripheral base address + * + * @return The status flags. This is the logical OR of members of the + * enumeration ::ctimer_status_flags_t + */ +static inline uint32_t CTIMER_GetStatusFlags(CTIMER_Type *base) +{ + return base->IR; +} + +/*! + * @brief Clears the Timer status flags. + * + * @param base Ctimer peripheral base address + * @param mask The status flags to clear. This is a logical OR of members of the + * enumeration ::ctimer_status_flags_t + */ +static inline void CTIMER_ClearStatusFlags(CTIMER_Type *base, uint32_t mask) +{ + base->IR = mask; +} + +/*! @}*/ + +/*! + * @name Counter Start and Stop + * @{ + */ + +/*! + * @brief Starts the Timer counter. + * + * @param base Ctimer peripheral base address + */ +static inline void CTIMER_StartTimer(CTIMER_Type *base) +{ + base->TCR |= CTIMER_TCR_CEN_MASK; +} + +/*! + * @brief Stops the Timer counter. + * + * @param base Ctimer peripheral base address + */ +static inline void CTIMER_StopTimer(CTIMER_Type *base) +{ + base->TCR &= ~CTIMER_TCR_CEN_MASK; +} + +/*! @}*/ + +/*! + * @brief Reset the counter. + * + * The timer counter and prescale counter are reset on the next positive edge of the APB clock. + * + * @param base Ctimer peripheral base address + */ +static inline void CTIMER_Reset(CTIMER_Type *base) +{ + base->TCR |= CTIMER_TCR_CRST_MASK; + base->TCR &= ~CTIMER_TCR_CRST_MASK; +} + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_CTIMER_H_ */ diff --git a/platform/mcu/lpc54102/drivers/fsl_dma.c b/platform/mcu/lpc54102/drivers/fsl_dma.c new file mode 100644 index 0000000000..37ad0c28c2 --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_dma.c @@ -0,0 +1,415 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_dma.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/*! + * @brief Get instance number for DMA. + * + * @param base DMA peripheral base address. + */ +static int32_t DMA_GetInstance(DMA_Type *base); + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/*! @brief Array to map DMA instance number to base pointer. */ +static DMA_Type *const s_dmaBases[] = DMA_BASE_PTRS; + +/*! @brief Array to map DMA instance number to IRQ number. */ +static const IRQn_Type s_dmaIRQNumber[] = DMA_IRQS; + +/*! @brief Pointers to transfer handle for each DMA channel. */ +static dma_handle_t *s_DMAHandle[FSL_FEATURE_DMA_NUMBER_OF_CHANNELS]; + +/*! @brief Static table of descriptors */ +#if defined(__ICCARM__) +#pragma data_alignment = 512 +dma_descriptor_t s_dma_descriptor_table[FSL_FEATURE_DMA_NUMBER_OF_CHANNELS] = {0}; +#elif defined(__CC_ARM) +__attribute__((aligned(512))) dma_descriptor_t s_dma_descriptor_table[FSL_FEATURE_DMA_NUMBER_OF_CHANNELS] = {0}; +#elif defined(__GNUC__) +__attribute__((aligned(512))) dma_descriptor_t s_dma_descriptor_table[FSL_FEATURE_DMA_NUMBER_OF_CHANNELS] = {0}; +#endif + +/******************************************************************************* + * Code + ******************************************************************************/ + +static int32_t DMA_GetInstance(DMA_Type *base) +{ + int32_t instance; + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < ARRAY_SIZE(s_dmaBases); instance++) + { + if (s_dmaBases[instance] == base) + { + break; + } + } + assert(instance < ARRAY_SIZE(s_dmaBases)); + return instance < ARRAY_SIZE(s_dmaBases) ? instance : -1; +} + +void DMA_Init(DMA_Type *base) +{ +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* enable dma clock gate */ + CLOCK_EnableClock(kCLOCK_Dma); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + /* set descriptor table */ + base->SRAMBASE = (uint32_t)s_dma_descriptor_table; + /* enable dma peripheral */ + base->CTRL |= DMA_CTRL_ENABLE_MASK; +} + +void DMA_Deinit(DMA_Type *base) +{ +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Disable DMA peripheral */ + base->CTRL &= ~(DMA_CTRL_ENABLE_MASK); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +void DMA_ConfigureChannelTrigger(DMA_Type *base, uint32_t channel, dma_channel_trigger_t *trigger) +{ + assert((channel < FSL_FEATURE_DMA_NUMBER_OF_CHANNELS) && (NULL != trigger)); + + uint32_t tmp = (DMA_CHANNEL_CFG_HWTRIGEN_MASK | DMA_CHANNEL_CFG_TRIGPOL_MASK | DMA_CHANNEL_CFG_TRIGTYPE_MASK | + DMA_CHANNEL_CFG_TRIGBURST_MASK | DMA_CHANNEL_CFG_BURSTPOWER_MASK | + DMA_CHANNEL_CFG_SRCBURSTWRAP_MASK | DMA_CHANNEL_CFG_DSTBURSTWRAP_MASK); + tmp = base->CHANNEL[channel].CFG & (~tmp); + tmp |= (uint32_t)(trigger->type) | (uint32_t)(trigger->burst) | (uint32_t)(trigger->wrap); + base->CHANNEL[channel].CFG = tmp; +} + +/*! + * @brief Gets the remaining bytes of the current DMA descriptor transfer. + * + * @param base DMA peripheral base address. + * @param channel DMA channel number. + * @return The number of bytes which have not been transferred yet. + */ +uint32_t DMA_GetRemainingBytes(DMA_Type *base, uint32_t channel) +{ + assert(channel < FSL_FEATURE_DMA_NUMBER_OF_CHANNELS); + + /* NOTE: when descriptors are chained, ACTIVE bit is set for whole chain. It makes + * impossible to distinguish between: + * - transfer finishes (represented by value '0x3FF') + * - and remaining 1024 bytes to transfer (value 0x3FF) + * for all descriptor in chain, except the last one. + * If you decide to use this function, please use 1023 transfers as maximal value */ + + /* Channel not active (transfer finished) and value is 0x3FF - nothing to transfer */ + if ((!(base->COMMON[DMA_CHANNEL_GROUP(channel)].ACTIVE & (1U << (DMA_CHANNEL_INDEX(channel))))) && + (0x3FF == ((base->CHANNEL[channel].XFERCFG & DMA_CHANNEL_XFERCFG_XFERCOUNT_MASK) >> + DMA_CHANNEL_XFERCFG_XFERCOUNT_SHIFT))) + { + return 0; + } + + return base->CHANNEL[channel].XFERCFG + 1; +} + +static void DMA_SetupDescriptor( + dma_descriptor_t *desc, uint32_t xfercfg, void *srcEndAddr, void *dstEndAddr, void *nextDesc) +{ + desc->xfercfg = xfercfg; + desc->srcEndAddr = srcEndAddr; + desc->dstEndAddr = dstEndAddr; + desc->linkToNextDesc = nextDesc; +} + +/* Verify and convert dma_xfercfg_t to XFERCFG register */ +static void DMA_SetupXferCFG(dma_xfercfg_t *xfercfg, uint32_t *xfercfg_addr) +{ + assert(xfercfg != NULL); + /* check source increment */ + assert((xfercfg->srcInc == 0) || (xfercfg->srcInc == 1) || (xfercfg->srcInc == 2) || (xfercfg->srcInc == 4)); + /* check destination increment */ + assert((xfercfg->dstInc == 0) || (xfercfg->dstInc == 1) || (xfercfg->dstInc == 2) || (xfercfg->dstInc == 4)); + /* check data width */ + assert((xfercfg->byteWidth == 1) || (xfercfg->byteWidth == 2) || (xfercfg->byteWidth == 4)); + /* check transfer count */ + assert(xfercfg->transferCount <= DMA_MAX_TRANSFER_COUNT); + + uint32_t xfer = 0, tmp; + /* set valid flag - descriptor is ready now */ + xfer |= DMA_CHANNEL_XFERCFG_CFGVALID(xfercfg->valid ? 1 : 0); + /* set reload - allow link to next descriptor */ + xfer |= DMA_CHANNEL_XFERCFG_RELOAD(xfercfg->reload ? 1 : 0); + /* set swtrig flag - start transfer */ + xfer |= DMA_CHANNEL_XFERCFG_SWTRIG(xfercfg->swtrig ? 1 : 0); + /* set transfer count */ + xfer |= DMA_CHANNEL_XFERCFG_CLRTRIG(xfercfg->clrtrig ? 1 : 0); + /* set INTA */ + xfer |= DMA_CHANNEL_XFERCFG_SETINTA(xfercfg->intA ? 1 : 0); + /* set INTB */ + xfer |= DMA_CHANNEL_XFERCFG_SETINTB(xfercfg->intB ? 1 : 0); + /* set data width */ + tmp = xfercfg->byteWidth == 4 ? 2 : xfercfg->byteWidth - 1; + xfer |= DMA_CHANNEL_XFERCFG_WIDTH(tmp); + /* set source increment value */ + tmp = xfercfg->srcInc == 4 ? 3 : xfercfg->srcInc; + xfer |= DMA_CHANNEL_XFERCFG_SRCINC(tmp); + /* set destination increment value */ + tmp = xfercfg->dstInc == 4 ? 3 : xfercfg->dstInc; + xfer |= DMA_CHANNEL_XFERCFG_DSTINC(tmp); + /* set transfer count */ + xfer |= DMA_CHANNEL_XFERCFG_XFERCOUNT(xfercfg->transferCount - 1); + + /* store xferCFG */ + *xfercfg_addr = xfer; +} + +void DMA_CreateDescriptor(dma_descriptor_t *desc, dma_xfercfg_t *xfercfg, void *srcAddr, void *dstAddr, void *nextDesc) +{ + uint32_t xfercfg_reg = 0; + + assert((NULL != desc) && (0 == (uint32_t)desc % 16) && (NULL != xfercfg)); + assert((NULL != srcAddr) && (0 == (uint32_t)srcAddr % xfercfg->byteWidth)); + assert((NULL != dstAddr) && (0 == (uint32_t)dstAddr % xfercfg->byteWidth)); + assert((NULL == nextDesc) || (0 == (uint32_t)nextDesc % 16)); + + /* Setup channel configuration */ + DMA_SetupXferCFG(xfercfg, &xfercfg_reg); + + /* Set descriptor structure */ + DMA_SetupDescriptor( + desc, xfercfg_reg, (uint8_t *)srcAddr + (xfercfg->srcInc * xfercfg->byteWidth * (xfercfg->transferCount - 1)), + (uint8_t *)dstAddr + (xfercfg->dstInc * xfercfg->byteWidth * (xfercfg->transferCount - 1)), nextDesc); +} + +void DMA_AbortTransfer(dma_handle_t *handle) +{ + assert(NULL != handle); + + DMA_DisableChannel(handle->base, handle->channel); + while (handle->base->COMMON[DMA_CHANNEL_GROUP(handle->channel)].BUSY & (1U << DMA_CHANNEL_INDEX(handle->channel))) + { + } + handle->base->COMMON[DMA_CHANNEL_GROUP(handle->channel)].ABORT |= 1U << DMA_CHANNEL_INDEX(handle->channel); + DMA_EnableChannel(handle->base, handle->channel); +} + +void DMA_CreateHandle(dma_handle_t *handle, DMA_Type *base, uint32_t channel) +{ + int32_t dmaInstance; + assert((NULL != handle) && (channel < FSL_FEATURE_DMA_NUMBER_OF_CHANNELS)); + + /* base address is invalid DMA instance */ + dmaInstance = DMA_GetInstance(base); + + memset(handle, 0, sizeof(*handle)); + handle->base = base; + handle->channel = channel; + s_DMAHandle[channel] = handle; + /* Enable NVIC interrupt */ + EnableIRQ(s_dmaIRQNumber[dmaInstance]); +} + +void DMA_SetCallback(dma_handle_t *handle, dma_callback callback, void *userData) +{ + assert(handle != NULL); + + handle->callback = callback; + handle->userData = userData; +} + +void DMA_PrepareTransfer(dma_transfer_config_t *config, + void *srcAddr, + void *dstAddr, + uint32_t byteWidth, + uint32_t transferBytes, + dma_transfer_type_t type, + void *nextDesc) +{ + uint32_t xfer_count; + assert((NULL != config) && (NULL != srcAddr) && (NULL != dstAddr)); + assert((byteWidth == 1) || (byteWidth == 2) || (byteWidth == 4)); + + /* check max */ + xfer_count = transferBytes / byteWidth; + assert((xfer_count <= DMA_MAX_TRANSFER_COUNT) && (0 == transferBytes % byteWidth)); + + memset(config, 0, sizeof(*config)); + switch (type) + { + case kDMA_MemoryToMemory: + config->xfercfg.srcInc = 1; + config->xfercfg.dstInc = 1; + config->isPeriph = false; + break; + case kDMA_PeripheralToMemory: + /* Peripheral register - source doesn't increment */ + config->xfercfg.srcInc = 0; + config->xfercfg.dstInc = 1; + config->isPeriph = true; + break; + case kDMA_MemoryToPeripheral: + /* Peripheral register - destination doesn't increment */ + config->xfercfg.srcInc = 1; + config->xfercfg.dstInc = 0; + config->isPeriph = true; + break; + case kDMA_StaticToStatic: + config->xfercfg.srcInc = 0; + config->xfercfg.dstInc = 0; + config->isPeriph = true; + break; + default: + return; + } + + config->dstAddr = (uint8_t *)dstAddr; + config->srcAddr = (uint8_t *)srcAddr; + config->nextDesc = (uint8_t *)nextDesc; + config->xfercfg.transferCount = xfer_count; + config->xfercfg.byteWidth = byteWidth; + config->xfercfg.intA = true; + config->xfercfg.reload = nextDesc != NULL; + config->xfercfg.valid = true; +} + +status_t DMA_SubmitTransfer(dma_handle_t *handle, dma_transfer_config_t *config) +{ + assert((NULL != handle) && (NULL != config)); + + /* Previous transfer has not finished */ + if (DMA_ChannelIsActive(handle->base, handle->channel)) + { + return kStatus_DMA_Busy; + } + + /* enable/disable peripheral request */ + if (config->isPeriph) + { + DMA_EnableChannelPeriphRq(handle->base, handle->channel); + } + else + { + DMA_DisableChannelPeriphRq(handle->base, handle->channel); + } + + DMA_CreateDescriptor(&s_dma_descriptor_table[handle->channel], &config->xfercfg, config->srcAddr, config->dstAddr, + config->nextDesc); + + return kStatus_Success; +} + +void DMA_StartTransfer(dma_handle_t *handle) +{ + assert(NULL != handle); + + /* Enable channel interrupt */ + handle->base->COMMON[DMA_CHANNEL_GROUP(handle->channel)].INTENSET |= 1U << DMA_CHANNEL_INDEX(handle->channel); + + /* If HW trigger is enabled - disable SW trigger */ + if (handle->base->CHANNEL[handle->channel].CFG & DMA_CHANNEL_CFG_HWTRIGEN_MASK) + { + s_dma_descriptor_table[handle->channel].xfercfg &= ~(DMA_CHANNEL_XFERCFG_SWTRIG_MASK); + } + /* Otherwise enable SW trigger */ + else + { + s_dma_descriptor_table[handle->channel].xfercfg |= DMA_CHANNEL_XFERCFG_SWTRIG_MASK; + } + + /* Set channel XFERCFG register according first channel descriptor. */ + handle->base->CHANNEL[handle->channel].XFERCFG = s_dma_descriptor_table[handle->channel].xfercfg; + /* At this moment, the channel ACTIVE bit is set and application cannot modify + * or start another transfer using this channel. Channel ACTIVE bit is cleared by + * 'AbortTransfer' function or when the transfer finishes */ +} + +void DMA0_DriverIRQHandler(void) +{ + dma_handle_t *handle; + int32_t channel_group; + int32_t channel_index; + + /* Find channels that have completed transfer */ + for (int i = 0; i < FSL_FEATURE_DMA_NUMBER_OF_CHANNELS; i++) + { + handle = s_DMAHandle[i]; + /* Handle is not present */ + if (NULL == handle) + { + continue; + } + channel_group = DMA_CHANNEL_GROUP(handle->channel); + channel_index = DMA_CHANNEL_INDEX(handle->channel); + /* Channel uses INTA flag */ + if (handle->base->COMMON[channel_group].INTA & (1U << channel_index)) + { + /* Clear INTA flag */ + handle->base->COMMON[channel_group].INTA = 1U << channel_index; + if (handle->callback) + { + (handle->callback)(handle, handle->userData, true, kDMA_IntA); + } + } + /* Channel uses INTB flag */ + if (handle->base->COMMON[channel_group].INTB & (1U << channel_index)) + { + /* Clear INTB flag */ + handle->base->COMMON[channel_group].INTB = 1U << channel_index; + if (handle->callback) + { + (handle->callback)(handle, handle->userData, true, kDMA_IntB); + } + } + /* Error flag */ + if (handle->base->COMMON[channel_group].ERRINT & (1U << channel_index)) + { + /* Clear error flag */ + handle->base->COMMON[channel_group].ERRINT = 1U << channel_index; + if (handle->callback) + { + (handle->callback)(handle, handle->userData, false, kDMA_IntError); + } + } + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} diff --git a/platform/mcu/lpc54102/drivers/fsl_dma.h b/platform/mcu/lpc54102/drivers/fsl_dma.h new file mode 100644 index 0000000000..4b93f0285c --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_dma.h @@ -0,0 +1,493 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_DMA_H_ +#define _FSL_DMA_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup dma + * @{ + */ + +/*! @file */ +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief DMA driver version */ +#define FSL_DMA_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0. */ +/*@}*/ + +#define DMA_MAX_TRANSFER_COUNT 0x400 + +/* Channel group consists of 32 channels. channel_group = (channel / 32) */ +#define DMA_CHANNEL_GROUP(channel) (((uint8_t)channel) >> 5U) +/* Channel index in channel group. channel_index = (channel % 32) */ +#define DMA_CHANNEL_INDEX(channel) (((uint8_t)channel) & 0x1F) + +/*! @brief DMA descriptor structure */ +typedef struct _dma_descriptor +{ + uint32_t xfercfg; /*!< Transfer configuration */ + void *srcEndAddr; /*!< Last source address of DMA transfer */ + void *dstEndAddr; /*!< Last destination address of DMA transfer */ + void *linkToNextDesc; /*!< Address of next DMA descriptor in chain */ +} dma_descriptor_t; + +/*! @brief DMA transfer configuration */ +typedef struct _dma_xfercfg +{ + bool valid; /*!< Descriptor is ready to transfer */ + bool reload; /*!< Reload channel configuration register after + current descriptor is exhausted */ + bool swtrig; /*!< Perform software trigger. Transfer if fired + when 'valid' is set */ + bool clrtrig; /*!< Clear trigger */ + bool intA; /*!< Raises IRQ when transfer is done and set IRQA status register flag */ + bool intB; /*!< Raises IRQ when transfer is done and set IRQB status register flag */ + uint8_t byteWidth; /*!< Byte width of data to transfer */ + uint8_t srcInc; /*!< Increment source address by 'srcInc' x 'byteWidth' */ + uint8_t dstInc; /*!< Increment destination address by 'dstInc' x 'byteWidth' */ + uint16_t transferCount; /*!< Number of transfers */ +} dma_xfercfg_t; + +/*! @brief DMA channel priority */ +typedef enum _dma_priority +{ + kDMA_ChannelPriority0 = 0, /*!< Highest channel priority - priority 0 */ + kDMA_ChannelPriority1, /*!< Channel priority 1 */ + kDMA_ChannelPriority2, /*!< Channel priority 2 */ + kDMA_ChannelPriority3, /*!< Channel priority 3 */ + kDMA_ChannelPriority4, /*!< Channel priority 4 */ + kDMA_ChannelPriority5, /*!< Channel priority 5 */ + kDMA_ChannelPriority6, /*!< Channel priority 6 */ + kDMA_ChannelPriority7, /*!< Lowest channel priority - priority 7 */ +} dma_priority_t; + +/*! @brief DMA interrupt flags */ +typedef enum _dma_int +{ + kDMA_IntA, /*!< DMA interrupt flag A */ + kDMA_IntB, /*!< DMA interrupt flag B */ + kDMA_IntError, /*!< DMA interrupt flag error */ +} dma_irq_t; + +/*! @brief DMA trigger type*/ +typedef enum _dma_trigger_type +{ + kDMA_NoTrigger = 0, /*!< Trigger is disabled */ + kDMA_LowLevelTrigger = DMA_CHANNEL_CFG_HWTRIGEN(1) | DMA_CHANNEL_CFG_TRIGTYPE(1), /*!< Low level active trigger */ + kDMA_HighLevelTrigger = DMA_CHANNEL_CFG_HWTRIGEN(1) | DMA_CHANNEL_CFG_TRIGTYPE(1) | + DMA_CHANNEL_CFG_TRIGPOL(1), /*!< High level active trigger */ + kDMA_FallingEdgeTrigger = DMA_CHANNEL_CFG_HWTRIGEN(1), /*!< Falling edge active trigger */ + kDMA_RisingEdgeTrigger = + DMA_CHANNEL_CFG_HWTRIGEN(1) | DMA_CHANNEL_CFG_TRIGPOL(1), /*!< Rising edge active trigger */ +} dma_trigger_type_t; + +/*! @brief DMA trigger burst */ +typedef enum _dma_trigger_burst +{ + kDMA_SingleTransfer = 0, /*!< Single transfer */ + kDMA_LevelBurstTransfer = DMA_CHANNEL_CFG_TRIGBURST(1), /*!< Burst transfer driven by level trigger */ + kDMA_EdgeBurstTransfer1 = DMA_CHANNEL_CFG_TRIGBURST(1), /*!< Perform 1 transfer by edge trigger */ + kDMA_EdgeBurstTransfer2 = + DMA_CHANNEL_CFG_TRIGBURST(1) | DMA_CHANNEL_CFG_BURSTPOWER(1), /*!< Perform 2 transfers by edge trigger */ + kDMA_EdgeBurstTransfer4 = + DMA_CHANNEL_CFG_TRIGBURST(1) | DMA_CHANNEL_CFG_BURSTPOWER(2), /*!< Perform 4 transfers by edge trigger */ + kDMA_EdgeBurstTransfer8 = + DMA_CHANNEL_CFG_TRIGBURST(1) | DMA_CHANNEL_CFG_BURSTPOWER(3), /*!< Perform 8 transfers by edge trigger */ + kDMA_EdgeBurstTransfer16 = + DMA_CHANNEL_CFG_TRIGBURST(1) | DMA_CHANNEL_CFG_BURSTPOWER(4), /*!< Perform 16 transfers by edge trigger */ + kDMA_EdgeBurstTransfer32 = + DMA_CHANNEL_CFG_TRIGBURST(1) | DMA_CHANNEL_CFG_BURSTPOWER(5), /*!< Perform 32 transfers by edge trigger */ + kDMA_EdgeBurstTransfer64 = + DMA_CHANNEL_CFG_TRIGBURST(1) | DMA_CHANNEL_CFG_BURSTPOWER(6), /*!< Perform 64 transfers by edge trigger */ + kDMA_EdgeBurstTransfer128 = + DMA_CHANNEL_CFG_TRIGBURST(1) | DMA_CHANNEL_CFG_BURSTPOWER(7), /*!< Perform 128 transfers by edge trigger */ + kDMA_EdgeBurstTransfer256 = + DMA_CHANNEL_CFG_TRIGBURST(1) | DMA_CHANNEL_CFG_BURSTPOWER(8), /*!< Perform 256 transfers by edge trigger */ + kDMA_EdgeBurstTransfer512 = + DMA_CHANNEL_CFG_TRIGBURST(1) | DMA_CHANNEL_CFG_BURSTPOWER(9), /*!< Perform 512 transfers by edge trigger */ + kDMA_EdgeBurstTransfer1024 = + DMA_CHANNEL_CFG_TRIGBURST(1) | DMA_CHANNEL_CFG_BURSTPOWER(10), /*!< Perform 1024 transfers by edge trigger */ +} dma_trigger_burst_t; + +/*! @brief DMA burst wrapping */ +typedef enum _dma_burst_wrap +{ + kDMA_NoWrap = 0, /*!< Wrapping is disabled */ + kDMA_SrcWrap = DMA_CHANNEL_CFG_SRCBURSTWRAP(1), /*!< Wrapping is enabled for source */ + kDMA_DstWrap = DMA_CHANNEL_CFG_DSTBURSTWRAP(1), /*!< Wrapping is enabled for destination */ + kDMA_SrcAndDstWrap = DMA_CHANNEL_CFG_SRCBURSTWRAP(1) | + DMA_CHANNEL_CFG_DSTBURSTWRAP(1), /*!< Wrapping is enabled for source and destination */ +} dma_burst_wrap_t; + +/*! @brief DMA transfer type */ +typedef enum _dma_transfer_type +{ + kDMA_MemoryToMemory = 0x0U, /*!< Transfer from memory to memory (increment source and destination) */ + kDMA_PeripheralToMemory, /*!< Transfer from peripheral to memory (increment only destination) */ + kDMA_MemoryToPeripheral, /*!< Transfer from memory to peripheral (increment only source)*/ + kDMA_StaticToStatic, /*!< Peripheral to static memory (do not increment source or destination) */ +} dma_transfer_type_t; + +/*! @brief DMA channel trigger */ +typedef struct _dma_channel_trigger +{ + dma_trigger_type_t type; /*!< Select hardware trigger as edge triggered or level triggered. */ + dma_trigger_burst_t burst; /*!< Select whether hardware triggers cause a single or burst transfer. */ + dma_burst_wrap_t wrap; /*!< Select wrap type, source wrap or dest wrap, or both. */ +} dma_channel_trigger_t; + +/*! @brief DMA transfer status */ +enum _dma_transfer_status +{ + kStatus_DMA_Busy = MAKE_STATUS(kStatusGroup_DMA, 0), /*!< Channel is busy and can't handle the + transfer request. */ +}; + +/*! @brief DMA transfer configuration */ +typedef struct _dma_transfer_config +{ + uint8_t *srcAddr; /*!< Source data address */ + uint8_t *dstAddr; /*!< Destination data address */ + uint8_t *nextDesc; /*!< Chain custom descriptor */ + dma_xfercfg_t xfercfg; /*!< Transfer options */ + bool isPeriph; /*!< DMA transfer is driven by peripheral */ +} dma_transfer_config_t; + +/*! @brief Callback for DMA */ +struct _dma_handle; + +/*! @brief Define Callback function for DMA. */ +typedef void (*dma_callback)(struct _dma_handle *handle, void *userData, bool transferDone, uint32_t intmode); + +/*! @brief DMA transfer handle structure */ +typedef struct _dma_handle +{ + dma_callback callback; /*!< Callback function. Invoked when transfer + of descriptor with interrupt flag finishes */ + void *userData; /*!< Callback function parameter */ + DMA_Type *base; /*!< DMA peripheral base address */ + uint8_t channel; /*!< DMA channel number */ +} dma_handle_t; + +/******************************************************************************* + * APIs + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + +/*! + * @name DMA initialization and De-initialization + * @{ + */ + +/*! + * @brief Initializes DMA peripheral. + * + * This function enable the DMA clock, set descriptor table and + * enable DMA peripheral. + * + * @param base DMA peripheral base address. + */ +void DMA_Init(DMA_Type *base); + +/*! + * @brief Deinitializes DMA peripheral. + * + * This function gates the DMA clock. + * + * @param base DMA peripheral base address. + */ +void DMA_Deinit(DMA_Type *base); + +/* @} */ +/*! + * @name DMA Channel Operation + * @{ + */ + +/*! +* @brief Return whether DMA channel is processing transfer +* +* @param base DMA peripheral base address. +* @param channel DMA channel number. +* @return True for active state, false otherwise. +*/ +static inline bool DMA_ChannelIsActive(DMA_Type *base, uint32_t channel) +{ + assert(channel < FSL_FEATURE_DMA_NUMBER_OF_CHANNELS); + return (base->COMMON[DMA_CHANNEL_GROUP(channel)].ACTIVE & (1U << DMA_CHANNEL_INDEX(channel))) ? true : false; +} + +/*! + * @brief Enables the interrupt source for the DMA transfer. + * + * @param base DMA peripheral base address. + * @param channel DMA channel number. + */ +static inline void DMA_EnableChannelInterrupts(DMA_Type *base, uint32_t channel) +{ + assert(channel < FSL_FEATURE_DMA_NUMBER_OF_CHANNELS); + base->COMMON[DMA_CHANNEL_GROUP(channel)].INTENSET |= 1U << DMA_CHANNEL_INDEX(channel); +} + +/*! + * @brief Disables the interrupt source for the DMA transfer. + * + * @param base DMA peripheral base address. + * @param channel DMA channel number. + */ +static inline void DMA_DisableChannelInterrupts(DMA_Type *base, uint32_t channel) +{ + assert(channel < FSL_FEATURE_DMA_NUMBER_OF_CHANNELS); + base->COMMON[DMA_CHANNEL_GROUP(channel)].INTENCLR |= 1U << DMA_CHANNEL_INDEX(channel); +} + +/*! + * @brief Enable DMA channel. + * + * @param base DMA peripheral base address. + * @param channel DMA channel number. + */ +static inline void DMA_EnableChannel(DMA_Type *base, uint32_t channel) +{ + assert(channel < FSL_FEATURE_DMA_NUMBER_OF_CHANNELS); + base->COMMON[DMA_CHANNEL_GROUP(channel)].ENABLESET |= 1U << DMA_CHANNEL_INDEX(channel); +} + +/*! + * @brief Disable DMA channel. + * + * @param base DMA peripheral base address. + * @param channel DMA channel number. + */ +static inline void DMA_DisableChannel(DMA_Type *base, uint32_t channel) +{ + assert(channel < FSL_FEATURE_DMA_NUMBER_OF_CHANNELS); + base->COMMON[DMA_CHANNEL_GROUP(channel)].ENABLECLR |= 1U << DMA_CHANNEL_INDEX(channel); +} + +/*! + * @brief Set PERIPHREQEN of channel configuration register. + * + * @param base DMA peripheral base address. + * @param channel DMA channel number. + */ +static inline void DMA_EnableChannelPeriphRq(DMA_Type *base, uint32_t channel) +{ + assert(channel < FSL_FEATURE_DMA_NUMBER_OF_CHANNELS); + base->CHANNEL[channel].CFG |= DMA_CHANNEL_CFG_PERIPHREQEN_MASK; +} + +/*! + * @brief Get PERIPHREQEN value of channel configuration register. + * + * @param base DMA peripheral base address. + * @param channel DMA channel number. + * @return True for enabled PeriphRq, false for disabled. + */ +static inline void DMA_DisableChannelPeriphRq(DMA_Type *base, uint32_t channel) +{ + assert(channel < FSL_FEATURE_DMA_NUMBER_OF_CHANNELS); + base->CHANNEL[channel].CFG &= ~DMA_CHANNEL_CFG_PERIPHREQEN_MASK; +} + +/*! + * @brief Set trigger settings of DMA channel. + * + * @param base DMA peripheral base address. + * @param channel DMA channel number. + * @param trigger trigger configuration. + */ +void DMA_ConfigureChannelTrigger(DMA_Type *base, uint32_t channel, dma_channel_trigger_t *trigger); + +/*! + * @brief Gets the remaining bytes of the current DMA descriptor transfer. + * + * @param base DMA peripheral base address. + * @param channel DMA channel number. + * @return The number of bytes which have not been transferred yet. + */ +uint32_t DMA_GetRemainingBytes(DMA_Type *base, uint32_t channel); + +/*! + * @brief Set priority of channel configuration register. + * + * @param base DMA peripheral base address. + * @param channel DMA channel number. + * @param priority Channel priority value. + */ +static inline void DMA_SetChannelPriority(DMA_Type *base, uint32_t channel, dma_priority_t priority) +{ + assert(channel < FSL_FEATURE_DMA_NUMBER_OF_CHANNELS); + base->CHANNEL[channel].CFG = + (base->CHANNEL[channel].CFG & (~(DMA_CHANNEL_CFG_CHPRIORITY_MASK))) | DMA_CHANNEL_CFG_CHPRIORITY(priority); +} + +/*! + * @brief Get priority of channel configuration register. + * + * @param base DMA peripheral base address. + * @param channel DMA channel number. + * @return Channel priority value. + */ +static inline dma_priority_t DMA_GetChannelPriority(DMA_Type *base, uint32_t channel) +{ + assert(channel < FSL_FEATURE_DMA_NUMBER_OF_CHANNELS); + return (dma_priority_t)((base->CHANNEL[channel].CFG & DMA_CHANNEL_CFG_CHPRIORITY_MASK) >> + DMA_CHANNEL_CFG_CHPRIORITY_SHIFT); +} + +/*! + * @brief Create application specific DMA descriptor + * to be used in a chain in transfer + * + * @param desc DMA descriptor address. + * @param xfercfg Transfer configuration for DMA descriptor. + * @param srcAddr Address of last item to transmit + * @param dstAddr Address of last item to receive. + * @param nextDesc Address of next descriptor in chain. + */ +void DMA_CreateDescriptor(dma_descriptor_t *desc, dma_xfercfg_t *xfercfg, void *srcAddr, void *dstAddr, void *nextDesc); + +/* @} */ + +/*! + * @name DMA Transactional Operation + * @{ + */ + +/*! + * @brief Abort running transfer by handle. + * + * This function aborts DMA transfer specified by handle. + * + * @param handle DMA handle pointer. + */ +void DMA_AbortTransfer(dma_handle_t *handle); + +/*! + * @brief Creates the DMA handle. + * + * This function is called if using transaction API for DMA. This function + * initializes the internal state of DMA handle. + * + * @param handle DMA handle pointer. The DMA handle stores callback function and + * parameters. + * @param base DMA peripheral base address. + * @param channel DMA channel number. + */ +void DMA_CreateHandle(dma_handle_t *handle, DMA_Type *base, uint32_t channel); + +/*! + * @brief Installs a callback function for the DMA transfer. + * + * This callback is called in DMA IRQ handler. Use the callback to do something after + * the current major loop transfer completes. + * + * @param handle DMA handle pointer. + * @param callback DMA callback function pointer. + * @param userData Parameter for callback function. + */ +void DMA_SetCallback(dma_handle_t *handle, dma_callback callback, void *userData); + +/*! + * @brief Prepares the DMA transfer structure. + * + * This function prepares the transfer configuration structure according to the user input. + * + * @param config The user configuration structure of type dma_transfer_t. + * @param srcAddr DMA transfer source address. + * @param dstAddr DMA transfer destination address. + * @param byteWidth DMA transfer destination address width(bytes). + * @param transferBytes DMA transfer bytes to be transferred. + * @param type DMA transfer type. + * @param nextDesc Chain custom descriptor to transfer. + * @note The data address and the data width must be consistent. For example, if the SRC + * is 4 bytes, so the source address must be 4 bytes aligned, or it shall result in + * source address error(SAE). + */ +void DMA_PrepareTransfer(dma_transfer_config_t *config, + void *srcAddr, + void *dstAddr, + uint32_t byteWidth, + uint32_t transferBytes, + dma_transfer_type_t type, + void *nextDesc); + +/*! + * @brief Submits the DMA transfer request. + * + * This function submits the DMA transfer request according to the transfer configuration structure. + * If the user submits the transfer request repeatedly, this function packs an unprocessed request as + * a TCD and enables scatter/gather feature to process it in the next time. + * + * @param handle DMA handle pointer. + * @param config Pointer to DMA transfer configuration structure. + * @retval kStatus_DMA_Success It means submit transfer request succeed. + * @retval kStatus_DMA_QueueFull It means TCD queue is full. Submit transfer request is not allowed. + * @retval kStatus_DMA_Busy It means the given channel is busy, need to submit request later. + */ +status_t DMA_SubmitTransfer(dma_handle_t *handle, dma_transfer_config_t *config); + +/*! + * @brief DMA start transfer. + * + * This function enables the channel request. User can call this function after submitting the transfer request + * or before submitting the transfer request. + * + * @param handle DMA handle pointer. + */ +void DMA_StartTransfer(dma_handle_t *handle); + +/*! + * @brief DMA IRQ handler for descriptor transfer complete. + * + * This function clears the channel major interrupt flag and call + * the callback function if it is not NULL. + */ +void DMA_HandleIRQ(void); + +/* @} */ + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + +/* @} */ + +#endif /*_FSL_DMA_H_*/ diff --git a/platform/mcu/lpc54102/drivers/fsl_flashiap.c b/platform/mcu/lpc54102/drivers/fsl_flashiap.c new file mode 100644 index 0000000000..862fd2d227 --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_flashiap.c @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_flashiap.h" + +#define HZ_TO_KHZ_DIV 1000 + +/******************************************************************************* + * Code + ******************************************************************************/ + +static status_t translate_iap_status(uint32_t status) +{ + /* Translate IAP return code to sdk status code */ + if (status == kStatus_Success) + { + return status; + } + else + { + return MAKE_STATUS(kStatusGroup_FLASHIAP, status); + } +} + +status_t FLASHIAP_PrepareSectorForWrite(uint32_t startSector, uint32_t endSector) +{ + uint32_t command[5], result[4]; + + command[0] = kIapCmd_FLASHIAP_PrepareSectorforWrite; + command[1] = startSector; + command[2] = endSector; + iap_entry(command, result); + + return translate_iap_status(result[0]); +} + +status_t FLASHIAP_CopyRamToFlash(uint32_t dstAddr, uint32_t *srcAddr, uint32_t numOfBytes, uint32_t systemCoreClock) +{ + uint32_t command[5], result[4]; + + command[0] = kIapCmd_FLASHIAP_CopyRamToFlash; + command[1] = dstAddr; + command[2] = (uint32_t)srcAddr; + command[3] = numOfBytes; + command[4] = systemCoreClock / HZ_TO_KHZ_DIV; + iap_entry(command, result); + + return translate_iap_status(result[0]); +} + +status_t FLASHIAP_EraseSector(uint32_t startSector, uint32_t endSector, uint32_t systemCoreClock) +{ + uint32_t command[5], result[4]; + + command[0] = kIapCmd_FLASHIAP_EraseSector; + command[1] = startSector; + command[2] = endSector; + command[3] = systemCoreClock / HZ_TO_KHZ_DIV; + iap_entry(command, result); + + return translate_iap_status(result[0]); +} + +status_t FLASHIAP_ErasePage(uint32_t startPage, uint32_t endPage, uint32_t systemCoreClock) +{ + uint32_t command[5], result[4]; + + command[0] = kIapCmd_FLASHIAP_ErasePage; + command[1] = startPage; + command[2] = endPage; + command[3] = systemCoreClock / HZ_TO_KHZ_DIV; + iap_entry(command, result); + + return translate_iap_status(result[0]); +} + +status_t FLASHIAP_BlankCheckSector(uint32_t startSector, uint32_t endSector) +{ + uint32_t command[5], result[4]; + + command[0] = kIapCmd_FLASHIAP_BlankCheckSector; + command[1] = startSector; + command[2] = endSector; + iap_entry(command, result); + + return translate_iap_status(result[0]); +} + +status_t FLASHIAP_Compare(uint32_t dstAddr, uint32_t *srcAddr, uint32_t numOfBytes) +{ + uint32_t command[5], result[4]; + + command[0] = kIapCmd_FLASHIAP_Compare; + command[1] = dstAddr; + command[2] = (uint32_t)srcAddr; + command[3] = numOfBytes; + iap_entry(command, result); + + return translate_iap_status(result[0]); +} diff --git a/platform/mcu/lpc54102/drivers/fsl_flashiap.h b/platform/mcu/lpc54102/drivers/fsl_flashiap.h new file mode 100644 index 0000000000..3325ea7ce9 --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_flashiap.h @@ -0,0 +1,264 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_FLASHIAP_H_ +#define _FSL_FLASHIAP_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup flashiap_driver + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +#define FSL_FLASHIAP_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0. */ + /*@}*/ + +/*! + * @brief Flashiap status codes. + */ +enum _flashiap_status +{ + kStatus_FLASHIAP_Success = kStatus_Success, /*!< Api is executed successfully */ + kStatus_FLASHIAP_InvalidCommand = MAKE_STATUS(kStatusGroup_FLASHIAP, 1U), /*!< Invalid command */ + kStatus_FLASHIAP_SrcAddrError = + MAKE_STATUS(kStatusGroup_FLASHIAP, 2U), /*!< Source address is not on word boundary */ + kStatus_FLASHIAP_DstAddrError = + MAKE_STATUS(kStatusGroup_FLASHIAP, 3U), /*!< Destination address is not on a correct boundary */ + kStatus_FLASHIAP_SrcAddrNotMapped = + MAKE_STATUS(kStatusGroup_FLASHIAP, 4U), /*!< Source address is not mapped in the memory map */ + kStatus_FLASHIAP_DstAddrNotMapped = + MAKE_STATUS(kStatusGroup_FLASHIAP, 5U), /*!< Destination address is not mapped in the memory map */ + kStatus_FLASHIAP_CountError = + MAKE_STATUS(kStatusGroup_FLASHIAP, 6U), /*!< Byte count is not multiple of 4 or is not a permitted value */ + kStatus_FLASHIAP_InvalidSector = + MAKE_STATUS(kStatusGroup_FLASHIAP, + 7), /*!< Sector number is invalid or end sector number is greater than start sector number */ + kStatus_FLASHIAP_SectorNotblank = MAKE_STATUS(kStatusGroup_FLASHIAP, 8U), /*!< One or more sectors are not blank */ + kStatus_FLASHIAP_NotPrepared = + MAKE_STATUS(kStatusGroup_FLASHIAP, 9U), /*!< Command to prepare sector for write operation was not executed */ + kStatus_FLASHIAP_CompareError = + MAKE_STATUS(kStatusGroup_FLASHIAP, 10U), /*!< Destination and source memory contents do not match */ + kStatus_FLASHIAP_Busy = + MAKE_STATUS(kStatusGroup_FLASHIAP, 11U), /*!< Flash programming hardware interface is busy */ + kStatus_FLASHIAP_ParamError = + MAKE_STATUS(kStatusGroup_FLASHIAP, 12U), /*!< Insufficient number of parameters or invalid parameter */ + kStatus_FLASHIAP_AddrError = MAKE_STATUS(kStatusGroup_FLASHIAP, 13U), /*!< Address is not on word boundary */ + kStatus_FLASHIAP_AddrNotMapped = + MAKE_STATUS(kStatusGroup_FLASHIAP, 14U), /*!< Address is not mapped in the memory map */ + kStatus_FLASHIAP_NoPower = MAKE_STATUS(kStatusGroup_FLASHIAP, 24U), /*!< Flash memory block is powered down */ + kStatus_FLASHIAP_NoClock = + MAKE_STATUS(kStatusGroup_FLASHIAP, 27U), /*!< Flash memory block or controller is not clocked */ +}; + +/*! + * @brief Flashiap command codes. + */ +enum _flashiap_commands +{ + kIapCmd_FLASHIAP_PrepareSectorforWrite = 50U, /*!< Prepare Sector for write */ + kIapCmd_FLASHIAP_CopyRamToFlash = 51U, /*!< Copy RAM to flash */ + kIapCmd_FLASHIAP_EraseSector = 52U, /*!< Erase Sector */ + kIapCmd_FLASHIAP_BlankCheckSector = 53U, /*!< Blank check sector */ + kIapCmd_FLASHIAP_ReadPartId = 54U, /*!< Read part id */ + kIapCmd_FLASHIAP_Read_BootromVersion = 55U, /*!< Read bootrom version */ + kIapCmd_FLASHIAP_Compare = 56U, /*!< Compare */ + kIapCmd_FLASHIAP_ReinvokeISP = 57U, /*!< Reinvoke ISP */ + kIapCmd_FLASHIAP_ReadUid = 58U, /*!< Read Uid isp */ + kIapCmd_FLASHIAP_ErasePage = 59U, /*!< Erase Page */ + kIapCmd_FLASHIAP_ReadMisr = 70U, /*!< Read Misr */ + kIapCmd_FLASHIAP_ReinvokeI2cSpiISP = 71U /*!< Reinvoke I2C/SPI isp */ +}; + +/*! @brief IAP_ENTRY API function type */ +typedef void (*IAP_ENTRY_T)(uint32_t cmd[5], uint32_t stat[4]); + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief IAP_ENTRY API function type + * + * Wrapper for rom iap call + * + * @param cmd_param IAP command and relevant parameter array. + * @param status_result IAP status result array. + * + * @retval None. Status/Result is returned via status_result array. + */ +static inline void iap_entry(uint32_t *cmd_param, uint32_t *status_result) +{ + ((IAP_ENTRY_T)FSL_FEATURE_SYSCON_IAP_ENTRY_LOCATION)(cmd_param, status_result); +} + +/*! + * @brief Prepare sector for write operation + + * This function prepares sector(s) for write/erase operation. This function must be + * called before calling the FLASHIAP_CopyRamToFlash() or FLASHIAP_EraseSector() or + * FLASHIAP_ErasePage() function. The end sector must be greater than or equal to + * start sector number. + * + * @param startSector Start sector number. + * @param endSector End sector number. + * + * @retval #kStatus_FLASHIAP_Success Api was executed successfully. + * @retval #kStatus_FLASHIAP_NoPower Flash memory block is powered down. + * @retval #kStatus_FLASHIAP_NoClock Flash memory block or controller is not clocked. + * @retval #kStatus_FLASHIAP_InvalidSector Sector number is invalid or end sector number + * is greater than start sector number. + * @retval #kStatus_FLASHIAP_Busy Flash programming hardware interface is busy. + */ +status_t FLASHIAP_PrepareSectorForWrite(uint32_t startSector, uint32_t endSector); + +/*! + * @brief Copy RAM to flash. + + * This function programs the flash memory. Corresponding sectors must be prepared + * via FLASHIAP_PrepareSectorForWrite before calling calling this function. The addresses + * should be a 256 byte boundary and the number of bytes should be 256 | 512 | 1024 | 4096. + * + * @param dstAddr Destination flash address where data bytes are to be written. + * @param srcAddr Source ram address from where data bytes are to be read. + * @param numOfBytes Number of bytes to be written. + * @param systemCoreClock SystemCoreClock in Hz. It is converted to KHz before calling the + * rom IAP function. + * + * @retval #kStatus_FLASHIAP_Success Api was executed successfully. + * @retval #kStatus_FLASHIAP_NoPower Flash memory block is powered down. + * @retval #kStatus_FLASHIAP_NoClock Flash memory block or controller is not clocked. + * @retval #kStatus_FLASHIAP_SrcAddrError Source address is not on word boundary. + * @retval #kStatus_FLASHIAP_DstAddrError Destination address is not on a correct boundary. + * @retval #kStatus_FLASHIAP_SrcAddrNotMapped Source address is not mapped in the memory map. + * @retval #kStatus_FLASHIAP_DstAddrNotMapped Destination address is not mapped in the memory map. + * @retval #kStatus_FLASHIAP_CountError Byte count is not multiple of 4 or is not a permitted value. + * @retval #kStatus_FLASHIAP_NotPrepared Command to prepare sector for write operation was not executed. + * @retval #kStatus_FLASHIAP_Busy Flash programming hardware interface is busy. + */ +status_t FLASHIAP_CopyRamToFlash(uint32_t dstAddr, uint32_t *srcAddr, uint32_t numOfBytes, uint32_t systemCoreClock); + +/*! + * @brief Erase sector + + * This function erases sector(s). The end sector must be greater than or equal to + * start sector number. FLASHIAP_PrepareSectorForWrite must be called before + * calling this function. + * + * @param startSector Start sector number. + * @param endSector End sector number. + * @param systemCoreClock SystemCoreClock in Hz. It is converted to KHz before calling the + * rom IAP function. + * + * @retval #kStatus_FLASHIAP_Success Api was executed successfully. + * @retval #kStatus_FLASHIAP_NoPower Flash memory block is powered down. + * @retval #kStatus_FLASHIAP_NoClock Flash memory block or controller is not clocked. + * @retval #kStatus_FLASHIAP_InvalidSector Sector number is invalid or end sector number + * is greater than start sector number. + * @retval #kStatus_FLASHIAP_NotPrepared Command to prepare sector for write operation was not executed. + * @retval #kStatus_FLASHIAP_Busy Flash programming hardware interface is busy. + */ +status_t FLASHIAP_EraseSector(uint32_t startSector, uint32_t endSector, uint32_t systemCoreClock); + +/*! + + * This function erases page(s). The end page must be greater than or equal to + * start page number. Corresponding sectors must be prepared via FLASHIAP_PrepareSectorForWrite + * before calling calling this function. + * + * @param startPage Start page number + * @param endPage End page number + * @param systemCoreClock SystemCoreClock in Hz. It is converted to KHz before calling the + * rom IAP function. + * + * @retval #kStatus_FLASHIAP_Success Api was executed successfully. + * @retval #kStatus_FLASHIAP_NoPower Flash memory block is powered down. + * @retval #kStatus_FLASHIAP_NoClock Flash memory block or controller is not clocked. + * @retval #kStatus_FLASHIAP_InvalidSector Page number is invalid or end page number + * is greater than start page number + * @retval #kStatus_FLASHIAP_NotPrepared Command to prepare sector for write operation was not executed. + * @retval #kStatus_FLASHIAP_Busy Flash programming hardware interface is busy. + */ +status_t FLASHIAP_ErasePage(uint32_t startPage, uint32_t endPage, uint32_t systemCoreClock); + +/*! + * @brief Blank check sector(s) + * + * Blank check single or multiples sectors of flash memory. The end sector must be greater than or equal to + * start sector number. It can be used to verify the sector eraseure after FLASHIAP_EraseSector call. + * + * @param startSector : Start sector number. Must be greater than or equal to start sector number + * @param endSector : End sector number + * @retval #kStatus_FLASHIAP_Success One or more sectors are in erased state. + * @retval #kStatus_FLASHIAP_NoPower Flash memory block is powered down. + * @retval #kStatus_FLASHIAP_NoClock Flash memory block or controller is not clocked. + * @retval #kStatus_FLASHIAP_SectorNotblank One or more sectors are not blank. + */ +status_t FLASHIAP_BlankCheckSector(uint32_t startSector, uint32_t endSector); + +/*! + * @brief Compare memory contents of flash with ram. + + * This function compares the contents of flash and ram. It can be used to verify the flash + * memory contents after FLASHIAP_CopyRamToFlash call. + * + * @param dstAddr Destination flash address. + * @param srcAddr Source ram address. + * @param numOfBytes Number of bytes to be compared. + * + * @retval #kStatus_FLASHIAP_Success Contents of flash and ram match. + * @retval #kStatus_FLASHIAP_NoPower Flash memory block is powered down. + * @retval #kStatus_FLASHIAP_NoClock Flash memory block or controller is not clocked. + * @retval #kStatus_FLASHIAP_AddrError Address is not on word boundary. + * @retval #kStatus_FLASHIAP_AddrNotMapped Address is not mapped in the memory map. + * @retval #kStatus_FLASHIAP_CountError Byte count is not multiple of 4 or is not a permitted value. + * @retval #kStatus_FLASHIAP_CompareError Destination and source memory contents do not match. + */ +status_t FLASHIAP_Compare(uint32_t dstAddr, uint32_t *srcAddr, uint32_t numOfBytes); + +#ifdef __cplusplus +} +#endif + +/*@}*/ + +#endif /* _FSL_FLASHIAP_H_ */ diff --git a/platform/mcu/lpc54102/drivers/fsl_fmeas.c b/platform/mcu/lpc54102/drivers/fsl_fmeas.c new file mode 100644 index 0000000000..6e6e7c0c66 --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_fmeas.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_fmeas.h" + +/******************************************************************************* + * Definitions + *******************************************************************************/ + +/*! @brief Target clock counter value. + * According to user manual, 2 has to be subtracted from captured value (CAPVAL). */ +#define TARGET_CLOCK_COUNT(base) \ + ((uint32_t)( \ + ((((SYSCON_Type *)base)->FREQMECTRL & SYSCON_FREQMECTRL_CAPVAL_MASK) >> SYSCON_FREQMECTRL_CAPVAL_SHIFT) - 2)) + +/*! @brief Reference clock counter value. */ +#define REFERENCE_CLOCK_COUNT ((uint32_t)((SYSCON_FREQMECTRL_CAPVAL_MASK >> SYSCON_FREQMECTRL_CAPVAL_SHIFT) + 1)) + +/******************************************************************************* + * Code + ******************************************************************************/ + +uint32_t FMEAS_GetFrequency(SYSCON_Type *base, uint32_t refClockRate) +{ + uint32_t targetClockCount = TARGET_CLOCK_COUNT(base); + uint64_t clkrate = 0; + + if (targetClockCount > 0) + { + clkrate = (((uint64_t)targetClockCount) * (uint64_t)refClockRate) / REFERENCE_CLOCK_COUNT; + } + + return (uint32_t)clkrate; +} diff --git a/platform/mcu/lpc54102/drivers/fsl_fmeas.h b/platform/mcu/lpc54102/drivers/fsl_fmeas.h new file mode 100644 index 0000000000..354f513e97 --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_fmeas.h @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_FMEAS_H_ +#define _FSL_FMEAS_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup fmeas + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Definitions + *******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief Defines LPC Frequency Measure driver version 2.0.0. + * + * Change log: + * - Version 2.0.0 + * - initial version + */ +#define FSL_FMEAS_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*@}*/ + +/******************************************************************************* + * API + *******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + +/*! + * @name FMEAS Functional Operation + * @{ + */ + +/*! + * @brief Starts a frequency measurement cycle. + * + * @param base : SYSCON peripheral base address. + */ +static inline void FMEAS_StartMeasure(SYSCON_Type *base) +{ + base->FREQMECTRL = 0; + base->FREQMECTRL = (1UL << 31); +} + +/*! + * @brief Indicates when a frequency measurement cycle is complete. + * + * @param base : SYSCON peripheral base address. + * @return true if a measurement cycle is active, otherwise false. + */ +static inline bool FMEAS_IsMeasureComplete(SYSCON_Type *base) +{ + return (bool)((base->FREQMECTRL & (1UL << 31)) == 0); +} + +/*! + * @brief Returns the computed value for a frequency measurement cycle + * + * @param base : SYSCON peripheral base address. + * @param refClockRate : Reference clock rate used during the frequency measurement cycle. + * + * @return Frequency in Hz. + */ +uint32_t FMEAS_GetFrequency(SYSCON_Type *base, uint32_t refClockRate); + +/*@}*/ + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + +/*! @}*/ + +#endif /* _FSL_FMEAS_H_ */ diff --git a/platform/mcu/lpc54102/drivers/fsl_gint.c b/platform/mcu/lpc54102/drivers/fsl_gint.c new file mode 100644 index 0000000000..dd3574ba61 --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_gint.c @@ -0,0 +1,311 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_gint.h" + +/******************************************************************************* + * Variables + ******************************************************************************/ +/*! @brief Pointers to GINT bases for each instance. */ +static GINT_Type *const s_gintBases[FSL_FEATURE_SOC_GINT_COUNT] = GINT_BASE_PTRS; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +/*! @brief Clocks for each instance. */ +static const clock_ip_name_t s_gintClocks[FSL_FEATURE_SOC_GINT_COUNT] = GINT_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +/*! @brief Resets for each instance. */ +static const reset_ip_name_t s_gintResets[FSL_FEATURE_SOC_GINT_COUNT] = GINT_RSTS; + +/* @brief Irq number for each instance */ +static const IRQn_Type s_gintIRQ[FSL_FEATURE_SOC_GINT_COUNT] = GINT_IRQS; + +/*! @brief Callback function array for GINT(s). */ +static gint_cb_t s_gintCallback[FSL_FEATURE_SOC_GINT_COUNT]; + +/******************************************************************************* + * Code + ******************************************************************************/ + +static uint32_t GINT_GetInstance(GINT_Type *base) +{ + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < ARRAY_SIZE(s_gintBases); instance++) + { + if (s_gintBases[instance] == base) + { + break; + } + } + + assert(instance < ARRAY_SIZE(s_gintBases)); + + return instance; +} + +void GINT_Init(GINT_Type *base) +{ + uint32_t instance; + + instance = GINT_GetInstance(base); + + s_gintCallback[instance] = NULL; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Enable the peripheral clock */ + CLOCK_EnableClock(s_gintClocks[instance]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + + /* Reset the peripheral */ + RESET_PeripheralReset(s_gintResets[instance]); +} + +void GINT_SetCtrl(GINT_Type *base, gint_comb_t comb, gint_trig_t trig, gint_cb_t callback) +{ + uint32_t instance; + + instance = GINT_GetInstance(base); + + base->CTRL = (GINT_CTRL_COMB(comb) | GINT_CTRL_TRIG(trig)); + + /* Save callback pointer */ + s_gintCallback[instance] = callback; +} + +void GINT_GetCtrl(GINT_Type *base, gint_comb_t *comb, gint_trig_t *trig, gint_cb_t *callback) +{ + uint32_t instance; + + instance = GINT_GetInstance(base); + + *comb = (gint_comb_t)((base->CTRL & GINT_CTRL_COMB_MASK) >> GINT_CTRL_COMB_SHIFT); + *trig = (gint_trig_t)((base->CTRL & GINT_CTRL_TRIG_MASK) >> GINT_CTRL_TRIG_SHIFT); + *callback = s_gintCallback[instance]; +} + +void GINT_ConfigPins(GINT_Type *base, gint_port_t port, uint32_t polarityMask, uint32_t enableMask) +{ + base->PORT_POL[port] = polarityMask; + base->PORT_ENA[port] = enableMask; +} + +void GINT_GetConfigPins(GINT_Type *base, gint_port_t port, uint32_t *polarityMask, uint32_t *enableMask) +{ + *polarityMask = base->PORT_POL[port]; + *enableMask = base->PORT_ENA[port]; +} + +void GINT_EnableCallback(GINT_Type *base) +{ + uint32_t instance; + + instance = GINT_GetInstance(base); + /* If GINT is configured in "AND" mode a spurious interrupt is generated. + Clear status and pending interrupt before enabling the irq in NVIC. */ + GINT_ClrStatus(base); + NVIC_ClearPendingIRQ(s_gintIRQ[instance]); + EnableIRQ(s_gintIRQ[instance]); +} + +void GINT_DisableCallback(GINT_Type *base) +{ + uint32_t instance; + + instance = GINT_GetInstance(base); + DisableIRQ(s_gintIRQ[instance]); + GINT_ClrStatus(base); + NVIC_ClearPendingIRQ(s_gintIRQ[instance]); +} + +void GINT_Deinit(GINT_Type *base) +{ + uint32_t instance; + + instance = GINT_GetInstance(base); + + /* Cleanup */ + GINT_DisableCallback(base); + s_gintCallback[instance] = NULL; + + /* Reset the peripheral */ + RESET_PeripheralReset(s_gintResets[instance]); + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Disable the peripheral clock */ + CLOCK_DisableClock(s_gintClocks[instance]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +/* IRQ handler functions overloading weak symbols in the startup */ +#if defined(GINT0) +void GINT0_DriverIRQHandler(void) +{ + /* Clear interrupt before callback */ + s_gintBases[0]->CTRL |= GINT_CTRL_INT_MASK; + /* Call user function */ + if (s_gintCallback[0] != NULL) + { + s_gintCallback[0](); + } + /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif + +#if defined(GINT1) +void GINT1_DriverIRQHandler(void) +{ + /* Clear interrupt before callback */ + s_gintBases[1]->CTRL |= GINT_CTRL_INT_MASK; + /* Call user function */ + if (s_gintCallback[1] != NULL) + { + s_gintCallback[1](); + } + /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif + +#if defined(GINT2) +void GINT2_DriverIRQHandler(void) +{ + /* Clear interrupt before callback */ + s_gintBases[2]->CTRL |= GINT_CTRL_INT_MASK; + /* Call user function */ + if (s_gintCallback[2] != NULL) + { + s_gintCallback[2](); + } + /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif + +#if defined(GINT3) +void GINT3_DriverIRQHandler(void) +{ + /* Clear interrupt before callback */ + s_gintBases[3]->CTRL |= GINT_CTRL_INT_MASK; + /* Call user function */ + if (s_gintCallback[3] != NULL) + { + s_gintCallback[3](); + } + /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif + +#if defined(GINT4) +void GINT4_DriverIRQHandler(void) +{ + /* Clear interrupt before callback */ + s_gintBases[4]->CTRL |= GINT_CTRL_INT_MASK; + /* Call user function */ + if (s_gintCallback[4] != NULL) + { + s_gintCallback[4](); + } + /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif + +#if defined(GINT5) +void GINT5_DriverIRQHandler(void) +{ + /* Clear interrupt before callback */ + s_gintBases[5]->CTRL |= GINT_CTRL_INT_MASK; + /* Call user function */ + if (s_gintCallback[5] != NULL) + { + s_gintCallback[5](); + } + /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif + +#if defined(GINT6) +void GINT6_DriverIRQHandler(void) +{ + /* Clear interrupt before callback */ + s_gintBases[6]->CTRL |= GINT_CTRL_INT_MASK; + /* Call user function */ + if (s_gintCallback[6] != NULL) + { + s_gintCallback[6](); + } + /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif + +#if defined(GINT7) +void GINT7_DriverIRQHandler(void) +{ + /* Clear interrupt before callback */ + s_gintBases[7]->CTRL |= GINT_CTRL_INT_MASK; + /* Call user function */ + if (s_gintCallback[7] != NULL) + { + s_gintCallback[7](); + } + /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif diff --git a/platform/mcu/lpc54102/drivers/fsl_gint.h b/platform/mcu/lpc54102/drivers/fsl_gint.h new file mode 100644 index 0000000000..499536c4ae --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_gint.h @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_GINT_H_ +#define _FSL_GINT_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup gint_driver + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +#define FSL_GINT_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0. */ +/*@}*/ + +/*! @brief GINT combine inputs type */ +typedef enum _gint_comb +{ + kGINT_CombineOr = 0U, /*!< A grouped interrupt is generated when any one of the enabled inputs is active */ + kGINT_CombineAnd = 1U /*!< A grouped interrupt is generated when all enabled inputs are active */ +} gint_comb_t; + +/*! @brief GINT trigger type */ +typedef enum _gint_trig +{ + kGINT_TrigEdge = 0U, /*!< Edge triggered based on polarity */ + kGINT_TrigLevel = 1U /*!< Level triggered based on polarity */ +} gint_trig_t; + +/* @brief GINT port type */ +typedef enum _gint_port +{ + kGINT_Port0 = 0U, + kGINT_Port1 = 1U, +#if defined(FSL_FEATURE_GINT_PORT_COUNT) && (FSL_FEATURE_GINT_PORT_COUNT > 2U) + kGINT_Port2 = 2U, +#endif +#if defined(FSL_FEATURE_GINT_PORT_COUNT) && (FSL_FEATURE_GINT_PORT_COUNT > 3U) + kGINT_Port3 = 3U, +#endif +#if defined(FSL_FEATURE_GINT_PORT_COUNT) && (FSL_FEATURE_GINT_PORT_COUNT > 4U) + kGINT_Port4 = 4U, +#endif +#if defined(FSL_FEATURE_GINT_PORT_COUNT) && (FSL_FEATURE_GINT_PORT_COUNT > 5U) + kGINT_Port5 = 5U, +#endif +#if defined(FSL_FEATURE_GINT_PORT_COUNT) && (FSL_FEATURE_GINT_PORT_COUNT > 6U) + kGINT_Port6 = 6U, +#endif +#if defined(FSL_FEATURE_GINT_PORT_COUNT) && (FSL_FEATURE_GINT_PORT_COUNT > 7U) + kGINT_Port7 = 7U, +#endif +} gint_port_t; + +/*! @brief GINT Callback function. */ +typedef void (*gint_cb_t)(void); + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Initialize GINT peripheral. + + * This function initializes the GINT peripheral and enables the clock. + * + * @param base Base address of the GINT peripheral. + * + * @retval None. + */ +void GINT_Init(GINT_Type *base); + +/*! + * @brief Setup GINT peripheral control parameters. + + * This function sets the control parameters of GINT peripheral. + * + * @param base Base address of the GINT peripheral. + * @param comb Controls if the enabled inputs are logically ORed or ANDed for interrupt generation. + * @param trig Controls if the enabled inputs are level or edge sensitive based on polarity. + * @param callback This function is called when configured group interrupt is generated. + * + * @retval None. + */ +void GINT_SetCtrl(GINT_Type *base, gint_comb_t comb, gint_trig_t trig, gint_cb_t callback); + +/*! + * @brief Get GINT peripheral control parameters. + + * This function returns the control parameters of GINT peripheral. + * + * @param base Base address of the GINT peripheral. + * @param comb Pointer to store combine input value. + * @param trig Pointer to store trigger value. + * @param callback Pointer to store callback function. + * + * @retval None. + */ +void GINT_GetCtrl(GINT_Type *base, gint_comb_t *comb, gint_trig_t *trig, gint_cb_t *callback); + +/*! + * @brief Configure GINT peripheral pins. + + * This function enables and controls the polarity of enabled pin(s) of a given port. + * + * @param base Base address of the GINT peripheral. + * @param port Port number. + * @param polarityMask Each bit position selects the polarity of the corresponding enabled pin. + * 0 = The pin is active LOW. 1 = The pin is active HIGH. + * @param enableMask Each bit position selects if the corresponding pin is enabled or not. + * 0 = The pin is disabled. 1 = The pin is enabled. + * + * @retval None. + */ +void GINT_ConfigPins(GINT_Type *base, gint_port_t port, uint32_t polarityMask, uint32_t enableMask); + +/*! + * @brief Get GINT peripheral pin configuration. + + * This function returns the pin configuration of a given port. + * + * @param base Base address of the GINT peripheral. + * @param port Port number. + * @param polarityMask Pointer to store the polarity mask Each bit position indicates the polarity of the corresponding + enabled pin. + * 0 = The pin is active LOW. 1 = The pin is active HIGH. + * @param enableMask Pointer to store the enable mask. Each bit position indicates if the corresponding pin is enabled + or not. + * 0 = The pin is disabled. 1 = The pin is enabled. + * + * @retval None. + */ +void GINT_GetConfigPins(GINT_Type *base, gint_port_t port, uint32_t *polarityMask, uint32_t *enableMask); + +/*! + * @brief Enable callback. + + * This function enables the interrupt for the selected GINT peripheral. Although the pin(s) are monitored + * as soon as they are enabled, the callback function is not enabled until this function is called. + * + * @param base Base address of the GINT peripheral. + * + * @retval None. + */ +void GINT_EnableCallback(GINT_Type *base); + +/*! + * @brief Disable callback. + + * This function disables the interrupt for the selected GINT peripheral. Although the pins are still + * being monitored but the callback function is not called. + * + * @param base Base address of the peripheral. + * + * @retval None. + */ +void GINT_DisableCallback(GINT_Type *base); + +/*! + * @brief Clear GINT status. + + * This function clears the GINT status bit. + * + * @param base Base address of the GINT peripheral. + * + * @retval None. + */ +static inline void GINT_ClrStatus(GINT_Type *base) +{ + base->CTRL |= GINT_CTRL_INT_MASK; +} + +/*! + * @brief Get GINT status. + + * This function returns the GINT status. + * + * @param base Base address of the GINT peripheral. + * + * @retval status = 0 No group interrupt request. = 1 Group interrupt request active. + */ +static inline uint32_t GINT_GetStatus(GINT_Type *base) +{ + return (base->CTRL & GINT_CTRL_INT_MASK); +} + +/*! + * @brief Deinitialize GINT peripheral. + + * This function disables the GINT clock. + * + * @param base Base address of the GINT peripheral. + * + * @retval None. + */ +void GINT_Deinit(GINT_Type *base); + +#ifdef __cplusplus +} +#endif + +/*@}*/ + +#endif /* _FSL_GINT_H_ */ diff --git a/platform/mcu/lpc54102/drivers/fsl_gpio.c b/platform/mcu/lpc54102/drivers/fsl_gpio.c new file mode 100644 index 0000000000..acc2d4a517 --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_gpio.c @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_gpio.h" + +/******************************************************************************* + * Variables + ******************************************************************************/ +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +/*! @brief Array to map FGPIO instance number to clock name. */ +static const clock_ip_name_t s_gpioClockName[] = GPIO_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +/******************************************************************************* +* Prototypes +************ ******************************************************************/ + +/******************************************************************************* + * Code + ******************************************************************************/ +void GPIO_PortInit(GPIO_Type *base, uint32_t port) +{ +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + assert(port < ARRAY_SIZE(s_gpioClockName)); + + /* Upgate the GPIO clock */ + CLOCK_EnableClock(s_gpioClockName[port]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +void GPIO_PinInit(GPIO_Type *base, uint32_t port, uint32_t pin, const gpio_pin_config_t *config) +{ + if (config->pinDirection == kGPIO_DigitalInput) + { + base->DIR[port] &= ~(1U << pin); + } + else + { + /* Set default output value */ + if (config->outputLogic == 0U) + { + base->CLR[port] = (1U << pin); + } + else + { + base->SET[port] = (1U << pin); + } + /* Set pin direction */ + base->DIR[port] |= 1U << pin; + } +} diff --git a/platform/mcu/lpc54102/drivers/fsl_gpio.h b/platform/mcu/lpc54102/drivers/fsl_gpio.h new file mode 100644 index 0000000000..b2f198cab5 --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_gpio.h @@ -0,0 +1,351 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _LPC_GPIO_H_ +#define _LPC_GPIO_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup lpc_gpio + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief LPC GPIO driver version 2.1.1. */ +#define FSL_GPIO_DRIVER_VERSION (MAKE_VERSION(2, 1, 1)) +/*@}*/ + +/*! @brief LPC GPIO direction definition */ +typedef enum _gpio_pin_direction +{ + kGPIO_DigitalInput = 0U, /*!< Set current pin as digital input*/ + kGPIO_DigitalOutput = 1U, /*!< Set current pin as digital output*/ +} gpio_pin_direction_t; + +/*! + * @brief The GPIO pin configuration structure. + * + * Every pin can only be configured as either output pin or input pin at a time. + * If configured as a input pin, then leave the outputConfig unused. + */ +typedef struct _gpio_pin_config +{ + gpio_pin_direction_t pinDirection; /*!< GPIO direction, input or output */ + /* Output configurations, please ignore if configured as a input one */ + uint8_t outputLogic; /*!< Set default output logic, no use in input */ +} gpio_pin_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif + +/*! @name GPIO Configuration */ +/*@{*/ + +/*! + * @brief Initializes the GPIO peripheral. + * + * This function ungates the GPIO clock. + * + * @param base GPIO peripheral base pointer. + * @param port GPIO port number. + */ +void GPIO_PortInit(GPIO_Type *base, uint32_t port); + +/*! + * @brief Initializes the GPIO peripheral. + * @deprecated Do not use this function. It has been superceded by @ref GPIO_PortInit. + */ +static inline void GPIO_Init(GPIO_Type *base, uint32_t port) +{ + GPIO_PortInit(base, port); +} + +/*! + * @brief Initializes a GPIO pin used by the board. + * + * To initialize the GPIO, define a pin configuration, either input or output, in the user file. + * Then, call the GPIO_PinInit() function. + * + * This is an example to define an input pin or output pin configuration: + * @code + * // Define a digital input pin configuration, + * gpio_pin_config_t config = + * { + * kGPIO_DigitalInput, + * 0, + * } + * //Define a digital output pin configuration, + * gpio_pin_config_t config = + * { + * kGPIO_DigitalOutput, + * 0, + * } + * @endcode + * + * @param base GPIO peripheral base pointer(Typically GPIO) + * @param port GPIO port number + * @param pin GPIO pin number + * @param config GPIO pin configuration pointer + */ +void GPIO_PinInit(GPIO_Type *base, uint32_t port, uint32_t pin, const gpio_pin_config_t *config); + +/*@}*/ + +/*! @name GPIO Output Operations */ +/*@{*/ + +/*! + * @brief Sets the output level of the one GPIO pin to the logic 1 or 0. + * + * @param base GPIO peripheral base pointer(Typically GPIO) + * @param port GPIO port number + * @param pin GPIO pin number + * @param output GPIO pin output logic level. + * - 0: corresponding pin output low-logic level. + * - 1: corresponding pin output high-logic level. + */ +static inline void GPIO_PinWrite(GPIO_Type *base, uint32_t port, uint32_t pin, uint8_t output) +{ + base->B[port][pin] = output; +} + +/*! + * @brief Sets the output level of the one GPIO pin to the logic 1 or 0. + * @deprecated Do not use this function. It has been superceded by @ref GPIO_PinWrite. + */ +static inline void GPIO_WritePinOutput(GPIO_Type *base, uint32_t port, uint32_t pin, uint8_t output) +{ + base->B[port][pin] = output; +} +/*@}*/ +/*! @name GPIO Input Operations */ +/*@{*/ + +/*! + * @brief Reads the current input value of the GPIO PIN. + * + * @param base GPIO peripheral base pointer(Typically GPIO) + * @param port GPIO port number + * @param pin GPIO pin number + * @retval GPIO port input value + * - 0: corresponding pin input low-logic level. + * - 1: corresponding pin input high-logic level. + */ +static inline uint32_t GPIO_PinRead(GPIO_Type *base, uint32_t port, uint32_t pin) +{ + return (uint32_t)base->B[port][pin]; +} + +/*! + * @brief Reads the current input value of the GPIO PIN. + * @deprecated Do not use this function. It has been superceded by @ref GPIO_PinRead. + */ +static inline uint32_t GPIO_ReadPinInput(GPIO_Type *base, uint32_t port, uint32_t pin) +{ + return GPIO_PinRead(base, port, pin); +} +/*@}*/ + +/*! + * @brief Sets the output level of the multiple GPIO pins to the logic 1. + * + * @param base GPIO peripheral base pointer(Typically GPIO) + * @param port GPIO port number + * @param mask GPIO pin number macro + */ +static inline void GPIO_PortSet(GPIO_Type *base, uint32_t port, uint32_t mask) +{ + base->SET[port] = mask; +} + +/*! + * @brief Sets the output level of the multiple GPIO pins to the logic 1. + * @deprecated Do not use this function. It has been superceded by @ref GPIO_PortSet. + */ +static inline void GPIO_SetPinsOutput(GPIO_Type *base, uint32_t port, uint32_t mask) +{ + GPIO_PortSet(base, port, mask); +} + +/*! + * @brief Sets the output level of the multiple GPIO pins to the logic 0. + * + * @param base GPIO peripheral base pointer(Typically GPIO) + * @param port GPIO port number + * @param mask GPIO pin number macro + */ +static inline void GPIO_PortClear(GPIO_Type *base, uint32_t port, uint32_t mask) +{ + base->CLR[port] = mask; +} + +/*! + * @brief Sets the output level of the multiple GPIO pins to the logic 0. + * @deprecated Do not use this function. It has been superceded by @ref GPIO_PortClear. + */ +static inline void GPIO_ClearPinsOutput(GPIO_Type *base, uint32_t port, uint32_t mask) +{ + GPIO_PortClear(base, port, mask); +} + +/*! + * @brief Reverses current output logic of the multiple GPIO pins. + * + * @param base GPIO peripheral base pointer(Typically GPIO) + * @param port GPIO port number + * @param mask GPIO pin number macro + */ +static inline void GPIO_PortToggle(GPIO_Type *base, uint32_t port, uint32_t mask) +{ + base->NOT[port] = mask; +} + +/*! + * @brief Reverses current output logic of the multiple GPIO pins. + * @deprecated Do not use this function. It has been superceded by @ref GPIO_PortToggle. + */ +static inline void GPIO_TogglePinsOutput(GPIO_Type *base, uint32_t port, uint32_t mask) +{ + GPIO_PortToggle(base, port, mask); +} +/*@}*/ + +/*! + * @brief Reads the current input value of the whole GPIO port. + * + * @param base GPIO peripheral base pointer(Typically GPIO) + * @param port GPIO port number + */ +static inline uint32_t GPIO_PortRead(GPIO_Type *base, uint32_t port) +{ + return (uint32_t)base->PIN[port]; +} + +/*! + * @brief Reads the current input value of the whole GPIO port. + * @deprecated Do not use this function. It has been superceded by @ref GPIO_PortRead + */ +static inline uint32_t GPIO_ReadPinsInput(GPIO_Type *base, uint32_t port) +{ + return GPIO_PortRead(base, port); +} + +/*@}*/ +/*! @name GPIO Mask Operations */ +/*@{*/ + +/*! + * @brief Sets port mask, 0 - enable pin, 1 - disable pin. + * + * @param base GPIO peripheral base pointer(Typically GPIO) + * @param port GPIO port number + * @param mask GPIO pin number macro + */ +static inline void GPIO_PortMaskedSet(GPIO_Type *base, uint32_t port, uint32_t mask) +{ + base->MASK[port] = mask; +} + +/*! + * @brief Sets port mask, 0 - enable pin, 1 - disable pin. + * @deprecated Do not use this function. It has been superceded by @ref GPIO_PortMaskedSet. + */ +static inline void GPIO_SetPortMask(GPIO_Type *base, uint32_t port, uint32_t mask) +{ + GPIO_PortMaskedSet(base, port, mask); +} + +/*! + * @brief Sets the output level of the masked GPIO port. Only pins enabled by GPIO_SetPortMask() will be affected. + * + * @param base GPIO peripheral base pointer(Typically GPIO) + * @param port GPIO port number + * @param output GPIO port output value. + */ +static inline void GPIO_PortMaskedWrite(GPIO_Type *base, uint32_t port, uint32_t output) +{ + base->MPIN[port] = output; +} + +/*! + * @brief Sets the output level of the masked GPIO port. Only pins enabled by GPIO_SetPortMask() will be affected. + * @deprecated Do not use this function. It has been superceded by @ref GPIO_PortMaskedWrite. + */ +static inline void GPIO_WriteMPort(GPIO_Type *base, uint32_t port, uint32_t output) +{ + GPIO_PortMaskedWrite(base, port, output); +} + +/*! + * @brief Reads the current input value of the masked GPIO port. Only pins enabled by GPIO_SetPortMask() will be + * affected. + * + * @param base GPIO peripheral base pointer(Typically GPIO) + * @param port GPIO port number + * @retval masked GPIO port value + */ +static inline uint32_t GPIO_PortMaskedRead(GPIO_Type *base, uint32_t port) +{ + return (uint32_t)base->MPIN[port]; +} + +/*! + * @brief Reads the current input value of the masked GPIO port. Only pins enabled by GPIO_SetPortMask() will be + * affected. + * @deprecated Do not use this function. It has been superceded by @ref GPIO_PortMaskedRead. + */ +static inline uint32_t GPIO_ReadMPort(GPIO_Type *base, uint32_t port) +{ + return GPIO_PortMaskedRead(base, port); +} + +/*@}*/ + +#if defined(__cplusplus) +} +#endif + +/*! + * @} + */ + +#endif /* _LPC_GPIO_H_*/ diff --git a/platform/mcu/lpc54102/drivers/fsl_i2c.c b/platform/mcu/lpc54102/drivers/fsl_i2c.c new file mode 100644 index 0000000000..6ee6aa7d86 --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_i2c.c @@ -0,0 +1,1561 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_i2c.h" +#include +#include + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief Common sets of flags used by the driver. */ +enum _i2c_flag_constants +{ + kI2C_MasterIrqFlags = I2C_INTSTAT_MSTPENDING_MASK | I2C_INTSTAT_MSTARBLOSS_MASK | I2C_INTSTAT_MSTSTSTPERR_MASK, + kI2C_SlaveIrqFlags = I2C_INTSTAT_SLVPENDING_MASK | I2C_INTSTAT_SLVDESEL_MASK, +}; + +/*! @brief Typedef for interrupt handler. */ +typedef void (*i2c_isr_t)(I2C_Type *base, void *i2cHandle); +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +static status_t I2C_InitTransferStateMachine(I2C_Type *base, i2c_master_handle_t *handle, i2c_master_transfer_t *xfer); +static void I2C_SlaveInternalStateMachineReset(I2C_Type *base); +static status_t I2C_SlaveDivVal(uint32_t srcClock_Hz, i2c_slave_bus_speed_t busSpeed, uint32_t *divVal); +static uint32_t I2C_SlavePollPending(I2C_Type *base); +static void I2C_SlaveInvokeEvent(I2C_Type *base, i2c_slave_handle_t *handle, i2c_slave_transfer_event_t event); +static bool I2C_SlaveAddressIRQ(I2C_Type *base, i2c_slave_handle_t *handle); +static status_t I2C_SlaveTransferNonBlockingInternal(I2C_Type *base, + i2c_slave_handle_t *handle, + const void *txData, + size_t txSize, + void *rxData, + size_t rxSize, + uint32_t eventMask); + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/*! @brief Array to map i2c instance number to base address. */ +static I2C_Type *const s_i2cBases[] = I2C_BASE_PTRS; + +/*! @brief IRQ name array */ +static const IRQn_Type s_i2cIRQ[] = I2C_IRQS; + +/*! @brief Pointers to i2c clocks for each instance. */ +static const clock_ip_name_t s_i2cClocks[] = I2C_CLOCKS; + +/*! @brief Pointer to master IRQ handler for each instance. */ +i2c_isr_t s_i2cMasterIsr; + +/*! @brief Pointer to slave IRQ handler for each instance. */ +static i2c_isr_t s_i2cSlaveIsr; + +/*! @brief Pointers to i2c handles for each instance. */ +void *s_i2cHandle[FSL_FEATURE_SOC_I2C_COUNT] = {NULL}; +/******************************************************************************* + * Code + ******************************************************************************/ + +/*! + * @brief Returns an instance number given a base address. + * + * If an invalid base address is passed, debug builds will assert. Release builds will just return + * instance number 0. + * + * @param base The I2C peripheral base address. + * @return I2C instance number starting from 0. + */ +uint32_t I2C_GetInstance(I2C_Type *base) +{ + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < ARRAY_SIZE(s_i2cBases); instance++) + { + if (s_i2cBases[instance] == base) + { + break; + } + } + + assert(instance < ARRAY_SIZE(s_i2cBases)); + + return instance; +} + +void I2C_MasterGetDefaultConfig(i2c_master_config_t *masterConfig) +{ + masterConfig->enableMaster = true; + masterConfig->baudRate_Bps = 100000U; + masterConfig->enableTimeout = false; +} + +void I2C_MasterInit(I2C_Type *base, const i2c_master_config_t *masterConfig, uint32_t srcClock_Hz) +{ + /* Enable I2C clock. */ + CLOCK_EnableClock(s_i2cClocks[I2C_GetInstance(base)]); + + I2C_MasterEnable(base, masterConfig->enableMaster); + I2C_MasterSetBaudRate(base, masterConfig->baudRate_Bps, srcClock_Hz); +} + +void I2C_MasterDeinit(I2C_Type *base) +{ + I2C_MasterEnable(base, false); + /* Disable I2C clock. */ + CLOCK_DisableClock(s_i2cClocks[I2C_GetInstance(base)]); +} + +void I2C_MasterSetBaudRate(I2C_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz) +{ + uint32_t scl, divider; + uint32_t best_scl, best_div; + uint32_t err, best_err; + + best_err = 0; + + for (scl = 9; scl >= 2; scl--) + { + /* calculated ideal divider value for given scl */ + divider = srcClock_Hz / (baudRate_Bps * scl * 2u); + + /* adjust it if it is out of range */ + divider = (divider > 0x10000u) ? 0x10000 : divider; + + /* calculate error */ + err = srcClock_Hz - (baudRate_Bps * scl * 2u * divider); + if ((err < best_err) || (best_err == 0)) + { + best_div = divider; + best_scl = scl; + best_err = err; + } + + if ((err == 0) || (divider >= 0x10000u)) + { + /* either exact value was found + or divider is at its max (it would even greater in the next iteration for sure) */ + break; + } + } + + base->CLKDIV = I2C_CLKDIV_DIVVAL(best_div - 1); + base->MSTTIME = I2C_MSTTIME_MSTSCLLOW(best_scl - 2u) | I2C_MSTTIME_MSTSCLHIGH(best_scl - 2u); +} + +static uint32_t I2C_PendingStatusWait(I2C_Type *base) +{ + uint32_t status; + +#if I2C_WAIT_TIMEOUT + uint32_t waitTimes = I2C_WAIT_TIMEOUT; +#endif + + do + { + status = I2C_GetStatusFlags(base); +#if I2C_WAIT_TIMEOUT + } while (((status & I2C_STAT_MSTPENDING_MASK) == 0) && (--waitTimes)); + + if (waitTimes == 0) + { + return kStatus_I2C_Timeout; + } +#else + } while ((status & I2C_STAT_MSTPENDING_MASK) == 0); +#endif + + /* Clear controller state. */ + I2C_MasterClearStatusFlags(base, I2C_STAT_MSTARBLOSS_MASK | I2C_STAT_MSTSTSTPERR_MASK); + + return status; +} + +status_t I2C_MasterStart(I2C_Type *base, uint8_t address, i2c_direction_t direction) +{ + status_t result; + result = I2C_PendingStatusWait(base); + if (result == kStatus_I2C_Timeout) + { + return kStatus_I2C_Timeout; + } + + /* Write Address and RW bit to data register */ + base->MSTDAT = ((uint32_t)address << 1) | ((uint32_t)direction & 1u); + /* Start the transfer */ + base->MSTCTL = I2C_MSTCTL_MSTSTART_MASK; + + return kStatus_Success; +} + +status_t I2C_MasterStop(I2C_Type *base) +{ + status_t result; + result = I2C_PendingStatusWait(base); + if (result == kStatus_I2C_Timeout) + { + return kStatus_I2C_Timeout; + } + + base->MSTCTL = I2C_MSTCTL_MSTSTOP_MASK; + return kStatus_Success; +} + +status_t I2C_MasterWriteBlocking(I2C_Type *base, const void *txBuff, size_t txSize, uint32_t flags) +{ + uint32_t status; + uint32_t master_state; + status_t err; + + const uint8_t *buf = (const uint8_t *)(uintptr_t)txBuff; + + assert(txBuff); + + err = kStatus_Success; + while (txSize) + { + status = I2C_PendingStatusWait(base); + if (status == kStatus_I2C_Timeout) + { + return kStatus_I2C_Timeout; + } + + if (status & I2C_STAT_MSTARBLOSS_MASK) + { + return kStatus_I2C_ArbitrationLost; + } + + if (status & I2C_STAT_MSTSTSTPERR_MASK) + { + return kStatus_I2C_StartStopError; + } + + master_state = (status & I2C_STAT_MSTSTATE_MASK) >> I2C_STAT_MSTSTATE_SHIFT; + switch (master_state) + { + case I2C_STAT_MSTCODE_TXREADY: + /* ready to send next byte */ + base->MSTDAT = *buf++; + txSize--; + base->MSTCTL = I2C_MSTCTL_MSTCONTINUE_MASK; + break; + + case I2C_STAT_MSTCODE_NACKADR: + /* slave nacked the address */ + err = kStatus_I2C_Addr_Nak; + break; + + case I2C_STAT_MSTCODE_NACKDAT: + /* slave nacked the last byte */ + err = kStatus_I2C_Nak; + break; + + default: + /* unexpected state */ + err = kStatus_I2C_UnexpectedState; + break; + } + + if (err != kStatus_Success) + { + return err; + } + } + + status = I2C_PendingStatusWait(base); + if (status == kStatus_I2C_Timeout) + { + return kStatus_I2C_Timeout; + } + + if ((status & (I2C_STAT_MSTARBLOSS_MASK | I2C_STAT_MSTSTSTPERR_MASK)) == 0) + { + if (!(flags & kI2C_TransferNoStopFlag)) + { + /* Initiate stop */ + base->MSTCTL = I2C_MSTCTL_MSTSTOP_MASK; + status = I2C_PendingStatusWait(base); + if (status == kStatus_I2C_Timeout) + { + return kStatus_I2C_Timeout; + } + } + } + + if (status & I2C_STAT_MSTARBLOSS_MASK) + { + return kStatus_I2C_ArbitrationLost; + } + + if (status & I2C_STAT_MSTSTSTPERR_MASK) + { + return kStatus_I2C_StartStopError; + } + + return kStatus_Success; +} + +status_t I2C_MasterReadBlocking(I2C_Type *base, void *rxBuff, size_t rxSize, uint32_t flags) +{ + uint32_t status = 0; + uint32_t master_state; + status_t err; + + uint8_t *buf = (uint8_t *)(rxBuff); + + assert(rxBuff); + + err = kStatus_Success; + while (rxSize) + { + status = I2C_PendingStatusWait(base); + if (status == kStatus_I2C_Timeout) + { + return kStatus_I2C_Timeout; + } + + if (status & (I2C_STAT_MSTARBLOSS_MASK | I2C_STAT_MSTSTSTPERR_MASK)) + { + break; + } + + master_state = (status & I2C_STAT_MSTSTATE_MASK) >> I2C_STAT_MSTSTATE_SHIFT; + switch (master_state) + { + case I2C_STAT_MSTCODE_RXREADY: + /* ready to receive next byte */ + *(buf++) = base->MSTDAT; + if (--rxSize) + { + base->MSTCTL = I2C_MSTCTL_MSTCONTINUE_MASK; + } + else + { + if ((flags & kI2C_TransferNoStopFlag) == 0) + { + /* initiate NAK and stop */ + base->MSTCTL = I2C_MSTCTL_MSTSTOP_MASK; + status = I2C_PendingStatusWait(base); + if (status == kStatus_I2C_Timeout) + { + return kStatus_I2C_Timeout; + } + } + } + break; + + case I2C_STAT_MSTCODE_NACKADR: + case I2C_STAT_MSTCODE_NACKDAT: + /* slave nacked the last byte */ + err = kStatus_I2C_Nak; + break; + + default: + /* unexpected state */ + err = kStatus_I2C_UnexpectedState; + break; + } + + if (err != kStatus_Success) + { + return err; + } + } + + if (status & I2C_STAT_MSTARBLOSS_MASK) + { + return kStatus_I2C_ArbitrationLost; + } + + if (status & I2C_STAT_MSTSTSTPERR_MASK) + { + return kStatus_I2C_StartStopError; + } + + return kStatus_Success; +} + +status_t I2C_MasterTransferBlocking(I2C_Type *base, i2c_master_transfer_t *xfer) +{ + status_t result = kStatus_Success; + uint32_t subaddress; + uint8_t subaddrBuf[4]; + int i; + + assert(xfer); + + /* If repeated start is requested, send repeated start. */ + if (!(xfer->flags & kI2C_TransferNoStartFlag)) + { + if (xfer->subaddressSize) + { + result = I2C_MasterStart(base, xfer->slaveAddress, kI2C_Write); + if (result == kStatus_Success) + { + /* Prepare subaddress transmit buffer, most significant byte is stored at the lowest address */ + subaddress = xfer->subaddress; + for (i = xfer->subaddressSize - 1; i >= 0; i--) + { + subaddrBuf[i] = subaddress & 0xff; + subaddress >>= 8; + } + /* Send subaddress. */ + result = I2C_MasterWriteBlocking(base, subaddrBuf, xfer->subaddressSize, kI2C_TransferNoStopFlag); + if ((result == kStatus_Success) && (xfer->direction == kI2C_Read)) + { + result = I2C_MasterRepeatedStart(base, xfer->slaveAddress, xfer->direction); + } + } + } + else if (xfer->flags & kI2C_TransferRepeatedStartFlag) + { + result = I2C_MasterRepeatedStart(base, xfer->slaveAddress, xfer->direction); + } + else + { + result = I2C_MasterStart(base, xfer->slaveAddress, xfer->direction); + } + } + + if (result == kStatus_Success) + { + if ((xfer->direction == kI2C_Write) && (xfer->dataSize > 0)) + { + /* Transmit data. */ + result = I2C_MasterWriteBlocking(base, xfer->data, xfer->dataSize, xfer->flags); + } + else + { + if ((xfer->direction == kI2C_Read) && (xfer->dataSize > 0)) + { + /* Receive Data. */ + result = I2C_MasterReadBlocking(base, xfer->data, xfer->dataSize, xfer->flags); + } + } + } + + if (result == kStatus_I2C_Nak) + { + I2C_MasterStop(base); + } + + return result; +} + +void I2C_MasterTransferCreateHandle(I2C_Type *base, + i2c_master_handle_t *handle, + i2c_master_transfer_callback_t callback, + void *userData) +{ + uint32_t instance; + + assert(handle); + + /* Clear out the handle. */ + memset(handle, 0, sizeof(*handle)); + + /* Look up instance number */ + instance = I2C_GetInstance(base); + + /* Save base and instance. */ + handle->completionCallback = callback; + handle->userData = userData; + + /* Save the context in global variables to support the double weak mechanism. */ + s_i2cHandle[instance] = handle; + + /* Save master interrupt handler. */ + s_i2cMasterIsr = I2C_MasterTransferHandleIRQ; + + /* Clear internal IRQ enables and enable NVIC IRQ. */ + I2C_DisableInterrupts(base, kI2C_MasterIrqFlags); + EnableIRQ(s_i2cIRQ[instance]); +} + +status_t I2C_MasterTransferNonBlocking(I2C_Type *base, i2c_master_handle_t *handle, i2c_master_transfer_t *xfer) +{ + status_t result; + + assert(handle); + assert(xfer); + assert(xfer->subaddressSize <= sizeof(xfer->subaddress)); + + /* Return busy if another transaction is in progress. */ + if (handle->state != kIdleState) + { + return kStatus_I2C_Busy; + } + + /* Disable I2C IRQ sources while we configure stuff. */ + I2C_DisableInterrupts(base, kI2C_MasterIrqFlags); + + /* Prepare transfer state machine. */ + result = I2C_InitTransferStateMachine(base, handle, xfer); + + /* Clear error flags. */ + I2C_MasterClearStatusFlags(base, I2C_STAT_MSTARBLOSS_MASK | I2C_STAT_MSTSTSTPERR_MASK); + + /* Enable I2C internal IRQ sources. */ + I2C_EnableInterrupts(base, kI2C_MasterIrqFlags); + + return result; +} + +status_t I2C_MasterTransferGetCount(I2C_Type *base, i2c_master_handle_t *handle, size_t *count) +{ + assert(handle); + + if (!count) + { + return kStatus_InvalidArgument; + } + + /* Catch when there is not an active transfer. */ + if (handle->state == kIdleState) + { + *count = 0; + return kStatus_NoTransferInProgress; + } + + /* There is no necessity to disable interrupts as we read a single integer value */ + *count = handle->transferCount; + return kStatus_Success; +} + +status_t I2C_MasterTransferAbort(I2C_Type *base, i2c_master_handle_t *handle) +{ + uint32_t status; + uint32_t master_state; + + if (handle->state != kIdleState) + { + /* Disable internal IRQ enables. */ + I2C_DisableInterrupts(base, kI2C_MasterIrqFlags); + + /* Wait until module is ready */ + status = I2C_PendingStatusWait(base); + if (status == kStatus_I2C_Timeout) + { + return kStatus_I2C_Timeout; + } + + /* Get the state of the I2C module */ + master_state = (status & I2C_STAT_MSTSTATE_MASK) >> I2C_STAT_MSTSTATE_SHIFT; + + if (master_state != I2C_STAT_MSTCODE_IDLE) + { + /* Send a stop command to finalize the transfer. */ + base->MSTCTL = I2C_MSTCTL_MSTSTOP_MASK; + + /* Wait until the STOP is completed */ + I2C_PendingStatusWait(base); + if (status == kStatus_I2C_Timeout) + { + return kStatus_I2C_Timeout; + } + } + + /* Reset handle. */ + handle->state = kIdleState; + } + + return kStatus_Success; +} + +/*! + * @brief Prepares the transfer state machine and fills in the command buffer. + * @param handle Master nonblocking driver handle. + */ +static status_t I2C_InitTransferStateMachine(I2C_Type *base, i2c_master_handle_t *handle, i2c_master_transfer_t *xfer) +{ + struct _i2c_master_transfer *transfer; + + handle->transfer = *xfer; + transfer = &(handle->transfer); + + handle->transferCount = 0; + handle->remainingBytes = transfer->dataSize; + handle->buf = (uint8_t *)transfer->data; + handle->remainingSubaddr = 0; + + if (transfer->flags & kI2C_TransferNoStartFlag) + { + /* Start condition shall be ommited, switch directly to next phase */ + if (transfer->dataSize == 0) + { + handle->state = kStopState; + } + else if (handle->transfer.direction == kI2C_Write) + { + handle->state = kTransmitDataState; + } + else if (handle->transfer.direction == kI2C_Read) + { + handle->state = kReceiveDataState; + } + else + { + return kStatus_I2C_InvalidParameter; + } + } + else + { + if (transfer->subaddressSize != 0) + { + int i; + uint32_t subaddress; + + if (transfer->subaddressSize > sizeof(handle->subaddrBuf)) + { + return kStatus_I2C_InvalidParameter; + } + + /* Prepare subaddress transmit buffer, most significant byte is stored at the lowest address */ + subaddress = xfer->subaddress; + for (i = xfer->subaddressSize - 1; i >= 0; i--) + { + handle->subaddrBuf[i] = subaddress & 0xff; + subaddress >>= 8; + } + handle->remainingSubaddr = transfer->subaddressSize; + } + handle->state = kStartState; + } + + return kStatus_Success; +} + +/*! + * @brief Execute states until FIFOs are exhausted. + * @param handle Master nonblocking driver handle. + * @param[out] isDone Set to true if the transfer has completed. + * @retval #kStatus_Success + * @retval #kStatus_I2C_ArbitrationLost + * @retval #kStatus_I2C_Nak + */ +static status_t I2C_RunTransferStateMachine(I2C_Type *base, i2c_master_handle_t *handle, bool *isDone) +{ + uint32_t status; + uint32_t master_state; + struct _i2c_master_transfer *transfer; + status_t err; + + transfer = &(handle->transfer); + + *isDone = false; + + status = I2C_GetStatusFlags(base); + + if (status & I2C_STAT_MSTARBLOSS_MASK) + { + I2C_MasterClearStatusFlags(base, I2C_STAT_MSTARBLOSS_MASK); + return kStatus_I2C_ArbitrationLost; + } + + if (status & I2C_STAT_MSTSTSTPERR_MASK) + { + I2C_MasterClearStatusFlags(base, I2C_STAT_MSTSTSTPERR_MASK); + return kStatus_I2C_StartStopError; + } + + if ((status & I2C_STAT_MSTPENDING_MASK) == 0) + { + return kStatus_I2C_Busy; + } + + /* Get the state of the I2C module */ + master_state = (status & I2C_STAT_MSTSTATE_MASK) >> I2C_STAT_MSTSTATE_SHIFT; + + if ((master_state == I2C_STAT_MSTCODE_NACKADR) || (master_state == I2C_STAT_MSTCODE_NACKDAT)) + { + /* Slave NACKed last byte, issue stop and return error */ + base->MSTCTL = I2C_MSTCTL_MSTSTOP_MASK; + handle->state = kWaitForCompletionState; + return kStatus_I2C_Nak; + } + + err = kStatus_Success; + switch (handle->state) + { + case kStartState: + if (handle->remainingSubaddr) + { + /* Subaddress takes precedence over the data transfer, direction is always "write" in this case */ + base->MSTDAT = (uint32_t)transfer->slaveAddress << 1; + handle->state = kTransmitSubaddrState; + } + else if (transfer->direction == kI2C_Write) + { + base->MSTDAT = (uint32_t)transfer->slaveAddress << 1; + handle->state = handle->remainingBytes ? kTransmitDataState : kStopState; + } + else + { + base->MSTDAT = ((uint32_t)transfer->slaveAddress << 1) | 1u; + handle->state = handle->remainingBytes ? kReceiveDataState : kStopState; + } + /* Send start condition */ + base->MSTCTL = I2C_MSTCTL_MSTSTART_MASK; + break; + + case kTransmitSubaddrState: + if (master_state != I2C_STAT_MSTCODE_TXREADY) + { + return kStatus_I2C_UnexpectedState; + } + + /* Most significant subaddress byte comes first */ + base->MSTDAT = handle->subaddrBuf[handle->transfer.subaddressSize - handle->remainingSubaddr]; + base->MSTCTL = I2C_MSTCTL_MSTCONTINUE_MASK; + if (--(handle->remainingSubaddr)) + { + /* There are still subaddress bytes to be transmitted */ + break; + } + if (handle->remainingBytes) + { + /* There is data to be transferred, if there is write to read turnaround it is necessary to perform + * repeated start */ + handle->state = (transfer->direction == kI2C_Read) ? kStartState : kTransmitDataState; + } + else + { + /* No more data, schedule stop condition */ + handle->state = kStopState; + } + break; + + case kTransmitDataState: + if (master_state != I2C_STAT_MSTCODE_TXREADY) + { + return kStatus_I2C_UnexpectedState; + } + base->MSTDAT = *(handle->buf)++; + base->MSTCTL = I2C_MSTCTL_MSTCONTINUE_MASK; + if (--handle->remainingBytes == 0) + { + /* No more data, schedule stop condition */ + handle->state = kStopState; + } + handle->transferCount++; + break; + + case kReceiveDataState: + if (master_state != I2C_STAT_MSTCODE_RXREADY) + { + return kStatus_I2C_UnexpectedState; + } + *(handle->buf)++ = base->MSTDAT; + if (--handle->remainingBytes) + { + base->MSTCTL = I2C_MSTCTL_MSTCONTINUE_MASK; + } + else + { + /* No more data expected, issue NACK and STOP right away */ + base->MSTCTL = I2C_MSTCTL_MSTSTOP_MASK; + handle->state = kWaitForCompletionState; + } + handle->transferCount++; + break; + + case kStopState: + if (transfer->flags & kI2C_TransferNoStopFlag) + { + /* Stop condition is omitted, we are done */ + *isDone = true; + handle->state = kIdleState; + break; + } + /* Send stop condition */ + base->MSTCTL = I2C_MSTCTL_MSTSTOP_MASK; + handle->state = kWaitForCompletionState; + break; + + case kWaitForCompletionState: + *isDone = true; + handle->state = kIdleState; + break; + + case kIdleState: + default: + /* State machine shall not be invoked again once it enters the idle state */ + err = kStatus_I2C_UnexpectedState; + break; + } + + return err; +} + +void I2C_MasterTransferHandleIRQ(I2C_Type *base, void *i2cHandle) +{ + assert(i2cHandle); + + i2c_master_handle_t *handle = (i2c_master_handle_t *)i2cHandle; + bool isDone; + status_t result; + + result = I2C_RunTransferStateMachine(base, handle, &isDone); + + if (isDone || (result != kStatus_Success)) + { + /* Disable internal IRQ enables. */ + I2C_DisableInterrupts(base, kI2C_MasterIrqFlags); + + /* Invoke callback. */ + if (handle->completionCallback) + { + handle->completionCallback(base, handle, result, handle->userData); + } + } +} + +/*! + * @brief Sets the hardware slave state machine to reset + * + * Per documentation, the only the state machine is reset, the configuration settings remain. + * + * @param base The I2C peripheral base address. + */ +static void I2C_SlaveInternalStateMachineReset(I2C_Type *base) +{ + I2C_SlaveEnable(base, false); /* clear SLVEN Slave enable bit */ +} + +/*! + * @brief Compute CLKDIV + * + * This function computes CLKDIV value according to the given bus speed and Flexcomm source clock frequency. + * This setting is used by hardware during slave clock stretching. + * + * @param base The I2C peripheral base address. + * @return status of the operation + */ +static status_t I2C_SlaveDivVal(uint32_t srcClock_Hz, i2c_slave_bus_speed_t busSpeed, uint32_t *divVal) +{ + uint32_t dataSetupTime_ns; + + switch (busSpeed) + { + case kI2C_SlaveStandardMode: + dataSetupTime_ns = 250u; + break; + + case kI2C_SlaveFastMode: + dataSetupTime_ns = 100u; + break; + + case kI2C_SlaveFastModePlus: + dataSetupTime_ns = 50u; + break; + + case kI2C_SlaveHsMode: + dataSetupTime_ns = 10u; + break; + + default: + dataSetupTime_ns = 0; + break; + } + + if (0 == dataSetupTime_ns) + { + return kStatus_InvalidArgument; + } + + /* divVal = (sourceClock_Hz / 1000000) * (dataSetupTime_ns / 1000) */ + *divVal = srcClock_Hz / 1000u; + *divVal = (*divVal) * dataSetupTime_ns; + *divVal = (*divVal) / 1000000u; + + if ((*divVal) > I2C_CLKDIV_DIVVAL_MASK) + { + *divVal = I2C_CLKDIV_DIVVAL_MASK; + } + + return kStatus_Success; +} + +/*! + * @brief Poll wait for the SLVPENDING flag. + * + * Wait for the pending status to be set (SLVPENDING = 1) by polling the STAT register. + * + * @param base The I2C peripheral base address. + * @return status register at time the SLVPENDING bit is read as set + */ +static uint32_t I2C_SlavePollPending(I2C_Type *base) +{ + uint32_t stat; + +#if I2C_WAIT_TIMEOUT + uint32_t waitTimes = I2C_WAIT_TIMEOUT; +#endif + + do + { + stat = base->STAT; +#if I2C_WAIT_TIMEOUT + } while ((0u == (stat & I2C_STAT_SLVPENDING_MASK)) && (--waitTimes)); + + if (waitTimes == 0u) + { + return kStatus_I2C_Timeout; + } +#else + } while (0u == (stat & I2C_STAT_SLVPENDING_MASK)); +#endif + return stat; +} + +/*! + * @brief Invoke event from I2C_SlaveTransferHandleIRQ(). + * + * Sets the event type to transfer structure and invokes the event callback, if it has been + * enabled by eventMask. + * + * @param base The I2C peripheral base address. + * @param handle The I2C slave handle for non-blocking APIs. + * @param event The I2C slave event to invoke. + */ +static void I2C_SlaveInvokeEvent(I2C_Type *base, i2c_slave_handle_t *handle, i2c_slave_transfer_event_t event) +{ + handle->transfer.event = event; + if ((handle->callback) && (handle->transfer.eventMask & event)) + { + handle->callback(base, &handle->transfer, handle->userData); + + /* if after event callback we have data buffer (callback func has added new data), keep transfer busy */ + if (false == handle->isBusy) + { + if (((handle->transfer.txData) && (handle->transfer.txSize)) || + ((handle->transfer.rxData) && (handle->transfer.rxSize))) + { + handle->isBusy = true; + } + } + + /* Clear the transferred count now that we have a new buffer. */ + if ((event == kI2C_SlaveReceiveEvent) || (event == kI2C_SlaveTransmitEvent)) + { + handle->transfer.transferredCount = 0; + } + } +} + +/*! + * @brief Handle slave address match event. + * + * Called by Slave interrupt routine to ACK or NACK the matched address. + * It also determines master direction (read or write). + * + * @param base The I2C peripheral base address. + * @return true if the matched address is ACK'ed + * @return false if the matched address is NACK'ed + */ +static bool I2C_SlaveAddressIRQ(I2C_Type *base, i2c_slave_handle_t *handle) +{ + uint8_t addressByte0; + + addressByte0 = (uint8_t)base->SLVDAT; + + /* store the matched address */ + handle->transfer.receivedAddress = addressByte0; + + /* R/nW */ + if (addressByte0 & 1u) + { + /* if we have no data in this transfer, call callback to get new */ + if ((handle->transfer.txData == NULL) || (handle->transfer.txSize == 0)) + { + I2C_SlaveInvokeEvent(base, handle, kI2C_SlaveTransmitEvent); + } + + /* NACK if we have no data in this transfer. */ + if ((handle->transfer.txData == NULL) || (handle->transfer.txSize == 0)) + { + base->SLVCTL = I2C_SLVCTL_SLVNACK_MASK; + return false; + } + + /* master wants to read, so slave transmit is next state */ + handle->slaveFsm = kI2C_SlaveFsmTransmit; + } + else + { + /* if we have no receive buffer in this transfer, call callback to get new */ + if ((handle->transfer.rxData == NULL) || (handle->transfer.rxSize == 0)) + { + I2C_SlaveInvokeEvent(base, handle, kI2C_SlaveReceiveEvent); + } + + /* NACK if we have no data in this transfer */ + if ((handle->transfer.rxData == NULL) || (handle->transfer.rxSize == 0)) + { + base->SLVCTL = I2C_SLVCTL_SLVNACK_MASK; + return false; + } + + /* master wants write, so slave receive is next state */ + handle->slaveFsm = kI2C_SlaveFsmReceive; + } + + /* continue transaction */ + base->SLVCTL = I2C_SLVCTL_SLVCONTINUE_MASK; + + return true; +} + +/*! + * @brief Starts accepting slave transfers. + * + * Call this API after calling I2C_SlaveInit() and I2C_SlaveTransferCreateHandle() to start processing + * transactions driven by an I2C master. The slave monitors the I2C bus and pass events to the + * callback that was passed into the call to I2C_SlaveTransferCreateHandle(). The callback is always invoked + * from the interrupt context. + * + * @param base The I2C peripheral base address. + * @param handle Pointer to #i2c_slave_handle_t structure which stores the transfer state. + * @param txData Data to be transmitted to master in response to master read from slave requests. NULL if slave RX only. + * @param txSize Size of txData buffer in bytes. + * @param rxData Data where received data from master will be stored in response to master write to slave requests. NULL + * if slave TX only. + * @param rxSize Size of rxData buffer in bytes. + * + * @retval #kStatus_Success Slave transfers were successfully started. + * @retval #kStatus_I2C_Busy Slave transfers have already been started on this handle. + */ +static status_t I2C_SlaveTransferNonBlockingInternal(I2C_Type *base, + i2c_slave_handle_t *handle, + const void *txData, + size_t txSize, + void *rxData, + size_t rxSize, + uint32_t eventMask) +{ + status_t status; + + assert(handle); + + status = kStatus_Success; + + /* Disable I2C IRQ sources while we configure stuff. */ + I2C_DisableInterrupts(base, kI2C_SlaveIrqFlags); + + /* Return busy if another transaction is in progress. */ + if (handle->isBusy) + { + status = kStatus_I2C_Busy; + } + + /* Save transfer into handle. */ + handle->transfer.txData = (const uint8_t *)(uintptr_t)txData; + handle->transfer.txSize = txSize; + handle->transfer.rxData = (uint8_t *)rxData; + handle->transfer.rxSize = rxSize; + handle->transfer.transferredCount = 0; + handle->transfer.eventMask = eventMask | kI2C_SlaveTransmitEvent | kI2C_SlaveReceiveEvent; + handle->isBusy = true; + + /* Set the SLVEN bit to 1 in the CFG register. */ + I2C_SlaveEnable(base, true); + + /* Clear w1c flags. */ + base->STAT |= 0u; + + /* Enable I2C internal IRQ sources. */ + I2C_EnableInterrupts(base, kI2C_SlaveIrqFlags); + + return status; +} + +status_t I2C_SlaveSetSendBuffer( + I2C_Type *base, volatile i2c_slave_transfer_t *transfer, const void *txData, size_t txSize, uint32_t eventMask) +{ + return I2C_SlaveTransferNonBlockingInternal(base, transfer->handle, txData, txSize, NULL, 0u, eventMask); +} + +status_t I2C_SlaveSetReceiveBuffer( + I2C_Type *base, volatile i2c_slave_transfer_t *transfer, void *rxData, size_t rxSize, uint32_t eventMask) +{ + return I2C_SlaveTransferNonBlockingInternal(base, transfer->handle, NULL, 0u, rxData, rxSize, eventMask); +} + +void I2C_SlaveSetAddress(I2C_Type *base, + i2c_slave_address_register_t addressRegister, + uint8_t address, + bool addressDisable) +{ + base->SLVADR[addressRegister] = I2C_SLVADR_SLVADR(address) | I2C_SLVADR_SADISABLE(addressDisable); +} + +void I2C_SlaveGetDefaultConfig(i2c_slave_config_t *slaveConfig) +{ + assert(slaveConfig); + + i2c_slave_config_t mySlaveConfig = {0}; + + /* default config enables slave address 0 match to general I2C call address zero */ + mySlaveConfig.enableSlave = true; + mySlaveConfig.address1.addressDisable = true; + mySlaveConfig.address2.addressDisable = true; + mySlaveConfig.address3.addressDisable = true; + + *slaveConfig = mySlaveConfig; +} + +status_t I2C_SlaveInit(I2C_Type *base, const i2c_slave_config_t *slaveConfig, uint32_t srcClock_Hz) +{ + status_t status; + uint32_t divVal = 0; + + /* Enable I2C clock. */ + CLOCK_EnableClock(s_i2cClocks[I2C_GetInstance(base)]); + + /* configure data setup time used when slave stretches clock */ + status = I2C_SlaveDivVal(srcClock_Hz, slaveConfig->busSpeed, &divVal); + if (kStatus_Success != status) + { + return status; + } + + /* I2C Clock Divider register */ + base->CLKDIV = divVal; + + /* set Slave address */ + I2C_SlaveSetAddress(base, kI2C_SlaveAddressRegister0, slaveConfig->address0.address, + slaveConfig->address0.addressDisable); + I2C_SlaveSetAddress(base, kI2C_SlaveAddressRegister1, slaveConfig->address1.address, + slaveConfig->address1.addressDisable); + I2C_SlaveSetAddress(base, kI2C_SlaveAddressRegister2, slaveConfig->address2.address, + slaveConfig->address2.addressDisable); + I2C_SlaveSetAddress(base, kI2C_SlaveAddressRegister3, slaveConfig->address3.address, + slaveConfig->address3.addressDisable); + + /* set Slave address 0 qual */ + base->SLVQUAL0 = I2C_SLVQUAL0_QUALMODE0(slaveConfig->qualMode) | I2C_SLVQUAL0_SLVQUAL0(slaveConfig->qualAddress); + + /* set Slave enable */ + base->CFG = I2C_CFG_SLVEN(slaveConfig->enableSlave); + + return status; +} + +void I2C_SlaveDeinit(I2C_Type *base) +{ + I2C_SlaveEnable(base, false); + /* Disable I2C clock. */ + CLOCK_DisableClock(s_i2cClocks[I2C_GetInstance(base)]); +} + +status_t I2C_SlaveWriteBlocking(I2C_Type *base, const uint8_t *txBuff, size_t txSize) +{ + const uint8_t *buf = txBuff; + uint32_t stat; + bool slaveAddress; + bool slaveTransmit; + + /* Set the SLVEN bit to 1 in the CFG register. */ + I2C_SlaveEnable(base, true); + + /* wait for SLVPENDING */ + stat = I2C_SlavePollPending(base); + if (stat == kStatus_I2C_Timeout) + { + return kStatus_I2C_Timeout; + } + + /* Get slave machine state */ + slaveAddress = (((stat & I2C_STAT_SLVSTATE_MASK) >> I2C_STAT_SLVSTATE_SHIFT) == I2C_STAT_SLVST_ADDR); + slaveTransmit = (((stat & I2C_STAT_SLVSTATE_MASK) >> I2C_STAT_SLVSTATE_SHIFT) == I2C_STAT_SLVST_TX); + + /* in I2C_SlaveSend() it shall be either slaveAddress or slaveTransmit */ + if (!(slaveAddress || slaveTransmit)) + { + I2C_SlaveInternalStateMachineReset(base); + return kStatus_Fail; + } + + if (slaveAddress) + { + /* Acknowledge (ack) the address by setting SLVCONTINUE = 1 in the slave control register */ + base->SLVCTL = I2C_SLVCTL_SLVCONTINUE_MASK; + + /* wait for SLVPENDING */ + stat = I2C_SlavePollPending(base); + if (stat == kStatus_I2C_Timeout) + { + return kStatus_I2C_Timeout; + } + } + + /* send bytes up to txSize */ + while (txSize) + { + slaveTransmit = (((stat & I2C_STAT_SLVSTATE_MASK) >> I2C_STAT_SLVSTATE_SHIFT) == I2C_STAT_SLVST_TX); + + if (!slaveTransmit) + { + I2C_SlaveInternalStateMachineReset(base); + return kStatus_Fail; + } + + /* Write 8 bits of data to the SLVDAT register */ + base->SLVDAT = I2C_SLVDAT_DATA(*buf); + + /* continue transaction */ + base->SLVCTL = I2C_SLVCTL_SLVCONTINUE_MASK; + + /* advance counters and pointers for next data */ + buf++; + txSize--; + + if (txSize) + { + /* wait for SLVPENDING */ + stat = I2C_SlavePollPending(base); + if (stat == kStatus_I2C_Timeout) + { + return kStatus_I2C_Timeout; + } + } + } + + return kStatus_Success; +} + +status_t I2C_SlaveReadBlocking(I2C_Type *base, uint8_t *rxBuff, size_t rxSize) +{ + uint8_t *buf = rxBuff; + uint32_t stat; + bool slaveAddress; + bool slaveReceive; + + /* Set the SLVEN bit to 1 in the CFG register. */ + I2C_SlaveEnable(base, true); + + /* wait for SLVPENDING */ + stat = I2C_SlavePollPending(base); + if (stat == kStatus_I2C_Timeout) + { + return kStatus_I2C_Timeout; + } + + /* Get slave machine state */ + slaveAddress = (((stat & I2C_STAT_SLVSTATE_MASK) >> I2C_STAT_SLVSTATE_SHIFT) == I2C_STAT_SLVST_ADDR); + slaveReceive = (((stat & I2C_STAT_SLVSTATE_MASK) >> I2C_STAT_SLVSTATE_SHIFT) == I2C_STAT_SLVST_RX); + + /* in I2C_SlaveReceive() it shall be either slaveAddress or slaveReceive */ + if (!(slaveAddress || slaveReceive)) + { + I2C_SlaveInternalStateMachineReset(base); + return kStatus_Fail; + } + + if (slaveAddress) + { + /* Acknowledge (ack) the address by setting SLVCONTINUE = 1 in the slave control register */ + base->SLVCTL = I2C_SLVCTL_SLVCONTINUE_MASK; + + /* wait for SLVPENDING */ + stat = I2C_SlavePollPending(base); + if (stat == kStatus_I2C_Timeout) + { + return kStatus_I2C_Timeout; + } + } + + /* receive bytes up to rxSize */ + while (rxSize) + { + slaveReceive = (((stat & I2C_STAT_SLVSTATE_MASK) >> I2C_STAT_SLVSTATE_SHIFT) == I2C_STAT_SLVST_RX); + + if (!slaveReceive) + { + I2C_SlaveInternalStateMachineReset(base); + return kStatus_Fail; + } + + /* Read 8 bits of data from the SLVDAT register */ + *buf = (uint8_t)base->SLVDAT; + + /* continue transaction */ + base->SLVCTL = I2C_SLVCTL_SLVCONTINUE_MASK; + + /* advance counters and pointers for next data */ + buf++; + rxSize--; + + if (rxSize) + { + /* wait for SLVPENDING */ + stat = I2C_SlavePollPending(base); + if (stat == kStatus_I2C_Timeout) + { + return kStatus_I2C_Timeout; + } + } + } + + return kStatus_Success; +} + +void I2C_SlaveTransferCreateHandle(I2C_Type *base, + i2c_slave_handle_t *handle, + i2c_slave_transfer_callback_t callback, + void *userData) +{ + uint32_t instance; + + assert(handle); + + /* Clear out the handle. */ + memset(handle, 0, sizeof(*handle)); + + /* Look up instance number */ + instance = I2C_GetInstance(base); + + /* Save base and instance. */ + handle->callback = callback; + handle->userData = userData; + + /* initialize fsm */ + handle->slaveFsm = kI2C_SlaveFsmAddressMatch; + + /* store pointer to handle into transfer struct */ + handle->transfer.handle = handle; + + /* Save the context in global variables to support the double weak mechanism. */ + s_i2cHandle[instance] = handle; + + /* Save slave interrupt handler. */ + s_i2cSlaveIsr = I2C_SlaveTransferHandleIRQ; + + /* Clear internal IRQ enables and enable NVIC IRQ. */ + I2C_DisableInterrupts(base, kI2C_SlaveIrqFlags); + EnableIRQ(s_i2cIRQ[instance]); +} + +status_t I2C_SlaveTransferNonBlocking(I2C_Type *base, i2c_slave_handle_t *handle, uint32_t eventMask) +{ + return I2C_SlaveTransferNonBlockingInternal(base, handle, NULL, 0u, NULL, 0u, eventMask); +} + +status_t I2C_SlaveTransferGetCount(I2C_Type *base, i2c_slave_handle_t *handle, size_t *count) +{ + assert(handle); + + if (!count) + { + return kStatus_InvalidArgument; + } + + /* Catch when there is not an active transfer. */ + if (!handle->isBusy) + { + *count = 0; + return kStatus_NoTransferInProgress; + } + + /* For an active transfer, just return the count from the handle. */ + *count = handle->transfer.transferredCount; + + return kStatus_Success; +} + +void I2C_SlaveTransferAbort(I2C_Type *base, i2c_slave_handle_t *handle) +{ + /* Disable I2C IRQ sources while we configure stuff. */ + I2C_DisableInterrupts(base, kI2C_SlaveIrqFlags); + + /* Set the SLVEN bit to 0 in the CFG register. */ + I2C_SlaveEnable(base, false); + + handle->isBusy = false; + handle->transfer.txSize = 0; + handle->transfer.rxSize = 0; +} + +void I2C_SlaveTransferHandleIRQ(I2C_Type *base, void *i2cHandle) +{ + assert(i2cHandle); + + i2c_slave_handle_t *handle = (i2c_slave_handle_t *)i2cHandle; + uint32_t i2cStatus = base->STAT; + + if (i2cStatus & I2C_STAT_SLVDESEL_MASK) + { + I2C_SlaveInvokeEvent(base, handle, kI2C_SlaveDeselectedEvent); + I2C_SlaveClearStatusFlags(base, I2C_STAT_SLVDESEL_MASK); + } + + /* SLVPENDING flag is cleared by writing I2C_SLVCTL_SLVCONTINUE_MASK to SLVCTL register */ + if (i2cStatus & I2C_STAT_SLVPENDING_MASK) + { + bool slaveAddress = (((i2cStatus & I2C_STAT_SLVSTATE_MASK) >> I2C_STAT_SLVSTATE_SHIFT) == I2C_STAT_SLVST_ADDR); + + if (slaveAddress) + { + I2C_SlaveAddressIRQ(base, handle); + I2C_SlaveInvokeEvent(base, handle, kI2C_SlaveAddressMatchEvent); + } + else + { + switch (handle->slaveFsm) + { + case kI2C_SlaveFsmReceive: + { + bool slaveReceive = + (((i2cStatus & I2C_STAT_SLVSTATE_MASK) >> I2C_STAT_SLVSTATE_SHIFT) == I2C_STAT_SLVST_RX); + + if (slaveReceive) + { + /* if we have no receive buffer in this transfer, call callback to get new */ + if ((handle->transfer.rxData == NULL) || (handle->transfer.rxSize == 0)) + { + I2C_SlaveInvokeEvent(base, handle, kI2C_SlaveReceiveEvent); + } + + /* receive a byte */ + if ((handle->transfer.rxData) && (handle->transfer.rxSize)) + { + *(handle->transfer.rxData) = (uint8_t)base->SLVDAT; + (handle->transfer.rxSize)--; + (handle->transfer.rxData)++; + (handle->transfer.transferredCount)++; + + /* continue transaction */ + base->SLVCTL = I2C_SLVCTL_SLVCONTINUE_MASK; + } + + /* is this last transaction for this transfer? allow next transaction */ + if ((0 == handle->transfer.rxSize) && (0 == handle->transfer.txSize)) + { + handle->isBusy = false; + I2C_SlaveInvokeEvent(base, handle, kI2C_SlaveCompletionEvent); + } + } + else + { + base->SLVCTL = I2C_SLVCTL_SLVNACK_MASK; + } + } + break; + + case kI2C_SlaveFsmTransmit: + { + bool slaveTransmit = + (((i2cStatus & I2C_STAT_SLVSTATE_MASK) >> I2C_STAT_SLVSTATE_SHIFT) == I2C_STAT_SLVST_TX); + + if (slaveTransmit) + { + /* if we have no data in this transfer, call callback to get new */ + if ((handle->transfer.txData == NULL) || (handle->transfer.txSize == 0)) + { + I2C_SlaveInvokeEvent(base, handle, kI2C_SlaveTransmitEvent); + } + + /* transmit a byte */ + if ((handle->transfer.txData) && (handle->transfer.txSize)) + { + base->SLVDAT = *(handle->transfer.txData); + (handle->transfer.txSize)--; + (handle->transfer.txData)++; + (handle->transfer.transferredCount)++; + + /* continue transaction */ + base->SLVCTL = I2C_SLVCTL_SLVCONTINUE_MASK; + } + + /* is this last transaction for this transfer? allow next transaction */ + if ((0 == handle->transfer.rxSize) && (0 == handle->transfer.txSize)) + { + handle->isBusy = false; + I2C_SlaveInvokeEvent(base, handle, kI2C_SlaveCompletionEvent); + } + } + else + { + base->SLVCTL = I2C_SLVCTL_SLVNACK_MASK; + } + } + break; + + default: + /* incorrect state, slv_abort()? */ + break; + } + } + } +} + +static void I2C_TransferCommonIRQHandler(I2C_Type *base, void *handle) +{ + /* Check if master interrupt. */ + if (base->CFG & I2C_CFG_MSTEN_MASK) + { + s_i2cMasterIsr(base, handle); + } + else + { + s_i2cSlaveIsr(base, handle); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +#if defined(I2C0) +void I2C0_DriverIRQHandler(void) +{ + I2C_TransferCommonIRQHandler(I2C0, s_i2cHandle[0]); +} +#endif + +#if defined(I2C1) +void I2C1_DriverIRQHandler(void) +{ + I2C_TransferCommonIRQHandler(I2C1, s_i2cHandle[1]); +} +#endif + +#if defined(I2C2) +void I2C2_DriverIRQHandler(void) +{ + I2C_TransferCommonIRQHandler(I2C2, s_i2cHandle[2]); +} +#endif diff --git a/platform/mcu/lpc54102/drivers/fsl_i2c.h b/platform/mcu/lpc54102/drivers/fsl_i2c.h new file mode 100644 index 0000000000..3dcdd4174e --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_i2c.h @@ -0,0 +1,1052 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_I2C_H_ +#define _FSL_I2C_H_ + +#include +#include "fsl_device_registers.h" +#include "fsl_common.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +#define I2C_CFG_MASK 0x1f + +/*! + * @addtogroup i2c_driver + * @{ + */ + +/*! @file */ + +/*! @name Driver version */ +/*@{*/ +/*! @brief I2C driver version 2.0.1. */ +#define NXP_I2C_DRIVER_VERSION (MAKE_VERSION(2, 0, 1)) +/*@}*/ + +/*! @brief Timeout times for waiting flag. */ +#ifndef I2C_WAIT_TIMEOUT +#define I2C_WAIT_TIMEOUT 0U /* Define to zero means keep waiting until the flag is assert/deassert. */ +#endif + +/* definitions for MSTCODE bits in I2C Status register STAT */ +#define I2C_STAT_MSTCODE_IDLE (0) /*!< Master Idle State Code */ +#define I2C_STAT_MSTCODE_RXREADY (1) /*!< Master Receive Ready State Code */ +#define I2C_STAT_MSTCODE_TXREADY (2) /*!< Master Transmit Ready State Code */ +#define I2C_STAT_MSTCODE_NACKADR (3) /*!< Master NACK by slave on address State Code */ +#define I2C_STAT_MSTCODE_NACKDAT (4) /*!< Master NACK by slave on data State Code */ + +/* definitions for SLVSTATE bits in I2C Status register STAT */ +#define I2C_STAT_SLVST_ADDR (0) +#define I2C_STAT_SLVST_RX (1) +#define I2C_STAT_SLVST_TX (2) + +/*! @brief I2C status return codes. */ +enum _i2c_status +{ + kStatus_I2C_Busy = MAKE_STATUS(kStatusGroup_LPC_I2C, 0), /*!< The master is already performing a transfer. */ + kStatus_I2C_Idle = MAKE_STATUS(kStatusGroup_LPC_I2C, 1), /*!< The slave driver is idle. */ + kStatus_I2C_Nak = MAKE_STATUS(kStatusGroup_LPC_I2C, 2), /*!< The slave device sent a NAK in response to a byte. */ + kStatus_I2C_InvalidParameter = + MAKE_STATUS(kStatusGroup_LPC_I2C, 3), /*!< Unable to proceed due to invalid parameter. */ + kStatus_I2C_BitError = MAKE_STATUS(kStatusGroup_LPC_I2C, 4), /*!< Transferred bit was not seen on the bus. */ + kStatus_I2C_ArbitrationLost = MAKE_STATUS(kStatusGroup_LPC_I2C, 5), /*!< Arbitration lost error. */ + kStatus_I2C_NoTransferInProgress = + MAKE_STATUS(kStatusGroup_LPC_I2C, 6), /*!< Attempt to abort a transfer when one is not in progress. */ + kStatus_I2C_DmaRequestFail = MAKE_STATUS(kStatusGroup_LPC_I2C, 7), /*!< DMA request failed. */ + kStatus_I2C_StartStopError = MAKE_STATUS(kStatusGroup_LPC_I2C, 8), + kStatus_I2C_UnexpectedState = MAKE_STATUS(kStatusGroup_LPC_I2C, 9), + kStatus_I2C_Addr_Nak = MAKE_STATUS(kStatusGroup_LPC_I2C, 10), /*!< NAK received during the address probe. */ + kStatus_I2C_Timeout = MAKE_STATUS(kStatusGroup_LPC_I2C, 11), /*!< Timeout poling status flags. */ +}; + +/*! @} */ + +/*! + * @addtogroup i2c_master_driver + * @{ + */ + +/*! + * @brief I2C master peripheral flags. + * + * @note These enums are meant to be OR'd together to form a bit mask. + */ +enum _i2c_master_flags +{ + kI2C_MasterPendingFlag = I2C_STAT_MSTPENDING_MASK, /*!< The I2C module is waiting for software interaction. */ + kI2C_MasterArbitrationLostFlag = + I2C_STAT_MSTARBLOSS_MASK, /*!< The arbitration of the bus was lost. There was collision on the bus */ + kI2C_MasterStartStopErrorFlag = + I2C_STAT_MSTSTSTPERR_MASK /*!< There was an error during start or stop phase of the transaction. */ +}; + +/*! @brief Direction of master and slave transfers. */ +typedef enum _i2c_direction +{ + kI2C_Write = 0U, /*!< Master transmit. */ + kI2C_Read = 1U /*!< Master receive. */ +} i2c_direction_t; + +/*! + * @brief Structure with settings to initialize the I2C master module. + * + * This structure holds configuration settings for the I2C peripheral. To initialize this + * structure to reasonable defaults, call the I2C_MasterGetDefaultConfig() function and + * pass a pointer to your configuration structure instance. + * + * The configuration structure can be made constant so it resides in flash. + */ +typedef struct _i2c_master_config +{ + bool enableMaster; /*!< Whether to enable master mode. */ + uint32_t baudRate_Bps; /*!< Desired baud rate in bits per second. */ + bool enableTimeout; /*!< Enable internal timeout function. */ +} i2c_master_config_t; + +/* Forward declaration of the transfer descriptor and handle typedefs. */ +/*! @brief I2C master transfer typedef */ +typedef struct _i2c_master_transfer i2c_master_transfer_t; + +/*! @brief I2C master handle typedef */ +typedef struct _i2c_master_handle i2c_master_handle_t; + +/*! + * @brief Master completion callback function pointer type. + * + * This callback is used only for the non-blocking master transfer API. Specify the callback you wish to use + * in the call to I2C_MasterTransferCreateHandle(). + * + * @param base The I2C peripheral base address. + * @param completionStatus Either kStatus_Success or an error code describing how the transfer completed. + * @param userData Arbitrary pointer-sized value passed from the application. + */ +typedef void (*i2c_master_transfer_callback_t)(I2C_Type *base, + i2c_master_handle_t *handle, + status_t completionStatus, + void *userData); + +/*! + * @brief Transfer option flags. + * + * @note These enumerations are intended to be OR'd together to form a bit mask of options for + * the #_i2c_master_transfer::flags field. + */ +enum _i2c_master_transfer_flags +{ + kI2C_TransferDefaultFlag = 0x00U, /*!< Transfer starts with a start signal, stops with a stop signal. */ + kI2C_TransferNoStartFlag = 0x01U, /*!< Don't send a start condition, address, and sub address */ + kI2C_TransferRepeatedStartFlag = 0x02U, /*!< Send a repeated start condition */ + kI2C_TransferNoStopFlag = 0x04U, /*!< Don't send a stop condition. */ +}; + +/*! @brief States for the state machine used by transactional APIs. */ +enum _i2c_transfer_states +{ + kIdleState = 0, + kTransmitSubaddrState, + kTransmitDataState, + kReceiveDataState, + kReceiveLastDataState, + kStartState, + kStopState, + kWaitForCompletionState +}; + +/*! + * @brief Non-blocking transfer descriptor structure. + * + * This structure is used to pass transaction parameters to the I2C_MasterTransferNonBlocking() API. + */ +struct _i2c_master_transfer +{ + uint32_t flags; /*!< Bit mask of options for the transfer. See enumeration #_i2c_master_transfer_flags for available + options. Set to 0 or #kI2C_TransferDefaultFlag for normal transfers. */ + uint16_t slaveAddress; /*!< The 7-bit slave address. */ + i2c_direction_t direction; /*!< Either #kI2C_Read or #kI2C_Write. */ + uint32_t subaddress; /*!< Sub address. Transferred MSB first. */ + size_t subaddressSize; /*!< Length of sub address to send in bytes. Maximum size is 4 bytes. */ + void *data; /*!< Pointer to data to transfer. */ + size_t dataSize; /*!< Number of bytes to transfer. */ +}; + +/*! + * @brief Driver handle for master non-blocking APIs. + * @note The contents of this structure are private and subject to change. + */ +struct _i2c_master_handle +{ + uint8_t state; /*!< Transfer state machine current state. */ + uint32_t transferCount; /*!< Indicates progress of the transfer */ + uint32_t remainingBytes; /*!< Remaining byte count in current state. */ + uint8_t *buf; /*!< Buffer pointer for current state. */ + uint32_t remainingSubaddr; + uint8_t subaddrBuf[4]; + i2c_master_transfer_t transfer; /*!< Copy of the current transfer info. */ + i2c_master_transfer_callback_t completionCallback; /*!< Callback function pointer. */ + void *userData; /*!< Application data passed to callback. */ +}; + +/*! @} */ + +/*! + * @addtogroup i2c_slave_driver + * @{ + */ + +/*! +* @brief I2C slave peripheral flags. +* +* @note These enums are meant to be OR'd together to form a bit mask. +*/ +enum _i2c_slave_flags +{ + kI2C_SlavePendingFlag = I2C_STAT_SLVPENDING_MASK, /*!< The I2C module is waiting for software interaction. */ + kI2C_SlaveNotStretching = + I2C_STAT_SLVNOTSTR_MASK, /*!< Indicates whether the slave is currently stretching clock (0 = yes, 1 = no). */ + kI2C_SlaveSelected = I2C_STAT_SLVSEL_MASK, /*!< Indicates whether the slave is selected by an address match. */ + kI2C_SaveDeselected = + I2C_STAT_SLVDESEL_MASK /*!< Indicates that slave was previously deselected (deselect event took place, w1c). */ +}; + +/*! @brief I2C slave address register. */ +typedef enum _i2c_slave_address_register +{ + kI2C_SlaveAddressRegister0 = 0U, /*!< Slave Address 0 register. */ + kI2C_SlaveAddressRegister1 = 1U, /*!< Slave Address 1 register. */ + kI2C_SlaveAddressRegister2 = 2U, /*!< Slave Address 2 register. */ + kI2C_SlaveAddressRegister3 = 3U, /*!< Slave Address 3 register. */ +} i2c_slave_address_register_t; + +/*! @brief Data structure with 7-bit Slave address and Slave address disable. */ +typedef struct _i2c_slave_address +{ + uint8_t address; /*!< 7-bit Slave address SLVADR. */ + bool addressDisable; /*!< Slave address disable SADISABLE. */ +} i2c_slave_address_t; + +/*! @brief I2C slave address match options. */ +typedef enum _i2c_slave_address_qual_mode +{ + kI2C_QualModeMask = 0U, /*!< The SLVQUAL0 field (qualAddress) is used as a logical mask for matching address0. */ + kI2C_QualModeExtend = + 1U, /*!< The SLVQUAL0 (qualAddress) field is used to extend address 0 matching in a range of addresses. */ +} i2c_slave_address_qual_mode_t; + +/*! @brief I2C slave bus speed options. */ +typedef enum _i2c_slave_bus_speed +{ + kI2C_SlaveStandardMode = 0U, + kI2C_SlaveFastMode = 1U, + kI2C_SlaveFastModePlus = 2U, + kI2C_SlaveHsMode = 3U, +} i2c_slave_bus_speed_t; + +/*! + * @brief Structure with settings to initialize the I2C slave module. + * + * This structure holds configuration settings for the I2C slave peripheral. To initialize this + * structure to reasonable defaults, call the I2C_SlaveGetDefaultConfig() function and + * pass a pointer to your configuration structure instance. + * + * The configuration structure can be made constant so it resides in flash. + */ +typedef struct _i2c_slave_config +{ + i2c_slave_address_t address0; /*!< Slave's 7-bit address and disable. */ + i2c_slave_address_t address1; /*!< Alternate slave 7-bit address and disable. */ + i2c_slave_address_t address2; /*!< Alternate slave 7-bit address and disable. */ + i2c_slave_address_t address3; /*!< Alternate slave 7-bit address and disable. */ + i2c_slave_address_qual_mode_t qualMode; /*!< Qualify mode for slave address 0. */ + uint8_t qualAddress; /*!< Slave address qualifier for address 0. */ + i2c_slave_bus_speed_t + busSpeed; /*!< Slave bus speed mode. If the slave function stretches SCL to allow for software response, it must + provide sufficient data setup time to the master before releasing the stretched clock. + This is accomplished by inserting one clock time of CLKDIV at that point. + The #busSpeed value is used to configure CLKDIV + such that one clock time is greater than the tSU;DAT value noted + in the I2C bus specification for the I2C mode that is being used. + If the #busSpeed mode is unknown at compile time, use the longest data setup time + kI2C_SlaveStandardMode (250 ns) */ + bool enableSlave; /*!< Enable slave mode. */ +} i2c_slave_config_t; + +/*! + * @brief Set of events sent to the callback for non blocking slave transfers. + * + * These event enumerations are used for two related purposes. First, a bit mask created by OR'ing together + * events is passed to I2C_SlaveTransferNonBlocking() in order to specify which events to enable. + * Then, when the slave callback is invoked, it is passed the current event through its @a transfer + * parameter. + * + * @note These enumerations are meant to be OR'd together to form a bit mask of events. + */ +typedef enum _i2c_slave_transfer_event +{ + kI2C_SlaveAddressMatchEvent = 0x01U, /*!< Received the slave address after a start or repeated start. */ + kI2C_SlaveTransmitEvent = 0x02U, /*!< Callback is requested to provide data to transmit + (slave-transmitter role). */ + kI2C_SlaveReceiveEvent = 0x04U, /*!< Callback is requested to provide a buffer in which to place received + data (slave-receiver role). */ + kI2C_SlaveCompletionEvent = 0x20U, /*!< All data in the active transfer have been consumed. */ + kI2C_SlaveDeselectedEvent = + 0x40U, /*!< The slave function has become deselected (SLVSEL flag changing from 1 to 0. */ + + /*! Bit mask of all available events. */ + kI2C_SlaveAllEvents = kI2C_SlaveAddressMatchEvent | kI2C_SlaveTransmitEvent | kI2C_SlaveReceiveEvent | + kI2C_SlaveCompletionEvent | kI2C_SlaveDeselectedEvent, +} i2c_slave_transfer_event_t; + +/*! @brief I2C slave handle typedef. */ +typedef struct _i2c_slave_handle i2c_slave_handle_t; + +/*! @brief I2C slave transfer structure */ +typedef struct _i2c_slave_transfer +{ + i2c_slave_handle_t *handle; /*!< Pointer to handle that contains this transfer. */ + i2c_slave_transfer_event_t event; /*!< Reason the callback is being invoked. */ + uint8_t receivedAddress; /*!< Matching address send by master. 7-bits plus R/nW bit0 */ + uint32_t eventMask; /*!< Mask of enabled events. */ + uint8_t *rxData; /*!< Transfer buffer for receive data */ + const uint8_t *txData; /*!< Transfer buffer for transmit data */ + size_t txSize; /*!< Transfer size */ + size_t rxSize; /*!< Transfer size */ + size_t transferredCount; /*!< Number of bytes transferred during this transfer. */ + status_t completionStatus; /*!< Success or error code describing how the transfer completed. Only applies for + #kI2C_SlaveCompletionEvent. */ +} i2c_slave_transfer_t; + +/*! + * @brief Slave event callback function pointer type. + * + * This callback is used only for the slave non-blocking transfer API. To install a callback, + * use the I2C_SlaveSetCallback() function after you have created a handle. + * + * @param base Base address for the I2C instance on which the event occurred. + * @param transfer Pointer to transfer descriptor containing values passed to and/or from the callback. + * @param userData Arbitrary pointer-sized value passed from the application. + */ +typedef void (*i2c_slave_transfer_callback_t)(I2C_Type *base, volatile i2c_slave_transfer_t *transfer, void *userData); + +/*! + * @brief I2C slave software finite state machine states. + */ +typedef enum _i2c_slave_fsm +{ + kI2C_SlaveFsmAddressMatch = 0u, + kI2C_SlaveFsmReceive = 2u, + kI2C_SlaveFsmTransmit = 3u, +} i2c_slave_fsm_t; + +/*! + * @brief I2C slave handle structure. + * @note The contents of this structure are private and subject to change. + */ +struct _i2c_slave_handle +{ + volatile i2c_slave_transfer_t transfer; /*!< I2C slave transfer. */ + volatile bool isBusy; /*!< Whether transfer is busy. */ + volatile i2c_slave_fsm_t slaveFsm; /*!< slave transfer state machine. */ + i2c_slave_transfer_callback_t callback; /*!< Callback function called at transfer event. */ + void *userData; /*!< Callback parameter passed to callback. */ +}; + +/*! @} */ + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @addtogroup i2c_master_driver + * @{ + */ + +/*! @name Initialization and deinitialization */ +/*@{*/ + +/*! + * @brief Provides a default configuration for the I2C master peripheral. + * + * This function provides the following default configuration for the I2C master peripheral: + * @code + * masterConfig->enableMaster = true; + * masterConfig->baudRate_Bps = 100000U; + * masterConfig->enableTimeout = false; + * @endcode + * + * After calling this function, you can override any settings in order to customize the configuration, + * prior to initializing the master driver with I2C_MasterInit(). + * + * @param[out] masterConfig User provided configuration structure for default values. Refer to #i2c_master_config_t. + */ +void I2C_MasterGetDefaultConfig(i2c_master_config_t *masterConfig); + +/*! + * @brief Initializes the I2C master peripheral. + * + * This function enables the peripheral clock and initializes the I2C master peripheral as described by the user + * provided configuration. A software reset is performed prior to configuration. + * + * @param base The I2C peripheral base address. + * @param masterConfig User provided peripheral configuration. Use I2C_MasterGetDefaultConfig() to get a set of + * defaults + * that you can override. + * @param srcClock_Hz Frequency in Hertz of the I2C functional clock. Used to calculate the baud rate divisors, + * filter widths, and timeout periods. + */ +void I2C_MasterInit(I2C_Type *base, const i2c_master_config_t *masterConfig, uint32_t srcClock_Hz); + +/*! +* @brief Deinitializes the I2C master peripheral. +* + * This function disables the I2C master peripheral and gates the clock. It also performs a software + * reset to restore the peripheral to reset conditions. + * + * @param base The I2C peripheral base address. + */ +void I2C_MasterDeinit(I2C_Type *base); + +/*! + * @brief Performs a software reset. + * + * Restores the I2C master peripheral to reset conditions. + * + * @param base The I2C peripheral base address. + */ +static inline void I2C_MasterReset(I2C_Type *base) +{ +} + +/*! + * @brief Enables or disables the I2C module as master. + * + * @param base The I2C peripheral base address. + * @param enable Pass true to enable or false to disable the specified I2C as master. + */ +static inline void I2C_MasterEnable(I2C_Type *base, bool enable) +{ + if (enable) + { + base->CFG = (base->CFG & I2C_CFG_MASK) | I2C_CFG_MSTEN_MASK; + } + else + { + base->CFG = (base->CFG & I2C_CFG_MASK) & ~I2C_CFG_MSTEN_MASK; + } +} + +/*@}*/ + +/*! @name Status */ +/*@{*/ + +/*! + * @brief Gets the I2C status flags. + * + * A bit mask with the state of all I2C status flags is returned. For each flag, the corresponding bit + * in the return value is set if the flag is asserted. + * + * @param base The I2C peripheral base address. + * @return State of the status flags: + * - 1: related status flag is set. + * - 0: related status flag is not set. + * @see _i2c_master_flags + */ +static inline uint32_t I2C_GetStatusFlags(I2C_Type *base) +{ + return base->STAT; +} + +/*! + * @brief Clears the I2C master status flag state. + * + * The following status register flags can be cleared: + * - #kI2C_MasterArbitrationLostFlag + * - #kI2C_MasterStartStopErrorFlag + * + * Attempts to clear other flags has no effect. + * + * @param base The I2C peripheral base address. + * @param statusMask A bitmask of status flags that are to be cleared. The mask is composed of + * #_i2c_master_flags enumerators OR'd together. You may pass the result of a previous call to + * I2C_GetStatusFlags(). + * @see _i2c_master_flags. + */ +static inline void I2C_MasterClearStatusFlags(I2C_Type *base, uint32_t statusMask) +{ + /* Allow clearing just master status flags */ + base->STAT = statusMask & (I2C_STAT_MSTARBLOSS_MASK | I2C_STAT_MSTSTSTPERR_MASK); +} + +/*@}*/ + +/*! @name Interrupts */ +/*@{*/ + +/*! + * @brief Enables the I2C master interrupt requests. + * + * @param base The I2C peripheral base address. + * @param interruptMask Bit mask of interrupts to enable. See #_i2c_master_flags for the set + * of constants that should be OR'd together to form the bit mask. + */ +static inline void I2C_EnableInterrupts(I2C_Type *base, uint32_t interruptMask) +{ + base->INTENSET = interruptMask; +} + +/*! + * @brief Disables the I2C master interrupt requests. + * + * @param base The I2C peripheral base address. + * @param interruptMask Bit mask of interrupts to disable. See #_i2c_master_flags for the set + * of constants that should be OR'd together to form the bit mask. + */ +static inline void I2C_DisableInterrupts(I2C_Type *base, uint32_t interruptMask) +{ + base->INTENCLR = interruptMask; +} + +/*! + * @brief Returns the set of currently enabled I2C master interrupt requests. + * + * @param base The I2C peripheral base address. + * @return A bitmask composed of #_i2c_master_flags enumerators OR'd together to indicate the + * set of enabled interrupts. + */ +static inline uint32_t I2C_GetEnabledInterrupts(I2C_Type *base) +{ + return base->INTSTAT; +} + +/*@}*/ + +/*! @name Bus operations */ +/*@{*/ + +/*! + * @brief Sets the I2C bus frequency for master transactions. + * + * The I2C master is automatically disabled and re-enabled as necessary to configure the baud + * rate. Do not call this function during a transfer, or the transfer is aborted. + * + * @param base The I2C peripheral base address. + * @param srcClock_Hz I2C functional clock frequency in Hertz. + * @param baudRate_Bps Requested bus frequency in bits per second. + */ +void I2C_MasterSetBaudRate(I2C_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz); + +/*! + * @brief Returns whether the bus is idle. + * + * Requires the master mode to be enabled. + * + * @param base The I2C peripheral base address. + * @retval true Bus is busy. + * @retval false Bus is idle. + */ +static inline bool I2C_MasterGetBusIdleState(I2C_Type *base) +{ + /* True if MSTPENDING flag is set and MSTSTATE is zero == idle */ + return ((base->STAT & (I2C_STAT_MSTPENDING_MASK | I2C_STAT_MSTSTATE_MASK)) == I2C_STAT_MSTPENDING_MASK); +} + +/*! + * @brief Sends a START on the I2C bus. + * + * This function is used to initiate a new master mode transfer by sending the START signal. + * The slave address is sent following the I2C START signal. + * + * @param base I2C peripheral base pointer + * @param address 7-bit slave device address. + * @param direction Master transfer directions(transmit/receive). + * @retval kStatus_Success Successfully send the start signal. + * @retval kStatus_I2C_Busy Current bus is busy. + */ +status_t I2C_MasterStart(I2C_Type *base, uint8_t address, i2c_direction_t direction); + +/*! + * @brief Sends a STOP signal on the I2C bus. + * + * @retval kStatus_Success Successfully send the stop signal. + * @retval kStatus_I2C_Timeout Send stop signal failed, timeout. + */ +status_t I2C_MasterStop(I2C_Type *base); + +/*! + * @brief Sends a REPEATED START on the I2C bus. + * + * @param base I2C peripheral base pointer + * @param address 7-bit slave device address. + * @param direction Master transfer directions(transmit/receive). + * @retval kStatus_Success Successfully send the start signal. + * @retval kStatus_I2C_Busy Current bus is busy but not occupied by current I2C master. + */ +static inline status_t I2C_MasterRepeatedStart(I2C_Type *base, uint8_t address, i2c_direction_t direction) +{ + return I2C_MasterStart(base, address, direction); +} + +/*! + * @brief Performs a polling send transfer on the I2C bus. + * + * Sends up to @a txSize number of bytes to the previously addressed slave device. The slave may + * reply with a NAK to any byte in order to terminate the transfer early. If this happens, this + * function returns #kStatus_I2C_Nak. + * + * @param base The I2C peripheral base address. + * @param txBuff The pointer to the data to be transferred. + * @param txSize The length in bytes of the data to be transferred. + * @param flags Transfer control flag to control special behavior like suppressing start or stop, for normal transfers + * use kI2C_TransferDefaultFlag + * @retval kStatus_Success Data was sent successfully. + * @retval #kStatus_I2C_Busy Another master is currently utilizing the bus. + * @retval #kStatus_I2C_Nak The slave device sent a NAK in response to a byte. + * @retval #kStatus_I2C_ArbitrationLost Arbitration lost error. + */ +status_t I2C_MasterWriteBlocking(I2C_Type *base, const void *txBuff, size_t txSize, uint32_t flags); + +/*! + * @brief Performs a polling receive transfer on the I2C bus. + * + * @param base The I2C peripheral base address. + * @param rxBuff The pointer to the data to be transferred. + * @param rxSize The length in bytes of the data to be transferred. + * @param flags Transfer control flag to control special behavior like suppressing start or stop, for normal transfers + * use kI2C_TransferDefaultFlag + * @retval kStatus_Success Data was received successfully. + * @retval #kStatus_I2C_Busy Another master is currently utilizing the bus. + * @retval #kStatus_I2C_Nak The slave device sent a NAK in response to a byte. + * @retval #kStatus_I2C_ArbitrationLost Arbitration lost error. + */ +status_t I2C_MasterReadBlocking(I2C_Type *base, void *rxBuff, size_t rxSize, uint32_t flags); + +/*! + * @brief Performs a master polling transfer on the I2C bus. + * + * @note The API does not return until the transfer succeeds or fails due + * to arbitration lost or receiving a NAK. + * + * @param base I2C peripheral base address. + * @param xfer Pointer to the transfer structure. + * @retval kStatus_Success Successfully complete the data transmission. + * @retval kStatus_I2C_Busy Previous transmission still not finished. + * @retval kStatus_I2C_Timeout Transfer error, wait signal timeout. + * @retval kStatus_I2C_ArbitrationLost Transfer error, arbitration lost. + * @retval kStataus_I2C_Nak Transfer error, receive NAK during transfer. + */ +status_t I2C_MasterTransferBlocking(I2C_Type *base, i2c_master_transfer_t *xfer); + +/*@}*/ + +/*! @name Non-blocking */ +/*@{*/ + +/*! + * @brief Creates a new handle for the I2C master non-blocking APIs. + * + * The creation of a handle is for use with the non-blocking APIs. Once a handle + * is created, there is not a corresponding destroy handle. If the user wants to + * terminate a transfer, the I2C_MasterTransferAbort() API shall be called. + * + * @param base The I2C peripheral base address. + * @param[out] handle Pointer to the I2C master driver handle. + * @param callback User provided pointer to the asynchronous callback function. + * @param userData User provided pointer to the application callback data. + */ +void I2C_MasterTransferCreateHandle(I2C_Type *base, + i2c_master_handle_t *handle, + i2c_master_transfer_callback_t callback, + void *userData); + +/*! + * @brief Performs a non-blocking transaction on the I2C bus. + * + * @param base The I2C peripheral base address. + * @param handle Pointer to the I2C master driver handle. + * @param xfer The pointer to the transfer descriptor. + * @retval kStatus_Success The transaction was started successfully. + * @retval #kStatus_I2C_Busy Either another master is currently utilizing the bus, or a non-blocking + * transaction is already in progress. + */ +status_t I2C_MasterTransferNonBlocking(I2C_Type *base, i2c_master_handle_t *handle, i2c_master_transfer_t *xfer); + +/*! + * @brief Returns number of bytes transferred so far. + * @param base The I2C peripheral base address. + * @param handle Pointer to the I2C master driver handle. + * @param[out] count Number of bytes transferred so far by the non-blocking transaction. + * @retval kStatus_Success + * @retval #kStatus_I2C_Busy + */ +status_t I2C_MasterTransferGetCount(I2C_Type *base, i2c_master_handle_t *handle, size_t *count); + +/*! + * @brief Terminates a non-blocking I2C master transmission early. + * + * @note It is not safe to call this function from an IRQ handler that has a higher priority than the + * I2C peripheral's IRQ priority. + * + * @param base The I2C peripheral base address. + * @param handle Pointer to the I2C master driver handle. + * @retval kStatus_Success A transaction was successfully aborted. + * @retval #kStatus_I2C_Timeout Abort failure due to flags polling timeout. + */ +status_t I2C_MasterTransferAbort(I2C_Type *base, i2c_master_handle_t *handle); + +/*@}*/ + +/*! @name IRQ handler */ +/*@{*/ + +/*! + * @brief Reusable routine to handle master interrupts. + * @note This function does not need to be called unless you are reimplementing the + * nonblocking API's interrupt handler routines to add special functionality. + * @param base The I2C peripheral base address. + * @param handle Pointer to the I2C master driver handle i2c_master_handle_t. + */ +void I2C_MasterTransferHandleIRQ(I2C_Type *base, void *i2cHandle); + +/*@}*/ + +/*! @} */ /* end of i2c_master_driver */ + +/*! + * @addtogroup i2c_slave_driver + * @{ + */ + +/*! @name Slave initialization and deinitialization */ +/*@{*/ + +/*! + * @brief Provides a default configuration for the I2C slave peripheral. + * + * This function provides the following default configuration for the I2C slave peripheral: + * @code + * slaveConfig->enableSlave = true; + * slaveConfig->address0.disable = false; + * slaveConfig->address0.address = 0u; + * slaveConfig->address1.disable = true; + * slaveConfig->address2.disable = true; + * slaveConfig->address3.disable = true; + * slaveConfig->busSpeed = kI2C_SlaveStandardMode; + * @endcode + * + * After calling this function, override any settings to customize the configuration, + * prior to initializing the master driver with I2C_SlaveInit(). Be sure to override at least the @a + * address0.address member of the configuration structure with the desired slave address. + * + * @param[out] slaveConfig User provided configuration structure that is set to default values. Refer to + * #i2c_slave_config_t. + */ +void I2C_SlaveGetDefaultConfig(i2c_slave_config_t *slaveConfig); + +/*! + * @brief Initializes the I2C slave peripheral. + * + * This function enables the peripheral clock and initializes the I2C slave peripheral as described by the user + * provided configuration. + * + * @param base The I2C peripheral base address. + * @param slaveConfig User provided peripheral configuration. Use I2C_SlaveGetDefaultConfig() to get a set of defaults + * that you can override. + * @param srcClock_Hz Frequency in Hertz of the I2C functional clock. Used to calculate CLKDIV value to provide + * enough + * data setup time for master when slave stretches the clock. + */ +status_t I2C_SlaveInit(I2C_Type *base, const i2c_slave_config_t *slaveConfig, uint32_t srcClock_Hz); + +/*! + * @brief Configures Slave Address n register. + * + * This function writes new value to Slave Address register. + * + * @param base The I2C peripheral base address. + * @param addressRegister The module supports multiple address registers. The parameter determines which one shall be + * changed. + * @param address The slave address to be stored to the address register for matching. + * @param addressDisable Disable matching of the specified address register. + */ +void I2C_SlaveSetAddress(I2C_Type *base, + i2c_slave_address_register_t addressRegister, + uint8_t address, + bool addressDisable); + +/*! +* @brief Deinitializes the I2C slave peripheral. +* + * This function disables the I2C slave peripheral and gates the clock. It also performs a software + * reset to restore the peripheral to reset conditions. + * + * @param base The I2C peripheral base address. + */ +void I2C_SlaveDeinit(I2C_Type *base); + +/*! + * @brief Enables or disables the I2C module as slave. + * + * @param base The I2C peripheral base address. + * @param enable True to enable or flase to disable. + */ +static inline void I2C_SlaveEnable(I2C_Type *base, bool enable) +{ + /* Set or clear the SLVEN bit in the CFG register. */ + base->CFG = I2C_CFG_SLVEN(enable); +} + +/*@}*/ /* end of Slave initialization and deinitialization */ + +/*! @name Slave status */ +/*@{*/ + +/*! + * @brief Clears the I2C status flag state. + * + * The following status register flags can be cleared: + * - slave deselected flag + * + * Attempts to clear other flags has no effect. + * + * @param base The I2C peripheral base address. + * @param statusMask A bitmask of status flags that are to be cleared. The mask is composed of + * #_i2c_slave_flags enumerators OR'd together. You may pass the result of a previous call to + * I2C_SlaveGetStatusFlags(). + * @see _i2c_slave_flags. + */ +static inline void I2C_SlaveClearStatusFlags(I2C_Type *base, uint32_t statusMask) +{ + /* Allow clearing just slave status flags */ + base->STAT = statusMask & I2C_STAT_SLVDESEL_MASK; +} + +/*@}*/ /* end of Slave status */ + +/*! @name Slave bus operations */ +/*@{*/ + +/*! + * @brief Performs a polling send transfer on the I2C bus. + * + * The function executes blocking address phase and blocking data phase. + * + * @param base The I2C peripheral base address. + * @param txBuff The pointer to the data to be transferred. + * @param txSize The length in bytes of the data to be transferred. + * @return kStatus_Success Data has been sent. + * @return kStatus_Fail Unexpected slave state (master data write while master read from slave is expected). + */ +status_t I2C_SlaveWriteBlocking(I2C_Type *base, const uint8_t *txBuff, size_t txSize); + +/*! + * @brief Performs a polling receive transfer on the I2C bus. + * + * The function executes blocking address phase and blocking data phase. + * + * @param base The I2C peripheral base address. + * @param rxBuff The pointer to the data to be transferred. + * @param rxSize The length in bytes of the data to be transferred. + * @return kStatus_Success Data has been received. + * @return kStatus_Fail Unexpected slave state (master data read while master write to slave is expected). + */ +status_t I2C_SlaveReadBlocking(I2C_Type *base, uint8_t *rxBuff, size_t rxSize); + +/*@}*/ /* end of Slave bus operations */ + +/*! @name Slave non-blocking */ +/*@{*/ + +/*! + * @brief Creates a new handle for the I2C slave non-blocking APIs. + * + * The creation of a handle is for use with the non-blocking APIs. Once a handle + * is created, there is not a corresponding destroy handle. If the user wants to + * terminate a transfer, the I2C_SlaveTransferAbort() API shall be called. + * + * @param base The I2C peripheral base address. + * @param[out] handle Pointer to the I2C slave driver handle. + * @param callback User provided pointer to the asynchronous callback function. + * @param userData User provided pointer to the application callback data. + */ +void I2C_SlaveTransferCreateHandle(I2C_Type *base, + i2c_slave_handle_t *handle, + i2c_slave_transfer_callback_t callback, + void *userData); + +/*! + * @brief Starts accepting slave transfers. + * + * Call this API after calling I2C_SlaveInit() and I2C_SlaveTransferCreateHandle() to start processing + * transactions driven by an I2C master. The slave monitors the I2C bus and pass events to the + * callback that was passed into the call to I2C_SlaveTransferCreateHandle(). The callback is always invoked + * from the interrupt context. + * + * If no slave Tx transfer is busy, a master read from slave request invokes #kI2C_SlaveTransmitEvent callback. + * If no slave Rx transfer is busy, a master write to slave request invokes #kI2C_SlaveReceiveEvent callback. + * + * The set of events received by the callback is customizable. To do so, set the @a eventMask parameter to + * the OR'd combination of #i2c_slave_transfer_event_t enumerators for the events you wish to receive. + * The #kI2C_SlaveTransmitEvent and #kI2C_SlaveReceiveEvent events are always enabled and do not need + * to be included in the mask. Alternatively, you can pass 0 to get a default set of only the transmit and + * receive events that are always enabled. In addition, the #kI2C_SlaveAllEvents constant is provided as + * a convenient way to enable all events. + * + * @param base The I2C peripheral base address. + * @param handle Pointer to i2c_slave_handle_t structure which stores the transfer state. + * @param eventMask Bit mask formed by OR'ing together #i2c_slave_transfer_event_t enumerators to specify + * which events to send to the callback. Other accepted values are 0 to get a default set of + * only the transmit and receive events, and #kI2C_SlaveAllEvents to enable all events. + * + * @retval kStatus_Success Slave transfers were successfully started. + * @retval #kStatus_I2C_Busy Slave transfers have already been started on this handle. + */ +status_t I2C_SlaveTransferNonBlocking(I2C_Type *base, i2c_slave_handle_t *handle, uint32_t eventMask); + +/*! + * @brief Starts accepting master read from slave requests. + * + * The function can be called in response to #kI2C_SlaveTransmitEvent callback to start a new slave Tx transfer + * from within the transfer callback. + * + * The set of events received by the callback is customizable. To do so, set the @a eventMask parameter to + * the OR'd combination of #i2c_slave_transfer_event_t enumerators for the events you wish to receive. + * The #kI2C_SlaveTransmitEvent and #kI2C_SlaveReceiveEvent events are always enabled and do not need + * to be included in the mask. Alternatively, you can pass 0 to get a default set of only the transmit and + * receive events that are always enabled. In addition, the #kI2C_SlaveAllEvents constant is provided as + * a convenient way to enable all events. + * + * @param base The I2C peripheral base address. + * @param transfer Pointer to #i2c_slave_transfer_t structure. + * @param txData Pointer to data to send to master. + * @param txSize Size of txData in bytes. + * @param eventMask Bit mask formed by OR'ing together #i2c_slave_transfer_event_t enumerators to specify + * which events to send to the callback. Other accepted values are 0 to get a default set of + * only the transmit and receive events, and #kI2C_SlaveAllEvents to enable all events. + * + * @retval kStatus_Success Slave transfers were successfully started. + * @retval #kStatus_I2C_Busy Slave transfers have already been started on this handle. + */ +status_t I2C_SlaveSetSendBuffer( + I2C_Type *base, volatile i2c_slave_transfer_t *transfer, const void *txData, size_t txSize, uint32_t eventMask); + +/*! + * @brief Starts accepting master write to slave requests. + * + * The function can be called in response to #kI2C_SlaveReceiveEvent callback to start a new slave Rx transfer + * from within the transfer callback. + * + * The set of events received by the callback is customizable. To do so, set the @a eventMask parameter to + * the OR'd combination of #i2c_slave_transfer_event_t enumerators for the events you wish to receive. + * The #kI2C_SlaveTransmitEvent and #kI2C_SlaveReceiveEvent events are always enabled and do not need + * to be included in the mask. Alternatively, you can pass 0 to get a default set of only the transmit and + * receive events that are always enabled. In addition, the #kI2C_SlaveAllEvents constant is provided as + * a convenient way to enable all events. + * + * @param base The I2C peripheral base address. + * @param transfer Pointer to #i2c_slave_transfer_t structure. + * @param rxData Pointer to data to store data from master. + * @param rxSize Size of rxData in bytes. + * @param eventMask Bit mask formed by OR'ing together #i2c_slave_transfer_event_t enumerators to specify + * which events to send to the callback. Other accepted values are 0 to get a default set of + * only the transmit and receive events, and #kI2C_SlaveAllEvents to enable all events. + * + * @retval kStatus_Success Slave transfers were successfully started. + * @retval #kStatus_I2C_Busy Slave transfers have already been started on this handle. + */ +status_t I2C_SlaveSetReceiveBuffer( + I2C_Type *base, volatile i2c_slave_transfer_t *transfer, void *rxData, size_t rxSize, uint32_t eventMask); + +/*! + * @brief Returns the slave address sent by the I2C master. + * + * This function should only be called from the address match event callback #kI2C_SlaveAddressMatchEvent. + * + * @param base The I2C peripheral base address. + * @param transfer The I2C slave transfer. + * @return The 8-bit address matched by the I2C slave. Bit 0 contains the R/w direction bit, and + * the 7-bit slave address is in the upper 7 bits. + */ +static inline uint32_t I2C_SlaveGetReceivedAddress(I2C_Type *base, volatile i2c_slave_transfer_t *transfer) +{ + return transfer->receivedAddress; +} + +/*! + * @brief Aborts the slave non-blocking transfers. + * @note This API could be called at any time to stop slave for handling the bus events. + * @param base The I2C peripheral base address. + * @param handle Pointer to i2c_slave_handle_t structure which stores the transfer state. + * @retval kStatus_Success + * @retval #kStatus_I2C_Idle + */ +void I2C_SlaveTransferAbort(I2C_Type *base, i2c_slave_handle_t *handle); + +/*! + * @brief Gets the slave transfer remaining bytes during a interrupt non-blocking transfer. + * + * @param base I2C base pointer. + * @param handle pointer to i2c_slave_handle_t structure. + * @param count Number of bytes transferred so far by the non-blocking transaction. + * @retval kStatus_InvalidArgument count is Invalid. + * @retval kStatus_Success Successfully return the count. + */ +status_t I2C_SlaveTransferGetCount(I2C_Type *base, i2c_slave_handle_t *handle, size_t *count); + +/*@}*/ /* end of Slave non-blocking */ + +/*! @name Slave IRQ handler */ +/*@{*/ + +/*! + * @brief Reusable routine to handle slave interrupts. + * @note This function does not need to be called unless you are reimplementing the + * non blocking API's interrupt handler routines to add special functionality. + * @param base The I2C peripheral base address. + * @param handle Pointer to i2c_slave_handle_t structure which stores the transfer state. + */ +void I2C_SlaveTransferHandleIRQ(I2C_Type *base, void *i2cHandle); + +/*@}*/ /* end of Slave IRQ handler */ + +/*! @} */ /* end of i2c_slave_driver */ + +#if defined(__cplusplus) +} +#endif + +#endif /* _FSL_I2C_H_ */ diff --git a/platform/mcu/lpc54102/drivers/fsl_i2c_dma.c b/platform/mcu/lpc54102/drivers/fsl_i2c_dma.c new file mode 100644 index 0000000000..4618816870 --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_i2c_dma.c @@ -0,0 +1,589 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_i2c_dma.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*transfer = *xfer; + transfer = &(handle->transfer); + + handle->transferCount = 0; + handle->remainingBytesDMA = 0; + handle->buf = (uint8_t *)transfer->data; + handle->remainingSubaddr = 0; + + if (transfer->flags & kI2C_TransferNoStartFlag) + { + /* Start condition shall be ommited, switch directly to next phase */ + if (transfer->dataSize == 0) + { + handle->state = kStopState; + } + else if (handle->transfer.direction == kI2C_Write) + { + handle->state = xfer->dataSize = kTransmitDataState; + } + else if (handle->transfer.direction == kI2C_Read) + { + handle->state = (xfer->dataSize == 1) ? kReceiveLastDataState : kReceiveDataState; + } + else + { + return kStatus_I2C_InvalidParameter; + } + } + else + { + if (transfer->subaddressSize != 0) + { + int i; + uint32_t subaddress; + + if (transfer->subaddressSize > sizeof(handle->subaddrBuf)) + { + return kStatus_I2C_InvalidParameter; + } + + /* Prepare subaddress transmit buffer, most significant byte is stored at the lowest address */ + subaddress = xfer->subaddress; + for (i = xfer->subaddressSize - 1; i >= 0; i--) + { + handle->subaddrBuf[i] = subaddress & 0xff; + subaddress >>= 8; + } + handle->remainingSubaddr = transfer->subaddressSize; + } + + handle->state = kStartState; + } + + return kStatus_Success; +} + +static void I2C_RunDMATransfer(I2C_Type *base, i2c_master_dma_handle_t *handle) +{ + int transfer_size; + dma_transfer_config_t xferConfig; + + /* Update transfer count */ + handle->transferCount = handle->buf - (uint8_t *)handle->transfer.data; + + /* Check if there is anything to be transferred at all */ + if (handle->remainingBytesDMA == 0) + { + /* No data to be transferrred, disable DMA */ + base->MSTCTL = 0; + return; + } + + /* Calculate transfer size */ + transfer_size = handle->remainingBytesDMA; + if (transfer_size > I2C_MAX_DMA_TRANSFER_COUNT) + { + transfer_size = I2C_MAX_DMA_TRANSFER_COUNT; + } + + switch (handle->transfer.direction) + { + case kI2C_Write: + DMA_PrepareTransfer(&xferConfig, handle->buf, (void *)&base->MSTDAT, sizeof(uint8_t), transfer_size, + kDMA_MemoryToPeripheral, NULL); + break; + + case kI2C_Read: + DMA_PrepareTransfer(&xferConfig, (void *)&base->MSTDAT, handle->buf, sizeof(uint8_t), transfer_size, + kDMA_PeripheralToMemory, NULL); + break; + + default: + /* This should never happen */ + assert(0); + break; + } + + DMA_SubmitTransfer(handle->dmaHandle, &xferConfig); + DMA_StartTransfer(handle->dmaHandle); + + handle->remainingBytesDMA -= transfer_size; + handle->buf += transfer_size; +} + +/*! + * @brief Execute states until the transfer is done. + * @param handle Master nonblocking driver handle. + * @param[out] isDone Set to true if the transfer has completed. + * @retval #kStatus_Success + * @retval #kStatus_I2C_ArbitrationLost + * @retval #kStatus_I2C_Nak + */ +static status_t I2C_RunTransferStateMachineDMA(I2C_Type *base, i2c_master_dma_handle_t *handle, bool *isDone) +{ + uint32_t status; + uint32_t master_state; + struct _i2c_master_transfer *transfer; + dma_transfer_config_t xferConfig; + status_t err; + uint32_t start_flag = 0; + + transfer = &(handle->transfer); + + *isDone = false; + + status = I2C_GetStatusFlags(base); + + if (status & I2C_STAT_MSTARBLOSS_MASK) + { + I2C_MasterClearStatusFlags(base, I2C_STAT_MSTARBLOSS_MASK); + DMA_AbortTransfer(handle->dmaHandle); + base->MSTCTL = 0; + return kStatus_I2C_ArbitrationLost; + } + + if (status & I2C_STAT_MSTSTSTPERR_MASK) + { + I2C_MasterClearStatusFlags(base, I2C_STAT_MSTSTSTPERR_MASK); + DMA_AbortTransfer(handle->dmaHandle); + base->MSTCTL = 0; + return kStatus_I2C_StartStopError; + } + + if ((status & I2C_STAT_MSTPENDING_MASK) == 0) + { + return kStatus_I2C_Busy; + } + + /* Get the state of the I2C module */ + master_state = (status & I2C_STAT_MSTSTATE_MASK) >> I2C_STAT_MSTSTATE_SHIFT; + + if ((master_state == I2C_STAT_MSTCODE_NACKADR) || (master_state == I2C_STAT_MSTCODE_NACKDAT)) + { + /* Slave NACKed last byte, issue stop and return error */ + DMA_AbortTransfer(handle->dmaHandle); + base->MSTCTL = I2C_MSTCTL_MSTSTOP_MASK; + handle->state = kWaitForCompletionState; + return kStatus_I2C_Nak; + } + + err = kStatus_Success; + + if (handle->state == kStartState) + { + /* set start flag for later use */ + start_flag = I2C_MSTCTL_MSTSTART_MASK; + + if (handle->remainingSubaddr) + { + base->MSTDAT = (uint32_t)transfer->slaveAddress << 1; + handle->state = kTransmitSubaddrState; + } + else if (transfer->direction == kI2C_Write) + { + base->MSTDAT = (uint32_t)transfer->slaveAddress << 1; + if (transfer->dataSize == 0) + { + /* No data to be transferred, initiate start and schedule stop */ + base->MSTCTL = I2C_MSTCTL_MSTSTART_MASK; + handle->state = kStopState; + return err; + } + handle->state = kTransmitDataState; + } + else if ((transfer->direction == kI2C_Read) && (transfer->dataSize > 0)) + { + base->MSTDAT = ((uint32_t)transfer->slaveAddress << 1) | 1u; + if (transfer->dataSize == 1) + { + /* The very last byte is always received by means of SW */ + base->MSTCTL = I2C_MSTCTL_MSTSTART_MASK; + handle->state = kReceiveLastDataState; + return err; + } + handle->state = kReceiveDataState; + } + else + { + handle->state = kIdleState; + err = kStatus_I2C_UnexpectedState; + return err; + } + } + + switch (handle->state) + { + case kTransmitSubaddrState: + if ((master_state != I2C_STAT_MSTCODE_TXREADY) && (!start_flag)) + { + return kStatus_I2C_UnexpectedState; + } + + base->MSTCTL = start_flag | I2C_MSTCTL_MSTDMA_MASK; + + /* Prepare and submit DMA transfer. */ + DMA_PrepareTransfer(&xferConfig, handle->subaddrBuf, (void *)&base->MSTDAT, sizeof(uint8_t), + handle->remainingSubaddr, kDMA_MemoryToPeripheral, NULL); + DMA_SubmitTransfer(handle->dmaHandle, &xferConfig); + DMA_StartTransfer(handle->dmaHandle); + handle->remainingSubaddr = 0; + if (transfer->dataSize) + { + /* There is data to be transferred, if there is write to read turnaround it is necessary to perform + * repeated start */ + handle->state = (transfer->direction == kI2C_Read) ? kStartState : kTransmitDataState; + } + else + { + /* No more data, schedule stop condition */ + handle->state = kStopState; + } + break; + + case kTransmitDataState: + if ((master_state != I2C_STAT_MSTCODE_TXREADY) && (!start_flag)) + { + return kStatus_I2C_UnexpectedState; + } + + base->MSTCTL = start_flag | I2C_MSTCTL_MSTDMA_MASK; + handle->remainingBytesDMA = handle->transfer.dataSize; + + I2C_RunDMATransfer(base, handle); + + /* Schedule stop condition */ + handle->state = kStopState; + break; + + case kReceiveDataState: + if ((master_state != I2C_STAT_MSTCODE_RXREADY) && (!start_flag)) + { + return kStatus_I2C_UnexpectedState; + } + + base->MSTCTL = start_flag | I2C_MSTCTL_MSTDMA_MASK; + handle->remainingBytesDMA = handle->transfer.dataSize - 1; + + I2C_RunDMATransfer(base, handle); + + /* Schedule reception of last data byte */ + handle->state = kReceiveLastDataState; + break; + + case kReceiveLastDataState: + if (master_state != I2C_STAT_MSTCODE_RXREADY) + { + return kStatus_I2C_UnexpectedState; + } + + ((uint8_t *)transfer->data)[transfer->dataSize - 1] = base->MSTDAT; + handle->transferCount++; + + /* No more data expected, issue NACK and STOP right away */ + base->MSTCTL = I2C_MSTCTL_MSTSTOP_MASK; + handle->state = kWaitForCompletionState; + break; + + case kStopState: + if (transfer->flags & kI2C_TransferNoStopFlag) + { + /* Stop condition is omitted, we are done */ + *isDone = true; + handle->state = kIdleState; + break; + } + /* Send stop condition */ + base->MSTCTL = I2C_MSTCTL_MSTSTOP_MASK; + handle->state = kWaitForCompletionState; + break; + + case kWaitForCompletionState: + *isDone = true; + handle->state = kIdleState; + break; + + case kStartState: + case kIdleState: + default: + /* State machine shall not be invoked again once it enters the idle state */ + err = kStatus_I2C_UnexpectedState; + break; + } + + return err; +} + +void I2C_MasterTransferDMAHandleIRQ(I2C_Type *base, void *i2cHandle) +{ + assert(i2cHandle); + + bool isDone; + status_t result; + i2c_master_dma_handle_t *handle = (i2c_master_dma_handle_t *)i2cHandle; + + /* Don't do anything if we don't have a valid handle. */ + if (!handle) + { + return; + } + + result = I2C_RunTransferStateMachineDMA(base, handle, &isDone); + + if (isDone || (result != kStatus_Success)) + { + /* Disable internal IRQ enables. */ + I2C_DisableInterrupts(base, + I2C_INTSTAT_MSTPENDING_MASK | I2C_INTSTAT_MSTARBLOSS_MASK | I2C_INTSTAT_MSTSTSTPERR_MASK); + + /* Invoke callback. */ + if (handle->completionCallback) + { + handle->completionCallback(base, handle, result, handle->userData); + } + } +} + +static void I2C_MasterTransferCallbackDMA(dma_handle_t *handle, void *userData) +{ + i2c_master_dma_private_handle_t *dmaPrivateHandle; + + /* Don't do anything if we don't have a valid handle. */ + if (!handle) + { + return; + } + + dmaPrivateHandle = (i2c_master_dma_private_handle_t *)userData; + I2C_RunDMATransfer(dmaPrivateHandle->base, dmaPrivateHandle->handle); +} + +void I2C_MasterTransferCreateHandleDMA(I2C_Type *base, + i2c_master_dma_handle_t *handle, + i2c_master_dma_transfer_callback_t callback, + void *userData, + dma_handle_t *dmaHandle) +{ + uint32_t instance; + + assert(handle); + assert(dmaHandle); + + /* Zero handle. */ + memset(handle, 0, sizeof(*handle)); + + /* Look up instance number */ + instance = I2C_GetInstance(base); + + /* Set the user callback and userData. */ + handle->completionCallback = callback; + handle->userData = userData; + + /* Save the context in global variables to support the double weak mechanism. */ + s_i2cHandle[instance] = handle; + + /* Save master interrupt handler. */ + s_i2cMasterIsr = I2C_MasterTransferDMAHandleIRQ; + + /* Clear internal IRQ enables and enable NVIC IRQ. */ + I2C_DisableInterrupts(base, + I2C_INTSTAT_MSTPENDING_MASK | I2C_INTSTAT_MSTARBLOSS_MASK | I2C_INTSTAT_MSTSTSTPERR_MASK); + EnableIRQ(s_i2cIRQ[instance]); + + /* Set the handle for DMA. */ + handle->dmaHandle = dmaHandle; + + s_dmaPrivateHandle[instance].base = base; + s_dmaPrivateHandle[instance].handle = handle; + + DMA_SetCallback(dmaHandle, (dma_callback)(uintptr_t)I2C_MasterTransferCallbackDMA, &s_dmaPrivateHandle[instance]); +} + +status_t I2C_MasterTransferDMA(I2C_Type *base, i2c_master_dma_handle_t *handle, i2c_master_transfer_t *xfer) +{ + status_t result; + + assert(handle); + assert(xfer); + assert(xfer->subaddressSize <= sizeof(xfer->subaddress)); + + /* Return busy if another transaction is in progress. */ + if (handle->state != kIdleState) + { + return kStatus_I2C_Busy; + } + + /* Prepare transfer state machine. */ + result = I2C_InitTransferStateMachineDMA(base, handle, xfer); + + /* Clear error flags. */ + I2C_MasterClearStatusFlags(base, I2C_STAT_MSTARBLOSS_MASK | I2C_STAT_MSTSTSTPERR_MASK); + + /* Enable I2C internal IRQ sources */ + I2C_EnableInterrupts(base, + I2C_INTSTAT_MSTARBLOSS_MASK | I2C_INTSTAT_MSTSTSTPERR_MASK | I2C_INTSTAT_MSTPENDING_MASK); + + return result; +} + +status_t I2C_MasterTransferGetCountDMA(I2C_Type *base, i2c_master_dma_handle_t *handle, size_t *count) +{ + assert(handle); + + if (!count) + { + return kStatus_InvalidArgument; + } + + /* Catch when there is not an active transfer. */ + if (handle->state == kIdleState) + { + *count = 0; + return kStatus_NoTransferInProgress; + } + + /* There is no necessity to disable interrupts as we read a single integer value */ + *count = handle->transferCount; + return kStatus_Success; +} + +void I2C_MasterTransferAbortDMA(I2C_Type *base, i2c_master_dma_handle_t *handle) +{ + uint32_t status; + uint32_t master_state; + + if (handle->state != kIdleState) + { + DMA_AbortTransfer(handle->dmaHandle); + + /* Disable DMA */ + base->MSTCTL = 0; + + /* Disable internal IRQ enables. */ + I2C_DisableInterrupts(base, + I2C_INTSTAT_MSTPENDING_MASK | I2C_INTSTAT_MSTARBLOSS_MASK | I2C_INTSTAT_MSTSTSTPERR_MASK); + + /* Wait until module is ready */ + do + { + status = I2C_GetStatusFlags(base); + } while ((status & I2C_STAT_MSTPENDING_MASK) == 0); + + /* Clear controller state. */ + I2C_MasterClearStatusFlags(base, I2C_STAT_MSTARBLOSS_MASK | I2C_STAT_MSTSTSTPERR_MASK); + + /* Get the state of the I2C module */ + master_state = (status & I2C_STAT_MSTSTATE_MASK) >> I2C_STAT_MSTSTATE_SHIFT; + + if (master_state != I2C_STAT_MSTCODE_IDLE) + { + /* Send a stop command to finalize the transfer. */ + base->MSTCTL = I2C_MSTCTL_MSTSTOP_MASK; + + /* Wait until module is ready */ + do + { + status = I2C_GetStatusFlags(base); + } while ((status & I2C_STAT_MSTPENDING_MASK) == 0); + + /* Clear controller state. */ + I2C_MasterClearStatusFlags(base, I2C_STAT_MSTARBLOSS_MASK | I2C_STAT_MSTSTSTPERR_MASK); + } + + /* Reset the state to idle. */ + handle->state = kIdleState; + } +} diff --git a/platform/mcu/lpc54102/drivers/fsl_i2c_dma.h b/platform/mcu/lpc54102/drivers/fsl_i2c_dma.h new file mode 100644 index 0000000000..794e8ec0ba --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_i2c_dma.h @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_I2C_DMA_H_ +#define _FSL_I2C_DMA_H_ + +#include "fsl_i2c.h" +#include "fsl_dma.h" + +/*! + * @addtogroup i2c_dma_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief Maximum lenght of single DMA transfer (determined by capability of the DMA engine) */ +#define I2C_MAX_DMA_TRANSFER_COUNT 1024 + +/*! @brief I2C master dma handle typedef. */ +typedef struct _i2c_master_dma_handle i2c_master_dma_handle_t; + +/*! @brief I2C master dma transfer callback typedef. */ +typedef void (*i2c_master_dma_transfer_callback_t)(I2C_Type *base, + i2c_master_dma_handle_t *handle, + status_t status, + void *userData); + +/*! @brief I2C master dma transfer structure. */ +struct _i2c_master_dma_handle +{ + uint8_t state; /*!< Transfer state machine current state. */ + uint32_t transferCount; /*!< Indicates progress of the transfer */ + uint32_t remainingBytesDMA; /*!< Remaining byte count to be transferred using DMA. */ + uint8_t *buf; /*!< Buffer pointer for current state. */ + uint32_t remainingSubaddr; + uint8_t subaddrBuf[4]; + dma_handle_t *dmaHandle; /*!< The DMA handler used. */ + i2c_master_transfer_t transfer; /*!< Copy of the current transfer info. */ + i2c_master_dma_transfer_callback_t completionCallback; /*!< Callback function called after dma transfer finished. */ + void *userData; /*!< Callback parameter passed to callback function. */ +}; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /*_cplusplus. */ + +/*! + * @name I2C Block DMA Transfer Operation + * @{ + */ + +/*! + * @brief Init the I2C handle which is used in transcational functions + * + * @param base I2C peripheral base address + * @param handle pointer to i2c_master_dma_handle_t structure + * @param callback pointer to user callback function + * @param userData user param passed to the callback function + * @param dmaHandle DMA handle pointer + */ +void I2C_MasterTransferCreateHandleDMA(I2C_Type *base, + i2c_master_dma_handle_t *handle, + i2c_master_dma_transfer_callback_t callback, + void *userData, + dma_handle_t *dmaHandle); + +/*! + * @brief Performs a master dma non-blocking transfer on the I2C bus + * + * @param base I2C peripheral base address + * @param handle pointer to i2c_master_dma_handle_t structure + * @param xfer pointer to transfer structure of i2c_master_transfer_t + * @retval kStatus_Success Sucessully complete the data transmission. + * @retval kStatus_I2C_Busy Previous transmission still not finished. + * @retval kStatus_I2C_Timeout Transfer error, wait signal timeout. + * @retval kStatus_I2C_ArbitrationLost Transfer error, arbitration lost. + * @retval kStataus_I2C_Nak Transfer error, receive Nak during transfer. + */ +status_t I2C_MasterTransferDMA(I2C_Type *base, i2c_master_dma_handle_t *handle, i2c_master_transfer_t *xfer); + +/*! + * @brief Get master transfer status during a dma non-blocking transfer + * + * @param base I2C peripheral base address + * @param handle pointer to i2c_master_dma_handle_t structure + * @param count Number of bytes transferred so far by the non-blocking transaction. + */ +status_t I2C_MasterTransferGetCountDMA(I2C_Type *base, i2c_master_dma_handle_t *handle, size_t *count); + +/*! + * @brief Abort a master dma non-blocking transfer in a early time + * + * @param base I2C peripheral base address + * @param handle pointer to i2c_master_dma_handle_t structure + */ +void I2C_MasterTransferAbortDMA(I2C_Type *base, i2c_master_dma_handle_t *handle); + +/* @} */ +#if defined(__cplusplus) +} +#endif /*_cplusplus. */ +/*@}*/ +#endif /*_FSL_I2C_DMA_H_*/ diff --git a/platform/mcu/lpc54102/drivers/fsl_inputmux.c b/platform/mcu/lpc54102/drivers/fsl_inputmux.c new file mode 100644 index 0000000000..923585174b --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_inputmux.c @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_inputmux.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Code + ******************************************************************************/ + +void INPUTMUX_Init(INPUTMUX_Type *base) +{ +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + CLOCK_EnableClock(kCLOCK_InputMux); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +void INPUTMUX_AttachSignal(INPUTMUX_Type *base, uint32_t index, inputmux_connection_t connection) +{ + uint32_t pmux_id; + uint32_t output_id; + + /* extract pmux to be used */ + pmux_id = ((uint32_t)(connection)) >> PMUX_SHIFT; + /* extract function number */ + output_id = ((uint32_t)(connection)) & 0xffffU; + /* programm signal */ + *(volatile uint32_t *)(((uint32_t)base) + pmux_id + (index * 4)) = output_id; +} + +void INPUTMUX_Deinit(INPUTMUX_Type *base) +{ +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + CLOCK_DisableClock(kCLOCK_InputMux); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} diff --git a/platform/mcu/lpc54102/drivers/fsl_inputmux.h b/platform/mcu/lpc54102/drivers/fsl_inputmux.h new file mode 100644 index 0000000000..3d298558bc --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_inputmux.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_INPUTMUX_H_ +#define _FSL_INPUTMUX_H_ + +#include "fsl_inputmux_connections.h" +#include "fsl_common.h" + +/*! + * @addtogroup inputmux_driver + * @{ + */ + +/*! @file */ +/*! @file fsl_inputmux_connections.h */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief Group interrupt driver version for SDK */ +#define FSL_INPUTMUX_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0. */ + /*@}*/ + +/******************************************************************************* + * API + ******************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*! + * @brief Initialize INPUTMUX peripheral. + + * This function enables the INPUTMUX clock. + * + * @param base Base address of the INPUTMUX peripheral. + * + * @retval None. + */ +void INPUTMUX_Init(INPUTMUX_Type *base); + +/*! + * @brief Attaches a signal + * + * This function gates the INPUTPMUX clock. + * + * @param base Base address of the INPUTMUX peripheral. + * @param index Destination peripheral to attach the signal to. + * @param connection Selects connection. + * + * @retval None. +*/ +void INPUTMUX_AttachSignal(INPUTMUX_Type *base, uint32_t index, inputmux_connection_t connection); + +/*! + * @brief Deinitialize INPUTMUX peripheral. + + * This function disables the INPUTMUX clock. + * + * @param base Base address of the INPUTMUX peripheral. + * + * @retval None. + */ +void INPUTMUX_Deinit(INPUTMUX_Type *base); + +#ifdef __cplusplus +} +#endif + +/*@}*/ + +#endif /* _FSL_INPUTMUX_H_ */ diff --git a/platform/mcu/lpc54102/drivers/fsl_inputmux_connections.h b/platform/mcu/lpc54102/drivers/fsl_inputmux_connections.h new file mode 100644 index 0000000000..a94781046a --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_inputmux_connections.h @@ -0,0 +1,174 @@ +/* + * Copyright 2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_INPUTMUX_CONNECTIONS_ +#define _FSL_INPUTMUX_CONNECTIONS_ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! + * @addtogroup inputmux_driver + * @{ + */ + +/*! @brief Periphinmux IDs */ +#define PINTSEL_PMUX_ID 0xC0U +#define DMA_TRIG0_PMUX_ID 0xE0U +#define DMA_OTRIG_PMUX_ID 0x140U +#define FREQMEAS_PMUX_ID 0x160U +#define PMUX_SHIFT 20U + +/*! @brief INPUTMUX connections type */ +typedef enum _inputmux_connection_t +{ + /*!< Frequency measure. */ + kINPUTMUX_ClockInToFreqmeas = 0U + (FREQMEAS_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_Irc12MhzToFreqmeas = 1U + (FREQMEAS_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_WdtOscToFreqmeas = 2U + (FREQMEAS_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_32KhzOscToFreqmeas = 3U + (FREQMEAS_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_MainClkToFreqmeas = 4U + (FREQMEAS_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin4ToFreqmeas = 5U + (FREQMEAS_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin20ToFreqmeas = 6U + (FREQMEAS_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin24ToFreqmeas = 7U + (FREQMEAS_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin4ToFreqmeas = 8U + (FREQMEAS_PMUX_ID << PMUX_SHIFT), + /*!< Pin Interrupt. */ + kINPUTMUX_GpioPort0Pin0ToPintsel = 0U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin1ToPintsel = 1U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin2ToPintsel = 2U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin3ToPintsel = 3U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin4ToPintsel = 4U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin5ToPintsel = 5U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin6ToPintsel = 6U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin7ToPintsel = 7U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin8ToPintsel = 8U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin9ToPintsel = 9U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin10ToPintsel = 10U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin11ToPintsel = 11U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin12ToPintsel = 12U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin13ToPintsel = 13U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin14ToPintsel = 14U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin15ToPintsel = 15U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin16ToPintsel = 16U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin17ToPintsel = 17U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin18ToPintsel = 18U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin19ToPintsel = 19U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin20ToPintsel = 20U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin21ToPintsel = 21U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin22ToPintsel = 22U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin23ToPintsel = 23U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin24ToPintsel = 24U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin25ToPintsel = 25U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin26ToPintsel = 26U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin27ToPintsel = 27U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin28ToPintsel = 28U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin29ToPintsel = 29U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin30ToPintsel = 30U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort0Pin31ToPintsel = 31U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin0ToPintsel = 32U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin1ToPintsel = 33U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin2ToPintsel = 34U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin3ToPintsel = 35U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin4ToPintsel = 36U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin5ToPintsel = 37U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin6ToPintsel = 38U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin7ToPintsel = 39U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin8ToPintsel = 40U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin9ToPintsel = 41U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin10ToPintsel = 42U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin11ToPintsel = 43U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin12ToPintsel = 44U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin13ToPintsel = 45U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin14ToPintsel = 46U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin15ToPintsel = 47U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin16ToPintsel = 48U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin17ToPintsel = 49U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin18ToPintsel = 50U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin19ToPintsel = 51U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin20ToPintsel = 52U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin21ToPintsel = 53U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin22ToPintsel = 54U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin23ToPintsel = 55U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin24ToPintsel = 56U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin25ToPintsel = 57U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin26ToPintsel = 58U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin27ToPintsel = 59U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin28ToPintsel = 60U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin29ToPintsel = 61U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin30ToPintsel = 62U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_GpioPort1Pin31ToPintsel = 63U + (PINTSEL_PMUX_ID << PMUX_SHIFT), + /*!< DMA ITRIG. */ + kINPUTMUX_Adc0SeqaIrqToDma = 0U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_Adc0SeqbIrqToDma = 1U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_Sct0DmaReq0ToDma = 2U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_Sct0DmaReq1ToDma = 3U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_Ctimer32B0M0ToDma = 4U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_Ctimer32B0M1ToDma = 5U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_Ctimer32B1M0ToDma = 6U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_Ctimer32B2M0ToDma = 7U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_Ctimer32B2M1ToDma = 8U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_Ctimer32B3M0ToDma = 9U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_Ctimer32B4M0ToDma = 10U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_Ctimer32B4M1ToDma = 11U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_PinInt0ToDma = 12U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_PinInt1ToDma = 13U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_PinInt2ToDma = 14U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_PinInt3ToDma = 15U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_Otrig0ToDma = 16U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_Otrig1ToDma = 17U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_Otrig2ToDma = 18U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_Otrig3ToDma = 19U + (DMA_TRIG0_PMUX_ID << PMUX_SHIFT), + /*!< DMA OTRIG. */ + kINPUTMUX_DmaUsart0RxTrigoutToTriginChannels = 0U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_DmaUsart0TxTrigoutToTriginChannels = 1U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_DmaUsart1RxTrigoutToTriginChannels = 2U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_DmaUsart1TxTrigoutToTriginChannels = 3U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_DmaUsart2RxTrigoutToTriginChannels = 4U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_DmaUsart2TxTrigoutToTriginChannels = 5U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_DmaUsart3RxTrigoutToTriginChannels = 6U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_DmaUsart3TxTrigoutToTriginChannels = 7U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_DmaSpi0RxTrigoutToTriginChannels = 8U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_DmaSpi0TxTrigoutToTriginChannels = 9U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_DmaSpi1RxTrigoutToTriginChannels = 10U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_DmaSpi1TxTrigoutToTriginChannels = 11U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_DmaI2c0SlaveTrigoutToTriginChannels = 12U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_DmaI2c0MasterTrigoutToTriginChannels = 13U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_DmaI2c1SlaveTrigoutToTriginChannels = 14U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_DmaI2c1MasterTrigoutToTriginChannels = 15U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_DmaI2c2SlaveTrigoutToTriginChannels = 16U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_DmaI2c2MasterTrigoutToTriginChannels = 17U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_DmaI2c0MonitorTrigoutToTriginChannels = 18U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_DmaI2c1MonitorTrigoutToTriginChannels = 19U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT), + kINPUTMUX_DmaI2c2MonitorTrigoutToTriginChannels = 20U + (DMA_OTRIG_PMUX_ID << PMUX_SHIFT), +} inputmux_connection_t; + +/*@}*/ + +#endif /* _FSL_INPUTMUX_CONNECTIONS_ */ diff --git a/platform/mcu/lpc54102/drivers/fsl_iocon.h b/platform/mcu/lpc54102/drivers/fsl_iocon.h new file mode 100644 index 0000000000..7cf6911f1e --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_iocon.h @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_IOCON_H_ +#define _FSL_IOCON_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup lpc_iocon + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief IOCON driver version 2.0.0. */ +#define LPC_IOCON_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*@}*/ + +/** + * @brief Array of IOCON pin definitions passed to IOCON_SetPinMuxing() must be in this format + */ +typedef struct _iocon_group +{ + uint32_t port : 8; /* Pin port */ + uint32_t pin : 8; /* Pin number */ + uint32_t modefunc : 16; /* Function and mode */ +} iocon_group_t; + +/** + * @brief IOCON function and mode selection definitions + * @note See the User Manual for specific modes and functions supported by the various pins. + */ +#if defined(FSL_FEATURE_IOCON_FUNC_FIELD_WIDTH) && (FSL_FEATURE_IOCON_FUNC_FIELD_WIDTH == 4) +#define IOCON_FUNC0 0x0 /*!< Selects pin function 0 */ +#define IOCON_FUNC1 0x1 /*!< Selects pin function 1 */ +#define IOCON_FUNC2 0x2 /*!< Selects pin function 2 */ +#define IOCON_FUNC3 0x3 /*!< Selects pin function 3 */ +#define IOCON_FUNC4 0x4 /*!< Selects pin function 4 */ +#define IOCON_FUNC5 0x5 /*!< Selects pin function 5 */ +#define IOCON_FUNC6 0x6 /*!< Selects pin function 6 */ +#define IOCON_FUNC7 0x7 /*!< Selects pin function 7 */ +#define IOCON_FUNC8 0x8 /*!< Selects pin function 8 */ +#define IOCON_FUNC9 0x9 /*!< Selects pin function 9 */ +#define IOCON_FUNC10 0xA /*!< Selects pin function 10 */ +#define IOCON_FUNC11 0xB /*!< Selects pin function 11 */ +#define IOCON_FUNC12 0xC /*!< Selects pin function 12 */ +#define IOCON_FUNC13 0xD /*!< Selects pin function 13 */ +#define IOCON_FUNC14 0xE /*!< Selects pin function 14 */ +#define IOCON_FUNC15 0xF /*!< Selects pin function 15 */ +#define IOCON_MODE_INACT (0x0 << 4) /*!< No addition pin function */ +#define IOCON_MODE_PULLDOWN (0x1 << 4) /*!< Selects pull-down function */ +#define IOCON_MODE_PULLUP (0x2 << 4) /*!< Selects pull-up function */ +#define IOCON_MODE_REPEATER (0x3 << 4) /*!< Selects pin repeater function */ +#define IOCON_HYS_EN (0x1 << 6) /*!< Enables hysteresis */ +#define IOCON_GPIO_MODE (0x1 << 6) /*!< GPIO Mode */ +#define IOCON_I2C_SLEW (0x0 << 6) /*!< I2C Slew Rate Control */ +#define IOCON_INV_EN (0x1 << 7) /*!< Enables invert function on input */ +#define IOCON_ANALOG_EN (0x0 << 8) /*!< Enables analog function by setting 0 to bit 7 */ +#define IOCON_DIGITAL_EN (0x1 << 8) /*!< Enables digital function by setting 1 to bit 7(default) */ +#define IOCON_STDI2C_EN (0x1 << 9) /*!< I2C standard mode/fast-mode */ +#define IOCON_FASTI2C_EN (0x3 << 9) /*!< I2C Fast-mode Plus and high-speed slave */ +#define IOCON_INPFILT_OFF (0x1 << 9) /*!< Input filter Off for GPIO pins */ +#define IOCON_INPFILT_ON (0x0 << 9) /*!< Input filter On for GPIO pins */ +#define IOCON_OPENDRAIN_EN (0x1 << 11) /*!< Enables open-drain function */ +#define IOCON_S_MODE_0CLK (0x0 << 12) /*!< Bypass input filter */ +#define IOCON_S_MODE_1CLK (0x1 << 12) /*!< Input pulses shorter than 1 filter clock are rejected */ +#define IOCON_S_MODE_2CLK (0x2 << 12) /*!< Input pulses shorter than 2 filter clock2 are rejected */ +#define IOCON_S_MODE_3CLK (0x3 << 12) /*!< Input pulses shorter than 3 filter clock2 are rejected */ +#define IOCON_S_MODE(clks) ((clks) << 12) /*!< Select clocks for digital input filter mode */ +#define IOCON_CLKDIV(div) \ + ((div) << 14) /*!< Select peripheral clock divider for input filter sampling clock, 2^n, n=0-6 */ +#else +#define IOCON_FUNC0 0x0 /*!< Selects pin function 0 */ +#define IOCON_FUNC1 0x1 /*!< Selects pin function 1 */ +#define IOCON_FUNC2 0x2 /*!< Selects pin function 2 */ +#define IOCON_FUNC3 0x3 /*!< Selects pin function 3 */ +#define IOCON_FUNC4 0x4 /*!< Selects pin function 4 */ +#define IOCON_FUNC5 0x5 /*!< Selects pin function 5 */ +#define IOCON_FUNC6 0x6 /*!< Selects pin function 6 */ +#define IOCON_FUNC7 0x7 /*!< Selects pin function 7 */ +#define IOCON_MODE_INACT (0x0 << 3) /*!< No addition pin function */ +#define IOCON_MODE_PULLDOWN (0x1 << 3) /*!< Selects pull-down function */ +#define IOCON_MODE_PULLUP (0x2 << 3) /*!< Selects pull-up function */ +#define IOCON_MODE_REPEATER (0x3 << 3) /*!< Selects pin repeater function */ +#define IOCON_HYS_EN (0x1 << 5) /*!< Enables hysteresis */ +#define IOCON_GPIO_MODE (0x1 << 5) /*!< GPIO Mode */ +#define IOCON_I2C_SLEW (0x0 << 5) /*!< I2C Slew Rate Control */ +#define IOCON_INV_EN (0x1 << 6) /*!< Enables invert function on input */ +#define IOCON_ANALOG_EN (0x0 << 7) /*!< Enables analog function by setting 0 to bit 7 */ +#define IOCON_DIGITAL_EN (0x1 << 7) /*!< Enables digital function by setting 1 to bit 7(default) */ +#define IOCON_STDI2C_EN (0x1 << 8) /*!< I2C standard mode/fast-mode */ +#define IOCON_FASTI2C_EN (0x3 << 8) /*!< I2C Fast-mode Plus and high-speed slave */ +#define IOCON_INPFILT_OFF (0x1 << 8) /*!< Input filter Off for GPIO pins */ +#define IOCON_INPFILT_ON (0x0 << 8) /*!< Input filter On for GPIO pins */ +#define IOCON_OPENDRAIN_EN (0x1 << 10) /*!< Enables open-drain function */ +#define IOCON_S_MODE_0CLK (0x0 << 11) /*!< Bypass input filter */ +#define IOCON_S_MODE_1CLK (0x1 << 11) /*!< Input pulses shorter than 1 filter clock are rejected */ +#define IOCON_S_MODE_2CLK (0x2 << 11) /*!< Input pulses shorter than 2 filter clock2 are rejected */ +#define IOCON_S_MODE_3CLK (0x3 << 11) /*!< Input pulses shorter than 3 filter clock2 are rejected */ +#define IOCON_S_MODE(clks) ((clks) << 11) /*!< Select clocks for digital input filter mode */ +#define IOCON_CLKDIV(div) \ + ((div) << 13) /*!< Select peripheral clock divider for input filter sampling clock, 2^n, n=0-6 */ +#endif +#if defined(__cplusplus) +extern "C" { +#endif + +/** + * @brief Sets I/O Control pin mux + * @param base : The base of IOCON peripheral on the chip + * @param port : GPIO port to mux + * @param pin : GPIO pin to mux + * @param modefunc : OR'ed values of type IOCON_* + * @return Nothing + */ +__STATIC_INLINE void IOCON_PinMuxSet(IOCON_Type *base, uint8_t port, uint8_t pin, uint32_t modefunc) +{ + base->PIO[port][pin] = modefunc; +} + +/** + * @brief Set all I/O Control pin muxing + * @param base : The base of IOCON peripheral on the chip + * @param pinArray : Pointer to array of pin mux selections + * @param arrayLength : Number of entries in pinArray + * @return Nothing + */ +__STATIC_INLINE void IOCON_SetPinMuxing(IOCON_Type *base, const iocon_group_t *pinArray, uint32_t arrayLength) +{ + uint32_t i; + + for (i = 0; i < arrayLength; i++) + { + IOCON_PinMuxSet(base, pinArray[i].port, pinArray[i].pin, pinArray[i].modefunc); + } +} + +/* @} */ + +#if defined(__cplusplus) +} +#endif + +#endif /* _FSL_IOCON_H_ */ diff --git a/platform/mcu/lpc54102/drivers/fsl_mailbox.h b/platform/mcu/lpc54102/drivers/fsl_mailbox.h new file mode 100644 index 0000000000..220e79a712 --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_mailbox.h @@ -0,0 +1,200 @@ +/* + * Copyright(C) NXP Semiconductors, 2014 + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_MAILBOX_H_ +#define _FSL_MAILBOX_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup mailbox + * @{ + */ + +/*! @file */ + +/****************************************************************************** + * Definitions + *****************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief MAILBOX driver version 2.0.0. */ +#define FSL_MAILBOX_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*@}*/ + +/*! + * @brief CPU ID. + */ +typedef enum _mailbox_cpu_id +{ + kMAILBOX_CM0Plus = 0, + kMAILBOX_CM4 +} mailbox_cpu_id_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*! + * @name MAILBOX initialization + * @{ + */ + +/*! + * @brief Initializes the MAILBOX module. + * + * This function enables the MAILBOX clock only. + * + * @param base MAILBOX peripheral base address. + */ +static inline void MAILBOX_Init(MAILBOX_Type *base) +{ +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + CLOCK_EnableClock(kCLOCK_Mailbox); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +/*! + * @brief De-initializes the MAILBOX module. + * + * This function disables the MAILBOX clock only. + * + * @param base MAILBOX peripheral base address. + */ +static inline void MAILBOX_Deinit(MAILBOX_Type *base) +{ +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + CLOCK_DisableClock(kCLOCK_Mailbox); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +/* @} */ + +/*! + * @brief Set data value in the mailbox based on the CPU ID. + * + * @param base MAILBOX peripheral base address. + * @param cpu_id CPU id, kMAILBOX_CM0Plus is M0+ or kMAILBOX_CM4 is M4. + * @param mboxData Data to send in the mailbox. + * + * @note Sets a data value to send via the MAILBOX to the other core. + */ +static inline void MAILBOX_SetValue(MAILBOX_Type *base, mailbox_cpu_id_t cpu_id, uint32_t mboxData) +{ + assert((cpu_id == kMAILBOX_CM0Plus) || (cpu_id == kMAILBOX_CM4)); + base->MBOXIRQ[cpu_id].IRQ = mboxData; +} + +/*! + * @brief Get data in the mailbox based on the CPU ID. + * + * @param base MAILBOX peripheral base address. + * @param cpu_id CPU id, kMAILBOX_CM0Plus is M0+ or kMAILBOX_CM4 is M4. + * + * @return Current mailbox data. + */ +static inline uint32_t MAILBOX_GetValue(MAILBOX_Type *base, mailbox_cpu_id_t cpu_id) +{ + assert((cpu_id == kMAILBOX_CM0Plus) || (cpu_id == kMAILBOX_CM4)); + return base->MBOXIRQ[cpu_id].IRQ; +} + +/*! + * @brief Set data bits in the mailbox based on the CPU ID. + * + * @param base MAILBOX peripheral base address. + * @param cpu_id CPU id, kMAILBOX_CM0Plus is M0+ or kMAILBOX_CM4 is M4. + * @param mboxSetBits Data bits to set in the mailbox. + * + * @note Sets data bits to send via the MAILBOX to the other core. A value of 0 will + * do nothing. Only sets bits selected with a 1 in it's bit position. + */ +static inline void MAILBOX_SetValueBits(MAILBOX_Type *base, mailbox_cpu_id_t cpu_id, uint32_t mboxSetBits) +{ + assert((cpu_id == kMAILBOX_CM0Plus) || (cpu_id == kMAILBOX_CM4)); + base->MBOXIRQ[cpu_id].IRQSET = mboxSetBits; +} + +/*! + * @brief Clear data bits in the mailbox based on the CPU ID. + * + * @param base MAILBOX peripheral base address. + * @param cpu_id CPU id, kMAILBOX_CM0Plus is M0+ or kMAILBOX_CM4 is M4. + * @param mboxClrBits Data bits to clear in the mailbox. + * + * @note Clear data bits to send via the MAILBOX to the other core. A value of 0 will + * do nothing. Only clears bits selected with a 1 in it's bit position. + */ +static inline void MAILBOX_ClearValueBits(MAILBOX_Type *base, mailbox_cpu_id_t cpu_id, uint32_t mboxClrBits) +{ + assert((cpu_id == kMAILBOX_CM0Plus) || (cpu_id == kMAILBOX_CM4)); + base->MBOXIRQ[cpu_id].IRQCLR = mboxClrBits; +} + +/*! + * @brief Get MUTEX state and lock mutex + * + * @param base MAILBOX peripheral base address. + * + * @return See note + * + * @note Returns '1' if the mutex was taken or '0' if another resources has the + * mutex locked. Once a mutex is taken, it can be returned with the MAILBOX_SetMutex() + * function. + */ +static inline uint32_t MAILBOX_GetMutex(MAILBOX_Type *base) +{ + return (base->MUTEX & MAILBOX_MUTEX_EX_MASK); +} + +/*! + * @brief Set MUTEX state + * + * @param base MAILBOX peripheral base address. + * + * @note Sets mutex state to '1' and allows other resources to get the mutex. + */ +static inline void MAILBOX_SetMutex(MAILBOX_Type *base) +{ + base->MUTEX = MAILBOX_MUTEX_EX_MASK; +} + +#if defined(__cplusplus) +} +#endif /*_cplusplus*/ +/*@}*/ + +#endif /* _FSL_MAILBOX_H_ */ diff --git a/platform/mcu/lpc54102/drivers/fsl_mrt.c b/platform/mcu/lpc54102/drivers/fsl_mrt.c new file mode 100644 index 0000000000..cd36ab2b4a --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_mrt.c @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_mrt.h" + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +/*! + * @brief Gets the instance from the base address + * + * @param base Multi-Rate timer peripheral base address + * + * @return The MRT instance + */ +static uint32_t MRT_GetInstance(MRT_Type *base); + +/******************************************************************************* + * Variables + ******************************************************************************/ +/*! @brief Pointers to MRT bases for each instance. */ +static MRT_Type *const s_mrtBases[] = MRT_BASE_PTRS; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +/*! @brief Pointers to MRT clocks for each instance. */ +static const clock_ip_name_t s_mrtClocks[] = MRT_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +/*! @brief Pointers to MRT resets for each instance. */ +static const reset_ip_name_t s_mrtResets[] = MRT_RSTS; + +/******************************************************************************* + * Code + ******************************************************************************/ +static uint32_t MRT_GetInstance(MRT_Type *base) +{ + uint32_t instance; + uint32_t mrtArrayCount = (sizeof(s_mrtBases) / sizeof(s_mrtBases[0])); + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < mrtArrayCount; instance++) + { + if (s_mrtBases[instance] == base) + { + break; + } + } + + assert(instance < mrtArrayCount); + + return instance; +} + +void MRT_Init(MRT_Type *base, const mrt_config_t *config) +{ + assert(config); + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Ungate the MRT clock */ + CLOCK_EnableClock(s_mrtClocks[MRT_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + + /* Reset the module */ + RESET_PeripheralReset(s_mrtResets[MRT_GetInstance(base)]); + + /* Set timer operating mode */ + base->MODCFG = MRT_MODCFG_MULTITASK(config->enableMultiTask); +} + +void MRT_Deinit(MRT_Type *base) +{ + /* Stop all the timers */ + MRT_StopTimer(base, kMRT_Channel_0); + MRT_StopTimer(base, kMRT_Channel_1); + MRT_StopTimer(base, kMRT_Channel_2); + MRT_StopTimer(base, kMRT_Channel_3); + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Gate the MRT clock*/ + CLOCK_DisableClock(s_mrtClocks[MRT_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +void MRT_UpdateTimerPeriod(MRT_Type *base, mrt_chnl_t channel, uint32_t count, bool immediateLoad) +{ + uint32_t newValue = count; + if (((base->CHANNEL[channel].CTRL & MRT_CHANNEL_CTRL_MODE_MASK) == kMRT_OneShotMode) || (immediateLoad)) + { + /* For one-shot interrupt mode, load the new value immediately even if user forgot to enable */ + newValue |= MRT_CHANNEL_INTVAL_LOAD_MASK; + } + + /* Update the timer interval value */ + base->CHANNEL[channel].INTVAL = newValue; +} diff --git a/platform/mcu/lpc54102/drivers/fsl_mrt.h b/platform/mcu/lpc54102/drivers/fsl_mrt.h new file mode 100644 index 0000000000..5638bf1675 --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_mrt.h @@ -0,0 +1,371 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_MRT_H_ +#define _FSL_MRT_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup mrt + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +#define FSL_MRT_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0 */ +/*@}*/ + +/*! @brief List of MRT channels */ +typedef enum _mrt_chnl +{ + kMRT_Channel_0 = 0U, /*!< MRT channel number 0*/ + kMRT_Channel_1, /*!< MRT channel number 1 */ + kMRT_Channel_2, /*!< MRT channel number 2 */ + kMRT_Channel_3 /*!< MRT channel number 3 */ +} mrt_chnl_t; + +/*! @brief List of MRT timer modes */ +typedef enum _mrt_timer_mode +{ + kMRT_RepeatMode = (0 << MRT_CHANNEL_CTRL_MODE_SHIFT), /*!< Repeat Interrupt mode */ + kMRT_OneShotMode = (1 << MRT_CHANNEL_CTRL_MODE_SHIFT), /*!< One-shot Interrupt mode */ + kMRT_OneShotStallMode = (2 << MRT_CHANNEL_CTRL_MODE_SHIFT) /*!< One-shot stall mode */ +} mrt_timer_mode_t; + +/*! @brief List of MRT interrupts */ +typedef enum _mrt_interrupt_enable +{ + kMRT_TimerInterruptEnable = MRT_CHANNEL_CTRL_INTEN_MASK /*!< Timer interrupt enable*/ +} mrt_interrupt_enable_t; + +/*! @brief List of MRT status flags */ +typedef enum _mrt_status_flags +{ + kMRT_TimerInterruptFlag = MRT_CHANNEL_STAT_INTFLAG_MASK, /*!< Timer interrupt flag */ + kMRT_TimerRunFlag = MRT_CHANNEL_STAT_RUN_MASK, /*!< Indicates state of the timer */ +} mrt_status_flags_t; + +/*! + * @brief MRT configuration structure + * + * This structure holds the configuration settings for the MRT peripheral. To initialize this + * structure to reasonable defaults, call the MRT_GetDefaultConfig() function and pass a + * pointer to your config structure instance. + * + * The config struct can be made const so it resides in flash + */ +typedef struct _mrt_config +{ + bool enableMultiTask; /*!< true: Timers run in multi-task mode; false: Timers run in hardware status mode */ +} mrt_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name Initialization and deinitialization + * @{ + */ + +/*! + * @brief Ungates the MRT clock and configures the peripheral for basic operation. + * + * @note This API should be called at the beginning of the application using the MRT driver. + * + * @param base Multi-Rate timer peripheral base address + * @param config Pointer to user's MRT config structure + */ +void MRT_Init(MRT_Type *base, const mrt_config_t *config); + +/*! + * @brief Gate the MRT clock + * + * @param base Multi-Rate timer peripheral base address + */ +void MRT_Deinit(MRT_Type *base); + +/*! + * @brief Fill in the MRT config struct with the default settings + * + * The default values are: + * @code + * config->enableMultiTask = false; + * @endcode + * @param config Pointer to user's MRT config structure. + */ +static inline void MRT_GetDefaultConfig(mrt_config_t *config) +{ + assert(config); + + /* Use hardware status operating mode */ + config->enableMultiTask = false; +} + +/*! + * @brief Sets up an MRT channel mode. + * + * @param base Multi-Rate timer peripheral base address + * @param channel Channel that is being configured. + * @param mode Timer mode to use for the channel. + */ +static inline void MRT_SetupChannelMode(MRT_Type *base, mrt_chnl_t channel, const mrt_timer_mode_t mode) +{ + uint32_t reg = base->CHANNEL[channel].CTRL; + + /* Clear old value */ + reg &= ~MRT_CHANNEL_CTRL_MODE_MASK; + /* Add the new mode */ + reg |= mode; + + base->CHANNEL[channel].CTRL = reg; +} + +/*! @}*/ + +/*! + * @name Interrupt Interface + * @{ + */ + +/*! + * @brief Enables the MRT interrupt. + * + * @param base Multi-Rate timer peripheral base address + * @param channel Timer channel number + * @param mask The interrupts to enable. This is a logical OR of members of the + * enumeration ::mrt_interrupt_enable_t + */ +static inline void MRT_EnableInterrupts(MRT_Type *base, mrt_chnl_t channel, uint32_t mask) +{ + base->CHANNEL[channel].CTRL |= mask; +} + +/*! + * @brief Disables the selected MRT interrupt. + * + * @param base Multi-Rate timer peripheral base address + * @param channel Timer channel number + * @param mask The interrupts to disable. This is a logical OR of members of the + * enumeration ::mrt_interrupt_enable_t + */ +static inline void MRT_DisableInterrupts(MRT_Type *base, mrt_chnl_t channel, uint32_t mask) +{ + base->CHANNEL[channel].CTRL &= ~mask; +} + +/*! + * @brief Gets the enabled MRT interrupts. + * + * @param base Multi-Rate timer peripheral base address + * @param channel Timer channel number + * + * @return The enabled interrupts. This is the logical OR of members of the + * enumeration ::mrt_interrupt_enable_t + */ +static inline uint32_t MRT_GetEnabledInterrupts(MRT_Type *base, mrt_chnl_t channel) +{ + return (base->CHANNEL[channel].CTRL & MRT_CHANNEL_CTRL_INTEN_MASK); +} + +/*! @}*/ + +/*! + * @name Status Interface + * @{ + */ + +/*! + * @brief Gets the MRT status flags + * + * @param base Multi-Rate timer peripheral base address + * @param channel Timer channel number + * + * @return The status flags. This is the logical OR of members of the + * enumeration ::mrt_status_flags_t + */ +static inline uint32_t MRT_GetStatusFlags(MRT_Type *base, mrt_chnl_t channel) +{ + return (base->CHANNEL[channel].STAT & (MRT_CHANNEL_STAT_INTFLAG_MASK | MRT_CHANNEL_STAT_RUN_MASK)); +} + +/*! + * @brief Clears the MRT status flags. + * + * @param base Multi-Rate timer peripheral base address + * @param channel Timer channel number + * @param mask The status flags to clear. This is a logical OR of members of the + * enumeration ::mrt_status_flags_t + */ +static inline void MRT_ClearStatusFlags(MRT_Type *base, mrt_chnl_t channel, uint32_t mask) +{ + base->CHANNEL[channel].STAT = (mask & MRT_CHANNEL_STAT_INTFLAG_MASK); +} + +/*! @}*/ + +/*! + * @name Read and Write the timer period + * @{ + */ + +/*! + * @brief Used to update the timer period in units of count. + * + * The new value will be immediately loaded or will be loaded at the end of the current time + * interval. For one-shot interrupt mode the new value will be immediately loaded. + * + * @note User can call the utility macros provided in fsl_common.h to convert to ticks + * + * @param base Multi-Rate timer peripheral base address + * @param channel Timer channel number + * @param count Timer period in units of ticks + * @param immediateLoad true: Load the new value immediately into the TIMER register; + * false: Load the new value at the end of current timer interval + */ +void MRT_UpdateTimerPeriod(MRT_Type *base, mrt_chnl_t channel, uint32_t count, bool immediateLoad); + +/*! + * @brief Reads the current timer counting value. + * + * This function returns the real-time timer counting value, in a range from 0 to a + * timer period. + * + * @note User can call the utility macros provided in fsl_common.h to convert ticks to usec or msec + * + * @param base Multi-Rate timer peripheral base address + * @param channel Timer channel number + * + * @return Current timer counting value in ticks + */ +static inline uint32_t MRT_GetCurrentTimerCount(MRT_Type *base, mrt_chnl_t channel) +{ + return base->CHANNEL[channel].TIMER; +} + +/*! @}*/ + +/*! + * @name Timer Start and Stop + * @{ + */ + +/*! + * @brief Starts the timer counting. + * + * After calling this function, timers load period value, counts down to 0 and + * depending on the timer mode it will either load the respective start value again or stop. + * + * @note User can call the utility macros provided in fsl_common.h to convert to ticks + * + * @param base Multi-Rate timer peripheral base address + * @param channel Timer channel number. + * @param count Timer period in units of ticks + */ +static inline void MRT_StartTimer(MRT_Type *base, mrt_chnl_t channel, uint32_t count) +{ + /* Write the timer interval value */ + base->CHANNEL[channel].INTVAL = count; +} + +/*! + * @brief Stops the timer counting. + * + * This function stops the timer from counting. + * + * @param base Multi-Rate timer peripheral base address + * @param channel Timer channel number. + */ +static inline void MRT_StopTimer(MRT_Type *base, mrt_chnl_t channel) +{ + /* Stop the timer immediately */ + base->CHANNEL[channel].INTVAL = MRT_CHANNEL_INTVAL_LOAD_MASK; +} + +/*! @}*/ + +/*! + * @name Get & release channel + * @{ + */ + +/*! + * @brief Find the available channel. + * + * This function returns the lowest available channel number. + * + * @param base Multi-Rate timer peripheral base address + */ +static inline uint32_t MRT_GetIdleChannel(MRT_Type *base) +{ + return base->IDLE_CH; +} + +/*! + * @brief Release the channel when the timer is using the multi-task mode. + * + * In multi-task mode, the INUSE flags allow more control over when MRT channels are released for + * further use. The user can hold on to a channel acquired by calling MRT_GetIdleChannel() for as + * long as it is needed and release it by calling this function. This removes the need to ask for + * an available channel for every use. + * + * @param base Multi-Rate timer peripheral base address + * @param channel Timer channel number. + */ +static inline void MRT_ReleaseChannel(MRT_Type *base, mrt_chnl_t channel) +{ + uint32_t reg = base->CHANNEL[channel].STAT; + + /* Clear flag bits to prevent accidentally clearing anything when writing back */ + reg = ~MRT_CHANNEL_STAT_INTFLAG_MASK; + reg |= MRT_CHANNEL_STAT_INUSE_MASK; + + base->CHANNEL[channel].STAT = reg; +} + +/*! @}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_MRT_H_ */ diff --git a/platform/mcu/lpc54102/drivers/fsl_pint.c b/platform/mcu/lpc54102/drivers/fsl_pint.c new file mode 100644 index 0000000000..86d87e9576 --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_pint.c @@ -0,0 +1,467 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_pint.h" + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/*! @brief Irq number array */ +static const IRQn_Type s_pintIRQ[FSL_FEATURE_PINT_NUMBER_OF_CONNECTED_OUTPUTS] = PINT_IRQS; + +/*! @brief Callback function array for PINT(s). */ +static pint_cb_t s_pintCallback[FSL_FEATURE_PINT_NUMBER_OF_CONNECTED_OUTPUTS]; + +/******************************************************************************* + * Code + ******************************************************************************/ + +void PINT_Init(PINT_Type *base) +{ + uint32_t i; + uint32_t pmcfg; + + assert(base); + + pmcfg = 0; + for (i = 0; i < FSL_FEATURE_PINT_NUMBER_OF_CONNECTED_OUTPUTS; i++) + { + s_pintCallback[i] = NULL; + } + + /* Disable all bit slices */ + for (i = 0; i < PINT_PIN_INT_COUNT; i++) + { + pmcfg = pmcfg | (kPINT_PatternMatchNever << (PININT_BITSLICE_CFG_START + (i * 3U))); + } + + /* Enable the peripheral clock */ + CLOCK_EnableClock(kCLOCK_Pint); + + /* Reset the peripheral */ + RESET_PeripheralReset(kPINT_RST_SHIFT_RSTn); + + /* Disable all pattern match bit slices */ + base->PMCFG = pmcfg; +} + +void PINT_PinInterruptConfig(PINT_Type *base, pint_pin_int_t intr, pint_pin_enable_t enable, pint_cb_t callback) +{ + assert(base); + + /* Clear Rise and Fall flags first */ + PINT_PinInterruptClrRiseFlag(base, intr); + PINT_PinInterruptClrFallFlag(base, intr); + + /* select level or edge sensitive */ + base->ISEL = (base->ISEL & ~(1U << intr)) | ((enable & PINT_PIN_INT_LEVEL) ? (1U << intr) : 0U); + + /* enable rising or level interrupt */ + if (enable & (PINT_PIN_INT_LEVEL | PINT_PIN_INT_RISE)) + { + base->SIENR = 1U << intr; + } + else + { + base->CIENR = 1U << intr; + } + + /* Enable falling or select high level */ + if (enable & PINT_PIN_INT_FALL_OR_HIGH_LEVEL) + { + base->SIENF = 1U << intr; + } + else + { + base->CIENF = 1U << intr; + } + + s_pintCallback[intr] = callback; +} + +void PINT_PinInterruptGetConfig(PINT_Type *base, pint_pin_int_t pintr, pint_pin_enable_t *enable, pint_cb_t *callback) +{ + uint32_t mask; + bool level; + + assert(base); + + *enable = kPINT_PinIntEnableNone; + level = false; + + mask = 1U << pintr; + if (base->ISEL & mask) + { + /* Pin interrupt is level sensitive */ + level = true; + } + + if (base->IENR & mask) + { + if (level) + { + /* Level interrupt is enabled */ + *enable = kPINT_PinIntEnableLowLevel; + } + else + { + /* Rising edge interrupt */ + *enable = kPINT_PinIntEnableRiseEdge; + } + } + + if (base->IENF & mask) + { + if (level) + { + /* Level interrupt is active high */ + *enable = kPINT_PinIntEnableHighLevel; + } + else + { + /* Either falling or both edge */ + if (*enable == kPINT_PinIntEnableRiseEdge) + { + /* Rising and faling edge */ + *enable = kPINT_PinIntEnableBothEdges; + } + else + { + /* Falling edge */ + *enable = kPINT_PinIntEnableFallEdge; + } + } + } + + *callback = s_pintCallback[pintr]; +} + +void PINT_PatternMatchConfig(PINT_Type *base, pint_pmatch_bslice_t bslice, pint_pmatch_cfg_t *cfg) +{ + uint32_t src_shift; + uint32_t cfg_shift; + uint32_t pmcfg; + + assert(base); + + src_shift = PININT_BITSLICE_SRC_START + (bslice * 3U); + cfg_shift = PININT_BITSLICE_CFG_START + (bslice * 3U); + + /* Input source selection for selected bit slice */ + base->PMSRC = (base->PMSRC & ~(PININT_BITSLICE_SRC_MASK << src_shift)) | (cfg->bs_src << src_shift); + + /* Bit slice configuration */ + pmcfg = base->PMCFG; + pmcfg = (pmcfg & ~(PININT_BITSLICE_CFG_MASK << cfg_shift)) | (cfg->bs_cfg << cfg_shift); + + /* If end point is true, enable the bits */ + if (bslice != 7U) + { + if (cfg->end_point) + { + pmcfg |= (0x1U << bslice); + } + else + { + pmcfg &= ~(0x1U << bslice); + } + } + + base->PMCFG = pmcfg; + + /* Save callback pointer */ + s_pintCallback[bslice] = cfg->callback; +} + +void PINT_PatternMatchGetConfig(PINT_Type *base, pint_pmatch_bslice_t bslice, pint_pmatch_cfg_t *cfg) +{ + uint32_t src_shift; + uint32_t cfg_shift; + + assert(base); + + src_shift = PININT_BITSLICE_SRC_START + (bslice * 3U); + cfg_shift = PININT_BITSLICE_CFG_START + (bslice * 3U); + + cfg->bs_src = (pint_pmatch_input_src_t)((base->PMSRC & (PININT_BITSLICE_SRC_MASK << src_shift)) >> src_shift); + cfg->bs_cfg = (pint_pmatch_bslice_cfg_t)((base->PMCFG & (PININT_BITSLICE_CFG_MASK << cfg_shift)) >> cfg_shift); + + if (bslice == 7U) + { + cfg->end_point = true; + } + else + { + cfg->end_point = (base->PMCFG & (0x1U << bslice)) >> bslice; + } + cfg->callback = s_pintCallback[bslice]; +} + +uint32_t PINT_PatternMatchResetDetectLogic(PINT_Type *base) +{ + uint32_t pmctrl; + uint32_t pmstatus; + uint32_t pmsrc; + + pmctrl = PINT->PMCTRL; + pmstatus = pmctrl >> PINT_PMCTRL_PMAT_SHIFT; + if (pmstatus) + { + /* Reset Pattern match engine detection logic */ + pmsrc = base->PMSRC; + base->PMSRC = pmsrc; + } + return (pmstatus); +} + +void PINT_EnableCallback(PINT_Type *base) +{ + uint32_t i; + + assert(base); + + PINT_PinInterruptClrStatusAll(base); + for (i = 0; i < FSL_FEATURE_PINT_NUMBER_OF_CONNECTED_OUTPUTS; i++) + { + NVIC_ClearPendingIRQ(s_pintIRQ[i]); + PINT_PinInterruptClrStatus(base, (pint_pin_int_t)i); + EnableIRQ(s_pintIRQ[i]); + } +} + +void PINT_DisableCallback(PINT_Type *base) +{ + uint32_t i; + + assert(base); + + for (i = 0; i < FSL_FEATURE_PINT_NUMBER_OF_CONNECTED_OUTPUTS; i++) + { + DisableIRQ(s_pintIRQ[i]); + PINT_PinInterruptClrStatus(base, (pint_pin_int_t)i); + NVIC_ClearPendingIRQ(s_pintIRQ[i]); + } +} + +void PINT_Deinit(PINT_Type *base) +{ + uint32_t i; + + assert(base); + + /* Cleanup */ + PINT_DisableCallback(base); + for (i = 0; i < FSL_FEATURE_PINT_NUMBER_OF_CONNECTED_OUTPUTS; i++) + { + s_pintCallback[i] = NULL; + } + + /* Reset the peripheral */ + RESET_PeripheralReset(kPINT_RST_SHIFT_RSTn); + + /* Disable the peripheral clock */ + CLOCK_DisableClock(kCLOCK_Pint); +} + +/* IRQ handler functions overloading weak symbols in the startup */ +void PIN_INT0_DriverIRQHandler(void) +{ + uint32_t pmstatus; + + /* Reset pattern match detection */ + pmstatus = PINT_PatternMatchResetDetectLogic(PINT); + /* Call user function */ + if (s_pintCallback[kPINT_PinInt0] != NULL) + { + s_pintCallback[kPINT_PinInt0](kPINT_PinInt0, pmstatus); + } + /* Clear Pin interrupt after callback */ + PINT_PinInterruptClrStatus(PINT, kPINT_PinInt0); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +#if (FSL_FEATURE_PINT_NUMBER_OF_CONNECTED_OUTPUTS > 1U) +void PIN_INT1_DriverIRQHandler(void) +{ + uint32_t pmstatus; + + /* Reset pattern match detection */ + pmstatus = PINT_PatternMatchResetDetectLogic(PINT); + /* Call user function */ + if (s_pintCallback[kPINT_PinInt1] != NULL) + { + s_pintCallback[kPINT_PinInt1](kPINT_PinInt1, pmstatus); + } + /* Clear Pin interrupt after callback */ + PINT_PinInterruptClrStatus(PINT, kPINT_PinInt1); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif + +#if (FSL_FEATURE_PINT_NUMBER_OF_CONNECTED_OUTPUTS > 2U) +void PIN_INT2_DriverIRQHandler(void) +{ + uint32_t pmstatus; + + /* Reset pattern match detection */ + pmstatus = PINT_PatternMatchResetDetectLogic(PINT); + /* Call user function */ + if (s_pintCallback[kPINT_PinInt2] != NULL) + { + s_pintCallback[kPINT_PinInt2](kPINT_PinInt2, pmstatus); + } + /* Clear Pin interrupt after callback */ + PINT_PinInterruptClrStatus(PINT, kPINT_PinInt2); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif + +#if (FSL_FEATURE_PINT_NUMBER_OF_CONNECTED_OUTPUTS > 3U) +void PIN_INT3_DriverIRQHandler(void) +{ + uint32_t pmstatus; + + /* Reset pattern match detection */ + pmstatus = PINT_PatternMatchResetDetectLogic(PINT); + /* Call user function */ + if (s_pintCallback[kPINT_PinInt3] != NULL) + { + s_pintCallback[kPINT_PinInt3](kPINT_PinInt3, pmstatus); + } + /* Clear Pin interrupt after callback */ + PINT_PinInterruptClrStatus(PINT, kPINT_PinInt3); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif + +#if (FSL_FEATURE_PINT_NUMBER_OF_CONNECTED_OUTPUTS > 4U) +void PIN_INT4_DriverIRQHandler(void) +{ + uint32_t pmstatus; + + /* Reset pattern match detection */ + pmstatus = PINT_PatternMatchResetDetectLogic(PINT); + /* Call user function */ + if (s_pintCallback[kPINT_PinInt4] != NULL) + { + s_pintCallback[kPINT_PinInt4](kPINT_PinInt4, pmstatus); + } + /* Clear Pin interrupt after callback */ + PINT_PinInterruptClrStatus(PINT, kPINT_PinInt4); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif + +#if (FSL_FEATURE_PINT_NUMBER_OF_CONNECTED_OUTPUTS > 5U) +void PIN_INT5_DriverIRQHandler(void) +{ + uint32_t pmstatus; + + /* Reset pattern match detection */ + pmstatus = PINT_PatternMatchResetDetectLogic(PINT); + /* Call user function */ + if (s_pintCallback[kPINT_PinInt5] != NULL) + { + s_pintCallback[kPINT_PinInt5](kPINT_PinInt5, pmstatus); + } + /* Clear Pin interrupt after callback */ + PINT_PinInterruptClrStatus(PINT, kPINT_PinInt5); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif + +#if (FSL_FEATURE_PINT_NUMBER_OF_CONNECTED_OUTPUTS > 6U) +void PIN_INT6_DriverIRQHandler(void) +{ + uint32_t pmstatus; + + /* Reset pattern match detection */ + pmstatus = PINT_PatternMatchResetDetectLogic(PINT); + /* Call user function */ + if (s_pintCallback[kPINT_PinInt6] != NULL) + { + s_pintCallback[kPINT_PinInt6](kPINT_PinInt6, pmstatus); + } + /* Clear Pin interrupt after callback */ + PINT_PinInterruptClrStatus(PINT, kPINT_PinInt6); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif + +#if (FSL_FEATURE_PINT_NUMBER_OF_CONNECTED_OUTPUTS > 7U) +void PIN_INT7_DriverIRQHandler(void) +{ + uint32_t pmstatus; + + /* Reset pattern match detection */ + pmstatus = PINT_PatternMatchResetDetectLogic(PINT); + /* Call user function */ + if (s_pintCallback[kPINT_PinInt7] != NULL) + { + s_pintCallback[kPINT_PinInt7](kPINT_PinInt7, pmstatus); + } + /* Clear Pin interrupt after callback */ + PINT_PinInterruptClrStatus(PINT, kPINT_PinInt7); +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif diff --git a/platform/mcu/lpc54102/drivers/fsl_pint.h b/platform/mcu/lpc54102/drivers/fsl_pint.h new file mode 100644 index 0000000000..ae3ce30428 --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_pint.h @@ -0,0 +1,568 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_PINT_H_ +#define _FSL_PINT_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup pint_driver + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +#define FSL_PINT_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0 */ +/*@}*/ + +/* Number of interrupt line supported by PINT */ +#define PINT_PIN_INT_COUNT 8U + +/* Number of input sources supported by PINT */ +#define PINT_INPUT_COUNT 8U + +/* PININT Bit slice source register bits */ +#define PININT_BITSLICE_SRC_START 8U +#define PININT_BITSLICE_SRC_MASK 7U + +/* PININT Bit slice configuration register bits */ +#define PININT_BITSLICE_CFG_START 8U +#define PININT_BITSLICE_CFG_MASK 7U +#define PININT_BITSLICE_ENDP_MASK 7U + +#define PINT_PIN_INT_LEVEL 0x10U +#define PINT_PIN_INT_EDGE 0x00U +#define PINT_PIN_INT_FALL_OR_HIGH_LEVEL 0x02U +#define PINT_PIN_INT_RISE 0x01U +#define PINT_PIN_RISE_EDGE (PINT_PIN_INT_EDGE | PINT_PIN_INT_RISE) +#define PINT_PIN_FALL_EDGE (PINT_PIN_INT_EDGE | PINT_PIN_INT_FALL_OR_HIGH_LEVEL) +#define PINT_PIN_BOTH_EDGE (PINT_PIN_INT_EDGE | PINT_PIN_INT_RISE | PINT_PIN_INT_FALL_OR_HIGH_LEVEL) +#define PINT_PIN_LOW_LEVEL (PINT_PIN_INT_LEVEL) +#define PINT_PIN_HIGH_LEVEL (PINT_PIN_INT_LEVEL | PINT_PIN_INT_FALL_OR_HIGH_LEVEL) + +/*! @brief PINT Pin Interrupt enable type */ +typedef enum _pint_pin_enable +{ + kPINT_PinIntEnableNone = 0U, /*!< Do not generate Pin Interrupt */ + kPINT_PinIntEnableRiseEdge = PINT_PIN_RISE_EDGE, /*!< Generate Pin Interrupt on rising edge */ + kPINT_PinIntEnableFallEdge = PINT_PIN_FALL_EDGE, /*!< Generate Pin Interrupt on falling edge */ + kPINT_PinIntEnableBothEdges = PINT_PIN_BOTH_EDGE, /*!< Generate Pin Interrupt on both edges */ + kPINT_PinIntEnableLowLevel = PINT_PIN_LOW_LEVEL, /*!< Generate Pin Interrupt on low level */ + kPINT_PinIntEnableHighLevel = PINT_PIN_HIGH_LEVEL /*!< Generate Pin Interrupt on high level */ +} pint_pin_enable_t; + +/*! @brief PINT Pin Interrupt type */ +typedef enum _pint_int +{ + kPINT_PinInt0 = 0U, /*!< Pin Interrupt 0 */ +#if (FSL_FEATURE_PINT_NUMBER_OF_CONNECTED_OUTPUTS > 1U) + kPINT_PinInt1 = 1U, /*!< Pin Interrupt 1 */ +#endif +#if (FSL_FEATURE_PINT_NUMBER_OF_CONNECTED_OUTPUTS > 2U) + kPINT_PinInt2 = 2U, /*!< Pin Interrupt 2 */ +#endif +#if (FSL_FEATURE_PINT_NUMBER_OF_CONNECTED_OUTPUTS > 3U) + kPINT_PinInt3 = 3U, /*!< Pin Interrupt 3 */ +#endif +#if (FSL_FEATURE_PINT_NUMBER_OF_CONNECTED_OUTPUTS > 4U) + kPINT_PinInt4 = 4U, /*!< Pin Interrupt 4 */ +#endif +#if (FSL_FEATURE_PINT_NUMBER_OF_CONNECTED_OUTPUTS > 5U) + kPINT_PinInt5 = 5U, /*!< Pin Interrupt 5 */ +#endif +#if (FSL_FEATURE_PINT_NUMBER_OF_CONNECTED_OUTPUTS > 6U) + kPINT_PinInt6 = 6U, /*!< Pin Interrupt 6 */ +#endif +#if (FSL_FEATURE_PINT_NUMBER_OF_CONNECTED_OUTPUTS > 7U) + kPINT_PinInt7 = 7U, /*!< Pin Interrupt 7 */ +#endif +} pint_pin_int_t; + +/*! @brief PINT Pattern Match bit slice input source type */ +typedef enum _pint_pmatch_input_src +{ + kPINT_PatternMatchInp0Src = 0U, /*!< Input source 0 */ + kPINT_PatternMatchInp1Src = 1U, /*!< Input source 1 */ + kPINT_PatternMatchInp2Src = 2U, /*!< Input source 2 */ + kPINT_PatternMatchInp3Src = 3U, /*!< Input source 3 */ + kPINT_PatternMatchInp4Src = 4U, /*!< Input source 4 */ + kPINT_PatternMatchInp5Src = 5U, /*!< Input source 5 */ + kPINT_PatternMatchInp6Src = 6U, /*!< Input source 6 */ + kPINT_PatternMatchInp7Src = 7U, /*!< Input source 7 */ +} pint_pmatch_input_src_t; + +/*! @brief PINT Pattern Match bit slice type */ +typedef enum _pint_pmatch_bslice +{ + kPINT_PatternMatchBSlice0 = 0U, /*!< Bit slice 0 */ +#if (FSL_FEATURE_PINT_NUMBER_OF_CONNECTED_OUTPUTS > 1U) + kPINT_PatternMatchBSlice1 = 1U, /*!< Bit slice 1 */ +#endif +#if (FSL_FEATURE_PINT_NUMBER_OF_CONNECTED_OUTPUTS > 2U) + kPINT_PatternMatchBSlice2 = 2U, /*!< Bit slice 2 */ +#endif +#if (FSL_FEATURE_PINT_NUMBER_OF_CONNECTED_OUTPUTS > 3U) + kPINT_PatternMatchBSlice3 = 3U, /*!< Bit slice 3 */ +#endif +#if (FSL_FEATURE_PINT_NUMBER_OF_CONNECTED_OUTPUTS > 4U) + kPINT_PatternMatchBSlice4 = 4U, /*!< Bit slice 4 */ +#endif +#if (FSL_FEATURE_PINT_NUMBER_OF_CONNECTED_OUTPUTS > 5U) + kPINT_PatternMatchBSlice5 = 5U, /*!< Bit slice 5 */ +#endif +#if (FSL_FEATURE_PINT_NUMBER_OF_CONNECTED_OUTPUTS > 6U) + kPINT_PatternMatchBSlice6 = 6U, /*!< Bit slice 6 */ +#endif +#if (FSL_FEATURE_PINT_NUMBER_OF_CONNECTED_OUTPUTS > 7U) + kPINT_PatternMatchBSlice7 = 7U, /*!< Bit slice 7 */ +#endif +} pint_pmatch_bslice_t; + +/*! @brief PINT Pattern Match configuration type */ +typedef enum _pint_pmatch_bslice_cfg +{ + kPINT_PatternMatchAlways = 0U, /*!< Always Contributes to product term match */ + kPINT_PatternMatchStickyRise = 1U, /*!< Sticky Rising edge */ + kPINT_PatternMatchStickyFall = 2U, /*!< Sticky Falling edge */ + kPINT_PatternMatchStickyBothEdges = 3U, /*!< Sticky Rising or Falling edge */ + kPINT_PatternMatchHigh = 4U, /*!< High level */ + kPINT_PatternMatchLow = 5U, /*!< Low level */ + kPINT_PatternMatchNever = 6U, /*!< Never contributes to product term match */ + kPINT_PatternMatchBothEdges = 7U, /*!< Either rising or falling edge */ +} pint_pmatch_bslice_cfg_t; + +/*! @brief PINT Callback function. */ +typedef void (*pint_cb_t)(pint_pin_int_t pintr, uint32_t pmatch_status); + +typedef struct _pint_pmatch_cfg +{ + pint_pmatch_input_src_t bs_src; + pint_pmatch_bslice_cfg_t bs_cfg; + bool end_point; + pint_cb_t callback; +} pint_pmatch_cfg_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Initialize PINT peripheral. + + * This function initializes the PINT peripheral and enables the clock. + * + * @param base Base address of the PINT peripheral. + * + * @retval None. + */ +void PINT_Init(PINT_Type *base); + +/*! + * @brief Configure PINT peripheral pin interrupt. + + * This function configures a given pin interrupt. + * + * @param base Base address of the PINT peripheral. + * @param intr Pin interrupt. + * @param enable Selects detection logic. + * @param callback Callback. + * + * @retval None. + */ +void PINT_PinInterruptConfig(PINT_Type *base, pint_pin_int_t intr, pint_pin_enable_t enable, pint_cb_t callback); + +/*! + * @brief Get PINT peripheral pin interrupt configuration. + + * This function returns the configuration of a given pin interrupt. + * + * @param base Base address of the PINT peripheral. + * @param pintr Pin interrupt. + * @param enable Pointer to store the detection logic. + * @param callback Callback. + * + * @retval None. + */ +void PINT_PinInterruptGetConfig(PINT_Type *base, pint_pin_int_t pintr, pint_pin_enable_t *enable, pint_cb_t *callback); + +/*! + * @brief Clear Selected pin interrupt status. + + * This function clears the selected pin interrupt status. + * + * @param base Base address of the PINT peripheral. + * @param pintr Pin interrupt. + * + * @retval None. + */ +static inline void PINT_PinInterruptClrStatus(PINT_Type *base, pint_pin_int_t pintr) +{ + base->IST = (1U << pintr); +} + +/*! + * @brief Get Selected pin interrupt status. + + * This function returns the selected pin interrupt status. + * + * @param base Base address of the PINT peripheral. + * @param pintr Pin interrupt. + * + * @retval status = 0 No pin interrupt request. = 1 Selected Pin interrupt request active. + */ +static inline uint32_t PINT_PinInterruptGetStatus(PINT_Type *base, pint_pin_int_t pintr) +{ + return ((base->IST & (1U << pintr)) ? 1U : 0U); +} + +/*! + * @brief Clear all pin interrupts status. + + * This function clears the status of all pin interrupts. + * + * @param base Base address of the PINT peripheral. + * + * @retval None. + */ +static inline void PINT_PinInterruptClrStatusAll(PINT_Type *base) +{ + base->IST = PINT_IST_PSTAT_MASK; +} + +/*! + * @brief Get all pin interrupts status. + + * This function returns the status of all pin interrupts. + * + * @param base Base address of the PINT peripheral. + * + * @retval status Each bit position indicates the status of corresponding pin interrupt. + * = 0 No pin interrupt request. = 1 Pin interrupt request active. + */ +static inline uint32_t PINT_PinInterruptGetStatusAll(PINT_Type *base) +{ + return (base->IST); +} + +/*! + * @brief Clear Selected pin interrupt fall flag. + + * This function clears the selected pin interrupt fall flag. + * + * @param base Base address of the PINT peripheral. + * @param pintr Pin interrupt. + * + * @retval None. + */ +static inline void PINT_PinInterruptClrFallFlag(PINT_Type *base, pint_pin_int_t pintr) +{ + base->FALL = (1U << pintr); +} + +/*! + * @brief Get selected pin interrupt fall flag. + + * This function returns the selected pin interrupt fall flag. + * + * @param base Base address of the PINT peripheral. + * @param pintr Pin interrupt. + * + * @retval flag = 0 Falling edge has not been detected. = 1 Falling edge has been detected. + */ +static inline uint32_t PINT_PinInterruptGetFallFlag(PINT_Type *base, pint_pin_int_t pintr) +{ + return ((base->FALL & (1U << pintr)) ? 1U : 0U); +} + +/*! + * @brief Clear all pin interrupt fall flags. + + * This function clears the fall flag for all pin interrupts. + * + * @param base Base address of the PINT peripheral. + * + * @retval None. + */ +static inline void PINT_PinInterruptClrFallFlagAll(PINT_Type *base) +{ + base->FALL = PINT_FALL_FDET_MASK; +} + +/*! + * @brief Get all pin interrupt fall flags. + + * This function returns the fall flag of all pin interrupts. + * + * @param base Base address of the PINT peripheral. + * + * @retval flags Each bit position indicates the falling edge detection of the corresponding pin interrupt. + * 0 Falling edge has not been detected. = 1 Falling edge has been detected. + */ +static inline uint32_t PINT_PinInterruptGetFallFlagAll(PINT_Type *base) +{ + return (base->FALL); +} + +/*! + * @brief Clear Selected pin interrupt rise flag. + + * This function clears the selected pin interrupt rise flag. + * + * @param base Base address of the PINT peripheral. + * @param pintr Pin interrupt. + * + * @retval None. + */ +static inline void PINT_PinInterruptClrRiseFlag(PINT_Type *base, pint_pin_int_t pintr) +{ + base->RISE = (1U << pintr); +} + +/*! + * @brief Get selected pin interrupt rise flag. + + * This function returns the selected pin interrupt rise flag. + * + * @param base Base address of the PINT peripheral. + * @param pintr Pin interrupt. + * + * @retval flag = 0 Rising edge has not been detected. = 1 Rising edge has been detected. + */ +static inline uint32_t PINT_PinInterruptGetRiseFlag(PINT_Type *base, pint_pin_int_t pintr) +{ + return ((base->RISE & (1U << pintr)) ? 1U : 0U); +} + +/*! + * @brief Clear all pin interrupt rise flags. + + * This function clears the rise flag for all pin interrupts. + * + * @param base Base address of the PINT peripheral. + * + * @retval None. + */ +static inline void PINT_PinInterruptClrRiseFlagAll(PINT_Type *base) +{ + base->RISE = PINT_RISE_RDET_MASK; +} + +/*! + * @brief Get all pin interrupt rise flags. + + * This function returns the rise flag of all pin interrupts. + * + * @param base Base address of the PINT peripheral. + * + * @retval flags Each bit position indicates the rising edge detection of the corresponding pin interrupt. + * 0 Rising edge has not been detected. = 1 Rising edge has been detected. + */ +static inline uint32_t PINT_PinInterruptGetRiseFlagAll(PINT_Type *base) +{ + return (base->RISE); +} + +/*! + * @brief Configure PINT pattern match. + + * This function configures a given pattern match bit slice. + * + * @param base Base address of the PINT peripheral. + * @param bslice Pattern match bit slice number. + * @param cfg Pointer to bit slice configuration. + * + * @retval None. + */ +void PINT_PatternMatchConfig(PINT_Type *base, pint_pmatch_bslice_t bslice, pint_pmatch_cfg_t *cfg); + +/*! + * @brief Get PINT pattern match configuration. + + * This function returns the configuration of a given pattern match bit slice. + * + * @param base Base address of the PINT peripheral. + * @param bslice Pattern match bit slice number. + * @param cfg Pointer to bit slice configuration. + * + * @retval None. + */ +void PINT_PatternMatchGetConfig(PINT_Type *base, pint_pmatch_bslice_t bslice, pint_pmatch_cfg_t *cfg); + +/*! + * @brief Get pattern match bit slice status. + + * This function returns the status of selected bit slice. + * + * @param base Base address of the PINT peripheral. + * @param bslice Pattern match bit slice number. + * + * @retval status = 0 Match has not been detected. = 1 Match has been detected. + */ +static inline uint32_t PINT_PatternMatchGetStatus(PINT_Type *base, pint_pmatch_bslice_t bslice) +{ + return ((base->PMCTRL >> PINT_PMCTRL_PMAT_SHIFT) & (0x1U << bslice)) >> bslice; +} + +/*! + * @brief Get status of all pattern match bit slices. + + * This function returns the status of all bit slices. + * + * @param base Base address of the PINT peripheral. + * + * @retval status Each bit position indicates the match status of corresponding bit slice. + * = 0 Match has not been detected. = 1 Match has been detected. + */ +static inline uint32_t PINT_PatternMatchGetStatusAll(PINT_Type *base) +{ + return base->PMCTRL >> PINT_PMCTRL_PMAT_SHIFT; +} + +/*! + * @brief Reset pattern match detection logic. + + * This function resets the pattern match detection logic if any of the product term is matching. + * + * @param base Base address of the PINT peripheral. + * + * @retval pmstatus Each bit position indicates the match status of corresponding bit slice. + * = 0 Match was detected. = 1 Match was not detected. + */ +uint32_t PINT_PatternMatchResetDetectLogic(PINT_Type *base); + +/*! + * @brief Enable pattern match function. + + * This function enables the pattern match function. + * + * @param base Base address of the PINT peripheral. + * + * @retval None. + */ +static inline void PINT_PatternMatchEnable(PINT_Type *base) +{ + base->PMCTRL = (base->PMCTRL & PINT_PMCTRL_ENA_RXEV_MASK) | PINT_PMCTRL_SEL_PMATCH_MASK; +} + +/*! + * @brief Disable pattern match function. + + * This function disables the pattern match function. + * + * @param base Base address of the PINT peripheral. + * + * @retval None. + */ +static inline void PINT_PatternMatchDisable(PINT_Type *base) +{ + base->PMCTRL = (base->PMCTRL & PINT_PMCTRL_ENA_RXEV_MASK) & ~PINT_PMCTRL_SEL_PMATCH_MASK; +} + +/*! + * @brief Enable RXEV output. + + * This function enables the pattern match RXEV output. + * + * @param base Base address of the PINT peripheral. + * + * @retval None. + */ +static inline void PINT_PatternMatchEnableRXEV(PINT_Type *base) +{ + base->PMCTRL = (base->PMCTRL & PINT_PMCTRL_SEL_PMATCH_MASK) | PINT_PMCTRL_ENA_RXEV_MASK; +} + +/*! + * @brief Disable RXEV output. + + * This function disables the pattern match RXEV output. + * + * @param base Base address of the PINT peripheral. + * + * @retval None. + */ +static inline void PINT_PatternMatchDisableRXEV(PINT_Type *base) +{ + base->PMCTRL = (base->PMCTRL & PINT_PMCTRL_SEL_PMATCH_MASK) & ~PINT_PMCTRL_ENA_RXEV_MASK; +} + +/*! + * @brief Enable callback. + + * This function enables the interrupt for the selected PINT peripheral. Although the pin(s) are monitored + * as soon as they are enabled, the callback function is not enabled until this function is called. + * + * @param base Base address of the PINT peripheral. + * + * @retval None. + */ +void PINT_EnableCallback(PINT_Type *base); + +/*! + * @brief Disable callback. + + * This function disables the interrupt for the selected PINT peripheral. Although the pins are still + * being monitored but the callback function is not called. + * + * @param base Base address of the peripheral. + * + * @retval None. + */ +void PINT_DisableCallback(PINT_Type *base); + +/*! + * @brief Deinitialize PINT peripheral. + + * This function disables the PINT clock. + * + * @param base Base address of the PINT peripheral. + * + * @retval None. + */ +void PINT_Deinit(PINT_Type *base); + +#ifdef __cplusplus +} +#endif + +/*@}*/ + +#endif /* _FSL_PINT_H_ */ diff --git a/platform/mcu/lpc54102/drivers/fsl_power.c b/platform/mcu/lpc54102/drivers/fsl_power.c new file mode 100644 index 0000000000..c0baad5de8 --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_power.c @@ -0,0 +1,36 @@ +/* + * Copyright 2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "fsl_common.h" +#include "fsl_power.h" + +/******************************************************************************* + * Code + ******************************************************************************/ + +/* Empty file since implementation is in header file and power library */ diff --git a/platform/mcu/lpc54102/drivers/fsl_power.h b/platform/mcu/lpc54102/drivers/fsl_power.h new file mode 100644 index 0000000000..279311b23b --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_power.h @@ -0,0 +1,239 @@ +/* + * Copyright 2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_POWER_H_ +#define _FSL_POWER_H_ + +#include "fsl_common.h" + +/*! @addtogroup power */ +/*! @{ */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief power driver version 2.0.0. */ +#define FSL_POWER_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*@}*/ + +#define MAKE_PD_BITS(reg, slot) ((reg << 8) | slot) +#define PDRCFG0 0x0U + +typedef enum pd_bits +{ + kPDRUNCFG_PD_IRC_OSC = MAKE_PD_BITS(PDRCFG0, 3U), + kPDRUNCFG_PD_IRC = MAKE_PD_BITS(PDRCFG0, 4U), + kPDRUNCFG_PD_FLASH = MAKE_PD_BITS(PDRCFG0, 5U), + kPDRUNCFG_PD_BOD_RST = MAKE_PD_BITS(PDRCFG0, 7U), + kPDRUNCFG_PD_BOD_INTR = MAKE_PD_BITS(PDRCFG0, 8U), + kPDRUNCFG_PD_ADC0 = MAKE_PD_BITS(PDRCFG0, 10U), + kPDRUNCFG_PD_SRAM0A = MAKE_PD_BITS(PDRCFG0, 13U), + kPDRUNCFG_PD_SRAM0B = MAKE_PD_BITS(PDRCFG0, 14U), + kPDRUNCFG_PD_SRAM1 = MAKE_PD_BITS(PDRCFG0, 15U), + kPDRUNCFG_PD_SRAM2 = MAKE_PD_BITS(PDRCFG0, 16U), + kPDRUNCFG_PD_ROM = MAKE_PD_BITS(PDRCFG0, 17U), + kPDRUNCFG_PD_VDDA = MAKE_PD_BITS(PDRCFG0, 19U), + kPDRUNCFG_PD_WDT_OSC = MAKE_PD_BITS(PDRCFG0, 20U), + kPDRUNCFG_PD_SYS_PLL = MAKE_PD_BITS(PDRCFG0, 22U), + kPDRUNCFG_PD_VREFP = MAKE_PD_BITS(PDRCFG0, 23U), + kPDRUNCFG_PD_32K_OSC = MAKE_PD_BITS(PDRCFG0, 24U), + kPDRUNCFG_ForceUnsigned = 0x80000000U + +} pd_bit_t; + +/* Power mode configuration API parameter */ +typedef enum _power_mode_config +{ + kPmu_Sleep = 0U, + kPmu_Deep_Sleep = 1U, + kPmu_Power_Down = 2U, + kPmu_Deep_PowerDown = 3U, +} power_mode_cfg_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#ifdef __cplusplus +extern "C" { +#endif + +/*! +* @name Power Configuration +* @{ +*/ + +/*! + * @brief API to enable PDRUNCFG bit in the Syscon. Note that enabling the bit powers down the peripheral + * + * @param en peripheral for which to enable the PDRUNCFG bit + * @return none + */ +static inline void POWER_EnablePD(pd_bit_t en) +{ + /* PDRUNCFGSET */ + SYSCON->PDRUNCFGSET = (1UL << (en & 0xffU)); +} + +/*! + * @brief API to disable PDRUNCFG bit in the Syscon. Note that disabling the bit powers up the peripheral + * + * @param en peripheral for which to disable the PDRUNCFG bit + * @return none + */ +static inline void POWER_DisablePD(pd_bit_t en) +{ + /* PDRUNCFGCLR */ + SYSCON->PDRUNCFGCLR = (1UL << (en & 0xffU)); +} + +/*! + * @brief API to enable deep sleep bit in the ARM Core. + * + * @return none + */ +static inline void POWER_EnableDeepSleep(void) +{ + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; +} + +/*! + * @brief API to disable deep sleep bit in the ARM Core. + * + * @return none + */ +static inline void POWER_DisableDeepSleep(void) +{ + SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; +} + +/*! + * @brief API in power lib to power down flash. + * + * @return none + */ +void Chip_POWER_SetFLASHPower(uint32_t new_power_mode); + +/*! + * @brief API to power down flash controller. + * + * @return none + */ +static inline void POWER_PowerDownFlash(void) +{ + Chip_POWER_SetFLASHPower(0U); + /* TURN OFF clock for Flash Controller (only needed for FLASH programming, will be turned on by ROM API) */ + CLOCK_DisableClock(kCLOCK_Flash); + + /* TURN OFF clock for Flash Accelerator */ + CLOCK_DisableClock(kCLOCK_Fmc); +} + +/*! + * @brief API to power up flash controller. + * + * @return none + */ +static inline void POWER_PowerUpFlash(void) +{ + Chip_POWER_SetFLASHPower(1U); + /* TURN ON clock for flash controller */ + CLOCK_EnableClock(kCLOCK_Fmc); +} + +/*! + * @brief Power Library API to enter different power mode. + * + * @param exclude_from_pd Bit mask of the PDRUNCFG bits that needs to be powered on during deep sleep + * @return none + */ +void POWER_EnterPowerMode(power_mode_cfg_t mode, uint64_t exclude_from_pd); + +/*! + * @brief Power Library API to enter sleep mode. + * + * @return none + */ +void POWER_EnterSleep(void); + +/*! + * @brief Power Library API to enter deep sleep mode. + * + * @param exclude_from_pd Bit mask of the PDRUNCFG bits that needs to be powered on during deep sleep + * @return none + */ +void POWER_EnterDeepSleep(uint64_t exclude_from_pd); + +/*! + * @brief Power Library API to enter power down mode. + * + * @param exclude_from_pd Bit mask of the PDRUNCFG bits that needs to be powered on during deep sleep + * @return none + */ +void POWER_EnterPowerDown(uint64_t exclude_from_pd); + +/*! + * @brief Power Library API to enter deep power down mode. + * + * @param exclude_from_pd Bit mask of the PDRUNCFG bits that needs to be powered on during deep power down mode, + * but this is has no effect as the voltages are cut off. + * @return none + */ +void POWER_EnterDeepPowerDown(uint64_t exclude_from_pd); + +/*! + * @brief Power Library API to choose normal regulation and set the voltage for the desired operating frequency. + * + * @param freq - The desired frequency at which the part would like to operate, + * note that the voltage and flash wait states should be set before changing frequency + * @return none + */ +void POWER_SetVoltageForFreq(uint32_t freq); + + +/*! + * @brief Power Library API to return the library version. + * + * @return version number of the power library + */ +uint32_t POWER_GetLibVersion(void); + +/* @} */ + +#ifdef __cplusplus +} +#endif + +/*! @} */ + +#endif /* _FSL_POWER_H_ */ diff --git a/platform/mcu/lpc54102/drivers/fsl_reset.c b/platform/mcu/lpc54102/drivers/fsl_reset.c new file mode 100644 index 0000000000..04ddef6481 --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_reset.c @@ -0,0 +1,168 @@ +/* + * Copyright 2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_common.h" +#include "fsl_reset.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/******************************************************************************* + * Code + ******************************************************************************/ + +#if ((defined(FSL_FEATURE_SOC_SYSCON_COUNT) && (FSL_FEATURE_SOC_SYSCON_COUNT > 0)) || \ + (defined(FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT) && (FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT > 0))) + +void RESET_SetPeripheralReset(reset_ip_name_t peripheral) +{ + const uint32_t regIndex = ((uint32_t)peripheral & 0xFFFF0000u) >> 16; + const uint32_t bitPos = ((uint32_t)peripheral & 0x0000FFFFu); + const uint32_t bitMask = 1u << bitPos; + + assert(bitPos < 32u); + + /* ASYNC_SYSCON registers have offset 1024 */ + if (regIndex >= SYSCON_PRESETCTRL_COUNT) + { + /* reset register is in ASYNC_SYSCON */ + + /* set bit */ + ASYNC_SYSCON->ASYNCPRESETCTRLSET = bitMask; + /* wait until it reads 0b1 */ + while (0u == (ASYNC_SYSCON->ASYNCPRESETCTRL & bitMask)) + { + } + } + else + { + /* reset register is in SYSCON */ + + /* set bit */ + SYSCON->PRESETCTRLSET[regIndex] = bitMask; + /* wait until it reads 0b1 */ + while (0u == (SYSCON->PRESETCTRL[regIndex] & bitMask)) + { + } + } +} + +void RESET_ClearPeripheralReset(reset_ip_name_t peripheral) +{ + const uint32_t regIndex = ((uint32_t)peripheral & 0xFFFF0000u) >> 16; + const uint32_t bitPos = ((uint32_t)peripheral & 0x0000FFFFu); + const uint32_t bitMask = 1u << bitPos; + + assert(bitPos < 32u); + + /* ASYNC_SYSCON registers have offset 1024 */ + if (regIndex >= SYSCON_PRESETCTRL_COUNT) + { + /* reset register is in ASYNC_SYSCON */ + + /* clear bit */ + ASYNC_SYSCON->ASYNCPRESETCTRLCLR = bitMask; + /* wait until it reads 0b0 */ + while (bitMask == (ASYNC_SYSCON->ASYNCPRESETCTRL & bitMask)) + { + } + } + else + { + /* reset register is in SYSCON */ + + /* clear bit */ + SYSCON->PRESETCTRLCLR[regIndex] = bitMask; + /* wait until it reads 0b0 */ + while (bitMask == (SYSCON->PRESETCTRL[regIndex] & bitMask)) + { + } + } +} + +void RESET_PeripheralReset(reset_ip_name_t peripheral) +{ + RESET_SetPeripheralReset(peripheral); + RESET_ClearPeripheralReset(peripheral); +} + +void RESET_SetSlaveCoreReset(void) +{ + uint32_t cpuctrl = (SYSCON->CPUCTRL & ~0x7F80U) | 0xC0C48000U; + + /* CM4 is the master. */ + if (cpuctrl & SYSCON_CPUCTRL_MASTERCPU_MASK) + { + SYSCON->CPUCTRL = cpuctrl | SYSCON_CPUCTRL_CM0RSTEN_MASK; + } + /* CM0 is the master. */ + else + { + SYSCON->CPUCTRL = cpuctrl | SYSCON_CPUCTRL_CM4RSTEN_MASK; + } +} + +void RESET_ClearSlaveCoreReset(void) +{ + uint32_t cpuctrl = (SYSCON->CPUCTRL & ~0x7F80U) | 0xC0C48000U; + + /* CM4 is the master. */ + if (cpuctrl & SYSCON_CPUCTRL_MASTERCPU_MASK) + { + SYSCON->CPUCTRL = cpuctrl & ~SYSCON_CPUCTRL_CM0RSTEN_MASK; + } + /* CM0 is the master. */ + else + { + SYSCON->CPUCTRL = cpuctrl & ~SYSCON_CPUCTRL_CM4RSTEN_MASK; + } +} + +void RESET_SlaveCoreReset(uint32_t bootAddr, uint32_t bootStackPointer) +{ + volatile uint32_t i = 10U; + + SYSCON->CPSTACK = bootStackPointer; + SYSCON->CPBOOT = bootAddr; + + RESET_SetSlaveCoreReset(); + while(i--){} + RESET_ClearSlaveCoreReset(); +} + +#endif /* FSL_FEATURE_SOC_SYSCON_COUNT || FSL_FEATURE_SOC_ASYNC_SYSCON_COUNT */ diff --git a/platform/mcu/lpc54102/drivers/fsl_reset.h b/platform/mcu/lpc54102/drivers/fsl_reset.h new file mode 100644 index 0000000000..a8997c25b3 --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_reset.h @@ -0,0 +1,243 @@ +/* + * Copyright 2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_RESET_H_ +#define _FSL_RESET_H_ + +#include +#include +#include +#include +#include "fsl_device_registers.h" + +/*! + * @addtogroup ksdk_common + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief reset driver version 2.0.0. */ +#define FSL_RESET_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*@}*/ + +/*! + * @brief Enumeration for peripheral reset control bits + * + * Defines the enumeration for peripheral reset control bits in PRESETCTRL/ASYNCPRESETCTRL registers + */ +typedef enum _SYSCON_RSTn +{ + kFLASH_RST_SHIFT_RSTn = 0 | 7U, /**< Flash controller reset control */ + kFMC_RST_SHIFT_RSTn = 0 | 8U, /**< Flash accelerator reset control */ + kMUX_RST_SHIFT_RSTn = 0 | 11U, /**< Input mux reset control */ + kIOCON_RST_SHIFT_RSTn = 0 | 13U, /**< IOCON reset control */ + kGPIO0_RST_SHIFT_RSTn = 0 | 14U, /**< GPIO0 reset control */ + kGPIO1_RST_SHIFT_RSTn = 0 | 15U, /**< GPIO1 reset control */ + kPINT_RST_SHIFT_RSTn = 0 | 18U, /**< Pin interrupt (PINT) reset control */ + kGINT_RST_SHIFT_RSTn = 0 | 19U, /**< Grouped interrupt (PINT) reset control. */ + kDMA_RST_SHIFT_RSTn = 0 | 20U, /**< DMA reset control */ + kCRC_RST_SHIFT_RSTn = 0 | 21U, /**< CRC reset control */ + kWWDT_RST_SHIFT_RSTn = 0 | 22U, /**< Watchdog timer reset control */ + kADC0_RST_SHIFT_RSTn = 0 | 27U, /**< ADC0 reset control */ + + kMRT_RST_SHIFT_RSTn = 65536 | 0U, /**< Multi-rate timer (MRT) reset control */ + kRIT_RST_SHIFT_RSTn = 65536 | 1U, /**< Repetitive interrupt timer (RIT) reset control */ + kSCT0_RST_SHIFT_RSTn = 65536 | 2U, /**< SCTimer/PWM 0 (SCT0) reset control */ + kFIFO_RST_SHIFT_RSTn = 65536 | 9U, /**< System FIFO reset control */ + kUTICK_RST_SHIFT_RSTn = 65536 | 10U, /**< Micro-tick timer reset control */ + kCT32B2_RST_SHIFT_RSTn = 65536 | 22U, /**< CT32B2 reset control */ + kCT32B3_RST_SHIFT_RSTn = 65536 | 26U, /**< CT32B3 reset control */ + kCT32B4_RST_SHIFT_RSTn = 65536 | 27U, /**< CT32B4 reset control */ + + kUSART0_RST_SHIFT_RSTn = 67108864 | 1U, /**< USART0 reset control */ + kUSART1_RST_SHIFT_RSTn = 67108864 | 2U, /**< USART1 reset control */ + kUSART2_RST_SHIFT_RSTn = 67108864 | 3U, /**< USART2 reset control */ + kUSART3_RST_SHIFT_RSTn = 67108864 | 4U, /**< USART3 reset control */ + + kI2C0_RST_SHIFT_RSTn = 67108864 | 5U, /**< I2C0 reset control */ + kI2C1_RST_SHIFT_RSTn = 67108864 | 6U, /**< I2C1 reset control */ + kI2C2_RST_SHIFT_RSTn = 67108864 | 7U, /**< I2C2 reset control */ + + kSPI0_RST_SHIFT_RSTn = 67108864 | 9U, /**< SPI0 reset control */ + kSPI1_RST_SHIFT_RSTn = 67108864 | 10U, /**< SPI1 reset control */ + + kCT32B0_RST_SHIFT_RSTn = 67108864 | 13U, /**< CT32B0 reset control */ + kCT32B1_RST_SHIFT_RSTn = 67108864 | 14U, /**< CT32B1 reset control */ + kFRG0_RST_SHIFT_RSTn = 67108864 | 15U, /**< FRG0 reset control */ + +} SYSCON_RSTn_t; + +/** Array initializers with peripheral reset bits **/ +#define ADC_RSTS \ + { \ + kADC0_RST_SHIFT_RSTn \ + } /* Reset bits for ADC peripheral */ +#define CRC_RSTS \ + { \ + kCRC_RST_SHIFT_RSTn \ + } /* Reset bits for CRC peripheral */ +#define DMA_RSTS \ + { \ + kDMA_RST_SHIFT_RSTn \ + } /* Reset bits for DMA peripheral */ +#define GINT_RSTS \ + { \ + kGINT_RST_SHIFT_RSTn, kGINT_RST_SHIFT_RSTn \ + } /* Reset bits for GINT peripheral. GINT0 & GINT1 share same slot */ +#define GPIO_RSTS \ + { \ + kGPIO0_RST_SHIFT_RSTn, kGPIO1_RST_SHIFT_RSTn \ + } /* Reset bits for GPIO peripheral */ +#define INPUTMUX_RSTS \ + { \ + kMUX_RST_SHIFT_RSTn \ + } /* Reset bits for INPUTMUX peripheral */ +#define IOCON_RSTS \ + { \ + kIOCON_RST_SHIFT_RSTn \ + } /* Reset bits for IOCON peripheral */ +#define FLASH_RSTS \ + { \ + kFLASH_RST_SHIFT_RSTn, kFMC_RST_SHIFT_RSTn \ + } /* Reset bits for Flash peripheral */ +#define MRT_RSTS \ + { \ + kMRT_RST_SHIFT_RSTn \ + } /* Reset bits for MRT peripheral */ +#define RIT_RSTS \ + { \ + kRIT_RST_SHIFT_RSTn \ + } /* Reset bits for RIT peripheral */ +#define PINT_RSTS \ + { \ + kPINT_RST_SHIFT_RSTn \ + } /* Reset bits for PINT peripheral */ +#define SCT_RSTS \ + { \ + kSCT0_RST_SHIFT_RSTn \ + } /* Reset bits for SCT peripheral */ +#define FIFO_RSTS \ + { \ + kFIFO_RST_SHIFT_RSTn \ + } /* Reset bits for FIFO peripheral */ +#define CTIMER_RSTS \ + { \ + kCT32B0_RST_SHIFT_RSTn, kCT32B1_RST_SHIFT_RSTn, kCT32B2_RST_SHIFT_RSTn, kCT32B3_RST_SHIFT_RSTn, \ + kCT32B4_RST_SHIFT_RSTn \ + } /* Reset bits for TIMER peripheral */ +#define UTICK_RSTS \ + { \ + kUTICK_RST_SHIFT_RSTn \ + } /* Reset bits for UTICK peripheral */ +#define WWDT_RSTS \ + { \ + kWWDT_RST_SHIFT_RSTn \ + } /* Reset bits for WWDT peripheral */ +#define USART_RSTS \ + { \ + kUSART0_RST_SHIFT_RSTn, kUSART1_RST_SHIFT_RSTn, kUSART2_RST_SHIFT_RSTn kUSART3_RST_SHIFT_RSTn \ + } /* Reset bits for USART peripheral */ +#define I2C_RSTS \ + { \ + kI2C0_RST_SHIFT_RSTn, kI2C1_RST_SHIFT_RSTn, kI2C2_RST_SHIFT_RSTn \ + } /* Reset bits for I2C peripheral */ +#define SPI_RSTS \ + { \ + kSPI0_RST_SHIFT_RSTn, kSPI0_RST_SHIFT_RSTn, \ + } /* Reset bits for SPI peripheral */ +#define FRG_RSTS \ + { \ + kFRG0_RST_SHIFT_RSTn \ + } /* Reset bits for WWDT peripheral */ +typedef SYSCON_RSTn_t reset_ip_name_t; + +/******************************************************************************* + * API + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Assert reset to peripheral. + * + * Asserts reset signal to specified peripheral module. + * + * @param peripheral Assert reset to this peripheral. The enum argument contains encoding of reset register + * and reset bit position in the reset register. + */ +void RESET_SetPeripheralReset(reset_ip_name_t peripheral); + +/*! + * @brief Clear reset to peripheral. + * + * Clears reset signal to specified peripheral module, allows it to operate. + * + * @param peripheral Clear reset to this peripheral. The enum argument contains encoding of reset register + * and reset bit position in the reset register. + */ +void RESET_ClearPeripheralReset(reset_ip_name_t peripheral); + +/*! + * @brief Reset peripheral module. + * + * Reset peripheral module. + * + * @param peripheral Peripheral to reset. The enum argument contains encoding of reset register + * and reset bit position in the reset register. + */ +void RESET_PeripheralReset(reset_ip_name_t peripheral); + +/*! + * @brief Set slave core to reset state and hold. + */ +void RESET_SetSlaveCoreReset(void); + +/*! + * @brief Release slave core from reset state. + */ +void RESET_ClearSlaveCoreReset(void); + +/*! + * @brief Reset slave core with the boot entry. + */ +void RESET_SlaveCoreReset(uint32_t bootAddr, uint32_t bootStackPointer); + +#if defined(__cplusplus) +} +#endif + +/*! @} */ + +#endif /* _FSL_RESET_H_ */ diff --git a/platform/mcu/lpc54102/drivers/fsl_rit.c b/platform/mcu/lpc54102/drivers/fsl_rit.c new file mode 100644 index 0000000000..23c9c9257c --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_rit.c @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_rit.h" + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +/*! + * @brief Gets the instance from the base address to be used to gate or ungate the module clock + * + * @param base RIT peripheral base address + * + * @return The RIT instance + */ +static uint32_t RIT_GetInstance(RIT_Type *base); + +/******************************************************************************* + * Variables + ******************************************************************************/ +/*! @brief Pointers to RIT bases for each instance. */ +static RIT_Type *const s_ritBases[] = RIT_BASE_PTRS; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +/*! @brief Pointers to PIT clocks for each instance. */ +static const clock_ip_name_t s_ritClocks[] = RIT_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +/******************************************************************************* + * Code + ******************************************************************************/ +static uint32_t RIT_GetInstance(RIT_Type *base) +{ + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < ARRAY_SIZE(s_ritBases); instance++) + { + if (s_ritBases[instance] == base) + { + break; + } + } + + assert(instance < ARRAY_SIZE(s_ritBases)); + + return instance; +} + +void RIT_GetDefaultConfig(rit_config_t *config) +{ + assert(config); + /* Timer operation are no effect in Debug mode */ + config->enableRunInDebug = false; +} + +void RIT_Init(RIT_Type *base, const rit_config_t *config) +{ + assert(config); + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Ungate the RIT clock*/ + CLOCK_EnableClock(s_ritClocks[RIT_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + + /* Enable RIT timers */ + base->CTRL &= ~RIT_CTRL_RITEN_MASK; + + /* Config timer operation is no effect in debug mode */ + if (!config->enableRunInDebug) + { + base->CTRL &= ~RIT_CTRL_RITENBR_MASK; + } + else + { + base->CTRL |= RIT_CTRL_RITENBR_MASK; + } +} + +void RIT_Deinit(RIT_Type *base) +{ + /* Disable RIT timers */ + base->CTRL |= ~RIT_CTRL_RITEN_MASK; +#ifdef FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL + /* Gate the RIT clock*/ + CLOCK_DisableClock(s_ritClocks[RIT_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +void RIT_SetTimerCompare(RIT_Type *base, uint64_t count) +{ + /* Disable RIT timers */ + base->CTRL &= ~RIT_CTRL_RITEN_MASK; + base->COMPVAL = (uint32_t)count; + base->COMPVAL_H = (uint16_t)(count >> 32U); +} + +void RIT_SetMaskBit(RIT_Type *base, uint64_t count) +{ + base->MASK = (uint32_t)count; + base->MASK_H = (uint16_t)(count >> 32U); +} + +uint64_t RIT_GetCompareTimerCount(RIT_Type *base) +{ + uint16_t valueH = 0U; + uint32_t valueL = 0U; + + /* COMPVAL_H should be read before COMPVAL */ + valueH = base->COMPVAL_H; + valueL = base->COMPVAL; + + return (((uint64_t)valueH << 32U) + (uint64_t)(valueL)); +} + +uint64_t RIT_GetCounterTimerCount(RIT_Type *base) +{ + uint16_t valueH = 0U; + uint32_t valueL = 0U; + + /* COUNTER_H should be read before COUNTER */ + valueH = base->COUNTER_H; + valueL = base->COUNTER; + + return (((uint64_t)valueH << 32U) + (uint64_t)(valueL)); +} + +uint64_t RIT_GetMaskTimerCount(RIT_Type *base) +{ + uint16_t valueH = 0U; + uint32_t valueL = 0U; + + /* MASK_H should be read before MASK */ + valueH = base->MASK_H; + valueL = base->MASK; + + return (((uint64_t)valueH << 32U) + (uint64_t)(valueL)); +} diff --git a/platform/mcu/lpc54102/drivers/fsl_rit.h b/platform/mcu/lpc54102/drivers/fsl_rit.h new file mode 100644 index 0000000000..e6f5e6be86 --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_rit.h @@ -0,0 +1,276 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_RIT_H_ +#define _FSL_RIT_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup rit + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +#define FSL_RIT_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0 */ +/*@}*/ + +/*! @brief List of RIT status flags */ +typedef enum _rit_status_flags +{ + kRIT_TimerFlag = RIT_CTRL_RITINT_MASK, /*!< Timer flag */ +} rit_status_flags_t; + +/*! + * @brief RIT config structure + * + * This structure holds the configuration settings for the RIT peripheral. To initialize this + * structure to reasonable defaults, call the RIT_GetDefaultConfig() function and pass a + * pointer to your config structure instance. + * + * The config struct can be made const so it resides in flash + */ +typedef struct _rit_config +{ + bool enableRunInDebug; /*!< true: The timer is halted when the processor is halted for debugging.; false: Debug has + no effect on the timer operation. */ +} rit_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name Initialization and deinitialization + * @{ + */ + +/*! + * @brief Ungates the RIT clock, enables the RIT module, and configures the peripheral for basic operations. + * + * @note This API should be called at the beginning of the application using the RIT driver. + * + * @param base RIT peripheral base address + * @param config Pointer to the user's RIT config structure + */ +void RIT_Init(RIT_Type *base, const rit_config_t *config); + +/*! + * @brief Gates the RIT clock and disables the RIT module. + * + * @param base RIT peripheral base address + */ +void RIT_Deinit(RIT_Type *base); + +/*! + * @brief Fills in the RIT configuration structure with the default settings. + * + * The default values are as follows. + * @code + * config->enableRunInDebug = false; + * @endcode + * @param config Pointer to the onfiguration structure. + */ +void RIT_GetDefaultConfig(rit_config_t *config); + +/*! @}*/ + +/*! + * @name Status Interface + * @{ + */ + +/*! + * @brief Gets the RIT status flags. + * + * @param base RIT peripheral base address + * + * @return The status flags. This is the logical OR of members of the + * enumeration ::rit_status_flags_t + */ +static inline uint32_t RIT_GetStatusFlags(RIT_Type *base) +{ + return (base->CTRL); +} + +/*! + * @brief Clears the RIT status flags. + * + * @param base RIT peripheral base address + * @param mask The status flags to clear. This is a logical OR of members of the + * enumeration ::rit_status_flags_t + */ +static inline void RIT_ClearStatusFlags(RIT_Type *base, uint32_t mask) +{ + base->CTRL |= mask; +} + +/*! @}*/ + +/*! + * @name Read and Write the timer period + * @{ + */ + +/*! + * @brief Sets the timer period in units of count. + * + * Timers begin counting from the value set by this function until it XXXXXXX, + * then it counting the value again. + * Software must stop the counter before reloading it with a new value.. + * + * @note Users can call the utility macros provided in fsl_common.h to convert to ticks + * + * @param base RIT peripheral base address + * @param count Timer period in units of ticks + */ +void RIT_SetTimerCompare(RIT_Type *base, uint64_t count); + +/*! + * @brief Sets the mask bit of count compare. + * + * Timers begin counting from the value set by this function until it XXXXXXX, + * then it counting the value again. + * Software must stop the counter before reloading it with a new value.. + * + * @note Users can call the utility macros provided in fsl_common.h to convert to ticks + * + * @param base RIT peripheral base address + * @param count Timer period in units of ticks + */ +void RIT_SetMaskBit(RIT_Type *base, uint64_t count); + +/*! + * @brief Reads the current timer counting value of compare register. + * + * This function returns the real-time timer counting value, in a range from 0 to a + * timer period. + * + * @note Users can call the utility macros provided in fsl_common.h to convert ticks to usec or msec + * + * @param base RIT peripheral base address + * + * @return Current timer counting value in ticks + */ +uint64_t RIT_GetCompareTimerCount(RIT_Type *base); + +/*! + * @brief Reads the current timer counting value of counter register. + * + * This function returns the real-time timer counting value, in a range from 0 to a + * timer period. + * + * @note Users can call the utility macros provided in fsl_common.h to convert ticks to usec or msec + * + * @param base RIT peripheral base address + * + * @return Current timer counting value in ticks + */ +uint64_t RIT_GetCounterTimerCount(RIT_Type *base); + +/*! + * @brief Reads the current timer counting value of mask register. + * + * This function returns the real-time timer counting value, in a range from 0 to a + * timer period. + * + * @note Users can call the utility macros provided in fsl_common.h to convert ticks to usec or msec + * + * @param base RIT peripheral base address + * + * @return Current timer counting value in ticks + */ +uint64_t RIT_GetMaskTimerCount(RIT_Type *base); + +/*! @}*/ + +/*! + * @name Timer Start and Stop + * @{ + */ + +/*! + * @brief Starts the timer counting. + * + * After calling this function, timers load initial value(0U), count up to desired value or over-flow + * then the counter will count up again. Each time a timer reaches desired value, + * it generates a XXXXXXX and sets XXXXXXX. + * + * @param base RIT peripheral base address + */ +static inline void RIT_StartTimer(RIT_Type *base) +{ + base->CTRL |= RIT_CTRL_RITEN_MASK; +} + +/*! + * @brief Stops the timer counting. + * + * This function stop timer counting. Timer reload their new value + * after the next time they call the RIT_StartTimer. + * + * @param base RIT peripheral base address + * @param channel Timer channel number. + */ +static inline void RIT_StopTimer(RIT_Type *base) +{ + /* Disable RIT timers */ + base->CTRL &= ~RIT_CTRL_RITEN_MASK; +} + +/*! @}*/ + +static inline void RIT_ClearCounter(RIT_Type *base, bool enable) +{ + if (enable) + { + base->CTRL |= RIT_CTRL_RITENCLR_MASK; + } + else + { + base->CTRL &= ~RIT_CTRL_RITENCLR_MASK; + } +} + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_RIT_H_ */ diff --git a/platform/mcu/lpc54102/drivers/fsl_rtc.c b/platform/mcu/lpc54102/drivers/fsl_rtc.c new file mode 100644 index 0000000000..c0fdef4982 --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_rtc.c @@ -0,0 +1,290 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_rtc.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define SECONDS_IN_A_DAY (86400U) +#define SECONDS_IN_A_HOUR (3600U) +#define SECONDS_IN_A_MINUTE (60U) +#define DAYS_IN_A_YEAR (365U) +#define YEAR_RANGE_START (1970U) +#define YEAR_RANGE_END (2099U) + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +/*! + * @brief Checks whether the date and time passed in is valid + * + * @param datetime Pointer to structure where the date and time details are stored + * + * @return Returns false if the date & time details are out of range; true if in range + */ +static bool RTC_CheckDatetimeFormat(const rtc_datetime_t *datetime); + +/*! + * @brief Converts time data from datetime to seconds + * + * @param datetime Pointer to datetime structure where the date and time details are stored + * + * @return The result of the conversion in seconds + */ +static uint32_t RTC_ConvertDatetimeToSeconds(const rtc_datetime_t *datetime); + +/*! + * @brief Converts time data from seconds to a datetime structure + * + * @param seconds Seconds value that needs to be converted to datetime format + * @param datetime Pointer to the datetime structure where the result of the conversion is stored + */ +static void RTC_ConvertSecondsToDatetime(uint32_t seconds, rtc_datetime_t *datetime); + +/******************************************************************************* + * Code + ******************************************************************************/ +static bool RTC_CheckDatetimeFormat(const rtc_datetime_t *datetime) +{ + assert(datetime); + + /* Table of days in a month for a non leap year. First entry in the table is not used, + * valid months start from 1 + */ + uint8_t daysPerMonth[] = {0U, 31U, 28U, 31U, 30U, 31U, 30U, 31U, 31U, 30U, 31U, 30U, 31U}; + + /* Check year, month, hour, minute, seconds */ + if ((datetime->year < YEAR_RANGE_START) || (datetime->year > YEAR_RANGE_END) || (datetime->month > 12U) || + (datetime->month < 1U) || (datetime->hour >= 24U) || (datetime->minute >= 60U) || (datetime->second >= 60U)) + { + /* If not correct then error*/ + return false; + } + + /* Adjust the days in February for a leap year */ + if ((((datetime->year & 3U) == 0) && (datetime->year % 100 != 0)) || (datetime->year % 400 == 0)) + { + daysPerMonth[2] = 29U; + } + + /* Check the validity of the day */ + if ((datetime->day > daysPerMonth[datetime->month]) || (datetime->day < 1U)) + { + return false; + } + + return true; +} + +static uint32_t RTC_ConvertDatetimeToSeconds(const rtc_datetime_t *datetime) +{ + assert(datetime); + + /* Number of days from begin of the non Leap-year*/ + /* Number of days from begin of the non Leap-year*/ + uint16_t monthDays[] = {0U, 0U, 31U, 59U, 90U, 120U, 151U, 181U, 212U, 243U, 273U, 304U, 334U}; + uint32_t seconds; + + /* Compute number of days from 1970 till given year*/ + seconds = (datetime->year - 1970U) * DAYS_IN_A_YEAR; + /* Add leap year days */ + seconds += ((datetime->year / 4) - (1970U / 4)); + /* Add number of days till given month*/ + seconds += monthDays[datetime->month]; + /* Add days in given month. We subtract the current day as it is + * represented in the hours, minutes and seconds field*/ + seconds += (datetime->day - 1); + /* For leap year if month less than or equal to Febraury, decrement day counter*/ + if ((!(datetime->year & 3U)) && (datetime->month <= 2U)) + { + seconds--; + } + + seconds = (seconds * SECONDS_IN_A_DAY) + (datetime->hour * SECONDS_IN_A_HOUR) + + (datetime->minute * SECONDS_IN_A_MINUTE) + datetime->second; + + return seconds; +} + +static void RTC_ConvertSecondsToDatetime(uint32_t seconds, rtc_datetime_t *datetime) +{ + assert(datetime); + + uint32_t x; + uint32_t secondsRemaining, days; + uint16_t daysInYear; + /* Table of days in a month for a non leap year. First entry in the table is not used, + * valid months start from 1 + */ + uint8_t daysPerMonth[] = {0U, 31U, 28U, 31U, 30U, 31U, 30U, 31U, 31U, 30U, 31U, 30U, 31U}; + + /* Start with the seconds value that is passed in to be converted to date time format */ + secondsRemaining = seconds; + + /* Calcuate the number of days, we add 1 for the current day which is represented in the + * hours and seconds field + */ + days = secondsRemaining / SECONDS_IN_A_DAY + 1; + + /* Update seconds left*/ + secondsRemaining = secondsRemaining % SECONDS_IN_A_DAY; + + /* Calculate the datetime hour, minute and second fields */ + datetime->hour = secondsRemaining / SECONDS_IN_A_HOUR; + secondsRemaining = secondsRemaining % SECONDS_IN_A_HOUR; + datetime->minute = secondsRemaining / 60U; + datetime->second = secondsRemaining % SECONDS_IN_A_MINUTE; + + /* Calculate year */ + daysInYear = DAYS_IN_A_YEAR; + datetime->year = YEAR_RANGE_START; + while (days > daysInYear) + { + /* Decrease day count by a year and increment year by 1 */ + days -= daysInYear; + datetime->year++; + + /* Adjust the number of days for a leap year */ + if (datetime->year & 3U) + { + daysInYear = DAYS_IN_A_YEAR; + } + else + { + daysInYear = DAYS_IN_A_YEAR + 1; + } + } + + /* Adjust the days in February for a leap year */ + if (!(datetime->year & 3U)) + { + daysPerMonth[2] = 29U; + } + + for (x = 1U; x <= 12U; x++) + { + if (days <= daysPerMonth[x]) + { + datetime->month = x; + break; + } + else + { + days -= daysPerMonth[x]; + } + } + + datetime->day = days; +} + +void RTC_Init(RTC_Type *base) +{ +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Enable the RTC peripheral clock */ + CLOCK_EnableClock(kCLOCK_Rtc); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + + /* Make sure the reset bit is cleared */ + base->CTRL &= ~RTC_CTRL_SWRESET_MASK; + +#if !(defined(FSL_FEATURE_RTC_HAS_NO_OSC_PD) && FSL_FEATURE_RTC_HAS_NO_OSC_PD) + /* Make sure the RTC OSC is powered up */ + base->CTRL &= ~RTC_CTRL_RTC_OSC_PD_MASK; +#endif +} + +status_t RTC_SetDatetime(RTC_Type *base, const rtc_datetime_t *datetime) +{ + assert(datetime); + + /* Return error if the time provided is not valid */ + if (!(RTC_CheckDatetimeFormat(datetime))) + { + return kStatus_InvalidArgument; + } + + /* Set time in seconds */ + base->COUNT = RTC_ConvertDatetimeToSeconds(datetime); + + return kStatus_Success; +} + +void RTC_GetDatetime(RTC_Type *base, rtc_datetime_t *datetime) +{ + assert(datetime); + + uint32_t seconds = 0; + + seconds = base->COUNT; + RTC_ConvertSecondsToDatetime(seconds, datetime); +} + +status_t RTC_SetAlarm(RTC_Type *base, const rtc_datetime_t *alarmTime) +{ + assert(alarmTime); + + uint32_t alarmSeconds = 0; + uint32_t currSeconds = 0; + + /* Return error if the alarm time provided is not valid */ + if (!(RTC_CheckDatetimeFormat(alarmTime))) + { + return kStatus_InvalidArgument; + } + + alarmSeconds = RTC_ConvertDatetimeToSeconds(alarmTime); + + /* Get the current time */ + currSeconds = base->COUNT; + + /* Return error if the alarm time has passed */ + if (alarmSeconds < currSeconds) + { + return kStatus_Fail; + } + + /* Set alarm in seconds*/ + base->MATCH = alarmSeconds; + + return kStatus_Success; +} + +void RTC_GetAlarm(RTC_Type *base, rtc_datetime_t *datetime) +{ + assert(datetime); + + uint32_t alarmSeconds = 0; + + /* Get alarm in seconds */ + alarmSeconds = base->MATCH; + + RTC_ConvertSecondsToDatetime(alarmSeconds, datetime); +} diff --git a/platform/mcu/lpc54102/drivers/fsl_rtc.h b/platform/mcu/lpc54102/drivers/fsl_rtc.h new file mode 100644 index 0000000000..83c5ba8549 --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_rtc.h @@ -0,0 +1,340 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_RTC_H_ +#define _FSL_RTC_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup rtc + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +#define FSL_RTC_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0 */ +/*@}*/ + +/*! @brief List of RTC interrupts */ +typedef enum _rtc_interrupt_enable +{ + kRTC_AlarmInterruptEnable = RTC_CTRL_ALARMDPD_EN_MASK, /*!< Alarm interrupt.*/ + kRTC_WakeupInterruptEnable = RTC_CTRL_WAKEDPD_EN_MASK /*!< Wake-up interrupt.*/ +} rtc_interrupt_enable_t; + +/*! @brief List of RTC flags */ +typedef enum _rtc_status_flags +{ + kRTC_AlarmFlag = RTC_CTRL_ALARM1HZ_MASK, /*!< Alarm flag*/ + kRTC_WakeupFlag = RTC_CTRL_WAKE1KHZ_MASK /*!< 1kHz wake-up timer flag*/ +} rtc_status_flags_t; + +/*! @brief Structure is used to hold the date and time */ +typedef struct _rtc_datetime +{ + uint16_t year; /*!< Range from 1970 to 2099.*/ + uint8_t month; /*!< Range from 1 to 12.*/ + uint8_t day; /*!< Range from 1 to 31 (depending on month).*/ + uint8_t hour; /*!< Range from 0 to 23.*/ + uint8_t minute; /*!< Range from 0 to 59.*/ + uint8_t second; /*!< Range from 0 to 59.*/ +} rtc_datetime_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name Initialization and deinitialization + * @{ + */ + +/*! + * @brief Ungates the RTC clock and enables the RTC oscillator. + * + * @note This API should be called at the beginning of the application using the RTC driver. + * + * @param base RTC peripheral base address + */ +void RTC_Init(RTC_Type *base); + +/*! + * @brief Stop the timer and gate the RTC clock + * + * @param base RTC peripheral base address + */ +static inline void RTC_Deinit(RTC_Type *base) +{ + /* Stop the RTC timer */ + base->CTRL &= ~RTC_CTRL_RTC_EN_MASK; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Gate the module clock */ + CLOCK_DisableClock(kCLOCK_Rtc); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +/*! @}*/ + +/*! + * @name Current Time & Alarm + * @{ + */ + +/*! + * @brief Sets the RTC date and time according to the given time structure. + * + * The RTC counter must be stopped prior to calling this function as writes to the RTC + * seconds register will fail if the RTC counter is running. + * + * @param base RTC peripheral base address + * @param datetime Pointer to structure where the date and time details to set are stored + * + * @return kStatus_Success: Success in setting the time and starting the RTC + * kStatus_InvalidArgument: Error because the datetime format is incorrect + */ +status_t RTC_SetDatetime(RTC_Type *base, const rtc_datetime_t *datetime); + +/*! + * @brief Gets the RTC time and stores it in the given time structure. + * + * @param base RTC peripheral base address + * @param datetime Pointer to structure where the date and time details are stored. + */ +void RTC_GetDatetime(RTC_Type *base, rtc_datetime_t *datetime); + +/*! + * @brief Sets the RTC alarm time + * + * The function checks whether the specified alarm time is greater than the present + * time. If not, the function does not set the alarm and returns an error. + * + * @param base RTC peripheral base address + * @param alarmTime Pointer to structure where the alarm time is stored. + * + * @return kStatus_Success: success in setting the RTC alarm + * kStatus_InvalidArgument: Error because the alarm datetime format is incorrect + * kStatus_Fail: Error because the alarm time has already passed + */ +status_t RTC_SetAlarm(RTC_Type *base, const rtc_datetime_t *alarmTime); + +/*! + * @brief Returns the RTC alarm time. + * + * @param base RTC peripheral base address + * @param datetime Pointer to structure where the alarm date and time details are stored. + */ +void RTC_GetAlarm(RTC_Type *base, rtc_datetime_t *datetime); + +/*! @}*/ + +/*! + * @brief Enable the RTC high resolution timer and set the wake-up time. + * + * @param base RTC peripheral base address + * @param wakeupValue The value to be loaded into the RTC WAKE register + */ +static inline void RTC_SetWakeupCount(RTC_Type *base, uint16_t wakeupValue) +{ + /* Enable the 1kHz RTC timer */ + base->CTRL |= RTC_CTRL_RTC1KHZ_EN_MASK; + + /* Set the start count value into the wake-up timer */ + base->WAKE = wakeupValue; +} + +/*! + * @brief Read actual RTC counter value. + * + * @param base RTC peripheral base address + */ +static inline uint16_t RTC_GetWakeupCount(RTC_Type *base) +{ + /* Read wake-up counter */ + return RTC_WAKE_VAL(base->WAKE); +} + +/*! + * @name Interrupt Interface + * @{ + */ + +/*! + * @brief Enables the selected RTC interrupts. + * + * @param base RTC peripheral base address + * @param mask The interrupts to enable. This is a logical OR of members of the + * enumeration ::rtc_interrupt_enable_t + */ +static inline void RTC_EnableInterrupts(RTC_Type *base, uint32_t mask) +{ + uint32_t reg = base->CTRL; + + /* Clear flag bits to prevent accidentally clearing anything when writing back */ + reg &= ~(RTC_CTRL_ALARM1HZ_MASK | RTC_CTRL_WAKE1KHZ_MASK); + reg |= mask; + + base->CTRL = reg; +} + +/*! + * @brief Disables the selected RTC interrupts. + * + * @param base RTC peripheral base address + * @param mask The interrupts to enable. This is a logical OR of members of the + * enumeration ::rtc_interrupt_enable_t + */ +static inline void RTC_DisableInterrupts(RTC_Type *base, uint32_t mask) +{ + uint32_t reg = base->CTRL; + + /* Clear flag bits to prevent accidentally clearing anything when writing back */ + reg &= ~(RTC_CTRL_ALARM1HZ_MASK | RTC_CTRL_WAKE1KHZ_MASK | mask); + + base->CTRL = reg; +} + +/*! + * @brief Gets the enabled RTC interrupts. + * + * @param base RTC peripheral base address + * + * @return The enabled interrupts. This is the logical OR of members of the + * enumeration ::rtc_interrupt_enable_t + */ +static inline uint32_t RTC_GetEnabledInterrupts(RTC_Type *base) +{ + return (base->CTRL & (RTC_CTRL_ALARMDPD_EN_MASK | RTC_CTRL_WAKEDPD_EN_MASK)); +} + +/*! @}*/ + +/*! + * @name Status Interface + * @{ + */ + +/*! + * @brief Gets the RTC status flags + * + * @param base RTC peripheral base address + * + * @return The status flags. This is the logical OR of members of the + * enumeration ::rtc_status_flags_t + */ +static inline uint32_t RTC_GetStatusFlags(RTC_Type *base) +{ + return (base->CTRL & (RTC_CTRL_ALARM1HZ_MASK | RTC_CTRL_WAKE1KHZ_MASK)); +} + +/*! + * @brief Clears the RTC status flags. + * + * @param base RTC peripheral base address + * @param mask The status flags to clear. This is a logical OR of members of the + * enumeration ::rtc_status_flags_t + */ +static inline void RTC_ClearStatusFlags(RTC_Type *base, uint32_t mask) +{ + uint32_t reg = base->CTRL; + + /* Clear flag bits to prevent accidentally clearing anything when writing back */ + reg &= ~(RTC_CTRL_ALARM1HZ_MASK | RTC_CTRL_WAKE1KHZ_MASK); + + /* Write 1 to the flags we wish to clear */ + reg |= mask; + + base->CTRL = reg; +} + +/*! @}*/ + +/*! + * @name Timer Start and Stop + * @{ + */ + +/*! + * @brief Starts the RTC time counter. + * + * After calling this function, the timer counter increments once a second provided SR[TOF] or + * SR[TIF] are not set. + * + * @param base RTC peripheral base address + */ +static inline void RTC_StartTimer(RTC_Type *base) +{ + base->CTRL |= RTC_CTRL_RTC_EN_MASK; +} + +/*! + * @brief Stops the RTC time counter. + * + * RTC's seconds register can be written to only when the timer is stopped. + * + * @param base RTC peripheral base address + */ +static inline void RTC_StopTimer(RTC_Type *base) +{ + base->CTRL &= ~RTC_CTRL_RTC_EN_MASK; +} + +/*! @}*/ + +/*! + * @brief Performs a software reset on the RTC module. + * + * This resets all RTC registers to their reset value. The bit is cleared by software explicitly clearing it. + * + * @param base RTC peripheral base address + */ +static inline void RTC_Reset(RTC_Type *base) +{ + base->CTRL |= RTC_CTRL_SWRESET_MASK; + base->CTRL &= ~RTC_CTRL_SWRESET_MASK; +} + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_RTC_H_ */ diff --git a/platform/mcu/lpc54102/drivers/fsl_sctimer.c b/platform/mcu/lpc54102/drivers/fsl_sctimer.c new file mode 100644 index 0000000000..e677bbb92c --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_sctimer.c @@ -0,0 +1,540 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_sctimer.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/*! @brief Typedef for interrupt handler. */ +typedef void (*sctimer_isr_t)(SCT_Type *base); + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +/*! + * @brief Gets the instance from the base address + * + * @param base SCTimer peripheral base address + * + * @return The SCTimer instance + */ +static uint32_t SCTIMER_GetInstance(SCT_Type *base); + +/******************************************************************************* + * Variables + ******************************************************************************/ +/*! @brief Pointers to SCT bases for each instance. */ +static SCT_Type *const s_sctBases[] = SCT_BASE_PTRS; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +/*! @brief Pointers to SCT clocks for each instance. */ +static const clock_ip_name_t s_sctClocks[] = SCT_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +/*! @brief Pointers to SCT resets for each instance. */ +static const reset_ip_name_t s_sctResets[] = SCT_RSTS; + +/*!< @brief SCTimer event Callback function. */ +static sctimer_event_callback_t s_eventCallback[FSL_FEATURE_SCT_NUMBER_OF_EVENTS]; + +/*!< @brief Keep track of SCTimer event number */ +static uint32_t s_currentEvent; + +/*!< @brief Keep track of SCTimer state number */ +static uint32_t s_currentState; + +/*!< @brief Keep track of SCTimer match/capture register number */ +static uint32_t s_currentMatch; + +/*! @brief Pointer to SCTimer IRQ handler */ +static sctimer_isr_t s_sctimerIsr; + +/******************************************************************************* + * Code + ******************************************************************************/ +static uint32_t SCTIMER_GetInstance(SCT_Type *base) +{ + uint32_t instance; + uint32_t sctArrayCount = (sizeof(s_sctBases) / sizeof(s_sctBases[0])); + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < sctArrayCount; instance++) + { + if (s_sctBases[instance] == base) + { + break; + } + } + + assert(instance < sctArrayCount); + + return instance; +} + +status_t SCTIMER_Init(SCT_Type *base, const sctimer_config_t *config) +{ + assert(config); + uint32_t i; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Enable the SCTimer clock*/ + CLOCK_EnableClock(s_sctClocks[SCTIMER_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + + /* Reset the module */ + RESET_PeripheralReset(s_sctResets[SCTIMER_GetInstance(base)]); + + /* Setup the counter operation */ + base->CONFIG = SCT_CONFIG_CKSEL(config->clockSelect) | SCT_CONFIG_CLKMODE(config->clockMode) | + SCT_CONFIG_UNIFY(config->enableCounterUnify); + + /* Write to the control register, clear the counter and keep the counters halted */ + base->CTRL = SCT_CTRL_BIDIR_L(config->enableBidirection_l) | SCT_CTRL_PRE_L(config->prescale_l) | + SCT_CTRL_CLRCTR_L_MASK | SCT_CTRL_HALT_L_MASK; + + if (!(config->enableCounterUnify)) + { + base->CTRL |= SCT_CTRL_BIDIR_H(config->enableBidirection_h) | SCT_CTRL_PRE_H(config->prescale_h) | + SCT_CTRL_CLRCTR_H_MASK | SCT_CTRL_HALT_H_MASK; + } + + /* Initial state of channel output */ + base->OUTPUT = config->outInitState; + + /* Clear the global variables */ + s_currentEvent = 0; + s_currentState = 0; + s_currentMatch = 0; + + /* Clear the callback array */ + for (i = 0; i < FSL_FEATURE_SCT_NUMBER_OF_EVENTS; i++) + { + s_eventCallback[i] = NULL; + } + + /* Save interrupt handler */ + s_sctimerIsr = SCTIMER_EventHandleIRQ; + + return kStatus_Success; +} + +void SCTIMER_Deinit(SCT_Type *base) +{ + /* Halt the counters */ + base->CTRL |= (SCT_CTRL_HALT_L_MASK | SCT_CTRL_HALT_H_MASK); + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Disable the SCTimer clock*/ + CLOCK_DisableClock(s_sctClocks[SCTIMER_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +void SCTIMER_GetDefaultConfig(sctimer_config_t *config) +{ + assert(config); + + /* SCT operates as a unified 32-bit counter */ + config->enableCounterUnify = true; + /* System clock clocks the entire SCT module */ + config->clockMode = kSCTIMER_System_ClockMode; + /* This is used only by certain clock modes */ + config->clockSelect = kSCTIMER_Clock_On_Rise_Input_0; + /* Up count mode only for the unified counter */ + config->enableBidirection_l = false; + /* Up count mode only for Counte_H */ + config->enableBidirection_h = false; + /* Prescale factor of 1 */ + config->prescale_l = 0; + /* Prescale factor of 1 for Counter_H*/ + config->prescale_h = 0; + /* Clear outputs */ + config->outInitState = 0; +} + +status_t SCTIMER_SetupPwm(SCT_Type *base, + const sctimer_pwm_signal_param_t *pwmParams, + sctimer_pwm_mode_t mode, + uint32_t pwmFreq_Hz, + uint32_t srcClock_Hz, + uint32_t *event) +{ + assert(pwmParams); + assert(srcClock_Hz); + assert(pwmFreq_Hz); + + uint32_t period, pulsePeriod = 0; + uint32_t sctClock = srcClock_Hz / (((base->CTRL & SCT_CTRL_PRE_L_MASK) >> SCT_CTRL_PRE_L_SHIFT) + 1); + uint32_t periodEvent, pulseEvent; + uint32_t reg; + + /* This function will create 2 events, return an error if we do not have enough events available */ + if ((s_currentEvent + 2) > FSL_FEATURE_SCT_NUMBER_OF_EVENTS) + { + return kStatus_Fail; + } + + if (pwmParams->dutyCyclePercent == 0) + { + return kStatus_Fail; + } + + /* Set unify bit to operate in 32-bit counter mode */ + base->CONFIG |= SCT_CONFIG_UNIFY_MASK; + + /* Use bi-directional mode for center-aligned PWM */ + if (mode == kSCTIMER_CenterAlignedPwm) + { + base->CTRL |= SCT_CTRL_BIDIR_L_MASK; + } + + /* Calculate PWM period match value */ + if (mode == kSCTIMER_EdgeAlignedPwm) + { + period = (sctClock / pwmFreq_Hz) - 1; + } + else + { + period = sctClock / (pwmFreq_Hz * 2); + } + + /* Calculate pulse width match value */ + pulsePeriod = (period * pwmParams->dutyCyclePercent) / 100; + + /* For 100% dutycyle, make pulse period greater than period so the event will never occur */ + if (pwmParams->dutyCyclePercent >= 100) + { + pulsePeriod = period + 2; + } + + /* Schedule an event when we reach the PWM period */ + SCTIMER_CreateAndScheduleEvent(base, kSCTIMER_MatchEventOnly, period, 0, kSCTIMER_Counter_L, &periodEvent); + + /* Schedule an event when we reach the pulse width */ + SCTIMER_CreateAndScheduleEvent(base, kSCTIMER_MatchEventOnly, pulsePeriod, 0, kSCTIMER_Counter_L, &pulseEvent); + + /* Reset the counter when we reach the PWM period */ + SCTIMER_SetupCounterLimitAction(base, kSCTIMER_Counter_L, periodEvent); + + /* Return the period event to the user */ + *event = periodEvent; + + /* For high-true level */ + if (pwmParams->level == kSCTIMER_HighTrue) + { + /* Set the initial output level to low which is the inactive state */ + base->OUTPUT &= ~(1U << pwmParams->output); + + if (mode == kSCTIMER_EdgeAlignedPwm) + { + /* Set the output when we reach the PWM period */ + SCTIMER_SetupOutputSetAction(base, pwmParams->output, periodEvent); + /* Clear the output when we reach the PWM pulse value */ + SCTIMER_SetupOutputClearAction(base, pwmParams->output, pulseEvent); + } + else + { + /* Clear the output when we reach the PWM pulse event */ + SCTIMER_SetupOutputClearAction(base, pwmParams->output, pulseEvent); + /* Reverse output when down counting */ + reg = base->OUTPUTDIRCTRL; + reg &= ~(SCT_OUTPUTDIRCTRL_SETCLR0_MASK << (2 * pwmParams->output)); + reg |= (1U << (2 * pwmParams->output)); + base->OUTPUTDIRCTRL = reg; + } + } + /* For low-true level */ + else + { + /* Set the initial output level to high which is the inactive state */ + base->OUTPUT |= (1U << pwmParams->output); + + if (mode == kSCTIMER_EdgeAlignedPwm) + { + /* Clear the output when we reach the PWM period */ + SCTIMER_SetupOutputClearAction(base, pwmParams->output, periodEvent); + /* Set the output when we reach the PWM pulse value */ + SCTIMER_SetupOutputSetAction(base, pwmParams->output, pulseEvent); + } + else + { + /* Set the output when we reach the PWM pulse event */ + SCTIMER_SetupOutputSetAction(base, pwmParams->output, pulseEvent); + /* Reverse output when down counting */ + reg = base->OUTPUTDIRCTRL; + reg &= ~(SCT_OUTPUTDIRCTRL_SETCLR0_MASK << (2 * pwmParams->output)); + reg |= (1U << (2 * pwmParams->output)); + base->OUTPUTDIRCTRL = reg; + } + } + + return kStatus_Success; +} + +void SCTIMER_UpdatePwmDutycycle(SCT_Type *base, sctimer_out_t output, uint8_t dutyCyclePercent, uint32_t event) + +{ + assert(dutyCyclePercent > 0); + + uint32_t periodMatchReg, pulseMatchReg; + uint32_t pulsePeriod = 0, period; + + /* Retrieve the match register number for the PWM period */ + periodMatchReg = base->EVENT[event].CTRL & SCT_EVENT_CTRL_MATCHSEL_MASK; + + /* Retrieve the match register number for the PWM pulse period */ + pulseMatchReg = base->EVENT[event + 1].CTRL & SCT_EVENT_CTRL_MATCHSEL_MASK; + + period = base->SCTMATCH[periodMatchReg]; + + /* Calculate pulse width match value */ + pulsePeriod = (period * dutyCyclePercent) / 100; + + /* For 100% dutycyle, make pulse period greater than period so the event will never occur */ + if (dutyCyclePercent >= 100) + { + pulsePeriod = period + 2; + } + + /* Stop the counter before updating match register */ + SCTIMER_StopTimer(base, kSCTIMER_Counter_L); + + /* Update dutycycle */ + base->SCTMATCH[pulseMatchReg] = SCT_SCTMATCH_MATCHn_L(pulsePeriod); + base->SCTMATCHREL[pulseMatchReg] = SCT_SCTMATCHREL_RELOADn_L(pulsePeriod); + + /* Restart the counter */ + SCTIMER_StartTimer(base, kSCTIMER_Counter_L); +} + +status_t SCTIMER_CreateAndScheduleEvent(SCT_Type *base, + sctimer_event_t howToMonitor, + uint32_t matchValue, + uint32_t whichIO, + sctimer_counter_t whichCounter, + uint32_t *event) +{ + uint32_t combMode = (((uint32_t)howToMonitor & SCT_EVENT_CTRL_COMBMODE_MASK) >> SCT_EVENT_CTRL_COMBMODE_SHIFT); + uint32_t currentCtrlVal = howToMonitor; + + /* Return an error if we have hit the limit in terms of number of events created */ + if (s_currentEvent >= FSL_FEATURE_SCT_NUMBER_OF_EVENTS) + { + return kStatus_Fail; + } + + /* IO only mode */ + if (combMode == 0x2U) + { + base->EVENT[s_currentEvent].CTRL = currentCtrlVal | SCT_EVENT_CTRL_IOSEL(whichIO); + } + /* Match mode only */ + else if (combMode == 0x1U) + { + /* Return an error if we have hit the limit in terms of number of number of match registers */ + if (s_currentMatch >= FSL_FEATURE_SCT_NUMBER_OF_MATCH_CAPTURE) + { + return kStatus_Fail; + } + + currentCtrlVal |= SCT_EVENT_CTRL_MATCHSEL(s_currentMatch); + /* Use Counter_L bits if counter is operating in 32-bit mode or user wants to setup the L counter */ + if ((base->CONFIG & SCT_CONFIG_UNIFY_MASK) || (whichCounter == kSCTIMER_Counter_L)) + { + base->SCTMATCH[s_currentMatch] = SCT_SCTMATCH_MATCHn_L(matchValue); + base->SCTMATCHREL[s_currentMatch] = SCT_SCTMATCHREL_RELOADn_L(matchValue); + } + else + { + /* Select the counter, no need for this if operating in 32-bit mode */ + currentCtrlVal |= SCT_EVENT_CTRL_HEVENT(whichCounter); + base->SCTMATCH[s_currentMatch] = SCT_SCTMATCH_MATCHn_H(matchValue); + base->SCTMATCHREL[s_currentMatch] = SCT_SCTMATCHREL_RELOADn_H(matchValue); + } + base->EVENT[s_currentEvent].CTRL = currentCtrlVal; + /* Increment the match register number */ + s_currentMatch++; + } + /* Use both Match & IO */ + else + { + /* Return an error if we have hit the limit in terms of number of number of match registers */ + if (s_currentMatch >= FSL_FEATURE_SCT_NUMBER_OF_MATCH_CAPTURE) + { + return kStatus_Fail; + } + + currentCtrlVal |= SCT_EVENT_CTRL_MATCHSEL(s_currentMatch) | SCT_EVENT_CTRL_IOSEL(whichIO); + /* Use Counter_L bits if counter is operating in 32-bit mode or user wants to setup the L counter */ + if ((base->CONFIG & SCT_CONFIG_UNIFY_MASK) || (whichCounter == kSCTIMER_Counter_L)) + { + base->SCTMATCH[s_currentMatch] = SCT_SCTMATCH_MATCHn_L(matchValue); + base->SCTMATCHREL[s_currentMatch] = SCT_SCTMATCHREL_RELOADn_L(matchValue); + } + else + { + /* Select the counter, no need for this if operating in 32-bit mode */ + currentCtrlVal |= SCT_EVENT_CTRL_HEVENT(whichCounter); + base->SCTMATCH[s_currentMatch] = SCT_SCTMATCH_MATCHn_H(matchValue); + base->SCTMATCHREL[s_currentMatch] = SCT_SCTMATCHREL_RELOADn_H(matchValue); + } + base->EVENT[s_currentEvent].CTRL = currentCtrlVal; + /* Increment the match register number */ + s_currentMatch++; + } + + /* Enable the event in the current state */ + base->EVENT[s_currentEvent].STATE = (1U << s_currentState); + + /* Return the event number */ + *event = s_currentEvent; + + /* Increment the event number */ + s_currentEvent++; + + return kStatus_Success; +} + +void SCTIMER_ScheduleEvent(SCT_Type *base, uint32_t event) +{ + /* Enable event in the current state */ + base->EVENT[event].STATE |= (1U << s_currentState); +} + +status_t SCTIMER_IncreaseState(SCT_Type *base) +{ + /* Return an error if we have hit the limit in terms of states used */ + if (s_currentState >= FSL_FEATURE_SCT_NUMBER_OF_STATES) + { + return kStatus_Fail; + } + + s_currentState++; + + return kStatus_Success; +} + +uint32_t SCTIMER_GetCurrentState(SCT_Type *base) +{ + return s_currentState; +} + +void SCTIMER_SetupOutputToggleAction(SCT_Type *base, uint32_t whichIO, uint32_t event) +{ + uint32_t reg; + + /* Set the same event to set and clear the output */ + base->OUT[whichIO].CLR |= (1U << event); + base->OUT[whichIO].SET |= (1U << event); + + /* Set the conflict resolution to toggle output */ + reg = base->RES; + reg &= ~(SCT_RES_O0RES_MASK << (2 * whichIO)); + reg |= (uint32_t)(kSCTIMER_ResolveToggle << (2 * whichIO)); + base->RES = reg; +} + +status_t SCTIMER_SetupCaptureAction(SCT_Type *base, + sctimer_counter_t whichCounter, + uint32_t *captureRegister, + uint32_t event) +{ + /* Return an error if we have hit the limit in terms of number of capture/match registers used */ + if (s_currentMatch >= FSL_FEATURE_SCT_NUMBER_OF_MATCH_CAPTURE) + { + return kStatus_Fail; + } + + /* Use Counter_L bits if counter is operating in 32-bit mode or user wants to setup the L counter */ + if ((base->CONFIG & SCT_CONFIG_UNIFY_MASK) || (whichCounter == kSCTIMER_Counter_L)) + { + /* Set the bit to enable event */ + base->SCTCAPCTRL[s_currentMatch] |= SCT_SCTCAPCTRL_CAPCONn_L(1 << event); + + /* Set this resource to be a capture rather than match */ + base->REGMODE |= SCT_REGMODE_REGMOD_L(1 << s_currentMatch); + } + else + { + /* Set bit to enable event */ + base->SCTCAPCTRL[s_currentMatch] |= SCT_SCTCAPCTRL_CAPCONn_H(1 << event); + + /* Set this resource to be a capture rather than match */ + base->REGMODE |= SCT_REGMODE_REGMOD_H(1 << s_currentMatch); + } + + /* Return the match register number */ + *captureRegister = s_currentMatch; + + /* Increase the match register number */ + s_currentMatch++; + + return kStatus_Success; +} + +void SCTIMER_SetCallback(SCT_Type *base, sctimer_event_callback_t callback, uint32_t event) +{ + s_eventCallback[event] = callback; +} + +void SCTIMER_EventHandleIRQ(SCT_Type *base) +{ + uint32_t eventFlag = SCT0->EVFLAG; + /* Only clear the flags whose interrupt field is enabled */ + uint32_t clearFlag = (eventFlag & SCT0->EVEN); + uint32_t mask = eventFlag; + int i = 0; + + /* Invoke the callback for certain events */ + for (i = 0; (i < FSL_FEATURE_SCT_NUMBER_OF_EVENTS) && (mask != 0); i++) + { + if (mask & 0x1) + { + if (s_eventCallback[i] != NULL) + { + s_eventCallback[i](); + } + } + mask >>= 1; + } + + /* Clear event interrupt flag */ + SCT0->EVFLAG = clearFlag; +} + +void SCT0_IRQHandler(void) +{ + s_sctimerIsr(SCT0); + /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} diff --git a/platform/mcu/lpc54102/drivers/fsl_sctimer.h b/platform/mcu/lpc54102/drivers/fsl_sctimer.h new file mode 100644 index 0000000000..e799e1ecef --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_sctimer.h @@ -0,0 +1,822 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_SCTIMER_H_ +#define _FSL_SCTIMER_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup sctimer + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +#define FSL_SCTIMER_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0 */ +/*@}*/ + +/*! @brief SCTimer PWM operation modes */ +typedef enum _sctimer_pwm_mode +{ + kSCTIMER_EdgeAlignedPwm = 0U, /*!< Edge-aligned PWM */ + kSCTIMER_CenterAlignedPwm /*!< Center-aligned PWM */ +} sctimer_pwm_mode_t; + +/*! @brief SCTimer counters when working as two independent 16-bit counters */ +typedef enum _sctimer_counter +{ + kSCTIMER_Counter_L = 0U, /*!< Counter L */ + kSCTIMER_Counter_H /*!< Counter H */ +} sctimer_counter_t; + +/*! @brief List of SCTimer input pins */ +typedef enum _sctimer_input +{ + kSCTIMER_Input_0 = 0U, /*!< SCTIMER input 0 */ + kSCTIMER_Input_1, /*!< SCTIMER input 1 */ + kSCTIMER_Input_2, /*!< SCTIMER input 2 */ + kSCTIMER_Input_3, /*!< SCTIMER input 3 */ + kSCTIMER_Input_4, /*!< SCTIMER input 4 */ + kSCTIMER_Input_5, /*!< SCTIMER input 5 */ + kSCTIMER_Input_6, /*!< SCTIMER input 6 */ + kSCTIMER_Input_7 /*!< SCTIMER input 7 */ +} sctimer_input_t; + +/*! @brief List of SCTimer output pins */ +typedef enum _sctimer_out +{ + kSCTIMER_Out_0 = 0U, /*!< SCTIMER output 0*/ + kSCTIMER_Out_1, /*!< SCTIMER output 1 */ + kSCTIMER_Out_2, /*!< SCTIMER output 2 */ + kSCTIMER_Out_3, /*!< SCTIMER output 3 */ + kSCTIMER_Out_4, /*!< SCTIMER output 4 */ + kSCTIMER_Out_5, /*!< SCTIMER output 5 */ + kSCTIMER_Out_6, /*!< SCTIMER output 6 */ + kSCTIMER_Out_7 /*!< SCTIMER output 7 */ +} sctimer_out_t; + +/*! @brief SCTimer PWM output pulse mode: high-true, low-true or no output */ +typedef enum _sctimer_pwm_level_select +{ + kSCTIMER_LowTrue = 0U, /*!< Low true pulses */ + kSCTIMER_HighTrue /*!< High true pulses */ +} sctimer_pwm_level_select_t; + +/*! @brief Options to configure a SCTimer PWM signal */ +typedef struct _sctimer_pwm_signal_param +{ + sctimer_out_t output; /*!< The output pin to use to generate the PWM signal */ + sctimer_pwm_level_select_t level; /*!< PWM output active level select. */ + uint8_t dutyCyclePercent; /*!< PWM pulse width, value should be between 1 to 100 + 100 = always active signal (100% duty cycle).*/ +} sctimer_pwm_signal_param_t; + +/*! @brief SCTimer clock mode options */ +typedef enum _sctimer_clock_mode +{ + kSCTIMER_System_ClockMode = 0U, /*!< System Clock Mode */ + kSCTIMER_Sampled_ClockMode, /*!< Sampled System Clock Mode */ + kSCTIMER_Input_ClockMode, /*!< SCT Input Clock Mode */ + kSCTIMER_Asynchronous_ClockMode /*!< Asynchronous Mode */ +} sctimer_clock_mode_t; + +/*! @brief SCTimer clock select options */ +typedef enum _sctimer_clock_select +{ + kSCTIMER_Clock_On_Rise_Input_0 = 0U, /*!< Rising edges on input 0 */ + kSCTIMER_Clock_On_Fall_Input_0, /*!< Falling edges on input 0 */ + kSCTIMER_Clock_On_Rise_Input_1, /*!< Rising edges on input 1 */ + kSCTIMER_Clock_On_Fall_Input_1, /*!< Falling edges on input 1 */ + kSCTIMER_Clock_On_Rise_Input_2, /*!< Rising edges on input 2 */ + kSCTIMER_Clock_On_Fall_Input_2, /*!< Falling edges on input 2 */ + kSCTIMER_Clock_On_Rise_Input_3, /*!< Rising edges on input 3 */ + kSCTIMER_Clock_On_Fall_Input_3, /*!< Falling edges on input 3 */ + kSCTIMER_Clock_On_Rise_Input_4, /*!< Rising edges on input 4 */ + kSCTIMER_Clock_On_Fall_Input_4, /*!< Falling edges on input 4 */ + kSCTIMER_Clock_On_Rise_Input_5, /*!< Rising edges on input 5 */ + kSCTIMER_Clock_On_Fall_Input_5, /*!< Falling edges on input 5 */ + kSCTIMER_Clock_On_Rise_Input_6, /*!< Rising edges on input 6 */ + kSCTIMER_Clock_On_Fall_Input_6, /*!< Falling edges on input 6 */ + kSCTIMER_Clock_On_Rise_Input_7, /*!< Rising edges on input 7 */ + kSCTIMER_Clock_On_Fall_Input_7 /*!< Falling edges on input 7 */ +} sctimer_clock_select_t; + +/*! + * @brief SCTimer output conflict resolution options. + * + * Specifies what action should be taken if multiple events dictate that a given output should be + * both set and cleared at the same time + */ +typedef enum _sctimer_conflict_resolution +{ + kSCTIMER_ResolveNone = 0U, /*!< No change */ + kSCTIMER_ResolveSet, /*!< Set output */ + kSCTIMER_ResolveClear, /*!< Clear output */ + kSCTIMER_ResolveToggle /*!< Toggle output */ +} sctimer_conflict_resolution_t; + +/*! @brief List of SCTimer event types */ +typedef enum _sctimer_event +{ + kSCTIMER_InputLowOrMatchEvent = + (0 << SCT_EVENT_CTRL_COMBMODE_SHIFT) + (0 << SCT_EVENT_CTRL_IOCOND_SHIFT) + (0 << SCT_EVENT_CTRL_OUTSEL_SHIFT), + kSCTIMER_InputRiseOrMatchEvent = + (0 << SCT_EVENT_CTRL_COMBMODE_SHIFT) + (1 << SCT_EVENT_CTRL_IOCOND_SHIFT) + (0 << SCT_EVENT_CTRL_OUTSEL_SHIFT), + kSCTIMER_InputFallOrMatchEvent = + (0 << SCT_EVENT_CTRL_COMBMODE_SHIFT) + (2 << SCT_EVENT_CTRL_IOCOND_SHIFT) + (0 << SCT_EVENT_CTRL_OUTSEL_SHIFT), + kSCTIMER_InputHighOrMatchEvent = + (0 << SCT_EVENT_CTRL_COMBMODE_SHIFT) + (3 << SCT_EVENT_CTRL_IOCOND_SHIFT) + (0 << SCT_EVENT_CTRL_OUTSEL_SHIFT), + + kSCTIMER_MatchEventOnly = + (1 << SCT_EVENT_CTRL_COMBMODE_SHIFT) + (0 << SCT_EVENT_CTRL_IOCOND_SHIFT) + (0 << SCT_EVENT_CTRL_OUTSEL_SHIFT), + + kSCTIMER_InputLowEvent = + (2 << SCT_EVENT_CTRL_COMBMODE_SHIFT) + (0 << SCT_EVENT_CTRL_IOCOND_SHIFT) + (0 << SCT_EVENT_CTRL_OUTSEL_SHIFT), + kSCTIMER_InputRiseEvent = + (2 << SCT_EVENT_CTRL_COMBMODE_SHIFT) + (1 << SCT_EVENT_CTRL_IOCOND_SHIFT) + (0 << SCT_EVENT_CTRL_OUTSEL_SHIFT), + kSCTIMER_InputFallEvent = + (2 << SCT_EVENT_CTRL_COMBMODE_SHIFT) + (2 << SCT_EVENT_CTRL_IOCOND_SHIFT) + (0 << SCT_EVENT_CTRL_OUTSEL_SHIFT), + kSCTIMER_InputHighEvent = + (2 << SCT_EVENT_CTRL_COMBMODE_SHIFT) + (3 << SCT_EVENT_CTRL_IOCOND_SHIFT) + (0 << SCT_EVENT_CTRL_OUTSEL_SHIFT), + + kSCTIMER_InputLowAndMatchEvent = + (3 << SCT_EVENT_CTRL_COMBMODE_SHIFT) + (0 << SCT_EVENT_CTRL_IOCOND_SHIFT) + (0 << SCT_EVENT_CTRL_OUTSEL_SHIFT), + kSCTIMER_InputRiseAndMatchEvent = + (3 << SCT_EVENT_CTRL_COMBMODE_SHIFT) + (1 << SCT_EVENT_CTRL_IOCOND_SHIFT) + (0 << SCT_EVENT_CTRL_OUTSEL_SHIFT), + kSCTIMER_InputFallAndMatchEvent = + (3 << SCT_EVENT_CTRL_COMBMODE_SHIFT) + (2 << SCT_EVENT_CTRL_IOCOND_SHIFT) + (0 << SCT_EVENT_CTRL_OUTSEL_SHIFT), + kSCTIMER_InputHighAndMatchEvent = + (3 << SCT_EVENT_CTRL_COMBMODE_SHIFT) + (3 << SCT_EVENT_CTRL_IOCOND_SHIFT) + (0 << SCT_EVENT_CTRL_OUTSEL_SHIFT), + + kSCTIMER_OutputLowOrMatchEvent = + (0 << SCT_EVENT_CTRL_COMBMODE_SHIFT) + (0 << SCT_EVENT_CTRL_IOCOND_SHIFT) + (1 << SCT_EVENT_CTRL_OUTSEL_SHIFT), + kSCTIMER_OutputRiseOrMatchEvent = + (0 << SCT_EVENT_CTRL_COMBMODE_SHIFT) + (1 << SCT_EVENT_CTRL_IOCOND_SHIFT) + (1 << SCT_EVENT_CTRL_OUTSEL_SHIFT), + kSCTIMER_OutputFallOrMatchEvent = + (0 << SCT_EVENT_CTRL_COMBMODE_SHIFT) + (2 << SCT_EVENT_CTRL_IOCOND_SHIFT) + (1 << SCT_EVENT_CTRL_OUTSEL_SHIFT), + kSCTIMER_OutputHighOrMatchEvent = + (0 << SCT_EVENT_CTRL_COMBMODE_SHIFT) + (3 << SCT_EVENT_CTRL_IOCOND_SHIFT) + (1 << SCT_EVENT_CTRL_OUTSEL_SHIFT), + + kSCTIMER_OutputLowEvent = + (2 << SCT_EVENT_CTRL_COMBMODE_SHIFT) + (0 << SCT_EVENT_CTRL_IOCOND_SHIFT) + (1 << SCT_EVENT_CTRL_OUTSEL_SHIFT), + kSCTIMER_OutputRiseEvent = + (2 << SCT_EVENT_CTRL_COMBMODE_SHIFT) + (1 << SCT_EVENT_CTRL_IOCOND_SHIFT) + (1 << SCT_EVENT_CTRL_OUTSEL_SHIFT), + kSCTIMER_OutputFallEvent = + (2 << SCT_EVENT_CTRL_COMBMODE_SHIFT) + (2 << SCT_EVENT_CTRL_IOCOND_SHIFT) + (1 << SCT_EVENT_CTRL_OUTSEL_SHIFT), + kSCTIMER_OutputHighEvent = + (2 << SCT_EVENT_CTRL_COMBMODE_SHIFT) + (3 << SCT_EVENT_CTRL_IOCOND_SHIFT) + (1 << SCT_EVENT_CTRL_OUTSEL_SHIFT), + + kSCTIMER_OutputLowAndMatchEvent = + (3 << SCT_EVENT_CTRL_COMBMODE_SHIFT) + (0 << SCT_EVENT_CTRL_IOCOND_SHIFT) + (1 << SCT_EVENT_CTRL_OUTSEL_SHIFT), + kSCTIMER_OutputRiseAndMatchEvent = + (3 << SCT_EVENT_CTRL_COMBMODE_SHIFT) + (1 << SCT_EVENT_CTRL_IOCOND_SHIFT) + (1 << SCT_EVENT_CTRL_OUTSEL_SHIFT), + kSCTIMER_OutputFallAndMatchEvent = + (3 << SCT_EVENT_CTRL_COMBMODE_SHIFT) + (2 << SCT_EVENT_CTRL_IOCOND_SHIFT) + (1 << SCT_EVENT_CTRL_OUTSEL_SHIFT), + kSCTIMER_OutputHighAndMatchEvent = + (3 << SCT_EVENT_CTRL_COMBMODE_SHIFT) + (3 << SCT_EVENT_CTRL_IOCOND_SHIFT) + (1 << SCT_EVENT_CTRL_OUTSEL_SHIFT) +} sctimer_event_t; + +/*! @brief SCTimer callback typedef. */ +typedef void (*sctimer_event_callback_t)(void); + +/*! @brief List of SCTimer interrupts */ +typedef enum _sctimer_interrupt_enable +{ + kSCTIMER_Event0InterruptEnable = (1U << 0), /*!< Event 0 interrupt */ + kSCTIMER_Event1InterruptEnable = (1U << 1), /*!< Event 1 interrupt */ + kSCTIMER_Event2InterruptEnable = (1U << 2), /*!< Event 2 interrupt */ + kSCTIMER_Event3InterruptEnable = (1U << 3), /*!< Event 3 interrupt */ + kSCTIMER_Event4InterruptEnable = (1U << 4), /*!< Event 4 interrupt */ + kSCTIMER_Event5InterruptEnable = (1U << 5), /*!< Event 5 interrupt */ + kSCTIMER_Event6InterruptEnable = (1U << 6), /*!< Event 6 interrupt */ + kSCTIMER_Event7InterruptEnable = (1U << 7), /*!< Event 7 interrupt */ + kSCTIMER_Event8InterruptEnable = (1U << 8), /*!< Event 8 interrupt */ + kSCTIMER_Event9InterruptEnable = (1U << 9), /*!< Event 9 interrupt */ + kSCTIMER_Event10InterruptEnable = (1U << 10), /*!< Event 10 interrupt */ + kSCTIMER_Event11InterruptEnable = (1U << 11), /*!< Event 11 interrupt */ + kSCTIMER_Event12InterruptEnable = (1U << 12), /*!< Event 12 interrupt */ +} sctimer_interrupt_enable_t; + +/*! @brief List of SCTimer flags */ +typedef enum _sctimer_status_flags +{ + kSCTIMER_Event0Flag = (1U << 0), /*!< Event 0 Flag */ + kSCTIMER_Event1Flag = (1U << 1), /*!< Event 1 Flag */ + kSCTIMER_Event2Flag = (1U << 2), /*!< Event 2 Flag */ + kSCTIMER_Event3Flag = (1U << 3), /*!< Event 3 Flag */ + kSCTIMER_Event4Flag = (1U << 4), /*!< Event 4 Flag */ + kSCTIMER_Event5Flag = (1U << 5), /*!< Event 5 Flag */ + kSCTIMER_Event6Flag = (1U << 6), /*!< Event 6 Flag */ + kSCTIMER_Event7Flag = (1U << 7), /*!< Event 7 Flag */ + kSCTIMER_Event8Flag = (1U << 8), /*!< Event 8 Flag */ + kSCTIMER_Event9Flag = (1U << 9), /*!< Event 9 Flag */ + kSCTIMER_Event10Flag = (1U << 10), /*!< Event 10 Flag */ + kSCTIMER_Event11Flag = (1U << 11), /*!< Event 11 Flag */ + kSCTIMER_Event12Flag = (1U << 12), /*!< Event 12 Flag */ + kSCTIMER_BusErrorLFlag = + (1U << SCT_CONFLAG_BUSERRL_SHIFT), /*!< Bus error due to write when L counter was not halted */ + kSCTIMER_BusErrorHFlag = + (1U << SCT_CONFLAG_BUSERRH_SHIFT) /*!< Bus error due to write when H counter was not halted */ +} sctimer_status_flags_t; + +/*! + * @brief SCTimer configuration structure + * + * This structure holds the configuration settings for the SCTimer peripheral. To initialize this + * structure to reasonable defaults, call the SCTMR_GetDefaultConfig() function and pass a + * pointer to the configuration structure instance. + * + * The configuration structure can be made constant so as to reside in flash. + */ +typedef struct _sctimer_config +{ + bool enableCounterUnify; /*!< true: SCT operates as a unified 32-bit counter; + false: SCT operates as two 16-bit counters */ + sctimer_clock_mode_t clockMode; /*!< SCT clock mode value */ + sctimer_clock_select_t clockSelect; /*!< SCT clock select value */ + bool enableBidirection_l; /*!< true: Up-down count mode for the L or unified counter + false: Up count mode only for the L or unified counter */ + bool enableBidirection_h; /*!< true: Up-down count mode for the H or unified counter + false: Up count mode only for the H or unified counter. + This field is used only if the enableCounterUnify is set + to false */ + uint8_t prescale_l; /*!< Prescale value to produce the L or unified counter clock */ + uint8_t prescale_h; /*!< Prescale value to produce the H counter clock. + This field is used only if the enableCounterUnify is set + to false */ + uint8_t outInitState; /*!< Defines the initial output value */ +} sctimer_config_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name Initialization and deinitialization + * @{ + */ + +/*! + * @brief Ungates the SCTimer clock and configures the peripheral for basic operation. + * + * @note This API should be called at the beginning of the application using the SCTimer driver. + * + * @param base SCTimer peripheral base address + * @param config Pointer to the user configuration structure. + * + * @return kStatus_Success indicates success; Else indicates failure. + */ +status_t SCTIMER_Init(SCT_Type *base, const sctimer_config_t *config); + +/*! + * @brief Gates the SCTimer clock. + * + * @param base SCTimer peripheral base address + */ +void SCTIMER_Deinit(SCT_Type *base); + +/*! + * @brief Fills in the SCTimer configuration structure with the default settings. + * + * The default values are: + * @code + * config->enableCounterUnify = true; + * config->clockMode = kSCTIMER_System_ClockMode; + * config->clockSelect = kSCTIMER_Clock_On_Rise_Input_0; + * config->enableBidirection_l = false; + * config->enableBidirection_h = false; + * config->prescale_l = 0; + * config->prescale_h = 0; + * config->outInitState = 0; + * @endcode + * @param config Pointer to the user configuration structure. + */ +void SCTIMER_GetDefaultConfig(sctimer_config_t *config); + +/*! @}*/ + +/*! + * @name PWM setup operations + * @{ + */ + +/*! + * @brief Configures the PWM signal parameters. + * + * Call this function to configure the PWM signal period, mode, duty cycle, and edge. This + * function will create 2 events; one of the events will trigger on match with the pulse value + * and the other will trigger when the counter matches the PWM period. The PWM period event is + * also used as a limit event to reset the counter or change direction. Both events are enabled + * for the same state. The state number can be retrieved by calling the function + * SCTIMER_GetCurrentStateNumber(). + * The counter is set to operate as one 32-bit counter (unify bit is set to 1). + * The counter operates in bi-directional mode when generating a center-aligned PWM. + * + * @note When setting PWM output from multiple output pins, they all should use the same PWM mode + * i.e all PWM's should be either edge-aligned or center-aligned. + * When using this API, the PWM signal frequency of all the initialized channels must be the same. + * Otherwise all the initialized channels' PWM signal frequency is equal to the last call to the + * API's pwmFreq_Hz. + * + * @param base SCTimer peripheral base address + * @param pwmParams PWM parameters to configure the output + * @param mode PWM operation mode, options available in enumeration ::sctimer_pwm_mode_t + * @param pwmFreq_Hz PWM signal frequency in Hz + * @param srcClock_Hz SCTimer counter clock in Hz + * @param event Pointer to a variable where the PWM period event number is stored + * + * @return kStatus_Success on success + * kStatus_Fail If we have hit the limit in terms of number of events created or if + * an incorrect PWM dutycylce is passed in. + */ +status_t SCTIMER_SetupPwm(SCT_Type *base, + const sctimer_pwm_signal_param_t *pwmParams, + sctimer_pwm_mode_t mode, + uint32_t pwmFreq_Hz, + uint32_t srcClock_Hz, + uint32_t *event); + +/*! + * @brief Updates the duty cycle of an active PWM signal. + * + * @param base SCTimer peripheral base address + * @param output The output to configure + * @param dutyCyclePercent New PWM pulse width; the value should be between 1 to 100 + * @param event Event number associated with this PWM signal. This was returned to the user by the + * function SCTIMER_SetupPwm(). + */ +void SCTIMER_UpdatePwmDutycycle(SCT_Type *base, sctimer_out_t output, uint8_t dutyCyclePercent, uint32_t event); + +/*! + * @name Interrupt Interface + * @{ + */ + +/*! + * @brief Enables the selected SCTimer interrupts. + * + * @param base SCTimer peripheral base address + * @param mask The interrupts to enable. This is a logical OR of members of the + * enumeration ::sctimer_interrupt_enable_t + */ +static inline void SCTIMER_EnableInterrupts(SCT_Type *base, uint32_t mask) +{ + base->EVEN |= mask; +} + +/*! + * @brief Disables the selected SCTimer interrupts. + * + * @param base SCTimer peripheral base address + * @param mask The interrupts to enable. This is a logical OR of members of the + * enumeration ::sctimer_interrupt_enable_t + */ +static inline void SCTIMER_DisableInterrupts(SCT_Type *base, uint32_t mask) +{ + base->EVEN &= ~mask; +} + +/*! + * @brief Gets the enabled SCTimer interrupts. + * + * @param base SCTimer peripheral base address + * + * @return The enabled interrupts. This is the logical OR of members of the + * enumeration ::sctimer_interrupt_enable_t + */ +static inline uint32_t SCTIMER_GetEnabledInterrupts(SCT_Type *base) +{ + return (base->EVEN & 0xFFFFU); +} + +/*! @}*/ + +/*! + * @name Status Interface + * @{ + */ + +/*! + * @brief Gets the SCTimer status flags. + * + * @param base SCTimer peripheral base address + * + * @return The status flags. This is the logical OR of members of the + * enumeration ::sctimer_status_flags_t + */ +static inline uint32_t SCTIMER_GetStatusFlags(SCT_Type *base) +{ + uint32_t statusFlags = 0; + + /* Add the recorded events */ + statusFlags = (base->EVFLAG & 0xFFFFU); + + /* Add bus error flags */ + statusFlags |= (base->CONFLAG & (SCT_CONFLAG_BUSERRL_MASK | SCT_CONFLAG_BUSERRH_MASK)); + + return statusFlags; +} + +/*! + * @brief Clears the SCTimer status flags. + * + * @param base SCTimer peripheral base address + * @param mask The status flags to clear. This is a logical OR of members of the + * enumeration ::sctimer_status_flags_t + */ +static inline void SCTIMER_ClearStatusFlags(SCT_Type *base, uint32_t mask) +{ + /* Write to the flag registers */ + base->EVFLAG = (mask & 0xFFFFU); + base->CONFLAG = (mask & (SCT_CONFLAG_BUSERRL_MASK | SCT_CONFLAG_BUSERRH_MASK)); +} + +/*! @}*/ + +/*! + * @name Counter Start and Stop + * @{ + */ + +/*! + * @brief Starts the SCTimer counter. + * + * @param base SCTimer peripheral base address + * @param countertoStart SCTimer counter to start; if unify mode is set then function always + * writes to HALT_L bit + */ +static inline void SCTIMER_StartTimer(SCT_Type *base, sctimer_counter_t countertoStart) +{ + /* Clear HALT_L bit if counter is operating in 32-bit mode or user wants to start L counter */ + if ((base->CONFIG & SCT_CONFIG_UNIFY_MASK) || (countertoStart == kSCTIMER_Counter_L)) + { + base->CTRL &= ~(SCT_CTRL_HALT_L_MASK); + } + else + { + /* Start H counter */ + base->CTRL &= ~(SCT_CTRL_HALT_H_MASK); + } +} + +/*! + * @brief Halts the SCTimer counter. + * + * @param base SCTimer peripheral base address + * @param countertoStop SCTimer counter to stop; if unify mode is set then function always + * writes to HALT_L bit + */ +static inline void SCTIMER_StopTimer(SCT_Type *base, sctimer_counter_t countertoStop) +{ + /* Set HALT_L bit if counter is operating in 32-bit mode or user wants to stop L counter */ + if ((base->CONFIG & SCT_CONFIG_UNIFY_MASK) || (countertoStop == kSCTIMER_Counter_L)) + { + base->CTRL |= (SCT_CTRL_HALT_L_MASK); + } + else + { + /* Stop H counter */ + base->CTRL |= (SCT_CTRL_HALT_H_MASK); + } +} + +/*! @}*/ + +/*! + * @name Functions to create a new event and manage the state logic + * @{ + */ + +/*! + * @brief Create an event that is triggered on a match or IO and schedule in current state. + * + * This function will configure an event using the options provided by the user. If the event type uses + * the counter match, then the function will set the user provided match value into a match register + * and put this match register number into the event control register. + * The event is enabled for the current state and the event number is increased by one at the end. + * The function returns the event number; this event number can be used to configure actions to be + * done when this event is triggered. + * + * @param base SCTimer peripheral base address + * @param howToMonitor Event type; options are available in the enumeration ::sctimer_interrupt_enable_t + * @param matchValue The match value that will be programmed to a match register + * @param whichIO The input or output that will be involved in event triggering. This field + * is ignored if the event type is "match only" + * @param whichCounter SCTimer counter to use when operating in 16-bit mode. In 32-bit mode, this + * field has no meaning as we have only 1 unified counter; hence ignored. + * @param event Pointer to a variable where the new event number is stored + * + * @return kStatus_Success on success + * kStatus_Error if we have hit the limit in terms of number of events created or + if we have reached the limit in terms of number of match registers + */ +status_t SCTIMER_CreateAndScheduleEvent(SCT_Type *base, + sctimer_event_t howToMonitor, + uint32_t matchValue, + uint32_t whichIO, + sctimer_counter_t whichCounter, + uint32_t *event); + +/*! + * @brief Enable an event in the current state. + * + * This function will allow the event passed in to trigger in the current state. The event must + * be created earlier by either calling the function SCTIMER_SetupPwm() or function + * SCTIMER_CreateAndScheduleEvent() . + * + * @param base SCTimer peripheral base address + * @param event Event number to enable in the current state + * + */ +void SCTIMER_ScheduleEvent(SCT_Type *base, uint32_t event); + +/*! + * @brief Increase the state by 1 + * + * All future events created by calling the function SCTIMER_ScheduleEvent() will be enabled in this new + * state. + * + * @param base SCTimer peripheral base address + * + * @return kStatus_Success on success + * kStatus_Error if we have hit the limit in terms of states used + + */ +status_t SCTIMER_IncreaseState(SCT_Type *base); + +/*! + * @brief Provides the current state + * + * User can use this to set the next state by calling the function SCTIMER_SetupNextStateAction(). + * + * @param base SCTimer peripheral base address + * + * @return The current state + */ +uint32_t SCTIMER_GetCurrentState(SCT_Type *base); + +/*! @}*/ + +/*! + * @name Actions to take in response to an event + * @{ + */ + +/*! + * @brief Setup capture of the counter value on trigger of a selected event + * + * @param base SCTimer peripheral base address + * @param whichCounter SCTimer counter to use when operating in 16-bit mode. In 32-bit mode, this + * field has no meaning as only the Counter_L bits are used. + * @param captureRegister Pointer to a variable where the capture register number will be returned. User + * can read the captured value from this register when the specified event is triggered. + * @param event Event number that will trigger the capture + * + * @return kStatus_Success on success + * kStatus_Error if we have hit the limit in terms of number of match/capture registers available + */ +status_t SCTIMER_SetupCaptureAction(SCT_Type *base, + sctimer_counter_t whichCounter, + uint32_t *captureRegister, + uint32_t event); + +/*! + * @brief Receive noticification when the event trigger an interrupt. + * + * If the interrupt for the event is enabled by the user, then a callback can be registered + * which will be invoked when the event is triggered + * + * @param base SCTimer peripheral base address + * @param event Event number that will trigger the interrupt + * @param callback Function to invoke when the event is triggered + */ + +void SCTIMER_SetCallback(SCT_Type *base, sctimer_event_callback_t callback, uint32_t event); + +/*! + * @brief Transition to the specified state. + * + * This transition will be triggered by the event number that is passed in by the user. + * + * @param base SCTimer peripheral base address + * @param nextState The next state SCTimer will transition to + * @param event Event number that will trigger the state transition + */ +static inline void SCTIMER_SetupNextStateAction(SCT_Type *base, uint32_t nextState, uint32_t event) +{ + uint32_t reg = base->EVENT[event].CTRL; + + reg &= ~(SCT_EVENT_CTRL_STATEV_MASK); + /* Load the STATEV value when the event occurs to be the next state */ + reg |= SCT_EVENT_CTRL_STATEV(nextState) | SCT_EVENT_CTRL_STATELD_MASK; + + base->EVENT[event].CTRL = reg; +} + +/*! + * @brief Set the Output. + * + * This output will be set when the event number that is passed in by the user is triggered. + * + * @param base SCTimer peripheral base address + * @param whichIO The output to set + * @param event Event number that will trigger the output change + */ +static inline void SCTIMER_SetupOutputSetAction(SCT_Type *base, uint32_t whichIO, uint32_t event) +{ + base->OUT[whichIO].SET |= (1U << event); +} + +/*! + * @brief Clear the Output. + * + * This output will be cleared when the event number that is passed in by the user is triggered. + * + * @param base SCTimer peripheral base address + * @param whichIO The output to clear + * @param event Event number that will trigger the output change + */ +static inline void SCTIMER_SetupOutputClearAction(SCT_Type *base, uint32_t whichIO, uint32_t event) +{ + base->OUT[whichIO].CLR |= (1U << event); +} + +/*! + * @brief Toggle the output level. + * + * This change in the output level is triggered by the event number that is passed in by the user. + * + * @param base SCTimer peripheral base address + * @param whichIO The output to toggle + * @param event Event number that will trigger the output change + */ +void SCTIMER_SetupOutputToggleAction(SCT_Type *base, uint32_t whichIO, uint32_t event); + +/*! + * @brief Limit the running counter. + * + * The counter is limited when the event number that is passed in by the user is triggered. + * + * @param base SCTimer peripheral base address + * @param whichCounter SCTimer counter to use when operating in 16-bit mode. In 32-bit mode, this + * field has no meaning as only the Counter_L bits are used. + * @param event Event number that will trigger the counter to be limited + */ +static inline void SCTIMER_SetupCounterLimitAction(SCT_Type *base, sctimer_counter_t whichCounter, uint32_t event) +{ + /* Use Counter_L bits if counter is operating in 32-bit mode or user wants to setup the L counter */ + if ((base->CONFIG & SCT_CONFIG_UNIFY_MASK) || (whichCounter == kSCTIMER_Counter_L)) + { + base->LIMIT |= SCT_LIMIT_LIMMSK_L(1U << event); + } + else + { + base->LIMIT |= SCT_LIMIT_LIMMSK_H(1U << event); + } +} + +/*! + * @brief Stop the running counter. + * + * The counter is stopped when the event number that is passed in by the user is triggered. + * + * @param base SCTimer peripheral base address + * @param whichCounter SCTimer counter to use when operating in 16-bit mode. In 32-bit mode, this + * field has no meaning as only the Counter_L bits are used. + * @param event Event number that will trigger the counter to be stopped + */ +static inline void SCTIMER_SetupCounterStopAction(SCT_Type *base, sctimer_counter_t whichCounter, uint32_t event) +{ + /* Use Counter_L bits if counter is operating in 32-bit mode or user wants to setup the L counter */ + if ((base->CONFIG & SCT_CONFIG_UNIFY_MASK) || (whichCounter == kSCTIMER_Counter_L)) + { + base->STOP |= SCT_STOP_STOPMSK_L(1U << event); + } + else + { + base->STOP |= SCT_STOP_STOPMSK_H(1U << event); + } +} + +/*! + * @brief Re-start the stopped counter. + * + * The counter will re-start when the event number that is passed in by the user is triggered. + * + * @param base SCTimer peripheral base address + * @param whichCounter SCTimer counter to use when operating in 16-bit mode. In 32-bit mode, this + * field has no meaning as only the Counter_L bits are used. + * @param event Event number that will trigger the counter to re-start + */ +static inline void SCTIMER_SetupCounterStartAction(SCT_Type *base, sctimer_counter_t whichCounter, uint32_t event) +{ + /* Use Counter_L bits if counter is operating in 32-bit mode or user wants to setup the L counter */ + if ((base->CONFIG & SCT_CONFIG_UNIFY_MASK) || (whichCounter == kSCTIMER_Counter_L)) + { + base->START |= SCT_START_STARTMSK_L(1U << event); + } + else + { + base->START |= SCT_START_STARTMSK_H(1U << event); + } +} + +/*! + * @brief Halt the running counter. + * + * The counter is disabled (halted) when the event number that is passed in by the user is + * triggered. When the counter is halted, all further events are disabled. The HALT condition + * can only be removed by calling the SCTIMER_StartTimer() function. + * + * @param base SCTimer peripheral base address + * @param whichCounter SCTimer counter to use when operating in 16-bit mode. In 32-bit mode, this + * field has no meaning as only the Counter_L bits are used. + * @param event Event number that will trigger the counter to be halted + */ +static inline void SCTIMER_SetupCounterHaltAction(SCT_Type *base, sctimer_counter_t whichCounter, uint32_t event) +{ + /* Use Counter_L bits if counter is operating in 32-bit mode or user wants to setup the L counter */ + if ((base->CONFIG & SCT_CONFIG_UNIFY_MASK) || (whichCounter == kSCTIMER_Counter_L)) + { + base->HALT |= SCT_HALT_HALTMSK_L(1U << event); + } + else + { + base->HALT |= SCT_HALT_HALTMSK_H(1U << event); + } +} + +/*! + * @brief Generate a DMA request. + * + * DMA request will be triggered by the event number that is passed in by the user. + * + * @param base SCTimer peripheral base address + * @param dmaNumber The DMA request to generate + * @param event Event number that will trigger the DMA request + */ +static inline void SCTIMER_SetupDmaTriggerAction(SCT_Type *base, uint32_t dmaNumber, uint32_t event) +{ + if (dmaNumber == 0) + { + base->DMA0REQUEST |= (1U << event); + } + else + { + base->DMA1REQUEST |= (1U << event); + } +} + +/*! + * @brief SCTimer interrupt handler. + * + * @param base SCTimer peripheral base address. + */ +void SCTIMER_EventHandleIRQ(SCT_Type *base); + +/*! @}*/ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_SCTIMER_H_ */ diff --git a/platform/mcu/lpc54102/drivers/fsl_spi.c b/platform/mcu/lpc54102/drivers/fsl_spi.c new file mode 100644 index 0000000000..0f4d93b4af --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_spi.c @@ -0,0 +1,1307 @@ +/* + * Copyright (c) 2017, NXP Semiconductors, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_spi.h" + +/******************************************************************************* + * Definitons + ******************************************************************************/ + +/* Convert transfer count to transfer bytes. dataWidth is a + * range <0,15>. Range <8,15> represents 2B transfer */ +#define SPI_COUNT_TO_BYTES(dataWidth, count) ((count) << ((dataWidth) >> 3U)) +#define SPI_BYTES_TO_COUNT(dataWidth, bytes) ((bytes) >> ((dataWidth) >> 3U)) +#define SPI_SSELPOL_MASK ((SPI_CFG_SPOL0_MASK) | (SPI_CFG_SPOL1_MASK) | (SPI_CFG_SPOL2_MASK) | (SPI_CFG_SPOL3_MASK)) + +/******************************************************************************* + * Variables + ******************************************************************************/ +/*! @brief SPI internal handle pointer array */ +static spi_master_handle_t *s_spiHandle[FSL_FEATURE_SOC_SPI_COUNT]; + +/*! @brief internal SPI config array */ +static spi_config_t g_configs[FSL_FEATURE_SOC_SPI_COUNT] = {(spi_data_width_t)0}; + +/*! @brief Array to map SPI instance number to base address. */ +static const uint32_t s_spiBaseAddrs[FSL_FEATURE_SOC_SPI_COUNT] = SPI_BASE_ADDRS; + +/*! @brief IRQ name array */ +static const IRQn_Type s_spiIRQ[] = SPI_IRQS; + +/* @brief Array to map SPI instance number to CLOCK names */ +static const clock_ip_name_t s_spiClock[] = SPI_CLOCKS; + +/* @brief Array to map SPI reset. */ +static const SYSCON_RSTn_t s_spiReset[2] = {kSPI0_RST_SHIFT_RSTn, kSPI1_RST_SHIFT_RSTn}; + +/*! @brief Typedef for spi master interrupt handler. spi master and slave handle is the same. */ +typedef void (*spi_isr_t)(SPI_Type *base, spi_master_handle_t *spiHandle); + +/*! @brief Pointer to master IRQ handler for each instance. */ +static spi_isr_t s_spiMasterIsr; +static spi_isr_t s_spiSlaveIsr; + +/* @brief Dummy data for each instance. This data is used when user's tx buffer is NULL*/ +volatile uint8_t s_dummyData[FSL_FEATURE_SOC_SPI_COUNT] = {0}; +/******************************************************************************* + * Code + ******************************************************************************/ + +/* Get the index corresponding to the FLEXCOMM */ +uint32_t SPI_GetInstance(SPI_Type *base) +{ + assert(NULL != base); + + int i = 0U; + + for (i = 0; i < FSL_FEATURE_SOC_SPI_COUNT; i++) + { + if ((uint32_t)base == s_spiBaseAddrs[i]) + { + return i; + } + } + + assert(false); + return 0; +} + +void SPI_SetDummyData(SPI_Type *base, uint8_t dummyData) +{ + uint32_t instance = SPI_GetInstance(base); + s_dummyData[instance] = dummyData; +} + +/* Get the information of datawidth and SSEL number. */ +void *SPI_GetConfig(SPI_Type *base) +{ + int32_t instance = SPI_GetInstance(base); + + if (instance < 0) + { + return NULL; + } + return &g_configs[instance]; +} + +/* Get status flags from FIFO status register. */ +uint32_t SPI_GetFifoStatusFlags(SPI_Type *base) +{ + uint32_t instance = SPI_GetInstance(base); + return (VFIFO->SPI[instance].STATSPI); +} + +/* Clear status flags of FIFO status register. */ +void SPI_ClearFifoStatusFlags(SPI_Type *base, uint32_t mask) +{ + uint32_t instance = SPI_GetInstance(base); + VFIFO->SPI[instance].STATSPI |= mask; +} + +/* Enable FIFO interrupt from FIFO CTLSETSPI register. */ +void SPI_EnableFifoInterrupts(SPI_Type *base, uint32_t irqs) +{ + uint32_t instance = SPI_GetInstance(base); + VFIFO->SPI[instance].CTLSETSPI |= irqs; +} + +/* Clear FIFO interrupt from FIFO CTLCLRSPI register. */ +void SPI_DisableFifoInterrupts(SPI_Type *base, uint32_t irqs) +{ + uint32_t instance = SPI_GetInstance(base); + VFIFO->SPI[instance].CTLCLRSPI |= irqs; +} + +/* Flush the FIFO for SPI transfer. */ +void SPI_FifoFlush(SPI_Type *base, uint32_t direction) +{ + uint32_t instance = SPI_GetInstance(base); + + if (kSPI_FifoTx & direction) + { + VFIFO->SPI[instance].CTLSETSPI |= VFIFO_SPI_CTLSETSPI_TXFLUSH_MASK; + VFIFO->SPI[instance].CTLCLRSPI |= VFIFO_SPI_CTLCLRSPI_TXFLUSHCLR_MASK; + } + + if (kSPI_FifoRx & direction) + { + VFIFO->SPI[instance].CTLSETSPI |= VFIFO_SPI_CTLSETSPI_RXFLUSH_MASK; + VFIFO->SPI[instance].CTLCLRSPI |= VFIFO_SPI_CTLCLRSPI_RXFLUSHCLR_MASK; + } +} + +/* Enable SPI FIFO function. */ +void SPI_EnableFifo(SPI_Type *base, const spi_fifo_config_t *config) +{ + uint32_t instance = 0U; + assert((config->enableRxFifo) || (config->enableTxFifo)); + + instance = SPI_GetInstance(base); + + /* Enable the system FIFO clock. */ + CLOCK_EnableClock(kCLOCK_Fifo); + + /* Configure the FIFOCTRL register to enable the SPI TX/RX FIFO . */ + switch (instance) + { + case 0: + SYSCON->FIFOCTRL &= ~(SYSCON_FIFOCTRL_SPI0TXFIFOEN_MASK | SYSCON_FIFOCTRL_SPI0RXFIFOEN_MASK); + SYSCON->FIFOCTRL |= + SYSCON_FIFOCTRL_SPI0TXFIFOEN(config->enableTxFifo) | SYSCON_FIFOCTRL_SPI0RXFIFOEN(config->enableRxFifo); + break; + case 1: + SYSCON->FIFOCTRL &= ~(SYSCON_FIFOCTRL_SPI1TXFIFOEN_MASK | SYSCON_FIFOCTRL_SPI1RXFIFOEN_MASK); + SYSCON->FIFOCTRL |= + SYSCON_FIFOCTRL_SPI1TXFIFOEN(config->enableTxFifo) | SYSCON_FIFOCTRL_SPI1RXFIFOEN(config->enableRxFifo); + break; + default: + break; + } + /* Pause the SPI FIFO for setting. */ + while ( + !((VFIFO->FIFOCTLSPI & VFIFO_FIFOCTLSPI_RXPAUSED_MASK) && (VFIFO->FIFOCTLSPI & VFIFO_FIFOCTLSPI_TXPAUSED_MASK))) + { + VFIFO->FIFOCTLSPI |= (VFIFO_FIFOCTLSPI_RXPAUSE_MASK | VFIFO_FIFOCTLSPI_TXPAUSE_MASK); + } + /* Flush the TX and RX FIFO buffer. */ + SPI_FifoFlush(base, kSPI_FifoTx | kSPI_FifoRx); + /* Set the TX and RX FIFO size. */ + VFIFO->FIFOCFGSPI[instance] = + VFIFO_FIFOCFGSPI_RXSIZE(config->rxFifoSize) | VFIFO_FIFOCFGSPI_TXSIZE(config->txFifoSize); + /* Update all the SPI FIFO size. */ + VFIFO->FIFOUPDATESPI |= VFIFO_FIFOUPDATESPI_SPI0RXUPDATESIZE_MASK | VFIFO_FIFOUPDATESPI_SPI0TXUPDATESIZE_MASK | + VFIFO_FIFOUPDATESPI_SPI1RXUPDATESIZE_MASK | VFIFO_FIFOUPDATESPI_SPI1TXUPDATESIZE_MASK; + /* Set the TX and RX FIFO threshold size. */ + VFIFO->SPI[instance].CFGSPI &= ~(VFIFO_SPI_CFGSPI_RXTHRESHOLD_MASK | VFIFO_SPI_CFGSPI_TXTHRESHOLD_MASK); + VFIFO->SPI[instance].CFGSPI |= + VFIFO_SPI_CFGSPI_RXTHRESHOLD(config->rxFifoThreshold) | VFIFO_SPI_CFGSPI_TXTHRESHOLD(config->txFifoThreshold); + /* Unpause the system FIFO for transfer. */ + VFIFO->FIFOCTLSPI &= ~(VFIFO_FIFOCTLSPI_RXPAUSE_MASK | VFIFO_FIFOCTLSPI_TXPAUSE_MASK); +} + +/* Disable system FIFO. */ +void SPI_DisableFifo(SPI_Type *base) +{ + assert(NULL != base); + uint32_t instance = SPI_GetInstance(base); + + /* Pause the SPI FIFO for setting. */ + while ( + !((VFIFO->FIFOCTLSPI & VFIFO_FIFOCTLSPI_RXPAUSED_MASK) && (VFIFO->FIFOCTLSPI & VFIFO_FIFOCTLSPI_TXPAUSED_MASK))) + { + VFIFO->FIFOCTLSPI |= (VFIFO_FIFOCTLSPI_RXPAUSE_MASK | VFIFO_FIFOCTLSPI_TXPAUSE_MASK); + } + + /* Flush the TX and RX FIFO buffer. */ + SPI_FifoFlush(base, kSPI_FifoTx | kSPI_FifoRx); + /* Set the TX and RX FIFO size to zero. */ + VFIFO->FIFOCFGSPI[instance] = VFIFO_FIFOCFGSPI_RXSIZE(0U) | VFIFO_FIFOCFGSPI_TXSIZE(0U); + /* Update all the SPI FIFO size. */ + VFIFO->FIFOUPDATESPI |= VFIFO_FIFOUPDATESPI_SPI0RXUPDATESIZE_MASK | VFIFO_FIFOUPDATESPI_SPI0TXUPDATESIZE_MASK | + VFIFO_FIFOUPDATESPI_SPI1RXUPDATESIZE_MASK | VFIFO_FIFOUPDATESPI_SPI1TXUPDATESIZE_MASK; + /* Disable all FIFO interrupts. */ + SPI_DisableFifoInterrupts(base, kSPI_AllFifoInterruptEnable); + /* Clear all FIFO status flags, only receive timeout and bus error flag can be cleared. */ + SPI_ClearFifoStatusFlags(base, kSPI_RxFifoTimeOutFlag | kSPI_FifoBusErrorFlag); + /* Unpause the system FIFO for transfer. */ + VFIFO->FIFOCTLSPI &= ~(VFIFO_FIFOCTLSPI_RXPAUSE_MASK | VFIFO_FIFOCTLSPI_TXPAUSE_MASK); + + /* Disable the TX/RX FIFO for tansfer. */ + switch (instance) + { + case 0: + SYSCON->FIFOCTRL &= ~(SYSCON_FIFOCTRL_SPI0TXFIFOEN_MASK | SYSCON_FIFOCTRL_SPI0RXFIFOEN_MASK); + break; + case 1: + SYSCON->FIFOCTRL &= ~(SYSCON_FIFOCTRL_SPI1TXFIFOEN_MASK | SYSCON_FIFOCTRL_SPI1RXFIFOEN_MASK); + break; + default: + break; + } +} +/* Check if TX FIFO enabled. */ +bool SPI_IsTxFifoEnabled(SPI_Type *base) +{ + uint32_t instance = SPI_GetInstance(base); + uint32_t fifosize = VFIFO->FIFOCFGSPI[instance]; + + /* Check if system FIFO control TX is enabled. */ + switch (instance) + { + case 0: + if (SYSCON->FIFOCTRL & SYSCON_FIFOCTRL_SPI0TXFIFOEN_MASK) + { + break; + } + else + { + return false; + } + case 1: + if (SYSCON->FIFOCTRL & SYSCON_FIFOCTRL_SPI1TXFIFOEN_MASK) + { + break; + } + else + { + return false; + } + default: + break; + } + + /* Check if TX FIFO size is available. */ + return (fifosize & VFIFO_FIFOCFGSPI_TXSIZE_MASK) ? (true) : (false); +} + +/* Check if RX FIFO enabled. */ +bool SPI_IsRxFifoEnabled(SPI_Type *base) +{ + uint32_t instance = SPI_GetInstance(base); + uint32_t fifosize = VFIFO->FIFOCFGSPI[instance]; + + /* Check if system FIFO control RX is enabled. */ + switch (instance) + { + case 0: + if (SYSCON->FIFOCTRL & SYSCON_FIFOCTRL_SPI0RXFIFOEN_MASK) + { + break; + } + else + { + return false; + } + case 1: + if (SYSCON->FIFOCTRL & SYSCON_FIFOCTRL_SPI1RXFIFOEN_MASK) + { + break; + } + else + { + return false; + } + default: + break; + } + + /* Check if RX FIFO size is available. */ + return (fifosize & VFIFO_FIFOCFGSPI_RXSIZE_MASK) ? (true) : (false); +} + +static void SPI_SendTransfer(SPI_Type *base, spi_master_handle_t *handle) +{ + uint32_t tx_ctrl = 0U, last_ctrl = 0U; + uint32_t tmp32 = 0U; + uint32_t instance = SPI_GetInstance(base); + + /* Select slave to talk with */ + tx_ctrl |= (SPI_DEASSERT_ALL & (~SPI_DEASSERT_SSELNUM(g_configs[instance].sselNum))); + /* Set width of data - range asserted at entry */ + tx_ctrl |= SPI_TXDATCTL_LEN(handle->dataWidth); + /* If the control flag is different with configuration. */ + if (handle->configFlags != + (base->TXCTL & SPI_TXDATCTL_RXIGNORE_MASK & SPI_TXDATCTL_EOT_MASK & SPI_TXDATCTL_EOF_MASK)) + { + /* Delay end of frame.*/ + tx_ctrl |= (handle->configFlags & (uint32_t)kSPI_FrameDelay) ? (uint32_t)kSPI_FrameDelay : 0; + /* Ignore the receive.*/ + tx_ctrl |= (handle->configFlags & SPI_TXDATCTL_RXIGNORE_MASK); + } + last_ctrl = tx_ctrl; + if (handle->configFlags & SPI_TXDATCTL_EOT_MASK) + { + last_ctrl |= SPI_TXDATCTL_EOT_MASK; + } + + if (handle->isTxFifoEnabled) + { + /* Fill data to tx fifo buffer until the tx threshold reached flag cleard. */ + while ((VFIFO->SPI[instance].STATSPI & VFIFO_SPI_STATSPI_TXTH_MASK) && (handle->txRemainingBytes)) + { + if (handle->txData) + { + tmp32 = *(handle->txData++); + handle->txRemainingBytes--; + if (handle->dataWidth > 7U) + { + tmp32 |= ((uint32_t)(*(handle->txData++)) << 8U); + handle->txRemainingBytes--; + } + } + else + { + tmp32 = ((uint32_t)s_dummyData[instance] << 8U) | s_dummyData[instance]; + handle->txRemainingBytes--; + if (handle->dataWidth > 7U) + { + handle->txRemainingBytes--; + } + } + /* If this transmit is the last to send, Set the control bits and disable Tx interrupt. */ + if (handle->txRemainingBytes == 0U) + { + VFIFO->SPI[instance].TXDATSPI = (tmp32 | last_ctrl); + SPI_DisableFifoInterrupts(base, kSPI_TxFifoThresholdInterruptEnable); + } + else + { + VFIFO->SPI[instance].TXDATSPI = (tmp32 | tx_ctrl); + } + } + } + else + { + /* If transmit is ready, write data once to TXDATCTL register. */ + if ((kSPI_TxReadyFlag & SPI_GetStatusFlags(base)) && (handle->txRemainingBytes)) + { + if (handle->txData) + { + tmp32 = *(handle->txData++); + handle->txRemainingBytes--; + if (handle->dataWidth > 7U) + { + tmp32 |= ((uint32_t)(*(handle->txData++)) << 8U); + handle->txRemainingBytes--; + } + } + else + { + tmp32 = ((uint32_t)s_dummyData[instance] << 8U) | s_dummyData[instance]; + handle->txRemainingBytes--; + if (handle->dataWidth > 7U) + { + handle->txRemainingBytes--; + } + } + /* If this transmit is the last to send, Set the control bits and disable Tx interrupt. */ + if (handle->txRemainingBytes == 0U) + { + base->TXDATCTL = (tmp32 | last_ctrl); + SPI_DisableInterrupts(base, kSPI_TxReadyInterruptEnable); + } + base->TXDATCTL = (tmp32 | tx_ctrl); + } + } +} + +static void SPI_ReceiveTransfer(SPI_Type *base, spi_master_handle_t *handle) +{ + uint32_t tmp32 = 0U; + uint32_t instance = SPI_GetInstance(base); + + if (handle->isRxFifoEnabled) + { + /* Read data from fifo buffer until the rx fifo is empty or to receive bytes is zero. */ + while ((!(VFIFO->SPI[instance].STATSPI & VFIFO_SPI_STATSPI_RXEMPTY_MASK)) && (handle->rxRemainingBytes)) + { + tmp32 = VFIFO->SPI[instance].RXDATSPI; + /* Check If receive buffer is NULL. */ + if (handle->rxData) + { + *(handle->rxData++) = tmp32; + if (handle->dataWidth > 7U) + { + *(handle->rxData++) = (tmp32 >> 8U); + } + } + handle->rxRemainingBytes--; + if (handle->dataWidth > 7U) + { + handle->rxRemainingBytes--; + } + } + } + else + { + /* If receive is ready, read data from RXDAT register. */ + if ((kSPI_RxReadyFlag & SPI_GetStatusFlags(base)) && (handle->rxRemainingBytes)) + { + tmp32 = (base->RXDAT & 0x0000FFFFU); + /* Check If receive buffer is NULL. */ + if (handle->rxData) + { + *(handle->rxData++) = tmp32; + if (handle->dataWidth > 7U) + { + *(handle->rxData++) = (tmp32 >> 8U); + } + } + handle->rxRemainingBytes--; + if (handle->dataWidth > 7U) + { + handle->rxRemainingBytes--; + } + } + } +} + +/* Set delay time for SPI transfer. */ +void SPI_SetTransferDelay(SPI_Type *base, const spi_delay_config_t *config) +{ + assert(NULL != config); + /* Clear the DLY register. */ + base->DLY &= + ~(SPI_DLY_PRE_DELAY_MASK | SPI_DLY_POST_DELAY_MASK | SPI_DLY_FRAME_DELAY_MASK | SPI_DLY_TRANSFER_DELAY_MASK); + /* Set the delay configuration. */ + base->DLY |= (SPI_DLY_PRE_DELAY(config->preDelay) | SPI_DLY_POST_DELAY(config->postDelay) | + SPI_DLY_FRAME_DELAY(config->frameDelay) | SPI_DLY_TRANSFER_DELAY(config->transferDelay)); +} +void SPI_MasterGetDefaultConfig(spi_master_config_t *config) +{ + assert(NULL != config); + + config->enableLoopback = false; + config->enableMaster = true; + config->polarity = kSPI_ClockPolarityActiveHigh; + config->phase = kSPI_ClockPhaseFirstEdge; + config->direction = kSPI_MsbFirst; + config->baudRate_Bps = 500000U; + config->dataWidth = kSPI_Data8Bits; + config->sselNum = kSPI_Ssel0; + config->sselPol = kSPI_SpolActiveAllLow; + config->fifoConfig.enableRxFifo = false; + config->fifoConfig.enableTxFifo = false; + config->fifoConfig.rxFifoSize = 8U; + config->fifoConfig.txFifoSize = 8U; + config->fifoConfig.rxFifoThreshold = 0U; + config->fifoConfig.txFifoThreshold = 1U; + config->delayConfig.frameDelay = 0U; + config->delayConfig.postDelay = 0U; + config->delayConfig.preDelay = 0U; + config->delayConfig.transferDelay = 0U; +} + +status_t SPI_MasterInit(SPI_Type *base, const spi_master_config_t *config, uint32_t srcClock_Hz) +{ + int32_t result = 0, instance = 0; + uint32_t tmp = 0U; + + /* assert params */ + assert(!((NULL == base) || (NULL == config) || (0 == srcClock_Hz))); + if ((NULL == base) || (NULL == config) || (0 == srcClock_Hz)) + { + return kStatus_InvalidArgument; + } + + /* Get instance number */ + instance = SPI_GetInstance(base); + assert(instance >= 0); + + /* Config FIFOs if the system FIFO is enabled. + * Note: The FIFO should be enabled before the baudrate has been configured. + */ + if ((config->fifoConfig.enableRxFifo) || (config->fifoConfig.enableTxFifo)) + { + SPI_EnableFifo(base, &(config->fifoConfig)); + } + + /* Enable clock. */ + CLOCK_EnableClock(s_spiClock[instance]); + /* Reset spi periphera. */ + RESET_PeripheralReset(s_spiReset[instance]); + + /* set divider */ + result = SPI_MasterSetBaud(base, config->baudRate_Bps, srcClock_Hz); + if (kStatus_Success != result) + { + return result; + } + + /* configure SPI mode */ + tmp &= ~(SPI_CFG_MASTER_MASK | SPI_CFG_LSBF_MASK | SPI_CFG_CPHA_MASK | SPI_CFG_CPOL_MASK | SPI_CFG_LOOP_MASK | + SPI_CFG_ENABLE_MASK | SPI_SSELPOL_MASK); + /* phase */ + tmp |= SPI_CFG_CPHA(config->phase); + /* polarity */ + tmp |= SPI_CFG_CPOL(config->polarity); + /* direction */ + tmp |= SPI_CFG_LSBF(config->direction); + /* master mode */ + tmp |= SPI_CFG_MASTER(1); + /* loopback */ + tmp |= SPI_CFG_LOOP(config->enableLoopback); + /* configure active level for all CS */ + tmp |= ((uint32_t)config->sselPol & (SPI_SSELPOL_MASK)); + base->CFG = tmp; + + /* Set delay configuration. */ + SPI_SetTransferDelay(base, &(config->delayConfig)); + + /* store configuration */ + g_configs[instance].dataWidth = config->dataWidth; + g_configs[instance].sselNum = config->sselNum; + + SPI_SetDummyData(base, (uint8_t)SPI_DUMMYDATA); + + /* Enable the SPI module. */ + SPI_Enable(base, config->enableMaster); + return kStatus_Success; +} + +void SPI_SlaveGetDefaultConfig(spi_slave_config_t *config) +{ + assert(NULL != config); + + config->enableSlave = true; + config->polarity = kSPI_ClockPolarityActiveHigh; + config->phase = kSPI_ClockPhaseFirstEdge; + config->direction = kSPI_MsbFirst; + config->dataWidth = kSPI_Data8Bits; + config->sselPol = kSPI_SpolActiveAllLow; + config->fifoConfig.enableRxFifo = false; + config->fifoConfig.enableTxFifo = false; + config->fifoConfig.rxFifoSize = 8U; + config->fifoConfig.txFifoSize = 8U; + config->fifoConfig.rxFifoThreshold = 0U; + config->fifoConfig.txFifoThreshold = 0U; +} + +status_t SPI_SlaveInit(SPI_Type *base, const spi_slave_config_t *config) +{ + int32_t instance = 0U; + uint32_t tmp = 0U; + + /* assert params */ + assert(!((NULL == base) || (NULL == config))); + if ((NULL == base) || (NULL == config)) + { + return kStatus_InvalidArgument; + } + + /* Get the instance of SPI. */ + instance = SPI_GetInstance(base); + + /* Config FIFOs if the system FIFO is enabled. */ + if ((config->fifoConfig.enableRxFifo) || (config->fifoConfig.enableTxFifo)) + { + SPI_EnableFifo(base, &(config->fifoConfig)); + } + + /* Enable clock. */ + CLOCK_EnableClock(s_spiClock[instance]); + /* Reset spi periphera. */ + RESET_PeripheralReset(s_spiReset[instance]); + + /* configure SPI mode */ + tmp &= ~(SPI_CFG_MASTER_MASK | SPI_CFG_LSBF_MASK | SPI_CFG_CPHA_MASK | SPI_CFG_CPOL_MASK | SPI_CFG_ENABLE_MASK | + SPI_SSELPOL_MASK); + /* phase */ + tmp |= SPI_CFG_CPHA(config->phase); + /* polarity */ + tmp |= SPI_CFG_CPOL(config->polarity); + /* direction */ + tmp |= SPI_CFG_LSBF(config->direction); + /* configure active level for all CS */ + tmp |= ((uint32_t)config->sselPol & (SPI_SSELPOL_MASK)); + base->CFG = tmp; + + /* store configuration */ + g_configs[instance].dataWidth = config->dataWidth; + + SPI_SetDummyData(base, (uint8_t)SPI_DUMMYDATA); + + /* Enable the SPI module. */ + SPI_Enable(base, config->enableSlave); + return kStatus_Success; +} + +void SPI_Deinit(SPI_Type *base) +{ + /* Assert arguments */ + assert(NULL != base); + uint32_t instance = SPI_GetInstance(base); + + /* Disable FIFO if enabled. */ + if ((SPI_IsTxFifoEnabled(base)) || (SPI_IsTxFifoEnabled(base))) + { + SPI_DisableFifo(base); + } + + /* Disable SPI module before shutting down the clock. */ + SPI_Enable(base, false); + /* Disable clock. */ + CLOCK_DisableClock(s_spiClock[instance]); +} + +status_t SPI_MasterSetBaud(SPI_Type *base, uint32_t baudrate_Bps, uint32_t srcClock_Hz) +{ + uint32_t tmp; + + /* assert params */ + assert(!((NULL == base) || (0 == baudrate_Bps) || (0 == srcClock_Hz))); + if ((NULL == base) || (0 == baudrate_Bps) || (0 == srcClock_Hz)) + { + return kStatus_InvalidArgument; + } + + /* calculate baudrate */ + tmp = (srcClock_Hz / baudrate_Bps) - 1; + if (tmp > 0xFFFF) + { + return kStatus_SPI_BaudrateNotSupport; + } + base->DIV &= ~SPI_DIV_DIVVAL_MASK; + base->DIV |= SPI_DIV_DIVVAL(tmp); + return kStatus_Success; +} + +void SPI_WriteData(SPI_Type *base, uint16_t data, uint32_t configFlags) +{ + uint32_t control = 0; + int32_t instance; + + /* check params */ + assert(NULL != base); + /* get and check instance */ + instance = SPI_GetInstance(base); + assert(!(instance < 0)); + if (instance < 0) + { + return; + } + + /* Set data width */ + control |= SPI_TXDATCTL_LEN(g_configs[instance].dataWidth); + /* Set sssel */ + control |= (SPI_DEASSERT_ALL & (~SPI_DEASSERT_SSELNUM(g_configs[instance].sselNum))); + /* Mask configFlags */ + control |= (configFlags & (SPI_TXDATCTL_EOT_MASK | SPI_TXDATCTL_EOF_MASK | SPI_TXDATCTL_RXIGNORE_MASK)); + /* Control should not affect lower 16 bits */ + assert(!(control & 0xFFFF)); + + if (SPI_IsTxFifoEnabled(base)) + { + VFIFO->SPI[instance].TXDATSPI = data | control; + } + else + { + base->TXDATCTL = (data | control); + } +} + +uint32_t SPI_ReadData(SPI_Type *base) +{ + assert(NULL != base); + uint32_t instance = SPI_GetInstance(base); + + if (SPI_IsRxFifoEnabled(base)) + { + return (VFIFO->SPI[instance].RXDATSPI); + } + else + { + return (base->RXDAT & 0x0000FFFFU); + } +} +status_t SPI_MasterTransferCreateHandle(SPI_Type *base, + spi_master_handle_t *handle, + spi_master_callback_t callback, + void *userData) +{ + int32_t instance = 0; + + /* check 'base' */ + assert(!(NULL == base)); + if (NULL == base) + { + return kStatus_InvalidArgument; + } + /* check 'handle' */ + assert(!(NULL == handle)); + if (NULL == handle) + { + return kStatus_InvalidArgument; + } + /* Get SPI instance by 'base' param */ + instance = SPI_GetInstance(base); + if (instance < 0) + { + return kStatus_InvalidArgument; + } + + memset(handle, 0, sizeof(*handle)); + + handle->dataWidth = g_configs[instance].dataWidth; + /* in slave mode, the sselNum is not important */ + handle->sselNum = g_configs[instance].sselNum; + handle->isRxFifoEnabled = SPI_IsRxFifoEnabled(base); + handle->isTxFifoEnabled = SPI_IsTxFifoEnabled(base); + handle->rxFifoThreshold = SPI_FIFO_GETRXTHRESHOLD(base); + handle->txFifoThreshold = SPI_FIFO_GETTXTHRESHOLD(base); + handle->callback = callback; + handle->userData = userData; + + s_spiHandle[instance] = handle; + s_spiMasterIsr = SPI_MasterTransferHandleIRQ; + /* Enable SPI NVIC */ + EnableIRQ(s_spiIRQ[instance]); + + return kStatus_Success; +} + +status_t SPI_SlaveTransferCreateHandle(SPI_Type *base, + spi_slave_handle_t *handle, + spi_slave_callback_t callback, + void *userData) +{ + SPI_MasterTransferCreateHandle(base, handle, callback, userData); + s_spiSlaveIsr = SPI_SlaveTransferHandleIRQ; + return kStatus_Success; +} + +status_t SPI_MasterTransferBlocking(SPI_Type *base, spi_transfer_t *xfer) +{ + int32_t instance; + uint32_t tx_ctrl = 0, last_ctrl = 0; + uint32_t tmp32, remainingBytes, dataWidth; + bool isTxFifoEnabled = SPI_IsTxFifoEnabled(base); + bool isRxFifoEnabled = SPI_IsRxFifoEnabled(base); + + /* Check params */ + assert(!((NULL == base) || (NULL == xfer) || ((NULL == xfer->txData) && (NULL == xfer->rxData)))); + if ((NULL == base) || (NULL == xfer) || ((NULL == xfer->txData) && (NULL == xfer->rxData))) + { + return kStatus_InvalidArgument; + } + remainingBytes = xfer->dataSize; + + instance = SPI_GetInstance(base); + assert(instance >= 0); + dataWidth = g_configs[instance].dataWidth; + + /* DataSize (in bytes) is not aligned to 16bit (2B) transfer */ + if ((dataWidth > kSPI_Data8Bits) && (xfer->dataSize & 0x1)) + { + return kStatus_InvalidArgument; + } + + /* Select slave to talk with */ + tx_ctrl |= (SPI_DEASSERT_ALL & (~SPI_DEASSERT_SSELNUM(g_configs[instance].sselNum))); + /* Set width of data - range asserted at entry */ + tx_ctrl |= SPI_TXDATCTL_LEN(dataWidth); + /* Delay end of transfer */ + tx_ctrl |= (xfer->configFlags & (uint32_t)kSPI_FrameDelay) ? (uint32_t)kSPI_FrameDelay : 0; + /* Ignore the receive.*/ + tx_ctrl |= (xfer->configFlags & SPI_TXDATCTL_RXIGNORE_MASK); + + last_ctrl = tx_ctrl; + /* End of transfer */ + last_ctrl |= (xfer->configFlags & (uint32_t)kSPI_FrameAssert) ? (uint32_t)kSPI_FrameAssert : 0; + + if (!isTxFifoEnabled) + { + base->TXCTL = tx_ctrl; + } + + /* Last index of loop */ + while (remainingBytes) + { + tmp32 = 0U; + /* Wait for Transmit is ready. */ + if (isTxFifoEnabled) + { + while (!(VFIFO->SPI[instance].STATSPI & VFIFO_SPI_STATSPI_TXEMPTY_MASK)) + { + } + } + else + { + while (!(base->STAT & SPI_STAT_TXRDY_MASK)) + { + } + } + /* If txdata is not NULL. */ + if (xfer->txData) + { + tmp32 = *(xfer->txData++); + if (dataWidth > 7U) + { + tmp32 |= ((uint32_t)(*(xfer->txData++))) << 8U; + } + } + else + { + tmp32 = ((uint32_t)s_dummyData[instance] << 8U) | s_dummyData[instance]; + } + if ((dataWidth > 7) ? (remainingBytes == 2U) : (remainingBytes == 1U)) + { + if (isTxFifoEnabled) + { + VFIFO->SPI[instance].TXDATSPI = (tmp32 | last_ctrl); + } + else + { + base->TXDATCTL = (tmp32 | last_ctrl); + } + } + else + { + if (isTxFifoEnabled) + { + VFIFO->SPI[instance].TXDATSPI = (tmp32 | tx_ctrl); + } + else + { + /* Write data to the Transmit register. */ + base->TXDAT = tmp32; + } + } + + /* Read data from the receive register. */ + if (isRxFifoEnabled) + { + while ((VFIFO->SPI[instance].STATSPI & VFIFO_SPI_STATSPI_RXEMPTY_MASK)) + { + } + tmp32 = VFIFO->SPI[instance].RXDATSPI; + } + else + { + while (!(base->STAT & SPI_STAT_RXRDY_MASK)) + { + } + tmp32 = base->RXDAT; + } + /* If receive buffer is NULL. */ + if (xfer->rxData) + { + *(xfer->rxData++) = tmp32; + if (dataWidth > 7U) + { + *(xfer->rxData++) = (tmp32 >> 8U); + } + } + + remainingBytes--; + if (dataWidth > 7U) + { + remainingBytes--; + } + } + + return kStatus_Success; +} + +status_t SPI_MasterTransferNonBlocking(SPI_Type *base, spi_master_handle_t *handle, spi_transfer_t *xfer) +{ + /* check params */ + assert( + !((NULL == base) || (NULL == handle) || (NULL == xfer) || ((NULL == xfer->txData) && (NULL == xfer->rxData)))); + if ((NULL == base) || (NULL == handle) || (NULL == xfer) || ((NULL == xfer->txData) && (NULL == xfer->rxData))) + { + return kStatus_InvalidArgument; + } + + /* dataSize (in bytes) is not aligned to 16bit (2B) transfer */ + if ((handle->dataWidth > kSPI_Data8Bits) && (xfer->dataSize & 0x1)) + { + return kStatus_InvalidArgument; + } + + /* Check if SPI is busy */ + if (handle->state == kStatus_SPI_Busy) + { + return kStatus_SPI_Busy; + } + + /* Set the handle information */ + handle->txData = xfer->txData; + handle->rxData = xfer->rxData; + /* Set count */ + handle->txRemainingBytes = xfer->dataSize; + handle->rxRemainingBytes = xfer->dataSize; + handle->totalByteCount = xfer->dataSize; + /* Other options */ + handle->configFlags = xfer->configFlags; + /* Set the SPI state to busy */ + handle->state = kStatus_SPI_Busy; + /* FIFO options. */ + if (SPI_IsTxFifoEnabled(base)) + { + SPI_EnableFifoInterrupts(base, kSPI_TxFifoThresholdInterruptEnable); + } + else + { + /* Enable generating txIRQ, first transfer is fired by TX ready interrupt. */ + SPI_EnableInterrupts(base, kSPI_TxReadyInterruptEnable); + } + if (SPI_IsRxFifoEnabled(base)) + { + SPI_EnableFifoInterrupts(base, kSPI_RxFifoThresholdInterruptEnable); + } + else + { + /* Enable generating rxIRQ. */ + SPI_EnableInterrupts(base, kSPI_RxReadyInterruptEnable); + } + return kStatus_Success; +} + +status_t SPI_MasterHalfDuplexTransferBlocking(SPI_Type *base, spi_half_duplex_transfer_t *xfer) +{ + assert(xfer); + + spi_transfer_t tempXfer = {0}; + status_t status; + + if (xfer->isTransmitFirst) + { + tempXfer.txData = xfer->txData; + tempXfer.rxData = NULL; + tempXfer.dataSize = xfer->txDataSize; + } + else + { + tempXfer.txData = NULL; + tempXfer.rxData = xfer->rxData; + tempXfer.dataSize = xfer->rxDataSize; + } + /* If the pcs pin keep assert between transmit and receive. */ + if (xfer->isPcsAssertInTransfer) + { + tempXfer.configFlags = (xfer->configFlags) & (uint32_t)(~kSPI_FrameAssert); + } + else + { + tempXfer.configFlags = (xfer->configFlags) | kSPI_FrameAssert; + } + + status = SPI_MasterTransferBlocking(base, &tempXfer); + + if (status != kStatus_Success) + { + return status; + } + + if (xfer->isTransmitFirst) + { + tempXfer.txData = NULL; + tempXfer.rxData = xfer->rxData; + tempXfer.dataSize = xfer->rxDataSize; + } + else + { + tempXfer.txData = xfer->txData; + tempXfer.rxData = NULL; + tempXfer.dataSize = xfer->txDataSize; + } + tempXfer.configFlags = xfer->configFlags; + + /* SPI transfer blocking. */ + status = SPI_MasterTransferBlocking(base, &tempXfer); + + return status; +} + +status_t SPI_MasterHalfDuplexTransferNonBlocking(SPI_Type *base, + spi_master_handle_t *handle, + spi_half_duplex_transfer_t *xfer) +{ + assert(xfer); + assert(handle); + spi_transfer_t tempXfer = {0}; + status_t status; + + if (xfer->isTransmitFirst) + { + tempXfer.txData = xfer->txData; + tempXfer.rxData = NULL; + tempXfer.dataSize = xfer->txDataSize; + } + else + { + tempXfer.txData = NULL; + tempXfer.rxData = xfer->rxData; + tempXfer.dataSize = xfer->rxDataSize; + } + /* If the pcs pin keep assert between transmit and receive. */ + if (xfer->isPcsAssertInTransfer) + { + tempXfer.configFlags = (xfer->configFlags) & (uint32_t)(~kSPI_FrameAssert); + } + else + { + tempXfer.configFlags = (xfer->configFlags) | kSPI_FrameAssert; + } + + status = SPI_MasterTransferBlocking(base, &tempXfer); + if (status != kStatus_Success) + { + return status; + } + + if (xfer->isTransmitFirst) + { + tempXfer.txData = NULL; + tempXfer.rxData = xfer->rxData; + tempXfer.dataSize = xfer->rxDataSize; + } + else + { + tempXfer.txData = xfer->txData; + tempXfer.rxData = NULL; + tempXfer.dataSize = xfer->txDataSize; + } + tempXfer.configFlags = xfer->configFlags; + + status = SPI_MasterTransferNonBlocking(base, handle, &tempXfer); + + return status; +} + +status_t SPI_SlaveTransferNonBlocking(SPI_Type *base, spi_slave_handle_t *handle, spi_transfer_t *xfer) +{ + status_t status = 0U; + + status = SPI_MasterTransferNonBlocking(base, handle, xfer); + if (kStatus_Success != status) + { + return status; + } + s_spiSlaveIsr = SPI_SlaveTransferHandleIRQ; + + return kStatus_Success; +} +status_t SPI_MasterTransferGetCount(SPI_Type *base, spi_master_handle_t *handle, size_t *count) +{ + assert(NULL != handle); + + if (!count) + { + return kStatus_InvalidArgument; + } + + /* Catch when there is not an active transfer. */ + if (handle->state != kStatus_SPI_Busy) + { + *count = 0; + return kStatus_NoTransferInProgress; + } + + *count = handle->totalByteCount - handle->rxRemainingBytes; + return kStatus_Success; +} + +void SPI_MasterTransferAbort(SPI_Type *base, spi_master_handle_t *handle) +{ + assert(NULL != handle); + + /* Disable interrupt requests*/ + if (SPI_IsTxFifoEnabled(base)) + { + SPI_DisableFifoInterrupts(base, kSPI_TxFifoThresholdInterruptEnable); + } + else + { + SPI_DisableInterrupts(base, kSPI_TxReadyInterruptEnable); + } + if (SPI_IsRxFifoEnabled(base)) + { + SPI_DisableFifoInterrupts(base, kSPI_RxFifoThresholdInterruptEnable); + } + else + { + SPI_DisableInterrupts(base, kSPI_RxReadyInterruptEnable); + } + + handle->state = kStatus_SPI_Idle; + handle->txRemainingBytes = 0; + handle->rxRemainingBytes = 0; +} + +void SPI_MasterTransferHandleIRQ(SPI_Type *base, spi_master_handle_t *handle) +{ + assert((NULL != base) && (NULL != handle)); + uint32_t instance = SPI_GetInstance(base); + + /* IRQ behaviour: + * - first interrupt is triggered by transmit ready interrupt or tx threshold reached if + * FIFO is enabled. The transfer function then tries read data and transmit data + * interleaved that results to strategy to process as many items as possible. + * - last interrupt is triggered by receive data ready. The last state is + * known by empty rxBuffer and txBuffer. If there is nothing to receive + * or send - both operations have been finished and interrupts can be disabled. + * - Note(case with the fifo used): Because the SPI0 and SPI1 share the same tx buffer and + * rx buffer, So the threshold interrupt may occured but the data in the buffer + * for SPIx may not reach the threshold separately if SPI0 and SPI1 are receiving + * data at the same time. The similar issue may happen when SPI0 and SPI1 are sending + * data at the same time with the FIFO used. + */ + + /* Data to send or read or expected to receive */ + if (handle->rxRemainingBytes) + { + SPI_ReceiveTransfer(base, handle); + } + if (handle->txRemainingBytes) + { + SPI_SendTransfer(base, handle); + } + if ((0U == handle->txRemainingBytes) && (0U == handle->rxRemainingBytes)) + { + if (SPI_IsRxFifoEnabled(base)) + { + SPI_EnableFifoInterrupts(base, kSPI_RxFifoThresholdInterruptEnable); + } + else + { + /* Disable TX and RX interrupt. */ + SPI_DisableInterrupts(base, kSPI_RxReadyInterruptEnable); + } + /* Set transfer state to idle. */ + handle->state = kStatus_SPI_Idle; + /* If callback is not NULL, call this function. */ + if (handle->callback) + { + (handle->callback)(base, handle, handle->state, handle->userData); + } + } + /* Check when the last receive, if the rx threshold can be triggered with the fifo enabled. */ + if (SPI_IsRxFifoEnabled(base)) + { + /* If the bytes to receive is not larger then the rx threshold, the interrupt will not be triggerred. + * So need to reload the rx threshold value to trigger the last receive. + */ + if ((handle->rxRemainingBytes != 0U) && (handle->rxRemainingBytes <= handle->rxFifoThreshold)) + { + VFIFO->SPI[instance].CFGSPI = ((VFIFO->SPI[instance].CFGSPI & ~VFIFO_SPI_CFGSPI_RXTHRESHOLD_MASK) | + VFIFO_SPI_CFGSPI_RXTHRESHOLD(handle->rxRemainingBytes - 1)); + } + /* If the rx threshold value in the register is not the default value in handle. Reload it to default value. */ + if ((handle->rxRemainingBytes == 0U) && (SPI_FIFO_GETRXTHRESHOLD(base) != handle->rxFifoThreshold)) + { + VFIFO->SPI[instance].CFGSPI = ((VFIFO->SPI[instance].CFGSPI & ~VFIFO_SPI_CFGSPI_RXTHRESHOLD_MASK) | + VFIFO_SPI_CFGSPI_RXTHRESHOLD(handle->rxFifoThreshold)); + } + } +} + +void SPI_SlaveTransferHandleIRQ(SPI_Type *base, spi_slave_handle_t *handle) +{ + assert((NULL != base) && (NULL != handle)); + uint32_t instance = SPI_GetInstance(base); + + /* IRQ behaviour: + * - first interrupt is triggered by transmit ready interrupt or tx threshold reached if + * FIFO is enabled. The transfer function then tries read data and transmit data + * interleaved that results to strategy to process as many items as possible. + * - last interrupt is triggered by receive data ready. The last state is + * known by empty rxBuffer and txBuffer. If there is nothing to receive + * or send - both operations have been finished and interrupts can be disabled. + * - Note(case with the fifo used): Because the SPI0 and SPI1 share the same tx buffer and + * rx buffer, So the threshold interrupt may occured but the data in the buffer + * for SPIx may not reach the threshold separately if SPI0 and SPI1 are receiving + * data at the same time. The similar issue may happen when SPI0 and SPI1 are sending + * data at the same time with the FIFO used. + */ + + /* Data to send or read or expected to receive */ + if (handle->rxRemainingBytes) + { + SPI_ReceiveTransfer(base, handle); + } + if (handle->txRemainingBytes) + { + SPI_SendTransfer(base, handle); + } + + if ((0U == handle->txRemainingBytes) && (0U == handle->rxRemainingBytes)) + { + if (SPI_IsRxFifoEnabled(base)) + { + SPI_EnableFifoInterrupts(base, kSPI_RxFifoThresholdInterruptEnable); + } + else + { + /* Disable TX and RX interrupt. */ + SPI_DisableInterrupts(base, kSPI_RxReadyInterruptEnable); + } + /* Set transfer state to idle. */ + handle->state = kStatus_SPI_Idle; + /* If callback is not NULL, call this function. */ + if (handle->callback) + { + (handle->callback)(base, handle, handle->state, handle->userData); + } + } + + /* Check when the last receive, if the rx threshold can be triggered with the fifo enabled. */ + if (SPI_IsRxFifoEnabled(base)) + { + /* If the bytes to receive is not larger then the rx threshold, the interrupt will not be triggerred. + * So need to reload the rx threshold value to trigger the last receive. + */ + if ((handle->rxRemainingBytes != 0U) && (handle->rxRemainingBytes <= handle->rxFifoThreshold)) + { + VFIFO->SPI[instance].CFGSPI = ((VFIFO->SPI[instance].CFGSPI & ~VFIFO_SPI_CFGSPI_RXTHRESHOLD_MASK) | + VFIFO_SPI_CFGSPI_RXTHRESHOLD(handle->rxRemainingBytes - 1)); + } + /* If the rx threshold value in the register is not the default value in handle. Reload it to default value. */ + if ((handle->rxRemainingBytes == 0U) && (SPI_FIFO_GETRXTHRESHOLD(base) != handle->rxFifoThreshold)) + { + VFIFO->SPI[instance].CFGSPI = ((VFIFO->SPI[instance].CFGSPI & ~VFIFO_SPI_CFGSPI_RXTHRESHOLD_MASK) | + VFIFO_SPI_CFGSPI_RXTHRESHOLD(handle->rxFifoThreshold)); + } + } +} + +static void SPI_CommonIRQHandler(SPI_Type *base, void *param) +{ + if (SPI_IsMaster(base)) + { + s_spiMasterIsr(base, (spi_master_handle_t *)param); + } + else + { + s_spiSlaveIsr(base, (spi_slave_handle_t *)param); + } +/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} + +#if defined(SPI0) +void SPI0_DriverIRQHandler(void) +{ + assert(s_spiHandle[0]); + SPI_CommonIRQHandler(SPI0, s_spiHandle[0]); +} +#endif + +#if defined(SPI1) +void SPI1_DriverIRQHandler(void) +{ + assert(s_spiHandle[1]); + SPI_CommonIRQHandler(SPI1, s_spiHandle[1]); +} +#endif diff --git a/platform/mcu/lpc54102/drivers/fsl_spi.h b/platform/mcu/lpc54102/drivers/fsl_spi.h new file mode 100644 index 0000000000..825640b014 --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_spi.h @@ -0,0 +1,833 @@ +/* + * Copyright (c) 2017, NXP Semiconductors, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_SPI_H_ +#define _FSL_SPI_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup spi_driver + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief USART driver version 2.0.0. */ +#define FSL_SPI_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*@}*/ + +#ifndef SPI_DUMMYDATA +/*! @brief SPI dummy transfer data, the data is sent while txBuff is NULL. */ +#define SPI_DUMMYDATA (0xFFU) +#endif + +#define SPI_ASSERT_SSELNUM(n) ((~(1U << ((n) + 16))) & 0xF0000) +#define SPI_DEASSERT_SSELNUM(n) (1U << ((n) + 16)) +#define SPI_DEASSERT_ALL (0xF0000) + +#define SPI_FIFO_GETRXTHRESHOLD(base) \ + ((SPI0 == base) ? \ + ((VFIFO->SPI[0].CFGSPI & VFIFO_SPI_CFGSPI_RXTHRESHOLD_MASK) >> VFIFO_SPI_CFGSPI_RXTHRESHOLD_SHIFT) : \ + ((VFIFO->SPI[1].CFGSPI & VFIFO_SPI_CFGSPI_RXTHRESHOLD_MASK) >> VFIFO_SPI_CFGSPI_RXTHRESHOLD_SHIFT)) +#define SPI_FIFO_GETTXTHRESHOLD(base) \ + ((SPI0 == base) ? \ + ((VFIFO->SPI[0].CFGSPI & VFIFO_SPI_CFGSPI_TXTHRESHOLD_MASK) >> VFIFO_SPI_CFGSPI_TXTHRESHOLD_SHIFT) : \ + ((VFIFO->SPI[1].CFGSPI & VFIFO_SPI_CFGSPI_TXTHRESHOLD_MASK) >> VFIFO_SPI_CFGSPI_TXTHRESHOLD_SHIFT)) + +/*! @brief SPI transfer option.*/ +typedef enum _spi_xfer_option +{ + kSPI_FrameDelay = (SPI_TXDATCTL_EOF_MASK), /*!< Delay chip select */ + kSPI_FrameAssert = (SPI_TXDATCTL_EOT_MASK), /*!< When transfer ends, assert chip select */ + kSPI_ReceiveIgnore = (SPI_TXDATCTL_RXIGNORE_MASK), /*!< Ignore the receive data. */ +} spi_xfer_option_t; + +/*! @brief SPI data shifter direction options.*/ +typedef enum _spi_shift_direction +{ + kSPI_MsbFirst = 0U, /*!< Data transfers start with most significant bit. */ + kSPI_LsbFirst = 1U, /*!< Data transfers start with least significant bit. */ +} spi_shift_direction_t; + +/*! @brief SPI clock polarity configuration.*/ +typedef enum _spi_clock_polarity +{ + kSPI_ClockPolarityActiveHigh = 0x0U, /*!< Active-high SPI clock (idles low). */ + kSPI_ClockPolarityActiveLow = 0x1U, /*!< Active-low SPI clock (idles high). */ +} spi_clock_polarity_t; + +/*! @brief SPI clock phase configuration.*/ +typedef enum _spi_clock_phase +{ + kSPI_ClockPhaseFirstEdge = 0x0U, /*!< First edge on SCK occurs at the middle of the first + * cycle of a data transfer. */ + kSPI_ClockPhaseSecondEdge = 0x1U, /*!< First edge on SCK occurs at the start of the + * first cycle of a data transfer. */ +} spi_clock_phase_t; + +/*! @brief SPI FIFO driection. */ +typedef enum _spi_fifo_direction +{ + kSPI_FifoTx = 1U, /*!< FIFO direction for transmit. */ + kSPI_FifoRx = 2U, /*!< FIFO direction for receive. */ +} spi_fifo_direction_t; + +/*! @brief Transfer data width */ +typedef enum _spi_data_width +{ + kSPI_Data1Bits = 0, /*!< 1 bits data width,when LEN = 0, the underrun status is not meaningful. */ + kSPI_Data2Bits = 1, /*!< 2 bits data width */ + kSPI_Data3Bits = 2, /*!< 3 bits data width */ + kSPI_Data4Bits = 3, /*!< 4 bits data width */ + kSPI_Data5Bits = 4, /*!< 5 bits data width */ + kSPI_Data6Bits = 5, /*!< 6 bits data width */ + kSPI_Data7Bits = 6, /*!< 7 bits data width */ + kSPI_Data8Bits = 7, /*!< 8 bits data width */ + kSPI_Data9Bits = 8, /*!< 9 bits data width */ + kSPI_Data10Bits = 9, /*!< 10 bits data width */ + kSPI_Data11Bits = 10, /*!< 11 bits data width */ + kSPI_Data12Bits = 11, /*!< 12 bits data width */ + kSPI_Data13Bits = 12, /*!< 13 bits data width */ + kSPI_Data14Bits = 13, /*!< 14 bits data width */ + kSPI_Data15Bits = 14, /*!< 15 bits data width */ + kSPI_Data16Bits = 15, /*!< 16 bits data width */ +} spi_data_width_t; + +/*! @brief Slave select */ +typedef enum _spi_ssel +{ + kSPI_Ssel0 = 0, /*!< Slave select 0 */ + kSPI_Ssel1 = 1, /*!< Slave select 1 */ + kSPI_Ssel2 = 2, /*!< Slave select 2 */ + kSPI_Ssel3 = 3, /*!< Slave select 3 */ +} spi_ssel_t; + +/*! @brief ssel polarity */ +typedef enum _spi_spol +{ + kSPI_Spol0ActiveHigh = SPI_CFG_SPOL0(1), + kSPI_Spol1ActiveHigh = SPI_CFG_SPOL1(1), + kSPI_Spol2ActiveHigh = SPI_CFG_SPOL2(1), + kSPI_Spol3ActiveHigh = SPI_CFG_SPOL3(1), + kSPI_SpolActiveAllHigh = + (kSPI_Spol0ActiveHigh | kSPI_Spol1ActiveHigh | kSPI_Spol2ActiveHigh | kSPI_Spol3ActiveHigh), + kSPI_SpolActiveAllLow = 0, +} spi_spol_t; + +/*! @brief SPI fifo user configure structure.*/ +typedef struct _spi_fifo_config +{ + bool enableTxFifo; /*!< Enable transmit FIFO */ + bool enableRxFifo; /*!< Enable receive FIFO */ + uint8_t txFifoSize; /*!< Configure txFIFO size */ + uint8_t rxFifoSize; /*!< Configure rxFIFO size */ + uint8_t txFifoThreshold; /*!< txFIFO threshold */ + uint8_t rxFifoThreshold; /*!< rxFIFO threshold */ +} spi_fifo_config_t; + +/*! @brief SPI delay time configure structure.*/ +typedef struct _spi_delay_config +{ + uint8_t preDelay; /*!< Delay between SSEL assertion and the beginning of transfer. */ + uint8_t postDelay; /*!< Delay between the end of transfer and SSEL deassertion. */ + uint8_t frameDelay; /*!< Delay between frame to frame. */ + uint8_t transferDelay; /*!< Delay between transfer to transfer. */ +} spi_delay_config_t; + +/*! @brief SPI master user configure structure.*/ +typedef struct _spi_master_config +{ + bool enableLoopback; /*!< Enable loopback for test purpose */ + bool enableMaster; /*!< Enable SPI at initialization time */ + spi_clock_polarity_t polarity; /*!< Clock polarity */ + spi_clock_phase_t phase; /*!< Clock phase */ + spi_shift_direction_t direction; /*!< MSB or LSB */ + uint32_t baudRate_Bps; /*!< Baud Rate for SPI in Hz */ + spi_data_width_t dataWidth; /*!< Width of the data */ + spi_ssel_t sselNum; /*!< Slave select number */ + spi_spol_t sselPol; /*!< Configure active CS polarity */ + spi_fifo_config_t fifoConfig; /*!< Configure for fifo. */ + spi_delay_config_t delayConfig; /*!< Configure for delay time. */ +} spi_master_config_t; + +/*! @brief SPI slave user configure structure.*/ +typedef struct _spi_slave_config +{ + bool enableSlave; /*!< Enable SPI at initialization time */ + spi_clock_polarity_t polarity; /*!< Clock polarity */ + spi_clock_phase_t phase; /*!< Clock phase */ + spi_shift_direction_t direction; /*!< MSB or LSB */ + spi_data_width_t dataWidth; /*!< Width of the data */ + spi_spol_t sselPol; /*!< Configure active CS polarity */ + spi_fifo_config_t fifoConfig; /*!< Configure for fifo. */ +} spi_slave_config_t; + +/*! @brief SPI transfer status.*/ +enum _spi_status +{ + kStatus_SPI_Busy = MAKE_STATUS(kStatusGroup_LPC_SPI, 0), /*!< SPI bus is busy */ + kStatus_SPI_Idle = MAKE_STATUS(kStatusGroup_LPC_SPI, 1), /*!< SPI is idle */ + kStatus_SPI_Error = MAKE_STATUS(kStatusGroup_LPC_SPI, 2), /*!< SPI error */ + kStatus_SPI_BaudrateNotSupport = + MAKE_STATUS(kStatusGroup_LPC_SPI, 3) /*!< Baudrate is not support in current clock source */ +}; + +/*! @brief SPI interrupt sources.*/ +enum _spi_interrupt_enable +{ + kSPI_RxReadyInterruptEnable = SPI_INTENSET_RXRDYEN_MASK, /*!< Rx ready interrupt */ + kSPI_TxReadyInterruptEnable = SPI_INTENSET_TXRDYEN_MASK, /*!< Tx ready interrupt */ + kSPI_RxOverrunInterruptEnable = SPI_INTENSET_RXOVEN_MASK, /*!< Rx overrun interrupt */ + kSPI_TxUnderrunInterruptEnable = SPI_INTENSET_TXUREN_MASK, /*!< Tx underrun interrupt */ + kSPI_SlaveSelectAssertInterruptEnable = SPI_INTENSET_SSAEN_MASK, /*!< Slave select assert interrupt */ + kSPI_SlaveSelectDeassertInterruptEnable = SPI_INTENSET_SSDEN_MASK, /*!< Slave select deassert interrupt */ + kSPI_MasterIdleInterruptEnable = SPI_INTENSET_MSTIDLEEN_MASK, /*!< Master idle interrupt */ + kSPI_AllInterruptEnable = + (SPI_INTENSET_RXRDYEN_MASK | SPI_INTENSET_TXRDYEN_MASK | SPI_INTENSET_RXOVEN_MASK | SPI_INTENSET_TXUREN_MASK | + SPI_INTENSET_SSAEN_MASK | SPI_INTENSET_SSDEN_MASK | SPI_INTENSET_MSTIDLEEN_MASK) +}; + +/*! @brief SPI FIFO interrupt sources.*/ +enum _spi_fifo_interrupt_enable +{ + kSPI_RxFifoThresholdInterruptEnable = + VFIFO_SPI_CTLSETSPI_RXTHINTEN_MASK, /*!< Rx FIFO reach the threshold interrupt */ + kSPI_TxFifoThresholdInterruptEnable = + VFIFO_SPI_CTLSETSPI_TXTHINTEN_MASK, /*!< Tx FIFO reach the threshold interrupt */ + kSPI_RxFifoTimeoutInterruptEnable = VFIFO_SPI_CTLSETSPI_RXTIMEOUTINTEN_MASK, /*!< Rx FIfo timeout interrupt */ + kSPI_AllFifoInterruptEnable = (VFIFO_SPI_CTLSETSPI_RXTHINTEN_MASK | VFIFO_SPI_CTLSETSPI_TXTHINTEN_MASK | + VFIFO_SPI_CTLSETSPI_RXTIMEOUTINTEN_MASK) +}; + +/*! @brief SPI status flags.*/ +enum _spi_status_flags +{ + kSPI_RxReadyFlag = SPI_STAT_RXRDY_MASK, /*!< Receive ready flag. */ + kSPI_TxReadyFlag = SPI_STAT_TXRDY_MASK, /*!< Transmit ready flag. */ + kSPI_RxOverrunFlag = SPI_STAT_RXOV_MASK, /*!< Receive overrun flag. */ + kSPI_TxUnderrunFlag = SPI_STAT_TXUR_MASK, /*!< Transmit underrun flag. */ + kSPI_SlaveSelectAssertFlag = SPI_STAT_SSA_MASK, /*!< Slave select assert flag. */ + kSPI_SlaveSelectDeassertFlag = SPI_STAT_SSD_MASK, /*!< slave select deassert flag. */ + kSPI_StallFlag = SPI_STAT_STALLED_MASK, /*!< Stall flag. */ + kSPI_EndTransferFlag = SPI_STAT_ENDTRANSFER_MASK, /*!< End transfer bit. */ + kSPI_MasterIdleFlag = SPI_STAT_MSTIDLE_MASK, /*!< Master in idle status flag. */ +}; + +/*! @brief SPI FIFO status flags.*/ +enum _spi_fifo_status_flags +{ + kSPI_RxFifoThresholdFlag = (VFIFO_SPI_STATSPI_RXTH_MASK), /*!< Receive FIFO threshold reached flag. */ + kSPI_TxFifoThresholdFlag = (VFIFO_SPI_STATSPI_TXTH_MASK), /*!< Transmit FIFO threshold reached flag. */ + kSPI_RxFifoTimeOutFlag = (VFIFO_SPI_STATSPI_RXTIMEOUT_MASK), /*!< Receive time out flag. */ + kSPI_FifoBusErrorFlag = (VFIFO_SPI_STATSPI_BUSERR_MASK), /*!< FIFO bus error flag. */ + kSPI_RxFifoEmptyFlag = (VFIFO_SPI_STATSPI_RXEMPTY_MASK), /*!< Receive fifo buffer empty flag. */ + kSPI_TxFifoEmptyFlag = (VFIFO_SPI_STATSPI_TXEMPTY_MASK), /*!< transmit fifo buffer empty flag. */ +}; + +/*! @brief SPI transfer structure */ +typedef struct _spi_transfer +{ + uint8_t *txData; /*!< Send buffer */ + uint8_t *rxData; /*!< Receive buffer */ + uint32_t configFlags; /*!< Additional option to control transfer */ + size_t dataSize; /*!< Transfer bytes */ +} spi_transfer_t; + +/*! @brief SPI half-duplex(master only) transfer structure */ +typedef struct _spi_half_duplex_transfer +{ + uint8_t *txData; /*!< Send buffer */ + uint8_t *rxData; /*!< Receive buffer */ + size_t txDataSize; /*!< Transfer bytes for transmit */ + size_t rxDataSize; /*!< Transfer bytes */ + uint32_t configFlags; /*!< Transfer configuration flags; set from _dspi_transfer_config_flag_for_master. */ + bool isPcsAssertInTransfer; /*!< If Pcs pin keep assert between transmit and receive. true for assert and false for + deassert. */ + bool isTransmitFirst; /*!< True for transmit first and false for receive first. */ +} spi_half_duplex_transfer_t; + +/*! @brief Internal configuration structure used in 'spi' and 'spi_dma' driver */ +typedef struct _spi_config +{ + spi_data_width_t dataWidth; + spi_ssel_t sselNum; +} spi_config_t; + +/*! @brief Master handle type */ +typedef struct _spi_master_handle spi_master_handle_t; + +/*! @brief Slave handle type */ +typedef spi_master_handle_t spi_slave_handle_t; + +/*! @brief SPI master callback for finished transmit */ +typedef void (*spi_master_callback_t)(SPI_Type *base, spi_master_handle_t *handle, status_t status, void *userData); + +/*! @brief SPI slave callback for finished transmit */ +typedef void (*spi_slave_callback_t)(SPI_Type *base, spi_slave_handle_t *handle, status_t status, void *userData); + +/*! @brief SPI transfer handle structure */ +struct _spi_master_handle +{ + uint8_t *volatile txData; /*!< Transfer buffer */ + uint8_t *volatile rxData; /*!< Receive buffer */ + volatile size_t txRemainingBytes; /*!< Number of data to be transmitted [in bytes] */ + volatile size_t rxRemainingBytes; /*!< Number of data to be received [in bytes] */ + size_t totalByteCount; /*!< A number of transfer bytes */ + volatile uint32_t state; /*!< SPI internal state */ + spi_master_callback_t callback; /*!< SPI callback */ + void *userData; /*!< Callback parameter */ + uint8_t dataWidth; /*!< Width of the data [Valid values: 1 to 16] */ + uint8_t sselNum; /*!< Slave select number to be asserted when transferring data [Valid values: 0 to 3] */ + uint32_t configFlags; /*!< Additional option to control transfer */ + bool isTxFifoEnabled; /*!< Is transmit FIFO enabled. */ + bool isRxFifoEnabled; /*!< Is receive FIFO enabled. */ + uint8_t txFifoThreshold; /*!< txFIFO threshold */ + uint8_t rxFifoThreshold; /*!< rxFIFO threshold */ +}; + +#if defined(__cplusplus) +extern "C" { +#endif +/******************************************************************************* + * API + ******************************************************************************/ + +/*! @brief Returns instance number for SPI peripheral base address. */ +uint32_t SPI_GetInstance(SPI_Type *base); + +/*! + * @name Initialization and deinitialization + * @{ + */ + +/*! + * @brief Sets the SPI master configuration structure to default values. + * + * The purpose of this API is to get the configuration structure initialized for use in SPI_MasterInit(). + * User may use the initialized structure unchanged in SPI_MasterInit(), or modify + * some fields of the structure before calling SPI_MasterInit(). After calling this API, + * the master is ready to transfer. + * Example: + @code + spi_master_config_t config; + SPI_MasterGetDefaultConfig(&config); + @endcode + * + * @param config pointer to master config structure + */ +void SPI_MasterGetDefaultConfig(spi_master_config_t *config); + +/*! + * @brief Initializes the SPI with master configuration. + * + * The configuration structure can be filled by user from scratch, or be set with default + * values by SPI_MasterGetDefaultConfig(). After calling this API, the slave is ready to transfer. + * Example + @code + spi_master_config_t config = { + .baudRate_Bps = 500000, + ... + }; + SPI_MasterInit(SPI0, &config); + @endcode + * + * @param base SPI base pointer + * @param config pointer to master configuration structure + * @param srcClock_Hz Source clock frequency. + */ +status_t SPI_MasterInit(SPI_Type *base, const spi_master_config_t *config, uint32_t srcClock_Hz); + +/*! + * @brief Sets the SPI slave configuration structure to default values. + * + * The purpose of this API is to get the configuration structure initialized for use in SPI_SlaveInit(). + * Modify some fields of the structure before calling SPI_SlaveInit(). + * Example: + @code + spi_slave_config_t config; + SPI_SlaveGetDefaultConfig(&config); + @endcode + * + * @param config pointer to slave configuration structure + */ +void SPI_SlaveGetDefaultConfig(spi_slave_config_t *config); + +/*! + * @brief Initializes the SPI with slave configuration. + * + * The configuration structure can be filled by user from scratch or be set with + * default values by SPI_SlaveGetDefaultConfig(). + * After calling this API, the slave is ready to transfer. + * Example + @code + spi_slave_config_t config = { + .polarity = kSPI_ClockPolarityActiveHigh; + .phase = kSPI_ClockPhaseFirstEdge; + .direction = kSPI_MsbFirst; + ... + }; + SPI_SlaveInit(SPI0, &config); + @endcode + * + * @param base SPI base pointer + * @param config pointer to slave configuration structure + */ +status_t SPI_SlaveInit(SPI_Type *base, const spi_slave_config_t *config); + +/*! + * @brief De-initializes the SPI. + * + * Calling this API resets the SPI module, gates the SPI clock. + * Disable the fifo if enabled. + * The SPI module can't work unless calling the SPI_MasterInit/SPI_SlaveInit to initialize module. + * + * @param base SPI base pointer + */ +void SPI_Deinit(SPI_Type *base); + +/*! + * @brief Enable or disable the SPI Master or Slave + * @param base SPI base pointer + * @param enable or disable ( true = enable, false = disable) + */ +static inline void SPI_Enable(SPI_Type *base, bool enable) +{ + if (enable) + { + base->CFG |= SPI_CFG_ENABLE_MASK; + } + else + { + base->CFG &= ~SPI_CFG_ENABLE_MASK; + } +} + +/*! @} */ + +/*! + * @name Status + * @{ + */ + +/*! + * @brief Gets the status flag. + * + * @param base SPI base pointer + * @return SPI Status, use status flag to AND @ref _spi_status_flags could get the related status. + */ +static inline uint32_t SPI_GetStatusFlags(SPI_Type *base) +{ + assert(NULL != base); + return base->STAT; +} + +/*! + * @brief Gets the FIFO status flag for SPI transfer. + * + * @param base SPI base pointer + * @return SPI Status, use status flag to AND @ref _spi_fifo_status_flags could get the related status. + */ +uint32_t SPI_GetFifoStatusFlags(SPI_Type *base); + +/*! + * @brief Clear the FIFO status flag for SPI transfer. + * Only kSPI_RxFifoTimeOutFlag and kSPI_FifoBusErrorFlag can be cleared. + * @param base SPI base pointer + * @param mask use status flag to AND @ref _spi_status_flags could get the related status. + */ +void SPI_ClearFifoStatusFlags(SPI_Type *base, uint32_t mask); +/*! @} */ + +/*! + * @name Interrupts + * @{ + */ + +/*! + * @brief Enables the interrupt for the SPI. + * + * @param base SPI base pointer + * @param irqs SPI interrupt source. The parameter can be any combination of the following values: + * @arg kSPI_RxReadyInterruptEnable + * @arg kSPI_TxReadyInterruptEnable + */ +static inline void SPI_EnableInterrupts(SPI_Type *base, uint32_t irqs) +{ + assert(NULL != base); + base->INTENSET = irqs; +} + +/*! + * @brief Disables the interrupt for the SPI. + * + * @param base SPI base pointer + * @param irqs SPI interrupt source. The parameter can be any combination of the following values: + * @arg kSPI_RxReadyInterruptEnable + * @arg kSPI_TxReadyInterruptEnable + */ +static inline void SPI_DisableInterrupts(SPI_Type *base, uint32_t irqs) +{ + assert(NULL != base); + base->INTENCLR = irqs; +} + +/*! + * @brief Enables the FIFO interrupt for the SPI. + * + * @param base SPI base pointer + * @param irqs SPI interrupt source. The parameter can be any combination of the following values: + * @arg kSPI_RxFifoThresholdInterruptEnable + * @arg kSPI_TxFifoThresholdInterruptEnable + */ +void SPI_EnableFifoInterrupts(SPI_Type *base, uint32_t irqs); + +/*! + * @brief Disables the FIFO interrupt for the SPI. + * + * @param base SPI base pointer + * @param irqs SPI interrupt source. The parameter can be any combination of the following values: + * @arg kSPI_RxFifoThresholdInterruptEnable + * @arg kSPI_TxFifoThresholdInterruptEnable + */ +void SPI_DisableFifoInterrupts(SPI_Type *base, uint32_t irqs); +/*! @} */ + +/*! + * @name Bus Operations + * @{ + */ + +/*! + * @brief Returns whether the SPI module is in master mode. + * + * @param base SPI peripheral address. + * @return Returns true if the module is in master mode or false if the module is in slave mode. + */ +static inline bool SPI_IsMaster(SPI_Type *base) +{ + return (bool)(((base->CFG) & SPI_CFG_MASTER_MASK) >> SPI_CFG_MASTER_SHIFT); +} + +/*! + * @brief Returns the configurations. + * + * @param base SPI peripheral address. + * @return return configurations which contain datawidth and SSEL numbers. + * return data type is a pointer of spi_config_t. + */ +void *SPI_GetConfig(SPI_Type *base); +/*! + * @brief Sets the baud rate for SPI transfer. This is only used in master. + * + * @param base SPI base pointer + * @param baudrate_Bps baud rate needed in Hz. + * @param srcClock_Hz SPI source clock frequency in Hz. + */ +status_t SPI_MasterSetBaud(SPI_Type *base, uint32_t baudrate_Bps, uint32_t srcClock_Hz); + +/*! + * @brief Writes a data into the SPI data register. + * + * @param base SPI base pointer + * @param data needs to be write. + * @param configFlags transfer configuration options @ref spi_xfer_option_t + */ +void SPI_WriteData(SPI_Type *base, uint16_t data, uint32_t configFlags); + +/*! + * @brief Gets a data from the SPI data register. + * + * @param base SPI base pointer + * @return Data in the register. + */ +uint32_t SPI_ReadData(SPI_Type *base); + +/*! + * @brief Set delay time for transfer. + * the delay uint is SPI clock time, maximum value is 0xF. + * @param base SPI base pointer + * @param config configuration for delay option @ref spi_delay_config_t. + */ +void SPI_SetTransferDelay(SPI_Type *base, const spi_delay_config_t *config); + +/*! + * @brief Set up the dummy data. + * + * @param base SPI peripheral address. + * @param dummyData Data to be transferred when tx buffer is NULL. + */ +void SPI_SetDummyData(SPI_Type *base, uint8_t dummyData); + +/*! @} */ + +/*! + * @name FIFO Operations + * @{ + */ + +/*! + * @brief Enable FIFO for SPI. + * + * This function will enable the FIFO for SPI according to pointer of the configure struct. + * Note: If this API is called, please reset the baudrate to adapt your demand after this API + * was called. + * + * @param base SPI peripheral base address. + * @param config pointer to FIFO configuration structure. + */ +void SPI_EnableFifo(SPI_Type *base, const spi_fifo_config_t *config); + +/*! + * @brief Disable FIFO for SPI. + * + * This function will Disable the FIFO for SPI transfer. + * disable interrupts, clear status flags, disable the TX/RX FIFO, set fifo size to zero. + * But will not disable the system FIFO, because other instance like USART may using the FIFO. + * + * @param base SPI peripheral base address. + * @param config pointer to FIFO configuration structure. + */ +void SPI_DisableFifo(SPI_Type *base); + +/*! + * @brief Is TX FIFO enabled. + * + * This function will return status if the transmit fifo is enabled. true for enabled and false for not enabled. + * + * @param base SPI peripheral base address. + * @return true for enabled and false for not enabled. + */ +bool SPI_IsTxFifoEnabled(SPI_Type *base); + +/*! + * @brief Is RX FIFO enabled. + * + * This function will return status if the receive fifo is enabled. true for enabled and false for not enabled. + * + * @param base SPI peripheral base address. + * @return true for enabled and false for not enabled. + */ +bool SPI_IsRxFifoEnabled(SPI_Type *base); + +/*! + * @brief Flush the FIFO buffer. + * + * This function will Flush tHE fifo buffer. + * + * @param base SPI peripheral base address. + * @param direction the fifo direction need to flushed, Tx FIFO or Rx FIFO. + */ +void SPI_FifoFlush(SPI_Type *base, uint32_t direction); +/*! @} */ + +/*! + * @name Transactional + * @{ + */ + +/*! + * @brief Initializes the SPI master handle. + * + * This function initializes the SPI master handle which can be used for other SPI master transactional APIs. Usually, + * for a specified SPI instance, call this API once to get the initialized handle. + * + * @param base SPI peripheral base address. + * @param handle SPI handle pointer. + * @param callback Callback function. + * @param userData User data. + */ +status_t SPI_MasterTransferCreateHandle(SPI_Type *base, + spi_master_handle_t *handle, + spi_master_callback_t callback, + void *userData); + +/*! + * @brief Transfers a block of data using a polling method. + * + * @param base SPI base pointer + * @param xfer pointer to spi_xfer_config_t structure + * @retval kStatus_Success Successfully start a transfer. + * @retval kStatus_InvalidArgument Input argument is invalid. + */ +status_t SPI_MasterTransferBlocking(SPI_Type *base, spi_transfer_t *xfer); + +/*! + * @brief Performs a non-blocking SPI interrupt transfer. + * + * @param base SPI peripheral base address. + * @param handle pointer to spi_master_handle_t structure which stores the transfer state + * @param xfer pointer to spi_xfer_config_t structure + * @retval kStatus_Success Successfully start a transfer. + * @retval kStatus_InvalidArgument Input argument is invalid. + * @retval kStatus_SPI_Busy SPI is not idle, is running another transfer. + */ +status_t SPI_MasterTransferNonBlocking(SPI_Type *base, spi_master_handle_t *handle, spi_transfer_t *xfer); + +/*! + * @brief Transfers a block of data using a polling method. + * + * This function will do a half-duplex transfer for SPI master, This is a blocking function, + * which does not retuen until all transfer have been completed. And data transfer will be half-duplex, + * users can set transmit first or receive first. + * + * @param base SPI base pointer + * @param xfer pointer to spi_half_duplex_transfer_t structure + * @return status of status_t. + */ +status_t SPI_MasterHalfDuplexTransferBlocking(SPI_Type *base, spi_half_duplex_transfer_t *xfer); + +/*! + * @brief Performs a non-blocking SPI interrupt transfer. + * + * This function using polling way to do the first half transimission and using interrupts to + * do the srcond half transimission, the transfer mechanism is half-duplex. + * When do the second half transimission, code will return right away. When all data is transferred, + * the callback function is called. + * + * @param base SPI peripheral base address. + * @param handle pointer to spi_master_handle_t structure which stores the transfer state + * @param xfer pointer to spi_half_duplex_transfer_t structure + * @return status of status_t. + */ +status_t SPI_MasterHalfDuplexTransferNonBlocking(SPI_Type *base, + spi_master_handle_t *handle, + spi_half_duplex_transfer_t *xfer); + +/*! + * @brief Gets the master transfer count. + * + * This function gets the master transfer count. + * + * @param base SPI peripheral base address. + * @param handle Pointer to the spi_master_handle_t structure which stores the transfer state. + * @param count The number of bytes transferred by using the non-blocking transaction. + * @return status of status_t. + */ +status_t SPI_MasterTransferGetCount(SPI_Type *base, spi_master_handle_t *handle, size_t *count); + +/*! + * @brief SPI master aborts a transfer using an interrupt. + * + * This function aborts a transfer using an interrupt. + * + * @param base SPI peripheral base address. + * @param handle Pointer to the spi_master_handle_t structure which stores the transfer state. + */ +void SPI_MasterTransferAbort(SPI_Type *base, spi_master_handle_t *handle); + +/*! + * @brief Interrupts the handler for the SPI. + * + * @param base SPI peripheral base address. + * @param handle pointer to spi_master_handle_t structure which stores the transfer state. + */ +void SPI_MasterTransferHandleIRQ(SPI_Type *base, spi_master_handle_t *handle); + +/*! + * @brief Initializes the SPI slave handle. + * + * This function initializes the SPI slave handle which can be used for other SPI slave transactional APIs. Usually, + * for a specified SPI instance, call this API once to get the initialized handle. + * + * @param base SPI peripheral base address. + * @param handle SPI handle pointer. + * @param callback Callback function. + * @param userData User data. + */ +status_t SPI_SlaveTransferCreateHandle(SPI_Type *base, + spi_slave_handle_t *handle, + spi_slave_callback_t callback, + void *userData); + +/*! + * @brief Performs a non-blocking SPI slave interrupt transfer. + * + * @note The API returns immediately after the transfer initialization is finished. + * + * @param base SPI peripheral base address. + * @param handle pointer to spi_master_handle_t structure which stores the transfer state + * @param xfer pointer to spi_xfer_config_t structure + * @retval kStatus_Success Successfully start a transfer. + * @retval kStatus_InvalidArgument Input argument is invalid. + * @retval kStatus_SPI_Busy SPI is not idle, is running another transfer. + */ +status_t SPI_SlaveTransferNonBlocking(SPI_Type *base, spi_slave_handle_t *handle, spi_transfer_t *xfer); + +/*! + * @brief Gets the slave transfer count. + * + * This function gets the slave transfer count. + * + * @param base SPI peripheral base address. + * @param handle Pointer to the spi_master_handle_t structure which stores the transfer state. + * @param count The number of bytes transferred by using the non-blocking transaction. + * @return status of status_t. + */ +static inline status_t SPI_SlaveTransferGetCount(SPI_Type *base, spi_slave_handle_t *handle, size_t *count) +{ + return SPI_MasterTransferGetCount(base, (spi_master_handle_t *)handle, count); +} + +/*! + * @brief SPI slave aborts a transfer using an interrupt. + * + * This function aborts a transfer using an interrupt. + * + * @param base SPI peripheral base address. + * @param handle Pointer to the spi_slave_handle_t structure which stores the transfer state. + */ +static inline void SPI_SlaveTransferAbort(SPI_Type *base, spi_slave_handle_t *handle) +{ + SPI_MasterTransferAbort(base, (spi_master_handle_t *)handle); +} + +/*! + * @brief Interrupts a handler for the SPI slave. + * + * @param base SPI peripheral base address. + * @param handle pointer to spi_slave_handle_t structure which stores the transfer state + */ +void SPI_SlaveTransferHandleIRQ(SPI_Type *base, spi_slave_handle_t *handle); + +/*! @} */ + +#if defined(__cplusplus) +} +#endif + +/*! @} */ + +#endif /* _FSL_SPI_H_*/ diff --git a/platform/mcu/lpc54102/drivers/fsl_spi_dma.c b/platform/mcu/lpc54102/drivers/fsl_spi_dma.c new file mode 100644 index 0000000000..a381b2070b --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_spi_dma.c @@ -0,0 +1,615 @@ +/* + * Copyright (c) 2017, NXP Semiconductors, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_spi_dma.h" + +/******************************************************************************* + * Definitons + ******************************************************************************/ +/*configFlags & (uint32_t)kSPI_FrameDelay) ? (uint32_t)kSPI_FrameDelay : 0; + *fifowr |= (xfer->configFlags & (uint32_t)kSPI_FrameAssert) ? (uint32_t)kSPI_FrameAssert : 0; + *fifowr |= (xfer->configFlags & (uint32_t)kSPI_ReceiveIgnore) ? (uint32_t)kSPI_ReceiveIgnore : 0; +} + +static void SpiConfigToFifoWR(spi_config_t *config, uint32_t *fifowr) +{ + *fifowr |= (SPI_DEASSERT_ALL & (~SPI_DEASSERT_SSELNUM(config->sselNum))); + /* set width of data - range asserted at entry */ + *fifowr |= SPI_TXDATCTL_LEN(config->dataWidth); +} + +static void SPI_SetupDummy(SPI_Type *base, spi_dma_txdummy_t *dummy, spi_transfer_t *xfer, spi_config_t *spi_config_p) +{ + uint32_t instance = SPI_GetInstance(base); + dummy->word = ((uint32_t)s_dummyData[instance] << 8U) | s_dummyData[instance]; + XferToFifoWR(xfer, &dummy->word); + SpiConfigToFifoWR(spi_config_p, &dummy->word); + if ((xfer->configFlags & kSPI_FrameAssert) && + ((spi_config_p->dataWidth > 7U) ? (xfer->dataSize > 2) : (xfer->dataSize > 1))) + { + dummy->lastWord = ((uint32_t)s_dummyData[instance] << 8U) | s_dummyData[instance]; + XferToFifoWR(xfer, &dummy->lastWord); + SpiConfigToFifoWR(spi_config_p, &dummy->lastWord); + dummy->word &= (uint32_t)(~kSPI_FrameAssert); + } +} + +status_t SPI_MasterTransferCreateHandleDMA(SPI_Type *base, + spi_dma_handle_t *handle, + spi_dma_callback_t callback, + void *userData, + dma_handle_t *txHandle, + dma_handle_t *rxHandle) +{ + int32_t instance = 0; + + /* check 'base' */ + assert(!(NULL == base)); + if (NULL == base) + { + return kStatus_InvalidArgument; + } + /* check 'handle' */ + assert(!(NULL == handle)); + if (NULL == handle) + { + return kStatus_InvalidArgument; + } + + instance = SPI_GetInstance(base); + + memset(handle, 0, sizeof(*handle)); + /* Set spi base to handle */ + handle->txHandle = txHandle; + handle->rxHandle = rxHandle; + handle->callback = callback; + handle->userData = userData; + + /* Set SPI state to idle */ + handle->state = kSPI_Idle; + + /* Set handle to global state */ + s_dmaPrivateHandle[instance].base = base; + s_dmaPrivateHandle[instance].handle = handle; + + /* Install callback for Tx dma channel */ + DMA_SetCallback(handle->txHandle, SPI_TxDMACallback, &s_dmaPrivateHandle[instance]); + DMA_SetCallback(handle->rxHandle, SPI_RxDMACallback, &s_dmaPrivateHandle[instance]); + + return kStatus_Success; +} + +status_t SPI_MasterTransferDMA(SPI_Type *base, spi_dma_handle_t *handle, spi_transfer_t *xfer) +{ + int32_t instance; + status_t result = kStatus_Success; + spi_config_t *spi_config_p; + + assert(!((NULL == handle) || (NULL == xfer))); + if ((NULL == handle) || (NULL == xfer)) + { + return kStatus_InvalidArgument; + } + /* byte size is zero. */ + assert(!(xfer->dataSize == 0)); + if (xfer->dataSize == 0) + { + return kStatus_InvalidArgument; + } + + /* cannot get instance from base address */ + instance = SPI_GetInstance(base); + assert(!(instance < 0)); + if (instance < 0) + { + return kStatus_InvalidArgument; + } + + /* Check if the device is busy */ + if (handle->state == kSPI_Busy) + { + return kStatus_SPI_Busy; + } + else + { + uint32_t tmp; + dma_transfer_config_t xferConfig = {0}; + spi_config_p = (spi_config_t *)SPI_GetConfig(base); + + handle->state = kStatus_SPI_Busy; + handle->transferSize = xfer->dataSize; + + /* Receive */ + if (xfer->rxData) + { + if (SPI_IsRxFifoEnabled(base)) + { + DMA_PrepareTransfer(&xferConfig, (void *)&VFIFO->SPI[instance].RXDATSPI, xfer->rxData, + ((spi_config_p->dataWidth > 7U) ? (sizeof(uint16_t)) : (sizeof(uint8_t))), + xfer->dataSize, kDMA_PeripheralToMemory, NULL); + } + else + { + DMA_PrepareTransfer(&xferConfig, (void *)&base->RXDAT, xfer->rxData, + ((spi_config_p->dataWidth > 7U) ? (sizeof(uint16_t)) : (sizeof(uint8_t))), + xfer->dataSize, kDMA_PeripheralToMemory, NULL); + } + } + else + { + if (SPI_IsRxFifoEnabled(base)) + { + DMA_PrepareTransfer(&xferConfig, (void *)&VFIFO->SPI[instance].RXDATSPI, &s_rxDummy, + ((spi_config_p->dataWidth > 7U) ? (sizeof(uint16_t)) : (sizeof(uint8_t))), + xfer->dataSize, kDMA_StaticToStatic, NULL); + } + else + { + DMA_PrepareTransfer(&xferConfig, (void *)&base->RXDAT, &s_rxDummy, + ((spi_config_p->dataWidth > 7U) ? (sizeof(uint16_t)) : (sizeof(uint8_t))), + xfer->dataSize, kDMA_StaticToStatic, NULL); + } + } + DMA_SubmitTransfer(handle->rxHandle, &xferConfig); + handle->rxInProgress = true; + DMA_StartTransfer(handle->rxHandle); + + /* Transmit */ + tmp = 0; + XferToFifoWR(xfer, &tmp); + SpiConfigToFifoWR(spi_config_p, &tmp); + + if ((xfer->configFlags & kSPI_FrameAssert) && + ((spi_config_p->dataWidth > 7U) ? (xfer->dataSize > 2) : (xfer->dataSize > 1))) + { + if (spi_config_p->dataWidth > 7U) + { + s_txLastData[instance] = + tmp | ((uint32_t)(xfer->txData[xfer->dataSize - 1]) << 8U) | (xfer->txData[xfer->dataSize - 2]); + } + else + { + s_txLastData[instance] = tmp | (xfer->txData[xfer->dataSize - 1]); + } + + /* If not the last data, clear the end of transfer control bit. */ + tmp &= ~((uint32_t)(kSPI_FrameAssert)); + } + + if (xfer->txData) + { + if (SPI_IsTxFifoEnabled(base)) + { + if ((xfer->configFlags & kSPI_FrameAssert) && + ((spi_config_p->dataWidth > 7U) ? (xfer->dataSize > 2) : (xfer->dataSize > 1))) + { + dma_xfercfg_t tmp_xfercfg = {0}; + tmp_xfercfg.valid = true; + tmp_xfercfg.swtrig = true; + tmp_xfercfg.intA = true; + tmp_xfercfg.byteWidth = sizeof(uint32_t); + tmp_xfercfg.srcInc = 0; + tmp_xfercfg.dstInc = 0; + tmp_xfercfg.transferCount = 1; + /* create chained descriptor to transmit last word */ + DMA_CreateDescriptor(&s_spi_descriptor_table[instance], &tmp_xfercfg, &s_txLastData[instance], + (uint32_t *)&VFIFO->SPI[instance].TXDATSPI, NULL); + if (spi_config_p->dataWidth > 7U) + { + DMA_PrepareTransfer(&xferConfig, (xfer->txData), (void *)&VFIFO->SPI[instance].TXDATSPI, + sizeof(uint16_t), (xfer->dataSize - 2), kDMA_MemoryToPeripheral, + &s_spi_descriptor_table[instance]); + } + else + { + DMA_PrepareTransfer(&xferConfig, xfer->txData, (void *)&VFIFO->SPI[instance].TXDATSPI, + sizeof(uint8_t), (xfer->dataSize - 1), kDMA_MemoryToPeripheral, + &s_spi_descriptor_table[instance]); + } + + /* Disable interrupts for first descriptor to avoid calling callback twice */ + xferConfig.xfercfg.intA = false; + xferConfig.xfercfg.intB = false; + } + else + { + if (spi_config_p->dataWidth > 7U) + { + DMA_PrepareTransfer(&xferConfig, (xfer->txData), (void *)&VFIFO->SPI[instance].TXDATSPI, + sizeof(uint16_t), (xfer->dataSize), kDMA_MemoryToPeripheral, NULL); + } + else + { + DMA_PrepareTransfer(&xferConfig, xfer->txData, (void *)&VFIFO->SPI[instance].TXDATSPI, + sizeof(uint8_t), (xfer->dataSize), kDMA_MemoryToPeripheral, NULL); + } + } + } + else + { + if ((xfer->configFlags & kSPI_FrameAssert) && + ((spi_config_p->dataWidth > 7U) ? (xfer->dataSize > 2) : (xfer->dataSize > 1))) + { + dma_xfercfg_t tmp_xfercfg = {0}; + tmp_xfercfg.valid = true; + tmp_xfercfg.swtrig = true; + tmp_xfercfg.intA = true; + tmp_xfercfg.byteWidth = sizeof(uint32_t); + tmp_xfercfg.srcInc = 0; + tmp_xfercfg.dstInc = 0; + tmp_xfercfg.transferCount = 1; + /* Create chained descriptor to transmit last word */ + DMA_CreateDescriptor(&s_spi_descriptor_table[instance], &tmp_xfercfg, &s_txLastData[instance], + (uint32_t *)&base->TXDATCTL, NULL); + if (spi_config_p->dataWidth > 7U) + { + DMA_PrepareTransfer(&xferConfig, xfer->txData, (void *)&base->TXDAT, sizeof(uint16_t), + (xfer->dataSize - 2), kDMA_MemoryToPeripheral, + &s_spi_descriptor_table[instance]); + } + else + { + DMA_PrepareTransfer(&xferConfig, xfer->txData, (void *)&base->TXDAT, sizeof(uint8_t), + (xfer->dataSize - 1), kDMA_MemoryToPeripheral, + &s_spi_descriptor_table[instance]); + } + /* disable interrupts for first descriptor to avoid calling callback twice */ + xferConfig.xfercfg.intA = false; + xferConfig.xfercfg.intB = false; + } + else + { + if (spi_config_p->dataWidth > 7U) + { + DMA_PrepareTransfer(&xferConfig, xfer->txData, (void *)&base->TXDAT, sizeof(uint16_t), + (xfer->dataSize), kDMA_MemoryToPeripheral, NULL); + } + else + { + DMA_PrepareTransfer(&xferConfig, xfer->txData, (void *)&base->TXDAT, sizeof(uint8_t), + (xfer->dataSize), kDMA_MemoryToPeripheral, NULL); + } + } + } + result = DMA_SubmitTransfer(handle->txHandle, &xferConfig); + if (result != kStatus_Success) + { + return result; + } + } + else + { + /* Create chained descriptor to transmit dummy word. */ + SPI_SetupDummy(base, &s_txDummy[instance], xfer, spi_config_p); + + if ((xfer->configFlags & kSPI_FrameAssert) && + ((spi_config_p->dataWidth > 7U) ? (xfer->dataSize > 2) : (xfer->dataSize > 1))) + { + dma_xfercfg_t tmp_xfercfg = {0}; + tmp_xfercfg.valid = true; + tmp_xfercfg.swtrig = true; + tmp_xfercfg.intA = true; + tmp_xfercfg.byteWidth = sizeof(uint32_t); + tmp_xfercfg.srcInc = 0; + tmp_xfercfg.dstInc = 0; + tmp_xfercfg.transferCount = 1; + + if (SPI_IsTxFifoEnabled(base)) + { + DMA_CreateDescriptor(&s_spi_descriptor_table[instance], &tmp_xfercfg, &s_txDummy[instance].lastWord, + (uint32_t *)&VFIFO->SPI[instance].TXDATSPI, NULL); + } + else + { + DMA_CreateDescriptor(&s_spi_descriptor_table[instance], &tmp_xfercfg, &s_txDummy[instance].lastWord, + (uint32_t *)&base->TXDATCTL, NULL); + } + + if (SPI_IsTxFifoEnabled(base)) + { + DMA_PrepareTransfer(&xferConfig, &s_txDummy[instance].word, (void *)&VFIFO->SPI[instance].TXDATSPI, + ((spi_config_p->dataWidth > 7U) ? (sizeof(uint16_t)) : (sizeof(uint8_t))), + ((spi_config_p->dataWidth > 7U) ? (xfer->dataSize - 2) : (xfer->dataSize - 1)), + kDMA_StaticToStatic, &s_spi_descriptor_table[instance]); + } + else + { + DMA_PrepareTransfer(&xferConfig, &s_txDummy[instance].word, (void *)&base->TXDATCTL, + ((spi_config_p->dataWidth > 7U) ? (sizeof(uint16_t)) : (sizeof(uint8_t))), + ((spi_config_p->dataWidth > 7U) ? (xfer->dataSize - 2) : (xfer->dataSize - 1)), + kDMA_StaticToStatic, &s_spi_descriptor_table[instance]); + } + /* Disable interrupts for first descriptor to avoid calling callback twice */ + xferConfig.xfercfg.intA = false; + xferConfig.xfercfg.intB = false; + result = DMA_SubmitTransfer(handle->txHandle, &xferConfig); + if (result != kStatus_Success) + { + return result; + } + } + else + { + if (SPI_IsTxFifoEnabled(base)) + { + DMA_PrepareTransfer(&xferConfig, &s_txDummy[instance].word, (void *)&VFIFO->SPI[instance].TXDATSPI, + ((spi_config_p->dataWidth > 7U) ? (sizeof(uint16_t)) : (sizeof(uint8_t))), + (xfer->dataSize), kDMA_StaticToStatic, NULL); + } + else + { + DMA_PrepareTransfer(&xferConfig, &s_txDummy[instance].word, (void *)&base->TXDAT, + ((spi_config_p->dataWidth > 7U) ? (sizeof(uint16_t)) : (sizeof(uint8_t))), + (xfer->dataSize), kDMA_StaticToStatic, NULL); + } + result = DMA_SubmitTransfer(handle->txHandle, &xferConfig); + if (result != kStatus_Success) + { + return result; + } + } + } + handle->txInProgress = true; + /* Setup the control information. */ + if (SPI_IsTxFifoEnabled(base)) + { + *((uint16_t *)&(VFIFO->SPI[instance].TXDATSPI) + 1) = (tmp >> 16U); + } + else + { + base->TXCTL = tmp; + } + DMA_StartTransfer(handle->txHandle); + } + + return result; +} + +status_t SPI_MasterHalfDuplexTransferDMA(SPI_Type *base, spi_dma_handle_t *handle, spi_half_duplex_transfer_t *xfer) +{ + assert(xfer); + assert(handle); + spi_transfer_t tempXfer = {0}; + status_t status; + + if (xfer->isTransmitFirst) + { + tempXfer.txData = xfer->txData; + tempXfer.rxData = NULL; + tempXfer.dataSize = xfer->txDataSize; + } + else + { + tempXfer.txData = NULL; + tempXfer.rxData = xfer->rxData; + tempXfer.dataSize = xfer->rxDataSize; + } + /* If the pcs pin keep assert between transmit and receive. */ + if (xfer->isPcsAssertInTransfer) + { + tempXfer.configFlags = (xfer->configFlags) & (uint32_t)(~kSPI_FrameAssert); + } + else + { + tempXfer.configFlags = (xfer->configFlags) | kSPI_FrameAssert; + } + + status = SPI_MasterTransferBlocking(base, &tempXfer); + if (status != kStatus_Success) + { + return status; + } + + if (xfer->isTransmitFirst) + { + tempXfer.txData = NULL; + tempXfer.rxData = xfer->rxData; + tempXfer.dataSize = xfer->rxDataSize; + } + else + { + tempXfer.txData = xfer->txData; + tempXfer.rxData = NULL; + tempXfer.dataSize = xfer->txDataSize; + } + tempXfer.configFlags = xfer->configFlags; + + status = SPI_MasterTransferDMA(base, handle, &tempXfer); + + return status; +} + +static void SPI_RxDMACallback(dma_handle_t *handle, void *userData, bool transferDone, uint32_t intmode) +{ + spi_dma_private_handle_t *privHandle = (spi_dma_private_handle_t *)userData; + spi_dma_handle_t *spiHandle = privHandle->handle; + SPI_Type *base = privHandle->base; + + /* change the state */ + spiHandle->rxInProgress = false; + + /* All finished, call the callback */ + if ((spiHandle->txInProgress == false) && (spiHandle->rxInProgress == false)) + { + spiHandle->state = kSPI_Idle; + if (spiHandle->callback) + { + (spiHandle->callback)(base, spiHandle, kStatus_Success, spiHandle->userData); + } + } +} + +static void SPI_TxDMACallback(dma_handle_t *handle, void *userData, bool transferDone, uint32_t intmode) +{ + spi_dma_private_handle_t *privHandle = (spi_dma_private_handle_t *)userData; + spi_dma_handle_t *spiHandle = privHandle->handle; + SPI_Type *base = privHandle->base; + /* change the state */ + spiHandle->txInProgress = false; + /* All finished, call the callback */ + if ((spiHandle->txInProgress == false) && (spiHandle->rxInProgress == false)) + { + spiHandle->state = kSPI_Idle; + if (spiHandle->callback) + { + (spiHandle->callback)(base, spiHandle, kStatus_Success, spiHandle->userData); + } + } +} + +void SPI_MasterTransferAbortDMA(SPI_Type *base, spi_dma_handle_t *handle) +{ + assert(NULL != handle); + + /* Stop tx transfer first */ + DMA_AbortTransfer(handle->txHandle); + /* Then rx transfer */ + DMA_AbortTransfer(handle->rxHandle); + + /* Set the handle state */ + handle->txInProgress = false; + handle->rxInProgress = false; + handle->state = kSPI_Idle; +} + +status_t SPI_MasterTransferGetCountDMA(SPI_Type *base, spi_dma_handle_t *handle, size_t *count) +{ + assert(handle); + + if (!count) + { + return kStatus_InvalidArgument; + } + + /* Catch when there is not an active transfer. */ + if (handle->state != kSPI_Busy) + { + *count = 0; + return kStatus_NoTransferInProgress; + } + + size_t bytes; + + bytes = DMA_GetRemainingBytes(handle->rxHandle->base, handle->rxHandle->channel); + + *count = handle->transferSize - bytes; + + return kStatus_Success; +} diff --git a/platform/mcu/lpc54102/drivers/fsl_spi_dma.h b/platform/mcu/lpc54102/drivers/fsl_spi_dma.h new file mode 100644 index 0000000000..c93ea9e663 --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_spi_dma.h @@ -0,0 +1,224 @@ +/* + * Copyright (c) 2017, NXP Semiconductors, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_SPI_DMA_H_ +#define _FSL_SPI_DMA_H_ + +#include "fsl_dma.h" +#include "fsl_spi.h" + +/*! + * @addtogroup spi_dma_driver + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +typedef struct _spi_dma_handle spi_dma_handle_t; + +/*! @brief SPI DMA callback called at the end of transfer. */ +typedef void (*spi_dma_callback_t)(SPI_Type *base, spi_dma_handle_t *handle, status_t status, void *userData); + +/*! @brief SPI DMA transfer handle, users should not touch the content of the handle.*/ +struct _spi_dma_handle +{ + volatile bool txInProgress; /*!< Send transfer finished */ + volatile bool rxInProgress; /*!< Receive transfer finished */ + dma_handle_t *txHandle; /*!< DMA handler for SPI send */ + dma_handle_t *rxHandle; /*!< DMA handler for SPI receive */ + uint8_t bytesPerFrame; /*!< Bytes in a frame for SPI tranfer */ + spi_dma_callback_t callback; /*!< Callback for SPI DMA transfer */ + void *userData; /*!< User Data for SPI DMA callback */ + uint32_t state; /*!< Internal state of SPI DMA transfer */ + size_t transferSize; /*!< Bytes need to be transfer */ +}; + +/******************************************************************************* + * APIs + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @name DMA Transactional + * @{ + */ + +/*! + * @brief Initialize the SPI master DMA handle. + * + * This function initializes the SPI master DMA handle which can be used for other SPI master transactional APIs. + * Usually, for a specified SPI instance, user need only call this API once to get the initialized handle. + * + * @param base SPI peripheral base address. + * @param handle SPI handle pointer. + * @param callback User callback function called at the end of a transfer. + * @param userData User data for callback. + * @param txHandle DMA handle pointer for SPI Tx, the handle shall be static allocated by users. + * @param rxHandle DMA handle pointer for SPI Rx, the handle shall be static allocated by users. + */ +status_t SPI_MasterTransferCreateHandleDMA(SPI_Type *base, + spi_dma_handle_t *handle, + spi_dma_callback_t callback, + void *userData, + dma_handle_t *txHandle, + dma_handle_t *rxHandle); + +/*! + * @brief Perform a non-blocking SPI transfer using DMA. + * + * @note This interface returned immediately after transfer initiates, users should call + * SPI_GetTransferStatus to poll the transfer status to check whether SPI transfer finished. + * + * @param base SPI peripheral base address. + * @param handle SPI DMA handle pointer. + * @param xfer Pointer to dma transfer structure. + * @retval kStatus_Success Successfully start a transfer. + * @retval kStatus_InvalidArgument Input argument is invalid. + * @retval kStatus_SPI_Busy SPI is not idle, is running another transfer. + */ +status_t SPI_MasterTransferDMA(SPI_Type *base, spi_dma_handle_t *handle, spi_transfer_t *xfer); + +/*! + * @brief Transfers a block of data using a DMA method. + * + * This function using polling way to do the first half transimission and using DMA way to + * do the srcond half transimission, the transfer mechanism is half-duplex. + * When do the second half transimission, code will return right away. When all data is transferred, + * the callback function is called. + * + * @param base SPI base pointer + * @param handle A pointer to the spi_master_dma_handle_t structure which stores the transfer state. + * @param transfer A pointer to the spi_half_duplex_transfer_t structure. + * @return status of status_t. + */ +status_t SPI_MasterHalfDuplexTransferDMA(SPI_Type *base, spi_dma_handle_t *handle, spi_half_duplex_transfer_t *xfer); + +/*! + * @brief Initialize the SPI slave DMA handle. + * + * This function initializes the SPI slave DMA handle which can be used for other SPI master transactional APIs. + * Usually, for a specified SPI instance, user need only call this API once to get the initialized handle. + * + * @param base SPI peripheral base address. + * @param handle SPI handle pointer. + * @param callback User callback function called at the end of a transfer. + * @param userData User data for callback. + * @param txHandle DMA handle pointer for SPI Tx, the handle shall be static allocated by users. + * @param rxHandle DMA handle pointer for SPI Rx, the handle shall be static allocated by users. + */ +static inline status_t SPI_SlaveTransferCreateHandleDMA(SPI_Type *base, + spi_dma_handle_t *handle, + spi_dma_callback_t callback, + void *userData, + dma_handle_t *txHandle, + dma_handle_t *rxHandle) +{ + return SPI_MasterTransferCreateHandleDMA(base, handle, callback, userData, txHandle, rxHandle); +} + +/*! + * @brief Perform a non-blocking SPI transfer using DMA. + * + * @note This interface returned immediately after transfer initiates, users should call + * SPI_GetTransferStatus to poll the transfer status to check whether SPI transfer finished. + * + * @param base SPI peripheral base address. + * @param handle SPI DMA handle pointer. + * @param xfer Pointer to dma transfer structure. + * @retval kStatus_Success Successfully start a transfer. + * @retval kStatus_InvalidArgument Input argument is invalid. + * @retval kStatus_SPI_Busy SPI is not idle, is running another transfer. + */ +static inline status_t SPI_SlaveTransferDMA(SPI_Type *base, spi_dma_handle_t *handle, spi_transfer_t *xfer) +{ + return SPI_MasterTransferDMA(base, handle, xfer); +} + +/*! + * @brief Abort a SPI transfer using DMA. + * + * @param base SPI peripheral base address. + * @param handle SPI DMA handle pointer. + */ +void SPI_MasterTransferAbortDMA(SPI_Type *base, spi_dma_handle_t *handle); + +/*! + * @brief Gets the master DMA transfer remaining bytes. + * + * This function gets the master DMA transfer remaining bytes. + * + * @param base SPI peripheral base address. + * @param handle A pointer to the spi_dma_handle_t structure which stores the transfer state. + * @param count A number of bytes transferred by the non-blocking transaction. + * @return status of status_t. + */ +status_t SPI_MasterTransferGetCountDMA(SPI_Type *base, spi_dma_handle_t *handle, size_t *count); + +/*! + * @brief Abort a SPI transfer using DMA. + * + * @param base SPI peripheral base address. + * @param handle SPI DMA handle pointer. + */ +static inline void SPI_SlaveTransferAbortDMA(SPI_Type *base, spi_dma_handle_t *handle) +{ + SPI_MasterTransferAbortDMA(base, handle); +} + +/*! + * @brief Gets the slave DMA transfer remaining bytes. + * + * This function gets the slave DMA transfer remaining bytes. + * + * @param base SPI peripheral base address. + * @param handle A pointer to the spi_dma_handle_t structure which stores the transfer state. + * @param count A number of bytes transferred by the non-blocking transaction. + * @return status of status_t. + */ +static inline status_t SPI_SlaveTransferGetCountDMA(SPI_Type *base, spi_dma_handle_t *handle, size_t *count) +{ + return SPI_MasterTransferGetCountDMA(base, handle, count); +} + +/*! @} */ + +#if defined(__cplusplus) +} +#endif + +/*! @} */ + +#endif /* _FSL_SPI_DMA_H_*/ diff --git a/platform/mcu/lpc54102/drivers/fsl_usart.c b/platform/mcu/lpc54102/drivers/fsl_usart.c new file mode 100644 index 0000000000..20b2f94fa1 --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_usart.c @@ -0,0 +1,1252 @@ +/* + * Copyright (c) 2017, NXP Semiconductors, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_usart.h" + +enum _usart_transfer_states +{ + kUSART_TxIdle, /* TX idle. */ + kUSART_TxBusy, /* TX busy. */ + kUSART_RxIdle, /* RX idle. */ + kUSART_RxBusy /* RX busy. */ +}; + +/******************************************************************************* + * Variables + ******************************************************************************/ +/* Array of USART handle. */ +static usart_handle_t *s_usartHandle[FSL_FEATURE_SOC_USART_COUNT]; + +/*! @brief IRQ name array */ +static const IRQn_Type s_usartIRQ[] = USART_IRQS; + +/*! @brief Array to map USART instance number to base address. */ +static const uint32_t s_usartBaseAddrs[FSL_FEATURE_SOC_USART_COUNT] = USART_BASE_ADDRS; + +/* @brief Array to map USART instance number to CLOCK names */ +static const clock_ip_name_t s_usartClock[] = USART_CLOCKS; + +/* Typedef for interrupt handler. */ +typedef void (*usart_isr_t)(USART_Type *base, usart_handle_t *handle); + +/* USART ISR for transactional APIs. */ +static usart_isr_t s_usartIsr; + +/******************************************************************************* + * Code + ******************************************************************************/ + +/* Get the index corresponding to the USART */ +uint32_t USART_GetInstance(USART_Type *base) +{ + int i; + + for (i = 0; i < FSL_FEATURE_SOC_USART_COUNT; i++) + { + if ((uint32_t)base == s_usartBaseAddrs[i]) + { + return i; + } + } + + assert(false); + return 0; +} +/* Write one byte to TX register. */ +void USART_WriteByte(USART_Type *base, uint8_t data) +{ + uint32_t instance = USART_GetInstance(base); + if (USART_IsTxFifoEnable(base)) + { + VFIFO->USART[instance].TXDATUSART = data; + } + else + { + base->TXDAT = data; + } +} + +/* Read one byte from RX register. */ +uint8_t USART_ReadByte(USART_Type *base) +{ + uint32_t instance = USART_GetInstance(base); + return ((USART_IsRxFifoEnable(base)) ? (VFIFO->USART[instance].RXDATUSART) : (base->RXDAT & 0x000000FFU)); +} + +/* Get system FIFO USART status flags. */ +uint32_t USART_GetFifoStatusFlags(USART_Type *base) +{ + uint32_t instance = USART_GetInstance(base); + return (VFIFO->USART[instance].STATUSART); +} + +/* Clear system FIFO USART status flag. */ +void USART_ClearFifoStatusFlags(USART_Type *base, uint32_t mask) +{ + uint32_t instance = USART_GetInstance(base); + VFIFO->USART[instance].STATUSART |= mask; +} + +/* Enable system FIFO interrupts for USART. */ +void USART_EnableFifoInterrupts(USART_Type *base, uint32_t mask) +{ + uint32_t instance = USART_GetInstance(base); + VFIFO->USART[instance].CTLSETUSART |= mask; +} + +/* Disable FIFO interrupts for USART. */ +void USART_DisableFifoInterrupts(USART_Type *base, uint32_t mask) +{ + uint32_t instance = USART_GetInstance(base); + VFIFO->USART[instance].CTLCLRUSART |= mask; +} + +/* Get enabled interrupt of FIFO for USART. */ +uint32_t USART_GetEnabledFifoInterrupts(USART_Type *base) +{ + uint32_t instance = USART_GetInstance(base); + return (VFIFO->USART[instance].CTLSETUSART); +} + +/* Flush the FIFO for USART transfer. */ +void USART_FifoFlush(USART_Type *base, uint32_t direction) +{ + uint32_t instance = USART_GetInstance(base); + + if (kUSART_FifoTx & direction) + { + VFIFO->USART[instance].CTLSETUSART |= VFIFO_USART_CTLSETUSART_TXFLUSH_MASK; + VFIFO->USART[instance].CTLCLRUSART |= VFIFO_USART_CTLCLRUSART_TXFLUSHCLR_MASK; + } + + if (kUSART_FifoRx & direction) + { + VFIFO->USART[instance].CTLSETUSART |= VFIFO_USART_CTLSETUSART_RXFLUSH_MASK; + VFIFO->USART[instance].CTLCLRUSART |= VFIFO_USART_CTLCLRUSART_RXFLUSHCLR_MASK; + } +} + +/* Enable USART FIFO function. */ +void USART_EnableFifo(USART_Type *base, const usart_fifo_config_t *config) +{ + uint32_t instance = 0U; + + instance = USART_GetInstance(base); + + /* Enable the system FIFO clock. */ + CLOCK_EnableClock(kCLOCK_Fifo); + + /* Enable the TX/RX FIFO mode. */ + switch (instance) + { + case 0: + SYSCON->FIFOCTRL &= ~(SYSCON_FIFOCTRL_U0TXFIFOEN_MASK | SYSCON_FIFOCTRL_U0RXFIFOEN_MASK); + SYSCON->FIFOCTRL |= + SYSCON_FIFOCTRL_U0TXFIFOEN(config->enableTxFifo) | SYSCON_FIFOCTRL_U0RXFIFOEN(config->enableRxFifo); + break; + case 1: + SYSCON->FIFOCTRL &= ~(SYSCON_FIFOCTRL_U1TXFIFOEN_MASK | SYSCON_FIFOCTRL_U1RXFIFOEN_MASK); + SYSCON->FIFOCTRL |= + SYSCON_FIFOCTRL_U1TXFIFOEN(config->enableTxFifo) | SYSCON_FIFOCTRL_U1RXFIFOEN(config->enableRxFifo); + break; + case 2: + SYSCON->FIFOCTRL &= ~(SYSCON_FIFOCTRL_U2TXFIFOEN_MASK | SYSCON_FIFOCTRL_U2RXFIFOEN_MASK); + SYSCON->FIFOCTRL |= + SYSCON_FIFOCTRL_U2TXFIFOEN(config->enableTxFifo) | SYSCON_FIFOCTRL_U2RXFIFOEN(config->enableRxFifo); + break; + case 3: + SYSCON->FIFOCTRL &= ~(SYSCON_FIFOCTRL_U3TXFIFOEN_MASK | SYSCON_FIFOCTRL_U3RXFIFOEN_MASK); + SYSCON->FIFOCTRL |= + SYSCON_FIFOCTRL_U3TXFIFOEN(config->enableTxFifo) | SYSCON_FIFOCTRL_U3RXFIFOEN(config->enableRxFifo); + break; + default: + break; + } + /* Pause the USART FIFO for setting. */ + while (!((VFIFO->FIFOCTLUSART & VFIFO_FIFOCTLUSART_RXPAUSED_MASK) && + (VFIFO->FIFOCTLUSART & VFIFO_FIFOCTLUSART_TXPAUSED_MASK))) + { + VFIFO->FIFOCTLUSART |= (VFIFO_FIFOCTLUSART_RXPAUSE_MASK | VFIFO_FIFOCTLUSART_TXPAUSE_MASK); + } + /* Flush the TX and RX FIFO buffer. */ + USART_FifoFlush(base, kUSART_FifoTx | kUSART_FifoRx); + /* Set the TX and RX FIFO size. */ + VFIFO->FIFOCFGUSART[instance] = + VFIFO_FIFOCFGUSART_RXSIZE(config->rxFifoSize) | VFIFO_FIFOCFGUSART_TXSIZE(config->txFifoSize); + /* Set the TX and RX FIFO threshold size. */ + VFIFO->USART[instance].CFGUSART &= ~(VFIFO_USART_CFGUSART_RXTHRESHOLD_MASK | VFIFO_USART_CFGUSART_TXTHRESHOLD_MASK); + VFIFO->USART[instance].CFGUSART |= VFIFO_USART_CFGUSART_RXTHRESHOLD(config->rxFifoThreshold) | + VFIFO_USART_CFGUSART_TXTHRESHOLD(config->txFifoThreshold); + /* Update all the TX and RX fifo size. */ + VFIFO->FIFOUPDATEUSART |= + VFIFO_FIFOUPDATEUSART_USART0RXUPDATESIZE_MASK | VFIFO_FIFOUPDATEUSART_USART1RXUPDATESIZE_MASK | + VFIFO_FIFOUPDATEUSART_USART2RXUPDATESIZE_MASK | VFIFO_FIFOUPDATEUSART_USART3RXUPDATESIZE_MASK | + VFIFO_FIFOUPDATEUSART_USART0TXUPDATESIZE_MASK | VFIFO_FIFOUPDATEUSART_USART1TXUPDATESIZE_MASK | + VFIFO_FIFOUPDATEUSART_USART2TXUPDATESIZE_MASK | VFIFO_FIFOUPDATEUSART_USART3TXUPDATESIZE_MASK; + /* Unpause the system FIFO for transfer. */ + VFIFO->FIFOCTLUSART &= ~(VFIFO_FIFOCTLUSART_RXPAUSE_MASK | VFIFO_FIFOCTLUSART_TXPAUSE_MASK); +} + +void USART_DisableFifo(USART_Type *base) +{ + assert(NULL != base); + uint32_t instance = 0U; + + instance = USART_GetInstance(base); + + /* Pause the USART FIFO for setting. */ + while (!((VFIFO->FIFOCTLUSART & VFIFO_FIFOCTLUSART_RXPAUSED_MASK) && + (VFIFO->FIFOCTLUSART & VFIFO_FIFOCTLUSART_TXPAUSED_MASK))) + { + VFIFO->FIFOCTLUSART |= (VFIFO_FIFOCTLUSART_RXPAUSE_MASK | VFIFO_FIFOCTLUSART_TXPAUSE_MASK); + } + /* Flush the TX and RX FIFO buffer. */ + USART_FifoFlush(base, kUSART_FifoTx | kUSART_FifoRx); + /* Set the TX and RX FIFO size. */ + VFIFO->FIFOCFGUSART[instance] = VFIFO_FIFOCFGUSART_RXSIZE(0U) | VFIFO_FIFOCFGUSART_TXSIZE(0U); + /* Set the TX and RX FIFO threshold size. */ + VFIFO->USART[instance].CFGUSART &= ~(VFIFO_USART_CFGUSART_RXTHRESHOLD_MASK | VFIFO_USART_CFGUSART_TXTHRESHOLD_MASK); + /* Disable all FIFO interrupts. */ + USART_DisableFifoInterrupts(base, kUSART_FifoAllinterruptEnable); + /* Clear all FIFO status flags, only receive timeout and bus error flag can be cleared. */ + USART_ClearFifoStatusFlags(base, kUSART_RxFifoTimeOutFlag | kUSART_FifoBusErrorFlag); + + /* Unpause the system FIFO for transfer. */ + VFIFO->FIFOCTLUSART &= ~(VFIFO_FIFOCTLUSART_RXPAUSE_MASK | VFIFO_FIFOCTLUSART_TXPAUSE_MASK); + + /* Disable the TX/RX FIFO mode. */ + switch (instance) + { + case 0: + SYSCON->FIFOCTRL &= ~(SYSCON_FIFOCTRL_U0TXFIFOEN_MASK | SYSCON_FIFOCTRL_U0RXFIFOEN_MASK); + break; + case 1: + SYSCON->FIFOCTRL &= ~(SYSCON_FIFOCTRL_U1TXFIFOEN_MASK | SYSCON_FIFOCTRL_U1RXFIFOEN_MASK); + break; + case 2: + SYSCON->FIFOCTRL &= ~(SYSCON_FIFOCTRL_U2TXFIFOEN_MASK | SYSCON_FIFOCTRL_U2RXFIFOEN_MASK); + break; + case 3: + SYSCON->FIFOCTRL &= ~(SYSCON_FIFOCTRL_U3TXFIFOEN_MASK | SYSCON_FIFOCTRL_U3RXFIFOEN_MASK); + break; + default: + break; + } +} + +/* Check if TX FIFO enabled. */ +bool USART_IsTxFifoEnable(USART_Type *base) +{ + uint32_t instance = USART_GetInstance(base); + uint32_t fifosize = VFIFO->FIFOCFGUSART[instance]; + + /* Check if system FIFO control TX is enabled. */ + switch (instance) + { + case 0: + if (SYSCON->FIFOCTRL & SYSCON_FIFOCTRL_U0TXFIFOEN_MASK) + { + break; + } + else + { + return false; + } + case 1: + if (SYSCON->FIFOCTRL & SYSCON_FIFOCTRL_U1TXFIFOEN_MASK) + { + break; + } + else + { + return false; + } + case 2: + if (SYSCON->FIFOCTRL & SYSCON_FIFOCTRL_U2TXFIFOEN_MASK) + { + break; + } + else + { + return false; + } + case 3: + if (SYSCON->FIFOCTRL & SYSCON_FIFOCTRL_U3TXFIFOEN_MASK) + { + break; + } + else + { + return false; + } + default: + break; + } + + /* Check if TX FIFO size is available. */ + return (fifosize & VFIFO_FIFOCFGUSART_TXSIZE_MASK) ? (true) : (false); +} + +/* Check if RX FIFO enabled. */ +bool USART_IsRxFifoEnable(USART_Type *base) +{ + uint32_t instance = USART_GetInstance(base); + uint32_t fifosize = VFIFO->FIFOCFGUSART[instance]; + + /* Check if system FIFO control RX is enabled. */ + switch (instance) + { + case 0: + if (SYSCON->FIFOCTRL & SYSCON_FIFOCTRL_U0RXFIFOEN_MASK) + { + break; + } + else + { + return false; + } + case 1: + if (SYSCON->FIFOCTRL & SYSCON_FIFOCTRL_U1RXFIFOEN_MASK) + { + break; + } + else + { + return false; + } + case 2: + if (SYSCON->FIFOCTRL & SYSCON_FIFOCTRL_U2RXFIFOEN_MASK) + { + break; + } + else + { + return false; + } + case 3: + if (SYSCON->FIFOCTRL & SYSCON_FIFOCTRL_U3RXFIFOEN_MASK) + { + break; + } + else + { + return false; + } + default: + break; + } + + /* Check if RX FIFO size is available. */ + return (fifosize & VFIFO_FIFOCFGUSART_RXSIZE_MASK) ? (true) : (false); +} + +size_t USART_TransferGetRxRingBufferLength(usart_handle_t *handle) +{ + size_t size = 0U; + + /* Check arguments */ + assert(NULL != handle); + + if (handle->rxRingBufferTail > handle->rxRingBufferHead) + { + size = (size_t)(handle->rxRingBufferHead + handle->rxRingBufferSize - handle->rxRingBufferTail); + } + else + { + size = (size_t)(handle->rxRingBufferHead - handle->rxRingBufferTail); + } + return size; +} + +static bool USART_TransferIsRxRingBufferFull(usart_handle_t *handle) +{ + bool full = 0U; + + /* Check arguments */ + assert(NULL != handle); + + if (USART_TransferGetRxRingBufferLength(handle) == (handle->rxRingBufferSize - 1U)) + { + full = true; + } + else + { + full = false; + } + return full; +} + +void USART_TransferStartRingBuffer(USART_Type *base, usart_handle_t *handle, uint8_t *ringBuffer, size_t ringBufferSize) +{ + /* Check arguments */ + assert(NULL != base); + assert(NULL != handle); + assert(NULL != ringBuffer); + + /* Setup the ringbuffer address */ + handle->rxRingBuffer = ringBuffer; + handle->rxRingBufferSize = ringBufferSize; + handle->rxRingBufferHead = 0U; + handle->rxRingBufferTail = 0U; + + /* Ring buffer is ready we can start receiving data */ + if (handle->isRxFifoEnabled) + { + /* Start RX threshold interrupt for ring buffer to receive data. */ + USART_EnableFifoInterrupts(base, kUSART_RxFifoThresholdInterruptEnable); + } + else + { + /* Start receive data read interrupt and reveive overrun interrupt. */ + USART_EnableInterrupts(base, kUSART_RxReadyInterruptEnable | kUSART_HardwareOverRunInterruptEnable); + } +} + +void USART_TransferStopRingBuffer(USART_Type *base, usart_handle_t *handle) +{ + /* Check arguments */ + assert(NULL != base); + assert(NULL != handle); + + /* If USART is in idle state, dsiable the interrupts for ring buffer. */ + if (handle->rxState == kUSART_RxIdle) + { + if (handle->isRxFifoEnabled) + { + /* Disable FIFO RX threshold interrupt. */ + USART_DisableFifoInterrupts(base, kUSART_RxFifoThresholdInterruptEnable); + } + else + { + USART_DisableInterrupts(base, kUSART_RxReadyInterruptEnable | kUSART_HardwareOverRunInterruptEnable); + } + } + handle->rxRingBuffer = NULL; + handle->rxRingBufferSize = 0U; + handle->rxRingBufferHead = 0U; + handle->rxRingBufferTail = 0U; +} + +status_t USART_Init(USART_Type *base, const usart_config_t *config, uint32_t srcClock_Hz) +{ + int result = 0U; + + /* Check arguments */ + assert(!((NULL == base) || (NULL == config) || (0 == srcClock_Hz))); + if ((NULL == base) || (NULL == config) || (0 == srcClock_Hz)) + { + return kStatus_InvalidArgument; + } + + /* Enable usart clock and FRG clock */ + CLOCK_EnableClock(s_usartClock[USART_GetInstance(base)]); + CLOCK_EnableClock(kCLOCK_Frg); + + /* Setup configuration and enable USART to configure other register. */ + base->CFG = USART_CFG_PARITYSEL(config->parityMode) | USART_CFG_STOPLEN(config->stopBitCount) | + USART_CFG_DATALEN(config->bitCountPerChar) | USART_CFG_LOOP(config->loopback) | USART_CFG_ENABLE_MASK; + + /* Setup baudrate */ + result = USART_SetBaudRate(base, config->baudRate_Bps, srcClock_Hz); + if (kStatus_Success != result) + { + return result; + } + + /* Check if FIFO is enabled from extern configuration. */ + if ((config->fifoConfig.enableTxFifo) || (config->fifoConfig.enableRxFifo)) + { + USART_EnableFifo(base, &config->fifoConfig); + } + /* Setup the USART transmit and receive. */ + USART_EnableTx(base, config->enableTx); + USART_EnableRx(base, config->enableRx); + + return kStatus_Success; +} + +void USART_Deinit(USART_Type *base) +{ + /* Check arguments */ + assert(NULL != base); + /* Wait for data transmit complete. */ + while (!(base->STAT & USART_STAT_TXIDLE_MASK)) + { + } + if ((USART_IsTxFifoEnable(base)) || (USART_IsRxFifoEnable(base))) + { + USART_DisableFifo(base); + } + /* Disable the USART module. */ + base->CFG &= ~(USART_CFG_ENABLE_MASK); + /* Disbable the clock for usart */ + CLOCK_DisableClock(s_usartClock[USART_GetInstance(base)]); +} + +void USART_GetDefaultConfig(usart_config_t *config) +{ + /* Check arguments */ + assert(NULL != config); + + /* Set always all members ! */ + config->baudRate_Bps = 115200U; + config->parityMode = kUSART_ParityDisabled; + config->stopBitCount = kUSART_OneStopBit; + config->bitCountPerChar = kUSART_8BitsPerChar; + config->loopback = false; + config->enableRx = false; + config->enableTx = false; + config->fifoConfig.enableTxFifo = false; + config->fifoConfig.enableRxFifo = false; + config->fifoConfig.rxFifoSize = 16U; + config->fifoConfig.txFifoSize = 16U; + config->fifoConfig.txFifoThreshold = 0U; + config->fifoConfig.rxFifoThreshold = 0U; +} + +status_t USART_SetBaudRate(USART_Type *base, uint32_t baudrate_Bps, uint32_t srcClock_Hz) +{ + uint32_t best_diff = (uint32_t)-1, best_osrval = 0xf, best_brgval = (uint32_t)-1; + uint32_t osrval, brgval, diff, baudrate; + + /* check arguments */ + assert(!((NULL == base) || (0 == baudrate_Bps) || (0 == srcClock_Hz))); + if ((NULL == base) || (0 == baudrate_Bps) || (0 == srcClock_Hz)) + { + return kStatus_InvalidArgument; + } + + /* + * Smaller values of OSR can make the sampling position within a data bit less accurate and may + * potentially cause more noise errors or incorrect data. + */ + for (osrval = best_osrval; osrval >= 8; osrval--) + { + brgval = (srcClock_Hz / ((osrval + 1) * baudrate_Bps)) - 1; + if (brgval > 0xFFFF) + { + continue; + } + baudrate = srcClock_Hz / ((osrval + 1) * (brgval + 1)); + diff = baudrate_Bps < baudrate ? baudrate - baudrate_Bps : baudrate_Bps - baudrate; + if (diff < best_diff) + { + best_diff = diff; + best_osrval = osrval; + best_brgval = brgval; + } + } + + /* value over range */ + if (best_brgval > 0xFFFF) + { + return kStatus_USART_BaudrateNotSupport; + } + + base->OSR = best_osrval; + base->BRG = best_brgval; + return kStatus_Success; +} + +void USART_WriteBlocking(USART_Type *base, const uint8_t *data, size_t length) +{ + uint32_t instance = 0U; + /* Check arguments */ + assert(!((NULL == base) || (NULL == data))); + if ((NULL == base) || (NULL == data)) + { + return; + } + + instance = USART_GetInstance(base); + + for (; length > 0; length--) + { + if (USART_IsTxFifoEnable(base)) + { + /* Loop until TX FIFO is empty for new data */ + while (!(VFIFO->USART[instance].STATUSART & VFIFO_USART_STATUSART_TXEMPTY_MASK)) + { + } + VFIFO->USART[instance].TXDATUSART = *data; + } + else + { + /* Wait for TX is ready to transmit new data. */ + while (!(base->STAT & USART_STAT_TXRDY_MASK)) + { + } + base->TXDAT = *data; + } + data++; + } + /* Wait to finish transfer */ + while (!(base->STAT & USART_STAT_TXIDLE_MASK)) + { + } +} + +status_t USART_ReadBlocking(USART_Type *base, uint8_t *data, size_t length) +{ + uint32_t status; + uint32_t instance = 0U; + + /* Check arguments */ + assert(!((NULL == base) || (NULL == data))); + if ((NULL == base) || (NULL == data)) + { + return kStatus_InvalidArgument; + } + + instance = USART_GetInstance(base); + + for (; length > 0; length--) + { + if (USART_IsRxFifoEnable(base)) + { + /* Wait for RX FIFO is not empty. */ + while ((VFIFO->USART[instance].STATUSART & VFIFO_USART_STATUSART_RXEMPTY_MASK)) + { + } + /* Check FIFO receive status. */ + status = VFIFO->USART[instance].STATUSART; + if (status & VFIFO_USART_STATUSART_BUSERR_MASK) + { + return kStatus_USART_FifoBusError; + } + status = VFIFO->USART[instance].RXDATSTATUSART; + if (status & VFIFO_USART_RXDATSTATUSART_FRAMERR_MASK) + { + return kStatus_USART_FramingError; + } + if (status & VFIFO_USART_RXDATSTATUSART_PARITYERR_MASK) + { + return kStatus_USART_ParityError; + } + if (status & VFIFO_USART_RXDATSTATUSART_RXNOISE_MASK) + { + return kStatus_USART_NoiseError; + } + *data = (status & VFIFO_USART_RXDATSTATUSART_RXDAT_MASK); + } + else + { + /* loop until receive is ready to read */ + while (!(base->STAT & USART_STAT_RXRDY_MASK)) + { + } + + /* Check receive status */ + status = base->STAT; + + if (status & USART_STAT_FRAMERRINT_MASK) + { + base->STAT |= USART_STAT_FRAMERRINT_MASK; + return kStatus_USART_FramingError; + } + if (status & USART_STAT_PARITYERRINT_MASK) + { + base->STAT |= USART_STAT_PARITYERRINT_MASK; + return kStatus_USART_ParityError; + } + if (status & USART_STAT_RXNOISEINT_MASK) + { + base->STAT |= USART_STAT_RXNOISEINT_MASK; + return kStatus_USART_NoiseError; + } + if (base->STAT & USART_STAT_OVERRUNINT_MASK) + { + base->STAT |= USART_STAT_OVERRUNINT_MASK; + return kStatus_USART_HardwareOverrun; + } + *data = base->RXDAT; + } + data++; + } + return 0; +} + +status_t USART_TransferCreateHandle(USART_Type *base, + usart_handle_t *handle, + usart_transfer_callback_t callback, + void *userData) +{ + int32_t instance = 0; + + /* Check 'base' */ + assert(!((NULL == base) || (NULL == handle))); + if ((NULL == base) || (NULL == handle)) + { + return kStatus_InvalidArgument; + } + + instance = USART_GetInstance(base); + + memset(handle, 0, sizeof(*handle)); + /* Set the TX/RX state. */ + handle->rxState = kUSART_RxIdle; + handle->txState = kUSART_TxIdle; + /* Set the callback and user data. */ + handle->callback = callback; + handle->userData = userData; + /* Check if TX/RX FIFO are enabled. */ + handle->isTxFifoEnabled = USART_IsTxFifoEnable(base); + handle->isRxFifoEnabled = USART_IsRxFifoEnable(base); + if ((handle->isTxFifoEnabled) || (handle->isRxFifoEnabled)) + { + handle->rxFifoThreshold = (VFIFO->USART[instance].CFGUSART & VFIFO_USART_CFGUSART_RXTHRESHOLD_MASK) >> + VFIFO_USART_CFGUSART_RXTHRESHOLD_SHIFT; + handle->txFifoThreshold = (VFIFO->USART[instance].CFGUSART & VFIFO_USART_CFGUSART_TXTHRESHOLD_MASK) >> + VFIFO_USART_CFGUSART_TXTHRESHOLD_SHIFT; + } + /* Store the handle data to global variables. */ + s_usartHandle[instance] = handle; + /* Mapping the interrupt function. */ + s_usartIsr = USART_TransferHandleIRQ; + + /* Enable interrupt in NVIC. */ + EnableIRQ(s_usartIRQ[instance]); + + return kStatus_Success; +} + +status_t USART_TransferSendNonBlocking(USART_Type *base, usart_handle_t *handle, usart_transfer_t *xfer) +{ + /* Check arguments */ + assert(!((NULL == base) || (NULL == handle) || (NULL == xfer))); + if ((NULL == base) || (NULL == handle) || (NULL == xfer)) + { + return kStatus_InvalidArgument; + } + /* Check xfer members */ + assert(!((0 == xfer->dataSize) || (NULL == xfer->data))); + if ((0 == xfer->dataSize) || (NULL == xfer->data)) + { + return kStatus_InvalidArgument; + } + uint32_t instance = USART_GetInstance(base); + + /* Return error if current TX busy. */ + if (kUSART_TxBusy == handle->txState) + { + return kStatus_USART_TxBusy; + } + else + { + handle->txData = xfer->data; + handle->txDataSize = xfer->dataSize; + handle->txDataSizeAll = xfer->dataSize; + handle->txState = kUSART_TxBusy; + /* Check if TX/RX FIFO are enabled. */ + handle->isTxFifoEnabled = USART_IsTxFifoEnable(base); + handle->isRxFifoEnabled = USART_IsRxFifoEnable(base); + if ((handle->isTxFifoEnabled) || (handle->isRxFifoEnabled)) + { + handle->rxFifoThreshold = (VFIFO->USART[instance].CFGUSART & VFIFO_USART_CFGUSART_RXTHRESHOLD_MASK) >> + VFIFO_USART_CFGUSART_RXTHRESHOLD_SHIFT; + handle->txFifoThreshold = (VFIFO->USART[instance].CFGUSART & VFIFO_USART_CFGUSART_TXTHRESHOLD_MASK) >> + VFIFO_USART_CFGUSART_TXTHRESHOLD_SHIFT; + } + /* Enable transmiter interrupt. */ + if (handle->isTxFifoEnabled) + { + /* Start system fifo usart tx threshold interrupt. */ + USART_EnableFifoInterrupts(base, kUSART_TxFifoThresholdInterruptEnable); + } + else + { + USART_EnableInterrupts(base, kUSART_TxReadyInterruptEnable); + /* Clear transmit disable bit. */ + base->CTL &= ~USART_CTL_TXDIS_MASK; + } + } + return kStatus_Success; +} + +void USART_TransferAbortSend(USART_Type *base, usart_handle_t *handle) +{ + assert(NULL != handle); + + /* Disable interrupts */ + if (handle->isTxFifoEnabled) + { + /* Disable system fifo usart tx threshold interrupt. */ + USART_DisableFifoInterrupts(base, kUSART_TxFifoThresholdInterruptEnable); + } + else + { + USART_DisableInterrupts(base, kUSART_TxReadyInterruptEnable); + } + /* Disable transmit after data being transmitted. */ + USART_EnableTx(base, false); + + handle->txDataSize = 0; + handle->txState = kUSART_TxIdle; +} + +status_t USART_TransferGetSendCount(USART_Type *base, usart_handle_t *handle, uint32_t *count) +{ + assert(NULL != handle); + assert(NULL != count); + + if (kUSART_TxIdle == handle->txState) + { + return kStatus_NoTransferInProgress; + } + + *count = handle->txDataSizeAll - handle->txDataSize; + + return kStatus_Success; +} + +status_t USART_TransferReceiveNonBlocking(USART_Type *base, + usart_handle_t *handle, + usart_transfer_t *xfer, + size_t *receivedBytes) +{ + uint32_t i; + /* How many bytes to copy from ring buffer to user memory. */ + size_t bytesToCopy = 0U; + /* How many bytes to receive. */ + size_t bytesToReceive; + /* How many bytes currently have received. */ + size_t bytesCurrentReceived; + uint32_t instance = USART_GetInstance(base); + + /* Check arguments */ + assert(!((NULL == base) || (NULL == handle) || (NULL == xfer))); + if ((NULL == base) || (NULL == handle) || (NULL == xfer)) + { + return kStatus_InvalidArgument; + } + /* Check xfer members */ + assert(!((0 == xfer->dataSize) || (NULL == xfer->data))); + if ((0 == xfer->dataSize) || (NULL == xfer->data)) + { + return kStatus_InvalidArgument; + } + + /* How to get data: + 1. If RX ring buffer is not enabled, then save xfer->data and xfer->dataSize + to uart handle, enable interrupt to store received data to xfer->data. When + all data received, trigger callback. + 2. If RX ring buffer is enabled and not empty, get data from ring buffer first. + If there are enough data in ring buffer, copy them to xfer->data and return. + If there are not enough data in ring buffer, copy all of them to xfer->data, + save the xfer->data remained empty space to uart handle, receive data + to this empty space and trigger callback when finished. */ + if (kUSART_RxBusy == handle->rxState) + { + return kStatus_USART_RxBusy; + } + else + { + /* Check if TX/RX FIFO are enabled. */ + handle->isTxFifoEnabled = USART_IsTxFifoEnable(base); + handle->isRxFifoEnabled = USART_IsRxFifoEnable(base); + if ((handle->isTxFifoEnabled) || (handle->isRxFifoEnabled)) + { + handle->rxFifoThreshold = (VFIFO->USART[instance].CFGUSART & VFIFO_USART_CFGUSART_RXTHRESHOLD_MASK) >> + VFIFO_USART_CFGUSART_RXTHRESHOLD_SHIFT; + handle->txFifoThreshold = (VFIFO->USART[instance].CFGUSART & VFIFO_USART_CFGUSART_TXTHRESHOLD_MASK) >> + VFIFO_USART_CFGUSART_TXTHRESHOLD_SHIFT; + } + + bytesToReceive = xfer->dataSize; + bytesCurrentReceived = 0U; + /* If RX ring buffer is used. */ + if (handle->rxRingBuffer) + { + /* Disable USART receive IRQ, protect ring buffer. */ + if (handle->isRxFifoEnabled) + { + /* Disable system fifo usart rx threshold interrupt. */ + USART_DisableFifoInterrupts(base, kUSART_RxFifoThresholdInterruptEnable); + } + else + { + USART_DisableInterrupts(base, kUSART_RxReadyInterruptEnable); + } + /* How many bytes in RX ring buffer currently. */ + bytesToCopy = USART_TransferGetRxRingBufferLength(handle); + if (bytesToCopy) + { + bytesToCopy = MIN(bytesToReceive, bytesToCopy); + bytesToReceive -= bytesToCopy; + /* Copy data from ring buffer to user memory. */ + for (i = 0U; i < bytesToCopy; i++) + { + xfer->data[bytesCurrentReceived++] = handle->rxRingBuffer[handle->rxRingBufferTail]; + /* Wrap to 0. Not use modulo (%) because it might be large and slow. */ + if (handle->rxRingBufferTail + 1U == handle->rxRingBufferSize) + { + handle->rxRingBufferTail = 0U; + } + else + { + handle->rxRingBufferTail++; + } + } + } + /* If ring buffer does not have enough data, still need to read more data. */ + if (bytesToReceive) + { + /* No data in ring buffer, save the request to UART handle. */ + handle->rxData = xfer->data + bytesCurrentReceived; + handle->rxDataSize = bytesToReceive; + handle->rxDataSizeAll = bytesToReceive; + handle->rxState = kUSART_RxBusy; + } + /* Enable USART receive interrupt for next transfer. */ + if (handle->isRxFifoEnabled) + { + /* Enable system fifo usart rx threshold interrupt. */ + USART_EnableFifoInterrupts(base, kUSART_RxFifoThresholdInterruptEnable); + } + else + { + USART_EnableInterrupts(base, kUSART_RxReadyInterruptEnable); + } + /* Call user callback since all data are received. */ + if (0 == bytesToReceive) + { + if (handle->callback) + { + handle->callback(base, handle, kStatus_USART_RxIdle, handle->userData); + } + } + } + /* Ring buffer not used. */ + else + { + handle->rxData = xfer->data + bytesCurrentReceived; + handle->rxDataSize = bytesToReceive; + handle->rxDataSizeAll = bytesToReceive; + handle->rxState = kUSART_RxBusy; + + /* Enable RX interrupt. */ + if (handle->isRxFifoEnabled) + { + USART_EnableFifoInterrupts(base, kUSART_RxFifoThresholdInterruptEnable); + } + else + { + USART_EnableInterrupts(base, kUSART_RxReadyInterruptEnable | kUSART_HardwareOverRunInterruptEnable); + } + } + /* Return the how many bytes have read. */ + if (receivedBytes) + { + *receivedBytes = bytesCurrentReceived; + } + } + return kStatus_Success; +} + +void USART_TransferAbortReceive(USART_Type *base, usart_handle_t *handle) +{ + assert(NULL != handle); + + /* Only abort the receive to handle->rxData, the RX ring buffer is still working. */ + if (!handle->rxRingBuffer) + { + /* Disable interrupts */ + if (handle->isRxFifoEnabled) + { + USART_DisableFifoInterrupts(base, kUSART_RxFifoThresholdInterruptEnable); + } + else + { + USART_DisableInterrupts(base, kUSART_RxReadyInterruptEnable | kUSART_HardwareOverRunInterruptEnable); + } + } + + handle->rxDataSize = 0U; + handle->rxState = kUSART_RxIdle; +} + +status_t USART_TransferGetReceiveCount(USART_Type *base, usart_handle_t *handle, uint32_t *count) +{ + assert(NULL != handle); + assert(NULL != count); + + if (kUSART_RxIdle == handle->rxState) + { + return kStatus_NoTransferInProgress; + } + + *count = handle->rxDataSizeAll - handle->rxDataSize; + + return kStatus_Success; +} + +void USART_TransferHandleIRQ(USART_Type *base, usart_handle_t *handle) +{ + /* Check arguments */ + assert((NULL != base) && (NULL != handle)); + + bool receiveEnabled = (handle->rxDataSize) || (handle->rxRingBuffer); + bool sendEnabled = handle->txDataSize; + uint32_t instance = USART_GetInstance(base); + + /* If RX overrun. */ + if (base->STAT & USART_STAT_OVERRUNINT_MASK) + { + /* Clear rx error state. */ + base->STAT |= USART_STAT_OVERRUNINT_MASK; + /* Trigger callback. */ + if (handle->callback) + { + handle->callback(base, handle, kStatus_USART_RxError, handle->userData); + } + } + if ((receiveEnabled && + ((handle->isRxFifoEnabled) ? (VFIFO->USART[instance].INTSTATUSART & VFIFO_USART_INTSTATUSART_RXTH_MASK) : + (base->STAT & USART_STAT_RXRDY_MASK))) || + (sendEnabled && + ((handle->isTxFifoEnabled) ? (VFIFO->USART[instance].INTSTATUSART & VFIFO_USART_INTSTATUSART_TXTH_MASK) : + (base->STAT & USART_STAT_TXRDY_MASK)))) + { + /* Receive data */ + if ((receiveEnabled) && + ((handle->isRxFifoEnabled) ? (VFIFO->USART[instance].INTSTATUSART & VFIFO_USART_INTSTATUSART_RXTH_MASK) : + (base->STAT & USART_STAT_RXRDY_MASK))) + { + /* Receive to app bufffer if app buffer is present */ + if ((handle->rxDataSize)) + { + if (handle->isRxFifoEnabled) + { + uint8_t dataToReceive = handle->rxFifoThreshold + 1; + do + { + *handle->rxData = VFIFO->USART[instance].RXDATUSART; + handle->rxDataSize--; + handle->rxData++; + receiveEnabled = ((handle->rxDataSize != 0) || (handle->rxRingBuffer)); + } while ((--dataToReceive) && (handle->rxDataSize)); + } + else + { + *handle->rxData = base->RXDAT; + handle->rxDataSize--; + handle->rxData++; + receiveEnabled = ((handle->rxDataSize != 0) || (handle->rxRingBuffer)); + } + + if (!handle->rxDataSize) + { + if (!handle->rxRingBuffer) + { + /* If system FIFO enabled. */ + if (handle->isRxFifoEnabled) + { + /* Disable system fifo usart rx threshold interrupt. */ + USART_DisableFifoInterrupts(base, kUSART_RxFifoThresholdInterruptEnable); + } + else + { + USART_DisableInterrupts( + base, kUSART_RxReadyInterruptEnable | kUSART_HardwareOverRunInterruptEnable); + } + } + handle->rxState = kUSART_RxIdle; + if (handle->callback) + { + handle->callback(base, handle, kStatus_USART_RxIdle, handle->userData); + } + } + } + /* Otherwise receive to ring buffer if ring buffer is present */ + else + { + if (handle->rxRingBuffer) + { + uint8_t count = (handle->isRxFifoEnabled) ? (handle->rxFifoThreshold + 1) : (1U); + /* If RX ring buffer is full, trigger callback to notify over run. */ + while (count--) + { + if (USART_TransferIsRxRingBufferFull(handle)) + { + if (handle->callback) + { + handle->callback(base, handle, kStatus_USART_RxRingBufferOverrun, handle->userData); + } + } + /* If ring buffer is still full after callback function, the oldest data is overrided. */ + if (USART_TransferIsRxRingBufferFull(handle)) + { + /* Increase handle->rxRingBufferTail to make room for new data. */ + if (handle->rxRingBufferTail + 1U == handle->rxRingBufferSize) + { + handle->rxRingBufferTail = 0U; + } + else + { + handle->rxRingBufferTail++; + } + } + /* Read data. */ + if (handle->isRxFifoEnabled) + { + handle->rxRingBuffer[handle->rxRingBufferHead] = VFIFO->USART[instance].RXDATUSART; + } + else + { + handle->rxRingBuffer[handle->rxRingBufferHead] = base->RXDAT; + } + /* Increase handle->rxRingBufferHead. */ + if (handle->rxRingBufferHead + 1U == handle->rxRingBufferSize) + { + handle->rxRingBufferHead = 0U; + } + else + { + handle->rxRingBufferHead++; + } + } + } + } + } + /* Send data */ + if (sendEnabled && + ((handle->isTxFifoEnabled) ? (VFIFO->USART[instance].INTSTATUSART & VFIFO_USART_INTSTATUSART_TXTH_MASK) : + (base->STAT & USART_STAT_TXRDY_MASK))) + { + /* Send data. */ + if (handle->isTxFifoEnabled) + { + uint8_t dataToSend = (handle->txFifoThreshold) ? (handle->txFifoThreshold) : (1U); + do + { + VFIFO->USART[instance].TXDATUSART = *handle->txData; + handle->txDataSize--; + handle->txData++; + sendEnabled = handle->txDataSize; + } while ((--dataToSend) && (sendEnabled)); + } + else + { + base->TXDAT = *handle->txData; + handle->txDataSize--; + handle->txData++; + sendEnabled = handle->txDataSize != 0; + } + + if (!sendEnabled) + { + /* Disable interrupts */ + if (handle->isTxFifoEnabled) + { + USART_DisableFifoInterrupts(base, kUSART_TxFifoThresholdInterruptEnable); + } + else + { + USART_DisableInterrupts(base, kUSART_TxReadyInterruptEnable); + } + handle->txState = kUSART_TxIdle; + if (handle->callback) + { + handle->callback(base, handle, kStatus_USART_TxIdle, handle->userData); + } + } + } + } + + /* Ring buffer is not used */ + if ((NULL == handle->rxRingBuffer) && (handle->isRxFifoEnabled)) + { + /* Restore if rx transfer ends and rxLevel is different from default value */ + if ((handle->rxDataSize == 0) && (((VFIFO->USART[instance].CFGUSART & VFIFO_USART_CFGUSART_RXTHRESHOLD_MASK) >> + VFIFO_USART_CFGUSART_RXTHRESHOLD_SHIFT) != handle->rxFifoThreshold)) + { + VFIFO->USART[instance].CFGUSART = + ((VFIFO->USART[instance].CFGUSART & (~VFIFO_USART_CFGUSART_RXTHRESHOLD_MASK)) | + VFIFO_USART_CFGUSART_RXTHRESHOLD(handle->rxFifoThreshold)); + } + /* Decrease level if rx transfer is bellow */ + if ((handle->rxDataSize != 0) && + (handle->rxDataSize <= (VFIFO->USART[instance].CFGUSART & VFIFO_USART_CFGUSART_RXTHRESHOLD_MASK) >> + VFIFO_USART_CFGUSART_RXTHRESHOLD_SHIFT)) + { + VFIFO->USART[instance].CFGUSART = + ((VFIFO->USART[instance].CFGUSART & (~VFIFO_USART_CFGUSART_RXTHRESHOLD_MASK)) | + VFIFO_USART_CFGUSART_RXTHRESHOLD(handle->rxDataSize - 1)); + } + } +} + +#if defined(USART0) +void USART0_DriverIRQHandler(void) +{ + s_usartIsr(USART0, s_usartHandle[0]); + /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif + +#if defined(USART1) +void USART1_DriverIRQHandler(void) +{ + s_usartIsr(USART1, s_usartHandle[1]); + /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif + +#if defined(USART2) +void USART2_DriverIRQHandler(void) +{ + s_usartIsr(USART2, s_usartHandle[2]); + /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif + +#if defined(USART3) +void USART3_DriverIRQHandler(void) +{ + s_usartIsr(USART3, s_usartHandle[3]); + /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif diff --git a/platform/mcu/lpc54102/drivers/fsl_usart.h b/platform/mcu/lpc54102/drivers/fsl_usart.h new file mode 100644 index 0000000000..55285a19ae --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_usart.h @@ -0,0 +1,852 @@ +/* + * Copyright (c) 2017, NXP Semiconductors, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_USART_H_ +#define _FSL_USART_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup usart_driver + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief USART driver version 2.0.0. */ +#define FSL_USART_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*@}*/ + +/*! @brief Error codes for the USART driver. */ +enum _usart_status +{ + kStatus_USART_TxBusy = MAKE_STATUS(kStatusGroup_LPC_USART, 0), /*!< Transmitter is busy. */ + kStatus_USART_RxBusy = MAKE_STATUS(kStatusGroup_LPC_USART, 1), /*!< Receiver is busy. */ + kStatus_USART_TxIdle = MAKE_STATUS(kStatusGroup_LPC_USART, 2), /*!< USART transmitter is idle. */ + kStatus_USART_RxIdle = MAKE_STATUS(kStatusGroup_LPC_USART, 3), /*!< USART receiver is idle. */ + kStatus_USART_TxError = MAKE_STATUS(kStatusGroup_LPC_USART, 7), /*!< Error happens on txFIFO. */ + kStatus_USART_RxError = MAKE_STATUS(kStatusGroup_LPC_USART, 9), /*!< Error happens on rxFIFO. */ + kStatus_USART_RxRingBufferOverrun = MAKE_STATUS(kStatusGroup_LPC_USART, 8), /*!< Error happens on rx ring buffer */ + kStatus_USART_NoiseError = MAKE_STATUS(kStatusGroup_LPC_USART, 10), /*!< USART noise error. */ + kStatus_USART_FramingError = MAKE_STATUS(kStatusGroup_LPC_USART, 11), /*!< USART framing error. */ + kStatus_USART_ParityError = MAKE_STATUS(kStatusGroup_LPC_USART, 12), /*!< USART parity error. */ + kStatus_USART_HardwareOverrun = MAKE_STATUS(kStatusGroup_LPC_USART, 13), /*!< USART hardware over flow. */ + kStatus_USART_FifoBusError = MAKE_STATUS(kStatusGroup_LPC_USART, 14), /*!< USART fifo bus error. */ + kStatus_USART_BaudrateNotSupport = + MAKE_STATUS(kStatusGroup_LPC_USART, 15), /*!< Baudrate is not support in current clock source */ +}; + +/*! @brief USART parity mode. */ +typedef enum _usart_parity_mode +{ + kUSART_ParityDisabled = 0x0U, /*!< Parity disabled */ + kUSART_ParityEven = 0x2U, /*!< Parity enabled, type even, bit setting: PE|PT = 10 */ + kUSART_ParityOdd = 0x3U, /*!< Parity enabled, type odd, bit setting: PE|PT = 11 */ +} usart_parity_mode_t; + +/*! @brief USART stop bit count. */ +typedef enum _usart_stop_bit_count +{ + kUSART_OneStopBit = 0U, /*!< One stop bit */ + kUSART_TwoStopBit = 1U, /*!< Two stop bits */ +} usart_stop_bit_count_t; + +/*! @brief USART data size. */ +typedef enum _usart_data_len +{ + kUSART_7BitsPerChar = 0U, /*!< Seven bit mode */ + kUSART_8BitsPerChar = 1U, /*!< Eight bit mode */ +} usart_data_len_t; + +/*! @brief USART FIFO driection. */ +typedef enum _usart_fifo_direction +{ + kUSART_FifoTx = 1U, /*!< FIFO direction for transmit. */ + kUSART_FifoRx = 2U, /*!< FIFO direction for receive. */ +} usart_fifo_direction_t; + +/*! + * @brief USART interrupt configuration structure, default settings all disabled. + */ +enum _usart_interrupt_enable +{ + kUSART_RxReadyInterruptEnable = (USART_INTENSET_RXRDYEN_MASK), /*!< Receive ready interrupt. */ + kUSART_TxReadyInterruptEnable = (USART_INTENSET_TXRDYEN_MASK), /*!< Transmit ready interrupt. */ + kUSART_TxIdleInterruptEnable = (USART_INTENSET_TXIDLEEN_MASK), /*!< Transmit idle interrupt. */ + kUSART_DeltaCtsInterruptEnable = (USART_INTENSET_DELTACTSEN_MASK), /*!< Cts pin change interrupt. */ + kUSART_TxDisableInterruptEnable = (USART_INTENSET_TXDISEN_MASK), /*!< Transmit disable interrupt. */ + kUSART_HardwareOverRunInterruptEnable = (USART_INTENSET_OVERRUNEN_MASK), /*!< hardware ove run interrupt. */ + kUSART_RxBreakInterruptEnable = (USART_INTENSET_DELTARXBRKEN_MASK), /*!< Receive break interrupt. */ + kUSART_RxStartInterruptEnable = (USART_INTENSET_STARTEN_MASK), /*!< Receive ready interrupt. */ + kUSART_FramErrorInterruptEnable = (USART_INTENSET_FRAMERREN_MASK), /*!< Receive start interrupt. */ + kUSART_ParityErrorInterruptEnable = (USART_INTENSET_PARITYERREN_MASK), /*!< Receive frame error interrupt. */ + kUSART_RxNoiseInterruptEnable = (USART_INTENSET_RXNOISEEN_MASK), /*!< Receive noise error interrupt. */ + kUSART_AutoBaudErrorInterruptEnable = (USART_INTENSET_ABERREN_MASK), /*!< Receive auto baud error interrupt. */ + kUSART_AllInterruptEnable = + (USART_INTENSET_RXRDYEN_MASK | USART_INTENSET_TXRDYEN_MASK | USART_INTENSET_TXIDLEEN_MASK | + USART_INTENSET_DELTACTSEN_MASK | USART_INTENSET_TXDISEN_MASK | USART_INTENSET_OVERRUNEN_MASK | + USART_INTENSET_DELTARXBRKEN_MASK | USART_INTENSET_STARTEN_MASK | USART_INTENSET_FRAMERREN_MASK | + USART_INTENSET_PARITYERREN_MASK | USART_INTENSET_RXNOISEEN_MASK | + USART_INTENSET_ABERREN_MASK), /*!< All interrupt. */ +}; + +/*! + * @brief System FIFO interrupt configuration structure for USART, default settings all disabled. + */ +enum _usart_fifo_interrupt_enable +{ + kUSART_RxFifoThresholdInterruptEnable = + (VFIFO_USART_CTLSETUSART_RXTHINTEN_MASK), /*!< Receive FIFO threshold interrupt. */ + kUSART_TxFifoThresholdInterruptEnable = + (VFIFO_USART_CTLSETUSART_TXTHINTEN_MASK), /*!< Transmit FIFO threshold interrupt. */ + kUSART_RxFifoTimeOutInterruptEnable = + (VFIFO_USART_CTLSETUSART_RXTIMEOUTINTEN_MASK), /*!< Receive FIFO timeout interrupt. */ + kUSART_FifoAllinterruptEnable = (VFIFO_USART_CTLSETUSART_RXTHINTEN_MASK | VFIFO_USART_CTLSETUSART_TXTHINTEN_MASK | + VFIFO_USART_CTLSETUSART_RXTIMEOUTINTEN_MASK), /*!< All FIFO interrupt. */ +}; + +/*! + * @brief USART status flags. + * + * This provides constants for the USART status flags for use in the USART functions. + */ +enum _usart_flags +{ + kUSART_RxReady = (USART_STAT_RXRDY_MASK), /*!< Receive ready flag. */ + kUSART_RxIdleFlag = (USART_STAT_RXIDLE_MASK), /*!< Receive IDLE flag. */ + kUSART_TxReady = (USART_STAT_TXRDY_MASK), /*!< Transmit ready flag. */ + kUSART_TxIdleFlag = (USART_STAT_TXIDLE_MASK), /*!< Transmit idle flag. */ + kUSART_CtsState = (USART_STAT_CTS_MASK), /*!< Cts pin status. */ + kUSART_DeltaCtsFlag = (USART_STAT_DELTACTS_MASK), /*!< Cts pin change flag. */ + kUSART_TxDisableFlag = (USART_STAT_TXDISSTAT_MASK), /*!< Transmit disable flag. */ + kUSART_HardwareOverrunFlag = (USART_STAT_OVERRUNINT_MASK), /*!< Hardware over run flag. */ + kUSART_RxBreakFlag = (USART_STAT_DELTARXBRK_MASK), /*!< Receive break flag. */ + kUSART_RxStartFlag = (USART_STAT_START_MASK), /*!< receive start flag. */ + kUSART_FramErrorFlag = (USART_STAT_FRAMERRINT_MASK), /*!< Frame error flag. */ + kUSART_ParityErrorFlag = (USART_STAT_PARITYERRINT_MASK), /*!< Parity error flag. */ + kUSART_RxNoiseFlag = (USART_STAT_RXNOISEINT_MASK), /*!< Receive noise flag. */ + kUSART_AutoBaudErrorFlag = (USART_STAT_ABERR_MASK), /*!< Auto baud error flag. */ +}; + +/*! + * @brief System FIFO status flags for USART. + * + * This provides constants for the USART status flags for use in the USART functions. + */ +enum _usart_fifo_flags +{ + kUSART_RxFifoThresholdFlag = (VFIFO_USART_STATUSART_RXTH_MASK), /*!< Receive FIFO threshold reached flag. */ + kUSART_TxFifoThresholdFlag = (VFIFO_USART_STATUSART_TXTH_MASK), /*!< Transmit FIFO threshold reached flag. */ + kUSART_RxFifoTimeOutFlag = (VFIFO_USART_STATUSART_RXTIMEOUT_MASK), /*!< Receive time out flag. */ + kUSART_FifoBusErrorFlag = (VFIFO_USART_STATUSART_BUSERR_MASK), /*!< FIFO bus error flag. */ + kUSART_RxFifoEmptyFlag = (VFIFO_USART_STATUSART_RXEMPTY_MASK), /*!< Receive fifo buffer empty flag. */ + kUSART_TxFifoEmptyFlag = (VFIFO_USART_STATUSART_TXEMPTY_MASK), /*!< transmit fifo buffer empty flag. */ +}; + +/*! @brief USART FIFO configuration structure. */ +typedef struct _usart_fifo_config +{ + bool enableTxFifo; /*!< Transmit FIFO enable */ + bool enableRxFifo; /*!< Receive FIFO enable */ + uint8_t txFifoSize; /*!< Transmit FIFO buffer size */ + uint8_t rxFifoSize; /*!< Receive FIFO buffer size */ + uint8_t txFifoThreshold; /*!< txFIFO threshold */ + uint8_t rxFifoThreshold; /*!< rxFIFO threshold */ +} usart_fifo_config_t; + +/*! @brief USART configuration structure. */ +typedef struct _usart_config +{ + uint32_t baudRate_Bps; /*!< USART baud rate */ + bool enableRx; /*!< USART receive enable. */ + bool enableTx; /*!< USART transmit enable. */ + usart_parity_mode_t parityMode; /*!< Parity mode, disabled (default), even, odd */ + usart_stop_bit_count_t stopBitCount; /*!< Number of stop bits, 1 stop bit (default) or 2 stop bits */ + usart_data_len_t bitCountPerChar; /*!< Data length - 7 bit, 8 bit */ + bool loopback; /*!< Enable peripheral loopback */ + usart_fifo_config_t fifoConfig; /*!< FIFO configuration for USART. */ +} usart_config_t; + +/*! @brief USART transfer structure. */ +typedef struct _usart_transfer +{ + uint8_t *data; /*!< The buffer of data to be transfer.*/ + size_t dataSize; /*!< The byte count to be transfer. */ +} usart_transfer_t; + +/* Forward declaration of the handle typedef. */ +typedef struct _usart_handle usart_handle_t; + +/*! @brief USART transfer callback function. */ +typedef void (*usart_transfer_callback_t)(USART_Type *base, usart_handle_t *handle, status_t status, void *userData); + +/*! @brief USART handle structure. */ +struct _usart_handle +{ + uint8_t *volatile txData; /*!< Address of remaining data to send. */ + volatile size_t txDataSize; /*!< Size of the remaining data to send. */ + size_t txDataSizeAll; /*!< Size of the data to send out. */ + uint8_t *volatile rxData; /*!< Address of remaining data to receive. */ + volatile size_t rxDataSize; /*!< Size of the remaining data to receive. */ + size_t rxDataSizeAll; /*!< Size of the data to receive. */ + + uint8_t *rxRingBuffer; /*!< Start address of the receiver ring buffer. */ + size_t rxRingBufferSize; /*!< Size of the ring buffer. */ + volatile uint16_t rxRingBufferHead; /*!< Index for the driver to store received data into ring buffer. */ + volatile uint16_t rxRingBufferTail; /*!< Index for the user to get data from the ring buffer. */ + + usart_transfer_callback_t callback; /*!< Callback function. */ + void *userData; /*!< USART callback function parameter.*/ + + volatile uint8_t txState; /*!< TX transfer state. */ + volatile uint8_t rxState; /*!< RX transfer state */ + + bool isTxFifoEnabled; /*!< TX transfer FIFO enabled. */ + bool isRxFifoEnabled; /*!< RX transfer FIFO enabled. */ + uint8_t txFifoThreshold; /*!< txFIFO threshold */ + uint8_t rxFifoThreshold; /*!< rxFIFO threshold */ +}; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* _cplusplus */ + +/*! + * @name Get the instance of USART + * @{ + */ + +/*! @brief Returns instance number for USART peripheral base address. */ +uint32_t USART_GetInstance(USART_Type *base); +/* @} */ + +/*! + * @name Initialization and deinitialization + * @{ + */ + +/*! + * @brief Initializes a USART instance with user configuration structure and peripheral clock. + * + * This function configures the USART module with the user-defined settings. The user can configure the configuration + * structure and also get the default configuration by using the USART_GetDefaultConfig() function. + * Example below shows how to use this API to configure USART. + * @code + * usart_config_t usartConfig; + * usartConfig.baudRate_Bps = 115200U; + * usartConfig.parityMode = kUSART_ParityDisabled; + * usartConfig.stopBitCount = kUSART_OneStopBit; + * USART_Init(USART1, &usartConfig, 20000000U); + * @endcode + * + * @param base USART peripheral base address. + * @param config Pointer to user-defined configuration structure. + * @param srcClock_Hz USART clock source frequency in HZ. + * @retval kStatus_USART_BaudrateNotSupport Baudrate is not support in current clock source. + * @retval kStatus_InvalidArgument USART base address is not valid + * @retval kStatus_Success Status USART initialize succeed + */ +status_t USART_Init(USART_Type *base, const usart_config_t *config, uint32_t srcClock_Hz); + +/*! + * @brief Deinitializes a USART instance. + * + * This function waits for TX complete, disables USART and FIFO if used, and disables the USART clock and FIFO clock if + * used. + * + * @param base USART peripheral base address. + */ +void USART_Deinit(USART_Type *base); + +/*! + * @brief Gets the default configuration structure. + * + * This function initializes the USART configuration structure to a default value. The default + * values are: + * usartConfig->baudRate_Bps = 115200U; + * usartConfig->parityMode = kUSART_ParityDisabled; + * usartConfig->stopBitCount = kUSART_OneStopBit; + * usartConfig->bitCountPerChar = kUSART_8BitsPerChar; + * usartConfig->loopback = false; + * usartConfig->enableTx = false; + * usartConfig->enableRx = false; + * ... + * @param config Pointer to configuration structure. + */ +void USART_GetDefaultConfig(usart_config_t *config); + +/*! + * @brief Sets the USART instance baud rate. + * + * This function configures the USART module baud rate. This function is used to update + * the USART module baud rate after the USART module is initialized by the USART_Init. + * @code + * USART_SetBaudRate(USART1, 115200U, 20000000U); + * @endcode + * + * @param base USART peripheral base address. + * @param baudrate_Bps USART baudrate to be set. + * @param srcClock_Hz USART clock source freqency in HZ. + * @retval kStatus_USART_BaudrateNotSupport Baudrate is not support in current clock source. + * @retval kStatus_Success Set baudrate succeed. + * @retval kStatus_InvalidArgument One or more arguments are invalid. + */ +status_t USART_SetBaudRate(USART_Type *base, uint32_t baudrate_Bps, uint32_t srcClock_Hz); + +/* @} */ + +/*! + * @name Status + * @{ + */ + +/*! + * @brief Get USART status flags. + * + * This function get all USART status flags, the flags are returned as the logical + * OR value of the enumerators @ref _usart_flags. To check a specific status, + * compare the return value with enumerators in @ref _usart_flags. + * For example, to check whether the RX is ready: + * @code + * if (kUSART_RxReady & USART_GetStatusFlags(USART1)) + * { + * ... + * } + * @endcode + * + * @param base USART peripheral base address. + * @return USART status flags which are ORed by the enumerators in the _usart_flags. + */ +static inline uint32_t USART_GetStatusFlags(USART_Type *base) +{ + return base->STAT; +} + +/*! + * @brief Clear USART status flags. + * + * This function clear supported USART status flags + * For example: + * @code + * USART_ClearStatusFlags(USART1, kUSART_HardwareOverrunFlag) + * @endcode + * + * @param base USART peripheral base address. + * @param mask status flags to be cleared. + */ +static inline void USART_ClearStatusFlags(USART_Type *base, uint32_t mask) +{ + base->STAT = mask; +} + +/*! + * @brief Get system FIFO status flags for USART. + * + * This function get all system FIFO status flags for USART, the flags are returned as the logical + * OR value of the enumerators @ref _usart_fifo_flags. To check a specific status, + * compare the return value with enumerators in @ref _usart_fifo_flags. + * For example, to check whether the TX FIFO is empty: + * @code + * if (kUSART_TxFifoEmptyFlag & USART_GetFifoStatusFlags(USART1)) + * { + * ... + * } + * @endcode + * + * @param base USART peripheral base address. + * @return USART status flags which are ORed by the enumerators in the _usart_fifo_flags. + */ +uint32_t USART_GetFifoStatusFlags(USART_Type *base); + +/*! + * @brief Clear FIFO status flag for USART. + * + * This function clear supported USART status flags + * Flags that can be cleared or set are: + * kUSART_FifoBusErrorFlag + * For example: + * @code + * USART_ClearFifoStatusFlags(USART0, kUSART_FifoBusErrorFlag) + * @endcode + * + * @param base USART peripheral base address. + * @param mask status flags to be cleared. + */ +void USART_ClearFifoStatusFlags(USART_Type *base, uint32_t mask); +/* @} */ + +/*! + * @name Interrupts + * @{ + */ + +/*! + * @brief Enables USART interrupts according to the provided mask. + * + * This function enables the USART interrupts according to the provided mask. The mask + * is a logical OR of enumeration members. See @ref _usart_interrupt_enable. + * For example, to enable TX ready interrupt and RX ready interrupt: + * @code + * USART_EnableInterrupts(USART1, kUSART_RxReadyInterruptEnable | kUSART_TxReadyInterruptEnable); + * @endcode + * + * @param base USART peripheral base address. + * @param mask The interrupts to enable. Logical OR of @ref _usart_interrupt_enable. + */ +static inline void USART_EnableInterrupts(USART_Type *base, uint32_t mask) +{ + base->INTENSET = mask & 0x1FF; +} + +/*! + * @brief Disables USART interrupts according to a provided mask. + * + * This function disables the USART interrupts according to a provided mask. The mask + * is a logical OR of enumeration members. See @ref _usart_interrupt_enable. + * This example shows how to disable the TX ready interrupt and RX ready interrupt: + * @code + * USART_DisableInterrupts(USART1, kUSART_TxReadyInterruptEnable | kUSART_RxReadyInterruptEnable); + * @endcode + * + * @param base USART peripheral base address. + * @param mask The interrupts to disable. Logical OR of @ref _usart_interrupt_enable. + */ +static inline void USART_DisableInterrupts(USART_Type *base, uint32_t mask) +{ + base->INTENCLR = mask & 0x1FF; +} + +/*! + * @brief Returns enabled USART interrupts. + * + * This function returns the enabled USART interrupts. + * + * @param base USART peripheral base address. + */ +static inline uint32_t USART_GetEnabledInterrupts(USART_Type *base) +{ + return base->INTENSET; +} + +/*! + * @brief Enables FIFO interrupts for USART according to the provided mask. + * + * This function enables the USART FIFO interrupts according to the provided mask. The mask + * is a logical OR of enumeration members. See @ref _usart_interrupt_enable. + * For example, to enable TX threshold interrupt and RX threshold interrupt: + * @code + * USART_EnableInterrupts(USART0, kUSART_RxFifoThresholdInterruptEnable | kUSART_RxFifoThresholdInterruptEnable); + * @endcode + * + * @param base USART peripheral base address. + * @param mask The interrupts to enable. Logical OR of @ref _usart_interrupt_enable. + */ +void USART_EnableFifoInterrupts(USART_Type *base, uint32_t mask); + +/*! + * @brief Disables FIFO interrupts for USART according to a provided mask. + * + * This function disables the USART FIFO interrupts according to a provided mask. The mask + * is a logical OR of enumeration members. See @ref _usart_interrupt_enable. + * This example shows how to disable the TX threshold interrupt and RX threshold interrupt: + * @code + * USART_DisableInterrupts(USART1, kUSART_RxFifoThresholdInterruptEnable | kUSART_RxFifoThresholdInterruptEnable); + * @endcode + * + * @param base USART peripheral base address. + * @param mask The interrupts to disable. Logical OR of @ref _usart_fifo_interrupt_enable. + */ +void USART_DisableFifoInterrupts(USART_Type *base, uint32_t mask); + +/*! + * @brief Returns enabled USART FIFO interrupts. + * + * This function returns the enabled USART FIFO interrupts. + * + * @param base USART peripheral base address. + */ +uint32_t USART_GetEnabledFifoInterrupts(USART_Type *base); +/* @} */ + +/*! + * @name FIFO Operations + * @{ + */ + +/*! + * @brief Enable FIFO. + * + * This function will configure the FIFOs according to the config struct. + * + * @param base USART peripheral base address. + * @param config Pointer to user-defined configuration structure. + */ +void USART_EnableFifo(USART_Type *base, const usart_fifo_config_t *config); + +/*! + * @brief Disable FIFO. + * + * This function will disable the FIFO. + * + * @param base USART peripheral base address. + */ +void USART_DisableFifo(USART_Type *base); + +/*! + * @brief Is TX FIFO enabled. + * + * This function will return status if the transmit fifo is enabled. true for enabled and false for not enabled. + * + * @param base USART peripheral base address. + * @param direction the fifo direction need to be check, Tx FIFO or Rx FIFO. + * @return true for enabled and false for not enabled. + */ +bool USART_IsTxFifoEnable(USART_Type *base); + +/*! + * @brief Is RX FIFO enabled. + * + * This function will return status if the receive fifo is enabled. true for enabled and false for not enabled. + * + * @param base USART peripheral base address. + * @param direction the fifo direction need to be check, Tx FIFO or Rx FIFK. + * @return true for enabled and false for not enabled. + */ +bool USART_IsRxFifoEnable(USART_Type *base); + +/*! + * @brief Flush the FIFO buffer. + * + * This function will Flush tHE fifo buffer. + * + * @param base USART peripheral base address. + * @param direction the fifo direction need to flushed, Tx FIFO or Rx FIFO. + */ +void USART_FifoFlush(USART_Type *base, uint32_t direction); +/* @} */ + +/*! + * @name Bus Operations + * @{ + */ + +/*! + * @brief Enable the USART transmit. + * + * This function will enable or disable the USART transmit. + * + * @param base USART peripheral base address. + * @param enable true for enable and false for disable. + */ +static inline void USART_EnableTx(USART_Type *base, bool enable) +{ + if (enable) + { + /* Make sure the USART module is enabled. */ + base->CFG |= USART_CFG_ENABLE_MASK; + base->CTL &= ~USART_CTL_TXDIS_MASK; + } + else + { + base->CTL |= USART_CTL_TXDIS_MASK; + } +} + +/*! + * @brief Enable the USART receive. + * + * This function will enable or disable the USART receive. + * Note: if the transmit is enabled, the receive will not be disabled. + * @param base USART peripheral base address. + * @param enable true for enable and false for disable. + */ +static inline void USART_EnableRx(USART_Type *base, bool enable) +{ + if (enable) + { + /* Make sure the USART module is enabled. */ + base->CFG |= USART_CFG_ENABLE_MASK; + } + else + { + /* If the transmit is disabled too. */ + if (base->CTL & USART_CTL_TXDIS_MASK) + { + base->CFG &= ~USART_CFG_ENABLE_MASK; + } + } +} + +/*! + * @brief Writes to the FIFO TXDATUSART register or TXDAT register. + * + * This function will writes data to the txFIFO register or TXDAT automatly, which depend + * on if the system FIFO is enabled.The upper layer must ensure + * that txFIFO has space for data to write before calling this function. + * + * @param base USART peripheral base address. + * @param data The byte to write. + */ +void USART_WriteByte(USART_Type *base, uint8_t data); + +/*! + * @brief Reads the FIFO RXDATUSART register or RXDAT directly. + * + * This function reads data from the FIFO RXDATUSART register or RXDAT automatly. which depend + * on if the system FIFO is enabled for USART. The upper layer must + * ensure that the rxFIFO is not empty before calling this function. + * + * @param base USART peripheral base address. + * @return The byte read from USART data register. + */ +uint8_t USART_ReadByte(USART_Type *base); + +/*! + * @brief Writes to the TX register using a blocking method. + * + * This function polls the TX register, waits for the TX register to be empty or for the TX FIFO + * to have room and writes data to the TX buffer. + * + * @param base USART peripheral base address. + * @param data Start address of the data to write. + * @param length Size of the data to write. + */ +void USART_WriteBlocking(USART_Type *base, const uint8_t *data, size_t length); + +/*! + * @brief Read RX data register using a blocking method. + * + * This function polls the RX register, waits for the RX register to be full or for RX FIFO to + * have data and read data from the TX register. + * + * @param base USART peripheral base address. + * @param data Start address of the buffer to store the received data. + * @param length Size of the buffer. + * @retval kStatus_USART_FramingError Receiver overrun happened while receiving data. + * @retval kStatus_USART_ParityError Noise error happened while receiving data. + * @retval kStatus_USART_NoiseError Framing error happened while receiving data. + * @retval kStatus_USART_RxError Overflow or underflow rxFIFO happened. + * @retval kStatus_Success Successfully received all data. + */ +status_t USART_ReadBlocking(USART_Type *base, uint8_t *data, size_t length); + +/* @} */ + +/*! + * @name Transactional + * @{ + */ + +/*! + * @brief Initializes the USART handle. + * + * This function initializes the USART handle which can be used for other USART + * transactional APIs. Usually, for a specified USART instance, + * call this API once to get the initialized handle. + * + * @param base USART peripheral base address. + * @param handle USART handle pointer. + * @param callback The callback function. + * @param userData The parameter of the callback function. + */ +status_t USART_TransferCreateHandle(USART_Type *base, + usart_handle_t *handle, + usart_transfer_callback_t callback, + void *userData); + +/*! + * @brief Transmits a buffer of data using the interrupt method. + * + * This function sends data using an interrupt method. This is a non-blocking function, which + * returns directly without waiting for all data to be written to the TX register. When + * all data is written to the TX register in the IRQ handler, the USART driver calls the callback + * function and passes the @ref kStatus_USART_TxIdle as status parameter. + * + * @note The kStatus_USART_TxIdle is passed to the upper layer when all data is written + * to the TX register. However it does not ensure that all data are sent out. Before disabling the TX, + * check the kUSART_TransmissionCompleteFlag to ensure that the TX is finished. + * + * @param base USART peripheral base address. + * @param handle USART handle pointer. + * @param xfer USART transfer structure. See #usart_transfer_t. + * @retval kStatus_Success Successfully start the data transmission. + * @retval kStatus_USART_TxBusy Previous transmission still not finished, data not all written to TX register yet. + * @retval kStatus_InvalidArgument Invalid argument. + */ +status_t USART_TransferSendNonBlocking(USART_Type *base, usart_handle_t *handle, usart_transfer_t *xfer); + +/*! + * @brief Sets up the RX ring buffer. + * + * This function sets up the RX ring buffer to a specific USART handle. + * + * When the RX ring buffer is used, data received are stored into the ring buffer even when the + * user doesn't call the USART_TransferReceiveNonBlocking() API. If there is already data received + * in the ring buffer, the user can get the received data from the ring buffer directly. + * + * @note When using the RX ring buffer, one byte is reserved for internal use. In other + * words, if @p ringBufferSize is 32, then only 31 bytes are used for saving data. + * + * @param base USART peripheral base address. + * @param handle USART handle pointer. + * @param ringBuffer Start address of the ring buffer for background receiving. Pass NULL to disable the ring buffer. + * @param ringBufferSize size of the ring buffer. + */ +void USART_TransferStartRingBuffer(USART_Type *base, + usart_handle_t *handle, + uint8_t *ringBuffer, + size_t ringBufferSize); + +/*! + * @brief Aborts the background transfer and uninstalls the ring buffer. + * + * This function aborts the background transfer and uninstalls the ring buffer. + * + * @param base USART peripheral base address. + * @param handle USART handle pointer. + */ +void USART_TransferStopRingBuffer(USART_Type *base, usart_handle_t *handle); + +/*! + * @brief Get the length of received data in RX ring buffer. + * + * @param handle USART handle pointer. + * @return Length of received data in RX ring buffer. + */ +size_t USART_TransferGetRxRingBufferLength(usart_handle_t *handle); + +/*! + * @brief Aborts the interrupt-driven data transmit. + * + * This function aborts the interrupt driven data sending. The user can get the remainBtyes to find out + * how many bytes are still not sent out. + * + * @param base USART peripheral base address. + * @param handle USART handle pointer. + */ +void USART_TransferAbortSend(USART_Type *base, usart_handle_t *handle); + +/*! + * @brief Get the number of bytes that have been written to USART TX register. + * + * This function gets the number of bytes that have been written to USART TX + * register by interrupt method. + * + * @param base USART peripheral base address. + * @param handle USART handle pointer. + * @param count Send bytes count. + * @retval kStatus_NoTransferInProgress No send in progress. + * @retval kStatus_InvalidArgument Parameter is invalid. + * @retval kStatus_Success Get successfully through the parameter \p count; + */ +status_t USART_TransferGetSendCount(USART_Type *base, usart_handle_t *handle, uint32_t *count); + +/*! + * @brief Receives a buffer of data using an interrupt method. + * + * This function receives data using an interrupt method. This is a non-blocking function, which + * returns without waiting for all data to be received. + * If the RX ring buffer is used and not empty, the data in the ring buffer is copied and + * the parameter @p receivedBytes shows how many bytes are copied from the ring buffer. + * After copying, if the data in the ring buffer is not enough to read, the receive + * request is saved by the USART driver. When the new data arrives, the receive request + * is serviced first. When all data is received, the USART driver notifies the upper layer + * through a callback function and passes the status parameter @ref kStatus_USART_RxIdle. + * For example, the upper layer needs 10 bytes but there are only 5 bytes in the ring buffer. + * The 5 bytes are copied to the xfer->data and this function returns with the + * parameter @p receivedBytes set to 5. For the left 5 bytes, newly arrived data is + * saved from the xfer->data[5]. When 5 bytes are received, the USART driver notifies the upper layer. + * If the RX ring buffer is not enabled, this function enables the RX and RX interrupt + * to receive data to the xfer->data. When all data is received, the upper layer is notified. + * + * @param base USART peripheral base address. + * @param handle USART handle pointer. + * @param xfer USART transfer structure, see #usart_transfer_t. + * @param receivedBytes Bytes received from the ring buffer directly. + * @retval kStatus_Success Successfully queue the transfer into transmit queue. + * @retval kStatus_USART_RxBusy Previous receive request is not finished. + * @retval kStatus_InvalidArgument Invalid argument. + */ +status_t USART_TransferReceiveNonBlocking(USART_Type *base, + usart_handle_t *handle, + usart_transfer_t *xfer, + size_t *receivedBytes); + +/*! + * @brief Aborts the interrupt-driven data receiving. + * + * This function aborts the interrupt-driven data receiving. The user can get the remainBytes to find out + * how many bytes not received yet. + * + * @param base USART peripheral base address. + * @param handle USART handle pointer. + */ +void USART_TransferAbortReceive(USART_Type *base, usart_handle_t *handle); + +/*! + * @brief Get the number of bytes that have been received. + * + * This function gets the number of bytes that have been received. + * + * @param base USART peripheral base address. + * @param handle USART handle pointer. + * @param count Receive bytes count. + * @retval kStatus_NoTransferInProgress No receive in progress. + * @retval kStatus_InvalidArgument Parameter is invalid. + * @retval kStatus_Success Get successfully through the parameter \p count; + */ +status_t USART_TransferGetReceiveCount(USART_Type *base, usart_handle_t *handle, uint32_t *count); + +/*! + * @brief USART IRQ handle function. + * + * This function handles the USART transmit and receive IRQ request. + * + * @param base USART peripheral base address. + * @param handle USART handle pointer. + */ +void USART_TransferHandleIRQ(USART_Type *base, usart_handle_t *handle); + +/* @} */ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_USART_H_ */ diff --git a/platform/mcu/lpc54102/drivers/fsl_usart_dma.c b/platform/mcu/lpc54102/drivers/fsl_usart_dma.c new file mode 100644 index 0000000000..0d8a4e528e --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_usart_dma.c @@ -0,0 +1,271 @@ +/* + * Copyright (c) 2017, NXP Semiconductors, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_usart.h" +#include "fsl_device_registers.h" +#include "fsl_dma.h" +#include "fsl_usart_dma.h" + +/*base))) + { + } + + usartPrivateHandle->handle->txState = kUSART_TxIdle; + + if (usartPrivateHandle->handle->callback) + { + usartPrivateHandle->handle->callback(usartPrivateHandle->base, usartPrivateHandle->handle, kStatus_USART_TxIdle, + usartPrivateHandle->handle->userData); + } +} + +static void USART_TransferReceiveDMACallback(dma_handle_t *handle, void *param, bool transferDone, uint32_t intmode) +{ + assert(handle); + assert(param); + + usart_dma_private_handle_t *usartPrivateHandle = (usart_dma_private_handle_t *)param; + + usartPrivateHandle->handle->rxState = kUSART_RxIdle; + + if (usartPrivateHandle->handle->callback) + { + usartPrivateHandle->handle->callback(usartPrivateHandle->base, usartPrivateHandle->handle, kStatus_USART_RxIdle, + usartPrivateHandle->handle->userData); + } +} + +status_t USART_TransferCreateHandleDMA(USART_Type *base, + usart_dma_handle_t *handle, + usart_dma_transfer_callback_t callback, + void *userData, + dma_handle_t *txDmaHandle, + dma_handle_t *rxDmaHandle) +{ + int32_t instance = 0; + + /* check 'base' */ + assert(!(NULL == base)); + if (NULL == base) + { + return kStatus_InvalidArgument; + } + /* check 'handle' */ + assert(!(NULL == handle)); + if (NULL == handle) + { + return kStatus_InvalidArgument; + } + + instance = USART_GetInstance(base); + + memset(handle, 0, sizeof(*handle)); + /* assign 'base' and 'handle' */ + s_dmaPrivateHandle[instance].base = base; + s_dmaPrivateHandle[instance].handle = handle; + + /* set tx/rx 'idle' state */ + handle->rxState = kUSART_RxIdle; + handle->txState = kUSART_TxIdle; + + handle->callback = callback; + handle->userData = userData; + + handle->rxDmaHandle = rxDmaHandle; + handle->txDmaHandle = txDmaHandle; + + /* Configure TX. */ + if (txDmaHandle) + { + DMA_SetCallback(txDmaHandle, USART_TransferSendDMACallback, &s_dmaPrivateHandle[instance]); + } + + /* Configure RX. */ + if (rxDmaHandle) + { + DMA_SetCallback(rxDmaHandle, USART_TransferReceiveDMACallback, &s_dmaPrivateHandle[instance]); + } + + return kStatus_Success; +} + +status_t USART_TransferSendDMA(USART_Type *base, usart_dma_handle_t *handle, usart_transfer_t *xfer) +{ + assert(handle); + assert(handle->txDmaHandle); + assert(xfer); + assert(xfer->data); + assert(xfer->dataSize); + + dma_transfer_config_t xferConfig; + status_t status; + uint32_t instance = USART_GetInstance(base); + + /* If previous TX not finished. */ + if (kUSART_TxBusy == handle->txState) + { + status = kStatus_USART_TxBusy; + } + else + { + handle->txState = kUSART_TxBusy; + handle->txDataSizeAll = xfer->dataSize; + + if (!USART_IsTxFifoEnable(base)) + { + /* Prepare transfer. */ + DMA_PrepareTransfer(&xferConfig, xfer->data, (void *)&base->TXDAT, sizeof(uint8_t), xfer->dataSize, + kDMA_MemoryToPeripheral, NULL); + } + else + { + /* Prepare transfer. */ + DMA_PrepareTransfer(&xferConfig, xfer->data, (void *)&VFIFO->USART[instance].TXDATUSART, sizeof(uint8_t), + xfer->dataSize, kDMA_MemoryToPeripheral, NULL); + } + /* Submit transfer. */ + DMA_SubmitTransfer(handle->txDmaHandle, &xferConfig); + DMA_StartTransfer(handle->txDmaHandle); + + status = kStatus_Success; + } + + return status; +} + +status_t USART_TransferReceiveDMA(USART_Type *base, usart_dma_handle_t *handle, usart_transfer_t *xfer) +{ + assert(handle); + assert(handle->rxDmaHandle); + assert(xfer); + assert(xfer->data); + assert(xfer->dataSize); + + dma_transfer_config_t xferConfig; + status_t status; + uint32_t instance = USART_GetInstance(base); + + /* If previous RX not finished. */ + if (kUSART_RxBusy == handle->rxState) + { + status = kStatus_USART_RxBusy; + } + else + { + handle->rxState = kUSART_RxBusy; + handle->rxDataSizeAll = xfer->dataSize; + + if (!USART_IsRxFifoEnable(base)) + { + /* Prepare transfer. */ + DMA_PrepareTransfer(&xferConfig, (void *)&base->RXDAT, xfer->data, sizeof(uint8_t), xfer->dataSize, + kDMA_PeripheralToMemory, NULL); + } + else + { + /* Prepare transfer. */ + DMA_PrepareTransfer(&xferConfig, (void *)&VFIFO->USART[instance].RXDATUSART, xfer->data, sizeof(uint8_t), + xfer->dataSize, kDMA_PeripheralToMemory, NULL); + } + /* Submit transfer. */ + DMA_SubmitTransfer(handle->rxDmaHandle, &xferConfig); + DMA_StartTransfer(handle->rxDmaHandle); + + status = kStatus_Success; + } + + return status; +} + +void USART_TransferAbortSendDMA(USART_Type *base, usart_dma_handle_t *handle) +{ + assert(NULL != handle); + assert(NULL != handle->txDmaHandle); + + /* Stop transfer. */ + DMA_AbortTransfer(handle->txDmaHandle); + handle->txState = kUSART_TxIdle; +} + +void USART_TransferAbortReceiveDMA(USART_Type *base, usart_dma_handle_t *handle) +{ + assert(NULL != handle); + assert(NULL != handle->rxDmaHandle); + + /* Stop transfer. */ + DMA_AbortTransfer(handle->rxDmaHandle); + handle->rxState = kUSART_RxIdle; +} + +status_t USART_TransferGetReceiveCountDMA(USART_Type *base, usart_dma_handle_t *handle, uint32_t *count) +{ + assert(handle); + assert(handle->rxDmaHandle); + assert(count); + + if (kUSART_RxIdle == handle->rxState) + { + return kStatus_NoTransferInProgress; + } + + *count = handle->rxDataSizeAll - DMA_GetRemainingBytes(handle->rxDmaHandle->base, handle->rxDmaHandle->channel); + + return kStatus_Success; +} diff --git a/platform/mcu/lpc54102/drivers/fsl_usart_dma.h b/platform/mcu/lpc54102/drivers/fsl_usart_dma.h new file mode 100644 index 0000000000..c45a380073 --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_usart_dma.h @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2017, NXP Semiconductors, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_USART_DMA_H_ +#define _FSL_USART_DMA_H_ + +#include "fsl_common.h" +#include "fsl_dma.h" +#include "fsl_usart.h" + +/*! + * @addtogroup usart_dma_driver + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/* Forward declaration of the handle typedef. */ +typedef struct _usart_dma_handle usart_dma_handle_t; + +/*! @brief UART transfer callback function. */ +typedef void (*usart_dma_transfer_callback_t)(USART_Type *base, + usart_dma_handle_t *handle, + status_t status, + void *userData); + +/*! +* @brief UART DMA handle +*/ +struct _usart_dma_handle +{ + USART_Type *base; /*!< UART peripheral base address. */ + + usart_dma_transfer_callback_t callback; /*!< Callback function. */ + void *userData; /*!< UART callback function parameter.*/ + size_t rxDataSizeAll; /*!< Size of the data to receive. */ + size_t txDataSizeAll; /*!< Size of the data to send out. */ + + dma_handle_t *txDmaHandle; /*!< The DMA TX channel used. */ + dma_handle_t *rxDmaHandle; /*!< The DMA RX channel used. */ + + volatile uint8_t txState; /*!< TX transfer state. */ + volatile uint8_t rxState; /*!< RX transfer state */ +}; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* _cplusplus */ + +/*! + * @name DMA transactional + * @{ + */ + +/*! + * @brief Initializes the USART handle which is used in transactional functions. + * @param base USART peripheral base address. + * @param handle Pointer to usart_dma_handle_t structure. + * @param callback Callback function. + * @param userData User data. + * @param txDmaHandle User-requested DMA handle for TX DMA transfer. + * @param rxDmaHandle User-requested DMA handle for RX DMA transfer. + */ +status_t USART_TransferCreateHandleDMA(USART_Type *base, + usart_dma_handle_t *handle, + usart_dma_transfer_callback_t callback, + void *userData, + dma_handle_t *txDmaHandle, + dma_handle_t *rxDmaHandle); + +/*! + * @brief Sends data using DMA. + * + * This function sends data using DMA. This is a non-blocking function, which returns + * right away. When all data is sent, the send callback function is called. + * + * @param base USART peripheral base address. + * @param handle USART handle pointer. + * @param xfer USART DMA transfer structure. See #usart_transfer_t. + * @retval kStatus_Success if succeed, others failed. + * @retval kStatus_USART_TxBusy Previous transfer on going. + * @retval kStatus_InvalidArgument Invalid argument. + */ +status_t USART_TransferSendDMA(USART_Type *base, usart_dma_handle_t *handle, usart_transfer_t *xfer); + +/*! + * @brief Receives data using DMA. + * + * This function receives data using DMA. This is a non-blocking function, which returns + * right away. When all data is received, the receive callback function is called. + * + * @param base USART peripheral base address. + * @param handle Pointer to usart_dma_handle_t structure. + * @param xfer USART DMA transfer structure. See #usart_transfer_t. + * @retval kStatus_Success if succeed, others failed. + * @retval kStatus_USART_RxBusy Previous transfer on going. + * @retval kStatus_InvalidArgument Invalid argument. + */ +status_t USART_TransferReceiveDMA(USART_Type *base, usart_dma_handle_t *handle, usart_transfer_t *xfer); + +/*! + * @brief Aborts the sent data using DMA. + * + * This function aborts send data using DMA. + * + * @param base USART peripheral base address + * @param handle Pointer to usart_dma_handle_t structure + */ +void USART_TransferAbortSendDMA(USART_Type *base, usart_dma_handle_t *handle); + +/*! + * @brief Aborts the received data using DMA. + * + * This function aborts the received data using DMA. + * + * @param base USART peripheral base address + * @param handle Pointer to usart_dma_handle_t structure + */ +void USART_TransferAbortReceiveDMA(USART_Type *base, usart_dma_handle_t *handle); + +/*! + * @brief Get the number of bytes that have been received. + * + * This function gets the number of bytes that have been received. + * + * @param base USART peripheral base address. + * @param handle USART handle pointer. + * @param count Receive bytes count. + * @retval kStatus_NoTransferInProgress No receive in progress. + * @retval kStatus_InvalidArgument Parameter is invalid. + * @retval kStatus_Success Get successfully through the parameter \p count; + */ +status_t USART_TransferGetReceiveCountDMA(USART_Type *base, usart_dma_handle_t *handle, uint32_t *count); + +/* @} */ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_USART_DMA_H_ */ diff --git a/platform/mcu/lpc54102/drivers/fsl_utick.c b/platform/mcu/lpc54102/drivers/fsl_utick.c new file mode 100644 index 0000000000..e814a7a5c7 --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_utick.c @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_utick.h" +#include "fsl_power.h" +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/* Typedef for interrupt handler. */ +typedef void (*utick_isr_t)(UTICK_Type *base, utick_callback_t cb); + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +/*! + * @brief Gets the instance from the base address + * + * @param base UTICK peripheral base address + * + * @return The UTICK instance + */ +static uint32_t UTICK_GetInstance(UTICK_Type *base); + +/******************************************************************************* + * Variables + ******************************************************************************/ +/* Array of UTICK handle. */ +static utick_callback_t s_utickHandle[FSL_FEATURE_SOC_UTICK_COUNT]; +/* Array of UTICK peripheral base address. */ +static UTICK_Type *const s_utickBases[] = UTICK_BASE_PTRS; +/* Array of UTICK IRQ number. */ +static const IRQn_Type s_utickIRQ[] = UTICK_IRQS; +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +/* Array of UTICK clock name. */ +static const clock_ip_name_t s_utickClock[] = UTICK_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +/* UTICK ISR for transactional APIs. */ +static utick_isr_t s_utickIsr; + +/******************************************************************************* + * Code + ******************************************************************************/ +static uint32_t UTICK_GetInstance(UTICK_Type *base) +{ + uint32_t instance; + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < ARRAY_SIZE(s_utickBases); instance++) + { + if (s_utickBases[instance] == base) + { + break; + } + } + + assert(instance < ARRAY_SIZE(s_utickBases)); + + return instance; +} + +void UTICK_SetTick(UTICK_Type *base, utick_mode_t mode, uint32_t count, utick_callback_t cb) +{ + uint32_t instance; + + /* Get instance from peripheral base address. */ + instance = UTICK_GetInstance(base); + + /* Save the handle in global variables to support the double weak mechanism. */ + s_utickHandle[instance] = cb; + EnableDeepSleepIRQ(s_utickIRQ[instance]); + base->CTRL = count | UTICK_CTRL_REPEAT(mode); +} + +void UTICK_Init(UTICK_Type *base) +{ + /* Enable utick clock */ + CLOCK_EnableClock(s_utickClock[UTICK_GetInstance(base)]); + /* Power up Watchdog oscillator*/ + POWER_DisablePD(kPDRUNCFG_PD_WDT_OSC); + s_utickIsr = UTICK_HandleIRQ; +} + +void UTICK_Deinit(UTICK_Type *base) +{ + /* Turn off utick */ + base->CTRL = 0; + /* Disable utick clock */ + CLOCK_DisableClock(s_utickClock[UTICK_GetInstance(base)]); +} + +uint32_t UTICK_GetStatusFlags(UTICK_Type *base) +{ + return (base->STAT); +} + +void UTICK_ClearStatusFlags(UTICK_Type *base) +{ + base->STAT = UTICK_STAT_INTR_MASK; +} + +void UTICK_HandleIRQ(UTICK_Type *base, utick_callback_t cb) +{ + UTICK_ClearStatusFlags(base); + if (cb) + { + cb(); + } +} + +#if defined(UTICK0) +void UTICK0_DriverIRQHandler(void) +{ + s_utickIsr(UTICK0, s_utickHandle[0]); + /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif +#if defined(UTICK1) +void UTICK1_DriverIRQHandler(void) +{ + s_utickIsr(UTICK1, s_utickHandle[1]); + /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif +#if defined(UTICK2) +void UTICK2_DriverIRQHandler(void) +{ + s_utickIsr(UTICK2, s_utickHandle[2]); + /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping + exception return operation might vector to incorrect interrupt */ +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif +} +#endif diff --git a/platform/mcu/lpc54102/drivers/fsl_utick.h b/platform/mcu/lpc54102/drivers/fsl_utick.h new file mode 100644 index 0000000000..6aa617d933 --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_utick.h @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_UTICK_H_ +#define _FSL_UTICK_H_ + +#include "fsl_common.h" +/*! + * @addtogroup utick + * @{ + */ + +/*! @file*/ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief UTICK driver version 2.0.0. */ +#define FSL_UTICK_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*@}*/ + +/*! @brief UTICK timer operational mode. */ +typedef enum _utick_mode +{ + kUTICK_Onetime = 0x0U, /*!< Trigger once*/ + kUTICK_Repeat = 0x1U, /*!< Trigger repeatedly */ +} utick_mode_t; + +/*! @brief UTICK callback function. */ +typedef void (*utick_callback_t)(void); + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* _cplusplus */ + +/*! + * @name Initialization and deinitialization + * @{ + */ + +/*! +* @brief Initializes an UTICK by turning its bus clock on +* +*/ +void UTICK_Init(UTICK_Type *base); + +/*! + * @brief Deinitializes a UTICK instance. + * + * This function shuts down Utick bus clock + * + * @param base UTICK peripheral base address. + */ +void UTICK_Deinit(UTICK_Type *base); +/*! + * @brief Get Status Flags. + * + * This returns the status flag + * + * @param base UTICK peripheral base address. + * @return status register value + */ +uint32_t UTICK_GetStatusFlags(UTICK_Type *base); +/*! + * @brief Clear Status Interrupt Flags. + * + * This clears intr status flag + * + * @param base UTICK peripheral base address. + * @return none + */ +void UTICK_ClearStatusFlags(UTICK_Type *base); + +/*! + * @brief Starts UTICK. + * + * This function starts a repeat/onetime countdown with an optional callback + * + * @param base UTICK peripheral base address. + * @param mode UTICK timer mode (ie kUTICK_onetime or kUTICK_repeat) + * @param count UTICK timer mode (ie kUTICK_onetime or kUTICK_repeat) + * @param cb UTICK callback (can be left as NULL if none, otherwise should be a void func(void)) + * @return none + */ +void UTICK_SetTick(UTICK_Type *base, utick_mode_t mode, uint32_t count, utick_callback_t cb); +/*! + * @brief UTICK Interrupt Service Handler. + * + * This function handles the interrupt and refers to the callback array in the driver to callback user (as per request + * in UTICK_SetTick()). + * if no user callback is scheduled, the interrupt will simply be cleared. + * + * @param base UTICK peripheral base address. + * @param cb callback scheduled for this instance of UTICK + * @return none + */ +void UTICK_HandleIRQ(UTICK_Type *base, utick_callback_t cb); + +/* @} */ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_UTICK_H_ */ diff --git a/platform/mcu/lpc54102/drivers/fsl_wwdt.c b/platform/mcu/lpc54102/drivers/fsl_wwdt.c new file mode 100644 index 0000000000..43c44de667 --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_wwdt.c @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_wwdt.h" + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/*! + * @brief Gets the instance from the base address + * + * @param base WWDT peripheral base address + * + * @return The WWDT instance + */ +static uint32_t WWDT_GetInstance(WWDT_Type *base); + +/******************************************************************************* + * Variables + ******************************************************************************/ +/*! @brief Pointers to WWDT bases for each instance. */ +static WWDT_Type *const s_wwdtBases[] = WWDT_BASE_PTRS; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) +/*! @brief Pointers to WWDT clocks for each instance. */ +static const clock_ip_name_t s_wwdtClocks[] = WWDT_CLOCKS; +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + +/*! @brief Pointers to WWDT resets for each instance. */ +static const reset_ip_name_t s_wwdtResets[] = WWDT_RSTS; + +/******************************************************************************* + * Code + ******************************************************************************/ +static uint32_t WWDT_GetInstance(WWDT_Type *base) +{ + uint32_t instance; + uint32_t wwdtArrayCount = (sizeof(s_wwdtBases) / sizeof(s_wwdtBases[0])); + + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < wwdtArrayCount; instance++) + { + if (s_wwdtBases[instance] == base) + { + break; + } + } + + assert(instance < wwdtArrayCount); + + return instance; +} + +/******************************************************************************* + * Code + ******************************************************************************/ + +void WWDT_GetDefaultConfig(wwdt_config_t *config) +{ + assert(config); + + /* Enable the watch dog */ + config->enableWwdt = true; + /* Disable the watchdog timeout reset */ + config->enableWatchdogReset = false; + /* Disable the watchdog protection for updating the timeout value */ + config->enableWatchdogProtect = false; + /* Do not lock the watchdog oscillator */ + config->enableLockOscillator = false; + /* Windowing is not in effect */ + config->windowValue = 0xFFFFFFU; + /* Set the timeout value to the max */ + config->timeoutValue = 0xFFFFFFU; + /* No warning is provided */ + config->warningValue = 0; +} + +void WWDT_Init(WWDT_Type *base, const wwdt_config_t *config) +{ + assert(config); + + uint32_t value = 0U; + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Enable the WWDT clock */ + CLOCK_EnableClock(s_wwdtClocks[WWDT_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ + + /* Reset the WWDT module */ + RESET_PeripheralReset(s_wwdtResets[WWDT_GetInstance(base)]); + + value = WWDT_MOD_WDEN(config->enableWwdt) | WWDT_MOD_WDRESET(config->enableWatchdogReset) | + WWDT_MOD_WDPROTECT(config->enableWatchdogProtect) | WWDT_MOD_LOCK(config->enableLockOscillator); + /* Set configruation */ + base->WINDOW = WWDT_WINDOW_WINDOW(config->windowValue); + base->TC = WWDT_TC_COUNT(config->timeoutValue); + base->WARNINT = WWDT_WARNINT_WARNINT(config->warningValue); + base->MOD = value; +} + +void WWDT_Deinit(WWDT_Type *base) +{ + WWDT_Disable(base); + +#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) + /* Disable the WWDT clock */ + CLOCK_DisableClock(s_wwdtClocks[WWDT_GetInstance(base)]); +#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ +} + +void WWDT_Refresh(WWDT_Type *base) +{ + uint32_t primaskValue = 0U; + + /* Disable the global interrupt to protect refresh sequence */ + primaskValue = DisableGlobalIRQ(); + base->FEED = WWDT_FIRST_WORD_OF_REFRESH; + base->FEED = WWDT_SECOND_WORD_OF_REFRESH; + EnableGlobalIRQ(primaskValue); +} + +void WWDT_ClearStatusFlags(WWDT_Type *base, uint32_t mask) +{ + /* Clear the WDINT bit so that we don't accidentally clear it */ + uint32_t reg = (base->MOD & (~WWDT_MOD_WDINT_MASK)); + + /* Clear timeout by writing a zero */ + if (mask & kWWDT_TimeoutFlag) + { + reg &= ~WWDT_MOD_WDTOF_MASK; + } + + /* Clear warning interrupt flag by writing a one */ + if (mask & kWWDT_WarningFlag) + { + reg |= WWDT_MOD_WDINT_MASK; + } + + base->MOD = reg; +} diff --git a/platform/mcu/lpc54102/drivers/fsl_wwdt.h b/platform/mcu/lpc54102/drivers/fsl_wwdt.h new file mode 100644 index 0000000000..02916aa2f2 --- /dev/null +++ b/platform/mcu/lpc54102/drivers/fsl_wwdt.h @@ -0,0 +1,283 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_WWDT_H_ +#define _FSL_WWDT_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup wwdt + * @{ + */ + +/*! @file */ + +/******************************************************************************* + * Definitions + *******************************************************************************/ + +/*! @name Driver version */ +/*@{*/ +/*! @brief Defines WWDT driver version 2.0.0. */ +#define FSL_WWDT_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) +/*@}*/ + +/*! @name Refresh sequence */ +/*@{*/ +#define WWDT_FIRST_WORD_OF_REFRESH (0xAAU) /*!< First word of refresh sequence */ +#define WWDT_SECOND_WORD_OF_REFRESH (0x55U) /*!< Second word of refresh sequence */ +/*@}*/ + +/*! @brief Describes WWDT configuration structure. */ +typedef struct _wwdt_config +{ + bool enableWwdt; /*!< Enables or disables WWDT */ + bool enableWatchdogReset; /*!< true: Watchdog timeout will cause a chip reset + false: Watchdog timeout will not cause a chip reset */ + bool enableWatchdogProtect; /*!< true: Enable watchdog protect i.e timeout value can only be + changed after counter is below warning & window values + false: Disable watchdog protect; timeout value can be changed + at any time */ + bool enableLockOscillator; /*!< true: Disabling or powering down the watchdog oscillator is prevented + Once set, this bit can only be cleared by a reset + false: Do not lock oscillator */ + uint32_t windowValue; /*!< Window value, set this to 0xFFFFFF if windowing is not in effect */ + uint32_t timeoutValue; /*!< Timeout value */ + uint32_t warningValue; /*!< Watchdog time counter value that will generate a + warning interrupt. Set this to 0 for no warning */ + +} wwdt_config_t; + +/*! + * @brief WWDT status flags. + * + * This structure contains the WWDT status flags for use in the WWDT functions. + */ +enum _wwdt_status_flags_t +{ + kWWDT_TimeoutFlag = WWDT_MOD_WDTOF_MASK, /*!< Time-out flag, set when the timer times out */ + kWWDT_WarningFlag = WWDT_MOD_WDINT_MASK /*!< Warning interrupt flag, set when timer is below the value WDWARNINT */ +}; + +/******************************************************************************* + * API + *******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + +/*! + * @name WWDT Initialization and De-initialization + * @{ + */ + +/*! + * @brief Initializes WWDT configure sturcture. + * + * This function initializes the WWDT configure structure to default value. The default + * value are: + * @code + * config->enableWwdt = true; + * config->enableWatchdogReset = false; + * config->enableWatchdogProtect = false; + * config->enableLockOscillator = false; + * config->windowValue = 0xFFFFFFU; + * config->timeoutValue = 0xFFFFFFU; + * config->warningValue = 0; + * @endcode + * + * @param config Pointer to WWDT config structure. + * @see wwdt_config_t + */ +void WWDT_GetDefaultConfig(wwdt_config_t *config); + +/*! + * @brief Initializes the WWDT. + * + * This function initializes the WWDT. When called, the WWDT runs according to the configuration. + * + * Example: + * @code + * wwdt_config_t config; + * WWDT_GetDefaultConfig(&config); + * config.timeoutValue = 0x7ffU; + * WWDT_Init(wwdt_base,&config); + * @endcode + * + * @param base WWDT peripheral base address + * @param config The configuration of WWDT + */ +void WWDT_Init(WWDT_Type *base, const wwdt_config_t *config); + +/*! + * @brief Shuts down the WWDT. + * + * This function shuts down the WWDT. + * + * @param base WWDT peripheral base address + */ +void WWDT_Deinit(WWDT_Type *base); + +/* @} */ + +/*! + * @name WWDT Functional Operation + * @{ + */ + +/*! + * @brief Enables the WWDT module. + * + * This function write value into WWDT_MOD register to enable the WWDT, it is a write-once bit; + * once this bit is set to one and a watchdog feed is performed, the watchdog timer will run + * permanently. + * + * @param base WWDT peripheral base address + */ +static inline void WWDT_Enable(WWDT_Type *base) +{ + base->MOD |= WWDT_MOD_WDEN_MASK; +} + +/*! + * @brief Disables the WWDT module. + * + * This function write value into WWDT_MOD register to disable the WWDT. + * + * @param base WWDT peripheral base address + */ +static inline void WWDT_Disable(WWDT_Type *base) +{ + base->MOD &= ~WWDT_MOD_WDEN_MASK; +} + +/*! + * @brief Gets all WWDT status flags. + * + * This function gets all status flags. + * + * Example for getting Timeout Flag: + * @code + * uint32_t status; + * status = WWDT_GetStatusFlags(wwdt_base) & kWWDT_TimeoutFlag; + * @endcode + * @param base WWDT peripheral base address + * @return The status flags. This is the logical OR of members of the + * enumeration ::_wwdt_status_flags_t + */ +static inline uint32_t WWDT_GetStatusFlags(WWDT_Type *base) +{ + return (base->MOD & (WWDT_MOD_WDTOF_MASK | WWDT_MOD_WDINT_MASK)); +} + +/*! + * @brief Clear WWDT flag. + * + * This function clears WWDT status flag. + * + * Example for clearing warning flag: + * @code + * WWDT_ClearStatusFlags(wwdt_base, kWWDT_WarningFlag); + * @endcode + * @param base WWDT peripheral base address + * @param mask The status flags to clear. This is a logical OR of members of the + * enumeration ::_wwdt_status_flags_t + */ +void WWDT_ClearStatusFlags(WWDT_Type *base, uint32_t mask); + +/*! + * @brief Set the WWDT warning value. + * + * The WDWARNINT register determines the watchdog timer counter value that will generate a watchdog + * interrupt. When the watchdog timer counter is no longer greater than the value defined by + * WARNINT, an interrupt will be generated after the subsequent WDCLK. + * + * @param base WWDT peripheral base address + * @param warningValue WWDT warning value. + */ +static inline void WWDT_SetWarningValue(WWDT_Type *base, uint32_t warningValue) +{ + base->WARNINT = WWDT_WARNINT_WARNINT(warningValue); +} + +/*! + * @brief Set the WWDT timeout value. + * + * This function sets the timeout value. Every time a feed sequence occurs the value in the TC + * register is loaded into the Watchdog timer. Writing a value below 0xFF will cause 0xFF to be + * loaded into the TC register. Thus the minimum time-out interval is TWDCLK*256*4. + * If enableWatchdogProtect flag is true in wwdt_config_t config structure, any attempt to change + * the timeout value before the watchdog counter is below the warning and window values + * will cause a watchdog reset and set the WDTOF flag. + * + * @param base WWDT peripheral base address + * @param timeoutCount WWDT timeout value, count of WWDT clock tick. + */ +static inline void WWDT_SetTimeoutValue(WWDT_Type *base, uint32_t timeoutCount) +{ + base->TC = WWDT_TC_COUNT(timeoutCount); +} + +/*! + * @brief Sets the WWDT window value. + * + * The WINDOW register determines the highest TV value allowed when a watchdog feed is performed. + * If a feed sequence occurs when timer value is greater than the value in WINDOW, a watchdog + * event will occur. To disable windowing, set windowValue to 0xFFFFFF (maximum possible timer + * value) so windowing is not in effect. + * + * @param base WWDT peripheral base address + * @param windowValue WWDT window value. + */ +static inline void WWDT_SetWindowValue(WWDT_Type *base, uint32_t windowValue) +{ + base->WINDOW = WWDT_WINDOW_WINDOW(windowValue); +} + +/*! + * @brief Refreshes the WWDT timer. + * + * This function feeds the WWDT. + * This function should be called before WWDT timer is in timeout. Otherwise, a reset is asserted. + * + * @param base WWDT peripheral base address + */ +void WWDT_Refresh(WWDT_Type *base); + +/*@}*/ + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + +/*! @}*/ + +#endif /* _FSL_WWDT_H_ */ diff --git a/platform/mcu/lpc54102/fsl_device_registers.h b/platform/mcu/lpc54102/fsl_device_registers.h new file mode 100644 index 0000000000..2d640f67d3 --- /dev/null +++ b/platform/mcu/lpc54102/fsl_device_registers.h @@ -0,0 +1,67 @@ +/* + * Copyright 2014-2016 Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef __FSL_DEVICE_REGISTERS_H__ +#define __FSL_DEVICE_REGISTERS_H__ + +/* + * Include the cpu specific register header files. + * + * The CPU macro should be declared in the project or makefile. + */ +#if (defined(CPU_LPC54102J256BD64_cm4) || defined(CPU_LPC54102J256UK49_cm4) || defined(CPU_LPC54102J512BD64_cm4) || \ + defined(CPU_LPC54102J512UK49_cm4)) + +#define LPC54102_cm4_SERIES + +/* CMSIS-style register definitions */ +#include "LPC54102_cm4.h" +/* CPU specific feature definitions */ +#include "LPC54102_cm4_features.h" + +#elif (defined(CPU_LPC54102J256BD64_cm0plus) || defined(CPU_LPC54102J256UK49_cm0plus) || defined(CPU_LPC54102J512BD64_cm0plus) || \ + defined(CPU_LPC54102J512UK49_cm0plus)) + +#define LPC54102_cm0plus_SERIES + +/* CMSIS-style register definitions */ +#include "LPC54102_cm0plus.h" +/* CPU specific feature definitions */ +#include "LPC54102_cm0plus_features.h" + +#else + #error "No valid CPU defined!" +#endif + +#endif /* __FSL_DEVICE_REGISTERS_H__ */ + +/******************************************************************************* + * EOF + ******************************************************************************/ diff --git a/platform/mcu/lpc54102/hal/csp_log.c b/platform/mcu/lpc54102/hal/csp_log.c new file mode 100644 index 0000000000..055a53edff --- /dev/null +++ b/platform/mcu/lpc54102/hal/csp_log.c @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * POSIX getopt for Windows + * Code given out at the 1985 UNIFORUM conference in Dallas. + * + * From std-unix@ut-sally.UUCP (Moderator, John Quarterman) Sun Nov 3 14:34:15 1985 + * Relay-Version: version B 2.10.3 4.3bsd-beta 6/6/85; site gatech.CSNET + * Posting-Version: version B 2.10.2 9/18/84; site ut-sally.UUCP + * Path: gatech!akgua!mhuxv!mhuxt!mhuxr!ulysses!allegra!mit-eddie!genrad!panda!talcott!harvard!seismo!ut-sally!std-unix + * From: std-unix@ut-sally.UUCP (Moderator, John Quarterman) + * Newsgroups: mod.std.unix + * Subject: public domain AT&T getopt source + * Message-ID: <3352@ut-sally.UUCP> + * Date: 3 Nov 85 19:34:15 GMT + * Date-Received: 4 Nov 85 12:25:09 GMT + * Organization: IEEE/P1003 Portable Operating System Environment Committee + * Lines: 91 + * Approved: jsq@ut-sally.UUC + * Here's something you've all been waiting for: the AT&T public domain + * source for getopt(3). It is the code which was given out at the 1985 + * UNIFORUM conference in Dallas. I obtained it by electronic mail + * directly from AT&T. The people there assure me that it is indeed + * in the public domain + * There is no manual page. That is because the one they gave out at + * UNIFORUM was slightly different from the current System V Release 2 + * manual page. The difference apparently involved a note about the + * famous rules 5 and 6, recommending using white space between an option + * and its first argument, and not grouping options that have arguments. + * Getopt itself is currently lenient about both of these things White + * space is allowed, but not mandatory, and the last option in a group can + * have an argument. That particular version of the man page evidently + * has no official existence, and my source at AT&T did not send a copy. + * The current SVR2 man page reflects the actual behavor of this getopt. + * However, I am not about to post a copy of anything licensed by AT&T. + */ +#include +#include +#include "fsl_str.h" +#if SDK_DEBUGCONSOLE +#define DEBUG_CONSOLE_PRINTF_MAX_LOG_LEN 128u +static void DbgConsole_RelocateLog(char *buf, int32_t *indicator, char val, int len) +{ + int i = 0; + + for (i = 0; i < len; i++) + { + if ((*indicator + 1) >= DEBUG_CONSOLE_PRINTF_MAX_LOG_LEN) + { + LOG_Push((uint8_t *)buf, *indicator); + *indicator = 0U; + } + + buf[*indicator] = val; + (*indicator)++; + } +} + +int csp_printf(const char *fmt_s, ...) +{ + va_list ap; + int logLength = 0U, result = 0U; + char printBuf[DEBUG_CONSOLE_PRINTF_MAX_LOG_LEN] = {0U}; + + va_start(ap, fmt_s); + /* format print log first */ + logLength = StrFormatPrintf(fmt_s, ap, printBuf, DbgConsole_RelocateLog); + /* print log */ + result = LOG_Push((uint8_t *)printBuf, logLength); + + va_end(ap); + + return result; +} +#else +int csp_printf(const char *fmt, ...){return 0;} +#endif + diff --git a/platform/mcu/lpc54102/hal/hal_flash.c b/platform/mcu/lpc54102/hal/hal_flash.c new file mode 100644 index 0000000000..fdad4ccae6 --- /dev/null +++ b/platform/mcu/lpc54102/hal/hal_flash.c @@ -0,0 +1,553 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * POSIX getopt for Windows + * Code given out at the 1985 UNIFORUM conference in Dallas. + * + * From std-unix@ut-sally.UUCP (Moderator, John Quarterman) Sun Nov 3 14:34:15 1985 + * Relay-Version: version B 2.10.3 4.3bsd-beta 6/6/85; site gatech.CSNET + * Posting-Version: version B 2.10.2 9/18/84; site ut-sally.UUCP + * Path: gatech!akgua!mhuxv!mhuxt!mhuxr!ulysses!allegra!mit-eddie!genrad!panda!talcott!harvard!seismo!ut-sally!std-unix + * From: std-unix@ut-sally.UUCP (Moderator, John Quarterman) + * Newsgroups: mod.std.unix + * Subject: public domain AT&T getopt source + * Message-ID: <3352@ut-sally.UUCP> + * Date: 3 Nov 85 19:34:15 GMT + * Date-Received: 4 Nov 85 12:25:09 GMT + * Organization: IEEE/P1003 Portable Operating System Environment Committee + * Lines: 91 + * Approved: jsq@ut-sally.UUC + * Here's something you've all been waiting for: the AT&T public domain + * source for getopt(3). It is the code which was given out at the 1985 + * UNIFORUM conference in Dallas. I obtained it by electronic mail + * directly from AT&T. The people there assure me that it is indeed + * in the public domain + * There is no manual page. That is because the one they gave out at + * UNIFORUM was slightly different from the current System V Release 2 + * manual page. The difference apparently involved a note about the + * famous rules 5 and 6, recommending using white space between an option + * and its first argument, and not grouping options that have arguments. + * Getopt itself is currently lenient about both of these things White + * space is allowed, but not mandatory, and the last option in a group can + * have an argument. That particular version of the man page evidently + * has no official existence, and my source at AT&T did not send a copy. + * The current SVR2 man page reflects the actual behavor of this getopt. + * However, I am not about to post a copy of anything licensed by AT&T. + */ +#include +#include +#include + +#include "fsl_device_registers.h" +#include "fsl_common.h" +#include "fsl_clock.h" +#include "fsl_power.h" +#include "hal/soc/flash.h" +#include "fsl_flashiap.h" + + +typedef int32_t (*flash_device_erase)(uint32_t phy_address, uint32_t size); +typedef int32_t (*flash_device_write)(uint32_t phy_address, const void *data, uint32_t size); +typedef int32_t (*flash_device_read)(uint32_t phy_address, void *data, uint32_t size); + +typedef struct +{ + uint32_t start_address; + uint32_t disk_size; + uint32_t page_size; + uint32_t sector_size; + flash_device_erase erase; + flash_device_write write; + flash_device_read read; +} flash_device_t; + + +//static uint8_t page_buffer[FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES]; + +static int32_t embedded_flash_erase(uint32_t phy_address, uint32_t size) +{ + int32_t ret = 0; + uint32_t system_clock = 0; + status_t status = 0; + + uint32_t start_sector = 0; + uint32_t end_sector = 0; + uint32_t sectors_to_erase = 0; + uint32_t start_page = 0; + uint32_t end_page = 0; + uint32_t pages_to_erase = 0; + + uint32_t write_step1_size = 0; + uint32_t write_step2_size = 0; + uint32_t residue = size; + + /* FLASH Controller Clock should be enabled firstly */ + CLOCK_EnableClock(kCLOCK_Flash); + + system_clock = CLOCK_GetMainClkFreq(); + /* Step 1, Erase flash until sector boundary or end */ + if (phy_address % FSL_FEATURE_SYSCON_FLASH_SECTOR_SIZE_BYTES != 0) // Not at sector boundary + { + write_step1_size = FSL_FEATURE_SYSCON_FLASH_SECTOR_SIZE_BYTES - + phy_address % FSL_FEATURE_SYSCON_FLASH_SECTOR_SIZE_BYTES; + if (size < write_step1_size) + { + write_step1_size = size; + } + + if((phy_address % FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES) != 0) + { + ret = -EIO; //Not supported yet + goto exit; + } + + if((write_step1_size % FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES) != 0) + { + ret = -EIO; + goto exit; + } + + start_sector = phy_address/FSL_FEATURE_SYSCON_FLASH_SECTOR_SIZE_BYTES; + start_page = phy_address / FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES; + + __disable_irq(); + status = FLASHIAP_PrepareSectorForWrite(start_sector, start_sector); + if (status != kStatus_FLASHIAP_Success) { + __enable_irq(); + ret = -EIO; //Check status flag for detail error + goto exit; + } + pages_to_erase = write_step1_size / FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES; + end_page = start_page + pages_to_erase - 1; + + status = FLASHIAP_ErasePage(start_page, end_page, system_clock); + if (status != kStatus_FLASHIAP_Success) { + __enable_irq(); + ret = -EIO; //Check status flag for detail error + goto exit; + } + __enable_irq(); + } + + residue = size - write_step1_size; + + sectors_to_erase = residue / FSL_FEATURE_SYSCON_FLASH_SECTOR_SIZE_BYTES; + + /* Step 2, sector erasing */ + if(sectors_to_erase > 0) { /* More than one sector to erase */ + start_sector = (phy_address + write_step1_size) / FSL_FEATURE_SYSCON_FLASH_SECTOR_SIZE_BYTES; + end_sector = start_sector + sectors_to_erase - 1; + __disable_irq(); + status = FLASHIAP_PrepareSectorForWrite(start_sector, end_sector); + if (status != kStatus_FLASHIAP_Success) { + __enable_irq(); + ret = -EIO; //Check status flag for detailed error + goto exit; + } + status = FLASHIAP_EraseSector(start_sector, end_sector, system_clock); + if (status != kStatus_FLASHIAP_Success) { + __enable_irq(); + ret = -EIO; //Check status flag for detailed error + goto exit; + } + __enable_irq(); + write_step2_size = FSL_FEATURE_SYSCON_FLASH_SECTOR_SIZE_BYTES * sectors_to_erase; + } + + residue = size - write_step1_size - write_step2_size; + /* Step 3, erasing residues */ + if (residue > 0) + { + if (residue % FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES != 0) + { + ret = -EIO; //Check status flag for detailed error + goto exit; + } + start_sector = (phy_address + write_step1_size + write_step2_size) / FSL_FEATURE_SYSCON_FLASH_SECTOR_SIZE_BYTES; + start_page = (phy_address + write_step1_size + write_step2_size) / FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES; + + __disable_irq(); + status = FLASHIAP_PrepareSectorForWrite(start_sector, start_sector); + if (status != kStatus_FLASHIAP_Success) + { + __enable_irq(); + ret = -EIO; + goto exit; + } + pages_to_erase = residue / FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES; + end_page = start_page + pages_to_erase - 1; + + status = FLASHIAP_ErasePage(start_page, end_page, system_clock); + if (status != kStatus_FLASHIAP_Success) { + __enable_irq(); + ret = -EIO; //Check status flag for detail error + goto exit; + } + __enable_irq(); + } +exit: + CLOCK_DisableClock(kCLOCK_Flash); + return ret; +} + +static int32_t embedded_flash_write(uint32_t phy_address, const void *data, uint32_t size) +{ + int32_t ret = 0; + uint32_t system_clock = 0; + status_t status = 0; + + uint32_t start_sector = 0; + uint32_t end_sector = 0; + + /* FLASH Program size 256 | 512 | 1024 | 4096 */ + uint16_t write_size_option[4] = {256, 512, 1024, 4096}; + uint8_t option = 0; + uint32_t offset = 0; + + + /* FLASH Controller Clock should be enabled firstly */ + CLOCK_EnableClock(kCLOCK_Flash); + system_clock = CLOCK_GetMainClkFreq(); + if (phy_address % FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES != 0) + { + ret = -EIO; // Not Support yet + goto exit; + } + + if (size % FSL_FEATURE_SYSCON_FLASH_PAGE_SIZE_BYTES != 0) + { + ret = -EIO; + goto exit; + } + + while (offset < size) { + start_sector = (phy_address + offset)/FSL_FEATURE_SYSCON_FLASH_SECTOR_SIZE_BYTES; + option = sizeof(write_size_option)/sizeof(write_size_option[0]) - 1; + while(option >= 0) + { + if ((option == 0) || ((size - offset) / write_size_option[option] != 0 && + (phy_address + offset + write_size_option[option]) <= (start_sector + 1) * FSL_FEATURE_SYSCON_FLASH_SECTOR_SIZE_BYTES)) + break; + option--; + } + + end_sector = start_sector; + __disable_irq(); + status = FLASHIAP_PrepareSectorForWrite(start_sector, end_sector); + if (status != kStatus_FLASHIAP_Success) { + __enable_irq(); + ret = -EIO; //Check status flag for detail error + goto exit; + } + + status = FLASHIAP_CopyRamToFlash(phy_address + offset, ((uint32_t *)data) + (offset >> 2), write_size_option[option], system_clock); + if (status != kStatus_FLASHIAP_Success) { + __enable_irq(); + ret = -EIO; //Check status flag for detail error + goto exit; + } + __enable_irq(); + offset += write_size_option[option]; + } + +exit: + CLOCK_DisableClock(kCLOCK_Flash); + return ret; +} + +static int32_t embedded_flash_read(uint32_t phy_address, void *data, uint32_t size) +{ + /* Use Address to access embeded FLASH, it is on the memory map */ + /* Do NOT use this method */ + return -EIO; +} + +static flash_device_t flash_device[HAL_FLASH_MAX] = +{ + { + .start_address = 0, + .disk_size = 0x80000, + .page_size = 0x100, + .sector_size = 0x8000, + embedded_flash_erase, + embedded_flash_write, + embedded_flash_read, + }, + { 0, 0, 0, 0, NULL, NULL, NULL }, + { 0, 0, 0, 0, NULL, NULL, NULL } +}; + + +hal_logic_partition_t hal_logic_partition[HAL_PARTITION_MAX] = +{ + { HAL_FLASH_EMBEDDED, "Bootloader", 0, 0, PAR_OPT_WRITE_DIS|PAR_OPT_READ_DIS}, + { HAL_FLASH_EMBEDDED, "Application", 0x40000, 0x40000, PAR_OPT_WRITE_EN|PAR_OPT_READ_EN}, + { HAL_FLASH_NONE, NULL, 0, 0, PAR_OPT_WRITE_DIS|PAR_OPT_READ_DIS}, + { HAL_FLASH_NONE, NULL, 0, 0, PAR_OPT_WRITE_DIS|PAR_OPT_READ_DIS}, + { HAL_FLASH_NONE, NULL, 0, 0, PAR_OPT_WRITE_DIS|PAR_OPT_READ_DIS}, + { HAL_FLASH_NONE, NULL, 0, 0, PAR_OPT_WRITE_DIS|PAR_OPT_READ_DIS}, + { HAL_FLASH_NONE, NULL, 0, 0, PAR_OPT_WRITE_DIS|PAR_OPT_READ_DIS}, + { HAL_FLASH_NONE, NULL, 0, 0, PAR_OPT_WRITE_DIS|PAR_OPT_READ_DIS}, + { HAL_FLASH_NONE, NULL, 0, 0, PAR_OPT_WRITE_DIS|PAR_OPT_READ_DIS}, + { HAL_FLASH_NONE, NULL, 0, 0, PAR_OPT_WRITE_DIS|PAR_OPT_READ_DIS}, +}; + + +/** + * Get the infomation of the specified flash area + * + * @param[in] in_partition The target flash logical partition which should be erased + * + * @return HAL_logi_partition struct + */ +/* FIXME: Return value should be a CONST */ +hal_logic_partition_t *hal_flash_get_info(hal_partition_t in_partition) +{ + hal_logic_partition_t *p_logic_partition = NULL; + + if (in_partition >= HAL_PARTITION_MAX) { + return NULL; + } + + switch (in_partition) + { + case HAL_PARTITION_APPLICATION: + p_logic_partition = &hal_logic_partition[in_partition]; + break; + default: + break; + } + return p_logic_partition; +} + +/** + * Erase an area on a Flash logical partition + * + * @note Erase on an address will erase all data on a sector that the + * address is belonged to, this function does not save data that + * beyond the address area but in the affected sector, the data + * will be lost. + * + * @param[in] in_partition The target flash logical partition which should be erased + * @param[in] off_set Start address of the erased flash area + * @param[in] size Size of the erased flash area + * + * @return 0 : On success, EIO : If an error occurred with any step + */ +int32_t hal_flash_erase(hal_partition_t in_partition, uint32_t off_set, uint32_t size) +{ + hal_logic_partition_t *p_logic_partition = NULL; + uint32_t start_addr_phy = 0; + flash_device_t *device = NULL; + int32_t ret = 0; + + p_logic_partition = hal_flash_get_info(in_partition); + if ((p_logic_partition == NULL) || (p_logic_partition->partition_owner == HAL_FLASH_NONE)) + { + return -EIO; + } + + device = &flash_device[p_logic_partition->partition_owner]; + + start_addr_phy = off_set + device->start_address; + if (start_addr_phy + size > device->disk_size) + { + return -EIO; + } + + ret = device->erase(start_addr_phy, size); + + return ret; +} + +/** + * Write data to an area on a flash logical partition without erase + * + * @param[in] in_partition The target flash logical partition which should be read which should be written + * @param[in] off_set Point to the start address that the data is written to, and + * point to the last unwritten address after this function is + * returned, so you can call this function serval times without + * update this start address. + * @param[in] inBuffer point to the data buffer that will be written to flash + * @param[in] inBufferLength The length of the buffer + * + * @return 0 : On success, EIO : If an error occurred with any step + */ +int32_t hal_flash_write(hal_partition_t in_partition, uint32_t *off_set, + const void *in_buf, uint32_t in_buf_len) +{ + hal_logic_partition_t *p_logic_partition = NULL; + uint32_t start_addr_phy = 0; + flash_device_t *device = NULL; + int32_t ret = 0; + + p_logic_partition = hal_flash_get_info(in_partition); + if ((p_logic_partition == NULL) || (p_logic_partition->partition_owner == HAL_FLASH_NONE)) + { + return -EIO; + } + + device = &flash_device[p_logic_partition->partition_owner]; + + start_addr_phy = *off_set + device->start_address; + if ((uint32_t)start_addr_phy + in_buf_len > device->disk_size) + { + return -EIO; + } + + ret = device->write(start_addr_phy, in_buf, in_buf_len); + *off_set += in_buf_len; + + return ret; +} + +/** + * Write data to an area on a flash logical partition with erase first + * + * @param[in] in_partition The target flash logical partition which should be read which should be written + * @param[in] off_set Point to the start address that the data is written to, and + * point to the last unwritten address after this function is + * returned, so you can call this function serval times without + * update this start address. + * @param[in] inBuffer point to the data buffer that will be written to flash + * @param[in] inBufferLength The length of the buffer + * + * @return 0 : On success, EIO : If an error occurred with any step + */ +int32_t hal_flash_erase_write(hal_partition_t in_partition, uint32_t *off_set, + const void *in_buf, uint32_t in_buf_len) +{ + hal_logic_partition_t *p_logic_partition = NULL; + uint32_t start_addr_phy = 0; + flash_device_t *device = NULL; + int32_t ret = 0; + + p_logic_partition = hal_flash_get_info(in_partition); + if ((p_logic_partition == NULL) || (p_logic_partition->partition_owner == HAL_FLASH_NONE)) + { + return -EIO; + } + + device = &flash_device[p_logic_partition->partition_owner]; + + start_addr_phy = *off_set + device->start_address + p_logic_partition->partition_start_addr; + if (start_addr_phy + in_buf_len > device->disk_size) + { + return -EIO; + } + + ret = device->erase(start_addr_phy, in_buf_len); + if (ret < 0) + { + return ret; + } + + ret = device->write(start_addr_phy, in_buf, in_buf_len); + + *off_set += in_buf_len; + + return ret; +} + +/** + * Read data from an area on a Flash to data buffer in RAM + * + * @param[in] in_partition The target flash logical partition which should be read + * @param[in] off_set Point to the start address that the data is read, and + * point to the last unread address after this function is + * returned, so you can call this function serval times without + * update this start address. + * @param[in] outBuffer Point to the data buffer that stores the data read from flash + * @param[in] inBufferLength The length of the buffer + * + * @return 0 : On success, EIO : If an error occurred with any step + */ +int32_t hal_flash_read(hal_partition_t in_partition, uint32_t *off_set, + void *out_buf, uint32_t in_buf_len) +{ + hal_logic_partition_t *p_logic_partition = NULL; + uint32_t start_addr_phy = 0; + flash_device_t *device = NULL; + int32_t ret = 0; + + p_logic_partition = hal_flash_get_info(in_partition); + if ((p_logic_partition == NULL) || (p_logic_partition->partition_owner == HAL_FLASH_NONE)) + { + return -EIO; + } + + device = &flash_device[p_logic_partition->partition_owner]; + + start_addr_phy = *off_set + device->start_address; + if (start_addr_phy + in_buf_len > device->disk_size) + { + return -EIO; + } + + ret = device->read(start_addr_phy, out_buf, in_buf_len); + + *off_set += in_buf_len; + + return ret; +} + +/** + * Set security options on a logical partition + * + * @param[in] partition The target flash logical partition + * @param[in] offset Point to the start address that the data is read, and + * point to the last unread address after this function is + * returned, so you can call this function serval times without + * update this start address. + * @param[in] size Size of enabled flash area + * + * @return 0 : On success, EIO : If an error occurred with any step + */ +int32_t hal_flash_enable_secure(hal_partition_t partition, uint32_t off_set, uint32_t size) +{ + return 0; +} + +/** + * Disable security options on a logical partition + * + * @param[in] partition The target flash logical partition + * @param[in] offset Point to the start address that the data is read, and + * point to the last unread address after this function is + * returned, so you can call this function serval times without + * update this start address. + * @param[in] size Size of disabled flash area + * + * @return 0 : On success, EIO : If an error occurred with any step + */ +int32_t hal_flash_dis_secure(hal_partition_t partition, uint32_t off_set, uint32_t size) +{ + return 0; +} + diff --git a/platform/mcu/lpc54102/hal/hal_ota.c b/platform/mcu/lpc54102/hal/hal_ota.c new file mode 100644 index 0000000000..e58bef4041 --- /dev/null +++ b/platform/mcu/lpc54102/hal/hal_ota.c @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * POSIX getopt for Windows + * Code given out at the 1985 UNIFORUM conference in Dallas. + * + * From std-unix@ut-sally.UUCP (Moderator, John Quarterman) Sun Nov 3 14:34:15 1985 + * Relay-Version: version B 2.10.3 4.3bsd-beta 6/6/85; site gatech.CSNET + * Posting-Version: version B 2.10.2 9/18/84; site ut-sally.UUCP + * Path: gatech!akgua!mhuxv!mhuxt!mhuxr!ulysses!allegra!mit-eddie!genrad!panda!talcott!harvard!seismo!ut-sally!std-unix + * From: std-unix@ut-sally.UUCP (Moderator, John Quarterman) + * Newsgroups: mod.std.unix + * Subject: public domain AT&T getopt source + * Message-ID: <3352@ut-sally.UUCP> + * Date: 3 Nov 85 19:34:15 GMT + * Date-Received: 4 Nov 85 12:25:09 GMT + * Organization: IEEE/P1003 Portable Operating System Environment Committee + * Lines: 91 + * Approved: jsq@ut-sally.UUC + * Here's something you've all been waiting for: the AT&T public domain + * source for getopt(3). It is the code which was given out at the 1985 + * UNIFORUM conference in Dallas. I obtained it by electronic mail + * directly from AT&T. The people there assure me that it is indeed + * in the public domain + * There is no manual page. That is because the one they gave out at + * UNIFORUM was slightly different from the current System V Release 2 + * manual page. The difference apparently involved a note about the + * famous rules 5 and 6, recommending using white space between an option + * and its first argument, and not grouping options that have arguments. + * Getopt itself is currently lenient about both of these things White + * space is allowed, but not mandatory, and the last option in a group can + * have an argument. That particular version of the man page evidently + * has no official existence, and my source at AT&T did not send a copy. + * The current SVR2 man page reflects the actual behavor of this getopt. + * However, I am not about to post a copy of anything licensed by AT&T. + */ +#include "hal/ota.h" +#include "hal/soc/flash.h" +#include "fsl_debug_console.h" + +int lpc54102_ota_init(hal_ota_module_t *m, void *something) +{ + PRINTF("lpc54102_ota_init\r\n"); + + return 0; +} +int lpc54102_ota_write(hal_ota_module_t *m, volatile uint32_t *off_set, + uint8_t *in_buf , uint32_t in_buf_len) +{ + PRINTF("lpc54102_ota_write\r\n"); + return hal_flash_erase_write(HAL_PARTITION_APPLICATION, (uint32_t *)off_set, in_buf, in_buf_len); +} + +int lpc54102_ota_read(hal_ota_module_t *m, volatile uint32_t *off_set, + uint8_t *out_buf , uint32_t out_buf_len) +{ + PRINTF("lpc54102_ota_read\r\n"); + return 0; +} + +int lpc54102_ota_set_boot(hal_ota_module_t *m, void *something) +{ + PRINTF("lpc54102_ota_set_boot\r\n"); + return 0; +} + + +struct hal_ota_module_s hal_lpc54102_ota_module = { + .init = lpc54102_ota_init, + .ota_write = lpc54102_ota_write, + .ota_read = lpc54102_ota_read, + .ota_set_boot = lpc54102_ota_set_boot, +}; + + diff --git a/platform/mcu/lpc54102/hal/hal_uart.c b/platform/mcu/lpc54102/hal/hal_uart.c new file mode 100644 index 0000000000..a99734f44d --- /dev/null +++ b/platform/mcu/lpc54102/hal/hal_uart.c @@ -0,0 +1,295 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * POSIX getopt for Windows + * Code given out at the 1985 UNIFORUM conference in Dallas. + * + * From std-unix@ut-sally.UUCP (Moderator, John Quarterman) Sun Nov 3 14:34:15 1985 + * Relay-Version: version B 2.10.3 4.3bsd-beta 6/6/85; site gatech.CSNET + * Posting-Version: version B 2.10.2 9/18/84; site ut-sally.UUCP + * Path: gatech!akgua!mhuxv!mhuxt!mhuxr!ulysses!allegra!mit-eddie!genrad!panda!talcott!harvard!seismo!ut-sally!std-unix + * From: std-unix@ut-sally.UUCP (Moderator, John Quarterman) + * Newsgroups: mod.std.unix + * Subject: public domain AT&T getopt source + * Message-ID: <3352@ut-sally.UUCP> + * Date: 3 Nov 85 19:34:15 GMT + * Date-Received: 4 Nov 85 12:25:09 GMT + * Organization: IEEE/P1003 Portable Operating System Environment Committee + * Lines: 91 + * Approved: jsq@ut-sally.UUC + * Here's something you've all been waiting for: the AT&T public domain + * source for getopt(3). It is the code which was given out at the 1985 + * UNIFORUM conference in Dallas. I obtained it by electronic mail + * directly from AT&T. The people there assure me that it is indeed + * in the public domain + * There is no manual page. That is because the one they gave out at + * UNIFORUM was slightly different from the current System V Release 2 + * manual page. The difference apparently involved a note about the + * famous rules 5 and 6, recommending using white space between an option + * and its first argument, and not grouping options that have arguments. + * Getopt itself is currently lenient about both of these things White + * space is allowed, but not mandatory, and the last option in a group can + * have an argument. That particular version of the man page evidently + * has no official existence, and my source at AT&T did not send a copy. + * The current SVR2 man page reflects the actual behavor of this getopt. + * However, I am not about to post a copy of anything licensed by AT&T. + */ +#include +#include +#include +#include "hal/soc/uart.h" +#include "fsl_device_registers.h" +#include "fsl_common.h" +#include "fsl_clock.h" +#include "fsl_usart.h" + +#include "fsl_debug_console.h" + + +static const uint32_t s_uartBaseAddrs[FSL_FEATURE_SOC_USART_COUNT] = USART_BASE_ADDRS; + +/* Global Variable for VFS DEBUG Output */ +uart_dev_t uart_0 = { + .port = 0, /* uart port */ + .config = {115200, DATA_WIDTH_8BIT, NO_PARITY, STOP_BITS_1, FLOW_CONTROL_DISABLED}, /* uart config */ + .priv = NULL /* priv data */ +}; + +uart_dev_t uart_1 = { + .port = 1, /* uart port */ + .config = {115200, DATA_WIDTH_8BIT, NO_PARITY, STOP_BITS_1, FLOW_CONTROL_DISABLED}, /* uart config */ + .priv = NULL /* priv data */ +}; + +uart_dev_t uart_2 = { + .port = 2, /* uart port */ + .config = {115200, DATA_WIDTH_8BIT, NO_PARITY, STOP_BITS_1, FLOW_CONTROL_DISABLED}, /* uart config */ + .priv = NULL /* priv data */ +}; + +uart_dev_t uart_3 = { + .port = 3, /* uart port */ + .config = {115200, DATA_WIDTH_8BIT, NO_PARITY, STOP_BITS_1, FLOW_CONTROL_DISABLED}, /* uart config */ + .priv = NULL /* priv data */ +}; + +uart_dev_t uart_4 = { + .port = 4, /* uart port */ + .config = {115200, DATA_WIDTH_8BIT, NO_PARITY, STOP_BITS_1, FLOW_CONTROL_DISABLED}, /* uart config */ + .priv = NULL /* priv data */ +}; +/** + * Initialises a UART interface + * + * + * @param[in] uart the interface which should be initialised + * + * @return 0 : on success, EIO : if an error occurred with any step + */ +int32_t hal_uart_init(uart_dev_t *uart) +{ + usart_config_t config = {0}; + status_t status; + + config.baudRate_Bps = uart->config.baud_rate; + config.enableRx = true; + config.enableTx = true; + config.loopback = false; + config.fifoConfig.enableTxFifo = false; + config.fifoConfig.enableRxFifo = false; + + switch(uart->config.parity) + { + case NO_PARITY: + config.parityMode = kUSART_ParityDisabled; + break; + case ODD_PARITY: + config.parityMode = kUSART_ParityOdd; + break; + case EVEN_PARITY: + config.parityMode = kUSART_ParityEven; + break; + default: + return -EIO; + } + + switch(uart->config.data_width) + { + case DATA_WIDTH_7BIT: + config.bitCountPerChar = kUSART_7BitsPerChar; + break; + case DATA_WIDTH_8BIT: + config.bitCountPerChar = kUSART_8BitsPerChar; + break; + default: + return -EIO; + } + + switch(uart->config.stop_bits) + { + case STOP_BITS_1: + config.stopBitCount = kUSART_OneStopBit; + break; + case STOP_BITS_2: + config.stopBitCount = kUSART_TwoStopBit; + break; + default: + return -EIO; + } + + status = USART_Init((USART_Type *)s_uartBaseAddrs[uart->port], &config, CLOCK_GetFreq(kCLOCK_Usart)); + + if(kStatus_Success != status) + return -EIO; + + return 0; +} + +/** + * Transmit data on a UART interface + * + * @param[in] uart the UART interface + * @param[in] data pointer to the start of data + * @param[in] size number of bytes to transmit + * + * @return 0 : on success, EIO : if an error occurred with any step + */ +int32_t hal_uart_send(uart_dev_t *uart, const void *data, uint32_t size, uint32_t timeout) +{ + USART_WriteBlocking((USART_Type *)s_uartBaseAddrs[uart->port], data, size); + return 0; +} + +/** + * Receive data on a UART interface + * + * @param[in] uart the UART interface + * @param[out] data pointer to the buffer which will store incoming data + * @param[in] expect_size number of bytes to receive + * @param[out] recv_size number of bytes received + * @param[in] timeout timeout in milisecond + * + * @return 0 : on success, EIO : if an error occurred with any step + */ +int32_t hal_uart_recv(uart_dev_t *uart, void *data, uint32_t expect_size, uint32_t *recv_size, uint32_t timeout) +{ + USART_Type *base = (USART_Type *)s_uartBaseAddrs[uart->port]; + uint8_t *data8 = (uint8_t *)data; + uint32_t status; + uint32_t count = 0; + uint32_t instance = 0U; + + if(recv_size != NULL) + *recv_size = 0; + + instance = USART_GetInstance(base); + + for (; expect_size > 0; expect_size--) + { + if (USART_IsRxFifoEnable(base)) + { + if((VFIFO->USART[instance].STATUSART & VFIFO_USART_STATUSART_RXEMPTY_MASK)) + { + return -EIO; + } + + status = VFIFO->USART[instance].STATUSART; + if (status & VFIFO_USART_STATUSART_BUSERR_MASK) + { + return -EIO; + } + status = VFIFO->USART[instance].RXDATSTATUSART; + if (status & VFIFO_USART_RXDATSTATUSART_FRAMERR_MASK) + { + return -EIO; + } + if (status & VFIFO_USART_RXDATSTATUSART_PARITYERR_MASK) + { + return -EIO; + } + if (status & VFIFO_USART_RXDATSTATUSART_RXNOISE_MASK) + { + return -EIO; + } + *data8 = (status & VFIFO_USART_RXDATSTATUSART_RXDAT_MASK); + } + else + { + if (!(base->STAT & USART_STAT_RXRDY_MASK)) + { + return -EIO; + } + /* Check receive status */ + status = base->STAT; + + if (status & USART_STAT_FRAMERRINT_MASK) + { + base->STAT |= USART_STAT_FRAMERRINT_MASK; + return -EIO; + } + if (status & USART_STAT_PARITYERRINT_MASK) + { + base->STAT |= USART_STAT_PARITYERRINT_MASK; + return -EIO; + } + if (status & USART_STAT_RXNOISEINT_MASK) + { + base->STAT |= USART_STAT_RXNOISEINT_MASK; + return -EIO; + } + if (base->STAT & USART_STAT_OVERRUNINT_MASK) + { + base->STAT |= USART_STAT_OVERRUNINT_MASK; + return -EIO; + } + *data8 = base->RXDAT; + } + data8++; + count++; + if(recv_size != NULL) + *recv_size = count; + } + + return 0; +} + +/** + * Deinitialises a UART interface + * + * @param[in] uart the interface which should be deinitialised + * + * @return 0 : on success, EIO : if an error occurred with any step + */ +int32_t hal_uart_finalize(uart_dev_t *uart) +{ + USART_Deinit((USART_Type *)s_uartBaseAddrs[uart->port]); + return 0; +} + + diff --git a/platform/mcu/lpc54102/hal/hal_wifi_wmi.c b/platform/mcu/lpc54102/hal/hal_wifi_wmi.c new file mode 100644 index 0000000000..30b1700ba2 --- /dev/null +++ b/platform/mcu/lpc54102/hal/hal_wifi_wmi.c @@ -0,0 +1,587 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * POSIX getopt for Windows + * Code given out at the 1985 UNIFORUM conference in Dallas. + * + * From std-unix@ut-sally.UUCP (Moderator, John Quarterman) Sun Nov 3 14:34:15 1985 + * Relay-Version: version B 2.10.3 4.3bsd-beta 6/6/85; site gatech.CSNET + * Posting-Version: version B 2.10.2 9/18/84; site ut-sally.UUCP + * Path: gatech!akgua!mhuxv!mhuxt!mhuxr!ulysses!allegra!mit-eddie!genrad!panda!talcott!harvard!seismo!ut-sally!std-unix + * From: std-unix@ut-sally.UUCP (Moderator, John Quarterman) + * Newsgroups: mod.std.unix + * Subject: public domain AT&T getopt source + * Message-ID: <3352@ut-sally.UUCP> + * Date: 3 Nov 85 19:34:15 GMT + * Date-Received: 4 Nov 85 12:25:09 GMT + * Organization: IEEE/P1003 Portable Operating System Environment Committee + * Lines: 91 + * Approved: jsq@ut-sally.UUC + * Here's something you've all been waiting for: the AT&T public domain + * source for getopt(3). It is the code which was given out at the 1985 + * UNIFORUM conference in Dallas. I obtained it by electronic mail + * directly from AT&T. The people there assure me that it is indeed + * in the public domain + * There is no manual page. That is because the one they gave out at + * UNIFORUM was slightly different from the current System V Release 2 + * manual page. The difference apparently involved a note about the + * famous rules 5 and 6, recommending using white space between an option + * and its first argument, and not grouping options that have arguments. + * Getopt itself is currently lenient about both of these things White + * space is allowed, but not mandatory, and the last option in a group can + * have an argument. That particular version of the man page evidently + * has no official existence, and my source at AT&T did not send a copy. + * The current SVR2 man page reflects the actual behavor of this getopt. + * However, I am not about to post a copy of anything licensed by AT&T. + */ + +#include +#include +#include +#include "hal/wifi.h" +#include "qcom_api.h" +#include "fsl_debug_console.h" + +#define WIFI_CONNECT_TIMEOUT_MS 20000 //20s +#define WIFI_DHCP_RETRY_TIME 20 +static int8_t _traceQcomApi = 1; + +static volatile int32_t devId = 0; +static volatile int8_t _isConnected = 0; +static ksem_t wifi_event_sem; + + +#define UINT32_IPADDR_TO_CSV_BYTES(a) (((a) >> 24) & 0xFF), (((a) >> 16) & 0xFF), (((a) >> 8) & 0xFF), ((a)&0xFF) +static void parseIPv4(char *in, uint8_t *addr) +{ + int8_t i, j; + for (i = 3; i >= 0; i--) { + for (j = 0; j < 3; j++) { + if(('0' <= in[j]) && (in[j] <= '9')) { + addr[i] *= 10; + addr[i] += (in[j] - 0x30); + } else { + break; + } + } + in += (j + 1); + } +} + +static void printError(uint32_t value, const char *funcName) +{ + PRINTF("ERROR: %s() returned %d\r\n", funcName, value); +} + +static int isQcomError(A_STATUS status, const char *funcName) +{ + if (status != A_OK) + { + printError(status, funcName); + } + else if (_traceQcomApi) + { + PRINTF("%s() OK\r\n", funcName); + } + return (status != A_OK); +} + +static void hal_wifi_onConnect(uint8_t event, uint8_t devId, char *bssid, uint8_t bssConn) +{ + switch (event) + { + case 1: + if (devId == 0) + { + PRINTF("%s connected\r\n", bssConn ? "AP" : "CLIENT"); + } + else + { + PRINTF("Connected\r\n"); + } + _isConnected = 1; + // NOTE that station is not fully connected until PEER_FIRST_NODE_JOIN_EVENT + krhino_sem_give(&wifi_event_sem); + break; + case 0: + _isConnected = 0; + if (devId == 0) + { + PRINTF("%s disconnect\r\n", bssConn ? "AP" : "CLIENT"); + } + krhino_sem_give(&wifi_event_sem); + break; + case INVALID_PROFILE: + // this event is used to indicate RSNA failure + _isConnected = 0; + PRINTF("4 way handshake failure for device=%d n", devId); + break; + case PEER_FIRST_NODE_JOIN_EVENT: + // this event is used to RSNA success + PRINTF("4 way handshake success for device=%d\r\n", devId); + break; + default: + PRINTF("code %d\r\n"); + } +} + +static void hal_dhcps_cb(void) +{ + PRINTF("DHCP Setup Event\r\n"); + krhino_sem_give(&wifi_event_sem); +} + + +static int wifi_init(hal_wifi_module_t *m) +{ + A_STATUS status = A_OK; + PRINTF("WIFI_Init\r\n"); + + status = WIFISHIELD_Init(); + PRINTF("WIFISHIELD_Init return %d\r\n", status); + if (status != A_OK) { + return status; + } + + status = wlan_driver_start(); + PRINTF("wlan_driver_start return %d\r\n", status); + if (status != A_OK) { + return status; + } + + krhino_sem_create(&wifi_event_sem, "wifi_event_sem", 0); + + return status; +} + +static void wifi_get_mac_addr(hal_wifi_module_t *m, uint8_t *mac) +{ + mac[0] = 0x84; mac[1] = 0x5D; mac[2] = 0xD7; mac[3] = 0x68; mac[4] = 0x3B; mac[5] = 0x91; + PRINTF("wifi_get_mac_addr\r\n"); +} + + +static A_STATUS wifi_start_station(hal_wifi_init_type_t *init_para) +{ + A_STATUS status; + QCOM_SSID q_ssid; + QCOM_PASSPHRASE q_passphrase; + WLAN_CRYPT_TYPE crypto_mode = WLAN_CRYPT_AES_CRYPT; + WLAN_AUTH_MODE authen_mode = WLAN_AUTH_WPA2_PSK; + + // Set station mode to station (0) or AP (1) + status = qcom_op_set_mode(devId, QCOM_WLAN_DEV_MODE_STATION); + if(isQcomError(status, "qcom_op_set_mode")) + return status; + + memcpy(q_ssid.ssid, init_para->wifi_ssid, 33); + // NOTE: qcom API requires to first set a valid SSID (before auth, cipher and passphrase) + status = qcom_set_ssid(devId, &q_ssid); + if(isQcomError(status, "qcom_set_ssid")) + return status; + + status = qcom_sec_set_encrypt_mode(devId, crypto_mode); + if(isQcomError(status, "qcom_sec_set_encrypt_mode")) + return status; + + // Note that only 4 of all modes listed in QCA 80-Y9106-1 are supported! + // The modes are: WLAN_AUTH_NONE, WLAN_AUTH_WPA_PSK, WLAN_AUTH_WPA2_PSK, WLAN_AUTH_WEP + status = qcom_sec_set_auth_mode(devId, WLAN_AUTH_WPA2_PSK); + if(isQcomError(status, "qcom_sec_set_auth_mode")) + return status; + + memcpy(q_passphrase.passphrase, init_para->wifi_key, 65); + // NOTE: The driver insists that the SSID is configured *before* the passphrase + status = qcom_sec_set_passphrase(devId, &q_passphrase); + if(isQcomError(status, "qcom_sec_set_passphrase")) + return status; + + // The connect callback is actually used for four different callbacks: + // onConnect(1 (TRUE), uint8_t devId, uint8_t *ssid, uint8_t bssMac[6]); + // onDisconnect(status, uint8_t devId, uint8_t *ssid, uint8_t bssMac[6]); + // where status = 0x10 (INVALID_PROFILE) on ? + // = 0 on normal disconnect + // onRSNASuccessEvent(uint8_t code, uint8_t devId, NULL, 0) + // onBitRateEvent_tx(wmi_rateTable[rateIndex][0], devId, NULL, 0); + // It is not possible to discern the onBitRateEvent_tx event from the others + status = qcom_set_connect_callback(devId, (void *)hal_wifi_onConnect); + if(isQcomError(status, "qcom_set_connect_callback")) + return status; + + status = qcom_commit(devId); + isQcomError(status, "qcom_commit"); + + return status; +} + +static A_STATUS wifi_start_softAP(hal_wifi_init_type_t *init_para) +{ + A_STATUS status = A_OK; + uint32_t ap_addr = 0; + uint32_t ap_mask = 0; + uint32_t ap_gateway = 0; + + status = qcom_op_set_mode(devId, QCOM_WLAN_DEV_MODE_AP); + if (status != A_OK) { + return status; + } + + /* Set SSID */ + status = qcom_set_ssid(devId, (QCOM_SSID*)"HomeWifi"); + if (status != A_OK) { + return status; + } + + /* Set encryption mode */ + status = qcom_sec_set_encrypt_mode(devId, WLAN_CRYPT_NONE); + if (status != A_OK) { + return status; + } + + /* Set auth mode */ + status = qcom_sec_set_auth_mode(devId, WLAN_AUTH_NONE); + if (status != A_OK) { + return status; + } + + /* Set password */ + status = qcom_sec_set_passphrase(devId, (QCOM_PASSPHRASE*)""); + if (status != A_OK) { + return status; + } + + status = qcom_set_connect_callback(devId, (void *)hal_wifi_onConnect); + if (status != A_OK) { + return status; + } + + status = qcom_commit(devId); + if (status != A_OK) { + return status; + } + + parseIPv4(init_para->local_ip_addr, &ap_addr); + parseIPv4(init_para->net_mask, &ap_mask); + parseIPv4(init_para->gateway_ip_addr, &ap_gateway); + + PRINTF("Configure AP IP:0x%x, MASK:0x%x, GW:0x%x\r\n", ap_addr, ap_mask, ap_gateway); + status = qcom_ipconfig(devId, QCOM_IPCONFIG_STATIC, &ap_addr, &ap_mask, &ap_gateway); + if (status != A_OK) { + return status; + } + + return A_OK; +} + +static int wifi_get_ip_stat(hal_wifi_module_t *m, hal_wifi_ip_stat_t *out_net_para, hal_wifi_type_t wifi_type); +static int wifi_start(hal_wifi_module_t *m, hal_wifi_init_type_t *init_para) +{ + A_STATUS status; + uint32_t retry = 0; + kstat_t wifi_sem_state; + uint32_t q_addr = 0, q_mask = 0, q_gateway = 0; + uint32_t dnsServers[3]; + uint32_t dnsnum = 0; + hal_wifi_ip_stat_t ip_stat; + + PRINTF("wifi_start parameter: Mode - %d\r\n", init_para->wifi_mode); + PRINTF("wifi_start parameter: SSID - %s\r\n", init_para->wifi_ssid); + PRINTF("wifi_start parameter: PASSWORD - %s\r\n", init_para->wifi_key); + + if(init_para->wifi_mode == STATION) + { + status = wifi_start_station(init_para); + if (status != A_OK) { + return status; + } + + wifi_sem_state = krhino_sem_take(&wifi_event_sem, krhino_ms_to_ticks(WIFI_CONNECT_TIMEOUT_MS)); + if (!((RHINO_SUCCESS == wifi_sem_state) && _isConnected)) { + PRINTF("krhino_sem_take state = %d, isConnected = %d\r\n", wifi_sem_state, _isConnected); + return A_TIMEOUT; + } + + if (init_para->dhcp_mode == DHCP_DISABLE) { + parseIPv4(init_para->local_ip_addr, &q_addr); + parseIPv4(init_para->net_mask, &q_mask); + parseIPv4(init_para->gateway_ip_addr, &q_gateway); + } + do { + if (init_para->dhcp_mode == DHCP_CLIENT) { + status = qcom_ipconfig(devId, QCOM_IPCONFIG_DHCP, &q_addr, &q_mask, &q_gateway); + } else if (init_para->dhcp_mode == DHCP_DISABLE) { + status = qcom_ipconfig(devId, QCOM_IPCONFIG_STATIC, &q_addr, &q_mask, &q_gateway); + } + A_MDELAY(50); + q_addr = q_mask = q_gateway = 0; + status = qcom_ipconfig(devId, QCOM_IPCONFIG_QUERY, &q_addr, &q_mask, &q_gateway); + if (q_addr != 0) + break; + } while(retry < WIFI_DHCP_RETRY_TIME); + + if (init_para->dhcp_mode == DHCP_CLIENT) + { + sprintf(init_para->local_ip_addr,"%d.%d.%d.%d", UINT32_IPADDR_TO_CSV_BYTES(q_addr)); + sprintf(init_para->net_mask,"%d.%d.%d.%d", UINT32_IPADDR_TO_CSV_BYTES(q_mask)); + sprintf(init_para->gateway_ip_addr,"%d.%d.%d.%d", UINT32_IPADDR_TO_CSV_BYTES(q_gateway)); + init_para->local_ip_addr[15] = 0; + init_para->net_mask[15] = 0; + init_para->gateway_ip_addr[15] = 0; + } + + PRINTF("IP: %d.%d.%d.%d\r\n", UINT32_IPADDR_TO_CSV_BYTES(q_addr)); + PRINTF("GATEWAY: %d.%d.%d.%d\r\n",UINT32_IPADDR_TO_CSV_BYTES(q_gateway)); + PRINTF("MASK: %d.%d.%d.%d\r\n", UINT32_IPADDR_TO_CSV_BYTES(q_mask)); + + status = qcom_dns_server_address_get(dnsServers, &dnsnum); + if (isQcomError(status, "qcom_dns_server_address_get")) + { + PRINTF("WARNING: No DNS servers returned by DHCP\r\n"); + PRINTF(" You will NOT be able to resolve domain names\r\n"); + return status; + } + + for (int i = 0; i < dnsnum; i++) + { + PRINTF("DNS %d: %d.%d.%d.%d\r\n", i, UINT32_IPADDR_TO_CSV_BYTES(dnsServers[i])); + } + } + else /* WIFI Mode SOFT_AP */ + { + status = wifi_start_softAP(init_para); + if (status != A_OK) { + return status; + } + wifi_sem_state = krhino_sem_take(&wifi_event_sem, krhino_ms_to_ticks(WIFI_CONNECT_TIMEOUT_MS)); + if (!((RHINO_SUCCESS == wifi_sem_state) && _isConnected)) { + return A_TIMEOUT; + } +#define WIFI_SOFTAP_DHCP_BEGIN 0xc0a80164 //192.168.1.100 +#define WIFI_SOFTAP_DHCP_END 0xc0a80196 //192.168.1.150 +#define WIFI_SOFTAP_DHCP_LEASE_TIME (3600) + status = qcom_dhcps_set_pool(devId, WIFI_SOFTAP_DHCP_BEGIN, WIFI_SOFTAP_DHCP_END, WIFI_SOFTAP_DHCP_LEASE_TIME); + if (status != A_OK) { + return status; + } + qcom_dhcps_register_cb(devId, hal_dhcps_cb); + + wifi_sem_state = krhino_sem_take(&wifi_event_sem, RHINO_WAIT_FOREVER); + if (!(RHINO_SUCCESS == wifi_sem_state)) { + return A_TIMEOUT; + } + } + + if (m->ev_cb && m->ev_cb->ip_got) { + PRINTF("m->ev_cb->ip_got \r\n"); + wifi_get_ip_stat(m, &ip_stat, STATION); + m->ev_cb->ip_got(m, &ip_stat, NULL); + } + return status; +} + +static int wifi_start_adv(hal_wifi_module_t *m,hal_wifi_init_type_adv_t *init_para_adv) +{ + PRINTF("wifi_start_adv\r\n"); + return 0; +} + +static int wifi_get_ip_stat(hal_wifi_module_t *m, hal_wifi_ip_stat_t *out_net_para, hal_wifi_type_t wifi_type) +{ + uint32_t q_addr = 0, q_mask = 0, q_gateway = 0; + A_STATUS status; + + q_addr = q_mask = q_gateway = 0; + status = qcom_ipconfig(devId, QCOM_IPCONFIG_QUERY, &q_addr, &q_mask, &q_gateway); + + sprintf(out_net_para->ip,"%d.%d.%d.%d", UINT32_IPADDR_TO_CSV_BYTES(q_addr)); + sprintf(out_net_para->mask,"%d.%d.%d.%d", UINT32_IPADDR_TO_CSV_BYTES(q_mask)); + sprintf(out_net_para->gate,"%d.%d.%d.%d", UINT32_IPADDR_TO_CSV_BYTES(q_gateway)); + + PRINTF("IP %s \r\n", out_net_para->ip); + PRINTF("GATEWAY %s\r\n", out_net_para->gate); + PRINTF("MASK %s\r\n", out_net_para->mask); + + return 0; +} + +static int wifi_get_link_stat(hal_wifi_module_t *m, hal_wifi_link_stat_t *out_stat) +{ + PRINTF("wifi_get_link_stat\r\n"); + return 0; +} + +static void wifi_start_scan(hal_wifi_module_t *m) +{ + A_STATUS status; + QCOM_BSS_SCAN_INFO *scanResult; + int16_t scanNumResults = 0; + hal_wifi_scan_result_t scan_result; + ap_list_t scan_list[12] = {0}; + PRINTF("wifi_start_scan\r\n"); + + status = qcom_set_scan(devId, NULL); + isQcomError(status, "qcom_set_scan"); + + // NOTE: calling qcom_get_scan() before qcom_set_scan() is the same as suspending for 5s, + // i.e. nothing happens for 5s where after 0 is returned + // NOTE: A maximum of 12 results are returned + status = qcom_get_scan(devId, &scanResult, &scanNumResults); + isQcomError(status, "qcom_get_scan"); + + scan_result.ap_num = scanNumResults; + scan_result.ap_list = &scan_list; + + for (int i = 0; i < scanNumResults; i++) + { + QCOM_BSS_SCAN_INFO *scr = &scanResult[i]; + int ssidLen = scr->ssid_len; + scr->ssid[ssidLen] = 0; + + PRINTF("%2d %2d %4d %02x:%02x:%02x:%02x:%02x:%02x %s\r\n", i, scr->channel, scr->rssi, scr->bssid[0], + scr->bssid[1], scr->bssid[2], scr->bssid[3], scr->bssid[4], scr->bssid[5], scr->ssid); + memcpy(scan_list[i].ssid, scr->ssid, scr->ssid_len); + scan_list[i].ap_power = scr->preamble; + } + + if (m->ev_cb && m->ev_cb->scan_compeleted) { + PRINTF("m->ev_cb->scan_compeleted\r\n"); + m->ev_cb->scan_compeleted(m, &scan_result, NULL); + } +} + +static void wifi_start_scan_adv(hal_wifi_module_t *m) +{ + A_STATUS status; + QCOM_BSS_SCAN_INFO *scanResult; + int16_t scanNumResults = 0; + hal_wifi_scan_result_adv_t scan_adv_result; + ap_list_adv_t scan_adv_list[12] = {0}; + + status = qcom_set_scan(devId, NULL); + isQcomError(status, "qcom_set_scan"); + + // NOTE: calling qcom_get_scan() before qcom_set_scan() is the same as suspending for 5s, + // i.e. nothing happens for 5s where after 0 is returned + // NOTE: A maximum of 12 results are returned + status = qcom_get_scan(devId, &scanResult, &scanNumResults); + isQcomError(status, "qcom_get_scan"); + + scan_adv_result.ap_num = scanNumResults; + scan_adv_result.ap_list = &scan_adv_list; + + for (int i = 0; i < scanNumResults; i++) + { + QCOM_BSS_SCAN_INFO *scr = &scanResult[i]; + int ssidLen = scr->ssid_len; + scr->ssid[ssidLen] = 0; + + PRINTF("%2d %2d %4d %02x:%02x:%02x:%02x:%02x:%02x %s\r\n", i, scr->channel, scr->rssi, scr->bssid[0], + scr->bssid[1], scr->bssid[2], scr->bssid[3], scr->bssid[4], scr->bssid[5], scr->ssid); + memcpy(scan_adv_list[i].ssid, scr->ssid, scr->ssid_len); + memcpy(scan_adv_list[i].bssid, scr->bssid, 6); + scan_adv_list[i].ap_power = scr->preamble; + scan_adv_list[i].channel = scr->channel; + } + + if (m->ev_cb && m->ev_cb->scan_adv_compeleted) { + PRINTF("m->ev_cb->scan_adv_compeleted\r\n"); + m->ev_cb->scan_adv_compeleted(m, &scan_adv_list, NULL); + } +} + +static int wifi_power_off(hal_wifi_module_t *m) +{ + PRINTF("wifi_power_off NOT Implemented"); + return 0; +} + +static int wifi_power_on(hal_wifi_module_t *m) +{ + PRINTF("wifi_power_on NOT Implemented"); + return 0; +} + +static int wifi_suspend(hal_wifi_module_t *m) +{ + PRINTF("wifi_suspend NOT Implemented"); + return 0; +} + +static int wifi_suspend_station(hal_wifi_module_t *m) +{ + PRINTF("wifi_suspend_station NOT Implemented"); + return 0; +} + +static int wifi_suspend_soft_ap(hal_wifi_module_t *m) +{ + PRINTF("wifi_suspend_soft_ap NOT Implemented"); + return 0; +} + +static int wifi_set_channel(hal_wifi_module_t *m, int ch) +{ + PRINTF("wifi_set_channel NOT Implemented"); + return 0; +} + +static void wifi_start_monitor(hal_wifi_module_t *m) +{ + PRINTF("wifi_start_monitor NOT Implemented"); +} + +static void wifi_stop_monitor(hal_wifi_module_t *m) +{ + PRINTF("wifi_stop_monitor NOT Implemented"); +} + +static void wifi_register_monitor_cb(hal_wifi_module_t *m, monitor_data_cb_t fn) +{ + PRINTF("wifi_register_monitor_cb NOT Implemented"); +} + +static void wifi_register_wlan_mgnt_monitor_cb(hal_wifi_module_t *m, monitor_data_cb_t fn) +{ + PRINTF("wifi_register_wlan_mgnt_monitor_cb NOT Implemented"); +} + +static int wifi_wlan_send_80211_raw_frame(hal_wifi_module_t *m, uint8_t *buf, int len) +{ + PRINTF("wifi_wlan_send_80211_raw_frame NOT Implemented"); + return 0; +} + +hal_wifi_module_t qca_4002_wmi = { + .base.name = "qca_4002_wmi", + .ev_cb = NULL, + .init = wifi_init, + .get_mac_addr = wifi_get_mac_addr, + .start = wifi_start, + .start_adv = wifi_start_adv, + .get_ip_stat = wifi_get_ip_stat, + .get_link_stat = wifi_get_link_stat, + .start_scan = wifi_start_scan, + .start_scan_adv = wifi_start_scan_adv, + .power_off = wifi_power_off, + .power_on = wifi_power_on, + .suspend = wifi_suspend, + .suspend_station = wifi_suspend_station, + .suspend_soft_ap = wifi_suspend_soft_ap, + .set_channel = wifi_set_channel, + .start_monitor = wifi_start_monitor, + .stop_monitor = wifi_stop_monitor, + .register_monitor_cb = wifi_register_monitor_cb, + .register_wlan_mgnt_monitor_cb = wifi_register_wlan_mgnt_monitor_cb, + .wlan_send_80211_raw_frame = wifi_wlan_send_80211_raw_frame +}; + + diff --git a/platform/mcu/lpc54102/hal/hook_impl.c b/platform/mcu/lpc54102/hal/hook_impl.c new file mode 100644 index 0000000000..ff26c776ea --- /dev/null +++ b/platform/mcu/lpc54102/hal/hook_impl.c @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#include +#include "fsl_debug_console.h" + +void _mytrace_event_create(ktask_t *task, kevent_t *event, const name_t *name, uint32_t flags_init) +{ + PRINTF("_mytrace_event_create TASK 0x%x, event 0x%x, name = %s, %d\r\n", task, event, name, flags_init); +} +void _mytrace_event_get(ktask_t *task, kevent_t *event) +{ + PRINTF("_mytrace_event_get TASK 0x%x, event 0x%x\r\n", task, event); +} +void _mytrace_event_get_blk(ktask_t *task, kevent_t *event, tick_t wait_option) +{ + PRINTF("_mytrace_event_get_blk TASK 0x%x, event 0x%x, wait_option %d\r\n", task, event, wait_option); +} +void _mytrace_event_task_wake(ktask_t *task, ktask_t *task_waked_up, kevent_t *event) +{ + PRINTF("_mytrace_event_task_wake TASK 0x%x, WKTASK 0x%x, EVENT 0x%x\r\n", task, task_waked_up, event); +} +void _mytrace_event_del(ktask_t *task, kevent_t *event) +{ + PRINTF("_mytrace_event_del TASK 0x%x, EVENT 0x%x\r\n", task, event); +} diff --git a/platform/mcu/lpc54102/lpc54102.mk b/platform/mcu/lpc54102/lpc54102.mk new file mode 100644 index 0000000000..9863b3e3b4 --- /dev/null +++ b/platform/mcu/lpc54102/lpc54102.mk @@ -0,0 +1,155 @@ +HOST_OPENOCD := LPC54102 +NAME := lpc54102impl + +$(NAME)_TYPE := kernel + +$(NAME)_COMPONENTS += platform/arch/arm/armv7m +$(NAME)_COMPONENTS += libc rhino hal netmgr framework.common mbedtls cjson cli digest_algorithm fota sal + +GLOBAL_CFLAGS += -DCORE_M4 +GLOBAL_CFLAGS += -fmessage-length=0 +GLOBAL_CFLAGS += -fno-builtin -ffunction-sections -fdata-sections -fno-common -std=gnu99 -nostdlib -DSDK_DEBUGCONSOLE=1 +#GLOBAL_CFLAGS += $(CPU_CFLAGS) -mlittle-endian +GLOBAL_CFLAGS += -mcpu=cortex-m4 -mlittle-endian -mthumb -mthumb-interwork -march=armv7e-m + +GLOBAL_CFLAGS += -DRHINO_CONFIG_TASK_STACK_CUR_CHECK=1 +GLOBAL_ASMFLAGS += -D__MULTICORE_MASTER -D__MULTICORE_M0SLAVE -DMULTICORE_MASTER_SLAVE_M0SLAVE + +GLOBAL_INCLUDES += ../../arch/arm/armv7m/gcc/m4/ + +#GLOBAL_LDFLAGS += -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -march=armv7e-m -mlittle-endian -mthumb-interwork -nostartfiles +GLOBAL_LDFLAGS += -mcpu=cortex-m4 \ + -mthumb -mthumb-interwork \ + -mlittle-endian \ + -nostartfiles \ + $(CLIB_LDFLAGS_NANO_FLOAT) + +GLOBAL_LDFLAGS += -L$(SOURCE_ROOT)platform/mcu/lpc54102/mcuxpresso +ifeq ($(HOST_ARCH),Cortex-M4F) +GLOBAL_LDFLAGS += -lfsl_power_cm4_hard +else ifeq ($(HOST_ARCH),Cortex-M4) +GLOBAL_LDFLAGS += -lfsl_power_lib_cm4 +endif +$(NAME)_CFLAGS += -Wall -Werror -Wno-unused-variable -Wno-unused-parameter -Wno-implicit-function-declaration +$(NAME)_CFLAGS += -Wno-type-limits -Wno-sign-compare -Wno-pointer-sign -Wno-uninitialized +$(NAME)_CFLAGS += -Wno-return-type -Wno-unused-function -Wno-unused-but-set-variable +$(NAME)_CFLAGS += -Wno-unused-value -Wno-strict-aliasing +GLOBAL_CFLAGS += -Wno-format -Wno-incompatible-pointer-types +$(NAME)_SOURCES := + +#$(NAME)_SOURCES += ../../arch/arm/armv7m/gcc/m4/port_c.c +#$(NAME)_SOURCES += ../../arch/arm/armv7m/gcc/m4/port_s.S + +$(NAME)_SOURCES += ./drivers/fsl_adc.c +$(NAME)_SOURCES += ./drivers/fsl_clock.c +$(NAME)_SOURCES += ./drivers/fsl_common.c +$(NAME)_SOURCES += ./drivers/fsl_crc.c +$(NAME)_SOURCES += ./drivers/fsl_ctimer.c +$(NAME)_SOURCES += ./drivers/fsl_dma.c +$(NAME)_SOURCES += ./drivers/fsl_flashiap.c +$(NAME)_SOURCES += ./drivers/fsl_fmeas.c +$(NAME)_SOURCES += ./drivers/fsl_gint.c +$(NAME)_SOURCES += ./drivers/fsl_gpio.c +$(NAME)_SOURCES += ./drivers/fsl_i2c.c +$(NAME)_SOURCES += ./drivers/fsl_i2c_dma.c +$(NAME)_SOURCES += ./drivers/fsl_inputmux.c +$(NAME)_SOURCES += ./drivers/fsl_mrt.c +$(NAME)_SOURCES += ./drivers/fsl_pint.c +$(NAME)_SOURCES += ./drivers/fsl_power.c +$(NAME)_SOURCES += ./drivers/fsl_reset.c +$(NAME)_SOURCES += ./drivers/fsl_rit.c +$(NAME)_SOURCES += ./drivers/fsl_rtc.c +$(NAME)_SOURCES += ./drivers/fsl_sctimer.c +$(NAME)_SOURCES += ./drivers/fsl_spi.c +$(NAME)_SOURCES += ./drivers/fsl_spi_dma.c +$(NAME)_SOURCES += ./drivers/fsl_usart.c +$(NAME)_SOURCES += ./drivers/fsl_usart_dma.c +$(NAME)_SOURCES += ./drivers/fsl_utick.c +$(NAME)_SOURCES += ./drivers/fsl_wwdt.c +$(NAME)_SOURCES += ./system_LPC54102_cm4.c +$(NAME)_SOURCES += ./utilities/log/fsl_log.c +$(NAME)_SOURCES += ./utilities/str/fsl_str.c +$(NAME)_SOURCES += ./utilities/io/fsl_io.c +$(NAME)_SOURCES += ./utilities/fsl_debug_console.c +$(NAME)_SOURCES += ./mcuxpresso/startup_lpc5410x.c +$(NAME)_SOURCES += ./hal/hal_uart.c +$(NAME)_SOURCES += ./hal/csp_log.c +$(NAME)_SOURCES += ./hal/hal_flash.c +$(NAME)_SOURCES += ./hal/hal_wifi_wmi.c +$(NAME)_SOURCES += ./hal/hal_ota.c +$(NAME)_SOURCES += ./aos/aos.c +$(NAME)_SOURCES += ./aos/soc_impl.c +$(NAME)_SOURCES += ./hal/hook_impl.c + + +GLOBAL_CFLAGS += -DA_LITTLE_ENDIAN + +GLOBAL_INCLUDES += ./wifi_qca/common_src/include +GLOBAL_INCLUDES += ./wifi_qca/common_src/hcd +GLOBAL_INCLUDES += ./wifi_qca/common_src/stack_common +GLOBAL_INCLUDES += ./wifi_qca/common_src/wmi +GLOBAL_INCLUDES += ./wifi_qca/custom_src/include +GLOBAL_INCLUDES += ./wifi_qca/custom_src/stack_custom +GLOBAL_INCLUDES += ./wifi_qca/port/boards/lpcxpresso54102/alios/gt202 +GLOBAL_INCLUDES += ./wifi_qca/port/boards/lpcxpresso54102/alios +GLOBAL_INCLUDES += ./wifi_qca/port/drivers/spi_alios +GLOBAL_INCLUDES += ./wifi_qca/port/shields +GLOBAL_INCLUDES += ./wifi_qca/port/env/alios +GLOBAL_INCLUDES += ./wifi_qca/port +GLOBAL_INCLUDES += ./wifi_qca/include +GLOBAL_INCLUDES += ./wifi_qca/include/AR6002/hw2.0/hw +GLOBAL_INCLUDES += ./wifi_qca/include/AR6002 +GLOBAL_INCLUDES += ./wifi_qca + +$(NAME)_SOURCES += ./wifi_qca/common_src/api_interface/api_init.c +$(NAME)_SOURCES += ./wifi_qca/common_src/api_interface/api_ioctl.c +$(NAME)_SOURCES += ./wifi_qca/common_src/api_interface/api_txrx.c +$(NAME)_SOURCES += ./wifi_qca/common_src/api_interface/api_wmi_rx.c +$(NAME)_SOURCES += ./wifi_qca/common_src/bmi/bmi.c +$(NAME)_SOURCES += ./wifi_qca/common_src/driver/driver_diag.c +$(NAME)_SOURCES += ./wifi_qca/common_src/driver/driver_init.c +$(NAME)_SOURCES += ./wifi_qca/common_src/driver/driver_main.c +$(NAME)_SOURCES += ./wifi_qca/common_src/driver/driver_netbuf.c +$(NAME)_SOURCES += ./wifi_qca/common_src/driver/driver_txrx.c +$(NAME)_SOURCES += ./wifi_qca/common_src/htc/htc.c +$(NAME)_SOURCES += ./wifi_qca/common_src/hcd/spi_hcd.c +$(NAME)_SOURCES += ./wifi_qca/common_src/hw_interface/hw_api.c +$(NAME)_SOURCES += ./wifi_qca/common_src/stack_common/api_stack_offload.c +$(NAME)_SOURCES += ./wifi_qca/common_src/qapi/qcom_api.c +$(NAME)_SOURCES += ./wifi_qca/common_src/qapi/qcom_legacy.c +$(NAME)_SOURCES += ./wifi_qca/common_src/reorder/rcv_aggr.c +$(NAME)_SOURCES += ./wifi_qca/common_src/storerecall/dset_api.c +$(NAME)_SOURCES += ./wifi_qca/common_src/storerecall/dset.c +$(NAME)_SOURCES += ./wifi_qca/common_src/storerecall/storerecall.c +$(NAME)_SOURCES += ./wifi_qca/common_src/util/util.c +$(NAME)_SOURCES += ./wifi_qca/common_src/wmi/wmi.c +$(NAME)_SOURCES += ./wifi_qca/custom_src/api_interface/cust_api_init.c +$(NAME)_SOURCES += ./wifi_qca/custom_src/api_interface/cust_api_ioctl.c +$(NAME)_SOURCES += ./wifi_qca/custom_src/api_interface/cust_api_txrx.c +$(NAME)_SOURCES += ./wifi_qca/custom_src/api_interface/cust_api_wmi_rx.c +$(NAME)_SOURCES += ./wifi_qca/custom_src/driver/cust_driver_main.c +$(NAME)_SOURCES += ./wifi_qca/custom_src/driver/cust_driver_netbuf.c +$(NAME)_SOURCES += ./wifi_qca/custom_src/hw_interface/cust_spi_hcd.c +$(NAME)_SOURCES += ./wifi_qca/custom_src/qapi/custom_qcom_api.c +$(NAME)_SOURCES += ./wifi_qca/custom_src/stack_custom/cust_api_stack_offload.c +$(NAME)_SOURCES += ./wifi_qca/custom_src/stack_custom/cust_api_stack_txrx.c + +$(NAME)_SOURCES += ./wifi_qca/port/boards/lpcxpresso54102/alios/wifi_shield.c +$(NAME)_SOURCES += ./wifi_qca/port/boards/lpcxpresso54102/alios/wlan_qca400x.c +$(NAME)_SOURCES += ./wifi_qca/port/env/alios/wifi_env.c +$(NAME)_SOURCES += ./wifi_qca/port/drivers/spi_alios/wifi_spi.c +$(NAME)_SOURCES += ./wifi_qca/port/drivers/spi_alios/wifi_driver_main.c +$(NAME)_SOURCES += ./wifi_qca/port/pin_mux.c + + + +ifndef OVERRIDE_LD_FILE +GLOBAL_LDFLAGS += -T platform/mcu/lpc54102/lpc54102_flash_96K.ld +endif + + + + + + + diff --git a/platform/mcu/lpc54102/lpc54102_flash_96K.ld b/platform/mcu/lpc54102/lpc54102_flash_96K.ld new file mode 100644 index 0000000000..f63c6be266 --- /dev/null +++ b/platform/mcu/lpc54102/lpc54102_flash_96K.ld @@ -0,0 +1,194 @@ +/* + * GENERATED FILE - DO NOT EDIT + * (c) Code Red Technologies Ltd, 2008-2013 + * (c) NXP Semiconductors 2013-2017 + * Generated linker script file for LPC54102J512 + * Created from linkscript.ldt by FMCreateLinkLibraries + * Using Freemarker v2.3.23 + * MCUXpresso IDE Debug Build on Oct 16, 2017 4:42:58 PM + */ + +GROUP ( + libgcc.a + libc.a + libg.a + libm.a + libnosys.a +) + +MEMORY +{ + /* Define each memory region */ + PROGRAM_FLASH (rx) : ORIGIN = 0x0, LENGTH = 0x80000 /* 512K bytes (alias Flash) */ + SRAM0 (rwx) : ORIGIN = 0x2000000, LENGTH = 0x18000 /* 96K bytes (alias RAM) */ + SRAM2 (rwx) : ORIGIN = 0x3400000, LENGTH = 0x2000 /* 8K bytes (alias RAM3) */ +} + + /* Define a symbol for the top of each memory region */ + __base_PROGRAM_FLASH = 0x0 ; /* PROGRAM_FLASH */ + __base_Flash = 0x0 ; /* Flash */ + __top_PROGRAM_FLASH = 0x0 + 0x80000 ; /* 512K bytes */ + __top_Flash = 0x0 + 0x80000 ; /* 512K bytes */ + __base_SRAM0 = 0x2000000 ; /* SRAM0 */ + __top_SRAM0 = 0x2000000 + 0x18000 ; /* 96K bytes */ + __base_SRAM2 = 0x3400000 ; /* SRAM2 */ + __top_SRAM2 = 0x3400000 + 0x2000 ; /* 8K bytes */ + +ENTRY(ResetISR) + +SECTIONS +{ + /* MAIN TEXT SECTION */ + .text : ALIGN(4) + { + FILL(0xff) + __vectors_start__ = ABSOLUTE(.) ; + KEEP(*(.isr_vector)) + /* Global Section Table */ + . = ALIGN(4) ; + __section_table_start = .; + __data_section_table = .; + LONG(LOADADDR(.data)); + LONG( ADDR(.data)); + LONG( SIZEOF(.data)); + LONG(LOADADDR(.data_RAM3)); + LONG( ADDR(.data_RAM3)); + LONG( SIZEOF(.data_RAM3)); + __data_section_table_end = .; + __bss_section_table = .; + LONG( ADDR(.bss)); + LONG( SIZEOF(.bss)); + LONG( ADDR(.bss_RAM3)); + LONG( SIZEOF(.bss_RAM3)); + __bss_section_table_end = .; + __section_table_end = . ; + /* End of Global Section Table */ + + *(.after_vectors*) + + + + } >PROGRAM_FLASH + + .text : ALIGN(4) + { + *(.text*) + *(.rodata .rodata.* .constdata .constdata.*) + . = ALIGN(4); + } > PROGRAM_FLASH + /* + * for exception handling/unwind - some Newlib functions (in common + * with C++ and STDC++) use this. + */ + .ARM.extab : ALIGN(4) + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > PROGRAM_FLASH + __exidx_start = .; + + .ARM.exidx : ALIGN(4) + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > PROGRAM_FLASH + __exidx_end = .; + + _etext = .; + + /* DATA section for SRAM2 */ + .data_RAM3 : ALIGN(4) + { + FILL(0xff) + PROVIDE(__start_data_RAM3 = .) ; + *(.ramfunc.$RAM3) + *(.ramfunc.$SRAM2) + *(.data.$RAM3*) + *(.data.$SRAM2*) + . = ALIGN(4) ; + PROVIDE(__end_data_RAM3 = .) ; + } > SRAM2 AT>PROGRAM_FLASH + + /* MAIN DATA SECTION */ + .uninit_RESERVED : ALIGN(4) + { + KEEP(*(.bss.$RESERVED*)) + . = ALIGN(4) ; + _end_uninit_RESERVED = .; + } > SRAM0 + /* Main DATA section (SRAM0) */ + .data : ALIGN(4) + { + FILL(0xff) + _data = . ; + *(vtable) + *(.ramfunc*) + *(.data*) + . = ALIGN(4) ; + _edata = . ; + } > SRAM0 AT>PROGRAM_FLASH + /* BSS section for SRAM2 */ + .bss_RAM3 : ALIGN(4) + { + PROVIDE(__start_bss_RAM3 = .) ; + *(.bss.$RAM3*) + *(.bss.$SRAM2*) + . = ALIGN (. != 0 ? 4 : 1) ; /* avoid empty segment */ + PROVIDE(__end_bss_RAM3 = .) ; + } > SRAM2 + /* MAIN BSS SECTION */ + .bss : ALIGN(4) + { + _bss = .; + *(.bss*) + *(COMMON) + . = ALIGN(4) ; + _ebss = .; + PROVIDE(end = .); + } > SRAM0 + /* NOINIT section for SRAM2 */ + .noinit_RAM3 (NOLOAD) : ALIGN(4) + { + *(.noinit.$RAM3*) + *(.noinit.$SRAM2*) + . = ALIGN(4) ; + } > SRAM2 + /* DEFAULT NOINIT SECTION */ + .noinit (NOLOAD): ALIGN(4) + { + _noinit = .; + *(.noinit*) + . = ALIGN(4) ; + _end_noinit = .; + } > SRAM0 + .heap : ALIGN(4) + { + PROVIDE(_pvHeapStart = .); + . += 0xE800; + . = ALIGN(4); + PROVIDE(_pvHeapLimit = .); + } > SRAM0 + /* + .heap2stackfill : + { + . += 0x1000; + } > SRAM2 + */ + .stack ORIGIN(SRAM2) : ALIGN(4) + { + _vStackBase = .; + . = ALIGN(4); + . += 0x800; + _vStackTop = .; + _vHeap2Base = .; + . += 0x1800; + } > SRAM2 + + /* ## Create checksum value (used in startup) ## */ + + PROVIDE(__valid_user_code_checksum = 0 - + (_vStackTop + + (ResetISR + 1) + + (( DEFINED(NMI_Handler) ? NMI_Handler : M0_NMI_Handler ) + 1) + + (( DEFINED(HardFault_Handler) ? HardFault_Handler : M0_HardFault_Handler ) + 1) + ) + ); +} diff --git a/platform/mcu/lpc54102/mcuxpresso/.DS_Store b/platform/mcu/lpc54102/mcuxpresso/.DS_Store new file mode 100644 index 0000000000..c7f7e04238 Binary files /dev/null and b/platform/mcu/lpc54102/mcuxpresso/.DS_Store differ diff --git a/platform/mcu/lpc54102/mcuxpresso/LPC5410x_256K.cfx b/platform/mcu/lpc54102/mcuxpresso/LPC5410x_256K.cfx new file mode 100644 index 0000000000..6d4f7aecc8 Binary files /dev/null and b/platform/mcu/lpc54102/mcuxpresso/LPC5410x_256K.cfx differ diff --git a/platform/mcu/lpc54102/mcuxpresso/LPC5410x_512K.cfx b/platform/mcu/lpc54102/mcuxpresso/LPC5410x_512K.cfx new file mode 100644 index 0000000000..bb2cbc3b53 Binary files /dev/null and b/platform/mcu/lpc54102/mcuxpresso/LPC5410x_512K.cfx differ diff --git a/platform/mcu/lpc54102/mcuxpresso/NXP/crp.h b/platform/mcu/lpc54102/mcuxpresso/NXP/crp.h new file mode 100644 index 0000000000..5bbb0add0a --- /dev/null +++ b/platform/mcu/lpc54102/mcuxpresso/NXP/crp.h @@ -0,0 +1,85 @@ +/**************************************************************************** + * Description: + * Code Read Protection macros + **************************************************************************** + * Software that is described herein is for illustrative purposes only + * which provides customers with programming information regarding the + * products. This software is supplied "AS IS" without any warranties. + * NXP Semiconductors assumes no responsibility or liability for the + * use of the software, conveys no license or title under any patent, + * copyright, or mask work right to the product. NXP Semiconductors + * reserves the right to make changes in the software without + * notification. NXP Semiconductors also make no representation or + * warranty that such application will be suitable for the specified + * use without further testing or modification. +****************************************************************************/ +#ifndef _CRP_H_INCLUDED_ +#define _CRP_H_INCLUDED_ + +// A macro for placing data into the Code Read Protect (CRP) section, +// which is then located at the correct address for the selected MCU +// by the automatically generated linker script. The CRP section should +// contain a single 32-bit value which is the CRP value. See appropriate +// documentation for the MCU to determine CRP values. +// +// This feature is only available for NXP MCU targets with the Code Read +// Protect Feature +// +// Example: +// __CRP const uint32_t CRP_WORD = CRP_NO_CRP ; +// +#define __CRP __attribute__ ((used,section(".crp"))) + +#define CRP_NO_CRP 0xFFFFFFFF + +// Disables UART and USB In System Programming (reads and writes) +// Leaves SWD debugging, with reads and writes, enabled +#define CRP_NO_ISP 0x4E697370 + +// Disables SWD debugging & JTAG, leaves ISP with with reads and writes enabled +// You will need UART connectivity and FlashMagic (flashmagictool.com) to reverse +// this. Don't even try this without these tools; most likely the SWD flash +// programming will not even complete. +// Allows reads and writes only to RAM above 0x10000300 and flash other than +// sector 0 (the first 4 kB). Full erase also allowed- again only through UART +// and FlashMagic (NO JTAG/SWD) +#define CRP_CRP1 0x12345678 + +// Disables SWD debugging & JTAG, leaves UART ISP with with only full erase +// enabled. You must have UART access and FlashMagic before setting this +// option. +// Don't even try this without these tools; most likely the SWD flash +// programming will not even complete. +#define CRP_CRP2 0x87654321 + +/************************************************************/ +/**** DANGER CRP3 WILL LOCK PART TO ALL READS and WRITES ****/ +#define CRP_CRP3_CONSUME_PART 0x43218765 +/************************************************************/ + +#if CONFIG_CRP_SETTING_NO_CRP == 1 +#define CURRENT_CRP_SETTING CRP_NO_CRP +#endif + +#if CONFIG_CRP_SETTING_NOISP == 1 +#define CURRENT_CRP_SETTING CRP_NO_ISP +#endif + +#if CONFIG_CRP_SETTING_CRP1 == 1 +#define CURRENT_CRP_SETTING CRP_CRP1 +#endif + +#if CONFIG_CRP_SETTING_CRP2 == 1 +#define CURRENT_CRP_SETTING CRP_CRP2 +#endif + +#if CONFIG_CRP_SETTING_CRP3_CONSUME_PART == 1 +#define CURRENT_CRP_SETTING CRP_CRP3_CONSUME_PART +#endif + +#ifndef CURRENT_CRP_SETTING +#define CURRENT_CRP_SETTING CRP_NO_CRP +#endif + + +#endif /* _CRP_H_INCLUDED_ */ diff --git a/platform/mcu/lpc54102/mcuxpresso/boot_multicore_slave.c b/platform/mcu/lpc54102/mcuxpresso/boot_multicore_slave.c new file mode 100644 index 0000000000..f7439cb80b --- /dev/null +++ b/platform/mcu/lpc54102/mcuxpresso/boot_multicore_slave.c @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright (c) 2016 - 2017 , NXP + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#if defined(__MULTICORE_MASTER_SLAVE_M0SLAVE) || defined(__MULTICORE_MASTER_SLAVE_M4SLAVE) +#if defined(__USE_LPCOPEN) +#include "chip.h" +#else +#include +#define SYSCON_BASE ((uint32_t)0x40000000) +#if defined(__LPC5410X__) +#define CPBOOT (((volatile uint32_t *)(SYSCON_BASE + 0x304))) +#define CPSTACK (((volatile uint32_t *)(SYSCON_BASE + 0x308))) +#define CPUCTRL (((volatile uint32_t *)(SYSCON_BASE + 0x300))) +#elif defined(__LPC5411X__) +#define CPBOOT (((volatile uint32_t *)(SYSCON_BASE + 0x804))) +#define CPSTACK (((volatile uint32_t *)(SYSCON_BASE + 0x808))) +#define CPUCTRL (((volatile uint32_t *)(SYSCON_BASE + 0x800))) +#else +#error Unrecognised MCU - cannot resolve Dual-CPU related registers +#endif +#define CPUCTRL_KEY ((uint32_t)(0x0000C0C4 << 16)) +#define CM4_CLK_ENA (1 << 2) +#define CM0_CLK_ENA (1 << 3) +#define CM4_RESET_ENA (1 << 4) +#define CM0_RESET_ENA (1 << 5) +#define CM4_SLEEPCON (1 << 6) + +#if defined(CORE_M4) +void Chip_CPU_CM0Boot(uint32_t *coentry, uint32_t *costackptr) +{ + volatile uint32_t *u32REG, u32Val; + + *CPSTACK = (uint32_t)costackptr; + *CPBOOT = (uint32_t)coentry; + + u32REG = (uint32_t *)CPUCTRL; + u32Val = *u32REG; + + // Enable slave clock and reset + u32Val |= (CPUCTRL_KEY | ((CM0_CLK_ENA | CM0_RESET_ENA) & 0x7F)); + *u32REG = u32Val; + + // Clear slave reset + u32Val &= ~CM0_RESET_ENA; + *u32REG = u32Val; +} +#else // !defined CORE_M4 +void Chip_CPU_CM4Boot(uint32_t *coentry, uint32_t *costackptr) +{ + volatile uint32_t *u32REG, u32Val; + + *CPSTACK = (uint32_t)costackptr; + *CPBOOT = (uint32_t)coentry; + + u32REG = (uint32_t *)CPUCTRL; + u32Val = *u32REG; + + // Enable slave clock and reset + u32Val |= (CPUCTRL_KEY | ((CM4_CLK_ENA | CM4_RESET_ENA) & 0x7F)); + *u32REG = u32Val; + + // Clear slave reset + u32Val &= ~CM0_RESET_ENA; + *u32REG = u32Val; +} +#endif // defined CORE_M4 +#endif // __USE_LPCOPEN + +#if defined(CORE_M4) +extern uint8_t __core_m0slave_START__; +#else +extern uint8_t __core_m4slave_START__; +#endif + +void boot_multicore_slave(void) +{ +#if defined(CORE_M4) + unsigned int *slavevectortable_ptr = (unsigned int *)&__core_m0slave_START__; +#else + unsigned int *slavevectortable_ptr = (unsigned int *)&__core_m4slave_START__; +#endif + + volatile unsigned int resetaddr; + volatile unsigned int spaddr; + spaddr = *slavevectortable_ptr; + resetaddr = *(slavevectortable_ptr + 1); + +#if defined(CORE_M4) + Chip_CPU_CM0Boot((uint32_t *)resetaddr, (uint32_t *)spaddr); +#else + Chip_CPU_CM4Boot((uint32_t *)resetaddr, (uint32_t *)spaddr); +#endif +} +#endif // defined (__MULTICORE_MASTER_SLAVE_M0SLAVE) || + // (__MULTICORE_MASTER_SLAVE_M4SLAVE) diff --git a/platform/mcu/lpc54102/mcuxpresso/boot_multicore_slave.h b/platform/mcu/lpc54102/mcuxpresso/boot_multicore_slave.h new file mode 100644 index 0000000000..de3ce3cff8 --- /dev/null +++ b/platform/mcu/lpc54102/mcuxpresso/boot_multicore_slave.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright (c) 2016 - 2017 , NXP + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef BOOT_MULTICORE_SLAVE_H_ +#define BOOT_MULTICORE_SLAVE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +void boot_multicore_slave(void); + +#ifdef __cplusplus +} +#endif + +#endif /* BOOT_MULTICORE_SLAVE_H_ */ diff --git a/platform/mcu/lpc54102/mcuxpresso/libfsl_power_cm4_hard.a b/platform/mcu/lpc54102/mcuxpresso/libfsl_power_cm4_hard.a new file mode 100644 index 0000000000..b94727904c Binary files /dev/null and b/platform/mcu/lpc54102/mcuxpresso/libfsl_power_cm4_hard.a differ diff --git a/platform/mcu/lpc54102/mcuxpresso/libfsl_power_lib_cm0.a b/platform/mcu/lpc54102/mcuxpresso/libfsl_power_lib_cm0.a new file mode 100644 index 0000000000..9eb67122b9 Binary files /dev/null and b/platform/mcu/lpc54102/mcuxpresso/libfsl_power_lib_cm0.a differ diff --git a/platform/mcu/lpc54102/mcuxpresso/libfsl_power_lib_cm4.a b/platform/mcu/lpc54102/mcuxpresso/libfsl_power_lib_cm4.a new file mode 100644 index 0000000000..3d47e627fe Binary files /dev/null and b/platform/mcu/lpc54102/mcuxpresso/libfsl_power_lib_cm4.a differ diff --git a/platform/mcu/lpc54102/mcuxpresso/startup_lpc5410x.c b/platform/mcu/lpc54102/mcuxpresso/startup_lpc5410x.c new file mode 100644 index 0000000000..8817e5ce57 --- /dev/null +++ b/platform/mcu/lpc54102/mcuxpresso/startup_lpc5410x.c @@ -0,0 +1,899 @@ +//***************************************************************************** +// LPC54102 startup code for use with MCUXpresso IDE +// +// Version : 230317 +//***************************************************************************** +// +// Copyright(C) NXP Semiconductors, 2017 +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, +// are permitted provided that the following conditions are met: +// +// o Redistributions of source code must retain the above copyright notice, this list +// of conditions and the following disclaimer. +// +// o 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. +// +// o Neither the name of copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from this +// software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//***************************************************************************** + +#if defined (DEBUG) +#pragma GCC push_options +#pragma GCC optimize ("Og") +#endif // (DEBUG) + +#if defined (__cplusplus) +#ifdef __REDLIB__ +#error Redlib does not support C++ +#else +//***************************************************************************** +// +// The entry point for the C++ library startup +// +//***************************************************************************** +extern "C" { + extern void __libc_init_array(void); +} +#endif +#endif + +#define WEAK __attribute__ ((weak)) +#define WEAK_AV __attribute__ ((weak, section(".after_vectors"))) +#define ALIAS(f) __attribute__ ((weak, alias (#f))) + +//***************************************************************************** +#if defined (__cplusplus) +extern "C" { +#endif + +//***************************************************************************** +// Variable to store CRP value in. Will be placed automatically +// by the linker when "Enable Code Read Protect" selected. +// See crp.h header for more information +//***************************************************************************** +#if !defined (CORE_M0PLUS) +#include "NXP/crp.h" +__CRP const unsigned int CRP_WORD = CRP_NO_CRP ; +#endif + +#include "k_api.h" // krhino_intrpt_enter, krhino_intrpt_exit + +//***************************************************************************** +// Declaration of external SystemInit function +//***************************************************************************** +#if defined (__USE_CMSIS) +extern void SystemInit(void); +#endif // (__USE_CMSIS) + +//***************************************************************************** +#if !defined (DONT_ENABLE_SWVTRACECLK) && !defined (CORE_M0PLUS) +// Allow confirmation that SWV trace has been enabled +unsigned int __SWVtrace_Enabled; +#endif + +//***************************************************************************** +// Forward declaration of the core exception handlers. +// When the application defines a handler (with the same name), this will +// automatically take precedence over these weak definitions +//***************************************************************************** + void ResetISR(void); +#if defined (__MULTICORE_MASTER) +void ResetISR2(void); +#endif +WEAK void NMI_Handler(void); +WEAK void HardFault_Handler(void); +WEAK void MemManage_Handler(void); +WEAK void BusFault_Handler(void); +WEAK void UsageFault_Handler(void); +WEAK void SVC_Handler(void); +WEAK void DebugMon_Handler(void); +WEAK void PendSV_Handler(void); +WEAK void SysTick_Handler(void); +WEAK void IntDefaultHandler(void); + +//***************************************************************************** +// Forward declaration of the application IRQ handlers. When the application +// defines a handler (with the same name), this will automatically take +// precedence over weak definitions below +//***************************************************************************** +// External Interrupts - Available on M0+/M4 +WEAK void WDT_IRQHandler(void); +WEAK void BOD_IRQHandler(void); +WEAK void Reserved18_IRQHandler(void); +WEAK void DMA0_IRQHandler(void); +WEAK void GINT0_IRQHandler(void); +WEAK void PIN_INT0_IRQHandler(void); +WEAK void PIN_INT1_IRQHandler(void); +WEAK void PIN_INT2_IRQHandler(void); +WEAK void PIN_INT3_IRQHandler(void); +WEAK void UTICK0_IRQHandler(void); +WEAK void MRT0_IRQHandler(void); +WEAK void CTIMER0_IRQHandler(void); +WEAK void CTIMER1_IRQHandler(void); +WEAK void CTIMER2_IRQHandler(void); +WEAK void CTIMER3_IRQHandler(void); +WEAK void CTIMER4_IRQHandler(void); +WEAK void SCT0_IRQHandler(void); +WEAK void USART0_IRQHandler(void); +WEAK void USART1_IRQHandler(void); +WEAK void USART2_IRQHandler(void); +WEAK void USART3_IRQHandler(void); +WEAK void I2C0_IRQHandler(void); +WEAK void I2C1_IRQHandler(void); +WEAK void I2C2_IRQHandler(void); +WEAK void SPI0_IRQHandler(void); +WEAK void SPI1_IRQHandler(void); +WEAK void ADC0_SEQA_IRQHandler(void); +WEAK void ADC0_SEQB_IRQHandler(void); +WEAK void ADC0_THCMP_IRQHandler(void); +WEAK void RTC_IRQHandler(void); +WEAK void Reserved46_IRQHandler(void); +WEAK void MAILBOX_IRQHandler(void); +// External Interrupts - For M4 only +#if defined (CORE_M4) +WEAK void GINT1_IRQHandler(void); +WEAK void PIN_INT4_IRQHandler(void); +WEAK void PIN_INT5_IRQHandler(void); +WEAK void PIN_INT6_IRQHandler(void); +WEAK void PIN_INT7_IRQHandler(void); +WEAK void Reserved53_IRQHandler(void); +WEAK void Reserved54_IRQHandler(void); +WEAK void Reserved55_IRQHandler(void); +WEAK void RIT_IRQHandler(void); +#endif + +//***************************************************************************** +// Forward declaration of the driver IRQ handlers. These are aliased +// to the IntDefaultHandler, which is a 'forever' loop. When the driver +// defines a handler (with the same name), this will automatically take +// precedence over these weak definitions +//***************************************************************************** +void WDT_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void BOD_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void Reserved18_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void DMA0_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void GINT0_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void PIN_INT0_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void PIN_INT1_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void PIN_INT2_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void PIN_INT3_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void UTICK0_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void MRT0_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void CTIMER0_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void CTIMER1_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void CTIMER2_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void CTIMER3_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void CTIMER4_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void SCT0_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void USART0_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void USART1_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void USART2_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void USART3_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void I2C0_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void I2C1_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void I2C2_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void SPI0_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void SPI1_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void ADC0_SEQA_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void ADC0_SEQB_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void ADC0_THCMP_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void RTC_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void Reserved46_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void MAILBOX_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +// External Interrupts - For M4 only +#if defined (CORE_M4) +void GINT1_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void PIN_INT4_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void PIN_INT5_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void PIN_INT6_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void PIN_INT7_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void Reserved53_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void Reserved54_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void Reserved55_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +void RIT_DriverIRQHandler(void) ALIAS(IntDefaultHandler); +#endif + +//***************************************************************************** +// The entry point for the application. +// __main() is the entry point for Redlib based applications +// main() is the entry point for Newlib based applications +//***************************************************************************** +#if defined (__REDLIB__) +extern void __main(void); +#endif +extern int main(void); + +//***************************************************************************** +// External declaration for the pointer to the stack top from the Linker Script +//***************************************************************************** +extern void _vStackTop(void); + +//***************************************************************************** +// +// External declaration for LPC MCU vector table checksum from Linker Script +// +//***************************************************************************** +WEAK extern void __valid_user_code_checksum(); + +//***************************************************************************** +#if defined (__cplusplus) +} // extern "C" +#endif + +//***************************************************************************** +// The vector table. +// This relies on the linker script to place at correct location in memory. +//***************************************************************************** +extern void (* const g_pfnVectors[])(void); +extern void * __Vectors __attribute__ ((alias ("g_pfnVectors"))); + +__attribute__ ((section(".isr_vector"))) +void (* const g_pfnVectors[])(void) = { +#if defined (CORE_M4) + // Core Level - CM4 + &_vStackTop, // The initial stack pointer + ResetISR, // The reset handler + NMI_Handler, // The NMI handler + HardFault_Handler, // The hard fault handler + MemManage_Handler, // The MPU fault handler + BusFault_Handler, // The bus fault handler + UsageFault_Handler, // The usage fault handler + __valid_user_code_checksum, // LPC MCU checksum + 0, // Reserved + 0, // Reserved + 0, // Reserved + SVC_Handler, // SVCall handler + DebugMon_Handler, // Debug monitor handler + 0, // Reserved + PendSV_Handler, // The PendSV handler + SysTick_Handler, // The SysTick handler +#else + // Core Level - CM0plus + &_vStackTop, // The initial stack pointer + ResetISR, // The reset handler + NMI_Handler, // The NMI handler + HardFault_Handler, // The hard fault handler + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + 0, // Reserved + SVC_Handler, // SVCall handler + 0, // Reserved + 0, // Reserved + PendSV_Handler, // The PendSV handler + SysTick_Handler, // The SysTick handler +#endif + + // External Interrupts - Available on M0+/M4 + WDT_IRQHandler, // 16: Windowed watchdog timer, Brownout detect + BOD_IRQHandler, // 17: BOD interrupt + Reserved18_IRQHandler, // 18: Reserved interrupt + DMA0_IRQHandler, // 19: DMA controller + GINT0_IRQHandler, // 20: GPIO group 0 + PIN_INT0_IRQHandler, // 21: Pin interrupt 0 or pattern match engine slice 0 + PIN_INT1_IRQHandler, // 22: Pin interrupt 1or pattern match engine slice 1 + PIN_INT2_IRQHandler, // 23: Pin interrupt 2 or pattern match engine slice 2 + PIN_INT3_IRQHandler, // 24: Pin interrupt 3 or pattern match engine slice 3 + UTICK0_IRQHandler, // 25: Micro-tick Timer + MRT0_IRQHandler, // 26: Multi-rate timer + CTIMER0_IRQHandler, // 27: Standard counter/timer CTIMER0 + CTIMER1_IRQHandler, // 28: Standard counter/timer CTIMER1 + CTIMER2_IRQHandler, // 29: Standard counter/timer CTIMER2 + CTIMER3_IRQHandler, // 30: Standard counter/timer CTIMER3 + CTIMER4_IRQHandler, // 31: Standard counter/timer CTIMER4 + SCT0_IRQHandler, // 32: SCTimer/PWM + USART0_IRQHandler, // 33: USART0 + USART1_IRQHandler, // 34: USART1 + USART2_IRQHandler, // 35: USART2 + USART3_IRQHandler, // 36: USART3 + I2C0_IRQHandler, // 37: I2C0 + I2C1_IRQHandler, // 38: I2C1 + I2C2_IRQHandler, // 39: I2C2 + SPI0_IRQHandler, // 40: SPI0 + SPI1_IRQHandler, // 41: SPI1 + ADC0_SEQA_IRQHandler, // 42: ADC0 sequence A completion. + ADC0_SEQB_IRQHandler, // 43: ADC0 sequence B completion. + ADC0_THCMP_IRQHandler, // 44: ADC0 threshold compare and error. + RTC_IRQHandler, // 45: RTC alarm and wake-up interrupts + Reserved46_IRQHandler, // 46: Reserved interrupt + MAILBOX_IRQHandler, // 47: Mailbox interrupt (present on selected devices) + // External Interrupts - For M4 only +#if defined (CORE_M4) + GINT1_IRQHandler, // 48: GPIO group 1 + PIN_INT4_IRQHandler, // 49: Pin interrupt 4 or pattern match engine slice 4 int + PIN_INT5_IRQHandler, // 50: Pin interrupt 5 or pattern match engine slice 5 int + PIN_INT6_IRQHandler, // 51: Pin interrupt 6 or pattern match engine slice 6 int + PIN_INT7_IRQHandler, // 52: Pin interrupt 7 or pattern match engine slice 7 int + Reserved53_IRQHandler, // 53: Reserved interrupt + Reserved54_IRQHandler, // 54: Reserved interrupt + Reserved55_IRQHandler, // 55: Reserved interrupt + RIT_IRQHandler, // 56: Repetitive Interrupt Timer +#endif + + +}; /* End of g_pfnVectors */ + +//***************************************************************************** +// Functions to carry out the initialization of RW and BSS data sections. These +// are written as separate functions rather than being inlined within the +// ResetISR() function in order to cope with MCUs with multiple banks of +// memory. +//***************************************************************************** +__attribute__ ((section(".after_vectors.init_data"))) +void data_init(unsigned int romstart, unsigned int start, unsigned int len) { + unsigned int *pulDest = (unsigned int*) start; + unsigned int *pulSrc = (unsigned int*) romstart; + unsigned int loop; + for (loop = 0; loop < len; loop = loop + 4) + *pulDest++ = *pulSrc++; +} + +__attribute__ ((section(".after_vectors.init_bss"))) +void bss_init(unsigned int start, unsigned int len) { + unsigned int *pulDest = (unsigned int*) start; + unsigned int loop; + for (loop = 0; loop < len; loop = loop + 4) + *pulDest++ = 0; +} + +//***************************************************************************** +// The following symbols are constructs generated by the linker, indicating +// the location of various points in the "Global Section Table". This table is +// created by the linker via the Code Red managed linker script mechanism. It +// contains the load address, execution address and length of each RW data +// section and the execution and length of each BSS (zero initialized) section. +//***************************************************************************** +extern unsigned int __data_section_table; +extern unsigned int __data_section_table_end; +extern unsigned int __bss_section_table; +extern unsigned int __bss_section_table_end; + +//***************************************************************************** +// Reset entry point for your code. +// Sets up a simple runtime environment and initializes the C/C++ +// library. +//***************************************************************************** + +#if defined (__MULTICORE_MASTER) +//#define cpu_ctrl 0x40000300 +//#define coproc_boot 0x40000304 +//#define set coproc_stack 0x40000308 +__attribute__ ((naked, section(".after_vectors.reset"))) +void ResetISR(void) { + asm volatile( + ".set cpu_ctrl, 0x40000300\t\n" + ".set coproc_boot, 0x40000304\t\n" + ".set coproc_stack, 0x40000308\t\n" + "MOVS R5, #1\t\n" + "LDR R0, =0xE000ED00\t\n" + "LDR R1, [R0]\t\n" // READ CPUID register + "LDR R2,=0x410CC601\t\n" // CM0 R0p1 identifier + "EORS R1,R1,R2\t\n" // XOR to see if we are C0 + "LDR R3, =cpu_ctrl\t\n" // get address of CPU_CTRL + "LDR R1,[R3]\t\n" // read cpu_ctrl reg into R1 + "BEQ.N cm0_boot\t\n" + "cm4_boot:\t\n" + "LDR R0,=coproc_boot\t\n" // coproc boot address + "LDR R0,[R0]\t\n" // get address to branch to + "MOVS R0,R0\t\n" // Check if 0 + "BEQ.N check_master_m4\t\n" // if zero in boot reg, we just branch to real reset + "BX R0\t\n" // otherwise, we branch to boot address + "commonboot:\t\n" + "LDR R0, =ResetISR2\t\n" // Jump to 'real' reset handler + "BX R0\t\n" + "cm0_boot:\t\n" + "LDR R0,=coproc_boot\t\n" // coproc boot address + "LDR R0,[R0]\t\n" // get address to branch to + "MOVS R0,R0\t\n" // Check if 0 + "BEQ.N check_master_m0\t\n" // if zero in boot reg, we just branch to real reset + "LDR R1,=coproc_stack\t\n" // pickup coprocesor stackpointer (from syscon CPSTACK) + "LDR R1,[R1]\t\n" + "MOV SP,R1\t\n" + "BX R0\t\n" // goto boot address + "check_master_m0:\t\n" + "ANDS R1,R1,R5\t\n" // bit test bit0 + "BEQ.N commonboot\t\n" // if we get 0, that means we are masters + "B.N goto_sleep_pending_reset\t\n" // Otherwise, there is no startup vector for slave, so we go to sleep + "check_master_m4:\t\n" + "ANDS R1,R1,R5\t\n" // bit test bit0 + "BNE.N commonboot\t\n" // if we get 1, that means we are masters + "goto_sleep_pending_reset:\t\n" + "MOV SP,R5\t\n" // load 0x1 into SP so that any stacking (eg on NMI) will not cause us to wakeup + // and write to uninitialised Stack area (instead it will LOCK us up before we cause damage) + // this code should only be reached if debugger bypassed ROM or we changed master without giving + // correct start address, the only way out of this is through a debugger change of SP and PC + "sleepo:\t\n" + "WFI\t\n" // go to sleep + "B.N sleepo\t\n" + ); +} + +void ResetISR2(void) { + +#else +__attribute__ ((section(".after_vectors.reset"))) +void ResetISR(void) { +#endif + + // Disable interrupts + __asm volatile ("cpsid i"); + + // Enable SRAM clock used by Stack + __asm volatile ("LDR R0, =0x400000C8\n\t" + "MOV R1, #24\n\t" + "STR R1, [R0]"); + +#if defined (__USE_CMSIS) +// If __USE_CMSIS defined, then call CMSIS SystemInit code + SystemInit(); +#endif // (__USE_CMSIS) + + // + // Copy the data sections from flash to SRAM. + // + unsigned int LoadAddr, ExeAddr, SectionLen; + unsigned int *SectionTableAddr; + + // Load base address of Global Section Table + SectionTableAddr = &__data_section_table; + + // Copy the data sections from flash to SRAM. + while (SectionTableAddr < &__data_section_table_end) { + LoadAddr = *SectionTableAddr++; + ExeAddr = *SectionTableAddr++; + SectionLen = *SectionTableAddr++; + data_init(LoadAddr, ExeAddr, SectionLen); + } + + // At this point, SectionTableAddr = &__bss_section_table; + // Zero fill the bss segment + while (SectionTableAddr < &__bss_section_table_end) { + ExeAddr = *SectionTableAddr++; + SectionLen = *SectionTableAddr++; + bss_init(ExeAddr, SectionLen); + } + + // Optionally enable Cortex-M4 SWV trace (off by default at reset) + // Note - your board support must also set up pinmuxing such that + // SWO is output on GPIO PIO0-15 (FUNC2) or PIO1_1 (FUNC2). +#if !defined (DONT_ENABLE_SWVTRACECLK) && !defined (CORE_M0PLUS) + volatile unsigned int *TRACECLKDIV = (unsigned int *) 0x400000E4; + volatile unsigned int *SYSAHBCLKCTRLSET = (unsigned int *) 0x400000C8; + volatile unsigned int *SYSAHBCLKCTRL = (unsigned int *) 0x400000C0; + // Write 0x00000001 to TRACECLKDIV – Trace divider + *TRACECLKDIV = 1; + // Enable IOCON peripheral clock (for SWO on PIO0-15 or PIO1_1) + // by setting bit13 via SYSAHBCLKCTRLSET[0] + *SYSAHBCLKCTRLSET = 1 << 13; // 0x2000 + // Read SYSAHBCLKCTRL[0] and check bit 13 + __SWVtrace_Enabled = ((*SYSAHBCLKCTRL & 1 << 13) == 1 << 13); +#endif + +#if !defined (__USE_CMSIS) +// Assume that if __USE_CMSIS defined, then CMSIS SystemInit code +// will enable the FPU +#if defined (__VFP_FP__) && !defined (__SOFTFP__) + // + // Code to enable the Cortex-M4 FPU only included + // if appropriate build options have been selected. + // Code taken from Section 7.1, Cortex-M4 TRM (DDI0439C) + // + // Read CPACR (located at address 0xE000ED88) + // Set bits 20-23 to enable CP10 and CP11 coprocessors + // Write back the modified value to the CPACR + asm volatile ("LDR.W R0, =0xE000ED88\n\t" + "LDR R1, [R0]\n\t" + "ORR R1, R1, #(0xF << 20)\n\t" + "STR R1, [R0]"); +#endif // (__VFP_FP__) && !(__SOFTFP__) +#endif // (__USE_CMSIS) + +#if !defined (__USE_CMSIS) +// Assume that if __USE_CMSIS defined, then CMSIS SystemInit code +// will setup the VTOR register + + // Check to see if we are running the code from a non-zero + // address (eg RAM, external flash), in which case we need + // to modify the VTOR register to tell the CPU that the + // vector table is located at a non-0x0 address. + unsigned int * pSCB_VTOR = (unsigned int *) 0xE000ED08; + if ((unsigned int *)g_pfnVectors!=(unsigned int *) 0x00000000) { + *pSCB_VTOR = (unsigned int)g_pfnVectors; + } +#endif // (__USE_CMSIS) + +#if defined (__cplusplus) + // + // Call C++ library initialisation + // + __libc_init_array(); +#endif + + // Reenable interrupts + __asm volatile ("cpsie i"); + +#if defined (__REDLIB__) + // Call the Redlib library, which in turn calls main() + __main(); +#else + main(); +#endif + + // + // main() shouldn't return, but if it does, we'll just enter an infinite loop + // + while (1) { + ; + } +} + +//***************************************************************************** +// Default core exception handlers. Override the ones here by defining your own +// handler routines in your application code. +//***************************************************************************** +WEAK_AV void NMI_Handler(void) +{ while(1) {} +} + +WEAK_AV void HardFault_Handler(void) +{ while(1) {} +} + +WEAK_AV void SVC_Handler(void) +{ while(1) {} +} + +WEAK_AV void PendSV_Handler(void) +{ while(1) {} +} + +WEAK_AV void SysTick_Handler(void) +{ while(1) {} +} + +// Core Level Interrupts - For M4 only +#if defined (CORE_M4) +WEAK_AV void MemManage_Handler(void) +{ while(1) {} +} + +WEAK_AV void BusFault_Handler(void) +{ while(1) {} +} + +WEAK_AV void UsageFault_Handler(void) +{ while(1) {} +} + +WEAK_AV void DebugMon_Handler(void) +{ while(1) {} +} +#endif // External Interrupts - For M4 only + +//***************************************************************************** +// Processor ends up here if an unexpected interrupt occurs or a specific +// handler is not present in the application code. +//***************************************************************************** +WEAK_AV void IntDefaultHandler(void) +{ while(1) {} +} + +//***************************************************************************** +// Default application exception handlers. Override the ones here by defining +// your own handler routines in your application code. These routines call +// driver exception handlers or IntDefaultHandler() if no driver exception +// handler is included. +//***************************************************************************** +WEAK void WDT_IRQHandler(void) +{ + krhino_intrpt_enter(); + WDT_DriverIRQHandler(); + krhino_intrpt_exit(); +} + +WEAK void BOD_IRQHandler(void) +{ + krhino_intrpt_enter(); + BOD_DriverIRQHandler(); + krhino_intrpt_exit(); +} + +WEAK void Reserved18_IRQHandler(void) +{ + krhino_intrpt_enter(); + Reserved18_DriverIRQHandler(); + krhino_intrpt_exit(); +} + +WEAK void DMA0_IRQHandler(void) +{ + krhino_intrpt_enter(); + DMA0_DriverIRQHandler(); + krhino_intrpt_exit(); +} + +WEAK void GINT0_IRQHandler(void) +{ + krhino_intrpt_enter(); + GINT0_DriverIRQHandler(); + krhino_intrpt_exit(); +} + +WEAK void PIN_INT0_IRQHandler(void) +{ + krhino_intrpt_enter(); + PIN_INT0_DriverIRQHandler(); + krhino_intrpt_exit(); +} + +WEAK void PIN_INT1_IRQHandler(void) +{ + krhino_intrpt_enter(); + PIN_INT1_DriverIRQHandler(); + krhino_intrpt_exit(); +} + +WEAK void PIN_INT2_IRQHandler(void) +{ + krhino_intrpt_enter(); + PIN_INT2_DriverIRQHandler(); + krhino_intrpt_exit(); +} + +WEAK void PIN_INT3_IRQHandler(void) +{ + krhino_intrpt_enter(); + PIN_INT3_DriverIRQHandler(); + krhino_intrpt_exit(); +} + +WEAK void UTICK0_IRQHandler(void) +{ + krhino_intrpt_enter(); + UTICK0_DriverIRQHandler(); + krhino_intrpt_exit(); +} + +WEAK void MRT0_IRQHandler(void) +{ + krhino_intrpt_enter(); + MRT0_DriverIRQHandler(); + krhino_intrpt_exit(); +} + +WEAK void CTIMER0_IRQHandler(void) +{ + krhino_intrpt_enter(); + CTIMER0_DriverIRQHandler(); + krhino_intrpt_exit(); +} + +WEAK void CTIMER1_IRQHandler(void) +{ + krhino_intrpt_enter(); + CTIMER1_DriverIRQHandler(); + krhino_intrpt_exit(); +} + +WEAK void CTIMER2_IRQHandler(void) +{ + krhino_intrpt_enter(); + CTIMER2_DriverIRQHandler(); + krhino_intrpt_exit(); +} + +WEAK void CTIMER3_IRQHandler(void) +{ + krhino_intrpt_enter(); + CTIMER3_DriverIRQHandler(); + krhino_intrpt_exit(); +} + +WEAK void CTIMER4_IRQHandler(void) +{ + krhino_intrpt_enter(); + CTIMER4_DriverIRQHandler(); + krhino_intrpt_exit(); +} + +WEAK void SCT0_IRQHandler(void) +{ + krhino_intrpt_enter(); + SCT0_DriverIRQHandler(); + krhino_intrpt_exit(); +} + +WEAK void USART0_IRQHandler(void) +{ + krhino_intrpt_enter(); + USART0_DriverIRQHandler(); + krhino_intrpt_exit(); +} + +WEAK void USART1_IRQHandler(void) +{ + krhino_intrpt_enter(); + USART1_DriverIRQHandler(); + krhino_intrpt_exit(); +} + +WEAK void USART2_IRQHandler(void) +{ + krhino_intrpt_enter(); + USART2_DriverIRQHandler(); + krhino_intrpt_exit(); +} + +WEAK void USART3_IRQHandler(void) +{ + krhino_intrpt_enter(); + USART3_DriverIRQHandler(); + krhino_intrpt_exit(); +} + +WEAK void I2C0_IRQHandler(void) +{ + krhino_intrpt_enter(); + I2C0_DriverIRQHandler(); + krhino_intrpt_exit(); +} + +WEAK void I2C1_IRQHandler(void) +{ + krhino_intrpt_enter(); + I2C1_DriverIRQHandler(); + krhino_intrpt_exit(); +} + +WEAK void I2C2_IRQHandler(void) +{ + krhino_intrpt_enter(); + I2C2_DriverIRQHandler(); + krhino_intrpt_exit(); +} + +WEAK void SPI0_IRQHandler(void) +{ + krhino_intrpt_enter(); + SPI0_DriverIRQHandler(); + krhino_intrpt_exit(); +} + +WEAK void SPI1_IRQHandler(void) +{ + krhino_intrpt_enter(); + SPI1_DriverIRQHandler(); + krhino_intrpt_exit(); +} + +WEAK void ADC0_SEQA_IRQHandler(void) +{ + krhino_intrpt_enter(); + ADC0_SEQA_DriverIRQHandler(); + krhino_intrpt_exit(); +} + +WEAK void ADC0_SEQB_IRQHandler(void) +{ + krhino_intrpt_enter(); + ADC0_SEQB_DriverIRQHandler(); + krhino_intrpt_exit(); +} + +WEAK void ADC0_THCMP_IRQHandler(void) +{ + krhino_intrpt_enter(); + ADC0_THCMP_DriverIRQHandler(); + krhino_intrpt_exit(); +} + +WEAK void RTC_IRQHandler(void) +{ + krhino_intrpt_enter(); + RTC_DriverIRQHandler(); + krhino_intrpt_exit(); +} + +WEAK void Reserved46_IRQHandler(void) +{ + krhino_intrpt_enter(); + Reserved46_DriverIRQHandler(); + krhino_intrpt_exit(); +} + +WEAK void MAILBOX_IRQHandler(void) +{ + krhino_intrpt_enter(); + MAILBOX_DriverIRQHandler(); + krhino_intrpt_exit(); +} +// External Interrupts - For M4 only +#if defined (CORE_M4) +WEAK void GINT1_IRQHandler(void) +{ + krhino_intrpt_enter(); + GINT1_DriverIRQHandler(); + krhino_intrpt_exit(); +} + +WEAK void PIN_INT4_IRQHandler(void) +{ + krhino_intrpt_enter(); + PIN_INT4_DriverIRQHandler(); + krhino_intrpt_exit(); +} + +WEAK void PIN_INT5_IRQHandler(void) +{ + krhino_intrpt_enter(); + PIN_INT5_DriverIRQHandler(); + krhino_intrpt_exit(); +} + +WEAK void PIN_INT6_IRQHandler(void) +{ + krhino_intrpt_enter(); + PIN_INT6_DriverIRQHandler(); + krhino_intrpt_exit(); +} + +WEAK void PIN_INT7_IRQHandler(void) +{ + krhino_intrpt_enter(); + PIN_INT7_DriverIRQHandler(); + krhino_intrpt_exit(); +} + +WEAK void Reserved53_IRQHandler(void) +{ + krhino_intrpt_enter(); + Reserved53_DriverIRQHandler(); + krhino_intrpt_exit(); +} + +WEAK void Reserved54_IRQHandler(void) +{ + krhino_intrpt_enter(); + Reserved54_DriverIRQHandler(); + krhino_intrpt_exit(); +} + +WEAK void Reserved55_IRQHandler(void) +{ + krhino_intrpt_enter(); + Reserved55_DriverIRQHandler(); + krhino_intrpt_exit(); +} + +WEAK void RIT_IRQHandler(void) +{ + krhino_intrpt_enter(); + RIT_DriverIRQHandler(); + krhino_intrpt_exit(); +} +#endif // External Interrupts - For M4 only + +//***************************************************************************** + +#if defined (DEBUG) +#pragma GCC pop_options +#endif // (DEBUG) diff --git a/platform/mcu/lpc54102/system_LPC54102_cm0plus.c b/platform/mcu/lpc54102/system_LPC54102_cm0plus.c new file mode 100644 index 0000000000..484788763d --- /dev/null +++ b/platform/mcu/lpc54102/system_LPC54102_cm0plus.c @@ -0,0 +1,108 @@ +/* +** ################################################################### +** Processors: LPC54102J256BD64_cm0plus +** LPC54102J256UK49_cm0plus +** LPC54102J512BD64_cm0plus +** LPC54102J512UK49_cm0plus +** +** Compilers: Keil ARM C/C++ Compiler +** IAR ANSI C/C++ Compiler for ARM +** MCUXpresso Compiler +** +** Reference manual: LPC5410x User manual Rev. 2.4 25 May 2016 +** Version: rev. 1.0, 2016-04-29 +** Build: b170426 +** +** Abstract: +** Provides a system configuration function and a global variable that +** contains the system frequency. It configures the device and initializes +** the oscillator (PLL) that is part of the microcontroller device. +** +** Copyright 2016 Freescale Semiconductor, Inc. +** Copyright 2016-2017 NXP +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o 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. +** +** o Neither the name of the copyright holder nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.nxp.com +** mail: support@nxp.com +** +** Revisions: +** - rev. 1.0 (2016-04-29) +** Initial version. +** +** ################################################################### +*/ + +/*! + * @file LPC54102_cm0plus + * @version 1.0 + * @date 2016-04-29 + * @brief Device specific configuration file for LPC54102_cm0plus + * (implementation file) + * + * Provides a system configuration function and a global variable that contains + * the system frequency. It configures the device and initializes the oscillator + * (PLL) that is part of the microcontroller device. + */ + +#include +#include "fsl_device_registers.h" + + + +/* ---------------------------------------------------------------------------- + -- Core clock + ---------------------------------------------------------------------------- */ + +uint32_t SystemCoreClock = DEFAULT_SYSTEM_CLOCK; + +/* ---------------------------------------------------------------------------- + -- SystemInit() + ---------------------------------------------------------------------------- */ + +void SystemInit (void) { + +#if defined(__CODE_RED) + extern void(*const g_pfnVectors[]) (void); + SCB->VTOR = (uint32_t) &g_pfnVectors; +#else + extern void *__Vectors; + SCB->VTOR = (uint32_t) &__Vectors; +#endif +/* Optionally enable RAM banks that may be off by default at reset */ +#if !defined (DONT_ENABLE_DISABLED_RAMBANKS) + SYSCON->AHBCLKCTRLSET[0] = SYSCON_AHBCLKCTRL_SRAM2_MASK; +#endif + +} + +/* ---------------------------------------------------------------------------- + -- SystemCoreClockUpdate() + ---------------------------------------------------------------------------- */ + +void SystemCoreClockUpdate (void) { + + +} diff --git a/platform/mcu/lpc54102/system_LPC54102_cm0plus.h b/platform/mcu/lpc54102/system_LPC54102_cm0plus.h new file mode 100644 index 0000000000..e09ce80240 --- /dev/null +++ b/platform/mcu/lpc54102/system_LPC54102_cm0plus.h @@ -0,0 +1,117 @@ +/* +** ################################################################### +** Processors: LPC54102J256BD64_cm0plus +** LPC54102J256UK49_cm0plus +** LPC54102J512BD64_cm0plus +** LPC54102J512UK49_cm0plus +** +** Compilers: Keil ARM C/C++ Compiler +** IAR ANSI C/C++ Compiler for ARM +** MCUXpresso Compiler +** +** Reference manual: LPC5410x User manual Rev. 2.4 25 May 2016 +** Version: rev. 1.0, 2016-04-29 +** Build: b170426 +** +** Abstract: +** Provides a system configuration function and a global variable that +** contains the system frequency. It configures the device and initializes +** the oscillator (PLL) that is part of the microcontroller device. +** +** Copyright 2016 Freescale Semiconductor, Inc. +** Copyright 2016-2017 NXP +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o 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. +** +** o Neither the name of the copyright holder nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.nxp.com +** mail: support@nxp.com +** +** Revisions: +** - rev. 1.0 (2016-04-29) +** Initial version. +** +** ################################################################### +*/ + +/*! + * @file LPC54102_cm0plus + * @version 1.0 + * @date 2016-04-29 + * @brief Device specific configuration file for LPC54102_cm0plus (header file) + * + * Provides a system configuration function and a global variable that contains + * the system frequency. It configures the device and initializes the oscillator + * (PLL) that is part of the microcontroller device. + */ + +#ifndef _SYSTEM_LPC54102_cm0plus_H_ +#define _SYSTEM_LPC54102_cm0plus_H_ /**< Symbol preventing repeated inclusion */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + + +#define DEFAULT_SYSTEM_CLOCK 12000000u /* Default System clock value */ +#define CLK_RTC_32K_CLK 32768u /* RTC oscillator 32 kHz output (32k_clk) */ +#define CLK_IRC_12MHZ 12000000u /* IRC 12 MHz (irc_12m) */ + + +/** + * @brief System clock frequency (core clock) + * + * The system clock frequency supplied to the SysTick timer and the processor + * core clock. This variable can be used by the user application to setup the + * SysTick timer or configure other parameters. It may also be used by debugger to + * query the frequency of the debug timer or configure the trace clock speed + * SystemCoreClock is initialized with a correct predefined value. + */ +extern uint32_t SystemCoreClock; + +/** + * @brief Setup the microcontroller system. + * + * Typically this function configures the oscillator (PLL) that is part of the + * microcontroller device. For systems with variable clock speed it also updates + * the variable SystemCoreClock. SystemInit is called from startup_device file. + */ +void SystemInit (void); + +/** + * @brief Updates the SystemCoreClock variable. + * + * It must be called whenever the core clock is changed during program + * execution. SystemCoreClockUpdate() evaluates the clock register settings and calculates + * the current core clock. + */ +void SystemCoreClockUpdate (void); + +#ifdef __cplusplus +} +#endif + +#endif /* _SYSTEM_LPC54102_cm0plus_H_ */ diff --git a/platform/mcu/lpc54102/system_LPC54102_cm4.c b/platform/mcu/lpc54102/system_LPC54102_cm4.c new file mode 100644 index 0000000000..759bf2fa57 --- /dev/null +++ b/platform/mcu/lpc54102/system_LPC54102_cm4.c @@ -0,0 +1,111 @@ +/* +** ################################################################### +** Processors: LPC54102J256BD64_cm4 +** LPC54102J256UK49_cm4 +** LPC54102J512BD64_cm4 +** LPC54102J512UK49_cm4 +** +** Compilers: Keil ARM C/C++ Compiler +** IAR ANSI C/C++ Compiler for ARM +** MCUXpresso Compiler +** +** Reference manual: LPC5410x User manual Rev. 2.4 25 May 2016 +** Version: rev. 1.0, 2016-04-29 +** Build: b170426 +** +** Abstract: +** Provides a system configuration function and a global variable that +** contains the system frequency. It configures the device and initializes +** the oscillator (PLL) that is part of the microcontroller device. +** +** Copyright 2016 Freescale Semiconductor, Inc. +** Copyright 2016-2017 NXP +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o 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. +** +** o Neither the name of the copyright holder nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.nxp.com +** mail: support@nxp.com +** +** Revisions: +** - rev. 1.0 (2016-04-29) +** Initial version. +** +** ################################################################### +*/ + +/*! + * @file LPC54102_cm4 + * @version 1.0 + * @date 2016-04-29 + * @brief Device specific configuration file for LPC54102_cm4 (implementation + * file) + * + * Provides a system configuration function and a global variable that contains + * the system frequency. It configures the device and initializes the oscillator + * (PLL) that is part of the microcontroller device. + */ + +#include +#include "fsl_device_registers.h" + + + +/* ---------------------------------------------------------------------------- + -- Core clock + ---------------------------------------------------------------------------- */ + +uint32_t SystemCoreClock = DEFAULT_SYSTEM_CLOCK; + +/* ---------------------------------------------------------------------------- + -- SystemInit() + ---------------------------------------------------------------------------- */ + +void SystemInit (void) { +#if ((__FPU_PRESENT == 1) && (__FPU_USED == 1)) + SCB->CPACR |= ((3UL << 10*2) | (3UL << 11*2)); /* set CP10, CP11 Full Access */ +#endif /* ((__FPU_PRESENT == 1) && (__FPU_USED == 1)) */ + +#if defined(__CODE_RED) + extern void(*const g_pfnVectors[]) (void); + SCB->VTOR = (uint32_t) &g_pfnVectors; +#else + extern void *__Vectors; + SCB->VTOR = (uint32_t) &__Vectors; +#endif +/* Optionally enable RAM banks that may be off by default at reset */ +#if !defined (DONT_ENABLE_DISABLED_RAMBANKS) + SYSCON->AHBCLKCTRLSET[0] = SYSCON_AHBCLKCTRL_SRAM2_MASK; +#endif + +} + +/* ---------------------------------------------------------------------------- + -- SystemCoreClockUpdate() + ---------------------------------------------------------------------------- */ + +void SystemCoreClockUpdate (void) { + + +} diff --git a/platform/mcu/lpc54102/system_LPC54102_cm4.h b/platform/mcu/lpc54102/system_LPC54102_cm4.h new file mode 100644 index 0000000000..00b8af6078 --- /dev/null +++ b/platform/mcu/lpc54102/system_LPC54102_cm4.h @@ -0,0 +1,117 @@ +/* +** ################################################################### +** Processors: LPC54102J256BD64_cm4 +** LPC54102J256UK49_cm4 +** LPC54102J512BD64_cm4 +** LPC54102J512UK49_cm4 +** +** Compilers: Keil ARM C/C++ Compiler +** IAR ANSI C/C++ Compiler for ARM +** MCUXpresso Compiler +** +** Reference manual: LPC5410x User manual Rev. 2.4 25 May 2016 +** Version: rev. 1.0, 2016-04-29 +** Build: b170426 +** +** Abstract: +** Provides a system configuration function and a global variable that +** contains the system frequency. It configures the device and initializes +** the oscillator (PLL) that is part of the microcontroller device. +** +** Copyright 2016 Freescale Semiconductor, Inc. +** Copyright 2016-2017 NXP +** Redistribution and use in source and binary forms, with or without modification, +** are permitted provided that the following conditions are met: +** +** o Redistributions of source code must retain the above copyright notice, this list +** of conditions and the following disclaimer. +** +** o 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. +** +** o Neither the name of the copyright holder nor the names of its +** contributors may be used to endorse or promote products derived from this +** software without specific prior written permission. +** +** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +** +** http: www.nxp.com +** mail: support@nxp.com +** +** Revisions: +** - rev. 1.0 (2016-04-29) +** Initial version. +** +** ################################################################### +*/ + +/*! + * @file LPC54102_cm4 + * @version 1.0 + * @date 2016-04-29 + * @brief Device specific configuration file for LPC54102_cm4 (header file) + * + * Provides a system configuration function and a global variable that contains + * the system frequency. It configures the device and initializes the oscillator + * (PLL) that is part of the microcontroller device. + */ + +#ifndef _SYSTEM_LPC54102_cm4_H_ +#define _SYSTEM_LPC54102_cm4_H_ /**< Symbol preventing repeated inclusion */ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + + +#define DEFAULT_SYSTEM_CLOCK 12000000u /* Default System clock value */ +#define CLK_RTC_32K_CLK 32768u /* RTC oscillator 32 kHz output (32k_clk) */ +#define CLK_IRC_12MHZ 12000000u /* IRC 12 MHz (irc_12m) */ + + +/** + * @brief System clock frequency (core clock) + * + * The system clock frequency supplied to the SysTick timer and the processor + * core clock. This variable can be used by the user application to setup the + * SysTick timer or configure other parameters. It may also be used by debugger to + * query the frequency of the debug timer or configure the trace clock speed + * SystemCoreClock is initialized with a correct predefined value. + */ +extern uint32_t SystemCoreClock; + +/** + * @brief Setup the microcontroller system. + * + * Typically this function configures the oscillator (PLL) that is part of the + * microcontroller device. For systems with variable clock speed it also updates + * the variable SystemCoreClock. SystemInit is called from startup_device file. + */ +void SystemInit (void); + +/** + * @brief Updates the SystemCoreClock variable. + * + * It must be called whenever the core clock is changed during program + * execution. SystemCoreClockUpdate() evaluates the clock register settings and calculates + * the current core clock. + */ +void SystemCoreClockUpdate (void); + +#ifdef __cplusplus +} +#endif + +#endif /* _SYSTEM_LPC54102_cm4_H_ */ diff --git a/platform/mcu/lpc54102/utilities/fsl_assert.c b/platform/mcu/lpc54102/utilities/fsl_assert.c new file mode 100644 index 0000000000..ac3a6eef0c --- /dev/null +++ b/platform/mcu/lpc54102/utilities/fsl_assert.c @@ -0,0 +1,55 @@ +/* +* Copyright (c) 2015-2016, Freescale Semiconductor, Inc. + * Copyright 2016 NXP +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without modification, +* are permitted provided that the following conditions are met: +* +* o Redistributions of source code must retain the above copyright notice, this list +* of conditions and the following disclaimer. +* +* o 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. +* +* o Neither the name of the copyright holder nor the names of its +* contributors may be used to endorse or promote products derived from this +* software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "fsl_common.h" +#include "fsl_debug_console.h" + +#ifndef NDEBUG +#if (defined(__CC_ARM)) || (defined(__ICCARM__)) +void __aeabi_assert(const char *failedExpr, const char *file, int line) +{ + PRINTF("ASSERT ERROR \" %s \": file \"%s\" Line \"%d\" \n", failedExpr, file, line); + for (;;) + { + __BKPT(0); + } +} +#elif(defined(__GNUC__)) +void __assert_func(const char *file, int line, const char *func, const char *failedExpr) +{ + PRINTF("ASSERT ERROR \" %s \": file \"%s\" Line \"%d\" function name \"%s\" \n", failedExpr, file, line, func); + for (;;) + { + __BKPT(0); + } +} +#endif /* (defined(__CC_ARM)) || (defined (__ICCARM__)) */ +#endif /* NDEBUG */ diff --git a/platform/mcu/lpc54102/utilities/fsl_debug_console.c b/platform/mcu/lpc54102/utilities/fsl_debug_console.c new file mode 100644 index 0000000000..e8cf170b21 --- /dev/null +++ b/platform/mcu/lpc54102/utilities/fsl_debug_console.c @@ -0,0 +1,361 @@ +/* + * This is a modified version of the file printf.c, which was distributed + * by Motorola as part of the M5407C3BOOT.zip package used to initialize + * the M5407C3 evaluation board. + * + * Copyright: + * 1999-2000 MOTOROLA, INC. All Rights Reserved. + * You are hereby granted a copyright license to use, modify, and + * distribute the SOFTWARE so long as this entire notice is + * retained without alteration in any modified and/or redistributed + * versions, and that such modified versions are clearly identified + * as such. No licenses are granted by implication, estoppel or + * otherwise under any patents or trademarks of Motorola, Inc. This + * software is provided on an "AS IS" basis and without warranty. + * + * To the maximum extent permitted by applicable law, MOTOROLA + * DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED, INCLUDING + * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR + * PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH REGARD TO THE + * SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF) AND ANY + * ACCOMPANYING WRITTEN MATERIALS. + * + * To the maximum extent permitted by applicable law, IN NO EVENT + * SHALL MOTOROLA BE LIABLE FOR ANY DAMAGES WHATSOEVER (INCLUDING + * WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS + * INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY + * LOSS) ARISING OF THE USE OR INABILITY TO USE THE SOFTWARE. + * + * Motorola assumes no responsibility for the maintenance and support + * of this software + + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#if defined(__CC_ARM) +#include +#endif + +#include "fsl_debug_console.h" +#include "fsl_debug_console_conf.h" +#include "fsl_log.h" +#include "fsl_str.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +/*! + * @brief This is a printf call back function which is used to relocate the log to buffer + * or print the log immediately when the local buffer is full. + * + * @param[in] buf Buffer to store log. + * @param[in] indicator Buffer index. + * @param[in] val Target character to store. + * @param[in] len length of the character + * + */ +#if SDK_DEBUGCONSOLE +static void DbgConsole_RelocateLog(char *buf, int32_t *indicator, char val, int len); +#endif +/******************************************************************************* + * Code + ******************************************************************************/ + +/*************Code for DbgConsole Init, Deinit, Printf, Scanf *******************************/ + +/* See fsl_debug_console.h for documentation of this function. */ +status_t DbgConsole_Init(uint32_t baseAddr, uint32_t baudRate, uint8_t device, uint32_t clkSrcFreq) +{ + assert(device != DEBUG_CONSOLE_DEVICE_TYPE_NONE); + + return LOG_Init(baseAddr, device, baudRate, clkSrcFreq); +} + +/* See fsl_debug_console.h for documentation of this function. */ +status_t DbgConsole_Deinit(void) +{ + /* LOG deinit */ + LOG_Deinit(); + + return kStatus_Success; +} + +status_t DbgConsole_Flush(void) +{ + /* wait log and io idle */ + return LOG_WaitIdle(); +} + +#if SDK_DEBUGCONSOLE +/* See fsl_debug_console.h for documentation of this function. */ +int DbgConsole_Printf(const char *fmt_s, ...) +{ + va_list ap; + int logLength = 0U, result = 0U; + char printBuf[DEBUG_CONSOLE_PRINTF_MAX_LOG_LEN] = {0U}; + + va_start(ap, fmt_s); + /* format print log first */ + logLength = StrFormatPrintf(fmt_s, ap, printBuf, DbgConsole_RelocateLog); + /* print log */ + result = LOG_Push((uint8_t *)printBuf, logLength); + + va_end(ap); + + return result; +} + +/* See fsl_debug_console.h for documentation of this function. */ +int DbgConsole_Putchar(int ch) +{ + /* print char */ + return LOG_Push((uint8_t *)&ch, 1U); +} + +/* See fsl_debug_console.h for documentation of this function. */ +int DbgConsole_Scanf(char *fmt_ptr, ...) +{ + va_list ap; + int result; + char scanfBuf[DEBUG_CONSOLE_SCANF_MAX_LOG_LEN + 1U] = {0U}; + + /* scanf log */ + LOG_ReadLine((uint8_t *)scanfBuf, DEBUG_CONSOLE_SCANF_MAX_LOG_LEN); + /* get va_list */ + va_start(ap, fmt_ptr); + /* format scanf log */ + result = StrFormatScanf(scanfBuf, fmt_ptr, ap); + + va_end(ap); + + return result; +} + +#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING +status_t DbgConsole_TryGetchar(char *ch) +{ + if (NULL != ch) + { + return LOG_TryReadCharacter((uint8_t *)ch); + } + + return kStatus_Fail; +} +#endif + +/* See fsl_debug_console.h for documentation of this function. */ +int DbgConsole_Getchar(void) +{ + uint8_t ch; + + /* Get char */ + LOG_ReadCharacter(&ch); + + return ch; +} + +static void DbgConsole_RelocateLog(char *buf, int32_t *indicator, char val, int len) +{ + int i = 0; + + for (i = 0; i < len; i++) + { + if ((*indicator + 1) >= DEBUG_CONSOLE_PRINTF_MAX_LOG_LEN) + { + LOG_Push((uint8_t *)buf, *indicator); + *indicator = 0U; + } + + buf[*indicator] = val; + (*indicator)++; + } +} + +#endif /* SDK_DEBUGCONSOLE */ +/*************Code to support toolchain's printf, scanf *******************************/ +/* These function __write and __read is used to support IAR toolchain to printf and scanf*/ +#if (defined(__ICCARM__)) +#pragma weak __write +size_t __write(int handle, const unsigned char *buffer, size_t size) +{ + if (buffer == 0) + { + /* + * This means that we should flush internal buffers. Since we don't we just return. + * (Remember, "handle" == -1 means that all handles should be flushed.) + */ + return 0; + } + + /* This function only writes to "standard out" and "standard err" for all other file handles it returns failure. */ + if ((handle != 1) && (handle != 2)) + { + return ((size_t)-1); + } + + /* Send data. */ + LOG_Push((uint8_t *)buffer, 1U); + + return size; +} + +#pragma weak __read +size_t __read(int handle, unsigned char *buffer, size_t size) +{ + /* This function only reads from "standard in", for all other file handles it returns failure. */ + if (handle != 0) + { + return ((size_t)-1); + } + + /* Receive data.*/ + LOG_ReadLine(buffer, size); + + return size; +} + +/* support LPC Xpresso with RedLib */ +#elif(defined(__REDLIB__)) + +#if (!SDK_DEBUGCONSOLE) && (defined(SDK_DEBUGCONSOLE_UART)) +int __attribute__((weak)) __sys_write(int handle, char *buffer, int size) +{ + if (buffer == 0) + { + /* return -1 if error. */ + return -1; + } + + /* This function only writes to "standard out" and "standard err" for all other file handles it returns failure. */ + if ((handle != 1) && (handle != 2)) + { + return -1; + } + + /* Send data. */ + LOG_Push((uint8_t *)buffer, size); + + return 0; +} + +int __attribute__((weak)) __sys_readc(void) +{ + char tmp; + + /* Receive data. */ + LOG_ReadCharacter((uint8_t *)&tmp); + + return tmp; +} +#endif + +/* These function __write and __read is used to support ARM_GCC, KDS, Atollic toolchains to printf and scanf*/ +#elif(defined(__GNUC__)) + +#if ((defined(__GNUC__) && (!defined(__MCUXPRESSO))) || \ + (defined(__MCUXPRESSO) && (!SDK_DEBUGCONSOLE) && (defined(SDK_DEBUGCONSOLE_UART)))) + +int __attribute__((weak)) _write(int handle, char *buffer, int size) +{ + if (buffer == 0) + { + /* return -1 if error. */ + return -1; + } + + /* This function only writes to "standard out" and "standard err" for all other file handles it returns failure. */ + if ((handle != 1) && (handle != 2)) + { + return -1; + } + + /* Send data. */ + LOG_Push((uint8_t *)buffer, size); + + return size; +} + +int __attribute__((weak)) _read(int handle, char *buffer, int size) +{ + /* This function only reads from "standard in", for all other file handles it returns failure. */ + if (handle != 0) + { + return -1; + } + + /* Receive data. */ + return LOG_ReadLine((uint8_t *)buffer, size); +} +#endif + +/* These function fputc and fgetc is used to support KEIL toolchain to printf and scanf*/ +#elif defined(__CC_ARM) +struct __FILE +{ + int handle; + /* + * Whatever you require here. If the only file you are using is standard output using printf() for debugging, + * no file handling is required. + */ +}; + +/* FILE is typedef in stdio.h. */ +#pragma weak __stdout +#pragma weak __stdin +FILE __stdout; +FILE __stdin; + +#pragma weak fputc +int fputc(int ch, FILE *f) +{ + /* Send data. */ + return LOG_Push((uint8_t *)(&ch), 1); +} + +#pragma weak fgetc +int fgetc(FILE *f) +{ + char ch; + + /* Receive data. */ + LOG_ReadCharacter((uint8_t *)&ch); + + return ch; +} +#endif /* __ICCARM__ */ diff --git a/platform/mcu/lpc54102/utilities/fsl_debug_console.h b/platform/mcu/lpc54102/utilities/fsl_debug_console.h new file mode 100644 index 0000000000..9b44d5d208 --- /dev/null +++ b/platform/mcu/lpc54102/utilities/fsl_debug_console.h @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Debug console shall provide input and output functions to scan and print formatted data. + * o Support a format specifier for PRINTF follows this prototype "%[flags][width][.precision][length]specifier" + * - [flags] :'-', '+', '#', ' ', '0' + * - [width]: number (0,1...) + * - [.precision]: number (0,1...) + * - [length]: do not support + * - [specifier]: 'd', 'i', 'f', 'F', 'x', 'X', 'o', 'p', 'u', 'c', 's', 'n' + * o Support a format specifier for SCANF follows this prototype " %[*][width][length]specifier" + * - [*]: is supported. + * - [width]: number (0,1...) + * - [length]: 'h', 'hh', 'l','ll','L'. ignore ('j','z','t') + * - [specifier]: 'd', 'i', 'u', 'f', 'F', 'e', 'E', 'g', 'G', 'a', 'A', 'o', 'c', 's' + */ + +#ifndef _FSL_DEBUGCONSOLE_H_ +#define _FSL_DEBUGCONSOLE_H_ + +#include "fsl_common.h" +/*! + * @addtogroup debugconsole + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief Definition to select sdk or toolchain printf, scanf. */ +#ifndef SDK_DEBUGCONSOLE +#define SDK_DEBUGCONSOLE 1U +#endif + +#if defined(SDK_DEBUGCONSOLE) && !(SDK_DEBUGCONSOLE) +#include +#endif + +#if SDK_DEBUGCONSOLE /* Select printf, scanf, putchar, getchar of SDK version. */ +#define PRINTF DbgConsole_Printf +#define SCANF DbgConsole_Scanf +#define PUTCHAR DbgConsole_Putchar +#define GETCHAR DbgConsole_Getchar +#else /* Select printf, scanf, putchar, getchar of toolchain. */ +#define PRINTF printf +#define SCANF scanf +#define PUTCHAR putchar +#define GETCHAR getchar +#endif /* SDK_DEBUGCONSOLE */ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + +/*! @name Initialization*/ +/* @{ */ + +/*! + * @brief Initializes the the peripheral used for debug messages. + * + * Call this function to enable debug log messages to be output via the specified peripheral, + * frequency of peripheral source clock, and base address at the specified baud rate. + * After this function has returned, stdout and stdin are connected to the selected peripheral. + * + * @param baseAddr Indicates the address of the peripheral used to send debug messages. + * @param baudRate The desired baud rate in bits per second. + * @param device Low level device type for the debug console, can be one of the following. + * @arg DEBUG_CONSOLE_DEVICE_TYPE_UART, + * @arg DEBUG_CONSOLE_DEVICE_TYPE_LPUART, + * @arg DEBUG_CONSOLE_DEVICE_TYPE_LPSCI, + * @arg DEBUG_CONSOLE_DEVICE_TYPE_USBCDC. + * @param clkSrcFreq Frequency of peripheral source clock. + * + * @return Indicates whether initialization was successful or not. + * @retval kStatus_Success Execution successfully + * @retval kStatus_Fail Execution failure + * @retval kStatus_InvalidArgument Invalid argument existed + */ +status_t DbgConsole_Init(uint32_t baseAddr, uint32_t baudRate, uint8_t device, uint32_t clkSrcFreq); + +/*! + * @brief De-initializes the peripheral used for debug messages. + * + * Call this function to disable debug log messages to be output via the specified peripheral + * base address and at the specified baud rate. + * + * @return Indicates whether de-initialization was successful or not. + */ +status_t DbgConsole_Deinit(void); + +#if SDK_DEBUGCONSOLE +/*! + * @brief Writes formatted output to the standard output stream. + * + * Call this function to write a formatted output to the standard output stream. + * + * @param fmt_s Format control string. + * @return Returns the number of characters printed or a negative value if an error occurs. + */ +int DbgConsole_Printf(const char *fmt_s, ...); + +/*! + * @brief Writes a character to stdout. + * + * Call this function to write a character to stdout. + * + * @param ch Character to be written. + * @return Returns the character written. + */ +int DbgConsole_Putchar(int ch); + +/*! + * @brief Reads formatted data from the standard input stream. + * + * Call this function to read formatted data from the standard input stream. + * + * @param fmt_ptr Format control string. + * @return Returns the number of fields successfully converted and assigned. + */ +int DbgConsole_Scanf(char *fmt_ptr, ...); + +/*! + * @brief Reads a character from standard input. + * + * Call this function to read a character from standard input. + * + * @return Returns the character read. + */ +int DbgConsole_Getchar(void); + +/*! + * @brief Debug console flush log. + * + * Call this function to wait the buffer empty and io idle before. + * If interrupt transfer is using, make sure the global IRQ is enable before call this function + * This function should be called when + * 1, before enter power down mode + * 2, log is required to print to terminal immediately + * @return Indicates whether wait idle was successful or not. + */ +status_t DbgConsole_Flush(void); + +#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING +/*! + * @brief Debug console try to get char + * This function provide a api which will not block current task, if character is + * avaliable return it , otherwise return fail. + * @param ch the address of char to receive + * @return Indicates get char was successful or not. + */ +status_t DbgConsole_TryGetchar(char *ch); +#endif + +#endif /* SDK_DEBUGCONSOLE */ + +/*! @} */ + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + +/*! @} */ + +#endif /* _FSL_DEBUGCONSOLE_H_ */ diff --git a/platform/mcu/lpc54102/utilities/fsl_debug_console_conf.h b/platform/mcu/lpc54102/utilities/fsl_debug_console_conf.h new file mode 100644 index 0000000000..4721d7177f --- /dev/null +++ b/platform/mcu/lpc54102/utilities/fsl_debug_console_conf.h @@ -0,0 +1,150 @@ +/* + * Copyright 2017 NXP + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _FSL_DEBUG_CONSOLE_CONF_H_ +#define _FSL_DEBUG_CONSOLE_CONF_H_ + +/****************Debug console configuration********************/ + +/*! @brief If Non-blocking mode is needed, please define it at project setting, +* otherwise blocking mode is the default transfer mode. +* Warning: If you want to use non-blocking transfer,please make sure the corresponding +* IO interrupt is enable, otherwise there is no output. +* And non-blocking is combine with buffer, no matter bare-metal or rtos. +*/ +#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING +/*! @brief define the transmit buffer length which is used to store the multi task log, buffer is enabled automatically +* when +* non-blocking transfer is using, +* This value will affect the RAM's ultilization, should be set per paltform's capability and software requirement. +* If it is configured too small, log maybe missed , because the log will not be +* buffered if the buffer is full, and the print will return immediately with -1. +* And this value should be multiple of 4 to meet memory alignment. +* +*/ +#ifndef DEBUG_CONSOLE_TRANSMIT_BUFFER_LEN +#define DEBUG_CONSOLE_TRANSMIT_BUFFER_LEN (512U) +#endif /* DEBUG_CONSOLE_TRANSMIT_BUFFER_LEN */ + +/*! @brief define the receive buffer length which is used to store the user input, buffer is enabled automatically when +* non-blocking transfer is using, +* This value will affect the RAM's ultilization, should be set per paltform's capability and software requirement. +* If it is configured too small, log maybe missed, because buffer will be overwrited if buffer is too small. +* And this value should be multiple of 4 to meet memory alignment. +* +*/ +#ifndef DEBUG_CONSOLE_RECEIVE_BUFFER_LEN +#define DEBUG_CONSOLE_RECEIVE_BUFFER_LEN (512U) +#endif /* DEBUG_CONSOLE_RECEIVE_BUFFER_LEN */ + +#else +#define DEBUG_CONSOLE_TRANSFER_BLOCKING +#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */ + +/*!@ brief define the MAX log length debug console support , that is when you call printf("log", x);, the log +* length can not bigger than this value. +* This macro decide the local log buffer length, the buffer locate at stack, the stack maybe overflow if +* the buffer is too big and current task stack size not big enough. +*/ +#ifndef DEBUG_CONSOLE_PRINTF_MAX_LOG_LEN +#define DEBUG_CONSOLE_PRINTF_MAX_LOG_LEN (128U) +#endif /* DEBUG_CONSOLE_PRINTF_MAX_LOG_LEN */ + +/*!@ brief define the buffer support buffer scanf log length, that is when you call scanf("log", &x);, the log +* length can not bigger than this value. +* As same as the DEBUG_CONSOLE_BUFFER_PRINTF_MAX_LOG_LEN. +*/ +#ifndef DEBUG_CONSOLE_SCANF_MAX_LOG_LEN +#define DEBUG_CONSOLE_SCANF_MAX_LOG_LEN (20U) +#endif /* DEBUG_CONSOLE_SCANF_MAX_LOG_LEN */ + +/*! @brief Debug console synchronization +* User should not change these macro for synchronization mode, but add the +* corresponding synchronization mechanism per different software environment. +* Such as, if another RTOS is used, +* add: +* #define DEBUG_CONSOLE_SYNCHRONIZATION_XXXX 3 +* in this configuration file and implement the synchronization in fsl.log.c. +*/ +/*! @brief synchronization for baremetal software */ +#define DEBUG_CONSOLE_SYNCHRONIZATION_BM 0 +/*! @brief synchronization for freertos software */ +#define DEBUG_CONSOLE_SYNCHRONIZATION_FREERTOS 1 + +/*! @brief RTOS synchronization mechanism disable +* If not defined, default is enable, to avoid multitask log print mess. +* If other RTOS is used, you can implement the RTOS's specific synchronization mechanism in fsl.log.c +* If synchronization is disabled, log maybe messed on terminal. +*/ +#ifndef DEBUG_CONSOLE_DISABLE_RTOS_SYNCHRONIZATION +#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING +#ifdef FSL_RTOS_FREE_RTOS +#define DEBUG_CONSOLE_SYNCHRONIZATION_MODE DEBUG_CONSOLE_SYNCHRONIZATION_FREERTOS +#else +#define DEBUG_CONSOLE_SYNCHRONIZATION_MODE DEBUG_CONSOLE_SYNCHRONIZATION_BM +#endif /* FSL_RTOS_FREE_RTOS */ +#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */ +#endif /* DEBUG_CONSOLE_DISABLE_RTOS_SYNCHRONIZATION */ + +/*! @brief echo function support +* If you want to use the echo function,please define DEBUG_CONSOLE_ENABLE_ECHO +* at your project setting. +*/ +#ifndef DEBUG_CONSOLE_ENABLE_ECHO +#define DEBUG_CONSOLE_ENABLE_ECHO_FUNCTION 0 +#else +#define DEBUG_CONSOLE_ENABLE_ECHO_FUNCTION 1 +#endif /* DEBUG_CONSOLE_ENABLE_ECHO */ + +/*********************************************************************/ + +/***************Debug console other configuration*********************/ +/*! @brief Definition to printf the float number. */ +#ifndef PRINTF_FLOAT_ENABLE +#define PRINTF_FLOAT_ENABLE 0U +#endif /* PRINTF_FLOAT_ENABLE */ + +/*! @brief Definition to scanf the float number. */ +#ifndef SCANF_FLOAT_ENABLE +#define SCANF_FLOAT_ENABLE 0U +#endif /* SCANF_FLOAT_ENABLE */ + +/*! @brief Definition to support advanced format specifier for printf. */ +#ifndef PRINTF_ADVANCED_ENABLE +#define PRINTF_ADVANCED_ENABLE 0U +#endif /* PRINTF_ADVANCED_ENABLE */ + +/*! @brief Definition to support advanced format specifier for scanf. */ +#ifndef SCANF_ADVANCED_ENABLE +#define SCANF_ADVANCED_ENABLE 0U +#endif /* SCANF_ADVANCED_ENABLE */ + +/*******************************************************************/ + +#endif /* _FSL_DEBUG_CONSOLE_CONF_H_ */ diff --git a/platform/mcu/lpc54102/utilities/fsl_notifier.c b/platform/mcu/lpc54102/utilities/fsl_notifier.c new file mode 100644 index 0000000000..730034d6a8 --- /dev/null +++ b/platform/mcu/lpc54102/utilities/fsl_notifier.c @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "fsl_notifier.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/******************************************************************************* + * Code + ******************************************************************************/ + +status_t NOTIFIER_CreateHandle(notifier_handle_t *notifierHandle, + notifier_user_config_t **configs, + uint8_t configsNumber, + notifier_callback_config_t *callbacks, + uint8_t callbacksNumber, + notifier_user_function_t userFunction, + void *userData) +{ + /* Check input parameter - at least one configuration is required and userFunction must exist */ + if ((configs == NULL) || (configsNumber == 0U) || (userFunction == NULL)) + { + return kStatus_Fail; + } + /* Initialize handle structure */ + memset(notifierHandle, 0, sizeof(notifier_handle_t)); + /* Store references to user-defined configurations */ + notifierHandle->configsTable = configs; + notifierHandle->configsNumber = configsNumber; + /* Store references to user-defined callback configurations */ + if (callbacks != NULL) + { + notifierHandle->callbacksTable = callbacks; + notifierHandle->callbacksNumber = callbacksNumber; + /* If all callbacks return success, then the errorCallbackIndex is callbacksNumber */ + notifierHandle->errorCallbackIndex = callbacksNumber; + } + notifierHandle->userFunction = userFunction; + notifierHandle->userData = userData; + + return kStatus_Success; +} + +status_t NOTIFIER_SwitchConfig(notifier_handle_t *notifierHandle, uint8_t configIndex, notifier_policy_t policy) +{ + uint8_t currentStaticCallback = 0U; /* Index to array of statically registered call-backs */ + status_t returnCode = kStatus_Success; /* Function return */ + + notifier_notification_block_t notifyBlock; /* Callback notification block */ + notifier_callback_config_t *callbackConfig; /* Pointer to callback configuration */ + + /* Set errorcallbackindex as callbacksNumber, which means no callback error now */ + notifierHandle->errorCallbackIndex = notifierHandle->callbacksNumber; + + /* Requested configuration availability check */ + if (configIndex >= notifierHandle->configsNumber) + { + return kStatus_OutOfRange; + } + + /* Initialization of local variables from the Notifier handle structure */ + + notifyBlock.policy = policy; + notifyBlock.targetConfig = notifierHandle->configsTable[configIndex]; + notifyBlock.notifyType = kNOTIFIER_NotifyBefore; + + /* From all statically registered call-backs... */ + for (currentStaticCallback = 0U; currentStaticCallback < notifierHandle->callbacksNumber; currentStaticCallback++) + { + callbackConfig = &(notifierHandle->callbacksTable[currentStaticCallback]); + /* ...notify only those which asked to be called before the configuration switch */ + if (((uint32_t)callbackConfig->callbackType) & kNOTIFIER_CallbackBefore) + { + /* In case that call-back returned error code mark it, store the call-back handle and eventually cancel + * the configuration switch */ + if (callbackConfig->callback(¬ifyBlock, callbackConfig->callbackData) != kStatus_Success) + { + returnCode = kStatus_NOTIFIER_ErrorNotificationBefore; + notifierHandle->errorCallbackIndex = currentStaticCallback; + /* If not forcing configuration switch, call all already notified call-backs to revert their state + * as the switch is canceled */ + if (policy != kNOTIFIER_PolicyForcible) + { + break; + } + } + } + } + + /* Set configuration */ + + /* In case that any call-back returned error code and policy doesn't force the configuration set, go to after + * switch call-backs */ + if ((policy == kNOTIFIER_PolicyForcible) || (returnCode == kStatus_Success)) + { + returnCode = notifierHandle->userFunction(notifierHandle->configsTable[configIndex], notifierHandle->userData); + if (returnCode != kStatus_Success) + { + return returnCode; + } + /* Update current configuration index */ + notifierHandle->currentConfigIndex = configIndex; + notifyBlock.notifyType = kNOTIFIER_NotifyAfter; + /* From all statically registered call-backs... */ + for (currentStaticCallback = 0U; currentStaticCallback < notifierHandle->callbacksNumber; + currentStaticCallback++) + { + callbackConfig = &(notifierHandle->callbacksTable[currentStaticCallback]); + /* ...notify only those which asked to be called after the configruation switch */ + if (((uint32_t)callbackConfig->callbackType) & kNOTIFIER_CallbackAfter) + { + /* In case that call-back returned error code mark it and store the call-back handle */ + if (callbackConfig->callback(¬ifyBlock, callbackConfig->callbackData) != kStatus_Success) + { + returnCode = kStatus_NOTIFIER_ErrorNotificationAfter; + notifierHandle->errorCallbackIndex = currentStaticCallback; + if (policy != kNOTIFIER_PolicyForcible) + { + break; + } + } + } + } + } + else + { + /* End of unsuccessful switch */ + notifyBlock.notifyType = kNOTIFIER_NotifyRecover; + while (currentStaticCallback--) + { + callbackConfig = &(notifierHandle->callbacksTable[currentStaticCallback]); + if (((uint32_t)callbackConfig->callbackType) & kNOTIFIER_CallbackBefore) + { + callbackConfig->callback(¬ifyBlock, callbackConfig->callbackData); + } + } + } + + return returnCode; +} + +uint8_t NOTIFIER_GetErrorCallbackIndex(notifier_handle_t *notifierHandle) +{ + return notifierHandle->errorCallbackIndex; +} diff --git a/platform/mcu/lpc54102/utilities/fsl_notifier.h b/platform/mcu/lpc54102/utilities/fsl_notifier.h new file mode 100644 index 0000000000..b3931d64f7 --- /dev/null +++ b/platform/mcu/lpc54102/utilities/fsl_notifier.h @@ -0,0 +1,259 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_NOTIFIER_H_ +#define _FSL_NOTIFIER_H_ + +#include "fsl_common.h" +/*! + * @addtogroup notifier + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! + * @brief Notifier error codes. + * + * Used as return value of Notifier functions. + */ +enum _notifier_status +{ + kStatus_NOTIFIER_ErrorNotificationBefore = + MAKE_STATUS(kStatusGroup_NOTIFIER, 0), /*!< An error occurs during send "BEFORE" notification. */ + kStatus_NOTIFIER_ErrorNotificationAfter = + MAKE_STATUS(kStatusGroup_NOTIFIER, 1), /*!< An error occurs during send "AFTER" notification. */ +}; + +/*! + * @brief Notifier policies. + * + * Defines whether the user function execution is forced or not. + * For kNOTIFIER_PolicyForcible, the user function is executed regardless of the callback results, + * while kNOTIFIER_PolicyAgreement policy is used to exit NOTIFIER_SwitchConfig() + * when any of the callbacks returns error code. + * See also NOTIFIER_SwitchConfig() description. + */ +typedef enum _notifier_policy +{ + kNOTIFIER_PolicyAgreement, /*!< NOTIFIER_SwitchConfig() method is exited when any of the callbacks returns error + code. */ + kNOTIFIER_PolicyForcible, /*!< The user function is executed regardless of the results. */ +} notifier_policy_t; + +/*! @brief Notification type. Used to notify registered callbacks */ +typedef enum _notifier_notification_type +{ + kNOTIFIER_NotifyRecover = 0x00U, /*!< Notify IP to recover to previous work state. */ + kNOTIFIER_NotifyBefore = 0x01U, /*!< Notify IP that configuration setting is going to change. */ + kNOTIFIER_NotifyAfter = 0x02U, /*!< Notify IP that configuration setting has been changed. */ +} notifier_notification_type_t; + +/*! + * @brief The callback type, which indicates kinds of notification the callback handles. + * + * Used in the callback configuration structure (notifier_callback_config_t) + * to specify when the registered callback is called during configuration switch initiated by the + * NOTIFIER_SwitchConfig(). + * Callback can be invoked in following situations. + * - Before the configuration switch (Callback return value can affect NOTIFIER_SwitchConfig() + * execution. See the NOTIFIER_SwitchConfig() and notifier_policy_t documentation). + * - After an unsuccessful attempt to switch configuration + * - After a successful configuration switch + */ +typedef enum _notifier_callback_type +{ + kNOTIFIER_CallbackBefore = 0x01U, /*!< Callback handles BEFORE notification. */ + kNOTIFIER_CallbackAfter = 0x02U, /*!< Callback handles AFTER notification. */ + kNOTIFIER_CallbackBeforeAfter = 0x03U, /*!< Callback handles BEFORE and AFTER notification. */ +} notifier_callback_type_t; + +/*! @brief Notifier user configuration type. + * + * Reference of the user defined configuration is stored in an array; the notifier switches between these configurations + * based on this array. + */ +typedef void notifier_user_config_t; + +/*! @brief Notifier user function prototype + * Use this function to execute specific operations in configuration switch. + * Before and after this function execution, different notification is sent to registered callbacks. + * If this function returns any error code, NOTIFIER_SwitchConfig() exits. + * + * @param targetConfig target Configuration. + * @param userData Refers to other specific data passed to user function. + * @return An error code or kStatus_Success. + */ +typedef status_t (*notifier_user_function_t)(notifier_user_config_t *targetConfig, void *userData); + +/*! @brief notification block passed to the registered callback function. */ +typedef struct _notifier_notification_block +{ + notifier_user_config_t *targetConfig; /*!< Pointer to target configuration. */ + notifier_policy_t policy; /*!< Configure transition policy. */ + notifier_notification_type_t notifyType; /*!< Configure notification type. */ +} notifier_notification_block_t; + +/*! + * @brief Callback prototype. + * + * Declaration of a callback. It is common for registered callbacks. + * Reference to function of this type is part of the notifier_callback_config_t callback configuration structure. + * Depending on callback type, function of this prototype is called (see NOTIFIER_SwitchConfig()) + * before configuration switch, after it or in both use cases to notify about + * the switch progress (see notifier_callback_type_t). When called, the type of the notification + * is passed as a parameter along with the reference to the target configuration structure (see notifier_notification_block_t) + * and any data passed during the callback registration. + * When notified before the configuration switch, depending on the configuration switch policy (see + * notifier_policy_t), the callback may deny the execution of the user function by returning an error code different + * than kStatus_Success (see NOTIFIER_SwitchConfig()). + * + * @param notify Notification block. + * @param data Callback data. Refers to the data passed during callback registration. Intended to + * pass any driver or application data such as internal state information. + * @return An error code or kStatus_Success. + */ +typedef status_t (*notifier_callback_t)(notifier_notification_block_t *notify, void *data); + +/*! + * @brief Callback configuration structure. + * + * This structure holds the configuration of callbacks. + * Callbacks of this type are expected to be statically allocated. + * This structure contains the following application-defined data. + * callback - pointer to the callback function + * callbackType - specifies when the callback is called + * callbackData - pointer to the data passed to the callback. + */ +typedef struct _notifier_callback_config +{ + notifier_callback_t callback; /*!< Pointer to the callback function. */ + notifier_callback_type_t callbackType; /*!< Callback type. */ + void *callbackData; /*!< Pointer to the data passed to the callback. */ +} notifier_callback_config_t; + +/*! + * @brief Notifier handle structure. + * + * Notifier handle structure. Contains data necessary for the Notifier proper function. + * Stores references to registered configurations, callbacks, information about their numbers, + * user function, user data, and other internal data. + * NOTIFIER_CreateHandle() must be called to initialize this handle. + */ +typedef struct _notifier_handle +{ + notifier_user_config_t **configsTable; /*!< Pointer to configure table. */ + uint8_t configsNumber; /*!< Number of configurations. */ + notifier_callback_config_t *callbacksTable; /*!< Pointer to callback table. */ + uint8_t callbacksNumber; /*!< Maximum number of callback configurations. */ + uint8_t errorCallbackIndex; /*!< Index of callback returns error. */ + uint8_t currentConfigIndex; /*!< Index of current configuration. */ + notifier_user_function_t userFunction; /*!< User function. */ + void *userData; /*!< User data passed to user function. */ +} notifier_handle_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif + +/*! + * @brief Creates a Notifier handle. + * + * @param notifierHandle A pointer to the notifier handle. + * @param configs A pointer to an array with references to all configurations which is handled by the Notifier. + * @param configsNumber Number of configurations. Size of the configuration array. + * @param callbacks A pointer to an array of callback configurations. + * If there are no callbacks to register during Notifier initialization, use NULL value. + * @param callbacksNumber Number of registered callbacks. Size of the callbacks array. + * @param userFunction User function. + * @param userData User data passed to user function. + * @return An error Code or kStatus_Success. + */ +status_t NOTIFIER_CreateHandle(notifier_handle_t *notifierHandle, + notifier_user_config_t **configs, + uint8_t configsNumber, + notifier_callback_config_t *callbacks, + uint8_t callbacksNumber, + notifier_user_function_t userFunction, + void *userData); + +/*! + * @brief Switches the configuration according to a pre-defined structure. + * + * This function sets the system to the target configuration. Before transition, + * the Notifier sends notifications to all callbacks registered to the callback table. + * Callbacks are invoked in the following order: All registered callbacks are notified + * ordered by index in the callbacks array. The same order is used for before and after switch notifications. + * The notifications before the configuration switch can be used to obtain confirmation about + * the change from registered callbacks. If any registered callback denies the + * configuration change, further execution of this function depends on the notifier policy: the + * configuration change is either forced (kNOTIFIER_PolicyForcible) or exited (kNOTIFIER_PolicyAgreement). + * When configuration change is forced, the result of the before switch notifications are ignored. If an + * agreement is required, if any callback returns an error code, further notifications + * before switch notifications are cancelled and all already notified callbacks are re-invoked. + * The index of the callback which returned error code during pre-switch notifications is stored + * (any error codes during callbacks re-invocation are ignored) and NOTIFIER_GetErrorCallback() can be used to get it. + * Regardless of the policies, if any callback returns an error code, an error code indicating in which phase + * the error occurred is returned when NOTIFIER_SwitchConfig() exits. + * @param notifierHandle pointer to notifier handle + * @param configIndex Index of the target configuration. + * @param policy Transaction policy, kNOTIFIER_PolicyAgreement or kNOTIFIER_PolicyForcible. + * + * @return An error code or kStatus_Success. + * + */ +status_t NOTIFIER_SwitchConfig(notifier_handle_t *notifierHandle, uint8_t configIndex, notifier_policy_t policy); + +/*! + * @brief This function returns the last failed notification callback. + * + * This function returns an index of the last callback that failed during the configuration switch while + * the last NOTIFIER_SwitchConfig() was called. If the last NOTIFIER_SwitchConfig() call ended successfully + * value equal to callbacks number is returned. The returned value represents an index in the array of + * static call-backs. + * + * @param notifierHandle Pointer to the notifier handle + * @return Callback Index of the last failed callback or value equal to callbacks count. + */ +uint8_t NOTIFIER_GetErrorCallbackIndex(notifier_handle_t *notifierHandle); + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + +/*! @}*/ + +#endif /* _FSL_NOTIFIER_H_ */ diff --git a/platform/mcu/lpc54102/utilities/fsl_shell.c b/platform/mcu/lpc54102/utilities/fsl_shell.c new file mode 100644 index 0000000000..71714c037b --- /dev/null +++ b/platform/mcu/lpc54102/utilities/fsl_shell.c @@ -0,0 +1,647 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * POSIX getopt for Windows + * Code given out at the 1985 UNIFORUM conference in Dallas. + * + * From std-unix@ut-sally.UUCP (Moderator, John Quarterman) Sun Nov 3 14:34:15 1985 + * Relay-Version: version B 2.10.3 4.3bsd-beta 6/6/85; site gatech.CSNET + * Posting-Version: version B 2.10.2 9/18/84; site ut-sally.UUCP + * Path: gatech!akgua!mhuxv!mhuxt!mhuxr!ulysses!allegra!mit-eddie!genrad!panda!talcott!harvard!seismo!ut-sally!std-unix + * From: std-unix@ut-sally.UUCP (Moderator, John Quarterman) + * Newsgroups: mod.std.unix + * Subject: public domain AT&T getopt source + * Message-ID: <3352@ut-sally.UUCP> + * Date: 3 Nov 85 19:34:15 GMT + * Date-Received: 4 Nov 85 12:25:09 GMT + * Organization: IEEE/P1003 Portable Operating System Environment Committee + * Lines: 91 + * Approved: jsq@ut-sally.UUC + * Here's something you've all been waiting for: the AT&T public domain + * source for getopt(3). It is the code which was given out at the 1985 + * UNIFORUM conference in Dallas. I obtained it by electronic mail + * directly from AT&T. The people there assure me that it is indeed + * in the public domain + * There is no manual page. That is because the one they gave out at + * UNIFORUM was slightly different from the current System V Release 2 + * manual page. The difference apparently involved a note about the + * famous rules 5 and 6, recommending using white space between an option + * and its first argument, and not grouping options that have arguments. + * Getopt itself is currently lenient about both of these things White + * space is allowed, but not mandatory, and the last option in a group can + * have an argument. That particular version of the man page evidently + * has no official existence, and my source at AT&T did not send a copy. + * The current SVR2 man page reflects the actual behavor of this getopt. + * However, I am not about to post a copy of anything licensed by AT&T. + */ + +#include +#include "fsl_shell.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define KEY_ESC (0x1BU) +#define KET_DEL (0x7FU) + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +static int32_t HelpCommand(p_shell_context_t context, int32_t argc, char **argv); /*!< help command */ + +static int32_t ExitCommand(p_shell_context_t context, int32_t argc, char **argv); /*!< exit command */ + +static int32_t ParseLine(const char *cmd, uint32_t len, char *argv[SHELL_MAX_ARGS]); /*!< parse line command */ + +static int32_t StrCompare(const char *str1, const char *str2, int32_t count); /*!< compare string command */ + +static void ProcessCommand(p_shell_context_t context, const char *cmd); /*!< process a command */ + +static void GetHistoryCommand(p_shell_context_t context, uint8_t hist_pos); /*!< get commands history */ + +static void AutoComplete(p_shell_context_t context); /*!< auto complete command */ + +static uint8_t GetChar(p_shell_context_t context); /*!< get a char from communication interface */ + +static int32_t StrLen(const char *str); /*!< get string length */ + +static char *StrCopy(char *dest, const char *src, int32_t count); /*!< string copy */ + +/******************************************************************************* + * Variables + ******************************************************************************/ +static const shell_command_context_t xHelpCommand = {"help", "\r\n\"help\": Lists all the registered commands\r\n", + HelpCommand, 0}; + +static const shell_command_context_t xExitCommand = {"exit", "\r\n\"exit\": Exit program\r\n", ExitCommand, 0}; + +static shell_command_context_list_t g_RegisteredCommands; + +static char g_paramBuffer[SHELL_BUFFER_SIZE]; + +/******************************************************************************* + * Code + ******************************************************************************/ +void SHELL_Init( + p_shell_context_t context, send_data_cb_t send_cb, recv_data_cb_t recv_cb, printf_data_t shell_printf, char *prompt) +{ + assert(send_cb != NULL); + assert(recv_cb != NULL); + assert(prompt != NULL); + assert(shell_printf != NULL); + + /* Memset for context */ + memset(context, 0, sizeof(shell_context_struct)); + context->send_data_func = send_cb; + context->recv_data_func = recv_cb; + context->printf_data_func = shell_printf; + context->prompt = prompt; + + SHELL_RegisterCommand(&xHelpCommand); + SHELL_RegisterCommand(&xExitCommand); +} + +int32_t SHELL_Main(p_shell_context_t context) +{ + uint8_t ch; + int32_t i; + + if (!context) + { + return -1; + } + + context->exit = false; + context->printf_data_func("\r\nSHELL (build: %s)\r\n", __DATE__); + context->printf_data_func("Copyright (c) 2017 NXP Semiconductor\r\n"); + context->printf_data_func(context->prompt); + + while (1) + { + if (context->exit) + { + break; + } + ch = GetChar(context); + /* If error occured when getting a char, continue to receive a new char. */ + if ((uint8_t)(-1) == ch) + { + continue; + } + /* Special key */ + if (ch == KEY_ESC) + { + context->stat = kSHELL_Special; + continue; + } + else if (context->stat == kSHELL_Special) + { + /* Function key */ + if (ch == '[') + { + context->stat = kSHELL_Function; + continue; + } + context->stat = kSHELL_Normal; + } + else if (context->stat == kSHELL_Function) + { + context->stat = kSHELL_Normal; + + switch ((uint8_t)ch) + { + /* History operation here */ + case 'A': /* Up key */ + GetHistoryCommand(context, context->hist_current); + if (context->hist_current < (context->hist_count - 1)) + { + context->hist_current++; + } + break; + case 'B': /* Down key */ + GetHistoryCommand(context, context->hist_current); + if (context->hist_current > 0) + { + context->hist_current--; + } + break; + case 'D': /* Left key */ + if (context->c_pos) + { + context->printf_data_func("\b"); + context->c_pos--; + } + break; + case 'C': /* Right key */ + if (context->c_pos < context->l_pos) + { + context->printf_data_func("%c", context->line[context->c_pos]); + context->c_pos++; + } + break; + default: + break; + } + continue; + } + /* Handle tab key */ + else if (ch == '\t') + { +#if SHELL_AUTO_COMPLETE + /* Move the cursor to the beginning of line */ + for (i = 0; i < context->c_pos; i++) + { + context->printf_data_func("\b"); + } + /* Do auto complete */ + AutoComplete(context); + /* Move position to end */ + context->c_pos = context->l_pos = StrLen(context->line); +#endif + continue; + } +#if SHELL_SEARCH_IN_HIST + /* Search command in history */ + else if ((ch == '`') && (context->l_pos == 0) && (context->line[0] == 0x00)) + { + } +#endif + /* Handle backspace key */ + else if ((ch == KET_DEL) || (ch == '\b')) + { + /* There must be at last one char */ + if (context->c_pos == 0) + { + continue; + } + + context->l_pos--; + context->c_pos--; + + if (context->l_pos > context->c_pos) + { + memmove(&context->line[context->c_pos], &context->line[context->c_pos + 1], + context->l_pos - context->c_pos); + context->line[context->l_pos] = 0; + context->printf_data_func("\b%s \b", &context->line[context->c_pos]); + + /* Reset position */ + for (i = context->c_pos; i <= context->l_pos; i++) + { + context->printf_data_func("\b"); + } + } + else /* Normal backspace operation */ + { + context->printf_data_func("\b \b"); + context->line[context->l_pos] = 0; + } + continue; + } + else + { + } + + /* Input too long */ + if (context->l_pos >= (SHELL_BUFFER_SIZE - 1)) + { + context->l_pos = 0; + } + + /* Handle end of line, break */ + if ((ch == '\r') || (ch == '\n')) + { + static char endoflinechar = 0U; + + if ((endoflinechar != 0U) && (endoflinechar != ch)) + { + continue; + } + else + { + endoflinechar = ch; + context->printf_data_func("\r\n"); + /* If command line is NULL, will start a new transfer */ + if (0U == StrLen(context->line)) + { + context->printf_data_func(context->prompt); + continue; + } + ProcessCommand(context, context->line); + /* Reset all params */ + context->c_pos = context->l_pos = 0; + context->hist_current = 0; + context->printf_data_func(context->prompt); + memset(context->line, 0, sizeof(context->line)); + continue; + } + } + + /* Normal character */ + if (context->c_pos < context->l_pos) + { + memmove(&context->line[context->c_pos + 1], &context->line[context->c_pos], + context->l_pos - context->c_pos); + context->line[context->c_pos] = ch; + context->printf_data_func("%s", &context->line[context->c_pos]); + /* Move the cursor to new position */ + for (i = context->c_pos; i < context->l_pos; i++) + { + context->printf_data_func("\b"); + } + } + else + { + context->line[context->l_pos] = ch; + context->printf_data_func("%c", ch); + } + + ch = 0; + context->l_pos++; + context->c_pos++; + } + return 0; +} + +static int32_t HelpCommand(p_shell_context_t context, int32_t argc, char **argv) +{ + uint8_t i = 0; + + for (i = 0; i < g_RegisteredCommands.numberOfCommandInList; i++) + { + context->printf_data_func(g_RegisteredCommands.CommandList[i]->pcHelpString); + } + return 0; +} + +static int32_t ExitCommand(p_shell_context_t context, int32_t argc, char **argv) +{ + /* Skip warning */ + context->printf_data_func("\r\nSHELL exited\r\n"); + context->exit = true; + return 0; +} + +static void ProcessCommand(p_shell_context_t context, const char *cmd) +{ + static const shell_command_context_t *tmpCommand = NULL; + static const char *tmpCommandString; + int32_t argc; + char *argv[SHELL_BUFFER_SIZE]; + uint8_t flag = 1; + uint8_t tmpCommandLen; + uint8_t tmpLen; + uint8_t i = 0; + + tmpLen = StrLen(cmd); + argc = ParseLine(cmd, tmpLen, argv); + + if ((tmpCommand == NULL) && (argc > 0)) + { + for (i = 0; i < g_RegisteredCommands.numberOfCommandInList; i++) + { + tmpCommand = g_RegisteredCommands.CommandList[i]; + tmpCommandString = tmpCommand->pcCommand; + tmpCommandLen = StrLen(tmpCommandString); + /* Compare with space or end of string */ + if ((cmd[tmpCommandLen] == ' ') || (cmd[tmpCommandLen] == 0x00)) + { + if (StrCompare(tmpCommandString, argv[0], tmpCommandLen) == 0) + { + /* support commands with optional number of parameters */ + if (tmpCommand->cExpectedNumberOfParameters == SHELL_OPTIONAL_PARAMS) + { + flag = 0; + } + else if ((tmpCommand->cExpectedNumberOfParameters == 0) && (argc == 1)) + { + flag = 0; + } + else if (tmpCommand->cExpectedNumberOfParameters > 0) + { + if ((argc - 1) == tmpCommand->cExpectedNumberOfParameters) + { + flag = 0; + } + } + else + { + flag = 1; + } + break; + } + } + } + } + + if ((tmpCommand != NULL) && (flag == 1U)) + { + context->printf_data_func( + "\r\nIncorrect command parameter(s). Enter \"help\" to view a list of available commands.\r\n\r\n"); + tmpCommand = NULL; + } + else if (tmpCommand != NULL) + { + tmpLen = StrLen(cmd); + /* Compare with last command. Push back to history buffer if different */ + if (tmpLen != StrCompare(cmd, context->hist_buf[0], StrLen(cmd))) + { + for (i = SHELL_HIST_MAX - 1; i > 0; i--) + { + memset(context->hist_buf[i], '\0', SHELL_BUFFER_SIZE); + tmpLen = StrLen(context->hist_buf[i - 1]); + StrCopy(context->hist_buf[i], context->hist_buf[i - 1], tmpLen); + } + memset(context->hist_buf[0], '\0', SHELL_BUFFER_SIZE); + tmpLen = StrLen(cmd); + StrCopy(context->hist_buf[0], cmd, tmpLen); + if (context->hist_count < SHELL_HIST_MAX) + { + context->hist_count++; + } + } + tmpCommand->pFuncCallBack(context, argc, argv); + tmpCommand = NULL; + } + else + { + context->printf_data_func( + "\r\nCommand not recognised. Enter 'help' to view a list of available commands.\r\n\r\n"); + tmpCommand = NULL; + } +} + +static void GetHistoryCommand(p_shell_context_t context, uint8_t hist_pos) +{ + uint8_t i; + uint32_t tmp; + + if (context->hist_buf[0][0] == '\0') + { + context->hist_current = 0; + return; + } + if (hist_pos >= SHELL_HIST_MAX) + { + hist_pos = SHELL_HIST_MAX - 1; + } + tmp = StrLen(context->line); + /* Clear current if have */ + if (tmp > 0) + { + memset(context->line, '\0', tmp); + for (i = 0; i < tmp; i++) + { + context->printf_data_func("\b \b"); + } + } + + context->l_pos = StrLen(context->hist_buf[hist_pos]); + context->c_pos = context->l_pos; + StrCopy(context->line, context->hist_buf[hist_pos], context->l_pos); + context->printf_data_func(context->hist_buf[hist_pos]); +} + +static void AutoComplete(p_shell_context_t context) +{ + int32_t len; + int32_t minLen; + uint8_t i = 0; + const shell_command_context_t *tmpCommand = NULL; + const char *namePtr; + const char *cmdName; + + minLen = 0; + namePtr = NULL; + + if (!StrLen(context->line)) + { + return; + } + context->printf_data_func("\r\n"); + /* Empty tab, list all commands */ + if (context->line[0] == '\0') + { + HelpCommand(context, 0, NULL); + return; + } + /* Do auto complete */ + for (i = 0; i < g_RegisteredCommands.numberOfCommandInList; i++) + { + tmpCommand = g_RegisteredCommands.CommandList[i]; + cmdName = tmpCommand->pcCommand; + if (StrCompare(context->line, cmdName, StrLen(context->line)) == 0) + { + if (minLen == 0) + { + namePtr = cmdName; + minLen = StrLen(namePtr); + /* Show possible matches */ + context->printf_data_func("%s\r\n", cmdName); + continue; + } + len = StrCompare(namePtr, cmdName, StrLen(namePtr)); + if (len < 0) + { + len = len * (-1); + } + if (len < minLen) + { + minLen = len; + } + } + } + /* Auto complete string */ + if (namePtr) + { + StrCopy(context->line, namePtr, minLen); + } + context->printf_data_func("%s%s", context->prompt, context->line); + return; +} + +static char *StrCopy(char *dest, const char *src, int32_t count) +{ + char *ret = dest; + int32_t i = 0; + + for (i = 0; i < count; i++) + { + dest[i] = src[i]; + } + + return ret; +} + +static int32_t StrLen(const char *str) +{ + int32_t i = 0; + + while (*str) + { + str++; + i++; + } + return i; +} + +static int32_t StrCompare(const char *str1, const char *str2, int32_t count) +{ + while (count--) + { + if (*str1++ != *str2++) + { + return *(unsigned char *)(str1 - 1) - *(unsigned char *)(str2 - 1); + } + } + return 0; +} + +static int32_t ParseLine(const char *cmd, uint32_t len, char *argv[SHELL_MAX_ARGS]) +{ + uint32_t argc; + char *p; + uint32_t position; + + /* Init params */ + memset(g_paramBuffer, '\0', len + 1); + StrCopy(g_paramBuffer, cmd, len); + + p = g_paramBuffer; + position = 0; + argc = 0; + + while (position < len) + { + /* Skip all blanks */ + while (((char)(*p) == ' ') && (position < len)) + { + *p = '\0'; + p++; + position++; + } + /* Process begin of a string */ + if (*p == '"') + { + p++; + position++; + argv[argc] = p; + argc++; + /* Skip this string */ + while ((*p != '"') && (position < len)) + { + p++; + position++; + } + /* Skip '"' */ + *p = '\0'; + p++; + position++; + } + else /* Normal char */ + { + argv[argc] = p; + argc++; + while (((char)*p != ' ') && ((char)*p != '\t') && (position < len)) + { + p++; + position++; + } + } + } + return argc; +} + +int32_t SHELL_RegisterCommand(const shell_command_context_t *command_context) +{ + int32_t result = 0; + + /* If have room in command list */ + if (g_RegisteredCommands.numberOfCommandInList < SHELL_MAX_CMD) + { + g_RegisteredCommands.CommandList[g_RegisteredCommands.numberOfCommandInList++] = command_context; + } + else + { + result = -1; + } + return result; +} + +static uint8_t GetChar(p_shell_context_t context) +{ + uint8_t ch; + +#if SHELL_USE_FILE_STREAM + ch = fgetc(context->STDIN); +#else + context->recv_data_func(&ch, 1U); +#endif + return ch; +} diff --git a/platform/mcu/lpc54102/utilities/fsl_shell.h b/platform/mcu/lpc54102/utilities/fsl_shell.h new file mode 100644 index 0000000000..d12357bcb0 --- /dev/null +++ b/platform/mcu/lpc54102/utilities/fsl_shell.h @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2015, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _FSL_SHELL_H_ +#define _FSL_SHELL_H_ + +#include "fsl_common.h" + +/*! + * @addtogroup SHELL + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/*! @brief Macro to set on/off history feature. */ +#ifndef SHELL_USE_HISTORY +#define SHELL_USE_HISTORY (0U) +#endif + +/*! @brief Macro to set on/off history feature. */ +#ifndef SHELL_SEARCH_IN_HIST +#define SHELL_SEARCH_IN_HIST (1U) +#endif + +/*! @brief Macro to select method stream. */ +#ifndef SHELL_USE_FILE_STREAM +#define SHELL_USE_FILE_STREAM (0U) +#endif + +/*! @brief Macro to set on/off auto-complete feature. */ +#ifndef SHELL_AUTO_COMPLETE +#define SHELL_AUTO_COMPLETE (1U) +#endif + +/*! @brief Macro to set console buffer size. */ +#ifndef SHELL_BUFFER_SIZE +#define SHELL_BUFFER_SIZE (64U) +#endif + +/*! @brief Macro to set maximum arguments in command. */ +#ifndef SHELL_MAX_ARGS +#define SHELL_MAX_ARGS (8U) +#endif + +/*! @brief Macro to set maximum count of history commands. */ +#ifndef SHELL_HIST_MAX +#define SHELL_HIST_MAX (3U) +#endif + +/*! @brief Macro to set maximum count of commands. */ +#ifndef SHELL_MAX_CMD +#define SHELL_MAX_CMD (20U) +#endif + +/*! @brief Macro to bypass arguments check */ +#define SHELL_OPTIONAL_PARAMS (0xFF) + +/*! @brief Shell user send data callback prototype.*/ +typedef void (*send_data_cb_t)(uint8_t *buf, uint32_t len); + +/*! @brief Shell user receiver data callback prototype.*/ +typedef void (*recv_data_cb_t)(uint8_t *buf, uint32_t len); + +/*! @brief Shell user printf data prototype.*/ +typedef int (*printf_data_t)(const char *format, ...); + +/*! @brief A type for the handle special key. */ +typedef enum _fun_key_status +{ + kSHELL_Normal = 0U, /*!< Normal key */ + kSHELL_Special = 1U, /*!< Special key */ + kSHELL_Function = 2U, /*!< Function key */ +} fun_key_status_t; + +/*! @brief Data structure for Shell environment. */ +typedef struct _shell_context_struct +{ + char *prompt; /*!< Prompt string */ + enum _fun_key_status stat; /*!< Special key status */ + char line[SHELL_BUFFER_SIZE]; /*!< Consult buffer */ + uint8_t cmd_num; /*!< Number of user commands */ + uint8_t l_pos; /*!< Total line position */ + uint8_t c_pos; /*!< Current line position */ +#if SHELL_USE_FILE_STREAM + FILE *STDOUT, *STDIN, *STDERR; +#else + send_data_cb_t send_data_func; /*!< Send data interface operation */ + recv_data_cb_t recv_data_func; /*!< Receive data interface operation */ + printf_data_t printf_data_func; +#endif + uint16_t hist_current; /*!< Current history command in hist buff*/ + uint16_t hist_count; /*!< Total history command in hist buff*/ + char hist_buf[SHELL_HIST_MAX][SHELL_BUFFER_SIZE]; /*!< History buffer*/ + bool exit; /*!< Exit Flag*/ +} shell_context_struct, *p_shell_context_t; + +/*! @brief User command function prototype. */ +typedef int32_t (*cmd_function_t)(p_shell_context_t context, int32_t argc, char **argv); + +/*! @brief User command data structure. */ +typedef struct _shell_command_context +{ + const char *pcCommand; /*!< The command that is executed. For example "help". It must be all lower case. */ + char *pcHelpString; /*!< String that describes how to use the command. It should start with the command itself, + and end with "\r\n". For example "help: Returns a list of all the commands\r\n". */ + const cmd_function_t + pFuncCallBack; /*!< A pointer to the callback function that returns the output generated by the command. */ + uint8_t cExpectedNumberOfParameters; /*!< Commands expect a fixed number of parameters, which may be zero. */ +} shell_command_context_t; + +/*! @brief Structure list command. */ +typedef struct _shell_command_context_list +{ + const shell_command_context_t *CommandList[SHELL_MAX_CMD]; /*!< The command table list */ + uint8_t numberOfCommandInList; /*!< The total command in list */ +} shell_command_context_list_t; + +/******************************************************************************* + * API + ******************************************************************************/ + +#if defined(__cplusplus) +extern "C" { +#endif /* _cplusplus */ + +/*! + * @name Shell functional operation + * @{ + */ + +/*! +* @brief Enables the clock gate and configures the Shell module according to the configuration structure. +* +* This function must be called before calling all other Shell functions. +* Call operation the Shell commands with user-defined settings. +* The example below shows how to set up the middleware Shell and +* how to call the SHELL_Init function by passing in these parameters. +* This is an example. +* @code +* shell_context_struct user_context; +* SHELL_Init(&user_context, SendDataFunc, ReceiveDataFunc, "SHELL>> "); +* @endcode +* @param context The pointer to the Shell environment and runtime states. +* @param send_cb The pointer to call back send data function. +* @param recv_cb The pointer to call back receive data function. +* @param prompt The string prompt of Shell +*/ +void SHELL_Init(p_shell_context_t context, + send_data_cb_t send_cb, + recv_data_cb_t recv_cb, + printf_data_t shell_printf, + char *prompt); + +/*! + * @brief Shell register command. + * @param command_context The pointer to the command data structure. + * @return -1 if error or 0 if success + */ +int32_t SHELL_RegisterCommand(const shell_command_context_t *command_context); + +/*! + * @brief Main loop for Shell. + * Main loop for Shell; After this function is called, Shell begins to initialize the basic variables and starts to + * work. + * @param context The pointer to the Shell environment and runtime states. + * @return This function does not return until Shell command exit was called. + */ +int32_t SHELL_Main(p_shell_context_t context); + +/* @} */ + +#if defined(__cplusplus) +} +#endif + +/*! @}*/ + +#endif /* _FSL_SHELL_H_ */ diff --git a/platform/mcu/lpc54102/utilities/io/fsl_io.c b/platform/mcu/lpc54102/utilities/io/fsl_io.c new file mode 100644 index 0000000000..49e6224901 --- /dev/null +++ b/platform/mcu/lpc54102/utilities/io/fsl_io.c @@ -0,0 +1,761 @@ +/* + * Copyright 2017 NXP + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of Freescale Semiconductor, Inc. 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 EPRESS 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, EEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +#include "fsl_io.h" +#include "fsl_debug_console_conf.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/* check avaliable device */ +#if (defined(FSL_FEATURE_SOC_UART_COUNT) && (FSL_FEATURE_SOC_UART_COUNT != 0)) +#define DEBUG_CONSOLE_IO_UART +#endif + +#if (defined(FSL_FEATURE_SOC_IUART_COUNT) && (FSL_FEATURE_SOC_IUART_COUNT != 0)) +#define DEBUG_CONSOLE_IO_IUART +#endif + +#if (defined(FSL_FEATURE_SOC_LPUART_COUNT) && (FSL_FEATURE_SOC_LPUART_COUNT != 0)) +#define DEBUG_CONSOLE_IO_LPUART +#endif + +#if (defined(FSL_FEATURE_SOC_LPSCI_COUNT) && (FSL_FEATURE_SOC_LPSCI_COUNT != 0)) +#define DEBUG_CONSOLE_IO_LPSCI +#endif + +#if ((defined(FSL_FEATURE_SOC_USB_COUNT) && (FSL_FEATURE_SOC_USB_COUNT != 0)) && defined(BOARD_USE_VIRTUALCOM)) +#define DEBUG_CONSOLE_IO_USBCDC +#endif + +#if (defined(FSL_FEATURE_SOC_FLEXCOMM_COUNT) && (FSL_FEATURE_SOC_FLEXCOMM_COUNT != 0)) +#define DEBUG_CONSOLE_IO_FLEXCOMM +#endif + +#if (defined(FSL_FEATURE_SOC_VFIFO_COUNT) && (FSL_FEATURE_SOC_VFIFO_COUNT != 0)) +#define DEBUG_CONSOLE_IO_VUSART +#endif + +/* configuration for debug console device */ +/* If new device is required as the low level device for debug console, + * Add the #elif branch and add the preprocessor macro to judge whether + * this kind of device exist in this SOC. */ +#if (defined DEBUG_CONSOLE_IO_UART) || (defined DEBUG_CONSOLE_IO_IUART) +#include "fsl_uart.h" +#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING +static uart_handle_t s_ioUartHandler; +#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */ +#endif /* defined DEBUG_CONSOLE_IO_UART) || (defined DEBUG_CONSOLE_IO_IUART */ + +#if defined DEBUG_CONSOLE_IO_LPUART +#include "fsl_lpuart.h" +#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING +static lpuart_handle_t s_ioLpuartHandler; +#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */ +#endif /* DEBUG_CONSOLE_IO_LPUART */ + +#if defined DEBUG_CONSOLE_IO_LPSCI +#include "fsl_lpsci.h" +#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING +static lpsci_handle_t s_ioLpsciHandler; +#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */ +#endif /* DEBUG_CONSOLE_IO_LPSCI */ + +#if defined DEBUG_CONSOLE_IO_USBCDC +#include "usb_device_config.h" +#include "usb.h" +#include "usb_device_cdc_acm.h" +#include "usb_device_ch9.h" +#include "virtual_com.h" +#endif /* DEBUG_CONSOLE_IO_USBCDC */ + +#if (defined DEBUG_CONSOLE_IO_FLEXCOMM) || (defined DEBUG_CONSOLE_IO_VUSART) +#include "fsl_usart.h" +#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING +static usart_handle_t s_ioUsartHandler; +#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */ +#endif /* defined DEBUG_CONSOLE_IO_FLEXCOMM) || (defined DEBUG_CONSOLE_IO_VUSART */ + +/******************************************************************************* + * Variables + ******************************************************************************/ + +/*! @brief Debug console IO state information. */ +static io_state_t s_debugConsoleIO = { + .ioBase = NULL, + .ioType = DEBUG_CONSOLE_DEVICE_TYPE_NONE, +#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING + .callBack = NULL, +#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */ +}; + +/******************************************************************************* + * Code + ******************************************************************************/ + +#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING + +#if (defined DEBUG_CONSOLE_IO_UART) || (defined DEBUG_CONSOLE_IO_IUART) +static void UART_Callback(UART_Type *base, uart_handle_t *handle, status_t status, void *userData) +{ + bool tx = false, rx = false; + size_t size = 0U; + + if (status == kStatus_UART_RxIdle) + { + rx = true; + size = handle->txDataSizeAll; + } + + if (status == kStatus_UART_TxIdle) + { + tx = true; + size = handle->txDataSizeAll; + } + + /* inform the buffer layer that transfer is complete */ + if (s_debugConsoleIO.callBack != NULL) + { + /* call buffer callback function */ + s_debugConsoleIO.callBack(&size, rx, tx); + } +} +#endif /* defined DEBUG_CONSOLE_IO_UART) || (defined DEBUG_CONSOLE_IO_IUART */ + +#if defined DEBUG_CONSOLE_IO_LPSCI +static void LPSCI_Callback(UART0_Type *base, lpsci_handle_t *handle, status_t status, void *userData) +{ + bool tx = false, rx = false; + size_t size = 0U; + + if (status == kStatus_LPSCI_RxIdle) + { + rx = true; + size = handle->txDataSizeAll; + } + + if (status == kStatus_LPSCI_TxIdle) + { + tx = true; + size = handle->txDataSizeAll; + } + + /* inform the buffer layer that transfer is complete */ + if (s_debugConsoleIO.callBack != NULL) + { + /* call buffer callback function */ + s_debugConsoleIO.callBack(&size, rx, tx); + } +} +#endif /* DEBUG_CONSOLE_IO_LPSCI */ + +#if defined DEBUG_CONSOLE_IO_LPUART +static void LPUART_Callback(LPUART_Type *base, lpuart_handle_t *handle, status_t status, void *userData) +{ + bool tx = false, rx = false; + size_t size = 0U; + + if (status == kStatus_LPUART_RxIdle) + { + rx = true; + size = handle->txDataSizeAll; + } + + if (status == kStatus_LPUART_TxIdle) + { + tx = true; + size = handle->txDataSizeAll; + } + + /* inform the buffer layer that transfer is complete */ + if (s_debugConsoleIO.callBack != NULL) + { + /* call buffer callback function */ + s_debugConsoleIO.callBack(&size, rx, tx); + } +} +#endif /* DEBUG_CONSOLE_IO_LPUART */ + +#if (defined DEBUG_CONSOLE_IO_FLEXCOMM) || (defined DEBUG_CONSOLE_IO_VUSART) +static void USART_Callback(USART_Type *base, usart_handle_t *handle, status_t status, void *userData) +{ + bool tx = false, rx = false; + size_t size = 0U; + + if (status == kStatus_USART_RxIdle) + { + rx = true; + size = handle->txDataSizeAll; + } + + if (status == kStatus_USART_TxIdle) + { + tx = true; + size = handle->txDataSizeAll; + } + + /* inform the buffer layer that transfer is complete */ + if (s_debugConsoleIO.callBack != NULL) + { + /* call buffer callback function */ + s_debugConsoleIO.callBack(&size, rx, tx); + } +} +#endif /* defined DEBUG_CONSOLE_IO_FLEXCOMM) || (defined DEBUG_CONSOLE_IO_VUSART */ +#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */ + +void IO_Init(io_state_t *io, uint32_t baudRate, uint32_t clkSrcFreq, uint8_t *ringBuffer) +{ + assert(NULL != io); + + /* record device type/base */ + s_debugConsoleIO.ioType = io->ioType; + s_debugConsoleIO.ioBase = (void *)(io->ioBase); + + switch (s_debugConsoleIO.ioType) + { +#if (defined DEBUG_CONSOLE_IO_UART) || (defined DEBUG_CONSOLE_IO_IUART) + case DEBUG_CONSOLE_DEVICE_TYPE_UART: + case DEBUG_CONSOLE_DEVICE_TYPE_IUART: + { + uart_config_t uart_config; + UART_GetDefaultConfig(&uart_config); + uart_config.baudRate_Bps = baudRate; + /* Enable clock and initial UART module follow user configure structure. */ + UART_Init((UART_Type *)s_debugConsoleIO.ioBase, &uart_config, clkSrcFreq); + UART_EnableTx(s_debugConsoleIO.ioBase, true); + UART_EnableRx(s_debugConsoleIO.ioBase, true); +#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING + s_debugConsoleIO.callBack = io->callBack; + /* create handler for interrupt transfer */ + UART_TransferCreateHandle(s_debugConsoleIO.ioBase, &s_ioUartHandler, UART_Callback, NULL); + /* start ring buffer */ + UART_TransferStartRingBuffer(s_debugConsoleIO.ioBase, &s_ioUartHandler, ringBuffer, + DEBUG_CONSOLE_RECEIVE_BUFFER_LEN); +#endif + } + break; +#endif + +#if defined DEBUG_CONSOLE_IO_LPUART + case DEBUG_CONSOLE_DEVICE_TYPE_LPUART: + { + lpuart_config_t lpuart_config; + LPUART_GetDefaultConfig(&lpuart_config); + lpuart_config.baudRate_Bps = baudRate; + /* Enable clock and initial UART module follow user configure structure. */ + LPUART_Init((LPUART_Type *)s_debugConsoleIO.ioBase, &lpuart_config, clkSrcFreq); + LPUART_EnableTx(s_debugConsoleIO.ioBase, true); + LPUART_EnableRx(s_debugConsoleIO.ioBase, true); +#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING + s_debugConsoleIO.callBack = io->callBack; + /* create handler for interrupt transfer */ + LPUART_TransferCreateHandle(s_debugConsoleIO.ioBase, &s_ioLpuartHandler, LPUART_Callback, NULL); + /* start ring buffer */ + LPUART_TransferStartRingBuffer(s_debugConsoleIO.ioBase, &s_ioLpuartHandler, ringBuffer, + DEBUG_CONSOLE_RECEIVE_BUFFER_LEN); +#endif + } + break; +#endif +#if defined DEBUG_CONSOLE_IO_LPSCI + case DEBUG_CONSOLE_DEVICE_TYPE_LPSCI: + { + lpsci_config_t lpsci_config; + LPSCI_GetDefaultConfig(&lpsci_config); + lpsci_config.baudRate_Bps = baudRate; + /* Enable clock and initial UART module follow user configure structure. */ + LPSCI_Init((UART0_Type *)s_debugConsoleIO.ioBase, &lpsci_config, clkSrcFreq); + LPSCI_EnableTx(s_debugConsoleIO.ioBase, true); + LPSCI_EnableRx(s_debugConsoleIO.ioBase, true); +#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING + s_debugConsoleIO.callBack = io->callBack; + /* create handler for interrupt transfer */ + LPSCI_TransferCreateHandle(s_debugConsoleIO.ioBase, &s_ioLpsciHandler, LPSCI_Callback, NULL); + /* start ring buffer */ + LPSCI_TransferStartRingBuffer(s_debugConsoleIO.ioBase, &s_ioLpsciHandler, ringBuffer, + DEBUG_CONSOLE_RECEIVE_BUFFER_LEN); +#endif + } + break; +#endif +#if defined DEBUG_CONSOLE_IO_USBCDC + case DEBUG_CONSOLE_DEVICE_TYPE_USBCDC: + { + s_debugConsoleIO.ioBase = USB_VcomInit(); + } + break; +#endif +#if defined DEBUG_CONSOLE_IO_FLEXCOMM + case DEBUG_CONSOLE_DEVICE_TYPE_FLEXCOMM: + { + usart_config_t usart_config; + USART_GetDefaultConfig(&usart_config); + usart_config.baudRate_Bps = baudRate; + /* Enable clock and initial UART module follow user configure structure. */ + USART_Init((USART_Type *)s_debugConsoleIO.ioBase, &usart_config, clkSrcFreq); +#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING + s_debugConsoleIO.callBack = io->callBack; + /* create handler for interrupt transfer */ + USART_TransferCreateHandle(s_debugConsoleIO.ioBase, &s_ioUsartHandler, USART_Callback, NULL); + /* start ring buffer */ + USART_TransferStartRingBuffer(s_debugConsoleIO.ioBase, &s_ioUsartHandler, ringBuffer, + DEBUG_CONSOLE_RECEIVE_BUFFER_LEN); +#endif + } + break; +#endif +#if defined DEBUG_CONSOLE_IO_VUSART + case DEBUG_CONSOLE_DEVICE_TYPE_VUSART: + { + usart_config_t usart_config; + USART_GetDefaultConfig(&usart_config); + usart_config.baudRate_Bps = baudRate; + usart_config.enableRx = true; + usart_config.enableTx = true; + /* Enable rx fifo for user's continously input */ + usart_config.fifoConfig.enableRxFifo = true; + usart_config.fifoConfig.rxFifoSize = 8; + /* Enable clock and initial UART module follow user configure structure. */ + USART_Init((USART_Type *)s_debugConsoleIO.ioBase, &usart_config, clkSrcFreq); +#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING + s_debugConsoleIO.callBack = io->callBack; + /* create handler for interrupt transfer */ + USART_TransferCreateHandle(s_debugConsoleIO.ioBase, &s_ioUsartHandler, USART_Callback, NULL); + /* start ring buffer */ + USART_TransferStartRingBuffer(s_debugConsoleIO.ioBase, &s_ioUsartHandler, ringBuffer, + DEBUG_CONSOLE_RECEIVE_BUFFER_LEN); +#endif + } + break; +#endif + } +} + +status_t IO_Deinit(void) +{ + if (s_debugConsoleIO.ioType == DEBUG_CONSOLE_DEVICE_TYPE_NONE) + { + return kStatus_Success; + } + + switch (s_debugConsoleIO.ioType) + { +#if (defined DEBUG_CONSOLE_IO_UART) || (defined DEBUG_CONSOLE_IO_IUART) + case DEBUG_CONSOLE_DEVICE_TYPE_UART: + case DEBUG_CONSOLE_DEVICE_TYPE_IUART: +#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING + /* stop ring buffer */ + UART_TransferStopRingBuffer(s_debugConsoleIO.ioBase, &s_ioUartHandler); +#endif + /* Disable UART module. */ + UART_Deinit((UART_Type *)s_debugConsoleIO.ioBase); + + break; +#endif +#if defined DEBUG_CONSOLE_IO_LPSCI + case DEBUG_CONSOLE_DEVICE_TYPE_LPSCI: +#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING + /* stop ring buffer */ + LPSCI_TransferStopRingBuffer(s_debugConsoleIO.ioBase, &s_ioLpsciHandler); +#endif + /* Disable LPSCI module. */ + LPSCI_Deinit((UART0_Type *)s_debugConsoleIO.ioBase); + + break; +#endif +#if defined DEBUG_CONSOLE_IO_LPUART + case DEBUG_CONSOLE_DEVICE_TYPE_LPUART: +#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING + /* stop ring buffer */ + LPUART_TransferStopRingBuffer(s_debugConsoleIO.ioBase, &s_ioLpuartHandler); +#endif + /* Disable LPUART module. */ + LPUART_Deinit((LPUART_Type *)s_debugConsoleIO.ioBase); + + break; +#endif +#if defined DEBUG_CONSOLE_IO_USBCDC + case DEBUG_CONSOLE_DEVICE_TYPE_USBCDC: + /* Disable USBCDC module. */ + USB_VcomDeinit(s_debugConsoleIO.ioBase); + break; +#endif +#if (defined DEBUG_CONSOLE_IO_FLEXCOMM) || (defined DEBUG_CONSOLE_IO_VUSART) + case DEBUG_CONSOLE_DEVICE_TYPE_FLEXCOMM: + case DEBUG_CONSOLE_DEVICE_TYPE_VUSART: +#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING + /* stop ring buffer */ + USART_TransferStopRingBuffer(s_debugConsoleIO.ioBase, &s_ioUsartHandler); +#endif + /* deinit IO */ + USART_Deinit((USART_Type *)s_debugConsoleIO.ioBase); + + break; +#endif + default: + s_debugConsoleIO.ioType = DEBUG_CONSOLE_DEVICE_TYPE_NONE; + break; + } + + s_debugConsoleIO.ioType = DEBUG_CONSOLE_DEVICE_TYPE_NONE; + + return kStatus_Success; +} + +status_t IO_WaitIdle(void) +{ + switch (s_debugConsoleIO.ioType) + { +#if (defined DEBUG_CONSOLE_IO_UART) + case DEBUG_CONSOLE_DEVICE_TYPE_UART: + /* wait transfer complete flag */ + while (!(UART_GetStatusFlags(s_debugConsoleIO.ioBase) & kUART_TransmissionCompleteFlag)) + ; + break; +#endif + +#if (defined DEBUG_CONSOLE_IO_IUART) + case DEBUG_CONSOLE_DEVICE_TYPE_IUART: + /* wait transfer complete flag */ + while (!(UART_GetStatusFlag(s_debugConsoleIO.ioBase, kUART_TxCompleteFlag))) + ; + break; +#endif + +#if defined DEBUG_CONSOLE_IO_LPSCI + case DEBUG_CONSOLE_DEVICE_TYPE_LPSCI: + /* wait transfer complete flag */ + while (!(LPSCI_GetStatusFlags(s_debugConsoleIO.ioBase) & kLPSCI_TransmissionCompleteFlag)) + ; + break; +#endif + +#if defined DEBUG_CONSOLE_IO_LPUART + case DEBUG_CONSOLE_DEVICE_TYPE_LPUART: + /* wait transfer complete flag */ + while (!(LPUART_GetStatusFlags(s_debugConsoleIO.ioBase) & kLPUART_TransmissionCompleteFlag)) + ; + break; +#endif + +#if (defined DEBUG_CONSOLE_IO_FLEXCOMM) || (defined DEBUG_CONSOLE_IO_VUSART) + case DEBUG_CONSOLE_DEVICE_TYPE_FLEXCOMM: + case DEBUG_CONSOLE_DEVICE_TYPE_VUSART: + /* wait transfer complete flag */ + while (!(USART_GetStatusFlags(s_debugConsoleIO.ioBase) & kUSART_TxFifoEmptyFlag)) + ; + break; +#endif + default: + break; + } + + return kStatus_Success; +} + +#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING + +status_t IO_Transfer(uint8_t *ch, size_t size, bool tx) +{ + status_t status = kStatus_Fail; + + switch (s_debugConsoleIO.ioType) + { +#if (defined DEBUG_CONSOLE_IO_UART) || (defined DEBUG_CONSOLE_IO_IUART) + case DEBUG_CONSOLE_DEVICE_TYPE_UART: + case DEBUG_CONSOLE_DEVICE_TYPE_IUART: + { + uart_transfer_t transfer = {0U}; + transfer.data = ch; + transfer.dataSize = size; + /* transfer data */ + if (tx) + { + status = UART_TransferSendNonBlocking(s_debugConsoleIO.ioBase, &s_ioUartHandler, &transfer); + } + else + { + status = UART_TransferReceiveNonBlocking(s_debugConsoleIO.ioBase, &s_ioUartHandler, &transfer, NULL); + } + } + break; +#endif +#if defined DEBUG_CONSOLE_IO_LPSCI + case DEBUG_CONSOLE_DEVICE_TYPE_LPSCI: + { + lpsci_transfer_t transfer = {0U}; + transfer.data = ch; + transfer.dataSize = size; + /* transfer data */ + if (tx) + { + status = LPSCI_TransferSendNonBlocking(s_debugConsoleIO.ioBase, &s_ioLpsciHandler, &transfer); + } + else + { + status = LPSCI_TransferReceiveNonBlocking(s_debugConsoleIO.ioBase, &s_ioLpsciHandler, &transfer, NULL); + } + } + break; +#endif + +#if defined DEBUG_CONSOLE_IO_LPUART + case DEBUG_CONSOLE_DEVICE_TYPE_LPUART: + { + lpuart_transfer_t transfer = {0U}; + transfer.data = ch; + transfer.dataSize = size; + /* transfer data */ + if (tx) + { + status = LPUART_TransferSendNonBlocking(s_debugConsoleIO.ioBase, &s_ioLpuartHandler, &transfer); + } + else + { + status = + LPUART_TransferReceiveNonBlocking(s_debugConsoleIO.ioBase, &s_ioLpuartHandler, &transfer, NULL); + } + } + break; +#endif + +#if defined DEBUG_CONSOLE_IO_USBCDC + case DEBUG_CONSOLE_DEVICE_TYPE_USBCDC: + { + if (tx) + { + USB_VcomWriteBlocking(s_debugConsoleIO.ioBase, ch, size); + } + else + { + USB_VcomReadBlocking(s_debugConsoleIO.ioBase, ch, size); + } + } + break; +#endif + +#if (defined DEBUG_CONSOLE_IO_FLEXCOMM) || (defined DEBUG_CONSOLE_IO_VUSART) + case DEBUG_CONSOLE_DEVICE_TYPE_FLEXCOMM: + case DEBUG_CONSOLE_DEVICE_TYPE_VUSART: + { + usart_transfer_t transfer = {0U}; + transfer.data = ch; + transfer.dataSize = size; + /* transfer data */ + if (tx) + { + status = USART_TransferSendNonBlocking(s_debugConsoleIO.ioBase, &s_ioUsartHandler, &transfer); + } + else + { + status = USART_TransferReceiveNonBlocking(s_debugConsoleIO.ioBase, &s_ioUsartHandler, &transfer, NULL); + } + } + break; +#endif + default: + break; + } + + return status; +} + +status_t IO_TryReceiveCharacter(uint8_t *ch) +{ + status_t status = kStatus_Fail; + uint32_t size = 1U; + + switch (s_debugConsoleIO.ioType) + { +#if (defined DEBUG_CONSOLE_IO_UART) || (defined DEBUG_CONSOLE_IO_IUART) + case DEBUG_CONSOLE_DEVICE_TYPE_UART: + case DEBUG_CONSOLE_DEVICE_TYPE_IUART: + { + uart_transfer_t transfer = {0U}; + transfer.data = ch; + transfer.dataSize = size; + if (UART_TransferGetRxRingBufferLength(&s_ioUartHandler) >= size) + { + /* transfer data */ + status = UART_TransferReceiveNonBlocking(s_debugConsoleIO.ioBase, &s_ioUartHandler, &transfer, NULL); + } + } + break; +#endif +#if defined DEBUG_CONSOLE_IO_LPSCI + case DEBUG_CONSOLE_DEVICE_TYPE_LPSCI: + { + lpsci_transfer_t transfer = {0U}; + transfer.data = ch; + transfer.dataSize = size; + if (LPSCI_TransferGetRxRingBufferLength(&s_ioLpsciHandler) >= size) + { + /* transfer data */ + status = LPSCI_TransferReceiveNonBlocking(s_debugConsoleIO.ioBase, &s_ioLpsciHandler, &transfer, NULL); + } + } + break; +#endif + +#if defined DEBUG_CONSOLE_IO_LPUART + case DEBUG_CONSOLE_DEVICE_TYPE_LPUART: + { + lpuart_transfer_t transfer = {0U}; + transfer.data = ch; + transfer.dataSize = size; + if (LPUART_TransferGetRxRingBufferLength(s_debugConsoleIO.ioBase, &s_ioLpuartHandler) >= size) + { + /* transfer data */ + status = + LPUART_TransferReceiveNonBlocking(s_debugConsoleIO.ioBase, &s_ioLpuartHandler, &transfer, NULL); + } + } + break; +#endif + +#if defined DEBUG_CONSOLE_IO_USBCDC + case DEBUG_CONSOLE_DEVICE_TYPE_USBCDC: + break; +#endif + +#if (defined DEBUG_CONSOLE_IO_FLEXCOMM) || (defined DEBUG_CONSOLE_IO_VUSART) + case DEBUG_CONSOLE_DEVICE_TYPE_FLEXCOMM: + case DEBUG_CONSOLE_DEVICE_TYPE_VUSART: + { + usart_transfer_t transfer = {0U}; + transfer.data = ch; + transfer.dataSize = size; + if (USART_TransferGetRxRingBufferLength(&s_ioUsartHandler) >= size) + { + /* transfer data */ + status = USART_TransferReceiveNonBlocking(s_debugConsoleIO.ioBase, &s_ioUsartHandler, &transfer, NULL); + } + } + break; +#endif + default: + break; + } + + return status; +} + +#else + +status_t IO_Transfer(uint8_t *ch, size_t size, bool tx) +{ + status_t status = kStatus_Success; + switch (s_debugConsoleIO.ioType) + { +#if (defined DEBUG_CONSOLE_IO_UART) || (defined DEBUG_CONSOLE_IO_IUART) + case DEBUG_CONSOLE_DEVICE_TYPE_UART: + case DEBUG_CONSOLE_DEVICE_TYPE_IUART: + { + if (tx) + { + UART_WriteBlocking(s_debugConsoleIO.ioBase, ch, size); + } + else + { + status = UART_ReadBlocking(s_debugConsoleIO.ioBase, ch, size); + } + } + break; +#endif +#if defined DEBUG_CONSOLE_IO_LPSCI + case DEBUG_CONSOLE_DEVICE_TYPE_LPSCI: + { + if (tx) + { + LPSCI_WriteBlocking(s_debugConsoleIO.ioBase, ch, size); + } + else + { + status = LPSCI_ReadBlocking(s_debugConsoleIO.ioBase, ch, size); + } + } + break; +#endif + +#if defined DEBUG_CONSOLE_IO_LPUART + case DEBUG_CONSOLE_DEVICE_TYPE_LPUART: + { + if (tx) + { + LPUART_WriteBlocking(s_debugConsoleIO.ioBase, ch, size); + } + else + { + status = LPUART_ReadBlocking(s_debugConsoleIO.ioBase, ch, size); + } + } + break; +#endif + +#if defined DEBUG_CONSOLE_IO_USBCDC + case DEBUG_CONSOLE_DEVICE_TYPE_USBCDC: + { + if (tx) + { + USB_VcomWriteBlocking(s_debugConsoleIO.ioBase, ch, size); + } + else + { + status = USB_VcomReadBlocking(s_debugConsoleIO.ioBase, ch, size); + } + } + break; +#endif + +#if (defined DEBUG_CONSOLE_IO_FLEXCOMM) || (defined DEBUG_CONSOLE_IO_VUSART) + case DEBUG_CONSOLE_DEVICE_TYPE_FLEXCOMM: + case DEBUG_CONSOLE_DEVICE_TYPE_VUSART: + { + if (tx) + { + USART_WriteBlocking(s_debugConsoleIO.ioBase, ch, size); + } + else + { + status = USART_ReadBlocking(s_debugConsoleIO.ioBase, ch, size); + } + } + break; +#endif + default: + status = kStatus_Fail; + break; + } + + return status; +} + +#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */ diff --git a/platform/mcu/lpc54102/utilities/io/fsl_io.h b/platform/mcu/lpc54102/utilities/io/fsl_io.h new file mode 100644 index 0000000000..c1243b244f --- /dev/null +++ b/platform/mcu/lpc54102/utilities/io/fsl_io.h @@ -0,0 +1,136 @@ +/* + * Copyright 2017 NXP + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of Freescale Semiconductor, Inc. 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 _FSL_IO_H +#define _FSL_IO_H + +#include "fsl_common.h" + +/*! + * @addtogroup debugconsole + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ +/*! @brief define a notify callback for IO +* @param size , transfer data size. +* @param rx, indicate a rx transfer is success. +* @param tx, indicate a tx transfer is success. +*/ +typedef void (*notify)(size_t *size, bool rx, bool tx); + +/*! @brief State structure storing io. */ +typedef struct io_State +{ + void *ioBase; /*!< Base of the IP register. */ + uint8_t ioType; /*!< device type */ +#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING + notify callBack; /*!< define the callback function for buffer */ +#endif + +} io_state_t; + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + +/*! + * @brief io init function. + * + * Call this function to init IO. + * + * @param io configuration pointer + * @param baudRate baud rate + * @param clkSrcFreq clock freq + * @param ringbuffer used to receive character + */ +void IO_Init(io_state_t *io, uint32_t baudRate, uint32_t clkSrcFreq, uint8_t *ringBuffer); + +/*! + * @brief Deinit IO. + * + * Call this function to Deinit IO. + * + * @return deinit status + */ +status_t IO_Deinit(void); + +/*! + * @brief io transfer function. + * + * Call this function to transfer log. + * Print log: + * @code + * IO_Transfer(ch, size, true); + * @endcode + * Scanf log: + * @code + * IO_Transfer(ch, size, false); + * @endcode + * + * @param ch transfer buffer pointer + * @param size transfer size + * @param tx indicate the transfer is TX or RX + */ +status_t IO_Transfer(uint8_t *ch, size_t size, bool tx); + +/*! + * @brief io wait idle. + * + * Call this function to wait the io idle + * + * @return Indicates whether wait idle was successful or not. + */ +status_t IO_WaitIdle(void); + +#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING +/*! + * @brief io try to receive one character. + * + * Call this function try to receive character + * @param ch the address of char to receive + * @return Indicates try getchar was successful or not. + */ +status_t IO_TryReceiveCharacter(uint8_t *ch); +#endif + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + +/*! @} */ + +#endif /* _FSL_IO_H */ diff --git a/platform/mcu/lpc54102/utilities/log/fsl_log.c b/platform/mcu/lpc54102/utilities/log/fsl_log.c new file mode 100644 index 0000000000..bd47ee7341 --- /dev/null +++ b/platform/mcu/lpc54102/utilities/log/fsl_log.c @@ -0,0 +1,583 @@ +/* + * Copyright 2017 NXP + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of Freescale Semiconductor, Inc. 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 EPRESS 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, EEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +#include "fsl_log.h" +#include "fsl_debug_console_conf.h" +#include "fsl_io.h" +#ifdef FSL_RTOS_FREE_RTOS +#include "FreeRTOS.h" +#include "task.h" +#include "semphr.h" +#endif +/******************************************************************************* + * Definitions + ******************************************************************************/ +#ifndef BACKSPACE +/*! @brief character backspace ASCII value */ +#define BACKSPACE 127 +#endif + +#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING +/*! @brief increase pop member */ +#define LOG_CHECK_BUFFER_INDEX_OVERFLOW(index) \ + { \ + if (index >= DEBUG_CONSOLE_TRANSMIT_BUFFER_LEN) \ + { \ + index -= DEBUG_CONSOLE_TRANSMIT_BUFFER_LEN; \ + } \ + \ +\ +} + +/*! @brief get current runing environment is ISR or not */ +#ifdef __CA7_REV +#define IS_RUNNING_IN_ISR() SystemGetIRQNestingLevel() +#else +#define IS_RUNNING_IN_ISR() __get_IPSR() +#endif /* __CA7_REV */ + +#else +#define IS_RUNNING_IN_ISR() (0U) +#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */ + +/* define for rtos */ +#if (DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_FREERTOS) +/* metex semaphore */ +#define LOG_CREATE_MUTEX_SEMAPHORE(mutex) (mutex = xSemaphoreCreateMutex()) + +#define LOG_GIVE_MUTEX_SEMAPHORE(mutex) \ + \ +{ \ + if (IS_RUNNING_IN_ISR() == 0U) \ + { \ + xSemaphoreGive(mutex); \ + } \ + \ +} + +#define LOG_TAKE_MUTEX_SEMAPHORE_BLOCKING(mutex) \ + \ +{ \ + if (IS_RUNNING_IN_ISR() == 0U) \ + { \ + xSemaphoreTake(mutex, portMAX_DELAY); \ + } \ + \ +} + +#define LOG_TAKE_MUTEX_SEMAPHORE_NONBLOCKING(mutex, result) \ + \ +{ \ + if (IS_RUNNING_IN_ISR() == 0U) \ + { \ + result = xSemaphoreTake(mutex, 0U); \ + } \ + else \ + { \ + result = 1U; \ + } \ + \ +} + +/* Binary semaphore */ +#define LOG_CREATE_BINARY_SEMAPHORE(binary) (binary = xSemaphoreCreateBinary()) +#define LOG_TAKE_BINARY_SEMAPHORE_BLOCKING(binary) (xSemaphoreTake(binary, portMAX_DELAY)) +#define LOG_GIVE_BINARY_SEMAPHORE_FROM_ISR(binary) (xSemaphoreGiveFromISR(binary, NULL)) + +#elif(DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_BM) + +#define LOG_CREATE_MUTEX_SEMAPHORE(mutex) +#define LOG_TAKE_MUTEX_SEMAPHORE_BLOCKING(mutex) +#define LOG_GIVE_MUTEX_SEMAPHORE(mutex) +#define LOG_CREATE_BINARY_SEMAPHORE(binary) +#define LOG_TAKE_MUTEX_SEMAPHORE_NONBLOCKING(mutex, result) (result = 1U) +#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING +#define LOG_TAKE_BINARY_SEMAPHORE_BLOCKING(binary) \ + \ +{ \ + while (!binary) \ + ; \ + binary = false; \ + \ +\ +} +#define LOG_GIVE_BINARY_SEMAPHORE_FROM_ISR(binary) (binary = true) +#else +#define LOG_TAKE_BINARY_SEMAPHORE_BLOCKING(binary) +#define LOG_GIVE_BINARY_SEMAPHORE_FROM_ISR(binary) +#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */ + +/* add other implementation here +*such as : +* #elif(DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_xxx) +*/ + +#else + +#define LOG_CREATE_MUTEX_SEMAPHORE(mutex) +#define LOG_TAKE_MUTEX_SEMAPHORE_BLOCKING(mutex) +#define LOG_TAKE_MUTEX_SEMAPHORE_NONBLOCKING(mutex, result) (result = 1U) +#define LOG_GIVE_MUTEX_SEMAPHORE(mutex) +#define LOG_CREATE_BINARY_SEMAPHORE(binary) +#define LOG_TAKE_BINARY_SEMAPHORE_BLOCKING(binary) +#endif /* DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_FREERTOS */ + +#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING +/*! @brief Define the buffer +* The total buffer size should be calucate as (BUFFER_SUPPORT_LOG_LENGTH + 1) * BUFFER_SUPPORT_LOG_NUM * 4 +*/ +typedef struct _log_buffer +{ + volatile uint16_t totalIndex; /*!< indicate the total usage of the buffer */ + volatile uint16_t pushIndex; /*!< indicate the next push index */ + volatile uint16_t popIndex; /*!< indicate the pop index */ + uint8_t txBuf[DEBUG_CONSOLE_TRANSMIT_BUFFER_LEN]; /*!< buffer to store printf log */ + + uint8_t rxBuf[DEBUG_CONSOLE_RECEIVE_BUFFER_LEN]; /*!< buffer to store scanf log */ +} log_buffer_t; +#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */ + +/******************************************************************************* + * Variables + ******************************************************************************/ +#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING +/* A global log buffer */ +static log_buffer_t s_log_buffer; +#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */ + +/* lock definition */ +#if (DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_FREERTOS) +#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING +static SemaphoreHandle_t s_logPushSemaphore = NULL; +static SemaphoreHandle_t s_logReadSemaphore = NULL; +#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */ +static SemaphoreHandle_t s_logPopSemaphore = NULL; +static SemaphoreHandle_t s_logReadWaitSemaphore = NULL; + +#elif(DEBUG_CONSOLE_SYNCHRONIZATION_MODE == DEBUG_CONSOLE_SYNCHRONIZATION_BM) + +#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING + +static volatile bool s_logReadWaitSemaphore = false; /* transferred event from ISR for bare-metal + interrupt */ + +#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */ + +#else +#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */ + +/******************************************************************************* +* Prototypes +******************************************************************************/ +#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING +/*! + * @brief callback function for IO layer to notify LOG + * + * @param size last transfer data size + * @param receive indicate a RX transfer + * @param transmit indicate a TX transfer + * + */ +static void LOG_Transferred(size_t *size, bool receive, bool transmit); + +/*! + * @brief log push function + * + * @param buf target buffer + * @param size log size + * + */ +static int LOG_BufPush(uint8_t *buf, size_t size); + +/*! + * @brief Get next avaliable log + * + * @param next avaliable size + * @return next avaliable address + */ +static uint8_t *LOG_BufGetNextAvaliableLog(size_t *size); + +/*! + * @brief buf pop + * + * @param size log size popped and next available log size + * @return next avaliable address + */ +static uint8_t *LOG_BufPop(size_t *size); + +#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */ + +/*! + * @brief read one character + * + * @param ch character address + * @return indicate the read status + * + */ +static status_t LOG_ReadOneCharacter(uint8_t *ch); + +#if DEBUG_CONSOLE_ENABLE_ECHO_FUNCTION +/*! + * @brief echo one character + * + * @param ch character address + * @param isGetchar flag to distinguish getchar from scanf + * @param index special for scanf to support backspace + * @return indicate the read status + * + */ +static status_t LOG_EchoCharacter(uint8_t *ch, bool isGetChar, int *index); +#endif + +/******************************************************************************* + * Code + ******************************************************************************/ +status_t LOG_Init(uint32_t baseAddr, uint8_t device, uint32_t baudRate, uint32_t clkSrcFreq) +{ + io_state_t io; + /* init io */ + io.ioBase = (void *)baseAddr; + io.ioType = device; + +#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING + /* memset the global queue */ + memset(&s_log_buffer, 0U, sizeof(s_log_buffer)); + /* init callback for NON-BLOCKING */ + io.callBack = LOG_Transferred; + /* io init function */ + IO_Init(&io, baudRate, clkSrcFreq, s_log_buffer.rxBuf); + /* Debug console buffer push lock create */ + LOG_CREATE_MUTEX_SEMAPHORE(s_logPushSemaphore); + /* Debug console get/scanf mutex lock create */ + LOG_CREATE_MUTEX_SEMAPHORE(s_logReadSemaphore); +#else + IO_Init(&io, baudRate, clkSrcFreq, NULL); +#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */ + + /* Debug console lock create */ + LOG_CREATE_MUTEX_SEMAPHORE(s_logPopSemaphore); + LOG_CREATE_BINARY_SEMAPHORE(s_logReadWaitSemaphore); + + return kStatus_Success; +} + +void LOG_Deinit(void) +{ +#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING + /* memset the global queue */ + memset(&s_log_buffer, 0U, sizeof(s_log_buffer)); +#endif /*DEBUG_CONSOLE_TRANSFER_NON_BLOCKING*/ + /* Deinit IO */ + IO_Deinit(); +} + +status_t LOG_WaitIdle(void) +{ +#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING + /* wait buffer empty */ + while (!(s_log_buffer.totalIndex == 0U)) + ; +#endif /*DEBUG_CONSOLE_TRANSFER_NON_BLOCKING*/ + /* wait IO idle */ + IO_WaitIdle(); + + return kStatus_Success; +} + +int LOG_Push(uint8_t *buf, size_t size) +{ + assert(buf != NULL); + +#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING + /* push to buffer */ + LOG_BufPush(buf, size); + buf = LOG_BufGetNextAvaliableLog(&size); +#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */ + /* pop log */ + return LOG_Pop(buf, size); +} + +int LOG_Pop(uint8_t *buf, size_t size) +{ + uint8_t getLock = 0U; + + if ((0 != size) && (NULL != buf)) + { + /* take POP lock, should be non-blocking */ + LOG_TAKE_MUTEX_SEMAPHORE_NONBLOCKING(s_logPopSemaphore, getLock); + + if (getLock) + { + /* call IO transfer function */ + if (IO_Transfer(buf, size, true) != kStatus_Success) + { + size = 0U; + } + /* release POP lock */ + LOG_GIVE_MUTEX_SEMAPHORE(s_logPopSemaphore); + } + } + + return size; +} + +int LOG_ReadLine(uint8_t *buf, size_t size) +{ + assert(buf != NULL); + + int i = 0; + + /* take mutex lock function */ + LOG_TAKE_MUTEX_SEMAPHORE_BLOCKING(s_logReadSemaphore); + + for (i = 0; i < size; i++) + { + /* recieve one char every time */ + if (LOG_ReadOneCharacter(&buf[i]) != kStatus_Success) + { + return -1; + } +#if DEBUG_CONSOLE_ENABLE_ECHO_FUNCTION + LOG_EchoCharacter(&buf[i], false, &i); +#endif + /* analysis data */ + if ((buf[i] == '\r') || (buf[i] == '\n')) + { + /* End of Line. */ + if (i == 0) + { + buf[i] = '\0'; + i = -1; + } + else + { + break; + } + } + } + /* get char should not add '\0'*/ + if (i == size) + { + buf[i] = '\0'; + } + else + { + buf[i + 1] = '\0'; + } + + /* release mutex lock function */ + LOG_GIVE_MUTEX_SEMAPHORE(s_logReadSemaphore); + + return i; +} + +int LOG_ReadCharacter(uint8_t *ch) +{ + assert(ch != NULL); + int ret = 0; + + /* take mutex lock function */ + LOG_TAKE_MUTEX_SEMAPHORE_BLOCKING(s_logReadSemaphore); + /* read one character */ + if (LOG_ReadOneCharacter(ch) == kStatus_Success) + { + ret = 1; +#if DEBUG_CONSOLE_ENABLE_ECHO_FUNCTION + LOG_EchoCharacter(ch, true, NULL); +#endif + } + else + { + ret = -1; + } + + /* release mutex lock function */ + LOG_GIVE_MUTEX_SEMAPHORE(s_logReadSemaphore); + + return ret; +} + +static status_t LOG_ReadOneCharacter(uint8_t *ch) +{ + /* recieve one char every time */ + if (IO_Transfer(ch, 1U, false) != kStatus_Success) + { + return kStatus_Fail; + } + + /* wait release from ISR */ + LOG_TAKE_BINARY_SEMAPHORE_BLOCKING(s_logReadWaitSemaphore); + + return kStatus_Success; +} + +#if DEBUG_CONSOLE_ENABLE_ECHO_FUNCTION +static status_t LOG_EchoCharacter(uint8_t *ch, bool isGetChar, int *index) +{ + /* Due to scanf take \n and \r as end of string,should not echo */ + if (((*ch != '\r') && (*ch != '\n')) || (isGetChar)) + { + /* recieve one char every time */ + if (IO_Transfer(ch, 1U, true) != kStatus_Success) + { + return kStatus_Fail; + } + } + + if (!isGetChar) + { + if ((*index > 0) && (*ch == BACKSPACE)) + { + *index -= 2; + } + } + + return kStatus_Success; +} +#endif + +#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING +static int LOG_BufPush(uint8_t *buf, size_t size) +{ + uint32_t pushIndex = 0U, i = 0U; + bool pushAvaliable = false; + + /* take mutex lock function */ + LOG_TAKE_MUTEX_SEMAPHORE_BLOCKING(s_logPushSemaphore); + if (size <= (DEBUG_CONSOLE_TRANSMIT_BUFFER_LEN - s_log_buffer.totalIndex)) + { + /* get push index */ + pushIndex = s_log_buffer.pushIndex; + s_log_buffer.pushIndex += size; + /* check index overflow */ + LOG_CHECK_BUFFER_INDEX_OVERFLOW(s_log_buffer.pushIndex); + /* update push/total index value */ + s_log_buffer.totalIndex += size; + pushAvaliable = true; + } + /* release mutex lock function */ + LOG_GIVE_MUTEX_SEMAPHORE(s_logPushSemaphore); + + /* check the buffer if have enough space to store the log */ + if (pushAvaliable) + { + for (i = size; i > 0; i--) + { + /* copy log to buffer, the buffer only support a fixed length argument, if the log argument + is longer than the fixed length, the left argument will be losed */ + s_log_buffer.txBuf[pushIndex] = *buf++; + /* increase index */ + pushIndex++; + /* check index overflow */ + LOG_CHECK_BUFFER_INDEX_OVERFLOW(pushIndex); + } + } + else + { + size = 0U; + } + + return size; +} + +static uint8_t *LOG_BufGetNextAvaliableLog(size_t *size) +{ + uint16_t popIndex = s_log_buffer.popIndex; + + /* get avaliable size */ + if (s_log_buffer.totalIndex > (DEBUG_CONSOLE_TRANSMIT_BUFFER_LEN - popIndex)) + { + *size = (DEBUG_CONSOLE_TRANSMIT_BUFFER_LEN - popIndex); + } + else + { + *size = s_log_buffer.totalIndex; + } + + /* return address */ + return (&(s_log_buffer.txBuf[popIndex])); +} + +static uint8_t *LOG_BufPop(size_t *size) +{ + if (s_log_buffer.totalIndex >= *size) + { + /* decrease the log total member */ + s_log_buffer.totalIndex -= *size; + /* there is more log in the queue to be pushed */ + if (s_log_buffer.totalIndex > 0U) + { + /* update the pop index */ + s_log_buffer.popIndex += *size; + /* check index overflow */ + LOG_CHECK_BUFFER_INDEX_OVERFLOW(s_log_buffer.popIndex); + + return LOG_BufGetNextAvaliableLog(size); + } + else + { + /* reset push and pop */ + s_log_buffer.popIndex = 0U; + s_log_buffer.pushIndex = 0U; + *size = 0U; + } + } + + return NULL; +} + +static void LOG_Transferred(size_t *size, bool receive, bool transmit) +{ + uint8_t *addr = NULL; + + if (transmit) + { + addr = LOG_BufPop(size); + /* continue pop log from buffer */ + LOG_Pop(addr, *size); + } + + if (receive) + { + /* release from ISR */ + LOG_GIVE_BINARY_SEMAPHORE_FROM_ISR(s_logReadWaitSemaphore); + } +} +#endif /* DEBUG_CONSOLE_TRANSFER_NON_BLOCKING */ + +#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING +status_t LOG_TryReadCharacter(uint8_t *ch) +{ + if (NULL != ch) + { + return IO_TryReceiveCharacter(ch); + } + return kStatus_Fail; +} +#endif diff --git a/platform/mcu/lpc54102/utilities/log/fsl_log.h b/platform/mcu/lpc54102/utilities/log/fsl_log.h new file mode 100644 index 0000000000..acdea7d673 --- /dev/null +++ b/platform/mcu/lpc54102/utilities/log/fsl_log.h @@ -0,0 +1,142 @@ +/* + * Copyright 2017 NXP + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of Freescale Semiconductor, Inc. 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 _FSL_LOG_H +#define _FSL_LOG_H + +#include "fsl_common.h" + +/*! + * @addtogroup debugconsole + * @{ + */ + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/************************************************************************************************* + * Prototypes + ************************************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + +/*! + * @brief Initializes + * + * Call this function to init the buffer + * @param baseAddr, device base address + * @param device, device type + * @param baudRate, device communicate baudrate + * @param clkSrcFreq, device source clock freq + * + * @return Indicates whether initialization was successful or not. + * @retval kStatus_Success Execution successfully + * @retval kStatus_Fail Execution failure + */ +status_t LOG_Init(uint32_t baseAddr, uint8_t device, uint32_t baudRate, uint32_t clkSrcFreq); + +/*! + * @brief De-Initializes + * + * Call this function to deinit the buffer + * + * @return Indicates whether Deinit was successful or not. + */ +void LOG_Deinit(void); + +/*! + * @brief log push interface + * + * Call this function to print log + * @param fmt, buffer pointer + * @param size, avaliable size + * @return indicate the push size + * @retval-1 indicate buffer is full or transfer fail. + * @retval size return the push log size. + */ +int LOG_Push(uint8_t *buf, size_t size); + +/*! + * @brief log read one line function + * + * Call this function to print log + * @param fmt, buffer pointer + * @param size, avaliable size + * @reutrn the number of the recieved character + */ +int LOG_ReadLine(uint8_t *buf, size_t size); + +/*! + * @brief log read one character function + * + * Call this function to GETCHAR + * @param ch receive address + * @reutrn the number of the recieved character + */ +int LOG_ReadCharacter(uint8_t *ch); + +/*! + * @brief wait log and io idle + * + * Call this function to wait log buffer empty and io idle before enter low power mode. + * @return Indicates whether wait idle was successful or not. + */ +status_t LOG_WaitIdle(void); + +#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING +/*! + * @brief log try read one character + * Call this function to check character avaliable or not, if not return fail, otherwise return it. + * @param ch the address of char to receive + * @return Indicates try getchar was successful or not. + */ +status_t LOG_TryReadCharacter(uint8_t *ch); +#endif + +/*! + * @brief log pop function + * + * Call this function to pop log from buffer. + * @param buf buffer address to pop + * @param size log size to pop + * @return pop log size. + */ +int LOG_Pop(uint8_t *buf, size_t size); + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + +/*! @} */ + +#endif diff --git a/platform/mcu/lpc54102/utilities/str/fsl_str.c b/platform/mcu/lpc54102/utilities/str/fsl_str.c new file mode 100644 index 0000000000..7cecde2b63 --- /dev/null +++ b/platform/mcu/lpc54102/utilities/str/fsl_str.c @@ -0,0 +1,1320 @@ +/* + * Copyright 2017 NXP + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of Freescale Semiconductor, Inc. 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 EPRESS 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, EEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING 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 "fsl_str.h" +#include "fsl_debug_console_conf.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ + +/*! @brief The overflow value.*/ +#ifndef HUGE_VAL +#define HUGE_VAL (99.e99) +#endif /* HUGE_VAL */ + +#if SCANF_FLOAT_ENABLE +static double fnum = 0.0; +#endif /* SCANF_FLOAT_ENABLE */ + +#if PRINTF_ADVANCED_ENABLE +/*! @brief Specification modifier flags for printf. */ +enum _debugconsole_printf_flag +{ + kPRINTF_Minus = 0x01U, /*!< Minus FLag. */ + kPRINTF_Plus = 0x02U, /*!< Plus Flag. */ + kPRINTF_Space = 0x04U, /*!< Space Flag. */ + kPRINTF_Zero = 0x08U, /*!< Zero Flag. */ + kPRINTF_Pound = 0x10U, /*!< Pound Flag. */ + kPRINTF_LengthChar = 0x20U, /*!< Length: Char Flag. */ + kPRINTF_LengthShortInt = 0x40U, /*!< Length: Short Int Flag. */ + kPRINTF_LengthLongInt = 0x80U, /*!< Length: Long Int Flag. */ + kPRINTF_LengthLongLongInt = 0x100U, /*!< Length: Long Long Int Flag. */ +}; +#endif /* PRINTF_ADVANCED_ENABLE */ + +/*! @brief Specification modifier flags for scanf. */ +enum _debugconsole_scanf_flag +{ + kSCANF_Suppress = 0x2U, /*!< Suppress Flag. */ + kSCANF_DestMask = 0x7cU, /*!< Destination Mask. */ + kSCANF_DestChar = 0x4U, /*!< Destination Char Flag. */ + kSCANF_DestString = 0x8U, /*!< Destination String FLag. */ + kSCANF_DestSet = 0x10U, /*!< Destination Set Flag. */ + kSCANF_DestInt = 0x20U, /*!< Destination Int Flag. */ + kSCANF_DestFloat = 0x30U, /*!< Destination Float Flag. */ + kSCANF_LengthMask = 0x1f00U, /*!< Length Mask Flag. */ +#if SCANF_ADVANCED_ENABLE + kSCANF_LengthChar = 0x100U, /*!< Length Char Flag. */ + kSCANF_LengthShortInt = 0x200U, /*!< Length ShortInt Flag. */ + kSCANF_LengthLongInt = 0x400U, /*!< Length LongInt Flag. */ + kSCANF_LengthLongLongInt = 0x800U, /*!< Length LongLongInt Flag. */ +#endif /* SCANF_ADVANCED_ENABLE */ +#if PRINTF_FLOAT_ENABLE + kSCANF_LengthLongLongDouble = 0x1000U, /*!< Length LongLongDuoble Flag. */ +#endif /*PRINTF_FLOAT_ENABLE */ + kSCANF_TypeSinged = 0x2000U, /*!< TypeSinged Flag. */ +}; + +/*! @brief Keil: suppress ellipsis warning in va_arg usage below. */ +#if defined(__CC_ARM) +#pragma diag_suppress 1256 +#endif /* __CC_ARM */ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +/*! + * @brief Scanline function which ignores white spaces. + * + * @param[in] s The address of the string pointer to update. + * @return String without white spaces. + */ +static uint32_t ScanIgnoreWhiteSpace(const char **s); + +/*! + * @brief Converts a radix number to a string and return its length. + * + * @param[in] numstr Converted string of the number. + * @param[in] nump Pointer to the number. + * @param[in] neg Polarity of the number. + * @param[in] radix The radix to be converted to. + * @param[in] use_caps Used to identify %x/X output format. + + * @return Length of the converted string. + */ +static int32_t ConvertRadixNumToString(char *numstr, void *nump, int32_t neg, int32_t radix, bool use_caps); + +#if PRINTF_FLOAT_ENABLE +/*! + * @brief Converts a floating radix number to a string and return its length. + * + * @param[in] numstr Converted string of the number. + * @param[in] nump Pointer to the number. + * @param[in] radix The radix to be converted to. + * @param[in] precision_width Specify the precision width. + + * @return Length of the converted string. + */ +static int32_t ConvertFloatRadixNumToString(char *numstr, void *nump, int32_t radix, uint32_t precision_width); +#endif /* PRINTF_FLOAT_ENABLE */ + +/*! +* + */ +double modf(double input_dbl, double *intpart_ptr); + +/*************Code for process formatted data*******************************/ + +static uint32_t ScanIgnoreWhiteSpace(const char **s) +{ + uint8_t count = 0; + uint8_t c; + + c = **s; + while ((c == ' ') || (c == '\t') || (c == '\n') || (c == '\r') || (c == '\v') || (c == '\f')) + { + count++; + (*s)++; + c = **s; + } + return count; +} + +static int32_t ConvertRadixNumToString(char *numstr, void *nump, int32_t neg, int32_t radix, bool use_caps) +{ +#if PRINTF_ADVANCED_ENABLE + int64_t a; + int64_t b; + int64_t c; + + uint64_t ua; + uint64_t ub; + uint64_t uc; +#else + int32_t a; + int32_t b; + int32_t c; + + uint32_t ua; + uint32_t ub; + uint32_t uc; +#endif /* PRINTF_ADVANCED_ENABLE */ + + int32_t nlen; + char *nstrp; + + nlen = 0; + nstrp = numstr; + *nstrp++ = '\0'; + + if (neg) + { +#if PRINTF_ADVANCED_ENABLE + a = *(int64_t *)nump; +#else + a = *(int32_t *)nump; +#endif /* PRINTF_ADVANCED_ENABLE */ + if (a == 0) + { + *nstrp = '0'; + ++nlen; + return nlen; + } + while (a != 0) + { +#if PRINTF_ADVANCED_ENABLE + b = (int64_t)a / (int64_t)radix; + c = (int64_t)a - ((int64_t)b * (int64_t)radix); + if (c < 0) + { + uc = (uint64_t)c; + c = (int64_t)(~uc) + 1 + '0'; + } +#else + b = a / radix; + c = a - (b * radix); + if (c < 0) + { + uc = (uint32_t)c; + c = (uint32_t)(~uc) + 1 + '0'; + } +#endif /* PRINTF_ADVANCED_ENABLE */ + else + { + c = c + '0'; + } + a = b; + *nstrp++ = (char)c; + ++nlen; + } + } + else + { +#if PRINTF_ADVANCED_ENABLE + ua = *(uint64_t *)nump; +#else + ua = *(uint32_t *)nump; +#endif /* PRINTF_ADVANCED_ENABLE */ + if (ua == 0) + { + *nstrp = '0'; + ++nlen; + return nlen; + } + while (ua != 0) + { +#if PRINTF_ADVANCED_ENABLE + ub = (uint64_t)ua / (uint64_t)radix; + uc = (uint64_t)ua - ((uint64_t)ub * (uint64_t)radix); +#else + ub = ua / (uint32_t)radix; + uc = ua - (ub * (uint32_t)radix); +#endif /* PRINTF_ADVANCED_ENABLE */ + + if (uc < 10) + { + uc = uc + '0'; + } + else + { + uc = uc - 10 + (use_caps ? 'A' : 'a'); + } + ua = ub; + *nstrp++ = (char)uc; + ++nlen; + } + } + return nlen; +} + +#if PRINTF_FLOAT_ENABLE +static int32_t ConvertFloatRadixNumToString(char *numstr, void *nump, int32_t radix, uint32_t precision_width) +{ + int32_t a; + int32_t b; + int32_t c; + int32_t i; + uint32_t uc; + double fa; + double dc; + double fb; + double r; + double fractpart; + double intpart; + + int32_t nlen; + char *nstrp; + nlen = 0; + nstrp = numstr; + *nstrp++ = '\0'; + r = *(double *)nump; + if (!r) + { + *nstrp = '0'; + ++nlen; + return nlen; + } + fractpart = modf((double)r, (double *)&intpart); + /* Process fractional part. */ + for (i = 0; i < precision_width; i++) + { + fractpart *= radix; + } + if (r >= 0) + { + fa = fractpart + (double)0.5; + if (fa >= pow(10, precision_width)) + { + intpart++; + } + } + else + { + fa = fractpart - (double)0.5; + if (fa <= -pow(10, precision_width)) + { + intpart--; + } + } + for (i = 0; i < precision_width; i++) + { + fb = fa / (int32_t)radix; + dc = (fa - (int64_t)fb * (int32_t)radix); + c = (int32_t)dc; + if (c < 0) + { + uc = (uint32_t)c; + c = (int32_t)(~uc) + 1 + '0'; + } + else + { + c = c + '0'; + } + fa = fb; + *nstrp++ = (char)c; + ++nlen; + } + *nstrp++ = (char)'.'; + ++nlen; + a = (int32_t)intpart; + if (a == 0) + { + *nstrp++ = '0'; + ++nlen; + } + else + { + while (a != 0) + { + b = (int32_t)a / (int32_t)radix; + c = (int32_t)a - ((int32_t)b * (int32_t)radix); + if (c < 0) + { + uc = (uint32_t)c; + c = (int32_t)(~uc) + 1 + '0'; + } + else + { + c = c + '0'; + } + a = b; + *nstrp++ = (char)c; + ++nlen; + } + } + return nlen; +} +#endif /* PRINTF_FLOAT_ENABLE */ + +int StrFormatPrintf(const char *fmt, va_list ap, char *buf, printfCb cb) +{ + /* va_list ap; */ + char *p; + int32_t c; + + char vstr[33]; + char *vstrp = NULL; + int32_t vlen = 0; + + int32_t done; + int32_t count = 0; + + uint32_t field_width; + uint32_t precision_width; + char *sval; + int32_t cval; + bool use_caps; + uint8_t radix = 0; + +#if PRINTF_ADVANCED_ENABLE + uint32_t flags_used; + int32_t schar, dschar; + int64_t ival; + uint64_t uval = 0; + bool valid_precision_width; +#else + int32_t ival; + uint32_t uval = 0; +#endif /* PRINTF_ADVANCED_ENABLE */ + +#if PRINTF_FLOAT_ENABLE + double fval; +#endif /* PRINTF_FLOAT_ENABLE */ + + /* Start parsing apart the format string and display appropriate formats and data. */ + for (p = (char *)fmt; (c = *p) != 0; p++) + { + /* + * All formats begin with a '%' marker. Special chars like + * '\n' or '\t' are normally converted to the appropriate + * character by the __compiler__. Thus, no need for this + * routine to account for the '\' character. + */ + if (c != '%') + { + cb(buf, &count, c, 1); + /* By using 'continue', the next iteration of the loop is used, skipping the code that follows. */ + continue; + } + + use_caps = true; + +#if PRINTF_ADVANCED_ENABLE + /* First check for specification modifier flags. */ + flags_used = 0; + done = false; + while (!done) + { + switch (*++p) + { + case '-': + flags_used |= kPRINTF_Minus; + break; + case '+': + flags_used |= kPRINTF_Plus; + break; + case ' ': + flags_used |= kPRINTF_Space; + break; + case '0': + flags_used |= kPRINTF_Zero; + break; + case '#': + flags_used |= kPRINTF_Pound; + break; + default: + /* We've gone one char too far. */ + --p; + done = true; + break; + } + } +#endif /* PRINTF_ADVANCED_ENABLE */ + + /* Next check for minimum field width. */ + field_width = 0; + done = false; + while (!done) + { + c = *++p; + if ((c >= '0') && (c <= '9')) + { + field_width = (field_width * 10) + (c - '0'); + } +#if PRINTF_ADVANCED_ENABLE + else if (c == '*') + { + field_width = (uint32_t)va_arg(ap, uint32_t); + } +#endif /* PRINTF_ADVANCED_ENABLE */ + else + { + /* We've gone one char too far. */ + --p; + done = true; + } + } + /* Next check for the width and precision field separator. */ + precision_width = 6; +#if PRINTF_ADVANCED_ENABLE + valid_precision_width = false; +#endif /* PRINTF_ADVANCED_ENABLE */ + if (*++p == '.') + { + /* Must get precision field width, if present. */ + precision_width = 0; + done = false; + while (!done) + { + c = *++p; + if ((c >= '0') && (c <= '9')) + { + precision_width = (precision_width * 10) + (c - '0'); +#if PRINTF_ADVANCED_ENABLE + valid_precision_width = true; +#endif /* PRINTF_ADVANCED_ENABLE */ + } +#if PRINTF_ADVANCED_ENABLE + else if (c == '*') + { + precision_width = (uint32_t)va_arg(ap, uint32_t); + valid_precision_width = true; + } +#endif /* PRINTF_ADVANCED_ENABLE */ + else + { + /* We've gone one char too far. */ + --p; + done = true; + } + } + } + else + { + /* We've gone one char too far. */ + --p; + } +#if PRINTF_ADVANCED_ENABLE + /* + * Check for the length modifier. + */ + switch (/* c = */ *++p) + { + case 'h': + if (*++p != 'h') + { + flags_used |= kPRINTF_LengthShortInt; + --p; + } + else + { + flags_used |= kPRINTF_LengthChar; + } + break; + case 'l': + if (*++p != 'l') + { + flags_used |= kPRINTF_LengthLongInt; + --p; + } + else + { + flags_used |= kPRINTF_LengthLongLongInt; + } + break; + default: + /* we've gone one char too far */ + --p; + break; + } +#endif /* PRINTF_ADVANCED_ENABLE */ + /* Now we're ready to examine the format. */ + c = *++p; + { + if ((c == 'd') || (c == 'i') || (c == 'f') || (c == 'F') || (c == 'x') || (c == 'X') || (c == 'o') || + (c == 'b') || (c == 'p') || (c == 'u')) + { + if ((c == 'd') || (c == 'i')) + { +#if PRINTF_ADVANCED_ENABLE + if (flags_used & kPRINTF_LengthLongLongInt) + { + ival = (int64_t)va_arg(ap, int64_t); + } + else +#endif /* PRINTF_ADVANCED_ENABLE */ + { + ival = (int32_t)va_arg(ap, int32_t); + } + vlen = ConvertRadixNumToString(vstr, &ival, true, 10, use_caps); + vstrp = &vstr[vlen]; +#if PRINTF_ADVANCED_ENABLE + if (ival < 0) + { + schar = '-'; + ++vlen; + } + else + { + if (flags_used & kPRINTF_Plus) + { + schar = '+'; + ++vlen; + } + else + { + if (flags_used & kPRINTF_Space) + { + schar = ' '; + ++vlen; + } + else + { + schar = 0; + } + } + } + dschar = false; + /* Do the ZERO pad. */ + if (flags_used & kPRINTF_Zero) + { + if (schar) + { + cb(buf, &count, schar, 1); + } + dschar = true; + + cb(buf, &count, '0', field_width - vlen); + vlen = field_width; + } + else + { + if (!(flags_used & kPRINTF_Minus)) + { + cb(buf, &count, ' ', field_width - vlen); + if (schar) + { + cb(buf, &count, schar, 1); + } + dschar = true; + } + } + /* The string was built in reverse order, now display in correct order. */ + if ((!dschar) && schar) + { + cb(buf, &count, schar, 1); + } +#endif /* PRINTF_ADVANCED_ENABLE */ + } + +#if PRINTF_FLOAT_ENABLE + if ((c == 'f') || (c == 'F')) + { + fval = (double)va_arg(ap, double); + vlen = ConvertFloatRadixNumToString(vstr, &fval, 10, precision_width); + vstrp = &vstr[vlen]; + +#if PRINTF_ADVANCED_ENABLE + if (fval < 0) + { + schar = '-'; + ++vlen; + } + else + { + if (flags_used & kPRINTF_Plus) + { + schar = '+'; + ++vlen; + } + else + { + if (flags_used & kPRINTF_Space) + { + schar = ' '; + ++vlen; + } + else + { + schar = 0; + } + } + } + dschar = false; + if (flags_used & kPRINTF_Zero) + { + if (schar) + { + cb(buf, &count, schar, 1); + } + dschar = true; + cb(buf, &count, '0', field_width - vlen); + vlen = field_width; + } + else + { + if (!(flags_used & kPRINTF_Minus)) + { + cb(buf, &count, ' ', field_width - vlen); + if (schar) + { + cb(buf, &count, schar, 1); + } + dschar = true; + } + } + if ((!dschar) && schar) + { + cb(buf, &count, schar, 1); + } +#endif /* PRINTF_ADVANCED_ENABLE */ + } +#endif /* PRINTF_FLOAT_ENABLE */ + if ((c == 'X') || (c == 'x')) + { + if (c == 'x') + { + use_caps = false; + } +#if PRINTF_ADVANCED_ENABLE + if (flags_used & kPRINTF_LengthLongLongInt) + { + uval = (uint64_t)va_arg(ap, uint64_t); + } + else +#endif /* PRINTF_ADVANCED_ENABLE */ + { + uval = (uint32_t)va_arg(ap, uint32_t); + } + vlen = ConvertRadixNumToString(vstr, &uval, false, 16, use_caps); + vstrp = &vstr[vlen]; + +#if PRINTF_ADVANCED_ENABLE + dschar = false; + if (flags_used & kPRINTF_Zero) + { + if (flags_used & kPRINTF_Pound) + { + cb(buf, &count, '0', 1); + cb(buf, &count, (use_caps ? 'X' : 'x'), 1); + dschar = true; + } + cb(buf, &count, '0', field_width - vlen); + vlen = field_width; + } + else + { + if (!(flags_used & kPRINTF_Minus)) + { + if (flags_used & kPRINTF_Pound) + { + vlen += 2; + } + cb(buf, &count, ' ', field_width - vlen); + if (flags_used & kPRINTF_Pound) + { + cb(buf, &count, '0', 1); + cb(buf, &count, (use_caps ? 'X' : 'x'), 1); + dschar = true; + } + } + } + + if ((flags_used & kPRINTF_Pound) && (!dschar)) + { + cb(buf, &count, '0', 1); + cb(buf, &count, (use_caps ? 'X' : 'x'), 1); + vlen += 2; + } +#endif /* PRINTF_ADVANCED_ENABLE */ + } + if ((c == 'o') || (c == 'b') || (c == 'p') || (c == 'u')) + { +#if PRINTF_ADVANCED_ENABLE + if (flags_used & kPRINTF_LengthLongLongInt) + { + uval = (uint64_t)va_arg(ap, uint64_t); + } + else +#endif /* PRINTF_ADVANCED_ENABLE */ + { + uval = (uint32_t)va_arg(ap, uint32_t); + } + switch (c) + { + case 'o': + radix = 8; + break; + case 'b': + radix = 2; + break; + case 'p': + radix = 16; + break; + case 'u': + radix = 10; + break; + } + vlen = ConvertRadixNumToString(vstr, &uval, false, radix, use_caps); + vstrp = &vstr[vlen]; +#if PRINTF_ADVANCED_ENABLE + if (flags_used & kPRINTF_Zero) + { + cb(buf, &count, '0', field_width - vlen); + vlen = field_width; + } + else + { + if (!(flags_used & kPRINTF_Minus)) + { + cb(buf, &count, ' ', field_width - vlen); + } + } +#endif /* PRINTF_ADVANCED_ENABLE */ + } +#if !PRINTF_ADVANCED_ENABLE + cb(buf, &count, ' ', field_width - vlen); +#endif /* !PRINTF_ADVANCED_ENABLE */ + if (vstrp != NULL) + { + while (*vstrp) + { + cb(buf, &count, *vstrp--, 1); + } + } +#if PRINTF_ADVANCED_ENABLE + if (flags_used & kPRINTF_Minus) + { + cb(buf, &count, ' ', field_width - vlen); + } +#endif /* PRINTF_ADVANCED_ENABLE */ + } + else if (c == 'c') + { + cval = (char)va_arg(ap, uint32_t); + cb(buf, &count, cval, 1); + } + else if (c == 's') + { + sval = (char *)va_arg(ap, char *); + if (sval) + { +#if PRINTF_ADVANCED_ENABLE + if (valid_precision_width) + { + vlen = precision_width; + } + else + { + vlen = strlen(sval); + } +#else + vlen = strlen(sval); +#endif /* PRINTF_ADVANCED_ENABLE */ +#if PRINTF_ADVANCED_ENABLE + if (!(flags_used & kPRINTF_Minus)) +#endif /* PRINTF_ADVANCED_ENABLE */ + { + cb(buf, &count, ' ', field_width - vlen); + } + +#if PRINTF_ADVANCED_ENABLE + if (valid_precision_width) + { + while ((*sval) && (vlen > 0)) + { + cb(buf, &count, *sval++, 1); + vlen--; + } + /* In case that vlen sval is shorter than vlen */ + vlen = precision_width - vlen; + } + else + { +#endif /* PRINTF_ADVANCED_ENABLE */ + while (*sval) + { + cb(buf, &count, *sval++, 1); + } +#if PRINTF_ADVANCED_ENABLE + } +#endif /* PRINTF_ADVANCED_ENABLE */ + +#if PRINTF_ADVANCED_ENABLE + if (flags_used & kPRINTF_Minus) + { + cb(buf, &count, ' ', field_width - vlen); + } +#endif /* PRINTF_ADVANCED_ENABLE */ + } + } + else + { + cb(buf, &count, c, 1); + } + } + } + + return count; +} + +int StrFormatScanf(const char *line_ptr, char *format, va_list args_ptr) +{ + uint8_t base; + int8_t neg; + /* Identifier for the format string. */ + char *c = format; + char temp; + char *buf; + /* Flag telling the conversion specification. */ + uint32_t flag = 0; + /* Filed width for the matching input streams. */ + uint32_t field_width; + /* How many arguments are assigned except the suppress. */ + uint32_t nassigned = 0; + /* How many characters are read from the input streams. */ + uint32_t n_decode = 0; + + int32_t val; + + const char *s; + /* Identifier for the input string. */ + const char *p = line_ptr; + + /* Return EOF error before any conversion. */ + if (*p == '\0') + { + return -1; + } + + /* Decode directives. */ + while ((*c) && (*p)) + { + /* Ignore all white-spaces in the format strings. */ + if (ScanIgnoreWhiteSpace((const char **)&c)) + { + n_decode += ScanIgnoreWhiteSpace(&p); + } + else if ((*c != '%') || ((*c == '%') && (*(c + 1) == '%'))) + { + /* Ordinary characters. */ + c++; + if (*p == *c) + { + n_decode++; + p++; + c++; + } + else + { + /* Match failure. Misalignment with C99, the unmatched characters need to be pushed back to stream. + * However, it is deserted now. */ + break; + } + } + else + { + /* convernsion specification */ + c++; + /* Reset. */ + flag = 0; + field_width = 0; + base = 0; + + /* Loop to get full conversion specification. */ + while ((*c) && (!(flag & kSCANF_DestMask))) + { + switch (*c) + { +#if SCANF_ADVANCED_ENABLE + case '*': + if (flag & kSCANF_Suppress) + { + /* Match failure. */ + return nassigned; + } + flag |= kSCANF_Suppress; + c++; + break; + case 'h': + if (flag & kSCANF_LengthMask) + { + /* Match failure. */ + return nassigned; + } + + if (c[1] == 'h') + { + flag |= kSCANF_LengthChar; + c++; + } + else + { + flag |= kSCANF_LengthShortInt; + } + c++; + break; + case 'l': + if (flag & kSCANF_LengthMask) + { + /* Match failure. */ + return nassigned; + } + + if (c[1] == 'l') + { + flag |= kSCANF_LengthLongLongInt; + c++; + } + else + { + flag |= kSCANF_LengthLongInt; + } + c++; + break; +#endif /* SCANF_ADVANCED_ENABLE */ +#if SCANF_FLOAT_ENABLE + case 'L': + if (flag & kSCANF_LengthMask) + { + /* Match failure. */ + return nassigned; + } + flag |= kSCANF_LengthLongLongDouble; + c++; + break; +#endif /* SCANF_FLOAT_ENABLE */ + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (field_width) + { + /* Match failure. */ + return nassigned; + } + do + { + field_width = field_width * 10 + *c - '0'; + c++; + } while ((*c >= '0') && (*c <= '9')); + break; + case 'd': + base = 10; + flag |= kSCANF_TypeSinged; + flag |= kSCANF_DestInt; + c++; + break; + case 'u': + base = 10; + flag |= kSCANF_DestInt; + c++; + break; + case 'o': + base = 8; + flag |= kSCANF_DestInt; + c++; + break; + case 'x': + case 'X': + base = 16; + flag |= kSCANF_DestInt; + c++; + break; + case 'i': + base = 0; + flag |= kSCANF_DestInt; + c++; + break; +#if SCANF_FLOAT_ENABLE + case 'a': + case 'A': + case 'e': + case 'E': + case 'f': + case 'F': + case 'g': + case 'G': + flag |= kSCANF_DestFloat; + c++; + break; +#endif /* SCANF_FLOAT_ENABLE */ + case 'c': + flag |= kSCANF_DestChar; + if (!field_width) + { + field_width = 1; + } + c++; + break; + case 's': + flag |= kSCANF_DestString; + c++; + break; + default: + return nassigned; + } + } + + if (!(flag & kSCANF_DestMask)) + { + /* Format strings are exhausted. */ + return nassigned; + } + + if (!field_width) + { + /* Large than length of a line. */ + field_width = 99; + } + + /* Matching strings in input streams and assign to argument. */ + switch (flag & kSCANF_DestMask) + { + case kSCANF_DestChar: + s = (const char *)p; + buf = va_arg(args_ptr, char *); + while ((field_width--) && (*p)) + { + if (!(flag & kSCANF_Suppress)) + { + *buf++ = *p++; + } + else + { + p++; + } + n_decode++; + } + + if ((!(flag & kSCANF_Suppress)) && (s != p)) + { + nassigned++; + } + break; + case kSCANF_DestString: + n_decode += ScanIgnoreWhiteSpace(&p); + s = p; + buf = va_arg(args_ptr, char *); + while ((field_width--) && (*p != '\0') && (*p != ' ') && (*p != '\t') && (*p != '\n') && + (*p != '\r') && (*p != '\v') && (*p != '\f')) + { + if (flag & kSCANF_Suppress) + { + p++; + } + else + { + *buf++ = *p++; + } + n_decode++; + } + + if ((!(flag & kSCANF_Suppress)) && (s != p)) + { + /* Add NULL to end of string. */ + *buf = '\0'; + nassigned++; + } + break; + case kSCANF_DestInt: + n_decode += ScanIgnoreWhiteSpace(&p); + s = p; + val = 0; + if ((base == 0) || (base == 16)) + { + if ((s[0] == '0') && ((s[1] == 'x') || (s[1] == 'X'))) + { + base = 16; + if (field_width >= 1) + { + p += 2; + n_decode += 2; + field_width -= 2; + } + } + } + + if (base == 0) + { + if (s[0] == '0') + { + base = 8; + } + else + { + base = 10; + } + } + + neg = 1; + switch (*p) + { + case '-': + neg = -1; + n_decode++; + p++; + field_width--; + break; + case '+': + neg = 1; + n_decode++; + p++; + field_width--; + break; + default: + break; + } + + while ((*p) && (field_width--)) + { + if ((*p <= '9') && (*p >= '0')) + { + temp = *p - '0'; + } + else if ((*p <= 'f') && (*p >= 'a')) + { + temp = *p - 'a' + 10; + } + else if ((*p <= 'F') && (*p >= 'A')) + { + temp = *p - 'A' + 10; + } + else + { + temp = base; + } + + if (temp >= base) + { + break; + } + else + { + val = base * val + temp; + } + p++; + n_decode++; + } + val *= neg; + if (!(flag & kSCANF_Suppress)) + { +#if SCANF_ADVANCED_ENABLE + switch (flag & kSCANF_LengthMask) + { + case kSCANF_LengthChar: + if (flag & kSCANF_TypeSinged) + { + *va_arg(args_ptr, signed char *) = (signed char)val; + } + else + { + *va_arg(args_ptr, unsigned char *) = (unsigned char)val; + } + break; + case kSCANF_LengthShortInt: + if (flag & kSCANF_TypeSinged) + { + *va_arg(args_ptr, signed short *) = (signed short)val; + } + else + { + *va_arg(args_ptr, unsigned short *) = (unsigned short)val; + } + break; + case kSCANF_LengthLongInt: + if (flag & kSCANF_TypeSinged) + { + *va_arg(args_ptr, signed long int *) = (signed long int)val; + } + else + { + *va_arg(args_ptr, unsigned long int *) = (unsigned long int)val; + } + break; + case kSCANF_LengthLongLongInt: + if (flag & kSCANF_TypeSinged) + { + *va_arg(args_ptr, signed long long int *) = (signed long long int)val; + } + else + { + *va_arg(args_ptr, unsigned long long int *) = (unsigned long long int)val; + } + break; + default: + /* The default type is the type int. */ + if (flag & kSCANF_TypeSinged) + { + *va_arg(args_ptr, signed int *) = (signed int)val; + } + else + { + *va_arg(args_ptr, unsigned int *) = (unsigned int)val; + } + break; + } +#else + /* The default type is the type int. */ + if (flag & kSCANF_TypeSinged) + { + *va_arg(args_ptr, signed int *) = (signed int)val; + } + else + { + *va_arg(args_ptr, unsigned int *) = (unsigned int)val; + } +#endif /* SCANF_ADVANCED_ENABLE */ + nassigned++; + } + break; +#if SCANF_FLOAT_ENABLE + case kSCANF_DestFloat: + n_decode += ScanIgnoreWhiteSpace(&p); + fnum = strtod(p, (char **)&s); + + if ((fnum >= HUGE_VAL) || (fnum <= -HUGE_VAL)) + { + break; + } + + n_decode += (int)(s) - (int)(p); + p = s; + if (!(flag & kSCANF_Suppress)) + { + if (flag & kSCANF_LengthLongLongDouble) + { + *va_arg(args_ptr, double *) = fnum; + } + else + { + *va_arg(args_ptr, float *) = (float)fnum; + } + nassigned++; + } + break; +#endif /* SCANF_FLOAT_ENABLE */ + default: + return nassigned; + } + } + } + return nassigned; +} diff --git a/platform/mcu/lpc54102/utilities/str/fsl_str.h b/platform/mcu/lpc54102/utilities/str/fsl_str.h new file mode 100644 index 0000000000..44440a9064 --- /dev/null +++ b/platform/mcu/lpc54102/utilities/str/fsl_str.h @@ -0,0 +1,88 @@ +/* + * Copyright 2017 NXP + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of Freescale Semiconductor, Inc. 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 EPRESS 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, EEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef _FSL_STR_H +#define _FSL_STR_H + +#include "fsl_common.h" + +/*! + * @addtogroup debugconsole + * @{ + */ + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + +/*! + * @brief A function pointer which is used when format printf log. + */ +typedef void (*printfCb)(char *buf, int32_t *indicator, char val, int len); + +/*! + * @brief This function outputs its parameters according to a formatted string. + * + * @note I/O is performed by calling given function pointer using following + * (*func_ptr)(c); + * + * @param[in] fmt_ptr Format string for printf. + * @param[in] args_ptr Arguments to printf. + * @param[in] buf pointer to the buffer + * @param cb print callbck function pointer + * + * @return Number of characters to be print + */ +int StrFormatPrintf(const char *fmt, va_list ap, char *buf, printfCb cb); + +/*! + * @brief Converts an input line of ASCII characters based upon a provided + * string format. + * + * @param[in] line_ptr The input line of ASCII data. + * @param[in] format Format first points to the format string. + * @param[in] args_ptr The list of parameters. + * + * @return Number of input items converted and assigned. + * @retval IO_EOF When line_ptr is empty string "". + */ +int StrFormatScanf(const char *line_ptr, char *format, va_list args_ptr); + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + +/*! @} */ + +#endif /* _FSL_STR_H */ diff --git a/platform/mcu/lpc54102/wifi_qca/atheros_stack_offload.h b/platform/mcu/lpc54102/wifi_qca/atheros_stack_offload.h new file mode 100644 index 0000000000..d562c264e2 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/atheros_stack_offload.h @@ -0,0 +1,815 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== +#ifndef __ATHEROS_STACK_OFFLOAD_H__ +#define __ATHEROS_STACK_OFFLOAD_H__ +#include +#include +#include +#include +#include +#include +#include +#include +#include "atheros_wifi.h" + +//TODO: find more appropriate place +typedef uint16_t socklen_t; + +#if ENABLE_STACK_OFFLOAD + +/**********************Macros and config parameters**********/ +#define MAX_SOCKETS_SUPPORTED (8) +#define SOCKET_NOT_FOUND (-1) +#define EMPTY_SOCKET_CONTEXT (0) +#define SOCKET_HANDLE_PLACEHOLDER (0xFFFFFFFF) +#define ATH_AF_INET (2) +#define ATH_PF_INET (ATH_AF_INET) +#define ATH_AF_INET6 (3) +#define ATH_PF_INET6 (ATH_AF_INET6) +#define IPV4_HEADER_LENGTH (20) +#define IPV6_HEADER_LENGTH (40) +#define TCP_HEADER_LENGTH (20) +#define UDP_HEADER_LENGTH (8) +#define IPV6_FRAGMENTATION_THRESHOLD (1280) +#define IPV4_FRAGMENTATION_THRESHOLD (AR4100_BUFFER_SIZE - TCP6_HEADROOM) +#define MAX_ETHERNET_FRAME_SIZE (1500) + +#define GLOBAL_SOCK_INDEX (MAX_SOCKETS_SUPPORTED) // Index used for global commands e.g. ipconfig, ping + +/*The following macro enables the zero copy feature. In memory-constrained systems, + the application will provide a pointer instead of an allocated buffer. The driver + will return the pointer to received packet instead of copying the packet over. + The application must call zero_copy_free() API after it is done with the buffer + and pass the pointer to buffer.*/ +#define ZERO_COPY 1 +#if !ZERO_COPY +# error "WiFi driver works only with ZERO_COPY enabled ! " +#endif + +/* NON_BLOCKING_TX- Macro used to control SEND behavior. + SECTION 1- Macro is disabled. + If this macro is disabled, application thread will block until a packet is + sent over SPI. This is not desirable in a single buffer scenario as it may + lead to deadlocks. + SECTION 2- Macro is enabled. + If this macro is enabled, the application thread will return after submitting + packet to the driver thread. Under this setting, the application MUST NOT + TRY TO REUSE OR FREE THIS BUFFER. This buffer is now owned by the driver. + The application should call custom_alloc again to get a new buffer. */ +#define NON_BLOCKING_TX 0 + +/* There may be scenarios where application does not wish to block on a receive operation. + This macro will enable non blocking receive behavior. Note that this change is only + limited to the host and does not affect target behavior.*/ +#define NON_BLOCKING_RX 0 + +/* If the host has only 1 RX buffer, receive operation can never be blocking, as + this may lead to deadlocks.*/ +#if WLAN_CONFIG_NUM_PRE_ALLOC_RX_BUFFERS < 2 + +#if NON_BLOCKING_RX == 0 +#error "Blocking receive not permitted with single RX buffer, please enable NON_BLOCKING_RX" +#endif + +#if NON_BLOCKING_TX == 0 +#error "Blocking tranmit not permitted with single RX buffer, please enable NON_BLOCKING_TX" +#endif + +#endif + +/* BSD Sockets errors */ +/* +//Remove all ERRNO MARCO as they have already defined in ERRNO.H +#define ENOBUFS 1 +#define ETIMEDOUT 2 +#define EISCONN 3 +#define EOPNOTSUPP 4 +#define ECONNABORTED 5 +#define EWOULDBLOCK 6 +#define ECONNREFUSED 7 +#define ECONNRESET 8 +#define ENOTCONN 9 +#define EALREADY 10 +#define EINVAL 11 +#define EMSGSIZE 12 +#define EPIPE 13 +#define EDESTADDRREQ 14 +#define ESHUTDOWN 15 +#define ENOPROTOOPT 16 +#define EHAVEOOB 17 +#define ENOMEM 18 +#define EADDRNOTAVAIL 19 +#define EADDRINUSE 20 +#define EAFNOSUPPORT 21 +*/ +/* Generic/TCP socket options */ +#define SOL_SOCKET 1 + +#define SO_KEEPALIVE 0x0008 /* keep connections alive */ +#define SO_MAXMSG 0x1010 /* get TCP_MSS (max segment size) */ +#define SO_LINGER 0x0080 /* linger on close if data present */ + +/* TCP User-settable options (used with setsockopt). */ +#define TCP_MAXSEG 0x2003 /* set maximum segment size */ + +/* RAW socket option */ +#define IP_HDRINCL 2 /* u_char; set/get IP header rcv/send or not */ + +/*Multicast options*/ +#define IP_MULTICAST_IF 9 /* u_char; set/get IP multicast i/f */ +#define IP_MULTICAST_TTL 10 /* u_char; set/get IP multicast ttl */ +#define IP_MULTICAST_LOOP 11 /* u_char; set/get IP multicast loopback */ +#define IP_ADD_MEMBERSHIP 12 /* ip_mreq; add an IP group membership */ +#define IP_DROP_MEMBERSHIP 13 /* ip_mreq; drop an IP group membership */ +#define IP_HDRINCL 2 /* int ; header is included with data */ + +/*IPv6*/ +#define IPV6_MULTICAST_IF 80 /* unisgned int; set IF for outgoing MC pkts */ +#define IPV6_MULTICAST_HOPS 81 /* int; set MC hopcount */ +#define IPV6_MULTICAST_LOOP 82 /* unisgned int; set to 1 to loop back */ +#define IPV6_JOIN_GROUP 83 /* ipv6_mreq; join MC group */ +#define IPV6_LEAVE_GROUP 84 /* ipv6_mreq; leave MC group */ +#define IPV6_V6ONLY 85 /* int; IPv6 only on this socket */ + +#define ATH_IN_MULTICAST(a) (((a)&0xF0000000L) == 0xE0000000L) + +#define CUSTOM_ALLOC(size) custom_alloc(size) + +#define CUSTOM_FREE(buf) custom_free(buf) + +#define ATH_IPPROTO_IP 0 +#define ATH_IPPROTO_ICMP 1 +#define ATH_IPPROTO_IGMP 2 /* added for IP multicasting changes */ +#define ATH_IPPROTO_TCP 6 +#define ATH_IPPROTO_UDP 17 +#define ATH_IPPROTO_RAW 255 +#define ATH_IPPROTO_IPV6 41 /* IPv6 header */ +#define ATH_IPPROTO_ROUTING 43 /* IPv6 Routing header */ +#define ATH_IPPROTO_FRAGMENT 44 /* IPv6 fragmentation header */ + +/* SSL cipher suites. To be used with SSL_configure(). */ +#define TLS_NULL_WITH_NULL_NULL 0x0000 +#define TLS_RSA_WITH_NULL_MD5 0x0001 +#define TLS_RSA_WITH_NULL_SHA 0x0002 +#define TLS_RSA_WITH_RC4_128_MD5 0x0004 +#define TLS_RSA_WITH_RC4_128_SHA 0x0005 +#define TLS_RSA_WITH_DES_CBC_SHA 0x0009 +#define TLS_RSA_WITH_3DES_EDE_CBC_SHA 0x000A +#define TLS_DHE_RSA_WITH_DES_CBC_SHA 0x0015 +#define TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA 0x0016 +#define TLS_RSA_WITH_AES_128_CBC_SHA 0x002F +#define TLS_DHE_RSA_WITH_AES_128_CBC_SHA 0x0033 +#define TLS_RSA_WITH_AES_256_CBC_SHA 0x0035 +#define TLS_DHE_RSA_WITH_AES_256_CBC_SHA 0x0039 +#define TLS_RSA_WITH_NULL_SHA256 0x003B +#define TLS_RSA_WITH_AES_128_CBC_SHA256 0x003C +#define TLS_RSA_WITH_AES_256_CBC_SHA256 0x003D +#define TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 0x0067 +#define TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 0x006B +#define TLS_PSK_WITH_RC4_128_SHA 0x008A +#define TLS_PSK_WITH_3DES_EDE_CBC_SHA 0x008B +#define TLS_PSK_WITH_AES_128_CBC_SHA 0x008C +#define TLS_PSK_WITH_AES_256_CBC_SHA 0x008D +#define TLS_RSA_WITH_AES_128_GCM_SHA256 0x009C +#define TLS_RSA_WITH_AES_256_GCM_SHA384 0x009D +#define TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 0x009E +#define TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 0x009F +#define TLS_ECDH_ECDSA_WITH_NULL_SHA 0xC001 +#define TLS_ECDH_ECDSA_WITH_RC4_128_SHA 0xC002 +#define TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA 0xC003 +#define TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA 0xC004 +#define TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA 0xC005 +#define TLS_ECDHE_ECDSA_WITH_NULL_SHA 0xC006 +#define TLS_ECDHE_ECDSA_WITH_RC4_128_SHA 0xC007 +#define TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA 0xC008 +#define TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA 0xC009 +#define TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA 0xC00A +#define TLS_ECDH_RSA_WITH_NULL_SHA 0xC00B +#define TLS_ECDH_RSA_WITH_RC4_128_SHA 0xC00C +#define TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA 0xC00D +#define TLS_ECDH_RSA_WITH_AES_128_CBC_SHA 0xC00E +#define TLS_ECDH_RSA_WITH_AES_256_CBC_SHA 0xC00F +#define TLS_ECDHE_RSA_WITH_NULL_SHA 0xC010 +#define TLS_ECDHE_RSA_WITH_RC4_128_SHA 0xC011 +#define TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA 0xC012 +#define TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA 0xC013 +#define TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA 0xC014 +#define TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 0xC023 +#define TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 0xC024 +#define TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 0xC025 +#define TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 0xC026 +#define TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 0xC027 +#define TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 0xC028 +#define TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 0xC029 +#define TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 0xC02A +#define TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 0xC02B +#define TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 0xC02C +#define TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 0xC02D +#define TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 0xC02E +#define TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 0xC02F +#define TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 0xC030 +#define TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 0xC031 +#define TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 0xC032 +#define TLS_RSA_WITH_AES_128_CCM 0xC09C +#define TLS_RSA_WITH_AES_256_CCM 0xC09D +#define TLS_DHE_RSA_WITH_AES_128_CCM 0xC09E +#define TLS_DHE_RSA_WITH_AES_256_CCM 0xC09F +#define TLS_RSA_WITH_AES_128_CCM_8 0xC0A0 +#define TLS_RSA_WITH_AES_256_CCM_8 0xC0A1 +#define TLS_DHE_RSA_WITH_AES_128_CCM_8 0xC0A2 +#define TLS_DHE_RSA_WITH_AES_256_CCM_8 0xC0A3 + +#define SSL_PROTOCOL_UNKNOWN 0x00 +#define SSL_PROTOCOL_SSL_3_0 0x30 +#define SSL_PROTOCOL_TLS_1_0 0x31 +#define SSL_PROTOCOL_TLS_1_1 0x32 +#define SSL_PROTOCOL_TLS_1_2 0x33 + +#define ATH_ETH_P_PAE 0x888E + +#define ATH_MAX_ROUTES 3 +/****************************************************************************** + * ***************************** CAUTION ****************************** + * THESE DATA STRUCTURES ARE USED BY FIRMWARE ALSO. MAKE SURE THAT BOTH ARE IN + * SYNCH WHEN YOU MODIFY THESE. + ******************************************************************************/ + +typedef PREPACK struct ip6_addr +{ + uint8_t s6_addr[16]; /* 128 bit IPv6 address */ +} POSTPACK IP6_ADDR_T; + +typedef PREPACK struct ip_addr +{ + uint32_t s_addr; +} POSTPACK IP_ADDR_T; + +typedef PREPACK struct sockaddr_4 +{ /// E.Y. add _4 + uint16_t sin_port FIELD_PACKED; // Port number + uint16_t sin_family FIELD_PACKED; // ATH_AF_INET + IP_ADDR_T sin_addr FIELD_PACKED; // IPv4 Address +} POSTPACK SOCKADDR_T; + +typedef PREPACK struct sockaddr_6 +{ + uint16_t sin6_family FIELD_PACKED; // ATH_AF_INET6 + uint16_t sin6_port FIELD_PACKED; // transport layer port # + uint32_t sin6_flowinfo FIELD_PACKED; // IPv6 flow information + IP6_ADDR_T sin6_addr FIELD_PACKED; // IPv6 address + uint32_t sin6_scope_id FIELD_PACKED; // set of interfaces for a scope +} POSTPACK SOCKADDR_6_T; + +typedef PREPACK struct _ip_mreq +{ + uint32_t imr_multiaddr FIELD_PACKED; // Multicast group address + uint32_t imr_interface FIELD_PACKED; // Interface address +} POSTPACK IP_MREQ_T; + +typedef PREPACK struct _ipv6_mreq +{ + IP6_ADDR_T ipv6mr_multiaddr FIELD_PACKED; /* IPv6 multicast addr */ + IP6_ADDR_T ipv6mr_interface FIELD_PACKED; /* IPv6 interface address */ +} POSTPACK IPV6_MREQ_T; + +enum SOCKET_TYPE +{ + SOCK_STREAM_TYPE = 1, /* TCP */ + SOCK_DGRAM_TYPE, /* UDP */ + SOCK_RAW_TYPE /* IP */ +}; + +enum IPCONFIG_MODE +{ + IPCFG_QUERY = 0, /*Retrieve IP parameters*/ + IPCFG_STATIC, /*Set static IP parameters*/ + IPCFG_DHCP, /*Run DHCP client*/ + IPCFG_AUTO, /*Run AUTO IP*/ +}; + +typedef PREPACK struct +{ + uint32_t length; + uint32_t resp_code; + uint32_t flags; + uint8_t data[1]; +} POSTPACK HTTPC_RESPONSE; + +enum DNSC_CMDS +{ + + GETHOSTBYNAME = 0, + GETHOSTBYNAME2, + RESOLVEHOSTNAME +}; + +/* HTTP Server socket command MACROS*/ +#define HTTP_UNKNOWN -1 +#define HTTP_SERVER_STOP 0 +#define HTTP_SERVER_START 1 +#define HTTPS_SERVER_STOP 2 +#define HTTPS_SERVER_START 3 + +/* HTTP Server Get/Post socket MACROS */ +#define HTTP_GET_METHOD 0 +#define HTTP_POST_METHOD 1 + +enum +{ + /* Host command macros */ + HTTPC_CONNECT_CMD, + HTTPC_GET_CMD, + HTTPC_POST_CMD, + HTTPC_DATA_CMD, + HTTPC_DISCONNECT_CMD, + HTTPC_CONNECT_SSL_CMD +}; + +enum +{ + ROUTE_ADD, + ROUTE_DEL, + ROUTE_SHOW, + ROUTE_MAX +}; + +#define GET_TLV_TYPE(x, y) (A_MEMCPY(&(y), (x), sizeof(uint16_t))) +#define GET_TLV_LENGTH(x, y) (A_MEMCPY(&(y), (x + 2), sizeof(uint16_t))) +#define GET_NEXT_TLV(x, y) ((x) + sizeof(uint16_t) + sizeof(uint16_t) + (y)) +#define GET_TLV_VAL(x) ((x) + sizeof(uint16_t) + sizeof(uint16_t)) + +enum WI_POST_EVENT_TLV_TYPE +{ + POST_TYPE_URI, + POST_TYPE_NAME, + POST_TYPE_VALUE +}; + +typedef struct +{ + uint32_t numTLV; /*Number of TLVs encapsulated in the event*/ + uint8_t data[1]; /*Start of TLV data*/ // TODO: original has size = 0 +} HTTP_POST_EVENT_T; + +#define MAX_DNSADDRS 3 +#define MAX_SNTP_SERVERS 2 +#define DNS_NAME_NOT_SPECIFIED 0 + +typedef PREPACK struct dnccfgcmd +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + uint32_t mode FIELD_PACKED; // 0-gethostbyname, 1-gethostbyname2, 2-resolvehostname + uint32_t domain FIELD_PACKED; // AF_INET ,AF_INET6 + uint8_t ahostname[255]; + FIELD_PACKED +} POSTPACK DNC_CFG_CMD; + +typedef PREPACK struct dncrespinfo +{ + char dns_names[64] FIELD_PACKED; /* Buffer of names (usually w/domain) */ + int32_t h_length; + FIELD_PACKED /* Length of the address */ + int32_t h_addrtype FIELD_PACKED; // host address type + int32_t ipaddrs FIELD_PACKED; // count of entries in ipaddr_list + uint32_t ipaddrs_list[MAX_DNSADDRS] FIELD_PACKED; // list of ipv4 address + int32_t ip6addrs FIELD_PACKED; // count of ip6 entries in ip6addr_list + IP6_ADDR_T ip6addrs_list[MAX_DNSADDRS] FIELD_PACKED; // list of ip6 address + +} POSTPACK DNC_RESP_INFO; + +typedef PREPACK struct ip46addr +{ + uint8_t type FIELD_PACKED; + uint8_t au1Rsvd[3] FIELD_PACKED; + uint32_t addr4 FIELD_PACKED; + IP6_ADDR_T addr6 FIELD_PACKED; +} POSTPACK IP46ADDR; + +typedef struct sntp_time +{ + int32_t Sec FIELD_PACKED; + int32_t min FIELD_PACKED; + int32_t hour FIELD_PACKED; + int32_t mon FIELD_PACKED; + int32_t year FIELD_PACKED; + int32_t wday FIELD_PACKED; + int32_t yday FIELD_PACKED; +} POSTPACK tSntpTime; + +typedef PREPACK struct sntp_tm +{ + uint32_t tv_sec FIELD_PACKED; /* seconds */ + uint32_t tv_usec FIELD_PACKED; /* and microseconds */ +} POSTPACK tSntpTM; + +typedef PREPACK struct sntp_dns_addr +{ + uint8_t addr[68] FIELD_PACKED; + uint8_t resolve FIELD_PACKED; +} POSTPACK tSntpDnsAddr; + +typedef PREPACK struct IPv4Route +{ + uint32_t reserved FIELD_PACKED; + uint32_t address FIELD_PACKED; + uint32_t mask FIELD_PACKED; + uint32_t gateway FIELD_PACKED; + uint32_t ifIndex FIELD_PACKED; + uint32_t prot FIELD_PACKED; +} POSTPACK IPV4_ROUTE_T; + +typedef PREPACK struct IPv4RouteLists +{ + uint32_t rtcount FIELD_PACKED; + IPV4_ROUTE_T route[ATH_MAX_ROUTES] FIELD_PACKED; +} POSTPACK IPV4_ROUTE_LIST_T; + +typedef PREPACK struct IPv6Route +{ + uint32_t command FIELD_PACKED; + uint8_t address[16] FIELD_PACKED; + int32_t prefixlen FIELD_PACKED; + uint8_t nexthop[16] FIELD_PACKED; + uint32_t ifindex; + uint32_t prot; +} POSTPACK IPV6_ROUTE_T; + +typedef PREPACK struct IPv6RouteLists +{ + uint32_t rtcount FIELD_PACKED; + IPV6_ROUTE_T route[ATH_MAX_ROUTES] FIELD_PACKED; +} POSTPACK IPV6_ROUTE_LIST_T; + +#define MAX_OTA_AREA_READ_SIZE 1024 +typedef struct ota_upgrade_resp +{ + uint32_t resp_code; + uint32_t size; +} tOtaUpgradeResp; + +typedef PREPACK struct ota_info +{ + uint32_t resp_code; + uint32_t size; + uint8_t *data; +} POSTPACK tOtaReadResp; + +typedef PREPACK struct ota_done +{ + uint32_t resp_code; +} POSTPACK tOtaDoneResp; + +typedef struct ota_response_s +{ + uint32_t resp_code; +} POSTPACK tOtaResp; + +typedef struct ota_partition_get_size_response_s +{ + uint32_t resp_code; + uint32_t size; +} POSTPACK tOtaPartitionGetSizeResp; + +typedef struct ota_parse_image_hdr_response_s +{ + uint32_t resp_code; + uint32_t offset; +} POSTPACK tOtaParseImageHdrResp; + +typedef struct ota_partition_write_data_response_s +{ + uint32_t resp_code; + uint32_t size; +} POSTPACK tOtaPartitionWriteDataResp; + +typedef enum OTA_STATUS +{ + QCOM_OTA_OK = 0, + QCOM_OTA_COMPLETED = 1, + QCOM_OTA_FLASH_AUTH_PENDING = 3, + + QCOM_OTA_ERR_UNKOWN_MSG = 1000, + QCOM_OTA_ERR_IMAGE_NOT_FOUND = 1001, + QCOM_OTA_ERR_IMAGE_DOWNLOAD_FAIL = 1002, + QCOM_OTA_ERR_IMAGE_CHECKSUM_INCORRECT = 1003, + QCOM_OTA_ERR_SERVER_RSP_TIMEOUT = 1004, + QCOM_OTA_ERR_INVALID_FILENAME = 1005, + QCOM_OTA_ERR_UNSUPPORT_PROTOCOL = 1006, + QCOM_OTA_ERR_INVALID_PARTITION_INDEX = 1007, + QCOM_OTA_ERR_IMAGE_HDR_INCORRECT = 1008, + QCOM_OTA_ERR_INSUFFICIENT_MEMORY = 1009, + QCOM_OTA_ERR_PRESERVE_LAST_FAILED = 1010, + QCOM_OTA_ERR_NO_ACTIVE_OTA_SESSION = 1011, + QCOM_OTA_ERR_INVALID_PARTITION_ACESS = 1012, + QCOM_OTA_ERR_OTA_SESS_IN_PROGRESS = 1013, + QCOM_OTA_ERR_FLASH_READ_TIMEOUT = 1014, + QCOM_OTA_ERR_FLASH_ERASE_ERROR = 1015, + QCOM_OTA_ERR_IMAGE_OVERFLOW = 1016, + QCOM_OTA_ERR_IMAGE_UNDERFLOW = 1017, + QCOM_OTA_ERR_WRITE_DATA_ERROR = 1018, +} QCOM_OTA_STATUS_CODE_t; + +enum SslErrors +{ + ESSL_OK = 0, // success + ESSL_INVAL = -1, // Invalid argument + ESSL_NOSOCKET = -2, // No more SSL socket descriptors available + ESSL_HSNOTDONE = -3, // Handshake not done + ESSL_HSDONE = -4, // Handshake already done + ESSL_NOMEM = -5, // Out of memory + ESSL_CONN = -6, // SharkSslCon_Error + ESSL_CERT = -7, // SharkSslCon_CertificateError + ESSL_ALERTRECV = -8, // SharkSslCon_AlertRecv + ESSL_ALERTFATAL = -9, // SharkSslCon_AlertSend FATAL received. Connection must be closed. + ESSL_TIMEOUT = -10, // Timeout during handshake + ESSL_OOPS = -29, // Oops (something is terribly wrong) + ESSL_OK_HANDSHAKE = -32, // handshake complete (internal reason code, not an error) + + // Following TRUST reason codes are returned by sslValidate() + + /** The peer's SSL certificate is trusted, CN matches the host name, time is valid */ + ESSL_TRUST_CertCnTime = -32, // Same as ESSL_OK_HANDSHAKE + /** The peer's SSL certificate is trusted, CN matches the host name, time is expired */ + ESSL_TRUST_CertCn = -33, // name OK, time NOTOK + /** The peer's SSL certificate is trusted, CN does NOT match the host name, time is valid */ + ESSL_TRUST_CertTime = -34, // name NOTOK, time OK + /** The peer's SSL certificate is trusted, CN does NOT match host name, time is expired */ + ESSL_TRUST_Cert = -35, // name NOTOK, time NOTOK + /** The peer's SSL certificate is NOT trusted */ + ESSL_TRUST_None = -36, +}; + +typedef void SSL_CTX; +typedef void SSL; +typedef const uint8_t *SslCert; +typedef const uint8_t *SslCAList; + +typedef enum +{ + SSL_SERVER = 1, + SSL_CLIENT_2 = 2 // rocky: conflicts with AliOS's sal definition +} SSL_ROLE_T; + +typedef enum +{ + SSL_CERTIFICATE = 1, + SSL_CA_LIST = 2 +} SSL_CERT_TYPE_T; + +typedef PREPACK struct sslVerifyPolicy +{ + /** True to verify certificate commonName against peer's domain name */ + uint8_t domain FIELD_PACKED; + /** True to verify certificate time validity */ + uint8_t timeValidity FIELD_PACKED; + /** True to immediately send a fatal alert on detection of untrusted certificate */ + uint8_t sendAlert FIELD_PACKED; + /** Reserved */ + uint8_t reserved FIELD_PACKED; +} POSTPACK SSL_VERIFY_POLICY; + +#define SSL_CIPHERSUITE_LIST_DEPTH 8 +typedef PREPACK struct SSL_config +{ + uint16_t protocol FIELD_PACKED; + uint16_t cipher[SSL_CIPHERSUITE_LIST_DEPTH] FIELD_PACKED; + SSL_VERIFY_POLICY verify FIELD_PACKED; + char matchName[40] FIELD_PACKED; +} POSTPACK SSL_CONFIG; + +typedef PREPACK struct ssl_file_name_list +{ + uint8_t name[10][20] FIELD_PACKED; // The file names of the certificates or CA lists +} POSTPACK SSL_FILE_NAME_LIST; + +#if ZERO_COPY +void zero_copy_free(void *buffer); +#endif + +int32_t t_socket(QCA_CONTEXT_STRUCT_PTR qca_ptr, uint32_t domain, uint32_t type, uint32_t protocol); +int32_t t_shutdown(QCA_CONTEXT_STRUCT_PTR qca_ptr, uint32_t handle); +int32_t t_connect(QCA_CONTEXT_STRUCT_PTR qca_ptr, uint32_t handle, void *name, uint16_t length); +int32_t t_bind(QCA_CONTEXT_STRUCT_PTR qca_ptr, uint32_t handle, void *name, uint16_t length); +int32_t t_listen(QCA_CONTEXT_STRUCT_PTR qca_ptr, uint32_t handle, uint32_t backlog); +int32_t t_accept(QCA_CONTEXT_STRUCT_PTR qca_ptr, uint32_t handle, void *name, socklen_t length); +int32_t t_sendto(QCA_CONTEXT_STRUCT_PTR qca_ptr, + uint32_t handle, + uint8_t *buffer, + uint32_t length, + uint32_t flags, + void *name, + uint32_t socklength); +int32_t t_send(QCA_CONTEXT_STRUCT_PTR qca_ptr, uint32_t handle, uint8_t *buffer, uint32_t length, uint32_t flags); + +#if T_SELECT_VER1 +int32_t t_accept_nb(QCA_CONTEXT_STRUCT_PTR qca_ptr, uint32_t handle, void *name, socklen_t length); +#endif +int32_t t_setsockopt(QCA_CONTEXT_STRUCT_PTR qca_ptr, + uint32_t handle, + uint32_t level, + uint32_t optname, + uint8_t *optval, + uint32_t optlen); +int32_t t_getsockopt(QCA_CONTEXT_STRUCT_PTR qca_ptr, + uint32_t handle, + uint32_t level, + uint32_t optname, + uint8_t *optval, + uint32_t optlen); + +#if ZERO_COPY +int32_t t_recvfrom(QCA_CONTEXT_STRUCT_PTR qca_ptr, + uint32_t handle, + void **buffer, + uint32_t length, + uint32_t flags, + void *name, + socklen_t *socklength); +int32_t t_recv(QCA_CONTEXT_STRUCT_PTR qca_ptr, uint32_t handle, void **buffer, uint32_t length, uint32_t flags); +#else +int32_t t_recvfrom(QCA_CONTEXT_STRUCT_PTR qca_ptr, + uint32_t handle, + void *buffer, + uint32_t length, + uint32_t flags, + void *name, + socklen_t *socklength); +int32_t t_recv(QCA_CONTEXT_STRUCT_PTR qca_ptr, uint32_t handle, void *buffer, uint32_t length, uint32_t flags); +#endif +int32_t t_select(QCA_CONTEXT_STRUCT_PTR qca_ptr, uint32_t handle, uint32_t tv); + +#if T_SELECT_VER1 +int32_t FD_IsSet(uint32_t handle, uint32_t mask); +int32_t FD_Set(uint32_t handle, uint32_t *mask); +int32_t FD_Clr(uint32_t handle, uint32_t *mask); +int32_t FD_Zero(uint32_t *mask); + +int32_t t_select_ver1( + QCA_CONTEXT_STRUCT_PTR qca_ptr, int32_t num, uint32_t *r_fd, uint32_t *w_fd, uint32_t *e_fd, uint32_t tv); +#endif // T_SELECT_VER1 + +int32_t t_errno(QCA_CONTEXT_STRUCT_PTR qca_ptr, uint32_t handle); +A_STATUS t_ipconfig(void *handle, + uint32_t mode, + uint32_t *ipv4_addr, + uint32_t *subnetMask, + uint32_t *gateway4, + IP46ADDR *Dnsaddr, + char *hostname); +A_STATUS t_ping(QCA_CONTEXT_STRUCT_PTR qca_ptr, uint32_t ipv4_addr, uint32_t size); +A_STATUS t_ping6(QCA_CONTEXT_STRUCT_PTR qca_ptr, uint8_t *ip6addr, uint32_t size); +A_STATUS t_ip6config(QCA_CONTEXT_STRUCT_PTR qca_ptr, + uint32_t mode, + IP6_ADDR_T *v6Global, + IP6_ADDR_T *v6Local, + IP6_ADDR_T *v6DefGw, + IP6_ADDR_T *v6GlobalExtd, + int32_t *LinkPrefix, + int32_t *GlbPrefix, + int32_t *DefGwPrefix, + int32_t *GlbPrefixExtd); +int32_t t_ipconfig_dhcp_pool(QCA_CONTEXT_STRUCT_PTR qca_ptr, + uint32_t *start_ipv4_addr, + uint32_t *end_ipv4_addr, + int32_t leasetime); +int32_t t_ipconfig_dhcps_cb_enable(QCA_CONTEXT_STRUCT_PTR qca_ptr, void *callback); +int32_t t_ipconfig_dhcpc_cb_enable(QCA_CONTEXT_STRUCT_PTR qca_ptr, void *callback); +A_STATUS t_ip6config_router_prefix(QCA_CONTEXT_STRUCT_PTR qca_ptr, + IP6_ADDR_T *v6addr, + int32_t prefixlen, + int32_t prefix_lifetime, + int32_t valid_lifetime); +A_STATUS custom_ipbridgemode(void *handle, uint16_t status); +A_STATUS custom_ipconfig_set_tcp_exponential_backoff_retry(QCA_CONTEXT_STRUCT_PTR qca_ptr, int32_t retry); +int32_t custom_ipconfig_set_ip6_status(QCA_CONTEXT_STRUCT_PTR qca_ptr, uint16_t status); +A_STATUS custom_ipconfig_dhcp_release(QCA_CONTEXT_STRUCT_PTR qca_ptr); +A_STATUS custom_ipconfig_set_tcp_rx_buffer(QCA_CONTEXT_STRUCT_PTR qca_ptr, int32_t rxbuf); +A_STATUS custom_ip_http_server(void *handle, int32_t command); +A_STATUS custom_ip_http_server_method(void *handle, + int32_t command, + uint8_t *pagename, + uint8_t *objname, + int32_t objtype, + int32_t objlen, + uint8_t *value); +int32_t custom_http_set_post_cb(void *handle, void *cxt, void *callback); + +#if ENABLE_DNS_CLIENT +int32_t custom_ip_set_dns_block_time(void *handle, int32_t blockSec); +int32_t custom_ip_resolve_hostname(void *handle, DNC_CFG_CMD *DncCfg, DNC_RESP_INFO *DncRespInfo); +int32_t custom_ip_dns_client(void *handle, int32_t command); +int32_t custom_ip_dns_server_addr(void *handle, IP46ADDR *addr); +#endif +int32_t custom_ip_hostname(void *handle, char *domain_name); +#if ENABLE_DNS_SERVER +int32_t custom_ip_dns_local_domain(void *handle, char *domain_name); +int32_t custom_ipsetdns(void *handle, int32_t command, char *domain_name, IP46ADDR *dnsaddr); +int32_t custom_ip_dns_server(void *handle, uint32_t command); +int32_t custom_ipdns(void *handle, int32_t command, char *domain_name, IP46ADDR *dnsaddr); +#endif +#if ENABLE_SNTP_CLIENT +int32_t custom_ip_sntp_srvr_addr(void *handle, int32_t command, char *sntp_srvr_addr); +int32_t custom_ip_sntp_get_time(void *handle, tSntpTime *SntpTime); +int32_t custom_ip_sntp_get_time_of_day(void *handle, tSntpTM *SntpTm); +int32_t custom_ip_sntp_modify_zone_dse(void *handle, uint8_t hour, uint8_t min, uint8_t add_sub, uint8_t dse); +int32_t custom_ip_sntp_query_srvr_address(void *handle, tSntpDnsAddr SntpDnsAddr[MAX_SNTP_SERVERS]); +int32_t custom_ip_sntp_client(void *handle, int32_t command); +#endif +#if ENABLE_HTTP_CLIENT +A_STATUS custom_httpc_method(void *a_handle, uint32_t command, uint8_t *url, uint8_t *data, uint8_t **output); +#endif /* ENABLE_HTTP_CLIENT */ +void zero_copy_http_free(void *buffer); +#if ENABLE_ROUTING_CMDS +A_STATUS custom_ipv4_route(void *handle, + uint32_t command, + IP_ADDR_T *ipv4_addr, + IP_ADDR_T *subnetMask, + IP_ADDR_T *gateway, + uint32_t *ifIndex, + IPV4_ROUTE_LIST_T *routelist); +A_STATUS custom_ipv6_route(void *handle, + uint32_t command, + IP6_ADDR_T *ipv6_addr, + uint32_t *prefixLen, + IP6_ADDR_T *gateway, + uint32_t *ifIndex, + IPV6_ROUTE_LIST_T *routelist); +#endif +A_STATUS custom_tcp_connection_timeout(void *handle, uint32_t timeout_val); + +int32_t custom_ota_upgrade(void *handle, + uint32_t addr, + char *filename, + uint8_t mode, + uint8_t preserve_last, + uint8_t protocol, + uint32_t *resp_code, + uint32_t *length); +int32_t custom_ota_read_area(void *handle, uint32_t offset, uint32_t size, uint8_t *buffer, uint32_t *retlen); +int32_t custom_ota_done(void *handle, boolean good_image); +int32_t custom_ota_session_start(void *handle, uint32_t flags, uint32_t partition_index); +uint32_t custom_ota_partition_get_size(void *handle); +int32_t custom_ota_partition_erase(void *handle); +int32_t custom_ota_partition_verify_checksum(void *handle); +int32_t custom_ota_parse_image_hdr(void *handle, uint8_t *header, uint32_t *offset); +int32_t custom_ota_partition_write_data(void *handle, uint32_t offset, uint8_t *buf, uint32_t size, uint32_t *ret_size); +int32_t custom_ota_set_response_cb(void *handle, void *callback); + +/***************************************************************************************************/ + +void *custom_alloc(uint32_t size); +void custom_free(void *buf); + +#if ENABLE_SSL +SSL_CTX *SSL_ctx_new(SSL_ROLE_T role, int32_t inbufSize, int32_t outbufSize, int32_t reserved); +int32_t SSL_ctx_free(SSL_CTX *ctx); +SSL *SSL_new(SSL_CTX *ctx); +int32_t SSL_setCaList(SSL_CTX *ctx, SslCAList caList, uint32_t size); +int32_t SSL_addCert(SSL_CTX *ctx, SslCert cert, uint32_t size); +int32_t SSL_storeCert(char *name, SslCert cert, uint32_t size); +int32_t SSL_loadCert(SSL_CTX *ctx, SSL_CERT_TYPE_T type, char *name); +int32_t SSL_listCert(SSL_FILE_NAME_LIST *fileNames); + +int32_t SSL_set_fd(SSL *ssl, uint32_t fd); +int32_t SSL_accept(SSL *ssl); +int32_t SSL_connect(SSL *ssl); +int32_t SSL_shutdown(SSL *ssl); +int32_t SSL_configure(SSL *ssl, SSL_CONFIG *cfg); + +#if ZERO_COPY +int32_t SSL_read(SSL *ssl, void **buf, int32_t num); +#else +int32_t SSL_read(SSL *ssl, void *buf, int32_t num); +#endif +int32_t SSL_write(SSL *ssl, const void *buf, int32_t num); +#endif +#else // ENABLE_STACK_OFFLOAD +//typedef PREPACK struct ip6_addr +//{ +// uint8_t addr[16]; /* 128 bit IPv6 address */ +//} POSTPACK IP6_ADDR_T; +#endif // ENABLE_STACK_OFFLOAD +#endif diff --git a/platform/mcu/lpc54102/wifi_qca/atheros_wifi.h b/platform/mcu/lpc54102/wifi_qca/atheros_wifi.h new file mode 100644 index 0000000000..a7d48996f0 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/atheros_wifi.h @@ -0,0 +1,58 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== +#ifndef __ATHEROS_WIFI_H__ +#define __ATHEROS_WIFI_H__ + +/* PORT_NOTE: atheros_wifi.h is intended to provide any system specific data + * structures and definitions required by the OS for a WIFI/Ethernet driver. + * Hence everything in this file is Customized to the requirements of the + * host OS. */ + +#include + +#include + +// ============================================================================ +// This is the ONLY place where the enet.h header files are included! +// ============================================================================ + +// typedef struct wlan_hardware_config_s { +//// /// The SPI bus instance number. Usually 0 or 1 +//// int spi_instance; +//// /// The SPI chip select (dspi_which_pcs_config_t) +//// int spi_cs; +//// /// The SPI baudrate +//// uint32_t spi_baudrate; +//// +//// /// The WLAN interrupt's IRQ number from the IRQn enum in MK22F51212.h (or similar) +//// int wlan_irq_number; +//// /// The GPIO ping used for power control of the WLAN chip, e.g. GPIO_MAKE_PIN(GPIOB_IDX, 19) +//// int wlan_power_pin; +//} wlan_hardware_config_t; + +#include "qca_structs.h" + +#endif /* __ATHEROS_WIFI_H__ */ diff --git a/platform/mcu/lpc54102/wifi_qca/atheros_wifi_api.h b/platform/mcu/lpc54102/wifi_qca/atheros_wifi_api.h new file mode 100644 index 0000000000..230bf3a128 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/atheros_wifi_api.h @@ -0,0 +1,575 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== +#ifndef __ATHEROS_WIFI_API_H__ +#define __ATHEROS_WIFI_API_H__ + +/* PORT_NOTE: atheros_wifi_api.h is intended to expose user level API's and + * data structures. These structures provide access to the driver that + * would not otherwise be provided by the system's existing driver interface. + * It is imagined that the existing driver interface would have some form + * of IO_CTRL API with pre-defined commands. These commands are intended to + * extend those provided by the default. It is further imagined that in + * such a system the developer would add an IO_CTRL for Vendor specific + * commands which would act as a wrapper for the ath_ioctl_cmd commands + * defined below. */ + +#include + +enum ath_ioctl_cmd +{ + ATH_SET_TXPWR, + ATH_SET_PMPARAMS, + ATH_SET_LISTEN_INT, + ATH_SET_CIPHER, + ATH_SET_SEC_MODE, + ATH_SET_PHY_MODE, + ATH_GET_PHY_MODE, + ATH_GET_RX_RSSI, /* output uint32_t */ + ATH_SET_CONNECT_STATE_CALLBACK, /* input ATH_CONNECT_CB */ + ATH_DEVICE_SUSPEND_ENABLE, /* input NONE */ + ATH_DEVICE_SUSPEND_START, /* */ + ATH_SET_PMK, + ATH_GET_PMK, + ATH_GET_VERSION, + ATH_START_WPS, + ATH_AWAIT_WPS_COMPLETION, + ATH_SCAN_CTRL, + ATH_CHIP_STATE, + ATH_MAC_TX_RAW, + ATH_SET_CHANNEL, + ATH_SET_AGGREGATION, + ATH_ASSERT_DUMP, + ATH_SET_SSID, + ATH_SET_CONNECT, + ATH_SET_SEC_TYPE, + ATH_SET_COMMIT, + ATH_SET_MODE, + ATH_SET_FREQ, + ATH_SET_RTS, + ATH_SET_PASSPHRASE, + ATH_SET_SCAN, + ATH_GET_SCAN_RESULTS, + ATH_SET_ENCODE, + ATH_SET_POWER, + ATH_GET_POWER, + ATH_GET_ESSID, + ATH_GET_SEC_TYPE, + ATH_PROGRAM_FLASH, + ATH_EXECUTE_FLASH, + ATH_GET_MACADDR, + ATH_IS_DRIVER_INITIALIZED, + ATH_GET_TX_STATUS, + ATH_SET_PROMISCUOUS_MODE, + ATH_GET_REG_DOMAIN, + ATH_START_SCAN_EXT, + ATH_GET_SCAN_EXT, + ATH_GET_LAST_ERROR, + ATH_GET_CHANNEL, + ATH_CONFIG_AP, + ATH_P2P_CONNECT, + ATH_P2P_CONNECT_CLIENT, + ATH_P2P_FIND, + ATH_P2P_LISTEN, + ATH_P2P_CANCEL, + ATH_P2P_STOP, + ATH_P2P_JOIN, + ATH_P2P_NODE_LIST, + ATH_P2P_SET_CONFIG, + ATH_P2P_WPS_CONFIG, + ATH_P2P_AUTH, + ATH_P2P_DISC_REQ, + ATH_P2P_SET, + ATH_P2P_INVITE_AUTH, + ATH_P2P_PERSISTENT_LIST, + ATH_P2P_INVITE, + ATH_P2P_INV_CONNECT, + ATH_P2P_JOIN_PROFILE, + ATH_P2P_APMODE, + ATH_P2P_APMODE_PP, + ATH_P2P_SWITCH, + ATH_P2P_SET_NOA, + ATH_P2P_SET_OPPPS, + ATH_P2P_SDPD, + ATH_SET_P2P_CALLBACK, + ATH_P2P_EVENT_CALLBACK, + ATH_ONOFF_LPL, + ATH_ONOFF_GTX, + ATH_PROGRAM_MAC_ADDR, + ATH_GET_RATE, + ATH_SET_RATE, + ATH_HTC_REVERSE_CREDITS_INIT, + ATH_GPIO_CMD, + ATH_SET_TX_PWR_SCALE, + + ATH_PFM_CMD, + ATH_DIAG_CMD, + ATH_PMU_SET_PARAMS, + ATH_SET_DEVICE_ID, + ATH_GET_VERSION_STR, + ATH_GET_CONC_DEV_CHANNEL, + ATH_DSET_READ_CMD, + ATH_DSET_WRITE_CMD, + + ATH_DSET_OP_CMD, + ATH_GET_TEMPERATURE, + ATH_ROAM_CTRL, + ATH_GET_CHANNELHINT, + ATH_SET_OP_MODE, + ATH_GET_OP_MODE, + ATH_SET_WEPKEY, + ATH_GET_WEPKEY, + ATH_SET_WEPINDEX, + ATH_GET_WEPINDEX, + ATH_SET_SCAN_PARAM, + ATH_SET_PARAM, + ATH_SET_PROBEREQ_CB, + ATH_SET_PROBEREQ_EV_ENABLE, + ATH_PROGRAM_COUNTRY_CODE, + ATH_GET_COUNTRY_CODE, + ATH_SET_APPIE, + ATH_WLAN_WPS_INIT_KEY, + ATH_HEARTBEAT_CHALLEANGE, + /************************************/ + /* add new commands above this line */ + /************************************/ + ATH_CMD_LAST /* NOTE: ensure that this is the last entry in the enum */ +}; + +// IEEE 802.11 channels in MHz Geographies where channel is allowed +#define ATH_IOCTL_FREQ_1 (2412) // USA, Canada, Europe, Japan +#define ATH_IOCTL_FREQ_2 (2417) // USA, Canada, Europe, Japan +#define ATH_IOCTL_FREQ_3 (2422) // USA, Canada, Europe, Japan +#define ATH_IOCTL_FREQ_4 (2427) // USA, Canada, Europe, Japan +#define ATH_IOCTL_FREQ_5 (2432) // USA, Canada, Europe, Japan +#define ATH_IOCTL_FREQ_6 (2437) // USA, Canada, Europe, Japan +#define ATH_IOCTL_FREQ_7 (2442) // USA, Canada, Europe, Japan +#define ATH_IOCTL_FREQ_8 (2447) // USA, Canada, Europe, Japan +#define ATH_IOCTL_FREQ_9 (2452) // USA, Canada, Europe, Japan +#define ATH_IOCTL_FREQ_10 (2457) // USA, Canada, Europe, Japan +#define ATH_IOCTL_FREQ_11 (2462) // USA, Canada, Europe, Japan +#define ATH_IOCTL_FREQ_12 (2467) // Europe, Japan +#define ATH_IOCTL_FREQ_13 (2472) // Europe, Japan +#define ATH_IOCTL_FREQ_14 (2484) // Japan +#define ATH_IOCTL_FREQ_36 (5180) // 11 A channels +#define ATH_IOCTL_FREQ_40 (5200) // 11 A channels +#define ATH_IOCTL_FREQ_44 (5220) // 11 A channels +#define ATH_IOCTL_FREQ_48 (5240) // 11 A channels +#define ATH_IOCTL_FREQ_52 (5260) // 11 A channels +#define ATH_IOCTL_FREQ_56 (5280) // 11 A channels +#define ATH_IOCTL_FREQ_60 (5300) // 11 A channels +#define ATH_IOCTL_FREQ_64 (5320) // 11 A channels +#define ATH_IOCTL_FREQ_100 (5500) // 11 A channels +#define ATH_IOCTL_FREQ_104 (5520) // 11 A channels +#define ATH_IOCTL_FREQ_108 (5540) // 11 A channels +#define ATH_IOCTL_FREQ_112 (5560) // 11 A channels +#define ATH_IOCTL_FREQ_116 (5580) // 11 A channels +#define ATH_IOCTL_FREQ_132 (5660) // 11 A channels +#define ATH_IOCTL_FREQ_136 (5680) // 11 A channels +#define ATH_IOCTL_FREQ_140 (5700) // 11 A channels +#define ATH_IOCTL_FREQ_149 (5745) // 11 A channels +#define ATH_IOCTL_FREQ_153 (5765) // 11 A channels +#define ATH_IOCTL_FREQ_157 (5785) // 11 A channels +#define ATH_IOCTL_FREQ_161 (5805) // 11 A channels +#define ATH_IOCTL_FREQ_165 (5825) // 11 A channels + +#define ATH_PMK_LEN (32) +#define ATH_PASSPHRASE_LEN (64) +#define ATH_MAX_SSID_LENGTH (32) +#define ATH_MAX_SCAN_CHANNELS (16) +#define ATH_MAX_SCAN_BUFFERS (12) + +#if DRIVER_CONFIG_ENABLE_STORE_RECALL +#define STORE_RECALL_BUF_SIZE (1400) // If store-recall is enabled, allocate shared buffer +// big enough to hold 1400 bytes of target data +#else +#define STORE_RECALL_BUF_SIZE (0) +#endif + +#define ATH_WPS_PIN_LEN (9) +#define ATH_WPS_MODE_PIN (1) +#define ATH_WPS_MODE_PUSHBUTTON (2) +#define WEP_SHORT_KEY (5) +#define WEP_LONG_KEY (13) +#define ATH_ACTIVE_CHAN_DWELL_TIME (60) // Max Dwell time per channel + +/*Structure definition for passing Atheros specific data from App*/ +typedef struct ath_ioctl_params +{ + uint16_t cmd_id; + void *data; + uint16_t length; +} ATH_IOCTL_PARAM_STRUCT, *ATH_IOCTL_PARAM_STRUCT_PTR; + +typedef struct ath_scan_list +{ + uint32_t num_scan_entries; + void *scan_list; +} ATH_SCAN_LIST, *ATH_SCAN_LIST_PTR; + +typedef struct ath_ap_params +{ + uint16_t cmd_subset; + void *data; +} ATH_AP_PARAM_STRUCT, *ATH_AP_PARAM_STRUCT_PTR; + +// AP mode sub commands +#define AP_SUB_CMD_BCON_INT 0x0001 +#define AP_SUB_CMD_HIDDEN_FLAG 0x0002 +#define AP_SUB_CMD_INACT_TIME 0x0003 +#define AP_SUB_CMD_SET_COUNTRY 0x0004 +#define AP_SUB_CMD_WPS_FLAG 0x0005 +#define AP_SUB_CMD_DTIM_INT 0x0006 +#define AP_SUB_CMD_PSBUF 0x0007 +/* A-MPDU aggregation is enabled on a per TID basis where each TID (0-7) + * represents a different traffic priority. The mapping to WMM access categories + * is as follows; WMM Best effort = TID 0-1 + * WMM Background = TID 2-3 + * WMM Video = TID 4-5 + * WMM Voice = TID 6-7 + * Once enabled A-MPDU aggregation may be negotiated with an Access Point/Peer + * device and then both devices may optionally use A-MPDU aggregation for + * transmission. Due to other bottle necks in the data path a system may not + * get improved performance by enabling A-MPDU aggregation. + */ +typedef struct +{ + uint16_t txTIDMask; /* bit mask to enable tx A-MPDU aggregation */ + uint16_t rxTIDMask; /* bit mask to enable rx A-MPDU aggregation */ +} ATH_SET_AGGREGATION_PARAM; + +#define ATH_CIPHER_TYPE_TKIP 0x04 +#define ATH_CIPHER_TYPE_CCMP 0x08 +#define ATH_CIPHER_TYPE_WEP 0x02 + +typedef struct cipher +{ + uint32_t ucipher; + uint32_t mcipher; +} cipher_t; + +typedef void (*ATH_CONNECT_CB)(int value, uint8_t devId, uint8_t *bssid, boolean bssConn); +typedef void (*WMI_HTTP_POST_EVENT_CB)(void *cxt, void *buf); +typedef void (*ATH_OTA_CB)(uint32_t ota_cmd, uint32_t resp_code, uint32_t result); +typedef void (*ATH_PROBEREQ_CB)(void *buf, int len, int freq); + +typedef struct _wepkeys +{ + uint8_t defKeyIndex; /* tx key index */ + uint8_t keyLength; /* must be one of WEP_SHORT_KEY || WEP_LONG_KEY */ + uint8_t numKeys; /* how many of the 4 keys below are populated */ + char *keys[4]; /* keys */ +} ATH_WEPKEYS, *ATH_WEPKEYS_PTR; + +typedef struct +{ + uint8_t ssid[32]; + uint8_t macaddress[6]; + uint16_t channel; + uint8_t ssid_len; +} WPS_SCAN_LST_ENTRY; + +typedef struct +{ + uint32_t host_ver; + uint32_t target_ver; + uint32_t wlan_ver; + uint32_t abi_ver; +} ATH_VERSION, *ATH_VERSION_PTR; + +typedef struct +{ + uint8_t host_ver[20]; + uint8_t target_ver[20]; + uint8_t wlan_ver[20]; + uint8_t abi_ver[20]; +} ATH_VERSION_STR, *ATH_VERSION_STR_PTR; + +typedef struct _wps_start +{ + WPS_SCAN_LST_ENTRY ssid_info; + uint8_t wps_mode; /* ATH_WPS_MODE_PIN | ATH_WPS_MODE_PUSHBUTTON */ + uint8_t timeout_seconds; + uint8_t connect_flag; + uint8_t pin[ATH_WPS_PIN_LEN]; + uint8_t pin_length; +} ATH_WPS_START, *ATH_WPS_START_PTR; + +typedef struct +{ + uint16_t idle_period; /* msec */ + uint16_t pspoll_number; + uint16_t dtim_policy; /*IGNORE_DTIM = 0x01, NORMAL_DTIM = 0x02,STICK_DTIM = 0x03, AUTO_DTIM = 0x04*/ + uint16_t tx_wakeup_policy; /*TX_WAKEUP_UPON_SLEEP = 1,TX_DONT_WAKEUP_UPON_SLEEP = 2*/ + uint16_t num_tx_to_wakeup; + uint16_t + ps_fail_event_policy; /*SEND_POWER_SAVE_FAIL_EVENT_ALWAYS = 1,IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN = 2*/ +} ATH_WMI_POWER_PARAMS_CMD; + +typedef enum +{ + ATH_WPS_ERROR_INVALID_START_INFO = 0x1, + ATH_WPS_ERROR_MULTIPLE_PBC_SESSIONS, + ATH_WPS_ERROR_WALKTIMER_TIMEOUT, + ATH_WPS_ERROR_M2D_RCVD +} ATH_WPS_ERROR_CODE; + +#define ATH_WPS_ERROR_SUCCESS 0x00 +#define ATH_WPS_ERROR_INVALID_START_INFO 0x01 +#define ATH_WPS_ERROR_MULTIPLE_PBC_SESSIONS 0x02 +#define ATH_WPS_ERROR_WALKTIMER_TIMEOUT 0x03 +#define ATH_WPS_ERROR_M2D_RCVD 0x04 +#define ATH_WPS_ERROR_PWD_AUTH_FAIL 0x05 +#define ATH_WPS_ERROR_CANCELLED 0x06 +#define ATH_WPS_ERROR_INVALID_PIN 0x07 + +typedef struct +{ + uint16_t ap_channel; + int8_t ssid[ATH_MAX_SSID_LENGTH + 1]; /* [OUT] network ssid */ + int16_t ssid_len; /* [OUT] number of valid chars in ssid[] */ + cipher_t cipher; /* [OUT] network cipher type values not defined */ + uint8_t key_index; /* [OUT] for WEP only. key index for tx */ + union + {/* [OUT] security key or passphrase */ + uint8_t wepkey[ATH_PASSPHRASE_LEN + 1]; + uint8_t passphrase[ATH_PASSPHRASE_LEN + 1]; + } u; + + uint8_t sec_type; /* [OUT] security type; one of QCA_MEDIACTL_SECURITY_TYPE... */ + uint8_t error; /* [OUT] error code one of ATH_WPS_ERROR_... */ + uint8_t dont_block; /* [IN] 1 - returns immediately if operation is not complete. + * 0 - blocks until operation completes. */ +} ATH_NETPARAMS; + +#define ATH_DISABLE_BG_SCAN (0x00000001) +#define ATH_DISABLE_FG_SCAN (0x00000002) + +typedef struct +{ + uint32_t flags; +} ATH_SCANPARAMS; + +typedef struct ath_program_flash +{ + uint8_t *buffer; + uint32_t load_addr; + uint16_t length; + uint32_t result; +} ATH_PROGRAM_FLASH_STRUCT; + +/* ATH_MAC_TX_FLAG... are used as TX qualifiers for frames containing WMI_TX_RATE_SCHEDULE in the + * meta data. 0 or more of these flags should be assigned to the flags member of the schedule. */ +#define ATH_MAC_TX_FLAG_ACK 0x01 // frame needs ACK response from receiver +#define ATH_MAC_TX_FLAG_SET_RETRY_BIT 0x02 // device will set retry bit in MAC header for retried frames. +#define ATH_MAC_TX_FLAG_SET_DURATION 0x04 // device will fill duration field in MAC header + /* NOTE: If ATH_MAC_TX_FLAG_USE_PREFIX == 0 device will NOT use prefix frame. + * If ATH_MAC_TX_FLAG_USE_PREFIX == 1 && ATH_MAC_TX_FLAG_PREFIX_RTS == 0 device will use CTS prefix. + * If ATH_MAC_TX_FLAG_USE_PREFIX == 1 && ATH_MAC_TX_FLAG_PREFIX_RTS == 1 device will use RTS prefix. + */ +#define ATH_MAC_TX_FLAG_USE_PREFIX 0x08 // device will send either RTS or CTS frame prior to subject frame. +#define ATH_MAC_TX_FLAG_PREFIX_RTS 0x10 // device will send RTS and wait for CTS prior to sending subject frame. +#define ATH_MAC_TX_LOAD_TSF 0x20 // device will fill the TSF field during transmit procedure. + +#define ATH_ACCESS_CAT_BE 0 /* best effort */ +#define ATH_ACCESS_CAT_BK 1 /* background */ +#define ATH_ACCESS_CAT_VI 2 /* video */ +#define ATH_ACCESS_CAT_VO 3 /* voice */ + +/* set ar4XXX_boot_param according to the desired boot options */ +/* AR4XXX_PARAM_MODE_NORMAL - instructs chip to boot normally; load wlan firmware to provide + * WMI services used in normal WIFI operation. + * AR4XXX_PARAM_MODE_BMI - instructs chip to boot to BMI and await further BMI communication + * from host processor. This option can be used to re-program chip serial flash and + * perform other non-standard tasks. + * AR4XXX_PARAM_QUAD_SPI_FLASH - instructs the chip to access flash chip using QUAD mode + * this mode is faster than standard mode but the flash chip must support it. This + * option can be OR'd (|) with other options. + * AR4XXX_PARAM_RAWMODE_BOOT - instructs the chip to boot a firmware image that supports the + * RAW TX mode but lacks support for many other WMI commands. This mode will allow for + * a faster boot in those instances where the full set of WMI commands is not necessary. + * This mode must be OR'd with AR4XXX_PARAM_NORMAL_BOOT. + */ + +#define AR4XXX_PARAM_MODE_NORMAL (0x00000002) +#define AR4XXX_PARAM_MODE_BMI (0x00000003) +#define AR4XXX_PARAM_MODE_MASK (0x0000000f) +#define AR4XXX_PARAM_QUAD_SPI_FLASH (0x80000000) +#define AR4XXX_PARAM_RAWMODE_BOOT (0x00000010 | AR4XXX_PARAM_MODE_NORMAL) +#define AR4XXX_PARAM_MACPROG_MODE (0x00000020 | AR4XXX_PARAM_MODE_NORMAL) +#define AR4XXX_PARAM_MANUFAC_MODE (0x00000030 | AR4XXX_PARAM_MODE_NORMAL) +#define AR4XXX_PARAM_COUNTRY_CODE_MODE (0x00000010 | AR4XXX_PARAM_MODE_NORMAL) + +/* combined params for common cases */ +#define AR4XXX_PARAM_NORMAL_QUAD (AR4XXX_PARAM_MODE_NORMAL | AR4XXX_PARAM_QUAD_SPI_FLASH) +#define AR4XXX_PARAM_RAW_QUAD (AR4XXX_PARAM_RAWMODE_BOOT | AR4XXX_PARAM_QUAD_SPI_FLASH) + +/*The following regulatory domain settings can be passed to target during boot*/ + +#define AR4XXX_PARAM_REG_DOMAIN_DEFAULT (0x00000000) /*Default regulatory domain*/ +#define AR4XXX_PARAM_REG_DOMAIN_1 (0x00000100) /* FCC3_FCCA reg domain*/ +#define AR4XXX_PARAM_REG_DOMAIN_2 (0x00000200) /* ETSI1_WORLD reg domain*/ +#define AR4XXX_PARAM_REG_DOMAIN_3 (0x00000300) /* MKK5_MKKC reg domain */ + +/* ATH_MAC_TX_RATE_SCHEDULE - Acts as a host-provided rate schedule to replace what would be normally determined + * by firmware. This allows the host to specify what rates and attempts should be used to transmit the + * frame. */ +typedef struct +{ +#define ATH_MAC_TX_MAX_RATE_SERIES (4) + uint8_t rateSeries[ATH_MAC_TX_MAX_RATE_SERIES]; // rate index for each series. first invalid rate terminates series. + uint8_t trySeries[ATH_MAC_TX_MAX_RATE_SERIES]; // number of tries for each series. + uint8_t flags; // combination of ATH_MAC_TX_FLAG... + uint8_t accessCategory; // should be ATH_ACCESS_CAT_BE for managment frames and multicast frames. +} ATH_MAC_TX_RATE_SCHEDULE; + +typedef struct +{ + ATH_MAC_TX_RATE_SCHEDULE rateSched; + uint8_t pktID; /* The packet ID to identify the tx request */ +} ATH_MAC_TX_PARAMS; + +typedef struct ath_mac_tx_raw +{ + uint8_t *buffer; /* pointer to contiguous tx buffer */ + uint16_t length; /* valid length in bytes of tx buffer */ + ATH_MAC_TX_PARAMS params; /* params governing transmit rules */ +} ATH_MAC_TX_RAW_S; + +typedef struct ath_tx_status +{ +#define ATH_TX_STATUS_IDLE 0x01 /* the TX pipe is 100% idle */ +#define ATH_TX_STATUS_HOST_PENDING 0x02 /* the TX pipe has 1 or more frames waiting in the host queue */ +#define ATH_TX_STATUS_WIFI_PENDING 0x03 /* the TX pipe has 1 or more frames in process on the WIFI device */ + uint16_t status; /* one of ATH_TX_STATUS_ */ +} ATH_TX_STATUS; + +typedef void (*ATH_PROMISCUOUS_CB)(void *); + +typedef struct ath_prom_mode +{ + uint8_t src_mac[6]; /* filter source mac address if desired. */ + uint8_t dst_mac[6]; /* filter destination mac address if desired. */ + uint8_t enable; /* 0 to disable promiscuous mode 1 to enable. */ +#define ATH_PROM_FILTER_SOURCE 0x01 /* only allow frames whose source mac matches src_mac */ +#define ATH_PROM_FILTER_DEST 0x02 /* only allow frames whose destination mac matches dst_mac */ + uint8_t filter_flags; /* filtering rules */ + ATH_PROMISCUOUS_CB cb; /* callback function driver will use to feed rx frames */ +} ATH_PROMISCUOUS_MODE; + +typedef struct ath_reg_domain +{ + uint32_t domain; +} ATH_REG_DOMAIN; + +#define SECURITY_AUTH_PSK 0x01 +#define SECURITY_AUTH_1X 0x02 + +typedef struct ath_scan_ext +{ + uint8_t channel; + uint8_t ssid_len; + uint8_t rssi; + uint8_t security_enabled; + uint16_t beacon_period; + uint8_t preamble; + uint8_t bss_type; + uint8_t bssid[6]; + uint8_t ssid[32]; + uint8_t rsn_cipher; + uint8_t rsn_auth; + uint8_t wpa_cipher; + uint8_t wpa_auth; +} ATH_SCAN_EXT; + +typedef struct ath_get_scan +{ + uint16_t num_entries; + ATH_SCAN_EXT *scan_list; +} ATH_GET_SCAN; + +typedef struct ath_program_country_code_addr +{ + uint8_t countryCode[3]; + uint8_t result; +} ATH_PROGRAM_COUNTRY_CODE_PARAM; +/* these result codes are provided in the result field of the ATH_PROGRAM_COUNTRY_CODE_PARAM structure */ +/*ATH_PROGRAM_COUNTRY_CODE_RESULT_SUCCESS - +successfully programmed country code address into wifi device +*/ +#define ATH_PROGRAM_COUNTRY_CODE_RESULT_SUCCESS (1) +/*ATH_PROGRAM_ COUNTRY_CODE _RESULT_DEV_DENIED - +Device denied the operation for several possible reasons. +The most common reason for this result is that the country code equals +the current country code found already in the device. +Also an invalid country code value can cause this result +*/ +#define ATH_PROGRAM_COUNTRY_CODE_RESULT_DEV_DENIED (2) +/*ATH_PROGRAM_ COUNTRY_CODE _RESULT_DEV_FAILED - +An error occurred on the device as it tried to program the country code. +*/ +#define ATH_PROGRAM_COUNTRY_CODE_RESULT_DEV_FAILED (3) +/*ATH_PROGRAM_ COUNTRY_CODE _RESULT_DRIVER_FAILED - +Driver tried but failed to program country code. +Possibly the driver did not have the proper code compiled to perform this operation. +*/ +#define ATH_PROGRAM_COUNTRY_CODE_RESULT_DRIVER_FAILED (4) +typedef struct ath_program_mac_addr +{ + uint8_t addr[6]; + uint8_t result; +} ATH_PROGRAM_MAC_ADDR_PARAM; + +/* these result codes are provided in the result field of the ATH_PROGRAM_MAC_ADDR_PARAM structure */ +/*ATH_PROGRAM_MAC_RESULT_SUCCESS - successfully (re-)programmed mac address into wifi device*/ +#define ATH_PROGRAM_MAC_RESULT_SUCCESS (1) +/*ATH_PROGRAM_MAC_RESULT_DEV_DENIED - Device denied the operation for several possible reasons + * the most common reason for this result is that the mac address equals the current mac + * address found already in the device. Also an invalid mac address value can cause this result + */ +#define ATH_PROGRAM_MAC_RESULT_DEV_DENIED (2) +/*ATH_PROGRAM_MAC_RESULT_DEV_FAILED - Device tried but failed to program mac address. + * An error occurred on the device as it tried to program the mac address. + */ +#define ATH_PROGRAM_MAC_RESULT_DEV_FAILED (3) +/*ATH_PROGRAM_MAC_RESULT_DRIVER_FAILED - Driver tried but failed to program mac address + * Possibly the driver did not have the proper code compiled to perform this operation. + */ +#define ATH_PROGRAM_MAC_RESULT_DRIVER_FAILED (4) + +#define ATH_MAX_IE_LEN 64 + +typedef struct ath_appie +{ + uint8_t mgmtFrmType; + uint8_t ieLen; + uint8_t *ieInfo; +} ATH_APPIE_PARAM; + +/* ATH_API_... return values should be of type ATH_API_RETURN_CODE and + * should be modified to suit the host sytem. */ +#define ATH_API_OK A_OK +#define ATH_API_ERROR A_ERROR +#endif /* __ATHEROS_WIFI_H__ */ diff --git a/platform/mcu/lpc54102/wifi_qca/atheros_wifi_internal.h b/platform/mcu/lpc54102/wifi_qca/atheros_wifi_internal.h new file mode 100644 index 0000000000..621dcfc11a --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/atheros_wifi_internal.h @@ -0,0 +1,73 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== +#ifndef __ATHEROS_WIFI_INTERNAL_H__ +#define __ATHEROS_WIFI_INTERNAL_H__ + +#define ATH_PROG_FEEDBACK_BLANK_FLASH (0x00000001) +#define ATH_PROG_FEEDBACK_LOADING (0x00000002) +#define ATH_PROG_FEEDBACK_EXECUTING (0x00000003) +#define ATH_PROG_FEEDBACK_DONE (0x00000004) +#define ATH_PROG_FEEDBACK_LOAD_FAIL (0x00000005) +#define ATH_PROG_FEEDBACK_COMM_ERROR (0x00000006) + +typedef struct +{ + A_STATUS (*Driver_TargetConfig)(void *); + A_STATUS (*Driver_BootComm)(void *); + A_STATUS (*Driver_BMIConfig)(void *); + void (*Api_TxComplete)(void *, void *); + void (*Api_RxComplete)(void *, void *); + void (*Boot_Profile)(uint32_t val); + void (*Custom_Delay)(uint32_t delay); + void (*Api_GpioDataEventRx)(uint8_t *datap, uint32_t len); + void (*Custom_reset_measure_timer)(void); + void (*Custom_Api_PfmDataEventRx)(uint8_t *datap, uint32_t len); + void (*Custom_Api_PfmDataDoneEventRx)(void *, uint8_t *datap, uint32_t len); + A_STATUS (*Driver_StoreRecallFirmwareDownload)(void *pCxt); + boolean skipWmi; + boolean exitAtBmi; +} ATH_CUSTOM_INIT_T; + +extern ATH_CUSTOM_INIT_T ath_custom_init; + +typedef struct +{ + uint32_t (*ath_ioctl_handler_ext)(void *, ATH_IOCTL_PARAM_STRUCT_PTR); +} ATH_CUSTOM_MEDIACTL_T; + +extern ATH_CUSTOM_MEDIACTL_T ath_custom_mediactl; + +typedef struct +{ + A_STATUS (*HTCConnectServiceExch)(void*, HTC_SERVICE_CONNECT_REQ*, HTC_SERVICE_CONNECT_RESP*, + HTC_ENDPOINT_ID*, uint32_t*); + A_STATUS (*HTCSendSetupComplete)(void *); + A_STATUS (*HTCGetReady)(void *); +} ATH_CUSTOM_HTC_T; + +extern ATH_CUSTOM_HTC_T ath_custom_htc; + +#endif /* __ATHEROS_WIFI_INTERNAL_H__ */ diff --git a/platform/mcu/lpc54102/wifi_qca/common_src/api_interface/api_init.c b/platform/mcu/lpc54102/wifi_qca/common_src/api_interface/api_init.c new file mode 100644 index 0000000000..f849d95514 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/common_src/api_interface/api_init.c @@ -0,0 +1,292 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== + +#include "wifi_common.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +const uint8_t max_performance_power_param = MAX_PERF_POWER; +const WMI_STORERECALL_CONFIGURE_CMD default_strrcl_config_cmd = {1, STRRCL_RECIPIENT_HOST}; +const WMI_POWER_PARAMS_CMD default_power_param = {0, + A_CPU2LE16(1), // nonzero value requires endian correction + 0, + 0, + A_CPU2LE16(1), // nonzero value requires endian correction + IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN}; + +const WMI_SCAN_PARAMS_CMD default_scan_param = {0, 0, 0, 0, 0, WMI_SHORTSCANRATIO_DEFAULT, DEFAULT_SCAN_CTRL_FLAGS, + 0, 0, 0}; + +#if ENABLE_P2P_MODE +const WMI_P2P_FW_SET_CONFIG_CMD default_p2p_config = {0, "US", 81, 6, 81, 6, A_CPU2LE32(3000), 10}; +#endif + +void Api_BootProfile(void *pCxt, uint8_t val) +{ + if (ath_custom_init.Boot_Profile != NULL) + { + ath_custom_init.Boot_Profile(val); + } +} + +/*****************************************************************************/ +/* Api_InitStart - implements common code for initializing the driver. + * This should be called before Api_InitFinish(). + * void *pCxt - the driver context. + *****************************************************************************/ +A_STATUS +Api_InitStart(void *pCxt) +{ + A_STATUS status; + + do + { + /* 1 - initialize context */ + if (A_OK != (status = Driver_ContextInit(pCxt))) + { + break; + } + /* 2 - insert driver into system if necessary */ + if (A_OK != (status = DRIVER_INSERT(pCxt))) + { + break; + } + + /*3 - initilize socket context*/ + if (A_OK != (status = SOCKET_CONTEXT_INIT)) + { + break; + } + + } while (0); + + return status; +} + +/*****************************************************************************/ +/* Api_InitFinish - implements common code for initializing the driver. + * This should be called after Api_InitStart(). + * void *pCxt - the driver context. + *****************************************************************************/ +A_STATUS +Api_InitFinish(void *pCxt) +{ + // int32_t timeleft; + // int16_t i; + A_STATUS ret = A_OK; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + + if (ath_custom_init.skipWmi) + { + return A_OK; + } + + do + { + // Api_BootProfile(pCxt, 0x00); + /* Wait for Wmi event to be ready Implementation of this macro is platform specific + * as multi-threaded systems will implement differently from single threaded. */ + /* Increased the WMI_READY timeout from 5 seconds to 15 seconds to allow + firmware download over SPI interface */ + PRINTF("WAITING FOR WMI READY\r\n"); + if (A_OK != DRIVER_WAIT_FOR_CONDITION(pCxt, &(pDCxt->wmiReady), true, 15000)) + { + ret = A_ERROR; + break; + } + + // Api_BootProfile(pCxt, BOOT_PROFILE_WMI_READY); + + // printf("%d\r\n", pDCxt->wmiReady); + if (pDCxt->wmiReady != true) + { + ret = A_ERROR; + break; + } + /* WMI_EVENT will have populated arVersion so now confirm that version is compatible */ + if (pDCxt->abiVersion != 1) + { + if ((pDCxt->abiVersion & ABI_MAJOR_MASK) != (AR6K_ABI_VERSION & ABI_MAJOR_MASK)) + { + ret = A_ERROR; + break; + } + } + + } while (0); + + return ret; +} + +static A_STATUS wmi_cmd_process(void *pCxt, WMI_COMMAND_ID cmd, const void *pParam, uint16_t length) +{ + A_STATUS status; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + + status = wmi_cmd_start(pDCxt->pWmiCxt, pParam, cmd, length); + + if (status == A_NO_MEMORY) + { + pDCxt->tx_complete_pend = true; + + if (A_OK != DRIVER_WAIT_FOR_CONDITION(pCxt, &(pDCxt->tx_complete_pend), false, 5000)) + { + A_ASSERT(0); + } + } + else if (status != A_OK) + { + A_ASSERT(0); + } + + return status; +} + +/*****************************************************************************/ +/* Api_WMIInitFinish - implements common code for sending default wmi commands + * to target. + * This should be called after Api_InitFinish(). + * void *pCxt - the driver context. + *****************************************************************************/ +void Api_WMIInitFinish(void *pCxt) +{ + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + A_STATUS status; + WMI_ALLOW_AGGR_CMD allow_aggr_cmd; + + if (pDCxt->wmiReady == true) + { + do + { + status = STACK_INIT(pCxt); + + if (status == A_OK) + { + WAIT_FOR_WMI_RESPONSE(pCxt); + break; + } + else if (status == A_NO_MEMORY) + { + pDCxt->tx_complete_pend = true; + + if (A_OK != DRIVER_WAIT_FOR_CONDITION(pCxt, &(pDCxt->tx_complete_pend), false, 5000)) + { + A_ASSERT(0); + } + } + else + { + A_ASSERT(0); + } + } while (1); + +/* issue some default WMI commands appropriate for most systems */ +#if WLAN_CONFIG_IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN + wmi_cmd_process(pCxt, WMI_SET_POWER_PARAMS_CMDID, &default_power_param, sizeof(WMI_POWER_PARAMS_CMD)); +#endif + wmi_cmd_process(pCxt, WMI_SET_SCAN_PARAMS_CMDID, &default_scan_param, sizeof(WMI_SCAN_PARAMS_CMD)); + + wmi_cmd_process(pCxt, WMI_STORERECALL_CONFIGURE_CMDID, &default_strrcl_config_cmd, + sizeof(WMI_STORERECALL_CONFIGURE_CMD)); + pDCxt->strrclState = STRRCL_ST_INIT; + /* technically this call to wmi_allow_aggr_cmd is not necessary if both + * masks are 0 as the firmware has 0,0 as the default. */ + allow_aggr_cmd.tx_allow_aggr = A_CPU2LE16(pDCxt->txAggrTidMask); + allow_aggr_cmd.rx_allow_aggr = A_CPU2LE16(pDCxt->rxAggrTidMask); + wmi_cmd_process(pCxt, WMI_ALLOW_AGGR_CMDID, &allow_aggr_cmd, sizeof(WMI_ALLOW_AGGR_CMD)); +#if ENABLE_P2P_MODE + if (WLAN_NUM_OF_DEVICES == 2) + { + /* Device-0 is P2P Device and Device-1 is Legacy STA.\ + Set Default P2P Params + */ + wmi_cmd_process(pCxt, WMI_P2P_SET_CONFIG_CMDID, &default_p2p_config, sizeof(WMI_P2P_FW_SET_CONFIG_CMD)); + } +#endif + /* Set the BSS Filter to None. If this is not set, by default the firmware + sets to forward the beacons to host. This causes unnecessary BSSINFO events in + the host even after connecting to the AP */ + wmi_bssfilter_cmd(pDCxt->pWmiCxt, NONE_BSS_FILTER, 0); + } +} + +/*****************************************************************************/ +/* Api_DeInitStart - implements common code for de-initializing the driver. + * This should be called before Api_DeInitFinish(). + * void *pCxt - the driver context. + *****************************************************************************/ +A_STATUS +Api_DeInitStart(void *pCxt) +{ + UNUSED_ARGUMENT(pCxt); + /* This is a place holder for future enhancements */ + return A_OK; +} + +/*****************************************************************************/ +/* Api_DeInitFinish - implements common code for de-initializing the driver. + * This should be called after Api_DeInitStart(). + * void *pCxt - the driver context. + *****************************************************************************/ +A_STATUS +Api_DeInitFinish(void *pCxt) +{ + A_STATUS status = A_ERROR; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + + do + { + /* 1 - block until driver thread is cleaned up. in systems without + * a driver thread this is a NOP. */ + if (A_OK != DRIVER_WAIT_FOR_CONDITION(pCxt, &(pDCxt->driver_up), false, 5000)) + { + break; + } + /* 2 - remove driver from system */ + DRIVER_REMOVE(pCxt); + /* 3 - De-initialize context */ + Driver_ContextDeInit(pCxt); + + /*4 - Deinitialize socket context*/ + SOCKET_CONTEXT_DEINIT(); + + status = A_OK; + } while (0); + + return status; +} diff --git a/platform/mcu/lpc54102/wifi_qca/common_src/api_interface/api_ioctl.c b/platform/mcu/lpc54102/wifi_qca/common_src/api_interface/api_ioctl.c new file mode 100644 index 0000000000..a7ca925df4 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/common_src/api_interface/api_ioctl.c @@ -0,0 +1,1164 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== + +#include "wifi_common.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "hw20_mbox_host_reg.h" +#include +#include "hw20_apb_map.h" +#include "hw20_mbox_reg.h" +extern const WMI_SCAN_PARAMS_CMD default_scan_param; +uint8_t countryCode_storge[4]; +A_STATUS +Program_CountryCode(void *pCxt) +{ + A_DRIVER_CONTEXT *pDCxt; + A_STATUS status = A_ERROR; + uint32_t param; + uint8_t pass_cycle = 0; + A_NETBUF_DECLARE req; + void *pReq = (void *)&req; + uint32_t country_code_word; + uint8_t *ptr_country_code = (uint8_t *)&country_code_word; + uint32_t i; + A_NETBUF_CONFIGURE(pReq, &country_code_word, 0, sizeof(uint32_t), sizeof(uint32_t)); + pDCxt = GET_DRIVER_COMMON(pCxt); + + do + { + /* bring the chip down */ + pDCxt->wmiReady = false; + HW_PowerUpDown(pCxt, false); + /* bring the chip back up */ + HW_PowerUpDown(pCxt, true); + pDCxt->htc_creditInit = 0; + /* re-initialize host controller (sub-)driver = HCD */ + if ((status = Hcd_ReinitTarget(pCxt)) != A_OK) + { + A_ASSERT(0); + } + + if (pass_cycle == 0) + { + A_MDELAY(5); + /* wait for chip to reach point in initialization */ + do + { + if (Driver_ReadDataDiag(pCxt, TARG_VTOP(HOST_INTEREST_ITEM_ADDRESS(hi_refclk_hz)), (uint8_t *)¶m, + 4) != A_OK) + { + A_ASSERT(0); + } + } while (param != A_CPU2LE32(EXPECTED_REF_CLK_AR4100) && param != A_CPU2LE32(EXPECTED_REF_CLK_AR400X)); + /* on 1st pass the mac address is loaded into the + * scratch registers and the parameter is set to + * cause the firmware to read/program the mac address. + */ + ptr_country_code[0] = 0; + // the first byte is used to store the result, the rest three bytes are used to store countrycode + A_MEMCPY(&ptr_country_code[1], &countryCode_storge[1], 3); + QCADRV_PRINTF("ptr_country_code is %c, %c.\n", ptr_country_code[1], ptr_country_code[2]); + // ATH_SET_PIO_EXTERNAL_WRITE_OPERATION(pReq, SCRATCH_ADDRESS, true, sizeof(uint32_t)); + ATH_SET_PIO_EXTERNAL_WRITE_OPERATION(pReq, SCRATCH_ADDRESS, true, sizeof(uint32_t)); + + if (A_OK != (status = Hcd_DoPioExternalAccess(pCxt, pReq))) + { + A_ASSERT(0); + } +#if 0 + A_MEMCPY(&ptr_country_code[0], &pDCxt->conn[pDCxt->devId].reqBssid[2], 4); + ATH_SET_PIO_EXTERNAL_WRITE_OPERATION(pReq, SCRATCH_ADDRESS+4, true, sizeof(uint32_t)); + + if(A_OK != (status = Hcd_DoPioExternalAccess(pCxt, pReq))){ + A_ASSERT(0); + } +#endif + A_MDELAY(5); + param = A_CPU2LE32(AR4XXX_PARAM_COUNTRY_CODE_MODE); + + if (Driver_WriteDataDiag(pCxt, TARG_VTOP(HOST_INTEREST_ITEM_ADDRESS(hi_flash_is_present)), + (uint8_t *)¶m, 4) != A_OK) + { + A_ASSERT(0); + } + /* wait some sufficient number of attempts before giving up. */ + for (i = 0; i < 100; i++) + { + /* poll scratch register for indication of completion */ + A_MDELAY(1); // delay 1 ms to make target execute the setting of countrycode + ATH_SET_PIO_EXTERNAL_READ_OPERATION(pReq, SCRATCH_ADDRESS, true, sizeof(uint32_t)); + if (A_OK != (status = Hcd_DoPioExternalAccess(pCxt, pReq))) + { + A_ASSERT(0); + } + // result from target is stored in ptr_country_code + if ((ptr_country_code[0] != 0)) + { + QCADRV_PRINTF("ptr_country_code break;.\n"); + break; /* done - exit loop */ + } + } + } + else + { + /* on 2nd pass the chip is brought up normally */ + A_MDELAY(5); + Driver_BootComm(pCxt); + pDCxt->chipDown = false; + } + + pass_cycle++; + } while (pass_cycle < 2); + + if (pass_cycle >= 2) + { + /* store result in reqBssid for use in calling function */ + countryCode_storge[0] = ptr_country_code[0]; + } + else + { + countryCode_storge[0] = 0; + } + QCADRV_PRINTF("target result is %c,%d.\n", ptr_country_code[0], ptr_country_code[0]); + status = A_OK; + pDCxt->asynchRequest = NULL; + // pDCxt->macProgramming = false; + DRIVER_WAKE_USER(pCxt); + + return status; +} +A_STATUS +Api_ProgramCountryCode(void *pCxt, uint8_t *country_code, uint16_t length, uint8_t *pResult) +{ + A_STATUS status = A_ERROR; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + boolean countryCodeProgram = true; + /* init pResult to an error code of 0 */ + *pResult = ATH_PROGRAM_COUNTRY_CODE_RESULT_DRIVER_FAILED; + + do + { + if (length != sizeof(ATH_PROGRAM_COUNTRY_CODE_PARAM)) + { + break; + } + + if (Api_DriverAccessCheck(pCxt, 0, ACCESS_REQUEST_IOCTL) != A_OK) + { + break; + } + + if (pDCxt->asynchRequest != NULL) + { + break; + } + /* use the reqBssid as storage for the country code. the Program_CountryCode + * function will retrieve this value for use in the operation. + */ + // A_MEMCPY(pDCxt->conn[pDCxt->devId].reqBssid, country_code, 3); + A_MEMCPY(&countryCode_storge[1], country_code, 3); + + QCADRV_PRINTF("api_ioctl countryCode_storge is %c,%c.\n", countryCode_storge[1], countryCode_storge[2]); + pDCxt->asynchRequest = Program_CountryCode; + DRIVER_WAKE_DRIVER(pCxt); + DRIVER_WAIT_FOR_CONDITION(pCxt, &countryCodeProgram, false, 5000); + + switch (countryCode_storge[0]) + { + case 1: /*successful result*/ + *pResult = ATH_PROGRAM_COUNTRY_CODE_RESULT_SUCCESS; + break; + case 2: /* device failed in the attempt */ + *pResult = ATH_PROGRAM_COUNTRY_CODE_RESULT_DEV_DENIED; + break; + case 4: /* the same country is already programmed */ + case 8: /* the device rejected the mac address */ + *pResult = ATH_PROGRAM_COUNTRY_CODE_RESULT_DEV_FAILED; + break; + case 0: /* driver failure to communicate with device */ + default: + break; + } + Api_InitFinish(pCxt); + Api_WMIInitFinish(pCxt); + status = A_OK; + + } while (0); + + A_MEMZERO(pDCxt->conn[pDCxt->devId].reqBssid, sizeof(pDCxt->conn[pDCxt->devId].reqBssid)); + + return status; +} + +#if DRIVER_CONFIG_PROGRAM_MAC_ADDR +/*****************************************************************************/ +/* program_mac_addr - Used to program a new mac address into the attached + * wifi device. the mac address is in pDCxt->reqBssid. Special firmware + * is loaded to perform the operation. the MAC address is provided to + * the firmware through the MBOX scratch registers. + * void *pCxt - the driver context. + *****************************************************************************/ +static A_STATUS program_mac_addr(void *pCxt) +{ + A_DRIVER_CONTEXT *pDCxt; + A_STATUS status = A_ERROR; + uint32_t param; + uint8_t pass_cycle = 0; + A_NETBUF_DECLARE req; + void *pReq = (void *)&req; + uint32_t mac_word; + uint8_t *ptr_mac_word = (uint8_t *)&mac_word; + uint32_t i; + + A_NETBUF_CONFIGURE(pReq, &mac_word, 0, sizeof(uint32_t), sizeof(uint32_t)); + pDCxt = GET_DRIVER_COMMON(pCxt); + + do + { + /* bring the chip down */ + pDCxt->wmiReady = false; + HW_PowerUpDown(pCxt, false); + /* bring the chip back up */ + HW_PowerUpDown(pCxt, true); + pDCxt->htc_creditInit = 0; + /* re-initialize host controller (sub-)driver = HCD */ + if ((status = Hcd_ReinitTarget(pCxt)) != A_OK) + { + A_ASSERT(0); + } + + if (pass_cycle == 0) + { + A_MDELAY(5); + /* wait for chip to reach point in initialization */ + do + { + if (Driver_ReadDataDiag(pCxt, TARG_VTOP(HOST_INTEREST_ITEM_ADDRESS(hi_refclk_hz)), (uint8_t *)¶m, + 4) != A_OK) + { + A_ASSERT(0); + } + } while (param != A_CPU2LE32(EXPECTED_REF_CLK_AR4100) && param != A_CPU2LE32(EXPECTED_REF_CLK_AR400X)); + /* on 1st pass the mac address is loaded into the + * scratch registers and the parameter is set to + * cause the firmware to read/program the mac address. + */ + ptr_mac_word[0] = 0; + ptr_mac_word[1] = 0; + A_MEMCPY(&ptr_mac_word[2], &pDCxt->conn[pDCxt->devId].reqBssid[0], 2); + ATH_SET_PIO_EXTERNAL_WRITE_OPERATION(pReq, SCRATCH_ADDRESS, true, sizeof(uint32_t)); + + if (A_OK != (status = Hcd_DoPioExternalAccess(pCxt, pReq))) + { + A_ASSERT(0); + } + + A_MEMCPY(&ptr_mac_word[0], &pDCxt->conn[pDCxt->devId].reqBssid[2], 4); + ATH_SET_PIO_EXTERNAL_WRITE_OPERATION(pReq, SCRATCH_ADDRESS + 4, true, sizeof(uint32_t)); + + if (A_OK != (status = Hcd_DoPioExternalAccess(pCxt, pReq))) + { + A_ASSERT(0); + } + A_MDELAY(5); + param = A_CPU2LE32(AR4XXX_PARAM_MACPROG_MODE); + + if (Driver_WriteDataDiag(pCxt, TARG_VTOP(HOST_INTEREST_ITEM_ADDRESS(hi_flash_is_present)), + (uint8_t *)¶m, 4) != A_OK) + { + A_ASSERT(0); + } + /* wait some sufficient number of attempts before giving up. */ + for (i = 0; i < 100; i++) + { + /* poll scratch register for indication of completion */ + ATH_SET_PIO_EXTERNAL_READ_OPERATION(pReq, SCRATCH_ADDRESS, true, sizeof(uint32_t)); + + if (A_OK != (status = Hcd_DoPioExternalAccess(pCxt, pReq))) + { + A_ASSERT(0); + } + QCADRV_PRINTF("ptr_mac_word[1] is %c.\n", ptr_mac_word[1]); + if (ptr_mac_word[1] != 0) + { + break; /* done - exit loop */ + } + /* delay 1 msec before polling again to give the op time to complete */ + A_MDELAY(1); + } + } + else + { + /* on 2nd pass the chip is brought up normally */ + A_MDELAY(5); + Driver_BootComm(pCxt); + pDCxt->chipDown = false; + } + + pass_cycle++; + } while (pass_cycle < 2); + + if (pass_cycle >= 2) + { + /* store result in reqBssid for use in calling function */ + pDCxt->conn[pDCxt->devId].reqBssid[0] = ptr_mac_word[1]; + } + else + { + pDCxt->conn[pDCxt->devId].reqBssid[0] = 0; + } + status = A_OK; + pDCxt->asynchRequest = NULL; + pDCxt->macProgramming = false; + DRIVER_WAKE_USER(pCxt); + + return status; +} +#endif /* DRIVER_CONFIG_PROGRAM_MAC_ADDR */ + +/*****************************************************************************/ +/* Install_static_wep_keys - Used to install WEP keys to the device at the + * appropriate time. + * void *pCxt - the driver context. + *****************************************************************************/ +static void Install_static_wep_keys(void *pCxt) +{ + uint8_t index; + uint8_t keyUsage; + A_DRIVER_CONTEXT *pDCxt; + WMI_ADD_CIPHER_KEY_CMD add_key_param; + + pDCxt = GET_DRIVER_COMMON(pCxt); + + for (index = WMI_MIN_KEY_INDEX; index <= WMI_MAX_KEY_INDEX; index++) + { + if (pDCxt->conn[pDCxt->devId].wepKeyList[index].keyLen) + { + keyUsage = GROUP_USAGE; + if (index == pDCxt->conn[pDCxt->devId].wepDefTxKeyIndex) + { + keyUsage |= TX_USAGE; + } + + A_MEMZERO(&add_key_param, sizeof(add_key_param)); + add_key_param.keyIndex = index; + add_key_param.keyType = WEP_CRYPT; + add_key_param.keyUsage = keyUsage; + add_key_param.keyLength = pDCxt->conn[pDCxt->devId].wepKeyList[index].keyLen; + A_MEMCPY(&add_key_param.key, pDCxt->conn[pDCxt->devId].wepKeyList[index].key, add_key_param.keyLength); + add_key_param.key_op_ctrl = KEY_OP_INIT_VAL; + wmi_cmd_start(pDCxt->pWmiCxt, &add_key_param, WMI_ADD_CIPHER_KEY_CMDID, sizeof(WMI_ADD_CIPHER_KEY_CMD)); + } + } +} + +/*****************************************************************************/ +/* Api_DisconnectWiFi - Called by upper layer to disconnect a network + * connection. Executes wmi_Disconnnect_cmd + * void *pCxt - the driver context. + *****************************************************************************/ +A_STATUS +Api_DisconnectWiFi(void *pCxt) +{ + A_DRIVER_CONTEXT *pDCxt; + + pDCxt = GET_DRIVER_COMMON(pCxt); + + if ((pDCxt->conn[pDCxt->devId].isConnected == true) || (pDCxt->conn[pDCxt->devId].isConnectPending == true)) + { + wmi_cmd_start(pDCxt->pWmiCxt, NULL, WMI_DISCONNECT_CMDID, 0); + /* + * Disconnect cmd is issued, clear connectPending. + * arConnected will be cleard in disconnect_event notification. + */ + pDCxt->conn[pDCxt->devId].isConnectPending = false; + /* + * clear connect state so that subsequent connect commands start with same + * initial configuration every time. + */ + pDCxt->conn[pDCxt->devId].dot11AuthMode = OPEN_AUTH; + pDCxt->conn[pDCxt->devId].wpaAuthMode = NONE_AUTH; + pDCxt->conn[pDCxt->devId].wpaPairwiseCrypto = pDCxt->conn[pDCxt->devId].wpaGroupCrypto = NONE_CRYPT; + pDCxt->conn[pDCxt->devId].wpaPairwiseCryptoLen = pDCxt->conn[pDCxt->devId].wpaGroupCryptoLen = 0; + A_MEMZERO(pDCxt->conn[pDCxt->devId].reqBssid, sizeof(pDCxt->conn[pDCxt->devId].reqBssid)); + pDCxt->conn[pDCxt->devId].channelHint = 0; + pDCxt->conn[pDCxt->devId].connectCtrlFlags = 0; + } + + return A_OK; +} + +/*****************************************************************************/ +/* Api_ConnectWiFi - Called by upper layer to start a network connection + * operation. Executes wmi_connnect_cmd + * void *pCxt - the driver context. + *****************************************************************************/ +A_STATUS +Api_ConnectWiFi(void *pCxt) +{ + A_DRIVER_CONTEXT *pDCxt; + A_STATUS status = A_OK; + WMI_CONNECT_CMD conn_cmd = {0}; + WMI_SCAN_PARAMS_CMD scan_param_cmd; + uint8_t devId; + + pDCxt = GET_DRIVER_COMMON(pCxt); + devId = pDCxt->devId; + /* The ssid length check prevents second "essid off" from the user, + to be treated as a connect cmd. The second "essid off" is ignored. + */ + if ((pDCxt->wmiReady == true) && (pDCxt->conn[devId].ssidLen > 0) && pDCxt->conn[devId].networkType != AP_NETWORK) + { + if (/*(ADHOC_NETWORK != ar->arNetworkType) &&*/ // Allow wep key installation in AD-HOC mode + (NONE_AUTH == pDCxt->conn[pDCxt->devId].wpaAuthMode) && + (WEP_CRYPT == pDCxt->conn[pDCxt->devId].wpaPairwiseCrypto)) + { + Install_static_wep_keys(pCxt); + } + /* set scan ctrl flags to default. this will ensure that the firmware will scan for + * an appropriate AP during connect operation. All params that are zero will remain + * unchanged from their pre existing value. If WPS had been previously used it would + * have set the scan ctrl flags in such a way that a subsequent connect might fail. + * This wmi_scanparams_cmd() fixes that issue. + */ + do + { + A_MEMCPY(&scan_param_cmd, &pDCxt->scan_param, sizeof(WMI_SCAN_PARAMS_CMD)); + scan_param_cmd.bg_period = pDCxt->scan_param.bg_period = A_CPU2LE16(0xffff); + if (A_OK != + wmi_cmd_start(pDCxt->pWmiCxt, &scan_param_cmd, WMI_SET_SCAN_PARAMS_CMDID, sizeof(WMI_SCAN_PARAMS_CMD))) + { + break; + } + else + { + WAIT_FOR_WMI_RESPONSE(pCxt); + } + + if (pDCxt->conn[devId].ssidLen) + { + A_MEMCPY(conn_cmd.ssid, pDCxt->conn[devId].ssid, pDCxt->conn[devId].ssidLen); + } + + conn_cmd.ssidLength = pDCxt->conn[devId].ssidLen; + conn_cmd.networkType = pDCxt->conn[devId].networkType; + conn_cmd.dot11AuthMode = pDCxt->conn[devId].dot11AuthMode; + conn_cmd.authMode = pDCxt->conn[devId].wpaAuthMode; + conn_cmd.pairwiseCryptoType = pDCxt->conn[devId].wpaPairwiseCrypto; + conn_cmd.pairwiseCryptoLen = pDCxt->conn[devId].wpaPairwiseCryptoLen; + conn_cmd.groupCryptoType = pDCxt->conn[devId].wpaGroupCrypto; + conn_cmd.groupCryptoLen = pDCxt->conn[devId].wpaGroupCryptoLen; + conn_cmd.channel = A_CPU2LE16(pDCxt->conn[devId].channelHint); + conn_cmd.ctrl_flags = A_CPU2LE32(pDCxt->conn[devId].connectCtrlFlags); + + //NOTE: coverity fix + A_MEMCPY(conn_cmd.bssid, pDCxt->conn[devId].reqBssid, ATH_MAC_LEN); + + status = wmi_cmd_start(pDCxt->pWmiCxt, (void *)&conn_cmd, WMI_CONNECT_CMDID, sizeof(WMI_CONNECT_CMD)); + + if (status != A_OK) + { + break; + } + else + { + WAIT_FOR_WMI_RESPONSE(pCxt); + } + + pDCxt->conn[pDCxt->devId].isConnectPending = true; + } while (0); + + return status; + } +#if ENABLE_AP_MODE + else if (pDCxt->wmiReady == true && pDCxt->conn[pDCxt->devId].networkType == AP_NETWORK) + { + if ((NONE_AUTH == pDCxt->conn[pDCxt->devId].wpaAuthMode) && + (WEP_CRYPT == pDCxt->conn[pDCxt->devId].wpaPairwiseCrypto)) + { + Install_static_wep_keys(pCxt); + } + A_MEMCPY(conn_cmd.ssid, (uint8_t *)pDCxt->conn[devId].ssid, sizeof(conn_cmd.ssid)); + conn_cmd.ssidLength = (int)pDCxt->conn[devId].ssidLen; + conn_cmd.pairwiseCryptoLen = (uint8_t)pDCxt->conn[devId].wpaPairwiseCryptoLen; + conn_cmd.groupCryptoLen = (uint8_t)pDCxt->conn[devId].wpaGroupCryptoLen; + conn_cmd.networkType = pDCxt->conn[devId].networkType; + conn_cmd.dot11AuthMode = pDCxt->conn[devId].dot11AuthMode; + conn_cmd.authMode = pDCxt->conn[devId].wpaAuthMode; + conn_cmd.pairwiseCryptoType = pDCxt->conn[devId].wpaPairwiseCrypto; + conn_cmd.groupCryptoType = pDCxt->conn[devId].wpaGroupCrypto; + + conn_cmd.ctrl_flags = (pDCxt->apmodeWPS) ? A_CPU2LE32(pDCxt->conn[devId].connectCtrlFlags | CONNECT_WPS_FLAG) : + A_CPU2LE32(pDCxt->conn[devId].connectCtrlFlags); + conn_cmd.channel = A_CPU2LE16(pDCxt->conn[devId].channelHint); + + status = wmi_cmd_start(pDCxt->pWmiCxt, (void *)&conn_cmd, WMI_AP_CONFIG_COMMIT_CMDID, sizeof(WMI_CONNECT_CMD)); + return status; + } +#endif /* ENABLE_AP_MODE */ + + return A_ERROR; +} + +static uint8_t wpa_auth_parse(uint8_t *sel) +{ +#define WPA_SEL(x) (((x) << 24) | WPA_OUI) + uint32_t w = A_LE_READ_4(sel); + + switch (w) + { + case WPA_SEL(WPA_ASE_8021X_UNSPEC): + return WPA_AUTH; + case WPA_SEL(WPA_ASE_8021X_PSK): + return WPA_PSK_AUTH; + case WPA_SEL(WPA_ASE_NONE): + return NONE_AUTH; + } + + return 0; +#undef WPA_SEL +} + +static uint8_t wpa_cipher_parse(uint8_t *sel, uint8_t *keylen) +{ +#define WPA_SEL(x) (((x) << 24) | WPA_OUI) + uint32_t w = A_LE_READ_4(sel); + + switch (w) + { + case WPA_SEL(WPA_CSE_NULL): + return NONE_CRYPT; + case WPA_SEL(WPA_CSE_WEP40): + if (keylen) + *keylen = 40 >> 3; // 40/bits_per_byte + return WEP_CRYPT; + case WPA_SEL(WPA_CSE_WEP104): + if (keylen) + *keylen = 104 >> 3; // 104/bits_per_byte + return WEP_CRYPT; + case WPA_SEL(WPA_CSE_TKIP): + return TKIP_CRYPT; + case WPA_SEL(WPA_CSE_CCMP): + return AES_CRYPT; + } + + return 0; +#undef WPA_SEL +} + +static CRYPTO_TYPE rsn_cipher_parse(uint8_t *sel, uint8_t *keylen) +{ +#define RSN_SEL(x) (((x) << 24) | RSN_OUI) + uint32_t w = A_LE_READ_4(sel); + + switch (w) + { + case RSN_SEL(RSN_CSE_NULL): + return NONE_CRYPT; + case RSN_SEL(RSN_CSE_WEP40): + if (keylen) + *keylen = 40 >> 3; // 40/bits_per_byte + return WEP_CRYPT; + case RSN_SEL(RSN_CSE_WEP104): + if (keylen) + *keylen = 104 >> 3; // 104/bits_per_byte + return WEP_CRYPT; + case RSN_SEL(RSN_CSE_TKIP): + return TKIP_CRYPT; + case RSN_SEL(RSN_CSE_CCMP): + return AES_CRYPT; + } + return NONE_CRYPT; +#undef RSN_SEL +} + +static uint8_t rsn_auth_parse(uint8_t *sel) +{ +#define RSN_SEL(x) (((x) << 24) | RSN_OUI) + uint32_t w = A_LE_READ_4(sel); + + switch (w) + { + case RSN_SEL(RSN_ASE_8021X_UNSPEC): + return WPA2_AUTH; + case RSN_SEL(RSN_ASE_8021X_PSK): + return WPA2_PSK_AUTH; + case RSN_SEL(RSN_ASE_NONE): + return NONE_AUTH; + } + + return 0; +#undef RSN_SEL +} + +static void security_ie_parse(uint8_t *pie, uint8_t ie_len, uint8_t *pResult, uint8_t ie_type) +{ + uint16_t cnt; + uint16_t i; + uint8_t wepKeyLen; + /* skip mcast cipher */ + if (ie_len >= 4) + { + ie_len -= 4; + pie += 4; + } + /* examine ucast cipher(s) */ + if (ie_len > 2) + { + cnt = A_LE_READ_2(pie); + ie_len -= 2; + pie += 2; + + for (i = 0; ((i < cnt) && (ie_len > 0)); i++) + { + if (ie_type == IEEE80211_ELEMID_RSN) + { + pResult[0] |= rsn_cipher_parse(pie, &wepKeyLen); + } + else + { + pResult[0] |= wpa_cipher_parse(pie, &wepKeyLen); + } + + ie_len -= 4; + pie += 4; + } + } + else + { + /* assume default TKIP for wpa */ + pResult[0] |= (ie_type == IEEE80211_ELEMID_RSN) ? AES_CRYPT : TKIP_CRYPT; + } + /* parse auth types */ + if (ie_len > 2) + { + cnt = A_LE_READ_2(pie); + ie_len -= 2; + pie += 2; + + for (i = 0; ((i < cnt) && (ie_len > 0)); i++) + { + if (ie_type == IEEE80211_ELEMID_RSN) + { + pResult[1] |= rsn_auth_parse(pie); + } + else + { + pResult[1] |= wpa_auth_parse(pie); + } + + ie_len -= 4; + pie += 4; + } + } + else + { + pResult[1] |= (ie_type == IEEE80211_ELEMID_RSN) ? WPA2_AUTH : WPA_AUTH; + } +} + +A_STATUS +Api_ParseInfoElem(void *pCxt, WMI_BSS_INFO_HDR *bih, int32_t len, A_SCAN_SUMMARY *pSummary) +{ + uint8_t *buf; + uint8_t *pie, *pieEnd, *pieTemp; + uint8_t ie_result[2]; + uint16_t ie_len; + + A_MEMZERO(pSummary, sizeof(A_SCAN_SUMMARY)); + + pSummary->channel = (uint8_t)Util_Freq2ieee(bih->channel); + pSummary->rssi = bih->snr; /* snr is a value from 0 -> 95 where 95 is a strong signal */ + A_MEMCPY(pSummary->bssid, bih->bssid, ATH_MAC_LEN); + + if ((uint32_t)len < sizeof(WMI_BSS_INFO_HDR) + IE_INDEX) + { + return A_ERROR; + } + + buf = (uint8_t *)(bih + 1); + len -= sizeof(WMI_BSS_INFO_HDR); + + pSummary->caps = (uint16_t)((uint16_t)buf[CAPS_IE_INDEX] | (uint16_t)(buf[CAPS_IE_INDEX + 1] << 8)); + pSummary->beacon_period = + (uint16_t)((uint16_t)buf[BEACON_PERIOD_IE_INDEX] | (uint16_t)(buf[BEACON_PERIOD_IE_INDEX + 1] << 8)); + /* loop through IE's to collect additional info */ + pie = &buf[IE_INDEX]; + len -= IE_INDEX; + pieEnd = &pie[len]; + + while (pie < pieEnd) + { + switch (*pie) + { + case IEEE80211_ELEMID_SSID: + if (pie[1] <= 32) + { + pSummary->ssid_len = pie[1]; + + if (pie[1]) + { + A_MEMCPY(pSummary->ssid, &pie[2], pie[1]); + } + } + break; + case IEEE80211_ELEMID_RSN: + /*******************/ + /* parse RSN IE */ + /*******************/ + ie_len = pie[1]; /* init ie_len - sizeof wpa_oui */ + pieTemp = &pie[2]; /* init pieTemp beyond wpa_oui */ + + if (A_LE_READ_2(pieTemp) != RSN_VERSION) + { + break; + } + ie_len -= 2; + pieTemp += 2; + ie_result[0] = ie_result[1] = 0; + + security_ie_parse(pieTemp, ie_len, &ie_result[0], IEEE80211_ELEMID_RSN); + pSummary->rsn_cipher = ie_result[0]; + pSummary->rsn_auth = ie_result[1]; + break; + case IEEE80211_ELEMID_VENDOR: + if (pie[1] > 6 && A_LE_READ_4(pie + 2) == ((WPA_OUI_TYPE << 24) | WPA_OUI)) + { + /*******************/ + /* parse WPA IE */ + /*******************/ + ie_len = pie[1] - 4; /* init ie_len - sizeof wpa_oui */ + pieTemp = &pie[6]; /* init pieTemp beyond wpa_oui */ + + if (A_LE_READ_2(pieTemp) != WPA_VERSION) + { + break; /* bad version */ + } + + ie_len -= 2; + pieTemp += 2; + ie_result[0] = ie_result[1] = 0; + + security_ie_parse(pieTemp, ie_len, &ie_result[0], IEEE80211_ELEMID_VENDOR); + pSummary->wpa_cipher = ie_result[0]; + pSummary->wpa_auth = ie_result[1]; + } + break; + } + + pie += pie[1] + 2; + } + + return A_OK; +} + +/*****************************************************************************/ +/* Api_DriverAccessCheck - Called by upper layer to confirm that the driver + * is in a State to allow IOCTL's and other requests. + * void *pCxt - the driver context. + * uint8_t block_allowed - caller can tolerate a task block if the + * check is not immediately satisfied. + * uint8_t request_reason - callers reason to request driver access. + *****************************************************************************/ +A_STATUS +Api_DriverAccessCheck(void *pCxt, uint8_t block_allowed, uint8_t request_reason) +{ + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + A_STATUS status = A_OK; + uint8_t blocked; + + UNUSED_ARGUMENT(request_reason); + + do + { + blocked = 0; + /* if the chip is powered down when a tx operation is submitted + * then the policy is to wait for the chip to come back */ + if (true == pDCxt->chipDown) + { + blocked = 1; + + if (block_allowed == 0) + { + /* caller forbids blocking so return A_ERROR */ + status = A_ERROR; + break; + } + + do + { + DRIVER_WAIT_FOR_CONDITION(pCxt, &(pDCxt->chipDown), false, 5000); + } while (true == pDCxt->chipDown); + } +#if DRIVER_CONFIG_ENABLE_STORE_RECALL + /*Check str-rcl state only if applications requests it*/ + if (request_reason != ACCESS_REQUEST_RX) + { + /* if a strrcl command is in process all ioctl's and tx operations + * must be blocked/deferred until it completes. + */ + if (true == pDCxt->strrclBlock) + { + blocked = 1; + + if (block_allowed == 0) + { + /* caller forbids blocking so return A_ERROR */ + status = A_ERROR; + break; + } + + do + { + DRIVER_WAIT_FOR_CONDITION(pCxt, &(pDCxt->strrclBlock), false, 5000); + } while (true == pDCxt->strrclBlock); + } + } +#endif + + } while (blocked); /* loop until all conditions are met at one pass */ + + return status; +} + +#if DRIVER_CONFIG_PROGRAM_MAC_ADDR +A_STATUS +Api_ProgramMacAddress(void *pCxt, uint8_t *addr, uint16_t length, uint8_t *pResult) +{ + A_STATUS status = A_ERROR; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + /* init pResult to an error code of 0 */ + *pResult = ATH_PROGRAM_MAC_RESULT_DRIVER_FAILED; + + do + { + if (length != sizeof(ATH_PROGRAM_MAC_ADDR_PARAM)) + { + break; + } + + if (Api_DriverAccessCheck(pCxt, 0, ACCESS_REQUEST_IOCTL) != A_OK) + { + break; + } + + if (pDCxt->asynchRequest != NULL) + { + break; + } + /* use the reqBssid as storage for the mac address. the program_mac_addr + * function will retrieve this value for use in the operation. + */ + A_MEMCPY(pDCxt->conn[pDCxt->devId].reqBssid, addr, sizeof(pDCxt->conn[pDCxt->devId].reqBssid)); + pDCxt->macProgramming = true; + pDCxt->asynchRequest = program_mac_addr; + DRIVER_WAKE_DRIVER(pCxt); + DRIVER_WAIT_FOR_CONDITION(pCxt, &(pDCxt->macProgramming), false, 5000); + + if (pDCxt->macProgramming == false) + { + switch (pDCxt->conn[pDCxt->devId].reqBssid[0]) + { + case 1: /*successful result*/ + *pResult = ATH_PROGRAM_MAC_RESULT_SUCCESS; + break; + case 2: /* device failed in the attempt */ + *pResult = ATH_PROGRAM_MAC_RESULT_DEV_FAILED; + break; + case 4: /* the same mac address is already programmed */ + case 8: /* the device rejected the mac address */ + *pResult = ATH_PROGRAM_MAC_RESULT_DEV_DENIED; + break; + case 0: /* driver failure to communicate with device */ + default: + break; + } + + Api_InitFinish(pCxt); + Api_WMIInitFinish(pCxt); + status = A_OK; + } + + } while (0); + + A_MEMZERO(pDCxt->conn[pDCxt->devId].reqBssid, sizeof(pDCxt->conn[pDCxt->devId].reqBssid)); + + return status; +} +#endif /* DRIVER_CONFIG_PROGRAM_MAC_ADDR */ +A_STATUS +Api_SetPowerMode(void *pCxt, POWER_MODE *app_setting) +{ + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + + if (app_setting->pwr_module < PWR_MAX) + { + (app_setting->pwr_mode == REC_POWER) ? (pDCxt->pwrStateSetting &= ~(1 << app_setting->pwr_module)) : + (pDCxt->pwrStateSetting |= (1 << app_setting->pwr_module)); + } + /* Set MAX Perf */ + if ((app_setting->pwr_mode == MAX_PERF_POWER) && (pDCxt->userPwrMode == REC_POWER)) + { + pDCxt->userPwrMode = MAX_PERF_POWER; + } + /* Set REC Power */ + if ((app_setting->pwr_mode == REC_POWER) && (pDCxt->pwrStateSetting == 0x00)) + { + pDCxt->userPwrMode = REC_POWER; + } + QCADRV_PRINTF("Power Mode : %x,%d,%d \n", pDCxt->pwrStateSetting, app_setting->pwr_mode, app_setting->pwr_module); + if (A_OK != + wmi_cmd_start(pDCxt->pWmiCxt, &pDCxt->userPwrMode, WMI_SET_POWER_MODE_CMDID, sizeof(WMI_POWER_MODE_CMD))) + { + return A_ERROR; + } + + if ((app_setting->pwr_mode == REC_POWER) && pDCxt->userPwrMode == MAX_PERF_POWER) + { + QCADRV_PRINTF("Device will remain MAX_PERF \n"); + } + return A_OK; +} + +#if !ENABLE_STACK_OFFLOAD +extern const uint8_t max_performance_power_param; +int32_t power_state_for_module = 0; +/*****************************************************************************/ +/* move_to_maxperf - Changes the power mode to max perf in firmware. There are + * some commands which need to run in MAX_PERF mode like store_recall etc + * This function changes the power modeto MAX_PERF and will not + * intimate the application. Later after the command succeeds, + * use restore_power_state to change to original power state + * Note: Application should not directly use this function + * int32_t - module which request the change + * Returns- A_OK on success, A_ERROR otherwise + *****************************************************************************/ +A_STATUS move_power_state_to_maxperf(void *pCxt, int32_t module) +{ + A_DRIVER_CONTEXT *pDCxt = (A_DRIVER_CONTEXT *)pCxt; + + /* Already some HIGH module changes state */ + if (power_state_for_module >= module) + { + return A_OK; + } + + /* Change the power mode only when the current power mode is REC_POWER */ + if (pDCxt->userPwrMode == REC_POWER) + { + if (A_OK != wmi_cmd_start(pDCxt->pWmiCxt, &max_performance_power_param, WMI_SET_POWER_MODE_CMDID, + sizeof(WMI_POWER_MODE_CMD))) + { + return A_ERROR; + } + } + power_state_for_module = module; + return A_OK; +} +#endif +A_STATUS wait_scan_done(void *pCxt, void *pWmi) +{ + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + + if (pDCxt->scanDone == false) + { + /* block until scan completes */ + DRIVER_WAIT_FOR_CONDITION(pCxt, &(pDCxt->scanDone), true, 5000); + + if (pDCxt->scanDone == false) + { + wmi_bssfilter_cmd(pWmi, NONE_BSS_FILTER, 0); + } + return A_ERROR; + } + pDCxt->scanDone = false; + return A_OK; +} + +A_STATUS scan_setup(void *pCxt, void *pWmi, WMI_START_SCAN_CMD *start_scan) +{ + union + { + WMI_START_SCAN_CMD scan_cmd; + WMI_PROBED_SSID_CMD probeParam; + } stackU; + A_STATUS error = A_OK; + uint32_t size; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + + do + { + if (pDCxt->conn[pDCxt->devId].ssidLen > 0) + { + /* apply filter ssid */ + stackU.probeParam.entryIndex = 1; + stackU.probeParam.flag = SPECIFIC_SSID_FLAG; + stackU.probeParam.ssidLength = pDCxt->conn[pDCxt->devId].ssidLen; + A_MEMCPY(stackU.probeParam.ssid, pDCxt->conn[pDCxt->devId].ssid, pDCxt->conn[pDCxt->devId].ssidLen); + + if (A_OK != wmi_cmd_start(pWmi, &stackU.probeParam, WMI_SET_PROBED_SSID_CMDID, sizeof(WMI_PROBED_SSID_CMD))) + { + error = A_ERROR; + break; + } + + if (A_OK != wmi_bssfilter_cmd(pWmi, PROBED_SSID_FILTER, 0)) + { + error = A_ERROR; + break; + } + } + else + { + /* clear any pre-existing filter ssid */ + stackU.probeParam.entryIndex = 1; + stackU.probeParam.flag = DISABLE_SSID_FLAG; + stackU.probeParam.ssidLength = 0; + + if (A_OK != wmi_cmd_start(pWmi, &stackU.probeParam, WMI_SET_PROBED_SSID_CMDID, sizeof(WMI_PROBED_SSID_CMD))) + { + error = A_ERROR; + break; + } + + if (A_OK != wmi_bssfilter_cmd(pWmi, ALL_BSS_FILTER, 0)) + { + error = A_ERROR; + break; + } + } + + GET_DRIVER_COMMON(pCxt)->scanOutSize = ATH_MAX_SCAN_BUFFERS; + GET_DRIVER_COMMON(pCxt)->scanOutCount = 0; + pDCxt->scanDone = false; + /* start the scan */ + if (start_scan == NULL) + { + A_MEMZERO(&stackU.scan_cmd, sizeof(WMI_START_SCAN_CMD)); + stackU.scan_cmd.scanType = WMI_LONG_SCAN; + stackU.scan_cmd.forceFgScan = false; + stackU.scan_cmd.isLegacy = false; + stackU.scan_cmd.homeDwellTime = 0; + stackU.scan_cmd.forceScanInterval = 1; + stackU.scan_cmd.numChannels = 0; + if (A_OK != wmi_cmd_start(pWmi, (void *)&stackU.scan_cmd, WMI_START_SCAN_CMDID, sizeof(WMI_START_SCAN_CMD))) + { + error = A_ERROR; + } + } + else + { + size = sizeof(WMI_START_SCAN_CMD); + if (start_scan->numChannels > 0) + { + size = size + (start_scan->numChannels - 1) * sizeof(uint16_t); + } + + if (A_OK != wmi_cmd_start(pWmi, (void *)start_scan, WMI_START_SCAN_CMDID, size)) + { + error = A_ERROR; + } + } + + } while (0); + + return error; +} + +uint8_t Util_Ascii2Hex(char val) +{ + if ('0' <= val && '9' >= val) + { + return (uint8_t)(val - '0'); + } + else if ('a' <= val && 'f' >= val) + { + return (uint8_t)((val - 'a') + 0x0a); + } + else if ('A' <= val && 'F' >= val) + { + return (uint8_t)((val - 'A') + 0x0a); + } + + return 0xff; /* error */ +} + +A_STATUS +TxRawPacket(void *pCxt, void *pReq, ATH_MAC_TX_PARAMS *pParams) +{ + WMI_TX_META_V3 v3_meta; + HTC_ENDPOINT_ID eid; + A_DRIVER_CONTEXT *pDCxt; + A_STATUS status = A_ERROR; + + eid = Util_AC2EndpointID(pCxt, WMM_AC_BE); + A_NETBUF_SET_ELEM(pReq, A_REQ_EPID, eid); + pDCxt = GET_DRIVER_COMMON(pCxt); + + do + { + /* translate from ATH_MAC_TX_PARAMS to WMI_TX_META_V3 */ + /* how convenient the values are all the same */ + v3_meta.pktID = pParams->pktID; + A_MEMCPY(&v3_meta.rateSched.rateSeries, &pParams->rateSched.rateSeries, + sizeof(uint8_t) * WMI_TX_MAX_RATE_SERIES); + A_MEMCPY(&v3_meta.rateSched.trySeries, &pParams->rateSched.trySeries, sizeof(uint8_t) * WMI_TX_MAX_RATE_SERIES); + v3_meta.rateSched.flags = pParams->rateSched.flags; + v3_meta.rateSched.accessCategory = pParams->rateSched.accessCategory; + + if (wmi_data_hdr_add(pDCxt->pWmiCxt, pReq, DATA_MSGTYPE, false, WMI_DATA_HDR_DATA_TYPE_802_11, + WMI_META_VERSION_3, (void *)&v3_meta) != A_OK) + { + break; + } + A_MDELAY(2); + /* HTC interface is asynchronous, if this fails, cleanup will happen in + * the ar6000_tx_complete callback */ + if (A_OK != Driver_SubmitTxRequest((void *)pCxt, pReq)) + { + A_NETBUF_FREE(pReq); + break; + } + + status = A_OK; + } while (0); + + return status; +} + +/* EOF */ diff --git a/platform/mcu/lpc54102/wifi_qca/common_src/api_interface/api_txrx.c b/platform/mcu/lpc54102/wifi_qca/common_src/api_interface/api_txrx.c new file mode 100644 index 0000000000..0156541e28 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/common_src/api_interface/api_txrx.c @@ -0,0 +1,446 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== +#include "wifi_common.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*****************************************************************************/ +/* query_credit_deficit - Executed by the driver task to satisfy the + * Api_TxGetStatus() request. It will query the wifi credit counters on + * the Wifi device as needed to get the most up-to-date tx credit status. + * void *pCxt - the driver context. + *****************************************************************************/ +static A_STATUS query_credit_deficit(void *pCxt) +{ + uint32_t reg; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + + do + { + if ((pDCxt->booleans & (SDHD_BOOL_FATAL_ERROR | SDHD_BOOL_DMA_IN_PROG | SDHD_BOOL_DMA_WRITE_WAIT_FOR_BUFFER))) + { + break; + } + + reg = Htc_ReadCreditCounter(pCxt, 1); + pDCxt->txQueryResult = (reg & 0x80000000) ? 1 : 0; + } while (0); + + pDCxt->asynchRequest = NULL; + pDCxt->txQueryInProgress = false; + DRIVER_WAKE_USER(pCxt); + return A_OK; +} + +/*****************************************************************************/ +/* Api_TxGetStatus - Learns the status regarding any TX requests. it will + * test the state of the driver first to learn if any TX requests are + * remaining on the host side. if none then it will test the state of + * the HTC credits to learn if any TX requests are still being processed + * by the WIFI device. If none then the function will return the idle + * status. + * void *pCxt - the driver context. + *****************************************************************************/ +uint16_t Api_TxGetStatus(void *pCxt) +{ + uint16_t status = ATH_TX_STATUS_IDLE; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + + do + { + if (0 != A_NETBUF_QUEUE_SIZE(&(pDCxt->txQueue)) || pDCxt->driver_state == DRIVER_STATE_TX_PROCESSING) + { + status = ATH_TX_STATUS_HOST_PENDING; + break; + } + /* Check the AR410X status */ + status = ATH_TX_STATUS_WIFI_PENDING; + /* set up driver operation to read credits from device */ + if (pDCxt->asynchRequest == NULL) + { + pDCxt->txQueryInProgress = true; + pDCxt->asynchRequest = query_credit_deficit; + DRIVER_WAKE_DRIVER(pCxt); + DRIVER_WAIT_FOR_CONDITION(pCxt, &(pDCxt->txQueryInProgress), false, 5000); + + if (pDCxt->txQueryInProgress == false) + { + if (pDCxt->txQueryResult == 0) + { + status = ATH_TX_STATUS_IDLE; + } + } + } + } while (0); + + return status; +} + +/*****************************************************************************/ +/* API_TxComplete - Brings a transmit packet to its final conclusion. The + * packet is either a data packet in which case it will be freed back to + * the caller, or it is a wmi command in which case it will freed. + * void *pCxt - the driver context. + * void *pReq - the packet. + *****************************************************************************/ +void Api_TxComplete(void *pCxt, void *pReq) +{ + /* some user tasks may have blocked until a transmit complete occurs + * these lines wake up these tasks. */ + GET_DRIVER_COMMON(pCxt)->tx_complete_pend = false; + DRIVER_WAKE_USER(pCxt); + + if (ath_custom_init.Api_TxComplete != NULL) + { + ath_custom_init.Api_TxComplete(pCxt, pReq); + return; + } + else + { + API_TXCOMPLETE(pCxt, pReq); + A_NETBUF_FREE(pReq); + } +} + +/*****************************************************************************/ +/* API_RxComplete - Brings a received packet to its final conclusion. The + * packet is either a data packet in which case it will be processed and + * sent to the network layer, or it is a wmi event in which case it will + * be delivered to the wmi layer. + * void *pCxt - the driver context. + * void *pReq - the packet. + *****************************************************************************/ +void Api_RxComplete(void *pCxt, void *pReq) +{ + A_STATUS status = A_OK; + uint16_t minHdrLen; + uint16_t packetLen; + uint8_t containsDot11Hdr = 0; + WMI_DATA_HDR *dhdr; +#if WLAN_CONFIG_11N_AGGR_SUPPORT +#if !ENABLE_STACK_OFFLOAD + ATH_MAC_HDR *mac_hdr; +#endif +#endif + uint8_t is_amsdu, is_acl_data_frame; +#if !ENABLE_STACK_OFFLOAD + uint16_t seq_no; + uint8_t tid; +#endif + uint8_t devId; + uint8_t meta_type; + HTC_ENDPOINT_ID ept = (HTC_ENDPOINT_ID)A_NETBUF_GET_ELEM(pReq, A_REQ_EPID); + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + /* take lock to protect buffer counts + * and adaptive power throughput state */ + + if (ath_custom_init.Api_RxComplete != NULL) + { + ath_custom_init.Api_RxComplete(pCxt, pReq); + return; + } + else + { + if (pDCxt->wmiEnabled == true) + { + if (ept == ENDPOINT_1) + { + /* + * this is a wmi control packet. + */ + wmi_control_rx(pDCxt->pWmiCxt, pReq); + } + else if (pDCxt->promiscuous_mode) + { + wmi_data_hdr_remove(pDCxt->pWmiCxt, pReq); + CUSTOM_DELIVER_FRAME(pCxt, pReq); + status = A_OK; + } + else + { + /* + * this is a data packet. + */ + dhdr = (WMI_DATA_HDR *)A_NETBUF_DATA(pReq); + packetLen = A_NETBUF_LEN(pReq); + dhdr->info2 = A_LE2CPU16(dhdr->info2); + dhdr->info3 = A_LE2CPU16(dhdr->info3); + is_acl_data_frame = (uint8_t)(WMI_DATA_HDR_GET_DATA_TYPE(dhdr) == WMI_DATA_HDR_DATA_TYPE_ACL); + + devId = WMI_DATA_HDR_GET_DEVID(dhdr); + + minHdrLen = MIN_HDR_LEN; + + /* In the case of AP mode we may receive NULL data frames + * that do not have LLC hdr. They are 16 bytes in size. + * Allow these frames in the AP mode. + * ACL data frames don't follow ethernet frame bounds for + * min length + */ + do + { + if ((pDCxt->conn[devId].networkType != AP_NETWORK && (packetLen < minHdrLen)) || + (packetLen > AR4100_MAX_RX_MESSAGE_SIZE)) + { + /* + * packet is too short or too long + */ + status = A_ERROR; + break; + } + else + { + is_amsdu = (uint8_t)WMI_DATA_HDR_IS_AMSDU(dhdr); +#if !ENABLE_STACK_OFFLOAD + tid = (uint8_t)WMI_DATA_HDR_GET_UP(dhdr); + seq_no = (uint16_t)(WMI_DATA_HDR_GET_SEQNO(dhdr)); +#endif + meta_type = (uint8_t)WMI_DATA_HDR_GET_META(dhdr); + containsDot11Hdr = (uint8_t)WMI_DATA_HDR_GET_DOT11(dhdr); + /* NOTE: rssi is not currently managed on a per peer basis. + * therefore, if multiple peers are sending packets to + * this radio the rssi will be averaged across all + * indiscriminately. + */ + /* simple averaging algorithm. 7/8 of original value is combined + * with 1/8 of new value unless original value is 0 in which case + * just adopt the new value as its probably the first in the + * connection. + */ + pDCxt->rssi = (int8_t)((pDCxt->rssi) ? (pDCxt->rssi * 7 + dhdr->rssi) >> 3 : dhdr->rssi); + wmi_data_hdr_remove(pDCxt->pWmiCxt, pReq); + + if (meta_type) + { + /* this code does not accept per frame + * meta data */ + A_ASSERT(0); + } + /* NWF: print the 802.11 hdr bytes */ + if (containsDot11Hdr) + { + /* this code does not accept dot11 headers */ + A_ASSERT(0); + } + else if (!is_amsdu && !is_acl_data_frame) + { + status = WMI_DOT3_2_DIX(pReq); + } + else + { + /* this code does not accept amsdu or acl data */ + A_ASSERT(0); + } + + if (status != A_OK) + { + /* Drop frames that could not be processed (lack of memory, etc.) */ + break; + } + +#if WLAN_CONFIG_11N_AGGR_SUPPORT +#if !ENABLE_STACK_OFFLOAD + mac_hdr = A_NETBUF_DATA(pReq); + /*Check if packet is multicast, if so, do not check for aggregation*/ + if ((mac_hdr->dstMac[0] & 0x01) == 0) + { + if (false == aggr_process_recv_frm(pDCxt->pAggrCxt, tid, seq_no, is_amsdu, (void **)&pReq)) + { + status = A_ERROR; + break; + } + } +#endif /* !ENABLE_STACK_OFFLOAD*/ +#endif /* WLAN_CONFIG_11N_AGGR_SUPPORT */ + CUSTOM_DELIVER_FRAME(pCxt, pReq); + status = A_OK; + } + } while (0); + + if (A_OK != status) + { + A_NETBUF_FREE(pReq); + } + } + } + else + { + A_NETBUF_FREE(pReq); + } + + return; + } +} + +/*****************************************************************************/ +/* API_WmiTxStart - Function used by WMI via A_WMI_CONTROL_TX() to send + * a WMI command. + * void *pCxt - the driver context. + * void *pReq - the packet. + *****************************************************************************/ +A_STATUS +Api_WmiTxStart(void *pCxt, void *pReq, HTC_ENDPOINT_ID eid) +{ + A_STATUS status = A_ERROR; + + do + { + A_NETBUF_SET_ELEM(pReq, A_REQ_EPID, eid); + + if (A_OK != Driver_SubmitTxRequest(pCxt, pReq)) + { + break; + } + + status = A_OK; + } while (0); + + return status; +} + +/*****************************************************************************/ +/* Api_DataTxStart - Starts the process of transmitting a data packet (pReq). + * Various checks are performed to ensure the driver and device are ready + * to open the data path. A dot.3 header is pre-pended if necessary and a + * WMI_DATA_HDR is pre-pended. In a multi-threaded system this function is + * expected to be executed on a non-driver thread. + * void *pCxt - the driver context. + * void *pReq - the Transmit packet. + *****************************************************************************/ +A_STATUS +Api_DataTxStart(void *pCxt, void *pReq) +{ +#define AC_NOT_MAPPED 99 + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + uint8_t ac = AC_NOT_MAPPED; + HTC_ENDPOINT_ID eid = ENDPOINT_UNUSED; + boolean bMoreData = false; + uint8_t dot11Hdr = WLAN_CONFIG_TX_DOT11_HDR; + A_STATUS status = A_ERROR; + WMI_TX_META_V5 ip_meta; + + do + { + /* If target is not associated */ + if ((false == pDCxt->conn[0].isConnected && false == pDCxt->conn[0].isConnectPending) +#if (WLAN_NUM_OF_DEVICES > 1) + && (false == pDCxt->conn[1].isConnected && false == pDCxt->conn[1].isConnectPending) +#endif + ) + { + break; + } + else if ((false == pDCxt->conn[0].isConnected) +#if (WLAN_NUM_OF_DEVICES > 1) + && (false == pDCxt->conn[1].isConnected) +#endif + ) + { + // block until connection completes. + DRIVER_WAIT_FOR_CONDITION(pCxt, &(pDCxt->conn[0].isConnected), true, 5000); + + if ((false == pDCxt->conn[0].isConnected) +#if (WLAN_NUM_OF_DEVICES > 1) + && (false == pDCxt->conn[1].isConnected) +#endif + ) + { + break; + } + } + + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_TX)) + { + break; + } + + if (pDCxt->wmiReady == false) + { + break; + } + + if (false == pDCxt->wmiEnabled) + { + break; + } + +/* add wmi_data_hdr to front of frame */ +#if ENABLE_STACK_OFFLOAD + if (wmi_data_hdr_add(pDCxt->pWmiCxt, pReq, DATA_MSGTYPE, bMoreData, + (dot11Hdr) ? WMI_DATA_HDR_DATA_TYPE_802_11 : WMI_DATA_HDR_DATA_TYPE_802_3, + WMI_META_VERSION_5, (void *)&ip_meta) != A_OK) + { + break; + } +#else + /* convert frame header */ + if (wmi_dix_2_dot3(pDCxt->pWmiCxt, pReq) != A_OK) + { + break; + } + + if (wmi_data_hdr_add(pDCxt->pWmiCxt, pReq, DATA_MSGTYPE, bMoreData, + (dot11Hdr) ? WMI_DATA_HDR_DATA_TYPE_802_11 : WMI_DATA_HDR_DATA_TYPE_802_3, 0, + NULL) != A_OK) + { + break; + } +#endif + /* get the stream mapping */ + ac = wmi_implicit_create_pstream(pDCxt->pWmiCxt, pReq, 0, pDCxt->wmmEnabled); + eid = Util_AC2EndpointID(pCxt, ac); + + if (eid && eid != ENDPOINT_UNUSED) + { + A_NETBUF_SET_ELEM(pReq, A_REQ_EPID, eid); + /* Submit for transmission to next layer */ + if (A_OK != Driver_SubmitTxRequest(pCxt, pReq)) + { + break; + } + } + else + { + break; + } + + status = A_OK; + } while (0); + + return status; +} diff --git a/platform/mcu/lpc54102/wifi_qca/common_src/api_interface/api_wmi_rx.c b/platform/mcu/lpc54102/wifi_qca/common_src/api_interface/api_wmi_rx.c new file mode 100644 index 0000000000..681c6e27df --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/common_src/api_interface/api_wmi_rx.c @@ -0,0 +1,1596 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== +#include "wifi_common.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include //IGX_UD_CHANGES +#include //IGX_UD_CHANGES +#include +#include + +#if ENABLE_P2P_MODE +#include "p2p.h" +#include "wmi.h" +#include "wmi_api.h" +#include "wmi_host.h" +// WPS_CREDENTIAL persistCredential; +// WMI_WPS_PROFILE_EVENT wpsProfEv; +#endif + +#include "dset.h" +#include "dset_api.h" + +extern const uint8_t max_performance_power_param; +extern const WMI_SCAN_PARAMS_CMD default_scan_param; + +/*****************************************************************************/ +/* Api_TargetStatsEvent - Processes WMI_REPORT_STATISTICS_EVENTID + * from the device. + * void *pCxt - the driver context. + * uint8_t *ptr - pointer to the stats buffer. + * uint32_t len - length of the ptr buffer. + *****************************************************************************/ +void Api_TargetStatsEvent(void *pCxt, uint8_t devId, uint8_t *ptr, uint32_t len) +{ + UNUSED_ARGUMENT(devId); + if (ptr != NULL && len != 0) + { + GET_DRIVER_COMMON(pCxt)->rssi = ((WMI_TARGET_STATS *)ptr)->cservStats.cs_snr; + } + GET_DRIVER_COMMON(pCxt)->rssiFlag = false; + API_TARGET_STATS_EVENT(pCxt, ptr, len); +} + +/*****************************************************************************/ +/* Api_RegDomainEvent - Processes WMI_REGDOMAIN_EVENTID from the device. + * void *pCxt - the driver context. + * uint32_t regCode - the encoded regulatory domain value. + *****************************************************************************/ +void Api_RegDomainEvent(void *pCxt, uint8_t devId, uint32_t regCode) +{ + UNUSED_ARGUMENT(devId); + // A_PRINTF("AR4XXX Reg Code = 0x%x\n", regCode); + GET_DRIVER_COMMON(pCxt)->regCode = regCode; + API_REGDOMAIN_EVENT(pCxt, regCode); +} + +/*****************************************************************************/ +/* Api_BitrateEvent - Processes WMI_BIT_RATE_REPLY from the device. + * void *pCxt - the driver context. + * int32_t rateKbps - the rate in Kbps used for recent transmission. + *****************************************************************************/ +void Api_BitrateEvent(void *pCxt, uint8_t devId, int32_t rateKbps) +{ + UNUSED_ARGUMENT(devId); + GET_DRIVER_COMMON(pCxt)->bitRate = rateKbps; + API_BITRATE_EVENT(pCxt, rateKbps); +} + +/*****************************************************************************/ +/* Api_GetBitRateEvent - Processes WMI_GET_BITRATE_CMDID from the device. + * void *pCxt - the driver context. + * uint8_t *datap - the rate index for recent transmission is in this pointer. + *****************************************************************************/ +void Api_GetBitRateEvent(void *pCxt, uint8_t devId, void *datap) +{ + UNUSED_ARGUMENT(devId); + CUSTOM_API_BITRATE_EVENT_TX(pCxt, devId, ((WMI_BIT_RATE_REPLY *)datap)->rateIndex); +} + +/*****************************************************************************/ +/* Api_ChannelListEvent - Processes a WMI_GET_CHANNEL_LIST_CMD from the device. + * This event will come when the host issues a WMI_GET_CHANNEL_LIST_CMD to + * the device to request a current channel list. + * void *pCxt - the driver context. + * int8_t numChan - number of channels in the list. + * uint16_t *chanList - array of numChan channels. + *****************************************************************************/ +void Api_ChannelListEvent(void *pCxt, uint8_t devId, int8_t numChan, void *chanList) +{ + uint16_t i; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + UNUSED_ARGUMENT(devId); + A_MEMCPY(pDCxt->channelList, chanList, numChan * sizeof(uint16_t)); + pDCxt->numChannels = numChan; + /* convert each channel to proper endianness */ + for (i = 0; i < pDCxt->numChannels; i++) + { + pDCxt->channelList[i] = A_LE2CPU16(pDCxt->channelList[i]); + } + + API_CHANNEL_LIST_EVENT(pCxt, pDCxt->numChannels, pDCxt->channelList); +} + +/*****************************************************************************/ +/* Api_ScanCompleteEvent - Processes a WMI_SCAN_COMPLETE_EVENTID from the device. + * These events will occur if the host has previously initiated a scan request. + * This event indicates the final conclusion of the scan operation. + * void *pCxt - the driver context. + * A_STATUS status - indicates the status of the scan operation. + *****************************************************************************/ +void Api_ScanCompleteEvent(void *pCxt, uint8_t devId, A_STATUS status) +{ + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + + UNUSED_ARGUMENT(status); + UNUSED_ARGUMENT(devId); + + wmi_bssfilter_cmd(pDCxt->pWmiCxt, NONE_BSS_FILTER, 0); + /* host initiated scan */ + pDCxt->scanDone = true; + + Api_BootProfile(pCxt, BOOT_PROFILE_DONE_SCAN); + + API_SCAN_COMPLETE_EVENT(pCxt, status); +} + +/*****************************************************************************/ +/* Api_BssInfoEvent - Processes a WMI_BSS_INFO_EVENT from the device. These + * events will occur if the host has previously initiated a scan request + * void *pCxt - the driver context. + * uint8_t *datap - the original event buffer. + * int32_t len - the length of datap. + *****************************************************************************/ +void Api_BssInfoEvent(void *pCxt, uint8_t devId, uint8_t *datap, int32_t len) +{ + UNUSED_ARGUMENT(devId); + CUSTOM_API_BSS_INFO_EVENT(pCxt, datap, len); +} + +/*****************************************************************************/ +/* Api_TkipMicErrorEvent - Processes a TKIP error event from the device. This + * event can happen when the device is using TKIP security and it detects a + * decryption error. + * void *pCxt - the driver context. + * uint8_t keyid - the Key ID used when the error occurred. + * boolean ismcast - 1 if packet was multi-cast 0 otherwise. + *****************************************************************************/ +void Api_TkipMicErrorEvent(void *pCxt, uint8_t devId, uint8_t keyid, boolean ismcast) +{ + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + UNUSED_ARGUMENT(ismcast); + UNUSED_ARGUMENT(keyid); + UNUSED_ARGUMENT(devId); + pDCxt->tkipCountermeasures = 1; + POWER_MODE pwrmode; + pwrmode.pwr_mode = MAX_PERF_POWER; + pwrmode.pwr_module = TKIP; + + Api_SetPowerMode(pCxt, &pwrmode); + + /* receiving this event informs the host that the wifi device + * encountered 2 TKIP MIC errors within the restricted time span. + * consequently, to fullfill the TKIP countermeasure requirement the + * host must disconnect from the network and remain disconnected for + * the specified period. + */ + wmi_cmd_start(pDCxt->pWmiCxt, NULL, WMI_DISCONNECT_CMDID, 0); + /* can't use A_MDELAY here as the wmi_disconnect_cmd() will + * cause a disconnect_event which should get processed. */ + // A_MDELAY(IEEE80211_TKIP_COUNTERMEASURES_TIMEOUT_MSEC); + API_TKIP_MIC_ERROR_EVENT(pCxt, keyid, ismcast); +} + +/*****************************************************************************/ +/* Api_GetPmkEvent - Processes a WMI_GET_PMK_REPLY from the + * device. + * This event will come when the caller has previously sent a WMI_GET_PMC_CMD. + * The function stores the result in wpaPmk for asynchronous access. + * void *pCxt - the driver context. + * uint8_t *datap - original event buffer. + *****************************************************************************/ +void Api_GetPmkEvent(void *pCxt, uint8_t devId, uint8_t *datap) +{ + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + WMI_GET_PMK_REPLY *pReply = (WMI_GET_PMK_REPLY *)datap; + + A_MEMCPY(pDCxt->conn[devId].wpaPmk, pReply->pmk, WMI_PMK_LEN); + pDCxt->conn[devId].wpaPmkValid = true; + API_GET_PMK_EVENT(pCxt, datap); +} + +/*****************************************************************************/ +/* Api_ConnectEvent - Processes a WMI_CONNECT_EVENT from the + * device. + * This event will come when the device has connected to a BSS + * network. + * void *pCxt - the driver context. + * uint16_t channel - RF channel on which connection exists. + * uint8_t *bssid - bssid address of the network. + * uint16_t listenInterval - assigned listen interval for sleep mode. + * uint16_t beaconInterval - BSS beacon interval. + * NETWORK_TYPE networkType - identifies the type of network. + * uint8_t beaconIeLen - length of beacon Information element. + * uint8_t assocReqLen - length of assocation request frame. + * uint8_t assocRespLen - length of assocation response length. + * uint8_t *assocInfo - pointer to assocation frame(s). + *****************************************************************************/ +void Api_ConnectEvent(void *pCxt, + uint8_t devId, + uint16_t channel, + uint8_t *bssid, + uint16_t listenInterval, + uint16_t beaconInterval, + NETWORK_TYPE networkType, + uint8_t beaconIeLen, + uint8_t assocReqLen, + uint8_t assocRespLen, + uint8_t *assocInfo) +{ + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + A_WEPKEY_T *pKey; + WMI_ADD_CIPHER_KEY_CMD add_key_param; + + UNUSED_ARGUMENT(listenInterval); + UNUSED_ARGUMENT(beaconInterval); + UNUSED_ARGUMENT(beaconIeLen); + UNUSED_ARGUMENT(assocReqLen); + UNUSED_ARGUMENT(assocRespLen); + UNUSED_ARGUMENT(assocInfo); + + /* In SoftAP mode, we will get connect event first time when we start as AP and then whenever a station connects to + * us. + * We should not set the channel and bssid, when the later connect event comes. + * The later connect event has network type as 0. + */ + if (networkType != 0) + { + A_MEMCPY(pDCxt->conn[devId].bssid, bssid, ATH_MAC_LEN); + pDCxt->conn[devId].bssChannel = channel; + } + + if ((networkType & ADHOC_NETWORK) && (OPEN_AUTH == pDCxt->conn[devId].dot11AuthMode) && + (NONE_AUTH == pDCxt->conn[devId].wpaAuthMode) && (WEP_CRYPT == pDCxt->conn[devId].wpaPairwiseCrypto)) + { + /* if we are connecting for the first time to an ad-hoc network with + * WEP. then submit the key via wmi_addKey_cmd */ + if (false == pDCxt->conn[devId].isConnected) + { + pKey = &(pDCxt->conn[devId].wepKeyList[pDCxt->conn[devId].wepDefTxKeyIndex]); + A_MEMZERO(&add_key_param, sizeof(add_key_param)); + add_key_param.keyIndex = pDCxt->conn[devId].wepDefTxKeyIndex; + add_key_param.keyType = WEP_CRYPT; + add_key_param.keyUsage = GROUP_USAGE | TX_USAGE; + add_key_param.keyLength = pKey->keyLen; + A_MEMCPY(&add_key_param.key, pKey->key, add_key_param.keyLength); + add_key_param.key_op_ctrl = KEY_OP_INIT_VAL; + wmi_cmd_start(pDCxt->pWmiCxt, &add_key_param, WMI_ADD_CIPHER_KEY_CMDID, sizeof(WMI_ADD_CIPHER_KEY_CMD)); + } + } + + /* Update connect & link status atomically */ + DRIVER_SHARED_RESOURCE_ACCESS_ACQUIRE(pCxt); + { + pDCxt->conn[devId].isConnected = true; + pDCxt->conn[devId].isConnectPending = false; + if ((channel > 2000) && (channel < 6500)) + { + pDCxt->conn[devId].channelHint = channel; + } + } + DRIVER_SHARED_RESOURCE_ACCESS_RELEASE(pCxt); + + Api_BootProfile(pCxt, BOOT_PROFILE_DONE_CONNECT); + + pDCxt->rssi = 0; + +/* reset the rx aggr state */ + +#if WLAN_CONFIG_11N_AGGR_SUPPORT + aggr_reset_state(pDCxt->pAggrCxt); +#endif + if (pDCxt->wps_in_progress && pDCxt->devId == devId) + { + pDCxt->wps_in_progress = 0; + } + + CUSTOM_API_CONNECT_EVENT(pCxt, devId, channel, bssid, listenInterval, beaconInterval, networkType, beaconIeLen, + assocReqLen, assocRespLen, assocInfo); +} + +/*****************************************************************************/ +/* Api_DisconnectEvent - Processes a WMI_DISCONNECT_EVENT from the + * device. + * This event will come when the device has disconnected from the BSS + * network. + * void *pCxt - the driver context. + * uint8_t reason - encoded reason for the disconnection. + * uint8_t *bssid - bssid address of the network. + * uint8_t assocRespLen - association response frame length. + * uint8_t *assocInfo - association response frame payload. + * uint16_t protocolReasonStatus - reason field from assocation response + * frame. + *****************************************************************************/ +void Api_DisconnectEvent(void *pCxt, + uint8_t devId, + uint8_t reason, + uint8_t *bssid, + uint8_t assocRespLen, + uint8_t *assocInfo, + uint16_t protocolReasonStatus) +{ + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + POWER_MODE pwrmode; + + UNUSED_ARGUMENT(bssid); + UNUSED_ARGUMENT(assocRespLen); + UNUSED_ARGUMENT(assocInfo); + UNUSED_ARGUMENT(protocolReasonStatus); +/* it is necessary to clear the host-side rx aggregation state */ +#if WLAN_CONFIG_11N_AGGR_SUPPORT + aggr_reset_state(pDCxt->pAggrCxt); +#endif + + /* + * If the event is due to disconnect cmd from the host, only they the target + * would stop trying to connect. Under any other condition, target would + * keep trying to connect. + * + */ + if (reason == DISCONNECT_CMD) + { + pDCxt->conn[devId].isConnectPending = false; + } + else + { + pDCxt->conn[devId].isConnectPending = true; + } + + /* Update connect & link status atomically */ + DRIVER_SHARED_RESOURCE_ACCESS_ACQUIRE(pCxt); + pDCxt->conn[devId].isConnected = false; + pDCxt->conn[devId].channelHint = 0; + DRIVER_SHARED_RESOURCE_ACCESS_RELEASE(pCxt); + pDCxt->rssi = 0; + A_MEMZERO(pDCxt->conn[devId].bssid, ATH_MAC_LEN); + pDCxt->conn[devId].bssChannel = 0; + + if (pDCxt->wps_in_progress && pDCxt->devId == devId) + { + pDCxt->wps_in_progress = 0; + } + CUSTOM_API_DISCONNECT_EVENT(pCxt, devId, reason, bssid, assocRespLen, assocInfo, protocolReasonStatus); + /* complete TKIP countermeasures operation. TKIP countermeasures + * requires that the STA avoid any contact with the AP for 60 seconds. + * this implementation simply blocks for that time via A_MDELAY(). + * Other implementations may choose to behave differently. */ + if (pDCxt->tkipCountermeasures != 0) + { + /* FIXME: should instead implement a way to block the driver at driver_main thus + * allowing the thread to continue running in single-threaded systems.*/ + A_MDELAY(IEEE80211_TKIP_COUNTERMEASURES_TIMEOUT_MSEC); + pDCxt->tkipCountermeasures = 0; + Api_ConnectWiFi(pCxt); + A_MDELAY(200); + + pwrmode.pwr_mode = REC_POWER; + pwrmode.pwr_module = TKIP; + Api_SetPowerMode(pCxt, &pwrmode); + } +} + +int dset_length; + +void Api_HostDsetStoreEvent(void *pCxt, uint8_t devId, uint8_t *datap, int32_t len, void *pReq) +{ + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + uint8_t *strrclData = pDCxt->tempStorage; + uint16_t cur_len = pDCxt->strrclCxtLen; + + WMI_HOST_DSET_STORE_EVENT *pDsetEvent = (WMI_HOST_DSET_STORE_EVENT *)datap; + UNUSED_ARGUMENT(devId); + + dset_length = pDsetEvent->length; + + strrclData = pDCxt->tempStorage + cur_len; + + if (cur_len + dset_length <= pDCxt->tempStorageLength) + { + A_MEMCPY(strrclData, pDsetEvent->data, dset_length); + } + else + { + A_ASSERT(0); + } + pDCxt->strrclCxtLen += dset_length; +} + +#if 0 +A_STATUS +wmi_storerecall_recall_cmd(struct wmi_t *wmip, uint32_t length, void* pData) +{ + void *osbuf; + WMI_STORERECALL_RECALL_CMD *p; + uint32_t msgLength = sizeof(WMI_STORERECALL_RECALL_CMD) - sizeof(uint8_t); + + osbuf = A_NETBUF_ALLOC((int32_t)msgLength); + if (osbuf == NULL) { + return A_NO_MEMORY; + } + + A_NETBUF_PUT(osbuf, (int32_t)msgLength); + + p = (WMI_STORERECALL_RECALL_CMD *)(A_NETBUF_DATA(osbuf)); + + p->length = A_CPU2LE32(length); + //A_MEMCPY(&p->data[0], pData, length); + /* here we append the payload to the msg rather than copy it. this is a + * memory and CPU optimization as the payload can be very large. + */ + A_NETBUF_APPEND_FRAGMENT(osbuf, pData, length); + + return (wmi_cmd_send(wmip, osbuf, WMI_STORERECALL_RECALL_CMDID, NO_SYNC_WMIFLAG)); +} +#endif + +void Api_HostDsetCreateEvent(void *pCxt, uint8_t devId, uint8_t *datap, int32_t len, void *pReq) +{ + void *osbuf; + uint32_t msgLength; + WMI_HOST_DSET_RESP_CREATE_CMD *p; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + HOST_DSET *pHost; + + UNUSED_ARGUMENT(devId); + + WMI_HOST_DSET_CREATE_EVENT *pDsetEvent = (WMI_HOST_DSET_CREATE_EVENT *)datap; + pHost = dset_get(pDsetEvent->dset_id, pDsetEvent->length); + QCADRV_PRINTF("dset create id=%d length=%d\n", pDsetEvent->dset_id, pDsetEvent->length); + + /* + * respose KF dset create request + */ + msgLength = sizeof(WMI_HOST_DSET_RESP_CREATE_CMD); + osbuf = A_NETBUF_ALLOC((int32_t)msgLength); + + //NOTE: coverity fix + A_ASSERT(!(NULL == osbuf)); + if (NULL == osbuf) + { + return; + } + + A_NETBUF_PUT(osbuf, (int32_t)(msgLength)); + + p = (WMI_HOST_DSET_RESP_CREATE_CMD *)(A_NETBUF_DATA(osbuf)); + if (pHost != NULL) + p->flags = 0; + else + p->flags = 1; + + wmi_cmd_send(pDCxt->pWmiCxt, osbuf, WMI_HOST_DSET_RESP_CREATE_CMDID, NO_SYNC_WMIFLAG); +} + +void Api_HostDsetWriteEvent(void *pCxt, uint8_t devId, uint8_t *datap, int32_t len, void *pReq) +{ + void *osbuf; + uint32_t msgLength; + WMI_HOST_DSET_RESP_WRITE_CMD *p; + HOST_DSET *pDset = NULL; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + + WMI_HOST_DSET_WRITE_EVENT *pDsetEvent = (WMI_HOST_DSET_WRITE_EVENT *)datap; + + if (IS_STRRCL_DSET(pDsetEvent->dset_id)) + { + pDset = dset_get(pDsetEvent->dset_id, pDsetEvent->length); + } + + if (pDset == NULL) + return; + + QCADRV_PRINTF("dset write id=%d offset:%d length=%d\n", pDsetEvent->dset_id, pDsetEvent->offset, + pDsetEvent->length); + dset_write(pDset, pDsetEvent->data, pDsetEvent->offset, pDsetEvent->length); + + /* + * respose KF dset write request + */ + msgLength = sizeof(WMI_HOST_DSET_RESP_WRITE_CMD); + osbuf = A_NETBUF_ALLOC((int32_t)msgLength); + + //NOTE: coverity fix + A_ASSERT(!(NULL == osbuf)); + if (NULL == osbuf) + { + return; + } + + A_NETBUF_PUT(osbuf, (int32_t)(msgLength)); + + p = (WMI_HOST_DSET_RESP_WRITE_CMD *)(A_NETBUF_DATA(osbuf)); + p->dset_id = pDsetEvent->dset_id; + p->offset = pDsetEvent->offset; + p->length = pDsetEvent->length; + + wmi_cmd_send(pDCxt->pWmiCxt, osbuf, WMI_HOST_DSET_RESP_WRITE_CMDID, NO_SYNC_WMIFLAG); +} + +void Api_HostDsetReadbackEvent(void *pCxt, uint8_t devId, uint8_t *datap, int32_t len, void *pReq) +{ + HOST_DSET *pDset; + uint32_t msgLength; + uint32_t strrcl_offset; + uint32_t offset, length; + // WMI_STORERECALL_RECALL_DSET *pRecallDset; + + uint16_t snd_size; + void *osbuf; + WMI_HOST_DSET_READBACK_CMD *p; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + + UNUSED_ARGUMENT(devId); + + WMI_HOST_DSET_READBACK_EVENT *pDsetEvent = (WMI_HOST_DSET_READBACK_EVENT *)datap; + + msgLength = sizeof(WMI_HOST_DSET_READBACK_CMD) - sizeof(uint8_t); + QCADRV_PRINTF("dset id=%d\n", pDsetEvent->dset_id); + + pDset = dset_find(pDsetEvent->dset_id); + + //NOTE: coverity fix + A_ASSERT(!(NULL == pDset)); + if (NULL == pDset) + { + return; + } + + if (IS_STRRCL_DSET(pDsetEvent->dset_id)) + { + // pRecallDset = (WMI_STORERECALL_RECALL_DSET *)pDset->data_ptr; + strrcl_offset = sizeof(WMI_STORERECALL_RECALL_DSET); + } + + offset = pDsetEvent->offset; + length = pDsetEvent->length; + + if (pDset->length < offset + length) + length = pDset->length - offset; + + while (length > 0) + { + if (length > MAX_EVENT_SIZE) + snd_size = MAX_EVENT_SIZE; + else + snd_size = length; + + osbuf = A_NETBUF_ALLOC((int32_t)msgLength + snd_size); + if (osbuf == NULL) + { + return; + } + + A_NETBUF_PUT(osbuf, (int32_t)(msgLength + snd_size)); + p = (WMI_HOST_DSET_READBACK_CMD *)(A_NETBUF_DATA(osbuf)); + p->dset_id = pDsetEvent->dset_id; + + p->offset = offset; + p->length = snd_size; + + dset_read(pDset, p->data, offset + strrcl_offset, snd_size); + wmi_cmd_send(pDCxt->pWmiCxt, osbuf, WMI_HOST_DSET_READBACK_CMDID, NO_SYNC_WMIFLAG); + + offset += snd_size; + length -= snd_size; + } + + restore_power_state(pDCxt, 1); + A_MDELAY(50); +} + +void Api_HostDsetSyncEvent(void *pCxt, uint8_t devId, uint8_t *datap, int32_t len, void *pReq) +{ + uint32_t msgLength; + uint16_t count; + void *osbuf; + WMI_HOST_DSET_SYNC_CMD *p; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + + UNUSED_ARGUMENT(devId); + + WMI_HOST_DSET_SYNC_EVENT *pDsetEvent = (WMI_HOST_DSET_SYNC_EVENT *)datap; + + if (pDsetEvent->dset_count < MAX_DSET_SIZE) + count = pDsetEvent->dset_count; + else + count = MAX_DSET_SIZE; + + msgLength = sizeof(WMI_HOST_DSET_SYNC_CMD) - sizeof(uint8_t); + + dset_length = sizeof(HOST_DSET_ITEM) * count; + osbuf = A_NETBUF_ALLOC((int32_t)msgLength + dset_length); + if (osbuf == NULL) + { + return; + } + + A_NETBUF_PUT(osbuf, (int32_t)(msgLength + dset_length)); + p = (WMI_HOST_DSET_SYNC_CMD *)(A_NETBUF_DATA(osbuf)); + + count = dset_fill(&p->data[0], count); + p->dset_count = count; + + wmi_cmd_send(pDCxt->pWmiCxt, osbuf, WMI_HOST_DSET_SYNC_CMDID, NO_SYNC_WMIFLAG); +} + +void Api_HostDsetReadEvent(void *pCxt, uint8_t devId, uint8_t *datap, int32_t len, void *pReq) +{ + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + uint8_t *strrclData = pDCxt->tempStorage; + void *osbuf; + WMI_STORERECALL_READ_CMD *p; + uint32_t msgLength = sizeof(WMI_STORERECALL_READ_CMD) - sizeof(uint8_t); + + UNUSED_ARGUMENT(devId); + + osbuf = A_NETBUF_ALLOC((int32_t)msgLength + dset_length); + if (osbuf == NULL) + { + return; + } + + A_NETBUF_PUT(osbuf, (int32_t)(msgLength + dset_length)); + + p = (WMI_STORERECALL_READ_CMD *)(A_NETBUF_DATA(osbuf)); + + p->length = A_CPU2LE32(dset_length); + A_MEMCPY(&p->data[0], strrclData, dset_length); + + QCADRV_PRINTF("[%02x][%02x][%02x][%02x] [%02x][%02x]\n", strrclData[0], strrclData[1], strrclData[2], strrclData[3], + strrclData[4], strrclData[5]); + + /* here we append the payload to the msg rather than copy it. this is a + * memory and CPU optimization as the payload can be very large. + */ + // A_NETBUF_APPEND_FRAGMENT(osbuf, strrclData, dset_length); + + wmi_cmd_send(pDCxt->pWmiCxt, osbuf, WMI_DSET_HOST_READ_CMDID, NO_SYNC_WMIFLAG); +} + +void Api_dset_read_event(A_DRIVER_CONTEXT *pDCxt, HOST_DSET_HANDLE *pDsetHandle, WMI_DSET_OP_READ_EVENT *pRespRead) +{ + uint32_t length; + uint32_t offset, buf_off; + + length = pRespRead->length; + offset = pRespRead->offset; + buf_off = offset - pRespRead->offset; + + if (pRespRead->status == 0) + { + QCADRV_PRINTF("read off:%d len:%d\n", pRespRead->offset, pRespRead->length); + + if (offset + length > pDsetHandle->offset + pDsetHandle->length) + length = pDsetHandle->offset + pDsetHandle->length - offset; + + A_MEMCPY(pDsetHandle->data_ptr + buf_off, pRespRead->data, length); + + pDsetHandle->left_len -= length; + + if (pDsetHandle->left_len != 0) + return; + } + + QCADRV_PRINTF("read done\n"); + + if (pDsetHandle->cb != NULL) + pDsetHandle->cb(pRespRead->status, pDsetHandle->cb_args); +} + +void Api_dset_write_event(A_DRIVER_CONTEXT *pDCxt, HOST_DSET_HANDLE *pDsetHandle, WMI_DSET_OP_READ_EVENT *pRespRead) +{ + uint32_t length; + uint32_t offset; + + length = pRespRead->length; + offset = pRespRead->offset; + + QCADRV_PRINTF("read off:%d len:%d\n", pRespRead->offset, pRespRead->length); + + if (offset + length > pDsetHandle->offset + pDsetHandle->length) + length = pDsetHandle->offset + pDsetHandle->length - offset; + + A_MEMCPY(pDsetHandle->data_ptr + offset, pRespRead->data, length); + + pDsetHandle->left_len -= length; + + if (pDsetHandle->left_len != 0) + return; + + QCADRV_PRINTF("write done\n"); + + if (pDsetHandle->cb != NULL) + pDsetHandle->cb(pRespRead->status, pDsetHandle->cb_args); +} + +void Api_DsetOPEvent(void *pCxt, uint8_t devId, uint8_t *datap, int32_t len, void *pReq) +{ + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + + struct WMIX_DSET_OP_SET_EVENT + { + uint32_t dset_id; + } * pCmd; + HOST_DSET_HANDLE *pDsetHandle; + + QCADRV_PRINTF("dset op event\n"); + + WMI_DSET_OP_EVENT *pDsetOPEvent = (WMI_DSET_OP_EVENT *)datap; + + pCmd = (struct WMIX_DSET_OP_SET_EVENT *)pDsetOPEvent->data; + pDsetHandle = dset_find_handle(pCmd->dset_id); + + //NOTE: coverity fix + A_ASSERT(!(NULL == pDsetHandle)); + if (NULL == pDsetHandle) + { + return; + } + + if (pDsetHandle->cb == NULL && (pDsetOPEvent->hdr.commandId != WMIX_DSET_READ_CMDID)) + pDCxt->dset_op_done = true; + + switch (pDsetOPEvent->hdr.commandId) + { + case WMIX_DSET_CREATE_CMDID: + { + WMI_DSET_OP_CREATE_EVENT *pCreateEvent; + pCreateEvent = (WMI_DSET_OP_CREATE_EVENT *)pDsetOPEvent->data; + + QCADRV_PRINTF("create return: %d\n", pCreateEvent->status); + if (pDsetHandle->cb != NULL) + pDsetHandle->cb(pCreateEvent->status, pDsetHandle->cb_args); + + pDCxt->setparamStatus = pCreateEvent->status; + pDCxt->dset_op_done = true; + break; + } + case WMIX_DSET_OPEN_CMDID: + { + WMI_DSET_OP_CREATE_EVENT *pCreateEvent; + pCreateEvent = (WMI_DSET_OP_CREATE_EVENT *)pDsetOPEvent->data; + + QCADRV_PRINTF("open return: %d\n", pCreateEvent->status); + if (pDsetHandle->cb != NULL) + pDsetHandle->cb(pCreateEvent->status, pDsetHandle->cb_args); + + pDCxt->setparamStatus = pCreateEvent->status; + pDCxt->dset_op_done = true; + break; + } + case WMIX_DSET_READ_CMDID: + { + WMI_DSET_OP_READ_EVENT *pRespRead; + pRespRead = (WMI_DSET_OP_READ_EVENT *)pDsetOPEvent->data; + + Api_dset_read_event(pDCxt, pDsetHandle, pRespRead); + + pDCxt->setparamStatus = pRespRead->status; + pDCxt->dset_op_done = true; + break; + } + case WMIX_DSET_WRITE_CMDID: + { + WMI_DSET_OP_CREATE_EVENT *pCreateEvent; + pCreateEvent = (WMI_DSET_OP_CREATE_EVENT *)pDsetOPEvent->data; + + QCADRV_PRINTF("write return: %d\n", pCreateEvent->status); + if (pDsetHandle->cb != NULL) + pDsetHandle->cb(pCreateEvent->status, pDsetHandle->cb_args); + + pDCxt->setparamStatus = pCreateEvent->status; + pDCxt->dset_op_done = true; + break; + } + case WMIX_DSET_COMMIT_CMDID: + { + WMI_DSET_OP_COMMIT_EVENT *pRespCommit; + pRespCommit = (WMI_DSET_OP_COMMIT_EVENT *)pDsetOPEvent->data; + + QCADRV_PRINTF("commit return: %d\n", pRespCommit->status); + if (pDsetHandle->cb != NULL) + pDsetHandle->cb(pRespCommit->status, pDsetHandle->cb_args); + + pDCxt->setparamStatus = pRespCommit->status; + pDCxt->dset_op_done = true; + break; + } + case WMIX_DSET_CLOSE_CMDID: + { + WMI_DSET_OP_CLOSE_EVENT *pRespClose; + pRespClose = (WMI_DSET_OP_CLOSE_EVENT *)pDsetOPEvent->data; + + QCADRV_PRINTF("close return: %d\n", pRespClose->status); + if (pDsetHandle->cb != NULL) + pDsetHandle->cb(pRespClose->status, pDsetHandle->cb_args); + + pDCxt->setparamStatus = pRespClose->status; + pDCxt->dset_op_done = true; + break; + } + case WMIX_DSET_SIZE_CMDID: + { + WMI_DSET_OP_CREATE_EVENT *pCreateEvent; + pCreateEvent = (WMI_DSET_OP_CREATE_EVENT *)pDsetOPEvent->data; + + QCADRV_PRINTF("size return: %d\n", pCreateEvent->status); + if (pDsetHandle->cb != NULL) + pDsetHandle->cb(pCreateEvent->status, pDsetHandle->cb_args); + + pDCxt->setparamStatus = pCreateEvent->status; + pDCxt->dset_op_done = true; + break; + } + case WMIX_DSET_DELETE_CMDID: + { + WMI_DSET_OP_CREATE_EVENT *pCreateEvent; + pCreateEvent = (WMI_DSET_OP_CREATE_EVENT *)pDsetOPEvent->data; + + QCADRV_PRINTF("delete return: %d\n", pCreateEvent->status); + if (pDsetHandle->cb != NULL) + pDsetHandle->cb(pCreateEvent->status, pDsetHandle->cb_args); + + pDCxt->setparamStatus = pCreateEvent->status; + pDCxt->dset_op_done = true; + break; + } + } + DRIVER_WAKE_DRIVER(pCxt); +} + +/*****************************************************************************/ +/* Api_StoreRecallEvent - Processes a WMI_STORERECALL_STORE_EVENT from the + * device. + * This event will come when the device is ready to be shutdown by the host + * as part of a store-and-recall sequence. + * void *pCxt - the driver context. + * uint8_t *datap - original event buffer. + * int32_t len - length in bytes of datap + * void *pReq - original event rx-request object. + *****************************************************************************/ +void Api_StoreRecallEvent(void *pCxt, uint8_t devId, uint8_t *datap, int32_t len, void *pReq) +{ + WMI_STORERECALL_STORE_EVENT *pEv; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + uint8_t *strrclData = pDCxt->tempStorage; + + UNUSED_ARGUMENT(devId); + + switch (pDCxt->strrclState) + { + case STRRCL_ST_START: + A_MEMCPY(strrclData, datap, len); + pEv = (WMI_STORERECALL_STORE_EVENT *)strrclData; + + if (pEv->msec_sleep == 0) + { + /* a 0 msec_sleep indicates a firmware condition which + * prevented StoreRecall from completing. in this event this + * driver merely aborts the operation and continues normally. + */ + pDCxt->strrclState = STRRCL_ST_INIT; + pDCxt->strrclBlock = false; + API_STORE_RECALL_EVENT(pCxt); + /* FIXME: Notify the application that S&R did not complete + * successfully. + */ + } + else + { + /* indicate chip shutdown via chip_down. */ + // pDCxt->strrclCxt = datap; + pDCxt->strrclCxt = strrclData; + pDCxt->strrclCxtLen = len; + pDCxt->strrclState = STRRCL_ST_ACTIVE; + /* this call should shutdown the chip and maintain that state for msec_sleep milliseconds */ + Strrcl_Recall(pCxt, A_LE2CPU32(pEv->msec_sleep)); + } + break; + case STRRCL_ST_AWAIT_FW: + pDCxt->strrclState = STRRCL_ST_INIT; + pDCxt->strrclBlock = false; + /* Indicate completion to the custom layer */ + API_STORE_RECALL_EVENT(pCxt); + break; + default: + /* do nothing but this should never happen */ + break; + } +} + +/*****************************************************************************/ +/* Api_StoreRecallEvent - Processes a WMI_STORERECALL_STORE_EVENT from the + * device. + * This event will come when the device is ready to be shutdown by the host + * as part of a store-and-recall sequence. + * void *pCxt - the driver context. + * uint8_t *datap - original event buffer. + * int32_t len - length in bytes of datap + * void *pReq - original event rx-request object. + *****************************************************************************/ +void Api_StoreRecallStartEvent(void *pCxt, uint8_t devId, uint8_t *datap, int32_t len, void *pReq) +{ + WMI_STORERECALL_START_EVENT *pEv; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + // uint8_t* strrclData = pDCxt->tempStorage; + + UNUSED_ARGUMENT(devId); + + pEv = (WMI_STORERECALL_START_EVENT *)datap; + if (pEv->msec_sleep == 0) + { + /* a 0 msec_sleep indicates a firmware condition which + * prevented StoreRecall from completing. in this event this + * driver merely aborts the operation and continues normally. + */ + pDCxt->strrclState = STRRCL_ST_INIT; + pDCxt->strrclBlock = false; + API_STORE_RECALL_EVENT(pCxt); + /* FIXME: Notify the application that S&R did not complete + * successfully. + */ + } + else + { + /* indicate chip shutdown via chip_down. */ + // pDCxt->strrclCxt = datap; + // pDCxt->strrclCxt = strrclData; + // pDCxt->strrclCxtLen = len; + + QCADRV_PRINTF("total = %d buff len=%d\n", pDCxt->strrclCxtLen, pDCxt->tempStorageLength); + + pDCxt->strrclState = STRRCL_ST_ACTIVE; + /* this call should shutdown the chip and maintain that state for msec_sleep milliseconds */ + Strrcl_Recall(pCxt, A_LE2CPU32(pEv->msec_sleep)); + } +} + +/*****************************************************************************/ +/* Api_WpsProfileEvent - Processes a WMI_WPS_PROFILE_EVENT from the device. + * this event will come when the device has finished a WPS operation. it + * announcess to the host the results of that operation. This function + * stores the information so that it can be processed asynchronously by + * an application thread waiting for the result. + * void *pCxt - the driver context. + * uint8_t *datap - original event buffer. + * int32_t len - length in bytes of datap + * void *pReq - original event rx-request object. + *****************************************************************************/ +void Api_WpsProfileEvent(void *pCxt, uint8_t devId, uint8_t *datap, int32_t len, void *pReq) +{ + WMI_WPS_PROFILE_EVENT *pEv = (WMI_WPS_PROFILE_EVENT *)datap; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + + UNUSED_ARGUMENT(len); + UNUSED_ARGUMENT(devId); + DRIVER_SHARED_RESOURCE_ACCESS_ACQUIRE(pCxt); + + do + { + /* cleanup previous buffer */ + if (pDCxt->wpsBuf != NULL) + { + A_NETBUF_FREE(pDCxt->wpsBuf); + pDCxt->wpsBuf = NULL; + } + + pDCxt->wpsBuf = pReq; + pDCxt->wpsEvent = (void *)pEv; + /* convert event values to host endian format */ + pEv->credential.auth_type = A_LE2CPU16(pEv->credential.auth_type); + pEv->credential.encr_type = A_LE2CPU16(pEv->credential.encr_type); + pEv->credential.ap_channel = A_LE2CPU16(pEv->credential.ap_channel); + /* announce event receive to any waiting threads */ + pDCxt->wpsState = false; + API_WPS_PROFILE_EVENT(pCxt, datap, len, pReq); + + } while (0); + + DRIVER_SHARED_RESOURCE_ACCESS_RELEASE(pCxt); +} + +#if WLAN_CONFIG_11N_AGGR_SUPPORT +/*****************************************************************************/ +/* Api_AggrRecvAddbaReqEvent - processes a WMI_ADDBA_REQ_EVENT from the device. + * These events come when the device reveives a add-block-ACK packet from + * an AP or peer device. This is only relevant for 11n aggregation. + * void *pCxt - the driver context. + * WMI_ADDBA_REQ_EVENT *evt - the event structure + *****************************************************************************/ +void Api_AggrRecvAddbaReqEvent(void *pCxt, uint8_t devId, WMI_ADDBA_REQ_EVENT *evt) +{ + UNUSED_ARGUMENT(devId); + evt->st_seq_no = A_LE2CPU16(evt->st_seq_no); + + if (evt->status == 0) + { + aggr_recv_addba_req_evt(GET_DRIVER_COMMON(pCxt)->pAggrCxt, evt->tid, evt->st_seq_no, evt->win_sz); + } + API_AGGR_RECV_ADDBA_REQ_EVENT(pCxt, evt); +} + +/*****************************************************************************/ +/* Api_AggrRecvDelbaReqEvent - processes a WMI_DELBA_EVENT from the device. + * These events come when the device reveives a delete-block-ACK packet from + * an AP or peer device. This is only relevant for 11n aggregation. + * void *pCxt - the driver context. + * WMI_DELBA_EVENT *evt - the event structure + *****************************************************************************/ +void Api_AggrRecvDelbaReqEvent(void *pCxt, uint8_t devId, WMI_DELBA_EVENT *evt) +{ + UNUSED_ARGUMENT(devId); + aggr_recv_delba_req_evt(GET_DRIVER_COMMON(pCxt)->pAggrCxt, evt->tid); + API_AGGR_RECV_DELBA_REQ_EVENT(pCxt, evt); +} +#endif /* WLAN_CONFIG_11N_AGGR_SUPPORT */ + +/*****************************************************************************/ +/* Api_ReadyEvent - processes a WMI_READY_EVENT from the device. records + * usefull information from the event. + * void *pCxt - the driver context. + * uint8_t *datap - original event buffer. + * uint8_t phyCap - device phy capabilities. + * uint32_t sw_ver - device firmware version. + * uint32_t abi_ver - device ABI version. + *****************************************************************************/ +void Api_ReadyEvent(void *pCxt, uint8_t devId, uint8_t *datap, uint8_t phyCap, uint32_t sw_ver, uint32_t abi_ver) +{ + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + + UNUSED_ARGUMENT(devId); + Api_BootProfile(pCxt, BOOT_PROFILE_WMI_READY); + + pDCxt->wmiReady = true; + pDCxt->phyCapability = phyCap; + pDCxt->wlanVersion = sw_ver; + pDCxt->abiVersion = abi_ver; + A_MEMCPY(&pDCxt->scan_param, &default_scan_param, sizeof(WMI_SCAN_PARAMS_CMD)); + + CUSTOM_API_READY_EVENT(pCxt, datap, phyCap, sw_ver, abi_ver); +} + +/*****************************************************************************/ +/* Api_RSNASuccessEvent - processes a RSNA SUCCESS Message from the device. + * void *pCxt - the driver context. + * uint8_t code - success code. + *****************************************************************************/ +void Api_RSNASuccessEvent(void *pCxt, uint8_t devId, uint8_t code) +{ + UNUSED_ARGUMENT(devId); + /* this will call the custom event which will call + * the WifiCallback which will indicate the status + */ + CUSTOM_API_RSNA_SUCCESS_EVENT(pCxt, devId, code); +} + +/*****************************************************************************/ +/* GetTemperatureReply - process the temperature reply from the device + * void *pCxt - the driver context. + * uint8_t *datap - original event buffer. + * uint8_t len - buffer length + *****************************************************************************/ +void Api_GetTemperatureReply(void *pCxt, uint8_t *datap, uint32_t len) +{ + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + WMI_GET_TEMPERATURE_REPLY *pReply = (WMI_GET_TEMPERATURE_REPLY *)datap; + pDCxt->temperatureValid = true; + pDCxt->raw_temperature = pReply->tempRegVal; + pDCxt->tempDegree = pReply->tempDegree; + API_GET_TEMPERATURE_REPLY(pCxt, datap, len); +} + +/*****************************************************************************/ +/* Api_GetWpsInitReply - Init WPS event back + * void *pCxt - the driver context. + * uint8_t *datap - original event buffer. + * uint8_t code - init return code + *****************************************************************************/ +void Api_GetWpsInitReply(void *pCxt, uint8_t *datap, uint32_t len) +{ + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + /* this will call the custom event which will call + * the WifiCallback which will indicate the status + */ + WMI_WLAN_WPS_INIT_KEY_REPLY *pReply = ( WMI_WLAN_WPS_INIT_KEY_REPLY *)datap; + pDCxt->wps_init_key = pReply->status; + API_WPS_INIT_REPLY(pCxt,datap, len); +} + +/*****************************************************************************/ +/* GetCountryCodeReply - process the countrycode reply from the device + * void *pCxt - the driver context. + * uint8_t *datap - original event buffer. + * uint8_t len - buffer length + *****************************************************************************/ +void Api_GetCountryCodeReply(void *pCxt, uint8_t *datap, uint32_t len) +{ + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + WMI_GET_COUNTRY_CODE_REPLY *pReply = (WMI_GET_COUNTRY_CODE_REPLY *)datap; + pDCxt->countryCodeValid = true; + A_MEMCPY(pDCxt->raw_countryCode, pReply->country_code, 3); + QCADRV_PRINTF("code is %c , %c.\n", pDCxt->raw_countryCode[0], pDCxt->raw_countryCode[1]); + API_GET_COUNTRY_CODE_REPLY(pCxt, datap, len); +} +/* GetSetParamReply - recv param set ack from the device + * A_VOID *pCxt - the driver context. + * uint8_t *datap - original event buffer. + *****************************************************************************/ +void Api_GetSetParamReply(void *pCxt, uint8_t *datap) +{ + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + WMI_PARAM_SET_REPLY *reply = (WMI_PARAM_SET_REPLY *)datap; + + pDCxt->setparamValid = true; + pDCxt->setparamStatus = reply->status; + API_SET_PARAM_REPLY_EVENT(pCxt); +} + +#if ENABLE_P2P_MODE +/*****************************************************************************/ +/* p2p_go_neg_event - processes a P2P GO Negotiation event from the device. + * void *pCxt - the driver context. + * uint8_t *datap - original event buffer. + * uint8_t len - buffer length + *****************************************************************************/ +void p2p_go_neg_event(void *pCxt, uint8_t devId, uint8_t *datap, uint32_t len, WMI_P2P_PROV_INFO *wps_info) +{ + API_P2P_GO_NEG_EVENT(pCxt, devId, datap, len, wps_info); +} + +void p2p_invite_sent_result_event(void *pCxt, uint8_t devId, uint8_t *datap, uint32_t len) +{ + API_P2P_INVITE_SEND_RESULT(pCxt, devId, datap, len); +} +/*****************************************************************************/ +/* p2p_node_list_event- event which gives the discovered nodes. + * void *pCxt - the driver context. + * uint8_t *datap - original event buffer. + * uint8_t len - buffer length + *****************************************************************************/ +void p2p_node_list_event(void *pCxt, uint8_t devId, uint8_t *datap, uint32_t len) +{ + API_P2P_NODE_LIST_EVENT(pCxt, devId, datap, len); +} + +/*****************************************************************************/ +/* p2p_list_persistent_network_event - event which gives the discovered nodes. + * void *pCxt - the driver context. + * uint8_t *datap - original event buffer. + * uint8_t len - buffer length + *****************************************************************************/ +void p2p_list_persistent_network_event(void *pCxt, uint8_t devId, uint8_t *datap, uint32_t len) +{ + API_P2P_LIST_PERSISTENT_NETWORK_EVENT(pCxt, devId, datap, len); +} + +/*****************************************************************************/ +/* p2p_req_auth_event - processes a response event for authentication request. + * void *pCxt - the driver context. + * uint8_t *datap - original event buffer. + * uint8_t len - buffer length + *****************************************************************************/ +void p2p_req_auth_event(void *pCxt, uint8_t devId, uint8_t *datap, uint32_t len) +{ + API_P2P_REQ_AUTH_EVENT(pCxt, devId, datap, len); +} + +void get_p2p_ctx(void *pCxt, uint8_t devId, uint8_t *datap, uint32_t len) +{ + API_GET_P2P_CTX(pCxt, devId, datap, len); +} + +void get_p2p_prov_disc_req(void *pCxt, uint8_t devId, uint8_t *datap, uint32_t len) +{ + API_P2P_PROV_DISC_REQ(pCxt, devId, datap, len); +} +#if 1 // KK +void get_p2p_serv_disc_req(void *pCxt, uint8_t devId, uint8_t *datap, uint32_t len) +{ + API_P2P_SERV_DISC_REQ(pCxt, devId, datap, len); +} + +void p2p_invite_req_rx(void *pCxt, uint8_t devId, uint8_t *datap, uint8_t len) +{ + API_P2P_INVITE_REQ(pCxt, devId, datap, len); +} + +void p2p_invite_rcvd_result_ev(void *pCxt, uint8_t devId, uint8_t *datap, uint32_t len) +{ + API_P2P_INVITE_RCVD_RESULT(pCxt, devId, datap, len); +} +#endif +#endif + +#if MANUFACTURING_SUPPORT +void Api_TestCmdEventRx(void *pCxt, uint8_t devId, uint8_t *datap, uint32_t len) +{ + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + UNUSED_ARGUMENT(devId); + API_TEST_RESP_EVENT(pCxt, datap, len); + + pDCxt->testResp = true; + DRIVER_WAKE_USER(pCxt); +} +#endif + +/*****************************************************************************/ +/* Api_RxDbglogEvent - Processes a WMIX_DBGLOG_EVENT from the device. + *****************************************************************************/ +void Api_RxDbglogEvent(void *wmip, uint8_t devId, uint8_t *datap, int32_t len) +{ + UNUSED_ARGUMENT(devId); + API_WMIX_DBGLOG_EVENT(wmip, datap, len); +} + +/*****************************************************************************/ +/* Api_RxGpioDataEvent - Processes a WMIX_GPIO_DATA_EVENT from the device. + *****************************************************************************/ +void Api_RxGpioDataEvent(void *wmip, uint8_t devId, uint8_t *datap, int32_t len) +{ + UNUSED_ARGUMENT(devId); + CUSTOM_API_WMIX_GPIO_DATA_EVENT(wmip, datap, len); +} + +/*****************************************************************************/ +/* Api_RxHBChallengeEvent - Processes a WMIX_GPIO_DATA_EVENT from the device. + *****************************************************************************/ +void Api_RxHBChallengeEvent(void *pCxt, uint8_t devId, uint8_t *datap, int32_t len) +{ + //pDCxt = GET_DRIVER_COMMON(pCxt); + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + WMIX_HB_CHALLENGE_RESP_EVENT *pEv = (WMIX_HB_CHALLENGE_RESP_EVENT *)datap; + + if(pEv->cookie == pDCxt->hb_sequence) + pDCxt->hb_challenge_done = true; + + DRIVER_WAKE_USER(pCxt); +} + +#if ENABLE_KF_PERFORMANCE + +/*****************************************************************************/ +/* Api_RxPfmDataEvent - Processes a WMIX_PFM_DATA_EVENT from the device. + *****************************************************************************/ +void Api_RxPfmDataEvent(void *wmip, uint8_t devId, uint8_t *datap, int32_t len) +{ + UNUSED_ARGUMENT(devId); + CUSTOM_API_WMIX_PFM_DATA_EVENT(wmip, datap, len); +} + +/*****************************************************************************/ +/* Api_RxPfmDataDoneEvent - Processes a WMIX_PFM_DATA_DONE_EVENT from the device. + *****************************************************************************/ + +void Api_RxPfmDataDoneEvent(void *wmip, uint8_t devId, uint8_t *datap, int32_t len) +{ + UNUSED_ARGUMENT(devId); + CUSTOM_API_WMIX_PFM_DATA_DONE_EVENT(wmip, datap, len); +} +#endif + +#if 0 +/*****************************************************************************/ +/* Api_PFMReportEvent - Processes a WMI_PFM_REPORT_EVENTID from the device. + *****************************************************************************/ +void add_one_profile(uint8_t event_id, uint16_t timestamp); + +void +Api_PFMReportEvent(void *pCxt, uint8_t devId, WMI_PFM_REPORT_EVENT *pEv) +{ + uint8_t i; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + + UNUSED_ARGUMENT(devId); + for (i=0; i < MAX_TIMESTAMP; i++) + { + if (pEv->eventID[i] == 0) + break; + + add_one_profile(pEv->eventID[i] + 15, (uint16_t)pEv->timestamp[i] / 32); + } + pDCxt->pfmDone = true; + + DRIVER_WAKE_USER(pCxt); +} + +/*****************************************************************************/ +/* Api_PFMReportEvent - Processes a WMI_PFM_REPORT_EVENTID from the device. + *****************************************************************************/ +void +Api_DiagReportEvent(void *pCxt, WMI_DIAG_EVENT *pEv) +{ + if(ath_custom_init.Boot_Profile == NULL) + return; + +/* if (pEv->commandId == WMID_FSM_AUTH_EVENTID) + { + ath_custom_init.Boot_Profile(BOOT_PROFILE_AUTH_EVENT); + } + + else if (pEv->commandId == WMID_FSM_ASSOC_EVENTID) + { + ath_custom_init.Boot_Profile(BOOT_PROFILE_ASSOC_EVENT); + } + else if (pEv->commandId == WMID_START_SCAN_EVENTID) + { + ath_custom_init.Boot_Profile(BOOT_PROFILE_START_SCAN); + } +*/ +} +#endif + +#if ENABLE_P2P_MODE +void Api_p2p_go_neg_event(void *pCxt, uint8_t devId, uint8_t *datap, uint32_t len, WMI_P2P_PROV_INFO *wps_info) +{ + uint32_t evt_id = 0; + evt_id = WMI_P2P_GO_NEG_RESULT_EVENTID; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + + DRIVER_SHARED_RESOURCE_ACCESS_ACQUIRE(pCxt); + { + A_MEMZERO(GET_DRIVER_COMMON(pCxt)->pScanOut, pDCxt->tempStorageLength); + + A_MEMCPY(GET_DRIVER_COMMON(pCxt)->pScanOut, &evt_id, sizeof(uint32_t)); + + A_MEMCPY((GET_DRIVER_COMMON(pCxt)->pScanOut) + sizeof(uint32_t), datap, sizeof(WMI_P2P_GO_NEG_RESULT_EVENT)); + + if (GET_DRIVER_COMMON(pCxt)->p2pEvtState == true) + { + GET_DRIVER_COMMON(pCxt)->p2pEvtState = false; + } + else + { + GET_DRIVER_COMMON(pCxt)->p2pevtflag = true; + } + } + DRIVER_SHARED_RESOURCE_ACCESS_RELEASE(pCxt); + + DRIVER_WAKE_USER(pCxt); +} + +void Api_p2p_node_list_event(void *pCxt, uint8_t devId, uint8_t *datap, uint32_t len) +{ + uint32_t evt_id = 0; + uint8_t *tmpBuf; + evt_id = WMI_P2P_NODE_LIST_EVENTID; + WMI_P2P_NODE_LIST_EVENT *handleP2PDev = (WMI_P2P_NODE_LIST_EVENT *)datap; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + + tmpBuf = GET_DRIVER_COMMON(pCxt)->pScanOut; + DRIVER_SHARED_RESOURCE_ACCESS_ACQUIRE(pCxt); + { + A_MEMZERO(GET_DRIVER_COMMON(pCxt)->pScanOut, pDCxt->tempStorageLength); + A_MEMCPY(GET_DRIVER_COMMON(pCxt)->pScanOut, &evt_id, sizeof(uint32_t)); + tmpBuf += sizeof(uint32_t); + *tmpBuf = handleP2PDev->num_p2p_dev; + tmpBuf++; + + A_MEMCPY((uint8_t *)tmpBuf, ((uint8_t *)(handleP2PDev->data)), + (sizeof(P2P_DEVICE_LITE) * (handleP2PDev->num_p2p_dev))); + + GET_DRIVER_COMMON(pCxt)->p2pEvtState = false; + } + DRIVER_SHARED_RESOURCE_ACCESS_RELEASE(pCxt); + + DRIVER_WAKE_USER(pCxt); +} + +void Api_p2p_req_auth_event(void *pCxt, uint8_t devId, uint8_t *datap, uint32_t len) +{ + uint32_t evt_id = 0; + evt_id = WMI_P2P_REQ_TO_AUTH_EVENTID; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + + DRIVER_SHARED_RESOURCE_ACCESS_ACQUIRE(pCxt); + { + A_MEMZERO(GET_DRIVER_COMMON(pCxt)->pScanOut, pDCxt->tempStorageLength); + + A_MEMCPY(GET_DRIVER_COMMON(pCxt)->pScanOut, &evt_id, sizeof(uint32_t)); + + A_MEMCPY((GET_DRIVER_COMMON(pCxt)->pScanOut) + sizeof(uint32_t), datap, sizeof(WMI_P2P_REQ_TO_AUTH_EVENT)); + + GET_DRIVER_COMMON(pCxt)->p2pevtflag = true; + } + DRIVER_SHARED_RESOURCE_ACCESS_RELEASE(pCxt); + + DRIVER_WAKE_USER(pCxt); +} + +void Api_p2p_list_persistent_network_event(void *pCxt, uint8_t devId, uint8_t *datap, uint32_t len) +{ + uint32_t evt_id = 0; + evt_id = WMI_P2P_LIST_PERSISTENT_NETWORK_EVENTID; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + WMI_P2P_PERSISTENT_LIST_NETWORK_EVENT *ev = (WMI_P2P_PERSISTENT_LIST_NETWORK_EVENT *)datap; + + DRIVER_SHARED_RESOURCE_ACCESS_ACQUIRE(pCxt); + { + A_MEMZERO(GET_DRIVER_COMMON(pCxt)->pScanOut, pDCxt->tempStorageLength); + + A_MEMCPY(GET_DRIVER_COMMON(pCxt)->pScanOut, &evt_id, sizeof(uint32_t)); + + A_MEMCPY((GET_DRIVER_COMMON(pCxt)->pScanOut) + sizeof(uint32_t), ev->data, + (MAX_LIST_COUNT * sizeof(WMI_PERSISTENT_MAC_LIST))); + + GET_DRIVER_COMMON(pCxt)->p2pEvtState = false; + } + DRIVER_SHARED_RESOURCE_ACCESS_RELEASE(pCxt); + + DRIVER_WAKE_USER(pCxt); +} + +void Api_get_p2p_ctx(void *pCxt, uint8_t devId, uint8_t *datap, uint32_t len) +{ + uint32_t evt_id = 0; + evt_id = WMI_P2P_PROV_DISC_RESP_EVENTID; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + + DRIVER_SHARED_RESOURCE_ACCESS_ACQUIRE(pCxt); + { + A_MEMZERO(GET_DRIVER_COMMON(pCxt)->pScanOut, pDCxt->tempStorageLength); + + A_MEMCPY(GET_DRIVER_COMMON(pCxt)->pScanOut, &evt_id, sizeof(uint32_t)); + + A_MEMCPY((GET_DRIVER_COMMON(pCxt)->pScanOut) + sizeof(uint32_t), datap, sizeof(WMI_P2P_PROV_DISC_RESP_EVENT)); + + GET_DRIVER_COMMON(pCxt)->p2pEvtState = false; + } + DRIVER_SHARED_RESOURCE_ACCESS_RELEASE(pCxt); + + DRIVER_WAKE_USER(pCxt); +} + +void Api_p2p_prov_disc_req(void *pCxt, uint8_t devId, uint8_t *datap, uint32_t len) +{ + uint32_t evt_id = 0; + evt_id = WMI_P2P_PROV_DISC_REQ_EVENTID; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + + DRIVER_SHARED_RESOURCE_ACCESS_ACQUIRE(pCxt); + { + A_MEMZERO(GET_DRIVER_COMMON(pCxt)->pScanOut, pDCxt->tempStorageLength); + + A_MEMCPY(GET_DRIVER_COMMON(pCxt)->pScanOut, &evt_id, sizeof(uint32_t)); + + A_MEMCPY((GET_DRIVER_COMMON(pCxt)->pScanOut) + sizeof(uint32_t), datap, sizeof(WMI_P2P_PROV_DISC_REQ_EVENT)); + + GET_DRIVER_COMMON(pCxt)->p2pevtflag = true; + } + DRIVER_SHARED_RESOURCE_ACCESS_RELEASE(pCxt); + + DRIVER_WAKE_USER(pCxt); +} + +void Api_p2p_serv_disc_req(void *pCxt, uint8_t devId, uint8_t *datap, uint32_t len) +{ + uint32_t evt_id = 0; + evt_id = WMI_P2P_SDPD_RX_EVENTID; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + DRIVER_SHARED_RESOURCE_ACCESS_ACQUIRE(pCxt); + { + A_MEMZERO(GET_DRIVER_COMMON(pCxt)->pScanOut, pDCxt->tempStorageLength); + + A_MEMCPY(GET_DRIVER_COMMON(pCxt)->pScanOut, &evt_id, sizeof(uint32_t)); + + A_MEMCPY((GET_DRIVER_COMMON(pCxt)->pScanOut) + sizeof(uint32_t), datap, sizeof(WMI_P2P_SDPD_RX_EVENT)); + + GET_DRIVER_COMMON(pCxt)->p2pevtflag = true; + } + + DRIVER_SHARED_RESOURCE_ACCESS_RELEASE(pCxt); + + DRIVER_WAKE_USER(pCxt); +} + +void Api_p2p_invite_req(void *pCxt, uint8_t devId, uint8_t *datap, uint32_t len) +{ + // async event for peer invite + uint32_t evt_id = 0; + evt_id = WMI_P2P_INVITE_REQ_EVENTID; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + + DRIVER_SHARED_RESOURCE_ACCESS_ACQUIRE(pCxt); + { + A_MEMZERO(GET_DRIVER_COMMON(pCxt)->pScanOut, pDCxt->tempStorageLength); + + A_MEMCPY(GET_DRIVER_COMMON(pCxt)->pScanOut, &evt_id, sizeof(uint32_t)); + + A_MEMCPY((GET_DRIVER_COMMON(pCxt)->pScanOut) + sizeof(uint32_t), datap, sizeof(WMI_P2P_FW_INVITE_REQ_EVENT)); + + GET_DRIVER_COMMON(pCxt)->p2pevtflag = true; + } + + DRIVER_SHARED_RESOURCE_ACCESS_RELEASE(pCxt); + + DRIVER_WAKE_USER(pCxt); +} + +void Api_p2p_invite_rcvd_result(void *pCxt, uint8_t devId, uint8_t *datap, uint32_t len) +{ + uint32_t evt_id = 0; + evt_id = WMI_P2P_INVITE_RCVD_RESULT_EVENTID; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + + DRIVER_SHARED_RESOURCE_ACCESS_ACQUIRE(pCxt); + { + A_MEMZERO(GET_DRIVER_COMMON(pCxt)->pScanOut, pDCxt->tempStorageLength); + + A_MEMCPY(GET_DRIVER_COMMON(pCxt)->pScanOut, &evt_id, sizeof(uint32_t)); + + A_MEMCPY((GET_DRIVER_COMMON(pCxt)->pScanOut) + sizeof(uint32_t), datap, + sizeof(WMI_P2P_INVITE_RCVD_RESULT_EVENT)); + + GET_DRIVER_COMMON(pCxt)->p2pevtflag = true; + } + DRIVER_SHARED_RESOURCE_ACCESS_RELEASE(pCxt); + + DRIVER_WAKE_USER(pCxt); +} + +void Api_p2p_invite_send_result(void *pCxt, uint8_t devId, uint8_t *datap, uint32_t len) +{ + uint32_t evt_id = 0; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + evt_id = WMI_P2P_INVITE_SENT_RESULT_EVENTID; + + DRIVER_SHARED_RESOURCE_ACCESS_ACQUIRE(pCxt); + { + A_MEMZERO(GET_DRIVER_COMMON(pCxt)->pScanOut, pDCxt->tempStorageLength); + + A_MEMCPY(GET_DRIVER_COMMON(pCxt)->pScanOut, &evt_id, sizeof(uint32_t)); + + A_MEMCPY((GET_DRIVER_COMMON(pCxt)->pScanOut) + sizeof(uint32_t), datap, + sizeof(WMI_P2P_INVITE_SENT_RESULT_EVENT)); + + GET_DRIVER_COMMON(pCxt)->p2pevtflag = true; + } + DRIVER_SHARED_RESOURCE_ACCESS_RELEASE(pCxt); + + DRIVER_WAKE_USER(pCxt); +} + +#endif +#if MANUFACTURING_SUPPORT +void Api_Test_Cmd_Event(void *pCxt, uint8_t *datap, uint32_t len) +{ + UNUSED_ARGUMENT(len); + A_MEMCPY(GET_DRIVER_COMMON(pCxt)->pScanOut, datap, len); + GET_DRIVER_COMMON(pCxt)->testCmdRespBufLen = len; +} +#endif + +void Api_ProbeReqEvent(void *pCxt, uint8_t *datap, uint32_t len) +{ + CUSTOM_API_PROBEREQ_EVENT(pCxt, datap, len); +} diff --git a/platform/mcu/lpc54102/wifi_qca/common_src/bmi/bmi.c b/platform/mcu/lpc54102/wifi_qca/common_src/bmi/bmi.c new file mode 100644 index 0000000000..1de69b6f9c --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/common_src/bmi/bmi.c @@ -0,0 +1,616 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== +#include +#include +#include +#include +#include +#include +#include +#include +#include "hw20_mbox_host_reg.h" +//#include "bmi_internal.h" +#include "atheros_wifi_api.h" +#include "bmi.h" + +#define BMI_ENDPOINT 0 + +#define BMI_COMMUNICATION_TIMEOUT 100000 + +/* +Although we had envisioned BMI to run on top of HTC, this is not how the +final implementation ended up. On the Target side, BMI is a part of the BSP +and does not use the HTC protocol nor even DMA -- it is intentionally kept +very simple. +*/ + +#if DRIVER_CONFIG_INCLUDE_BMI + +static uint8_t bmiDone = true; +static uint32_t *pBMICmdCredits; +static uint8_t *pBMICmdBuf; +#define MAX_BMI_CMDBUF_SZ \ + (BMI_DATASZ_MAX + sizeof(uint32_t) /* cmd */ + sizeof(uint32_t) /* addr */ + sizeof(uint32_t)) /* length */ +#define BMI_COMMAND_FITS(sz) ((sz) <= MAX_BMI_CMDBUF_SZ) + +static A_STATUS bmiBufferSend(void *pCxt, uint8_t *buffer, uint32_t length) +{ + A_NETBUF_DECLARE req; + void *pReq = (void *)&req; + A_STATUS status; + uint32_t timeout; + uint32_t address; + // A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + + A_NETBUF_CONFIGURE(pReq, pBMICmdCredits, 0, sizeof(uint32_t), sizeof(uint32_t)); + + *pBMICmdCredits = 0; + timeout = BMI_COMMUNICATION_TIMEOUT; + + while (timeout-- && !(*pBMICmdCredits)) + { + /* Read the counter register to get the command credits */ + address = COUNT_DEC_ADDRESS + (HTC_MAILBOX_NUM_MAX + BMI_ENDPOINT) * 4; + ATH_SET_PIO_EXTERNAL_READ_OPERATION(pReq, address, true, sizeof(uint32_t)); + /* hit the credit counter with a 4-byte access, the first byte read will hit the counter and cause + * a decrement, while the remaining 3 bytes has no effect. The rationale behind this is to + * make all HIF accesses 4-byte aligned */ + if (A_OK != (status = Hcd_DoPioExternalAccess(pCxt, pReq))) + { + break; + } + + /* the counter is only 8=bits, ignore anything in the upper 3 bytes */ + + *pBMICmdCredits = A_LE2CPU32(*pBMICmdCredits); + + (*pBMICmdCredits) &= 0xFF; + } + + if (*pBMICmdCredits) + { + A_NETBUF_CONFIGURE(pReq, buffer, 0, length, length); + address = HW_GetMboxAddress(pCxt, BMI_ENDPOINT, length); + address &= ATH_TRANS_ADDR_MASK; + A_NETBUF_SET_ELEM(pReq, A_REQ_ADDRESS, address); + A_NETBUF_SET_ELEM(pReq, A_REQ_TRANSFER_LEN, length); + /* init the packet read params/cmd incremental vs fixed address etc. */ + A_NETBUF_SET_ELEM(pReq, A_REQ_COMMAND, (ATH_TRANS_WRITE | ATH_TRANS_DMA)); + status = Hcd_Request(pCxt, pReq); + if (status != A_OK) + { + return A_ERROR; + } + } + else + { + return A_ERROR; + } + + return status; +} + +static A_STATUS bmiBufferReceive(void *pCxt, uint8_t *buffer, uint32_t length, boolean want_timeout) +{ + A_STATUS status; + uint32_t address; + uint32_t availableRecvBytes; + A_NETBUF_DECLARE req; + void *pReq = (void *)&req; + // A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + + if (length >= 4) + { /* NB: Currently, always true */ + /* + * NB: word_available is declared static for esoteric reasons + * having to do with protection on some OSes. + */ + static uint32_t word_available; + uint32_t timeout; + + word_available = 0; + timeout = BMI_COMMUNICATION_TIMEOUT; + while ((!want_timeout || timeout--) && !word_available) + { + status = Hcd_DoPioInternalAccess(pCxt, ATH_SPI_RDBUF_BYTE_AVA_REG, &availableRecvBytes, true); + if (status != A_OK) + { + break; + } + + if (availableRecvBytes >= sizeof(uint32_t)) + { + word_available = 1; + } + } + + if (!word_available) + { + return A_ERROR; + } + } + + A_NETBUF_CONFIGURE(pReq, buffer, 0, length, length); + address = HW_GetMboxAddress(pCxt, BMI_ENDPOINT, length); + address &= ATH_TRANS_ADDR_MASK; + A_NETBUF_SET_ELEM(pReq, A_REQ_ADDRESS, address); + A_NETBUF_SET_ELEM(pReq, A_REQ_TRANSFER_LEN, length); + /* init the packet read params/cmd incremental vs fixed address etc. */ + A_NETBUF_SET_ELEM(pReq, A_REQ_COMMAND, (ATH_TRANS_READ | ATH_TRANS_DMA)); + status = Hcd_Request(pCxt, pReq); + if (status != A_OK) + { + return A_ERROR; + } + + return A_OK; +} + +/* APIs visible to the driver */ +A_STATUS +BMIInit(void *pCxt) +{ + bmiDone = false; + + /* + * On some platforms, it's not possible to DMA to a static variable + * in a device driver (e.g. Linux loadable driver module). + * So we need to A_MALLOC space for "command credits" and for commands. + * + * Note: implicitly relies on A_MALLOC to provide a buffer that is + * suitable for DMA (or PIO). This buffer will be passed down the + * bus stack. + */ + if (!pBMICmdCredits) + { + pBMICmdCredits = (uint32_t *)A_MALLOC(4, MALLOC_ID_TEMPORARY); + A_ASSERT(pBMICmdCredits); + } + + if (!pBMICmdBuf) + { + pBMICmdBuf = (uint8_t *)A_MALLOC(MAX_BMI_CMDBUF_SZ, MALLOC_ID_TEMPORARY); + A_ASSERT(pBMICmdBuf); + } + + return A_OK; +} + +void BMICleanup(void) +{ + if (pBMICmdCredits) + { + A_FREE(pBMICmdCredits, MALLOC_ID_TEMPORARY); + pBMICmdCredits = NULL; + } + + if (pBMICmdBuf) + { + A_FREE(pBMICmdBuf, MALLOC_ID_TEMPORARY); + pBMICmdBuf = NULL; + } +} + +A_STATUS +BMIDone(void *pCxt) +{ + A_STATUS status; + uint32_t cid; + + if (bmiDone) + { + return A_OK; + } + + bmiDone = true; + cid = A_CPU2LE32(BMI_DONE); + + status = bmiBufferSend(pCxt, (uint8_t *)&cid, sizeof(cid)); + if (status != A_OK) + { + return A_ERROR; + } + + if (pBMICmdCredits) + { + A_FREE(pBMICmdCredits, MALLOC_ID_TEMPORARY); + pBMICmdCredits = NULL; + } + + if (pBMICmdBuf) + { + A_FREE(pBMICmdBuf, MALLOC_ID_TEMPORARY); + pBMICmdBuf = NULL; + } + + return A_OK; +} + +A_STATUS +BMIGetTargetInfo(void *pCxt, struct bmi_target_info *targ_info) +{ + uint32_t cid; + + if (bmiDone) + { + return A_ERROR; + } + + cid = A_CPU2LE32(BMI_GET_TARGET_INFO); + + if (A_OK != bmiBufferSend(pCxt, (uint8_t *)&cid, sizeof(cid))) + { + return A_ERROR; + } + + if (A_OK != bmiBufferReceive(pCxt, (uint8_t *)&targ_info->target_ver, sizeof(targ_info->target_ver), true)) + { + return A_ERROR; + } + + targ_info->target_ver = A_LE2CPU32(targ_info->target_ver); + + if (targ_info->target_ver == TARGET_VERSION_SENTINAL) + { + /* Determine how many bytes are in the Target's targ_info */ + if (A_OK != bmiBufferReceive(pCxt, (uint8_t *)&targ_info->target_info_byte_count, + sizeof(targ_info->target_info_byte_count), true)) + { + return A_ERROR; + } + + targ_info->target_info_byte_count = A_LE2CPU32(targ_info->target_info_byte_count); + + /* + * The Target's targ_info doesn't match the Host's targ_info. + * We need to do some backwards compatibility work to make this OK. + */ + A_ASSERT(targ_info->target_info_byte_count == sizeof(*targ_info)); + + /* Read the remainder of the targ_info */ + if (A_OK != bmiBufferReceive(pCxt, ((uint8_t *)targ_info) + sizeof(targ_info->target_info_byte_count), + sizeof(*targ_info) - sizeof(targ_info->target_info_byte_count), true)) + { + return A_ERROR; + } + + targ_info->target_ver = A_LE2CPU32(targ_info->target_ver); + targ_info->target_type = A_LE2CPU32(targ_info->target_type); + } + else + { + return A_ERROR; + } + + return A_OK; +} + +#if 1 +A_STATUS +BMIReadMemory(void *pCxt, uint32_t address, uint8_t *buffer, uint32_t length) +{ + uint32_t cid; + A_STATUS status; + uint32_t offset; + uint32_t remaining, rxlen, temp; + + A_ASSERT(BMI_COMMAND_FITS(BMI_DATASZ_MAX + sizeof(cid) + sizeof(address) + sizeof(length))); + memset(pBMICmdBuf, 0, BMI_DATASZ_MAX + sizeof(cid) + sizeof(address) + sizeof(length)); + + if (bmiDone) + { + return A_ERROR; + } + + cid = A_CPU2LE32(BMI_READ_MEMORY); + + remaining = length; + + while (remaining) + { + // rxlen = (remaining < BMI_DATASZ_MAX) ? remaining : BMI_DATASZ_MAX; + rxlen = (remaining < 4) ? remaining : 4; + offset = 0; + A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); + offset += sizeof(cid); + temp = A_CPU2LE32(address); + A_MEMCPY(&(pBMICmdBuf[offset]), &temp, sizeof(address)); + offset += sizeof(address); + temp = A_CPU2LE32(rxlen); + A_MEMCPY(&(pBMICmdBuf[offset]), &temp, sizeof(rxlen)); + offset += sizeof(length); + + status = bmiBufferSend(pCxt, pBMICmdBuf, offset); + if (status != A_OK) + { + return A_ERROR; + } + status = bmiBufferReceive(pCxt, pBMICmdBuf, rxlen, true); + if (status != A_OK) + { + return A_ERROR; + } + A_MEMCPY(&buffer[length - remaining], pBMICmdBuf, rxlen); + remaining -= rxlen; + address += rxlen; + } + + return A_OK; +} +#endif + +A_STATUS +BMIWriteMemory(void *pCxt, uint32_t address, uint8_t *buffer, uint32_t length) +{ + uint32_t cid; + uint32_t remaining, txlen, temp; + const uint32_t header = sizeof(cid) + sizeof(address) + sizeof(length); + // uint8_t alignedBuffer[BMI_DATASZ_MAX]; + uint8_t *src; + uint8_t *ptr; + + A_ASSERT(BMI_COMMAND_FITS(BMI_DATASZ_MAX + header)); + memset(pBMICmdBuf, 0, BMI_DATASZ_MAX + header); + + if (bmiDone) + { + return A_ERROR; + } + + cid = A_CPU2LE32(BMI_WRITE_MEMORY); + + remaining = length; + while (remaining) + { + src = &buffer[length - remaining]; + if (remaining < (BMI_DATASZ_MAX - header)) + { + if (remaining & 3) + { + /* align it with 4 bytes */ + remaining = remaining + (4 - (remaining & 3)); + // memcpy(alignedBuffer, src, remaining); + // src = alignedBuffer; + } + txlen = remaining; + } + else + { + txlen = (BMI_DATASZ_MAX - header); + } + + ptr = pBMICmdBuf; + A_MEMCPY(ptr, &cid, sizeof(cid)); + ptr += sizeof(cid); + temp = A_CPU2LE32(address); + A_MEMCPY(ptr, &temp, sizeof(address)); + ptr += sizeof(address); + temp = A_CPU2LE32(txlen); + A_MEMCPY(ptr, &temp, sizeof(txlen)); + ptr += sizeof(txlen); + A_MEMCPY(ptr, src, txlen); + ptr += txlen; + + if (A_OK != bmiBufferSend(pCxt, pBMICmdBuf, (uint32_t)(ptr - pBMICmdBuf))) + { + return A_ERROR; + } + remaining -= txlen; + address += txlen; + } + + return A_OK; +} + +A_STATUS +BMIExecute(void *pCxt, uint32_t address, uint32_t *param) +{ + uint32_t cid; + uint32_t temp; + uint8_t *ptr; + + A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address) + sizeof(param))); + memset(pBMICmdBuf, 0, sizeof(cid) + sizeof(address) + sizeof(param)); + + if (bmiDone) + { + return A_ERROR; + } + + cid = A_CPU2LE32(BMI_EXECUTE); + + ptr = pBMICmdBuf; + A_MEMCPY(ptr, &cid, sizeof(cid)); + ptr += sizeof(cid); + temp = A_CPU2LE32(address); + A_MEMCPY(ptr, &temp, sizeof(address)); + ptr += sizeof(address); + A_MEMCPY(ptr, param, sizeof(*param)); + ptr += sizeof(*param); + + if (A_OK != bmiBufferSend(pCxt, pBMICmdBuf, (uint32_t)(ptr - pBMICmdBuf))) + { + return A_ERROR; + } + + if (A_OK != bmiBufferReceive(pCxt, pBMICmdBuf, sizeof(*param), false)) + { + return A_ERROR; + } + + A_MEMCPY(param, pBMICmdBuf, sizeof(*param)); + + return A_OK; +} + +A_STATUS +BMIReadSOCRegister(void *pCxt, uint32_t address, uint32_t *param) +{ + uint32_t cid; + A_STATUS status; + uint32_t offset, temp; + + A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address))); + memset(pBMICmdBuf, 0, sizeof(cid) + sizeof(address)); + + if (bmiDone) + { + return A_ERROR; + } + + cid = A_CPU2LE32(BMI_READ_SOC_REGISTER); + + offset = 0; + A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); + offset += sizeof(cid); + temp = A_CPU2LE32(address); + A_MEMCPY(&(pBMICmdBuf[offset]), &temp, sizeof(address)); + offset += sizeof(address); + + status = bmiBufferSend(pCxt, pBMICmdBuf, offset); + if (status != A_OK) + { + return A_ERROR; + } + + status = bmiBufferReceive(pCxt, pBMICmdBuf, sizeof(*param), true); + if (status != A_OK) + { + return A_ERROR; + } + A_MEMCPY(param, pBMICmdBuf, sizeof(*param)); + + return A_OK; +} + +A_STATUS +BMIWriteSOCRegister(void *pCxt, uint32_t address, uint32_t param) +{ + uint32_t cid; + A_STATUS status; + uint32_t offset, temp; + + A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address) + sizeof(param))); + memset(pBMICmdBuf, 0, sizeof(cid) + sizeof(address) + sizeof(param)); + + if (bmiDone) + { + return A_ERROR; + } + + cid = A_CPU2LE32(BMI_WRITE_SOC_REGISTER); + + offset = 0; + A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); + offset += sizeof(cid); + temp = A_CPU2LE32(address); + A_MEMCPY(&(pBMICmdBuf[offset]), &temp, sizeof(address)); + offset += sizeof(address); + A_MEMCPY(&(pBMICmdBuf[offset]), ¶m, sizeof(param)); + offset += sizeof(param); + + status = bmiBufferSend(pCxt, pBMICmdBuf, offset); + + if (status != A_OK) + { + return A_ERROR; + } + + return A_OK; +} + +A_STATUS +BMIRawWrite(void *pCxt, uint8_t *buffer, uint32_t length) +{ + return bmiBufferSend(pCxt, buffer, length); +} + +A_STATUS +BMIRawRead(void *pCxt, uint8_t *buffer, uint32_t length, boolean want_timeout) +{ + return bmiBufferReceive(pCxt, buffer, length, want_timeout); +} + +#else + +/* STUB'd version when BMI is not used by the driver */ + +/* APIs visible to the driver */ +A_STATUS +BMIInit(void *pCxt) +{ + return A_ERROR; +} + +A_STATUS +BMIDone(void *pCxt) +{ + return A_ERROR; +} + +A_STATUS +BMIGetTargetInfo(void *pCxt, struct bmi_target_info *targ_info) +{ + return A_ERROR; +} + +A_STATUS +BMIWriteMemory(void *pCxt, uint32_t address, uint8_t *buffer, uint32_t length) +{ + return A_ERROR; +} + +A_STATUS +BMIExecute(void *pCxt, uint32_t address, uint32_t *param) +{ + return A_ERROR; +} + +A_STATUS +BMIReadSOCRegister(void *pCxt, uint32_t address, uint32_t *param) +{ + return A_ERROR; +} + +A_STATUS +BMIWriteSOCRegister(void *pCxt, uint32_t address, uint32_t param) +{ + return A_ERROR; +} + +A_STATUS +BMIRawWrite(void *pCxt, uint8_t *buffer, uint32_t length) +{ + return A_ERROR; +} + +A_STATUS +BMIRawRead(void *pCxt, uint8_t *buffer, uint32_t length, boolean want_timeout) +{ + return A_ERROR; +} + +#endif /* DRIVER_CONFIG_INCLUDE_BMI */ diff --git a/platform/mcu/lpc54102/wifi_qca/common_src/driver/driver_diag.c b/platform/mcu/lpc54102/wifi_qca/common_src/driver/driver_diag.c new file mode 100644 index 0000000000..71e9c1f5c1 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/common_src/driver/driver_diag.c @@ -0,0 +1,337 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== +#include +#include +#include +#include +#include +#include +#include +#include "hw20_mbox_host_reg.h" +#include "atheros_wifi_api.h" + +/* prototypes */ +static A_STATUS Driver_SetAddressWindowRegister(void *pCxt, uint32_t RegisterAddr, uint32_t Address); + +/* Compile the 4BYTE version of the window register setup routine, + * This mitigates host interconnect issues with non-4byte aligned bus requests, some + * interconnects use bus adapters that impose strict limitations. + * Since diag window access is not intended for performance critical operations, the 4byte mode should + * be satisfactory even though it generates 4X the bus activity. */ + +#ifdef USE_4BYTE_REGISTER_ACCESS + +/* set the window address register (using 4-byte register access ). */ +/*****************************************************************************/ +/* Driver_SetAddressWindowRegister - Utility function to set the window + * register. This is used for diagnostic reads and writes. + * void *pCxt - the driver context. + * uint32_t RegisterAddr - The window register address. + * uint32_t Address - the target address. + *****************************************************************************/ +static A_STATUS Driver_SetAddressWindowRegister(void *pCxt, uint32_t RegisterAddr, uint32_t Address) +{ + A_STATUS status; + uint8_t addrValue[4]; + int32_t i; + A_NETBUF_DECLARE req; + void *pReq = (void *)&req; + + /* write bytes 1,2,3 of the register to set the upper address bytes, the LSB is written + * last to initiate the access cycle */ + Address = A_CPU2LE32(Address); + + for (i = 1; i <= 3; i++) + { + /* fill the buffer with the address byte value we want to hit 4 times*/ + addrValue[0] = ((uint8_t *)&Address)[i]; + addrValue[1] = addrValue[0]; + addrValue[2] = addrValue[0]; + addrValue[3] = addrValue[0]; + + A_NETBUF_CONFIGURE(pReq, (void *)addrValue, 0, 4, 4); + ATH_SET_PIO_EXTERNAL_WRITE_OPERATION(pReq, RegisterAddr + i, false, 4); + + if (A_OK != (status = Hcd_DoPioExternalAccess(pCxt, pReq))) + { + break; + } + } + + if (status != A_OK) + { + return status; + } + + A_NETBUF_CONFIGURE(pReq, (void *)&Address, 0, 4, 4); + ATH_SET_PIO_EXTERNAL_WRITE_OPERATION(pReq, RegisterAddr, true, 4); + status = Hcd_DoPioExternalAccess(pCxt, pReq); + + return status; +} + +#else + +/*****************************************************************************/ +/* Driver_SetAddressWindowRegister - Utility function to set the window + * register. This is used for diagnostic reads and writes. + * void *pCxt - the driver context. + * uint32_t RegisterAddr - The window register address. + * uint32_t Address - the target address. + *****************************************************************************/ +static A_STATUS Driver_SetAddressWindowRegister(void *pCxt, uint32_t RegisterAddr, uint32_t Address) +{ + A_STATUS status; + A_NETBUF_DECLARE req; + void *pReq = (void *)&req; + + Address = A_CPU2LE32(Address); + + do + { + A_NETBUF_CONFIGURE(pReq, (((uint8_t *)(&Address)) + 1), (sizeof(uint32_t) - 1)); + ATH_SET_PIO_EXTERNAL_WRITE_OPERATION(pReq, RegisterAddr + 1, true, (sizeof(uint32_t) - 1)); + + if (A_OK != (status = Hcd_DoPioExternalAccess(pCxt, pReq))) + { + break; + } + + A_NETBUF_CONFIGURE(pReq, ((uint8_t *)(&Address)), sizeof(uint8_t)); + ATH_SET_PIO_EXTERNAL_WRITE_OPERATION(pReq, RegisterAddr, true, sizeof(uint8_t)); + + if (A_OK != (status = Hcd_DoPioExternalAccess(pCxt, pReq))) + { + break; + } + } while (0); + + return status; +} + +#endif + +/*****************************************************************************/ +/* Driver_ReadRegDiag - Reads four bytes of data from the specified chip + * device address. + * void *pCxt - the driver context. + * uint32_t address - the device chip address to start the read. + * uint8_t *data - the start of data destination buffer. + *****************************************************************************/ +A_STATUS +Driver_ReadRegDiag(void *pCxt, uint32_t *address, uint32_t *data) +{ + A_STATUS status; + A_NETBUF_DECLARE req; + void *pReq = (void *)&req; + + A_NETBUF_CONFIGURE(pReq, data, 0, sizeof(uint32_t), sizeof(uint32_t)); + + do + { + /* set window register to start read cycle */ + if (A_OK != (status = Driver_SetAddressWindowRegister(pCxt, WINDOW_READ_ADDR_ADDRESS, *address))) + { + break; + } + + ATH_SET_PIO_EXTERNAL_READ_OPERATION(pReq, WINDOW_DATA_ADDRESS, true, sizeof(uint32_t)); + + if (A_OK != (status = Hcd_DoPioExternalAccess(pCxt, pReq))) + { + break; + } + } while (0); + + return status; +} + +/*****************************************************************************/ +/* Driver_WriteRegDiag - Writes four bytes of data to the specified chip + * device address. + * void *pCxt - the driver context. + * uint32_t address - the device chip address to start the write. + * uint8_t *data - the start of data source buffer. + *****************************************************************************/ +A_STATUS +Driver_WriteRegDiag(void *pCxt, uint32_t *address, uint32_t *data) +{ + A_STATUS status; + + A_NETBUF_DECLARE req; + void *pReq = (void *)&req; + + A_NETBUF_CONFIGURE(pReq, data, 0, sizeof(uint32_t), sizeof(uint32_t)); + + ATH_SET_PIO_EXTERNAL_WRITE_OPERATION(pReq, WINDOW_DATA_ADDRESS, true, sizeof(uint32_t)); + + do + { + if (A_OK != (status = Hcd_DoPioExternalAccess(pCxt, pReq))) + { + break; + } + /* set window register, which starts the write cycle */ + if (A_OK != (status = Driver_SetAddressWindowRegister(pCxt, WINDOW_WRITE_ADDR_ADDRESS, *address))) + { + break; + } + } while (0); + + return status; +} + +/*****************************************************************************/ +/* Driver_ReadDataDiag - Reads a buffer of data starting from address. Length + * of data is specified by length. Data is read from a contiguous chip + * address memory/register space. + * void *pCxt - the driver context. + * uint32_t address - the device chip address to start the read. + * uint8_t *data - the start of data destination buffer. + * uint32_t length - the length of data in bytes. + *****************************************************************************/ +A_STATUS +Driver_ReadDataDiag(void *pCxt, uint32_t address, uint8_t *data, uint32_t length) +{ + uint32_t count; + A_STATUS status = A_OK; + + for (count = 0; count < length; count += 4, address += 4) + { + if ((status = Driver_ReadRegDiag(pCxt, &address, (uint32_t *)&data[count])) != A_OK) + { + break; + } + } + + return status; +} + +/*****************************************************************************/ +/* Driver_WriteDataDiag - Writes a buffer of data starting at address. Length + * of data is specified by length. Data is written to a contiguous chip + * address memory/register space. + * void *pCxt - the driver context. + * uint32_t address - the device chip address to start the write. + * uint8_t *data - the start of data source buffer. + * uint32_t length - the length of data in bytes. + *****************************************************************************/ +A_STATUS +Driver_WriteDataDiag(void *pCxt, uint32_t address, uint8_t *data, uint32_t length) +{ + uint32_t count; + A_STATUS status = A_OK; + + for (count = 0; count < length; count += 4, address += 4) + { + if ((status = Driver_WriteRegDiag(pCxt, &address, (uint32_t *)&data[count])) != A_OK) + { + break; + } + } + + return status; +} + +#define REG_DUMP_COUNT_AR4100 60 +#define REG_DUMP_COUNT_AR4002 60 +#define REGISTER_DUMP_LEN_MAX 60 + +/*****************************************************************************/ +/* Driver_DumpAssertInfo - Collects assert information from chip and writes + * it to stdout. + * void *pCxt - the driver context. + * uint32_t *pData - buffer to store UINT32 results + * uint16_t *pLength - IN/OUT param to store length of buffer for IN and + * length of contents for OUT. + *****************************************************************************/ +A_STATUS +Driver_DumpAssertInfo(void *pCxt, uint32_t *pData, uint16_t *pLength) +{ + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + uint32_t address; + uint32_t regDumpArea = 0; + A_STATUS status = A_ERROR; + uint32_t regDumpCount = 0; + + do + { + if (*pLength < REGISTER_DUMP_LEN_MAX) + { + break; + } + /* clear it */ + *pLength = 0; + /* the reg dump pointer is copied to the host interest area */ + address = HOST_INTEREST_ITEM_ADDRESS(hi_failure_state); + address = TARG_VTOP(address); + + if (pDCxt->targetType == TARGET_TYPE_AR4100 || pDCxt->targetType == TARGET_TYPE_AR400X) + { + regDumpCount = REG_DUMP_COUNT_AR4100; + } + else + { + A_ASSERT(0); /* should never happen */ +#if DRIVER_CONFIG_DISABLE_ASSERT + break; +#endif + } + + /* read RAM location through diagnostic window */ + if (A_OK != (status = Driver_ReadRegDiag(pCxt, &address, ®DumpArea))) + { + A_ASSERT(0); /* should never happen */ +#if DRIVER_CONFIG_DISABLE_ASSERT + break; +#endif + } + + regDumpArea = A_LE2CPU32(regDumpArea); + + if (regDumpArea == 0) + { + /* no reg dump */ + break; + } + + regDumpArea = TARG_VTOP(regDumpArea); + + /* fetch register dump data */ + if (A_OK != + (status = Driver_ReadDataDiag(pCxt, regDumpArea, (uint8_t *)&pData[0], regDumpCount * (sizeof(uint32_t))))) + { + A_ASSERT(0); /* should never happen */ +#if DRIVER_CONFIG_DISABLE_ASSERT + break; +#endif + } + + *pLength = regDumpCount; + } while (0); + + return status; +} diff --git a/platform/mcu/lpc54102/wifi_qca/common_src/driver/driver_init.c b/platform/mcu/lpc54102/wifi_qca/common_src/driver/driver_init.c new file mode 100644 index 0000000000..acd5832f6b --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/common_src/driver/driver_init.c @@ -0,0 +1,897 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "hw20_apb_map.h" +//#include "hw4.0/hw/rtc_reg.h" +#if (DRIVER_CONFIG_ENABLE_HOST_FW_DOWNLOAD) +#include +#include "hw20_mbox_reg.h" +#endif /* DRIVER_CONFIG_ENABLE_HOST_FW_DOWNLOAD */ + +#define HI_OPTION_NUM_DEV_SHIFT 0x9 +#define HI_OPTION_FW_MODE_BSS_STA 0x1 +#define HI_OPTION_FW_MODE_AP 0x2 +#define HI_OPTION_FW_MODE_SHIFT 0xC + +/* 2 bits of hi_option flag are usedto represent 4 submodes */ +#define HI_OPTION_FW_SUBMODE_NONE 0x0 /* Normal mode */ +#define HI_OPTION_FW_SUBMODE_P2PDEV 0x1 /* p2p device mode */ +#define HI_OPTION_FW_SUBMODE_P2PCLIENT 0x2 /* p2p client mode */ +#define HI_OPTION_FW_SUBMODE_P2PGO 0x3 /* p2p go mode */ +#define HI_OPTION_FW_SUBMODE_BITS 0x2 +#define HI_OPTION_FW_SUBMODE_SHIFT 0x14 + +/* hi_option_flag3 options */ +#define HI_OPTION_USE_OFFLOAD_P2P 0x01 + +#if (DRIVER_CONFIG_ENABLE_HOST_FW_DOWNLOAD) +uint32_t ar4XXX_boot_param = AR4XXX_PARAM_MODE_NORMAL | AR4XXX_PARAM_MODE_BMI; // AR4XXX_PARAM_RAW_QUAD; +#else +uint32_t ar4XXX_boot_param = AR4XXX_PARAM_MODE_NORMAL; // AR4XXX_PARAM_RAW_QUAD; +#endif /* DRIVER_CONFIG_ENABLE_HOST_FW_DOWNLOAD */ +uint32_t ar4xx_reg_domain = AR4XXX_PARAM_REG_DOMAIN_DEFAULT; +uint32_t last_driver_error; // Used to store the last error encountered by the driver + +/*****************************************************************************/ +/* ConnectService - Utility to set up a single endpoint service. + * void *pCxt - the driver context. + * HTC_SERVICE_CONNECT_REQ *pConnect - pointer to connect request + * structure. + *****************************************************************************/ +static A_STATUS ConnectService(void *pCxt, HTC_SERVICE_CONNECT_REQ *pConnect) +{ + A_STATUS status; + HTC_SERVICE_CONNECT_RESP response; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + + do + { + A_MEMZERO(&response, sizeof(response)); + + if (A_OK != (status = HTC_ConnectService(pCxt, pConnect, &response))) + { + break; + } + + switch (pConnect->ServiceID) + { + case WMI_CONTROL_SVC: + if (pDCxt->wmiEnabled == true) + { + /* set control endpoint for WMI use */ + wmi_set_control_ep(pDCxt->pWmiCxt, response.Endpoint); + } + break; + case WMI_DATA_BE_SVC: + pDCxt->ac2EpMapping[WMM_AC_BE] = response.Endpoint; + pDCxt->ep2AcMapping[response.Endpoint] = WMM_AC_BE; + break; + case WMI_DATA_BK_SVC: + pDCxt->ac2EpMapping[WMM_AC_BK] = response.Endpoint; + pDCxt->ep2AcMapping[response.Endpoint] = WMM_AC_BK; + break; + case WMI_DATA_VI_SVC: + pDCxt->ac2EpMapping[WMM_AC_VI] = response.Endpoint; + pDCxt->ep2AcMapping[response.Endpoint] = WMM_AC_VI; + break; + case WMI_DATA_VO_SVC: + pDCxt->ac2EpMapping[WMM_AC_VO] = response.Endpoint; + pDCxt->ep2AcMapping[response.Endpoint] = WMM_AC_VO; + break; + default: + status = A_EINVAL; + break; + } + + } while (0); + + return status; +} + +/*****************************************************************************/ +/* SetupServices - Utility to set up endpoint services. + * void *pCxt - the driver context. + *****************************************************************************/ +static A_STATUS SetupServices(void *pCxt) +{ + A_STATUS status; + HTC_SERVICE_CONNECT_REQ connect; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + (void)(pDCxt); + + do + { + A_MEMZERO(&connect, sizeof(connect)); + /* meta data is unused for now */ + connect.pMetaData = NULL; + connect.MetaDataLength = 0; + /* connect to control service */ + connect.ServiceID = WMI_CONTROL_SVC; + + if (A_OK != (status = ConnectService(pCxt, &connect))) + { + break; + } + + connect.LocalConnectionFlags |= HTC_LOCAL_CONN_FLAGS_ENABLE_SEND_BUNDLE_PADDING; + /* limit the HTC message size on the send path, although we can receive A-MSDU frames of + * 4K, we will only send ethernet-sized (802.3) frames on the send path. */ + connect.MaxSendMsgSize = WMI_MAX_TX_DATA_FRAME_LENGTH; + + /* for the remaining data services set the connection flag to reduce dribbling, + * if configured to do so */ + if (WLAN_CONFIG_REDUCE_CREDIT_DRIBBLE) + { + connect.ConnectionFlags |= HTC_CONNECT_FLAGS_REDUCE_CREDIT_DRIBBLE; + /* the credit dribble trigger threshold is (reduce_credit_dribble - 1) for a value + * of 0-3 */ + connect.ConnectionFlags &= ~HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_MASK; + connect.ConnectionFlags |= HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_ONE_HALF; + } + /* connect to best-effort service */ + connect.ServiceID = WMI_DATA_BE_SVC; + + if (A_OK != (status = ConnectService(pCxt, &connect))) + { + break; + } + + /* connect to back-ground + * map this to WMI LOW_PRI */ + connect.ServiceID = WMI_DATA_BK_SVC; + + if (A_OK != (status = ConnectService(pCxt, &connect))) + { + break; + } + + /* connect to Video service, map this to + * to HI PRI */ + connect.ServiceID = WMI_DATA_VI_SVC; + + if (A_OK != (status = ConnectService(pCxt, &connect))) + { + break; + } + + /* connect to VO service, this is currently not + * mapped to a WMI priority stream due to historical reasons. + * WMI originally defined 3 priorities over 3 mailboxes + * We can change this when WMI is reworked so that priorities are not + * dependent on mailboxes */ + connect.ServiceID = WMI_DATA_VO_SVC; + + if (A_OK != (status = ConnectService(pCxt, &connect))) + { + break; + } + + A_ASSERT(pDCxt->ac2EpMapping[WMM_AC_BE] != 0); + A_ASSERT(pDCxt->ac2EpMapping[WMM_AC_BK] != 0); + A_ASSERT(pDCxt->ac2EpMapping[WMM_AC_VI] != 0); + A_ASSERT(pDCxt->ac2EpMapping[WMM_AC_VO] != 0); + } while (0); + + return status; +} + +#if (DRIVER_CONFIG_ENABLE_HOST_FW_DOWNLOAD) +/*****************************************************************************/ +/* Driver_DownloadFirmwareBinary - Utility to download Board data + and athwlan firmware binary to target. + * void *pCxt - the driver context. + *****************************************************************************/ +uint32_t Driver_DownloadFirmwareBinary(void *pCxt) +{ + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + uint32_t address = 0, param = 0; + + /* Temporarily disable system sleep */ + address = MBOX_BASE_ADDRESS + LOCAL_SCRATCH_ADDRESS; + (BMIReadSOCRegister(pCxt, address, ¶m)); + param |= A_CPU2LE32(AR6K_OPTION_SLEEP_DISABLE | AR6K_OPTION_WDT_DISABLE); + (BMIWriteSOCRegister(pCxt, address, param)); + + address = RTC_BASE_ADDRESS + SYSTEM_SLEEP_ADDRESS; + (BMIReadSOCRegister(pCxt, address, ¶m)); + param |= A_CPU2LE32(WLAN_SYSTEM_SLEEP_DISABLE_SET(1)); + (BMIWriteSOCRegister(pCxt, address, param)); + + /* Set Option3 flag in host interest item to boot up + hostproxy application in firmware download mode */ + if (Driver_ReadDataDiag(pCxt, TARG_VTOP(HOST_INTEREST_ITEM_ADDRESS(hi_option_flag3)), (uint8_t *)¶m, 4) != A_OK) + { + A_ASSERT(0); + } + + param |= HI_OPTION_EN_HOST_PROXY_FW_DLOAD_MODE; + + if (Driver_WriteDataDiag(pCxt, TARG_VTOP(HOST_INTEREST_ITEM_ADDRESS(hi_option_flag3)), (uint8_t *)¶m, 4) != + A_OK) + { + A_ASSERT(0); + } + +#if ATH_FIRMWARE_TARGET == TARGET_AR400X_REV1 + /* Set the board data address in HOST interest item for + target to use it */ + param = A_CPU2LE32(AR400X_BOARD_DATA_ADDRESS); + + if (Driver_WriteDataDiag(pCxt, TARG_VTOP(HOST_INTEREST_ITEM_ADDRESS(hi_board_data)), (uint8_t *)¶m, 4) != A_OK) + { + A_ASSERT(0); + } + + /* non-zero value of hi_board_data_initialized indicates that the + board data is valid for the target */ + param = A_CPU2LE32(1); + if (Driver_WriteDataDiag(pCxt, TARG_VTOP(HOST_INTEREST_ITEM_ADDRESS(hi_board_data_initialized)), (uint8_t *)¶m, + 4) != A_OK) + { + A_ASSERT(0); + } +#endif /* ATH_FIRMWARE_TARGET */ + + /* Download firmware binary only if exitAtBmi is false as possibly flash + agent could be attempting to flash the binary onto target flash memory */ + if (true != ath_custom_init.exitAtBmi) + { + /* Clear BMI mode in hi_flash_is_present as we are already in BMI mode */ + param = A_CPU2LE32(AR4XXX_PARAM_MODE_NORMAL | ar4xx_reg_domain); + + if (Driver_WriteDataDiag(pCxt, TARG_VTOP(HOST_INTEREST_ITEM_ADDRESS(hi_flash_is_present)), (uint8_t *)¶m, + 4) != A_OK) + { + A_ASSERT(0); + } + + /* This is just a reference implementation to download the firmware + binary. If memory needs to be optimized, the binary file can be stored + in the host flash file system and can be opened, read in chunks using file + system APIs and can be downloaded using below BMI API */ + BMIWriteMemory(pCxt, BMI_SEGMENTED_WRITE_ADDR, (uint8_t *)&ath_fw_binary_buff, sizeof(ath_fw_binary_buff)); + } + + return 0; +} + +#endif /* DRIVER_CONFIG_ENABLE_HOST_FW_DOWNLOAD */ + +/*****************************************************************************/ +/* Driver_ContextInit - Initializes the drivers COMMON context. The allocation + * for the context should be made by the caller. This function will call + * the Custom_DRiverContextInit to perform any system specific initialization + * Look to Driver_ContextDeInit() to undo what gets done by this function. + * void *pCxt - the driver context. + *****************************************************************************/ +A_STATUS +Driver_ContextInit(void *pCxt) +{ + uint8_t i; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + /* most elements are initialized by setting to zero the rest are explicitly + * initialized. boolean are explicit as it is not obvious what false might be */ + A_MEMZERO(pDCxt, sizeof(A_DRIVER_CONTEXT)); + pDCxt->driver_up = false; + pDCxt->rxBufferStatus = false; + pDCxt->hostVersion = AR6K_SW_VERSION; + pDCxt->wmiReady = false; + pDCxt->wmiEnabled = false; + pDCxt->wmmEnabled = false; + pDCxt->chipDown = true; + pDCxt->strrclState = STRRCL_ST_DISABLED; + pDCxt->strrclBlock = false; + pDCxt->wpsState = false; + + /* Connection element for first device */ + pDCxt->conn[0].networkType = INFRA_NETWORK; + pDCxt->conn[0].dot11AuthMode = OPEN_AUTH; + pDCxt->conn[0].wpaAuthMode = NONE_AUTH; + pDCxt->conn[0].wpaPairwiseCrypto = NONE_CRYPT; + pDCxt->conn[0].wpaGroupCrypto = NONE_CRYPT; + pDCxt->conn[0].wpaPmkValid = false; + pDCxt->conn[0].isConnected = false; + pDCxt->conn[0].isConnectPending = false; + +#if (WLAN_NUM_OF_DEVICES > 1) + pDCxt->conn[1].networkType = INFRA_NETWORK; + pDCxt->conn[1].dot11AuthMode = OPEN_AUTH; + pDCxt->conn[1].wpaAuthMode = NONE_AUTH; + pDCxt->conn[1].wpaPairwiseCrypto = NONE_CRYPT; + pDCxt->conn[1].wpaGroupCrypto = NONE_CRYPT; + pDCxt->conn[1].wpaPmkValid = false; + pDCxt->conn[1].isConnected = false; + pDCxt->conn[1].isConnectPending = false; +#endif + + pDCxt->scanDone = false; + /* through measurement, it's in power save mode by default.*/ + pDCxt->userPwrMode = REC_POWER; + pDCxt->enabledSpiInts = ATH_SPI_INTR_PKT_AVAIL | ATH_SPI_INTR_LOCAL_CPU_INTR; + pDCxt->mboxAddress = HIF_MBOX_START_ADDR(HIF_ACTIVE_MBOX_INDEX); /* the address for mailbox reads/writes. */ + pDCxt->blockSize = HIF_MBOX_BLOCK_SIZE; /* the mailbox block size */ + pDCxt->blockMask = pDCxt->blockSize - 1; /* the mask derived from BlockSize */ + pDCxt->padBuffer = A_MALLOC(pDCxt->blockSize, MALLOC_ID_CONTEXT); + pDCxt->htcStart = false; + pDCxt->macProgramming = false; +#if MANUFACTURING_SUPPORT + pDCxt->testResp = false; +#endif + for (i = 0; i < ENDPOINT_MANAGED_MAX; i++) + { + pDCxt->ep[i].epIdx = i; + } + + A_ASSERT(pDCxt->padBuffer != NULL); + + return CUSTOM_DRIVER_CXT_INIT(pCxt); +} + +/*****************************************************************************/ +/* Driver_ContextDeInit - Undoes any work performed by Driver_ContextInit. + * Used as part of the shutdown process. Calls Driver_ContextDeInit() + * to cleanup any work done by Driver_ContextInit(). + * void *pCxt - the driver context. + *****************************************************************************/ +A_STATUS +Driver_ContextDeInit(void *pCxt) +{ + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + + CUSTOM_DRIVER_CXT_DEINIT(pCxt); + + if (pDCxt->padBuffer != NULL) + { + A_FREE(pDCxt->padBuffer, MALLOC_ID_CONTEXT); + pDCxt->padBuffer = NULL; + } + + return A_OK; +} + +/*****************************************************************************/ +/* Driver_Init - inits any HW resources for HW access. + * Turns CHIP on via GPIO if necessary. + * Performs initial chip interaction. + * If the system has a dedicated driver thread then + * this function should be called by the dedicated thread. + * If not then this function should be called between + * calls to api_InitStart and api_InitFinish + * void *pCxt - the driver context. + *****************************************************************************/ +A_STATUS +Driver_Init(void *pCxt) +{ + A_STATUS status; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + + A_EVENT_INIT(&GET_DRIVER_CXT(p_Global_Cxt)->driverWakeEvent, kEventAutoClear); + A_EVENT_INIT(&GET_DRIVER_CXT(p_Global_Cxt)->userWakeEvent, kEventManualClear); +#if T_SELECT_VER1 + A_EVENT_INIT(&GET_DRIVER_CXT(p_Global_Cxt)->sockSelectWakeEvent, kEventManualClear); +#endif // T_SELECT_VER1 + + do + { + /* initialize various protection elements */ + if (A_OK != (status = RXBUFFER_ACCESS_INIT(pCxt))) + { + break; + } + + if (A_OK != (status = TXQUEUE_ACCESS_INIT(pCxt))) + { + break; + } + + if (A_OK != (status = IRQEN_ACCESS_INIT(pCxt))) + { + break; + } + + if (A_OK != (status = DRIVER_SHARED_RESOURCE_ACCESS_INIT(pCxt))) + { + break; + } + + /* - init hw resources */ + if (A_OK != (status = CUSTOM_HW_INIT(pCxt))) + { + break; + } + /* - Power up device */ + HW_PowerUpDown(pCxt, 1); + + Api_BootProfile(pCxt, BOOT_PROFILE_POWER_UP); + + /* - bring chip CPU out of reset */ + if (A_OK != (status = Hcd_Init(pCxt))) + { + break; + } + + /* It is necessary to postpone further SPI commands, + * until WiFI gets ready. Empirical value is 100ms */ + A_MDELAY(100); + + /* - initiate communication with chip firmware */ + if (A_OK != (status = Driver_BootComm(pCxt))) + { + break; + } + + if ((ar4XXX_boot_param & AR4XXX_PARAM_MODE_MASK) == AR4XXX_PARAM_MODE_BMI) + { + BMIInit(pCxt); + } + + /* - acquire target type */ + if (A_OK != (status = Driver_GetTargetInfo(pCxt))) + { + break; + } + /* - perform any BMI chip configuration */ + if (ath_custom_init.Driver_BMIConfig != NULL) + { + if (A_OK != (status = ath_custom_init.Driver_BMIConfig(pCxt))) + { + break; + } + } + +#if (DRIVER_CONFIG_ENABLE_HOST_FW_DOWNLOAD) + Driver_DownloadFirmwareBinary(pCxt); +#endif /* DRIVER_CONFIG_ENABLE_HOST_FW_DOWNLOAD */ + + /* - perform any target configuration */ + if (ath_custom_init.Driver_TargetConfig != NULL) + { + if (A_OK != (status = ath_custom_init.Driver_TargetConfig(pCxt))) + { + break; + } + } + /* - choose wmi or not wmi */ + if (ath_custom_init.skipWmi == false) + { + pDCxt->pWmiCxt = wmi_init(pCxt); + pDCxt->wmiEnabled = true; +#if WLAN_CONFIG_11N_AGGR_SUPPORT + pDCxt->pAggrCxt = aggr_init(); +#endif + } + + /* - alternate boot mode - exit driver init with BMI active */ + if (ath_custom_init.exitAtBmi) + { + break; + } + + if ((ar4XXX_boot_param & AR4XXX_PARAM_MODE_MASK) == AR4XXX_PARAM_MODE_BMI) + { + /* - done with BMI; call BMIDone */ + if (A_OK != (status = BMIDone(pCxt))) + { + break; + } + } + + /* - wait for HTC setup complete */ + if (A_OK != (status = HTC_WaitTarget(pCxt))) + { + break; + } + /* - setup other non-htc endpoints */ + if (A_OK != (status = SetupServices(pCxt))) + { + break; + } + + + /* - start HTC */ + if (A_OK != (status = HTC_Start(pCxt))) + { + break; + } + + } while (0); + + if (status == A_OK) + { + pDCxt->chipDown = false; + pDCxt->driver_up = true; + pDCxt->driverShutdown = false; + } + + return status; +} + +/*****************************************************************************/ +/* Driver_DeInit - Undoes any work performed by Driver_Init. + * Used as part of the shutdown process. + * void *pCxt - the driver context. + *****************************************************************************/ +A_STATUS +Driver_DeInit(void *pCxt) +{ + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + + Hcd_Deinitialize(pCxt); /* not necessary if HW_PowerUpDown() actually + shuts down chip */ + HW_PowerUpDown(pCxt, 0); + CUSTOM_HW_DEINIT(pCxt); + + if (pDCxt->pWmiCxt) + { + wmi_shutdown(pDCxt->pWmiCxt); + pDCxt->pWmiCxt = NULL; + } +#if WLAN_CONFIG_11N_AGGR_SUPPORT + if (pDCxt->pAggrCxt) + { + aggr_deinit(pDCxt->pAggrCxt); + pDCxt->pAggrCxt = NULL; + } +#endif + + RXBUFFER_ACCESS_DESTROY(pCxt); + TXQUEUE_ACCESS_DESTROY(pCxt); + IRQEN_ACCESS_DESTROY(pCxt); + DRIVER_SHARED_RESOURCE_ACCESS_DESTROY(pCxt); + + pDCxt->driver_up = false; + A_EVENT_DELETE(&GET_DRIVER_CXT(p_Global_Cxt)->userWakeEvent); + A_EVENT_DELETE(&GET_DRIVER_CXT(p_Global_Cxt)->driverWakeEvent); +#if T_SELECT_VER1 + A_EVENT_DELETE(&GET_DRIVER_CXT(p_Global_Cxt)->sockSelectWakeEvent); +#endif // T_SELECT_VER1 + + return A_OK; +} + +/*****************************************************************************/ +/* Driver_GetTargetInfo - Used to get the device target info which includes + * the target version and target type. the results are stored in the + * context. + * void *pCxt - the driver context. + *****************************************************************************/ +A_STATUS +Driver_GetTargetInfo(void *pCxt) +{ + A_STATUS status = A_OK; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + struct bmi_target_info targ_info = {0}; + + if ((ar4XXX_boot_param & AR4XXX_PARAM_MODE_MASK) == AR4XXX_PARAM_MODE_BMI) + { + status = BMIGetTargetInfo(pCxt, &targ_info); + pDCxt->targetVersion = targ_info.target_ver; + pDCxt->targetType = targ_info.target_type; + } + else + { + /* hardcoded for boottime speedup */ + pDCxt->targetVersion = ATH_FIRMWARE_TARGET; + pDCxt->targetType = TARGET_TYPE; + } + + return status; +} + +/*****************************************************************************/ +/* Driver_TargReset - This function performs a warm reset operation on the + * wifi CPU after setting up firmware so that it can discover the + * nvram config structure. + * void *pCxt - the driver context. + *****************************************************************************/ +static uint16_t Driver_TargReset(void *pCxt) +{ +#if ATH_FIRMWARE_TARGET == TARGET_AR4100_REV2 + volatile uint32_t param; + + if ((ar4XXX_boot_param & AR4XXX_PARAM_MODE_MASK) == AR4XXX_PARAM_MODE_NORMAL) + { + do + { + if (Driver_ReadDataDiag(pCxt, TARG_VTOP(AR4100_NVRAM_SAMPLE_ADDR), (uint8_t *)¶m, 4) != A_OK) + { + A_ASSERT(0); + } + } while (param != A_CPU2LE32(AR4100_NVRAM_SAMPLE_VAL)); + + if (Driver_ReadDataDiag(pCxt, TARG_VTOP(AR4100_CONFIGFOUND_ADDR), (uint8_t *)¶m, 4) != A_OK) + { + A_ASSERT(0); + } + + if (param == A_CPU2LE32(AR4100_CONFIGFOUND_VAL)) + { + /* force config_found value */ + param = 0xffffffff; + if (Driver_WriteDataDiag(pCxt, TARG_VTOP(AR4100_CONFIGFOUND_ADDR), (uint8_t *)¶m, 4) != A_OK) + { + A_ASSERT(0); + } + /* instruct ROM to preserve nvram values */ + param = A_CPU2LE32(HI_RESET_FLAG_PRESERVE_NVRAM_STATE); + if (Driver_WriteDataDiag(pCxt, TARG_VTOP(HOST_INTEREST_ITEM_ADDRESS(hi_reset_flag)), (uint8_t *)¶m, + 4) != A_OK) + { + A_ASSERT(0); + } + /* instruct ROM to parse hi_reset_flag */ + param = A_CPU2LE32(HI_RESET_FLAG_IS_VALID); + if (Driver_WriteDataDiag(pCxt, TARG_VTOP(HOST_INTEREST_ITEM_ADDRESS(hi_reset_flag_valid)), + (uint8_t *)¶m, 4) != A_OK) + { + A_ASSERT(0); + } + /* clear hi_refclk_hz to identify reset point */ + param = A_CPU2LE32(0x00); + if (Driver_WriteDataDiag(pCxt, TARG_VTOP(HOST_INTEREST_ITEM_ADDRESS(hi_refclk_hz)), (uint8_t *)¶m, 4) != + A_OK) + { + A_ASSERT(0); + } + /* reset CPU */ + param = A_CPU2LE32(WLAN_RESET_CONTROL_WARM_RST_MASK); + if (Driver_WriteDataDiag(pCxt, TARG_VTOP(RTC_BASE_ADDRESS | RESET_CONTROL_ADDRESS), (uint8_t *)¶m, 4) != + A_OK) + { + A_ASSERT(0); + } + /* force delay before further chip access after reset */ + CUSTOM_HW_USEC_DELAY(pCxt, 1000); + + return 1; + } + } +#else + UNUSED_ARGUMENT(pCxt); +#endif + return 0; +} + +/*****************************************************************************/ +/* Driver_BootComm - Communicates with the device using the diagnostic + * window to perform various interactions during the boot process. + * void *pCxt - the driver context. + *****************************************************************************/ +A_STATUS +Driver_BootComm(void *pCxt) +{ + volatile uint32_t param; + uint8_t resetpass = 0; + + if (ath_custom_init.Driver_BootComm != NULL) + { + return ath_custom_init.Driver_BootComm(pCxt); + } + +#if (ATH_FIRMWARE_TARGET == TARGET_AR4100_REV2 || ATH_FIRMWARE_TARGET == TARGET_AR400X_REV1) + /* interact with host_proxy via HOST_INTEREST to control BMI active */ + + do + { +#if ENABLE_FPGA_BUILD + HW_USEC_DELAY(pCxt, 4000); +#endif + // On the QCA4004, the code sometimes hits one of the A_ASSERTs if this delay + // is not present. To be studied in detail later (THK, 2016-Jan) + A_MDELAY(4); + do + { + if (Driver_ReadDataDiag(pCxt, TARG_VTOP(HOST_INTEREST_ITEM_ADDRESS(hi_refclk_hz)), (uint8_t *)¶m, 4) != + A_OK) + { + A_ASSERT(0); + } + // printf("%d\r\n", param); + } while (param != A_CPU2LE32(EXPECTED_REF_CLK_AR4100) && param != A_CPU2LE32(EXPECTED_REF_CLK_AR400X)); + + Api_BootProfile(pCxt, BOOT_PROFILE_READ_REFCLK); + +#if 0 // Enabling firmware UART print and setting baud rate to 115200 + param = A_CPU2LE32(1); + if (Driver_WriteDataDiag(pCxt, + TARG_VTOP(HOST_INTEREST_ITEM_ADDRESS(hi_serial_enable)), + (uint8_t *)¶m, + 4) != A_OK) + { + A_ASSERT(0); + } + + param = A_CPU2LE32(115200); + if (Driver_WriteDataDiag(pCxt, + TARG_VTOP(HOST_INTEREST_ITEM_ADDRESS(hi_desired_baud_rate)), + (uint8_t *)¶m, + 4) != A_OK) + { + A_ASSERT(0); + } +#endif + + param = A_CPU2LE32(0x31); + if (Driver_WriteDataDiag(pCxt, TARG_VTOP(HOST_INTEREST_ITEM_ADDRESS(hi_pwr_save_flags)), (uint8_t *)¶m, + 4) != A_OK) + { + A_ASSERT(0); + } + +/* wait host_proxy ready */ +#if ENABLE_FPGA_BUILD + do + { + if (Driver_ReadDataDiag(pCxt, TARG_VTOP(HOST_INTEREST_ITEM_ADDRESS(hi_flash_is_present)), (uint8_t *)¶m, + 4) != A_OK) + { + A_ASSERT(0); + } + } while ((param & HOST_PROXY_BOOTCTL_MASK) != A_CPU2LE32(HOST_PROXY_INIT)); +#endif + /* this code is called prior to BMIGetTargInfo so we must assume AR6003 */ + param = A_CPU2LE32(ar4XXX_boot_param | ar4xx_reg_domain); + + Api_BootProfile(pCxt, BOOT_PROFILE_BOOT_PARAMETER); + + if (Driver_WriteDataDiag(pCxt, TARG_VTOP(HOST_INTEREST_ITEM_ADDRESS(hi_flash_is_present)), (uint8_t *)¶m, + 4) != A_OK) + { + A_ASSERT(0); + } + + // Api_BootProfile(pCxt, 0x02); + if (WLAN_NUM_OF_DEVICES == 1) + { + param = ((1 << HI_OPTION_NUM_DEV_SHIFT) | (HI_OPTION_FW_MODE_BSS_STA << HI_OPTION_FW_MODE_SHIFT) | + (1 << HI_OPTION_FW_BRIDGE_SHIFT)) | + HI_OPTION_DISABLE_DBGLOG; + + if (Driver_WriteDataDiag(pCxt, TARG_VTOP(HOST_INTEREST_ITEM_ADDRESS(hi_option_flag)), (uint8_t *)¶m, + 4) != A_OK) + { + A_ASSERT(0); + } + } + else + { + /* Set P2P Offload support */ + param = HI_OPTION_USE_OFFLOAD_P2P; + + if (Driver_WriteDataDiag(pCxt, TARG_VTOP(HOST_INTEREST_ITEM_ADDRESS(hi_option_flag3)), (uint8_t *)¶m, + 4) != A_OK) + { + A_ASSERT(0); + } + /* Set number of Device and device mode + device 0 - P2P Device ; device 1 - IEEE STA */ + param = ((2 << HI_OPTION_NUM_DEV_SHIFT) | + (((HI_OPTION_FW_MODE_BSS_STA << 2 | HI_OPTION_FW_MODE_BSS_STA)) << HI_OPTION_FW_MODE_SHIFT) | + (((HI_OPTION_FW_SUBMODE_NONE << HI_OPTION_FW_SUBMODE_BITS) | HI_OPTION_FW_SUBMODE_P2PDEV) + << HI_OPTION_FW_SUBMODE_SHIFT) | + (1 << HI_OPTION_FW_BRIDGE_SHIFT)); + + if (Driver_WriteDataDiag(pCxt, TARG_VTOP(HOST_INTEREST_ITEM_ADDRESS(hi_option_flag)), (uint8_t *)¶m, + 4) != A_OK) + { + A_ASSERT(0); + } + +#if !ENABLE_SCC_MODE + /* Enable MCC */ + if (Driver_ReadDataDiag(pCxt, TARG_VTOP(HOST_INTEREST_ITEM_ADDRESS(hi_option_flag2)), (uint8_t *)¶m, + 4) != A_OK) + { + A_ASSERT(0); + } + + param |= HI_OPTION_MCC_ENABLE; + if (Driver_WriteDataDiag(pCxt, TARG_VTOP(HOST_INTEREST_ITEM_ADDRESS(hi_option_flag2)), (uint8_t *)¶m, + 4) != A_OK) + { + A_ASSERT(0); + } +#endif /* ENABLE_SCC_MODE */ + } + + } while (resetpass++ < 1 && Driver_TargReset(pCxt)); + +#else + UNUSED_ARGUMENT(param); + UNUSED_ARGUMENT(loop); +#endif + return A_OK; +} + +#if (DRIVER_CONFIG_ENABLE_HOST_FW_DOWNLOAD) +A_STATUS Driver_StoreRecallFirmwareDownload(void *pCxt) +{ + A_STATUS status = A_OK; + + do + { + if ((ar4XXX_boot_param & AR4XXX_PARAM_MODE_MASK) == AR4XXX_PARAM_MODE_BMI) + { + BMIInit(pCxt); + } + + /* - acquire target type */ + if (A_OK != (status = Driver_GetTargetInfo(pCxt))) + { + break; + } + /* - perform any BMI chip configuration */ + if (ath_custom_init.Driver_BMIConfig != NULL) + { + if (A_OK != (status = ath_custom_init.Driver_BMIConfig(pCxt))) + { + break; + } + } + + /* Download the firmware binary */ + Driver_DownloadFirmwareBinary(pCxt); + + /* - perform any target configuration */ + if (ath_custom_init.Driver_TargetConfig != NULL) + { + if (A_OK != (status = ath_custom_init.Driver_TargetConfig(pCxt))) + { + break; + } + } + + if ((ar4XXX_boot_param & AR4XXX_PARAM_MODE_MASK) == AR4XXX_PARAM_MODE_BMI) + { + /* - done with BMI; call BMIDone */ + if (A_OK != (status = BMIDone(pCxt))) + { + break; + } + } + } while (0); + + return status; +} +#endif /* DRIVER_CONFIG_ENABLE_HOST_FW_DOWNLOAD */ diff --git a/platform/mcu/lpc54102/wifi_qca/common_src/driver/driver_main.c b/platform/mcu/lpc54102/wifi_qca/common_src/driver/driver_main.c new file mode 100644 index 0000000000..a1aa2a071c --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/common_src/driver/driver_main.c @@ -0,0 +1,848 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "atheros_wifi_api.h" +#include "atheros_wifi_internal.h" +#include "wifi_driver_main.h" //for OS Dependent +#include "fsl_debug_console.h" + +/*****************************************************************************/ +/********** IMPLEMENTATION **********/ +/*****************************************************************************/ + +uint32_t g_totAlloc = 0; +uint32_t g_poolid = 0xffffffff; + +/*****************************************************************************/ +/* Driver_Main - This is the top level entry point for the Atheros wifi driver + * This should be called from either a dedicated thread running in a loop or, + * in the case of single threaded systems it should be called periodically + * from the main loop. Also, if in a single threaded system a API call + * requires synchronous completion then it may be necessary to call this + * function from within the API call. + * void *pCxt - the driver context. + * uint8_t scope - Limits/allows what type of activity may be processed. + * Options are any combination of DRIVER_SCOPE_TX + DRIVER_SCOPE_RX. + * boolean *pCanBlock - used to report to caller whether the driver is + * in a state where it is safe to block until further notice. + * uint16_t *pBlock_msec - used to report to caller how long the driver + * may block for. if zero then driver can block indefinitely. + *****************************************************************************/ +A_STATUS +Driver_Main(void *pCxt, uint8_t scope, boolean *pCanBlock, uint16_t *pBlock_msec) +{ + void *pReq; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + + HW_ProcessPendingInterrupts(pCxt); // IGX_UD_CHANGES + + /* This is where packets are received from the + * wifi device. Because system buffers must be + * available to receive a packet we only call into + * this function if we know that buffers are + * available to satisfy the operation. + */ + if ((scope & DRIVER_SCOPE_RX) && true == Driver_RxReady(pCxt)) + { + pDCxt->driver_state = DRIVER_STATE_RX_PROCESSING; + pReq = pDCxt->pRxReq; + pDCxt->pRxReq = NULL; + if (A_OK != Driver_RecvPacket(pCxt, pReq)) + { + /* if this happens it is a critical error */ + A_ASSERT(0); + } + /* FIXME: as an optimization the next lookahead may have + * been acquired from the trailer of the previous rx packet. + * in that case we should pre-load the lookahead so as to + * avoid reading it from the registers. */ + /* reset the lookahead for the next read operation */ + pDCxt->lookAhead = 0; + /* check to see if a deferred bus request has completed. if so + * process it. */ + if (pDCxt->booleans & SDHD_BOOL_DMA_COMPLETE) + { + /* get the request */ + if (A_OK == Driver_CompleteRequest(pCxt, pDCxt->spi_hcd.pCurrentRequest)) + { + /* clear the pending request and the boolean */ + pDCxt->spi_hcd.pCurrentRequest = NULL; + pDCxt->booleans &= ~SDHD_BOOL_DMA_COMPLETE; + } + } + } + + pDCxt->driver_state = DRIVER_STATE_PENDING_CONDITION_D; + + if ((scope & DRIVER_SCOPE_TX) && true == Driver_TxReady(pCxt)) + { + pDCxt->driver_state = DRIVER_STATE_TX_PROCESSING; + /* after processing any outstanding device interrupts + * see if there is a packet that requires transmitting + */ + if (pDCxt->txQueue.count) + { + /* accesslock here to sync with threads calling + * submit TX + */ + TXQUEUE_ACCESS_ACQUIRE(pCxt); + { + pReq = A_NETBUF_DEQUEUE(&(pDCxt->txQueue)); + } + TXQUEUE_ACCESS_RELEASE(pCxt); + + if (pReq != NULL) + { + Driver_SendPacket(pCxt, pReq); + } + } + } + + pDCxt->driver_state = DRIVER_STATE_PENDING_CONDITION_E; + + /* execute any asynchronous/special request when possible */ + if (0 == (pDCxt->booleans & SDHD_BOOL_DMA_IN_PROG) && pDCxt->asynchRequest) + { + pDCxt->driver_state = DRIVER_STATE_ASYNC_PROCESSING; + pDCxt->asynchRequest(pCxt); + pDCxt->driver_state = DRIVER_STATE_PENDING_CONDITION_F; + } + + pDCxt->driver_state = DRIVER_STATE_PENDING_CONDITION_G; + /* allow caller to block if all necessary conditions are satisfied */ + if (pCanBlock) + { + if ((pDCxt->spi_hcd.PendingIrqAcks == 0 || pDCxt->rxBufferStatus == false) && + (pDCxt->spi_hcd.IrqDetected == false) && (pDCxt->txQueue.count == 0 || Driver_TxReady(pCxt) == false) && + (0 == (pDCxt->booleans & SDHD_BOOL_DMA_COMPLETE))) + { + *pCanBlock = true; + + if (pDCxt->creditDeadlock == true) + { + if (pBlock_msec) + { + *pBlock_msec = DEADLOCK_BLOCK_MSEC; + } + + pDCxt->creditDeadlockCounter++; + } + + pDCxt->driver_state = DRIVER_STATE_IDLE; + } + else + { + *pCanBlock = false; + } + } + + return A_OK; +} + +/*****************************************************************************/ +/* Driver_ReportRxBuffStatus - Tracks availability of Rx Buffers for those + * systems that have a limited pool. The driver quearies this status before + * initiating a RX packet transaction. + * void *pCxt - the driver context. + * boolean status - new status true - RX buffers are available, + * false - RX buffers are not available. + *****************************************************************************/ + +#if defined(DRIVER_CONFIG_IMPLEMENT_RX_FREE_MULTIPLE_QUEUE) +uint8_t GetQueueIndexByEPID(uint8_t epid) +{ + uint8_t i; + + for (i = 0; i < 8; i++) + if (GET_QUEUE_MASK(i) & (1 << epid)) + break; + if (i >= 1 && i < 8) + i = 7; + return i; +} + +uint8_t GetQueueCtrlIndexByEPID(uint8_t epid) +{ + uint8_t i; + + for (i = 0; i < 8; i++) + if (GET_QUEUE_MASK(i) & (1 << epid)) + break; + return i; +} + +void Driver_ReportRxBuffStatus(void *pCxt, boolean status, uint8_t epid) +{ + boolean oldStatus; // CHECKME + uint8_t bufNdx; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + + bufNdx = GetQueueIndexByEPID(epid); + /* NOTE: Dont acquire the lock here instead the + * caller should acquire this lock if necessary prior to calling this function */ + // RXBUFFER_ACCESS_ACQUIRE(pCxt); + + oldStatus = pDCxt->rxBufferStatus; + + if (status) + { + pDCxt->rxMultiBufferStatus |= 1 << bufNdx; + } + else + { + pDCxt->rxMultiBufferStatus &= ~(1 << bufNdx); + } + pDCxt->rxBufferStatus = (pDCxt->rxMultiBufferStatus != 0); + + // RXBUFFER_ACCESS_RELEASE(pCxt); + /* the driver thread may have blocked on this + * status so conditionally wake up the thread + * via QueueWork */ + if ((oldStatus == false) && (status == true)) + { + if (pDCxt->hcd.PendingIrqAcks) + { + DRIVER_WAKE_DRIVER(pCxt); + } + } +} +#else +void Driver_ReportRxBuffStatus(void *pCxt, boolean status) +{ + boolean oldStatus; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + + /* NOTE: Dont acquire the lock here instead the + * caller should acquire this lock if necessary prior to calling this function */ + // RXBUFFER_ACCESS_ACQUIRE(pCxt); + { + oldStatus = pDCxt->rxBufferStatus; + pDCxt->rxBufferStatus = status; + } + // RXBUFFER_ACCESS_RELEASE(pCxt); + /* the driver thread may have blocked on this + * status so conditionally wake up the thread + * via QueueWork */ + if (oldStatus == false && status == true) + { + if (pDCxt->spi_hcd.PendingIrqAcks) + { + DRIVER_WAKE_DRIVER(pCxt); + } + } +} +#endif + +/*****************************************************************************/ +/* Driver_CompleteRequest - Completes a deferred request. One that finished + * asynchronously. Such a request must have a non-null callback that will + * be called by this function to fullfill the operation. + * void *pCxt - the driver context. + * void *pReq - the bus request object. + *****************************************************************************/ +A_STATUS +Driver_CompleteRequest(void *pCxt, void *pReq) +{ + A_STATUS status = A_ERROR; + void (*cb)(void *, void *); + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + /* A hardware WAR exists whereby interrupts from the device are disabled + * during an ongoing bus transaction. This function is called when + * the bus transaction completes. if irqMask is set then it means that + * interrupts should be re-enabled */ + if (pDCxt->spi_hcd.irqMask) + { + Hcd_UnmaskInterrupts(pCxt, pDCxt->spi_hcd.irqMask); + pDCxt->spi_hcd.irqMask = 0; + } + + if (pReq != NULL && NULL != (cb = A_NETBUF_GET_ELEM(pReq, A_REQ_CALLBACK))) + { + cb(pCxt, pReq); + status = A_OK; + } + else + { + A_ASSERT(0); + } + + return status; +} + +/*****************************************************************************/ +/* Driver_TxReady - Determines whether it is safe to start a TX operation. If + * a TX operation can be started this function returns true else false. + * void *pCxt - the driver context. + *****************************************************************************/ +boolean Driver_TxReady(void *pCxt) +{ + boolean res = false; + void *pReq; + A_ENDPOINT_T *pEp; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + + pDCxt->creditDeadlock = false; + + do + { + /* there can be no errors */ + if (pDCxt->booleans & SDHD_BOOL_FATAL_ERROR) + { + break; + } + /* there can be no in-complete requests */ + if ((pDCxt->booleans & SDHD_BOOL_DMA_IN_PROG) || (pDCxt->booleans & SDHD_BOOL_DMA_COMPLETE) || + /* the write buffer watermark interrupt must not be configured */ + (pDCxt->booleans & SDHD_BOOL_DMA_WRITE_WAIT_FOR_BUFFER)) + { + break; + } + + /* there must be enough credits for the target endpoint */ + if (NULL == (pReq = A_NETBUF_PEEK_QUEUE(&(pDCxt->txQueue)))) + { + break; + } + + if (NULL == (pEp = Util_GetEndpoint(pCxt, A_NETBUF_GET_ELEM(pReq, A_REQ_EPID)))) + { + break; + } + /* ensure as sanity check that the request length is less than a credit length */ + if (pDCxt->creditSize < DEV_CALC_SEND_PADDED_LEN(pDCxt, A_NETBUF_LEN(pReq))) + { + // THIS IS AN ERROR AS REQUESTS SHOULD NEVER EXCEED THE CREDIT SIZE + A_ASSERT(0); +#if DRIVER_CONFIG_DISABLE_ASSERT + break; +#endif + } +#if RESERVE_ONE_CREDIT_FOR_CONTROL + if ((pEp->epIdx == 0) || (pEp->epIdx == 1)) + { + /* confirm there are enough credits for this transfer */ + if (0 == pEp->credits) + { + // if(pDCxt->rxBufferStatus == false) + { + /* need to use alternate mode to acquire credits */ + Htc_GetCreditCounterUpdate(pCxt, A_NETBUF_GET_ELEM(pReq, A_REQ_EPID)); + + if (0 == pEp->credits) + { /* test again in case no new credits were acquired */ + if (pDCxt->rxBufferStatus == false) + { + /* with no rx buffers to receive a credit report and no interrupt + * credits a condition exists where the driver may become deadlocked. + * Hence the creditDeadlock boolean is set to prevent the driver from + * sleeping. this will cause the driver to poll for credits until + * the condition is passed. + */ + pDCxt->creditDeadlock = true; +#if 0 + if(pDCxt->creditDeadlockCounter >= MAX_CREDIT_DEADLOCK_ATTEMPTS){ + /* This is a serious condition that can be brought about by + * a flood of RX packets which generate TX responses and do not + * return the RX buffer to the driver until the TX response + * completes. To mitigate this situation purge the tx queue + * of any packets on data endpoints. + */ + Driver_DropTxDataPackets(pCxt); + pDCxt->creditDeadlockCounter = 0; + } +#endif + } + + break; + } + } + // else{ + // break;/* wait for credit report from device */ + //} + } + } + + else + { + /* confirm there are enough credits for this transfer */ + if (pEp->credits <= 1) + { + // if(pDCxt->rxBufferStatus == false) + { + /* need to use alternate mode to acquire credits */ + Htc_GetCreditCounterUpdate(pCxt, A_NETBUF_GET_ELEM(pReq, A_REQ_EPID)); + + if (pEp->credits <= 1) + { /* test again in case no new credits were acquired */ + if (pDCxt->rxBufferStatus == false) + { + /* with no rx buffers to receive a credit report and no interrupt + * credits a condition exists where the driver may become deadlocked. + * Hence the creditDeadlock boolean is set to prevent the driver from + * sleeping. this will cause the driver to poll for credits until + * the condition is passed. + */ + pDCxt->creditDeadlock = true; +#if 0 + if(pDCxt->creditDeadlockCounter >= MAX_CREDIT_DEADLOCK_ATTEMPTS){ + /* This is a serious condition that can be brought about by + * a flood of RX packets which generate TX responses and do not + * return the RX buffer to the driver until the TX response + * completes. To mitigate this situation purge the tx queue + * of any packets on data endpoints. + */ + Driver_DropTxDataPackets(pCxt); + pDCxt->creditDeadlockCounter = 0; + } +#endif + } + + break; + } + } + // else{ + // break;/* wait for credit report from device */ + //} + } + + } /*(pEp->epIdx == 0) || (pEp->epIdx == 1)*/ +#else + if (0 == pEp->credits) + { + // if(pDCxt->rxBufferStatus == false) + { + /* need to use alternate mode to acquire credits */ + Htc_GetCreditCounterUpdate(pCxt, A_NETBUF_GET_ELEM(pReq, A_REQ_EPID)); + + if (0 == pEp->credits) + { /* test again in case no new credits were acquired */ + if (pDCxt->rxBufferStatus == false) + { + /* with no rx buffers to receive a credit report and no interrupt + * credits a condition exists where the driver may become deadlocked. + * Hence the creditDeadlock boolean is set to prevent the driver from + * sleeping. this will cause the driver to poll for credits until + * the condition is passed. + */ + pDCxt->creditDeadlock = true; +#if 1 + if(pDCxt->creditDeadlockCounter >= MAX_CREDIT_DEADLOCK_ATTEMPTS){ + /* This is a serious condition that can be brought about by + * a flood of RX packets which generate TX responses and do not + * return the RX buffer to the driver until the TX response + * completes. To mitigate this situation purge the tx queue + * of any packets on data endpoints. + */ + Driver_DropTxDataPackets(pCxt); + pDCxt->creditDeadlockCounter = 0; + } +#endif + } + + break; + } + } + // else{ + // break;/* wait for credit report from device */ + //} + } +#endif + + pDCxt->creditDeadlockCounter = 0; + + /* there must be enough write buffer space in the target fifo */ + if (pDCxt->spi_hcd.WriteBufferSpace < + DEV_CALC_SEND_PADDED_LEN(pDCxt, A_NETBUF_LEN(pReq)) + ATH_SPI_WRBUF_RSVD_BYTES) + { + /* this will read the internal register to get the latest value for write buffer space */ + Hcd_RefreshWriteBufferSpace(pCxt); + + if (pDCxt->spi_hcd.WriteBufferSpace < + DEV_CALC_SEND_PADDED_LEN(pDCxt, A_NETBUF_LEN(pReq)) + ATH_SPI_WRBUF_RSVD_BYTES) + { + /* there currently isn't enough space in the target fifo to accept this packet. + * Hence setup the write buffer watermark interrupt for future notification and exit. */ + Hcd_ProgramWriteBufferWaterMark(pCxt, DEV_CALC_SEND_PADDED_LEN(pDCxt, A_NETBUF_LEN(pReq))); + /* wait for interrupt to indicate space available */ + break; + } + } + /* all conditions are met to transmit a packet */ + res = true; + } while (0); + + return res; +} + +/*****************************************************************************/ +/* Driver_RxReady - Determines whether it is safe to start a RX operation. If + * a RX operation can be started this function returns true else false. + * void *pCxt - the driver context. + *****************************************************************************/ +boolean Driver_RxReady(void *pCxt) +{ + boolean res = false; + HTC_FRAME_HDR *pHTCHdr; + int32_t fullLength; + uint32_t interrupts; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + + do + { + /* there can be no errors */ + if (pDCxt->booleans & SDHD_BOOL_FATAL_ERROR) + { + break; + } + /* there can be no in-complete requests */ + if ((pDCxt->booleans & SDHD_BOOL_DMA_IN_PROG) || (pDCxt->booleans & SDHD_BOOL_DMA_COMPLETE)) + { + break; + } + /* the wifi device must have indicated that a packet is ready */ + if (0 == pDCxt->spi_hcd.PendingIrqAcks) + { + break; + } + /* there must be rx buffers to process the request */ + if (false == pDCxt->rxBufferStatus && NULL == pDCxt->pRxReq) + { + break; + } + /* clear the pkt interrupt if its set. We do this here rather than in the + * interrupt handler because we will continue to process packets until we + * read a lookahead==0. only then will we unmask the interrupt */ + if (A_OK != Hcd_DoPioInternalAccess(pCxt, ATH_SPI_INTR_CAUSE_REG, &interrupts, true)) + { + break; + } + + if (interrupts & ATH_SPI_INTR_PKT_AVAIL) + { + interrupts = ATH_SPI_INTR_PKT_AVAIL; + + if (A_OK != Hcd_DoPioInternalAccess(pCxt, ATH_SPI_INTR_CAUSE_REG, &interrupts, false)) + { + break; + } + } + /* RX packet interrupt processing must be enabled */ + if (0 == (pDCxt->enabledSpiInts & ATH_SPI_INTR_PKT_AVAIL)) + { + break; + } + /* As a last step read the lookahead and the Receive buffer register in an + * effort to determine that a complete packet is ready for transfer. Do this + * operation last as it does require several BUS transactions to complete. */ + if (0 == pDCxt->lookAhead) + { + /* need to refresh the lookahead */ + if (A_OK != Hcd_GetLookAhead(pCxt)) + { + /* this is a major error */ + A_ASSERT(0); + } + } + /* if lookahead is 0 then no need to proceed */ + if (0 == pDCxt->lookAhead) + { + if (0 != pDCxt->spi_hcd.PendingIrqAcks) + { + /* this should always be true here */ + pDCxt->spi_hcd.PendingIrqAcks = 0; + Hcd_UnmaskInterrupts(pCxt, ATH_SPI_INTR_PKT_AVAIL); + } + + break; + } + /* compare lookahead and recv buf ready value */ + pHTCHdr = (HTC_FRAME_HDR *)&(pDCxt->lookAhead); + if (pDCxt->spi_hcd.ReadBufferSpace < sizeof(HTC_FRAME_HDR) || + pDCxt->spi_hcd.ReadBufferSpace < A_LE2CPU16(pHTCHdr->PayloadLen)) + { + /* force a call to BUS_GetLookAhead on the next pass */ + pDCxt->lookAhead = 0; + break; + } + /* there must be resources available to receive a packet */ + if (NULL == pDCxt->pRxReq) + { + fullLength = + (int32_t)DEV_CALC_RECV_PADDED_LEN(pDCxt, A_LE2CPU16(pHTCHdr->PayloadLen) + sizeof(HTC_FRAME_HDR)); + +#if defined(DRIVER_CONFIG_IMPLEMENT_RX_FREE_MULTIPLE_QUEUE) + { + uint32_t flags, bufNdx; + + bufNdx = GetQueueIndexByEPID(pHTCHdr->EndpointID); + flags = 1 << bufNdx; + + if (pDCxt->rxMultiBufferStatus & flags) + { + /* try to get an RX buffer */ + pDCxt->pRxReq = CUSTOM_DRIVER_GET_RX_REQ(pCxt, fullLength, pHTCHdr->EndpointID); + } + } +#else + + if (pDCxt->rxBufferStatus) + { + /* try to get an RX buffer */ + pDCxt->pRxReq = CUSTOM_DRIVER_GET_RX_REQ(pCxt, fullLength); + } +#endif + + if (pDCxt->pRxReq == NULL) + { + break; + } + /* init the packet callback */ + A_NETBUF_SET_ELEM(pDCxt->pRxReq, A_REQ_CALLBACK, Driver_RxComplete); + } + /* all conditions are met to receive a packet */ + res = true; + } while (0); + + return res; +} + +void Driver_DropTxDataPackets(void *pCxt) +{ + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + void *pReq; + uint16_t i, count; + + if (pDCxt->txQueue.count) + { + count = pDCxt->txQueue.count; + /* accesslock here to sync with threads calling + * submit TX + */ + for (i = 0; i < count; i++) + { + TXQUEUE_ACCESS_ACQUIRE(pCxt); + { + pReq = A_NETBUF_DEQUEUE(&(pDCxt->txQueue)); + } + TXQUEUE_ACCESS_RELEASE(pCxt); + + if (pReq != NULL) + { + if (A_NETBUF_GET_ELEM(pReq, A_REQ_EPID) > ENDPOINT_1) + { + Driver_CompleteRequest(pCxt, pReq); + } + else + { + TXQUEUE_ACCESS_ACQUIRE(pCxt); + /* re-queue the packet as it is not one we can purge */ + A_NETBUF_ENQUEUE(&(pDCxt->txQueue), pReq); + TXQUEUE_ACCESS_RELEASE(pCxt); + } + } + } + } +} + +#if defined(DRIVER_CONFIG_IMPLEMENT_RX_FREE_MULTIPLE_QUEUE) +extern A_NETBUF *ep0_buf; + +void Driver_ReportReverseCredits(void *pReq) +{ + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(p_Global_Cxt); + A_NETBUF *pCurrTxReq; + +#if 0 + A_ENDPOINT_T *pEp; + void *osbuf; + void *pReq; + if (pDCxt->txQueue.count != 0) + { + pReq = A_NETBUF_PEEK_QUEUE(&(pDCxt->txQueue)); + pEp = Util_GetEndpoint(p_Global_Cxt, A_NETBUF_GET_ELEM(pReq, A_REQ_EPID)); + if (pEp->credits != 0) + return; + } + osbuf = A_NETBUF_ALLOC(0); + A_NETBUF_SET_ELEM(osbuf, A_REQ_EPID, 0); + Driver_SubmitTxRequest(p_Global_Cxt, osbuf); +#else + + if (hasRCSReport() == false) + { + return; + } + + pCurrTxReq = A_NETBUF_PEEK_QUEUE(&(pDCxt->txQueue)); + if (pCurrTxReq != NULL) + { + if (A_NETBUF_GET_ELEM(pCurrTxReq, A_REQ_EPID) == ENDPOINT_0) + return; + } + + a_netbuf_reinit(ep0_buf, 0); + A_NETBUF_SET_ELEM(ep0_buf, A_REQ_EPID, 0); + + qosal_intr_disable(); + Driver_SubmitEp0TxRequest(p_Global_Cxt, ep0_buf); + + qosal_intr_enable(); + +#endif +} + +#endif + +A_STATUS +Driver_WaitForCondition(void *pCxt, volatile boolean *pCond, boolean value, uint32_t msec) +{ + A_STATUS status = A_OK; + + event_t *pEvent = &GET_DRIVER_CXT(pCxt)->userWakeEvent; + + while (1) + { + if (*pCond != value) + { + A_EVENT_FLAGS setFlags; + if (A_OK != A_EVENT_WAIT(pEvent, 0x01, true, msec, &setFlags)) + { + status = A_ERROR; + break; + } + else + { + A_EVENT_CLEAR(pEvent, 0x01); + } + A_MDELAY(1); + } + else + { + break; + } + } + + return status; +} + +#if 1 +A_STATUS setup_host_dset(void *handle) +{ + return wmi_dset_host_cfg_cmd(handle); +} +#else +A_STATUS setup_host_dset(void *handle) +{ + return A_OK; +} +#endif + +void Atheros_Driver_Task(void *pCxt) +{ + boolean canBlock = false; + uint16_t block_msec = 1000; // TODO: what should be a correct value?? + uint32_t timeout = 0; + + do + { + PRINTF("Atheros_Driver_Task \r\n"); + if (A_OK == Driver_Init(pCxt)) + { + PRINTF("Driver_Init A_OK \r\n"); + while (1) + { + if (canBlock) + { + GET_DRIVER_COMMON(pCxt)->driverSleep = true; + timeout = block_msec; + + if (block_msec && timeout == 0) + { + timeout = 1; + } + event_t *pEvent = &(GET_DRIVER_CXT(pCxt)->driverWakeEvent); + A_EVENT_FLAGS setFlags; + if (A_OK != A_EVENT_WAIT(pEvent, 0x01, true, timeout, &setFlags)) + { + if (timeout == 0) + { + break; + } + } + } + + GET_DRIVER_COMMON(pCxt)->driverSleep = false; + + if (GET_DRIVER_COMMON(pCxt)->driverShutdown == true) + { + break; + } + + Driver_Main(pCxt, DRIVER_SCOPE_RX | DRIVER_SCOPE_TX, &canBlock, &block_msec); + } + PRINTF("Driver_Main EXIT!! canblock = %d, block_msec = %d \r\n", canBlock, block_msec); + Driver_DeInit(pCxt); + DRIVER_WAKE_USER(pCxt); + } +#if QOSAL_TASK_DESTRUCTION + } while (0); + + atheros_wifi_task_id = QOSAL_NULL_TASK_HANDLE; +#else + /* block on this event until a task wants to re-activate the driver thread */ + // qosal_task_suspend(NULL); + } while (1); +#endif +} + + +void Driver_WakeDriver(void *pCxt) +{ + A_EVENT_SET(&(GET_DRIVER_CXT(pCxt)->driverWakeEvent), 0x01); +} + +void Driver_WakeUser(void *pCxt) +{ + A_EVENT_SET(&(GET_DRIVER_CXT(pCxt)->userWakeEvent), 0x01); +} + +void qcadrv_assert_func(const char *func_name, int line) +{ + PRINTF("QCADriver ASSERT at %s:%d\r\n", func_name, line); + volatile int i = 1; + while (i) + ; +} diff --git a/platform/mcu/lpc54102/wifi_qca/common_src/driver/driver_netbuf.c b/platform/mcu/lpc54102/wifi_qca/common_src/driver/driver_netbuf.c new file mode 100644 index 0000000000..db9826547f --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/common_src/driver/driver_netbuf.c @@ -0,0 +1,117 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== +#include +#include +#include +#include +#include +#include + +void Driver_ReportReverseCredits(void *pReq); + +#if defined(DRIVER_CONFIG_IMPLEMENT_RX_FREE_MULTIPLE_QUEUE) +uint8_t GET_QUEUE_INDEX(A_NETBUF_QUEUE_T *q) +{ + uint8_t i; + + for (i = 0; i < 8; i++) + { + if (&GET_FREE_QUEUE(i) == q) + break; + } + + return i; +} +#endif + +#if defined(DRIVER_CONFIG_IMPLEMENT_RX_FREE_MULTIPLE_QUEUE) + +extern uint8_t reverse_credits_init; +uint8_t credits_test = 0; + +void a_rxbuf_enqueue(A_NETBUF_QUEUE_T *q, void *pReq) +{ + uint8_t epid; + uint32_t bufCtrlNdx; + + a_netbuf_enqueue(q, pReq); + + if (reverse_credits_init == 0) + return; + + epid = A_NETBUF_GET_ELEM(pReq, A_REQ_EPID); + if (epid == ENDPOINT_0) + return; + + // i = GET_QUEUE_INDEX(q); + bufCtrlNdx = GetQueueCtrlIndexByEPID(epid); + if (bufCtrlNdx < 8 && bufCtrlNdx != 7) + { + CREDIT_INC(bufCtrlNdx); + // Driver_ReportReverseCredits(pReq); + } + else + { + // printf("wrong\n"); + } +} + +void *a_rxbuf_dequeue(A_NETBUF_QUEUE_T *q) +{ + void *pReq; + // uint8_t i; + + pReq = a_netbuf_dequeue(q); + if (pReq == NULL) + { + return pReq; + } + + /* i = GET_QUEUE_INDEX(q); + + if ( i < 8) + CREDIT_DEC(i); + */ + return pReq; +} +#endif + +void *a_netbuf_peek_queue(A_NETBUF_QUEUE_T *q) +{ + return q->head; +} + +int32_t a_netbuf_queue_size(A_NETBUF_QUEUE_T *q) +{ + return q->count; +} + +int32_t a_netbuf_queue_empty(A_NETBUF_QUEUE_T *q) +{ + return ((q->count == 0) ? 1 : 0); +} + +/* EOF */ diff --git a/platform/mcu/lpc54102/wifi_qca/common_src/driver/driver_txrx.c b/platform/mcu/lpc54102/wifi_qca/common_src/driver/driver_txrx.c new file mode 100644 index 0000000000..70038c0a5b --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/common_src/driver/driver_txrx.c @@ -0,0 +1,312 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*****************************************************************************/ +/* Driver_RxComplete - For completed RX packet requests this function routes + * the request to a handler based on endpoint ID. Called when the Bus + * transfer operation has completed. + * void *pCxt - the driver context. + * void *pReq - the request object. + *****************************************************************************/ +void Driver_RxComplete(void *pCxt, void *pReq) +{ + uint32_t lookAheads[1]; + uint32_t NumLookAheads = 0; + + if (A_OK != Htc_ProcessRecvHeader(pCxt, pReq, lookAheads, &NumLookAheads)) + { + A_ASSERT(0); + } + + if (A_NETBUF_GET_ELEM(pReq, A_REQ_EPID) == ENDPOINT_0) + { + Htc_RxComplete(pCxt, pReq); + } + else + { + Api_RxComplete(pCxt, pReq); + } +} + +/*****************************************************************************/ +/* Driver_TxComplete - For completed TX packet requests this function routes + * the request to a handler based on endpoint ID. Called when the Bus + * transfer operation has completed. + * void *pCxt - the driver context. + * void *pReq - the request object. + *****************************************************************************/ +static void Driver_TxComplete(void *pCxt, void *pReq) +{ + Htc_ProcessTxComplete(pCxt, pReq); + +#if 0 + if(A_NETBUF_GET_ELEM(pReq, A_REQ_EPID) == ENDPOINT_0){ + /* this should never happen in practice as the driver + * does not SEND messages on the HTC endpoint */ + A_ASSERT(0); + //HTC_TxComplete(pCxt, pReq); + }else{ + Api_TxComplete(pCxt, pReq); + } +#else + Api_TxComplete(pCxt, pReq); +#endif +} + +/*****************************************************************************/ +/* Driver_PostProcessRequest - Utility to post process requests that have + * completed Hcd_Request(). + * void *pCxt - the driver context. + * void *pReq - the request object. + * A_STATUS reqStatus - the status of the transaction. + *****************************************************************************/ +static void Driver_PostProcessRequest(void *pCxt, void *pReq, A_STATUS reqStatus) +{ + A_DRIVER_CONTEXT *pDCxt; + + A_NETBUF_SET_ELEM(pReq, A_REQ_STATUS, reqStatus); + + if (A_NETBUF_GET_ELEM(pReq, A_REQ_CALLBACK) != NULL) + { + pDCxt = GET_DRIVER_COMMON(pCxt); + pDCxt->spi_hcd.pCurrentRequest = pReq; + + if (reqStatus != A_PENDING) + { + pDCxt->booleans |= SDHD_BOOL_DMA_COMPLETE; + } + } +} + +/*****************************************************************************/ +/* Driver_SubmitTxRequest - Called from a User thread to submit a new + * Tx packet to the driver. The function will append the request to the + * drivers txqueue and wake up the driver thread. + * void *pCxt - the driver context. + * void *pReq - the request object. + *****************************************************************************/ +A_STATUS +Driver_SubmitTxRequest(void *pCxt, void *pReq) +{ + A_STATUS status = A_ERROR; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + uint32_t transferLength, creditsRequired; + + do + { + A_NETBUF_SET_ELEM(pReq, A_REQ_CALLBACK, Driver_TxComplete); + /* reserve space for HTC header to allow for proper calculation + * of transmit length. The header will be populated when the + * request is transmitted. */ + if (A_NETBUF_PUSH(pReq, HTC_HDR_LENGTH) != A_OK) + { + break; + } + /* The length of the request is now complete so + * calculate and assign the number of credits required by this + * request. */ + transferLength = DEV_CALC_SEND_PADDED_LEN(pDCxt, A_NETBUF_LEN(pReq)); + + if (transferLength <= pDCxt->creditSize) + { + creditsRequired = 1; + } + else + { + /* figure out how many credits this message requires */ + creditsRequired = (uint32_t)(transferLength / pDCxt->creditSize); + + if (creditsRequired * pDCxt->creditSize < transferLength) + { + creditsRequired++; + } + } + + A_NETBUF_SET_ELEM(pReq, A_REQ_CREDITS, creditsRequired); + + TXQUEUE_ACCESS_ACQUIRE(pCxt); + { + A_NETBUF_ENQUEUE(&(pDCxt->txQueue), pReq); + status = A_OK; + } + TXQUEUE_ACCESS_RELEASE(pCxt); + + if (status == A_OK) + { + DRIVER_WAKE_DRIVER(pCxt); + } + } while (0); + + return status; +} + +/*****************************************************************************/ +/* Driver_TxComplete - For completed TX packet requests this function routes + * the request to a handler based on endpoint ID. Called when the Bus + * transfer operation has completed. + * void *pCxt - the driver context. + * void *pReq - the request object. + *****************************************************************************/ +static void Driver_Ep0TxComplete(void *pCxt, void *pReq) +{ + Htc_ProcessTxComplete(pCxt, pReq); +} + +A_STATUS +Driver_SubmitEp0TxRequest(void *pCxt, void *pReq) +{ + A_STATUS status = A_ERROR; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + uint32_t transferLength, creditsRequired; + + do + { + A_NETBUF_SET_ELEM(pReq, A_REQ_CALLBACK, Driver_Ep0TxComplete); + /* reserve space for HTC header to allow for proper calculation + * of transmit length. The header will be populated when the + * request is transmitted. */ + if (A_NETBUF_PUSH(pReq, HTC_HDR_LENGTH) != A_OK) + { + break; + } + /* The length of the request is now complete so + * calculate and assign the number of credits required by this + * request. */ + transferLength = DEV_CALC_SEND_PADDED_LEN(pDCxt, A_NETBUF_LEN(pReq)); + + if (transferLength <= pDCxt->creditSize) + { + creditsRequired = 1; + } + else + { + /* figure out how many credits this message requires */ + creditsRequired = (uint32_t)(transferLength / pDCxt->creditSize); + + if (creditsRequired * pDCxt->creditSize < transferLength) + { + creditsRequired++; + } + } + + A_NETBUF_SET_ELEM(pReq, A_REQ_CREDITS, creditsRequired); + + TXQUEUE_ACCESS_ACQUIRE(pCxt); + { + A_NETBUF_PREQUEUE(&(pDCxt->txQueue), pReq); + status = A_OK; + } + TXQUEUE_ACCESS_RELEASE(pCxt); + + if (status == A_OK) + { + DRIVER_WAKE_DRIVER(pCxt); + } + } while (0); + + return status; +} + +/*****************************************************************************/ +/* Driver_SendPacket - Entry point to send a packet from the device. Sets + * up request params address and other and calls HCD_Request to perform the + * work. If a callback is provided in the request then it will be used to + * complete the request. If a callback is not provided the lower layers + * must complete the request synchronously. + * void *pCxt - the driver context. + * void *pReq - the request object. + *****************************************************************************/ +A_STATUS Driver_SendPacket(void *pCxt, void *pReq) +{ + A_STATUS status = A_ERROR; + uint32_t address; + uint16_t transLength; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + + do + { + if (A_OK != (status = Htc_SendPacket(pCxt, pReq))) + { + Driver_PostProcessRequest(pCxt, pReq, status); + break; + } + /* calc the padding and mbox address */ + /* NOTE: for Transmit the request length may not equal the transfer length due to + * padding requirements. */ + transLength = DEV_CALC_RECV_PADDED_LEN(pDCxt, A_NETBUF_LEN(pReq)); + address = HW_GetMboxAddress(pCxt, HIF_ACTIVE_MBOX_INDEX, transLength); + address &= ATH_TRANS_ADDR_MASK; + A_NETBUF_SET_ELEM(pReq, A_REQ_ADDRESS, address); + A_NETBUF_SET_ELEM(pReq, A_REQ_TRANSFER_LEN, transLength); + /* init the packet read params/cmd incremental vs fixed address etc. */ + A_NETBUF_SET_ELEM(pReq, A_REQ_COMMAND, (ATH_TRANS_WRITE | ATH_TRANS_DMA)); + status = Hcd_Request(pCxt, pReq); + Driver_PostProcessRequest(pCxt, pReq, status); + } while (0); + + return status; +} + +/*****************************************************************************/ +/* Driver_RecvPacket - Entry point to receive a packet from the device. Sets + * up request params address and other and calls HCD_Request to perform the + * work. This path always provides a request callback for asynchronous + * completion. This is because DMA if available will always be used for + * packet requests. + * void *pCxt - the driver context. + * void *pReq - the request object. + *****************************************************************************/ +A_STATUS Driver_RecvPacket(void *pCxt, void *pReq) +{ + // uint16_t validLength, transLength, hdrLength; + + A_STATUS status; + uint32_t address; + + Htc_PrepareRecvPacket(pCxt, pReq); + + /* init the packet mailbox address - begin with mailbox end address and then subtract the request transfer length */ + address = HW_GetMboxAddress(pCxt, HIF_ACTIVE_MBOX_INDEX, A_NETBUF_LEN(pReq)); + address &= ATH_TRANS_ADDR_MASK; + A_NETBUF_SET_ELEM(pReq, A_REQ_ADDRESS, address); + /* init the packet read params/cmd incremental vs fixed address etc. */ + A_NETBUF_SET_ELEM(pReq, A_REQ_COMMAND, (ATH_TRANS_READ | ATH_TRANS_DMA)); + + status = Hcd_Request(pCxt, pReq); + Driver_PostProcessRequest(pCxt, pReq, status); + + return status; +} diff --git a/platform/mcu/lpc54102/wifi_qca/common_src/hcd/hcd_api.h b/platform/mcu/lpc54102/wifi_qca/common_src/hcd/hcd_api.h new file mode 100644 index 0000000000..5b2075b1fb --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/common_src/hcd/hcd_api.h @@ -0,0 +1,77 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +#ifndef _HCD_API_H_ +#define _HCD_API_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include + +A_STATUS +Hcd_Request(void *pCxt, void *pReq); +boolean Hcd_ReadCPUInterrupt(void *pCxt, uint8_t *cpuIntrCause); +void Hcd_ClearCPUInterrupt(void *pCxt); +A_STATUS +Hcd_UnmaskInterrupts(void *pCxt, uint16_t Mask); // IGX_UD_CHANGES +A_STATUS +Hcd_UnmaskInterrupts(void *pCxt, uint16_t Mask); +A_STATUS +Hcd_GetLookAhead(void *pCxt); +boolean Hcd_BusInterrupt(void *pCxt); +A_STATUS +Hcd_ReinitTarget(void *pCxt); +void Hcd_Deinitialize(void *pCxt); +A_STATUS +Hcd_Init(void *pCxt); +void Hcd_EnableCPUInterrupt(void *pCxt); +A_STATUS +Hcd_DoPioExternalAccess(void *pCxt, void *pReq); +void Hcd_MaskInterrupts(void *pCxt, uint16_t Mask); +A_STATUS +Hcd_ReinitTarget(void *pCxt); +A_STATUS +Hcd_UnmaskInterrupts(void *pCxt, uint16_t Mask); +A_STATUS +Bus_InOutDescriptorSet(void *pCxt, void *pReq); + +#if 0 +/* +* The below 3-functions are need to implement and +* HCD_SUSPEND_CB and HCD_RESUME_CB structures are not avialable with +* current driver source +*/ + +void Hcd_AckInterrupt(void *pCxt, uint16_t Mask); +void Hcd_RegisterSuspendHandler(HCD_SUSPEND_CB *suspendCallback, void *pSuspContext); +void Hcd_RegisterResumeHandler(HCD_RESUME_CB *resumeCallback, void *pSuspContext); +void +Hcd_RegisterInterruptHandler(HCD_INTR_CALLBACK_T *callback, void *pContext); +#endif //#if 0 + +#endif //_HCD_API_H_ diff --git a/platform/mcu/lpc54102/wifi_qca/common_src/hcd/spi_hcd.c b/platform/mcu/lpc54102/wifi_qca/common_src/hcd/spi_hcd.c new file mode 100644 index 0000000000..5501409cfd --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/common_src/hcd/spi_hcd.c @@ -0,0 +1,1486 @@ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== + +#include +#include +#include +#include +#include +#include +#include +#include +#include "spi_hcd_if.h" +#include +#include "hw20_mbox_host_reg.h" +#include +#include "atheros_wifi_api.h" + +#define CMD_ADDR_READ (1 << 15) +#define CMD_ADDRESS_INTERNAL (1 << 14) + +#define ADJUST_WRBUF_SPACE(p, b) \ + \ +{ \ + (p)->spi_hcd.WriteBufferSpace = (p)->spi_hcd.WriteBufferSpace - (b)-ATH_SPI_WRBUF_RSVD_BYTES; \ + \ +} + +/* macro to issue command/address phase */ +#define OUT_TOKEN_CMD_ADDR_DMA_WRITE(pdev, addr) \ + Bus_InOutToken((pdev), (uint32_t)A_CPU2BE16((addr)), ATH_TRANS_DS_16, NULL) + +#define OUT_TOKEN_CMD_ADDR_DMA_READ(pdev, addr) OUT_TOKEN_CMD_ADDR_DMA_WRITE(pdev, ((addr) | CMD_ADDR_READ)) + +#define OUT_TOKEN_CMD_ADDR_INTERNAL_READ(pdev, addr) OUT_TOKEN_CMD_ADDR_DMA_READ(pdev, ((addr) | CMD_ADDRESS_INTERNAL)) + +#define OUT_TOKEN_CMD_ADDR_INTERNAL_WRITE(pdev, addr) \ + OUT_TOKEN_CMD_ADDR_DMA_WRITE(pdev, ((addr) | CMD_ADDRESS_INTERNAL)) + +static A_STATUS Hcd_TransferData(void *pCxt, void *pReq); + +/*****************************************************************************/ +/* DoPioReadInternal - Used to write a device internal register. + * void *pCxt - the driver context. + * uint16_t Addr - address of the register. + * uint32_t value - value to write to the register. + *****************************************************************************/ +#if 0 +static A_STATUS +DoPioWriteInternal(void *pCxt, + uint16_t Addr, + uint32_t Value) +{ + A_STATUS status; + + Addr |= CMD_ADDRESS_INTERNAL; + + /* issue CMD/ADDR token */ + if(A_OK != (status = OUT_TOKEN_CMD_ADDR_INTERNAL_WRITE(pCxt,Addr))){ + return status; + } + /* despite the UINT32 there are only 2 bytes of data for internal + * register. These bytes must be set in Big Endian format for + * proper parsing by the chip. */ + Value = A_CPU2BE16(Value); + /* send out data */ + return Bus_InOutToken(pCxt, Value, ATH_TRANS_DS_16, NULL); +} +#else +static A_STATUS DoPioWriteInternal(void *pCxt, uint16_t Addr, uint32_t Value) +{ + uint32_t dataIn; + uint32_t dataOut; + + /* despite the UINT32 there are only 2 bytes of data for internal + * register. These bytes must be set in Big Endian format for + * proper parsing by the chip. */ + Addr = (Addr | CMD_ADDRESS_INTERNAL); + Addr = A_CPU2BE16(Addr); + Value = A_CPU2BE16(Value); + dataOut = Addr | ((Value & 0xFFFF) << 16); + return (CUSTOM_BUS_INOUT_TOKEN(pCxt, dataOut, 4, &dataIn)); +} +#endif + +/*****************************************************************************/ +/* DoPioReadInternal - Used to read a device internal register. + * void *pCxt - the driver context. + * uint16_t Addr - address of the register. + * uint32_t *pValue - pointer to the location to where the value should + * be stored. + *****************************************************************************/ +#if 0 +static A_STATUS +DoPioReadInternal(void *pCxt, + uint16_t Addr, + uint32_t *pValue) +{ + A_STATUS status; + + do { + Addr |= CMD_ADDRESS_INTERNAL; + + if(A_OK != (status = OUT_TOKEN_CMD_ADDR_INTERNAL_READ(pCxt, Addr))){ + break; + } + + status = Bus_InOutToken(pCxt, 0x00000000, ATH_TRANS_DS_16, pValue); + /* despite the UINT32 storage there are only 2 bytes of data from the + * internal register. These bytes arrive in Big Endian format so + * must be converted to CPU format for proper consumption. */ + *pValue = (uint16_t) A_BE2CPU16(*pValue); + } while (false); + + return status; +} +#else +static A_STATUS DoPioReadInternal(void *pCxt, uint16_t Addr, uint32_t *pValue) +{ + A_STATUS status; + uint32_t dataIn; + uint32_t dataOut; + + Addr = (Addr | CMD_ADDRESS_INTERNAL | CMD_ADDR_READ); + dataOut = A_CPU2BE16(Addr); + status = CUSTOM_BUS_INOUT_TOKEN(pCxt, dataOut, 4, &dataIn); + *pValue = dataIn >> 16; + *pValue = A_BE2CPU16(*pValue); + return status; +} + +#endif + +/*****************************************************************************/ +/* EnableDisableSPIIRQHwDetect - Used to enable/disable SPI interrupt detection + * Ultimately this function calls HW_EnableDisableSPIIRQ to enable/disable the IRQ. + * void *pCxt - the driver context. + * boolean Enable - if true then enable SPI Interrupt if false then + * disable SPI Interrupt. + *****************************************************************************/ +static void EnableDisableSPIIRQHwDetect(void *pCxt, boolean Enable) +{ + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + + if ((pDCxt->spi_hcd.SpiHWCapabilitiesFlags & HW_SPI_INT_EDGE_DETECT) && Enable) + { + /* the SPI interrupt is edge triggered and has requirements for a good edge + * when we enable interrupt detection we disable all interrupts on the module and + then re-enable them again to generate a good edge */ + + if (A_OK != DoPioWriteInternal(pCxt, ATH_SPI_INTR_ENABLE_REG, 0)) + { + A_ASSERT(0); + } + /* re-enable SPI interrupt detection at the host controller */ + HW_EnableDisableSPIIRQ(pCxt, true, false); + + /* re-enable interrupt sources, if there are pending interrupts, this should + * generate a nice clean edge */ + if (A_OK != DoPioWriteInternal(pCxt, ATH_SPI_INTR_ENABLE_REG, pDCxt->spi_hcd.SpiIntEnableShadow)) + { + A_ASSERT(0); + } + } + else + { + /* the SPI interrupt logic is level triggered (or we are simply disabling) so we can simply tell + * the hardware layer to enable/disable it */ + HW_EnableDisableSPIIRQ(pCxt, Enable, false); + } +} + +/*****************************************************************************/ +/* MaskSPIInterrupts - Used to mask specific device interrupts + * function will write the SPI Interrupt Enable register with the resulting + * mask value. + * void *pCxt - the driver context. + * uint16_t Mask - bit mask indicating which interrupts should be + * masked. + *****************************************************************************/ +static A_STATUS MaskSPIInterrupts(void *pCxt, uint16_t Mask) +{ + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + pDCxt->spi_hcd.SpiIntEnableShadow &= ~Mask; + + if (Mask & pDCxt->spi_hcd.SpiIntEnableShadow) + { + Hcd_UnmaskInterrupts(pCxt, Mask); + } + + return DoPioWriteInternal(pCxt, ATH_SPI_INTR_ENABLE_REG, (uint32_t)pDCxt->spi_hcd.SpiIntEnableShadow); +} + +/*****************************************************************************/ +/*****************************************************************************/ +/* HandleExternalReadDone - Utlity to complete an External IO read operation. + * void *pCxt - the driver context. + * void *pReq - the transfer request object. + *****************************************************************************/ +static A_STATUS HandleExternalReadDone(void *pCxt, void *pReq) +{ + A_STATUS status; + /* send out cmd/addr token */ + if (A_OK != (status = OUT_TOKEN_CMD_ADDR_INTERNAL_READ(pCxt, ATH_SPI_HOST_CTRL_RD_PORT_REG))) + { + return status; + } + /* do the data frames to get the data */ + status = Hcd_TransferData(pCxt, pReq); + /* this should never return pending, external I/O accesses do not invoke the DMA hardware */ + A_ASSERT(status != A_PENDING); + + return status; +} + +#if 0 +/*****************************************************************************/ +/* ReadSomeInternalReg - Utility function to read some device registers as + * a Workaround for some chipsets. + * void *pCxt - the driver context. + *****************************************************************************/ +static void +ReadSomeInternalReg(void *pCxt) +{ + uint32_t reg; + + do{ + if(A_OK != DoPioReadInternal(pCxt, ATH_SPI_WRBUF_SPC_AVA_REG, ®)){ + break; + } + + if(A_OK != DoPioReadInternal(pCxt, ATH_SPI_RDBUF_BYTE_AVA_REG, ®)){ + break; + } + + if(A_OK != DoPioReadInternal(pCxt, ATH_SPI_CONFIG_REG, ®)){ + break; + } + }while(0); +} +#endif +A_STATUS +Hcd_DoPioInternalAccess(void *pCxt, uint16_t addr, uint32_t *pValue, boolean isRead) +{ + A_STATUS status; + + if (isRead == true) + { + status = DoPioReadInternal(pCxt, addr, pValue); + } + else + { + status = DoPioWriteInternal(pCxt, addr, *pValue); + } + + return status; +} + +/*****************************************************************************/ +/* Hcd_DoPioExternalAccess - accessing external registers requires the use + * of the SPI slave controller's internal proxy state machine + * in the event that the chip is asleep. The internal proxy performs the operation + * and will signal us via an interrupt or polling operation + * void *pCxt - the driver context. + * void *pReq - the transfer request object. + *****************************************************************************/ +A_STATUS +Hcd_DoPioExternalAccess(void *pCxt, void *pReq) +{ + A_STATUS status; + uint32_t regValue; + int retry; + + do + { + /* set incrementing or fixed addressing */ + regValue = (uint32_t)(ATH_IS_TRANS_EXT_ADDR_FIXED(pReq) ? ATH_SPI_HOST_CTRL_NO_ADDR_INC : 0); + /* set the length */ + regValue |= A_NETBUF_LEN(pReq); + /* write control reg */ + if (A_OK != (status = DoPioWriteInternal(pCxt, ATH_SPI_HOST_CTRL_BYTE_SIZE_REG, regValue))) + { + break; + } + + if (ATH_IS_TRANS_WRITE(pReq)) + { + /* write to the data port */ + /* send out cmd/addr token */ + if (A_OK != (status = OUT_TOKEN_CMD_ADDR_INTERNAL_WRITE(pCxt, ATH_SPI_HOST_CTRL_WR_PORT_REG))) + { + break; + } + /* do the data frames */ + status = Hcd_TransferData(pCxt, pReq); + /* these frames should go out without using interrupts */ + A_ASSERT(status != A_PENDING); + if (A_OK != status) + { + break; + } + } + + /* enable, set direction and set address range to do the operation on */ + regValue = ATH_SPI_HOST_CTRL_CONFIG_ENABLE; + regValue |= ATH_IS_TRANS_READ(pReq) ? 0 : ATH_SPI_HOST_CTRL_CONFIG_DIR_WRITE; + regValue |= A_NETBUF_GET_ELEM(pReq, A_REQ_ADDRESS); // ATH_GET_IO_ADDRESS(pReq); + /* write config to start the operation */ + if (A_OK != (status = DoPioWriteInternal(pCxt, ATH_SPI_HOST_CTRL_CONFIG_REG, regValue))) + { + break; + } + /* poll the host_access_done bit in SPI_STATUS register, if the access takes longer + * than the retry count, the core was probably asleep, we need to wait for an interrupt + * for the operation to complete */ + // retry = EXTERNAL_ACCESS_DONE_RETRY_COUNT; + retry = 200; + + while (retry) + { + if (A_OK != (status = DoPioReadInternal(pCxt, ATH_SPI_STATUS_REG, ®Value))) + { + break; + } + + if (regValue & ATH_SPI_STATUS_HOST_ACCESS_DONE) + { + break; + } + + retry--; + if (retry) + { + HW_USEC_DELAY(pCxt, 1000); + } + } + + if (0 == retry) + { + status = A_ERROR; + break; + } + + /* if we get here the chip was awake and the access finished within the polling interval */ + + if (ATH_IS_TRANS_READ(pReq)) + { + /* for reads, empty the read port */ + status = HandleExternalReadDone(pCxt, pReq); + } + + /* clear the interrupt cause, each host access operation will set the RD or WR + * cause bit */ + if (A_OK != (status = DoPioWriteInternal(pCxt, ATH_SPI_INTR_CAUSE_REG, + ATH_SPI_INTR_HOST_CTRL_RD_DONE | ATH_SPI_INTR_HOST_CTRL_WR_DONE))) + { + break; + } + } while (false); + + return status; +} + +/*****************************************************************************/ +/* ResetWriteBufferWaterMark - Used to reset the write buffer watermark on + * the device so as to prevent any further watermark interrupts from the + * device. + * void *pCxt - the driver context. + *****************************************************************************/ +static A_STATUS ResetWriteBufferWaterMark(void *pCxt) +{ + A_STATUS status; + + if (A_OK != (status = DoPioWriteInternal(pCxt, ATH_SPI_WRBUF_WATERMARK_REG, 0))) + { + return status; + } + /* the watermark interrupt status constantly latches, so after we + * set to zero, we need to clear the cause register */ + return DoPioWriteInternal(pCxt, ATH_SPI_INTR_CAUSE_REG, ATH_SPI_INTR_WRBUF_BELOW_WMARK); +} + +/*****************************************************************************/ +/* ConfigureByteSwap - Configures the byte swapping if any to be applied + * to any subsequent SPI transactions. This will write the SPI Config + * register as necessary to configure the device for proper byte swapping. + * void *pCxt - the driver context. + * uint8_t TransferType - indicates the unit size for SPI transfer. + *****************************************************************************/ +static A_STATUS ConfigureByteSwap(void *pCxt, uint8_t TransferType) +{ + uint16_t swapSettings; + + swapSettings = GET_DRIVER_COMMON(pCxt)->spi_hcd.SpiConfigShadow; + + /* based on the transfer type, figure out what mode settings we need */ + + if (TransferType == ATH_TRANS_DS_32) + { + /* make sure swap is turned on */ + swapSettings |= ATH_SPI_CONFIG_BYTE_SWAP; + /* turn off 16 bit mode - which actually turns ON 32 bit swapping */ + swapSettings &= ~ATH_SPI_CONFIG_SWAP_16BIT; + } + else if (TransferType == ATH_TRANS_DS_16) + { + /* make sure swap is turned on */ + swapSettings |= ATH_SPI_CONFIG_BYTE_SWAP; + /* turn on 16 bit swapping mode */ + swapSettings |= ATH_SPI_CONFIG_SWAP_16BIT; + } + else if (TransferType == ATH_TRANS_DS_8) + { + /* disable byte swapping entirely */ + swapSettings &= ~ATH_SPI_CONFIG_BYTE_SWAP; + swapSettings &= ~ATH_SPI_CONFIG_SWAP_16BIT; + } + else + { + A_ASSERT(0); + } + + /* did any bits change? */ + if (swapSettings ^ GET_DRIVER_COMMON(pCxt)->spi_hcd.SpiConfigShadow) + { + /* save new value */ + GET_DRIVER_COMMON(pCxt)->spi_hcd.SpiConfigShadow = swapSettings; + /* write it out */ + return DoPioWriteInternal(pCxt, ATH_SPI_CONFIG_REG, swapSettings); + } + + return A_OK; +} + +/*****************************************************************************/ +/* DoDMAOp - Utility function to initiate a DMA or other SPI transaction. + * Starts by writing the SPI DMA Size Register as required by the device. + * void *pCxt - the driver context. + * void *pReq - The request packet object. + *****************************************************************************/ +static A_STATUS DoDMAOp(void *pCxt, void *pReq) +{ + A_STATUS status; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + uint16_t mask = (uint16_t)(pDCxt->spi_hcd.SpiIntEnableShadow & ATH_SPI_INTR_PKT_AVAIL); + /* WAR during a data transfer/mbox operation it is necessary + * to mask the interrupt from the wifi device as that has been shown + * to corrupt SPI communication. */ + if (mask) + { + MaskSPIInterrupts(pCxt, mask); + } + + do + { + /* setup DMA size register */ + if (A_OK != + (status = DoPioWriteInternal(pCxt, ATH_SPI_DMA_SIZE_REG, A_NETBUF_GET_ELEM(pReq, A_REQ_TRANSFER_LEN)))) + { + break; + } + + if (ATH_IS_TRANS_READ(pReq)) + { + /* send out the read DMA token */ + status = OUT_TOKEN_CMD_ADDR_DMA_READ(pCxt, A_NETBUF_GET_ELEM(pReq, A_REQ_ADDRESS)); + } + else + { + /* send out the write DMA token */ + status = OUT_TOKEN_CMD_ADDR_DMA_WRITE(pCxt, A_NETBUF_GET_ELEM(pReq, A_REQ_ADDRESS)); + } + + if (A_OK != status) + { + break; + } + /* call transfer state machine to handle data frames */ + status = Hcd_TransferData(pCxt, pReq); + + if (A_PENDING == status) + { + /* transfer routine requires DMA to start */ + pDCxt->booleans |= SDHD_BOOL_DMA_IN_PROG; + /* we are transfering control to the SPI hardware's DMA engine, while it is + * running we cannot process SPI interrupts. SPI interrupt processing requires + * CMD/Data frames on the SPI bus and requires ownership of the SPI hardware. + * this function is called with the driver lock held to hold off the SPI interrupt + * handler HcdSpiInterrupt() , the handler should wake up and check for a pending + * DMA hardware transfer and exit. On completion of the DMA transfer, the SPI + * interrupt detection will be enabled */ + /* disable SPI interrupt detection at the hardware layer */ + EnableDisableSPIIRQHwDetect(pCxt, false); + // HW_StartDMA(pCxt); + } + + } while (false); + + if (mask) + { + if (status == A_PENDING) + { + pDCxt->spi_hcd.irqMask = mask; + } + else + { + Hcd_UnmaskInterrupts(pCxt, mask); + } + } + + return status; +} + +/*****************************************************************************/ +/* Hcd_ProgramWriteBufferWaterMark - Programs the device's write buffer + * watermark level to trigger an interrupt when device FiFo space becomes + * available. + * void *pCxt - the driver context. + * uint32_t length - the desired byte length to program watermark. + *****************************************************************************/ +A_STATUS +Hcd_ProgramWriteBufferWaterMark(void *pCxt, uint32_t length) +{ + uint32_t waterMarkLevel, regValue; + A_STATUS status = A_OK; + boolean waitInterrupt = true; + uint32_t param; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + + do + { + /* calculate the water mark based on the number of bytes currently in the buffer + * and the number of bytes we need to fullfill the request, this is the level + * the buffer needs to drop below to trigger an interrupt */ + waterMarkLevel = pDCxt->spi_hcd.MaxWriteBufferSpace - length; + + if (waterMarkLevel < pDCxt->spi_hcd.MaxWriteBufferSpace) + { + /* also... watermark level cannot be zero */ + waterMarkLevel = waterMarkLevel ? waterMarkLevel : 1; + } + else + { + A_ASSERT(0); +#if DRIVER_CONFIG_DISABLE_ASSERT + waterMarkLevel = 1; +#endif + } + + /* update watermark trigger */ + if (A_OK != (status = DoPioWriteInternal(pCxt, ATH_SPI_WRBUF_WATERMARK_REG, waterMarkLevel))) + { + break; + } + /* re-sample SPI_STATUS and space available, the operation to update the watermark could + * miss the window when the core is still awake, if this happens the + * watermark level will be reached but it will not generate an interrupt + * as INTR_CAUSE is only updated while the core clock is active, so any updates to + * WR_BUF_WATERMARK_REG are only valid while the core is awake */ + + if (A_OK != (status = DoPioReadInternal(pCxt, ATH_SPI_STATUS_REG, ®Value))) + { + break; + } + + if ((regValue & ATH_SPI_STATUS_RTC_STATE_MASK) == ATH_SPI_STATUS_RTC_STATE_SLEEP) + { + /* it can take up to 60 microseconds for the sleep state to change */ + HW_USEC_DELAY(pCxt, 60); + + /* re-read status and re-check the sleep state */ + if (A_OK != (status = DoPioReadInternal(pCxt, ATH_SPI_STATUS_REG, ®Value))) + { + break; + } + + if ((regValue & ATH_SPI_STATUS_RTC_STATE_MASK) != ATH_SPI_STATUS_RTC_STATE_SLEEP) + { + /* core is awake or is just about to wakeup. We can wait for an interrupt */ + break; + } + + /* re-read space available, the core went to sleep and we may never get an interrupt */ + if (A_OK != (status = DoPioReadInternal(pCxt, ATH_SPI_WRBUF_SPC_AVA_REG, ¶m))) + { + break; + } + + pDCxt->spi_hcd.WriteBufferSpace = param; + /* no need to wait, we have buffer space to send this packet */ + waitInterrupt = false; + + /* the core drained the write buffer after we sampled + * SPC_AVAIL, we now have room and the core went to sleep. + * reset watermark since we won't be using it */ + if (A_OK != (status = ResetWriteBufferWaterMark(pCxt))) + { + break; + } + /* fall through and return SUCCESS */ + } + + } while (false); + + if (A_OK == status && waitInterrupt) + { + /* no space, need to wait for interrupt */ + pDCxt->booleans |= SDHD_BOOL_DMA_WRITE_WAIT_FOR_BUFFER; + /* wait for the buffer to empty below the water mark */ + Hcd_UnmaskInterrupts(pCxt, ATH_SPI_INTR_WRBUF_BELOW_WMARK); + status = A_PENDING; + } + + return status; +} + +/*****************************************************************************/ +/* Hcd_RefreshWriteBufferSpace - Reads the device Write buffer space available + * register to learn the available byte length that the device can + * currently accept for transmit operations. + * void *pCxt - the driver context. + *****************************************************************************/ +void Hcd_RefreshWriteBufferSpace(void *pCxt) +{ + uint32_t param; + if (A_OK == DoPioReadInternal(pCxt, ATH_SPI_WRBUF_SPC_AVA_REG, ¶m)) + { + GET_DRIVER_COMMON(pCxt)->spi_hcd.WriteBufferSpace = param; + } +} + +#if 1 // Common_HCD API's +/*****************************************************************************/ +/* Hcd_Request - Used to process a bus request. This could be a Tx or Rx + * request. + * void *pCxt - the driver context. + * void *pReq - the packet object + *****************************************************************************/ +A_STATUS +Hcd_Request(void *pCxt, void *pReq) +{ + A_STATUS status = A_OK; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + uint32_t transLength = 0; + + do + { + if (pDCxt->booleans & SDHD_BOOL_FATAL_ERROR) + { + status = A_HARDWARE; + break; + } + + if (pDCxt->booleans & SDHD_BOOL_SHUTDOWN) + { + status = A_ECANCELED; + break; + } + /* check if we need to change byte swap logic + * TODO : normally DMADataWidth does not change, however for testing + * purposes we allow the width to change dynamically through a config request */ + if (A_OK != (status = ConfigureByteSwap(pCxt, pDCxt->spi_hcd.DMADataWidth))) + { + break; + } + + if (ATH_IS_TRANS_READ(pReq)) + { + status = DoDMAOp(pCxt, pReq); + } + else + { + transLength = A_NETBUF_GET_ELEM(pReq, A_REQ_TRANSFER_LEN); + + /* for writes we keep track of the write buffer space */ + ADJUST_WRBUF_SPACE(pDCxt, transLength); + /* fire off the write operation */ + status = DoDMAOp(pCxt, pReq); + } + } while (false); + + return status; +} + +boolean Hcd_ReadCPUInterrupt(void *pCxt, uint8_t *cpuIntrCause) +{ + A_NETBUF_DECLARE req; + void *pReq = (void *)&req; + uint8_t data; + boolean ret = 1; + + A_NETBUF_CONFIGURE(pReq, &data, 0, sizeof(uint8_t), sizeof(uint8_t)); + + do + { + ATH_SET_PIO_EXTERNAL_READ_OPERATION(pReq, CPU_INT_STATUS_ADDRESS, true, sizeof(uint8_t)); + + if (A_OK != Hcd_DoPioExternalAccess(pCxt, pReq)) + { + ret = 0; + break; + } + *cpuIntrCause = data; + } while (0); + + return ret; +} + +void Hcd_ClearCPUInterrupt(void *pCxt) +{ + A_NETBUF_DECLARE req; + void *pReq = (void *)&req; + uint8_t data; + + A_NETBUF_CONFIGURE(pReq, &data, 0, sizeof(uint8_t), sizeof(uint8_t)); + + do + { + data = 0xff; + + ATH_SET_PIO_EXTERNAL_WRITE_OPERATION(pReq, CPU_INT_STATUS_ADDRESS, true, sizeof(uint8_t)); + + if (A_OK != Hcd_DoPioExternalAccess(pCxt, pReq)) + { + break; + } + } while (0); +} + +/* Hcd_UnmaskInterrupts - Used to un-mask specific device interrupts + * function will write the SPI Interrupt Enable register with the resulting + * mask value. + * void *pCxt - the driver context. + * uint16_t Mask - bit mask indicating which interrupts should be + * unmasked. + *****************************************************************************/ +A_STATUS +Hcd_UnmaskInterrupts(void *pCxt, uint16_t Mask) +{ + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + pDCxt->spi_hcd.SpiIntEnableShadow |= Mask; + + if ((Mask & pDCxt->spi_hcd.SpiIntEnableShadow) == 0) + { + MaskSPIInterrupts(pCxt, Mask); + } + + return DoPioWriteInternal(pCxt, ATH_SPI_INTR_ENABLE_REG, (uint32_t)pDCxt->spi_hcd.SpiIntEnableShadow); +} + +void Hcd_EnableCPUInterrupt(void *pCxt) +{ + A_NETBUF_DECLARE req; + void *pReq = (void *)&req; + uint8_t data; + + A_NETBUF_CONFIGURE(pReq, &data, 0, sizeof(uint8_t), sizeof(uint8_t)); + + do + { + data = 0xff; + + ATH_SET_PIO_EXTERNAL_WRITE_OPERATION(pReq, CPU_INT_STATUS_ENABLE_ADDRESS, true, sizeof(uint8_t)); + + if (A_OK != Hcd_DoPioExternalAccess(pCxt, pReq)) + { + break; + } + } while (0); +} + +/*****************************************************************************/ +/* HcdSpiInterrupt - Used to process an Interrupt from the device. It reads + * the SPI_INTR_CAUSE register to learn the reason(s) for the interrupt. + * Error causes are handled inside this function and other reasons are + * stored and used to notify other driver layers. + * void *pCxt - the driver context. + *****************************************************************************/ +boolean Hcd_BusInterrupt(void *pCxt) +{ + A_STATUS status; + boolean notifyFunctionIRQs = false; + uint32_t interrupts, entry_interrupts, entry_mask; + uint32_t hostIrqs; + uint32_t param; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + /* check for pending DMA HW transfers */ + if (pDCxt->booleans & SDHD_BOOL_DMA_IN_PROG) + { + /* The DMA engine owns the hardware. We may not have been able to stop this task/thread + * from running, so we need to abort processing interrupts immediately. + * The SPI interrupts would have been disabled at this point so we can pick up the pending + * interrupts later when the DMA completion routine turns interrupts back on */ + /* exit immediately, we do not want to turn the interrupts back on */ + return true; + } + + do + { + /* read the Interrupt Cause register to determine the reason(s) for the interrupt */ + if (A_OK != (status = DoPioReadInternal(pCxt, ATH_SPI_INTR_CAUSE_REG, &interrupts))) + { + break; + } + + /* save first interrupt flags and mask */ + entry_interrupts = interrupts; + entry_mask = pDCxt->spi_hcd.SpiIntEnableShadow; + + interrupts &= pDCxt->spi_hcd.SpiIntEnableShadow; + /* get the HCD-owned IRQs */ + hostIrqs = interrupts & (ATH_SPI_HCD_IRQ_SOURCES | ATH_SPI_INTR_HOST_CTRL_ACCESS_DONE); + + /* before processing HCD-owned IRQ sources we need to Ack them, some processing + * may cause additional bus requests which can generate more interrupts , we want to + * avoid clearing an interrupt that might be valid */ + + if (hostIrqs) + { + /* ack interrupts that are HCD owned */ + if (A_OK != (status = DoPioWriteInternal(pCxt, ATH_SPI_INTR_CAUSE_REG, hostIrqs))) + { + break; + } + } + + /* process errors */ + if (interrupts & ATH_SPI_HCD_ERROR_IRQS) + { + /* if an error has occurred the device will need to be reset before + * any new communication can be attempted. There is not graceful + * recovery from one of these errors. */ + if (interrupts & ATH_SPI_INTR_ADDRESS_ERROR) + { + // REL_PRINT(SDDBG_ERROR, ("ATH SPI - ADDRESS ERROR \n")); + } + + if (interrupts & ATH_SPI_INTR_WRBUF_ERROR) + { + // REL_PRINT(SDDBG_ERROR, ("ATH SPI - WRBUF ERROR \n")); + } + + if (interrupts & ATH_SPI_INTR_RDBUF_ERROR) + { + // REL_PRINT(SDDBG_ERROR, ("ATH SPI - RDBUF ERROR \n")); + } + /* ack error interrupts */ + DoPioWriteInternal(pCxt, ATH_SPI_INTR_CAUSE_REG, interrupts & ATH_SPI_HCD_ERROR_IRQS); + + interrupts &= ~ATH_SPI_HCD_ERROR_IRQS; + pDCxt->booleans |= SDHD_BOOL_FATAL_ERROR; + /* mask all interrupts */ + DoPioWriteInternal(pCxt, ATH_SPI_INTR_ENABLE_REG, 0); + break; + } + + if (interrupts & ATH_SPI_INTR_HOST_CTRL_ACCESS_DONE) + { + /* this should not happen */ + interrupts &= ~ATH_SPI_INTR_HOST_CTRL_ACCESS_DONE; + + /* mask host access interrupts */ + MaskSPIInterrupts(pCxt, (ATH_SPI_INTR_HOST_CTRL_RD_DONE | ATH_SPI_INTR_HOST_CTRL_WR_DONE)); + } + + if (interrupts & ATH_SPI_INTR_WRBUF_BELOW_WMARK) + { + interrupts &= ~ATH_SPI_INTR_WRBUF_BELOW_WMARK; + /* disable interrupt */ + MaskSPIInterrupts(pCxt, ATH_SPI_INTR_WRBUF_BELOW_WMARK); + /* check to see if we need to start any pending DMA waiting on more buffer space */ + if (pDCxt->booleans & SDHD_BOOL_DMA_WRITE_WAIT_FOR_BUFFER) + { + /* re-cache the buffer space available register */ + if (A_OK != (status = DoPioReadInternal(pCxt, ATH_SPI_WRBUF_SPC_AVA_REG, ¶m))) + { + break; + } + + pDCxt->spi_hcd.WriteBufferSpace = param; + pDCxt->booleans &= ~SDHD_BOOL_DMA_WRITE_WAIT_FOR_BUFFER; + /* reset water mark */ + if (A_OK != (status = ResetWriteBufferWaterMark(pCxt))) + { + break; + } + } + } + /* check to see if any other sources remain, these belong to the function driver */ + + if (interrupts & ATH_SPI_INTR_PKT_AVAIL) + { + /* If there are pending interrupts of interest to the function driver + * we disable all function-driver IRQ sources while the function driver processes + * the interrupt event. This allows the host driver to continue processing + * host access done and write buffer water mark interrupts. + * + * The function driver will re-enable sources when it is done */ + MaskSPIInterrupts(pCxt, ATH_SPI_INTR_PKT_AVAIL); + + /* if flood is detected, postpone driver task */ + if ((entry_interrupts & entry_mask) == 0x1) + { + uint32_t tmp = 0; + status = Hcd_DoPioInternalAccess(pCxt, ATH_SPI_RDBUF_BYTE_AVA_REG, &tmp, true); + assert(A_OK == status); + if (tmp == 0) + { + A_MDELAY(MSEC_TO_TICK(5)); + } + } + + notifyFunctionIRQs = true; + } + + /* process the CPU interrupt */ + if (interrupts & ATH_SPI_INTR_LOCAL_CPU_INTR) + { + MaskSPIInterrupts(pCxt, ATH_SPI_INTR_CPU_INTR | ATH_SPI_INTR_LOCAL_CPU_INTR); + pDCxt->spi_hcd.CpuInterrupt = 1; + } + } while (0); + + if ((pDCxt->booleans & SDHD_BOOL_DMA_IN_PROG) == 0) + { + /* re-enable SPI interrupt detection at the hardware layer, note we always enable the + * SPI interrupt so that the HCD can get host-access-done interrupts. + * Note also that we do not enable interrupts if a DMA transfer is in progress */ + EnableDisableSPIIRQHwDetect(pCxt, true); + } + + if (notifyFunctionIRQs) + { + pDCxt->spi_hcd.PendingIrqAcks = 1 << 1; + } + + if (A_OK != status) + { + A_ASSERT(0); +#if DRIVER_CONFIG_DISABLE_ASSERT + return false; +#endif + } + + return true; +} + +/*****************************************************************************/ +/* Hcd_ReinitTarget - Used to re-initialize the device. If the HCD layer is + * already up but the device has been shutdown and needs to be re-started + * this function can be used to bring the chip out of reset and set the + * write buffer watermark. + * void *pCxt - the driver context. + *****************************************************************************/ +A_STATUS +Hcd_ReinitTarget(void *pCxt) +{ + A_STATUS status; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + + do + { + if (A_OK != (status = DoPioWriteInternal(pCxt, ATH_SPI_CONFIG_REG, pDCxt->spi_hcd.SpiConfigShadow))) + { + break; + } + + if (A_OK != (status = ResetWriteBufferWaterMark(pCxt))) + { + break; + } + + Hcd_UnmaskInterrupts(pCxt, ATH_SPI_HCD_ERROR_IRQS); + /* Enable the CPU interrupt so that the first interrupt + * is not lost. */ + Hcd_UnmaskInterrupts(pCxt, ATH_SPI_INTR_LOCAL_CPU_INTR); + } while (0); + + return status; +} + +/*****************************************************************************/ +/* Hcd_Deinitialize - Used to de-initialize the HCD layer. Conditionally + * write the SPI config register to reset the device. + * void *pCxt - the driver context. + *****************************************************************************/ +void Hcd_Deinitialize(void *pCxt) +{ + if (GET_DRIVER_COMMON(pCxt)->spi_hcd.MiscFlags & MISC_FLAG_RESET_SPI_IF_SHUTDOWN) + { + /* reset spi */ + DoPioWriteInternal(pCxt, ATH_SPI_CONFIG_REG, ATH_SPI_CONFIG_RESET); + } +} + +/*****************************************************************************/ +/* Hcd_GetLookAhead - Interacts with device over SPI to acquire lookahead + * structure. This structure provides details of a rx packet. + * void *pCxt - the driver context. + *****************************************************************************/ +A_STATUS +Hcd_GetLookAhead(void *pCxt) +{ + A_STATUS status; + uint16_t lookAhead1, lookAhead2; + uint32_t bytesAvail; + uint32_t assembledLookAhead; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + + do + { + /* get the bytes available in the SPI buffer */ + if (A_OK != (status = DoPioReadInternal(pCxt, ATH_SPI_RDBUF_BYTE_AVA_REG, &bytesAvail))) + { + break; + } + + pDCxt->spi_hcd.ReadBufferSpace = bytesAvail; + /* is there a header's worth ?*/ + if (bytesAvail < 4) + { + /* not enough bytes for the look-ahead */ + break; + } + + /* peak into the SPI read buffer using the look aheads since we + * established that there is at least a look-ahead number of bytes */ + if (A_OK != (status = DoPioReadInternal(pCxt, ATH_SPI_RDBUF_LOOKAHEAD1_REG, &assembledLookAhead))) + { + break; + } + + lookAhead1 = (uint16_t)assembledLookAhead; + + if (A_OK != (status = DoPioReadInternal(pCxt, ATH_SPI_RDBUF_LOOKAHEAD2_REG, &assembledLookAhead))) + { + break; + } + + lookAhead2 = (uint16_t)assembledLookAhead; + /* the lookaheads were already converted to native Endian by DoPioReadInternal + * however for the assembledLookAhead code to work properly for both + * big E and little E it must be converted again for little E. + */ + lookAhead1 = A_BE2CPU16(lookAhead1); + lookAhead2 = A_BE2CPU16(lookAhead2); + /* assemble look-ahead , first we need to swap bytes */ + ((uint8_t *)&assembledLookAhead)[0] = ((uint8_t *)&lookAhead1)[0]; + ((uint8_t *)&assembledLookAhead)[1] = ((uint8_t *)&lookAhead1)[1]; + ((uint8_t *)&assembledLookAhead)[2] = ((uint8_t *)&lookAhead2)[0]; + ((uint8_t *)&assembledLookAhead)[3] = ((uint8_t *)&lookAhead2)[1]; + + A_ASSERT(assembledLookAhead != 0); + pDCxt->lookAhead = assembledLookAhead; + } while (0); + + return status; +} + +/* Hcd_Init - Used to initialize the Host Controller Driver (HCD) layer. Uses + * SPI API to write the SPI config register which will bring the device + * out of reset. reads the WRITE buffer space register to learn the default + * size for this fifo. + * void *pCxt - the driver context. + *****************************************************************************/ +A_STATUS +Hcd_Init(void *pCxt) +{ + A_STATUS status; + uint32_t startUpClock; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + + do + { + // if (0 == (pDCxt->spi_hcd.SpiHWCapabilitiesFlags & (HW_SPI_FRAME_WIDTH_8 | HW_SPI_FRAME_WIDTH_16))) { + // /* We minimally require 8 and 16 bit frame widths + // * 16-bits - Command/Addr frames + // * 8-bits - data frames including early termination */ + // status = A_ERROR; + // A_ASSERT(0); + //#if DRIVER_CONFIG_DISABLE_ASSERT + // break; + //#endif + // } + + /* the SPI module has byte swapping capability for DMA requests and we will be turning it on + * set the DMA buffer copy mode to not swap */ + pDCxt->booleans &= ~SDHD_BOOL_HOST_DMA_COPY_MODE; + /* for host access data frames, byte swaping is required */ + pDCxt->booleans |= SDHD_BOOL_HOST_ACCESS_COPY_MODE; + + if (pDCxt->spi_hcd.SpiHWCapabilitiesFlags & HW_SPI_FRAME_WIDTH_32) + { + pDCxt->spi_hcd.HostAccessDataWidth = ATH_TRANS_DS_32; + pDCxt->spi_hcd.DMADataWidth = ATH_TRANS_DS_32; + } + else if (pDCxt->spi_hcd.SpiHWCapabilitiesFlags & HW_SPI_FRAME_WIDTH_8) + { + pDCxt->spi_hcd.HostAccessDataWidth = ATH_TRANS_DS_8; + pDCxt->spi_hcd.DMADataWidth = ATH_TRANS_DS_8; + pDCxt->booleans &= ~SDHD_BOOL_HOST_ACCESS_COPY_MODE; + } + else + { + pDCxt->spi_hcd.HostAccessDataWidth = ATH_TRANS_DS_16; + pDCxt->spi_hcd.DMADataWidth = ATH_TRANS_DS_16; + } + pDCxt->spi_hcd.SpiConfigShadow = 0; + + startUpClock = AR4XXX_NORMAL_CLOCK_RATE; + + if (startUpClock > pDCxt->spi_hcd.OperationalClock) + { + /* the hardware layer wants a clock rate that is less than the normal rate */ + startUpClock = pDCxt->spi_hcd.OperationalClock; + } + + if (pDCxt->spi_hcd.OperationalClock > AR4XXX_NORMAL_CLOCK_RATE) + { + /* when operating above the normal clock rate, we need to enable some + * logic to improve timing margins. + * *** NOTE : setting the config register must be done at our startup clock rate. + * We can switch to the higher clock rate once the SPI config register is written + * */ + pDCxt->spi_hcd.SpiConfigShadow |= (0x1 << ATH_SPI_CONFIG_MISO_MUXSEL_MASK_SHIFT); + } + + /* set our startup clock mode, the config register must be written with the startup clock + * rate */ + HW_SET_CLOCK(pCxt, &startUpClock); + + /* start off with the I/O enable bit and byte swapping turned off */ + pDCxt->spi_hcd.SpiConfigShadow |= ATH_SPI_CONFIG_IO_ENABLE; + + if (ATH_TRANS_DS_32 == pDCxt->spi_hcd.DMADataWidth) + { + /* enable byte swapping logic, default is 32 bit mode */ + pDCxt->spi_hcd.SpiConfigShadow |= ATH_SPI_CONFIG_BYTE_SWAP; + } + else if (ATH_TRANS_DS_16 == pDCxt->spi_hcd.DMADataWidth) + { + /* enable byte swapping logic for 16 bit mode */ + pDCxt->spi_hcd.SpiConfigShadow |= (ATH_SPI_CONFIG_SWAP_16BIT | ATH_SPI_CONFIG_BYTE_SWAP); + } + else + { + /* for 8 bit mode, do not turn on byte swapping */ + } + +/* delay a bit before our first SPI operation */ +#if ENABLE_FPGA_BUILD + HW_USEC_DELAY(pCxt, pDCxt->hcd.PowerUpDelay * 500000); +#else + HW_USEC_DELAY(pCxt, pDCxt->spi_hcd.PowerUpDelay * 1000); +#endif + + // FIRST SPI OPERATION START!!! + status = DoPioWriteInternal(pCxt, ATH_SPI_CONFIG_REG, pDCxt->spi_hcd.SpiConfigShadow); + + Api_BootProfile(pCxt, BOOT_PROFILE_DONE_CONFIG); + + if (A_OK != status) + { + break; + } + /* SPI configuration has been written, we can safely switch to the desired operating clock rate */ + startUpClock = pDCxt->spi_hcd.OperationalClock; + HW_SET_CLOCK(pCxt, &startUpClock); + + /* read the buffer space available for this chip, at reset we should have an empty buffer */ + status = DoPioReadInternal(pCxt, ATH_SPI_WRBUF_SPC_AVA_REG, &pDCxt->spi_hcd.WriteBufferSpace); + assert(A_OK == status); +// DoPioReadInternal(pDevice,ATH_SPI_WRBUF_SPC_AVA_REG,&pDevice->WriteBufferSpace); +#if 0 +{ +int i=0; +while(i<50000){ + DoPioReadInternal(pCxt, ATH_SPI_WRBUF_SPC_AVA_REG, (uint32_t*)&test); + if(test == EXPECTED_MAX_WRITE_BUFFER_SPACE){ + good++; + }else{ + bad++; + } + test = 0; + i++; +} +} +#endif + + if (A_OK != status) + { + break; + } + + /* save this off for watermark level calculations */ + pDCxt->spi_hcd.MaxWriteBufferSpace = pDCxt->spi_hcd.WriteBufferSpace; + + // printf("%d\r\n", pDCxt->spi_hcd.MaxWriteBufferSpace); + /* NOTE: if this assert fails it suggests that SPI communication with the WIFI device + * is not functioning. Perhaps the 2 chips are not connected. */ + A_ASSERT((uint16_t)pDCxt->spi_hcd.MaxWriteBufferSpace == EXPECTED_MAX_WRITE_BUFFER_SPACE); + /* set write buffer watermark to zero, we only set it when we need an interrupt */ + if (A_OK != (status = ResetWriteBufferWaterMark(pCxt))) + { + break; + } + /* Enable error IRQ sources */ + Hcd_UnmaskInterrupts(pCxt, ATH_SPI_HCD_ERROR_IRQS); + /* Enable the CPU interrupt so that the first interrupt + * is not lost. */ + Hcd_UnmaskInterrupts(pCxt, ATH_SPI_INTR_LOCAL_CPU_INTR); + /* enable interrupts at the HW layer */ + EnableDisableSPIIRQHwDetect(pCxt, true); + /* this delay is necessary to prevent other driver code from accessing + * the chip before it has had sufficient time to boot. accessing + * prematurely will put the chip in a failed state. + */ + A_MDELAY(2); + } while (false); + + return status; +} + +/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + HcdTransferData - transfer data state machine + Input: pDevice - device object + pReq - transfer request + Output: + Return: + Notes: This state machine handles the data phases of a DMA request or an external I/O access through + the read and write ports. + This state machine handles early termination of bytes and transfers bytes manually if + the remaining bytes is small. + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ +// FIXME remove this function later +static A_STATUS Hcd_TransferData(void *pCxt, void *pReq) +{ + return Bus_InOutDescriptorSet(pCxt, pReq); +} + +#endif //#if 1 //Common HCD API's + +/*****************************************************************************/ +void HW_EnableDisableSPIIRQ(void *pCxt, boolean Enable, boolean FromIrq) +{ + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + OSA_Critical(kCriticalDisableInt); + if (false == FromIrq) + { + IRQEN_ACCESS_ACQUIRE(pCxt); + OSA_EnterCritical(kCriticalDisableInt); + } + + do + { + if (Enable) + { + if (false == pDCxt->spi_hcd.IrqsEnabled) + { + pDCxt->spi_hcd.IrqsEnabled = true; + // Custom_Hcd_EnableDisableSPIIRQ(pCxt, Enable); + } + } + else + { + if (true == pDCxt->spi_hcd.IrqsEnabled) + { + pDCxt->spi_hcd.IrqsEnabled = false; + // Custom_Hcd_EnableDisableSPIIRQ(pCxt, Enable); + } + } + } while (0); + + if (false == FromIrq) + { + OSA_ExitCritical(kCriticalDisableInt); + IRQEN_ACCESS_RELEASE(pCxt); + } +} + +/*****************************************************************************/ +/* BUS_InOut_DescriptorSet - Attempts to read OR write a set of buffers + * on the BUS (SPI or other). The effort is required to occur synchronously + * if the sync boolean is true. Otherwise it may optionally occur + * asynchronously. If the underlying bus cannot satisfy a synchronous + * request then the custom code must by written in such a way that + * any asychronous activity is handled under the covers. + * void * pCxt - the driver context. + * A_TRANSPORT_OBJ *pObj - The object containing the buffers. + * boolean sync - indication of synchronous or asynchronous completion. + *****************************************************************************/ +A_STATUS +Bus_InOutDescriptorSet(void *pCxt, void *pReq) +{ + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + A_STATUS status; + uint16_t i, totalLength; + boolean sync = (A_NETBUF_GET_ELEM(pReq, A_REQ_CALLBACK) != NULL) ? false : true; + uint8_t *pBuf; + int32_t length; + uint8_t doRead; + + doRead = (A_NETBUF_GET_ELEM(pReq, A_REQ_COMMAND) & ATH_TRANS_READ) ? 1 : 0; + + do + { + /* Custom_Bus_Start_Transfer - allows the custom solution + * to perform any pre transfer operations such as + * changing the SPI chip select if necessary. */ + if (A_OK != (status = CUSTOM_BUS_START_TRANSFER(pCxt, sync))) + { + break; + } + + i = 0; + totalLength = 0; + + while (NULL != (pBuf = A_NETBUF_GET_FRAGMENT(pReq, i, &length))) + { + if (length) + { + /* Submit each buffer with a length to the underlying custom + * bus solution. whether the buffers actually transfer in + * the context of this function call is up to the solution. + */ + if (A_OK != (status = CUSTOM_BUS_INOUT_BUFFER(pCxt, pBuf, length, doRead, sync))) + { + break; + } + } + + totalLength += length; + i++; + } + /* account for any padding bytes that were not part of the request length */ + if (totalLength < A_NETBUF_GET_ELEM(pReq, A_REQ_TRANSFER_LEN)) + { + A_ASSERT((uint32_t)(A_NETBUF_GET_ELEM(pReq, A_REQ_TRANSFER_LEN) - totalLength) <= pDCxt->blockSize); + + status = CUSTOM_BUS_INOUT_BUFFER(pCxt, (uint8_t *)pDCxt->padBuffer, + A_NETBUF_GET_ELEM(pReq, A_REQ_TRANSFER_LEN) - totalLength, doRead, sync); + } + + /* Custom_Bus_Complete_Transfer - allows the custom solution + * to perform any post transfer operations such as + * changing the SPI chip select if necessary. */ + if (A_OK == status) + { + status = CUSTOM_BUS_COMPLETE_TRANSFER(pCxt, sync); + } + } while (0); + return status; +} + +/*****************************************************************************/ +/* BUS_InOut_Token - Attempts to read AND write 4 or less bytes on the SPI bus. + * The effort is expected to occur synchronously so that when the function + * call returns the operation will have completed. If the underlying + * bus cannot satisfy this requirement then Custom_InOut_Token must be + * written in such a way that any asychronous activity is handled under + * the covers. + * void * pCxt - the driver context. + * uint32_t OutToken - 4 or less bytes of write data. + * uint8_t dataSize - length of data. + * uint32_t *pInToken - pointer to memory to store 4 or less bytes of + * read data. + *****************************************************************************/ +A_STATUS +Bus_InOutToken(void *pCxt, uint32_t OutToken, uint8_t DataSize, uint32_t *pInToken) +{ + uint32_t dummy; + A_STATUS status; + + if (pInToken == NULL) + { + pInToken = &dummy; + } + + DataSize += 1; // data size if really a enum that is 1 less than number of bytes +#if A_BIG_ENDIAN + // because OutToken is passed in as a U32 the + // valid bytes will be the last bytes as this + // is a big-endian cpu. so we need to shift + // the valid bytes over to eliminate the invalid bytes. + OutToken <<= (32 - (DataSize << 3)); +#endif + status = CUSTOM_BUS_INOUT_TOKEN(pCxt, OutToken, DataSize, pInToken); + + if (pInToken != &dummy) + { +#if A_BIG_ENDIAN + // reading less than 4 bytes requires that the bytes + // be shifted by the number of invalid bytes. + *pInToken >>= (32 - (DataSize << 3)); +#endif + } + + return status; +} + +/*****************************************************************************/ +/* BUS_TransferComplete - Callback for the Custom Bus solution to indicate + * when an asynchronous operation has completed. This function is intended + * to be called from an interrupt level context if required by the custom + * solution. + * void *pCxt - the driver context. + * A_STATUS status - A_OK if transfer completed successfully. + *****************************************************************************/ +void Bus_TransferComplete(void *pCxt, A_STATUS status) +{ + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + UNUSED_ARGUMENT(status); + if (0 == (pDCxt->booleans & SDHD_BOOL_DMA_IN_PROG)) + { + /* error condition */ + return; + } + + pDCxt->booleans |= SDHD_BOOL_DMA_COMPLETE; + pDCxt->booleans &= ~SDHD_BOOL_DMA_IN_PROG; + /* QueueWork will kick start the driver thread if needed to perform any + * any deferred work. */ + DRIVER_WAKE_DRIVER(pCxt); +} + +void HW_EnableDisableIRQ(void *pCxt, boolean Enable, boolean FromIrq) +{ + HW_EnableDisableSPIIRQ(pCxt, Enable, FromIrq); +} + +void Hcd_Irq(void *pCxt) +{ + /* pass global context to common layer */ + HW_InterruptHandler(p_Global_Cxt); + UNUSED_ARGUMENT(pCxt); +} + +void Hcd_MaskInterrupts(void *pCxt, uint16_t Mask) +{ + MaskSPIInterrupts(pCxt, Mask); +} + +#if 0 // TBD +/* +* The below 3-functions are need to implement and +* HCD_SUSPEND_CB and HCD_RESUME_CB structures are not avialable with +* current driver source +*/ + +void Hcd_AckInterrupt(void *pCxt, uint16_t Mask) +{ + //TBD +} + +void Hcd_RegisterSuspendHandler(HCD_SUSPEND_CB *suspendCallback, void *pSuspContext) +{ + //TBD +} + +void Hcd_RegisterResumeHandler(HCD_RESUME_CB *resumeCallback, void *pSuspContext) +{ + //TBD +} + +#endif //#if 0 diff --git a/platform/mcu/lpc54102/wifi_qca/common_src/htc/htc.c b/platform/mcu/lpc54102/wifi_qca/common_src/htc/htc.c new file mode 100644 index 0000000000..f4f64f1472 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/common_src/htc/htc.c @@ -0,0 +1,960 @@ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== +#include "wifi_common.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "hw20_mbox_host_reg.h" +#include + +//#include "htc_internal.h" + +extern uint8_t reverse_credits_init; +uint8_t trailor[sizeof(HTC_RECORD_HDR) + 6 * sizeof(HTC_CREDIT_REPORT)]; + +void Htc_PrepareRecvPacket(void *pCxt, void *pReq) +{ + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + HTC_FRAME_HDR *pHTCHdr; + uint16_t validLength, transLength; + + pHTCHdr = (HTC_FRAME_HDR *)&(pDCxt->lookAhead); + /* Credits are only used in TX so init to 0 here. */ + A_NETBUF_SET_ELEM(pReq, A_REQ_CREDITS, 0); + /* get the endpoint ID from the lookahead */ + A_NETBUF_SET_ELEM(pReq, A_REQ_EPID, pHTCHdr->EndpointID); + /* calc the full recv length */ + validLength = A_LE2CPU16(pHTCHdr->PayloadLen) + sizeof(HTC_FRAME_HDR); + transLength = DEV_CALC_RECV_PADDED_LEN(pDCxt, validLength); + /* init the packet length = payloadLen + sizeof(HTC_FRAME_HDR) + */ + /* NOTE: For receive packets the request transfer length and actual buffer length are the same + * this may not be true for transmit as the driver does not have control of the transmit + * buffers. + */ + A_NETBUF_PUT(pReq, transLength); + A_NETBUF_SET_ELEM(pReq, A_REQ_TRANSFER_LEN, transLength); + /* init the packet lookahead value */ + A_NETBUF_SET_ELEM(pReq, A_REQ_LOOKAHEAD, pDCxt->lookAhead); +} + +/*****************************************************************************/ +/* HTC_RxComplete - Completes processing of received packets whose + * endpoint ID == ENDPOINT_0. This is the special HTC control endpoint. + * void *pCxt - the driver context. + * void *pReq - the packet. + *****************************************************************************/ +void Htc_RxComplete(void *pCxt, void *pReq) +{ + UNUSED_ARGUMENT(pCxt); + /* the only control messages we are expecting are NULL messages (credit resports) */ + if (A_NETBUF_LEN(pReq) > 0) + { + A_ASSERT(0); + } + + A_NETBUF_FREE(pReq); +} + +uint32_t Htc_ReadCreditCounter(void *pCxt, uint32_t index) +{ + A_NETBUF_DECLARE req; + void *pReq = (void *)&req; + uint32_t collector; + + A_NETBUF_CONFIGURE(pReq, &collector, 0, sizeof(uint32_t), sizeof(uint32_t)); + /* read the target credit counter */ + ATH_SET_PIO_EXTERNAL_READ_OPERATION(pReq, COUNT_ADDRESS + 4 * index, true, sizeof(uint32_t)); + + if (A_OK != Hcd_DoPioExternalAccess(pCxt, pReq)) + { + A_ASSERT(0); + } + + collector = A_LE2CPU32(collector); + + return collector; +} + +void Htc_GetCreditCounterUpdate(void *pCxt, uint16_t epId) +{ + A_ENDPOINT_T *pEp; + uint32_t collector; + uint16_t reg_index, array_index; +#if USE_16BIT_CREDIT_COUNTER + uint16_t credits; +#else + uint8_t credits; +#endif + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + + pEp = Util_GetEndpoint(pCxt, epId); + + if (pDCxt->htc_creditInit == 0) + { + /* never got interrupt from chip to indicate that this + * credit scheme was supported */ + pEp->intCreditCounter = 0; + return; + } + + reg_index = pEp->epIdx >> 2; + array_index = pEp->epIdx & 0x03; + /* read the target credit counter */ + collector = Htc_ReadCreditCounter(pCxt, reg_index); + +#if USE_16BIT_CREDIT_COUNTER + credits = (collector >> (8 * array_index)) & 0xffff; // modify this credits variable to 16bit + if ((credits & 0xFF00) >> 8) + { + credits = 255 + ((credits & 0xFF00) >> 8); + // ath_io_printf("Credits 0x%x \n",255 + ((credits & 0xFF00) >> 8)); + } + else + { + credits = (credits & 0xFF); + } +#else + credits = (collector >> (8 * array_index)) & 0xff; +#endif + pEp->intCreditCounter = credits; + credits = pEp->intCreditCounter - pEp->rptCreditCounter; + + /* The below condition occurs when we stop recieving in-band credits and are purely relying */ + /* on out-of-band credits. In such cases it is possible that out-of-band credit can wrap around and this prevents + * the same */ + if (credits < pEp->intCredits) + { + return; + } + + credits = credits - pEp->intCredits; // deduct any previous int credits + pEp->intCredits += credits; // track num credits acquired this way. + /* add the new credits to the EP credit count */ + pEp->credits += credits; +} + +static void Htc_DistributeCredits(void *pCxt) +{ + uint32_t numCredits; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + + numCredits = (uint16_t)pDCxt->creditCount; + pDCxt->ep[0].maxCredits = pDCxt->ep[0].credits = 1; + pDCxt->ep[0].rptCreditCounter = 0; + pDCxt->ep[0].intCreditCounter = 0; + pDCxt->ep[0].intCredits = 0; + numCredits--; + pDCxt->ep[1].maxCredits = pDCxt->ep[1].credits = 1; + pDCxt->ep[1].rptCreditCounter = 0; + pDCxt->ep[1].intCreditCounter = 0; + pDCxt->ep[1].intCredits = 0; + numCredits--; + +#if USE_16BIT_CREDIT_COUNTER + pDCxt->ep[2].maxCredits = pDCxt->ep[2].credits = (uint16_t)numCredits; +#else + pDCxt->ep[2].maxCredits = pDCxt->ep[2].credits = (uint8_t)numCredits; +#endif + pDCxt->ep[2].rptCreditCounter = 0; + pDCxt->ep[2].intCreditCounter = 0; + pDCxt->ep[2].intCredits = 0; +} + +/* process credit reports and call distribution function */ +static void Htc_ProcessCreditRpt(void *pCxt, HTC_CREDIT_REPORT *pRpt, int32_t NumEntries, HTC_ENDPOINT_ID FromEndpoint) +{ + int i; + A_ENDPOINT_T *pEndpoint; +#if USE_16BIT_CREDIT_COUNTER + uint16_t credits; +#else + uint8_t credits; +#endif + UNUSED_ARGUMENT(FromEndpoint); + + for (i = 0; i < NumEntries; i++) + { + if (pRpt[i].EndpointID >= ENDPOINT_MAX) + { + A_ASSERT(0); +#if DRIVER_CONFIG_DISABLE_ASSERT + break; +#endif + } + + pEndpoint = Util_GetEndpoint(pCxt, pRpt[i].EndpointID); + /* this variable will and should wrap around. */ + pEndpoint->rptCreditCounter += pRpt[i].Credits; + + credits = pRpt[i].Credits; + + if (pEndpoint->intCredits) + { + if (pEndpoint->intCredits <= pRpt[i].Credits) + { + credits = pRpt[i].Credits - pEndpoint->intCredits; + pEndpoint->intCredits = 0; + } + else + { + credits = 0; + pEndpoint->intCredits -= pRpt[i].Credits; + } + } + + pEndpoint->credits += credits; + } +} + +/* Interrupt cause register bit definitions: + * bit 0 - used for initial credit distribution + * bit 1 - Start of frame in Argos + * bit 2-7 - unused + */ +void HTC_ProcessCpuInterrupt(void *pCxt) +{ + A_NETBUF_DECLARE req; + void *pReq = (void *)&req; + uint32_t collector; + uint8_t *ptr = (uint8_t *)&collector; + + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + + /* The interrupt cause register indicates the reason who raised + * this interrupt. Use it to decode*/ + /* bit 0 is for credit distribution */ + if (pDCxt->spi_hcd.CpuInterruptCause & 0x1) + { + /* if this is the first such interrupt then acquire the + * address of the HTC comm memory. */ + A_NETBUF_CONFIGURE(pReq, &collector, 0, sizeof(uint32_t), sizeof(uint32_t)); + + if (pDCxt->htc_creditInit == 0) + { + pDCxt->htc_creditInit = 1; + ATH_SET_PIO_EXTERNAL_READ_OPERATION(pReq, COUNT_ADDRESS + 4, true, sizeof(uint32_t)); + + if (A_OK != Hcd_DoPioExternalAccess(pCxt, pReq)) + { + A_ASSERT(0); + } + + /* the last byte of the COUNT_ADDRESS contain the creditCount */ + pDCxt->creditCount = ptr[3]; + /* distribute the credits among the endpoints */ + Htc_DistributeCredits(pCxt); + } + } + + /* bit 1 is for SOF in argos */ + if (pDCxt->spi_hcd.CpuInterruptCause & 0x2) + { + // printf("SOF intr\n"); + } + + /* All interrupts have been processed */ + pDCxt->spi_hcd.CpuInterruptCause = 0x0; +} + +/*****************************************************************************/ +/* Htc_ProcessTrailer - Trailers can be appended to the end of a received + * packet. This function processes those trailers prior to their removal + * from the packet. + * void *pCxt - the driver context. + * uint8_t *pBuffer - the buffer holding the trailers. + * int32_t Length - the length of the pBuffer in bytes. + * uint32_t *pNextLookAheads - storage for any lookaheads found in + * the trailer. + * int32_t *pNumLookAheads - storage for a count of valid lookaheads + * stored in pNextLookAheads. + * HTC_ENDPOINT_ID FromEndpoint - the endpoint ID of the received packet. + *****************************************************************************/ +static A_STATUS Htc_ProcessTrailer(void *pCxt, + uint8_t *pBuffer, + int32_t Length, + uint32_t *pNextLookAheads, + uint32_t *pNumLookAheads, + HTC_ENDPOINT_ID FromEndpoint) +{ + HTC_RECORD_HDR *pRecord; + uint8_t *pRecordBuf; + HTC_LOOKAHEAD_REPORT *pLookAhead; + A_STATUS status; + + status = A_OK; + + while (Length > 0) + { + if (Length < (int32_t)sizeof(HTC_RECORD_HDR)) + { + status = A_EPROTO; + break; + } + /* these are byte aligned structs */ + pRecord = (HTC_RECORD_HDR *)pBuffer; + Length -= sizeof(HTC_RECORD_HDR); + pBuffer += sizeof(HTC_RECORD_HDR); + + if (pRecord->Length > Length) + { + /* no room left in buffer for record */ + status = A_EPROTO; + break; + } + /* start of record follows the header */ + pRecordBuf = pBuffer; + + switch (pRecord->RecordID) + { + case HTC_RECORD_CREDITS: /* the device is indicating that new TX credits are available */ + Htc_ProcessCreditRpt(pCxt, (HTC_CREDIT_REPORT *)pRecordBuf, + (int32_t)(pRecord->Length / (sizeof(HTC_CREDIT_REPORT))), FromEndpoint); + break; + case HTC_RECORD_LOOKAHEAD: /* the device is providing the lookahead for the next packet */ + A_ASSERT(pRecord->Length >= sizeof(HTC_LOOKAHEAD_REPORT)); + pLookAhead = (HTC_LOOKAHEAD_REPORT *)pRecordBuf; + if ((pLookAhead->PreValid == ((~pLookAhead->PostValid) & 0xFF)) && (pNextLookAheads != NULL)) + { + /* look ahead bytes are valid, copy them over */ + ((uint8_t *)(&pNextLookAheads[0]))[0] = pLookAhead->LookAhead[0]; + ((uint8_t *)(&pNextLookAheads[0]))[1] = pLookAhead->LookAhead[1]; + ((uint8_t *)(&pNextLookAheads[0]))[2] = pLookAhead->LookAhead[2]; + ((uint8_t *)(&pNextLookAheads[0]))[3] = pLookAhead->LookAhead[3]; + + /* just one normal lookahead */ + *pNumLookAheads = 1; + } + break; + case HTC_RECORD_LOOKAHEAD_BUNDLE: +#if 0 /* this feature is not currently supported by this driver */ + AR_DEBUG_ASSERT(pRecord->Length >= sizeof(HTC_BUNDLED_LOOKAHEAD_REPORT)); + if (pRecord->Length >= sizeof(HTC_BUNDLED_LOOKAHEAD_REPORT) && + (pNextLookAheads != NULL)) { + HTC_BUNDLED_LOOKAHEAD_REPORT *pBundledLookAheadRpt; + int32_t i; + + pBundledLookAheadRpt = (HTC_BUNDLED_LOOKAHEAD_REPORT *)pRecordBuf; + + if ((pRecord->Length / (sizeof(HTC_BUNDLED_LOOKAHEAD_REPORT))) > + HTC_HOST_MAX_MSG_PER_BUNDLE) { + /* this should never happen, the target restricts the number + * of messages per bundle configured by the host */ + A_ASSERT(false); + status = A_EPROTO; + break; + } + + for (i = 0; i < (int)(pRecord->Length / (sizeof(HTC_BUNDLED_LOOKAHEAD_REPORT))); i++) { + ((uint8_t *)(&pNextLookAheads[i]))[0] = pBundledLookAheadRpt->LookAhead[0]; + ((uint8_t *)(&pNextLookAheads[i]))[1] = pBundledLookAheadRpt->LookAhead[1]; + ((uint8_t *)(&pNextLookAheads[i]))[2] = pBundledLookAheadRpt->LookAhead[2]; + ((uint8_t *)(&pNextLookAheads[i]))[3] = pBundledLookAheadRpt->LookAhead[3]; + pBundledLookAheadRpt++; + } + + *pNumLookAheads = i; + } + break; +#else + A_ASSERT(0); +#if DRIVER_CONFIG_DISABLE_ASSERT + break; +#endif +#endif + + default: + break; + } + + if (A_OK != status) + { + break; + } + + /* advance buffer past this record for next time around */ + pBuffer += pRecord->Length; + Length -= pRecord->Length; + } + + if (A_OK != status) + { + A_ASSERT(0); + } + + return status; +} + +#if defined(DRIVER_CONFIG_IMPLEMENT_RX_FREE_MULTIPLE_QUEUE) +int hasRCSReport() +{ + uint8_t i; + +#if TWO_MSQ + for (i = 0; i < 8; i++) +#else + for (i = 1; i < 8; i++) +#endif + { + if (GET_CREDIT(i) != 0) + return true; + } + return false; +} + +static int CollectCredits(uint8_t *buff, int lenFreeTrail) +{ + HTC_RECORD_HDR *hd; + HTC_CREDIT_REPORT *rec; + + int len = 0; + uint8_t i; + + hd = (HTC_RECORD_HDR *)buff; + rec = (HTC_CREDIT_REPORT *)(buff + sizeof(HTC_RECORD_HDR)); + +// qosal_intr_disable(); + +#if TWO_MSQ + for (i = 0; i < 8; i++) +#else + for (i = 1; i < 8; i++) +#endif + { + if (len + sizeof(HTC_CREDIT_REPORT) > lenFreeTrail) + break; + + if (GET_CREDIT(i) != 0) + { + rec->EndpointID = i; + rec->Credits = GET_CREDIT(i); + CLEAR_CREDIT(i); + + len += sizeof(HTC_CREDIT_REPORT); + rec++; + } + } + hd->RecordID = HTC_RECORD_CREDITS; + hd->Length = len; + + len += sizeof(HTC_RECORD_HDR); + // send_reverse_credits_flag = 0; + + // qosal_intr_enable(); + + return len; +} +#endif + +A_NETBUF *p; + +A_STATUS +Htc_SendPacket(void *pCxt, void *pReq) +{ + A_STATUS status = A_ERROR; + A_ENDPOINT_T *pEp; + uint8_t htcFlags = 0; + uint8_t SeqNo = 0; + uint8_t *pHdrBuf; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + + do + { + /* adjust the Endpoint credit count */ + if (NULL == (pEp = Util_GetEndpoint(pCxt, A_NETBUF_GET_ELEM(pReq, A_REQ_EPID)))) + { + break; + } + if (pDCxt->htcStart == true) + { + if (0 == pEp->credits) + { + break; + } + + if (A_NETBUF_GET_ELEM(pReq, A_REQ_CREDITS) == 0) + { + SeqNo = 0; + } + + A_ASSERT(A_NETBUF_GET_ELEM(pReq, A_REQ_CREDITS)); + pEp->credits -= A_NETBUF_GET_ELEM(pReq, A_REQ_CREDITS); + SeqNo = pEp->seqNo; + pEp->seqNo++; + + if (0 == pEp->credits) + { + htcFlags |= HTC_FLAGS_NEED_CREDIT_UPDATE; + } + } + + pHdrBuf = A_NETBUF_DATA(pReq); + +#if defined(DRIVER_CONFIG_IMPLEMENT_RX_FREE_MULTIPLE_QUEUE) + if (reverse_credits_init != 0) + { + int lenRecord, lenFreeTrail; + uint8_t buff[sizeof(HTC_RECORD_HDR) + 6 * sizeof(HTC_CREDIT_REPORT)]; + uint8_t *data; + + if (A_NETBUF_GET_ELEM(pReq, A_REQ_EPID) == ENDPOINT_0) + { + lenFreeTrail = A_NETBUF_TAILROOM(pReq); + if (lenFreeTrail < 12) + { + p = (A_NETBUF *)pReq; + } + A_ASSERT(lenFreeTrail >= 12); + + lenRecord = CollectCredits(buff, lenFreeTrail); + + pHdrBuf = A_NETBUF_DATA(pReq); + if (lenRecord > sizeof(HTC_RECORD_HDR)) + { + A_NETBUF_PUT_DATA(pReq, buff, lenRecord); + htcFlags |= HTC_FLAGS_SEND_TRAILER; + A_SET_UINT8_FIELD(pHdrBuf, HTC_FRAME_HDR, ControlBytes[1], lenRecord); + } + else + { + A_SET_UINT8_FIELD(pHdrBuf, HTC_FRAME_HDR, ControlBytes[1], 0); + } + } + else + { + lenRecord = CollectCredits(buff, lenFreeTrail); + + pHdrBuf = A_NETBUF_DATA(pReq); + data = NULL; + + if (lenRecord > sizeof(HTC_RECORD_HDR)) + { + data = trailor; + } + + if (data != NULL) + { + A_MEMCPY(data, buff, lenRecord); + A_NETBUF_APPEND_FRAGMENT(pReq, data, lenRecord); + htcFlags |= HTC_FLAGS_SEND_TRAILER; + A_SET_UINT8_FIELD(pHdrBuf, HTC_FRAME_HDR, ControlBytes[1], lenRecord); + } + else + { + A_SET_UINT8_FIELD(pHdrBuf, HTC_FRAME_HDR, ControlBytes[1], 0); + } + } + } +#else + A_SET_UINT8_FIELD(pHdrBuf, HTC_FRAME_HDR, ControlBytes[1], (uint8_t)(SeqNo)); +#endif + /* fill in elements of the HTC header. treat the header as an un-aligned struct for safety */ + A_SET_UINT16_FIELD(pHdrBuf, HTC_FRAME_HDR, PayloadLen, (uint16_t)A_NETBUF_LEN(pReq) - HTC_HDR_LENGTH); + A_SET_UINT8_FIELD(pHdrBuf, HTC_FRAME_HDR, Flags, (htcFlags)); + A_SET_UINT8_FIELD(pHdrBuf, HTC_FRAME_HDR, EndpointID, (uint8_t)A_NETBUF_GET_ELEM(pReq, A_REQ_EPID)); + A_SET_UINT8_FIELD(pHdrBuf, HTC_FRAME_HDR, ControlBytes[0], (uint8_t)(0)); + /* A_SET_UINT8_FIELD(pHdrBuf, HTC_FRAME_HDR,ControlBytes[1], (uint8_t)(SeqNo)); + */ + status = A_OK; + } while (0); + + return status; +} + +A_STATUS +Htc_ProcessTxComplete(void *pCxt, void *pReq) +{ + UNUSED_ARGUMENT(pCxt); + /* remove the HTC header from the front of the packet. */ + return A_NETBUF_PULL(pReq, HTC_HDR_LENGTH); +} + +/*****************************************************************************/ +/* HTC_ProcessRecvHeader - Processes HTC headers and removes them from the + * front of the packet. + * void *pCxt - the driver context. + * void *pReq - the packet. + * uint32_t *pNextLookAheads - storage for any lookaheads found in + * the trailer. + * int32_t *pNumLookAheads - storage for a count of valid lookaheads + * stored in pNextLookAheads. + *****************************************************************************/ +A_STATUS +Htc_ProcessRecvHeader(void *pCxt, void *pReq, uint32_t *pNextLookAheads, uint32_t *pNumLookAheads) +{ + uint8_t temp; + uint8_t *pBuf; + A_STATUS status = A_OK; + uint16_t payloadLen, bufLength; + uint32_t lookAhead; + + //NOTE: coverity fix + if (NULL == pNumLookAheads) + { + return A_ERROR; + } + + *pNumLookAheads = 0; + + do + { + bufLength = A_NETBUF_LEN(pReq); + /* gets the first buffer which will/must contain the HTC header */ + if (NULL == (pBuf = A_NETBUF_DATA(pReq)) || bufLength < HTC_HDR_LENGTH) + { + /* this is a critical error */ + A_ASSERT(0); +#if DRIVER_CONFIG_DISABLE_ASSERT + status = A_EPROTO; + break; +#endif + } + /* note, we cannot assume the alignment of pBuffer, so we use the safe macros to + * retrieve 16 bit fields */ + payloadLen = (uint16_t)A_GET_UINT16_FIELD(pBuf, HTC_FRAME_HDR, PayloadLen); + + ((uint8_t *)&lookAhead)[0] = pBuf[0]; + ((uint8_t *)&lookAhead)[1] = pBuf[1]; + ((uint8_t *)&lookAhead)[2] = pBuf[2]; + ((uint8_t *)&lookAhead)[3] = pBuf[3]; + + if (lookAhead != A_NETBUF_GET_ELEM(pReq, A_REQ_LOOKAHEAD)) + { + /* this is a critical error */ + A_ASSERT(0); +#if DRIVER_CONFIG_DISABLE_ASSERT + status = A_EPROTO; + break; +#endif + } + /* now that the payloadLen and the HTC header has been confirmed + * remove any padding length that may have been added to the buffer + */ + if (payloadLen + HTC_HDR_LENGTH < A_NETBUF_LEN(pReq)) + { + A_NETBUF_TRIM(pReq, A_NETBUF_LEN(pReq) - (payloadLen + HTC_HDR_LENGTH)); + } + + /* get flags */ + temp = A_GET_UINT8_FIELD(pBuf, HTC_FRAME_HDR, Flags); + + if (temp & HTC_FLAGS_RECV_TRAILER) + { + /* this packet has a trailer */ + + /* extract the trailer length in control byte 0 */ + temp = A_GET_UINT8_FIELD(pBuf, HTC_FRAME_HDR, ControlBytes[0]); + + if ((temp < sizeof(HTC_RECORD_HDR)) || (temp > payloadLen)) + { + /* this is a critical error */ + A_ASSERT(0); +#if DRIVER_CONFIG_DISABLE_ASSERT + status = A_EPROTO; + break; +#endif + } + /* process trailer data that follows HDR + application payload */ + if (A_OK != + (status = Htc_ProcessTrailer(pCxt, (pBuf + HTC_HDR_LENGTH + payloadLen - temp), temp, pNextLookAheads, + pNumLookAheads, (HTC_ENDPOINT_ID)A_NETBUF_GET_ELEM(pReq, A_REQ_EPID)))) + { + break; + } + /* remove the trailer bytess via buffer trim */ + A_NETBUF_TRIM(pReq, temp); + } + /* if we get to this point, the packet is good */ + /* remove header and adjust length */ + A_NETBUF_PULL(pReq, HTC_HDR_LENGTH); + + } while (0); + + if (A_OK != status) + { + A_ASSERT(0); + } + + return status; +} + +A_STATUS +HTC_WaitTarget(void *pCxt) +{ + A_STATUS status; + // HTC_READY_EX_MSG *pRdyMsg; + HTC_SERVICE_CONNECT_REQ connect; + HTC_SERVICE_CONNECT_RESP resp; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + + do + { + if (ath_custom_htc.HTCGetReady != NULL) + { + if (A_OK != (status = ath_custom_htc.HTCGetReady(pCxt))) + { + break; + } + } + else + { + pDCxt->creditCount = AR4100_DEFAULT_CREDIT_COUNT; // TODO: ??? + pDCxt->creditSize = AR4100_BUFFER_SIZE; + } + /* setup our pseudo HTC control endpoint connection */ + A_MEMZERO(&connect, sizeof(connect)); + A_MEMZERO(&resp, sizeof(resp)); + + connect.ServiceID = HTC_CTRL_RSVD_SVC; + + /* connect fake service */ + status = HTC_ConnectService(pCxt, &connect, &resp); + + if (!A_FAILED(status)) + { + break; + } + } while (false); + + return status; +} + +A_STATUS +HTC_ConnectService(void *pCxt, HTC_SERVICE_CONNECT_REQ *pConnectReq, HTC_SERVICE_CONNECT_RESP *pConnectResp) +{ + A_STATUS status = A_OK; + HTC_ENDPOINT_ID assignedEndpoint = ENDPOINT_MAX; + A_ENDPOINT_T *pEndpoint; + uint32_t maxMsgSize = 0; + + do + { + if (HTC_CTRL_RSVD_SVC == pConnectReq->ServiceID) + { + /* special case for pseudo control service */ + assignedEndpoint = ENDPOINT_0; + maxMsgSize = HTC_MAX_CONTROL_MESSAGE_LENGTH; + } + else + { + if (ath_custom_htc.HTCConnectServiceExch != NULL) + { + status = ath_custom_htc.HTCConnectServiceExch(pCxt, pConnectReq, pConnectResp, &assignedEndpoint, + &maxMsgSize); + + if (status != A_OK) + { + break; + } + } + else + { + pConnectResp->ConnectRespCode = HTC_SERVICE_SUCCESS; + + switch (pConnectReq->ServiceID) + { + case WMI_CONTROL_SVC: + assignedEndpoint = ENDPOINT_1; + maxMsgSize = 1542; + break; + case WMI_DATA_BE_SVC: + assignedEndpoint = ENDPOINT_2; + maxMsgSize = 4144; + break; + case WMI_DATA_BK_SVC: + assignedEndpoint = ENDPOINT_3; + maxMsgSize = 4144; + break; + case WMI_DATA_VI_SVC: + assignedEndpoint = ENDPOINT_4; + maxMsgSize = 4144; + break; + case WMI_DATA_VO_SVC: + assignedEndpoint = ENDPOINT_5; + maxMsgSize = 4144; + break; + } + } + } + + /* the rest of these are parameter checks so set the error status */ + status = A_EPROTO; + + if (0 == maxMsgSize) + { + A_ASSERT(0); +#if DRIVER_CONFIG_DISABLE_ASSERT + break; +#endif + } + + pEndpoint = Util_GetEndpoint(pCxt, assignedEndpoint); + /* this marks the endpoint in use */ + pEndpoint->serviceID = pConnectReq->ServiceID; + /* return assigned endpoint to caller */ + pConnectResp->Endpoint = assignedEndpoint; + pConnectResp->MaxMsgLength = maxMsgSize; + + pEndpoint->maxMsgLength = (int32_t)maxMsgSize; + + status = A_OK; + + } while (0); + + return status; +} + +/* Start HTC, enable interrupts and let the target know host has finished setup */ +A_STATUS +HTC_Start(void *pCxt) +{ + A_STATUS status = A_OK; + + do + { + Htc_DistributeCredits(pCxt); + + if (ath_custom_htc.HTCSendSetupComplete != NULL) + { + /* the caller is done connecting to services, so we can indicate to the + * target that the setup phase is complete */ + status = ath_custom_htc.HTCSendSetupComplete(pCxt); + + if (A_FAILED(status)) + { + break; + } + } + + /* unmask the packet interrupt on-chip */ + Hcd_UnmaskInterrupts(pCxt, ATH_SPI_INTR_PKT_AVAIL); + GET_DRIVER_COMMON(pCxt)->htcStart = true; + } while (0); + + return status; +} + +/* synchronously wait for a message from the target, + */ +#if 0 +A_STATUS +Htc_WaitforMessage(HTC_HANDLE HTCHandle, HTC_PACKET **ppControlPacket, uint8_t EndpointID) +{ + A_STATUS status; + uint32_t lookAhead; + HTC_PACKET *pPacket = NULL; + HTC_FRAME_HDR *pHdr; + HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); + + do { + + /* call the polling function to see if we have a message */ + status = DevPollMboxMsgRecv(&target->Device, + &lookAhead, + HTC_TARGET_RESPONSE_TIMEOUT); + + if (A_FAILED(status)) { + break; + } + + /* check the lookahead */ + pHdr = (HTC_FRAME_HDR *)&lookAhead; + + if (pHdr->EndpointID != EndpointID) { + /* unexpected endpoint number, should be zero */ + status = A_EPROTO; + break; + } + + if (A_FAILED(status)) { + /* bad message */ + status = A_EPROTO; + break; + } + + if(*ppControlPacket != NULL){ + pPacket = *ppControlPacket; + }else{ + pPacket = HTC_ALLOC_CONTROL_RX(target); + + if (pPacket == NULL) { + status = A_NO_MEMORY; + break; + } + } + + pPacket->PktInfo.AsRx.HTCRxFlags = 0; + pPacket->PktInfo.AsRx.ExpectedHdr = lookAhead; + pPacket->ActualLength = A_LE2CPU16(pHdr->PayloadLen) + HTC_HDR_LENGTH; + + if (pPacket->ActualLength > pPacket->BufferLength) { + status = A_EPROTO; + break; + } + + /* we want synchronous operation */ + pPacket->Completion = NULL; + + /* get the message from the device, this will block */ + status = HTCIssueRecv(target, pPacket); + + if (A_FAILED(status)) { + break; + } + + /* process receive header */ + status = HTCProcessRecvHeader(target,pPacket,NULL,NULL); + + pPacket->Status = status; + + if (A_FAILED(status)) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("HTCWaitforMessage, HTCProcessRecvHeader failed (status = %d) \n", + status)); + break; + } + + /* give the caller this control message packet, they are responsible to free */ + *ppControlPacket = pPacket; + + } while (false); + + if (A_FAILED(status)) { + if (pPacket != NULL && *ppControlPacket == NULL) { + /* cleanup buffer on error */ + HTC_FREE_CONTROL_RX(target,pPacket); + } + } + + return status; +} + +#endif diff --git a/platform/mcu/lpc54102/wifi_qca/common_src/hw_interface/hw_api.c b/platform/mcu/lpc54102/wifi_qca/common_src/hw_interface/hw_api.c new file mode 100644 index 0000000000..97bffb1b38 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/common_src/hw_interface/hw_api.c @@ -0,0 +1,151 @@ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +A_STATUS HW_ProcessPendingInterrupts(void *pCxt) +{ + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + uint8_t cpuIntrCause; + + pDCxt->driver_state = DRIVER_STATE_PENDING_CONDITION_A; + + /* identify the interrupt and mask it */ + if (pDCxt->spi_hcd.IrqDetected == true) + { + pDCxt->driver_state = DRIVER_STATE_INTERRUPT_PROCESSING; + pDCxt->spi_hcd.IrqDetected = false; + + if (false == Hcd_BusInterrupt(pCxt)) + { + /* FIXME: HANDLE ERROR CONDITION */ + } + } + + pDCxt->driver_state = DRIVER_STATE_PENDING_CONDITION_B; + /* check to see if a deferred bus request has completed. if so + * process it. */ + if (pDCxt->booleans & SDHD_BOOL_DMA_COMPLETE) + { + /* get the request */ + if (A_OK == Driver_CompleteRequest(pCxt, pDCxt->spi_hcd.pCurrentRequest)) + { + /* clear the pending request and the boolean */ + pDCxt->spi_hcd.pCurrentRequest = NULL; + pDCxt->booleans &= ~SDHD_BOOL_DMA_COMPLETE; + } + } + + if (pDCxt->spi_hcd.CpuInterrupt) + { + cpuIntrCause = 0x0; + if (Hcd_ReadCPUInterrupt(pCxt, &cpuIntrCause)) + { + pDCxt->spi_hcd.CpuInterruptCause = cpuIntrCause; + } + pDCxt->driver_state = DRIVER_STATE_INTERRUPT_PROCESSING; + Hcd_ClearCPUInterrupt(pCxt); + Hcd_UnmaskInterrupts(pCxt, ATH_SPI_INTR_LOCAL_CPU_INTR); + HTC_ProcessCpuInterrupt(pCxt); + pDCxt->spi_hcd.CpuInterrupt = 0; + } + + pDCxt->driver_state = DRIVER_STATE_PENDING_CONDITION_C; + return A_OK; +} + +void HW_PowerUpDown(void *pCxt, uint8_t powerUp) +{ +#if WLAN_CONFIG_ENABLE_CHIP_PWD_GPIO + /* NOTE: when powering down it is necessary that the SPI MOSI on the MCU + * be configured high so that current does not leak from the AR6003. + * Hence because the SPI interface retains its last state we write a single + * 0xf out the SPI bus prior to powering the chip down. + */ + if (powerUp == 0) + { + Bus_InOutToken(pCxt, (uint32_t)0xff, 1, NULL); + } + + HW_USEC_DELAY(pCxt, 1000); + CUSTOM_HW_POWER_UP_DOWN(pCxt, powerUp); + + if (powerUp) + { + if (ath_custom_init.Custom_reset_measure_timer != NULL) + { + ath_custom_init.Custom_reset_measure_timer(); + } + + // delay to give chip time to come alive + HW_USEC_DELAY(pCxt, 2000); + } +#endif +} + +void HW_InterruptHandler(void *pCxt) +{ + if (pCxt) + { + GET_DRIVER_COMMON(pCxt)->spi_hcd.IrqDetected = true; + + /* disable IRQ while we process it */ + HW_EnableDisableIRQ(pCxt, false, true); + /* startup work item to process IRQs */ + DRIVER_WAKE_DRIVER(pCxt); + } +} + +void HW_SetClock(void *pCxt, uint32_t *pClockRate) +{ + UNUSED_ARGUMENT(pCxt); + UNUSED_ARGUMENT(pClockRate); +} + +uint32_t HW_GetMboxAddress(void *pCxt, uint16_t mbox, uint32_t length) +{ + uint32_t address = 0; + + if (mbox == 0) + { + address = GET_DRIVER_COMMON(pCxt)->mboxAddress + HIF_MBOX_WIDTH - length; + } + else + { + A_ASSERT(0); + } + + return address; +} diff --git a/platform/mcu/lpc54102/wifi_qca/common_src/include/a_debug.h b/platform/mcu/lpc54102/wifi_qca/common_src/include/a_debug.h new file mode 100644 index 0000000000..0f58a11056 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/common_src/include/a_debug.h @@ -0,0 +1,41 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== +#ifndef _A_DEBUG_H_ +#define _A_DEBUG_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define A_REGISTER_MODULE_DEBUG_INFO(mod) +#define AR_DEBUG_PRINTF(mask, args) +//#define AR_DEBUG_PRINTF(mask, args) do { if(1) PRINTF args ; } while(0) + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif diff --git a/platform/mcu/lpc54102/wifi_qca/common_src/include/a_drv.h b/platform/mcu/lpc54102/wifi_qca/common_src/include/a_drv.h new file mode 100644 index 0000000000..e0f6b452f7 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/common_src/include/a_drv.h @@ -0,0 +1,29 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== +#ifndef _A_DRV_H_ +#define _A_DRV_H_ + +#endif /* _ADRV_H_ */ diff --git a/platform/mcu/lpc54102/wifi_qca/common_src/include/a_drv_api.h b/platform/mcu/lpc54102/wifi_qca/common_src/include/a_drv_api.h new file mode 100644 index 0000000000..6d9d3402a5 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/common_src/include/a_drv_api.h @@ -0,0 +1,264 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== +#ifndef _A_DRV_API_H_ +#define _A_DRV_API_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************************************/ +/****************************************************************************/ +/** **/ +/** WMI related hooks **/ +/** **/ +/****************************************************************************/ +/****************************************************************************/ +void Api_ChannelListEvent(void *pCxt, uint8_t devId, int8_t numChan, void *chanList); +void Api_TargetStatsEvent(void *pCxt, uint8_t devId, uint8_t *ptr, uint32_t len); +void Api_ScanCompleteEvent(void *pCxt, uint8_t devId, A_STATUS status); +void Api_RegDomainEvent(void *pCxt, uint8_t devId, uint32_t regCode); +void Api_DisconnectEvent(void *pCxt, + uint8_t devId, + uint8_t reason, + uint8_t *bssid, + uint8_t assocRespLen, + uint8_t *assocInfo, + uint16_t protocolReasonStatus); +void Api_ConnectEvent(void *pCxt, + uint8_t devId, + uint16_t channel, + uint8_t *bssid, + uint16_t listenInterval, + uint16_t beaconInterval, + NETWORK_TYPE networkType, + uint8_t beaconIeLen, + uint8_t assocReqLen, + uint8_t assocRespLen, + uint8_t *assocInfo); +void Api_BitrateEvent(void *pCxt, uint8_t devId, int32_t rateKbps); +void Api_ReadyEvent(void *pCxt, uint8_t devId, uint8_t *datap, uint8_t phyCap, uint32_t sw_ver, uint32_t abi_ver); +void Api_BssInfoEvent(void *pCxt, uint8_t devId, uint8_t *datap, int32_t len); +void Api_TkipMicErrorEvent(void *pCxt, uint8_t devId, uint8_t keyid, boolean ismcast); +void Api_GetPmkEvent(void *pCxt, uint8_t devId, uint8_t *datap); +void Api_RxDbglogEvent(void *wmip, uint8_t devId, uint8_t *datap, int32_t len); +void Api_RxGpioDataEvent(void *wmip, uint8_t devId, uint8_t *datap, int32_t len); +void Api_RxHBChallengeEvent(void *wmip, uint8_t devId, uint8_t *datap, int32_t len); +void Api_RxPfmDataEvent(void *wmip, uint8_t devId, uint8_t *datap, int32_t len); +void Api_RxPfmDataDoneEvent(void *wmip, uint8_t devId, uint8_t *datap, int32_t len); + +void Api_StoreRecallEvent(void *pCxt, uint8_t devId, uint8_t *datap, int32_t len, void *pReq); +void Api_StoreRecallStartEvent(void *pCxt, uint8_t devId, uint8_t *datap, int32_t len, void *pReq); +void Api_HostDsetStoreEvent(void *pCxt, uint8_t devId, uint8_t *datap, int32_t len, void *pReq); +void Api_HostDsetReadEvent(void *pCxt, uint8_t devId, uint8_t *datap, int32_t len, void *pReq); +void Api_HostDsetCreateEvent(void *pCxt, uint8_t devId, uint8_t *datap, int32_t len, void *pReq); +void Api_HostDsetWriteEvent(void *pCxt, uint8_t devId, uint8_t *datap, int32_t len, void *pReq); +void Api_HostDsetReadbackEvent(void *pCxt, uint8_t devId, uint8_t *datap, int32_t len, void *pReq); +void Api_HostDsetSyncEvent(void *pCxt, uint8_t devId, uint8_t *datap, int32_t len, void *pReq); +void Api_DsetOPEvent(void *pCxt, uint8_t devId, uint8_t *datap, int32_t len, void *pReq); + +void Api_WpsProfileEvent(void *pCxt, uint8_t devId, uint8_t *datap, int32_t len, void *pReq); +void Api_AggrRecvAddbaReqEvent(void *pCxt, uint8_t devId, WMI_ADDBA_REQ_EVENT *evt); +void Api_AggrRecvDelbaReqEvent(void *pCxt, uint8_t devId, WMI_DELBA_EVENT *evt); +A_STATUS +Api_WmiTxStart(void *pCxt, void *pReq, HTC_ENDPOINT_ID eid); +void Api_RSNASuccessEvent(void *pCxt, uint8_t devId, uint8_t code); +void Api_GetBitRateEvent(void *pCxt, uint8_t devId, void *datap); +A_STATUS +Api_SockResponseEventRx(void *pCxt, uint8_t devId, uint8_t *datap, uint32_t len, void *pReq); +void Api_ProbeReqEvent(void *pCxt, uint8_t *datap, uint32_t len); + +#if MANUFACTURING_SUPPORT +void Api_TestCmdEventRx(void *pCxt, uint8_t devId, uint8_t *datap, uint32_t len); +#endif +void Api_GetTemperatureReply(void *pCxt, uint8_t *datap, uint32_t len); +void Api_GetCountryCodeReply(void *pCxt, uint8_t *datap, uint32_t len); +void Api_GetSetParamReply(void *pCxt, uint8_t *datap); +void Api_GetWpsInitReply(void *pCxt, uint8_t *datap, uint32_t len); +#if ENABLE_P2P_MODE +void p2p_go_neg_event(void *pCxt, uint8_t devId, uint8_t *datap, uint32_t len, WMI_P2P_PROV_INFO *wps_info); + +void p2p_invite_sent_result_event(void *pCxt, uint8_t devId, uint8_t *datap, uint32_t len); + +void p2p_node_list_event(void *pCxt, uint8_t devId, uint8_t *datap, uint32_t len); + +void p2p_list_persistent_network_event(void *pCxt, uint8_t devId, uint8_t *datap, uint32_t len); + +void p2p_req_auth_event(void *pCxt, uint8_t devId, uint8_t *datap, uint32_t len); + +void get_p2p_ctx(void *pCxt, uint8_t devId, uint8_t *datap, uint32_t len); + +void get_p2p_prov_disc_req(void *pCxt, uint8_t devId, uint8_t *datap, uint32_t len); + +void get_p2p_serv_disc_req(void *pCxt, uint8_t devId, uint8_t *datap, uint32_t len); + +void p2p_invite_req_rx(void *pCxt, uint8_t devId, uint8_t *datap, uint8_t len); + +void p2p_invite_rcvd_result_ev(void *pCxt, uint8_t devId, uint8_t *datap, uint32_t len); + +#define A_WMI_P2P_GO_NEG_EVENT(devt, devId, res, len, wps_info) \ + p2p_go_neg_event((devt), (devId), (res), (len), (wps_info)) + +#define A_WMI_P2P_NODE_LIST_EVENT(devt, devId, res, len) p2p_node_list_event((devt), (devId), (res), (len)) + +#define A_WMI_P2P_PERSISTENT_LIST_NETWORK_EVENT(devt, devId, res, len) \ + p2p_list_persistent_network_event((devt), (devId), (res), (len)) + +#define A_WMI_P2P_REQ_AUTH_EVENT(devt, devId, res, len) p2p_req_auth_event((devt), (devId), (res), (len)) + +#define A_WMI_GET_P2P_CTX(devt, devId, res, len) get_p2p_ctx((devt), (devId), (res), (len)) + +#define A_WMI_P2P_PROV_DISC_REQ(devt, devId, res, len) get_p2p_prov_disc_req((devt), (devId), (res), (len)) +#if 1 // KK +#define A_WMI_P2P_SERV_DISC_REQ(devt, devId, res, len) get_p2p_serv_disc_req((devt), (devId), (res), (len)) + +#define A_WMI_P2P_INVITE_REQ_RX(devt, devId, datap, len) p2p_invite_req_rx((devt), (devId), (datap), (len)) + +#define A_WMI_P2P_INVITE_RCVD_RESULT_EVENT(devt, devId, datap, len) \ + p2p_invite_rcvd_result_ev((devt), (devId), (datap), (len)) + +#define A_WMI_P2P_INVITE_SENT_RESULT_EVENT(devt, devId, res, len) \ + p2p_invite_sent_result_event((devt), (devId), (res), (len)) +#endif +#endif + +#define A_WMI_CHANNELLIST_RX(devt, devId, numChan, chanList) \ + Api_ChannelListEvent((devt), (devId), (numChan), (chanList)) + +#define A_WMI_SET_NUMDATAENDPTS(devt, num) + +#define A_WMI_CONTROL_TX(devt, osbuf, streamID) Api_WmiTxStart((devt), (osbuf), (streamID)) + +#define A_WMI_TARGETSTATS_EVENT(devt, devId, pStats, len) Api_TargetStatsEvent((devt), (devId), (pStats), (len)) + +#define A_WMI_SCANCOMPLETE_EVENT(devt, devId, status) Api_ScanCompleteEvent((devt), (devId), (status)) + +#define A_WMI_CONNECT_EVENT(devt, devId, channel, bssid, listenInterval, beaconInterval, networkType, beaconIeLen, \ + assocReqLen, assocRespLen, assocInfo) \ + Api_ConnectEvent((devt), (devId), (channel), (bssid), (listenInterval), (beaconInterval), (networkType), \ + (beaconIeLen), (assocReqLen), (assocRespLen), (assocInfo)) + +#define A_WMI_REGDOMAIN_EVENT(devt, devId, regCode) Api_RegDomainEvent((devt), (devId), (regCode)) + +#define A_WMI_DISCONNECT_EVENT(devt, devId, reason, bssid, assocRespLen, assocInfo, protocolReasonStatus) \ + Api_DisconnectEvent((devt), (devId), (reason), (bssid), (assocRespLen), (assocInfo), (protocolReasonStatus)) + +#define A_WMI_RSNA_SUCCESS_EVENT(devt, devId, code) Api_RSNASuccessEvent((devt), (devId), (code)) + +#define A_WMI_BITRATE_RX(devt, devId, rateKbps) Api_BitrateEvent((devt), (devId), (rateKbps)) + +/* A_WMI_TXPWR_RX - not currently supported */ +#define A_WMI_TXPWR_RX(devt, devId, txPwr) + +#define A_WMI_READY_EVENT(devt, devId, datap, phyCap, sw_ver, abi_ver) \ + Api_ReadyEvent((devt), (devId), (datap), (phyCap), (sw_ver), (abi_ver)) + +#define A_WMI_GET_BITRATE_EVEVT(devt, devId, datap) Api_GetBitRateEvent((devt), (devId), (datap)) + +#define A_WMI_SEND_EVENT_TO_APP(ar, eventId, datap, len) +#define A_WMI_SEND_GENERIC_EVENT_TO_APP(ar, eventId, datap, len) + +#define A_WMI_BSSINFO_EVENT_RX(ar, devId, datap, len) Api_BssInfoEvent((ar), (devId), (datap), (len)) + +#define A_WMI_TKIP_MICERR_EVENT(devt, devId, keyid, ismcast) Api_TkipMicErrorEvent((devt), (devId), (keyid), (ismcast)) + +#define A_WMI_Ac2EndpointID(devht, devId, ac) Driver_AC2EndpointID((devht), (devId), (ac)) + +#define A_WMI_Endpoint2Ac(devt, devId, ep) Driver_EndpointID2AC((devt), (devId), (ep)) + +#define A_WMI_GET_PMK_RX(devt, devId, datap) Api_GetPmkEvent((devt), (devId), (datap)) + +#define A_WMIX_DBGLOG_EVENT(wmip, devId, datap, len) Api_RxDbglogEvent((wmip), (devId), (datap), (len)) + +#define A_WMIX_GPIO_DATA_EVENT(wmip, devId, datap, len) Api_RxGpioDataEvent((wmip), (devId), (datap), (len)) + +#define WMIX_HB_CHALLENGE_RESP_RX(wmip, devId, datap, len) Api_RxHBChallengeEvent((wmip), (devId), (datap), (len)) + +#define A_WMIX_PFM_DATA_EVENT(wmip, devId, datap, len) Api_RxPfmDataEvent((wmip), (devId), (datap), (len)) + +#define A_WMIX_PFM_DATA_DONE_EVENT(wmip, devId, datap, len) Api_RxPfmDataDoneEvent((wmip), (devId), (datap), (len)) + +#if DRIVER_CONFIG_ENABLE_STORE_RECALL +#define A_WMI_STORERECALL_EVENT_RX(devt, devId, datap, len, osbuf) \ + Api_StoreRecallEvent((devt), (devId), (datap), (len), (osbuf)) +#else +#define A_WMI_STORERECALL_EVENT_RX(devt, devId, datap, len, osbuf) A_OK +#endif + +#define A_WMI_STORERECALL_START_EVENT_RX(devt, devId, datap, len, osbuf) \ + Api_StoreRecallStartEvent((devt), (devId), (datap), (len), (osbuf)) + +#define A_WMI_PROBE_REQ_EVENT_RX(devt, datap, len) Api_ProbeReqEvent((devt), (datap), (len)) + +#define A_WMI_HOST_DSET_EVENT_STORE_RX(devt, devId, datap, len, osbuf) \ + Api_HostDsetStoreEvent((devt), (devId), (datap), (len), (osbuf)) + +#define A_WMI_HOST_DSET_EVENT_READ_RX(devt, devId, datap, len, osbuf) \ + Api_HostDsetReadEvent((devt), (devId), (datap), (len), (osbuf)) + +#define A_WMI_HOST_DSET_EVENT_CREATE_RX(devt, devId, datap, len, osbuf) \ + Api_HostDsetCreateEvent((devt), (devId), (datap), (len), (osbuf)) + +#define A_WMI_HOST_DSET_EVENT_WRITE_RX(devt, devId, datap, len, osbuf) \ + Api_HostDsetWriteEvent((devt), (devId), (datap), (len), (osbuf)) + +#define A_WMI_HOST_DSET_EVENT_READBACK_RX(devt, devId, datap, len, osbuf) \ + Api_HostDsetReadbackEvent((devt), (devId), (datap), (len), (osbuf)) + +#define A_WMI_HOST_DSET_EVENT_SYNC_RX(devt, devId, datap, len, osbuf) \ + Api_HostDsetSyncEvent((devt), (devId), (datap), (len), (osbuf)) + +#define A_WMI_DSET_EVENT_OP_RX(devt, devId, datap, len, osbuf) Api_DsetOPEvent((devt), (devId), (datap), (len), (osbuf)) + +#define A_WMI_WPS_PROFILE_EVENT_RX(devt, devId, datap, len, osbuf) \ + Api_WpsProfileEvent((devt), (devId), (datap), (len), (osbuf)) + +#if WLAN_CONFIG_11N_AGGR_SUPPORT +#define A_WMI_AGGR_RECV_ADDBA_REQ_EVT(devt, devId, cmd) Api_AggrRecvAddbaReqEvent((devt), (devId), (cmd)) + +#define A_WMI_AGGR_RECV_DELBA_REQ_EVT(devt, devId, cmd) Api_AggrRecvDelbaReqEvent((devt), (devId), (cmd)) +#endif + +#define A_WMI_GET_TEMPERATURE_REPLY(devt, datap, len) Api_GetTemperatureReply((devt), (datap), (len)) + +#define A_WMI_GET_COUNTRY_CODE_REPLY(devt, datap, len) Api_GetCountryCodeReply((devt), (datap), (len)) +#define A_WMI_SET_PARAM_REPLY(devt, datap) Api_GetSetParamReply((devt), (datap)) +#define A_WMI_WLAN_WPS_INIT_REPLY_RX(devt, datap, len) Api_GetWpsInitReply((devt), (datap), (len)) + +#if ENABLE_STACK_OFFLOAD +#define A_WMI_SOCK_RESPONSE_EVENT_RX(devt, devId, datap, len, osbuf) \ + Api_SockResponseEventRx((devt), (devId), (datap), (len), (osbuf)) +#else +#define A_WMI_SOCK_RESPONSE_EVENT_RX(devt, devId, datap, len, osbuf) A_OK +#endif +#if MANUFACTURING_SUPPORT +#define A_WMI_TEST_CMD_EVENT_RX(devt, devId, datap, len) Api_TestCmdEventRx((devt), (devId), (datap), (len)) +#endif +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/mcu/lpc54102/wifi_qca/common_src/include/aggr_recv_api.h b/platform/mcu/lpc54102/wifi_qca/common_src/include/aggr_recv_api.h new file mode 100644 index 0000000000..c2e645e611 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/common_src/include/aggr_recv_api.h @@ -0,0 +1,108 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== + +#ifndef __AGGR_RECV_API_H__ +#define __AGGR_RECV_API_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*RX_CALLBACK)(void *dev, void *osbuf); + +typedef void (*ALLOC_NETBUFS)(A_NETBUF_QUEUE_T *q, uint16_t num); + +/* + * aggr_init: + * Initialises the data structures, allocates data queues and + * os buffers. Netbuf allocator is the input param, used by the + * aggr module for allocation of NETBUFs from driver context. + * These NETBUFs are used for AMSDU processing. + * Returns the context for the aggr module. + */ +void *aggr_init(void); + +/* + * aggr_deinit: + * Frees any allocated resources allocated by aggr_init. + */ +void aggr_deinit(void *cntxt); + +/* + * aggr_recv_addba_req_evt: + * This event is to initiate/modify the receive side window. + * Target will send WMI_ADDBA_REQ_EVENTID event to host - to setup + * recv re-ordering queues. Target will negotiate ADDBA with peer, + * and indicate via this event after succesfully completing the + * negotiation. This happens in two situations: + * 1. Initial setup of aggregation + * 2. Renegotiation of current recv window. + * Window size for re-ordering is limited by target buffer + * space, which is reflected in win_sz. + * (Re)Start the periodic timer to deliver long standing frames, + * in hold_q to OS. + */ +void aggr_recv_addba_req_evt(void *cntxt, uint8_t tid, uint16_t seq_no, uint8_t win_sz); + +/* + * aggr_recv_delba_req_evt: + * Target indicates deletion of a BA window for a tid via the + * WMI_DELBA_EVENTID. Host would deliver all the frames in the + * hold_q, reset tid config and disable the periodic timer, if + * aggr is not enabled on any tid. + */ +void aggr_recv_delba_req_evt(void *cntxt, uint8_t tid); + +/* + * aggr_process_recv_frm: + * Called only for data frames. When aggr is ON for a tid, the buffer + * is always consumed, and osbuf would be NULL. For a non-aggr case, + * osbuf is not modified. + * AMSDU frames are consumed and are later freed. They are sliced and + * diced to individual frames and dispatched to stack. + * After consuming a osbuf(when aggr is ON), a previously registered + * callback may be called to deliver frames in order. + */ +boolean aggr_process_recv_frm(void *cntxt, uint8_t tid, uint16_t seq_no, boolean is_amsdu, void **osbuf); + +/* + * aggr_module_destroy: + * Frees up all the queues and frames in them. Releases the cntxt to OS. + */ +void aggr_module_destroy(void *cntxt); + +/* + * aggr_reset_state -- Called when it is deemed necessary to clear the aggregate + * hold Q state. Examples include when a Connect event or disconnect event is + * received. + */ +void aggr_reset_state(void *cntxt); + +#ifdef __cplusplus +} +#endif + +#endif /*__AGGR_RECV_API_H__ */ diff --git a/platform/mcu/lpc54102/wifi_qca/common_src/include/bmi.h b/platform/mcu/lpc54102/wifi_qca/common_src/include/bmi.h new file mode 100644 index 0000000000..68af468c89 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/common_src/include/bmi.h @@ -0,0 +1,77 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== +#ifndef _BMI_H_ +#define _BMI_H_ + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Header files */ +#include "a_config.h" +#include "athdefs.h" +#include "a_types.h" +//#include "hif.h" +#include "a_osapi.h" +#include "bmi_msg.h" + +A_STATUS +BMIInit(void *pCxt); + +void BMICleanup(void); + +A_STATUS +BMIDone(void *pCxt); + +A_STATUS +BMIGetTargetInfo(void *pCxt, struct bmi_target_info *targ_info); + +A_STATUS +BMIReadMemory(void *pCxt, uint32_t address, uint8_t *buffer, uint32_t length); + +A_STATUS +BMIWriteMemory(void *pCxt, uint32_t address, uint8_t *buffer, uint32_t length); + +A_STATUS +BMIExecute(void *pCxt, uint32_t address, uint32_t *param); + +A_STATUS +BMIReadSOCRegister(void *pCxt, uint32_t address, uint32_t *param); + +A_STATUS +BMIWriteSOCRegister(void *pCxt, uint32_t address, uint32_t param); + +A_STATUS +BMIRawWrite(void *pCxt, uint8_t *buffer, uint32_t length); + +A_STATUS +BMIRawRead(void *pCxt, uint8_t *buffer, uint32_t length, boolean want_timeout); + +#ifdef __cplusplus +} +#endif + +#endif /* _BMI_H_ */ diff --git a/platform/mcu/lpc54102/wifi_qca/common_src/include/common_api.h b/platform/mcu/lpc54102/wifi_qca/common_src/include/common_api.h new file mode 100644 index 0000000000..115b6c8572 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/common_src/include/common_api.h @@ -0,0 +1,311 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== +#ifndef _COMMON_API_H_ +#define _COMMON_API_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include + +// IGX_UD_CHANGES +typedef struct hcd_intr_callback_t +{ + void *pCxt; +} HCD_INTR_CB, *HCD_INTR_CALLBACK_T; + +A_STATUS Driver_CreateThread(void *pCxt); + +A_STATUS Driver_DestroyThread(void *pCxt); + +void HW_EnableDisableIRQ(void *pCxt, boolean Enable, boolean FromIrq); + +A_STATUS HW_ProcessPendingInterrupts(void *pCxt); + +A_STATUS wmi_dset_host_cfg_cmd(void *handle); + +A_STATUS Driver_Init(void *pCxt); + +A_STATUS Driver_DeInit(void *pCxt); + +A_STATUS Driver_ContextInit(void *pCxt); + +A_STATUS Driver_ContextDeInit(void *pCxt); + +uint32_t Htc_ReadCreditCounter(void *pCxt, uint32_t index); + +void Htc_GetCreditCounterUpdate(void *pCxt, uint16_t epid); + +void Htc_PrepareRecvPacket(void *pCxt, void *pReq); + +A_STATUS Htc_SendPacket(void *pCxt, void *pReq); + +void Htc_RxComplete(void *pCxt, void *pReq); + +A_STATUS Htc_ProcessTxComplete(void *pCxt, void *pReq); + +A_STATUS Htc_ProcessRecvHeader(void *pCxt, void *pReq, uint32_t *pNextLookAheads, uint32_t *pNumLookAheads); + +A_STATUS HTC_Start(void *pCxt); + +A_STATUS HTC_WaitTarget(void *pCxt); + +A_STATUS HTC_ConnectService(void *pCxt, HTC_SERVICE_CONNECT_REQ *pConnectReq, HTC_SERVICE_CONNECT_RESP *pConnectResp); + +void HTC_ProcessCpuInterrupt(void *pCxt); + +void Hcd_Irq(void *pCxt); + +A_STATUS Driver_Main(void *pCxt, uint8_t scope, boolean *pCanBlock, uint16_t *pBlock_msec); + +#if defined(DRIVER_CONFIG_IMPLEMENT_RX_FREE_MULTIPLE_QUEUE) +void Driver_ReportRxBuffStatus(void *pCxt, boolean status, uint8_t epid); +#else +void Driver_ReportRxBuffStatus(void *pCxt, boolean status); +#endif + +A_STATUS Driver_CompleteRequest(void *pCxt, void *pReq); + +boolean Driver_TxReady(void *pCxt); + +A_STATUS Driver_SubmitTxRequest(void *pCxt, void *pReq); + +A_STATUS Driver_SubmitEp0TxRequest(void *pCxt, void *pReq); + +boolean Driver_RxReady(void *pCxt); + +void Driver_DropTxDataPackets(void *pCxt); + +A_STATUS Driver_SendPacket(void *pCxt, void *pReq); + +A_STATUS Driver_RecvPacket(void *pCxt, void *pReq); + +A_STATUS Driver_GetTargetInfo(void *pCxt); + +A_STATUS Driver_BootComm(void *pCxt); + +void Driver_RxComplete(void *pCxt, void *pReq); + +A_STATUS Driver_ReadRegDiag(void *pCxt, uint32_t *address, uint32_t *data); + +A_STATUS Driver_WriteRegDiag(void *pCxt, uint32_t *address, uint32_t *data); + +A_STATUS Driver_ReadDataDiag(void *pCxt, uint32_t address, uint8_t *data, uint32_t length); + +A_STATUS Driver_WriteDataDiag(void *pCxt, uint32_t address, uint8_t *data, uint32_t length); + +A_STATUS Driver_DumpAssertInfo(void *pCxt, uint32_t *pData, uint16_t *pLength); + +A_STATUS Driver_StoreRecallFirmwareDownload(void *pCxt); + +void HW_EnableDisableSPIIRQ(void *pCxt, boolean Enable, boolean FromIrq); + +void HW_PowerUpDown(void *pCxt, uint8_t powerUp); + +A_STATUS Bus_InOutToken(void *pCxt, uint32_t OutToken, uint8_t DataSize, uint32_t *pInToken); + +void Bus_TransferComplete(void *pCxt, A_STATUS status); + +void HW_InterruptHandler(void *pCxt); + +void Strrcl_Recall(void *pCxt, uint32_t msec_sleep); + +A_STATUS Hcd_ProgramWriteBufferWaterMark(void *pCxt, uint32_t length); + +void Hcd_RefreshWriteBufferSpace(void *pCxt); + +// Todo +A_STATUS Hcd_DoPioInternalAccess(void *pCxt, uint16_t addr, uint32_t *pValue, boolean isRead); + +/**********TBD**********/ +uint16_t Api_TxGetStatus(void *pCxt); + +void Api_TxComplete(void *pCxt, void *pReq); + +void Api_RxComplete(void *pCxt, void *pReq); + +A_STATUS Api_WmiTxStart(void *pCxt, void *pReq, HTC_ENDPOINT_ID eid); + +A_STATUS Api_DataTxStart(void *pCxt, void *pReq); + +void Api_BootProfile(void *pCxt, uint8_t val); + +A_STATUS Api_InitStart(void *pCxt); + +A_STATUS Api_InitFinish(void *pCxt); + +void Api_WMIInitFinish(void *pCxt); + +A_STATUS Api_DeInitStart(void *pCxt); + +A_STATUS Api_DeInitFinish(void *pCxt); + +A_STATUS Api_DisconnectWiFi(void *pCxt); + +A_STATUS Api_ConnectWiFi(void *pCxt); + +A_STATUS Api_ParseInfoElem(void *pCxt, WMI_BSS_INFO_HDR *bih, int32_t len, A_SCAN_SUMMARY *pSummary); + +A_STATUS Api_DriverAccessCheck(void *pCxt, uint8_t block_allowed, uint8_t request_reason); + +A_STATUS Api_ProgramCountryCode(void *pCxt, uint8_t *country_code, uint16_t length, uint8_t *pResult); + +A_STATUS Api_ProgramMacAddress(void *pCxt, uint8_t *addr, uint16_t length, uint8_t *pResult); + +A_STATUS Api_SetPowerMode(void *pCxt, POWER_MODE *pwrmode); + +uint32_t HW_GetMboxAddress(void *pCxt, uint16_t mbox, uint32_t length); + +A_ENDPOINT_T *Util_GetEndpoint(void *pCxt, uint16_t id); + +uint16_t Util_Ieee2freq(int32_t chan); + +uint32_t Util_Freq2ieee(uint16_t freq); + +HTC_ENDPOINT_ID Util_AC2EndpointID(void *pCxt, uint8_t ac); + +uint8_t Util_EndpointID2AC(void *pCxt, HTC_ENDPOINT_ID ep); + +uint8_t Util_Ascii2Hex(char val); + +A_STATUS scan_setup(void *pCxt, void *pWmi, WMI_START_SCAN_CMD *start_scan); + +A_STATUS wait_scan_done(void *pCxt, void *pWmi); + +A_STATUS move_power_state_to_maxperf(void *pCxt, int32_t module); + +A_STATUS TxRawPacket(void *pCxt, void *pReq, ATH_MAC_TX_PARAMS *pParams); + +#if MANUFACTURING_SUPPORT +void Api_Test_Cmd_Event(void *pCxt, uint8_t *datap, uint32_t len); +#endif + +#if MANUFACTURING_SUPPORT +#define API_TEST_RESP_EVENT(pCxt, datap, len) Api_Test_Cmd_Event((pCxt), (datap), (len)) +#endif + +void Driver_WakeDriver(void *pCxt); + +void Driver_WakeUser(void *pCxt); + + +#define DRIVER_WAKE_DRIVER(pCxt) Driver_WakeDriver((pCxt)) +#define DRIVER_WAKE_USER(pCxt) Driver_WakeUser((pCxt)) + +#if ENABLE_STACK_OFFLOAD + +#define SOCKET_CONTEXT_INIT socket_context_init() +#define STACK_INIT(pCxt) send_stack_init((pCxt)) +#define SOCKET_CONTEXT_DEINIT() socket_context_deinit() +#define MIN_HDR_LEN sizeof(WMI_DATA_HDR) +#define WMI_DOT3_2_DIX(pReq) A_OK + +#else + +#define STACK_INIT(pCxt) A_OK +#define SOCKET_CONTEXT_INIT A_OK +#define SOCKET_CONTEXT_DEINIT() A_OK +#define MIN_HDR_LEN sizeof(WMI_DATA_HDR) + sizeof(ATH_MAC_HDR) + sizeof(ATH_LLC_SNAP_HDR) +#define WMI_DOT3_2_DIX(pReq) wmi_dot3_2_dix((pReq)) + +#endif + +enum BOOT_PROFILE +{ + BOOT_PROFILE_WMI_READY = 0, + BOOT_PROFILE_READ_REFCLK, + BOOT_PROFILE_DONE_CONFIG, + BOOT_PROFILE_START_CONNECT, + BOOT_PROFILE_DONE_CONNECT, + BOOT_PROFILE_DRIVE_READY, + BOOT_PROFILE_START_SCAN, + BOOT_PROFILE_DONE_SCAN, + BOOT_PROFILE_POWER_UP, + BOOT_PROFILE_BOOT_PARAMETER, +}; + +#if ENABLE_P2P_MODE + +#define API_P2P_GO_NEG_EVENT(devt, devId, res, len, wps_info) \ + Api_p2p_go_neg_event((devt), (devId), (res), (len), (wps_info)) + +#define API_P2P_INVITE_SEND_RESULT(pCxt, devId, datap, len) Api_p2p_invite_send_result((pCxt), (devId), (datap), (len)) + +#define API_P2P_NODE_LIST_EVENT(devt, devId, res, len) Api_p2p_node_list_event((devt), (devId), (res), (len)) + +#define API_P2P_LIST_PERSISTENT_NETWORK_EVENT(devt, devId, res, len) \ + Api_p2p_list_persistent_network_event((devt), (devId), (res), (len)) + +#define API_GET_P2P_CTX(devt, devId, res, len) Api_get_p2p_ctx((devt), (devId), (res), (len)) + +#define API_P2P_PROV_DISC_REQ(devt, devId, res, len) Api_p2p_prov_disc_req((devt), (devId), (res), (len)) + +#define API_P2P_SERV_DISC_REQ(devt, devId, res, len) Api_p2p_serv_disc_req((devt), (devId), (res), (len)) + +#define API_P2P_INVITE_REQ(pCxt, devId, datap, len) Api_p2p_invite_req((pCxt), (devId), (datap), (len)) + +#define API_P2P_INVITE_RCVD_RESULT(pCxt, devId, datap, len) Api_p2p_invite_rcvd_result((pCxt), (devId), (datap), (len)) + +#define API_P2P_REQ_AUTH_EVENT(devt, devId, res, len) Api_p2p_req_auth_event((devt), (devId), (res), (len)) + +void Api_p2p_go_neg_event(void *pCxt, uint8_t devId, uint8_t *datap, uint32_t len, WMI_P2P_PROV_INFO *wps_info); + +void Api_p2p_invite_send_result(void *pCxt, uint8_t devId, uint8_t *datap, uint32_t len); + +void Api_p2p_node_list_event(void *pCxt, uint8_t devId, uint8_t *datap, uint32_t len); + +void Api_p2p_list_persistent_network_event(void *pCxt, uint8_t devId, uint8_t *datap, uint32_t len); + +void Api_get_p2p_ctx(void *pCxt, uint8_t devId, uint8_t *datap, uint32_t len); + +void Api_p2p_prov_disc_req(void *pCxt, uint8_t devId, uint8_t *datap, uint32_t len); + +void Api_p2p_serv_disc_req(void *pCxt, uint8_t devId, uint8_t *datap, uint32_t len); + +void Api_p2p_invite_req(void *pCxt, uint8_t devId, uint8_t *datap, uint32_t len); + +void Api_p2p_req_auth_event(void *pCxt, uint8_t devId, uint8_t *datap, uint32_t len); + +void Api_p2p_invite_rcvd_result(void *pCxt, uint8_t devId, uint8_t *datap, uint32_t len); +#endif // ENABLE_P2P_MODE + +#if MANUFACTURING_SUPPORT +#define API_TEST_RESP_EVENT(pCxt, datap, len) Api_Test_Cmd_Event((pCxt), (datap), (len)) + +void Api_Test_Cmd_Event(void *pCxt, uint8_t *datap, uint32_t len); + +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* _COMMON_API_H_ */ diff --git a/platform/mcu/lpc54102/wifi_qca/common_src/include/dbglog_api.h b/platform/mcu/lpc54102/wifi_qca/common_src/include/dbglog_api.h new file mode 100644 index 0000000000..54115fdc4b --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/common_src/include/dbglog_api.h @@ -0,0 +1,49 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== +#ifndef _DBGLOG_API_H_ +#define _DBGLOG_API_H_ + +#ifdef __cplusplus +extern "C" { +#endif +#if 0 +#include "dbglog.h" + +#define DBGLOG_HOST_LOG_BUFFER_SIZE DBGLOG_LOG_BUFFER_SIZE + +#define DBGLOG_GET_DBGID(arg) ((arg & DBGLOG_DBGID_MASK) >> DBGLOG_DBGID_OFFSET) + +#define DBGLOG_GET_MODULEID(arg) ((arg & DBGLOG_MODULEID_MASK) >> DBGLOG_MODULEID_OFFSET) + +#define DBGLOG_GET_NUMARGS(arg) ((arg & DBGLOG_NUM_ARGS_MASK) >> DBGLOG_NUM_ARGS_OFFSET) + +#define DBGLOG_GET_TIMESTAMP(arg) ((arg & DBGLOG_TIMESTAMP_MASK) >> DBGLOG_TIMESTAMP_OFFSET) +#endif +#ifdef __cplusplus +} +#endif + +#endif /* _DBGLOG_API_H_ */ diff --git a/platform/mcu/lpc54102/wifi_qca/common_src/include/driver_cxt.h b/platform/mcu/lpc54102/wifi_qca/common_src/include/driver_cxt.h new file mode 100644 index 0000000000..70bd373fb5 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/common_src/include/driver_cxt.h @@ -0,0 +1,369 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== +#ifndef _DRIVER_CXT_H_ +#define _DRIVER_CXT_H_ + +#include "a_types.h" +#include +#include +#include +#include "ieee80211.h" +#include "atheros_wifi.h" + +#define MIN_STRRCL_MSEC (100) + +#define AR4100_DEFAULT_CREDIT_COUNT 6 + +#define AR4100_BUFFER_SIZE 1664 + +#define AR4100_MAX_AMSDU_RX_BUFFERS 4 +#define AR4100_AMSDU_REFILL_THRESHOLD 3 + +#define AR4100_AMSDU_BUFFER_SIZE (WMI_MAX_AMSDU_RX_DATA_FRAME_LENGTH + 128) + +#if WLAN_CONFIG_AMSDU_ON_HOST +#define AR4100_MAX_RX_MESSAGE_SIZE (max(WMI_MAX_NORMAL_RX_DATA_FRAME_LENGTH, WMI_MAX_AMSDU_RX_DATA_FRAME_LENGTH)) +/* The RX MESSAGE SIZE is ultimately dictated by the size of the firmware buffers used to + * hold packets. This is because any remaining space may be used by HTC for trailers. hence + * a full size buffer must be anticipated by the host. */ +#else +#define AR4100_MAX_RX_MESSAGE_SIZE (AR4100_BUFFER_SIZE) +#endif + +#define MAX_NUM_CHANLIST_CHANNELS (16) + +#define MAX_WEP_KEY_SZ (16) + +#define STRRCL_ST_DISABLED 0 +#define STRRCL_ST_INIT 1 +#define STRRCL_ST_START 2 +#define STRRCL_ST_ACTIVE 3 +#define STRRCL_ST_ACTIVE_B 4 +#define STRRCL_ST_AWAIT_FW 5 + +#define AES_KEY_SIZE_BYTES 16 + +#define ACCESS_REQUEST_IOCTL 0 +#define ACCESS_REQUEST_TX 1 +#define ACCESS_REQUEST_RX 2 + +#define DRIVER_SCOPE_RX 0x01 +#define DRIVER_SCOPE_TX 0x02 + +#define DRIVER_STATE_IDLE 0x00 /* the driver task is idle/sleeping */ +#define DRIVER_STATE_RX_PROCESSING 0x01 /* the driver task is processing a RX request */ +#define DRIVER_STATE_TX_PROCESSING 0x02 /* the driver task is processing a TX request */ +#define DRIVER_STATE_INTERRUPT_PROCESSING 0x03 /* the driver task is processing a chip Interrupt */ +#define DRIVER_STATE_ASYNC_PROCESSING 0x04 /* the driver task is processing an asynch operation */ +#define DRIVER_STATE_PENDING_CONDITION_A 0x05 /* the driver task is waiting for a condition to be met */ +#define DRIVER_STATE_PENDING_CONDITION_B 0x06 +#define DRIVER_STATE_PENDING_CONDITION_C 0x07 +#define DRIVER_STATE_PENDING_CONDITION_D 0x08 +#define DRIVER_STATE_PENDING_CONDITION_E 0x09 +#define DRIVER_STATE_PENDING_CONDITION_F 0x0a +#define DRIVER_STATE_PENDING_CONDITION_G 0x0b + +#define MAX_CREDIT_DEADLOCK_ATTEMPTS 2 +#define DEADLOCK_BLOCK_MSEC 10 + +typedef struct ar_wep_key +{ + uint8_t keyLen; + uint8_t key[MAX_WEP_KEY_SZ]; +} A_WEPKEY_T; + +/* A_SCAN_SUMMARY provides useful information that + * has been parsed from bss info headers and probe/beacon information elements. + */ +typedef struct scan_summary +{ + uint16_t beacon_period; + uint16_t caps; + uint8_t bssid[6]; + uint8_t ssid[32]; + uint8_t channel; + uint8_t ssid_len; + uint8_t rssi; + uint8_t bss_type; + uint8_t rsn_cipher; + uint8_t rsn_auth; + uint8_t wpa_cipher; + uint8_t wpa_auth; + uint8_t wep_support; + uint8_t reserved; // keeps struct on 4-byte boundary +} A_SCAN_SUMMARY; + +typedef struct +{ + uint16_t maxMsgLength; + uint16_t serviceID; + uint32_t intCredits; + uint8_t intCreditCounter; + uint8_t rptCreditCounter; + uint8_t epIdx; + uint8_t credits; + uint8_t maxCredits; + uint8_t seqNo; +} A_ENDPOINT_T; + +#if USE_16BIT_CREDIT_COUNTER +typedef struct +{ + uint16_t maxMsgLength; + uint16_t serviceID; + uint32_t intCredits; + uint16_t intCreditCounter; + uint16_t rptCreditCounter; + uint8_t epIdx; + uint8_t rsvd; + uint16_t credits; + uint16_t maxCredits; + uint8_t seqNo; +} A_ENDPOINT_T; +#endif + +typedef A_STATUS (*TEMP_FUNC_T)(void *pCxt); + +typedef struct _a_connection_elements +{ + int32_t ssidLen; + uint8_t ssid[32]; + uint8_t networkType; /* one of NETWORK_TYPE enum */ + uint32_t connectCtrlFlags; + uint8_t dot11AuthMode; + uint8_t wpaAuthMode; + uint8_t wpaPairwiseCrypto; + uint8_t wpaPairwiseCryptoLen; + uint8_t wpaGroupCrypto; + uint8_t wpaGroupCryptoLen; + uint8_t wepDefTxKeyIndex; + A_WEPKEY_T wepKeyList[WMI_MAX_KEY_INDEX + 1]; + uint8_t wpaPmk[WMI_PMK_LEN]; + boolean wpaPmkValid; + uint8_t bssid[ATH_MAC_LEN]; + uint8_t reqBssid[ATH_MAC_LEN]; + uint16_t channelHint; + uint16_t bssChannel; + boolean isConnected; + boolean isConnectPending; + uint8_t phyMode; +} A_CONNECTION_ELEMENTS_T; + +typedef struct _a_spi_hcd_context +{ +#define SDHD_BOOL_SHUTDOWN 0x00000001 +#define SDHD_BOOL_EXTERNALIO_PENDING 0x00000002 +#define SDHD_BOOL_DMA_WRITE_WAIT_FOR_BUFFER 0x00000004 +#define SDHD_BOOL_DMA_IN_PROG 0x00000008 +#define SDHD_BOOL_TRANSFER_DIR_RX 0x00000010 +#define SDHD_BOOL_HOST_DMA_COPY_MODE 0x00000020 +#define SDHD_BOOL_HOST_ACCESS_COPY_MODE 0x00000040 +#define SDHD_BOOL_FATAL_ERROR 0x00000080 +#define SDHD_BOOL_DMA_COMPLETE 0x00000100 + +#define BYTE_SWAP true +#define NO_BYTE_SWAP false + + /******************************************* + * + * the following fields must be filled in by the hardware specific layer + * + ********************************************/ + // from SDHCD START HERE + uint8_t PendingIrqAcks; /* mask of pending interrupts that have not been ACK'd */ + uint8_t IrqsEnabled; + uint8_t IrqDetected; + // from SDHCD END HERE + uint8_t CpuInterrupt; + uint8_t CpuInterruptCause; + + uint16_t SpiIntEnableShadow; /* shadow copy of interrupt enables */ + uint16_t SpiConfigShadow; /* shadow copy of configuration register */ + uint16_t irqMask; + uint8_t HostAccessDataWidth; /* data width to use for host access */ + uint8_t DMADataWidth; /* data width to use for DMA access */ + uint32_t ReadBufferSpace; /* cached copy of read buffer available register */ + uint32_t WriteBufferSpace; /* cached copy of space remaining in the SPI write buffer */ + uint32_t MaxWriteBufferSpace; /* max write buffer space that the SPI interface supports */ + uint32_t PktsInSPIWriteBuffer; /* number of packets in SPI write buffer so far */ + void *pCurrentRequest; /* pointer to a request in-progress used only for deferred SPI ops. */ + + uint32_t OperationalClock; /* spi module operational clock */ + uint32_t PowerUpDelay; /* delay before the common layer should initialize over spi */ +/* SPI SPECIFICE ELEMENTS Starts here */ +#define HW_SPI_FRAME_WIDTH_8 0x01 +#define HW_SPI_FRAME_WIDTH_16 0x02 +#define HW_SPI_FRAME_WIDTH_24 0x04 +#define HW_SPI_FRAME_WIDTH_32 0x08 +#define HW_SPI_INT_EDGE_DETECT 0x80 +#define HW_SPI_NO_DMA 0x40 + uint8_t SpiHWCapabilitiesFlags; /* SPI hardware capabilities flags */ + +#define MISC_FLAG_SPI_SLEEP_WAR 0x04 +#define MISC_FLAG_RESET_SPI_IF_SHUTDOWN 0x02 +#define MISC_FLAG_DUMP_STATE_ON_SHUTDOWN 0x01 + uint8_t MiscFlags; + A_MUTEX_T lock; +} A_SPI_HCD_CXT; + +typedef struct _a_driver_context +{ + uint16_t driver_state; /* maintains current state of driver one of DRIVER_STATE_... */ + uint8_t txQueryResult; + boolean txQueryInProgress; + boolean driver_up; /* maintains driver status for external access */ + boolean chipDown; + boolean rxBufferStatus; /* maintains available status of rx buffers */ + boolean creditDeadlock; + uint32_t creditDeadlockCounter; + A_NETBUF_QUEUE_T txQueue; + void *pRxReq; + A_ENDPOINT_T ep[ENDPOINT_MANAGED_MAX]; + HTC_ENDPOINT_ID ac2EpMapping[WMM_NUM_AC]; + uint8_t ep2AcMapping[ENDPOINT_MAX]; + uint16_t creditCount; /* number of tx credits available at init */ + uint16_t creditSize; // size in bytes of a credit + /* the 5 version values maintained by the context */ + uint32_t targetType; /* general type value */ + uint32_t targetVersion; /* identifies the target chip */ + uint32_t wlanVersion; /* identifies firmware running on target chip */ + uint32_t abiVersion; /* identifies the interface compatible with wlan firmware */ + uint32_t hostVersion; /* identifies version of host driver */ + + uint8_t phyCapability; /* identifies chip phy capability */ + boolean wmiReady; + boolean wmiEnabled; + void *pWmiCxt; /* context for wmi driver component */ + void *pAggrCxt; /* context for rx aggregate driver component */ + uint16_t txAggrTidMask; + uint16_t rxAggrTidMask; + + int8_t numChannels; + uint16_t channelList[MAX_NUM_CHANLIST_CHANNELS]; + + uint32_t regCode; + int8_t rssi; + int32_t bitRate; + boolean wmmEnabled; + boolean tx_complete_pend; /* tracks new tx completes for task sync */ + TEMP_FUNC_T asynchRequest; + /* STORE&RECALL SPECIFICE ELEMENTS Starts here */ + void *strrclCxt; + int32_t strrclCxtLen; + boolean strrclBlock; + uint8_t strrclState; + /* STORE&RECALL SPECIFICE ELEMENTS Ends here */ + /* WPS SPECIFICE ELEMENTS Starts here */ + void *wpsBuf; + void *wpsEvent; + boolean wpsState; + /* WPS SPECIFIC ELEMENTS Ends here */ + uint8_t userPwrMode; + uint8_t tkipCountermeasures; + /* CONNECT SPECIFIC ELEMENTS Start Here */ + uint8_t devId; + A_CONNECTION_ELEMENTS_T conn[WLAN_NUM_OF_DEVICES]; + /* CONNECT SPECIFIC ELEMENTS End Here */ + /* from hif_device START HERE */ + uint16_t enabledSpiInts; + uint32_t lookAhead; + uint32_t mboxAddress; /* the address for mailbox reads/writes. */ + uint32_t blockSize; /* the mailbox block size */ + uint32_t blockMask; /* the mask derived from BlockSize */ + uint32_t *padBuffer; + uint16_t booleans; + /* from hif_device ENDS HERE */ + /* SPI SPECIFICE ELEMENTS Starts here */ + A_SPI_HCD_CXT spi_hcd; + + /* SPI SPECIFIC ELEMENTS Ends here */ + boolean scanDone; /* scan done indicator, set by WMI_SCAN_COMPLETE_EVENTID */ + boolean driverSleep; + boolean htcStart; + uint8_t htc_creditInit; + uint8_t *tempStorage; /*temporary storage shared by independent modules*/ + uint16_t tempStorageLength; /*size of temp storage allocated at init time, decided by feature set*/ + uint8_t promiscuous_mode; /* if 1 promiscuous mode is enabled */ + boolean rssiFlag; + + uint8_t apmodeWPS; +#if ENABLE_P2P_MODE + boolean p2p_avail; + uint8_t wpsRole; +#endif + boolean macProgramming; +#if MANUFACTURING_SUPPORT + boolean testResp; +#endif + uint8_t rxMultiBufferStatus; /* maintains available status of rx buffers */ + boolean pfmDone; /* scan done indicator, set by WMI_SCAN_COMPLETE_EVENTID */ + boolean wps_in_progress; + uint32_t pwrStateSetting; + boolean dset_op_done; /* dset op done indicator, set by WMI_SCAN_COMPLETE_EVENTID */ + uint8_t raw_temperature; /*register value */ + uint32_t tempDegree; /*temperature degree*/ + boolean temperatureValid; + uint8_t raw_countryCode[3]; + boolean countryCodeValid; + boolean setparamValid; + uint32_t setparamStatus; +/* PORT_NOTE: rxFreeQueue stores pre-allocated rx net-buffers. If dynamic heap +* allocation is preferred for RX net-buffers then this option should be disabled. */ +#if DRIVER_CONFIG_IMPLEMENT_RX_FREE_QUEUE + A_NETBUF_QUEUE_T rxFreeQueue; +#endif + + /* PORT_NOTE: pScanOut stores scan results in a buffer so that they + * can be retrieved aysnchronously by a User task. */ + uint8_t *pScanOut; /* callers buffer to hold results. */ + uint16_t scanOutSize; /* size of pScanOut buffer */ + uint16_t scanOutCount; /* current fill count of pScanOut buffer */ + + boolean driverShutdown; /* used to shutdown the driver */ + uint32_t line; + uint8_t securityType; /* used to satisfy SEC_TYPE */ + uint8_t extended_scan; /* used to indicate whether an extended scan is in progress */ +#if ENABLE_P2P_MODE + void *p2pevtCB; + boolean p2pEvtState; + boolean p2pevtflag; +#endif +#if MANUFACTURING_SUPPORT + uint32_t testCmdRespBufLen; +#endif + boolean wps_init_key; + uint32_t hb_sequence; + boolean hb_challenge_done; + WMI_SCAN_PARAMS_CMD scan_param; // save scan parameters for roam mode change +} A_DRIVER_CONTEXT; + +extern uint32_t last_driver_error; + +#define DEV_CALC_RECV_PADDED_LEN(pDCxt, length) (((length) + (pDCxt)->blockMask) & (~((pDCxt)->blockMask))) +#define DEV_CALC_SEND_PADDED_LEN(pDCxt, length) DEV_CALC_RECV_PADDED_LEN(pDCxt, length) +#define DEV_IS_LEN_BLOCK_ALIGNED(pDCxt, length) (((length) % (pDCxt)->blockSize) == 0) + +#endif /* _DRIVER_CXT_H_ */ diff --git a/platform/mcu/lpc54102/wifi_qca/common_src/include/dset.h b/platform/mcu/lpc54102/wifi_qca/common_src/include/dset.h new file mode 100644 index 0000000000..67853fee55 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/common_src/include/dset.h @@ -0,0 +1,98 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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******************************************************************** +* +* +* $FileName: dset.h$ +* $Version : 3.8.40.0$ +* $Date : May-28-2014$ +* +* Comments: +* +* This file contains the defines, externs and data +* structure definitions required by application +* programs in order to use the Ethernet packet driver. +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*END************************************************************************/ +#ifndef __dset_h__ +#define __dset_h__ + +/*--------------------------------------------------------------------------*/ +/* +** CONSTANT DEFINITIONS +*/ + +#define MAX_DSET_SIZE 16 + +/*--------------------------------------------------------------------------*/ +/* +** TYPE DEFINITIONS +*/ + +typedef struct host_dset_struct +{ + uint32_t dset_id; /* dset id */ + uint32_t length; /* dset length */ + uint8_t *data_ptr; /* dset buffer address */ +} HOST_DSET; + +typedef struct host_dset_item +{ + uint32_t dset_id; /* dset id */ + uint32_t length; /* dset length */ +} HOST_DSET_ITEM; + +/*--------------------------------------------------------------------------*/ +/* +** PROTOTYPES AND GLOBAL EXTERNS +*/ + +HOST_DSET *dset_find(uint32_t dset_id); +HOST_DSET *dset_get(uint32_t dset_id, uint32_t length); +uint32_t dset_write(HOST_DSET *pDset, uint8_t *pData, uint32_t offset, uint32_t length); +uint32_t dset_read(HOST_DSET *pDset, uint8_t *pData, uint32_t offset, uint32_t length); +uint32_t dset_fill(uint8_t *pData, uint32_t max_dset_count); + +HOST_DSET *dset_get_first(void); +HOST_DSET *dset_get_next(void); + +#endif diff --git a/platform/mcu/lpc54102/wifi_qca/common_src/include/dset_api.h b/platform/mcu/lpc54102/wifi_qca/common_src/include/dset_api.h new file mode 100644 index 0000000000..3df793c093 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/common_src/include/dset_api.h @@ -0,0 +1,145 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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******************************************************************** +* +* +* +* $FileName: dset.h$ +* $Version : 3.8.40.0$ +* $Date : May-28-2014$ +* +* Comments: +* +* This file contains the defines, externs and data +* structure definitions required by application +* programs in order to use the Ethernet packet driver. +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*END************************************************************************/ +#ifndef __dset_api_h__ +#define __dset_api_h__ + +/*--------------------------------------------------------------------------*/ +/* +** CONSTANT DEFINITIONS +*/ + +#define MAX_HOST_DSET_SIZE 8 + +#define INVALID_DSET_ID 0 + +typedef enum __DSET_OP +{ + DSET_OP_CREATE = 1, + DSET_OP_OPEN = 2, + DSET_OP_READ = 3, + DSET_OP_WRITE = 4, + DSET_OP_COMMIT = 5, + DSET_OP_CLOSE = 6, + DSET_OP_SIZE = 7, + DSET_OP_DELETE = 8, +} DSET_OP; + +#define MAX_DSET_BUFF_SIZE 1500 + +/*--------------------------------------------------------------------------*/ +/* +** TYPE DEFINITIONS +*/ + +typedef void (*dset_callback_fn_t)(uint32_t status, void *pv); + +typedef struct host_api_dset_struct +{ + uint32_t dset_id; /* dset id */ + uint32_t media_id; + uint32_t flags; + uint32_t offset; /* dset offset */ + uint32_t length; /* dset length */ + uint32_t left_len; /* for large read/write */ + dset_callback_fn_t cb; + void *cb_args; + uint8_t done_flag; + uint8_t *data_ptr; /* dset buffer address */ +} HOST_DSET_HANDLE; + +// typedef struct host_dset_item { +// uint32_t dset_id; /* dset id */ +// uint32_t length; /* dset length */ +//} HOST_DSET_ITEM; + +/*--------------------------------------------------------------------------*/ +/* +** PROTOTYPES AND GLOBAL EXTERNS +*/ + +extern HOST_DSET_HANDLE dset_handles[]; + +HOST_DSET_HANDLE *dset_find_handle(uint32_t dset_id); + +int32_t qcom_dset_create(HOST_DSET_HANDLE **pDsetHandle, + uint32_t dset_id, + uint32_t media_id, + uint32_t length, + uint32_t flags, + dset_callback_fn_t create_cb, + void *callback_arg); +int32_t qcom_dset_open( + HOST_DSET_HANDLE **pDsetHandle, uint32_t dset_id, uint32_t flags, dset_callback_fn_t open_cb, void *callback_arg); +uint32_t qcom_dset_write(HOST_DSET_HANDLE *pDsetHandle, + uint8_t *buffer, + uint32_t length, + uint32_t offset, + uint32_t flags, + dset_callback_fn_t write_cb, + void *callback_arg); +uint32_t qcom_dset_read(HOST_DSET_HANDLE *pDsetHandle, + uint8_t *buffer, + uint32_t length, + uint32_t offset, + dset_callback_fn_t read_cb, + void *callback_arg); +uint32_t qcom_dset_commit(HOST_DSET_HANDLE *pDsetHandle, dset_callback_fn_t read_cb, void *callback_arg); +uint32_t qcom_dset_close(HOST_DSET_HANDLE *pDsetHandle, dset_callback_fn_t read_cb, void *callback_arg); +uint32_t qcom_dset_size(HOST_DSET_HANDLE *pDsetHandle, dset_callback_fn_t read_cb, void *callback_arg); +uint32_t qcom_dset_delete(uint32_t dset_id, uint32_t flags, dset_callback_fn_t read_cb, void *callback_arg); + +#endif diff --git a/platform/mcu/lpc54102/wifi_qca/common_src/include/hif_internal.h b/platform/mcu/lpc54102/wifi_qca/common_src/include/hif_internal.h new file mode 100644 index 0000000000..53d9f14f99 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/common_src/include/hif_internal.h @@ -0,0 +1,46 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== +#ifndef _HIF_INTERNAL_H_ +#define _HIF_INTERNAL_H_ + +#define HIF_ACTIVE_MBOX_INDEX (0) + +#define HIF_MBOX_BLOCK_SIZE 32 +#define HIF_MBOX_BASE_ADDR 0x800 +#define HIF_MBOX_WIDTH 0x800 +#define HIF_MBOX0_BLOCK_SIZE HIF_MBOX_BLOCK_SIZE +#define HIF_MBOX1_BLOCK_SIZE HIF_MBOX_BLOCK_SIZE +#define HIF_MBOX2_BLOCK_SIZE HIF_MBOX_BLOCK_SIZE +#define HIF_MBOX3_BLOCK_SIZE HIF_MBOX_BLOCK_SIZE + +#define SPI_CLOCK_FREQUENCY_DEFAULT 24000000 +#define SPI_CLOCK_FREQUENCY_REDUCED 12000000 + +#define HIF_MBOX_START_ADDR(mbox) HIF_MBOX_BASE_ADDR + mbox *HIF_MBOX_WIDTH + +#define HIF_MBOX_END_ADDR(mbox) HIF_MBOX_START_ADDR(mbox) + HIF_MBOX_WIDTH - 1 + +#endif /* _HIF_INTERNAL_H_ */ diff --git a/platform/mcu/lpc54102/wifi_qca/common_src/include/htc_api.h b/platform/mcu/lpc54102/wifi_qca/common_src/include/htc_api.h new file mode 100644 index 0000000000..fe102b9bbf --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/common_src/include/htc_api.h @@ -0,0 +1,80 @@ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== + +#ifndef _HTC_API_H_ +#define _HTC_API_H_ + +#include + +typedef uint16_t HTC_SERVICE_ID; + +#define HTC_MAILBOX_NUM_MAX 4 + +/* ------ Endpoint IDS ------ */ +typedef enum +{ + ENDPOINT_UNUSED = -1, + ENDPOINT_0 = 0, + ENDPOINT_1, + ENDPOINT_2, + ENDPOINT_MANAGED_MAX, + ENDPOINT_3 = ENDPOINT_2 + 1, + ENDPOINT_4, + ENDPOINT_5, +#if WLAN_CONFIG_TRUNCATED_ENDPOINTS + ENDPOINT_MAX +#else + ENDPOINT_6, + ENDPOINT_7, + ENDPOINT_8, + ENDPOINT_MAX +#endif +} HTC_ENDPOINT_ID; + +/* service connection information */ +typedef struct _HTC_SERVICE_CONNECT_REQ +{ + HTC_SERVICE_ID ServiceID; /* service ID to connect to */ + uint16_t ConnectionFlags; /* connection flags, see htc protocol definition */ + uint8_t *pMetaData; /* ptr to optional service-specific meta-data */ + uint8_t MetaDataLength; /* optional meta data length */ + int32_t MaxSendQueueDepth; /* maximum depth of any send queue */ + uint32_t LocalConnectionFlags; /* HTC flags for the host-side (local) connection */ + uint32_t MaxSendMsgSize; /* override max message size in send direction */ +} HTC_SERVICE_CONNECT_REQ; + +#define HTC_LOCAL_CONN_FLAGS_ENABLE_SEND_BUNDLE_PADDING (1 << 0) /* enable send bundle padding for this endpoint */ + +/* service connection response information */ +typedef struct _HTC_SERVICE_CONNECT_RESP +{ + uint8_t *pMetaData; /* caller supplied buffer to optional meta-data */ + uint8_t BufferLength; /* length of caller supplied buffer */ + uint8_t ActualLength; /* actual length of meta data */ + HTC_ENDPOINT_ID Endpoint; /* endpoint to communicate over */ + uint32_t MaxMsgLength; /* max length of all messages over this endpoint */ + uint8_t ConnectRespCode; /* connect response code from target */ +} HTC_SERVICE_CONNECT_RESP; + +#endif /* _HTC_API_H_ */ diff --git a/platform/mcu/lpc54102/wifi_qca/common_src/include/ieee80211.h b/platform/mcu/lpc54102/wifi_qca/common_src/include/ieee80211.h new file mode 100644 index 0000000000..954aacae45 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/common_src/include/ieee80211.h @@ -0,0 +1,388 @@ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== + +#ifndef _NET80211_IEEE80211_H_ +#define _NET80211_IEEE80211_H_ + +/* + * 802.11 protocol definitions. + */ +#define IEEE80211_WEP_KEYLEN 5 /* 40bit */ +#define IEEE80211_WEP_IVLEN 3 /* 24bit */ +#define IEEE80211_WEP_KIDLEN 1 /* 1 octet */ +#define IEEE80211_WEP_CRCLEN 4 /* CRC-32 */ +#define IEEE80211_WEP_NKID 4 /* number of key ids */ + +/* + * 802.11i defines an extended IV for use with non-WEP ciphers. + * When the EXTIV bit is set in the key id byte an additional + * 4 bytes immediately follow the IV for TKIP. For CCMP the + * EXTIV bit is likewise set but the 8 bytes represent the + * CCMP header rather than IV+extended-IV. + */ +#define IEEE80211_WEP_EXTIV 0x20 +#define IEEE80211_WEP_EXTIVLEN 4 /* extended IV length */ +#define IEEE80211_WEP_MICLEN 8 /* trailing MIC */ + +#define IEEE80211_CRC_LEN 4 + +#ifdef WAPI_ENABLE +#define IEEE80211_WAPI_EXTIVLEN 10 /* extended IV length */ +#endif /* WAPI ENABLE */ + +#define IEEE80211_ADDR_LEN 6 /* size of 802.11 address */ +/* is 802.11 address multicast/broadcast? */ +#define IEEE80211_IS_MULTICAST(_a) (*(_a)&0x01) +#define IEEE80211_IS_BROADCAST(_a) (*(_a) == 0xFF) +#define WEP_HEADER (IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN) +#define WEP_TRAILER IEEE80211_WEP_CRCLEN +#define CCMP_HEADER (IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN + IEEE80211_WEP_EXTIVLEN) +#define CCMP_TRAILER IEEE80211_WEP_MICLEN +#define TKIP_HEADER (IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN + IEEE80211_WEP_EXTIVLEN) +#define TKIP_TRAILER IEEE80211_WEP_CRCLEN +#define TKIP_MICLEN IEEE80211_WEP_MICLEN + +#define IEEE80211_ADDR_EQ(addr1, addr2) (A_MEMCMP(addr1, addr2, IEEE80211_ADDR_LEN) == 0) + +#define IEEE80211_ADDR_COPY(dst, src) A_MEMCPY(dst, src, IEEE80211_ADDR_LEN) + +#define IEEE80211_KEYBUF_SIZE 16 +#define IEEE80211_MICBUF_SIZE (8 + 8) /* space for both tx and rx */ + +/* + * NB: these values are ordered carefully; there are lots of + * of implications in any reordering. In particular beware + * that 4 is not used to avoid conflicting with IEEE80211_F_PRIVACY. + */ +#define IEEE80211_CIPHER_WEP 0 +#define IEEE80211_CIPHER_TKIP 1 +#define IEEE80211_CIPHER_AES_OCB 2 +#define IEEE80211_CIPHER_AES_CCM 3 +#define IEEE80211_CIPHER_CKIP 5 +#define IEEE80211_CIPHER_CCKM_KRK 6 +#define IEEE80211_CIPHER_NONE 7 /* pseudo value */ + +#define IEEE80211_CIPHER_MAX (IEEE80211_CIPHER_NONE + 1) + +#define IEEE80211_IS_VALID_WEP_CIPHER_LEN(len) (((len) == 5) || ((len) == 13) || ((len) == 16)) + +/* + * generic definitions for IEEE 802.11 frames + */ +PREPACK struct ieee80211_frame +{ + uint8_t i_fc[2] FIELD_PACKED; + uint8_t i_dur[2] FIELD_PACKED; + uint8_t i_addr1[IEEE80211_ADDR_LEN] FIELD_PACKED; + uint8_t i_addr2[IEEE80211_ADDR_LEN] FIELD_PACKED; + uint8_t i_addr3[IEEE80211_ADDR_LEN] FIELD_PACKED; + uint8_t i_seq[2] FIELD_PACKED; + /* possibly followed by addr4[IEEE80211_ADDR_LEN]; */ + /* see below */ +} POSTPACK; + +PREPACK struct ieee80211_qosframe +{ + uint8_t i_fc[2] FIELD_PACKED; + uint8_t i_dur[2] FIELD_PACKED; + uint8_t i_addr1[IEEE80211_ADDR_LEN] FIELD_PACKED; + uint8_t i_addr2[IEEE80211_ADDR_LEN] FIELD_PACKED; + uint8_t i_addr3[IEEE80211_ADDR_LEN] FIELD_PACKED; + uint8_t i_seq[2] FIELD_PACKED; + uint8_t i_qos[2] FIELD_PACKED; +} POSTPACK; + +#define IEEE80211_FC0_VERSION_MASK 0x03 +#define IEEE80211_FC0_VERSION_SHIFT 0 +#define IEEE80211_FC0_VERSION_0 0x00 +#define IEEE80211_FC0_TYPE_MASK 0x0c +#define IEEE80211_FC0_TYPE_SHIFT 2 +#define IEEE80211_FC0_TYPE_MGT 0x00 +#define IEEE80211_FC0_TYPE_CTL 0x04 +#define IEEE80211_FC0_TYPE_DATA 0x08 + +#define IEEE80211_FC0_SUBTYPE_MASK 0xf0 +#define IEEE80211_FC0_SUBTYPE_SHIFT 4 +/* for TYPE_MGT */ +#define IEEE80211_FC0_SUBTYPE_ASSOC_REQ 0x00 +#define IEEE80211_FC0_SUBTYPE_ASSOC_RESP 0x10 +#define IEEE80211_FC0_SUBTYPE_REASSOC_REQ 0x20 +#define IEEE80211_FC0_SUBTYPE_REASSOC_RESP 0x30 +#define IEEE80211_FC0_SUBTYPE_PROBE_REQ 0x40 +#define IEEE80211_FC0_SUBTYPE_PROBE_RESP 0x50 +#define IEEE80211_FC0_SUBTYPE_BEACON 0x80 +#define IEEE80211_FC0_SUBTYPE_ATIM 0x90 +#define IEEE80211_FC0_SUBTYPE_DISASSOC 0xa0 +#define IEEE80211_FC0_SUBTYPE_AUTH 0xb0 +#define IEEE80211_FC0_SUBTYPE_DEAUTH 0xc0 +/* for TYPE_CTL */ +#define IEEE80211_FC0_SUBTYPE_PS_POLL 0xa0 +#define IEEE80211_FC0_SUBTYPE_RTS 0xb0 +#define IEEE80211_FC0_SUBTYPE_CTS 0xc0 +#define IEEE80211_FC0_SUBTYPE_ACK 0xd0 +#define IEEE80211_FC0_SUBTYPE_CF_END 0xe0 +#define IEEE80211_FC0_SUBTYPE_CF_END_ACK 0xf0 +/* for TYPE_DATA (bit combination) */ +#define IEEE80211_FC0_SUBTYPE_DATA 0x00 +#define IEEE80211_FC0_SUBTYPE_CF_ACK 0x10 +#define IEEE80211_FC0_SUBTYPE_CF_POLL 0x20 +#define IEEE80211_FC0_SUBTYPE_CF_ACPL 0x30 +#define IEEE80211_FC0_SUBTYPE_NODATA 0x40 +#define IEEE80211_FC0_SUBTYPE_CFACK 0x50 +#define IEEE80211_FC0_SUBTYPE_CFPOLL 0x60 +#define IEEE80211_FC0_SUBTYPE_CF_ACK_CF_ACK 0x70 +#define IEEE80211_FC0_SUBTYPE_QOS 0x80 +#define IEEE80211_FC0_SUBTYPE_QOS_NULL 0xc0 + +#define IEEE80211_FC1_DIR_MASK 0x03 +#define IEEE80211_FC1_DIR_NODS 0x00 /* STA->STA */ +#define IEEE80211_FC1_DIR_TODS 0x01 /* STA->AP */ +#define IEEE80211_FC1_DIR_FROMDS 0x02 /* AP ->STA */ +#define IEEE80211_FC1_DIR_DSTODS 0x03 /* AP ->AP */ + +#define IEEE80211_FC1_MORE_FRAG 0x04 +#define IEEE80211_FC1_RETRY 0x08 +#define IEEE80211_FC1_PWR_MGT 0x10 +#define IEEE80211_FC1_MORE_DATA 0x20 +#define IEEE80211_FC1_WEP 0x40 +#define IEEE80211_FC1_ORDER 0x80 + +#define IEEE80211_SEQ_FRAG_MASK 0x000f +#define IEEE80211_SEQ_FRAG_SHIFT 0 +#define IEEE80211_SEQ_SEQ_MASK 0xfff0 +#define IEEE80211_SEQ_SEQ_SHIFT 4 + +#define IEEE80211_NWID_LEN 32 + +/* + * 802.11 rate set. + */ +#define IEEE80211_RATE_SIZE 8 /* 802.11 standard */ +#define IEEE80211_RATE_MAXSIZE 15 /* max rates we'll handle */ + +#define WMM_NUM_AC 4 /* 4 AC categories */ + +#define WMM_PARAM_ACI_M 0x60 /* Mask for ACI field */ +#define WMM_PARAM_ACI_S 5 /* Shift for ACI field */ +#define WMM_PARAM_ACM_M 0x10 /* Mask for ACM bit */ +#define WMM_PARAM_ACM_S 4 /* Shift for ACM bit */ +#define WMM_PARAM_AIFSN_M 0x0f /* Mask for aifsn field */ +#define WMM_PARAM_LOGCWMIN_M 0x0f /* Mask for CwMin field (in log) */ +#define WMM_PARAM_LOGCWMAX_M 0xf0 /* Mask for CwMax field (in log) */ +#define WMM_PARAM_LOGCWMAX_S 4 /* Shift for CwMax field */ + +#define WMM_AC_TO_TID(_ac) (((_ac) == WMM_AC_VO) ? 6 : ((_ac) == WMM_AC_VI) ? 5 : ((_ac) == WMM_AC_BK) ? 1 : 0) + +#define TID_TO_WMM_AC(_tid) (((_tid) < 1) ? WMM_AC_BE : ((_tid) < 3) ? WMM_AC_BK : ((_tid) < 6) ? WMM_AC_VI : WMM_AC_VO) +/* + * Management information element payloads. + */ + +enum +{ + IEEE80211_ELEMID_SSID = 0, + IEEE80211_ELEMID_RATES = 1, + IEEE80211_ELEMID_FHPARMS = 2, + IEEE80211_ELEMID_DSPARMS = 3, + IEEE80211_ELEMID_CFPARMS = 4, + IEEE80211_ELEMID_TIM = 5, + IEEE80211_ELEMID_IBSSPARMS = 6, + IEEE80211_ELEMID_COUNTRY = 7, + IEEE80211_ELEMID_CHALLENGE = 16, + /* 17-31 reserved for challenge text extension */ + IEEE80211_ELEMID_PWRCNSTR = 32, + IEEE80211_ELEMID_PWRCAP = 33, + IEEE80211_ELEMID_TPCREQ = 34, + IEEE80211_ELEMID_TPCREP = 35, + IEEE80211_ELEMID_SUPPCHAN = 36, + IEEE80211_ELEMID_CHANSWITCH = 37, + IEEE80211_ELEMID_MEASREQ = 38, + IEEE80211_ELEMID_MEASREP = 39, + IEEE80211_ELEMID_QUIET = 40, + IEEE80211_ELEMID_IBSSDFS = 41, + IEEE80211_ELEMID_ERP = 42, + IEEE80211_ELEMID_HTCAP_ANA = 45, /* Address ANA, and non-ANA story, for interop. CL#171733 */ + IEEE80211_ELEMID_RSN = 48, + IEEE80211_ELEMID_XRATES = 50, + IEEE80211_ELEMID_HTINFO_ANA = 61, +#ifdef WAPI_ENABLE + IEEE80211_ELEMID_WAPI = 68, +#endif + IEEE80211_ELEMID_TPC = 150, + IEEE80211_ELEMID_CCKM = 156, + IEEE80211_ELEMID_VENDOR = 221 /* vendor private */ +}; + +#define ATH_OUI 0x7f0300 /* Atheros OUI */ +#define ATH_OUI_TYPE 0x01 +#define ATH_OUI_SUBTYPE 0x01 +#define ATH_OUI_VERSION 0x00 + +#define WPA_OUI 0xf25000 +#define WPA_OUI_TYPE 0x01 +#define WPA_VERSION 1 /* current supported version */ + +#define WPA_CSE_NULL 0x00 +#define WPA_CSE_WEP40 0x01 +#define WPA_CSE_TKIP 0x02 +#define WPA_CSE_CCMP 0x04 +#define WPA_CSE_WEP104 0x05 + +#define WPA_ASE_NONE 0x00 +#define WPA_ASE_8021X_UNSPEC 0x01 +#define WPA_ASE_8021X_PSK 0x02 + +#define RSN_OUI 0xac0f00 +#define RSN_VERSION 1 /* current supported version */ + +#define RSN_CSE_NULL 0x00 +#define RSN_CSE_WEP40 0x01 +#define RSN_CSE_TKIP 0x02 +#define RSN_CSE_WRAP 0x03 +#define RSN_CSE_CCMP 0x04 +#define RSN_CSE_WEP104 0x05 + +#define RSN_ASE_NONE 0x00 +#define RSN_ASE_8021X_UNSPEC 0x01 +#define RSN_ASE_8021X_PSK 0x02 + +#define RSN_CAP_PREAUTH 0x01 + +#define WMM_OUI 0xf25000 +#define WMM_OUI_TYPE 0x02 +#define WMM_INFO_OUI_SUBTYPE 0x00 +#define WMM_PARAM_OUI_SUBTYPE 0x01 +#define WMM_VERSION 1 + +/* WMM stream classes */ +#define WMM_NUM_AC 4 +#define WMM_AC_BE 0 /* best effort */ +#define WMM_AC_BK 1 /* background */ +#define WMM_AC_VI 2 /* video */ +#define WMM_AC_VO 3 /* voice */ + +/* TSPEC related */ +#define ACTION_CATEGORY_CODE_TSPEC 17 +#define ACTION_CODE_TSPEC_ADDTS 0 +#define ACTION_CODE_TSPEC_ADDTS_RESP 1 +#define ACTION_CODE_TSPEC_DELTS 2 + +typedef enum +{ + TSPEC_STATUS_CODE_ADMISSION_ACCEPTED = 0, + TSPEC_STATUS_CODE_ADDTS_INVALID_PARAMS = 0x1, + TSPEC_STATUS_CODE_ADDTS_REQUEST_REFUSED = 0x3, + TSPEC_STATUS_CODE_UNSPECIFIED_QOS_RELATED_FAILURE = 0xC8, + TSPEC_STATUS_CODE_REQUESTED_REFUSED_POLICY_CONFIGURATION = 0xC9, + TSPEC_STATUS_CODE_INSUFFCIENT_BANDWIDTH = 0xCA, + TSPEC_STATUS_CODE_INVALID_PARAMS = 0xCB, + TSPEC_STATUS_CODE_DELTS_SENT = 0x30, + TSPEC_STATUS_CODE_DELTS_RECV = 0x31 +} TSPEC_STATUS_CODE; + +#define TSPEC_TSID_MASK 0xF +#define TSPEC_TSID_S 1 + +/* + * WMM/802.11e Tspec Element + */ +typedef PREPACK struct wmm_tspec_ie_t +{ + uint8_t elementId FIELD_PACKED; + uint8_t len FIELD_PACKED; + uint8_t oui[3] FIELD_PACKED; + uint8_t ouiType FIELD_PACKED; + uint8_t ouiSubType FIELD_PACKED; + uint8_t version FIELD_PACKED; + uint16_t tsInfo_info FIELD_PACKED; + uint8_t tsInfo_reserved FIELD_PACKED; + uint16_t nominalMSDU FIELD_PACKED; + uint16_t maxMSDU FIELD_PACKED; + uint32_t minServiceInt FIELD_PACKED; + uint32_t maxServiceInt FIELD_PACKED; + uint32_t inactivityInt FIELD_PACKED; + uint32_t suspensionInt FIELD_PACKED; + uint32_t serviceStartTime FIELD_PACKED; + uint32_t minDataRate FIELD_PACKED; + uint32_t meanDataRate FIELD_PACKED; + uint32_t peakDataRate FIELD_PACKED; + uint32_t maxBurstSize FIELD_PACKED; + uint32_t delayBound FIELD_PACKED; + uint32_t minPhyRate FIELD_PACKED; + uint16_t sba FIELD_PACKED; + uint16_t mediumTime FIELD_PACKED; +} POSTPACK WMM_TSPEC_IE; + +/* + * BEACON management packets + * + * octet timestamp[8] + * octet beacon interval[2] + * octet capability information[2] + * information element + * octet elemid + * octet length + * octet information[length] + */ + +#define IEEE80211_BEACON_INTERVAL(beacon) ((beacon)[8] | ((beacon)[9] << 8)) +#define IEEE80211_BEACON_CAPABILITY(beacon) ((beacon)[10] | ((beacon)[11] << 8)) + +#define IEEE80211_CAPINFO_ESS 0x0001 +#define IEEE80211_CAPINFO_IBSS 0x0002 +#define IEEE80211_CAPINFO_CF_POLLABLE 0x0004 +#define IEEE80211_CAPINFO_CF_POLLREQ 0x0008 +#define IEEE80211_CAPINFO_PRIVACY 0x0010 +#define IEEE80211_CAPINFO_SHORT_PREAMBLE 0x0020 +#define IEEE80211_CAPINFO_PBCC 0x0040 +#define IEEE80211_CAPINFO_CHNL_AGILITY 0x0080 +/* bits 8-9 are reserved */ +#define IEEE80211_CAPINFO_SHORT_SLOTTIME 0x0400 +#define IEEE80211_CAPINFO_APSD 0x0800 +/* bit 12 is reserved */ +#define IEEE80211_CAPINFO_DSSSOFDM 0x2000 +/* bits 14-15 are reserved */ + +/* + * Authentication Modes + */ + +enum ieee80211_authmode +{ + IEEE80211_AUTH_NONE = 0, + IEEE80211_AUTH_OPEN = 1, + IEEE80211_AUTH_SHARED = 2, + IEEE80211_AUTH_8021X = 3, + IEEE80211_AUTH_AUTO = 4, /* auto-select/accept */ + /* NB: these are used only for ioctls */ + IEEE80211_AUTH_WPA = 5, /* WPA/RSN w/ 802.1x */ + IEEE80211_AUTH_WPA_PSK = 6, /* WPA/RSN w/ PSK */ + IEEE80211_AUTH_WPA_CCKM = 7 /* WPA/RSN IE w/ CCKM */ +}; + +#define IEEE80211_PS_MAX_QUEUE 50 /*Maximum no of buffers that can be queues for PS*/ + +#define IEEE80211_TKIP_COUNTERMEASURES_TIMEOUT_MSEC (60000) + +#endif /* _NET80211_IEEE80211_H_ */ diff --git a/platform/mcu/lpc54102/wifi_qca/common_src/include/netbuf.h b/platform/mcu/lpc54102/wifi_qca/common_src/include/netbuf.h new file mode 100644 index 0000000000..711913fd39 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/common_src/include/netbuf.h @@ -0,0 +1,178 @@ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== + +#ifndef _NETBUF_H_ +#define _NETBUF_H_ + +#include +#include +#include + +/* + * Network buffer queue support + */ +typedef struct +{ + void *head; + void *tail; + uint16_t count; +} A_NETBUF_QUEUE_T; + +typedef void (*A_TRANS_CB)(void *, void *); + +/* A_TRANSPORT_OBJ - the structure used to encapsulate any/all bus requests */ +typedef struct _transport_obj +{ + uint32_t lookahead; /* expected lookahead value for sanity checking */ + uint16_t transferLength; /* total transfer length including any pad bytes */ + uint16_t address; /* register address from which the transfer will begin */ + uint16_t cmd; /* bit field containing command values */ + uint8_t credits; /* num credits consumed by this request (TX only) */ + uint8_t epid; /* endpoint ID */ + A_STATUS status; /* transport status */ + A_TRANS_CB cb; /* callback to be used upon completion */ +} A_TRANSPORT_OBJ; + +#define A_NETBUF_QUEUE_INIT(q) a_netbuf_queue_init(q) + +#define A_NETBUF_ENQUEUE(q, pReq) a_netbuf_enqueue((q), (pReq)) +#define A_NETBUF_PREQUEUE(q, pReq) a_netbuf_prequeue((q), (pReq)) +#define A_NETBUF_DEQUEUE(q) (a_netbuf_dequeue((q))) +#define A_NETBUF_PEEK_QUEUE(q) ((A_NETBUF_QUEUE_T *)(q))->head +#define A_NETBUF_QUEUE_SIZE(q) ((A_NETBUF_QUEUE_T *)(q))->count +#define A_NETBUF_QUEUE_EMPTY(q) (!((A_NETBUF_QUEUE_T *)(q))->count) + +/* + * receiver buffer + */ + +#define A_RXBUF_ENQUEUE(q, pReq) a_rxbuf_enqueue((q), (pReq)) +#define A_RXBUF_DEQUEUE(q) (a_rxbuf_dequeue((q))) + +void a_netbuf_enqueue(A_NETBUF_QUEUE_T *q, void *pReq); +void a_netbuf_prequeue(A_NETBUF_QUEUE_T *q, void *pReq); +void *a_netbuf_dequeue(A_NETBUF_QUEUE_T *q); + +void a_rxbuf_enqueue(A_NETBUF_QUEUE_T *q, void *pReq); +void *a_rxbuf_dequeue(A_NETBUF_QUEUE_T *q); + +// int32_t a_netbuf_queue_size(A_NETBUF_QUEUE_T *q); +// int32_t a_netbuf_queue_empty(A_NETBUF_QUEUE_T *q); +void a_netbuf_queue_init(A_NETBUF_QUEUE_T *q); +// void *a_netbuf_peek_queue(A_NETBUF_QUEUE_T *q); + +#define MAX_NUM_FREE_QUEUES 8 +#define AR6000_DATA_OFFSET 64 + +typedef struct mgmt_credits +{ + uint16_t rxMaxBufferSizeInQueues; + uint8_t rxMaxBuffersInQueues; + uint8_t rxQueueMask; + uint8_t credit_count; + uint8_t init_credits; +} MGMT_CREDITS; + +extern uint8_t send_reverse_credits_flag; +extern MGMT_CREDITS host_credits[MAX_NUM_FREE_QUEUES]; + +extern A_NETBUF_QUEUE_T rxFreeQueues[MAX_NUM_FREE_QUEUES]; + +#if defined(DRIVER_CONFIG_IMPLEMENT_RX_FREE_MULTIPLE_QUEUE) +extern uint8_t credits_test; +#endif + +// extern uint16_t rxMaxBuffersInQueues[MAX_NUM_FREE_QUEUES]; +// extern uint16_t rxMaxBufferSizeInQueues[MAX_NUM_FREE_QUEUES]; +// extern uint8_t rxQueueMask[MAX_NUM_FREE_QUEUES]; + +#define GET_NUM_CREDIT_QUEUES() (MAX_NUM_FREE_QUEUES) + +#define GET_MAX_BUFFERS_IN_QUEUE(i) (MAX_BUFFERS_IN_QUEUE_##i) + +#define GET_INIT_CREDITS_IN_QUEUES(a) \ + a[0].init_credits = GET_MAX_BUFFERS_IN_QUEUE(0); \ + a[1].init_credits = GET_MAX_BUFFERS_IN_QUEUE(1); \ + a[2].init_credits = GET_MAX_BUFFERS_IN_QUEUE(2); \ + a[3].init_credits = GET_MAX_BUFFERS_IN_QUEUE(3); \ + a[4].init_credits = GET_MAX_BUFFERS_IN_QUEUE(4); \ + a[5].init_credits = GET_MAX_BUFFERS_IN_QUEUE(5); \ + a[6].init_credits = GET_MAX_BUFFERS_IN_QUEUE(6); \ + a[7].init_credits = GET_MAX_BUFFERS_IN_QUEUE(7); + +#define GET_MAX_BUFFERS_IN_QUEUES(a) \ + a[0].rxMaxBuffersInQueues = GET_MAX_BUFFERS_IN_QUEUE(0); \ + a[1].rxMaxBuffersInQueues = GET_MAX_BUFFERS_IN_QUEUE(1); \ + a[2].rxMaxBuffersInQueues = GET_MAX_BUFFERS_IN_QUEUE(2); \ + a[3].rxMaxBuffersInQueues = GET_MAX_BUFFERS_IN_QUEUE(3); \ + a[4].rxMaxBuffersInQueues = GET_MAX_BUFFERS_IN_QUEUE(4); \ + a[5].rxMaxBuffersInQueues = GET_MAX_BUFFERS_IN_QUEUE(5); \ + a[6].rxMaxBuffersInQueues = GET_MAX_BUFFERS_IN_QUEUE(6); \ + a[7].rxMaxBuffersInQueues = GET_MAX_BUFFERS_IN_QUEUE(7); + +#define GET_BUFFER_SIZE_IN_QUEUE(i) (BUFFER_SIZE_IN_QUEUE_##i) + +#define GET_BUFFER_SIZE_IN_QUEUES(a) \ + a[0].rxMaxBufferSizeInQueues = GET_BUFFER_SIZE_IN_QUEUE(0); \ + a[1].rxMaxBufferSizeInQueues = GET_BUFFER_SIZE_IN_QUEUE(1); \ + a[2].rxMaxBufferSizeInQueues = GET_BUFFER_SIZE_IN_QUEUE(2); \ + a[3].rxMaxBufferSizeInQueues = GET_BUFFER_SIZE_IN_QUEUE(3); \ + a[4].rxMaxBufferSizeInQueues = GET_BUFFER_SIZE_IN_QUEUE(4); \ + a[5].rxMaxBufferSizeInQueues = GET_BUFFER_SIZE_IN_QUEUE(5); \ + a[6].rxMaxBufferSizeInQueues = GET_BUFFER_SIZE_IN_QUEUE(6); \ + a[7].rxMaxBufferSizeInQueues = GET_BUFFER_SIZE_IN_QUEUE(7); + +#define QUEUE_MASK(i) (QUEUE_MASK_##i) + +#define GET_MASK_ALL_QUEUES(a) \ + a[0].rxQueueMask = QUEUE_MASK(0); \ + a[1].rxQueueMask = QUEUE_MASK(1); \ + a[2].rxQueueMask = QUEUE_MASK(2); \ + a[3].rxQueueMask = QUEUE_MASK(3); \ + a[4].rxQueueMask = QUEUE_MASK(4); \ + a[5].rxQueueMask = QUEUE_MASK(5); \ + a[6].rxQueueMask = QUEUE_MASK(6); \ + a[7].rxQueueMask = QUEUE_MASK(7); + +#define GET_FREE_QUEUE(i) (rxFreeQueues[i]) + +#define GET_QUEUE_BUFFER_SIZE(i) (host_credits[i].rxMaxBufferSizeInQueues + AR6000_DATA_OFFSET) +#define GET_QUEUE_DATA_BUFFER_SIZE(i) (host_credits[i].rxMaxBufferSizeInQueues) +#define GET_MAX_NUM_BUFFERS(i) (host_credits[i].rxMaxBuffersInQueues) +#define GET_QUEUE_MASK(i) (host_credits[i].rxQueueMask) +#define CREDIT_INC(i) \ + { \ + if (credits_test == 0) \ + host_credits[i].credit_count++; \ + } +#define CREDIT_ADD(i, c) \ + { \ + host_credits[i].credit_count += c; \ + } +#define CREDIT_DEC(i) (host_credits[i].credit_count--) +#define GET_CREDIT(i) (host_credits[i].credit_count) +#define GET_INIT_CREDITS(i) (host_credits[i].init_credits) +#define CLEAR_CREDIT(i) (host_credits[i].credit_count = 0) + +#endif /* _NETBUF_H_ */ diff --git a/platform/mcu/lpc54102/wifi_qca/common_src/include/spi_hcd_if.h b/platform/mcu/lpc54102/wifi_qca/common_src/include/spi_hcd_if.h new file mode 100644 index 0000000000..c9bc18eadb --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/common_src/include/spi_hcd_if.h @@ -0,0 +1,246 @@ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== + +#ifndef __SPI_HCD_IF_H___ +#define __SPI_HCD_IF_H___ + +typedef uint8_t ATH_TRANS_CMD; + +/* transfer SPI frame size flags for HCD internal use */ +#define ATH_TRANS_DS_8 0x00 +#define ATH_TRANS_DS_16 0x01 +#define ATH_TRANS_DS_24 0x02 /* 24 bit transfer, for HCD internal use only! */ +#define ATH_TRANS_DS_32 0x03 + +#define ATH_TRANS_DS_MASK 0x03 +#define ATH_TRANS_DMA 0x04 /* special DMA transfer */ +#define ATH_TRANS_TYPE_MASK 0x07 +/* register access is internal or external */ +#define ATH_TRANS_INT_TRANS 0x00 /* internal register (SPI internal) transfer */ +#define ATH_TRANS_EXT_TRANS 0x10 /* external register transfer */ +/* transfer to fixed or incrementing address (external transfers only) */ +#define ATH_TRANS_EXT_TRANS_ADDR_INC 0x00 +#define ATH_TRANS_EXT_TRANS_ADDR_FIXED 0x20 +/* direction of operation */ +#define ATH_TRANS_READ 0x80 +#define ATH_TRANS_WRITE 0x00 + +#define ATH_TRANS_EXT_MAX_PIO_BYTES 32 + +/* address mask */ +#define ATH_TRANS_ADDR_MASK 0x7FFF +/* macro to get the transfer type from a command */ +#define ATH_GET_TRANS_TYPE(cmd) ((cmd)&ATH_TRANS_TYPE_MASK) +/* macro to get the transfer data size */ +#define ATH_GET_TRANS_DS(cmd) ((cmd)&ATH_TRANS_DS_MASK) + +#define ATH_TRANS_IS_DIR_READ(cmd) ((cmd)&ATH_TRANS_READ) +#define ATH_TRANS_IS_DIR_WRITE(cmd) !ATH_TRANS_IS_DIR_READ(cmd) + +/* macros for passing values in writes and getting read data and status values */ +#define ATH_GET_PIO_WRITE_VALUE(pReq) GET_REQ_HEADER_ELEM((pReq), A_REQ_HEADER_DATA)[0] +#define ATH_SET_PIO_WRITE_VALUE(pReq, v) GET_REQ_HEADER_ELEM((pReq), A_REQ_HEADER_DATA)[0] = (UINT32)(v) +#define ATH_GET_PIO_INTERNAL_READ_RESULT(pReq) (UINT16) GET_REQ_HEADER_ELEM((pReq), A_REQ_HEADER_DATA)[1] +#define ATH_SET_PIO_INTERNAL_READ_RESULT(pReq, result) \ + GET_REQ_HEADER_ELEM((pReq), A_REQ_HEADER_DATA)[1] = (UINT32)(result) + +#define ATH_GET_IO_CMD(pReq) A_NETBUF_GET_ELEM((pReq), A_REQ_COMMAND) +#define ATH_SET_IO_CMD(pReq, cmd) A_NETBUF_SET_ELEM((pReq), A_REQ_COMMAND, (cmd)) +#define ATH_GET_IO_DS(pReq) ATH_GET_TRANS_DS(ATH_GET_IO_CMD(pReq)) + +#define ATH_GET_IO_ADDRESS(pReq) A_NETBUF_GET_ELEM((pReq), A_REQ_ADDRESS) +#define ATH_SET_IO_ADDRESS(pReq, addr) A_NETBUF_SET_ELEM((pReq), A_REQ_ADDRESS, (addr)) +#define ATH_GET_DMA_TRANSFER_BYTES(pReq) A_NETBUF_GET_ELEM((pReq), A_REQ_TRANSFER_LEN) +#define ATH_GET_EXT_TRANSFER_BYTES(pReq) A_NETBUF_LEN(pReq) +#define ATH_SET_TRANSFER_BYTES(pReq, bytes) A_NETBUF_SET_ELEM((pReq), A_REQ_TRANSFER_LEN, (bytes)) + +#define ATH_IS_TRANS_READ(pReq) (ATH_TRANS_IS_DIR_READ(ATH_GET_IO_CMD(pReq))) +#define ATH_IS_TRANS_WRITE(pReq) (!ATH_IS_TRANS_READ(pReq)) +#define ATH_IS_TRANS_DMA(pReq) (ATH_GET_IO_CMD(pReq) & ATH_TRANS_DMA) +#define ATH_IS_TRANS_PIO(pReq) (!ATH_IS_TRANS_DMA(pReq)) +#define ATH_IS_TRANS_PIO_EXTERNAL(pReq) (ATH_GET_IO_CMD(pReq) & ATH_TRANS_EXT_TRANS) +#define ATH_IS_TRANS_PIO_INTERNAL(pReq) !ATH_IS_TRANS_PIO_EXTERNAL(pReq) +#define ATH_IS_TRANS_EXT_ADDR_FIXED(pReq) (ATH_GET_IO_CMD(pReq) & ATH_TRANS_EXT_TRANS_ADDR_FIXED) +#define ATH_IS_TRANS_EXT_ADDR_INC(pReq) !ATH_IS_TRANS_EXT_ADDR_FIXED(pReq) + +/* macros to setup PIO write transfer requests */ +#define ATH_SET_PIO_INTERNAL_WRITE_OPERATION(pReq, addr, value) \ + \ +{ \ + ATH_SET_IO_CMD(pReq, ATH_TRANS_WRITE | ATH_TRANS_INT_TRANS); \ + ATH_SET_IO_ADDRESS(pReq, (uint16_t)((addr)&ATH_TRANS_ADDR_MASK)); \ + ATH_SET_PIO_WRITE_VALUE(pReq, value); \ + \ +} + +/* macros to setup PIO read transfer requests */ +#define ATH_SET_PIO_INTERNAL_READ_OPERATION(pReq, addr) \ + \ +{ \ + ATH_SET_IO_CMD(pReq, ATH_TRANS_READ | ATH_TRANS_INT_TRANS); \ + ATH_SET_IO_ADDRESS(pReq, (uint16_t)((addr)&ATH_TRANS_ADDR_MASK)); \ + \ +} + +/* macro to setup external register transfer request + * note: caller must set pReq->pDataBuffer separately */ +#define ATH_SET_PIO_EXTERNAL_OPERATION(pReq, type, addr, incaddr, length) \ + \ +{ \ + ATH_SET_IO_CMD(pReq, (type) | ATH_TRANS_EXT_TRANS | \ + ((incaddr) ? ATH_TRANS_EXT_TRANS_ADDR_INC : ATH_TRANS_EXT_TRANS_ADDR_FIXED)); \ + ATH_SET_IO_ADDRESS(pReq, (uint16_t)((addr)&ATH_TRANS_ADDR_MASK)); \ + ATH_SET_TRANSFER_BYTES(pReq, (uint16_t)(length)); \ + \ +} + +#define ATH_SET_PIO_EXTERNAL_WRITE_OPERATION(pReq, addr, incaddr, length) \ + ATH_SET_PIO_EXTERNAL_OPERATION(pReq, ATH_TRANS_WRITE, addr, incaddr, length) + +#define ATH_SET_PIO_EXTERNAL_READ_OPERATION(pReq, addr, incaddr, length) \ + ATH_SET_PIO_EXTERNAL_OPERATION(pReq, ATH_TRANS_READ, addr, incaddr, length) + +/* macros to setup DMA transfer requests, 64K max transfers + * note, the caller must set pReq->pDataBuffer separately + * and the number bytes (length) must be aligned to the DMA data width */ +#define ATH_SET_DMA_OPERATION(pReq, dir, addr, length) \ + \ +{ \ + ATH_SET_IO_CMD(pReq, ATH_TRANS_DMA | (dir)); \ + ATH_SET_IO_ADDRESS(pReq, (UINT16)((addr)&ATH_TRANS_ADDR_MASK)); \ + ATH_SET_TRANSFER_BYTES(pReq, (UINT16)(length)); \ + \ +} + +#define ATH_SPI_DMA_SIZE_REG (0x0100) /* internal */ +#define ATH_SPI_DMA_SIZE_MAX (4095) /* 12 bit counter 0-4095 are valid */ + +#define ATH_SPI_WRBUF_SPC_AVA_REG (0x0200) /* internal */ + +#define ATH_SPI_RDBUF_BYTE_AVA_REG (0x0300) /* internal */ + +#define ATH_SPI_CONFIG_REG (0x0400) /* internal */ +#define ATH_SPI_CONFIG_RESET (1 << 15) /* SPI interface reset */ +#define ATH_SPI_CONFIG_MBOX_INTR_EN (1 << 8) +#define ATH_SPI_CONFIG_IO_ENABLE (1 << 7) +#define ATH_SPI_CONFIG_CORE_RESET (1 << 6) /* core reset */ +#define ATH_SPI_CONFIG_KEEP_AWAKE_ON_INTR (1 << 4) +#define ATH_SPI_CONFIG_KEEP_AWAKE (1 << 3) +#define ATH_SPI_CONFIG_BYTE_SWAP (1 << 2) +#define ATH_SPI_CONFIG_SWAP_16BIT (1 << 1) +#define ATH_SPI_CONFIG_PREFETCH_MODE_RR (1 << 0) + +#define ATH_SPI_CONFIG_MISO_MUXSEL_MASK_SHIFT 9 + +#define ATH_SPI_STATUS_REG (0x0500) /* internal */ +#define ATH_SPI_STATUS_MBOX_FLOW_CTRL (1 << 5) +#define ATH_SPI_STATUS_WRBUF_ERROR (1 << 4) +#define ATH_SPI_STATUS_RDBUF_ERROR (1 << 3) +#define ATH_SPI_STATUS_RTC_STATE_MASK (0x3 << 1) +#define ATH_SPI_STATUS_RTC_STATE_WAKEUP (0x3 << 1) +#define ATH_SPI_STATUS_RTC_STATE_SLEEP (0x2 << 1) +#define ATH_SPI_STATUS_RTC_STATE_ON (0x1 << 1) +#define ATH_SPI_STATUS_RTC_STATE_SHUTDOWN (0x0) +#define ATH_SPI_STATUS_HOST_ACCESS_DONE (1 << 0) +#define ATH_SPI_STATUS_ERRORS (ATH_SPI_STATUS_WRBUF_ERROR | ATH_SPI_STATUS_RDBUF_ERROR) + +#define ATH_SPI_HOST_CTRL_BYTE_SIZE_REG (0x0600) /* internal */ +#define ATH_SPI_HOST_CTRL_NO_ADDR_INC (1 << 6) +#define ATH_SPI_HOST_CTRL_MAX_BYTES 32 + +#define ATH_SPI_HOST_CTRL_CONFIG_REG (0x0700) /* internal */ +#define ATH_SPI_HOST_CTRL_CONFIG_ENABLE (1 << 15) +#define ATH_SPI_HOST_CTRL_CONFIG_DIR_WRITE (1 << 14) + +#define ATH_SPI_HOST_CTRL_RD_PORT_REG (0x0800) /* internal */ +#define ATH_SPI_HOST_CTRL_WR_PORT_REG (0x0A00) /* internal */ + +#define ATH_SPI_INTR_CAUSE_REG (0x0C00) /* internal */ +#define ATH_SPI_INTR_ENABLE_REG (0x0D00) /* internal */ +#define ATH_SPI_INTR_WRBUF_BELOW_WMARK (1 << 10) +#define ATH_SPI_INTR_HOST_CTRL_RD_DONE (1 << 9) +#define ATH_SPI_INTR_HOST_CTRL_WR_DONE (1 << 8) +#define ATH_SPI_INTR_HOST_CTRL_ACCESS_DONE (ATH_SPI_INTR_HOST_CTRL_RD_DONE | ATH_SPI_INTR_HOST_CTRL_WR_DONE) + +#define ATH_SPI_INTR_CPU_INTR (1 << 7) +#define ATH_SPI_INTR_CPU_ON (1 << 6) +#define ATH_SPI_INTR_COUNTER_INTR (1 << 5) +#define ATH_SPI_INTR_LOCAL_CPU_INTR (1 << 4) +#define ATH_SPI_INTR_ADDRESS_ERROR (1 << 3) +#define ATH_SPI_INTR_WRBUF_ERROR (1 << 2) +#define ATH_SPI_INTR_RDBUF_ERROR (1 << 1) +#define ATH_SPI_INTR_PKT_AVAIL (1 << 0) + +#define ATH_SPI_RDBUF_WATERMARK_REG (0x1200) +#define ATH_SPI_RDBUF_WATERMARK_MAX 0x0FFF +#define ATH_SPI_WRBUF_WATERMARK_REG (0x1300) + +#define ATH_SPI_WRBUF_WRPTR_REG (0x0E00) /* internal */ +#define ATH_SPI_WRBUF_RDPTR_REG (0x0F00) /* internal */ +#define ATH_SPI_RDBUF_WRPTR_REG (0x1000) /* internal */ +#define ATH_SPI_RDBUF_RDPTR_REG (0x1100) /* internal */ + +#define ATH_SPI_WRBUF_RSVD_BYTES \ + 5 /* the SPI write buffer also contains 4 bytes \ + for mailbox and length, these bytes must be \ + taken into account when the write space is checked */ + +/* the 4-byte look ahead is split into 2 registers */ +#define ATH_SPI_RDBUF_LOOKAHEAD1_REG (0x1400) +#define ATH_SPI_GET_LOOKAHEAD1_BYTE_0(word) ((UINT8)((word) >> 8)) +#define ATH_SPI_GET_LOOKAHEAD1_BYTE_1(word) ((UINT8)(word)) +#define ATH_SPI_RDBUF_LOOKAHEAD2_REG (0x1500) +#define ATH_SPI_GET_LOOKAHEAD2_BYTE_3(word) ((UINT8)((word) >> 8)) +#define ATH_SPI_GET_LOOKAHEAD2_BYTE_4(word) ((UINT8)(word)) + +/* get/set clock, takes an UINT32 parameter */ +#define ATH_SPI_CONFIG_SET_CLOCK (SDCONFIG_PUT_HOST_CUSTOM + 2) +#define ATH_SPI_CONFIG_GET_CLOCK (SDCONFIG_GET_HOST_CUSTOM + 2) + +/* for testing purposes, set the DMA data frame width + * takes a UINT8 paramter with data size */ +#define ATH_SPI_CONFIG_SET_DMA_DATA_WIDTH (SDCONFIG_PUT_HOST_CUSTOM + 3) + +/* for testing purposes, set the host access data frame width + * takes a UINT8 paramter with data size */ +#define ATH_SPI_CONFIG_SET_HOST_ACCESS_DATA_WIDTH (SDCONFIG_PUT_HOST_CUSTOM + 4) + +/* for testing purposes dump the SPI registers, takes no data */ +#define ATH_SPI_CONFIG_DUMP_SPI_INTERNAL_REGISTERS (SDCONFIG_PUT_HOST_CUSTOM + 5) + +/* turn on/off the power of the SPI bus */ +#define ATH_SPI_CONFIG_SET_POWER (SDCONFIG_PUT_HOST_CUSTOM + 6) + +/* function driver IRQ sources */ +#define ATH_SPI_FUNC_DRIVER_IRQ_SOURCES (ATH_SPI_INTR_CPU_INTR | ATH_SPI_INTR_PKT_AVAIL) + +/* host driver error IRQs */ +#define ATH_SPI_HCD_ERROR_IRQS (ATH_SPI_INTR_ADDRESS_ERROR | ATH_SPI_INTR_WRBUF_ERROR | ATH_SPI_INTR_RDBUF_ERROR) +/* host driver IRQ sources */ +#define ATH_SPI_HCD_IRQ_SOURCES (ATH_SPI_INTR_WRBUF_BELOW_WMARK | ATH_SPI_HCD_ERROR_IRQS) + +#define AR4XXX_MAX_SPI_CLOCK_RATE 48000000 +#define AR4XXX_NORMAL_CLOCK_RATE 24000000 +#define AR4XXX_WRITE_BUFFER_SIZE 3163 +#endif /* __RAW_SPI_HCD_IF_H___ */ diff --git a/platform/mcu/lpc54102/wifi_qca/common_src/include/wlan_api.h b/platform/mcu/lpc54102/wifi_qca/common_src/include/wlan_api.h new file mode 100644 index 0000000000..821ddc349c --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/common_src/include/wlan_api.h @@ -0,0 +1,82 @@ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== + +#ifndef _HOST_WLAN_API_H_ +#define _HOST_WLAN_API_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#define DRIVER_INSERT(pCxt) A_OK +#define DRIVER_REMOVE(pCxt) + +A_STATUS Driver_WaitForCondition(void *pCxt, volatile boolean *pCond, boolean value, uint32_t msec); +#define DRIVER_WAIT_FOR_CONDITION(pCxt, pC, v, ms) Driver_WaitForCondition((pCxt), (pC), (v), (ms)) +#define WAIT_FOR_WMI_RESPONSE(pCxt) + +#define API_TXCOMPLETE(pCxt, pReq) \ + UNUSED_ARGUMENT((pCxt)); \ + UNUSED_ARGUMENT((pReq)); + +#define API_TARGET_STATS_EVENT(pCxt, ptr, len) Driver_WakeUser((pCxt)) + +#define API_REGDOMAIN_EVENT(pCxt, regCode) + +#define API_BITRATE_EVENT(pCxt, rateKbps) Driver_WakeUser((pCxt)) +#define API_CHANNEL_LIST_EVENT(pCxt, numChan, chanList) Driver_WakeUser((pCxt)) +#define API_SCAN_COMPLETE_EVENT(pCxt, status) Driver_WakeUser((pCxt)) +#define API_GET_PMK_EVENT(pCxt, datap) Driver_WakeUser((pCxt)) +#define API_STORE_RECALL_EVENT(pCxt) Driver_WakeUser((pCxt)) +#define API_WPS_PROFILE_EVENT(pCxt, datap, len, pReq) Driver_WakeUser((pCxt)) +#define API_GET_TEMPERATURE_REPLY(pCxt, datap, len) Driver_WakeUser((pCxt)) +#define API_SET_PARAM_REPLY_EVENT(pCxt) Driver_WakeUser((pCxt)) +#define API_GET_COUNTRY_CODE_REPLY(pCxt, datap, len) Driver_WakeUser((pCxt)) +#define API_WPS_INIT_REPLY(pCxt, datap, len) Driver_WakeUser((pCxt)) + +#define API_TKIP_MIC_ERROR_EVENT(pCxt, keyid, ismcast) +#define API_AGGR_RECV_ADDBA_REQ_EVENT(pCxt, evt) +#define API_AGGR_RECV_DELBA_REQ_EVENT(pCxt, evt) +#define API_WMIX_DBGLOG_EVENT(wmip, datap, len) + +// The best resolution we have is 1 millisecond so there is no microsecond delay. +// To avoid OSA_TimeDelay() delaying for 0ms, we add 1 millisecond +/* TODO: move to env layer !!*/ +#define HW_USEC_DELAY(pCxt, usec) A_MDELAY(1 >= MSEC_TO_TICK((usec) / 1000) ? 1 : MSEC_TO_TICK((usec) / 1000)) + +void HW_SetClock(void *pCxt, uint32_t *pClockRate); +#define HW_SET_CLOCK(pCxt, pClockRate) HW_SetClock((pCxt), (pClockRate)) + +#define A_WMI_EVENT(evt, pCxt, datap, len, osbuf) A_ERROR + +uint16_t wlan_ieee2freq(int chan); +uint32_t wlan_freq2ieee(uint16_t freq); + +#ifdef __cplusplus +} +#endif + +#endif /* _HOST_WLAN_API_H_ */ diff --git a/platform/mcu/lpc54102/wifi_qca/common_src/include/wmi_api.h b/platform/mcu/lpc54102/wifi_qca/common_src/include/wmi_api.h new file mode 100644 index 0000000000..f2abead6e3 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/common_src/include/wmi_api.h @@ -0,0 +1,155 @@ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== + +#ifndef _WMI_API_H_ +#define _WMI_API_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* WMI converts a dix frame with an ethernet payload (up to 1500 bytes) + * to an 802.3 frame (adds SNAP header) and adds on a WMI data header */ +#define WMI_MAX_TX_DATA_FRAME_LENGTH \ + (1500 + sizeof(WMI_DATA_HDR) + WMI_MAX_TX_META_SZ + sizeof(ATH_MAC_HDR) + sizeof(ATH_LLC_SNAP_HDR)) + +/* A normal WMI data frame */ +#define WMI_MAX_NORMAL_RX_DATA_FRAME_LENGTH \ + (1500 + HTC_HEADER_LEN + sizeof(WMI_DATA_HDR) + WMI_MAX_RX_META_SZ + sizeof(ATH_MAC_HDR) + sizeof(ATH_LLC_SNAP_HDR)) + +/* An AMSDU frame */ +#define WMI_MAX_AMSDU_RX_DATA_FRAME_LENGTH \ + (4096 + sizeof(WMI_DATA_HDR) + sizeof(ATH_MAC_HDR) + sizeof(ATH_LLC_SNAP_HDR)) + +/* + * IP QoS Field definitions according to 802.1p + */ +#define BEST_EFFORT_PRI 0 +#define BACKGROUND_PRI 1 +#define EXCELLENT_EFFORT_PRI 3 +#define CONTROLLED_LOAD_PRI 4 +#define VIDEO_PRI 5 +#define VOICE_PRI 6 +#define NETWORK_CONTROL_PRI 7 +#define MAX_NUM_PRI 8 + +#define UNDEFINED_PRI (0xff) + +#define WMI_IMPLICIT_PSTREAM_INACTIVITY_INT 5000 /* 5 seconds */ + +#define A_ROUND_UP(x, y) ((((x) + ((y)-1)) / (y)) * (y)) + +typedef enum +{ + ATHEROS_COMPLIANCE = 0x1 +} TSPEC_PARAM_COMPLIANCE; + +struct wmi_t; + +void *wmi_init(void *devt); + +void wmi_qos_state_init(struct wmi_t *wmip); +void wmi_shutdown(struct wmi_t *wmip); +HTC_ENDPOINT_ID wmi_get_control_ep(struct wmi_t *wmip); +void wmi_set_control_ep(struct wmi_t *wmip, HTC_ENDPOINT_ID eid); +A_STATUS wmi_dix_2_dot3(struct wmi_t *wmip, void *osbuf); +A_STATUS wmi_meta_add(struct wmi_t *wmip, void *osbuf, uint8_t *pVersion, void *pTxMetaS); +A_STATUS wmi_data_hdr_add(struct wmi_t *wmip, + void *osbuf, + uint8_t msgType, + boolean bMoreData, + WMI_DATA_HDR_DATA_TYPE data_type, + uint8_t metaVersion, + void *pTxMetaS); +A_STATUS wmi_dot3_2_dix(void *osbuf); + +A_STATUS wmi_dot11_hdr_remove(struct wmi_t *wmip, void *osbuf); +A_STATUS wmi_dot11_hdr_add(struct wmi_t *wmip, void *osbuf, NETWORK_TYPE mode); + +A_STATUS wmi_data_hdr_remove(struct wmi_t *wmip, void *osbuf); + +uint8_t wmi_implicit_create_pstream(struct wmi_t *wmip, void *osbuf, uint32_t layer2Priority, boolean wmmEnabled); + +A_STATUS wmi_control_rx(struct wmi_t *wmip, void *osbuf); + +typedef enum +{ + NO_SYNC_WMIFLAG = 0, + SYNC_BEFORE_WMIFLAG, /* transmit all queued data before cmd */ + SYNC_AFTER_WMIFLAG, /* any new data waits until cmd execs */ + SYNC_BOTH_WMIFLAG, + END_WMIFLAG /* end marker */ +} WMI_SYNC_FLAG; + +A_STATUS +wmi_cmd_start(struct wmi_t *wmip, const void *pInput, WMI_COMMAND_ID cmdID, uint16_t buffsize); + +A_STATUS wmi_cmd_send(struct wmi_t *wmip, void *osbuf, WMI_COMMAND_ID cmdId, WMI_SYNC_FLAG flag); + +A_STATUS wmi_bssfilter_cmd(struct wmi_t *wmip, uint8_t filter, uint32_t ieMask); + +#if WLAN_CONFIG_ENABLE_WMI_SYNC +A_STATUS wmi_dataSync_send(struct wmi_t *wmip, void *osbuf, HTC_ENDPOINT_ID eid); +#endif + +A_STATUS +wmi_storerecall_recall_cmd(struct wmi_t *wmip, uint32_t length, void *pData); + +A_STATUS wmi_socket_cmd(struct wmi_t *wmip, uint32_t cmd_type, void *pData, uint32_t length); + +#if ENABLE_P2P_MODE +void wmi_save_key_info(WMI_P2P_PROV_INFO *p2p_info); + +void p2p_go_neg_complete_rx(void *ctx, const uint8_t *datap, uint8_t len); + +A_STATUS +wmi_p2p_set_noa(struct wmi_t *wmip, WMI_NOA_INFO_STRUCT *buf); + +A_STATUS +wmi_p2p_set_oppps(struct wmi_t *wmip, WMI_OPPPS_INFO_STRUCT *pOpp); + +A_STATUS wmi_sdpd_send_cmd(struct wmi_t *wmip, WMI_P2P_SDPD_TX_CMD *buf); +#endif + +#if ENABLE_AP_MODE +A_STATUS +wmi_ap_set_param(struct wmi_t *wmip, void *data); +#endif + +A_STATUS wmi_reverse_credit_cmd(void *handle, boolean enable, uint8_t *endpoints, uint8_t *credits); +A_STATUS wmi_rcv_data_classifier_cmd(void *handle, + uint8_t offset, + uint8_t shift, + uint32_t mask, + uint8_t count, + uint32_t *class_mapping, + uint8_t *ep_mapping); +A_STATUS wmi_update_reverse_credits_cmd(void *handle, uint8_t endpoint, uint32_t nCredits); +A_STATUS wmi_set_appie_cmd(struct wmi_t *wmip, void *data); + +#ifdef __cplusplus +} +#endif + +#endif /* _WMI_API_H_ */ diff --git a/platform/mcu/lpc54102/wifi_qca/common_src/qapi/qcom_api.c b/platform/mcu/lpc54102/wifi_qca/common_src/qapi/qcom_api.c new file mode 100644 index 0000000000..49829c8491 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/common_src/qapi/qcom_api.c @@ -0,0 +1,2896 @@ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if ENABLE_P2P_MODE +#include +#include "p2p.h" +#endif +#include "atheros_wifi.h" +#include "atheros_wifi_api.h" +#include "atheros_wifi_internal.h" +#include "atheros_stack_offload.h" +#include "dset_api.h" +#include "common_stack_offload.h" +#include "qcom_api.h" +//------------------------------------------------------------------------------------------------------------ +qcom_wps_credentials_t gWpsCredentials; + +//------------------------------------------------------------------------------------------------------------ + +A_STATUS custom_qapi(uint8_t device_id, uint32_t cmd, void *param); +void *Custom_Api_GetDriverCxt(uint8_t device_id); + +/*FUNCTION*------------------------------------------------------------- +* +* Function Name : qcom_set_deviceid() +* Returned Value : A_ERROR is command failed, else A_OK +* Comments : Sets device ID in driver context +* +*END*-----------------------------------------------------------------*/ +A_STATUS qcom_set_deviceid(uint16_t id) +{ + ATH_IOCTL_PARAM_STRUCT inout_param; + + inout_param.cmd_id = ATH_SET_DEVICE_ID; + inout_param.data = (void *)&id; + inout_param.length = sizeof(uint16_t); + + return (custom_qapi(id, ATH_SET_DEVICE_ID, &inout_param)); +} + +#if 0 +static enum p2p_wps_method qcom_p2p_get_wps(P2P_WPS_METHOD wps) +{ + switch (wps) { + case P2P_WPS_NOT_READY: + return WPS_NOT_READY; + case P2P_WPS_PIN_LABEL: + return WPS_PIN_LABEL; + case P2P_WPS_PIN_DISPLAY: + return WPS_PIN_DISPLAY; + case P2P_WPS_PIN_KEYPAD: + return WPS_PIN_KEYPAD; + case P2P_WPS_PBC: + return WPS_PBC; + default: + return WPS_NOT_READY; + } +} +#endif + +//------------------------------------------------------------------------------------------------------------ + +#if ENABLE_STACK_OFFLOAD + +int qcom_socket(int family, int type, int protocol) +{ + return (t_socket(Custom_Api_GetDriverCxt(0), family, type, protocol)); +} + +int qcom_connect(int s, struct sockaddr *addr, int addrlen) +{ + return (t_connect(Custom_Api_GetDriverCxt(0), s, addr, addrlen)); +} + +int qcom_bind(int s, struct sockaddr *addr, int addrlen) +{ + return (t_bind(Custom_Api_GetDriverCxt(0), s, addr, addrlen)); +} + +int qcom_listen(int s, int backlog) +{ + return (t_listen(Custom_Api_GetDriverCxt(0), s, backlog)); +} + +int qcom_accept(int s, struct sockaddr *addr, socklen_t *addrlen) +{ + return (t_accept(Custom_Api_GetDriverCxt(0), s, addr, *addrlen)); +} + +int qcom_setsockopt(int s, int level, int name, void *arg, int arglen) +{ + return (t_setsockopt(Custom_Api_GetDriverCxt(0), s, level, name, arg, arglen)); +} + +int qcom_getsockopt(int s, int level, int name, void *arg, int arglen) +{ + return (t_getsockopt(Custom_Api_GetDriverCxt(0), s, level, name, arg, arglen)); +} + +#if ZERO_COPY +int qcom_recv(int s, char **buf, int len, int flags) +#else +int qcom_recv(int s, char *buf, int len, int flags) +#endif +{ + return (t_recv(Custom_Api_GetDriverCxt(0), s, (void *)buf, len, flags)); +} + +#if ZERO_COPY +int qcom_recvfrom(int s, char **buf, int len, int flags, struct sockaddr *from, socklen_t *fromlen) +#else +int qcom_recvfrom(int s, char *buf, int len, int flags, struct sockaddr *from, socklen_t *fromlen) +#endif +{ + return (t_recvfrom(Custom_Api_GetDriverCxt(0), s, (void *)buf, len, flags, from, (socklen_t*)fromlen)); +} + +#if ENABLE_DNS_CLIENT +A_STATUS qcom_dnsc_enable(boolean enable) +{ + return ((A_STATUS)custom_ip_dns_client(Custom_Api_GetDriverCxt(0), enable)); +} + +A_STATUS qcom_dnsc_add_server_address(uint8_t *ipaddress, uint8_t type) +{ + IP46ADDR dnsaddr; + + memset(&dnsaddr, 0, sizeof(IP46ADDR)); + if (type == ATH_AF_INET) + { + dnsaddr.type = ATH_AF_INET; + dnsaddr.addr4 = (uint32_t) * (uint32_t *)ipaddress; + } + else + { + dnsaddr.type = ATH_AF_INET6; + memcpy(&dnsaddr.addr6, ipaddress, sizeof(IP6_ADDR_T)); + } + + return ((A_STATUS)custom_ip_dns_server_addr(Custom_Api_GetDriverCxt(0), &dnsaddr)); +} + +A_STATUS qcom_dnsc_del_server_address(uint8_t *ipaddress, uint8_t type) +{ + IP46ADDR dnsaddr; +#define DELETE_DNS_SERVER_ADDR 1 + + memset(&dnsaddr, 0, sizeof(IP46ADDR)); + dnsaddr.au1Rsvd[0] = DELETE_DNS_SERVER_ADDR; + if (type == ATH_AF_INET) + { + dnsaddr.type = ATH_AF_INET; + dnsaddr.addr4 = (uint32_t) * (uint32_t *)ipaddress; + } + else + { + dnsaddr.type = ATH_AF_INET6; + memcpy(&dnsaddr.addr6, ipaddress, sizeof(IP6_ADDR_T)); + } + + return ((A_STATUS)custom_ip_dns_server_addr(Custom_Api_GetDriverCxt(0), &dnsaddr)); +} + +A_STATUS qcom_dnsc_get_host_by_name(char *pname, uint32_t *pipaddress) +{ + DNC_CFG_CMD DnsCfg; + DNC_RESP_INFO DnsRespInfo; + + memset(&DnsRespInfo, 0, sizeof(DnsRespInfo)); + strcpy((char *)DnsCfg.ahostname, pname); + DnsCfg.domain = 2; + DnsCfg.mode = GETHOSTBYNAME; + if (A_OK != custom_ip_resolve_hostname(Custom_Api_GetDriverCxt(0), &DnsCfg, &DnsRespInfo)) + { + return A_ERROR; + } + *pipaddress = A_CPU2BE32(DnsRespInfo.ipaddrs_list[0]); + return A_OK; +} + +A_STATUS qcom_dnsc_get_host_by_name2(char *pname, uint32_t *pipaddress, int32_t domain, uint32_t mode) +{ + DNC_CFG_CMD DnsCfg; + DNC_RESP_INFO DnsRespInfo; + + memset(&DnsRespInfo, 0, sizeof(DnsRespInfo)); + strcpy((char *)DnsCfg.ahostname, pname); + DnsCfg.domain = domain; + DnsCfg.mode = mode; + if (A_OK != custom_ip_resolve_hostname(Custom_Api_GetDriverCxt(0), &DnsCfg, &DnsRespInfo)) + { + return A_ERROR; + } + + if (domain == 3) + memcpy(pipaddress, (void*)&DnsRespInfo.ip6addrs_list[0], 16); + else + memcpy(pipaddress, (void*)&DnsRespInfo.ipaddrs_list[0], 4); + return A_OK; +} + +#endif +#if ENABLE_DNS_SERVER +A_STATUS qcom_dns_server_address_get(uint32_t pdns[], uint32_t *number) +{ + int i; + A_STATUS error; + IP46ADDR dnsaddr[MAX_DNSADDRS]; + + memset(&dnsaddr[0], 0, sizeof(dnsaddr)); + error = t_ipconfig(Custom_Api_GetDriverCxt(0), IPCFG_QUERY, NULL, NULL, NULL, dnsaddr, NULL); + *number = 0; + + if (error == A_OK) + { + for (i = 0; i < MAX_DNSADDRS; i++) + { + if (dnsaddr[i].addr4 != 0) + { + pdns[i] = A_CPU2BE32(dnsaddr[i].addr4); + *number = *number + 1; + } + else + { + break; + } + } + } + + return error; +} + +A_STATUS qcom_dnss_enable(boolean enable) +{ + return ((A_STATUS)custom_ip_dns_server(Custom_Api_GetDriverCxt(0), (uint32_t)enable)); +} + +A_STATUS qcom_dns_local_domain(char *local_domain) +{ + return ((A_STATUS)custom_ip_dns_local_domain(Custom_Api_GetDriverCxt(0), local_domain)); +} + +A_STATUS qcom_dns_entry_create(char *hostname, uint32_t ipaddress) +{ + IP46ADDR dnsaddr = {0}; + dnsaddr.type = ATH_AF_INET; + dnsaddr.addr4 = ipaddress; + return ((A_STATUS)custom_ipdns(Custom_Api_GetDriverCxt(0), 1, hostname, &dnsaddr)); +} + +A_STATUS qcom_dns_entry_delete(char *hostname, uint32_t ipaddress) +{ + IP46ADDR dnsaddr = {0}; + dnsaddr.type = ATH_AF_INET; + dnsaddr.addr4 = ipaddress; + return ((A_STATUS)custom_ipdns(Custom_Api_GetDriverCxt(0), 2, hostname, &dnsaddr)); +} + +A_STATUS qcom_dns_6entry_create(char *hostname, IP6_ADDR_T *ip6addr) +{ + IP46ADDR dnsaddr = {0}; + dnsaddr.type = ATH_AF_INET6; + memcpy(&dnsaddr.addr6, ip6addr, sizeof(dnsaddr.addr6)); + return ((A_STATUS)custom_ipdns(Custom_Api_GetDriverCxt(0), 1, hostname, &dnsaddr)); +} + +A_STATUS qcom_dns_6entry_delete(char *hostname, IP6_ADDR_T *ip6addr) +{ + IP46ADDR dnsaddr = {0}; + dnsaddr.type = ATH_AF_INET6; + memcpy(&dnsaddr.addr6, ip6addr, sizeof(dnsaddr.addr6)); + return ((A_STATUS)custom_ipdns(Custom_Api_GetDriverCxt(0), 2, hostname, &dnsaddr)); +} + +#endif + +#if ENABLE_SNTP_CLIENT +void qcom_sntp_srvr_addr(int flag, char *srv_addr) +{ + custom_ip_sntp_srvr_addr(Custom_Api_GetDriverCxt(0), flag, srv_addr); +} + +void qcom_sntp_get_time(uint8_t device_id, tSntpTime *time) +{ + if (A_OK != qcom_set_deviceid(device_id)) + { + return; + } + custom_ip_sntp_get_time(Custom_Api_GetDriverCxt(device_id), time); +} + +void qcom_sntp_get_time_of_day(uint8_t device_id, tSntpTM *time) +{ + if (A_OK != qcom_set_deviceid(device_id)) + { + return; + } + custom_ip_sntp_get_time_of_day(Custom_Api_GetDriverCxt(device_id), time); +} +void qcom_sntp_zone(int hour, int min, int add_sub, int enable) +{ + custom_ip_sntp_modify_zone_dse(Custom_Api_GetDriverCxt(0), hour, min, add_sub, enable); +} + +void qcom_sntp_query_srvr_address(uint8_t device_id, tSntpDnsAddr *addr) +{ + if (A_OK != qcom_set_deviceid(device_id)) + { + return; + } + custom_ip_sntp_query_srvr_address(Custom_Api_GetDriverCxt(device_id), addr); +} + +void qcom_enable_sntp_client(int enable) +{ + custom_ip_sntp_client(Custom_Api_GetDriverCxt(0), enable); +} + +#endif + +/****************QCOM_OTA_APIs************************/ + +A_STATUS qcom_ota_upgrade(uint8_t device_id, + uint32_t addr, + char *filename, + uint8_t mode, + uint8_t preserve_last, + uint8_t protocol, + uint32_t *resp_code, + uint32_t *length) +{ + return ((A_STATUS)custom_ota_upgrade(Custom_Api_GetDriverCxt(device_id), addr, filename, mode, preserve_last, + protocol, resp_code, length)); +} + +A_STATUS qcom_ota_read_area(uint32_t offset, uint32_t size, uint8_t *buffer, uint32_t *retlen) +{ + return ((A_STATUS)custom_ota_read_area(Custom_Api_GetDriverCxt(0), offset, size, buffer, retlen)); +} + +A_STATUS qcom_ota_done(boolean good_image) +{ + return ((A_STATUS)custom_ota_done(Custom_Api_GetDriverCxt(0), good_image)); +} + +QCOM_OTA_STATUS_CODE_t qcom_ota_session_start(uint32_t flags, uint32_t partition_index) +{ + return ((QCOM_OTA_STATUS_CODE_t)custom_ota_session_start(Custom_Api_GetDriverCxt(0), flags, partition_index)); +} + +uint32_t qcom_ota_partition_get_size(void) +{ + return (custom_ota_partition_get_size(Custom_Api_GetDriverCxt(0))); +} + +QCOM_OTA_STATUS_CODE_t qcom_ota_partition_erase(void) +{ + return ((QCOM_OTA_STATUS_CODE_t)custom_ota_partition_erase(Custom_Api_GetDriverCxt(0))); +} + +QCOM_OTA_STATUS_CODE_t qcom_ota_partition_verify_checksum(void) +{ + return ((QCOM_OTA_STATUS_CODE_t)custom_ota_partition_verify_checksum(Custom_Api_GetDriverCxt(0))); +} + +QCOM_OTA_STATUS_CODE_t qcom_ota_parse_image_hdr(uint8_t *header, uint32_t *offset) +{ + return ((QCOM_OTA_STATUS_CODE_t)custom_ota_parse_image_hdr(Custom_Api_GetDriverCxt(0), header, offset)); +} + +uint32_t qcom_ota_partition_read_data(uint32_t offset, uint8_t *buf, uint32_t size) +{ + uint32_t rtn_len = 0; + if (qcom_ota_read_area(offset, size, buf, &rtn_len) != A_OK) + { + if (rtn_len > 0) + { + rtn_len = rtn_len; + } + } + return (rtn_len); +} + +QCOM_OTA_STATUS_CODE_t qcom_ota_partition_write_data(uint32_t offset, uint8_t *buf, uint32_t size, uint32_t *ret_size) +{ + return ((QCOM_OTA_STATUS_CODE_t)custom_ota_partition_write_data(Custom_Api_GetDriverCxt(0), offset, buf, size, + ret_size)); +} + +QCOM_OTA_STATUS_CODE_t qcom_ota_session_end(uint32_t good_image) +{ + return (QCOM_OTA_STATUS_CODE_t)qcom_ota_done(good_image); +} + +QCOM_OTA_STATUS_CODE_t qcom_ota_partition_format(uint32_t partition_index) +{ + QCOM_OTA_STATUS_CODE_t rtn; + + if (partition_index == 0) + return QCOM_OTA_ERR_INVALID_PARTITION_INDEX; + + if ((rtn = qcom_ota_session_start(QCOM_OTA_ERASING_RW_DSET, partition_index)) == QCOM_OTA_OK) + { + rtn = (QCOM_OTA_STATUS_CODE_t)qcom_ota_partition_erase(); + qcom_ota_session_end(0); + } + return rtn; +} + +A_STATUS qcom_ota_set_callback(void *callback) +{ + return ((A_STATUS)custom_ota_set_response_cb(Custom_Api_GetDriverCxt(0), callback)); +} + +int qcom_sendto(int s, char *buffer, int length, int flags, struct sockaddr *to, int tolen) +{ + return (t_sendto(Custom_Api_GetDriverCxt(0), s, (uint8_t *)buffer, length, flags, to, tolen)); +} + +int qcom_send(int s, char *buffer, int length, int flags) +{ + return (t_send(Custom_Api_GetDriverCxt(0), s, (uint8_t *)buffer, length, flags)); +} + +int qcom_socket_close(int s) +{ + return (t_shutdown(Custom_Api_GetDriverCxt(0), s)); +} + +A_STATUS qcom_ipconfig(uint8_t device_id, QCOM_IPCONFIG_MODE mode, uint32_t *address, uint32_t *submask, uint32_t *gateway) +{ + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + return (t_ipconfig(Custom_Api_GetDriverCxt(device_id), mode, address, submask, gateway, NULL, NULL)); +} + +A_STATUS qcom_ip6_address_get(uint8_t device_id, + IP6_ADDR_T *v6Global, + IP6_ADDR_T *v6Link, + IP6_ADDR_T *v6DefGw, + IP6_ADDR_T *v6GlobalExtd, + int32_t *LinkPrefix, + int32_t *GlbPrefix, + int32_t *DefgwPrefix, + int32_t *GlbPrefixExtd) +{ + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + return (t_ip6config(Custom_Api_GetDriverCxt(device_id), IPCFG_QUERY, (IP6_ADDR_T *)v6Global, (IP6_ADDR_T *)v6Link, + (IP6_ADDR_T *)v6DefGw, (IP6_ADDR_T *)v6GlobalExtd, LinkPrefix, GlbPrefix, DefgwPrefix, + GlbPrefixExtd)); +} + +A_STATUS qcom_ping(uint32_t host, uint32_t size) +{ + return (t_ping(Custom_Api_GetDriverCxt(0), host, size)); +} + +A_STATUS qcom_ping6(uint8_t *host, uint32_t size) +{ + return (t_ping6(Custom_Api_GetDriverCxt(0), host, size)); +} + +A_STATUS qcom_ip6config_router_prefix( + uint8_t device_id, IP6_ADDR_T *addr, int32_t prefixlen, int32_t prefix_lifetime, int32_t valid_lifetime) +{ + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + return (t_ip6config_router_prefix(Custom_Api_GetDriverCxt(0), addr, prefixlen, prefix_lifetime, valid_lifetime)); +} + +A_STATUS qcom_bridge_mode_enable(uint16_t bridgemode) +{ + return (custom_ipbridgemode(Custom_Api_GetDriverCxt(0), bridgemode)); +} + +A_STATUS qcom_tcp_set_exp_backoff(uint8_t device_id, int32_t retry) +{ + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + return (custom_ipconfig_set_tcp_exponential_backoff_retry(Custom_Api_GetDriverCxt(device_id), retry)); +} + +#if ENABLE_ROUTING_CMDS +A_STATUS qcom_ip4_route(uint8_t device_id, + uint32_t cmd, + IP_ADDR_T *addr, + IP_ADDR_T *subnet, + IP_ADDR_T *gw, + uint32_t *ifindex, + IPV4_ROUTE_LIST_T *rtlist) +{ + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + return (custom_ipv4_route(Custom_Api_GetDriverCxt(device_id), cmd, addr, subnet, gw, ifindex, rtlist)); +} + +A_STATUS qcom_ip6_route(uint8_t device_id, + uint32_t cmd, + IP6_ADDR_T *ip6addr, + uint32_t *prefixLen, + IP6_ADDR_T *gw, + uint32_t *ifindex, + IPV6_ROUTE_LIST_T *rtlist) +{ + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + return (custom_ipv6_route(Custom_Api_GetDriverCxt(device_id), cmd, ip6addr, prefixLen, gw, ifindex, rtlist)); +} + +#endif + +A_STATUS qcom_tcp_conn_timeout(uint32_t timeout_val) +{ + return (custom_tcp_connection_timeout(Custom_Api_GetDriverCxt(0), timeout_val)); +} + +int32_t qcom_dhcps_set_pool(uint8_t device_id, uint32_t startip, uint32_t endip, int32_t leasetime) +{ + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + return (t_ipconfig_dhcp_pool(Custom_Api_GetDriverCxt(device_id), &startip, &endip, leasetime)); +} + +int32_t qcom_dhcps_register_cb(uint8_t device_id, void *callback) +{ + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + return (t_ipconfig_dhcps_cb_enable(Custom_Api_GetDriverCxt(device_id), callback)); +} + +int32_t qcom_dhcpc_register_cb(uint8_t device_id, void *callback) +{ + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + return (t_ipconfig_dhcpc_cb_enable(Custom_Api_GetDriverCxt(device_id), callback)); +} + +A_STATUS qcom_dhcps_release_pool(uint8_t device_id) +{ + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + return (custom_ipconfig_dhcp_release(Custom_Api_GetDriverCxt(device_id))); +} + +A_STATUS qcom_http_server(int32_t enable) +{ + return (custom_ip_http_server(Custom_Api_GetDriverCxt(0), enable)); +} + +A_STATUS qcom_http_set_post_cb(void *cxt, void *callback) +{ + if (callback == NULL) + { + return A_ERROR; + } + return ((A_STATUS)custom_http_set_post_cb(Custom_Api_GetDriverCxt(0), cxt, callback)); +} + +A_STATUS qcom_ip_http_server_method( + int32_t cmd, uint8_t *pagename, uint8_t *objname, int32_t objtype, int32_t objlen, uint8_t *value) +{ + return (custom_ip_http_server_method(Custom_Api_GetDriverCxt(0), cmd, pagename, objname, objtype, objlen, value)); +} + +#if ENABLE_HTTP_CLIENT +A_STATUS qcom_http_client_method(uint32_t cmd, uint8_t *url, uint8_t *data, uint8_t *value) +{ + HTTPC_RESPONSE *output = NULL; + A_STATUS result = A_OK; + + if (NULL == value) + { + // for HTTPC_CONNECT or HTTPC_DISC + result = custom_httpc_method(Custom_Api_GetDriverCxt(0), cmd, url, data, NULL); + } + else + { + result = custom_httpc_method(Custom_Api_GetDriverCxt(0), cmd, url, data, (uint8_t **)&output); + } + + if (result == A_OK) + { + if (output && value) + { + A_MEMCPY(value, output, sizeof(HTTPC_RESPONSE) + output->length - 1); + zero_copy_http_free((void *)output); + } + } + + return result; +} +#endif + +#if ENABLE_SSL +SSL_CTX *qcom_SSL_ctx_new(SSL_ROLE_T role, int32_t inbufSize, int32_t outbufSize, int32_t reserved) +{ + return ((SSL_CTX *)SSL_ctx_new(role, inbufSize, outbufSize, reserved)); +} + +int32_t qcom_SSL_ctx_free(SSL_CTX *ctx) +{ + return (SSL_ctx_free(ctx)); +} + +SSL *qcom_SSL_new(SSL_CTX *ctx) +{ + return ((SSL *)SSL_new(ctx)); +} + +int32_t qcom_SSL_setCaList(SSL_CTX *ctx, SslCAList caList, uint32_t size) +{ + return (SSL_setCaList(ctx, caList, size)); +} + +int32_t qcom_SSL_addCert(SSL_CTX *ctx, SslCert cert, uint32_t size) +{ + return (SSL_addCert(ctx, cert, size)); +} + +int32_t qcom_SSL_storeCert(char *name, SslCert cert, uint32_t size) +{ + return (SSL_storeCert(name, cert, size)); +} +int32_t qcom_SSL_loadCert(SSL_CTX *ctx, SSL_CERT_TYPE_T type, char *name) +{ + return (SSL_loadCert(ctx, type, name)); +} + +int32_t qcom_SSL_listCert(SSL_FILE_NAME_LIST *fileNames) +{ + return (SSL_listCert(fileNames)); +} + +int32_t qcom_SSL_set_fd(SSL *ssl, uint32_t fd) +{ + return (SSL_set_fd(ssl, fd)); +} + +int32_t qcom_SSL_accept(SSL *ssl) +{ + return (SSL_accept(ssl)); +} + +int32_t qcom_SSL_connect(SSL *ssl) +{ + return (SSL_connect(ssl)); +} + +int32_t qcom_SSL_shutdown(SSL *ssl) +{ + return (SSL_shutdown(ssl)); +} + +int32_t qcom_SSL_configure(SSL *ssl, SSL_CONFIG *cfg) +{ + return (SSL_configure(ssl, cfg)); +} + +#if ZERO_COPY +int32_t qcom_SSL_read(SSL *ssl, void **buf, int32_t num) +#else +int32_t qcom_SSL_read(SSL *ssl, void *buf, int32_t num) +#endif +{ + return (SSL_read(ssl, buf, num)); +} +int32_t qcom_SSL_write(SSL *ssl, const void *buf, int32_t num) +{ + return (SSL_write(ssl, buf, num)); +} + +#endif // ENABLE_SSL +#endif + +/****************************************************************************************/ +A_STATUS _qcom_set_scan(uint8_t device_id, qcom_start_scan_params_t *pScanParams) +{ + uint32_t size; + WMI_START_SCAN_CMD *pStartScan; + A_STATUS error = A_OK; + uint8_t *buffer = NULL; + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + + if (pScanParams == NULL) + { + pStartScan = NULL; + } + else + { + size = sizeof(WMI_START_SCAN_CMD); + if (pScanParams->numChannels > 0) + { + size = size + (pScanParams->numChannels - 1) * sizeof(uint16_t); + } + + if (NULL == (buffer = A_MALLOC(size, MALLOC_ID_CONTEXT))) + { + return A_ERROR; + } + + pStartScan = (WMI_START_SCAN_CMD *)buffer; + A_MEMZERO(pStartScan, size); + pStartScan->forceFgScan = pScanParams->forceFgScan; + pStartScan->isLegacy = false; + pStartScan->homeDwellTime = pScanParams->homeDwellTimeInMs; + pStartScan->forceScanInterval = pScanParams->forceScanIntervalInMs; + pStartScan->scanType = pScanParams->scanType; + pStartScan->numChannels = pScanParams->numChannels; + A_MEMCPY((uint8_t *)pStartScan->channelList, (uint8_t *)pScanParams->channelList, + pScanParams->numChannels * sizeof(uint16_t)); + } + if (custom_qapi(device_id, ATH_SET_SCAN, (void *)pStartScan) != A_OK) + error = A_ERROR; + + if (buffer) + A_FREE(buffer, MALLOC_ID_CONTEXT); + return error; +} + +A_STATUS qcom_get_scan(uint8_t device_id, QCOM_BSS_SCAN_INFO **buf, int16_t *numResults) +{ + ATH_SCAN_LIST param = {0}; + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + + if (custom_qapi(device_id, ATH_GET_SCAN_RESULTS, ¶m) != A_OK) + { + return A_ERROR; + } + *buf = (QCOM_BSS_SCAN_INFO *)param.scan_list; + *numResults = param.num_scan_entries; + + return A_OK; +} + +/* NOTE: Passing NULL to pssid is not longer supported. Use empty + * string "" instead */ +A_STATUS qcom_set_ssid(uint8_t device_id, QCOM_SSID *pssid) +{ + ATH_IOCTL_PARAM_STRUCT param = {0}; + if (NULL == pssid) + { + return A_ERROR; + } + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + //TODO: check sizeof vs strlen ? + param.data = pssid; + if (A_OK != custom_qapi(device_id, ATH_SET_SSID, ¶m)) + { + return A_ERROR; + } + return A_OK; +} + +A_STATUS qcom_get_ssid(uint8_t device_id, QCOM_SSID *pssid) +{ + ATH_IOCTL_PARAM_STRUCT param = {0}; + uint32_t null_position; + if (NULL == pssid) + { + return A_ERROR; + } + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + param.data = (void *)pssid; + if (A_OK != custom_qapi(device_id, ATH_GET_ESSID, ¶m)) + { + return A_ERROR; + } + /* terminate SSID string */ + null_position = param.length < sizeof(QCOM_SSID) ? param.length : sizeof(QCOM_SSID) - 1; + pssid->ssid[null_position] = '\0'; + return A_OK; +} + +A_STATUS qcom_set_connect_callback(uint8_t device_id, void *callback) +{ + ATH_IOCTL_PARAM_STRUCT inout_param; + A_STATUS error = A_OK; + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + inout_param.cmd_id = ATH_SET_CONNECT_STATE_CALLBACK; + inout_param.data = (void *)callback; + inout_param.length = sizeof(void *); + + if (custom_qapi(device_id, ATH_SET_CONNECT_STATE_CALLBACK, &inout_param) != A_OK) + { + error = A_ERROR; + } + return error; +} + +A_STATUS qcom_set_probe_req_callback(uint8_t device_id, void *callback) +{ + ATH_IOCTL_PARAM_STRUCT inout_param; + A_STATUS error = A_OK; + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + inout_param.cmd_id = ATH_SET_PROBEREQ_CB; + inout_param.data = (void *)callback; + inout_param.length = sizeof(void *); + + if (custom_qapi(device_id, ATH_SET_PROBEREQ_CB, &inout_param) != A_OK) + { + error = A_ERROR; + } + return error; +} + +A_STATUS qcom_enable_probe_req_event(uint8_t device_id, uint8_t enable) +{ + ATH_IOCTL_PARAM_STRUCT inout_param; + A_STATUS error = A_OK; + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + inout_param.cmd_id = ATH_SET_PROBEREQ_EV_ENABLE; + inout_param.data = (void *)&enable; + inout_param.length = sizeof(void *); + + if (custom_qapi(device_id, ATH_SET_PROBEREQ_EV_ENABLE, &inout_param) != A_OK) + { + error = A_ERROR; + } + return error; +} + +#if ENABLE_SCC_MODE +static A_STATUS qcom_get_concurrent_channel(uint8_t device_id, uint16_t *conc_channel) +{ + ATH_IOCTL_PARAM_STRUCT ath_param = {0}; + A_STATUS error = A_OK; + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + ath_param.cmd_id = ATH_GET_CONC_DEV_CHANNEL; + ath_param.data = conc_channel; + + if (custom_qapi(device_id, ATH_GET_CONC_DEV_CHANNEL, &ath_param) != A_OK) + { + error = A_ERROR; + } + return error; +} + +static A_STATUS qcom_get_channelhint(uint8_t device_id, uint16_t *pchannel) +{ + ATH_IOCTL_PARAM_STRUCT inout_param = {0}; + A_STATUS error = A_OK; + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + inout_param.cmd_id = ATH_GET_CHANNELHINT; + inout_param.data = pchannel; + + if (custom_qapi(device_id, ATH_GET_CHANNELHINT, &inout_param) != A_OK) + { + error = A_ERROR; + } + return error; +} + +#endif + +A_STATUS qcom_commit(uint8_t device_id) +{ +#if ENABLE_SCC_MODE + uint16_t conc_channel, cur_channel; + QCOM_SSID ssid; + int num_dev = WLAN_NUM_OF_DEVICES; + + if (qcom_get_ssid(device_id, &ssid) != A_OK) + return A_ERROR; + + /*this is connect request */ + if ((strlen(ssid.ssid) != 0) && (num_dev > 1)) + { + qcom_get_channelhint(device_id, &cur_channel); + qcom_get_concurrent_channel(device_id, &conc_channel); + /* if device 1 is connected and this connect request is from device 0, + check both devices whether stay at same channel, if not, return fail due to device 1 is primary + */ + if ((conc_channel != 0) && (device_id == 0) && (conc_channel != cur_channel)) + { + return A_ERROR; + } + /* if device 0 is connected and this connect request is from device 1, + check both devices whether stay at same channel, if not, p2p_cancel is issue to device 0 because device 1 is + promary + */ + if ((conc_channel != 0) && (device_id == 1) && (conc_channel != cur_channel)) + { + qcom_set_deviceid(0); + qcom_set_channel(0, conc_channel); + A_MDELAY(50); + qcom_p2p_func_cancel(0); + A_MDELAY(500); + qcom_set_deviceid(1); + qcom_set_channel(1, cur_channel); + A_MDELAY(50); + } + } + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + + return (custom_qapi(device_id, ATH_SET_COMMIT, NULL)); + +#else + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + + return (custom_qapi(device_id, ATH_SET_COMMIT, NULL)); +#endif // ENABLE_SCC_MODE +} + +A_STATUS qcom_sta_get_rssi(uint8_t device_id, uint8_t *prssi) +{ + A_STATUS error = A_OK; + ATH_IOCTL_PARAM_STRUCT inout_param; + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + inout_param.cmd_id = ATH_GET_RX_RSSI; + inout_param.data = prssi; + + if (custom_qapi(device_id, ATH_GET_RX_RSSI, &inout_param) != A_OK) + { + error = A_ERROR; + } + return error; +} + +/* for hostless , the listentime is 1Tus, 1Tus = 1024 us. need to confirm the UNIT */ +A_STATUS qcom_sta_set_listen_time(uint8_t device_id, uint32_t listentime) +{ + ATH_IOCTL_PARAM_STRUCT inout_param; + A_STATUS error = A_OK; + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + + inout_param.cmd_id = ATH_SET_LISTEN_INT; + inout_param.data = &listentime; + inout_param.length = 4; + + if (custom_qapi(device_id, ATH_SET_LISTEN_INT, &inout_param) != A_OK) + { + error = A_ERROR; + } + return error; +} + +A_STATUS qcom_ap_set_beacon_interval(uint8_t device_id, uint16_t beacon_interval) +{ + ATH_IOCTL_PARAM_STRUCT inout_param = {0}; + ATH_AP_PARAM_STRUCT ap_param; + A_STATUS error = A_OK; + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + inout_param.cmd_id = ATH_CONFIG_AP; + ap_param.cmd_subset = AP_SUB_CMD_BCON_INT; + ap_param.data = &beacon_interval; + inout_param.data = &ap_param; + + if (custom_qapi(device_id, ATH_CONFIG_AP, &inout_param) != A_OK) + { + error = A_ERROR; + } + return error; +} + +A_STATUS qcom_ap_hidden_mode_enable(uint8_t device_id, boolean enable) +{ + ATH_IOCTL_PARAM_STRUCT inout_param = {0}; + ATH_AP_PARAM_STRUCT ap_param; + A_STATUS error = A_OK; + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + + inout_param.cmd_id = ATH_CONFIG_AP; + ap_param.cmd_subset = AP_SUB_CMD_HIDDEN_FLAG; + ap_param.data = &enable; + inout_param.data = &ap_param; + + if (custom_qapi(device_id, ATH_CONFIG_AP, &inout_param) != A_OK) + { + error = A_ERROR; + } + return error; +} + +//TODO: always check return value in place of call +A_STATUS qcom_op_get_mode(uint8_t device_id, QCOM_WLAN_DEV_MODE *pmode) +{ + uint32_t inout_param = 0; + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + + if (custom_qapi(device_id, ATH_GET_OP_MODE, &inout_param) != A_OK) + { + return A_ERROR; + } + *pmode = (QCOM_WLAN_DEV_MODE)inout_param; + + return A_OK; +} + +A_STATUS qcom_op_set_mode(uint8_t device_id, QCOM_WLAN_DEV_MODE mode) +{ + uint32_t inout_param = 0; + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + inout_param = mode; + + if (A_OK != custom_qapi(device_id, ATH_SET_OP_MODE, &inout_param)) + { + return A_ERROR; + } + + return A_OK; +} + +A_STATUS qcom_disconnect(uint8_t device_id) +{ + A_STATUS error = A_OK; + QCOM_SSID tmp_ssid = QCOM_SSID_FROM_STR(""); + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + /* set ssid to be blank string , ssid length is 0 , the fist step to disconnectl*/ + if (qcom_set_ssid(device_id, &tmp_ssid) != A_OK) + { + return A_ERROR; + } + /* a zero length ssid + a COMMIT command is interpreted as a + request from the caller to disconnect.*/ + if (qcom_commit(device_id) != A_OK) + { + return A_ERROR; + } + return error; +} + +static const char qcom_phy_mode_a[] = "a"; +static const char qcom_phy_mode_g[] = "g"; +static const char qcom_phy_mode_b[] = "b"; +static const char qcom_phy_mode_mixed[] = "mixed"; + +A_STATUS qcom_get_phy_mode(uint8_t device_id, char **pphymode) +{ + ATH_IOCTL_PARAM_STRUCT inout_param; + uint32_t value = 0; + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + inout_param.cmd_id = ATH_GET_PHY_MODE; + inout_param.data = &value; + + if (custom_qapi(device_id, ATH_GET_PHY_MODE, &inout_param) != A_OK) + { + return A_ERROR; + } + + if (*(uint32_t *)(inout_param.data) == 0x01) + { + *pphymode = (char*)qcom_phy_mode_a; + } + else if (*(uint32_t *)(inout_param.data) == 0x02) + { + *pphymode = (char*)qcom_phy_mode_g; + } + else if (*(uint32_t *)(inout_param.data) == 0x04) + { + *pphymode = (char*)qcom_phy_mode_b; + } + else + { + *pphymode = (char*)qcom_phy_mode_mixed; + } + return A_OK; +} + +A_STATUS qcom_get_country_code(uint8_t device_id, uint8_t *countryCode) +{ + ATH_IOCTL_PARAM_STRUCT inout_param; + WMI_GET_COUNTRY_CODE_REPLY para_countryCode; + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + + inout_param.cmd_id = ATH_GET_COUNTRY_CODE; + inout_param.data = (uint8_t *)¶_countryCode; + inout_param.length = sizeof(para_countryCode); + + if (custom_qapi(device_id, ATH_GET_COUNTRY_CODE, &inout_param) != A_OK) + { + return A_ERROR; + } + A_MEMCPY(countryCode, para_countryCode.country_code, 3); + + return A_OK; +} + +A_STATUS qcom_set_country_code(uint8_t device_id, uint8_t *countryCode) +{ + ATH_IOCTL_PARAM_STRUCT inout_param; + ATH_PROGRAM_COUNTRY_CODE_PARAM data; + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + + A_MEMZERO(data.countryCode, 3); + A_MEMCPY(data.countryCode, countryCode, 3); + + inout_param.cmd_id = ATH_PROGRAM_COUNTRY_CODE; + inout_param.length = sizeof(data); + inout_param.data = (uint8_t *)&data; + + if (custom_qapi(device_id, ATH_PROGRAM_COUNTRY_CODE, &inout_param) != A_OK) + { + QCADRV_PRINTF("countryCode PROGRAM ERROR: unknown driver error\n"); + return A_ERROR; + } + else + { + switch (data.result) + { + case ATH_PROGRAM_COUNTRY_CODE_RESULT_DRIVER_FAILED: + QCADRV_PRINTF("COUNTRY_CODE PROGRAM ERROR: the driver was unable to complete the request.\n"); + break; + case ATH_PROGRAM_COUNTRY_CODE_RESULT_SUCCESS: + QCADRV_PRINTF("COUNTRY_CODE PROGRAM SUCCESS.\n"); + break; + case ATH_PROGRAM_COUNTRY_CODE_RESULT_DEV_DENIED: + QCADRV_PRINTF("COUNTRY_CODE PROGRAM ERROR: the firmware failed to program the country_code.\n"); + QCADRV_PRINTF(" possibly the same COUNTRY_CODEis already programmed.\n"); + break; + case ATH_PROGRAM_COUNTRY_CODE_RESULT_DEV_FAILED: + default: + QCADRV_PRINTF("COUNTRY_CODE PROGRAM ERROR: Device unknown failure.\n"); + break; + } + } + + return A_OK; +} +A_STATUS qcom_set_phy_mode(uint8_t device_id, uint8_t phymode) +{ +#define BUF_LEN 20 + ATH_IOCTL_PARAM_STRUCT inout_param; + A_STATUS error = A_OK; + char p[BUF_LEN]; + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + if (phymode == QCOM_11A_MODE) + strcpy(p, "a"); + else if (phymode == QCOM_11B_MODE) + strcpy(p, "b"); + else if (phymode == QCOM_11G_MODE) + strcpy(p, "g"); + else if (phymode == QCOM_11N_MODE) + strcpy(p, "n"); + else if (phymode == QCOM_HT40_MODE) + strcpy(p, "ht40"); + + inout_param.cmd_id = ATH_SET_PHY_MODE; + inout_param.data = p; + inout_param.length = strlen(p); + + if (custom_qapi(device_id, ATH_SET_PHY_MODE, &inout_param) != A_OK) + { + error = A_ERROR; + } + return error; +} + +A_STATUS qcom_set_channel(uint8_t device_id, uint16_t channel) +{ + ATH_IOCTL_PARAM_STRUCT inout_param; + A_STATUS error = A_OK; + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + + if (channel < 1 || channel > 165) + { + return A_ERROR; + } + if (channel < 27) + { + channel = ATH_IOCTL_FREQ_1 + (channel - 1) * 5; + } + else + { + channel = (5000 + (channel * 5)); + } + + inout_param.cmd_id = ATH_SET_CHANNEL; + inout_param.data = &channel; + inout_param.length = 4; + + if (custom_qapi(device_id, ATH_SET_CHANNEL, &inout_param) != A_OK) + { + error = A_ERROR; + } + return error; +} + +A_STATUS qcom_get_channel(uint8_t device_id, uint16_t *pchannel) +{ + ATH_IOCTL_PARAM_STRUCT inout_param = {0}; + A_STATUS error = A_OK; + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + inout_param.cmd_id = ATH_GET_CHANNEL; + inout_param.data = pchannel; + + if (custom_qapi(device_id, ATH_GET_CHANNEL, &inout_param) != A_OK) + { + error = A_ERROR; + } + return error; +} + +A_STATUS qcom_get_tx_power(uint8_t device_id, uint32_t *pdbm) +{ + /* No command id for get tx_power */ + return A_OK; +} + +A_STATUS qcom_set_tx_power(uint8_t device_id, uint32_t dbm) +{ + ATH_IOCTL_PARAM_STRUCT inout_param; + A_STATUS error = A_OK; + uint8_t pdBm; + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + pdBm = (uint8_t)dbm; + inout_param.cmd_id = ATH_SET_TXPWR; + inout_param.data = &pdBm; + inout_param.length = 1; // strlen(dBm); + + if (custom_qapi(device_id, ATH_SET_TXPWR, &inout_param) != A_OK) + { + error = A_ERROR; + } + return error; +} + +A_STATUS qcom_allow_aggr_set_tid(uint8_t device_id, uint16_t tx_allow_aggr, uint16_t rx_allow_aggr) +{ + A_STATUS error = A_OK; + ATH_SET_AGGREGATION_PARAM param; + ATH_IOCTL_PARAM_STRUCT inout_param; + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + + param.txTIDMask = tx_allow_aggr; + param.rxTIDMask = rx_allow_aggr; + + inout_param.cmd_id = ATH_SET_AGGREGATION; + inout_param.data = ¶m; + inout_param.length = sizeof(ATH_SET_AGGREGATION_PARAM); + if (custom_qapi(device_id, ATH_SET_AGGREGATION, &inout_param) != A_OK) + { + error = A_ERROR; + } + return error; +} + +A_STATUS qcom_scan_set_mode(uint8_t device_id, uint32_t mode) +{ + A_STATUS error = A_OK; + ATH_IOCTL_PARAM_STRUCT inout_param; + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + inout_param.cmd_id = ATH_SCAN_CTRL; + inout_param.data = &mode; + inout_param.length = 4; + + if (custom_qapi(device_id, ATH_SCAN_CTRL, &inout_param) != A_OK) + { + error = A_ERROR; + } + return error; +} + +A_STATUS qcom_scan_params_set(uint8_t device_id, qcom_scan_params_t *pParam) +{ + A_STATUS error = A_OK; + ATH_IOCTL_PARAM_STRUCT inout_param; + WMI_SCAN_PARAMS_CMD scan_param; + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + + scan_param.fg_start_period = pParam->fgStartPeriod; + scan_param.fg_end_period = pParam->fgEndPeriod; + scan_param.bg_period = pParam->bgPeriod; + scan_param.maxact_chdwell_time = pParam->maxActChDwellTimeInMs; + scan_param.pas_chdwell_time = pParam->pasChDwellTimeInMs; + scan_param.shortScanRatio = pParam->shortScanRatio; + scan_param.scanCtrlFlags = pParam->scanCtrlFlags; + scan_param.minact_chdwell_time = pParam->minActChDwellTimeInMs; + scan_param.maxact_scan_per_ssid = pParam->maxActScanPerSsid; + scan_param.max_dfsch_act_time = pParam->maxDfsChActTimeInMs; + + inout_param.cmd_id = ATH_SET_SCAN_PARAM; + inout_param.data = &scan_param; + inout_param.length = sizeof(WMI_SCAN_PARAMS_CMD); + + if (custom_qapi(device_id, ATH_SET_SCAN_PARAM, &inout_param) != A_OK) + { + error = A_ERROR; + } + return error; +} + +/*************************************************************************************** +* QCOM SECURITY APIs +***************************************************************************************/ +/*FUNCTION*----------------------------------------------------------------- +* +* Function Name : set_wep_key +* Returned Value : A_ERROR on error else A_OK +* Comments : Store WEP key for later use. Size of Key must be 10 or 26 +* Hex characters +* +*END------------------------------------------------------------------*/ +A_STATUS qcom_sec_set_wepkey(uint8_t device_id, uint32_t keyindex, char *pkey) +{ + A_STATUS error = A_OK; + uint32_t len = strlen(pkey); + ATH_IOCTL_PARAM_STRUCT inout_param; + ATH_WEPKEYS param; + + param.defKeyIndex = keyindex; + param.keyLength = len; + param.numKeys = 1; + param.keys[0] = pkey; + + inout_param.cmd_id = ATH_SET_WEPKEY; + inout_param.data = ¶m; + inout_param.length = sizeof(ATH_WEPKEYS); + if (custom_qapi(device_id, ATH_SET_WEPKEY, &inout_param) != A_OK) + { + error = A_ERROR; + } + + return error; +} + +A_STATUS qcom_sec_get_wepkey(uint8_t device_id, uint32_t keyindex, char *pkey) +{ + A_STATUS error = A_OK; + ATH_IOCTL_PARAM_STRUCT inout_param; + ATH_WEPKEYS param; + + param.defKeyIndex = keyindex; + param.numKeys = 1; + param.keys[0] = pkey; + + inout_param.cmd_id = ATH_GET_WEPKEY; + inout_param.data = ¶m; + inout_param.length = sizeof(ATH_WEPKEYS); + if (custom_qapi(device_id, ATH_GET_WEPKEY, &inout_param) != A_OK) + { + error = A_ERROR; + } + + return error; +} + +A_STATUS qcom_sec_set_wepkey_index(uint8_t device_id, uint32_t keyindex) +{ + ATH_IOCTL_PARAM_STRUCT inout_param; + uint32_t param; + + param = keyindex; + + inout_param.cmd_id = ATH_SET_WEPINDEX; + inout_param.data = ¶m; + inout_param.length = sizeof(uint32_t); + if (custom_qapi(device_id, ATH_SET_WEPINDEX, &inout_param) != A_OK) + { + return A_ERROR; + } + + param = WLAN_AUTH_WEP; + return (custom_qapi(device_id, ATH_SET_SEC_TYPE, ¶m)); +} + +A_STATUS qcom_sec_get_wepkey_index(uint8_t device_id, uint32_t *pkeyindex) +{ + ATH_IOCTL_PARAM_STRUCT inout_param; + uint32_t param; + + inout_param.cmd_id = ATH_GET_WEPINDEX; + inout_param.data = ¶m; + inout_param.length = sizeof(uint32_t); + if (custom_qapi(device_id, ATH_GET_WEPINDEX, &inout_param) != A_OK) + { + return A_ERROR; + } + + *pkeyindex = param; + return A_OK; +} + +A_STATUS qcom_sec_set_auth_mode(uint8_t device_id, WLAN_AUTH_MODE mode) +{ + uint32_t inout_param = {0}; + if ((uint32_t)mode >= (uint32_t)WLAN_AUTH_INVALID) + { + return A_ERROR; + } + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + inout_param = mode; + return (custom_qapi(device_id, ATH_SET_SEC_TYPE, &inout_param)); +} + +A_STATUS qcom_sec_set_encrypt_mode(uint8_t device_id, WLAN_CRYPT_TYPE mode) +{ + cipher_t cipher_mode; + ATH_IOCTL_PARAM_STRUCT inout_param = {0}; + + /* NOTE: lower layer does not perform *any* range check !! */ + if ((uint32_t)mode >= (uint32_t)WLAN_CRYPT_INVALID) + { + return A_ERROR; + } + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + + cipher_mode.ucipher = 0x1 << mode; + cipher_mode.mcipher = cipher_mode.ucipher; + inout_param.cmd_id = ATH_SET_CIPHER; + inout_param.data = &cipher_mode; + inout_param.length = sizeof(cipher_t); + + if (A_OK != custom_qapi(device_id, ATH_SET_CIPHER, &inout_param)) + { + return A_ERROR; + } + + return A_OK; +} + +A_STATUS qcom_sec_set_passphrase(uint8_t device_id, QCOM_PASSPHRASE *passphrase) +{ + ATH_IOCTL_PARAM_STRUCT param = {0}; + if (NULL == passphrase) + { + return A_ERROR; + } + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + + param.data = passphrase; + param.length = strlen(passphrase->passphrase); + + if (param.length >= sizeof(QCOM_PASSPHRASE)) + { + return A_ERROR; + } + if (A_OK != custom_qapi(device_id, ATH_SET_PASSPHRASE, ¶m)) + { + return A_ERROR; + } + return A_OK; +} + +A_STATUS qcom_sec_set_pmk(uint8_t device_id, char *pmk) +{ + int j; + uint8_t val = 0; + WMI_SET_PMK_CMD cmd; + ATH_IOCTL_PARAM_STRUCT inout_param; + A_STATUS error = A_OK; + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + + A_MEMZERO(cmd.pmk, WMI_PMK_LEN); + cmd.pmk_len = WMI_PMK_LEN; + + for (j = 0; j < 64; j++) + { + val = Util_Ascii2Hex(pmk[j]); + if (val == 0xff) + { + QCADRV_PRINTF("Invalid character\n"); + return A_ERROR; + } + else + { + if ((j & 1) == 0) + val <<= 4; + + cmd.pmk[j >> 1] |= val; + } + } + + inout_param.cmd_id = ATH_SET_PMK; + inout_param.data = &cmd; + inout_param.length = sizeof(cmd); + if (custom_qapi(device_id, ATH_SET_PMK, &inout_param) != A_OK) + { + error = A_ERROR; + } + return error; +} + +A_STATUS qcom_power_set_mode(uint8_t device_id, uint32_t powerMode, uint8_t powerModule) +{ + ATH_IOCTL_PARAM_STRUCT param; + POWER_MODE power; + A_STATUS error = A_OK; + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + + power.pwr_module = powerModule; + power.pwr_mode = powerMode; + + param.cmd_id = ATH_SET_POWER; + param.data = (void *)&power; + param.length = sizeof(POWER_MODE); + + if (custom_qapi(device_id, ATH_SET_POWER, ¶m) != A_OK) + { + error = A_ERROR; + } + + return error; +} + +A_STATUS qcom_power_get_mode(uint8_t device_id, uint32_t *powerMode) +{ + uint32_t inout_param = 0; + A_STATUS error; + + error = custom_qapi(device_id, ATH_GET_POWER, &inout_param); + if (A_OK != error) + { + return A_ERROR; + } + + if (inout_param == 1) + { + *powerMode = REC_POWER; + } + else if (inout_param == 0) + { + *powerMode = MAX_PERF_POWER; + } + else + { + *powerMode = 0; + } + return error; +} + +A_STATUS qcom_suspend_enable(boolean enable) +{ + ATH_IOCTL_PARAM_STRUCT inout_param; + A_STATUS error = A_OK; + + inout_param.cmd_id = ATH_DEVICE_SUSPEND_ENABLE; + inout_param.data = NULL; + inout_param.length = 0; + + if (custom_qapi(0, ATH_DEVICE_SUSPEND_ENABLE, &inout_param) != A_OK) + { + error = A_ERROR; + } + + return error; +} + +A_STATUS qcom_suspend_start(uint32_t susp_time) +{ + uint32_t suspend_time; + ATH_IOCTL_PARAM_STRUCT inout_param; + A_STATUS error = A_OK; + + suspend_time = susp_time; + inout_param.cmd_id = ATH_DEVICE_SUSPEND_START; + inout_param.data = &suspend_time; + inout_param.length = sizeof(uint32_t); + + if (custom_qapi(0, ATH_DEVICE_SUSPEND_START, &inout_param) != A_OK) + { + error = A_ERROR; + } + + return error; +} + +A_STATUS qcom_power_set_parameters(uint8_t device_id, + uint16_t idlePeriod, + uint16_t psPollNum, + uint16_t dtimPolicy, + uint16_t tx_wakeup_policy, + uint16_t num_tx_to_wakeup, + uint16_t ps_fail_event_policy) +{ + ATH_WMI_POWER_PARAMS_CMD pm; + ATH_IOCTL_PARAM_STRUCT inout_param; + A_STATUS error = A_OK; + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + pm.idle_period = idlePeriod; + pm.pspoll_number = psPollNum; + pm.dtim_policy = dtimPolicy; + pm.tx_wakeup_policy = tx_wakeup_policy; + pm.num_tx_to_wakeup = num_tx_to_wakeup; + pm.ps_fail_event_policy = ps_fail_event_policy; + + inout_param.cmd_id = ATH_SET_PMPARAMS; + inout_param.data = ± + inout_param.length = sizeof(ATH_WMI_POWER_PARAMS_CMD); + + if (custom_qapi(device_id, ATH_SET_PMPARAMS, &inout_param) != A_OK) + { + error = A_ERROR; + } + + return error; +} + +A_STATUS qcom_get_bssid(uint8_t device_id, uint8_t mac_addr[ATH_MAC_LEN]) +{ + ATH_IOCTL_PARAM_STRUCT inout_param; + A_STATUS error = A_OK; + + inout_param.cmd_id = ATH_GET_MACADDR; + inout_param.data = mac_addr; + inout_param.length = ATH_MAC_LEN; + + if (custom_qapi(device_id, ATH_GET_MACADDR, &inout_param) != A_OK) + { + error = A_ERROR; + } + return error; +} + +/*************************************************************************************************************** +* QCOM WPS APIs +****************************************************************************************************************/ + +A_STATUS qcom_wps_start(uint8_t device_id, int connect, int use_pinmode, char *pin) +{ +#define WPS_STANDARD_TIMEOUT (30) + ATH_IOCTL_PARAM_STRUCT param; + ATH_WPS_START wps_start; + A_STATUS error = A_OK; + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + + do + { + A_MEMZERO(&wps_start, sizeof(ATH_WPS_START)); + param.cmd_id = ATH_START_WPS; + param.data = &wps_start; + param.length = sizeof(wps_start); + + wps_start.connect_flag = connect; + if (use_pinmode == 0) + { + wps_start.wps_mode = ATH_WPS_MODE_PIN; + wps_start.pin_length = strlen(pin); + // FIXME: This hardcoded pin value needs to be changed + // for production to reflect what is on a sticker/label + // TODO: what is this ???? + memcpy(wps_start.pin, pin, wps_start.pin_length + 1); + } + else + { + wps_start.wps_mode = ATH_WPS_MODE_PUSHBUTTON; + } + wps_start.timeout_seconds = WPS_STANDARD_TIMEOUT; + + if (gWpsCredentials.ssid_len == 0) + { + wps_start.ssid_info.ssid_len = 0; + } + else + { + memcpy(wps_start.ssid_info.ssid, &gWpsCredentials.ssid, sizeof(wps_start.ssid_info.ssid)); + memcpy(wps_start.ssid_info.macaddress, gWpsCredentials.mac_addr, ATH_MAC_LEN); + wps_start.ssid_info.channel = gWpsCredentials.ap_channel; + wps_start.ssid_info.ssid_len = gWpsCredentials.ssid_len; + } + + /* this starts WPS on the Aheros wifi */ + if (custom_qapi(device_id, ATH_START_WPS, ¶m) != A_OK) + { + error = A_ERROR; + } + } while (0); + + return error; +} + +A_STATUS qcom_wps_connect(uint8_t device_id) +{ + qcom_set_ssid(device_id, &gWpsCredentials.ssid); + if (gWpsCredentials.key_idx != 0) + { + qcom_sec_set_wepkey(device_id, gWpsCredentials.key_idx, (char *)gWpsCredentials.key); + qcom_sec_set_wepkey_index(device_id, gWpsCredentials.key_idx); + } + else if (gWpsCredentials.auth_type != WLAN_AUTH_NONE) + { + qcom_sec_set_auth_mode(device_id, gWpsCredentials.auth_type); + qcom_sec_set_encrypt_mode(device_id, gWpsCredentials.encr_type); + } + + return qcom_commit(device_id); +} + +A_STATUS qcom_wps_set_credentials(uint8_t device_id, qcom_wps_credentials_t *pwps_prof) +{ + /* save wps credentials */ + A_MEMZERO(&gWpsCredentials, sizeof(qcom_wps_credentials_t)); + if (pwps_prof != NULL) + A_MEMCPY(&gWpsCredentials, pwps_prof, sizeof(qcom_wps_credentials_t)); + return A_OK; +} + +A_STATUS qcom_param_set( + uint8_t device_id, uint16_t grp_id, uint16_t param_id, void *data, uint32_t data_length, boolean wait_for_status) +{ + A_STATUS error = A_OK; + ATH_IOCTL_PARAM_STRUCT inout_param; + uint32_t which_param = QCOM_PARAM_MAKE_ID(grp_id, param_id); + uint32_t cmd_length = sizeof(WMI_PARAM_SET_CMD) + data_length - 1; + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + + WMI_PARAM_SET_CMD *cmd = (WMI_PARAM_SET_CMD *)A_MALLOC(cmd_length + sizeof(boolean), MALLOC_ID_CONTEXT); + + if (!cmd) + { + QCADRV_PRINTF("malloc fail\n"); + return A_ERROR; + } + cmd->length = cmd_length; + cmd->which_param = which_param; + memcpy(cmd->data_buffer, data, data_length); + + inout_param.cmd_id = ATH_SET_PARAM; + inout_param.data = cmd; + *((uint32_t *)((uint8_t *)(inout_param.data) + cmd_length)) = wait_for_status; + inout_param.length = cmd_length; + + if (custom_qapi(device_id, ATH_SET_PARAM, &inout_param) != A_OK) + { + error = A_ERROR; + } + + A_FREE(cmd, MALLOC_ID_CONTEXT); + + return error; +} + +#if ENABLE_P2P_MODE + +A_STATUS qcom_p2p_enable(uint8_t device_id, P2P_DEV_CTXT *dev, int32_t enable) +{ + ATH_IOCTL_PARAM_STRUCT param; + A_STATUS error = A_OK; + WMI_P2P_SET_PROFILE_CMD p2p; + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + A_MEMZERO(&p2p, sizeof(WMI_P2P_SET_PROFILE_CMD)); + p2p.enable = enable; + + param.cmd_id = ATH_P2P_SWITCH; + param.data = &p2p; + param.length = sizeof(p2p); + if (custom_qapi(device_id, ATH_P2P_SWITCH, ¶m) != A_OK) + { + error = A_ERROR; + } + return error; +} + +static A_STATUS qcom_p2p_group_init(uint8_t device_id, uint8_t persistent_group, uint8_t group_formation) +{ + ATH_IOCTL_PARAM_STRUCT param; + A_STATUS error = A_OK; + WMI_P2P_GRP_INIT_CMD grpInit; + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + A_MEMZERO(&grpInit, sizeof(WMI_P2P_GRP_INIT_CMD)); + grpInit.group_formation = group_formation; + grpInit.persistent_group = persistent_group; + + param.cmd_id = ATH_P2P_APMODE; + param.data = &grpInit; + param.length = sizeof(grpInit); + if (custom_qapi(device_id, ATH_P2P_APMODE, ¶m) != A_OK) + { + error = A_ERROR; + } + return error; +} + +static A_STATUS qcom_set_ap_params(uint8_t device_id, uint16_t param_cmd, uint8_t *data_val) +{ + ATH_IOCTL_PARAM_STRUCT inout_param = {0}; + ATH_AP_PARAM_STRUCT ap_param; + A_STATUS error = A_OK; + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + + inout_param.cmd_id = ATH_CONFIG_AP; + ap_param.cmd_subset = param_cmd; + ap_param.data = data_val; + inout_param.data = &ap_param; + + if (custom_qapi(device_id, ATH_CONFIG_AP, &inout_param) != A_OK) + { + error = A_ERROR; + } + return error; +} + +A_STATUS qcom_p2p_func_start_go( + uint8_t device_id, QCOM_SSID *pssid, QCOM_PASSPHRASE *ppass, int32_t channel, boolean ucpersistent) +{ + A_STATUS error = A_OK; + uint8_t wps_flag; + + qcom_sec_set_auth_mode(device_id, WLAN_AUTH_WPA2_PSK); + qcom_sec_set_encrypt_mode(device_id, WLAN_CRYPT_AES_CRYPT); + if (pssid != NULL) + { + qcom_p2p_func_set_pass_ssid(device_id, ppass, pssid); + } + + qcom_op_set_mode(device_id, QCOM_WLAN_DEV_MODE_AP); + + if (channel != P2P_AUTO_CHANNEL) + { + qcom_set_channel(device_id, channel); + } + + wps_flag = 0x01; + if (qcom_set_ap_params(device_id, AP_SUB_CMD_WPS_FLAG, &wps_flag) != A_OK) + { + return A_ERROR; + } + + qcom_op_set_mode(device_id, QCOM_WLAN_DEV_MODE_AP); + + if (qcom_p2p_group_init(device_id, ucpersistent, 1) != A_OK) + { + return A_ERROR; + } + + /* Set MAX PERF */ + qcom_power_set_mode(device_id, MAX_PERF_POWER, P2P); + return error; +} + +A_STATUS qcom_p2p_func_init(uint8_t device_id, int32_t enable) +{ + static int32_t p2p_enable_flag = 0xFEFE; + + if (enable == p2p_enable_flag) + { + return A_OK; + } + p2p_enable_flag = enable; + + qcom_p2p_enable(device_id, NULL, enable); + qcom_p2p_func_set_config(device_id, 0, 1, 1, 3000, 81, 81, 5); + + return A_OK; +} + +A_STATUS qcom_p2p_func_find(uint8_t device_id, void *dev, uint8_t type, uint32_t timeout) +{ + WMI_P2P_FIND_CMD find_params; + ATH_IOCTL_PARAM_STRUCT param; + A_STATUS error = A_OK; + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + find_params.type = type; + find_params.timeout = A_CPU2LE32(timeout); + param.cmd_id = ATH_P2P_FIND; + param.data = &find_params; + param.length = sizeof(WMI_P2P_FIND_CMD); + if (custom_qapi(device_id, ATH_P2P_FIND, ¶m) != A_OK) + { + error = A_ERROR; + } + return error; +} + +A_STATUS qcom_p2p_func_set_pass_ssid(uint8_t device_id, QCOM_PASSPHRASE *ppass, QCOM_SSID *pssid) +{ + ATH_IOCTL_PARAM_STRUCT param; + A_STATUS error = A_OK; + WMI_SET_PASSPHRASE_CMD setPassPhrase; + + if (qcom_set_ssid(device_id, pssid) != A_OK) + return A_ERROR; + + strcpy((char *)setPassPhrase.passphrase, ppass->passphrase); + setPassPhrase.passphrase_len = strlen(ppass->passphrase); + strcpy((char *)setPassPhrase.ssid, pssid->ssid); + setPassPhrase.ssid_len = strlen(pssid->ssid); + + param.cmd_id = ATH_P2P_APMODE_PP; + param.data = &setPassPhrase; + param.length = sizeof(WMI_SET_PASSPHRASE_CMD); + if (custom_qapi(device_id, ATH_P2P_APMODE_PP, ¶m) != A_OK) + { + error = A_ERROR; + } + + return error; +} + +A_STATUS qcom_p2p_func_listen(uint8_t device_id, uint32_t timeout) +{ + ATH_IOCTL_PARAM_STRUCT param; + A_STATUS error = A_OK; + uint32_t tout; + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + + tout = timeout; + param.cmd_id = ATH_P2P_LISTEN; + param.data = &tout; + param.length = sizeof(tout); + if (custom_qapi(device_id, ATH_P2P_LISTEN, ¶m) != A_OK) + { + error = A_ERROR; + } + return error; +} + +A_STATUS qcom_p2p_func_connect(uint8_t device_id, P2P_WPS_METHOD wps_method, uint8_t *peer_mac, boolean persistent) +{ + ATH_IOCTL_PARAM_STRUCT param; + A_STATUS error = A_OK; + WMI_P2P_FW_CONNECT_CMD_STRUCT p2p_connect; + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + + A_MEMZERO(&p2p_connect, sizeof(WMI_P2P_FW_CONNECT_CMD_STRUCT)); + p2p_connect.wps_method = wps_method; + A_MEMCPY(p2p_connect.peer_addr, peer_mac, ATH_MAC_LEN); + + /* Setting Default Value for now !!! */ + p2p_connect.dialog_token = 1; + p2p_connect.go_intent = 0; + p2p_connect.go_dev_dialog_token = 0; + p2p_connect.dev_capab = 0x23; + if (persistent) + { + p2p_connect.dev_capab |= P2P_PERSISTENT_FLAG; + } + + param.cmd_id = ATH_P2P_CONNECT_CLIENT; + param.data = &p2p_connect; + param.length = sizeof(WMI_P2P_FW_CONNECT_CMD_STRUCT); + if (custom_qapi(device_id, ATH_P2P_CONNECT_CLIENT, ¶m) != A_OK) + { + error = A_ERROR; + } + return error; +} + +A_STATUS qcom_p2p_func_auth( + uint8_t device_id, int32_t dev_auth, P2P_WPS_METHOD wps_method, uint8_t *peer_mac, boolean persistent) +{ + ATH_IOCTL_PARAM_STRUCT param; + A_STATUS error = A_OK; + WMI_P2P_FW_CONNECT_CMD_STRUCT p2p_connect; + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + A_MEMZERO(&p2p_connect, sizeof(WMI_P2P_FW_CONNECT_CMD_STRUCT)); + + if (persistent) + p2p_connect.dev_capab |= P2P_PERSISTENT_FLAG; + p2p_connect.dev_auth = dev_auth; + p2p_connect.wps_method = wps_method; + A_MEMCPY(p2p_connect.peer_addr, peer_mac, ATH_MAC_LEN); + /* If go_intent <= 0, wlan firmware will use the intent value configured via + * qcom_p2p_set + */ + p2p_connect.go_intent = 0; + + param.cmd_id = ATH_P2P_AUTH; + param.data = &p2p_connect; + param.length = sizeof(WMI_P2P_FW_CONNECT_CMD_STRUCT); + if (custom_qapi(device_id, ATH_P2P_AUTH, ¶m) != A_OK) + { + error = A_ERROR; + } + return error; +} + +A_STATUS qcom_p2p_func_cancel(uint8_t device_id) +{ + ATH_IOCTL_PARAM_STRUCT param; + A_STATUS error = A_OK; + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + + param.cmd_id = ATH_P2P_CANCEL; + param.data = NULL; + param.length = 0; + if (custom_qapi(device_id, ATH_P2P_CANCEL, ¶m) != A_OK) + { + error = A_ERROR; + } + return error; +} + +A_STATUS qcom_p2p_func_stop_find(uint8_t device_id) +{ + ATH_IOCTL_PARAM_STRUCT param; + A_STATUS error = A_OK; + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + param.cmd_id = ATH_P2P_STOP; + param.data = NULL; + param.length = 0; + if (custom_qapi(device_id, ATH_P2P_STOP, ¶m) != A_OK) + { + error = A_ERROR; + } + return error; +} + +/* NODE_LIST */ +A_STATUS qcom_p2p_func_get_node_list(uint8_t device_id, void *app_buf, uint32_t buf_size) +{ + ATH_IOCTL_PARAM_STRUCT param; + A_STATUS error = A_OK; + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + param.cmd_id = ATH_P2P_NODE_LIST; + param.data = app_buf; + param.length = buf_size; + if (custom_qapi(device_id, ATH_P2P_NODE_LIST, ¶m) != A_OK) + { + error = A_ERROR; + } + return error; +} + +A_STATUS qcom_p2p_func_set_config(uint8_t device_id, + uint32_t uigo_intent, + uint32_t uiclisten_ch, + uint32_t uiop_ch, + uint32_t uiage, + uint32_t reg_class, + uint32_t op_reg_class, + uint32_t max_node_count) +{ + ATH_IOCTL_PARAM_STRUCT param; + A_STATUS error = A_OK; + WMI_P2P_FW_SET_CONFIG_CMD stp2p_cfg_cmd; + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + A_MEMZERO(&stp2p_cfg_cmd, sizeof(stp2p_cfg_cmd)); + stp2p_cfg_cmd.go_intent = uigo_intent; + stp2p_cfg_cmd.reg_class = reg_class; + stp2p_cfg_cmd.op_reg_class = op_reg_class; + stp2p_cfg_cmd.op_channel = uiop_ch; + stp2p_cfg_cmd.listen_channel = uiclisten_ch; + stp2p_cfg_cmd.node_age_to = uiage; + stp2p_cfg_cmd.max_node_count = max_node_count; + + param.cmd_id = ATH_P2P_SET_CONFIG; + param.data = &stp2p_cfg_cmd; + param.length = sizeof(WMI_P2P_FW_SET_CONFIG_CMD); + if (custom_qapi(device_id, ATH_P2P_SET_CONFIG, ¶m) != A_OK) + { + error = A_ERROR; + } + return error; +} + +A_STATUS qcom_p2p_func_wps_config(uint8_t device_id, uint8_t *p2p_ptr) +{ + ATH_IOCTL_PARAM_STRUCT param; + A_STATUS error = A_OK; + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + + param.cmd_id = ATH_P2P_WPS_CONFIG; + param.data = p2p_ptr; + param.length = sizeof(WMI_WPS_SET_CONFIG_CMD); + if (custom_qapi(device_id, ATH_P2P_WPS_CONFIG, ¶m) != A_OK) + { + error = A_ERROR; + } + return error; +} + +A_STATUS qcom_p2p_func_disc_req(uint8_t device_id, uint8_t *p2p_ptr) +{ + ATH_IOCTL_PARAM_STRUCT param; + A_STATUS error = A_OK; + + param.cmd_id = ATH_P2P_DISC_REQ; + param.data = p2p_ptr; + param.length = sizeof(WMI_P2P_FW_PROV_DISC_REQ_CMD); + if (custom_qapi(device_id, ATH_P2P_DISC_REQ, ¶m) != A_OK) + { + error = A_ERROR; + } + return error; +} + +A_STATUS qcom_p2p_set(uint8_t device_id, P2P_CONF_ID config_id, void *data, uint32_t data_length) +{ + ATH_IOCTL_PARAM_STRUCT param; + A_STATUS error = A_OK; + WMI_P2P_SET_CMD p2p_set_params; + WMI_P2P_CONF_ID wmi_config_id; + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + A_MEMZERO(&p2p_set_params, sizeof(p2p_set_params)); + + /*TODO: aren't WMI_P2P_CONF_ID / P2P_CONF_ID the same ?*/ + switch (config_id) + { + case P2P_CONFIG_LISTEN_CHANNEL: + wmi_config_id = WMI_P2P_CONFID_LISTEN_CHANNEL; + break; + case P2P_CONFIG_CROSS_CONNECT: + wmi_config_id = WMI_P2P_CONFID_CROSS_CONNECT; + break; + case P2P_CONFIG_SSID_POSTFIX: + wmi_config_id = WMI_P2P_CONFID_SSID_POSTFIX; + break; + case P2P_CONFIG_INTRA_BSS: + wmi_config_id = WMI_P2P_CONFID_INTRA_BSS; + break; + case P2P_CONFIG_CONCURRENT_MODE: + wmi_config_id = WMI_P2P_CONFID_CONCURRENT_MODE; + break; + case P2P_CONFIG_GO_INTENT: + wmi_config_id = WMI_P2P_CONFID_GO_INTENT; + break; + case P2P_CONFIG_DEV_NAME: + wmi_config_id = WMI_P2P_CONFID_DEV_NAME; + break; + case P2P_CONFIG_P2P_OPMODE: + wmi_config_id = WMI_P2P_CONFID_P2P_OPMODE; + break; + case P2P_CONFIG_CCK_RATES: + wmi_config_id = WMI_P2P_CONFID_CCK_RATES; + break; + default: + /* Unknown parameter */ + return A_ERROR; + } + + p2p_set_params.config_id = wmi_config_id; + A_MEMCPY(&p2p_set_params.val, data, data_length); + + param.cmd_id = ATH_P2P_SET; + param.data = &p2p_set_params; + param.length = sizeof(WMI_P2P_SET_CMD); + if (custom_qapi(device_id, ATH_P2P_SET, ¶m) != A_OK) + { + error = A_ERROR; + } + return error; +} + +A_STATUS qcom_p2p_func_join(uint8_t device_id, P2P_WPS_METHOD wps_method, uint8_t *pmac, char *ppin, uint16_t channel) +{ + uint16_t conc_channel; + WMI_P2P_FW_CONNECT_CMD_STRUCT p2p_join_profile; + WMI_P2P_PROV_INFO p2p_info; + ATH_IOCTL_PARAM_STRUCT param; + A_STATUS error = A_OK; + +#if ENABLE_SCC_MODE + int num_dev = WLAN_NUM_OF_DEVICES; + if ((num_dev > 1) && (device_id == 0)) + { + qcom_get_concurrent_channel(device_id, &conc_channel); + if ((conc_channel != 0) && (channel == 0)) + { + return A_ERROR; + } + if ((conc_channel != 0) && (channel != conc_channel)) + { + return A_ERROR; + } + } +#endif /* ENABLE_SCC_MODE */ + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + + A_MEMZERO(&p2p_join_profile, sizeof(WMI_P2P_FW_CONNECT_CMD_STRUCT)); + A_MEMCPY(p2p_join_profile.peer_addr, pmac, ATH_MAC_LEN); + p2p_join_profile.go_oper_freq = channel; + p2p_join_profile.wps_method = wps_method; + + if (wps_method != (uint8_t)WPS_PBC) + { + strcpy(p2p_info.wps_pin, ppin); + wmi_save_key_info(&p2p_info); + } + + param.cmd_id = ATH_P2P_JOIN; + param.data = &p2p_join_profile; + param.length = sizeof(WMI_P2P_FW_CONNECT_CMD_STRUCT); + if (custom_qapi(device_id, ATH_P2P_JOIN, ¶m) != A_OK) + { + error = A_ERROR; + } + return error; +} + +A_STATUS qcom_p2p_func_invite_auth(uint8_t device_id, uint8_t *inv) +{ + ATH_IOCTL_PARAM_STRUCT param; + A_STATUS error = A_OK; + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + + param.cmd_id = ATH_P2P_INVITE_AUTH; + param.data = inv; + param.length = sizeof(WMI_P2P_FW_INVITE_REQ_RSP_CMD); + if (custom_qapi(device_id, ATH_P2P_INVITE_AUTH, ¶m) != A_OK) + { + error = A_ERROR; + } + return error; +} + +/* LIST_NETWORK */ +A_STATUS qcom_p2p_func_get_network_list(uint8_t device_id, void *app_buf, uint32_t buf_size) +{ + ATH_IOCTL_PARAM_STRUCT param; + A_STATUS error = A_OK; + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + param.cmd_id = ATH_P2P_PERSISTENT_LIST; + param.data = app_buf; + param.length = buf_size; + if (custom_qapi(device_id, ATH_P2P_PERSISTENT_LIST, ¶m) != A_OK) + { + error = A_ERROR; + } + return error; +} + +A_STATUS qcom_p2p_func_invite( + uint8_t device_id, char *pssid, P2P_WPS_METHOD wps_method, uint8_t *pmac, boolean persistent, P2P_INV_ROLE role) +{ + ATH_IOCTL_PARAM_STRUCT param; + A_STATUS error = A_OK; + WMI_P2P_INVITE_CMD p2pInvite; + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + + A_MEMZERO(&p2pInvite, sizeof(p2pInvite)); + + A_MEMCPY(p2pInvite.ssid.ssid, pssid, strlen(pssid)); + p2pInvite.ssid.ssidLength = strlen(pssid); + A_MEMCPY(p2pInvite.peer_addr, pmac, ATH_MAC_LEN); + p2pInvite.wps_method = wps_method; + p2pInvite.is_persistent = persistent; + p2pInvite.role = role; + + param.cmd_id = ATH_P2P_INVITE; + param.data = &p2pInvite; + param.length = sizeof(WMI_P2P_INVITE_CMD); + + if (custom_qapi(device_id, ATH_P2P_INVITE, ¶m) != A_OK) + { + error = A_ERROR; + } + return error; +} + +A_STATUS qcom_p2p_func_join_profile(uint8_t device_id, uint8_t *pmac) +{ + ATH_IOCTL_PARAM_STRUCT param; + A_STATUS error = A_OK; + WMI_P2P_FW_CONNECT_CMD_STRUCT p2p_connect; + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + A_MEMZERO(&p2p_connect, sizeof(p2p_connect)); + A_MEMCPY(p2p_connect.peer_addr, pmac, ATH_MAC_LEN); + + param.cmd_id = ATH_P2P_JOIN_PROFILE; + param.data = &p2p_connect; + param.length = sizeof(WMI_P2P_FW_CONNECT_CMD_STRUCT); + if (custom_qapi(device_id, ATH_P2P_JOIN_PROFILE, ¶m) != A_OK) + { + error = A_ERROR; + } + return error; +} + +A_STATUS qcom_p2p_ap_mode(uint8_t device_id, uint8_t *p2p_ptr) +{ + ATH_IOCTL_PARAM_STRUCT param; + A_STATUS error = A_OK; + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + param.cmd_id = ATH_P2P_APMODE; + param.data = p2p_ptr; + param.length = sizeof(WMI_P2P_GRP_INIT_CMD); + if (custom_qapi(device_id, ATH_P2P_APMODE, ¶m) != A_OK) + { + error = A_ERROR; + } + return error; +} + +A_STATUS qcom_p2p_func_on_off(uint8_t device_id, uint8_t *p2p_ptr) +{ + ATH_IOCTL_PARAM_STRUCT param; + A_STATUS error = A_OK; + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + param.cmd_id = ATH_P2P_SWITCH; + param.data = p2p_ptr; + param.length = sizeof(WMI_P2P_SET_PROFILE_CMD); + if (custom_qapi(device_id, ATH_P2P_SWITCH, ¶m) != A_OK) + { + error = A_ERROR; + } + return error; +} + +A_STATUS qcom_p2p_func_set_noa( + uint8_t device_id, uint8_t uccount, uint32_t uistart, uint32_t uiduration, uint32_t uiinterval) +{ + ATH_IOCTL_PARAM_STRUCT param; + A_STATUS error = A_OK; + P2P_NOA_INFO p2p_noa_desc; + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + if (uccount >= P2P_MAX_NOA_DESCRIPTORS) + { + return A_ERROR; + } + + A_MEMZERO(&p2p_noa_desc, sizeof(p2p_noa_desc)); + if (uccount > 0) + { + uint8_t i; + p2p_noa_desc.enable = 1; + p2p_noa_desc.count = uccount; + + for (i = 0; i < uccount; i++) + { + p2p_noa_desc.noas[i].count_or_type = uccount; + p2p_noa_desc.noas[i].duration = uiduration; + p2p_noa_desc.noas[i].interval = uiinterval; + p2p_noa_desc.noas[i].start_or_offset = uistart; + } + } + + param.cmd_id = ATH_P2P_SET_NOA; + param.data = &p2p_noa_desc; + param.length = sizeof(p2p_noa_desc); + if (custom_qapi(device_id, ATH_P2P_SET_NOA, ¶m) != A_OK) + { + error = A_ERROR; + } + return error; +} + +A_STATUS qcom_p2p_func_set_oppps(uint8_t device_id, uint8_t enable, uint8_t ctwin) +{ + ATH_IOCTL_PARAM_STRUCT param; + A_STATUS error = A_OK; + WMI_OPPPS_INFO_STRUCT p2p_oppps; + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + A_MEMZERO(&p2p_oppps, sizeof(WMI_OPPPS_INFO_STRUCT)); + p2p_oppps.enable = enable; + p2p_oppps.ctwin = ctwin; + + param.cmd_id = ATH_P2P_SET_OPPPS; + param.data = &p2p_oppps; + param.length = sizeof(WMI_OPPPS_INFO_STRUCT); + if (custom_qapi(device_id, ATH_P2P_SET_OPPPS, ¶m) != A_OK) + { + error = A_ERROR; + } + return error; +} + +A_STATUS qcom_p2p_func_prov(uint8_t device_id, P2P_WPS_METHOD wps_method, uint8_t *pmac) +{ + ATH_IOCTL_PARAM_STRUCT param; + A_STATUS error = A_OK; + WMI_P2P_FW_PROV_DISC_REQ_CMD p2p_prov_disc; + + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + A_MEMZERO(&p2p_prov_disc, sizeof(p2p_prov_disc)); + p2p_prov_disc.dialog_token = 1; + p2p_prov_disc.wps_method = wps_method; + A_MEMCPY(p2p_prov_disc.peer, pmac, ATH_MAC_LEN); + + param.cmd_id = ATH_P2P_DISC_REQ; + param.data = &p2p_prov_disc; + param.length = sizeof(p2p_prov_disc); + if (custom_qapi(device_id, ATH_P2P_DISC_REQ, ¶m) != A_OK) + { + error = A_ERROR; + } + return error; +} +#endif + +A_STATUS qcom_raw_mode_send_pkt(QCOM_RAW_MODE_PARAM_t *ppara) +{ + uint8_t access_cat; + int32_t i; + ATH_IOCTL_PARAM_STRUCT param; + ATH_MAC_TX_RAW_S details; + uint8_t *buffer = NULL; + typedef struct + { + uint8_t fc[2]; + uint8_t duration[2]; + uint8_t addr[3][6]; + uint8_t seq[2]; + } WIFI_HDR; + + typedef struct + { + uint8_t fc[2]; + uint8_t duration[2]; + uint8_t addr[3][6]; + uint8_t seq[2]; + uint8_t addr_3[6]; + uint8_t pad[2]; // pad required by firmware + } WIFI_4_HDR; + + typedef struct + { + uint8_t fc[2]; + uint8_t duration[2]; + uint8_t addr[3][6]; + uint8_t seq[2]; + uint8_t qos[2]; + uint8_t pad[2]; // pad required by firmware + } WIFI_QOS_HDR; +#define WIFI_HDR_SZ (24) +#define WIFI_4_HDR_SZ (32) +#define WIFI_QOS_HDR_SZ (28) + uint8_t header_sz[3] = {WIFI_HDR_SZ, WIFI_QOS_HDR_SZ, WIFI_4_HDR_SZ}; + WIFI_4_HDR *p4Hdr; + WIFI_HDR *pHdr; + WIFI_QOS_HDR *pQosHdr; + A_STATUS error = A_OK; + + uint8_t rate_index = ppara->rate_index; + uint8_t tries = ppara->tries; + uint32_t size = ppara->size; + uint32_t chan = ppara->chan; + uint8_t header_type = ppara->header_type; + uint16_t bcn_seq_num = ppara->seq; + uint8_t *paddr1 = &ppara->addr1.addr[0]; + uint8_t *paddr2 = &ppara->addr2.addr[0]; + uint8_t *paddr3 = &ppara->addr3.addr[0]; + uint8_t *paddr4 = &ppara->addr4.addr[0]; + uint8_t *pdatabuf = ppara->pdatabuf; + uint32_t buflen = ppara->buflen; + + do + { + if (rate_index > 19 || tries > 14 || size > 1400 || chan > 14 || header_type > 2) + { + error = A_ERROR; + break; + } + + if ((pdatabuf != NULL) && (buflen >= size)) + { + error = A_ERROR; + break; + } + + if (chan != 0) + { + error = qcom_set_channel(0, chan); + if (A_OK != error) + { + break; + } + } + + size += header_sz[header_type]; + if (NULL == (buffer = A_MALLOC(size, MALLOC_ID_CONTEXT))) + { + error = A_ERROR; + break; + } + + pHdr = (WIFI_HDR *)&buffer[0]; + + A_MEMZERO(pHdr, WIFI_HDR_SZ); + + pHdr->fc[0] = 0x80; // beacon + pHdr->seq[0] = ((bcn_seq_num & 0xf) << 4); + pHdr->seq[1] = ((bcn_seq_num & 0xff0) >> 4); + + A_MEMCPY(&pHdr->addr[0][0], paddr1, ATH_MAC_LEN); + A_MEMCPY(&pHdr->addr[1][0], paddr2, ATH_MAC_LEN); + A_MEMCPY(&pHdr->addr[2][0], paddr3, ATH_MAC_LEN); + + access_cat = ATH_ACCESS_CAT_BE; + + if (header_type == 1) + { + // change frame control to qos data + pHdr->fc[0] = 0x88; + pHdr->fc[1] = 0x01; // to-ds + pQosHdr = (WIFI_QOS_HDR *)pHdr; + pQosHdr->qos[0] = 0x03; + pQosHdr->qos[1] = 0x00; + // bssid == addr[0] + // memcpy(&(pHdr->addr[0][0]), &(pHdr->addr[1][0]), 6); + // change destination address + // pHdr->addr[2][3] = 0xaa; + // pHdr->addr[2][4] = 0xaa; + // pHdr->addr[2][5] = 0xaa; + access_cat = ATH_ACCESS_CAT_VI; + } + else if (header_type == 2) + { + pHdr->fc[0] = 0x08; + pHdr->fc[1] = 0x03; // to-ds | from-ds + p4Hdr = (WIFI_4_HDR *)pHdr; + p4Hdr->addr_3[0] = paddr4[0]; + p4Hdr->addr_3[1] = paddr4[1]; + p4Hdr->addr_3[2] = paddr4[2]; + p4Hdr->addr_3[3] = paddr4[3]; + p4Hdr->addr_3[4] = paddr4[4]; + p4Hdr->addr_3[5] = paddr4[5]; + } + + /* now setup the frame for transmission */ + if (pdatabuf == NULL) + { + for (i = header_sz[header_type]; i < (int32_t)size; i++) + buffer[i] = (i - header_sz[header_type]) & 0xff; + } + else + { + i = header_sz[header_type]; + A_MEMCPY(&(buffer[i]), pdatabuf, buflen); + } + + A_MEMZERO(&details, sizeof(details)); + + details.buffer = buffer; + details.length = size; + details.params.pktID = 1; + details.params.rateSched.accessCategory = access_cat; + /* we set the ACK bit simply to force the desired number of retries */ + details.params.rateSched.flags = ATH_MAC_TX_FLAG_ACK; + details.params.rateSched.trySeries[0] = tries; + details.params.rateSched.rateSeries[0] = rate_index; + details.params.rateSched.rateSeries[1] = 0xff; // terminate series + + param.cmd_id = ATH_MAC_TX_RAW; + param.data = &details; + param.length = sizeof(details); + + if (custom_qapi(0, ATH_MAC_TX_RAW, ¶m) != A_OK) + { + error = A_ERROR; + } + } while (0); + + if (buffer) + A_FREE(buffer, MALLOC_ID_CONTEXT); + + return error; +} + +A_STATUS qcom_get_versionstr(ATH_VERSION_STR *versionstr) +{ + ATH_IOCTL_PARAM_STRUCT param; + + param.cmd_id = ATH_GET_VERSION_STR; + param.data = versionstr; + param.length = sizeof(ATH_VERSION_STR); + + return custom_qapi(0, ATH_GET_VERSION_STR, ¶m); +} + +A_STATUS qcom_set_appie(uint8_t device_id, uint8_t mgmtType, uint8_t *appie, uint8_t ieLen) +{ + A_STATUS error = A_OK; + ATH_IOCTL_PARAM_STRUCT inout_param; + ATH_APPIE_PARAM param; + + if(A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + + /* appie is a hex string beginning with DD */ + param.mgmtFrmType = mgmtType; + param.ieLen = ieLen; + param.ieInfo = appie; + + inout_param.cmd_id = ATH_SET_APPIE; + inout_param.data = ¶m; + inout_param.length = sizeof(ATH_APPIE_PARAM); + + if(param.ieLen > ATH_MAX_IE_LEN) + { + PRINTF("Application-specified IE length exceeds Maximum value\n"); + return A_ERROR; + } + + if(custom_qapi(device_id, ATH_SET_APPIE, &inout_param) != A_OK) + { + error = A_ERROR; + } + + return error; +} + +A_STATUS qcom_wps_init_key (uint8_t device_id) +{ + ATH_IOCTL_PARAM_STRUCT inout_param; + A_STATUS error = A_OK; + + inout_param.cmd_id = ATH_WLAN_WPS_INIT_KEY; + inout_param.data = NULL; + inout_param.length = 0; + + if(custom_qapi(device_id, ATH_WLAN_WPS_INIT_KEY, &inout_param) != A_OK) + { + error = A_ERROR; + } + return error; +} + +A_STATUS qcom_heartbeat_challenge (uint8_t device_id) +{ + ATH_IOCTL_PARAM_STRUCT inout_param; + A_STATUS error = A_OK; + +#define HB_MAGIC 0x63825363L + + struct WMIX_GPIO_REGISTER_GET { + WMIX_CMD_HDR cmd; + WMIX_HB_CHALLENGE_RESP_CMD hb; + } hb_challenge_cmd; + + + hb_challenge_cmd.cmd.commandId =WMIX_HB_CHALLENGE_RESP_CMDID; + hb_challenge_cmd.hb.cookie = HB_MAGIC; + hb_challenge_cmd.hb.source = 0; //TODO + + inout_param.cmd_id = ATH_HEARTBEAT_CHALLEANGE; + inout_param.data = (void *)&hb_challenge_cmd; + inout_param.length = sizeof(hb_challenge_cmd); + + if(custom_qapi(device_id, ATH_HEARTBEAT_CHALLEANGE, &inout_param) != A_OK) + { + error = A_ERROR; + } + return error; +} + diff --git a/platform/mcu/lpc54102/wifi_qca/common_src/qapi/qcom_legacy.c b/platform/mcu/lpc54102/wifi_qca/common_src/qapi/qcom_legacy.c new file mode 100644 index 0000000000..90ab6ef54a --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/common_src/qapi/qcom_legacy.c @@ -0,0 +1,71 @@ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if ENABLE_P2P_MODE +#include +#include "p2p.h" +#endif +#include "atheros_wifi.h" +#include "atheros_wifi_api.h" +#include "atheros_wifi_internal.h" +#include "atheros_stack_offload.h" +#include "dset_api.h" +#include "common_stack_offload.h" +#include "qcom_api.h" + +extern A_STATUS qcom_set_deviceid(uint16_t id); +A_STATUS custom_qapi(uint8_t device_id, uint32_t cmd, void *param); + +/*-----------------------------------------------------------------------------------------------------------------*/ +A_STATUS depr_qcom_set_scan(uint8_t device_id) +{ + A_STATUS error = A_OK; + if (A_OK != qcom_set_deviceid(device_id)) + { + return A_ERROR; + } + if (custom_qapi(device_id, ATH_SET_SCAN, NULL) != A_OK) + error = A_ERROR; + + return error; +} + +A_STATUS depr_qcom_ota_done() +{ +#if ENABLE_STACK_OFFLOAD + return ((A_STATUS)custom_ota_done(Custom_Api_GetDriverCxt(0), 1)); +#else + return A_ERROR; +#endif +} diff --git a/platform/mcu/lpc54102/wifi_qca/common_src/reorder/rcv_aggr.c b/platform/mcu/lpc54102/wifi_qca/common_src/reorder/rcv_aggr.c new file mode 100644 index 0000000000..4e9d534bcf --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/common_src/reorder/rcv_aggr.c @@ -0,0 +1,187 @@ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== + +#include +#include +#include +#include +#include "wmi.h" +#include "atheros_wifi_api.h" + +#if WLAN_CONFIG_11N_AGGR_SUPPORT + +#define NUM_OF_TIDS 8 +#define AGGR_SZ_DEFAULT 8 + +#define IEEE80211_MAX_SEQ_NO 0xFFF + +typedef struct +{ + uint32_t aggr_enabled_tid_mask; /* config value of aggregation size */ + uint16_t seq_last[NUM_OF_TIDS]; +} AGGR_INFO; + +static AGGR_INFO aggr_context; + +void aggr_deinit(void *cntxt) +{ + UNUSED_ARGUMENT(cntxt); +} + +/*FUNCTION*------------------------------------------------------------- +* +* Function Name : aggr_init +* Returned Value : +* Comments : +* Initializes aggregation data structures. +* +*END*-----------------------------------------------------------------*/ +void *aggr_init(void) +{ + /* some implementations malloc a context but this version simply uses + * a global context */ + + aggr_reset_state((void *)&aggr_context); + + return &aggr_context; +} + +/*FUNCTION*------------------------------------------------------------- +* +* Function Name : aggr_recv_addba_req_evt +* Returned Value : +* Comments : +* Firmware has indicated that aggregation is enabled +* for this TID. +* +*END*-----------------------------------------------------------------*/ +void aggr_recv_addba_req_evt(void *cntxt, uint8_t tidaid, uint16_t seq_no, uint8_t win_sz) +{ + AGGR_INFO *p_aggr = (AGGR_INFO *)cntxt; + uint8_t tid = tidaid & 0xF; + A_ASSERT(p_aggr); + A_ASSERT(tid < NUM_OF_TIDS); + UNUSED_ARGUMENT(win_sz); + p_aggr->aggr_enabled_tid_mask |= (1 << tid); + p_aggr->seq_last[tid] = seq_no; +} + +/*FUNCTION*------------------------------------------------------------- +* +* Function Name : aggr_recv_delba_req_evt +* Returned Value : +* Comments : +* Firmware has indicated that aggregation is no longer enabled +* for this TID. +* +*END*-----------------------------------------------------------------*/ +void aggr_recv_delba_req_evt(void *cntxt, uint8_t tidaid) +{ + AGGR_INFO *p_aggr = (AGGR_INFO *)cntxt; + uint8_t tid = tidaid & 0xF; + A_ASSERT(p_aggr); + A_ASSERT(tid < NUM_OF_TIDS); + + p_aggr->aggr_enabled_tid_mask &= ~(1 << tid); +} + +/*FUNCTION*------------------------------------------------------------- +* +* Function Name : aggr_reset_state +* Returned Value : +* Comments : +* Called when it is deemed necessary to clear the aggregate +* hold Q state. Examples include when a Connect event or +* disconnect event is received. +* +*END*-----------------------------------------------------------------*/ +void aggr_reset_state(void *cntxt) +{ + AGGR_INFO *p_aggr = (AGGR_INFO *)cntxt; + + A_ASSERT(p_aggr); + + p_aggr->aggr_enabled_tid_mask = 0; +} + +/*FUNCTION*------------------------------------------------------------- +* +* Function Name : aggr_process_recv_frm +* Returned Value : true - forward frame it is in-order +* false - drop frame as its out-of-order +* Comments : +* Processes a received frame to determine whether it should be +* dropped. Aggregation allows for frames to be sent out-of-order +* which some systems/tcp stacks fail to handle. One option is +* to queue packets in the driver and re-order them so that the +* driver always delivers packets to the next layer in-order. +* That however requires significant buffer space and so this +* implementation instead will drop any out-of-order packets. +* it does this by returning true for in-order packets and +* false for out-of-order packets. If aggregation +* is not enabled then there is no need to monitor the tid +* and the return value will always be true. +* +*END*-----------------------------------------------------------------*/ +boolean aggr_process_recv_frm(void *cntxt, uint8_t tid, uint16_t seq_no, boolean is_amsdu, void **osbuf) +{ + AGGR_INFO *p_aggr = (AGGR_INFO *)cntxt; + boolean result = false; + A_ASSERT(p_aggr); + A_ASSERT(tid < NUM_OF_TIDS); + UNUSED_ARGUMENT(osbuf); + UNUSED_ARGUMENT(is_amsdu); + + do + { + if ((!p_aggr->aggr_enabled_tid_mask) & (1 << tid)) + { + result = true; + break; + } + + if (p_aggr->seq_last[tid] > seq_no) + { + if (p_aggr->seq_last[tid] - seq_no <= (IEEE80211_MAX_SEQ_NO >> 1)) + { + /* drop this out-of-order packet */ + break; + } + } + else + { + if (seq_no - p_aggr->seq_last[tid] > (IEEE80211_MAX_SEQ_NO >> 1)) + { + /* drop this out-of-order packet */ + break; + } + } + /* adopt the new seq_no and allow the packet */ + result = true; + p_aggr->seq_last[tid] = seq_no; + } while (0); + + return result; +} +#endif diff --git a/platform/mcu/lpc54102/wifi_qca/common_src/stack_common/api_stack_offload.c b/platform/mcu/lpc54102/wifi_qca/common_src/stack_common/api_stack_offload.c new file mode 100644 index 0000000000..34b7c3a873 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/common_src/stack_common/api_stack_offload.c @@ -0,0 +1,4641 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== +#include "a_config.h" + +// This conditional encapsulates the entire file +#if ENABLE_STACK_OFFLOAD + +#include "wifi_common.h" +#include +#include +#include +#include +#include "wmi_api.h" +#include "a_drv_api.h" +#include "cust_netbuf.h" +#include +#include "atheros_wifi_api.h" + +#include "atheros_stack_offload.h" +#include "common_stack_offload.h" +#include "custom_stack_offload.h" + +#define MAX_CERT_DATA_LENGTH 1400 +#define SSL_MAX_CERT_NAME_LEN 31 +extern const uint8_t max_performance_power_param; +ATH_SOCKET_CONTEXT *ath_sock_context[MAX_SOCKETS_SUPPORTED + 1]; + +/*****************************************************************************/ +/* custom_queue_empty - Checkes whether a socket queue is empty + * RETURNS: 1 - empty or 0 - not empty + *****************************************************************************/ +uint32_t queue_empty(uint32_t index) +{ + SOCKET_CONTEXT_PTR pcustctxt; + pcustctxt = GET_SOCKET_CONTEXT(ath_sock_context[index]); + + return A_NETBUF_QUEUE_EMPTY(&(pcustctxt->rxqueue)); +} + +#if ENABLE_SSL +void *sslhandle = NULL; // Driver context ptr needed by the SSL_xxx() API functions + +int32_t find_socket_context_from_ssl(SSL *ssl) +{ + int32_t index = 0; + + for (index = 0; index < MAX_SOCKETS_SUPPORTED; index++) + { + if (ath_sock_context[index]->ssl == ssl) + return index; + } + /*Index not found*/ + return SOCKET_NOT_FOUND; +} +#endif + +/*****************************************************************************/ +/* find_socket_context - Finds socket context based on socket handle. "retrieve" + * flag is used to identify if a new context is requested or an + * exiting context is retrieved. + * uint32_t handle - socket handle. + * uint8_t retrieve - see description + * Returns- index in context array + *****************************************************************************/ +int32_t find_socket_context(uint32_t handle, uint8_t retrieve) +{ + int32_t index = 0; + if (retrieve) + { + if (handle == 0) + return SOCKET_NOT_FOUND; + } + + /*If handle is 0, we want to find first empty context and return the index. + If handle is non zero, return the index that matches */ + for (index = 0; index < MAX_SOCKETS_SUPPORTED; index++) + { + if ((uint32_t)ath_sock_context[index]->handle == handle) + return index; + } + /*Index not found*/ + return SOCKET_NOT_FOUND; +} + +/*****************************************************************************/ +/* socket_context_init - Initializes common socket context, called during + * driver init. + * + * Returns- A_OK in case of successful init, A_ERROR otherwise + *****************************************************************************/ +A_STATUS socket_context_init(void) +{ + SOCKET_CONTEXT_PTR pcustctxt = NULL; + uint32_t index = 0; + + for (index = 0; index < MAX_SOCKETS_SUPPORTED + 1; index++) + { + /*Allocate socket contexts*/ + if ((ath_sock_context[index] = A_MALLOC(sizeof(ATH_SOCKET_CONTEXT), MALLOC_ID_CONTEXT)) == NULL) + return A_NO_MEMORY; + + memset(ath_sock_context[index], 0, sizeof(ATH_SOCKET_CONTEXT)); + } + + for (index = 0; index < MAX_SOCKETS_SUPPORTED + 1; index++) + { + if ((pcustctxt = A_MALLOC(sizeof(SOCKET_CONTEXT), MALLOC_ID_CONTEXT)) == NULL) + { + return A_NO_MEMORY; + } + A_EVENT_INIT(&pcustctxt->sockRxWakeEvent, kEventManualClear); + A_EVENT_INIT(&pcustctxt->sockTxWakeEvent, kEventManualClear); + + A_NETBUF_QUEUE_INIT(&(pcustctxt->rxqueue)); + + pcustctxt->blockFlag = 0; + pcustctxt->respAvailable = false; + ath_sock_context[index]->sock_context = pcustctxt; + ath_sock_context[index]->remaining_bytes = 0; + ath_sock_context[index]->old_netbuf = NULL; + +#if NON_BLOCKING_TX + A_NETBUF_QUEUE_INIT(&(pcustctxt->non_block_queue)); + A_MUTEX_INIT(&pcustctxt->nb_tx_mutex); +#endif + } + +#if ZERO_COPY + /*Initilize common queue used to store Rx packets for zero copy option*/ + A_NETBUF_QUEUE_INIT(&zero_copy_free_queue); +#endif + + return A_OK; +} + +/*****************************************************************************/ +/* socket_context_deinit - De-initializes common socket context, called during + * driver deinit. + *****************************************************************************/ +void socket_context_deinit(void) +{ + uint32_t index = 0; + SOCKET_CONTEXT_PTR pcustctxt = NULL; + + for (index = 0; index < MAX_SOCKETS_SUPPORTED + 1; index++) + { + A_FREE(ath_sock_context[index], MALLOC_ID_CONTEXT); + ath_sock_context[index] = NULL; + } + /*Free the custom context as well*/ + + for (index = 0; index < MAX_SOCKETS_SUPPORTED + 1; index++) + { + pcustctxt = GET_SOCKET_CONTEXT(ath_sock_context[index]); +#if NON_BLOCKING_TX + A_MUTEX_DELETE(&pcustctxt->nb_tx_mutex); +#endif + A_EVENT_DELETE(&pcustctxt->sockRxWakeEvent); + A_EVENT_DELETE(&pcustctxt->sockTxWakeEvent); + A_FREE(pcustctxt, MALLOC_ID_CONTEXT); + } +} + +/*****************************************************************************/ +/* Api_SockResponseEventRx - Handler for WMI socket receive events. + * void *pCxt - driver context + * uint8_t *datap - pointer to incoming event data + * uint32_t len - length of event data + *****************************************************************************/ +A_STATUS Api_SockResponseEventRx(void *pCxt, uint8_t devId, uint8_t *datap, uint32_t len, void *pReq) +{ + int32_t index = 0; + uint8_t unblock_flag = 0; + WMI_SOCK_RESPONSE_EVENT *response = (WMI_SOCK_RESPONSE_EVENT *)datap; + uint32_t resp_type = A_CPU2LE32(response->resp_type); + A_STATUS status = A_OK; + uint8_t freeBuf = 1; + + switch (resp_type) + { + case SOCK_OPEN: + index = find_socket_context(SOCKET_HANDLE_PLACEHOLDER, true); + + if (index < 0 || index > MAX_SOCKETS_SUPPORTED) + { + last_driver_error = A_SOCKCXT_NOT_FOUND; + status = A_ERROR; + break; + } + /*Check if a socket is waiting on the response*/ + if (SOCK_EV_MASK_TEST(ath_sock_context[index], resp_type)) + { + /*Store the newly created socket handle*/ + ath_sock_context[index]->handle = A_CPU2LE32(response->sock_handle); + /* unlock the application thread*/ + unblock_flag = 1; + } + break; + + case SOCK_ACCEPT: + index = find_socket_context(A_CPU2LE32(response->sock_handle), true); + + if (index < 0 || index > MAX_SOCKETS_SUPPORTED) + { + last_driver_error = A_SOCKCXT_NOT_FOUND; + status = A_ERROR; + break; + } + + /*Check if a socket is waiting on the response*/ + // if(SOCK_EV_MASK_TEST(ath_sock_context[index], resp_type)) + { + /*Copy incoming socket related information*/ + ath_sock_context[index]->data = response->data; + ath_sock_context[index]->pReq = pReq; + + /*Store the response in socket context result field*/ + ath_sock_context[index]->result = A_CPU2LE32(response->error); + /*unlock the thread*/ + if (SOCK_EV_MASK_TEST(ath_sock_context[index], resp_type)) + { + unblock_flag = 1; + } + freeBuf = 0; + UNBLOCK_SELECT(pCxt); + } + break; + case SOCK_CLOSE: + /* A socket close event may be received under two scenarios- + 1. In response to explicit socket close request from host. + 2. An unsolicited socket close to close a socket created earlier for + an incoming TCP connection + In the first scenario, the application thread is waiting for the response, + so unblock the thread. + In the second case, just cleanup the socket context*/ + + index = find_socket_context(A_CPU2LE32(response->sock_handle), true); + + if (index < 0 || index > MAX_SOCKETS_SUPPORTED) + { + last_driver_error = A_SOCKCXT_NOT_FOUND; + status = A_ERROR; + break; + } + + if (SOCK_EV_MASK_TEST(ath_sock_context[index], resp_type)) + { + /* the blocked flag will clear the context. clearing + * the context here will erase the mask which would + * break up the task synchronization. */ + /*unlock the thread*/ + unblock_flag = 1; + /*Store the response in socket context result field*/ + ath_sock_context[index]->result = A_CPU2LE32(response->error); + } + else + { + /* Case 2: clear the context here, no one is waiting */ + if(QUEUE_EMPTY(index)) { + clear_socket_context(index); + } + else + { + ath_sock_context[index]->TCPCtrFlag = TCP_FIN; + } +#if T_SELECT_VER1 + // Asynchronous sock_close event. + // printf("Asynch SOCK Close for socket index %d\n", index); + // SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_CLOSE); + UNBLOCK_SELECT(pCxt); +#endif // T_SELECT_VER1 + } + break; + case SOCK_CONNECT: + index = find_socket_context(A_CPU2LE32(response->sock_handle), true); + + if (index < 0 || index > MAX_SOCKETS_SUPPORTED) + { + last_driver_error = A_SOCKCXT_NOT_FOUND; + status = A_ERROR; + break; + } + /*Store the response in socket context result field*/ + ath_sock_context[index]->result = A_CPU2LE32(response->error); + /*Check if a socket is waiting on the response*/ + if (SOCK_EV_MASK_TEST(ath_sock_context[index], resp_type)) + { + /*unlock the thread*/ + unblock_flag = 1; + } + else + { + if (A_CPU2LE32(response->error) == TCP_CONNECTION_AVAILABLE) + { + /*Special case: async listen event has been received indicating a new + TCP connection is available. The User thread may be blocked with a select + call, set the unblock_flag so the user thread can be unlocked*/ + unblock_flag = 1; + } + } + UNBLOCK_SELECT(pCxt); + break; + + case SOCK_BIND: + case SOCK_LISTEN: + /*Listen Event may be received in two cases: + Case 1: In response to a listen request from host, that puts TCP socket in + Listen state. + Case 2: An unsolicited listen with a result value TCP_CONNECTION_AVAILABLE, + that informs an application thread that a new TCP connection is + available. This allows the application to call accept.*/ + case SOCK_ERRNO: + case SOCK_SETSOCKOPT: + index = find_socket_context(A_CPU2LE32(response->sock_handle), true); + + if (index < 0 || index > MAX_SOCKETS_SUPPORTED) + { + last_driver_error = A_SOCKCXT_NOT_FOUND; + status = A_ERROR; + break; + } + /*Check if a socket is waiting on the response*/ + if (SOCK_EV_MASK_TEST(ath_sock_context[index], resp_type)) + { + /*Store the response in socket context result field*/ + ath_sock_context[index]->result = A_CPU2LE32(response->error); + /*unlock the thread*/ + unblock_flag = 1; + } + else + { + if (A_CPU2LE32(response->error) == TCP_CONNECTION_AVAILABLE) + { + /*Special case: async listen event has been received indicating a new + TCP connection is available. The User thread may be blocked with a select + call, set the unblock_flag so the user thread can be unlocked*/ + ath_sock_context[index]->result = A_CPU2LE32(response->error); + unblock_flag = 1; + } + } + break; + case SOCK_GETSOCKOPT: + index = find_socket_context(A_CPU2LE32(response->sock_handle), true); + + if (index < 0 || index > MAX_SOCKETS_SUPPORTED) + { + last_driver_error = A_SOCKCXT_NOT_FOUND; + status = A_ERROR; + break; + } + + /*Check if a socket is waiting on the response*/ + if (SOCK_EV_MASK_TEST(ath_sock_context[index], resp_type)) + { + ath_sock_context[index]->result = A_CPU2LE32(response->error); + /*Copy select related information*/ + ath_sock_context[index]->data = response->data; + ath_sock_context[index]->pReq = pReq; + /* unlock the application thread*/ + unblock_flag = 1; + freeBuf = 0; + } + break; + case SOCK_IPCONFIG: + index = GLOBAL_SOCK_INDEX; + /*Check if a socket is waiting on the response*/ + if (SOCK_EV_MASK_TEST(ath_sock_context[index], resp_type)) + { + /*Copy ipconfig related information*/ + ath_sock_context[index]->data = response->data; + ath_sock_context[index]->pReq = pReq; + ath_sock_context[index]->result = A_CPU2LE32(response->error); + /*unlock the thread*/ + unblock_flag = 1; + freeBuf = 0; + } + break; + case SOCK_PING: + case SOCK_PING6: + index = GLOBAL_SOCK_INDEX; + /*Check if a socket is waiting on the response*/ + if (SOCK_EV_MASK_TEST(ath_sock_context[index], resp_type)) + { + /*Copy ipconfig related information*/ + ath_sock_context[index]->result = A_CPU2LE32(response->error); + /*unlock the thread*/ + unblock_flag = 1; + } + + break; + case SOCK_IP6CONFIG: + index = GLOBAL_SOCK_INDEX; + /*Check if a socket is waiting on the response*/ + if (SOCK_EV_MASK_TEST(ath_sock_context[index], resp_type)) + { + /*Copy ipconfig related information*/ + ath_sock_context[index]->data = response->data; + ath_sock_context[index]->result = A_CPU2LE32(response->error); + ath_sock_context[index]->pReq = pReq; + /*unlock the thread*/ + unblock_flag = 1; + freeBuf = 0; + } + break; +#if ENABLE_HTTP_SERVER + case SOCK_HTTP_SERVER: + index = GLOBAL_SOCK_INDEX; + /*Check if a socket is waiting on the response*/ + if (SOCK_EV_MASK_TEST(ath_sock_context[index], resp_type)) + { + ath_sock_context[index]->result = A_CPU2LE32(response->error); + /*unlock the thread*/ + unblock_flag = 1; + } + break; + case SOCK_HTTP_SERVER_CMD: + index = GLOBAL_SOCK_INDEX; + /*Check if a socket is waiting on the response*/ + if (SOCK_EV_MASK_TEST(ath_sock_context[index], resp_type)) + { + ath_sock_context[index]->pReq = pReq; + ath_sock_context[index]->result = A_CPU2LE32(response->error); + /*Copy select related information*/ + ath_sock_context[index]->data = response->data; + ath_sock_context[index]->pReq = pReq; + /*unlock the thread*/ + unblock_flag = 1; + freeBuf = 0; + } + break; + case SOCK_HTTP_POST_EVENT: + CUSTOM_API_HTTP_POST_EVENT(pCxt, response->data); + break; +#endif +#if ENABLE_HTTP_CLIENT + case SOCK_HTTPC: + index = GLOBAL_SOCK_INDEX; + /*Check if a socket is waiting on the response*/ + if (SOCK_EV_MASK_TEST(ath_sock_context[index], resp_type)) + { + ath_sock_context[index]->pReq = pReq; + ath_sock_context[index]->result = A_CPU2LE32(response->error); + /*Copy select related information*/ + ath_sock_context[index]->data = response->data; + ath_sock_context[index]->pReq = pReq; + /*unlock the thread*/ + unblock_flag = 1; + freeBuf = 0; + } + // printf("Received http client resp :%d req %x\n", ath_sock_context[index]->result, + // ath_sock_context[index]->pReq); + break; +#endif /* ENABLE_HTTP_CLIENT */ + case SOCK_DNC_CMD: + index = GLOBAL_SOCK_INDEX; + /*Check if a socket is waiting on the response*/ + if (SOCK_EV_MASK_TEST(ath_sock_context[index], resp_type)) + { + /*Copy ipconfig related information*/ + ath_sock_context[index]->data = response->data; + ath_sock_context[index]->result = A_CPU2LE32(response->error); + ath_sock_context[index]->pReq = pReq; + /*unlock the thread*/ + unblock_flag = 1; + freeBuf = 0; + } + break; + case SOCK_DNC_ENABLE: + index = GLOBAL_SOCK_INDEX; + /*Check if a socket is waiting on the response*/ + if (SOCK_EV_MASK_TEST(ath_sock_context[index], resp_type)) + { + ath_sock_context[index]->result = A_CPU2LE32(response->error); + /*unlock the thread*/ + unblock_flag = 1; + } + case SOCK_DNS_SRVR_CFG_ADDR: + index = GLOBAL_SOCK_INDEX; + /*Check if a socket is waiting on the response*/ + if (SOCK_EV_MASK_TEST(ath_sock_context[index], resp_type)) + { + ath_sock_context[index]->result = A_CPU2LE32(response->error); + /*unlock the thread*/ + unblock_flag = 1; + } + break; + case SOCK_IP_HOST_NAME: + index = GLOBAL_SOCK_INDEX; + /*Check if a socket is waiting on the response*/ + if (SOCK_EV_MASK_TEST(ath_sock_context[index], resp_type)) + { + ath_sock_context[index]->result = A_CPU2LE32(response->error); + /*unlock the thread*/ + unblock_flag = 1; + } + break; + case SOCK_IP_DNS: + index = GLOBAL_SOCK_INDEX; + /*Check if a socket is waiting on the response*/ + if (SOCK_EV_MASK_TEST(ath_sock_context[index], resp_type)) + { + ath_sock_context[index]->result = A_CPU2LE32(response->error); + /*unlock the thread*/ + unblock_flag = 1; + } + break; + case SOCK_IP_SNTP_GET_TIME: + index = GLOBAL_SOCK_INDEX; + // printf("resp from sntp \r\n"); + /*Check if a socket is waiting on the response*/ + if (SOCK_EV_MASK_TEST(ath_sock_context[index], resp_type)) + { + /*Copy ipconfig related information*/ + ath_sock_context[index]->data = response->data; + ath_sock_context[index]->result = A_CPU2LE32(response->error); + ath_sock_context[index]->pReq = pReq; + /*unlock the thread*/ + //("unblock\r\n"); + unblock_flag = 1; + freeBuf = 0; + } + break; + case SOCK_IP_SNTP_GET_TIME_OF_DAY: + index = GLOBAL_SOCK_INDEX; + /*Check if a socket is waiting on the response*/ + if (SOCK_EV_MASK_TEST(ath_sock_context[index], resp_type)) + { + /*Copy ipconfig related information*/ + ath_sock_context[index]->data = response->data; + ath_sock_context[index]->result = A_CPU2LE32(response->error); + ath_sock_context[index]->pReq = pReq; + /*unlock the thread*/ + //("unblock\r\n"); + unblock_flag = 1; + freeBuf = 0; + } + break; + case SOCK_IP_SNTP_QUERY_SNTP_ADDRESS: + index = GLOBAL_SOCK_INDEX; + /*Check if a socket is waiting on the response*/ + if (SOCK_EV_MASK_TEST(ath_sock_context[index], resp_type)) + { + /*Copy ipconfig related information*/ + ath_sock_context[index]->data = response->data; + ath_sock_context[index]->result = A_CPU2LE32(response->error); + ath_sock_context[index]->pReq = pReq; + /*unlock the thread*/ + //("unblock\r\n"); + unblock_flag = 1; + freeBuf = 0; + } + break; + case SOCK_IPV4_ROUTE: + index = GLOBAL_SOCK_INDEX; + /*Check if a socket is waiting on the response*/ + if (SOCK_EV_MASK_TEST(ath_sock_context[index], resp_type)) + { + /*Copy ipconfig related information*/ + ath_sock_context[index]->data = response->data; + ath_sock_context[index]->result = A_CPU2LE32(response->error); + ath_sock_context[index]->pReq = pReq; + /*unlock the thread*/ + unblock_flag = 1; + freeBuf = 0; + } + break; + case SOCK_IPV6_ROUTE: + index = GLOBAL_SOCK_INDEX; + /*Check if a socket is waiting on the response*/ + if (SOCK_EV_MASK_TEST(ath_sock_context[index], resp_type)) + { + /*Copy ipconfig related information*/ + ath_sock_context[index]->data = response->data; + ath_sock_context[index]->result = A_CPU2LE32(response->error); + ath_sock_context[index]->pReq = pReq; + /*unlock the thread*/ + unblock_flag = 1; + freeBuf = 0; + } + break; +#if ENABLE_SSL + case SOCK_SSL_SET_FD: + case SOCK_SSL_ACCEPT: + case SOCK_SSL_CONNECT: + index = find_socket_context_from_ssl((SSL *)response->sock_handle); // ssl context + if (index == SOCKET_NOT_FOUND) + { + /* We send the configure command on the "global socket" if the configure is + * done before the socket is created */ + index = GLOBAL_SOCK_INDEX; + } + if (SOCK_EV_MASK_TEST(ath_sock_context[index], resp_type)) + { + ath_sock_context[index]->result = A_CPU2LE32(response->error); + /*unlock the thread*/ + unblock_flag = 1; + } + break; + + case SOCK_SSL_CONFIGURE: + case SOCK_SSL_SHUTDOWN: + index = find_socket_context_from_ssl((SSL *)response->sock_handle); // ssl context + if (index == SOCKET_NOT_FOUND) + { + index = GLOBAL_SOCK_INDEX; + } + if (SOCK_EV_MASK_TEST(ath_sock_context[index], resp_type)) + { + ath_sock_context[index]->result = A_CPU2LE32(response->error); + /*unlock the thread*/ + unblock_flag = 1; + } + break; + + case SOCK_SSL_CTX_NEW: + case SOCK_SSL_CTX_FREE: + case SOCK_SSL_NEW: + case SOCK_SSL_ADD_CERT: + case SOCK_SSL_STORE_CERT: + case SOCK_SSL_LOAD_CERT: + index = GLOBAL_SOCK_INDEX; + if (SOCK_EV_MASK_TEST(ath_sock_context[index], resp_type)) + { + ath_sock_context[index]->result = A_CPU2LE32(response->error); + /*unlock the thread*/ + unblock_flag = 1; + } + break; + + case SOCK_SSL_LIST_CERT: + index = GLOBAL_SOCK_INDEX; + if (SOCK_EV_MASK_TEST(ath_sock_context[index], resp_type)) + { + ath_sock_context[index]->pReq = pReq; + ath_sock_context[index]->data = response->data; + ath_sock_context[index]->result = A_CPU2LE32(response->error); + /*unlock the thread*/ + unblock_flag = 1; + freeBuf = 0; + } + break; +#endif + case SOCK_OTA_UPGRADE: + case SOCK_OTA_READ: + case SOCK_OTA_DONE: + case SOCK_OTA_SESSION_START: + case SOCK_OTA_PARTITION_GET_SIZE: + case SOCK_OTA_PARTITION_ERASE: + case SOCK_OTA_PARTITION_VERIFY_CHECKSUM: + index = GLOBAL_SOCK_INDEX; + /*Check if a socket is waiting on the response*/ + if (SOCK_EV_MASK_TEST(ath_sock_context[index], resp_type)) + { + /*Copy ipconfig related information*/ + ath_sock_context[index]->data = response->data; + ath_sock_context[index]->result = A_CPU2LE32(response->error); + ath_sock_context[index]->pReq = pReq; + /*unlock the thread*/ + unblock_flag = 1; + freeBuf = 0; + } + break; + case SOCK_OTA_PARSE_IMAGE_HDR: + index = GLOBAL_SOCK_INDEX; + /*Check if a socket is waiting on the response*/ + if (SOCK_EV_MASK_TEST(ath_sock_context[index], resp_type)) + { + /*Copy ipconfig related information*/ + ath_sock_context[index]->data = response->data; + ath_sock_context[index]->result = A_CPU2LE32(response->error); + ath_sock_context[index]->pReq = pReq; + /*unlock the thread*/ + unblock_flag = 1; + freeBuf = 0; + } + else + { + tOtaParseImageHdrResp *tmp_resp = (tOtaParseImageHdrResp*)response->data; + Custom_Api_Ota_Resp_Result(pCxt, SOCK_OTA_PARSE_IMAGE_HDR, + tmp_resp->resp_code, + tmp_resp->offset); + } + break; + case SOCK_OTA_PARTITION_WRITE_DATA: + index = GLOBAL_SOCK_INDEX; + /*Check if a socket is waiting on the response*/ + if (SOCK_EV_MASK_TEST(ath_sock_context[index], resp_type)) + { + /*Copy ipconfig related information*/ + ath_sock_context[index]->data = response->data; + ath_sock_context[index]->result = A_CPU2LE32(response->error); + ath_sock_context[index]->pReq = pReq; + /*unlock the thread*/ + unblock_flag = 1; + freeBuf = 0; + } + else + { + tOtaPartitionWriteDataResp *tmp_resp = (tOtaPartitionWriteDataResp*)response->data; + Custom_Api_Ota_Resp_Result(pCxt, SOCK_OTA_PARTITION_WRITE_DATA, + tmp_resp->resp_code, + tmp_resp->size); + } + break; + case SOCK_DHCPS_SUCCESS_CALLBACK: + Custom_Api_Dhcps_Success_Callback_Event(pCxt, response->data); + break; + case SOCK_DHCPC_SUCCESS_CALLBACK: + Custom_Api_Dhcpc_Success_Callback_Event(pCxt, response->data); + break; + default: + last_driver_error = A_UNKNOWN_CMD; + status = A_ERROR; + break; + } + /* if a user task is blocked on this event then unblock it. */ + if (unblock_flag /* && SOCK_EV_MASK_TEST(ath_sock_context[index], resp_type)*/) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], resp_type); + UNBLOCK(ath_sock_context[index], RX_DIRECTION); + } + + if (freeBuf) + { + /*Free the netbuf*/ + A_NETBUF_FREE(pReq); + } + return status; +} + +/*****************************************************************************/ +/* getIPLength - Calculates total IP header length. + * uint8_t version - IP version + * Returns- IP header length + *****************************************************************************/ +uint32_t getIPLength(uint8_t version) +{ + uint32_t length = 0; + switch (version) + { + case ATH_AF_INET: + length = IPV4_HEADER_LENGTH; + break; + + case ATH_AF_INET6: + length = IPV6_HEADER_LENGTH; + break; + default: + break; + } + + return length; +} + +/*****************************************************************************/ +/* getTransportLength - Calculates Transport layer header length + * uint8_t proto - UDP or TCP + * Returns- Transport layer header length + *****************************************************************************/ +uint32_t getTransportLength(uint8_t proto) +{ + uint32_t length = 0; + switch (proto) + { + case SOCK_STREAM_TYPE: + length = TCP_HEADER_LENGTH; + break; + + case SOCK_DGRAM_TYPE: + length = UDP_HEADER_LENGTH; + break; + default: + break; + } + + return length; +} + +/*****************************************************************************/ +/* Api_socket - API to create new socket + * void *pCxt- driver context + * uint32_t domain- IPv4, IPv6 + * uint32_t type- TCP, UDP + * uint32_t protocol- + * Returns- socket handle in case of success, A_ERROR otherwise + *****************************************************************************/ +int32_t Api_socket(void *pCxt, uint32_t domain, uint32_t type, uint32_t protocol) +{ + A_DRIVER_CONTEXT *pDCxt; + SOCK_OPEN_T sock_open; + int32_t index = 0; + int32_t result = A_OK; + + pDCxt = GET_DRIVER_COMMON(pCxt); + + do + { + /*Create new context*/ + if ((index = find_socket_context(EMPTY_SOCKET_CONTEXT, false)) != SOCKET_NOT_FOUND) + { + ath_sock_context[index]->handle = SOCKET_HANDLE_PLACEHOLDER; + ath_sock_context[index]->domain = domain; + ath_sock_context[index]->type = type; + } + else + { + last_driver_error = A_SOCK_UNAVAILABLE; + result = A_ERROR; + break; + } + + /*Create socket open wmi message*/ + sock_open.domain = A_CPU2LE32(domain); + sock_open.type = A_CPU2LE32(type); + sock_open.protocol = A_CPU2LE32(protocol); + + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_OPEN); + + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_OPEN, (void *)(&sock_open), sizeof(SOCK_OPEN_T)) != A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_OPEN); + /*Command failed, clear socket context and return error*/ + clear_socket_context(index); + result = A_ERROR; + break; + } + + /*Wait for response from target*/ + do + { + if (BLOCK(pCxt, ath_sock_context[index], COMMAND_BLOCK_TIMEOUT, RX_DIRECTION) != A_OK) + { + A_ASSERT(0); + } + } while (SOCK_EV_MASK_TEST(ath_sock_context[index], SOCK_OPEN)); + + if (ath_sock_context[index]->handle == A_ERROR) + { + /*Socket not created, return error*/ + clear_socket_context(index); + result = A_ERROR; + break; + } + else + { + result = ath_sock_context[index]->handle; + } + } while (0); + + return result; +} + +/*****************************************************************************/ +/* Api_shutdown - Close a previously opened socket + * void *pCxt- driver context + * uint32_t handle- socket handle + * Returns- 0 in case of successful shutdown, A_ERROR otherwise + *****************************************************************************/ +int32_t Api_shutdown(void *pCxt, uint32_t handle) +{ + SOCK_CLOSE_T sock_close; + int32_t index = 0; + A_DRIVER_CONTEXT *pDCxt; + int32_t result = A_OK; + + pDCxt = GET_DRIVER_COMMON(pCxt); + + do + { + /*Find context*/ + if ((index = find_socket_context(handle, true)) == SOCKET_NOT_FOUND) + { + result = A_ERROR; + break; + } + + /*Check if some other thread is wating on this socket*/ + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + result = A_ERROR; + break; + } + + /*Delete all pending packets in the receive queue*/ + CUSTOM_PURGE_QUEUE(index); + + /*Create a socket close wmi message*/ + sock_close.handle = A_CPU2LE32(handle); + /* set the sock_st_flags before calling wmi_ to avoid possible race conditions */ + // SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_CLOSE); + + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_CLOSE, (void *)(&sock_close), sizeof(SOCK_CLOSE_T)) != A_OK) + { + /* clear the flag that would have been cleared by receiving the event */ + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_CLOSE); + result = A_ERROR; + break; + } + +#if 0 // For shutdown, we are not gonna wait for response. Fire and forgot + /*Wait for response from target*/ + do{ + if(BLOCK(pCxt, ath_sock_context[index], COMMAND_BLOCK_TIMEOUT, RX_DIRECTION) != A_OK){ + A_ASSERT(0); + } + }while(SOCK_EV_MASK_TEST(ath_sock_context[index], SOCK_CLOSE)); +#endif + + result = ath_sock_context[index]->result; + /* Delete all pending packets */ + CUSTOM_PURGE_QUEUE(index); + + /* clear the socket to make it available for re-use */ + clear_socket_context(index); + } while (0); + + return result; +} + +/*****************************************************************************/ +/* Api_connect - API to connect to a peer + * void *pCxt- driver context + * uint32_t handle- socket handle + * void* name- sock addr structure + * uint16_t length- sock add length + * Returns- 0 in case of successful connect, A_ERROR otherwise + *****************************************************************************/ +int32_t Api_connect(void *pCxt, uint32_t handle, void *name, uint16_t length) +{ + A_DRIVER_CONTEXT *pDCxt; + SOCK_CONNECT_CMD_T sock_connect; + int32_t index = 0; + int32_t result = A_OK; + + pDCxt = GET_DRIVER_COMMON(pCxt); + + do + { + /*Retrieve context*/ + if ((index = find_socket_context(handle, true)) == SOCKET_NOT_FOUND) + { + result = A_ERROR; + break; + } + + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + result = A_ERROR; + break; + } + + sock_connect.handle = A_CPU2LE32(handle); + sock_connect.length = A_CPU2LE16(length); + + if (ath_sock_context[index]->domain == ATH_AF_INET) + { + sock_connect.addr.name.sin_port = A_CPU2LE16(((SOCKADDR_T *)name)->sin_port); + sock_connect.addr.name.sin_family = A_CPU2LE16(((SOCKADDR_T *)name)->sin_family); + sock_connect.addr.name.sin_addr = A_CPU2LE32(((SOCKADDR_T *)name)->sin_addr); + } + else + { + sock_connect.addr.name6.sin6_port = A_CPU2LE16(((SOCKADDR_6_T *)name)->sin6_port); + sock_connect.addr.name6.sin6_family = A_CPU2LE16(((SOCKADDR_6_T *)name)->sin6_family); + sock_connect.addr.name6.sin6_flowinfo = A_CPU2LE32(((SOCKADDR_6_T *)name)->sin6_flowinfo); + A_MEMCPY((uint8_t *)&(sock_connect.addr.name6.sin6_addr), (uint8_t *)&((SOCKADDR_6_T *)name)->sin6_addr, + sizeof(IP6_ADDR_T)); + } + + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_CONNECT); + + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_CONNECT, (void *)(&sock_connect), sizeof(SOCK_CONNECT_CMD_T)) != A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_CONNECT); + result = A_ERROR; + break; + } + + do + { + if (BLOCK(pCxt, ath_sock_context[index], COMMAND_BLOCK_TIMEOUT, RX_DIRECTION) != A_OK) + { + A_ASSERT(0); + } + } while (SOCK_EV_MASK_TEST(ath_sock_context[index], SOCK_CONNECT)); + result = ath_sock_context[index]->result; + } while (0); + + return result; +} + +// Non blocking version of connect +int32_t Api_connect_nb(void *pCxt, uint32_t handle, void *name, uint16_t length) +{ + A_DRIVER_CONTEXT *pDCxt; + SOCK_CONNECT_CMD_T sock_connect; + int32_t index = 0; + int32_t result = A_OK; + + pDCxt = GET_DRIVER_COMMON(pCxt); + + do + { + /*Retrieve context*/ + if ((index = find_socket_context(handle, true)) == SOCKET_NOT_FOUND) + { + result = A_ERROR; + break; + } + + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + result = A_ERROR; + break; + } + + sock_connect.handle = A_CPU2LE32(handle); + sock_connect.length = A_CPU2LE16(length); + + if (ath_sock_context[index]->domain == ATH_AF_INET) + { + sock_connect.addr.name.sin_port = A_CPU2LE16(((SOCKADDR_T *)name)->sin_port); + sock_connect.addr.name.sin_family = A_CPU2LE16(((SOCKADDR_T *)name)->sin_family); + sock_connect.addr.name.sin_addr = A_CPU2LE32(((SOCKADDR_T *)name)->sin_addr); + } + else + { + sock_connect.addr.name6.sin6_port = A_CPU2LE16(((SOCKADDR_6_T *)name)->sin6_port); + sock_connect.addr.name6.sin6_family = A_CPU2LE16(((SOCKADDR_6_T *)name)->sin6_family); + sock_connect.addr.name6.sin6_flowinfo = A_CPU2LE32(((SOCKADDR_6_T *)name)->sin6_flowinfo); + A_MEMCPY((uint8_t *)&(sock_connect.addr.name6.sin6_addr), (uint8_t *)&((SOCKADDR_6_T *)name)->sin6_addr, + sizeof(IP6_ADDR_T)); + } + + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_CONNECT, (void *)(&sock_connect), sizeof(SOCK_CONNECT_CMD_T)) != A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_CONNECT); + result = A_ERROR; + break; + } + + } while (0); + + return result; +} + +/*****************************************************************************/ +/* Api_bind - API to bind to an interface. Works for both IPv4 and v6, name + * field must be populated accordingly. + * void *pCxt- driver context + * uint32_t handle- socket handle + * void* name- sock addr structure + * uint16_t length- sock add length + * Returns- 0 in case of successful connect, A_ERROR otherwise + *****************************************************************************/ +int32_t Api_bind(void *pCxt, uint32_t handle, void *name, uint16_t length) +{ + A_DRIVER_CONTEXT *pDCxt; + SOCK_BIND_CMD_T sock_bind; + int32_t index = 0; + int32_t result = A_OK; + + pDCxt = GET_DRIVER_COMMON(pCxt); + + do + { + /*Find context*/ + if ((index = find_socket_context(handle, true)) == SOCKET_NOT_FOUND) + { + result = A_ERROR; + break; + } + + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + result = A_ERROR; + break; + } + sock_bind.handle = A_CPU2LE32(handle); + sock_bind.length = A_CPU2LE16(length); + + if (ath_sock_context[index]->domain == ATH_AF_INET) + { + sock_bind.addr.name.sin_port = A_CPU2LE16(((SOCKADDR_T *)name)->sin_port); + sock_bind.addr.name.sin_family = A_CPU2LE16(((SOCKADDR_T *)name)->sin_family); + sock_bind.addr.name.sin_addr = A_CPU2LE32(((SOCKADDR_T *)name)->sin_addr); + } + else + { + sock_bind.addr.name6.sin6_port = A_CPU2LE16(((SOCKADDR_6_T *)name)->sin6_port); + sock_bind.addr.name6.sin6_family = A_CPU2LE16(((SOCKADDR_6_T *)name)->sin6_family); + sock_bind.addr.name6.sin6_flowinfo = A_CPU2LE32(((SOCKADDR_6_T *)name)->sin6_flowinfo); + A_MEMCPY((uint8_t *)&(sock_bind.addr.name6.sin6_addr), (uint8_t *)&((SOCKADDR_6_T *)name)->sin6_addr, + sizeof(IP6_ADDR_T)); + } + + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_BIND); + + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_BIND, (void *)(&sock_bind), sizeof(SOCK_BIND_CMD_T)) != A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_BIND); + result = A_ERROR; + break; + } + + do + { + if (BLOCK(pCxt, ath_sock_context[index], COMMAND_BLOCK_TIMEOUT, RX_DIRECTION) != A_OK) + { + A_ASSERT(0); + } + } while (SOCK_EV_MASK_TEST(ath_sock_context[index], SOCK_BIND)); + result = ath_sock_context[index]->result; + } while (0); + + return result; +} + +/*****************************************************************************/ +/* Api_listen - API to Listen for incoming connections. Only used on stream sockets + * Works for both IPv4 and v6. + * void *pCxt- driver context + * uint32_t handle- socket handle + * uint32_t backlog- backlog of pending connections. The backlog parameter defines + * the maximum length for the queue of pending connections + * Returns- 0 in case of success, A_ERROR otherwise + *****************************************************************************/ +int32_t Api_listen(void *pCxt, uint32_t handle, uint32_t backlog) +{ + A_DRIVER_CONTEXT *pDCxt; + SOCK_LISTEN_T sock_listen; + int32_t index = 0; + int32_t result = A_OK; + + pDCxt = GET_DRIVER_COMMON(pCxt); + + do + { + /*Find context*/ + if ((index = find_socket_context(handle, true)) == SOCKET_NOT_FOUND) + { + result = A_ERROR; + break; + } + + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + result = A_ERROR; + break; + } + + sock_listen.handle = A_CPU2LE32(handle); + sock_listen.backlog = A_CPU2LE16(backlog); + + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_LISTEN, (void *)(&sock_listen), sizeof(SOCK_LISTEN_T)) != A_OK) + { + result = A_ERROR; + break; + } + + // result = ath_sock_context[index]->result; + } while (0); + + if (index >= 0 && result == A_OK) + { + ath_sock_context[index]->TCPCtrFlag = TCP_LISTEN; + } + else + { + // TODO: fixme, how to handle this case !!! + assert(0); + } + + return result; +} + +/*****************************************************************************/ +/* Api_accept - API to accept incoming inconnections. Works for both IPv4 and v6, + * name field must be populated accordingly. Must call select to wait + * for incoming connection before calling this API. + * void *pCxt- driver context + * uint32_t handle- socket handle + * void* name- sock addr structure + * uint16_t length- sock add length + * Returns- 0 in case of successful connect, A_ERROR otherwise + *****************************************************************************/ +int32_t Api_accept(void *pCxt, uint32_t handle, void *name, socklen_t length) +{ + A_DRIVER_CONTEXT *pDCxt; + SOCK_ACCEPT_CMD_T sock_accept; + int32_t index = 0; + int32_t accept_index = 0; + int32_t result = A_OK; + uint8_t free_buf = 1; + + pDCxt = GET_DRIVER_COMMON(pCxt); + + do + { + /*Find context*/ + if ((index = find_socket_context(handle, true)) == SOCKET_NOT_FOUND) + { + result = A_ERROR; + free_buf = 0; + break; + } + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + result = A_ERROR; + free_buf = 0; + break; + } + /* prepare wmi accept structure*/ + sock_accept.handle = A_CPU2LE32(handle); + sock_accept.length = A_CPU2LE16(length); + + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_ACCEPT); + + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_ACCEPT, (void *)(&sock_accept), sizeof(SOCK_ACCEPT_CMD_T)) != A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_ACCEPT); + result = A_ERROR; + free_buf = 0; + break; + } + + /*Block until stack provides a response*/ + do + { + if (BLOCK(pCxt, ath_sock_context[index], COMMAND_BLOCK_TIMEOUT, RX_DIRECTION) != A_OK) + { + A_ASSERT(0); + } + } while (SOCK_EV_MASK_TEST(ath_sock_context[index], SOCK_ACCEPT)); + + if (ath_sock_context[index]->result == TCP_CONNECTION_AVAILABLE) + { + /*Special case: Received TCP_CONN_AVAILABLE from target in response to accept, call + Accept again to create new connection, free the previos netbuf*/ + if (free_buf) + { + /*Free the netbuf*/ + A_NETBUF_FREE(ath_sock_context[index]->pReq); + } + /*Target stack indicates that a new TCP connection is available, accept it*/ + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_ACCEPT); + + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_ACCEPT, (void *)(&sock_accept), sizeof(SOCK_ACCEPT_CMD_T)) != A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_ACCEPT); + result = A_ERROR; + free_buf = 0; + break; + } + + /*Block until stack provides a response*/ + do + { + if (BLOCK(pCxt, ath_sock_context[index], COMMAND_BLOCK_TIMEOUT, RX_DIRECTION) != A_OK) + { + A_ASSERT(0); + } + } while (SOCK_EV_MASK_TEST(ath_sock_context[index], SOCK_ACCEPT)); + } + + if (ath_sock_context[index]->result != A_ERROR) + { + /*Create new context*/ + if ((accept_index = find_socket_context(EMPTY_SOCKET_CONTEXT, false)) != SOCKET_NOT_FOUND) + { + ath_sock_context[accept_index]->handle = ath_sock_context[index]->result; + ath_sock_context[accept_index]->domain = ath_sock_context[index]->domain; + ath_sock_context[accept_index]->type = ath_sock_context[index]->type; + } + else + { + last_driver_error = A_SOCK_UNAVAILABLE; + result = A_ERROR; + break; + } + + if (ath_sock_context[index]->data != NULL) + { + /*Based on IPv4 vs IPv6, fill in name fields*/ + if (ath_sock_context[index]->domain == ATH_AF_INET) + { + A_MEMCPY(name, &((SOCK_ACCEPT_RECV_T *)(ath_sock_context[index]->data))->addr.name, + sizeof(SOCKADDR_T)); + ((SOCKADDR_T *)name)->sin_port = A_CPU2LE16(((SOCKADDR_T *)name)->sin_port); + ((SOCKADDR_T *)name)->sin_family = A_CPU2LE16(((SOCKADDR_T *)name)->sin_family); + ((SOCKADDR_T *)name)->sin_addr = A_CPU2LE32(((SOCKADDR_T *)name)->sin_addr); + } + else + { + A_MEMCPY(name, &((SOCK_ACCEPT_RECV_T *)(ath_sock_context[index]->data))->addr.name6, + sizeof(SOCKADDR_6_T)); + ((SOCKADDR_6_T *)name)->sin6_port = A_CPU2LE16(((SOCKADDR_6_T *)name)->sin6_port); + ((SOCKADDR_6_T *)name)->sin6_family = A_CPU2LE16(((SOCKADDR_6_T *)name)->sin6_family); + } + // A_FREE(ath_sock_context[index]->data, MALLOC_ID_CONTEXT); + // ath_sock_context[index]->data = NULL; + + ath_sock_context[index]->data = NULL; + } + } + result = ath_sock_context[index]->result; + } while (0); + + if (free_buf) + { + /*Free the netbuf*/ + A_NETBUF_FREE(ath_sock_context[index]->pReq); + } + return result; +} + +#if T_SELECT_VER1 + +// Non blocking accept +int32_t Api_accept_ver1(void *pCxt, uint32_t handle, void *name, socklen_t length) +{ + A_DRIVER_CONTEXT *pDCxt; + SOCK_ACCEPT_CMD_T sock_accept; + int32_t index = 0; + int32_t accept_index = 0; + int32_t result = A_OK; + + pDCxt = GET_DRIVER_COMMON(pCxt); + + do + { + /*Find context*/ + if ((index = find_socket_context(handle, true)) == SOCKET_NOT_FOUND) + { + result = A_ERROR; + break; + } + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + result = A_ERROR; + break; + } + + // The accept was issued earlier and the result of accept is avaible here + if ((ath_sock_context[index]->result != TCP_CONNECTION_AVAILABLE) && (ath_sock_context[index]->data != NULL)) + { + /*Create new context*/ + if ((accept_index = find_socket_context(EMPTY_SOCKET_CONTEXT, false)) != SOCKET_NOT_FOUND) + { + ath_sock_context[accept_index]->handle = ath_sock_context[index]->result; + ath_sock_context[accept_index]->domain = ath_sock_context[index]->domain; + ath_sock_context[accept_index]->type = ath_sock_context[index]->type; + } + else + { + last_driver_error = A_SOCK_UNAVAILABLE; + result = A_ERROR; + break; + } + if (ath_sock_context[index]->data != NULL) + { + /*Based on IPv4 vs IPv6, fill in name fields*/ + if (ath_sock_context[index]->domain == ATH_AF_INET) + { + A_MEMCPY(name, &((SOCK_ACCEPT_RECV_T *)(ath_sock_context[index]->data))->addr.name, + sizeof(SOCKADDR_T)); + ((SOCKADDR_T *)name)->sin_port = A_CPU2LE16(((SOCKADDR_T *)name)->sin_port); + ((SOCKADDR_T *)name)->sin_family = A_CPU2LE16(((SOCKADDR_T *)name)->sin_family); + ((SOCKADDR_T *)name)->sin_addr = A_CPU2LE32(((SOCKADDR_T *)name)->sin_addr); + } + else + { + A_MEMCPY(name, &((SOCK_ACCEPT_RECV_T *)(ath_sock_context[index]->data))->addr.name6, + sizeof(SOCKADDR_6_T)); + ((SOCKADDR_6_T *)name)->sin6_port = A_CPU2LE16(((SOCKADDR_6_T *)name)->sin6_port); + ((SOCKADDR_6_T *)name)->sin6_family = A_CPU2LE16(((SOCKADDR_6_T *)name)->sin6_family); + } + // A_FREE(ath_sock_context[index]->data, MALLOC_ID_CONTEXT); + // ath_sock_context[index]->data = NULL; + + ath_sock_context[index]->data = NULL; + } + result = ath_sock_context[index]->result; + A_NETBUF_FREE(ath_sock_context[index]->pReq); + } + else + { + /* prepare wmi accept structure*/ + sock_accept.handle = A_CPU2LE32(handle); + sock_accept.length = A_CPU2LE16(length); + + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_ACCEPT); + + // This is a non-blocking accept + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_ACCEPT, (void *)(&sock_accept), sizeof(SOCK_ACCEPT_CMD_T)) != A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_ACCEPT); + result = A_ERROR; + break; + } + } + } while (0); + + return result; +} +#endif // T_SELECT_VER1 + +/*****************************************************************************/ +/* Api_errno - API to fetch last error code from target + * + * void *pCxt- driver context + * uint32_t handle- socket handle + * Returns- error code in case of success, A_ERROR otherwise + *****************************************************************************/ +int32_t Api_errno(void *pCxt, uint32_t handle) +{ + A_DRIVER_CONTEXT *pDCxt; + int32_t index = 0; + int32_t result = A_OK; + SOCK_ERRNO_T sock_errno; + + pDCxt = GET_DRIVER_COMMON(pCxt); + + do + { + /*Find context*/ + if ((index = find_socket_context(handle, true)) == SOCKET_NOT_FOUND) + { + result = A_ERROR; + break; + } + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + result = A_ERROR; + break; + } + sock_errno.errno = A_CPU2LE32(handle); + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_ERRNO); + + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_ERRNO, (uint8_t *)&sock_errno, sizeof(SOCK_ERRNO_T)) != A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_ERRNO); + result = A_ERROR; + break; + } + + do + { + if (BLOCK(pCxt, ath_sock_context[index], COMMAND_BLOCK_TIMEOUT, RX_DIRECTION) != A_OK) + { + A_ASSERT(0); + } + } while (SOCK_EV_MASK_TEST(ath_sock_context[index], SOCK_ERRNO)); + result = ath_sock_context[index]->result; + } while (0); + + return result; +} + +/*****************************************************************************/ +/* Api_select - + * + * void *pCxt- driver context + * uint32_t handle- socket handle + * uint32_t tv - time to wait in milliseconds + * Returns- 0 in case of successful connect, A_ERROR otherwise + * Select can be called to check for incoming connections or for incoming data. + * It waits for a specified time period before returning. This call does not + * propagate to the target, it is consumed in the host. + *****************************************************************************/ +int32_t Api_select(void *pCxt, uint32_t handle, uint32_t tv) +{ + int32_t index = 0; + int32_t result = A_OK; + + do + { + /*Find context*/ + if ((index = find_socket_context(handle, true)) == SOCKET_NOT_FOUND) + { + result = A_SOCK_INVALID; + break; + } + + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + result = A_ERROR; + break; + } + if ((ath_sock_context[index]->type == SOCK_STREAM_TYPE) && (ath_sock_context[index]->remaining_bytes != 0) && + (ath_sock_context[index]->old_netbuf != NULL)) + { + result = A_OK; + break; + } + /*Packet is available, return*/ + if (!QUEUE_EMPTY(index)) + { + result = A_OK; + break; + } + + if (ath_sock_context[index]->TCPCtrFlag == TCP_FIN) + { + if (QUEUE_EMPTY(index)) + { + clear_socket_context(index); + result = A_SOCK_INVALID; + // Why on earth is this here? (MMJ) + // OS_INT_ENABLE(0); + break; + } + } + + if (ath_sock_context[index]->TCPCtrFlag == TCP_LISTEN) + { + /*Wait for specified time*/ + if (BLOCK(pCxt, ath_sock_context[index], tv, RX_DIRECTION) != A_OK) + { + /*Check if Peer closed socket while we were waiting*/ + if (ath_sock_context[index]->handle == 0) + { + result = A_SOCK_INVALID; + break; + } + /*Timeout, no activity detected*/ + result = A_ERROR; + } + else + { + /*Something is available, it may be a new incoming connection or data*/ + if ((!QUEUE_EMPTY(index)) || (ath_sock_context[index]->result == TCP_CONNECTION_AVAILABLE)) + { + ath_sock_context[index]->result = 0; + result = A_OK; + } + else + { + result = A_ERROR; + } + } + } + else + { + /*Wait for specified time*/ + if (BLOCK_FOR_DATA(pCxt, ath_sock_context[index], tv, RX_DIRECTION) != A_OK) + { + /*Check if Peer closed socket while we were waiting*/ + if (ath_sock_context[index]->handle == 0) + { + result = A_SOCK_INVALID; + break; + } + /*Timeout, no activity detected*/ + result = A_ERROR; + } + else + { + /*Something is available, it may be a new incoming connection or data*/ + if ((!QUEUE_EMPTY(index)) || (ath_sock_context[index]->result == TCP_CONNECTION_AVAILABLE)) + { + ath_sock_context[index]->result = 0; + result = A_OK; + } + else + { + result = A_ERROR; + } + } + } + } while (0); + return result; +} + +#if T_SELECT_VER1 +/*****************************************************************************/ +/* Api_select - + * + * void *pCxt- driver context + * uint32_t handle- socket handle + * uint32_t tv - time to wait in milliseconds + * Returns- 0 in case of successful connect, A_ERROR otherwise + * Select can be called to check for incoming connections or for incoming data. + * It waits for a specified time period before returning. This call does not + * propagate to the target, it is consumed in the host. + *****************************************************************************/ + +int32_t Api_select_ver1(void *pCxt, int32_t num, uint32_t *r_fd, uint32_t *w_fd, uint32_t *e_fd, uint32_t tv) +{ + int32_t index = 0; + int32_t result = 0; + int32_t first_time = 1; + uint32_t r_mask, w_mask; + HTC_ENDPOINT_ID eid; + A_ENDPOINT_T *pEp; + static uint32_t next_txsock = 0; + uint32_t startsock; + uint8_t credits; + + w_mask = r_mask = 0; + + // w_fd and r_fd are used to return the socket indexes which have some + // activity. Take a backup and initialize them to zero + if (w_fd) + { + eid = Util_AC2EndpointID(pCxt, WMM_AC_BE); + pEp = Util_GetEndpoint(pCxt, eid); + credits = pEp->credits; + + if (credits > 0) /* Credits Available */ + { + /* Save the last serviced socket and start from the next one to avoid + * servicing the first socket alone in case of only one credit available + */ + startsock = next_txsock; + for (index = startsock; index < (MAX_SOCKETS_SUPPORTED + startsock); index++) + { + index %= MAX_SOCKETS_SUPPORTED; + if (w_mask & (1 << index)) + { + if (ath_sock_context[index]->handle != 0) + { + *w_fd |= 1 << index; + result += 1; + + next_txsock = index + 1; + credits--; + } + else + { + // STALE socket. Update the mask for this handle. The next + // read will return 0/-1 + *(w_fd) |= (1 << index); + result += 1; + } + } + /* If there are no credits, break */ + if (!credits) + break; + } + } /* credits > 0 */ + } /* w_mask */ + + if (r_fd) + { + r_mask = *r_fd; + *r_fd = 0; + } + + if ((w_mask == 0) && (r_mask == 0)) + { + // Nothing to do + return result; + } + +AGAIN: + // Check if we have enough credits + if (w_mask) + { + eid = Util_AC2EndpointID(pCxt, WMM_AC_BE); + pEp = Util_GetEndpoint(pCxt, eid); + if (pEp->credits > 0) + { + for (index = 0; index < MAX_SOCKETS_SUPPORTED; index++) + { + if (w_mask & (1 << index)) + { + *w_fd = 1 << index; + result += 1; + break; + } + } + } + } + + // Go through all read handles + if (r_mask) + { + for (index = 0; index < MAX_SOCKETS_SUPPORTED; index++) + { + if (r_mask & (1 << index)) + { + if (ath_sock_context[index]->handle != 0) + { +#if 0 + if(/*(ath_sock_context[index]->type == SOCK_STREAM_TYPE) && */ + (ath_sock_context[index]->remaining_bytes != 0) && + (ath_sock_context[index]->old_netbuf != NULL)) + { + //Update the mask for this handle + *(r_fd) |= (1<result == TCP_CONNECTION_AVAILABLE) || + (ath_sock_context[index]->data != NULL)) + { + // Update the mask for this handle + *(r_fd) |= (1 << index); + result += 1; + } + + // Update the mask for this handle. The next + // read will return 0/-1 + if (ath_sock_context[index]->TCPCtrFlag == TCP_FIN) + { + // Update the mask for this handle + *(r_fd) |= (1 << index); + result += 1; + } + } + else // if( (r_mask & (1<handle == 0) ) + { + // STALE socket. Update the mask for this handle. The next + // read will return 0/-1 + *(r_fd) |= (1 << index); + result += 1; + } + } + } + } + + // If no pending activity, wait for the time requested and again check for + // activity + if ((result == 0) && (first_time)) + { + first_time = 0; + // Wait for the specified time + if (BLOCK_SELECT(pCxt, tv) == A_OK) + { + // Some activity happened because of which we were woken up. Figure + // out the activity and set the mask accordingly + goto AGAIN; + } + } + + return result; +} + +#endif + +/*****************************************************************************/ +/* Api_setsockopt - API to set specified socket option + * name field must be populated accordingly. + * void *pCxt- driver context + * uint32_t handle- socket handle + * uint32_t level- option level + * uint32_t optname- option name + * uint32_t optlen- option length + * Returns- 0 in case of success, A_ERROR otherwise + *****************************************************************************/ +int32_t Api_setsockopt(void *pCxt, uint32_t handle, uint32_t level, uint32_t optname, uint8_t *optval, uint32_t optlen) +{ + A_DRIVER_CONTEXT *pDCxt; + SOCK_OPT_T *sockSetopt; + // uint8_t* data = NULL; + int32_t index = 0, total_length = 0; + int32_t result = A_OK; + + pDCxt = GET_DRIVER_COMMON(pCxt); + + do + { + /*Find context*/ + if ((index = find_socket_context(handle, true)) == SOCKET_NOT_FOUND) + { + result = A_ERROR; + break; + } + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + result = A_ERROR; + break; + } + total_length = sizeof(SOCK_OPT_T); + + if (optval != NULL && optlen != 0) + { + total_length += optlen - sizeof(uint8_t); + } + + /*Allocate space for option*/ + if ((sockSetopt = A_MALLOC(total_length, MALLOC_ID_CONTEXT)) == NULL) + { + result = A_NO_MEMORY; + break; + } + + if (optval != NULL && optlen != 0) + { + A_MEMCPY(sockSetopt->optval, optval, optlen); + } + + sockSetopt->handle = A_CPU2LE32(handle); + sockSetopt->level = A_CPU2LE32(level); + sockSetopt->optname = A_CPU2LE32(optname); + sockSetopt->optlen = A_CPU2LE32(optlen); + + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_SETSOCKOPT); + + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_SETSOCKOPT, (uint8_t *)sockSetopt, total_length) != A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_SETSOCKOPT); + A_FREE(sockSetopt, MALLOC_ID_CONTEXT); + result = A_ERROR; + break; + } + + do + { + if (BLOCK(pCxt, ath_sock_context[index], COMMAND_BLOCK_TIMEOUT, RX_DIRECTION) != A_OK) + { + A_ASSERT(0); + } + } while (SOCK_EV_MASK_TEST(ath_sock_context[index], SOCK_SETSOCKOPT)); + + A_FREE(sockSetopt, MALLOC_ID_CONTEXT); + result = ath_sock_context[index]->result; + } while (0); + + return result; +} + +/*****************************************************************************/ +/* Api_getsockopt - API to fetch specified socket option + * name field must be populated accordingly. + * void *pCxt- driver context + * uint32_t handle- socket handle + * uint32_t level- option level + * uint32_t optname- option name + * uint32_t optlen- option length + * Returns- 0 in case of success, A_ERROR otherwise + *****************************************************************************/ +int32_t Api_getsockopt(void *pCxt, uint32_t handle, uint32_t level, uint32_t optname, uint8_t *optval, uint32_t optlen) +{ + A_DRIVER_CONTEXT *pDCxt; + SOCK_OPT_T *sock_getopt = NULL; + uint32_t index = 0, total_length = 0; + int32_t result = A_OK; + uint8_t free_buf = 1; + + pDCxt = GET_DRIVER_COMMON(pCxt); + + do + { + /*Find context*/ + if ((int32_t)(index = find_socket_context(handle, true)) == SOCKET_NOT_FOUND) + { + result = A_ERROR; + free_buf = 0; + break; + } + + /*Check if socket is blocked for a previous command*/ + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + result = A_ERROR; + free_buf = 0; + break; + } + /*Cannot call getsockopt with NULL*/ + if (optval == NULL || optlen == 0) + { + result = A_ERROR; + free_buf = 0; + break; + } + /*Total length depends upon the type of option*/ + total_length = sizeof(SOCK_OPT_T) + optlen - sizeof(uint8_t); + + /*Allocate buffer for option*/ + if ((sock_getopt = A_MALLOC(total_length, MALLOC_ID_CONTEXT)) == NULL) + { + result = A_NO_MEMORY; + free_buf = 0; + break; + } + + sock_getopt->handle = A_CPU2LE32(handle); + sock_getopt->level = A_CPU2LE32(level); + sock_getopt->optname = A_CPU2LE32(optname); + sock_getopt->optlen = A_CPU2LE32(optlen); + + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_GETSOCKOPT); + /*Send the packet*/ + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_GETSOCKOPT, (uint8_t *)sock_getopt, total_length) != A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_GETSOCKOPT); + result = A_ERROR; + free_buf = 0; + break; + } + + /*Wait for response from stack*/ + do + { + if (BLOCK(pCxt, ath_sock_context[index], COMMAND_BLOCK_TIMEOUT, RX_DIRECTION) != A_OK) + { + A_ASSERT(0); + } + } while (SOCK_EV_MASK_TEST(ath_sock_context[index], SOCK_GETSOCKOPT)); + + if (ath_sock_context[index]->data != NULL) + { + A_MEMCPY(optval, ((SOCK_OPT_T *)ath_sock_context[index]->data)->optval, optlen); + // A_FREE(ath_sock_context[index]->data,MALLOC_ID_CONTEXT); + ath_sock_context[index]->data = NULL; //TODO: check possible leak !! + } + result = ath_sock_context[index]->result; + } while (0); + + A_FREE(sock_getopt, MALLOC_ID_CONTEXT); + + if (free_buf) + { + /*Free the netbuf*/ + A_NETBUF_FREE(ath_sock_context[index]->pReq); + } + + return result; +} + +/*****************************************************************************/ +/* Api_ipconfig - API to obtain IP address information from target + * void *pCxt- driver context + * uint32_t mode- query vs set + * uint32_t* ipv4_addrA_UINT32* subnetMask, uint32_t* gateway4 + * Returns- 0 in case of successful connect, A_ERROR otherwise + *****************************************************************************/ +int32_t Api_ipconfig(void *pCxt, + uint32_t mode, + uint32_t *ipv4_addr, + uint32_t *subnetMask, + uint32_t *gateway4, + IP46ADDR *dnsaddr, + char *hostname) +{ + A_DRIVER_CONTEXT *pDCxt; + IPCONFIG_CMD_T ipcfg; + IPCONFIG_RECV_T *result; + uint32_t index = GLOBAL_SOCK_INDEX; // reserved for global commands ToDo- cleanup later + int32_t res = A_OK; + uint8_t free_buf = 1; + + pDCxt = GET_DRIVER_COMMON(pCxt); + + do + { + /*Check if socket is blocked for a previous command*/ + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + res = A_ERROR; + free_buf = 0; + break; + } + if (mode == 1) + { + /*This is not a query or dhcp command*/ + ipcfg.mode = A_CPU2LE32(mode); + ipcfg.ipv4 = A_CPU2LE32(*ipv4_addr); + ipcfg.subnetMask = A_CPU2LE32(*subnetMask); + ipcfg.gateway4 = A_CPU2LE32(*gateway4); + } + else if (mode == 3) + { + ipcfg.ipv4 = A_CPU2LE32(*ipv4_addr); + } + ipcfg.mode = A_CPU2LE32(mode); + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_IPCONFIG); + + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_IPCONFIG, (void *)(&ipcfg), sizeof(IPCONFIG_CMD_T)) != A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_IPCONFIG); + res = A_ERROR; + free_buf = 0; + break; + } + + do + { + if (mode == 2) + { + if (BLOCK(pCxt, ath_sock_context[index], DHCP_WAIT_TIME, RX_DIRECTION) != A_OK) + { + return (int32_t)A_TIMEOUT; + } + } + else if (mode == 3) + { + if (BLOCK(pCxt, ath_sock_context[index], DHCP_AUTO_WAIT_TIME, RX_DIRECTION) != A_OK) + { + return (int32_t)A_TIMEOUT; + } + } + else + { + if (BLOCK(pCxt, ath_sock_context[index], IPCONFIG_WAIT_TIME, RX_DIRECTION) != A_OK) + { + return (int32_t)A_TIMEOUT; + } + } + + } while (SOCK_EV_MASK_TEST(ath_sock_context[index], SOCK_IPCONFIG)); + + /*Got a response*/ + if (ath_sock_context[index]->result != -1) + { + result = (IPCONFIG_RECV_T *)(ath_sock_context[index]->data); + if (mode != 1) + { + if (ipv4_addr != NULL) + *ipv4_addr = A_CPU2LE32(result->ipv4); + if (subnetMask != NULL) + *subnetMask = A_CPU2LE32(result->subnetMask); + if (gateway4 != NULL) + *gateway4 = A_CPU2LE32(result->gateway4); + if (dnsaddr != NULL) + memcpy(dnsaddr, &result->dnsaddr, sizeof(result->dnsaddr)); + if (hostname != NULL) + strcpy(hostname, result->hostname); + } + } + res = ath_sock_context[index]->result; + } while (0); + + if (free_buf) + { + /*Free the netbuf*/ + A_NETBUF_FREE(ath_sock_context[index]->pReq); + } + return res; +} + +/*****************************************************************************/ +/* Api_ip6config - API to obtain IPv6 address information from target + * void *pCxt- driver context + * uint32_t mode- query vs set + * + * Returns- 0 in case of successful connect, A_ERROR otherwise + *****************************************************************************/ +int32_t Api_ip6config(void *pCxt, + uint32_t mode, + IP6_ADDR_T *v6Global, + IP6_ADDR_T *v6Link, + IP6_ADDR_T *v6DefGw, + IP6_ADDR_T *v6GlobalExtd, + int32_t *LinkPrefix, + int32_t *GlbPrefix, + int32_t *DefgwPrefix, + int32_t *GlbPrefixExtd) +{ + A_DRIVER_CONTEXT *pDCxt; + IPCONFIG_CMD_T ipcfg; + IPCONFIG_RECV_T *result; + uint32_t index = GLOBAL_SOCK_INDEX; // reserved for global commands ToDo- cleanup later + int32_t res = A_OK; + uint8_t free_buf = 1; + + pDCxt = GET_DRIVER_COMMON(pCxt); + + do + { + /*Check if socket is blocked for a previous command*/ + if (IS_SOCKET_BLOCKED(ath_sock_context[GLOBAL_SOCK_INDEX])) + { + res = A_ERROR; + free_buf = 0; + break; + } + + ipcfg.mode = A_CPU2LE32(mode); + + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_IP6CONFIG); + + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_IP6CONFIG, (void *)(&ipcfg), sizeof(IPCONFIG_CMD_T)) != A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_IP6CONFIG); + res = A_ERROR; + free_buf = 0; + break; + } + + do + { + if (BLOCK(pCxt, ath_sock_context[index], COMMAND_BLOCK_TIMEOUT, RX_DIRECTION) != A_OK) + { + A_ASSERT(0); + } + + } while (SOCK_EV_MASK_TEST(ath_sock_context[index], SOCK_IP6CONFIG)); + + /*Got a response*/ + if (ath_sock_context[index]->result != -1) + { + result = (IPCONFIG_RECV_T *)(ath_sock_context[index]->data); + + A_MEMCPY(v6Global, &result->ipv6GlobalAddr, sizeof(IP6_ADDR_T)); + A_MEMCPY(v6Link, &result->ipv6LinkAddr, sizeof(IP6_ADDR_T)); + A_MEMCPY(v6DefGw, &result->ipv6DefGw, sizeof(IP6_ADDR_T)); + A_MEMCPY(v6GlobalExtd, &result->ipv6LinkAddrExtd, sizeof(IP6_ADDR_T)); + *LinkPrefix = A_CPU2LE32(result->LinkPrefix); + *GlbPrefix = A_CPU2LE32(result->GlbPrefix); + *DefgwPrefix = A_CPU2LE32(result->DefGwPrefix); + *GlbPrefixExtd = A_CPU2LE32(result->GlbPrefixExtd); + } + res = ath_sock_context[index]->result; + } while (0); + + if (free_buf) + { + /*Free the netbuf*/ + A_NETBUF_FREE(ath_sock_context[index]->pReq); + } + + return res; +} + +/*****************************************************************************/ +/* Api_ipconfig_dhcp_pool - API to configure dhcp pool + * void *pCxt- driver context + * uint32_t *start_ipv4_addr - Start ip address + * uint32_t* end_ipv4_addr int32_t leasetime + * Returns- 0 in case of successful connect, A_ERROR otherwise + *****************************************************************************/ +int32_t Api_ipconfig_dhcp_pool(void *pCxt, uint32_t *start_ipv4_addr, uint32_t *end_ipv4_addr, int32_t leasetime) +{ + A_DRIVER_CONTEXT *pDCxt; + IPCONFIG_DHCP_POOL_T ipcfg; + uint32_t index = GLOBAL_SOCK_INDEX; // reserved for global commands ToDo- cleanup later + pDCxt = GET_DRIVER_COMMON(pCxt); + + /*Check if socket is blocked for a previous command*/ + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + return A_ERROR; + } + ipcfg.startaddr = A_CPU2LE32(*start_ipv4_addr); + ipcfg.endaddr = A_CPU2LE32(*end_ipv4_addr); + ipcfg.leasetime = A_CPU2LE32(leasetime); + + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_IPCONFIG_DHCP_POOL, (void *)(&ipcfg), sizeof(IPCONFIG_DHCP_POOL_T)) != A_OK) + { + return A_ERROR; + } + + return (A_OK); +} + +/*****************************************************************************/ +/* Api_ip6config_router_prefix - API to configure router prefix + * void *pCxt- driver context + * uint8_t *v6addr - v6prefix + * int32_t prefixlen int32_t prefix_lifetime ,int32_t valid_lifetime + * Returns- 0 in case of successful connect, A_ERROR otherwise + *****************************************************************************/ +int32_t Api_ip6config_router_prefix( + void *pCxt, IP6_ADDR_T *v6addr, int32_t prefixlen, int32_t prefix_lifetime, int32_t valid_lifetime) +{ + A_DRIVER_CONTEXT *pDCxt; + IP6CONFIG_ROUTER_PREFIX_T ip6cfg; + uint32_t index = GLOBAL_SOCK_INDEX; // reserved for global commands ToDo- cleanup later + pDCxt = GET_DRIVER_COMMON(pCxt); + + /*Check if socket is blocked for a previous command*/ + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + return A_ERROR; + } + A_MEMCPY(ip6cfg.v6addr, v6addr, sizeof(IP6_ADDR_T)); + ip6cfg.prefixlen = A_CPU2LE32(prefixlen); + ip6cfg.prefix_lifetime = A_CPU2LE32(prefix_lifetime); + ip6cfg.valid_lifetime = A_CPU2LE32(valid_lifetime); + + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_IP6CONFIG_ROUTER_PREFIX, (void *)(&ip6cfg), + sizeof(IP6CONFIG_ROUTER_PREFIX_T)) != A_OK) + { + return A_ERROR; + } + return (A_OK); +} + +/*****************************************************************************/ +/* Api_ipbridgemode - API to enable bridge mode + * void *pCxt- driver context + * int32_t status - enable the bridge mode + * Returns- A_OK in case of successful connect, A_ERROR otherwise + *****************************************************************************/ +int32_t Api_ipbridgemode(void *pCxt, uint16_t status) +{ + A_DRIVER_CONTEXT *pDCxt = NULL; + SOCK_IP_BRIDGEMODE_T sock_ipbridgemode; + + pDCxt = GET_DRIVER_COMMON(pCxt); + /*Check if socket is blocked for a previous command*/ + if (IS_SOCKET_BLOCKED(ath_sock_context[GLOBAL_SOCK_INDEX])) + { + return A_ERROR; + } + sock_ipbridgemode.bridgemode = A_CPU2LE16(status); + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_IP_BRIDGEMODE, (void *)(&sock_ipbridgemode), sizeof(sock_ipbridgemode)) != + A_OK) + { + return A_ERROR; + } + return (A_OK); +} + +/*****************************************************************************/ +/* Api_ipconfig_set_tcp_exponential_backoff_retry - API to tcp exponential backoff retry + * void *pCxt- driver context + * int32_t retry - No of MAX Retries + * Returns- 0 in case of successful connect, A_ERROR otherwise + *****************************************************************************/ +int32_t Api_ipconfig_set_tcp_exponential_backoff_retry(void *pCxt, int32_t retry) +{ + A_DRIVER_CONTEXT *pDCxt = NULL; + SOCK_IP_BACKOFF_T sock_backoff; + + pDCxt = GET_DRIVER_COMMON(pCxt); + /*Check if socket is blocked for a previous command*/ + if (IS_SOCKET_BLOCKED(ath_sock_context[GLOBAL_SOCK_INDEX])) + { + return A_ERROR; + } + sock_backoff.max_retry = A_CPU2LE32(retry); + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_IP_SET_TCP_EXP_BACKOFF_RETRY, (void *)(&sock_backoff), + sizeof(SOCK_IP_BACKOFF_T)) != A_OK) + { + return A_ERROR; + } + return (A_OK); +} + +/*****************************************************************************/ +/* Api_ipconfig_set_ip6_status - API to set ip6 status + * void *pCxt- driver context + * uint16_t status - enable or diable + * Returns- 0 in case of successful connect, A_ERROR otherwise + *****************************************************************************/ +int32_t Api_ipconfig_set_ip6_status(void *pCxt, uint16_t status) +{ + A_DRIVER_CONTEXT *pDCxt = NULL; + SOCK_IPv6_STATUS_T sock_ip6status; + + pDCxt = GET_DRIVER_COMMON(pCxt); + /*Check if socket is blocked for a previous command*/ + if (IS_SOCKET_BLOCKED(ath_sock_context[GLOBAL_SOCK_INDEX])) + { + return A_ERROR; + } + sock_ip6status.ipv6_status = A_CPU2LE16(status); + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_IP_SET_IP6_STATUS, (void *)(&sock_ip6status), sizeof(sock_ip6status)) != + A_OK) + { + return A_ERROR; + } + return (A_OK); +} + +/*****************************************************************************/ +/* Api_ipconfig_dhcp_release - API to release dhcp ip address + * void *pCxt- driver context + * Returns- 0 in case of successful connect, A_ERROR otherwise + *****************************************************************************/ +int32_t Api_ipconfig_dhcp_release(void *pCxt) +{ + A_DRIVER_CONTEXT *pDCxt = NULL; + SOCK_IP_DHCP_RELEASE_T release; + uint16_t ifindx = 0; + + pDCxt = GET_DRIVER_COMMON(pCxt); + /*Check if socket is blocked for a previous command*/ + if (IS_SOCKET_BLOCKED(ath_sock_context[GLOBAL_SOCK_INDEX])) + { + return A_ERROR; + } + release.ifIndex = A_CPU2LE16(ifindx); + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_IP_DHCP_RELEASE, (void *)(&release), sizeof(SOCK_IP_DHCP_RELEASE_T)) != + A_OK) + { + return A_ERROR; + } + return (A_OK); +} + +int32_t Api_ipconfig_set_tcp_rx_buffer(void *pCxt, int32_t rxbuf) +{ + A_DRIVER_CONTEXT *pDCxt = NULL; + SOCK_IP_TCP_RX_BUF_T sock_tcp_rx_buf; + + pDCxt = GET_DRIVER_COMMON(pCxt); + /*Check if socket is blocked for a previous command*/ + if (IS_SOCKET_BLOCKED(ath_sock_context[GLOBAL_SOCK_INDEX])) + { + return A_ERROR; + } + sock_tcp_rx_buf.rxbuf = A_CPU2LE32(rxbuf); + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_IP_SET_TCP_RX_BUF, (void *)(&sock_tcp_rx_buf), + sizeof(SOCK_IP_TCP_RX_BUF_T)) != A_OK) + { + return A_ERROR; + } + return (A_OK); +} + +#if ENABLE_HTTP_SERVER +int32_t Api_ip_http_server(void *pCxt, int32_t command) +{ + A_DRIVER_CONTEXT *pDCxt = NULL; + SOCK_IP_HTTP_SERVER_T sock_http_server; + int index = GLOBAL_SOCK_INDEX; + + pDCxt = GET_DRIVER_COMMON(pCxt); + /*Check if socket is blocked for a previous command*/ + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + return A_ERROR; + } + sock_http_server.enable = A_CPU2LE32(command); + + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_HTTP_SERVER); + + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_HTTP_SERVER, (void *)(&sock_http_server), sizeof(SOCK_IP_HTTP_SERVER_T)) != + A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_HTTP_SERVER); + return A_ERROR; + } + + do + { + if (BLOCK(pCxt, ath_sock_context[index], COMMAND_BLOCK_TIMEOUT, RX_DIRECTION) != A_OK) + { + A_ASSERT(0); + } + } while (SOCK_EV_MASK_TEST(ath_sock_context[index], SOCK_HTTP_SERVER)); + + return (ath_sock_context[index]->result); +} + +int32_t Api_ip_http_server_method( + void *pCxt, int32_t command, uint8_t *pagename, uint8_t *objname, int32_t objtype, int32_t objlen, uint8_t *value) +{ + A_DRIVER_CONTEXT *pDCxt = NULL; + SOCK_IP_HTTP_SERVER_CMD_T sock_http_server; + int index = GLOBAL_SOCK_INDEX; + uint32_t *length; + uint8_t *buf; + + pDCxt = GET_DRIVER_COMMON(pCxt); + /*Check if socket is blocked for a previous command*/ + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + return A_ERROR; + } + sock_http_server.command = A_CPU2LE32(command); + strcpy((char *)sock_http_server.pagename, (const char *)pagename); + strcpy((char *)sock_http_server.objname, (const char *)objname); + sock_http_server.objlen = A_CPU2LE32(objlen); + if (command == HTTP_POST_METHOD) /* For POST command */ + strcpy((char *)sock_http_server.value, (const char *)value); + + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_HTTP_SERVER_CMD); + + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_HTTP_SERVER_CMD, (void *)(&sock_http_server), + sizeof(SOCK_IP_HTTP_SERVER_CMD_T)) != A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_HTTP_SERVER_CMD); + return A_ERROR; + } + + do + { + if (BLOCK(pCxt, ath_sock_context[index], COMMAND_BLOCK_TIMEOUT, RX_DIRECTION) != A_OK) + { + A_ASSERT(0); + } + } while (SOCK_EV_MASK_TEST(ath_sock_context[index], SOCK_HTTP_SERVER_CMD)); + + if ((ath_sock_context[index]->result != -1) && (command == HTTP_GET_METHOD)) + { + length = (uint32_t *)ath_sock_context[index]->data; + if (*length > 512) + A_ASSERT(0); + buf = (uint8_t *)(length + 1); + A_MEMCPY(value, buf, *length); + value[*length] = '\0'; // NULL terminating the string + } + + A_NETBUF_FREE(ath_sock_context[index]->pReq); + + return (ath_sock_context[index]->result); +} +#endif + +#if ENABLE_HTTP_CLIENT +/*****************************************************************************/ +/* Api_httpc_method - API to use http client methods + * It is a non blocking call. Just sends the HTTP command and return + * void *pCxt- driver context + * Returns- 0 in case of successful connect, A_ERROR otherwise + *****************************************************************************/ + +int32_t Api_httpc_method(void *pCxt, uint32_t command, uint8_t *url, uint8_t *data, uint8_t **output) +{ + A_DRIVER_CONTEXT *pDCxt = NULL; + SOCK_HTTPC_T httpc; + int32_t index = GLOBAL_SOCK_INDEX; + + pDCxt = GET_DRIVER_COMMON(pCxt); + + /*Check if socket is blocked for a previous command*/ + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + return A_ERROR; + } + + memset(&httpc, 0, sizeof(httpc)); + + httpc.command = A_CPU2LE32(command); + if (url) + A_MEMCPY(httpc.url, url, strlen((const char *)url)); + if (data) + A_MEMCPY(httpc.data, data, strlen((const char *)data)); + + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_HTTPC); + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_HTTPC, (void *)(&httpc), sizeof(SOCK_HTTPC_T)) != A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_HTTPC); + return A_ERROR; + } + + do + { + if (BLOCK(pCxt, ath_sock_context[index], COMMAND_BLOCK_TIMEOUT, RX_DIRECTION) != A_OK) + { + A_ASSERT(0); + } + } while (SOCK_EV_MASK_TEST(ath_sock_context[index], SOCK_HTTPC)); + + if ((ath_sock_context[index]->result != A_ERROR) && (output != NULL)) + { + *output = ath_sock_context[index]->data; + // printf("Adding Q %p %p\n", ath_sock_context[index]->pReq, ath_sock_context[index]->data); + A_NETBUF_ENQUEUE(&zero_copy_free_queue, ath_sock_context[index]->pReq); + } + else + A_NETBUF_FREE(ath_sock_context[index]->pReq); + + return ath_sock_context[index]->result; +} + +#endif /* ENABLE_HTTP_CLIENT */ + +#if ENABLE_DNS_CLIENT +extern uint32_t dns_block_time; + +int32_t Api_ip_resolve_host_name(void *pCxt, DNC_CFG_CMD *DncCfg, DNC_RESP_INFO *DncRespInfo) +{ + A_DRIVER_CONTEXT *pDCxt = NULL; + int index = GLOBAL_SOCK_INDEX; + DNC_RESP_INFO *result = NULL; + int32_t res = A_OK; + uint8_t free_buf = 1; + + pDCxt = GET_DRIVER_COMMON(pCxt); + /*Check if socket is blocked for a previous command*/ + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + free_buf = 0; + return A_ERROR; + } + DncCfg->mode = A_CPU2LE32(DncCfg->mode); + DncCfg->domain = A_CPU2LE32(DncCfg->domain); + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_DNC_CMD); + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_DNC_CMD, (void *)DncCfg, sizeof(DNC_CFG_CMD)) != A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_DNC_CMD); + free_buf = 0; + return A_ERROR; + } + + do + { + if (BLOCK(pCxt, ath_sock_context[index], dns_block_time, RX_DIRECTION) != A_OK) + { + // printf("dnsclient timed out \r\n"); + return -1; + } + } while (SOCK_EV_MASK_TEST(ath_sock_context[index], SOCK_DNC_CMD)); + + if (ath_sock_context[index]->result != -1) + { + result = (DNC_RESP_INFO *)(ath_sock_context[index]->data); + A_MEMCPY(DncRespInfo, result, sizeof(DNC_RESP_INFO)); + } + res = ath_sock_context[index]->result; + /*Free the netbuf*/ + if (free_buf) + { + A_NETBUF_FREE(ath_sock_context[index]->pReq); + } + return res; +} + +int32_t Api_ip_dns_client(void *pCxt, int32_t command) +{ + A_DRIVER_CONTEXT *pDCxt = NULL; + SOCK_IP_DNS_CLIENT_T sock_dns_client; + int index = GLOBAL_SOCK_INDEX; + + pDCxt = GET_DRIVER_COMMON(pCxt); + /*Check if socket is blocked for a previous command*/ + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + return A_ERROR; + } + sock_dns_client.command = A_CPU2LE32(command); + + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_DNC_ENABLE); + + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_DNC_ENABLE, (void *)(&sock_dns_client), sizeof(SOCK_IP_DNS_CLIENT_T)) != + A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_DNC_ENABLE); + return A_ERROR; + } + + do + { + if (BLOCK(pCxt, ath_sock_context[index], COMMAND_BLOCK_TIMEOUT, RX_DIRECTION) != A_OK) + { + A_ASSERT(0); + } + } while (SOCK_EV_MASK_TEST(ath_sock_context[index], SOCK_DNC_ENABLE)); + + return (ath_sock_context[index]->result); +} + +int32_t Api_ip_dns_server_addr(void *pCxt, IP46ADDR *addr) +{ + A_DRIVER_CONTEXT *pDCxt = NULL; + SOCK_IP_CFG_DNS_SRVR_ADDR sock_dns_srvr_addr; + int index = GLOBAL_SOCK_INDEX; + + pDCxt = GET_DRIVER_COMMON(pCxt); + /*Check if socket is blocked for a previous command*/ + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + return A_ERROR; + } + + if (addr->type == ATH_AF_INET) + { + sock_dns_srvr_addr.addr.type = ATH_AF_INET; + sock_dns_srvr_addr.addr.addr4 = addr->addr4; + sock_dns_srvr_addr.addr.au1Rsvd[0] = addr->au1Rsvd[0]; + } + if (addr->type == ATH_AF_INET6) + { + sock_dns_srvr_addr.addr.type = ATH_AF_INET6; + sock_dns_srvr_addr.addr.au1Rsvd[0] = addr->au1Rsvd[0]; + memcpy(&sock_dns_srvr_addr.addr.addr6, &addr->addr6, sizeof(IP6_ADDR_T)); + } + + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_DNS_SRVR_CFG_ADDR); + + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_DNS_SRVR_CFG_ADDR, (void *)(&sock_dns_srvr_addr), + sizeof(SOCK_IP_CFG_DNS_SRVR_ADDR)) != A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_DNS_SRVR_CFG_ADDR); + return A_ERROR; + } + + do + { + if (BLOCK(pCxt, ath_sock_context[index], COMMAND_BLOCK_TIMEOUT, RX_DIRECTION) != A_OK) + { + A_ASSERT(0); + } + } while (SOCK_EV_MASK_TEST(ath_sock_context[index], SOCK_DNS_SRVR_CFG_ADDR)); + + return (ath_sock_context[index]->result); +} +#endif /* ENABLE_DNS_CLIENT */ + +int32_t Api_ip_hostname(void *pCxt, char *domain_name) +{ + A_DRIVER_CONTEXT *pDCxt = NULL; + SOCK_IP_CFG_HOST_NAME sock_ip_host_name; + int index = GLOBAL_SOCK_INDEX; + + pDCxt = GET_DRIVER_COMMON(pCxt); + /*Check if socket is blocked for a previous command*/ + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + return A_ERROR; + } + strcpy(sock_ip_host_name.domain_name, domain_name); + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_IP_HOST_NAME); + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_IP_HOST_NAME, (void *)(&sock_ip_host_name), + sizeof(SOCK_IP_CFG_HOST_NAME)) != A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_IP_HOST_NAME); + return A_ERROR; + } + + do + { + if (BLOCK(pCxt, ath_sock_context[index], COMMAND_BLOCK_TIMEOUT, RX_DIRECTION) != A_OK) + { + A_ASSERT(0); + } + } while (SOCK_EV_MASK_TEST(ath_sock_context[index], SOCK_IP_HOST_NAME)); + + return (ath_sock_context[index]->result); +} + +#if ENABLE_DNS_SERVER + +int32_t Api_ip_dns_local_domain(void *pCxt, char *domain_name) +{ + A_DRIVER_CONTEXT *pDCxt = NULL; + SOCK_IP_CFG_DNS_LOCAL_DOMAIN sock_dns_local_domain; + int index = GLOBAL_SOCK_INDEX; + + pDCxt = GET_DRIVER_COMMON(pCxt); + /*Check if socket is blocked for a previous command*/ + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + return A_ERROR; + } + strcpy(sock_dns_local_domain.domain_name, domain_name); + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_DNS_LOCAL_DOMAIN, (void *)(&sock_dns_local_domain), + sizeof(SOCK_IP_CFG_DNS_LOCAL_DOMAIN)) != A_OK) + { + return A_ERROR; + } + return (A_OK); +} + +int32_t Api_ipdns(void *pCxt, int32_t command, char *domain_name, IP46ADDR *dnsaddr) +{ + A_DRIVER_CONTEXT *pDCxt = NULL; + SOCK_IP_DNS_T sock_ip_dns; + int index = GLOBAL_SOCK_INDEX; + + pDCxt = GET_DRIVER_COMMON(pCxt); + /*Check if socket is blocked for a previous command*/ + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + return A_ERROR; + } + memset(&sock_ip_dns, 0, sizeof(SOCK_IP_DNS_T)); + strcpy(sock_ip_dns.domain_name, domain_name); + sock_ip_dns.command = A_CPU2LE32(command); + // printf("api_dns addr type %d \r\n",dnsaddr->type); + if (dnsaddr->type == ATH_AF_INET) + { + sock_ip_dns.addr.type = ATH_AF_INET; + sock_ip_dns.addr.addr4 = dnsaddr->addr4; + sock_ip_dns.addr.au1Rsvd[0] = dnsaddr->au1Rsvd[0]; + } + if (dnsaddr->type == ATH_AF_INET6) + { + sock_ip_dns.addr.type = ATH_AF_INET6; + sock_ip_dns.addr.au1Rsvd[0] = dnsaddr->au1Rsvd[0]; + memcpy(&sock_ip_dns.addr.addr6, &dnsaddr->addr6, sizeof(IP6_ADDR_T)); + } + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_IP_DNS); + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_IP_DNS, (void *)(&sock_ip_dns), sizeof(SOCK_IP_DNS_T)) != A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_IP_DNS); + return A_ERROR; + } + do + { + if (BLOCK(pCxt, ath_sock_context[index], COMMAND_BLOCK_TIMEOUT, RX_DIRECTION) != A_OK) + { + A_ASSERT(0); + } + } while (SOCK_EV_MASK_TEST(ath_sock_context[index], SOCK_IP_DNS)); + + return (ath_sock_context[index]->result); +} + +int32_t Api_ip_dns_server(void *pCxt, int32_t command) +{ + A_DRIVER_CONTEXT *pDCxt = NULL; + + SOCK_IP_DNS_SERVER_STATUS_T sock_dns_server; + int index = GLOBAL_SOCK_INDEX; + pDCxt = GET_DRIVER_COMMON(pCxt); + + /*Check if socket is blocked for a previous command*/ + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + return A_ERROR; + } + memset(&sock_dns_server, 0, sizeof(SOCK_IP_DNS_SERVER_STATUS_T)); + sock_dns_server.enable = A_CPU2LE32(command); + + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_DNS_SERVER_STATUS, (void *)(&sock_dns_server), + sizeof(SOCK_IP_DNS_SERVER_STATUS_T)) != A_OK) + { + return A_ERROR; + } + + return (A_OK); +} + +#endif /* ENABLE_DNS_SERVER */ + +#if ENABLE_SNTP_CLIENT +int32_t Api_ip_sntp_srvr_addr(void *pCxt, int32_t command, char *sntp_srvr_addr) +{ + A_DRIVER_CONTEXT *pDCxt = NULL; + SOCK_IP_CFG_SNTP_SRVR_ADDR sock_ip_sntp_srvr_addr; + int index = GLOBAL_SOCK_INDEX; + + pDCxt = GET_DRIVER_COMMON(pCxt); + /*Check if socket is blocked for a previous command*/ + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + return A_ERROR; + } + strcpy(sock_ip_sntp_srvr_addr.addr, sntp_srvr_addr); + sock_ip_sntp_srvr_addr.command = A_CPU2LE32(command); + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_IP_SNTP_SRVR_ADDR, (void *)(&sock_ip_sntp_srvr_addr), + sizeof(SOCK_IP_CFG_SNTP_SRVR_ADDR)) != A_OK) + { + return A_ERROR; + } + return (A_OK); +} + +int32_t Api_ip_sntp_get_time(void *pCxt, tSntpTime *SntpTime) +{ + A_DRIVER_CONTEXT *pDCxt = NULL; + int index = GLOBAL_SOCK_INDEX; + int32_t res = A_OK; + uint8_t free_buf = 1; + tSntpTime *result = NULL; + uint8_t buffer[sizeof(WMI_SOCKET_CMD) + 4]; + WMI_SOCKET_CMD *sock_cmd = (WMI_SOCKET_CMD *)&buffer[0]; + + pDCxt = GET_DRIVER_COMMON(pCxt); + /*Check if socket is blocked for a previous command*/ + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + free_buf = 0; + return A_ERROR; + } + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_IP_SNTP_GET_TIME); + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_IP_SNTP_GET_TIME, (void *)&sock_cmd, (sizeof(WMI_SOCKET_CMD) + 4)) != A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_IP_SNTP_GET_TIME); + free_buf = 0; + return A_ERROR; + } + do + { + if (BLOCK(pCxt, ath_sock_context[index], (DHCP_WAIT_TIME * 2), RX_DIRECTION) != A_OK) + { + return -1; + } + } while (SOCK_EV_MASK_TEST(ath_sock_context[index], SOCK_IP_SNTP_GET_TIME)); + + if (ath_sock_context[index]->result != -1) + { + result = (tSntpTime *)(ath_sock_context[index]->data); + A_MEMCPY(SntpTime, result, sizeof(tSntpTime)); + } + res = ath_sock_context[index]->result; + /*Free the netbuf*/ + if (free_buf) + { + A_NETBUF_FREE(ath_sock_context[index]->pReq); + } + return res; +} + +int32_t Api_ip_sntp_get_time_of_day(void *pCxt, tSntpTM *SntpTm) +{ + A_DRIVER_CONTEXT *pDCxt = NULL; + int index = GLOBAL_SOCK_INDEX; + int32_t res = A_OK; + uint8_t free_buf = 1; + tSntpTM *result = NULL; + uint8_t buffer[sizeof(WMI_SOCKET_CMD) + 4]; + WMI_SOCKET_CMD *sock_cmd = (WMI_SOCKET_CMD *)&buffer[0]; + + pDCxt = GET_DRIVER_COMMON(pCxt); + /*Check if socket is blocked for a previous command*/ + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + free_buf = 0; + return A_ERROR; + } + + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_IP_SNTP_GET_TIME_OF_DAY); + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_IP_SNTP_GET_TIME_OF_DAY, (void *)&sock_cmd, (sizeof(WMI_SOCKET_CMD) + 4)) != + A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_IP_SNTP_GET_TIME_OF_DAY); + free_buf = 0; + return A_ERROR; + } + do + { + if (BLOCK(pCxt, ath_sock_context[index], (DHCP_WAIT_TIME * 2), RX_DIRECTION) != A_OK) + { + return -1; + } + } while (SOCK_EV_MASK_TEST(ath_sock_context[index], SOCK_IP_SNTP_GET_TIME_OF_DAY)); + + if (ath_sock_context[index]->result != -1) + { + result = (tSntpTM *)(ath_sock_context[index]->data); + A_MEMCPY(SntpTm, result, sizeof(tSntpTM)); + } + res = ath_sock_context[index]->result; + /*Free the netbuf*/ + if (free_buf) + { + A_NETBUF_FREE(ath_sock_context[index]->pReq); + } + return res; +} + +int32_t Api_ip_sntp_modify_zone_dse(void *pCxt, uint8_t hr, uint8_t mn, uint8_t zone_cal, uint8_t dse_en_dis) +{ + A_DRIVER_CONTEXT *pDCxt = NULL; + int index = GLOBAL_SOCK_INDEX; + int32_t res = A_OK; + SOCK_SNTP_MODIFY_TIMEZONE sock_ip_sntp_time_zone; + + pDCxt = GET_DRIVER_COMMON(pCxt); + /*Check if socket is blocked for a previous command*/ + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + return A_ERROR; + } + sock_ip_sntp_time_zone.hour = hr; + sock_ip_sntp_time_zone.min = mn; + sock_ip_sntp_time_zone.add_sub = zone_cal; + sock_ip_sntp_time_zone.dse = dse_en_dis; + + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_IP_SNTP_CONFIG_TIMEZONE_DSE); + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_IP_SNTP_CONFIG_TIMEZONE_DSE, (void *)(&sock_ip_sntp_time_zone), + sizeof(SOCK_SNTP_MODIFY_TIMEZONE)) != A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_IP_SNTP_CONFIG_TIMEZONE_DSE); + return A_ERROR; + } + + return res; +} + +int32_t Api_ip_sntp_query_srvr_address(void *pCxt, tSntpDnsAddr SntpDnsAddr[MAX_SNTP_SERVERS]) +{ + A_DRIVER_CONTEXT *pDCxt = NULL; + int index = GLOBAL_SOCK_INDEX; + int32_t res = A_OK; + uint8_t free_buf = 1; + tSntpDnsAddr *result = NULL; + SOCK_IP_QUERY_SNTP_CONFIG sock_ip_query_sntp_config; + + pDCxt = GET_DRIVER_COMMON(pCxt); + /*Check if socket is blocked for a previous command*/ + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + free_buf = 0; + return A_ERROR; + } + + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_IP_SNTP_QUERY_SNTP_ADDRESS); + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_IP_SNTP_QUERY_SNTP_ADDRESS, (void *)(&sock_ip_query_sntp_config), + sizeof(SOCK_IP_QUERY_SNTP_CONFIG)) != A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_IP_SNTP_QUERY_SNTP_ADDRESS); + free_buf = 0; + return A_ERROR; + } + + do + { + if (BLOCK(pCxt, ath_sock_context[index], (DHCP_WAIT_TIME * 2), RX_DIRECTION) != A_OK) + { + return -1; + } + } while (SOCK_EV_MASK_TEST(ath_sock_context[index], SOCK_IP_SNTP_QUERY_SNTP_ADDRESS)); + + if (ath_sock_context[index]->result != -1) + { + result = (tSntpDnsAddr *)(ath_sock_context[index]->data); + A_MEMCPY(SntpDnsAddr, result, (sizeof(tSntpDnsAddr) * MAX_SNTP_SERVERS)); + } + res = ath_sock_context[index]->result; + /*Free the netbuf*/ + if (free_buf) + { + A_NETBUF_FREE(ath_sock_context[index]->pReq); + } + return res; +} + +int32_t Api_ip_sntp_client(void *pCxt, int32_t command) +{ + A_DRIVER_CONTEXT *pDCxt = NULL; + SOCK_IP_SNTP_CLIENT_T sock_sntp_client; + int index = GLOBAL_SOCK_INDEX; + int32_t res = A_OK; + + pDCxt = GET_DRIVER_COMMON(pCxt); + /*Check if socket is blocked for a previous command*/ + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + return A_ERROR; + } + sock_sntp_client.command = A_CPU2LE32(command); + + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_IP_SNTP_CLIENT_ENABLE); + + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_IP_SNTP_CLIENT_ENABLE, (void *)(&sock_sntp_client), + sizeof(SOCK_IP_SNTP_CLIENT_T)) != A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_IP_SNTP_CLIENT_ENABLE); + return A_ERROR; + } + + return (res); +} + +#endif /* ENABLE_SNTP_CLIENT */ + +#if ENABLE_ROUTING_CMDS +/*****************************************************************************/ +/* Api_ipv4_route - API to add, del and show IPv4 routes + * void *pCxt- driver context + * uint32_t* ipv4_addr + * uint32_t* subnetMask + * uint32_t* gateway + * uint32_t* ifIndex + * Returns- 0 in case of successful connect, A_ERROR otherwise + *****************************************************************************/ +int32_t Api_ipv4_route(void *pCxt, + uint32_t command, + IP_ADDR_T *ipv4_addr, + IP_ADDR_T *subnetMask, + IP_ADDR_T *gateway, + uint32_t *ifIndex, + IPV4_ROUTE_LIST_T *routelist) +{ + A_DRIVER_CONTEXT *pDCxt = NULL; + SOCK_IPV4_ROUTE_T sock_ipv4_route; + int index = GLOBAL_SOCK_INDEX; + int32_t res = A_OK; + + pDCxt = GET_DRIVER_COMMON(pCxt); + /*Check if socket is blocked for a previous command*/ + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + return A_ERROR; + } + sock_ipv4_route.command = A_CPU2LE32(command); + sock_ipv4_route.address = A_CPU2LE32(ipv4_addr->s_addr); + sock_ipv4_route.mask = A_CPU2LE32(subnetMask->s_addr); + sock_ipv4_route.gateway = A_CPU2LE32(gateway->s_addr); + sock_ipv4_route.ifIndex = A_CPU2LE32(*ifIndex); + + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_IPV4_ROUTE); + + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_IPV4_ROUTE, (void *)(&sock_ipv4_route), sizeof(SOCK_IPV4_ROUTE_T)) != A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_IPV4_ROUTE); + return A_ERROR; + } + + do + { + if (BLOCK(pCxt, ath_sock_context[index], COMMAND_BLOCK_TIMEOUT, RX_DIRECTION) != A_OK) + { + return A_ERROR; + } + } while (SOCK_EV_MASK_TEST(ath_sock_context[index], SOCK_IPV4_ROUTE)); + + if (command == 2) + { + A_MEMCPY(routelist, ath_sock_context[index]->data, sizeof(IPV4_ROUTE_LIST_T)); + } + A_NETBUF_FREE(ath_sock_context[index]->pReq); + return (res); +} + +/*****************************************************************************/ +/* Api_ipv6_route - API to add, del and show IPv6 routes + * void *pCxt- driver context + * Returns- 0 in case of successful connect, A_ERROR otherwise + *****************************************************************************/ +int32_t Api_ipv6_route(void *pCxt, + uint32_t command, + IP6_ADDR_T *ip6addr, + uint32_t *prefixLen, + IP6_ADDR_T *gateway, + uint32_t *ifIndex, + IPV6_ROUTE_LIST_T *routelist) +{ + A_DRIVER_CONTEXT *pDCxt = NULL; + SOCK_IPV6_ROUTE_T sock_ipv6_route; + int index = GLOBAL_SOCK_INDEX; + int32_t res = A_OK; + + pDCxt = GET_DRIVER_COMMON(pCxt); + /*Check if socket is blocked for a previous command*/ + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + return A_ERROR; + } + sock_ipv6_route.command = A_CPU2LE32(command); + A_MEMCPY(sock_ipv6_route.address, ip6addr->s6_addr, sizeof(sock_ipv6_route.address)); + sock_ipv6_route.prefixLen = A_CPU2LE32(*prefixLen); + A_MEMCPY(sock_ipv6_route.nexthop, gateway, sizeof(sock_ipv6_route.nexthop)); + sock_ipv6_route.ifIndex = A_CPU2LE32(*ifIndex); + + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_IPV6_ROUTE); + + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_IPV6_ROUTE, (void *)(&sock_ipv6_route), sizeof(SOCK_IPV6_ROUTE_T)) != A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_IPV6_ROUTE); + return A_ERROR; + } + + do + { + if (BLOCK(pCxt, ath_sock_context[index], COMMAND_BLOCK_TIMEOUT, RX_DIRECTION) != A_OK) + { + return A_ERROR; + } + } while (SOCK_EV_MASK_TEST(ath_sock_context[index], SOCK_IPV6_ROUTE)); + + if (command == 2) + { + A_MEMCPY(routelist, ath_sock_context[index]->data, sizeof(IPV6_ROUTE_LIST_T)); + } + A_NETBUF_FREE(ath_sock_context[index]->pReq); + return (res); +} +#endif /* ENABLE_ROUTING_CMDS */ + /*****************************************************************************/ + /* Api_tcp_connection_timeout - API to set TCp Connection Timeout + * void *pCxt- driver context + * Returns- 0 on Success , A_ERROR otherwise + *****************************************************************************/ +int32_t Api_tcp_connection_timeout(void *pCxt, uint32_t timeout_val) +{ + A_DRIVER_CONTEXT *pDCxt = NULL; + SOCK_TCP_CONN_TIMEOUT_T sock_tcp_conn_timeout; + int index = GLOBAL_SOCK_INDEX; + + pDCxt = GET_DRIVER_COMMON(pCxt); + // Check if socket is blocked for a previous command + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + return A_ERROR; + } + A_MEMZERO(&sock_tcp_conn_timeout, sizeof(SOCK_TCP_CONN_TIMEOUT_T)); + sock_tcp_conn_timeout.timeout_val = timeout_val; + + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_TCP_CONN_TIMEOUT); + + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_TCP_CONN_TIMEOUT, (void *)(&sock_tcp_conn_timeout), + sizeof(SOCK_TCP_CONN_TIMEOUT_T)) != A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_TCP_CONN_TIMEOUT); + return A_ERROR; + } + return A_OK; +} +/*****************************************************************************/ +/* Api_ota_upgrade - API to intialize OTA upgrade + * void *pCxt- driver context + * Returns- 0 in case of successful OTA, A_ERROR otherwise + *****************************************************************************/ +int32_t Api_ota_upgrade(void *pCxt, + uint32_t addr, + char *filename, + uint8_t mode, + uint8_t preserve_last, + uint8_t protocol, + uint32_t *resp_code, + uint32_t *length) +{ + A_DRIVER_CONTEXT *pDCxt = NULL; + SOCK_OTA_UPGRADE_T sock_ota_upgrade; + int index = GLOBAL_SOCK_INDEX; + + pDCxt = GET_DRIVER_COMMON(pCxt); + // Check if socket is blocked for a previous command + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + return A_ERROR; + } + A_MEMZERO(&sock_ota_upgrade, sizeof(SOCK_OTA_UPGRADE_T)); + sock_ota_upgrade.ipaddress = addr; + A_MEMCPY(sock_ota_upgrade.filename, filename, strlen(filename)); + sock_ota_upgrade.mode = mode; + sock_ota_upgrade.preserve_last = preserve_last; + sock_ota_upgrade.protocol = protocol; + + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_OTA_UPGRADE); + + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_OTA_UPGRADE, (void *)(&sock_ota_upgrade), sizeof(SOCK_OTA_UPGRADE_T)) != + A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_OTA_UPGRADE); + return A_ERROR; + } + + do + { + if (BLOCK(pCxt, ath_sock_context[index], COMMAND_BLOCK_TIMEOUT, RX_DIRECTION) != A_OK) + { + return A_ERROR; + } + } while (SOCK_EV_MASK_TEST(ath_sock_context[index], SOCK_OTA_UPGRADE)); + + *resp_code = ((tOtaUpgradeResp *)(ath_sock_context[index]->data))->resp_code; + *length = ((tOtaUpgradeResp *)(ath_sock_context[index]->data))->size; + A_NETBUF_FREE(ath_sock_context[index]->pReq); + + return A_OK; +} +/*****************************************************************************/ +/* Api_ota_read - API to read OTA upgrade area + * void *pCxt- driver context + * Returns- 0 in case of successful OTA READ, A_ERROR otherwise + *****************************************************************************/ +int32_t Api_ota_read_area(void *pCxt, uint32_t offset, uint32_t size, uint8_t *buffer, uint32_t *ret_len) +{ + A_DRIVER_CONTEXT *pDCxt = NULL; + SOCK_OTA_READ_OTA_AREA_T sock_ota_read; + int index = GLOBAL_SOCK_INDEX; + + pDCxt = GET_DRIVER_COMMON(pCxt); + // Check if socket is blocked for a previous command + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + return A_ERROR; + } + A_MEMZERO(&sock_ota_read, sizeof(SOCK_OTA_READ_OTA_AREA_T)); + sock_ota_read.offset = offset; + sock_ota_read.size = size; + + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_OTA_READ); + + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_OTA_READ, (void *)(&sock_ota_read), sizeof(SOCK_OTA_READ_OTA_AREA_T)) != + A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_OTA_READ); + return A_ERROR; + } + + do + { + if (BLOCK(pCxt, ath_sock_context[index], COMMAND_BLOCK_TIMEOUT, RX_DIRECTION) != A_OK) + { + return A_ERROR; + } + } while (SOCK_EV_MASK_TEST(ath_sock_context[index], SOCK_OTA_READ)); + + // resp->resp_code=((tOtaReadResp*)(ath_sock_context[index]->data))->resp_code; + *ret_len = ((tOtaReadResp *)(ath_sock_context[index]->data))->size; + + A_MEMCPY(buffer, (void*)&((tOtaReadResp *)(ath_sock_context[index]->data))->data, *ret_len); + + A_NETBUF_FREE(ath_sock_context[index]->pReq); + + return A_OK; +} +/*****************************************************************************/ +/* Api_ota_done - API to send OTA Complete event to target + * void *pCxt- driver context + * Returns- 0 in case of successful OTA , A_ERROR otherwise + *****************************************************************************/ +int32_t Api_ota_done(void *pCxt, boolean good_image) +{ + A_DRIVER_CONTEXT *pDCxt = NULL; + SOCK_OTA_DONE_T sock_ota_done; + int index = GLOBAL_SOCK_INDEX; + + pDCxt = GET_DRIVER_COMMON(pCxt); + // Check if socket is blocked for a previous command + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + return A_ERROR; + } + A_MEMZERO(&sock_ota_done, sizeof(SOCK_OTA_DONE_T)); + sock_ota_done.data = good_image; + + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_OTA_DONE); + + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_OTA_DONE, (void *)(&sock_ota_done), sizeof(SOCK_OTA_DONE_T)) != A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_OTA_DONE); + return A_ERROR; + } + + do + { + if (BLOCK(pCxt, ath_sock_context[index], COMMAND_BLOCK_TIMEOUT, RX_DIRECTION) != A_OK) + { + return A_ERROR; + } + } while (SOCK_EV_MASK_TEST(ath_sock_context[index], SOCK_OTA_DONE)); + + // A_MEMCPY(resp, ath_sock_context[index]->data, sizeof(tOtaDoneResp)); + + A_NETBUF_FREE(ath_sock_context[index]->pReq); + + return A_OK; +} + +/*****************************************************************************/ +/* Api_ota_session_start - API to send OTA Session Start command to target + * A_VOID *pCxt- driver context + * Returns- 0 in case of successful OTA , A_ERROR otherwise + *****************************************************************************/ +int32_t Api_ota_session_start(void *pCxt, uint32_t flags, uint32_t partition_index) +{ + A_DRIVER_CONTEXT *pDCxt = NULL; + SOCK_OTA_SESSION_START_T ota_cmd; + int index = GLOBAL_SOCK_INDEX; + int32_t res = A_OK; + pDCxt = GET_DRIVER_COMMON(pCxt); + // Check if socket is blocked for a previous command + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + return A_ERROR; + } + A_MEMZERO(&ota_cmd, sizeof(ota_cmd)); + ota_cmd.flags = flags; + ota_cmd.partition_index = partition_index; + + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_OTA_SESSION_START); + + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_OTA_SESSION_START, (void *)(&ota_cmd), sizeof(ota_cmd)) != A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_OTA_SESSION_START); + return A_ERROR; + } + + do + { + if (BLOCK(pCxt, ath_sock_context[index], COMMAND_BLOCK_TIMEOUT, RX_DIRECTION) != A_OK) + { + return A_ERROR; + } + } while (SOCK_EV_MASK_TEST(ath_sock_context[index], SOCK_OTA_SESSION_START)); + res = ((tOtaResp *)(ath_sock_context[index]->data))->resp_code; + A_NETBUF_FREE(ath_sock_context[index]->pReq); + + return res; +} + +/*****************************************************************************/ +/* Api_ota_partition_get_size - API to send OTA Partition Get Size command to target + * A_VOID *pCxt- driver context + * Returns- partition size in case of successful OTA , 0 otherwise + *****************************************************************************/ +uint32_t Api_ota_partition_get_size(void *pCxt) +{ + A_DRIVER_CONTEXT *pDCxt = NULL; + struct sock_ota_cmd_s + { + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + uint8_t data[1]; + } POSTPACK ota_cmd; + int index = GLOBAL_SOCK_INDEX; + int32_t res; + + pDCxt = GET_DRIVER_COMMON(pCxt); + // Check if socket is blocked for a previous command + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + return 0; + } + A_MEMZERO(&ota_cmd, sizeof(ota_cmd)); + + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_OTA_PARTITION_GET_SIZE); + + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_OTA_PARTITION_GET_SIZE, (void *)(&ota_cmd), sizeof(ota_cmd)) != A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_OTA_PARTITION_GET_SIZE); + return 0; + } + + do + { + if (BLOCK(pCxt, ath_sock_context[index], COMMAND_BLOCK_TIMEOUT, RX_DIRECTION) != A_OK) + { + return 0; + } + } while (SOCK_EV_MASK_TEST(ath_sock_context[index], SOCK_OTA_PARTITION_GET_SIZE)); + + res = ((tOtaPartitionGetSizeResp *)(ath_sock_context[index]->data))->size; + A_NETBUF_FREE(ath_sock_context[index]->pReq); + + return res; +} + +/*****************************************************************************/ +/* Api_ota_partition_erase - API to send OTA Partition Erase command to target + * A_VOID *pCxt- driver context + * Returns- 0 in case of successful OTA , A_ERROR otherwise + *****************************************************************************/ +int32_t Api_ota_partition_erase(void *pCxt) +{ + A_DRIVER_CONTEXT *pDCxt = NULL; + struct sock_ota_cmd_s + { + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + uint8_t data[1]; + } POSTPACK ota_cmd; + int index = GLOBAL_SOCK_INDEX; + int32_t res; + + pDCxt = GET_DRIVER_COMMON(pCxt); + // Check if socket is blocked for a previous command + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + return A_ERROR; + } + A_MEMZERO(&ota_cmd, sizeof(ota_cmd)); + + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_OTA_PARTITION_ERASE); + + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_OTA_PARTITION_ERASE, (void *)(&ota_cmd), sizeof(ota_cmd)) != A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_OTA_PARTITION_ERASE); + return A_ERROR; + } + + do + { + if (BLOCK(pCxt, ath_sock_context[index], COMMAND_BLOCK_TIMEOUT, RX_DIRECTION) != A_OK) + { + return A_ERROR; + } + } while (SOCK_EV_MASK_TEST(ath_sock_context[index], SOCK_OTA_PARTITION_ERASE)); + + res = ((tOtaResp *)(ath_sock_context[index]->data))->resp_code; + A_NETBUF_FREE(ath_sock_context[index]->pReq); + + return res; +} + +/*****************************************************************************/ +/* Api_ota_partition_verify_checksum - API to send OTA Partition Verify Checksum command to target + * A_VOID *pCxt- driver context + * Returns- 0 in case of successful OTA , A_ERROR otherwise + *****************************************************************************/ +int32_t Api_ota_partition_verify_checksum(void *pCxt) +{ + A_DRIVER_CONTEXT *pDCxt = NULL; + struct sock_ota_cmd_s + { + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + uint8_t data[1]; + } POSTPACK ota_cmd; + int index = GLOBAL_SOCK_INDEX; + int32_t res; + + pDCxt = GET_DRIVER_COMMON(pCxt); + // Check if socket is blocked for a previous command + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + return A_ERROR; + } + A_MEMZERO(&ota_cmd, sizeof(ota_cmd)); + + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_OTA_PARTITION_VERIFY_CHECKSUM); + + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_OTA_PARTITION_VERIFY_CHECKSUM, (void *)(&ota_cmd), sizeof(ota_cmd)) != A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_OTA_PARTITION_VERIFY_CHECKSUM); + return A_ERROR; + } + + do + { + if (BLOCK(pCxt, ath_sock_context[index], COMMAND_BLOCK_TIMEOUT, RX_DIRECTION) != A_OK) + { + return A_ERROR; + } + } while (SOCK_EV_MASK_TEST(ath_sock_context[index], SOCK_OTA_PARTITION_VERIFY_CHECKSUM)); + + res = ((tOtaResp *)(ath_sock_context[index]->data))->resp_code; + A_NETBUF_FREE(ath_sock_context[index]->pReq); + + return res; +} + +/*****************************************************************************/ +/* Api_ota_parse_image_hdr - API to send OTA Parse Image Header command to target + * A_VOID *pCxt- driver context + * Returns- 0 in case of successful OTA , A_ERROR otherwise + *****************************************************************************/ +int32_t Api_ota_parse_image_hdr(void *pCxt, uint8_t *header, uint32_t *offset) +{ + A_DRIVER_CONTEXT *pDCxt = NULL; + SOCK_OTA_PARSE_IMAGE_HDR_T ota_cmd; + int index = GLOBAL_SOCK_INDEX; + int32_t res; + + pDCxt = GET_DRIVER_COMMON(pCxt); + // Check if socket is blocked for a previous command + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + return A_ERROR; + } + A_MEMZERO(&ota_cmd, sizeof(ota_cmd)); + A_MEMCPY(ota_cmd.header, header, 24); // copy ota image header + + if (GET_DRIVER_CXT(pCxt)->otaCB != NULL) // non blocking */ + { + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_OTA_PARSE_IMAGE_HDR, (void *)(&ota_cmd), sizeof(ota_cmd)) != A_OK) + { + return A_ERROR; + } + else + { + return A_PENDING; + } + } + else + { + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_OTA_PARSE_IMAGE_HDR); + + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_OTA_PARSE_IMAGE_HDR, (void *)(&ota_cmd), sizeof(ota_cmd)) != A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_OTA_PARSE_IMAGE_HDR); + return A_ERROR; + } + + do + { + if (BLOCK(pCxt, ath_sock_context[index], COMMAND_BLOCK_TIMEOUT, RX_DIRECTION) != A_OK) + { + return A_ERROR; + } + } while (SOCK_EV_MASK_TEST(ath_sock_context[index], SOCK_OTA_PARSE_IMAGE_HDR)); + + *offset = ((tOtaParseImageHdrResp *)(ath_sock_context[index]->data))->offset; + res = ((tOtaParseImageHdrResp *)(ath_sock_context[index]->data))->resp_code; + A_NETBUF_FREE(ath_sock_context[index]->pReq); + } + return res; +} + +/*****************************************************************************/ +/* Api_ota_partition_write_data - API to send OTA Partition Write Data command to target + * A_VOID *pCxt- driver context + * Returns- 0 in case of successful OTA , A_ERROR otherwise + *****************************************************************************/ +int32_t Api_ota_partition_write_data(void *pCxt, uint32_t offset, uint8_t *buf, uint32_t buf_size, uint32_t *ret_size) +{ + A_DRIVER_CONTEXT *pDCxt = NULL; + SOCK_OTA_PARTITON_WRITE_DATA_T *ota_cmd = NULL; + int index = GLOBAL_SOCK_INDEX; + int32_t res = QCOM_OTA_ERR_WRITE_DATA_ERROR; + uint32_t cmd_len; + + pDCxt = GET_DRIVER_COMMON(pCxt); + // Check if socket is blocked for a previous command + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + goto ota_error; + } + + *ret_size = 0; + if (buf_size == 0) + return QCOM_OTA_OK; + if ((buf == NULL) || (buf_size > MAX_OTA_AREA_READ_SIZE)) + return QCOM_OTA_ERR_WRITE_DATA_ERROR; + + cmd_len = sizeof(SOCK_OTA_PARTITON_WRITE_DATA_T) + buf_size - 1; + + ota_cmd = A_MALLOC(cmd_len, MALLOC_ID_CONTEXT); + if (ota_cmd == NULL) + { + return A_NO_MEMORY; + } + + A_MEMZERO(ota_cmd, cmd_len); + A_MEMCPY(ota_cmd->data, buf, buf_size); + ota_cmd->offset = offset; + ota_cmd->size = buf_size; + + if (GET_DRIVER_CXT(pCxt)->otaCB != NULL) // non blocking */ + { + if ((res = wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_OTA_PARTITION_WRITE_DATA, (void *)(ota_cmd), cmd_len)) != A_OK) + { + goto ota_error; + } + else + { + res = A_PENDING; + } + } + else + { + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_OTA_PARTITION_WRITE_DATA); + + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_OTA_PARTITION_WRITE_DATA, (void *)(ota_cmd), cmd_len) != A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_OTA_PARTITION_WRITE_DATA); + goto ota_error; + } + + do + { + if (BLOCK(pCxt, ath_sock_context[index], COMMAND_BLOCK_TIMEOUT, RX_DIRECTION) != A_OK) + { + goto ota_error; + } + } while (SOCK_EV_MASK_TEST(ath_sock_context[index], SOCK_OTA_PARTITION_WRITE_DATA)); + + *ret_size = ((tOtaPartitionWriteDataResp *)(ath_sock_context[index]->data))->size; + res = ((tOtaPartitionWriteDataResp *)(ath_sock_context[index]->data))->resp_code; + A_NETBUF_FREE(ath_sock_context[index]->pReq); + } +ota_error: + if (ota_cmd != NULL) + A_FREE(ota_cmd, MALLOC_ID_CONTEXT); + return res; +} + +/*****************************************************************************/ +/* Api_ping - API to obtain IP address information from target + * void *pCxt- driver context + * uint32_t* ipv4_addr + * Returns- 0 in case of successful connect, A_ERROR otherwise + *****************************************************************************/ +int32_t Api_ping(void *pCxt, uint32_t ipv4_addr, uint32_t size) +{ + A_DRIVER_CONTEXT *pDCxt; + PING_T ping; + uint32_t index = GLOBAL_SOCK_INDEX; // reserved for global commands ToDo- cleanup later + int32_t result = A_OK; + + pDCxt = GET_DRIVER_COMMON(pCxt); + + do + { + /*Check if socket is blocked for a previous command*/ + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + result = A_ERROR; + break; + } + ping.ip_addr = A_CPU2LE32(ipv4_addr); + ping.size = A_CPU2LE32(size); + + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_PING); + + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_PING, (void *)(&ping), sizeof(PING_T)) != A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_PING); + result = A_ERROR; + break; + } + + do + { + if (BLOCK(pCxt, ath_sock_context[index], COMMAND_BLOCK_TIMEOUT, RX_DIRECTION) != A_OK) + { + A_ASSERT(0); + } + + } while (SOCK_EV_MASK_TEST(ath_sock_context[index], SOCK_PING)); + result = ath_sock_context[index]->result; + } while (0); + + return result; +} + +/*****************************************************************************/ +/* Api_ping6 - API to obtain IP address information from target + * void *pCxt- driver context + * uint32_t* ipv4_addr + * Returns- 0 in case of successful connect, A_ERROR otherwise + *****************************************************************************/ +int32_t Api_ping6(void *pCxt, uint8_t *ip6addr, uint32_t size) +{ + A_DRIVER_CONTEXT *pDCxt; + PING_6_T ping6; + uint32_t index = GLOBAL_SOCK_INDEX; // reserved for global commands ToDo- cleanup later + int32_t result = A_OK; + + pDCxt = GET_DRIVER_COMMON(pCxt); + + do + { + /*Check if socket is blocked for a previous command*/ + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + result = A_ERROR; + break; + } + A_MEMCPY(ping6.ip6addr, ip6addr, sizeof(ping6.ip6addr)); + ping6.size = A_CPU2LE32(size); + + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_PING6); + + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_PING6, (void *)(&ping6), sizeof(PING_6_T)) != A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_PING6); + result = A_ERROR; + break; + } + + do + { + if (BLOCK(pCxt, ath_sock_context[index], COMMAND_BLOCK_TIMEOUT, RX_DIRECTION) != A_OK) + { + A_ASSERT(0); + } + } while (SOCK_EV_MASK_TEST(ath_sock_context[index], SOCK_PING6)); + result = ath_sock_context[index]->result; + } while (0); + + return result; +} + +/*****************************************************************************/ +/* clear_socket_context - clears all elements of socket context + * int32_t - index to socket context + * Returns- None + *****************************************************************************/ +void clear_socket_context(int32_t index) +{ + ath_sock_context[index]->handle = 0; + ath_sock_context[index]->domain = 0; + ath_sock_context[index]->type = 0; + ath_sock_context[index]->TCPCtrFlag = 0; + A_MEMZERO(&ath_sock_context[index]->sock_st_mask[0], sizeof(ath_sock_context[index]->sock_st_mask)); + + /* Free remaining data when socket is closed */ + if (ath_sock_context[index]->old_netbuf != NULL) + { + A_NETBUF_FREE(ath_sock_context[index]->old_netbuf); + ath_sock_context[index]->old_netbuf = NULL; + } + ath_sock_context[index]->remaining_bytes = 0; + + /*If for some reason, data field is not freed, free it here + This may happen when a command response comes later than Timeout period*/ + if (ath_sock_context[index]->data) + { + QCADRV_PRINTF("%s index:%d data:%p\n", __func__, index, ath_sock_context[index]->data); + A_FREE(ath_sock_context[index]->data, MALLOC_ID_CONTEXT); + ath_sock_context[index]->data = NULL; + } +} + +/*****************************************************************************/ +/* send_stack_init - Sends Stack initialization information. + * RETURNS: A_OK on success A_ERROR otherwise + *****************************************************************************/ +A_STATUS send_stack_init(void *pCxt) +{ + A_DRIVER_CONTEXT *pDCxt; + uint8_t buffer[sizeof(WMI_SOCKET_CMD) + 4]; + WMI_SOCKET_CMD *sock_cmd = (WMI_SOCKET_CMD *)&buffer[0]; + pDCxt = GET_DRIVER_COMMON(pCxt); + + buffer[8] = 1; + buffer[9] = 2; + buffer[10] = MAX_SOCKETS_SUPPORTED; + + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_STACK_INIT, (void *)(sock_cmd), sizeof(WMI_SOCKET_CMD) + 4) != A_OK) + { + return A_ERROR; + } + +#if ENABLE_SSL + sslhandle = (GET_DRIVER_CXT(pCxt)->pUpperCxt[0]); +#endif + + return A_OK; +} + +enum +{ + /* Least priority since we dont allow any operation during store-recall */ + POWER_STATE_MOVED_FOR_STRRCL = 1, + /* IPDHCP will happen only after the network connection usually */ + POWER_STATE_MOVED_FOR_IPDHCP, + POWER_STATE_MOVED_FOR_TCPRX +}; + +int32_t power_state_for_module = 0; +/*****************************************************************************/ +/* move_to_maxperf - Changes the power mode to max perf in firmware. There are + * some commands which need to run in MAX_PERF mode like store_recall etc + * This function changes the power modeto MAX_PERF and will not + * intimate the application. Later after the command succeeds, + * use restore_power_state to change to original power state + * Note: Application should not directly use this function + * int32_t - module which request the change + * Returns- A_OK on success, A_ERROR otherwise + *****************************************************************************/ +A_STATUS move_power_state_to_maxperf(void *pCxt, int32_t module) +{ + A_DRIVER_CONTEXT *pDCxt = (A_DRIVER_CONTEXT *)pCxt; + + /* Already some HIGH module changes state */ + if (power_state_for_module >= module) + { + return A_OK; + } + + /* Change the power mode only when the current power mode is REC_POWER */ + if (pDCxt->userPwrMode == REC_POWER) + { + if (A_OK != wmi_cmd_start(pDCxt->pWmiCxt, &max_performance_power_param, WMI_SET_POWER_MODE_CMDID, + sizeof(WMI_POWER_MODE_CMD))) + { + return A_ERROR; + } + } + power_state_for_module = module; + return A_OK; +} +/*****************************************************************************/ +/* restore_power_state - Restores the original power state, which is changed by + * "move_power_state_to_maxperf" + * int32_t - module which request the change + * RETURNS: A_OK on success A_ERROR otherwise + *****************************************************************************/ +A_STATUS restore_power_state(void *pCxt, int32_t module) +{ + A_DRIVER_CONTEXT *pDCxt = (A_DRIVER_CONTEXT *)pCxt; + + /* Already some HIGH priority module changes state, + * so don't change the state now */ + if (!power_state_for_module || (power_state_for_module > module)) + { + return A_OK; + } + if (pDCxt->userPwrMode != max_performance_power_param) + { + if (A_OK != + wmi_cmd_start(pDCxt->pWmiCxt, &pDCxt->userPwrMode, WMI_SET_POWER_MODE_CMDID, sizeof(WMI_POWER_MODE_CMD))) + { + return A_ERROR; + } + } + + power_state_for_module = 0; + return A_OK; +} +#if ENABLE_SSL +/*****************************************************************************/ +/* SSL_ctx_new - Create new SSL context. This function must be called before + * using any other SSL functions. It needs to be called as either + * server or client + * Sslrole role - 1 = server, 2 = client + * int32_t inbufSize - initial inBuf size: Can grow + * int32_t outbufSize - outBuf size: Fixed + * int32_t reserved - currently not used (must be zero) + * Returns - SSL context handle on success or NULL on error (out of memory) + *****************************************************************************/ +SSL_CTX *Api_SSL_ctx_new(void *pCxt, SSL_ROLE_T role, int32_t inbufSize, int32_t outbufSize, int32_t reserved) +{ + SOCK_SSL_CTX_NEW_T cmd; + SSL_CTX *result = NULL; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + int32_t index = GLOBAL_SOCK_INDEX; + + do + { + /*Check if socket is blocked for a previous command*/ + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + break; + } + + /* Send command and wait for response */ + cmd.role = role; + cmd.inbufSize = inbufSize; + cmd.outbufSize = outbufSize; + cmd.reserved = reserved; + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_SSL_CTX_NEW); + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_SSL_CTX_NEW, (void *)(&cmd), sizeof(cmd)) != A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_SSL_CTX_NEW); + break; + } + do + { + if (BLOCK(pCxt, ath_sock_context[index], COMMAND_BLOCK_TIMEOUT, RX_DIRECTION) != A_OK) + { + A_ASSERT(0); + } + } while (SOCK_EV_MASK_TEST(ath_sock_context[index], SOCK_SSL_CTX_NEW)); + result = (SSL_CTX *)ath_sock_context[GLOBAL_SOCK_INDEX]->result; + } while (0); + + return result; +} + +/*****************************************************************************/ +/* SSL_ctx_free - Free the SSL context + * SSL_CTX *ctx - sslContext + *****************************************************************************/ +int32_t Api_SSL_ctx_free(void *pCxt, SSL_CTX *ctx) +{ + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + SOCK_SSL_CTX_FREE_T cmd; + int32_t result = A_OK; + int32_t index = GLOBAL_SOCK_INDEX; + + do + { + /*Check if socket is blocked for a previous command*/ + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + result = A_ERROR; + break; + } + + /* Send command and wait for response */ + cmd.ctx = (uint32_t)ctx; + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_SSL_CTX_FREE); + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_SSL_CTX_FREE, (void *)(&cmd), sizeof(cmd)) != A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_SSL_CTX_FREE); + result = A_ERROR; + break; + } + do + { + if (BLOCK(pCxt, ath_sock_context[index], COMMAND_BLOCK_TIMEOUT, RX_DIRECTION) != A_OK) + { + A_ASSERT(0); + } + } while (SOCK_EV_MASK_TEST(ath_sock_context[index], SOCK_SSL_CTX_FREE)); + result = ath_sock_context[GLOBAL_SOCK_INDEX]->result; + } while (0); + + return result; +} + +/*****************************************************************************/ +/* SSL_new - Create SSL connection object. When SSL transaction is done, close + * it with ssl_shutdown(). + * Note that the socket should subsequently also be closed. + * SSL_CTX *ctx - sslContext + * Return - SSL object handle on success or NULL on error (out of memory) + *****************************************************************************/ +SSL *Api_SSL_new(void *pCxt, SSL_CTX *ctx) +{ + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + SOCK_SSL_NEW_T cmd; + SSL *result = NULL; + int32_t index = GLOBAL_SOCK_INDEX; + + do + { + /*Check if socket is blocked for a previous command*/ + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + break; + } + + /* Send command and wait for response */ + cmd.ctx = (uint32_t)ctx; + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_SSL_NEW); + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_SSL_NEW, (void *)(&cmd), sizeof(cmd)) != A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_SSL_NEW); + break; + } + do + { + if (BLOCK(pCxt, ath_sock_context[index], COMMAND_BLOCK_TIMEOUT, RX_DIRECTION) != A_OK) + { + A_ASSERT(0); + } + } while (SOCK_EV_MASK_TEST(ath_sock_context[index], SOCK_SSL_NEW)); + result = (SSL *)ath_sock_context[index]->result; + } while (0); + + return result; +} + +/*****************************************************************************/ +/* SSL_set_fd - Attach given socket descriptor to the SSL connection + * SSL *ssl - SSL connection + * uint32_t fd - Socket descriptor + * Return - 1 on success or negative error code on error (see SslErrors) + *****************************************************************************/ +int32_t Api_SSL_set_fd(void *pCxt, SSL *ssl, uint32_t fd) +{ + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + SOCK_SSL_SET_FD_T cmd; + int32_t result = A_OK; + int32_t index; + + do + { + /* Find the socket */ + index = find_socket_context(fd, true); + if (index == SOCKET_NOT_FOUND) + { + return A_ERROR; + } + + /* Check if socket is blocked for a previous command */ + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + return A_ERROR; + } + + /* Store the ssl object pointer in the socket struct */ + ath_sock_context[index]->ssl = ssl; + + /* Send command and wait for response */ + cmd.ssl = (uint32_t)ssl; + cmd.fd = fd; + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_SSL_SET_FD); + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_SSL_SET_FD, (void *)(&cmd), sizeof(cmd)) != A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_SSL_SET_FD); + result = A_ERROR; + break; + } + do + { + if (BLOCK(pCxt, ath_sock_context[index], COMMAND_BLOCK_TIMEOUT, RX_DIRECTION) != A_OK) + { + A_ASSERT(0); + } + } while (SOCK_EV_MASK_TEST(ath_sock_context[index], SOCK_SSL_SET_FD)); + result = ath_sock_context[index]->result; + } while (0); + + if (result < 0) + { + /* remove the ssl pointer again if the cmd failed */ + ath_sock_context[index]->ssl = NULL; + } + + return result; +} + +/*****************************************************************************/ +/* SSL_accept - Initiate SSL handshake. + * SSL *ssl - SSL connection + * Returns - 1 on success, ESSL_HSDONE if handshake has already been performed. + * Negative error code otherwise. + *****************************************************************************/ +int32_t Api_SSL_accept(void *pCxt, SSL *ssl) +{ + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + SOCK_SSL_ACCEPT_T cmd; + int32_t result = A_OK; + int32_t index; + + do + { + /* Find the socket used with this SSL connection */ + index = find_socket_context_from_ssl(ssl); + if (index == SOCKET_NOT_FOUND) + { + result = A_ERROR; + break; + } + + /* Check if socket is blocked for a previous command */ + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + result = A_ERROR; + break; + } + + /* Send command and wait for response */ + cmd.ssl = (uint32_t)ssl; + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_SSL_ACCEPT); + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_SSL_ACCEPT, (void *)(&cmd), sizeof(cmd)) != A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_SSL_ACCEPT); + result = A_ERROR; + break; + } + do + { + if (BLOCK(pCxt, ath_sock_context[index], COMMAND_BLOCK_TIMEOUT, RX_DIRECTION) != A_OK) + { + A_ASSERT(0); + } + } while (SOCK_EV_MASK_TEST(ath_sock_context[index], SOCK_SSL_ACCEPT)); + result = ath_sock_context[index]->result; + } while (0); + + return result; +} + +/*****************************************************************************/ +/* SSL_connect - Initiate SSL handshake. + * SSL *ssl - SSL connection + * Returns - 1 on success, ESSL_HSDONE if handshake has already been performed. + * Negative error code otherwise. + *****************************************************************************/ +int32_t Api_SSL_connect(void *pCxt, SSL *ssl) +{ + A_DRIVER_CONTEXT *pDCxt; + SOCK_SSL_ACCEPT_T cmd; + int32_t result = A_OK; + int32_t index; + + pDCxt = GET_DRIVER_COMMON(pCxt); + do + { + index = find_socket_context_from_ssl(ssl); + if (index == SOCKET_NOT_FOUND) + { + result = A_ERROR; + break; + } + + /* Check if socket is blocked for a previous command */ + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + result = A_ERROR; + break; + } + + /* Send command and wait for response */ + cmd.ssl = (uint32_t)ssl; + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_SSL_CONNECT); + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_SSL_CONNECT, (void *)(&cmd), sizeof(cmd)) != A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_SSL_CONNECT); + result = A_ERROR; + break; + } + do + { + if (BLOCK(pCxt, ath_sock_context[index], COMMAND_BLOCK_TIMEOUT, RX_DIRECTION) != A_OK) + { + A_ASSERT(0); + } + } while (SOCK_EV_MASK_TEST(ath_sock_context[index], SOCK_SSL_CONNECT)); + result = ath_sock_context[index]->result; + } while (0); + + return result; +} + +/*****************************************************************************/ +/* SSL_shutdown - Close SSL connection. + * The socket must be closed by other means. + * SSL *ssl - SSL connection + * Returns - 1 on success or negative error code on error (see SslErrors) + *****************************************************************************/ +int32_t Api_SSL_shutdown(void *pCxt, SSL *ssl) +{ + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + ; + SOCK_SSL_SHUTDOWN_T cmd; + int32_t result = A_OK; + int32_t index = find_socket_context_from_ssl(ssl); + + if (index == SOCKET_NOT_FOUND) + { + /* We send the shutdown command on the "global socket" if the socket used for + the SSL is disconnected/closed before the SSL connection is shutdown. */ + index = GLOBAL_SOCK_INDEX; + } + do + { + /* Check if socket is blocked for a previous command */ + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + result = A_ERROR; + break; + } + + /* Send command and wait for response */ + cmd.ssl = (uint32_t)ssl; + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_SSL_SHUTDOWN); + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_SSL_SHUTDOWN, (void *)(&cmd), sizeof(cmd)) != A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_SSL_SHUTDOWN); + result = A_ERROR; + break; + } + do + { + if (BLOCK(pCxt, ath_sock_context[index], COMMAND_BLOCK_TIMEOUT, RX_DIRECTION) != A_OK) + { + A_ASSERT(0); + } + } while (SOCK_EV_MASK_TEST(ath_sock_context[index], SOCK_SSL_SHUTDOWN)); + result = ath_sock_context[index]->result; + + /* clear the SSL object ptr in the socket struct */ + ath_sock_context[index]->ssl = NULL; + } while (0); + + return result; +} + +int32_t Api_SSL_configure(void *pCxt, SSL *ssl, SSL_CONFIG *cfg) +{ + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + ; + SOCK_SSL_CONFIGURE_T cmd; + int32_t result = A_OK; + int32_t index = find_socket_context_from_ssl(ssl); + + if (index == SOCKET_NOT_FOUND) + { + /* We send the configure command on the "global socket" if the configure is + * done before the socket is created */ + index = GLOBAL_SOCK_INDEX; + } + do + { + /* Check if socket is blocked for a previous command */ + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + result = A_ERROR; + break; + } + + /* Send command and wait for response */ + cmd.ssl = (uint32_t)ssl; + cmd.size = sizeof(SSL_CONFIG); + memcpy(cmd.data, cfg, sizeof(SSL_CONFIG)); + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_SSL_CONFIGURE); + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_SSL_CONFIGURE, (void *)(&cmd), sizeof(cmd)) != A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_SSL_CONFIGURE); + result = A_ERROR; + break; + } + do + { + if (BLOCK(pCxt, ath_sock_context[index], COMMAND_BLOCK_TIMEOUT, RX_DIRECTION) != A_OK) + { + A_ASSERT(0); + } + } while (SOCK_EV_MASK_TEST(ath_sock_context[index], SOCK_SSL_CONFIGURE)); + result = ath_sock_context[index]->result; + } while (0); + + return result; +} + +/*****************************************************************************/ +/* SSL_addCert - Add a certificate or Certificate Authority (CA) list to the + * SharkSsl object. + * A SharkSsl object in server mode is required to have at least + * one certificate. + * You can only set one CA list, thus the CA list must include + * all root certificates required for the session. + * SSL *ssl - SSL connection + * SslCert cert -address of array of binary data + * uint32_t size - size of array + * SSL_CERT_TYPE_T type - certificate or CA list + * Returns - 1 on success or negative error code on error (see SslErrors) + *****************************************************************************/ +int32_t Api_SSL_addCert(void *pCxt, SSL_CTX *ctx, SSL_CERT_TYPE_T type, uint8_t *cert, uint32_t size) +{ + A_DRIVER_CONTEXT *pDCxt; + SOCK_SSL_ADD_CERT_T *pCmd; + int32_t result = A_OK; + uint32_t n, buffSize, offset = 0; + void *pBuff; + int index = GLOBAL_SOCK_INDEX; + uint8_t *data = (uint8_t *)cert; + + pDCxt = GET_DRIVER_COMMON(pCxt); + do + { + /* Check if socket is blocked for a previous command */ + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + result = A_ERROR; + break; + } + + do + { + n = size - offset; + if (n > MAX_CERT_DATA_LENGTH) + { + n = MAX_CERT_DATA_LENGTH; + } + buffSize = sizeof(SOCK_SSL_ADD_CERT_T) + n - 1; + pBuff = A_NETBUF_ALLOC(buffSize); + if (pBuff) + { + /* reserve the necessary space in the buffer */ + A_NETBUF_PUT(pBuff, buffSize); + + pCmd = A_NETBUF_DATA(pBuff); + pCmd->wmi_cmd.cmd_type = SOCK_SSL_ADD_CERT; + pCmd->wmi_cmd.length = buffSize - sizeof(WMI_SOCKET_CMD); + pCmd->ctx = (uint32_t)ctx; + pCmd->type = type; + pCmd->total = size; + pCmd->offset = offset; + pCmd->size = n; + A_MEMCPY(pCmd->data, &data[offset], n); + offset += n; + + /* send the buffer to the wifi device */ + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_SSL_ADD_CERT); + result = wmi_cmd_send(pDCxt->pWmiCxt, pBuff, WMI_SOCKET_CMDID, NO_SYNC_WMIFLAG); + if (result != A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_SSL_ADD_CERT); + return A_ERROR; + } + do + { + if (BLOCK(pCxt, ath_sock_context[index], COMMAND_BLOCK_TIMEOUT, RX_DIRECTION) != A_OK) + { + A_ASSERT(0); + } + } while (SOCK_EV_MASK_TEST(ath_sock_context[index], SOCK_SSL_ADD_CERT)); + result = ath_sock_context[index]->result; + } + } while (offset < size && result >= A_OK); + if (offset != size) + { + result = A_ERROR; + } + } while (0); + + return result; +} + +int32_t Api_SSL_storeCert(void *pCxt, char *name, uint8_t *cert, uint32_t size) +{ + A_DRIVER_CONTEXT *pDCxt; + SOCK_SSL_STORE_CERT_T *pCmd; + int32_t result = A_OK; + uint32_t n, buffSize, offset = 0; + void *pBuff; + int index = GLOBAL_SOCK_INDEX; + uint8_t *data = (uint8_t *)cert; + + pDCxt = GET_DRIVER_COMMON(pCxt); + do + { + /* Check if socket is blocked for a previous command */ + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + result = A_ERROR; + break; + } + + do + { + n = size - offset; + if (n > MAX_CERT_DATA_LENGTH) + { + n = MAX_CERT_DATA_LENGTH; + } + buffSize = sizeof(SOCK_SSL_STORE_CERT_T) + n - 1; + pBuff = A_NETBUF_ALLOC(buffSize); + if (pBuff) + { + /* reserve the necessary space in the buffer */ + A_NETBUF_PUT(pBuff, buffSize); + + pCmd = A_NETBUF_DATA(pBuff); + pCmd->wmi_cmd.cmd_type = SOCK_SSL_STORE_CERT; + pCmd->wmi_cmd.length = buffSize - sizeof(WMI_SOCKET_CMD); + strncpy((char *)pCmd->name, name, SSL_MAX_CERT_NAME_LEN); + pCmd->name[SSL_MAX_CERT_NAME_LEN] = '\0'; + pCmd->total = size; + pCmd->offset = offset; + pCmd->size = n; + A_MEMCPY(pCmd->data, &data[offset], n); + offset += n; + + /* send the buffer to the wifi device */ + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_SSL_STORE_CERT); + result = wmi_cmd_send(pDCxt->pWmiCxt, pBuff, WMI_SOCKET_CMDID, NO_SYNC_WMIFLAG); + if (result != A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_SSL_STORE_CERT); + return A_ERROR; + } + do + { + if (BLOCK(pCxt, ath_sock_context[index], COMMAND_BLOCK_TIMEOUT, RX_DIRECTION) != A_OK) + { + A_ASSERT(0); + } + } while (SOCK_EV_MASK_TEST(ath_sock_context[index], SOCK_SSL_STORE_CERT)); + result = ath_sock_context[index]->result; + } + } while (offset < size && result >= A_OK); + if (offset != size) + { + result = A_ERROR; + } + } while (0); + + return result; +} + +int32_t Api_SSL_loadCert(void *pCxt, SSL_CTX *ctx, SSL_CERT_TYPE_T type, char *name) +{ + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + SOCK_SSL_LOAD_CERT_T cmd; + int32_t result = A_ERROR; + int32_t index = GLOBAL_SOCK_INDEX; + + do + { + /*Check if socket is blocked for a previous command*/ + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + break; + } + + /* Send command and wait for response */ + cmd.ctx = (uint32_t)ctx; + cmd.type = type; + strncpy((char *)cmd.name, name, SSL_MAX_CERT_NAME_LEN); + cmd.name[SSL_MAX_CERT_NAME_LEN] = '\0'; + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_SSL_LOAD_CERT); + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_SSL_LOAD_CERT, (void *)(&cmd), sizeof(cmd)) != A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_SSL_LOAD_CERT); + break; + } + do + { + if (BLOCK(pCxt, ath_sock_context[index], COMMAND_BLOCK_TIMEOUT, RX_DIRECTION) != A_OK) + { + A_ASSERT(0); + } + } while (SOCK_EV_MASK_TEST(ath_sock_context[index], SOCK_SSL_LOAD_CERT)); + result = ath_sock_context[index]->result; + } while (0); + + return result; +} + +int32_t Api_SSL_listCert(void *pCxt, SSL_FILE_NAME_LIST *fileNames) +{ + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + SOCK_SSL_LIST_CERT_T cmd; + int32_t result = A_ERROR; + int32_t index = GLOBAL_SOCK_INDEX; + + do + { + /*Check if socket is blocked for a previous command*/ + if (IS_SOCKET_BLOCKED(ath_sock_context[index])) + { + break; + } + + /* Send command and wait for response */ + SOCK_EV_MASK_SET(ath_sock_context[index], SOCK_SSL_LIST_CERT); + if (wmi_socket_cmd(pDCxt->pWmiCxt, SOCK_SSL_LIST_CERT, (void *)(&cmd), sizeof(cmd)) != A_OK) + { + SOCK_EV_MASK_CLEAR(ath_sock_context[index], SOCK_SSL_LIST_CERT); + break; + } + do + { + if (BLOCK(pCxt, ath_sock_context[index], COMMAND_BLOCK_TIMEOUT, RX_DIRECTION) != A_OK) + { + A_ASSERT(0); + } + } while (SOCK_EV_MASK_TEST(ath_sock_context[index], SOCK_SSL_LIST_CERT)); + result = ath_sock_context[index]->result; + memcpy(fileNames, ath_sock_context[index]->data, sizeof(SSL_FILE_NAME_LIST)); + A_NETBUF_FREE(ath_sock_context[index]->pReq); + } while (0); + + return result; +} + +#endif // ENABLE_SSL + +A_STATUS blockForDataRx(void *pCxt, void *ctxt, uint32_t msec, uint8_t direction) +{ + SOCKET_CONTEXT_PTR pcustctxt = GET_SOCKET_CONTEXT(ctxt); + pcustctxt->respAvailable = false; + return (blockForResponse(pCxt, ctxt, msec, direction)); +} +/*****************************************************************************/ +/* blockForResponse - blocks a thread, either indefinitely or for a specified + * time period in milliseconds + * RETURNS: A_OK on success or error if timeout occurs. + *****************************************************************************/ +A_STATUS blockForResponse(void *pCxt, void *ctxt, uint32_t msec, uint8_t direction) +{ + A_STATUS result = A_OK; + SOCKET_CONTEXT_PTR pcustctxt = GET_SOCKET_CONTEXT(ctxt); + A_EVENT_FLAGS setFlags; + + pcustctxt->blockFlag = 1; + if (msec == 0) + { + msec = 1; + } + + if (direction == RX_DIRECTION) + { + if (pcustctxt->respAvailable == false) + { + pcustctxt->rxBlock = true; + event_t *pEvent = &pcustctxt->sockRxWakeEvent; + A_STATUS res = A_EVENT_WAIT(pEvent, 0x01, false, msec, &setFlags); + if (A_OK != res) + { + result = A_ERROR; + } + else + { + A_EVENT_CLEAR(pEvent, 0x01); + } + pcustctxt->rxBlock = false; + } + else if (pcustctxt->respAvailable == true) + { + /*Response is available, reset the flag for future use*/ + result = A_OK; + pcustctxt->respAvailable = false; + } + else + { + // undefined state + assert(0); + } + } + else if (direction == TX_DIRECTION) + { + if (pcustctxt->txUnblocked == false) + { + pcustctxt->txBlock = true; + event_t *pEvent = &pcustctxt->sockTxWakeEvent; + if (A_OK != A_EVENT_WAIT(pEvent, 0x01, false, msec, &setFlags)) + { + result = A_ERROR; + } + else + { + A_EVENT_CLEAR(pEvent, 0x01); + } + pcustctxt->txBlock = false; + } + + if (pcustctxt->txUnblocked == true) + { + /*Response is available, reset the flag for future use*/ + result = A_OK; + pcustctxt->txUnblocked = false; + } + } + else + { + last_driver_error = A_EINVAL; + } + + pcustctxt->blockFlag = 0; + return result; +} + +#if T_SELECT_VER1 +A_STATUS blockSelect(void *pCxt, uint32_t msec) +{ + A_STATUS result = A_OK; + if (msec == 0) + { + msec = 1; + } + + event_t *pEvent = &GET_DRIVER_CXT(pCxt)->sockSelectWakeEvent; + A_EVENT_FLAGS setFlags; + if (A_OK != A_EVENT_WAIT(pEvent, 0x01, true, msec, &setFlags)) + { + result = A_ERROR; + } + else + { + A_EVENT_CLEAR(pEvent, 0x01); + } + return result; +} +#endif // T_SELECT_VER1 + +/*****************************************************************************/ +/* isSocketBlocked - Checks if a thread is blocked on a given socket + * RETURNS: value of block flag + *****************************************************************************/ +uint32_t isSocketBlocked(void *ctxt) +{ + SOCKET_CONTEXT_PTR pcustctxt = GET_SOCKET_CONTEXT(ctxt); + return pcustctxt->blockFlag; +} + +/*****************************************************************************/ +/* unblock - Unblocks a thread if it is blocked. + * RETURNS: A_OK if unblock was successful, A_ERROR if thread was not blocked + *****************************************************************************/ +A_STATUS unblock(void *ctxt, uint8_t direction) +{ + A_STATUS result = A_OK; + SOCKET_CONTEXT_PTR pcustctxt = GET_SOCKET_CONTEXT(ctxt); + + /*Unblock task if it is blocked*/ + if (direction == RX_DIRECTION) + { + pcustctxt->respAvailable = true; + /*Unblock task if it is blocked*/ + if (pcustctxt->rxBlock == true) + { + A_EVENT_SET(&pcustctxt->sockRxWakeEvent, 0x01); + } + } + else if (direction == TX_DIRECTION) + { + pcustctxt->txUnblocked = true; + if (pcustctxt->txBlock == true) + { + A_EVENT_SET(&pcustctxt->sockTxWakeEvent, 0x01); + } + } + return result; +} + +#if T_SELECT_VER1 +A_STATUS unblockSelect(void *pCxt) +{ + A_STATUS result = A_OK; + A_EVENT_SET(&((GET_DRIVER_CXT(pCxt))->sockSelectWakeEvent), 0x01); + return result; +} +#endif + +#if T_SELECT_VER1 + +#define __FDMASK(d) (((uint32_t)1) << (d)) +#define __FD_SET(d, set) ((*set) |= __FDMASK(d)) +#define __FD_CLR(d, set) ((*set) &= ~__FDMASK(d)) +#define __FD_ISSET(d, set) (((set)&__FDMASK(d)) != 0) +#define __FD_ZERO(set) ((*set) = 0) + +int32_t FD_IsSet(uint32_t handle, uint32_t mask) +{ + int32_t index = 0; + if ((index = find_socket_context(handle, true)) == SOCKET_NOT_FOUND) + { + return 1; + } + return (__FD_ISSET(index, mask)); +} + +int32_t FD_Set(uint32_t handle, uint32_t *mask) +{ + int32_t index = 0; + if ((index = find_socket_context(handle, true)) == SOCKET_NOT_FOUND) + { + return 0; + } + __FD_SET(index, (mask)); + return (A_OK); +} + +int32_t FD_Clr(uint32_t handle, uint32_t *mask) +{ + int32_t index = 0; + if ((index = find_socket_context(handle, true)) == SOCKET_NOT_FOUND) + { + // special case, we are trying to clear the mask for a non-existent socket. + // This is a workaround now. Need to come up with an elegant solution. + // Go through the all the existing sockets and remove the mask elements for which no valid sockets exists. + + *mask &= ((1 << (MAX_SOCKETS_SUPPORTED + 1)) - 1); + for (index = 0; index < MAX_SOCKETS_SUPPORTED; index++) + { + if ((*mask & (1 << index)) && (ath_sock_context[index]->handle == 0)) + { + __FD_CLR(index, (mask)); + } + } + return A_OK; + } + __FD_CLR(index, (mask)); + return (A_OK); +} + +int32_t FD_Zero(uint32_t *mask) +{ + *mask = 0; + return (A_OK); +} + +#endif // T_SELECT_VER1 + +#endif // ENABLE_STACK_OFFLOAD diff --git a/platform/mcu/lpc54102/wifi_qca/common_src/stack_common/common_stack_offload.h b/platform/mcu/lpc54102/wifi_qca/common_src/stack_common/common_stack_offload.h new file mode 100644 index 0000000000..ab0940070f --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/common_src/stack_common/common_stack_offload.h @@ -0,0 +1,898 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== +#ifndef __COMMON_STACK_OFFLOAD_H__ +#define __COMMON_STACK_OFFLOAD_H__ + +#if ENABLE_STACK_OFFLOAD + +#include "atheros_stack_offload.h" + +#define COMMAND_BLOCK_TIMEOUT (960000) // Socket will block for this period in msec, if no +// response is received, socket will unblock +#define TRANSMIT_BLOCK_TIMEOUT (900000) // Time in ms for which a send operation blocks, +// after this time, error is returned to application +#define LAST_FRAGMENT (0x01) // Indicates this is the last fragment +#define RX_DIRECTION (0) +#define TX_DIRECTION (1) +#define TCP_CONNECTION_AVAILABLE (99) // Sent by Target in Listen event that a new TCP +// incoming connection is available. Application +// should call accept on receving this from target. + +/* Wait 1 minute for DHCP response, report error otherwise */ +#ifndef DHCP_WAIT_TIME +#define DHCP_WAIT_TIME (60000) +#endif + +/* Wait 1 second for IPCONFIG response, report error otherwise */ +#ifndef IPCONFIG_WAIT_TIME +#define IPCONFIG_WAIT_TIME (1000) +#endif + +/* Wait 2 minutes for AUTOIP/DHCP response, report error otherwise */ +#ifndef DHCP_AUTO_WAIT_TIME +#define DHCP_AUTO_WAIT_TIME (60000 * 2) +#endif + +#define TCP_MSS 1452 +#if DEBUG +#define DEBUG_PRINT(arg) // User may define +#endif + +#define TCP_FIN 1 +#define TCP_LISTEN 2 + +enum SOCKET_CMDS +{ + SOCK_OPEN = 0, /*Open a socket*/ + SOCK_CLOSE, /*Close existing socket*/ + SOCK_CONNECT, /*Connect to a peer*/ + SOCK_BIND, /*Bind to interface*/ + SOCK_LISTEN, /*Listen on socket*/ + SOCK_ACCEPT, /*Accept incoming connection*/ + SOCK_SELECT, /*Wait for specified file descriptors*/ + SOCK_SETSOCKOPT, /*Set specified socket option*/ + SOCK_GETSOCKOPT, /*Get socket option*/ + SOCK_ERRNO, /*Get error number for last error*/ + SOCK_IPCONFIG, /*Set static IP information, or get current IP config*/ + SOCK_PING, + SOCK_STACK_INIT, /*Command to initialize stack*/ + SOCK_STACK_MISC, /*Used to exchanges miscellaneous info, e.g. reassembly etc*/ + SOCK_PING6, + SOCK_IP6CONFIG, /*Set static IP information, or get current IP config*/ + SOCK_IPCONFIG_DHCP_POOL, /*Set DHCP Pool */ + SOCK_IP6CONFIG_ROUTER_PREFIX, /* Set ipv6 router prefix */ + SOCK_IP_SET_TCP_EXP_BACKOFF_RETRY, /* set tcp exponential backoff retry */ + SOCK_IP_SET_IP6_STATUS, /* set ip6 module status enable/disable */ + SOCK_IP_DHCP_RELEASE, /* Release the DHCP IP Addres */ + SOCK_IP_SET_TCP_RX_BUF, /* set tcp rx buffer space */ + SOCK_HTTP_SERVER, /* Http Server Command*/ + SOCK_HTTP_SERVER_CMD, /* Commands to get and post data */ + SOCK_DNC_CMD, /* Commands related to resolver */ + SOCK_DNC_ENABLE, /* Command to enable/disable DNS Client */ + SOCK_DNS_SRVR_CFG_ADDR, /* Command to configure DNS Server Address */ + SOCK_HTTPC, /* HTTP Client commands */ + SOCK_DNS_LOCAL_DOMAIN, /* Configures the local domain */ + SOCK_IP_HOST_NAME, /* Configures the local host name */ + SOCK_IP_DNS, /* Configures DNS Database */ + SOCK_IP_SNTP_SRVR_ADDR, /* Configures the sntp server addr */ + SOCK_IP_SNTP_GET_TIME, /* GET UTC Time from SNTP Client */ + SOCK_IP_SNTP_GET_TIME_OF_DAY, /* Get time of day (secs)*/ + SOCK_IP_SNTP_CONFIG_TIMEZONE_DSE, /*Command to modify time zone and to enable/disable DSE */ + SOCK_IP_SNTP_QUERY_SNTP_ADDRESS, /* Command to query SNTP Server Address*/ + SOCK_IP_SNTP_CLIENT_ENABLE, /* Command to enable/disable SNTP client */ + SOCK_IPV4_ROUTE, /* Commands to add,del and show IPv4 routes */ + SOCK_IPV6_ROUTE, /* Commands to add,del and show IPv6 routes */ + SOCK_IP_BRIDGEMODE, /* Command to enable bridge mode */ + SOCK_DNS_SERVER_STATUS, /*Command to enable/disable DNS Server*/ + SOCK_SSL_CTX_NEW, /* Create a new SSL context */ + SOCK_SSL_CTX_FREE, /* Free/close SSL context */ + SOCK_SSL_NEW, /* Create new SSL connection object/instance */ + SOCK_SSL_SET_FD, /* Add socket handle to a SSL connection */ + SOCK_SSL_ACCEPT, /* Accept SSL connection request from SSL client */ + SOCK_SSL_CONNECT, /* Establish SSL connection from SSL client to SSL server */ + SOCK_SSL_SHUTDOWN, /* Shutdown/close SSL connection */ + SOCK_SSL_ADD_CERT, /* Add a certificate to SSL context */ + SOCK_SSL_STORE_CERT, /* Store a certificate or CA list file in FLASH */ + SOCK_SSL_LOAD_CERT, /* Reads a certificate or CA list from FLASH and adds it to SSL context */ + SOCK_SSL_CONFIGURE, /* Configure a SSL connection */ + SOCK_SSL_LIST_CERT, /* Request the names of the cert's stored in FLASH */ + SOCK_GET_DEV_ID_FROM_DEST_IP, /* Gets the device ID for the given destination IP address */ + SOCK_OTA_UPGRADE, + /* 54*/ /*Intializes OTA upgrade*/ + SOCK_OTA_READ, + /*55*/ /*Reads OTA Area after OTA download*/ + SOCK_OTA_DONE, + /*56*/ /*OTA download Complete Event*/ + SOCK_SET_DHCP_HOSTNAME, + /*57*/ /*set the DHCP Hostname*/ + SOCK_TCP_CONN_TIMEOUT, + /*58*/ /*TCP Connection Timeout */ + SOCK_HTTP_POST_EVENT, + /*59*/ /*HTTP server post event*/ + SOCK_OTA_SESSION_START, + /*60*/ /*start OTA session */ + SOCK_OTA_PARTITION_GET_SIZE, + /*61*/ /*start OTA session */ + SOCK_OTA_PARTITION_ERASE, + /*62*/ /*start OTA session */ + SOCK_OTA_PARSE_IMAGE_HDR, + /*63*/ /*parse OTA image header */ + SOCK_OTA_PARTITION_VERIFY_CHECKSUM, + /*64*/ /*veirfy OTA partition checksum */ + SOCK_OTA_PARTITION_WRITE_DATA, + /*65*/ /*write OTA partition data */ + SOCK_DHCPS_SUCCESS_CALLBACK, + /*66*/ /*DHCP Server callback event*/ + SOCK_DHCPC_SUCCESS_CALLBACK, + /*66*/ /*DHCP Client callback event*/ + /************************************/ + /* add new socket commands above this line */ + /************************************/ + SOCK_CMD_LAST /* NOTE: ensure that this is the last entry in the enum */ +}; + +/***socket context. This must be adjusted based on the underlying OS ***/ +typedef struct socket_context +{ + A_EVENT sockRxWakeEvent; // Event to unblock waiting RX socket + A_EVENT sockTxWakeEvent; // Event to unblock waiting TX socket + A_NETBUF_QUEUE_T rxqueue; // Queue to hold incoming packets + uint8_t blockFlag; + boolean respAvailable; // Flag to indicate a response from target is available + boolean txUnblocked; + boolean txBlock; + boolean rxBlock; +#if NON_BLOCKING_TX + A_NETBUF_QUEUE_T non_block_queue; // Queue to hold packets to be freed later + A_MUTEX_T nb_tx_mutex; // Mutex to synchronize access to non blocking queue +#endif +} SOCKET_CONTEXT, *SOCKET_CONTEXT_PTR; + +#define GET_SOCKET_CONTEXT(ctxt) ((SOCKET_CONTEXT_PTR)(((ATH_SOCKET_CONTEXT_PTR)ctxt)->sock_context)) + +typedef struct ath_socket_context +{ + int32_t handle; // Socket handle + uint32_t sock_st_mask[SOCK_CMD_LAST / 32 + 1]; + int32_t result; // API return value + void *sock_context; // Pointer to custom socket context + void *pReq; // Used to hold wmi netbuf to be freed from the user thread + uint8_t *data; // Generic pointer to data recevied from target + uint8_t domain; // IPv4/v6 + uint8_t type; // TCP vs UDP + uint16_t remaining_bytes; + void *old_netbuf; +#if ENABLE_SSL + SSL *ssl; // SSL connection object +#endif + uint8_t TCPCtrFlag; +} ATH_SOCKET_CONTEXT, *ATH_SOCKET_CONTEXT_PTR; + +typedef struct ath_sock_stack_init +{ + uint8_t stack_enabled; // Flag to indicate if stack should be enabled in the target + uint8_t num_sockets; // number of sockets supported by the host + uint8_t num_buffers; // Number of RX buffers supported by host + uint8_t reserved; +} ATH_STACK_INIT; + +typedef PREPACK struct sock_open +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + uint32_t domain FIELD_PACKED; // ATH_AF_INET, ATH_AF_INET6 + uint32_t type FIELD_PACKED; // SOCK_STREAM_TYPE, SOCK_DGRAM_TYPE + uint32_t protocol FIELD_PACKED; // 0 +} POSTPACK SOCK_OPEN_T; + +typedef PREPACK struct sock_close +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + uint32_t handle FIELD_PACKED; // socket handle +} POSTPACK SOCK_CLOSE_T; + +typedef PREPACK struct sock_connect_cmd +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + uint32_t handle FIELD_PACKED; // socket handle + PREPACK union + { + SOCKADDR_T name FIELD_PACKED; + SOCKADDR_6_T name6 FIELD_PACKED; + } POSTPACK addr; + uint16_t length FIELD_PACKED; // socket address length +} POSTPACK SOCK_CONNECT_CMD_T, SOCK_BIND_CMD_T, SOCK_ACCEPT_CMD_T; + +typedef PREPACK struct sock_connect_recv +{ + uint32_t handle FIELD_PACKED; // socket handle + PREPACK union + { + SOCKADDR_T name FIELD_PACKED; + SOCKADDR_6_T name6 FIELD_PACKED; + } POSTPACK addr; + uint16_t length FIELD_PACKED; // socket address length +} POSTPACK SOCK_CONNECT_RECV_T, SOCK_BIND_RECV_T, SOCK_ACCEPT_RECV_T; + +typedef PREPACK struct sock_errno +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + uint32_t errno; +} POSTPACK SOCK_ERRNO_T; + +typedef struct sock_listen +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + uint32_t handle FIELD_PACKED; // Socket handle + uint32_t backlog FIELD_PACKED; // Max length of queue of backlog connections +} POSTPACK SOCK_LISTEN_T; + +typedef PREPACK struct sock_setopt +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + uint32_t handle FIELD_PACKED; // socket handle + uint32_t level FIELD_PACKED; // Option level (ATH_IPPROTO_IP, ATH_IPPROTO_UDP, ATH_IPPROTO_TCP...) + uint32_t optname FIELD_PACKED; // Choose from list above + uint32_t optlen FIELD_PACKED; // option of length + uint8_t optval[1] FIELD_PACKED; // option value +} POSTPACK SOCK_OPT_T; + +typedef PREPACK struct ipconfig_recv +{ + uint32_t mode FIELD_PACKED; // 0-query, 1-static, 2-dhcp + uint32_t ipv4 FIELD_PACKED; // IPv4 address + uint32_t subnetMask FIELD_PACKED; + uint32_t gateway4 FIELD_PACKED; + IP6_ADDR_T ipv6LinkAddr FIELD_PACKED; /* IPv6 Link Local address */ + IP6_ADDR_T ipv6GlobalAddr FIELD_PACKED; /* IPv6 Global address */ + IP6_ADDR_T ipv6DefGw FIELD_PACKED; /* IPv6 Default Gateway */ + IP6_ADDR_T ipv6LinkAddrExtd FIELD_PACKED; /* IPv6 Link Local address for Logo*/ + int32_t LinkPrefix FIELD_PACKED; + int32_t GlbPrefix FIELD_PACKED; + int32_t DefGwPrefix FIELD_PACKED; + int32_t GlbPrefixExtd FIELD_PACKED; + IP46ADDR dnsaddr[MAX_DNSADDRS] FIELD_PACKED; + char hostname[33] FIELD_PACKED; +} POSTPACK IPCONFIG_RECV_T; + +typedef PREPACK struct ipconfig +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + uint32_t mode FIELD_PACKED; // 0-query, 1-static, 2-dhcp + uint32_t ipv4 FIELD_PACKED; // IPv4 address + uint32_t subnetMask FIELD_PACKED; + uint32_t gateway4 FIELD_PACKED; + IP6_ADDR_T ipv6LinkAddr FIELD_PACKED; /* IPv6 Link Local address */ + IP6_ADDR_T ipv6GlobalAddr FIELD_PACKED; /* IPv6 Global address */ + IP6_ADDR_T ipv6DefGw FIELD_PACKED; /* IPv6 Default Gateway */ + IP6_ADDR_T ipv6LinkAddrExtd FIELD_PACKED; /* IPv6 Link Local address for Logo*/ + int32_t LinkPrefix; + int32_t GlbPrefix; + int32_t DefGwPrefix; + int32_t GlbPrefixExtd; +} POSTPACK IPCONFIG_CMD_T; + +typedef PREPACK struct ping +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + uint32_t ip_addr FIELD_PACKED; // Destination IPv4 address + uint32_t size FIELD_PACKED; +} POSTPACK PING_T; + +typedef PREPACK struct ping6 +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + uint8_t ip6addr[16] FIELD_PACKED; // Destination IPv6 address + uint32_t size FIELD_PACKED; +} POSTPACK PING_6_T; + +typedef PREPACK struct ipconfigdhcppool +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + uint32_t startaddr FIELD_PACKED; + uint32_t endaddr FIELD_PACKED; + int32_t leasetime FIELD_PACKED; +} POSTPACK IPCONFIG_DHCP_POOL_T; + +typedef PREPACK struct ip6config_router_prefix +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + uint8_t v6addr[16] FIELD_PACKED; + int32_t prefixlen FIELD_PACKED; + int32_t prefix_lifetime FIELD_PACKED; + int32_t valid_lifetime FIELD_PACKED; +} POSTPACK IP6CONFIG_ROUTER_PREFIX_T; + +typedef PREPACK struct sock_ip_backoff +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + int32_t max_retry FIELD_PACKED; +} POSTPACK SOCK_IP_BACKOFF_T; + +typedef PREPACK struct sock_ipv6_status +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + uint16_t ipv6_status FIELD_PACKED; +} POSTPACK SOCK_IPv6_STATUS_T; + +typedef PREPACK struct sock_ip_bridgemode +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + uint16_t bridgemode FIELD_PACKED; +} POSTPACK SOCK_IP_BRIDGEMODE_T; + +typedef PREPACK struct sock_ip_dhcp_release +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + uint16_t ifIndex FIELD_PACKED; +} POSTPACK SOCK_IP_DHCP_RELEASE_T; + +typedef PREPACK struct sock_ip_tcp_rx_buf +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + int32_t rxbuf FIELD_PACKED; +} POSTPACK SOCK_IP_TCP_RX_BUF_T; + +typedef PREPACK struct sock_ip_http_server +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + int32_t enable FIELD_PACKED; +} POSTPACK SOCK_IP_HTTP_SERVER_T; + +typedef PREPACK struct sock_ip_http_server_cmd +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + int32_t command FIELD_PACKED; + uint8_t pagename[32] FIELD_PACKED; + uint8_t objname[32] FIELD_PACKED; + uint32_t objlen FIELD_PACKED; + uint8_t value[32] FIELD_PACKED; +} POSTPACK SOCK_IP_HTTP_SERVER_CMD_T; + +typedef PREPACK struct sock_ip_dns_client +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + int32_t command FIELD_PACKED; +} POSTPACK SOCK_IP_DNS_CLIENT_T; + +typedef PREPACK struct sock_ip_dns_config_server_addr +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + IP46ADDR addr FIELD_PACKED; // Server address +} POSTPACK SOCK_IP_CFG_DNS_SRVR_ADDR; + +typedef PREPACK struct sock_ip_dns_local_domain +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + char domain_name[33] FIELD_PACKED; // Server address +} POSTPACK SOCK_IP_CFG_DNS_LOCAL_DOMAIN; + +typedef PREPACK struct sock_ip_dns_hostname +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + char domain_name[33] FIELD_PACKED; // Server address +} POSTPACK SOCK_IP_CFG_HOST_NAME; + +typedef PREPACK struct sock_ip_dns +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + int32_t command FIELD_PACKED; + char domain_name[36] FIELD_PACKED; // Server address + IP46ADDR addr FIELD_PACKED; +} POSTPACK SOCK_IP_DNS_T; + +typedef PREPACK struct sock_ip_dns_server +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + int32_t enable FIELD_PACKED; +} POSTPACK SOCK_IP_DNS_SERVER_STATUS_T; + +#if ENABLE_HTTP_CLIENT +typedef PREPACK struct httpc_command +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + uint32_t command FIELD_PACKED; + uint8_t url[256] FIELD_PACKED; + uint8_t data[128] FIELD_PACKED; +} POSTPACK SOCK_HTTPC_T; +#endif /* ENABLE_HTTP_CLIENT */ + +typedef PREPACK struct sock_ip_sntp_local_domain +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + int32_t command FIELD_PACKED; + char addr[68] FIELD_PACKED; // Server address +} POSTPACK SOCK_IP_CFG_SNTP_SRVR_ADDR; + +typedef PREPACK struct sock_ip_sntp_zone +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + uint8_t hour FIELD_PACKED; + uint8_t min FIELD_PACKED; + uint8_t add_sub FIELD_PACKED; // add=1,sub=0 + uint8_t dse FIELD_PACKED; // enable/disable day light saving +} POSTPACK SOCK_SNTP_MODIFY_TIMEZONE; + +typedef PREPACK struct sock_ip_sntp_config +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + tSntpDnsAddr SntpDnsAddr[MAX_SNTP_SERVERS] FIELD_PACKED; +} POSTPACK SOCK_IP_QUERY_SNTP_CONFIG; + +typedef PREPACK struct sDestIpToDevMapEvtType +{ + int8_t result; + uint8_t domain; + int16_t device_id; + PREPACK union + { + uint32_t ip_addr FIELD_PACKED; + IP6_ADDR_T ip6_addr FIELD_PACKED; + } POSTPACK dev_addr; + PREPACK union + { + uint32_t ip_addr FIELD_PACKED; + IP6_ADDR_T ip6_addr FIELD_PACKED; + } POSTPACK dest_addr; +} POSTPACK tDestIpToDevMapEvtType; + +typedef PREPACK struct sock_destip_dev_map_evt_type +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + tDestIpToDevMapEvtType ipToDevMap FIELD_PACKED; +} POSTPACK WMI_SOCK_DESTIP_TO_DEV_MAP_EVENT; + +typedef PREPACK struct sock_ip_sntp_client +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + int32_t command FIELD_PACKED; +} POSTPACK SOCK_IP_SNTP_CLIENT_T; + +typedef PREPACK struct sock_ipv4_route +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + int32_t command FIELD_PACKED; + uint32_t address FIELD_PACKED; + uint32_t mask FIELD_PACKED; + uint32_t gateway FIELD_PACKED; + uint32_t ifIndex FIELD_PACKED; + uint32_t prot FIELD_PACKED; +} POSTPACK SOCK_IPV4_ROUTE_T; + +typedef PREPACK struct sock_ipv6_route +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + uint32_t command FIELD_PACKED; + uint8_t address[16] FIELD_PACKED; + int32_t prefixLen FIELD_PACKED; + uint8_t nexthop[16] FIELD_PACKED; + uint32_t ifIndex FIELD_PACKED; + uint32_t prot FIELD_PACKED; +} POSTPACK SOCK_IPV6_ROUTE_T; + +typedef PREPACK struct sock_tcp_conn_timeout +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + uint32_t timeout_val; +} POSTPACK SOCK_TCP_CONN_TIMEOUT_T; + +typedef PREPACK struct sock_ota_upgrade +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + uint32_t ipaddress FIELD_PACKED; + char filename[256] FIELD_PACKED; + uint8_t mode FIELD_PACKED; + uint8_t preserve_last FIELD_PACKED; + uint8_t protocol FIELD_PACKED; +} POSTPACK SOCK_OTA_UPGRADE_T; + +typedef PREPACK struct sock_ota_read_ota_area +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + uint32_t offset; + uint32_t size; +} POSTPACK SOCK_OTA_READ_OTA_AREA_T; + +typedef PREPACK struct sock_ota_done +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + uint32_t data; +} POSTPACK SOCK_OTA_DONE_T; + +typedef PREPACK struct sock_ota_session_start_s +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + uint32_t flags; + uint32_t partition_index; +} POSTPACK SOCK_OTA_SESSION_START_T; + +typedef PREPACK struct sock_ota_parse_image_hdr_s +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + uint8_t header[40]; +} POSTPACK SOCK_OTA_PARSE_IMAGE_HDR_T; + +typedef PREPACK struct sock_ota_partion_write_data_s +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + uint32_t offset; + uint32_t size; + uint8_t data[1]; +} POSTPACK SOCK_OTA_PARTITON_WRITE_DATA_T; + +typedef PREPACK struct dhcps_success_cb_resp +{ + uint32_t resp_code; + uint8_t mac[16]; + uint32_t ip; +} POSTPACK SOCK_DHCPS_SUCCESS_CALLBACK_T; + +typedef PREPACK struct dhcpc_success_cb_resp +{ + uint32_t resp_code; + uint32_t ip; + uint32_t mask; + uint32_t gw; +} POSTPACK SOCK_DHCPC_SUCCESS_CALLBACK_T; + +/*This structure is sent to the target in a data packet. + It allows the target to route the data to correct socket with + all the necessary parameters*/ +typedef PREPACK struct sock_send +{ + uint32_t handle FIELD_PACKED; // Socket handle + uint16_t length FIELD_PACKED; // Payload length + uint16_t reserved FIELD_PACKED; // Reserved + uint32_t flags FIELD_PACKED; // Send flags + SOCKADDR_T name FIELD_PACKED; // IPv4 destination socket information + uint16_t socklength FIELD_PACKED; +} POSTPACK SOCK_SEND_T; + +typedef PREPACK struct sock_send6 +{ + uint32_t handle FIELD_PACKED; // Socket handle + uint16_t length FIELD_PACKED; // Payload length + uint16_t reserved FIELD_PACKED; // Reserved + uint32_t flags FIELD_PACKED; // Send flags + SOCKADDR_6_T name6 FIELD_PACKED; // IPv6 destination socket information + uint16_t socklength FIELD_PACKED; +} POSTPACK SOCK_SEND6_T; + +typedef PREPACK struct sock_recv +{ + uint32_t handle FIELD_PACKED; // Socket handle + SOCKADDR_T name FIELD_PACKED; // IPv4 destination socket information + uint16_t socklength FIELD_PACKED; // Length of sockaddr structure + uint16_t reserved FIELD_PACKED; // Length of sockaddr structure + uint32_t reassembly_info FIELD_PACKED; // Placeholder for reassembly info +} POSTPACK SOCK_RECV_T; + +typedef PREPACK struct sock_recv6 +{ + uint32_t handle FIELD_PACKED; // Socket handle + SOCKADDR_6_T name6 FIELD_PACKED; // IPv6 destination socket information + uint16_t socklength FIELD_PACKED; + uint16_t reserved FIELD_PACKED; // Reserved + uint32_t reassembly_info FIELD_PACKED; // Placeholder for reassembly info +} POSTPACK SOCK_RECV6_T; + +#if ENABLE_SSL +typedef PREPACK struct sock_ssl_new +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + uint32_t ctx FIELD_PACKED; // SSL context +} POSTPACK SOCK_SSL_NEW_T; + +typedef PREPACK struct sock_ssl_set_fd +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + uint32_t ssl FIELD_PACKED; // SSL connection object + uint32_t fd FIELD_PACKED; // Socket handle +} POSTPACK SOCK_SSL_SET_FD_T; + +typedef PREPACK struct sock_ssl_accept +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + uint32_t ssl FIELD_PACKED; // SSL connection object +} POSTPACK SOCK_SSL_ACCEPT_T; + +typedef PREPACK struct sock_ssl_connect +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + uint32_t ssl FIELD_PACKED; // SSL connection object +} POSTPACK SOCK_SSL_CONNECT_T; + +typedef PREPACK struct sock_ssl_shutdown +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + uint32_t ssl FIELD_PACKED; // SSL connection object +} POSTPACK SOCK_SSL_SHUTDOWN_T; + +typedef PREPACK struct sock_ssl_configure +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + uint32_t ssl FIELD_PACKED; // SSL connection object + uint32_t size FIELD_PACKED; // the size of the configuration data + uint8_t data[sizeof(SSL_CONFIG)] FIELD_PACKED; // The configuration data +} POSTPACK SOCK_SSL_CONFIGURE_T; + +typedef PREPACK struct sock_ssl_ctx_new +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + uint32_t role FIELD_PACKED; + int32_t inbufSize FIELD_PACKED; + int32_t outbufSize FIELD_PACKED; + int32_t reserved FIELD_PACKED; +} POSTPACK SOCK_SSL_CTX_NEW_T; + +typedef PREPACK struct sock_ssl_ctx_free +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + uint32_t ctx FIELD_PACKED; // SSL context +} POSTPACK SOCK_SSL_CTX_FREE_T; + +typedef PREPACK struct sock_ssl_add_cert +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + uint32_t ctx FIELD_PACKED; // SSL context + uint32_t type FIELD_PACKED; // Type: 1 for device certificate, 2: CA list + uint32_t total FIELD_PACKED; // The size of ca_list + uint32_t offset FIELD_PACKED; // offset of this fragment + uint32_t size FIELD_PACKED; // fragment size + uint8_t data[1] FIELD_PACKED; // CA list or certificate data +} POSTPACK SOCK_SSL_ADD_CERT_T; + +typedef PREPACK struct sock_ssl_store_cert +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + uint8_t name[32] FIELD_PACKED; // The name of the certificate or CA list + uint32_t total FIELD_PACKED; // The size of the certificate or CA list + uint32_t offset FIELD_PACKED; // offset of this fragment + uint32_t size FIELD_PACKED; // fragment size + uint8_t data[1] FIELD_PACKED; // certificate or CA list data +} POSTPACK SOCK_SSL_STORE_CERT_T; + +typedef PREPACK struct sock_ssl_load_cert +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + uint32_t ctx FIELD_PACKED; // SSL context + uint32_t type FIELD_PACKED; // Type: 1 for device certificate, 2: CA list + uint8_t name[32] FIELD_PACKED; // The name of the certificate or CA list +} POSTPACK SOCK_SSL_LOAD_CERT_T; + +typedef PREPACK struct sock_ssl_list_cert +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + uint32_t reserved FIELD_PACKED; +} POSTPACK SOCK_SSL_LIST_CERT_T; + +#endif + +typedef PREPACK struct sock_get_dev_from_dest_ip +{ + WMI_SOCKET_CMD wmi_cmd FIELD_PACKED; + uint32_t handle FIELD_PACKED; // socket handle + PREPACK union + { + uint32_t ipaddr FIELD_PACKED; + IP6_ADDR_T ip6addr FIELD_PACKED; + } POSTPACK addr; + uint8_t domain FIELD_PACKED; // socket domain +} POSTPACK SOCK_GET_DEV_FROM_DEST_T; + +//#define SOCK_EV_MASK_SET(_pcxt, _cmd) (_pcxt)->sock_st_mask[(_cmd) >> 5] |= ((uint32_t)((uint32_t)1 << ((_cmd)&0x1f))) +static inline void SOCK_EV_MASK_SET(ATH_SOCKET_CONTEXT *_pcxt, uint32_t _cmd) +{ + _pcxt->sock_st_mask[(_cmd) >> 5] |= ((uint32_t)((uint32_t)1 << ((_cmd)&0x1f))); +} + +//#define SOCK_EV_MASK_CLEAR(_pcxt, _cmd) (_pcxt)->sock_st_mask[(_cmd) >> 5] &= ((uint32_t)(~((uint32_t)1 << ((_cmd)&0x1f)))) +static inline void SOCK_EV_MASK_CLEAR(ATH_SOCKET_CONTEXT *_pcxt, uint32_t _cmd) +{ + _pcxt->sock_st_mask[(_cmd) >> 5] &= ((uint32_t)(~((uint32_t)1 << ((_cmd)&0x1f)))); +} + +//#define SOCK_EV_MASK_TEST(_pcxt, _cmd) (( ((uint32_t)(_pcxt)->sock_st_mask[(_cmd) >> 5]) & ((uint32_t)((uint32_t)1 << ((_cmd)&0x1f))) ) ? 1 : 0) +static inline uint32_t SOCK_EV_MASK_TEST(ATH_SOCKET_CONTEXT *_pcxt, uint32_t _cmd) +{ + uint32_t tmp = ( ((uint32_t)(_pcxt)->sock_st_mask[(_cmd) >> 5]) & ((uint32_t)((uint32_t)1 << ((_cmd)&0x1f))) ); + return tmp ? 1 : 0; +} + +extern ATH_SOCKET_CONTEXT *ath_sock_context[]; + +/************************** Internal Function declarations*****************************/ + +uint32_t queue_empty(uint32_t index); + +#define QUEUE_EMPTY(index) queue_empty((index)) + +#define BLOCK_FOR_DATA(pCxt, ctxt, msec, direction) blockForDataRx((pCxt), (ctxt), (msec), (direction)) + +/******* Function Declarations *******************/ +A_STATUS unblock(void *ctxt, uint8_t direction); +A_STATUS blockForResponse(void *pCxt, void *ctxt, uint32_t msec, uint8_t direction); +A_STATUS blockForDataRx(void *pCxt, void *ctxt, uint32_t msec, uint8_t direction); + +#define BLOCK(pCxt, ctxt, msec, direction) blockForResponse((pCxt), (ctxt), (msec), (direction)) + +#define UNBLOCK(ctxt, direction) unblock((ctxt), (direction)) + +#if T_SELECT_VER1 +A_STATUS unblockSelect(void *ctxt); +A_STATUS blockSelect(void *pCxt, uint32_t msec); +#endif + +#if T_SELECT_VER1 + +#define BLOCK_SELECT(pCxt, msec) blockSelect((pCxt), (msec)) + +#define UNBLOCK_SELECT(pCxt) unblockSelect((pCxt)) +#else + +#define BLOCK_SELECT(pCxt, msec) + +#define UNBLOCK_SELECT(pCxt) + +#endif // T_SELECT_VER1 + +A_STATUS socket_context_init(void); +int32_t find_socket_context(uint32_t handle, uint8_t retrieve); +uint32_t getTransportLength(uint8_t proto); +uint32_t getIPLength(uint8_t version); +A_STATUS move_power_state_to_maxperf(void *pDCxt, int32_t module); +A_STATUS restore_power_state(void *pDCxt, int32_t module); + +/************************* Socket APIs *************************************************/ +int32_t Api_socket(void *pCxt, uint32_t domain, uint32_t type, uint32_t protocol); +int32_t Api_shutdown(void *pCxt, uint32_t handle); +int32_t Api_connect(void *pCxt, uint32_t handle, void *name, uint16_t length); +int32_t Api_bind(void *pCxt, uint32_t handle, void *name, uint16_t length); +int32_t Api_listen(void *pCxt, uint32_t handle, uint32_t backlog); +int32_t Api_accept(void *pCxt, uint32_t handle, void *name, socklen_t length); + +#if T_SELECT_VER1 +int32_t Api_accept_ver1(void *pCxt, uint32_t handle, void *name, socklen_t length); +int32_t Api_select_ver1(void *pCxt, int32_t num, uint32_t *r_fd, uint32_t *w_fd, uint32_t *e_fd, uint32_t tv); +#endif + +int32_t Api_sendto(void *pCxt, + uint32_t handle, + uint8_t *buffer, + uint32_t length, + uint32_t flags, + SOCKADDR_T *name, + uint32_t socklength); +int32_t Api_select(void *pCxt, uint32_t handle, uint32_t tv); +int32_t Api_errno(void *pCxt, uint32_t handle); +int32_t Api_getsockopt(void *pCxt, uint32_t handle, uint32_t level, uint32_t optname, uint8_t *optval, uint32_t optlen); +int32_t Api_setsockopt(void *pCxt, uint32_t handle, uint32_t level, uint32_t optname, uint8_t *optval, uint32_t optlen); +#if ZERO_COPY +int32_t Api_recvfrom( + void *pCxt, uint32_t handle, void **buffer, uint32_t length, uint32_t flags, void *name, socklen_t *socklength); +#else +int32_t Api_recvfrom( + void *pCxt, uint32_t handle, void *buffer, uint32_t length, uint32_t flags, void *name, socklen_t *socklength); +#endif +int32_t Api_ipconfig(void *pCxt, + uint32_t mode, + uint32_t *ipv4_addr, + uint32_t *subnetMask, + uint32_t *gateway4, + IP46ADDR *dnsaddr, + char *hostname); +void clear_socket_context(int32_t index); +int32_t Api_ping(void *pCxt, uint32_t ipv4_addr, uint32_t size); +int32_t Api_ping6(void *pCxt, uint8_t *ip6addr, uint32_t size); +int32_t Api_ip6config(void *pCxt, + uint32_t mode, + IP6_ADDR_T *v6Global, + IP6_ADDR_T *v6Link, + IP6_ADDR_T *v6DefGw, + IP6_ADDR_T *v6GlobalExtd, + int32_t *LinkPrefix, + int32_t *GlbPrefix, + int32_t *DefgwPrefix, + int32_t *GlbPrefixExtd); +A_STATUS send_stack_init(void *pCxt); +void socket_context_deinit(void); +int32_t Api_ipconfig_dhcp_pool(void *pCxt, uint32_t *start_ipv4_addr, uint32_t *end_ipv4_addr, int32_t leasetime); +int32_t Api_ip6config_router_prefix( + void *pCxt, IP6_ADDR_T *v6addr, int32_t prefixlen, int32_t prefix_lifetime, int32_t valid_lifetime); +int32_t Api_ipconfig_set_tcp_exponential_backoff_retry(void *pCxt, int32_t retry); +int32_t Api_ipconfig_set_ip6_status(void *pCxt, uint16_t status); +int32_t Api_ipconfig_dhcp_release(void *pCxt); +int32_t Api_ipbridgemode(void *handle, uint16_t status); +int32_t Api_ipconfig_set_tcp_rx_buffer(void *pCxt, int32_t rxbuf); +int32_t Api_ip_http_server(void *pCxt, int32_t command); +int32_t Api_ip_http_server_method( + void *pCxt, int32_t command, uint8_t *pagename, uint8_t *objname, int32_t objtype, int32_t objlen, uint8_t *value); +int32_t Api_httpc_method(void *pCxt, uint32_t command, uint8_t *url, uint8_t *data, uint8_t **output); +int32_t Api_ip_resolve_host_name(void *pCxt, DNC_CFG_CMD *DncCfg, DNC_RESP_INFO *DncRespInfo); +int32_t Api_ip_dns_client(void *pCxt, int32_t command); +int32_t Api_ip_dns_server_addr(void *pCxt, IP46ADDR *addr); +int32_t Api_ip_dns_local_domain(void *pCxt, char *domain_name); +int32_t Api_ip_hostname(void *pCxt, char *domain_name); +int32_t Api_ipdns(void *pCxt, int32_t command, char *domain_name, IP46ADDR *dnsaddr); +int32_t Api_ip_sntp_srvr_addr(void *pCxt, int32_t command, char *sntp_srvr_addr); +int32_t Api_ip_sntp_get_time(void *pCxt, tSntpTime *SntpTime); +int32_t Api_ip_sntp_get_time_of_day(void *pCxt, tSntpTM *SntpTm); +int32_t Api_ip_sntp_modify_zone_dse(void *pCxt, uint8_t hr, uint8_t mn, uint8_t zone_cal, uint8_t dse_en_dis); +int32_t Api_ip_sntp_query_srvr_address(void *pcxt, tSntpDnsAddr SntpDnsAddr[MAX_SNTP_SERVERS]); +int32_t Api_ip_sntp_client(void *pCxt, int32_t command); + +int32_t Api_tcp_connection_timeout(void *pCxt, uint32_t timeout_val); + +int32_t Api_ota_upgrade(void *pCxt, + uint32_t addr, + char *filename, + uint8_t mode, + uint8_t preserve_last, + uint8_t protocol, + uint32_t *resp_code, + uint32_t *length); +int32_t Api_ota_read_area(void *pCxt, uint32_t offset, uint32_t size, uint8_t *buffer, uint32_t *retlen); +int32_t Api_ota_done(void *pCxt, boolean good_image); +int32_t Api_ota_session_start(void *pCxt, uint32_t flags, uint32_t partition_index); +uint32_t Api_ota_partition_get_size(void *pCxt); +int32_t Api_ota_partition_erase(void *pCxthandle); +int32_t Api_ota_partition_verify_checksum(void *pCxthandle); +int32_t Api_ota_parse_image_hdr(void *pCxt, uint8_t *header, uint32_t *offset); +int32_t Api_ota_partition_write_data(void *pCxt, uint32_t offset, uint8_t *buf, uint32_t size, uint32_t *ret_size); + +#if ENABLE_ROUTING_CMDS +int32_t Api_ipv4_route(void *pCxt, + uint32_t command, + IP_ADDR_T *ipv4_addr, + IP_ADDR_T *subnetMask, + IP_ADDR_T *gateway, + uint32_t *ifIndex, + IPV4_ROUTE_LIST_T *routelist); +int32_t Api_ipv6_route(void *pCxt, + uint32_t command, + IP6_ADDR_T *ipv6_addr, + uint32_t *prefixLen, + IP6_ADDR_T *gateway, + uint32_t *ifIndex, + IPV6_ROUTE_LIST_T *routelist); +#endif + +int32_t Api_ip_dns_server(void *pCxt, int32_t command); +#if ENABLE_SSL +SSL_CTX *Api_SSL_ctx_new(void *pCxt, SSL_ROLE_T role, int32_t inbufSize, int32_t outbufSize, int32_t reserved); +int32_t Api_SSL_ctx_free(void *pCxt, SSL_CTX *ctx); +SSL *Api_SSL_new(void *pCxt, SSL_CTX *ctx); +int32_t Api_SSL_set_fd(void *pCxt, SSL *ssl, uint32_t fd); +int32_t Api_SSL_accept(void *pCxt, SSL *ssl); +int32_t Api_SSL_connect(void *pCxt, SSL *ssl); +int32_t Api_SSL_shutdown(void *pCxt, SSL *ssl); +int32_t Api_SSL_configure(void *pCxt, SSL *ssl, SSL_CONFIG *cfg); +int32_t Api_SSL_addCert(void *pCxt, SSL_CTX *ctx, SSL_CERT_TYPE_T type, uint8_t *cert, uint32_t size); +int32_t Api_SSL_storeCert(void *pCxt, char *name, uint8_t *cert, uint32_t size); +int32_t Api_SSL_loadCert(void *pCxt, SSL_CTX *ctx, SSL_CERT_TYPE_T type, char *name); +int32_t Api_SSL_listCert(void *pCxt, SSL_FILE_NAME_LIST *fileNames); +#endif +#endif // ENABLE_STACK_OFFLOAD +#endif diff --git a/platform/mcu/lpc54102/wifi_qca/common_src/storerecall/dset.c b/platform/mcu/lpc54102/wifi_qca/common_src/storerecall/dset.c new file mode 100644 index 0000000000..e885d5237b --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/common_src/storerecall/dset.c @@ -0,0 +1,190 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== +#include +#include +#include + +#include "dset.h" + +HOST_DSET host_dsets[MAX_DSET_SIZE]; + +HOST_DSET *dset_find(uint32_t dset_id) +{ + uint16_t i; + HOST_DSET *pDset; + + for (i = 0, pDset = host_dsets; i < MAX_DSET_SIZE; i++, pDset++) + { + if (pDset->dset_id == dset_id) + return pDset; + } + + return NULL; +} + +HOST_DSET *dset_insert(uint32_t dset_id) +{ + uint16_t i; + HOST_DSET *pDset; + + for (i = 0, pDset = host_dsets; i < MAX_DSET_SIZE; i++, pDset++) + { + if (pDset->dset_id == 0) + { + pDset->dset_id = dset_id; + if (pDset->data_ptr) + { + A_FREE(pDset->data_ptr, MALLOC_ID_CONTEXT); + pDset->data_ptr = NULL; + } + + return pDset; + } + } + + return NULL; +} + +HOST_DSET *dset_get(uint32_t dset_id, uint32_t length) +{ + unsigned char *pbuf; + + HOST_DSET *pDset; + + pDset = dset_find(dset_id); + + if (pDset == NULL) + { + pDset = dset_insert(dset_id); + if (pDset == NULL) + return pDset; + } + + /* Free the data buffer and reallocate based on new length */ + if (pDset->data_ptr) + { + A_FREE(pDset->data_ptr, MALLOC_ID_CONTEXT); + pDset->data_ptr = NULL; + } + + pbuf = (unsigned char *)A_MALLOC(length, MALLOC_ID_CONTEXT); + if (pbuf == NULL) + { + pDset->dset_id = 0; + return NULL; + } + + pDset->data_ptr = pbuf; + pDset->length = length; + + return pDset; +} + +uint32_t dset_write(HOST_DSET *pDset, uint8_t *pData, uint32_t offset, uint32_t length) +{ + uint32_t wrt_len; + + if (offset + length > pDset->length) + wrt_len = pDset->length - offset; + else + wrt_len = length; + + memcpy(pDset->data_ptr + offset, pData, wrt_len); + + return wrt_len; +} + +uint32_t dset_read(HOST_DSET *pDset, uint8_t *pData, uint32_t offset, uint32_t length) +{ + uint32_t wrt_len; + + if (offset + length > pDset->length) + wrt_len = pDset->length - offset; + else + wrt_len = length; + + memcpy(pData, pDset->data_ptr + offset, wrt_len); + + return wrt_len; +} + +uint32_t dset_fill(uint8_t *pData, uint32_t max_dset_count) +{ + uint16_t i, count = 0; + HOST_DSET *pDset; + HOST_DSET_ITEM *pItem = (HOST_DSET_ITEM *)pData; + + for (i = 0, pDset = host_dsets; i < MAX_DSET_SIZE && count < max_dset_count; i++, pDset++) + { + if (pDset->dset_id != 0) + { + pItem->dset_id = pDset->dset_id; + pItem->length = pDset->length; + pItem++; + count++; + } + } + + return count; +} + +uint16_t next_dset_ndx; + +HOST_DSET *dset_get_first(void) +{ + uint16_t i; + HOST_DSET *pDset; + + for (i = 0, pDset = host_dsets; i < MAX_DSET_SIZE; i++, pDset++) + { + if (pDset->dset_id != 0) + { + next_dset_ndx = i + 1; + return pDset; + } + } + + return NULL; +} + +HOST_DSET *dset_get_next(void) +{ + uint16_t i; + HOST_DSET *pDset; + + pDset = &host_dsets[next_dset_ndx]; + + for (i = next_dset_ndx; i < MAX_DSET_SIZE; i++, pDset++) + { + if (pDset->dset_id != 0) + { + next_dset_ndx = i + 1; + return pDset; + } + } + + return NULL; +} diff --git a/platform/mcu/lpc54102/wifi_qca/common_src/storerecall/dset_api.c b/platform/mcu/lpc54102/wifi_qca/common_src/storerecall/dset_api.c new file mode 100644 index 0000000000..746470c0f5 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/common_src/storerecall/dset_api.c @@ -0,0 +1,245 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== + +#include +#include +#include +#include +#include + +#include "dset_api.h" + +HOST_DSET_HANDLE dset_handles[MAX_HOST_DSET_SIZE]; + + +//TODO: fixme. dummy fn, implemented in app +PREWEAK_CODE int32_t POSTWEAK_CODE remote_dset_op(DSET_OP op, HOST_DSET_HANDLE *pDsetHandle) +{ + return A_ERROR; +} + + +HOST_DSET_HANDLE *dset_find_handle(uint32_t dset_id) +{ + uint16_t i; + HOST_DSET_HANDLE *pDsetHandle = dset_handles; + + for (i = 0; i < MAX_HOST_DSET_SIZE; i++) + { + if (pDsetHandle->dset_id == dset_id) + return pDsetHandle; + } + return NULL; +} + +void dset_close_handle(HOST_DSET_HANDLE *pDsetHandle) +{ + pDsetHandle->dset_id = INVALID_DSET_ID; + if (pDsetHandle->data_ptr) + A_FREE(pDsetHandle->data_ptr, MALLOC_ID_TEMPORARY); +} + +HOST_DSET_HANDLE *dset_insert_handle(uint32_t dset_id, uint32_t flags, dset_callback_fn_t cb, void *cb_args) +{ + uint16_t i; + HOST_DSET_HANDLE *pDsetHandle = dset_handles; + + for (i = 0; i < MAX_HOST_DSET_SIZE; i++, pDsetHandle++) + { + if (pDsetHandle->dset_id == INVALID_DSET_ID) + { + pDsetHandle->dset_id = dset_id; + pDsetHandle->flags = flags; + pDsetHandle->cb = cb; + pDsetHandle->cb_args = cb_args; + pDsetHandle->data_ptr = NULL; + return pDsetHandle; + }; + } + return NULL; +} + +int32_t qcom_dset_create(HOST_DSET_HANDLE **pDsetHandle, + uint32_t dset_id, + uint32_t media_id, + uint32_t length, + uint32_t flags, + dset_callback_fn_t create_cb, + void *callback_arg) +{ + int32_t status; + + *pDsetHandle = dset_find_handle(dset_id); + if (*pDsetHandle != NULL) + return A_ERROR; + + *pDsetHandle = dset_insert_handle(dset_id, flags, create_cb, callback_arg); + if (*pDsetHandle == NULL) + return A_ERROR; + + (*pDsetHandle)->length = length; + (*pDsetHandle)->media_id = media_id; + + status = remote_dset_op(DSET_OP_CREATE, *pDsetHandle); + + return status; +} + +int32_t qcom_dset_open( + HOST_DSET_HANDLE **ppDsetHandle, uint32_t dset_id, uint32_t flags, dset_callback_fn_t open_cb, void *callback_arg) +{ + int32_t status; + + *ppDsetHandle = dset_find_handle(dset_id); + if (*ppDsetHandle != NULL) + return A_OK; + + *ppDsetHandle = dset_insert_handle(dset_id, flags, open_cb, callback_arg); + if (*ppDsetHandle == NULL) + return A_ERROR; + + status = remote_dset_op(DSET_OP_OPEN, *ppDsetHandle); + + return status; +} + +uint32_t qcom_dset_write(HOST_DSET_HANDLE *pDsetHandle, + uint8_t *buffer, + uint32_t length, + uint32_t offset, + uint32_t flags, + dset_callback_fn_t write_cb, + void *callback_arg) +{ +#define DSET_WRITE_HEAD_SIZE (sizeof(WMIX_DSET_OP_WRITE_PARAM_CMD) + +sizeof(WMIX_DSET_CMD_HDR) - 1) + + uint32_t status; + + pDsetHandle->offset = offset; + pDsetHandle->length = length; + pDsetHandle->flags = flags; + pDsetHandle->cb = write_cb; + pDsetHandle->cb_args = callback_arg; + + if (length + DSET_WRITE_HEAD_SIZE > MAX_DSET_BUFF_SIZE) + return 0; + + if (pDsetHandle->data_ptr == NULL) + pDsetHandle->data_ptr = A_MALLOC(MAX_DSET_BUFF_SIZE, MALLOC_ID_TEMPORARY); + + memcpy(pDsetHandle->data_ptr + DSET_WRITE_HEAD_SIZE, buffer, length); + + status = remote_dset_op(DSET_OP_WRITE, pDsetHandle); + return status; +} + +uint32_t qcom_dset_read(HOST_DSET_HANDLE *pDsetHandle, + uint8_t *buffer, + uint32_t length, + uint32_t offset, + dset_callback_fn_t read_cb, + void *callback_arg) +{ + uint32_t status; + + pDsetHandle->offset = offset; + pDsetHandle->length = length; + + pDsetHandle->cb = read_cb; + pDsetHandle->cb_args = callback_arg; + + if (length + sizeof(WMIX_DSET_OP_WRITE_PARAM_CMD) > MAX_DSET_BUFF_SIZE) + return 0; + + if (pDsetHandle->data_ptr == NULL) + pDsetHandle->data_ptr = A_MALLOC(MAX_DSET_BUFF_SIZE, MALLOC_ID_TEMPORARY); + + status = remote_dset_op(DSET_OP_READ, pDsetHandle); + memcpy(buffer, pDsetHandle->data_ptr, length); + return status; +} + +uint32_t qcom_dset_commit(HOST_DSET_HANDLE *pDsetHandle, dset_callback_fn_t commit_cb, void *callback_arg) +{ + uint32_t status; + + pDsetHandle->cb = commit_cb; + pDsetHandle->cb_args = callback_arg; + status = remote_dset_op(DSET_OP_COMMIT, pDsetHandle); + + dset_close_handle(pDsetHandle); + + return status; +} + +uint32_t qcom_dset_close(HOST_DSET_HANDLE *pDsetHandle, dset_callback_fn_t close_cb, void *callback_arg) +{ + uint32_t status; + + pDsetHandle->cb = close_cb; + pDsetHandle->cb_args = callback_arg; + + status = remote_dset_op(DSET_OP_CLOSE, pDsetHandle); + + dset_close_handle(pDsetHandle); + + return status; +} + +uint32_t qcom_dset_size(HOST_DSET_HANDLE *pDsetHandle, dset_callback_fn_t size_cb, void *callback_arg) +{ + uint32_t status; + + pDsetHandle->cb = size_cb; + pDsetHandle->cb_args = callback_arg; + + status = remote_dset_op(DSET_OP_SIZE, pDsetHandle); + return status; +} + +uint32_t qcom_dset_delete(uint32_t dset_id, uint32_t flags, dset_callback_fn_t delete_cb, void *callback_arg) +{ + uint32_t status; + HOST_DSET_HANDLE *pDsetHandle; + + pDsetHandle = dset_find_handle(dset_id); + if (pDsetHandle == NULL) + { + pDsetHandle = dset_insert_handle(dset_id, flags, delete_cb, callback_arg); + if (pDsetHandle == NULL) + return false; + } + else + { + pDsetHandle->cb = delete_cb; + pDsetHandle->cb_args = callback_arg; + pDsetHandle->dset_id = dset_id; + pDsetHandle->flags = flags; + } + + status = remote_dset_op(DSET_OP_DELETE, pDsetHandle); + return status; +} diff --git a/platform/mcu/lpc54102/wifi_qca/common_src/storerecall/storerecall.c b/platform/mcu/lpc54102/wifi_qca/common_src/storerecall/storerecall.c new file mode 100644 index 0000000000..1a77ddc347 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/common_src/storerecall/storerecall.c @@ -0,0 +1,264 @@ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +A_STATUS setup_host_dset(void *handle); + +#if DRIVER_CONFIG_ENABLE_STORE_RECALL +extern const uint8_t max_performance_power_param; + +#if !ENABLE_STACK_OFFLOAD +extern int32_t power_state_for_module; +/*****************************************************************************/ +/* restore_power_state - Restores the original power state, which is changed by + * "move_power_state_to_maxperf" + * int32_t - module which request the change + * RETURNS: A_OK on success A_ERROR otherwise + *****************************************************************************/ +A_STATUS restore_power_state(void *pCxt, int32_t module) +{ + A_DRIVER_CONTEXT *pDCxt = (A_DRIVER_CONTEXT *)pCxt; + + /* Already some HIGH priority module changes state, + * so don't change the state now */ + if (!power_state_for_module || (power_state_for_module > module)) + { + return A_OK; + } + if (pDCxt->userPwrMode != max_performance_power_param) + { + if (A_OK != + wmi_cmd_start(pDCxt->pWmiCxt, &pDCxt->userPwrMode, WMI_SET_POWER_MODE_CMDID, sizeof(WMI_POWER_MODE_CMD))) + { + return A_ERROR; + } + } + + power_state_for_module = 0; + return A_OK; +} +#endif +/*****************************************************************************/ +/* Strrcl_ChipUpFinish - Utility function to complete the chip_up process. + * when WMI_READY is received from chip this function clears the chipDown + * boolean and sends the wmi store recall command to the chip so that its + * associated State can be refreshed. + * void *pCxt - the driver context. + *****************************************************************************/ +static A_STATUS Strrcl_ChipUpFinish(void *pCxt) +{ + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + WMI_STORERECALL_RECALL_CMD *pDsetInfo; + uint32_t dset_info_len; + + if (pDCxt->wmiReady == true) + { + switch (pDCxt->strrclState) + { + case STRRCL_ST_ACTIVE: + /* clear the chipDown boolean to allow outside activity to resume */ + pDCxt->chipDown = false; + + if (A_OK != STACK_INIT(pCxt)) + { + break; + } + + pDCxt->strrclState = STRRCL_ST_ACTIVE_B; + // INTENTIONAL FALL_THRU + case STRRCL_ST_ACTIVE_B: +/* send recall */ +#if 0 + pEv = (WMI_STORERECALL_STORE_EVENT*)pDCxt->strrclCxt; + + if(A_OK != wmi_storerecall_recall_cmd(pDCxt->pWmiCxt, A_LE2CPU32(pEv->length), &pEv->data[0])){ + break; //try again later this is likely because a previous wmi cmd has not finished. + } +#elifndef ENABLE_LARGE_DSET + + setup_host_dset(pCxt); + + pDsetData = pDCxt->tempStorage; + + if(A_OK != wmi_storerecall_recall_cmd(pDCxt->pWmiCxt, A_LE2CPU32(pDCxt->strrclCxtLen), pDsetData)){ + break; //try again later this is likely because a previous wmi cmd has not finished. + } +#else + setup_host_dset(pCxt); + + pDsetInfo = (WMI_STORERECALL_RECALL_CMD *)pDCxt->tempStorage; + if (pDsetInfo->length == 0) + { + dset_info_len = sizeof(WMI_STORERECALL_RECALL_CMD); + } + else + { + dset_info_len = sizeof(WMI_STORERECALL_RECALL_CMD) - sizeof(uint8_t); + dset_info_len += sizeof(WMI_STORERECALL_RECALL_DSET) * pDsetInfo->length; + } + + if (A_OK != wmi_storerecall_recall_cmd(pDCxt->pWmiCxt, dset_info_len, pDsetInfo)) + { + break; // try again later this is likely because a previous wmi cmd has not finished. + } +#endif + + pDCxt->strrclCxt = NULL; + pDCxt->strrclCxtLen = 0; + + // pDCxt->strrclState = STRRCL_ST_AWAIT_FW; + + pDCxt->strrclState = STRRCL_ST_INIT; + pDCxt->strrclBlock = false; + + /* Indicate completion to the custom layer */ + API_STORE_RECALL_EVENT(pCxt); + + /* clear this function from the driver's temporary calls */ + pDCxt->asynchRequest = NULL; + /* Since we are setting MAX_PERF before going to store-recall we need to set the state + after we wakes up */ + restore_power_state(pDCxt, 1); /* POWER_STATE_MOVED_FOR_STRRCL */ + + break; // done!! + default: + A_ASSERT(0); // should never happen +#if DRIVER_CONFIG_DISABLE_ASSERT + break; +#endif + } + } + + return A_OK; +} + +/*****************************************************************************/ +/* Strrcl_ChipUpStart - Utility function to bring bring the chip back up. Also + * sets up the driver tempFunc so that when the WMI_READY is received the + * store recall process can be completed via Strrcl_ChipUpFinish. + * void *pCxt - the driver context. + *****************************************************************************/ +static A_STATUS Strrcl_ChipUpStart(void *pCxt) +{ + A_STATUS status = A_ERROR; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + A_MDELAY(2); + /* assert pwd line */ + HW_PowerUpDown(pCxt, true); + + A_MDELAY(2); + do + { + /* reset htc_creditInit to re-process the HTC interrupt */ + pDCxt->htc_creditInit = 0; + + if ((status = Hcd_ReinitTarget(pCxt)) != A_OK) + { + break; + } + + A_MDELAY(1); + + if (A_OK != (status = Driver_BootComm(pCxt))) + { + break; + } + +#if (DRIVER_CONFIG_ENABLE_HOST_FW_DOWNLOAD) + if (A_OK != (status = Driver_StoreRecallFirmwareDownload(pCxt))) + { + break; + } +#endif /* DRIVER_CONFIG_ENABLE_HOST_FW_DOWNLOAD */ + + /* unmask the packet interrupt on-chip */ + Hcd_UnmaskInterrupts(pCxt, ATH_SPI_INTR_PKT_AVAIL); + /* when the driver receives the WMI_READY event chip_up_finish + * will complete the re-boot process and open the way for + * outside requests to resume. */ + pDCxt->asynchRequest = Strrcl_ChipUpFinish; + + } while (0); + + return status; +} + +/*****************************************************************************/ +/* Strrcl_ChipDown - Utility function to bring the chip down. Also sets + * driver booleans to prevent any unwanted activity until the chip is + * brought back up. + * void *pCxt - the driver context. + *****************************************************************************/ +static void Strrcl_ChipDown(void *pCxt) +{ + /* disable interrupt line - prevent un-expected INTs when chip powers down */ + // EnableDisableSPIIRQHwDetect(pDevice,false); + GET_DRIVER_COMMON(pCxt)->chipDown = true; + GET_DRIVER_COMMON(pCxt)->wmiReady = false; + /* assert pwd line */ + HW_PowerUpDown(pCxt, false); +} + +/*****************************************************************************/ +/* Strrcl_Recall - Implements the store-recall procedure. powers down the chip + * waits for x msec powers up the chip, reboots the chip. Called when the + * store-recall event is received from the chip indicating that it can be + * powered down for the specified timeout. + * void *pCxt - the driver context. + * uint32_t msec_sleep - number of milliseconds to wait + *****************************************************************************/ +void Strrcl_Recall(void *pCxt, uint32_t msec_sleep) +{ + /* bring down the chip */ + Strrcl_ChipDown(pCxt); + /* this will block the driver thread */ + /* FIXME: should instead implement a way to block the driver at driver_main thus + * allowing the thread to continue running in single-threaded systems.*/ + if (ath_custom_init.Custom_Delay != NULL) + { + /*It is possible that some hosts support low power modes, this would be a + good place to invoke it. Call app defined function if available*/ + ath_custom_init.Custom_Delay(msec_sleep); + } + else + A_MDELAY(msec_sleep); + + /* wake up chip */ + Strrcl_ChipUpStart(pCxt); +} + +#endif // DRIVER_CONFIG_ENABLE_STORE_RECALL diff --git a/platform/mcu/lpc54102/wifi_qca/common_src/util/util.c b/platform/mcu/lpc54102/wifi_qca/common_src/util/util.c new file mode 100644 index 0000000000..e8b2b1cec6 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/common_src/util/util.c @@ -0,0 +1,87 @@ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== + +#include +#include +#include +#include +#include + +A_ENDPOINT_T *Util_GetEndpoint(void *pCxt, uint16_t id) +{ + /* this translation allows multiple virtual endpoints to be mapped to + * a common endpoint object. */ + if (id >= ENDPOINT_MANAGED_MAX) + { + id = ENDPOINT_MANAGED_MAX - 1; + } + return &(GET_DRIVER_COMMON(pCxt)->ep[id]); +} + +/* + * converts ieee channel number to frequency + */ +uint16_t Util_Ieee2freq(int32_t chan) +{ + if (chan == 14) + { + return (uint16_t)2484; + } + if (chan < 14) + { /* 0-13 */ + return (uint16_t)(2407 + (chan * 5)); + } + if (chan < 27) + { /* 15-26 */ + return (uint16_t)(2512 + ((chan - 15) * 20)); + } + return (uint16_t)(5000 + (chan * 5)); +} + +/* + * Converts MHz frequency to IEEE channel number. + */ +uint32_t Util_Freq2ieee(uint16_t freq) +{ + if (freq == 2484) + return (uint32_t)14; + if (freq < 2484) + return (uint32_t)((freq - 2407) / 5); + if (freq < 5000) + return (uint32_t)(15 + ((freq - 2512) / 20)); + return (uint32_t)((freq - 5000) / 5); +} + +HTC_ENDPOINT_ID +Util_AC2EndpointID(void *pCxt, uint8_t ac) +{ + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + return pDCxt->ac2EpMapping[ac]; +} + +uint8_t Util_EndpointID2AC(void *pCxt, HTC_ENDPOINT_ID ep) +{ + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + return pDCxt->ep2AcMapping[ep]; +} diff --git a/platform/mcu/lpc54102/wifi_qca/common_src/wmi/wmi.c b/platform/mcu/lpc54102/wifi_qca/common_src/wmi/wmi.c new file mode 100644 index 0000000000..9e03bead89 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/common_src/wmi/wmi.c @@ -0,0 +1,1698 @@ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== + +#ifdef WIN_MOBILE7 +#include +#endif + +#include +#include +#include +#include +#include "htc.h" +#include "htc_api.h" +#include "wmi.h" +#include +#include +#include +#include "wmi_host.h" +#include "a_drv.h" +#include "a_drv_api.h" +#include "atheros_wifi_api.h" +#define ATH_MODULE_NAME wmi +#include "a_debug.h" +#include "dbglog_api.h" +#include "cust_netbuf.h" +#include "custom_wlan_api.h" + +#if ENABLE_P2P_MODE +#include "p2p.h" +#endif + +#include "driver_cxt.h" +#include "dset.h" + +extern uint32_t last_driver_error; +// static uint16_t channel_no = 0; + +#define ATH_DEBUG_WMI 1 +#define ATH_DEBUG_ERR 1 + +#ifdef DEBUG_WMI_TRACE + +static ATH_DEBUG_MASK_DESCRIPTION wmi_debug_desc[] = { + {ATH_DEBUG_WMI, "General WMI Tracing"}, +}; + +ATH_DEBUG_INSTANTIATE_MODULE_VAR(wmi, + "wmi", + "Wireless Module Interface", + ATH_DEBUG_MASK_DEFAULTS, + ATH_DEBUG_DESCRIPTION_COUNT(wmi_debug_desc), + wmi_debug_desc); + +#endif + +#ifndef REXOS +#define DBGARG __func__ +#define DBGFMT "%s() : " +#define DBG_WMI ATH_DEBUG_WMI +#define DBG_ERROR ATH_DEBUG_ERR +#define DBG_WMI2 ATH_DEBUG_WMI +#define A_DPRINTF AR_DEBUG_PRINTF +#endif + +#if ENABLE_P2P_MODE +static A_STATUS wmi_p2p_goneg_result_event_rx(struct wmi_t *wmip, uint8_t devId, uint8_t *datap, uint8_t len); + +static A_STATUS wmi_p2p_list_peristent_network(struct wmi_t *wmip, uint8_t devId, uint8_t *datap, uint8_t len); + +static A_STATUS wmi_p2p_req_auth_event_rx(struct wmi_t *wmip, uint8_t devId, uint8_t *datap, uint32_t len); + +static A_STATUS wmi_p2p_node_list_event_rx(struct wmi_t *wmip, uint8_t devId, uint8_t *datap, uint32_t len); + +static A_STATUS wmi_p2p_invite_sent_result_rx(struct wmi_t *wmip, uint8_t devId, uint8_t *datap, uint8_t len); +static A_STATUS wmi_p2p_prov_disc_resp_rx(struct wmi_t *wmip, uint8_t devId, uint8_t *datap, uint8_t len); +static A_STATUS wmi_p2p_prov_disc_req_rx(struct wmi_t *wmip, uint8_t devId, uint8_t *datap, uint8_t len); +#if 1 // KK +static A_STATUS wmi_p2p_sdpd_event_rx(struct wmi_t *wmip, uint8_t devId, uint8_t *datap, uint8_t len); +static A_STATUS wmi_p2p_invite_req_rx(struct wmi_t *wmip, uint8_t devId, uint8_t *datap, uint8_t len); +static A_STATUS wmi_p2p_invite_rcvd_result_rx(struct wmi_t *wmip, uint8_t devId, uint8_t *datap, uint8_t len); +#endif +WMI_P2P_PROV_INFO p2p_key_val; + +#endif +#if MANUFACTURING_SUPPORT +static A_STATUS wmi_test_event_rx(struct wmi_t *wmip, uint8_t devId, uint8_t *datap, uint32_t len); +#endif +static A_STATUS wmi_errorEvent_rx(struct wmi_t *wmip, uint8_t devId, uint8_t *datap, int len); + +#define MODE_A_SUPPORT_RATE_START ((int32_t)4) +#define MODE_A_SUPPORT_RATE_STOP ((int32_t)11) + +#define MODE_GONLY_SUPPORT_RATE_START MODE_A_SUPPORT_RATE_START +#define MODE_GONLY_SUPPORT_RATE_STOP MODE_A_SUPPORT_RATE_STOP + +#define MODE_B_SUPPORT_RATE_START ((int32_t)0) +#define MODE_B_SUPPORT_RATE_STOP ((int32_t)3) + +#define MODE_G_SUPPORT_RATE_START ((int32_t)0) +#define MODE_G_SUPPORT_RATE_STOP ((int32_t)11) + +#define MODE_GHT20_SUPPORT_RATE_START ((int32_t)0) +#define MODE_GHT20_SUPPORT_RATE_STOP ((int32_t)19) + +#define MAX_NUMBER_OF_SUPPORT_RATES (MODE_GHT20_SUPPORT_RATE_STOP + 1) + +/* 802.1d to AC mapping. Refer pg 57 of WMM-test-plan-v1.2 */ +const uint8_t up_to_ac[] = { + WMM_AC_BE, WMM_AC_BK, WMM_AC_BK, WMM_AC_BE, WMM_AC_VI, WMM_AC_VI, WMM_AC_VO, WMM_AC_VO, +}; + +void *wmi_init(void *devt) +{ + struct wmi_t *wmip; + + A_REGISTER_MODULE_DEBUG_INFO(wmi); + + wmip = A_MALLOC(sizeof(struct wmi_t), MALLOC_ID_CONTEXT); + if (wmip == NULL) + { + return (NULL); + } + A_MEMZERO(wmip, sizeof(*wmip)); + A_MUTEX_INIT(&wmip->wmi_lock); + wmip->wmi_devt = devt; + wmi_qos_state_init(wmip); + + return (wmip); +} + +void wmi_qos_state_init(struct wmi_t *wmip) +{ + uint8_t i; + + if (wmip == NULL) + { + return; + } + LOCK_WMI(wmip); + + /* Initialize QoS States */ + wmip->wmi_numQoSStream = 0; + + wmip->wmi_fatPipeExists = 0; + + for (i = 0; i < WMM_NUM_AC; i++) + { + wmip->wmi_streamExistsForAC[i] = 0; + } + + UNLOCK_WMI(wmip); + + A_WMI_SET_NUMDATAENDPTS(wmip->wmi_devt, 1); +} + +void wmi_set_control_ep(struct wmi_t *wmip, HTC_ENDPOINT_ID eid) +{ + A_ASSERT(eid != ENDPOINT_UNUSED); + wmip->wmi_endpoint_id = eid; +} + +HTC_ENDPOINT_ID +wmi_get_control_ep(struct wmi_t *wmip) +{ + return (wmip->wmi_endpoint_id); +} + +void wmi_shutdown(struct wmi_t *wmip) +{ + if (wmip != NULL) + { + if (A_IS_MUTEX_VALID(&wmip->wmi_lock)) + { + A_MUTEX_DELETE(&wmip->wmi_lock); + } + A_FREE(wmip, MALLOC_ID_CONTEXT); + } +} + +/* + * performs DIX to 802.3 encapsulation for transmit packets. + * uses passed in buffer. Returns buffer or NULL if failed. + * Assumes the entire DIX header is contigous and that there is + * enough room in the buffer for a 802.3 mac header and LLC+SNAP headers. + */ +A_STATUS +wmi_dix_2_dot3(struct wmi_t *wmip, void *osbuf) +{ + uint8_t *datap; + uint16_t typeorlen; + ATH_MAC_HDR macHdr; + ATH_LLC_SNAP_HDR *llcHdr; + + UNUSED_ARGUMENT(wmip); + + A_ASSERT(osbuf != NULL); + + if (A_NETBUF_HEADROOM(osbuf) < (int32_t)(sizeof(ATH_LLC_SNAP_HDR) + sizeof(WMI_DATA_HDR))) + { + return A_NO_MEMORY; + } + + datap = A_NETBUF_DATA(osbuf); + + typeorlen = *(uint16_t *)(datap + ATH_MAC_LEN + ATH_MAC_LEN); + + if (!IS_ETHERTYPE(A_BE2CPU16(typeorlen))) + { + /* + * packet is already in 802.3 format - return success + */ + A_DPRINTF(DBG_WMI, (DBGFMT "packet already 802.3\n", DBGARG)); + return (A_OK); + } + + /* + * Save mac fields and length to be inserted later + */ + A_MEMCPY(macHdr.dstMac, datap, ATH_MAC_LEN); + A_MEMCPY(macHdr.srcMac, datap + ATH_MAC_LEN, ATH_MAC_LEN); + macHdr.typeOrLen = (uint16_t)A_CPU2BE16(A_NETBUF_LEN(osbuf) - sizeof(ATH_MAC_HDR) + sizeof(ATH_LLC_SNAP_HDR)); + + /* + * Make room for LLC+SNAP headers + */ + if (A_NETBUF_PUSH(osbuf, sizeof(ATH_LLC_SNAP_HDR)) != A_OK) + { + return A_NO_MEMORY; + } + datap = A_NETBUF_DATA(osbuf); + + A_MEMCPY(datap, &macHdr, sizeof(ATH_MAC_HDR)); + + llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(ATH_MAC_HDR)); + llcHdr->dsap = 0xAA; + llcHdr->ssap = 0xAA; + llcHdr->cntl = 0x03; + llcHdr->orgCode[0] = 0x0; + llcHdr->orgCode[1] = 0x0; + llcHdr->orgCode[2] = 0x0; + llcHdr->etherType = typeorlen; + + return (A_OK); +} + +A_STATUS +wmi_meta_add(struct wmi_t *wmip, void *osbuf, uint8_t *pVersion, void *pTxMetaS) +{ + WMI_TX_META_V3 v3In; + WMI_TX_META_V3 *pV3 = NULL; + WMI_TX_META_V5 v5In; + WMI_TX_META_V5 *pV5 = NULL; + UNUSED_ARGUMENT(wmip); + + switch (*pVersion) + { + case WMI_META_VERSION_3: + A_ASSERT(osbuf != NULL); + + if (A_NETBUF_PUSH(osbuf, WMI_MAX_TX_META_SZ) != A_OK) + { + return A_NO_MEMORY; + } + + A_MEMCPY(&v3In, pTxMetaS, sizeof(WMI_TX_META_V3)); + /* convert for any endianness */ + // no conversions for this structure + /* copy to frame */ + pV3 = (WMI_TX_META_V3 *)A_NETBUF_DATA(osbuf); + A_MEMCPY(pV3, &v3In, sizeof(WMI_TX_META_V3)); + + A_ASSERT(pVersion != NULL); + /* the version must be used to populate the meta field of the WMI_DATA_HDR */ + *pVersion = WMI_META_VERSION_3; + break; + + case WMI_META_VERSION_5: + A_ASSERT(osbuf != NULL); + + if (A_NETBUF_PUSH(osbuf, WMI_MAX_TX_META_SZ) != A_OK) + { + return A_NO_MEMORY; + } + + A_MEMCPY(&v5In, pTxMetaS, sizeof(WMI_TX_META_V5)); + /* convert for any endianness */ + // no conversions for this structure + /* copy to frame */ + pV5 = (WMI_TX_META_V5 *)A_NETBUF_DATA(osbuf); + A_MEMCPY(pV5, &v5In, sizeof(WMI_TX_META_V5)); + + A_ASSERT(pVersion != NULL); + /* the version must be used to populate the meta field of the WMI_DATA_HDR */ + *pVersion = WMI_META_VERSION_5; + break; + } + + return A_OK; +} + +/* Adds a WMI data header */ +A_STATUS +wmi_data_hdr_add(struct wmi_t *wmip, + void *osbuf, + uint8_t msgType, + boolean bMoreData, + WMI_DATA_HDR_DATA_TYPE data_type, + uint8_t metaVersion, + void *pTxMetaS) +{ + WMI_DATA_HDR *dtHdr; + // uint8_t metaVersion = 0; + A_STATUS status = A_OK; + A_ASSERT(osbuf != NULL); + + if ((status = wmi_meta_add(wmip, osbuf, &metaVersion, pTxMetaS)) != A_OK) + { + return status; + } + + if (A_NETBUF_PUSH(osbuf, sizeof(WMI_DATA_HDR)) != A_OK) + { + return A_NO_MEMORY; + } + + dtHdr = (WMI_DATA_HDR *)A_NETBUF_DATA(osbuf); + A_MEMZERO(dtHdr, sizeof(WMI_DATA_HDR)); + + WMI_DATA_HDR_SET_MSG_TYPE(dtHdr, msgType); + WMI_DATA_HDR_SET_DATA_TYPE(dtHdr, data_type); + + if (bMoreData) + { + WMI_DATA_HDR_SET_MORE_BIT(dtHdr); + } + + WMI_DATA_HDR_SET_META(dtHdr, metaVersion); + // dtHdr->rssi = 0; + // lastly convert the U16 value to LE + dtHdr->info2 = A_CPU2LE16(dtHdr->info2); + return status; +} + +/* This stuff is used when we want a simple layer-3 visibility */ +typedef PREPACK struct _iphdr +{ + uint8_t ip_ver_hdrlen FIELD_PACKED; /* version and hdr length */ + uint8_t ip_tos FIELD_PACKED; /* type of service */ + uint16_t ip_len FIELD_PACKED; /* total length */ + uint16_t ip_id FIELD_PACKED; /* identification */ + int16_t ip_off FIELD_PACKED; /* fragment offset field */ +#define IP_DF 0x4000 /* dont fragment flag */ +#define IP_MF 0x2000 /* more fragments flag */ +#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ + uint8_t ip_ttl FIELD_PACKED; /* time to live */ + uint8_t ip_p FIELD_PACKED; /* protocol */ + uint16_t ip_sum FIELD_PACKED; /* checksum */ + uint8_t ip_src[4] FIELD_PACKED; /* source and dest address */ + uint8_t ip_dst[4] FIELD_PACKED; +} POSTPACK iphdr; + +static uint8_t wmi_determine_userPriority(uint8_t *pkt, uint32_t layer2Pri) +{ + uint8_t ipPri; + iphdr *ipHdr = (iphdr *)pkt; + + /* Determine IPTOS priority */ + /* + * IP Tos format : + * (Refer Pg 57 WMM-test-plan-v1.2) + * IP-TOS - 8bits + * : DSCP(6-bits) ECN(2-bits) + * : DSCP - P2 P1 P0 X X X + * where (P2 P1 P0) form 802.1D + */ + ipPri = ipHdr->ip_tos >> 5; + ipPri &= 0x7; + + if ((layer2Pri & 0x7) > ipPri) + return ((uint8_t)layer2Pri & 0x7); + else + return ipPri; +} + +uint8_t wmi_implicit_create_pstream(struct wmi_t *wmip, void *osbuf, uint32_t layer2Priority, boolean wmmEnabled) +{ + uint8_t *datap; + uint8_t trafficClass = WMM_AC_BE; + uint16_t ipType = IP_ETHERTYPE; + WMI_DATA_HDR *dtHdr; + uint8_t userPriority; + uint32_t metasize; + ATH_LLC_SNAP_HDR *llcHdr; + + // WMI_CREATE_PSTREAM_CMD cmd; + UNUSED_ARGUMENT(wmip); + + A_ASSERT(osbuf != NULL); + + datap = A_NETBUF_DATA(osbuf); + dtHdr = (WMI_DATA_HDR *)datap; + metasize = (WMI_DATA_HDR_GET_META(dtHdr)) ? WMI_MAX_TX_META_SZ : 0; + + if (!wmmEnabled) + { + /* If WMM is disabled all traffic goes as BE traffic */ + userPriority = 0; + } + else + { + llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(WMI_DATA_HDR) + metasize + sizeof(ATH_MAC_HDR)); + + if (llcHdr->etherType == A_CPU2BE16(ipType)) + { + /* Extract the endpoint info from the TOS field in the IP header */ + + userPriority = wmi_determine_userPriority(((uint8_t *)llcHdr) + sizeof(ATH_LLC_SNAP_HDR), layer2Priority); + } + else + { + userPriority = layer2Priority & 0x7; + } + } + + trafficClass = (up_to_ac[userPriority & 0x7]); + + WMI_DATA_HDR_SET_UP(dtHdr, userPriority); + + return trafficClass; +} + +/* + * performs 802.3 to DIX encapsulation for received packets. + * Assumes the entire 802.3 header is contigous. + */ +A_STATUS +wmi_dot3_2_dix(void *osbuf) +{ + uint8_t *datap; + ATH_MAC_HDR macHdr; + ATH_LLC_SNAP_HDR *llcHdr; + + A_ASSERT(osbuf != NULL); + datap = A_NETBUF_DATA(osbuf); + + A_MEMCPY(&macHdr, datap, sizeof(ATH_MAC_HDR)); + llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(ATH_MAC_HDR)); + macHdr.typeOrLen = llcHdr->etherType; + + if (A_NETBUF_PULL(osbuf, sizeof(ATH_LLC_SNAP_HDR)) != A_OK) + { + return A_NO_MEMORY; + } + + datap = A_NETBUF_DATA(osbuf); + + A_MEMCPY(datap, &macHdr, sizeof(ATH_MAC_HDR)); + + return (A_OK); +} + +/* + * Removes a WMI data header + */ +A_STATUS +wmi_data_hdr_remove(struct wmi_t *wmip, void *osbuf) +{ + UNUSED_ARGUMENT(wmip); + A_ASSERT(osbuf != NULL); + + return (A_NETBUF_PULL(osbuf, sizeof(WMI_DATA_HDR))); +} + +static A_STATUS wmi_test_ev_length(uint16_t id, int32_t len) +{ + uint16_t i; + const struct + { + uint16_t id; + uint16_t len; + } length_array[] = {{WMI_BSSINFO_EVENTID, sizeof(WMI_BSS_INFO_HDR)}, + {WMI_CONNECT_EVENTID, sizeof(WMI_CONNECT_EVENT)}, + {WMI_GET_CHANNEL_LIST_CMDID, sizeof(WMI_CHANNEL_LIST_REPLY)}, + {WMI_READY_EVENTID, sizeof(WMI_READY_EVENT)}, + {WMI_DISCONNECT_EVENTID, sizeof(WMI_DISCONNECT_EVENT)}, + {WMI_BSSINFO_EVENTID, sizeof(WMI_BSS_INFO_HDR)}, + {WMI_REGDOMAIN_EVENTID, sizeof(WMI_REG_DOMAIN_EVENT)}, + {WMI_GET_PMK_EVENTID, WMI_PMK_LEN}, + {WMI_TKIP_MICERR_EVENTID, sizeof(WMI_TKIP_MICERR_EVENT)}, + {WMI_PEER_NODE_EVENTID, sizeof(WMI_PEER_NODE_EVENT)}}; + + for (i = 0; i < sizeof(length_array) / sizeof(length_array[0]); i++) + { + if (id == length_array[i].id) + { + if (len < length_array[i].len) + { + return A_ERROR; + } + + return A_OK; + } + } + + return A_OK; // could not find entry for eventID +} + +/* + * WMI Extended Event received from Target. + */ +A_STATUS +wmi_control_rx_xtnd(struct wmi_t *wmip, uint8_t devId, void *osbuf) +{ + WMIX_CMD_HDR *cmd; + uint16_t id; + uint8_t *datap; + uint32_t len; + A_STATUS status = A_OK; + + if (A_NETBUF_LEN(osbuf) < sizeof(WMIX_CMD_HDR)) + { + A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 1\n", DBGARG)); + wmip->wmi_stats.cmd_len_err++; + return A_ERROR; + } + + cmd = (WMIX_CMD_HDR *)A_NETBUF_DATA(osbuf); + id = cmd->commandId; + + if (A_NETBUF_PULL(osbuf, sizeof(WMIX_CMD_HDR)) != A_OK) + { + A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 2\n", DBGARG)); + wmip->wmi_stats.cmd_len_err++; + return A_ERROR; + } + + datap = A_NETBUF_DATA(osbuf); + len = A_NETBUF_LEN(osbuf); + + switch (id) + { + case (WMIX_DBGLOG_EVENTID): + A_WMIX_DBGLOG_EVENT(wmip, devId, datap, len); + break; + case (WMIX_GPIO_DATA_EVENTID): + A_WMIX_GPIO_DATA_EVENT(wmip, devId, datap, len); + break; + +#if ENABLE_KF_PERFORMANCE + case (WMIX_PFM_DATA_EVENTID): + A_WMIX_PFM_DATA_EVENT(wmip, devId, datap, len); + break; + case (WMIX_PFM_DATA_DONE_EVENTID): + A_WMIX_PFM_DATA_DONE_EVENT(wmip, devId, datap, len); + break; +#endif + + case (WMIX_HB_CHALLENGE_RESP_EVENTID): + WMIX_HB_CHALLENGE_RESP_RX(wmip->wmi_devt, devId, datap, len); + break; + + default: + A_DPRINTF(DBG_WMI | DBG_ERROR, (DBGFMT "Unknown id 0x%x\n", DBGARG, id)); + wmip->wmi_stats.cmd_id_err++; + status = A_ERROR; + break; + } + + return status; +} + +/* + * Control Path + */ + +A_STATUS +wmi_control_rx(struct wmi_t *wmip, void *osbuf) +{ + // printf("wmi_control_rx.\n"); + WMI_CMD_HDR *cmd; + uint16_t id; + uint8_t *datap; + int32_t len; + A_STATUS status = A_OK; + uint8_t spareBuf = 0; + WMI_BSS_INFO_HDR2 bih2; + WMI_BSS_INFO_HDR *bih; + union + { + void *void_ev; // used for initialization only + WMI_CONNECT_EVENT *conn_ev; + WMI_CHANNEL_LIST_REPLY *chan_ev; + WMI_READY_EVENT *ready_ev; + WMI_DISCONNECT_EVENT *disc_ev; + WMI_REG_DOMAIN_EVENT *regdom_ev; + WMI_SCAN_COMPLETE_EVENT *scan_comp_ev; + WMI_TKIP_MICERR_EVENT *tkip_err_ev; + WMI_PEER_NODE_EVENT *peer_ev; + } stackU; + uint8_t devId; + +#define VOID_EV (stackU.void_ev) +#define CONN_EV (stackU.conn_ev) +#define CHAN_EV (stackU.chan_ev) +#define READY_EV (stackU.ready_ev) +#define DISC_EV (stackU.disc_ev) +#define REG_EV (stackU.regdom_ev) +#define SCAN_EV (stackU.scan_comp_ev) +#define TKIP_EV (stackU.tkip_err_ev) +#define PEER_EV (stackU.peer_ev) + + A_ASSERT(osbuf != NULL); + if (A_NETBUF_LEN(osbuf) < sizeof(WMI_CMD_HDR)) + { + A_NETBUF_FREE(osbuf); + A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 1\n", DBGARG)); + wmip->wmi_stats.cmd_len_err++; + return A_ERROR; + } + + cmd = (WMI_CMD_HDR *)A_NETBUF_DATA(osbuf); + id = A_LE2CPU16(cmd->commandId); + + cmd->info1 = A_LE2CPU16(cmd->info1); + devId = WMI_GET_DEVICE_ID(cmd->info1); + + if (A_NETBUF_PULL(osbuf, sizeof(WMI_CMD_HDR)) != A_OK) + { + A_NETBUF_FREE(osbuf); + A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 2\n", DBGARG)); + wmip->wmi_stats.cmd_len_err++; + return A_ERROR; + } + + datap = A_NETBUF_DATA(osbuf); + VOID_EV = datap; + len = (int32_t)A_NETBUF_LEN(osbuf); + + if (A_OK != wmi_test_ev_length(id, len)) + { + A_ASSERT(0); + } + + WMI_DEBUG_RX_EVENT(id, osbuf); + + switch (id) + { + case (WMI_GET_CHANNEL_LIST_CMDID): + A_WMI_CHANNELLIST_RX(wmip->wmi_devt, devId, (int8_t)CHAN_EV->numChannels, (void*)CHAN_EV->channelList); + break; + case (WMI_GET_BITRATE_CMDID): + { + A_WMI_GET_BITRATE_EVEVT(wmip->wmi_devt, devId, datap); + } + break; + case (WMI_GET_TEMPERATURE_REPLY_EVENTID): + { + A_WMI_GET_TEMPERATURE_REPLY(wmip->wmi_devt, datap, len); + }; + break; + case (WMI_GET_COUNTRY_CODE_REPLY_EVENTID): + { + // printf("wmi code reply.\n"); + A_WMI_GET_COUNTRY_CODE_REPLY(wmip->wmi_devt, datap, len); + }; + break; + case (WMI_PARAM_SET_REPLY_EVENTID): + A_WMI_SET_PARAM_REPLY(wmip->wmi_devt, datap); + break; + case (WMI_READY_EVENTID): + A_WMI_READY_EVENT(wmip->wmi_devt, devId, READY_EV->macaddr, READY_EV->phyCapability, + A_LE2CPU32(READY_EV->sw_version), A_LE2CPU32(READY_EV->abi_version)); + A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len); + break; + case (WMI_CONNECT_EVENTID): + // convert for native endianness + CONN_EV->channel = A_LE2CPU16(stackU.conn_ev->channel); + CONN_EV->listenInterval = A_LE2CPU16(CONN_EV->listenInterval); + CONN_EV->beaconInterval = A_LE2CPU16(CONN_EV->beaconInterval); + CONN_EV->networkType = A_LE2CPU32(CONN_EV->networkType); + A_WMI_CONNECT_EVENT(wmip->wmi_devt, devId, CONN_EV->channel, CONN_EV->bssid, CONN_EV->listenInterval, + CONN_EV->beaconInterval, (NETWORK_TYPE)CONN_EV->networkType, CONN_EV->beaconIeLen, + CONN_EV->assocReqLen, CONN_EV->assocRespLen, CONN_EV->assocInfo); + + A_WMI_SEND_GENERIC_EVENT_TO_APP(wmip->wmi_devt, id, datap, len); + break; + case (WMI_DISCONNECT_EVENTID): + A_WMI_DISCONNECT_EVENT(wmip->wmi_devt, devId, DISC_EV->disconnectReason, DISC_EV->bssid, + DISC_EV->assocRespLen, DISC_EV->assocInfo, + A_LE2CPU16(DISC_EV->protocolReasonStatus)); + A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len); + break; + case (WMI_PEER_NODE_EVENTID): + /* this event will be sent from device to indicate 4 way success + */ + // status = wmi_rsna_4way_rx(wmip, datap, len); + if (PEER_EV->eventCode == PEER_NODE_JOIN_EVENT) + { + /* need to call an custom event which will give a callback + * to the application this event will indicate to application + * 4 way handshake success from the firmware + */ + A_WMI_RSNA_SUCCESS_EVENT(wmip->wmi_devt, devId, PEER_FIRST_NODE_JOIN_EVENT); + } + break; + case (WMI_BSSINFO_EVENTID): + A_DPRINTF(DBG_WMI, (DBGFMT "WMI_BSSINFO_EVENTID\n", DBGARG)); + { + /* + * convert WMI_BSS_INFO_HDR2 to WMI_BSS_INFO_HDR + * Take a local copy of the WMI_BSS_INFO_HDR2 from the wmi buffer + * and reconstruct the WMI_BSS_INFO_HDR in its place + */ + A_MEMCPY(&bih2, datap, sizeof(WMI_BSS_INFO_HDR2)); + + A_NETBUF_PUSH(osbuf, 4); + datap = A_NETBUF_DATA(osbuf); + len = (int32_t)A_NETBUF_LEN(osbuf); + bih = (WMI_BSS_INFO_HDR *)datap; + + bih->channel = A_LE2CPU16(bih2.channel); + bih->frameType = bih2.frameType; + bih->snr = bih2.snr; + bih->rssi = (int16_t)(bih2.snr - 95); + bih->ieMask = A_LE2CPU16(bih2.ieMask); + A_MEMCPY(bih->bssid, bih2.bssid, ATH_MAC_LEN); + + if (bih->rssi <= 0) + { + A_WMI_BSSINFO_EVENT_RX(wmip->wmi_devt, devId, datap, len); + A_WMI_SEND_GENERIC_EVENT_TO_APP(wmip->wmi_devt, id, datap, len); + } + } + break; + case (WMI_REGDOMAIN_EVENTID): + A_WMI_REGDOMAIN_EVENT(wmip->wmi_devt, devId, A_LE2CPU32(REG_EV->regDomain)); + break; + case (WMI_SCAN_COMPLETE_EVENTID): + A_WMI_SCANCOMPLETE_EVENT(wmip->wmi_devt, devId, (A_STATUS)A_LE2CPU32(SCAN_EV->status)); + A_WMI_SEND_EVENT_TO_APP(wmip->wmi_devt, id, datap, len); + break; + case (WMI_CMDERROR_EVENTID): + status = wmi_errorEvent_rx(wmip, devId, datap, len); + break; + case (WMI_REPORT_STATISTICS_EVENTID): + A_WMI_TARGETSTATS_EVENT(wmip->wmi_devt, devId, datap, (uint32_t)len); + break; + case (WMI_EXTENSION_EVENTID): + status = wmi_control_rx_xtnd(wmip, devId, osbuf); + break; + case (WMI_GET_PMK_EVENTID): + A_WMI_GET_PMK_RX(wmip->wmi_devt, devId, datap); + break; + case (WMI_STORERECALL_STORE_EVENTID): + A_WMI_STORERECALL_EVENT_RX(wmip->wmi_devt, devId, datap, len, osbuf); + break; + + /* new store-recall event */ + case (WMI_STORERECALL_START_EVENTID): + A_WMI_STORERECALL_START_EVENT_RX(wmip->wmi_devt, devId, datap, len, osbuf); + break; + case (WMI_HOST_DSET_STORE_EVENTID): + A_WMI_HOST_DSET_EVENT_STORE_RX(wmip->wmi_devt, devId, datap, len, osbuf); + break; + case (WMI_HOST_DSET_READ_EVENTID): + A_WMI_HOST_DSET_EVENT_READ_RX(wmip->wmi_devt, devId, datap, len, osbuf); + break; + case (WMI_HOST_DSET_CREATE_EVENTID): + A_WMI_HOST_DSET_EVENT_CREATE_RX(wmip->wmi_devt, devId, datap, len, osbuf); + break; + case (WMI_HOST_DSET_LARGE_WRITE_EVENTID): + A_WMI_HOST_DSET_EVENT_WRITE_RX(wmip->wmi_devt, devId, datap, len, osbuf); + break; + case (WMI_HOST_DSET_LARGE_READ_EVENTID): + A_WMI_HOST_DSET_EVENT_READBACK_RX(wmip->wmi_devt, devId, datap, len, osbuf); + break; + case (WMI_HOST_DSET_SYNC_EVENTID): + A_WMI_HOST_DSET_EVENT_SYNC_RX(wmip->wmi_devt, devId, datap, len, osbuf); + break; + case (WMI_DSET_OP_EVENTID): + A_WMI_DSET_EVENT_OP_RX(wmip->wmi_devt, devId, datap, len, osbuf); + break; + /* */ + + case (WMI_WPS_PROFILE_EVENTID): + A_WMI_WPS_PROFILE_EVENT_RX(wmip->wmi_devt, devId, datap, len, osbuf); + spareBuf = 1; /* prevent buffer from A_NETBUF_FREE() below */ + break; +#if WLAN_CONFIG_11N_AGGR_SUPPORT + case (WMI_ADDBA_REQ_EVENTID): + A_WMI_AGGR_RECV_ADDBA_REQ_EVT(wmip->wmi_devt, devId, (WMI_ADDBA_REQ_EVENT *)datap); + break; + case (WMI_DELBA_REQ_EVENTID): + A_WMI_AGGR_RECV_DELBA_REQ_EVT(wmip->wmi_devt, devId, (WMI_DELBA_EVENT *)datap); + break; +#endif + case (WMI_TKIP_MICERR_EVENTID): + A_WMI_TKIP_MICERR_EVENT(wmip->wmi_devt, devId, TKIP_EV->keyid, TKIP_EV->ismcast); + break; + case (WMI_SOCKET_RESPONSE_EVENTID): + status = A_WMI_SOCK_RESPONSE_EVENT_RX(wmip->wmi_devt, devId, datap, len, osbuf); + spareBuf = 1; /* prevent buffer from A_NETBUF_FREE() below */ + break; + +#if ENABLE_P2P_MODE + case WMI_P2P_LIST_PERSISTENT_NETWORK_EVENTID: + status = wmi_p2p_list_peristent_network(wmip, devId, datap, len); + break; + case WMI_P2P_GO_NEG_RESULT_EVENTID: + status = wmi_p2p_goneg_result_event_rx(wmip, devId, datap, len); + break; + + case WMI_P2P_NODE_LIST_EVENTID: + status = wmi_p2p_node_list_event_rx(wmip, devId, datap, len); + break; + + case WMI_P2P_REQ_TO_AUTH_EVENTID: + status = wmi_p2p_req_auth_event_rx(wmip, devId, datap, len); + break; + + case WMI_P2P_PROV_DISC_RESP_EVENTID: + status = wmi_p2p_prov_disc_resp_rx(wmip, devId, datap, len); + break; + + case WMI_P2P_PROV_DISC_REQ_EVENTID: + status = wmi_p2p_prov_disc_req_rx(wmip, devId, datap, len); + break; + + case WMI_P2P_INVITE_REQ_EVENTID: + status = wmi_p2p_invite_req_rx(wmip, devId, datap, len); + break; + + case WMI_P2P_INVITE_RCVD_RESULT_EVENTID: + status = wmi_p2p_invite_rcvd_result_rx(wmip, devId, datap, len); + break; + + case WMI_P2P_INVITE_SENT_RESULT_EVENTID: + status = wmi_p2p_invite_sent_result_rx(wmip, devId, datap, len); + break; + + case WMI_P2P_SDPD_RX_EVENTID: + status = wmi_p2p_sdpd_event_rx(wmip, devId, datap, len); + break; + +#endif +#if MANUFACTURING_SUPPORT + case WMI_TEST_EVENTID: + status = wmi_test_event_rx(wmip, devId, datap, len); + break; +#endif + case WMI_RX_PROBE_REQ_EVENTID: + A_WMI_PROBE_REQ_EVENT_RX(wmip->wmi_devt, datap, len); + break; + + case WMI_WLAN_WPS_INIT_KEY_EVENTID: + A_WMI_WLAN_WPS_INIT_REPLY_RX(wmip->wmi_devt, datap, len); + break; + + default: + if (A_OK != (status = A_WMI_EVENT(id, wmip->wmi_devt, datap, len, osbuf))) + { + A_DPRINTF(DBG_WMI | DBG_ERROR, (DBGFMT "Unknown id 0x%x\n", DBGARG, id)); + wmip->wmi_stats.cmd_id_err++; + status = A_ERROR; + } + break; + } + /* spareBuf != 0 if the packet handler needed to keep the buffer. + * it becomes the handler's responsibility to free it. + */ + if (spareBuf == 0) + { + A_NETBUF_FREE(osbuf); + } + + return status; +} + +/* + * Target is reporting a programming error. This is for + * developer aid only. Target only checks a few common violations + * and it is responsibility of host to do all error checking. + * Behavior of target after wmi error event is undefined. + * A reset is recommended. + */ +static A_STATUS wmi_errorEvent_rx(struct wmi_t *wmip, uint8_t devId, uint8_t *datap, int len) +{ + WMI_CMD_ERROR_EVENT *ev; + UNUSED_ARGUMENT(wmip); + UNUSED_ARGUMENT(len); + UNUSED_ARGUMENT(devId); + ev = (WMI_CMD_ERROR_EVENT *)datap; + AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Programming Error: cmd=%d ", ev->commandId)); + switch (ev->errorCode) + { + case (INVALID_PARAM): + AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Illegal Parameter\n")); + break; + case (ILLEGAL_STATE): + AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Illegal State\n")); + break; + case (INTERNAL_ERROR): + AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Internal Error\n")); + break; + case (STACK_ERROR): + AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("TCP/IP stack not present on Target\n")); + A_ASSERT(0); + } + + return A_OK; +} + +/* + * Called to send a wmi command. Command specific data is already built + * on osbuf and current osbuf->data points to it. + */ +A_STATUS +wmi_cmd_send(struct wmi_t *wmip, void *osbuf, WMI_COMMAND_ID cmdId, WMI_SYNC_FLAG syncflag) +{ + A_STATUS status = A_OK; + WMI_CMD_HDR *cHdr; + HTC_ENDPOINT_ID eid = wmip->wmi_endpoint_id; + + A_ASSERT(osbuf != NULL); + + if (syncflag >= END_WMIFLAG) + { + A_NETBUF_FREE(osbuf); + return A_EINVAL; + } + + WMI_DEBUG_TX_COMMAND(cmdId, osbuf); + +#if 0 + WMI_SOCKET_CMD *cmd; + cmd = (WMI_SOCKET_CMD *)A_NETBUF_DATA(osbuf); + printf("cmd type is %d.\n",cmd->cmd_type); +#endif + +#if WLAN_CONFIG_ENABLE_WMI_SYNC + if ((syncflag == SYNC_BEFORE_WMIFLAG) || (syncflag == SYNC_BOTH_WMIFLAG)) + { + /* + * We want to make sure all data currently queued is transmitted before + * the cmd execution. Establish a new sync point. + */ + wmi_sync_point(wmip); + } +#endif + + if (A_NETBUF_PUSH(osbuf, sizeof(WMI_CMD_HDR)) != A_OK) + { + A_NETBUF_FREE(osbuf); + return A_NO_MEMORY; + } + + cHdr = (WMI_CMD_HDR *)A_NETBUF_DATA(osbuf); + cHdr->commandId = A_CPU2LE16((uint16_t)cmdId); + + WMI_SET_DEVICE_ID(cHdr, wmip->deviceid); + cHdr->info1 = A_CPU2LE16(cHdr->info1); // added for virtual interface + + A_WMI_CONTROL_TX(wmip->wmi_devt, osbuf, eid); + +#if WLAN_CONFIG_ENABLE_WMI_SYNC + if ((syncflag == SYNC_AFTER_WMIFLAG) || (syncflag == SYNC_BOTH_WMIFLAG)) + { + /* + * We want to make sure all new data queued waits for the command to + * execute. Establish a new sync point. + */ + wmi_sync_point(wmip); + } +#endif + + return (status); +} + +#if ENABLE_AP_MODE +A_STATUS +wmi_ap_set_param(struct wmi_t *wmip, void *data) +{ + ATH_AP_PARAM_STRUCT *ap_param = (ATH_AP_PARAM_STRUCT *)data; + union + { + uint8_t hidden_ssid_flag; + WMI_AP_CONN_INACT_CMD conn_inact_cmd; + WMI_BEACON_INT_CMD beacon_int_cmd; + WMI_AP_SET_DTIM_CMD set_dtim_cmd; + WMI_AP_PSBUF_OFFLOAD_CMD psbuf_offload_cmd; + } stackU; + + switch (ap_param->cmd_subset) + { + case AP_SUB_CMD_HIDDEN_FLAG: + { + stackU.hidden_ssid_flag = HIDDEN_SSID_TRUE; + return (wmi_cmd_start(wmip, &stackU.hidden_ssid_flag, WMI_AP_HIDDEN_SSID_CMDID, + sizeof(WMI_AP_HIDDEN_SSID_CMD))); + } + + case AP_SUB_CMD_INACT_TIME: + { + A_MEMZERO(&stackU.conn_inact_cmd, sizeof(WMI_AP_CONN_INACT_CMD)); + stackU.conn_inact_cmd.period = A_CPU2LE32(*(uint32_t *)(ap_param->data)); + return ( + wmi_cmd_start(wmip, &stackU.conn_inact_cmd, WMI_AP_CONN_INACT_CMDID, sizeof(WMI_AP_CONN_INACT_CMD))); + } + + case AP_SUB_CMD_BCON_INT: + { + A_MEMZERO(&stackU.beacon_int_cmd, sizeof(WMI_BEACON_INT_CMD)); + stackU.beacon_int_cmd.beaconInterval = A_CPU2LE16((*(uint16_t *)(ap_param->data))); + return (wmi_cmd_start(wmip, &stackU.conn_inact_cmd, WMI_SET_BEACON_INT_CMDID, sizeof(WMI_BEACON_INT_CMD))); + } + + case AP_SUB_CMD_DTIM_INT: + { + A_MEMZERO(&stackU.set_dtim_cmd, sizeof(WMI_AP_SET_DTIM_CMD)); + stackU.set_dtim_cmd.dtim = *(uint8_t *)(ap_param->data); + return (wmi_cmd_start(wmip, &stackU.conn_inact_cmd, WMI_AP_SET_DTIM_CMDID, sizeof(WMI_AP_SET_DTIM_CMD))); + } + case AP_SUB_CMD_PSBUF: + { + A_MEMZERO(&stackU.psbuf_offload_cmd, sizeof(WMI_AP_PSBUF_OFFLOAD_CMD)); + stackU.psbuf_offload_cmd.enable = ((uint8_t *)ap_param->data)[0]; + stackU.psbuf_offload_cmd.psBufCount = ((uint8_t *)ap_param->data)[1]; + return (wmi_cmd_start(wmip, &stackU.conn_inact_cmd, WMI_AP_PSBUF_OFFLOAD_CMDID, + sizeof(WMI_AP_PSBUF_OFFLOAD_CMD))); + } + default: + break; + } + + return A_OK; +} +#endif + +#if WLAN_CONFIG_ENABLE_WMI_SYNC + +A_STATUS +wmi_dataSync_send(struct wmi_t *wmip, void *osbuf, HTC_ENDPOINT_ID eid) +{ + WMI_DATA_HDR *dtHdr; + + A_ASSERT(eid != wmip->wmi_endpoint_id); + A_ASSERT(osbuf != NULL); + + if (A_NETBUF_PUSH(osbuf, sizeof(WMI_DATA_HDR)) != A_OK) + { + return A_NO_MEMORY; + } + + dtHdr = (WMI_DATA_HDR *)A_NETBUF_DATA(osbuf); + dtHdr->info = (SYNC_MSGTYPE & WMI_DATA_HDR_MSG_TYPE_MASK) << WMI_DATA_HDR_MSG_TYPE_SHIFT; + + A_DPRINTF(DBG_WMI, (DBGFMT "Enter - eid %d\n", DBGARG, eid)); + + return (A_WMI_CONTROL_TX(wmip->wmi_devt, osbuf, eid)); +} + +typedef struct _WMI_DATA_SYNC_BUFS +{ + uint8_t trafficClass; + void *osbuf; +} WMI_DATA_SYNC_BUFS; + +static A_STATUS wmi_sync_point(struct wmi_t *wmip) +{ + void *cmd_osbuf; + WMI_SYNC_CMD *cmd; + WMI_DATA_SYNC_BUFS dataSyncBufs[WMM_NUM_AC]; + uint8_t i, numPriStreams = 0; + A_STATUS status = A_OK; + + A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); + + memset(dataSyncBufs, 0, sizeof(dataSyncBufs)); + + /* lock out while we walk through the priority list and assemble our local array */ + LOCK_WMI(wmip); + + for (i = 0; i < WMM_NUM_AC; i++) + { + if (wmip->wmi_fatPipeExists & (1 << i)) + { + numPriStreams++; + dataSyncBufs[numPriStreams - 1].trafficClass = i; + } + } + + UNLOCK_WMI(wmip); + + /* dataSyncBufs is now filled with entries (starting at index 0) containing valid streamIDs */ + + do + { + /* + * We allocate all network buffers needed so we will be able to + * send all required frames. + */ + cmd_osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); + if (cmd_osbuf == NULL) + { + status = A_NO_MEMORY; + break; + } + + A_NETBUF_PUT(cmd_osbuf, sizeof(*cmd)); + + cmd = (WMI_SYNC_CMD *)(A_NETBUF_DATA(cmd_osbuf)); + A_MEMZERO(cmd, sizeof(*cmd)); + + /* In the SYNC cmd sent on the control Ep, send a bitmap of the data + * eps on which the Data Sync will be sent + */ + cmd->dataSyncMap = wmip->wmi_fatPipeExists; + + for (i = 0; i < numPriStreams; i++) + { + dataSyncBufs[i].osbuf = A_NETBUF_ALLOC(0); + if (dataSyncBufs[i].osbuf == NULL) + { + status = A_NO_MEMORY; + break; + } + } // end for + + /* if Buffer allocation for any of the dataSync fails, then do not + * send the Synchronize cmd on the control ep + */ + if (A_FAILED(status)) + { + break; + } + + /* + * Send sync cmd followed by sync data messages on all endpoints being + * used + */ + status = wmi_cmd_send(wmip, cmd_osbuf, WMI_SYNCHRONIZE_CMDID, NO_SYNC_WMIFLAG); + + if (A_FAILED(status)) + { + break; + } + /* cmd buffer sent, we no longer own it */ + cmd_osbuf = NULL; + + for (i = 0; i < numPriStreams; i++) + { + A_ASSERT(dataSyncBufs[i].osbuf != NULL); + status = wmi_dataSync_send(wmip, dataSyncBufs[i].osbuf, + A_WMI_Ac2EndpointID(wmip->wmi_devt, dataSyncBufs[i].trafficClass)); + + if (A_FAILED(status)) + { + break; + } + /* we don't own this buffer anymore, NULL it out of the array so it + * won't get cleaned up */ + dataSyncBufs[i].osbuf = NULL; + } // end for + + } while (false); + + /* free up any resources left over (possibly due to an error) */ + + if (cmd_osbuf != NULL) + { + A_NETBUF_FREE(cmd_osbuf); + } + + for (i = 0; i < numPriStreams; i++) + { + if (dataSyncBufs[i].osbuf != NULL) + { + A_NETBUF_FREE(dataSyncBufs[i].osbuf); + } + } + + return (status); +} +#endif /* WLAN_CONFIG_ENABLE_WMI_SYNC */ + +A_STATUS +wmi_storerecall_recall_cmd(struct wmi_t *wmip, uint32_t length, void *pData) +{ + void *osbuf; + WMI_STORERECALL_RECALL_CMD *p; + uint32_t msgLength = sizeof(WMI_STORERECALL_RECALL_CMD) - sizeof(uint8_t); + + osbuf = A_NETBUF_ALLOC((int32_t)msgLength); + if (osbuf == NULL) + { + return A_NO_MEMORY; + } + + A_NETBUF_PUT(osbuf, (int32_t)msgLength); + + p = (WMI_STORERECALL_RECALL_CMD *)(A_NETBUF_DATA(osbuf)); + + p->length = A_CPU2LE32(length); + // A_MEMCPY(&p->data[0], pData, length); + /* here we append the payload to the msg rather than copy it. this is a + * memory and CPU optimization as the payload can be very large. + */ + A_NETBUF_APPEND_FRAGMENT(osbuf, pData, length); + + return (wmi_cmd_send(wmip, osbuf, WMI_STORERECALL_RECALL_CMDID, NO_SYNC_WMIFLAG)); +} + +A_STATUS +wmi_bssfilter_cmd(struct wmi_t *wmip, uint8_t filter, uint32_t ieMask) +{ + WMI_BSS_FILTER_CMD bssFilterParam = {0}; + + bssFilterParam.bssFilter = filter; + bssFilterParam.ieMask = A_CPU2LE32(ieMask); + + return wmi_cmd_start(wmip, &bssFilterParam, WMI_SET_BSS_FILTER_CMDID, sizeof(bssFilterParam)); +} + +#if ENABLE_STACK_OFFLOAD +A_STATUS wmi_socket_cmd(struct wmi_t *wmip, uint32_t cmd_type, void *pData, uint32_t length) +{ + WMI_SOCKET_CMD *cmd; + + if (pData == NULL || length < sizeof(WMI_SOCKET_CMD)) + { + // Should not happen + A_ASSERT(0); + } + + cmd = (WMI_SOCKET_CMD *)pData; + cmd->cmd_type = A_CPU2LE32(cmd_type); + cmd->length = A_CPU2LE32((length - sizeof(WMI_SOCKET_CMD))); + + return (wmi_cmd_start(wmip, pData, WMI_SOCKET_CMDID, length)); +} +#endif + +#if MANUFACTURING_SUPPORT +static A_STATUS wmi_test_event_rx(struct wmi_t *wmip, uint8_t devId, uint8_t *datap, uint32_t len) +{ + UNUSED_ARGUMENT(devId); + A_WMI_TEST_CMD_EVENT_RX(wmip->wmi_devt, devId, datap, len); + return A_OK; +} +#endif + +#if ENABLE_P2P_MODE + +static A_STATUS wmi_p2p_goneg_result_event_rx(struct wmi_t *wmip, uint8_t devId, uint8_t *datap, uint8_t len) +{ + // A_WMI_P2P_GO_NEG_EVENT(wmip->wmi_devt, datap, len); + A_WMI_P2P_GO_NEG_EVENT(wmip->wmi_devt, devId, datap, len, &p2p_key_val); + return A_OK; +} + +static A_STATUS wmi_p2p_list_peristent_network(struct wmi_t *wmip, uint8_t devId, uint8_t *datap, uint8_t len) +{ + A_WMI_P2P_PERSISTENT_LIST_NETWORK_EVENT(wmip->wmi_devt, devId, datap, len); + return A_OK; +} + +static A_STATUS wmi_p2p_req_auth_event_rx(struct wmi_t *wmip, uint8_t devId, uint8_t *datap, uint32_t len) +{ + A_WMI_P2P_REQ_AUTH_EVENT(wmip->wmi_devt, devId, datap, len); + return A_OK; +} + +static A_STATUS wmi_p2p_node_list_event_rx(struct wmi_t *wmip, uint8_t devId, uint8_t *datap, uint32_t len) +{ + A_WMI_P2P_NODE_LIST_EVENT(wmip->wmi_devt, devId, datap, len); + return A_OK; +} + +static A_STATUS wmi_p2p_prov_disc_resp_rx(struct wmi_t *wmip, uint8_t devId, uint8_t *datap, uint8_t len) +{ + A_WMI_GET_P2P_CTX(wmip->wmi_devt, devId, datap, len); + return A_OK; +} + +static A_STATUS wmi_p2p_prov_disc_req_rx(struct wmi_t *wmip, uint8_t devId, uint8_t *datap, uint8_t len) +{ + A_WMI_P2P_PROV_DISC_REQ(wmip->wmi_devt, devId, datap, len); + return A_OK; +} +#if 1 // KK +static A_STATUS wmi_p2p_sdpd_event_rx(struct wmi_t *wmip, uint8_t devId, uint8_t *datap, uint8_t len) +{ + A_WMI_P2P_SERV_DISC_REQ(wmip->wmi_devt, devId, datap, len); + return A_OK; +} + +static A_STATUS wmi_p2p_invite_req_rx(struct wmi_t *wmip, uint8_t devId, uint8_t *datap, uint8_t len) +{ + A_WMI_P2P_INVITE_REQ_RX(wmip->wmi_devt, devId, datap, len); + return A_OK; +} + +static A_STATUS wmi_p2p_invite_rcvd_result_rx(struct wmi_t *wmip, uint8_t devId, uint8_t *datap, uint8_t len) +{ + A_WMI_P2P_INVITE_RCVD_RESULT_EVENT(wmip->wmi_devt, devId, datap, len); + return A_OK; +} +#endif + +static A_STATUS wmi_p2p_invite_sent_result_rx(struct wmi_t *wmip, uint8_t devId, uint8_t *datap, uint8_t len) +{ + A_WMI_P2P_INVITE_SENT_RESULT_EVENT(wmip->wmi_devt, devId, datap, len); + return A_OK; +} + +A_STATUS wmi_sdpd_send_cmd(struct wmi_t *wmip, WMI_P2P_SDPD_TX_CMD *buf) +{ + void *osbuf; + WMI_P2P_SDPD_TX_CMD *sdpd_tx_cmd; + A_STATUS status; + + osbuf = A_NETBUF_ALLOC(sizeof(WMI_P2P_SDPD_TX_CMD)); + if (osbuf == NULL) + { + return A_NO_MEMORY; + } + + A_NETBUF_PUT(osbuf, sizeof(WMI_P2P_SDPD_TX_CMD)); + + sdpd_tx_cmd = (WMI_P2P_SDPD_TX_CMD *)(A_NETBUF_DATA(osbuf)); + A_MEMZERO(sdpd_tx_cmd, sizeof(WMI_P2P_SDPD_TX_CMD)); + A_MEMCPY(sdpd_tx_cmd, buf, sizeof(WMI_P2P_SDPD_TX_CMD)); + sdpd_tx_cmd->freq = A_CPU2LE16(sdpd_tx_cmd->freq); + sdpd_tx_cmd->status_code = A_CPU2LE16(sdpd_tx_cmd->status_code); + sdpd_tx_cmd->comeback_delay = A_CPU2LE16(sdpd_tx_cmd->comeback_delay); + sdpd_tx_cmd->tlv_length = A_CPU2LE16(sdpd_tx_cmd->tlv_length); + sdpd_tx_cmd->update_indic = A_CPU2LE16(sdpd_tx_cmd->update_indic); + sdpd_tx_cmd->total_length = A_CPU2LE16(sdpd_tx_cmd->total_length); + + status = wmi_cmd_send(wmip, osbuf, WMI_P2P_SDPD_TX_CMDID, NO_SYNC_WMIFLAG); + + if (status != A_OK) + { + A_NETBUF_FREE(osbuf); + } + + return status; +} + +A_STATUS +wmi_p2p_set_oppps(struct wmi_t *wmip, WMI_OPPPS_INFO_STRUCT *pOpp) +{ + WMI_OPPPS_INFO_STRUCT *cmd; + void *osbuf; + + osbuf = A_NETBUF_ALLOC(sizeof(WMI_OPPPS_INFO_STRUCT)); + if (osbuf == NULL) + { + return A_NO_MEMORY; + } + + A_NETBUF_PUT(osbuf, sizeof(WMI_OPPPS_INFO_STRUCT)); + cmd = (WMI_OPPPS_INFO_STRUCT *)(A_NETBUF_DATA(osbuf)); + + cmd->enable = pOpp->enable; + cmd->ctwin = pOpp->ctwin; + + return (wmi_cmd_send(wmip, osbuf, WMI_P2P_FW_SET_OPPPS_CMDID, NO_SYNC_WMIFLAG)); +} + +A_STATUS wmi_p2p_set_noa(struct wmi_t *wmip, WMI_NOA_INFO_STRUCT *noa) +{ + void *osbuf; + WMI_NOA_INFO_STRUCT *p2p_set_noa_cmd; + int i; + A_STATUS status; + + osbuf = A_NETBUF_ALLOC(sizeof(WMI_NOA_INFO_STRUCT) - 1 + noa->count * sizeof(P2P_NOA_DESCRIPTOR)); + if (osbuf == NULL) + { + return A_NO_MEMORY; + } + + A_NETBUF_PUT(osbuf, sizeof(WMI_NOA_INFO_STRUCT) - 1 + noa->count * sizeof(P2P_NOA_DESCRIPTOR)); + + p2p_set_noa_cmd = (WMI_NOA_INFO_STRUCT *)(A_NETBUF_DATA(osbuf)); + + p2p_set_noa_cmd->enable = noa->enable; + p2p_set_noa_cmd->count = noa->count; + + for (i = 0; i < p2p_set_noa_cmd->count; i++) + { + A_MEMCPY(((P2P_NOA_DESCRIPTOR *)p2p_set_noa_cmd->noas) + i, ((P2P_NOA_DESCRIPTOR *)noa->noas) + i, + sizeof(P2P_NOA_DESCRIPTOR)); + } + + status = wmi_cmd_send(wmip, osbuf, WMI_P2P_FW_SET_NOA_CMDID, NO_SYNC_WMIFLAG); + + if (status != A_OK) + { + A_NETBUF_FREE(osbuf); + } + + return status; +} + +void wmi_save_key_info(WMI_P2P_PROV_INFO *p2p_info) +{ + A_MEMCPY(&p2p_key_val, p2p_info, sizeof(WMI_P2P_PROV_INFO)); +} + +#endif + +A_STATUS +wmi_cmd_start(struct wmi_t *wmip, const void *pInput, WMI_COMMAND_ID cmdID, uint16_t buffSize) +{ + A_STATUS status = A_ERROR; + void *osbuf; + + do + { + /* allocate a buffer for communication to the wifi device */ + if (NULL == (osbuf = A_NETBUF_ALLOC(buffSize))) + { + status = A_NO_MEMORY; + break; + } + + if (buffSize) + { + /* reserve the necessary space in the buffer */ + A_NETBUF_PUT(osbuf, buffSize); + A_MEMCPY(A_NETBUF_DATA(osbuf), pInput, buffSize); + } + /* send the buffer to the wifi device */ + if (A_OK != (status = wmi_cmd_send(wmip, osbuf, cmdID, NO_SYNC_WMIFLAG))) + { + // No need to free the buffer. wmi_cmd_send is freeing the + // buffer in case of error (the error condition is very rare). + // Hence commenting this out. + // A_NETBUF_FREE(osbuf); //wmi_cmd_send is freeing the buffer + } + } while (0); + + return status; +} + +#if defined(DRIVER_CONFIG_IMPLEMENT_RX_FREE_MULTIPLE_QUEUE) + +uint8_t reverse_credits_init = 0; + +A_STATUS wmi_reverse_credit_cmd(void *handle, boolean enable, uint8_t *endpoints, uint8_t *credits) +{ + A_STATUS status = A_ERROR; + uint8_t i; + + WMI_INIT_REVERSE_CREDIT_CMD reverse_credits; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(handle); + + for (i = 0; i < 8; i++) + { + if (endpoints[i] == 0) + break; + } + + reverse_credits.num_credit_queues = i; + reverse_credits.max_queued_buffers = 64; /// GET_TOTAL_BUFFERS(); + + memcpy(reverse_credits.endpoint_mapping, endpoints, sizeof(reverse_credits.endpoint_mapping)); + memcpy(reverse_credits.start_credits_per_queue, credits, sizeof(reverse_credits.start_credits_per_queue)); + + do + { + status = wmi_cmd_start(pDCxt->pWmiCxt, &reverse_credits, WMI_SET_CREDIT_REVERSE_CMDID, + sizeof(WMI_INIT_REVERSE_CREDIT_CMD)); + + if (status == A_OK) + { + break; + } + else if (status == A_NO_MEMORY) + { + pDCxt->tx_complete_pend = true; + + if (A_OK != DRIVER_WAIT_FOR_CONDITION(p_Global_Cxt, &(pDCxt->tx_complete_pend), false, 5000)) + { + A_ASSERT(0); + } + } + else + { + A_ASSERT(0); + } + } while (1); + + Driver_WakeDriver(p_Global_Cxt); + A_MDELAY(10); + + reverse_credits_init = 1; +} + +#define CLASS_HEAD_LEN(a) (sizeof((a)->offset) + sizeof((a)->shift) + sizeof((a)->mask) + sizeof((a)->count)) +#define CLASS_MAPPING_LEN(n) (sizeof(uint32_t) * n + n) + +A_STATUS wmi_rcv_data_classifier_cmd(void *handle, + uint8_t offset, + uint8_t shift, + uint32_t mask, + uint8_t count, + uint32_t *category_mapping, + uint8_t *ep_mapping) +{ + A_STATUS status = A_ERROR; + WMI_INIT_RCV_DATA_CLASSIFIER_CMD DataCls; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(handle); + uint16_t len; + + if (count > 8) + return status; +#if 0 + len = CLASS_HEAD_LEN(pDataCls) + CLASS_MAPPING_LEN(count); + pDataCls = (WMI_INIT_RCV_DATA_CLASSIFIER_CMD *)A_MALLOC(len, MALLOC_ID_TEMPORARY); + if (pDataCls == NULL) + return status; +#endif + + DataCls.offset = offset; + DataCls.shift = shift; + DataCls.mask = mask; + DataCls.count = count; + + memcpy(DataCls.category_mapping_data, category_mapping, sizeof(uint32_t) * count); + memcpy(DataCls.ep_mapping_data, ep_mapping, count); + + do + { + status = wmi_cmd_start(pDCxt->pWmiCxt, &DataCls, WMI_SET_RCV_DATA_CLASSIFIER_CMDID, + sizeof(WMI_INIT_RCV_DATA_CLASSIFIER_CMD)); + + if (status == A_OK) + { + break; + } + else if (status == A_NO_MEMORY) + { + pDCxt->tx_complete_pend = true; + + if (A_OK != DRIVER_WAIT_FOR_CONDITION(p_Global_Cxt, &(pDCxt->tx_complete_pend), false, 5000)) + { + A_ASSERT(0); + } + } + else + { + A_ASSERT(0); + } + } while (1); + +#if 0 + A_FREE(pDataCls, MALLOC_ID_TEMPORARY); +#endif + + return status; +} + +A_STATUS wmi_update_reverse_credits_cmd(void *handle, uint8_t endpoint, uint32_t nCredits) +{ + A_STATUS status = A_ERROR; + + return status; +} +#endif + +#ifndef ENABLE_LARGE_DSET +A_STATUS wmi_dset_host_cfg_cmd(void *handle) +{ + A_STATUS status = A_ERROR; + uint8_t i; + + WMI_DSET_HOST_CFG_CMD dset; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(handle); + + dset.length = 1; + + dset.dset[0].dset_id = 0x0901; + // dset.dset[0].dset_id = 0x0902; + dset.dset[0].len = 2048; + dset.dset[0].offset = 0; + + do + { + status = wmi_cmd_start(pDCxt->pWmiCxt, &dset, WMI_DSET_HOST_CFG_CMDID, sizeof(WMI_DSET_HOST_CFG_CMD)); + + if (status == A_OK) + { + break; + } + else if (status == A_NO_MEMORY) + { + pDCxt->tx_complete_pend = true; + + if (A_OK != DRIVER_WAIT_FOR_CONDITION(p_Global_Cxt, &(pDCxt->tx_complete_pend), false, 5000)) + { + A_ASSERT(0); + } + } + else + { + A_ASSERT(0); + } + } while (1); + + Driver_WakeDriver(p_Global_Cxt); + A_MDELAY(10); +} + +#else + +A_STATUS wmi_dset_host_cfg_cmd(void *handle) +{ + HOST_DSET *pDset; + WMI_STORERECALL_RECALL_CMD *pStrrclCmd; + WMI_STORERECALL_RECALL_DSET *pDsetInfo; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(handle); + + pStrrclCmd = (WMI_STORERECALL_RECALL_CMD *)pDCxt->tempStorage; + pStrrclCmd->length = 0; + + pDsetInfo = (WMI_STORERECALL_RECALL_DSET *)pStrrclCmd->data; + + pDset = dset_get_first(); + + while (pDset != NULL) + { + if (IS_STRRCL_DSET(pDset->dset_id)) + { + pDsetInfo->dset_id = pDset->dset_id; + pDsetInfo->length = pDset->length; + + pStrrclCmd->length++; + pDsetInfo++; + } + pDset = dset_get_next(); + } + + return A_OK; +} +#endif + +A_STATUS wmi_set_appie_cmd(struct wmi_t *wmip, void *data) +{ + ATH_APPIE_PARAM *appie_param = (ATH_APPIE_PARAM *)data; + void *osbuf = NULL; + WMI_SET_APPIE_CMD *set_appie_cmd; + A_STATUS status; + + osbuf = A_NETBUF_ALLOC(sizeof(WMI_SET_APPIE_CMD) + appie_param->ieLen); + if (osbuf == NULL) { + return A_NO_MEMORY; + } + + A_NETBUF_PUT(osbuf, sizeof(WMI_SET_APPIE_CMD) + appie_param->ieLen); + + set_appie_cmd = (WMI_SET_APPIE_CMD *)(A_NETBUF_DATA(osbuf)); + set_appie_cmd->mgmtFrmType = appie_param->mgmtFrmType; + set_appie_cmd->ieLen = appie_param->ieLen; + + A_MEMCPY(set_appie_cmd->ieInfo, appie_param->ieInfo, appie_param->ieLen); + status = wmi_cmd_send(wmip, osbuf, WMI_SET_APPIE_CMDID, NO_SYNC_WMIFLAG); + + if (status != A_OK) { + A_NETBUF_FREE(osbuf); + } + + return status; +} + diff --git a/platform/mcu/lpc54102/wifi_qca/common_src/wmi/wmi_host.h b/platform/mcu/lpc54102/wifi_qca/common_src/wmi/wmi_host.h new file mode 100644 index 0000000000..2e1d79dad7 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/common_src/wmi/wmi_host.h @@ -0,0 +1,73 @@ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== + +#ifndef _WMI_HOST_H_ +#define _WMI_HOST_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +struct wmi_stats +{ + uint32_t cmd_len_err; + uint32_t cmd_id_err; +}; + +#define BEACON_PERIOD_IE_INDEX 8 +#define CAPS_IE_INDEX 10 +#define IE_INDEX 12 + +/* + * These constants are used with A_WLAN_BAND_SET. + */ +#define A_BAND_24GHZ 0 +#define A_BAND_5GHZ 1 +#define A_NUM_BANDS 2 + +struct wmi_t +{ + boolean wmi_numQoSStream; + uint16_t wmi_streamExistsForAC[WMM_NUM_AC]; + uint8_t wmi_fatPipeExists; + void *wmi_devt; + struct wmi_stats wmi_stats; + A_MUTEX_T wmi_lock; + HTC_ENDPOINT_ID wmi_endpoint_id; + void *persistentProfile; + uint16_t deviceid; +#if ENABLE_P2P_MODE + // WMI_P2P_PERSISTENT_PROFILE_CMD persistentNode; + WMI_SET_PASSPHRASE_CMD apPassPhrase; +#endif +}; + +#define LOCK_WMI(w) A_MUTEX_ACQUIRE(&(w)->wmi_lock); +#define UNLOCK_WMI(w) A_MUTEX_RELEASE(&(w)->wmi_lock); + +#ifdef __cplusplus +} +#endif + +#endif /* _WMI_HOST_H_ */ diff --git a/platform/mcu/lpc54102/wifi_qca/custom_src/api_interface/cust_api_init.c b/platform/mcu/lpc54102/wifi_qca/custom_src/api_interface/cust_api_init.c new file mode 100644 index 0000000000..e5918daba2 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/custom_src/api_interface/cust_api_init.c @@ -0,0 +1,312 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== +#include "wifi_common.h" + +#include +#include +#include +#include +#include +#include +#include + +// This is A_CUSTOM_DRIVER_CONTEXT, the top-level driver context. +// It contains pCommonCxt which points to the internal (aka "common") +// driver context (of type A_DRIVER_CONTEXT) +void *p_Global_Cxt = NULL; + +/*The following pointers store the custom driver context used by QAPIs*/ +// The pointers are of type QCA_CONTEXT_STRUCT_PTR +// and first entry is initialized by Custom_Api_Initialize(QCA_CONTEXT_STRUCT_PTR qca_ptr) +// (near the bottom) while the second is initialized in same function near the top +// Custom_Api_Initialize() also initializes p_Global_Cxt->pUpperCxt[] which +// is the exact same array as this one! +void *p_Driver_Cxt[2]; + +static uint32_t Custom_Api_Readmii(struct qca_context_struct *p_ctxt, uint32_t val, uint32_t *p_val, uint32_t val2); +static uint32_t Custom_Api_Writemii(struct qca_context_struct *p_ctxt, uint32_t val1, uint32_t val2, uint32_t val3); + +static uint32_t Custom_Api_Join(struct qca_context_struct *p_ctxt, struct qca_mcb_struct *p_mcb); +static uint32_t Custom_Api_Rejoin(struct qca_context_struct *p_ctxt); +static uint32_t Custom_Api_Initialize(QCA_CONTEXT_STRUCT_PTR qca_ptr); +static uint32_t Custom_Api_Shutdown(struct qca_context_struct *qca_ptr); +extern uint32_t Custom_Api_Send( + QCA_CONTEXT_STRUCT_PTR qca_ptr, PCB_PTR pcb_ptr, uint32_t size, uint32_t frags, uint32_t flags); +extern uint32_t Custom_Api_Mediactl(QCA_CONTEXT_STRUCT_PTR qca_ptr, uint32_t command_id, void *inout_param); + +uint32_t chip_state_ctrl(QCA_CONTEXT_STRUCT_PTR qca_ptr, uint32_t state); + +const QCA_MAC_IF_STRUCT ATHEROS_WIFI_IF = {Custom_Api_Initialize, Custom_Api_Shutdown, Custom_Api_Send, + Custom_Api_Readmii, Custom_Api_Writemii, Custom_Api_Join, + Custom_Api_Rejoin, Custom_Api_Mediactl}; + +static uint32_t Custom_Api_Readmii(struct qca_context_struct *p_ctxt, uint32_t val, uint32_t *p_val, uint32_t val2) +{ + /* NOTHING TO DO HERE */ + UNUSED_ARGUMENT(p_ctxt); + UNUSED_ARGUMENT(val); + UNUSED_ARGUMENT(p_val); + UNUSED_ARGUMENT(val2); + + assert(0); + return 0; +} + +static uint32_t Custom_Api_Writemii(struct qca_context_struct *p_ctxt, uint32_t val1, uint32_t val2, uint32_t val3) +{ + /* NOTHING TO DO HERE */ + UNUSED_ARGUMENT(p_ctxt); + UNUSED_ARGUMENT(val1); + UNUSED_ARGUMENT(val2); + UNUSED_ARGUMENT(val3); + + assert(0); + return 0; +} + +static uint32_t Custom_Api_Join(struct qca_context_struct *p_ctxt, struct qca_mcb_struct *p_mcb) +{ + /* NOTHING TO DO HERE */ + UNUSED_ARGUMENT(p_ctxt); + UNUSED_ARGUMENT(p_mcb); + + assert(0); + return 0; +} + +static uint32_t Custom_Api_Rejoin(struct qca_context_struct *p_ctxt) +{ + /* NOTHING TO DO HERE */ + UNUSED_ARGUMENT(p_ctxt); + + assert(0); + return 0; +} + +uint32_t chip_state_ctrl(QCA_CONTEXT_STRUCT_PTR qca_ptr, uint32_t state) +{ + uint32_t error = QCA_OK; + + if (state == 0) + { + /* confirm that the driver is not already down */ + if (qca_ptr->MAC_CONTEXT_PTR != NULL) + { + /* shutdown chip and driver */ + error = Custom_Api_Shutdown(qca_ptr); + } + } + else + { + /* confirm that the driver is not already up */ + if (qca_ptr->MAC_CONTEXT_PTR == NULL) + { + /* bring up chip and driver */ + error = Custom_Api_Initialize(qca_ptr); + } + } + + return error; +} + +/*****************************************************************************/ +/* Custom_Api_Initialize - Entry point for MQX to initialize the Driver. + * QCA_CONTEXT_STRUCT_PTR qca_ptr - pointer to MQX ethernet object. + * RETURNS: QCA_OK on success or QCA_ERROR otherwise. + *****************************************************************************/ +static uint32_t Custom_Api_Initialize(QCA_CONTEXT_STRUCT_PTR qca_ptr) +{ + uint32_t error = QCA_OK; + + /* If it is the second device which is getting initialised, + * Fill the pointers and generate the MAC address from the + * first device + */ + if (p_Global_Cxt) + { + QCA_CONTEXT_STRUCT_PTR tempqca_ptr = (QCA_CONTEXT_STRUCT_PTR)GET_DRIVER_CXT(p_Global_Cxt)->pUpperCxt[0]; + uint8_t devId; + + devId = qca_ptr->PARAM_PTR->QCA_IF->PHY_NUMBER; + A_ASSERT(devId < WLAN_NUM_OF_DEVICES); + /* Generating the MAC Address of the second interface using the first interface MAC */ + A_MEMCPY(qca_ptr->ADDRESS, tempqca_ptr->ADDRESS, ATH_MAC_LEN); + qca_ptr->ADDRESS[0] = (((qca_ptr->ADDRESS[0]) ^ (1 << devId)) | 0x2); + // qca_ptr->ADDRESS[0] = ((qca_ptr->ADDRESS[0])+ (devId << 4)) | 0x2; + + qca_ptr->MAC_CONTEXT_PTR = p_Global_Cxt; + GET_DRIVER_CXT(p_Global_Cxt)->pUpperCxt[devId] = qca_ptr; + p_Driver_Cxt[1] = qca_ptr; + return error; + } + + do + { + /* allocate the driver context and assign it to the qca_ptr mac_param */ + if (NULL == (p_Global_Cxt = (void *)A_MALLOC(sizeof(A_CUSTOM_DRIVER_CONTEXT), MALLOC_ID_CONTEXT))) + { + PRINTF("p_Global_Cxt is NULL\r\n"); + error = QCA_ERROR; + break; + } + + A_MEMZERO(p_Global_Cxt, sizeof(A_CUSTOM_DRIVER_CONTEXT)); + /* alloc the driver common context */ + void *pCommonCxt = A_MALLOC(sizeof(A_DRIVER_CONTEXT), MALLOC_ID_CONTEXT); + GET_DRIVER_CXT(p_Global_Cxt)->pCommonCxt = pCommonCxt; + if (NULL == pCommonCxt) + { + PRINTF("pCommonCxt is NULL\r\n"); + error = QCA_ERROR; + break; + } + + qca_ptr->MAC_CONTEXT_PTR = p_Global_Cxt; + /* initialize backwards pointers */ + GET_DRIVER_CXT(p_Global_Cxt)->pUpperCxt[0] = qca_ptr; + GET_DRIVER_CXT(p_Global_Cxt)->pDriverParam = qca_ptr->PARAM_PTR->MAC_PARAM; + /* create the 2 driver events. */ + PRINTF("Api_InitStart\r\n"); + /* Api_InitStart() will perform any additional allocations that are done as part of + * the common_driver initialization */ + if (A_OK != Api_InitStart(p_Global_Cxt)) + { + PRINTF("Api_InitStart ERROR\r\n"); + error = QCA_ERROR; + break; + } +/* CreateDriverThread is a custom function to create or restart the driver thread. + * the bulk of the driver initialization is handled by the driver thread. + */ + // Start the driver thread with maximum priority. + // It will be scheduled immediately ensuring that Driver_Init() is called before + // the main thread calls Api_InitFinish() below + PRINTF("Driver_CreateThread\r\n"); + if (A_OK != Driver_CreateThread(p_Global_Cxt)) + { + PRINTF("Driver_CreateThread ERROR\r\n"); + error = QCA_ERROR; + break; + } + PRINTF("Api_InitFinish\r\n"); + + /* Api_InitFinish waits for wmi_ready event from chip. */ + if (A_OK != Api_InitFinish(p_Global_Cxt)) + { + PRINTF("Api_InitFinish ERROR \r\n"); + error = QCA_ERROR; + break; + } + + g_driverState = DRIVER_STATE_RUN; + PRINTF("Api_WMIInitFinish\r\n"); + + Api_WMIInitFinish(p_Global_Cxt); + } while (0); + + if (error != QCA_OK) + { + if (p_Global_Cxt != NULL) + { +#if 0 + void * tmp_addr; + /* NOTE: ***do not free memory*** in case of timeout/failure + * there is no proper initialization fallback ! */ + + /* Free driver context, may be interrupted */ + tmp_addr = ((cust_context_t *)p_Global_Cxt)->pCommonCxt; + ((cust_context_t *)p_Global_Cxt)->pCommonCxt = NULL; + A_FREE(tmp_addr, MALLOC_ID_CONTEXT); + + /* Free custom driver context, may be interrupted */ + tmp_addr = p_Global_Cxt; + p_Global_Cxt = NULL; + A_FREE(tmp_addr, MALLOC_ID_CONTEXT); +#endif + return error; + } + } + else + { + p_Driver_Cxt[0] = qca_ptr; + } + +#if 0 +if(g_totAlloc){ + A_PRINTF("init alloc: %d\n", g_totAlloc); + //for more information one can implement _mem_get_free() to + //determine how much free memory exists in the system pool. +} +#endif + + Api_BootProfile(p_Global_Cxt, BOOT_PROFILE_DRIVE_READY); + + return error; +} + +/*****************************************************************************/ +/* Custom_Api_Shutdown - Entry point for MQX to shutdown the Driver. + * QCA_CONTEXT_STRUCT_PTR qca_ptr - pointer to MQX ethernet object. + * RETURNS: QCA_OK on success or QCA_ERROR otherwise. + *****************************************************************************/ +static uint32_t Custom_Api_Shutdown(struct qca_context_struct *qca_ptr) +{ + void *pCxt = qca_ptr->MAC_CONTEXT_PTR; + + // Notify driver task to reset itself + Driver_DestroyThread(pCxt); + +//TODO: It simply cannot work +#if 0 + if (pCxt != NULL) + { + Api_DeInitStart(pCxt); + Driver_DestroyThread(pCxt); + Api_DeInitFinish(pCxt); + + if (NULL != GET_DRIVER_COMMON(pCxt)) + { + A_FREE(GET_DRIVER_COMMON(pCxt), MALLOC_ID_CONTEXT); + } + + A_FREE(pCxt, MALLOC_ID_CONTEXT); + p_Global_Cxt = NULL; + qca_ptr->MAC_CONTEXT_PTR = NULL; + } +#endif + + return (uint32_t)QCA_OK; +} + +/*****************************************************************************/ +/* Custom_Api_GetDriverCxt - return driver context based on device ID + * QCA_CONTEXT_STRUCT_PTR qca_ptr - pointer to MQX ethernet object. + * RETURNS: QCA_OK on success or QCA_ERROR otherwise. + *****************************************************************************/ +void *Custom_Api_GetDriverCxt(uint8_t device_id) +{ + return (p_Driver_Cxt[device_id]); +} diff --git a/platform/mcu/lpc54102/wifi_qca/custom_src/api_interface/cust_api_ioctl.c b/platform/mcu/lpc54102/wifi_qca/custom_src/api_interface/cust_api_ioctl.c new file mode 100644 index 0000000000..a101c1cff8 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/custom_src/api_interface/cust_api_ioctl.c @@ -0,0 +1,1995 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if ENABLE_P2P_MODE +#include +#include "p2p.h" +#endif + +#include "atheros_wifi.h" +#include "atheros_wifi_api.h" +#include "atheros_wifi_internal.h" +#include "dset_api.h" +#include "hw20_mbox_host_reg.h" +#include +#include "hw20_apb_map.h" +#include "hw20_mbox_reg.h" + +#if ENABLE_P2P_MODE +// extern WPS_CREDENTIAL persistCredential; +extern WMI_P2P_PROV_INFO p2p_key_val; +#endif + +extern const uint8_t max_performance_power_param; +extern const WMI_STORERECALL_CONFIGURE_CMD default_strrcl_config_cmd; +extern const WMI_SCAN_PARAMS_CMD default_scan_param; + +uint32_t Custom_Api_Mediactl(QCA_CONTEXT_STRUCT_PTR qca_ptr, uint32_t command_id, void *inout_param); +extern uint32_t chip_state_ctrl(QCA_CONTEXT_STRUCT_PTR qca_ptr, uint32_t state); + +/* used to translate from the WPS_ERROR_CODE to that ATH_WPS_ERROR_CODE exposed to app */ +const uint8_t const_wps_error_code_translation[] = { + ATH_WPS_ERROR_SUCCESS, ATH_WPS_ERROR_INVALID_START_INFO, ATH_WPS_ERROR_MULTIPLE_PBC_SESSIONS, + ATH_WPS_ERROR_WALKTIMER_TIMEOUT, ATH_WPS_ERROR_M2D_RCVD, ATH_WPS_ERROR_PWD_AUTH_FAIL, + ATH_WPS_ERROR_CANCELLED, ATH_WPS_ERROR_INVALID_PIN, +}; + +static A_STATUS config_dump_target_assert_info(void *pCxt) +{ + uint32_t regDumpValues[60]; + uint16_t length = 60; + uint16_t i; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + + if (A_OK == Driver_DumpAssertInfo(pCxt, regDumpValues, &length)) + { + for (i = 0; i < length; i += 4) + { + QCADRV_PRINTF("0x%08X ", A_LE2CPU32(regDumpValues[i])); + QCADRV_PRINTF("0x%08X ", A_LE2CPU32(regDumpValues[i + 1])); + QCADRV_PRINTF("0x%08X ", A_LE2CPU32(regDumpValues[i + 2])); + QCADRV_PRINTF("0x%08X\n", A_LE2CPU32(regDumpValues[i + 3])); + } + } + /* clear this request */ + pDCxt->asynchRequest = NULL; + return A_OK; +} + +/*FUNCTION*------------------------------------------------------------- +* +* Function Name : ath_ioctl_handler +* PARAMS : +* qca_ptr-> ptr to enet context +* inout_param -> input/output data for command. +* Returned Value : QCA_OK or error code +* Comments : +* IOCTL implementation of Atheros Wifi device. +* +*END*-----------------------------------------------------------------*/ + +int32_t ath_ioctl_handler(QCA_CONTEXT_STRUCT_PTR qca_ptr, ATH_IOCTL_PARAM_STRUCT_PTR param_ptr) +{ + A_STATUS status = A_OK; + int32_t error = QCA_OK; + void *pCxt, *pWmi; + A_DRIVER_CONTEXT *pDCxt; + void *data; + WMI_WPS_PROFILE_EVENT *pWpsEv; + WMI_SCAN_PARAMS_CMD scan_param_cmd; + WMI_CHANNEL_PARAMS_CMD channel_param_cmd; + WMI_SET_ROAM_CTRL_CMD *pRoamCtrl; + uint32_t devId; + uint32_t i, ii; + uint8_t val; + int32_t wait_for_status; + +#if ENABLE_P2P_MODE + WMI_P2P_FW_CONNECT_CMD_STRUCT *pP2PConnect; + WMI_P2P_INVITE_CMD *p2pInvite; + WMI_P2P_GRP_INIT_CMD *p2pGroup; + + union + { + WMI_WPS_START_CMD wps_start; + WMI_P2P_FW_CONNECT_CMD_STRUCT joinProfile; + WMI_SET_HT_CAP_CMD ht_cap_cmd; + WPS_CREDENTIAL *pCred; + A_NETBUF *a_netbuf_ptr; + uint32_t param; + WMI_SCAN_PARAMS_CMD scan_param_cmd; + WMI_LISTEN_INT_CMD listen_param; + WMI_ALLOW_AGGR_CMD allow_aggr_param; + WMI_STORERECALL_HOST_READY_CMD storerecall_ready_param; + WMI_POWER_PARAMS_CMD power_param_param; + WMI_SET_CHANNEL_CMD set_channel_param; + WMI_SET_FILTERED_PROMISCUOUS_MODE_CMD set_prom_param; + WMI_GREENTX_PARAMS_CMD gtx_param; + WMI_LPL_FORCE_ENABLE_CMD lpl_param; + } stackU; +#else + union + { + WMI_WPS_START_CMD wps_start; + WMI_SET_HT_CAP_CMD ht_cap_cmd; + WPS_CREDENTIAL *pCred; + A_NETBUF *a_netbuf_ptr; + uint32_t param; + WMI_SCAN_PARAMS_CMD scan_param_cmd; + WMI_LISTEN_INT_CMD listen_param; + WMI_ALLOW_AGGR_CMD allow_aggr_param; + WMI_STORERECALL_HOST_READY_CMD storerecall_ready_param; + WMI_POWER_PARAMS_CMD power_param_param; + WMI_SET_CHANNEL_CMD set_channel_param; + WMI_SET_FILTERED_PROMISCUOUS_MODE_CMD set_prom_param; + WMI_GREENTX_PARAMS_CMD gtx_param; + WMI_LPL_FORCE_ENABLE_CMD lpl_param; + } stackU; +#endif + +#define WPS_START (stackU.wps_start) +#define HT_CAP (stackU.ht_cap_cmd) +#define CRED_PTR (stackU.pCred) +#define PCB_PTR (stackU.a_netbuf_ptr) +#define PARAM (stackU.param) +#define SCAN_PARAM (stackU.scan_param_cmd) +#define LISTEN_PARAM (stackU.listen_param) +#define AGGR_PARAM (stackU.allow_aggr_param) +#define STRRCL_RDY_PARAM (stackU.storerecall_ready_param) +#define POWER_PARAM_PARAM (stackU.power_param_param) +#define SET_CHANNEL_PARAM (stackU.set_channel_param) +#define SET_PROM_PARAM (stackU.set_prom_param) +#define GTX_PARAM (stackU.gtx_param) +#define LPL_PARAM (stackU.lpl_param) + +#define PTR_POWER_PARAM ((WMI_POWER_PARAMS_CMD *)(data)) +#define PTR_LI ((uint32_t *)(data)) +#define PTR_HOST_MODE ((char *)(data)) +#define PTR_CIPHER ((cipher_t *)(data)) +#define PTR_SEC_MODE ((char *)(data)) +#define PTR_PHY_MODE ((char *)(data)) +#define PTR_CONNECT_CB ((ATH_CONNECT_CB)(data)) +#define PTR_PROBE_CB ((ATH_PROBEREQ_CB)(data)) +#define PTR_STRRCL_START ((uint32_t *)(data)) +#define PTR_VERSION ((ATH_VERSION_PTR)(data)) +#define PTR_VERSION_STR ((ATH_VERSION_STR_PTR)(data)) +#define PTR_WPS_START ((ATH_WPS_START *)(data)) +#define PTR_WPS_GET ((ATH_NETPARAMS *)(data)) +#define PTR_PMK_SET ((uint8_t *)(data)) +#define PTR_SCAN_CTRL ((ATH_SCANPARAMS *)(data)) +#define PTR_SCAN_PARAMS ((WMI_SCAN_PARAMS_CMD *)(data)) +#define PTR_MAC_TX ((ATH_MAC_TX_RAW_S *)(data)) +#define PTR_SET_CHAN ((uint32_t *)(data)) +#define PTR_SET_AGGR ((ATH_SET_AGGREGATION_PARAM *)(data)) +#define PTR_FLASH_CMD ((ATH_PROGRAM_FLASH_STRUCT *)(data)) +#define PTR_TX_STATUS_CMD ((ATH_TX_STATUS *)(data)) +#define PTR_PROM_MODE ((ATH_PROMISCUOUS_MODE *)(data)) +#define PTR_REG_DOMAIN_CMD ((ATH_REG_DOMAIN *)(data)) +#define PTR_EXT_SCAN_CMD ((ATH_GET_SCAN *)(data)) +#define PTR_WEP_IN ((ATH_WEPKEYS *)data) +#define PTR_WEP_INDEX ((uint32_t *)(data)) + +#if ENABLE_P2P_MODE +#define INVITE_PROF (stackU.wpsProfile) +#define JOIN_CONN_PROF (stackU.joinProfile) +#define PTR_PASS_PHRASE ((WMI_SET_PASSPHRASE_CMD *)(data)) +#endif + +#define PTR_LAST_ERROR (uint32_t *)(data) +#define PTR_GTX (uint8_t *)(data) +#define PTR_LPL (uint8_t *)(data) +#define PTR_MAC_ADDR ((ATH_PROGRAM_MAC_ADDR_PARAM *)(data)) +#define PTR_COUNTRY_CODE ((ATH_PROGRAM_COUNTRY_CODE_PARAM *)(data)) + + data = param_ptr->data; + + if ((pCxt = qca_ptr->MAC_CONTEXT_PTR) == NULL) + { + return QCA_ERROR; + } + + pDCxt = GET_DRIVER_COMMON(pCxt); + pWmi = pDCxt->pWmiCxt; + devId = pDCxt->devId; + + switch (param_ptr->cmd_id) + { + case ATH_SCAN_CTRL: + A_MEMCPY(&SCAN_PARAM, &default_scan_param, sizeof(WMI_SCAN_PARAMS_CMD)); + SCAN_PARAM.fg_start_period = + ((PTR_SCAN_CTRL->flags & ATH_DISABLE_FG_SCAN) ? A_CPU2LE16(0xffff) : A_CPU2LE16(0)); + SCAN_PARAM.fg_end_period = + ((PTR_SCAN_CTRL->flags & ATH_DISABLE_FG_SCAN) ? A_CPU2LE16(0xffff) : A_CPU2LE16(0)); + SCAN_PARAM.bg_period = ((PTR_SCAN_CTRL->flags & ATH_DISABLE_BG_SCAN) ? A_CPU2LE16(0xffff) : A_CPU2LE16(0)); + if (A_OK != wmi_cmd_start(pWmi, &SCAN_PARAM, WMI_SET_SCAN_PARAMS_CMDID, sizeof(WMI_SCAN_PARAMS_CMD))) + { + error = QCA_ERROR; + } + else + { + A_MEMCPY(&pDCxt->scan_param, &SCAN_PARAM, sizeof(WMI_SCAN_PARAMS_CMD));//to save scan parameters + } + break; + case ATH_SET_SCAN_PARAM: + A_MEMCPY(&SCAN_PARAM, PTR_SCAN_PARAMS, sizeof(WMI_SCAN_PARAMS_CMD)); + + if (A_OK != wmi_cmd_start(pWmi, &SCAN_PARAM, WMI_SET_SCAN_PARAMS_CMDID, sizeof(WMI_SCAN_PARAMS_CMD))) + { + error = QCA_ERROR; + } + else + { + A_MEMCPY(&pDCxt->scan_param, &SCAN_PARAM, sizeof(WMI_SCAN_PARAMS_CMD));//to save scan parameters + } + break; + case ATH_SET_TXPWR: + if (A_OK != wmi_cmd_start(pWmi, param_ptr->data, WMI_SET_TX_PWR_CMDID, sizeof(WMI_SET_TX_PWR_CMD))) + { + error = QCA_ERROR; + } + break; + case ATH_SET_DEVICE_ID: + { + uint16_t deviceId = *(uint16_t *)(param_ptr->data); + /*No change needed, don't return failure*/ + if (pDCxt->devId == deviceId) + { + break; + } + + if (pDCxt->wps_in_progress) + { + error = QCA_ERROR; + } + + if (deviceId >= WLAN_NUM_OF_DEVICES) + { + error = QCA_ERROR; + break; + } + + ((struct wmi_t *)pWmi)->deviceid = deviceId; + pDCxt->devId = deviceId; + } + break; + case ATH_SET_PMPARAMS: + A_MEMZERO(&POWER_PARAM_PARAM, sizeof(WMI_POWER_PARAMS_CMD)); + POWER_PARAM_PARAM.idle_period = A_CPU2LE16(PTR_POWER_PARAM->idle_period); + POWER_PARAM_PARAM.pspoll_number = A_CPU2LE16(PTR_POWER_PARAM->pspoll_number); + POWER_PARAM_PARAM.dtim_policy = A_CPU2LE16(PTR_POWER_PARAM->dtim_policy); + POWER_PARAM_PARAM.tx_wakeup_policy = A_CPU2LE16(PTR_POWER_PARAM->tx_wakeup_policy); + POWER_PARAM_PARAM.num_tx_to_wakeup = A_CPU2LE16(PTR_POWER_PARAM->num_tx_to_wakeup); + POWER_PARAM_PARAM.ps_fail_event_policy = A_CPU2LE16(PTR_POWER_PARAM->ps_fail_event_policy); + + if (A_OK != + wmi_cmd_start(pWmi, &POWER_PARAM_PARAM, WMI_SET_POWER_PARAMS_CMDID, sizeof(WMI_POWER_PARAMS_CMD))) + { + error = QCA_ERROR; + } + break; + case ATH_SET_LISTEN_INT: + LISTEN_PARAM.listenInterval = A_CPU2LE16((*PTR_LI)); + LISTEN_PARAM.numBeacons = A_CPU2LE16(0); + if (A_OK != wmi_cmd_start(pWmi, &LISTEN_PARAM, WMI_SET_LISTEN_INT_CMDID, sizeof(WMI_LISTEN_INT_CMD))) + { + error = QCA_ERROR; + } + break; + case ATH_SET_CIPHER: + pDCxt->conn[pDCxt->devId].wpaPairwiseCrypto = (uint8_t)PTR_CIPHER->ucipher; + pDCxt->conn[pDCxt->devId].wpaGroupCrypto = (uint8_t)PTR_CIPHER->mcipher; + break; + case ATH_GET_CONC_DEV_CHANNEL: + *(uint16_t *)(param_ptr->data) = 0; +#if WLAN_NUM_OF_DEVICES == 2 + if (pDCxt->devId == 1) + { + if ((pDCxt->conn[0].isConnected) && (!(pDCxt->conn[1].isConnected))) + { + *(uint16_t *)(param_ptr->data) = pDCxt->conn[0].channelHint; + } + } + else if (pDCxt->devId == 0) + { + if ((pDCxt->conn[1].isConnected) && (!(pDCxt->conn[0].isConnected))) + { + *(uint16_t *)(param_ptr->data) = pDCxt->conn[1].channelHint; + } + } +#elif WLAN_NUM_OF_DEVICES == 1 + if (pDCxt->devId == 0) + { + if (pDCxt->conn[0].isConnected) + { + *(uint16_t *)(param_ptr->data) = pDCxt->conn[0].channelHint; + } + } + +#endif + break; + case ATH_SET_SEC_MODE: + if (strcmp(PTR_SEC_MODE, "open") == 0) + { + pDCxt->conn[pDCxt->devId].dot11AuthMode = OPEN_AUTH; + } + else if (strcmp(PTR_SEC_MODE, "shared") == 0) + { + pDCxt->conn[pDCxt->devId].dot11AuthMode = SHARED_AUTH; + } + else + { + error = QCA_ERR_INVALID_INIT_PARAM; + } + break; + case ATH_SET_PHY_MODE: + A_MEMZERO(&HT_CAP, sizeof(WMI_SET_HT_CAP_CMD)); + + if (strcmp(PTR_PHY_MODE, "b") == 0) + { + pDCxt->conn[pDCxt->devId].phyMode = WMI_11B_MODE; + } + else if (strcmp(PTR_PHY_MODE, "g") == 0) + { + pDCxt->conn[pDCxt->devId].phyMode = WMI_11G_MODE; + } + else if (strcmp(PTR_PHY_MODE, "a") == 0) + { + pDCxt->conn[pDCxt->devId].phyMode = WMI_11A_MODE; + } + else if (strcmp(PTR_PHY_MODE, "n") == 0) + { + pDCxt->conn[pDCxt->devId].phyMode = + (pDCxt->conn[pDCxt->devId].phyMode == WMI_11A_MODE) ? WMI_11A_MODE : WMI_11G_MODE; + HT_CAP.band = (pDCxt->conn[pDCxt->devId].phyMode == WMI_11A_MODE) ? 0x01 : 0x00; + HT_CAP.enable = 1; + HT_CAP.short_GI_20MHz = 1; + HT_CAP.max_ampdu_len_exp = 2; + } + else if (strcmp(PTR_PHY_MODE, "ht40") == 0) + { + pDCxt->conn[pDCxt->devId].phyMode = + (pDCxt->conn[pDCxt->devId].phyMode == WMI_11A_MODE) ? WMI_11A_MODE : WMI_11G_MODE; + HT_CAP.band = (pDCxt->conn[pDCxt->devId].phyMode == WMI_11A_MODE) ? 0x01 : 0x00; + HT_CAP.enable = 1; + HT_CAP.short_GI_20MHz = 1; + HT_CAP.short_GI_40MHz = 1; + HT_CAP.intolerance_40MHz = 0; + HT_CAP.max_ampdu_len_exp = 2; + HT_CAP.chan_width_40M_supported = 1; + } + + A_MEMZERO(&channel_param_cmd, sizeof(WMI_CHANNEL_PARAMS_CMD)); + channel_param_cmd.scanParam = 1; + channel_param_cmd.phyMode = pDCxt->conn[pDCxt->devId].phyMode; + if (A_OK != + wmi_cmd_start(pWmi, &channel_param_cmd, WMI_SET_CHANNEL_PARAMS_CMDID, sizeof(WMI_CHANNEL_PARAMS_CMD))) + { + error = QCA_ERROR; + break; + } + + if (A_OK != wmi_cmd_start(pWmi, &HT_CAP, WMI_SET_HT_CAP_CMDID, sizeof(WMI_SET_HT_CAP_CMD))) + { + error = QCA_ERROR; + break; + } + break; + case ATH_GET_PHY_MODE: + *(uint32_t *)(param_ptr->data) = pDCxt->conn[pDCxt->devId].phyMode; + break; + case ATH_GET_RX_RSSI: + pDCxt->rssiFlag = true; + wmi_cmd_start(pWmi, NULL, WMI_GET_STATISTICS_CMDID, 0); + + while (pDCxt->rssiFlag == true) + { + DRIVER_WAIT_FOR_CONDITION(pCxt, &(pDCxt->rssiFlag), false, 1000); + } + + *(uint32_t *)(param_ptr->data) = pDCxt->rssi; + break; + case ATH_GET_TEMPERATURE: + pDCxt->temperatureValid = false; + if (A_OK == wmi_cmd_start(pWmi, NULL, WMI_GET_TEMPERATURE_CMDID, 0)) + { + /* block here until event arrives from wifi device */ + DRIVER_WAIT_FOR_CONDITION(pCxt, &(pDCxt->temperatureValid), true, 1000); + } + if (pDCxt->temperatureValid == false) + { + error = QCA_ERROR; + } + else + { + (((WMI_GET_TEMPERATURE_REPLY *)(param_ptr->data))->tempRegVal) = pDCxt->raw_temperature; + (((WMI_GET_TEMPERATURE_REPLY *)(param_ptr->data))->tempDegree) = pDCxt->tempDegree; + pDCxt->temperatureValid = false; + } + break; + case ATH_GET_COUNTRY_CODE: + pDCxt->countryCodeValid = false; + + if (A_OK == wmi_cmd_start(pWmi, param_ptr->data, WMI_GET_COUNTRY_CODE_CMDID, param_ptr->length)) + { + /* block here until event arrives from wifi device */ + DRIVER_WAIT_FOR_CONDITION(pCxt, &(pDCxt->countryCodeValid), true, 1000); + } + + if (pDCxt->countryCodeValid == false) + { + error = QCA_ERROR; + } + else + { + A_MEMCPY(((WMI_GET_COUNTRY_CODE_REPLY *)(param_ptr->data))->country_code, pDCxt->raw_countryCode, 3); + + pDCxt->countryCodeValid = false; + } + + break; + case ATH_SET_PARAM: + wait_for_status = *((uint32_t *)((uint8_t *)param_ptr->data + param_ptr->length)); + pDCxt->setparamValid = false; + if (A_OK == wmi_cmd_start(pWmi, param_ptr->data, WMI_PARAM_SET_CMDID, param_ptr->length)) + { + if (wait_for_status) + { + /* block here until event arrives from wifi device */ + DRIVER_WAIT_FOR_CONDITION(pCxt, &(pDCxt->setparamValid), true, 1000); + if (pDCxt->setparamValid == false) + { + error = QCA_ERROR; + } + else + { + if (pDCxt->setparamStatus != A_OK) + { + error = QCA_ERROR; + } + } + } + } + else + { + error = QCA_ERROR; + } + break; + case ATH_ROAM_CTRL: + A_MEMCPY( &SCAN_PARAM,&pDCxt->scan_param, sizeof(WMI_SCAN_PARAMS_CMD)); + pRoamCtrl = (WMI_SET_ROAM_CTRL_CMD *) param_ptr->data; + //pDCxt->roam_req_enable = (pRoamCtrl->info.roamMode == 1) ? A_TRUE:A_FALSE ; + if(pRoamCtrl->info.roamMode == 3)//disable roaming and forbid PROREQ_SEND + { + SCAN_PARAM.scanCtrlFlags &= ~ROAM_SCAN_CTRL_FLAGS; + } + else + { + SCAN_PARAM.scanCtrlFlags |= ROAM_SCAN_CTRL_FLAGS ; + } + //wmi_cmd_start(pWmi, param_ptr->data, WMI_SET_ROAM_CTRL_CMDID, sizeof(WMI_SET_ROAM_CTRL_CMD)) ; + if(A_OK != wmi_cmd_start(pWmi, &SCAN_PARAM, WMI_SET_SCAN_PARAMS_CMDID, sizeof(WMI_SCAN_PARAMS_CMD))) + { + error = A_ERROR; + } + else + { + A_MEMCPY(&pDCxt->scan_param, &SCAN_PARAM, sizeof(WMI_SCAN_PARAMS_CMD));//update scan parameters + } + break; + case ATH_SET_CONNECT_STATE_CALLBACK: + DRIVER_SHARED_RESOURCE_ACCESS_ACQUIRE(pCxt); + GET_DRIVER_CXT(pCxt)->connectStateCB = (void *)PTR_CONNECT_CB; + DRIVER_SHARED_RESOURCE_ACCESS_RELEASE(pCxt); + break; + + case ATH_SET_PROBEREQ_CB: + DRIVER_SHARED_RESOURCE_ACCESS_ACQUIRE(pCxt); + GET_DRIVER_CXT(pCxt)->probeReqCB = (void *)PTR_PROBE_CB; + DRIVER_SHARED_RESOURCE_ACCESS_RELEASE(pCxt); + break; + +#if DRIVER_CONFIG_ENABLE_STORE_RECALL + case ATH_DEVICE_SUSPEND_ENABLE: + if (pDCxt->strrclState == STRRCL_ST_DISABLED && + A_OK == wmi_cmd_start(pDCxt->pWmiCxt, &default_strrcl_config_cmd, WMI_STORERECALL_CONFIGURE_CMDID, + sizeof(WMI_STORERECALL_CONFIGURE_CMD))) + { + pDCxt->strrclState = STRRCL_ST_INIT; + error = QCA_OK; + } + else + { + if (pDCxt->strrclState != STRRCL_ST_INIT) + error = QCA_ERROR; + } + break; + + case ATH_DEVICE_SUSPEND_START: + error = QCA_ERROR; + +/* ensure that no power save is used during Suspend. Store-recall and Power save + are not supposed to work together, it is one-or-the-other */ +#if 1 + if (A_OK != move_power_state_to_maxperf(pDCxt, 1)) /* refer POWER_STATE_MOVED_FOR_STRRCL */ + { + status = A_ERROR; + break; + } +#else + if (A_OK != + wmi_cmd_start(pWmi, &max_performance_power_param, WMI_SET_POWER_MODE_CMDID, sizeof(WMI_POWER_MODE_CMD))) + { + error = QCA_ERROR; + } + pDCxt->userPwrMode = MAX_PERF_POWER; +#endif + +#if 0 + STRRCL_RDY_PARAM.sleep_msec = A_CPU2LE32((*PTR_STRRCL_START)); + STRRCL_RDY_PARAM.store_after_tx_empty = 1; + STRRCL_RDY_PARAM.store_after_fresh_beacon_rx = 1; + + if(pDCxt->strrclState == STRRCL_ST_INIT){ + if(((*PTR_STRRCL_START) >= MIN_STRRCL_MSEC) && + A_OK == wmi_cmd_start(pWmi, &STRRCL_RDY_PARAM, + WMI_STORERECALL_HOST_READY_CMDID, + sizeof(WMI_STORERECALL_HOST_READY_CMD))) + { + pDCxt->strrclState = STRRCL_ST_START; + error = QCA_OK; + } + } +#else + if (pDCxt->strrclState == STRRCL_ST_INIT && ((*PTR_STRRCL_START) >= MIN_STRRCL_MSEC)) + { + /* set strrclBlock before call to wmi_storerecall_ready_cmd to prevent + * any potential race conditions with other tasks calling into the + * driver. + */ + pDCxt->strrclBlock = true; + STRRCL_RDY_PARAM.sleep_msec = A_CPU2LE32((*PTR_STRRCL_START)); + STRRCL_RDY_PARAM.store_after_tx_empty = 1; + STRRCL_RDY_PARAM.store_after_fresh_beacon_rx = 1; + + if (A_OK == wmi_cmd_start(pWmi, &STRRCL_RDY_PARAM, WMI_STORERECALL_HOST_READY_CMDID, + sizeof(WMI_STORERECALL_HOST_READY_CMD))) + { + pDCxt->strrclState = STRRCL_ST_START; + status = A_OK; + error = QCA_OK; + } + else + { + pDCxt->strrclBlock = false; + } + } +#endif + break; +#endif /* DRIVER_CONFIG_ENABLE_STORE_RECALL */ + case ATH_SET_PMK: + if (A_OK != wmi_cmd_start(pWmi, PTR_PMK_SET, WMI_SET_PMK_CMDID, sizeof(WMI_SET_PMK_CMD))) + { + error = QCA_ERROR; + } + break; + case ATH_GET_PMK: + pDCxt->conn[pDCxt->devId].wpaPmkValid = false; + + if (A_OK == wmi_cmd_start(pWmi, NULL, WMI_GET_PMK_CMDID, 0)) + { + /* block here until event arrives from wifi device */ + DRIVER_WAIT_FOR_CONDITION(pCxt, &(pDCxt->conn[pDCxt->devId].wpaPmkValid), true, 5000); + + if (pDCxt->conn[pDCxt->devId].wpaPmkValid == false) + { + error = QCA_ERROR; + } + else + { + A_MEMCPY((uint8_t *)param_ptr->data, pDCxt->conn[pDCxt->devId].wpaPmk, WMI_PMK_LEN); + pDCxt->conn[pDCxt->devId].wpaPmkValid = false; + } + } + break; + case ATH_GET_VERSION: + PTR_VERSION->host_ver = pDCxt->hostVersion; + PTR_VERSION->target_ver = pDCxt->targetVersion; + PTR_VERSION->wlan_ver = pDCxt->wlanVersion; + PTR_VERSION->abi_ver = pDCxt->abiVersion; + break; + case ATH_GET_VERSION_STR: +#define PRINT_HOSTFWVERSION(ver) \ + (uint16_t)((ver & 0xF0000000) >> 28), (uint16_t)((ver & 0x0F000000) >> 24), (uint16_t)((ver & 0x00FF0000) >> 16), \ + (uint16_t)(ver & 0x0000FFFF) + sprintf((char *)PTR_VERSION_STR->host_ver, "%u.%u.%u.%u", PRINT_HOSTFWVERSION(pDCxt->hostVersion)); + sprintf((char *)PTR_VERSION_STR->target_ver, "0x%lx", pDCxt->targetVersion); + sprintf((char *)PTR_VERSION_STR->wlan_ver, "%u.%u.%u.%u", PRINT_HOSTFWVERSION(pDCxt->wlanVersion)); + sprintf((char *)PTR_VERSION_STR->abi_ver, "%lu", pDCxt->abiVersion); + break; + case ATH_GET_MACADDR: + A_MEMCPY(param_ptr->data, qca_ptr->ADDRESS, ATH_MAC_LEN); + break; + case ATH_START_WPS: + /* FIXME: there exists the possibility of a race condition if the device has + * sent a WPS event in response to a previous ATH_START_WPS then it becomes + * possible for the driver to misinterpret that event as being the result of + * the most recent ATH_START_WPS. To fix this the wmi command should include + * an ID value that is returned by the WPS event so that the driver can + * accurately match an event from the device to the most recent WPS command. + */ + DRIVER_SHARED_RESOURCE_ACCESS_ACQUIRE(pCxt); + if (pDCxt->wpsBuf) + { + A_NETBUF_FREE(pDCxt->wpsBuf); + pDCxt->wpsBuf = NULL; + } + + pDCxt->wpsEvent = NULL; + + if (pDCxt->wpsState == true) + { + pDCxt->wpsState = false; + } + + DRIVER_SHARED_RESOURCE_ACCESS_RELEASE(pCxt); + + A_MEMZERO(&WPS_START, sizeof(WMI_WPS_START_CMD)); + WPS_START.timeout = PTR_WPS_START->timeout_seconds; + WPS_START.role = + (AP_NETWORK == pDCxt->conn[pDCxt->devId].networkType) ? WPS_REGISTRAR_ROLE : WPS_ENROLLEE_ROLE; + + if (0x02 == PTR_WPS_START->connect_flag) + { + WPS_START.role = WPS_AP_ENROLLEE_ROLE; + } + if (PTR_WPS_START->wps_mode == ATH_WPS_MODE_PIN) + { + WPS_START.config_mode = WPS_PIN_MODE; + WPS_START.wps_pin.pin_length = PTR_WPS_START->pin_length; + A_MEMCPY(WPS_START.wps_pin.pin, PTR_WPS_START->pin, ATH_WPS_PIN_LEN); + } + else if (PTR_WPS_START->wps_mode == ATH_WPS_MODE_PUSHBUTTON) + { + WPS_START.config_mode = WPS_PBC_MODE; + } + else + { + error = A_ERROR; + break; /* early break */ + } + if (AP_NETWORK != pDCxt->conn[pDCxt->devId].networkType) + { + if (0x08 == PTR_WPS_START->connect_flag) + { + /* WPS Request from P2P Module */ + WPS_START.ctl_flag |= 0x1; + } + if (PTR_WPS_START->ssid_info.ssid_len != 0) + { + A_MEMCPY(WPS_START.ssid_info.ssid, PTR_WPS_START->ssid_info.ssid, + PTR_WPS_START->ssid_info.ssid_len); + A_MEMCPY(WPS_START.ssid_info.macaddress, PTR_WPS_START->ssid_info.macaddress, 6); + WPS_START.ssid_info.channel = PTR_WPS_START->ssid_info.channel; + WPS_START.ssid_info.ssid_len = PTR_WPS_START->ssid_info.ssid_len; + } + + /* prevent background scan during WPS */ + A_MEMCPY(&scan_param_cmd, &default_scan_param, sizeof(WMI_SCAN_PARAMS_CMD)); + scan_param_cmd.bg_period = A_CPU2LE16(0xffff); + + if (A_OK != + wmi_cmd_start(pWmi, &scan_param_cmd, WMI_SET_SCAN_PARAMS_CMDID, sizeof(WMI_SCAN_PARAMS_CMD))) + { + error = A_ERROR; + break; + } + } + else + { + WPS_START.ctl_flag |= 0x1; + } + + if (A_OK != wmi_cmd_start(pWmi, &WPS_START, WMI_WPS_START_CMDID, sizeof(WMI_WPS_START_CMD))) + { + error = A_ERROR; + break; + } + + pDCxt->wpsState = true; + pDCxt->wps_in_progress = true; + break; + case ATH_AWAIT_WPS_COMPLETION: + /* await wps completion */ + + if (PTR_WPS_GET->dont_block && pDCxt->wpsState == true) + { + /* the caller does not want to block the task until completion + * so if not yet complete then return immediately with appropriate + * error code. */ + error = A_PENDING; + break; + } + + while (pDCxt->wpsState == true) + { + DRIVER_WAIT_FOR_CONDITION(pCxt, &(pDCxt->wpsState), false, 1000); + } + + /* reach here means wps_in_progress is done whether wps success or fail */ + pDCxt->wps_in_progress = false; + if (pDCxt->wpsBuf != NULL) + { + if (pDCxt->wpsEvent != NULL) + { + pWpsEv = (WMI_WPS_PROFILE_EVENT *)pDCxt->wpsEvent; + + if (pWpsEv->status == WPS_STATUS_SUCCESS) + { + CRED_PTR = &(pWpsEv->credential); + PTR_WPS_GET->error = ATH_WPS_ERROR_SUCCESS; + A_MEMCPY(PTR_WPS_GET->ssid, CRED_PTR->ssid, CRED_PTR->ssid_len); + PTR_WPS_GET->ssid_len = CRED_PTR->ssid_len; + PTR_WPS_GET->ssid[CRED_PTR->ssid_len] = '\0'; + PTR_WPS_GET->ap_channel = CRED_PTR->ap_channel; + + if (CRED_PTR->key_len) + { + /* the encr_type may have multiple options (bits) set + * therefore the order in which we test for support is + * important. this code tests for AES first and so AES + * will be the default when AES is at least one option. + */ + if (CRED_PTR->encr_type & WPS_CRED_ENCR_AES) + { + PTR_WPS_GET->cipher.ucipher = AES_CRYPT; + PTR_WPS_GET->cipher.mcipher = AES_CRYPT; + } + else if (CRED_PTR->encr_type & WPS_CRED_ENCR_TKIP) + { + PTR_WPS_GET->cipher.ucipher = TKIP_CRYPT; + PTR_WPS_GET->cipher.mcipher = TKIP_CRYPT; + } + else if (CRED_PTR->encr_type & WPS_CRED_ENCR_WEP) + { + PTR_WPS_GET->cipher.ucipher = WEP_CRYPT; + PTR_WPS_GET->cipher.mcipher = WEP_CRYPT; + } + /* as with encr_type the auth_type field may contain multiple options. + * As such we test for options in a preferred order with WPA2 as top + * followed by WPA and lastly by the 2 WEP options. */ + if (CRED_PTR->auth_type & WPS_CRED_AUTH_WPA2PSK) + { + PTR_WPS_GET->sec_type = QCA_MEDIACTL_SECURITY_TYPE_WPA2; + GET_DRIVER_COMMON(pCxt)->securityType = QCA_MEDIACTL_SECURITY_TYPE_WPA2; + A_MEMCPY(PTR_WPS_GET->u.passphrase, CRED_PTR->key, CRED_PTR->key_len); + PTR_WPS_GET->u.passphrase[CRED_PTR->key_len] = '\0'; + } + else if (CRED_PTR->auth_type & WPS_CRED_AUTH_WPAPSK) + { + PTR_WPS_GET->sec_type = QCA_MEDIACTL_SECURITY_TYPE_WPA; + GET_DRIVER_COMMON(pCxt)->securityType = QCA_MEDIACTL_SECURITY_TYPE_WPA; + A_MEMCPY(PTR_WPS_GET->u.passphrase, CRED_PTR->key, CRED_PTR->key_len); + PTR_WPS_GET->u.passphrase[CRED_PTR->key_len] = '\0'; + } + else if ((CRED_PTR->auth_type & WPS_CRED_AUTH_OPEN) || + (CRED_PTR->auth_type & WPS_CRED_AUTH_SHARED)) + { + PTR_WPS_GET->sec_type = QCA_MEDIACTL_SECURITY_TYPE_WEP; + GET_DRIVER_COMMON(pCxt)->securityType = QCA_MEDIACTL_SECURITY_TYPE_WEP; + A_MEMCPY(PTR_WPS_GET->u.wepkey, CRED_PTR->key, CRED_PTR->key_len); + PTR_WPS_GET->u.wepkey[CRED_PTR->key_len] = '\0'; + PTR_WPS_GET->key_index = CRED_PTR->key_idx; + } + else + { + /* this driver does not support these modes: WPS_CRED_AUTH_WPA || WPS_CRED_AUTH_WPA2 */ + error = A_ERROR; + pDCxt->wps_in_progress = false; + break; + } + } + else + { + /* no security */ + PTR_WPS_GET->sec_type = QCA_MEDIACTL_SECURITY_TYPE_NONE; + GET_DRIVER_COMMON(pCxt)->securityType = QCA_MEDIACTL_SECURITY_TYPE_NONE; + PTR_WPS_GET->cipher.ucipher = NONE_CRYPT; + PTR_WPS_GET->cipher.mcipher = NONE_CRYPT; + } + } + else if (pWpsEv->status == WPS_STATUS_FAILURE) + { + if (pWpsEv->error_code < sizeof(const_wps_error_code_translation) / sizeof(uint8_t)) + { + PTR_WPS_GET->error = const_wps_error_code_translation[pWpsEv->error_code]; + } + else + { + //NOTE: Change was demanded by Coverity, set 'error' instead 'return', need to free netbuf + //Former code: PTR_WPS_GET->error = const_wps_error_code_translation[pWpsEv->error_code]; + assert(0); + error = QCA_ERROR; + } + pDCxt->wps_in_progress = false; + } + pDCxt->wpsEvent = NULL; + } + + A_NETBUF_FREE(pDCxt->wpsBuf); + pDCxt->wpsBuf = NULL; + /* ensure that the device is disconnected from the wps session */ + if (AP_NETWORK == pDCxt->conn[pDCxt->devId].networkType) + { + pDCxt->wps_in_progress = false; + break; + } + +#if ENABLE_P2P_MODE + if (1 == pDCxt->p2p_avail) + { + break; + } +#endif + if (wmi_cmd_start(pDCxt->pWmiCxt, NULL, WMI_DISCONNECT_CMDID, 0) != A_OK) + { + pDCxt->wps_in_progress = false; + error = A_ERROR; + break; + } + } + else + { + pDCxt->wps_in_progress = false; + error = A_ERROR; + } + break; + case ATH_MAC_TX_RAW: + /* FIXME: need away to hold the buffer until the transmit is complete. for + * now we block the thread until the transmit completes. */ + if ((PCB_PTR = A_NETBUF_ALLOC(0)) == NULL) + { + error = QCA_ERR_ALLOC_PCB; + break; + } + + A_NETBUF_APPEND_FRAGMENT(PCB_PTR, PTR_MAC_TX->buffer, PTR_MAC_TX->length); + + // ensure there is enough headroom to complete the tx operation + if (A_NETBUF_HEADROOM(PCB_PTR) < (int32_t)(sizeof(WMI_DATA_HDR) + HTC_HDR_LENGTH + WMI_MAX_TX_META_SZ)) + { + error = QCA_ERR_ALLOC_PCB; + A_NETBUF_FREE(PCB_PTR); + break; + } + + if (A_OK != TxRawPacket(pCxt, (void *)PCB_PTR, &(PTR_MAC_TX->params))) + { + A_NETBUF_FREE(PCB_PTR); + error = QCA_ERROR; + break; + } + break; + case ATH_SET_CHANNEL: + pDCxt->conn[pDCxt->devId].channelHint = (uint16_t)(*(PTR_SET_CHAN)); + SET_CHANNEL_PARAM.channel = A_CPU2LE16(pDCxt->conn[pDCxt->devId].channelHint); + + if (A_OK != wmi_cmd_start(pWmi, &SET_CHANNEL_PARAM, WMI_SET_CHANNEL_CMDID, sizeof(uint16_t))) + { + error = QCA_ERROR; + break; + } + break; + case ATH_SET_AGGREGATION: +#if WLAN_CONFIG_11N_AGGR_SUPPORT + pDCxt->txAggrTidMask = PTR_SET_AGGR->txTIDMask; + pDCxt->rxAggrTidMask = PTR_SET_AGGR->rxTIDMask; + AGGR_PARAM.tx_allow_aggr = A_CPU2LE16(pDCxt->txAggrTidMask); + AGGR_PARAM.rx_allow_aggr = A_CPU2LE16(pDCxt->rxAggrTidMask); + wmi_cmd_start(pWmi, &AGGR_PARAM, WMI_ALLOW_AGGR_CMDID, sizeof(WMI_ALLOW_AGGR_CMD)); +#endif /* WLAN_CONFIG_11N_AGGR_SUPPORT */ + break; + case ATH_ASSERT_DUMP: + /* setup driver thread to perform operation on behalf of this thread. + * this will avoid accessing HCD by multiple threads. */ + if (pDCxt->asynchRequest == NULL) + { + pDCxt->asynchRequest = config_dump_target_assert_info; + DRIVER_WAKE_DRIVER(pCxt); + } + break; + case ATH_PROGRAM_FLASH: + status = + BMIWriteMemory(pCxt, PTR_FLASH_CMD->load_addr, (uint8_t *)PTR_FLASH_CMD->buffer, PTR_FLASH_CMD->length); + + if (status == A_OK) + { + PTR_FLASH_CMD->result = 1; + } + else + { + PTR_FLASH_CMD->result = status; + } + break; + case ATH_EXECUTE_FLASH: + + PARAM = A_CPU2LE32(PTR_FLASH_CMD->result); + status = BMIExecute(pCxt, PTR_FLASH_CMD->load_addr, &PARAM); + + if (status == A_OK) + { + PTR_FLASH_CMD->result = PARAM; + } + else + { + PTR_FLASH_CMD->result = 0; + } + break; + case ATH_GET_TX_STATUS: + PTR_TX_STATUS_CMD->status = Api_TxGetStatus(pCxt); + break; + case ATH_GET_RATE: + { + if (A_OK != wmi_cmd_start(pWmi, NULL, WMI_GET_BITRATE_CMDID, 0)) + { + error = QCA_ERROR; + } + } + break; + case ATH_SET_PROMISCUOUS_MODE: + pDCxt->promiscuous_mode = (PTR_PROM_MODE->enable == 0) ? 0 : 1; + GET_DRIVER_CXT(pCxt)->promiscuous_cb = (void *)PTR_PROM_MODE->cb; + SET_PROM_PARAM.enable = pDCxt->promiscuous_mode; + SET_PROM_PARAM.filters = PTR_PROM_MODE->filter_flags; + A_MEMCPY(SET_PROM_PARAM.srcAddr, &(PTR_PROM_MODE->src_mac[0]), ATH_MAC_LEN); + A_MEMCPY(SET_PROM_PARAM.dstAddr, &(PTR_PROM_MODE->dst_mac[0]), ATH_MAC_LEN); + + if (A_OK != wmi_cmd_start(pWmi, &SET_PROM_PARAM, WMI_SET_FILTERED_PROMISCUOUS_MODE_CMDID, + sizeof(WMI_SET_FILTERED_PROMISCUOUS_MODE_CMD))) + { + error = QCA_ERROR; + } + break; + case ATH_GET_REG_DOMAIN: + PTR_REG_DOMAIN_CMD->domain = GET_DRIVER_COMMON(pCxt)->regCode; + break; + case ATH_START_SCAN_EXT: + GET_DRIVER_COMMON(pCxt)->extended_scan = 1; + error = scan_setup(pCxt, pWmi, NULL); + break; + case ATH_GET_SCAN_EXT: + wait_scan_done(pCxt, pWmi); + PTR_EXT_SCAN_CMD->scan_list = (ATH_SCAN_EXT *)GET_DRIVER_COMMON(pCxt)->pScanOut; + PTR_EXT_SCAN_CMD->num_entries = GET_DRIVER_COMMON(pCxt)->scanOutCount; + break; + case ATH_GET_LAST_ERROR: + *PTR_LAST_ERROR = last_driver_error; + break; +#if ENABLE_AP_MODE + // case ATH_SET_EZCONN: + // pDCxt->ezConnectCmd = 1; + // break; + case ATH_CONFIG_AP: + { + ATH_AP_PARAM_STRUCT *ap_param = (ATH_AP_PARAM_STRUCT *)param_ptr->data; + if (AP_SUB_CMD_WPS_FLAG == ap_param->cmd_subset) + { + pDCxt->apmodeWPS = 1; + + break; + } + wmi_ap_set_param(pWmi, (void *)param_ptr->data); + } + break; +#endif /* ENABLE_AP_MODE */ + case ATH_GET_CHANNEL: + *((uint16_t *)param_ptr->data) = pDCxt->conn[pDCxt->devId].bssChannel; + break; + case ATH_GET_CHANNELHINT: + *((uint16_t *)param_ptr->data) = pDCxt->conn[pDCxt->devId].channelHint; + break; +#if ENABLE_P2P_MODE + case ATH_SET_P2P_CALLBACK: + + if (GET_DRIVER_COMMON(pCxt)->p2pEvtState == true) + { + if (DRIVER_WAIT_FOR_CONDITION(pCxt, &(GET_DRIVER_COMMON(pCxt)->p2pEvtState), false, 5000) != A_OK) + { + GET_DRIVER_COMMON(pCxt)->p2pEvtState = false; + status = A_ERROR; + break; + } + GET_DRIVER_COMMON(pCxt)->p2pEvtState = false; + } + A_MEMCPY(param_ptr->data, GET_DRIVER_COMMON(pCxt)->pScanOut, P2P_EVT_BUF_SIZE); + + break; + case ATH_P2P_EVENT_CALLBACK: + if (GET_DRIVER_COMMON(pCxt)->p2pevtflag == true) + { + A_MEMCPY(param_ptr->data, GET_DRIVER_COMMON(pCxt)->pScanOut, 516); + GET_DRIVER_COMMON(pCxt)->p2pevtflag = false; + } + else + { + status = A_ERROR; + } + break; + case ATH_P2P_APMODE: + { + p2pGroup = (WMI_P2P_GRP_INIT_CMD *)param_ptr->data; + + pDCxt->p2p_avail = 1; + pDCxt->conn[pDCxt->devId].networkType = AP_NETWORK; + + if (p2pGroup->group_formation) + { + wmi_cmd_start(pWmi, p2pGroup, WMI_P2P_GRP_INIT_CMDID, sizeof(WMI_P2P_GRP_INIT_CMD)); + } + + if (Api_ConnectWiFi(pCxt) != A_OK) + { + status = A_ERROR; + } + pDCxt->userPwrMode = MAX_PERF_POWER; + } + break; + case ATH_P2P_APMODE_PP: + { +#if 1 + A_MEMCPY(((struct wmi_t *)pWmi)->apPassPhrase.passphrase, PTR_PASS_PHRASE->passphrase, + PTR_PASS_PHRASE->passphrase_len); + ((struct wmi_t *)pWmi)->apPassPhrase.passphrase_len = PTR_PASS_PHRASE->passphrase_len; + A_MEMCPY(((struct wmi_t *)pWmi)->apPassPhrase.ssid, PTR_PASS_PHRASE->ssid, PTR_PASS_PHRASE->ssid_len); + ((struct wmi_t *)pWmi)->apPassPhrase.ssid_len = PTR_PASS_PHRASE->ssid_len; + // if (((struct wmi_t *)pWmi)->apPassPhrase.ssid_len != 0) { + if (A_OK != wmi_cmd_start(pWmi, &((struct wmi_t *)pWmi)->apPassPhrase, WMI_SET_PASSPHRASE_CMDID, + sizeof(WMI_SET_PASSPHRASE_CMD))) + { + status = A_ERROR; + } + +//} +#endif + } + break; + case ATH_P2P_FIND: + { + pDCxt->p2p_avail = 1; + if (wmi_cmd_start(pWmi, (WMI_P2P_FIND_CMD *)param_ptr->data, WMI_P2P_FIND_CMDID, + sizeof(WMI_P2P_FIND_CMD)) != A_OK) + { + status = A_ERROR; + } + } + break; + case ATH_P2P_CONNECT: + { +#if 0 + if(wmi_p2p_go_neg_start(pWmi, (WMI_P2P_GO_NEG_START_CMD *)param_ptr->data) != A_OK) + { + status = A_ERROR; + } +#endif + } + break; + case ATH_P2P_CONNECT_CLIENT: + { + WMI_P2P_FW_CONNECT_CMD_STRUCT p2p_connect_param; + GET_DRIVER_COMMON(pCxt)->p2pEvtState = true; + A_MEMZERO(&p2p_connect_param, sizeof(WMI_P2P_FW_CONNECT_CMD_STRUCT)); + A_MEMCPY(&p2p_connect_param, (WMI_P2P_FW_CONNECT_CMD_STRUCT *)param_ptr->data, + sizeof(WMI_P2P_FW_CONNECT_CMD_STRUCT)); + if ((p2p_connect_param.go_intent >= 10) || (p2p_connect_param.go_intent == 15)) + { + pDCxt->conn[pDCxt->devId].networkType = AP_NETWORK; + } + if ((p2p_connect_param.go_intent <= 9) || (p2p_connect_param.go_intent == 0)) + { + pDCxt->conn[pDCxt->devId].networkType = INFRA_NETWORK; + } + if (wmi_cmd_start(pWmi, (WMI_P2P_FW_CONNECT_CMD_STRUCT *)param_ptr->data, WMI_P2P_CONNECT_CMDID, + sizeof(WMI_P2P_FW_CONNECT_CMD_STRUCT)) != A_OK) + { + status = A_ERROR; + } + } + break; + case ATH_P2P_LISTEN: + { + uint32_t time_out_val; + A_MEMCPY(&time_out_val, param_ptr->data, sizeof(uint32_t)); + if (wmi_cmd_start(pWmi, &time_out_val, WMI_P2P_LISTEN_CMDID, sizeof(time_out_val)) != A_OK) + { + status = A_ERROR; + } + } + break; + case ATH_P2P_CANCEL: + { + if (wmi_cmd_start(pWmi, NULL, WMI_P2P_CANCEL_CMDID, 0) != A_OK) + { + status = A_ERROR; + } + } + break; + case ATH_P2P_STOP: + { + if (wmi_cmd_start(pWmi, NULL, WMI_P2P_STOP_FIND_CMDID, 0) != A_OK) + { + status = A_ERROR; + } + } + break; + case ATH_P2P_NODE_LIST: + { + GET_DRIVER_COMMON(pCxt)->p2pEvtState = true; + if (wmi_cmd_start(pWmi, NULL, WMI_P2P_GET_NODE_LIST_CMDID, 0) != A_OK) + { + status = A_ERROR; + } + } + break; + case ATH_P2P_SET_CONFIG: + { + if (wmi_cmd_start(pWmi, (WMI_P2P_FW_SET_CONFIG_CMD *)param_ptr->data, WMI_P2P_SET_CONFIG_CMDID, + sizeof(WMI_P2P_FW_SET_CONFIG_CMD)) != A_OK) + { + status = A_ERROR; + } + } + break; + case ATH_P2P_WPS_CONFIG: + { + if (wmi_cmd_start(pWmi, (WMI_WPS_SET_CONFIG_CMD *)param_ptr->data, WMI_WPS_SET_CONFIG_CMDID, + sizeof(WMI_WPS_SET_CONFIG_CMD)) != A_OK) + { + status = A_ERROR; + } + } + break; + case ATH_P2P_AUTH: + { + if (wmi_cmd_start(pWmi, (WMI_P2P_FW_CONNECT_CMD_STRUCT *)param_ptr->data, WMI_P2P_AUTH_GO_NEG_CMDID, + sizeof(WMI_P2P_FW_CONNECT_CMD_STRUCT)) != A_OK) + { + status = A_ERROR; + } + } + break; + case ATH_P2P_DISC_REQ: + { + if (wmi_cmd_start(pWmi, (WMI_P2P_FW_PROV_DISC_REQ_CMD *)param_ptr->data, WMI_P2P_FW_PROV_DISC_REQ_CMDID, + sizeof(WMI_P2P_FW_PROV_DISC_REQ_CMD)) != A_OK) + { + status = A_ERROR; + } + GET_DRIVER_COMMON(pCxt)->p2pEvtState = true; + } + break; + case ATH_P2P_SET: + { + if (wmi_cmd_start(pWmi, (WMI_P2P_SET_CMD *)param_ptr->data, WMI_P2P_SET_CMDID, sizeof(WMI_P2P_SET_CMD)) != + A_OK) + { + status = A_ERROR; + } + } + break; +#if 1 + case ATH_P2P_INVITE_AUTH: + { + GET_DRIVER_COMMON(pCxt)->p2pEvtState = true; + if (wmi_cmd_start(pWmi, (WMI_P2P_FW_INVITE_REQ_RSP_CMD *)param_ptr->data, WMI_P2P_INVITE_REQ_RSP_CMDID, + sizeof(WMI_P2P_FW_INVITE_REQ_RSP_CMD)) != A_OK) + { + status = A_ERROR; + } + } + break; + case ATH_P2P_PERSISTENT_LIST: + { + GET_DRIVER_COMMON(pCxt)->p2pEvtState = true; + if (wmi_cmd_start(pWmi, NULL, WMI_P2P_LIST_PERSISTENT_NETWORK_CMDID, 0) != A_OK) + { + status = A_ERROR; + } + } + break; + case ATH_P2P_INVITE: + { + p2pInvite = (WMI_P2P_INVITE_CMD *)param_ptr->data; + // p2pInvite->is_persistent = 1; // for now we do invitation for persistent clients + p2pInvite->dialog_token = 1; + if (wmi_cmd_start(pWmi, (WMI_P2P_INVITE_CMD *)param_ptr->data, WMI_P2P_INVITE_CMDID, + sizeof(WMI_P2P_INVITE_CMD)) != A_OK) + { + status = A_ERROR; + } + } + break; +#endif + case ATH_P2P_JOIN: + { + pP2PConnect = (WMI_P2P_FW_CONNECT_CMD_STRUCT *)param_ptr->data; + A_MEMZERO(&WPS_START, sizeof(WMI_WPS_START_CMD)); + WPS_START.timeout = 30; + WPS_START.role = WPS_ENROLLEE_ROLE; + +#if ENABLE_SCC_MODE + int num_dev = WLAN_NUM_OF_DEVICES; + + if ((num_dev > 1) && (pDCxt->conn[1].isConnected == true) && (pP2PConnect->go_oper_freq == 0)) + { + error = A_ERROR; + break; + } + if ((num_dev > 1) && (pDCxt->conn[1].isConnected == true)) + { + if (pP2PConnect->go_oper_freq != pDCxt->conn[1].channelHint) + { + error = A_ERROR; + break; + } + } +#endif /* ENABLE_SCC_MODE */ + if (pP2PConnect->wps_method == WPS_PBC) + { + WPS_START.config_mode = WPS_PBC_MODE; + } + else if (pP2PConnect->wps_method == WPS_PIN_DISPLAY || pP2PConnect->wps_method == WPS_PIN_KEYPAD) + { + WPS_START.config_mode = WPS_PIN_MODE; + A_MEMCPY(WPS_START.wps_pin.pin, p2p_key_val.wps_pin, WPS_PIN_LEN); + WPS_START.wps_pin.pin_length = WPS_PIN_LEN; + } + else + { + status = A_ERROR; + break; /* early break */ + } + if (pP2PConnect->peer_go_ssid.ssidLength != 0) + { + memcpy(WPS_START.ssid_info.ssid, pP2PConnect->peer_go_ssid.ssid, pP2PConnect->peer_go_ssid.ssidLength); + memcpy(WPS_START.ssid_info.macaddress, pP2PConnect->peer_addr, 6); + WPS_START.ssid_info.ssid_len = pP2PConnect->peer_go_ssid.ssidLength; + } + + /* prevent background scan during WPS */ + A_MEMCPY(&scan_param_cmd, &default_scan_param, sizeof(WMI_SCAN_PARAMS_CMD)); + scan_param_cmd.bg_period = A_CPU2LE16(0xffff); + wmi_cmd_start(pWmi, &scan_param_cmd, WMI_SET_SCAN_PARAMS_CMDID, sizeof(WMI_SCAN_PARAMS_CMD)); + WPS_START.ctl_flag |= 0x1; + wmi_cmd_start(pWmi, &WPS_START, WMI_WPS_START_CMDID, sizeof(WMI_WPS_START_CMD)); + } + break; +#if 0 + case ATH_P2P_INV_CONNECT: + { + pInvitation_connect_param = (WMI_PERSISTENT_MAC_LIST *)param_ptr->data; + + p2p_invite_conn_cmd.ssidLength = strlen(pInvitation_connect_param->ssid); + p2p_invite_conn_cmd.networkType = INFRA_NETWORK; + p2p_invite_conn_cmd.dot11AuthMode = OPEN_AUTH; + p2p_invite_conn_cmd.authMode = WPA2_PSK_AUTH; + p2p_invite_conn_cmd.pairwiseCryptoType = AES_CRYPT; + p2p_invite_conn_cmd.pairwiseCryptoLen = 0; + p2p_invite_conn_cmd.groupCryptoType = AES_CRYPT; + p2p_invite_conn_cmd.groupCryptoLen = 0; + p2p_invite_conn_cmd.channel = 0; + p2p_invite_conn_cmd.ctrl_flags = A_CPU2LE32(DEFAULT_CONNECT_CTRL_FLAGS |CONNECT_DO_WPA_OFFLOAD | CONNECT_IGNORE_WPAx_GROUP_CIPHER); + + if (pInvitation_connect_param->ssid != NULL) { + A_MEMCPY(p2p_invite_conn_cmd.ssid, pInvitation_connect_param->ssid, strlen(pInvitation_connect_param->ssid)); + } + + status = wmi_cmd_start(pDCxt->pWmiCxt, (void*)&p2p_invite_conn_cmd, + WMI_CONNECT_CMDID, sizeof(WMI_CONNECT_CMD)); + + if(status != A_OK){ + break; + } + + } + break; +#endif + case ATH_P2P_JOIN_PROFILE: + { + pP2PConnect = (WMI_P2P_FW_CONNECT_CMD_STRUCT *)param_ptr->data; + A_MEMZERO(&JOIN_CONN_PROF, sizeof(WMI_P2P_FW_CONNECT_CMD_STRUCT)); + A_MEMCPY(&JOIN_CONN_PROF, pP2PConnect, sizeof(WMI_P2P_FW_CONNECT_CMD_STRUCT)); + wmi_cmd_start(pWmi, &JOIN_CONN_PROF, WMI_P2P_SET_JOIN_PROFILE_CMDID, sizeof(WMI_P2P_FW_CONNECT_CMD_STRUCT)); + } + break; + case ATH_P2P_SWITCH: + { + wmi_cmd_start(pWmi, (WMI_P2P_SET_PROFILE_CMD *)param_ptr->data, WMI_P2P_SET_PROFILE_CMDID, + sizeof(WMI_P2P_SET_PROFILE_CMD)); + GET_DRIVER_COMMON(pCxt)->p2pEvtState = false; + GET_DRIVER_COMMON(pCxt)->p2pevtflag = false; + // TODO: p2p_avail need to set to 0 after p2p off + } + break; +#if 1 + case ATH_P2P_SET_NOA: + { + wmi_p2p_set_noa(pWmi, (WMI_NOA_INFO_STRUCT *)param_ptr->data); + } + break; + case ATH_P2P_SET_OPPPS: + { + wmi_p2p_set_oppps(pWmi, (WMI_OPPPS_INFO_STRUCT *)param_ptr->data); + } + break; + case ATH_P2P_SDPD: + { + wmi_sdpd_send_cmd(pWmi, (WMI_P2P_SDPD_TX_CMD *)param_ptr->data); + } + break; +#endif +#endif + case ATH_ONOFF_GTX: + { + A_MEMZERO(>X_PARAM,sizeof(GTX_PARAM)); + GTX_PARAM.enable = *((uint8_t *)param_ptr->data); + GTX_PARAM.nextProbeCount = 5; // if 5 packets are successfully transmitted reduce the power level + GTX_PARAM.forceBackOff = 0; + if (A_OK != wmi_cmd_start(pWmi, >X_PARAM, WMI_GREENTX_PARAMS_CMDID, sizeof(WMI_GREENTX_PARAMS_CMD))) + { + error = QCA_ERROR; + } + } + break; + + case ATH_ONOFF_LPL: + { + // WMI_LPL_FORCE_ENABLE_CMD lplParams = {0}; + LPL_PARAM.lplPolicy = *((uint8_t *)PTR_LPL); + + if (A_OK != wmi_cmd_start(pWmi, &LPL_PARAM, WMI_LPL_FORCE_ENABLE_CMDID, sizeof(WMI_LPL_FORCE_ENABLE_CMD))) + { + error = QCA_ERROR; + } + } + break; + case ATH_SET_TX_PWR_SCALE: + { + if (A_OK != wmi_cmd_start(pWmi, (WMI_SET_TX_POWER_SCALE_CMD *)param_ptr->data, WMI_SET_TX_POWER_SCALE_CMDID, + sizeof(WMI_SET_TX_POWER_SCALE_CMD))) + { + error = QCA_ERROR; + } + } + break; + case ATH_SET_PROBEREQ_EV_ENABLE: + { + if (A_OK != wmi_cmd_start(pWmi, (WMI_PROBE_REQ_REPORT_CMD_STRUCT *)param_ptr->data, + WMI_WLAN_SET_PROBEREQ_ENABLE_CMDID, sizeof(WMI_PROBE_REQ_REPORT_CMD_STRUCT))) + { + error = QCA_ERROR; + } + } + break; + + case ATH_SET_RATE: + { + if (A_OK != wmi_cmd_start(pWmi, (WMI_BIT_RATE_CMD *)param_ptr->data, WMI_SET_BITRATE_CMDID, + sizeof(WMI_BIT_RATE_CMD))) + { + error = QCA_ERROR; + } + } + break; + case ATH_PROGRAM_MAC_ADDR: + { + if (PTR_MAC_ADDR == NULL) + { + error = QCA_ERROR; + } + else + { +#if DRIVER_CONFIG_PROGRAM_MAC_ADDR + if (A_OK != Api_ProgramMacAddress(pCxt, PTR_MAC_ADDR->addr, param_ptr->length, &PTR_MAC_ADDR->result)) + { + error = QCA_ERROR; + } +#else + PTR_MAC_ADDR->result = ATH_PROGRAM_MAC_RESULT_DRIVER_FAILED; + error = QCA_ERROR; // command not supported by this build +#endif + } + } + break; + + case ATH_GPIO_CMD: + { + if (A_OK != wmi_cmd_start(pWmi, param_ptr->data, WMI_EXTENSION_CMDID, param_ptr->length)) + { + status = A_ERROR; + } + break; + } + + case ATH_PFM_CMD: + pDCxt->pfmDone = false; + + if (A_OK != wmi_cmd_start(pWmi, param_ptr->data, WMI_PFM_GET_CMDID, param_ptr->length)) + { + status = A_ERROR; + } + /* block until data return */ + DRIVER_WAIT_FOR_CONDITION(pCxt, &(pDCxt->pfmDone), true, 5000); + break; + case ATH_SET_POWER: + if (A_OK != Api_SetPowerMode(pCxt, (POWER_MODE *)param_ptr->data)) + { + status = A_ERROR; + } + break; + case ATH_DSET_READ_CMD: + if (A_OK != wmi_cmd_start(pWmi, param_ptr->data, WMI_HOST_DSET_LARGE_READ_CMDID, param_ptr->length)) + { + status = A_ERROR; + } + break; + case ATH_DSET_WRITE_CMD: + if (A_OK != wmi_cmd_start(pWmi, param_ptr->data, WMI_HOST_DSET_LARGE_WRITE_CMDID, param_ptr->length)) + { + status = A_ERROR; + } + break; + case ATH_DSET_OP_CMD: + { + struct WMIX_DSET_OP_SET_CMD + { + WMIX_DSET_CMD_HDR cmd; + uint32_t dset_id; + } * pCmd; + HOST_DSET_HANDLE *pDsetHandle; + + pDCxt->dset_op_done = false; + + if (A_OK != wmi_cmd_start(pWmi, param_ptr->data, WMI_DSET_OP_CMDID, param_ptr->length)) + { + error = A_ERROR; + } + + pCmd = (struct WMIX_DSET_OP_SET_CMD *)param_ptr->data; + pDsetHandle = dset_find_handle(pCmd->dset_id); + + //NOTE: coverity fix + if (NULL == pDsetHandle) + { + error = A_ERROR; + } + else if (pDsetHandle->cb == NULL) + { + if (pDCxt->dset_op_done == false) + /* block until data return */ + DRIVER_WAIT_FOR_CONDITION(pCxt, &(pDCxt->dset_op_done), true, 5000); + if (pDCxt->dset_op_done == true && pDCxt->setparamStatus == 0) + error = A_OK; + else + error = A_ERROR; + } + else + status = A_PENDING; + } + break; + case ATH_SET_WEPKEY: + /* copy wep keys to driver context for use later during connect */ + if (((PTR_WEP_IN->defKeyIndex - 1) < WMI_MIN_KEY_INDEX) || + ((PTR_WEP_IN->defKeyIndex - 1) > WMI_MAX_KEY_INDEX) || (PTR_WEP_IN->numKeys > WMI_MAX_KEY_INDEX + 1) || + /* user passes in num digits as keyLength */ + ((PTR_WEP_IN->keyLength != WEP_SHORT_KEY * 2) && (PTR_WEP_IN->keyLength != WEP_LONG_KEY * 2) && + /* user passes in num digits as keyLength */ + (PTR_WEP_IN->keyLength != WEP_SHORT_KEY) && (PTR_WEP_IN->keyLength != WEP_LONG_KEY))) + { + return A_ERROR; + } + + pDCxt->conn[devId].wepDefTxKeyIndex = (uint8_t)(PTR_WEP_IN->defKeyIndex - 1); + + for (i = 0; i < PTR_WEP_IN->numKeys; i++) + { + if ((PTR_WEP_IN->keyLength == WEP_SHORT_KEY) || (PTR_WEP_IN->keyLength == WEP_LONG_KEY)) + { + A_MEMCPY(pDCxt->conn[devId].wepKeyList[i].key, PTR_WEP_IN->keys[i], PTR_WEP_IN->keyLength); + pDCxt->conn[devId].wepKeyList[i].keyLen = (uint8_t)PTR_WEP_IN->keyLength; + } + else + { + pDCxt->conn[devId].wepKeyList[i].keyLen = (uint8_t)(PTR_WEP_IN->keyLength >> 1); + A_MEMZERO(pDCxt->conn[devId].wepKeyList[i].key, MAX_WEP_KEY_SZ); + /* convert key data from string to bytes */ + for (ii = 0; ii < PTR_WEP_IN->keyLength; ii++) + { + if ((val = Util_Ascii2Hex(PTR_WEP_IN->keys[i][ii])) == 0xff) + { + return A_ERROR; + } + if ((ii & 1) == 0) + { + val <<= 4; + } + pDCxt->conn[devId].wepKeyList[i].key[ii >> 1] |= val; + } + } + } + break; + case ATH_GET_WEPKEY: + if ((PTR_WEP_IN->defKeyIndex - 1) < 1 || (PTR_WEP_IN->defKeyIndex - 1) > WMI_MAX_KEY_INDEX + 1) + return A_ERROR; + + // NOTE: Change was demanded by Coverity + // 'defKeyIndex' is in range of 'wepKeyList' + if (PTR_WEP_IN->defKeyIndex <= (sizeof(pDCxt->conn[devId].wepKeyList) / sizeof(pDCxt->conn[devId].wepKeyList[0]))) + { + A_WEPKEY_T *conn_key = &pDCxt->conn[devId].wepKeyList[PTR_WEP_IN->defKeyIndex - 1]; + // 'conn_key->keyLen' does not exceed 'keys[0]' + if (sizeof(PTR_WEP_IN->keys[0]) >= conn_key->keyLen) + { + A_MEMCPY(PTR_WEP_IN->keys[0], conn_key->key, conn_key->keyLen); + } + else + { + error = QCA_ERROR; + } + } + else + { + error = QCA_ERROR; + } + + break; + case ATH_SET_WEPINDEX: + { + uint32_t index = *(uint32_t *)PTR_WEP_INDEX; + + if (index < 1 || index > WMI_MAX_KEY_INDEX + 1) + return A_ERROR; + + pDCxt->conn[devId].wepDefTxKeyIndex = (uint8_t)(index - 1); + } + break; + case ATH_GET_WEPINDEX: + *(uint32_t *)PTR_WEP_INDEX = pDCxt->conn[devId].wepDefTxKeyIndex; + break; + case ATH_PROGRAM_COUNTRY_CODE: + if (PTR_COUNTRY_CODE == NULL) + { + error = QCA_ERROR; + } + else + { + if (A_OK != Api_ProgramCountryCode(pCxt, PTR_COUNTRY_CODE->countryCode, param_ptr->length, + &PTR_COUNTRY_CODE->result)) + { + error = QCA_ERROR; + } + QCADRV_PRINTF("the set country code is %c, %c\n", PTR_COUNTRY_CODE->countryCode[0], + PTR_COUNTRY_CODE->countryCode[1]); + } + break; + + case ATH_SET_APPIE: + if (A_OK != wmi_set_appie_cmd(pWmi, (void *)param_ptr->data)) + { + status = A_ERROR; + } + break; + + case ATH_WLAN_WPS_INIT_KEY: + pDCxt->wps_init_key = (boolean)A_ERROR; + if (A_OK == wmi_cmd_start(pWmi, NULL, WMI_WLAN_WPS_INIT_KEY_CMDID, 0)) + { + /* block here until event arrives from wifi device */ + DRIVER_WAIT_FOR_CONDITION(pCxt, &(pDCxt->wps_init_key), true, 4000); + } + if (pDCxt->wps_init_key != A_OK){ + error = A_ERROR; + printf("wps init failed\n"); + } + else + { + error = A_OK; + printf("wps init done\n"); + } + break; + + case ATH_HEARTBEAT_CHALLEANGE: + pDCxt->hb_challenge_done = false; + #define HB_MAGIC 0x63825363L + pDCxt->hb_sequence = HB_MAGIC ; + if(A_OK == wmi_cmd_start(pWmi, param_ptr->data, WMI_EXTENSION_CMDID, param_ptr->length)) + { + /* block until data return */ + DRIVER_WAIT_FOR_CONDITION(pCxt, &(pDCxt->hb_challenge_done), true, 5000); + } + if (pDCxt->hb_challenge_done != true) + { + error = A_ERROR; + printf("heart beat challenge failed\n"); + } + else + { + error = A_OK; + printf("heart beat challenge done\n"); + } + break; + + default: + if (ath_custom_mediactl.ath_ioctl_handler_ext != NULL) + { + error = ath_custom_mediactl.ath_ioctl_handler_ext(qca_ptr, param_ptr); + } + else + { + error = QCA_ERROR; + } + break; + } + + return error; +} + +uint32_t Custom_Api_Mediactl(QCA_CONTEXT_STRUCT_PTR qca_ptr, uint32_t command_id, void *inout_param) +{ + uint8_t devId; + uint32_t error = QCA_OK; + void *pCxt, *pWmi; + A_DRIVER_CONTEXT *pDCxt; + QCA_MEDIACTL_PARAM_PTR param_ptr = (QCA_MEDIACTL_PARAM_PTR)inout_param; +#define PTR_DEV_MODE ((uint32_t *)inout_param) +#define PTR_ESSID ((QCA_ESSID *)inout_param) +#define PTR_SECTYPE ((uint32_t *)inout_param) +#define PTR_FREQ (uint32_t *)(param_ptr->data) +#define PTR_RTS ((uint32_t *)inout_param) +#define PTR_PASSPHRASE ((QCA_MEDIACTL_PARAM *)inout_param) +#define PTR_SCAN_OUT ((QCA_SCAN_LIST *)inout_param) +#define PTR_POWER_IN ((QCA_MEDIACTL_PARAM *)inout_param) +#define PTR_POWER_OUT ((QCA_MEDIACTL_PARAM *)inout_param) +#define PTR_ATH_IOCTL ((ATH_IOCTL_PARAM_STRUCT_PTR)inout_param) +#define PTR_START_SCAN ((WMI_START_SCAN_CMD *)inout_param) + + union + { + WMI_SET_PASSPHRASE_CMD passCmd; + WMI_SET_RTS_CMD rtsCmd; + } local; + + if (qca_ptr == NULL) + { + error = QCA_ERROR; + goto MEDIACTL_DONE; + } + /* ATH_CHIP_STATE is a special command to bring + * driver + wifi device + * up or down without officially shutting down the + * driver. This allows a task to shutdown the chip + * but prevents other tasks from having invalid qca_ptr's + */ + if (command_id == QCA_MEDIACTL_VENDOR_SPECIFIC && PTR_ATH_IOCTL->cmd_id == ATH_CHIP_STATE) + { + error = chip_state_ctrl(qca_ptr, *((uint32_t *)PTR_ATH_IOCTL->data)); + + if (error != QCA_OK) + { + config_dump_target_assert_info(qca_ptr->MAC_CONTEXT_PTR); + } + + goto MEDIACTL_DONE; + } + + if ((pCxt = qca_ptr->MAC_CONTEXT_PTR) == NULL) + { + error = QCA_ERROR; + goto MEDIACTL_DONE; + } + + pDCxt = GET_DRIVER_COMMON(pCxt); + pWmi = pDCxt->pWmiCxt; + devId = pDCxt->devId; + // devId = qca_ptr->PARAM_PTR->QCA_IF->PHY_NUMBER; + + if (command_id == QCA_MEDIACTL_IS_INITIALIZED) + { + *((uint32_t *)inout_param) = (uint32_t)((pDCxt->wmiReady == true) ? 1 : 0); + goto MEDIACTL_DONE; + } + else if (pDCxt->wmiReady == false && ath_custom_init.skipWmi == 0) + { + /* no other ioctl's allowed until driver is properly initialized */ + error = QCA_ERR_INIT_FAILED; + goto MEDIACTL_DONE; + } + + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return QCA_ERROR; + } + + switch (command_id) + { + case QCA_MEDIACTL_VENDOR_SPECIFIC: + error = ath_ioctl_handler(qca_ptr, PTR_ATH_IOCTL); + break; + case QCA_SET_MEDIACTL_COMMIT: + if (pDCxt->conn[devId].ssidLen == 0) + { + /* a zero length ssid + a COMMIT command is interpreted as a + * request from the caller to disconnect. + */ + Api_DisconnectWiFi(pCxt); + GET_DRIVER_COMMON(pCxt)->securityType = QCA_MEDIACTL_SECURITY_TYPE_NONE; + } + else + { + if (Api_ConnectWiFi(pCxt) != A_OK) + { + error = QCA_ERROR; + } + } + pDCxt->wps_in_progress = false; + break; + case QCA_SET_MEDIACTL_MODE: + switch (*PTR_DEV_MODE) + { + case QCA_MEDIACTL_MODE_INFRA: + pDCxt->conn[devId].networkType = INFRA_NETWORK; + break; + case QCA_MEDIACTL_MODE_ADHOC: + pDCxt->conn[devId].networkType = ADHOC_NETWORK; + break; +#if ENABLE_AP_MODE + case QCA_MEDIACTL_MODE_MASTER: + pDCxt->conn[devId].networkType = AP_NETWORK; + break; +#endif + default: + error = QCA_ERR_INVALID_INIT_PARAM; + break; + } + break; + case QCA_SET_MEDIACTL_ESSID: + if (PTR_ESSID->length < 33) + { + pDCxt->conn[devId].ssidLen = (int32_t)PTR_ESSID->length; + if (pDCxt->conn[devId].ssidLen) + { + A_MEMCPY(pDCxt->conn[devId].ssid, PTR_ESSID->essid, (uint32_t)pDCxt->conn[devId].ssidLen); + } + else + { + // clear ssid; this is the first step to disconnect + A_MEMZERO(pDCxt->conn[devId].ssid, 32); + } + } + else + { + error = QCA_ERR_INVALID_INIT_PARAM; + } + + break; + case QCA_SET_MEDIACTL_SEC_TYPE: + GET_DRIVER_COMMON(pCxt)->securityType = (uint8_t)(*PTR_SECTYPE); + switch (*PTR_SECTYPE) + { + case QCA_MEDIACTL_SECURITY_TYPE_NONE: + pDCxt->conn[devId].wpaAuthMode = NONE_AUTH; + pDCxt->conn[devId].wpaPairwiseCrypto = NONE_CRYPT; + pDCxt->conn[devId].wpaGroupCrypto = NONE_CRYPT; + pDCxt->conn[devId].dot11AuthMode = OPEN_AUTH; + pDCxt->conn[devId].connectCtrlFlags &= ~CONNECT_DO_WPA_OFFLOAD; + break; + case QCA_MEDIACTL_SECURITY_TYPE_WEP: + pDCxt->conn[devId].wpaAuthMode = NONE_AUTH; + pDCxt->conn[devId].wpaPairwiseCrypto = WEP_CRYPT; + pDCxt->conn[devId].wpaGroupCrypto = WEP_CRYPT; + /* allow either form of auth for WEP */ + pDCxt->conn[devId].dot11AuthMode = (OPEN_AUTH | SHARED_AUTH); + pDCxt->conn[devId].connectCtrlFlags &= ~CONNECT_DO_WPA_OFFLOAD; + break; + case QCA_MEDIACTL_SECURITY_TYPE_WPA: + /* FIXME: need t allow WPA with AES */ + pDCxt->conn[devId].wpaAuthMode = WPA_PSK_AUTH; + pDCxt->conn[devId].dot11AuthMode = OPEN_AUTH; + /* by ignoring the group cipher the wifi can connect to mixed mode AP's */ + pDCxt->conn[devId].connectCtrlFlags |= CONNECT_DO_WPA_OFFLOAD | CONNECT_IGNORE_WPAx_GROUP_CIPHER; + break; + case QCA_MEDIACTL_SECURITY_TYPE_WPA2: + /* FIXME: need to allow WPA2 with TKIP */ + pDCxt->conn[devId].wpaAuthMode = WPA2_PSK_AUTH; + pDCxt->conn[devId].dot11AuthMode = OPEN_AUTH; + /* by ignoring the group cipher the wifi can connect to mixed mode AP's */ + pDCxt->conn[devId].connectCtrlFlags |= CONNECT_DO_WPA_OFFLOAD | CONNECT_IGNORE_WPAx_GROUP_CIPHER; + break; + default: + error = QCA_ERR_INVALID_INIT_PARAM; + break; + } + break; + case QCA_SET_MEDIACTL_FREQ: + /* Normally only used for starting a new Ad-hoc network */ + /* In Infrastructure mode the wifi device will scan for the + * SSID on allowed channels. */ + /* arChannelHint is used in connect command to wifi device */ + if (ATH_IOCTL_FREQ_1 <= *PTR_FREQ && ATH_IOCTL_FREQ_14 >= *PTR_FREQ) + { + pDCxt->conn[devId].channelHint = (uint16_t)(*PTR_FREQ); + } + else + { + error = QCA_ERR_INVALID_INIT_PARAM; + } + break; + case QCA_SET_MEDIACTL_RTS: + local.rtsCmd.threshold = A_CPU2LE16((uint16_t)(*PTR_RTS)); + if (A_OK != wmi_cmd_start(pWmi, &local.rtsCmd, WMI_SET_RTS_CMDID, sizeof(WMI_SET_RTS_CMD))) + { + error = QCA_ERROR; + } + break; + case QCA_SET_MEDIACTL_PASSPHRASE: + /* must have already set SSID prior to this call */ + if (PTR_PASSPHRASE->length > WMI_PASSPHRASE_LEN) + { + error = QCA_ERR_INVALID_INIT_PARAM; + } + else if (pDCxt->conn[devId].ssidLen == 0) + { + error = QCA_ERR_INIT_FAILED; + } + else + { + local.passCmd.ssid_len = (uint8_t)pDCxt->conn[devId].ssidLen; + A_MEMCPY(local.passCmd.ssid, pDCxt->conn[devId].ssid, (uint32_t)pDCxt->conn[devId].ssidLen); + local.passCmd.passphrase_len = (uint8_t)PTR_PASSPHRASE->length; + A_MEMCPY(local.passCmd.passphrase, PTR_PASSPHRASE->data, local.passCmd.passphrase_len); + + if (A_OK != + wmi_cmd_start(pWmi, &local.passCmd, WMI_SET_PASSPHRASE_CMDID, sizeof(WMI_SET_PASSPHRASE_CMD))) + { + error = QCA_ERROR; + } + } + break; + case QCA_SET_MEDIACTL_SCAN: + GET_DRIVER_COMMON(pCxt)->extended_scan = 0; + error = scan_setup(pCxt, pWmi, PTR_START_SCAN); + break; + case QCA_SET_MEDIACTL_POWER: + /* atheros wifi allows for 2 power modes; + * 1) MAX_PERF - the radio is always on either transmitting, receiving or listening + * 2) REC_MODE - the wifi device will according to its built in rules enter/exit sleep + * mode with the Access point. + */ + if (PTR_POWER_IN->value) + { + /* a non-zero value implies REC_MODE */ + pDCxt->userPwrMode = REC_POWER; + } + else + { + pDCxt->userPwrMode = MAX_PERF_POWER; + } + + wmi_cmd_start(pWmi, &pDCxt->userPwrMode, WMI_SET_POWER_MODE_CMDID, sizeof(WMI_POWER_MODE_CMD)); + break; + case QCA_GET_MEDIACTL_POWER: + if (pDCxt->userPwrMode == REC_POWER) + { + PTR_POWER_OUT->value = 1; + } + else + { + PTR_POWER_OUT->value = 0; + } + + break; + case QCA_GET_MEDIACTL_SCAN: + wait_scan_done(pCxt, pWmi); + PTR_SCAN_OUT->scan_info_list = (QCA_SCAN_INFO *)GET_DRIVER_COMMON(pCxt)->pScanOut; + PTR_SCAN_OUT->num_scan_entries = GET_DRIVER_COMMON(pCxt)->scanOutCount; + break; + case QCA_GET_MEDIACTL_ESSID: + ((QCA_MEDIACTL_PARAM *)inout_param)->length = (uint32_t)pDCxt->conn[devId].ssidLen; + A_MEMCPY(((QCA_MEDIACTL_PARAM *)inout_param)->data, pDCxt->conn[devId].ssid, + (uint32_t)pDCxt->conn[devId].ssidLen + 1); + break; + case QCA_GET_MEDIACTL_SEC_TYPE: + *((uint32_t *)inout_param) = GET_DRIVER_COMMON(pCxt)->securityType; + break; + case QCA_GET_MEDIACTL_MODE: + *((uint32_t *)inout_param) = (uint32_t)pDCxt->conn[devId].networkType; + switch (pDCxt->conn[devId].networkType) + { + case INFRA_NETWORK: + *((uint32_t *)inout_param) = QCA_MEDIACTL_MODE_INFRA; + break; + case ADHOC_NETWORK: + *((uint32_t *)inout_param) = QCA_MEDIACTL_MODE_ADHOC; + break; +#if ENABLE_AP_MODE + case AP_NETWORK: + *((uint32_t *)inout_param) = QCA_MEDIACTL_MODE_MASTER; + break; +#endif + default: + error = QCA_ERR_INVALID_INIT_PARAM; + break; + } + break; +#if 0 /* currently unsupported MEDIACTLS */ + case QCA_SET_MEDIACTL_ENCODE: + error = + break; + case QCA_GET_MEDIACTL_PASSPHRASE: + error = + break; + case QCA_GET_MEDIACTL_NAME: + error = + break; + case QCA_GET_MEDIACTL_FREQ: + error = + break; + case QCA_GET_MEDIACTL_RANGE: + break; + case QCA_GET_MEDIACTL_WAP: + break; + case QCA_GET_MEDIACTL_RATE: + error = + break; + case QCA_GET_MEDIACTL_RTS: + error = + break; + case QCA_GET_MEDIACTL_RETRY: + error = + break; +#endif + default: + QCADRV_PRINTF("Atheros ERROR: mediactl command not valid. command_id=0x%x\n", command_id); + error = QCA_ERROR; + break; + // while(1){}; + } /* Swtich*/ + +MEDIACTL_DONE: + + return error; +} + +/* EOF */ diff --git a/platform/mcu/lpc54102/wifi_qca/custom_src/api_interface/cust_api_txrx.c b/platform/mcu/lpc54102/wifi_qca/custom_src/api_interface/cust_api_txrx.c new file mode 100644 index 0000000000..25f314d1c9 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/custom_src/api_interface/cust_api_txrx.c @@ -0,0 +1,173 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== +#include +#include +#include +#include +#include +#include +#include + +#if (!ENABLE_STACK_OFFLOAD) + +uint32_t Custom_Api_Send( + QCA_CONTEXT_STRUCT_PTR qca_ptr, PCB_PTR pcb_ptr, uint32_t size, uint32_t frags, uint32_t flags); + +/*****************************************************************************/ +/* Custom_DeliverFrameToNetworkStack - Called by API_RxComplete to + * deliver a data frame to the network stack. This code will perform + * platform specific operations. + * void *pCxt - the driver context. + * void *pReq - the packet. + *****************************************************************************/ +void Custom_DeliverFrameToNetworkStack(void *pCxt, void *pReq) +{ + A_NETBUF *a_netbuf_ptr = (A_NETBUF *)pReq; + QCA_CONTEXT_STRUCT_PTR qca_ptr = (QCA_CONTEXT_STRUCT_PTR)GET_DRIVER_CXT(pCxt)->pUpperCxt[0]; + QCA_ECB_STRUCT_PTR RxECB; + uint32_t len; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + ATH_PROMISCUOUS_CB prom_cb = (ATH_PROMISCUOUS_CB)(GET_DRIVER_CXT(pCxt)->promiscuous_cb); + + if (a_netbuf_ptr) + { + len = A_NETBUF_LEN(pReq); + _DCACHE_INVALIDATE_MBYTES(A_NETBUF_DATA(pReq), len); + + if (pDCxt->promiscuous_mode) + { + if (prom_cb) + { + /* send frame to callback function rather than an QCA_receiver */ + a_netbuf_ptr->native.FRAG[0].LENGTH = len; + a_netbuf_ptr->native.FRAG[0].FRAGMENT = A_NETBUF_DATA(pReq); + prom_cb((void *)&(a_netbuf_ptr->native)); + } + else + { + A_NETBUF_FREE(pReq); + } + } + else if ((RxECB = QCA_find_receiver(qca_ptr, (QCA_HEADER_PTR)A_NETBUF_DATA(pReq), &len)) != NULL) + { + // Call the receiver's service function to pass the PCB to the receiver + a_netbuf_ptr->native.FRAG[0].LENGTH = len; + a_netbuf_ptr->native.FRAG[0].FRAGMENT = A_NETBUF_DATA(pReq); + RxECB->SERVICE((PCB_PTR) & (a_netbuf_ptr->native), RxECB->PRIVATE); + } + else + { + /* failed to find a receiver for this data packet. */ + A_NETBUF_FREE(pReq); + } + } +} + +/*****************************************************************************/ +/* Custom_Api_Send - Entry point for MQX driver interface to send a packet. + * This is specific to MQX. This function is NOT called from within the + * driver. + * QCA_CONTEXT_STRUCT_PTR qca_ptr - the MQX driver context. + * PCB_PTR pcb_ptr - the MQX packet object. + * uint32_t size - the length in bytes of pcb_ptr. + * uint32_t frags - the number of fragments in pcb_ptr. + * uint32_t flags - optional flags for transmit. + *****************************************************************************/ +uint32_t Custom_Api_Send(QCA_CONTEXT_STRUCT_PTR qca_ptr, + /* [IN] the Ethernet state structure */ + PCB_PTR pcb_ptr, + /* [IN] the packet to send */ + uint32_t size, + /* [IN] total size of the packet */ + uint32_t frags, + /* [IN] total fragments in the packet */ + uint32_t flags + /* [IN] optional flags, zero = default */ + ) +{ + uint32_t error = QCA_OK; + A_NETBUF *a_netbuf_ptr; + UNUSED_ARGUMENT(flags); + UNUSED_ARGUMENT(size); +#if 0 +if(g_sampleTotAlloc != g_totAlloc){ + A_PRINTF("send alloc: %d\n", g_totAlloc); + g_sampleTotAlloc = g_totAlloc; +} +#endif + /* create an atheros pcb and continue or fail. */ + do + { + /* provide enough space in the top buffer to store the 14 byte + * header which will be copied from its position in the original + * buffer. this will allow wmi_dix_2_dot3() to function properly. + */ + if ((a_netbuf_ptr = (A_NETBUF *)A_NETBUF_ALLOC(sizeof(ATH_MAC_HDR))) == NULL) + { + error = ENETERR_ALLOC_PCB; + break; + } + + a_netbuf_ptr->num_frags = (uint8_t)frags; + /* HACK: copy the first part of the fragment to the new buf in order to allow + * wmi_dix_2_dot3() to function properly. */ + A_ASSERT(pcb_ptr->FRAG[0].LENGTH >= sizeof(ATH_MAC_HDR)); + A_NETBUF_PUT_DATA(a_netbuf_ptr, (uint8_t *)pcb_ptr->FRAG[0].FRAGMENT, sizeof(ATH_MAC_HDR)); + /*(char*)pcb_ptr->FRAG[0].FRAGMENT += sizeof(ATH_MAC_HDR);*/ + pcb_ptr->FRAG[0].FRAGMENT = (uint8_t *)((uint32_t)pcb_ptr->FRAG[0].FRAGMENT + sizeof(ATH_MAC_HDR)); + pcb_ptr->FRAG[0].LENGTH -= sizeof(ATH_MAC_HDR); + + // ensure there is enough headroom to complete the tx operation + if (A_NETBUF_HEADROOM(a_netbuf_ptr) < + sizeof(ATH_MAC_HDR) + sizeof(ATH_LLC_SNAP_HDR) + sizeof(WMI_DATA_HDR) + HTC_HDR_LENGTH + WMI_MAX_TX_META_SZ) + { + error = ENETERR_ALLOC_PCB; + break; + } + // carry the original around until completion. + // it is freed by A_NETBUF_FREE + a_netbuf_ptr->native_orig = pcb_ptr; + + if (A_OK != Api_DataTxStart((void *)qca_ptr->MAC_CONTEXT_PTR, (void *)a_netbuf_ptr)) + { + error = QCA_ERROR; + break; + } + + } while (0); + + if (error != QCA_OK) + { + /* in the event of api failure, the original pcb should be returned to the caller un-touched + * and the a_netbuf_ptr should be freed */ + a_netbuf_ptr->native_orig = NULL; + A_NETBUF_FREE((void *)a_netbuf_ptr); + } + + return error; +} + +#endif diff --git a/platform/mcu/lpc54102/wifi_qca/custom_src/api_interface/cust_api_wmi_rx.c b/platform/mcu/lpc54102/wifi_qca/custom_src/api_interface/cust_api_wmi_rx.c new file mode 100644 index 0000000000..33cdc9dc3c --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/custom_src/api_interface/cust_api_wmi_rx.c @@ -0,0 +1,481 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== +#include +#include +#include +#include +#include +#include +#include + +//TODO: mixin different layers, need to fix +// introduced by on_connect events enum +// need to specify connections between layers +#include "qcom_api.h" + +#if ENABLE_P2P_MODE +#include "p2p.h" +#include "wmi.h" +#include "wmi_api.h" +#include "wmi_host.h" +#endif + +#include +#include +#if ENABLE_P2P_MODE +extern const WMI_SCAN_PARAMS_CMD default_scan_param; +extern const uint8_t max_performance_power_param; +#endif +static void fill_scan_info(void *pCxt, QCA_SCAN_INFO *pScanInfo, WMI_BSS_INFO_HDR *bih, int32_t len) +{ + A_SCAN_SUMMARY scan_summary; + + if (A_OK == Api_ParseInfoElem(pCxt, bih, len, &scan_summary)) + { + pScanInfo->channel = scan_summary.channel; + pScanInfo->rssi = scan_summary.rssi; + A_MEMCPY(pScanInfo->bssid, scan_summary.bssid, ATH_MAC_LEN); + pScanInfo->ssid_len = scan_summary.ssid_len; + + A_MEMCPY(pScanInfo->ssid, &(scan_summary.ssid[0]), scan_summary.ssid_len); + pScanInfo->security_enabled = (uint8_t)((scan_summary.caps & IEEE80211_CAPINFO_PRIVACY) ? 1 : 0); + pScanInfo->preamble = (uint8_t)((scan_summary.caps & IEEE80211_CAPINFO_SHORT_PREAMBLE) ? 1 : 0); + + if ((scan_summary.caps & (IEEE80211_CAPINFO_ESS | IEEE80211_CAPINFO_IBSS)) == IEEE80211_CAPINFO_ESS) + { + pScanInfo->bss_type = QCA_MEDIACTL_MODE_INFRA; + } + else if ((scan_summary.caps & (IEEE80211_CAPINFO_ESS | IEEE80211_CAPINFO_IBSS)) == IEEE80211_CAPINFO_IBSS) + { + pScanInfo->bss_type = QCA_MEDIACTL_MODE_ADHOC; + } + else + { + /* error condition report it as ad-hoc in this case*/ + pScanInfo->bss_type = QCA_MEDIACTL_MODE_ADHOC; + } + + pScanInfo->beacon_period = scan_summary.beacon_period; + + if (scan_summary.rsn_cipher & TKIP_CRYPT) + { + pScanInfo->rsn_cipher |= ATH_CIPHER_TYPE_TKIP; + } + + if (scan_summary.rsn_cipher & AES_CRYPT) + { + pScanInfo->rsn_cipher |= ATH_CIPHER_TYPE_CCMP; + } + + if (scan_summary.rsn_cipher & WEP_CRYPT) + { + pScanInfo->rsn_cipher |= ATH_CIPHER_TYPE_WEP; + } + + if (scan_summary.wpa_cipher & TKIP_CRYPT) + { + pScanInfo->wpa_cipher |= ATH_CIPHER_TYPE_TKIP; + } + + if (scan_summary.wpa_cipher & AES_CRYPT) + { + pScanInfo->wpa_cipher |= ATH_CIPHER_TYPE_CCMP; + } + + if (scan_summary.wpa_cipher & WEP_CRYPT) + { + pScanInfo->wpa_cipher |= ATH_CIPHER_TYPE_WEP; + } + + if (scan_summary.rsn_auth & WPA2_AUTH) + { + pScanInfo->rsn_auth |= SECURITY_AUTH_1X; + } + + if (scan_summary.rsn_auth & WPA2_PSK_AUTH) + { + pScanInfo->rsn_auth |= SECURITY_AUTH_PSK; + } + + if (scan_summary.wpa_auth & WPA_AUTH) + { + pScanInfo->wpa_auth |= SECURITY_AUTH_1X; + } + + if (scan_summary.wpa_auth & WPA_PSK_AUTH) + { + pScanInfo->wpa_auth |= SECURITY_AUTH_PSK; + } + } +} + +static void fill_ext_scan_info(void *pCxt, ATH_SCAN_EXT *pExtScanInfo, WMI_BSS_INFO_HDR *bih, int32_t len) +{ + A_SCAN_SUMMARY scan_summary; + + if (A_OK == Api_ParseInfoElem(pCxt, bih, len, &scan_summary)) + { + A_MEMZERO(pExtScanInfo, sizeof(ATH_SCAN_EXT)); + pExtScanInfo->channel = scan_summary.channel; + pExtScanInfo->rssi = scan_summary.rssi; + A_MEMCPY(pExtScanInfo->bssid, scan_summary.bssid, ATH_MAC_LEN); + pExtScanInfo->ssid_len = scan_summary.ssid_len; + + A_MEMCPY(pExtScanInfo->ssid, &(scan_summary.ssid[0]), scan_summary.ssid_len); + pExtScanInfo->security_enabled = (uint8_t)((scan_summary.caps & IEEE80211_CAPINFO_PRIVACY) ? 1 : 0); + pExtScanInfo->preamble = (uint8_t)((scan_summary.caps & IEEE80211_CAPINFO_SHORT_PREAMBLE) ? 1 : 0); + + if ((scan_summary.caps & (IEEE80211_CAPINFO_ESS | IEEE80211_CAPINFO_IBSS)) == IEEE80211_CAPINFO_ESS) + { + pExtScanInfo->bss_type = QCA_MEDIACTL_MODE_INFRA; + } + else if ((scan_summary.caps & (IEEE80211_CAPINFO_ESS | IEEE80211_CAPINFO_IBSS)) == IEEE80211_CAPINFO_IBSS) + { + pExtScanInfo->bss_type = QCA_MEDIACTL_MODE_ADHOC; + } + else + { + /* error condition report it as ad-hoc in this case*/ + pExtScanInfo->bss_type = QCA_MEDIACTL_MODE_ADHOC; + } + + pExtScanInfo->beacon_period = scan_summary.beacon_period; + + if (scan_summary.rsn_cipher & TKIP_CRYPT) + { + pExtScanInfo->rsn_cipher |= ATH_CIPHER_TYPE_TKIP; + } + + if (scan_summary.rsn_cipher & AES_CRYPT) + { + pExtScanInfo->rsn_cipher |= ATH_CIPHER_TYPE_CCMP; + } + + if (scan_summary.rsn_cipher & WEP_CRYPT) + { + pExtScanInfo->rsn_cipher |= ATH_CIPHER_TYPE_WEP; + } + + if (scan_summary.wpa_cipher & TKIP_CRYPT) + { + pExtScanInfo->wpa_cipher |= ATH_CIPHER_TYPE_TKIP; + } + + if (scan_summary.wpa_cipher & AES_CRYPT) + { + pExtScanInfo->wpa_cipher |= ATH_CIPHER_TYPE_CCMP; + } + + if (scan_summary.wpa_cipher & WEP_CRYPT) + { + pExtScanInfo->wpa_cipher |= ATH_CIPHER_TYPE_WEP; + } + + if (scan_summary.rsn_auth & WPA2_AUTH) + { + pExtScanInfo->rsn_auth |= SECURITY_AUTH_1X; + } + + if (scan_summary.rsn_auth & WPA2_PSK_AUTH) + { + pExtScanInfo->rsn_auth |= SECURITY_AUTH_PSK; + } + + if (scan_summary.wpa_auth & WPA_AUTH) + { + pExtScanInfo->wpa_auth |= SECURITY_AUTH_1X; + } + + if (scan_summary.wpa_auth & WPA_PSK_AUTH) + { + pExtScanInfo->wpa_auth |= SECURITY_AUTH_PSK; + } + } +} + +void Custom_Api_BssInfoEvent(void *pCxt, uint8_t *datap, int32_t len) +{ + WMI_BSS_INFO_HDR *bih = (WMI_BSS_INFO_HDR *)datap; + QCA_SCAN_INFO_PTR pScanInfo; + ATH_SCAN_EXT *pExtScanInfo; + uint16_t i; + uint8_t worst_snr_idx = 0; + uint8_t worst_snr = 0xff; + uint16_t scanCount; + + /* add/replace entry in application scan results */ + if (GET_DRIVER_COMMON(pCxt)->extended_scan) + { + pExtScanInfo = (ATH_SCAN_EXT *)(GET_DRIVER_COMMON(pCxt)->pScanOut); + scanCount = GET_DRIVER_COMMON(pCxt)->scanOutCount; + // look for previous match + for (i = 0; i < scanCount; i++) + { + if (0 == A_MEMCMP(bih->bssid, pExtScanInfo[i].bssid, ATH_MAC_LEN)) + { + fill_ext_scan_info(pCxt, &pExtScanInfo[i], bih, len); + break; + } + /* keep worst rssi entry for optional use below */ + if (worst_snr > pExtScanInfo[i].rssi) + { + worst_snr = pExtScanInfo[i].rssi; + worst_snr_idx = i; + } + } + + if (i >= scanCount) + { + if (GET_DRIVER_COMMON(pCxt)->scanOutSize <= scanCount) + { + /* replace other non-matching entry based on rssi */ + if (bih->snr > worst_snr) + { + fill_ext_scan_info(pCxt, &pExtScanInfo[worst_snr_idx], bih, len); + } + } + else + { + /* populate new entry */ + fill_ext_scan_info(pCxt, &pExtScanInfo[scanCount], bih, len); + scanCount++; + GET_DRIVER_COMMON(pCxt)->scanOutCount = scanCount; + } + } + } + else + { + pScanInfo = (QCA_SCAN_INFO_PTR)(GET_DRIVER_COMMON(pCxt)->pScanOut); + scanCount = GET_DRIVER_COMMON(pCxt)->scanOutCount; + // look for previous match + for (i = 0; i < scanCount; i++) + { + if (0 == A_MEMCMP(bih->bssid, pScanInfo[i].bssid, ATH_MAC_LEN)) + { + fill_scan_info(pCxt, &pScanInfo[i], bih, len); + break; + } + /* keep worst rssi entry for optional use below */ + if (worst_snr > pScanInfo[i].rssi) + { + worst_snr = pScanInfo[i].rssi; + worst_snr_idx = i; + } + } + + if (i >= scanCount) + { + if (GET_DRIVER_COMMON(pCxt)->scanOutSize <= scanCount) + { + /* replace other non-matching entry based on rssi */ + if (bih->snr > worst_snr) + { + fill_scan_info(pCxt, &pScanInfo[worst_snr_idx], bih, len); + } + } + else + { + /* populate new entry */ + fill_scan_info(pCxt, &pScanInfo[scanCount], bih, len); + scanCount++; + GET_DRIVER_COMMON(pCxt)->scanOutCount = scanCount; + } + } + } +} + +void Custom_Api_ConnectEvent(void *pCxt, uint8_t devId, uint16_t channel, uint8_t *bssid) +{ + ATH_CONNECT_CB cb = NULL; + boolean bssConn = false; + + /* Update connect & link status atomically */ + DRIVER_SHARED_RESOURCE_ACCESS_ACQUIRE(pCxt); + { + if (GET_DRIVER_CXT(pCxt)->connectStateCB != NULL) + { + cb = (ATH_CONNECT_CB)GET_DRIVER_CXT(pCxt)->connectStateCB; + /* call this later from outside the spinlock */ + } + } + DRIVER_SHARED_RESOURCE_ACCESS_RELEASE(pCxt); + + DRIVER_WAKE_USER(pCxt); + QCA_CONTEXT_STRUCT_PTR qca_ptr = (QCA_CONTEXT_STRUCT_PTR)GET_DRIVER_CXT(pCxt)->pUpperCxt[devId]; + bssConn = !A_MEMCMP(qca_ptr->ADDRESS, bssid, ATH_MAC_LEN); + + /* call the callback function provided by application to + * indicate connection state */ + if (cb != NULL) + { + cb(QCOM_ONCONNECT_EVENT_SUCCESS, devId, bssid, bssConn); + } +} + +void Custom_Api_DisconnectEvent(void *pCxt, + uint8_t devId, + uint8_t reason, + uint8_t *bssid, + uint8_t assocRespLen, + uint8_t *assocInfo, + uint16_t protocolReasonStatus) +{ + ATH_CONNECT_CB cb = NULL; + boolean bssConn = false; + uint8_t bssMac[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + + /* Update connect & link status atomically */ + DRIVER_SHARED_RESOURCE_ACCESS_ACQUIRE(pCxt); + if (GET_DRIVER_CXT(pCxt)->connectStateCB != NULL) + { + cb = (ATH_CONNECT_CB)GET_DRIVER_CXT(pCxt)->connectStateCB; + /* call this later from outside the spinlock */ + } + DRIVER_SHARED_RESOURCE_ACCESS_RELEASE(pCxt); + /* call the callback function provided by application to + * indicate connection state */ + if (cb != NULL) + { + QCA_CONTEXT_STRUCT_PTR qca_ptr = (QCA_CONTEXT_STRUCT_PTR)GET_DRIVER_CXT(pCxt)->pUpperCxt[devId]; + bssConn = !A_MEMCMP(qca_ptr->ADDRESS, bssid, ATH_MAC_LEN); + bssConn = !A_MEMCMP(bssMac, bssid, ATH_MAC_LEN); + + if (reason == INVALID_PROFILE) + { + cb(INVALID_PROFILE, devId, bssid, bssConn); + } + else + { + cb(QCOM_ONCONNECT_EVENT_DISCONNECT, devId, bssid, bssConn); + } + } +} + +void Custom_Api_ReadyEvent(void *pCxt, uint8_t *datap, uint8_t phyCap, uint32_t sw_ver, uint32_t abi_ver) +{ + QCA_CONTEXT_STRUCT_PTR qca_ptr = (QCA_CONTEXT_STRUCT_PTR)GET_DRIVER_CXT(pCxt)->pUpperCxt[0]; + /* this custom implementation sets an event after setting CXT_WMI_READY + * so as to allow the blocked user thread to wake up. */ + A_MEMCPY(qca_ptr->ADDRESS, datap, ATH_MAC_LEN); + DRIVER_WAKE_USER(pCxt); + UNUSED_ARGUMENT(phyCap); + UNUSED_ARGUMENT(sw_ver); + UNUSED_ARGUMENT(abi_ver); +} + +void Custom_Api_GpioDataEvent(void *wmip, uint8_t *datap, int32_t len) +{ + if (ath_custom_init.Api_GpioDataEventRx != NULL) + { + ath_custom_init.Api_GpioDataEventRx(datap, len); + } +} + +void Custom_Api_PfmDataEvent(void *wmip, uint8_t *datap, int32_t len) +{ + if (ath_custom_init.Custom_Api_PfmDataEventRx != NULL) + { + ath_custom_init.Custom_Api_PfmDataEventRx(datap, len); + } +} + +void Custom_Api_PfmDataDoneEvent(void *wmip, uint8_t *datap, int32_t len) +{ + if (ath_custom_init.Custom_Api_PfmDataDoneEventRx != NULL) + { + ath_custom_init.Custom_Api_PfmDataDoneEventRx(((struct wmi_t *)wmip)->wmi_devt, datap, len); + } +} + +void Custom_Api_RSNASuccessEvent(void *pCxt, uint8_t devId, uint8_t code) +{ + ATH_CONNECT_CB cb = NULL; + /* this is the event that the customer has to use to send a callback + * to the application so that it will print the success event */ + + /* get the callback handler from the device context */ + DRIVER_SHARED_RESOURCE_ACCESS_ACQUIRE(pCxt); + if (GET_DRIVER_CXT(pCxt)->connectStateCB != NULL) + { + cb = (ATH_CONNECT_CB)GET_DRIVER_CXT(pCxt)->connectStateCB; + /* call this later from outside the spinlock */ + } + DRIVER_SHARED_RESOURCE_ACCESS_RELEASE(pCxt); + /* call the callback function provided by application to + * indicate 4 way handshake status */ + if (cb != NULL) + { + cb(code, devId, NULL, false); + } +} + +void Custom_Api_BitRateEvent_tx(void *pCxt, uint8_t devId, int8_t rateIndex) +{ + ATH_CONNECT_CB cb = NULL; + /* the driver will get the index of the last tx rate from chip + * based on this index we get the rate tx from the array */ + + /* get the callback handler from the device context */ + DRIVER_SHARED_RESOURCE_ACCESS_ACQUIRE(pCxt); + if (GET_DRIVER_CXT(pCxt)->connectStateCB != NULL) + { + cb = (ATH_CONNECT_CB)GET_DRIVER_CXT(pCxt)->connectStateCB; + /* call this later from outside the spinlock */ + } + DRIVER_SHARED_RESOURCE_ACCESS_RELEASE(pCxt); + /* call the callback function provided by application to + * indicate last transmitted rate */ + + if (cb != NULL) + { + cb(wmi_rateTable[rateIndex][0], devId, NULL, false); + } +} + +void Custom_Api_ProbeReq_Event(void *pCxt, uint8_t *datap, uint32_t len) +{ + ATH_PROBEREQ_CB cb = NULL; + WMI_P2P_RX_PROBE_REQ_EVENT_STRUCT *buf = (WMI_P2P_RX_PROBE_REQ_EVENT_STRUCT *)datap; + + DRIVER_SHARED_RESOURCE_ACCESS_ACQUIRE(pCxt); + { + if (GET_DRIVER_CXT(pCxt)->probeReqCB != NULL) + { + cb = (ATH_PROBEREQ_CB)GET_DRIVER_CXT(pCxt)->probeReqCB; + /* call this later from outside the spinlock */ + } + } + DRIVER_SHARED_RESOURCE_ACCESS_RELEASE(pCxt); + + /* call the callback function provided by application to + * indicate Probe request message to the application */ + if (cb != NULL) + { + cb(buf->data, buf->len, buf->freq); + } +} + +/* EOF */ diff --git a/platform/mcu/lpc54102/wifi_qca/custom_src/driver/cust_driver_main.c b/platform/mcu/lpc54102/wifi_qca/custom_src/driver/cust_driver_main.c new file mode 100644 index 0000000000..42cc48e35b --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/custom_src/driver/cust_driver_main.c @@ -0,0 +1,211 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== +#include +#include +#include + +#include +#include +#include + +#include "atheros_wifi.h" +#include "atheros_wifi_api.h" +#include "atheros_wifi_internal.h" + +ATH_CUSTOM_INIT_T ath_custom_init = { + NULL, NULL, NULL, NULL, NULL, NULL, NULL, false, false, +}; + +ATH_CUSTOM_MEDIACTL_T ath_custom_mediactl = {NULL}; + +ATH_CUSTOM_HTC_T ath_custom_htc = {NULL, NULL}; + +static void Custom_FreeRxRequest(A_NATIVE_NETBUF *native_ptr) +{ +#if (!ENABLE_STACK_OFFLOAD) + A_NETBUF *a_netbuf_ptr = (A_NETBUF *)native_ptr; +#if DRIVER_CONFIG_IMPLEMENT_RX_FREE_QUEUE + A_CUSTOM_DRIVER_CONTEXT *pCxt = (A_CUSTOM_DRIVER_CONTEXT *)a_netbuf_ptr->native.PRIVATE; + + if (_mem_get_type(a_netbuf_ptr) == MEM_TYPE_ATHEROS_PERSIST_RX_PCB) + { + RXBUFFER_ACCESS_ACQUIRE((void *)pCxt); + A_NETBUF_ENQUEUE(&(GET_DRIVER_COMMON(pCxt)->rxFreeQueue), a_netbuf_ptr); + Driver_ReportRxBuffStatus((void *)pCxt, true); + RXBUFFER_ACCESS_RELEASE((void *)pCxt); + } + else + { + A_ASSERT(0); + } +#else + default_native_free_fn((PCB_PTR)a_netbuf_ptr); +#endif +#endif +} + +/*****************************************************************************/ +/* Custom_GetRxRequest - Attempts to get an RX Buffer + RX Request object + * for a pending RX packet. If an Rx Request cannot be acquired then this + * function calls Driver_ReportRxBuffStatus(pCxt, false) to prevent the + * driver from repeating the request until a buffer becomes available. + * void *pCxt - the driver context. + * uint16_t length - length of request in bytes. + *****************************************************************************/ +void *Custom_GetRxRequest(void *pCxt, uint16_t length) +{ + void *pReq; + + do + { + RXBUFFER_ACCESS_ACQUIRE(pCxt); + { +#if DRIVER_CONFIG_IMPLEMENT_RX_FREE_QUEUE + pReq = A_NETBUF_DEQUEUE(&(GET_DRIVER_COMMON(pCxt)->rxFreeQueue)); + + if (A_NETBUF_QUEUE_EMPTY(&(GET_DRIVER_COMMON(pCxt)->rxFreeQueue))) + { + Driver_ReportRxBuffStatus(pCxt, false); + } +#else + pReq = A_NETBUF_ALLOC(length); + if (pReq == NULL) + { + Driver_ReportRxBuffStatus(pCxt, false); + } +#endif + } + RXBUFFER_ACCESS_RELEASE(pCxt); + + if (pReq != NULL) + { + /* init pcb */ + A_NETBUF_INIT(pReq, (void *)Custom_FreeRxRequest, pCxt); + A_ASSERT(length <= A_NETBUF_TAILROOM(pReq)); + } + else + { + // should never happen thanks to HW_ReportRxBuffStatus + A_ASSERT(0); + } + } while (0); + + return pReq; +} + +/*****************************************************************************/ +/* Custom_Driver_ContextDeInit - Frees any allocations performed by + * Custom_Driver_ContextInit. + * void *pCxt - the driver context. + *****************************************************************************/ +void Custom_Driver_ContextDeInit(void *pCxt) +{ + void *pReq; + + while (GET_DRIVER_COMMON(pCxt)->rxBufferStatus == true) + { + pReq = Custom_GetRxRequest(pCxt, 10); + /* call default free function */ + default_native_free_fn((PCB_PTR)pReq); + } + + if (GET_DRIVER_COMMON(pCxt)->tempStorage != NULL) + { + A_FREE(GET_DRIVER_COMMON(pCxt)->tempStorage, 0); + GET_DRIVER_COMMON(pCxt)->tempStorage = NULL; + } +} + +/*****************************************************************************/ +/* Custom_Driver_ContextInit - Allocates and initializes driver context + * elements including pre-allocated rx buffers. This function will call + * A_ASSERT for any failure. Look to Custom_Driver_ContextDeInit to undo + * any allocations performed by this function. + * void *pCxt - the driver context. + *****************************************************************************/ +A_STATUS +Custom_Driver_ContextInit(void *pCxt) +{ + uint32_t tempStorageLen = 0; + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); + + /*Allocate the temporary storage buffer. This may be shared by multiple modules. + If store recall is enabled, it may use this buffer for storing target data. + Will also be shared by scan module to store scan results*/ + tempStorageLen = max((STORE_RECALL_BUF_SIZE), (ATH_MAX_SCAN_BUFFERS * sizeof(QCA_SCAN_INFO))); + tempStorageLen = max(tempStorageLen, (ATH_MAX_SCAN_BUFFERS * sizeof(ATH_SCAN_EXT))); + + if (tempStorageLen) + { + if (NULL == (pDCxt->tempStorage = A_MALLOC(tempStorageLen, 0))) + { + return A_NO_MEMORY; + } + pDCxt->tempStorageLength = tempStorageLen; + } + else + { + pDCxt->tempStorage = NULL; + pDCxt->tempStorageLength = 0; + } + + /* Prepare buffer for the scan results, reuse tempStorage. */ + GET_DRIVER_COMMON(pCxt)->pScanOut = pDCxt->tempStorage; + A_ASSERT(GET_DRIVER_COMMON(pCxt)->pScanOut != NULL); + GET_DRIVER_COMMON(pCxt)->securityType = QCA_MEDIACTL_SECURITY_TYPE_NONE; +#if DRIVER_CONFIG_IMPLEMENT_RX_FREE_QUEUE + { + QCA_CONTEXT_STRUCT_PTR qca_ptr = (QCA_CONTEXT_STRUCT_PTR)GET_DRIVER_CXT(pCxt)->pUpperCxt[0]; + uint16_t numRxBuffers, i; + void *pReq; + /* allocate rx objects and buffers */ + A_NETBUF_QUEUE_INIT(&GET_DRIVER_COMMON(pCxt)->rxFreeQueue); + /* NUM_RX_PCBS should be == BSP_CONFIG_ATHEROS_PCB which + * is defined in atheros_wifi.h + */ + numRxBuffers = qca_ptr->PARAM_PTR->NUM_RX_PCBS; + // pre-allocate rx buffers + for (i = 0; i < numRxBuffers; i++) + { + pReq = A_NETBUF_ALLOC_RAW(AR4100_MAX_RX_MESSAGE_SIZE); + + A_ASSERT(pReq != NULL); +#if ENABLE_STACK_OFFLOAD + /*Set rx pool ID so that the buffer is freed to the RX pool*/ + A_NETBUF_SET_RX_POOL(pReq); +#endif + A_NETBUF_ENQUEUE(&GET_DRIVER_COMMON(pCxt)->rxFreeQueue, pReq); + } + } +#endif + + /* init the common->rxBufferStatus to true to indicate that rx buffers are + * ready for use. */ + pDCxt->rxBufferStatus = true; + GET_DRIVER_COMMON(pCxt)->driverShutdown = false; + + return A_OK; +} diff --git a/platform/mcu/lpc54102/wifi_qca/custom_src/driver/cust_driver_netbuf.c b/platform/mcu/lpc54102/wifi_qca/custom_src/driver/cust_driver_netbuf.c new file mode 100644 index 0000000000..d3af4de474 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/custom_src/driver/cust_driver_netbuf.c @@ -0,0 +1,802 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== + +#include +#include +#include +#include +#include "atheros_wifi_api.h" + +#define AR6000_DATA_OFFSET 64 + +uint8_t g_driverState = DRIVER_STATE_INVALID; + +#if (!ENABLE_STACK_OFFLOAD) + +void default_native_free_fn(PCB_PTR pcb_ptr) +{ + A_NETBUF *a_netbuf_ptr = (A_NETBUF *)pcb_ptr; + /* head is guaranteed to always point to the + * start of the original buffer */ + if (a_netbuf_ptr->head) + A_FREE(a_netbuf_ptr->head, MALLOC_ID_NETBUFF); + + if (a_netbuf_ptr->native_orig) + a_netbuf_ptr->native_orig->FREE(a_netbuf_ptr->native_orig); + + A_FREE(a_netbuf_ptr, MALLOC_ID_NETBUFF_OBJ); +} + +typedef void (*_pcb_free_fn)(PCB_PTR pcb_ptr); + +void a_netbuf_init(void *buffptr, void *freefn, void *priv) +{ + A_NETBUF *a_netbuf_ptr = (A_NETBUF *)buffptr; + + a_netbuf_ptr->native.FREE = (_pcb_free_fn)freefn; + a_netbuf_ptr->native.PRIVATE = priv; + a_netbuf_ptr->tail = a_netbuf_ptr->data = (pointer)((uint32_t)a_netbuf_ptr->head + AR6000_DATA_OFFSET); + a_netbuf_ptr->native.FRAG[0].FRAGMENT = a_netbuf_ptr->head; + a_netbuf_ptr->native.FRAG[0].LENGTH = (uint32_t)a_netbuf_ptr->end - (uint32_t)a_netbuf_ptr->head; +} + +void *a_netbuf_alloc(int32_t size) +{ + A_NETBUF *a_netbuf_ptr; + + do + { + a_netbuf_ptr = A_MALLOC(sizeof(A_NETBUF), MALLOC_ID_NETBUFF_OBJ); + + if (a_netbuf_ptr == NULL) + { + break; + } + A_MEMZERO(a_netbuf_ptr, sizeof(A_NETBUF)); + + a_netbuf_ptr->native.FREE = default_native_free_fn; + + a_netbuf_ptr->native.FRAG[0].LENGTH = AR6000_DATA_OFFSET + size; + a_netbuf_ptr->native.FRAG[0].FRAGMENT = + A_MALLOC((int32_t)(a_netbuf_ptr->native.FRAG[0].LENGTH), MALLOC_ID_NETBUFF); + + if (a_netbuf_ptr->native.FRAG[0].FRAGMENT == NULL) + { + A_FREE(a_netbuf_ptr, MALLOC_ID_NETBUFF_OBJ); + a_netbuf_ptr = NULL; + break; + } + + a_netbuf_ptr->head = a_netbuf_ptr->native.FRAG[0].FRAGMENT; + a_netbuf_ptr->end = + (pointer)((uint32_t)a_netbuf_ptr->native.FRAG[0].FRAGMENT + a_netbuf_ptr->native.FRAG[0].LENGTH); + // reserve head room + a_netbuf_ptr->tail = a_netbuf_ptr->data = (pointer)((uint32_t)a_netbuf_ptr->head + AR6000_DATA_OFFSET); + A_MEMZERO(&a_netbuf_ptr->trans, sizeof(A_TRANSPORT_OBJ)); + } while (0); + + return ((void *)a_netbuf_ptr); +} + +/* + * Allocate an NETBUF w.o. any encapsulation requirement. + */ +void *a_netbuf_alloc_raw(int32_t size) +{ + A_NETBUF *a_netbuf_ptr = NULL; + + do + { + a_netbuf_ptr = A_MALLOC(sizeof(A_NETBUF), MALLOC_ID_NETBUFF_OBJ); + + if (a_netbuf_ptr == NULL) + { + break; + } + + A_MEMZERO(a_netbuf_ptr, sizeof(A_NETBUF)); + + a_netbuf_ptr->native.FREE = default_native_free_fn; + a_netbuf_ptr->native.FRAG[0].LENGTH = (uint32_t)size; + a_netbuf_ptr->native.FRAG[0].FRAGMENT = + A_MALLOC((int32_t)a_netbuf_ptr->native.FRAG[0].LENGTH, MALLOC_ID_NETBUFF); + + if (a_netbuf_ptr->native.FRAG[0].FRAGMENT == NULL) + { + A_FREE(a_netbuf_ptr, MALLOC_ID_NETBUFF_OBJ); + a_netbuf_ptr = NULL; + break; + } + + a_netbuf_ptr->head = a_netbuf_ptr->tail = a_netbuf_ptr->data = a_netbuf_ptr->native.FRAG[0].FRAGMENT; + a_netbuf_ptr->end = + (pointer)((uint32_t)a_netbuf_ptr->native.FRAG[0].FRAGMENT + (uint32_t)a_netbuf_ptr->native.FRAG[0].LENGTH); + A_MEMZERO(&a_netbuf_ptr->trans, sizeof(A_TRANSPORT_OBJ)); + } while (0); + + return ((void *)a_netbuf_ptr); +} + +void a_netbuf_free(void *buffptr) +{ + ((A_NATIVE_ORIG *)buffptr)->FREE(((A_NATIVE_ORIG *)buffptr)); +} + +/* returns the length in bytes of the entire packet. The packet may + * be composed of multiple fragments or it may be just a single buffer. + */ +uint32_t a_netbuf_to_len(void *bufPtr) +{ + A_NETBUF *a_netbuf_ptr = (A_NETBUF *)bufPtr; + uint32_t len = (uint32_t)a_netbuf_ptr->tail - (uint32_t)a_netbuf_ptr->data; + uint16_t i = 0; + + if (a_netbuf_ptr->num_frags) + { + if (a_netbuf_ptr->native_orig != NULL) + { + /* count up fragments */ + for (i = 0; i < a_netbuf_ptr->num_frags; i++) + { + len += a_netbuf_ptr->native_orig->FRAG[i].LENGTH; + } + } + else + { + /* used for special case native's from ATH_TX_RAW */ + for (i = 1; i <= a_netbuf_ptr->num_frags; i++) + { + len += a_netbuf_ptr->native.FRAG[i].LENGTH; + } + } + } + + return len; +} + +/* returns a buffer fragment of a packet. If the packet is not + * fragmented only index == 0 will return a buffer which will be + * the whole packet. pLen will hold the length of the buffer in + * bytes. + */ +void *a_netbuf_get_fragment(void *bufPtr, uint8_t index, int32_t *pLen) +{ + void *pBuf = NULL; + A_NETBUF *a_netbuf_ptr = (A_NETBUF *)bufPtr; + + if (0 == index) + { + pBuf = a_netbuf_to_data(bufPtr); + *pLen = (int32_t)((uint32_t)a_netbuf_ptr->tail - (uint32_t)a_netbuf_ptr->data); + } + else if (a_netbuf_ptr->num_frags >= index) + { + if (a_netbuf_ptr->native_orig) + { + /* additional fragments are held in native_orig. this is only + * used for tx packets received from the TCP stack. */ + pBuf = a_netbuf_ptr->native_orig->FRAG[index - 1].FRAGMENT; + *pLen = (int32_t)a_netbuf_ptr->native_orig->FRAG[index - 1].LENGTH; + } + else + { + /* used for special case native's from ATH_TX_RAW */ + pBuf = a_netbuf_ptr->native.FRAG[index].FRAGMENT; + *pLen = (int32_t)a_netbuf_ptr->native.FRAG[index].LENGTH; + } + } + + return pBuf; +} + +/* fills the spare bufFragment position for the net buffer */ +void a_netbuf_append_fragment(void *bufPtr, uint8_t *frag, int32_t len) +{ + A_NETBUF *a_netbuf_ptr = (A_NETBUF *)bufPtr; + /* the first bufFragment is used to hold the built-in buffer. subsequent + * entries if any can be used to append additional buffers. hence + * deduct 1 from MAX_BUF_FRAGS */ + if (a_netbuf_ptr->num_frags < MAX_BUF_FRAGS - 1) + { + a_netbuf_ptr->num_frags++; + a_netbuf_ptr->native.FRAG[a_netbuf_ptr->num_frags].FRAGMENT = frag; + a_netbuf_ptr->native.FRAG[a_netbuf_ptr->num_frags].LENGTH = len; + } + else + { + A_ASSERT(0); + } +} + +#else +#include "common_stack_offload.h" +#include "custom_stack_offload.h" + +void a_netbuf_set_tx_pool(void *buffptr); +void a_netbuf_set_rx_pool(void *buffptr); +void a_netbuf_free_tx_pool(void *buffptr); +void a_netbuf_free_rx_pool(void *buffptr); +void Driver_ReportRxBuffStatus(void *pCxt, boolean status); + +void default_native_free_fn(void *pcb_ptr) +{ + A_NETBUF *a_netbuf_ptr = (A_NETBUF *)pcb_ptr; + /* head is guaranteed to always point to the + * start of the original buffer */ + if (a_netbuf_ptr->head) + { + A_FREE(a_netbuf_ptr->head, MALLOC_ID_NETBUFF); + } + if (a_netbuf_ptr->native_orig) + { + txpkt_free(a_netbuf_ptr->native_orig); + } + A_FREE(a_netbuf_ptr, MALLOC_ID_NETBUFF_OBJ); +} + +void *a_netbuf_dequeue_adv(A_NETBUF_QUEUE_T *q, void *pkt) +{ + A_NETBUF *curr, *prev = NULL; + + if (q->head == NULL) + return (void *)NULL; + + curr = (A_NETBUF *)q->head; + + while (curr != NULL) + { + if ((A_NETBUF *)curr->data == pkt) + { + /*Match found*/ + if (curr == (A_NETBUF *)q->head) + { + /*Match found at head*/ + q->head = curr->queueLink; + break; + } + else + { + /*Match found at intermediate node*/ + prev->queueLink = curr->queueLink; + if (q->tail == curr) + { + /*Last node*/ + q->tail = prev; + } + break; + } + } + prev = curr; + curr = curr->queueLink; + } + + if (curr != NULL) + { + q->count--; + curr->queueLink = NULL; + } + return (void *)curr; +} + +void a_netbuf_purge_queue(uint32_t index) +{ + SOCKET_CONTEXT_PTR pcustctxt; + A_NETBUF_QUEUE_T *q; + A_NETBUF *temp; + + pcustctxt = GET_SOCKET_CONTEXT(ath_sock_context[index]); + + q = &pcustctxt->rxqueue; + + while (q->count) + { + temp = q->head; + q->head = A_GET_QUEUE_LINK(temp); + A_CLEAR_QUEUE_LINK(temp); + A_NETBUF_FREE(temp); + q->count--; + } + q->head = q->tail = NULL; +} + +void a_netbuf_init(void *buffptr, void *freefn, void *priv) +{ + A_NETBUF *a_netbuf_ptr = (A_NETBUF *)buffptr; + + // a_netbuf_ptr->native.FREE = (_pcb_free_fn)freefn; + a_netbuf_ptr->native.context = priv; + a_netbuf_ptr->tail = a_netbuf_ptr->data = (void *)((uint32_t)a_netbuf_ptr->head + AR6000_DATA_OFFSET); + a_netbuf_ptr->native.bufFragment[0].payload = a_netbuf_ptr->head; + a_netbuf_ptr->native.bufFragment[0].length = (uint32_t)a_netbuf_ptr->end - (uint32_t)a_netbuf_ptr->head; +#if DRIVER_CONFIG_IMPLEMENT_RX_FREE_QUEUE + a_netbuf_ptr->rxPoolID = 1; +#endif +} + +void *a_netbuf_alloc(int32_t size) +{ + A_NETBUF *a_netbuf_ptr; + + do + { + a_netbuf_ptr = A_MALLOC(sizeof(A_NETBUF), MALLOC_ID_NETBUFF_OBJ); + + if (a_netbuf_ptr == NULL) + { + break; + } + A_MEMZERO(a_netbuf_ptr, sizeof(A_NETBUF)); + + a_netbuf_ptr->native.bufFragment[0].length = AR6000_DATA_OFFSET + size; + a_netbuf_ptr->native.bufFragment[0].payload = + A_MALLOC((int32_t)(a_netbuf_ptr->native.bufFragment[0].length), MALLOC_ID_NETBUFF); + + if (a_netbuf_ptr->native.bufFragment[0].payload == NULL) + { + A_FREE(a_netbuf_ptr, MALLOC_ID_NETBUFF_OBJ); + a_netbuf_ptr = NULL; + break; + } + + a_netbuf_ptr->head = a_netbuf_ptr->native.bufFragment[0].payload; + a_netbuf_ptr->end = (void *)((uint32_t)a_netbuf_ptr->native.bufFragment[0].payload + + a_netbuf_ptr->native.bufFragment[0].length); + // reserve head room + a_netbuf_ptr->tail = a_netbuf_ptr->data = (void *)((uint32_t)a_netbuf_ptr->head + AR6000_DATA_OFFSET); + A_MEMZERO(&a_netbuf_ptr->trans, sizeof(A_TRANSPORT_OBJ)); + /*Init pool IDs*/ + a_netbuf_ptr->txPoolID = 0; + a_netbuf_ptr->rxPoolID = 0; + } while (0); + + return ((void *)a_netbuf_ptr); +} + +/*****************************************************************************/ +/* a_netbuf_reinit - called from custom free after TX over SPI is completed. + It is only called in "Blocking TX" mode where we reuse the same + netbuf. + Tail, data pointers within netbuf may have moved during previous TX, + reinit the netbuf so it can be used again. No allocation is done here. + + * RETURNS: reinitialized netbuf pointer for success and NULL for failure + *****************************************************************************/ +void *a_netbuf_reinit(void *netbuf_ptr, int32_t size) +{ + A_NETBUF *a_netbuf_ptr = (A_NETBUF *)(netbuf_ptr); + + do + { + a_netbuf_ptr->native.bufFragment[0].length = AR6000_DATA_OFFSET + size; + + a_netbuf_ptr->head = a_netbuf_ptr->native.bufFragment[0].payload; + a_netbuf_ptr->end = (void *)((uint32_t)a_netbuf_ptr->native.bufFragment[0].payload + + a_netbuf_ptr->native.bufFragment[0].length); + // reserve head room + a_netbuf_ptr->tail = a_netbuf_ptr->data = (void *)((uint32_t)a_netbuf_ptr->head + AR6000_DATA_OFFSET); + A_MEMZERO(&a_netbuf_ptr->trans, sizeof(A_TRANSPORT_OBJ)); + /*Init pool IDs*/ + a_netbuf_ptr->txPoolID = 0; + a_netbuf_ptr->rxPoolID = 0; + } while (0); + + return ((void *)a_netbuf_ptr); +} + +void a_netbuf_set_rx_pool(void *buffptr) +{ + A_NETBUF *a_netbuf_ptr = (A_NETBUF *)buffptr; + a_netbuf_ptr->rxPoolID = 1; +} + +void a_netbuf_set_tx_pool(void *buffptr) +{ + A_NETBUF *a_netbuf_ptr = (A_NETBUF *)buffptr; + a_netbuf_ptr->txPoolID = 1; +} + +/* + * Allocate an NETBUF w.o. any encapsulation requirement. + */ +void *a_netbuf_alloc_raw(int32_t size) +{ + A_NETBUF *a_netbuf_ptr = NULL; + + do + { + a_netbuf_ptr = A_MALLOC(sizeof(A_NETBUF), MALLOC_ID_NETBUFF_OBJ); + + if (a_netbuf_ptr == NULL) + { + break; + } + + A_MEMZERO(a_netbuf_ptr, sizeof(A_NETBUF)); + + // a_netbuf_ptr->native.FREE = default_native_free_fn; + a_netbuf_ptr->native.bufFragment[0].length = (uint32_t)size; + a_netbuf_ptr->native.bufFragment[0].payload = + A_MALLOC((int32_t)a_netbuf_ptr->native.bufFragment[0].length, MALLOC_ID_NETBUFF); + + if (a_netbuf_ptr->native.bufFragment[0].payload == NULL) + { + A_FREE(a_netbuf_ptr, MALLOC_ID_NETBUFF_OBJ); + a_netbuf_ptr = NULL; + break; + } + + a_netbuf_ptr->head = a_netbuf_ptr->tail = a_netbuf_ptr->data = a_netbuf_ptr->native.bufFragment[0].payload; + a_netbuf_ptr->end = (void *)((uint32_t)a_netbuf_ptr->native.bufFragment[0].payload + + (uint32_t)a_netbuf_ptr->native.bufFragment[0].length); + A_MEMZERO(&a_netbuf_ptr->trans, sizeof(A_TRANSPORT_OBJ)); + } while (0); + + return ((void *)a_netbuf_ptr); +} + +void a_netbuf_free(void *buffptr) +{ + A_NETBUF *a_netbuf_ptr = (A_NETBUF *)buffptr; + if (a_netbuf_ptr->rxPoolID != 0) + { + a_netbuf_free_rx_pool(buffptr); + return; + } + else if (a_netbuf_ptr->txPoolID != 0) + { + a_netbuf_free_tx_pool(buffptr); + return; + } + else + { + if (a_netbuf_ptr->native_orig) + { + /*This was a TX packet, do not free netbuf here as it may be reused*/ + txpkt_free(a_netbuf_ptr); + } + else + { + /*For all other packets, free the netbuf*/ + if (a_netbuf_ptr->head) + { + A_FREE(a_netbuf_ptr->head, MALLOC_ID_NETBUFF); + } + + A_FREE(a_netbuf_ptr, MALLOC_ID_NETBUFF_OBJ); + } + } +} + +void a_netbuf_free_rx_pool(void *buffptr) +{ + A_NETBUF *a_netbuf_ptr = (A_NETBUF *)buffptr; + A_CUSTOM_DRIVER_CONTEXT *pCxt = (A_CUSTOM_DRIVER_CONTEXT *)a_netbuf_ptr->native.context; + + RXBUFFER_ACCESS_ACQUIRE((void *)pCxt); +// A_NETBUF_ENQUEUE(&(pCxt->rxFreeQueue), a_netbuf_ptr); +#if DRIVER_CONFIG_IMPLEMENT_RX_FREE_QUEUE + A_NETBUF_ENQUEUE(&(GET_DRIVER_COMMON(pCxt)->rxFreeQueue), a_netbuf_ptr); +#endif + Driver_ReportRxBuffStatus((void *)pCxt, true); + RXBUFFER_ACCESS_RELEASE((void *)pCxt); +} + +void a_netbuf_free_tx_pool(void *buffptr) +{ +} +/* returns the length in bytes of the entire packet. The packet may + * be composed of multiple fragments or it may be just a single buffer. + */ +uint32_t a_netbuf_to_len(void *bufPtr) +{ + A_NETBUF *a_netbuf_ptr = (A_NETBUF *)bufPtr; + uint32_t len = (uint32_t)a_netbuf_ptr->tail - (uint32_t)a_netbuf_ptr->data; + uint16_t i = 0; + + if (a_netbuf_ptr->num_frags) + { + if (a_netbuf_ptr->native_orig != NULL) + { + /* count up fragments */ + for (i = 0; i < a_netbuf_ptr->num_frags; i++) + { + len += a_netbuf_ptr->native_orig->bufFragment[i].length; + } + } + else + { + /* used for special case native's from ATH_TX_RAW */ + for (i = 1; i <= a_netbuf_ptr->num_frags; i++) + { + len += a_netbuf_ptr->native.bufFragment[i].length; + } + } + } + + return len; +} + +/* returns a buffer fragment of a packet. If the packet is not + * fragmented only index == 0 will return a buffer which will be + * the whole packet. pLen will hold the length of the buffer in + * bytes. + */ +void *a_netbuf_get_fragment(void *bufPtr, uint8_t index, int32_t *pLen) +{ + void *pBuf = NULL; + A_NETBUF *a_netbuf_ptr = (A_NETBUF *)bufPtr; + + if (0 == index) + { + pBuf = a_netbuf_to_data(bufPtr); + *pLen = (int32_t)((uint32_t)a_netbuf_ptr->tail - (uint32_t)a_netbuf_ptr->data); + } + else if (a_netbuf_ptr->num_frags >= index) + { + if (a_netbuf_ptr->native_orig) + { + /* additional fragments are held in native_orig. this is only + * used for tx packets received from the TCP stack. */ + pBuf = a_netbuf_ptr->native_orig->bufFragment[index - 1].payload; + *pLen = (int32_t)a_netbuf_ptr->native_orig->bufFragment[index - 1].length; + } + else + { + /* used for special case native's from ATH_TX_RAW */ + pBuf = a_netbuf_ptr->native.bufFragment[index].payload; + *pLen = (int32_t)a_netbuf_ptr->native.bufFragment[index].length; + } + } + + return pBuf; +} + +/* fills the spare bufFragment position for the net buffer */ +void a_netbuf_append_fragment(void *bufPtr, uint8_t *frag, int32_t len) +{ + A_NETBUF *a_netbuf_ptr = (A_NETBUF *)bufPtr; + /* the first bufFragment is used to hold the built-in buffer. subsequent + * entries if any can be used to append additional buffers. hence + * deduct 1 from MAX_BUF_FRAGS */ + if (a_netbuf_ptr->num_frags < MAX_BUF_FRAGS - 1) + { + a_netbuf_ptr->num_frags++; + a_netbuf_ptr->native.bufFragment[a_netbuf_ptr->num_frags].payload = frag; + a_netbuf_ptr->native.bufFragment[a_netbuf_ptr->num_frags].length = len; + } + else + { + A_ASSERT(0); + } +} + +#endif /*!ENABLE_STACK_OFFLOAD*/ + +void a_netbuf_enqueue(A_NETBUF_QUEUE_T *q, void *pReq) +{ + // uint8_t i; + OSA_Critical(kCriticalDisableInt); + OSA_EnterCritical(kCriticalDisableInt); + if (q->head == NULL) + { + q->head = pReq; + } + else + { + A_ASSIGN_QUEUE_LINK(q->tail, pReq); + //((A_NETBUF*)q->tail)->queueLink = (A_NETBUF*)pReq; + } + + q->tail = pReq; + A_CLEAR_QUEUE_LINK(pReq); + //((A_NETBUF*)pkt)->queueLink = NULL; + q->count++; + OSA_ExitCritical(kCriticalDisableInt); +} + +void a_netbuf_prequeue(A_NETBUF_QUEUE_T *q, void *pReq) +{ + if (q->head == NULL) + { + q->tail = pReq; + } + A_ASSIGN_QUEUE_LINK(pReq, q->head); + //((A_NETBUF*)pkt)->queueLink = q->head; + q->head = pReq; + q->count++; +} + +void *a_netbuf_dequeue(A_NETBUF_QUEUE_T *q) +{ + void *pReq; + OSA_Critical(kCriticalDisableInt); + if (q->head == NULL) + return (void *)NULL; + OSA_EnterCritical(kCriticalDisableInt); + pReq = q->head; + + if (q->tail == q->head) + { + q->tail = q->head = NULL; + } + else + { + q->head = A_GET_QUEUE_LINK(pReq); + // q->head = (void*)(curr->queueLink); + } + + q->count--; + A_CLEAR_QUEUE_LINK(pReq); + // curr->queueLink = NULL; + OSA_ExitCritical(kCriticalDisableInt); + return (void *)pReq; +} + +void a_netbuf_queue_init(A_NETBUF_QUEUE_T *q) +{ + q->head = q->tail = NULL; + q->count = 0; +} + +void a_netbuf_configure(void *buffptr, void *buffer, uint16_t headroom, uint16_t length, uint16_t size) +{ + A_NETBUF *a_netbuf_ptr = (A_NETBUF *)buffptr; + + A_MEMZERO(a_netbuf_ptr, sizeof(A_NETBUF)); + + if (buffer != NULL) + { + a_netbuf_ptr->head = buffer; + a_netbuf_ptr->data = &(((uint8_t *)buffer)[headroom]); + a_netbuf_ptr->tail = &(((uint8_t *)buffer)[headroom + length]); + a_netbuf_ptr->end = &(((uint8_t *)buffer)[size]); + } +} + +void *a_netbuf_to_data(void *bufPtr) +{ + return (((A_NETBUF *)bufPtr)->data); +} + +/* + * Add len # of bytes to the beginning of the network buffer + * pointed to by bufPtr + */ +A_STATUS +a_netbuf_push(void *bufPtr, int32_t len) +{ + A_NETBUF *a_netbuf_ptr = (A_NETBUF *)bufPtr; + + if ((uint32_t)a_netbuf_ptr->data - (uint32_t)a_netbuf_ptr->head < (uint32_t)len) + { + A_ASSERT(0); + } + + a_netbuf_ptr->data = (void *)(((uint32_t)a_netbuf_ptr->data) - len); + + return A_OK; +} + +/* + * Add len # of bytes to the beginning of the network buffer + * pointed to by bufPtr and also fill with data + */ +A_STATUS +a_netbuf_push_data(void *bufPtr, uint8_t *srcPtr, int32_t len) +{ + a_netbuf_push(bufPtr, len); + A_MEMCPY(((A_NETBUF *)bufPtr)->data, srcPtr, (uint32_t)len); + + return A_OK; +} + +/* + * Add len # of bytes to the end of the network buffer + * pointed to by bufPtr + */ +A_STATUS +a_netbuf_put(void *bufPtr, int32_t len) +{ + A_NETBUF *a_netbuf_ptr = (A_NETBUF *)bufPtr; + + if ((uint32_t)a_netbuf_ptr->end - (uint32_t)a_netbuf_ptr->tail < (uint32_t)len) + { + A_ASSERT(0); + } + + a_netbuf_ptr->tail = (void *)(((uint32_t)a_netbuf_ptr->tail) + len); + + return A_OK; +} + +/* + * Add len # of bytes to the end of the network buffer + * pointed to by bufPtr and also fill with data + */ +A_STATUS +a_netbuf_put_data(void *bufPtr, uint8_t *srcPtr, int32_t len) +{ + A_NETBUF *a_netbuf_ptr = (A_NETBUF *)bufPtr; + void *start = a_netbuf_ptr->tail; + + a_netbuf_put(bufPtr, len); + A_MEMCPY(start, srcPtr, (uint32_t)len); + + return A_OK; +} + +/* + * Returns the number of bytes available to a a_netbuf_push() + */ +int32_t a_netbuf_headroom(void *bufPtr) +{ + A_NETBUF *a_netbuf_ptr = (A_NETBUF *)bufPtr; + + return (int32_t)((uint32_t)a_netbuf_ptr->data - (uint32_t)a_netbuf_ptr->head); +} + +int32_t a_netbuf_tailroom(void *bufPtr) +{ + A_NETBUF *a_netbuf_ptr = (A_NETBUF *)bufPtr; + + return (int32_t)((uint32_t)a_netbuf_ptr->end - (uint32_t)a_netbuf_ptr->tail); +} + +/* + * Removes specified number of bytes from the beginning of the buffer + */ +A_STATUS +a_netbuf_pull(void *bufPtr, int32_t len) +{ + A_NETBUF *a_netbuf_ptr = (A_NETBUF *)bufPtr; + + if ((uint32_t)a_netbuf_ptr->tail - (uint32_t)a_netbuf_ptr->data < (uint32_t)len) + { + A_ASSERT(0); + } + + a_netbuf_ptr->data = (void *)((uint32_t)a_netbuf_ptr->data + len); + + return A_OK; +} + +/* + * Removes specified number of bytes from the end of the buffer + */ +A_STATUS +a_netbuf_trim(void *bufPtr, int32_t len) +{ + A_NETBUF *a_netbuf_ptr = (A_NETBUF *)bufPtr; + + if ((uint32_t)a_netbuf_ptr->tail - (uint32_t)a_netbuf_ptr->data < (uint32_t)len) + { + A_ASSERT(0); + } + + a_netbuf_ptr->tail = (void *)((uint32_t)a_netbuf_ptr->tail - len); + + return A_OK; +} diff --git a/platform/mcu/lpc54102/wifi_qca/custom_src/hw_interface/cust_spi_hcd.c b/platform/mcu/lpc54102/wifi_qca/custom_src/hw_interface/cust_spi_hcd.c new file mode 100644 index 0000000000..3161910d26 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/custom_src/hw_interface/cust_spi_hcd.c @@ -0,0 +1,126 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== + +#include +#include +#include +#include +#include +#include +#include +#include "spi_hcd_if.h" +#include +#include "hw20_mbox_host_reg.h" +#include +#include +#include "atheros_wifi_api.h" + +// ============================================================================ +// +// ============================================================================ + +#define SPI_POWER_UP_DELAY (1) +#define SPI_HW_CAPS (HW_SPI_FRAME_WIDTH_8 | HW_SPI_NO_DMA | HW_SPI_INT_EDGE_DETECT) +#define SPI_MAX_ALLOWED_BAUD_RATE 25000000 + +// ============================================================================ +// +// ============================================================================ + +// DROPPED +// void Custom_Hcd_EnableDisableSPIIRQ(void *pCxt, boolean enable) +//{ +// A_CUSTOM_DRIVER_CONTEXT *pCustCxt = (A_CUSTOM_DRIVER_CONTEXT *) pCxt; +// wlan_hardware_config_t *wlanHardwareConfig = (wlan_hardware_config_t *) pCustCxt->pDriverParam; +// IRQn_Type irqNumber = wlanHardwareConfig->wlan_irq_number; +// +// if (enable) { +// INT_SYS_EnableIRQ(irqNumber); +// } +// else { +// INT_SYS_DisableIRQ(irqNumber); +// } +//} + +// A_STATUS Custom_HW_Init(void *pCxt) +//{ +// // TODO: Check endianess of SPI +// +// A_CUSTOM_DRIVER_CONTEXT *pCustCxt = (A_CUSTOM_DRIVER_CONTEXT *) pCxt; +// wlan_hardware_config_t *wlanHardwareConfig = (wlan_hardware_config_t *) pCustCxt->pDriverParam; +// +// A_SPI_CTX *spiCxt = &pCustCxt->customhcdcxt.spi_cxt; +// +// // Copy the SPI instance number from the configuration to the local copy +// spiCxt->spi_instance = wlanHardwareConfig->spi_instance; +// //uint32_t spiClk = CLOCK_SYS_GetSpiFreq(spiCxt->spi_instance); +// +// uint32_t baudrate = wlanHardwareConfig->spi_baudrate; +// //if (baudrate > SPI_MAX_ALLOWED_BAUD_RATE) +// // baudrate = SPI_MAX_ALLOWED_BAUD_RATE; +// +// +// +//// spiCxt->userConfig.isChipSelectContinuous = false; +//// spiCxt->userConfig.isSckContinuous = false; +//// spiCxt->userConfig.pcsPolarity = kDspiPcs_ActiveLow; +//// spiCxt->userConfig.whichCtar = kDspiCtar0; +//// spiCxt->userConfig.whichPcs = wlanHardwareConfig->spi_cs; +// spiCxt->masterDevice.dataBusConfig.bitsPerFrame = 8; +// // spiCxt->masterDevice.dataBusConfig.clkPhase = kDspiClockPhase_FirstEdge; +// spiCxt->masterDevice.dataBusConfig.clkPhase = kDspiClockPhase_SecondEdge; +// spiCxt->masterDevice.dataBusConfig.clkPolarity = kDspiClockPolarity_ActiveLow; +// spiCxt->masterDevice.dataBusConfig.direction = kDspiMsbFirst; +// +// spiCxt->masterDevice.bitsPerSec = baudrate; +// +// // Initialize master driver +// dspi_status_t res; +// res = DSPI_DRV_MasterInit(spiCxt->spi_instance, +// &spiCxt->masterState, +// &spiCxt->userConfig); +// if (spiCxt->spiResult != kStatus_DSPI_Success) { +// return res; +// } +// +// res = DSPI_DRV_MasterConfigureBus(spiCxt->spi_instance, +// &spiCxt->masterDevice, +// &spiCxt->calculatedBaudRate); +// if (res != kStatus_DSPI_Success) { +// return res; +// } +// +// +// // It is necessary for the custom code to populate the following parameters +// // so that the common code knows what kind of hardware it is working with +// A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(pCxt); +// pDCxt->spi_hcd.OperationalClock = spiCxt->calculatedBaudRate; +// pDCxt->spi_hcd.PowerUpDelay = SPI_POWER_UP_DELAY; +// pDCxt->spi_hcd.SpiHWCapabilitiesFlags = SPI_HW_CAPS; +// pDCxt->spi_hcd.MiscFlags |= MISC_FLAG_RESET_SPI_IF_SHUTDOWN; +// +// return A_OK; +//} diff --git a/platform/mcu/lpc54102/wifi_qca/custom_src/include/a_config.h b/platform/mcu/lpc54102/wifi_qca/custom_src/include/a_config.h new file mode 100644 index 0000000000..7b3014988b --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/custom_src/include/a_config.h @@ -0,0 +1,171 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +// Author(s): ="Atheros" +//============================================================================== + +#ifndef _CONFIG_H_ +#define _CONFIG_H_ +#include "fsl_debug_console.h" + +#include "wifi_common.h" + +#ifdef __cplusplus +extern "C" { +#endif + +// ============================================================================ +// Debug and assert printing +// ============================================================================ + +// KSDK printf defined in fsl_debug_console.h +// extern int debug_printf(const char *fmt_s, ...); + +// Define this to a printf-like function to print asserts via qcadrv_assert_func() +//#define ASSERT_PRINTF(...) +//#define ASSERT_PRINTF(...) debug_printf(__VA_ARGS__) + +// Define these to enable WMI RX event tracing +#define WMI_DEBUG_RX_EVENT(cmdId, pReq) +//#define WMI_DEBUG_RX_EVENT(cmdId, pReq) debug_printf("wmiRx=%x\r\n", id) + +// Define this to enable WMI TX command tracing +#define WMI_DEBUG_TX_COMMAND(cmdId, pReq) +//#define WMI_DEBUG_TX_COMMAND(cmdId, pReq) debug_printf("wmiTx=%x\r\n", cmdId) + +// The original QCA driver developers have sprinkled printf statements at more +// or less random places and if you want to see thes, then define this macro +#define QCADRV_PRINTF(...) +//#define QCADRV_PRINTF(...) debug_printf(__VA_ARGS__) + +// NOTE: wmi.c contains a plethora of debug definitions and they are pretty hard +// to make head or tails out of but if you define AR_DEBUG_PRINTF() in a_debug.h +// to some printf() function then you enable some additional WMI tracing that +// were put in place by the original QCA driver developers. + +// ============================================================================ +// +// ============================================================================ + +#define ENABLE_FPGA_BUILD 0 + +#define USE_4BYTE_REGISTER_ACCESS + +#define TARGET_AR4100_REV2 0x30000582 +#define TARGET_AR400X_REV1 0x31C80997 +#define TARGET_AR400X_REV2 0x31C80002 +#define TARGET_AR400X_REV3 0x31C8270E +#define TARGET_AR400X_REV4 0x32000052 + +#define ATH_FIRMWARE_TARGET TARGET_AR400X_REV1 // TARGET_AR400X_REV2 + +#ifndef SUPPORT_11N +#define SUPPORT_11N 1 +#endif + +/* PORT_NOTE: Set the following DRIVER_CONFIG_... defines according to + * the requirements/attributes of the OS and MCU. */ + +/* DRIVER_CONFIG_INCLUDE_BMI - optionally set to 0 if the driver will + * not be used in BMI mode and code space needs to be saved. + * If the driver will be used in BMI for flash reprogram or other then + * this option must be 1. + */ +#define DRIVER_CONFIG_INCLUDE_BMI 1 // 1 or 0 + +/* DRIVER_CONFIG_DISABLE_ASSERT - set to 1 if assert NOP behavior is + * preferred */ +#define DRIVER_CONFIG_DISABLE_ASSERT 0 // 1 or 0 +/* DRIVER_CONFIG_PROFILE_BOOT - can be used to profile driver boot + * process with GPIO's + logic analyzer */ +#define DRIVER_CONFIG_PROFILE_BOOT 0 // 1 or 0 + +/* DRIVER_CONFIG_IMPLEMENT_RX_FREE_QUEUE - set if driver should + * implement a RX Free Queue */ +#define DRIVER_CONFIG_IMPLEMENT_RX_FREE_QUEUE 1 // 1 or 0 + +/*TCPIP stack offload for AR4001*/ +#define ENABLE_STACK_OFFLOAD 1 // 1 or 0 +#if !ENABLE_STACK_OFFLOAD +# error "WiFi driver works only with ENABLE_STACK_OFFLOAD enabled ! " +#endif + +#define T_SELECT_VER1 1 // 1 or 0 + +/* DRIVER_CONFIG_ENABLE_STORE_RECALL - optionally set to zero to reduce + * driver memory footprint. + */ +#define DRIVER_CONFIG_ENABLE_STORE_RECALL 1 // 1 or 0 + +#define ENABLE_AP_MODE 1 // 1 or 0 + +#define MULTI_SOCKET_SUPPORT 1 // 1 or 0 + +#define MANUFACTURING_SUPPORT 1 +#define ENABLE_P2P_MODE 1 // 1 or 0 + +/* DRIVER_CONFIG_PROGRAM_MAC_ADDR - optionally add code to allow an application + * to program a new mac address to the wifi device. this code should only + * be included when programming a mac address is required such as during + * production. otherwise code space can be saved by setting this to 0. + */ +#define DRIVER_CONFIG_PROGRAM_MAC_ADDR 1 // 1 or 0 + +/* DRIVER_CONFIG_ENABLE_HOST_FW_DOWNLOAD is used to enable Firmware download + from the host. This feature is implemented but kept disable and can be enabled + on need basis. DO NOT EDIT NEXT LINE INCLUDING THE SPACE. BUILD SCRIPT SEARCHES + FOR THIS PATTERN AND UPDATES IT IN BUILD TIME. */ +#define DRIVER_CONFIG_ENABLE_HOST_FW_DOWNLOAD 0 // 1 or 0 + +#define ENABLE_HTTP_SERVER 1 // 1 or 0 + +#define ENABLE_HTTP_CLIENT 1 // 1 or 0 + +#define ENABLE_DNS_SERVER 1 // 1 or 0 + +#define ENABLE_DNS_CLIENT 1 // 1 or 0 + +#define ENABLE_SNTP_CLIENT 1 // 1 or 0 + +#define ENABLE_RAW_SOCKET_DEMO 1 // 1 or 0 + +#define WLAN_NUM_OF_DEVICES 1 // 1 or 2 + +#define ENABLE_ROUTING_CMDS 1 // 1 or 0 +#define ENABLE_HTTPS_SERVER 1 // 1 or 0 + +#define ENABLE_HTTPS_CLIENT 1 // 1 or 0 + +#define ENABLE_SSL 1 // 1 or 0 + +#define ENABLE_SCC_MODE 1 // 1 or 0 +#define ENABLE_KF_PERFORMANCE 1 + +#define ENABLE_LARGE_DSET 1 // 1 or 0 + +#include "wlan_config.h" + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/platform/mcu/lpc54102/wifi_qca/custom_src/include/a_osapi.h b/platform/mcu/lpc54102/wifi_qca/custom_src/include/a_osapi.h new file mode 100644 index 0000000000..73352988be --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/custom_src/include/a_osapi.h @@ -0,0 +1,191 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== +#ifndef _A_OSAPI_H_ +#define _A_OSAPI_H_ + +/* PORT_NOTE: Include any System header files here to resolve any types used + * in A_CUSTOM_DRIVER_CONTEXT */ +#include + +#include "a_config.h" +#include "a_types.h" +#include +#include + +#define MEM_TYPE_ATHEROS_PERSIST_RX_PCB 0x2001 + +/* there exist within the common code a few places that make use of the + * inline option. This macro can be used to properly declare inline for the compiler + * or it can be used to disable inlining be leaving the macro blank. + */ +#ifndef INLINE +#define INLINE inline +#endif +/* PREPACK and/or POSTPACK are used with compilers that require each data structure + * that requires single byte alignment be declared individually. these macros typically + * would be used in place of athstartpack.h and athendpack.h which would be used with + * compilers that allow this feature to be invoked through a one-time pre-processor command. + */ + +#if defined(__ICCARM__) +# define PREPACK __packed +# define POSTPACK +# define FIELD_PACKED +# define PREWEAK_CODE __weak +# define POSTWEAK_CODE +#elif defined(__GNUC__) +# define PREPACK +# define POSTPACK __attribute__ ((__packed__)) +# define FIELD_PACKED +# define PREWEAK_CODE +# define POSTWEAK_CODE __attribute__((weak)) +#elif defined(__CC_ARM) +# define PREPACK __packed +# define POSTPACK +# define FIELD_PACKED +# define PREWEAK_CODE __weak +# define POSTWEAK_CODE +#else +# error "Unsupported toolchain" +#endif + +#ifndef min +#define min(a, b) ((a) < (b)) ? (a) : (b) +#endif + +#ifndef max +#define max(a, b) ((a) > (b)) ? (a) : (b) +#endif + +/* unaligned little endian access */ +#define A_LE_READ_2(p) ((uint16_t)((((uint8_t *)(p))[0]) | (((uint8_t *)(p))[1] << 8))) + +#define A_LE_READ_4(p) \ + ((uint32_t)((((uint8_t *)(p))[0]) | (((uint8_t *)(p))[1] << 8) | (((uint8_t *)(p))[2] << 16) | \ + (((uint8_t *)(p))[3] << 24))) + +/* + * Endianes macros - Used to achieve proper translation to/from wifi chipset endianess. + * these macros should be directed to OS macros or functions that serve this purpose. the + * naming convention is the direction of translation (BE2CPU == BigEndian to native CPU) + * appended with the bit-size (BE2CPU16 == 16 bit operation BE2CPU32 == 32 bit operation + */ + +#if !defined(A_LITTLE_ENDIAN) && !defined(A_BIG_ENDIAN) +# error "Either A_BIG_ENDIAN or A_LITTLE_ENDIAN must be #defined" +#elif defined(A_LITTLE_ENDIAN) && defined(A_BIG_ENDIAN) +# error "A_BIG_ENDIAN and A_LITTLE_ENDIAN cannot be #defined at the same time" +#elif defined(A_LITTLE_ENDIAN) +# define A_BE2CPU16(x) ((uint16_t)(((x) << 8) & 0xff00) | (uint16_t)(((x) >> 8) & 0x00ff)) +# define A_BE2CPU32(x) \ + ((((x) << 24) & 0xff000000) | (((x)&0x0000ff00) << 8) | (((x)&0x00ff0000) >> 8) | (((x) >> 24) & 0x000000ff)) +# define A_LE2CPU16(x) (x) +# define A_LE2CPU32(x) (x) +# define A_CPU2BE16(x) ((uint16_t)(((x) << 8) & 0xff00) | (uint16_t)(((x) >> 8) & 0x00ff)) +# define A_CPU2BE32(x) \ + ((((x) << 24) & 0xff000000) | (((x)&0x0000ff00) << 8) | (((x)&0x00ff0000) >> 8) | (((x) >> 24) & 0x000000ff)) +# define A_CPU2LE32(x) (x) +# define A_CPU2LE16(x) (x) +#elif defined(A_BIG_ENDIAN) +# define A_BE2CPU16(x) (x) +# define A_BE2CPU32(x) (x) +# define A_LE2CPU16(x) ((uint16_t)(((x) << 8) & 0xff00) | (uint16_t)(((x) >> 8) & 0x00ff)) +# define A_LE2CPU32(x) \ + ((((x) << 24) & 0xff000000) | (((x)&0x0000ff00) << 8) | (((x)&0x00ff0000) >> 8) | (((x) >> 24) & 0x000000ff)) +# define A_CPU2BE16(x) (x) +# define A_CPU2BE32(x) (x) +# define A_CPU2LE32(x) \ + ((((x) << 24) & 0xff000000) | (((x)&0x0000ff00) << 8) | (((x)&0x00ff0000) >> 8) | (((x) >> 24) & 0x000000ff)) +# define A_CPU2LE16(x) ((uint16_t)(((x) << 8) & 0xff00) | (uint16_t)(((x) >> 8) & 0x00ff)) +#endif + +/* A_MEM -- macros that should be mapped to OS/STDLIB equivalent functions */ +#define A_MEMCPY(dst, src, len) memcpy((dst), (src), (len)) +#define A_MEMZERO(addr, len) memset((addr), 0, (len)) +#define A_MEMCMP(addr1, addr2, len) memcmp((addr1), (addr2), (len)) + +extern uint32_t g_totAlloc; +extern uint32_t g_poolid; + +#define DRIVER_STATE_INVALID 0 +#define DRIVER_STATE_INIT 1 +#define DRIVER_STATE_RUN 2 +#define DRIVER_STATE_SHUTDOWN 3 +extern uint8_t g_driverState; + +inline uint32_t _get_size(void *addr) +{ + uint32_t *ptr = addr; + ptr -= 3; + + if (g_poolid == 0xffffffff) + { + g_poolid = ptr[1]; + } + + if (ptr[1] == g_poolid) + { + return ptr[0]; + } + else + { + QCADRV_PRINTF("STUCK\n"); + while (1) + { + }; + } +} + +void *a_malloc(int32_t size, uint8_t id); +void a_free(void *addr, uint8_t id); + +/* Definitions used for ID param in calls to A_MALLOC and A_FREE */ +// NAME VALUE DESCRIPTION +#define MALLOC_ID_CONTEXT 1 // persistent allocation for the life of Driver +#define MALLOC_ID_NETBUFF 2 // buffer used to perform TX/RX SPI transaction +#define MALLOC_ID_NETBUFF_OBJ 3 // NETBUF object +#define MALLOC_ID_TEMPORARY 4 // other temporary allocation +/* Macros used for heap memory allocation and free */ +#define A_MALLOCINIT() +#define A_MALLOC(size, id) a_malloc(size, id) +#define A_FREE(addr, id) a_free(addr, id) + +#define A_PRINTF(args...) QCADRV_PRINTF(args) + +#if DRIVER_CONFIG_DISABLE_ASSERT +#define A_ASSERT(expr) +#else /* DRIVER_CONFIG_DISABLE_ASSERT */ +extern void *p_Global_Cxt; +extern void qcadrv_assert_func(const char *, int); +//#define A_ASSERT(expr) if(!(expr)) do { qcadrv_assert_func(__FUNCTION__, __LINE__); } while(0) +#define A_ASSERT(expr) assert(expr) +#endif /* DRIVER_CONFIG_DISABLE_ASSERT */ + +/* UNUSED_ARGUMENT - used to solve compiler warnings where arguments to functions are not used + * within the function. + */ + +#endif /* _OSAPI_MQX_H_ */ diff --git a/platform/mcu/lpc54102/wifi_qca/custom_src/include/a_types.h b/platform/mcu/lpc54102/wifi_qca/custom_src/include/a_types.h new file mode 100644 index 0000000000..875521b1e1 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/custom_src/include/a_types.h @@ -0,0 +1,43 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== + +#ifndef _A_TYPES_H_ +#define _A_TYPES_H_ + +#include +#include + +#define UNUSED_ARGUMENT(arg) ((void)arg) + +/* NOTE: boolean is a type that is used in various WMI commands and events. + * as such it is a type that is shared between the wifi chipset and the host. + * It is required for that reason that boolean be treated as a 32-bit/4-byte type. + */ + +// TODO: change those types to int +// typedef int32_t boolean; + +#endif /* _A_TYPES_H_ */ diff --git a/platform/mcu/lpc54102/wifi_qca/custom_src/include/cust_netbuf.h b/platform/mcu/lpc54102/wifi_qca/custom_src/include/cust_netbuf.h new file mode 100644 index 0000000000..a21a19c5d7 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/custom_src/include/cust_netbuf.h @@ -0,0 +1,225 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== +#ifndef _CUST_NETBUF_H_ +#define _CUST_NETBUF_H_ + +#include +#include +#include +#include + +#if !ENABLE_STACK_OFFLOAD + +#include + +#define MAX_BUF_FRAGS 2 /* must match definition of PCB2 */ + /* A_NATIVE_NETBUF and A_NATIVE_ORIG are used to point to upper-layer + * netbuf structures. They are OS/TCP stack dependant. */ +typedef PCB2 A_NATIVE_NETBUF; +typedef PCB A_NATIVE_ORIG; + +/* A_NETBUF represents the data structure for a pReq object (packet) + * throughout the driver. It is part of the custom implementation + * because there may be more optimal ways to achieve the same results + * in other OS/systems. It is expected that any of the elements except + * for the A_TRANSPORT_OBJ can be replaced by some OS specific construct + * thereby making more efficient use of resources. */ +typedef struct _ath_netbuf +{ + A_NATIVE_NETBUF native; // DO NOT MOVE: must be first struct element + uint8_t num_frags; // number of total fragments representing buffer + A_NATIVE_ORIG *native_orig; // the callers ptr passed in send() or NULL + uint8_t *head; // marks the start of head space + uint8_t *data; // marks the start of data space + uint8_t *tail; // marks the start of tail space + uint8_t *end; // marks the end of packet. + void *queueLink; // used to enqueue packets + A_TRANSPORT_OBJ trans; /* container object for netbuf elements */ +} A_NETBUF, *A_NETBUF_PTR; + +void default_native_free_fn(PCB_PTR pcb_ptr); + +#else + +#define MAX_BUF_FRAGS 2 /* must match definition of PCB2 */ +/*Fragment structure*/ +typedef struct db_frag +{ + uint32_t length; // Length in bytes + uint8_t *payload; // Pointer to data +} DB_FRAG, *DB_FRAG_PTR; + +typedef struct drv_buffer +{ + void *context; // Generic placeholder, can be used to store context + DB_FRAG bufFragment[1]; // data fragment +} DRV_BUFFER, *DRV_BUFFER_PTR; + +typedef struct min_db +{ + void *context; + DB_FRAG bufFragment[MAX_BUF_FRAGS]; +} MIN_DB, *MIN_DB_PTR; + +typedef struct tx_packet +{ + DRV_BUFFER db; + uint8_t hdr[88]; + void *a_netbuf_ptr; +} TX_PACKET, *TX_PACKET_PTR; + +/* A_NATIVE_NETBUF and A_NATIVE_ORIG are used to point to upper-layer + * netbuf structures. They are OS/TCP stack dependant. */ +typedef MIN_DB A_NATIVE_NETBUF; +typedef DRV_BUFFER A_NATIVE_ORIG; + +/* A_NETBUF represents the data structure for a pReq object (packet) + * throughout the driver. It is part of the custom implementation + * because there may be more optimal ways to achieve the same results + * in other OS/systems. It is expected that any of the elements except + * for the A_TRANSPORT_OBJ can be replaced by some OS specific construct + * thereby making more efficient use of resources. */ +typedef struct _ath_netbuf +{ + A_NATIVE_NETBUF native; // DO NOT MOVE: must be first struct element + uint8_t num_frags; // number of total fragments representing buffer + A_NATIVE_ORIG *native_orig; // the callers ptr passed in send() or NULL + uint8_t *head; // marks the start of head space + uint8_t *data; // marks the start of data space + uint8_t *tail; // marks the start of tail space + uint8_t *end; // marks the end of packet. + uint8_t txPoolID; // If TX pools are used, assign ID here + uint8_t rxPoolID; // If rx pools are used, assign ID here + void *queueLink; // used to enqueue packets + A_TRANSPORT_OBJ trans; /* container object for netbuf elements */ +} A_NETBUF, *A_NETBUF_PTR; + +/* A_NETBUF_SET_TX_POOL - Set pool ID to indicate buffer is part of tx pool */ +#define A_NETBUF_SET_TX_POOL(bufPtr) a_netbuf_set_tx_pool(bufPtr) + +/* A_NETBUF_SET_RX_POOL - Set pool ID to indicate buffer is part of RX pool */ +#define A_NETBUF_SET_RX_POOL(bufPtr) a_netbuf_set_rx_pool(bufPtr) + +#define A_NETBUF_DEQUEUE_ADV(q, pkt) a_netbuf_dequeue_adv((q), (pkt)) + +#define CUSTOM_PURGE_QUEUE(index) a_netbuf_purge_queue((index)) + +void default_native_free_fn(void *pcb_ptr); +void a_netbuf_set_tx_pool(void *buffptr); +void a_netbuf_set_rx_pool(void *buffptr); +void *a_netbuf_dequeue_adv(A_NETBUF_QUEUE_T *q, void *pkt); +void a_netbuf_purge_queue(uint32_t index); +void *a_netbuf_reinit(void *netbuf_ptr, int32_t size); + +#endif /*!ENABLE_STACK_OFFLOAD*/ + +/* the A_REQ_... definitions are used in calls to A_NETBUF_GET_ELEM and + * A_NETBUF_SET_ELEM. They identify what element is required. The + * developer can either adopt this implementation or create their + * own more suitable definitions as appropriate. */ +#define A_REQ_ADDRESS trans.address +#define A_REQ_EPID trans.epid +#define A_REQ_STATUS trans.status +#define A_REQ_CREDITS trans.credits +#define A_REQ_CALLBACK trans.cb +#define A_REQ_COMMAND trans.cmd +#define A_REQ_LOOKAHEAD trans.lookahead +#define A_REQ_TRANSFER_LEN trans.transferLength + +#define A_NETBUF_GET_ELEM(_obj, _e) ((A_NETBUF *)(_obj))->_e +#define A_NETBUF_SET_ELEM(_obj, _e, _v) ((A_NETBUF *)(_obj))->_e = (_v) + +/* A_CLEAR_QUEUE_LINK - used by netbuf queue code to clear the link. */ +#define A_CLEAR_QUEUE_LINK(_pReq) ((A_NETBUF *)(_pReq))->queueLink = NULL +/* A_ASSIGN_QUEUE_LINK - used by netbuf queue code to populate/connect the link. */ +#define A_ASSIGN_QUEUE_LINK(_pReq, _pN) ((A_NETBUF *)(_pReq))->queueLink = (_pN) +/* A_GET_QUEUE_LINK - used by netbuf queue code to get the link. */ +#define A_GET_QUEUE_LINK(_pReq) ((A_NETBUF *)(_pReq))->queueLink +/* + * Network buffer support + */ + +/* A_NETBUF_DECLARE - declare a NETBUF object on the stack */ +#define A_NETBUF_DECLARE A_NETBUF +/* A_NETBUF_CONFIGURE - (re-)configure a NETBUF object */ +#define A_NETBUF_CONFIGURE(bufPtr, buffer, headroom, length, size) \ + a_netbuf_configure((bufPtr), (buffer), (headroom), (length), (size)) +/* A_NETBUF_ALLOC - allocate a NETBUF object from the "heap". */ +#define A_NETBUF_ALLOC(size) a_netbuf_alloc(size) +/* A_NETBUF_ALLOC_RAW - allocate a NETBUF object from the "heap". */ +#define A_NETBUF_ALLOC_RAW(size) a_netbuf_alloc_raw(size) +/* A_NETBUF_INIT - (re-)initialize a NETBUF object. */ +#define A_NETBUF_INIT(bufPtr, freefn, priv) a_netbuf_init((bufPtr), (freefn), (priv)) +/* A_NETBUF_FREE - release a NETBUF object back to the "heap". */ +#define A_NETBUF_FREE(bufPtr) a_netbuf_free(bufPtr) +/* A_NETBUF_DATA - Get a pointer to the front of valid/populated NETBUF memory. */ +#define A_NETBUF_DATA(bufPtr) a_netbuf_to_data(bufPtr) +/* A_NETBUF_LEN - Get the length of valid/populated NETBUF memory (total for all fragments). */ +#define A_NETBUF_LEN(bufPtr) a_netbuf_to_len(bufPtr) +/* A_NETBUF_PUSH - Adds #len bytes to the beginning of valid/populated NETBUF memory */ +#define A_NETBUF_PUSH(bufPtr, len) a_netbuf_push(bufPtr, len) +/* A_NETBUF_PUT - Adds #len bytes to the end of valid/populated NETBUF memory */ +#define A_NETBUF_PUT(bufPtr, len) a_netbuf_put(bufPtr, len) +/* A_NETBUF_TRIM - Removes #len bytes from the end of the valid/populated NETBUF memory */ +#define A_NETBUF_TRIM(bufPtr, len) a_netbuf_trim(bufPtr, len) +/* A_NETBUF_PULL - Removes #len bytes from the beginning valid/populated NETBUF memory */ +#define A_NETBUF_PULL(bufPtr, len) a_netbuf_pull(bufPtr, len) +/* A_NETBUF_HEADROOM - return the amount of space remaining to prepend content/headers */ +#define A_NETBUF_HEADROOM(bufPtr) a_netbuf_headroom(bufPtr) +/* A_NETBUF_TAILROOM - return the amount of space remaining to append content/trailers */ +#define A_NETBUF_TAILROOM(bufPtr) a_netbuf_tailroom(bufPtr) +/* A_NETBUF_GET_FRAGMENT - Get the indexed fragment from the netbuf */ +#define A_NETBUF_GET_FRAGMENT(bufPtr, index, pLen) a_netbuf_get_fragment((bufPtr), (index), (pLen)) + +/* A_NETBUF_APPEND_FRAGMENT - Add a fragment to the end of the netbuf fragment list */ +#define A_NETBUF_APPEND_FRAGMENT(bufPtr, frag, len) a_netbuf_append_fragment((bufPtr), (frag), (len)) + +/* A_NETBUF_PUT_DATA - Add data to end of a buffer */ +#define A_NETBUF_PUT_DATA(bufPtr, srcPtr, len) a_netbuf_put_data(bufPtr, srcPtr, len) + +/* + * OS specific network buffer access routines + */ + +void a_netbuf_configure(void *buffptr, void *buffer, uint16_t headroom, uint16_t length, uint16_t size); +void a_netbuf_init(void *buffptr, void *freefn, void *priv); +void *a_netbuf_alloc(int32_t size); +void *a_netbuf_alloc_raw(int32_t size); +void a_netbuf_free(void *bufPtr); +void *a_netbuf_to_data(void *bufPtr); +uint32_t a_netbuf_to_len(void *bufPtr); +A_STATUS a_netbuf_push(void *bufPtr, int32_t len); +A_STATUS a_netbuf_push_data(void *bufPtr, uint8_t *srcPtr, int32_t len); +A_STATUS a_netbuf_put(void *bufPtr, int32_t len); +A_STATUS a_netbuf_put_data(void *bufPtr, uint8_t *srcPtr, int32_t len); +A_STATUS a_netbuf_pull(void *bufPtr, int32_t len); +void *a_netbuf_get_fragment(void *bufPtr, uint8_t index, int32_t *pLen); +void a_netbuf_append_fragment(void *bufPtr, uint8_t *frag, int32_t len); +A_STATUS a_netbuf_trim(void *bufPtr, int32_t len); +int32_t a_netbuf_headroom(void *bufPtr); +int32_t a_netbuf_tailroom(void *bufPtr); + +#endif /* _CUST_NETBUF_H_ */ diff --git a/platform/mcu/lpc54102/wifi_qca/custom_src/include/custom_wlan_api.h b/platform/mcu/lpc54102/wifi_qca/custom_src/include/custom_wlan_api.h new file mode 100644 index 0000000000..727e680c97 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/custom_src/include/custom_wlan_api.h @@ -0,0 +1,127 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== +#ifndef _CUSTOM_API_H_ +#define _CUSTOM_API_H_ + +#include + +void Custom_HW_PowerUpDown(void *pCxt, uint32_t powerUp); +/*1A_STATUS +Custom_HW_Init(void *pCxt); +A_STATUS +Custom_HW_DeInit(void *pCxt);*/ + +void custom_os_usec_delay(uint32_t uSeconds); + +A_STATUS +Custom_Driver_CreateThread(void *pCxt); +A_STATUS +Custom_Driver_DestroyThread(void *pCxt); +A_STATUS +Custom_Driver_ContextInit(void *pCxt); +void Custom_Driver_ContextDeInit(void *pCxt); +void *Custom_GetRxRequest(void *pCxt, uint16_t length); +void Custom_DeliverFrameToNetworkStack(void *pCxt, void *pReq); +void Custom_Api_BssInfoEvent(void *pCxt, uint8_t *datap, int32_t len); +void Custom_Api_ConnectEvent(void *pCxt, uint8_t devId, uint16_t channel, uint8_t *bssid); +void Custom_Api_DisconnectEvent(void *pCxt, + uint8_t devId, + uint8_t reason, + uint8_t *bssid, + uint8_t assocRespLen, + uint8_t *assocInfo, + uint16_t protocolReasonStatus); +void Custom_Api_RSNASuccessEvent(void *pCxt, uint8_t devid, uint8_t code); +void Custom_Api_ReadyEvent(void *pCxt, uint8_t *datap, uint8_t phyCap, uint32_t sw_ver, uint32_t abi_ver); +void Custom_Api_BitRateEvent_tx(void *pCxt, uint8_t devId, int8_t rateIndex); +void Custom_Api_ProbeReq_Event(void *pCxt, uint8_t *datap, uint32_t len); +void Custom_Api_Wps_Init_Event(void *pCxt, uint8_t devid, uint8_t code); + +A_STATUS Custom_HW_Init(void *pCxt); +A_STATUS Custom_HW_DeInit(void *pCxt); + +void *Custom_Api_GetDriverCxt(uint8_t device_id); + +void Custom_Api_PfmDataEvent(void *wmip, uint8_t *datap, int32_t len); +void Custom_Api_PfmDataDoneEvent(void *wmip, uint8_t *datap, int32_t len); +void Custom_Api_Http_Post_Event(void *pCxt, uint8_t *datap); + +#define CUSTOM_API_WMIX_PFM_DATA_EVENT(wmip, datap, len) Custom_Api_PfmDataEvent((wmip), (datap), (len)) +#define CUSTOM_API_WMIX_PFM_DATA_DONE_EVENT(wmip, datap, len) Custom_Api_PfmDataDoneEvent((wmip), (datap), (len)) + +#if ENABLE_P2P_MODE +// void +// Custom_Api_wps_profile_event_rx(void *pCxt, uint8_t devId, uint8_t *datap, int32_t len, void *pReq); + +void Api_GpioDataEvent(void *wmip, uint8_t *datap, int32_t len); // IGX_UD_CHANGES + +#endif + +/* COMMON -> CUSTOM APIs :: These macros are used by common code to call into custom code. + * For a given system many of these will resolve to function calls however for some it + * may be appropriate to simply define them as A_OK. */ +#define CUSTOM_DELIVER_FRAME(pCxt, pReq) Custom_DeliverFrameToNetworkStack((pCxt), (pReq)) + +void Custom_Api_GpioDataEvent(void *wmip, uint8_t *datap, int32_t len); +#define CUSTOM_API_WMIX_GPIO_DATA_EVENT(wmip, datap, len) Custom_Api_GpioDataEvent((wmip), (datap), (len)) + +#define CUSTOM_API_BSS_INFO_EVENT(pCxt, datap, len) Custom_Api_BssInfoEvent((pCxt), (datap), (len)) + +#define CUSTOM_API_PROBEREQ_EVENT(pCxt, datap, len) Custom_Api_ProbeReq_Event((pCxt), (datap), (len)) + +#define CUSTOM_API_BITRATE_EVENT_TX(pCxt, devId, rateIndex) Custom_Api_BitRateEvent_tx((pCxt), (devId), (rateIndex)) +#define CUSTOM_API_CONNECT_EVENT(pCxt, devId, channel, bssid, c, d, e, f, g, h, i) \ + Custom_Api_ConnectEvent((pCxt), (devId), (channel), (bssid)) +#define CUSTOM_API_DISCONNECT_EVENT(pCxt, devId, a, b, c, d, e) \ + Custom_Api_DisconnectEvent((pCxt), (devId), (a), (b), (c), (d), (e)) +#define CUSTOM_API_RSNA_SUCCESS_EVENT(pCxt, devId, code) Custom_Api_RSNASuccessEvent((pCxt), (devId), (code)) + +#define CUSTOM_API_READY_EVENT(pCxt, datap, phyCap, sw_ver, abi_ver) \ + Custom_Api_ReadyEvent((pCxt), (datap), (phyCap), (sw_ver), (abi_ver)) + +//#define CUSTOM_HW_POWER_UP_DOWN(pCxt, powerup) Custom_HW_PowerUpDown((pCxt), (powerup)) +//#define CUSTOM_HW_INIT(pCxt) Custom_HW_Init((pCxt)) +//#define CUSTOM_HW_DEINIT(pCxt) Custom_HW_DeInit((pCxt)) + +#define CUSTOM_DRIVER_CXT_INIT(pCxt) Custom_Driver_ContextInit((pCxt)) +#define CUSTOM_DRIVER_CXT_DEINIT(pCxt) Custom_Driver_ContextDeInit((pCxt)) +#define CUSTOM_DRIVER_GET_RX_REQ(pCxt, l) Custom_GetRxRequest((pCxt), (l)) +#define CUSTOM_API_HTTP_POST_EVENT(pCxt, datap) Custom_Api_Http_Post_Event((pCxt), (datap)) +void Custom_Api_Ota_Resp_Result(void *pCxt, uint32_t cmd, uint32_t resp_code, uint32_t result); +int32_t Custom_Api_Dhcps_Success_Callback_Event(void *pCxt, uint8_t *datap); +int32_t Custom_Api_Dhcpc_Success_Callback_Event(void *pCxt, uint8_t *datap); + +#if ENABLE_P2P_MODE +//#define CUSTOM_API_WPS_PROFILE_EVENT_RX(pCxt, datap, len, pReq) Custom_Api_wps_profile_event_rx((pCxt), (datap), +//(len), (pReq)) +//#define CUSTOM_API_P2P_SAVE_WPS_CRED(pCxt) Custom_Api_p2p_save_wps_credentials((pCxt)) +#endif + +typedef void (*CUSTOM_HW_INTR_CB)(void *); + +void Custom_HW_InterruptHandler(CUSTOM_HW_INTR_CB pHcdCallback, void *pHcdContext); + +#endif /* _CUSTOM_API_H_ */ diff --git a/platform/mcu/lpc54102/wifi_qca/custom_src/include/wlan_config.h b/platform/mcu/lpc54102/wifi_qca/custom_src/include/wlan_config.h new file mode 100644 index 0000000000..ba1c327dbc --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/custom_src/include/wlan_config.h @@ -0,0 +1,158 @@ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== +#ifndef _HOST_WLAN_CONFIG_H_ +#define _HOST_WLAN_CONFIG_H_ + +/* Include definitions here that can be used to tune the WLAN module behavior. + * Different customers can tune the behavior as per their needs, here. + */ + +/* This configuration item when defined will consider the barker preamble + * mentioned in the ERP IE of the beacons from the AP to determine the short + * preamble support sent in the (Re)Assoc request frames. + */ +#define WLAN_CONFIG_DONOT_IGNORE_BARKER_IN_ERP 0 + +/* This config item when defined will not send the power module state transition + * failure events that happen during scan, to the host. + */ +#define WLAN_CONFIG_IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN 0 + +/* + * This configuration item enable/disable keepalive support. + * Keepalive support: In the absence of any data traffic to AP, null + * frames will be sent to the AP at periodic interval, to keep the association + * active. This configuration item defines the periodic interval. + * Use value of zero to disable keepalive support + * Default: 60 seconds + */ +#define WLAN_CONFIG_KEEP_ALIVE_INTERVAL 60 + +/* + * This configuration item disables 11n support. + * The wifi device will connect using 11g, 11b + * or 11a(if supported by chipset) only. + * The consequence of allowing + * 11n is that aggregate packets must be + * supported by the host which requires more + * RAM for received buffers. Because + * throughput will anyways be limited by the + * SPI interface 11n support will not provide + * greater throughput on slower host systems. However some + * access points can be configured for 11n only connections + * in which case disabling 11n would prevent the system from + * being able to connect to such AP's. + * 0 - Enable + * 1 - Disable + */ +#define WLAN_CONFIG_DISABLE_11N 0 + +/* + * This configuration is used to support 11N aggregation + * inside the driver. If aggregation is intended + * to be used then this must be set to 1. The code + * and RAM footprints for the driver will increase + * by enabling this feature. This feature can + * improve throughput performance if the RF is + * the throughput bottle-neck for the system. + * + */ +#define WLAN_CONFIG_11N_AGGR_SUPPORT 1 + +/* + * This configuration controls whether statistics + * from the wifi device are stored in the driver. + * This takes a fair amount of RAM and so should + * only be activated if needed. + */ +#define WLAN_CONFIG_CAPTURE_TARGET_STATS 0 + +/* + * This configuration controls whether the + * wifi driver accepts 802.11 frames from + * the stack. If 0 then 802.3 frames + * are required. + * ****** DO NOT ADJUST ****** + */ +#define WLAN_CONFIG_TX_DOT11_HDR 0 + +/* + * This configuration enables/disables internal + * driver stat tracking using the AR_SOFTC_T. + * Storage cost is ~100 bytes. + */ +#define WLAN_CONFIG_NET_STATS 0 + +/* + * This configuration reduces the number of + * virtual endpoints managed by the driver + * to what would be used if WMM were active + * rather than what the device is capable + * of supporting. enabling this configuration + * saves some RAM and reduces execution time + * modestly. + * ****** DO NOT ADJUST ****** + */ +#define WLAN_CONFIG_TRUNCATED_ENDPOINTS 1 + +/* + * This configuration enables/disables use + * of a GPIO to reset/power down the WiFi device. + * If this value is 0 then the wifi board should + * be configured (via jumpers) so that the PWD line + * is asserted low through some other appropriate + * method. + */ +#define WLAN_CONFIG_ENABLE_CHIP_PWD_GPIO 1 + +/* + * This configuration enable/disables use of + * WMI command synchronization. It is only + * needed if wmi commands which use a flag + * other than NO_SYNC_WMIFLAG are introduced. + * ****** DO NOT ADJUST ****** + */ +#define WLAN_CONFIG_ENABLE_WMI_SYNC 0 + +/* + * This configuration should be set to 1 when + * it is desired to allow AMSDU's to be sliced + * by the host system. This should only be + * enabled (set to 1) by Atheros. + * ****** DO NOT ADJUST ****** + */ +#define WLAN_CONFIG_AMSDU_ON_HOST 0 + +#define WLAN_CONFIG_REDUCE_CREDIT_DRIBBLE 1 + +#define WLAN_CONFIG_NUM_PRE_ALLOC_RX_BUFFERS 2 + +/* compile time test to ensure a valid 11N configuration */ +#if WLAN_CONFIG_DISABLE_11N +#if (WLAN_CONFIG_11N_AGGR_SUPPORT || WLAN_CONFIG_AMSDU_ON_HOST) +#error INVALID 11N COMPILE CONFIGURATION +#endif +#endif + +#endif /* _HOST_WLAN_CONFIG_H_ */ diff --git a/platform/mcu/lpc54102/wifi_qca/custom_src/qapi/custom_qcom_api.c b/platform/mcu/lpc54102/wifi_qca/custom_src/qapi/custom_qcom_api.c new file mode 100644 index 0000000000..8ff5de9796 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/custom_src/qapi/custom_qcom_api.c @@ -0,0 +1,204 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if ENABLE_P2P_MODE +#include +#include "p2p.h" +#endif +#include "atheros_wifi.h" +#include "atheros_wifi_api.h" +#include "atheros_wifi_internal.h" +#include "atheros_stack_offload.h" +#include "dset_api.h" +#include "common_stack_offload.h" +#include "qcom_api.h" +//------------------------------------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------------------------------------ + +extern uint32_t Custom_Api_Mediactl(QCA_CONTEXT_STRUCT_PTR qca_ptr, uint32_t command_id, void *inout_param); + +/*FUNCTION*----------------------------------------------------------------- +* +* Function Name : custom_qapi +* Returned Value : A_ERROR on error else A_OK +* Comments : Custom part of QAPI layer. This function will implement the +* custom portion of different QAPIs (OS specific). +* PORTING NOTE: Engineer should rewrite this function based on +* the OS framework. +*END------------------------------------------------------------------*/ +A_STATUS custom_qapi(uint8_t device_id, uint32_t cmd, void *param) +{ + uint32_t result; + //TODO: check param against NULL ! + switch (cmd) + { + case ATH_SET_SCAN: + result = Custom_Api_Mediactl(Custom_Api_GetDriverCxt(device_id), QCA_SET_MEDIACTL_SCAN, NULL); + return QCA_OK == result ? A_OK : A_ERROR; + case ATH_GET_SCAN_RESULTS: + { + QCA_SCAN_LIST scan_param; + if (Custom_Api_Mediactl(Custom_Api_GetDriverCxt(device_id), QCA_GET_MEDIACTL_SCAN, &scan_param) != A_OK) + { + return A_ERROR; + } + ((ATH_SCAN_LIST *)param)->scan_list = scan_param.scan_info_list; + ((ATH_SCAN_LIST *)param)->num_scan_entries = scan_param.num_scan_entries; + return A_OK; + } + case ATH_SET_SSID: + { + QCA_ESSID ssid_param; + char *pssid = ((ATH_IOCTL_PARAM_STRUCT *)param)->data; + + //NOTE: lower layer does not use 'ssid_param.flags' at all. The decision actually depends on 'ssid_param.length'. + //TODO: remove ssid_param.flags ?? + if (NULL == pssid) + { + ssid_param.flags = 0; + ssid_param.essid = pssid; + ssid_param.length = 0; + } + else + { + ssid_param.flags = 1; + ssid_param.essid = pssid; + ssid_param.length = strlen(pssid); + } + + result = Custom_Api_Mediactl(Custom_Api_GetDriverCxt(device_id), QCA_SET_MEDIACTL_ESSID, &ssid_param); + return QCA_OK == result ? A_OK : A_ERROR; + } + case ATH_GET_ESSID: + { + QCA_MEDIACTL_PARAM ssid_param; + ssid_param.data = ((ATH_IOCTL_PARAM_STRUCT *)param)->data; + if (Custom_Api_Mediactl(Custom_Api_GetDriverCxt(device_id), QCA_GET_MEDIACTL_ESSID, &ssid_param) != A_OK) + return A_ERROR; + + ((ATH_IOCTL_PARAM_STRUCT *)param)->length = ssid_param.length; + } + break; + case ATH_SET_COMMIT: + result = Custom_Api_Mediactl(Custom_Api_GetDriverCxt(device_id), QCA_SET_MEDIACTL_COMMIT, param); + return QCA_OK == result ? A_OK : A_ERROR; + case ATH_GET_POWER: + { + QCA_MEDIACTL_PARAM inout_param; + if (Custom_Api_Mediactl(Custom_Api_GetDriverCxt(device_id), QCA_GET_MEDIACTL_POWER, &inout_param) != A_OK) + { + return A_ERROR; + } + *(uint32_t *)param = inout_param.value; + return A_OK; + } + case ATH_SET_SEC_TYPE: + switch (*(uint32_t *)param) + { + case WLAN_AUTH_NONE: + *(uint32_t *)param = QCA_MEDIACTL_SECURITY_TYPE_NONE; + break; + case WLAN_AUTH_WPA_PSK: + *(uint32_t *)param = QCA_MEDIACTL_SECURITY_TYPE_WPA; + break; + case WLAN_AUTH_WPA2_PSK: + *(uint32_t *)param = QCA_MEDIACTL_SECURITY_TYPE_WPA2; + break; + case WLAN_AUTH_WEP: + *(uint32_t *)param = QCA_MEDIACTL_SECURITY_TYPE_WEP; + break; + default: + return (A_ERROR); + } + result = Custom_Api_Mediactl(Custom_Api_GetDriverCxt(device_id), QCA_SET_MEDIACTL_SEC_TYPE, param); + return QCA_OK == result ? A_OK : A_ERROR; + + case ATH_SET_OP_MODE: + if (*(uint32_t *)param == QCOM_WLAN_DEV_MODE_STATION) + { + *(uint32_t *)param = QCA_MEDIACTL_MODE_INFRA; + } + else if (*(uint32_t *)param == QCOM_WLAN_DEV_MODE_ADHOC) + { + *(uint32_t *)param = QCA_MEDIACTL_MODE_ADHOC; + } + else if (*(uint32_t *)param == QCOM_WLAN_DEV_MODE_AP) + { + *(uint32_t *)param = QCA_MEDIACTL_MODE_MASTER; + } + else + { + return A_ERROR; + } + result = Custom_Api_Mediactl(Custom_Api_GetDriverCxt(device_id), QCA_SET_MEDIACTL_MODE, param); + return QCA_OK == result ? A_OK : A_ERROR; + + case ATH_GET_OP_MODE: + if (Custom_Api_Mediactl(Custom_Api_GetDriverCxt(device_id), QCA_GET_MEDIACTL_MODE, param) != A_OK) + { + return A_ERROR; + } + + switch (*(uint32_t *)param) + { + case QCA_MEDIACTL_MODE_INFRA: + *(uint32_t *)param = QCOM_WLAN_DEV_MODE_STATION; + break; + case QCA_MEDIACTL_MODE_ADHOC: + *(uint32_t *)param = QCOM_WLAN_DEV_MODE_ADHOC; + break; + case QCA_MEDIACTL_MODE_MASTER: + *(uint32_t *)param = QCOM_WLAN_DEV_MODE_AP; + break; + default: + break; + } + break; + case ATH_SET_PASSPHRASE: + { + QCA_MEDIACTL_PARAM enet_param; + enet_param.data = ((ATH_IOCTL_PARAM_STRUCT *)param)->data; + enet_param.length = ((ATH_IOCTL_PARAM_STRUCT *)param)->length; + result = Custom_Api_Mediactl(Custom_Api_GetDriverCxt(device_id), QCA_SET_MEDIACTL_PASSPHRASE, &enet_param); + return QCA_OK == result ? A_OK : A_ERROR; + } + default: + result = Custom_Api_Mediactl(Custom_Api_GetDriverCxt(device_id), QCA_MEDIACTL_VENDOR_SPECIFIC, param); + return QCA_OK == result ? A_OK : A_ERROR; + } + return A_OK; +} diff --git a/platform/mcu/lpc54102/wifi_qca/custom_src/stack_custom/cust_api_stack_offload.c b/platform/mcu/lpc54102/wifi_qca/custom_src/stack_custom/cust_api_stack_offload.c new file mode 100644 index 0000000000..8cfb7c00a4 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/custom_src/stack_custom/cust_api_stack_offload.c @@ -0,0 +1,2189 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 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 +#include +#include +#include +#include +#include "atheros_wifi.h" +#include "atheros_wifi_api.h" +#include "atheros_wifi_internal.h" +#include "cust_netbuf.h" + +#if ENABLE_STACK_OFFLOAD +#include "atheros_stack_offload.h" +#include "common_stack_offload.h" +#include "custom_stack_offload.h" + +#if ZERO_COPY +A_NETBUF_QUEUE_T zero_copy_free_queue; +#endif + +#if ENABLE_SSL +extern void *sslhandle; +int32_t find_socket_context_from_ssl(SSL *ssl); +#endif + +#define DEFAULT_DNS_TIMEOUT 25000 /* 25 seconds */ +uint32_t dns_block_time = DEFAULT_DNS_TIMEOUT; +uint32_t (*dhcps_success_callback)(uint8_t *mac, uint32_t ip) = NULL; +uint32_t (*dhcpc_success_callback)(uint32_t ip, uint32_t mask, uint32_t gw) = NULL; + +/*****************************************************************************/ +/* t_socket - Custom version of socket API- please see Api_socket for details + * RETURNS: socket handle or A_ERROR + *****************************************************************************/ +int32_t t_socket(QCA_CONTEXT_STRUCT_PTR qca_ptr, uint32_t domain, uint32_t type, uint32_t protocol) +{ + void *pCxt; + + if ((pCxt = qca_ptr->MAC_CONTEXT_PTR) == NULL) + { + return A_ERROR; + } + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + + return (Api_socket(pCxt, domain, type, protocol)); +} + +/*****************************************************************************/ +/* t_shutdown - Custom version of socket shutdown API- please see Api_shutdown for details + * RETURNS: A_OK or A_ERROR + *****************************************************************************/ +int32_t t_shutdown(QCA_CONTEXT_STRUCT_PTR qca_ptr, uint32_t handle) +{ + void *pCxt; + + if ((pCxt = qca_ptr->MAC_CONTEXT_PTR) == NULL) + { + return A_ERROR; + } + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + + return (Api_shutdown(pCxt, handle)); +} + +/*****************************************************************************/ +/* t_connect - Custom version of socket connect API- please see Api_connect for details + * RETURNS: A_OK or A_ERROR + *****************************************************************************/ +int32_t t_connect(QCA_CONTEXT_STRUCT_PTR qca_ptr, uint32_t handle, void *name, uint16_t length) +{ + void *pCxt; + + if ((pCxt = qca_ptr->MAC_CONTEXT_PTR) == NULL) + { + return A_ERROR; + } + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + + return (Api_connect(pCxt, handle, name, length)); +} + +/*****************************************************************************/ +/* t_bind - Custom version of socket bind API- please see Api_bind for details + * RETURNS: A_OK or A_ERROR + *****************************************************************************/ +int32_t t_bind(QCA_CONTEXT_STRUCT_PTR qca_ptr, uint32_t handle, void *name, uint16_t length) +{ + void *pCxt; + + if ((pCxt = qca_ptr->MAC_CONTEXT_PTR) == NULL) + { + return A_ERROR; + } + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + + return (Api_bind(pCxt, handle, name, length)); +} + +/*****************************************************************************/ +/* t_listen - Custom version of socket listen API- please see Api_listen for details + * RETURNS: A_OK or A_ERROR + *****************************************************************************/ +int32_t t_listen(QCA_CONTEXT_STRUCT_PTR qca_ptr, uint32_t handle, uint32_t backlog) +{ + void *pCxt; + + if ((pCxt = qca_ptr->MAC_CONTEXT_PTR) == NULL) + { + return A_ERROR; + } + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + + return (Api_listen(pCxt, handle, backlog)); +} + +/*****************************************************************************/ +/* t_accept - Custom version of socket accept API- please see Api_accept for details + * RETURNS: A_OK or A_ERROR + *****************************************************************************/ +int32_t t_accept(QCA_CONTEXT_STRUCT_PTR qca_ptr, uint32_t handle, void *name, socklen_t length) +{ + void *pCxt; + + if ((pCxt = qca_ptr->MAC_CONTEXT_PTR) == NULL) + { + return A_ERROR; + } + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + return (Api_accept(pCxt, handle, name, length)); +} + +#if T_SELECT_VER1 +int32_t t_accept_nb(QCA_CONTEXT_STRUCT_PTR qca_ptr, uint32_t handle, void *name, socklen_t length) +{ + void *pCxt; + + if ((pCxt = qca_ptr->MAC_CONTEXT_PTR) == NULL) + { + return A_ERROR; + } + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + + return (Api_accept_ver1(pCxt, handle, name, length)); +} + +int32_t t_select_ver1( + QCA_CONTEXT_STRUCT_PTR qca_ptr, int32_t num, uint32_t *r_fd, uint32_t *w_fd, uint32_t *e_fd, uint32_t tv) +{ + void *pCxt; + + if ((pCxt = qca_ptr->MAC_CONTEXT_PTR) == NULL) + { + return A_ERROR; + } + + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_RX)) + { + return A_ERROR; + } + + return (Api_select_ver1(pCxt, num, r_fd, w_fd, e_fd, tv)); +} + +#endif + +/*****************************************************************************/ +/* t_select - Custom version of socket select API- please see Api_select for details + * RETURNS: A_OK or A_ERROR + *****************************************************************************/ +int32_t t_select(QCA_CONTEXT_STRUCT_PTR qca_ptr, uint32_t handle, uint32_t tv) +{ + void *pCxt; + + if ((pCxt = qca_ptr->MAC_CONTEXT_PTR) == NULL) + { + return A_ERROR; + } + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_RX)) + { + return A_ERROR; + } + + return (Api_select(pCxt, handle, tv)); +} + +/*****************************************************************************/ +/* t_errno - Custom version of socket errno API- please see Api_errno for details + * RETURNS: A_OK or A_ERROR + *****************************************************************************/ +int32_t t_errno(QCA_CONTEXT_STRUCT_PTR qca_ptr, uint32_t handle) +{ + void *pCxt; + + if ((pCxt = qca_ptr->MAC_CONTEXT_PTR) == NULL) + { + return A_ERROR; + } + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + + return (Api_errno(pCxt, handle)); +} + +/*****************************************************************************/ +/* t_setsockopt - Custom version of socket setsockopt API- please see Api_setsockopt for details + * RETURNS: A_OK or A_ERROR + *****************************************************************************/ +int32_t t_setsockopt( + QCA_CONTEXT_STRUCT_PTR qca_ptr, uint32_t handle, uint32_t level, uint32_t optname, uint8_t *optval, uint32_t optlen) +{ + void *pCxt; + + if ((pCxt = qca_ptr->MAC_CONTEXT_PTR) == NULL) + { + return A_ERROR; + } + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + + return (Api_setsockopt(pCxt, handle, level, optname, optval, optlen)); +} + +/*****************************************************************************/ +/* t_getsockopt - Custom version of socket getsockopt API- please see + * Api_getsockopt for details. + * RETURNS: A_OK or A_ERROR + *****************************************************************************/ +int32_t t_getsockopt( + QCA_CONTEXT_STRUCT_PTR qca_ptr, uint32_t handle, uint32_t level, uint32_t optname, uint8_t *optval, uint32_t optlen) +{ + void *pCxt; + + if ((pCxt = qca_ptr->MAC_CONTEXT_PTR) == NULL) + { + return A_ERROR; + } + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + + return (Api_getsockopt(pCxt, handle, level, optname, optval, optlen)); +} + +/*****************************************************************************/ +/* t_ipconfig - Custom version of ipconfig API- please see + * Api_ipconfig for details. + * RETURNS: A_OK or A_ERROR + *****************************************************************************/ +// int32_t t_ipconfig(QCA_CONTEXT_STRUCT_PTR qca_ptr, uint32_t mode,uint32_t* ipv4_addr, uint32_t* subnetMask, uint32_t* +// gateway4) +A_STATUS t_ipconfig(void *handle, + uint32_t mode, + uint32_t *ipv4_addr, + uint32_t *subnetMask, + uint32_t *gateway4, + IP46ADDR *dnsaddr, + char *hostname) +{ + void *pCxt = ((QCA_CONTEXT_STRUCT_PTR)handle)->MAC_CONTEXT_PTR; + int32_t result; + + if (pCxt == NULL) + { + return A_ERROR; + } + + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + + result = Api_ipconfig(pCxt, mode, ipv4_addr, subnetMask, gateway4, dnsaddr, hostname); + return result == 0 ? A_OK : A_ERROR; +} + +/*****************************************************************************/ +/* t_ip6config - Custom version of ipconfig API- please see + * Api_ip6config for details. + * RETURNS: A_OK or A_ERROR + *****************************************************************************/ +A_STATUS t_ip6config(QCA_CONTEXT_STRUCT_PTR qca_ptr, + uint32_t mode, + IP6_ADDR_T *v6Global, + IP6_ADDR_T *v6Local, + IP6_ADDR_T *v6DefGw, + IP6_ADDR_T *v6GlobalExtd, + int32_t *LinkPrefix, + int32_t *GlbPrefix, + int32_t *DefGwPrefix, + int32_t *GlbPrefixExtd) +{ + void *pCxt; + int32_t result; + + if ((pCxt = qca_ptr->MAC_CONTEXT_PTR) == NULL) + { + return A_ERROR; + } + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + + result = Api_ip6config(pCxt, mode, v6Global, v6Local, v6DefGw, v6GlobalExtd, LinkPrefix, GlbPrefix, DefGwPrefix, + GlbPrefixExtd); + return 0 == result ? A_OK : A_ERROR; +} + +/*****************************************************************************/ +/* t_ipconfig_dhcp_pool - Function to create DHCP Pool + * RETURNS: A_OK or A_ERROR + *****************************************************************************/ +int32_t t_ipconfig_dhcp_pool(QCA_CONTEXT_STRUCT_PTR qca_ptr, + uint32_t *start_ipv4_addr, + uint32_t *end_ipv4_addr, + int32_t leasetime) +{ + void *pCxt; + + if ((pCxt = qca_ptr->MAC_CONTEXT_PTR) == NULL) + { + return A_ERROR; + } + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + + return (Api_ipconfig_dhcp_pool(pCxt, start_ipv4_addr, end_ipv4_addr, leasetime)); +} + +/*****************************************************************************/ +/* t_ipconfig_dhcps_cb_enable - Function to register DHCP Server Callback + Callback is invoked with the client MAC Addr + and the IP address assigned + * RETURNS: A_OK or A_ERROR + *****************************************************************************/ +int32_t t_ipconfig_dhcps_cb_enable(QCA_CONTEXT_STRUCT_PTR qca_ptr, void *callback) +{ + if (qca_ptr->MAC_CONTEXT_PTR == NULL) + { + return A_ERROR; + } + /*Register the dhcp callback*/ + dhcps_success_callback = (uint32_t (*)(uint8_t *, uint32_t))callback; + return A_OK; +} + +/*****************************************************************************/ +/* t_ipconfig_dhcpc_cb_enable - Function to register DHCP Client Callback + Callback is invoked with the client's IP, + Mask and the Gateway Address + * RETURNS: A_OK or A_ERROR + *****************************************************************************/ +int32_t t_ipconfig_dhcpc_cb_enable(QCA_CONTEXT_STRUCT_PTR qca_ptr, void *callback) +{ + if (qca_ptr->MAC_CONTEXT_PTR == NULL) + { + return A_ERROR; + } + /*Register the dhcp callback*/ + dhcpc_success_callback = (uint32_t (*)(uint32_t, uint32_t, uint32_t))callback; + return A_OK; +} + +A_STATUS t_ip6config_router_prefix( + QCA_CONTEXT_STRUCT_PTR qca_ptr, IP6_ADDR_T *v6addr, int32_t prefixlen, int32_t prefix_lifetime, int32_t valid_lifetime) +{ + void *pCxt; + int32_t result; + + if ((pCxt = qca_ptr->MAC_CONTEXT_PTR) == NULL) + { + return A_ERROR; + } + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + + result = Api_ip6config_router_prefix(pCxt, v6addr, prefixlen, prefix_lifetime, valid_lifetime); + return 0 == result ? A_OK : A_ERROR; +} + +/*****************************************************************************/ +/* custom_ipbridgemode - Custom version of bridgemode API- please see + * Api_ipbridgemode for details. + * RETURNS: A_OK or A_ERROR + *****************************************************************************/ +A_STATUS custom_ipbridgemode(void *handle, uint16_t status) +{ + void *pCxt = ((QCA_CONTEXT_STRUCT_PTR)handle)->MAC_CONTEXT_PTR; + int32_t result; + + if (pCxt == NULL) + { + return A_ERROR; + } + + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + + result = Api_ipbridgemode(pCxt, status); + return 0 == result ? A_OK : A_ERROR; +} + +A_STATUS custom_ipconfig_set_tcp_exponential_backoff_retry(QCA_CONTEXT_STRUCT_PTR qca_ptr, int32_t retry) +{ + void *pCxt; + int32_t result; + + if ((pCxt = qca_ptr->MAC_CONTEXT_PTR) == NULL) + { + return A_ERROR; + } + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + + result = Api_ipconfig_set_tcp_exponential_backoff_retry(pCxt, retry); + return 0 == result ? A_OK : A_ERROR; +} + +int32_t custom_ipconfig_set_ip6_status(QCA_CONTEXT_STRUCT_PTR qca_ptr, uint16_t status) +{ + void *pCxt; + + if ((pCxt = qca_ptr->MAC_CONTEXT_PTR) == NULL) + { + return A_ERROR; + } + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + return (Api_ipconfig_set_ip6_status(pCxt, status)); +} + +A_STATUS custom_ipconfig_dhcp_release(QCA_CONTEXT_STRUCT_PTR qca_ptr) +{ + void *pCxt; + int32_t result; + + if ((pCxt = qca_ptr->MAC_CONTEXT_PTR) == NULL) + { + return A_ERROR; + } + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + + result = Api_ipconfig_dhcp_release(pCxt); + return 0 == result ? A_OK : A_ERROR; +} +int32_t Custom_Api_Dhcps_Success_Callback_Event(void *pCxt, uint8_t *datap) +{ + SOCK_DHCPS_SUCCESS_CALLBACK_T *dhcps_cb_info = (SOCK_DHCPS_SUCCESS_CALLBACK_T *)datap; + if (dhcps_success_callback) + { + dhcps_success_callback(dhcps_cb_info->mac, dhcps_cb_info->ip); + } + return A_OK; +} + +int32_t Custom_Api_Dhcpc_Success_Callback_Event(void *pCxt, uint8_t *datap) +{ + SOCK_DHCPC_SUCCESS_CALLBACK_T *dhcpc_cb_info = (SOCK_DHCPC_SUCCESS_CALLBACK_T *)datap; + if (dhcpc_success_callback) + { + dhcpc_success_callback(dhcpc_cb_info->ip, dhcpc_cb_info->mask, dhcpc_cb_info->gw); + } + return A_OK; +} + +A_STATUS custom_ipconfig_set_tcp_rx_buffer(QCA_CONTEXT_STRUCT_PTR qca_ptr, int32_t rxbuf) +{ + void *pCxt; + int32_t result; + + if ((pCxt = qca_ptr->MAC_CONTEXT_PTR) == NULL) + { + return A_ERROR; + } + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + + result = Api_ipconfig_set_tcp_rx_buffer(pCxt, rxbuf); + return 0 == result ? A_OK : A_ERROR; +} + +#if ENABLE_HTTP_SERVER +A_STATUS custom_ip_http_server(void *handle, int32_t command) +{ + int32_t result; +#if 0 /* keviny */ + void *pCxt = handle; +#else + void *pCxt = ((QCA_CONTEXT_STRUCT_PTR)handle)->MAC_CONTEXT_PTR; +#endif + + if (pCxt == NULL) + { + return A_ERROR; + } + + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + + result = Api_ip_http_server(pCxt, command); + return 0 == result ? A_OK : A_ERROR; +} + +A_STATUS custom_ip_http_server_method( + void *handle, int32_t command, uint8_t *pagename, uint8_t *objname, int32_t objtype, int32_t objlen, uint8_t *value) +{ + int32_t result; +#if 0 /* keviny */ + void *pCxt = handle; +#else + void *pCxt = ((QCA_CONTEXT_STRUCT_PTR)handle)->MAC_CONTEXT_PTR; +#endif + + if (pCxt == NULL) + { + return A_ERROR; + } + + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + + result = Api_ip_http_server_method(pCxt, command, pagename, objname, objtype, objlen, value); + return 0 == result ? A_OK : A_ERROR; +} + +void Custom_Api_Http_Post_Event(void *pCxt, uint8_t *datap) +{ + WMI_HTTP_POST_EVENT_CB cb = NULL; + + DRIVER_SHARED_RESOURCE_ACCESS_ACQUIRE(pCxt); + + cb = (WMI_HTTP_POST_EVENT_CB)(GET_DRIVER_CXT(pCxt)->httpPostCb); + + DRIVER_SHARED_RESOURCE_ACCESS_RELEASE(pCxt); + + if (cb) + { + cb(GET_DRIVER_CXT(pCxt)->httpPostCbCxt, (void *)datap); + } +} + +int32_t custom_http_set_post_cb(void *handle, void *cxt, void *callback) +{ + void *pCxt = ((QCA_CONTEXT_STRUCT_PTR)handle)->MAC_CONTEXT_PTR; + + GET_DRIVER_CXT(pCxt)->httpPostCb = callback; + GET_DRIVER_CXT(pCxt)->httpPostCbCxt = cxt; + return A_OK; +} +#endif + +#if ENABLE_HTTP_CLIENT + +/*****************************************************************************/ +/* cust_httpc_method - Custom version of httpc API- please see Api_httpc_connect for details +* RETURNS: A_OK or A_ERROR +*****************************************************************************/ +A_STATUS custom_httpc_method(void *handle, uint32_t command, uint8_t *url, uint8_t *data, uint8_t **output) +{ + void *pCxt = ((QCA_CONTEXT_STRUCT_PTR)handle)->MAC_CONTEXT_PTR; + int32_t result; + + if (pCxt == NULL) + { + return A_ERROR; + } + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + + result = Api_httpc_method(pCxt, command, url, data, output); + return 0 == result ? A_OK : A_ERROR; +} + +/*****************************************************************************/ +/* zero_copy_http_free - ZERO_COPY free API.It will find and remove rx buffer + * for HTTP client. + * RETURNS: Nothing + *****************************************************************************/ +void zero_copy_http_free(void *buffer) +{ + uint32_t *length; + + length = (uint32_t *)buffer; + buffer = (void *)(length - 3); + // printf("Deleting from Q %p\n", buffer); + zero_copy_free(buffer); +} +#endif /* ENABLE_HTTP_CLIENT */ + +int32_t custom_ip_hostname(void *handle, char *domain_name) +{ + void *pCxt = ((QCA_CONTEXT_STRUCT_PTR)handle)->MAC_CONTEXT_PTR; + + if (pCxt == NULL) + { + return A_ERROR; + } + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + return (Api_ip_hostname(pCxt, domain_name)); +} + +#if ENABLE_DNS_SERVER +int32_t custom_ip_dns_local_domain(void *handle, char *domain_name) +{ + void *pCxt = ((QCA_CONTEXT_STRUCT_PTR)handle)->MAC_CONTEXT_PTR; + if (pCxt == NULL) + { + return A_ERROR; + } + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + return (Api_ip_dns_local_domain(pCxt, domain_name)); +} + +int32_t custom_ipdns(void *handle, int32_t command, char *domain_name, IP46ADDR *dnsaddr) +{ + void *pCxt = ((QCA_CONTEXT_STRUCT_PTR)handle)->MAC_CONTEXT_PTR; + + if (pCxt == NULL) + { + return A_ERROR; + } + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + return (Api_ipdns(pCxt, command, domain_name, dnsaddr)); +} + +int32_t custom_ip_dns_server(void *handle, uint32_t command) +{ + void *pCxt = ((QCA_CONTEXT_STRUCT_PTR)handle)->MAC_CONTEXT_PTR; + if (pCxt == NULL) + { + return A_ERROR; + } + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + + return (Api_ip_dns_server(pCxt, command)); +} + +#endif /* ENABLE_DNS_SERVER */ + +#if ENABLE_DNS_CLIENT +int32_t custom_ip_set_dns_block_time(void *handle, int32_t blockSec) +{ + if (blockSec <= 0) + { + dns_block_time = DEFAULT_DNS_TIMEOUT; + } + else + { + dns_block_time = (blockSec > 0xFF ? 0xFF : blockSec) * 1000; + } + return A_OK; +} + +int32_t custom_ip_resolve_hostname(void *handle, DNC_CFG_CMD *DncCfg, DNC_RESP_INFO *DncRespInfo) +{ + void *pCxt = ((QCA_CONTEXT_STRUCT_PTR)handle)->MAC_CONTEXT_PTR; + + if (pCxt == NULL) + { + return A_ERROR; + } + + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + return (Api_ip_resolve_host_name(pCxt, DncCfg, DncRespInfo)); +} + +int32_t custom_ip_dns_server_addr(void *handle, IP46ADDR *addr) +{ + void *pCxt = ((QCA_CONTEXT_STRUCT_PTR)handle)->MAC_CONTEXT_PTR; + if (pCxt == NULL) + { + return A_ERROR; + } + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + return (Api_ip_dns_server_addr(pCxt, addr)); +} + +int32_t custom_ip_dns_client(void *handle, int32_t command) +{ + void *pCxt = ((QCA_CONTEXT_STRUCT_PTR)handle)->MAC_CONTEXT_PTR; + + if (pCxt == NULL) + { + return A_ERROR; + } + + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + return (Api_ip_dns_client(pCxt, command)); +} +#endif /* ENABLE_DNS_CLIENT */ + +#if ENABLE_SNTP_CLIENT +int32_t custom_ip_sntp_srvr_addr(void *handle, int32_t command, char *sntp_srvr_addr) +{ + void *pCxt = ((QCA_CONTEXT_STRUCT_PTR)handle)->MAC_CONTEXT_PTR; + + if (pCxt == NULL) + { + return A_ERROR; + } + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + return (Api_ip_sntp_srvr_addr(pCxt, command, sntp_srvr_addr)); +} + +int32_t custom_ip_sntp_get_time(void *handle, tSntpTime *SntpTime) +{ + void *pCxt = ((QCA_CONTEXT_STRUCT_PTR)handle)->MAC_CONTEXT_PTR; + + if (pCxt == NULL) + { + return A_ERROR; + } + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + return (Api_ip_sntp_get_time(pCxt, SntpTime)); +} +int32_t custom_ip_sntp_get_time_of_day(void *handle, tSntpTM *SntpTm) +{ + void *pCxt = ((QCA_CONTEXT_STRUCT_PTR)handle)->MAC_CONTEXT_PTR; + + if (pCxt == NULL) + { + return A_ERROR; + } + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + return (Api_ip_sntp_get_time_of_day(pCxt, SntpTm)); +} +int32_t custom_ip_sntp_modify_zone_dse(void *handle, uint8_t hour, uint8_t min, uint8_t add_sub, uint8_t dse) +{ + void *pCxt = ((QCA_CONTEXT_STRUCT_PTR)handle)->MAC_CONTEXT_PTR; + + if (pCxt == NULL) + { + return A_ERROR; + } + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + return (Api_ip_sntp_modify_zone_dse(pCxt, hour, min, add_sub, dse)); +} + +int32_t custom_ip_sntp_query_srvr_address(void *handle, tSntpDnsAddr SntpDnsAddr[MAX_SNTP_SERVERS]) +{ + void *pCxt = ((QCA_CONTEXT_STRUCT_PTR)handle)->MAC_CONTEXT_PTR; + + if (pCxt == NULL) + { + return A_ERROR; + } + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + return (Api_ip_sntp_query_srvr_address(pCxt, SntpDnsAddr)); +} + +int32_t custom_ip_sntp_client(void *handle, int32_t command) +{ + void *pCxt = ((QCA_CONTEXT_STRUCT_PTR)handle)->MAC_CONTEXT_PTR; + + if (pCxt == NULL) + { + return A_ERROR; + } + + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + return (Api_ip_sntp_client(pCxt, command)); +} +#endif /* ENABLE_SNTP_CLIENT */ + +#if ENABLE_ROUTING_CMDS +A_STATUS custom_ipv4_route(void *handle, + uint32_t command, + IP_ADDR_T *ipv4_addr, + IP_ADDR_T *subnetMask, + IP_ADDR_T *gateway, + uint32_t *ifIndex, + IPV4_ROUTE_LIST_T *routelist) +{ + void *pCxt = ((QCA_CONTEXT_STRUCT_PTR)handle)->MAC_CONTEXT_PTR; + int32_t result; + + if (pCxt == NULL) + { + return A_ERROR; + } + + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + + result = Api_ipv4_route(pCxt, command, ipv4_addr, subnetMask, gateway, ifIndex, routelist); + return 0 == result ? A_OK : A_ERROR; +} + +A_STATUS custom_ipv6_route(void *handle, + uint32_t command, + IP6_ADDR_T *ipv6_addr, + uint32_t *prefixLen, + IP6_ADDR_T *gateway, + uint32_t *ifIndex, + IPV6_ROUTE_LIST_T *routelist) +{ + void *pCxt = ((QCA_CONTEXT_STRUCT_PTR)handle)->MAC_CONTEXT_PTR; + int32_t result; + + if (pCxt == NULL) + { + return A_ERROR; + } + + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + + result = Api_ipv6_route(pCxt, command, ipv6_addr, prefixLen, gateway, ifIndex, routelist); + return 0 == result ? A_OK : A_ERROR; +} +#endif /* ENABLE_ROUTING_CMDS */ +A_STATUS custom_tcp_connection_timeout(void *handle, uint32_t timeout_val) +{ + void *pCxt = ((QCA_CONTEXT_STRUCT_PTR)handle)->MAC_CONTEXT_PTR; + int32_t result; + + if (pCxt == NULL) + { + return A_ERROR; + } + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + + result = Api_tcp_connection_timeout(pCxt, timeout_val); + return 0 == result ? A_OK : A_ERROR; +} +int32_t custom_ota_upgrade(void *handle, + uint32_t addr, + char *filename, + uint8_t mode, + uint8_t preserve_last, + uint8_t protocol, + uint32_t *resp_code, + uint32_t *ret_len) +{ + void *pCxt = ((QCA_CONTEXT_STRUCT_PTR)handle)->MAC_CONTEXT_PTR; + + if (pCxt == NULL) + { + return A_ERROR; + } + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + + return (Api_ota_upgrade(pCxt, addr, filename, mode, preserve_last, protocol, resp_code, ret_len)); +} +int32_t custom_ota_read_area(void *handle, uint32_t offset, uint32_t size, uint8_t *buffer, uint32_t *ret_len) +{ + void *pCxt = ((QCA_CONTEXT_STRUCT_PTR)handle)->MAC_CONTEXT_PTR; + + if (pCxt == NULL) + { + return A_ERROR; + } + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + + return (Api_ota_read_area(pCxt, offset, size, buffer, ret_len)); +} + +int32_t custom_ota_done(void *handle, boolean good_image) +{ + void *pCxt = ((QCA_CONTEXT_STRUCT_PTR)handle)->MAC_CONTEXT_PTR; + + if (pCxt == NULL) + { + return A_ERROR; + } + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + + return (Api_ota_done(pCxt, good_image)); +} + +int32_t custom_ota_session_start(void *handle, uint32_t flags, uint32_t partition_index) +{ + void *pCxt = ((QCA_CONTEXT_STRUCT_PTR)handle)->MAC_CONTEXT_PTR; + + if (pCxt == NULL) + { + return A_ERROR; + } + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + + return (Api_ota_session_start(pCxt, flags, partition_index)); +} + +uint32_t custom_ota_partition_get_size(void *handle) +{ + void *pCxt = ((QCA_CONTEXT_STRUCT_PTR)handle)->MAC_CONTEXT_PTR; + + if (pCxt == NULL) + { + return 0; + } + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return 0; + } + + return (Api_ota_partition_get_size(pCxt)); +} + +int32_t custom_ota_partition_erase(void *handle) +{ + void *pCxt = ((QCA_CONTEXT_STRUCT_PTR)handle)->MAC_CONTEXT_PTR; + + if (pCxt == NULL) + { + return A_ERROR; + } + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + + return (Api_ota_partition_erase(pCxt)); +} + +int32_t custom_ota_partition_verify_checksum(void *handle) +{ + void *pCxt = ((QCA_CONTEXT_STRUCT_PTR)handle)->MAC_CONTEXT_PTR; + + if (pCxt == NULL) + { + return A_ERROR; + } + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + + return (Api_ota_partition_verify_checksum(pCxt)); +} + +int32_t custom_ota_parse_image_hdr(void *handle, uint8_t *header, uint32_t *offset) +{ + void *pCxt = ((QCA_CONTEXT_STRUCT_PTR)handle)->MAC_CONTEXT_PTR; + + if (pCxt == NULL) + { + return A_ERROR; + } + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + + return (Api_ota_parse_image_hdr(pCxt, header, offset)); +} + +int32_t custom_ota_partition_write_data(void *handle, uint32_t offset, uint8_t *buf, uint32_t size, uint32_t *ret_size) +{ + void *pCxt = ((QCA_CONTEXT_STRUCT_PTR)handle)->MAC_CONTEXT_PTR; + + if (pCxt == NULL) + { + return 0; + } + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return 0; + } + + return (Api_ota_partition_write_data(pCxt, offset, buf, size, ret_size)); +} + +int32_t custom_ota_set_response_cb(void *handle, void *callback) +{ + void *pCxt = ((QCA_CONTEXT_STRUCT_PTR)handle)->MAC_CONTEXT_PTR; + + GET_DRIVER_CXT(pCxt)->otaCB = callback; + return A_OK; +} + +void Custom_Api_Ota_Resp_Result(void *pCxt, uint32_t cmd, uint32_t resp_code, uint32_t result) +{ + ATH_OTA_CB cb = NULL; + DRIVER_SHARED_RESOURCE_ACCESS_ACQUIRE(pCxt); + cb = (ATH_OTA_CB)(GET_DRIVER_CXT(pCxt)->otaCB); + DRIVER_SHARED_RESOURCE_ACCESS_RELEASE(pCxt); + + if (cb) + { + cb(cmd, resp_code, result); + } +} + +/*****************************************************************************/ +/* t_ping - Custom version of ping API- please see + * Api_ping for details. + * RETURNS: A_OK or A_ERROR + *****************************************************************************/ +A_STATUS t_ping(QCA_CONTEXT_STRUCT_PTR qca_ptr, uint32_t ipv4_addr, uint32_t size) +{ + void *pCxt; + int32_t result; + + if ((pCxt = qca_ptr->MAC_CONTEXT_PTR) == NULL) + { + return A_ERROR; + } + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + + result = Api_ping(pCxt, ipv4_addr, size); + return result == 0 ? A_OK : A_ERROR; +} + +/*****************************************************************************/ +/* t_ping6 - Custom version of ping API- please see + * Api_ping6 for details. + * RETURNS: A_OK or A_ERROR + *****************************************************************************/ +A_STATUS t_ping6(QCA_CONTEXT_STRUCT_PTR qca_ptr, uint8_t *ip6addr, uint32_t size) +{ + void *pCxt; + int32_t result; + + if ((pCxt = qca_ptr->MAC_CONTEXT_PTR) == NULL) + { + return A_ERROR; + } + + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + + result = Api_ping6(pCxt, ip6addr, size); + return 0 == result ? A_OK : A_ERROR; +} + +/*****************************************************************************/ +/* t_send - Custom version of socket send API. Used for stream based sockets. + * Sends provided buffer to target. + * RETURNS: Number of bytes sent to target + *****************************************************************************/ +int32_t t_send(QCA_CONTEXT_STRUCT_PTR qca_ptr, uint32_t handle, uint8_t *buffer, uint32_t length, uint32_t flags) +{ + int32_t index; + + /*Find socket context*/ + if((index = find_socket_context(handle, true)) == SOCKET_NOT_FOUND) + { + last_driver_error = A_SOCKCXT_NOT_FOUND; + return A_SOCK_INVALID; + } + + if( ath_sock_context[index]->TCPCtrFlag == TCP_FIN ) + { + last_driver_error = A_SOCKCXT_NOT_FOUND; + return A_SOCK_INVALID; + } + + return (t_sendto(qca_ptr, handle, buffer, length, flags, NULL, 0)); +} + +/*****************************************************************************/ +/* t_sendto - Custom version of socket send API. Used for datagram sockets. + * Sends provided buffer to target. Creates space for headroom at + * the begining of the packet. The headroom is used by the stack to + * fill in the TCP-IP header. + * RETURNS: Number of bytes sent to target + *****************************************************************************/ +int32_t t_sendto(QCA_CONTEXT_STRUCT_PTR qca_ptr, + uint32_t handle, + uint8_t *buffer, + uint32_t length, + uint32_t flags, + void *name, + uint32_t socklength) +{ + uint8_t custom_hdr[TCP6_HEADROOM]; + int32_t index = 0; + uint16_t custom_hdr_length = 0; + DRV_BUFFER_PTR db_ptr; + uint16_t hdr_length = sizeof(ATH_MAC_HDR); + uint8_t *hdr = NULL, *bufPtr = buffer; + void *pCxt; +#if NON_BLOCKING_TX + SOCKET_CONTEXT_PTR pcustctxt; +#endif + int32_t result = 0; + A_STATUS status = A_OK; + uint16_t rem_len = length; + uint16_t offset = 0; + + if ((pCxt = qca_ptr->MAC_CONTEXT_PTR) == NULL) + { + return A_ERROR; + } + + /*Find socket context*/ + if ((index = find_socket_context(handle, true)) == SOCKET_NOT_FOUND) + { + last_driver_error = A_SOCKCXT_NOT_FOUND; + return A_SOCK_INVALID; + } + + while (rem_len != 0) + { + length = rem_len; + A_MEMZERO(custom_hdr, TCP6_HEADROOM); + + if (ath_sock_context[index]->domain == ATH_AF_INET) + { + if (ath_sock_context[index]->type == SOCK_STREAM_TYPE) + hdr_length = TCP_HEADROOM; + else + hdr_length = UDP_HEADROOM; + } + else + { + if (ath_sock_context[index]->type == SOCK_STREAM_TYPE) + hdr_length = TCP6_HEADROOM_WITH_NO_OPTION; + else + hdr_length = UDP6_HEADROOM; + } + + /*Calculate fragmentation threshold. We cannot send packets greater that HTC credit size + over HTC, Bigger packets need to be fragmented. Thresholds are different for IP v4 vs v6*/ + if (ath_sock_context[index]->domain == ATH_AF_INET6) + { + custom_hdr_length = sizeof(SOCK_SEND6_T); + SOCK_SEND6_T *tmp_ipv6 = (SOCK_SEND6_T*)custom_hdr; + if (name != NULL) + { + tmp_ipv6->name6.sin6_port = A_CPU2LE16(((SOCKADDR_6_T *)name)->sin6_port); + tmp_ipv6->name6.sin6_family = A_CPU2LE16(((SOCKADDR_6_T *)name)->sin6_family); + tmp_ipv6->name6.sin6_flowinfo = A_CPU2LE32(((SOCKADDR_6_T *)name)->sin6_flowinfo); + A_MEMCPY((uint8_t *)&(tmp_ipv6->name6.sin6_addr), + (uint8_t *)&((SOCKADDR_6_T *)name)->sin6_addr, sizeof(IP6_ADDR_T)); + tmp_ipv6->socklength = A_CPU2LE32(socklength); + } + else + { + memset((uint8_t *)(&tmp_ipv6->name6), 0, sizeof(name)); + } + } + else + { + custom_hdr_length = sizeof(SOCK_SEND_T); + SOCK_SEND_T *tmp_ipv4 = (SOCK_SEND_T*)custom_hdr; + if (name != NULL) + { + tmp_ipv4->name.sin_port = A_CPU2LE16(((SOCKADDR_T *)name)->sin_port); + tmp_ipv4->name.sin_family = A_CPU2LE16(((SOCKADDR_T *)name)->sin_family); + tmp_ipv4->name.sin_addr = A_CPU2LE32(((SOCKADDR_T *)name)->sin_addr); + tmp_ipv4->socklength = A_CPU2LE32(socklength); + } + else + { + memset((uint8_t *)(&tmp_ipv4->name), 0, sizeof(name)); + } + } + + /*Populate common fields of custom header, these are the same for IP v4/v6*/ + SOCK_SEND_T *tmp_sock = (SOCK_SEND_T*)custom_hdr; + tmp_sock->handle = A_CPU2LE32(handle); + tmp_sock->flags = A_CPU2LE32(flags); + + if (offset != 0) + { + memmove(bufPtr, (bufPtr + offset), rem_len); + } + + db_ptr = &((TX_PACKET_PTR)(bufPtr - TX_PKT_OVERHEAD))->db; + hdr = ((TX_PACKET_PTR)(bufPtr - TX_PKT_OVERHEAD))->hdr; + + A_MEMZERO(hdr, hdr_length); + +#if NON_BLOCKING_TX + pcustctxt = GET_SOCKET_CONTEXT(ath_sock_context[index]); + /*In non blocking TX case, Enqueue the packet so that it can be freed later when + TX over SPI is successful. Application should not free this buffer*/ + + A_MUTEX_ACQUIRE(&pcustctxt->nb_tx_mutex); + A_NETBUF_ENQUEUE(&(pcustctxt->non_block_queue), bufPtr); + A_MUTEX_RELEASE(&pcustctxt->nb_tx_mutex); +#endif + + if ((length == 0) || (length > IPV4_FRAGMENTATION_THRESHOLD)) + { + /*Host fragmentation is not allowed, application must send payload + below IPV4_FRAGMENTATION_THRESHOLD size*/ + A_ASSERT(0); + } + + tmp_sock->length = A_CPU2LE32(length); + + A_MEMCPY(hdr, custom_hdr, custom_hdr_length); + + db_ptr->context = (void *)ath_sock_context[index]; + if ((ath_sock_context[index]->type == SOCK_STREAM_TYPE) && (length > TCP_MSS)) + { + offset = TCP_MSS; + length = TCP_MSS; + } + + rem_len -= length; + + db_ptr->bufFragment[0].payload = bufPtr; + db_ptr->bufFragment[0].length = length; + result += length; + status = custom_send_tcpip(pCxt, db_ptr, length, 1, hdr, hdr_length); + if (status != A_OK) + { + goto END_TX; + } + +#if !NON_BLOCKING_TX + /*Wait till packet is sent to target*/ + if (BLOCK(pCxt, ath_sock_context[index], TRANSMIT_BLOCK_TIMEOUT, TX_DIRECTION) != A_OK) + { + result = -1; + goto END_TX; + } +#endif + } +END_TX: + + if (status != A_OK) + { + result = A_SOCK_INVALID; + } + + return result; +} + +#if ZERO_COPY +int32_t t_recvfrom(QCA_CONTEXT_STRUCT_PTR qca_ptr, + uint32_t handle, + void **buffer, + uint32_t length, + uint32_t flags, + void *name, + socklen_t *socklength) +#else +int32_t t_recvfrom(QCA_CONTEXT_STRUCT_PTR qca_ptr, + uint32_t handle, + void *buffer, + uint32_t length, + uint32_t flags, + void *name, + socklen_t *socklength) +#endif +{ + void *pCxt; + + if ((pCxt = qca_ptr->MAC_CONTEXT_PTR) == NULL) + { + return A_ERROR; + } + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_RX)) + { + return A_ERROR; + } + + return (Api_recvfrom(pCxt, handle, buffer, length, flags, name, socklength)); +} + +#if ZERO_COPY +int32_t t_recv(QCA_CONTEXT_STRUCT_PTR qca_ptr, uint32_t handle, void **buffer, uint32_t length, uint32_t flags) +#else +int32_t t_recv(QCA_CONTEXT_STRUCT_PTR qca_ptr, uint32_t handle, void *buffer, uint32_t length, uint32_t flags) +#endif +{ + return (t_recvfrom(qca_ptr, handle, buffer, length, flags, NULL, NULL)); +} + +#if ZERO_COPY + +/*****************************************************************************/ +/* zero_copy_free - ZERO_COPY free API.It will find and remove rx buffer from + * a common queue. + * RETURNS: Number of bytes received or A_ERROR in case of failure + *****************************************************************************/ +void zero_copy_free(void *buffer) +{ + A_NETBUF *a_netbuf_ptr = NULL; + + /*find buffer in zero copy queue*/ + a_netbuf_ptr = A_NETBUF_DEQUEUE_ADV(&zero_copy_free_queue, buffer); + + if (a_netbuf_ptr != NULL) + A_NETBUF_FREE(a_netbuf_ptr); + // else + // printf("Error: buffer not found\n"); +} + +/*****************************************************************************/ +/* Api_recvfrom - ZERO_COPY version of receive API.It will check socket's + * receive quese for pending packets. If a packet is available, + * it will be passed to the application without a memcopy. The + * application must call a zero_copy_free API to free this buffer. + * RETURNS: Number of bytes received or A_ERROR in case of failure + *****************************************************************************/ +int32_t Api_recvfrom( + void *pCxt, uint32_t handle, void **buffer, uint32_t length, uint32_t flags, void *name, socklen_t *socklength) +{ + int32_t index; + uint32_t len = 0, hdrlen = 0; + A_NETBUF *a_netbuf_ptr = NULL; + uint8_t *data = NULL; + SOCKET_CONTEXT_PTR pcustctxt; + + /*Find context*/ + if ((index = find_socket_context(handle, true)) == SOCKET_NOT_FOUND) + { + return A_SOCK_INVALID; + } + pcustctxt = GET_SOCKET_CONTEXT(ath_sock_context[index]); + /*Check if a packet is available*/ + /*Check if a packet is available*/ + if ((ath_sock_context[index]->type == SOCK_STREAM_TYPE) && (ath_sock_context[index]->remaining_bytes != 0) && + (ath_sock_context[index]->old_netbuf != NULL)) + { + a_netbuf_ptr = ath_sock_context[index]->old_netbuf; + data = (uint8_t *)A_NETBUF_DATA(a_netbuf_ptr); + } + else + { + while ((a_netbuf_ptr = A_NETBUF_DEQUEUE(&(pcustctxt->rxqueue))) == NULL) + { +#if NON_BLOCKING_RX + /*No packet is available, return -1*/ + return -1; +#else + if (ath_sock_context[index]->TCPCtrFlag == TCP_FIN) + { + if (queue_empty(index)) + { + QCADRV_PRINTF("fin in recv \r\n"); + clear_socket_context(index); + return A_SOCK_INVALID; + } + } + /*No packet available, block*/ + if (BLOCK(pCxt, ath_sock_context[index], 0, RX_DIRECTION) != A_OK) + { + /*Check if Peer closed socket while we were waiting*/ + if (ath_sock_context[index]->handle == 0) + { + return A_SOCK_INVALID; + } + if (ath_sock_context[index]->TCPCtrFlag == TCP_FIN) + { + QCADRV_PRINTF("clr sock in recv \r\n"); + clear_socket_context(index); + return A_SOCK_INVALID; + } + return A_ERROR; + } +#endif + } + data = (uint8_t *)A_NETBUF_DATA(a_netbuf_ptr); + } + + if (ath_sock_context[index]->domain == ATH_AF_INET) + { + hdrlen = sizeof(SOCK_RECV_T); + /*If we are receiving data for a UDP socket, extract sockaddr info*/ + if ((ath_sock_context[index]->type == SOCK_DGRAM_TYPE) || (ath_sock_context[index]->type == SOCK_RAW_TYPE)) + { + A_MEMCPY(name, &((SOCK_RECV_T *)data)->name, sizeof(SOCKADDR_T)); + ((SOCKADDR_T *)name)->sin_port = A_CPU2LE16(((SOCKADDR_T *)name)->sin_port); + ((SOCKADDR_T *)name)->sin_family = A_CPU2LE16(((SOCKADDR_T *)name)->sin_family); + ((SOCKADDR_T *)name)->sin_addr = A_CPU2LE32(((SOCKADDR_T *)name)->sin_addr); + *socklength = sizeof(SOCKADDR_T); + } + } + else if (ath_sock_context[index]->domain == ATH_AF_INET6) + { + hdrlen = sizeof(SOCK_RECV6_T); + /*If we are receiving data for a UDP socket, extract sockaddr info*/ + if ((ath_sock_context[index]->type == SOCK_DGRAM_TYPE) || (ath_sock_context[index]->type == SOCK_RAW_TYPE)) + { + A_MEMCPY(name, &((SOCK_RECV6_T *)data)->name6, sizeof(SOCKADDR_6_T)); + *socklength = sizeof(SOCKADDR_6_T); + } + } + else + { + A_ASSERT(0); + } + + if (!((ath_sock_context[index]->type == SOCK_STREAM_TYPE) && (ath_sock_context[index]->remaining_bytes != 0) && + (ath_sock_context[index]->old_netbuf != NULL))) + { + /*Remove custom header from payload*/ + A_NETBUF_PULL(a_netbuf_ptr, hdrlen); + } + + len = A_NETBUF_LEN(a_netbuf_ptr); + if (ath_sock_context[index]->type == SOCK_STREAM_TYPE) + { + if (len > length) + { + ath_sock_context[index]->remaining_bytes = (len - length); + len = length; + } + else + { + ath_sock_context[index]->remaining_bytes = 0; + ath_sock_context[index]->old_netbuf = NULL; + } + } + else + { + if (len > length) + { + len = length; // Discard excess bytes + } + } + + *buffer = (uint8_t *)A_NETBUF_DATA(a_netbuf_ptr); + if (ath_sock_context[index]->type == SOCK_STREAM_TYPE) + { + if (ath_sock_context[index]->remaining_bytes == 0) + { + A_NETBUF_ENQUEUE(&zero_copy_free_queue, a_netbuf_ptr); + } + else + { + A_NETBUF_PULL(a_netbuf_ptr, len); + ath_sock_context[index]->old_netbuf = a_netbuf_ptr; + } + } + else + { + A_NETBUF_ENQUEUE(&zero_copy_free_queue, a_netbuf_ptr); + } + return len; +} +#else + +/*****************************************************************************/ +/* Api_recvfrom - Non ZERO_COPY version of receive API.It will check socket's + * receive quese for pending packets. If a packet is available, + * it will be copied into user provided buffer. + * RETURNS: Number of bytes received or A_ERROR in case of failure + *****************************************************************************/ +int32_t Api_recvfrom( + void *pCxt, uint32_t handle, void *buffer, uint32_t length, uint32_t flags, void *name, socklen_t *socklength) +{ + int32_t index; + uint32_t len = 0, hdrlen = 0; + A_NETBUF *a_netbuf_ptr = NULL; + uint8_t *data = NULL; + SOCKET_CONTEXT_PTR pcustctxt; + + /*Find context*/ + if ((index = find_socket_context(handle, true)) == SOCKET_NOT_FOUND) + { + return A_SOCK_INVALID; + } + pcustctxt = GET_SOCKET_CONTEXT(ath_sock_context[index]); + + while ((a_netbuf_ptr = A_NETBUF_DEQUEUE(&(pcustctxt->rxqueue))) == NULL) + { +#if NON_BLOCKING_RX + /*No packet is available, return -1*/ + return A_ERROR; +#else + /*No packet available, block*/ + if (CUSTOM_BLOCK(pCxt, ath_sock_context[index], 0, RX_DIRECTION) != A_OK) + { + /*Check if Peer closed socket while we were waiting*/ + if (ath_sock_context[index]->handle == 0) + { + return A_SOCK_INVALID; + } + return A_ERROR; + } +#endif + } + + /*Extract custom header*/ + data = (uint8_t *)A_NETBUF_DATA(a_netbuf_ptr); + if (ath_sock_context[index]->domain == ATH_AF_INET) + { + hdrlen = sizeof(SOCK_RECV_T); + /*If we are receiving data for a UDP socket, extract sockaddr info*/ + if (ath_sock_context[index]->type == SOCK_DGRAM_TYPE) + { + A_MEMCPY(name, &((SOCK_RECV_T *)data)->name, sizeof(SOCKADDR_T)); + ((SOCKADDR_T *)name)->sin_port = A_CPU2LE16(((SOCKADDR_T *)name)->sin_port); + ((SOCKADDR_T *)name)->sin_family = A_CPU2LE16(((SOCKADDR_T *)name)->sin_family); + ((SOCKADDR_T *)name)->sin_addr = A_CPU2LE32(((SOCKADDR_T *)name)->sin_addr); + *socklength = sizeof(SOCKADDR_T); + } + } + else if (ath_sock_context[index]->domain == ATH_AF_INET6) + { + hdrlen = sizeof(SOCK_RECV6_T); + /*If we are receiving data for a UDP socket, extract sockaddr info*/ + if (ath_sock_context[index]->type == SOCK_DGRAM_TYPE) + { + A_MEMCPY(name, &((SOCK_RECV6_T *)data)->name6, sizeof(SOCKADDR_6_T)); + *socklength = sizeof(SOCKADDR_6_T); + } + } + else + { + A_ASSERT(0); + } + + /*Remove custom header from payload*/ + A_NETBUF_PULL(a_netbuf_ptr, hdrlen); + + len = A_NETBUF_LEN(a_netbuf_ptr); + + if (len > length) + len = length; // Discard excess bytes + + A_MEMCPY((uint8_t *)buffer, (uint8_t *)A_NETBUF_DATA(a_netbuf_ptr), len); + A_NETBUF_FREE(a_netbuf_ptr); + + return len; +} +#endif + +/*****************************************************************************/ +/* txpkt_free - function to free driver buffers that are allocated during send + * operations. The function is called from a_netbuf_free, after tx + * has successfully completed. + * If NON_BLOCKING_TX is defined, the user buffer is freed here + * as well. + * Note 1- called from driver thread. + * Note 2- should not be called from application + * RETURNS: none + *****************************************************************************/ +void txpkt_free(void *buffPtr) +{ + A_NETBUF_PTR a_netbuf_ptr = (A_NETBUF *)buffPtr; + DRV_BUFFER_PTR db_ptr = a_netbuf_ptr->native_orig; + +#if NON_BLOCKING_TX + SOCKET_CONTEXT_PTR pcustctxt = GET_SOCKET_CONTEXT((ATH_SOCKET_CONTEXT_PTR)db_ptr->context); + void *bufPtr = NULL; + /*In case of non blocking TX, driver should free the payload buffer*/ + A_MUTEX_ACQUIRE(&pcustctxt->nb_tx_mutex); + bufPtr = A_NETBUF_DEQUEUE(&(pcustctxt->non_block_queue)); + A_MUTEX_RELEASE(&pcustctxt->nb_tx_mutex); + + if (bufPtr != NULL) + { + A_FREE(((uint8_t *)bufPtr - TX_PKT_OVERHEAD), MALLOC_ID_CONTEXT); + bufPtr = NULL; + } + + /*We are done with netbuf, free Netbuf structure here*/ + A_FREE(a_netbuf_ptr->head, MALLOC_ID_NETBUFF); + A_FREE(a_netbuf_ptr, MALLOC_ID_NETBUFF_OBJ); +#else + /*Tail, data pointers within netbuf may have moved during previous TX, + reinit the netbuf so it can be used again*/ + a_netbuf_ptr = a_netbuf_reinit((void *)a_netbuf_ptr, TCP6_HEADROOM); + + /*Unblock the application thread*/ + UNBLOCK(db_ptr->context, TX_DIRECTION); +#endif +} + +/*****************************************************************************/ +/* custom_alloc - API for application to allocate a TX buffer. Here we ensure that + enough resources are available for a packet TX. All allocations + for a TX operation are made here. This includes Headroom, DB and netbuf. + If any allocation fails, this API returns NULL, and the host must + wait for some time to allow memory to be freed. + Note 1- Allocation may fail if too many packets are queued up for Transmission, + e.g. in the the non-blocking TX case. + Note 2- This API should ONLY be used for TX packets. + + * RETURNS: pointer to payload buffer for success and NULL for failure + *****************************************************************************/ +void *custom_alloc(uint32_t size) +{ + uint32_t total_size = 0; + uint8_t *buffer, *payload; + + /*Allocate TX buffer that will include- payload + headroom + Driver buffer + pointer to netbuf*/ + total_size = size + TX_PKT_OVERHEAD; + + /*Round off to 4 byte boundary*/ + if ((total_size % 4) != 0) + { + total_size += 4 - total_size % 4; + } + if ((buffer = A_MALLOC(total_size, MALLOC_ID_CONTEXT)) == NULL) + { + return NULL; + } + + /*Allocate netbuf with max possible headroom here so that there is no need to do it during TX*/ + if ((((TX_PACKET_PTR)buffer)->a_netbuf_ptr = A_NETBUF_ALLOC(TCP6_HEADROOM)) == NULL) + { + A_FREE(buffer, MALLOC_ID_CONTEXT); + return NULL; + } + /*Obtain pointer to start of payload*/ + payload = buffer + TX_PKT_OVERHEAD; + return payload; +} + +/*****************************************************************************/ +/* custom_free - API for application to free TX buffer. It should ONLY be called + * by the app if Blocking TX mode is enabled. It will free all allocations + * made during the custom_alloc + * RETURNS: none + *****************************************************************************/ +void custom_free(void *buf) +{ +#if (!NON_BLOCKING_TX) + uint8_t *buffer; + A_NETBUF_PTR a_netbuf_ptr; + + /*Move the the begining of TX buffer*/ + buffer = (uint8_t *)buf - TX_PKT_OVERHEAD; + + /*Get pointer to netbuf from TX buffer*/ + a_netbuf_ptr = ((TX_PACKET_PTR)buffer)->a_netbuf_ptr; + + if (a_netbuf_ptr) + { + /*We are done with netbuf, free Netbuf structure here*/ + A_FREE(a_netbuf_ptr->head, MALLOC_ID_NETBUFF); + A_FREE(a_netbuf_ptr, MALLOC_ID_NETBUFF_OBJ); + } + A_FREE(buffer, MALLOC_ID_CONTEXT); +#endif +} + +/*****************************************************************************/ +/* get_total_pkts_buffered - Returns number of packets buffered across all + * socket queues. + * RETURNS: number of packets + *****************************************************************************/ +uint32_t get_total_pkts_buffered(void) +{ + uint32_t index; + uint32_t totalPkts = 0; + + SOCKET_CONTEXT_PTR pcustctxt; + + for (index = 0; index < MAX_SOCKETS_SUPPORTED; index++) + { + pcustctxt = GET_SOCKET_CONTEXT(ath_sock_context[index]); + totalPkts += A_NETBUF_QUEUE_SIZE(&(pcustctxt->rxqueue)); + } + return totalPkts; +} + +#if ENABLE_SSL +/*****************************************************************************/ +/* SSL_ctx_new - Create new SSL context. This function must be called before + * using any other SSL functions. It needs to be called as either + * server or client + * Sslrole role - 1 = server, 2 = client + * int32_t inbufSize - initial inBuf size: Can grow + * int32_t outbufSize - outBuf size: Fixed + * int32_t reserved - currently not used (must be zero) + * Returns - SSL context handle on success or NULL on error (out of memory) + *****************************************************************************/ +SSL_CTX *SSL_ctx_new(SSL_ROLE_T role, int32_t inbufSize, int32_t outbufSize, int32_t reserved) +{ + void *pCxt; + + if ((pCxt = ((QCA_CONTEXT_STRUCT_PTR)sslhandle)->MAC_CONTEXT_PTR) == NULL) + { + return NULL; + } + + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return NULL; + } + return ((SSL_CTX *)Api_SSL_ctx_new(pCxt, role, inbufSize, outbufSize, reserved)); +} + +/*****************************************************************************/ +/* SSL_ctx_free - Free the SSL context + * SSL_CTX *ctx - sslContext + *****************************************************************************/ +int32_t SSL_ctx_free(SSL_CTX *ctx) +{ + void *pCxt; + + if ((pCxt = ((QCA_CONTEXT_STRUCT_PTR)sslhandle)->MAC_CONTEXT_PTR) == NULL) + { + return A_ERROR; + } + + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + return (Api_SSL_ctx_free(pCxt, ctx)); +} + +/*****************************************************************************/ +/* SSL_new - Create SSL connection object. When SSL transaction is done, close + * it with ssl_shutdown(). + * Note that the socket should subsequently also be closed. + * SSL_CTX *ctx - sslContext + * Return - SSL object handle on success or NULL on error (out of memory) + *****************************************************************************/ +SSL *SSL_new(SSL_CTX *ctx) +{ + void *pCxt; + + if ((pCxt = ((QCA_CONTEXT_STRUCT_PTR)sslhandle)->MAC_CONTEXT_PTR) == NULL) + { + return NULL; + } + + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return NULL; + } + return (Api_SSL_new(pCxt, ctx)); +} + +/*****************************************************************************/ +/* SSL_set_fd - Attach given socket descriptor to the SSL connection + * SSL *ssl - SSL connection + * uint32_t fd - Socket descriptor + * Return - 1 on success or negative error code on error (see SslErrors) + *****************************************************************************/ +int32_t SSL_set_fd(SSL *ssl, uint32_t fd) +{ + void *pCxt; + + if ((pCxt = ((QCA_CONTEXT_STRUCT_PTR)sslhandle)->MAC_CONTEXT_PTR) == NULL) + { + return A_ERROR; + } + + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + return (Api_SSL_set_fd(pCxt, ssl, fd)); +} + +/*****************************************************************************/ +/* SSL_accept - Initiate SSL handshake. + * SSL *ssl - SSL connection + * Returns - 1 on success, ESSL_HSDONE if handshake has already been performed. + * Negative error code otherwise. + *****************************************************************************/ +int32_t SSL_accept(SSL *ssl) +{ + void *pCxt; + + if ((pCxt = ((QCA_CONTEXT_STRUCT_PTR)sslhandle)->MAC_CONTEXT_PTR) == NULL) + { + return A_ERROR; + } + + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + return (Api_SSL_accept(pCxt, ssl)); +} + +/*****************************************************************************/ +/* SSL_connect - Initiate SSL handshake. + * SSL *ssl - SSL connection + * Returns - 1 on success, ESSL_HSDONE if handshake has already been performed. + * Negative error code otherwise. + *****************************************************************************/ +int32_t SSL_connect(SSL *ssl) +{ + void *pCxt; + + if ((pCxt = ((QCA_CONTEXT_STRUCT_PTR)sslhandle)->MAC_CONTEXT_PTR) == NULL) + { + return A_ERROR; + } + + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + return (Api_SSL_connect(pCxt, ssl)); +} + +/*****************************************************************************/ +/* SSL_shutdown - Close SSL connection. + * The socket must be closed by other means. + * SSL *ssl - SSL connection + * Returns - 1 on success or negative error code on error (see SslErrors) + *****************************************************************************/ +int32_t SSL_shutdown(SSL *ssl) +{ + void *pCxt; + + if ((pCxt = ((QCA_CONTEXT_STRUCT_PTR)sslhandle)->MAC_CONTEXT_PTR) == NULL) + { + return A_ERROR; + } + + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + return (Api_SSL_shutdown(pCxt, ssl)); +} + +/*****************************************************************************/ +/* SSL_configure - Configure a SSL connection. + * SSL *ssl - SSL connection + * SSL_CONFIG *cfg - pointer to struct holding the SSL configuration. + * Returns - 1 on success or negative error code on error (see SslErrors) + *****************************************************************************/ +int32_t SSL_configure(SSL *ssl, SSL_CONFIG *cfg) +{ + void *pCxt; + + if ((pCxt = ((QCA_CONTEXT_STRUCT_PTR)sslhandle)->MAC_CONTEXT_PTR) == NULL) + { + return A_ERROR; + } + + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + return (Api_SSL_configure(pCxt, ssl, cfg)); +} + +/*****************************************************************************/ +/* SSL_setCaList - Set a Certificate Authority (CA) list so SSL can perform + * certificate validation on the peer's certificate. + * You can only set one CA list, thus the CA list must include + * all root certificates required for the session. + * SSL *ssl - SSL connection + * SslCert cert -address of array of binary data + * uint32_t size - size of array + * Returns - 1 on success or negative error code on error (see SslErrors) + *****************************************************************************/ +int32_t SSL_setCaList(SSL_CTX *ctx, SslCAList caList, uint32_t size) +{ + void *pCxt; + + if ((pCxt = ((QCA_CONTEXT_STRUCT_PTR)sslhandle)->MAC_CONTEXT_PTR) == NULL) + { + return A_ERROR; + } + + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + return (Api_SSL_addCert(pCxt, ctx, SSL_CA_LIST, (uint8_t *)caList, size)); +} + +/*****************************************************************************/ +/* SSL_addCert - Add a certificate to the SharkSsl object. A SharkSsl object + * in server mode is required to have at least one certificate. + * SSL *ssl - SSL connection + * SslCert cert -address of array of binary data + * uint32_t size - size of array + * Returns - 1 on success or negative error code on error (see SslErrors) + *****************************************************************************/ +int32_t SSL_addCert(SSL_CTX *ctx, SslCert cert, uint32_t size) +{ + void *pCxt; + + if ((pCxt = ((QCA_CONTEXT_STRUCT_PTR)sslhandle)->MAC_CONTEXT_PTR) == NULL) + { + return A_ERROR; + } + + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + return (Api_SSL_addCert(pCxt, ctx, SSL_CERTIFICATE, (uint8_t *)cert, size)); +} + +/*****************************************************************************/ +/* SSL_storeCert - Store a certificate or CA list in FLASH. + * char *name - the name + * SslCert cert -address of array of binary data + * uint32_t size - size of array + * Returns - 1 on success or negative error code on error (see SslErrors) + *****************************************************************************/ +int32_t SSL_storeCert(char *name, SslCert cert, uint32_t size) +{ + void *pCxt; + + if ((pCxt = ((QCA_CONTEXT_STRUCT_PTR)sslhandle)->MAC_CONTEXT_PTR) == NULL) + { + return A_ERROR; + } + + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + return (Api_SSL_storeCert(pCxt, name, (uint8_t *)cert, size)); +} + +/*****************************************************************************/ +/* SSL_loadCert - Load a certificate or CA list from FLASH and store it in the + * sharkSs object. + * SSL_CERT_TYPE_T type - certificate or CA list + * char *name - the name + * Returns - 1 on success or negative error code on error (see SslErrors) + *****************************************************************************/ +int32_t SSL_loadCert(SSL_CTX *ctx, SSL_CERT_TYPE_T type, char *name) +{ + void *pCxt; + + if ((pCxt = ((QCA_CONTEXT_STRUCT_PTR)sslhandle)->MAC_CONTEXT_PTR) == NULL) + { + return A_ERROR; + } + + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + return (Api_SSL_loadCert(pCxt, ctx, type, name)); +} + +int32_t SSL_listCert(SSL_FILE_NAME_LIST *fileNames) +{ + void *pCxt; + + if ((pCxt = ((QCA_CONTEXT_STRUCT_PTR)sslhandle)->MAC_CONTEXT_PTR) == NULL) + { + return A_ERROR; + } + + /*Wait for chip to be up*/ + if (A_OK != Api_DriverAccessCheck(pCxt, 1, ACCESS_REQUEST_IOCTL)) + { + return A_ERROR; + } + return (Api_SSL_listCert(pCxt, fileNames)); +} + +#if ZERO_COPY +/*****************************************************************************/ +/* SSL_read - ZERO_COPY version of SSL read function. It uses the ssl pointer + * to find the socket to read from.It will check socket's receive + * queues for pending packets. If a packet is available, it will be + * passed to the application without a memcopy. The application must + * call a zero_copy_free API to free this buffer. + * SSL *ssl - pointer to SSL connection object. + * void **buf - pointer to pointer holding the address of the receive buffer. + * int32_t num - The max number of bytes to read. + * Returns - Number of bytes received or A_ERROR in case of failure + *****************************************************************************/ +int32_t SSL_read(SSL *ssl, void **buf, int32_t num) +#else +int32_t SSL_read(SSL *ssl, void *buf, int32_t num) +#endif +{ + /* Find the socket used with this SSL connection */ + int32_t index = find_socket_context_from_ssl(ssl); + if (index == SOCKET_NOT_FOUND) + { + return A_ERROR; + } + + /* Read data from the socket */ + return t_recv(sslhandle, ath_sock_context[index]->handle, buf, num, 0); +} + +/*****************************************************************************/ +/* SSL_write - Encrypt and send data in buf and send them on the associated + * socket. The ssl pointer is sued to find the socket to send on. + * SSL *ssl - pointer to SSL connection object. + * void *buf - pointer to buffer holding the data to send. + * int32_t num - The number of bytes to send. + * Returns - Number of bytes sent on success or negative error code on error + *****************************************************************************/ +int32_t SSL_write(SSL *ssl, const void *buf, int32_t num) +{ + /* Find the socket used with this SSL connection */ + int32_t index = find_socket_context_from_ssl(ssl); + if (index == SOCKET_NOT_FOUND) + { + return A_ERROR; + } + + /* Send the data */ + return t_send(sslhandle, ath_sock_context[index]->handle, (uint8_t *)buf, num, 0); +} + +#endif // ENABLE_SSL +#endif diff --git a/platform/mcu/lpc54102/wifi_qca/custom_src/stack_custom/cust_api_stack_txrx.c b/platform/mcu/lpc54102/wifi_qca/custom_src/stack_custom/cust_api_stack_txrx.c new file mode 100644 index 0000000000..3c3bfc2528 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/custom_src/stack_custom/cust_api_stack_txrx.c @@ -0,0 +1,206 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== +#include +#include +#include +#include +#include +#include +#include +#include "cust_netbuf.h" + +#if ENABLE_STACK_OFFLOAD +#include "atheros_stack_offload.h" +#include "common_stack_offload.h" +#include "custom_stack_offload.h" +#include "atheros_wifi.h" + +uint32_t Custom_Api_Send( + QCA_CONTEXT_STRUCT_PTR qca_ptr, PCB_PTR pcb_ptr, uint32_t size, uint32_t frags, uint32_t flags); + +uint32_t Custom_Api_Send(QCA_CONTEXT_STRUCT_PTR qca_ptr, PCB_PTR pcb_ptr, uint32_t size, uint32_t frags, uint32_t flags) +{ + return A_OK; +} + +uint32_t custom_sock_is_pending(ATH_SOCKET_CONTEXT *sock_context) +{ + uint32_t i, rtn; + for (rtn = 0, i = 0; i < (SOCK_CMD_LAST / 32 + 1); i++) + { + rtn |= sock_context->sock_st_mask[i]; + } + + return rtn; +} + +/*****************************************************************************/ +/* custom_receive_tcpip - Called by Custom_DeliverFrameToNetworkStack to + * deliver a data frame to the application thread. It unblocks a waiting + * application thread and queues the packet in the queue of the corresponding + * socket. If socket is not valid, the packet is dropped. + * void *pCxt - the driver context. + * void *pReq - the packet. + *****************************************************************************/ +A_STATUS custom_receive_tcpip(void *pCxt, void *pReq) +{ + A_NETBUF *a_netbuf_ptr = (A_NETBUF *)pReq; + int32_t index = 0, handle = 0; + uint8_t *data; + + SOCKET_CONTEXT_PTR pcustctxt = NULL; + + if (a_netbuf_ptr) + { + data = (uint8_t *)A_NETBUF_DATA(a_netbuf_ptr); + + /*Extract socket handle from custom header*/ + handle = A_CPU2LE32(*((uint32_t *)data)); + + /*Get index*/ + index = find_socket_context(handle, true); + if (index < 0 || index > MAX_SOCKETS_SUPPORTED) + { + last_driver_error = A_SOCKCXT_NOT_FOUND; + A_NETBUF_FREE(pReq); + return A_ERROR; + } + + if (custom_sock_is_pending(ath_sock_context[index]) != 0) + { + /* socket is pending a socket event so it cannot + * receive data packets */ + last_driver_error = A_SOCK_UNAVAILABLE; + A_NETBUF_FREE(pReq); + return A_ERROR; + } + + UNBLOCK_SELECT(pCxt); + pcustctxt = GET_SOCKET_CONTEXT(ath_sock_context[index]); + + // if(!IS_SOCKET_BLOCKED(ath_sock_context[index])) + /*To-Do- Remove this once drop ligic is implemented in firmware*/ + if (get_total_pkts_buffered() >= WLAN_CONFIG_NUM_PRE_ALLOC_RX_BUFFERS /*- 1*/) + { + QCADRV_PRINTF("%s dropping packets for %x\n", __FUNCTION__, handle); + A_NETBUF_FREE(pReq); + } + else + { + A_NETBUF_ENQUEUE(&(pcustctxt->rxqueue), a_netbuf_ptr); + UNBLOCK(ath_sock_context[index], RX_DIRECTION); + } + } + return A_OK; +} + +/*****************************************************************************/ +/* Custom_DeliverFrameToNetworkStack - Called by API_RxComplete to + * deliver a data frame to the network stack. This code will perform + * platform specific operations. + * void *pCxt - the driver context. + * void *pReq - the packet. + *****************************************************************************/ +void Custom_DeliverFrameToNetworkStack(void *pCxt, void *pReq) +{ + ATH_PROMISCUOUS_CB prom_cb = (ATH_PROMISCUOUS_CB)(GET_DRIVER_CXT(pCxt)->promiscuous_cb); + + if (GET_DRIVER_COMMON(pCxt)->promiscuous_mode) + { + prom_cb(pReq); + } + else + { + custom_receive_tcpip(pCxt, pReq); + } +} + +/*****************************************************************************/ +/* Custom_Api_Send - Entry point for MQX driver interface to send a packet. + * This is specific to MQX. This function is NOT called from within the + * driver. + * QCA_CONTEXT_STRUCT_PTR qca_ptr - the MQX driver context. + * PCB_PTR pcb_ptr - the MQX packet object. + * uint32_t size - the length in bytes of pcb_ptr. + * uint32_t frags - the number of fragments in pcb_ptr. + * uint32_t flags - optional flags for transmit. + *****************************************************************************/ +A_STATUS custom_send_tcpip(void *pCxt, + DRV_BUFFER_PTR db_ptr, + /* [IN] the packet to send */ + uint32_t size, + /* [IN] total size of the packet */ + uint32_t frags, + /* [IN] total fragments in the packet */ + uint8_t *header, + uint32_t header_size + + ) +{ + A_STATUS error = A_OK; + A_NETBUF *a_netbuf_ptr; + uint32_t total_hdr_size = header_size; + uint8_t *payloadPtr = db_ptr->bufFragment[0].payload; + + /* create an atheros pcb and continue or fail. */ + do + { + /*Get the netbuf pointer from TX packet*/ + a_netbuf_ptr = ((TX_PACKET_PTR)(payloadPtr - TX_PKT_OVERHEAD))->a_netbuf_ptr; + + a_netbuf_ptr->num_frags = (uint8_t)frags; + + A_NETBUF_PUT_DATA(a_netbuf_ptr, (uint8_t *)header, total_hdr_size); + // ensure there is enough headroom to complete the tx operation + if (A_NETBUF_HEADROOM(a_netbuf_ptr) < (int32_t)(sizeof(ATH_MAC_HDR) + sizeof(ATH_LLC_SNAP_HDR) + + sizeof(WMI_DATA_HDR) + HTC_HDR_LENGTH + WMI_MAX_TX_META_SZ)) + { + error = A_NO_MEMORY; + A_NETBUF_FREE(a_netbuf_ptr); + break; + } + // carry the original around until completion. + // it is freed by A_NETBUF_FREE + a_netbuf_ptr->native_orig = db_ptr; + + if (A_OK != Api_DataTxStart(pCxt, (void *)a_netbuf_ptr)) + { + error = A_ERROR; + break; + } + } while (0); + + if (error != A_OK) + { + /* in the event of api failure, the original pcb should be returned to the caller un-touched + * and the a_netbuf_ptr should be freed */ + if (error != A_NO_MEMORY) + A_NETBUF_FREE((void *)a_netbuf_ptr); + } + return error; +} + +#endif diff --git a/platform/mcu/lpc54102/wifi_qca/custom_src/stack_custom/custom_stack_offload.h b/platform/mcu/lpc54102/wifi_qca/custom_src/stack_custom/custom_stack_offload.h new file mode 100644 index 0000000000..291534c8ac --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/custom_src/stack_custom/custom_stack_offload.h @@ -0,0 +1,70 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== + +#ifndef _CUSTOM_STACK_OFFLOAD_H_ +#define _CUSTOM_STACK_OFFLOAD_H_ + +#if ENABLE_STACK_OFFLOAD + +#include + +#define IS_SOCKET_BLOCKED(index) isSocketBlocked((index)) + +/* Headroom definitions*/ +#define UDP_HEADROOM 44 +#define TCP_HEADROOM 64 +#define UDP6_HEADROOM 64 +#define TCP6_HEADROOM 88 +#define TCP6_HEADROOM_WITH_NO_OPTION 84 + +#define TX_PKT_OVERHEAD (TCP6_HEADROOM + sizeof(DRV_BUFFER) + sizeof(uint32_t)) + +#if ZERO_COPY +extern A_NETBUF_QUEUE_T zero_copy_free_queue; +#endif + +uint32_t isSocketBlocked(void *ctxt); + +A_STATUS custom_receive_tcpip(void *pCxt, void *pReq); +void txpkt_free(void *buffPtr); +A_STATUS custom_send_tcpip(void *pCxt, + /* [IN] the Ethernet state structure */ + DRV_BUFFER_PTR db_ptr, + /* [IN] the packet to send */ + uint32_t size, + /* [IN] total size of the packet */ + uint32_t frags, + /* [IN] total fragments in the packet */ + uint8_t *header, + uint32_t header_size + + ); + +void custom_free(void *buf); +void *custom_alloc(uint32_t size); +uint32_t get_total_pkts_buffered(void); +#endif // ENABLE_STACK_OFFLOAD +#endif diff --git a/platform/mcu/lpc54102/wifi_qca/custom_src/stack_custom/qca_structs.h b/platform/mcu/lpc54102/wifi_qca/custom_src/stack_custom/qca_structs.h new file mode 100644 index 0000000000..d80b0a36c0 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/custom_src/stack_custom/qca_structs.h @@ -0,0 +1,197 @@ +/* + * The Clear BSD License + * Copyright (c) 2016, NXP Semiconductor, Inc. + * All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted (subject to the limitations in the disclaimer below) provided + * that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of NXP Semiconductor, Inc. nor the names of its + * contributors may be used tom endorse or promote products derived from this + * software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 + * 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 __qca_structs_h__ +#define __qca_structs_h__ + +/* Error codes */ +#define QCA_ERROR_BASE (0) +#define QCA_OK (0) +#define QCA_ERROR (QCA_ERROR_BASE | 0xff) /* general error */ + +#define QCA_ERR_INVALID_DEVICE (QCA_ERROR_BASE | 0x00) /* Device number out of range */ +#define QCA_ERR_ALLOC_PCB (QCA_ERROR_BASE | 0x03) /* Alloc PCBs failed */ +#define QCA_ERR_INIT_FAILED (QCA_ERROR_BASE | 0x12) /* Device failed to initialize */ +#define QCA_ERR_INVALID_INIT_PARAM (QCA_ERROR_BASE | 0x17) /* Invalid init. parameter */ + +typedef void *PCB_PTR; + +/* MODES */ +#define QCA_HALF_DUPLEX 0x1 +#define QCA_FULL_DUPLEX 0x0 +#define QCA_DUPLEX_MASK 0x1 +#define QCA_10M 0x02 +#define QCA_100M 0x04 +#define QCA_1G 0x06 +#define QCA_SPEED_MASK 0x0e +#define QCA_AUTONEGOTIATE 0x10 + +/* Security types */ +#define QCA_MEDIACTL_SECURITY_TYPE_NONE (0x00) +#define QCA_MEDIACTL_SECURITY_TYPE_WEP (0x01) +#define QCA_MEDIACTL_SECURITY_TYPE_WPA (0x02) +#define QCA_MEDIACTL_SECURITY_TYPE_WPA2 (0x03) + +/* Single cell network */ +#define QCA_MEDIACTL_MODE_ADHOC (1) +/* Multi cell network, roaming, ... */ +#define QCA_MEDIACTL_MODE_INFRA (2) +/* Synchronisation master or Access Point */ +#define QCA_MEDIACTL_MODE_MASTER (3) + +/* Media control definition types */ +#define IO_TYPE_MEDIACTL_WIFI 0x00 + +#define QCA_SET_MEDIACTL_COMMIT (IO_TYPE_MEDIACTL_WIFI | 0x01) +#define QCA_SET_MEDIACTL_FREQ (IO_TYPE_MEDIACTL_WIFI | 0x02) +#define QCA_SET_MEDIACTL_MODE (IO_TYPE_MEDIACTL_WIFI | 0x03) +#define QCA_SET_MEDIACTL_SCAN (IO_TYPE_MEDIACTL_WIFI | 0x04) +#define QCA_SET_MEDIACTL_ESSID (IO_TYPE_MEDIACTL_WIFI | 0x05) +#define QCA_SET_MEDIACTL_RTS (IO_TYPE_MEDIACTL_WIFI | 0x07) +#define QCA_SET_MEDIACTL_POWER (IO_TYPE_MEDIACTL_WIFI | 0x0A) +#define QCA_SET_MEDIACTL_SEC_TYPE (IO_TYPE_MEDIACTL_WIFI | 0x0B) +#define QCA_SET_MEDIACTL_PASSPHRASE (IO_TYPE_MEDIACTL_WIFI | 0x0C) +/* IOCTL's to get various features of WIFI device. */ +#define QCA_GET_MEDIACTL_MODE (IO_TYPE_MEDIACTL_WIFI | 0x10) +#define QCA_GET_MEDIACTL_SCAN (IO_TYPE_MEDIACTL_WIFI | 0x13) +#define QCA_GET_MEDIACTL_ESSID (IO_TYPE_MEDIACTL_WIFI | 0x14) +#define QCA_GET_MEDIACTL_POWER (IO_TYPE_MEDIACTL_WIFI | 0x19) +#define QCA_GET_MEDIACTL_SEC_TYPE (IO_TYPE_MEDIACTL_WIFI | 0x20) +#define QCA_MEDIACTL_IS_INITIALIZED (IO_TYPE_MEDIACTL_WIFI | 0x21) +#define QCA_MEDIACTL_VENDOR_SPECIFIC (IO_TYPE_MEDIACTL_WIFI | 0x81) + +typedef struct _scan_info +{ + uint8_t channel; + uint8_t ssid_len; + uint8_t rssi; + uint8_t security_enabled; + uint16_t beacon_period; + uint8_t preamble; + uint8_t bss_type; + uint8_t bssid[6]; + uint8_t ssid[32]; + uint8_t rsn_cipher; + uint8_t rsn_auth; + uint8_t wpa_cipher; + uint8_t wpa_auth; +} QCA_SCAN_INFO, *QCA_SCAN_INFO_PTR; + +typedef struct _scan_list +{ + int32_t num_scan_entries; + QCA_SCAN_INFO_PTR scan_info_list; +} QCA_SCAN_LIST, *QCA_SCAN_LIST_PTR; + +/* + * Generic format for most parameters that fit in an int + */ +typedef struct _param +{ + int32_t value; /* The value of the parameter itself */ + void *data; + uint32_t length; +} QCA_MEDIACTL_PARAM, *QCA_MEDIACTL_PARAM_PTR; + +typedef struct __essid +{ + char *essid; + uint16_t flags; + uint32_t length; +} QCA_ESSID, *QCA_ESSID_PTR; + +typedef unsigned char _qca_address[6]; + +/* Joined multicast groups */ +typedef struct qca_mcb_struct +{ + _qca_address GROUP; + uint32_t HASH; + struct qca_mcb_struct *NEXT; +} QCA_MCB_STRUCT, *QCA_MCB_STRUCT_PTR; + +/* The Ethernet state structure */ +struct qca_context_struct; + +typedef struct +{ + uint32_t (*INIT)(struct qca_context_struct *); + uint32_t (*STOP)(struct qca_context_struct *); + uint32_t (*SEND)(struct qca_context_struct *, PCB_PTR, uint32_t, uint32_t, uint32_t); + uint32_t (*PHY_READ)(struct qca_context_struct *, uint32_t, uint32_t *, uint32_t); + uint32_t (*PHY_WRITE)(struct qca_context_struct *, uint32_t, uint32_t, uint32_t); + uint32_t (*JOIN)(struct qca_context_struct *, struct qca_mcb_struct *); + uint32_t (*REJOIN)(struct qca_context_struct *); + uint32_t (*MEDIACTL)(struct qca_context_struct *, uint32_t command_id, void *inout_param); +} QCA_MAC_IF_STRUCT, *QCA_MAC_IF_STRUCT_PTR; + +typedef struct qca_if_struct +{ + const QCA_MAC_IF_STRUCT *MAC_IF; /* pointer to MAC interface struct */ + unsigned char MAC_NUMBER; /* MAC device number */ + unsigned char PHY_NUMBER; /* MAC device number for communication with PHY */ + unsigned char PHY_ADDRESS; /* PHY address */ +} QCA_IF_STRUCT, *QCA_IF_STRUCT_PTR; + +typedef void *_qca_handle; + +typedef enum +{ + Half_Duplex_10M = (QCA_HALF_DUPLEX | QCA_10M), + Full_Duplex_10M = (QCA_FULL_DUPLEX | QCA_10M), + Half_Duplex_100M = (QCA_HALF_DUPLEX | QCA_100M), + Full_Duplex_100M = (QCA_FULL_DUPLEX | QCA_100M), + Half_Duplex_1G = (QCA_HALF_DUPLEX | QCA_1G), + Full_Duplex_1G = (QCA_FULL_DUPLEX | QCA_1G), + Auto_Negotiate = QCA_AUTONEGOTIATE +} QCA_mode; + +typedef struct qca_param_struct +{ + const QCA_IF_STRUCT *QCA_IF; + QCA_mode MODE; + uint32_t OPTIONS; + uint16_t NUM_RX_PCBS; + void *MAC_PARAM; + +} QCA_PARAM_STRUCT; + +typedef struct qca_context_struct +{ + const QCA_PARAM_STRUCT *PARAM_PTR; + _qca_address ADDRESS; + void *MAC_CONTEXT_PTR; +} QCA_CONTEXT_STRUCT, *QCA_CONTEXT_STRUCT_PTR; +#endif +/* EOF */ diff --git a/platform/mcu/lpc54102/wifi_qca/include/AR6002/AR6K_version.h b/platform/mcu/lpc54102/wifi_qca/include/AR6002/AR6K_version.h new file mode 100644 index 0000000000..5e6dc9d493 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/include/AR6002/AR6K_version.h @@ -0,0 +1,64 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== + +#define __VER_MAJOR_ 3 // corresponds to release X._._._._ +#define __VER_MINOR_ 3 // corresponds to release _.X._._._ +#define __VER_PATCH_ 0 // corresponds to release _._.X._. +#define __VER_REV_ 0 // corresponds to release _._._.X._ <-- Increment This field manually for every build + +/* The makear6ksdk script (used for release builds) modifies the following line. */ +#define __BUILD_NUMBER_ 0 + +/* Format of the version number. */ +#define VER_MAJOR_BIT_OFFSET 28 +#define VER_MINOR_BIT_OFFSET 24 +#define VER_PATCH_BIT_OFFSET 16 +#define VER_BUILD_NUM_BIT_OFFSET 0 + +/* + * The version has the following format: + * Bits 28-31: Major version + * Bits 24-27: Minor version + * Bite 18-23: Patch number + * Bits 8-17: Revision number (Increment this every build) + * Bits 0-7: build number which is automatically updated + * + * DO NOT split the following macro into multiple lines as this may confuse the build scripts. + */ +#define AR6K_SW_VERSION \ + ((__VER_MAJOR_ << VER_MAJOR_BIT_OFFSET) + (__VER_MINOR_ << VER_MINOR_BIT_OFFSET) + \ + ((__VER_PATCH_ & 0xFF) << VER_PATCH_BIT_OFFSET) + (((__BUILD_NUMBER_)&0xFFFF) << VER_BUILD_NUM_BIT_OFFSET)) + +/* ABI Version. Reflects the version of binary interface exposed by AR6K target firmware. Needs to be incremented by 1 + * for any change in the firmware that requires upgrade of the driver on the host side for the change to work correctly + */ +#define ABI_VERSION_MAJOR (1) +#define ABI_VERSION_MINOR (0) +#define ABI_MAJOR_OFFSET (16) +#define ABI_MAJOR_MASK (0xffff0000) +#define ABI_MINOR_OFFSET (0) +#define ABI_MINOR_MASK (0x0000ffff) +#define AR6K_ABI_VERSION ((ABI_VERSION_MAJOR << ABI_MAJOR_OFFSET) | (ABI_VERSION_MINOR << ABI_MINOR_OFFSET)) diff --git a/platform/mcu/lpc54102/wifi_qca/include/AR6002/hw2.0/hw/hw20_apb_map.h b/platform/mcu/lpc54102/wifi_qca/include/AR6002/hw2.0/hw/hw20_apb_map.h new file mode 100644 index 0000000000..487c96ddd7 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/include/AR6002/hw2.0/hw/hw20_apb_map.h @@ -0,0 +1,38 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== +#ifndef _APB_MAP_H_ +#define _APB_MAP_H_ + +#define RTC_BASE_ADDRESS 0x00004000 +#define VMC_BASE_ADDRESS 0x00008000 +#define UART_BASE_ADDRESS 0x0000c000 +#define SI_BASE_ADDRESS 0x00010000 +#define GPIO_BASE_ADDRESS 0x00014000 +#define MBOX_BASE_ADDRESS 0x00018000 +#define ANALOG_INTF_BASE_ADDRESS 0x0001c000 +#define MAC_BASE_ADDRESS 0x00020000 + +#endif /* _APB_MAP_REG_H_ */ diff --git a/platform/mcu/lpc54102/wifi_qca/include/AR6002/hw2.0/hw/hw20_gpio_reg.h b/platform/mcu/lpc54102/wifi_qca/include/AR6002/hw2.0/hw/hw20_gpio_reg.h new file mode 100644 index 0000000000..8bbcba0b8e --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/include/AR6002/hw2.0/hw/hw20_gpio_reg.h @@ -0,0 +1,1001 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== +#ifndef _GPIO_REG_REG_H_ +#define _GPIO_REG_REG_H_ + +#define GPIO_OUT_ADDRESS 0x00000000 +#define GPIO_OUT_OFFSET 0x00000000 +#define GPIO_OUT_DATA_MSB 17 +#define GPIO_OUT_DATA_LSB 0 +#define GPIO_OUT_DATA_MASK 0x0003ffff +#define GPIO_OUT_DATA_GET(x) (((x)&GPIO_OUT_DATA_MASK) >> GPIO_OUT_DATA_LSB) +#define GPIO_OUT_DATA_SET(x) (((x) << GPIO_OUT_DATA_LSB) & GPIO_OUT_DATA_MASK) + +#define GPIO_OUT_W1TS_ADDRESS 0x00000004 +#define GPIO_OUT_W1TS_OFFSET 0x00000004 +#define GPIO_OUT_W1TS_DATA_MSB 17 +#define GPIO_OUT_W1TS_DATA_LSB 0 +#define GPIO_OUT_W1TS_DATA_MASK 0x0003ffff +#define GPIO_OUT_W1TS_DATA_GET(x) (((x)&GPIO_OUT_W1TS_DATA_MASK) >> GPIO_OUT_W1TS_DATA_LSB) +#define GPIO_OUT_W1TS_DATA_SET(x) (((x) << GPIO_OUT_W1TS_DATA_LSB) & GPIO_OUT_W1TS_DATA_MASK) + +#define GPIO_OUT_W1TC_ADDRESS 0x00000008 +#define GPIO_OUT_W1TC_OFFSET 0x00000008 +#define GPIO_OUT_W1TC_DATA_MSB 17 +#define GPIO_OUT_W1TC_DATA_LSB 0 +#define GPIO_OUT_W1TC_DATA_MASK 0x0003ffff +#define GPIO_OUT_W1TC_DATA_GET(x) (((x)&GPIO_OUT_W1TC_DATA_MASK) >> GPIO_OUT_W1TC_DATA_LSB) +#define GPIO_OUT_W1TC_DATA_SET(x) (((x) << GPIO_OUT_W1TC_DATA_LSB) & GPIO_OUT_W1TC_DATA_MASK) + +#define GPIO_ENABLE_ADDRESS 0x0000000c +#define GPIO_ENABLE_OFFSET 0x0000000c +#define GPIO_ENABLE_DATA_MSB 17 +#define GPIO_ENABLE_DATA_LSB 0 +#define GPIO_ENABLE_DATA_MASK 0x0003ffff +#define GPIO_ENABLE_DATA_GET(x) (((x)&GPIO_ENABLE_DATA_MASK) >> GPIO_ENABLE_DATA_LSB) +#define GPIO_ENABLE_DATA_SET(x) (((x) << GPIO_ENABLE_DATA_LSB) & GPIO_ENABLE_DATA_MASK) + +#define GPIO_ENABLE_W1TS_ADDRESS 0x00000010 +#define GPIO_ENABLE_W1TS_OFFSET 0x00000010 +#define GPIO_ENABLE_W1TS_DATA_MSB 17 +#define GPIO_ENABLE_W1TS_DATA_LSB 0 +#define GPIO_ENABLE_W1TS_DATA_MASK 0x0003ffff +#define GPIO_ENABLE_W1TS_DATA_GET(x) (((x)&GPIO_ENABLE_W1TS_DATA_MASK) >> GPIO_ENABLE_W1TS_DATA_LSB) +#define GPIO_ENABLE_W1TS_DATA_SET(x) (((x) << GPIO_ENABLE_W1TS_DATA_LSB) & GPIO_ENABLE_W1TS_DATA_MASK) + +#define GPIO_ENABLE_W1TC_ADDRESS 0x00000014 +#define GPIO_ENABLE_W1TC_OFFSET 0x00000014 +#define GPIO_ENABLE_W1TC_DATA_MSB 17 +#define GPIO_ENABLE_W1TC_DATA_LSB 0 +#define GPIO_ENABLE_W1TC_DATA_MASK 0x0003ffff +#define GPIO_ENABLE_W1TC_DATA_GET(x) (((x)&GPIO_ENABLE_W1TC_DATA_MASK) >> GPIO_ENABLE_W1TC_DATA_LSB) +#define GPIO_ENABLE_W1TC_DATA_SET(x) (((x) << GPIO_ENABLE_W1TC_DATA_LSB) & GPIO_ENABLE_W1TC_DATA_MASK) + +#define GPIO_IN_ADDRESS 0x00000018 +#define GPIO_IN_OFFSET 0x00000018 +#define GPIO_IN_DATA_MSB 17 +#define GPIO_IN_DATA_LSB 0 +#define GPIO_IN_DATA_MASK 0x0003ffff +#define GPIO_IN_DATA_GET(x) (((x)&GPIO_IN_DATA_MASK) >> GPIO_IN_DATA_LSB) +#define GPIO_IN_DATA_SET(x) (((x) << GPIO_IN_DATA_LSB) & GPIO_IN_DATA_MASK) + +#define GPIO_STATUS_ADDRESS 0x0000001c +#define GPIO_STATUS_OFFSET 0x0000001c +#define GPIO_STATUS_INTERRUPT_MSB 17 +#define GPIO_STATUS_INTERRUPT_LSB 0 +#define GPIO_STATUS_INTERRUPT_MASK 0x0003ffff +#define GPIO_STATUS_INTERRUPT_GET(x) (((x)&GPIO_STATUS_INTERRUPT_MASK) >> GPIO_STATUS_INTERRUPT_LSB) +#define GPIO_STATUS_INTERRUPT_SET(x) (((x) << GPIO_STATUS_INTERRUPT_LSB) & GPIO_STATUS_INTERRUPT_MASK) + +#define GPIO_STATUS_W1TS_ADDRESS 0x00000020 +#define GPIO_STATUS_W1TS_OFFSET 0x00000020 +#define GPIO_STATUS_W1TS_INTERRUPT_MSB 17 +#define GPIO_STATUS_W1TS_INTERRUPT_LSB 0 +#define GPIO_STATUS_W1TS_INTERRUPT_MASK 0x0003ffff +#define GPIO_STATUS_W1TS_INTERRUPT_GET(x) (((x)&GPIO_STATUS_W1TS_INTERRUPT_MASK) >> GPIO_STATUS_W1TS_INTERRUPT_LSB) +#define GPIO_STATUS_W1TS_INTERRUPT_SET(x) (((x) << GPIO_STATUS_W1TS_INTERRUPT_LSB) & GPIO_STATUS_W1TS_INTERRUPT_MASK) + +#define GPIO_STATUS_W1TC_ADDRESS 0x00000024 +#define GPIO_STATUS_W1TC_OFFSET 0x00000024 +#define GPIO_STATUS_W1TC_INTERRUPT_MSB 17 +#define GPIO_STATUS_W1TC_INTERRUPT_LSB 0 +#define GPIO_STATUS_W1TC_INTERRUPT_MASK 0x0003ffff +#define GPIO_STATUS_W1TC_INTERRUPT_GET(x) (((x)&GPIO_STATUS_W1TC_INTERRUPT_MASK) >> GPIO_STATUS_W1TC_INTERRUPT_LSB) +#define GPIO_STATUS_W1TC_INTERRUPT_SET(x) (((x) << GPIO_STATUS_W1TC_INTERRUPT_LSB) & GPIO_STATUS_W1TC_INTERRUPT_MASK) + +#define GPIO_PIN0_ADDRESS 0x00000028 +#define GPIO_PIN0_OFFSET 0x00000028 +#define GPIO_PIN0_CONFIG_MSB 12 +#define GPIO_PIN0_CONFIG_LSB 11 +#define GPIO_PIN0_CONFIG_MASK 0x00001800 +#define GPIO_PIN0_CONFIG_GET(x) (((x)&GPIO_PIN0_CONFIG_MASK) >> GPIO_PIN0_CONFIG_LSB) +#define GPIO_PIN0_CONFIG_SET(x) (((x) << GPIO_PIN0_CONFIG_LSB) & GPIO_PIN0_CONFIG_MASK) +#define GPIO_PIN0_WAKEUP_ENABLE_MSB 10 +#define GPIO_PIN0_WAKEUP_ENABLE_LSB 10 +#define GPIO_PIN0_WAKEUP_ENABLE_MASK 0x00000400 +#define GPIO_PIN0_WAKEUP_ENABLE_GET(x) (((x)&GPIO_PIN0_WAKEUP_ENABLE_MASK) >> GPIO_PIN0_WAKEUP_ENABLE_LSB) +#define GPIO_PIN0_WAKEUP_ENABLE_SET(x) (((x) << GPIO_PIN0_WAKEUP_ENABLE_LSB) & GPIO_PIN0_WAKEUP_ENABLE_MASK) +#define GPIO_PIN0_INT_TYPE_MSB 9 +#define GPIO_PIN0_INT_TYPE_LSB 7 +#define GPIO_PIN0_INT_TYPE_MASK 0x00000380 +#define GPIO_PIN0_INT_TYPE_GET(x) (((x)&GPIO_PIN0_INT_TYPE_MASK) >> GPIO_PIN0_INT_TYPE_LSB) +#define GPIO_PIN0_INT_TYPE_SET(x) (((x) << GPIO_PIN0_INT_TYPE_LSB) & GPIO_PIN0_INT_TYPE_MASK) +#define GPIO_PIN0_PAD_DRIVER_MSB 2 +#define GPIO_PIN0_PAD_DRIVER_LSB 2 +#define GPIO_PIN0_PAD_DRIVER_MASK 0x00000004 +#define GPIO_PIN0_PAD_DRIVER_GET(x) (((x)&GPIO_PIN0_PAD_DRIVER_MASK) >> GPIO_PIN0_PAD_DRIVER_LSB) +#define GPIO_PIN0_PAD_DRIVER_SET(x) (((x) << GPIO_PIN0_PAD_DRIVER_LSB) & GPIO_PIN0_PAD_DRIVER_MASK) +#define GPIO_PIN0_SOURCE_MSB 0 +#define GPIO_PIN0_SOURCE_LSB 0 +#define GPIO_PIN0_SOURCE_MASK 0x00000001 +#define GPIO_PIN0_SOURCE_GET(x) (((x)&GPIO_PIN0_SOURCE_MASK) >> GPIO_PIN0_SOURCE_LSB) +#define GPIO_PIN0_SOURCE_SET(x) (((x) << GPIO_PIN0_SOURCE_LSB) & GPIO_PIN0_SOURCE_MASK) + +#define GPIO_PIN1_ADDRESS 0x0000002c +#define GPIO_PIN1_OFFSET 0x0000002c +#define GPIO_PIN1_CONFIG_MSB 12 +#define GPIO_PIN1_CONFIG_LSB 11 +#define GPIO_PIN1_CONFIG_MASK 0x00001800 +#define GPIO_PIN1_CONFIG_GET(x) (((x)&GPIO_PIN1_CONFIG_MASK) >> GPIO_PIN1_CONFIG_LSB) +#define GPIO_PIN1_CONFIG_SET(x) (((x) << GPIO_PIN1_CONFIG_LSB) & GPIO_PIN1_CONFIG_MASK) +#define GPIO_PIN1_WAKEUP_ENABLE_MSB 10 +#define GPIO_PIN1_WAKEUP_ENABLE_LSB 10 +#define GPIO_PIN1_WAKEUP_ENABLE_MASK 0x00000400 +#define GPIO_PIN1_WAKEUP_ENABLE_GET(x) (((x)&GPIO_PIN1_WAKEUP_ENABLE_MASK) >> GPIO_PIN1_WAKEUP_ENABLE_LSB) +#define GPIO_PIN1_WAKEUP_ENABLE_SET(x) (((x) << GPIO_PIN1_WAKEUP_ENABLE_LSB) & GPIO_PIN1_WAKEUP_ENABLE_MASK) +#define GPIO_PIN1_INT_TYPE_MSB 9 +#define GPIO_PIN1_INT_TYPE_LSB 7 +#define GPIO_PIN1_INT_TYPE_MASK 0x00000380 +#define GPIO_PIN1_INT_TYPE_GET(x) (((x)&GPIO_PIN1_INT_TYPE_MASK) >> GPIO_PIN1_INT_TYPE_LSB) +#define GPIO_PIN1_INT_TYPE_SET(x) (((x) << GPIO_PIN1_INT_TYPE_LSB) & GPIO_PIN1_INT_TYPE_MASK) +#define GPIO_PIN1_PAD_DRIVER_MSB 2 +#define GPIO_PIN1_PAD_DRIVER_LSB 2 +#define GPIO_PIN1_PAD_DRIVER_MASK 0x00000004 +#define GPIO_PIN1_PAD_DRIVER_GET(x) (((x)&GPIO_PIN1_PAD_DRIVER_MASK) >> GPIO_PIN1_PAD_DRIVER_LSB) +#define GPIO_PIN1_PAD_DRIVER_SET(x) (((x) << GPIO_PIN1_PAD_DRIVER_LSB) & GPIO_PIN1_PAD_DRIVER_MASK) +#define GPIO_PIN1_SOURCE_MSB 0 +#define GPIO_PIN1_SOURCE_LSB 0 +#define GPIO_PIN1_SOURCE_MASK 0x00000001 +#define GPIO_PIN1_SOURCE_GET(x) (((x)&GPIO_PIN1_SOURCE_MASK) >> GPIO_PIN1_SOURCE_LSB) +#define GPIO_PIN1_SOURCE_SET(x) (((x) << GPIO_PIN1_SOURCE_LSB) & GPIO_PIN1_SOURCE_MASK) + +#define GPIO_PIN2_ADDRESS 0x00000030 +#define GPIO_PIN2_OFFSET 0x00000030 +#define GPIO_PIN2_CONFIG_MSB 12 +#define GPIO_PIN2_CONFIG_LSB 11 +#define GPIO_PIN2_CONFIG_MASK 0x00001800 +#define GPIO_PIN2_CONFIG_GET(x) (((x)&GPIO_PIN2_CONFIG_MASK) >> GPIO_PIN2_CONFIG_LSB) +#define GPIO_PIN2_CONFIG_SET(x) (((x) << GPIO_PIN2_CONFIG_LSB) & GPIO_PIN2_CONFIG_MASK) +#define GPIO_PIN2_WAKEUP_ENABLE_MSB 10 +#define GPIO_PIN2_WAKEUP_ENABLE_LSB 10 +#define GPIO_PIN2_WAKEUP_ENABLE_MASK 0x00000400 +#define GPIO_PIN2_WAKEUP_ENABLE_GET(x) (((x)&GPIO_PIN2_WAKEUP_ENABLE_MASK) >> GPIO_PIN2_WAKEUP_ENABLE_LSB) +#define GPIO_PIN2_WAKEUP_ENABLE_SET(x) (((x) << GPIO_PIN2_WAKEUP_ENABLE_LSB) & GPIO_PIN2_WAKEUP_ENABLE_MASK) +#define GPIO_PIN2_INT_TYPE_MSB 9 +#define GPIO_PIN2_INT_TYPE_LSB 7 +#define GPIO_PIN2_INT_TYPE_MASK 0x00000380 +#define GPIO_PIN2_INT_TYPE_GET(x) (((x)&GPIO_PIN2_INT_TYPE_MASK) >> GPIO_PIN2_INT_TYPE_LSB) +#define GPIO_PIN2_INT_TYPE_SET(x) (((x) << GPIO_PIN2_INT_TYPE_LSB) & GPIO_PIN2_INT_TYPE_MASK) +#define GPIO_PIN2_PAD_DRIVER_MSB 2 +#define GPIO_PIN2_PAD_DRIVER_LSB 2 +#define GPIO_PIN2_PAD_DRIVER_MASK 0x00000004 +#define GPIO_PIN2_PAD_DRIVER_GET(x) (((x)&GPIO_PIN2_PAD_DRIVER_MASK) >> GPIO_PIN2_PAD_DRIVER_LSB) +#define GPIO_PIN2_PAD_DRIVER_SET(x) (((x) << GPIO_PIN2_PAD_DRIVER_LSB) & GPIO_PIN2_PAD_DRIVER_MASK) +#define GPIO_PIN2_SOURCE_MSB 0 +#define GPIO_PIN2_SOURCE_LSB 0 +#define GPIO_PIN2_SOURCE_MASK 0x00000001 +#define GPIO_PIN2_SOURCE_GET(x) (((x)&GPIO_PIN2_SOURCE_MASK) >> GPIO_PIN2_SOURCE_LSB) +#define GPIO_PIN2_SOURCE_SET(x) (((x) << GPIO_PIN2_SOURCE_LSB) & GPIO_PIN2_SOURCE_MASK) + +#define GPIO_PIN3_ADDRESS 0x00000034 +#define GPIO_PIN3_OFFSET 0x00000034 +#define GPIO_PIN3_CONFIG_MSB 12 +#define GPIO_PIN3_CONFIG_LSB 11 +#define GPIO_PIN3_CONFIG_MASK 0x00001800 +#define GPIO_PIN3_CONFIG_GET(x) (((x)&GPIO_PIN3_CONFIG_MASK) >> GPIO_PIN3_CONFIG_LSB) +#define GPIO_PIN3_CONFIG_SET(x) (((x) << GPIO_PIN3_CONFIG_LSB) & GPIO_PIN3_CONFIG_MASK) +#define GPIO_PIN3_WAKEUP_ENABLE_MSB 10 +#define GPIO_PIN3_WAKEUP_ENABLE_LSB 10 +#define GPIO_PIN3_WAKEUP_ENABLE_MASK 0x00000400 +#define GPIO_PIN3_WAKEUP_ENABLE_GET(x) (((x)&GPIO_PIN3_WAKEUP_ENABLE_MASK) >> GPIO_PIN3_WAKEUP_ENABLE_LSB) +#define GPIO_PIN3_WAKEUP_ENABLE_SET(x) (((x) << GPIO_PIN3_WAKEUP_ENABLE_LSB) & GPIO_PIN3_WAKEUP_ENABLE_MASK) +#define GPIO_PIN3_INT_TYPE_MSB 9 +#define GPIO_PIN3_INT_TYPE_LSB 7 +#define GPIO_PIN3_INT_TYPE_MASK 0x00000380 +#define GPIO_PIN3_INT_TYPE_GET(x) (((x)&GPIO_PIN3_INT_TYPE_MASK) >> GPIO_PIN3_INT_TYPE_LSB) +#define GPIO_PIN3_INT_TYPE_SET(x) (((x) << GPIO_PIN3_INT_TYPE_LSB) & GPIO_PIN3_INT_TYPE_MASK) +#define GPIO_PIN3_PAD_DRIVER_MSB 2 +#define GPIO_PIN3_PAD_DRIVER_LSB 2 +#define GPIO_PIN3_PAD_DRIVER_MASK 0x00000004 +#define GPIO_PIN3_PAD_DRIVER_GET(x) (((x)&GPIO_PIN3_PAD_DRIVER_MASK) >> GPIO_PIN3_PAD_DRIVER_LSB) +#define GPIO_PIN3_PAD_DRIVER_SET(x) (((x) << GPIO_PIN3_PAD_DRIVER_LSB) & GPIO_PIN3_PAD_DRIVER_MASK) +#define GPIO_PIN3_SOURCE_MSB 0 +#define GPIO_PIN3_SOURCE_LSB 0 +#define GPIO_PIN3_SOURCE_MASK 0x00000001 +#define GPIO_PIN3_SOURCE_GET(x) (((x)&GPIO_PIN3_SOURCE_MASK) >> GPIO_PIN3_SOURCE_LSB) +#define GPIO_PIN3_SOURCE_SET(x) (((x) << GPIO_PIN3_SOURCE_LSB) & GPIO_PIN3_SOURCE_MASK) + +#define GPIO_PIN4_ADDRESS 0x00000038 +#define GPIO_PIN4_OFFSET 0x00000038 +#define GPIO_PIN4_CONFIG_MSB 12 +#define GPIO_PIN4_CONFIG_LSB 11 +#define GPIO_PIN4_CONFIG_MASK 0x00001800 +#define GPIO_PIN4_CONFIG_GET(x) (((x)&GPIO_PIN4_CONFIG_MASK) >> GPIO_PIN4_CONFIG_LSB) +#define GPIO_PIN4_CONFIG_SET(x) (((x) << GPIO_PIN4_CONFIG_LSB) & GPIO_PIN4_CONFIG_MASK) +#define GPIO_PIN4_WAKEUP_ENABLE_MSB 10 +#define GPIO_PIN4_WAKEUP_ENABLE_LSB 10 +#define GPIO_PIN4_WAKEUP_ENABLE_MASK 0x00000400 +#define GPIO_PIN4_WAKEUP_ENABLE_GET(x) (((x)&GPIO_PIN4_WAKEUP_ENABLE_MASK) >> GPIO_PIN4_WAKEUP_ENABLE_LSB) +#define GPIO_PIN4_WAKEUP_ENABLE_SET(x) (((x) << GPIO_PIN4_WAKEUP_ENABLE_LSB) & GPIO_PIN4_WAKEUP_ENABLE_MASK) +#define GPIO_PIN4_INT_TYPE_MSB 9 +#define GPIO_PIN4_INT_TYPE_LSB 7 +#define GPIO_PIN4_INT_TYPE_MASK 0x00000380 +#define GPIO_PIN4_INT_TYPE_GET(x) (((x)&GPIO_PIN4_INT_TYPE_MASK) >> GPIO_PIN4_INT_TYPE_LSB) +#define GPIO_PIN4_INT_TYPE_SET(x) (((x) << GPIO_PIN4_INT_TYPE_LSB) & GPIO_PIN4_INT_TYPE_MASK) +#define GPIO_PIN4_PAD_DRIVER_MSB 2 +#define GPIO_PIN4_PAD_DRIVER_LSB 2 +#define GPIO_PIN4_PAD_DRIVER_MASK 0x00000004 +#define GPIO_PIN4_PAD_DRIVER_GET(x) (((x)&GPIO_PIN4_PAD_DRIVER_MASK) >> GPIO_PIN4_PAD_DRIVER_LSB) +#define GPIO_PIN4_PAD_DRIVER_SET(x) (((x) << GPIO_PIN4_PAD_DRIVER_LSB) & GPIO_PIN4_PAD_DRIVER_MASK) +#define GPIO_PIN4_SOURCE_MSB 0 +#define GPIO_PIN4_SOURCE_LSB 0 +#define GPIO_PIN4_SOURCE_MASK 0x00000001 +#define GPIO_PIN4_SOURCE_GET(x) (((x)&GPIO_PIN4_SOURCE_MASK) >> GPIO_PIN4_SOURCE_LSB) +#define GPIO_PIN4_SOURCE_SET(x) (((x) << GPIO_PIN4_SOURCE_LSB) & GPIO_PIN4_SOURCE_MASK) + +#define GPIO_PIN5_ADDRESS 0x0000003c +#define GPIO_PIN5_OFFSET 0x0000003c +#define GPIO_PIN5_CONFIG_MSB 12 +#define GPIO_PIN5_CONFIG_LSB 11 +#define GPIO_PIN5_CONFIG_MASK 0x00001800 +#define GPIO_PIN5_CONFIG_GET(x) (((x)&GPIO_PIN5_CONFIG_MASK) >> GPIO_PIN5_CONFIG_LSB) +#define GPIO_PIN5_CONFIG_SET(x) (((x) << GPIO_PIN5_CONFIG_LSB) & GPIO_PIN5_CONFIG_MASK) +#define GPIO_PIN5_WAKEUP_ENABLE_MSB 10 +#define GPIO_PIN5_WAKEUP_ENABLE_LSB 10 +#define GPIO_PIN5_WAKEUP_ENABLE_MASK 0x00000400 +#define GPIO_PIN5_WAKEUP_ENABLE_GET(x) (((x)&GPIO_PIN5_WAKEUP_ENABLE_MASK) >> GPIO_PIN5_WAKEUP_ENABLE_LSB) +#define GPIO_PIN5_WAKEUP_ENABLE_SET(x) (((x) << GPIO_PIN5_WAKEUP_ENABLE_LSB) & GPIO_PIN5_WAKEUP_ENABLE_MASK) +#define GPIO_PIN5_INT_TYPE_MSB 9 +#define GPIO_PIN5_INT_TYPE_LSB 7 +#define GPIO_PIN5_INT_TYPE_MASK 0x00000380 +#define GPIO_PIN5_INT_TYPE_GET(x) (((x)&GPIO_PIN5_INT_TYPE_MASK) >> GPIO_PIN5_INT_TYPE_LSB) +#define GPIO_PIN5_INT_TYPE_SET(x) (((x) << GPIO_PIN5_INT_TYPE_LSB) & GPIO_PIN5_INT_TYPE_MASK) +#define GPIO_PIN5_PAD_DRIVER_MSB 2 +#define GPIO_PIN5_PAD_DRIVER_LSB 2 +#define GPIO_PIN5_PAD_DRIVER_MASK 0x00000004 +#define GPIO_PIN5_PAD_DRIVER_GET(x) (((x)&GPIO_PIN5_PAD_DRIVER_MASK) >> GPIO_PIN5_PAD_DRIVER_LSB) +#define GPIO_PIN5_PAD_DRIVER_SET(x) (((x) << GPIO_PIN5_PAD_DRIVER_LSB) & GPIO_PIN5_PAD_DRIVER_MASK) +#define GPIO_PIN5_SOURCE_MSB 0 +#define GPIO_PIN5_SOURCE_LSB 0 +#define GPIO_PIN5_SOURCE_MASK 0x00000001 +#define GPIO_PIN5_SOURCE_GET(x) (((x)&GPIO_PIN5_SOURCE_MASK) >> GPIO_PIN5_SOURCE_LSB) +#define GPIO_PIN5_SOURCE_SET(x) (((x) << GPIO_PIN5_SOURCE_LSB) & GPIO_PIN5_SOURCE_MASK) + +#define GPIO_PIN6_ADDRESS 0x00000040 +#define GPIO_PIN6_OFFSET 0x00000040 +#define GPIO_PIN6_CONFIG_MSB 12 +#define GPIO_PIN6_CONFIG_LSB 11 +#define GPIO_PIN6_CONFIG_MASK 0x00001800 +#define GPIO_PIN6_CONFIG_GET(x) (((x)&GPIO_PIN6_CONFIG_MASK) >> GPIO_PIN6_CONFIG_LSB) +#define GPIO_PIN6_CONFIG_SET(x) (((x) << GPIO_PIN6_CONFIG_LSB) & GPIO_PIN6_CONFIG_MASK) +#define GPIO_PIN6_WAKEUP_ENABLE_MSB 10 +#define GPIO_PIN6_WAKEUP_ENABLE_LSB 10 +#define GPIO_PIN6_WAKEUP_ENABLE_MASK 0x00000400 +#define GPIO_PIN6_WAKEUP_ENABLE_GET(x) (((x)&GPIO_PIN6_WAKEUP_ENABLE_MASK) >> GPIO_PIN6_WAKEUP_ENABLE_LSB) +#define GPIO_PIN6_WAKEUP_ENABLE_SET(x) (((x) << GPIO_PIN6_WAKEUP_ENABLE_LSB) & GPIO_PIN6_WAKEUP_ENABLE_MASK) +#define GPIO_PIN6_INT_TYPE_MSB 9 +#define GPIO_PIN6_INT_TYPE_LSB 7 +#define GPIO_PIN6_INT_TYPE_MASK 0x00000380 +#define GPIO_PIN6_INT_TYPE_GET(x) (((x)&GPIO_PIN6_INT_TYPE_MASK) >> GPIO_PIN6_INT_TYPE_LSB) +#define GPIO_PIN6_INT_TYPE_SET(x) (((x) << GPIO_PIN6_INT_TYPE_LSB) & GPIO_PIN6_INT_TYPE_MASK) +#define GPIO_PIN6_PAD_DRIVER_MSB 2 +#define GPIO_PIN6_PAD_DRIVER_LSB 2 +#define GPIO_PIN6_PAD_DRIVER_MASK 0x00000004 +#define GPIO_PIN6_PAD_DRIVER_GET(x) (((x)&GPIO_PIN6_PAD_DRIVER_MASK) >> GPIO_PIN6_PAD_DRIVER_LSB) +#define GPIO_PIN6_PAD_DRIVER_SET(x) (((x) << GPIO_PIN6_PAD_DRIVER_LSB) & GPIO_PIN6_PAD_DRIVER_MASK) +#define GPIO_PIN6_SOURCE_MSB 0 +#define GPIO_PIN6_SOURCE_LSB 0 +#define GPIO_PIN6_SOURCE_MASK 0x00000001 +#define GPIO_PIN6_SOURCE_GET(x) (((x)&GPIO_PIN6_SOURCE_MASK) >> GPIO_PIN6_SOURCE_LSB) +#define GPIO_PIN6_SOURCE_SET(x) (((x) << GPIO_PIN6_SOURCE_LSB) & GPIO_PIN6_SOURCE_MASK) + +#define GPIO_PIN7_ADDRESS 0x00000044 +#define GPIO_PIN7_OFFSET 0x00000044 +#define GPIO_PIN7_CONFIG_MSB 12 +#define GPIO_PIN7_CONFIG_LSB 11 +#define GPIO_PIN7_CONFIG_MASK 0x00001800 +#define GPIO_PIN7_CONFIG_GET(x) (((x)&GPIO_PIN7_CONFIG_MASK) >> GPIO_PIN7_CONFIG_LSB) +#define GPIO_PIN7_CONFIG_SET(x) (((x) << GPIO_PIN7_CONFIG_LSB) & GPIO_PIN7_CONFIG_MASK) +#define GPIO_PIN7_WAKEUP_ENABLE_MSB 10 +#define GPIO_PIN7_WAKEUP_ENABLE_LSB 10 +#define GPIO_PIN7_WAKEUP_ENABLE_MASK 0x00000400 +#define GPIO_PIN7_WAKEUP_ENABLE_GET(x) (((x)&GPIO_PIN7_WAKEUP_ENABLE_MASK) >> GPIO_PIN7_WAKEUP_ENABLE_LSB) +#define GPIO_PIN7_WAKEUP_ENABLE_SET(x) (((x) << GPIO_PIN7_WAKEUP_ENABLE_LSB) & GPIO_PIN7_WAKEUP_ENABLE_MASK) +#define GPIO_PIN7_INT_TYPE_MSB 9 +#define GPIO_PIN7_INT_TYPE_LSB 7 +#define GPIO_PIN7_INT_TYPE_MASK 0x00000380 +#define GPIO_PIN7_INT_TYPE_GET(x) (((x)&GPIO_PIN7_INT_TYPE_MASK) >> GPIO_PIN7_INT_TYPE_LSB) +#define GPIO_PIN7_INT_TYPE_SET(x) (((x) << GPIO_PIN7_INT_TYPE_LSB) & GPIO_PIN7_INT_TYPE_MASK) +#define GPIO_PIN7_PAD_DRIVER_MSB 2 +#define GPIO_PIN7_PAD_DRIVER_LSB 2 +#define GPIO_PIN7_PAD_DRIVER_MASK 0x00000004 +#define GPIO_PIN7_PAD_DRIVER_GET(x) (((x)&GPIO_PIN7_PAD_DRIVER_MASK) >> GPIO_PIN7_PAD_DRIVER_LSB) +#define GPIO_PIN7_PAD_DRIVER_SET(x) (((x) << GPIO_PIN7_PAD_DRIVER_LSB) & GPIO_PIN7_PAD_DRIVER_MASK) +#define GPIO_PIN7_SOURCE_MSB 0 +#define GPIO_PIN7_SOURCE_LSB 0 +#define GPIO_PIN7_SOURCE_MASK 0x00000001 +#define GPIO_PIN7_SOURCE_GET(x) (((x)&GPIO_PIN7_SOURCE_MASK) >> GPIO_PIN7_SOURCE_LSB) +#define GPIO_PIN7_SOURCE_SET(x) (((x) << GPIO_PIN7_SOURCE_LSB) & GPIO_PIN7_SOURCE_MASK) + +#define GPIO_PIN8_ADDRESS 0x00000048 +#define GPIO_PIN8_OFFSET 0x00000048 +#define GPIO_PIN8_CONFIG_MSB 12 +#define GPIO_PIN8_CONFIG_LSB 11 +#define GPIO_PIN8_CONFIG_MASK 0x00001800 +#define GPIO_PIN8_CONFIG_GET(x) (((x)&GPIO_PIN8_CONFIG_MASK) >> GPIO_PIN8_CONFIG_LSB) +#define GPIO_PIN8_CONFIG_SET(x) (((x) << GPIO_PIN8_CONFIG_LSB) & GPIO_PIN8_CONFIG_MASK) +#define GPIO_PIN8_WAKEUP_ENABLE_MSB 10 +#define GPIO_PIN8_WAKEUP_ENABLE_LSB 10 +#define GPIO_PIN8_WAKEUP_ENABLE_MASK 0x00000400 +#define GPIO_PIN8_WAKEUP_ENABLE_GET(x) (((x)&GPIO_PIN8_WAKEUP_ENABLE_MASK) >> GPIO_PIN8_WAKEUP_ENABLE_LSB) +#define GPIO_PIN8_WAKEUP_ENABLE_SET(x) (((x) << GPIO_PIN8_WAKEUP_ENABLE_LSB) & GPIO_PIN8_WAKEUP_ENABLE_MASK) +#define GPIO_PIN8_INT_TYPE_MSB 9 +#define GPIO_PIN8_INT_TYPE_LSB 7 +#define GPIO_PIN8_INT_TYPE_MASK 0x00000380 +#define GPIO_PIN8_INT_TYPE_GET(x) (((x)&GPIO_PIN8_INT_TYPE_MASK) >> GPIO_PIN8_INT_TYPE_LSB) +#define GPIO_PIN8_INT_TYPE_SET(x) (((x) << GPIO_PIN8_INT_TYPE_LSB) & GPIO_PIN8_INT_TYPE_MASK) +#define GPIO_PIN8_PAD_DRIVER_MSB 2 +#define GPIO_PIN8_PAD_DRIVER_LSB 2 +#define GPIO_PIN8_PAD_DRIVER_MASK 0x00000004 +#define GPIO_PIN8_PAD_DRIVER_GET(x) (((x)&GPIO_PIN8_PAD_DRIVER_MASK) >> GPIO_PIN8_PAD_DRIVER_LSB) +#define GPIO_PIN8_PAD_DRIVER_SET(x) (((x) << GPIO_PIN8_PAD_DRIVER_LSB) & GPIO_PIN8_PAD_DRIVER_MASK) +#define GPIO_PIN8_SOURCE_MSB 0 +#define GPIO_PIN8_SOURCE_LSB 0 +#define GPIO_PIN8_SOURCE_MASK 0x00000001 +#define GPIO_PIN8_SOURCE_GET(x) (((x)&GPIO_PIN8_SOURCE_MASK) >> GPIO_PIN8_SOURCE_LSB) +#define GPIO_PIN8_SOURCE_SET(x) (((x) << GPIO_PIN8_SOURCE_LSB) & GPIO_PIN8_SOURCE_MASK) + +#define GPIO_PIN9_ADDRESS 0x0000004c +#define GPIO_PIN9_OFFSET 0x0000004c +#define GPIO_PIN9_CONFIG_MSB 12 +#define GPIO_PIN9_CONFIG_LSB 11 +#define GPIO_PIN9_CONFIG_MASK 0x00001800 +#define GPIO_PIN9_CONFIG_GET(x) (((x)&GPIO_PIN9_CONFIG_MASK) >> GPIO_PIN9_CONFIG_LSB) +#define GPIO_PIN9_CONFIG_SET(x) (((x) << GPIO_PIN9_CONFIG_LSB) & GPIO_PIN9_CONFIG_MASK) +#define GPIO_PIN9_WAKEUP_ENABLE_MSB 10 +#define GPIO_PIN9_WAKEUP_ENABLE_LSB 10 +#define GPIO_PIN9_WAKEUP_ENABLE_MASK 0x00000400 +#define GPIO_PIN9_WAKEUP_ENABLE_GET(x) (((x)&GPIO_PIN9_WAKEUP_ENABLE_MASK) >> GPIO_PIN9_WAKEUP_ENABLE_LSB) +#define GPIO_PIN9_WAKEUP_ENABLE_SET(x) (((x) << GPIO_PIN9_WAKEUP_ENABLE_LSB) & GPIO_PIN9_WAKEUP_ENABLE_MASK) +#define GPIO_PIN9_INT_TYPE_MSB 9 +#define GPIO_PIN9_INT_TYPE_LSB 7 +#define GPIO_PIN9_INT_TYPE_MASK 0x00000380 +#define GPIO_PIN9_INT_TYPE_GET(x) (((x)&GPIO_PIN9_INT_TYPE_MASK) >> GPIO_PIN9_INT_TYPE_LSB) +#define GPIO_PIN9_INT_TYPE_SET(x) (((x) << GPIO_PIN9_INT_TYPE_LSB) & GPIO_PIN9_INT_TYPE_MASK) +#define GPIO_PIN9_PAD_DRIVER_MSB 2 +#define GPIO_PIN9_PAD_DRIVER_LSB 2 +#define GPIO_PIN9_PAD_DRIVER_MASK 0x00000004 +#define GPIO_PIN9_PAD_DRIVER_GET(x) (((x)&GPIO_PIN9_PAD_DRIVER_MASK) >> GPIO_PIN9_PAD_DRIVER_LSB) +#define GPIO_PIN9_PAD_DRIVER_SET(x) (((x) << GPIO_PIN9_PAD_DRIVER_LSB) & GPIO_PIN9_PAD_DRIVER_MASK) +#define GPIO_PIN9_SOURCE_MSB 0 +#define GPIO_PIN9_SOURCE_LSB 0 +#define GPIO_PIN9_SOURCE_MASK 0x00000001 +#define GPIO_PIN9_SOURCE_GET(x) (((x)&GPIO_PIN9_SOURCE_MASK) >> GPIO_PIN9_SOURCE_LSB) +#define GPIO_PIN9_SOURCE_SET(x) (((x) << GPIO_PIN9_SOURCE_LSB) & GPIO_PIN9_SOURCE_MASK) + +#define GPIO_PIN10_ADDRESS 0x00000050 +#define GPIO_PIN10_OFFSET 0x00000050 +#define GPIO_PIN10_CONFIG_MSB 12 +#define GPIO_PIN10_CONFIG_LSB 11 +#define GPIO_PIN10_CONFIG_MASK 0x00001800 +#define GPIO_PIN10_CONFIG_GET(x) (((x)&GPIO_PIN10_CONFIG_MASK) >> GPIO_PIN10_CONFIG_LSB) +#define GPIO_PIN10_CONFIG_SET(x) (((x) << GPIO_PIN10_CONFIG_LSB) & GPIO_PIN10_CONFIG_MASK) +#define GPIO_PIN10_WAKEUP_ENABLE_MSB 10 +#define GPIO_PIN10_WAKEUP_ENABLE_LSB 10 +#define GPIO_PIN10_WAKEUP_ENABLE_MASK 0x00000400 +#define GPIO_PIN10_WAKEUP_ENABLE_GET(x) (((x)&GPIO_PIN10_WAKEUP_ENABLE_MASK) >> GPIO_PIN10_WAKEUP_ENABLE_LSB) +#define GPIO_PIN10_WAKEUP_ENABLE_SET(x) (((x) << GPIO_PIN10_WAKEUP_ENABLE_LSB) & GPIO_PIN10_WAKEUP_ENABLE_MASK) +#define GPIO_PIN10_INT_TYPE_MSB 9 +#define GPIO_PIN10_INT_TYPE_LSB 7 +#define GPIO_PIN10_INT_TYPE_MASK 0x00000380 +#define GPIO_PIN10_INT_TYPE_GET(x) (((x)&GPIO_PIN10_INT_TYPE_MASK) >> GPIO_PIN10_INT_TYPE_LSB) +#define GPIO_PIN10_INT_TYPE_SET(x) (((x) << GPIO_PIN10_INT_TYPE_LSB) & GPIO_PIN10_INT_TYPE_MASK) +#define GPIO_PIN10_PAD_DRIVER_MSB 2 +#define GPIO_PIN10_PAD_DRIVER_LSB 2 +#define GPIO_PIN10_PAD_DRIVER_MASK 0x00000004 +#define GPIO_PIN10_PAD_DRIVER_GET(x) (((x)&GPIO_PIN10_PAD_DRIVER_MASK) >> GPIO_PIN10_PAD_DRIVER_LSB) +#define GPIO_PIN10_PAD_DRIVER_SET(x) (((x) << GPIO_PIN10_PAD_DRIVER_LSB) & GPIO_PIN10_PAD_DRIVER_MASK) +#define GPIO_PIN10_SOURCE_MSB 0 +#define GPIO_PIN10_SOURCE_LSB 0 +#define GPIO_PIN10_SOURCE_MASK 0x00000001 +#define GPIO_PIN10_SOURCE_GET(x) (((x)&GPIO_PIN10_SOURCE_MASK) >> GPIO_PIN10_SOURCE_LSB) +#define GPIO_PIN10_SOURCE_SET(x) (((x) << GPIO_PIN10_SOURCE_LSB) & GPIO_PIN10_SOURCE_MASK) + +#define GPIO_PIN11_ADDRESS 0x00000054 +#define GPIO_PIN11_OFFSET 0x00000054 +#define GPIO_PIN11_CONFIG_MSB 12 +#define GPIO_PIN11_CONFIG_LSB 11 +#define GPIO_PIN11_CONFIG_MASK 0x00001800 +#define GPIO_PIN11_CONFIG_GET(x) (((x)&GPIO_PIN11_CONFIG_MASK) >> GPIO_PIN11_CONFIG_LSB) +#define GPIO_PIN11_CONFIG_SET(x) (((x) << GPIO_PIN11_CONFIG_LSB) & GPIO_PIN11_CONFIG_MASK) +#define GPIO_PIN11_WAKEUP_ENABLE_MSB 10 +#define GPIO_PIN11_WAKEUP_ENABLE_LSB 10 +#define GPIO_PIN11_WAKEUP_ENABLE_MASK 0x00000400 +#define GPIO_PIN11_WAKEUP_ENABLE_GET(x) (((x)&GPIO_PIN11_WAKEUP_ENABLE_MASK) >> GPIO_PIN11_WAKEUP_ENABLE_LSB) +#define GPIO_PIN11_WAKEUP_ENABLE_SET(x) (((x) << GPIO_PIN11_WAKEUP_ENABLE_LSB) & GPIO_PIN11_WAKEUP_ENABLE_MASK) +#define GPIO_PIN11_INT_TYPE_MSB 9 +#define GPIO_PIN11_INT_TYPE_LSB 7 +#define GPIO_PIN11_INT_TYPE_MASK 0x00000380 +#define GPIO_PIN11_INT_TYPE_GET(x) (((x)&GPIO_PIN11_INT_TYPE_MASK) >> GPIO_PIN11_INT_TYPE_LSB) +#define GPIO_PIN11_INT_TYPE_SET(x) (((x) << GPIO_PIN11_INT_TYPE_LSB) & GPIO_PIN11_INT_TYPE_MASK) +#define GPIO_PIN11_PAD_DRIVER_MSB 2 +#define GPIO_PIN11_PAD_DRIVER_LSB 2 +#define GPIO_PIN11_PAD_DRIVER_MASK 0x00000004 +#define GPIO_PIN11_PAD_DRIVER_GET(x) (((x)&GPIO_PIN11_PAD_DRIVER_MASK) >> GPIO_PIN11_PAD_DRIVER_LSB) +#define GPIO_PIN11_PAD_DRIVER_SET(x) (((x) << GPIO_PIN11_PAD_DRIVER_LSB) & GPIO_PIN11_PAD_DRIVER_MASK) +#define GPIO_PIN11_SOURCE_MSB 0 +#define GPIO_PIN11_SOURCE_LSB 0 +#define GPIO_PIN11_SOURCE_MASK 0x00000001 +#define GPIO_PIN11_SOURCE_GET(x) (((x)&GPIO_PIN11_SOURCE_MASK) >> GPIO_PIN11_SOURCE_LSB) +#define GPIO_PIN11_SOURCE_SET(x) (((x) << GPIO_PIN11_SOURCE_LSB) & GPIO_PIN11_SOURCE_MASK) + +#define GPIO_PIN12_ADDRESS 0x00000058 +#define GPIO_PIN12_OFFSET 0x00000058 +#define GPIO_PIN12_CONFIG_MSB 12 +#define GPIO_PIN12_CONFIG_LSB 11 +#define GPIO_PIN12_CONFIG_MASK 0x00001800 +#define GPIO_PIN12_CONFIG_GET(x) (((x)&GPIO_PIN12_CONFIG_MASK) >> GPIO_PIN12_CONFIG_LSB) +#define GPIO_PIN12_CONFIG_SET(x) (((x) << GPIO_PIN12_CONFIG_LSB) & GPIO_PIN12_CONFIG_MASK) +#define GPIO_PIN12_WAKEUP_ENABLE_MSB 10 +#define GPIO_PIN12_WAKEUP_ENABLE_LSB 10 +#define GPIO_PIN12_WAKEUP_ENABLE_MASK 0x00000400 +#define GPIO_PIN12_WAKEUP_ENABLE_GET(x) (((x)&GPIO_PIN12_WAKEUP_ENABLE_MASK) >> GPIO_PIN12_WAKEUP_ENABLE_LSB) +#define GPIO_PIN12_WAKEUP_ENABLE_SET(x) (((x) << GPIO_PIN12_WAKEUP_ENABLE_LSB) & GPIO_PIN12_WAKEUP_ENABLE_MASK) +#define GPIO_PIN12_INT_TYPE_MSB 9 +#define GPIO_PIN12_INT_TYPE_LSB 7 +#define GPIO_PIN12_INT_TYPE_MASK 0x00000380 +#define GPIO_PIN12_INT_TYPE_GET(x) (((x)&GPIO_PIN12_INT_TYPE_MASK) >> GPIO_PIN12_INT_TYPE_LSB) +#define GPIO_PIN12_INT_TYPE_SET(x) (((x) << GPIO_PIN12_INT_TYPE_LSB) & GPIO_PIN12_INT_TYPE_MASK) +#define GPIO_PIN12_PAD_DRIVER_MSB 2 +#define GPIO_PIN12_PAD_DRIVER_LSB 2 +#define GPIO_PIN12_PAD_DRIVER_MASK 0x00000004 +#define GPIO_PIN12_PAD_DRIVER_GET(x) (((x)&GPIO_PIN12_PAD_DRIVER_MASK) >> GPIO_PIN12_PAD_DRIVER_LSB) +#define GPIO_PIN12_PAD_DRIVER_SET(x) (((x) << GPIO_PIN12_PAD_DRIVER_LSB) & GPIO_PIN12_PAD_DRIVER_MASK) +#define GPIO_PIN12_SOURCE_MSB 0 +#define GPIO_PIN12_SOURCE_LSB 0 +#define GPIO_PIN12_SOURCE_MASK 0x00000001 +#define GPIO_PIN12_SOURCE_GET(x) (((x)&GPIO_PIN12_SOURCE_MASK) >> GPIO_PIN12_SOURCE_LSB) +#define GPIO_PIN12_SOURCE_SET(x) (((x) << GPIO_PIN12_SOURCE_LSB) & GPIO_PIN12_SOURCE_MASK) + +#define GPIO_PIN13_ADDRESS 0x0000005c +#define GPIO_PIN13_OFFSET 0x0000005c +#define GPIO_PIN13_CONFIG_MSB 12 +#define GPIO_PIN13_CONFIG_LSB 11 +#define GPIO_PIN13_CONFIG_MASK 0x00001800 +#define GPIO_PIN13_CONFIG_GET(x) (((x)&GPIO_PIN13_CONFIG_MASK) >> GPIO_PIN13_CONFIG_LSB) +#define GPIO_PIN13_CONFIG_SET(x) (((x) << GPIO_PIN13_CONFIG_LSB) & GPIO_PIN13_CONFIG_MASK) +#define GPIO_PIN13_WAKEUP_ENABLE_MSB 10 +#define GPIO_PIN13_WAKEUP_ENABLE_LSB 10 +#define GPIO_PIN13_WAKEUP_ENABLE_MASK 0x00000400 +#define GPIO_PIN13_WAKEUP_ENABLE_GET(x) (((x)&GPIO_PIN13_WAKEUP_ENABLE_MASK) >> GPIO_PIN13_WAKEUP_ENABLE_LSB) +#define GPIO_PIN13_WAKEUP_ENABLE_SET(x) (((x) << GPIO_PIN13_WAKEUP_ENABLE_LSB) & GPIO_PIN13_WAKEUP_ENABLE_MASK) +#define GPIO_PIN13_INT_TYPE_MSB 9 +#define GPIO_PIN13_INT_TYPE_LSB 7 +#define GPIO_PIN13_INT_TYPE_MASK 0x00000380 +#define GPIO_PIN13_INT_TYPE_GET(x) (((x)&GPIO_PIN13_INT_TYPE_MASK) >> GPIO_PIN13_INT_TYPE_LSB) +#define GPIO_PIN13_INT_TYPE_SET(x) (((x) << GPIO_PIN13_INT_TYPE_LSB) & GPIO_PIN13_INT_TYPE_MASK) +#define GPIO_PIN13_PAD_DRIVER_MSB 2 +#define GPIO_PIN13_PAD_DRIVER_LSB 2 +#define GPIO_PIN13_PAD_DRIVER_MASK 0x00000004 +#define GPIO_PIN13_PAD_DRIVER_GET(x) (((x)&GPIO_PIN13_PAD_DRIVER_MASK) >> GPIO_PIN13_PAD_DRIVER_LSB) +#define GPIO_PIN13_PAD_DRIVER_SET(x) (((x) << GPIO_PIN13_PAD_DRIVER_LSB) & GPIO_PIN13_PAD_DRIVER_MASK) +#define GPIO_PIN13_SOURCE_MSB 0 +#define GPIO_PIN13_SOURCE_LSB 0 +#define GPIO_PIN13_SOURCE_MASK 0x00000001 +#define GPIO_PIN13_SOURCE_GET(x) (((x)&GPIO_PIN13_SOURCE_MASK) >> GPIO_PIN13_SOURCE_LSB) +#define GPIO_PIN13_SOURCE_SET(x) (((x) << GPIO_PIN13_SOURCE_LSB) & GPIO_PIN13_SOURCE_MASK) + +#define GPIO_PIN14_ADDRESS 0x00000060 +#define GPIO_PIN14_OFFSET 0x00000060 +#define GPIO_PIN14_CONFIG_MSB 12 +#define GPIO_PIN14_CONFIG_LSB 11 +#define GPIO_PIN14_CONFIG_MASK 0x00001800 +#define GPIO_PIN14_CONFIG_GET(x) (((x)&GPIO_PIN14_CONFIG_MASK) >> GPIO_PIN14_CONFIG_LSB) +#define GPIO_PIN14_CONFIG_SET(x) (((x) << GPIO_PIN14_CONFIG_LSB) & GPIO_PIN14_CONFIG_MASK) +#define GPIO_PIN14_WAKEUP_ENABLE_MSB 10 +#define GPIO_PIN14_WAKEUP_ENABLE_LSB 10 +#define GPIO_PIN14_WAKEUP_ENABLE_MASK 0x00000400 +#define GPIO_PIN14_WAKEUP_ENABLE_GET(x) (((x)&GPIO_PIN14_WAKEUP_ENABLE_MASK) >> GPIO_PIN14_WAKEUP_ENABLE_LSB) +#define GPIO_PIN14_WAKEUP_ENABLE_SET(x) (((x) << GPIO_PIN14_WAKEUP_ENABLE_LSB) & GPIO_PIN14_WAKEUP_ENABLE_MASK) +#define GPIO_PIN14_INT_TYPE_MSB 9 +#define GPIO_PIN14_INT_TYPE_LSB 7 +#define GPIO_PIN14_INT_TYPE_MASK 0x00000380 +#define GPIO_PIN14_INT_TYPE_GET(x) (((x)&GPIO_PIN14_INT_TYPE_MASK) >> GPIO_PIN14_INT_TYPE_LSB) +#define GPIO_PIN14_INT_TYPE_SET(x) (((x) << GPIO_PIN14_INT_TYPE_LSB) & GPIO_PIN14_INT_TYPE_MASK) +#define GPIO_PIN14_PAD_DRIVER_MSB 2 +#define GPIO_PIN14_PAD_DRIVER_LSB 2 +#define GPIO_PIN14_PAD_DRIVER_MASK 0x00000004 +#define GPIO_PIN14_PAD_DRIVER_GET(x) (((x)&GPIO_PIN14_PAD_DRIVER_MASK) >> GPIO_PIN14_PAD_DRIVER_LSB) +#define GPIO_PIN14_PAD_DRIVER_SET(x) (((x) << GPIO_PIN14_PAD_DRIVER_LSB) & GPIO_PIN14_PAD_DRIVER_MASK) +#define GPIO_PIN14_SOURCE_MSB 0 +#define GPIO_PIN14_SOURCE_LSB 0 +#define GPIO_PIN14_SOURCE_MASK 0x00000001 +#define GPIO_PIN14_SOURCE_GET(x) (((x)&GPIO_PIN14_SOURCE_MASK) >> GPIO_PIN14_SOURCE_LSB) +#define GPIO_PIN14_SOURCE_SET(x) (((x) << GPIO_PIN14_SOURCE_LSB) & GPIO_PIN14_SOURCE_MASK) + +#define GPIO_PIN15_ADDRESS 0x00000064 +#define GPIO_PIN15_OFFSET 0x00000064 +#define GPIO_PIN15_CONFIG_MSB 12 +#define GPIO_PIN15_CONFIG_LSB 11 +#define GPIO_PIN15_CONFIG_MASK 0x00001800 +#define GPIO_PIN15_CONFIG_GET(x) (((x)&GPIO_PIN15_CONFIG_MASK) >> GPIO_PIN15_CONFIG_LSB) +#define GPIO_PIN15_CONFIG_SET(x) (((x) << GPIO_PIN15_CONFIG_LSB) & GPIO_PIN15_CONFIG_MASK) +#define GPIO_PIN15_WAKEUP_ENABLE_MSB 10 +#define GPIO_PIN15_WAKEUP_ENABLE_LSB 10 +#define GPIO_PIN15_WAKEUP_ENABLE_MASK 0x00000400 +#define GPIO_PIN15_WAKEUP_ENABLE_GET(x) (((x)&GPIO_PIN15_WAKEUP_ENABLE_MASK) >> GPIO_PIN15_WAKEUP_ENABLE_LSB) +#define GPIO_PIN15_WAKEUP_ENABLE_SET(x) (((x) << GPIO_PIN15_WAKEUP_ENABLE_LSB) & GPIO_PIN15_WAKEUP_ENABLE_MASK) +#define GPIO_PIN15_INT_TYPE_MSB 9 +#define GPIO_PIN15_INT_TYPE_LSB 7 +#define GPIO_PIN15_INT_TYPE_MASK 0x00000380 +#define GPIO_PIN15_INT_TYPE_GET(x) (((x)&GPIO_PIN15_INT_TYPE_MASK) >> GPIO_PIN15_INT_TYPE_LSB) +#define GPIO_PIN15_INT_TYPE_SET(x) (((x) << GPIO_PIN15_INT_TYPE_LSB) & GPIO_PIN15_INT_TYPE_MASK) +#define GPIO_PIN15_PAD_DRIVER_MSB 2 +#define GPIO_PIN15_PAD_DRIVER_LSB 2 +#define GPIO_PIN15_PAD_DRIVER_MASK 0x00000004 +#define GPIO_PIN15_PAD_DRIVER_GET(x) (((x)&GPIO_PIN15_PAD_DRIVER_MASK) >> GPIO_PIN15_PAD_DRIVER_LSB) +#define GPIO_PIN15_PAD_DRIVER_SET(x) (((x) << GPIO_PIN15_PAD_DRIVER_LSB) & GPIO_PIN15_PAD_DRIVER_MASK) +#define GPIO_PIN15_SOURCE_MSB 0 +#define GPIO_PIN15_SOURCE_LSB 0 +#define GPIO_PIN15_SOURCE_MASK 0x00000001 +#define GPIO_PIN15_SOURCE_GET(x) (((x)&GPIO_PIN15_SOURCE_MASK) >> GPIO_PIN15_SOURCE_LSB) +#define GPIO_PIN15_SOURCE_SET(x) (((x) << GPIO_PIN15_SOURCE_LSB) & GPIO_PIN15_SOURCE_MASK) + +#define GPIO_PIN16_ADDRESS 0x00000068 +#define GPIO_PIN16_OFFSET 0x00000068 +#define GPIO_PIN16_CONFIG_MSB 12 +#define GPIO_PIN16_CONFIG_LSB 11 +#define GPIO_PIN16_CONFIG_MASK 0x00001800 +#define GPIO_PIN16_CONFIG_GET(x) (((x)&GPIO_PIN16_CONFIG_MASK) >> GPIO_PIN16_CONFIG_LSB) +#define GPIO_PIN16_CONFIG_SET(x) (((x) << GPIO_PIN16_CONFIG_LSB) & GPIO_PIN16_CONFIG_MASK) +#define GPIO_PIN16_WAKEUP_ENABLE_MSB 10 +#define GPIO_PIN16_WAKEUP_ENABLE_LSB 10 +#define GPIO_PIN16_WAKEUP_ENABLE_MASK 0x00000400 +#define GPIO_PIN16_WAKEUP_ENABLE_GET(x) (((x)&GPIO_PIN16_WAKEUP_ENABLE_MASK) >> GPIO_PIN16_WAKEUP_ENABLE_LSB) +#define GPIO_PIN16_WAKEUP_ENABLE_SET(x) (((x) << GPIO_PIN16_WAKEUP_ENABLE_LSB) & GPIO_PIN16_WAKEUP_ENABLE_MASK) +#define GPIO_PIN16_INT_TYPE_MSB 9 +#define GPIO_PIN16_INT_TYPE_LSB 7 +#define GPIO_PIN16_INT_TYPE_MASK 0x00000380 +#define GPIO_PIN16_INT_TYPE_GET(x) (((x)&GPIO_PIN16_INT_TYPE_MASK) >> GPIO_PIN16_INT_TYPE_LSB) +#define GPIO_PIN16_INT_TYPE_SET(x) (((x) << GPIO_PIN16_INT_TYPE_LSB) & GPIO_PIN16_INT_TYPE_MASK) +#define GPIO_PIN16_PAD_DRIVER_MSB 2 +#define GPIO_PIN16_PAD_DRIVER_LSB 2 +#define GPIO_PIN16_PAD_DRIVER_MASK 0x00000004 +#define GPIO_PIN16_PAD_DRIVER_GET(x) (((x)&GPIO_PIN16_PAD_DRIVER_MASK) >> GPIO_PIN16_PAD_DRIVER_LSB) +#define GPIO_PIN16_PAD_DRIVER_SET(x) (((x) << GPIO_PIN16_PAD_DRIVER_LSB) & GPIO_PIN16_PAD_DRIVER_MASK) +#define GPIO_PIN16_SOURCE_MSB 0 +#define GPIO_PIN16_SOURCE_LSB 0 +#define GPIO_PIN16_SOURCE_MASK 0x00000001 +#define GPIO_PIN16_SOURCE_GET(x) (((x)&GPIO_PIN16_SOURCE_MASK) >> GPIO_PIN16_SOURCE_LSB) +#define GPIO_PIN16_SOURCE_SET(x) (((x) << GPIO_PIN16_SOURCE_LSB) & GPIO_PIN16_SOURCE_MASK) + +#define GPIO_PIN17_ADDRESS 0x0000006c +#define GPIO_PIN17_OFFSET 0x0000006c +#define GPIO_PIN17_CONFIG_MSB 12 +#define GPIO_PIN17_CONFIG_LSB 11 +#define GPIO_PIN17_CONFIG_MASK 0x00001800 +#define GPIO_PIN17_CONFIG_GET(x) (((x)&GPIO_PIN17_CONFIG_MASK) >> GPIO_PIN17_CONFIG_LSB) +#define GPIO_PIN17_CONFIG_SET(x) (((x) << GPIO_PIN17_CONFIG_LSB) & GPIO_PIN17_CONFIG_MASK) +#define GPIO_PIN17_WAKEUP_ENABLE_MSB 10 +#define GPIO_PIN17_WAKEUP_ENABLE_LSB 10 +#define GPIO_PIN17_WAKEUP_ENABLE_MASK 0x00000400 +#define GPIO_PIN17_WAKEUP_ENABLE_GET(x) (((x)&GPIO_PIN17_WAKEUP_ENABLE_MASK) >> GPIO_PIN17_WAKEUP_ENABLE_LSB) +#define GPIO_PIN17_WAKEUP_ENABLE_SET(x) (((x) << GPIO_PIN17_WAKEUP_ENABLE_LSB) & GPIO_PIN17_WAKEUP_ENABLE_MASK) +#define GPIO_PIN17_INT_TYPE_MSB 9 +#define GPIO_PIN17_INT_TYPE_LSB 7 +#define GPIO_PIN17_INT_TYPE_MASK 0x00000380 +#define GPIO_PIN17_INT_TYPE_GET(x) (((x)&GPIO_PIN17_INT_TYPE_MASK) >> GPIO_PIN17_INT_TYPE_LSB) +#define GPIO_PIN17_INT_TYPE_SET(x) (((x) << GPIO_PIN17_INT_TYPE_LSB) & GPIO_PIN17_INT_TYPE_MASK) +#define GPIO_PIN17_PAD_DRIVER_MSB 2 +#define GPIO_PIN17_PAD_DRIVER_LSB 2 +#define GPIO_PIN17_PAD_DRIVER_MASK 0x00000004 +#define GPIO_PIN17_PAD_DRIVER_GET(x) (((x)&GPIO_PIN17_PAD_DRIVER_MASK) >> GPIO_PIN17_PAD_DRIVER_LSB) +#define GPIO_PIN17_PAD_DRIVER_SET(x) (((x) << GPIO_PIN17_PAD_DRIVER_LSB) & GPIO_PIN17_PAD_DRIVER_MASK) +#define GPIO_PIN17_SOURCE_MSB 0 +#define GPIO_PIN17_SOURCE_LSB 0 +#define GPIO_PIN17_SOURCE_MASK 0x00000001 +#define GPIO_PIN17_SOURCE_GET(x) (((x)&GPIO_PIN17_SOURCE_MASK) >> GPIO_PIN17_SOURCE_LSB) +#define GPIO_PIN17_SOURCE_SET(x) (((x) << GPIO_PIN17_SOURCE_LSB) & GPIO_PIN17_SOURCE_MASK) + +#define SDIO_PIN_ADDRESS 0x00000070 +#define SDIO_PIN_OFFSET 0x00000070 +#define SDIO_PIN_PAD_PULL_MSB 3 +#define SDIO_PIN_PAD_PULL_LSB 2 +#define SDIO_PIN_PAD_PULL_MASK 0x0000000c +#define SDIO_PIN_PAD_PULL_GET(x) (((x)&SDIO_PIN_PAD_PULL_MASK) >> SDIO_PIN_PAD_PULL_LSB) +#define SDIO_PIN_PAD_PULL_SET(x) (((x) << SDIO_PIN_PAD_PULL_LSB) & SDIO_PIN_PAD_PULL_MASK) +#define SDIO_PIN_PAD_STRENGTH_MSB 1 +#define SDIO_PIN_PAD_STRENGTH_LSB 0 +#define SDIO_PIN_PAD_STRENGTH_MASK 0x00000003 +#define SDIO_PIN_PAD_STRENGTH_GET(x) (((x)&SDIO_PIN_PAD_STRENGTH_MASK) >> SDIO_PIN_PAD_STRENGTH_LSB) +#define SDIO_PIN_PAD_STRENGTH_SET(x) (((x) << SDIO_PIN_PAD_STRENGTH_LSB) & SDIO_PIN_PAD_STRENGTH_MASK) + +#define CLK_REQ_PIN_ADDRESS 0x00000074 +#define CLK_REQ_PIN_OFFSET 0x00000074 +#define CLK_REQ_PIN_PAD_PULL_MSB 3 +#define CLK_REQ_PIN_PAD_PULL_LSB 2 +#define CLK_REQ_PIN_PAD_PULL_MASK 0x0000000c +#define CLK_REQ_PIN_PAD_PULL_GET(x) (((x)&CLK_REQ_PIN_PAD_PULL_MASK) >> CLK_REQ_PIN_PAD_PULL_LSB) +#define CLK_REQ_PIN_PAD_PULL_SET(x) (((x) << CLK_REQ_PIN_PAD_PULL_LSB) & CLK_REQ_PIN_PAD_PULL_MASK) +#define CLK_REQ_PIN_PAD_STRENGTH_MSB 1 +#define CLK_REQ_PIN_PAD_STRENGTH_LSB 0 +#define CLK_REQ_PIN_PAD_STRENGTH_MASK 0x00000003 +#define CLK_REQ_PIN_PAD_STRENGTH_GET(x) (((x)&CLK_REQ_PIN_PAD_STRENGTH_MASK) >> CLK_REQ_PIN_PAD_STRENGTH_LSB) +#define CLK_REQ_PIN_PAD_STRENGTH_SET(x) (((x) << CLK_REQ_PIN_PAD_STRENGTH_LSB) & CLK_REQ_PIN_PAD_STRENGTH_MASK) + +#define SIGMA_DELTA_ADDRESS 0x00000078 +#define SIGMA_DELTA_OFFSET 0x00000078 +#define SIGMA_DELTA_ENABLE_MSB 16 +#define SIGMA_DELTA_ENABLE_LSB 16 +#define SIGMA_DELTA_ENABLE_MASK 0x00010000 +#define SIGMA_DELTA_ENABLE_GET(x) (((x)&SIGMA_DELTA_ENABLE_MASK) >> SIGMA_DELTA_ENABLE_LSB) +#define SIGMA_DELTA_ENABLE_SET(x) (((x) << SIGMA_DELTA_ENABLE_LSB) & SIGMA_DELTA_ENABLE_MASK) +#define SIGMA_DELTA_PRESCALAR_MSB 15 +#define SIGMA_DELTA_PRESCALAR_LSB 8 +#define SIGMA_DELTA_PRESCALAR_MASK 0x0000ff00 +#define SIGMA_DELTA_PRESCALAR_GET(x) (((x)&SIGMA_DELTA_PRESCALAR_MASK) >> SIGMA_DELTA_PRESCALAR_LSB) +#define SIGMA_DELTA_PRESCALAR_SET(x) (((x) << SIGMA_DELTA_PRESCALAR_LSB) & SIGMA_DELTA_PRESCALAR_MASK) +#define SIGMA_DELTA_TARGET_MSB 7 +#define SIGMA_DELTA_TARGET_LSB 0 +#define SIGMA_DELTA_TARGET_MASK 0x000000ff +#define SIGMA_DELTA_TARGET_GET(x) (((x)&SIGMA_DELTA_TARGET_MASK) >> SIGMA_DELTA_TARGET_LSB) +#define SIGMA_DELTA_TARGET_SET(x) (((x) << SIGMA_DELTA_TARGET_LSB) & SIGMA_DELTA_TARGET_MASK) + +#define DEBUG_CONTROL_ADDRESS 0x0000007c +#define DEBUG_CONTROL_OFFSET 0x0000007c +#define DEBUG_CONTROL_OBS_OE_L_MSB 1 +#define DEBUG_CONTROL_OBS_OE_L_LSB 1 +#define DEBUG_CONTROL_OBS_OE_L_MASK 0x00000002 +#define DEBUG_CONTROL_OBS_OE_L_GET(x) (((x)&DEBUG_CONTROL_OBS_OE_L_MASK) >> DEBUG_CONTROL_OBS_OE_L_LSB) +#define DEBUG_CONTROL_OBS_OE_L_SET(x) (((x) << DEBUG_CONTROL_OBS_OE_L_LSB) & DEBUG_CONTROL_OBS_OE_L_MASK) +#define DEBUG_CONTROL_ENABLE_MSB 0 +#define DEBUG_CONTROL_ENABLE_LSB 0 +#define DEBUG_CONTROL_ENABLE_MASK 0x00000001 +#define DEBUG_CONTROL_ENABLE_GET(x) (((x)&DEBUG_CONTROL_ENABLE_MASK) >> DEBUG_CONTROL_ENABLE_LSB) +#define DEBUG_CONTROL_ENABLE_SET(x) (((x) << DEBUG_CONTROL_ENABLE_LSB) & DEBUG_CONTROL_ENABLE_MASK) + +#define DEBUG_INPUT_SEL_ADDRESS 0x00000080 +#define DEBUG_INPUT_SEL_OFFSET 0x00000080 +#define DEBUG_INPUT_SEL_SRC_MSB 3 +#define DEBUG_INPUT_SEL_SRC_LSB 0 +#define DEBUG_INPUT_SEL_SRC_MASK 0x0000000f +#define DEBUG_INPUT_SEL_SRC_GET(x) (((x)&DEBUG_INPUT_SEL_SRC_MASK) >> DEBUG_INPUT_SEL_SRC_LSB) +#define DEBUG_INPUT_SEL_SRC_SET(x) (((x) << DEBUG_INPUT_SEL_SRC_LSB) & DEBUG_INPUT_SEL_SRC_MASK) + +#define DEBUG_OUT_ADDRESS 0x00000084 +#define DEBUG_OUT_OFFSET 0x00000084 +#define DEBUG_OUT_DATA_MSB 17 +#define DEBUG_OUT_DATA_LSB 0 +#define DEBUG_OUT_DATA_MASK 0x0003ffff +#define DEBUG_OUT_DATA_GET(x) (((x)&DEBUG_OUT_DATA_MASK) >> DEBUG_OUT_DATA_LSB) +#define DEBUG_OUT_DATA_SET(x) (((x) << DEBUG_OUT_DATA_LSB) & DEBUG_OUT_DATA_MASK) + +#define LA_CONTROL_ADDRESS 0x00000088 +#define LA_CONTROL_OFFSET 0x00000088 +#define LA_CONTROL_RUN_MSB 1 +#define LA_CONTROL_RUN_LSB 1 +#define LA_CONTROL_RUN_MASK 0x00000002 +#define LA_CONTROL_RUN_GET(x) (((x)&LA_CONTROL_RUN_MASK) >> LA_CONTROL_RUN_LSB) +#define LA_CONTROL_RUN_SET(x) (((x) << LA_CONTROL_RUN_LSB) & LA_CONTROL_RUN_MASK) +#define LA_CONTROL_TRIGGERED_MSB 0 +#define LA_CONTROL_TRIGGERED_LSB 0 +#define LA_CONTROL_TRIGGERED_MASK 0x00000001 +#define LA_CONTROL_TRIGGERED_GET(x) (((x)&LA_CONTROL_TRIGGERED_MASK) >> LA_CONTROL_TRIGGERED_LSB) +#define LA_CONTROL_TRIGGERED_SET(x) (((x) << LA_CONTROL_TRIGGERED_LSB) & LA_CONTROL_TRIGGERED_MASK) + +#define LA_CLOCK_ADDRESS 0x0000008c +#define LA_CLOCK_OFFSET 0x0000008c +#define LA_CLOCK_DIV_MSB 7 +#define LA_CLOCK_DIV_LSB 0 +#define LA_CLOCK_DIV_MASK 0x000000ff +#define LA_CLOCK_DIV_GET(x) (((x)&LA_CLOCK_DIV_MASK) >> LA_CLOCK_DIV_LSB) +#define LA_CLOCK_DIV_SET(x) (((x) << LA_CLOCK_DIV_LSB) & LA_CLOCK_DIV_MASK) + +#define LA_STATUS_ADDRESS 0x00000090 +#define LA_STATUS_OFFSET 0x00000090 +#define LA_STATUS_INTERRUPT_MSB 0 +#define LA_STATUS_INTERRUPT_LSB 0 +#define LA_STATUS_INTERRUPT_MASK 0x00000001 +#define LA_STATUS_INTERRUPT_GET(x) (((x)&LA_STATUS_INTERRUPT_MASK) >> LA_STATUS_INTERRUPT_LSB) +#define LA_STATUS_INTERRUPT_SET(x) (((x) << LA_STATUS_INTERRUPT_LSB) & LA_STATUS_INTERRUPT_MASK) + +#define LA_TRIGGER_SAMPLE_ADDRESS 0x00000094 +#define LA_TRIGGER_SAMPLE_OFFSET 0x00000094 +#define LA_TRIGGER_SAMPLE_COUNT_MSB 15 +#define LA_TRIGGER_SAMPLE_COUNT_LSB 0 +#define LA_TRIGGER_SAMPLE_COUNT_MASK 0x0000ffff +#define LA_TRIGGER_SAMPLE_COUNT_GET(x) (((x)&LA_TRIGGER_SAMPLE_COUNT_MASK) >> LA_TRIGGER_SAMPLE_COUNT_LSB) +#define LA_TRIGGER_SAMPLE_COUNT_SET(x) (((x) << LA_TRIGGER_SAMPLE_COUNT_LSB) & LA_TRIGGER_SAMPLE_COUNT_MASK) + +#define LA_TRIGGER_POSITION_ADDRESS 0x00000098 +#define LA_TRIGGER_POSITION_OFFSET 0x00000098 +#define LA_TRIGGER_POSITION_VALUE_MSB 15 +#define LA_TRIGGER_POSITION_VALUE_LSB 0 +#define LA_TRIGGER_POSITION_VALUE_MASK 0x0000ffff +#define LA_TRIGGER_POSITION_VALUE_GET(x) (((x)&LA_TRIGGER_POSITION_VALUE_MASK) >> LA_TRIGGER_POSITION_VALUE_LSB) +#define LA_TRIGGER_POSITION_VALUE_SET(x) (((x) << LA_TRIGGER_POSITION_VALUE_LSB) & LA_TRIGGER_POSITION_VALUE_MASK) + +#define LA_PRE_TRIGGER_ADDRESS 0x0000009c +#define LA_PRE_TRIGGER_OFFSET 0x0000009c +#define LA_PRE_TRIGGER_COUNT_MSB 15 +#define LA_PRE_TRIGGER_COUNT_LSB 0 +#define LA_PRE_TRIGGER_COUNT_MASK 0x0000ffff +#define LA_PRE_TRIGGER_COUNT_GET(x) (((x)&LA_PRE_TRIGGER_COUNT_MASK) >> LA_PRE_TRIGGER_COUNT_LSB) +#define LA_PRE_TRIGGER_COUNT_SET(x) (((x) << LA_PRE_TRIGGER_COUNT_LSB) & LA_PRE_TRIGGER_COUNT_MASK) + +#define LA_POST_TRIGGER_ADDRESS 0x000000a0 +#define LA_POST_TRIGGER_OFFSET 0x000000a0 +#define LA_POST_TRIGGER_COUNT_MSB 15 +#define LA_POST_TRIGGER_COUNT_LSB 0 +#define LA_POST_TRIGGER_COUNT_MASK 0x0000ffff +#define LA_POST_TRIGGER_COUNT_GET(x) (((x)&LA_POST_TRIGGER_COUNT_MASK) >> LA_POST_TRIGGER_COUNT_LSB) +#define LA_POST_TRIGGER_COUNT_SET(x) (((x) << LA_POST_TRIGGER_COUNT_LSB) & LA_POST_TRIGGER_COUNT_MASK) + +#define LA_FILTER_CONTROL_ADDRESS 0x000000a4 +#define LA_FILTER_CONTROL_OFFSET 0x000000a4 +#define LA_FILTER_CONTROL_DELTA_MSB 0 +#define LA_FILTER_CONTROL_DELTA_LSB 0 +#define LA_FILTER_CONTROL_DELTA_MASK 0x00000001 +#define LA_FILTER_CONTROL_DELTA_GET(x) (((x)&LA_FILTER_CONTROL_DELTA_MASK) >> LA_FILTER_CONTROL_DELTA_LSB) +#define LA_FILTER_CONTROL_DELTA_SET(x) (((x) << LA_FILTER_CONTROL_DELTA_LSB) & LA_FILTER_CONTROL_DELTA_MASK) + +#define LA_FILTER_DATA_ADDRESS 0x000000a8 +#define LA_FILTER_DATA_OFFSET 0x000000a8 +#define LA_FILTER_DATA_MATCH_MSB 17 +#define LA_FILTER_DATA_MATCH_LSB 0 +#define LA_FILTER_DATA_MATCH_MASK 0x0003ffff +#define LA_FILTER_DATA_MATCH_GET(x) (((x)&LA_FILTER_DATA_MATCH_MASK) >> LA_FILTER_DATA_MATCH_LSB) +#define LA_FILTER_DATA_MATCH_SET(x) (((x) << LA_FILTER_DATA_MATCH_LSB) & LA_FILTER_DATA_MATCH_MASK) + +#define LA_FILTER_WILDCARD_ADDRESS 0x000000ac +#define LA_FILTER_WILDCARD_OFFSET 0x000000ac +#define LA_FILTER_WILDCARD_MATCH_MSB 17 +#define LA_FILTER_WILDCARD_MATCH_LSB 0 +#define LA_FILTER_WILDCARD_MATCH_MASK 0x0003ffff +#define LA_FILTER_WILDCARD_MATCH_GET(x) (((x)&LA_FILTER_WILDCARD_MATCH_MASK) >> LA_FILTER_WILDCARD_MATCH_LSB) +#define LA_FILTER_WILDCARD_MATCH_SET(x) (((x) << LA_FILTER_WILDCARD_MATCH_LSB) & LA_FILTER_WILDCARD_MATCH_MASK) + +#define LA_TRIGGERA_DATA_ADDRESS 0x000000b0 +#define LA_TRIGGERA_DATA_OFFSET 0x000000b0 +#define LA_TRIGGERA_DATA_MATCH_MSB 17 +#define LA_TRIGGERA_DATA_MATCH_LSB 0 +#define LA_TRIGGERA_DATA_MATCH_MASK 0x0003ffff +#define LA_TRIGGERA_DATA_MATCH_GET(x) (((x)&LA_TRIGGERA_DATA_MATCH_MASK) >> LA_TRIGGERA_DATA_MATCH_LSB) +#define LA_TRIGGERA_DATA_MATCH_SET(x) (((x) << LA_TRIGGERA_DATA_MATCH_LSB) & LA_TRIGGERA_DATA_MATCH_MASK) + +#define LA_TRIGGERA_WILDCARD_ADDRESS 0x000000b4 +#define LA_TRIGGERA_WILDCARD_OFFSET 0x000000b4 +#define LA_TRIGGERA_WILDCARD_MATCH_MSB 17 +#define LA_TRIGGERA_WILDCARD_MATCH_LSB 0 +#define LA_TRIGGERA_WILDCARD_MATCH_MASK 0x0003ffff +#define LA_TRIGGERA_WILDCARD_MATCH_GET(x) (((x)&LA_TRIGGERA_WILDCARD_MATCH_MASK) >> LA_TRIGGERA_WILDCARD_MATCH_LSB) +#define LA_TRIGGERA_WILDCARD_MATCH_SET(x) (((x) << LA_TRIGGERA_WILDCARD_MATCH_LSB) & LA_TRIGGERA_WILDCARD_MATCH_MASK) + +#define LA_TRIGGERB_DATA_ADDRESS 0x000000b8 +#define LA_TRIGGERB_DATA_OFFSET 0x000000b8 +#define LA_TRIGGERB_DATA_MATCH_MSB 17 +#define LA_TRIGGERB_DATA_MATCH_LSB 0 +#define LA_TRIGGERB_DATA_MATCH_MASK 0x0003ffff +#define LA_TRIGGERB_DATA_MATCH_GET(x) (((x)&LA_TRIGGERB_DATA_MATCH_MASK) >> LA_TRIGGERB_DATA_MATCH_LSB) +#define LA_TRIGGERB_DATA_MATCH_SET(x) (((x) << LA_TRIGGERB_DATA_MATCH_LSB) & LA_TRIGGERB_DATA_MATCH_MASK) + +#define LA_TRIGGERB_WILDCARD_ADDRESS 0x000000bc +#define LA_TRIGGERB_WILDCARD_OFFSET 0x000000bc +#define LA_TRIGGERB_WILDCARD_MATCH_MSB 17 +#define LA_TRIGGERB_WILDCARD_MATCH_LSB 0 +#define LA_TRIGGERB_WILDCARD_MATCH_MASK 0x0003ffff +#define LA_TRIGGERB_WILDCARD_MATCH_GET(x) (((x)&LA_TRIGGERB_WILDCARD_MATCH_MASK) >> LA_TRIGGERB_WILDCARD_MATCH_LSB) +#define LA_TRIGGERB_WILDCARD_MATCH_SET(x) (((x) << LA_TRIGGERB_WILDCARD_MATCH_LSB) & LA_TRIGGERB_WILDCARD_MATCH_MASK) + +#define LA_TRIGGER_ADDRESS 0x000000c0 +#define LA_TRIGGER_OFFSET 0x000000c0 +#define LA_TRIGGER_EVENT_MSB 2 +#define LA_TRIGGER_EVENT_LSB 0 +#define LA_TRIGGER_EVENT_MASK 0x00000007 +#define LA_TRIGGER_EVENT_GET(x) (((x)&LA_TRIGGER_EVENT_MASK) >> LA_TRIGGER_EVENT_LSB) +#define LA_TRIGGER_EVENT_SET(x) (((x) << LA_TRIGGER_EVENT_LSB) & LA_TRIGGER_EVENT_MASK) + +#define LA_FIFO_ADDRESS 0x000000c4 +#define LA_FIFO_OFFSET 0x000000c4 +#define LA_FIFO_FULL_MSB 1 +#define LA_FIFO_FULL_LSB 1 +#define LA_FIFO_FULL_MASK 0x00000002 +#define LA_FIFO_FULL_GET(x) (((x)&LA_FIFO_FULL_MASK) >> LA_FIFO_FULL_LSB) +#define LA_FIFO_FULL_SET(x) (((x) << LA_FIFO_FULL_LSB) & LA_FIFO_FULL_MASK) +#define LA_FIFO_EMPTY_MSB 0 +#define LA_FIFO_EMPTY_LSB 0 +#define LA_FIFO_EMPTY_MASK 0x00000001 +#define LA_FIFO_EMPTY_GET(x) (((x)&LA_FIFO_EMPTY_MASK) >> LA_FIFO_EMPTY_LSB) +#define LA_FIFO_EMPTY_SET(x) (((x) << LA_FIFO_EMPTY_LSB) & LA_FIFO_EMPTY_MASK) + +#define LA_ADDRESS 0x000000c8 +#define LA_OFFSET 0x000000c8 +#define LA_DATA_MSB 17 +#define LA_DATA_LSB 0 +#define LA_DATA_MASK 0x0003ffff +#define LA_DATA_GET(x) (((x)&LA_DATA_MASK) >> LA_DATA_LSB) +#define LA_DATA_SET(x) (((x) << LA_DATA_LSB) & LA_DATA_MASK) + +#define ANT_PIN_ADDRESS 0x000000d0 +#define ANT_PIN_OFFSET 0x000000d0 +#define ANT_PIN_PAD_PULL_MSB 3 +#define ANT_PIN_PAD_PULL_LSB 2 +#define ANT_PIN_PAD_PULL_MASK 0x0000000c +#define ANT_PIN_PAD_PULL_GET(x) (((x)&ANT_PIN_PAD_PULL_MASK) >> ANT_PIN_PAD_PULL_LSB) +#define ANT_PIN_PAD_PULL_SET(x) (((x) << ANT_PIN_PAD_PULL_LSB) & ANT_PIN_PAD_PULL_MASK) +#define ANT_PIN_PAD_STRENGTH_MSB 1 +#define ANT_PIN_PAD_STRENGTH_LSB 0 +#define ANT_PIN_PAD_STRENGTH_MASK 0x00000003 +#define ANT_PIN_PAD_STRENGTH_GET(x) (((x)&ANT_PIN_PAD_STRENGTH_MASK) >> ANT_PIN_PAD_STRENGTH_LSB) +#define ANT_PIN_PAD_STRENGTH_SET(x) (((x) << ANT_PIN_PAD_STRENGTH_LSB) & ANT_PIN_PAD_STRENGTH_MASK) + +#define ANTD_PIN_ADDRESS 0x000000d4 +#define ANTD_PIN_OFFSET 0x000000d4 +#define ANTD_PIN_PAD_PULL_MSB 1 +#define ANTD_PIN_PAD_PULL_LSB 0 +#define ANTD_PIN_PAD_PULL_MASK 0x00000003 +#define ANTD_PIN_PAD_PULL_GET(x) (((x)&ANTD_PIN_PAD_PULL_MASK) >> ANTD_PIN_PAD_PULL_LSB) +#define ANTD_PIN_PAD_PULL_SET(x) (((x) << ANTD_PIN_PAD_PULL_LSB) & ANTD_PIN_PAD_PULL_MASK) + +#define GPIO_PIN_ADDRESS 0x000000d8 +#define GPIO_PIN_OFFSET 0x000000d8 +#define GPIO_PIN_PAD_PULL_MSB 3 +#define GPIO_PIN_PAD_PULL_LSB 2 +#define GPIO_PIN_PAD_PULL_MASK 0x0000000c +#define GPIO_PIN_PAD_PULL_GET(x) (((x)&GPIO_PIN_PAD_PULL_MASK) >> GPIO_PIN_PAD_PULL_LSB) +#define GPIO_PIN_PAD_PULL_SET(x) (((x) << GPIO_PIN_PAD_PULL_LSB) & GPIO_PIN_PAD_PULL_MASK) +#define GPIO_PIN_PAD_STRENGTH_MSB 1 +#define GPIO_PIN_PAD_STRENGTH_LSB 0 +#define GPIO_PIN_PAD_STRENGTH_MASK 0x00000003 +#define GPIO_PIN_PAD_STRENGTH_GET(x) (((x)&GPIO_PIN_PAD_STRENGTH_MASK) >> GPIO_PIN_PAD_STRENGTH_LSB) +#define GPIO_PIN_PAD_STRENGTH_SET(x) (((x) << GPIO_PIN_PAD_STRENGTH_LSB) & GPIO_PIN_PAD_STRENGTH_MASK) + +#define GPIO_H_PIN_ADDRESS 0x000000dc +#define GPIO_H_PIN_OFFSET 0x000000dc +#define GPIO_H_PIN_PAD_PULL_MSB 1 +#define GPIO_H_PIN_PAD_PULL_LSB 0 +#define GPIO_H_PIN_PAD_PULL_MASK 0x00000003 +#define GPIO_H_PIN_PAD_PULL_GET(x) (((x)&GPIO_H_PIN_PAD_PULL_MASK) >> GPIO_H_PIN_PAD_PULL_LSB) +#define GPIO_H_PIN_PAD_PULL_SET(x) (((x) << GPIO_H_PIN_PAD_PULL_LSB) & GPIO_H_PIN_PAD_PULL_MASK) + +#define BT_PIN_ADDRESS 0x000000e0 +#define BT_PIN_OFFSET 0x000000e0 +#define BT_PIN_PAD_PULL_MSB 3 +#define BT_PIN_PAD_PULL_LSB 2 +#define BT_PIN_PAD_PULL_MASK 0x0000000c +#define BT_PIN_PAD_PULL_GET(x) (((x)&BT_PIN_PAD_PULL_MASK) >> BT_PIN_PAD_PULL_LSB) +#define BT_PIN_PAD_PULL_SET(x) (((x) << BT_PIN_PAD_PULL_LSB) & BT_PIN_PAD_PULL_MASK) +#define BT_PIN_PAD_STRENGTH_MSB 1 +#define BT_PIN_PAD_STRENGTH_LSB 0 +#define BT_PIN_PAD_STRENGTH_MASK 0x00000003 +#define BT_PIN_PAD_STRENGTH_GET(x) (((x)&BT_PIN_PAD_STRENGTH_MASK) >> BT_PIN_PAD_STRENGTH_LSB) +#define BT_PIN_PAD_STRENGTH_SET(x) (((x) << BT_PIN_PAD_STRENGTH_LSB) & BT_PIN_PAD_STRENGTH_MASK) + +#define BT_WLAN_PIN_ADDRESS 0x000000e4 +#define BT_WLAN_PIN_OFFSET 0x000000e4 +#define BT_WLAN_PIN_PAD_PULL_MSB 1 +#define BT_WLAN_PIN_PAD_PULL_LSB 0 +#define BT_WLAN_PIN_PAD_PULL_MASK 0x00000003 +#define BT_WLAN_PIN_PAD_PULL_GET(x) (((x)&BT_WLAN_PIN_PAD_PULL_MASK) >> BT_WLAN_PIN_PAD_PULL_LSB) +#define BT_WLAN_PIN_PAD_PULL_SET(x) (((x) << BT_WLAN_PIN_PAD_PULL_LSB) & BT_WLAN_PIN_PAD_PULL_MASK) + +#define SI_UART_PIN_ADDRESS 0x000000e8 +#define SI_UART_PIN_OFFSET 0x000000e8 +#define SI_UART_PIN_PAD_PULL_MSB 3 +#define SI_UART_PIN_PAD_PULL_LSB 2 +#define SI_UART_PIN_PAD_PULL_MASK 0x0000000c +#define SI_UART_PIN_PAD_PULL_GET(x) (((x)&SI_UART_PIN_PAD_PULL_MASK) >> SI_UART_PIN_PAD_PULL_LSB) +#define SI_UART_PIN_PAD_PULL_SET(x) (((x) << SI_UART_PIN_PAD_PULL_LSB) & SI_UART_PIN_PAD_PULL_MASK) +#define SI_UART_PIN_PAD_STRENGTH_MSB 1 +#define SI_UART_PIN_PAD_STRENGTH_LSB 0 +#define SI_UART_PIN_PAD_STRENGTH_MASK 0x00000003 +#define SI_UART_PIN_PAD_STRENGTH_GET(x) (((x)&SI_UART_PIN_PAD_STRENGTH_MASK) >> SI_UART_PIN_PAD_STRENGTH_LSB) +#define SI_UART_PIN_PAD_STRENGTH_SET(x) (((x) << SI_UART_PIN_PAD_STRENGTH_LSB) & SI_UART_PIN_PAD_STRENGTH_MASK) + +#define CLK32K_PIN_ADDRESS 0x000000ec +#define CLK32K_PIN_OFFSET 0x000000ec +#define CLK32K_PIN_PAD_PULL_MSB 1 +#define CLK32K_PIN_PAD_PULL_LSB 0 +#define CLK32K_PIN_PAD_PULL_MASK 0x00000003 +#define CLK32K_PIN_PAD_PULL_GET(x) (((x)&CLK32K_PIN_PAD_PULL_MASK) >> CLK32K_PIN_PAD_PULL_LSB) +#define CLK32K_PIN_PAD_PULL_SET(x) (((x) << CLK32K_PIN_PAD_PULL_LSB) & CLK32K_PIN_PAD_PULL_MASK) + +#define RESET_TUPLE_STATUS_ADDRESS 0x000000f0 +#define RESET_TUPLE_STATUS_OFFSET 0x000000f0 +#define RESET_TUPLE_STATUS_TEST_RESET_TUPLE_MSB 11 +#define RESET_TUPLE_STATUS_TEST_RESET_TUPLE_LSB 8 +#define RESET_TUPLE_STATUS_TEST_RESET_TUPLE_MASK 0x00000f00 +#define RESET_TUPLE_STATUS_TEST_RESET_TUPLE_GET(x) \ + (((x)&RESET_TUPLE_STATUS_TEST_RESET_TUPLE_MASK) >> RESET_TUPLE_STATUS_TEST_RESET_TUPLE_LSB) +#define RESET_TUPLE_STATUS_TEST_RESET_TUPLE_SET(x) \ + (((x) << RESET_TUPLE_STATUS_TEST_RESET_TUPLE_LSB) & RESET_TUPLE_STATUS_TEST_RESET_TUPLE_MASK) +#define RESET_TUPLE_STATUS_PIN_RESET_TUPLE_MSB 7 +#define RESET_TUPLE_STATUS_PIN_RESET_TUPLE_LSB 0 +#define RESET_TUPLE_STATUS_PIN_RESET_TUPLE_MASK 0x000000ff +#define RESET_TUPLE_STATUS_PIN_RESET_TUPLE_GET(x) \ + (((x)&RESET_TUPLE_STATUS_PIN_RESET_TUPLE_MASK) >> RESET_TUPLE_STATUS_PIN_RESET_TUPLE_LSB) +#define RESET_TUPLE_STATUS_PIN_RESET_TUPLE_SET(x) \ + (((x) << RESET_TUPLE_STATUS_PIN_RESET_TUPLE_LSB) & RESET_TUPLE_STATUS_PIN_RESET_TUPLE_MASK) + +#ifndef __ASSEMBLER__ + +typedef struct gpio_reg_reg_s +{ + volatile unsigned int gpio_out; + volatile unsigned int gpio_out_w1ts; + volatile unsigned int gpio_out_w1tc; + volatile unsigned int gpio_enable; + volatile unsigned int gpio_enable_w1ts; + volatile unsigned int gpio_enable_w1tc; + volatile unsigned int gpio_in; + volatile unsigned int gpio_status; + volatile unsigned int gpio_status_w1ts; + volatile unsigned int gpio_status_w1tc; + volatile unsigned int gpio_pin0; + volatile unsigned int gpio_pin1; + volatile unsigned int gpio_pin2; + volatile unsigned int gpio_pin3; + volatile unsigned int gpio_pin4; + volatile unsigned int gpio_pin5; + volatile unsigned int gpio_pin6; + volatile unsigned int gpio_pin7; + volatile unsigned int gpio_pin8; + volatile unsigned int gpio_pin9; + volatile unsigned int gpio_pin10; + volatile unsigned int gpio_pin11; + volatile unsigned int gpio_pin12; + volatile unsigned int gpio_pin13; + volatile unsigned int gpio_pin14; + volatile unsigned int gpio_pin15; + volatile unsigned int gpio_pin16; + volatile unsigned int gpio_pin17; + volatile unsigned int sdio_pin; + volatile unsigned int clk_req_pin; + volatile unsigned int sigma_delta; + volatile unsigned int debug_control; + volatile unsigned int debug_input_sel; + volatile unsigned int debug_out; + volatile unsigned int la_control; + volatile unsigned int la_clock; + volatile unsigned int la_status; + volatile unsigned int la_trigger_sample; + volatile unsigned int la_trigger_position; + volatile unsigned int la_pre_trigger; + volatile unsigned int la_post_trigger; + volatile unsigned int la_filter_control; + volatile unsigned int la_filter_data; + volatile unsigned int la_filter_wildcard; + volatile unsigned int la_triggera_data; + volatile unsigned int la_triggera_wildcard; + volatile unsigned int la_triggerb_data; + volatile unsigned int la_triggerb_wildcard; + volatile unsigned int la_trigger; + volatile unsigned int la_fifo; + volatile unsigned int la[2]; + volatile unsigned int ant_pin; + volatile unsigned int antd_pin; + volatile unsigned int gpio_pin; + volatile unsigned int gpio_h_pin; + volatile unsigned int bt_pin; + volatile unsigned int bt_wlan_pin; + volatile unsigned int si_uart_pin; + volatile unsigned int clk32k_pin; + volatile unsigned int reset_tuple_status; +} gpio_reg_reg_t; + +#endif /* __ASSEMBLER__ */ + +#endif /* _GPIO_REG_H_ */ diff --git a/platform/mcu/lpc54102/wifi_qca/include/AR6002/hw2.0/hw/hw20_mbox_host_reg.h b/platform/mcu/lpc54102/wifi_qca/include/AR6002/hw2.0/hw/hw20_mbox_host_reg.h new file mode 100644 index 0000000000..58eef5fb7f --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/include/AR6002/hw2.0/hw/hw20_mbox_host_reg.h @@ -0,0 +1,421 @@ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== +#ifndef _MBOX_HOST_REG_REG_H_ +#define _MBOX_HOST_REG_REG_H_ + +#define HOST_INT_STATUS_ADDRESS 0x00000400 +#define HOST_INT_STATUS_OFFSET 0x00000400 +#define HOST_INT_STATUS_ERROR_MSB 7 +#define HOST_INT_STATUS_ERROR_LSB 7 +#define HOST_INT_STATUS_ERROR_MASK 0x00000080 +#define HOST_INT_STATUS_ERROR_GET(x) (((x)&HOST_INT_STATUS_ERROR_MASK) >> HOST_INT_STATUS_ERROR_LSB) +#define HOST_INT_STATUS_ERROR_SET(x) (((x) << HOST_INT_STATUS_ERROR_LSB) & HOST_INT_STATUS_ERROR_MASK) +#define HOST_INT_STATUS_CPU_MSB 6 +#define HOST_INT_STATUS_CPU_LSB 6 +#define HOST_INT_STATUS_CPU_MASK 0x00000040 +#define HOST_INT_STATUS_CPU_GET(x) (((x)&HOST_INT_STATUS_CPU_MASK) >> HOST_INT_STATUS_CPU_LSB) +#define HOST_INT_STATUS_CPU_SET(x) (((x) << HOST_INT_STATUS_CPU_LSB) & HOST_INT_STATUS_CPU_MASK) +#define HOST_INT_STATUS_DRAGON_INT_MSB 5 +#define HOST_INT_STATUS_DRAGON_INT_LSB 5 +#define HOST_INT_STATUS_DRAGON_INT_MASK 0x00000020 +#define HOST_INT_STATUS_DRAGON_INT_GET(x) (((x)&HOST_INT_STATUS_DRAGON_INT_MASK) >> HOST_INT_STATUS_DRAGON_INT_LSB) +#define HOST_INT_STATUS_DRAGON_INT_SET(x) (((x) << HOST_INT_STATUS_DRAGON_INT_LSB) & HOST_INT_STATUS_DRAGON_INT_MASK) +#define HOST_INT_STATUS_COUNTER_MSB 4 +#define HOST_INT_STATUS_COUNTER_LSB 4 +#define HOST_INT_STATUS_COUNTER_MASK 0x00000010 +#define HOST_INT_STATUS_COUNTER_GET(x) (((x)&HOST_INT_STATUS_COUNTER_MASK) >> HOST_INT_STATUS_COUNTER_LSB) +#define HOST_INT_STATUS_COUNTER_SET(x) (((x) << HOST_INT_STATUS_COUNTER_LSB) & HOST_INT_STATUS_COUNTER_MASK) +#define HOST_INT_STATUS_MBOX_DATA_MSB 3 +#define HOST_INT_STATUS_MBOX_DATA_LSB 0 +#define HOST_INT_STATUS_MBOX_DATA_MASK 0x0000000f +#define HOST_INT_STATUS_MBOX_DATA_GET(x) (((x)&HOST_INT_STATUS_MBOX_DATA_MASK) >> HOST_INT_STATUS_MBOX_DATA_LSB) +#define HOST_INT_STATUS_MBOX_DATA_SET(x) (((x) << HOST_INT_STATUS_MBOX_DATA_LSB) & HOST_INT_STATUS_MBOX_DATA_MASK) + +#define CPU_INT_STATUS_ADDRESS 0x00000401 +#define CPU_INT_STATUS_OFFSET 0x00000401 +#define CPU_INT_STATUS_BIT_MSB 7 +#define CPU_INT_STATUS_BIT_LSB 0 +#define CPU_INT_STATUS_BIT_MASK 0x000000ff +#define CPU_INT_STATUS_BIT_GET(x) (((x)&CPU_INT_STATUS_BIT_MASK) >> CPU_INT_STATUS_BIT_LSB) +#define CPU_INT_STATUS_BIT_SET(x) (((x) << CPU_INT_STATUS_BIT_LSB) & CPU_INT_STATUS_BIT_MASK) + +#define ERROR_INT_STATUS_ADDRESS 0x00000402 +#define ERROR_INT_STATUS_OFFSET 0x00000402 +#define ERROR_INT_STATUS_SPI_MSB 3 +#define ERROR_INT_STATUS_SPI_LSB 3 +#define ERROR_INT_STATUS_SPI_MASK 0x00000008 +#define ERROR_INT_STATUS_SPI_GET(x) (((x)&ERROR_INT_STATUS_SPI_MASK) >> ERROR_INT_STATUS_SPI_LSB) +#define ERROR_INT_STATUS_SPI_SET(x) (((x) << ERROR_INT_STATUS_SPI_LSB) & ERROR_INT_STATUS_SPI_MASK) +#define ERROR_INT_STATUS_WAKEUP_MSB 2 +#define ERROR_INT_STATUS_WAKEUP_LSB 2 +#define ERROR_INT_STATUS_WAKEUP_MASK 0x00000004 +#define ERROR_INT_STATUS_WAKEUP_GET(x) (((x)&ERROR_INT_STATUS_WAKEUP_MASK) >> ERROR_INT_STATUS_WAKEUP_LSB) +#define ERROR_INT_STATUS_WAKEUP_SET(x) (((x) << ERROR_INT_STATUS_WAKEUP_LSB) & ERROR_INT_STATUS_WAKEUP_MASK) +#define ERROR_INT_STATUS_RX_UNDERFLOW_MSB 1 +#define ERROR_INT_STATUS_RX_UNDERFLOW_LSB 1 +#define ERROR_INT_STATUS_RX_UNDERFLOW_MASK 0x00000002 +#define ERROR_INT_STATUS_RX_UNDERFLOW_GET(x) \ + (((x)&ERROR_INT_STATUS_RX_UNDERFLOW_MASK) >> ERROR_INT_STATUS_RX_UNDERFLOW_LSB) +#define ERROR_INT_STATUS_RX_UNDERFLOW_SET(x) \ + (((x) << ERROR_INT_STATUS_RX_UNDERFLOW_LSB) & ERROR_INT_STATUS_RX_UNDERFLOW_MASK) +#define ERROR_INT_STATUS_TX_OVERFLOW_MSB 0 +#define ERROR_INT_STATUS_TX_OVERFLOW_LSB 0 +#define ERROR_INT_STATUS_TX_OVERFLOW_MASK 0x00000001 +#define ERROR_INT_STATUS_TX_OVERFLOW_GET(x) \ + (((x)&ERROR_INT_STATUS_TX_OVERFLOW_MASK) >> ERROR_INT_STATUS_TX_OVERFLOW_LSB) +#define ERROR_INT_STATUS_TX_OVERFLOW_SET(x) \ + (((x) << ERROR_INT_STATUS_TX_OVERFLOW_LSB) & ERROR_INT_STATUS_TX_OVERFLOW_MASK) + +#define COUNTER_INT_STATUS_ADDRESS 0x00000403 +#define COUNTER_INT_STATUS_OFFSET 0x00000403 +#define COUNTER_INT_STATUS_COUNTER_MSB 7 +#define COUNTER_INT_STATUS_COUNTER_LSB 0 +#define COUNTER_INT_STATUS_COUNTER_MASK 0x000000ff +#define COUNTER_INT_STATUS_COUNTER_GET(x) (((x)&COUNTER_INT_STATUS_COUNTER_MASK) >> COUNTER_INT_STATUS_COUNTER_LSB) +#define COUNTER_INT_STATUS_COUNTER_SET(x) (((x) << COUNTER_INT_STATUS_COUNTER_LSB) & COUNTER_INT_STATUS_COUNTER_MASK) + +#define MBOX_FRAME_ADDRESS 0x00000404 +#define MBOX_FRAME_OFFSET 0x00000404 +#define MBOX_FRAME_RX_EOM_MSB 7 +#define MBOX_FRAME_RX_EOM_LSB 4 +#define MBOX_FRAME_RX_EOM_MASK 0x000000f0 +#define MBOX_FRAME_RX_EOM_GET(x) (((x)&MBOX_FRAME_RX_EOM_MASK) >> MBOX_FRAME_RX_EOM_LSB) +#define MBOX_FRAME_RX_EOM_SET(x) (((x) << MBOX_FRAME_RX_EOM_LSB) & MBOX_FRAME_RX_EOM_MASK) +#define MBOX_FRAME_RX_SOM_MSB 3 +#define MBOX_FRAME_RX_SOM_LSB 0 +#define MBOX_FRAME_RX_SOM_MASK 0x0000000f +#define MBOX_FRAME_RX_SOM_GET(x) (((x)&MBOX_FRAME_RX_SOM_MASK) >> MBOX_FRAME_RX_SOM_LSB) +#define MBOX_FRAME_RX_SOM_SET(x) (((x) << MBOX_FRAME_RX_SOM_LSB) & MBOX_FRAME_RX_SOM_MASK) + +#define RX_LOOKAHEAD_VALID_ADDRESS 0x00000405 +#define RX_LOOKAHEAD_VALID_OFFSET 0x00000405 +#define RX_LOOKAHEAD_VALID_MBOX_MSB 3 +#define RX_LOOKAHEAD_VALID_MBOX_LSB 0 +#define RX_LOOKAHEAD_VALID_MBOX_MASK 0x0000000f +#define RX_LOOKAHEAD_VALID_MBOX_GET(x) (((x)&RX_LOOKAHEAD_VALID_MBOX_MASK) >> RX_LOOKAHEAD_VALID_MBOX_LSB) +#define RX_LOOKAHEAD_VALID_MBOX_SET(x) (((x) << RX_LOOKAHEAD_VALID_MBOX_LSB) & RX_LOOKAHEAD_VALID_MBOX_MASK) + +#define RX_LOOKAHEAD0_ADDRESS 0x00000408 +#define RX_LOOKAHEAD0_OFFSET 0x00000408 +#define RX_LOOKAHEAD0_DATA_MSB 7 +#define RX_LOOKAHEAD0_DATA_LSB 0 +#define RX_LOOKAHEAD0_DATA_MASK 0x000000ff +#define RX_LOOKAHEAD0_DATA_GET(x) (((x)&RX_LOOKAHEAD0_DATA_MASK) >> RX_LOOKAHEAD0_DATA_LSB) +#define RX_LOOKAHEAD0_DATA_SET(x) (((x) << RX_LOOKAHEAD0_DATA_LSB) & RX_LOOKAHEAD0_DATA_MASK) + +#define RX_LOOKAHEAD1_ADDRESS 0x0000040c +#define RX_LOOKAHEAD1_OFFSET 0x0000040c +#define RX_LOOKAHEAD1_DATA_MSB 7 +#define RX_LOOKAHEAD1_DATA_LSB 0 +#define RX_LOOKAHEAD1_DATA_MASK 0x000000ff +#define RX_LOOKAHEAD1_DATA_GET(x) (((x)&RX_LOOKAHEAD1_DATA_MASK) >> RX_LOOKAHEAD1_DATA_LSB) +#define RX_LOOKAHEAD1_DATA_SET(x) (((x) << RX_LOOKAHEAD1_DATA_LSB) & RX_LOOKAHEAD1_DATA_MASK) + +#define RX_LOOKAHEAD2_ADDRESS 0x00000410 +#define RX_LOOKAHEAD2_OFFSET 0x00000410 +#define RX_LOOKAHEAD2_DATA_MSB 7 +#define RX_LOOKAHEAD2_DATA_LSB 0 +#define RX_LOOKAHEAD2_DATA_MASK 0x000000ff +#define RX_LOOKAHEAD2_DATA_GET(x) (((x)&RX_LOOKAHEAD2_DATA_MASK) >> RX_LOOKAHEAD2_DATA_LSB) +#define RX_LOOKAHEAD2_DATA_SET(x) (((x) << RX_LOOKAHEAD2_DATA_LSB) & RX_LOOKAHEAD2_DATA_MASK) + +#define RX_LOOKAHEAD3_ADDRESS 0x00000414 +#define RX_LOOKAHEAD3_OFFSET 0x00000414 +#define RX_LOOKAHEAD3_DATA_MSB 7 +#define RX_LOOKAHEAD3_DATA_LSB 0 +#define RX_LOOKAHEAD3_DATA_MASK 0x000000ff +#define RX_LOOKAHEAD3_DATA_GET(x) (((x)&RX_LOOKAHEAD3_DATA_MASK) >> RX_LOOKAHEAD3_DATA_LSB) +#define RX_LOOKAHEAD3_DATA_SET(x) (((x) << RX_LOOKAHEAD3_DATA_LSB) & RX_LOOKAHEAD3_DATA_MASK) + +#define INT_STATUS_ENABLE_ADDRESS 0x00000418 +#define INT_STATUS_ENABLE_OFFSET 0x00000418 +#define INT_STATUS_ENABLE_ERROR_MSB 7 +#define INT_STATUS_ENABLE_ERROR_LSB 7 +#define INT_STATUS_ENABLE_ERROR_MASK 0x00000080 +#define INT_STATUS_ENABLE_ERROR_GET(x) (((x)&INT_STATUS_ENABLE_ERROR_MASK) >> INT_STATUS_ENABLE_ERROR_LSB) +#define INT_STATUS_ENABLE_ERROR_SET(x) (((x) << INT_STATUS_ENABLE_ERROR_LSB) & INT_STATUS_ENABLE_ERROR_MASK) +#define INT_STATUS_ENABLE_CPU_MSB 6 +#define INT_STATUS_ENABLE_CPU_LSB 6 +#define INT_STATUS_ENABLE_CPU_MASK 0x00000040 +#define INT_STATUS_ENABLE_CPU_GET(x) (((x)&INT_STATUS_ENABLE_CPU_MASK) >> INT_STATUS_ENABLE_CPU_LSB) +#define INT_STATUS_ENABLE_CPU_SET(x) (((x) << INT_STATUS_ENABLE_CPU_LSB) & INT_STATUS_ENABLE_CPU_MASK) +#define INT_STATUS_ENABLE_DRAGON_INT_MSB 5 +#define INT_STATUS_ENABLE_DRAGON_INT_LSB 5 +#define INT_STATUS_ENABLE_DRAGON_INT_MASK 0x00000020 +#define INT_STATUS_ENABLE_DRAGON_INT_GET(x) \ + (((x)&INT_STATUS_ENABLE_DRAGON_INT_MASK) >> INT_STATUS_ENABLE_DRAGON_INT_LSB) +#define INT_STATUS_ENABLE_DRAGON_INT_SET(x) \ + (((x) << INT_STATUS_ENABLE_DRAGON_INT_LSB) & INT_STATUS_ENABLE_DRAGON_INT_MASK) +#define INT_STATUS_ENABLE_COUNTER_MSB 4 +#define INT_STATUS_ENABLE_COUNTER_LSB 4 +#define INT_STATUS_ENABLE_COUNTER_MASK 0x00000010 +#define INT_STATUS_ENABLE_COUNTER_GET(x) (((x)&INT_STATUS_ENABLE_COUNTER_MASK) >> INT_STATUS_ENABLE_COUNTER_LSB) +#define INT_STATUS_ENABLE_COUNTER_SET(x) (((x) << INT_STATUS_ENABLE_COUNTER_LSB) & INT_STATUS_ENABLE_COUNTER_MASK) +#define INT_STATUS_ENABLE_MBOX_DATA_MSB 3 +#define INT_STATUS_ENABLE_MBOX_DATA_LSB 0 +#define INT_STATUS_ENABLE_MBOX_DATA_MASK 0x0000000f +#define INT_STATUS_ENABLE_MBOX_DATA_GET(x) (((x)&INT_STATUS_ENABLE_MBOX_DATA_MASK) >> INT_STATUS_ENABLE_MBOX_DATA_LSB) +#define INT_STATUS_ENABLE_MBOX_DATA_SET(x) (((x) << INT_STATUS_ENABLE_MBOX_DATA_LSB) & INT_STATUS_ENABLE_MBOX_DATA_MASK) + +#define CPU_INT_STATUS_ENABLE_ADDRESS 0x00000419 +#define CPU_INT_STATUS_ENABLE_OFFSET 0x00000419 +#define CPU_INT_STATUS_ENABLE_BIT_MSB 7 +#define CPU_INT_STATUS_ENABLE_BIT_LSB 0 +#define CPU_INT_STATUS_ENABLE_BIT_MASK 0x000000ff +#define CPU_INT_STATUS_ENABLE_BIT_GET(x) (((x)&CPU_INT_STATUS_ENABLE_BIT_MASK) >> CPU_INT_STATUS_ENABLE_BIT_LSB) +#define CPU_INT_STATUS_ENABLE_BIT_SET(x) (((x) << CPU_INT_STATUS_ENABLE_BIT_LSB) & CPU_INT_STATUS_ENABLE_BIT_MASK) + +#define ERROR_STATUS_ENABLE_ADDRESS 0x0000041a +#define ERROR_STATUS_ENABLE_OFFSET 0x0000041a +#define ERROR_STATUS_ENABLE_WAKEUP_MSB 2 +#define ERROR_STATUS_ENABLE_WAKEUP_LSB 2 +#define ERROR_STATUS_ENABLE_WAKEUP_MASK 0x00000004 +#define ERROR_STATUS_ENABLE_WAKEUP_GET(x) (((x)&ERROR_STATUS_ENABLE_WAKEUP_MASK) >> ERROR_STATUS_ENABLE_WAKEUP_LSB) +#define ERROR_STATUS_ENABLE_WAKEUP_SET(x) (((x) << ERROR_STATUS_ENABLE_WAKEUP_LSB) & ERROR_STATUS_ENABLE_WAKEUP_MASK) +#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_MSB 1 +#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB 1 +#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK 0x00000002 +#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_GET(x) \ + (((x)&ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK) >> ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB) +#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_SET(x) \ + (((x) << ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB) & ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK) +#define ERROR_STATUS_ENABLE_TX_OVERFLOW_MSB 0 +#define ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB 0 +#define ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK 0x00000001 +#define ERROR_STATUS_ENABLE_TX_OVERFLOW_GET(x) \ + (((x)&ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK) >> ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB) +#define ERROR_STATUS_ENABLE_TX_OVERFLOW_SET(x) \ + (((x) << ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB) & ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK) + +#define COUNTER_INT_STATUS_ENABLE_ADDRESS 0x0000041b +#define COUNTER_INT_STATUS_ENABLE_OFFSET 0x0000041b +#define COUNTER_INT_STATUS_ENABLE_BIT_MSB 7 +#define COUNTER_INT_STATUS_ENABLE_BIT_LSB 0 +#define COUNTER_INT_STATUS_ENABLE_BIT_MASK 0x000000ff +#define COUNTER_INT_STATUS_ENABLE_BIT_GET(x) \ + (((x)&COUNTER_INT_STATUS_ENABLE_BIT_MASK) >> COUNTER_INT_STATUS_ENABLE_BIT_LSB) +#define COUNTER_INT_STATUS_ENABLE_BIT_SET(x) \ + (((x) << COUNTER_INT_STATUS_ENABLE_BIT_LSB) & COUNTER_INT_STATUS_ENABLE_BIT_MASK) + +#define COUNT_ADDRESS 0x00000420 +#define COUNT_OFFSET 0x00000420 +#define COUNT_VALUE_MSB 7 +#define COUNT_VALUE_LSB 0 +#define COUNT_VALUE_MASK 0x000000ff +#define COUNT_VALUE_GET(x) (((x)&COUNT_VALUE_MASK) >> COUNT_VALUE_LSB) +#define COUNT_VALUE_SET(x) (((x) << COUNT_VALUE_LSB) & COUNT_VALUE_MASK) + +#define COUNT_DEC_ADDRESS 0x00000440 +#define COUNT_DEC_OFFSET 0x00000440 +#define COUNT_DEC_VALUE_MSB 7 +#define COUNT_DEC_VALUE_LSB 0 +#define COUNT_DEC_VALUE_MASK 0x000000ff +#define COUNT_DEC_VALUE_GET(x) (((x)&COUNT_DEC_VALUE_MASK) >> COUNT_DEC_VALUE_LSB) +#define COUNT_DEC_VALUE_SET(x) (((x) << COUNT_DEC_VALUE_LSB) & COUNT_DEC_VALUE_MASK) + +#define SCRATCH_ADDRESS 0x00000460 +#define SCRATCH_OFFSET 0x00000460 +#define SCRATCH_VALUE_MSB 7 +#define SCRATCH_VALUE_LSB 0 +#define SCRATCH_VALUE_MASK 0x000000ff +#define SCRATCH_VALUE_GET(x) (((x)&SCRATCH_VALUE_MASK) >> SCRATCH_VALUE_LSB) +#define SCRATCH_VALUE_SET(x) (((x) << SCRATCH_VALUE_LSB) & SCRATCH_VALUE_MASK) + +#define FIFO_TIMEOUT_ADDRESS 0x00000468 +#define FIFO_TIMEOUT_OFFSET 0x00000468 +#define FIFO_TIMEOUT_VALUE_MSB 7 +#define FIFO_TIMEOUT_VALUE_LSB 0 +#define FIFO_TIMEOUT_VALUE_MASK 0x000000ff +#define FIFO_TIMEOUT_VALUE_GET(x) (((x)&FIFO_TIMEOUT_VALUE_MASK) >> FIFO_TIMEOUT_VALUE_LSB) +#define FIFO_TIMEOUT_VALUE_SET(x) (((x) << FIFO_TIMEOUT_VALUE_LSB) & FIFO_TIMEOUT_VALUE_MASK) + +#define FIFO_TIMEOUT_ENABLE_ADDRESS 0x00000469 +#define FIFO_TIMEOUT_ENABLE_OFFSET 0x00000469 +#define FIFO_TIMEOUT_ENABLE_SET_MSB 0 +#define FIFO_TIMEOUT_ENABLE_SET_LSB 0 +#define FIFO_TIMEOUT_ENABLE_SET_MASK 0x00000001 +#define FIFO_TIMEOUT_ENABLE_SET_GET(x) (((x)&FIFO_TIMEOUT_ENABLE_SET_MASK) >> FIFO_TIMEOUT_ENABLE_SET_LSB) +#define FIFO_TIMEOUT_ENABLE_SET_SET(x) (((x) << FIFO_TIMEOUT_ENABLE_SET_LSB) & FIFO_TIMEOUT_ENABLE_SET_MASK) + +#define DISABLE_SLEEP_ADDRESS 0x0000046a +#define DISABLE_SLEEP_OFFSET 0x0000046a +#define DISABLE_SLEEP_FOR_INT_MSB 1 +#define DISABLE_SLEEP_FOR_INT_LSB 1 +#define DISABLE_SLEEP_FOR_INT_MASK 0x00000002 +#define DISABLE_SLEEP_FOR_INT_GET(x) (((x)&DISABLE_SLEEP_FOR_INT_MASK) >> DISABLE_SLEEP_FOR_INT_LSB) +#define DISABLE_SLEEP_FOR_INT_SET(x) (((x) << DISABLE_SLEEP_FOR_INT_LSB) & DISABLE_SLEEP_FOR_INT_MASK) +#define DISABLE_SLEEP_ON_MSB 0 +#define DISABLE_SLEEP_ON_LSB 0 +#define DISABLE_SLEEP_ON_MASK 0x00000001 +#define DISABLE_SLEEP_ON_GET(x) (((x)&DISABLE_SLEEP_ON_MASK) >> DISABLE_SLEEP_ON_LSB) +#define DISABLE_SLEEP_ON_SET(x) (((x) << DISABLE_SLEEP_ON_LSB) & DISABLE_SLEEP_ON_MASK) + +#define LOCAL_BUS_ADDRESS 0x00000470 +#define LOCAL_BUS_OFFSET 0x00000470 +#define LOCAL_BUS_STATE_MSB 1 +#define LOCAL_BUS_STATE_LSB 0 +#define LOCAL_BUS_STATE_MASK 0x00000003 +#define LOCAL_BUS_STATE_GET(x) (((x)&LOCAL_BUS_STATE_MASK) >> LOCAL_BUS_STATE_LSB) +#define LOCAL_BUS_STATE_SET(x) (((x) << LOCAL_BUS_STATE_LSB) & LOCAL_BUS_STATE_MASK) + +#define INT_WLAN_ADDRESS 0x00000472 +#define INT_WLAN_OFFSET 0x00000472 +#define INT_WLAN_VECTOR_MSB 7 +#define INT_WLAN_VECTOR_LSB 0 +#define INT_WLAN_VECTOR_MASK 0x000000ff +#define INT_WLAN_VECTOR_GET(x) (((x)&INT_WLAN_VECTOR_MASK) >> INT_WLAN_VECTOR_LSB) +#define INT_WLAN_VECTOR_SET(x) (((x) << INT_WLAN_VECTOR_LSB) & INT_WLAN_VECTOR_MASK) + +#define WINDOW_DATA_ADDRESS 0x00000474 +#define WINDOW_DATA_OFFSET 0x00000474 +#define WINDOW_DATA_DATA_MSB 7 +#define WINDOW_DATA_DATA_LSB 0 +#define WINDOW_DATA_DATA_MASK 0x000000ff +#define WINDOW_DATA_DATA_GET(x) (((x)&WINDOW_DATA_DATA_MASK) >> WINDOW_DATA_DATA_LSB) +#define WINDOW_DATA_DATA_SET(x) (((x) << WINDOW_DATA_DATA_LSB) & WINDOW_DATA_DATA_MASK) + +#define WINDOW_WRITE_ADDR_ADDRESS 0x00000478 +#define WINDOW_WRITE_ADDR_OFFSET 0x00000478 +#define WINDOW_WRITE_ADDR_ADDR_MSB 7 +#define WINDOW_WRITE_ADDR_ADDR_LSB 0 +#define WINDOW_WRITE_ADDR_ADDR_MASK 0x000000ff +#define WINDOW_WRITE_ADDR_ADDR_GET(x) (((x)&WINDOW_WRITE_ADDR_ADDR_MASK) >> WINDOW_WRITE_ADDR_ADDR_LSB) +#define WINDOW_WRITE_ADDR_ADDR_SET(x) (((x) << WINDOW_WRITE_ADDR_ADDR_LSB) & WINDOW_WRITE_ADDR_ADDR_MASK) + +#define WINDOW_READ_ADDR_ADDRESS 0x0000047c +#define WINDOW_READ_ADDR_OFFSET 0x0000047c +#define WINDOW_READ_ADDR_ADDR_MSB 7 +#define WINDOW_READ_ADDR_ADDR_LSB 0 +#define WINDOW_READ_ADDR_ADDR_MASK 0x000000ff +#define WINDOW_READ_ADDR_ADDR_GET(x) (((x)&WINDOW_READ_ADDR_ADDR_MASK) >> WINDOW_READ_ADDR_ADDR_LSB) +#define WINDOW_READ_ADDR_ADDR_SET(x) (((x) << WINDOW_READ_ADDR_ADDR_LSB) & WINDOW_READ_ADDR_ADDR_MASK) + +#define SPI_CONFIG_ADDRESS 0x00000480 +#define SPI_CONFIG_OFFSET 0x00000480 +#define SPI_CONFIG_SPI_RESET_MSB 4 +#define SPI_CONFIG_SPI_RESET_LSB 4 +#define SPI_CONFIG_SPI_RESET_MASK 0x00000010 +#define SPI_CONFIG_SPI_RESET_GET(x) (((x)&SPI_CONFIG_SPI_RESET_MASK) >> SPI_CONFIG_SPI_RESET_LSB) +#define SPI_CONFIG_SPI_RESET_SET(x) (((x) << SPI_CONFIG_SPI_RESET_LSB) & SPI_CONFIG_SPI_RESET_MASK) +#define SPI_CONFIG_INTERRUPT_ENABLE_MSB 3 +#define SPI_CONFIG_INTERRUPT_ENABLE_LSB 3 +#define SPI_CONFIG_INTERRUPT_ENABLE_MASK 0x00000008 +#define SPI_CONFIG_INTERRUPT_ENABLE_GET(x) (((x)&SPI_CONFIG_INTERRUPT_ENABLE_MASK) >> SPI_CONFIG_INTERRUPT_ENABLE_LSB) +#define SPI_CONFIG_INTERRUPT_ENABLE_SET(x) (((x) << SPI_CONFIG_INTERRUPT_ENABLE_LSB) & SPI_CONFIG_INTERRUPT_ENABLE_MASK) +#define SPI_CONFIG_TEST_MODE_MSB 2 +#define SPI_CONFIG_TEST_MODE_LSB 2 +#define SPI_CONFIG_TEST_MODE_MASK 0x00000004 +#define SPI_CONFIG_TEST_MODE_GET(x) (((x)&SPI_CONFIG_TEST_MODE_MASK) >> SPI_CONFIG_TEST_MODE_LSB) +#define SPI_CONFIG_TEST_MODE_SET(x) (((x) << SPI_CONFIG_TEST_MODE_LSB) & SPI_CONFIG_TEST_MODE_MASK) +#define SPI_CONFIG_DATA_SIZE_MSB 1 +#define SPI_CONFIG_DATA_SIZE_LSB 0 +#define SPI_CONFIG_DATA_SIZE_MASK 0x00000003 +#define SPI_CONFIG_DATA_SIZE_GET(x) (((x)&SPI_CONFIG_DATA_SIZE_MASK) >> SPI_CONFIG_DATA_SIZE_LSB) +#define SPI_CONFIG_DATA_SIZE_SET(x) (((x) << SPI_CONFIG_DATA_SIZE_LSB) & SPI_CONFIG_DATA_SIZE_MASK) + +#define SPI_STATUS_ADDRESS 0x00000481 +#define SPI_STATUS_OFFSET 0x00000481 +#define SPI_STATUS_ADDR_ERR_MSB 3 +#define SPI_STATUS_ADDR_ERR_LSB 3 +#define SPI_STATUS_ADDR_ERR_MASK 0x00000008 +#define SPI_STATUS_ADDR_ERR_GET(x) (((x)&SPI_STATUS_ADDR_ERR_MASK) >> SPI_STATUS_ADDR_ERR_LSB) +#define SPI_STATUS_ADDR_ERR_SET(x) (((x) << SPI_STATUS_ADDR_ERR_LSB) & SPI_STATUS_ADDR_ERR_MASK) +#define SPI_STATUS_RD_ERR_MSB 2 +#define SPI_STATUS_RD_ERR_LSB 2 +#define SPI_STATUS_RD_ERR_MASK 0x00000004 +#define SPI_STATUS_RD_ERR_GET(x) (((x)&SPI_STATUS_RD_ERR_MASK) >> SPI_STATUS_RD_ERR_LSB) +#define SPI_STATUS_RD_ERR_SET(x) (((x) << SPI_STATUS_RD_ERR_LSB) & SPI_STATUS_RD_ERR_MASK) +#define SPI_STATUS_WR_ERR_MSB 1 +#define SPI_STATUS_WR_ERR_LSB 1 +#define SPI_STATUS_WR_ERR_MASK 0x00000002 +#define SPI_STATUS_WR_ERR_GET(x) (((x)&SPI_STATUS_WR_ERR_MASK) >> SPI_STATUS_WR_ERR_LSB) +#define SPI_STATUS_WR_ERR_SET(x) (((x) << SPI_STATUS_WR_ERR_LSB) & SPI_STATUS_WR_ERR_MASK) +#define SPI_STATUS_READY_MSB 0 +#define SPI_STATUS_READY_LSB 0 +#define SPI_STATUS_READY_MASK 0x00000001 +#define SPI_STATUS_READY_GET(x) (((x)&SPI_STATUS_READY_MASK) >> SPI_STATUS_READY_LSB) +#define SPI_STATUS_READY_SET(x) (((x) << SPI_STATUS_READY_LSB) & SPI_STATUS_READY_MASK) + +#define NON_ASSOC_SLEEP_EN_ADDRESS 0x00000482 +#define NON_ASSOC_SLEEP_EN_OFFSET 0x00000482 +#define NON_ASSOC_SLEEP_EN_BIT_MSB 0 +#define NON_ASSOC_SLEEP_EN_BIT_LSB 0 +#define NON_ASSOC_SLEEP_EN_BIT_MASK 0x00000001 +#define NON_ASSOC_SLEEP_EN_BIT_GET(x) (((x)&NON_ASSOC_SLEEP_EN_BIT_MASK) >> NON_ASSOC_SLEEP_EN_BIT_LSB) +#define NON_ASSOC_SLEEP_EN_BIT_SET(x) (((x) << NON_ASSOC_SLEEP_EN_BIT_LSB) & NON_ASSOC_SLEEP_EN_BIT_MASK) + +#define CIS_WINDOW_ADDRESS 0x00000600 +#define CIS_WINDOW_OFFSET 0x00000600 +#define CIS_WINDOW_DATA_MSB 7 +#define CIS_WINDOW_DATA_LSB 0 +#define CIS_WINDOW_DATA_MASK 0x000000ff +#define CIS_WINDOW_DATA_GET(x) (((x)&CIS_WINDOW_DATA_MASK) >> CIS_WINDOW_DATA_LSB) +#define CIS_WINDOW_DATA_SET(x) (((x) << CIS_WINDOW_DATA_LSB) & CIS_WINDOW_DATA_MASK) + +#ifndef __ASSEMBLER__ + +typedef struct mbox_host_reg_reg_s +{ + unsigned char pad0[1024]; /* pad to 0x400 */ + volatile unsigned char host_int_status; + volatile unsigned char cpu_int_status; + volatile unsigned char error_int_status; + volatile unsigned char counter_int_status; + volatile unsigned char mbox_frame; + volatile unsigned char rx_lookahead_valid; + unsigned char pad1[2]; /* pad to 0x408 */ + volatile unsigned char rx_lookahead0[4]; + volatile unsigned char rx_lookahead1[4]; + volatile unsigned char rx_lookahead2[4]; + volatile unsigned char rx_lookahead3[4]; + volatile unsigned char int_status_enable; + volatile unsigned char cpu_int_status_enable; + volatile unsigned char error_status_enable; + volatile unsigned char counter_int_status_enable; + unsigned char pad2[4]; /* pad to 0x420 */ + volatile unsigned char count[8]; + unsigned char pad3[24]; /* pad to 0x440 */ + volatile unsigned char count_dec[32]; + volatile unsigned char scratch[8]; + volatile unsigned char fifo_timeout; + volatile unsigned char fifo_timeout_enable; + volatile unsigned char disable_sleep; + unsigned char pad4[5]; /* pad to 0x470 */ + volatile unsigned char local_bus; + unsigned char pad5[1]; /* pad to 0x472 */ + volatile unsigned char int_wlan; + unsigned char pad6[1]; /* pad to 0x474 */ + volatile unsigned char window_data[4]; + volatile unsigned char window_write_addr[4]; + volatile unsigned char window_read_addr[4]; + volatile unsigned char spi_config; + volatile unsigned char spi_status; + volatile unsigned char non_assoc_sleep_en; + unsigned char pad7[381]; /* pad to 0x600 */ + volatile unsigned char cis_window[512]; +} mbox_host_reg_reg_t; + +#endif /* __ASSEMBLER__ */ + +#endif /* _MBOX_HOST_REG_H_ */ diff --git a/platform/mcu/lpc54102/wifi_qca/include/AR6002/hw2.0/hw/hw20_mbox_reg.h b/platform/mcu/lpc54102/wifi_qca/include/AR6002/hw2.0/hw/hw20_mbox_reg.h new file mode 100644 index 0000000000..582f822f9a --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/include/AR6002/hw2.0/hw/hw20_mbox_reg.h @@ -0,0 +1,540 @@ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== +#ifndef _MBOX_REG_REG_H_ +#define _MBOX_REG_REG_H_ + +#define MBOX_FIFO_ADDRESS 0x00000000 +#define MBOX_FIFO_OFFSET 0x00000000 +#define MBOX_FIFO_DATA_MSB 19 +#define MBOX_FIFO_DATA_LSB 0 +#define MBOX_FIFO_DATA_MASK 0x000fffff +#define MBOX_FIFO_DATA_GET(x) (((x)&MBOX_FIFO_DATA_MASK) >> MBOX_FIFO_DATA_LSB) +#define MBOX_FIFO_DATA_SET(x) (((x) << MBOX_FIFO_DATA_LSB) & MBOX_FIFO_DATA_MASK) + +#define MBOX_FIFO_STATUS_ADDRESS 0x00000010 +#define MBOX_FIFO_STATUS_OFFSET 0x00000010 +#define MBOX_FIFO_STATUS_EMPTY_MSB 19 +#define MBOX_FIFO_STATUS_EMPTY_LSB 16 +#define MBOX_FIFO_STATUS_EMPTY_MASK 0x000f0000 +#define MBOX_FIFO_STATUS_EMPTY_GET(x) (((x)&MBOX_FIFO_STATUS_EMPTY_MASK) >> MBOX_FIFO_STATUS_EMPTY_LSB) +#define MBOX_FIFO_STATUS_EMPTY_SET(x) (((x) << MBOX_FIFO_STATUS_EMPTY_LSB) & MBOX_FIFO_STATUS_EMPTY_MASK) +#define MBOX_FIFO_STATUS_FULL_MSB 15 +#define MBOX_FIFO_STATUS_FULL_LSB 12 +#define MBOX_FIFO_STATUS_FULL_MASK 0x0000f000 +#define MBOX_FIFO_STATUS_FULL_GET(x) (((x)&MBOX_FIFO_STATUS_FULL_MASK) >> MBOX_FIFO_STATUS_FULL_LSB) +#define MBOX_FIFO_STATUS_FULL_SET(x) (((x) << MBOX_FIFO_STATUS_FULL_LSB) & MBOX_FIFO_STATUS_FULL_MASK) + +#define MBOX_DMA_POLICY_ADDRESS 0x00000014 +#define MBOX_DMA_POLICY_OFFSET 0x00000014 +#define MBOX_DMA_POLICY_TX_QUANTUM_MSB 3 +#define MBOX_DMA_POLICY_TX_QUANTUM_LSB 3 +#define MBOX_DMA_POLICY_TX_QUANTUM_MASK 0x00000008 +#define MBOX_DMA_POLICY_TX_QUANTUM_GET(x) (((x)&MBOX_DMA_POLICY_TX_QUANTUM_MASK) >> MBOX_DMA_POLICY_TX_QUANTUM_LSB) +#define MBOX_DMA_POLICY_TX_QUANTUM_SET(x) (((x) << MBOX_DMA_POLICY_TX_QUANTUM_LSB) & MBOX_DMA_POLICY_TX_QUANTUM_MASK) +#define MBOX_DMA_POLICY_TX_ORDER_MSB 2 +#define MBOX_DMA_POLICY_TX_ORDER_LSB 2 +#define MBOX_DMA_POLICY_TX_ORDER_MASK 0x00000004 +#define MBOX_DMA_POLICY_TX_ORDER_GET(x) (((x)&MBOX_DMA_POLICY_TX_ORDER_MASK) >> MBOX_DMA_POLICY_TX_ORDER_LSB) +#define MBOX_DMA_POLICY_TX_ORDER_SET(x) (((x) << MBOX_DMA_POLICY_TX_ORDER_LSB) & MBOX_DMA_POLICY_TX_ORDER_MASK) +#define MBOX_DMA_POLICY_RX_QUANTUM_MSB 1 +#define MBOX_DMA_POLICY_RX_QUANTUM_LSB 1 +#define MBOX_DMA_POLICY_RX_QUANTUM_MASK 0x00000002 +#define MBOX_DMA_POLICY_RX_QUANTUM_GET(x) (((x)&MBOX_DMA_POLICY_RX_QUANTUM_MASK) >> MBOX_DMA_POLICY_RX_QUANTUM_LSB) +#define MBOX_DMA_POLICY_RX_QUANTUM_SET(x) (((x) << MBOX_DMA_POLICY_RX_QUANTUM_LSB) & MBOX_DMA_POLICY_RX_QUANTUM_MASK) +#define MBOX_DMA_POLICY_RX_ORDER_MSB 0 +#define MBOX_DMA_POLICY_RX_ORDER_LSB 0 +#define MBOX_DMA_POLICY_RX_ORDER_MASK 0x00000001 +#define MBOX_DMA_POLICY_RX_ORDER_GET(x) (((x)&MBOX_DMA_POLICY_RX_ORDER_MASK) >> MBOX_DMA_POLICY_RX_ORDER_LSB) +#define MBOX_DMA_POLICY_RX_ORDER_SET(x) (((x) << MBOX_DMA_POLICY_RX_ORDER_LSB) & MBOX_DMA_POLICY_RX_ORDER_MASK) + +#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS 0x00000018 +#define MBOX0_DMA_RX_DESCRIPTOR_BASE_OFFSET 0x00000018 +#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB 27 +#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB 2 +#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc +#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) \ + (((x)&MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) >> MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) +#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) \ + (((x) << MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) & MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) + +#define MBOX0_DMA_RX_CONTROL_ADDRESS 0x0000001c +#define MBOX0_DMA_RX_CONTROL_OFFSET 0x0000001c +#define MBOX0_DMA_RX_CONTROL_RESUME_MSB 2 +#define MBOX0_DMA_RX_CONTROL_RESUME_LSB 2 +#define MBOX0_DMA_RX_CONTROL_RESUME_MASK 0x00000004 +#define MBOX0_DMA_RX_CONTROL_RESUME_GET(x) (((x)&MBOX0_DMA_RX_CONTROL_RESUME_MASK) >> MBOX0_DMA_RX_CONTROL_RESUME_LSB) +#define MBOX0_DMA_RX_CONTROL_RESUME_SET(x) (((x) << MBOX0_DMA_RX_CONTROL_RESUME_LSB) & MBOX0_DMA_RX_CONTROL_RESUME_MASK) +#define MBOX0_DMA_RX_CONTROL_START_MSB 1 +#define MBOX0_DMA_RX_CONTROL_START_LSB 1 +#define MBOX0_DMA_RX_CONTROL_START_MASK 0x00000002 +#define MBOX0_DMA_RX_CONTROL_START_GET(x) (((x)&MBOX0_DMA_RX_CONTROL_START_MASK) >> MBOX0_DMA_RX_CONTROL_START_LSB) +#define MBOX0_DMA_RX_CONTROL_START_SET(x) (((x) << MBOX0_DMA_RX_CONTROL_START_LSB) & MBOX0_DMA_RX_CONTROL_START_MASK) +#define MBOX0_DMA_RX_CONTROL_STOP_MSB 0 +#define MBOX0_DMA_RX_CONTROL_STOP_LSB 0 +#define MBOX0_DMA_RX_CONTROL_STOP_MASK 0x00000001 +#define MBOX0_DMA_RX_CONTROL_STOP_GET(x) (((x)&MBOX0_DMA_RX_CONTROL_STOP_MASK) >> MBOX0_DMA_RX_CONTROL_STOP_LSB) +#define MBOX0_DMA_RX_CONTROL_STOP_SET(x) (((x) << MBOX0_DMA_RX_CONTROL_STOP_LSB) & MBOX0_DMA_RX_CONTROL_STOP_MASK) + +#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS 0x00000020 +#define MBOX0_DMA_TX_DESCRIPTOR_BASE_OFFSET 0x00000020 +#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB 27 +#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB 2 +#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc +#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) \ + (((x)&MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) >> MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) +#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) \ + (((x) << MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) & MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) + +#define MBOX0_DMA_TX_CONTROL_ADDRESS 0x00000024 +#define MBOX0_DMA_TX_CONTROL_OFFSET 0x00000024 +#define MBOX0_DMA_TX_CONTROL_RESUME_MSB 2 +#define MBOX0_DMA_TX_CONTROL_RESUME_LSB 2 +#define MBOX0_DMA_TX_CONTROL_RESUME_MASK 0x00000004 +#define MBOX0_DMA_TX_CONTROL_RESUME_GET(x) (((x)&MBOX0_DMA_TX_CONTROL_RESUME_MASK) >> MBOX0_DMA_TX_CONTROL_RESUME_LSB) +#define MBOX0_DMA_TX_CONTROL_RESUME_SET(x) (((x) << MBOX0_DMA_TX_CONTROL_RESUME_LSB) & MBOX0_DMA_TX_CONTROL_RESUME_MASK) +#define MBOX0_DMA_TX_CONTROL_START_MSB 1 +#define MBOX0_DMA_TX_CONTROL_START_LSB 1 +#define MBOX0_DMA_TX_CONTROL_START_MASK 0x00000002 +#define MBOX0_DMA_TX_CONTROL_START_GET(x) (((x)&MBOX0_DMA_TX_CONTROL_START_MASK) >> MBOX0_DMA_TX_CONTROL_START_LSB) +#define MBOX0_DMA_TX_CONTROL_START_SET(x) (((x) << MBOX0_DMA_TX_CONTROL_START_LSB) & MBOX0_DMA_TX_CONTROL_START_MASK) +#define MBOX0_DMA_TX_CONTROL_STOP_MSB 0 +#define MBOX0_DMA_TX_CONTROL_STOP_LSB 0 +#define MBOX0_DMA_TX_CONTROL_STOP_MASK 0x00000001 +#define MBOX0_DMA_TX_CONTROL_STOP_GET(x) (((x)&MBOX0_DMA_TX_CONTROL_STOP_MASK) >> MBOX0_DMA_TX_CONTROL_STOP_LSB) +#define MBOX0_DMA_TX_CONTROL_STOP_SET(x) (((x) << MBOX0_DMA_TX_CONTROL_STOP_LSB) & MBOX0_DMA_TX_CONTROL_STOP_MASK) + +#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS 0x00000028 +#define MBOX1_DMA_RX_DESCRIPTOR_BASE_OFFSET 0x00000028 +#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB 27 +#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB 2 +#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc +#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) \ + (((x)&MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) >> MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) +#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) \ + (((x) << MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) & MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) + +#define MBOX1_DMA_RX_CONTROL_ADDRESS 0x0000002c +#define MBOX1_DMA_RX_CONTROL_OFFSET 0x0000002c +#define MBOX1_DMA_RX_CONTROL_RESUME_MSB 2 +#define MBOX1_DMA_RX_CONTROL_RESUME_LSB 2 +#define MBOX1_DMA_RX_CONTROL_RESUME_MASK 0x00000004 +#define MBOX1_DMA_RX_CONTROL_RESUME_GET(x) (((x)&MBOX1_DMA_RX_CONTROL_RESUME_MASK) >> MBOX1_DMA_RX_CONTROL_RESUME_LSB) +#define MBOX1_DMA_RX_CONTROL_RESUME_SET(x) (((x) << MBOX1_DMA_RX_CONTROL_RESUME_LSB) & MBOX1_DMA_RX_CONTROL_RESUME_MASK) +#define MBOX1_DMA_RX_CONTROL_START_MSB 1 +#define MBOX1_DMA_RX_CONTROL_START_LSB 1 +#define MBOX1_DMA_RX_CONTROL_START_MASK 0x00000002 +#define MBOX1_DMA_RX_CONTROL_START_GET(x) (((x)&MBOX1_DMA_RX_CONTROL_START_MASK) >> MBOX1_DMA_RX_CONTROL_START_LSB) +#define MBOX1_DMA_RX_CONTROL_START_SET(x) (((x) << MBOX1_DMA_RX_CONTROL_START_LSB) & MBOX1_DMA_RX_CONTROL_START_MASK) +#define MBOX1_DMA_RX_CONTROL_STOP_MSB 0 +#define MBOX1_DMA_RX_CONTROL_STOP_LSB 0 +#define MBOX1_DMA_RX_CONTROL_STOP_MASK 0x00000001 +#define MBOX1_DMA_RX_CONTROL_STOP_GET(x) (((x)&MBOX1_DMA_RX_CONTROL_STOP_MASK) >> MBOX1_DMA_RX_CONTROL_STOP_LSB) +#define MBOX1_DMA_RX_CONTROL_STOP_SET(x) (((x) << MBOX1_DMA_RX_CONTROL_STOP_LSB) & MBOX1_DMA_RX_CONTROL_STOP_MASK) + +#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS 0x00000030 +#define MBOX1_DMA_TX_DESCRIPTOR_BASE_OFFSET 0x00000030 +#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB 27 +#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB 2 +#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc +#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) \ + (((x)&MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) >> MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) +#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) \ + (((x) << MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) & MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) + +#define MBOX1_DMA_TX_CONTROL_ADDRESS 0x00000034 +#define MBOX1_DMA_TX_CONTROL_OFFSET 0x00000034 +#define MBOX1_DMA_TX_CONTROL_RESUME_MSB 2 +#define MBOX1_DMA_TX_CONTROL_RESUME_LSB 2 +#define MBOX1_DMA_TX_CONTROL_RESUME_MASK 0x00000004 +#define MBOX1_DMA_TX_CONTROL_RESUME_GET(x) (((x)&MBOX1_DMA_TX_CONTROL_RESUME_MASK) >> MBOX1_DMA_TX_CONTROL_RESUME_LSB) +#define MBOX1_DMA_TX_CONTROL_RESUME_SET(x) (((x) << MBOX1_DMA_TX_CONTROL_RESUME_LSB) & MBOX1_DMA_TX_CONTROL_RESUME_MASK) +#define MBOX1_DMA_TX_CONTROL_START_MSB 1 +#define MBOX1_DMA_TX_CONTROL_START_LSB 1 +#define MBOX1_DMA_TX_CONTROL_START_MASK 0x00000002 +#define MBOX1_DMA_TX_CONTROL_START_GET(x) (((x)&MBOX1_DMA_TX_CONTROL_START_MASK) >> MBOX1_DMA_TX_CONTROL_START_LSB) +#define MBOX1_DMA_TX_CONTROL_START_SET(x) (((x) << MBOX1_DMA_TX_CONTROL_START_LSB) & MBOX1_DMA_TX_CONTROL_START_MASK) +#define MBOX1_DMA_TX_CONTROL_STOP_MSB 0 +#define MBOX1_DMA_TX_CONTROL_STOP_LSB 0 +#define MBOX1_DMA_TX_CONTROL_STOP_MASK 0x00000001 +#define MBOX1_DMA_TX_CONTROL_STOP_GET(x) (((x)&MBOX1_DMA_TX_CONTROL_STOP_MASK) >> MBOX1_DMA_TX_CONTROL_STOP_LSB) +#define MBOX1_DMA_TX_CONTROL_STOP_SET(x) (((x) << MBOX1_DMA_TX_CONTROL_STOP_LSB) & MBOX1_DMA_TX_CONTROL_STOP_MASK) + +#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS 0x00000038 +#define MBOX2_DMA_RX_DESCRIPTOR_BASE_OFFSET 0x00000038 +#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB 27 +#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB 2 +#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc +#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) \ + (((x)&MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) >> MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) +#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) \ + (((x) << MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) & MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) + +#define MBOX2_DMA_RX_CONTROL_ADDRESS 0x0000003c +#define MBOX2_DMA_RX_CONTROL_OFFSET 0x0000003c +#define MBOX2_DMA_RX_CONTROL_RESUME_MSB 2 +#define MBOX2_DMA_RX_CONTROL_RESUME_LSB 2 +#define MBOX2_DMA_RX_CONTROL_RESUME_MASK 0x00000004 +#define MBOX2_DMA_RX_CONTROL_RESUME_GET(x) (((x)&MBOX2_DMA_RX_CONTROL_RESUME_MASK) >> MBOX2_DMA_RX_CONTROL_RESUME_LSB) +#define MBOX2_DMA_RX_CONTROL_RESUME_SET(x) (((x) << MBOX2_DMA_RX_CONTROL_RESUME_LSB) & MBOX2_DMA_RX_CONTROL_RESUME_MASK) +#define MBOX2_DMA_RX_CONTROL_START_MSB 1 +#define MBOX2_DMA_RX_CONTROL_START_LSB 1 +#define MBOX2_DMA_RX_CONTROL_START_MASK 0x00000002 +#define MBOX2_DMA_RX_CONTROL_START_GET(x) (((x)&MBOX2_DMA_RX_CONTROL_START_MASK) >> MBOX2_DMA_RX_CONTROL_START_LSB) +#define MBOX2_DMA_RX_CONTROL_START_SET(x) (((x) << MBOX2_DMA_RX_CONTROL_START_LSB) & MBOX2_DMA_RX_CONTROL_START_MASK) +#define MBOX2_DMA_RX_CONTROL_STOP_MSB 0 +#define MBOX2_DMA_RX_CONTROL_STOP_LSB 0 +#define MBOX2_DMA_RX_CONTROL_STOP_MASK 0x00000001 +#define MBOX2_DMA_RX_CONTROL_STOP_GET(x) (((x)&MBOX2_DMA_RX_CONTROL_STOP_MASK) >> MBOX2_DMA_RX_CONTROL_STOP_LSB) +#define MBOX2_DMA_RX_CONTROL_STOP_SET(x) (((x) << MBOX2_DMA_RX_CONTROL_STOP_LSB) & MBOX2_DMA_RX_CONTROL_STOP_MASK) + +#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS 0x00000040 +#define MBOX2_DMA_TX_DESCRIPTOR_BASE_OFFSET 0x00000040 +#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB 27 +#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB 2 +#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc +#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) \ + (((x)&MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) >> MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) +#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) \ + (((x) << MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) & MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) + +#define MBOX2_DMA_TX_CONTROL_ADDRESS 0x00000044 +#define MBOX2_DMA_TX_CONTROL_OFFSET 0x00000044 +#define MBOX2_DMA_TX_CONTROL_RESUME_MSB 2 +#define MBOX2_DMA_TX_CONTROL_RESUME_LSB 2 +#define MBOX2_DMA_TX_CONTROL_RESUME_MASK 0x00000004 +#define MBOX2_DMA_TX_CONTROL_RESUME_GET(x) (((x)&MBOX2_DMA_TX_CONTROL_RESUME_MASK) >> MBOX2_DMA_TX_CONTROL_RESUME_LSB) +#define MBOX2_DMA_TX_CONTROL_RESUME_SET(x) (((x) << MBOX2_DMA_TX_CONTROL_RESUME_LSB) & MBOX2_DMA_TX_CONTROL_RESUME_MASK) +#define MBOX2_DMA_TX_CONTROL_START_MSB 1 +#define MBOX2_DMA_TX_CONTROL_START_LSB 1 +#define MBOX2_DMA_TX_CONTROL_START_MASK 0x00000002 +#define MBOX2_DMA_TX_CONTROL_START_GET(x) (((x)&MBOX2_DMA_TX_CONTROL_START_MASK) >> MBOX2_DMA_TX_CONTROL_START_LSB) +#define MBOX2_DMA_TX_CONTROL_START_SET(x) (((x) << MBOX2_DMA_TX_CONTROL_START_LSB) & MBOX2_DMA_TX_CONTROL_START_MASK) +#define MBOX2_DMA_TX_CONTROL_STOP_MSB 0 +#define MBOX2_DMA_TX_CONTROL_STOP_LSB 0 +#define MBOX2_DMA_TX_CONTROL_STOP_MASK 0x00000001 +#define MBOX2_DMA_TX_CONTROL_STOP_GET(x) (((x)&MBOX2_DMA_TX_CONTROL_STOP_MASK) >> MBOX2_DMA_TX_CONTROL_STOP_LSB) +#define MBOX2_DMA_TX_CONTROL_STOP_SET(x) (((x) << MBOX2_DMA_TX_CONTROL_STOP_LSB) & MBOX2_DMA_TX_CONTROL_STOP_MASK) + +#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS 0x00000048 +#define MBOX3_DMA_RX_DESCRIPTOR_BASE_OFFSET 0x00000048 +#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB 27 +#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB 2 +#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc +#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) \ + (((x)&MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) >> MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) +#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) \ + (((x) << MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) & MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) + +#define MBOX3_DMA_RX_CONTROL_ADDRESS 0x0000004c +#define MBOX3_DMA_RX_CONTROL_OFFSET 0x0000004c +#define MBOX3_DMA_RX_CONTROL_RESUME_MSB 2 +#define MBOX3_DMA_RX_CONTROL_RESUME_LSB 2 +#define MBOX3_DMA_RX_CONTROL_RESUME_MASK 0x00000004 +#define MBOX3_DMA_RX_CONTROL_RESUME_GET(x) (((x)&MBOX3_DMA_RX_CONTROL_RESUME_MASK) >> MBOX3_DMA_RX_CONTROL_RESUME_LSB) +#define MBOX3_DMA_RX_CONTROL_RESUME_SET(x) (((x) << MBOX3_DMA_RX_CONTROL_RESUME_LSB) & MBOX3_DMA_RX_CONTROL_RESUME_MASK) +#define MBOX3_DMA_RX_CONTROL_START_MSB 1 +#define MBOX3_DMA_RX_CONTROL_START_LSB 1 +#define MBOX3_DMA_RX_CONTROL_START_MASK 0x00000002 +#define MBOX3_DMA_RX_CONTROL_START_GET(x) (((x)&MBOX3_DMA_RX_CONTROL_START_MASK) >> MBOX3_DMA_RX_CONTROL_START_LSB) +#define MBOX3_DMA_RX_CONTROL_START_SET(x) (((x) << MBOX3_DMA_RX_CONTROL_START_LSB) & MBOX3_DMA_RX_CONTROL_START_MASK) +#define MBOX3_DMA_RX_CONTROL_STOP_MSB 0 +#define MBOX3_DMA_RX_CONTROL_STOP_LSB 0 +#define MBOX3_DMA_RX_CONTROL_STOP_MASK 0x00000001 +#define MBOX3_DMA_RX_CONTROL_STOP_GET(x) (((x)&MBOX3_DMA_RX_CONTROL_STOP_MASK) >> MBOX3_DMA_RX_CONTROL_STOP_LSB) +#define MBOX3_DMA_RX_CONTROL_STOP_SET(x) (((x) << MBOX3_DMA_RX_CONTROL_STOP_LSB) & MBOX3_DMA_RX_CONTROL_STOP_MASK) + +#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS 0x00000050 +#define MBOX3_DMA_TX_DESCRIPTOR_BASE_OFFSET 0x00000050 +#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB 27 +#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB 2 +#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc +#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) \ + (((x)&MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) >> MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) +#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) \ + (((x) << MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) & MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) + +#define MBOX3_DMA_TX_CONTROL_ADDRESS 0x00000054 +#define MBOX3_DMA_TX_CONTROL_OFFSET 0x00000054 +#define MBOX3_DMA_TX_CONTROL_RESUME_MSB 2 +#define MBOX3_DMA_TX_CONTROL_RESUME_LSB 2 +#define MBOX3_DMA_TX_CONTROL_RESUME_MASK 0x00000004 +#define MBOX3_DMA_TX_CONTROL_RESUME_GET(x) (((x)&MBOX3_DMA_TX_CONTROL_RESUME_MASK) >> MBOX3_DMA_TX_CONTROL_RESUME_LSB) +#define MBOX3_DMA_TX_CONTROL_RESUME_SET(x) (((x) << MBOX3_DMA_TX_CONTROL_RESUME_LSB) & MBOX3_DMA_TX_CONTROL_RESUME_MASK) +#define MBOX3_DMA_TX_CONTROL_START_MSB 1 +#define MBOX3_DMA_TX_CONTROL_START_LSB 1 +#define MBOX3_DMA_TX_CONTROL_START_MASK 0x00000002 +#define MBOX3_DMA_TX_CONTROL_START_GET(x) (((x)&MBOX3_DMA_TX_CONTROL_START_MASK) >> MBOX3_DMA_TX_CONTROL_START_LSB) +#define MBOX3_DMA_TX_CONTROL_START_SET(x) (((x) << MBOX3_DMA_TX_CONTROL_START_LSB) & MBOX3_DMA_TX_CONTROL_START_MASK) +#define MBOX3_DMA_TX_CONTROL_STOP_MSB 0 +#define MBOX3_DMA_TX_CONTROL_STOP_LSB 0 +#define MBOX3_DMA_TX_CONTROL_STOP_MASK 0x00000001 +#define MBOX3_DMA_TX_CONTROL_STOP_GET(x) (((x)&MBOX3_DMA_TX_CONTROL_STOP_MASK) >> MBOX3_DMA_TX_CONTROL_STOP_LSB) +#define MBOX3_DMA_TX_CONTROL_STOP_SET(x) (((x) << MBOX3_DMA_TX_CONTROL_STOP_LSB) & MBOX3_DMA_TX_CONTROL_STOP_MASK) + +#define MBOX_INT_STATUS_ADDRESS 0x00000058 +#define MBOX_INT_STATUS_OFFSET 0x00000058 +#define MBOX_INT_STATUS_RX_DMA_COMPLETE_MSB 31 +#define MBOX_INT_STATUS_RX_DMA_COMPLETE_LSB 28 +#define MBOX_INT_STATUS_RX_DMA_COMPLETE_MASK 0xf0000000 +#define MBOX_INT_STATUS_RX_DMA_COMPLETE_GET(x) \ + (((x)&MBOX_INT_STATUS_RX_DMA_COMPLETE_MASK) >> MBOX_INT_STATUS_RX_DMA_COMPLETE_LSB) +#define MBOX_INT_STATUS_RX_DMA_COMPLETE_SET(x) \ + (((x) << MBOX_INT_STATUS_RX_DMA_COMPLETE_LSB) & MBOX_INT_STATUS_RX_DMA_COMPLETE_MASK) +#define MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MSB 27 +#define MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB 24 +#define MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK 0x0f000000 +#define MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_GET(x) \ + (((x)&MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK) >> MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB) +#define MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_SET(x) \ + (((x) << MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB) & MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK) +#define MBOX_INT_STATUS_TX_DMA_COMPLETE_MSB 23 +#define MBOX_INT_STATUS_TX_DMA_COMPLETE_LSB 20 +#define MBOX_INT_STATUS_TX_DMA_COMPLETE_MASK 0x00f00000 +#define MBOX_INT_STATUS_TX_DMA_COMPLETE_GET(x) \ + (((x)&MBOX_INT_STATUS_TX_DMA_COMPLETE_MASK) >> MBOX_INT_STATUS_TX_DMA_COMPLETE_LSB) +#define MBOX_INT_STATUS_TX_DMA_COMPLETE_SET(x) \ + (((x) << MBOX_INT_STATUS_TX_DMA_COMPLETE_LSB) & MBOX_INT_STATUS_TX_DMA_COMPLETE_MASK) +#define MBOX_INT_STATUS_TX_OVERFLOW_MSB 17 +#define MBOX_INT_STATUS_TX_OVERFLOW_LSB 17 +#define MBOX_INT_STATUS_TX_OVERFLOW_MASK 0x00020000 +#define MBOX_INT_STATUS_TX_OVERFLOW_GET(x) (((x)&MBOX_INT_STATUS_TX_OVERFLOW_MASK) >> MBOX_INT_STATUS_TX_OVERFLOW_LSB) +#define MBOX_INT_STATUS_TX_OVERFLOW_SET(x) (((x) << MBOX_INT_STATUS_TX_OVERFLOW_LSB) & MBOX_INT_STATUS_TX_OVERFLOW_MASK) +#define MBOX_INT_STATUS_RX_UNDERFLOW_MSB 16 +#define MBOX_INT_STATUS_RX_UNDERFLOW_LSB 16 +#define MBOX_INT_STATUS_RX_UNDERFLOW_MASK 0x00010000 +#define MBOX_INT_STATUS_RX_UNDERFLOW_GET(x) \ + (((x)&MBOX_INT_STATUS_RX_UNDERFLOW_MASK) >> MBOX_INT_STATUS_RX_UNDERFLOW_LSB) +#define MBOX_INT_STATUS_RX_UNDERFLOW_SET(x) \ + (((x) << MBOX_INT_STATUS_RX_UNDERFLOW_LSB) & MBOX_INT_STATUS_RX_UNDERFLOW_MASK) +#define MBOX_INT_STATUS_TX_NOT_EMPTY_MSB 15 +#define MBOX_INT_STATUS_TX_NOT_EMPTY_LSB 12 +#define MBOX_INT_STATUS_TX_NOT_EMPTY_MASK 0x0000f000 +#define MBOX_INT_STATUS_TX_NOT_EMPTY_GET(x) \ + (((x)&MBOX_INT_STATUS_TX_NOT_EMPTY_MASK) >> MBOX_INT_STATUS_TX_NOT_EMPTY_LSB) +#define MBOX_INT_STATUS_TX_NOT_EMPTY_SET(x) \ + (((x) << MBOX_INT_STATUS_TX_NOT_EMPTY_LSB) & MBOX_INT_STATUS_TX_NOT_EMPTY_MASK) +#define MBOX_INT_STATUS_RX_NOT_FULL_MSB 11 +#define MBOX_INT_STATUS_RX_NOT_FULL_LSB 8 +#define MBOX_INT_STATUS_RX_NOT_FULL_MASK 0x00000f00 +#define MBOX_INT_STATUS_RX_NOT_FULL_GET(x) (((x)&MBOX_INT_STATUS_RX_NOT_FULL_MASK) >> MBOX_INT_STATUS_RX_NOT_FULL_LSB) +#define MBOX_INT_STATUS_RX_NOT_FULL_SET(x) (((x) << MBOX_INT_STATUS_RX_NOT_FULL_LSB) & MBOX_INT_STATUS_RX_NOT_FULL_MASK) +#define MBOX_INT_STATUS_HOST_MSB 7 +#define MBOX_INT_STATUS_HOST_LSB 0 +#define MBOX_INT_STATUS_HOST_MASK 0x000000ff +#define MBOX_INT_STATUS_HOST_GET(x) (((x)&MBOX_INT_STATUS_HOST_MASK) >> MBOX_INT_STATUS_HOST_LSB) +#define MBOX_INT_STATUS_HOST_SET(x) (((x) << MBOX_INT_STATUS_HOST_LSB) & MBOX_INT_STATUS_HOST_MASK) + +#define MBOX_INT_ENABLE_ADDRESS 0x0000005c +#define MBOX_INT_ENABLE_OFFSET 0x0000005c +#define MBOX_INT_ENABLE_RX_DMA_COMPLETE_MSB 31 +#define MBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB 28 +#define MBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK 0xf0000000 +#define MBOX_INT_ENABLE_RX_DMA_COMPLETE_GET(x) \ + (((x)&MBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK) >> MBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB) +#define MBOX_INT_ENABLE_RX_DMA_COMPLETE_SET(x) \ + (((x) << MBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB) & MBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK) +#define MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MSB 27 +#define MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB 24 +#define MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK 0x0f000000 +#define MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_GET(x) \ + (((x)&MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK) >> MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB) +#define MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_SET(x) \ + (((x) << MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB) & MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK) +#define MBOX_INT_ENABLE_TX_DMA_COMPLETE_MSB 23 +#define MBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB 20 +#define MBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK 0x00f00000 +#define MBOX_INT_ENABLE_TX_DMA_COMPLETE_GET(x) \ + (((x)&MBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK) >> MBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB) +#define MBOX_INT_ENABLE_TX_DMA_COMPLETE_SET(x) \ + (((x) << MBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB) & MBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK) +#define MBOX_INT_ENABLE_TX_OVERFLOW_MSB 17 +#define MBOX_INT_ENABLE_TX_OVERFLOW_LSB 17 +#define MBOX_INT_ENABLE_TX_OVERFLOW_MASK 0x00020000 +#define MBOX_INT_ENABLE_TX_OVERFLOW_GET(x) (((x)&MBOX_INT_ENABLE_TX_OVERFLOW_MASK) >> MBOX_INT_ENABLE_TX_OVERFLOW_LSB) +#define MBOX_INT_ENABLE_TX_OVERFLOW_SET(x) (((x) << MBOX_INT_ENABLE_TX_OVERFLOW_LSB) & MBOX_INT_ENABLE_TX_OVERFLOW_MASK) +#define MBOX_INT_ENABLE_RX_UNDERFLOW_MSB 16 +#define MBOX_INT_ENABLE_RX_UNDERFLOW_LSB 16 +#define MBOX_INT_ENABLE_RX_UNDERFLOW_MASK 0x00010000 +#define MBOX_INT_ENABLE_RX_UNDERFLOW_GET(x) \ + (((x)&MBOX_INT_ENABLE_RX_UNDERFLOW_MASK) >> MBOX_INT_ENABLE_RX_UNDERFLOW_LSB) +#define MBOX_INT_ENABLE_RX_UNDERFLOW_SET(x) \ + (((x) << MBOX_INT_ENABLE_RX_UNDERFLOW_LSB) & MBOX_INT_ENABLE_RX_UNDERFLOW_MASK) +#define MBOX_INT_ENABLE_TX_NOT_EMPTY_MSB 15 +#define MBOX_INT_ENABLE_TX_NOT_EMPTY_LSB 12 +#define MBOX_INT_ENABLE_TX_NOT_EMPTY_MASK 0x0000f000 +#define MBOX_INT_ENABLE_TX_NOT_EMPTY_GET(x) \ + (((x)&MBOX_INT_ENABLE_TX_NOT_EMPTY_MASK) >> MBOX_INT_ENABLE_TX_NOT_EMPTY_LSB) +#define MBOX_INT_ENABLE_TX_NOT_EMPTY_SET(x) \ + (((x) << MBOX_INT_ENABLE_TX_NOT_EMPTY_LSB) & MBOX_INT_ENABLE_TX_NOT_EMPTY_MASK) +#define MBOX_INT_ENABLE_RX_NOT_FULL_MSB 11 +#define MBOX_INT_ENABLE_RX_NOT_FULL_LSB 8 +#define MBOX_INT_ENABLE_RX_NOT_FULL_MASK 0x00000f00 +#define MBOX_INT_ENABLE_RX_NOT_FULL_GET(x) (((x)&MBOX_INT_ENABLE_RX_NOT_FULL_MASK) >> MBOX_INT_ENABLE_RX_NOT_FULL_LSB) +#define MBOX_INT_ENABLE_RX_NOT_FULL_SET(x) (((x) << MBOX_INT_ENABLE_RX_NOT_FULL_LSB) & MBOX_INT_ENABLE_RX_NOT_FULL_MASK) +#define MBOX_INT_ENABLE_HOST_MSB 7 +#define MBOX_INT_ENABLE_HOST_LSB 0 +#define MBOX_INT_ENABLE_HOST_MASK 0x000000ff +#define MBOX_INT_ENABLE_HOST_GET(x) (((x)&MBOX_INT_ENABLE_HOST_MASK) >> MBOX_INT_ENABLE_HOST_LSB) +#define MBOX_INT_ENABLE_HOST_SET(x) (((x) << MBOX_INT_ENABLE_HOST_LSB) & MBOX_INT_ENABLE_HOST_MASK) + +#define INT_HOST_ADDRESS 0x00000060 +#define INT_HOST_OFFSET 0x00000060 +#define INT_HOST_VECTOR_MSB 7 +#define INT_HOST_VECTOR_LSB 0 +#define INT_HOST_VECTOR_MASK 0x000000ff +#define INT_HOST_VECTOR_GET(x) (((x)&INT_HOST_VECTOR_MASK) >> INT_HOST_VECTOR_LSB) +#define INT_HOST_VECTOR_SET(x) (((x) << INT_HOST_VECTOR_LSB) & INT_HOST_VECTOR_MASK) + +#define LOCAL_COUNT_ADDRESS 0x00000080 +#define LOCAL_COUNT_OFFSET 0x00000080 +#define LOCAL_COUNT_VALUE_MSB 7 +#define LOCAL_COUNT_VALUE_LSB 0 +#define LOCAL_COUNT_VALUE_MASK 0x000000ff +#define LOCAL_COUNT_VALUE_GET(x) (((x)&LOCAL_COUNT_VALUE_MASK) >> LOCAL_COUNT_VALUE_LSB) +#define LOCAL_COUNT_VALUE_SET(x) (((x) << LOCAL_COUNT_VALUE_LSB) & LOCAL_COUNT_VALUE_MASK) + +#define COUNT_INC_ADDRESS 0x000000a0 +#define COUNT_INC_OFFSET 0x000000a0 +#define COUNT_INC_VALUE_MSB 7 +#define COUNT_INC_VALUE_LSB 0 +#define COUNT_INC_VALUE_MASK 0x000000ff +#define COUNT_INC_VALUE_GET(x) (((x)&COUNT_INC_VALUE_MASK) >> COUNT_INC_VALUE_LSB) +#define COUNT_INC_VALUE_SET(x) (((x) << COUNT_INC_VALUE_LSB) & COUNT_INC_VALUE_MASK) + +#define LOCAL_SCRATCH_ADDRESS 0x000000c0 +#define LOCAL_SCRATCH_OFFSET 0x000000c0 +#define LOCAL_SCRATCH_VALUE_MSB 7 +#define LOCAL_SCRATCH_VALUE_LSB 0 +#define LOCAL_SCRATCH_VALUE_MASK 0x000000ff +#define LOCAL_SCRATCH_VALUE_GET(x) (((x)&LOCAL_SCRATCH_VALUE_MASK) >> LOCAL_SCRATCH_VALUE_LSB) +#define LOCAL_SCRATCH_VALUE_SET(x) (((x) << LOCAL_SCRATCH_VALUE_LSB) & LOCAL_SCRATCH_VALUE_MASK) + +#define USE_LOCAL_BUS_ADDRESS 0x000000e0 +#define USE_LOCAL_BUS_OFFSET 0x000000e0 +#define USE_LOCAL_BUS_PIN_INIT_MSB 0 +#define USE_LOCAL_BUS_PIN_INIT_LSB 0 +#define USE_LOCAL_BUS_PIN_INIT_MASK 0x00000001 +#define USE_LOCAL_BUS_PIN_INIT_GET(x) (((x)&USE_LOCAL_BUS_PIN_INIT_MASK) >> USE_LOCAL_BUS_PIN_INIT_LSB) +#define USE_LOCAL_BUS_PIN_INIT_SET(x) (((x) << USE_LOCAL_BUS_PIN_INIT_LSB) & USE_LOCAL_BUS_PIN_INIT_MASK) + +#define SDIO_CONFIG_ADDRESS 0x000000e4 +#define SDIO_CONFIG_OFFSET 0x000000e4 +#define SDIO_CONFIG_CCCR_IOR1_MSB 0 +#define SDIO_CONFIG_CCCR_IOR1_LSB 0 +#define SDIO_CONFIG_CCCR_IOR1_MASK 0x00000001 +#define SDIO_CONFIG_CCCR_IOR1_GET(x) (((x)&SDIO_CONFIG_CCCR_IOR1_MASK) >> SDIO_CONFIG_CCCR_IOR1_LSB) +#define SDIO_CONFIG_CCCR_IOR1_SET(x) (((x) << SDIO_CONFIG_CCCR_IOR1_LSB) & SDIO_CONFIG_CCCR_IOR1_MASK) + +#define MBOX_DEBUG_ADDRESS 0x000000e8 +#define MBOX_DEBUG_OFFSET 0x000000e8 +#define MBOX_DEBUG_SEL_MSB 2 +#define MBOX_DEBUG_SEL_LSB 0 +#define MBOX_DEBUG_SEL_MASK 0x00000007 +#define MBOX_DEBUG_SEL_GET(x) (((x)&MBOX_DEBUG_SEL_MASK) >> MBOX_DEBUG_SEL_LSB) +#define MBOX_DEBUG_SEL_SET(x) (((x) << MBOX_DEBUG_SEL_LSB) & MBOX_DEBUG_SEL_MASK) + +#define MBOX_FIFO_RESET_ADDRESS 0x000000ec +#define MBOX_FIFO_RESET_OFFSET 0x000000ec +#define MBOX_FIFO_RESET_INIT_MSB 0 +#define MBOX_FIFO_RESET_INIT_LSB 0 +#define MBOX_FIFO_RESET_INIT_MASK 0x00000001 +#define MBOX_FIFO_RESET_INIT_GET(x) (((x)&MBOX_FIFO_RESET_INIT_MASK) >> MBOX_FIFO_RESET_INIT_LSB) +#define MBOX_FIFO_RESET_INIT_SET(x) (((x) << MBOX_FIFO_RESET_INIT_LSB) & MBOX_FIFO_RESET_INIT_MASK) + +#define MBOX_TXFIFO_POP_ADDRESS 0x000000f0 +#define MBOX_TXFIFO_POP_OFFSET 0x000000f0 +#define MBOX_TXFIFO_POP_DATA_MSB 0 +#define MBOX_TXFIFO_POP_DATA_LSB 0 +#define MBOX_TXFIFO_POP_DATA_MASK 0x00000001 +#define MBOX_TXFIFO_POP_DATA_GET(x) (((x)&MBOX_TXFIFO_POP_DATA_MASK) >> MBOX_TXFIFO_POP_DATA_LSB) +#define MBOX_TXFIFO_POP_DATA_SET(x) (((x) << MBOX_TXFIFO_POP_DATA_LSB) & MBOX_TXFIFO_POP_DATA_MASK) + +#define MBOX_RXFIFO_POP_ADDRESS 0x00000100 +#define MBOX_RXFIFO_POP_OFFSET 0x00000100 +#define MBOX_RXFIFO_POP_DATA_MSB 0 +#define MBOX_RXFIFO_POP_DATA_LSB 0 +#define MBOX_RXFIFO_POP_DATA_MASK 0x00000001 +#define MBOX_RXFIFO_POP_DATA_GET(x) (((x)&MBOX_RXFIFO_POP_DATA_MASK) >> MBOX_RXFIFO_POP_DATA_LSB) +#define MBOX_RXFIFO_POP_DATA_SET(x) (((x) << MBOX_RXFIFO_POP_DATA_LSB) & MBOX_RXFIFO_POP_DATA_MASK) + +#define SDIO_DEBUG_ADDRESS 0x00000110 +#define SDIO_DEBUG_OFFSET 0x00000110 +#define SDIO_DEBUG_SEL_MSB 3 +#define SDIO_DEBUG_SEL_LSB 0 +#define SDIO_DEBUG_SEL_MASK 0x0000000f +#define SDIO_DEBUG_SEL_GET(x) (((x)&SDIO_DEBUG_SEL_MASK) >> SDIO_DEBUG_SEL_LSB) +#define SDIO_DEBUG_SEL_SET(x) (((x) << SDIO_DEBUG_SEL_LSB) & SDIO_DEBUG_SEL_MASK) + +#define HOST_IF_WINDOW_ADDRESS 0x00002000 +#define HOST_IF_WINDOW_OFFSET 0x00002000 +#define HOST_IF_WINDOW_DATA_MSB 7 +#define HOST_IF_WINDOW_DATA_LSB 0 +#define HOST_IF_WINDOW_DATA_MASK 0x000000ff +#define HOST_IF_WINDOW_DATA_GET(x) (((x)&HOST_IF_WINDOW_DATA_MASK) >> HOST_IF_WINDOW_DATA_LSB) +#define HOST_IF_WINDOW_DATA_SET(x) (((x) << HOST_IF_WINDOW_DATA_LSB) & HOST_IF_WINDOW_DATA_MASK) + +#ifndef __ASSEMBLER__ + +typedef struct mbox_reg_reg_s +{ + volatile unsigned int mbox_fifo[4]; + volatile unsigned int mbox_fifo_status; + volatile unsigned int mbox_dma_policy; + volatile unsigned int mbox0_dma_rx_descriptor_base; + volatile unsigned int mbox0_dma_rx_control; + volatile unsigned int mbox0_dma_tx_descriptor_base; + volatile unsigned int mbox0_dma_tx_control; + volatile unsigned int mbox1_dma_rx_descriptor_base; + volatile unsigned int mbox1_dma_rx_control; + volatile unsigned int mbox1_dma_tx_descriptor_base; + volatile unsigned int mbox1_dma_tx_control; + volatile unsigned int mbox2_dma_rx_descriptor_base; + volatile unsigned int mbox2_dma_rx_control; + volatile unsigned int mbox2_dma_tx_descriptor_base; + volatile unsigned int mbox2_dma_tx_control; + volatile unsigned int mbox3_dma_rx_descriptor_base; + volatile unsigned int mbox3_dma_rx_control; + volatile unsigned int mbox3_dma_tx_descriptor_base; + volatile unsigned int mbox3_dma_tx_control; + volatile unsigned int mbox_int_status; + volatile unsigned int mbox_int_enable; + volatile unsigned int int_host; + unsigned char pad0[28]; /* pad to 0x80 */ + volatile unsigned int local_count[8]; + volatile unsigned int count_inc[8]; + volatile unsigned int local_scratch[8]; + volatile unsigned int use_local_bus; + volatile unsigned int sdio_config; + volatile unsigned int mbox_debug; + volatile unsigned int mbox_fifo_reset; + volatile unsigned int mbox_txfifo_pop[4]; + volatile unsigned int mbox_rxfifo_pop[4]; + volatile unsigned int sdio_debug; + unsigned char pad1[7916]; /* pad to 0x2000 */ + volatile unsigned int host_if_window[2048]; +} mbox_reg_reg_t; + +#endif /* __ASSEMBLER__ */ + +#endif /* _MBOX_REG_H_ */ diff --git a/platform/mcu/lpc54102/wifi_qca/include/AR6002/hw2.0/hw/hw20_rtc_reg.h b/platform/mcu/lpc54102/wifi_qca/include/AR6002/hw2.0/hw/hw20_rtc_reg.h new file mode 100644 index 0000000000..a1894a5800 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/include/AR6002/hw2.0/hw/hw20_rtc_reg.h @@ -0,0 +1,1216 @@ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== +#ifndef _RTC_REG_REG_H_ +#define _RTC_REG_REG_H_ + +#define RESET_CONTROL_ADDRESS 0x00000000 +#define RESET_CONTROL_OFFSET 0x00000000 +#define RESET_CONTROL_CPU_INIT_RESET_MSB 11 +#define RESET_CONTROL_CPU_INIT_RESET_LSB 11 +#define RESET_CONTROL_CPU_INIT_RESET_MASK 0x00000800 +#define RESET_CONTROL_CPU_INIT_RESET_GET(x) \ + (((x)&RESET_CONTROL_CPU_INIT_RESET_MASK) >> RESET_CONTROL_CPU_INIT_RESET_LSB) +#define RESET_CONTROL_CPU_INIT_RESET_SET(x) \ + (((x) << RESET_CONTROL_CPU_INIT_RESET_LSB) & RESET_CONTROL_CPU_INIT_RESET_MASK) +#define RESET_CONTROL_VMC_REMAP_RESET_MSB 10 +#define RESET_CONTROL_VMC_REMAP_RESET_LSB 10 +#define RESET_CONTROL_VMC_REMAP_RESET_MASK 0x00000400 +#define RESET_CONTROL_VMC_REMAP_RESET_GET(x) \ + (((x)&RESET_CONTROL_VMC_REMAP_RESET_MASK) >> RESET_CONTROL_VMC_REMAP_RESET_LSB) +#define RESET_CONTROL_VMC_REMAP_RESET_SET(x) \ + (((x) << RESET_CONTROL_VMC_REMAP_RESET_LSB) & RESET_CONTROL_VMC_REMAP_RESET_MASK) +#define RESET_CONTROL_RST_OUT_MSB 9 +#define RESET_CONTROL_RST_OUT_LSB 9 +#define RESET_CONTROL_RST_OUT_MASK 0x00000200 +#define RESET_CONTROL_RST_OUT_GET(x) (((x)&RESET_CONTROL_RST_OUT_MASK) >> RESET_CONTROL_RST_OUT_LSB) +#define RESET_CONTROL_RST_OUT_SET(x) (((x) << RESET_CONTROL_RST_OUT_LSB) & RESET_CONTROL_RST_OUT_MASK) +#define RESET_CONTROL_COLD_RST_MSB 8 +#define RESET_CONTROL_COLD_RST_LSB 8 +#define RESET_CONTROL_COLD_RST_MASK 0x00000100 +#define RESET_CONTROL_COLD_RST_GET(x) (((x)&RESET_CONTROL_COLD_RST_MASK) >> RESET_CONTROL_COLD_RST_LSB) +#define RESET_CONTROL_COLD_RST_SET(x) (((x) << RESET_CONTROL_COLD_RST_LSB) & RESET_CONTROL_COLD_RST_MASK) +#define RESET_CONTROL_WARM_RST_MSB 7 +#define RESET_CONTROL_WARM_RST_LSB 7 +#define RESET_CONTROL_WARM_RST_MASK 0x00000080 +#define RESET_CONTROL_WARM_RST_GET(x) (((x)&RESET_CONTROL_WARM_RST_MASK) >> RESET_CONTROL_WARM_RST_LSB) +#define RESET_CONTROL_WARM_RST_SET(x) (((x) << RESET_CONTROL_WARM_RST_LSB) & RESET_CONTROL_WARM_RST_MASK) +#define RESET_CONTROL_CPU_WARM_RST_MSB 6 +#define RESET_CONTROL_CPU_WARM_RST_LSB 6 +#define RESET_CONTROL_CPU_WARM_RST_MASK 0x00000040 +#define RESET_CONTROL_CPU_WARM_RST_GET(x) (((x)&RESET_CONTROL_CPU_WARM_RST_MASK) >> RESET_CONTROL_CPU_WARM_RST_LSB) +#define RESET_CONTROL_CPU_WARM_RST_SET(x) (((x) << RESET_CONTROL_CPU_WARM_RST_LSB) & RESET_CONTROL_CPU_WARM_RST_MASK) +#define RESET_CONTROL_MAC_COLD_RST_MSB 5 +#define RESET_CONTROL_MAC_COLD_RST_LSB 5 +#define RESET_CONTROL_MAC_COLD_RST_MASK 0x00000020 +#define RESET_CONTROL_MAC_COLD_RST_GET(x) (((x)&RESET_CONTROL_MAC_COLD_RST_MASK) >> RESET_CONTROL_MAC_COLD_RST_LSB) +#define RESET_CONTROL_MAC_COLD_RST_SET(x) (((x) << RESET_CONTROL_MAC_COLD_RST_LSB) & RESET_CONTROL_MAC_COLD_RST_MASK) +#define RESET_CONTROL_MAC_WARM_RST_MSB 4 +#define RESET_CONTROL_MAC_WARM_RST_LSB 4 +#define RESET_CONTROL_MAC_WARM_RST_MASK 0x00000010 +#define RESET_CONTROL_MAC_WARM_RST_GET(x) (((x)&RESET_CONTROL_MAC_WARM_RST_MASK) >> RESET_CONTROL_MAC_WARM_RST_LSB) +#define RESET_CONTROL_MAC_WARM_RST_SET(x) (((x) << RESET_CONTROL_MAC_WARM_RST_LSB) & RESET_CONTROL_MAC_WARM_RST_MASK) +#define RESET_CONTROL_MBOX_RST_MSB 2 +#define RESET_CONTROL_MBOX_RST_LSB 2 +#define RESET_CONTROL_MBOX_RST_MASK 0x00000004 +#define RESET_CONTROL_MBOX_RST_GET(x) (((x)&RESET_CONTROL_MBOX_RST_MASK) >> RESET_CONTROL_MBOX_RST_LSB) +#define RESET_CONTROL_MBOX_RST_SET(x) (((x) << RESET_CONTROL_MBOX_RST_LSB) & RESET_CONTROL_MBOX_RST_MASK) +#define RESET_CONTROL_UART_RST_MSB 1 +#define RESET_CONTROL_UART_RST_LSB 1 +#define RESET_CONTROL_UART_RST_MASK 0x00000002 +#define RESET_CONTROL_UART_RST_GET(x) (((x)&RESET_CONTROL_UART_RST_MASK) >> RESET_CONTROL_UART_RST_LSB) +#define RESET_CONTROL_UART_RST_SET(x) (((x) << RESET_CONTROL_UART_RST_LSB) & RESET_CONTROL_UART_RST_MASK) +#define RESET_CONTROL_SI0_RST_MSB 0 +#define RESET_CONTROL_SI0_RST_LSB 0 +#define RESET_CONTROL_SI0_RST_MASK 0x00000001 +#define RESET_CONTROL_SI0_RST_GET(x) (((x)&RESET_CONTROL_SI0_RST_MASK) >> RESET_CONTROL_SI0_RST_LSB) +#define RESET_CONTROL_SI0_RST_SET(x) (((x) << RESET_CONTROL_SI0_RST_LSB) & RESET_CONTROL_SI0_RST_MASK) + +#define XTAL_CONTROL_ADDRESS 0x00000004 +#define XTAL_CONTROL_OFFSET 0x00000004 +#define XTAL_CONTROL_TCXO_MSB 0 +#define XTAL_CONTROL_TCXO_LSB 0 +#define XTAL_CONTROL_TCXO_MASK 0x00000001 +#define XTAL_CONTROL_TCXO_GET(x) (((x)&XTAL_CONTROL_TCXO_MASK) >> XTAL_CONTROL_TCXO_LSB) +#define XTAL_CONTROL_TCXO_SET(x) (((x) << XTAL_CONTROL_TCXO_LSB) & XTAL_CONTROL_TCXO_MASK) + +#define TCXO_DETECT_ADDRESS 0x00000008 +#define TCXO_DETECT_OFFSET 0x00000008 +#define TCXO_DETECT_PRESENT_MSB 0 +#define TCXO_DETECT_PRESENT_LSB 0 +#define TCXO_DETECT_PRESENT_MASK 0x00000001 +#define TCXO_DETECT_PRESENT_GET(x) (((x)&TCXO_DETECT_PRESENT_MASK) >> TCXO_DETECT_PRESENT_LSB) +#define TCXO_DETECT_PRESENT_SET(x) (((x) << TCXO_DETECT_PRESENT_LSB) & TCXO_DETECT_PRESENT_MASK) + +#define XTAL_TEST_ADDRESS 0x0000000c +#define XTAL_TEST_OFFSET 0x0000000c +#define XTAL_TEST_NOTCXODET_MSB 0 +#define XTAL_TEST_NOTCXODET_LSB 0 +#define XTAL_TEST_NOTCXODET_MASK 0x00000001 +#define XTAL_TEST_NOTCXODET_GET(x) (((x)&XTAL_TEST_NOTCXODET_MASK) >> XTAL_TEST_NOTCXODET_LSB) +#define XTAL_TEST_NOTCXODET_SET(x) (((x) << XTAL_TEST_NOTCXODET_LSB) & XTAL_TEST_NOTCXODET_MASK) + +#define QUADRATURE_ADDRESS 0x00000010 +#define QUADRATURE_OFFSET 0x00000010 +#define QUADRATURE_ADC_MSB 5 +#define QUADRATURE_ADC_LSB 4 +#define QUADRATURE_ADC_MASK 0x00000030 +#define QUADRATURE_ADC_GET(x) (((x)&QUADRATURE_ADC_MASK) >> QUADRATURE_ADC_LSB) +#define QUADRATURE_ADC_SET(x) (((x) << QUADRATURE_ADC_LSB) & QUADRATURE_ADC_MASK) +#define QUADRATURE_SEL_MSB 2 +#define QUADRATURE_SEL_LSB 2 +#define QUADRATURE_SEL_MASK 0x00000004 +#define QUADRATURE_SEL_GET(x) (((x)&QUADRATURE_SEL_MASK) >> QUADRATURE_SEL_LSB) +#define QUADRATURE_SEL_SET(x) (((x) << QUADRATURE_SEL_LSB) & QUADRATURE_SEL_MASK) +#define QUADRATURE_DAC_MSB 1 +#define QUADRATURE_DAC_LSB 0 +#define QUADRATURE_DAC_MASK 0x00000003 +#define QUADRATURE_DAC_GET(x) (((x)&QUADRATURE_DAC_MASK) >> QUADRATURE_DAC_LSB) +#define QUADRATURE_DAC_SET(x) (((x) << QUADRATURE_DAC_LSB) & QUADRATURE_DAC_MASK) + +#define PLL_CONTROL_ADDRESS 0x00000014 +#define PLL_CONTROL_OFFSET 0x00000014 +#define PLL_CONTROL_DIG_TEST_CLK_MSB 20 +#define PLL_CONTROL_DIG_TEST_CLK_LSB 20 +#define PLL_CONTROL_DIG_TEST_CLK_MASK 0x00100000 +#define PLL_CONTROL_DIG_TEST_CLK_GET(x) (((x)&PLL_CONTROL_DIG_TEST_CLK_MASK) >> PLL_CONTROL_DIG_TEST_CLK_LSB) +#define PLL_CONTROL_DIG_TEST_CLK_SET(x) (((x) << PLL_CONTROL_DIG_TEST_CLK_LSB) & PLL_CONTROL_DIG_TEST_CLK_MASK) +#define PLL_CONTROL_MAC_OVERRIDE_MSB 19 +#define PLL_CONTROL_MAC_OVERRIDE_LSB 19 +#define PLL_CONTROL_MAC_OVERRIDE_MASK 0x00080000 +#define PLL_CONTROL_MAC_OVERRIDE_GET(x) (((x)&PLL_CONTROL_MAC_OVERRIDE_MASK) >> PLL_CONTROL_MAC_OVERRIDE_LSB) +#define PLL_CONTROL_MAC_OVERRIDE_SET(x) (((x) << PLL_CONTROL_MAC_OVERRIDE_LSB) & PLL_CONTROL_MAC_OVERRIDE_MASK) +#define PLL_CONTROL_NOPWD_MSB 18 +#define PLL_CONTROL_NOPWD_LSB 18 +#define PLL_CONTROL_NOPWD_MASK 0x00040000 +#define PLL_CONTROL_NOPWD_GET(x) (((x)&PLL_CONTROL_NOPWD_MASK) >> PLL_CONTROL_NOPWD_LSB) +#define PLL_CONTROL_NOPWD_SET(x) (((x) << PLL_CONTROL_NOPWD_LSB) & PLL_CONTROL_NOPWD_MASK) +#define PLL_CONTROL_UPDATING_MSB 17 +#define PLL_CONTROL_UPDATING_LSB 17 +#define PLL_CONTROL_UPDATING_MASK 0x00020000 +#define PLL_CONTROL_UPDATING_GET(x) (((x)&PLL_CONTROL_UPDATING_MASK) >> PLL_CONTROL_UPDATING_LSB) +#define PLL_CONTROL_UPDATING_SET(x) (((x) << PLL_CONTROL_UPDATING_LSB) & PLL_CONTROL_UPDATING_MASK) +#define PLL_CONTROL_BYPASS_MSB 16 +#define PLL_CONTROL_BYPASS_LSB 16 +#define PLL_CONTROL_BYPASS_MASK 0x00010000 +#define PLL_CONTROL_BYPASS_GET(x) (((x)&PLL_CONTROL_BYPASS_MASK) >> PLL_CONTROL_BYPASS_LSB) +#define PLL_CONTROL_BYPASS_SET(x) (((x) << PLL_CONTROL_BYPASS_LSB) & PLL_CONTROL_BYPASS_MASK) +#define PLL_CONTROL_REFDIV_MSB 15 +#define PLL_CONTROL_REFDIV_LSB 12 +#define PLL_CONTROL_REFDIV_MASK 0x0000f000 +#define PLL_CONTROL_REFDIV_GET(x) (((x)&PLL_CONTROL_REFDIV_MASK) >> PLL_CONTROL_REFDIV_LSB) +#define PLL_CONTROL_REFDIV_SET(x) (((x) << PLL_CONTROL_REFDIV_LSB) & PLL_CONTROL_REFDIV_MASK) +#define PLL_CONTROL_DIV_MSB 9 +#define PLL_CONTROL_DIV_LSB 0 +#define PLL_CONTROL_DIV_MASK 0x000003ff +#define PLL_CONTROL_DIV_GET(x) (((x)&PLL_CONTROL_DIV_MASK) >> PLL_CONTROL_DIV_LSB) +#define PLL_CONTROL_DIV_SET(x) (((x) << PLL_CONTROL_DIV_LSB) & PLL_CONTROL_DIV_MASK) + +#define PLL_SETTLE_ADDRESS 0x00000018 +#define PLL_SETTLE_OFFSET 0x00000018 +#define PLL_SETTLE_TIME_MSB 11 +#define PLL_SETTLE_TIME_LSB 0 +#define PLL_SETTLE_TIME_MASK 0x00000fff +#define PLL_SETTLE_TIME_GET(x) (((x)&PLL_SETTLE_TIME_MASK) >> PLL_SETTLE_TIME_LSB) +#define PLL_SETTLE_TIME_SET(x) (((x) << PLL_SETTLE_TIME_LSB) & PLL_SETTLE_TIME_MASK) + +#define XTAL_SETTLE_ADDRESS 0x0000001c +#define XTAL_SETTLE_OFFSET 0x0000001c +#define XTAL_SETTLE_TIME_MSB 7 +#define XTAL_SETTLE_TIME_LSB 0 +#define XTAL_SETTLE_TIME_MASK 0x000000ff +#define XTAL_SETTLE_TIME_GET(x) (((x)&XTAL_SETTLE_TIME_MASK) >> XTAL_SETTLE_TIME_LSB) +#define XTAL_SETTLE_TIME_SET(x) (((x) << XTAL_SETTLE_TIME_LSB) & XTAL_SETTLE_TIME_MASK) + +#define CPU_CLOCK_ADDRESS 0x00000020 +#define CPU_CLOCK_OFFSET 0x00000020 +#define CPU_CLOCK_STANDARD_MSB 1 +#define CPU_CLOCK_STANDARD_LSB 0 +#define CPU_CLOCK_STANDARD_MASK 0x00000003 +#define CPU_CLOCK_STANDARD_GET(x) (((x)&CPU_CLOCK_STANDARD_MASK) >> CPU_CLOCK_STANDARD_LSB) +#define CPU_CLOCK_STANDARD_SET(x) (((x) << CPU_CLOCK_STANDARD_LSB) & CPU_CLOCK_STANDARD_MASK) + +#define CLOCK_OUT_ADDRESS 0x00000024 +#define CLOCK_OUT_OFFSET 0x00000024 +#define CLOCK_OUT_SELECT_MSB 3 +#define CLOCK_OUT_SELECT_LSB 0 +#define CLOCK_OUT_SELECT_MASK 0x0000000f +#define CLOCK_OUT_SELECT_GET(x) (((x)&CLOCK_OUT_SELECT_MASK) >> CLOCK_OUT_SELECT_LSB) +#define CLOCK_OUT_SELECT_SET(x) (((x) << CLOCK_OUT_SELECT_LSB) & CLOCK_OUT_SELECT_MASK) + +#define CLOCK_CONTROL_ADDRESS 0x00000028 +#define CLOCK_CONTROL_OFFSET 0x00000028 +#define CLOCK_CONTROL_LF_CLK32_MSB 2 +#define CLOCK_CONTROL_LF_CLK32_LSB 2 +#define CLOCK_CONTROL_LF_CLK32_MASK 0x00000004 +#define CLOCK_CONTROL_LF_CLK32_GET(x) (((x)&CLOCK_CONTROL_LF_CLK32_MASK) >> CLOCK_CONTROL_LF_CLK32_LSB) +#define CLOCK_CONTROL_LF_CLK32_SET(x) (((x) << CLOCK_CONTROL_LF_CLK32_LSB) & CLOCK_CONTROL_LF_CLK32_MASK) +#define CLOCK_CONTROL_UART_CLK_MSB 1 +#define CLOCK_CONTROL_UART_CLK_LSB 1 +#define CLOCK_CONTROL_UART_CLK_MASK 0x00000002 +#define CLOCK_CONTROL_UART_CLK_GET(x) (((x)&CLOCK_CONTROL_UART_CLK_MASK) >> CLOCK_CONTROL_UART_CLK_LSB) +#define CLOCK_CONTROL_UART_CLK_SET(x) (((x) << CLOCK_CONTROL_UART_CLK_LSB) & CLOCK_CONTROL_UART_CLK_MASK) +#define CLOCK_CONTROL_SI0_CLK_MSB 0 +#define CLOCK_CONTROL_SI0_CLK_LSB 0 +#define CLOCK_CONTROL_SI0_CLK_MASK 0x00000001 +#define CLOCK_CONTROL_SI0_CLK_GET(x) (((x)&CLOCK_CONTROL_SI0_CLK_MASK) >> CLOCK_CONTROL_SI0_CLK_LSB) +#define CLOCK_CONTROL_SI0_CLK_SET(x) (((x) << CLOCK_CONTROL_SI0_CLK_LSB) & CLOCK_CONTROL_SI0_CLK_MASK) + +#define BIAS_OVERRIDE_ADDRESS 0x0000002c +#define BIAS_OVERRIDE_OFFSET 0x0000002c +#define BIAS_OVERRIDE_ON_MSB 0 +#define BIAS_OVERRIDE_ON_LSB 0 +#define BIAS_OVERRIDE_ON_MASK 0x00000001 +#define BIAS_OVERRIDE_ON_GET(x) (((x)&BIAS_OVERRIDE_ON_MASK) >> BIAS_OVERRIDE_ON_LSB) +#define BIAS_OVERRIDE_ON_SET(x) (((x) << BIAS_OVERRIDE_ON_LSB) & BIAS_OVERRIDE_ON_MASK) + +#define WDT_CONTROL_ADDRESS 0x00000030 +#define WDT_CONTROL_OFFSET 0x00000030 +#define WDT_CONTROL_ACTION_MSB 2 +#define WDT_CONTROL_ACTION_LSB 0 +#define WDT_CONTROL_ACTION_MASK 0x00000007 +#define WDT_CONTROL_ACTION_GET(x) (((x)&WDT_CONTROL_ACTION_MASK) >> WDT_CONTROL_ACTION_LSB) +#define WDT_CONTROL_ACTION_SET(x) (((x) << WDT_CONTROL_ACTION_LSB) & WDT_CONTROL_ACTION_MASK) + +#define WDT_STATUS_ADDRESS 0x00000034 +#define WDT_STATUS_OFFSET 0x00000034 +#define WDT_STATUS_INTERRUPT_MSB 0 +#define WDT_STATUS_INTERRUPT_LSB 0 +#define WDT_STATUS_INTERRUPT_MASK 0x00000001 +#define WDT_STATUS_INTERRUPT_GET(x) (((x)&WDT_STATUS_INTERRUPT_MASK) >> WDT_STATUS_INTERRUPT_LSB) +#define WDT_STATUS_INTERRUPT_SET(x) (((x) << WDT_STATUS_INTERRUPT_LSB) & WDT_STATUS_INTERRUPT_MASK) + +#define WDT_ADDRESS 0x00000038 +#define WDT_OFFSET 0x00000038 +#define WDT_TARGET_MSB 21 +#define WDT_TARGET_LSB 0 +#define WDT_TARGET_MASK 0x003fffff +#define WDT_TARGET_GET(x) (((x)&WDT_TARGET_MASK) >> WDT_TARGET_LSB) +#define WDT_TARGET_SET(x) (((x) << WDT_TARGET_LSB) & WDT_TARGET_MASK) + +#define WDT_COUNT_ADDRESS 0x0000003c +#define WDT_COUNT_OFFSET 0x0000003c +#define WDT_COUNT_VALUE_MSB 21 +#define WDT_COUNT_VALUE_LSB 0 +#define WDT_COUNT_VALUE_MASK 0x003fffff +#define WDT_COUNT_VALUE_GET(x) (((x)&WDT_COUNT_VALUE_MASK) >> WDT_COUNT_VALUE_LSB) +#define WDT_COUNT_VALUE_SET(x) (((x) << WDT_COUNT_VALUE_LSB) & WDT_COUNT_VALUE_MASK) + +#define WDT_RESET_ADDRESS 0x00000040 +#define WDT_RESET_OFFSET 0x00000040 +#define WDT_RESET_VALUE_MSB 0 +#define WDT_RESET_VALUE_LSB 0 +#define WDT_RESET_VALUE_MASK 0x00000001 +#define WDT_RESET_VALUE_GET(x) (((x)&WDT_RESET_VALUE_MASK) >> WDT_RESET_VALUE_LSB) +#define WDT_RESET_VALUE_SET(x) (((x) << WDT_RESET_VALUE_LSB) & WDT_RESET_VALUE_MASK) + +#define INT_STATUS_ADDRESS 0x00000044 +#define INT_STATUS_OFFSET 0x00000044 +#define INT_STATUS_RTC_POWER_MSB 14 +#define INT_STATUS_RTC_POWER_LSB 14 +#define INT_STATUS_RTC_POWER_MASK 0x00004000 +#define INT_STATUS_RTC_POWER_GET(x) (((x)&INT_STATUS_RTC_POWER_MASK) >> INT_STATUS_RTC_POWER_LSB) +#define INT_STATUS_RTC_POWER_SET(x) (((x) << INT_STATUS_RTC_POWER_LSB) & INT_STATUS_RTC_POWER_MASK) +#define INT_STATUS_MAC_MSB 13 +#define INT_STATUS_MAC_LSB 13 +#define INT_STATUS_MAC_MASK 0x00002000 +#define INT_STATUS_MAC_GET(x) (((x)&INT_STATUS_MAC_MASK) >> INT_STATUS_MAC_LSB) +#define INT_STATUS_MAC_SET(x) (((x) << INT_STATUS_MAC_LSB) & INT_STATUS_MAC_MASK) +#define INT_STATUS_MAILBOX_MSB 12 +#define INT_STATUS_MAILBOX_LSB 12 +#define INT_STATUS_MAILBOX_MASK 0x00001000 +#define INT_STATUS_MAILBOX_GET(x) (((x)&INT_STATUS_MAILBOX_MASK) >> INT_STATUS_MAILBOX_LSB) +#define INT_STATUS_MAILBOX_SET(x) (((x) << INT_STATUS_MAILBOX_LSB) & INT_STATUS_MAILBOX_MASK) +#define INT_STATUS_RTC_ALARM_MSB 11 +#define INT_STATUS_RTC_ALARM_LSB 11 +#define INT_STATUS_RTC_ALARM_MASK 0x00000800 +#define INT_STATUS_RTC_ALARM_GET(x) (((x)&INT_STATUS_RTC_ALARM_MASK) >> INT_STATUS_RTC_ALARM_LSB) +#define INT_STATUS_RTC_ALARM_SET(x) (((x) << INT_STATUS_RTC_ALARM_LSB) & INT_STATUS_RTC_ALARM_MASK) +#define INT_STATUS_HF_TIMER_MSB 10 +#define INT_STATUS_HF_TIMER_LSB 10 +#define INT_STATUS_HF_TIMER_MASK 0x00000400 +#define INT_STATUS_HF_TIMER_GET(x) (((x)&INT_STATUS_HF_TIMER_MASK) >> INT_STATUS_HF_TIMER_LSB) +#define INT_STATUS_HF_TIMER_SET(x) (((x) << INT_STATUS_HF_TIMER_LSB) & INT_STATUS_HF_TIMER_MASK) +#define INT_STATUS_LF_TIMER3_MSB 9 +#define INT_STATUS_LF_TIMER3_LSB 9 +#define INT_STATUS_LF_TIMER3_MASK 0x00000200 +#define INT_STATUS_LF_TIMER3_GET(x) (((x)&INT_STATUS_LF_TIMER3_MASK) >> INT_STATUS_LF_TIMER3_LSB) +#define INT_STATUS_LF_TIMER3_SET(x) (((x) << INT_STATUS_LF_TIMER3_LSB) & INT_STATUS_LF_TIMER3_MASK) +#define INT_STATUS_LF_TIMER2_MSB 8 +#define INT_STATUS_LF_TIMER2_LSB 8 +#define INT_STATUS_LF_TIMER2_MASK 0x00000100 +#define INT_STATUS_LF_TIMER2_GET(x) (((x)&INT_STATUS_LF_TIMER2_MASK) >> INT_STATUS_LF_TIMER2_LSB) +#define INT_STATUS_LF_TIMER2_SET(x) (((x) << INT_STATUS_LF_TIMER2_LSB) & INT_STATUS_LF_TIMER2_MASK) +#define INT_STATUS_LF_TIMER1_MSB 7 +#define INT_STATUS_LF_TIMER1_LSB 7 +#define INT_STATUS_LF_TIMER1_MASK 0x00000080 +#define INT_STATUS_LF_TIMER1_GET(x) (((x)&INT_STATUS_LF_TIMER1_MASK) >> INT_STATUS_LF_TIMER1_LSB) +#define INT_STATUS_LF_TIMER1_SET(x) (((x) << INT_STATUS_LF_TIMER1_LSB) & INT_STATUS_LF_TIMER1_MASK) +#define INT_STATUS_LF_TIMER0_MSB 6 +#define INT_STATUS_LF_TIMER0_LSB 6 +#define INT_STATUS_LF_TIMER0_MASK 0x00000040 +#define INT_STATUS_LF_TIMER0_GET(x) (((x)&INT_STATUS_LF_TIMER0_MASK) >> INT_STATUS_LF_TIMER0_LSB) +#define INT_STATUS_LF_TIMER0_SET(x) (((x) << INT_STATUS_LF_TIMER0_LSB) & INT_STATUS_LF_TIMER0_MASK) +#define INT_STATUS_KEYPAD_MSB 5 +#define INT_STATUS_KEYPAD_LSB 5 +#define INT_STATUS_KEYPAD_MASK 0x00000020 +#define INT_STATUS_KEYPAD_GET(x) (((x)&INT_STATUS_KEYPAD_MASK) >> INT_STATUS_KEYPAD_LSB) +#define INT_STATUS_KEYPAD_SET(x) (((x) << INT_STATUS_KEYPAD_LSB) & INT_STATUS_KEYPAD_MASK) +#define INT_STATUS_SI_MSB 4 +#define INT_STATUS_SI_LSB 4 +#define INT_STATUS_SI_MASK 0x00000010 +#define INT_STATUS_SI_GET(x) (((x)&INT_STATUS_SI_MASK) >> INT_STATUS_SI_LSB) +#define INT_STATUS_SI_SET(x) (((x) << INT_STATUS_SI_LSB) & INT_STATUS_SI_MASK) +#define INT_STATUS_GPIO_MSB 3 +#define INT_STATUS_GPIO_LSB 3 +#define INT_STATUS_GPIO_MASK 0x00000008 +#define INT_STATUS_GPIO_GET(x) (((x)&INT_STATUS_GPIO_MASK) >> INT_STATUS_GPIO_LSB) +#define INT_STATUS_GPIO_SET(x) (((x) << INT_STATUS_GPIO_LSB) & INT_STATUS_GPIO_MASK) +#define INT_STATUS_UART_MSB 2 +#define INT_STATUS_UART_LSB 2 +#define INT_STATUS_UART_MASK 0x00000004 +#define INT_STATUS_UART_GET(x) (((x)&INT_STATUS_UART_MASK) >> INT_STATUS_UART_LSB) +#define INT_STATUS_UART_SET(x) (((x) << INT_STATUS_UART_LSB) & INT_STATUS_UART_MASK) +#define INT_STATUS_ERROR_MSB 1 +#define INT_STATUS_ERROR_LSB 1 +#define INT_STATUS_ERROR_MASK 0x00000002 +#define INT_STATUS_ERROR_GET(x) (((x)&INT_STATUS_ERROR_MASK) >> INT_STATUS_ERROR_LSB) +#define INT_STATUS_ERROR_SET(x) (((x) << INT_STATUS_ERROR_LSB) & INT_STATUS_ERROR_MASK) +#define INT_STATUS_WDT_INT_MSB 0 +#define INT_STATUS_WDT_INT_LSB 0 +#define INT_STATUS_WDT_INT_MASK 0x00000001 +#define INT_STATUS_WDT_INT_GET(x) (((x)&INT_STATUS_WDT_INT_MASK) >> INT_STATUS_WDT_INT_LSB) +#define INT_STATUS_WDT_INT_SET(x) (((x) << INT_STATUS_WDT_INT_LSB) & INT_STATUS_WDT_INT_MASK) + +#define LF_TIMER0_ADDRESS 0x00000048 +#define LF_TIMER0_OFFSET 0x00000048 +#define LF_TIMER0_TARGET_MSB 31 +#define LF_TIMER0_TARGET_LSB 0 +#define LF_TIMER0_TARGET_MASK 0xffffffff +#define LF_TIMER0_TARGET_GET(x) (((x)&LF_TIMER0_TARGET_MASK) >> LF_TIMER0_TARGET_LSB) +#define LF_TIMER0_TARGET_SET(x) (((x) << LF_TIMER0_TARGET_LSB) & LF_TIMER0_TARGET_MASK) + +#define LF_TIMER_COUNT0_ADDRESS 0x0000004c +#define LF_TIMER_COUNT0_OFFSET 0x0000004c +#define LF_TIMER_COUNT0_VALUE_MSB 31 +#define LF_TIMER_COUNT0_VALUE_LSB 0 +#define LF_TIMER_COUNT0_VALUE_MASK 0xffffffff +#define LF_TIMER_COUNT0_VALUE_GET(x) (((x)&LF_TIMER_COUNT0_VALUE_MASK) >> LF_TIMER_COUNT0_VALUE_LSB) +#define LF_TIMER_COUNT0_VALUE_SET(x) (((x) << LF_TIMER_COUNT0_VALUE_LSB) & LF_TIMER_COUNT0_VALUE_MASK) + +#define LF_TIMER_CONTROL0_ADDRESS 0x00000050 +#define LF_TIMER_CONTROL0_OFFSET 0x00000050 +#define LF_TIMER_CONTROL0_ENABLE_MSB 2 +#define LF_TIMER_CONTROL0_ENABLE_LSB 2 +#define LF_TIMER_CONTROL0_ENABLE_MASK 0x00000004 +#define LF_TIMER_CONTROL0_ENABLE_GET(x) (((x)&LF_TIMER_CONTROL0_ENABLE_MASK) >> LF_TIMER_CONTROL0_ENABLE_LSB) +#define LF_TIMER_CONTROL0_ENABLE_SET(x) (((x) << LF_TIMER_CONTROL0_ENABLE_LSB) & LF_TIMER_CONTROL0_ENABLE_MASK) +#define LF_TIMER_CONTROL0_AUTO_RESTART_MSB 1 +#define LF_TIMER_CONTROL0_AUTO_RESTART_LSB 1 +#define LF_TIMER_CONTROL0_AUTO_RESTART_MASK 0x00000002 +#define LF_TIMER_CONTROL0_AUTO_RESTART_GET(x) \ + (((x)&LF_TIMER_CONTROL0_AUTO_RESTART_MASK) >> LF_TIMER_CONTROL0_AUTO_RESTART_LSB) +#define LF_TIMER_CONTROL0_AUTO_RESTART_SET(x) \ + (((x) << LF_TIMER_CONTROL0_AUTO_RESTART_LSB) & LF_TIMER_CONTROL0_AUTO_RESTART_MASK) +#define LF_TIMER_CONTROL0_RESET_MSB 0 +#define LF_TIMER_CONTROL0_RESET_LSB 0 +#define LF_TIMER_CONTROL0_RESET_MASK 0x00000001 +#define LF_TIMER_CONTROL0_RESET_GET(x) (((x)&LF_TIMER_CONTROL0_RESET_MASK) >> LF_TIMER_CONTROL0_RESET_LSB) +#define LF_TIMER_CONTROL0_RESET_SET(x) (((x) << LF_TIMER_CONTROL0_RESET_LSB) & LF_TIMER_CONTROL0_RESET_MASK) + +#define LF_TIMER_STATUS0_ADDRESS 0x00000054 +#define LF_TIMER_STATUS0_OFFSET 0x00000054 +#define LF_TIMER_STATUS0_INTERRUPT_MSB 0 +#define LF_TIMER_STATUS0_INTERRUPT_LSB 0 +#define LF_TIMER_STATUS0_INTERRUPT_MASK 0x00000001 +#define LF_TIMER_STATUS0_INTERRUPT_GET(x) (((x)&LF_TIMER_STATUS0_INTERRUPT_MASK) >> LF_TIMER_STATUS0_INTERRUPT_LSB) +#define LF_TIMER_STATUS0_INTERRUPT_SET(x) (((x) << LF_TIMER_STATUS0_INTERRUPT_LSB) & LF_TIMER_STATUS0_INTERRUPT_MASK) + +#define LF_TIMER1_ADDRESS 0x00000058 +#define LF_TIMER1_OFFSET 0x00000058 +#define LF_TIMER1_TARGET_MSB 31 +#define LF_TIMER1_TARGET_LSB 0 +#define LF_TIMER1_TARGET_MASK 0xffffffff +#define LF_TIMER1_TARGET_GET(x) (((x)&LF_TIMER1_TARGET_MASK) >> LF_TIMER1_TARGET_LSB) +#define LF_TIMER1_TARGET_SET(x) (((x) << LF_TIMER1_TARGET_LSB) & LF_TIMER1_TARGET_MASK) + +#define LF_TIMER_COUNT1_ADDRESS 0x0000005c +#define LF_TIMER_COUNT1_OFFSET 0x0000005c +#define LF_TIMER_COUNT1_VALUE_MSB 31 +#define LF_TIMER_COUNT1_VALUE_LSB 0 +#define LF_TIMER_COUNT1_VALUE_MASK 0xffffffff +#define LF_TIMER_COUNT1_VALUE_GET(x) (((x)&LF_TIMER_COUNT1_VALUE_MASK) >> LF_TIMER_COUNT1_VALUE_LSB) +#define LF_TIMER_COUNT1_VALUE_SET(x) (((x) << LF_TIMER_COUNT1_VALUE_LSB) & LF_TIMER_COUNT1_VALUE_MASK) + +#define LF_TIMER_CONTROL1_ADDRESS 0x00000060 +#define LF_TIMER_CONTROL1_OFFSET 0x00000060 +#define LF_TIMER_CONTROL1_ENABLE_MSB 2 +#define LF_TIMER_CONTROL1_ENABLE_LSB 2 +#define LF_TIMER_CONTROL1_ENABLE_MASK 0x00000004 +#define LF_TIMER_CONTROL1_ENABLE_GET(x) (((x)&LF_TIMER_CONTROL1_ENABLE_MASK) >> LF_TIMER_CONTROL1_ENABLE_LSB) +#define LF_TIMER_CONTROL1_ENABLE_SET(x) (((x) << LF_TIMER_CONTROL1_ENABLE_LSB) & LF_TIMER_CONTROL1_ENABLE_MASK) +#define LF_TIMER_CONTROL1_AUTO_RESTART_MSB 1 +#define LF_TIMER_CONTROL1_AUTO_RESTART_LSB 1 +#define LF_TIMER_CONTROL1_AUTO_RESTART_MASK 0x00000002 +#define LF_TIMER_CONTROL1_AUTO_RESTART_GET(x) \ + (((x)&LF_TIMER_CONTROL1_AUTO_RESTART_MASK) >> LF_TIMER_CONTROL1_AUTO_RESTART_LSB) +#define LF_TIMER_CONTROL1_AUTO_RESTART_SET(x) \ + (((x) << LF_TIMER_CONTROL1_AUTO_RESTART_LSB) & LF_TIMER_CONTROL1_AUTO_RESTART_MASK) +#define LF_TIMER_CONTROL1_RESET_MSB 0 +#define LF_TIMER_CONTROL1_RESET_LSB 0 +#define LF_TIMER_CONTROL1_RESET_MASK 0x00000001 +#define LF_TIMER_CONTROL1_RESET_GET(x) (((x)&LF_TIMER_CONTROL1_RESET_MASK) >> LF_TIMER_CONTROL1_RESET_LSB) +#define LF_TIMER_CONTROL1_RESET_SET(x) (((x) << LF_TIMER_CONTROL1_RESET_LSB) & LF_TIMER_CONTROL1_RESET_MASK) + +#define LF_TIMER_STATUS1_ADDRESS 0x00000064 +#define LF_TIMER_STATUS1_OFFSET 0x00000064 +#define LF_TIMER_STATUS1_INTERRUPT_MSB 0 +#define LF_TIMER_STATUS1_INTERRUPT_LSB 0 +#define LF_TIMER_STATUS1_INTERRUPT_MASK 0x00000001 +#define LF_TIMER_STATUS1_INTERRUPT_GET(x) (((x)&LF_TIMER_STATUS1_INTERRUPT_MASK) >> LF_TIMER_STATUS1_INTERRUPT_LSB) +#define LF_TIMER_STATUS1_INTERRUPT_SET(x) (((x) << LF_TIMER_STATUS1_INTERRUPT_LSB) & LF_TIMER_STATUS1_INTERRUPT_MASK) + +#define LF_TIMER2_ADDRESS 0x00000068 +#define LF_TIMER2_OFFSET 0x00000068 +#define LF_TIMER2_TARGET_MSB 31 +#define LF_TIMER2_TARGET_LSB 0 +#define LF_TIMER2_TARGET_MASK 0xffffffff +#define LF_TIMER2_TARGET_GET(x) (((x)&LF_TIMER2_TARGET_MASK) >> LF_TIMER2_TARGET_LSB) +#define LF_TIMER2_TARGET_SET(x) (((x) << LF_TIMER2_TARGET_LSB) & LF_TIMER2_TARGET_MASK) + +#define LF_TIMER_COUNT2_ADDRESS 0x0000006c +#define LF_TIMER_COUNT2_OFFSET 0x0000006c +#define LF_TIMER_COUNT2_VALUE_MSB 31 +#define LF_TIMER_COUNT2_VALUE_LSB 0 +#define LF_TIMER_COUNT2_VALUE_MASK 0xffffffff +#define LF_TIMER_COUNT2_VALUE_GET(x) (((x)&LF_TIMER_COUNT2_VALUE_MASK) >> LF_TIMER_COUNT2_VALUE_LSB) +#define LF_TIMER_COUNT2_VALUE_SET(x) (((x) << LF_TIMER_COUNT2_VALUE_LSB) & LF_TIMER_COUNT2_VALUE_MASK) + +#define LF_TIMER_CONTROL2_ADDRESS 0x00000070 +#define LF_TIMER_CONTROL2_OFFSET 0x00000070 +#define LF_TIMER_CONTROL2_ENABLE_MSB 2 +#define LF_TIMER_CONTROL2_ENABLE_LSB 2 +#define LF_TIMER_CONTROL2_ENABLE_MASK 0x00000004 +#define LF_TIMER_CONTROL2_ENABLE_GET(x) (((x)&LF_TIMER_CONTROL2_ENABLE_MASK) >> LF_TIMER_CONTROL2_ENABLE_LSB) +#define LF_TIMER_CONTROL2_ENABLE_SET(x) (((x) << LF_TIMER_CONTROL2_ENABLE_LSB) & LF_TIMER_CONTROL2_ENABLE_MASK) +#define LF_TIMER_CONTROL2_AUTO_RESTART_MSB 1 +#define LF_TIMER_CONTROL2_AUTO_RESTART_LSB 1 +#define LF_TIMER_CONTROL2_AUTO_RESTART_MASK 0x00000002 +#define LF_TIMER_CONTROL2_AUTO_RESTART_GET(x) \ + (((x)&LF_TIMER_CONTROL2_AUTO_RESTART_MASK) >> LF_TIMER_CONTROL2_AUTO_RESTART_LSB) +#define LF_TIMER_CONTROL2_AUTO_RESTART_SET(x) \ + (((x) << LF_TIMER_CONTROL2_AUTO_RESTART_LSB) & LF_TIMER_CONTROL2_AUTO_RESTART_MASK) +#define LF_TIMER_CONTROL2_RESET_MSB 0 +#define LF_TIMER_CONTROL2_RESET_LSB 0 +#define LF_TIMER_CONTROL2_RESET_MASK 0x00000001 +#define LF_TIMER_CONTROL2_RESET_GET(x) (((x)&LF_TIMER_CONTROL2_RESET_MASK) >> LF_TIMER_CONTROL2_RESET_LSB) +#define LF_TIMER_CONTROL2_RESET_SET(x) (((x) << LF_TIMER_CONTROL2_RESET_LSB) & LF_TIMER_CONTROL2_RESET_MASK) + +#define LF_TIMER_STATUS2_ADDRESS 0x00000074 +#define LF_TIMER_STATUS2_OFFSET 0x00000074 +#define LF_TIMER_STATUS2_INTERRUPT_MSB 0 +#define LF_TIMER_STATUS2_INTERRUPT_LSB 0 +#define LF_TIMER_STATUS2_INTERRUPT_MASK 0x00000001 +#define LF_TIMER_STATUS2_INTERRUPT_GET(x) (((x)&LF_TIMER_STATUS2_INTERRUPT_MASK) >> LF_TIMER_STATUS2_INTERRUPT_LSB) +#define LF_TIMER_STATUS2_INTERRUPT_SET(x) (((x) << LF_TIMER_STATUS2_INTERRUPT_LSB) & LF_TIMER_STATUS2_INTERRUPT_MASK) + +#define LF_TIMER3_ADDRESS 0x00000078 +#define LF_TIMER3_OFFSET 0x00000078 +#define LF_TIMER3_TARGET_MSB 31 +#define LF_TIMER3_TARGET_LSB 0 +#define LF_TIMER3_TARGET_MASK 0xffffffff +#define LF_TIMER3_TARGET_GET(x) (((x)&LF_TIMER3_TARGET_MASK) >> LF_TIMER3_TARGET_LSB) +#define LF_TIMER3_TARGET_SET(x) (((x) << LF_TIMER3_TARGET_LSB) & LF_TIMER3_TARGET_MASK) + +#define LF_TIMER_COUNT3_ADDRESS 0x0000007c +#define LF_TIMER_COUNT3_OFFSET 0x0000007c +#define LF_TIMER_COUNT3_VALUE_MSB 31 +#define LF_TIMER_COUNT3_VALUE_LSB 0 +#define LF_TIMER_COUNT3_VALUE_MASK 0xffffffff +#define LF_TIMER_COUNT3_VALUE_GET(x) (((x)&LF_TIMER_COUNT3_VALUE_MASK) >> LF_TIMER_COUNT3_VALUE_LSB) +#define LF_TIMER_COUNT3_VALUE_SET(x) (((x) << LF_TIMER_COUNT3_VALUE_LSB) & LF_TIMER_COUNT3_VALUE_MASK) + +#define LF_TIMER_CONTROL3_ADDRESS 0x00000080 +#define LF_TIMER_CONTROL3_OFFSET 0x00000080 +#define LF_TIMER_CONTROL3_ENABLE_MSB 2 +#define LF_TIMER_CONTROL3_ENABLE_LSB 2 +#define LF_TIMER_CONTROL3_ENABLE_MASK 0x00000004 +#define LF_TIMER_CONTROL3_ENABLE_GET(x) (((x)&LF_TIMER_CONTROL3_ENABLE_MASK) >> LF_TIMER_CONTROL3_ENABLE_LSB) +#define LF_TIMER_CONTROL3_ENABLE_SET(x) (((x) << LF_TIMER_CONTROL3_ENABLE_LSB) & LF_TIMER_CONTROL3_ENABLE_MASK) +#define LF_TIMER_CONTROL3_AUTO_RESTART_MSB 1 +#define LF_TIMER_CONTROL3_AUTO_RESTART_LSB 1 +#define LF_TIMER_CONTROL3_AUTO_RESTART_MASK 0x00000002 +#define LF_TIMER_CONTROL3_AUTO_RESTART_GET(x) \ + (((x)&LF_TIMER_CONTROL3_AUTO_RESTART_MASK) >> LF_TIMER_CONTROL3_AUTO_RESTART_LSB) +#define LF_TIMER_CONTROL3_AUTO_RESTART_SET(x) \ + (((x) << LF_TIMER_CONTROL3_AUTO_RESTART_LSB) & LF_TIMER_CONTROL3_AUTO_RESTART_MASK) +#define LF_TIMER_CONTROL3_RESET_MSB 0 +#define LF_TIMER_CONTROL3_RESET_LSB 0 +#define LF_TIMER_CONTROL3_RESET_MASK 0x00000001 +#define LF_TIMER_CONTROL3_RESET_GET(x) (((x)&LF_TIMER_CONTROL3_RESET_MASK) >> LF_TIMER_CONTROL3_RESET_LSB) +#define LF_TIMER_CONTROL3_RESET_SET(x) (((x) << LF_TIMER_CONTROL3_RESET_LSB) & LF_TIMER_CONTROL3_RESET_MASK) + +#define LF_TIMER_STATUS3_ADDRESS 0x00000084 +#define LF_TIMER_STATUS3_OFFSET 0x00000084 +#define LF_TIMER_STATUS3_INTERRUPT_MSB 0 +#define LF_TIMER_STATUS3_INTERRUPT_LSB 0 +#define LF_TIMER_STATUS3_INTERRUPT_MASK 0x00000001 +#define LF_TIMER_STATUS3_INTERRUPT_GET(x) (((x)&LF_TIMER_STATUS3_INTERRUPT_MASK) >> LF_TIMER_STATUS3_INTERRUPT_LSB) +#define LF_TIMER_STATUS3_INTERRUPT_SET(x) (((x) << LF_TIMER_STATUS3_INTERRUPT_LSB) & LF_TIMER_STATUS3_INTERRUPT_MASK) + +#define HF_TIMER_ADDRESS 0x00000088 +#define HF_TIMER_OFFSET 0x00000088 +#define HF_TIMER_TARGET_MSB 31 +#define HF_TIMER_TARGET_LSB 12 +#define HF_TIMER_TARGET_MASK 0xfffff000 +#define HF_TIMER_TARGET_GET(x) (((x)&HF_TIMER_TARGET_MASK) >> HF_TIMER_TARGET_LSB) +#define HF_TIMER_TARGET_SET(x) (((x) << HF_TIMER_TARGET_LSB) & HF_TIMER_TARGET_MASK) + +#define HF_TIMER_COUNT_ADDRESS 0x0000008c +#define HF_TIMER_COUNT_OFFSET 0x0000008c +#define HF_TIMER_COUNT_VALUE_MSB 31 +#define HF_TIMER_COUNT_VALUE_LSB 12 +#define HF_TIMER_COUNT_VALUE_MASK 0xfffff000 +#define HF_TIMER_COUNT_VALUE_GET(x) (((x)&HF_TIMER_COUNT_VALUE_MASK) >> HF_TIMER_COUNT_VALUE_LSB) +#define HF_TIMER_COUNT_VALUE_SET(x) (((x) << HF_TIMER_COUNT_VALUE_LSB) & HF_TIMER_COUNT_VALUE_MASK) + +#define HF_LF_COUNT_ADDRESS 0x00000090 +#define HF_LF_COUNT_OFFSET 0x00000090 +#define HF_LF_COUNT_VALUE_MSB 31 +#define HF_LF_COUNT_VALUE_LSB 0 +#define HF_LF_COUNT_VALUE_MASK 0xffffffff +#define HF_LF_COUNT_VALUE_GET(x) (((x)&HF_LF_COUNT_VALUE_MASK) >> HF_LF_COUNT_VALUE_LSB) +#define HF_LF_COUNT_VALUE_SET(x) (((x) << HF_LF_COUNT_VALUE_LSB) & HF_LF_COUNT_VALUE_MASK) + +#define HF_TIMER_CONTROL_ADDRESS 0x00000094 +#define HF_TIMER_CONTROL_OFFSET 0x00000094 +#define HF_TIMER_CONTROL_ENABLE_MSB 3 +#define HF_TIMER_CONTROL_ENABLE_LSB 3 +#define HF_TIMER_CONTROL_ENABLE_MASK 0x00000008 +#define HF_TIMER_CONTROL_ENABLE_GET(x) (((x)&HF_TIMER_CONTROL_ENABLE_MASK) >> HF_TIMER_CONTROL_ENABLE_LSB) +#define HF_TIMER_CONTROL_ENABLE_SET(x) (((x) << HF_TIMER_CONTROL_ENABLE_LSB) & HF_TIMER_CONTROL_ENABLE_MASK) +#define HF_TIMER_CONTROL_ON_MSB 2 +#define HF_TIMER_CONTROL_ON_LSB 2 +#define HF_TIMER_CONTROL_ON_MASK 0x00000004 +#define HF_TIMER_CONTROL_ON_GET(x) (((x)&HF_TIMER_CONTROL_ON_MASK) >> HF_TIMER_CONTROL_ON_LSB) +#define HF_TIMER_CONTROL_ON_SET(x) (((x) << HF_TIMER_CONTROL_ON_LSB) & HF_TIMER_CONTROL_ON_MASK) +#define HF_TIMER_CONTROL_AUTO_RESTART_MSB 1 +#define HF_TIMER_CONTROL_AUTO_RESTART_LSB 1 +#define HF_TIMER_CONTROL_AUTO_RESTART_MASK 0x00000002 +#define HF_TIMER_CONTROL_AUTO_RESTART_GET(x) \ + (((x)&HF_TIMER_CONTROL_AUTO_RESTART_MASK) >> HF_TIMER_CONTROL_AUTO_RESTART_LSB) +#define HF_TIMER_CONTROL_AUTO_RESTART_SET(x) \ + (((x) << HF_TIMER_CONTROL_AUTO_RESTART_LSB) & HF_TIMER_CONTROL_AUTO_RESTART_MASK) +#define HF_TIMER_CONTROL_RESET_MSB 0 +#define HF_TIMER_CONTROL_RESET_LSB 0 +#define HF_TIMER_CONTROL_RESET_MASK 0x00000001 +#define HF_TIMER_CONTROL_RESET_GET(x) (((x)&HF_TIMER_CONTROL_RESET_MASK) >> HF_TIMER_CONTROL_RESET_LSB) +#define HF_TIMER_CONTROL_RESET_SET(x) (((x) << HF_TIMER_CONTROL_RESET_LSB) & HF_TIMER_CONTROL_RESET_MASK) + +#define HF_TIMER_STATUS_ADDRESS 0x00000098 +#define HF_TIMER_STATUS_OFFSET 0x00000098 +#define HF_TIMER_STATUS_INTERRUPT_MSB 0 +#define HF_TIMER_STATUS_INTERRUPT_LSB 0 +#define HF_TIMER_STATUS_INTERRUPT_MASK 0x00000001 +#define HF_TIMER_STATUS_INTERRUPT_GET(x) (((x)&HF_TIMER_STATUS_INTERRUPT_MASK) >> HF_TIMER_STATUS_INTERRUPT_LSB) +#define HF_TIMER_STATUS_INTERRUPT_SET(x) (((x) << HF_TIMER_STATUS_INTERRUPT_LSB) & HF_TIMER_STATUS_INTERRUPT_MASK) + +#define RTC_CONTROL_ADDRESS 0x0000009c +#define RTC_CONTROL_OFFSET 0x0000009c +#define RTC_CONTROL_ENABLE_MSB 2 +#define RTC_CONTROL_ENABLE_LSB 2 +#define RTC_CONTROL_ENABLE_MASK 0x00000004 +#define RTC_CONTROL_ENABLE_GET(x) (((x)&RTC_CONTROL_ENABLE_MASK) >> RTC_CONTROL_ENABLE_LSB) +#define RTC_CONTROL_ENABLE_SET(x) (((x) << RTC_CONTROL_ENABLE_LSB) & RTC_CONTROL_ENABLE_MASK) +#define RTC_CONTROL_LOAD_RTC_MSB 1 +#define RTC_CONTROL_LOAD_RTC_LSB 1 +#define RTC_CONTROL_LOAD_RTC_MASK 0x00000002 +#define RTC_CONTROL_LOAD_RTC_GET(x) (((x)&RTC_CONTROL_LOAD_RTC_MASK) >> RTC_CONTROL_LOAD_RTC_LSB) +#define RTC_CONTROL_LOAD_RTC_SET(x) (((x) << RTC_CONTROL_LOAD_RTC_LSB) & RTC_CONTROL_LOAD_RTC_MASK) +#define RTC_CONTROL_LOAD_ALARM_MSB 0 +#define RTC_CONTROL_LOAD_ALARM_LSB 0 +#define RTC_CONTROL_LOAD_ALARM_MASK 0x00000001 +#define RTC_CONTROL_LOAD_ALARM_GET(x) (((x)&RTC_CONTROL_LOAD_ALARM_MASK) >> RTC_CONTROL_LOAD_ALARM_LSB) +#define RTC_CONTROL_LOAD_ALARM_SET(x) (((x) << RTC_CONTROL_LOAD_ALARM_LSB) & RTC_CONTROL_LOAD_ALARM_MASK) + +#define RTC_TIME_ADDRESS 0x000000a0 +#define RTC_TIME_OFFSET 0x000000a0 +#define RTC_TIME_WEEK_DAY_MSB 26 +#define RTC_TIME_WEEK_DAY_LSB 24 +#define RTC_TIME_WEEK_DAY_MASK 0x07000000 +#define RTC_TIME_WEEK_DAY_GET(x) (((x)&RTC_TIME_WEEK_DAY_MASK) >> RTC_TIME_WEEK_DAY_LSB) +#define RTC_TIME_WEEK_DAY_SET(x) (((x) << RTC_TIME_WEEK_DAY_LSB) & RTC_TIME_WEEK_DAY_MASK) +#define RTC_TIME_HOUR_MSB 21 +#define RTC_TIME_HOUR_LSB 16 +#define RTC_TIME_HOUR_MASK 0x003f0000 +#define RTC_TIME_HOUR_GET(x) (((x)&RTC_TIME_HOUR_MASK) >> RTC_TIME_HOUR_LSB) +#define RTC_TIME_HOUR_SET(x) (((x) << RTC_TIME_HOUR_LSB) & RTC_TIME_HOUR_MASK) +#define RTC_TIME_MINUTE_MSB 14 +#define RTC_TIME_MINUTE_LSB 8 +#define RTC_TIME_MINUTE_MASK 0x00007f00 +#define RTC_TIME_MINUTE_GET(x) (((x)&RTC_TIME_MINUTE_MASK) >> RTC_TIME_MINUTE_LSB) +#define RTC_TIME_MINUTE_SET(x) (((x) << RTC_TIME_MINUTE_LSB) & RTC_TIME_MINUTE_MASK) +#define RTC_TIME_SECOND_MSB 6 +#define RTC_TIME_SECOND_LSB 0 +#define RTC_TIME_SECOND_MASK 0x0000007f +#define RTC_TIME_SECOND_GET(x) (((x)&RTC_TIME_SECOND_MASK) >> RTC_TIME_SECOND_LSB) +#define RTC_TIME_SECOND_SET(x) (((x) << RTC_TIME_SECOND_LSB) & RTC_TIME_SECOND_MASK) + +#define RTC_DATE_ADDRESS 0x000000a4 +#define RTC_DATE_OFFSET 0x000000a4 +#define RTC_DATE_YEAR_MSB 23 +#define RTC_DATE_YEAR_LSB 16 +#define RTC_DATE_YEAR_MASK 0x00ff0000 +#define RTC_DATE_YEAR_GET(x) (((x)&RTC_DATE_YEAR_MASK) >> RTC_DATE_YEAR_LSB) +#define RTC_DATE_YEAR_SET(x) (((x) << RTC_DATE_YEAR_LSB) & RTC_DATE_YEAR_MASK) +#define RTC_DATE_MONTH_MSB 12 +#define RTC_DATE_MONTH_LSB 8 +#define RTC_DATE_MONTH_MASK 0x00001f00 +#define RTC_DATE_MONTH_GET(x) (((x)&RTC_DATE_MONTH_MASK) >> RTC_DATE_MONTH_LSB) +#define RTC_DATE_MONTH_SET(x) (((x) << RTC_DATE_MONTH_LSB) & RTC_DATE_MONTH_MASK) +#define RTC_DATE_MONTH_DAY_MSB 5 +#define RTC_DATE_MONTH_DAY_LSB 0 +#define RTC_DATE_MONTH_DAY_MASK 0x0000003f +#define RTC_DATE_MONTH_DAY_GET(x) (((x)&RTC_DATE_MONTH_DAY_MASK) >> RTC_DATE_MONTH_DAY_LSB) +#define RTC_DATE_MONTH_DAY_SET(x) (((x) << RTC_DATE_MONTH_DAY_LSB) & RTC_DATE_MONTH_DAY_MASK) + +#define RTC_SET_TIME_ADDRESS 0x000000a8 +#define RTC_SET_TIME_OFFSET 0x000000a8 +#define RTC_SET_TIME_WEEK_DAY_MSB 26 +#define RTC_SET_TIME_WEEK_DAY_LSB 24 +#define RTC_SET_TIME_WEEK_DAY_MASK 0x07000000 +#define RTC_SET_TIME_WEEK_DAY_GET(x) (((x)&RTC_SET_TIME_WEEK_DAY_MASK) >> RTC_SET_TIME_WEEK_DAY_LSB) +#define RTC_SET_TIME_WEEK_DAY_SET(x) (((x) << RTC_SET_TIME_WEEK_DAY_LSB) & RTC_SET_TIME_WEEK_DAY_MASK) +#define RTC_SET_TIME_HOUR_MSB 21 +#define RTC_SET_TIME_HOUR_LSB 16 +#define RTC_SET_TIME_HOUR_MASK 0x003f0000 +#define RTC_SET_TIME_HOUR_GET(x) (((x)&RTC_SET_TIME_HOUR_MASK) >> RTC_SET_TIME_HOUR_LSB) +#define RTC_SET_TIME_HOUR_SET(x) (((x) << RTC_SET_TIME_HOUR_LSB) & RTC_SET_TIME_HOUR_MASK) +#define RTC_SET_TIME_MINUTE_MSB 14 +#define RTC_SET_TIME_MINUTE_LSB 8 +#define RTC_SET_TIME_MINUTE_MASK 0x00007f00 +#define RTC_SET_TIME_MINUTE_GET(x) (((x)&RTC_SET_TIME_MINUTE_MASK) >> RTC_SET_TIME_MINUTE_LSB) +#define RTC_SET_TIME_MINUTE_SET(x) (((x) << RTC_SET_TIME_MINUTE_LSB) & RTC_SET_TIME_MINUTE_MASK) +#define RTC_SET_TIME_SECOND_MSB 6 +#define RTC_SET_TIME_SECOND_LSB 0 +#define RTC_SET_TIME_SECOND_MASK 0x0000007f +#define RTC_SET_TIME_SECOND_GET(x) (((x)&RTC_SET_TIME_SECOND_MASK) >> RTC_SET_TIME_SECOND_LSB) +#define RTC_SET_TIME_SECOND_SET(x) (((x) << RTC_SET_TIME_SECOND_LSB) & RTC_SET_TIME_SECOND_MASK) + +#define RTC_SET_DATE_ADDRESS 0x000000ac +#define RTC_SET_DATE_OFFSET 0x000000ac +#define RTC_SET_DATE_YEAR_MSB 23 +#define RTC_SET_DATE_YEAR_LSB 16 +#define RTC_SET_DATE_YEAR_MASK 0x00ff0000 +#define RTC_SET_DATE_YEAR_GET(x) (((x)&RTC_SET_DATE_YEAR_MASK) >> RTC_SET_DATE_YEAR_LSB) +#define RTC_SET_DATE_YEAR_SET(x) (((x) << RTC_SET_DATE_YEAR_LSB) & RTC_SET_DATE_YEAR_MASK) +#define RTC_SET_DATE_MONTH_MSB 12 +#define RTC_SET_DATE_MONTH_LSB 8 +#define RTC_SET_DATE_MONTH_MASK 0x00001f00 +#define RTC_SET_DATE_MONTH_GET(x) (((x)&RTC_SET_DATE_MONTH_MASK) >> RTC_SET_DATE_MONTH_LSB) +#define RTC_SET_DATE_MONTH_SET(x) (((x) << RTC_SET_DATE_MONTH_LSB) & RTC_SET_DATE_MONTH_MASK) +#define RTC_SET_DATE_MONTH_DAY_MSB 5 +#define RTC_SET_DATE_MONTH_DAY_LSB 0 +#define RTC_SET_DATE_MONTH_DAY_MASK 0x0000003f +#define RTC_SET_DATE_MONTH_DAY_GET(x) (((x)&RTC_SET_DATE_MONTH_DAY_MASK) >> RTC_SET_DATE_MONTH_DAY_LSB) +#define RTC_SET_DATE_MONTH_DAY_SET(x) (((x) << RTC_SET_DATE_MONTH_DAY_LSB) & RTC_SET_DATE_MONTH_DAY_MASK) + +#define RTC_SET_ALARM_ADDRESS 0x000000b0 +#define RTC_SET_ALARM_OFFSET 0x000000b0 +#define RTC_SET_ALARM_HOUR_MSB 21 +#define RTC_SET_ALARM_HOUR_LSB 16 +#define RTC_SET_ALARM_HOUR_MASK 0x003f0000 +#define RTC_SET_ALARM_HOUR_GET(x) (((x)&RTC_SET_ALARM_HOUR_MASK) >> RTC_SET_ALARM_HOUR_LSB) +#define RTC_SET_ALARM_HOUR_SET(x) (((x) << RTC_SET_ALARM_HOUR_LSB) & RTC_SET_ALARM_HOUR_MASK) +#define RTC_SET_ALARM_MINUTE_MSB 14 +#define RTC_SET_ALARM_MINUTE_LSB 8 +#define RTC_SET_ALARM_MINUTE_MASK 0x00007f00 +#define RTC_SET_ALARM_MINUTE_GET(x) (((x)&RTC_SET_ALARM_MINUTE_MASK) >> RTC_SET_ALARM_MINUTE_LSB) +#define RTC_SET_ALARM_MINUTE_SET(x) (((x) << RTC_SET_ALARM_MINUTE_LSB) & RTC_SET_ALARM_MINUTE_MASK) +#define RTC_SET_ALARM_SECOND_MSB 6 +#define RTC_SET_ALARM_SECOND_LSB 0 +#define RTC_SET_ALARM_SECOND_MASK 0x0000007f +#define RTC_SET_ALARM_SECOND_GET(x) (((x)&RTC_SET_ALARM_SECOND_MASK) >> RTC_SET_ALARM_SECOND_LSB) +#define RTC_SET_ALARM_SECOND_SET(x) (((x) << RTC_SET_ALARM_SECOND_LSB) & RTC_SET_ALARM_SECOND_MASK) + +#define RTC_CONFIG_ADDRESS 0x000000b4 +#define RTC_CONFIG_OFFSET 0x000000b4 +#define RTC_CONFIG_BCD_MSB 2 +#define RTC_CONFIG_BCD_LSB 2 +#define RTC_CONFIG_BCD_MASK 0x00000004 +#define RTC_CONFIG_BCD_GET(x) (((x)&RTC_CONFIG_BCD_MASK) >> RTC_CONFIG_BCD_LSB) +#define RTC_CONFIG_BCD_SET(x) (((x) << RTC_CONFIG_BCD_LSB) & RTC_CONFIG_BCD_MASK) +#define RTC_CONFIG_TWELVE_HOUR_MSB 1 +#define RTC_CONFIG_TWELVE_HOUR_LSB 1 +#define RTC_CONFIG_TWELVE_HOUR_MASK 0x00000002 +#define RTC_CONFIG_TWELVE_HOUR_GET(x) (((x)&RTC_CONFIG_TWELVE_HOUR_MASK) >> RTC_CONFIG_TWELVE_HOUR_LSB) +#define RTC_CONFIG_TWELVE_HOUR_SET(x) (((x) << RTC_CONFIG_TWELVE_HOUR_LSB) & RTC_CONFIG_TWELVE_HOUR_MASK) +#define RTC_CONFIG_DSE_MSB 0 +#define RTC_CONFIG_DSE_LSB 0 +#define RTC_CONFIG_DSE_MASK 0x00000001 +#define RTC_CONFIG_DSE_GET(x) (((x)&RTC_CONFIG_DSE_MASK) >> RTC_CONFIG_DSE_LSB) +#define RTC_CONFIG_DSE_SET(x) (((x) << RTC_CONFIG_DSE_LSB) & RTC_CONFIG_DSE_MASK) + +#define RTC_ALARM_STATUS_ADDRESS 0x000000b8 +#define RTC_ALARM_STATUS_OFFSET 0x000000b8 +#define RTC_ALARM_STATUS_ENABLE_MSB 1 +#define RTC_ALARM_STATUS_ENABLE_LSB 1 +#define RTC_ALARM_STATUS_ENABLE_MASK 0x00000002 +#define RTC_ALARM_STATUS_ENABLE_GET(x) (((x)&RTC_ALARM_STATUS_ENABLE_MASK) >> RTC_ALARM_STATUS_ENABLE_LSB) +#define RTC_ALARM_STATUS_ENABLE_SET(x) (((x) << RTC_ALARM_STATUS_ENABLE_LSB) & RTC_ALARM_STATUS_ENABLE_MASK) +#define RTC_ALARM_STATUS_INTERRUPT_MSB 0 +#define RTC_ALARM_STATUS_INTERRUPT_LSB 0 +#define RTC_ALARM_STATUS_INTERRUPT_MASK 0x00000001 +#define RTC_ALARM_STATUS_INTERRUPT_GET(x) (((x)&RTC_ALARM_STATUS_INTERRUPT_MASK) >> RTC_ALARM_STATUS_INTERRUPT_LSB) +#define RTC_ALARM_STATUS_INTERRUPT_SET(x) (((x) << RTC_ALARM_STATUS_INTERRUPT_LSB) & RTC_ALARM_STATUS_INTERRUPT_MASK) + +#define UART_WAKEUP_ADDRESS 0x000000bc +#define UART_WAKEUP_OFFSET 0x000000bc +#define UART_WAKEUP_ENABLE_MSB 0 +#define UART_WAKEUP_ENABLE_LSB 0 +#define UART_WAKEUP_ENABLE_MASK 0x00000001 +#define UART_WAKEUP_ENABLE_GET(x) (((x)&UART_WAKEUP_ENABLE_MASK) >> UART_WAKEUP_ENABLE_LSB) +#define UART_WAKEUP_ENABLE_SET(x) (((x) << UART_WAKEUP_ENABLE_LSB) & UART_WAKEUP_ENABLE_MASK) + +#define RESET_CAUSE_ADDRESS 0x000000c0 +#define RESET_CAUSE_OFFSET 0x000000c0 +#define RESET_CAUSE_LAST_MSB 2 +#define RESET_CAUSE_LAST_LSB 0 +#define RESET_CAUSE_LAST_MASK 0x00000007 +#define RESET_CAUSE_LAST_GET(x) (((x)&RESET_CAUSE_LAST_MASK) >> RESET_CAUSE_LAST_LSB) +#define RESET_CAUSE_LAST_SET(x) (((x) << RESET_CAUSE_LAST_LSB) & RESET_CAUSE_LAST_MASK) + +#define SYSTEM_SLEEP_ADDRESS 0x000000c4 +#define SYSTEM_SLEEP_OFFSET 0x000000c4 +#define SYSTEM_SLEEP_HOST_IF_MSB 4 +#define SYSTEM_SLEEP_HOST_IF_LSB 4 +#define SYSTEM_SLEEP_HOST_IF_MASK 0x00000010 +#define SYSTEM_SLEEP_HOST_IF_GET(x) (((x)&SYSTEM_SLEEP_HOST_IF_MASK) >> SYSTEM_SLEEP_HOST_IF_LSB) +#define SYSTEM_SLEEP_HOST_IF_SET(x) (((x) << SYSTEM_SLEEP_HOST_IF_LSB) & SYSTEM_SLEEP_HOST_IF_MASK) +#define SYSTEM_SLEEP_MBOX_MSB 3 +#define SYSTEM_SLEEP_MBOX_LSB 3 +#define SYSTEM_SLEEP_MBOX_MASK 0x00000008 +#define SYSTEM_SLEEP_MBOX_GET(x) (((x)&SYSTEM_SLEEP_MBOX_MASK) >> SYSTEM_SLEEP_MBOX_LSB) +#define SYSTEM_SLEEP_MBOX_SET(x) (((x) << SYSTEM_SLEEP_MBOX_LSB) & SYSTEM_SLEEP_MBOX_MASK) +#define SYSTEM_SLEEP_MAC_IF_MSB 2 +#define SYSTEM_SLEEP_MAC_IF_LSB 2 +#define SYSTEM_SLEEP_MAC_IF_MASK 0x00000004 +#define SYSTEM_SLEEP_MAC_IF_GET(x) (((x)&SYSTEM_SLEEP_MAC_IF_MASK) >> SYSTEM_SLEEP_MAC_IF_LSB) +#define SYSTEM_SLEEP_MAC_IF_SET(x) (((x) << SYSTEM_SLEEP_MAC_IF_LSB) & SYSTEM_SLEEP_MAC_IF_MASK) +#define SYSTEM_SLEEP_LIGHT_MSB 1 +#define SYSTEM_SLEEP_LIGHT_LSB 1 +#define SYSTEM_SLEEP_LIGHT_MASK 0x00000002 +#define SYSTEM_SLEEP_LIGHT_GET(x) (((x)&SYSTEM_SLEEP_LIGHT_MASK) >> SYSTEM_SLEEP_LIGHT_LSB) +#define SYSTEM_SLEEP_LIGHT_SET(x) (((x) << SYSTEM_SLEEP_LIGHT_LSB) & SYSTEM_SLEEP_LIGHT_MASK) +#define SYSTEM_SLEEP_DISABLE_MSB 0 +#define SYSTEM_SLEEP_DISABLE_LSB 0 +#define SYSTEM_SLEEP_DISABLE_MASK 0x00000001 +#define SYSTEM_SLEEP_DISABLE_GET(x) (((x)&SYSTEM_SLEEP_DISABLE_MASK) >> SYSTEM_SLEEP_DISABLE_LSB) +#define SYSTEM_SLEEP_DISABLE_SET(x) (((x) << SYSTEM_SLEEP_DISABLE_LSB) & SYSTEM_SLEEP_DISABLE_MASK) + +#define SDIO_WRAPPER_ADDRESS 0x000000c8 +#define SDIO_WRAPPER_OFFSET 0x000000c8 +#define SDIO_WRAPPER_SLEEP_MSB 3 +#define SDIO_WRAPPER_SLEEP_LSB 3 +#define SDIO_WRAPPER_SLEEP_MASK 0x00000008 +#define SDIO_WRAPPER_SLEEP_GET(x) (((x)&SDIO_WRAPPER_SLEEP_MASK) >> SDIO_WRAPPER_SLEEP_LSB) +#define SDIO_WRAPPER_SLEEP_SET(x) (((x) << SDIO_WRAPPER_SLEEP_LSB) & SDIO_WRAPPER_SLEEP_MASK) +#define SDIO_WRAPPER_WAKEUP_MSB 2 +#define SDIO_WRAPPER_WAKEUP_LSB 2 +#define SDIO_WRAPPER_WAKEUP_MASK 0x00000004 +#define SDIO_WRAPPER_WAKEUP_GET(x) (((x)&SDIO_WRAPPER_WAKEUP_MASK) >> SDIO_WRAPPER_WAKEUP_LSB) +#define SDIO_WRAPPER_WAKEUP_SET(x) (((x) << SDIO_WRAPPER_WAKEUP_LSB) & SDIO_WRAPPER_WAKEUP_MASK) +#define SDIO_WRAPPER_SOC_ON_MSB 1 +#define SDIO_WRAPPER_SOC_ON_LSB 1 +#define SDIO_WRAPPER_SOC_ON_MASK 0x00000002 +#define SDIO_WRAPPER_SOC_ON_GET(x) (((x)&SDIO_WRAPPER_SOC_ON_MASK) >> SDIO_WRAPPER_SOC_ON_LSB) +#define SDIO_WRAPPER_SOC_ON_SET(x) (((x) << SDIO_WRAPPER_SOC_ON_LSB) & SDIO_WRAPPER_SOC_ON_MASK) +#define SDIO_WRAPPER_ON_MSB 0 +#define SDIO_WRAPPER_ON_LSB 0 +#define SDIO_WRAPPER_ON_MASK 0x00000001 +#define SDIO_WRAPPER_ON_GET(x) (((x)&SDIO_WRAPPER_ON_MASK) >> SDIO_WRAPPER_ON_LSB) +#define SDIO_WRAPPER_ON_SET(x) (((x) << SDIO_WRAPPER_ON_LSB) & SDIO_WRAPPER_ON_MASK) + +#define MAC_SLEEP_CONTROL_ADDRESS 0x000000cc +#define MAC_SLEEP_CONTROL_OFFSET 0x000000cc +#define MAC_SLEEP_CONTROL_ENABLE_MSB 1 +#define MAC_SLEEP_CONTROL_ENABLE_LSB 0 +#define MAC_SLEEP_CONTROL_ENABLE_MASK 0x00000003 +#define MAC_SLEEP_CONTROL_ENABLE_GET(x) (((x)&MAC_SLEEP_CONTROL_ENABLE_MASK) >> MAC_SLEEP_CONTROL_ENABLE_LSB) +#define MAC_SLEEP_CONTROL_ENABLE_SET(x) (((x) << MAC_SLEEP_CONTROL_ENABLE_LSB) & MAC_SLEEP_CONTROL_ENABLE_MASK) + +#define KEEP_AWAKE_ADDRESS 0x000000d0 +#define KEEP_AWAKE_OFFSET 0x000000d0 +#define KEEP_AWAKE_COUNT_MSB 7 +#define KEEP_AWAKE_COUNT_LSB 0 +#define KEEP_AWAKE_COUNT_MASK 0x000000ff +#define KEEP_AWAKE_COUNT_GET(x) (((x)&KEEP_AWAKE_COUNT_MASK) >> KEEP_AWAKE_COUNT_LSB) +#define KEEP_AWAKE_COUNT_SET(x) (((x) << KEEP_AWAKE_COUNT_LSB) & KEEP_AWAKE_COUNT_MASK) + +#define LPO_CAL_TIME_ADDRESS 0x000000d4 +#define LPO_CAL_TIME_OFFSET 0x000000d4 +#define LPO_CAL_TIME_LENGTH_MSB 13 +#define LPO_CAL_TIME_LENGTH_LSB 0 +#define LPO_CAL_TIME_LENGTH_MASK 0x00003fff +#define LPO_CAL_TIME_LENGTH_GET(x) (((x)&LPO_CAL_TIME_LENGTH_MASK) >> LPO_CAL_TIME_LENGTH_LSB) +#define LPO_CAL_TIME_LENGTH_SET(x) (((x) << LPO_CAL_TIME_LENGTH_LSB) & LPO_CAL_TIME_LENGTH_MASK) + +#define LPO_INIT_DIVIDEND_INT_ADDRESS 0x000000d8 +#define LPO_INIT_DIVIDEND_INT_OFFSET 0x000000d8 +#define LPO_INIT_DIVIDEND_INT_VALUE_MSB 23 +#define LPO_INIT_DIVIDEND_INT_VALUE_LSB 0 +#define LPO_INIT_DIVIDEND_INT_VALUE_MASK 0x00ffffff +#define LPO_INIT_DIVIDEND_INT_VALUE_GET(x) (((x)&LPO_INIT_DIVIDEND_INT_VALUE_MASK) >> LPO_INIT_DIVIDEND_INT_VALUE_LSB) +#define LPO_INIT_DIVIDEND_INT_VALUE_SET(x) (((x) << LPO_INIT_DIVIDEND_INT_VALUE_LSB) & LPO_INIT_DIVIDEND_INT_VALUE_MASK) + +#define LPO_INIT_DIVIDEND_FRACTION_ADDRESS 0x000000dc +#define LPO_INIT_DIVIDEND_FRACTION_OFFSET 0x000000dc +#define LPO_INIT_DIVIDEND_FRACTION_VALUE_MSB 10 +#define LPO_INIT_DIVIDEND_FRACTION_VALUE_LSB 0 +#define LPO_INIT_DIVIDEND_FRACTION_VALUE_MASK 0x000007ff +#define LPO_INIT_DIVIDEND_FRACTION_VALUE_GET(x) \ + (((x)&LPO_INIT_DIVIDEND_FRACTION_VALUE_MASK) >> LPO_INIT_DIVIDEND_FRACTION_VALUE_LSB) +#define LPO_INIT_DIVIDEND_FRACTION_VALUE_SET(x) \ + (((x) << LPO_INIT_DIVIDEND_FRACTION_VALUE_LSB) & LPO_INIT_DIVIDEND_FRACTION_VALUE_MASK) + +#define LPO_CAL_ADDRESS 0x000000e0 +#define LPO_CAL_OFFSET 0x000000e0 +#define LPO_CAL_ENABLE_MSB 20 +#define LPO_CAL_ENABLE_LSB 20 +#define LPO_CAL_ENABLE_MASK 0x00100000 +#define LPO_CAL_ENABLE_GET(x) (((x)&LPO_CAL_ENABLE_MASK) >> LPO_CAL_ENABLE_LSB) +#define LPO_CAL_ENABLE_SET(x) (((x) << LPO_CAL_ENABLE_LSB) & LPO_CAL_ENABLE_MASK) +#define LPO_CAL_COUNT_MSB 19 +#define LPO_CAL_COUNT_LSB 0 +#define LPO_CAL_COUNT_MASK 0x000fffff +#define LPO_CAL_COUNT_GET(x) (((x)&LPO_CAL_COUNT_MASK) >> LPO_CAL_COUNT_LSB) +#define LPO_CAL_COUNT_SET(x) (((x) << LPO_CAL_COUNT_LSB) & LPO_CAL_COUNT_MASK) + +#define LPO_CAL_TEST_CONTROL_ADDRESS 0x000000e4 +#define LPO_CAL_TEST_CONTROL_OFFSET 0x000000e4 +#define LPO_CAL_TEST_CONTROL_ENABLE_MSB 5 +#define LPO_CAL_TEST_CONTROL_ENABLE_LSB 5 +#define LPO_CAL_TEST_CONTROL_ENABLE_MASK 0x00000020 +#define LPO_CAL_TEST_CONTROL_ENABLE_GET(x) (((x)&LPO_CAL_TEST_CONTROL_ENABLE_MASK) >> LPO_CAL_TEST_CONTROL_ENABLE_LSB) +#define LPO_CAL_TEST_CONTROL_ENABLE_SET(x) (((x) << LPO_CAL_TEST_CONTROL_ENABLE_LSB) & LPO_CAL_TEST_CONTROL_ENABLE_MASK) +#define LPO_CAL_TEST_CONTROL_RTC_CYCLES_MSB 4 +#define LPO_CAL_TEST_CONTROL_RTC_CYCLES_LSB 0 +#define LPO_CAL_TEST_CONTROL_RTC_CYCLES_MASK 0x0000001f +#define LPO_CAL_TEST_CONTROL_RTC_CYCLES_GET(x) \ + (((x)&LPO_CAL_TEST_CONTROL_RTC_CYCLES_MASK) >> LPO_CAL_TEST_CONTROL_RTC_CYCLES_LSB) +#define LPO_CAL_TEST_CONTROL_RTC_CYCLES_SET(x) \ + (((x) << LPO_CAL_TEST_CONTROL_RTC_CYCLES_LSB) & LPO_CAL_TEST_CONTROL_RTC_CYCLES_MASK) + +#define LPO_CAL_TEST_STATUS_ADDRESS 0x000000e8 +#define LPO_CAL_TEST_STATUS_OFFSET 0x000000e8 +#define LPO_CAL_TEST_STATUS_READY_MSB 16 +#define LPO_CAL_TEST_STATUS_READY_LSB 16 +#define LPO_CAL_TEST_STATUS_READY_MASK 0x00010000 +#define LPO_CAL_TEST_STATUS_READY_GET(x) (((x)&LPO_CAL_TEST_STATUS_READY_MASK) >> LPO_CAL_TEST_STATUS_READY_LSB) +#define LPO_CAL_TEST_STATUS_READY_SET(x) (((x) << LPO_CAL_TEST_STATUS_READY_LSB) & LPO_CAL_TEST_STATUS_READY_MASK) +#define LPO_CAL_TEST_STATUS_COUNT_MSB 15 +#define LPO_CAL_TEST_STATUS_COUNT_LSB 0 +#define LPO_CAL_TEST_STATUS_COUNT_MASK 0x0000ffff +#define LPO_CAL_TEST_STATUS_COUNT_GET(x) (((x)&LPO_CAL_TEST_STATUS_COUNT_MASK) >> LPO_CAL_TEST_STATUS_COUNT_LSB) +#define LPO_CAL_TEST_STATUS_COUNT_SET(x) (((x) << LPO_CAL_TEST_STATUS_COUNT_LSB) & LPO_CAL_TEST_STATUS_COUNT_MASK) + +#define CHIP_ID_ADDRESS 0x000000ec +#define CHIP_ID_OFFSET 0x000000ec +#define CHIP_ID_DEVICE_ID_MSB 31 +#define CHIP_ID_DEVICE_ID_LSB 16 +#define CHIP_ID_DEVICE_ID_MASK 0xffff0000 +#define CHIP_ID_DEVICE_ID_GET(x) (((x)&CHIP_ID_DEVICE_ID_MASK) >> CHIP_ID_DEVICE_ID_LSB) +#define CHIP_ID_DEVICE_ID_SET(x) (((x) << CHIP_ID_DEVICE_ID_LSB) & CHIP_ID_DEVICE_ID_MASK) +#define CHIP_ID_CONFIG_ID_MSB 15 +#define CHIP_ID_CONFIG_ID_LSB 4 +#define CHIP_ID_CONFIG_ID_MASK 0x0000fff0 +#define CHIP_ID_CONFIG_ID_GET(x) (((x)&CHIP_ID_CONFIG_ID_MASK) >> CHIP_ID_CONFIG_ID_LSB) +#define CHIP_ID_CONFIG_ID_SET(x) (((x) << CHIP_ID_CONFIG_ID_LSB) & CHIP_ID_CONFIG_ID_MASK) +#define CHIP_ID_VERSION_ID_MSB 3 +#define CHIP_ID_VERSION_ID_LSB 0 +#define CHIP_ID_VERSION_ID_MASK 0x0000000f +#define CHIP_ID_VERSION_ID_GET(x) (((x)&CHIP_ID_VERSION_ID_MASK) >> CHIP_ID_VERSION_ID_LSB) +#define CHIP_ID_VERSION_ID_SET(x) (((x) << CHIP_ID_VERSION_ID_LSB) & CHIP_ID_VERSION_ID_MASK) + +#define DERIVED_RTC_CLK_ADDRESS 0x000000f0 +#define DERIVED_RTC_CLK_OFFSET 0x000000f0 +#define DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_MSB 20 +#define DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_LSB 20 +#define DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_MASK 0x00100000 +#define DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_GET(x) \ + (((x)&DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_MASK) >> DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_LSB) +#define DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_SET(x) \ + (((x) << DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_LSB) & DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_MASK) +#define DERIVED_RTC_CLK_EXTERNAL_DETECT_MSB 18 +#define DERIVED_RTC_CLK_EXTERNAL_DETECT_LSB 18 +#define DERIVED_RTC_CLK_EXTERNAL_DETECT_MASK 0x00040000 +#define DERIVED_RTC_CLK_EXTERNAL_DETECT_GET(x) \ + (((x)&DERIVED_RTC_CLK_EXTERNAL_DETECT_MASK) >> DERIVED_RTC_CLK_EXTERNAL_DETECT_LSB) +#define DERIVED_RTC_CLK_EXTERNAL_DETECT_SET(x) \ + (((x) << DERIVED_RTC_CLK_EXTERNAL_DETECT_LSB) & DERIVED_RTC_CLK_EXTERNAL_DETECT_MASK) +#define DERIVED_RTC_CLK_FORCE_MSB 17 +#define DERIVED_RTC_CLK_FORCE_LSB 16 +#define DERIVED_RTC_CLK_FORCE_MASK 0x00030000 +#define DERIVED_RTC_CLK_FORCE_GET(x) (((x)&DERIVED_RTC_CLK_FORCE_MASK) >> DERIVED_RTC_CLK_FORCE_LSB) +#define DERIVED_RTC_CLK_FORCE_SET(x) (((x) << DERIVED_RTC_CLK_FORCE_LSB) & DERIVED_RTC_CLK_FORCE_MASK) +#define DERIVED_RTC_CLK_PERIOD_MSB 15 +#define DERIVED_RTC_CLK_PERIOD_LSB 1 +#define DERIVED_RTC_CLK_PERIOD_MASK 0x0000fffe +#define DERIVED_RTC_CLK_PERIOD_GET(x) (((x)&DERIVED_RTC_CLK_PERIOD_MASK) >> DERIVED_RTC_CLK_PERIOD_LSB) +#define DERIVED_RTC_CLK_PERIOD_SET(x) (((x) << DERIVED_RTC_CLK_PERIOD_LSB) & DERIVED_RTC_CLK_PERIOD_MASK) + +#define MAC_PCU_SLP32_MODE_ADDRESS 0x000000f4 +#define MAC_PCU_SLP32_MODE_OFFSET 0x000000f4 +#define MAC_PCU_SLP32_MODE_TSF_WRITE_PENDING_MSB 21 +#define MAC_PCU_SLP32_MODE_TSF_WRITE_PENDING_LSB 21 +#define MAC_PCU_SLP32_MODE_TSF_WRITE_PENDING_MASK 0x00200000 +#define MAC_PCU_SLP32_MODE_TSF_WRITE_PENDING_GET(x) \ + (((x)&MAC_PCU_SLP32_MODE_TSF_WRITE_PENDING_MASK) >> MAC_PCU_SLP32_MODE_TSF_WRITE_PENDING_LSB) +#define MAC_PCU_SLP32_MODE_TSF_WRITE_PENDING_SET(x) \ + (((x) << MAC_PCU_SLP32_MODE_TSF_WRITE_PENDING_LSB) & MAC_PCU_SLP32_MODE_TSF_WRITE_PENDING_MASK) +#define MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_MSB 19 +#define MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_LSB 0 +#define MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_MASK 0x000fffff +#define MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_GET(x) \ + (((x)&MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_MASK) >> MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_LSB) +#define MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_SET(x) \ + (((x) << MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_LSB) & MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_MASK) + +#define MAC_PCU_SLP32_WAKE_ADDRESS 0x000000f8 +#define MAC_PCU_SLP32_WAKE_OFFSET 0x000000f8 +#define MAC_PCU_SLP32_WAKE_XTL_TIME_MSB 15 +#define MAC_PCU_SLP32_WAKE_XTL_TIME_LSB 0 +#define MAC_PCU_SLP32_WAKE_XTL_TIME_MASK 0x0000ffff +#define MAC_PCU_SLP32_WAKE_XTL_TIME_GET(x) (((x)&MAC_PCU_SLP32_WAKE_XTL_TIME_MASK) >> MAC_PCU_SLP32_WAKE_XTL_TIME_LSB) +#define MAC_PCU_SLP32_WAKE_XTL_TIME_SET(x) (((x) << MAC_PCU_SLP32_WAKE_XTL_TIME_LSB) & MAC_PCU_SLP32_WAKE_XTL_TIME_MASK) + +#define MAC_PCU_SLP32_INC_ADDRESS 0x000000fc +#define MAC_PCU_SLP32_INC_OFFSET 0x000000fc +#define MAC_PCU_SLP32_INC_TSF_INC_MSB 19 +#define MAC_PCU_SLP32_INC_TSF_INC_LSB 0 +#define MAC_PCU_SLP32_INC_TSF_INC_MASK 0x000fffff +#define MAC_PCU_SLP32_INC_TSF_INC_GET(x) (((x)&MAC_PCU_SLP32_INC_TSF_INC_MASK) >> MAC_PCU_SLP32_INC_TSF_INC_LSB) +#define MAC_PCU_SLP32_INC_TSF_INC_SET(x) (((x) << MAC_PCU_SLP32_INC_TSF_INC_LSB) & MAC_PCU_SLP32_INC_TSF_INC_MASK) + +#define MAC_PCU_SLP_MIB1_ADDRESS 0x00000100 +#define MAC_PCU_SLP_MIB1_OFFSET 0x00000100 +#define MAC_PCU_SLP_MIB1_SLEEP_CNT_MSB 31 +#define MAC_PCU_SLP_MIB1_SLEEP_CNT_LSB 0 +#define MAC_PCU_SLP_MIB1_SLEEP_CNT_MASK 0xffffffff +#define MAC_PCU_SLP_MIB1_SLEEP_CNT_GET(x) (((x)&MAC_PCU_SLP_MIB1_SLEEP_CNT_MASK) >> MAC_PCU_SLP_MIB1_SLEEP_CNT_LSB) +#define MAC_PCU_SLP_MIB1_SLEEP_CNT_SET(x) (((x) << MAC_PCU_SLP_MIB1_SLEEP_CNT_LSB) & MAC_PCU_SLP_MIB1_SLEEP_CNT_MASK) + +#define MAC_PCU_SLP_MIB2_ADDRESS 0x00000104 +#define MAC_PCU_SLP_MIB2_OFFSET 0x00000104 +#define MAC_PCU_SLP_MIB2_CYCLE_CNT_MSB 31 +#define MAC_PCU_SLP_MIB2_CYCLE_CNT_LSB 0 +#define MAC_PCU_SLP_MIB2_CYCLE_CNT_MASK 0xffffffff +#define MAC_PCU_SLP_MIB2_CYCLE_CNT_GET(x) (((x)&MAC_PCU_SLP_MIB2_CYCLE_CNT_MASK) >> MAC_PCU_SLP_MIB2_CYCLE_CNT_LSB) +#define MAC_PCU_SLP_MIB2_CYCLE_CNT_SET(x) (((x) << MAC_PCU_SLP_MIB2_CYCLE_CNT_LSB) & MAC_PCU_SLP_MIB2_CYCLE_CNT_MASK) + +#define MAC_PCU_SLP_MIB3_ADDRESS 0x00000108 +#define MAC_PCU_SLP_MIB3_OFFSET 0x00000108 +#define MAC_PCU_SLP_MIB3_PENDING_MSB 1 +#define MAC_PCU_SLP_MIB3_PENDING_LSB 1 +#define MAC_PCU_SLP_MIB3_PENDING_MASK 0x00000002 +#define MAC_PCU_SLP_MIB3_PENDING_GET(x) (((x)&MAC_PCU_SLP_MIB3_PENDING_MASK) >> MAC_PCU_SLP_MIB3_PENDING_LSB) +#define MAC_PCU_SLP_MIB3_PENDING_SET(x) (((x) << MAC_PCU_SLP_MIB3_PENDING_LSB) & MAC_PCU_SLP_MIB3_PENDING_MASK) +#define MAC_PCU_SLP_MIB3_CLR_CNT_MSB 0 +#define MAC_PCU_SLP_MIB3_CLR_CNT_LSB 0 +#define MAC_PCU_SLP_MIB3_CLR_CNT_MASK 0x00000001 +#define MAC_PCU_SLP_MIB3_CLR_CNT_GET(x) (((x)&MAC_PCU_SLP_MIB3_CLR_CNT_MASK) >> MAC_PCU_SLP_MIB3_CLR_CNT_LSB) +#define MAC_PCU_SLP_MIB3_CLR_CNT_SET(x) (((x) << MAC_PCU_SLP_MIB3_CLR_CNT_LSB) & MAC_PCU_SLP_MIB3_CLR_CNT_MASK) + +#define MAC_PCU_SLP_BEACON_ADDRESS 0x0000010c +#define MAC_PCU_SLP_BEACON_OFFSET 0x0000010c +#define MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_ENABLE_MSB 24 +#define MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_ENABLE_LSB 24 +#define MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_ENABLE_MASK 0x01000000 +#define MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_ENABLE_GET(x) \ + (((x)&MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_ENABLE_MASK) >> MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_ENABLE_LSB) +#define MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_ENABLE_SET(x) \ + (((x) << MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_ENABLE_LSB) & MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_ENABLE_MASK) +#define MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_MSB 23 +#define MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_LSB 0 +#define MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_MASK 0x00ffffff +#define MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_GET(x) \ + (((x)&MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_MASK) >> MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_LSB) +#define MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_SET(x) \ + (((x) << MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_LSB) & MAC_PCU_SLP_BEACON_BMISS_TIMEOUT_MASK) + +#define POWER_REG_ADDRESS 0x00000110 +#define POWER_REG_OFFSET 0x00000110 +#define POWER_REG_VLVL_MSB 11 +#define POWER_REG_VLVL_LSB 8 +#define POWER_REG_VLVL_MASK 0x00000f00 +#define POWER_REG_VLVL_GET(x) (((x)&POWER_REG_VLVL_MASK) >> POWER_REG_VLVL_LSB) +#define POWER_REG_VLVL_SET(x) (((x) << POWER_REG_VLVL_LSB) & POWER_REG_VLVL_MASK) +#define POWER_REG_CPU_INT_ENABLE_MSB 7 +#define POWER_REG_CPU_INT_ENABLE_LSB 7 +#define POWER_REG_CPU_INT_ENABLE_MASK 0x00000080 +#define POWER_REG_CPU_INT_ENABLE_GET(x) (((x)&POWER_REG_CPU_INT_ENABLE_MASK) >> POWER_REG_CPU_INT_ENABLE_LSB) +#define POWER_REG_CPU_INT_ENABLE_SET(x) (((x) << POWER_REG_CPU_INT_ENABLE_LSB) & POWER_REG_CPU_INT_ENABLE_MASK) +#define POWER_REG_WLAN_ISO_DIS_MSB 6 +#define POWER_REG_WLAN_ISO_DIS_LSB 6 +#define POWER_REG_WLAN_ISO_DIS_MASK 0x00000040 +#define POWER_REG_WLAN_ISO_DIS_GET(x) (((x)&POWER_REG_WLAN_ISO_DIS_MASK) >> POWER_REG_WLAN_ISO_DIS_LSB) +#define POWER_REG_WLAN_ISO_DIS_SET(x) (((x) << POWER_REG_WLAN_ISO_DIS_LSB) & POWER_REG_WLAN_ISO_DIS_MASK) +#define POWER_REG_WLAN_ISO_CNTL_MSB 5 +#define POWER_REG_WLAN_ISO_CNTL_LSB 5 +#define POWER_REG_WLAN_ISO_CNTL_MASK 0x00000020 +#define POWER_REG_WLAN_ISO_CNTL_GET(x) (((x)&POWER_REG_WLAN_ISO_CNTL_MASK) >> POWER_REG_WLAN_ISO_CNTL_LSB) +#define POWER_REG_WLAN_ISO_CNTL_SET(x) (((x) << POWER_REG_WLAN_ISO_CNTL_LSB) & POWER_REG_WLAN_ISO_CNTL_MASK) +#define POWER_REG_RADIO_PWD_EN_MSB 4 +#define POWER_REG_RADIO_PWD_EN_LSB 4 +#define POWER_REG_RADIO_PWD_EN_MASK 0x00000010 +#define POWER_REG_RADIO_PWD_EN_GET(x) (((x)&POWER_REG_RADIO_PWD_EN_MASK) >> POWER_REG_RADIO_PWD_EN_LSB) +#define POWER_REG_RADIO_PWD_EN_SET(x) (((x) << POWER_REG_RADIO_PWD_EN_LSB) & POWER_REG_RADIO_PWD_EN_MASK) +#define POWER_REG_SOC_SCALE_EN_MSB 3 +#define POWER_REG_SOC_SCALE_EN_LSB 3 +#define POWER_REG_SOC_SCALE_EN_MASK 0x00000008 +#define POWER_REG_SOC_SCALE_EN_GET(x) (((x)&POWER_REG_SOC_SCALE_EN_MASK) >> POWER_REG_SOC_SCALE_EN_LSB) +#define POWER_REG_SOC_SCALE_EN_SET(x) (((x) << POWER_REG_SOC_SCALE_EN_LSB) & POWER_REG_SOC_SCALE_EN_MASK) +#define POWER_REG_WLAN_SCALE_EN_MSB 2 +#define POWER_REG_WLAN_SCALE_EN_LSB 2 +#define POWER_REG_WLAN_SCALE_EN_MASK 0x00000004 +#define POWER_REG_WLAN_SCALE_EN_GET(x) (((x)&POWER_REG_WLAN_SCALE_EN_MASK) >> POWER_REG_WLAN_SCALE_EN_LSB) +#define POWER_REG_WLAN_SCALE_EN_SET(x) (((x) << POWER_REG_WLAN_SCALE_EN_LSB) & POWER_REG_WLAN_SCALE_EN_MASK) +#define POWER_REG_WLAN_PWD_EN_MSB 1 +#define POWER_REG_WLAN_PWD_EN_LSB 1 +#define POWER_REG_WLAN_PWD_EN_MASK 0x00000002 +#define POWER_REG_WLAN_PWD_EN_GET(x) (((x)&POWER_REG_WLAN_PWD_EN_MASK) >> POWER_REG_WLAN_PWD_EN_LSB) +#define POWER_REG_WLAN_PWD_EN_SET(x) (((x) << POWER_REG_WLAN_PWD_EN_LSB) & POWER_REG_WLAN_PWD_EN_MASK) +#define POWER_REG_POWER_EN_MSB 0 +#define POWER_REG_POWER_EN_LSB 0 +#define POWER_REG_POWER_EN_MASK 0x00000001 +#define POWER_REG_POWER_EN_GET(x) (((x)&POWER_REG_POWER_EN_MASK) >> POWER_REG_POWER_EN_LSB) +#define POWER_REG_POWER_EN_SET(x) (((x) << POWER_REG_POWER_EN_LSB) & POWER_REG_POWER_EN_MASK) + +#define CORE_CLK_CTRL_ADDRESS 0x00000114 +#define CORE_CLK_CTRL_OFFSET 0x00000114 +#define CORE_CLK_CTRL_DIV_MSB 2 +#define CORE_CLK_CTRL_DIV_LSB 0 +#define CORE_CLK_CTRL_DIV_MASK 0x00000007 +#define CORE_CLK_CTRL_DIV_GET(x) (((x)&CORE_CLK_CTRL_DIV_MASK) >> CORE_CLK_CTRL_DIV_LSB) +#define CORE_CLK_CTRL_DIV_SET(x) (((x) << CORE_CLK_CTRL_DIV_LSB) & CORE_CLK_CTRL_DIV_MASK) + +#define SDIO_SETUP_CIRCUIT_ADDRESS 0x00000120 +#define SDIO_SETUP_CIRCUIT_OFFSET 0x00000120 +#define SDIO_SETUP_CIRCUIT_VECTOR_MSB 7 +#define SDIO_SETUP_CIRCUIT_VECTOR_LSB 0 +#define SDIO_SETUP_CIRCUIT_VECTOR_MASK 0x000000ff +#define SDIO_SETUP_CIRCUIT_VECTOR_GET(x) (((x)&SDIO_SETUP_CIRCUIT_VECTOR_MASK) >> SDIO_SETUP_CIRCUIT_VECTOR_LSB) +#define SDIO_SETUP_CIRCUIT_VECTOR_SET(x) (((x) << SDIO_SETUP_CIRCUIT_VECTOR_LSB) & SDIO_SETUP_CIRCUIT_VECTOR_MASK) + +#define SDIO_SETUP_CONFIG_ADDRESS 0x00000140 +#define SDIO_SETUP_CONFIG_OFFSET 0x00000140 +#define SDIO_SETUP_CONFIG_ENABLE_MSB 1 +#define SDIO_SETUP_CONFIG_ENABLE_LSB 1 +#define SDIO_SETUP_CONFIG_ENABLE_MASK 0x00000002 +#define SDIO_SETUP_CONFIG_ENABLE_GET(x) (((x)&SDIO_SETUP_CONFIG_ENABLE_MASK) >> SDIO_SETUP_CONFIG_ENABLE_LSB) +#define SDIO_SETUP_CONFIG_ENABLE_SET(x) (((x) << SDIO_SETUP_CONFIG_ENABLE_LSB) & SDIO_SETUP_CONFIG_ENABLE_MASK) +#define SDIO_SETUP_CONFIG_CLEAR_MSB 0 +#define SDIO_SETUP_CONFIG_CLEAR_LSB 0 +#define SDIO_SETUP_CONFIG_CLEAR_MASK 0x00000001 +#define SDIO_SETUP_CONFIG_CLEAR_GET(x) (((x)&SDIO_SETUP_CONFIG_CLEAR_MASK) >> SDIO_SETUP_CONFIG_CLEAR_LSB) +#define SDIO_SETUP_CONFIG_CLEAR_SET(x) (((x) << SDIO_SETUP_CONFIG_CLEAR_LSB) & SDIO_SETUP_CONFIG_CLEAR_MASK) + +#define CPU_SETUP_CONFIG_ADDRESS 0x00000144 +#define CPU_SETUP_CONFIG_OFFSET 0x00000144 +#define CPU_SETUP_CONFIG_ENABLE_MSB 1 +#define CPU_SETUP_CONFIG_ENABLE_LSB 1 +#define CPU_SETUP_CONFIG_ENABLE_MASK 0x00000002 +#define CPU_SETUP_CONFIG_ENABLE_GET(x) (((x)&CPU_SETUP_CONFIG_ENABLE_MASK) >> CPU_SETUP_CONFIG_ENABLE_LSB) +#define CPU_SETUP_CONFIG_ENABLE_SET(x) (((x) << CPU_SETUP_CONFIG_ENABLE_LSB) & CPU_SETUP_CONFIG_ENABLE_MASK) +#define CPU_SETUP_CONFIG_CLEAR_MSB 0 +#define CPU_SETUP_CONFIG_CLEAR_LSB 0 +#define CPU_SETUP_CONFIG_CLEAR_MASK 0x00000001 +#define CPU_SETUP_CONFIG_CLEAR_GET(x) (((x)&CPU_SETUP_CONFIG_CLEAR_MASK) >> CPU_SETUP_CONFIG_CLEAR_LSB) +#define CPU_SETUP_CONFIG_CLEAR_SET(x) (((x) << CPU_SETUP_CONFIG_CLEAR_LSB) & CPU_SETUP_CONFIG_CLEAR_MASK) + +#define CPU_SETUP_CIRCUIT_ADDRESS 0x00000160 +#define CPU_SETUP_CIRCUIT_OFFSET 0x00000160 +#define CPU_SETUP_CIRCUIT_VECTOR_MSB 7 +#define CPU_SETUP_CIRCUIT_VECTOR_LSB 0 +#define CPU_SETUP_CIRCUIT_VECTOR_MASK 0x000000ff +#define CPU_SETUP_CIRCUIT_VECTOR_GET(x) (((x)&CPU_SETUP_CIRCUIT_VECTOR_MASK) >> CPU_SETUP_CIRCUIT_VECTOR_LSB) +#define CPU_SETUP_CIRCUIT_VECTOR_SET(x) (((x) << CPU_SETUP_CIRCUIT_VECTOR_LSB) & CPU_SETUP_CIRCUIT_VECTOR_MASK) + +#define BB_SETUP_CONFIG_ADDRESS 0x00000180 +#define BB_SETUP_CONFIG_OFFSET 0x00000180 +#define BB_SETUP_CONFIG_ENABLE_MSB 1 +#define BB_SETUP_CONFIG_ENABLE_LSB 1 +#define BB_SETUP_CONFIG_ENABLE_MASK 0x00000002 +#define BB_SETUP_CONFIG_ENABLE_GET(x) (((x)&BB_SETUP_CONFIG_ENABLE_MASK) >> BB_SETUP_CONFIG_ENABLE_LSB) +#define BB_SETUP_CONFIG_ENABLE_SET(x) (((x) << BB_SETUP_CONFIG_ENABLE_LSB) & BB_SETUP_CONFIG_ENABLE_MASK) +#define BB_SETUP_CONFIG_CLEAR_MSB 0 +#define BB_SETUP_CONFIG_CLEAR_LSB 0 +#define BB_SETUP_CONFIG_CLEAR_MASK 0x00000001 +#define BB_SETUP_CONFIG_CLEAR_GET(x) (((x)&BB_SETUP_CONFIG_CLEAR_MASK) >> BB_SETUP_CONFIG_CLEAR_LSB) +#define BB_SETUP_CONFIG_CLEAR_SET(x) (((x) << BB_SETUP_CONFIG_CLEAR_LSB) & BB_SETUP_CONFIG_CLEAR_MASK) + +#define BB_SETUP_CIRCUIT_ADDRESS 0x000001a0 +#define BB_SETUP_CIRCUIT_OFFSET 0x000001a0 +#define BB_SETUP_CIRCUIT_VECTOR_MSB 7 +#define BB_SETUP_CIRCUIT_VECTOR_LSB 0 +#define BB_SETUP_CIRCUIT_VECTOR_MASK 0x000000ff +#define BB_SETUP_CIRCUIT_VECTOR_GET(x) (((x)&BB_SETUP_CIRCUIT_VECTOR_MASK) >> BB_SETUP_CIRCUIT_VECTOR_LSB) +#define BB_SETUP_CIRCUIT_VECTOR_SET(x) (((x) << BB_SETUP_CIRCUIT_VECTOR_LSB) & BB_SETUP_CIRCUIT_VECTOR_MASK) + +#define GPIO_WAKEUP_CONTROL_ADDRESS 0x000001c0 +#define GPIO_WAKEUP_CONTROL_OFFSET 0x000001c0 +#define GPIO_WAKEUP_CONTROL_ENABLE_MSB 0 +#define GPIO_WAKEUP_CONTROL_ENABLE_LSB 0 +#define GPIO_WAKEUP_CONTROL_ENABLE_MASK 0x00000001 +#define GPIO_WAKEUP_CONTROL_ENABLE_GET(x) (((x)&GPIO_WAKEUP_CONTROL_ENABLE_MASK) >> GPIO_WAKEUP_CONTROL_ENABLE_LSB) +#define GPIO_WAKEUP_CONTROL_ENABLE_SET(x) (((x) << GPIO_WAKEUP_CONTROL_ENABLE_LSB) & GPIO_WAKEUP_CONTROL_ENABLE_MASK) + +#ifndef __ASSEMBLER__ + +typedef struct rtc_reg_reg_s +{ + volatile unsigned int reset_control; + volatile unsigned int xtal_control; + volatile unsigned int tcxo_detect; + volatile unsigned int xtal_test; + volatile unsigned int quadrature; + volatile unsigned int pll_control; + volatile unsigned int pll_settle; + volatile unsigned int xtal_settle; + volatile unsigned int cpu_clock; + volatile unsigned int clock_out; + volatile unsigned int clock_control; + volatile unsigned int bias_override; + volatile unsigned int wdt_control; + volatile unsigned int wdt_status; + volatile unsigned int wdt; + volatile unsigned int wdt_count; + volatile unsigned int wdt_reset; + volatile unsigned int int_status; + volatile unsigned int lf_timer0; + volatile unsigned int lf_timer_count0; + volatile unsigned int lf_timer_control0; + volatile unsigned int lf_timer_status0; + volatile unsigned int lf_timer1; + volatile unsigned int lf_timer_count1; + volatile unsigned int lf_timer_control1; + volatile unsigned int lf_timer_status1; + volatile unsigned int lf_timer2; + volatile unsigned int lf_timer_count2; + volatile unsigned int lf_timer_control2; + volatile unsigned int lf_timer_status2; + volatile unsigned int lf_timer3; + volatile unsigned int lf_timer_count3; + volatile unsigned int lf_timer_control3; + volatile unsigned int lf_timer_status3; + volatile unsigned int hf_timer; + volatile unsigned int hf_timer_count; + volatile unsigned int hf_lf_count; + volatile unsigned int hf_timer_control; + volatile unsigned int hf_timer_status; + volatile unsigned int rtc_control; + volatile unsigned int rtc_time; + volatile unsigned int rtc_date; + volatile unsigned int rtc_set_time; + volatile unsigned int rtc_set_date; + volatile unsigned int rtc_set_alarm; + volatile unsigned int rtc_config; + volatile unsigned int rtc_alarm_status; + volatile unsigned int uart_wakeup; + volatile unsigned int reset_cause; + volatile unsigned int system_sleep; + volatile unsigned int sdio_wrapper; + volatile unsigned int mac_sleep_control; + volatile unsigned int keep_awake; + volatile unsigned int lpo_cal_time; + volatile unsigned int lpo_init_dividend_int; + volatile unsigned int lpo_init_dividend_fraction; + volatile unsigned int lpo_cal; + volatile unsigned int lpo_cal_test_control; + volatile unsigned int lpo_cal_test_status; + volatile unsigned int chip_id; + volatile unsigned int derived_rtc_clk; + volatile unsigned int mac_pcu_slp32_mode; + volatile unsigned int mac_pcu_slp32_wake; + volatile unsigned int mac_pcu_slp32_inc; + volatile unsigned int mac_pcu_slp_mib1; + volatile unsigned int mac_pcu_slp_mib2; + volatile unsigned int mac_pcu_slp_mib3; + volatile unsigned int mac_pcu_slp_beacon; + volatile unsigned int power_reg; + volatile unsigned int core_clk_ctrl; + unsigned char pad0[8]; /* pad to 0x120 */ + volatile unsigned int sdio_setup_circuit[8]; + volatile unsigned int sdio_setup_config; + volatile unsigned int cpu_setup_config; + unsigned char pad1[24]; /* pad to 0x160 */ + volatile unsigned int cpu_setup_circuit[8]; + volatile unsigned int bb_setup_config; + unsigned char pad2[28]; /* pad to 0x1a0 */ + volatile unsigned int bb_setup_circuit[8]; + volatile unsigned int gpio_wakeup_control; +} rtc_reg_reg_t; + +#endif /* __ASSEMBLER__ */ + +#endif /* _RTC_REG_H_ */ diff --git a/platform/mcu/lpc54102/wifi_qca/include/AR6002/hw2.0/hw/hw20_si_reg.h b/platform/mcu/lpc54102/wifi_qca/include/AR6002/hw2.0/hw/hw20_si_reg.h new file mode 100644 index 0000000000..454c40b159 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/include/AR6002/hw2.0/hw/hw20_si_reg.h @@ -0,0 +1,209 @@ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== +#ifndef _SI_REG_REG_H_ +#define _SI_REG_REG_H_ + +#define SI_CONFIG_ADDRESS 0x00000000 +#define SI_CONFIG_OFFSET 0x00000000 +#define SI_CONFIG_ERR_INT_MSB 19 +#define SI_CONFIG_ERR_INT_LSB 19 +#define SI_CONFIG_ERR_INT_MASK 0x00080000 +#define SI_CONFIG_ERR_INT_GET(x) (((x)&SI_CONFIG_ERR_INT_MASK) >> SI_CONFIG_ERR_INT_LSB) +#define SI_CONFIG_ERR_INT_SET(x) (((x) << SI_CONFIG_ERR_INT_LSB) & SI_CONFIG_ERR_INT_MASK) +#define SI_CONFIG_BIDIR_OD_DATA_MSB 18 +#define SI_CONFIG_BIDIR_OD_DATA_LSB 18 +#define SI_CONFIG_BIDIR_OD_DATA_MASK 0x00040000 +#define SI_CONFIG_BIDIR_OD_DATA_GET(x) (((x)&SI_CONFIG_BIDIR_OD_DATA_MASK) >> SI_CONFIG_BIDIR_OD_DATA_LSB) +#define SI_CONFIG_BIDIR_OD_DATA_SET(x) (((x) << SI_CONFIG_BIDIR_OD_DATA_LSB) & SI_CONFIG_BIDIR_OD_DATA_MASK) +#define SI_CONFIG_I2C_MSB 16 +#define SI_CONFIG_I2C_LSB 16 +#define SI_CONFIG_I2C_MASK 0x00010000 +#define SI_CONFIG_I2C_GET(x) (((x)&SI_CONFIG_I2C_MASK) >> SI_CONFIG_I2C_LSB) +#define SI_CONFIG_I2C_SET(x) (((x) << SI_CONFIG_I2C_LSB) & SI_CONFIG_I2C_MASK) +#define SI_CONFIG_POS_SAMPLE_MSB 7 +#define SI_CONFIG_POS_SAMPLE_LSB 7 +#define SI_CONFIG_POS_SAMPLE_MASK 0x00000080 +#define SI_CONFIG_POS_SAMPLE_GET(x) (((x)&SI_CONFIG_POS_SAMPLE_MASK) >> SI_CONFIG_POS_SAMPLE_LSB) +#define SI_CONFIG_POS_SAMPLE_SET(x) (((x) << SI_CONFIG_POS_SAMPLE_LSB) & SI_CONFIG_POS_SAMPLE_MASK) +#define SI_CONFIG_POS_DRIVE_MSB 6 +#define SI_CONFIG_POS_DRIVE_LSB 6 +#define SI_CONFIG_POS_DRIVE_MASK 0x00000040 +#define SI_CONFIG_POS_DRIVE_GET(x) (((x)&SI_CONFIG_POS_DRIVE_MASK) >> SI_CONFIG_POS_DRIVE_LSB) +#define SI_CONFIG_POS_DRIVE_SET(x) (((x) << SI_CONFIG_POS_DRIVE_LSB) & SI_CONFIG_POS_DRIVE_MASK) +#define SI_CONFIG_INACTIVE_DATA_MSB 5 +#define SI_CONFIG_INACTIVE_DATA_LSB 5 +#define SI_CONFIG_INACTIVE_DATA_MASK 0x00000020 +#define SI_CONFIG_INACTIVE_DATA_GET(x) (((x)&SI_CONFIG_INACTIVE_DATA_MASK) >> SI_CONFIG_INACTIVE_DATA_LSB) +#define SI_CONFIG_INACTIVE_DATA_SET(x) (((x) << SI_CONFIG_INACTIVE_DATA_LSB) & SI_CONFIG_INACTIVE_DATA_MASK) +#define SI_CONFIG_INACTIVE_CLK_MSB 4 +#define SI_CONFIG_INACTIVE_CLK_LSB 4 +#define SI_CONFIG_INACTIVE_CLK_MASK 0x00000010 +#define SI_CONFIG_INACTIVE_CLK_GET(x) (((x)&SI_CONFIG_INACTIVE_CLK_MASK) >> SI_CONFIG_INACTIVE_CLK_LSB) +#define SI_CONFIG_INACTIVE_CLK_SET(x) (((x) << SI_CONFIG_INACTIVE_CLK_LSB) & SI_CONFIG_INACTIVE_CLK_MASK) +#define SI_CONFIG_DIVIDER_MSB 3 +#define SI_CONFIG_DIVIDER_LSB 0 +#define SI_CONFIG_DIVIDER_MASK 0x0000000f +#define SI_CONFIG_DIVIDER_GET(x) (((x)&SI_CONFIG_DIVIDER_MASK) >> SI_CONFIG_DIVIDER_LSB) +#define SI_CONFIG_DIVIDER_SET(x) (((x) << SI_CONFIG_DIVIDER_LSB) & SI_CONFIG_DIVIDER_MASK) + +#define SI_CS_ADDRESS 0x00000004 +#define SI_CS_OFFSET 0x00000004 +#define SI_CS_BIT_CNT_IN_LAST_BYTE_MSB 13 +#define SI_CS_BIT_CNT_IN_LAST_BYTE_LSB 11 +#define SI_CS_BIT_CNT_IN_LAST_BYTE_MASK 0x00003800 +#define SI_CS_BIT_CNT_IN_LAST_BYTE_GET(x) (((x)&SI_CS_BIT_CNT_IN_LAST_BYTE_MASK) >> SI_CS_BIT_CNT_IN_LAST_BYTE_LSB) +#define SI_CS_BIT_CNT_IN_LAST_BYTE_SET(x) (((x) << SI_CS_BIT_CNT_IN_LAST_BYTE_LSB) & SI_CS_BIT_CNT_IN_LAST_BYTE_MASK) +#define SI_CS_DONE_ERR_MSB 10 +#define SI_CS_DONE_ERR_LSB 10 +#define SI_CS_DONE_ERR_MASK 0x00000400 +#define SI_CS_DONE_ERR_GET(x) (((x)&SI_CS_DONE_ERR_MASK) >> SI_CS_DONE_ERR_LSB) +#define SI_CS_DONE_ERR_SET(x) (((x) << SI_CS_DONE_ERR_LSB) & SI_CS_DONE_ERR_MASK) +#define SI_CS_DONE_INT_MSB 9 +#define SI_CS_DONE_INT_LSB 9 +#define SI_CS_DONE_INT_MASK 0x00000200 +#define SI_CS_DONE_INT_GET(x) (((x)&SI_CS_DONE_INT_MASK) >> SI_CS_DONE_INT_LSB) +#define SI_CS_DONE_INT_SET(x) (((x) << SI_CS_DONE_INT_LSB) & SI_CS_DONE_INT_MASK) +#define SI_CS_START_MSB 8 +#define SI_CS_START_LSB 8 +#define SI_CS_START_MASK 0x00000100 +#define SI_CS_START_GET(x) (((x)&SI_CS_START_MASK) >> SI_CS_START_LSB) +#define SI_CS_START_SET(x) (((x) << SI_CS_START_LSB) & SI_CS_START_MASK) +#define SI_CS_RX_CNT_MSB 7 +#define SI_CS_RX_CNT_LSB 4 +#define SI_CS_RX_CNT_MASK 0x000000f0 +#define SI_CS_RX_CNT_GET(x) (((x)&SI_CS_RX_CNT_MASK) >> SI_CS_RX_CNT_LSB) +#define SI_CS_RX_CNT_SET(x) (((x) << SI_CS_RX_CNT_LSB) & SI_CS_RX_CNT_MASK) +#define SI_CS_TX_CNT_MSB 3 +#define SI_CS_TX_CNT_LSB 0 +#define SI_CS_TX_CNT_MASK 0x0000000f +#define SI_CS_TX_CNT_GET(x) (((x)&SI_CS_TX_CNT_MASK) >> SI_CS_TX_CNT_LSB) +#define SI_CS_TX_CNT_SET(x) (((x) << SI_CS_TX_CNT_LSB) & SI_CS_TX_CNT_MASK) + +#define SI_TX_DATA0_ADDRESS 0x00000008 +#define SI_TX_DATA0_OFFSET 0x00000008 +#define SI_TX_DATA0_DATA3_MSB 31 +#define SI_TX_DATA0_DATA3_LSB 24 +#define SI_TX_DATA0_DATA3_MASK 0xff000000 +#define SI_TX_DATA0_DATA3_GET(x) (((x)&SI_TX_DATA0_DATA3_MASK) >> SI_TX_DATA0_DATA3_LSB) +#define SI_TX_DATA0_DATA3_SET(x) (((x) << SI_TX_DATA0_DATA3_LSB) & SI_TX_DATA0_DATA3_MASK) +#define SI_TX_DATA0_DATA2_MSB 23 +#define SI_TX_DATA0_DATA2_LSB 16 +#define SI_TX_DATA0_DATA2_MASK 0x00ff0000 +#define SI_TX_DATA0_DATA2_GET(x) (((x)&SI_TX_DATA0_DATA2_MASK) >> SI_TX_DATA0_DATA2_LSB) +#define SI_TX_DATA0_DATA2_SET(x) (((x) << SI_TX_DATA0_DATA2_LSB) & SI_TX_DATA0_DATA2_MASK) +#define SI_TX_DATA0_DATA1_MSB 15 +#define SI_TX_DATA0_DATA1_LSB 8 +#define SI_TX_DATA0_DATA1_MASK 0x0000ff00 +#define SI_TX_DATA0_DATA1_GET(x) (((x)&SI_TX_DATA0_DATA1_MASK) >> SI_TX_DATA0_DATA1_LSB) +#define SI_TX_DATA0_DATA1_SET(x) (((x) << SI_TX_DATA0_DATA1_LSB) & SI_TX_DATA0_DATA1_MASK) +#define SI_TX_DATA0_DATA0_MSB 7 +#define SI_TX_DATA0_DATA0_LSB 0 +#define SI_TX_DATA0_DATA0_MASK 0x000000ff +#define SI_TX_DATA0_DATA0_GET(x) (((x)&SI_TX_DATA0_DATA0_MASK) >> SI_TX_DATA0_DATA0_LSB) +#define SI_TX_DATA0_DATA0_SET(x) (((x) << SI_TX_DATA0_DATA0_LSB) & SI_TX_DATA0_DATA0_MASK) + +#define SI_TX_DATA1_ADDRESS 0x0000000c +#define SI_TX_DATA1_OFFSET 0x0000000c +#define SI_TX_DATA1_DATA7_MSB 31 +#define SI_TX_DATA1_DATA7_LSB 24 +#define SI_TX_DATA1_DATA7_MASK 0xff000000 +#define SI_TX_DATA1_DATA7_GET(x) (((x)&SI_TX_DATA1_DATA7_MASK) >> SI_TX_DATA1_DATA7_LSB) +#define SI_TX_DATA1_DATA7_SET(x) (((x) << SI_TX_DATA1_DATA7_LSB) & SI_TX_DATA1_DATA7_MASK) +#define SI_TX_DATA1_DATA6_MSB 23 +#define SI_TX_DATA1_DATA6_LSB 16 +#define SI_TX_DATA1_DATA6_MASK 0x00ff0000 +#define SI_TX_DATA1_DATA6_GET(x) (((x)&SI_TX_DATA1_DATA6_MASK) >> SI_TX_DATA1_DATA6_LSB) +#define SI_TX_DATA1_DATA6_SET(x) (((x) << SI_TX_DATA1_DATA6_LSB) & SI_TX_DATA1_DATA6_MASK) +#define SI_TX_DATA1_DATA5_MSB 15 +#define SI_TX_DATA1_DATA5_LSB 8 +#define SI_TX_DATA1_DATA5_MASK 0x0000ff00 +#define SI_TX_DATA1_DATA5_GET(x) (((x)&SI_TX_DATA1_DATA5_MASK) >> SI_TX_DATA1_DATA5_LSB) +#define SI_TX_DATA1_DATA5_SET(x) (((x) << SI_TX_DATA1_DATA5_LSB) & SI_TX_DATA1_DATA5_MASK) +#define SI_TX_DATA1_DATA4_MSB 7 +#define SI_TX_DATA1_DATA4_LSB 0 +#define SI_TX_DATA1_DATA4_MASK 0x000000ff +#define SI_TX_DATA1_DATA4_GET(x) (((x)&SI_TX_DATA1_DATA4_MASK) >> SI_TX_DATA1_DATA4_LSB) +#define SI_TX_DATA1_DATA4_SET(x) (((x) << SI_TX_DATA1_DATA4_LSB) & SI_TX_DATA1_DATA4_MASK) + +#define SI_RX_DATA0_ADDRESS 0x00000010 +#define SI_RX_DATA0_OFFSET 0x00000010 +#define SI_RX_DATA0_DATA3_MSB 31 +#define SI_RX_DATA0_DATA3_LSB 24 +#define SI_RX_DATA0_DATA3_MASK 0xff000000 +#define SI_RX_DATA0_DATA3_GET(x) (((x)&SI_RX_DATA0_DATA3_MASK) >> SI_RX_DATA0_DATA3_LSB) +#define SI_RX_DATA0_DATA3_SET(x) (((x) << SI_RX_DATA0_DATA3_LSB) & SI_RX_DATA0_DATA3_MASK) +#define SI_RX_DATA0_DATA2_MSB 23 +#define SI_RX_DATA0_DATA2_LSB 16 +#define SI_RX_DATA0_DATA2_MASK 0x00ff0000 +#define SI_RX_DATA0_DATA2_GET(x) (((x)&SI_RX_DATA0_DATA2_MASK) >> SI_RX_DATA0_DATA2_LSB) +#define SI_RX_DATA0_DATA2_SET(x) (((x) << SI_RX_DATA0_DATA2_LSB) & SI_RX_DATA0_DATA2_MASK) +#define SI_RX_DATA0_DATA1_MSB 15 +#define SI_RX_DATA0_DATA1_LSB 8 +#define SI_RX_DATA0_DATA1_MASK 0x0000ff00 +#define SI_RX_DATA0_DATA1_GET(x) (((x)&SI_RX_DATA0_DATA1_MASK) >> SI_RX_DATA0_DATA1_LSB) +#define SI_RX_DATA0_DATA1_SET(x) (((x) << SI_RX_DATA0_DATA1_LSB) & SI_RX_DATA0_DATA1_MASK) +#define SI_RX_DATA0_DATA0_MSB 7 +#define SI_RX_DATA0_DATA0_LSB 0 +#define SI_RX_DATA0_DATA0_MASK 0x000000ff +#define SI_RX_DATA0_DATA0_GET(x) (((x)&SI_RX_DATA0_DATA0_MASK) >> SI_RX_DATA0_DATA0_LSB) +#define SI_RX_DATA0_DATA0_SET(x) (((x) << SI_RX_DATA0_DATA0_LSB) & SI_RX_DATA0_DATA0_MASK) + +#define SI_RX_DATA1_ADDRESS 0x00000014 +#define SI_RX_DATA1_OFFSET 0x00000014 +#define SI_RX_DATA1_DATA7_MSB 31 +#define SI_RX_DATA1_DATA7_LSB 24 +#define SI_RX_DATA1_DATA7_MASK 0xff000000 +#define SI_RX_DATA1_DATA7_GET(x) (((x)&SI_RX_DATA1_DATA7_MASK) >> SI_RX_DATA1_DATA7_LSB) +#define SI_RX_DATA1_DATA7_SET(x) (((x) << SI_RX_DATA1_DATA7_LSB) & SI_RX_DATA1_DATA7_MASK) +#define SI_RX_DATA1_DATA6_MSB 23 +#define SI_RX_DATA1_DATA6_LSB 16 +#define SI_RX_DATA1_DATA6_MASK 0x00ff0000 +#define SI_RX_DATA1_DATA6_GET(x) (((x)&SI_RX_DATA1_DATA6_MASK) >> SI_RX_DATA1_DATA6_LSB) +#define SI_RX_DATA1_DATA6_SET(x) (((x) << SI_RX_DATA1_DATA6_LSB) & SI_RX_DATA1_DATA6_MASK) +#define SI_RX_DATA1_DATA5_MSB 15 +#define SI_RX_DATA1_DATA5_LSB 8 +#define SI_RX_DATA1_DATA5_MASK 0x0000ff00 +#define SI_RX_DATA1_DATA5_GET(x) (((x)&SI_RX_DATA1_DATA5_MASK) >> SI_RX_DATA1_DATA5_LSB) +#define SI_RX_DATA1_DATA5_SET(x) (((x) << SI_RX_DATA1_DATA5_LSB) & SI_RX_DATA1_DATA5_MASK) +#define SI_RX_DATA1_DATA4_MSB 7 +#define SI_RX_DATA1_DATA4_LSB 0 +#define SI_RX_DATA1_DATA4_MASK 0x000000ff +#define SI_RX_DATA1_DATA4_GET(x) (((x)&SI_RX_DATA1_DATA4_MASK) >> SI_RX_DATA1_DATA4_LSB) +#define SI_RX_DATA1_DATA4_SET(x) (((x) << SI_RX_DATA1_DATA4_LSB) & SI_RX_DATA1_DATA4_MASK) + +#ifndef __ASSEMBLER__ + +typedef struct si_reg_reg_s +{ + volatile unsigned int si_config; + volatile unsigned int si_cs; + volatile unsigned int si_tx_data0; + volatile unsigned int si_tx_data1; + volatile unsigned int si_rx_data0; + volatile unsigned int si_rx_data1; +} si_reg_reg_t; + +#endif /* __ASSEMBLER__ */ + +#endif /* _SI_REG_H_ */ diff --git a/platform/mcu/lpc54102/wifi_qca/include/AR6002/hw2.0/hw/hw20_uart_reg.h b/platform/mcu/lpc54102/wifi_qca/include/AR6002/hw2.0/hw/hw20_uart_reg.h new file mode 100644 index 0000000000..5461d77432 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/include/AR6002/hw2.0/hw/hw20_uart_reg.h @@ -0,0 +1,350 @@ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== +#ifndef _UART_REG_REG_H_ +#define _UART_REG_REG_H_ + +#define RBR_ADDRESS 0x00000000 +#define RBR_OFFSET 0x00000000 +#define RBR_RBR_MSB 7 +#define RBR_RBR_LSB 0 +#define RBR_RBR_MASK 0x000000ff +#define RBR_RBR_GET(x) (((x)&RBR_RBR_MASK) >> RBR_RBR_LSB) +#define RBR_RBR_SET(x) (((x) << RBR_RBR_LSB) & RBR_RBR_MASK) + +#define THR_ADDRESS 0x00000000 +#define THR_OFFSET 0x00000000 +#define THR_THR_MSB 7 +#define THR_THR_LSB 0 +#define THR_THR_MASK 0x000000ff +#define THR_THR_GET(x) (((x)&THR_THR_MASK) >> THR_THR_LSB) +#define THR_THR_SET(x) (((x) << THR_THR_LSB) & THR_THR_MASK) + +#define DLL_ADDRESS 0x00000000 +#define DLL_OFFSET 0x00000000 +#define DLL_DLL_MSB 7 +#define DLL_DLL_LSB 0 +#define DLL_DLL_MASK 0x000000ff +#define DLL_DLL_GET(x) (((x)&DLL_DLL_MASK) >> DLL_DLL_LSB) +#define DLL_DLL_SET(x) (((x) << DLL_DLL_LSB) & DLL_DLL_MASK) + +#define DLH_ADDRESS 0x00000004 +#define DLH_OFFSET 0x00000004 +#define DLH_DLH_MSB 7 +#define DLH_DLH_LSB 0 +#define DLH_DLH_MASK 0x000000ff +#define DLH_DLH_GET(x) (((x)&DLH_DLH_MASK) >> DLH_DLH_LSB) +#define DLH_DLH_SET(x) (((x) << DLH_DLH_LSB) & DLH_DLH_MASK) + +#define IER_ADDRESS 0x00000004 +#define IER_OFFSET 0x00000004 +#define IER_EDDSI_MSB 3 +#define IER_EDDSI_LSB 3 +#define IER_EDDSI_MASK 0x00000008 +#define IER_EDDSI_GET(x) (((x)&IER_EDDSI_MASK) >> IER_EDDSI_LSB) +#define IER_EDDSI_SET(x) (((x) << IER_EDDSI_LSB) & IER_EDDSI_MASK) +#define IER_ELSI_MSB 2 +#define IER_ELSI_LSB 2 +#define IER_ELSI_MASK 0x00000004 +#define IER_ELSI_GET(x) (((x)&IER_ELSI_MASK) >> IER_ELSI_LSB) +#define IER_ELSI_SET(x) (((x) << IER_ELSI_LSB) & IER_ELSI_MASK) +#define IER_ETBEI_MSB 1 +#define IER_ETBEI_LSB 1 +#define IER_ETBEI_MASK 0x00000002 +#define IER_ETBEI_GET(x) (((x)&IER_ETBEI_MASK) >> IER_ETBEI_LSB) +#define IER_ETBEI_SET(x) (((x) << IER_ETBEI_LSB) & IER_ETBEI_MASK) +#define IER_ERBFI_MSB 0 +#define IER_ERBFI_LSB 0 +#define IER_ERBFI_MASK 0x00000001 +#define IER_ERBFI_GET(x) (((x)&IER_ERBFI_MASK) >> IER_ERBFI_LSB) +#define IER_ERBFI_SET(x) (((x) << IER_ERBFI_LSB) & IER_ERBFI_MASK) + +#define IIR_ADDRESS 0x00000008 +#define IIR_OFFSET 0x00000008 +#define IIR_FIFO_STATUS_MSB 7 +#define IIR_FIFO_STATUS_LSB 6 +#define IIR_FIFO_STATUS_MASK 0x000000c0 +#define IIR_FIFO_STATUS_GET(x) (((x)&IIR_FIFO_STATUS_MASK) >> IIR_FIFO_STATUS_LSB) +#define IIR_FIFO_STATUS_SET(x) (((x) << IIR_FIFO_STATUS_LSB) & IIR_FIFO_STATUS_MASK) +#define IIR_IID_MSB 3 +#define IIR_IID_LSB 0 +#define IIR_IID_MASK 0x0000000f +#define IIR_IID_GET(x) (((x)&IIR_IID_MASK) >> IIR_IID_LSB) +#define IIR_IID_SET(x) (((x) << IIR_IID_LSB) & IIR_IID_MASK) + +#define FCR_ADDRESS 0x00000008 +#define FCR_OFFSET 0x00000008 +#define FCR_RCVR_TRIG_MSB 7 +#define FCR_RCVR_TRIG_LSB 6 +#define FCR_RCVR_TRIG_MASK 0x000000c0 +#define FCR_RCVR_TRIG_GET(x) (((x)&FCR_RCVR_TRIG_MASK) >> FCR_RCVR_TRIG_LSB) +#define FCR_RCVR_TRIG_SET(x) (((x) << FCR_RCVR_TRIG_LSB) & FCR_RCVR_TRIG_MASK) +#define FCR_DMA_MODE_MSB 3 +#define FCR_DMA_MODE_LSB 3 +#define FCR_DMA_MODE_MASK 0x00000008 +#define FCR_DMA_MODE_GET(x) (((x)&FCR_DMA_MODE_MASK) >> FCR_DMA_MODE_LSB) +#define FCR_DMA_MODE_SET(x) (((x) << FCR_DMA_MODE_LSB) & FCR_DMA_MODE_MASK) +#define FCR_XMIT_FIFO_RST_MSB 2 +#define FCR_XMIT_FIFO_RST_LSB 2 +#define FCR_XMIT_FIFO_RST_MASK 0x00000004 +#define FCR_XMIT_FIFO_RST_GET(x) (((x)&FCR_XMIT_FIFO_RST_MASK) >> FCR_XMIT_FIFO_RST_LSB) +#define FCR_XMIT_FIFO_RST_SET(x) (((x) << FCR_XMIT_FIFO_RST_LSB) & FCR_XMIT_FIFO_RST_MASK) +#define FCR_RCVR_FIFO_RST_MSB 1 +#define FCR_RCVR_FIFO_RST_LSB 1 +#define FCR_RCVR_FIFO_RST_MASK 0x00000002 +#define FCR_RCVR_FIFO_RST_GET(x) (((x)&FCR_RCVR_FIFO_RST_MASK) >> FCR_RCVR_FIFO_RST_LSB) +#define FCR_RCVR_FIFO_RST_SET(x) (((x) << FCR_RCVR_FIFO_RST_LSB) & FCR_RCVR_FIFO_RST_MASK) +#define FCR_FIFO_EN_MSB 0 +#define FCR_FIFO_EN_LSB 0 +#define FCR_FIFO_EN_MASK 0x00000001 +#define FCR_FIFO_EN_GET(x) (((x)&FCR_FIFO_EN_MASK) >> FCR_FIFO_EN_LSB) +#define FCR_FIFO_EN_SET(x) (((x) << FCR_FIFO_EN_LSB) & FCR_FIFO_EN_MASK) + +#define LCR_ADDRESS 0x0000000c +#define LCR_OFFSET 0x0000000c +#define LCR_DLAB_MSB 7 +#define LCR_DLAB_LSB 7 +#define LCR_DLAB_MASK 0x00000080 +#define LCR_DLAB_GET(x) (((x)&LCR_DLAB_MASK) >> LCR_DLAB_LSB) +#define LCR_DLAB_SET(x) (((x) << LCR_DLAB_LSB) & LCR_DLAB_MASK) +#define LCR_BREAK_MSB 6 +#define LCR_BREAK_LSB 6 +#define LCR_BREAK_MASK 0x00000040 +#define LCR_BREAK_GET(x) (((x)&LCR_BREAK_MASK) >> LCR_BREAK_LSB) +#define LCR_BREAK_SET(x) (((x) << LCR_BREAK_LSB) & LCR_BREAK_MASK) +#define LCR_EPS_MSB 4 +#define LCR_EPS_LSB 4 +#define LCR_EPS_MASK 0x00000010 +#define LCR_EPS_GET(x) (((x)&LCR_EPS_MASK) >> LCR_EPS_LSB) +#define LCR_EPS_SET(x) (((x) << LCR_EPS_LSB) & LCR_EPS_MASK) +#define LCR_PEN_MSB 3 +#define LCR_PEN_LSB 3 +#define LCR_PEN_MASK 0x00000008 +#define LCR_PEN_GET(x) (((x)&LCR_PEN_MASK) >> LCR_PEN_LSB) +#define LCR_PEN_SET(x) (((x) << LCR_PEN_LSB) & LCR_PEN_MASK) +#define LCR_STOP_MSB 2 +#define LCR_STOP_LSB 2 +#define LCR_STOP_MASK 0x00000004 +#define LCR_STOP_GET(x) (((x)&LCR_STOP_MASK) >> LCR_STOP_LSB) +#define LCR_STOP_SET(x) (((x) << LCR_STOP_LSB) & LCR_STOP_MASK) +#define LCR_CLS_MSB 1 +#define LCR_CLS_LSB 0 +#define LCR_CLS_MASK 0x00000003 +#define LCR_CLS_GET(x) (((x)&LCR_CLS_MASK) >> LCR_CLS_LSB) +#define LCR_CLS_SET(x) (((x) << LCR_CLS_LSB) & LCR_CLS_MASK) + +#define MCR_ADDRESS 0x00000010 +#define MCR_OFFSET 0x00000010 +#define MCR_LOOPBACK_MSB 5 +#define MCR_LOOPBACK_LSB 5 +#define MCR_LOOPBACK_MASK 0x00000020 +#define MCR_LOOPBACK_GET(x) (((x)&MCR_LOOPBACK_MASK) >> MCR_LOOPBACK_LSB) +#define MCR_LOOPBACK_SET(x) (((x) << MCR_LOOPBACK_LSB) & MCR_LOOPBACK_MASK) +#define MCR_OUT2_MSB 3 +#define MCR_OUT2_LSB 3 +#define MCR_OUT2_MASK 0x00000008 +#define MCR_OUT2_GET(x) (((x)&MCR_OUT2_MASK) >> MCR_OUT2_LSB) +#define MCR_OUT2_SET(x) (((x) << MCR_OUT2_LSB) & MCR_OUT2_MASK) +#define MCR_OUT1_MSB 2 +#define MCR_OUT1_LSB 2 +#define MCR_OUT1_MASK 0x00000004 +#define MCR_OUT1_GET(x) (((x)&MCR_OUT1_MASK) >> MCR_OUT1_LSB) +#define MCR_OUT1_SET(x) (((x) << MCR_OUT1_LSB) & MCR_OUT1_MASK) +#define MCR_RTS_MSB 1 +#define MCR_RTS_LSB 1 +#define MCR_RTS_MASK 0x00000002 +#define MCR_RTS_GET(x) (((x)&MCR_RTS_MASK) >> MCR_RTS_LSB) +#define MCR_RTS_SET(x) (((x) << MCR_RTS_LSB) & MCR_RTS_MASK) +#define MCR_DTR_MSB 0 +#define MCR_DTR_LSB 0 +#define MCR_DTR_MASK 0x00000001 +#define MCR_DTR_GET(x) (((x)&MCR_DTR_MASK) >> MCR_DTR_LSB) +#define MCR_DTR_SET(x) (((x) << MCR_DTR_LSB) & MCR_DTR_MASK) + +#define LSR_ADDRESS 0x00000014 +#define LSR_OFFSET 0x00000014 +#define LSR_FERR_MSB 7 +#define LSR_FERR_LSB 7 +#define LSR_FERR_MASK 0x00000080 +#define LSR_FERR_GET(x) (((x)&LSR_FERR_MASK) >> LSR_FERR_LSB) +#define LSR_FERR_SET(x) (((x) << LSR_FERR_LSB) & LSR_FERR_MASK) +#define LSR_TEMT_MSB 6 +#define LSR_TEMT_LSB 6 +#define LSR_TEMT_MASK 0x00000040 +#define LSR_TEMT_GET(x) (((x)&LSR_TEMT_MASK) >> LSR_TEMT_LSB) +#define LSR_TEMT_SET(x) (((x) << LSR_TEMT_LSB) & LSR_TEMT_MASK) +#define LSR_THRE_MSB 5 +#define LSR_THRE_LSB 5 +#define LSR_THRE_MASK 0x00000020 +#define LSR_THRE_GET(x) (((x)&LSR_THRE_MASK) >> LSR_THRE_LSB) +#define LSR_THRE_SET(x) (((x) << LSR_THRE_LSB) & LSR_THRE_MASK) +#define LSR_BI_MSB 4 +#define LSR_BI_LSB 4 +#define LSR_BI_MASK 0x00000010 +#define LSR_BI_GET(x) (((x)&LSR_BI_MASK) >> LSR_BI_LSB) +#define LSR_BI_SET(x) (((x) << LSR_BI_LSB) & LSR_BI_MASK) +#define LSR_FE_MSB 3 +#define LSR_FE_LSB 3 +#define LSR_FE_MASK 0x00000008 +#define LSR_FE_GET(x) (((x)&LSR_FE_MASK) >> LSR_FE_LSB) +#define LSR_FE_SET(x) (((x) << LSR_FE_LSB) & LSR_FE_MASK) +#define LSR_PE_MSB 2 +#define LSR_PE_LSB 2 +#define LSR_PE_MASK 0x00000004 +#define LSR_PE_GET(x) (((x)&LSR_PE_MASK) >> LSR_PE_LSB) +#define LSR_PE_SET(x) (((x) << LSR_PE_LSB) & LSR_PE_MASK) +#define LSR_OE_MSB 1 +#define LSR_OE_LSB 1 +#define LSR_OE_MASK 0x00000002 +#define LSR_OE_GET(x) (((x)&LSR_OE_MASK) >> LSR_OE_LSB) +#define LSR_OE_SET(x) (((x) << LSR_OE_LSB) & LSR_OE_MASK) +#define LSR_DR_MSB 0 +#define LSR_DR_LSB 0 +#define LSR_DR_MASK 0x00000001 +#define LSR_DR_GET(x) (((x)&LSR_DR_MASK) >> LSR_DR_LSB) +#define LSR_DR_SET(x) (((x) << LSR_DR_LSB) & LSR_DR_MASK) + +#define MSR_ADDRESS 0x00000018 +#define MSR_OFFSET 0x00000018 +#define MSR_DCD_MSB 7 +#define MSR_DCD_LSB 7 +#define MSR_DCD_MASK 0x00000080 +#define MSR_DCD_GET(x) (((x)&MSR_DCD_MASK) >> MSR_DCD_LSB) +#define MSR_DCD_SET(x) (((x) << MSR_DCD_LSB) & MSR_DCD_MASK) +#define MSR_RI_MSB 6 +#define MSR_RI_LSB 6 +#define MSR_RI_MASK 0x00000040 +#define MSR_RI_GET(x) (((x)&MSR_RI_MASK) >> MSR_RI_LSB) +#define MSR_RI_SET(x) (((x) << MSR_RI_LSB) & MSR_RI_MASK) +#define MSR_DSR_MSB 5 +#define MSR_DSR_LSB 5 +#define MSR_DSR_MASK 0x00000020 +#define MSR_DSR_GET(x) (((x)&MSR_DSR_MASK) >> MSR_DSR_LSB) +#define MSR_DSR_SET(x) (((x) << MSR_DSR_LSB) & MSR_DSR_MASK) +#define MSR_CTS_MSB 4 +#define MSR_CTS_LSB 4 +#define MSR_CTS_MASK 0x00000010 +#define MSR_CTS_GET(x) (((x)&MSR_CTS_MASK) >> MSR_CTS_LSB) +#define MSR_CTS_SET(x) (((x) << MSR_CTS_LSB) & MSR_CTS_MASK) +#define MSR_DDCD_MSB 3 +#define MSR_DDCD_LSB 3 +#define MSR_DDCD_MASK 0x00000008 +#define MSR_DDCD_GET(x) (((x)&MSR_DDCD_MASK) >> MSR_DDCD_LSB) +#define MSR_DDCD_SET(x) (((x) << MSR_DDCD_LSB) & MSR_DDCD_MASK) +#define MSR_TERI_MSB 2 +#define MSR_TERI_LSB 2 +#define MSR_TERI_MASK 0x00000004 +#define MSR_TERI_GET(x) (((x)&MSR_TERI_MASK) >> MSR_TERI_LSB) +#define MSR_TERI_SET(x) (((x) << MSR_TERI_LSB) & MSR_TERI_MASK) +#define MSR_DDSR_MSB 1 +#define MSR_DDSR_LSB 1 +#define MSR_DDSR_MASK 0x00000002 +#define MSR_DDSR_GET(x) (((x)&MSR_DDSR_MASK) >> MSR_DDSR_LSB) +#define MSR_DDSR_SET(x) (((x) << MSR_DDSR_LSB) & MSR_DDSR_MASK) +#define MSR_DCTS_MSB 0 +#define MSR_DCTS_LSB 0 +#define MSR_DCTS_MASK 0x00000001 +#define MSR_DCTS_GET(x) (((x)&MSR_DCTS_MASK) >> MSR_DCTS_LSB) +#define MSR_DCTS_SET(x) (((x) << MSR_DCTS_LSB) & MSR_DCTS_MASK) + +#define SCR_ADDRESS 0x0000001c +#define SCR_OFFSET 0x0000001c +#define SCR_SCR_MSB 7 +#define SCR_SCR_LSB 0 +#define SCR_SCR_MASK 0x000000ff +#define SCR_SCR_GET(x) (((x)&SCR_SCR_MASK) >> SCR_SCR_LSB) +#define SCR_SCR_SET(x) (((x) << SCR_SCR_LSB) & SCR_SCR_MASK) + +#define SRBR_ADDRESS 0x00000020 +#define SRBR_OFFSET 0x00000020 +#define SRBR_SRBR_MSB 7 +#define SRBR_SRBR_LSB 0 +#define SRBR_SRBR_MASK 0x000000ff +#define SRBR_SRBR_GET(x) (((x)&SRBR_SRBR_MASK) >> SRBR_SRBR_LSB) +#define SRBR_SRBR_SET(x) (((x) << SRBR_SRBR_LSB) & SRBR_SRBR_MASK) + +#define SIIR_ADDRESS 0x00000028 +#define SIIR_OFFSET 0x00000028 +#define SIIR_SIIR_MSB 7 +#define SIIR_SIIR_LSB 0 +#define SIIR_SIIR_MASK 0x000000ff +#define SIIR_SIIR_GET(x) (((x)&SIIR_SIIR_MASK) >> SIIR_SIIR_LSB) +#define SIIR_SIIR_SET(x) (((x) << SIIR_SIIR_LSB) & SIIR_SIIR_MASK) + +#define MWR_ADDRESS 0x0000002c +#define MWR_OFFSET 0x0000002c +#define MWR_MWR_MSB 31 +#define MWR_MWR_LSB 0 +#define MWR_MWR_MASK 0xffffffff +#define MWR_MWR_GET(x) (((x)&MWR_MWR_MASK) >> MWR_MWR_LSB) +#define MWR_MWR_SET(x) (((x) << MWR_MWR_LSB) & MWR_MWR_MASK) + +#define SLSR_ADDRESS 0x00000034 +#define SLSR_OFFSET 0x00000034 +#define SLSR_SLSR_MSB 7 +#define SLSR_SLSR_LSB 0 +#define SLSR_SLSR_MASK 0x000000ff +#define SLSR_SLSR_GET(x) (((x)&SLSR_SLSR_MASK) >> SLSR_SLSR_LSB) +#define SLSR_SLSR_SET(x) (((x) << SLSR_SLSR_LSB) & SLSR_SLSR_MASK) + +#define SMSR_ADDRESS 0x00000038 +#define SMSR_OFFSET 0x00000038 +#define SMSR_SMSR_MSB 7 +#define SMSR_SMSR_LSB 0 +#define SMSR_SMSR_MASK 0x000000ff +#define SMSR_SMSR_GET(x) (((x)&SMSR_SMSR_MASK) >> SMSR_SMSR_LSB) +#define SMSR_SMSR_SET(x) (((x) << SMSR_SMSR_LSB) & SMSR_SMSR_MASK) + +#define MRR_ADDRESS 0x0000003c +#define MRR_OFFSET 0x0000003c +#define MRR_MRR_MSB 31 +#define MRR_MRR_LSB 0 +#define MRR_MRR_MASK 0xffffffff +#define MRR_MRR_GET(x) (((x)&MRR_MRR_MASK) >> MRR_MRR_LSB) +#define MRR_MRR_SET(x) (((x) << MRR_MRR_LSB) & MRR_MRR_MASK) + +#ifndef __ASSEMBLER__ + +typedef struct uart_reg_reg_s +{ + volatile unsigned int rbr; + volatile unsigned int dlh; + volatile unsigned int iir; + volatile unsigned int lcr; + volatile unsigned int mcr; + volatile unsigned int lsr; + volatile unsigned int msr; + volatile unsigned int scr; + volatile unsigned int srbr; + unsigned char pad0[4]; /* pad to 0x28 */ + volatile unsigned int siir; + volatile unsigned int mwr; + unsigned char pad1[4]; /* pad to 0x34 */ + volatile unsigned int slsr; + volatile unsigned int smsr; + volatile unsigned int mrr; +} uart_reg_reg_t; + +#endif /* __ASSEMBLER__ */ + +#endif /* _UART_REG_H_ */ diff --git a/platform/mcu/lpc54102/wifi_qca/include/AR6002/hw2.0/hw/hw20_vmc_reg.h b/platform/mcu/lpc54102/wifi_qca/include/AR6002/hw2.0/hw/hw20_vmc_reg.h new file mode 100644 index 0000000000..5390fd1c2e --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/include/AR6002/hw2.0/hw/hw20_vmc_reg.h @@ -0,0 +1,101 @@ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== +#ifndef _VMC_REG_REG_H_ +#define _VMC_REG_REG_H_ + +#define MC_TCAM_VALID_ADDRESS 0x00000000 +#define MC_TCAM_VALID_OFFSET 0x00000000 +#define MC_TCAM_VALID_BIT_MSB 0 +#define MC_TCAM_VALID_BIT_LSB 0 +#define MC_TCAM_VALID_BIT_MASK 0x00000001 +#define MC_TCAM_VALID_BIT_GET(x) (((x)&MC_TCAM_VALID_BIT_MASK) >> MC_TCAM_VALID_BIT_LSB) +#define MC_TCAM_VALID_BIT_SET(x) (((x) << MC_TCAM_VALID_BIT_LSB) & MC_TCAM_VALID_BIT_MASK) + +#define MC_TCAM_MASK_ADDRESS 0x00000080 +#define MC_TCAM_MASK_OFFSET 0x00000080 +#define MC_TCAM_MASK_SIZE_MSB 2 +#define MC_TCAM_MASK_SIZE_LSB 0 +#define MC_TCAM_MASK_SIZE_MASK 0x00000007 +#define MC_TCAM_MASK_SIZE_GET(x) (((x)&MC_TCAM_MASK_SIZE_MASK) >> MC_TCAM_MASK_SIZE_LSB) +#define MC_TCAM_MASK_SIZE_SET(x) (((x) << MC_TCAM_MASK_SIZE_LSB) & MC_TCAM_MASK_SIZE_MASK) + +#define MC_TCAM_COMPARE_ADDRESS 0x00000100 +#define MC_TCAM_COMPARE_OFFSET 0x00000100 +#define MC_TCAM_COMPARE_KEY_MSB 21 +#define MC_TCAM_COMPARE_KEY_LSB 5 +#define MC_TCAM_COMPARE_KEY_MASK 0x003fffe0 +#define MC_TCAM_COMPARE_KEY_GET(x) (((x)&MC_TCAM_COMPARE_KEY_MASK) >> MC_TCAM_COMPARE_KEY_LSB) +#define MC_TCAM_COMPARE_KEY_SET(x) (((x) << MC_TCAM_COMPARE_KEY_LSB) & MC_TCAM_COMPARE_KEY_MASK) + +#define MC_TCAM_TARGET_ADDRESS 0x00000180 +#define MC_TCAM_TARGET_OFFSET 0x00000180 +#define MC_TCAM_TARGET_ADDR_MSB 21 +#define MC_TCAM_TARGET_ADDR_LSB 5 +#define MC_TCAM_TARGET_ADDR_MASK 0x003fffe0 +#define MC_TCAM_TARGET_ADDR_GET(x) (((x)&MC_TCAM_TARGET_ADDR_MASK) >> MC_TCAM_TARGET_ADDR_LSB) +#define MC_TCAM_TARGET_ADDR_SET(x) (((x) << MC_TCAM_TARGET_ADDR_LSB) & MC_TCAM_TARGET_ADDR_MASK) + +#define ADDR_ERROR_CONTROL_ADDRESS 0x00000200 +#define ADDR_ERROR_CONTROL_OFFSET 0x00000200 +#define ADDR_ERROR_CONTROL_QUAL_ENABLE_MSB 1 +#define ADDR_ERROR_CONTROL_QUAL_ENABLE_LSB 1 +#define ADDR_ERROR_CONTROL_QUAL_ENABLE_MASK 0x00000002 +#define ADDR_ERROR_CONTROL_QUAL_ENABLE_GET(x) \ + (((x)&ADDR_ERROR_CONTROL_QUAL_ENABLE_MASK) >> ADDR_ERROR_CONTROL_QUAL_ENABLE_LSB) +#define ADDR_ERROR_CONTROL_QUAL_ENABLE_SET(x) \ + (((x) << ADDR_ERROR_CONTROL_QUAL_ENABLE_LSB) & ADDR_ERROR_CONTROL_QUAL_ENABLE_MASK) +#define ADDR_ERROR_CONTROL_ENABLE_MSB 0 +#define ADDR_ERROR_CONTROL_ENABLE_LSB 0 +#define ADDR_ERROR_CONTROL_ENABLE_MASK 0x00000001 +#define ADDR_ERROR_CONTROL_ENABLE_GET(x) (((x)&ADDR_ERROR_CONTROL_ENABLE_MASK) >> ADDR_ERROR_CONTROL_ENABLE_LSB) +#define ADDR_ERROR_CONTROL_ENABLE_SET(x) (((x) << ADDR_ERROR_CONTROL_ENABLE_LSB) & ADDR_ERROR_CONTROL_ENABLE_MASK) + +#define ADDR_ERROR_STATUS_ADDRESS 0x00000204 +#define ADDR_ERROR_STATUS_OFFSET 0x00000204 +#define ADDR_ERROR_STATUS_WRITE_MSB 25 +#define ADDR_ERROR_STATUS_WRITE_LSB 25 +#define ADDR_ERROR_STATUS_WRITE_MASK 0x02000000 +#define ADDR_ERROR_STATUS_WRITE_GET(x) (((x)&ADDR_ERROR_STATUS_WRITE_MASK) >> ADDR_ERROR_STATUS_WRITE_LSB) +#define ADDR_ERROR_STATUS_WRITE_SET(x) (((x) << ADDR_ERROR_STATUS_WRITE_LSB) & ADDR_ERROR_STATUS_WRITE_MASK) +#define ADDR_ERROR_STATUS_ADDRESS_MSB 24 +#define ADDR_ERROR_STATUS_ADDRESS_LSB 0 +#define ADDR_ERROR_STATUS_ADDRESS_MASK 0x01ffffff +#define ADDR_ERROR_STATUS_ADDRESS_GET(x) (((x)&ADDR_ERROR_STATUS_ADDRESS_MASK) >> ADDR_ERROR_STATUS_ADDRESS_LSB) +#define ADDR_ERROR_STATUS_ADDRESS_SET(x) (((x) << ADDR_ERROR_STATUS_ADDRESS_LSB) & ADDR_ERROR_STATUS_ADDRESS_MASK) + +#ifndef __ASSEMBLER__ + +typedef struct vmc_reg_reg_s +{ + volatile unsigned int mc_tcam_valid[32]; + volatile unsigned int mc_tcam_mask[32]; + volatile unsigned int mc_tcam_compare[32]; + volatile unsigned int mc_tcam_target[32]; + volatile unsigned int addr_error_control; + volatile unsigned int addr_error_status; +} vmc_reg_reg_t; + +#endif /* __ASSEMBLER__ */ + +#endif /* _VMC_REG_H_ */ diff --git a/platform/mcu/lpc54102/wifi_qca/include/AR6002/hw4.0/hw/hw40_rtc_reg.h b/platform/mcu/lpc54102/wifi_qca/include/AR6002/hw4.0/hw/hw40_rtc_reg.h new file mode 100644 index 0000000000..48b100b6df --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/include/AR6002/hw4.0/hw/hw40_rtc_reg.h @@ -0,0 +1,968 @@ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== +#ifndef _RTC_REG_REG_H_ +#define _RTC_REG_REG_H_ + +#include "hw40_rtc_wlan_reg.h" + +#define RESET_CONTROL_ADDRESS WLAN_RESET_CONTROL_ADDRESS +#define RESET_CONTROL_OFFSET WLAN_RESET_CONTROL_OFFSET +#define RESET_CONTROL_DEBUG_UART_RST_MSB WLAN_RESET_CONTROL_DEBUG_UART_RST_MSB +#define RESET_CONTROL_DEBUG_UART_RST_LSB WLAN_RESET_CONTROL_DEBUG_UART_RST_LSB +#define RESET_CONTROL_DEBUG_UART_RST_MASK WLAN_RESET_CONTROL_DEBUG_UART_RST_MASK +#define RESET_CONTROL_DEBUG_UART_RST_GET(x) WLAN_RESET_CONTROL_DEBUG_UART_RST_GET(x) +#define RESET_CONTROL_DEBUG_UART_RST_SET(x) WLAN_RESET_CONTROL_DEBUG_UART_RST_SET(x) +#define RESET_CONTROL_BB_COLD_RST_MSB WLAN_RESET_CONTROL_BB_COLD_RST_MSB +#define RESET_CONTROL_BB_COLD_RST_LSB WLAN_RESET_CONTROL_BB_COLD_RST_LSB +#define RESET_CONTROL_BB_COLD_RST_MASK WLAN_RESET_CONTROL_BB_COLD_RST_MASK +#define RESET_CONTROL_BB_COLD_RST_GET(x) WLAN_RESET_CONTROL_BB_COLD_RST_GET(x) +#define RESET_CONTROL_BB_COLD_RST_SET(x) WLAN_RESET_CONTROL_BB_COLD_RST_SET(x) +#define RESET_CONTROL_BB_WARM_RST_MSB WLAN_RESET_CONTROL_BB_WARM_RST_MSB +#define RESET_CONTROL_BB_WARM_RST_LSB WLAN_RESET_CONTROL_BB_WARM_RST_LSB +#define RESET_CONTROL_BB_WARM_RST_MASK WLAN_RESET_CONTROL_BB_WARM_RST_MASK +#define RESET_CONTROL_BB_WARM_RST_GET(x) WLAN_RESET_CONTROL_BB_WARM_RST_GET(x) +#define RESET_CONTROL_BB_WARM_RST_SET(x) WLAN_RESET_CONTROL_BB_WARM_RST_SET(x) +#define RESET_CONTROL_CPU_INIT_RESET_MSB WLAN_RESET_CONTROL_CPU_INIT_RESET_MSB +#define RESET_CONTROL_CPU_INIT_RESET_LSB WLAN_RESET_CONTROL_CPU_INIT_RESET_LSB +#define RESET_CONTROL_CPU_INIT_RESET_MASK WLAN_RESET_CONTROL_CPU_INIT_RESET_MASK +#define RESET_CONTROL_CPU_INIT_RESET_GET(x) WLAN_RESET_CONTROL_CPU_INIT_RESET_GET(x) +#define RESET_CONTROL_CPU_INIT_RESET_SET(x) WLAN_RESET_CONTROL_CPU_INIT_RESET_SET(x) +#define RESET_CONTROL_VMC_REMAP_RESET_MSB WLAN_RESET_CONTROL_VMC_REMAP_RESET_MSB +#define RESET_CONTROL_VMC_REMAP_RESET_LSB WLAN_RESET_CONTROL_VMC_REMAP_RESET_LSB +#define RESET_CONTROL_VMC_REMAP_RESET_MASK WLAN_RESET_CONTROL_VMC_REMAP_RESET_MASK +#define RESET_CONTROL_VMC_REMAP_RESET_GET(x) WLAN_RESET_CONTROL_VMC_REMAP_RESET_GET(x) +#define RESET_CONTROL_VMC_REMAP_RESET_SET(x) WLAN_RESET_CONTROL_VMC_REMAP_RESET_SET(x) +#define RESET_CONTROL_RST_OUT_MSB WLAN_RESET_CONTROL_RST_OUT_MSB +#define RESET_CONTROL_RST_OUT_LSB WLAN_RESET_CONTROL_RST_OUT_LSB +#define RESET_CONTROL_RST_OUT_MASK WLAN_RESET_CONTROL_RST_OUT_MASK +#define RESET_CONTROL_RST_OUT_GET(x) WLAN_RESET_CONTROL_RST_OUT_GET(x) +#define RESET_CONTROL_RST_OUT_SET(x) WLAN_RESET_CONTROL_RST_OUT_SET(x) +#define RESET_CONTROL_COLD_RST_MSB WLAN_RESET_CONTROL_COLD_RST_MSB +#define RESET_CONTROL_COLD_RST_LSB WLAN_RESET_CONTROL_COLD_RST_LSB +#define RESET_CONTROL_COLD_RST_MASK WLAN_RESET_CONTROL_COLD_RST_MASK +#define RESET_CONTROL_COLD_RST_GET(x) WLAN_RESET_CONTROL_COLD_RST_GET(x) +#define RESET_CONTROL_COLD_RST_SET(x) WLAN_RESET_CONTROL_COLD_RST_SET(x) +#define RESET_CONTROL_WARM_RST_MSB WLAN_RESET_CONTROL_WARM_RST_MSB +#define RESET_CONTROL_WARM_RST_LSB WLAN_RESET_CONTROL_WARM_RST_LSB +#define RESET_CONTROL_WARM_RST_MASK WLAN_RESET_CONTROL_WARM_RST_MASK +#define RESET_CONTROL_WARM_RST_GET(x) WLAN_RESET_CONTROL_WARM_RST_GET(x) +#define RESET_CONTROL_WARM_RST_SET(x) WLAN_RESET_CONTROL_WARM_RST_SET(x) +#define RESET_CONTROL_CPU_WARM_RST_MSB WLAN_RESET_CONTROL_CPU_WARM_RST_MSB +#define RESET_CONTROL_CPU_WARM_RST_LSB WLAN_RESET_CONTROL_CPU_WARM_RST_LSB +#define RESET_CONTROL_CPU_WARM_RST_MASK WLAN_RESET_CONTROL_CPU_WARM_RST_MASK +#define RESET_CONTROL_CPU_WARM_RST_GET(x) WLAN_RESET_CONTROL_CPU_WARM_RST_GET(x) +#define RESET_CONTROL_CPU_WARM_RST_SET(x) WLAN_RESET_CONTROL_CPU_WARM_RST_SET(x) +#define RESET_CONTROL_MAC_COLD_RST_MSB WLAN_RESET_CONTROL_MAC_COLD_RST_MSB +#define RESET_CONTROL_MAC_COLD_RST_LSB WLAN_RESET_CONTROL_MAC_COLD_RST_LSB +#define RESET_CONTROL_MAC_COLD_RST_MASK WLAN_RESET_CONTROL_MAC_COLD_RST_MASK +#define RESET_CONTROL_MAC_COLD_RST_GET(x) WLAN_RESET_CONTROL_MAC_COLD_RST_GET(x) +#define RESET_CONTROL_MAC_COLD_RST_SET(x) WLAN_RESET_CONTROL_MAC_COLD_RST_SET(x) +#define RESET_CONTROL_MAC_WARM_RST_MSB WLAN_RESET_CONTROL_MAC_WARM_RST_MSB +#define RESET_CONTROL_MAC_WARM_RST_LSB WLAN_RESET_CONTROL_MAC_WARM_RST_LSB +#define RESET_CONTROL_MAC_WARM_RST_MASK WLAN_RESET_CONTROL_MAC_WARM_RST_MASK +#define RESET_CONTROL_MAC_WARM_RST_GET(x) WLAN_RESET_CONTROL_MAC_WARM_RST_GET(x) +#define RESET_CONTROL_MAC_WARM_RST_SET(x) WLAN_RESET_CONTROL_MAC_WARM_RST_SET(x) +#define RESET_CONTROL_MBOX_RST_MSB WLAN_RESET_CONTROL_MBOX_RST_MSB +#define RESET_CONTROL_MBOX_RST_LSB WLAN_RESET_CONTROL_MBOX_RST_LSB +#define RESET_CONTROL_MBOX_RST_MASK WLAN_RESET_CONTROL_MBOX_RST_MASK +#define RESET_CONTROL_MBOX_RST_GET(x) WLAN_RESET_CONTROL_MBOX_RST_GET(x) +#define RESET_CONTROL_MBOX_RST_SET(x) WLAN_RESET_CONTROL_MBOX_RST_SET(x) +#define RESET_CONTROL_UART_RST_MSB WLAN_RESET_CONTROL_UART_RST_MSB +#define RESET_CONTROL_UART_RST_LSB WLAN_RESET_CONTROL_UART_RST_LSB +#define RESET_CONTROL_UART_RST_MASK WLAN_RESET_CONTROL_UART_RST_MASK +#define RESET_CONTROL_UART_RST_GET(x) WLAN_RESET_CONTROL_UART_RST_GET(x) +#define RESET_CONTROL_UART_RST_SET(x) WLAN_RESET_CONTROL_UART_RST_SET(x) +#define RESET_CONTROL_SI0_RST_MSB WLAN_RESET_CONTROL_SI0_RST_MSB +#define RESET_CONTROL_SI0_RST_LSB WLAN_RESET_CONTROL_SI0_RST_LSB +#define RESET_CONTROL_SI0_RST_MASK WLAN_RESET_CONTROL_SI0_RST_MASK +#define RESET_CONTROL_SI0_RST_GET(x) WLAN_RESET_CONTROL_SI0_RST_GET(x) +#define RESET_CONTROL_SI0_RST_SET(x) WLAN_RESET_CONTROL_SI0_RST_SET(x) +#define XTAL_CONTROL_ADDRESS WLAN_XTAL_CONTROL_ADDRESS +#define XTAL_CONTROL_OFFSET WLAN_XTAL_CONTROL_OFFSET +#define XTAL_CONTROL_TCXO_MSB WLAN_XTAL_CONTROL_TCXO_MSB +#define XTAL_CONTROL_TCXO_LSB WLAN_XTAL_CONTROL_TCXO_LSB +#define XTAL_CONTROL_TCXO_MASK WLAN_XTAL_CONTROL_TCXO_MASK +#define XTAL_CONTROL_TCXO_GET(x) WLAN_XTAL_CONTROL_TCXO_GET(x) +#define XTAL_CONTROL_TCXO_SET(x) WLAN_XTAL_CONTROL_TCXO_SET(x) +#define TCXO_DETECT_ADDRESS WLAN_TCXO_DETECT_ADDRESS +#define TCXO_DETECT_OFFSET WLAN_TCXO_DETECT_OFFSET +#define TCXO_DETECT_PRESENT_MSB WLAN_TCXO_DETECT_PRESENT_MSB +#define TCXO_DETECT_PRESENT_LSB WLAN_TCXO_DETECT_PRESENT_LSB +#define TCXO_DETECT_PRESENT_MASK WLAN_TCXO_DETECT_PRESENT_MASK +#define TCXO_DETECT_PRESENT_GET(x) WLAN_TCXO_DETECT_PRESENT_GET(x) +#define TCXO_DETECT_PRESENT_SET(x) WLAN_TCXO_DETECT_PRESENT_SET(x) +#define XTAL_TEST_ADDRESS WLAN_XTAL_TEST_ADDRESS +#define XTAL_TEST_OFFSET WLAN_XTAL_TEST_OFFSET +#define XTAL_TEST_NOTCXODET_MSB WLAN_XTAL_TEST_NOTCXODET_MSB +#define XTAL_TEST_NOTCXODET_LSB WLAN_XTAL_TEST_NOTCXODET_LSB +#define XTAL_TEST_NOTCXODET_MASK WLAN_XTAL_TEST_NOTCXODET_MASK +#define XTAL_TEST_NOTCXODET_GET(x) WLAN_XTAL_TEST_NOTCXODET_GET(x) +#define XTAL_TEST_NOTCXODET_SET(x) WLAN_XTAL_TEST_NOTCXODET_SET(x) +#define QUADRATURE_ADDRESS WLAN_QUADRATURE_ADDRESS +#define QUADRATURE_OFFSET WLAN_QUADRATURE_OFFSET +#define QUADRATURE_ADC_MSB WLAN_QUADRATURE_ADC_MSB +#define QUADRATURE_ADC_LSB WLAN_QUADRATURE_ADC_LSB +#define QUADRATURE_ADC_MASK WLAN_QUADRATURE_ADC_MASK +#define QUADRATURE_ADC_GET(x) WLAN_QUADRATURE_ADC_GET(x) +#define QUADRATURE_ADC_SET(x) WLAN_QUADRATURE_ADC_SET(x) +#define QUADRATURE_SEL_MSB WLAN_QUADRATURE_SEL_MSB +#define QUADRATURE_SEL_LSB WLAN_QUADRATURE_SEL_LSB +#define QUADRATURE_SEL_MASK WLAN_QUADRATURE_SEL_MASK +#define QUADRATURE_SEL_GET(x) WLAN_QUADRATURE_SEL_GET(x) +#define QUADRATURE_SEL_SET(x) WLAN_QUADRATURE_SEL_SET(x) +#define QUADRATURE_DAC_MSB WLAN_QUADRATURE_DAC_MSB +#define QUADRATURE_DAC_LSB WLAN_QUADRATURE_DAC_LSB +#define QUADRATURE_DAC_MASK WLAN_QUADRATURE_DAC_MASK +#define QUADRATURE_DAC_GET(x) WLAN_QUADRATURE_DAC_GET(x) +#define QUADRATURE_DAC_SET(x) WLAN_QUADRATURE_DAC_SET(x) +#define PLL_CONTROL_ADDRESS WLAN_PLL_CONTROL_ADDRESS +#define PLL_CONTROL_OFFSET WLAN_PLL_CONTROL_OFFSET +#define PLL_CONTROL_DIG_TEST_CLK_MSB WLAN_PLL_CONTROL_DIG_TEST_CLK_MSB +#define PLL_CONTROL_DIG_TEST_CLK_LSB WLAN_PLL_CONTROL_DIG_TEST_CLK_LSB +#define PLL_CONTROL_DIG_TEST_CLK_MASK WLAN_PLL_CONTROL_DIG_TEST_CLK_MASK +#define PLL_CONTROL_DIG_TEST_CLK_GET(x) WLAN_PLL_CONTROL_DIG_TEST_CLK_GET(x) +#define PLL_CONTROL_DIG_TEST_CLK_SET(x) WLAN_PLL_CONTROL_DIG_TEST_CLK_SET(x) +#define PLL_CONTROL_MAC_OVERRIDE_MSB WLAN_PLL_CONTROL_MAC_OVERRIDE_MSB +#define PLL_CONTROL_MAC_OVERRIDE_LSB WLAN_PLL_CONTROL_MAC_OVERRIDE_LSB +#define PLL_CONTROL_MAC_OVERRIDE_MASK WLAN_PLL_CONTROL_MAC_OVERRIDE_MASK +#define PLL_CONTROL_MAC_OVERRIDE_GET(x) WLAN_PLL_CONTROL_MAC_OVERRIDE_GET(x) +#define PLL_CONTROL_MAC_OVERRIDE_SET(x) WLAN_PLL_CONTROL_MAC_OVERRIDE_SET(x) +#define PLL_CONTROL_NOPWD_MSB WLAN_PLL_CONTROL_NOPWD_MSB +#define PLL_CONTROL_NOPWD_LSB WLAN_PLL_CONTROL_NOPWD_LSB +#define PLL_CONTROL_NOPWD_MASK WLAN_PLL_CONTROL_NOPWD_MASK +#define PLL_CONTROL_NOPWD_GET(x) WLAN_PLL_CONTROL_NOPWD_GET(x) +#define PLL_CONTROL_NOPWD_SET(x) WLAN_PLL_CONTROL_NOPWD_SET(x) +#define PLL_CONTROL_UPDATING_MSB WLAN_PLL_CONTROL_UPDATING_MSB +#define PLL_CONTROL_UPDATING_LSB WLAN_PLL_CONTROL_UPDATING_LSB +#define PLL_CONTROL_UPDATING_MASK WLAN_PLL_CONTROL_UPDATING_MASK +#define PLL_CONTROL_UPDATING_GET(x) WLAN_PLL_CONTROL_UPDATING_GET(x) +#define PLL_CONTROL_UPDATING_SET(x) WLAN_PLL_CONTROL_UPDATING_SET(x) +#define PLL_CONTROL_BYPASS_MSB WLAN_PLL_CONTROL_BYPASS_MSB +#define PLL_CONTROL_BYPASS_LSB WLAN_PLL_CONTROL_BYPASS_LSB +#define PLL_CONTROL_BYPASS_MASK WLAN_PLL_CONTROL_BYPASS_MASK +#define PLL_CONTROL_BYPASS_GET(x) WLAN_PLL_CONTROL_BYPASS_GET(x) +#define PLL_CONTROL_BYPASS_SET(x) WLAN_PLL_CONTROL_BYPASS_SET(x) +#define PLL_CONTROL_REFDIV_MSB WLAN_PLL_CONTROL_REFDIV_MSB +#define PLL_CONTROL_REFDIV_LSB WLAN_PLL_CONTROL_REFDIV_LSB +#define PLL_CONTROL_REFDIV_MASK WLAN_PLL_CONTROL_REFDIV_MASK +#define PLL_CONTROL_REFDIV_GET(x) WLAN_PLL_CONTROL_REFDIV_GET(x) +#define PLL_CONTROL_REFDIV_SET(x) WLAN_PLL_CONTROL_REFDIV_SET(x) +#define PLL_CONTROL_DIV_MSB WLAN_PLL_CONTROL_DIV_MSB +#define PLL_CONTROL_DIV_LSB WLAN_PLL_CONTROL_DIV_LSB +#define PLL_CONTROL_DIV_MASK WLAN_PLL_CONTROL_DIV_MASK +#define PLL_CONTROL_DIV_GET(x) WLAN_PLL_CONTROL_DIV_GET(x) +#define PLL_CONTROL_DIV_SET(x) WLAN_PLL_CONTROL_DIV_SET(x) +#define PLL_SETTLE_ADDRESS WLAN_PLL_SETTLE_ADDRESS +#define PLL_SETTLE_OFFSET WLAN_PLL_SETTLE_OFFSET +#define PLL_SETTLE_TIME_MSB WLAN_PLL_SETTLE_TIME_MSB +#define PLL_SETTLE_TIME_LSB WLAN_PLL_SETTLE_TIME_LSB +#define PLL_SETTLE_TIME_MASK WLAN_PLL_SETTLE_TIME_MASK +#define PLL_SETTLE_TIME_GET(x) WLAN_PLL_SETTLE_TIME_GET(x) +#define PLL_SETTLE_TIME_SET(x) WLAN_PLL_SETTLE_TIME_SET(x) +#define XTAL_SETTLE_ADDRESS WLAN_XTAL_SETTLE_ADDRESS +#define XTAL_SETTLE_OFFSET WLAN_XTAL_SETTLE_OFFSET +#define XTAL_SETTLE_TIME_MSB WLAN_XTAL_SETTLE_TIME_MSB +#define XTAL_SETTLE_TIME_LSB WLAN_XTAL_SETTLE_TIME_LSB +#define XTAL_SETTLE_TIME_MASK WLAN_XTAL_SETTLE_TIME_MASK +#define XTAL_SETTLE_TIME_GET(x) WLAN_XTAL_SETTLE_TIME_GET(x) +#define XTAL_SETTLE_TIME_SET(x) WLAN_XTAL_SETTLE_TIME_SET(x) +#define CPU_CLOCK_ADDRESS WLAN_CPU_CLOCK_ADDRESS +#define CPU_CLOCK_OFFSET WLAN_CPU_CLOCK_OFFSET +#define CPU_CLOCK_STANDARD_MSB WLAN_CPU_CLOCK_STANDARD_MSB +#define CPU_CLOCK_STANDARD_LSB WLAN_CPU_CLOCK_STANDARD_LSB +#define CPU_CLOCK_STANDARD_MASK WLAN_CPU_CLOCK_STANDARD_MASK +#define CPU_CLOCK_STANDARD_GET(x) WLAN_CPU_CLOCK_STANDARD_GET(x) +#define CPU_CLOCK_STANDARD_SET(x) WLAN_CPU_CLOCK_STANDARD_SET(x) +#define CLOCK_OUT_ADDRESS WLAN_CLOCK_OUT_ADDRESS +#define CLOCK_OUT_OFFSET WLAN_CLOCK_OUT_OFFSET +#define CLOCK_OUT_SELECT_MSB WLAN_CLOCK_OUT_SELECT_MSB +#define CLOCK_OUT_SELECT_LSB WLAN_CLOCK_OUT_SELECT_LSB +#define CLOCK_OUT_SELECT_MASK WLAN_CLOCK_OUT_SELECT_MASK +#define CLOCK_OUT_SELECT_GET(x) WLAN_CLOCK_OUT_SELECT_GET(x) +#define CLOCK_OUT_SELECT_SET(x) WLAN_CLOCK_OUT_SELECT_SET(x) +#define CLOCK_CONTROL_ADDRESS WLAN_CLOCK_CONTROL_ADDRESS +#define CLOCK_CONTROL_OFFSET WLAN_CLOCK_CONTROL_OFFSET +#define CLOCK_CONTROL_LF_CLK32_MSB WLAN_CLOCK_CONTROL_LF_CLK32_MSB +#define CLOCK_CONTROL_LF_CLK32_LSB WLAN_CLOCK_CONTROL_LF_CLK32_LSB +#define CLOCK_CONTROL_LF_CLK32_MASK WLAN_CLOCK_CONTROL_LF_CLK32_MASK +#define CLOCK_CONTROL_LF_CLK32_GET(x) WLAN_CLOCK_CONTROL_LF_CLK32_GET(x) +#define CLOCK_CONTROL_LF_CLK32_SET(x) WLAN_CLOCK_CONTROL_LF_CLK32_SET(x) +#define CLOCK_CONTROL_SI0_CLK_MSB WLAN_CLOCK_CONTROL_SI0_CLK_MSB +#define CLOCK_CONTROL_SI0_CLK_LSB WLAN_CLOCK_CONTROL_SI0_CLK_LSB +#define CLOCK_CONTROL_SI0_CLK_MASK WLAN_CLOCK_CONTROL_SI0_CLK_MASK +#define CLOCK_CONTROL_SI0_CLK_GET(x) WLAN_CLOCK_CONTROL_SI0_CLK_GET(x) +#define CLOCK_CONTROL_SI0_CLK_SET(x) WLAN_CLOCK_CONTROL_SI0_CLK_SET(x) +#define BIAS_OVERRIDE_ADDRESS WLAN_BIAS_OVERRIDE_ADDRESS +#define BIAS_OVERRIDE_OFFSET WLAN_BIAS_OVERRIDE_OFFSET +#define BIAS_OVERRIDE_ON_MSB WLAN_BIAS_OVERRIDE_ON_MSB +#define BIAS_OVERRIDE_ON_LSB WLAN_BIAS_OVERRIDE_ON_LSB +#define BIAS_OVERRIDE_ON_MASK WLAN_BIAS_OVERRIDE_ON_MASK +#define BIAS_OVERRIDE_ON_GET(x) WLAN_BIAS_OVERRIDE_ON_GET(x) +#define BIAS_OVERRIDE_ON_SET(x) WLAN_BIAS_OVERRIDE_ON_SET(x) +#define WDT_CONTROL_ADDRESS WLAN_WDT_CONTROL_ADDRESS +#define WDT_CONTROL_OFFSET WLAN_WDT_CONTROL_OFFSET +#define WDT_CONTROL_ACTION_MSB WLAN_WDT_CONTROL_ACTION_MSB +#define WDT_CONTROL_ACTION_LSB WLAN_WDT_CONTROL_ACTION_LSB +#define WDT_CONTROL_ACTION_MASK WLAN_WDT_CONTROL_ACTION_MASK +#define WDT_CONTROL_ACTION_GET(x) WLAN_WDT_CONTROL_ACTION_GET(x) +#define WDT_CONTROL_ACTION_SET(x) WLAN_WDT_CONTROL_ACTION_SET(x) +#define WDT_STATUS_ADDRESS WLAN_WDT_STATUS_ADDRESS +#define WDT_STATUS_OFFSET WLAN_WDT_STATUS_OFFSET +#define WDT_STATUS_INTERRUPT_MSB WLAN_WDT_STATUS_INTERRUPT_MSB +#define WDT_STATUS_INTERRUPT_LSB WLAN_WDT_STATUS_INTERRUPT_LSB +#define WDT_STATUS_INTERRUPT_MASK WLAN_WDT_STATUS_INTERRUPT_MASK +#define WDT_STATUS_INTERRUPT_GET(x) WLAN_WDT_STATUS_INTERRUPT_GET(x) +#define WDT_STATUS_INTERRUPT_SET(x) WLAN_WDT_STATUS_INTERRUPT_SET(x) +#define WDT_ADDRESS WLAN_WDT_ADDRESS +#define WDT_OFFSET WLAN_WDT_OFFSET +#define WDT_TARGET_MSB WLAN_WDT_TARGET_MSB +#define WDT_TARGET_LSB WLAN_WDT_TARGET_LSB +#define WDT_TARGET_MASK WLAN_WDT_TARGET_MASK +#define WDT_TARGET_GET(x) WLAN_WDT_TARGET_GET(x) +#define WDT_TARGET_SET(x) WLAN_WDT_TARGET_SET(x) +#define WDT_COUNT_ADDRESS WLAN_WDT_COUNT_ADDRESS +#define WDT_COUNT_OFFSET WLAN_WDT_COUNT_OFFSET +#define WDT_COUNT_VALUE_MSB WLAN_WDT_COUNT_VALUE_MSB +#define WDT_COUNT_VALUE_LSB WLAN_WDT_COUNT_VALUE_LSB +#define WDT_COUNT_VALUE_MASK WLAN_WDT_COUNT_VALUE_MASK +#define WDT_COUNT_VALUE_GET(x) WLAN_WDT_COUNT_VALUE_GET(x) +#define WDT_COUNT_VALUE_SET(x) WLAN_WDT_COUNT_VALUE_SET(x) +#define WDT_RESET_ADDRESS WLAN_WDT_RESET_ADDRESS +#define WDT_RESET_OFFSET WLAN_WDT_RESET_OFFSET +#define WDT_RESET_VALUE_MSB WLAN_WDT_RESET_VALUE_MSB +#define WDT_RESET_VALUE_LSB WLAN_WDT_RESET_VALUE_LSB +#define WDT_RESET_VALUE_MASK WLAN_WDT_RESET_VALUE_MASK +#define WDT_RESET_VALUE_GET(x) WLAN_WDT_RESET_VALUE_GET(x) +#define WDT_RESET_VALUE_SET(x) WLAN_WDT_RESET_VALUE_SET(x) +#define INT_STATUS_ADDRESS WLAN_INT_STATUS_ADDRESS +#define INT_STATUS_OFFSET WLAN_INT_STATUS_OFFSET +#define INT_STATUS_HCI_UART_MSB WLAN_INT_STATUS_HCI_UART_MSB +#define INT_STATUS_HCI_UART_LSB WLAN_INT_STATUS_HCI_UART_LSB +#define INT_STATUS_HCI_UART_MASK WLAN_INT_STATUS_HCI_UART_MASK +#define INT_STATUS_HCI_UART_GET(x) WLAN_INT_STATUS_HCI_UART_GET(x) +#define INT_STATUS_HCI_UART_SET(x) WLAN_INT_STATUS_HCI_UART_SET(x) +#define INT_STATUS_THERM_MSB WLAN_INT_STATUS_THERM_MSB +#define INT_STATUS_THERM_LSB WLAN_INT_STATUS_THERM_LSB +#define INT_STATUS_THERM_MASK WLAN_INT_STATUS_THERM_MASK +#define INT_STATUS_THERM_GET(x) WLAN_INT_STATUS_THERM_GET(x) +#define INT_STATUS_THERM_SET(x) WLAN_INT_STATUS_THERM_SET(x) +#define INT_STATUS_EFUSE_OVERWRITE_MSB WLAN_INT_STATUS_EFUSE_OVERWRITE_MSB +#define INT_STATUS_EFUSE_OVERWRITE_LSB WLAN_INT_STATUS_EFUSE_OVERWRITE_LSB +#define INT_STATUS_EFUSE_OVERWRITE_MASK WLAN_INT_STATUS_EFUSE_OVERWRITE_MASK +#define INT_STATUS_EFUSE_OVERWRITE_GET(x) WLAN_INT_STATUS_EFUSE_OVERWRITE_GET(x) +#define INT_STATUS_EFUSE_OVERWRITE_SET(x) WLAN_INT_STATUS_EFUSE_OVERWRITE_SET(x) +#define INT_STATUS_UART_MBOX_MSB WLAN_INT_STATUS_UART_MBOX_MSB +#define INT_STATUS_UART_MBOX_LSB WLAN_INT_STATUS_UART_MBOX_LSB +#define INT_STATUS_UART_MBOX_MASK WLAN_INT_STATUS_UART_MBOX_MASK +#define INT_STATUS_UART_MBOX_GET(x) WLAN_INT_STATUS_UART_MBOX_GET(x) +#define INT_STATUS_UART_MBOX_SET(x) WLAN_INT_STATUS_UART_MBOX_SET(x) +#define INT_STATUS_GENERIC_MBOX_MSB WLAN_INT_STATUS_GENERIC_MBOX_MSB +#define INT_STATUS_GENERIC_MBOX_LSB WLAN_INT_STATUS_GENERIC_MBOX_LSB +#define INT_STATUS_GENERIC_MBOX_MASK WLAN_INT_STATUS_GENERIC_MBOX_MASK +#define INT_STATUS_GENERIC_MBOX_GET(x) WLAN_INT_STATUS_GENERIC_MBOX_GET(x) +#define INT_STATUS_GENERIC_MBOX_SET(x) WLAN_INT_STATUS_GENERIC_MBOX_SET(x) +#define INT_STATUS_RDMA_MSB WLAN_INT_STATUS_RDMA_MSB +#define INT_STATUS_RDMA_LSB WLAN_INT_STATUS_RDMA_LSB +#define INT_STATUS_RDMA_MASK WLAN_INT_STATUS_RDMA_MASK +#define INT_STATUS_RDMA_GET(x) WLAN_INT_STATUS_RDMA_GET(x) +#define INT_STATUS_RDMA_SET(x) WLAN_INT_STATUS_RDMA_SET(x) +#define INT_STATUS_BTCOEX_MSB WLAN_INT_STATUS_BTCOEX_MSB +#define INT_STATUS_BTCOEX_LSB WLAN_INT_STATUS_BTCOEX_LSB +#define INT_STATUS_BTCOEX_MASK WLAN_INT_STATUS_BTCOEX_MASK +#define INT_STATUS_BTCOEX_GET(x) WLAN_INT_STATUS_BTCOEX_GET(x) +#define INT_STATUS_BTCOEX_SET(x) WLAN_INT_STATUS_BTCOEX_SET(x) +#define INT_STATUS_RTC_POWER_MSB WLAN_INT_STATUS_RTC_POWER_MSB +#define INT_STATUS_RTC_POWER_LSB WLAN_INT_STATUS_RTC_POWER_LSB +#define INT_STATUS_RTC_POWER_MASK WLAN_INT_STATUS_RTC_POWER_MASK +#define INT_STATUS_RTC_POWER_GET(x) WLAN_INT_STATUS_RTC_POWER_GET(x) +#define INT_STATUS_RTC_POWER_SET(x) WLAN_INT_STATUS_RTC_POWER_SET(x) +#define INT_STATUS_MAC_MSB WLAN_INT_STATUS_MAC_MSB +#define INT_STATUS_MAC_LSB WLAN_INT_STATUS_MAC_LSB +#define INT_STATUS_MAC_MASK WLAN_INT_STATUS_MAC_MASK +#define INT_STATUS_MAC_GET(x) WLAN_INT_STATUS_MAC_GET(x) +#define INT_STATUS_MAC_SET(x) WLAN_INT_STATUS_MAC_SET(x) +#define INT_STATUS_MAILBOX_MSB WLAN_INT_STATUS_MAILBOX_MSB +#define INT_STATUS_MAILBOX_LSB WLAN_INT_STATUS_MAILBOX_LSB +#define INT_STATUS_MAILBOX_MASK WLAN_INT_STATUS_MAILBOX_MASK +#define INT_STATUS_MAILBOX_GET(x) WLAN_INT_STATUS_MAILBOX_GET(x) +#define INT_STATUS_MAILBOX_SET(x) WLAN_INT_STATUS_MAILBOX_SET(x) +#define INT_STATUS_RTC_ALARM_MSB WLAN_INT_STATUS_RTC_ALARM_MSB +#define INT_STATUS_RTC_ALARM_LSB WLAN_INT_STATUS_RTC_ALARM_LSB +#define INT_STATUS_RTC_ALARM_MASK WLAN_INT_STATUS_RTC_ALARM_MASK +#define INT_STATUS_RTC_ALARM_GET(x) WLAN_INT_STATUS_RTC_ALARM_GET(x) +#define INT_STATUS_RTC_ALARM_SET(x) WLAN_INT_STATUS_RTC_ALARM_SET(x) +#define INT_STATUS_HF_TIMER_MSB WLAN_INT_STATUS_HF_TIMER_MSB +#define INT_STATUS_HF_TIMER_LSB WLAN_INT_STATUS_HF_TIMER_LSB +#define INT_STATUS_HF_TIMER_MASK WLAN_INT_STATUS_HF_TIMER_MASK +#define INT_STATUS_HF_TIMER_GET(x) WLAN_INT_STATUS_HF_TIMER_GET(x) +#define INT_STATUS_HF_TIMER_SET(x) WLAN_INT_STATUS_HF_TIMER_SET(x) +#define INT_STATUS_LF_TIMER3_MSB WLAN_INT_STATUS_LF_TIMER3_MSB +#define INT_STATUS_LF_TIMER3_LSB WLAN_INT_STATUS_LF_TIMER3_LSB +#define INT_STATUS_LF_TIMER3_MASK WLAN_INT_STATUS_LF_TIMER3_MASK +#define INT_STATUS_LF_TIMER3_GET(x) WLAN_INT_STATUS_LF_TIMER3_GET(x) +#define INT_STATUS_LF_TIMER3_SET(x) WLAN_INT_STATUS_LF_TIMER3_SET(x) +#define INT_STATUS_LF_TIMER2_MSB WLAN_INT_STATUS_LF_TIMER2_MSB +#define INT_STATUS_LF_TIMER2_LSB WLAN_INT_STATUS_LF_TIMER2_LSB +#define INT_STATUS_LF_TIMER2_MASK WLAN_INT_STATUS_LF_TIMER2_MASK +#define INT_STATUS_LF_TIMER2_GET(x) WLAN_INT_STATUS_LF_TIMER2_GET(x) +#define INT_STATUS_LF_TIMER2_SET(x) WLAN_INT_STATUS_LF_TIMER2_SET(x) +#define INT_STATUS_LF_TIMER1_MSB WLAN_INT_STATUS_LF_TIMER1_MSB +#define INT_STATUS_LF_TIMER1_LSB WLAN_INT_STATUS_LF_TIMER1_LSB +#define INT_STATUS_LF_TIMER1_MASK WLAN_INT_STATUS_LF_TIMER1_MASK +#define INT_STATUS_LF_TIMER1_GET(x) WLAN_INT_STATUS_LF_TIMER1_GET(x) +#define INT_STATUS_LF_TIMER1_SET(x) WLAN_INT_STATUS_LF_TIMER1_SET(x) +#define INT_STATUS_LF_TIMER0_MSB WLAN_INT_STATUS_LF_TIMER0_MSB +#define INT_STATUS_LF_TIMER0_LSB WLAN_INT_STATUS_LF_TIMER0_LSB +#define INT_STATUS_LF_TIMER0_MASK WLAN_INT_STATUS_LF_TIMER0_MASK +#define INT_STATUS_LF_TIMER0_GET(x) WLAN_INT_STATUS_LF_TIMER0_GET(x) +#define INT_STATUS_LF_TIMER0_SET(x) WLAN_INT_STATUS_LF_TIMER0_SET(x) +#define INT_STATUS_KEYPAD_MSB WLAN_INT_STATUS_KEYPAD_MSB +#define INT_STATUS_KEYPAD_LSB WLAN_INT_STATUS_KEYPAD_LSB +#define INT_STATUS_KEYPAD_MASK WLAN_INT_STATUS_KEYPAD_MASK +#define INT_STATUS_KEYPAD_GET(x) WLAN_INT_STATUS_KEYPAD_GET(x) +#define INT_STATUS_KEYPAD_SET(x) WLAN_INT_STATUS_KEYPAD_SET(x) +#define INT_STATUS_SI_MSB WLAN_INT_STATUS_SI_MSB +#define INT_STATUS_SI_LSB WLAN_INT_STATUS_SI_LSB +#define INT_STATUS_SI_MASK WLAN_INT_STATUS_SI_MASK +#define INT_STATUS_SI_GET(x) WLAN_INT_STATUS_SI_GET(x) +#define INT_STATUS_SI_SET(x) WLAN_INT_STATUS_SI_SET(x) +#define INT_STATUS_GPIO_MSB WLAN_INT_STATUS_GPIO_MSB +#define INT_STATUS_GPIO_LSB WLAN_INT_STATUS_GPIO_LSB +#define INT_STATUS_GPIO_MASK WLAN_INT_STATUS_GPIO_MASK +#define INT_STATUS_GPIO_GET(x) WLAN_INT_STATUS_GPIO_GET(x) +#define INT_STATUS_GPIO_SET(x) WLAN_INT_STATUS_GPIO_SET(x) +#define INT_STATUS_UART_MSB WLAN_INT_STATUS_UART_MSB +#define INT_STATUS_UART_LSB WLAN_INT_STATUS_UART_LSB +#define INT_STATUS_UART_MASK WLAN_INT_STATUS_UART_MASK +#define INT_STATUS_UART_GET(x) WLAN_INT_STATUS_UART_GET(x) +#define INT_STATUS_UART_SET(x) WLAN_INT_STATUS_UART_SET(x) +#define INT_STATUS_ERROR_MSB WLAN_INT_STATUS_ERROR_MSB +#define INT_STATUS_ERROR_LSB WLAN_INT_STATUS_ERROR_LSB +#define INT_STATUS_ERROR_MASK WLAN_INT_STATUS_ERROR_MASK +#define INT_STATUS_ERROR_GET(x) WLAN_INT_STATUS_ERROR_GET(x) +#define INT_STATUS_ERROR_SET(x) WLAN_INT_STATUS_ERROR_SET(x) +#define INT_STATUS_WDT_INT_MSB WLAN_INT_STATUS_WDT_INT_MSB +#define INT_STATUS_WDT_INT_LSB WLAN_INT_STATUS_WDT_INT_LSB +#define INT_STATUS_WDT_INT_MASK WLAN_INT_STATUS_WDT_INT_MASK +#define INT_STATUS_WDT_INT_GET(x) WLAN_INT_STATUS_WDT_INT_GET(x) +#define INT_STATUS_WDT_INT_SET(x) WLAN_INT_STATUS_WDT_INT_SET(x) +#define LF_TIMER0_ADDRESS WLAN_LF_TIMER0_ADDRESS +#define LF_TIMER0_OFFSET WLAN_LF_TIMER0_OFFSET +#define LF_TIMER0_TARGET_MSB WLAN_LF_TIMER0_TARGET_MSB +#define LF_TIMER0_TARGET_LSB WLAN_LF_TIMER0_TARGET_LSB +#define LF_TIMER0_TARGET_MASK WLAN_LF_TIMER0_TARGET_MASK +#define LF_TIMER0_TARGET_GET(x) WLAN_LF_TIMER0_TARGET_GET(x) +#define LF_TIMER0_TARGET_SET(x) WLAN_LF_TIMER0_TARGET_SET(x) +#define LF_TIMER_COUNT0_ADDRESS WLAN_LF_TIMER_COUNT0_ADDRESS +#define LF_TIMER_COUNT0_OFFSET WLAN_LF_TIMER_COUNT0_OFFSET +#define LF_TIMER_COUNT0_VALUE_MSB WLAN_LF_TIMER_COUNT0_VALUE_MSB +#define LF_TIMER_COUNT0_VALUE_LSB WLAN_LF_TIMER_COUNT0_VALUE_LSB +#define LF_TIMER_COUNT0_VALUE_MASK WLAN_LF_TIMER_COUNT0_VALUE_MASK +#define LF_TIMER_COUNT0_VALUE_GET(x) WLAN_LF_TIMER_COUNT0_VALUE_GET(x) +#define LF_TIMER_COUNT0_VALUE_SET(x) WLAN_LF_TIMER_COUNT0_VALUE_SET(x) +#define LF_TIMER_CONTROL0_ADDRESS WLAN_LF_TIMER_CONTROL0_ADDRESS +#define LF_TIMER_CONTROL0_OFFSET WLAN_LF_TIMER_CONTROL0_OFFSET +#define LF_TIMER_CONTROL0_ENABLE_MSB WLAN_LF_TIMER_CONTROL0_ENABLE_MSB +#define LF_TIMER_CONTROL0_ENABLE_LSB WLAN_LF_TIMER_CONTROL0_ENABLE_LSB +#define LF_TIMER_CONTROL0_ENABLE_MASK WLAN_LF_TIMER_CONTROL0_ENABLE_MASK +#define LF_TIMER_CONTROL0_ENABLE_GET(x) WLAN_LF_TIMER_CONTROL0_ENABLE_GET(x) +#define LF_TIMER_CONTROL0_ENABLE_SET(x) WLAN_LF_TIMER_CONTROL0_ENABLE_SET(x) +#define LF_TIMER_CONTROL0_AUTO_RESTART_MSB WLAN_LF_TIMER_CONTROL0_AUTO_RESTART_MSB +#define LF_TIMER_CONTROL0_AUTO_RESTART_LSB WLAN_LF_TIMER_CONTROL0_AUTO_RESTART_LSB +#define LF_TIMER_CONTROL0_AUTO_RESTART_MASK WLAN_LF_TIMER_CONTROL0_AUTO_RESTART_MASK +#define LF_TIMER_CONTROL0_AUTO_RESTART_GET(x) WLAN_LF_TIMER_CONTROL0_AUTO_RESTART_GET(x) +#define LF_TIMER_CONTROL0_AUTO_RESTART_SET(x) WLAN_LF_TIMER_CONTROL0_AUTO_RESTART_SET(x) +#define LF_TIMER_CONTROL0_RESET_MSB WLAN_LF_TIMER_CONTROL0_RESET_MSB +#define LF_TIMER_CONTROL0_RESET_LSB WLAN_LF_TIMER_CONTROL0_RESET_LSB +#define LF_TIMER_CONTROL0_RESET_MASK WLAN_LF_TIMER_CONTROL0_RESET_MASK +#define LF_TIMER_CONTROL0_RESET_GET(x) WLAN_LF_TIMER_CONTROL0_RESET_GET(x) +#define LF_TIMER_CONTROL0_RESET_SET(x) WLAN_LF_TIMER_CONTROL0_RESET_SET(x) +#define LF_TIMER_STATUS0_ADDRESS WLAN_LF_TIMER_STATUS0_ADDRESS +#define LF_TIMER_STATUS0_OFFSET WLAN_LF_TIMER_STATUS0_OFFSET +#define LF_TIMER_STATUS0_INTERRUPT_MSB WLAN_LF_TIMER_STATUS0_INTERRUPT_MSB +#define LF_TIMER_STATUS0_INTERRUPT_LSB WLAN_LF_TIMER_STATUS0_INTERRUPT_LSB +#define LF_TIMER_STATUS0_INTERRUPT_MASK WLAN_LF_TIMER_STATUS0_INTERRUPT_MASK +#define LF_TIMER_STATUS0_INTERRUPT_GET(x) WLAN_LF_TIMER_STATUS0_INTERRUPT_GET(x) +#define LF_TIMER_STATUS0_INTERRUPT_SET(x) WLAN_LF_TIMER_STATUS0_INTERRUPT_SET(x) +#define LF_TIMER1_ADDRESS WLAN_LF_TIMER1_ADDRESS +#define LF_TIMER1_OFFSET WLAN_LF_TIMER1_OFFSET +#define LF_TIMER1_TARGET_MSB WLAN_LF_TIMER1_TARGET_MSB +#define LF_TIMER1_TARGET_LSB WLAN_LF_TIMER1_TARGET_LSB +#define LF_TIMER1_TARGET_MASK WLAN_LF_TIMER1_TARGET_MASK +#define LF_TIMER1_TARGET_GET(x) WLAN_LF_TIMER1_TARGET_GET(x) +#define LF_TIMER1_TARGET_SET(x) WLAN_LF_TIMER1_TARGET_SET(x) +#define LF_TIMER_COUNT1_ADDRESS WLAN_LF_TIMER_COUNT1_ADDRESS +#define LF_TIMER_COUNT1_OFFSET WLAN_LF_TIMER_COUNT1_OFFSET +#define LF_TIMER_COUNT1_VALUE_MSB WLAN_LF_TIMER_COUNT1_VALUE_MSB +#define LF_TIMER_COUNT1_VALUE_LSB WLAN_LF_TIMER_COUNT1_VALUE_LSB +#define LF_TIMER_COUNT1_VALUE_MASK WLAN_LF_TIMER_COUNT1_VALUE_MASK +#define LF_TIMER_COUNT1_VALUE_GET(x) WLAN_LF_TIMER_COUNT1_VALUE_GET(x) +#define LF_TIMER_COUNT1_VALUE_SET(x) WLAN_LF_TIMER_COUNT1_VALUE_SET(x) +#define LF_TIMER_CONTROL1_ADDRESS WLAN_LF_TIMER_CONTROL1_ADDRESS +#define LF_TIMER_CONTROL1_OFFSET WLAN_LF_TIMER_CONTROL1_OFFSET +#define LF_TIMER_CONTROL1_ENABLE_MSB WLAN_LF_TIMER_CONTROL1_ENABLE_MSB +#define LF_TIMER_CONTROL1_ENABLE_LSB WLAN_LF_TIMER_CONTROL1_ENABLE_LSB +#define LF_TIMER_CONTROL1_ENABLE_MASK WLAN_LF_TIMER_CONTROL1_ENABLE_MASK +#define LF_TIMER_CONTROL1_ENABLE_GET(x) WLAN_LF_TIMER_CONTROL1_ENABLE_GET(x) +#define LF_TIMER_CONTROL1_ENABLE_SET(x) WLAN_LF_TIMER_CONTROL1_ENABLE_SET(x) +#define LF_TIMER_CONTROL1_AUTO_RESTART_MSB WLAN_LF_TIMER_CONTROL1_AUTO_RESTART_MSB +#define LF_TIMER_CONTROL1_AUTO_RESTART_LSB WLAN_LF_TIMER_CONTROL1_AUTO_RESTART_LSB +#define LF_TIMER_CONTROL1_AUTO_RESTART_MASK WLAN_LF_TIMER_CONTROL1_AUTO_RESTART_MASK +#define LF_TIMER_CONTROL1_AUTO_RESTART_GET(x) WLAN_LF_TIMER_CONTROL1_AUTO_RESTART_GET(x) +#define LF_TIMER_CONTROL1_AUTO_RESTART_SET(x) WLAN_LF_TIMER_CONTROL1_AUTO_RESTART_SET(x) +#define LF_TIMER_CONTROL1_RESET_MSB WLAN_LF_TIMER_CONTROL1_RESET_MSB +#define LF_TIMER_CONTROL1_RESET_LSB WLAN_LF_TIMER_CONTROL1_RESET_LSB +#define LF_TIMER_CONTROL1_RESET_MASK WLAN_LF_TIMER_CONTROL1_RESET_MASK +#define LF_TIMER_CONTROL1_RESET_GET(x) WLAN_LF_TIMER_CONTROL1_RESET_GET(x) +#define LF_TIMER_CONTROL1_RESET_SET(x) WLAN_LF_TIMER_CONTROL1_RESET_SET(x) +#define LF_TIMER_STATUS1_ADDRESS WLAN_LF_TIMER_STATUS1_ADDRESS +#define LF_TIMER_STATUS1_OFFSET WLAN_LF_TIMER_STATUS1_OFFSET +#define LF_TIMER_STATUS1_INTERRUPT_MSB WLAN_LF_TIMER_STATUS1_INTERRUPT_MSB +#define LF_TIMER_STATUS1_INTERRUPT_LSB WLAN_LF_TIMER_STATUS1_INTERRUPT_LSB +#define LF_TIMER_STATUS1_INTERRUPT_MASK WLAN_LF_TIMER_STATUS1_INTERRUPT_MASK +#define LF_TIMER_STATUS1_INTERRUPT_GET(x) WLAN_LF_TIMER_STATUS1_INTERRUPT_GET(x) +#define LF_TIMER_STATUS1_INTERRUPT_SET(x) WLAN_LF_TIMER_STATUS1_INTERRUPT_SET(x) +#define LF_TIMER2_ADDRESS WLAN_LF_TIMER2_ADDRESS +#define LF_TIMER2_OFFSET WLAN_LF_TIMER2_OFFSET +#define LF_TIMER2_TARGET_MSB WLAN_LF_TIMER2_TARGET_MSB +#define LF_TIMER2_TARGET_LSB WLAN_LF_TIMER2_TARGET_LSB +#define LF_TIMER2_TARGET_MASK WLAN_LF_TIMER2_TARGET_MASK +#define LF_TIMER2_TARGET_GET(x) WLAN_LF_TIMER2_TARGET_GET(x) +#define LF_TIMER2_TARGET_SET(x) WLAN_LF_TIMER2_TARGET_SET(x) +#define LF_TIMER_COUNT2_ADDRESS WLAN_LF_TIMER_COUNT2_ADDRESS +#define LF_TIMER_COUNT2_OFFSET WLAN_LF_TIMER_COUNT2_OFFSET +#define LF_TIMER_COUNT2_VALUE_MSB WLAN_LF_TIMER_COUNT2_VALUE_MSB +#define LF_TIMER_COUNT2_VALUE_LSB WLAN_LF_TIMER_COUNT2_VALUE_LSB +#define LF_TIMER_COUNT2_VALUE_MASK WLAN_LF_TIMER_COUNT2_VALUE_MASK +#define LF_TIMER_COUNT2_VALUE_GET(x) WLAN_LF_TIMER_COUNT2_VALUE_GET(x) +#define LF_TIMER_COUNT2_VALUE_SET(x) WLAN_LF_TIMER_COUNT2_VALUE_SET(x) +#define LF_TIMER_CONTROL2_ADDRESS WLAN_LF_TIMER_CONTROL2_ADDRESS +#define LF_TIMER_CONTROL2_OFFSET WLAN_LF_TIMER_CONTROL2_OFFSET +#define LF_TIMER_CONTROL2_ENABLE_MSB WLAN_LF_TIMER_CONTROL2_ENABLE_MSB +#define LF_TIMER_CONTROL2_ENABLE_LSB WLAN_LF_TIMER_CONTROL2_ENABLE_LSB +#define LF_TIMER_CONTROL2_ENABLE_MASK WLAN_LF_TIMER_CONTROL2_ENABLE_MASK +#define LF_TIMER_CONTROL2_ENABLE_GET(x) WLAN_LF_TIMER_CONTROL2_ENABLE_GET(x) +#define LF_TIMER_CONTROL2_ENABLE_SET(x) WLAN_LF_TIMER_CONTROL2_ENABLE_SET(x) +#define LF_TIMER_CONTROL2_AUTO_RESTART_MSB WLAN_LF_TIMER_CONTROL2_AUTO_RESTART_MSB +#define LF_TIMER_CONTROL2_AUTO_RESTART_LSB WLAN_LF_TIMER_CONTROL2_AUTO_RESTART_LSB +#define LF_TIMER_CONTROL2_AUTO_RESTART_MASK WLAN_LF_TIMER_CONTROL2_AUTO_RESTART_MASK +#define LF_TIMER_CONTROL2_AUTO_RESTART_GET(x) WLAN_LF_TIMER_CONTROL2_AUTO_RESTART_GET(x) +#define LF_TIMER_CONTROL2_AUTO_RESTART_SET(x) WLAN_LF_TIMER_CONTROL2_AUTO_RESTART_SET(x) +#define LF_TIMER_CONTROL2_RESET_MSB WLAN_LF_TIMER_CONTROL2_RESET_MSB +#define LF_TIMER_CONTROL2_RESET_LSB WLAN_LF_TIMER_CONTROL2_RESET_LSB +#define LF_TIMER_CONTROL2_RESET_MASK WLAN_LF_TIMER_CONTROL2_RESET_MASK +#define LF_TIMER_CONTROL2_RESET_GET(x) WLAN_LF_TIMER_CONTROL2_RESET_GET(x) +#define LF_TIMER_CONTROL2_RESET_SET(x) WLAN_LF_TIMER_CONTROL2_RESET_SET(x) +#define LF_TIMER_STATUS2_ADDRESS WLAN_LF_TIMER_STATUS2_ADDRESS +#define LF_TIMER_STATUS2_OFFSET WLAN_LF_TIMER_STATUS2_OFFSET +#define LF_TIMER_STATUS2_INTERRUPT_MSB WLAN_LF_TIMER_STATUS2_INTERRUPT_MSB +#define LF_TIMER_STATUS2_INTERRUPT_LSB WLAN_LF_TIMER_STATUS2_INTERRUPT_LSB +#define LF_TIMER_STATUS2_INTERRUPT_MASK WLAN_LF_TIMER_STATUS2_INTERRUPT_MASK +#define LF_TIMER_STATUS2_INTERRUPT_GET(x) WLAN_LF_TIMER_STATUS2_INTERRUPT_GET(x) +#define LF_TIMER_STATUS2_INTERRUPT_SET(x) WLAN_LF_TIMER_STATUS2_INTERRUPT_SET(x) +#define LF_TIMER3_ADDRESS WLAN_LF_TIMER3_ADDRESS +#define LF_TIMER3_OFFSET WLAN_LF_TIMER3_OFFSET +#define LF_TIMER3_TARGET_MSB WLAN_LF_TIMER3_TARGET_MSB +#define LF_TIMER3_TARGET_LSB WLAN_LF_TIMER3_TARGET_LSB +#define LF_TIMER3_TARGET_MASK WLAN_LF_TIMER3_TARGET_MASK +#define LF_TIMER3_TARGET_GET(x) WLAN_LF_TIMER3_TARGET_GET(x) +#define LF_TIMER3_TARGET_SET(x) WLAN_LF_TIMER3_TARGET_SET(x) +#define LF_TIMER_COUNT3_ADDRESS WLAN_LF_TIMER_COUNT3_ADDRESS +#define LF_TIMER_COUNT3_OFFSET WLAN_LF_TIMER_COUNT3_OFFSET +#define LF_TIMER_COUNT3_VALUE_MSB WLAN_LF_TIMER_COUNT3_VALUE_MSB +#define LF_TIMER_COUNT3_VALUE_LSB WLAN_LF_TIMER_COUNT3_VALUE_LSB +#define LF_TIMER_COUNT3_VALUE_MASK WLAN_LF_TIMER_COUNT3_VALUE_MASK +#define LF_TIMER_COUNT3_VALUE_GET(x) WLAN_LF_TIMER_COUNT3_VALUE_GET(x) +#define LF_TIMER_COUNT3_VALUE_SET(x) WLAN_LF_TIMER_COUNT3_VALUE_SET(x) +#define LF_TIMER_CONTROL3_ADDRESS WLAN_LF_TIMER_CONTROL3_ADDRESS +#define LF_TIMER_CONTROL3_OFFSET WLAN_LF_TIMER_CONTROL3_OFFSET +#define LF_TIMER_CONTROL3_ENABLE_MSB WLAN_LF_TIMER_CONTROL3_ENABLE_MSB +#define LF_TIMER_CONTROL3_ENABLE_LSB WLAN_LF_TIMER_CONTROL3_ENABLE_LSB +#define LF_TIMER_CONTROL3_ENABLE_MASK WLAN_LF_TIMER_CONTROL3_ENABLE_MASK +#define LF_TIMER_CONTROL3_ENABLE_GET(x) WLAN_LF_TIMER_CONTROL3_ENABLE_GET(x) +#define LF_TIMER_CONTROL3_ENABLE_SET(x) WLAN_LF_TIMER_CONTROL3_ENABLE_SET(x) +#define LF_TIMER_CONTROL3_AUTO_RESTART_MSB WLAN_LF_TIMER_CONTROL3_AUTO_RESTART_MSB +#define LF_TIMER_CONTROL3_AUTO_RESTART_LSB WLAN_LF_TIMER_CONTROL3_AUTO_RESTART_LSB +#define LF_TIMER_CONTROL3_AUTO_RESTART_MASK WLAN_LF_TIMER_CONTROL3_AUTO_RESTART_MASK +#define LF_TIMER_CONTROL3_AUTO_RESTART_GET(x) WLAN_LF_TIMER_CONTROL3_AUTO_RESTART_GET(x) +#define LF_TIMER_CONTROL3_AUTO_RESTART_SET(x) WLAN_LF_TIMER_CONTROL3_AUTO_RESTART_SET(x) +#define LF_TIMER_CONTROL3_RESET_MSB WLAN_LF_TIMER_CONTROL3_RESET_MSB +#define LF_TIMER_CONTROL3_RESET_LSB WLAN_LF_TIMER_CONTROL3_RESET_LSB +#define LF_TIMER_CONTROL3_RESET_MASK WLAN_LF_TIMER_CONTROL3_RESET_MASK +#define LF_TIMER_CONTROL3_RESET_GET(x) WLAN_LF_TIMER_CONTROL3_RESET_GET(x) +#define LF_TIMER_CONTROL3_RESET_SET(x) WLAN_LF_TIMER_CONTROL3_RESET_SET(x) +#define LF_TIMER_STATUS3_ADDRESS WLAN_LF_TIMER_STATUS3_ADDRESS +#define LF_TIMER_STATUS3_OFFSET WLAN_LF_TIMER_STATUS3_OFFSET +#define LF_TIMER_STATUS3_INTERRUPT_MSB WLAN_LF_TIMER_STATUS3_INTERRUPT_MSB +#define LF_TIMER_STATUS3_INTERRUPT_LSB WLAN_LF_TIMER_STATUS3_INTERRUPT_LSB +#define LF_TIMER_STATUS3_INTERRUPT_MASK WLAN_LF_TIMER_STATUS3_INTERRUPT_MASK +#define LF_TIMER_STATUS3_INTERRUPT_GET(x) WLAN_LF_TIMER_STATUS3_INTERRUPT_GET(x) +#define LF_TIMER_STATUS3_INTERRUPT_SET(x) WLAN_LF_TIMER_STATUS3_INTERRUPT_SET(x) +#define HF_TIMER_ADDRESS WLAN_HF_TIMER_ADDRESS +#define HF_TIMER_OFFSET WLAN_HF_TIMER_OFFSET +#define HF_TIMER_TARGET_MSB WLAN_HF_TIMER_TARGET_MSB +#define HF_TIMER_TARGET_LSB WLAN_HF_TIMER_TARGET_LSB +#define HF_TIMER_TARGET_MASK WLAN_HF_TIMER_TARGET_MASK +#define HF_TIMER_TARGET_GET(x) WLAN_HF_TIMER_TARGET_GET(x) +#define HF_TIMER_TARGET_SET(x) WLAN_HF_TIMER_TARGET_SET(x) +#define HF_TIMER_COUNT_ADDRESS WLAN_HF_TIMER_COUNT_ADDRESS +#define HF_TIMER_COUNT_OFFSET WLAN_HF_TIMER_COUNT_OFFSET +#define HF_TIMER_COUNT_VALUE_MSB WLAN_HF_TIMER_COUNT_VALUE_MSB +#define HF_TIMER_COUNT_VALUE_LSB WLAN_HF_TIMER_COUNT_VALUE_LSB +#define HF_TIMER_COUNT_VALUE_MASK WLAN_HF_TIMER_COUNT_VALUE_MASK +#define HF_TIMER_COUNT_VALUE_GET(x) WLAN_HF_TIMER_COUNT_VALUE_GET(x) +#define HF_TIMER_COUNT_VALUE_SET(x) WLAN_HF_TIMER_COUNT_VALUE_SET(x) +#define HF_LF_COUNT_ADDRESS WLAN_HF_LF_COUNT_ADDRESS +#define HF_LF_COUNT_OFFSET WLAN_HF_LF_COUNT_OFFSET +#define HF_LF_COUNT_VALUE_MSB WLAN_HF_LF_COUNT_VALUE_MSB +#define HF_LF_COUNT_VALUE_LSB WLAN_HF_LF_COUNT_VALUE_LSB +#define HF_LF_COUNT_VALUE_MASK WLAN_HF_LF_COUNT_VALUE_MASK +#define HF_LF_COUNT_VALUE_GET(x) WLAN_HF_LF_COUNT_VALUE_GET(x) +#define HF_LF_COUNT_VALUE_SET(x) WLAN_HF_LF_COUNT_VALUE_SET(x) +#define HF_TIMER_CONTROL_ADDRESS WLAN_HF_TIMER_CONTROL_ADDRESS +#define HF_TIMER_CONTROL_OFFSET WLAN_HF_TIMER_CONTROL_OFFSET +#define HF_TIMER_CONTROL_ENABLE_MSB WLAN_HF_TIMER_CONTROL_ENABLE_MSB +#define HF_TIMER_CONTROL_ENABLE_LSB WLAN_HF_TIMER_CONTROL_ENABLE_LSB +#define HF_TIMER_CONTROL_ENABLE_MASK WLAN_HF_TIMER_CONTROL_ENABLE_MASK +#define HF_TIMER_CONTROL_ENABLE_GET(x) WLAN_HF_TIMER_CONTROL_ENABLE_GET(x) +#define HF_TIMER_CONTROL_ENABLE_SET(x) WLAN_HF_TIMER_CONTROL_ENABLE_SET(x) +#define HF_TIMER_CONTROL_ON_MSB WLAN_HF_TIMER_CONTROL_ON_MSB +#define HF_TIMER_CONTROL_ON_LSB WLAN_HF_TIMER_CONTROL_ON_LSB +#define HF_TIMER_CONTROL_ON_MASK WLAN_HF_TIMER_CONTROL_ON_MASK +#define HF_TIMER_CONTROL_ON_GET(x) WLAN_HF_TIMER_CONTROL_ON_GET(x) +#define HF_TIMER_CONTROL_ON_SET(x) WLAN_HF_TIMER_CONTROL_ON_SET(x) +#define HF_TIMER_CONTROL_AUTO_RESTART_MSB WLAN_HF_TIMER_CONTROL_AUTO_RESTART_MSB +#define HF_TIMER_CONTROL_AUTO_RESTART_LSB WLAN_HF_TIMER_CONTROL_AUTO_RESTART_LSB +#define HF_TIMER_CONTROL_AUTO_RESTART_MASK WLAN_HF_TIMER_CONTROL_AUTO_RESTART_MASK +#define HF_TIMER_CONTROL_AUTO_RESTART_GET(x) WLAN_HF_TIMER_CONTROL_AUTO_RESTART_GET(x) +#define HF_TIMER_CONTROL_AUTO_RESTART_SET(x) WLAN_HF_TIMER_CONTROL_AUTO_RESTART_SET(x) +#define HF_TIMER_CONTROL_RESET_MSB WLAN_HF_TIMER_CONTROL_RESET_MSB +#define HF_TIMER_CONTROL_RESET_LSB WLAN_HF_TIMER_CONTROL_RESET_LSB +#define HF_TIMER_CONTROL_RESET_MASK WLAN_HF_TIMER_CONTROL_RESET_MASK +#define HF_TIMER_CONTROL_RESET_GET(x) WLAN_HF_TIMER_CONTROL_RESET_GET(x) +#define HF_TIMER_CONTROL_RESET_SET(x) WLAN_HF_TIMER_CONTROL_RESET_SET(x) +#define HF_TIMER_STATUS_ADDRESS WLAN_HF_TIMER_STATUS_ADDRESS +#define HF_TIMER_STATUS_OFFSET WLAN_HF_TIMER_STATUS_OFFSET +#define HF_TIMER_STATUS_INTERRUPT_MSB WLAN_HF_TIMER_STATUS_INTERRUPT_MSB +#define HF_TIMER_STATUS_INTERRUPT_LSB WLAN_HF_TIMER_STATUS_INTERRUPT_LSB +#define HF_TIMER_STATUS_INTERRUPT_MASK WLAN_HF_TIMER_STATUS_INTERRUPT_MASK +#define HF_TIMER_STATUS_INTERRUPT_GET(x) WLAN_HF_TIMER_STATUS_INTERRUPT_GET(x) +#define HF_TIMER_STATUS_INTERRUPT_SET(x) WLAN_HF_TIMER_STATUS_INTERRUPT_SET(x) +#define RTC_CONTROL_ADDRESS WLAN_RTC_CONTROL_ADDRESS +#define RTC_CONTROL_OFFSET WLAN_RTC_CONTROL_OFFSET +#define RTC_CONTROL_ENABLE_MSB WLAN_RTC_CONTROL_ENABLE_MSB +#define RTC_CONTROL_ENABLE_LSB WLAN_RTC_CONTROL_ENABLE_LSB +#define RTC_CONTROL_ENABLE_MASK WLAN_RTC_CONTROL_ENABLE_MASK +#define RTC_CONTROL_ENABLE_GET(x) WLAN_RTC_CONTROL_ENABLE_GET(x) +#define RTC_CONTROL_ENABLE_SET(x) WLAN_RTC_CONTROL_ENABLE_SET(x) +#define RTC_CONTROL_LOAD_RTC_MSB WLAN_RTC_CONTROL_LOAD_RTC_MSB +#define RTC_CONTROL_LOAD_RTC_LSB WLAN_RTC_CONTROL_LOAD_RTC_LSB +#define RTC_CONTROL_LOAD_RTC_MASK WLAN_RTC_CONTROL_LOAD_RTC_MASK +#define RTC_CONTROL_LOAD_RTC_GET(x) WLAN_RTC_CONTROL_LOAD_RTC_GET(x) +#define RTC_CONTROL_LOAD_RTC_SET(x) WLAN_RTC_CONTROL_LOAD_RTC_SET(x) +#define RTC_CONTROL_LOAD_ALARM_MSB WLAN_RTC_CONTROL_LOAD_ALARM_MSB +#define RTC_CONTROL_LOAD_ALARM_LSB WLAN_RTC_CONTROL_LOAD_ALARM_LSB +#define RTC_CONTROL_LOAD_ALARM_MASK WLAN_RTC_CONTROL_LOAD_ALARM_MASK +#define RTC_CONTROL_LOAD_ALARM_GET(x) WLAN_RTC_CONTROL_LOAD_ALARM_GET(x) +#define RTC_CONTROL_LOAD_ALARM_SET(x) WLAN_RTC_CONTROL_LOAD_ALARM_SET(x) +#define RTC_TIME_ADDRESS WLAN_RTC_TIME_ADDRESS +#define RTC_TIME_OFFSET WLAN_RTC_TIME_OFFSET +#define RTC_TIME_WEEK_DAY_MSB WLAN_RTC_TIME_WEEK_DAY_MSB +#define RTC_TIME_WEEK_DAY_LSB WLAN_RTC_TIME_WEEK_DAY_LSB +#define RTC_TIME_WEEK_DAY_MASK WLAN_RTC_TIME_WEEK_DAY_MASK +#define RTC_TIME_WEEK_DAY_GET(x) WLAN_RTC_TIME_WEEK_DAY_GET(x) +#define RTC_TIME_WEEK_DAY_SET(x) WLAN_RTC_TIME_WEEK_DAY_SET(x) +#define RTC_TIME_HOUR_MSB WLAN_RTC_TIME_HOUR_MSB +#define RTC_TIME_HOUR_LSB WLAN_RTC_TIME_HOUR_LSB +#define RTC_TIME_HOUR_MASK WLAN_RTC_TIME_HOUR_MASK +#define RTC_TIME_HOUR_GET(x) WLAN_RTC_TIME_HOUR_GET(x) +#define RTC_TIME_HOUR_SET(x) WLAN_RTC_TIME_HOUR_SET(x) +#define RTC_TIME_MINUTE_MSB WLAN_RTC_TIME_MINUTE_MSB +#define RTC_TIME_MINUTE_LSB WLAN_RTC_TIME_MINUTE_LSB +#define RTC_TIME_MINUTE_MASK WLAN_RTC_TIME_MINUTE_MASK +#define RTC_TIME_MINUTE_GET(x) WLAN_RTC_TIME_MINUTE_GET(x) +#define RTC_TIME_MINUTE_SET(x) WLAN_RTC_TIME_MINUTE_SET(x) +#define RTC_TIME_SECOND_MSB WLAN_RTC_TIME_SECOND_MSB +#define RTC_TIME_SECOND_LSB WLAN_RTC_TIME_SECOND_LSB +#define RTC_TIME_SECOND_MASK WLAN_RTC_TIME_SECOND_MASK +#define RTC_TIME_SECOND_GET(x) WLAN_RTC_TIME_SECOND_GET(x) +#define RTC_TIME_SECOND_SET(x) WLAN_RTC_TIME_SECOND_SET(x) +#define RTC_DATE_ADDRESS WLAN_RTC_DATE_ADDRESS +#define RTC_DATE_OFFSET WLAN_RTC_DATE_OFFSET +#define RTC_DATE_YEAR_MSB WLAN_RTC_DATE_YEAR_MSB +#define RTC_DATE_YEAR_LSB WLAN_RTC_DATE_YEAR_LSB +#define RTC_DATE_YEAR_MASK WLAN_RTC_DATE_YEAR_MASK +#define RTC_DATE_YEAR_GET(x) WLAN_RTC_DATE_YEAR_GET(x) +#define RTC_DATE_YEAR_SET(x) WLAN_RTC_DATE_YEAR_SET(x) +#define RTC_DATE_MONTH_MSB WLAN_RTC_DATE_MONTH_MSB +#define RTC_DATE_MONTH_LSB WLAN_RTC_DATE_MONTH_LSB +#define RTC_DATE_MONTH_MASK WLAN_RTC_DATE_MONTH_MASK +#define RTC_DATE_MONTH_GET(x) WLAN_RTC_DATE_MONTH_GET(x) +#define RTC_DATE_MONTH_SET(x) WLAN_RTC_DATE_MONTH_SET(x) +#define RTC_DATE_MONTH_DAY_MSB WLAN_RTC_DATE_MONTH_DAY_MSB +#define RTC_DATE_MONTH_DAY_LSB WLAN_RTC_DATE_MONTH_DAY_LSB +#define RTC_DATE_MONTH_DAY_MASK WLAN_RTC_DATE_MONTH_DAY_MASK +#define RTC_DATE_MONTH_DAY_GET(x) WLAN_RTC_DATE_MONTH_DAY_GET(x) +#define RTC_DATE_MONTH_DAY_SET(x) WLAN_RTC_DATE_MONTH_DAY_SET(x) +#define RTC_SET_TIME_ADDRESS WLAN_RTC_SET_TIME_ADDRESS +#define RTC_SET_TIME_OFFSET WLAN_RTC_SET_TIME_OFFSET +#define RTC_SET_TIME_WEEK_DAY_MSB WLAN_RTC_SET_TIME_WEEK_DAY_MSB +#define RTC_SET_TIME_WEEK_DAY_LSB WLAN_RTC_SET_TIME_WEEK_DAY_LSB +#define RTC_SET_TIME_WEEK_DAY_MASK WLAN_RTC_SET_TIME_WEEK_DAY_MASK +#define RTC_SET_TIME_WEEK_DAY_GET(x) WLAN_RTC_SET_TIME_WEEK_DAY_GET(x) +#define RTC_SET_TIME_WEEK_DAY_SET(x) WLAN_RTC_SET_TIME_WEEK_DAY_SET(x) +#define RTC_SET_TIME_HOUR_MSB WLAN_RTC_SET_TIME_HOUR_MSB +#define RTC_SET_TIME_HOUR_LSB WLAN_RTC_SET_TIME_HOUR_LSB +#define RTC_SET_TIME_HOUR_MASK WLAN_RTC_SET_TIME_HOUR_MASK +#define RTC_SET_TIME_HOUR_GET(x) WLAN_RTC_SET_TIME_HOUR_GET(x) +#define RTC_SET_TIME_HOUR_SET(x) WLAN_RTC_SET_TIME_HOUR_SET(x) +#define RTC_SET_TIME_MINUTE_MSB WLAN_RTC_SET_TIME_MINUTE_MSB +#define RTC_SET_TIME_MINUTE_LSB WLAN_RTC_SET_TIME_MINUTE_LSB +#define RTC_SET_TIME_MINUTE_MASK WLAN_RTC_SET_TIME_MINUTE_MASK +#define RTC_SET_TIME_MINUTE_GET(x) WLAN_RTC_SET_TIME_MINUTE_GET(x) +#define RTC_SET_TIME_MINUTE_SET(x) WLAN_RTC_SET_TIME_MINUTE_SET(x) +#define RTC_SET_TIME_SECOND_MSB WLAN_RTC_SET_TIME_SECOND_MSB +#define RTC_SET_TIME_SECOND_LSB WLAN_RTC_SET_TIME_SECOND_LSB +#define RTC_SET_TIME_SECOND_MASK WLAN_RTC_SET_TIME_SECOND_MASK +#define RTC_SET_TIME_SECOND_GET(x) WLAN_RTC_SET_TIME_SECOND_GET(x) +#define RTC_SET_TIME_SECOND_SET(x) WLAN_RTC_SET_TIME_SECOND_SET(x) +#define RTC_SET_DATE_ADDRESS WLAN_RTC_SET_DATE_ADDRESS +#define RTC_SET_DATE_OFFSET WLAN_RTC_SET_DATE_OFFSET +#define RTC_SET_DATE_YEAR_MSB WLAN_RTC_SET_DATE_YEAR_MSB +#define RTC_SET_DATE_YEAR_LSB WLAN_RTC_SET_DATE_YEAR_LSB +#define RTC_SET_DATE_YEAR_MASK WLAN_RTC_SET_DATE_YEAR_MASK +#define RTC_SET_DATE_YEAR_GET(x) WLAN_RTC_SET_DATE_YEAR_GET(x) +#define RTC_SET_DATE_YEAR_SET(x) WLAN_RTC_SET_DATE_YEAR_SET(x) +#define RTC_SET_DATE_MONTH_MSB WLAN_RTC_SET_DATE_MONTH_MSB +#define RTC_SET_DATE_MONTH_LSB WLAN_RTC_SET_DATE_MONTH_LSB +#define RTC_SET_DATE_MONTH_MASK WLAN_RTC_SET_DATE_MONTH_MASK +#define RTC_SET_DATE_MONTH_GET(x) WLAN_RTC_SET_DATE_MONTH_GET(x) +#define RTC_SET_DATE_MONTH_SET(x) WLAN_RTC_SET_DATE_MONTH_SET(x) +#define RTC_SET_DATE_MONTH_DAY_MSB WLAN_RTC_SET_DATE_MONTH_DAY_MSB +#define RTC_SET_DATE_MONTH_DAY_LSB WLAN_RTC_SET_DATE_MONTH_DAY_LSB +#define RTC_SET_DATE_MONTH_DAY_MASK WLAN_RTC_SET_DATE_MONTH_DAY_MASK +#define RTC_SET_DATE_MONTH_DAY_GET(x) WLAN_RTC_SET_DATE_MONTH_DAY_GET(x) +#define RTC_SET_DATE_MONTH_DAY_SET(x) WLAN_RTC_SET_DATE_MONTH_DAY_SET(x) +#define RTC_SET_ALARM_ADDRESS WLAN_RTC_SET_ALARM_ADDRESS +#define RTC_SET_ALARM_OFFSET WLAN_RTC_SET_ALARM_OFFSET +#define RTC_SET_ALARM_HOUR_MSB WLAN_RTC_SET_ALARM_HOUR_MSB +#define RTC_SET_ALARM_HOUR_LSB WLAN_RTC_SET_ALARM_HOUR_LSB +#define RTC_SET_ALARM_HOUR_MASK WLAN_RTC_SET_ALARM_HOUR_MASK +#define RTC_SET_ALARM_HOUR_GET(x) WLAN_RTC_SET_ALARM_HOUR_GET(x) +#define RTC_SET_ALARM_HOUR_SET(x) WLAN_RTC_SET_ALARM_HOUR_SET(x) +#define RTC_SET_ALARM_MINUTE_MSB WLAN_RTC_SET_ALARM_MINUTE_MSB +#define RTC_SET_ALARM_MINUTE_LSB WLAN_RTC_SET_ALARM_MINUTE_LSB +#define RTC_SET_ALARM_MINUTE_MASK WLAN_RTC_SET_ALARM_MINUTE_MASK +#define RTC_SET_ALARM_MINUTE_GET(x) WLAN_RTC_SET_ALARM_MINUTE_GET(x) +#define RTC_SET_ALARM_MINUTE_SET(x) WLAN_RTC_SET_ALARM_MINUTE_SET(x) +#define RTC_SET_ALARM_SECOND_MSB WLAN_RTC_SET_ALARM_SECOND_MSB +#define RTC_SET_ALARM_SECOND_LSB WLAN_RTC_SET_ALARM_SECOND_LSB +#define RTC_SET_ALARM_SECOND_MASK WLAN_RTC_SET_ALARM_SECOND_MASK +#define RTC_SET_ALARM_SECOND_GET(x) WLAN_RTC_SET_ALARM_SECOND_GET(x) +#define RTC_SET_ALARM_SECOND_SET(x) WLAN_RTC_SET_ALARM_SECOND_SET(x) +#define RTC_CONFIG_ADDRESS WLAN_RTC_CONFIG_ADDRESS +#define RTC_CONFIG_OFFSET WLAN_RTC_CONFIG_OFFSET +#define RTC_CONFIG_BCD_MSB WLAN_RTC_CONFIG_BCD_MSB +#define RTC_CONFIG_BCD_LSB WLAN_RTC_CONFIG_BCD_LSB +#define RTC_CONFIG_BCD_MASK WLAN_RTC_CONFIG_BCD_MASK +#define RTC_CONFIG_BCD_GET(x) WLAN_RTC_CONFIG_BCD_GET(x) +#define RTC_CONFIG_BCD_SET(x) WLAN_RTC_CONFIG_BCD_SET(x) +#define RTC_CONFIG_TWELVE_HOUR_MSB WLAN_RTC_CONFIG_TWELVE_HOUR_MSB +#define RTC_CONFIG_TWELVE_HOUR_LSB WLAN_RTC_CONFIG_TWELVE_HOUR_LSB +#define RTC_CONFIG_TWELVE_HOUR_MASK WLAN_RTC_CONFIG_TWELVE_HOUR_MASK +#define RTC_CONFIG_TWELVE_HOUR_GET(x) WLAN_RTC_CONFIG_TWELVE_HOUR_GET(x) +#define RTC_CONFIG_TWELVE_HOUR_SET(x) WLAN_RTC_CONFIG_TWELVE_HOUR_SET(x) +#define RTC_CONFIG_DSE_MSB WLAN_RTC_CONFIG_DSE_MSB +#define RTC_CONFIG_DSE_LSB WLAN_RTC_CONFIG_DSE_LSB +#define RTC_CONFIG_DSE_MASK WLAN_RTC_CONFIG_DSE_MASK +#define RTC_CONFIG_DSE_GET(x) WLAN_RTC_CONFIG_DSE_GET(x) +#define RTC_CONFIG_DSE_SET(x) WLAN_RTC_CONFIG_DSE_SET(x) +#define RTC_ALARM_STATUS_ADDRESS WLAN_RTC_ALARM_STATUS_ADDRESS +#define RTC_ALARM_STATUS_OFFSET WLAN_RTC_ALARM_STATUS_OFFSET +#define RTC_ALARM_STATUS_ENABLE_MSB WLAN_RTC_ALARM_STATUS_ENABLE_MSB +#define RTC_ALARM_STATUS_ENABLE_LSB WLAN_RTC_ALARM_STATUS_ENABLE_LSB +#define RTC_ALARM_STATUS_ENABLE_MASK WLAN_RTC_ALARM_STATUS_ENABLE_MASK +#define RTC_ALARM_STATUS_ENABLE_GET(x) WLAN_RTC_ALARM_STATUS_ENABLE_GET(x) +#define RTC_ALARM_STATUS_ENABLE_SET(x) WLAN_RTC_ALARM_STATUS_ENABLE_SET(x) +#define RTC_ALARM_STATUS_INTERRUPT_MSB WLAN_RTC_ALARM_STATUS_INTERRUPT_MSB +#define RTC_ALARM_STATUS_INTERRUPT_LSB WLAN_RTC_ALARM_STATUS_INTERRUPT_LSB +#define RTC_ALARM_STATUS_INTERRUPT_MASK WLAN_RTC_ALARM_STATUS_INTERRUPT_MASK +#define RTC_ALARM_STATUS_INTERRUPT_GET(x) WLAN_RTC_ALARM_STATUS_INTERRUPT_GET(x) +#define RTC_ALARM_STATUS_INTERRUPT_SET(x) WLAN_RTC_ALARM_STATUS_INTERRUPT_SET(x) +#define UART_WAKEUP_ADDRESS WLAN_UART_WAKEUP_ADDRESS +#define UART_WAKEUP_OFFSET WLAN_UART_WAKEUP_OFFSET +#define UART_WAKEUP_ENABLE_MSB WLAN_UART_WAKEUP_ENABLE_MSB +#define UART_WAKEUP_ENABLE_LSB WLAN_UART_WAKEUP_ENABLE_LSB +#define UART_WAKEUP_ENABLE_MASK WLAN_UART_WAKEUP_ENABLE_MASK +#define UART_WAKEUP_ENABLE_GET(x) WLAN_UART_WAKEUP_ENABLE_GET(x) +#define UART_WAKEUP_ENABLE_SET(x) WLAN_UART_WAKEUP_ENABLE_SET(x) +#define RESET_CAUSE_ADDRESS WLAN_RESET_CAUSE_ADDRESS +#define RESET_CAUSE_OFFSET WLAN_RESET_CAUSE_OFFSET +#define RESET_CAUSE_LAST_MSB WLAN_RESET_CAUSE_LAST_MSB +#define RESET_CAUSE_LAST_LSB WLAN_RESET_CAUSE_LAST_LSB +#define RESET_CAUSE_LAST_MASK WLAN_RESET_CAUSE_LAST_MASK +#define RESET_CAUSE_LAST_GET(x) WLAN_RESET_CAUSE_LAST_GET(x) +#define RESET_CAUSE_LAST_SET(x) WLAN_RESET_CAUSE_LAST_SET(x) +#define SYSTEM_SLEEP_ADDRESS WLAN_SYSTEM_SLEEP_ADDRESS +#define SYSTEM_SLEEP_OFFSET WLAN_SYSTEM_SLEEP_OFFSET +#define SYSTEM_SLEEP_HOST_IF_MSB WLAN_SYSTEM_SLEEP_HOST_IF_MSB +#define SYSTEM_SLEEP_HOST_IF_LSB WLAN_SYSTEM_SLEEP_HOST_IF_LSB +#define SYSTEM_SLEEP_HOST_IF_MASK WLAN_SYSTEM_SLEEP_HOST_IF_MASK +#define SYSTEM_SLEEP_HOST_IF_GET(x) WLAN_SYSTEM_SLEEP_HOST_IF_GET(x) +#define SYSTEM_SLEEP_HOST_IF_SET(x) WLAN_SYSTEM_SLEEP_HOST_IF_SET(x) +#define SYSTEM_SLEEP_MBOX_MSB WLAN_SYSTEM_SLEEP_MBOX_MSB +#define SYSTEM_SLEEP_MBOX_LSB WLAN_SYSTEM_SLEEP_MBOX_LSB +#define SYSTEM_SLEEP_MBOX_MASK WLAN_SYSTEM_SLEEP_MBOX_MASK +#define SYSTEM_SLEEP_MBOX_GET(x) WLAN_SYSTEM_SLEEP_MBOX_GET(x) +#define SYSTEM_SLEEP_MBOX_SET(x) WLAN_SYSTEM_SLEEP_MBOX_SET(x) +#define SYSTEM_SLEEP_MAC_IF_MSB WLAN_SYSTEM_SLEEP_MAC_IF_MSB +#define SYSTEM_SLEEP_MAC_IF_LSB WLAN_SYSTEM_SLEEP_MAC_IF_LSB +#define SYSTEM_SLEEP_MAC_IF_MASK WLAN_SYSTEM_SLEEP_MAC_IF_MASK +#define SYSTEM_SLEEP_MAC_IF_GET(x) WLAN_SYSTEM_SLEEP_MAC_IF_GET(x) +#define SYSTEM_SLEEP_MAC_IF_SET(x) WLAN_SYSTEM_SLEEP_MAC_IF_SET(x) +#define SYSTEM_SLEEP_LIGHT_MSB WLAN_SYSTEM_SLEEP_LIGHT_MSB +#define SYSTEM_SLEEP_LIGHT_LSB WLAN_SYSTEM_SLEEP_LIGHT_LSB +#define SYSTEM_SLEEP_LIGHT_MASK WLAN_SYSTEM_SLEEP_LIGHT_MASK +#define SYSTEM_SLEEP_LIGHT_GET(x) WLAN_SYSTEM_SLEEP_LIGHT_GET(x) +#define SYSTEM_SLEEP_LIGHT_SET(x) WLAN_SYSTEM_SLEEP_LIGHT_SET(x) +#define SYSTEM_SLEEP_DISABLE_MSB WLAN_SYSTEM_SLEEP_DISABLE_MSB +#define SYSTEM_SLEEP_DISABLE_LSB WLAN_SYSTEM_SLEEP_DISABLE_LSB +#define SYSTEM_SLEEP_DISABLE_MASK WLAN_SYSTEM_SLEEP_DISABLE_MASK +#define SYSTEM_SLEEP_DISABLE_GET(x) WLAN_SYSTEM_SLEEP_DISABLE_GET(x) +#define SYSTEM_SLEEP_DISABLE_SET(x) WLAN_SYSTEM_SLEEP_DISABLE_SET(x) +#define SDIO_WRAPPER_ADDRESS WLAN_SDIO_WRAPPER_ADDRESS +#define SDIO_WRAPPER_OFFSET WLAN_SDIO_WRAPPER_OFFSET +#define SDIO_WRAPPER_SLEEP_MSB WLAN_SDIO_WRAPPER_SLEEP_MSB +#define SDIO_WRAPPER_SLEEP_LSB WLAN_SDIO_WRAPPER_SLEEP_LSB +#define SDIO_WRAPPER_SLEEP_MASK WLAN_SDIO_WRAPPER_SLEEP_MASK +#define SDIO_WRAPPER_SLEEP_GET(x) WLAN_SDIO_WRAPPER_SLEEP_GET(x) +#define SDIO_WRAPPER_SLEEP_SET(x) WLAN_SDIO_WRAPPER_SLEEP_SET(x) +#define SDIO_WRAPPER_WAKEUP_MSB WLAN_SDIO_WRAPPER_WAKEUP_MSB +#define SDIO_WRAPPER_WAKEUP_LSB WLAN_SDIO_WRAPPER_WAKEUP_LSB +#define SDIO_WRAPPER_WAKEUP_MASK WLAN_SDIO_WRAPPER_WAKEUP_MASK +#define SDIO_WRAPPER_WAKEUP_GET(x) WLAN_SDIO_WRAPPER_WAKEUP_GET(x) +#define SDIO_WRAPPER_WAKEUP_SET(x) WLAN_SDIO_WRAPPER_WAKEUP_SET(x) +#define SDIO_WRAPPER_SOC_ON_MSB WLAN_SDIO_WRAPPER_SOC_ON_MSB +#define SDIO_WRAPPER_SOC_ON_LSB WLAN_SDIO_WRAPPER_SOC_ON_LSB +#define SDIO_WRAPPER_SOC_ON_MASK WLAN_SDIO_WRAPPER_SOC_ON_MASK +#define SDIO_WRAPPER_SOC_ON_GET(x) WLAN_SDIO_WRAPPER_SOC_ON_GET(x) +#define SDIO_WRAPPER_SOC_ON_SET(x) WLAN_SDIO_WRAPPER_SOC_ON_SET(x) +#define SDIO_WRAPPER_ON_MSB WLAN_SDIO_WRAPPER_ON_MSB +#define SDIO_WRAPPER_ON_LSB WLAN_SDIO_WRAPPER_ON_LSB +#define SDIO_WRAPPER_ON_MASK WLAN_SDIO_WRAPPER_ON_MASK +#define SDIO_WRAPPER_ON_GET(x) WLAN_SDIO_WRAPPER_ON_GET(x) +#define SDIO_WRAPPER_ON_SET(x) WLAN_SDIO_WRAPPER_ON_SET(x) +#define MAC_SLEEP_CONTROL_ADDRESS WLAN_MAC_SLEEP_CONTROL_ADDRESS +#define MAC_SLEEP_CONTROL_OFFSET WLAN_MAC_SLEEP_CONTROL_OFFSET +#define MAC_SLEEP_CONTROL_ENABLE_MSB WLAN_MAC_SLEEP_CONTROL_ENABLE_MSB +#define MAC_SLEEP_CONTROL_ENABLE_LSB WLAN_MAC_SLEEP_CONTROL_ENABLE_LSB +#define MAC_SLEEP_CONTROL_ENABLE_MASK WLAN_MAC_SLEEP_CONTROL_ENABLE_MASK +#define MAC_SLEEP_CONTROL_ENABLE_GET(x) WLAN_MAC_SLEEP_CONTROL_ENABLE_GET(x) +#define MAC_SLEEP_CONTROL_ENABLE_SET(x) WLAN_MAC_SLEEP_CONTROL_ENABLE_SET(x) +#define KEEP_AWAKE_ADDRESS WLAN_KEEP_AWAKE_ADDRESS +#define KEEP_AWAKE_OFFSET WLAN_KEEP_AWAKE_OFFSET +#define KEEP_AWAKE_COUNT_MSB WLAN_KEEP_AWAKE_COUNT_MSB +#define KEEP_AWAKE_COUNT_LSB WLAN_KEEP_AWAKE_COUNT_LSB +#define KEEP_AWAKE_COUNT_MASK WLAN_KEEP_AWAKE_COUNT_MASK +#define KEEP_AWAKE_COUNT_GET(x) WLAN_KEEP_AWAKE_COUNT_GET(x) +#define KEEP_AWAKE_COUNT_SET(x) WLAN_KEEP_AWAKE_COUNT_SET(x) +#define LPO_CAL_TIME_ADDRESS WLAN_LPO_CAL_TIME_ADDRESS +#define LPO_CAL_TIME_OFFSET WLAN_LPO_CAL_TIME_OFFSET +#define LPO_CAL_TIME_LENGTH_MSB WLAN_LPO_CAL_TIME_LENGTH_MSB +#define LPO_CAL_TIME_LENGTH_LSB WLAN_LPO_CAL_TIME_LENGTH_LSB +#define LPO_CAL_TIME_LENGTH_MASK WLAN_LPO_CAL_TIME_LENGTH_MASK +#define LPO_CAL_TIME_LENGTH_GET(x) WLAN_LPO_CAL_TIME_LENGTH_GET(x) +#define LPO_CAL_TIME_LENGTH_SET(x) WLAN_LPO_CAL_TIME_LENGTH_SET(x) +#define LPO_INIT_DIVIDEND_INT_ADDRESS WLAN_LPO_INIT_DIVIDEND_INT_ADDRESS +#define LPO_INIT_DIVIDEND_INT_OFFSET WLAN_LPO_INIT_DIVIDEND_INT_OFFSET +#define LPO_INIT_DIVIDEND_INT_VALUE_MSB WLAN_LPO_INIT_DIVIDEND_INT_VALUE_MSB +#define LPO_INIT_DIVIDEND_INT_VALUE_LSB WLAN_LPO_INIT_DIVIDEND_INT_VALUE_LSB +#define LPO_INIT_DIVIDEND_INT_VALUE_MASK WLAN_LPO_INIT_DIVIDEND_INT_VALUE_MASK +#define LPO_INIT_DIVIDEND_INT_VALUE_GET(x) WLAN_LPO_INIT_DIVIDEND_INT_VALUE_GET(x) +#define LPO_INIT_DIVIDEND_INT_VALUE_SET(x) WLAN_LPO_INIT_DIVIDEND_INT_VALUE_SET(x) +#define LPO_INIT_DIVIDEND_FRACTION_ADDRESS WLAN_LPO_INIT_DIVIDEND_FRACTION_ADDRESS +#define LPO_INIT_DIVIDEND_FRACTION_OFFSET WLAN_LPO_INIT_DIVIDEND_FRACTION_OFFSET +#define LPO_INIT_DIVIDEND_FRACTION_VALUE_MSB WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_MSB +#define LPO_INIT_DIVIDEND_FRACTION_VALUE_LSB WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_LSB +#define LPO_INIT_DIVIDEND_FRACTION_VALUE_MASK WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_MASK +#define LPO_INIT_DIVIDEND_FRACTION_VALUE_GET(x) WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_GET(x) +#define LPO_INIT_DIVIDEND_FRACTION_VALUE_SET(x) WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_SET(x) +#define LPO_CAL_ADDRESS WLAN_LPO_CAL_ADDRESS +#define LPO_CAL_OFFSET WLAN_LPO_CAL_OFFSET +#define LPO_CAL_ENABLE_MSB WLAN_LPO_CAL_ENABLE_MSB +#define LPO_CAL_ENABLE_LSB WLAN_LPO_CAL_ENABLE_LSB +#define LPO_CAL_ENABLE_MASK WLAN_LPO_CAL_ENABLE_MASK +#define LPO_CAL_ENABLE_GET(x) WLAN_LPO_CAL_ENABLE_GET(x) +#define LPO_CAL_ENABLE_SET(x) WLAN_LPO_CAL_ENABLE_SET(x) +#define LPO_CAL_COUNT_MSB WLAN_LPO_CAL_COUNT_MSB +#define LPO_CAL_COUNT_LSB WLAN_LPO_CAL_COUNT_LSB +#define LPO_CAL_COUNT_MASK WLAN_LPO_CAL_COUNT_MASK +#define LPO_CAL_COUNT_GET(x) WLAN_LPO_CAL_COUNT_GET(x) +#define LPO_CAL_COUNT_SET(x) WLAN_LPO_CAL_COUNT_SET(x) +#define LPO_CAL_TEST_CONTROL_ADDRESS WLAN_LPO_CAL_TEST_CONTROL_ADDRESS +#define LPO_CAL_TEST_CONTROL_OFFSET WLAN_LPO_CAL_TEST_CONTROL_OFFSET +#define LPO_CAL_TEST_CONTROL_ENABLE_MSB WLAN_LPO_CAL_TEST_CONTROL_ENABLE_MSB +#define LPO_CAL_TEST_CONTROL_ENABLE_LSB WLAN_LPO_CAL_TEST_CONTROL_ENABLE_LSB +#define LPO_CAL_TEST_CONTROL_ENABLE_MASK WLAN_LPO_CAL_TEST_CONTROL_ENABLE_MASK +#define LPO_CAL_TEST_CONTROL_ENABLE_GET(x) WLAN_LPO_CAL_TEST_CONTROL_ENABLE_GET(x) +#define LPO_CAL_TEST_CONTROL_ENABLE_SET(x) WLAN_LPO_CAL_TEST_CONTROL_ENABLE_SET(x) +#define LPO_CAL_TEST_CONTROL_RTC_CYCLES_MSB WLAN_LPO_CAL_TEST_CONTROL_RTC_CYCLES_MSB +#define LPO_CAL_TEST_CONTROL_RTC_CYCLES_LSB WLAN_LPO_CAL_TEST_CONTROL_RTC_CYCLES_LSB +#define LPO_CAL_TEST_CONTROL_RTC_CYCLES_MASK WLAN_LPO_CAL_TEST_CONTROL_RTC_CYCLES_MASK +#define LPO_CAL_TEST_CONTROL_RTC_CYCLES_GET(x) WLAN_LPO_CAL_TEST_CONTROL_RTC_CYCLES_GET(x) +#define LPO_CAL_TEST_CONTROL_RTC_CYCLES_SET(x) WLAN_LPO_CAL_TEST_CONTROL_RTC_CYCLES_SET(x) +#define LPO_CAL_TEST_STATUS_ADDRESS WLAN_LPO_CAL_TEST_STATUS_ADDRESS +#define LPO_CAL_TEST_STATUS_OFFSET WLAN_LPO_CAL_TEST_STATUS_OFFSET +#define LPO_CAL_TEST_STATUS_READY_MSB WLAN_LPO_CAL_TEST_STATUS_READY_MSB +#define LPO_CAL_TEST_STATUS_READY_LSB WLAN_LPO_CAL_TEST_STATUS_READY_LSB +#define LPO_CAL_TEST_STATUS_READY_MASK WLAN_LPO_CAL_TEST_STATUS_READY_MASK +#define LPO_CAL_TEST_STATUS_READY_GET(x) WLAN_LPO_CAL_TEST_STATUS_READY_GET(x) +#define LPO_CAL_TEST_STATUS_READY_SET(x) WLAN_LPO_CAL_TEST_STATUS_READY_SET(x) +#define LPO_CAL_TEST_STATUS_COUNT_MSB WLAN_LPO_CAL_TEST_STATUS_COUNT_MSB +#define LPO_CAL_TEST_STATUS_COUNT_LSB WLAN_LPO_CAL_TEST_STATUS_COUNT_LSB +#define LPO_CAL_TEST_STATUS_COUNT_MASK WLAN_LPO_CAL_TEST_STATUS_COUNT_MASK +#define LPO_CAL_TEST_STATUS_COUNT_GET(x) WLAN_LPO_CAL_TEST_STATUS_COUNT_GET(x) +#define LPO_CAL_TEST_STATUS_COUNT_SET(x) WLAN_LPO_CAL_TEST_STATUS_COUNT_SET(x) +#define CHIP_ID_ADDRESS WLAN_CHIP_ID_ADDRESS +#define CHIP_ID_OFFSET WLAN_CHIP_ID_OFFSET +#define CHIP_ID_DEVICE_ID_MSB WLAN_CHIP_ID_DEVICE_ID_MSB +#define CHIP_ID_DEVICE_ID_LSB WLAN_CHIP_ID_DEVICE_ID_LSB +#define CHIP_ID_DEVICE_ID_MASK WLAN_CHIP_ID_DEVICE_ID_MASK +#define CHIP_ID_DEVICE_ID_GET(x) WLAN_CHIP_ID_DEVICE_ID_GET(x) +#define CHIP_ID_DEVICE_ID_SET(x) WLAN_CHIP_ID_DEVICE_ID_SET(x) +#define CHIP_ID_CONFIG_ID_MSB WLAN_CHIP_ID_CONFIG_ID_MSB +#define CHIP_ID_CONFIG_ID_LSB WLAN_CHIP_ID_CONFIG_ID_LSB +#define CHIP_ID_CONFIG_ID_MASK WLAN_CHIP_ID_CONFIG_ID_MASK +#define CHIP_ID_CONFIG_ID_GET(x) WLAN_CHIP_ID_CONFIG_ID_GET(x) +#define CHIP_ID_CONFIG_ID_SET(x) WLAN_CHIP_ID_CONFIG_ID_SET(x) +#define CHIP_ID_VERSION_ID_MSB WLAN_CHIP_ID_VERSION_ID_MSB +#define CHIP_ID_VERSION_ID_LSB WLAN_CHIP_ID_VERSION_ID_LSB +#define CHIP_ID_VERSION_ID_MASK WLAN_CHIP_ID_VERSION_ID_MASK +#define CHIP_ID_VERSION_ID_GET(x) WLAN_CHIP_ID_VERSION_ID_GET(x) +#define CHIP_ID_VERSION_ID_SET(x) WLAN_CHIP_ID_VERSION_ID_SET(x) +#define DERIVED_RTC_CLK_ADDRESS WLAN_DERIVED_RTC_CLK_ADDRESS +#define DERIVED_RTC_CLK_OFFSET WLAN_DERIVED_RTC_CLK_OFFSET +#define DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_MSB WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_MSB +#define DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_LSB WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_LSB +#define DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_MASK WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_MASK +#define DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_GET(x) WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_GET(x) +#define DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_SET(x) WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_SET(x) +#define DERIVED_RTC_CLK_EXTERNAL_DETECT_MSB WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_MSB +#define DERIVED_RTC_CLK_EXTERNAL_DETECT_LSB WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_LSB +#define DERIVED_RTC_CLK_EXTERNAL_DETECT_MASK WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_MASK +#define DERIVED_RTC_CLK_EXTERNAL_DETECT_GET(x) WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_GET(x) +#define DERIVED_RTC_CLK_EXTERNAL_DETECT_SET(x) WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_SET(x) +#define DERIVED_RTC_CLK_FORCE_MSB WLAN_DERIVED_RTC_CLK_FORCE_MSB +#define DERIVED_RTC_CLK_FORCE_LSB WLAN_DERIVED_RTC_CLK_FORCE_LSB +#define DERIVED_RTC_CLK_FORCE_MASK WLAN_DERIVED_RTC_CLK_FORCE_MASK +#define DERIVED_RTC_CLK_FORCE_GET(x) WLAN_DERIVED_RTC_CLK_FORCE_GET(x) +#define DERIVED_RTC_CLK_FORCE_SET(x) WLAN_DERIVED_RTC_CLK_FORCE_SET(x) +#define DERIVED_RTC_CLK_PERIOD_MSB WLAN_DERIVED_RTC_CLK_PERIOD_MSB +#define DERIVED_RTC_CLK_PERIOD_LSB WLAN_DERIVED_RTC_CLK_PERIOD_LSB +#define DERIVED_RTC_CLK_PERIOD_MASK WLAN_DERIVED_RTC_CLK_PERIOD_MASK +#define DERIVED_RTC_CLK_PERIOD_GET(x) WLAN_DERIVED_RTC_CLK_PERIOD_GET(x) +#define DERIVED_RTC_CLK_PERIOD_SET(x) WLAN_DERIVED_RTC_CLK_PERIOD_SET(x) +#define POWER_REG_ADDRESS WLAN_POWER_REG_ADDRESS +#define POWER_REG_OFFSET WLAN_POWER_REG_OFFSET +#define POWER_REG_SLEEP_MAKE_N_BREAK_EN_MSB WLAN_POWER_REG_SLEEP_MAKE_N_BREAK_EN_MSB +#define POWER_REG_SLEEP_MAKE_N_BREAK_EN_LSB WLAN_POWER_REG_SLEEP_MAKE_N_BREAK_EN_LSB +#define POWER_REG_SLEEP_MAKE_N_BREAK_EN_MASK WLAN_POWER_REG_SLEEP_MAKE_N_BREAK_EN_MASK +#define POWER_REG_SLEEP_MAKE_N_BREAK_EN_GET(x) WLAN_POWER_REG_SLEEP_MAKE_N_BREAK_EN_GET(x) +#define POWER_REG_SLEEP_MAKE_N_BREAK_EN_SET(x) WLAN_POWER_REG_SLEEP_MAKE_N_BREAK_EN_SET(x) +#define POWER_REG_DEBUG_EN_MSB WLAN_POWER_REG_DEBUG_EN_MSB +#define POWER_REG_DEBUG_EN_LSB WLAN_POWER_REG_DEBUG_EN_LSB +#define POWER_REG_DEBUG_EN_MASK WLAN_POWER_REG_DEBUG_EN_MASK +#define POWER_REG_DEBUG_EN_GET(x) WLAN_POWER_REG_DEBUG_EN_GET(x) +#define POWER_REG_DEBUG_EN_SET(x) WLAN_POWER_REG_DEBUG_EN_SET(x) +#define POWER_REG_WLAN_BB_PWD_EN_MSB WLAN_POWER_REG_WLAN_BB_PWD_EN_MSB +#define POWER_REG_WLAN_BB_PWD_EN_LSB WLAN_POWER_REG_WLAN_BB_PWD_EN_LSB +#define POWER_REG_WLAN_BB_PWD_EN_MASK WLAN_POWER_REG_WLAN_BB_PWD_EN_MASK +#define POWER_REG_WLAN_BB_PWD_EN_GET(x) WLAN_POWER_REG_WLAN_BB_PWD_EN_GET(x) +#define POWER_REG_WLAN_BB_PWD_EN_SET(x) WLAN_POWER_REG_WLAN_BB_PWD_EN_SET(x) +#define POWER_REG_WLAN_MAC_PWD_EN_MSB WLAN_POWER_REG_WLAN_MAC_PWD_EN_MSB +#define POWER_REG_WLAN_MAC_PWD_EN_LSB WLAN_POWER_REG_WLAN_MAC_PWD_EN_LSB +#define POWER_REG_WLAN_MAC_PWD_EN_MASK WLAN_POWER_REG_WLAN_MAC_PWD_EN_MASK +#define POWER_REG_WLAN_MAC_PWD_EN_GET(x) WLAN_POWER_REG_WLAN_MAC_PWD_EN_GET(x) +#define POWER_REG_WLAN_MAC_PWD_EN_SET(x) WLAN_POWER_REG_WLAN_MAC_PWD_EN_SET(x) +#define POWER_REG_VLVL_MSB WLAN_POWER_REG_VLVL_MSB +#define POWER_REG_VLVL_LSB WLAN_POWER_REG_VLVL_LSB +#define POWER_REG_VLVL_MASK WLAN_POWER_REG_VLVL_MASK +#define POWER_REG_VLVL_GET(x) WLAN_POWER_REG_VLVL_GET(x) +#define POWER_REG_VLVL_SET(x) WLAN_POWER_REG_VLVL_SET(x) +#define POWER_REG_CPU_INT_ENABLE_MSB WLAN_POWER_REG_CPU_INT_ENABLE_MSB +#define POWER_REG_CPU_INT_ENABLE_LSB WLAN_POWER_REG_CPU_INT_ENABLE_LSB +#define POWER_REG_CPU_INT_ENABLE_MASK WLAN_POWER_REG_CPU_INT_ENABLE_MASK +#define POWER_REG_CPU_INT_ENABLE_GET(x) WLAN_POWER_REG_CPU_INT_ENABLE_GET(x) +#define POWER_REG_CPU_INT_ENABLE_SET(x) WLAN_POWER_REG_CPU_INT_ENABLE_SET(x) +#define POWER_REG_WLAN_ISO_DIS_MSB WLAN_POWER_REG_WLAN_ISO_DIS_MSB +#define POWER_REG_WLAN_ISO_DIS_LSB WLAN_POWER_REG_WLAN_ISO_DIS_LSB +#define POWER_REG_WLAN_ISO_DIS_MASK WLAN_POWER_REG_WLAN_ISO_DIS_MASK +#define POWER_REG_WLAN_ISO_DIS_GET(x) WLAN_POWER_REG_WLAN_ISO_DIS_GET(x) +#define POWER_REG_WLAN_ISO_DIS_SET(x) WLAN_POWER_REG_WLAN_ISO_DIS_SET(x) +#define POWER_REG_WLAN_ISO_CNTL_MSB WLAN_POWER_REG_WLAN_ISO_CNTL_MSB +#define POWER_REG_WLAN_ISO_CNTL_LSB WLAN_POWER_REG_WLAN_ISO_CNTL_LSB +#define POWER_REG_WLAN_ISO_CNTL_MASK WLAN_POWER_REG_WLAN_ISO_CNTL_MASK +#define POWER_REG_WLAN_ISO_CNTL_GET(x) WLAN_POWER_REG_WLAN_ISO_CNTL_GET(x) +#define POWER_REG_WLAN_ISO_CNTL_SET(x) WLAN_POWER_REG_WLAN_ISO_CNTL_SET(x) +#define POWER_REG_RADIO_PWD_EN_MSB WLAN_POWER_REG_RADIO_PWD_EN_MSB +#define POWER_REG_RADIO_PWD_EN_LSB WLAN_POWER_REG_RADIO_PWD_EN_LSB +#define POWER_REG_RADIO_PWD_EN_MASK WLAN_POWER_REG_RADIO_PWD_EN_MASK +#define POWER_REG_RADIO_PWD_EN_GET(x) WLAN_POWER_REG_RADIO_PWD_EN_GET(x) +#define POWER_REG_RADIO_PWD_EN_SET(x) WLAN_POWER_REG_RADIO_PWD_EN_SET(x) +#define POWER_REG_SOC_ISO_EN_MSB WLAN_POWER_REG_SOC_ISO_EN_MSB +#define POWER_REG_SOC_ISO_EN_LSB WLAN_POWER_REG_SOC_ISO_EN_LSB +#define POWER_REG_SOC_ISO_EN_MASK WLAN_POWER_REG_SOC_ISO_EN_MASK +#define POWER_REG_SOC_ISO_EN_GET(x) WLAN_POWER_REG_SOC_ISO_EN_GET(x) +#define POWER_REG_SOC_ISO_EN_SET(x) WLAN_POWER_REG_SOC_ISO_EN_SET(x) +#define POWER_REG_WLAN_ISO_EN_MSB WLAN_POWER_REG_WLAN_ISO_EN_MSB +#define POWER_REG_WLAN_ISO_EN_LSB WLAN_POWER_REG_WLAN_ISO_EN_LSB +#define POWER_REG_WLAN_ISO_EN_MASK WLAN_POWER_REG_WLAN_ISO_EN_MASK +#define POWER_REG_WLAN_ISO_EN_GET(x) WLAN_POWER_REG_WLAN_ISO_EN_GET(x) +#define POWER_REG_WLAN_ISO_EN_SET(x) WLAN_POWER_REG_WLAN_ISO_EN_SET(x) +#define POWER_REG_WLAN_PWD_EN_MSB WLAN_POWER_REG_WLAN_PWD_EN_MSB +#define POWER_REG_WLAN_PWD_EN_LSB WLAN_POWER_REG_WLAN_PWD_EN_LSB +#define POWER_REG_WLAN_PWD_EN_MASK WLAN_POWER_REG_WLAN_PWD_EN_MASK +#define POWER_REG_WLAN_PWD_EN_GET(x) WLAN_POWER_REG_WLAN_PWD_EN_GET(x) +#define POWER_REG_WLAN_PWD_EN_SET(x) WLAN_POWER_REG_WLAN_PWD_EN_SET(x) +#define POWER_REG_POWER_EN_MSB WLAN_POWER_REG_POWER_EN_MSB +#define POWER_REG_POWER_EN_LSB WLAN_POWER_REG_POWER_EN_LSB +#define POWER_REG_POWER_EN_MASK WLAN_POWER_REG_POWER_EN_MASK +#define POWER_REG_POWER_EN_GET(x) WLAN_POWER_REG_POWER_EN_GET(x) +#define POWER_REG_POWER_EN_SET(x) WLAN_POWER_REG_POWER_EN_SET(x) +#define CORE_CLK_CTRL_ADDRESS WLAN_CORE_CLK_CTRL_ADDRESS +#define CORE_CLK_CTRL_OFFSET WLAN_CORE_CLK_CTRL_OFFSET +#define CORE_CLK_CTRL_DIV_MSB WLAN_CORE_CLK_CTRL_DIV_MSB +#define CORE_CLK_CTRL_DIV_LSB WLAN_CORE_CLK_CTRL_DIV_LSB +#define CORE_CLK_CTRL_DIV_MASK WLAN_CORE_CLK_CTRL_DIV_MASK +#define CORE_CLK_CTRL_DIV_GET(x) WLAN_CORE_CLK_CTRL_DIV_GET(x) +#define CORE_CLK_CTRL_DIV_SET(x) WLAN_CORE_CLK_CTRL_DIV_SET(x) +#define GPIO_WAKEUP_CONTROL_ADDRESS WLAN_GPIO_WAKEUP_CONTROL_ADDRESS +#define GPIO_WAKEUP_CONTROL_OFFSET WLAN_GPIO_WAKEUP_CONTROL_OFFSET +#define GPIO_WAKEUP_CONTROL_ENABLE_MSB WLAN_GPIO_WAKEUP_CONTROL_ENABLE_MSB +#define GPIO_WAKEUP_CONTROL_ENABLE_LSB WLAN_GPIO_WAKEUP_CONTROL_ENABLE_LSB +#define GPIO_WAKEUP_CONTROL_ENABLE_MASK WLAN_GPIO_WAKEUP_CONTROL_ENABLE_MASK +#define GPIO_WAKEUP_CONTROL_ENABLE_GET(x) WLAN_GPIO_WAKEUP_CONTROL_ENABLE_GET(x) +#define GPIO_WAKEUP_CONTROL_ENABLE_SET(x) WLAN_GPIO_WAKEUP_CONTROL_ENABLE_SET(x) + +#endif diff --git a/platform/mcu/lpc54102/wifi_qca/include/AR6002/hw4.0/hw/hw40_rtc_wlan_reg.h b/platform/mcu/lpc54102/wifi_qca/include/AR6002/hw4.0/hw/hw40_rtc_wlan_reg.h new file mode 100644 index 0000000000..ef178cfab6 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/include/AR6002/hw4.0/hw/hw40_rtc_wlan_reg.h @@ -0,0 +1,2212 @@ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== + +#ifndef _RTC_WLAN_REG_REG_H_ +#define _RTC_WLAN_REG_REG_H_ + +#define WLAN_RESET_CONTROL_ADDRESS 0x00000000 +#define WLAN_RESET_CONTROL_OFFSET 0x00000000 +#define WLAN_RESET_CONTROL_DEBUG_UART_RST_MSB 14 +#define WLAN_RESET_CONTROL_DEBUG_UART_RST_LSB 14 +#define WLAN_RESET_CONTROL_DEBUG_UART_RST_MASK 0x00004000 +#define WLAN_RESET_CONTROL_DEBUG_UART_RST_GET(x) \ + (((x)&WLAN_RESET_CONTROL_DEBUG_UART_RST_MASK) >> WLAN_RESET_CONTROL_DEBUG_UART_RST_LSB) +#define WLAN_RESET_CONTROL_DEBUG_UART_RST_SET(x) \ + (((x) << WLAN_RESET_CONTROL_DEBUG_UART_RST_LSB) & WLAN_RESET_CONTROL_DEBUG_UART_RST_MASK) +#define WLAN_RESET_CONTROL_BB_COLD_RST_MSB 13 +#define WLAN_RESET_CONTROL_BB_COLD_RST_LSB 13 +#define WLAN_RESET_CONTROL_BB_COLD_RST_MASK 0x00002000 +#define WLAN_RESET_CONTROL_BB_COLD_RST_GET(x) \ + (((x)&WLAN_RESET_CONTROL_BB_COLD_RST_MASK) >> WLAN_RESET_CONTROL_BB_COLD_RST_LSB) +#define WLAN_RESET_CONTROL_BB_COLD_RST_SET(x) \ + (((x) << WLAN_RESET_CONTROL_BB_COLD_RST_LSB) & WLAN_RESET_CONTROL_BB_COLD_RST_MASK) +#define WLAN_RESET_CONTROL_BB_WARM_RST_MSB 12 +#define WLAN_RESET_CONTROL_BB_WARM_RST_LSB 12 +#define WLAN_RESET_CONTROL_BB_WARM_RST_MASK 0x00001000 +#define WLAN_RESET_CONTROL_BB_WARM_RST_GET(x) \ + (((x)&WLAN_RESET_CONTROL_BB_WARM_RST_MASK) >> WLAN_RESET_CONTROL_BB_WARM_RST_LSB) +#define WLAN_RESET_CONTROL_BB_WARM_RST_SET(x) \ + (((x) << WLAN_RESET_CONTROL_BB_WARM_RST_LSB) & WLAN_RESET_CONTROL_BB_WARM_RST_MASK) +#define WLAN_RESET_CONTROL_CPU_INIT_RESET_MSB 11 +#define WLAN_RESET_CONTROL_CPU_INIT_RESET_LSB 11 +#define WLAN_RESET_CONTROL_CPU_INIT_RESET_MASK 0x00000800 +#define WLAN_RESET_CONTROL_CPU_INIT_RESET_GET(x) \ + (((x)&WLAN_RESET_CONTROL_CPU_INIT_RESET_MASK) >> WLAN_RESET_CONTROL_CPU_INIT_RESET_LSB) +#define WLAN_RESET_CONTROL_CPU_INIT_RESET_SET(x) \ + (((x) << WLAN_RESET_CONTROL_CPU_INIT_RESET_LSB) & WLAN_RESET_CONTROL_CPU_INIT_RESET_MASK) +#define WLAN_RESET_CONTROL_VMC_REMAP_RESET_MSB 10 +#define WLAN_RESET_CONTROL_VMC_REMAP_RESET_LSB 10 +#define WLAN_RESET_CONTROL_VMC_REMAP_RESET_MASK 0x00000400 +#define WLAN_RESET_CONTROL_VMC_REMAP_RESET_GET(x) \ + (((x)&WLAN_RESET_CONTROL_VMC_REMAP_RESET_MASK) >> WLAN_RESET_CONTROL_VMC_REMAP_RESET_LSB) +#define WLAN_RESET_CONTROL_VMC_REMAP_RESET_SET(x) \ + (((x) << WLAN_RESET_CONTROL_VMC_REMAP_RESET_LSB) & WLAN_RESET_CONTROL_VMC_REMAP_RESET_MASK) +#define WLAN_RESET_CONTROL_RST_OUT_MSB 9 +#define WLAN_RESET_CONTROL_RST_OUT_LSB 9 +#define WLAN_RESET_CONTROL_RST_OUT_MASK 0x00000200 +#define WLAN_RESET_CONTROL_RST_OUT_GET(x) (((x)&WLAN_RESET_CONTROL_RST_OUT_MASK) >> WLAN_RESET_CONTROL_RST_OUT_LSB) +#define WLAN_RESET_CONTROL_RST_OUT_SET(x) (((x) << WLAN_RESET_CONTROL_RST_OUT_LSB) & WLAN_RESET_CONTROL_RST_OUT_MASK) +#define WLAN_RESET_CONTROL_COLD_RST_MSB 8 +#define WLAN_RESET_CONTROL_COLD_RST_LSB 8 +#define WLAN_RESET_CONTROL_COLD_RST_MASK 0x00000100 +#define WLAN_RESET_CONTROL_COLD_RST_GET(x) (((x)&WLAN_RESET_CONTROL_COLD_RST_MASK) >> WLAN_RESET_CONTROL_COLD_RST_LSB) +#define WLAN_RESET_CONTROL_COLD_RST_SET(x) (((x) << WLAN_RESET_CONTROL_COLD_RST_LSB) & WLAN_RESET_CONTROL_COLD_RST_MASK) +#define WLAN_RESET_CONTROL_WARM_RST_MSB 7 +#define WLAN_RESET_CONTROL_WARM_RST_LSB 7 +#define WLAN_RESET_CONTROL_WARM_RST_MASK 0x00000080 +#define WLAN_RESET_CONTROL_WARM_RST_GET(x) (((x)&WLAN_RESET_CONTROL_WARM_RST_MASK) >> WLAN_RESET_CONTROL_WARM_RST_LSB) +#define WLAN_RESET_CONTROL_WARM_RST_SET(x) (((x) << WLAN_RESET_CONTROL_WARM_RST_LSB) & WLAN_RESET_CONTROL_WARM_RST_MASK) +#define WLAN_RESET_CONTROL_CPU_WARM_RST_MSB 6 +#define WLAN_RESET_CONTROL_CPU_WARM_RST_LSB 6 +#define WLAN_RESET_CONTROL_CPU_WARM_RST_MASK 0x00000040 +#define WLAN_RESET_CONTROL_CPU_WARM_RST_GET(x) \ + (((x)&WLAN_RESET_CONTROL_CPU_WARM_RST_MASK) >> WLAN_RESET_CONTROL_CPU_WARM_RST_LSB) +#define WLAN_RESET_CONTROL_CPU_WARM_RST_SET(x) \ + (((x) << WLAN_RESET_CONTROL_CPU_WARM_RST_LSB) & WLAN_RESET_CONTROL_CPU_WARM_RST_MASK) +#define WLAN_RESET_CONTROL_MAC_COLD_RST_MSB 5 +#define WLAN_RESET_CONTROL_MAC_COLD_RST_LSB 5 +#define WLAN_RESET_CONTROL_MAC_COLD_RST_MASK 0x00000020 +#define WLAN_RESET_CONTROL_MAC_COLD_RST_GET(x) \ + (((x)&WLAN_RESET_CONTROL_MAC_COLD_RST_MASK) >> WLAN_RESET_CONTROL_MAC_COLD_RST_LSB) +#define WLAN_RESET_CONTROL_MAC_COLD_RST_SET(x) \ + (((x) << WLAN_RESET_CONTROL_MAC_COLD_RST_LSB) & WLAN_RESET_CONTROL_MAC_COLD_RST_MASK) +#define WLAN_RESET_CONTROL_MAC_WARM_RST_MSB 4 +#define WLAN_RESET_CONTROL_MAC_WARM_RST_LSB 4 +#define WLAN_RESET_CONTROL_MAC_WARM_RST_MASK 0x00000010 +#define WLAN_RESET_CONTROL_MAC_WARM_RST_GET(x) \ + (((x)&WLAN_RESET_CONTROL_MAC_WARM_RST_MASK) >> WLAN_RESET_CONTROL_MAC_WARM_RST_LSB) +#define WLAN_RESET_CONTROL_MAC_WARM_RST_SET(x) \ + (((x) << WLAN_RESET_CONTROL_MAC_WARM_RST_LSB) & WLAN_RESET_CONTROL_MAC_WARM_RST_MASK) +#define WLAN_RESET_CONTROL_MBOX_RST_MSB 2 +#define WLAN_RESET_CONTROL_MBOX_RST_LSB 2 +#define WLAN_RESET_CONTROL_MBOX_RST_MASK 0x00000004 +#define WLAN_RESET_CONTROL_MBOX_RST_GET(x) (((x)&WLAN_RESET_CONTROL_MBOX_RST_MASK) >> WLAN_RESET_CONTROL_MBOX_RST_LSB) +#define WLAN_RESET_CONTROL_MBOX_RST_SET(x) (((x) << WLAN_RESET_CONTROL_MBOX_RST_LSB) & WLAN_RESET_CONTROL_MBOX_RST_MASK) +#define WLAN_RESET_CONTROL_UART_RST_MSB 1 +#define WLAN_RESET_CONTROL_UART_RST_LSB 1 +#define WLAN_RESET_CONTROL_UART_RST_MASK 0x00000002 +#define WLAN_RESET_CONTROL_UART_RST_GET(x) (((x)&WLAN_RESET_CONTROL_UART_RST_MASK) >> WLAN_RESET_CONTROL_UART_RST_LSB) +#define WLAN_RESET_CONTROL_UART_RST_SET(x) (((x) << WLAN_RESET_CONTROL_UART_RST_LSB) & WLAN_RESET_CONTROL_UART_RST_MASK) +#define WLAN_RESET_CONTROL_SI0_RST_MSB 0 +#define WLAN_RESET_CONTROL_SI0_RST_LSB 0 +#define WLAN_RESET_CONTROL_SI0_RST_MASK 0x00000001 +#define WLAN_RESET_CONTROL_SI0_RST_GET(x) (((x)&WLAN_RESET_CONTROL_SI0_RST_MASK) >> WLAN_RESET_CONTROL_SI0_RST_LSB) +#define WLAN_RESET_CONTROL_SI0_RST_SET(x) (((x) << WLAN_RESET_CONTROL_SI0_RST_LSB) & WLAN_RESET_CONTROL_SI0_RST_MASK) + +#define WLAN_XTAL_CONTROL_ADDRESS 0x00000004 +#define WLAN_XTAL_CONTROL_OFFSET 0x00000004 +#define WLAN_XTAL_CONTROL_TCXO_MSB 0 +#define WLAN_XTAL_CONTROL_TCXO_LSB 0 +#define WLAN_XTAL_CONTROL_TCXO_MASK 0x00000001 +#define WLAN_XTAL_CONTROL_TCXO_GET(x) (((x)&WLAN_XTAL_CONTROL_TCXO_MASK) >> WLAN_XTAL_CONTROL_TCXO_LSB) +#define WLAN_XTAL_CONTROL_TCXO_SET(x) (((x) << WLAN_XTAL_CONTROL_TCXO_LSB) & WLAN_XTAL_CONTROL_TCXO_MASK) + +#define WLAN_TCXO_DETECT_ADDRESS 0x00000008 +#define WLAN_TCXO_DETECT_OFFSET 0x00000008 +#define WLAN_TCXO_DETECT_PRESENT_MSB 0 +#define WLAN_TCXO_DETECT_PRESENT_LSB 0 +#define WLAN_TCXO_DETECT_PRESENT_MASK 0x00000001 +#define WLAN_TCXO_DETECT_PRESENT_GET(x) (((x)&WLAN_TCXO_DETECT_PRESENT_MASK) >> WLAN_TCXO_DETECT_PRESENT_LSB) +#define WLAN_TCXO_DETECT_PRESENT_SET(x) (((x) << WLAN_TCXO_DETECT_PRESENT_LSB) & WLAN_TCXO_DETECT_PRESENT_MASK) + +#define WLAN_XTAL_TEST_ADDRESS 0x0000000c +#define WLAN_XTAL_TEST_OFFSET 0x0000000c +#define WLAN_XTAL_TEST_NOTCXODET_MSB 0 +#define WLAN_XTAL_TEST_NOTCXODET_LSB 0 +#define WLAN_XTAL_TEST_NOTCXODET_MASK 0x00000001 +#define WLAN_XTAL_TEST_NOTCXODET_GET(x) (((x)&WLAN_XTAL_TEST_NOTCXODET_MASK) >> WLAN_XTAL_TEST_NOTCXODET_LSB) +#define WLAN_XTAL_TEST_NOTCXODET_SET(x) (((x) << WLAN_XTAL_TEST_NOTCXODET_LSB) & WLAN_XTAL_TEST_NOTCXODET_MASK) + +#define WLAN_QUADRATURE_ADDRESS 0x00000010 +#define WLAN_QUADRATURE_OFFSET 0x00000010 +#define WLAN_QUADRATURE_ADC_MSB 7 +#define WLAN_QUADRATURE_ADC_LSB 4 +#define WLAN_QUADRATURE_ADC_MASK 0x000000f0 +#define WLAN_QUADRATURE_ADC_GET(x) (((x)&WLAN_QUADRATURE_ADC_MASK) >> WLAN_QUADRATURE_ADC_LSB) +#define WLAN_QUADRATURE_ADC_SET(x) (((x) << WLAN_QUADRATURE_ADC_LSB) & WLAN_QUADRATURE_ADC_MASK) +#define WLAN_QUADRATURE_SEL_MSB 2 +#define WLAN_QUADRATURE_SEL_LSB 2 +#define WLAN_QUADRATURE_SEL_MASK 0x00000004 +#define WLAN_QUADRATURE_SEL_GET(x) (((x)&WLAN_QUADRATURE_SEL_MASK) >> WLAN_QUADRATURE_SEL_LSB) +#define WLAN_QUADRATURE_SEL_SET(x) (((x) << WLAN_QUADRATURE_SEL_LSB) & WLAN_QUADRATURE_SEL_MASK) +#define WLAN_QUADRATURE_DAC_MSB 1 +#define WLAN_QUADRATURE_DAC_LSB 0 +#define WLAN_QUADRATURE_DAC_MASK 0x00000003 +#define WLAN_QUADRATURE_DAC_GET(x) (((x)&WLAN_QUADRATURE_DAC_MASK) >> WLAN_QUADRATURE_DAC_LSB) +#define WLAN_QUADRATURE_DAC_SET(x) (((x) << WLAN_QUADRATURE_DAC_LSB) & WLAN_QUADRATURE_DAC_MASK) + +#define WLAN_PLL_CONTROL_ADDRESS 0x00000014 +#define WLAN_PLL_CONTROL_OFFSET 0x00000014 +#define WLAN_PLL_CONTROL_DIG_TEST_CLK_MSB 20 +#define WLAN_PLL_CONTROL_DIG_TEST_CLK_LSB 20 +#define WLAN_PLL_CONTROL_DIG_TEST_CLK_MASK 0x00100000 +#define WLAN_PLL_CONTROL_DIG_TEST_CLK_GET(x) \ + (((x)&WLAN_PLL_CONTROL_DIG_TEST_CLK_MASK) >> WLAN_PLL_CONTROL_DIG_TEST_CLK_LSB) +#define WLAN_PLL_CONTROL_DIG_TEST_CLK_SET(x) \ + (((x) << WLAN_PLL_CONTROL_DIG_TEST_CLK_LSB) & WLAN_PLL_CONTROL_DIG_TEST_CLK_MASK) +#define WLAN_PLL_CONTROL_MAC_OVERRIDE_MSB 19 +#define WLAN_PLL_CONTROL_MAC_OVERRIDE_LSB 19 +#define WLAN_PLL_CONTROL_MAC_OVERRIDE_MASK 0x00080000 +#define WLAN_PLL_CONTROL_MAC_OVERRIDE_GET(x) \ + (((x)&WLAN_PLL_CONTROL_MAC_OVERRIDE_MASK) >> WLAN_PLL_CONTROL_MAC_OVERRIDE_LSB) +#define WLAN_PLL_CONTROL_MAC_OVERRIDE_SET(x) \ + (((x) << WLAN_PLL_CONTROL_MAC_OVERRIDE_LSB) & WLAN_PLL_CONTROL_MAC_OVERRIDE_MASK) +#define WLAN_PLL_CONTROL_NOPWD_MSB 18 +#define WLAN_PLL_CONTROL_NOPWD_LSB 18 +#define WLAN_PLL_CONTROL_NOPWD_MASK 0x00040000 +#define WLAN_PLL_CONTROL_NOPWD_GET(x) (((x)&WLAN_PLL_CONTROL_NOPWD_MASK) >> WLAN_PLL_CONTROL_NOPWD_LSB) +#define WLAN_PLL_CONTROL_NOPWD_SET(x) (((x) << WLAN_PLL_CONTROL_NOPWD_LSB) & WLAN_PLL_CONTROL_NOPWD_MASK) +#define WLAN_PLL_CONTROL_UPDATING_MSB 17 +#define WLAN_PLL_CONTROL_UPDATING_LSB 17 +#define WLAN_PLL_CONTROL_UPDATING_MASK 0x00020000 +#define WLAN_PLL_CONTROL_UPDATING_GET(x) (((x)&WLAN_PLL_CONTROL_UPDATING_MASK) >> WLAN_PLL_CONTROL_UPDATING_LSB) +#define WLAN_PLL_CONTROL_UPDATING_SET(x) (((x) << WLAN_PLL_CONTROL_UPDATING_LSB) & WLAN_PLL_CONTROL_UPDATING_MASK) +#define WLAN_PLL_CONTROL_BYPASS_MSB 16 +#define WLAN_PLL_CONTROL_BYPASS_LSB 16 +#define WLAN_PLL_CONTROL_BYPASS_MASK 0x00010000 +#define WLAN_PLL_CONTROL_BYPASS_GET(x) (((x)&WLAN_PLL_CONTROL_BYPASS_MASK) >> WLAN_PLL_CONTROL_BYPASS_LSB) +#define WLAN_PLL_CONTROL_BYPASS_SET(x) (((x) << WLAN_PLL_CONTROL_BYPASS_LSB) & WLAN_PLL_CONTROL_BYPASS_MASK) +#define WLAN_PLL_CONTROL_REFDIV_MSB 15 +#define WLAN_PLL_CONTROL_REFDIV_LSB 12 +#define WLAN_PLL_CONTROL_REFDIV_MASK 0x0000f000 +#define WLAN_PLL_CONTROL_REFDIV_GET(x) (((x)&WLAN_PLL_CONTROL_REFDIV_MASK) >> WLAN_PLL_CONTROL_REFDIV_LSB) +#define WLAN_PLL_CONTROL_REFDIV_SET(x) (((x) << WLAN_PLL_CONTROL_REFDIV_LSB) & WLAN_PLL_CONTROL_REFDIV_MASK) +#define WLAN_PLL_CONTROL_DIV_MSB 9 +#define WLAN_PLL_CONTROL_DIV_LSB 0 +#define WLAN_PLL_CONTROL_DIV_MASK 0x000003ff +#define WLAN_PLL_CONTROL_DIV_GET(x) (((x)&WLAN_PLL_CONTROL_DIV_MASK) >> WLAN_PLL_CONTROL_DIV_LSB) +#define WLAN_PLL_CONTROL_DIV_SET(x) (((x) << WLAN_PLL_CONTROL_DIV_LSB) & WLAN_PLL_CONTROL_DIV_MASK) + +#define WLAN_PLL_SETTLE_ADDRESS 0x00000018 +#define WLAN_PLL_SETTLE_OFFSET 0x00000018 +#define WLAN_PLL_SETTLE_TIME_MSB 11 +#define WLAN_PLL_SETTLE_TIME_LSB 0 +#define WLAN_PLL_SETTLE_TIME_MASK 0x00000fff +#define WLAN_PLL_SETTLE_TIME_GET(x) (((x)&WLAN_PLL_SETTLE_TIME_MASK) >> WLAN_PLL_SETTLE_TIME_LSB) +#define WLAN_PLL_SETTLE_TIME_SET(x) (((x) << WLAN_PLL_SETTLE_TIME_LSB) & WLAN_PLL_SETTLE_TIME_MASK) + +#define WLAN_XTAL_SETTLE_ADDRESS 0x0000001c +#define WLAN_XTAL_SETTLE_OFFSET 0x0000001c +#define WLAN_XTAL_SETTLE_TIME_MSB 7 +#define WLAN_XTAL_SETTLE_TIME_LSB 0 +#define WLAN_XTAL_SETTLE_TIME_MASK 0x000000ff +#define WLAN_XTAL_SETTLE_TIME_GET(x) (((x)&WLAN_XTAL_SETTLE_TIME_MASK) >> WLAN_XTAL_SETTLE_TIME_LSB) +#define WLAN_XTAL_SETTLE_TIME_SET(x) (((x) << WLAN_XTAL_SETTLE_TIME_LSB) & WLAN_XTAL_SETTLE_TIME_MASK) + +#define WLAN_CPU_CLOCK_ADDRESS 0x00000020 +#define WLAN_CPU_CLOCK_OFFSET 0x00000020 +#define WLAN_CPU_CLOCK_STANDARD_MSB 1 +#define WLAN_CPU_CLOCK_STANDARD_LSB 0 +#define WLAN_CPU_CLOCK_STANDARD_MASK 0x00000003 +#define WLAN_CPU_CLOCK_STANDARD_GET(x) (((x)&WLAN_CPU_CLOCK_STANDARD_MASK) >> WLAN_CPU_CLOCK_STANDARD_LSB) +#define WLAN_CPU_CLOCK_STANDARD_SET(x) (((x) << WLAN_CPU_CLOCK_STANDARD_LSB) & WLAN_CPU_CLOCK_STANDARD_MASK) + +#define WLAN_CLOCK_OUT_ADDRESS 0x00000024 +#define WLAN_CLOCK_OUT_OFFSET 0x00000024 +#define WLAN_CLOCK_OUT_SELECT_MSB 3 +#define WLAN_CLOCK_OUT_SELECT_LSB 0 +#define WLAN_CLOCK_OUT_SELECT_MASK 0x0000000f +#define WLAN_CLOCK_OUT_SELECT_GET(x) (((x)&WLAN_CLOCK_OUT_SELECT_MASK) >> WLAN_CLOCK_OUT_SELECT_LSB) +#define WLAN_CLOCK_OUT_SELECT_SET(x) (((x) << WLAN_CLOCK_OUT_SELECT_LSB) & WLAN_CLOCK_OUT_SELECT_MASK) + +#define WLAN_CLOCK_CONTROL_ADDRESS 0x00000028 +#define WLAN_CLOCK_CONTROL_OFFSET 0x00000028 +#define WLAN_CLOCK_CONTROL_LF_CLK32_MSB 2 +#define WLAN_CLOCK_CONTROL_LF_CLK32_LSB 2 +#define WLAN_CLOCK_CONTROL_LF_CLK32_MASK 0x00000004 +#define WLAN_CLOCK_CONTROL_LF_CLK32_GET(x) (((x)&WLAN_CLOCK_CONTROL_LF_CLK32_MASK) >> WLAN_CLOCK_CONTROL_LF_CLK32_LSB) +#define WLAN_CLOCK_CONTROL_LF_CLK32_SET(x) (((x) << WLAN_CLOCK_CONTROL_LF_CLK32_LSB) & WLAN_CLOCK_CONTROL_LF_CLK32_MASK) +#define WLAN_CLOCK_CONTROL_SI0_CLK_MSB 0 +#define WLAN_CLOCK_CONTROL_SI0_CLK_LSB 0 +#define WLAN_CLOCK_CONTROL_SI0_CLK_MASK 0x00000001 +#define WLAN_CLOCK_CONTROL_SI0_CLK_GET(x) (((x)&WLAN_CLOCK_CONTROL_SI0_CLK_MASK) >> WLAN_CLOCK_CONTROL_SI0_CLK_LSB) +#define WLAN_CLOCK_CONTROL_SI0_CLK_SET(x) (((x) << WLAN_CLOCK_CONTROL_SI0_CLK_LSB) & WLAN_CLOCK_CONTROL_SI0_CLK_MASK) + +#define WLAN_BIAS_OVERRIDE_ADDRESS 0x0000002c +#define WLAN_BIAS_OVERRIDE_OFFSET 0x0000002c +#define WLAN_BIAS_OVERRIDE_ON_MSB 0 +#define WLAN_BIAS_OVERRIDE_ON_LSB 0 +#define WLAN_BIAS_OVERRIDE_ON_MASK 0x00000001 +#define WLAN_BIAS_OVERRIDE_ON_GET(x) (((x)&WLAN_BIAS_OVERRIDE_ON_MASK) >> WLAN_BIAS_OVERRIDE_ON_LSB) +#define WLAN_BIAS_OVERRIDE_ON_SET(x) (((x) << WLAN_BIAS_OVERRIDE_ON_LSB) & WLAN_BIAS_OVERRIDE_ON_MASK) + +#define WLAN_WDT_CONTROL_ADDRESS 0x00000030 +#define WLAN_WDT_CONTROL_OFFSET 0x00000030 +#define WLAN_WDT_CONTROL_ACTION_MSB 2 +#define WLAN_WDT_CONTROL_ACTION_LSB 0 +#define WLAN_WDT_CONTROL_ACTION_MASK 0x00000007 +#define WLAN_WDT_CONTROL_ACTION_GET(x) (((x)&WLAN_WDT_CONTROL_ACTION_MASK) >> WLAN_WDT_CONTROL_ACTION_LSB) +#define WLAN_WDT_CONTROL_ACTION_SET(x) (((x) << WLAN_WDT_CONTROL_ACTION_LSB) & WLAN_WDT_CONTROL_ACTION_MASK) + +#define WLAN_WDT_STATUS_ADDRESS 0x00000034 +#define WLAN_WDT_STATUS_OFFSET 0x00000034 +#define WLAN_WDT_STATUS_INTERRUPT_MSB 0 +#define WLAN_WDT_STATUS_INTERRUPT_LSB 0 +#define WLAN_WDT_STATUS_INTERRUPT_MASK 0x00000001 +#define WLAN_WDT_STATUS_INTERRUPT_GET(x) (((x)&WLAN_WDT_STATUS_INTERRUPT_MASK) >> WLAN_WDT_STATUS_INTERRUPT_LSB) +#define WLAN_WDT_STATUS_INTERRUPT_SET(x) (((x) << WLAN_WDT_STATUS_INTERRUPT_LSB) & WLAN_WDT_STATUS_INTERRUPT_MASK) + +#define WLAN_WDT_ADDRESS 0x00000038 +#define WLAN_WDT_OFFSET 0x00000038 +#define WLAN_WDT_TARGET_MSB 21 +#define WLAN_WDT_TARGET_LSB 0 +#define WLAN_WDT_TARGET_MASK 0x003fffff +#define WLAN_WDT_TARGET_GET(x) (((x)&WLAN_WDT_TARGET_MASK) >> WLAN_WDT_TARGET_LSB) +#define WLAN_WDT_TARGET_SET(x) (((x) << WLAN_WDT_TARGET_LSB) & WLAN_WDT_TARGET_MASK) + +#define WLAN_WDT_COUNT_ADDRESS 0x0000003c +#define WLAN_WDT_COUNT_OFFSET 0x0000003c +#define WLAN_WDT_COUNT_VALUE_MSB 21 +#define WLAN_WDT_COUNT_VALUE_LSB 0 +#define WLAN_WDT_COUNT_VALUE_MASK 0x003fffff +#define WLAN_WDT_COUNT_VALUE_GET(x) (((x)&WLAN_WDT_COUNT_VALUE_MASK) >> WLAN_WDT_COUNT_VALUE_LSB) +#define WLAN_WDT_COUNT_VALUE_SET(x) (((x) << WLAN_WDT_COUNT_VALUE_LSB) & WLAN_WDT_COUNT_VALUE_MASK) + +#define WLAN_WDT_RESET_ADDRESS 0x00000040 +#define WLAN_WDT_RESET_OFFSET 0x00000040 +#define WLAN_WDT_RESET_VALUE_MSB 0 +#define WLAN_WDT_RESET_VALUE_LSB 0 +#define WLAN_WDT_RESET_VALUE_MASK 0x00000001 +#define WLAN_WDT_RESET_VALUE_GET(x) (((x)&WLAN_WDT_RESET_VALUE_MASK) >> WLAN_WDT_RESET_VALUE_LSB) +#define WLAN_WDT_RESET_VALUE_SET(x) (((x) << WLAN_WDT_RESET_VALUE_LSB) & WLAN_WDT_RESET_VALUE_MASK) + +#define WLAN_INT_STATUS_ADDRESS 0x00000044 +#define WLAN_INT_STATUS_OFFSET 0x00000044 +#define WLAN_INT_STATUS_HCI_UART_MSB 21 +#define WLAN_INT_STATUS_HCI_UART_LSB 21 +#define WLAN_INT_STATUS_HCI_UART_MASK 0x00200000 +#define WLAN_INT_STATUS_HCI_UART_GET(x) (((x)&WLAN_INT_STATUS_HCI_UART_MASK) >> WLAN_INT_STATUS_HCI_UART_LSB) +#define WLAN_INT_STATUS_HCI_UART_SET(x) (((x) << WLAN_INT_STATUS_HCI_UART_LSB) & WLAN_INT_STATUS_HCI_UART_MASK) +#define WLAN_INT_STATUS_THERM_MSB 20 +#define WLAN_INT_STATUS_THERM_LSB 20 +#define WLAN_INT_STATUS_THERM_MASK 0x00100000 +#define WLAN_INT_STATUS_THERM_GET(x) (((x)&WLAN_INT_STATUS_THERM_MASK) >> WLAN_INT_STATUS_THERM_LSB) +#define WLAN_INT_STATUS_THERM_SET(x) (((x) << WLAN_INT_STATUS_THERM_LSB) & WLAN_INT_STATUS_THERM_MASK) +#define WLAN_INT_STATUS_EFUSE_OVERWRITE_MSB 19 +#define WLAN_INT_STATUS_EFUSE_OVERWRITE_LSB 19 +#define WLAN_INT_STATUS_EFUSE_OVERWRITE_MASK 0x00080000 +#define WLAN_INT_STATUS_EFUSE_OVERWRITE_GET(x) \ + (((x)&WLAN_INT_STATUS_EFUSE_OVERWRITE_MASK) >> WLAN_INT_STATUS_EFUSE_OVERWRITE_LSB) +#define WLAN_INT_STATUS_EFUSE_OVERWRITE_SET(x) \ + (((x) << WLAN_INT_STATUS_EFUSE_OVERWRITE_LSB) & WLAN_INT_STATUS_EFUSE_OVERWRITE_MASK) +#define WLAN_INT_STATUS_UART_MBOX_MSB 18 +#define WLAN_INT_STATUS_UART_MBOX_LSB 18 +#define WLAN_INT_STATUS_UART_MBOX_MASK 0x00040000 +#define WLAN_INT_STATUS_UART_MBOX_GET(x) (((x)&WLAN_INT_STATUS_UART_MBOX_MASK) >> WLAN_INT_STATUS_UART_MBOX_LSB) +#define WLAN_INT_STATUS_UART_MBOX_SET(x) (((x) << WLAN_INT_STATUS_UART_MBOX_LSB) & WLAN_INT_STATUS_UART_MBOX_MASK) +#define WLAN_INT_STATUS_GENERIC_MBOX_MSB 17 +#define WLAN_INT_STATUS_GENERIC_MBOX_LSB 17 +#define WLAN_INT_STATUS_GENERIC_MBOX_MASK 0x00020000 +#define WLAN_INT_STATUS_GENERIC_MBOX_GET(x) \ + (((x)&WLAN_INT_STATUS_GENERIC_MBOX_MASK) >> WLAN_INT_STATUS_GENERIC_MBOX_LSB) +#define WLAN_INT_STATUS_GENERIC_MBOX_SET(x) \ + (((x) << WLAN_INT_STATUS_GENERIC_MBOX_LSB) & WLAN_INT_STATUS_GENERIC_MBOX_MASK) +#define WLAN_INT_STATUS_RDMA_MSB 16 +#define WLAN_INT_STATUS_RDMA_LSB 16 +#define WLAN_INT_STATUS_RDMA_MASK 0x00010000 +#define WLAN_INT_STATUS_RDMA_GET(x) (((x)&WLAN_INT_STATUS_RDMA_MASK) >> WLAN_INT_STATUS_RDMA_LSB) +#define WLAN_INT_STATUS_RDMA_SET(x) (((x) << WLAN_INT_STATUS_RDMA_LSB) & WLAN_INT_STATUS_RDMA_MASK) +#define WLAN_INT_STATUS_BTCOEX_MSB 15 +#define WLAN_INT_STATUS_BTCOEX_LSB 15 +#define WLAN_INT_STATUS_BTCOEX_MASK 0x00008000 +#define WLAN_INT_STATUS_BTCOEX_GET(x) (((x)&WLAN_INT_STATUS_BTCOEX_MASK) >> WLAN_INT_STATUS_BTCOEX_LSB) +#define WLAN_INT_STATUS_BTCOEX_SET(x) (((x) << WLAN_INT_STATUS_BTCOEX_LSB) & WLAN_INT_STATUS_BTCOEX_MASK) +#define WLAN_INT_STATUS_RTC_POWER_MSB 14 +#define WLAN_INT_STATUS_RTC_POWER_LSB 14 +#define WLAN_INT_STATUS_RTC_POWER_MASK 0x00004000 +#define WLAN_INT_STATUS_RTC_POWER_GET(x) (((x)&WLAN_INT_STATUS_RTC_POWER_MASK) >> WLAN_INT_STATUS_RTC_POWER_LSB) +#define WLAN_INT_STATUS_RTC_POWER_SET(x) (((x) << WLAN_INT_STATUS_RTC_POWER_LSB) & WLAN_INT_STATUS_RTC_POWER_MASK) +#define WLAN_INT_STATUS_MAC_MSB 13 +#define WLAN_INT_STATUS_MAC_LSB 13 +#define WLAN_INT_STATUS_MAC_MASK 0x00002000 +#define WLAN_INT_STATUS_MAC_GET(x) (((x)&WLAN_INT_STATUS_MAC_MASK) >> WLAN_INT_STATUS_MAC_LSB) +#define WLAN_INT_STATUS_MAC_SET(x) (((x) << WLAN_INT_STATUS_MAC_LSB) & WLAN_INT_STATUS_MAC_MASK) +#define WLAN_INT_STATUS_MAILBOX_MSB 12 +#define WLAN_INT_STATUS_MAILBOX_LSB 12 +#define WLAN_INT_STATUS_MAILBOX_MASK 0x00001000 +#define WLAN_INT_STATUS_MAILBOX_GET(x) (((x)&WLAN_INT_STATUS_MAILBOX_MASK) >> WLAN_INT_STATUS_MAILBOX_LSB) +#define WLAN_INT_STATUS_MAILBOX_SET(x) (((x) << WLAN_INT_STATUS_MAILBOX_LSB) & WLAN_INT_STATUS_MAILBOX_MASK) +#define WLAN_INT_STATUS_RTC_ALARM_MSB 11 +#define WLAN_INT_STATUS_RTC_ALARM_LSB 11 +#define WLAN_INT_STATUS_RTC_ALARM_MASK 0x00000800 +#define WLAN_INT_STATUS_RTC_ALARM_GET(x) (((x)&WLAN_INT_STATUS_RTC_ALARM_MASK) >> WLAN_INT_STATUS_RTC_ALARM_LSB) +#define WLAN_INT_STATUS_RTC_ALARM_SET(x) (((x) << WLAN_INT_STATUS_RTC_ALARM_LSB) & WLAN_INT_STATUS_RTC_ALARM_MASK) +#define WLAN_INT_STATUS_HF_TIMER_MSB 10 +#define WLAN_INT_STATUS_HF_TIMER_LSB 10 +#define WLAN_INT_STATUS_HF_TIMER_MASK 0x00000400 +#define WLAN_INT_STATUS_HF_TIMER_GET(x) (((x)&WLAN_INT_STATUS_HF_TIMER_MASK) >> WLAN_INT_STATUS_HF_TIMER_LSB) +#define WLAN_INT_STATUS_HF_TIMER_SET(x) (((x) << WLAN_INT_STATUS_HF_TIMER_LSB) & WLAN_INT_STATUS_HF_TIMER_MASK) +#define WLAN_INT_STATUS_LF_TIMER3_MSB 9 +#define WLAN_INT_STATUS_LF_TIMER3_LSB 9 +#define WLAN_INT_STATUS_LF_TIMER3_MASK 0x00000200 +#define WLAN_INT_STATUS_LF_TIMER3_GET(x) (((x)&WLAN_INT_STATUS_LF_TIMER3_MASK) >> WLAN_INT_STATUS_LF_TIMER3_LSB) +#define WLAN_INT_STATUS_LF_TIMER3_SET(x) (((x) << WLAN_INT_STATUS_LF_TIMER3_LSB) & WLAN_INT_STATUS_LF_TIMER3_MASK) +#define WLAN_INT_STATUS_LF_TIMER2_MSB 8 +#define WLAN_INT_STATUS_LF_TIMER2_LSB 8 +#define WLAN_INT_STATUS_LF_TIMER2_MASK 0x00000100 +#define WLAN_INT_STATUS_LF_TIMER2_GET(x) (((x)&WLAN_INT_STATUS_LF_TIMER2_MASK) >> WLAN_INT_STATUS_LF_TIMER2_LSB) +#define WLAN_INT_STATUS_LF_TIMER2_SET(x) (((x) << WLAN_INT_STATUS_LF_TIMER2_LSB) & WLAN_INT_STATUS_LF_TIMER2_MASK) +#define WLAN_INT_STATUS_LF_TIMER1_MSB 7 +#define WLAN_INT_STATUS_LF_TIMER1_LSB 7 +#define WLAN_INT_STATUS_LF_TIMER1_MASK 0x00000080 +#define WLAN_INT_STATUS_LF_TIMER1_GET(x) (((x)&WLAN_INT_STATUS_LF_TIMER1_MASK) >> WLAN_INT_STATUS_LF_TIMER1_LSB) +#define WLAN_INT_STATUS_LF_TIMER1_SET(x) (((x) << WLAN_INT_STATUS_LF_TIMER1_LSB) & WLAN_INT_STATUS_LF_TIMER1_MASK) +#define WLAN_INT_STATUS_LF_TIMER0_MSB 6 +#define WLAN_INT_STATUS_LF_TIMER0_LSB 6 +#define WLAN_INT_STATUS_LF_TIMER0_MASK 0x00000040 +#define WLAN_INT_STATUS_LF_TIMER0_GET(x) (((x)&WLAN_INT_STATUS_LF_TIMER0_MASK) >> WLAN_INT_STATUS_LF_TIMER0_LSB) +#define WLAN_INT_STATUS_LF_TIMER0_SET(x) (((x) << WLAN_INT_STATUS_LF_TIMER0_LSB) & WLAN_INT_STATUS_LF_TIMER0_MASK) +#define WLAN_INT_STATUS_KEYPAD_MSB 5 +#define WLAN_INT_STATUS_KEYPAD_LSB 5 +#define WLAN_INT_STATUS_KEYPAD_MASK 0x00000020 +#define WLAN_INT_STATUS_KEYPAD_GET(x) (((x)&WLAN_INT_STATUS_KEYPAD_MASK) >> WLAN_INT_STATUS_KEYPAD_LSB) +#define WLAN_INT_STATUS_KEYPAD_SET(x) (((x) << WLAN_INT_STATUS_KEYPAD_LSB) & WLAN_INT_STATUS_KEYPAD_MASK) +#define WLAN_INT_STATUS_SI_MSB 4 +#define WLAN_INT_STATUS_SI_LSB 4 +#define WLAN_INT_STATUS_SI_MASK 0x00000010 +#define WLAN_INT_STATUS_SI_GET(x) (((x)&WLAN_INT_STATUS_SI_MASK) >> WLAN_INT_STATUS_SI_LSB) +#define WLAN_INT_STATUS_SI_SET(x) (((x) << WLAN_INT_STATUS_SI_LSB) & WLAN_INT_STATUS_SI_MASK) +#define WLAN_INT_STATUS_GPIO_MSB 3 +#define WLAN_INT_STATUS_GPIO_LSB 3 +#define WLAN_INT_STATUS_GPIO_MASK 0x00000008 +#define WLAN_INT_STATUS_GPIO_GET(x) (((x)&WLAN_INT_STATUS_GPIO_MASK) >> WLAN_INT_STATUS_GPIO_LSB) +#define WLAN_INT_STATUS_GPIO_SET(x) (((x) << WLAN_INT_STATUS_GPIO_LSB) & WLAN_INT_STATUS_GPIO_MASK) +#define WLAN_INT_STATUS_UART_MSB 2 +#define WLAN_INT_STATUS_UART_LSB 2 +#define WLAN_INT_STATUS_UART_MASK 0x00000004 +#define WLAN_INT_STATUS_UART_GET(x) (((x)&WLAN_INT_STATUS_UART_MASK) >> WLAN_INT_STATUS_UART_LSB) +#define WLAN_INT_STATUS_UART_SET(x) (((x) << WLAN_INT_STATUS_UART_LSB) & WLAN_INT_STATUS_UART_MASK) +#define WLAN_INT_STATUS_ERROR_MSB 1 +#define WLAN_INT_STATUS_ERROR_LSB 1 +#define WLAN_INT_STATUS_ERROR_MASK 0x00000002 +#define WLAN_INT_STATUS_ERROR_GET(x) (((x)&WLAN_INT_STATUS_ERROR_MASK) >> WLAN_INT_STATUS_ERROR_LSB) +#define WLAN_INT_STATUS_ERROR_SET(x) (((x) << WLAN_INT_STATUS_ERROR_LSB) & WLAN_INT_STATUS_ERROR_MASK) +#define WLAN_INT_STATUS_WDT_INT_MSB 0 +#define WLAN_INT_STATUS_WDT_INT_LSB 0 +#define WLAN_INT_STATUS_WDT_INT_MASK 0x00000001 +#define WLAN_INT_STATUS_WDT_INT_GET(x) (((x)&WLAN_INT_STATUS_WDT_INT_MASK) >> WLAN_INT_STATUS_WDT_INT_LSB) +#define WLAN_INT_STATUS_WDT_INT_SET(x) (((x) << WLAN_INT_STATUS_WDT_INT_LSB) & WLAN_INT_STATUS_WDT_INT_MASK) + +#define WLAN_LF_TIMER0_ADDRESS 0x00000048 +#define WLAN_LF_TIMER0_OFFSET 0x00000048 +#define WLAN_LF_TIMER0_TARGET_MSB 31 +#define WLAN_LF_TIMER0_TARGET_LSB 0 +#define WLAN_LF_TIMER0_TARGET_MASK 0xffffffff +#define WLAN_LF_TIMER0_TARGET_GET(x) (((x)&WLAN_LF_TIMER0_TARGET_MASK) >> WLAN_LF_TIMER0_TARGET_LSB) +#define WLAN_LF_TIMER0_TARGET_SET(x) (((x) << WLAN_LF_TIMER0_TARGET_LSB) & WLAN_LF_TIMER0_TARGET_MASK) + +#define WLAN_LF_TIMER_COUNT0_ADDRESS 0x0000004c +#define WLAN_LF_TIMER_COUNT0_OFFSET 0x0000004c +#define WLAN_LF_TIMER_COUNT0_VALUE_MSB 31 +#define WLAN_LF_TIMER_COUNT0_VALUE_LSB 0 +#define WLAN_LF_TIMER_COUNT0_VALUE_MASK 0xffffffff +#define WLAN_LF_TIMER_COUNT0_VALUE_GET(x) (((x)&WLAN_LF_TIMER_COUNT0_VALUE_MASK) >> WLAN_LF_TIMER_COUNT0_VALUE_LSB) +#define WLAN_LF_TIMER_COUNT0_VALUE_SET(x) (((x) << WLAN_LF_TIMER_COUNT0_VALUE_LSB) & WLAN_LF_TIMER_COUNT0_VALUE_MASK) + +#define WLAN_LF_TIMER_CONTROL0_ADDRESS 0x00000050 +#define WLAN_LF_TIMER_CONTROL0_OFFSET 0x00000050 +#define WLAN_LF_TIMER_CONTROL0_ENABLE_MSB 2 +#define WLAN_LF_TIMER_CONTROL0_ENABLE_LSB 2 +#define WLAN_LF_TIMER_CONTROL0_ENABLE_MASK 0x00000004 +#define WLAN_LF_TIMER_CONTROL0_ENABLE_GET(x) \ + (((x)&WLAN_LF_TIMER_CONTROL0_ENABLE_MASK) >> WLAN_LF_TIMER_CONTROL0_ENABLE_LSB) +#define WLAN_LF_TIMER_CONTROL0_ENABLE_SET(x) \ + (((x) << WLAN_LF_TIMER_CONTROL0_ENABLE_LSB) & WLAN_LF_TIMER_CONTROL0_ENABLE_MASK) +#define WLAN_LF_TIMER_CONTROL0_AUTO_RESTART_MSB 1 +#define WLAN_LF_TIMER_CONTROL0_AUTO_RESTART_LSB 1 +#define WLAN_LF_TIMER_CONTROL0_AUTO_RESTART_MASK 0x00000002 +#define WLAN_LF_TIMER_CONTROL0_AUTO_RESTART_GET(x) \ + (((x)&WLAN_LF_TIMER_CONTROL0_AUTO_RESTART_MASK) >> WLAN_LF_TIMER_CONTROL0_AUTO_RESTART_LSB) +#define WLAN_LF_TIMER_CONTROL0_AUTO_RESTART_SET(x) \ + (((x) << WLAN_LF_TIMER_CONTROL0_AUTO_RESTART_LSB) & WLAN_LF_TIMER_CONTROL0_AUTO_RESTART_MASK) +#define WLAN_LF_TIMER_CONTROL0_RESET_MSB 0 +#define WLAN_LF_TIMER_CONTROL0_RESET_LSB 0 +#define WLAN_LF_TIMER_CONTROL0_RESET_MASK 0x00000001 +#define WLAN_LF_TIMER_CONTROL0_RESET_GET(x) \ + (((x)&WLAN_LF_TIMER_CONTROL0_RESET_MASK) >> WLAN_LF_TIMER_CONTROL0_RESET_LSB) +#define WLAN_LF_TIMER_CONTROL0_RESET_SET(x) \ + (((x) << WLAN_LF_TIMER_CONTROL0_RESET_LSB) & WLAN_LF_TIMER_CONTROL0_RESET_MASK) + +#define WLAN_LF_TIMER_STATUS0_ADDRESS 0x00000054 +#define WLAN_LF_TIMER_STATUS0_OFFSET 0x00000054 +#define WLAN_LF_TIMER_STATUS0_INTERRUPT_MSB 0 +#define WLAN_LF_TIMER_STATUS0_INTERRUPT_LSB 0 +#define WLAN_LF_TIMER_STATUS0_INTERRUPT_MASK 0x00000001 +#define WLAN_LF_TIMER_STATUS0_INTERRUPT_GET(x) \ + (((x)&WLAN_LF_TIMER_STATUS0_INTERRUPT_MASK) >> WLAN_LF_TIMER_STATUS0_INTERRUPT_LSB) +#define WLAN_LF_TIMER_STATUS0_INTERRUPT_SET(x) \ + (((x) << WLAN_LF_TIMER_STATUS0_INTERRUPT_LSB) & WLAN_LF_TIMER_STATUS0_INTERRUPT_MASK) + +#define WLAN_LF_TIMER1_ADDRESS 0x00000058 +#define WLAN_LF_TIMER1_OFFSET 0x00000058 +#define WLAN_LF_TIMER1_TARGET_MSB 31 +#define WLAN_LF_TIMER1_TARGET_LSB 0 +#define WLAN_LF_TIMER1_TARGET_MASK 0xffffffff +#define WLAN_LF_TIMER1_TARGET_GET(x) (((x)&WLAN_LF_TIMER1_TARGET_MASK) >> WLAN_LF_TIMER1_TARGET_LSB) +#define WLAN_LF_TIMER1_TARGET_SET(x) (((x) << WLAN_LF_TIMER1_TARGET_LSB) & WLAN_LF_TIMER1_TARGET_MASK) + +#define WLAN_LF_TIMER_COUNT1_ADDRESS 0x0000005c +#define WLAN_LF_TIMER_COUNT1_OFFSET 0x0000005c +#define WLAN_LF_TIMER_COUNT1_VALUE_MSB 31 +#define WLAN_LF_TIMER_COUNT1_VALUE_LSB 0 +#define WLAN_LF_TIMER_COUNT1_VALUE_MASK 0xffffffff +#define WLAN_LF_TIMER_COUNT1_VALUE_GET(x) (((x)&WLAN_LF_TIMER_COUNT1_VALUE_MASK) >> WLAN_LF_TIMER_COUNT1_VALUE_LSB) +#define WLAN_LF_TIMER_COUNT1_VALUE_SET(x) (((x) << WLAN_LF_TIMER_COUNT1_VALUE_LSB) & WLAN_LF_TIMER_COUNT1_VALUE_MASK) + +#define WLAN_LF_TIMER_CONTROL1_ADDRESS 0x00000060 +#define WLAN_LF_TIMER_CONTROL1_OFFSET 0x00000060 +#define WLAN_LF_TIMER_CONTROL1_ENABLE_MSB 2 +#define WLAN_LF_TIMER_CONTROL1_ENABLE_LSB 2 +#define WLAN_LF_TIMER_CONTROL1_ENABLE_MASK 0x00000004 +#define WLAN_LF_TIMER_CONTROL1_ENABLE_GET(x) \ + (((x)&WLAN_LF_TIMER_CONTROL1_ENABLE_MASK) >> WLAN_LF_TIMER_CONTROL1_ENABLE_LSB) +#define WLAN_LF_TIMER_CONTROL1_ENABLE_SET(x) \ + (((x) << WLAN_LF_TIMER_CONTROL1_ENABLE_LSB) & WLAN_LF_TIMER_CONTROL1_ENABLE_MASK) +#define WLAN_LF_TIMER_CONTROL1_AUTO_RESTART_MSB 1 +#define WLAN_LF_TIMER_CONTROL1_AUTO_RESTART_LSB 1 +#define WLAN_LF_TIMER_CONTROL1_AUTO_RESTART_MASK 0x00000002 +#define WLAN_LF_TIMER_CONTROL1_AUTO_RESTART_GET(x) \ + (((x)&WLAN_LF_TIMER_CONTROL1_AUTO_RESTART_MASK) >> WLAN_LF_TIMER_CONTROL1_AUTO_RESTART_LSB) +#define WLAN_LF_TIMER_CONTROL1_AUTO_RESTART_SET(x) \ + (((x) << WLAN_LF_TIMER_CONTROL1_AUTO_RESTART_LSB) & WLAN_LF_TIMER_CONTROL1_AUTO_RESTART_MASK) +#define WLAN_LF_TIMER_CONTROL1_RESET_MSB 0 +#define WLAN_LF_TIMER_CONTROL1_RESET_LSB 0 +#define WLAN_LF_TIMER_CONTROL1_RESET_MASK 0x00000001 +#define WLAN_LF_TIMER_CONTROL1_RESET_GET(x) \ + (((x)&WLAN_LF_TIMER_CONTROL1_RESET_MASK) >> WLAN_LF_TIMER_CONTROL1_RESET_LSB) +#define WLAN_LF_TIMER_CONTROL1_RESET_SET(x) \ + (((x) << WLAN_LF_TIMER_CONTROL1_RESET_LSB) & WLAN_LF_TIMER_CONTROL1_RESET_MASK) + +#define WLAN_LF_TIMER_STATUS1_ADDRESS 0x00000064 +#define WLAN_LF_TIMER_STATUS1_OFFSET 0x00000064 +#define WLAN_LF_TIMER_STATUS1_INTERRUPT_MSB 0 +#define WLAN_LF_TIMER_STATUS1_INTERRUPT_LSB 0 +#define WLAN_LF_TIMER_STATUS1_INTERRUPT_MASK 0x00000001 +#define WLAN_LF_TIMER_STATUS1_INTERRUPT_GET(x) \ + (((x)&WLAN_LF_TIMER_STATUS1_INTERRUPT_MASK) >> WLAN_LF_TIMER_STATUS1_INTERRUPT_LSB) +#define WLAN_LF_TIMER_STATUS1_INTERRUPT_SET(x) \ + (((x) << WLAN_LF_TIMER_STATUS1_INTERRUPT_LSB) & WLAN_LF_TIMER_STATUS1_INTERRUPT_MASK) + +#define WLAN_LF_TIMER2_ADDRESS 0x00000068 +#define WLAN_LF_TIMER2_OFFSET 0x00000068 +#define WLAN_LF_TIMER2_TARGET_MSB 31 +#define WLAN_LF_TIMER2_TARGET_LSB 0 +#define WLAN_LF_TIMER2_TARGET_MASK 0xffffffff +#define WLAN_LF_TIMER2_TARGET_GET(x) (((x)&WLAN_LF_TIMER2_TARGET_MASK) >> WLAN_LF_TIMER2_TARGET_LSB) +#define WLAN_LF_TIMER2_TARGET_SET(x) (((x) << WLAN_LF_TIMER2_TARGET_LSB) & WLAN_LF_TIMER2_TARGET_MASK) + +#define WLAN_LF_TIMER_COUNT2_ADDRESS 0x0000006c +#define WLAN_LF_TIMER_COUNT2_OFFSET 0x0000006c +#define WLAN_LF_TIMER_COUNT2_VALUE_MSB 31 +#define WLAN_LF_TIMER_COUNT2_VALUE_LSB 0 +#define WLAN_LF_TIMER_COUNT2_VALUE_MASK 0xffffffff +#define WLAN_LF_TIMER_COUNT2_VALUE_GET(x) (((x)&WLAN_LF_TIMER_COUNT2_VALUE_MASK) >> WLAN_LF_TIMER_COUNT2_VALUE_LSB) +#define WLAN_LF_TIMER_COUNT2_VALUE_SET(x) (((x) << WLAN_LF_TIMER_COUNT2_VALUE_LSB) & WLAN_LF_TIMER_COUNT2_VALUE_MASK) + +#define WLAN_LF_TIMER_CONTROL2_ADDRESS 0x00000070 +#define WLAN_LF_TIMER_CONTROL2_OFFSET 0x00000070 +#define WLAN_LF_TIMER_CONTROL2_ENABLE_MSB 2 +#define WLAN_LF_TIMER_CONTROL2_ENABLE_LSB 2 +#define WLAN_LF_TIMER_CONTROL2_ENABLE_MASK 0x00000004 +#define WLAN_LF_TIMER_CONTROL2_ENABLE_GET(x) \ + (((x)&WLAN_LF_TIMER_CONTROL2_ENABLE_MASK) >> WLAN_LF_TIMER_CONTROL2_ENABLE_LSB) +#define WLAN_LF_TIMER_CONTROL2_ENABLE_SET(x) \ + (((x) << WLAN_LF_TIMER_CONTROL2_ENABLE_LSB) & WLAN_LF_TIMER_CONTROL2_ENABLE_MASK) +#define WLAN_LF_TIMER_CONTROL2_AUTO_RESTART_MSB 1 +#define WLAN_LF_TIMER_CONTROL2_AUTO_RESTART_LSB 1 +#define WLAN_LF_TIMER_CONTROL2_AUTO_RESTART_MASK 0x00000002 +#define WLAN_LF_TIMER_CONTROL2_AUTO_RESTART_GET(x) \ + (((x)&WLAN_LF_TIMER_CONTROL2_AUTO_RESTART_MASK) >> WLAN_LF_TIMER_CONTROL2_AUTO_RESTART_LSB) +#define WLAN_LF_TIMER_CONTROL2_AUTO_RESTART_SET(x) \ + (((x) << WLAN_LF_TIMER_CONTROL2_AUTO_RESTART_LSB) & WLAN_LF_TIMER_CONTROL2_AUTO_RESTART_MASK) +#define WLAN_LF_TIMER_CONTROL2_RESET_MSB 0 +#define WLAN_LF_TIMER_CONTROL2_RESET_LSB 0 +#define WLAN_LF_TIMER_CONTROL2_RESET_MASK 0x00000001 +#define WLAN_LF_TIMER_CONTROL2_RESET_GET(x) \ + (((x)&WLAN_LF_TIMER_CONTROL2_RESET_MASK) >> WLAN_LF_TIMER_CONTROL2_RESET_LSB) +#define WLAN_LF_TIMER_CONTROL2_RESET_SET(x) \ + (((x) << WLAN_LF_TIMER_CONTROL2_RESET_LSB) & WLAN_LF_TIMER_CONTROL2_RESET_MASK) + +#define WLAN_LF_TIMER_STATUS2_ADDRESS 0x00000074 +#define WLAN_LF_TIMER_STATUS2_OFFSET 0x00000074 +#define WLAN_LF_TIMER_STATUS2_INTERRUPT_MSB 0 +#define WLAN_LF_TIMER_STATUS2_INTERRUPT_LSB 0 +#define WLAN_LF_TIMER_STATUS2_INTERRUPT_MASK 0x00000001 +#define WLAN_LF_TIMER_STATUS2_INTERRUPT_GET(x) \ + (((x)&WLAN_LF_TIMER_STATUS2_INTERRUPT_MASK) >> WLAN_LF_TIMER_STATUS2_INTERRUPT_LSB) +#define WLAN_LF_TIMER_STATUS2_INTERRUPT_SET(x) \ + (((x) << WLAN_LF_TIMER_STATUS2_INTERRUPT_LSB) & WLAN_LF_TIMER_STATUS2_INTERRUPT_MASK) + +#define WLAN_LF_TIMER3_ADDRESS 0x00000078 +#define WLAN_LF_TIMER3_OFFSET 0x00000078 +#define WLAN_LF_TIMER3_TARGET_MSB 31 +#define WLAN_LF_TIMER3_TARGET_LSB 0 +#define WLAN_LF_TIMER3_TARGET_MASK 0xffffffff +#define WLAN_LF_TIMER3_TARGET_GET(x) (((x)&WLAN_LF_TIMER3_TARGET_MASK) >> WLAN_LF_TIMER3_TARGET_LSB) +#define WLAN_LF_TIMER3_TARGET_SET(x) (((x) << WLAN_LF_TIMER3_TARGET_LSB) & WLAN_LF_TIMER3_TARGET_MASK) + +#define WLAN_LF_TIMER_COUNT3_ADDRESS 0x0000007c +#define WLAN_LF_TIMER_COUNT3_OFFSET 0x0000007c +#define WLAN_LF_TIMER_COUNT3_VALUE_MSB 31 +#define WLAN_LF_TIMER_COUNT3_VALUE_LSB 0 +#define WLAN_LF_TIMER_COUNT3_VALUE_MASK 0xffffffff +#define WLAN_LF_TIMER_COUNT3_VALUE_GET(x) (((x)&WLAN_LF_TIMER_COUNT3_VALUE_MASK) >> WLAN_LF_TIMER_COUNT3_VALUE_LSB) +#define WLAN_LF_TIMER_COUNT3_VALUE_SET(x) (((x) << WLAN_LF_TIMER_COUNT3_VALUE_LSB) & WLAN_LF_TIMER_COUNT3_VALUE_MASK) + +#define WLAN_LF_TIMER_CONTROL3_ADDRESS 0x00000080 +#define WLAN_LF_TIMER_CONTROL3_OFFSET 0x00000080 +#define WLAN_LF_TIMER_CONTROL3_ENABLE_MSB 2 +#define WLAN_LF_TIMER_CONTROL3_ENABLE_LSB 2 +#define WLAN_LF_TIMER_CONTROL3_ENABLE_MASK 0x00000004 +#define WLAN_LF_TIMER_CONTROL3_ENABLE_GET(x) \ + (((x)&WLAN_LF_TIMER_CONTROL3_ENABLE_MASK) >> WLAN_LF_TIMER_CONTROL3_ENABLE_LSB) +#define WLAN_LF_TIMER_CONTROL3_ENABLE_SET(x) \ + (((x) << WLAN_LF_TIMER_CONTROL3_ENABLE_LSB) & WLAN_LF_TIMER_CONTROL3_ENABLE_MASK) +#define WLAN_LF_TIMER_CONTROL3_AUTO_RESTART_MSB 1 +#define WLAN_LF_TIMER_CONTROL3_AUTO_RESTART_LSB 1 +#define WLAN_LF_TIMER_CONTROL3_AUTO_RESTART_MASK 0x00000002 +#define WLAN_LF_TIMER_CONTROL3_AUTO_RESTART_GET(x) \ + (((x)&WLAN_LF_TIMER_CONTROL3_AUTO_RESTART_MASK) >> WLAN_LF_TIMER_CONTROL3_AUTO_RESTART_LSB) +#define WLAN_LF_TIMER_CONTROL3_AUTO_RESTART_SET(x) \ + (((x) << WLAN_LF_TIMER_CONTROL3_AUTO_RESTART_LSB) & WLAN_LF_TIMER_CONTROL3_AUTO_RESTART_MASK) +#define WLAN_LF_TIMER_CONTROL3_RESET_MSB 0 +#define WLAN_LF_TIMER_CONTROL3_RESET_LSB 0 +#define WLAN_LF_TIMER_CONTROL3_RESET_MASK 0x00000001 +#define WLAN_LF_TIMER_CONTROL3_RESET_GET(x) \ + (((x)&WLAN_LF_TIMER_CONTROL3_RESET_MASK) >> WLAN_LF_TIMER_CONTROL3_RESET_LSB) +#define WLAN_LF_TIMER_CONTROL3_RESET_SET(x) \ + (((x) << WLAN_LF_TIMER_CONTROL3_RESET_LSB) & WLAN_LF_TIMER_CONTROL3_RESET_MASK) + +#define WLAN_LF_TIMER_STATUS3_ADDRESS 0x00000084 +#define WLAN_LF_TIMER_STATUS3_OFFSET 0x00000084 +#define WLAN_LF_TIMER_STATUS3_INTERRUPT_MSB 0 +#define WLAN_LF_TIMER_STATUS3_INTERRUPT_LSB 0 +#define WLAN_LF_TIMER_STATUS3_INTERRUPT_MASK 0x00000001 +#define WLAN_LF_TIMER_STATUS3_INTERRUPT_GET(x) \ + (((x)&WLAN_LF_TIMER_STATUS3_INTERRUPT_MASK) >> WLAN_LF_TIMER_STATUS3_INTERRUPT_LSB) +#define WLAN_LF_TIMER_STATUS3_INTERRUPT_SET(x) \ + (((x) << WLAN_LF_TIMER_STATUS3_INTERRUPT_LSB) & WLAN_LF_TIMER_STATUS3_INTERRUPT_MASK) + +#define WLAN_HF_TIMER_ADDRESS 0x00000088 +#define WLAN_HF_TIMER_OFFSET 0x00000088 +#define WLAN_HF_TIMER_TARGET_MSB 31 +#define WLAN_HF_TIMER_TARGET_LSB 12 +#define WLAN_HF_TIMER_TARGET_MASK 0xfffff000 +#define WLAN_HF_TIMER_TARGET_GET(x) (((x)&WLAN_HF_TIMER_TARGET_MASK) >> WLAN_HF_TIMER_TARGET_LSB) +#define WLAN_HF_TIMER_TARGET_SET(x) (((x) << WLAN_HF_TIMER_TARGET_LSB) & WLAN_HF_TIMER_TARGET_MASK) + +#define WLAN_HF_TIMER_COUNT_ADDRESS 0x0000008c +#define WLAN_HF_TIMER_COUNT_OFFSET 0x0000008c +#define WLAN_HF_TIMER_COUNT_VALUE_MSB 31 +#define WLAN_HF_TIMER_COUNT_VALUE_LSB 12 +#define WLAN_HF_TIMER_COUNT_VALUE_MASK 0xfffff000 +#define WLAN_HF_TIMER_COUNT_VALUE_GET(x) (((x)&WLAN_HF_TIMER_COUNT_VALUE_MASK) >> WLAN_HF_TIMER_COUNT_VALUE_LSB) +#define WLAN_HF_TIMER_COUNT_VALUE_SET(x) (((x) << WLAN_HF_TIMER_COUNT_VALUE_LSB) & WLAN_HF_TIMER_COUNT_VALUE_MASK) + +#define WLAN_HF_LF_COUNT_ADDRESS 0x00000090 +#define WLAN_HF_LF_COUNT_OFFSET 0x00000090 +#define WLAN_HF_LF_COUNT_VALUE_MSB 31 +#define WLAN_HF_LF_COUNT_VALUE_LSB 0 +#define WLAN_HF_LF_COUNT_VALUE_MASK 0xffffffff +#define WLAN_HF_LF_COUNT_VALUE_GET(x) (((x)&WLAN_HF_LF_COUNT_VALUE_MASK) >> WLAN_HF_LF_COUNT_VALUE_LSB) +#define WLAN_HF_LF_COUNT_VALUE_SET(x) (((x) << WLAN_HF_LF_COUNT_VALUE_LSB) & WLAN_HF_LF_COUNT_VALUE_MASK) + +#define WLAN_HF_TIMER_CONTROL_ADDRESS 0x00000094 +#define WLAN_HF_TIMER_CONTROL_OFFSET 0x00000094 +#define WLAN_HF_TIMER_CONTROL_ENABLE_MSB 3 +#define WLAN_HF_TIMER_CONTROL_ENABLE_LSB 3 +#define WLAN_HF_TIMER_CONTROL_ENABLE_MASK 0x00000008 +#define WLAN_HF_TIMER_CONTROL_ENABLE_GET(x) \ + (((x)&WLAN_HF_TIMER_CONTROL_ENABLE_MASK) >> WLAN_HF_TIMER_CONTROL_ENABLE_LSB) +#define WLAN_HF_TIMER_CONTROL_ENABLE_SET(x) \ + (((x) << WLAN_HF_TIMER_CONTROL_ENABLE_LSB) & WLAN_HF_TIMER_CONTROL_ENABLE_MASK) +#define WLAN_HF_TIMER_CONTROL_ON_MSB 2 +#define WLAN_HF_TIMER_CONTROL_ON_LSB 2 +#define WLAN_HF_TIMER_CONTROL_ON_MASK 0x00000004 +#define WLAN_HF_TIMER_CONTROL_ON_GET(x) (((x)&WLAN_HF_TIMER_CONTROL_ON_MASK) >> WLAN_HF_TIMER_CONTROL_ON_LSB) +#define WLAN_HF_TIMER_CONTROL_ON_SET(x) (((x) << WLAN_HF_TIMER_CONTROL_ON_LSB) & WLAN_HF_TIMER_CONTROL_ON_MASK) +#define WLAN_HF_TIMER_CONTROL_AUTO_RESTART_MSB 1 +#define WLAN_HF_TIMER_CONTROL_AUTO_RESTART_LSB 1 +#define WLAN_HF_TIMER_CONTROL_AUTO_RESTART_MASK 0x00000002 +#define WLAN_HF_TIMER_CONTROL_AUTO_RESTART_GET(x) \ + (((x)&WLAN_HF_TIMER_CONTROL_AUTO_RESTART_MASK) >> WLAN_HF_TIMER_CONTROL_AUTO_RESTART_LSB) +#define WLAN_HF_TIMER_CONTROL_AUTO_RESTART_SET(x) \ + (((x) << WLAN_HF_TIMER_CONTROL_AUTO_RESTART_LSB) & WLAN_HF_TIMER_CONTROL_AUTO_RESTART_MASK) +#define WLAN_HF_TIMER_CONTROL_RESET_MSB 0 +#define WLAN_HF_TIMER_CONTROL_RESET_LSB 0 +#define WLAN_HF_TIMER_CONTROL_RESET_MASK 0x00000001 +#define WLAN_HF_TIMER_CONTROL_RESET_GET(x) (((x)&WLAN_HF_TIMER_CONTROL_RESET_MASK) >> WLAN_HF_TIMER_CONTROL_RESET_LSB) +#define WLAN_HF_TIMER_CONTROL_RESET_SET(x) (((x) << WLAN_HF_TIMER_CONTROL_RESET_LSB) & WLAN_HF_TIMER_CONTROL_RESET_MASK) + +#define WLAN_HF_TIMER_STATUS_ADDRESS 0x00000098 +#define WLAN_HF_TIMER_STATUS_OFFSET 0x00000098 +#define WLAN_HF_TIMER_STATUS_INTERRUPT_MSB 0 +#define WLAN_HF_TIMER_STATUS_INTERRUPT_LSB 0 +#define WLAN_HF_TIMER_STATUS_INTERRUPT_MASK 0x00000001 +#define WLAN_HF_TIMER_STATUS_INTERRUPT_GET(x) \ + (((x)&WLAN_HF_TIMER_STATUS_INTERRUPT_MASK) >> WLAN_HF_TIMER_STATUS_INTERRUPT_LSB) +#define WLAN_HF_TIMER_STATUS_INTERRUPT_SET(x) \ + (((x) << WLAN_HF_TIMER_STATUS_INTERRUPT_LSB) & WLAN_HF_TIMER_STATUS_INTERRUPT_MASK) + +#define WLAN_RTC_CONTROL_ADDRESS 0x0000009c +#define WLAN_RTC_CONTROL_OFFSET 0x0000009c +#define WLAN_RTC_CONTROL_ENABLE_MSB 2 +#define WLAN_RTC_CONTROL_ENABLE_LSB 2 +#define WLAN_RTC_CONTROL_ENABLE_MASK 0x00000004 +#define WLAN_RTC_CONTROL_ENABLE_GET(x) (((x)&WLAN_RTC_CONTROL_ENABLE_MASK) >> WLAN_RTC_CONTROL_ENABLE_LSB) +#define WLAN_RTC_CONTROL_ENABLE_SET(x) (((x) << WLAN_RTC_CONTROL_ENABLE_LSB) & WLAN_RTC_CONTROL_ENABLE_MASK) +#define WLAN_RTC_CONTROL_LOAD_RTC_MSB 1 +#define WLAN_RTC_CONTROL_LOAD_RTC_LSB 1 +#define WLAN_RTC_CONTROL_LOAD_RTC_MASK 0x00000002 +#define WLAN_RTC_CONTROL_LOAD_RTC_GET(x) (((x)&WLAN_RTC_CONTROL_LOAD_RTC_MASK) >> WLAN_RTC_CONTROL_LOAD_RTC_LSB) +#define WLAN_RTC_CONTROL_LOAD_RTC_SET(x) (((x) << WLAN_RTC_CONTROL_LOAD_RTC_LSB) & WLAN_RTC_CONTROL_LOAD_RTC_MASK) +#define WLAN_RTC_CONTROL_LOAD_ALARM_MSB 0 +#define WLAN_RTC_CONTROL_LOAD_ALARM_LSB 0 +#define WLAN_RTC_CONTROL_LOAD_ALARM_MASK 0x00000001 +#define WLAN_RTC_CONTROL_LOAD_ALARM_GET(x) (((x)&WLAN_RTC_CONTROL_LOAD_ALARM_MASK) >> WLAN_RTC_CONTROL_LOAD_ALARM_LSB) +#define WLAN_RTC_CONTROL_LOAD_ALARM_SET(x) (((x) << WLAN_RTC_CONTROL_LOAD_ALARM_LSB) & WLAN_RTC_CONTROL_LOAD_ALARM_MASK) + +#define WLAN_RTC_TIME_ADDRESS 0x000000a0 +#define WLAN_RTC_TIME_OFFSET 0x000000a0 +#define WLAN_RTC_TIME_WEEK_DAY_MSB 26 +#define WLAN_RTC_TIME_WEEK_DAY_LSB 24 +#define WLAN_RTC_TIME_WEEK_DAY_MASK 0x07000000 +#define WLAN_RTC_TIME_WEEK_DAY_GET(x) (((x)&WLAN_RTC_TIME_WEEK_DAY_MASK) >> WLAN_RTC_TIME_WEEK_DAY_LSB) +#define WLAN_RTC_TIME_WEEK_DAY_SET(x) (((x) << WLAN_RTC_TIME_WEEK_DAY_LSB) & WLAN_RTC_TIME_WEEK_DAY_MASK) +#define WLAN_RTC_TIME_HOUR_MSB 21 +#define WLAN_RTC_TIME_HOUR_LSB 16 +#define WLAN_RTC_TIME_HOUR_MASK 0x003f0000 +#define WLAN_RTC_TIME_HOUR_GET(x) (((x)&WLAN_RTC_TIME_HOUR_MASK) >> WLAN_RTC_TIME_HOUR_LSB) +#define WLAN_RTC_TIME_HOUR_SET(x) (((x) << WLAN_RTC_TIME_HOUR_LSB) & WLAN_RTC_TIME_HOUR_MASK) +#define WLAN_RTC_TIME_MINUTE_MSB 14 +#define WLAN_RTC_TIME_MINUTE_LSB 8 +#define WLAN_RTC_TIME_MINUTE_MASK 0x00007f00 +#define WLAN_RTC_TIME_MINUTE_GET(x) (((x)&WLAN_RTC_TIME_MINUTE_MASK) >> WLAN_RTC_TIME_MINUTE_LSB) +#define WLAN_RTC_TIME_MINUTE_SET(x) (((x) << WLAN_RTC_TIME_MINUTE_LSB) & WLAN_RTC_TIME_MINUTE_MASK) +#define WLAN_RTC_TIME_SECOND_MSB 6 +#define WLAN_RTC_TIME_SECOND_LSB 0 +#define WLAN_RTC_TIME_SECOND_MASK 0x0000007f +#define WLAN_RTC_TIME_SECOND_GET(x) (((x)&WLAN_RTC_TIME_SECOND_MASK) >> WLAN_RTC_TIME_SECOND_LSB) +#define WLAN_RTC_TIME_SECOND_SET(x) (((x) << WLAN_RTC_TIME_SECOND_LSB) & WLAN_RTC_TIME_SECOND_MASK) + +#define WLAN_RTC_DATE_ADDRESS 0x000000a4 +#define WLAN_RTC_DATE_OFFSET 0x000000a4 +#define WLAN_RTC_DATE_YEAR_MSB 23 +#define WLAN_RTC_DATE_YEAR_LSB 16 +#define WLAN_RTC_DATE_YEAR_MASK 0x00ff0000 +#define WLAN_RTC_DATE_YEAR_GET(x) (((x)&WLAN_RTC_DATE_YEAR_MASK) >> WLAN_RTC_DATE_YEAR_LSB) +#define WLAN_RTC_DATE_YEAR_SET(x) (((x) << WLAN_RTC_DATE_YEAR_LSB) & WLAN_RTC_DATE_YEAR_MASK) +#define WLAN_RTC_DATE_MONTH_MSB 12 +#define WLAN_RTC_DATE_MONTH_LSB 8 +#define WLAN_RTC_DATE_MONTH_MASK 0x00001f00 +#define WLAN_RTC_DATE_MONTH_GET(x) (((x)&WLAN_RTC_DATE_MONTH_MASK) >> WLAN_RTC_DATE_MONTH_LSB) +#define WLAN_RTC_DATE_MONTH_SET(x) (((x) << WLAN_RTC_DATE_MONTH_LSB) & WLAN_RTC_DATE_MONTH_MASK) +#define WLAN_RTC_DATE_MONTH_DAY_MSB 5 +#define WLAN_RTC_DATE_MONTH_DAY_LSB 0 +#define WLAN_RTC_DATE_MONTH_DAY_MASK 0x0000003f +#define WLAN_RTC_DATE_MONTH_DAY_GET(x) (((x)&WLAN_RTC_DATE_MONTH_DAY_MASK) >> WLAN_RTC_DATE_MONTH_DAY_LSB) +#define WLAN_RTC_DATE_MONTH_DAY_SET(x) (((x) << WLAN_RTC_DATE_MONTH_DAY_LSB) & WLAN_RTC_DATE_MONTH_DAY_MASK) + +#define WLAN_RTC_SET_TIME_ADDRESS 0x000000a8 +#define WLAN_RTC_SET_TIME_OFFSET 0x000000a8 +#define WLAN_RTC_SET_TIME_WEEK_DAY_MSB 26 +#define WLAN_RTC_SET_TIME_WEEK_DAY_LSB 24 +#define WLAN_RTC_SET_TIME_WEEK_DAY_MASK 0x07000000 +#define WLAN_RTC_SET_TIME_WEEK_DAY_GET(x) (((x)&WLAN_RTC_SET_TIME_WEEK_DAY_MASK) >> WLAN_RTC_SET_TIME_WEEK_DAY_LSB) +#define WLAN_RTC_SET_TIME_WEEK_DAY_SET(x) (((x) << WLAN_RTC_SET_TIME_WEEK_DAY_LSB) & WLAN_RTC_SET_TIME_WEEK_DAY_MASK) +#define WLAN_RTC_SET_TIME_HOUR_MSB 21 +#define WLAN_RTC_SET_TIME_HOUR_LSB 16 +#define WLAN_RTC_SET_TIME_HOUR_MASK 0x003f0000 +#define WLAN_RTC_SET_TIME_HOUR_GET(x) (((x)&WLAN_RTC_SET_TIME_HOUR_MASK) >> WLAN_RTC_SET_TIME_HOUR_LSB) +#define WLAN_RTC_SET_TIME_HOUR_SET(x) (((x) << WLAN_RTC_SET_TIME_HOUR_LSB) & WLAN_RTC_SET_TIME_HOUR_MASK) +#define WLAN_RTC_SET_TIME_MINUTE_MSB 14 +#define WLAN_RTC_SET_TIME_MINUTE_LSB 8 +#define WLAN_RTC_SET_TIME_MINUTE_MASK 0x00007f00 +#define WLAN_RTC_SET_TIME_MINUTE_GET(x) (((x)&WLAN_RTC_SET_TIME_MINUTE_MASK) >> WLAN_RTC_SET_TIME_MINUTE_LSB) +#define WLAN_RTC_SET_TIME_MINUTE_SET(x) (((x) << WLAN_RTC_SET_TIME_MINUTE_LSB) & WLAN_RTC_SET_TIME_MINUTE_MASK) +#define WLAN_RTC_SET_TIME_SECOND_MSB 6 +#define WLAN_RTC_SET_TIME_SECOND_LSB 0 +#define WLAN_RTC_SET_TIME_SECOND_MASK 0x0000007f +#define WLAN_RTC_SET_TIME_SECOND_GET(x) (((x)&WLAN_RTC_SET_TIME_SECOND_MASK) >> WLAN_RTC_SET_TIME_SECOND_LSB) +#define WLAN_RTC_SET_TIME_SECOND_SET(x) (((x) << WLAN_RTC_SET_TIME_SECOND_LSB) & WLAN_RTC_SET_TIME_SECOND_MASK) + +#define WLAN_RTC_SET_DATE_ADDRESS 0x000000ac +#define WLAN_RTC_SET_DATE_OFFSET 0x000000ac +#define WLAN_RTC_SET_DATE_YEAR_MSB 23 +#define WLAN_RTC_SET_DATE_YEAR_LSB 16 +#define WLAN_RTC_SET_DATE_YEAR_MASK 0x00ff0000 +#define WLAN_RTC_SET_DATE_YEAR_GET(x) (((x)&WLAN_RTC_SET_DATE_YEAR_MASK) >> WLAN_RTC_SET_DATE_YEAR_LSB) +#define WLAN_RTC_SET_DATE_YEAR_SET(x) (((x) << WLAN_RTC_SET_DATE_YEAR_LSB) & WLAN_RTC_SET_DATE_YEAR_MASK) +#define WLAN_RTC_SET_DATE_MONTH_MSB 12 +#define WLAN_RTC_SET_DATE_MONTH_LSB 8 +#define WLAN_RTC_SET_DATE_MONTH_MASK 0x00001f00 +#define WLAN_RTC_SET_DATE_MONTH_GET(x) (((x)&WLAN_RTC_SET_DATE_MONTH_MASK) >> WLAN_RTC_SET_DATE_MONTH_LSB) +#define WLAN_RTC_SET_DATE_MONTH_SET(x) (((x) << WLAN_RTC_SET_DATE_MONTH_LSB) & WLAN_RTC_SET_DATE_MONTH_MASK) +#define WLAN_RTC_SET_DATE_MONTH_DAY_MSB 5 +#define WLAN_RTC_SET_DATE_MONTH_DAY_LSB 0 +#define WLAN_RTC_SET_DATE_MONTH_DAY_MASK 0x0000003f +#define WLAN_RTC_SET_DATE_MONTH_DAY_GET(x) (((x)&WLAN_RTC_SET_DATE_MONTH_DAY_MASK) >> WLAN_RTC_SET_DATE_MONTH_DAY_LSB) +#define WLAN_RTC_SET_DATE_MONTH_DAY_SET(x) (((x) << WLAN_RTC_SET_DATE_MONTH_DAY_LSB) & WLAN_RTC_SET_DATE_MONTH_DAY_MASK) + +#define WLAN_RTC_SET_ALARM_ADDRESS 0x000000b0 +#define WLAN_RTC_SET_ALARM_OFFSET 0x000000b0 +#define WLAN_RTC_SET_ALARM_HOUR_MSB 21 +#define WLAN_RTC_SET_ALARM_HOUR_LSB 16 +#define WLAN_RTC_SET_ALARM_HOUR_MASK 0x003f0000 +#define WLAN_RTC_SET_ALARM_HOUR_GET(x) (((x)&WLAN_RTC_SET_ALARM_HOUR_MASK) >> WLAN_RTC_SET_ALARM_HOUR_LSB) +#define WLAN_RTC_SET_ALARM_HOUR_SET(x) (((x) << WLAN_RTC_SET_ALARM_HOUR_LSB) & WLAN_RTC_SET_ALARM_HOUR_MASK) +#define WLAN_RTC_SET_ALARM_MINUTE_MSB 14 +#define WLAN_RTC_SET_ALARM_MINUTE_LSB 8 +#define WLAN_RTC_SET_ALARM_MINUTE_MASK 0x00007f00 +#define WLAN_RTC_SET_ALARM_MINUTE_GET(x) (((x)&WLAN_RTC_SET_ALARM_MINUTE_MASK) >> WLAN_RTC_SET_ALARM_MINUTE_LSB) +#define WLAN_RTC_SET_ALARM_MINUTE_SET(x) (((x) << WLAN_RTC_SET_ALARM_MINUTE_LSB) & WLAN_RTC_SET_ALARM_MINUTE_MASK) +#define WLAN_RTC_SET_ALARM_SECOND_MSB 6 +#define WLAN_RTC_SET_ALARM_SECOND_LSB 0 +#define WLAN_RTC_SET_ALARM_SECOND_MASK 0x0000007f +#define WLAN_RTC_SET_ALARM_SECOND_GET(x) (((x)&WLAN_RTC_SET_ALARM_SECOND_MASK) >> WLAN_RTC_SET_ALARM_SECOND_LSB) +#define WLAN_RTC_SET_ALARM_SECOND_SET(x) (((x) << WLAN_RTC_SET_ALARM_SECOND_LSB) & WLAN_RTC_SET_ALARM_SECOND_MASK) + +#define WLAN_RTC_CONFIG_ADDRESS 0x000000b4 +#define WLAN_RTC_CONFIG_OFFSET 0x000000b4 +#define WLAN_RTC_CONFIG_BCD_MSB 2 +#define WLAN_RTC_CONFIG_BCD_LSB 2 +#define WLAN_RTC_CONFIG_BCD_MASK 0x00000004 +#define WLAN_RTC_CONFIG_BCD_GET(x) (((x)&WLAN_RTC_CONFIG_BCD_MASK) >> WLAN_RTC_CONFIG_BCD_LSB) +#define WLAN_RTC_CONFIG_BCD_SET(x) (((x) << WLAN_RTC_CONFIG_BCD_LSB) & WLAN_RTC_CONFIG_BCD_MASK) +#define WLAN_RTC_CONFIG_TWELVE_HOUR_MSB 1 +#define WLAN_RTC_CONFIG_TWELVE_HOUR_LSB 1 +#define WLAN_RTC_CONFIG_TWELVE_HOUR_MASK 0x00000002 +#define WLAN_RTC_CONFIG_TWELVE_HOUR_GET(x) (((x)&WLAN_RTC_CONFIG_TWELVE_HOUR_MASK) >> WLAN_RTC_CONFIG_TWELVE_HOUR_LSB) +#define WLAN_RTC_CONFIG_TWELVE_HOUR_SET(x) (((x) << WLAN_RTC_CONFIG_TWELVE_HOUR_LSB) & WLAN_RTC_CONFIG_TWELVE_HOUR_MASK) +#define WLAN_RTC_CONFIG_DSE_MSB 0 +#define WLAN_RTC_CONFIG_DSE_LSB 0 +#define WLAN_RTC_CONFIG_DSE_MASK 0x00000001 +#define WLAN_RTC_CONFIG_DSE_GET(x) (((x)&WLAN_RTC_CONFIG_DSE_MASK) >> WLAN_RTC_CONFIG_DSE_LSB) +#define WLAN_RTC_CONFIG_DSE_SET(x) (((x) << WLAN_RTC_CONFIG_DSE_LSB) & WLAN_RTC_CONFIG_DSE_MASK) + +#define WLAN_RTC_ALARM_STATUS_ADDRESS 0x000000b8 +#define WLAN_RTC_ALARM_STATUS_OFFSET 0x000000b8 +#define WLAN_RTC_ALARM_STATUS_ENABLE_MSB 1 +#define WLAN_RTC_ALARM_STATUS_ENABLE_LSB 1 +#define WLAN_RTC_ALARM_STATUS_ENABLE_MASK 0x00000002 +#define WLAN_RTC_ALARM_STATUS_ENABLE_GET(x) \ + (((x)&WLAN_RTC_ALARM_STATUS_ENABLE_MASK) >> WLAN_RTC_ALARM_STATUS_ENABLE_LSB) +#define WLAN_RTC_ALARM_STATUS_ENABLE_SET(x) \ + (((x) << WLAN_RTC_ALARM_STATUS_ENABLE_LSB) & WLAN_RTC_ALARM_STATUS_ENABLE_MASK) +#define WLAN_RTC_ALARM_STATUS_INTERRUPT_MSB 0 +#define WLAN_RTC_ALARM_STATUS_INTERRUPT_LSB 0 +#define WLAN_RTC_ALARM_STATUS_INTERRUPT_MASK 0x00000001 +#define WLAN_RTC_ALARM_STATUS_INTERRUPT_GET(x) \ + (((x)&WLAN_RTC_ALARM_STATUS_INTERRUPT_MASK) >> WLAN_RTC_ALARM_STATUS_INTERRUPT_LSB) +#define WLAN_RTC_ALARM_STATUS_INTERRUPT_SET(x) \ + (((x) << WLAN_RTC_ALARM_STATUS_INTERRUPT_LSB) & WLAN_RTC_ALARM_STATUS_INTERRUPT_MASK) + +#define WLAN_UART_WAKEUP_ADDRESS 0x000000bc +#define WLAN_UART_WAKEUP_OFFSET 0x000000bc +#define WLAN_UART_WAKEUP_ENABLE_MSB 0 +#define WLAN_UART_WAKEUP_ENABLE_LSB 0 +#define WLAN_UART_WAKEUP_ENABLE_MASK 0x00000001 +#define WLAN_UART_WAKEUP_ENABLE_GET(x) (((x)&WLAN_UART_WAKEUP_ENABLE_MASK) >> WLAN_UART_WAKEUP_ENABLE_LSB) +#define WLAN_UART_WAKEUP_ENABLE_SET(x) (((x) << WLAN_UART_WAKEUP_ENABLE_LSB) & WLAN_UART_WAKEUP_ENABLE_MASK) + +#define WLAN_RESET_CAUSE_ADDRESS 0x000000c0 +#define WLAN_RESET_CAUSE_OFFSET 0x000000c0 +#define WLAN_RESET_CAUSE_LAST_MSB 2 +#define WLAN_RESET_CAUSE_LAST_LSB 0 +#define WLAN_RESET_CAUSE_LAST_MASK 0x00000007 +#define WLAN_RESET_CAUSE_LAST_GET(x) (((x)&WLAN_RESET_CAUSE_LAST_MASK) >> WLAN_RESET_CAUSE_LAST_LSB) +#define WLAN_RESET_CAUSE_LAST_SET(x) (((x) << WLAN_RESET_CAUSE_LAST_LSB) & WLAN_RESET_CAUSE_LAST_MASK) + +#define WLAN_SYSTEM_SLEEP_ADDRESS 0x000000c4 +#define WLAN_SYSTEM_SLEEP_OFFSET 0x000000c4 +#define WLAN_SYSTEM_SLEEP_HOST_IF_MSB 4 +#define WLAN_SYSTEM_SLEEP_HOST_IF_LSB 4 +#define WLAN_SYSTEM_SLEEP_HOST_IF_MASK 0x00000010 +#define WLAN_SYSTEM_SLEEP_HOST_IF_GET(x) (((x)&WLAN_SYSTEM_SLEEP_HOST_IF_MASK) >> WLAN_SYSTEM_SLEEP_HOST_IF_LSB) +#define WLAN_SYSTEM_SLEEP_HOST_IF_SET(x) (((x) << WLAN_SYSTEM_SLEEP_HOST_IF_LSB) & WLAN_SYSTEM_SLEEP_HOST_IF_MASK) +#define WLAN_SYSTEM_SLEEP_MBOX_MSB 3 +#define WLAN_SYSTEM_SLEEP_MBOX_LSB 3 +#define WLAN_SYSTEM_SLEEP_MBOX_MASK 0x00000008 +#define WLAN_SYSTEM_SLEEP_MBOX_GET(x) (((x)&WLAN_SYSTEM_SLEEP_MBOX_MASK) >> WLAN_SYSTEM_SLEEP_MBOX_LSB) +#define WLAN_SYSTEM_SLEEP_MBOX_SET(x) (((x) << WLAN_SYSTEM_SLEEP_MBOX_LSB) & WLAN_SYSTEM_SLEEP_MBOX_MASK) +#define WLAN_SYSTEM_SLEEP_MAC_IF_MSB 2 +#define WLAN_SYSTEM_SLEEP_MAC_IF_LSB 2 +#define WLAN_SYSTEM_SLEEP_MAC_IF_MASK 0x00000004 +#define WLAN_SYSTEM_SLEEP_MAC_IF_GET(x) (((x)&WLAN_SYSTEM_SLEEP_MAC_IF_MASK) >> WLAN_SYSTEM_SLEEP_MAC_IF_LSB) +#define WLAN_SYSTEM_SLEEP_MAC_IF_SET(x) (((x) << WLAN_SYSTEM_SLEEP_MAC_IF_LSB) & WLAN_SYSTEM_SLEEP_MAC_IF_MASK) +#define WLAN_SYSTEM_SLEEP_LIGHT_MSB 1 +#define WLAN_SYSTEM_SLEEP_LIGHT_LSB 1 +#define WLAN_SYSTEM_SLEEP_LIGHT_MASK 0x00000002 +#define WLAN_SYSTEM_SLEEP_LIGHT_GET(x) (((x)&WLAN_SYSTEM_SLEEP_LIGHT_MASK) >> WLAN_SYSTEM_SLEEP_LIGHT_LSB) +#define WLAN_SYSTEM_SLEEP_LIGHT_SET(x) (((x) << WLAN_SYSTEM_SLEEP_LIGHT_LSB) & WLAN_SYSTEM_SLEEP_LIGHT_MASK) +#define WLAN_SYSTEM_SLEEP_DISABLE_MSB 0 +#define WLAN_SYSTEM_SLEEP_DISABLE_LSB 0 +#define WLAN_SYSTEM_SLEEP_DISABLE_MASK 0x00000001 +#define WLAN_SYSTEM_SLEEP_DISABLE_GET(x) (((x)&WLAN_SYSTEM_SLEEP_DISABLE_MASK) >> WLAN_SYSTEM_SLEEP_DISABLE_LSB) +#define WLAN_SYSTEM_SLEEP_DISABLE_SET(x) (((x) << WLAN_SYSTEM_SLEEP_DISABLE_LSB) & WLAN_SYSTEM_SLEEP_DISABLE_MASK) + +#define WLAN_SDIO_WRAPPER_ADDRESS 0x000000c8 +#define WLAN_SDIO_WRAPPER_OFFSET 0x000000c8 +#define WLAN_SDIO_WRAPPER_SLEEP_MSB 3 +#define WLAN_SDIO_WRAPPER_SLEEP_LSB 3 +#define WLAN_SDIO_WRAPPER_SLEEP_MASK 0x00000008 +#define WLAN_SDIO_WRAPPER_SLEEP_GET(x) (((x)&WLAN_SDIO_WRAPPER_SLEEP_MASK) >> WLAN_SDIO_WRAPPER_SLEEP_LSB) +#define WLAN_SDIO_WRAPPER_SLEEP_SET(x) (((x) << WLAN_SDIO_WRAPPER_SLEEP_LSB) & WLAN_SDIO_WRAPPER_SLEEP_MASK) +#define WLAN_SDIO_WRAPPER_WAKEUP_MSB 2 +#define WLAN_SDIO_WRAPPER_WAKEUP_LSB 2 +#define WLAN_SDIO_WRAPPER_WAKEUP_MASK 0x00000004 +#define WLAN_SDIO_WRAPPER_WAKEUP_GET(x) (((x)&WLAN_SDIO_WRAPPER_WAKEUP_MASK) >> WLAN_SDIO_WRAPPER_WAKEUP_LSB) +#define WLAN_SDIO_WRAPPER_WAKEUP_SET(x) (((x) << WLAN_SDIO_WRAPPER_WAKEUP_LSB) & WLAN_SDIO_WRAPPER_WAKEUP_MASK) +#define WLAN_SDIO_WRAPPER_SOC_ON_MSB 1 +#define WLAN_SDIO_WRAPPER_SOC_ON_LSB 1 +#define WLAN_SDIO_WRAPPER_SOC_ON_MASK 0x00000002 +#define WLAN_SDIO_WRAPPER_SOC_ON_GET(x) (((x)&WLAN_SDIO_WRAPPER_SOC_ON_MASK) >> WLAN_SDIO_WRAPPER_SOC_ON_LSB) +#define WLAN_SDIO_WRAPPER_SOC_ON_SET(x) (((x) << WLAN_SDIO_WRAPPER_SOC_ON_LSB) & WLAN_SDIO_WRAPPER_SOC_ON_MASK) +#define WLAN_SDIO_WRAPPER_ON_MSB 0 +#define WLAN_SDIO_WRAPPER_ON_LSB 0 +#define WLAN_SDIO_WRAPPER_ON_MASK 0x00000001 +#define WLAN_SDIO_WRAPPER_ON_GET(x) (((x)&WLAN_SDIO_WRAPPER_ON_MASK) >> WLAN_SDIO_WRAPPER_ON_LSB) +#define WLAN_SDIO_WRAPPER_ON_SET(x) (((x) << WLAN_SDIO_WRAPPER_ON_LSB) & WLAN_SDIO_WRAPPER_ON_MASK) + +#define WLAN_MAC_SLEEP_CONTROL_ADDRESS 0x000000cc +#define WLAN_MAC_SLEEP_CONTROL_OFFSET 0x000000cc +#define WLAN_MAC_SLEEP_CONTROL_ENABLE_MSB 1 +#define WLAN_MAC_SLEEP_CONTROL_ENABLE_LSB 0 +#define WLAN_MAC_SLEEP_CONTROL_ENABLE_MASK 0x00000003 +#define WLAN_MAC_SLEEP_CONTROL_ENABLE_GET(x) \ + (((x)&WLAN_MAC_SLEEP_CONTROL_ENABLE_MASK) >> WLAN_MAC_SLEEP_CONTROL_ENABLE_LSB) +#define WLAN_MAC_SLEEP_CONTROL_ENABLE_SET(x) \ + (((x) << WLAN_MAC_SLEEP_CONTROL_ENABLE_LSB) & WLAN_MAC_SLEEP_CONTROL_ENABLE_MASK) + +#define WLAN_KEEP_AWAKE_ADDRESS 0x000000d0 +#define WLAN_KEEP_AWAKE_OFFSET 0x000000d0 +#define WLAN_KEEP_AWAKE_COUNT_MSB 7 +#define WLAN_KEEP_AWAKE_COUNT_LSB 0 +#define WLAN_KEEP_AWAKE_COUNT_MASK 0x000000ff +#define WLAN_KEEP_AWAKE_COUNT_GET(x) (((x)&WLAN_KEEP_AWAKE_COUNT_MASK) >> WLAN_KEEP_AWAKE_COUNT_LSB) +#define WLAN_KEEP_AWAKE_COUNT_SET(x) (((x) << WLAN_KEEP_AWAKE_COUNT_LSB) & WLAN_KEEP_AWAKE_COUNT_MASK) + +#define WLAN_LPO_CAL_TIME_ADDRESS 0x000000d4 +#define WLAN_LPO_CAL_TIME_OFFSET 0x000000d4 +#define WLAN_LPO_CAL_TIME_LENGTH_MSB 13 +#define WLAN_LPO_CAL_TIME_LENGTH_LSB 0 +#define WLAN_LPO_CAL_TIME_LENGTH_MASK 0x00003fff +#define WLAN_LPO_CAL_TIME_LENGTH_GET(x) (((x)&WLAN_LPO_CAL_TIME_LENGTH_MASK) >> WLAN_LPO_CAL_TIME_LENGTH_LSB) +#define WLAN_LPO_CAL_TIME_LENGTH_SET(x) (((x) << WLAN_LPO_CAL_TIME_LENGTH_LSB) & WLAN_LPO_CAL_TIME_LENGTH_MASK) + +#define WLAN_LPO_INIT_DIVIDEND_INT_ADDRESS 0x000000d8 +#define WLAN_LPO_INIT_DIVIDEND_INT_OFFSET 0x000000d8 +#define WLAN_LPO_INIT_DIVIDEND_INT_VALUE_MSB 23 +#define WLAN_LPO_INIT_DIVIDEND_INT_VALUE_LSB 0 +#define WLAN_LPO_INIT_DIVIDEND_INT_VALUE_MASK 0x00ffffff +#define WLAN_LPO_INIT_DIVIDEND_INT_VALUE_GET(x) \ + (((x)&WLAN_LPO_INIT_DIVIDEND_INT_VALUE_MASK) >> WLAN_LPO_INIT_DIVIDEND_INT_VALUE_LSB) +#define WLAN_LPO_INIT_DIVIDEND_INT_VALUE_SET(x) \ + (((x) << WLAN_LPO_INIT_DIVIDEND_INT_VALUE_LSB) & WLAN_LPO_INIT_DIVIDEND_INT_VALUE_MASK) + +#define WLAN_LPO_INIT_DIVIDEND_FRACTION_ADDRESS 0x000000dc +#define WLAN_LPO_INIT_DIVIDEND_FRACTION_OFFSET 0x000000dc +#define WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_MSB 10 +#define WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_LSB 0 +#define WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_MASK 0x000007ff +#define WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_GET(x) \ + (((x)&WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_MASK) >> WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_LSB) +#define WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_SET(x) \ + (((x) << WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_LSB) & WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_MASK) + +#define WLAN_LPO_CAL_ADDRESS 0x000000e0 +#define WLAN_LPO_CAL_OFFSET 0x000000e0 +#define WLAN_LPO_CAL_ENABLE_MSB 20 +#define WLAN_LPO_CAL_ENABLE_LSB 20 +#define WLAN_LPO_CAL_ENABLE_MASK 0x00100000 +#define WLAN_LPO_CAL_ENABLE_GET(x) (((x)&WLAN_LPO_CAL_ENABLE_MASK) >> WLAN_LPO_CAL_ENABLE_LSB) +#define WLAN_LPO_CAL_ENABLE_SET(x) (((x) << WLAN_LPO_CAL_ENABLE_LSB) & WLAN_LPO_CAL_ENABLE_MASK) +#define WLAN_LPO_CAL_COUNT_MSB 19 +#define WLAN_LPO_CAL_COUNT_LSB 0 +#define WLAN_LPO_CAL_COUNT_MASK 0x000fffff +#define WLAN_LPO_CAL_COUNT_GET(x) (((x)&WLAN_LPO_CAL_COUNT_MASK) >> WLAN_LPO_CAL_COUNT_LSB) +#define WLAN_LPO_CAL_COUNT_SET(x) (((x) << WLAN_LPO_CAL_COUNT_LSB) & WLAN_LPO_CAL_COUNT_MASK) + +#define WLAN_LPO_CAL_TEST_CONTROL_ADDRESS 0x000000e4 +#define WLAN_LPO_CAL_TEST_CONTROL_OFFSET 0x000000e4 +#define WLAN_LPO_CAL_TEST_CONTROL_ENABLE_MSB 5 +#define WLAN_LPO_CAL_TEST_CONTROL_ENABLE_LSB 5 +#define WLAN_LPO_CAL_TEST_CONTROL_ENABLE_MASK 0x00000020 +#define WLAN_LPO_CAL_TEST_CONTROL_ENABLE_GET(x) \ + (((x)&WLAN_LPO_CAL_TEST_CONTROL_ENABLE_MASK) >> WLAN_LPO_CAL_TEST_CONTROL_ENABLE_LSB) +#define WLAN_LPO_CAL_TEST_CONTROL_ENABLE_SET(x) \ + (((x) << WLAN_LPO_CAL_TEST_CONTROL_ENABLE_LSB) & WLAN_LPO_CAL_TEST_CONTROL_ENABLE_MASK) +#define WLAN_LPO_CAL_TEST_CONTROL_RTC_CYCLES_MSB 4 +#define WLAN_LPO_CAL_TEST_CONTROL_RTC_CYCLES_LSB 0 +#define WLAN_LPO_CAL_TEST_CONTROL_RTC_CYCLES_MASK 0x0000001f +#define WLAN_LPO_CAL_TEST_CONTROL_RTC_CYCLES_GET(x) \ + (((x)&WLAN_LPO_CAL_TEST_CONTROL_RTC_CYCLES_MASK) >> WLAN_LPO_CAL_TEST_CONTROL_RTC_CYCLES_LSB) +#define WLAN_LPO_CAL_TEST_CONTROL_RTC_CYCLES_SET(x) \ + (((x) << WLAN_LPO_CAL_TEST_CONTROL_RTC_CYCLES_LSB) & WLAN_LPO_CAL_TEST_CONTROL_RTC_CYCLES_MASK) + +#define WLAN_LPO_CAL_TEST_STATUS_ADDRESS 0x000000e8 +#define WLAN_LPO_CAL_TEST_STATUS_OFFSET 0x000000e8 +#define WLAN_LPO_CAL_TEST_STATUS_READY_MSB 16 +#define WLAN_LPO_CAL_TEST_STATUS_READY_LSB 16 +#define WLAN_LPO_CAL_TEST_STATUS_READY_MASK 0x00010000 +#define WLAN_LPO_CAL_TEST_STATUS_READY_GET(x) \ + (((x)&WLAN_LPO_CAL_TEST_STATUS_READY_MASK) >> WLAN_LPO_CAL_TEST_STATUS_READY_LSB) +#define WLAN_LPO_CAL_TEST_STATUS_READY_SET(x) \ + (((x) << WLAN_LPO_CAL_TEST_STATUS_READY_LSB) & WLAN_LPO_CAL_TEST_STATUS_READY_MASK) +#define WLAN_LPO_CAL_TEST_STATUS_COUNT_MSB 15 +#define WLAN_LPO_CAL_TEST_STATUS_COUNT_LSB 0 +#define WLAN_LPO_CAL_TEST_STATUS_COUNT_MASK 0x0000ffff +#define WLAN_LPO_CAL_TEST_STATUS_COUNT_GET(x) \ + (((x)&WLAN_LPO_CAL_TEST_STATUS_COUNT_MASK) >> WLAN_LPO_CAL_TEST_STATUS_COUNT_LSB) +#define WLAN_LPO_CAL_TEST_STATUS_COUNT_SET(x) \ + (((x) << WLAN_LPO_CAL_TEST_STATUS_COUNT_LSB) & WLAN_LPO_CAL_TEST_STATUS_COUNT_MASK) + +#define WLAN_CHIP_ID_ADDRESS 0x000000ec +#define WLAN_CHIP_ID_OFFSET 0x000000ec +#define WLAN_CHIP_ID_DEVICE_ID_MSB 31 +#define WLAN_CHIP_ID_DEVICE_ID_LSB 16 +#define WLAN_CHIP_ID_DEVICE_ID_MASK 0xffff0000 +#define WLAN_CHIP_ID_DEVICE_ID_GET(x) (((x)&WLAN_CHIP_ID_DEVICE_ID_MASK) >> WLAN_CHIP_ID_DEVICE_ID_LSB) +#define WLAN_CHIP_ID_DEVICE_ID_SET(x) (((x) << WLAN_CHIP_ID_DEVICE_ID_LSB) & WLAN_CHIP_ID_DEVICE_ID_MASK) +#define WLAN_CHIP_ID_CONFIG_ID_MSB 15 +#define WLAN_CHIP_ID_CONFIG_ID_LSB 4 +#define WLAN_CHIP_ID_CONFIG_ID_MASK 0x0000fff0 +#define WLAN_CHIP_ID_CONFIG_ID_GET(x) (((x)&WLAN_CHIP_ID_CONFIG_ID_MASK) >> WLAN_CHIP_ID_CONFIG_ID_LSB) +#define WLAN_CHIP_ID_CONFIG_ID_SET(x) (((x) << WLAN_CHIP_ID_CONFIG_ID_LSB) & WLAN_CHIP_ID_CONFIG_ID_MASK) +#define WLAN_CHIP_ID_VERSION_ID_MSB 3 +#define WLAN_CHIP_ID_VERSION_ID_LSB 0 +#define WLAN_CHIP_ID_VERSION_ID_MASK 0x0000000f +#define WLAN_CHIP_ID_VERSION_ID_GET(x) (((x)&WLAN_CHIP_ID_VERSION_ID_MASK) >> WLAN_CHIP_ID_VERSION_ID_LSB) +#define WLAN_CHIP_ID_VERSION_ID_SET(x) (((x) << WLAN_CHIP_ID_VERSION_ID_LSB) & WLAN_CHIP_ID_VERSION_ID_MASK) + +#define WLAN_DERIVED_RTC_CLK_ADDRESS 0x000000f0 +#define WLAN_DERIVED_RTC_CLK_OFFSET 0x000000f0 +#define WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_MSB 20 +#define WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_LSB 20 +#define WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_MASK 0x00100000 +#define WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_GET(x) \ + (((x)&WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_MASK) >> WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_LSB) +#define WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_SET(x) \ + (((x) << WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_LSB) & WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_EN_MASK) +#define WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_MSB 18 +#define WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_LSB 18 +#define WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_MASK 0x00040000 +#define WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_GET(x) \ + (((x)&WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_MASK) >> WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_LSB) +#define WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_SET(x) \ + (((x) << WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_LSB) & WLAN_DERIVED_RTC_CLK_EXTERNAL_DETECT_MASK) +#define WLAN_DERIVED_RTC_CLK_FORCE_MSB 17 +#define WLAN_DERIVED_RTC_CLK_FORCE_LSB 16 +#define WLAN_DERIVED_RTC_CLK_FORCE_MASK 0x00030000 +#define WLAN_DERIVED_RTC_CLK_FORCE_GET(x) (((x)&WLAN_DERIVED_RTC_CLK_FORCE_MASK) >> WLAN_DERIVED_RTC_CLK_FORCE_LSB) +#define WLAN_DERIVED_RTC_CLK_FORCE_SET(x) (((x) << WLAN_DERIVED_RTC_CLK_FORCE_LSB) & WLAN_DERIVED_RTC_CLK_FORCE_MASK) +#define WLAN_DERIVED_RTC_CLK_PERIOD_MSB 15 +#define WLAN_DERIVED_RTC_CLK_PERIOD_LSB 1 +#define WLAN_DERIVED_RTC_CLK_PERIOD_MASK 0x0000fffe +#define WLAN_DERIVED_RTC_CLK_PERIOD_GET(x) (((x)&WLAN_DERIVED_RTC_CLK_PERIOD_MASK) >> WLAN_DERIVED_RTC_CLK_PERIOD_LSB) +#define WLAN_DERIVED_RTC_CLK_PERIOD_SET(x) (((x) << WLAN_DERIVED_RTC_CLK_PERIOD_LSB) & WLAN_DERIVED_RTC_CLK_PERIOD_MASK) + +#define MAC_PCU_SLP32_MODE_ADDRESS 0x000000f4 +#define MAC_PCU_SLP32_MODE_OFFSET 0x000000f4 +#define MAC_PCU_SLP32_MODE_TSF2_WRITE_STATUS_MSB 24 +#define MAC_PCU_SLP32_MODE_TSF2_WRITE_STATUS_LSB 24 +#define MAC_PCU_SLP32_MODE_TSF2_WRITE_STATUS_MASK 0x01000000 +#define MAC_PCU_SLP32_MODE_TSF2_WRITE_STATUS_GET(x) \ + (((x)&MAC_PCU_SLP32_MODE_TSF2_WRITE_STATUS_MASK) >> MAC_PCU_SLP32_MODE_TSF2_WRITE_STATUS_LSB) +#define MAC_PCU_SLP32_MODE_TSF2_WRITE_STATUS_SET(x) \ + (((x) << MAC_PCU_SLP32_MODE_TSF2_WRITE_STATUS_LSB) & MAC_PCU_SLP32_MODE_TSF2_WRITE_STATUS_MASK) +#define MAC_PCU_SLP32_MODE_FORCE_BIAS_BLOCK_ON_MSB 23 +#define MAC_PCU_SLP32_MODE_FORCE_BIAS_BLOCK_ON_LSB 23 +#define MAC_PCU_SLP32_MODE_FORCE_BIAS_BLOCK_ON_MASK 0x00800000 +#define MAC_PCU_SLP32_MODE_FORCE_BIAS_BLOCK_ON_GET(x) \ + (((x)&MAC_PCU_SLP32_MODE_FORCE_BIAS_BLOCK_ON_MASK) >> MAC_PCU_SLP32_MODE_FORCE_BIAS_BLOCK_ON_LSB) +#define MAC_PCU_SLP32_MODE_FORCE_BIAS_BLOCK_ON_SET(x) \ + (((x) << MAC_PCU_SLP32_MODE_FORCE_BIAS_BLOCK_ON_LSB) & MAC_PCU_SLP32_MODE_FORCE_BIAS_BLOCK_ON_MASK) +#define MAC_PCU_SLP32_MODE_DISABLE_32KHZ_MSB 22 +#define MAC_PCU_SLP32_MODE_DISABLE_32KHZ_LSB 22 +#define MAC_PCU_SLP32_MODE_DISABLE_32KHZ_MASK 0x00400000 +#define MAC_PCU_SLP32_MODE_DISABLE_32KHZ_GET(x) \ + (((x)&MAC_PCU_SLP32_MODE_DISABLE_32KHZ_MASK) >> MAC_PCU_SLP32_MODE_DISABLE_32KHZ_LSB) +#define MAC_PCU_SLP32_MODE_DISABLE_32KHZ_SET(x) \ + (((x) << MAC_PCU_SLP32_MODE_DISABLE_32KHZ_LSB) & MAC_PCU_SLP32_MODE_DISABLE_32KHZ_MASK) +#define MAC_PCU_SLP32_MODE_TSF_WRITE_STATUS_MSB 21 +#define MAC_PCU_SLP32_MODE_TSF_WRITE_STATUS_LSB 21 +#define MAC_PCU_SLP32_MODE_TSF_WRITE_STATUS_MASK 0x00200000 +#define MAC_PCU_SLP32_MODE_TSF_WRITE_STATUS_GET(x) \ + (((x)&MAC_PCU_SLP32_MODE_TSF_WRITE_STATUS_MASK) >> MAC_PCU_SLP32_MODE_TSF_WRITE_STATUS_LSB) +#define MAC_PCU_SLP32_MODE_TSF_WRITE_STATUS_SET(x) \ + (((x) << MAC_PCU_SLP32_MODE_TSF_WRITE_STATUS_LSB) & MAC_PCU_SLP32_MODE_TSF_WRITE_STATUS_MASK) +#define MAC_PCU_SLP32_MODE_ENABLE_MSB 20 +#define MAC_PCU_SLP32_MODE_ENABLE_LSB 20 +#define MAC_PCU_SLP32_MODE_ENABLE_MASK 0x00100000 +#define MAC_PCU_SLP32_MODE_ENABLE_GET(x) (((x)&MAC_PCU_SLP32_MODE_ENABLE_MASK) >> MAC_PCU_SLP32_MODE_ENABLE_LSB) +#define MAC_PCU_SLP32_MODE_ENABLE_SET(x) (((x) << MAC_PCU_SLP32_MODE_ENABLE_LSB) & MAC_PCU_SLP32_MODE_ENABLE_MASK) +#define MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_MSB 19 +#define MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_LSB 0 +#define MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_MASK 0x000fffff +#define MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_GET(x) \ + (((x)&MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_MASK) >> MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_LSB) +#define MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_SET(x) \ + (((x) << MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_LSB) & MAC_PCU_SLP32_MODE_HALF_CLK_LATENCY_MASK) + +#define MAC_PCU_SLP32_WAKE_ADDRESS 0x000000f8 +#define MAC_PCU_SLP32_WAKE_OFFSET 0x000000f8 +#define MAC_PCU_SLP32_WAKE_XTL_TIME_MSB 15 +#define MAC_PCU_SLP32_WAKE_XTL_TIME_LSB 0 +#define MAC_PCU_SLP32_WAKE_XTL_TIME_MASK 0x0000ffff +#define MAC_PCU_SLP32_WAKE_XTL_TIME_GET(x) (((x)&MAC_PCU_SLP32_WAKE_XTL_TIME_MASK) >> MAC_PCU_SLP32_WAKE_XTL_TIME_LSB) +#define MAC_PCU_SLP32_WAKE_XTL_TIME_SET(x) (((x) << MAC_PCU_SLP32_WAKE_XTL_TIME_LSB) & MAC_PCU_SLP32_WAKE_XTL_TIME_MASK) + +#define MAC_PCU_SLP32_INC_ADDRESS 0x000000fc +#define MAC_PCU_SLP32_INC_OFFSET 0x000000fc +#define MAC_PCU_SLP32_INC_TSF_INC_MSB 19 +#define MAC_PCU_SLP32_INC_TSF_INC_LSB 0 +#define MAC_PCU_SLP32_INC_TSF_INC_MASK 0x000fffff +#define MAC_PCU_SLP32_INC_TSF_INC_GET(x) (((x)&MAC_PCU_SLP32_INC_TSF_INC_MASK) >> MAC_PCU_SLP32_INC_TSF_INC_LSB) +#define MAC_PCU_SLP32_INC_TSF_INC_SET(x) (((x) << MAC_PCU_SLP32_INC_TSF_INC_LSB) & MAC_PCU_SLP32_INC_TSF_INC_MASK) + +#define MAC_PCU_SLP_MIB1_ADDRESS 0x00000100 +#define MAC_PCU_SLP_MIB1_OFFSET 0x00000100 +#define MAC_PCU_SLP_MIB1_SLEEP_CNT_MSB 31 +#define MAC_PCU_SLP_MIB1_SLEEP_CNT_LSB 0 +#define MAC_PCU_SLP_MIB1_SLEEP_CNT_MASK 0xffffffff +#define MAC_PCU_SLP_MIB1_SLEEP_CNT_GET(x) (((x)&MAC_PCU_SLP_MIB1_SLEEP_CNT_MASK) >> MAC_PCU_SLP_MIB1_SLEEP_CNT_LSB) +#define MAC_PCU_SLP_MIB1_SLEEP_CNT_SET(x) (((x) << MAC_PCU_SLP_MIB1_SLEEP_CNT_LSB) & MAC_PCU_SLP_MIB1_SLEEP_CNT_MASK) + +#define MAC_PCU_SLP_MIB2_ADDRESS 0x00000104 +#define MAC_PCU_SLP_MIB2_OFFSET 0x00000104 +#define MAC_PCU_SLP_MIB2_CYCLE_CNT_MSB 31 +#define MAC_PCU_SLP_MIB2_CYCLE_CNT_LSB 0 +#define MAC_PCU_SLP_MIB2_CYCLE_CNT_MASK 0xffffffff +#define MAC_PCU_SLP_MIB2_CYCLE_CNT_GET(x) (((x)&MAC_PCU_SLP_MIB2_CYCLE_CNT_MASK) >> MAC_PCU_SLP_MIB2_CYCLE_CNT_LSB) +#define MAC_PCU_SLP_MIB2_CYCLE_CNT_SET(x) (((x) << MAC_PCU_SLP_MIB2_CYCLE_CNT_LSB) & MAC_PCU_SLP_MIB2_CYCLE_CNT_MASK) + +#define MAC_PCU_SLP_MIB3_ADDRESS 0x00000108 +#define MAC_PCU_SLP_MIB3_OFFSET 0x00000108 +#define MAC_PCU_SLP_MIB3_PENDING_MSB 1 +#define MAC_PCU_SLP_MIB3_PENDING_LSB 1 +#define MAC_PCU_SLP_MIB3_PENDING_MASK 0x00000002 +#define MAC_PCU_SLP_MIB3_PENDING_GET(x) (((x)&MAC_PCU_SLP_MIB3_PENDING_MASK) >> MAC_PCU_SLP_MIB3_PENDING_LSB) +#define MAC_PCU_SLP_MIB3_PENDING_SET(x) (((x) << MAC_PCU_SLP_MIB3_PENDING_LSB) & MAC_PCU_SLP_MIB3_PENDING_MASK) +#define MAC_PCU_SLP_MIB3_CLR_CNT_MSB 0 +#define MAC_PCU_SLP_MIB3_CLR_CNT_LSB 0 +#define MAC_PCU_SLP_MIB3_CLR_CNT_MASK 0x00000001 +#define MAC_PCU_SLP_MIB3_CLR_CNT_GET(x) (((x)&MAC_PCU_SLP_MIB3_CLR_CNT_MASK) >> MAC_PCU_SLP_MIB3_CLR_CNT_LSB) +#define MAC_PCU_SLP_MIB3_CLR_CNT_SET(x) (((x) << MAC_PCU_SLP_MIB3_CLR_CNT_LSB) & MAC_PCU_SLP_MIB3_CLR_CNT_MASK) + +#define WLAN_POWER_REG_ADDRESS 0x0000010c +#define WLAN_POWER_REG_OFFSET 0x0000010c +#define WLAN_POWER_REG_SLEEP_MAKE_N_BREAK_EN_MSB 15 +#define WLAN_POWER_REG_SLEEP_MAKE_N_BREAK_EN_LSB 15 +#define WLAN_POWER_REG_SLEEP_MAKE_N_BREAK_EN_MASK 0x00008000 +#define WLAN_POWER_REG_SLEEP_MAKE_N_BREAK_EN_GET(x) \ + (((x)&WLAN_POWER_REG_SLEEP_MAKE_N_BREAK_EN_MASK) >> WLAN_POWER_REG_SLEEP_MAKE_N_BREAK_EN_LSB) +#define WLAN_POWER_REG_SLEEP_MAKE_N_BREAK_EN_SET(x) \ + (((x) << WLAN_POWER_REG_SLEEP_MAKE_N_BREAK_EN_LSB) & WLAN_POWER_REG_SLEEP_MAKE_N_BREAK_EN_MASK) +#define WLAN_POWER_REG_DEBUG_EN_MSB 14 +#define WLAN_POWER_REG_DEBUG_EN_LSB 14 +#define WLAN_POWER_REG_DEBUG_EN_MASK 0x00004000 +#define WLAN_POWER_REG_DEBUG_EN_GET(x) (((x)&WLAN_POWER_REG_DEBUG_EN_MASK) >> WLAN_POWER_REG_DEBUG_EN_LSB) +#define WLAN_POWER_REG_DEBUG_EN_SET(x) (((x) << WLAN_POWER_REG_DEBUG_EN_LSB) & WLAN_POWER_REG_DEBUG_EN_MASK) +#define WLAN_POWER_REG_WLAN_BB_PWD_EN_MSB 13 +#define WLAN_POWER_REG_WLAN_BB_PWD_EN_LSB 13 +#define WLAN_POWER_REG_WLAN_BB_PWD_EN_MASK 0x00002000 +#define WLAN_POWER_REG_WLAN_BB_PWD_EN_GET(x) \ + (((x)&WLAN_POWER_REG_WLAN_BB_PWD_EN_MASK) >> WLAN_POWER_REG_WLAN_BB_PWD_EN_LSB) +#define WLAN_POWER_REG_WLAN_BB_PWD_EN_SET(x) \ + (((x) << WLAN_POWER_REG_WLAN_BB_PWD_EN_LSB) & WLAN_POWER_REG_WLAN_BB_PWD_EN_MASK) +#define WLAN_POWER_REG_WLAN_MAC_PWD_EN_MSB 12 +#define WLAN_POWER_REG_WLAN_MAC_PWD_EN_LSB 12 +#define WLAN_POWER_REG_WLAN_MAC_PWD_EN_MASK 0x00001000 +#define WLAN_POWER_REG_WLAN_MAC_PWD_EN_GET(x) \ + (((x)&WLAN_POWER_REG_WLAN_MAC_PWD_EN_MASK) >> WLAN_POWER_REG_WLAN_MAC_PWD_EN_LSB) +#define WLAN_POWER_REG_WLAN_MAC_PWD_EN_SET(x) \ + (((x) << WLAN_POWER_REG_WLAN_MAC_PWD_EN_LSB) & WLAN_POWER_REG_WLAN_MAC_PWD_EN_MASK) +#define WLAN_POWER_REG_VLVL_MSB 11 +#define WLAN_POWER_REG_VLVL_LSB 8 +#define WLAN_POWER_REG_VLVL_MASK 0x00000f00 +#define WLAN_POWER_REG_VLVL_GET(x) (((x)&WLAN_POWER_REG_VLVL_MASK) >> WLAN_POWER_REG_VLVL_LSB) +#define WLAN_POWER_REG_VLVL_SET(x) (((x) << WLAN_POWER_REG_VLVL_LSB) & WLAN_POWER_REG_VLVL_MASK) +#define WLAN_POWER_REG_CPU_INT_ENABLE_MSB 7 +#define WLAN_POWER_REG_CPU_INT_ENABLE_LSB 7 +#define WLAN_POWER_REG_CPU_INT_ENABLE_MASK 0x00000080 +#define WLAN_POWER_REG_CPU_INT_ENABLE_GET(x) \ + (((x)&WLAN_POWER_REG_CPU_INT_ENABLE_MASK) >> WLAN_POWER_REG_CPU_INT_ENABLE_LSB) +#define WLAN_POWER_REG_CPU_INT_ENABLE_SET(x) \ + (((x) << WLAN_POWER_REG_CPU_INT_ENABLE_LSB) & WLAN_POWER_REG_CPU_INT_ENABLE_MASK) +#define WLAN_POWER_REG_WLAN_ISO_DIS_MSB 6 +#define WLAN_POWER_REG_WLAN_ISO_DIS_LSB 6 +#define WLAN_POWER_REG_WLAN_ISO_DIS_MASK 0x00000040 +#define WLAN_POWER_REG_WLAN_ISO_DIS_GET(x) (((x)&WLAN_POWER_REG_WLAN_ISO_DIS_MASK) >> WLAN_POWER_REG_WLAN_ISO_DIS_LSB) +#define WLAN_POWER_REG_WLAN_ISO_DIS_SET(x) (((x) << WLAN_POWER_REG_WLAN_ISO_DIS_LSB) & WLAN_POWER_REG_WLAN_ISO_DIS_MASK) +#define WLAN_POWER_REG_WLAN_ISO_CNTL_MSB 5 +#define WLAN_POWER_REG_WLAN_ISO_CNTL_LSB 5 +#define WLAN_POWER_REG_WLAN_ISO_CNTL_MASK 0x00000020 +#define WLAN_POWER_REG_WLAN_ISO_CNTL_GET(x) \ + (((x)&WLAN_POWER_REG_WLAN_ISO_CNTL_MASK) >> WLAN_POWER_REG_WLAN_ISO_CNTL_LSB) +#define WLAN_POWER_REG_WLAN_ISO_CNTL_SET(x) \ + (((x) << WLAN_POWER_REG_WLAN_ISO_CNTL_LSB) & WLAN_POWER_REG_WLAN_ISO_CNTL_MASK) +#define WLAN_POWER_REG_RADIO_PWD_EN_MSB 4 +#define WLAN_POWER_REG_RADIO_PWD_EN_LSB 4 +#define WLAN_POWER_REG_RADIO_PWD_EN_MASK 0x00000010 +#define WLAN_POWER_REG_RADIO_PWD_EN_GET(x) (((x)&WLAN_POWER_REG_RADIO_PWD_EN_MASK) >> WLAN_POWER_REG_RADIO_PWD_EN_LSB) +#define WLAN_POWER_REG_RADIO_PWD_EN_SET(x) (((x) << WLAN_POWER_REG_RADIO_PWD_EN_LSB) & WLAN_POWER_REG_RADIO_PWD_EN_MASK) +#define WLAN_POWER_REG_SOC_ISO_EN_MSB 3 +#define WLAN_POWER_REG_SOC_ISO_EN_LSB 3 +#define WLAN_POWER_REG_SOC_ISO_EN_MASK 0x00000008 +#define WLAN_POWER_REG_SOC_ISO_EN_GET(x) (((x)&WLAN_POWER_REG_SOC_ISO_EN_MASK) >> WLAN_POWER_REG_SOC_ISO_EN_LSB) +#define WLAN_POWER_REG_SOC_ISO_EN_SET(x) (((x) << WLAN_POWER_REG_SOC_ISO_EN_LSB) & WLAN_POWER_REG_SOC_ISO_EN_MASK) +#define WLAN_POWER_REG_WLAN_ISO_EN_MSB 2 +#define WLAN_POWER_REG_WLAN_ISO_EN_LSB 2 +#define WLAN_POWER_REG_WLAN_ISO_EN_MASK 0x00000004 +#define WLAN_POWER_REG_WLAN_ISO_EN_GET(x) (((x)&WLAN_POWER_REG_WLAN_ISO_EN_MASK) >> WLAN_POWER_REG_WLAN_ISO_EN_LSB) +#define WLAN_POWER_REG_WLAN_ISO_EN_SET(x) (((x) << WLAN_POWER_REG_WLAN_ISO_EN_LSB) & WLAN_POWER_REG_WLAN_ISO_EN_MASK) +#define WLAN_POWER_REG_WLAN_PWD_EN_MSB 1 +#define WLAN_POWER_REG_WLAN_PWD_EN_LSB 1 +#define WLAN_POWER_REG_WLAN_PWD_EN_MASK 0x00000002 +#define WLAN_POWER_REG_WLAN_PWD_EN_GET(x) (((x)&WLAN_POWER_REG_WLAN_PWD_EN_MASK) >> WLAN_POWER_REG_WLAN_PWD_EN_LSB) +#define WLAN_POWER_REG_WLAN_PWD_EN_SET(x) (((x) << WLAN_POWER_REG_WLAN_PWD_EN_LSB) & WLAN_POWER_REG_WLAN_PWD_EN_MASK) +#define WLAN_POWER_REG_POWER_EN_MSB 0 +#define WLAN_POWER_REG_POWER_EN_LSB 0 +#define WLAN_POWER_REG_POWER_EN_MASK 0x00000001 +#define WLAN_POWER_REG_POWER_EN_GET(x) (((x)&WLAN_POWER_REG_POWER_EN_MASK) >> WLAN_POWER_REG_POWER_EN_LSB) +#define WLAN_POWER_REG_POWER_EN_SET(x) (((x) << WLAN_POWER_REG_POWER_EN_LSB) & WLAN_POWER_REG_POWER_EN_MASK) + +#define WLAN_CORE_CLK_CTRL_ADDRESS 0x00000110 +#define WLAN_CORE_CLK_CTRL_OFFSET 0x00000110 +#define WLAN_CORE_CLK_CTRL_DIV_MSB 2 +#define WLAN_CORE_CLK_CTRL_DIV_LSB 0 +#define WLAN_CORE_CLK_CTRL_DIV_MASK 0x00000007 +#define WLAN_CORE_CLK_CTRL_DIV_GET(x) (((x)&WLAN_CORE_CLK_CTRL_DIV_MASK) >> WLAN_CORE_CLK_CTRL_DIV_LSB) +#define WLAN_CORE_CLK_CTRL_DIV_SET(x) (((x) << WLAN_CORE_CLK_CTRL_DIV_LSB) & WLAN_CORE_CLK_CTRL_DIV_MASK) + +#define WLAN_GPIO_WAKEUP_CONTROL_ADDRESS 0x00000114 +#define WLAN_GPIO_WAKEUP_CONTROL_OFFSET 0x00000114 +#define WLAN_GPIO_WAKEUP_CONTROL_ENABLE_MSB 0 +#define WLAN_GPIO_WAKEUP_CONTROL_ENABLE_LSB 0 +#define WLAN_GPIO_WAKEUP_CONTROL_ENABLE_MASK 0x00000001 +#define WLAN_GPIO_WAKEUP_CONTROL_ENABLE_GET(x) \ + (((x)&WLAN_GPIO_WAKEUP_CONTROL_ENABLE_MASK) >> WLAN_GPIO_WAKEUP_CONTROL_ENABLE_LSB) +#define WLAN_GPIO_WAKEUP_CONTROL_ENABLE_SET(x) \ + (((x) << WLAN_GPIO_WAKEUP_CONTROL_ENABLE_LSB) & WLAN_GPIO_WAKEUP_CONTROL_ENABLE_MASK) + +#define HT_ADDRESS 0x00000118 +#define HT_OFFSET 0x00000118 +#define HT_MODE_MSB 0 +#define HT_MODE_LSB 0 +#define HT_MODE_MASK 0x00000001 +#define HT_MODE_GET(x) (((x)&HT_MODE_MASK) >> HT_MODE_LSB) +#define HT_MODE_SET(x) (((x) << HT_MODE_LSB) & HT_MODE_MASK) + +#define MAC_PCU_TSF_L32_ADDRESS 0x0000011c +#define MAC_PCU_TSF_L32_OFFSET 0x0000011c +#define MAC_PCU_TSF_L32_VALUE_MSB 31 +#define MAC_PCU_TSF_L32_VALUE_LSB 0 +#define MAC_PCU_TSF_L32_VALUE_MASK 0xffffffff +#define MAC_PCU_TSF_L32_VALUE_GET(x) (((x)&MAC_PCU_TSF_L32_VALUE_MASK) >> MAC_PCU_TSF_L32_VALUE_LSB) +#define MAC_PCU_TSF_L32_VALUE_SET(x) (((x) << MAC_PCU_TSF_L32_VALUE_LSB) & MAC_PCU_TSF_L32_VALUE_MASK) + +#define MAC_PCU_TSF_U32_ADDRESS 0x00000120 +#define MAC_PCU_TSF_U32_OFFSET 0x00000120 +#define MAC_PCU_TSF_U32_VALUE_MSB 31 +#define MAC_PCU_TSF_U32_VALUE_LSB 0 +#define MAC_PCU_TSF_U32_VALUE_MASK 0xffffffff +#define MAC_PCU_TSF_U32_VALUE_GET(x) (((x)&MAC_PCU_TSF_U32_VALUE_MASK) >> MAC_PCU_TSF_U32_VALUE_LSB) +#define MAC_PCU_TSF_U32_VALUE_SET(x) (((x) << MAC_PCU_TSF_U32_VALUE_LSB) & MAC_PCU_TSF_U32_VALUE_MASK) + +#define MAC_PCU_WBTIMER_ADDRESS 0x00000124 +#define MAC_PCU_WBTIMER_OFFSET 0x00000124 +#define MAC_PCU_WBTIMER_VALUE_MSB 31 +#define MAC_PCU_WBTIMER_VALUE_LSB 0 +#define MAC_PCU_WBTIMER_VALUE_MASK 0xffffffff +#define MAC_PCU_WBTIMER_VALUE_GET(x) (((x)&MAC_PCU_WBTIMER_VALUE_MASK) >> MAC_PCU_WBTIMER_VALUE_LSB) +#define MAC_PCU_WBTIMER_VALUE_SET(x) (((x) << MAC_PCU_WBTIMER_VALUE_LSB) & MAC_PCU_WBTIMER_VALUE_MASK) + +#define MAC_PCU_GENERIC_TIMERS_ADDRESS 0x00000140 +#define MAC_PCU_GENERIC_TIMERS_OFFSET 0x00000140 +#define MAC_PCU_GENERIC_TIMERS_DATA_MSB 31 +#define MAC_PCU_GENERIC_TIMERS_DATA_LSB 0 +#define MAC_PCU_GENERIC_TIMERS_DATA_MASK 0xffffffff +#define MAC_PCU_GENERIC_TIMERS_DATA_GET(x) (((x)&MAC_PCU_GENERIC_TIMERS_DATA_MASK) >> MAC_PCU_GENERIC_TIMERS_DATA_LSB) +#define MAC_PCU_GENERIC_TIMERS_DATA_SET(x) (((x) << MAC_PCU_GENERIC_TIMERS_DATA_LSB) & MAC_PCU_GENERIC_TIMERS_DATA_MASK) + +#define MAC_PCU_GENERIC_TIMERS_MODE_ADDRESS 0x00000180 +#define MAC_PCU_GENERIC_TIMERS_MODE_OFFSET 0x00000180 +#define MAC_PCU_GENERIC_TIMERS_MODE_ENABLE_MSB 15 +#define MAC_PCU_GENERIC_TIMERS_MODE_ENABLE_LSB 0 +#define MAC_PCU_GENERIC_TIMERS_MODE_ENABLE_MASK 0x0000ffff +#define MAC_PCU_GENERIC_TIMERS_MODE_ENABLE_GET(x) \ + (((x)&MAC_PCU_GENERIC_TIMERS_MODE_ENABLE_MASK) >> MAC_PCU_GENERIC_TIMERS_MODE_ENABLE_LSB) +#define MAC_PCU_GENERIC_TIMERS_MODE_ENABLE_SET(x) \ + (((x) << MAC_PCU_GENERIC_TIMERS_MODE_ENABLE_LSB) & MAC_PCU_GENERIC_TIMERS_MODE_ENABLE_MASK) + +#define MAC_PCU_GENERIC_TIMERS2_ADDRESS 0x000001c0 +#define MAC_PCU_GENERIC_TIMERS2_OFFSET 0x000001c0 +#define MAC_PCU_GENERIC_TIMERS2_DATA_MSB 31 +#define MAC_PCU_GENERIC_TIMERS2_DATA_LSB 0 +#define MAC_PCU_GENERIC_TIMERS2_DATA_MASK 0xffffffff +#define MAC_PCU_GENERIC_TIMERS2_DATA_GET(x) \ + (((x)&MAC_PCU_GENERIC_TIMERS2_DATA_MASK) >> MAC_PCU_GENERIC_TIMERS2_DATA_LSB) +#define MAC_PCU_GENERIC_TIMERS2_DATA_SET(x) \ + (((x) << MAC_PCU_GENERIC_TIMERS2_DATA_LSB) & MAC_PCU_GENERIC_TIMERS2_DATA_MASK) + +#define MAC_PCU_GENERIC_TIMERS_MODE2_ADDRESS 0x00000200 +#define MAC_PCU_GENERIC_TIMERS_MODE2_OFFSET 0x00000200 +#define MAC_PCU_GENERIC_TIMERS_MODE2_ENABLE_MSB 15 +#define MAC_PCU_GENERIC_TIMERS_MODE2_ENABLE_LSB 0 +#define MAC_PCU_GENERIC_TIMERS_MODE2_ENABLE_MASK 0x0000ffff +#define MAC_PCU_GENERIC_TIMERS_MODE2_ENABLE_GET(x) \ + (((x)&MAC_PCU_GENERIC_TIMERS_MODE2_ENABLE_MASK) >> MAC_PCU_GENERIC_TIMERS_MODE2_ENABLE_LSB) +#define MAC_PCU_GENERIC_TIMERS_MODE2_ENABLE_SET(x) \ + (((x) << MAC_PCU_GENERIC_TIMERS_MODE2_ENABLE_LSB) & MAC_PCU_GENERIC_TIMERS_MODE2_ENABLE_MASK) + +#define MAC_PCU_SLP1_ADDRESS 0x00000204 +#define MAC_PCU_SLP1_OFFSET 0x00000204 +#define MAC_PCU_SLP1_ASSUME_DTIM_MSB 19 +#define MAC_PCU_SLP1_ASSUME_DTIM_LSB 19 +#define MAC_PCU_SLP1_ASSUME_DTIM_MASK 0x00080000 +#define MAC_PCU_SLP1_ASSUME_DTIM_GET(x) (((x)&MAC_PCU_SLP1_ASSUME_DTIM_MASK) >> MAC_PCU_SLP1_ASSUME_DTIM_LSB) +#define MAC_PCU_SLP1_ASSUME_DTIM_SET(x) (((x) << MAC_PCU_SLP1_ASSUME_DTIM_LSB) & MAC_PCU_SLP1_ASSUME_DTIM_MASK) +#define MAC_PCU_SLP1_CAB_TIMEOUT_MSB 15 +#define MAC_PCU_SLP1_CAB_TIMEOUT_LSB 0 +#define MAC_PCU_SLP1_CAB_TIMEOUT_MASK 0x0000ffff +#define MAC_PCU_SLP1_CAB_TIMEOUT_GET(x) (((x)&MAC_PCU_SLP1_CAB_TIMEOUT_MASK) >> MAC_PCU_SLP1_CAB_TIMEOUT_LSB) +#define MAC_PCU_SLP1_CAB_TIMEOUT_SET(x) (((x) << MAC_PCU_SLP1_CAB_TIMEOUT_LSB) & MAC_PCU_SLP1_CAB_TIMEOUT_MASK) + +#define MAC_PCU_SLP2_ADDRESS 0x00000208 +#define MAC_PCU_SLP2_OFFSET 0x00000208 +#define MAC_PCU_SLP2_BEACON_TIMEOUT_MSB 15 +#define MAC_PCU_SLP2_BEACON_TIMEOUT_LSB 0 +#define MAC_PCU_SLP2_BEACON_TIMEOUT_MASK 0x0000ffff +#define MAC_PCU_SLP2_BEACON_TIMEOUT_GET(x) (((x)&MAC_PCU_SLP2_BEACON_TIMEOUT_MASK) >> MAC_PCU_SLP2_BEACON_TIMEOUT_LSB) +#define MAC_PCU_SLP2_BEACON_TIMEOUT_SET(x) (((x) << MAC_PCU_SLP2_BEACON_TIMEOUT_LSB) & MAC_PCU_SLP2_BEACON_TIMEOUT_MASK) + +#define MAC_PCU_RESET_TSF_ADDRESS 0x0000020c +#define MAC_PCU_RESET_TSF_OFFSET 0x0000020c +#define MAC_PCU_RESET_TSF_ONE_SHOT2_MSB 25 +#define MAC_PCU_RESET_TSF_ONE_SHOT2_LSB 25 +#define MAC_PCU_RESET_TSF_ONE_SHOT2_MASK 0x02000000 +#define MAC_PCU_RESET_TSF_ONE_SHOT2_GET(x) (((x)&MAC_PCU_RESET_TSF_ONE_SHOT2_MASK) >> MAC_PCU_RESET_TSF_ONE_SHOT2_LSB) +#define MAC_PCU_RESET_TSF_ONE_SHOT2_SET(x) (((x) << MAC_PCU_RESET_TSF_ONE_SHOT2_LSB) & MAC_PCU_RESET_TSF_ONE_SHOT2_MASK) +#define MAC_PCU_RESET_TSF_ONE_SHOT_MSB 24 +#define MAC_PCU_RESET_TSF_ONE_SHOT_LSB 24 +#define MAC_PCU_RESET_TSF_ONE_SHOT_MASK 0x01000000 +#define MAC_PCU_RESET_TSF_ONE_SHOT_GET(x) (((x)&MAC_PCU_RESET_TSF_ONE_SHOT_MASK) >> MAC_PCU_RESET_TSF_ONE_SHOT_LSB) +#define MAC_PCU_RESET_TSF_ONE_SHOT_SET(x) (((x) << MAC_PCU_RESET_TSF_ONE_SHOT_LSB) & MAC_PCU_RESET_TSF_ONE_SHOT_MASK) + +#define MAC_PCU_TSF_ADD_PLL_ADDRESS 0x00000210 +#define MAC_PCU_TSF_ADD_PLL_OFFSET 0x00000210 +#define MAC_PCU_TSF_ADD_PLL_VALUE_MSB 7 +#define MAC_PCU_TSF_ADD_PLL_VALUE_LSB 0 +#define MAC_PCU_TSF_ADD_PLL_VALUE_MASK 0x000000ff +#define MAC_PCU_TSF_ADD_PLL_VALUE_GET(x) (((x)&MAC_PCU_TSF_ADD_PLL_VALUE_MASK) >> MAC_PCU_TSF_ADD_PLL_VALUE_LSB) +#define MAC_PCU_TSF_ADD_PLL_VALUE_SET(x) (((x) << MAC_PCU_TSF_ADD_PLL_VALUE_LSB) & MAC_PCU_TSF_ADD_PLL_VALUE_MASK) + +#define SLEEP_RETENTION_ADDRESS 0x00000214 +#define SLEEP_RETENTION_OFFSET 0x00000214 +#define SLEEP_RETENTION_TIME_MSB 9 +#define SLEEP_RETENTION_TIME_LSB 2 +#define SLEEP_RETENTION_TIME_MASK 0x000003fc +#define SLEEP_RETENTION_TIME_GET(x) (((x)&SLEEP_RETENTION_TIME_MASK) >> SLEEP_RETENTION_TIME_LSB) +#define SLEEP_RETENTION_TIME_SET(x) (((x) << SLEEP_RETENTION_TIME_LSB) & SLEEP_RETENTION_TIME_MASK) +#define SLEEP_RETENTION_MODE_MSB 1 +#define SLEEP_RETENTION_MODE_LSB 1 +#define SLEEP_RETENTION_MODE_MASK 0x00000002 +#define SLEEP_RETENTION_MODE_GET(x) (((x)&SLEEP_RETENTION_MODE_MASK) >> SLEEP_RETENTION_MODE_LSB) +#define SLEEP_RETENTION_MODE_SET(x) (((x) << SLEEP_RETENTION_MODE_LSB) & SLEEP_RETENTION_MODE_MASK) +#define SLEEP_RETENTION_ENABLE_MSB 0 +#define SLEEP_RETENTION_ENABLE_LSB 0 +#define SLEEP_RETENTION_ENABLE_MASK 0x00000001 +#define SLEEP_RETENTION_ENABLE_GET(x) (((x)&SLEEP_RETENTION_ENABLE_MASK) >> SLEEP_RETENTION_ENABLE_LSB) +#define SLEEP_RETENTION_ENABLE_SET(x) (((x) << SLEEP_RETENTION_ENABLE_LSB) & SLEEP_RETENTION_ENABLE_MASK) + +#define BTCOEXCTRL_ADDRESS 0x00000218 +#define BTCOEXCTRL_OFFSET 0x00000218 +#define BTCOEXCTRL_WBTIMER_ENABLE_MSB 26 +#define BTCOEXCTRL_WBTIMER_ENABLE_LSB 26 +#define BTCOEXCTRL_WBTIMER_ENABLE_MASK 0x04000000 +#define BTCOEXCTRL_WBTIMER_ENABLE_GET(x) (((x)&BTCOEXCTRL_WBTIMER_ENABLE_MASK) >> BTCOEXCTRL_WBTIMER_ENABLE_LSB) +#define BTCOEXCTRL_WBTIMER_ENABLE_SET(x) (((x) << BTCOEXCTRL_WBTIMER_ENABLE_LSB) & BTCOEXCTRL_WBTIMER_ENABLE_MASK) +#define BTCOEXCTRL_WBSYNC_ON_BEACON_MSB 25 +#define BTCOEXCTRL_WBSYNC_ON_BEACON_LSB 25 +#define BTCOEXCTRL_WBSYNC_ON_BEACON_MASK 0x02000000 +#define BTCOEXCTRL_WBSYNC_ON_BEACON_GET(x) (((x)&BTCOEXCTRL_WBSYNC_ON_BEACON_MASK) >> BTCOEXCTRL_WBSYNC_ON_BEACON_LSB) +#define BTCOEXCTRL_WBSYNC_ON_BEACON_SET(x) (((x) << BTCOEXCTRL_WBSYNC_ON_BEACON_LSB) & BTCOEXCTRL_WBSYNC_ON_BEACON_MASK) +#define BTCOEXCTRL_PTA_MODE_MSB 24 +#define BTCOEXCTRL_PTA_MODE_LSB 23 +#define BTCOEXCTRL_PTA_MODE_MASK 0x01800000 +#define BTCOEXCTRL_PTA_MODE_GET(x) (((x)&BTCOEXCTRL_PTA_MODE_MASK) >> BTCOEXCTRL_PTA_MODE_LSB) +#define BTCOEXCTRL_PTA_MODE_SET(x) (((x) << BTCOEXCTRL_PTA_MODE_LSB) & BTCOEXCTRL_PTA_MODE_MASK) +#define BTCOEXCTRL_FREQ_TIME_MSB 22 +#define BTCOEXCTRL_FREQ_TIME_LSB 18 +#define BTCOEXCTRL_FREQ_TIME_MASK 0x007c0000 +#define BTCOEXCTRL_FREQ_TIME_GET(x) (((x)&BTCOEXCTRL_FREQ_TIME_MASK) >> BTCOEXCTRL_FREQ_TIME_LSB) +#define BTCOEXCTRL_FREQ_TIME_SET(x) (((x) << BTCOEXCTRL_FREQ_TIME_LSB) & BTCOEXCTRL_FREQ_TIME_MASK) +#define BTCOEXCTRL_PRIORITY_TIME_MSB 17 +#define BTCOEXCTRL_PRIORITY_TIME_LSB 12 +#define BTCOEXCTRL_PRIORITY_TIME_MASK 0x0003f000 +#define BTCOEXCTRL_PRIORITY_TIME_GET(x) (((x)&BTCOEXCTRL_PRIORITY_TIME_MASK) >> BTCOEXCTRL_PRIORITY_TIME_LSB) +#define BTCOEXCTRL_PRIORITY_TIME_SET(x) (((x) << BTCOEXCTRL_PRIORITY_TIME_LSB) & BTCOEXCTRL_PRIORITY_TIME_MASK) +#define BTCOEXCTRL_SYNC_DET_EN_MSB 11 +#define BTCOEXCTRL_SYNC_DET_EN_LSB 11 +#define BTCOEXCTRL_SYNC_DET_EN_MASK 0x00000800 +#define BTCOEXCTRL_SYNC_DET_EN_GET(x) (((x)&BTCOEXCTRL_SYNC_DET_EN_MASK) >> BTCOEXCTRL_SYNC_DET_EN_LSB) +#define BTCOEXCTRL_SYNC_DET_EN_SET(x) (((x) << BTCOEXCTRL_SYNC_DET_EN_LSB) & BTCOEXCTRL_SYNC_DET_EN_MASK) +#define BTCOEXCTRL_IDLE_CNT_EN_MSB 10 +#define BTCOEXCTRL_IDLE_CNT_EN_LSB 10 +#define BTCOEXCTRL_IDLE_CNT_EN_MASK 0x00000400 +#define BTCOEXCTRL_IDLE_CNT_EN_GET(x) (((x)&BTCOEXCTRL_IDLE_CNT_EN_MASK) >> BTCOEXCTRL_IDLE_CNT_EN_LSB) +#define BTCOEXCTRL_IDLE_CNT_EN_SET(x) (((x) << BTCOEXCTRL_IDLE_CNT_EN_LSB) & BTCOEXCTRL_IDLE_CNT_EN_MASK) +#define BTCOEXCTRL_FRAME_CNT_EN_MSB 9 +#define BTCOEXCTRL_FRAME_CNT_EN_LSB 9 +#define BTCOEXCTRL_FRAME_CNT_EN_MASK 0x00000200 +#define BTCOEXCTRL_FRAME_CNT_EN_GET(x) (((x)&BTCOEXCTRL_FRAME_CNT_EN_MASK) >> BTCOEXCTRL_FRAME_CNT_EN_LSB) +#define BTCOEXCTRL_FRAME_CNT_EN_SET(x) (((x) << BTCOEXCTRL_FRAME_CNT_EN_LSB) & BTCOEXCTRL_FRAME_CNT_EN_MASK) +#define BTCOEXCTRL_CLK_CNT_EN_MSB 8 +#define BTCOEXCTRL_CLK_CNT_EN_LSB 8 +#define BTCOEXCTRL_CLK_CNT_EN_MASK 0x00000100 +#define BTCOEXCTRL_CLK_CNT_EN_GET(x) (((x)&BTCOEXCTRL_CLK_CNT_EN_MASK) >> BTCOEXCTRL_CLK_CNT_EN_LSB) +#define BTCOEXCTRL_CLK_CNT_EN_SET(x) (((x) << BTCOEXCTRL_CLK_CNT_EN_LSB) & BTCOEXCTRL_CLK_CNT_EN_MASK) +#define BTCOEXCTRL_GAP_MSB 7 +#define BTCOEXCTRL_GAP_LSB 0 +#define BTCOEXCTRL_GAP_MASK 0x000000ff +#define BTCOEXCTRL_GAP_GET(x) (((x)&BTCOEXCTRL_GAP_MASK) >> BTCOEXCTRL_GAP_LSB) +#define BTCOEXCTRL_GAP_SET(x) (((x) << BTCOEXCTRL_GAP_LSB) & BTCOEXCTRL_GAP_MASK) + +#define WBSYNC_PRIORITY1_ADDRESS 0x0000021c +#define WBSYNC_PRIORITY1_OFFSET 0x0000021c +#define WBSYNC_PRIORITY1_BITMAP_MSB 31 +#define WBSYNC_PRIORITY1_BITMAP_LSB 0 +#define WBSYNC_PRIORITY1_BITMAP_MASK 0xffffffff +#define WBSYNC_PRIORITY1_BITMAP_GET(x) (((x)&WBSYNC_PRIORITY1_BITMAP_MASK) >> WBSYNC_PRIORITY1_BITMAP_LSB) +#define WBSYNC_PRIORITY1_BITMAP_SET(x) (((x) << WBSYNC_PRIORITY1_BITMAP_LSB) & WBSYNC_PRIORITY1_BITMAP_MASK) + +#define WBSYNC_PRIORITY2_ADDRESS 0x00000220 +#define WBSYNC_PRIORITY2_OFFSET 0x00000220 +#define WBSYNC_PRIORITY2_BITMAP_MSB 31 +#define WBSYNC_PRIORITY2_BITMAP_LSB 0 +#define WBSYNC_PRIORITY2_BITMAP_MASK 0xffffffff +#define WBSYNC_PRIORITY2_BITMAP_GET(x) (((x)&WBSYNC_PRIORITY2_BITMAP_MASK) >> WBSYNC_PRIORITY2_BITMAP_LSB) +#define WBSYNC_PRIORITY2_BITMAP_SET(x) (((x) << WBSYNC_PRIORITY2_BITMAP_LSB) & WBSYNC_PRIORITY2_BITMAP_MASK) + +#define WBSYNC_PRIORITY3_ADDRESS 0x00000224 +#define WBSYNC_PRIORITY3_OFFSET 0x00000224 +#define WBSYNC_PRIORITY3_BITMAP_MSB 31 +#define WBSYNC_PRIORITY3_BITMAP_LSB 0 +#define WBSYNC_PRIORITY3_BITMAP_MASK 0xffffffff +#define WBSYNC_PRIORITY3_BITMAP_GET(x) (((x)&WBSYNC_PRIORITY3_BITMAP_MASK) >> WBSYNC_PRIORITY3_BITMAP_LSB) +#define WBSYNC_PRIORITY3_BITMAP_SET(x) (((x) << WBSYNC_PRIORITY3_BITMAP_LSB) & WBSYNC_PRIORITY3_BITMAP_MASK) + +#define BTCOEX0_ADDRESS 0x00000228 +#define BTCOEX0_OFFSET 0x00000228 +#define BTCOEX0_SYNC_DUR_MSB 7 +#define BTCOEX0_SYNC_DUR_LSB 0 +#define BTCOEX0_SYNC_DUR_MASK 0x000000ff +#define BTCOEX0_SYNC_DUR_GET(x) (((x)&BTCOEX0_SYNC_DUR_MASK) >> BTCOEX0_SYNC_DUR_LSB) +#define BTCOEX0_SYNC_DUR_SET(x) (((x) << BTCOEX0_SYNC_DUR_LSB) & BTCOEX0_SYNC_DUR_MASK) + +#define BTCOEX1_ADDRESS 0x0000022c +#define BTCOEX1_OFFSET 0x0000022c +#define BTCOEX1_CLK_THRES_MSB 20 +#define BTCOEX1_CLK_THRES_LSB 0 +#define BTCOEX1_CLK_THRES_MASK 0x001fffff +#define BTCOEX1_CLK_THRES_GET(x) (((x)&BTCOEX1_CLK_THRES_MASK) >> BTCOEX1_CLK_THRES_LSB) +#define BTCOEX1_CLK_THRES_SET(x) (((x) << BTCOEX1_CLK_THRES_LSB) & BTCOEX1_CLK_THRES_MASK) + +#define BTCOEX2_ADDRESS 0x00000230 +#define BTCOEX2_OFFSET 0x00000230 +#define BTCOEX2_FRAME_THRES_MSB 7 +#define BTCOEX2_FRAME_THRES_LSB 0 +#define BTCOEX2_FRAME_THRES_MASK 0x000000ff +#define BTCOEX2_FRAME_THRES_GET(x) (((x)&BTCOEX2_FRAME_THRES_MASK) >> BTCOEX2_FRAME_THRES_LSB) +#define BTCOEX2_FRAME_THRES_SET(x) (((x) << BTCOEX2_FRAME_THRES_LSB) & BTCOEX2_FRAME_THRES_MASK) + +#define BTCOEX3_ADDRESS 0x00000234 +#define BTCOEX3_OFFSET 0x00000234 +#define BTCOEX3_CLK_CNT_MSB 20 +#define BTCOEX3_CLK_CNT_LSB 0 +#define BTCOEX3_CLK_CNT_MASK 0x001fffff +#define BTCOEX3_CLK_CNT_GET(x) (((x)&BTCOEX3_CLK_CNT_MASK) >> BTCOEX3_CLK_CNT_LSB) +#define BTCOEX3_CLK_CNT_SET(x) (((x) << BTCOEX3_CLK_CNT_LSB) & BTCOEX3_CLK_CNT_MASK) + +#define BTCOEX4_ADDRESS 0x00000238 +#define BTCOEX4_OFFSET 0x00000238 +#define BTCOEX4_FRAME_CNT_MSB 7 +#define BTCOEX4_FRAME_CNT_LSB 0 +#define BTCOEX4_FRAME_CNT_MASK 0x000000ff +#define BTCOEX4_FRAME_CNT_GET(x) (((x)&BTCOEX4_FRAME_CNT_MASK) >> BTCOEX4_FRAME_CNT_LSB) +#define BTCOEX4_FRAME_CNT_SET(x) (((x) << BTCOEX4_FRAME_CNT_LSB) & BTCOEX4_FRAME_CNT_MASK) + +#define BTCOEX5_ADDRESS 0x0000023c +#define BTCOEX5_OFFSET 0x0000023c +#define BTCOEX5_IDLE_CNT_MSB 15 +#define BTCOEX5_IDLE_CNT_LSB 0 +#define BTCOEX5_IDLE_CNT_MASK 0x0000ffff +#define BTCOEX5_IDLE_CNT_GET(x) (((x)&BTCOEX5_IDLE_CNT_MASK) >> BTCOEX5_IDLE_CNT_LSB) +#define BTCOEX5_IDLE_CNT_SET(x) (((x) << BTCOEX5_IDLE_CNT_LSB) & BTCOEX5_IDLE_CNT_MASK) + +#define BTCOEX6_ADDRESS 0x00000240 +#define BTCOEX6_OFFSET 0x00000240 +#define BTCOEX6_IDLE_RESET_LVL_BITMAP_MSB 31 +#define BTCOEX6_IDLE_RESET_LVL_BITMAP_LSB 0 +#define BTCOEX6_IDLE_RESET_LVL_BITMAP_MASK 0xffffffff +#define BTCOEX6_IDLE_RESET_LVL_BITMAP_GET(x) \ + (((x)&BTCOEX6_IDLE_RESET_LVL_BITMAP_MASK) >> BTCOEX6_IDLE_RESET_LVL_BITMAP_LSB) +#define BTCOEX6_IDLE_RESET_LVL_BITMAP_SET(x) \ + (((x) << BTCOEX6_IDLE_RESET_LVL_BITMAP_LSB) & BTCOEX6_IDLE_RESET_LVL_BITMAP_MASK) + +#define LOCK_ADDRESS 0x00000244 +#define LOCK_OFFSET 0x00000244 +#define LOCK_TLOCK_SLAVE_MSB 31 +#define LOCK_TLOCK_SLAVE_LSB 24 +#define LOCK_TLOCK_SLAVE_MASK 0xff000000 +#define LOCK_TLOCK_SLAVE_GET(x) (((x)&LOCK_TLOCK_SLAVE_MASK) >> LOCK_TLOCK_SLAVE_LSB) +#define LOCK_TLOCK_SLAVE_SET(x) (((x) << LOCK_TLOCK_SLAVE_LSB) & LOCK_TLOCK_SLAVE_MASK) +#define LOCK_TUNLOCK_SLAVE_MSB 23 +#define LOCK_TUNLOCK_SLAVE_LSB 16 +#define LOCK_TUNLOCK_SLAVE_MASK 0x00ff0000 +#define LOCK_TUNLOCK_SLAVE_GET(x) (((x)&LOCK_TUNLOCK_SLAVE_MASK) >> LOCK_TUNLOCK_SLAVE_LSB) +#define LOCK_TUNLOCK_SLAVE_SET(x) (((x) << LOCK_TUNLOCK_SLAVE_LSB) & LOCK_TUNLOCK_SLAVE_MASK) +#define LOCK_TLOCK_MASTER_MSB 15 +#define LOCK_TLOCK_MASTER_LSB 8 +#define LOCK_TLOCK_MASTER_MASK 0x0000ff00 +#define LOCK_TLOCK_MASTER_GET(x) (((x)&LOCK_TLOCK_MASTER_MASK) >> LOCK_TLOCK_MASTER_LSB) +#define LOCK_TLOCK_MASTER_SET(x) (((x) << LOCK_TLOCK_MASTER_LSB) & LOCK_TLOCK_MASTER_MASK) +#define LOCK_TUNLOCK_MASTER_MSB 7 +#define LOCK_TUNLOCK_MASTER_LSB 0 +#define LOCK_TUNLOCK_MASTER_MASK 0x000000ff +#define LOCK_TUNLOCK_MASTER_GET(x) (((x)&LOCK_TUNLOCK_MASTER_MASK) >> LOCK_TUNLOCK_MASTER_LSB) +#define LOCK_TUNLOCK_MASTER_SET(x) (((x) << LOCK_TUNLOCK_MASTER_LSB) & LOCK_TUNLOCK_MASTER_MASK) + +#define NOLOCK_PRIORITY_ADDRESS 0x00000248 +#define NOLOCK_PRIORITY_OFFSET 0x00000248 +#define NOLOCK_PRIORITY_BITMAP_MSB 31 +#define NOLOCK_PRIORITY_BITMAP_LSB 0 +#define NOLOCK_PRIORITY_BITMAP_MASK 0xffffffff +#define NOLOCK_PRIORITY_BITMAP_GET(x) (((x)&NOLOCK_PRIORITY_BITMAP_MASK) >> NOLOCK_PRIORITY_BITMAP_LSB) +#define NOLOCK_PRIORITY_BITMAP_SET(x) (((x) << NOLOCK_PRIORITY_BITMAP_LSB) & NOLOCK_PRIORITY_BITMAP_MASK) + +#define WBSYNC_ADDRESS 0x0000024c +#define WBSYNC_OFFSET 0x0000024c +#define WBSYNC_BTCLOCK_MSB 31 +#define WBSYNC_BTCLOCK_LSB 0 +#define WBSYNC_BTCLOCK_MASK 0xffffffff +#define WBSYNC_BTCLOCK_GET(x) (((x)&WBSYNC_BTCLOCK_MASK) >> WBSYNC_BTCLOCK_LSB) +#define WBSYNC_BTCLOCK_SET(x) (((x) << WBSYNC_BTCLOCK_LSB) & WBSYNC_BTCLOCK_MASK) + +#define WBSYNC1_ADDRESS 0x00000250 +#define WBSYNC1_OFFSET 0x00000250 +#define WBSYNC1_BTCLOCK_MSB 31 +#define WBSYNC1_BTCLOCK_LSB 0 +#define WBSYNC1_BTCLOCK_MASK 0xffffffff +#define WBSYNC1_BTCLOCK_GET(x) (((x)&WBSYNC1_BTCLOCK_MASK) >> WBSYNC1_BTCLOCK_LSB) +#define WBSYNC1_BTCLOCK_SET(x) (((x) << WBSYNC1_BTCLOCK_LSB) & WBSYNC1_BTCLOCK_MASK) + +#define WBSYNC2_ADDRESS 0x00000254 +#define WBSYNC2_OFFSET 0x00000254 +#define WBSYNC2_BTCLOCK_MSB 31 +#define WBSYNC2_BTCLOCK_LSB 0 +#define WBSYNC2_BTCLOCK_MASK 0xffffffff +#define WBSYNC2_BTCLOCK_GET(x) (((x)&WBSYNC2_BTCLOCK_MASK) >> WBSYNC2_BTCLOCK_LSB) +#define WBSYNC2_BTCLOCK_SET(x) (((x) << WBSYNC2_BTCLOCK_LSB) & WBSYNC2_BTCLOCK_MASK) + +#define WBSYNC3_ADDRESS 0x00000258 +#define WBSYNC3_OFFSET 0x00000258 +#define WBSYNC3_BTCLOCK_MSB 31 +#define WBSYNC3_BTCLOCK_LSB 0 +#define WBSYNC3_BTCLOCK_MASK 0xffffffff +#define WBSYNC3_BTCLOCK_GET(x) (((x)&WBSYNC3_BTCLOCK_MASK) >> WBSYNC3_BTCLOCK_LSB) +#define WBSYNC3_BTCLOCK_SET(x) (((x) << WBSYNC3_BTCLOCK_LSB) & WBSYNC3_BTCLOCK_MASK) + +#define WB_TIMER_TARGET_ADDRESS 0x0000025c +#define WB_TIMER_TARGET_OFFSET 0x0000025c +#define WB_TIMER_TARGET_VALUE_MSB 31 +#define WB_TIMER_TARGET_VALUE_LSB 0 +#define WB_TIMER_TARGET_VALUE_MASK 0xffffffff +#define WB_TIMER_TARGET_VALUE_GET(x) (((x)&WB_TIMER_TARGET_VALUE_MASK) >> WB_TIMER_TARGET_VALUE_LSB) +#define WB_TIMER_TARGET_VALUE_SET(x) (((x) << WB_TIMER_TARGET_VALUE_LSB) & WB_TIMER_TARGET_VALUE_MASK) + +#define WB_TIMER_SLOP_ADDRESS 0x00000260 +#define WB_TIMER_SLOP_OFFSET 0x00000260 +#define WB_TIMER_SLOP_VALUE_MSB 9 +#define WB_TIMER_SLOP_VALUE_LSB 0 +#define WB_TIMER_SLOP_VALUE_MASK 0x000003ff +#define WB_TIMER_SLOP_VALUE_GET(x) (((x)&WB_TIMER_SLOP_VALUE_MASK) >> WB_TIMER_SLOP_VALUE_LSB) +#define WB_TIMER_SLOP_VALUE_SET(x) (((x) << WB_TIMER_SLOP_VALUE_LSB) & WB_TIMER_SLOP_VALUE_MASK) + +#define BTCOEX_INT_EN_ADDRESS 0x00000264 +#define BTCOEX_INT_EN_OFFSET 0x00000264 +#define BTCOEX_INT_EN_I2C_RECV_OVERFLOW_MSB 11 +#define BTCOEX_INT_EN_I2C_RECV_OVERFLOW_LSB 11 +#define BTCOEX_INT_EN_I2C_RECV_OVERFLOW_MASK 0x00000800 +#define BTCOEX_INT_EN_I2C_RECV_OVERFLOW_GET(x) \ + (((x)&BTCOEX_INT_EN_I2C_RECV_OVERFLOW_MASK) >> BTCOEX_INT_EN_I2C_RECV_OVERFLOW_LSB) +#define BTCOEX_INT_EN_I2C_RECV_OVERFLOW_SET(x) \ + (((x) << BTCOEX_INT_EN_I2C_RECV_OVERFLOW_LSB) & BTCOEX_INT_EN_I2C_RECV_OVERFLOW_MASK) +#define BTCOEX_INT_EN_I2C_TX_FAILED_MSB 10 +#define BTCOEX_INT_EN_I2C_TX_FAILED_LSB 10 +#define BTCOEX_INT_EN_I2C_TX_FAILED_MASK 0x00000400 +#define BTCOEX_INT_EN_I2C_TX_FAILED_GET(x) (((x)&BTCOEX_INT_EN_I2C_TX_FAILED_MASK) >> BTCOEX_INT_EN_I2C_TX_FAILED_LSB) +#define BTCOEX_INT_EN_I2C_TX_FAILED_SET(x) (((x) << BTCOEX_INT_EN_I2C_TX_FAILED_LSB) & BTCOEX_INT_EN_I2C_TX_FAILED_MASK) +#define BTCOEX_INT_EN_I2C_MESG_SENT_MSB 9 +#define BTCOEX_INT_EN_I2C_MESG_SENT_LSB 9 +#define BTCOEX_INT_EN_I2C_MESG_SENT_MASK 0x00000200 +#define BTCOEX_INT_EN_I2C_MESG_SENT_GET(x) (((x)&BTCOEX_INT_EN_I2C_MESG_SENT_MASK) >> BTCOEX_INT_EN_I2C_MESG_SENT_LSB) +#define BTCOEX_INT_EN_I2C_MESG_SENT_SET(x) (((x) << BTCOEX_INT_EN_I2C_MESG_SENT_LSB) & BTCOEX_INT_EN_I2C_MESG_SENT_MASK) +#define BTCOEX_INT_EN_ST_MESG_RECV_MSB 8 +#define BTCOEX_INT_EN_ST_MESG_RECV_LSB 8 +#define BTCOEX_INT_EN_ST_MESG_RECV_MASK 0x00000100 +#define BTCOEX_INT_EN_ST_MESG_RECV_GET(x) (((x)&BTCOEX_INT_EN_ST_MESG_RECV_MASK) >> BTCOEX_INT_EN_ST_MESG_RECV_LSB) +#define BTCOEX_INT_EN_ST_MESG_RECV_SET(x) (((x) << BTCOEX_INT_EN_ST_MESG_RECV_LSB) & BTCOEX_INT_EN_ST_MESG_RECV_MASK) +#define BTCOEX_INT_EN_WB_TIMER_MSB 7 +#define BTCOEX_INT_EN_WB_TIMER_LSB 7 +#define BTCOEX_INT_EN_WB_TIMER_MASK 0x00000080 +#define BTCOEX_INT_EN_WB_TIMER_GET(x) (((x)&BTCOEX_INT_EN_WB_TIMER_MASK) >> BTCOEX_INT_EN_WB_TIMER_LSB) +#define BTCOEX_INT_EN_WB_TIMER_SET(x) (((x) << BTCOEX_INT_EN_WB_TIMER_LSB) & BTCOEX_INT_EN_WB_TIMER_MASK) +#define BTCOEX_INT_EN_NOSYNC_MSB 4 +#define BTCOEX_INT_EN_NOSYNC_LSB 4 +#define BTCOEX_INT_EN_NOSYNC_MASK 0x00000010 +#define BTCOEX_INT_EN_NOSYNC_GET(x) (((x)&BTCOEX_INT_EN_NOSYNC_MASK) >> BTCOEX_INT_EN_NOSYNC_LSB) +#define BTCOEX_INT_EN_NOSYNC_SET(x) (((x) << BTCOEX_INT_EN_NOSYNC_LSB) & BTCOEX_INT_EN_NOSYNC_MASK) +#define BTCOEX_INT_EN_SYNC_MSB 3 +#define BTCOEX_INT_EN_SYNC_LSB 3 +#define BTCOEX_INT_EN_SYNC_MASK 0x00000008 +#define BTCOEX_INT_EN_SYNC_GET(x) (((x)&BTCOEX_INT_EN_SYNC_MASK) >> BTCOEX_INT_EN_SYNC_LSB) +#define BTCOEX_INT_EN_SYNC_SET(x) (((x) << BTCOEX_INT_EN_SYNC_LSB) & BTCOEX_INT_EN_SYNC_MASK) +#define BTCOEX_INT_EN_END_MSB 2 +#define BTCOEX_INT_EN_END_LSB 2 +#define BTCOEX_INT_EN_END_MASK 0x00000004 +#define BTCOEX_INT_EN_END_GET(x) (((x)&BTCOEX_INT_EN_END_MASK) >> BTCOEX_INT_EN_END_LSB) +#define BTCOEX_INT_EN_END_SET(x) (((x) << BTCOEX_INT_EN_END_LSB) & BTCOEX_INT_EN_END_MASK) +#define BTCOEX_INT_EN_FRAME_CNT_MSB 1 +#define BTCOEX_INT_EN_FRAME_CNT_LSB 1 +#define BTCOEX_INT_EN_FRAME_CNT_MASK 0x00000002 +#define BTCOEX_INT_EN_FRAME_CNT_GET(x) (((x)&BTCOEX_INT_EN_FRAME_CNT_MASK) >> BTCOEX_INT_EN_FRAME_CNT_LSB) +#define BTCOEX_INT_EN_FRAME_CNT_SET(x) (((x) << BTCOEX_INT_EN_FRAME_CNT_LSB) & BTCOEX_INT_EN_FRAME_CNT_MASK) +#define BTCOEX_INT_EN_CLK_CNT_MSB 0 +#define BTCOEX_INT_EN_CLK_CNT_LSB 0 +#define BTCOEX_INT_EN_CLK_CNT_MASK 0x00000001 +#define BTCOEX_INT_EN_CLK_CNT_GET(x) (((x)&BTCOEX_INT_EN_CLK_CNT_MASK) >> BTCOEX_INT_EN_CLK_CNT_LSB) +#define BTCOEX_INT_EN_CLK_CNT_SET(x) (((x) << BTCOEX_INT_EN_CLK_CNT_LSB) & BTCOEX_INT_EN_CLK_CNT_MASK) + +#define BTCOEX_INT_STAT_ADDRESS 0x00000268 +#define BTCOEX_INT_STAT_OFFSET 0x00000268 +#define BTCOEX_INT_STAT_I2C_RECV_OVERFLOW_MSB 11 +#define BTCOEX_INT_STAT_I2C_RECV_OVERFLOW_LSB 11 +#define BTCOEX_INT_STAT_I2C_RECV_OVERFLOW_MASK 0x00000800 +#define BTCOEX_INT_STAT_I2C_RECV_OVERFLOW_GET(x) \ + (((x)&BTCOEX_INT_STAT_I2C_RECV_OVERFLOW_MASK) >> BTCOEX_INT_STAT_I2C_RECV_OVERFLOW_LSB) +#define BTCOEX_INT_STAT_I2C_RECV_OVERFLOW_SET(x) \ + (((x) << BTCOEX_INT_STAT_I2C_RECV_OVERFLOW_LSB) & BTCOEX_INT_STAT_I2C_RECV_OVERFLOW_MASK) +#define BTCOEX_INT_STAT_I2C_TX_FAILED_MSB 10 +#define BTCOEX_INT_STAT_I2C_TX_FAILED_LSB 10 +#define BTCOEX_INT_STAT_I2C_TX_FAILED_MASK 0x00000400 +#define BTCOEX_INT_STAT_I2C_TX_FAILED_GET(x) \ + (((x)&BTCOEX_INT_STAT_I2C_TX_FAILED_MASK) >> BTCOEX_INT_STAT_I2C_TX_FAILED_LSB) +#define BTCOEX_INT_STAT_I2C_TX_FAILED_SET(x) \ + (((x) << BTCOEX_INT_STAT_I2C_TX_FAILED_LSB) & BTCOEX_INT_STAT_I2C_TX_FAILED_MASK) +#define BTCOEX_INT_STAT_I2C_MESG_SENT_MSB 9 +#define BTCOEX_INT_STAT_I2C_MESG_SENT_LSB 9 +#define BTCOEX_INT_STAT_I2C_MESG_SENT_MASK 0x00000200 +#define BTCOEX_INT_STAT_I2C_MESG_SENT_GET(x) \ + (((x)&BTCOEX_INT_STAT_I2C_MESG_SENT_MASK) >> BTCOEX_INT_STAT_I2C_MESG_SENT_LSB) +#define BTCOEX_INT_STAT_I2C_MESG_SENT_SET(x) \ + (((x) << BTCOEX_INT_STAT_I2C_MESG_SENT_LSB) & BTCOEX_INT_STAT_I2C_MESG_SENT_MASK) +#define BTCOEX_INT_STAT_I2C_MESG_RECV_MSB 8 +#define BTCOEX_INT_STAT_I2C_MESG_RECV_LSB 8 +#define BTCOEX_INT_STAT_I2C_MESG_RECV_MASK 0x00000100 +#define BTCOEX_INT_STAT_I2C_MESG_RECV_GET(x) \ + (((x)&BTCOEX_INT_STAT_I2C_MESG_RECV_MASK) >> BTCOEX_INT_STAT_I2C_MESG_RECV_LSB) +#define BTCOEX_INT_STAT_I2C_MESG_RECV_SET(x) \ + (((x) << BTCOEX_INT_STAT_I2C_MESG_RECV_LSB) & BTCOEX_INT_STAT_I2C_MESG_RECV_MASK) +#define BTCOEX_INT_STAT_WB_TIMER_MSB 7 +#define BTCOEX_INT_STAT_WB_TIMER_LSB 7 +#define BTCOEX_INT_STAT_WB_TIMER_MASK 0x00000080 +#define BTCOEX_INT_STAT_WB_TIMER_GET(x) (((x)&BTCOEX_INT_STAT_WB_TIMER_MASK) >> BTCOEX_INT_STAT_WB_TIMER_LSB) +#define BTCOEX_INT_STAT_WB_TIMER_SET(x) (((x) << BTCOEX_INT_STAT_WB_TIMER_LSB) & BTCOEX_INT_STAT_WB_TIMER_MASK) +#define BTCOEX_INT_STAT_BTPRIORITY_STOMP_MSB 6 +#define BTCOEX_INT_STAT_BTPRIORITY_STOMP_LSB 6 +#define BTCOEX_INT_STAT_BTPRIORITY_STOMP_MASK 0x00000040 +#define BTCOEX_INT_STAT_BTPRIORITY_STOMP_GET(x) \ + (((x)&BTCOEX_INT_STAT_BTPRIORITY_STOMP_MASK) >> BTCOEX_INT_STAT_BTPRIORITY_STOMP_LSB) +#define BTCOEX_INT_STAT_BTPRIORITY_STOMP_SET(x) \ + (((x) << BTCOEX_INT_STAT_BTPRIORITY_STOMP_LSB) & BTCOEX_INT_STAT_BTPRIORITY_STOMP_MASK) +#define BTCOEX_INT_STAT_BTPRIORITY_MSB 5 +#define BTCOEX_INT_STAT_BTPRIORITY_LSB 5 +#define BTCOEX_INT_STAT_BTPRIORITY_MASK 0x00000020 +#define BTCOEX_INT_STAT_BTPRIORITY_GET(x) (((x)&BTCOEX_INT_STAT_BTPRIORITY_MASK) >> BTCOEX_INT_STAT_BTPRIORITY_LSB) +#define BTCOEX_INT_STAT_BTPRIORITY_SET(x) (((x) << BTCOEX_INT_STAT_BTPRIORITY_LSB) & BTCOEX_INT_STAT_BTPRIORITY_MASK) +#define BTCOEX_INT_STAT_NOSYNC_MSB 4 +#define BTCOEX_INT_STAT_NOSYNC_LSB 4 +#define BTCOEX_INT_STAT_NOSYNC_MASK 0x00000010 +#define BTCOEX_INT_STAT_NOSYNC_GET(x) (((x)&BTCOEX_INT_STAT_NOSYNC_MASK) >> BTCOEX_INT_STAT_NOSYNC_LSB) +#define BTCOEX_INT_STAT_NOSYNC_SET(x) (((x) << BTCOEX_INT_STAT_NOSYNC_LSB) & BTCOEX_INT_STAT_NOSYNC_MASK) +#define BTCOEX_INT_STAT_SYNC_MSB 3 +#define BTCOEX_INT_STAT_SYNC_LSB 3 +#define BTCOEX_INT_STAT_SYNC_MASK 0x00000008 +#define BTCOEX_INT_STAT_SYNC_GET(x) (((x)&BTCOEX_INT_STAT_SYNC_MASK) >> BTCOEX_INT_STAT_SYNC_LSB) +#define BTCOEX_INT_STAT_SYNC_SET(x) (((x) << BTCOEX_INT_STAT_SYNC_LSB) & BTCOEX_INT_STAT_SYNC_MASK) +#define BTCOEX_INT_STAT_END_MSB 2 +#define BTCOEX_INT_STAT_END_LSB 2 +#define BTCOEX_INT_STAT_END_MASK 0x00000004 +#define BTCOEX_INT_STAT_END_GET(x) (((x)&BTCOEX_INT_STAT_END_MASK) >> BTCOEX_INT_STAT_END_LSB) +#define BTCOEX_INT_STAT_END_SET(x) (((x) << BTCOEX_INT_STAT_END_LSB) & BTCOEX_INT_STAT_END_MASK) +#define BTCOEX_INT_STAT_FRAME_CNT_MSB 1 +#define BTCOEX_INT_STAT_FRAME_CNT_LSB 1 +#define BTCOEX_INT_STAT_FRAME_CNT_MASK 0x00000002 +#define BTCOEX_INT_STAT_FRAME_CNT_GET(x) (((x)&BTCOEX_INT_STAT_FRAME_CNT_MASK) >> BTCOEX_INT_STAT_FRAME_CNT_LSB) +#define BTCOEX_INT_STAT_FRAME_CNT_SET(x) (((x) << BTCOEX_INT_STAT_FRAME_CNT_LSB) & BTCOEX_INT_STAT_FRAME_CNT_MASK) +#define BTCOEX_INT_STAT_CLK_CNT_MSB 0 +#define BTCOEX_INT_STAT_CLK_CNT_LSB 0 +#define BTCOEX_INT_STAT_CLK_CNT_MASK 0x00000001 +#define BTCOEX_INT_STAT_CLK_CNT_GET(x) (((x)&BTCOEX_INT_STAT_CLK_CNT_MASK) >> BTCOEX_INT_STAT_CLK_CNT_LSB) +#define BTCOEX_INT_STAT_CLK_CNT_SET(x) (((x) << BTCOEX_INT_STAT_CLK_CNT_LSB) & BTCOEX_INT_STAT_CLK_CNT_MASK) + +#define BTPRIORITY_INT_EN_ADDRESS 0x0000026c +#define BTPRIORITY_INT_EN_OFFSET 0x0000026c +#define BTPRIORITY_INT_EN_BITMAP_MSB 31 +#define BTPRIORITY_INT_EN_BITMAP_LSB 0 +#define BTPRIORITY_INT_EN_BITMAP_MASK 0xffffffff +#define BTPRIORITY_INT_EN_BITMAP_GET(x) (((x)&BTPRIORITY_INT_EN_BITMAP_MASK) >> BTPRIORITY_INT_EN_BITMAP_LSB) +#define BTPRIORITY_INT_EN_BITMAP_SET(x) (((x) << BTPRIORITY_INT_EN_BITMAP_LSB) & BTPRIORITY_INT_EN_BITMAP_MASK) + +#define BTPRIORITY_INT_STAT_ADDRESS 0x00000270 +#define BTPRIORITY_INT_STAT_OFFSET 0x00000270 +#define BTPRIORITY_INT_STAT_BITMAP_MSB 31 +#define BTPRIORITY_INT_STAT_BITMAP_LSB 0 +#define BTPRIORITY_INT_STAT_BITMAP_MASK 0xffffffff +#define BTPRIORITY_INT_STAT_BITMAP_GET(x) (((x)&BTPRIORITY_INT_STAT_BITMAP_MASK) >> BTPRIORITY_INT_STAT_BITMAP_LSB) +#define BTPRIORITY_INT_STAT_BITMAP_SET(x) (((x) << BTPRIORITY_INT_STAT_BITMAP_LSB) & BTPRIORITY_INT_STAT_BITMAP_MASK) + +#define BTPRIORITY_STOMP_INT_EN_ADDRESS 0x00000274 +#define BTPRIORITY_STOMP_INT_EN_OFFSET 0x00000274 +#define BTPRIORITY_STOMP_INT_EN_BITMAP_MSB 31 +#define BTPRIORITY_STOMP_INT_EN_BITMAP_LSB 0 +#define BTPRIORITY_STOMP_INT_EN_BITMAP_MASK 0xffffffff +#define BTPRIORITY_STOMP_INT_EN_BITMAP_GET(x) \ + (((x)&BTPRIORITY_STOMP_INT_EN_BITMAP_MASK) >> BTPRIORITY_STOMP_INT_EN_BITMAP_LSB) +#define BTPRIORITY_STOMP_INT_EN_BITMAP_SET(x) \ + (((x) << BTPRIORITY_STOMP_INT_EN_BITMAP_LSB) & BTPRIORITY_STOMP_INT_EN_BITMAP_MASK) + +#define BTPRIORITY_STOMP_INT_STAT_ADDRESS 0x00000278 +#define BTPRIORITY_STOMP_INT_STAT_OFFSET 0x00000278 +#define BTPRIORITY_STOMP_INT_STAT_BITMAP_MSB 31 +#define BTPRIORITY_STOMP_INT_STAT_BITMAP_LSB 0 +#define BTPRIORITY_STOMP_INT_STAT_BITMAP_MASK 0xffffffff +#define BTPRIORITY_STOMP_INT_STAT_BITMAP_GET(x) \ + (((x)&BTPRIORITY_STOMP_INT_STAT_BITMAP_MASK) >> BTPRIORITY_STOMP_INT_STAT_BITMAP_LSB) +#define BTPRIORITY_STOMP_INT_STAT_BITMAP_SET(x) \ + (((x) << BTPRIORITY_STOMP_INT_STAT_BITMAP_LSB) & BTPRIORITY_STOMP_INT_STAT_BITMAP_MASK) + +#define MAC_PCU_BMISS_TIMEOUT_ADDRESS 0x0000027c +#define MAC_PCU_BMISS_TIMEOUT_OFFSET 0x0000027c +#define MAC_PCU_BMISS_TIMEOUT_ENABLE_MSB 24 +#define MAC_PCU_BMISS_TIMEOUT_ENABLE_LSB 24 +#define MAC_PCU_BMISS_TIMEOUT_ENABLE_MASK 0x01000000 +#define MAC_PCU_BMISS_TIMEOUT_ENABLE_GET(x) \ + (((x)&MAC_PCU_BMISS_TIMEOUT_ENABLE_MASK) >> MAC_PCU_BMISS_TIMEOUT_ENABLE_LSB) +#define MAC_PCU_BMISS_TIMEOUT_ENABLE_SET(x) \ + (((x) << MAC_PCU_BMISS_TIMEOUT_ENABLE_LSB) & MAC_PCU_BMISS_TIMEOUT_ENABLE_MASK) +#define MAC_PCU_BMISS_TIMEOUT_VALUE_MSB 23 +#define MAC_PCU_BMISS_TIMEOUT_VALUE_LSB 0 +#define MAC_PCU_BMISS_TIMEOUT_VALUE_MASK 0x00ffffff +#define MAC_PCU_BMISS_TIMEOUT_VALUE_GET(x) (((x)&MAC_PCU_BMISS_TIMEOUT_VALUE_MASK) >> MAC_PCU_BMISS_TIMEOUT_VALUE_LSB) +#define MAC_PCU_BMISS_TIMEOUT_VALUE_SET(x) (((x) << MAC_PCU_BMISS_TIMEOUT_VALUE_LSB) & MAC_PCU_BMISS_TIMEOUT_VALUE_MASK) + +#define MAC_PCU_CAB_AWAKE_ADDRESS 0x00000280 +#define MAC_PCU_CAB_AWAKE_OFFSET 0x00000280 +#define MAC_PCU_CAB_AWAKE_ENABLE_MSB 16 +#define MAC_PCU_CAB_AWAKE_ENABLE_LSB 16 +#define MAC_PCU_CAB_AWAKE_ENABLE_MASK 0x00010000 +#define MAC_PCU_CAB_AWAKE_ENABLE_GET(x) (((x)&MAC_PCU_CAB_AWAKE_ENABLE_MASK) >> MAC_PCU_CAB_AWAKE_ENABLE_LSB) +#define MAC_PCU_CAB_AWAKE_ENABLE_SET(x) (((x) << MAC_PCU_CAB_AWAKE_ENABLE_LSB) & MAC_PCU_CAB_AWAKE_ENABLE_MASK) +#define MAC_PCU_CAB_AWAKE_DURATION_MSB 15 +#define MAC_PCU_CAB_AWAKE_DURATION_LSB 0 +#define MAC_PCU_CAB_AWAKE_DURATION_MASK 0x0000ffff +#define MAC_PCU_CAB_AWAKE_DURATION_GET(x) (((x)&MAC_PCU_CAB_AWAKE_DURATION_MASK) >> MAC_PCU_CAB_AWAKE_DURATION_LSB) +#define MAC_PCU_CAB_AWAKE_DURATION_SET(x) (((x) << MAC_PCU_CAB_AWAKE_DURATION_LSB) & MAC_PCU_CAB_AWAKE_DURATION_MASK) + +#define LP_PERF_COUNTER_ADDRESS 0x00000284 +#define LP_PERF_COUNTER_OFFSET 0x00000284 +#define LP_PERF_COUNTER_EN_MSB 0 +#define LP_PERF_COUNTER_EN_LSB 0 +#define LP_PERF_COUNTER_EN_MASK 0x00000001 +#define LP_PERF_COUNTER_EN_GET(x) (((x)&LP_PERF_COUNTER_EN_MASK) >> LP_PERF_COUNTER_EN_LSB) +#define LP_PERF_COUNTER_EN_SET(x) (((x) << LP_PERF_COUNTER_EN_LSB) & LP_PERF_COUNTER_EN_MASK) + +#define LP_PERF_LIGHT_SLEEP_ADDRESS 0x00000288 +#define LP_PERF_LIGHT_SLEEP_OFFSET 0x00000288 +#define LP_PERF_LIGHT_SLEEP_CNT_MSB 31 +#define LP_PERF_LIGHT_SLEEP_CNT_LSB 0 +#define LP_PERF_LIGHT_SLEEP_CNT_MASK 0xffffffff +#define LP_PERF_LIGHT_SLEEP_CNT_GET(x) (((x)&LP_PERF_LIGHT_SLEEP_CNT_MASK) >> LP_PERF_LIGHT_SLEEP_CNT_LSB) +#define LP_PERF_LIGHT_SLEEP_CNT_SET(x) (((x) << LP_PERF_LIGHT_SLEEP_CNT_LSB) & LP_PERF_LIGHT_SLEEP_CNT_MASK) + +#define LP_PERF_DEEP_SLEEP_ADDRESS 0x0000028c +#define LP_PERF_DEEP_SLEEP_OFFSET 0x0000028c +#define LP_PERF_DEEP_SLEEP_CNT_MSB 31 +#define LP_PERF_DEEP_SLEEP_CNT_LSB 0 +#define LP_PERF_DEEP_SLEEP_CNT_MASK 0xffffffff +#define LP_PERF_DEEP_SLEEP_CNT_GET(x) (((x)&LP_PERF_DEEP_SLEEP_CNT_MASK) >> LP_PERF_DEEP_SLEEP_CNT_LSB) +#define LP_PERF_DEEP_SLEEP_CNT_SET(x) (((x) << LP_PERF_DEEP_SLEEP_CNT_LSB) & LP_PERF_DEEP_SLEEP_CNT_MASK) + +#define LP_PERF_ON_ADDRESS 0x00000290 +#define LP_PERF_ON_OFFSET 0x00000290 +#define LP_PERF_ON_CNT_MSB 31 +#define LP_PERF_ON_CNT_LSB 0 +#define LP_PERF_ON_CNT_MASK 0xffffffff +#define LP_PERF_ON_CNT_GET(x) (((x)&LP_PERF_ON_CNT_MASK) >> LP_PERF_ON_CNT_LSB) +#define LP_PERF_ON_CNT_SET(x) (((x) << LP_PERF_ON_CNT_LSB) & LP_PERF_ON_CNT_MASK) + +#define ST_64_BIT_ADDRESS 0x00000294 +#define ST_64_BIT_OFFSET 0x00000294 +#define ST_64_BIT_TIMEOUT_MSB 26 +#define ST_64_BIT_TIMEOUT_LSB 9 +#define ST_64_BIT_TIMEOUT_MASK 0x07fffe00 +#define ST_64_BIT_TIMEOUT_GET(x) (((x)&ST_64_BIT_TIMEOUT_MASK) >> ST_64_BIT_TIMEOUT_LSB) +#define ST_64_BIT_TIMEOUT_SET(x) (((x) << ST_64_BIT_TIMEOUT_LSB) & ST_64_BIT_TIMEOUT_MASK) +#define ST_64_BIT_REQ_ACK_NOT_PULLED_DOWN_MSB 8 +#define ST_64_BIT_REQ_ACK_NOT_PULLED_DOWN_LSB 8 +#define ST_64_BIT_REQ_ACK_NOT_PULLED_DOWN_MASK 0x00000100 +#define ST_64_BIT_REQ_ACK_NOT_PULLED_DOWN_GET(x) \ + (((x)&ST_64_BIT_REQ_ACK_NOT_PULLED_DOWN_MASK) >> ST_64_BIT_REQ_ACK_NOT_PULLED_DOWN_LSB) +#define ST_64_BIT_REQ_ACK_NOT_PULLED_DOWN_SET(x) \ + (((x) << ST_64_BIT_REQ_ACK_NOT_PULLED_DOWN_LSB) & ST_64_BIT_REQ_ACK_NOT_PULLED_DOWN_MASK) +#define ST_64_BIT_DRIVE_MODE_MSB 7 +#define ST_64_BIT_DRIVE_MODE_LSB 7 +#define ST_64_BIT_DRIVE_MODE_MASK 0x00000080 +#define ST_64_BIT_DRIVE_MODE_GET(x) (((x)&ST_64_BIT_DRIVE_MODE_MASK) >> ST_64_BIT_DRIVE_MODE_LSB) +#define ST_64_BIT_DRIVE_MODE_SET(x) (((x) << ST_64_BIT_DRIVE_MODE_LSB) & ST_64_BIT_DRIVE_MODE_MASK) +#define ST_64_BIT_CLOCK_GATE_MSB 6 +#define ST_64_BIT_CLOCK_GATE_LSB 6 +#define ST_64_BIT_CLOCK_GATE_MASK 0x00000040 +#define ST_64_BIT_CLOCK_GATE_GET(x) (((x)&ST_64_BIT_CLOCK_GATE_MASK) >> ST_64_BIT_CLOCK_GATE_LSB) +#define ST_64_BIT_CLOCK_GATE_SET(x) (((x) << ST_64_BIT_CLOCK_GATE_LSB) & ST_64_BIT_CLOCK_GATE_MASK) +#define ST_64_BIT_SOC_CLK_DIVIDE_RATIO_MSB 5 +#define ST_64_BIT_SOC_CLK_DIVIDE_RATIO_LSB 1 +#define ST_64_BIT_SOC_CLK_DIVIDE_RATIO_MASK 0x0000003e +#define ST_64_BIT_SOC_CLK_DIVIDE_RATIO_GET(x) \ + (((x)&ST_64_BIT_SOC_CLK_DIVIDE_RATIO_MASK) >> ST_64_BIT_SOC_CLK_DIVIDE_RATIO_LSB) +#define ST_64_BIT_SOC_CLK_DIVIDE_RATIO_SET(x) \ + (((x) << ST_64_BIT_SOC_CLK_DIVIDE_RATIO_LSB) & ST_64_BIT_SOC_CLK_DIVIDE_RATIO_MASK) +#define ST_64_BIT_MODE_MSB 0 +#define ST_64_BIT_MODE_LSB 0 +#define ST_64_BIT_MODE_MASK 0x00000001 +#define ST_64_BIT_MODE_GET(x) (((x)&ST_64_BIT_MODE_MASK) >> ST_64_BIT_MODE_LSB) +#define ST_64_BIT_MODE_SET(x) (((x) << ST_64_BIT_MODE_LSB) & ST_64_BIT_MODE_MASK) + +#define MESSAGE_WR_ADDRESS 0x00000298 +#define MESSAGE_WR_OFFSET 0x00000298 +#define MESSAGE_WR_TYPE_MSB 31 +#define MESSAGE_WR_TYPE_LSB 0 +#define MESSAGE_WR_TYPE_MASK 0xffffffff +#define MESSAGE_WR_TYPE_GET(x) (((x)&MESSAGE_WR_TYPE_MASK) >> MESSAGE_WR_TYPE_LSB) +#define MESSAGE_WR_TYPE_SET(x) (((x) << MESSAGE_WR_TYPE_LSB) & MESSAGE_WR_TYPE_MASK) + +#define MESSAGE_WR_P_ADDRESS 0x0000029c +#define MESSAGE_WR_P_OFFSET 0x0000029c +#define MESSAGE_WR_P_PARAMETER_MSB 31 +#define MESSAGE_WR_P_PARAMETER_LSB 0 +#define MESSAGE_WR_P_PARAMETER_MASK 0xffffffff +#define MESSAGE_WR_P_PARAMETER_GET(x) (((x)&MESSAGE_WR_P_PARAMETER_MASK) >> MESSAGE_WR_P_PARAMETER_LSB) +#define MESSAGE_WR_P_PARAMETER_SET(x) (((x) << MESSAGE_WR_P_PARAMETER_LSB) & MESSAGE_WR_P_PARAMETER_MASK) + +#define MESSAGE_RD_ADDRESS 0x000002a0 +#define MESSAGE_RD_OFFSET 0x000002a0 +#define MESSAGE_RD_TYPE_MSB 31 +#define MESSAGE_RD_TYPE_LSB 0 +#define MESSAGE_RD_TYPE_MASK 0xffffffff +#define MESSAGE_RD_TYPE_GET(x) (((x)&MESSAGE_RD_TYPE_MASK) >> MESSAGE_RD_TYPE_LSB) +#define MESSAGE_RD_TYPE_SET(x) (((x) << MESSAGE_RD_TYPE_LSB) & MESSAGE_RD_TYPE_MASK) + +#define MESSAGE_RD_P_ADDRESS 0x000002a4 +#define MESSAGE_RD_P_OFFSET 0x000002a4 +#define MESSAGE_RD_P_PARAMETER_MSB 31 +#define MESSAGE_RD_P_PARAMETER_LSB 0 +#define MESSAGE_RD_P_PARAMETER_MASK 0xffffffff +#define MESSAGE_RD_P_PARAMETER_GET(x) (((x)&MESSAGE_RD_P_PARAMETER_MASK) >> MESSAGE_RD_P_PARAMETER_LSB) +#define MESSAGE_RD_P_PARAMETER_SET(x) (((x) << MESSAGE_RD_P_PARAMETER_LSB) & MESSAGE_RD_P_PARAMETER_MASK) + +#define CHIP_MODE_ADDRESS 0x000002a8 +#define CHIP_MODE_OFFSET 0x000002a8 +#define CHIP_MODE_BIT_MSB 1 +#define CHIP_MODE_BIT_LSB 0 +#define CHIP_MODE_BIT_MASK 0x00000003 +#define CHIP_MODE_BIT_GET(x) (((x)&CHIP_MODE_BIT_MASK) >> CHIP_MODE_BIT_LSB) +#define CHIP_MODE_BIT_SET(x) (((x) << CHIP_MODE_BIT_LSB) & CHIP_MODE_BIT_MASK) + +#define CLK_REQ_FALL_EDGE_ADDRESS 0x000002ac +#define CLK_REQ_FALL_EDGE_OFFSET 0x000002ac +#define CLK_REQ_FALL_EDGE_EN_MSB 31 +#define CLK_REQ_FALL_EDGE_EN_LSB 31 +#define CLK_REQ_FALL_EDGE_EN_MASK 0x80000000 +#define CLK_REQ_FALL_EDGE_EN_GET(x) (((x)&CLK_REQ_FALL_EDGE_EN_MASK) >> CLK_REQ_FALL_EDGE_EN_LSB) +#define CLK_REQ_FALL_EDGE_EN_SET(x) (((x) << CLK_REQ_FALL_EDGE_EN_LSB) & CLK_REQ_FALL_EDGE_EN_MASK) +#define CLK_REQ_FALL_EDGE_DELAY_MSB 7 +#define CLK_REQ_FALL_EDGE_DELAY_LSB 0 +#define CLK_REQ_FALL_EDGE_DELAY_MASK 0x000000ff +#define CLK_REQ_FALL_EDGE_DELAY_GET(x) (((x)&CLK_REQ_FALL_EDGE_DELAY_MASK) >> CLK_REQ_FALL_EDGE_DELAY_LSB) +#define CLK_REQ_FALL_EDGE_DELAY_SET(x) (((x) << CLK_REQ_FALL_EDGE_DELAY_LSB) & CLK_REQ_FALL_EDGE_DELAY_MASK) + +#define OTP_ADDRESS 0x000002b0 +#define OTP_OFFSET 0x000002b0 +#define OTP_LDO25_EN_MSB 1 +#define OTP_LDO25_EN_LSB 1 +#define OTP_LDO25_EN_MASK 0x00000002 +#define OTP_LDO25_EN_GET(x) (((x)&OTP_LDO25_EN_MASK) >> OTP_LDO25_EN_LSB) +#define OTP_LDO25_EN_SET(x) (((x) << OTP_LDO25_EN_LSB) & OTP_LDO25_EN_MASK) +#define OTP_VDD12_EN_MSB 0 +#define OTP_VDD12_EN_LSB 0 +#define OTP_VDD12_EN_MASK 0x00000001 +#define OTP_VDD12_EN_GET(x) (((x)&OTP_VDD12_EN_MASK) >> OTP_VDD12_EN_LSB) +#define OTP_VDD12_EN_SET(x) (((x) << OTP_VDD12_EN_LSB) & OTP_VDD12_EN_MASK) + +#define OTP_STATUS_ADDRESS 0x000002b4 +#define OTP_STATUS_OFFSET 0x000002b4 +#define OTP_STATUS_LDO25_EN_READY_MSB 1 +#define OTP_STATUS_LDO25_EN_READY_LSB 1 +#define OTP_STATUS_LDO25_EN_READY_MASK 0x00000002 +#define OTP_STATUS_LDO25_EN_READY_GET(x) (((x)&OTP_STATUS_LDO25_EN_READY_MASK) >> OTP_STATUS_LDO25_EN_READY_LSB) +#define OTP_STATUS_LDO25_EN_READY_SET(x) (((x) << OTP_STATUS_LDO25_EN_READY_LSB) & OTP_STATUS_LDO25_EN_READY_MASK) +#define OTP_STATUS_VDD12_EN_READY_MSB 0 +#define OTP_STATUS_VDD12_EN_READY_LSB 0 +#define OTP_STATUS_VDD12_EN_READY_MASK 0x00000001 +#define OTP_STATUS_VDD12_EN_READY_GET(x) (((x)&OTP_STATUS_VDD12_EN_READY_MASK) >> OTP_STATUS_VDD12_EN_READY_LSB) +#define OTP_STATUS_VDD12_EN_READY_SET(x) (((x) << OTP_STATUS_VDD12_EN_READY_LSB) & OTP_STATUS_VDD12_EN_READY_MASK) + +#define PMU_ADDRESS 0x000002b8 +#define PMU_OFFSET 0x000002b8 +#define PMU_REG_WAKEUP_TIME_SEL_MSB 1 +#define PMU_REG_WAKEUP_TIME_SEL_LSB 0 +#define PMU_REG_WAKEUP_TIME_SEL_MASK 0x00000003 +#define PMU_REG_WAKEUP_TIME_SEL_GET(x) (((x)&PMU_REG_WAKEUP_TIME_SEL_MASK) >> PMU_REG_WAKEUP_TIME_SEL_LSB) +#define PMU_REG_WAKEUP_TIME_SEL_SET(x) (((x) << PMU_REG_WAKEUP_TIME_SEL_LSB) & PMU_REG_WAKEUP_TIME_SEL_MASK) + +#define PMU_CONFIG_ADDRESS 0x000002c0 +#define PMU_CONFIG_OFFSET 0x000002c0 +#define PMU_CONFIG_VALUE_MSB 15 +#define PMU_CONFIG_VALUE_LSB 0 +#define PMU_CONFIG_VALUE_MASK 0x0000ffff +#define PMU_CONFIG_VALUE_GET(x) (((x)&PMU_CONFIG_VALUE_MASK) >> PMU_CONFIG_VALUE_LSB) +#define PMU_CONFIG_VALUE_SET(x) (((x) << PMU_CONFIG_VALUE_LSB) & PMU_CONFIG_VALUE_MASK) + +#define PMU_BYPASS_ADDRESS 0x000002c8 +#define PMU_BYPASS_OFFSET 0x000002c8 +#define PMU_BYPASS_SWREG_MSB 2 +#define PMU_BYPASS_SWREG_LSB 2 +#define PMU_BYPASS_SWREG_MASK 0x00000004 +#define PMU_BYPASS_SWREG_GET(x) (((x)&PMU_BYPASS_SWREG_MASK) >> PMU_BYPASS_SWREG_LSB) +#define PMU_BYPASS_SWREG_SET(x) (((x) << PMU_BYPASS_SWREG_LSB) & PMU_BYPASS_SWREG_MASK) +#define PMU_BYPASS_DREG_MSB 1 +#define PMU_BYPASS_DREG_LSB 1 +#define PMU_BYPASS_DREG_MASK 0x00000002 +#define PMU_BYPASS_DREG_GET(x) (((x)&PMU_BYPASS_DREG_MASK) >> PMU_BYPASS_DREG_LSB) +#define PMU_BYPASS_DREG_SET(x) (((x) << PMU_BYPASS_DREG_LSB) & PMU_BYPASS_DREG_MASK) +#define PMU_BYPASS_PAREG_MSB 0 +#define PMU_BYPASS_PAREG_LSB 0 +#define PMU_BYPASS_PAREG_MASK 0x00000001 +#define PMU_BYPASS_PAREG_GET(x) (((x)&PMU_BYPASS_PAREG_MASK) >> PMU_BYPASS_PAREG_LSB) +#define PMU_BYPASS_PAREG_SET(x) (((x) << PMU_BYPASS_PAREG_LSB) & PMU_BYPASS_PAREG_MASK) + +#define MAC_PCU_TSF2_L32_ADDRESS 0x000002cc +#define MAC_PCU_TSF2_L32_OFFSET 0x000002cc +#define MAC_PCU_TSF2_L32_VALUE_MSB 31 +#define MAC_PCU_TSF2_L32_VALUE_LSB 0 +#define MAC_PCU_TSF2_L32_VALUE_MASK 0xffffffff +#define MAC_PCU_TSF2_L32_VALUE_GET(x) (((x)&MAC_PCU_TSF2_L32_VALUE_MASK) >> MAC_PCU_TSF2_L32_VALUE_LSB) +#define MAC_PCU_TSF2_L32_VALUE_SET(x) (((x) << MAC_PCU_TSF2_L32_VALUE_LSB) & MAC_PCU_TSF2_L32_VALUE_MASK) + +#define MAC_PCU_TSF2_U32_ADDRESS 0x000002d0 +#define MAC_PCU_TSF2_U32_OFFSET 0x000002d0 +#define MAC_PCU_TSF2_U32_VALUE_MSB 31 +#define MAC_PCU_TSF2_U32_VALUE_LSB 0 +#define MAC_PCU_TSF2_U32_VALUE_MASK 0xffffffff +#define MAC_PCU_TSF2_U32_VALUE_GET(x) (((x)&MAC_PCU_TSF2_U32_VALUE_MASK) >> MAC_PCU_TSF2_U32_VALUE_LSB) +#define MAC_PCU_TSF2_U32_VALUE_SET(x) (((x) << MAC_PCU_TSF2_U32_VALUE_LSB) & MAC_PCU_TSF2_U32_VALUE_MASK) + +#define MAC_PCU_GENERIC_TIMERS_MODE3_ADDRESS 0x000002d4 +#define MAC_PCU_GENERIC_TIMERS_MODE3_OFFSET 0x000002d4 +#define MAC_PCU_GENERIC_TIMERS_MODE3_OVERFLOW_INDEX_MSB 27 +#define MAC_PCU_GENERIC_TIMERS_MODE3_OVERFLOW_INDEX_LSB 24 +#define MAC_PCU_GENERIC_TIMERS_MODE3_OVERFLOW_INDEX_MASK 0x0f000000 +#define MAC_PCU_GENERIC_TIMERS_MODE3_OVERFLOW_INDEX_GET(x) \ + (((x)&MAC_PCU_GENERIC_TIMERS_MODE3_OVERFLOW_INDEX_MASK) >> MAC_PCU_GENERIC_TIMERS_MODE3_OVERFLOW_INDEX_LSB) +#define MAC_PCU_GENERIC_TIMERS_MODE3_OVERFLOW_INDEX_SET(x) \ + (((x) << MAC_PCU_GENERIC_TIMERS_MODE3_OVERFLOW_INDEX_LSB) & MAC_PCU_GENERIC_TIMERS_MODE3_OVERFLOW_INDEX_MASK) +#define MAC_PCU_GENERIC_TIMERS_MODE3_THRESH_MSB 19 +#define MAC_PCU_GENERIC_TIMERS_MODE3_THRESH_LSB 0 +#define MAC_PCU_GENERIC_TIMERS_MODE3_THRESH_MASK 0x000fffff +#define MAC_PCU_GENERIC_TIMERS_MODE3_THRESH_GET(x) \ + (((x)&MAC_PCU_GENERIC_TIMERS_MODE3_THRESH_MASK) >> MAC_PCU_GENERIC_TIMERS_MODE3_THRESH_LSB) +#define MAC_PCU_GENERIC_TIMERS_MODE3_THRESH_SET(x) \ + (((x) << MAC_PCU_GENERIC_TIMERS_MODE3_THRESH_LSB) & MAC_PCU_GENERIC_TIMERS_MODE3_THRESH_MASK) + +#define MAC_PCU_DIRECT_CONNECT_ADDRESS 0x000002d8 +#define MAC_PCU_DIRECT_CONNECT_OFFSET 0x000002d8 +#define MAC_PCU_DIRECT_CONNECT_STA_TSF_1_2_SEL_MSB 2 +#define MAC_PCU_DIRECT_CONNECT_STA_TSF_1_2_SEL_LSB 2 +#define MAC_PCU_DIRECT_CONNECT_STA_TSF_1_2_SEL_MASK 0x00000004 +#define MAC_PCU_DIRECT_CONNECT_STA_TSF_1_2_SEL_GET(x) \ + (((x)&MAC_PCU_DIRECT_CONNECT_STA_TSF_1_2_SEL_MASK) >> MAC_PCU_DIRECT_CONNECT_STA_TSF_1_2_SEL_LSB) +#define MAC_PCU_DIRECT_CONNECT_STA_TSF_1_2_SEL_SET(x) \ + (((x) << MAC_PCU_DIRECT_CONNECT_STA_TSF_1_2_SEL_LSB) & MAC_PCU_DIRECT_CONNECT_STA_TSF_1_2_SEL_MASK) +#define MAC_PCU_DIRECT_CONNECT_AP_TSF_1_2_SEL_MSB 1 +#define MAC_PCU_DIRECT_CONNECT_AP_TSF_1_2_SEL_LSB 1 +#define MAC_PCU_DIRECT_CONNECT_AP_TSF_1_2_SEL_MASK 0x00000002 +#define MAC_PCU_DIRECT_CONNECT_AP_TSF_1_2_SEL_GET(x) \ + (((x)&MAC_PCU_DIRECT_CONNECT_AP_TSF_1_2_SEL_MASK) >> MAC_PCU_DIRECT_CONNECT_AP_TSF_1_2_SEL_LSB) +#define MAC_PCU_DIRECT_CONNECT_AP_TSF_1_2_SEL_SET(x) \ + (((x) << MAC_PCU_DIRECT_CONNECT_AP_TSF_1_2_SEL_LSB) & MAC_PCU_DIRECT_CONNECT_AP_TSF_1_2_SEL_MASK) +#define MAC_PCU_DIRECT_CONNECT_AP_STA_ENABLE_MSB 0 +#define MAC_PCU_DIRECT_CONNECT_AP_STA_ENABLE_LSB 0 +#define MAC_PCU_DIRECT_CONNECT_AP_STA_ENABLE_MASK 0x00000001 +#define MAC_PCU_DIRECT_CONNECT_AP_STA_ENABLE_GET(x) \ + (((x)&MAC_PCU_DIRECT_CONNECT_AP_STA_ENABLE_MASK) >> MAC_PCU_DIRECT_CONNECT_AP_STA_ENABLE_LSB) +#define MAC_PCU_DIRECT_CONNECT_AP_STA_ENABLE_SET(x) \ + (((x) << MAC_PCU_DIRECT_CONNECT_AP_STA_ENABLE_LSB) & MAC_PCU_DIRECT_CONNECT_AP_STA_ENABLE_MASK) + +#define THERM_CTRL1_ADDRESS 0x000002dc +#define THERM_CTRL1_OFFSET 0x000002dc +#define THERM_CTRL1_BYPASS_MSB 16 +#define THERM_CTRL1_BYPASS_LSB 16 +#define THERM_CTRL1_BYPASS_MASK 0x00010000 +#define THERM_CTRL1_BYPASS_GET(x) (((x)&THERM_CTRL1_BYPASS_MASK) >> THERM_CTRL1_BYPASS_LSB) +#define THERM_CTRL1_BYPASS_SET(x) (((x) << THERM_CTRL1_BYPASS_LSB) & THERM_CTRL1_BYPASS_MASK) +#define THERM_CTRL1_WIDTH_ARBITOR_MSB 15 +#define THERM_CTRL1_WIDTH_ARBITOR_LSB 12 +#define THERM_CTRL1_WIDTH_ARBITOR_MASK 0x0000f000 +#define THERM_CTRL1_WIDTH_ARBITOR_GET(x) (((x)&THERM_CTRL1_WIDTH_ARBITOR_MASK) >> THERM_CTRL1_WIDTH_ARBITOR_LSB) +#define THERM_CTRL1_WIDTH_ARBITOR_SET(x) (((x) << THERM_CTRL1_WIDTH_ARBITOR_LSB) & THERM_CTRL1_WIDTH_ARBITOR_MASK) +#define THERM_CTRL1_WIDTH_MSB 11 +#define THERM_CTRL1_WIDTH_LSB 5 +#define THERM_CTRL1_WIDTH_MASK 0x00000fe0 +#define THERM_CTRL1_WIDTH_GET(x) (((x)&THERM_CTRL1_WIDTH_MASK) >> THERM_CTRL1_WIDTH_LSB) +#define THERM_CTRL1_WIDTH_SET(x) (((x) << THERM_CTRL1_WIDTH_LSB) & THERM_CTRL1_WIDTH_MASK) +#define THERM_CTRL1_TYPE_MSB 4 +#define THERM_CTRL1_TYPE_LSB 3 +#define THERM_CTRL1_TYPE_MASK 0x00000018 +#define THERM_CTRL1_TYPE_GET(x) (((x)&THERM_CTRL1_TYPE_MASK) >> THERM_CTRL1_TYPE_LSB) +#define THERM_CTRL1_TYPE_SET(x) (((x) << THERM_CTRL1_TYPE_LSB) & THERM_CTRL1_TYPE_MASK) +#define THERM_CTRL1_MEASURE_MSB 2 +#define THERM_CTRL1_MEASURE_LSB 2 +#define THERM_CTRL1_MEASURE_MASK 0x00000004 +#define THERM_CTRL1_MEASURE_GET(x) (((x)&THERM_CTRL1_MEASURE_MASK) >> THERM_CTRL1_MEASURE_LSB) +#define THERM_CTRL1_MEASURE_SET(x) (((x) << THERM_CTRL1_MEASURE_LSB) & THERM_CTRL1_MEASURE_MASK) +#define THERM_CTRL1_INT_EN_MSB 1 +#define THERM_CTRL1_INT_EN_LSB 1 +#define THERM_CTRL1_INT_EN_MASK 0x00000002 +#define THERM_CTRL1_INT_EN_GET(x) (((x)&THERM_CTRL1_INT_EN_MASK) >> THERM_CTRL1_INT_EN_LSB) +#define THERM_CTRL1_INT_EN_SET(x) (((x) << THERM_CTRL1_INT_EN_LSB) & THERM_CTRL1_INT_EN_MASK) +#define THERM_CTRL1_INT_STATUS_MSB 0 +#define THERM_CTRL1_INT_STATUS_LSB 0 +#define THERM_CTRL1_INT_STATUS_MASK 0x00000001 +#define THERM_CTRL1_INT_STATUS_GET(x) (((x)&THERM_CTRL1_INT_STATUS_MASK) >> THERM_CTRL1_INT_STATUS_LSB) +#define THERM_CTRL1_INT_STATUS_SET(x) (((x) << THERM_CTRL1_INT_STATUS_LSB) & THERM_CTRL1_INT_STATUS_MASK) + +#define THERM_CTRL2_ADDRESS 0x000002e0 +#define THERM_CTRL2_OFFSET 0x000002e0 +#define THERM_CTRL2_ADC_OFF_MSB 25 +#define THERM_CTRL2_ADC_OFF_LSB 25 +#define THERM_CTRL2_ADC_OFF_MASK 0x02000000 +#define THERM_CTRL2_ADC_OFF_GET(x) (((x)&THERM_CTRL2_ADC_OFF_MASK) >> THERM_CTRL2_ADC_OFF_LSB) +#define THERM_CTRL2_ADC_OFF_SET(x) (((x) << THERM_CTRL2_ADC_OFF_LSB) & THERM_CTRL2_ADC_OFF_MASK) +#define THERM_CTRL2_ADC_ON_MSB 24 +#define THERM_CTRL2_ADC_ON_LSB 24 +#define THERM_CTRL2_ADC_ON_MASK 0x01000000 +#define THERM_CTRL2_ADC_ON_GET(x) (((x)&THERM_CTRL2_ADC_ON_MASK) >> THERM_CTRL2_ADC_ON_LSB) +#define THERM_CTRL2_ADC_ON_SET(x) (((x) << THERM_CTRL2_ADC_ON_LSB) & THERM_CTRL2_ADC_ON_MASK) +#define THERM_CTRL2_SAMPLE_MSB 23 +#define THERM_CTRL2_SAMPLE_LSB 16 +#define THERM_CTRL2_SAMPLE_MASK 0x00ff0000 +#define THERM_CTRL2_SAMPLE_GET(x) (((x)&THERM_CTRL2_SAMPLE_MASK) >> THERM_CTRL2_SAMPLE_LSB) +#define THERM_CTRL2_SAMPLE_SET(x) (((x) << THERM_CTRL2_SAMPLE_LSB) & THERM_CTRL2_SAMPLE_MASK) +#define THERM_CTRL2_HIGH_MSB 15 +#define THERM_CTRL2_HIGH_LSB 8 +#define THERM_CTRL2_HIGH_MASK 0x0000ff00 +#define THERM_CTRL2_HIGH_GET(x) (((x)&THERM_CTRL2_HIGH_MASK) >> THERM_CTRL2_HIGH_LSB) +#define THERM_CTRL2_HIGH_SET(x) (((x) << THERM_CTRL2_HIGH_LSB) & THERM_CTRL2_HIGH_MASK) +#define THERM_CTRL2_LOW_MSB 7 +#define THERM_CTRL2_LOW_LSB 0 +#define THERM_CTRL2_LOW_MASK 0x000000ff +#define THERM_CTRL2_LOW_GET(x) (((x)&THERM_CTRL2_LOW_MASK) >> THERM_CTRL2_LOW_LSB) +#define THERM_CTRL2_LOW_SET(x) (((x) << THERM_CTRL2_LOW_LSB) & THERM_CTRL2_LOW_MASK) + +#define THERM_CTRL3_ADDRESS 0x000002e4 +#define THERM_CTRL3_OFFSET 0x000002e4 +#define THERM_CTRL3_ADC_GAIN_MSB 16 +#define THERM_CTRL3_ADC_GAIN_LSB 8 +#define THERM_CTRL3_ADC_GAIN_MASK 0x0001ff00 +#define THERM_CTRL3_ADC_GAIN_GET(x) (((x)&THERM_CTRL3_ADC_GAIN_MASK) >> THERM_CTRL3_ADC_GAIN_LSB) +#define THERM_CTRL3_ADC_GAIN_SET(x) (((x) << THERM_CTRL3_ADC_GAIN_LSB) & THERM_CTRL3_ADC_GAIN_MASK) +#define THERM_CTRL3_ADC_OFFSET_MSB 7 +#define THERM_CTRL3_ADC_OFFSET_LSB 0 +#define THERM_CTRL3_ADC_OFFSET_MASK 0x000000ff +#define THERM_CTRL3_ADC_OFFSET_GET(x) (((x)&THERM_CTRL3_ADC_OFFSET_MASK) >> THERM_CTRL3_ADC_OFFSET_LSB) +#define THERM_CTRL3_ADC_OFFSET_SET(x) (((x) << THERM_CTRL3_ADC_OFFSET_LSB) & THERM_CTRL3_ADC_OFFSET_MASK) + +#ifndef __ASSEMBLER__ + +typedef struct rtc_wlan_reg_reg_s +{ + volatile unsigned int wlan_reset_control; + volatile unsigned int wlan_xtal_control; + volatile unsigned int wlan_tcxo_detect; + volatile unsigned int wlan_xtal_test; + volatile unsigned int wlan_quadrature; + volatile unsigned int wlan_pll_control; + volatile unsigned int wlan_pll_settle; + volatile unsigned int wlan_xtal_settle; + volatile unsigned int wlan_cpu_clock; + volatile unsigned int wlan_clock_out; + volatile unsigned int wlan_clock_control; + volatile unsigned int wlan_bias_override; + volatile unsigned int wlan_wdt_control; + volatile unsigned int wlan_wdt_status; + volatile unsigned int wlan_wdt; + volatile unsigned int wlan_wdt_count; + volatile unsigned int wlan_wdt_reset; + volatile unsigned int wlan_int_status; + volatile unsigned int wlan_lf_timer0; + volatile unsigned int wlan_lf_timer_count0; + volatile unsigned int wlan_lf_timer_control0; + volatile unsigned int wlan_lf_timer_status0; + volatile unsigned int wlan_lf_timer1; + volatile unsigned int wlan_lf_timer_count1; + volatile unsigned int wlan_lf_timer_control1; + volatile unsigned int wlan_lf_timer_status1; + volatile unsigned int wlan_lf_timer2; + volatile unsigned int wlan_lf_timer_count2; + volatile unsigned int wlan_lf_timer_control2; + volatile unsigned int wlan_lf_timer_status2; + volatile unsigned int wlan_lf_timer3; + volatile unsigned int wlan_lf_timer_count3; + volatile unsigned int wlan_lf_timer_control3; + volatile unsigned int wlan_lf_timer_status3; + volatile unsigned int wlan_hf_timer; + volatile unsigned int wlan_hf_timer_count; + volatile unsigned int wlan_hf_lf_count; + volatile unsigned int wlan_hf_timer_control; + volatile unsigned int wlan_hf_timer_status; + volatile unsigned int wlan_rtc_control; + volatile unsigned int wlan_rtc_time; + volatile unsigned int wlan_rtc_date; + volatile unsigned int wlan_rtc_set_time; + volatile unsigned int wlan_rtc_set_date; + volatile unsigned int wlan_rtc_set_alarm; + volatile unsigned int wlan_rtc_config; + volatile unsigned int wlan_rtc_alarm_status; + volatile unsigned int wlan_uart_wakeup; + volatile unsigned int wlan_reset_cause; + volatile unsigned int wlan_system_sleep; + volatile unsigned int wlan_sdio_wrapper; + volatile unsigned int wlan_mac_sleep_control; + volatile unsigned int wlan_keep_awake; + volatile unsigned int wlan_lpo_cal_time; + volatile unsigned int wlan_lpo_init_dividend_int; + volatile unsigned int wlan_lpo_init_dividend_fraction; + volatile unsigned int wlan_lpo_cal; + volatile unsigned int wlan_lpo_cal_test_control; + volatile unsigned int wlan_lpo_cal_test_status; + volatile unsigned int wlan_chip_id; + volatile unsigned int wlan_derived_rtc_clk; + volatile unsigned int mac_pcu_slp32_mode; + volatile unsigned int mac_pcu_slp32_wake; + volatile unsigned int mac_pcu_slp32_inc; + volatile unsigned int mac_pcu_slp_mib1; + volatile unsigned int mac_pcu_slp_mib2; + volatile unsigned int mac_pcu_slp_mib3; + volatile unsigned int wlan_power_reg; + volatile unsigned int wlan_core_clk_ctrl; + volatile unsigned int wlan_gpio_wakeup_control; + volatile unsigned int ht; + volatile unsigned int mac_pcu_tsf_l32; + volatile unsigned int mac_pcu_tsf_u32; + volatile unsigned int mac_pcu_wbtimer; + unsigned char pad0[24]; /* pad to 0x140 */ + volatile unsigned int mac_pcu_generic_timers[16]; + volatile unsigned int mac_pcu_generic_timers_mode; + unsigned char pad1[60]; /* pad to 0x1c0 */ + volatile unsigned int mac_pcu_generic_timers2[16]; + volatile unsigned int mac_pcu_generic_timers_mode2; + volatile unsigned int mac_pcu_slp1; + volatile unsigned int mac_pcu_slp2; + volatile unsigned int mac_pcu_reset_tsf; + volatile unsigned int mac_pcu_tsf_add_pll; + volatile unsigned int sleep_retention; + volatile unsigned int btcoexctrl; + volatile unsigned int wbsync_priority1; + volatile unsigned int wbsync_priority2; + volatile unsigned int wbsync_priority3; + volatile unsigned int btcoex0; + volatile unsigned int btcoex1; + volatile unsigned int btcoex2; + volatile unsigned int btcoex3; + volatile unsigned int btcoex4; + volatile unsigned int btcoex5; + volatile unsigned int btcoex6; + volatile unsigned int lock; + volatile unsigned int nolock_priority; + volatile unsigned int wbsync; + volatile unsigned int wbsync1; + volatile unsigned int wbsync2; + volatile unsigned int wbsync3; + volatile unsigned int wb_timer_target; + volatile unsigned int wb_timer_slop; + volatile unsigned int btcoex_int_en; + volatile unsigned int btcoex_int_stat; + volatile unsigned int btpriority_int_en; + volatile unsigned int btpriority_int_stat; + volatile unsigned int btpriority_stomp_int_en; + volatile unsigned int btpriority_stomp_int_stat; + volatile unsigned int mac_pcu_bmiss_timeout; + volatile unsigned int mac_pcu_cab_awake; + volatile unsigned int lp_perf_counter; + volatile unsigned int lp_perf_light_sleep; + volatile unsigned int lp_perf_deep_sleep; + volatile unsigned int lp_perf_on; + volatile unsigned int st_64_bit; + volatile unsigned int message_wr; + volatile unsigned int message_wr_p; + volatile unsigned int message_rd; + volatile unsigned int message_rd_p; + volatile unsigned int chip_mode; + volatile unsigned int clk_req_fall_edge; + volatile unsigned int otp; + volatile unsigned int otp_status; + volatile unsigned int pmu; + unsigned char pad2[4]; /* pad to 0x2c0 */ + volatile unsigned int pmu_config[2]; + volatile unsigned int pmu_bypass; + volatile unsigned int mac_pcu_tsf2_l32; + volatile unsigned int mac_pcu_tsf2_u32; + volatile unsigned int mac_pcu_generic_timers_mode3; + volatile unsigned int mac_pcu_direct_connect; + volatile unsigned int therm_ctrl1; + volatile unsigned int therm_ctrl2; + volatile unsigned int therm_ctrl3; +} rtc_wlan_reg_reg_t; + +#endif /* __ASSEMBLER__ */ + +#endif /* _RTC_WLAN_REG_H_ */ diff --git a/platform/mcu/lpc54102/wifi_qca/include/athdefs.h b/platform/mcu/lpc54102/wifi_qca/include/athdefs.h new file mode 100644 index 0000000000..953df1028a --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/include/athdefs.h @@ -0,0 +1,106 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== +#ifndef __ATHDEFS_H__ +#define __ATHDEFS_H__ + +/* + * This file contains definitions that may be used across both + * Host and Target software. Nothing here is module-dependent + * or platform-dependent. + */ + +#include +typedef uint32_t boolean; + +/* + * Generic error codes that can be used by hw, sta, ap, sim, dk + * and any other environments. Since these are enums, feel free to + * add any more codes that you need. + */ + +typedef enum +{ + A_TIMEOUT = -3, /*TODO: fix later*/ + A_SOCK_INVALID = -2, + A_ERROR = -1, /* Generic error return */ + A_OK = 0, /* success */ + /* Following values start at 1 */ + A_DEVICE_NOT_FOUND, /* not able to find PCI device */ + A_NO_MEMORY, /* not able to allocate memory, not available */ + A_MEMORY_NOT_AVAIL, /* memory region is not free for mapping */ + A_NO_FREE_DESC, /* no free descriptors available */ + A_BAD_ADDRESS, /* address does not match descriptor */ + A_WIN_DRIVER_ERROR, /* used in NT_HW version, if problem at init */ + A_REGS_NOT_MAPPED, /* registers not correctly mapped */ + A_EPERM, /* Not superuser */ + A_EACCES, /* Access denied */ + A_ENOENT, /* No such entry, search failed, etc. */ + A_EEXIST, /* The object already exists (can't create) */ + A_EFAULT, /* Bad address fault */ + A_EBUSY, /* Object is busy */ + A_EINVAL, /* Invalid parameter */ + A_EMSGSIZE, /* Inappropriate message buffer length */ + A_ECANCELED, /* Operation canceled */ + A_ENOTSUP, /* Operation not supported */ + A_ECOMM, /* Communication error on send */ + A_EPROTO, /* Protocol error */ + A_ENODEV, /* No such device */ + A_EDEVNOTUP, /* device is not UP */ + A_NO_RESOURCE, /* No resources for requested operation */ + A_HARDWARE, /* Hardware failure */ + A_PENDING, /* Asynchronous routine; will send up results later (typically in callback) */ + A_EBADCHANNEL, /* The channel cannot be used */ + A_DECRYPT_ERROR, /* Decryption error */ + A_PHY_ERROR, /* RX PHY error */ + A_CONSUMED, /* Object was consumed */ + A_SOCKCXT_NOT_FOUND, /*Socket context not found*/ + A_UNKNOWN_CMD, /*Unknown socket ocmmand*/ + A_SOCK_UNAVAILABLE, /*Socket limit reached*/ + A_MEMFREE_ERROR /*Error while freeing resource*/ +} A_STATUS; + +#define A_SUCCESS(x) (x == A_OK) +#define A_FAILED(x) (!A_SUCCESS(x)) + +typedef enum +{ + USER, /* Max Perf set by user */ + WPS, /* Max Perf set by WPS */ + P2P, /* Max Perf set by P2P */ + SOFTAP, + SRCALL, + DHCP, + TCPL1, + TCPL2, + TKIP, + RAWMODE, + PWR_MAX = 32, +} A_PWR_MODULE; + +#define EXPECTED_REF_CLK_AR4100 26000000 +#define EXPECTED_REF_CLK_AR400X 40000000 + +#endif /* __ATHDEFS_H__ */ diff --git a/platform/mcu/lpc54102/wifi_qca/include/bmi_msg.h b/platform/mcu/lpc54102/wifi_qca/include/bmi_msg.h new file mode 100644 index 0000000000..ffef2d31eb --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/include/bmi_msg.h @@ -0,0 +1,271 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== + +#ifndef __BMI_MSG_H__ +#define __BMI_MSG_H__ + +/* + * Bootloader Messaging Interface (BMI) + * + * BMI is a very simple messaging interface used during initialization + * to read memory, write memory, execute code, and to define an + * application entry PC. + * + * It is used to download an application to AR6K, to provide + * patches to code that is already resident on AR6K, and generally + * to examine and modify state. The Host has an opportunity to use + * BMI only once during bootup. Once the Host issues a BMI_DONE + * command, this opportunity ends. + * + * The Host writes BMI requests to mailbox0, and reads BMI responses + * from mailbox0. BMI requests all begin with a command + * (see below for specific commands), and are followed by + * command-specific data. + * + * Flow control: + * The Host can only issue a command once the Target gives it a + * "BMI Command Credit", using AR6K Counter #4. As soon as the + * Target has completed a command, it issues another BMI Command + * Credit (so the Host can issue the next command). + * + * BMI handles all required Target-side cache flushing. + */ + +/* Maximum data size used for BMI transfers */ +#define BMI_DATASZ_MAX 256 + +/* BMI Commands */ + +#define BMI_NO_COMMAND 0 + +#define BMI_DONE 1 +/* + * Semantics: Host is done using BMI + * Request format: + * uint32_t command (BMI_DONE) + * Response format: none + */ + +#define BMI_READ_MEMORY 2 +/* + * Semantics: Host reads AR6K memory + * Request format: + * uint32_t command (BMI_READ_MEMORY) + * uint32_t address + * uint32_t length, at most BMI_DATASZ_MAX + * Response format: + * uint8_t data[length] + */ + +#define BMI_WRITE_MEMORY 3 +/* + * Semantics: Host writes AR6K memory + * Request format: + * uint32_t command (BMI_WRITE_MEMORY) + * uint32_t address + * uint32_t length, at most BMI_DATASZ_MAX + * uint8_t data[length] + * Response format: none + */ + +#define BMI_EXECUTE 4 +/* + * Semantics: Causes AR6K to execute code + * Request format: + * uint32_t command (BMI_EXECUTE) + * uint32_t address + * uint32_t parameter + * Response format: + * uint32_t return value + */ + +#define BMI_SET_APP_START 5 +/* + * Semantics: Set Target application starting address + * Request format: + * uint32_t command (BMI_SET_APP_START) + * uint32_t address + * Response format: none + */ + +#define BMI_READ_SOC_REGISTER 6 +/* + * Semantics: Read a 32-bit Target SOC register. + * Request format: + * uint32_t command (BMI_READ_REGISTER) + * uint32_t address + * Response format: + * uint32_t value + */ + +#define BMI_WRITE_SOC_REGISTER 7 +/* + * Semantics: Write a 32-bit Target SOC register. + * Request format: + * uint32_t command (BMI_WRITE_REGISTER) + * uint32_t address + * uint32_t value + * + * Response format: none + */ + +#define BMI_GET_TARGET_ID 8 +#define BMI_GET_TARGET_INFO 8 +/* + * Semantics: Fetch the 4-byte Target information + * Request format: + * uint32_t command (BMI_GET_TARGET_ID/INFO) + * Response format1 (old firmware): + * uint32_t TargetVersionID + * Response format2 (newer firmware): + * uint32_t TARGET_VERSION_SENTINAL + * struct bmi_target_info; + */ + +struct bmi_target_info +{ + uint32_t target_info_byte_count; /* size of this structure */ + uint32_t target_ver; /* Target Version ID */ + uint32_t target_type; /* Target type */ +}; + +#define TARGET_VERSION_SENTINAL 0xffffffff +#define TARGET_TYPE_AR4100 3 +#define TARGET_TYPE_AR400X 6 + +#if ATH_FIRMWARE_TARGET == TARGET_AR4100_REV2 +#define TARGET_TYPE TARGET_TYPE_AR4100 +#elif ATH_FIRMWARE_TARGET == TARGET_AR400X_REV1 +#define TARGET_TYPE TARGET_TYPE_AR400X +#endif + +#define BMI_ROMPATCH_INSTALL 9 +/* + * Semantics: Install a ROM Patch. + * Request format: + * uint32_t command (BMI_ROMPATCH_INSTALL) + * uint32_t Target ROM Address + * uint32_t Target RAM Address or Value (depending on Target Type) + * uint32_t Size, in bytes + * uint32_t Activate? 1-->activate; + * 0-->install but do not activate + * Response format: + * uint32_t PatchID + */ + +#define BMI_ROMPATCH_UNINSTALL 10 +/* + * Semantics: Uninstall a previously-installed ROM Patch, + * automatically deactivating, if necessary. + * Request format: + * uint32_t command (BMI_ROMPATCH_UNINSTALL) + * uint32_t PatchID + * + * Response format: none + */ + +#define BMI_ROMPATCH_ACTIVATE 11 +/* + * Semantics: Activate a list of previously-installed ROM Patches. + * Request format: + * uint32_t command (BMI_ROMPATCH_ACTIVATE) + * uint32_t rompatch_count + * uint32_t PatchID[rompatch_count] + * + * Response format: none + */ + +#define BMI_ROMPATCH_DEACTIVATE 12 +/* + * Semantics: Deactivate a list of active ROM Patches. + * Request format: + * uint32_t command (BMI_ROMPATCH_DEACTIVATE) + * uint32_t rompatch_count + * uint32_t PatchID[rompatch_count] + * + * Response format: none + */ + +#define BMI_LZ_STREAM_START 13 +/* + * Semantics: Begin an LZ-compressed stream of input + * which is to be uncompressed by the Target to an + * output buffer at address. The output buffer must + * be sufficiently large to hold the uncompressed + * output from the compressed input stream. This BMI + * command should be followed by a series of 1 or more + * BMI_LZ_DATA commands. + * uint32_t command (BMI_LZ_STREAM_START) + * uint32_t address + * Note: Not supported on all versions of ROM firmware. + */ + +#define BMI_LZ_DATA 14 +/* + * Semantics: Host writes AR6K memory with LZ-compressed + * data which is uncompressed by the Target. This command + * must be preceded by a BMI_LZ_STREAM_START command. A series + * of BMI_LZ_DATA commands are considered part of a single + * input stream until another BMI_LZ_STREAM_START is issued. + * Request format: + * uint32_t command (BMI_LZ_DATA) + * uint32_t length (of compressed data), + * at most BMI_DATASZ_MAX + * uint8_t CompressedData[length] + * Response format: none + * Note: Not supported on all versions of ROM firmware. + */ + +#define BMI_NVRAM_PROCESS 15 +#define BMI_NVRAM_SEG_NAME_SZ 16 +/* + * Semantics: Cause Target to search NVRAM (if any) for a + * segment with the specified name and process it according + * to NVRAM metadata. + * Request format: + * uint32_t command (BMI_NVRAM_PROCESS) + * uint8_t name[BMI_NVRAM_SEG_NAME_SZ] name (LE format) + * Response format: + * uint32_t 0, if nothing was executed; + * otherwise the value returned from the + * last NVRAM segment that was executed + */ + +#define BMI_SEGMENTED_WRITE_ADDR 0x1234 +/* + * Semantics: This is not a command but just the write memory address + * that should be used by hosted systems while downloading segmented + * firmware binary file to the target while target is in BMI mode. + * Target in BMI mode interprets stream and loads the various segments + * being downloaded onto appropriate target RAM locations. + * Request format: + * uint32_t command (BMI_WRITE_MEMORY) + * uint32_t address + * uint32_t length, at most BMI_DATASZ_MAX + * uint8_t data[length] + * Response format: none + */ +#endif /* __BMI_MSG_H__ */ diff --git a/platform/mcu/lpc54102/wifi_qca/include/dbglog.h b/platform/mcu/lpc54102/wifi_qca/include/dbglog.h new file mode 100644 index 0000000000..2cde2448f6 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/include/dbglog.h @@ -0,0 +1,136 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== + +#ifndef _DBGLOG_H_ +#define _DBGLOG_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#define DBGLOG_TIMESTAMP_OFFSET 0 +#define DBGLOG_TIMESTAMP_MASK \ + 0x0000FFFF /* Bit 0-15. Contains bit \ + 8-23 of the LF0 timer */ +#define DBGLOG_DBGID_OFFSET 16 +#define DBGLOG_DBGID_MASK 0x03FF0000 /* Bit 16-25 */ +#define DBGLOG_DBGID_NUM_MAX 256 /* Upper limit is width of mask */ + +#define DBGLOG_MODULEID_OFFSET 26 +#define DBGLOG_MODULEID_MASK 0x3C000000 /* Bit 26-29 */ +#define DBGLOG_MODULEID_NUM_MAX 16 /* Upper limit is width of mask */ + +/* + * Please ensure that the definition of any new module intrduced is captured + * between the DBGLOG_MODULEID_START and DBGLOG_MODULEID_END defines. The + * structure is required for the parser to correctly pick up the values for + * different modules. + */ +#define DBGLOG_MODULEID_START +#define DBGLOG_MODULEID_INF 0 +#define DBGLOG_MODULEID_WMI 1 +#define DBGLOG_MODULEID_MISC 2 +#define DBGLOG_MODULEID_PM 3 +#define DBGLOG_MODULEID_TXRX_MGMTBUF 4 +#define DBGLOG_MODULEID_TXRX_TXBUF 5 +#define DBGLOG_MODULEID_TXRX_RXBUF 6 +#define DBGLOG_MODULEID_WOW 7 +#define DBGLOG_MODULEID_WHAL 8 +#define DBGLOG_MODULEID_DC 9 +#define DBGLOG_MODULEID_CO 10 +#define DBGLOG_MODULEID_RO 11 +#define DBGLOG_MODULEID_CM 12 +#define DBGLOG_MODULEID_MGMT 13 +#define DBGLOG_MODULEID_TMR 14 +#define DBGLOG_MODULEID_BTCOEX 15 +#define DBGLOG_MODULEID_TLPM 2 +#define DBGLOG_MODULEID_END + +#define DBGLOG_NUM_ARGS_OFFSET 30 +#define DBGLOG_NUM_ARGS_MASK 0xC0000000 /* Bit 30-31 */ +#define DBGLOG_NUM_ARGS_MAX 2 /* Upper limit is width of mask */ + +#define DBGLOG_MODULE_LOG_ENABLE_OFFSET 0 +#define DBGLOG_MODULE_LOG_ENABLE_MASK 0x0000FFFF + +#define DBGLOG_REPORTING_ENABLED_OFFSET 16 +#define DBGLOG_REPORTING_ENABLED_MASK 0x00010000 + +#define DBGLOG_TIMESTAMP_RESOLUTION_OFFSET 17 +#define DBGLOG_TIMESTAMP_RESOLUTION_MASK 0x000E0000 + +#define DBGLOG_REPORT_SIZE_OFFSET 20 +#define DBGLOG_REPORT_SIZE_MASK 0x3FF00000 + +#define DBGLOG_LOG_BUFFER_SIZE 1500 +#define DBGLOG_DBGID_DEFINITION_LEN_MAX 90 + +struct dbglog_buf_s +{ + struct dbglog_buf_s *next; + uint8_t *buffer; + uint32_t bufsize; + uint32_t length; + uint32_t count; + uint32_t free; +}; + +struct dbglog_hdr_s +{ + struct dbglog_buf_s *dbuf; + uint32_t dropped; +}; + +struct dbglog_config_s +{ + uint32_t cfgvalid; /* Mask with valid config bits */ + union + { + /* TODO: Take care of endianness */ + struct + { + uint32_t mmask : 16; /* Mask of modules with logging on */ + uint32_t rep : 1; /* Reporting enabled or not */ + uint32_t tsr : 3; /* Time stamp resolution. Def: 1 ms */ + uint32_t size : 10; /* Report size in number of messages */ + uint32_t reserved : 2; + } dbglog_config; + + uint32_t value; + } u; +}; + +#define cfgmmask u.dbglog_config.mmask +#define cfgrep u.dbglog_config.rep +#define cfgtsr u.dbglog_config.tsr +#define cfgsize u.dbglog_config.size +#define cfgvalue u.value + +#ifdef __cplusplus +} +#endif + +#endif /* _DBGLOG_H_ */ diff --git a/platform/mcu/lpc54102/wifi_qca/include/dbglog_id.h b/platform/mcu/lpc54102/wifi_qca/include/dbglog_id.h new file mode 100644 index 0000000000..a5ab32d7ab --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/include/dbglog_id.h @@ -0,0 +1,562 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== + +#ifndef _DBGLOG_ID_H_ +#define _DBGLOG_ID_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * The nomenclature for the debug identifiers is MODULE_DESCRIPTION. + * Please ensure that the definition of any new debugid introduced is captured + * between the _DBGID_DEFINITION_START and + * _DBGID_DEFINITION_END defines. The structure is required for the + * parser to correctly pick up the values for different debug identifiers. + */ + +/* INF debug identifier definitions */ +#define INF_DBGID_DEFINITION_START +#define INF_ASSERTION_FAILED 1 +#define INF_TARGET_ID 2 +#define INF_DBGID_DEFINITION_END + +/* WMI debug identifier definitions */ +#define WMI_DBGID_DEFINITION_START +#define WMI_CMD_RX_XTND_PKT_TOO_SHORT 1 +#define WMI_EXTENDED_CMD_NOT_HANDLED 2 +#define WMI_CMD_RX_PKT_TOO_SHORT 3 +#define WMI_CALLING_WMI_EXTENSION_FN 4 +#define WMI_CMD_NOT_HANDLED 5 +#define WMI_IN_SYNC 6 +#define WMI_TARGET_WMI_SYNC_CMD 7 +#define WMI_SET_SNR_THRESHOLD_PARAMS 8 +#define WMI_SET_RSSI_THRESHOLD_PARAMS 9 +#define WMI_SET_LQ_TRESHOLD_PARAMS 10 +#define WMI_TARGET_CREATE_PSTREAM_CMD 11 +#define WMI_WI_DTM_INUSE 12 +#define WMI_TARGET_DELETE_PSTREAM_CMD 13 +#define WMI_TARGET_IMPLICIT_DELETE_PSTREAM_CMD 14 +#define WMI_TARGET_GET_BIT_RATE_CMD 15 +#define WMI_GET_RATE_MASK_CMD_FIX_RATE_MASK_IS 16 +#define WMI_TARGET_GET_AVAILABLE_CHANNELS_CMD 17 +#define WMI_TARGET_GET_TX_PWR_CMD 18 +#define WMI_FREE_EVBUF_WMIBUF 19 +#define WMI_FREE_EVBUF_DATABUF 20 +#define WMI_FREE_EVBUF_BADFLAG 21 +#define WMI_HTC_RX_ERROR_DATA_PACKET 22 +#define WMI_HTC_RX_SYNC_PAUSING_FOR_MBOX 23 +#define WMI_INCORRECT_WMI_DATA_HDR_DROPPING_PKT 24 +#define WMI_SENDING_READY_EVENT 25 +#define WMI_SETPOWER_MDOE_TO_MAXPERF 26 +#define WMI_SETPOWER_MDOE_TO_REC 27 +#define WMI_BSSINFO_EVENT_FROM 28 +#define WMI_TARGET_GET_STATS_CMD 29 +#define WMI_SENDING_SCAN_COMPLETE_EVENT 30 +#define WMI_SENDING_RSSI_INDB_THRESHOLD_EVENT 31 +#define WMI_SENDING_RSSI_INDBM_THRESHOLD_EVENT 32 +#define WMI_SENDING_LINK_QUALITY_THRESHOLD_EVENT 33 +#define WMI_SENDING_ERROR_REPORT_EVENT 34 +#define WMI_SENDING_CAC_EVENT 35 +#define WMI_TARGET_GET_ROAM_TABLE_CMD 36 +#define WMI_TARGET_GET_ROAM_DATA_CMD 37 +#define WMI_SENDING_GPIO_INTR_EVENT 38 +#define WMI_SENDING_GPIO_ACK_EVENT 39 +#define WMI_SENDING_GPIO_DATA_EVENT 40 +#define WMI_CMD_RX 41 +#define WMI_CMD_RX_XTND 42 +#define WMI_EVENT_SEND 43 +#define WMI_EVENT_SEND_XTND 44 +#define WMI_CMD_PARAMS_DUMP_START 45 +#define WMI_CMD_PARAMS_DUMP_END 46 +#define WMI_CMD_PARAMS 47 +#define WMI_DBGID_DEFINITION_END + +/* MISC debug identifier definitions */ +#define MISC_DBGID_DEFINITION_START +#define MISC_WLAN_SCHEDULER_EVENT_REGISTER_ERROR 1 +#define MISC_DBGID_DEFINITION_END + +/* TXRX debug identifier definitions */ +#define TXRX_TXBUF_DBGID_DEFINITION_START +#define TXRX_TXBUF_ALLOCATE_BUF 1 +#define TXRX_TXBUF_QUEUE_BUF_TO_MBOX 2 +#define TXRX_TXBUF_QUEUE_BUF_TO_TXQ 3 +#define TXRX_TXBUF_TXQ_DEPTH 4 +#define TXRX_TXBUF_IBSS_QUEUE_TO_SFQ 5 +#define TXRX_TXBUF_IBSS_QUEUE_TO_TXQ_FRM_SFQ 6 +#define TXRX_TXBUF_INITIALIZE_TIMER 7 +#define TXRX_TXBUF_ARM_TIMER 8 +#define TXRX_TXBUF_DISARM_TIMER 9 +#define TXRX_TXBUF_UNINITIALIZE_TIMER 10 +#define TXRX_TXBUF_DBGID_DEFINITION_END + +#define TXRX_RXBUF_DBGID_DEFINITION_START +#define TXRX_RXBUF_ALLOCATE_BUF 1 +#define TXRX_RXBUF_QUEUE_TO_HOST 2 +#define TXRX_RXBUF_QUEUE_TO_WLAN 3 +#define TXRX_RXBUF_ZERO_LEN_BUF 4 +#define TXRX_RXBUF_QUEUE_TO_HOST_LASTBUF_IN_RXCHAIN 5 +#define TXRX_RXBUF_LASTBUF_IN_RXCHAIN_ZEROBUF 6 +#define TXRX_RXBUF_QUEUE_EMPTY_QUEUE_TO_WLAN 7 +#define TXRX_RXBUF_SEND_TO_RECV_MGMT 8 +#define TXRX_RXBUF_SEND_TO_IEEE_LAYER 9 +#define TXRX_RXBUF_REQUEUE_ERROR 10 +#define TXRX_RXBUF_DBGID_DEFINITION_END + +#define TXRX_MGMTBUF_DBGID_DEFINITION_START +#define TXRX_MGMTBUF_ALLOCATE_BUF 1 +#define TXRX_MGMTBUF_ALLOCATE_SM_BUF 2 +#define TXRX_MGMTBUF_ALLOCATE_RMBUF 3 +#define TXRX_MGMTBUF_GET_BUF 4 +#define TXRX_MGMTBUF_GET_SM_BUF 5 +#define TXRX_MGMTBUF_QUEUE_BUF_TO_TXQ 6 +#define TXRX_MGMTBUF_REAPED_BUF 7 +#define TXRX_MGMTBUF_REAPED_SM_BUF 8 +#define TXRX_MGMTBUF_WAIT_FOR_TXQ_DRAIN 9 +#define TXRX_MGMTBUF_WAIT_FOR_TXQ_SFQ_DRAIN 10 +#define TXRX_MGMTBUF_ENQUEUE_INTO_DATA_SFQ 11 +#define TXRX_MGMTBUF_DEQUEUE_FROM_DATA_SFQ 12 +#define TXRX_MGMTBUF_PAUSE_DATA_TXQ 13 +#define TXRX_MGMTBUF_RESUME_DATA_TXQ 14 +#define TXRX_MGMTBUF_WAIT_FORTXQ_DRAIN_TIMEOUT 15 +#define TXRX_MGMTBUF_DRAINQ 16 +#define TXRX_MGMTBUF_INDICATE_Q_DRAINED 17 +#define TXRX_MGMTBUF_ENQUEUE_INTO_HW_SFQ 18 +#define TXRX_MGMTBUF_DEQUEUE_FROM_HW_SFQ 19 +#define TXRX_MGMTBUF_PAUSE_HW_TXQ 20 +#define TXRX_MGMTBUF_RESUME_HW_TXQ 21 +#define TXRX_MGMTBUF_TEAR_DOWN_BA 22 +#define TXRX_MGMTBUF_PROCESS_ADDBA_REQ 23 +#define TXRX_MGMTBUF_PROCESS_DELBA 24 +#define TXRX_MGMTBUF_PERFORM_BA 25 +#define TXRX_MGMTBUF_DBGID_DEFINITION_END + +/* PM (Power Module) debug identifier definitions */ +#define PM_DBGID_DEFINITION_START +#define PM_INIT 1 +#define PM_ENABLE 2 +#define PM_SET_STATE 3 +#define PM_SET_POWERMODE 4 +#define PM_CONN_NOTIFY 5 +#define PM_REF_COUNT_NEGATIVE 6 +#define PM_INFRA_STA_APSD_ENABLE 7 +#define PM_INFRA_STA_UPDATE_APSD_STATE 8 +#define PM_CHAN_OP_REQ 9 +#define PM_SET_MY_BEACON_POLICY 10 +#define PM_SET_ALL_BEACON_POLICY 11 +#define PM_INFRA_STA_SET_PM_PARAMS1 12 +#define PM_INFRA_STA_SET_PM_PARAMS2 13 +#define PM_ADHOC_SET_PM_CAPS_FAIL 14 +#define PM_ADHOC_UNKNOWN_IBSS_ATTRIB_ID 15 +#define PM_ADHOC_SET_PM_PARAMS 16 +#define PM_ADHOC_STATE1 18 +#define PM_ADHOC_STATE2 19 +#define PM_ADHOC_CONN_MAP 20 +#define PM_FAKE_SLEEP 21 +#define PM_AP_STATE1 22 +#define PM_AP_SET_PM_PARAMS 23 +#define PM_DBGID_DEFINITION_END + +/* Wake on Wireless debug identifier definitions */ +#define WOW_DBGID_DEFINITION_START +#define WOW_INIT 1 +#define WOW_GET_CONFIG_DSET 2 +#define WOW_NO_CONFIG_DSET 3 +#define WOW_INVALID_CONFIG_DSET 4 +#define WOW_USE_DEFAULT_CONFIG 5 +#define WOW_SETUP_GPIO 6 +#define WOW_INIT_DONE 7 +#define WOW_SET_GPIO_PIN 8 +#define WOW_CLEAR_GPIO_PIN 9 +#define WOW_SET_WOW_MODE_CMD 10 +#define WOW_SET_HOST_MODE_CMD 11 +#define WOW_ADD_WOW_PATTERN_CMD 12 +#define WOW_NEW_WOW_PATTERN_AT_INDEX 13 +#define WOW_DEL_WOW_PATTERN_CMD 14 +#define WOW_LIST_CONTAINS_PATTERNS 15 +#define WOW_GET_WOW_LIST_CMD 16 +#define WOW_INVALID_FILTER_ID 17 +#define WOW_INVALID_FILTER_LISTID 18 +#define WOW_NO_VALID_FILTER_AT_ID 19 +#define WOW_NO_VALID_LIST_AT_ID 20 +#define WOW_NUM_PATTERNS_EXCEEDED 21 +#define WOW_NUM_LISTS_EXCEEDED 22 +#define WOW_GET_WOW_STATS 23 +#define WOW_CLEAR_WOW_STATS 24 +#define WOW_WAKEUP_HOST 25 +#define WOW_EVENT_WAKEUP_HOST 26 +#define WOW_EVENT_DISCARD 27 +#define WOW_PATTERN_MATCH 28 +#define WOW_PATTERN_NOT_MATCH 29 +#define WOW_PATTERN_NOT_MATCH_OFFSET 30 +#define WOW_DISABLED_HOST_ASLEEP 31 +#define WOW_ENABLED_HOST_ASLEEP_NO_PATTERNS 32 +#define WOW_ENABLED_HOST_ASLEEP_NO_MATCH_FOUND 33 +#define WOW_DBGID_DEFINITION_END + +/* WHAL debug identifier definitions */ +#define WHAL_DBGID_DEFINITION_START +#define WHAL_ERROR_ANI_CONTROL 1 +#define WHAL_ERROR_CHIP_TEST1 2 +#define WHAL_ERROR_CHIP_TEST2 3 +#define WHAL_ERROR_EEPROM_CHECKSUM 4 +#define WHAL_ERROR_EEPROM_MACADDR 5 +#define WHAL_ERROR_INTERRUPT_HIU 6 +#define WHAL_ERROR_KEYCACHE_RESET 7 +#define WHAL_ERROR_KEYCACHE_SET 8 +#define WHAL_ERROR_KEYCACHE_TYPE 9 +#define WHAL_ERROR_KEYCACHE_TKIPENTRY 10 +#define WHAL_ERROR_KEYCACHE_WEPLENGTH 11 +#define WHAL_ERROR_PHY_INVALID_CHANNEL 12 +#define WHAL_ERROR_POWER_AWAKE 13 +#define WHAL_ERROR_POWER_SET 14 +#define WHAL_ERROR_RECV_STOPDMA 15 +#define WHAL_ERROR_RECV_STOPPCU 16 +#define WHAL_ERROR_RESET_CHANNF1 17 +#define WHAL_ERROR_RESET_CHANNF2 18 +#define WHAL_ERROR_RESET_PM 19 +#define WHAL_ERROR_RESET_OFFSETCAL 20 +#define WHAL_ERROR_RESET_RFGRANT 21 +#define WHAL_ERROR_RESET_RXFRAME 22 +#define WHAL_ERROR_RESET_STOPDMA 23 +#define WHAL_ERROR_RESET_RECOVER 24 +#define WHAL_ERROR_XMIT_COMPUTE 25 +#define WHAL_ERROR_XMIT_NOQUEUE 26 +#define WHAL_ERROR_XMIT_ACTIVEQUEUE 27 +#define WHAL_ERROR_XMIT_BADTYPE 28 +#define WHAL_ERROR_XMIT_STOPDMA 29 +#define WHAL_ERROR_INTERRUPT_BB_PANIC 30 +#define WHAL_ERROR_RESET_TXIQCAL 31 +#define WHAL_ERROR_PAPRD_MAXGAIN_ABOVE_WINDOW 32 +#define WHAL_DBGID_DEFINITION_END + +/* DC debug identifier definitions */ +#define DC_DBGID_DEFINITION_START +#define DC_SCAN_CHAN_START 1 +#define DC_SCAN_CHAN_FINISH 2 +#define DC_BEACON_RECEIVE7 3 +#define DC_SSID_PROBE_CB 4 +#define DC_SEND_NEXT_SSID_PROBE 5 +#define DC_START_SEARCH 6 +#define DC_CANCEL_SEARCH_CB 7 +#define DC_STOP_SEARCH 8 +#define DC_END_SEARCH 9 +#define DC_MIN_CHDWELL_TIMEOUT 10 +#define DC_START_SEARCH_CANCELED 11 +#define DC_SET_POWER_MODE 12 +#define DC_INIT 13 +#define DC_SEARCH_OPPORTUNITY 14 +#define DC_RECEIVED_ANY_BEACON 15 +#define DC_RECEIVED_MY_BEACON 16 +#define DC_PROFILE_IS_ADHOC_BUT_BSS_IS_INFRA 17 +#define DC_PS_ENABLED_BUT_ATHEROS_IE_ABSENT 18 +#define DC_BSS_ADHOC_CHANNEL_NOT_ALLOWED 19 +#define DC_SET_BEACON_UPDATE 20 +#define DC_BEACON_UPDATE_COMPLETE 21 +#define DC_END_SEARCH_BEACON_UPDATE_COMP_CB 22 +#define DC_BSSINFO_EVENT_DROPPED 23 +#define DC_IEEEPS_ENABLED_BUT_ATIM_ABSENT 24 +#define DC_DBGID_DEFINITION_END + +/* CO debug identifier definitions */ +#define CO_DBGID_DEFINITION_START +#define CO_INIT 1 +#define CO_ACQUIRE_LOCK 2 +#define CO_START_OP1 3 +#define CO_START_OP2 4 +#define CO_DRAIN_TX_COMPLETE_CB 5 +#define CO_CHANGE_CHANNEL_CB 6 +#define CO_RETURN_TO_HOME_CHANNEL 7 +#define CO_FINISH_OP_TIMEOUT 8 +#define CO_OP_END 9 +#define CO_CANCEL_OP 10 +#define CO_CHANGE_CHANNEL 11 +#define CO_RELEASE_LOCK 12 +#define CO_CHANGE_STATE 13 +#define CO_DBGID_DEFINITION_END + +/* RO debug identifier definitions */ +#define RO_DBGID_DEFINITION_START +#define RO_REFRESH_ROAM_TABLE 1 +#define RO_UPDATE_ROAM_CANDIDATE 2 +#define RO_UPDATE_ROAM_CANDIDATE_CB 3 +#define RO_UPDATE_ROAM_CANDIDATE_FINISH 4 +#define RO_REFRESH_ROAM_TABLE_DONE 5 +#define RO_PERIODIC_SEARCH_CB 6 +#define RO_PERIODIC_SEARCH_TIMEOUT 7 +#define RO_INIT 8 +#define RO_BMISS_STATE1 9 +#define RO_BMISS_STATE2 10 +#define RO_SET_PERIODIC_SEARCH_ENABLE 11 +#define RO_SET_PERIODIC_SEARCH_DISABLE 12 +#define RO_ENABLE_SQ_THRESHOLD 13 +#define RO_DISABLE_SQ_THRESHOLD 14 +#define RO_ADD_BSS_TO_ROAM_TABLE 15 +#define RO_SET_PERIODIC_SEARCH_MODE 16 +#define RO_CONFIGURE_SQ_THRESHOLD1 17 +#define RO_CONFIGURE_SQ_THRESHOLD2 18 +#define RO_CONFIGURE_SQ_PARAMS 19 +#define RO_LOW_SIGNAL_QUALITY_EVENT 20 +#define RO_HIGH_SIGNAL_QUALITY_EVENT 21 +#define RO_REMOVE_BSS_FROM_ROAM_TABLE 22 +#define RO_UPDATE_CONNECTION_STATE_METRIC 23 +#define RO_DBGID_DEFINITION_END + +/* CM debug identifier definitions */ +#define CM_DBGID_DEFINITION_START +#define CM_INITIATE_HANDOFF 1 +#define CM_INITIATE_HANDOFF_CB 2 +#define CM_CONNECT_EVENT 3 +#define CM_DISCONNECT_EVENT 4 +#define CM_INIT 5 +#define CM_HANDOFF_SOURCE 6 +#define CM_SET_HANDOFF_TRIGGERS 7 +#define CM_CONNECT_REQUEST 8 +#define CM_CONNECT_REQUEST_CB 9 +#define CM_CONTINUE_SCAN_CB 10 +#define CM_DBGID_DEFINITION_END + +/* mgmt debug identifier definitions */ +#define MGMT_DBGID_DEFINITION_START +#define KEYMGMT_CONNECTION_INIT 1 +#define KEYMGMT_CONNECTION_COMPLETE 2 +#define KEYMGMT_CONNECTION_CLOSE 3 +#define KEYMGMT_ADD_KEY 4 +#define MLME_NEW_STATE 5 +#define MLME_CONN_INIT 6 +#define MLME_CONN_COMPLETE 7 +#define MLME_CONN_CLOSE 8 +#define MGMT_DBGID_DEFINITION_END + +/* TMR debug identifier definitions */ +#define TMR_DBGID_DEFINITION_START +#define TMR_HANG_DETECTED 1 +#define TMR_WDT_TRIGGERED 2 +#define TMR_WDT_RESET 3 +#define TMR_HANDLER_ENTRY 4 +#define TMR_HANDLER_EXIT 5 +#define TMR_SAVED_START 6 +#define TMR_SAVED_END 7 +#define TMR_DBGID_DEFINITION_END + +/* BTCOEX debug identifier definitions */ +#define BTCOEX_DBGID_DEFINITION_START +#define BTCOEX_STATUS_CMD 1 +#define BTCOEX_PARAMS_CMD 2 +#define BTCOEX_ANT_CONFIG 3 +#define BTCOEX_COLOCATED_BT_DEVICE 4 +#define BTCOEX_CLOSE_RANGE_SCO_ON 5 +#define BTCOEX_CLOSE_RANGE_SCO_OFF 6 +#define BTCOEX_CLOSE_RANGE_A2DP_ON 7 +#define BTCOEX_CLOSE_RANGE_A2DP_OFF 8 +#define BTCOEX_A2DP_PROTECT_ON 9 +#define BTCOEX_A2DP_PROTECT_OFF 10 +#define BTCOEX_SCO_PROTECT_ON 11 +#define BTCOEX_SCO_PROTECT_OFF 12 +#define BTCOEX_CLOSE_RANGE_DETECTOR_START 13 +#define BTCOEX_CLOSE_RANGE_DETECTOR_STOP 14 +#define BTCOEX_CLOSE_RANGE_TOGGLE 15 +#define BTCOEX_CLOSE_RANGE_TOGGLE_RSSI_LRCNT 16 +#define BTCOEX_CLOSE_RANGE_RSSI_THRESH 17 +#define BTCOEX_CLOSE_RANGE_LOW_RATE_THRESH 18 +#define BTCOEX_PTA_PRI_INTR_HANDLER 19 +#define BTCOEX_PSPOLL_QUEUED 20 +#define BTCOEX_PSPOLL_COMPLETE 21 +#define BTCOEX_DBG_PM_AWAKE 22 +#define BTCOEX_DBG_PM_SLEEP 23 +#define BTCOEX_DBG_SCO_COEX_ON 24 +#define BTCOEX_SCO_DATARECEIVE 25 +#define BTCOEX_INTR_INIT 26 +#define BTCOEX_PTA_PRI_DIFF 27 +#define BTCOEX_TIM_NOTIFICATION 28 +#define BTCOEX_SCO_WAKEUP_ON_DATA 29 +#define BTCOEX_SCO_SLEEP 30 +#define BTCOEX_SET_WEIGHTS 31 +#define BTCOEX_SCO_DATARECEIVE_LATENCY_VAL 32 +#define BTCOEX_SCO_MEASURE_TIME_DIFF 33 +#define BTCOEX_SET_EOL_VAL 34 +#define BTCOEX_OPT_DETECT_HANDLER 35 +#define BTCOEX_SCO_TOGGLE_STATE 36 +#define BTCOEX_SCO_STOMP 37 +#define BTCOEX_NULL_COMP_CALLBACK 38 +#define BTCOEX_RX_INCOMING 39 +#define BTCOEX_RX_INCOMING_CTL 40 +#define BTCOEX_RX_INCOMING_MGMT 41 +#define BTCOEX_RX_INCOMING_DATA 42 +#define BTCOEX_RTS_RECEPTION 43 +#define BTCOEX_FRAME_PRI_LOW_RATE_THRES 44 +#define BTCOEX_PM_FAKE_SLEEP 45 +#define BTCOEX_ACL_COEX_STATUS 46 +#define BTCOEX_ACL_COEX_DETECTION 47 +#define BTCOEX_A2DP_COEX_STATUS 48 +#define BTCOEX_SCO_STATUS 49 +#define BTCOEX_WAKEUP_ON_DATA 50 +#define BTCOEX_DATARECEIVE 51 +#define BTCOEX_GET_MAX_AGGR_SIZE 53 +#define BTCOEX_MAX_AGGR_AVAIL_TIME 54 +#define BTCOEX_DBG_WBTIMER_INTR 55 +#define BTCOEX_DBG_SCO_SYNC 57 +#define BTCOEX_UPLINK_QUEUED_RATE 59 +#define BTCOEX_DBG_UPLINK_ENABLE_EOL 60 +#define BTCOEX_UPLINK_FRAME_DURATION 61 +#define BTCOEX_UPLINK_SET_EOL 62 +#define BTCOEX_DBG_EOL_EXPIRED 63 +#define BTCOEX_DBG_DATA_COMPLETE 64 +#define BTCOEX_UPLINK_QUEUED_TIMESTAMP 65 +#define BTCOEX_DBG_DATA_COMPLETE_TIME 66 +#define BTCOEX_DBG_A2DP_ROLE_IS_SLAVE 67 +#define BTCOEX_DBG_A2DP_ROLE_IS_MASTER 68 +#define BTCOEX_DBG_UPLINK_SEQ_NUM 69 +#define BTCOEX_UPLINK_AGGR_SEQ 70 +#define BTCOEX_DBG_TX_COMP_SEQ_NO 71 +#define BTCOEX_DBG_MAX_AGGR_PAUSE_STATE 72 +#define BTCOEX_DBG_ACL_TRAFFIC 73 +#define BTCOEX_CURR_AGGR_PROP 74 +#define BTCOEX_DBG_SCO_GET_PER_TIME_DIFF 75 +#define BTCOEX_PSPOLL_PROCESS 76 +#define BTCOEX_RETURN_FROM_MAC 77 +#define BTCOEX_FREED_REQUEUED_CNT 78 +#define BTCOEX_DBG_TOGGLE_LOW_RATES 79 +#define BTCOEX_MAC_GOES_TO_SLEEP 80 +#define BTCOEX_DBG_A2DP_NO_SYNC 81 +#define BTCOEX_RETURN_FROM_MAC_HOLD_Q_INFO 82 +#define BTCOEX_RETURN_FROM_MAC_AC 83 +#define BTCOEX_DBG_DTIM_RECV 84 +#define BTCOEX_IS_PRE_UPDATE 86 +#define BTCOEX_ENQUEUED_BIT_MAP 87 +#define BTCOEX_TX_COMPLETE_FIRST_DESC_STATS 88 +#define BTCOEX_UPLINK_DESC 89 +#define BTCOEX_SCO_GET_PER_FIRST_FRM_TIMESTAMP 90 +#define BTCOEX_DBG_RECV_ACK 94 +#define BTCOEX_DBG_ADDBA_INDICATION 95 +#define BTCOEX_TX_COMPLETE_EOL_FAILED 96 +#define BTCOEX_DBG_A2DP_USAGE_COMPLETE 97 +#define BTCOEX_DBG_A2DP_STOMP_FOR_BCN_HANDLER 98 +#define BTCOEX_DBG_A2DP_SYNC_INTR 99 +#define BTCOEX_DBG_A2DP_STOMP_FOR_BCN_RECEPTION 100 +#define BTCOEX_FORM_AGGR_CURR_AGGR 101 +#define BTCOEX_DBG_TOGGLE_A2DP_BURST_CNT 102 +#define BTCOEX_DBG_BT_TRAFFIC 103 +#define BTCOEX_DBG_STOMP_BT_TRAFFIC 104 +#define BTCOEX_RECV_NULL 105 +#define BTCOEX_DBG_A2DP_MASTER_BT_END 106 +#define BTCOEX_DBG_A2DP_BT_START 107 +#define BTCOEX_DBG_A2DP_SLAVE_BT_END 108 +#define BTCOEX_DBG_A2DP_STOMP_BT 109 +#define BTCOEX_DBG_GO_TO_SLEEP 110 +#define BTCOEX_DBG_A2DP_PKT 111 +#define BTCOEX_DBG_A2DP_PSPOLL_DATA_RECV 112 +#define BTCOEX_DBG_A2DP_NULL 113 +#define BTCOEX_DBG_UPLINK_DATA 114 +#define BTCOEX_DBG_A2DP_STOMP_LOW_PRIO_NULL 115 +#define BTCOEX_DBG_ADD_BA_RESP_TIMEOUT 116 +#define BTCOEX_DBG_TXQ_STATE 117 +#define BTCOEX_DBG_ALLOW_SCAN 118 +#define BTCOEX_DBG_SCAN_REQUEST 119 +#define BTCOEX_A2DP_SLEEP 127 +#define BTCOEX_DBG_DATA_ACTIV_TIMEOUT 128 +#define BTCOEX_DBG_SWITCH_TO_PSPOLL_ON_MODE 129 +#define BTCOEX_DBG_SWITCH_TO_PSPOLL_OFF_MODE 130 +#define BTCOEX_DATARECEIVE_AGGR 131 +#define BTCOEX_DBG_DATA_RECV_SLEEPING_PENDING 132 +#define BTCOEX_DBG_DATARESP_TIMEOUT 133 +#define BTCOEX_BDG_BMISS 134 +#define BTCOEX_DBG_DATA_RECV_WAKEUP_TIM 135 +#define BTCOEX_DBG_SECOND_BMISS 136 +#define BTCOEX_DBG_SET_WLAN_STATE 138 +#define BTCOEX_BDG_FIRST_BMISS 139 +#define BTCOEX_DBG_A2DP_CHAN_OP 140 +#define BTCOEX_DBG_A2DP_INTR 141 +#define BTCOEX_DBG_BT_INQUIRY 142 +#define BTCOEX_DBG_BT_INQUIRY_DATA_FETCH 143 +#define BTCOEX_DBG_POST_INQUIRY_FINISH 144 +#define BTCOEX_DBG_SCO_OPT_MODE_TIMER_HANDLER 145 +#define BTCOEX_DBG_NULL_FRAME_SLEEP 146 +#define BTCOEX_DBG_NULL_FRAME_AWAKE 147 +#define BTCOEX_DBG_SET_AGGR_SIZE 152 +#define BTCOEX_DBG_TEAR_BA_TIMEOUT 153 +#define BTCOEX_DBG_MGMT_FRAME_SEQ_NO 154 +#define BTCOEX_DBG_SCO_STOMP_HIGH_PRI 155 +#define BTCOEX_DBG_COLOCATED_BT_DEV 156 +#define BTCOEX_DBG_FE_ANT_TYPE 157 +#define BTCOEX_DBG_BT_INQUIRY_CMD 158 +#define BTCOEX_DBG_SCO_CONFIG 159 +#define BTCOEX_DBG_SCO_PSPOLL_CONFIG 160 +#define BTCOEX_DBG_SCO_OPTMODE_CONFIG 161 +#define BTCOEX_DBG_A2DP_CONFIG 162 +#define BTCOEX_DBG_A2DP_PSPOLL_CONFIG 163 +#define BTCOEX_DBG_A2DP_OPTMODE_CONFIG 164 +#define BTCOEX_DBG_ACLCOEX_CONFIG 165 +#define BTCOEX_DBG_ACLCOEX_PSPOLL_CONFIG 166 +#define BTCOEX_DBG_ACLCOEX_OPTMODE_CONFIG 167 +#define BTCOEX_DBG_DEBUG_CMD 168 +#define BTCOEX_DBG_SET_BT_OPERATING_STATUS 169 +#define BTCOEX_DBG_GET_CONFIG 170 +#define BTCOEX_DBG_GET_STATS 171 +#define BTCOEX_DBG_BT_OPERATING_STATUS 172 +#define BTCOEX_DBG_PERFORM_RECONNECT 173 +#define BTCOEX_DBG_ACL_WLAN_MED 175 +#define BTCOEX_DBG_ACL_BT_MED 176 +#define BTCOEX_DBG_WLAN_CONNECT 177 +#define BTCOEX_DBG_A2DP_DUAL_START 178 +#define BTCOEX_DBG_PMAWAKE_NOTIFY 179 +#define BTCOEX_DBG_BEACON_SCAN_ENABLE 180 +#define BTCOEX_DBG_BEACON_SCAN_DISABLE 181 +#define BTCOEX_DBG_RX_NOTIFY 182 +#define BTCOEX_SCO_GET_PER_SECOND_FRM_TIMESTAMP 183 +#define BTCOEX_DBG_TXQ_DETAILS 184 +#define BTCOEX_DBG_SCO_STOMP_LOW_PRI 185 +#define BTCOEX_DBG_A2DP_FORCE_SCAN 186 +#define BTCOEX_DBG_DTIM_STOMP_COMP 187 +#define BTCOEX_ACL_PRESENCE_TIMER 188 +#define BTCOEX_DBGID_DEFINITION_END + +#define TLPM_DBGID_DEFINITION_START +#define TLPM_INIT 1 +#define TLPM_FILTER_POWER_STATE 2 +#define TLPM_NOTIFY_NOT_IDLE 3 +#define TLPM_TIMEOUT_IDLE_HANDLER 4 +#define TLPM_TIMEOUT_WAKEUP_HANDLER 5 +#define TLPM_WAKEUP_SIGNAL_HANDLER 6 +#define TLPM_UNEXPECTED_GPIO_INTR_ERROR 7 +#define TLPM_BREAK_ON_NOT_RECEIVED_ERROR 8 +#define TLPM_BREAK_OFF_NOT_RECIVED_ERROR 9 +#define TLPM_ACK_GPIO_INTR 10 +#define TLPM_ON 11 +#define TLPM_OFF 12 +#define TLPM_WAKEUP_FROM_HOST 13 +#define TLPM_WAKEUP_FROM_BT 14 +#define TLPM_TX_BREAK_RECIVED 15 +#define TLPM_IDLE_TIMER_NOT_RUNNING 16 +#define TLPM_DBGID_DEFINITION_END + +#ifdef __cplusplus +} +#endif + +#endif /* _DBGLOG_ID_H_ */ diff --git a/platform/mcu/lpc54102/wifi_qca/include/htc.h b/platform/mcu/lpc54102/wifi_qca/include/htc.h new file mode 100644 index 0000000000..d875a30f7b --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/include/htc.h @@ -0,0 +1,241 @@ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== + +#ifndef __HTC_H__ +#define __HTC_H__ + +#define A_OFFSETOF(type, field) (int)(&(((type *)0)->field)) + +#define ASSEMBLE_UNALIGNED_UINT16(p, highbyte, lowbyte) \ + (((uint16_t)(((uint8_t *)(p))[(highbyte)])) << 8 | (uint16_t)(((uint8_t *)(p))[(lowbyte)])) + +/* alignment independent macros (little-endian) to fetch UINT16s or UINT8s from a + * structure using only the type and field name. + * Use these macros if there is the potential for unaligned buffer accesses. */ +#define A_GET_UINT16_FIELD(p, type, field) \ + ASSEMBLE_UNALIGNED_UINT16(p, A_OFFSETOF(type, field) + 1, A_OFFSETOF(type, field)) + +#define A_SET_UINT16_FIELD(p, type, field, value) \ + \ +{ \ + ((uint8_t *)(p))[A_OFFSETOF(type, field)] = (uint8_t)(value); \ + ((uint8_t *)(p))[A_OFFSETOF(type, field) + 1] = (uint8_t)((value) >> 8); \ + \ +} + +#define A_GET_UINT8_FIELD(p, type, field) ((uint8_t *)(p))[A_OFFSETOF(type, field)] + +#define A_SET_UINT8_FIELD(p, type, field, value) ((uint8_t *)(p))[A_OFFSETOF(type, field)] = (value) + +/****** DANGER DANGER *************** + * + * The frame header length and message formats defined herein were + * selected to accommodate optimal alignment for target processing. This reduces code + * size and improves performance. + * + * Any changes to the header length may alter the alignment and cause exceptions + * on the target. When adding to the message structures insure that fields are + * properly aligned. + * + */ + +/* HTC frame header */ +typedef PREPACK struct _HTC_FRAME_HDR +{ + /* do not remove or re-arrange these fields, these are minimally required + * to take advantage of 4-byte lookaheads in some hardware implementations */ + uint8_t EndpointID FIELD_PACKED; + uint8_t Flags FIELD_PACKED; + uint16_t PayloadLen FIELD_PACKED; /* length of data (including trailer) that follows the header */ + + /***** end of 4-byte lookahead ****/ + + uint8_t ControlBytes[2] FIELD_PACKED; + + /* message payload starts after the header */ + +} POSTPACK HTC_FRAME_HDR; + +/* frame header flags */ + +/* send direction */ +#define HTC_FLAGS_NEED_CREDIT_UPDATE (1 << 0) +#define HTC_FLAGS_SEND_BUNDLE (1 << 1) /* start or part of bundle */ +#define HTC_FLAGS_SEND_TRAILER (1 << 2) /* send trailer data */ + +/* receive direction */ +#define HTC_FLAGS_RECV_UNUSED_0 (1 << 0) /* bit 0 unused */ +#define HTC_FLAGS_RECV_TRAILER (1 << 1) /* bit 1 trailer data present */ +#define HTC_FLAGS_RECV_UNUSED_2 (1 << 0) /* bit 2 unused */ +#define HTC_FLAGS_RECV_UNUSED_3 (1 << 0) /* bit 3 unused */ +#define HTC_FLAGS_RECV_BUNDLE_CNT_MASK (0xF0) /* bits 7..4 */ +#define HTC_FLAGS_RECV_BUNDLE_CNT_SHIFT 4 + +#define HTC_HDR_LENGTH (sizeof(HTC_FRAME_HDR)) +#define HTC_MAX_TRAILER_LENGTH 255 +#define HTC_MAX_PAYLOAD_LENGTH (4096 - sizeof(HTC_FRAME_HDR)) + +/* HTC control message IDs */ + +#define HTC_MSG_READY_ID 1 +#define HTC_MSG_CONNECT_SERVICE_ID 2 +#define HTC_MSG_CONNECT_SERVICE_RESPONSE_ID 3 +#define HTC_MSG_SETUP_COMPLETE_ID 4 +#define HTC_MSG_SETUP_COMPLETE_EX_ID 5 + +#define HTC_MAX_CONTROL_MESSAGE_LENGTH 256 + +/* base message ID header */ +typedef PREPACK struct +{ + uint16_t MessageID FIELD_PACKED; +} POSTPACK HTC_UNKNOWN_MSG; + +/* HTC ready message + * direction : target-to-host */ +typedef PREPACK struct +{ + uint16_t MessageID FIELD_PACKED; /* ID */ + uint16_t CreditCount FIELD_PACKED; /* number of credits the target can offer */ + uint16_t CreditSize FIELD_PACKED; /* size of each credit */ + uint8_t MaxEndpoints FIELD_PACKED; /* maximum number of endpoints the target has resources for */ + uint8_t _Pad1 FIELD_PACKED; +} POSTPACK HTC_READY_MSG; + +/* extended HTC ready message */ +typedef PREPACK struct +{ + HTC_READY_MSG Version2_0_Info FIELD_PACKED; /* legacy version 2.0 information at the front... */ + /* extended information */ + uint8_t HTCVersion FIELD_PACKED; + uint8_t MaxMsgsPerHTCBundle FIELD_PACKED; +} POSTPACK HTC_READY_EX_MSG; + +#define HTC_VERSION_2P0 0x00 +#define HTC_VERSION_2P1 0x01 /* HTC 2.1 */ + +#define HTC_SERVICE_META_DATA_MAX_LENGTH 128 + +/* connect service + * direction : host-to-target */ +typedef PREPACK struct +{ + uint16_t MessageID FIELD_PACKED; + uint16_t ServiceID FIELD_PACKED; /* service ID of the service to connect to */ + uint16_t ConnectionFlags FIELD_PACKED; /* connection flags */ + +#define HTC_CONNECT_FLAGS_REDUCE_CREDIT_DRIBBLE \ + (1 << 2) /* reduce credit dribbling when \ + the host needs credits */ +#define HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_MASK (0x3) +#define HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_ONE_FOURTH 0x0 +#define HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_ONE_HALF 0x1 +#define HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_THREE_FOURTHS 0x2 +#define HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_UNITY 0x3 + + uint8_t ServiceMetaLength; /* length of meta data that follows */ + uint8_t _Pad1; + + /* service-specific meta data starts after the header */ + +} POSTPACK HTC_CONNECT_SERVICE_MSG; + +/* connect response + * direction : target-to-host */ +typedef PREPACK struct +{ + uint16_t MessageID FIELD_PACKED; + uint16_t ServiceID FIELD_PACKED; /* service ID that the connection request was made */ + uint8_t Status FIELD_PACKED; /* service connection status */ + uint8_t EndpointID FIELD_PACKED; /* assigned endpoint ID */ + uint16_t MaxMsgSize FIELD_PACKED; /* maximum expected message size on this endpoint */ + uint8_t ServiceMetaLength FIELD_PACKED; /* length of meta data that follows */ + uint8_t _Pad1 FIELD_PACKED; + + /* service-specific meta data starts after the header */ + +} POSTPACK HTC_CONNECT_SERVICE_RESPONSE_MSG; + +typedef PREPACK struct +{ + uint16_t MessageID FIELD_PACKED; + /* currently, no other fields */ +} POSTPACK HTC_SETUP_COMPLETE_MSG; + +/* extended setup completion message */ +typedef PREPACK struct +{ + uint16_t MessageID FIELD_PACKED; + uint32_t SetupFlags FIELD_PACKED; + uint8_t MaxMsgsPerBundledRecv FIELD_PACKED; + uint8_t Rsvd[3] FIELD_PACKED; +} POSTPACK HTC_SETUP_COMPLETE_EX_MSG; + +#define HTC_SETUP_COMPLETE_FLAGS_ENABLE_BUNDLE_RECV (1 << 0) + +/* connect response status codes */ +#define HTC_SERVICE_SUCCESS 0 /* success */ +#define HTC_SERVICE_NOT_FOUND 1 /* service could not be found */ +#define HTC_SERVICE_FAILED 2 /* specific service failed the connect */ +#define HTC_SERVICE_NO_RESOURCES 3 /* no resources (i.e. no more endpoints) */ +#define HTC_SERVICE_NO_MORE_EP \ + 4 /* specific service is not allowing any more \ + endpoints */ + +/* report record IDs */ + +#define HTC_RECORD_NULL 0 +#define HTC_RECORD_CREDITS 1 +#define HTC_RECORD_LOOKAHEAD 2 +#define HTC_RECORD_LOOKAHEAD_BUNDLE 3 + +typedef PREPACK struct +{ + uint8_t RecordID FIELD_PACKED; /* Record ID */ + uint8_t Length FIELD_PACKED; /* Length of record */ +} POSTPACK HTC_RECORD_HDR; + +typedef PREPACK struct +{ + uint8_t EndpointID FIELD_PACKED; /* Endpoint that owns these credits */ + uint8_t Credits FIELD_PACKED; /* credits to report since last report */ +} POSTPACK HTC_CREDIT_REPORT; + +typedef PREPACK struct +{ + uint8_t PreValid FIELD_PACKED; /* pre valid guard */ + uint8_t LookAhead[4] FIELD_PACKED; /* 4 byte lookahead */ + uint8_t PostValid FIELD_PACKED; /* post valid guard */ + + /* NOTE: the LookAhead array is guarded by a PreValid and Post Valid guard bytes. + * The PreValid bytes must equal the inverse of the PostValid byte */ + +} POSTPACK HTC_LOOKAHEAD_REPORT; + +typedef PREPACK struct +{ + uint8_t LookAhead[4] FIELD_PACKED; /* 4 byte lookahead */ +} POSTPACK HTC_BUNDLED_LOOKAHEAD_REPORT; + +#endif /* __HTC_H__ */ diff --git a/platform/mcu/lpc54102/wifi_qca/include/htc_services.h b/platform/mcu/lpc54102/wifi_qca/include/htc_services.h new file mode 100644 index 0000000000..dda7700536 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/include/htc_services.h @@ -0,0 +1,53 @@ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== + +#ifndef __HTC_SERVICES_H__ +#define __HTC_SERVICES_H__ + +/* Current service IDs */ + +typedef enum +{ + RSVD_SERVICE_GROUP = 0, + WMI_SERVICE_GROUP = 1, + + HTC_TEST_GROUP = 254, + HTC_SERVICE_GROUP_LAST = 255 +} HTC_SERVICE_GROUP_IDS; + +#define MAKE_SERVICE_ID(group, index) (int)(((int)group << 8) | (int)(index)) + +/* NOTE: service ID of 0x0000 is reserved and should never be used */ +#define HTC_CTRL_RSVD_SVC MAKE_SERVICE_ID(RSVD_SERVICE_GROUP, 1) +#define WMI_CONTROL_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 0) +#define WMI_DATA_BE_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 1) +#define WMI_DATA_BK_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 2) +#define WMI_DATA_VI_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 3) +#define WMI_DATA_VO_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 4) +#define WMI_MAX_SERVICES 5 + +/* raw stream service (i.e. flash, tcmd, calibration apps) */ +#define HTC_RAW_STREAMS_SVC MAKE_SERVICE_ID(HTC_TEST_GROUP, 0) + +#endif /*HTC_SERVICES_H_*/ diff --git a/platform/mcu/lpc54102/wifi_qca/include/p2p.h b/platform/mcu/lpc54102/wifi_qca/include/p2p.h new file mode 100644 index 0000000000..af02548511 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/include/p2p.h @@ -0,0 +1,470 @@ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 file has the shared declarations between the host & target P2P modules. + */ +#ifndef _P2P_H_ +#define _P2P_H_ + +#define WPS_NONCE_LEN 16 +#define WPS_DEV_TYPE_LEN 8 +#define WPS_AUTHENTICATOR_LEN 8 +#define WPS_HASH_LEN 32 +#define WPS_SECRET_NONCE_LEN 16 +#define WPS_KWA_LEN 8 +#define WPS_MAX_PIN_LEN 8 +#define P2P_MAX_SSID_LEN 32 + +#define WPS_DEV_OUI_WFA 0x0050f204 +#define P2P_IE_VENDOR_TYPE 0x506f9a09 + +#define WLAN_EID_VENDOR_SPECIFIC 221 + +#define P2P_DEV_CAPAB_SERVICE_DISCOVERY BIT(0) + +/* Config Methods */ +#define WPS_CONFIG_USBA 0x0001 +#define WPS_CONFIG_ETHERNET 0x0002 +#define WPS_CONFIG_LABEL 0x0004 +#define WPS_CONFIG_DISPLAY 0x0008 +#define WPS_CONFIG_EXT_NFC_TOKEN 0x0010 +#define WPS_CONFIG_INT_NFC_TOKEN 0x0020 +#define WPS_CONFIG_NFC_INTERFACE 0x0040 +#define WPS_CONFIG_PUSHBUTTON 0x0080 +#define WPS_CONFIG_KEYPAD 0x0100 + +/* Attribute Types */ +enum wps_attribute +{ + ATTR_AP_CHANNEL = 0x1001, + ATTR_ASSOC_STATE = 0x1002, + ATTR_AUTH_TYPE = 0x1003, + ATTR_AUTH_TYPE_FLAGS = 0x1004, + ATTR_AUTHENTICATOR = 0x1005, + ATTR_CONFIG_METHODS = 0x1008, + ATTR_CONFIG_ERROR = 0x1009, + ATTR_CONFIRM_URL4 = 0x100a, + ATTR_CONFIRM_URL6 = 0x100b, + ATTR_CONN_TYPE = 0x100c, + ATTR_CONN_TYPE_FLAGS = 0x100d, + ATTR_CRED = 0x100e, + ATTR_ENCR_TYPE = 0x100f, + ATTR_ENCR_TYPE_FLAGS = 0x1010, + ATTR_DEV_NAME = 0x1011, + ATTR_DEV_PASSWORD_ID = 0x1012, + ATTR_E_HASH1 = 0x1014, + ATTR_E_HASH2 = 0x1015, + ATTR_E_SNONCE1 = 0x1016, + ATTR_E_SNONCE2 = 0x1017, + ATTR_ENCR_SETTINGS = 0x1018, + ATTR_ENROLLEE_NONCE = 0x101a, + ATTR_FEATURE_ID = 0x101b, + ATTR_IDENTITY = 0x101c, + ATTR_IDENTITY_PROOF = 0x101d, + ATTR_KEY_WRAP_AUTH = 0x101e, + ATTR_KEY_ID = 0x101f, + ATTR_MAC_ADDR = 0x1020, + ATTR_MANUFACTURER = 0x1021, + ATTR_MSG_TYPE = 0x1022, + ATTR_MODEL_NAME = 0x1023, + ATTR_MODEL_NUMBER = 0x1024, + ATTR_NETWORK_INDEX = 0x1026, + ATTR_NETWORK_KEY = 0x1027, + ATTR_NETWORK_KEY_INDEX = 0x1028, + ATTR_NEW_DEVICE_NAME = 0x1029, + ATTR_NEW_PASSWORD = 0x102a, + ATTR_OOB_DEVICE_PASSWORD = 0x102c, + ATTR_OS_VERSION = 0x102d, + ATTR_POWER_LEVEL = 0x102f, + ATTR_PSK_CURRENT = 0x1030, + ATTR_PSK_MAX = 0x1031, + ATTR_PUBLIC_KEY = 0x1032, + ATTR_RADIO_ENABLE = 0x1033, + ATTR_REBOOT = 0x1034, + ATTR_REGISTRAR_CURRENT = 0x1035, + ATTR_REGISTRAR_ESTABLISHED = 0x1036, + ATTR_REGISTRAR_LIST = 0x1037, + ATTR_REGISTRAR_MAX = 0x1038, + ATTR_REGISTRAR_NONCE = 0x1039, + ATTR_REQUEST_TYPE = 0x103a, + ATTR_RESPONSE_TYPE = 0x103b, + ATTR_RF_BANDS = 0x103c, + ATTR_R_HASH1 = 0x103d, + ATTR_R_HASH2 = 0x103e, + ATTR_R_SNONCE1 = 0x103f, + ATTR_R_SNONCE2 = 0x1040, + ATTR_SELECTED_REGISTRAR = 0x1041, + ATTR_SERIAL_NUMBER = 0x1042, + ATTR_WPS_STATE = 0x1044, + ATTR_SSID = 0x1045, + ATTR_TOTAL_NETWORKS = 0x1046, + ATTR_UUID_E = 0x1047, + ATTR_UUID_R = 0x1048, + ATTR_VENDOR_EXT = 0x1049, + ATTR_VERSION = 0x104a, + ATTR_X509_CERT_REQ = 0x104b, + ATTR_X509_CERT = 0x104c, + ATTR_EAP_IDENTITY = 0x104d, + ATTR_MSG_COUNTER = 0x104e, + ATTR_PUBKEY_HASH = 0x104f, + ATTR_REKEY_KEY = 0x1050, + ATTR_KEY_LIFETIME = 0x1051, + ATTR_PERMITTED_CFG_METHODS = 0x1052, + ATTR_SELECTED_REGISTRAR_CONFIG_METHODS = 0x1053, + ATTR_PRIMARY_DEV_TYPE = 0x1054, + ATTR_SECONDARY_DEV_TYP_ELIST = 0x1055, + ATTR_PORTABLE_DEV = 0x1056, + ATTR_AP_SETUP_LOCKED = 0x1057, + ATTR_APPLICATION_EXT = 0x1058, + ATTR_EAP_TYPE = 0x1059, + ATTR_IV = 0x1060, + ATTR_KEY_PROVIDED_AUTO = 0x1061, + ATTR_802_1X_ENABLED = 0x1062, + ATTR_APPSESSIONKEY = 0x1063, + ATTR_WEPTRANSMITKEY = 0x1064, + ATTR_REQUESTED_DEV_TYPE = 0x106a +}; + +enum p2p_wps_method +{ + WPS_NOT_READY, + WPS_PIN_LABEL, + WPS_PIN_DISPLAY, + WPS_PIN_KEYPAD, + WPS_PBC +}; + +enum p2p_status_code +{ + P2P_SC_SUCCESS = 0, + P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE = 1, + P2P_SC_FAIL_INCOMPATIBLE_PARAMS = 2, + P2P_SC_FAIL_LIMIT_REACHED = 3, + P2P_SC_FAIL_INVALID_PARAMS = 4, + P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE = 5, + P2P_SC_FAIL_PREV_PROTOCOL_ERROR = 6, + P2P_SC_FAIL_NO_COMMON_CHANNELS = 7, + P2P_SC_FAIL_UNKNOWN_GROUP = 8, + P2P_SC_FAIL_BOTH_GO_INTENT_15 = 9, + P2P_SC_FAIL_INCOMPATIBLE_PROV_METHOD = 10, + P2P_SC_FAIL_REJECTED_BY_USER = 11 +}; + +struct wps_parse_attr +{ + /* fixed length fields */ + const uint8_t *version; /* 1 octet */ + const uint8_t *msg_type; /* 1 octet */ + const uint8_t *enrollee_nonce; /* WPS_NONCE_LEN (16) octets */ + const uint8_t *registrar_nonce; /* WPS_NONCE_LEN (16) octets */ + const uint8_t *uuid_r; /* WPS_UUID_LEN (16) octets */ + const uint8_t *uuid_e; /* WPS_UUID_LEN (16) octets */ + const uint8_t *auth_type_flags; /* 2 octets */ + const uint8_t *encr_type_flags; /* 2 octets */ + const uint8_t *conn_type_flags; /* 1 octet */ + const uint8_t *config_methods; /* 2 octets */ + const uint8_t *sel_reg_config_methods; /* 2 octets */ + const uint8_t *primary_dev_type; /* 8 octets */ + const uint8_t *rf_bands; /* 1 octet */ + const uint8_t *assoc_state; /* 2 octets */ + const uint8_t *config_error; /* 2 octets */ + const uint8_t *dev_password_id; /* 2 octets */ + const uint8_t *oob_dev_password; /* WPS_OOB_DEVICE_PASSWORD_ATTR_LEN (54) + * octets */ + const uint8_t *os_version; /* 4 octets */ + const uint8_t *wps_state; /* 1 octet */ + const uint8_t *authenticator; /* WPS_AUTHENTICATOR_LEN (8) octets */ + const uint8_t *r_hash1; /* WPS_HASH_LEN (32) octets */ + const uint8_t *r_hash2; /* WPS_HASH_LEN (32) octets */ + const uint8_t *e_hash1; /* WPS_HASH_LEN (32) octets */ + const uint8_t *e_hash2; /* WPS_HASH_LEN (32) octets */ + const uint8_t *r_snonce1; /* WPS_SECRET_NONCE_LEN (16) octets */ + const uint8_t *r_snonce2; /* WPS_SECRET_NONCE_LEN (16) octets */ + const uint8_t *e_snonce1; /* WPS_SECRET_NONCE_LEN (16) octets */ + const uint8_t *e_snonce2; /* WPS_SECRET_NONCE_LEN (16) octets */ + const uint8_t *key_wrap_auth; /* WPS_KWA_LEN (8) octets */ + const uint8_t *auth_type; /* 2 octets */ + const uint8_t *encr_type; /* 2 octets */ + const uint8_t *network_idx; /* 1 octet */ + const uint8_t *network_key_idx; /* 1 octet */ + const uint8_t *mac_addr; /* ETH_ALEN (6) octets */ + const uint8_t *key_prov_auto; /* 1 octet (Bool) */ + const uint8_t *dot1x_enabled; /* 1 octet (Bool) */ + const uint8_t *selected_registrar; /* 1 octet (Bool) */ + const uint8_t *request_type; /* 1 octet */ + const uint8_t *response_type; /* 1 octet */ + const uint8_t *ap_setup_locked; /* 1 octet */ + + /* variable length fields */ + const uint8_t *manufacturer; + uint32_t manufacturer_len; + const uint8_t *model_name; + uint32_t model_name_len; + const uint8_t *model_number; + uint32_t model_number_len; + const uint8_t *serial_number; + uint32_t serial_number_len; + const uint8_t *dev_name; + uint32_t dev_name_len; + const uint8_t *public_key; + uint32_t public_key_len; + const uint8_t *encr_settings; + uint32_t encr_settings_len; + const uint8_t *ssid; /* <= 32 octets */ + uint32_t ssid_len; + const uint8_t *network_key; /* <= 64 octets */ + uint32_t network_key_len; + const uint8_t *eap_type; /* <= 8 octets */ + uint32_t eap_type_len; + const uint8_t *eap_identity; /* <= 64 octets */ + uint32_t eap_identity_len; + +/* attributes that can occur multiple times */ +#define MAX_CRED_COUNT 10 + const uint8_t *cred[MAX_CRED_COUNT]; + uint32_t cred_len[MAX_CRED_COUNT]; + uint32_t num_cred; + +#define MAX_REQ_DEV_TYPE_COUNT 10 + const uint8_t *req_dev_type[MAX_REQ_DEV_TYPE_COUNT]; + uint32_t num_req_dev_type; +}; + +#define P2P_WPS_PIN_LEN 9 +#define P2P_CHANNEL_LEN 3 +// char p2p_wps_pin_val[P2P_WPS_PIN_LEN]; + +enum p2p_sublem_id +{ + P2P_ATTR_STATUS = 0, + P2P_ATTR_MINOR_REASON_CODE = 1, + P2P_ATTR_CAPABILITY = 2, + P2P_ATTR_DEVICE_ID = 3, + P2P_ATTR_GROUP_OWNER_INTENT = 4, + P2P_ATTR_CONFIGURATION_TIMEOUT = 5, + P2P_ATTR_LISTEN_CHANNEL = 6, + P2P_ATTR_GROUP_BSSID = 7, + P2P_ATTR_EXT_LISTEN_TIMING = 8, + P2P_ATTR_INTENDED_INTERFACE_ADDR = 9, + P2P_ATTR_MANAGEABILITY = 10, + P2P_ATTR_CHANNEL_LIST = 11, + P2P_ATTR_NOTICE_OF_ABSENCE = 12, + P2P_ATTR_DEVICE_INFO = 13, + P2P_ATTR_GROUP_INFO = 14, + P2P_ATTR_GROUP_ID = 15, + P2P_ATTR_INTERFACE = 16, + P2P_ATTR_OPERATING_CHANNEL = 17, + P2P_ATTR_INVITATION_FLAGS = 18, + P2P_ATTR_VENDOR_SPECIFIC = 221 +}; + +#define P2P_MAX_REG_CLASSES 10 +#define P2P_MAX_REG_CLASS_CHANNELS 20 + +#define P2P_WILDCARD_SSID "DIRECT-" +#define P2P_WILDCARD_SSID_LEN 7 + +struct p2p_channels +{ + struct p2p_reg_class + { + uint8_t reg_class; + uint8_t channel[P2P_MAX_REG_CLASS_CHANNELS]; + uint8_t channels; + } reg_class[P2P_MAX_REG_CLASSES]; + uint8_t reg_classes; +}; + +#define P2P_NOA_DESCRIPTOR_LEN 13 +struct p2p_noa_descriptor +{ + uint8_t type_count; /* 255: continuous schedule, 0: reserved */ + uint32_t duration; /* Absent period duration in micro seconds */ + uint32_t interval; /* Absent period interval in micro seconds */ + uint32_t start_time; /* 32 bit tsf time when in starts */ +}; + +#define P2P_MAX_NOA_DESCRIPTORS 4 +/* + * Length = (2 octets for Index and CTWin/Opp PS) and + * (13 octets for each NOA Descriptors) + */ +#define P2P_NOA_IE_SIZE(num_desc) (2 + (13 * (num_desc))) + +#define P2P_NOE_IE_OPP_PS_SET (0x80) +#define P2P_NOE_IE_CTWIN_MASK (0x7F) + +struct p2p_sub_element_noa +{ + uint8_t p2p_sub_id; + uint8_t p2p_sub_len; + uint8_t index; /* identifies instance of NOA su element */ + uint8_t oppPS : 1, /* oppPS state of the AP */ + ctwindow : 7; /* ctwindow in TUs */ + uint8_t num_descriptors; /* number of NOA descriptors */ + struct p2p_noa_descriptor noa_descriptors[P2P_MAX_NOA_DESCRIPTORS]; +}; + +#define ETH_ALEN 6 + +struct p2p_ie +{ + uint8_t dialog_token; + const uint8_t *capability; + const uint8_t *go_intent; + const uint8_t *status; + const uint8_t *listen_channel; + const uint8_t *operating_channel; + const uint8_t *channel_list; + uint8_t channel_list_len; + const uint8_t *config_timeout; + const uint8_t *intended_addr; + const uint8_t *group_bssid; + const uint8_t *invitation_flags; + + const uint8_t *group_info; + uint32_t group_info_len; + const uint8_t *group_id; + uint32_t group_id_len; + + const uint8_t *device_id; + const uint8_t *manageability; + + const uint8_t *noa; + uint32_t noa_len; + const uint8_t *ext_listen_timing; + + const uint8_t *minor_reason_code; + + /* P2P Device Info */ + const uint8_t *p2p_device_info; + uint32_t p2p_device_info_len; + const uint8_t *p2p_device_addr; + const uint8_t *pri_dev_type; + uint8_t num_sec_dev_types; + char device_name[33]; + uint8_t dev_name_len; + uint16_t config_methods; + + /* WPS IE */ + uint16_t dev_password_id; + uint16_t wps_config_methods; + + /* SSID IE */ + const uint8_t *ssid; +}; + +struct p2p_device +{ + uint16_t listen_freq; + uint32_t wps_pbc; + char wps_pin[WPS_MAX_PIN_LEN]; + uint8_t pin_len; + uint32_t wps_method; + + uint8_t p2p_device_addr[ETH_ALEN]; + uint8_t pri_dev_type[8]; + char device_name[33]; + uint16_t config_methods; + uint8_t dev_capab; + uint8_t group_capab; + + uint8_t interface_addr[ETH_ALEN]; + + /* Dev. Discoverability data */ + uint8_t dev_disc_dialog_token; + uint8_t member_in_go_dev[ETH_ALEN]; + uint8_t member_in_go_iface[ETH_ALEN]; + uint8_t dev_disc_go_oper_ssid[WMI_MAX_SSID_LEN]; + uint8_t dev_disc_go_oper_ssid_len; + uint16_t dev_disc_go_oper_freq; + + uint32_t go_neg_req_sent; + + uint32_t go_state; + uint8_t dialog_token; + uint8_t intended_addr[ETH_ALEN]; + + struct p2p_channels channels; + uint16_t oper_freq; + uint8_t oper_ssid[P2P_MAX_SSID_LEN]; + uint8_t oper_ssid_len; + + uint16_t req_config_methods; + +#define P2P_DEV_PROBE_REQ_ONLY BIT(0) +#define P2P_DEV_REPORTED BIT(1) +#define P2P_DEV_NOT_YET_READY BIT(2) +#define P2P_DEV_SD_INFO BIT(3) +#define P2P_DEV_SD_SCHEDULE BIT(4) +#define P2P_DEV_PD_PEER_DISPLAY BIT(5) +#define P2P_DEV_PD_PEER_KEYPAD BIT(6) +#define P2P_DEV_USER_REJECTED BIT(7) +#define P2P_DEV_PEER_WAITING_RESPONSE BIT(8) +#define P2P_DEV_PREFER_PERSISTENT_GROUP BIT(9) +#define P2P_DEV_WAIT_GO_NEG_RESPONSE BIT(10) +#define P2P_DEV_WAIT_GO_NEG_CONFIRM BIT(11) +#define P2P_DEV_GROUP_CLIENT_ONLY BIT(12) +#define P2P_DEV_FORCE_FREQ BIT(13) + + uint32_t flags; + + uint32_t status; + uint8_t wait_count; + uint32_t invitation_reqs; + + uint16_t ext_listen_period; + uint16_t ext_listen_interval; + + uint8_t go_timeout; + uint8_t client_timeout; + uint8_t persistent_grp; +}; + +typedef PREPACK struct +{ + uint32_t wps_method; + uint16_t config_methods; + uint16_t oper_freq; + uint8_t pri_dev_type[8]; + uint8_t p2p_device_addr[ETH_ALEN]; + uint8_t interface_addr[ETH_ALEN]; + uint8_t dev_capab; + uint8_t group_capab; + uint8_t persistent_grp; + char device_name[33]; +} POSTPACK P2P_DEVICE_LITE; +#if 0 +struct p2p_default_profile { + char wps_pin[WPS_MAX_PIN_LEN]; + uint8_t pin_len; +#define P2P_WPS_PUSH (1 << 0) +#define P2P_WPS_PIN (1 << 1) +#define P2P_WPS_PIN_MY_PIN (1 << 2) + uint8_t default_wps_method; + uint32_t default_find_to; + uint8_t ssid_postfix[WMI_MAX_SSID_LEN-9]; + uint8_t ssid_postfix_len; + +} +#endif +// struct p2p_device p2p_persistent_device; +#endif /* _P2P_H_ */ diff --git a/platform/mcu/lpc54102/wifi_qca/include/pkt_log.h b/platform/mcu/lpc54102/wifi_qca/include/pkt_log.h new file mode 100644 index 0000000000..3594ab33d9 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/include/pkt_log.h @@ -0,0 +1,55 @@ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== + +#ifndef __PKT_LOG_H__ +#define __PKT_LOG_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef ATH_TARGET +#include "athstartpack.h" +#endif + +/* Pkt log info */ +typedef PREPACK struct pkt_log_t +{ + struct info_t + { + uint16_t st FIELD_PACKED; + uint16_t end FIELD_PACKED; + uint16_t cur FIELD_PACKED; + } info[4096] FIELD_PACKED; + uint16_t last_idx FIELD_PACKED; +} POSTPACK PACKET_LOG; + +#ifndef ATH_TARGET +#include "athendpack.h" +#endif + +#ifdef __cplusplus +} +#endif +#endif /* __PKT_LOG_H__ */ diff --git a/platform/mcu/lpc54102/wifi_qca/include/pmu.h b/platform/mcu/lpc54102/wifi_qca/include/pmu.h new file mode 100644 index 0000000000..1ed0f26203 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/include/pmu.h @@ -0,0 +1,42 @@ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== + +#ifndef _PMU_H_ +#define _PMU_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#define WAKE_MGR_WAKE_EVENT_TIMER 0X00000001 +#define WAKE_MGR_WAKE_EVENT_GPIO30_HIGH 0x00000002 +#define WAKE_MGR_WAKE_EVENT_GPIO30_LOW 0x00000004 +#define WAKE_MGR_WAKE_EVENT_GPIO31_HIGH 0x00000008 +#define WAKE_MGR_WAKE_EVENT_GPIO31_LOW 0x00000010 + +#ifdef __cplusplus +} +#endif + +#endif /* _DBGLOG_H_ */ diff --git a/platform/mcu/lpc54102/wifi_qca/include/targaddrs.h b/platform/mcu/lpc54102/wifi_qca/include/targaddrs.h new file mode 100644 index 0000000000..08c8cba822 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/include/targaddrs.h @@ -0,0 +1,658 @@ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== + +#ifndef __TARGADDRS_H__ +#define __TARGADDRS_H__ + +#include "bmi_msg.h" + +/* + * AR6K option bits, to enable/disable various features. + * By default, all option bits are 0. + * These bits can be set in LOCAL_SCRATCH register 0. + */ +#define AR6K_OPTION_BMI_DISABLE 0x01 /* Disable BMI comm with Host */ +#define AR6K_OPTION_SERIAL_ENABLE 0x02 /* Enable serial port msgs */ +#define AR6K_OPTION_WDT_DISABLE 0x04 /* WatchDog Timer override */ +#define AR6K_OPTION_SLEEP_DISABLE 0x08 /* Disable system sleep */ +#define AR6K_OPTION_STOP_BOOT 0x10 /* Stop boot processes (for ATE) */ +#define AR6K_OPTION_ENABLE_NOANI 0x20 /* Operate without ANI */ +#define AR6K_OPTION_DSET_DISABLE 0x40 /* Ignore DataSets */ +#define AR6K_OPTION_IGNORE_FLASH 0x80 /* Ignore flash during bootup */ + +/* + * xxx_HOST_INTEREST_ADDRESS is the address in Target RAM of the + * host_interest structure. It must match the address of the _host_interest + * symbol (see linker script). + * + * Host Interest is shared between Host and Target in order to coordinate + * between the two, and is intended to remain constant (with additions only + * at the end) across software releases. + * + * All addresses are available here so that it's possible to + * write a single binary that works with all Target Types. + * May be used in assembler code as well as C. + */ + +#define AR4100_HOST_INTEREST_ADDRESS 0x00540600 +#define AR4002_HOST_INTEREST_ADDRESS 0x00428800 + +#if ATH_FIRMWARE_TARGET == TARGET_AR4100_REV2 +#define HOST_INTEREST ((uint32_t *)AR4100_HOST_INTEREST_ADDRESS) +#define HOST_INTEREST_MAX_SIZE 0x100 +#elif ATH_FIRMWARE_TARGET == TARGET_AR400X_REV1 +#define HOST_INTEREST ((uint32_t *)AR4002_HOST_INTEREST_ADDRESS) +#define HOST_INTEREST_MAX_SIZE 0x200 +#endif + +#if !defined(__ASSEMBLER__) +struct register_dump_s; +struct dbglog_hdr_s; + +/* + * These are items that the Host may need to access + * via BMI or via the Diagnostic Window. The position + * of items in this structure must remain constant + * across firmware revisions! + * + * Types for each item must be fixed size across + * target and host platforms. + * + * More items may be added at the end. + */ +struct host_interest_s +{ + /* + * Pointer to application-defined area, if any. + * Set by Target application during startup. + */ + uint32_t hi_app_host_interest; /* 0x00 */ + + /* Pointer to register dump area, valid after Target crash. */ + uint32_t hi_failure_state; /* 0x04 */ + + /* Pointer to debug logging header */ + uint32_t hi_dbglog_hdr; /* 0x08 */ + + /* Indicates whether or not flash is present on Target. + * NB: flash_is_present indicator is here not just + * because it might be of interest to the Host; but + * also because it's set early on by Target's startup + * asm code and we need it to have a special RAM address + * so that it doesn't get reinitialized with the rest + * of data. + */ + uint32_t hi_flash_is_present; /* 0x0c */ + + /* + * General-purpose flag bits, similar to AR6000_OPTION_* flags. + * Can be used by application rather than by OS. + */ + uint32_t hi_option_flag; /* 0x10 */ + + /* + * Boolean that determines whether or not to + * display messages on the serial port. + */ + uint32_t hi_serial_enable; /* 0x14 */ + + /* Start address of Flash DataSet index, if any */ + uint32_t hi_dset_list_head; /* 0x18 */ + + /* Override Target application start address */ + uint32_t hi_app_start; /* 0x1c */ + + /* Clock and voltage tuning */ + uint32_t hi_skip_clock_init; /* 0x20 */ + uint32_t hi_core_clock_setting; /* 0x24 */ + uint32_t hi_cpu_clock_setting; /* 0x28 */ + uint32_t hi_system_sleep_setting; /* 0x2c */ + uint32_t hi_xtal_control_setting; /* 0x30 */ + uint32_t hi_pll_ctrl_setting_24ghz; /* 0x34 */ + uint32_t hi_pll_ctrl_setting_5ghz; /* 0x38 */ + uint32_t hi_ref_voltage_trim_setting; /* 0x3c */ + uint32_t hi_clock_info; /* 0x40 */ + + /* + * Flash configuration overrides, used only + * when firmware is not executing from flash. + * (When using flash, modify the global variables + * with equivalent names.) + */ + uint32_t hi_bank0_addr_value; /* 0x44 */ + uint32_t hi_bank0_read_value; /* 0x48 */ + uint32_t hi_bank0_write_value; /* 0x4c */ + uint32_t hi_bank0_config_value; /* 0x50 */ + + /* Pointer to Board Data */ + uint32_t hi_board_data; /* 0x54 */ + + /* + * Indication of Board Data state: + * 0: board data is not yet initialized. + * 1: board data is initialized; unknown size + * >1: number of bytes of initialized board data (varies with board type) + */ + uint32_t hi_board_data_initialized; /* 0x58 */ + + uint32_t hi_dset_RAM_index_table; /* 0x5c */ + + uint32_t hi_desired_baud_rate; /* 0x60 */ + uint32_t hi_dbglog_config; /* 0x64 */ + uint32_t hi_end_RAM_reserve_sz; /* 0x68 */ + uint32_t hi_mbox_io_block_sz; /* 0x6c */ + + uint32_t hi_num_bpatch_streams; /* 0x70 -- unused */ + uint32_t hi_mbox_isr_yield_limit; /* 0x74 */ + + uint32_t hi_refclk_hz; /* 0x78 */ + uint32_t hi_ext_clk_detected; /* 0x7c */ + uint32_t hi_dbg_uart_txpin; /* 0x80 */ + uint32_t hi_dbg_uart_rxpin; /* 0x84 */ + uint32_t hi_hci_uart_baud; /* 0x88 */ + uint32_t hi_hci_uart_pin_assignments; /* 0x8C */ + /* NOTE: byte [0] = tx pin, [1] = rx pin, [2] = rts pin, [3] = cts pin */ + uint32_t hi_hci_uart_baud_scale_val; /* 0x90 */ + uint32_t hi_hci_uart_baud_step_val; /* 0x94 */ + + uint32_t hi_allocram_start; /* 0x98 */ + uint32_t hi_allocram_sz; /* 0x9c */ + uint32_t hi_hci_bridge_flags; /* 0xa0 */ + uint32_t hi_hci_uart_support_pins; /* 0xa4 */ + /* NOTE: byte [0] = RESET pin (bit 7 is polarity), bytes[1]..bytes[3] are for future use */ + uint32_t hi_hci_uart_pwr_mgmt_params; /* 0xa8 */ + /* 0xa8 - [0]: 1 = enable, 0 = disable + * [1]: 0 = UART FC active low, 1 = UART FC active high + * 0xa9 - [7:0]: wakeup timeout in ms + * 0xaa, 0xab - [15:0]: idle timeout in ms + */ + /* Pointer to extended board Data */ + uint32_t hi_board_ext_data; /* 0xac */ + uint32_t hi_board_ext_data_config; /* 0xb0 */ + /* + * Bit [0] : valid + * Bit[31:16: size + */ + /* + * hi_reset_flag is used to do some stuff when target reset. + * such as restore app_start after warm reset or + * preserve host Interest area, or preserve ROM data, literals etc. + */ + uint32_t hi_reset_flag; /* 0xb4 */ + /* indicate hi_reset_flag is valid */ + uint32_t hi_reset_flag_valid; /* 0xb8 */ + uint32_t hi_hci_uart_pwr_mgmt_params_ext; /* 0xbc */ + /* 0xbc - [31:0]: idle timeout in ms + */ + /* ACS flags */ + uint32_t hi_acs_flags; /* 0xc0 */ + uint32_t hi_console_flags; /* 0xc4 */ + uint32_t hi_nvram_state; /* 0xc8 */ + uint32_t hi_option_flag2; /* 0xcc */ + + /* If non-zero, override values sent to Host in WMI_READY event. */ + uint32_t hi_sw_version_override; /* 0xd0 */ + uint32_t hi_abi_version_override; /* 0xd4 */ + /* Percentage of high priority RX traffic to total expected RX traffic - + * applicable only to ar6004 */ + uint32_t hi_hp_rx_traffic_ratio; /* 0xd8 */ + + /* test applications flags */ + uint32_t hi_test_apps_related; /* 0xdc */ + /* location of test script */ + uint32_t hi_ota_testscript; /* 0xe0 */ + /* location of CAL data */ + uint32_t hi_cal_data; /* 0xe4 */ + + /* Number of packet log buffers */ + uint32_t hi_pktlog_num_buffers; /* 0xe8 */ + + /* wow extension configuration */ + uint32_t hi_wow_ext_config; /* 0xec */ + + uint32_t hi_pwr_save_flags; /* 0xf0 */ + + /* Spatial Multiplexing Power Save (SMPS) options */ + uint32_t hi_smps_options; /* 0xf4 */ + /* rx coalescing filter configuration */ + uint32_t hi_rx_coalesce_filter_config; /* 0xf8 */ + + uint32_t hi_bt_sharing_info; /* 0xfc */ + +#if (HOST_INTEREST_MAX_SIZE > 0x100) + + uint32_t hi_i2c_slv_cfg; /* 0x100 */ + + uint32_t hi_reserved_3; /* 0x104*/ + uint32_t hi_reserved_4; /* 0x108 */ + uint32_t hi_reserved_5; /* 0x10c */ + uint32_t hi_reserved_6; /* 0x110 */ + + /* RTOS-specific pointer-sized value */ + uint32_t hi_rtos; /* 0x114 */ + + /* Extending General purpose Flags */ + uint32_t hi_option_flag3; /* 0x118 */ +#endif /*HOST_INTEREST_MAX_SIZE*/ +}; + +/* bitmap for hi_test_apps_related */ +#define HI_TEST_APPS_TESTSCRIPT_LOADED 0x00000001 +#define HI_TEST_APPS_CAL_DATA_AVAIL 0x00000002 +#define HI_TEST_APPS_ENABLE_WHCK_LOG 0x00000004 + +/* Bits defined in hi_option_flag */ +#define HI_OPTION_TIMER_WAR 0x01 /* Enable timer workaround */ +#define HI_OPTION_BMI_CRED_LIMIT 0x02 /* Limit BMI command credits */ +#define HI_OPTION_RELAY_DOT11_HDR 0x04 /* Relay Dot11 hdr to/from host */ +#define HI_OPTION_MAC_ADDR_METHOD 0x08 /* MAC addr method 0-locally administred 1-globally unique addrs */ +#define HI_OPTION_FW_BRIDGE 0x10 /* Firmware Bridging */ +#define HI_OPTION_ENABLE_PROFILE 0x20 /* Enable CPU profiling */ +#define HI_OPTION_DISABLE_DBGLOG 0x40 /* Disable debug logging */ +#define HI_OPTION_SKIP_ERA_TRACKING 0x80 /* Skip Era Tracking */ +#define HI_OPTION_PAPRD_DISABLE 0x100 /* Disable PAPRD (debug) */ +#define HI_OPTION_NUM_DEV_LSB 0x200 +#define HI_OPTION_NUM_DEV_MSB 0x800 +#define HI_OPTION_DEV_MODE_LSB 0x1000 +#define HI_OPTION_ATTUNNEL_MODE 0x2000 +#define HI_OPTION_DEV_MODE_MSB 0x8000000 +#define HI_OPTION_NO_LFT_STBL 0x10000000 /* Disable LowFreq Timer Stabilization */ +#define HI_OPTION_SKIP_REG_SCAN 0x20000000 /* Skip regulatory scan */ +#define HI_OPTION_INIT_REG_SCAN \ + 0x40000000 /* Do regulatory scan during init before \ + * sending WMI ready event to host */ +#define HI_OPTION_SKIP_MEMMAP 0x80000000 /* REV6: Do not adjust memory map */ + +#define HI_OPTION_MAC_ADDR_METHOD_SHIFT 3 + +/* 2 bits of hi_option_flag are used to represent 3 modes */ +#define HI_OPTION_FW_MODE_IBSS 0x0 /* IBSS Mode */ +#define HI_OPTION_FW_MODE_BSS_STA 0x1 /* STA Mode */ +#define HI_OPTION_FW_MODE_AP 0x2 /* AP Mode */ +#define HI_OPTION_FW_MODE_BT30AMP 0x3 /* BT30 AMP Mode */ + +/* 2 bits of hi_option flag are usedto represent 4 submodes */ +#define HI_OPTION_FW_SUBMODE_NONE 0x0 /* Normal mode */ +#define HI_OPTION_FW_SUBMODE_P2PDEV 0x1 /* p2p device mode */ +#define HI_OPTION_FW_SUBMODE_P2PCLIENT 0x2 /* p2p client mode */ +#define HI_OPTION_FW_SUBMODE_P2PGO 0x3 /* p2p go mode */ + +/* Num dev Mask */ +#define HI_OPTION_NUM_DEV_MASK 0x7 +#define HI_OPTION_NUM_DEV_SHIFT 0x9 + +/* firmware bridging */ +#define HI_OPTION_FW_BRIDGE_SHIFT 0x04 + +/* Fw Mode/SubMode Mask +|-------------------------------------------------------------------------------| +| SUB | SUB | SUB | SUB | | | | | +| MODE[3] | MODE[2] | MODE[1] | MODE[0] | MODE[3] | MODE[2] | MODE[1] | MODE[0] | +| (2) | (2) | (2) | (2) | (2) | (2) | (2) | (2) | +|-------------------------------------------------------------------------------| +*/ +#define HI_OPTION_FW_MODE_BITS 0x2 +#define HI_OPTION_FW_MODE_MASK 0x3 +#define HI_OPTION_FW_MODE_SHIFT 0xC +#define HI_OPTION_ALL_FW_MODE_MASK 0xFF + +#define HI_OPTION_FW_SUBMODE_BITS 0x2 +#define HI_OPTION_FW_SUBMODE_MASK 0x3 +#define HI_OPTION_FW_SUBMODE_SHIFT 0x14 +#define HI_OPTION_ALL_FW_SUBMODE_MASK 0xFF00 +#define HI_OPTION_ALL_FW_SUBMODE_SHIFT 0x8 + +/* hi_option_flag2 options */ +#define HI_OPTION_OFFLOAD_AMSDU 0x01 +#define HI_OPTION_DFS_SUPPORT 0x02 /* Enable DFS support */ +#define HI_OPTION_ENABLE_RFKILL 0x04 /* RFKill Enable Feature*/ +#define HI_OPTION_RADIO_RETENTION_DISABLE 0x08 /* Disable radio retention */ +#define HI_OPTION_ENABLE_REALTIME_DEBUGGING 0x10 /* Enable realtime debugging */ +#define HI_OPTION_DISABLE_RTT 0x20 /* Disable RTT Feature */ +#define HI_OPTION_DISABLE_MAC_OTP 0x40 /* Disable MAC address overwrite via OTP Feature */ +#define HI_OPTION_USE_MBOX_CREDIT_REPORT 0x80 /* Enable MBOX Credit report mechanism */ +#define HI_OPTION_DISABLE_P2P_DEDICATE 0x100 /* Disable p2p dedicate device */ +#define HI_OPTION_INCREASE_TXBUF 0x200 /* Increase txbuf flag for host */ +#define HI_OPTION_AP_CLIENT_CNT 0x3c00 /* alternate number of clients in apmode */ +#define HI_OPTION_AP_DTIM_VAL 0x3c000 /* alternate dtim val in apmode */ +#define HI_OPTION_IOE_STA_OFFLOAD 0x40000 /* provision to enable station switching in apmode */ +#define HI_OPTION_EXT_FW_DOWNLOAD_DONE 0x80000 /* ext patch download finished after WMI ready*/ +#define HI_OPTION_ENABLE_NDIS_WAKE_WAR 0x100000 /* Enable NDIS wake WAR */ +#define HI_OPTION_ENABLE_LTE_COEX 0x200000 /* enable ltecoex hook up function in ROM */ +#define HI_OPTION_WOW_ACTIVE_LOW 0x400000 /* WoW in active low manner */ +#define HI_OPTION_BAM2BAM_MODE 0x800000 /* Enable BAM2BAM mode */ +#define HI_OPTION_ENABLE_PANASONIC_WAR 0x1000000 /* Enable Panasonic's WAR */ +#define HI_OPTION_ENABLE_ONE_SHOT_NOA 0x2000000 /* Enable one shot ona */ +#define HI_OPTION_ENABLE_SB_SPECIFIC 0x4000000 /* Enable customer specific function */ +#define HI_OPTION_WOW_SINGLE_CHAIN 0x8000000 /* Enable single chain in wow */ +#define HI_OPTION_ENABLE_WLAN_HB 0x10000000 /* Enable wlan hb function */ +#define HI_OPTION_ENABLE_SOFTAP_CH13 0x20000000 /* Enable Softap in Channel 13 */ +#define HI_OPTION_IGNORE_11D_BEACON 0x40000000 /* Ignore 11d beacon */ +#define HI_OPTION_MCC_ENABLE \ + 0x80000000 /* Disable Multichannel Concurrency (MCC) - used last bit to sync with mainline */ +#define HI_OPTION_RF_KILL_SHIFT 0x2 +#define HI_OPTION_RF_KILL_MASK 0x1 + +#define HI_OPTION_AP_CLIENT_CNT_SHIFT 0x0A +#define HI_OPTION_AP_DTIM_VAL_SHIFT 0x0E +#define HI_OPTION_IOE_STA_OFFLOAD_SHIFT 0x12 + +/* 4-bits(Bit 13 - Bit 10) to notify number of clients in apmode */ +#define HI_OPTION_AP_CLIENT_CNT_MASK 0x0F +/* 4-bits(Bit 17 - Bit 14)) use this 4 bit mask for dtim val in apmode*/ +#define HI_OPTION_AP_DTIM_VAL_MASK 0x0F +/* 1-bit(Bit 18)) use this 1 bit mask to enable sta-sta switching offload in apmode*/ +#define HI_OPTION_IOE_STA_OFFLOAD_MASK 0x01 + +/* hi_option_flag3 options */ +#define HI_OPTION_USE_OFFLOAD_P2P 0x01 +#define HI_OPTION_EN_HOST_PROXY_FW_DLOAD_MODE 0x02 /* Controls host proxy boot mode */ + +/* hi_reset_flag */ +#define HI_RESET_FLAG_PRESERVE_APP_START 0x01 /* preserve App Start address */ +#define HI_RESET_FLAG_PRESERVE_HOST_INTEREST 0x02 /* preserve host interest */ +#define HI_RESET_FLAG_PRESERVE_ROMDATA 0x04 /* preserve ROM data */ +#define HI_RESET_FLAG_PRESERVE_NVRAM_STATE 0x08 +#define HI_RESET_FLAG_PRESERVE_BOOT_INFO 0x10 +#define HI_RESET_FLAG_WARM_RESET 0x20 + +#define HI_RESET_FLAG_IS_VALID 0x12345678 /* indicate the reset flag is valid */ + +#define HI_ACS_FLAGS_ENABLED (1 << 0) /* ACS is enabled */ +#define HI_ACS_FLAGS_USE_WWAN (1 << 1) /* Use physical WWAN device */ +#define HI_ACS_FLAGS_TEST_VAP (1 << 2) /* Use test VAP */ +#define HI_ACS_FLAGS_ATTUNNEL_MODE (1 << 3) /* Use at tunnel mode */ +#define HI_ACS_FLAGS_RADIO_OFF (1 << 4) /* WWAN radio off */ +#define HI_ACS_FLAGS_USE_VAP (1 << 5) /* Use VAP as a client */ + +/* Bits defined in hi_customer_flags */ +#define HI_CE_FLAG_SPCIFIC_ENABLE 0x01 + +#define ON_RESET_FLAGS_VALID() (HOST_INTEREST->hi_reset_flag_valid == HI_RESET_FLAG_IS_VALID) + +#define RESET_FLAGS_VALIDATE() (HOST_INTEREST->hi_reset_flag_valid = HI_RESET_FLAG_IS_VALID) + +#define RESET_FLAGS_INVALIDATE() (HOST_INTEREST->hi_reset_flag_valid = 0) + +#define ON_RESET_PRESERVE_APP_START() (HOST_INTEREST->hi_reset_flag & HI_RESET_FLAG_PRESERVE_APP_START) + +#define ON_RESET_PRESERVE_NVRAM_STATE() (HOST_INTEREST->hi_reset_flag & HI_RESET_FLAG_PRESERVE_NVRAM_STATE) + +#define ON_RESET_PRESERVE_HOST_INTEREST() (HOST_INTEREST->hi_reset_flag & HI_RESET_FLAG_PRESERVE_HOST_INTEREST) + +#define ON_RESET_PRESERVE_ROMDATA() (HOST_INTEREST->hi_reset_flag & HI_RESET_FLAG_PRESERVE_ROMDATA) + +#define ON_RESET_PRESERVE_BOOT_INFO() (HOST_INTEREST->hi_reset_flag & HI_RESET_FLAG_PRESERVE_BOOT_INFO) + +#define ON_RESET_WARM_RESET() (HOST_INTEREST->hi_reset_flag & HI_RESET_FLAG_WARM_RESET) + +#define IS_ATTUNNEL_MODE_ENABLED() (HOST_INTEREST->hi_acs_flags & HI_ACS_FLAGS_ATTUNNEL_MODE) + +#define IS_WWAN_RADIO_OFF() (HOST_INTEREST->hi_acs_flags & HI_ACS_FLAGS_RADIO_OFF) + +/* CONSOLE FLAGS + * + * Bit Range Meaning + * --------- -------------------------------- + * 2..0 UART ID (0 = Default) + * 3 Baud Select (0 = 9600, 1 = 115200) + * 30..4 Reserved + * 31 Enable Console + * + * */ + +#define HI_CONSOLE_FLAGS_ENABLE (1 << 31) +#define HI_CONSOLE_FLAGS_UART_MASK (0x7) +#define HI_CONSOLE_FLAGS_UART_SHIFT 0 +#define HI_CONSOLE_FLAGS_BAUD_SELECT (1 << 3) + +/* SM power save options */ +#define HI_SMPS_ALLOW_MASK (0x00000001) +#define HI_SMPS_MODE_MASK (0x00000002) +#define HI_SMPS_MODE_STATIC (0x00000000) +#define HI_SMPS_MODE_DYNAMIC (0x00000002) +#define HI_SMPS_DISABLE_AUTO_MODE (0x00000004) +#define HI_SMPS_DATA_THRESH_MASK (0x000007f8) +#define HI_SMPS_DATA_THRESH_SHIFT (3) +#define HI_SMPS_RSSI_THRESH_MASK (0x0007f800) +#define HI_SMPS_RSSI_THRESH_SHIFT (11) +#define HI_SMPS_LOWPWR_CM_MASK (0x00380000) +#define HI_SMPS_LOWPWR_CM_SHIFT (15) +#define HI_SMPS_HIPWR_CM_MASK (0x03c00000) +#define HI_SMPS_HIPWR_CM_SHIFT (19) + +#define HOST_INTEREST_SMPS_GET_MODE() (HOST_INTEREST->hi_smps_options & HI_SMPS_MODE_MASK) +#define HOST_INTEREST_SMPS_GET_DATA_THRESH() \ + ((HOST_INTEREST->hi_smps_options & HI_SMPS_DATA_THRESH_MASK) >> HI_SMPS_DATA_THRESH_SHIFT) +#define HOST_INTEREST_SMPS_SET_DATA_THRESH(x) (((x) << HI_SMPS_DATA_THRESH_SHIFT) & HI_SMPS_DATA_THRESH_MASK) +#define HOST_INTEREST_SMPS_GET_RSSI_THRESH() \ + ((HOST_INTEREST->hi_smps_options & HI_SMPS_RSSI_THRESH_MASK) >> HI_SMPS_RSSI_THRESH_SHIFT) +#define HOST_INTEREST_SMPS_SET_RSSI_THRESH(x) (((x) << HI_SMPS_RSSI_THRESH_SHIFT) & HI_SMPS_RSSI_THRESH_MASK) +#define HOST_INTEREST_SMPS_SET_LOWPWR_CM() \ + ((HOST_INTEREST->hi_smps_options & HI_SMPS_LOWPWR_CM_MASK) >> HI_SMPS_LOWPWR_CM_SHIFT) +#define HOST_INTEREST_SMPS_SET_HIPWR_CM() \ + ((HOST_INTEREST->hi_smps_options << HI_SMPS_HIPWR_CM_MASK) & HI_SMPS_HIPWR_CM_SHIFT) +#define HOST_INTEREST_SMPS_IS_AUTO_MODE_DISABLED() (HOST_INTEREST->hi_smps_options & HI_SMPS_DISABLE_AUTO_MODE) + +/* WOW Extension configuration + * + * Bit Range Meaning + * --------- -------------------------------- + * 8..0 Size of each WOW pattern (max 511) + * 15..9 Number of patterns per list (max 127) + * 17..16 Number of lists (max 4) + * 30..18 Reserved + * 31 Enabled + * + * set values (except enable) to zeros for default settings + * + * */ + +#define HI_WOW_EXT_ENABLED_MASK (1 << 31) +#define HI_WOW_EXT_NUM_LIST_SHIFT 16 +#define HI_WOW_EXT_NUM_LIST_MASK (0x3 << HI_WOW_EXT_NUM_LIST_SHIFT) +#define HI_WOW_EXT_NUM_PATTERNS_SHIFT 9 +#define HI_WOW_EXT_NUM_PATTERNS_MASK (0x7F << HI_WOW_EXT_NUM_PATTERNS_SHIFT) +#define HI_WOW_EXT_PATTERN_SIZE_SHIFT 0 +#define HI_WOW_EXT_PATTERN_SIZE_MASK (0x1FF << HI_WOW_EXT_PATTERN_SIZE_SHIFT) + +#define HI_WOW_EXT_MAKE_CONFIG(num_lists, count, size) \ + ((((num_lists) << HI_WOW_EXT_NUM_LIST_SHIFT) & HI_WOW_EXT_NUM_LIST_MASK) | \ + (((count) << HI_WOW_EXT_NUM_PATTERNS_SHIFT) & HI_WOW_EXT_NUM_PATTERNS_MASK) | \ + (((size) << HI_WOW_EXT_PATTERN_SIZE_SHIFT) & HI_WOW_EXT_PATTERN_SIZE_MASK)) + +#define HI_WOW_EXT_GET_NUM_LISTS(config) (((config)&HI_WOW_EXT_NUM_LIST_MASK) >> HI_WOW_EXT_NUM_LIST_SHIFT) +#define HI_WOW_EXT_GET_NUM_PATTERNS(config) (((config)&HI_WOW_EXT_NUM_PATTERNS_MASK) >> HI_WOW_EXT_NUM_PATTERNS_SHIFT) +#define HI_WOW_EXT_GET_PATTERN_SIZE(config) (((config)&HI_WOW_EXT_PATTERN_SIZE_MASK) >> HI_WOW_EXT_PATTERN_SIZE_SHIFT) + +/* RX Coalescing filter configuration + * + * Bit Range Meaning + * --------- -------------------------------- + * 7..0 Number of filters (0 = use default) + * 11..8 Number of tests per filter (0 = use default) + * 15..12 Buffer threshold multiplier (Rx filter threshold = RX buffers * multipler / divisor) + * 19..16 Buffer threshold divisor + * 23..20 RX idle recheck interval (in 25MS increments) + * 31 Enabled + * + * set values (except enable) to zeros for default settings + * + * */ + +#define HI_RX_COALESCE_FILTER_ENABLED_MASK (1 << 31) +#define HI_RX_COALESCE_FILTER_COUNT_SHIFT 0 +#define HI_RX_COALESCE_FILTER_COUNT_MASK (0xFF << HI_RX_COALESCE_FILTER_COUNT_SHIFT) +#define HI_RX_COALESCE_FILTER_TESTS_SHIFT 8 +#define HI_RX_COALESCE_FILTER_TESTS_MASK (0xF << HI_RX_COALESCE_FILTER_TESTS_SHIFT) +#define HI_RX_COALESCE_FILTER_BUF_MULT_SHIFT 12 +#define HI_RX_COALESCE_FILTER_BUF_MULT_MASK (0xF << HI_RX_COALESCE_FILTER_BUF_MULT_SHIFT) +#define HI_RX_COALESCE_FILTER_BUF_DIV_SHIFT 16 +#define HI_RX_COALESCE_FILTER_BUF_DIV_MASK (0xF << HI_RX_COALESCE_FILTER_BUF_DIV_SHIFT) +#define HI_RX_COALESCE_FILTER_REARM_INTVL_SHIFT 20 +#define HI_RX_COALESCE_FILTER_REARM_INTVL_MASK (0xF << HI_RX_COALESCE_FILTER_REARM_INTVL_SHIFT) + +#define HI_GET_RX_COALESCE_FILTER_COUNT(config) \ + (((config)&HI_RX_COALESCE_FILTER_COUNT_MASK) >> HI_RX_COALESCE_FILTER_COUNT_SHIFT) + +#define HI_GET_RX_COALESCE_FILTER_TESTS(config) \ + (((config)&HI_RX_COALESCE_FILTER_TESTS_MASK) >> HI_RX_COALESCE_FILTER_TESTS_SHIFT) + +#define HI_GET_RX_COALESCE_FILTER_BUF_MULTIPLIER(config) \ + (((config)&HI_RX_COALESCE_FILTER_BUF_MULT_MASK) >> HI_RX_COALESCE_FILTER_BUF_MULT_SHIFT) + +#define HI_GET_RX_COALESC_FILTER_BUF_DIVIDER(config) \ + (((config)&HI_RX_COALESCE_FILTER_BUF_DIV_MASK) >> HI_RX_COALESCE_FILTER_BUF_DIV_SHIFT) + +#define HI_GET_RX_COALESCE_FILTER_REARM_INTERVAL(config) \ + (((config)&HI_RX_COALESCE_FILTER_REARM_INTVL_MASK) >> HI_RX_COALESCE_FILTER_REARM_INTVL_SHIFT) + +#define HI_RX_COALESCE_FILTER_MAKE_CONFIG(nfilt, tpf, mult, div, rx_check) \ + \ +((((nfilt) << HI_RX_COALESCE_FILTER_COUNT_SHIFT) & HI_RX_COALESCE_FILTER_COUNT_MASK) | \ + (((tpf) << HI_RX_COALESCE_FILTER_TESTS_SHIFT) & HI_RX_COALESCE_FILTER_TESTS_MASK) | \ + (((mult) << HI_RX_COALESCE_FILTER_BUF_MULT_SHIFT) & HI_RX_COALESCE_FILTER_BUF_MULT_MASK) | \ + (((div) << HI_RX_COALESCE_FILTER_BUF_DIV_SHIFT) & HI_RX_COALESCE_FILTER_BUF_DIV_MASK) | \ + (((rx_check) << HI_RX_COALESCE_FILTER_REARM_INTVL_SHIFT) & HI_RX_COALESCE_FILTER_REARM_INTVL_MASK)\ +) + +/* input values for hi_i2c_slv_cfg */ +#define HI_SET_I2C_SLV_CFG(_sda, _sck) (((_sda) << 16) & 0xffff0000) | ((_sck)&0x0000ffff) +#define HI_GET_I2C_SLV_CFG_SDA() ((HOST_INTEREST->hi_i2c_slv_cfg >> 16) & 0x0000ffff) +#define HI_GET_I2C_SLV_CFG_SCK() ((HOST_INTEREST->hi_i2c_slv_cfg) & 0x0000ffff) + +/* + * Intended for use by Host software, this macro returns the Target RAM + * address of any item in the host_interest structure. + * Example: target_addr = AR4100_HOST_INTEREST_ITEM_ADDRESS(hi_board_data); + */ +#define AR4100_HOST_INTEREST_ITEM_ADDRESS(item) \ + ((uint32_t) & ((((struct host_interest_s *)(AR4100_HOST_INTEREST_ADDRESS))->item))) + +#define AR4002_HOST_INTEREST_ITEM_ADDRESS(item) \ + ((uint32_t) & ((((struct host_interest_s *)(AR4002_HOST_INTEREST_ADDRESS))->item))) + +#define HOST_INTEREST_DBGLOG_IS_ENABLED() (!(HOST_INTEREST->hi_option_flag & HI_OPTION_DISABLE_DBGLOG)) + +#define HOST_INTEREST_PKTLOG_IS_ENABLED() ((HOST_INTEREST->hi_pktlog_num_buffers)) + +#define HOST_INTEREST_PROFILE_IS_ENABLED() (HOST_INTEREST->hi_option_flag & HI_OPTION_ENABLE_PROFILE) + +#define LF_TIMER_STABILIZATION_IS_ENABLED() (!(HOST_INTEREST->hi_option_flag & HI_OPTION_NO_LFT_STBL)) + +#define IS_AMSDU_OFFLAOD_ENABLED() ((HOST_INTEREST->hi_option_flag2 & HI_OPTION_OFFLOAD_AMSDU)) + +#define HOST_INTEREST_DFS_IS_ENABLED() ((HOST_INTEREST->hi_option_flag2 & HI_OPTION_DFS_SUPPORT)) + +#define HOST_INTEREST_REALTIME_DEBUGGING_IS_ENABLED() \ + ((HOST_INTEREST->hi_option_flag2 & HI_OPTION_ENABLE_REALTIME_DEBUGGING)) + +#define HOST_INTEREST_RTT_IS_DISABLED() ((HOST_INTEREST->hi_option_flag2 & HI_OPTION_DISABLE_RTT)) + +#define HOST_INTEREST_MAC_OTP_IS_DISABLED() ((HOST_INTEREST->hi_option_flag2 & HI_OPTION_DISABLE_MAC_OTP)) + +#define HOST_INTEREST_DISABLE_P2P_DEDICATE() ((HOST_INTEREST->hi_option_flag2 & HI_OPTION_DISABLE_P2P_DEDICATE)) + +#define HOST_INTEREST_INCREASE_TXBUF_IS_ENABLED() ((HOST_INTEREST->hi_option_flag2 & HI_OPTION_INCREASE_TXBUF)) + +#define HOST_INTEREST_PANASONIC_WAR_ENABLE() ((HOST_INTEREST->hi_option_flag2 & HI_OPTION_ENABLE_PANASONIC_WAR)) + +#define HOST_INTEREST_ONE_SHOT_NOA_ENABLED() ((HOST_INTEREST->hi_option_flag2 & HI_OPTION_ENABLE_ONE_SHOT_NOA)) + +#define HOST_INTEREST_SB_SPECIFIC_ENABLED() ((HOST_INTEREST->hi_option_flag2 & HI_OPTION_ENABLE_SB_SPECIFIC)) + +#define HOST_INTEREST_EXT_FW_DOWNLOAD_DONE() ((HOST_INTEREST->hi_option_flag2 & HI_OPTION_EXT_FW_DOWNLOAD_DONE)) +#define HOST_INTEREST_WOW_ACTIVE_IS_LOW() ((HOST_INTEREST->hi_option_flag2 & HI_OPTION_WOW_ACTIVE_LOW)) + +#define HOST_INTEREST_NDIS_WAKE_WAR_IS_ENABLEED() ((HOST_INTEREST->hi_option_flag2 & HI_OPTION_ENABLE_NDIS_WAKE_WAR)) +#define HOST_INTEREST_LTECOEX_ENABLED() ((HOST_INTEREST->hi_option_flag2 & HI_OPTION_ENABLE_LTE_COEX)) + +#define HOST_INTEREST_IS_BAM2BAM_MODE() ((HOST_INTEREST->hi_option_flag2 & HI_OPTION_BAM2BAM_MODE)) + +#define HOST_INTEREST_WLAN_HB_ENABLED() ((HOST_INTEREST->hi_option_flag2 & HI_OPTION_ENABLE_WLAN_HB)) + +#define HOST_INTEREST_MCC_ENABLE() ((HOST_INTEREST->hi_option_flag2 & HI_OPTION_MCC_ENABLE)) + +#define HOST_INTEREST_IGNORE_11D_BEACON() ((HOST_INTEREST->hi_option_flag2 & HI_OPTION_IGNORE_11D_BEACON)) + +#define HOST_INTEREST_ENABLE_SOFTAP_CH13() ((HOST_INTEREST->hi_option_flag2 & HI_OPTION_ENABLE_SOFTAP_CH13)) + +#define HOST_INTEREST_OFFLOAD_P2P_IS_ENABLED() ((HOST_INTEREST->hi_option_flag3 & HI_OPTION_USE_OFFLOAD_P2P)) + +/*power save flag bit definitions*/ +#define HI_PWR_SAVE_LPL_ENABLED 0x1 +/*b1-b3 reserved*/ +/*b4-b5 : dev0 LPL type : 0 - none + 1- Reduce Pwr Search + 2- Reduce Pwr Listen*/ +/*b6-b7 : dev1 LPL type and so on for Max 8 devices*/ +#define HI_PWR_SAVE_LPL_DEV0_LSB 4 +#define HI_PWR_SAVE_LPL_DEV_MASK 0x3 +/*power save related utility macros*/ +#define HI_LPL_ENABLED() ((HOST_INTEREST->hi_pwr_save_flags & HI_PWR_SAVE_LPL_ENABLED)) +#define HI_DEV_LPL_TYPE_GET(_devix) \ + (HOST_INTEREST->hi_pwr_save_flags & ((HI_PWR_SAVE_LPL_DEV_MASK) << (HI_PWR_SAVE_LPL_DEV0_LSB + (_devix)*2))) + +#define HOST_INTEREST_SMPS_IS_ALLOWED() ((HOST_INTEREST->hi_smps_options & HI_SMPS_ALLOW_MASK)) + +/* Convert a Target virtual address into a Target physical address */ + +#define AR4100_VTOP(vaddr) ((vaddr)&0x001fffff) +#define AR4002_VTOP(vaddr) (vaddr) + +#if ATH_FIRMWARE_TARGET == TARGET_AR4100_REV2 +#define EXPECTED_MAX_WRITE_BUFFER_SPACE 3163 +#define TARG_VTOP(vaddr) AR4100_VTOP(vaddr) +#define HOST_INTEREST_ITEM_ADDRESS(item) AR4100_HOST_INTEREST_ITEM_ADDRESS(item) +#elif ATH_FIRMWARE_TARGET == TARGET_AR400X_REV1 +#define EXPECTED_MAX_WRITE_BUFFER_SPACE 3163 // FIXME: confirm this value +#define TARG_VTOP(vaddr) AR4002_VTOP(vaddr) +#define HOST_INTEREST_ITEM_ADDRESS(item) AR4002_HOST_INTEREST_ITEM_ADDRESS(item) +#define AR400X_BOARD_DATA_ADDRESS 0x46B800 +#define AR400X_BOARD_DATA_SIZE 6144 +#define AR400X_EXT_BOARD_DATA_SIZE 0 +#define AR400X_RAM_RESERVE_SIZE 18432 +#else +#error Must have defined value for ATH_FIRMWARE_TARGET +#endif + +/* # of uint32_t entries in targregs, used by DIAG_FETCH_TARG_REGS */ +#define AR4100_FETCH_TARG_REGS_COUNT 64 + +#define AR4100_CONFIGFOUND_ADDR 0x540720 +#define AR4100_CONFIGFOUND_VAL 0 +#define AR4100_CONFIGFOUND_STK_ADDR 0x544239 +#define AR4100_NVRAM_SAMPLE_VAL 0x1e0104 +#define AR4100_NVRAM_SAMPLE_ADDR 0x54070c + +/* hi_flash_is_present value definition */ + +#define HOST_PROXY_INIT 0x01 +#define HOST_PROXY_NORMAL_BOOT 0x02 +#define HOST_PROXY_BMI_BOOT 0x03 +#define HOST_PROXY_BOOTCTL_MASK 0x03 + +#endif /* !__ASSEMBLER__ */ + +#endif /* __TARGADDRS_H__ */ diff --git a/platform/mcu/lpc54102/wifi_qca/include/wlan_defs.h b/platform/mcu/lpc54102/wifi_qca/include/wlan_defs.h new file mode 100644 index 0000000000..80f234cf86 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/include/wlan_defs.h @@ -0,0 +1,78 @@ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== + +#ifndef __WLAN_DEFS_H__ +#define __WLAN_DEFS_H__ + +/* + * This file contains WLAN definitions that may be used across both + * Host and Target software. + */ + +typedef enum +{ + MODE_11A = 0, /* 11a Mode */ + MODE_11G = 1, /* 11b/g Mode */ + MODE_11B = 2, /* 11b Mode */ + MODE_11GONLY = 3, /* 11g only Mode */ +#ifdef SUPPORT_11N + MODE_11NA_HT20 = 4, /* 11a HT20 mode */ + MODE_11NG_HT20 = 5, /* 11g HT20 mode */ + MODE_11NA_HT40 = 6, /* 11a HT40 mode */ + MODE_11NG_HT40 = 7, /* 11g HT40 mode */ + MODE_UNKNOWN = 8, + MODE_MAX = 8 +#else + MODE_UNKNOWN = 4, + MODE_MAX = 4 +#endif +} WLAN_PHY_MODE; + +typedef enum +{ + WLAN_11A_CAPABILITY = 1, + WLAN_11G_CAPABILITY = 2, + WLAN_11AG_CAPABILITY = 3 +} WLAN_CAPABILITY; + +#ifdef SUPPORT_11N +typedef unsigned long A_RATEMASK; +#else +typedef unsigned short A_RATEMASK; +#endif + +#ifdef SUPPORT_11N +#define IS_MODE_11A(mode) (((mode) == MODE_11A) || ((mode) == MODE_11NA_HT20) || ((mode) == MODE_11NA_HT40)) +#define IS_MODE_11B(mode) ((mode) == MODE_11B) +#define IS_MODE_11G(mode) \ + (((mode) == MODE_11G) || ((mode) == MODE_11GONLY) || ((mode) == MODE_11NG_HT20) || ((mode) == MODE_11NG_HT40)) +#define IS_MODE_11GONLY(mode) ((mode) == MODE_11GONLY) +#else +#define IS_MODE_11A(mode) ((mode) == MODE_11A) +#define IS_MODE_11B(mode) ((mode) == MODE_11B) +#define IS_MODE_11G(mode) (((mode) == MODE_11G) || ((mode) == MODE_11GONLY)) +#define IS_MODE_11GONLY(mode) ((mode) == MODE_11GONLY) +#endif /* SUPPORT_11N */ + +#endif /* __WLANDEFS_H__ */ diff --git a/platform/mcu/lpc54102/wifi_qca/include/wmi.h b/platform/mcu/lpc54102/wifi_qca/include/wmi.h new file mode 100644 index 0000000000..85c88bdfca --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/include/wmi.h @@ -0,0 +1,3082 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== + +/* + * This file contains the definitions of the WMI protocol specified in the + * Wireless Module Interface (WMI). It includes definitions of all the + * commands and events. Commands are messages from the host to the WM. + * Events and Replies are messages from the WM to the host. + * + * Ownership of correctness in regards to commands + * belongs to the host driver and the WMI is not required to validate + * parameters for value, proper range, or any other checking. + * + */ + +#ifndef _WMI_H_ +#define _WMI_H_ + +//#include "wmix.h" +#include "wlan_defs.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define HTC_PROTOCOL_VERSION 0x0002 +#define HTC_PROTOCOL_REVISION 0x0000 + +#define WMI_PROTOCOL_VERSION 0x0002 +#define WMI_PROTOCOL_REVISION 0x0000 + +#define ATH_MAC_LEN 6 /* length of mac in bytes */ +#define WMI_CMD_MAX_LEN 100 +#define WMI_CONTROL_MSG_MAX_LEN 256 +#define WMI_OPT_CONTROL_MSG_MAX_LEN 1536 +#define MAX_EVENT_SIZE 1200 +#define IS_ETHERTYPE(_typeOrLen) ((_typeOrLen) >= 0x0600) +#define RFC1042OUI \ + { \ + 0x00, 0x00, 0x00 \ + } + +#define IP_ETHERTYPE 0x0800 + +#define WMI_IMPLICIT_PSTREAM 0xFF +#define WMI_MAX_THINSTREAM 15 + +#define WOW_MAX_PATTERN_LEN 64 + +#ifdef AR6002_REV2 +#define IBSS_MAX_NUM_STA 4 +#else +#define IBSS_MAX_NUM_STA 8 +#endif + +struct host_app_area_s +{ + uint32_t wmi_protocol_ver; +}; + +typedef PREPACK struct +{ + uint8_t a FIELD_PACKED; + uint8_t b FIELD_PACKED; + uint8_t c FIELD_PACKED; +} POSTPACK MY_TEST; + +/* + * Data Path + */ +typedef PREPACK struct +{ + uint8_t dstMac[ATH_MAC_LEN] FIELD_PACKED; + uint8_t srcMac[ATH_MAC_LEN] FIELD_PACKED; + uint16_t typeOrLen FIELD_PACKED; +} POSTPACK ATH_MAC_HDR; + +typedef PREPACK struct +{ + uint8_t dsap FIELD_PACKED; + uint8_t ssap FIELD_PACKED; + uint8_t cntl FIELD_PACKED; + uint8_t orgCode[3] FIELD_PACKED; + uint16_t etherType FIELD_PACKED; +} POSTPACK ATH_LLC_SNAP_HDR; + +typedef enum +{ + DATA_MSGTYPE = 0x0, + CNTL_MSGTYPE, + SYNC_MSGTYPE, + OPT_MSGTYPE +} WMI_MSG_TYPE; + +/* + * Macros for operating on WMI_DATA_HDR (info) field + */ + +#define WMI_DATA_HDR_MSG_TYPE_MASK 0x03 +#define WMI_DATA_HDR_MSG_TYPE_SHIFT 0 +#define WMI_DATA_HDR_UP_MASK 0x07 +#define WMI_DATA_HDR_UP_SHIFT 2 +/* In AP mode, the same bit (b5) is used to indicate Power save state in + * the Rx dir and More data bit state in the tx direction. + */ +#define WMI_DATA_HDR_PS_MASK 0x1 +#define WMI_DATA_HDR_PS_SHIFT 5 + +#define WMI_DATA_HDR_MORE_MASK 0x1 +#define WMI_DATA_HDR_MORE_SHIFT 5 + +typedef enum +{ + WMI_DATA_HDR_DATA_TYPE_802_3 = 0, + WMI_DATA_HDR_DATA_TYPE_802_11, + WMI_DATA_HDR_DATA_TYPE_ACL +} WMI_DATA_HDR_DATA_TYPE; + +#define WMI_DATA_HDR_DATA_TYPE_MASK 0x3 +#define WMI_DATA_HDR_DATA_TYPE_SHIFT 6 + +#define WMI_DATA_HDR_SET_MORE_BIT(h) ((h)->info |= (WMI_DATA_HDR_MORE_MASK << WMI_DATA_HDR_MORE_SHIFT)) + +#define WMI_DATA_HDR_IS_MSG_TYPE(h, t) (((h)->info & (WMI_DATA_HDR_MSG_TYPE_MASK)) == (t)) +#define WMI_DATA_HDR_SET_MSG_TYPE(h, t) \ + (h)->info = (uint8_t)(((h)->info & ~(WMI_DATA_HDR_MSG_TYPE_MASK << WMI_DATA_HDR_MSG_TYPE_SHIFT)) | \ + (t << WMI_DATA_HDR_MSG_TYPE_SHIFT)) +#define WMI_DATA_HDR_GET_UP(h) (((h)->info >> WMI_DATA_HDR_UP_SHIFT) & WMI_DATA_HDR_UP_MASK) +#define WMI_DATA_HDR_SET_UP(h, p) \ + (h)->info = (uint8_t)(((h)->info & ~(WMI_DATA_HDR_UP_MASK << WMI_DATA_HDR_UP_SHIFT)) | (p << WMI_DATA_HDR_UP_SHIFT)) + +#define WMI_DATA_HDR_GET_DATA_TYPE(h) (((h)->info >> WMI_DATA_HDR_DATA_TYPE_SHIFT) & WMI_DATA_HDR_DATA_TYPE_MASK) +#define WMI_DATA_HDR_SET_DATA_TYPE(h, p) \ + (h)->info = (uint8_t)(((h)->info & ~(WMI_DATA_HDR_DATA_TYPE_MASK << WMI_DATA_HDR_DATA_TYPE_SHIFT)) | \ + ((p) << WMI_DATA_HDR_DATA_TYPE_SHIFT)) + +#define WMI_DATA_HDR_GET_DOT11(h) (WMI_DATA_HDR_GET_DATA_TYPE((h)) == WMI_DATA_HDR_DATA_TYPE_802_11) +#define WMI_DATA_HDR_SET_DOT11(h, p) WMI_DATA_HDR_SET_DATA_TYPE((h), (p)) + +/* Macros for operating on WMI_DATA_HDR (info2) field */ +#define WMI_DATA_HDR_SEQNO_MASK 0xFFF +#define WMI_DATA_HDR_SEQNO_SHIFT 0 + +#define WMI_DATA_HDR_AMSDU_MASK 0x1 +#define WMI_DATA_HDR_AMSDU_SHIFT 12 + +#define WMI_DATA_HDR_META_MASK 0x7 +#define WMI_DATA_HDR_META_SHIFT 13 + +#define GET_SEQ_NO(_v) ((_v)&WMI_DATA_HDR_SEQNO_MASK) +#define GET_ISMSDU(_v) ((_v)&WMI_DATA_HDR_AMSDU_MASK) + +#define WMI_DATA_HDR_GET_SEQNO(h) GET_SEQ_NO((h)->info2 >> WMI_DATA_HDR_SEQNO_SHIFT) +#define WMI_DATA_HDR_SET_SEQNO(h, _v) \ + ((h)->info2 = ((h)->info2 & ~(WMI_DATA_HDR_SEQNO_MASK << WMI_DATA_HDR_SEQNO_SHIFT)) | \ + (GET_SEQ_NO(_v) << WMI_DATA_HDR_SEQNO_SHIFT)) + +#define WMI_DATA_HDR_IS_AMSDU(h) GET_ISMSDU((h)->info2 >> WMI_DATA_HDR_AMSDU_SHIFT) +#define WMI_DATA_HDR_SET_AMSDU(h, _v) \ + ((h)->info2 = (uint16_t)((h)->info2 & ~(WMI_DATA_HDR_AMSDU_MASK << WMI_DATA_HDR_AMSDU_SHIFT)) | \ + (GET_ISMSDU(_v) << WMI_DATA_HDR_AMSDU_SHIFT)) + +#define WMI_DATA_HDR_GET_META(h) (((h)->info2 >> WMI_DATA_HDR_META_SHIFT) & WMI_DATA_HDR_META_MASK) +#define WMI_DATA_HDR_SET_META(h, _v) \ + ((h)->info2 = (uint16_t)(((h)->info2 & ~(WMI_DATA_HDR_META_MASK << WMI_DATA_HDR_META_SHIFT)) | \ + ((_v) << WMI_DATA_HDR_META_SHIFT))) + +/* Macros for operating on WMI_DATA_HDR (info3) field */ +#define WMI_DATA_HDR_DEVID_MASK 0xF +#define WMI_DATA_HDR_DEVID_SHIFT 0 +#define GET_DEVID(_v) ((_v)&WMI_DATA_HDR_DEVID_MASK) + +#define WMI_DATA_HDR_GET_DEVID(h) (((h)->info3 >> WMI_DATA_HDR_DEVID_SHIFT) & WMI_DATA_HDR_DEVID_MASK) +#define WMI_DATA_HDR_SET_DEVID(h, _v) \ + ((h)->info3 = ((h)->info3 & ~(WMI_DATA_HDR_DEVID_MASK << WMI_DATA_HDR_DEVID_SHIFT)) | \ + (GET_DEVID(_v) << WMI_DATA_HDR_DEVID_SHIFT)) + +#define WMI_DATA_HDR_RXFILT_SHIFT 4 +#define WMI_DATA_HDR_RXFILT_MASK (0x1 << WMI_DATA_HDR_RXFILT_SHIFT) + +#define WMI_DATA_HDR_IS_RXFILTERED(h) ((h)->info3 & WMI_DATA_HDR_RXFILT_MASK) +#define SET_WMI_DATA_HDR_RXFILTERED(h) (h)->info3 |= WMI_DATA_HDR_RXFILT_MASK + +#define WMI_DATA_HDR_TRIGGER_MASK 0x1 +#define WMI_DATA_HDR_TRIGGER_SHIFT 4 +#define WMI_DATA_HDR_SET_TRIGGER(h, _v) \ + ((h)->info3 = ((h)->info3 & ~(WMI_DATA_HDR_TRIGGER_MASK << WMI_DATA_HDR_TRIGGER_SHIFT)) | \ + ((_v) << WMI_DATA_HDR_TRIGGER_SHIFT)) +#define WMI_DATA_HDR_IS_TRIGGER(h) \ + ((((h)->info3 >> WMI_DATA_HDR_TRIGGER_SHIFT) & WMI_DATA_HDR_TRIGGER_MASK) == WMI_DATA_HDR_TRIGGER_MASK) + +#define WMI_DATA_HDR_EOSP_MASK WMI_DATA_HDR_TRIGGER_MASK +#define WMI_DATA_HDR_EOSP_SHIFT WMI_DATA_HDR_TRIGGER_SHIFT + +#define WMI_DATA_HDR_SET_EOSP_BIT(h) ((h)->info3 |= (WMI_DATA_HDR_EOSP_MASK << WMI_DATA_HDR_EOSP_SHIFT)) +#define WMI_DATA_HDR_HAS_EOSP_BIT(h) ((h)->info3 & (WMI_DATA_HDR_EOSP_MASK << WMI_DATA_HDR_EOSP_SHIFT)) + +#define WMI_DATA_HDR_CCX_LINKTEST_MASK 0x1 +#define WMI_DATA_HDR_CCX_LINKTEST_SHIFT 5 +#define WMI_DATA_HDR_SET_CCX_LINKTEST_BIT(h) \ + ((h)->info3 |= (WMI_DATA_HDR_CCX_LINKTEST_MASK << WMI_DATA_HDR_CCX_LINKTEST_SHIFT)) +#define WMI_DATA_HDR_HAS_CCX_LINKTEST_BIT(h) \ + ((h)->info3 & (WMI_DATA_HDR_CCX_LINKTEST_MASK << WMI_DATA_HDR_CCX_LINKTEST_SHIFT)) + +#define WMI_DATA_HDR_PAD_BEFORE_DATA_MASK 0xFF +#define WMI_DATA_HDR_PAD_BEFORE_DATA_SHIFT 0x8 +#define GET_PAD_BEFORE_DATA_START(_v) ((_v)&WMI_DATA_HDR_PAD_BEFORE_DATA_MASK) + +#define WMI_DATA_HDR_GET_PAD_BEFORE_DATA_START(h) \ + (((h)->info3 >> WMI_DATA_HDR_PAD_BEFORE_DATA_SHIFT) & WMI_DATA_HDR_PAD_BEFORE_DATA_MASK) +#define WMI_DATA_HDR_SET_PAD_BEFORE_DATA_START(h, _v) \ + ((h)->info3 = ((h)->info3 & ~(WMI_DATA_HDR_PAD_BEFORE_DATA_MASK << WMI_DATA_HDR_PAD_BEFORE_DATA_SHIFT)) | \ + (GET_PAD_BEFORE_DATA_START(_v) << WMI_DATA_HDR_PAD_BEFORE_DATA_SHIFT)) + +#define WMI_DATA_HDR_TRIGGERED_MASK 0x1 +#define WMI_DATA_HDR_TRIGGERED_SHIFT 6 +#define WMI_DATA_HDR_SET_TRIGGERED_BIT(h) ((h)->info3 |= (WMI_DATA_HDR_TRIGGERED_MASK << WMI_DATA_HDR_TRIGGERED_SHIFT)) +#define WMI_DATA_HDR_HAS_TRIGGERED_BIT(h) ((h)->info3 & (WMI_DATA_HDR_TRIGGERED_MASK << WMI_DATA_HDR_TRIGGERED_SHIFT)) + +#define WMI_DATA_HDR_PSPOLLED_MASK 0x1 +#define WMI_DATA_HDR_PSPOLLED_SHIFT 7 +#define WMI_DATA_HDR_SET_PSPOLLED_BIT(h) ((h)->info3 |= (WMI_DATA_HDR_PSPOLLED_MASK << WMI_DATA_HDR_PSPOLLED_SHIFT)) +#define WMI_DATA_HDR_HAS_PSPOLLED_BIT(h) ((h)->info3 & (WMI_DATA_HDR_PSPOLLED_MASK << WMI_DATA_HDR_PSPOLLED_SHIFT)) + +#define WMI_DATA_HDR_PAD_BEFORE_DATA_MASK 0xFF +#define WMI_DATA_HDR_PAD_BEFORE_DATA_SHIFT 0x8 +#define GET_PAD_BEFORE_DATA_START(_v) ((_v)&WMI_DATA_HDR_PAD_BEFORE_DATA_MASK) + +#define WMI_DATA_HDR_HOST_RETRY_MASK 0x1 +#define WMI_DATA_HDR_GET_HOST_RETRY(h) (WMI_DATA_HDR_GET_PAD_BEFORE_DATA_START(h) & WMI_DATA_HDR_HOST_RETRY_MASK) + +#define WMI_DATA_HDR_GET_PAD_BEFORE_DATA_START(h) \ + (((h)->info3 >> WMI_DATA_HDR_PAD_BEFORE_DATA_SHIFT) & WMI_DATA_HDR_PAD_BEFORE_DATA_MASK) +#define WMI_DATA_HDR_SET_PAD_BEFORE_DATA_START(h, _v) \ + ((h)->info3 = ((h)->info3 & ~(WMI_DATA_HDR_PAD_BEFORE_DATA_MASK << WMI_DATA_HDR_PAD_BEFORE_DATA_SHIFT)) | \ + (GET_PAD_BEFORE_DATA_START(_v) << WMI_DATA_HDR_PAD_BEFORE_DATA_SHIFT)) + +#define WMI_DATA_HDR_EXCEPTION_BIT_MASK 0x1 +#define WMI_DATA_HDR_EXCEPTION_BIT_SHIFT 8 +#define WMI_DATA_HDR_SET_EXCEPTION_BIT(h) \ + ((h)->info3 |= (WMI_DATA_HDR_EXCEPTION_BIT_MASK << WMI_DATA_HDR_EXCEPTION_BIT_SHIFT)) + +#define WMI_DATA_HDR_AMPDU_FLUSH_BIT_MASK 0x1 +#define WMI_DATA_HDR_AMPDU_FLUSH_BIT_SHIFT 9 +#define WMI_DATA_HDR_SET_AMPDU_FLUSH_BIT(h) \ + ((h)->info3 |= (WMI_DATA_HDR_AMPDU_FLUSH_BIT_MASK << WMI_DATA_HDR_AMPDU_FLUSH_BIT_SHIFT)) + +#define WMI_DATA_HDR_WLAN_BIT_MASK 0x0 +#define WMI_DATA_HDR_WLAN_BIT_SHIFT 10 +#define WMI_DATA_HDR_SET_WLAN_BIT(h) ((h)->info3 |= (WMI_DATA_HDR_WLAN_BIT_MASK << WMI_DATA_HDR_WLAN_BIT_SHIFT)) + +#define WMI_DATA_HDR_WAN_BIT_MASK 0x1 +#define WMI_DATA_HDR_WAN_BIT_SHIFT 10 +#define WMI_DATA_HDR_SET_WAN_BIT(h) ((h)->info3 |= (WMI_DATA_HDR_WAN_BIT_MASK << WMI_DATA_HDR_WAN_BIT_SHIFT)) + +#define WMI_DATA_HDR_OUT_OF_ORDER_BIT_MASK 0x1 +#define WMI_DATA_HDR_OUT_OF_ORDER_BIT_SHIFT 11 +#define WMI_DATA_HDR_SET_OUT_OF_ORDER_BIT(h) \ + ((h)->info3 |= (WMI_DATA_HDR_OUT_OF_ORDER_BIT_MASK << WMI_DATA_HDR_OUT_OF_ORDER_BIT_SHIFT)) + +#define WMI_DATA_HDR_FLUSH_ALL_BIT_MASK 0x1 +#define WMI_DATA_HDR_FLUSH_ALL_BIT_SHIFT 12 +#define WMI_DATA_HDR_SET_FLUSH_ALL_BIT(h) \ + ((h)->info3 |= (WMI_DATA_HDR_FLUSH_ALL_BIT_MASK << WMI_DATA_HDR_FLUSH_ALL_BIT_SHIFT)) + +#define WMI_DATA_HDR_PARTIAL_FLUSH_BIT_MASK 0x1 +#define WMI_DATA_HDR_PARTIAL_FLUSH_BIT_SHIFT 13 +#define WMI_DATA_HDR_SET_PARTIAL_FLUSH_BIT(h) \ + ((h)->info3 |= (WMI_DATA_HDR_PARTIAL_FLUSH_BIT_MASK << WMI_DATA_HDR_PARTIAL_FLUSH_BIT_SHIFT)) + +typedef PREPACK struct +{ + int8_t rssi FIELD_PACKED; + uint8_t info FIELD_PACKED; /* usage of 'info' field(8-bit): + * b1:b0 - WMI_MSG_TYPE + * b4:b3:b2 - UP(tid) + * b5 - Used in AP mode. More-data in tx dir, PS in rx. + * b7:b6 - Dot3 header(0), + * Dot11 Header(1), + * ACL data(2) + */ + + uint16_t info2 FIELD_PACKED; /* usage of 'info2' field(16-bit): + * b11:b0 - seq_no + * b12 - A-MSDU? + * b15:b13 - META_DATA_VERSION 0 - 7 + */ + uint16_t info3 FIELD_PACKED; /* b3:b2:b1:b0 - device id + * b4 - Used in AP mode. uAPSD trigger in rx, EOSP in tx + * b5 - Used by CCX. + * b6 - Used in AP mode. uAPSD triggered frame in tx, + * meaningless in rx + * b7 - Used in AP mode. PS-POLL triggered frame in tx, + * meaningless in rx + * b15:b8 - pad before data start(irrespective of meta version) + */ +} POSTPACK WMI_DATA_HDR; + +/* + * TX META VERSION DEFINITIONS + */ +#define WMI_MAX_TX_META_SZ (12) +#define WMI_MAX_TX_META_VERSION (7) +#define WMI_META_VERSION_1 (0x01) +#define WMI_META_VERSION_2 (0x02) +#define WMI_META_VERSION_3 (0x03) +#define WMI_META_VERSION_4 (0x04) +#define WMI_META_VERSION_5 (0x05) // USed for stack offload packets + +#define WMI_ACL_TO_DOT11_HEADROOM 36 + +#if 0 /* removed to prevent compile errors for WM.. */ +typedef PREPACK struct { +/* intentionally empty. Default version is no meta data. */ +} POSTPACK WMI_TX_META_V0; +#endif + +typedef PREPACK struct +{ + uint8_t pktID FIELD_PACKED; /* The packet ID to identify the tx request */ + uint8_t ratePolicyID FIELD_PACKED; /* The rate policy to be used for the tx of this frame */ +} POSTPACK WMI_TX_META_V1; + +#define WMI_CSUM_DIR_TX (0x1) +#define TX_CSUM_CALC_FILL (0x1) +typedef PREPACK struct +{ + uint8_t csumStart FIELD_PACKED; /*Offset from start of the WMI header for csum calculation to begin */ + uint8_t csumDest FIELD_PACKED; /*Offset from start of WMI header where final csum goes*/ + uint8_t csumFlags FIELD_PACKED; /*number of bytes over which csum is calculated*/ +} POSTPACK WMI_TX_META_V2; + +/* WMI_META_TX_FLAG... are used as TX qualifiers for frames containing WMI_TX_RATE_SCHEDULE in the + * meta data. 0 or more of these flags should be assigned to the flags member of the schedule. */ +#define WMI_META_TX_FLAG_ACK 0x01 // frame needs ACK response from receiver +#define WMI_META_TX_FLAG_SET_RETRY_BIT 0x02 // device will set retry bit in MAC header for retried frames. +#define WMI_META_TX_FLAG_SET_DURATION 0x04 // device will fill duration field in MAC header +/* NOTE: If WMI_META_TX_FLAG_USE_PREFIX == 0 device will NOT use prefix frame. + * If WMI_META_TX_FLAG_USE_PREFIX == 1 && WMI_META_TX_FLAG_PREFIX_RTS == 0 device will use CTS prefix. + * If WMI_META_TX_FLAG_USE_PREFIX == 1 && WMI_META_TX_FLAG_PREFIX_RTS == 1 device will use RTS prefix. + */ +#define WMI_META_TX_FLAG_USE_PREFIX 0x08 // device will send either RTS or CTS frame prior to subject frame. +#define WMI_META_TX_FLAG_PREFIX_RTS 0x10 // device will send RTS and wait for CTS prior to sending subject frame. +#define WMI_META_TX_LOAD_TSF 0x20 // device will fill the TSF field during transmit procedure. + +/* WMI_TX_RATE_SCHEDULE - Acts as a host-provided rate schedule to replace what would be normally determined + * by firmware. This allows the host to specify what rates and attempts should be used to transmit the + * frame. */ +typedef PREPACK struct +{ +#define WMI_TX_MAX_RATE_SERIES (4) + uint8_t rateSeries[WMI_TX_MAX_RATE_SERIES] FIELD_PACKED; // rate index for each series. first invalid rate + // terminates series. + uint8_t trySeries[WMI_TX_MAX_RATE_SERIES] FIELD_PACKED; // number of tries for each series. + uint8_t flags FIELD_PACKED; // combination of WMI_META_TX_FLAG... + uint8_t accessCategory FIELD_PACKED; // should be WMM_AC_BE for managment frames and multicast frames. + // uint8_t keyIndex FIELD_PACKED; + // +} POSTPACK WMI_TX_RATE_SCHEDULE; + +typedef PREPACK struct +{ + WMI_TX_RATE_SCHEDULE rateSched FIELD_PACKED; + uint8_t pktID FIELD_PACKED; /* The packet ID to identify the tx request */ +} POSTPACK WMI_TX_META_V3; + +typedef PREPACK struct +{ + uint8_t reserved FIELD_PACKED; +} POSTPACK WMI_TX_META_V5; + +/* + * RX META VERSION DEFINITIONS + */ +/* if RX meta data is present at all then the meta data field + * will consume WMI_MAX_RX_META_SZ bytes of space between the + * WMI_DATA_HDR and the payload. How much of the available + * Meta data is actually used depends on which meta data + * version is active. */ +#define WMI_MAX_RX_META_SZ (12) +#define WMI_MAX_RX_META_VERSION (7) + +#define WMI_RX_STATUS_OK 0 /* success */ +#define WMI_RX_STATUS_DECRYPT_ERR 1 /* decrypt error */ +#define WMI_RX_STATUS_MIC_ERR 2 /* tkip MIC error */ +#define WMI_RX_STATUS_ERR 3 /* undefined error */ + +#define WMI_RX_FLAGS_AGGR 0x0001 /* part of AGGR */ +#define WMI_RX_FlAGS_STBC 0x0002 /* used STBC */ +#define WMI_RX_FLAGS_SGI 0x0004 /* used SGI */ +#define WMI_RX_FLAGS_HT 0x0008 /* is HT packet */ + /* the flags field is also used to store the CRYPTO_TYPE of the frame + * that value is shifted by WMI_RX_FLAGS_CRYPTO_SHIFT */ +#define WMI_RX_FLAGS_CRYPTO_SHIFT 4 +#define WMI_RX_FLAGS_CRYPTO_MASK 0x1f +#define WMI_RX_META_GET_CRYPTO(flags) (((flags) >> WMI_RX_FLAGS_CRYPTO_SHIFT) & WMI_RX_FLAGS_CRYPTO_MASK) + +#if 0 /* removed to prevent compile errors for WM.. */ +typedef PREPACK struct { +/* intentionally empty. Default version is no meta data. */ +} POSTPACK WMI_RX_META_VERSION_0; +#endif + +typedef PREPACK struct +{ + uint8_t status FIELD_PACKED; /* one of WMI_RX_STATUS_... */ + uint8_t rix FIELD_PACKED; /* rate index mapped to rate at which this packet was received. */ + uint8_t rssi FIELD_PACKED; /* rssi of packet */ + uint8_t channel FIELD_PACKED; /* rf channel during packet reception */ + uint16_t flags FIELD_PACKED; /* a combination of WMI_RX_FLAGS_... */ +} POSTPACK WMI_RX_META_V1; + +#define RX_CSUM_VALID_FLAG (0x1) +typedef PREPACK struct +{ + uint16_t csum FIELD_PACKED; + uint8_t csumFlags FIELD_PACKED; /* bit 0 set -partial csum valid + bit 1 set -test mode */ +} POSTPACK WMI_RX_META_V2; + +/* Macros for operating on WMI_CMD_HDR (info1) field */ +#define WMI_CMD_HDR_DEVID_MASK 0xF +#define WMI_CMD_HDR_DEVID_SHIFT 0 + +#define WMI_GET_DEVICE_ID(info1) ((info1)&0xF) +#define WMI_SET_DEVICE_ID(h, _v) \ + ((h)->info1 = ((h)->info1 & ~(WMI_CMD_HDR_DEVID_MASK << WMI_CMD_HDR_DEVID_SHIFT)) | \ + (WMI_GET_DEVICE_ID(_v) << WMI_CMD_HDR_DEVID_SHIFT)) + +/* + * Control Path + */ +typedef PREPACK struct +{ + uint16_t commandId FIELD_PACKED; + /* + * info1 - 16 bits + * b03:b00 - id + * b15:b04 - unused + */ + uint16_t info1 FIELD_PACKED; + + uint16_t reserved FIELD_PACKED; /* For alignment */ +} POSTPACK WMI_CMD_HDR; /* used for commands and events */ + +/* + * List of Commnands + */ +typedef enum +{ + WMI_CONNECT_CMDID = 0x0001, + WMI_RECONNECT_CMDID = 0x0002, + WMI_DISCONNECT_CMDID = 0x0003, + WMI_SYNCHRONIZE_CMDID = 0x0004, + WMI_START_SCAN_CMDID = 0x0007, + WMI_SET_SCAN_PARAMS_CMDID = 0x0008, + WMI_SET_BSS_FILTER_CMDID = 0x0009, + WMI_SET_PROBED_SSID_CMDID = 0x000a, /* 10 */ + WMI_SET_LISTEN_INT_CMDID = 0x000b, + WMI_GET_CHANNEL_LIST_CMDID = 0x000e, + WMI_SET_BEACON_INT_CMDID = 0x000f, + WMI_GET_STATISTICS_CMDID = 0x0010, + WMI_SET_CHANNEL_PARAMS_CMDID = 0x0011, + WMI_SET_POWER_MODE_CMDID = 0x0012, + WMI_SET_POWER_PARAMS_CMDID = 0x0014, /* 20 */ + WMI_ADD_CIPHER_KEY_CMDID = 0x0016, + WMI_DELETE_CIPHER_KEY_CMDID = 0x0017, + WMI_SET_TX_PWR_CMDID = 0x001b, + WMI_GET_TX_PWR_CMDID = 0x001c, + WMI_TARGET_ERROR_REPORT_BITMASK_CMDID = 0x0022, + WMI_SET_ROAM_CTRL_CMDID = 0x0029, + WMI_EXTENSION_CMDID = 0x002e, + WMI_SET_RTS_CMDID = 0x0032, /* 50 */ +#if MANUFACTURING_SUPPORT + WMI_TEST_CMDID = 0x003a, +#endif + WMI_SET_KEEPALIVE_CMDID = 0x003d, + WMI_GET_KEEPALIVE_CMDID = 0x003e, + WMI_SET_APPIE_CMDID = 0x003f, +#if ENABLE_AP_MODE + WMI_AP_SET_NUM_STA_CMDID = 0xf00c, + WMI_AP_HIDDEN_SSID_CMDID = 0xf00b, + WMI_AP_CONFIG_COMMIT_CMDID = 0xf00f, + WMI_AP_CONN_INACT_CMDID = 0xf012, + RESERVED = 0xf014, + WMI_AP_SET_DTIM_CMDID = 0xf015, + WMI_AP_PSBUF_OFFLOAD_CMDID = 0xf0AF, +#endif + WMI_ALLOW_AGGR_CMDID = 0xf01b, /* F01B */ + WMI_SET_HT_CAP_CMDID = 0xf01e, + WMI_SET_PMK_CMDID = 0xf028, +#if ATH_FIRMWARE_TARGET == TARGET_AR4100_REV2 + WMI_SET_CHANNEL_CMDID = 0xf042, + WMI_GET_PMK_CMDID = 0xf047, + WMI_SET_PASSPHRASE_CMDID = 0xf048, + WMI_STORERECALL_CONFIGURE_CMDID = 0xf04e, + WMI_STORERECALL_RECALL_CMDID = 0xf04f, + WMI_STORERECALL_HOST_READY_CMDID = 0xf050, + + /* WPS Commands */ + WMI_WPS_START_CMDID = 0xf053, + WMI_GET_WPS_STATUS_CMDID = 0xf054, + /*Socket commands*/ + WMI_SOCKET_CMDID = 0xf055, + WMI_SET_FILTERED_PROMISCUOUS_MODE_CMDID = 0xf056, +#elif ATH_FIRMWARE_TARGET == TARGET_AR400X_REV1 + WMI_SET_CHANNEL_CMDID = 0xf042, + WMI_GET_PMK_CMDID = 0xf047, + WMI_SET_PASSPHRASE_CMDID = 0xf048, + WMI_STORERECALL_CONFIGURE_CMDID = 0xf05e, + WMI_STORERECALL_RECALL_CMDID = 0xf05f, + WMI_STORERECALL_HOST_READY_CMDID = 0xf060, + /* WPS Commands */ + WMI_WPS_START_CMDID = 0xf07a, + WMI_GET_WPS_STATUS_CMDID = 0xf07b, + /*Socket commands*/ + WMI_SOCKET_CMDID = 0xf08d, + WMI_SET_FILTERED_PROMISCUOUS_MODE_CMDID = 0xf099, +#endif + +#if ENABLE_P2P_MODE +/* P2P CMDS */ + +#if ATH_FIRMWARE_TARGET == TARGET_AR4100_REV2 /* Jade */ + WMI_P2P_SET_CONFIG_CMDID = 0xF038, + WMI_WPS_SET_CONFIG_CMDID = 0xF039, + WMI_SET_REQ_DEV_ATTR_CMDID = 0xF03A, + WMI_P2P_FIND_CMDID = 0xF03B, + WMI_P2P_STOP_FIND_CMDID = 0xF03C, + WMI_P2P_LISTEN_CMDID = 0xF03D, + + WMI_P2P_SET_CMDID = 0xF057, + + WMI_P2P_SDPD_TX_CMDID = 0xF058, /* F058 */ + WMI_P2P_STOP_SDPD_CMDID = 0xF059, + WMI_P2P_CANCEL_CMDID = 0xF05a, + WMI_P2P_CONNECT_CMDID = 0xf05b, + WMI_P2P_GET_NODE_LIST_CMDID = 0xf05c, + WMI_P2P_AUTH_GO_NEG_CMDID = 0xf05d, + WMI_P2P_FW_PROV_DISC_REQ_CMDID = 0xf05e, + WMI_P2P_PERSISTENT_PROFILE_CMDID = 0xf05f, + WMI_P2P_SET_JOIN_PROFILE_CMDID = 0xf060, + WMI_P2P_GRP_INIT_CMDID = 0xf061, + WMI_P2P_SET_PROFILE_CMDID = 0xf065, + WMI_P2P_INVITE_CMDID = 0xF070, + WMI_P2P_INVITE_REQ_RSP_CMDID = 0xF071, + WMI_P2P_FW_SET_NOA_CMDID = 0xf072, + WMI_P2P_FW_GET_NOA_CMDID = 0xf073, + WMI_P2P_FW_SET_OPPPS_CMDID = 0xf074, + WMI_P2P_FW_GET_OPPPS_CMDID = 0xf075, + +#elif ATH_FIRMWARE_TARGET == TARGET_AR400X_REV1 + WMI_P2P_SET_CONFIG_CMDID = 0xF038, + WMI_WPS_SET_CONFIG_CMDID = 0xF039, + WMI_SET_REQ_DEV_ATTR_CMDID = 0xF03A, + WMI_P2P_FIND_CMDID = 0xF03B, + WMI_P2P_STOP_FIND_CMDID = 0xF03C, + WMI_P2P_LISTEN_CMDID = 0xF03E, + + WMI_P2P_GRP_INIT_CMDID = 0xF051, + WMI_P2P_GRP_FORMATION_DONE_CMDID = 0xF052, + WMI_P2P_INVITE_CMDID = 0xF053, + WMI_P2P_INVITE_REQ_RSP_CMDID = 0xF054, + WMI_P2P_SET_CMDID = 0xF056, + + WMI_P2P_SDPD_TX_CMDID = 0xF05B, /* F058 */ + WMI_P2P_STOP_SDPD_CMDID = 0xF05C, + WMI_P2P_CANCEL_CMDID = 0xF05D, + WMI_P2P_CONNECT_CMDID = 0xf091, + WMI_P2P_GET_NODE_LIST_CMDID = 0xf092, + WMI_P2P_AUTH_GO_NEG_CMDID = 0xf093, + WMI_P2P_FW_PROV_DISC_REQ_CMDID = 0xf094, + WMI_P2P_PERSISTENT_PROFILE_CMDID = 0xf09D, + WMI_P2P_SET_JOIN_PROFILE_CMDID = 0xf09E, + WMI_P2P_SET_PROFILE_CMDID = 0xf0A8, + WMI_P2P_FW_SET_NOA_CMDID = 0xf0A9, + WMI_P2P_FW_GET_NOA_CMDID = 0xf0AA, + WMI_P2P_FW_SET_OPPPS_CMDID = 0xf0AB, + WMI_P2P_FW_GET_OPPPS_CMDID = 0xf0AC, + WMI_P2P_LIST_PERSISTENT_NETWORK_CMDID = 0xf0D7, +#endif + +#endif + WMI_SET_BITRATE_CMDID = 0xf000, + WMI_GET_BITRATE_CMDID = 0xf001, + /*GreenTx specific commands*/ + WMI_GREENTX_PARAMS_CMDID = 0xF079, + WMI_LPL_FORCE_ENABLE_CMDID = 0xF072, + WMI_ARGOS_CMDID = 0xf0B1, + WMI_SET_CREDIT_REVERSE_CMDID = 0xF0B6, + WMI_SET_RCV_DATA_CLASSIFIER_CMDID, + WMI_SET_TX_POWER_SCALE_CMDID = 0xF0D6, + + WMI_PFM_GET_CMDID = 0xF0DC, + + WMI_DSET_HOST_CFG_CMDID = 0xF0DE, + WMI_DSET_HOST_READ_CMDID = 0xF0DF, + + WMI_HOST_DSET_LARGE_READ_CMDID = 0xF0EA, + WMI_HOST_DSET_LARGE_WRITE_CMDID = 0xF0EB, + WMI_HOST_DSET_RESP_CREATE_CMDID = 0xF0EC, + WMI_HOST_DSET_SYNC_CMDID = 0xF0ED, + WMI_HOST_DSET_READBACK_CMDID = 0xF0EE, + WMI_HOST_DSET_RESP_WRITE_CMDID = 0xF0EF, + + WMI_DSET_OP_CMDID = 0xF0F0, + WMI_GET_TEMPERATURE_CMDID = 0xF0F1, + WMI_PARAM_SET_CMDID = 0xF0F3, + WMI_WLAN_SET_PROBEREQ_ENABLE_CMDID = 0xF0F5, + WMI_GET_COUNTRY_CODE_CMDID = 0xF0F6, + WMI_WLAN_WPS_INIT_KEY_CMDID = 0xF0F7, + WMI_HEATBEAT_CHALLENGE = 0xF0F8, +} WMI_COMMAND_ID; + +typedef PREPACK struct +{ + uint8_t enable; +} POSTPACK WMI_PROBE_REQ_REPORT_CMD_STRUCT; + +typedef PREPACK struct +{ + int32_t param_val; +} POSTPACK WMI_SET_TX_POWER_SCALE_CMD; + +/* + * Frame Types + */ +typedef enum +{ + WMI_FRAME_BEACON = 0, + WMI_FRAME_PROBE_REQ, + WMI_FRAME_PROBE_RESP, + WMI_FRAME_ASSOC_REQ, + WMI_FRAME_ASSOC_RESP, + WMI_NUM_MGMT_FRAME +} WMI_MGMT_FRAME_TYPE; + +/* + * Connect Command + */ +typedef enum +{ + INFRA_NETWORK = 0x01, + ADHOC_NETWORK = 0x02, + ADHOC_CREATOR = 0x04, + AP_NETWORK = 0x10, + NETWORK_CONNECTED_USING_WPS = 0x20 +} NETWORK_TYPE; + +typedef enum +{ + SUBTYPE_NONE, + SUBTYPE_BT, + SUBTYPE_P2PDEV, + SUBTYPE_P2PCLIENT, + SUBTYPE_P2PGO +} NETWORK_SUBTYPE; + +typedef enum +{ + OPEN_AUTH = 0x01, + SHARED_AUTH = 0x02, + LEAP_AUTH = 0x04 /* different from IEEE_AUTH_MODE definitions */ +} DOT11_AUTH_MODE; + +typedef enum +{ + NONE_AUTH = 0x01, + WPA_AUTH = 0x02, + WPA2_AUTH = 0x04, + WPA_PSK_AUTH = 0x08, + WPA2_PSK_AUTH = 0x10, + WPA_AUTH_CCKM = 0x20, + WPA2_AUTH_CCKM = 0x40 +} AUTH_MODE; + +typedef enum +{ + NONE_CRYPT = 0x01, + WEP_CRYPT = 0x02, + TKIP_CRYPT = 0x04, + AES_CRYPT = 0x08 +#ifdef WAPI_ENABLE + , + WAPI_CRYPT = 0x10 +#endif /*WAPI_ENABLE*/ +} CRYPTO_TYPE; + +#define WMI_MIN_CRYPTO_TYPE NONE_CRYPT +#define WMI_MAX_CRYPTO_TYPE (AES_CRYPT + 1) + +#ifdef WAPI_ENABLE +#undef WMI_MAX_CRYPTO_TYPE +#define WMI_MAX_CRYPTO_TYPE (WAPI_CRYPT + 1) +#endif /* WAPI_ENABLE */ + +#ifdef WAPI_ENABLE +#define IW_ENCODE_ALG_SM4 0x20 +#define IW_AUTH_WAPI_ENABLED 0x20 +#endif + +#define WMI_MIN_KEY_INDEX 0 +#define WMI_MAX_KEY_INDEX 3 + +#ifdef WAPI_ENABLE +#undef WMI_MAX_KEY_INDEX +#define WMI_MAX_KEY_INDEX 7 /* wapi grpKey 0-3, prwKey 4-7 */ +#endif /* WAPI_ENABLE */ + +#define WMI_MAX_KEY_LEN 32 + +#define WMI_MAX_SSID_LEN 32 + +typedef enum +{ + CONNECT_ASSOC_POLICY_USER = 0x0001, + CONNECT_SEND_REASSOC = 0x0002, + CONNECT_IGNORE_WPAx_GROUP_CIPHER = 0x0004, + CONNECT_PROFILE_MATCH_DONE = 0x0008, + CONNECT_IGNORE_AAC_BEACON = 0x0010, + CONNECT_CSA_FOLLOW_BSS = 0x0020, + CONNECT_DO_WPA_OFFLOAD = 0x0040, + CONNECT_DO_NOT_DEAUTH = 0x0080, + CONNECT_WPS_FLAG = 0x0100 +} WMI_CONNECT_CTRL_FLAGS_BITS; + +#define DEFAULT_CONNECT_CTRL_FLAGS (CONNECT_CSA_FOLLOW_BSS) + +typedef PREPACK struct +{ + uint8_t networkType FIELD_PACKED; + uint8_t dot11AuthMode FIELD_PACKED; + uint8_t authMode FIELD_PACKED; + uint8_t pairwiseCryptoType FIELD_PACKED; + uint8_t pairwiseCryptoLen FIELD_PACKED; + uint8_t groupCryptoType FIELD_PACKED; + uint8_t groupCryptoLen FIELD_PACKED; + uint8_t ssidLength FIELD_PACKED; + uint8_t ssid[WMI_MAX_SSID_LEN] FIELD_PACKED; + uint16_t channel FIELD_PACKED; + uint8_t bssid[ATH_MAC_LEN] FIELD_PACKED; + uint32_t ctrl_flags FIELD_PACKED; +} POSTPACK WMI_CONNECT_CMD; + +#if ENABLE_AP_MODE +/* + * Used with WMI_AP_HIDDEN_SSID_CMDID + */ +#define HIDDEN_SSID_FALSE 0 +#define HIDDEN_SSID_TRUE 1 + +typedef PREPACK struct +{ + uint8_t hidden_ssid FIELD_PACKED; +} POSTPACK WMI_AP_HIDDEN_SSID_CMD; + +typedef PREPACK struct +{ + uint32_t period FIELD_PACKED; +} POSTPACK WMI_AP_CONN_INACT_CMD; + +typedef PREPACK struct +{ + uint16_t beaconInterval FIELD_PACKED; +} POSTPACK WMI_BEACON_INT_CMD; + +typedef PREPACK struct +{ + uint8_t dtim FIELD_PACKED; +} POSTPACK WMI_AP_SET_DTIM_CMD; + +typedef PREPACK struct +{ + uint8_t enable FIELD_PACKED; /* enable/disable IoE AP PS Offload */ + uint8_t psBufCount FIELD_PACKED; /* PS Buf count per PS Client */ +} POSTPACK WMI_AP_PSBUF_OFFLOAD_CMD; +#endif + +/* + * WMI_RECONNECT_CMDID + */ +typedef PREPACK struct +{ + uint16_t channel FIELD_PACKED; /* hint */ + uint8_t bssid[ATH_MAC_LEN] FIELD_PACKED; /* mandatory if set */ +} POSTPACK WMI_RECONNECT_CMD; + +#define WMI_PMK_LEN 32 +typedef PREPACK struct +{ + uint8_t pmk[WMI_PMK_LEN] FIELD_PACKED; + uint8_t pmk_len FIELD_PACKED; +} POSTPACK WMI_SET_PMK_CMD, WMI_GET_PMK_REPLY; + +#define WMI_PASSPHRASE_LEN 64 +typedef PREPACK struct +{ + uint8_t ssid[WMI_MAX_SSID_LEN] FIELD_PACKED; + uint8_t passphrase[WMI_PASSPHRASE_LEN] FIELD_PACKED; + uint8_t ssid_len FIELD_PACKED; + uint8_t passphrase_len FIELD_PACKED; +} POSTPACK WMI_SET_PASSPHRASE_CMD; + +/* + * WMI_ADD_CIPHER_KEY_CMDID + */ +typedef enum +{ + PAIRWISE_USAGE = 0x00, + GROUP_USAGE = 0x01, + TX_USAGE = 0x02 /* default Tx Key - Static WEP only */ +} KEY_USAGE; + +/* + * Bit Flag + * Bit 0 - Initialise TSC - default is Initialize + */ +#define KEY_OP_INIT_TSC 0x01 +#define KEY_OP_INIT_RSC 0x02 +#ifdef WAPI_ENABLE +#define KEY_OP_INIT_WAPIPN 0x10 +#endif /* WAPI_ENABLE */ + +#define KEY_OP_INIT_VAL 0x03 /* Default Initialise the TSC & RSC */ +#define KEY_OP_VALID_MASK 0x03 + +typedef PREPACK struct +{ + uint8_t keyIndex FIELD_PACKED; + uint8_t keyType FIELD_PACKED; + uint8_t keyUsage FIELD_PACKED; /* KEY_USAGE */ + uint8_t keyLength FIELD_PACKED; + uint8_t keyRSC[8] FIELD_PACKED; /* key replay sequence counter */ + uint8_t key[WMI_MAX_KEY_LEN] FIELD_PACKED; + uint8_t key_op_ctrl FIELD_PACKED; /* Additional Key Control information */ + uint8_t key_macaddr[ATH_MAC_LEN] FIELD_PACKED; +} POSTPACK WMI_ADD_CIPHER_KEY_CMD; + +/* + * WMI_DELETE_CIPHER_KEY_CMDID + */ +typedef PREPACK struct +{ + uint8_t keyIndex FIELD_PACKED; +} POSTPACK WMI_DELETE_CIPHER_KEY_CMD; + +/* + * WMI_START_SCAN_CMD + */ +typedef enum +{ + WMI_LONG_SCAN = 0, + WMI_SHORT_SCAN = 1 +} WMI_SCAN_TYPE; + +typedef PREPACK struct +{ + boolean forceFgScan FIELD_PACKED; + boolean isLegacy FIELD_PACKED; /* For Legacy Cisco AP compatibility */ + uint32_t homeDwellTime FIELD_PACKED; /* Maximum duration in the home channel(milliseconds) */ + uint32_t forceScanInterval FIELD_PACKED; /* Time interval between scans (milliseconds)*/ + uint8_t scanType FIELD_PACKED; /* WMI_SCAN_TYPE */ + uint8_t numChannels FIELD_PACKED; /* how many channels follow */ + uint16_t channelList[1] FIELD_PACKED; /* channels in Mhz */ +} POSTPACK WMI_START_SCAN_CMD; + +/* + * WMI_SET_SCAN_PARAMS_CMDID + */ +#define WMI_SHORTSCANRATIO_DEFAULT 3 +/* + * Warning: ScanCtrlFlag value of 0xFF is used to disable all flags in WMI_SCAN_PARAMS_CMD + * Do not add any more flags to WMI_SCAN_CTRL_FLAG_BITS + */ +typedef enum +{ + CONNECT_SCAN_CTRL_FLAGS = 0x01, /* set if can scan in the Connect cmd */ + SCAN_CONNECTED_CTRL_FLAGS = 0x02, /* set if scan for the SSID it is */ + /* already connected to */ + ACTIVE_SCAN_CTRL_FLAGS = 0x04, /* set if enable active scan */ + ROAM_SCAN_CTRL_FLAGS = 0x08, /* set if enable roam scan when bmiss and lowrssi */ + REPORT_BSSINFO_CTRL_FLAGS = 0x10, /* set if follows customer BSSINFO reporting rule */ + ENABLE_AUTO_CTRL_FLAGS = 0x20, /* if disabled, target doesn't + scan after a disconnect event */ + ENABLE_SCAN_ABORT_EVENT = + 0x40 /* Scan complete event with canceled status will be generated when a scan is prempted before it gets + completed */ +} WMI_SCAN_CTRL_FLAGS_BITS; + +#define CAN_SCAN_IN_CONNECT(flags) (flags & CONNECT_SCAN_CTRL_FLAGS) +#define CAN_SCAN_CONNECTED(flags) (flags & SCAN_CONNECTED_CTRL_FLAGS) +#define ENABLE_ACTIVE_SCAN(flags) (flags & ACTIVE_SCAN_CTRL_FLAGS) +#define ENABLE_ROAM_SCAN(flags) (flags & ROAM_SCAN_CTRL_FLAGS) +#define CONFIG_REPORT_BSSINFO(flags) (flags & REPORT_BSSINFO_CTRL_FLAGS) +#define IS_AUTO_SCAN_ENABLED(flags) (flags & ENABLE_AUTO_CTRL_FLAGS) +#define SCAN_ABORT_EVENT_ENABLED(flags) (flags & ENABLE_SCAN_ABORT_EVENT) + +#define DEFAULT_SCAN_CTRL_FLAGS \ + (CONNECT_SCAN_CTRL_FLAGS | SCAN_CONNECTED_CTRL_FLAGS | ACTIVE_SCAN_CTRL_FLAGS | ROAM_SCAN_CTRL_FLAGS | \ + ENABLE_AUTO_CTRL_FLAGS) + +typedef PREPACK struct +{ + uint16_t fg_start_period FIELD_PACKED; /* seconds */ + uint16_t fg_end_period FIELD_PACKED; /* seconds */ + uint16_t bg_period FIELD_PACKED; /* seconds */ + uint16_t maxact_chdwell_time FIELD_PACKED; /* msec */ + uint16_t pas_chdwell_time FIELD_PACKED; /* msec */ + uint8_t shortScanRatio FIELD_PACKED; /* how many shorts scan for one long */ + uint8_t scanCtrlFlags FIELD_PACKED; + uint16_t minact_chdwell_time FIELD_PACKED; /* msec */ + uint16_t maxact_scan_per_ssid FIELD_PACKED; /* max active scans per ssid */ + uint32_t max_dfsch_act_time FIELD_PACKED; /* msecs */ +} POSTPACK WMI_SCAN_PARAMS_CMD; + +/* + * WMI_SET_BSS_FILTER_CMDID + */ +typedef enum +{ + NONE_BSS_FILTER = 0x0, /* no beacons forwarded */ + ALL_BSS_FILTER, /* all beacons forwarded */ + PROFILE_FILTER, /* only beacons matching profile */ + ALL_BUT_PROFILE_FILTER, /* all but beacons matching profile */ + CURRENT_BSS_FILTER, /* only beacons matching current BSS */ + ALL_BUT_BSS_FILTER, /* all but beacons matching BSS */ + PROBED_SSID_FILTER, /* beacons matching probed ssid */ + LAST_BSS_FILTER /* marker only */ +} WMI_BSS_FILTER; + +typedef PREPACK struct +{ + uint8_t bssFilter FIELD_PACKED; /* see WMI_BSS_FILTER */ + uint8_t reserved1 FIELD_PACKED; /* For alignment */ + uint16_t reserved2 FIELD_PACKED; /* For alignment */ + uint32_t ieMask FIELD_PACKED; +} POSTPACK WMI_BSS_FILTER_CMD; + +/* + * WMI_SET_PROBED_SSID_CMDID + */ +#define MAX_PROBED_SSID_INDEX 9 + +typedef enum +{ + DISABLE_SSID_FLAG = 0, /* disables entry */ + SPECIFIC_SSID_FLAG = 0x01, /* probes specified ssid */ + ANY_SSID_FLAG = 0x02 /* probes for any ssid */ +} WMI_SSID_FLAG; + +typedef PREPACK struct +{ + uint8_t entryIndex FIELD_PACKED; /* 0 to MAX_PROBED_SSID_INDEX */ + uint8_t flag FIELD_PACKED; /* WMI_SSID_FLG */ + uint8_t ssidLength FIELD_PACKED; + uint8_t ssid[32] FIELD_PACKED; +} POSTPACK WMI_PROBED_SSID_CMD; + +/* + * WMI_SET_LISTEN_INT_CMDID + * The Listen interval is between 15 and 3000 TUs + */ +#define MIN_LISTEN_INTERVAL 15 +#define MAX_LISTEN_INTERVAL 5000 +#define MIN_LISTEN_BEACONS 1 +#define MAX_LISTEN_BEACONS 50 + +typedef PREPACK struct +{ + uint16_t listenInterval FIELD_PACKED; + uint16_t numBeacons FIELD_PACKED; +} POSTPACK WMI_LISTEN_INT_CMD; + +/* + * WMI_SET_BMISS_TIME_CMDID + * valid values are between 1000 and 5000 TUs + */ + +#define MIN_BMISS_TIME 1000 +#define MAX_BMISS_TIME 5000 +#define MIN_BMISS_BEACONS 1 +#define MAX_BMISS_BEACONS 50 + +typedef PREPACK struct +{ + uint16_t bmissTime FIELD_PACKED; + uint16_t numBeacons FIELD_PACKED; +} POSTPACK WMI_BMISS_TIME_CMD; + +/* + * WMI_SET_POWER_MODE_CMDID + */ +typedef enum +{ + REC_POWER = 0x01, + MAX_PERF_POWER +} WMI_POWER_MODE; + +typedef PREPACK struct +{ + uint8_t powerMode FIELD_PACKED; /* WMI_POWER_MODE */ +} POSTPACK WMI_POWER_MODE_CMD; + +typedef PREPACK struct +{ + int8_t status FIELD_PACKED; /* WMI_SET_PARAMS_REPLY */ +} POSTPACK WMI_SET_PARAMS_REPLY; + +/* + * WMI_SET_POWER_PARAMS_CMDID + */ +typedef enum +{ + IGNORE_DTIM = 0x01, + NORMAL_DTIM = 0x02, + STICK_DTIM = 0x03, + AUTO_DTIM = 0x04 +} WMI_DTIM_POLICY; + +/* Policy to determnine whether TX should wakeup WLAN if sleeping */ +typedef enum +{ + TX_WAKEUP_UPON_SLEEP = 1, + TX_DONT_WAKEUP_UPON_SLEEP = 2 +} WMI_TX_WAKEUP_POLICY_UPON_SLEEP; + +/* + * Policy to determnine whether power save failure event should be sent to + * host during scanning + */ +typedef enum +{ + SEND_POWER_SAVE_FAIL_EVENT_ALWAYS = 1, + IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN = 2 +} POWER_SAVE_FAIL_EVENT_POLICY; + +typedef PREPACK struct +{ + uint16_t idle_period FIELD_PACKED; /* msec */ + uint16_t pspoll_number FIELD_PACKED; + uint16_t dtim_policy FIELD_PACKED; + uint16_t tx_wakeup_policy FIELD_PACKED; + uint16_t num_tx_to_wakeup FIELD_PACKED; + uint16_t ps_fail_event_policy FIELD_PACKED; +} POSTPACK WMI_POWER_PARAMS_CMD; + +/* Adhoc power save types */ +typedef enum +{ + ADHOC_PS_DISABLE = 1, + ADHOC_PS_ATH = 2, + ADHOC_PS_IEEE = 3, + ADHOC_PS_OTHER = 4 +} WMI_ADHOC_PS_TYPE; + +/* + * WMI_SET_DISC_TIMEOUT_CMDID + */ +typedef PREPACK struct +{ + uint8_t disconnectTimeout FIELD_PACKED; /* seconds */ +} POSTPACK WMI_DISC_TIMEOUT_CMD; + +typedef enum +{ + UPLINK_TRAFFIC = 0, + DNLINK_TRAFFIC = 1, + BIDIR_TRAFFIC = 2 +} DIR_TYPE; + +typedef enum +{ + DISABLE_FOR_THIS_AC = 0, + ENABLE_FOR_THIS_AC = 1, + ENABLE_FOR_ALL_AC = 2 +} VOICEPS_CAP_TYPE; + +typedef enum +{ + TRAFFIC_TYPE_APERIODIC = 0, + TRAFFIC_TYPE_PERIODIC = 1 +} TRAFFIC_TYPE; + +/* + * WMI_SYNCHRONIZE_CMDID + */ +typedef PREPACK struct +{ + uint8_t dataSyncMap FIELD_PACKED; +} POSTPACK WMI_SYNC_CMD; + +/* + * WMI_CREATE_PSTREAM_CMDID + */ +typedef PREPACK struct +{ + uint32_t minServiceInt FIELD_PACKED; /* in milli-sec */ + uint32_t maxServiceInt FIELD_PACKED; /* in milli-sec */ + uint32_t inactivityInt FIELD_PACKED; /* in milli-sec */ + uint32_t suspensionInt FIELD_PACKED; /* in milli-sec */ + uint32_t serviceStartTime FIELD_PACKED; + uint32_t minDataRate FIELD_PACKED; /* in bps */ + uint32_t meanDataRate FIELD_PACKED; /* in bps */ + uint32_t peakDataRate FIELD_PACKED; /* in bps */ + uint32_t maxBurstSize FIELD_PACKED; + uint32_t delayBound FIELD_PACKED; + uint32_t minPhyRate FIELD_PACKED; /* in bps */ + uint32_t sba FIELD_PACKED; + uint32_t mediumTime FIELD_PACKED; + uint16_t nominalMSDU FIELD_PACKED; /* in octects */ + uint16_t maxMSDU FIELD_PACKED; /* in octects */ + uint8_t trafficClass FIELD_PACKED; + uint8_t trafficDirection FIELD_PACKED; /* DIR_TYPE */ + uint8_t rxQueueNum FIELD_PACKED; + uint8_t trafficType FIELD_PACKED; /* TRAFFIC_TYPE */ + uint8_t voicePSCapability FIELD_PACKED; /* VOICEPS_CAP_TYPE */ + uint8_t tsid FIELD_PACKED; + uint8_t userPriority FIELD_PACKED; /* 802.1D user priority */ + uint8_t nominalPHY FIELD_PACKED; /* nominal phy rate */ +} POSTPACK WMI_CREATE_PSTREAM_CMD; + +/* + * WMI_DELETE_PSTREAM_CMDID + */ +typedef PREPACK struct +{ + uint8_t txQueueNumber FIELD_PACKED; + uint8_t rxQueueNumber FIELD_PACKED; + uint8_t trafficDirection FIELD_PACKED; + uint8_t trafficClass FIELD_PACKED; + uint8_t tsid FIELD_PACKED; +} POSTPACK WMI_DELETE_PSTREAM_CMD; + +/* + * WMI_SET_CHANNEL_PARAMS_CMDID + */ +typedef enum +{ + WMI_11A_MODE = 0x1, + WMI_11G_MODE = 0x2, + WMI_11AG_MODE = 0x3, + WMI_11B_MODE = 0x4, + WMI_11GONLY_MODE = 0x5 +} WMI_PHY_MODE; + +#define WMI_MAX_CHANNELS 32 + +typedef PREPACK struct +{ + uint8_t reserved1 FIELD_PACKED; + uint8_t scanParam FIELD_PACKED; /* set if enable scan */ + uint8_t phyMode FIELD_PACKED; /* see WMI_PHY_MODE */ + uint8_t numChannels FIELD_PACKED; /* how many channels follow */ + uint16_t channelList[1] FIELD_PACKED; /* channels in Mhz */ +} POSTPACK WMI_CHANNEL_PARAMS_CMD; + +typedef enum +{ + WMI_LPREAMBLE_DISABLED = 0, + WMI_LPREAMBLE_ENABLED +} WMI_LPREAMBLE_STATUS; + +typedef enum +{ + WMI_IGNORE_BARKER_IN_ERP = 0, + WMI_DONOT_IGNORE_BARKER_IN_ERP +} WMI_PREAMBLE_POLICY; + +typedef PREPACK struct +{ + uint16_t threshold FIELD_PACKED; +} POSTPACK WMI_SET_RTS_CMD; + +/* + * WMI_TARGET_ERROR_REPORT_BITMASK_CMDID + * Sets the error reporting event bitmask in target. Target clears it + * upon an error. Subsequent errors are counted, but not reported + * via event, unless the bitmask is set again. + */ +typedef PREPACK struct +{ + uint32_t bitmask FIELD_PACKED; +} POSTPACK WMI_TARGET_ERROR_REPORT_BITMASK; + +/* + * WMI_SET_TX_PWR_CMDID + */ +typedef PREPACK struct +{ + uint8_t dbM FIELD_PACKED; /* in dbM units */ +} POSTPACK WMI_SET_TX_PWR_CMD, WMI_TX_PWR_REPLY; + +/* + * WMI_GET_TX_PWR_CMDID does not take any parameters + */ + +/* + * WMI_SET_ACCESS_PARAMS_CMDID + */ +#define WMI_DEFAULT_TXOP_ACPARAM 0 /* implies one MSDU */ +#define WMI_DEFAULT_ECWMIN_ACPARAM 4 /* corresponds to CWmin of 15 */ +#define WMI_DEFAULT_ECWMAX_ACPARAM 10 /* corresponds to CWmax of 1023 */ +#define WMI_MAX_CW_ACPARAM 15 /* maximum eCWmin or eCWmax */ +#define WMI_DEFAULT_AIFSN_ACPARAM 2 +#define WMI_MAX_AIFSN_ACPARAM 15 +typedef PREPACK struct +{ + uint16_t txop FIELD_PACKED; /* in units of 32 usec */ + uint8_t eCWmin FIELD_PACKED; + uint8_t eCWmax FIELD_PACKED; + uint8_t aifsn FIELD_PACKED; + uint8_t ac FIELD_PACKED; +} POSTPACK WMI_SET_ACCESS_PARAMS_CMD; + +typedef PREPACK struct +{ + uint32_t sleepState FIELD_PACKED; +} WMI_REPORT_SLEEP_STATE_EVENT; + +/* + * Command Replies + */ + +/* + * WMI_GET_CHANNEL_LIST_CMDID reply + */ +typedef PREPACK struct +{ + uint8_t reserved1 FIELD_PACKED; + uint8_t numChannels FIELD_PACKED; /* number of channels in reply */ + uint16_t channelList[1] FIELD_PACKED; /* channel in Mhz */ +} POSTPACK WMI_CHANNEL_LIST_REPLY; + +typedef enum +{ + A_SUCCEEDED = A_OK, + A_FAILED_DELETE_STREAM_DOESNOT_EXIST = 250, + A_SUCCEEDED_MODIFY_STREAM = 251, + A_FAILED_INVALID_STREAM = 252, + A_FAILED_MAX_THINSTREAMS = 253, + A_FAILED_CREATE_REMOVE_PSTREAM_FIRST = 254 +} PSTREAM_REPLY_STATUS; + +typedef PREPACK struct +{ + uint8_t status FIELD_PACKED; /* PSTREAM_REPLY_STATUS */ + uint8_t txQueueNumber FIELD_PACKED; + uint8_t rxQueueNumber FIELD_PACKED; + uint8_t trafficClass FIELD_PACKED; + uint8_t trafficDirection FIELD_PACKED; /* DIR_TYPE */ +} POSTPACK WMI_CRE_PRIORITY_STREAM_REPLY; + +typedef PREPACK struct +{ + uint8_t status FIELD_PACKED; /* PSTREAM_REPLY_STATUS */ + uint8_t txQueueNumber FIELD_PACKED; + uint8_t rxQueueNumber FIELD_PACKED; + uint8_t trafficDirection FIELD_PACKED; /* DIR_TYPE */ + uint8_t trafficClass FIELD_PACKED; +} POSTPACK WMI_DEL_PRIORITY_STREAM_REPLY; + +typedef PREPACK struct +{ + uint32_t tempDegree; + uint8_t tempRegVal; +} POSTPACK WMI_GET_TEMPERATURE_REPLY; + +typedef PREPACK struct +{ + uint32_t status; +} POSTPACK WMI_WLAN_WPS_INIT_KEY_REPLY; + +typedef PREPACK struct +{ + uint8_t country_code[3]; +} POSTPACK WMI_GET_COUNTRY_CODE_REPLY; + +typedef PREPACK struct +{ + uint8_t bssid[ATH_MAC_LEN]; + int8_t bias; +} POSTPACK WMI_BSS_BIAS; + +typedef PREPACK struct +{ + uint8_t numBss; + WMI_BSS_BIAS bssBias[1]; +} POSTPACK WMI_BSS_BIAS_INFO; + +typedef PREPACK struct WMI_LOWRSSI_SCAN_PARAMS +{ + uint16_t lowrssi_scan_period; + int16_t lowrssi_scan_threshold; + int16_t lowrssi_roam_threshold; + uint8_t roam_rssi_floor; + uint8_t reserved[1]; /* For alignment */ +} POSTPACK WMI_LOWRSSI_SCAN_PARAMS; + +typedef PREPACK struct +{ + PREPACK union + { + uint8_t bssid[ATH_MAC_LEN]; /* WMI_FORCE_ROAM */ + uint8_t roamMode; /* WMI_SET_ROAM_MODE */ + WMI_BSS_BIAS_INFO bssBiasInfo; /* WMI_SET_HOST_BIAS */ + uint8_t bias5G; /* WMI_SET_HOST_5G_BIAS */ + WMI_LOWRSSI_SCAN_PARAMS lrScanParams; + } POSTPACK info; + uint8_t roamCtrlType; +} POSTPACK WMI_SET_ROAM_CTRL_CMD; +/* + * List of Events (target to host) + */ +typedef enum +{ + WMI_READY_EVENTID = 0x1001, + WMI_CONNECT_EVENTID = 0x1002, + WMI_DISCONNECT_EVENTID = 0x1003, + WMI_BSSINFO_EVENTID = 0x1004, + WMI_CMDERROR_EVENTID = 0x1005, + WMI_REGDOMAIN_EVENTID = 0x1006, + WMI_PSTREAM_TIMEOUT_EVENTID = 0x1007, + WMI_NEIGHBOR_REPORT_EVENTID = 0x1008, + WMI_TKIP_MICERR_EVENTID = 0x1009, + WMI_SCAN_COMPLETE_EVENTID = 0x100a, /* 0x100a */ + WMI_REPORT_STATISTICS_EVENTID = 0x100b, + WMI_RSSI_THRESHOLD_EVENTID = 0x100c, + WMI_ERROR_REPORT_EVENTID = 0x100d, + WMI_REPORT_ROAM_TBL_EVENTID = 0x100f, + WMI_EXTENSION_EVENTID = 0x1010, + WMI_SNR_THRESHOLD_EVENTID = 0x1012, + WMI_LQ_THRESHOLD_EVENTID = 0x1013, + WMI_TX_RETRY_ERR_EVENTID = 0x1014, /* 0x1014 */ + WMI_REPORT_ROAM_DATA_EVENTID = 0x1015, +#if MANUFACTURING_SUPPORT + WMI_TEST_EVENTID = 0x1016, +#endif + WMI_APLIST_EVENTID = 0x1017, + WMI_GET_PMKID_LIST_EVENTID = 0x1019, + WMI_CHANNEL_CHANGE_EVENTID = 0x101a, + WMI_PEER_NODE_EVENTID = 0x101b, + WMI_DTIMEXPIRY_EVENTID = 0x101d, + WMI_WLAN_VERSION_EVENTID = 0x101e, + WMI_SET_PARAMS_REPLY_EVENTID = 0x101f, + WMI_ADDBA_REQ_EVENTID = 0x1020, /*0x1020 */ + WMI_ADDBA_RESP_EVENTID = 0x1021, + WMI_DELBA_REQ_EVENTID = 0x1022, + WMI_REPORT_SLEEP_STATE_EVENTID = 0x1026, + WMI_GET_PMK_EVENTID = 0x102a, + WMI_SET_CHANNEL_EVENTID = 0x9000, + WMI_RX_PROBE_REQ_EVENTID = 0x900a, + +#if ATH_FIRMWARE_TARGET == TARGET_AR4100_REV2 + WMI_STORERECALL_STORE_EVENTID = 0x9004, + WMI_WPS_GET_STATUS_EVENTID = 0x9005, + WMI_WPS_PROFILE_EVENTID = 0x9006, + WMI_SOCKET_RESPONSE_EVENTID = 0x9007, + + /* P2P Events */ + WMI_P2P_GO_NEG_RESULT_EVENTID = 0x1036, /* 1035 */ + WMI_P2P_INVITE_REQ_EVENTID = 0x103C, + WMI_P2P_INVITE_RCVD_RESULT_EVENTID = 0x103d, + WMI_P2P_INVITE_SENT_RESULT_EVENTID = 0x103e, + WMI_P2P_PROV_DISC_RESP_EVENTID = 0x103f, + WMI_P2P_PROV_DISC_REQ_EVENTID = 0x1040, + WMI_P2P_START_SDPD_EVENTID = 0x1045, + WMI_P2P_SDPD_RX_EVENTID = 0x1046, + WMI_P2P_NODE_LIST_EVENTID = 0x901a, + WMI_P2P_REQ_TO_AUTH_EVENTID = 0x901b, +#elif ATH_FIRMWARE_TARGET == TARGET_AR400X_REV1 + WMI_STORERECALL_STORE_EVENTID = 0x9003, + WMI_WPS_GET_STATUS_EVENTID = 0x900e, + WMI_WPS_PROFILE_EVENTID = 0x900f, + WMI_SOCKET_RESPONSE_EVENTID = 0x9016, + WMI_P2P_GO_NEG_RESULT_EVENTID = 0x1036, + WMI_P2P_INVITE_REQ_EVENTID = 0x103E, + WMI_P2P_INVITE_RCVD_RESULT_EVENTID = 0x103F, + WMI_P2P_INVITE_SENT_RESULT_EVENTID = 0x1040, + WMI_P2P_PROV_DISC_RESP_EVENTID = 0x1041, + WMI_P2P_PROV_DISC_REQ_EVENTID = 0x1042, + WMI_P2P_START_SDPD_EVENTID = 0x1045, + WMI_P2P_SDPD_RX_EVENTID = 0x1046, + WMI_P2P_NODE_LIST_EVENTID = 0x901a, + WMI_P2P_REQ_TO_AUTH_EVENTID = 0x901b, + WMI_P2P_LIST_PERSISTENT_NETWORK_EVENTID = 0x9030, + +#endif + WMI_ARGOS_EVENTID = 0x901f, + WMI_HOST_DSET_STORE_EVENTID = 0x9031, + WMI_HOST_DSET_READ_EVENTID = 0x9032, + WMI_STORERECALL_START_EVENTID = 0x9033, + WMI_HOST_DSET_CREATE_EVENTID = 0x9038, + WMI_HOST_DSET_LARGE_WRITE_EVENTID = 0x9039, + WMI_HOST_DSET_LARGE_READ_EVENTID = 0x903A, + WMI_HOST_DSET_SYNC_EVENTID = 0x903B, + + WMI_DSET_OP_EVENTID = 0x903C, + WMI_GET_TEMPERATURE_REPLY_EVENTID = 0x903D, + WMI_PARAM_SET_REPLY_EVENTID = 0x903E, + WMI_GET_COUNTRY_CODE_REPLY_EVENTID = 0x9040, + WMI_WLAN_WPS_INIT_KEY_EVENTID = 0x9041, +} WMI_EVENT_ID; + +#if ENABLE_P2P_MODE +#define P2P_EVT_BUF_SIZE 512 +typedef PREPACK struct +{ + uint32_t EVENT_ID FIELD_PACKED; + uint8_t data[P2P_EVT_BUF_SIZE] FIELD_PACKED; +} POSTPACK WMI_EVT_TO_APP; +#endif + +typedef struct +{ + uint8_t pwr_module; + boolean pwr_mode; +} POWER_MODE; + +typedef enum +{ + WMI_11A_CAPABILITY = 1, + WMI_11G_CAPABILITY = 2, + WMI_11AG_CAPABILITY = 3, + WMI_11NA_CAPABILITY = 4, + WMI_11NG_CAPABILITY = 5, + WMI_11NAG_CAPABILITY = 6, + // END CAPABILITY + WMI_11N_CAPABILITY_OFFSET = (WMI_11NA_CAPABILITY - WMI_11A_CAPABILITY) +} WMI_PHY_CAPABILITY; + +typedef PREPACK struct +{ + uint8_t macaddr[ATH_MAC_LEN] FIELD_PACKED; + uint8_t phyCapability FIELD_PACKED; /* WMI_PHY_CAPABILITY */ +} POSTPACK WMI_READY_EVENT_1; + +typedef PREPACK struct +{ + uint32_t sw_version FIELD_PACKED; + uint32_t abi_version FIELD_PACKED; + uint8_t macaddr[ATH_MAC_LEN] FIELD_PACKED; + uint8_t phyCapability FIELD_PACKED; /* WMI_PHY_CAPABILITY */ +} POSTPACK WMI_READY_EVENT_2; + +#define WMI_READY_EVENT WMI_READY_EVENT_2 /* host code */ + +typedef PREPACK struct +{ + uint32_t freq; + uint16_t len; + uint8_t data[1]; +} POSTPACK WMI_P2P_RX_PROBE_REQ_EVENT_STRUCT; + +/* + * Connect Event + */ +typedef PREPACK struct +{ + uint16_t channel FIELD_PACKED; + uint8_t bssid[ATH_MAC_LEN] FIELD_PACKED; + uint16_t listenInterval FIELD_PACKED; + uint16_t beaconInterval FIELD_PACKED; + uint32_t networkType FIELD_PACKED; + uint8_t beaconIeLen FIELD_PACKED; + uint8_t assocReqLen FIELD_PACKED; + uint8_t assocRespLen FIELD_PACKED; + uint8_t assocInfo[1] FIELD_PACKED; +} POSTPACK WMI_CONNECT_EVENT; + +/* + * Disconnect Event + */ +typedef enum +{ + NO_NETWORK_AVAIL = 0x01, + LOST_LINK = 0x02, /* bmiss */ + DISCONNECT_CMD = 0x03, + BSS_DISCONNECTED = 0x04, + AUTH_FAILED = 0x05, + ASSOC_FAILED = 0x06, + NO_RESOURCES_AVAIL = 0x07, + CSERV_DISCONNECT = 0x08, + INVALID_PROFILE = 0x0a, + DOT11H_CHANNEL_SWITCH = 0x0b, + PROFILE_MISMATCH = 0x0c, + CONNECTION_EVICTED = 0x0d, + IBSS_MERGE = 0xe +} WMI_DISCONNECT_REASON; + +typedef PREPACK struct +{ + uint16_t protocolReasonStatus FIELD_PACKED; /* reason code, see 802.11 spec. */ + uint8_t bssid[ATH_MAC_LEN] FIELD_PACKED; /* set if known */ + uint8_t disconnectReason FIELD_PACKED; /* see WMI_DISCONNECT_REASON */ + uint8_t assocRespLen FIELD_PACKED; + uint8_t assocInfo[1] FIELD_PACKED; +} POSTPACK WMI_DISCONNECT_EVENT; + +/* + * BSS Info Event. + * Mechanism used to inform host of the presence and characteristic of + * wireless networks present. Consists of bss info header followed by + * the beacon or probe-response frame body. The 802.11 header is not included. + */ +typedef enum +{ + BEACON_FTYPE = 0x1, + PROBERESP_FTYPE, + ACTION_MGMT_FTYPE, + PROBEREQ_FTYPE +} WMI_BI_FTYPE; + +enum +{ + BSS_ELEMID_CHANSWITCH = 0x01, + BSS_ELEMID_ATHEROS = 0x02 +}; + +typedef PREPACK struct +{ + uint16_t channel FIELD_PACKED; + uint8_t frameType FIELD_PACKED; /* see WMI_BI_FTYPE */ + uint8_t snr FIELD_PACKED; + int16_t rssi FIELD_PACKED; + uint8_t bssid[ATH_MAC_LEN] FIELD_PACKED; + uint32_t ieMask FIELD_PACKED; +} POSTPACK WMI_BSS_INFO_HDR; + +/* + * BSS INFO HDR version 2.0 + * With 6 bytes HTC header and 6 bytes of WMI header + * WMI_BSS_INFO_HDR cannot be accomodated in the removed 802.11 management + * header space. + * - Reduce the ieMask to 2 bytes as only two bit flags are used + * - Remove rssi and compute it on the host. rssi = snr - 95 + */ +typedef PREPACK struct +{ + uint16_t channel FIELD_PACKED; + uint8_t frameType FIELD_PACKED; /* see WMI_BI_FTYPE */ + uint8_t snr FIELD_PACKED; + uint8_t bssid[ATH_MAC_LEN] FIELD_PACKED; + uint16_t ieMask FIELD_PACKED; +} POSTPACK WMI_BSS_INFO_HDR2; + +/* + * Command Error Event + */ +typedef enum +{ + INVALID_PARAM = 0x01, + ILLEGAL_STATE = 0x02, + INTERNAL_ERROR = 0x03, + STACK_ERROR = 0x04 +} WMI_ERROR_CODE; + +typedef PREPACK struct +{ + uint16_t commandId FIELD_PACKED; + uint8_t errorCode FIELD_PACKED; +} POSTPACK WMI_CMD_ERROR_EVENT; + +/* + * New Regulatory Domain Event + */ +typedef PREPACK struct +{ + uint32_t regDomain FIELD_PACKED; +} POSTPACK WMI_REG_DOMAIN_EVENT; + +typedef PREPACK struct +{ + uint8_t txQueueNumber FIELD_PACKED; + uint8_t rxQueueNumber FIELD_PACKED; + uint8_t trafficDirection FIELD_PACKED; + uint8_t trafficClass FIELD_PACKED; +} POSTPACK WMI_PSTREAM_TIMEOUT_EVENT; + +/* + * TKIP MIC Error Event + */ +typedef PREPACK struct +{ + uint8_t keyid FIELD_PACKED; + uint8_t ismcast FIELD_PACKED; +} POSTPACK WMI_TKIP_MICERR_EVENT; + +/* + * WMI_SCAN_COMPLETE_EVENTID - no parameters (old), staus parameter (new) + */ +typedef PREPACK struct +{ + int32_t status FIELD_PACKED; +} POSTPACK WMI_SCAN_COMPLETE_EVENT; + +#define MAX_OPT_DATA_LEN 1400 + +/* + * Reporting statistics. + */ +typedef PREPACK struct +{ + uint32_t tx_packets FIELD_PACKED; + uint32_t tx_bytes FIELD_PACKED; + uint32_t tx_unicast_pkts FIELD_PACKED; + uint32_t tx_unicast_bytes FIELD_PACKED; + uint32_t tx_multicast_pkts FIELD_PACKED; + uint32_t tx_multicast_bytes FIELD_PACKED; + uint32_t tx_broadcast_pkts FIELD_PACKED; + uint32_t tx_broadcast_bytes FIELD_PACKED; + uint32_t tx_rts_success_cnt FIELD_PACKED; + uint32_t tx_packet_per_ac[4] FIELD_PACKED; + uint32_t tx_errors_per_ac[4] FIELD_PACKED; + + uint32_t tx_errors FIELD_PACKED; + uint32_t tx_failed_cnt FIELD_PACKED; + uint32_t tx_retry_cnt FIELD_PACKED; + uint32_t tx_mult_retry_cnt FIELD_PACKED; + uint32_t tx_rts_fail_cnt FIELD_PACKED; + int32_t tx_unicast_rate FIELD_PACKED; +} POSTPACK tx_stats_t; + +typedef PREPACK struct +{ + uint32_t rx_packets FIELD_PACKED; + uint32_t rx_bytes FIELD_PACKED; + uint32_t rx_unicast_pkts FIELD_PACKED; + uint32_t rx_unicast_bytes FIELD_PACKED; + uint32_t rx_multicast_pkts FIELD_PACKED; + uint32_t rx_multicast_bytes FIELD_PACKED; + uint32_t rx_broadcast_pkts FIELD_PACKED; + uint32_t rx_broadcast_bytes FIELD_PACKED; + uint32_t rx_fragment_pkt FIELD_PACKED; + + uint32_t rx_errors FIELD_PACKED; + uint32_t rx_crcerr FIELD_PACKED; + uint32_t rx_key_cache_miss FIELD_PACKED; + uint32_t rx_decrypt_err FIELD_PACKED; + uint32_t rx_duplicate_frames FIELD_PACKED; + int32_t rx_unicast_rate FIELD_PACKED; +} POSTPACK rx_stats_t; + +typedef PREPACK struct +{ + uint32_t tkip_local_mic_failure FIELD_PACKED; + uint32_t tkip_counter_measures_invoked FIELD_PACKED; + uint32_t tkip_replays FIELD_PACKED; + uint32_t tkip_format_errors FIELD_PACKED; + uint32_t ccmp_format_errors FIELD_PACKED; + uint32_t ccmp_replays FIELD_PACKED; +} POSTPACK tkip_ccmp_stats_t FIELD_PACKED; + +typedef PREPACK struct +{ + uint32_t power_save_failure_cnt FIELD_PACKED; + uint16_t stop_tx_failure_cnt FIELD_PACKED; + uint16_t atim_tx_failure_cnt FIELD_PACKED; + uint16_t atim_rx_failure_cnt FIELD_PACKED; + uint16_t bcn_rx_failure_cnt FIELD_PACKED; +} POSTPACK pm_stats_t; + +typedef PREPACK struct +{ + uint32_t cs_bmiss_cnt FIELD_PACKED; + uint32_t cs_lowRssi_cnt FIELD_PACKED; + uint16_t cs_connect_cnt FIELD_PACKED; + uint16_t cs_disconnect_cnt FIELD_PACKED; + int16_t cs_aveBeacon_rssi FIELD_PACKED; + uint16_t cs_roam_count FIELD_PACKED; + int16_t cs_rssi FIELD_PACKED; + uint8_t cs_snr FIELD_PACKED; + uint8_t cs_aveBeacon_snr FIELD_PACKED; + uint8_t cs_lastRoam_msec FIELD_PACKED; +} POSTPACK cserv_stats_t; + +typedef PREPACK struct +{ + tx_stats_t tx_stats FIELD_PACKED; + rx_stats_t rx_stats FIELD_PACKED; + tkip_ccmp_stats_t tkipCcmpStats FIELD_PACKED; +} POSTPACK wlan_net_stats_t; + +typedef PREPACK struct +{ + uint32_t arp_received FIELD_PACKED; + uint32_t arp_matched FIELD_PACKED; + uint32_t arp_replied FIELD_PACKED; +} POSTPACK arp_stats_t; + +typedef PREPACK struct +{ + uint32_t wow_num_pkts_dropped FIELD_PACKED; + uint16_t wow_num_events_discarded FIELD_PACKED; + uint8_t wow_num_host_pkt_wakeups FIELD_PACKED; + uint8_t wow_num_host_event_wakeups FIELD_PACKED; +} POSTPACK wlan_wow_stats_t; + +typedef PREPACK struct +{ + uint32_t lqVal FIELD_PACKED; + int32_t noise_floor_calibation FIELD_PACKED; + pm_stats_t pmStats FIELD_PACKED; + wlan_net_stats_t txrxStats FIELD_PACKED; + wlan_wow_stats_t wowStats FIELD_PACKED; + arp_stats_t arpStats FIELD_PACKED; + cserv_stats_t cservStats FIELD_PACKED; +} POSTPACK WMI_TARGET_STATS; + +/* + * WMI_ERROR_REPORT_EVENTID + */ +typedef enum +{ + WMI_TARGET_PM_ERR_FAIL = 0x00000001, + WMI_TARGET_KEY_NOT_FOUND = 0x00000002, + WMI_TARGET_DECRYPTION_ERR = 0x00000004, + WMI_TARGET_BMISS = 0x00000008, + WMI_PSDISABLE_NODE_JOIN = 0x00000010, + WMI_TARGET_COM_ERR = 0x00000020, + WMI_TARGET_FATAL_ERR = 0x00000040 +} WMI_TARGET_ERROR_VAL; + +typedef PREPACK struct +{ + uint32_t errorVal FIELD_PACKED; +} POSTPACK WMI_TARGET_ERROR_REPORT_EVENT; + +typedef PREPACK struct +{ + uint8_t retrys FIELD_PACKED; +} POSTPACK WMI_TX_RETRY_ERR_EVENT; + +/* + * developer commands + */ + +#if 1 +static const int32_t wmi_rateTable[][2] = { + //{W/O SGI, with SGI} + {1000, 1000}, {2000, 2000}, {5500, 5500}, {11000, 11000}, {6000, 6000}, {9000, 9000}, + {12000, 12000}, {18000, 18000}, {24000, 24000}, {36000, 36000}, {48000, 48000}, {54000, 54000}, + {6500, 7200}, {13000, 14400}, {19500, 21700}, {26000, 28900}, {39000, 43300}, {52000, 57800}, + {58500, 65000}, {65000, 72200}, {13500, 15000}, {27500, 30000}, {40500, 45000}, {54000, 60000}, + {81500, 90000}, {108000, 120000}, {121500, 135000}, {135000, 150000}}; +#endif + +/* + * WMI_SET_BITRATE_CMDID + * + * Get bit rate cmd uses same definition as set bit rate cmd + */ +typedef enum +{ + RATE_AUTO = -1, + RATE_1Mb = 0, + RATE_2Mb = 1, + RATE_5_5Mb = 2, + RATE_11Mb = 3, + RATE_6Mb = 4, + RATE_9Mb = 5, + RATE_12Mb = 6, + RATE_18Mb = 7, + RATE_24Mb = 8, + RATE_36Mb = 9, + RATE_48Mb = 10, + RATE_54Mb = 11, + RATE_MCS_0_20 = 12, + RATE_MCS_1_20 = 13, + RATE_MCS_2_20 = 14, + RATE_MCS_3_20 = 15, + RATE_MCS_4_20 = 16, + RATE_MCS_5_20 = 17, + RATE_MCS_6_20 = 18, + RATE_MCS_7_20 = 19, + RATE_MCS_0_40 = 20, + RATE_MCS_1_40 = 21, + RATE_MCS_2_40 = 22, + RATE_MCS_3_40 = 23, + RATE_MCS_4_40 = 24, + RATE_MCS_5_40 = 25, + RATE_MCS_6_40 = 26, + RATE_MCS_7_40 = 27 +} WMI_BIT_RATE; + +typedef PREPACK struct +{ + int8_t rateIndex FIELD_PACKED; /* see WMI_BIT_RATE */ + int8_t mgmtRateIndex FIELD_PACKED; + int8_t ctlRateIndex FIELD_PACKED; +} POSTPACK WMI_BIT_RATE_CMD; + +typedef PREPACK struct +{ + int8_t rateIndex FIELD_PACKED; /* see WMI_BIT_RATE */ +} POSTPACK WMI_BIT_RATE_REPLY; + +/* + * WMI_SET_FIXRATES_CMDID + * + * Get fix rates cmd uses same definition as set fix rates cmd + */ +#define FIX_RATE_1Mb ((uint32_t)0x1) +#define FIX_RATE_2Mb ((uint32_t)0x2) +#define FIX_RATE_5_5Mb ((uint32_t)0x4) +#define FIX_RATE_11Mb ((uint32_t)0x8) +#define FIX_RATE_6Mb ((uint32_t)0x10) +#define FIX_RATE_9Mb ((uint32_t)0x20) +#define FIX_RATE_12Mb ((uint32_t)0x40) +#define FIX_RATE_18Mb ((uint32_t)0x80) +#define FIX_RATE_24Mb ((uint32_t)0x100) +#define FIX_RATE_36Mb ((uint32_t)0x200) +#define FIX_RATE_48Mb ((uint32_t)0x400) +#define FIX_RATE_54Mb ((uint32_t)0x800) +#define FIX_RATE_MCS_0_20 ((uint32_t)0x1000) +#define FIX_RATE_MCS_1_20 ((uint32_t)0x2000) +#define FIX_RATE_MCS_2_20 ((uint32_t)0x4000) +#define FIX_RATE_MCS_3_20 ((uint32_t)0x8000) +#define FIX_RATE_MCS_4_20 ((uint32_t)0x10000) +#define FIX_RATE_MCS_5_20 ((uint32_t)0x20000) +#define FIX_RATE_MCS_6_20 ((uint32_t)0x40000) +#define FIX_RATE_MCS_7_20 ((uint32_t)0x80000) +#define FIX_RATE_MCS_0_40 ((uint32_t)0x100000) +#define FIX_RATE_MCS_1_40 ((uint32_t)0x200000) +#define FIX_RATE_MCS_2_40 ((uint32_t)0x400000) +#define FIX_RATE_MCS_3_40 ((uint32_t)0x800000) +#define FIX_RATE_MCS_4_40 ((uint32_t)0x1000000) +#define FIX_RATE_MCS_5_40 ((uint32_t)0x2000000) +#define FIX_RATE_MCS_6_40 ((uint32_t)0x4000000) +#define FIX_RATE_MCS_7_40 ((uint32_t)0x8000000) + +typedef enum +{ + WMI_WMM_DISABLED = 0, + WMI_WMM_ENABLED +} WMI_WMM_STATUS; + +typedef PREPACK struct +{ + uint8_t status FIELD_PACKED; +} POSTPACK WMI_SET_WMM_CMD; + +typedef PREPACK struct +{ + uint8_t status FIELD_PACKED; +} POSTPACK WMI_SET_QOS_SUPP_CMD; + +typedef enum +{ + WMI_TXOP_DISABLED = 0, + WMI_TXOP_ENABLED +} WMI_TXOP_CFG; + +typedef PREPACK struct +{ + uint8_t txopEnable FIELD_PACKED; +} POSTPACK WMI_SET_WMM_TXOP_CMD; + +typedef PREPACK struct +{ + uint8_t keepaliveInterval FIELD_PACKED; +} POSTPACK WMI_SET_KEEPALIVE_CMD; + +typedef PREPACK struct +{ + boolean configured FIELD_PACKED; + uint8_t keepaliveInterval FIELD_PACKED; +} POSTPACK WMI_GET_KEEPALIVE_CMD; + +/* + * Add Application specified IE to a management frame + */ +#define WMI_MAX_IE_LEN 64 + +typedef PREPACK struct { + uint8_t mgmtFrmType; /* one of WMI_MGMT_FRAME_TYPE */ + uint8_t ieLen; /* Length of the IE that should be added to the MGMT frame */ + uint8_t ieInfo[1]; +} POSTPACK WMI_SET_APPIE_CMD; + +typedef PREPACK struct +{ + uint16_t oldChannel FIELD_PACKED; + uint32_t newChannel FIELD_PACKED; +} POSTPACK WMI_CHANNEL_CHANGE_EVENT; + +typedef PREPACK struct +{ + uint32_t version FIELD_PACKED; +} POSTPACK WMI_WLAN_VERSION_EVENT; + +/* WMI_ADDBA_REQ_EVENTID */ +typedef PREPACK struct +{ + uint8_t tid FIELD_PACKED; + uint8_t win_sz FIELD_PACKED; + uint16_t st_seq_no FIELD_PACKED; + uint8_t status FIELD_PACKED; /* f/w response for ADDBA Req; OK(0) or failure(!=0) */ +} POSTPACK WMI_ADDBA_REQ_EVENT; + +/* WMI_ADDBA_RESP_EVENTID */ +typedef PREPACK struct +{ + uint8_t tid FIELD_PACKED; + uint8_t status FIELD_PACKED; /* OK(0), failure (!=0) */ + uint16_t amsdu_sz FIELD_PACKED; /* Three values: Not supported(0), 3839, 8k */ +} POSTPACK WMI_ADDBA_RESP_EVENT; + +/* WMI_DELBA_EVENTID + * f/w received a DELBA for peer and processed it. + * Host is notified of this + */ +typedef PREPACK struct +{ + uint8_t tid FIELD_PACKED; + uint8_t is_peer_initiator FIELD_PACKED; + uint16_t reason_code FIELD_PACKED; +} POSTPACK WMI_DELBA_EVENT; + +/* WMI_ALLOW_AGGR_CMDID + * Configures tid's to allow ADDBA negotiations + * on each tid, in each direction + */ +typedef PREPACK struct +{ + uint16_t tx_allow_aggr FIELD_PACKED; /* 16-bit mask to allow uplink ADDBA negotiation - bit position indicates tid*/ + uint16_t rx_allow_aggr + FIELD_PACKED; /* 16-bit mask to allow donwlink ADDBA negotiation - bit position indicates tid*/ +} POSTPACK WMI_ALLOW_AGGR_CMD; + +/* WMI_ADDBA_REQ_CMDID + * f/w starts performing ADDBA negotiations with peer + * on the given tid + */ +typedef PREPACK struct +{ + uint8_t tid FIELD_PACKED; +} POSTPACK WMI_ADDBA_REQ_CMD; + +/* WMI_DELBA_REQ_CMDID + * f/w would teardown BA with peer. + * is_send_initiator indicates if it's or tx or rx side + */ +typedef PREPACK struct +{ + uint8_t tid FIELD_PACKED; + uint8_t is_sender_initiator FIELD_PACKED; + +} POSTPACK WMI_DELBA_REQ_CMD; + +#define PEER_NODE_JOIN_EVENT 0x00 +#define PEER_NODE_LEAVE_EVENT 0x01 +#define PEER_FIRST_NODE_JOIN_EVENT 0x10 +#define PEER_LAST_NODE_LEAVE_EVENT 0x11 +typedef PREPACK struct +{ + uint8_t eventCode FIELD_PACKED; + uint8_t peerMacAddr[ATH_MAC_LEN] FIELD_PACKED; +} POSTPACK WMI_PEER_NODE_EVENT; + +#define IEEE80211_FRAME_TYPE_MGT 0x00 +#define IEEE80211_FRAME_TYPE_CTL 0x04 + +typedef PREPACK struct +{ + uint8_t band FIELD_PACKED; /* specifies which band to apply these values */ + uint8_t enable FIELD_PACKED; /* allows 11n to be disabled on a per band basis */ + uint8_t chan_width_40M_supported FIELD_PACKED; + uint8_t short_GI_20MHz FIELD_PACKED; + uint8_t short_GI_40MHz FIELD_PACKED; + uint8_t intolerance_40MHz FIELD_PACKED; + uint8_t max_ampdu_len_exp FIELD_PACKED; +} POSTPACK WMI_SET_HT_CAP_CMD; + +typedef PREPACK struct +{ + uint8_t sta_chan_width FIELD_PACKED; +} POSTPACK WMI_SET_HT_OP_CMD; + +typedef PREPACK struct +{ + uint8_t metaVersion FIELD_PACKED; /* version of meta data for rx packets <0 = default> (0-7 = valid) */ + uint8_t dot11Hdr FIELD_PACKED; /* 1 == leave .11 header intact , 0 == replace .11 header with .3 */ + uint8_t defragOnHost + FIELD_PACKED; /* 1 == defragmentation is performed by host, 0 == performed by target */ + uint8_t reserved[1] FIELD_PACKED; /* alignment */ +} POSTPACK WMI_RX_FRAME_FORMAT_CMD; + +/* STORE / RECALL Commands AND Events DEFINITION START */ + +#define DSET_STORE_RECALL_START 0x00000900 +#define DSET_STORE_RECALL_END 0x000009FF + +#define IS_STRRCL_DSET(a) (((a) >= DSET_STORE_RECALL_START) && ((a) <= DSET_STORE_RECALL_END)) + +typedef PREPACK struct +{ + uint8_t enable FIELD_PACKED; +#define STRRCL_RECIPIENT_HOST 1 + uint8_t recipient FIELD_PACKED; +} POSTPACK WMI_STORERECALL_CONFIGURE_CMD; + +typedef PREPACK struct +{ + uint32_t dset_id FIELD_PACKED; /* number of bytes of data to follow */ + uint32_t length FIELD_PACKED; /* start of data */ +} POSTPACK WMI_STORERECALL_RECALL_DSET; + +typedef PREPACK struct +{ + uint32_t length FIELD_PACKED; /* number of bytes of data to follow */ + uint8_t data[1] FIELD_PACKED; /* start of data */ +} POSTPACK WMI_STORERECALL_RECALL_CMD; + +typedef PREPACK struct +{ + uint32_t sleep_msec FIELD_PACKED; + uint8_t store_after_tx_empty FIELD_PACKED; + uint8_t store_after_fresh_beacon_rx FIELD_PACKED; +} POSTPACK WMI_STORERECALL_HOST_READY_CMD; + +typedef PREPACK struct +{ + uint32_t msec_sleep FIELD_PACKED; /* time between power off/on */ + uint32_t length FIELD_PACKED; /* length of following data */ + uint8_t data[1] FIELD_PACKED; /* start of data */ +} POSTPACK WMI_STORERECALL_STORE_EVENT; + +typedef PREPACK struct +{ + uint32_t length FIELD_PACKED; /* length of following data */ + uint8_t data[1] FIELD_PACKED; /* start of data */ +} POSTPACK WMI_HOST_DSET_STORE_EVENT; + +typedef PREPACK struct +{ + uint32_t dset_id FIELD_PACKED; /* length of following data */ + uint32_t length FIELD_PACKED; /* length of following data */ +} POSTPACK WMI_HOST_DSET_CREATE_EVENT; + +typedef PREPACK struct +{ + uint32_t dset_id FIELD_PACKED; /* length of following data */ + uint32_t offset FIELD_PACKED; /* length of following data */ + uint32_t length FIELD_PACKED; /* length of following data */ + uint8_t data[1] FIELD_PACKED; /* start of data */ +} POSTPACK WMI_HOST_DSET_WRITE_EVENT; + +typedef PREPACK struct +{ + uint32_t dset_id FIELD_PACKED; /* length of following data */ + uint32_t offset FIELD_PACKED; /* length of following data */ + uint32_t length FIELD_PACKED; /* length of following data */ +} POSTPACK WMI_HOST_DSET_READBACK_EVENT; + +typedef PREPACK struct +{ + uint32_t dset_count FIELD_PACKED; /* length of following data */ +} POSTPACK WMI_HOST_DSET_SYNC_EVENT; + +typedef PREPACK struct +{ + uint32_t dset_id FIELD_PACKED; /* dset_id */ + uint32_t status FIELD_PACKED; /* status */ +} POSTPACK WMI_DSET_OP_CREATE_EVENT; + +typedef PREPACK struct +{ + uint32_t dset_id FIELD_PACKED; /* dset_id */ + uint32_t status FIELD_PACKED; /* status */ +} POSTPACK WMI_DSET_OP_OPEN_EVENT; + +typedef PREPACK struct +{ + uint32_t dset_id FIELD_PACKED; /* dset_id */ + uint32_t status FIELD_PACKED; /* status */ + uint32_t offset FIELD_PACKED; /* status */ + uint32_t length FIELD_PACKED; /* status */ + uint8_t data[1]; +} POSTPACK WMI_DSET_OP_READ_EVENT; + +typedef PREPACK struct +{ + uint32_t dset_id FIELD_PACKED; /* dset_id */ + uint32_t status FIELD_PACKED; /* status */ +} POSTPACK WMI_DSET_OP_WRITE_EVENT; + +typedef PREPACK struct +{ + uint32_t dset_id FIELD_PACKED; /* dset_id */ + uint32_t status FIELD_PACKED; /* status */ +} POSTPACK WMI_DSET_OP_COMMIT_EVENT; + +typedef PREPACK struct +{ + uint32_t dset_id FIELD_PACKED; /* dset_id */ + uint32_t status FIELD_PACKED; /* status */ +} POSTPACK WMI_DSET_OP_CLOSE_EVENT; + +typedef PREPACK struct +{ + uint32_t length FIELD_PACKED; /* number of bytes of data to follow */ + uint8_t data[1] FIELD_PACKED; /* start of data */ +} POSTPACK WMI_STORERECALL_READ_CMD; + +typedef PREPACK struct +{ + uint32_t dset_count FIELD_PACKED; /* number of bytes of data to follow */ + uint8_t data[1] FIELD_PACKED; /* start of data */ +} POSTPACK WMI_HOST_DSET_SYNC_CMD; + +typedef PREPACK struct +{ + uint32_t dset_id FIELD_PACKED; /* length of following data */ + uint32_t length FIELD_PACKED; /* length of following data */ + uint32_t offset FIELD_PACKED; /* length of following data */ + uint8_t data[1] FIELD_PACKED; /* start of data */ +} POSTPACK WMI_HOST_DSET_READBACK_CMD; + +typedef PREPACK struct +{ + uint32_t flags FIELD_PACKED; /* number of bytes of data to follow */ +} POSTPACK WMI_HOST_DSET_RESP_CREATE_CMD; + +typedef PREPACK struct +{ + uint32_t dset_id FIELD_PACKED; /* length of following data */ + uint32_t offset FIELD_PACKED; /* length of following data */ + uint32_t length FIELD_PACKED; /* length of following data */ +} POSTPACK WMI_HOST_DSET_RESP_WRITE_CMD; + +typedef PREPACK struct +{ + uint32_t msec_sleep FIELD_PACKED; /* time between power off/on */ +} POSTPACK WMI_STORERECALL_START_EVENT; + +/* STORE / RECALL Commands AND Events DEFINITION END */ +/* WPS Commands AND Events DEFINITION START */ + +typedef PREPACK struct +{ + uint8_t ssid[WMI_MAX_SSID_LEN] FIELD_PACKED; + uint8_t macaddress[ATH_MAC_LEN] FIELD_PACKED; + uint16_t channel FIELD_PACKED; + uint8_t ssid_len FIELD_PACKED; +} POSTPACK WPS_SCAN_LIST_ENTRY; + +typedef enum +{ + WPS_REGISTRAR_ROLE = 0x1, + WPS_ENROLLEE_ROLE = 0x2, + WPS_AP_ENROLLEE_ROLE = 0x3 +} WPS_OPER_MODE; + +typedef enum +{ + WPS_DO_CONNECT_AFTER_CRED_RECVD = 0x1 +} WPS_START_CTRL_FLAG; + +#define WPS_PIN_LEN (8) + +typedef PREPACK struct +{ + uint8_t pin[WPS_PIN_LEN + 1] FIELD_PACKED; + uint8_t pin_length FIELD_PACKED; +} POSTPACK WPS_PIN; + +typedef enum +{ + WPS_PIN_MODE = 0x1, + WPS_PBC_MODE = 0x2 +} WPS_MODE; + +typedef PREPACK struct +{ + WPS_SCAN_LIST_ENTRY ssid_info FIELD_PACKED; + uint8_t config_mode FIELD_PACKED; /* WPS_MODE */ + WPS_PIN wps_pin FIELD_PACKED; + uint8_t timeout FIELD_PACKED; /* in Seconds */ + uint8_t role FIELD_PACKED; /* WPS_OPER_MOD */ + uint8_t ctl_flag FIELD_PACKED; /* WPS_START_CTRL_FLAG */ +} POSTPACK WMI_WPS_START_CMD; + +typedef enum +{ + WPS_STATUS_SUCCESS = 0x0, + WPS_STATUS_FAILURE = 0x1, + WPS_STATUS_IDLE = 0x2, + WPS_STATUS_IN_PROGRESS = 0x3 +} WPS_STATUS; + +typedef PREPACK struct +{ + uint8_t wps_status FIELD_PACKED; /* WPS_STATUS */ + uint8_t wps_state FIELD_PACKED; +} POSTPACK WMI_WPS_GET_STATUS_EVENT; + +typedef enum +{ + WPS_ERROR_INVALID_START_INFO = 0x1, + WPS_ERROR_MULTIPLE_PBC_SESSIONS, + WPS_ERROR_WALKTIMER_TIMEOUT, + WPS_ERROR_M2D_RCVD, + WPS_ERROR_PWD_AUTH_FAIL, + WPS_ERROR_CANCELLED, + WPS_ERROR_INVALID_PIN +} WPS_ERROR_CODE; + +/* Authentication Type Flags */ +#define WPS_CRED_AUTH_OPEN 0x0001 +#define WPS_CRED_AUTH_WPAPSK 0x0002 +#define WPS_CRED_AUTH_SHARED 0x0004 +#define WPS_CRED_AUTH_WPA 0x0008 +#define WPS_CRED_AUTH_WPA2 0x0010 +#define WPS_CRED_AUTH_WPA2PSK 0x0020 + +/* Encryption Type Flags */ +#define WPS_CRED_ENCR_NONE 0x0001 +#define WPS_CRED_ENCR_WEP 0x0002 +#define WPS_CRED_ENCR_TKIP 0x0004 +#define WPS_CRED_ENCR_AES 0x0008 + +typedef PREPACK struct +{ + uint16_t ap_channel FIELD_PACKED; + uint8_t ssid[WMI_MAX_SSID_LEN] FIELD_PACKED; + uint8_t ssid_len FIELD_PACKED; + uint16_t auth_type FIELD_PACKED; + uint16_t encr_type FIELD_PACKED; + uint8_t key_idx FIELD_PACKED; + uint8_t key[64] FIELD_PACKED; + uint8_t key_len FIELD_PACKED; + uint8_t mac_addr[ATH_MAC_LEN] FIELD_PACKED; +} POSTPACK WPS_CREDENTIAL; + +typedef PREPACK struct +{ + uint8_t status FIELD_PACKED; /* WPS_STATUS */ + uint8_t error_code FIELD_PACKED; /* WPS_ERROR_CODE */ + WPS_CREDENTIAL credential FIELD_PACKED; + uint8_t peer_dev_addr[ATH_MAC_LEN] FIELD_PACKED; +} POSTPACK WMI_WPS_PROFILE_EVENT; +/* WPS Commands AND Events DEFINITION END */ + +typedef PREPACK struct +{ + uint8_t enable FIELD_PACKED; /* 1 == device operates in promiscuous mode , 0 == normal mode */ +#define WMI_PROM_FILTER_SRC_ADDR 0x01 +#define WMI_PROM_FILTER_DST_ADDR 0x02 + uint8_t filters FIELD_PACKED; + uint8_t srcAddr[ATH_MAC_LEN] FIELD_PACKED; + uint8_t dstAddr[ATH_MAC_LEN] FIELD_PACKED; +} POSTPACK WMI_SET_FILTERED_PROMISCUOUS_MODE_CMD; + +typedef PREPACK struct +{ + uint16_t channel FIELD_PACKED; /* frequency in Mhz */ +} POSTPACK WMI_SET_CHANNEL_CMD; + +typedef PREPACK struct +{ + uint32_t cmd_type FIELD_PACKED; /*Socket command type*/ + uint32_t length FIELD_PACKED; /* number of bytes of data to follow */ + // uint8_t data[1] FIELD_PACKED; /* start of data */ +} POSTPACK WMI_SOCKET_CMD; + +typedef PREPACK struct +{ + uint32_t resp_type FIELD_PACKED; /*Socket command response type*/ + uint32_t sock_handle FIELD_PACKED; /*Socket handle*/ + uint32_t error FIELD_PACKED; /*Return value*/ + uint8_t data[1] FIELD_PACKED; /*data for socket command e.g. select FDs*/ +} POSTPACK WMI_SOCK_RESPONSE_EVENT; + +#if ENABLE_P2P_MODE + +typedef PREPACK struct +{ + uint8_t flag FIELD_PACKED; +} POSTPACK WMI_P2P_SET_CONCURRENT_MODE; + +typedef PREPACK struct +{ + uint8_t value FIELD_PACKED; +} POSTPACK WMI_P2P_SET_GO_INTENT; + +typedef PREPACK struct +{ + uint8_t enable FIELD_PACKED; +} POSTPACK WMI_P2P_SET_CCK_RATES; + +typedef PREPACK struct +{ + uint8_t go_intent FIELD_PACKED; + uint8_t reserved[3] FIELD_PACKED; /* Deprecated 'country' field */ + uint8_t reg_class FIELD_PACKED; + uint8_t listen_channel FIELD_PACKED; + uint8_t op_reg_class FIELD_PACKED; + uint8_t op_channel FIELD_PACKED; + uint32_t node_age_to FIELD_PACKED; + uint8_t max_node_count FIELD_PACKED; +} POSTPACK WMI_P2P_FW_SET_CONFIG_CMD; + +typedef PREPACK struct +{ + uint8_t enable FIELD_PACKED; +} POSTPACK WMI_P2P_SET_PROFILE_CMD; + +typedef PREPACK struct +{ + uint16_t categ FIELD_PACKED; + uint16_t sub_categ FIELD_PACKED; +} POSTPACK device_type_tuple; + +typedef PREPACK struct +{ + device_type_tuple pri_dev_type FIELD_PACKED; + uint8_t pri_device_type[8] FIELD_PACKED; +#define MAX_P2P_SEC_DEVICE_TYPES 5 + device_type_tuple sec_dev_type[MAX_P2P_SEC_DEVICE_TYPES] FIELD_PACKED; +#define WPS_UUID_LEN 16 + uint8_t uuid[WPS_UUID_LEN] FIELD_PACKED; +#define WPS_MAX_DEVNAME_LEN 32 + uint8_t device_name[WPS_MAX_DEVNAME_LEN] FIELD_PACKED; + uint8_t dev_name_len FIELD_PACKED; +} POSTPACK WMI_WPS_SET_CONFIG_CMD; + +typedef PREPACK struct +{ + device_type_tuple pri_dev_type FIELD_PACKED; + device_type_tuple sec_dev_type[MAX_P2P_SEC_DEVICE_TYPES] FIELD_PACKED; + uint8_t device_addr[ATH_MAC_LEN] FIELD_PACKED; +} POSTPACK WMI_SET_REQ_DEV_ATTR_CMD; + +#define MAX_LIST_COUNT 8 +#define MAX_PASS_LEN 32 + +typedef PREPACK struct +{ + uint8_t data[1]; +} POSTPACK WMI_P2P_PERSISTENT_LIST_NETWORK_EVENT; + +typedef PREPACK struct +{ + uint8_t role; + uint8_t macaddr[ATH_MAC_LEN]; + uint8_t ssid[WMI_MAX_SSID_LEN]; + uint8_t passphrase[MAX_PASS_LEN]; +} POSTPACK WMI_PERSISTENT_MAC_LIST; + +typedef PREPACK struct +{ + uint8_t ssidLength FIELD_PACKED; + uint8_t ssid[WMI_MAX_SSID_LEN] FIELD_PACKED; +} POSTPACK P2P_SSID; + +typedef enum wmi_p2p_discovery_type +{ + WMI_P2P_FIND_START_WITH_FULL, + WMI_P2P_FIND_ONLY_SOCIAL, + WMI_P2P_FIND_PROGRESSIVE +} WMI_P2P_DISC_TYPE; + +typedef PREPACK struct +{ + uint32_t timeout FIELD_PACKED; + uint8_t type FIELD_PACKED; +} POSTPACK WMI_P2P_FIND_CMD; + +typedef PREPACK struct +{ + uint16_t listen_freq FIELD_PACKED; + uint16_t force_freq FIELD_PACKED; + uint16_t go_oper_freq FIELD_PACKED; + uint8_t dialog_token FIELD_PACKED; + uint8_t peer_addr[ATH_MAC_LEN] FIELD_PACKED; + uint8_t own_interface_addr[ATH_MAC_LEN] FIELD_PACKED; + uint8_t member_in_go_dev[ATH_MAC_LEN] FIELD_PACKED; + uint8_t go_dev_dialog_token FIELD_PACKED; + P2P_SSID peer_go_ssid FIELD_PACKED; + uint8_t wps_method FIELD_PACKED; + uint8_t dev_capab FIELD_PACKED; + int8_t go_intent FIELD_PACKED; + uint8_t persistent_grp FIELD_PACKED; +} POSTPACK WMI_P2P_GO_NEG_START_CMD; + +typedef PREPACK struct +{ + uint8_t persistent_group FIELD_PACKED; + uint8_t group_formation FIELD_PACKED; +} POSTPACK WMI_P2P_GRP_INIT_CMD; + +typedef PREPACK struct +{ + uint8_t peer_addr[ATH_MAC_LEN] FIELD_PACKED; + uint8_t grp_formation_status FIELD_PACKED; +} POSTPACK WMI_P2P_GRP_FORMATION_DONE_CMD; + +typedef PREPACK struct +{ + uint32_t timeout FIELD_PACKED; +} POSTPACK WMI_P2P_LISTEN_CMD; + +typedef PREPACK struct +{ + uint16_t listen_freq FIELD_PACKED; + uint16_t force_freq FIELD_PACKED; + uint8_t status FIELD_PACKED; + int8_t go_intent FIELD_PACKED; + uint8_t wps_buf[512] FIELD_PACKED; + uint16_t wps_buflen FIELD_PACKED; + uint8_t p2p_buf[512] FIELD_PACKED; + uint16_t p2p_buflen FIELD_PACKED; + uint8_t dialog_token FIELD_PACKED; + uint8_t wps_method FIELD_PACKED; + uint8_t persistent_grp FIELD_PACKED; +} POSTPACK WMI_P2P_GO_NEG_REQ_RSP_CMD; + +typedef enum +{ + WMI_P2P_INVITE_ROLE_GO, + WMI_P2P_INVITE_ROLE_ACTIVE_GO, + WMI_P2P_INVITE_ROLE_CLIENT +} WMI_P2P_INVITE_ROLE; + +typedef PREPACK struct +{ + uint8_t role FIELD_PACKED; + uint16_t listen_freq FIELD_PACKED; + uint16_t force_freq FIELD_PACKED; + uint8_t dialog_token FIELD_PACKED; + uint8_t peer_addr[ATH_MAC_LEN] FIELD_PACKED; + uint8_t bssid[ATH_MAC_LEN] FIELD_PACKED; + uint8_t go_dev_addr[ATH_MAC_LEN] FIELD_PACKED; + P2P_SSID ssid FIELD_PACKED; + uint8_t is_persistent FIELD_PACKED; + uint8_t wps_method FIELD_PACKED; +} POSTPACK WMI_P2P_INVITE_CMD; + +typedef PREPACK struct +{ + uint16_t force_freq FIELD_PACKED; + uint8_t status FIELD_PACKED; + uint8_t dialog_token FIELD_PACKED; + // uint8_t p2p_buf[512]; + uint16_t p2p_buflen FIELD_PACKED; + uint8_t is_go FIELD_PACKED; + uint8_t group_bssid[ATH_MAC_LEN] FIELD_PACKED; +} POSTPACK WMI_P2P_INVITE_REQ_RSP_CMD; + +typedef PREPACK struct +{ + uint16_t force_freq FIELD_PACKED; + uint8_t status FIELD_PACKED; + uint8_t dialog_token FIELD_PACKED; + uint8_t is_go FIELD_PACKED; + uint8_t group_bssid[ATH_MAC_LEN] FIELD_PACKED; +} POSTPACK WMI_P2P_FW_INVITE_REQ_RSP_CMD; + +typedef PREPACK struct +{ + uint16_t wps_method FIELD_PACKED; + uint16_t listen_freq FIELD_PACKED; + uint8_t dialog_token FIELD_PACKED; + uint8_t peer[ATH_MAC_LEN] FIELD_PACKED; + uint8_t go_dev_addr[ATH_MAC_LEN] FIELD_PACKED; + P2P_SSID go_oper_ssid FIELD_PACKED; +} POSTPACK WMI_P2P_PROV_DISC_REQ_CMD; + +typedef enum +{ + WMI_P2P_CONFID_LISTEN_CHANNEL = 1, + WMI_P2P_CONFID_CROSS_CONNECT = 2, + WMI_P2P_CONFID_SSID_POSTFIX = 3, + WMI_P2P_CONFID_INTRA_BSS = 4, + WMI_P2P_CONFID_CONCURRENT_MODE = 5, + WMI_P2P_CONFID_GO_INTENT = 6, + WMI_P2P_CONFID_DEV_NAME = 7, + WMI_P2P_CONFID_P2P_OPMODE = 8, + WMI_P2P_CONFID_CCK_RATES = 9 +} WMI_P2P_CONF_ID; + +typedef PREPACK struct +{ + uint8_t reg_class FIELD_PACKED; + uint8_t listen_channel FIELD_PACKED; +} POSTPACK WMI_P2P_LISTEN_CHANNEL; + +typedef PREPACK struct +{ + uint8_t flag FIELD_PACKED; +} POSTPACK WMI_P2P_SET_CROSS_CONNECT; + +typedef PREPACK struct +{ + uint8_t ssid_postfix[WMI_MAX_SSID_LEN - 9] FIELD_PACKED; + uint8_t ssid_postfix_len FIELD_PACKED; +} POSTPACK WMI_P2P_SET_SSID_POSTFIX; + +typedef PREPACK struct +{ + uint8_t flag FIELD_PACKED; +} POSTPACK WMI_P2P_SET_INTRA_BSS; + +#define P2P_DEV (1 << 0) +#define P2P_CLIENT (1 << 1) +#define P2P_GO (1 << 2) +#define P2P_PERSISTENT_FLAG 0x80 +typedef PREPACK struct +{ + uint8_t p2pmode FIELD_PACKED; +} POSTPACK WMI_P2P_SET_MODE; + +#define RATECTRL_MODE_DEFAULT 0 +#define RATECTRL_MODE_PERONLY 1 + +typedef PREPACK struct +{ + uint32_t mode FIELD_PACKED; +} POSTPACK WMI_SET_RATECTRL_PARM_CMD; + +#define WMI_P2P_MAX_TLV_LEN 1024 +typedef enum +{ + WMI_P2P_SD_TYPE_GAS_INITIAL_REQ = 0x1, + WMI_P2P_SD_TYPE_GAS_INITIAL_RESP = 0x2, + WMI_P2P_SD_TYPE_GAS_COMEBACK_REQ = 0x3, + WMI_P2P_SD_TYPE_GAS_COMEBACK_RESP = 0x4, + WMI_P2P_PD_TYPE_RESP = 0x5, + WMI_P2P_SD_TYPE_STATUS_IND = 0x6 +} WMI_P2P_SDPD_TYPE; + +typedef enum +{ + WMI_P2P_SDPD_TRANSACTION_PENDING = 0x1, + WMI_P2P_SDPD_TRANSACTION_COMP = 0x2 +} WMI_P2P_SDPD_TRANSACTION_STATUS; + +typedef PREPACK struct +{ + uint8_t type FIELD_PACKED; + uint8_t dialog_token FIELD_PACKED; + uint8_t frag_id FIELD_PACKED; + uint8_t reserved1 FIELD_PACKED; /* alignment */ + uint8_t peer_addr[ATH_MAC_LEN] FIELD_PACKED; + uint16_t freq FIELD_PACKED; + uint16_t status_code FIELD_PACKED; + uint16_t comeback_delay FIELD_PACKED; + uint16_t tlv_length FIELD_PACKED; + uint16_t update_indic FIELD_PACKED; + uint16_t total_length FIELD_PACKED; + uint16_t reserved2 FIELD_PACKED; /* future */ + uint8_t tlv[WMI_P2P_MAX_TLV_LEN] FIELD_PACKED; +} POSTPACK WMI_P2P_SDPD_TX_CMD; + +typedef PREPACK struct +{ + uint16_t go_oper_freq FIELD_PACKED; + uint8_t dialog_token FIELD_PACKED; + uint8_t peer_addr[ATH_MAC_LEN] FIELD_PACKED; + uint8_t own_interface_addr[ATH_MAC_LEN] FIELD_PACKED; + uint8_t go_dev_dialog_token FIELD_PACKED; + P2P_SSID peer_go_ssid FIELD_PACKED; + uint8_t wps_method FIELD_PACKED; + uint8_t dev_capab FIELD_PACKED; + uint8_t dev_auth FIELD_PACKED; + uint8_t go_intent FIELD_PACKED; +} POSTPACK WMI_P2P_FW_CONNECT_CMD_STRUCT; + +typedef PREPACK struct +{ + uint16_t wps_method FIELD_PACKED; + uint8_t dialog_token FIELD_PACKED; + uint8_t peer[ATH_MAC_LEN] FIELD_PACKED; +} POSTPACK WMI_P2P_FW_PROV_DISC_REQ_CMD; + +/* P2P module events */ + +typedef PREPACK struct +{ + uint8_t num_p2p_dev FIELD_PACKED; + uint8_t data[1] FIELD_PACKED; +} POSTPACK WMI_P2P_NODE_LIST_EVENT; + +typedef PREPACK struct +{ + uint8_t sa[ATH_MAC_LEN] FIELD_PACKED; + uint8_t dialog_token FIELD_PACKED; + uint16_t dev_password_id FIELD_PACKED; +} POSTPACK WMI_P2P_REQ_TO_AUTH_EVENT; + +typedef PREPACK struct +{ + uint8_t sa[ATH_MAC_LEN] FIELD_PACKED; + uint8_t wps_buf[512] FIELD_PACKED; + uint16_t wps_buflen FIELD_PACKED; + uint8_t p2p_buf[512] FIELD_PACKED; + uint16_t p2p_buflen FIELD_PACKED; + uint8_t dialog_token FIELD_PACKED; +} POSTPACK WMI_P2P_GO_NEG_REQ_EVENT; + +typedef PREPACK struct +{ + uint16_t freq FIELD_PACKED; + int8_t status FIELD_PACKED; + uint8_t role_go FIELD_PACKED; + uint8_t ssid[WMI_MAX_SSID_LEN] FIELD_PACKED; + uint8_t ssid_len FIELD_PACKED; +#define WMI_MAX_PASSPHRASE_LEN 9 + char pass_phrase[WMI_MAX_PASSPHRASE_LEN] FIELD_PACKED; + uint8_t peer_device_addr[ATH_MAC_LEN] FIELD_PACKED; + uint8_t peer_interface_addr[ATH_MAC_LEN] FIELD_PACKED; + uint8_t wps_method FIELD_PACKED; + uint8_t persistent_grp FIELD_PACKED; +} POSTPACK WMI_P2P_GO_NEG_RESULT_EVENT; + +typedef PREPACK struct +{ + uint8_t sa[ATH_MAC_LEN] FIELD_PACKED; + uint8_t bssid[ATH_MAC_LEN] FIELD_PACKED; + uint8_t go_dev_addr[ATH_MAC_LEN] FIELD_PACKED; + P2P_SSID ssid FIELD_PACKED; + uint8_t is_persistent FIELD_PACKED; + uint8_t dialog_token FIELD_PACKED; +} POSTPACK WMI_P2P_FW_INVITE_REQ_EVENT; + +typedef PREPACK struct +{ + uint16_t oper_freq FIELD_PACKED; + uint8_t sa[ATH_MAC_LEN] FIELD_PACKED; + uint8_t bssid[ATH_MAC_LEN] FIELD_PACKED; + uint8_t is_bssid_valid FIELD_PACKED; + uint8_t go_dev_addr[ATH_MAC_LEN] FIELD_PACKED; + P2P_SSID ssid FIELD_PACKED; + uint8_t status FIELD_PACKED; +} POSTPACK WMI_P2P_INVITE_RCVD_RESULT_EVENT; + +typedef PREPACK struct +{ + uint8_t status FIELD_PACKED; + uint8_t bssid[ATH_MAC_LEN] FIELD_PACKED; + uint8_t is_bssid_valid FIELD_PACKED; +} POSTPACK WMI_P2P_INVITE_SENT_RESULT_EVENT; + +typedef PREPACK struct +{ + uint8_t sa[ATH_MAC_LEN] FIELD_PACKED; + uint16_t wps_config_method FIELD_PACKED; + uint8_t dev_addr[ATH_MAC_LEN] FIELD_PACKED; +#define WPS_DEV_TYPE_LEN 8 +#define WPS_MAX_DEVNAME_LEN 32 + uint8_t pri_dev_type[WPS_DEV_TYPE_LEN] FIELD_PACKED; + uint8_t device_name[WPS_MAX_DEVNAME_LEN] FIELD_PACKED; + uint8_t dev_name_len FIELD_PACKED; + uint16_t dev_config_methods FIELD_PACKED; + uint8_t device_capab FIELD_PACKED; + uint8_t group_capab FIELD_PACKED; +} POSTPACK WMI_P2P_PROV_DISC_REQ_EVENT; + +typedef PREPACK struct +{ + uint8_t peer[ATH_MAC_LEN] FIELD_PACKED; + uint16_t config_methods FIELD_PACKED; +} POSTPACK WMI_P2P_PROV_DISC_RESP_EVENT; + +typedef PREPACK struct +{ + uint8_t type FIELD_PACKED; + uint8_t transaction_status FIELD_PACKED; + uint8_t dialog_token FIELD_PACKED; + uint8_t frag_id FIELD_PACKED; + uint8_t peer_addr[ATH_MAC_LEN] FIELD_PACKED; + uint16_t freq FIELD_PACKED; + uint16_t status_code FIELD_PACKED; + uint16_t comeback_delay FIELD_PACKED; + uint16_t tlv_length FIELD_PACKED; + uint16_t update_indic FIELD_PACKED; + // Variable length TLV will be placed after the event +} POSTPACK WMI_P2P_SDPD_RX_EVENT; + +typedef PREPACK struct +{ + char wps_pin[WPS_PIN_LEN] FIELD_PACKED; + uint8_t peer_addr[ATH_MAC_LEN] FIELD_PACKED; + uint8_t wps_role FIELD_PACKED; +} POSTPACK WMI_P2P_PROV_INFO; + +typedef PREPACK struct +{ + WPS_CREDENTIAL credential FIELD_PACKED; +} POSTPACK WMI_P2P_PERSISTENT_PROFILE_CMD; + +#endif + +#if ENABLE_P2P_MODE + +typedef PREPACK struct +{ + uint8_t dev_name[WPS_MAX_DEVNAME_LEN] FIELD_PACKED; + uint8_t dev_name_len FIELD_PACKED; +} POSTPACK WMI_P2P_SET_DEV_NAME; + +typedef PREPACK struct +{ + uint8_t config_id; /* set to one of WMI_P2P_CONF_ID */ + PREPACK union + { + WMI_P2P_LISTEN_CHANNEL listen_ch; + WMI_P2P_SET_CROSS_CONNECT cross_conn; + WMI_P2P_SET_SSID_POSTFIX ssid_postfix; + WMI_P2P_SET_INTRA_BSS intra_bss; + WMI_P2P_SET_CONCURRENT_MODE concurrent_mode; + WMI_P2P_SET_GO_INTENT go_intent; + WMI_P2P_SET_DEV_NAME device_name; + WMI_P2P_SET_MODE mode; + WMI_P2P_SET_CCK_RATES cck_rates; + } POSTPACK val; +} POSTPACK WMI_P2P_SET_CMD; + +typedef PREPACK struct +{ + uint32_t duration FIELD_PACKED; + uint32_t interval FIELD_PACKED; + uint32_t start_or_offset FIELD_PACKED; + uint8_t count_or_type FIELD_PACKED; +} POSTPACK P2P_NOA_DESCRIPTOR; + +typedef PREPACK struct +{ + uint8_t enable FIELD_PACKED; + uint8_t count FIELD_PACKED; + uint8_t noas[1] FIELD_PACKED; +} POSTPACK WMI_NOA_INFO_STRUCT; + +typedef PREPACK struct +{ + uint8_t enable FIELD_PACKED; + uint8_t ctwin FIELD_PACKED; +} POSTPACK WMI_OPPPS_INFO_STRUCT; + +#endif + +typedef PREPACK struct +{ + boolean enable FIELD_PACKED; + uint8_t nextProbeCount FIELD_PACKED; + uint8_t maxBackOff FIELD_PACKED; + uint8_t minGtxRssi FIELD_PACKED; + uint8_t forceBackOff FIELD_PACKED; +} POSTPACK WMI_GREENTX_PARAMS_CMD; + +/* LPL commands */ +typedef PREPACK struct +{ + uint8_t lplPolicy FIELD_PACKED; /*0 - force off, 1 force on, 2 dynamic*/ + uint8_t noBlockerDetect FIELD_PACKED; /*don't do blocker detection if lpl policy is set + to dynamic*/ + uint8_t noRfbDetect FIELD_PACKED; /*don't do rate fall back detection if lpl policy is set + to dynamic*/ + uint8_t rsvd FIELD_PACKED; +} POSTPACK WMI_LPL_FORCE_ENABLE_CMD; + +/* + * Extended WMI commands are those that are needed during wireless + * operation, but which are not really wireless commands. This allows, + * for instance, platform-specific commands. Extended WMI commands are + * embedded in a WMI command message with WMI_COMMAND_ID=WMI_EXTENSION_CMDID. + * Extended WMI events are similarly embedded in a WMI event message with + * WMI_EVENT_ID=WMI_EXTENSION_EVENTID. + */ +typedef PREPACK struct +{ + uint32_t commandId FIELD_PACKED; +} POSTPACK WMIX_CMD_HDR; + +#define WMIX_GPIO_OUTPUT_SET_CMDID 0x2003 +#define WMIX_GPIO_INPUT_GET_CMDID 0x2004 +#define WMIX_GPIO_REGISTER_SET_CMDID 0x2005 +#define WMIX_GPIO_REGISTER_GET_CMDID 0x2006 +#define WMIX_HB_CHALLENGE_RESP_CMDID 0x2008 +#define WMIX_DBGLOG_CFG_MODULE_CMDID 0x2009 +#define WMIX_GPIO_DATA_EVENTID 0x3005 +#define WMIX_HB_CHALLENGE_RESP_EVENTID 0x3007 +#define WMIX_DBGLOG_EVENTID 0x3008 +#define WMIX_PFM_DATA_EVENTID 0x300C +#define WMIX_PFM_DATA_DONE_EVENTID 0x300D + +/* + * =============GPIO support================= + * NB: Some of the WMIX APIs use a 32-bit mask. On Targets that support + * more than 32 GPIO pins, those APIs only support the first 32 GPIO pins. + */ + +/* + * Set GPIO pin output state. + * In order for output to be driven, a pin must be enabled for output. + * This can be done during initialization through the GPIO Configuration + * DataSet, or during operation with the enable_mask. + * + * If a request is made to simultaneously set/clear or set/disable or + * clear/disable or disable/enable, results are undefined. + */ +typedef PREPACK struct +{ + uint32_t set_mask; /* pins to set */ + uint32_t clear_mask; /* pins to clear */ + uint32_t enable_mask; /* pins to enable for output */ + uint32_t disable_mask; /* pins to disable/tristate */ +} POSTPACK WMIX_GPIO_OUTPUT_SET_CMD; + +/* + * Set a GPIO register. For debug/exceptional cases. + * Values for gpioreg_id are GPIO_ID_*, defined in a + * platform-dependent header, gpio.h. + */ +typedef PREPACK struct +{ + uint32_t gpioreg_id; /* GPIO register ID */ + uint32_t value; /* value to write */ +} POSTPACK WMIX_GPIO_REGISTER_SET_CMD; + +/* Get a GPIO register. For debug/exceptional cases. */ +typedef PREPACK struct +{ + uint32_t gpioreg_id; /* GPIO register to read */ +} POSTPACK WMIX_GPIO_REGISTER_GET_CMD; + +/* + * Host acknowledges and re-arms GPIO interrupts. A single + * message should be used to acknowledge all interrupts that + * were delivered in an earlier WMIX_GPIO_INTR_EVENT message. + */ +typedef PREPACK struct +{ + uint32_t ack_mask; /* interrupts to acknowledge */ +} POSTPACK WMIX_GPIO_INTR_ACK_CMD; + +/* + * Target informs Host of GPIO interrupts that have ocurred since the + * last WMIX_GIPO_INTR_ACK_CMD was received. Additional information -- + * the current GPIO input values is provided -- in order to support + * use of a GPIO interrupt as a Data Valid signal for other GPIO pins. + */ +typedef PREPACK struct +{ + uint32_t intr_mask; /* pending GPIO interrupts */ + uint32_t input_values; /* recent GPIO input values */ +} POSTPACK WMIX_GPIO_INTR_EVENT; + +/* + * WMIX_HB_CHALLENGE_RESP_CMDID + * Heartbeat Challenge Response command + */ +typedef PREPACK struct { + uint32_t cookie; + uint32_t source; +} POSTPACK WMIX_HB_CHALLENGE_RESP_CMD; + +#define WMIX_HB_CHALLENGE_RESP_EVENT WMIX_HB_CHALLENGE_RESP_CMD + +/* + * Target responds to Host's earlier WMIX_GPIO_INPUT_GET_CMDID request + * using a GPIO_DATA_EVENT with + * value set to the mask of GPIO pin inputs and + * reg_id set to GPIO_ID_NONE + * + * + * Target responds to Hosts's earlier WMIX_GPIO_REGISTER_GET_CMDID request + * using a GPIO_DATA_EVENT with + * value set to the value of the requested register and + * reg_id identifying the register (reflects the original request) + * NB: reg_id supports the future possibility of unsolicited + * WMIX_GPIO_DATA_EVENTs (for polling GPIO input), and it may + * simplify Host GPIO support. + */ +typedef PREPACK struct +{ + uint32_t value; + uint32_t reg_id; +} POSTPACK WMIX_GPIO_DATA_EVENT; + +/*----------------------------------------------------------------------------------------------------------------------*/ +/*----------------------------------------------------------------------------------------------------------------------*/ + +typedef PREPACK struct +{ + uint8_t max_queued_buffers FIELD_PACKED; /*don't do blocker detection if lpl policy is set to dynamic*/ + uint8_t endpoint_mapping[8] FIELD_PACKED; /*don't do rate fall back detection if lpl policy is set to dynamic*/ + uint8_t start_credits_per_queue[8] FIELD_PACKED; + uint8_t num_credit_queues FIELD_PACKED; /*0 - force off, 1 force on, 2 dynamic*/ +} POSTPACK WMI_INIT_REVERSE_CREDIT_CMD; + +typedef PREPACK struct +{ + uint8_t offset FIELD_PACKED; + uint8_t shift FIELD_PACKED; + uint32_t mask FIELD_PACKED; + uint8_t count FIELD_PACKED; + uint32_t category_mapping_data[8] FIELD_PACKED; + uint8_t ep_mapping_data[8] FIELD_PACKED; + +} POSTPACK WMI_INIT_RCV_DATA_CLASSIFIER_CMD; + +typedef PREPACK struct +{ + uint32_t log_time; + uint16_t event_id; + uint16_t unused; +} POSTPACK WMIX_PFM_DATA_EVENT; + +typedef PREPACK struct +{ + boolean enable FIELD_PACKED; +} POSTPACK WMID_EVENT_SET_CMD; + +typedef struct ath_pmu_param +{ + uint32_t options; + uint32_t wake_msec; +} ATH_PMU_PARAM; + +typedef struct ath_pfm_param +{ + uint32_t options; +} ATH_PFM_PARAM; + +typedef struct ath_dset_param +{ + uint32_t dset_id; + uint32_t offset; + uint32_t length; + +} ATH_DSET_PARAM; + +#define MAX_TIMESTAMP 32 + +typedef PREPACK struct +{ + uint8_t eventID[MAX_TIMESTAMP] FIELD_PACKED; + uint32_t timestamp[MAX_TIMESTAMP] FIELD_PACKED; +} POSTPACK WMI_PFM_REPORT_EVENT; + +typedef struct +{ + uint16_t dset_id; + uint16_t len; + uint32_t offset; +} POSTPACK WMI_DSET_HOST_CFG_ITEM; + +typedef struct +{ + uint32_t length; + WMI_DSET_HOST_CFG_ITEM dset[2]; +} POSTPACK WMI_DSET_HOST_CFG_CMD; + +/* + * Extended WMIX_DSET commands are those that are needed for host dset + * operation + */ +typedef PREPACK struct +{ + uint32_t commandId FIELD_PACKED; +} POSTPACK WMIX_DSET_CMD_HDR; + +#define WMIX_DSET_CREATE_CMDID 0x1001 +#define WMIX_DSET_OPEN_CMDID 0x1002 +#define WMIX_DSET_READ_CMDID 0x1003 +#define WMIX_DSET_WRITE_CMDID 0x1004 +#define WMIX_DSET_COMMIT_CMDID 0x1005 +#define WMIX_DSET_CLOSE_CMDID 0x1006 +#define WMIX_DSET_SIZE_CMDID 0x1007 +#define WMIX_DSET_DELETE_CMDID 0x1008 + +typedef PREPACK struct +{ + WMIX_DSET_CMD_HDR hdr; + uint8_t data[1] FIELD_PACKED; /* start of data */ +} POSTPACK WMI_DSET_OP_EVENT; + +/* + */ +typedef PREPACK struct +{ + uint32_t dset_id FIELD_PACKED; + uint32_t flags FIELD_PACKED; + uint32_t length FIELD_PACKED; +} POSTPACK WMIX_DSET_OP_CREATE_PARAM_CMD; + +typedef PREPACK struct +{ + uint32_t dset_id FIELD_PACKED; + uint32_t flags FIELD_PACKED; +} POSTPACK WMIX_DSET_OP_OPEN_PARAM_CMD; + +typedef PREPACK struct +{ + uint32_t dset_id FIELD_PACKED; +} POSTPACK WMIX_DSET_OP_COMMIT_PARAM_CMD; + +typedef PREPACK struct +{ + uint32_t dset_id FIELD_PACKED; +} POSTPACK WMIX_DSET_OP_CLOSE_PARAM_CMD; + +typedef PREPACK struct +{ + uint32_t dset_id FIELD_PACKED; + uint32_t flags FIELD_PACKED; +} POSTPACK WMIX_DSET_OP_DELETE_PARAM_CMD; + +typedef PREPACK struct +{ + uint32_t dset_id FIELD_PACKED; + uint32_t flags FIELD_PACKED; + uint32_t offset FIELD_PACKED; + uint32_t length FIELD_PACKED; + uint8_t data[1] FIELD_PACKED; +} POSTPACK WMIX_DSET_OP_WRITE_PARAM_CMD; + +typedef PREPACK struct +{ + uint32_t dset_id FIELD_PACKED; + uint32_t offset FIELD_PACKED; + uint32_t length FIELD_PACKED; +} POSTPACK WMIX_DSET_OP_READ_PARAM_CMD; + +/*Define all SET/GET Param Groups here */ +#define QCOM_GROUPID_OFFSET 16 + +#define QCOM_GROUPID_MASK 0xFFFF + +#define QCOM_PARAMID_MASK 0xFFFF + +#define QCOM_PARAM_MAKE_ID(grpid, paramid) (grpid << QCOM_GROUPID_OFFSET | paramid) + +#define QCOM_PARAM_GET_GROUP_ID(which_param) (which_param >> QCOM_GROUPID_OFFSET && QCOM_GROUPID_MASK) + +#define QCOM_PARAM_GET_PARAM_ID(which_param) (which_param && QCOM_PARAMID_MASK) + +/* WMI_SYS_SET_PARAM_REPLY */ + +typedef PREPACK struct +{ + A_STATUS status; +} POSTPACK WMI_PARAM_SET_REPLY; + +/* WMI_SYS_SET_PARAMS */ + +typedef PREPACK struct +{ + uint32_t length; + uint32_t which_param; + uint8_t data_buffer[1]; +} POSTPACK WMI_PARAM_SET_CMD; + +#ifdef __cplusplus +} +#endif + +#endif /* _WMI_H_ */ diff --git a/platform/mcu/lpc54102/wifi_qca/port/a_osapi.h b/platform/mcu/lpc54102/wifi_qca/port/a_osapi.h new file mode 100644 index 0000000000..06d39f73f2 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/port/a_osapi.h @@ -0,0 +1,196 @@ +//------------------------------------------------------------------------------ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//------------------------------------------------------------------------------ +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== +#ifndef _A_OSAPI_H_ +#define _A_OSAPI_H_ + +/* PORT_NOTE: Include any System header files here to resolve any types used + * in A_CUSTOM_DRIVER_CONTEXT */ +#include + +#include "a_config.h" +#include "a_types.h" +#include +#include + +#define MEM_TYPE_ATHEROS_PERSIST_RX_PCB 0x2001 + +/* there exist within the common code a few places that make use of the + * inline option. This macro can be used to properly declare inline for the compiler + * or it can be used to disable inlining be leaving the macro blank. + */ +#ifndef INLINE +#define INLINE inline +#endif +/* PREPACK and/or POSTPACK are used with compilers that require each data structure + * that requires single byte alignment be declared individually. these macros typically + * would be used in place of athstartpack.h and athendpack.h which would be used with + * compilers that allow this feature to be invoked through a one-time pre-processor command. + */ + +#if defined(__ICCARM__) +# define PREPACK __packed +# define POSTPACK +# define FIELD_PACKED +# define PREWEAK_CODE __weak +# define POSTWEAK_CODE +#elif defined(__GNUC__) +# define PREPACK +# define POSTPACK __attribute__ ((__packed__)) +# define FIELD_PACKED +# define PREWEAK_CODE +# define POSTWEAK_CODE __attribute__((weak)) +#elif defined(__CC_ARM) +# define PREPACK __packed +# define POSTPACK +# define FIELD_PACKED +# define PREWEAK_CODE __weak +# define POSTWEAK_CODE +#else +# error "Unsupported toolchain" +#endif + +#ifndef min +#define min(a, b) ((a) < (b)) ? (a) : (b) +#endif + +#ifndef max +#define max(a, b) ((a) > (b)) ? (a) : (b) +#endif + +/* unaligned little endian access */ +#define A_LE_READ_2(p) ((uint16_t)((((uint8_t *)(p))[0]) | (((uint8_t *)(p))[1] << 8))) + +#define A_LE_READ_4(p) \ + ((uint32_t)((((uint8_t *)(p))[0]) | (((uint8_t *)(p))[1] << 8) | (((uint8_t *)(p))[2] << 16) | \ + (((uint8_t *)(p))[3] << 24))) + +/* + * Endianes macros - Used to achieve proper translation to/from wifi chipset endianess. + * these macros should be directed to OS macros or functions that serve this purpose. the + * naming convention is the direction of translation (BE2CPU == BigEndian to native CPU) + * appended with the bit-size (BE2CPU16 == 16 bit operation BE2CPU32 == 32 bit operation + */ + +#if !defined(A_LITTLE_ENDIAN) && !defined(A_BIG_ENDIAN) +# error "Either A_BIG_ENDIAN or A_LITTLE_ENDIAN must be #defined" +#elif defined(A_LITTLE_ENDIAN) && defined(A_BIG_ENDIAN) +# error "A_BIG_ENDIAN and A_LITTLE_ENDIAN cannot be #defined at the same time" +#elif defined(A_LITTLE_ENDIAN) +# define A_BE2CPU16(x) ((uint16_t)(((x) << 8) & 0xff00) | (uint16_t)(((x) >> 8) & 0x00ff)) +# define A_BE2CPU32(x) \ + ((((x) << 24) & 0xff000000) | (((x)&0x0000ff00) << 8) | (((x)&0x00ff0000) >> 8) | (((x) >> 24) & 0x000000ff)) +# define A_LE2CPU16(x) (x) +# define A_LE2CPU32(x) (x) +# define A_CPU2BE16(x) ((uint16_t)(((x) << 8) & 0xff00) | (uint16_t)(((x) >> 8) & 0x00ff)) +# define A_CPU2BE32(x) \ + ((((x) << 24) & 0xff000000) | (((x)&0x0000ff00) << 8) | (((x)&0x00ff0000) >> 8) | (((x) >> 24) & 0x000000ff)) +# define A_CPU2LE32(x) (x) +# define A_CPU2LE16(x) (x) +#elif defined(A_BIG_ENDIAN) +# define A_BE2CPU16(x) (x) +# define A_BE2CPU32(x) (x) +# define A_LE2CPU16(x) ((uint16_t)(((x) << 8) & 0xff00) | (uint16_t)(((x) >> 8) & 0x00ff)) +# define A_LE2CPU32(x) \ + ((((x) << 24) & 0xff000000) | (((x)&0x0000ff00) << 8) | (((x)&0x00ff0000) >> 8) | (((x) >> 24) & 0x000000ff)) +# define A_CPU2BE16(x) (x) +# define A_CPU2BE32(x) (x) +# define A_CPU2LE32(x) \ + ((((x) << 24) & 0xff000000) | (((x)&0x0000ff00) << 8) | (((x)&0x00ff0000) >> 8) | (((x) >> 24) & 0x000000ff)) +# define A_CPU2LE16(x) ((uint16_t)(((x) << 8) & 0xff00) | (uint16_t)(((x) >> 8) & 0x00ff)) +#endif + +/* A_MEM -- macros that should be mapped to OS/STDLIB equivalent functions */ +#define A_MEMCPY(dst, src, len) memcpy((dst), (src), (len)) +#define A_MEMZERO(addr, len) memset((addr), 0, (len)) +#define A_MEMCMP(addr1, addr2, len) memcmp((addr1), (addr2), (len)) + +extern uint32_t g_totAlloc; +extern uint32_t g_poolid; + +#define DRIVER_STATE_INVALID 0 +#define DRIVER_STATE_INIT 1 +#define DRIVER_STATE_RUN 2 +#define DRIVER_STATE_SHUTDOWN 3 +extern uint8_t g_driverState; + +inline uint32_t _get_size(void *addr) +{ + uint32_t *ptr = addr; + ptr -= 3; + + if (g_poolid == 0xffffffff) + { + g_poolid = ptr[1]; + } + + if (ptr[1] == g_poolid) + { + return ptr[0]; + } + else + { + QCADRV_PRINTF("STUCK\n"); + while (1) + { + }; + } +} + +void *a_malloc(int32_t size, uint8_t id); +void a_free(void *addr, uint8_t id); + +/* Definitions used for ID param in calls to A_MALLOC and A_FREE */ +// NAME VALUE DESCRIPTION +#define MALLOC_ID_CONTEXT 1 // persistent allocation for the life of Driver +#define MALLOC_ID_NETBUFF 2 // buffer used to perform TX/RX SPI transaction +#define MALLOC_ID_NETBUFF_OBJ 3 // NETBUF object +#define MALLOC_ID_TEMPORARY 4 // other temporary allocation +/* Macros used for heap memory allocation and free */ +#define A_MALLOCINIT() +#define A_MALLOC(size, id) a_malloc(size, id) +#define A_FREE(addr, id) a_free(addr, id) + +#define A_PRINTF(args...) QCADRV_PRINTF(args) + +/* + * A_MDELAY - used to delay specified number of milliseconds. + */ +#define A_MDELAY(msecs) vTaskDelay(1 >= MSEC_TO_TICK(msecs) ? 1 : MSEC_TO_TICK(msecs)) + +#if DRIVER_CONFIG_DISABLE_ASSERT +#define A_ASSERT(expr) +#else /* DRIVER_CONFIG_DISABLE_ASSERT */ +extern void *p_Global_Cxt; +extern void qcadrv_assert_func(const char *, int); +//#define A_ASSERT(expr) if(!(expr)) do { qcadrv_assert_func(__FUNCTION__, __LINE__); } while(0) +#define A_ASSERT(expr) assert(expr) +#endif /* DRIVER_CONFIG_DISABLE_ASSERT */ + +/* UNUSED_ARGUMENT - used to solve compiler warnings where arguments to functions are not used + * within the function. + */ + +#endif /* _OSAPI_MQX_H_ */ diff --git a/platform/mcu/lpc54102/wifi_qca/port/boards/lpcxpresso54102/alios/gt202/wifi_shield_gt202.h b/platform/mcu/lpc54102/wifi_qca/port/boards/lpcxpresso54102/alios/gt202/wifi_shield_gt202.h new file mode 100644 index 0000000000..6f478cc6d3 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/port/boards/lpcxpresso54102/alios/gt202/wifi_shield_gt202.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2017, NXP Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of NXP Semiconductor, Inc. nor the names of its + * contributors may be used tom 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 __WIFI_SHIELD_GT202_H__ +#define __WIFI_SHIELD_GT202_H__ + +#include "wifi_common.h" +#include "pin_mux.h" + +/* This file cannot be included directly in common code, it must pass through "wifi_shield.h" */ +#ifndef WIFISHIELD_ENABLED +# define WIFISHIELD_ENABLED +#else +# error "Other WiFi shield is already enabled !" +#endif + +/* Pinmux function, generated by pinmuxtool */ +#define WIFISHIELD_PINMUX_INIT BOARD_InitGT202Shield + +/* WLAN_IRQ PINT */ +#define WIFISHIELD_WLAN_PINT (kPINT_PinInt0) +#define WIFISHIELD_WLAN_PINT_EDGE (kPINT_PinIntEnableFallEdge) +#define WIFISHIELD_WLAN_PINT_CONNECT (kINPUTMUX_GpioPort0Pin6ToPintsel) +#define WIFISHIELD_WLAN_PINT_IRQ (PIN_INT0_IRQn) + +/* WLAN_IRQ signal */ +#define WIFISHIELD_WLAN_IRQ_DIRECTION (BOARD_INITGT202SHIELD_IRQ_DIRECTION) +#define WIFISHIELD_WLAN_IRQ_PORT (BOARD_INITGT202SHIELD_IRQ_PORT) +#define WIFISHIELD_WLAN_IRQ_GPIO (BOARD_INITGT202SHIELD_IRQ_GPIO) +#define WIFISHIELD_WLAN_IRQ_PIN (BOARD_INITGT202SHIELD_IRQ_GPIO_PIN) +#define WIFISHIELD_WLAN_IRQ_CLOCKSRC (kCLOCK_Gpio0) + +/* WLAN_PWRON (PWRDWN) signal */ +#define WIFISHIELD_WLAN_PWRON_DIRECTION (BOARD_INITGT202SHIELD_PWRON_DIRECTION) +#define WIFISHIELD_WLAN_PWRON_PORT (BOARD_INITGT202SHIELD_PWRON_PORT) +#define WIFISHIELD_WLAN_PWRON_GPIO (BOARD_INITGT202SHIELD_PWRON_GPIO) +#define WIFISHIELD_WLAN_PWRON_PIN (BOARD_INITGT202SHIELD_PWRON_GPIO_PIN) +#define WIFISHIELD_WLAN_PWRON_CLOCKSRC (kCLOCK_Gpio0) + +/* SPI settings */ +#define WIFISHIELD_SPI (SPI1) +#define WIFISHIELD_SPI_INIT_CS (kSPI_Ssel0) +#define WIFISHIELD_SPI_CLK_CONNECT (kIRC12M_to_SPI) +#define WIFISHIELD_SPI_IP_RESET (kSPI1_RST_SHIFT_RSTn) +#define WIFISHIELD_SPI_BAUDRATE (1*1000*1000) +#define WIFISHIELD_SPI_THRESHOLD (8) + +/* EDMA settings */ +#define WIFISHIELD_DMA (DMA0) +#define WIFISHIELD_DMA_RX_CHNL (10) +#define WIFISHIELD_DMA_TX_CHNL (11) + +#endif diff --git a/platform/mcu/lpc54102/wifi_qca/port/boards/lpcxpresso54102/alios/wifi_shield.c b/platform/mcu/lpc54102/wifi_qca/port/boards/lpcxpresso54102/alios/wifi_shield.c new file mode 100644 index 0000000000..bfcb605f05 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/port/boards/lpcxpresso54102/alios/wifi_shield.c @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2017, NXP Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of NXP Semiconductor, Inc. nor the names of its + * contributors may be used tom 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 "wifi_common.h" +#include "fsl_gpio.h" +#include "driver_cxt.h" +#include "wifi_spi.h" +#include "wifi_shield.h" +#include "fsl_pint.h" +#include "fsl_inputmux.h" +#include "fsl_inputmux_connections.h" + +static void PINT_callback(pint_pin_int_t pintr, uint32_t pmatch_status); + +/*! + * @brief Low level initialization, RTOS does not have to run yet + */ +A_STATUS WIFISHIELD_Init(void) +{ + gpio_pin_config_t config; + memset(&config, 0, sizeof(config)); + + /* Initialize pinmux */ +#ifdef WIFISHIELD_PINMUX_INIT + WIFISHIELD_PINMUX_INIT(); +#endif + + /* Enable clocks for GPIO */ + CLOCK_EnableClock(WIFISHIELD_WLAN_PWRON_CLOCKSRC); + CLOCK_EnableClock(WIFISHIELD_WLAN_IRQ_CLOCKSRC); + + /* Enable clocks for SPI */ + CLOCK_AttachClk(WIFISHIELD_SPI_CLK_CONNECT); + RESET_PeripheralReset(WIFISHIELD_SPI_IP_RESET); + + /* Set up WLAN_PWRON signal */ + config.pinDirection = (gpio_pin_direction_t)WIFISHIELD_WLAN_PWRON_DIRECTION; + GPIO_PinInit(WIFISHIELD_WLAN_PWRON_GPIO, WIFISHIELD_WLAN_PWRON_PORT, WIFISHIELD_WLAN_PWRON_PIN, &config); + + /* Set up WLAN_IRQ signal */ + config.pinDirection = (gpio_pin_direction_t)WIFISHIELD_WLAN_IRQ_DIRECTION; + GPIO_PinInit(WIFISHIELD_WLAN_IRQ_GPIO, WIFISHIELD_WLAN_IRQ_PORT, WIFISHIELD_WLAN_IRQ_PIN, &config); + + CLOCK_EnableClock(kCLOCK_Gpio1); + config.pinDirection = kPIN_MUX_DirectionOutput; + config.outputLogic = 1; + GPIO_PinInit(GPIO, 1, 15, &config); + + /* Set up Inputmux */ + INPUTMUX_Init(INPUTMUX); + INPUTMUX_AttachSignal(INPUTMUX, WIFISHIELD_WLAN_PINT, WIFISHIELD_WLAN_PINT_CONNECT); + INPUTMUX_Deinit(INPUTMUX); + + /* Set up PINT for WLAN_IRQ */ + PINT_Init(PINT); + PINT_PinInterruptConfig(PINT, WIFISHIELD_WLAN_PINT, WIFISHIELD_WLAN_PINT_EDGE, PINT_callback); + PINT_EnableCallback(PINT); + + /* Enable NVIC interrupt for WLAN_IRQ */ + NVIC_EnableIRQ(WIFISHIELD_WLAN_PINT_IRQ); + + /* Set NVIC priority if is required by Freertos */ + NVIC_SetPriority(WIFISHIELD_WLAN_PINT_IRQ, WIFISHIELD_WLAN_IRQ_PRIORITY); + + return A_OK; +} + +/*! + * @brief Initialization is maintained by WIFI stack + */ +A_STATUS WIFISHIELD_InitDrivers(void *param) +{ + /* Set up capabilities of SPI transfer, used in upper layer */ + A_DRIVER_CONTEXT *pDCxt = GET_DRIVER_COMMON(param); + + /* Force WIFI stack to use this SPI settings */ + pDCxt->spi_hcd.PowerUpDelay = 1; + pDCxt->spi_hcd.SpiHWCapabilitiesFlags = (HW_SPI_FRAME_WIDTH_8 | HW_SPI_NO_DMA | HW_SPI_INT_EDGE_DETECT); + + /* Complex DMAMUX/DMA/SPI config structure */ + WIFIDRVS_SPI_config_t spi_config = {0}; + + /* Load default settings */ + WIFIDRVS_SPI_GetDefaultConfig(&spi_config); + +#if defined(WIFISHIELD_DMA) + /* Configure dma_mode */ + spi_config.dma_mode.enabled = true; + spi_config.dma_mode.dma_base = (void*)WIFISHIELD_DMA; + spi_config.dma_mode.dma_rx_chnl = WIFISHIELD_DMA_RX_CHNL; + spi_config.dma_mode.dma_rx_chnl_prio = kDMA_ChannelPriority3; + spi_config.dma_mode.dma_tx_chnl = WIFISHIELD_DMA_TX_CHNL; + spi_config.dma_mode.dma_tx_chnl_prio = kDMA_ChannelPriority4; + spi_config.dma_mode.dma_irq_prio = WIFISHIELD_DMA_IRQ_PRIORITY; +#endif + +#if defined(WIFISHIELD_SPI_IRQ_PRIORITY) + /* Configure irq_mode */ + spi_config.irq_mode.enabled = true; + spi_config.irq_mode.spi_irq_prio = WIFISHIELD_SPI_IRQ_PRIORITY; +#endif + + /* Configure spi */ + spi_config.spi.base = (void*)WIFISHIELD_SPI; + spi_config.spi.clk_hz = CLOCK_GetFreq(kCLOCK_Spi); + spi_config.spi.baudrate = WIFISHIELD_SPI_BAUDRATE; + spi_config.spi.irq_threshold = WIFISHIELD_SPI_THRESHOLD; + + /* Load recommended SPI settings */ + WIFIDRVS_SPI_GetSPIConfig(&spi_config.spi.config, WIFISHIELD_SPI_BAUDRATE, WIFISHIELD_SPI_INIT_CS); + + /* Initialize driver */ + A_STATUS result = WIFIDRVS_SPI_Init(&spi_config); + assert(A_OK == result); + + return result; +} + +/*! + * @brief Deinitialization is maintained by WIFI stack + */ +A_STATUS WIFISHIELD_DeinitDrivers(void *param) +{ + // WIFI_Spi_Deinit(); + return A_OK; +} + +/*! + * @brief Power up WiFi shield, RTOS does not have to run yet + */ +A_STATUS WIFISHIELD_PowerUp(uint32_t enable) +{ + if (enable) + { + GPIO_WritePinOutput(WIFISHIELD_WLAN_PWRON_GPIO, WIFISHIELD_WLAN_PWRON_PORT, WIFISHIELD_WLAN_PWRON_PIN, 1); + } + else + { + GPIO_WritePinOutput(WIFISHIELD_WLAN_PWRON_GPIO, WIFISHIELD_WLAN_PWRON_PORT, WIFISHIELD_WLAN_PWRON_PIN, 0); + } + return A_OK; +} + +/*! + * @brief Fn post DriverTask semaphore, can be called only from WLAN_IRQ ISR + */ +void WIFISHIELD_NotifyDriverTask(void *param) +{ + extern QCA_CONTEXT_STRUCT wifiCtx; + void HW_InterruptHandler(void *pCxt); + + void *pCxt = wifiCtx.MAC_CONTEXT_PTR; + if (pCxt) + { + HW_InterruptHandler(pCxt); + } +} + +/* ISR callback for WLAN_IRQ */ +static void PINT_callback(pint_pin_int_t pintr, uint32_t pmatch_status) +{ +// PRINTF("PINT CALLBACK \r\n"); + WIFISHIELD_NotifyDriverTask(NULL); +} + diff --git a/platform/mcu/lpc54102/wifi_qca/port/boards/lpcxpresso54102/alios/wifi_shield.h b/platform/mcu/lpc54102/wifi_qca/port/boards/lpcxpresso54102/alios/wifi_shield.h new file mode 100644 index 0000000000..a33914f355 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/port/boards/lpcxpresso54102/alios/wifi_shield.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2017, NXP Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of NXP Semiconductor, Inc. nor the names of its + * contributors may be used tom 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 __WIFI_SHIELD_H__ +#define __WIFI_SHIELD_H__ + +/* Select specific shield support */ +#define WIFISHIELD_IS_GT202 + +/* NOTE: Silex is not supported. WLAN_IRQ is routed to P3_2 + * that does not support interrupts */ + +/* Include shields support */ +#if defined(WIFISHIELD_IS_GT202) +#include "wifi_shield_gt202.h" +#else +#error "No shield is selected !" +#endif + +/* define IRQ priority level */ +#ifndef WIFISHIELD_SPI_IRQ_PRIORITY +# define WIFISHIELD_SPI_IRQ_PRIORITY (3) +#endif +#ifndef WIFISHIELD_DMA_IRQ_PRIORITY +# define WIFISHIELD_DMA_IRQ_PRIORITY (3) +#endif +#ifndef WIFISHIELD_WLAN_IRQ_PRIORITY +# define WIFISHIELD_WLAN_IRQ_PRIORITY (3) +#endif + +/* Fn prototypes, which need to be implemented */ +A_STATUS WIFISHIELD_Init(void); +A_STATUS WIFISHIELD_InitDrivers(void *param); +A_STATUS WIFISHIELD_DeinitDrivers(void *param); +A_STATUS WIFISHIELD_PowerUp(uint32_t enable); +void WIFISHIELD_NotifyDriverTask(void *param); + +#endif diff --git a/platform/mcu/lpc54102/wifi_qca/port/boards/lpcxpresso54102/alios/wlan_qca400x.c b/platform/mcu/lpc54102/wifi_qca/port/boards/lpcxpresso54102/alios/wlan_qca400x.c new file mode 100644 index 0000000000..72ffd1f489 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/port/boards/lpcxpresso54102/alios/wlan_qca400x.c @@ -0,0 +1,146 @@ +/**HEADER******************************************************************** +* +* The Clear BSD License +* Copyright (c) 2008 Freescale Semiconductor; +* All Rights Reserved +* +*************************************************************************** +* Redistribution and use in source and binary forms, with or without modification, +* are permitted (subject to the limitations in the disclaimer below) provided +* that the following conditions are met: +* +* o Redistributions of source code must retain the above copyright notice, this list +* of conditions and the following disclaimer. +* +* o 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. +* +* o Neither the name of the copyright holder nor the names of its +* contributors may be used to endorse or promote products derived from this +* software without specific prior written permission. +* +* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +* 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. +* +************************************************************************** +* +* $FileName: wlan_qca400x.c$ +* $Version : $ +* $Date : $ +* +* Comments: +* +* This file contains the function that reads the timer and returns +* the number of nanoseconds elapsed since the last interrupt. +* +*END************************************************************************/ + +#include "board.h" + +#include +#include +#include "qcom_api.h" + +// ============================================================================ +// Definitions +// ============================================================================ + + +// ============================================================================ +// Globals +// ============================================================================ + +// This is the structure passed on to the QCA WIFI driver. +// It contains primarily SPI hardware configuration and little else +QCA_CONTEXT_STRUCT wifiCtx; + +// This is the WIFI function pointer struct defined in QCA driver file cust_api_init.c +extern const QCA_MAC_IF_STRUCT ATHEROS_WIFI_IF; + +/// SPI hardware configuration that is used by cust_spi_hcd.c - the QCA SPI driver +// struct wlan_hardware_config_s wlanHardwareConfig = { +// .spi_instance = SPI_INSTANCE_NUMBER, +// .spi_cs = kDspiPcs0, +// .wlan_irq_number = WLAN_IRQ_NUMBER, +// .wlan_power_pin = WLAN_CHIP_POWER_PIN, +//}; + +const QCA_IF_STRUCT ENET_0 = { + .MAC_IF = &ATHEROS_WIFI_IF, .MAC_NUMBER = 0, .PHY_NUMBER = 0, .PHY_ADDRESS = 0, +}; + +const QCA_PARAM_STRUCT ENET_default_params = { + .QCA_IF = &ENET_0, + .MODE = Auto_Negotiate, + .OPTIONS = 0, + .NUM_RX_PCBS = WLAN_CONFIG_NUM_PRE_ALLOC_RX_BUFFERS, // # Number of RX PCBs (Packet Control Blocks) + + // cust_spi_hcd.c - the QCA hardware specific SPI driver uses this config + // .MAC_PARAM = &wlanHardwareConfig, +}; + +// ============================================================================ +// WIFI Interrupt handler and Initialization +// ============================================================================ + +static int numIrqs = 0; +static int initTime = 0; + +/** Initialize the QCA400x WLAN driver and start the associated driver task + * This function MUST be called from a task/thread context + */ +int wlan_driver_start(void) +{ + uint32_t result = A_OK; + uint32_t time = 0; + + // Power off the WLAN and wait 30ms + CUSTOM_HW_POWER_UP_DOWN(NULL, false); + + A_MDELAY(MSEC_TO_TICK(30)); + + // Initialize WIFI driver by calling Custom_Api_Initialize() which + // allocates memory for various structures and starts the driver RTOS task + // represented by Atheros_Driver_Task() function. + // The driver task establishes SPI communication with the QCA400x chip and sets + // up various registers of the WLAN chip. + // Note that this initialization involves the currently running task to wait + // for the ready signal from the Atheros_Driver_Task() where upon we return + // from the function call. This process takes approximately 60ms. + time = A_TIME_GET_MSEC(); + wifiCtx.PARAM_PTR = &ENET_default_params; + result = ATHEROS_WIFI_IF.INIT(&wifiCtx); + if (A_OK != result) + { + PRINTF("WLAN driver initialization failed \r\n"); + return result; + } + + // Print init time + initTime = time = A_TIME_GET_MSEC() - time; + PRINTF("WLAN driver initialized in %dms with %d irqs\r\n", time, numIrqs); + + // Amount of malloc'ed memory as counted by the QCA400x driver + extern uint32_t g_totAlloc; + PRINTF("WLAN driver malloc'ed %d bytes (not counting OS structures!)\r\n", g_totAlloc); + + // avoid SPI bus flood + qcom_power_set_mode(0, MAX_PERF_POWER, USER); + + return result; +} + +QCA_CONTEXT_STRUCT *wlan_get_context(void) +{ + return &wifiCtx; +} diff --git a/platform/mcu/lpc54102/wifi_qca/port/drivers/spi_alios/wifi_driver_main.c b/platform/mcu/lpc54102/wifi_qca/port/drivers/spi_alios/wifi_driver_main.c new file mode 100644 index 0000000000..98be61ee23 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/port/drivers/spi_alios/wifi_driver_main.c @@ -0,0 +1,37 @@ +#include "wifi_driver_main.h" +#include "k_api.h" +#include "common_api.h" +#include "wifi_env.h" +#include "aos/kernel.h" + +// The WLAN driver task priority is set to the next highest priority (0 is highest priority) +// because blockForResponse() needs to temporarily boost caller task's priority +// over that of the driver task + +ktask_t atheros_wifi_task; +#define ATHEROS_TASK_STACKSIZE 1024 + +cpu_stack_t atheros_wifi_task_stack[ATHEROS_TASK_STACKSIZE]; + +/* NOTE: the whole file will be included as part of freertos env */ +/* TODO: check stackSize/sizeof(portSTACK_TYPE) */ + +extern void Atheros_Driver_Task(void *param); + +A_STATUS Driver_CreateThread(void *pCxt) +{ + kstat_t status; + status = krhino_task_create(&atheros_wifi_task, "atheros_wifi", pCxt, (AOS_DEFAULT_APP_PRI - 10), 0, + atheros_wifi_task_stack, ATHEROS_TASK_STACKSIZE, Atheros_Driver_Task, 1); + PRINTF("Driver_CreateThread status = %d\r\n", status); + + return RHINO_SUCCESS == status ? A_OK : A_ERROR; +} + +// Compliments CreateDriverThread +A_STATUS Driver_DestroyThread(void *pCxt) +{ + GET_DRIVER_COMMON(pCxt)->driverShutdown = true; + DRIVER_WAKE_DRIVER(pCxt); + return A_OK; +} diff --git a/platform/mcu/lpc54102/wifi_qca/port/drivers/spi_alios/wifi_driver_main.h b/platform/mcu/lpc54102/wifi_qca/port/drivers/spi_alios/wifi_driver_main.h new file mode 100644 index 0000000000..b7cb59ca9e --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/port/drivers/spi_alios/wifi_driver_main.h @@ -0,0 +1,11 @@ +#ifndef WIFI_DRIVER_MAIN_H +#define WIFI_DRIVER_MAIN_H + +#include "athdefs.h" + +A_STATUS Driver_CreateThread(void *pCxt); +A_STATUS Driver_DestroyThread(void *pCxt); + + +#endif + diff --git a/platform/mcu/lpc54102/wifi_qca/port/drivers/spi_alios/wifi_spi.c b/platform/mcu/lpc54102/wifi_qca/port/drivers/spi_alios/wifi_spi.c new file mode 100644 index 0000000000..bd34ec9687 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/port/drivers/spi_alios/wifi_spi.c @@ -0,0 +1,431 @@ +/* + * The Clear BSD License + * Copyright (c) 2016, NXP Semiconductor, Inc. + * All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted (subject to the limitations in the disclaimer below) provided + * that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of NXP Semiconductor, Inc. nor the names of its + * contributors may be used tom endorse or promote products derived from this + * software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 + * 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 "wifi_common.h" +#include "athdefs.h" + +#include "fsl_spi.h" +#include "fsl_spi_dma.h" +//#include "fsl_dmamux.h" +//#include "fsl_edma.h" +//#include "fsl_dspi_edma.h" +#include "wifi_spi.h" +#include "fsl_gpio.h" + +static spi_dma_handle_t g_spi_edma_m_handle; +static dma_handle_t g_m_tx_handle; +static dma_handle_t g_m_rx_handle; +static spi_dma_handle_t g_m_dma_handle; +static spi_master_handle_t g_m_handle; + +static kmutex_t spi_resource_mutex; +static ksem_t spi_transfer_event; +static int32_t g_dma_chunk = 1023; +//static enum IRQn g_dma_irqs[][FSL_FEATURE_EDMA_MODULE_CHANNEL] = DMA_CHN_IRQS; +static enum IRQn g_spi_irqs[] = SPI_IRQS; +static spi_master_config_t g_spi_config; + +static SPI_Type *g_spi_base = NULL; +static uint32_t g_xfer_cs = 0; +static uint32_t g_irq_threshold = 0; + +extern uint32_t SPI_GetInstance(SPI_Type *base); + +/*! @brief Array to map DMA instance number to IRQ number. */ +static const IRQn_Type s_dmaIRQNumber[] = DMA_IRQS; + +/*! @brief Array to map DMA instance number to base pointer. */ +static DMA_Type *const s_dmaBases[] = DMA_BASE_PTRS; + +static int32_t DMA_GetInstance(DMA_Type *base) +{ + int32_t instance; + /* Find the instance index from base address mappings. */ + for (instance = 0; instance < ARRAY_SIZE(s_dmaBases); instance++) + { + if (s_dmaBases[instance] == base) + { + break; + } + } + assert(instance < ARRAY_SIZE(s_dmaBases)); + return instance < ARRAY_SIZE(s_dmaBases) ? instance : -1; +} + +/* + * DMA handler, release transfer semaphore + */ +static void SPI_DMA_MasterUserCallback(SPI_Type *base, spi_dma_handle_t *handle, status_t status, void *userData) +{ + /* disable DMA requests before invoke callback */ + GPIO_WritePinOutput(GPIO, 1, 15, 1); + krhino_sem_give(&spi_transfer_event); +} + +/* + * IRQ handler, release transfer semaphore + */ +static void SPI_MasterUserCallback(SPI_Type *base, spi_master_handle_t *handle, status_t status, void *userData) +{ + /* disable IRQ requests before invoke callback */ + GPIO_WritePinOutput(GPIO, 1, 15, 1); + krhino_sem_give(&spi_transfer_event); +} + +/* + * Initialize SPI IRQ mode + */ +static A_STATUS WIFIDRVS_SPI_InitIRQMode(WIFIDRVS_SPI_config_t *config) +{ + uint32_t spi_id = SPI_GetInstance(config->spi.base); + NVIC_SetPriority(g_spi_irqs[spi_id], config->irq_mode.spi_irq_prio); + + /* SPI IRQ non-blocking handle */ + SPI_MasterTransferCreateHandle(config->spi.base, &g_m_handle, SPI_MasterUserCallback, NULL); + + return A_OK; +} + +/* + * Initialize SPI DMA mode + */ +static A_STATUS WIFIDRVS_SPI_InitDMAMode(WIFIDRVS_SPI_config_t *config) +{ + int32_t dmaInstance; + DMA_Init(config->dma_mode.dma_base); + DMA_EnableChannel(config->dma_mode.dma_base, config->dma_mode.dma_rx_chnl); + DMA_EnableChannel(config->dma_mode.dma_base, config->dma_mode.dma_tx_chnl); + DMA_SetChannelPriority(config->dma_mode.dma_base, config->dma_mode.dma_rx_chnl, config->dma_mode.dma_rx_chnl_prio); + DMA_SetChannelPriority(config->dma_mode.dma_base, config->dma_mode.dma_tx_chnl, config->dma_mode.dma_tx_chnl_prio); + DMA_CreateHandle(&g_m_rx_handle, config->dma_mode.dma_base, config->dma_mode.dma_rx_chnl); + DMA_CreateHandle(&g_m_tx_handle, config->dma_mode.dma_base, config->dma_mode.dma_tx_chnl); + SPI_MasterTransferCreateHandleDMA(config->spi.base, &g_m_dma_handle, SPI_DMA_MasterUserCallback, NULL, &g_m_tx_handle, + &g_m_rx_handle); + dmaInstance = DMA_GetInstance(config->dma_mode.dma_base); + NVIC_SetPriority(s_dmaIRQNumber[dmaInstance], config->dma_mode.dma_irq_prio); + return A_OK; +} + +/* + * Initialize SPI peripheral + */ +static A_STATUS WIFIDRVS_SPI_InitPeriph( + SPI_Type *base, + uint32_t src_clk_hz, + uint32_t xfer_cs, + spi_master_config_t *user_config +) +{ + assert(NULL != base); + assert(NULL != user_config); + + krhino_mutex_create(&spi_resource_mutex, "spi_resource_mutex"); + + krhino_sem_create(&spi_transfer_event, "spi_transfer_event", 0); + + /* DSPI init */ + SPI_MasterInit(base, &g_spi_config, src_clk_hz); + + return A_OK; +} + +/* + * Transfer data in DMA mode + */ +static A_STATUS WIFIDRVS_SPI_DMA_Transfer(spi_transfer_t *transfer) +{ + assert(NULL != transfer); + GPIO_WritePinOutput(GPIO, 1, 15, 0); + status_t result = SPI_MasterTransferDMA(g_spi_base, &g_m_dma_handle, transfer); + if (kStatus_Success != result) + { + assert(0); + return A_ERROR; + } + /* semaphore is released in callback fn */ + if (RHINO_SUCCESS != krhino_sem_take(&spi_transfer_event, RHINO_WAIT_FOREVER)) + { + assert(0); + return A_ERROR; + } + +// SPI_EnableTxDMA(g_spi_base, false); +// SPI_EnableRxDMA(g_spi_base, false); + + return A_OK; +} + +/* + * Transfer data in IRQ mode + */ +static A_STATUS WIFIDRVS_SPI_IRQ_Transfer(spi_transfer_t *transfer) +{ + assert(NULL != transfer); + + GPIO_WritePinOutput(GPIO, 1, 15, 0); + status_t result = SPI_MasterTransferNonBlocking(g_spi_base, &g_m_handle, transfer); + if (kStatus_Success != result) + { + assert(0); + return A_ERROR; + } + if (RHINO_SUCCESS != krhino_sem_take(&spi_transfer_event,RHINO_WAIT_FOREVER)) + { + assert(0); + result = A_ERROR; + } + return A_OK; +} + +/* + * Transfer data + */ +static A_STATUS WIFIDRVS_SPI_Transfer(spi_transfer_t *transfer) +{ + A_STATUS result = A_OK; + int32_t to_transfer; + + /* NOTE: following code expects that SDK drivers do not + * modify members of 'transfer' argument */ + for (to_transfer = transfer->dataSize; to_transfer > 0;) + { + if (to_transfer < g_irq_threshold) +// if (1) + { + /* DMA is unefficient for small amount of data, so use IRQ mode. + * IRQ mode can transfer unlimited number of data */ + transfer->dataSize = to_transfer; + transfer->configFlags |= kSPI_FrameAssert; + transfer->configFlags |= SPI_TXDATCTL_EOT_MASK; + result = WIFIDRVS_SPI_IRQ_Transfer(transfer); + if (A_OK != result) + break; + to_transfer = 0; + } + else + { + /* DMA has bug !!!!!!!!!!!!!!!!!!! */ + /* DSPI over EDMA can transfer only limited number of bytes + * so we have to split transfer into chunks */ + //transfer->dataSize = to_transfer < g_dma_chunk ? to_transfer : g_dma_chunk; + // TODO: need to verify behaviour when transfer is splitted in default continuous mode + // TODO: allows CS for every word ? + if (to_transfer < g_dma_chunk) + { + transfer->dataSize = to_transfer; + transfer->configFlags |= kSPI_FrameAssert; + } + else + { + transfer->dataSize = g_dma_chunk; + } + result = WIFIDRVS_SPI_DMA_Transfer(transfer); + if (A_OK != result) + break; + to_transfer -= transfer->dataSize; + /* recalculate rx/rx offsets */ + if (NULL != transfer->txData) + { + transfer->txData += transfer->dataSize; + } + if (NULL != transfer->rxData) + { + transfer->rxData += transfer->dataSize; + } + } + } + + return result; +} + +/*! + * @brief Initialize SPI driver + */ +A_STATUS WIFIDRVS_SPI_Init(WIFIDRVS_SPI_config_t *config) +{ + /* No SPI base address, invalid config*/ + assert(!((NULL == config) || (NULL == config->spi.base))); + if ((NULL == config) || (NULL == config->spi.base)) return A_ERROR; + + /* IRQ mode only - set threshold to max value */ + if ((config->irq_mode.enabled) && (!config->dma_mode.enabled)) + { + g_irq_threshold = (uint32_t)-1; + } + /* DMA mode only - set threshold to 0 */ + else if ((!config->irq_mode.enabled) && (config->dma_mode.enabled)) + { + g_irq_threshold = 0; + } + /* DMA and IRQ mode - set user defined value */ + else if ((config->irq_mode.enabled) && (config->dma_mode.enabled)) + { + g_irq_threshold = config->spi.irq_threshold; + } + /* Neither of modes is enabled, return error */ + else + { + return A_ERROR; + } + + /* Prepare driver internal context */ + g_spi_base = config->spi.base; + g_xfer_cs = config->spi.xfer_cs; + g_spi_config = config->spi.config; + + /* Initialize SPI peripheral */ + WIFIDRVS_SPI_InitPeriph(config->spi.base, config->spi.clk_hz, config->spi.xfer_cs, &config->spi.config); + + /* Enable IRQ mode */ + if (config->irq_mode.enabled) + { + WIFIDRVS_SPI_InitIRQMode(config); + } + + /* Enable DMA mode */ + if (config->dma_mode.enabled) + { + WIFIDRVS_SPI_InitDMAMode(config); + } + + return A_OK; +} + +/*! + * @brief Deinitialize SPI driver + */ +A_STATUS WIFIDRVS_SPI_Deinit(WIFIDRVS_SPI_config_t *config) +{ + assert(!(NULL == config)); + if (NULL == config) return A_ERROR; + + if (NULL == config->spi.base) return A_ERROR; + SPI_Deinit(config->spi.base); + + return A_OK; +} + +/*! + * @brief Return default configuration + */ +A_STATUS WIFIDRVS_SPI_GetDefaultConfig(WIFIDRVS_SPI_config_t *config) +{ + assert(!(NULL == config)); + if (NULL == config) return A_ERROR; + + memset(config, 0, sizeof(*config)); + config->dma_mode.dma_rx_chnl = -1; + config->dma_mode.dma_tx_chnl = -1; + + return A_OK; +} + +/*! + * @brief Return default SPI peripheral settings + */ +A_STATUS WIFIDRVS_SPI_GetSPIConfig(spi_master_config_t *user_config, uint32_t baudrate, spi_ssel_t cs) +{ + assert(!(NULL == user_config)); + if (NULL == user_config) return A_ERROR; + + memset(user_config, 0, sizeof(*user_config)); + SPI_MasterGetDefaultConfig(user_config); + + user_config->polarity = kSPI_ClockPolarityActiveLow; + user_config->phase = kSPI_ClockPhaseSecondEdge; + user_config->direction = kSPI_MsbFirst; + user_config->baudRate_Bps = baudrate; + user_config->dataWidth = kSPI_Data8Bits; + user_config->sselNum = cs; + user_config->sselPol = kSPI_SpolActiveAllLow; + + return A_OK; +} + +/*! + * @brief WiFi SPI transfer SPI + */ +A_STATUS WIFIDRVS_SPI_InOutToken(uint32_t OutToken, uint8_t DataSize, uint32_t *pInToken) +{ + A_STATUS result; + spi_transfer_t transfer = {0}; + + transfer.txData = (uint8_t *)&OutToken; + transfer.rxData = (uint8_t *)pInToken; + transfer.dataSize = DataSize; + transfer.configFlags = g_xfer_cs; + + /* Protect transmit by spi_resource_mutex */ + + if (RHINO_SUCCESS != krhino_mutex_lock(&spi_resource_mutex, RHINO_WAIT_FOREVER)) + { + return A_ERROR; + } + result = WIFIDRVS_SPI_Transfer(&transfer); + + krhino_mutex_unlock(&spi_resource_mutex); + return result; +} + +/*! + * @brief WiFi SPI transfer SPI + */ +A_STATUS WIFIDRVS_SPI_InOutBuffer(uint8_t *pBuffer, uint16_t length, uint8_t doRead, boolean sync) +{ + A_STATUS result; + spi_transfer_t transfer = {0}; + + if (doRead) + { + transfer.txData = NULL; + transfer.rxData = pBuffer; + } + else + { + transfer.txData = pBuffer; + transfer.rxData = NULL; + } + transfer.dataSize = length; + transfer.configFlags = g_xfer_cs; + + /* Protect transmit by spi_resource_mutex */ + if (RHINO_SUCCESS != krhino_mutex_lock(&spi_resource_mutex, RHINO_WAIT_FOREVER)) + { + return A_ERROR; + } + result = WIFIDRVS_SPI_Transfer(&transfer); + krhino_mutex_unlock(&spi_resource_mutex); + return result; +} + diff --git a/platform/mcu/lpc54102/wifi_qca/port/drivers/spi_alios/wifi_spi.h b/platform/mcu/lpc54102/wifi_qca/port/drivers/spi_alios/wifi_spi.h new file mode 100644 index 0000000000..2c206c87f0 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/port/drivers/spi_alios/wifi_spi.h @@ -0,0 +1,75 @@ +/* + * The Clear BSD License + * Copyright (c) 2016, NXP Semiconductor, Inc. + * All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted (subject to the limitations in the disclaimer below) provided + * that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of NXP Semiconductor, Inc. nor the names of its + * contributors may be used tom endorse or promote products derived from this + * software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 + * 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 __WIFI_SPI_H__ +#define __WIFI_SPI_H__ + +#include +#include "fsl_spi.h" +#include "fsl_dma.h" + +/* can be extended in future */ +typedef struct { + struct { + uint32_t enabled; + DMA_Type *dma_base; + int32_t dma_rx_chnl; + dma_priority_t dma_rx_chnl_prio; + int32_t dma_tx_chnl; + dma_priority_t dma_tx_chnl_prio; + uint32_t dma_irq_prio; + } dma_mode; + struct { + uint32_t enabled; + uint32_t spi_irq_prio; + } irq_mode; + struct { + SPI_Type *base; + uint32_t clk_hz; + uint32_t xfer_cs; + uint32_t baudrate; + uint32_t irq_threshold; + spi_master_config_t config; + } spi; +} WIFIDRVS_SPI_config_t; + +/* prototypes */ +A_STATUS WIFIDRVS_SPI_Init(WIFIDRVS_SPI_config_t *config); +A_STATUS WIFIDRVS_SPI_Deinit(WIFIDRVS_SPI_config_t *config); +A_STATUS WIFIDRVS_SPI_InOutToken(uint32_t OutToken, uint8_t DataSize, uint32_t *pInToken); +A_STATUS WIFIDRVS_SPI_InOutBuffer(uint8_t *pBuffer, uint16_t length, uint8_t doRead, boolean sync); +A_STATUS WIFIDRVS_SPI_GetDefaultConfig(WIFIDRVS_SPI_config_t *config); +A_STATUS WIFIDRVS_SPI_GetSPIConfig(spi_master_config_t *user_config, uint32_t baudrate, spi_ssel_t cs); + +#endif diff --git a/platform/mcu/lpc54102/wifi_qca/port/env/alios/wifi_env.c b/platform/mcu/lpc54102/wifi_qca/port/env/alios/wifi_env.c new file mode 100644 index 0000000000..72277b2d97 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/port/env/alios/wifi_env.c @@ -0,0 +1,208 @@ +/* + * The Clear BSD License + * Copyright (c) 2016, NXP Semiconductor, Inc. + * All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted (subject to the limitations in the disclaimer below) provided + * that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of NXP Semiconductor, Inc. nor the names of its + * contributors may be used tom endorse or promote products derived from this + * software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 + * 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 "wifi_common.h" + +/*TODO: check return value */ +void a_free(void *addr, uint8_t id) +{ + // UNUSED_ARGUMENT(id); + krhino_mm_free(addr); +} + +/* FIXME !! */ +extern uint32_t g_totAlloc; +void *a_malloc(int32_t size, uint8_t id) +{ + void *addr; + + addr = (void *)krhino_mm_alloc(size); + assert(addr); + if (addr != NULL) + { + /*FIXME: !!!*/ +// PRINTF("SIZE = %d\r\n", size); + g_totAlloc += size; + } + // UNUSED_ARGUMENT(id); + + return addr; +} + +A_STATUS a_mutex_init(A_MUTEX_T *pMutex) +{ + assert(pMutex); + krhino_mutex_create(pMutex, "mutex"); + if (NULL == pMutex) + { + return A_ERROR; + } + else + { + return A_OK; + } +} + +A_STATUS a_mutex_acquire(A_MUTEX_T *pMutex) +{ + assert(pMutex); + + if (krhino_mutex_lock(pMutex, RHINO_WAIT_FOREVER) == RHINO_SUCCESS) + { + return A_OK; + } + else + { + return A_ERROR; + } +} + +A_STATUS a_mutex_release(A_MUTEX_T *pMutex) +{ + assert(pMutex); + + if (krhino_mutex_unlock(pMutex) == RHINO_SUCCESS) + { + return A_OK; + } + else + { + assert(0); // TODO: use assert cause no-one check return value + return A_ERROR; + } +} + +boolean a_is_mutex_valid(A_MUTEX_T *pMutex) +{ + // FIXME: check owner of mutex + krhino_mutex_is_valid(pMutex); + return true; +} + +A_STATUS a_mutex_delete(A_MUTEX_T *pMutex) +{ + assert(pMutex); + + krhino_mutex_del(pMutex); + return A_OK; +} + +A_STATUS a_event_delete(A_EVENT *pEvent) +{ + assert(pEvent); + krhino_event_del(&pEvent->event); + return A_OK; +} + +// zrusit autoclear flag !!! +A_STATUS a_event_init(A_EVENT *pEvent, osa_event_clear_mode_t clearMode) +{ + assert(pEvent); + + krhino_event_create(&pEvent->event, "event", 0); + + pEvent->clearMode = clearMode; + return A_OK; +} + +A_STATUS a_event_clear(A_EVENT *pEvent, A_EVENT_FLAGS flagsToClear) +{ + assert(pEvent); +#if 0 + A_EVENT_FLAGS actl_flags = flagsToClear; + if (pEvent->clearMode == kEventAutoClear) { + krhino_event_get(&pEvent->event, flagsToClear, RHINO_OR_CLEAR, &actl_flags, RHINO_NO_WAIT); + } else { + krhino_event_get(&pEvent->event, flagsToClear, RHINO_OR, &actl_flags, RHINO_NO_WAIT); + } +#else + A_EVENT_FLAGS flag = ~flagsToClear; + krhino_event_set(&pEvent->event, flag, RHINO_AND); +#endif + return A_OK; +} + +A_STATUS a_event_set(A_EVENT *pEvent, A_EVENT_FLAGS flagsToSet) +{ + assert(pEvent); + + krhino_event_set(&pEvent->event, flagsToSet, RHINO_OR); + + return A_OK; +} + +A_STATUS a_event_wait( + A_EVENT *pEvent, A_EVENT_FLAGS flagsToWait, boolean waitAll, uint32_t timeout, A_EVENT_FLAGS *setFlags) +{ + assert(pEvent); + + if (pEvent->clearMode == kEventAutoClear) { + if (waitAll) { + krhino_event_get(&pEvent->event, flagsToWait, RHINO_AND_CLEAR, setFlags, timeout); + } else { + krhino_event_get(&pEvent->event, flagsToWait, RHINO_OR_CLEAR, setFlags, timeout); + } + } else { + if (waitAll) { + krhino_event_get(&pEvent->event, flagsToWait, RHINO_AND, setFlags, timeout); + } else { + krhino_event_get(&pEvent->event, flagsToWait, RHINO_OR, setFlags, timeout); + } + } + + return A_OK; +} + +uint32_t a_time_get_msec(void) +{ + sys_time_t ticks; + + if (__get_IPSR()) + { + ticks = krhino_sys_tick_get(); + } + else + { + ticks = krhino_sys_tick_get(); + } + + return TICKS_TO_MSEC(ticks); +} + + + +void a_task_delay(uint32_t ticks) +{ + krhino_task_sleep(ticks); +} diff --git a/platform/mcu/lpc54102/wifi_qca/port/env/alios/wifi_env.h b/platform/mcu/lpc54102/wifi_qca/port/env/alios/wifi_env.h new file mode 100644 index 0000000000..4a714ada3e --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/port/env/alios/wifi_env.h @@ -0,0 +1,152 @@ +/* + * The Clear BSD License + * Copyright (c) 2016, NXP Semiconductor, Inc. + * All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted (subject to the limitations in the disclaimer below) provided + * that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of NXP Semiconductor, Inc. nor the names of its + * contributors may be used tom endorse or promote products derived from this + * software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 + * 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 __WIFI_ENV_H__ +#define __WIFI_ENV_H__ + +#include + +/* contains only prototypes and struct. no defines !!! */ +#include "wifi_common.h" + +// TODO: remove +#include "a_config.h" + +/*! @brief The event flags are cleared automatically or manually.*/ +typedef enum _osa_event_clear_mode_t +{ + kEventAutoClear = 0U, /*!< The flags of the event will be cleared automatically. */ + kEventManualClear = 1U /*!< The flags of the event will be cleared manually. */ +} osa_event_clear_mode_t; + +/*! @brief Locks the task scheduler or disables interrupt in critical section. */ +typedef enum _osa_critical_section_mode_t +{ + kCriticalLockSched = 0U, /*!< Lock scheduler in critical section. */ + kCriticalDisableInt = 1U /*!< Disable interrupt in critical selection. */ +} osa_critical_section_mode_t; + +/*! @brief Type for an event group object in FreeRTOS OS */ +// typedef EventGroupHandle_t event_freertos; + +/*! @brief Type for an event group object */ + +typedef struct alios_event_t +{ + kevent_t event; /*!< FreeRTOS OS event handler */ + osa_event_clear_mode_t clearMode; /*!< Auto clear or manual clear */ +} event_t; + +typedef struct +{ + uint32_t dummy; +} cust_hw_context_t; + +typedef struct +{ + cust_hw_context_t *hw_context; + + /* PORT_NOTE: utility_mutex is a mutex used to protect resources that + * might be accessed by multiple task/threads in a system. + * It is used by the ACQUIRE/RELEASE macros below. If the target + * system is single threaded then this mutex can be omitted and + * the macros should be blank.*/ + A_MUTEX_T utility_mutex; + /* PORT_NOTE: connectStateCB allows an app to get feedback/notification + * as the WIFI connection state changes. If used it should be populated + * with a function pointer by an IOCTL or system equivalent. */ + void *connectStateCB; + /* PORT_NOTE: pScanOut stores scan results in a buffer so that they + * can be retrieved aysnchronously by a User task. */ + // uint8_t* pScanOut; /* callers buffer to hold results. */ + // uint16_t scanOutSize;/* size of pScanOut buffer */ + // uint16_t scanOutCount;/* current fill count of pScanOut buffer */ + + /* PORT_NOTE: These 2 events are used to block & wake their respective + * tasks. */ + A_EVENT driverWakeEvent; /* wakes the driver thread */ + A_EVENT userWakeEvent; /* wakes blocked user threads */ + //#if T_SELECT_VER1 + A_EVENT sockSelectWakeEvent; /* wakes t_select */ + //#endif //T_SELECT_VER1 + //#endif + /* PORT_NOTE: These 2 elements provide pointers to system context. + * The pDriverParam is intended provide definition for info such as + * which GPIO's to use for the SPI bus. The pUpperCxt should be + * populated with a system specific object that is required when the + * driver calls any system API's. In case of multi interface, the + * different enet pointers are stored in the corresponding array index + */ + void *pDriverParam; /* param struct containing initialization params */ + void *pUpperCxt[WLAN_NUM_OF_DEVICES]; /* back pointer to the MQX enet object. */ + /* PORT_NOTE: pCommonCxt stores the drivers common context. It is + * accessed by the common source via GET_DRIVER_COMMON() below. */ + void *pCommonCxt; /* the common driver context link */ + boolean driverShutdown; /* used to shutdown the driver */ + void *promiscuous_cb; /* used to feed rx frames in promiscuous mode. */ + //#if ENABLE_P2P_MODE + void *p2pevtCB; + boolean p2pEvtState; + boolean p2pevtflag; + //#if MANUFACTURING_SUPPORT + uint32_t testCmdRespBufLen; + //#endif + // A_CUSTOM_HCD_CXT *customhcdcxt; + void *httpPostCb; /*callback handler for http post events*/ + void *httpPostCbCxt; + void *otaCB; /* callback handler for OTA event */ + void *probeReqCB; + +} cust_context_t; + +/*TODO: check return value */ +void a_free(void *addr, uint8_t id); +void *a_malloc(int32_t size, uint8_t id); +A_STATUS a_mutex_init(A_MUTEX_T *pMutex); +A_STATUS a_mutex_acquire(A_MUTEX_T *pMutex); +A_STATUS a_mutex_release(A_MUTEX_T *pMutex); +boolean a_is_mutex_valid(A_MUTEX_T *pMutex); +A_STATUS a_mutex_delete(A_MUTEX_T *pMutex); +A_STATUS a_event_delete(A_EVENT *pEvent); +A_STATUS a_event_init(A_EVENT *pEvent, osa_event_clear_mode_t clearMode); +A_STATUS a_event_clear(A_EVENT *pEvent, A_EVENT_FLAGS flagsToClear); +A_STATUS a_event_set(A_EVENT *pEvent, A_EVENT_FLAGS flagsToSet); +A_STATUS a_event_wait( + A_EVENT *pEvent, A_EVENT_FLAGS flagsToWait, boolean waitAll, uint32_t timeout, A_EVENT_FLAGS *setFlags); +uint32_t a_time_get_msec(void); +#define OSA_Critical(x) CPSR_ALLOC() +#define OSA_EnterCritical(x) { /*PRINTF("DISABLE IRQ\r\n");*/ RHINO_CRITICAL_ENTER(); } +#define OSA_ExitCritical(x) { RHINO_CRITICAL_EXIT(); /*PRINTF("ENABLE IRQ\r\n");*/ } + +#endif diff --git a/platform/mcu/lpc54102/wifi_qca/port/env/alios/wifi_env_port.h b/platform/mcu/lpc54102/wifi_qca/port/env/alios/wifi_env_port.h new file mode 100644 index 0000000000..31479655c4 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/port/env/alios/wifi_env_port.h @@ -0,0 +1,284 @@ +/* + * The Clear BSD License + * Copyright (c) 2016, NXP Semiconductor, Inc. + * All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted (subject to the limitations in the disclaimer below) provided + * that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of NXP Semiconductor, Inc. nor the names of its + * contributors may be used tom endorse or promote products derived from this + * software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 + * 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 __WIFI_ENV_PORT_H__ +#define __WIFI_ENV_PORT_H__ + +/* + * This file contains definition of environment specific macros. + * This file cannot be included directly, use #include "wifi_common.h" + */ +#include "k_api.h" + +#ifndef __WIFI_PORT_H__ +#error "'wifi_env_port.h' cannot be included directly" +#endif + +/* TODO: find better place */ +#define WLAN_NUM_OF_DEVICES 1 + +#ifndef MSEC_TO_TICK +#define MSEC_TO_TICK(msec) \ + ((uint32_t)(msec) * (uint32_t)RHINO_CONFIG_TICKS_PER_SECOND / 1000uL) +#endif + +#ifndef TICKS_TO_MSEC +#define TICKS_TO_MSEC(tick) ((tick)*1000uL / (uint32_t)RHINO_CONFIG_TICKS_PER_SECOND) +#endif + +#ifndef RXBUFFER_ACCESS_INIT +#define RXBUFFER_ACCESS_INIT(pCxt) A_MUTEX_INIT(&(GET_DRIVER_CXT(pCxt)->utility_mutex)) +#endif + +#ifndef RXBUFFER_ACCESS_ACQUIRE +#define RXBUFFER_ACCESS_ACQUIRE(pCxt) A_MUTEX_ACQUIRE(&(GET_DRIVER_CXT(pCxt)->utility_mutex)) +#endif + +#ifndef RXBUFFER_ACCESS_RELEASE +#define RXBUFFER_ACCESS_RELEASE(pCxt) A_MUTEX_RELEASE(&(GET_DRIVER_CXT(pCxt)->utility_mutex)) +#endif + +#ifndef RXBUFFER_ACCESS_DESTROY +#define RXBUFFER_ACCESS_DESTROY(pCxt) A_MUTEX_DELETE(&(GET_DRIVER_CXT(pCxt)->utility_mutex)) +#endif + +#ifndef TXQUEUE_ACCESS_INIT +/* because its the same mutex as RXBUFFER_ACCESS this is NOP */ +#define TXQUEUE_ACCESS_INIT(pCxt) (A_OK) +#endif + +#ifndef TXQUEUE_ACCESS_ACQUIRE +#define TXQUEUE_ACCESS_ACQUIRE(pCxt) A_MUTEX_ACQUIRE(&(GET_DRIVER_CXT(pCxt)->utility_mutex)) +#endif + +#ifndef TXQUEUE_ACCESS_RELEASE +#define TXQUEUE_ACCESS_RELEASE(pCxt) A_MUTEX_RELEASE(&(GET_DRIVER_CXT(pCxt)->utility_mutex)) +#endif + +#ifndef TXQUEUE_ACCESS_DESTROY +/* because its the same mutex as RXBUFFER_ACCESS this is NOP */ +#define TXQUEUE_ACCESS_DESTROY(pCxt) +#endif + +#ifndef IRQEN_ACCESS_INIT +/* because its the same mutex as RXBUFFER_ACCESS this is NOP */ +#define IRQEN_ACCESS_INIT(pCxt) (A_OK) +#endif + +#ifndef IRQEN_ACCESS_ACQUIRE +#define IRQEN_ACCESS_ACQUIRE(pCxt) A_MUTEX_ACQUIRE(&(GET_DRIVER_CXT(pCxt)->utility_mutex)) +#endif + +#ifndef IRQEN_ACCESS_RELEASE +#define IRQEN_ACCESS_RELEASE(pCxt) A_MUTEX_RELEASE(&(GET_DRIVER_CXT(pCxt)->utility_mutex)) +#endif + +#ifndef IRQEN_ACCESS_DESTROY +/* because its the same mutex as RXBUFFER_ACCESS this is NOP */ +#define IRQEN_ACCESS_DESTROY(pCxt) +#endif + +#ifndef DRIVER_SHARED_RESOURCE_ACCESS_INIT +/* because its the same mutex as RXBUFFER_ACCESS this is NOP */ +#define DRIVER_SHARED_RESOURCE_ACCESS_INIT(pCxt) (A_OK) +#endif + +#ifndef DRIVER_SHARED_RESOURCE_ACCESS_ACQUIRE +#define DRIVER_SHARED_RESOURCE_ACCESS_ACQUIRE(pCxt) A_MUTEX_ACQUIRE(&(GET_DRIVER_CXT(pCxt)->utility_mutex)) +#endif + +#ifndef DRIVER_SHARED_RESOURCE_ACCESS_RELEASE +#define DRIVER_SHARED_RESOURCE_ACCESS_RELEASE(pCxt) A_MUTEX_RELEASE(&(GET_DRIVER_CXT(pCxt)->utility_mutex)) +#endif + +#ifndef DRIVER_SHARED_RESOURCE_ACCESS_DESTROY +/* because its the same mutex as RXBUFFER_ACCESS this is NOP */ +#define DRIVER_SHARED_RESOURCE_ACCESS_DESTROY(pCxt) +#endif + +#ifndef A_MUTEX_T +#define A_MUTEX_T kmutex_t +#endif + +#ifndef A_MUTEX_INIT +#define A_MUTEX_INIT(mutex) a_mutex_init((mutex)) +#endif + +#ifndef A_MUTEX_ACQUIRE +#define A_MUTEX_ACQUIRE(mutex) a_mutex_acquire((mutex)) +#endif + +#ifndef A_MUTEX_RELEASE +#define A_MUTEX_RELEASE(mutex) a_mutex_release((mutex)) +#endif + +#ifndef A_IS_MUTEX_VALID +#define A_IS_MUTEX_VALID(mutex) a_is_mutex_valid((mutex)) +#endif + +#ifndef A_MUTEX_DELETE +#define A_MUTEX_DELETE(mutex) a_mutex_delete((mutex)) +#endif + +#ifndef A_EVENT +#define A_EVENT event_t //a wrapper for kevent_t +#endif + +#ifndef A_EVENT_FLAGS +#define A_EVENT_FLAGS uint32_t +#endif + +/* OSA replacement */ +#ifndef A_EVENT_DELETE +#define A_EVENT_DELETE(event) a_event_delete((event)) +#endif + +#ifndef A_EVENT_INIT +#define A_EVENT_INIT(event, autoclear) a_event_init((event), (autoclear)) +#endif + +#ifndef A_EVENT_CLEAR +#define A_EVENT_CLEAR(event, flags) a_event_clear((event), (flags)) +#endif + +#ifndef A_EVENT_SET +#define A_EVENT_SET(event, flags) a_event_set((event), (flags)) +#endif + +#ifndef A_EVENT_WAIT +#define A_EVENT_WAIT(event, flagsToWait, waitAll, timeout, setFlags) \ + a_event_wait((event), (flagsToWait), (waitAll), (timeout), (setFlags)) +#endif + +#ifndef A_TIME_GET_MSEC +#define A_TIME_GET_MSEC a_time_get_msec +#endif + +#ifndef A_ENTER_CRITICAL +#define A_ENTER_CRITICAL(mode) a_enter_critical((mode)) +#endif + +#ifndef A_EXIT_CRITICAL +#define A_EXIT_CRITICAL(mode) a_exit_critical((mode)) +#endif + +#ifndef A_CUSTOM_DRIVER_CONTEXT +#define A_CUSTOM_DRIVER_CONTEXT cust_context_t +#endif + +#ifndef GET_DRIVER_CXT +#define GET_DRIVER_CXT(pCxt) ((cust_context_t *)(pCxt)) +#endif + +#ifndef GET_DRIVER_COMMON +#define GET_DRIVER_COMMON(pCxt) ((A_DRIVER_CONTEXT *)(((cust_context_t *)(pCxt))->pCommonCxt)) +#endif + +#ifndef RXBUFFER_ACCESS_INIT +#define RXBUFFER_ACCESS_INIT(pCxt) A_MUTEX_INIT(&(GET_DRIVER_CXT(pCxt)->utility_mutex)) +#endif + +#ifndef RXBUFFER_ACCESS_ACQUIRE +#define RXBUFFER_ACCESS_ACQUIRE(pCxt) A_MUTEX_ACQUIRE(&(GET_DRIVER_CXT(pCxt)->utility_mutex)) +#endif + +#ifndef RXBUFFER_ACCESS_RELEASE +#define RXBUFFER_ACCESS_RELEASE(pCxt) A_MUTEX_RELEASE(&(GET_DRIVER_CXT(pCxt)->utility_mutex)) +#endif + +#ifndef RXBUFFER_ACCESS_DESTROY +#define RXBUFFER_ACCESS_DESTROY(pCxt) +A_MUTEX_DELETE(&(GET_DRIVER_CXT(pCxt)->utility_mutex)) +#endif + +#ifndef TXQUEUE_ACCESS_INIT +/* because its the same mutex as RXBUFFER_ACCESS this is NOP */ +#define TXQUEUE_ACCESS_INIT(pCxt) (A_OK) +#endif + +#ifndef TXQUEUE_ACCESS_ACQUIRE +#define TXQUEUE_ACCESS_ACQUIRE(pCxt) A_MUTEX_ACQUIRE(&(GET_DRIVER_CXT(pCxt)->utility_mutex)) +#endif + +#ifndef TXQUEUE_ACCESS_RELEASE +#define TXQUEUE_ACCESS_RELEASE(pCxt) A_MUTEX_RELEASE(&(GET_DRIVER_CXT(pCxt)->utility_mutex)) +#endif + +#ifndef TXQUEUE_ACCESS_DESTROY +/* because its the same mutex as RXBUFFER_ACCESS this is NOP */ +#define TXQUEUE_ACCESS_DESTROY(pCxt) +#endif + +#ifndef IRQEN_ACCESS_INIT +/* because its the same mutex as RXBUFFER_ACCESS this is NOP */ +#define IRQEN_ACCESS_INIT(pCxt) (A_OK) +#endif + +#ifndef IRQEN_ACCESS_ACQUIRE +#define IRQEN_ACCESS_ACQUIRE(pCxt) A_MUTEX_ACQUIRE(&(GET_DRIVER_CXT(pCxt)->utility_mutex)) +#endif + +#ifndef IRQEN_ACCESS_RELEASE +#define IRQEN_ACCESS_RELEASE(pCxt) A_MUTEX_RELEASE(&(GET_DRIVER_CXT(pCxt)->utility_mutex)) +#endif + +#ifndef IRQEN_ACCESS_DESTROY +/* because its the same mutex as RXBUFFER_ACCESS this is NOP */ +#define IRQEN_ACCESS_DESTROY(pCxt) +#endif + +#ifndef DRIVER_SHARED_RESOURCE_ACCESS_INIT +/* because its the same mutex as RXBUFFER_ACCESS this is NOP */ +#define DRIVER_SHARED_RESOURCE_ACCESS_INIT(pCxt) (A_OK) +#endif + +#ifndef DRIVER_SHARED_RESOURCE_ACCESS_ACQUIRE +#define DRIVER_SHARED_RESOURCE_ACCESS_ACQUIRE(pCxt) A_MUTEX_ACQUIRE(&(GET_DRIVER_CXT(pCxt)->utility_mutex)) +#endif + +#ifndef DRIVER_SHARED_RESOURCE_ACCESS_RELEASE +#define DRIVER_SHARED_RESOURCE_ACCESS_RELEASE(pCxt) A_MUTEX_RELEASE(&(GET_DRIVER_CXT(pCxt)->utility_mutex)) +#endif + +#ifndef DRIVER_SHARED_RESOURCE_ACCESS_DESTROY +/* because its the same mutex as RXBUFFER_ACCESS this is NOP */ +#define DRIVER_SHARED_RESOURCE_ACCESS_DESTROY(pCxt) +#endif + +/* + * A_MDELAY - used to delay specified number of milliseconds. + */ +#define A_MDELAY(msecs) a_task_delay(1 >= MSEC_TO_TICK(msecs) ? 1 : MSEC_TO_TICK(msecs)) + +#endif diff --git a/platform/mcu/lpc54102/wifi_qca/port/env/alios/wifi_port.h b/platform/mcu/lpc54102/wifi_qca/port/env/alios/wifi_port.h new file mode 100644 index 0000000000..f77c4a5a14 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/port/env/alios/wifi_port.h @@ -0,0 +1,65 @@ +/* + * The Clear BSD License + * Copyright (c) 2016, NXP Semiconductor, Inc. + * All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted (subject to the limitations in the disclaimer below) provided + * that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of NXP Semiconductor, Inc. nor the names of its + * contributors may be used tom endorse or promote products derived from this + * software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 + * 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 __WIFI_PORT_H__ +#define __WIFI_PORT_H__ + +/* "wifi_env_port.h" macros can be overloaded here. + * This file can contain only porting macros, nothing else */ + +#include "wifi_env_port.h" + +extern A_STATUS WIFISHIELD_PowerUp(uint32_t enable); +#define CUSTOM_HW_POWER_UP_DOWN(pCxt, powerup) \ + WIFISHIELD_PowerUp(powerup) + +extern A_STATUS WIFIDRVS_SPI_InOutBuffer(uint8_t *pBuffer, uint16_t length, uint8_t doRead, boolean sync); +#define CUSTOM_BUS_INOUT_BUFFER(pCxt, pBuffer, length, doRead, sync) \ + WIFIDRVS_SPI_InOutBuffer((pBuffer), (length), (doRead), (sync)) + +extern A_STATUS WIFIDRVS_SPI_InOutToken(uint32_t OutToken, uint8_t DataSize, uint32_t *pInToken); +#define CUSTOM_BUS_INOUT_TOKEN(pCxt, oT, dS, pInT) \ + WIFIDRVS_SPI_InOutToken((oT), (dS), (pInT)) + +#define CUSTOM_BUS_START_TRANSFER(pCxt, sync) (A_OK) + +#define CUSTOM_BUS_COMPLETE_TRANSFER(pCxt, sync) (A_OK) + +extern A_STATUS WIFISHIELD_InitDrivers(void *param); +#define CUSTOM_HW_INIT(pCxt) WIFISHIELD_InitDrivers((pCxt)) + +extern A_STATUS WIFISHIELD_DeinitDrivers(void *param); +#define CUSTOM_HW_DEINIT(pCxt) WIFISHIELD_DeinitDrivers((pCxt)) + +#endif diff --git a/platform/mcu/lpc54102/wifi_qca/port/pin_mux.c b/platform/mcu/lpc54102/wifi_qca/port/pin_mux.c new file mode 100644 index 0000000000..e9062ab6f0 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/port/pin_mux.c @@ -0,0 +1,152 @@ +/* + * The Clear BSD License + * Copyright (c) 2016, Freescale Semiconductor, Inc. + * Copyright 2016-2017 NXP + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted (subject to the limitations in the disclaimer below) provided + * that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 + * 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. + */ + +/* + * TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* +!!GlobalInfo +product: Pins v3.0 +processor: LPC54102J512 +package_id: LPC54102J512BD64 +mcu_data: ksdk2_0 +processor_version: 0.0.5 + * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS *********** + */ + +#include "fsl_common.h" +#include "fsl_iocon.h" +#include "pin_mux.h" + + + +#define IOCON_PIO_DIGITAL_EN 0x80u /*!< Enables digital function */ +#define IOCON_PIO_FUNC1 0x01u /*!< Selects pin function 1 */ +#define IOCON_PIO_INPFILT_OFF 0x0100u /*!< Input filter disabled */ +#define IOCON_PIO_INPFILT_ON 0x00u /*!< Input filter enabled */ +#define IOCON_PIO_INV_DI 0x00u /*!< Input function is not inverted */ +#define IOCON_PIO_MODE_INACT 0x00u /*!< No addition pin function */ +#define IOCON_PIO_OPENDRAIN_DI 0x00u /*!< Open drain is disabled */ +#define IOCON_PIO_SLEW_STANDARD 0x00u /*!< Standard mode, output slew rate control is enabled */ +#define PIN0_IDX 0u /*!< Pin number for pin 0 in a port 0 */ +#define PIN1_IDX 1u /*!< Pin number for pin 1 in a port 0 */ +#define PORT0_IDX 0u /*!< Port index */ + + +void BOARD_InitGT202Shield(void) +{ + /* Enables the clock for the IOCON block. 0 = Disable; 1 = Enable.: 0x01u */ + CLOCK_EnableClock(kCLOCK_Iocon); + + const uint32_t port1_pin6_config = ( + 2 | + IOCON_PIO_MODE_INACT | + IOCON_PIO_INV_DI | + IOCON_PIO_DIGITAL_EN | + IOCON_PIO_INPFILT_OFF | + IOCON_PIO_SLEW_STANDARD | + IOCON_PIO_OPENDRAIN_DI + ); + IOCON_PinMuxSet(IOCON, 1, 6, port1_pin6_config); + + const uint32_t port1_pin14_config = ( + 4 | + IOCON_PIO_MODE_INACT | + IOCON_PIO_INV_DI | + IOCON_PIO_DIGITAL_EN | + IOCON_PIO_INPFILT_OFF | + IOCON_PIO_SLEW_STANDARD | + IOCON_PIO_OPENDRAIN_DI + ); + IOCON_PinMuxSet(IOCON, 1, 14, port1_pin14_config); + + const uint32_t port1_pin7_config = ( + 2 | + IOCON_PIO_MODE_INACT | + IOCON_PIO_INV_DI | + IOCON_PIO_DIGITAL_EN | + IOCON_PIO_INPFILT_OFF | + IOCON_PIO_SLEW_STANDARD | + IOCON_PIO_OPENDRAIN_DI + ); + IOCON_PinMuxSet(IOCON, 1, 7, port1_pin7_config); +#if 0 + const uint32_t port1_pin15_config = ( + 4 | + IOCON_PIO_MODE_INACT | + IOCON_PIO_INV_DI | + IOCON_PIO_DIGITAL_EN | + IOCON_PIO_INPFILT_OFF | + IOCON_PIO_SLEW_STANDARD | + IOCON_PIO_OPENDRAIN_DI + ); +#else + const uint32_t port1_pin15_config = ( + 0 | + IOCON_PIO_MODE_INACT | + IOCON_PIO_INV_DI | + IOCON_PIO_DIGITAL_EN | + IOCON_PIO_INPFILT_OFF | + IOCON_PIO_SLEW_STANDARD | + IOCON_PIO_OPENDRAIN_DI + ); +#endif + IOCON_PinMuxSet(IOCON, 1, 15, port1_pin15_config); + + const uint32_t port0_pin4_config = ( + 0 | + IOCON_PIO_MODE_INACT | + IOCON_PIO_INV_DI | + IOCON_PIO_DIGITAL_EN | + IOCON_PIO_INPFILT_OFF | + IOCON_PIO_MODE(1) | + IOCON_PIO_SLEW_STANDARD | + IOCON_PIO_OPENDRAIN_DI + ); + IOCON_PinMuxSet(IOCON, 0, 4, port0_pin4_config); + + const uint32_t port0_pin6_config = ( + 0 | + IOCON_PIO_MODE_INACT | + IOCON_PIO_INV_DI | + IOCON_PIO_DIGITAL_EN | + IOCON_PIO_INPFILT_OFF | + IOCON_PIO_SLEW_STANDARD | + IOCON_PIO_MODE(2) | + IOCON_PIO_OPENDRAIN_DI + ); + IOCON_PinMuxSet(IOCON, 0, 6, port0_pin6_config); +} + +/******************************************************************************* + * EOF + ******************************************************************************/ diff --git a/platform/mcu/lpc54102/wifi_qca/port/wifi_common.h b/platform/mcu/lpc54102/wifi_qca/port/wifi_common.h new file mode 100644 index 0000000000..9c856c1d18 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/port/wifi_common.h @@ -0,0 +1,51 @@ +/* + * The Clear BSD License + * Copyright (c) 2016, NXP Semiconductor, Inc. + * All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted (subject to the limitations in the disclaimer below) provided + * that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o 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. + * + * o Neither the name of NXP Semiconductor, Inc. nor the names of its + * contributors may be used tom endorse or promote products derived from this + * software without specific prior written permission. + * + * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 + * 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 __WIFI_COMMON_H__ +#define __WIFI_COMMON_H__ + +#include "athdefs.h" +#include "fsl_common.h" + +/* porting macros only, + * redirected to env, board fn */ +#include "wifi_port.h" + +/* enviroment related code */ +#include "wifi_env.h" + +/* board related code */ +#include "wifi_shield.h" + +#endif diff --git a/platform/mcu/lpc54102/wifi_qca/qcom_api.h b/platform/mcu/lpc54102/wifi_qca/qcom_api.h new file mode 100644 index 0000000000..b9b0fb4250 --- /dev/null +++ b/platform/mcu/lpc54102/wifi_qca/qcom_api.h @@ -0,0 +1,597 @@ +// Copyright (c) Qualcomm Atheros, Inc. +// All rights reserved. +// Redistribution and use in source and binary forms, with or without modification, are permitted (subject to +// the limitations in the disclaimer below) 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 nor the names of its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY 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 +// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//============================================================================== +// Author(s): ="Atheros" +//============================================================================== + +#ifndef __QCOM_API_H__ +#define __QCOM_API_H__ + +#include "wmi.h" +#include "atheros_stack_offload.h" +#include "atheros_wifi.h" + + + + +/* NOTE: According 802.11 standard, the SSID can hold max 32B = 32 octets + * of unspecified content. However, the API treats SSID as an ASCII + * NULL terminated string of 32 chars max, so last 33th byte is + * reserved for last NULL char and '\0' won't be included in the + * SSID name. UTF8 encoding probably does not work as well. + * NOTE: 'ssid' member is a dummy array. Using nested struct allows to use + * sizeof() operator on QCOM_SSID pointer */ +typedef struct { + char ssid[33]; +} QCOM_SSID; + +/* EXAMPLE: + * QCOM_SSID ssid = QCOM_SSID_FROM_STR("my_ssid"); */ +#define QCOM_SSID_FROM_STR(str) ((QCOM_SSID){.ssid = (str)}) + +/* EXAMPLE: + * printf("%s", QCOM_SSID_TO_STR(ssid)); */ +#define QCOM_SSID_TO_STR(var) ((var).ssid) + + + + +/* NOTE: Pass-phrase must fit into 64B = 64 octets. The 65th + * byte is reserved for last NULL char. */ +typedef struct { + char passphrase[65]; +} QCOM_PASSPHRASE; + +/* EXAMPLE: + * QCOM_PASSPHRASE pass = QCOM_PASSPHRASE_FROM_STR("my_password"); */ +#define QCOM_PASSPHRASE_FROM_STR(str) ((QCOM_PASSPHRASE){.passphrase = (str)}) + +/* EXAMPLE: + * printf("%s", QCOM_PASSPHRASE_TO_STR(passphrase)); */ +#define QCOM_PASSPHRASE_TO_STR(var) ((var).passphrase) + + + + +/* NOTE: BSSID uses MAC addr */ +typedef struct { + uint8_t bssid[6]; +} QCOM_BSSID; + + +/* NOTE: Values must be shared amongst internals and API + * The name and place is probably not the best */ +typedef enum { + QCOM_ONCONNECT_EVENT_DISCONNECT = 0, + QCOM_ONCONNECT_EVENT_SUCCESS +} QCOM_ONCONNECT_EVENT; + + +/* 'ipconfig' enums */ +typedef enum +{ + QCOM_IPCONFIG_QUERY = IPCFG_QUERY, /*Retrieve IP parameters*/ + QCOM_IPCONFIG_STATIC = IPCFG_STATIC, /*Set static IP parameters*/ + QCOM_IPCONFIG_DHCP = IPCFG_DHCP, /*Run DHCP client*/ + QCOM_IPCONFIG_AUTO = IPCFG_AUTO, /*Run AUTO IP*/ +} QCOM_IPCONFIG_MODE; + + +#define QCOM_WPS_MAX_KEY_LEN 64 +#define WPS_MAX_DEVNAME_LEN 32 +#define MAX_SSID_LEN 32 +#define MAC_LEN 6 +#define MAX_SSID_LENGTH (32 + 1) +#define P2P_WPS_PIN_LEN 9 +#define MAX_PASSPHRASE_SIZE 64 +#define P2P_MAX_NOA_DESCRIPTORS 4 +#define WPS_MAX_PASSPHRASE_LEN 9 +#define P2P_PERSISTENT_FLAG 0x80 +#define MAX_LIST_COUNT 8 +#define P2P_AUTO_CHANNEL 0 +#define P2P_DEFAULT_CHAN 1 + +#define QCOM_PARAM_GROUP_SYSTEM 1 +#define QCOM_PARAM_GROUP_WLAN 2 +#define QCOM_PARAM_GROUP_NETWORK 3 + +/*define new param groups here*/ + +/*QCOM_PARAM_GROUP_SYSTEM Parameters*/ +#define QCOM_PARAM_GROUP_SYSTEM_SLEEP_MAINT_TIMEOUT_MSECS 1 +#define QCOM_PARAM_GROUP_SYSTEM_SLEEP_WATCHDOG_TIMEOUT_SECS 2 +/* Add new system tunables here, at the end */ + +/*QCOM_PARAM_GROUP_WLAN_Parameters*/ +#define QCOM_PARAM_GROUP_WLAN_WOW_ENABLE 1 +#define QCOM_PARAM_GROUP_WLAN_WOW_PATTERN 2 +#define QCOM_PARAM_GROUP_WLAN_WOW_GPIO 3 +#define QCOM_PARAM_GROUP_WLAN_WOW_HOSTSLEEP 4 + +/*QCOM_PARAM_GROUP_NETWORK_Parameters*/ +#define QCOM_PARAM_GROUP_NETWORK_DNS_TIMEOUT_SECS 1 + +#define QCOM_WOW_PATTERN_MAX_SIZE 8 + +typedef void *P2P_DEV_CTXT; +typedef void (*QCOM_PROMISCUOUS_CB)(unsigned char *buf, int length); + +typedef struct _qcom_scan_info +{ + uint8_t channel; + uint8_t ssid_len; + uint8_t rssi; + uint8_t security_enabled; + int16_t beacon_period; + uint8_t preamble; + uint8_t bss_type; + uint8_t bssid[6]; + uint8_t ssid[32]; + uint8_t rsn_cipher; + uint8_t rsn_auth; + uint8_t wpa_cipher; + uint8_t wpa_auth; +} QCOM_BSS_SCAN_INFO, *QCOM_BSS_SCAN_INFO_PTR; + +typedef struct _qcom_scan_params +{ + uint16_t fgStartPeriod; + uint16_t fgEndPeriod; + uint16_t bgPeriod; + uint16_t maxActChDwellTimeInMs; + uint16_t pasChDwellTimeInMs; + uint8_t shortScanRatio; + uint8_t scanCtrlFlags; + uint16_t minActChDwellTimeInMs; + uint16_t maxActScanPerSsid; + uint32_t maxDfsChActTimeInMs; +} qcom_scan_params_t; + +#define QCOM_START_SCAN_PARAMS_CHANNEL_LIST_MAX 12 + +typedef struct _qcom_start_scan_params +{ + boolean forceFgScan; + uint32_t homeDwellTimeInMs; + uint32_t forceScanIntervalInMs; + uint8_t scanType; + uint8_t numChannels; + uint16_t channelList[QCOM_START_SCAN_PARAMS_CHANNEL_LIST_MAX]; +} qcom_start_scan_params_t; + +typedef enum +{ + QCOM_WLAN_DEV_MODE_STATION = 0, + QCOM_WLAN_DEV_MODE_AP, + QCOM_WLAN_DEV_MODE_ADHOC, + QCOM_WLAN_DEV_MODE_INVALID +} QCOM_WLAN_DEV_MODE; + +typedef enum +{ + QCOM_11A_MODE = 0x1, + QCOM_11G_MODE = 0x2, + QCOM_11N_MODE = 0x3, + QCOM_11B_MODE = 0x4, + QCOM_HT40_MODE = 0x5, +} QCOM_WLAN_DEV_PHY_MODE; + +typedef enum +{ + WLAN_AUTH_NONE = 0, + WLAN_AUTH_WPA, + WLAN_AUTH_WPA2, + WLAN_AUTH_WPA_PSK, + WLAN_AUTH_WPA2_PSK, + WLAN_AUTH_WPA_CCKM, + WLAN_AUTH_WPA2_CCKM, + WLAN_AUTH_WPA2_PSK_SHA256, + WLAN_AUTH_WEP, + WLAN_AUTH_INVALID +} WLAN_AUTH_MODE; + +typedef enum +{ + WLAN_CRYPT_NONE = 0, + WLAN_CRYPT_WEP_CRYPT, + WLAN_CRYPT_TKIP_CRYPT, + WLAN_CRYPT_AES_CRYPT, + WLAN_CRYPT_WAPI_CRYPT, + WLAN_CRYPT_BIP_CRYPT, + WLAN_CRYPT_KTK_CRYPT, + WLAN_CRYPT_INVALID +} WLAN_CRYPT_TYPE; + +typedef enum { + WLAN_FRAME_BEACON = 0, + WLAN_FRAME_PROBE_REQ, + WLAN_FRAME_PROBE_RESP, + WLAN_FRAME_ASSOC_REQ, + WLAN_FRAME_ASSOC_RESP, + WLAN_FRAME_INVALID +} WLAN_MGMT_FRAME_TYPE; + +/* WPS credential information */ +typedef struct +{ + uint16_t ap_channel; + QCOM_SSID ssid; + uint8_t ssid_len; + WLAN_AUTH_MODE auth_type; /* WPS_AUTH_TYPE */ + WLAN_CRYPT_TYPE encr_type; /* WPS_ENCR_TYPE */ + uint8_t key_idx; + uint8_t key[QCOM_WPS_MAX_KEY_LEN + 1]; + uint8_t key_len; + uint8_t mac_addr[ATH_MAC_LEN]; +} qcom_wps_credentials_t; + +#if ENABLE_P2P_MODE + +typedef enum +{ + P2P_WPS_NOT_READY, + P2P_WPS_PIN_LABEL, + P2P_WPS_PIN_DISPLAY, + P2P_WPS_PIN_KEYPAD, + P2P_WPS_PBC +} P2P_WPS_METHOD; + +typedef struct +{ + uint8_t enable; + uint8_t count; + P2P_NOA_DESCRIPTOR noas[P2P_MAX_NOA_DESCRIPTORS]; +} P2P_NOA_INFO; + +typedef enum +{ + P2P_INV_ROLE_GO, + P2P_INV_ROLE_ACTIVE_GO, + P2P_INV_ROLE_CLIENT, +} P2P_INV_ROLE; + +typedef enum +{ + P2P_CONFIG_LISTEN_CHANNEL, + P2P_CONFIG_CROSS_CONNECT, + P2P_CONFIG_SSID_POSTFIX, + P2P_CONFIG_INTRA_BSS, + P2P_CONFIG_CONCURRENT_MODE, + P2P_CONFIG_GO_INTENT, + P2P_CONFIG_DEV_NAME, + P2P_CONFIG_P2P_OPMODE, + P2P_CONFIG_CCK_RATES, + P2P_CONFIG_MAX, +} P2P_CONF_ID; + +#endif // ENABLE_P2P_MODE + +typedef struct +{ + uint8_t addr[6]; +} A_MACADDR; + +typedef struct +{ + uint8_t rate_index; + uint8_t tries; + uint32_t size; + uint32_t chan; + uint8_t header_type; + uint16_t seq; + A_MACADDR addr1; + A_MACADDR addr2; + A_MACADDR addr3; + A_MACADDR addr4; + uint8_t *pdatabuf; + uint32_t buflen; +} QCOM_RAW_MODE_PARAM_t; + +typedef enum +{ + GPIO_EDGE_TRIGGER, + GPIO_LEVEL_TRIGGER +} QCOM_WOW_GPIO_TRIGGER; + +typedef struct +{ + uint32_t gpio; + boolean isActiveLow; + uint32_t triggerMechanism; /*0: edge triggered 1: level triggered*/ +} QCOM_WOW_GPIO; + +typedef struct +{ + uint32_t pattern_size; + uint32_t offset; + uint32_t pattern_index; + uint8_t pattern[QCOM_WOW_PATTERN_MAX_SIZE]; +} QCOM_WOW_PATTERN; + +typedef struct +{ + uint32_t enable; +} QCOM_WOW_ENABLE; + +typedef struct +{ + uint32_t awake; +} QCOM_WOW_HOST_SLEEP; + +#if ENABLE_STACK_OFFLOAD + +typedef struct sockaddr +{ + uint16_t sa_family; + char sa_data[32]; +} sockaddr_t; + +/*===================================================================================*/ +/* OTA */ +/* Set to upgrade Target FW. Otherwise, update customer image */ +#define QCOM_OTA_TARGET_FIRMWARE_UPGRADE (1 << 0) +/* Set to preserve the last active FW */ +#define QCOM_OTA_PRESERVE_LAST (1 << 1) +/* Set to erase upgrade partition rw dset */ +#define QCOM_OTA_ERASING_RW_DSET (1 << 2) +/* OTA Upgrade partitions */ +#define PARTITION_AUTO 0 /* Auto-select OTA partition */ + +typedef enum +{ + QCOM_OTA_PROTOCOL_TFTP = 0, + QCOM_OTA_PROTOCOL_FTP, + QCOM_OTA_PROTOCOL_HTTP, + QCOM_OTA_PROTOCOL_HTTPS, + QCOM_OTA_PROTOCOL_MAX = QCOM_OTA_PROTOCOL_TFTP, +} QCOM_OTA_PROTOCOL_t; + +int qcom_socket(int family, int type, int protocol); +int qcom_connect(int s, struct sockaddr *addr, int addrlen); +int qcom_bind(int s, struct sockaddr *addr, int addrlen); +int qcom_listen(int s, int backlog); +int qcom_accept(int s, struct sockaddr *addr, socklen_t *addrlen); +int qcom_setsockopt(int s, int level, int name, void *arg, int arglen); +int qcom_getsockopt(int s, int level, int name, void *arg, int arglen); +#if ZERO_COPY +int qcom_recv(int s, char **buf, int len, int flags); +#else +int qcom_recv(int s, char *buf, int len, int flags); +#endif + +#if ZERO_COPY +int qcom_recvfrom(int s, char **buf, int len, int flags, struct sockaddr *from, socklen_t *fromlen); +#else +int qcom_recvfrom(int s, char *buf, int len, int flags, struct sockaddr *from, socklen_t *fromlen); + +#endif +A_STATUS qcom_ipconfig(uint8_t device_id, QCOM_IPCONFIG_MODE mode, uint32_t *address, uint32_t *submask, uint32_t *gateway); +SSL *qcom_SSL_new(SSL_CTX *ctx); +SSL_CTX *qcom_SSL_ctx_new(SSL_ROLE_T role, int32_t inbufSize, int32_t outbufSize, int32_t reserved); +int32_t qcom_SSL_setCaList(SSL_CTX *ctx, SslCAList caList, uint32_t size); +int32_t qcom_SSL_addCert(SSL_CTX *ctx, SslCert cert, uint32_t size); +int32_t qcom_SSL_storeCert(char *name, SslCert cert, uint32_t size); +int32_t qcom_SSL_loadCert(SSL_CTX *ctx, SSL_CERT_TYPE_T type, char *name); +int32_t qcom_SSL_listCert(SSL_FILE_NAME_LIST *fileNames); +int32_t qcom_SSL_set_fd(SSL *ssl, uint32_t fd); +int32_t qcom_SSL_accept(SSL *ssl); +int32_t qcom_SSL_connect(SSL *ssl); +int32_t qcom_SSL_shutdown(SSL *ssl); +int32_t qcom_SSL_ctx_free(SSL_CTX *ctx); +int32_t qcom_SSL_configure(SSL *ssl, SSL_CONFIG *cfg); +#if ZERO_COPY +int32_t qcom_SSL_read(SSL *ssl, void **buf, int32_t num); +#else +int32_t qcom_SSL_read(SSL *ssl, void *buf, int32_t num); +#endif +int32_t qcom_SSL_write(SSL *ssl, const void *buf, int32_t num); + +int qcom_sendto(int s, char *buffer, int length, int flags, struct sockaddr *to, int tolen); +int qcom_send(int s, char *buffer, int length, int flags); +int qcom_socket_close(int s); +A_STATUS qcom_ip6_address_get(uint8_t device_id, + IP6_ADDR_T *v6Global, + IP6_ADDR_T *v6Link, + IP6_ADDR_T *v6DefGw, + IP6_ADDR_T *v6GlobalExtd, + int32_t *LinkPrefix, + int32_t *GlbPrefix, + int32_t *DefgwPrefix, + int32_t *GlbPrefixExtd); +A_STATUS qcom_ping(uint32_t host, uint32_t size); +A_STATUS qcom_ping6(uint8_t *host, uint32_t size); +A_STATUS qcom_ip6config_router_prefix( + uint8_t device_id, IP6_ADDR_T *addr, int32_t prefixlen, int32_t prefix_lifetime, int32_t valid_lifetime); +int32_t qcom_dhcps_set_pool(uint8_t device_id, uint32_t startip, uint32_t endip, int32_t leasetime); +A_STATUS qcom_http_server(int32_t enable); +A_STATUS qcom_http_set_post_cb(void *cxt, void *callback); +A_STATUS qcom_ip_http_server_method( + int32_t cmd, uint8_t *pagename, uint8_t *objname, int32_t objtype, int32_t objlen, uint8_t *value); +#if ENABLE_HTTP_CLIENT +A_STATUS qcom_http_client_method(uint32_t cmd, uint8_t *url, uint8_t *data, uint8_t *value); +#endif +#if ENABLE_ROUTING_CMDS +A_STATUS qcom_ip6_route(uint8_t device_id, + uint32_t cmd, + IP6_ADDR_T *ip6addr, + uint32_t *prefixLen, + IP6_ADDR_T *gw, + uint32_t *ifindex, + IPV6_ROUTE_LIST_T *rtlist); +A_STATUS qcom_ip4_route(uint8_t device_id, + uint32_t cmd, + IP_ADDR_T *addr, + IP_ADDR_T *subnet, + IP_ADDR_T *gw, + uint32_t *ifindex, + IPV4_ROUTE_LIST_T *rtlist); +#endif +A_STATUS qcom_tcp_conn_timeout(uint32_t timeout_val); +A_STATUS qcom_tcp_set_exp_backoff(uint8_t device_id, int32_t retry); +A_STATUS qcom_dhcps_release_pool(uint8_t device_id); +A_STATUS qcom_bridge_mode_enable(uint16_t bridgemode); +int32_t qcom_dhcps_register_cb(uint8_t device_id, void *callback); +int32_t qcom_dhcpc_register_cb(uint8_t device_id, void *callback); +#if ENABLE_DNS_CLIENT +A_STATUS qcom_dnsc_enable(boolean enable); +A_STATUS qcom_dnsc_add_server_address(uint8_t *ipaddress, uint8_t type); +A_STATUS qcom_dnsc_del_server_address(uint8_t *ipaddress, uint8_t type); +A_STATUS qcom_dnsc_get_host_by_name(char *pname, uint32_t *pipaddress); +A_STATUS qcom_dnsc_get_host_by_name2(char *pname, uint32_t *pipaddress, int32_t domain, uint32_t mode); +#endif + +#if ENABLE_DNS_SERVER +A_STATUS qcom_dns_server_address_get(uint32_t pdns[], uint32_t *number); +A_STATUS qcom_dnss_enable(boolean enable); +A_STATUS qcom_dns_local_domain(char *local_domain); +A_STATUS qcom_dns_entry_create(char *hostname, uint32_t ipaddress); +A_STATUS qcom_dns_entry_delete(char *hostname, uint32_t ipaddress); +A_STATUS qcom_dns_6entry_create(char *hostname, IP6_ADDR_T *ip6addr); +A_STATUS qcom_dns_6entry_delete(char *hostname, IP6_ADDR_T *ip6addr); +#endif + +#if ENABLE_SNTP_CLIENT +void qcom_sntp_srvr_addr(int flag, char *srv_addr); +void qcom_sntp_get_time(uint8_t device_id, tSntpTime *time); +void qcom_sntp_get_time_of_day(uint8_t device_id, tSntpTM *time); +void qcom_sntp_zone(int hour, int min, int add_sub, int enable); +void qcom_sntp_query_srvr_address(uint8_t device_id, tSntpDnsAddr *addr); +void qcom_enable_sntp_client(int enable); +#endif + +A_STATUS qcom_ota_upgrade(uint8_t device_id, + uint32_t addr, + char *filename, + uint8_t mode, + uint8_t preserve_last, + uint8_t protocol, + uint32_t *resp_code, + uint32_t *length); +A_STATUS qcom_ota_read_area(uint32_t offset, uint32_t size, uint8_t *buffer, uint32_t *ret_len); +A_STATUS qcom_ota_done(boolean good_image); +QCOM_OTA_STATUS_CODE_t qcom_ota_session_start(uint32_t flags, uint32_t partition_index); +uint32_t qcom_ota_partition_get_size(void); +QCOM_OTA_STATUS_CODE_t qcom_ota_partition_erase(void); +QCOM_OTA_STATUS_CODE_t qcom_ota_parse_image_hdr(uint8_t *header, uint32_t *offset); +QCOM_OTA_STATUS_CODE_t qcom_ota_partition_verify_checksum(void); +uint32_t qcom_ota_partition_read_data(uint32_t offset, uint8_t *buf, uint32_t size); +QCOM_OTA_STATUS_CODE_t qcom_ota_partition_write_data(uint32_t offset, uint8_t *buf, uint32_t size, uint32_t *ret_size); +QCOM_OTA_STATUS_CODE_t qcom_ota_session_end(uint32_t good_image); +QCOM_OTA_STATUS_CODE_t qcom_ota_partition_format(uint32_t partition_index); +A_STATUS qcom_ota_set_callback(void *callback); +#endif + +#define qcom_set_scan(device_id, pScanParams) _qcom_set_scan(device_id, pScanParams) +A_STATUS _qcom_set_scan(uint8_t device_id, qcom_start_scan_params_t *pScanParams); +A_STATUS qcom_get_scan(uint8_t device_id, QCOM_BSS_SCAN_INFO **buf, int16_t *numResults); +A_STATUS qcom_set_ssid(uint8_t device_id, QCOM_SSID *pssid); +A_STATUS qcom_get_ssid(uint8_t device_id, QCOM_SSID *pssid); +A_STATUS qcom_scan_set_mode(uint8_t device_id, uint32_t mode); +A_STATUS qcom_set_connect_callback(uint8_t device_id, void *callback); +A_STATUS qcom_set_probe_req_callback(uint8_t device_id, void *callback); +A_STATUS qcom_enable_probe_req_event(uint8_t device_id, uint8_t enable); +A_STATUS qcom_commit(uint8_t device_id); +A_STATUS qcom_sta_get_rssi(uint8_t device_id, uint8_t *prssi); +A_STATUS qcom_sta_set_listen_time(uint8_t device_id, uint32_t listentime); +A_STATUS qcom_ap_set_beacon_interval(uint8_t device_id, uint16_t beacon_interval); +A_STATUS qcom_ap_hidden_mode_enable(uint8_t device_id, boolean enable); +A_STATUS qcom_op_get_mode(uint8_t device_id, QCOM_WLAN_DEV_MODE *pmode); +A_STATUS qcom_op_set_mode(uint8_t device_id, QCOM_WLAN_DEV_MODE mode); +A_STATUS qcom_disconnect(uint8_t device_id); +A_STATUS qcom_set_phy_mode(uint8_t device_id, uint8_t phymode); +A_STATUS qcom_get_phy_mode(uint8_t device_id, char **pphymode); +A_STATUS qcom_get_country_code(uint8_t device_id, uint8_t *countryCode); +A_STATUS qcom_set_country_code(uint8_t device_id, uint8_t *countryCode); +A_STATUS qcom_set_channel(uint8_t device_id, uint16_t channel); +A_STATUS qcom_get_channel(uint8_t device_id, uint16_t *pchannel); +A_STATUS qcom_set_tx_power(uint8_t device_id, uint32_t dbm); +A_STATUS qcom_allow_aggr_set_tid(uint8_t device_id, uint16_t tx_allow_aggr, uint16_t rx_allow_aggr); +A_STATUS qcom_sec_set_wepkey(uint8_t device_id, uint32_t keyindex, char *pkey); +A_STATUS qcom_sec_get_wepkey(uint8_t device_id, uint32_t keyindex, char *pkey); +A_STATUS qcom_sec_set_wepkey_index(uint8_t device_id, uint32_t keyindex); +A_STATUS qcom_sec_get_wepkey_index(uint8_t device_id, uint32_t *pkeyindex); +A_STATUS qcom_sec_set_auth_mode(uint8_t device_id, WLAN_AUTH_MODE mode); +A_STATUS qcom_sec_set_encrypt_mode(uint8_t device_id, WLAN_CRYPT_TYPE mode); +A_STATUS qcom_sec_set_passphrase(uint8_t device_id, QCOM_PASSPHRASE *passphrase); +A_STATUS qcom_sec_set_pmk(uint8_t device_id, char *pmk); + +A_STATUS qcom_power_set_mode(uint8_t device_id, uint32_t powerMode, uint8_t powerModule); +A_STATUS qcom_power_get_mode(uint8_t device_id, uint32_t *powerMode); +A_STATUS qcom_suspend_enable(boolean enable); +A_STATUS qcom_suspend_start(uint32_t susp_time); +A_STATUS qcom_power_set_parameters(uint8_t device_id, + uint16_t idlePeriod, + uint16_t psPollNum, + uint16_t dtimPolicy, + uint16_t tx_wakeup_policy, + uint16_t num_tx_to_wakeup, + uint16_t ps_fail_event_policy); +A_STATUS qcom_get_bssid(uint8_t device_id, uint8_t mac_addr[ATH_MAC_LEN]); + +A_STATUS qcom_sec_get_auth_mode(uint8_t device_id, uint32_t *pmode); +A_STATUS qcom_sec_get_encrypt_mode(uint8_t device_id, uint32_t *pmode); +A_STATUS qcom_sec_get_passphrase(uint8_t device_id, char *passphrase); + +A_STATUS qcom_wps_start(uint8_t device_id, int connect, int use_pinmode, char *pin); +A_STATUS qcom_wps_connect(uint8_t device_id); +A_STATUS qcom_wps_set_credentials(uint8_t device_id, qcom_wps_credentials_t *pwps_prof); + +#if ENABLE_P2P_MODE +A_STATUS qcom_p2p_func_init(uint8_t device_id, int32_t enable); +A_STATUS qcom_p2p_func_cancel(uint8_t device_id); +A_STATUS qcom_p2p_func_set_pass_ssid(uint8_t device_id, QCOM_PASSPHRASE *ppass, QCOM_SSID *pssid); +A_STATUS qcom_p2p_func_auth( + uint8_t device_id, int32_t dev_auth, P2P_WPS_METHOD wps_method, uint8_t *peer_mac, boolean persistent); +A_STATUS qcom_p2p_func_connect(uint8_t device_id, P2P_WPS_METHOD wps_method, uint8_t *peer_mac, boolean persistent); +A_STATUS qcom_p2p_func_set_config(uint8_t device_id, + uint32_t uigo_intent, + uint32_t uiclisten_ch, + uint32_t uiop_ch, + uint32_t uiage, + uint32_t reg_class, + uint32_t op_reg_class, + uint32_t max_node_count); +A_STATUS qcom_p2p_func_set_oppps(uint8_t device_id, uint8_t enable, uint8_t ctwin); +A_STATUS qcom_p2p_func_set_noa( + uint8_t device_id, uint8_t uccount, uint32_t uistart, uint32_t uiduration, uint32_t uiinterval); +A_STATUS qcom_p2p_func_invite( + uint8_t device_id, char *pssid, P2P_WPS_METHOD wps_method, uint8_t *pmac, boolean persistent, P2P_INV_ROLE role); +A_STATUS qcom_p2p_func_find(uint8_t device_id, void *dev, uint8_t type, uint32_t timeout); +A_STATUS qcom_p2p_func_stop_find(uint8_t device_id); +A_STATUS qcom_p2p_func_get_node_list(uint8_t device_id, void *app_buf, uint32_t buf_size); +A_STATUS qcom_p2p_func_get_network_list(uint8_t device_id, void *app_buf, uint32_t buf_size); +A_STATUS qcom_p2p_func_invite_auth(uint8_t device_id, uint8_t *inv); +A_STATUS qcom_p2p_func_listen(uint8_t device_id, uint32_t timeout); +A_STATUS qcom_p2p_func_join_profile(uint8_t device_id, uint8_t *pmac); +A_STATUS qcom_p2p_set(uint8_t device_id, P2P_CONF_ID config_id, void *data, uint32_t data_length); +A_STATUS qcom_p2p_func_prov(uint8_t device_id, P2P_WPS_METHOD wps_method, uint8_t *pmac); +A_STATUS qcom_p2p_func_join(uint8_t device_id, P2P_WPS_METHOD wps_method, uint8_t *pmac, char *ppin, uint16_t channel); +A_STATUS qcom_p2p_func_start_go( + uint8_t device_id, QCOM_SSID *pssid, QCOM_PASSPHRASE *ppass, int32_t channel, boolean ucpersistent); +#endif // ENABLE_P2P_MODE +A_STATUS qcom_raw_mode_send_pkt(QCOM_RAW_MODE_PARAM_t *ppara); +A_STATUS qcom_scan_params_set(uint8_t device_id, qcom_scan_params_t *pParam); +A_STATUS qcom_param_set( + uint8_t device_id, uint16_t grp_id, uint16_t param_id, void *data, uint32_t data_length, boolean wait_for_status); + +A_STATUS qcom_get_versionstr(ATH_VERSION_STR *versionstr); + +#endif diff --git a/platform/mcu/moc108/aos/framework_runtime/framework_runtime.c b/platform/mcu/moc108/aos/framework_runtime/framework_runtime.c index 31e8f91fdb..ba5fb20adc 100644 --- a/platform/mcu/moc108/aos/framework_runtime/framework_runtime.c +++ b/platform/mcu/moc108/aos/framework_runtime/framework_runtime.c @@ -24,7 +24,10 @@ static void framework_entry(void *syscall_tbl, int argc, char *argv[]) { /* syscall_ktbl assignment must be first */ syscall_ktbl = (int *)syscall_tbl; + +#ifdef AOS_FRAMEWORK_COMMON aos_framework_init(); +#endif /*app_pre_init();*/ if (app_info->app_entry) { diff --git a/platform/mcu/moc108/hal/StringUtils.c b/platform/mcu/moc108/hal/StringUtils.c index 72f424fd8e..34a7100649 100644 --- a/platform/mcu/moc108/hal/StringUtils.c +++ b/platform/mcu/moc108/hal/StringUtils.c @@ -1,34 +1,3 @@ -/** - ****************************************************************************** - * @file StringUtils.c - * @author William Xu - * @version V1.0.0 - * @date 05-May-2014 - * @brief This file contains function for manipulating strings.. - ****************************************************************************** - * - * The MIT License - * Copyright (c) 2014 MXCHIP Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR - * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ****************************************************************************** - */ - #include "StringUtils.h" #include "aos/aos.h" diff --git a/platform/mcu/moc108/hal/StringUtils.h b/platform/mcu/moc108/hal/StringUtils.h index 16a9bce2e9..90d1764c8b 100644 --- a/platform/mcu/moc108/hal/StringUtils.h +++ b/platform/mcu/moc108/hal/StringUtils.h @@ -1,33 +1,3 @@ -/** - ****************************************************************************** - * @file StringUtils.h - * @author William Xu - * @version V1.0.0 - * @date 05-May-2014 - * @brief This header contains function prototypes for manipulating strings.. - ****************************************************************************** - * - * The MIT License - * Copyright (c) 2014 MXCHIP Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR - * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ****************************************************************************** - */ #ifndef __StringUtils_h__ #define __StringUtils_h__ diff --git a/platform/mcu/moc108/hal/hw.c b/platform/mcu/moc108/hal/hw.c index e464a02914..16df327d3c 100644 --- a/platform/mcu/moc108/hal/hw.c +++ b/platform/mcu/moc108/hal/hw.c @@ -21,28 +21,23 @@ static void _timer_cb(void *timer, void *arg) { - hal_timer_t *tmr = arg; - tmr->cb(tmr->arg); + timer_dev_t *tmr = arg; + tmr->config.cb(tmr->config.arg); } -void hal_timer_init(hal_timer_t *tmr, unsigned int period, unsigned char auto_reload, unsigned char ch, hal_timer_cb_t cb, void *arg) +int32_t hal_timer_init(timer_dev_t *tim) { - (void)ch; - memset(tmr, 0, sizeof(*tmr)); - tmr->cb = cb; - tmr->arg = arg; - if (auto_reload > 0u) { - krhino_timer_dyn_create((ktimer_t **)&tmr->priv, "hwtmr", _timer_cb, - us2tick(period), us2tick(period), tmr, 0); + if (tim->config.reload_mode == TIMER_RELOAD_AUTO) { + krhino_timer_dyn_create((ktimer_t **)&tim->priv, "hwtmr", _timer_cb, + us2tick(tim->config.period), us2tick(tim->config.period), tim, 0); } else { - krhino_timer_dyn_create((ktimer_t **)&tmr->priv, "hwtmr", _timer_cb, - us2tick(period), 0, tmr, 0); + krhino_timer_dyn_create((ktimer_t **)&tim->priv, "hwtmr", _timer_cb, + us2tick(tim->config.period), 0, tim, 0); } } - -void hal_timer_stop(hal_timer_t *tmr) +void hal_timer_stop(timer_dev_t *tmr) { krhino_timer_stop(tmr->priv); krhino_timer_dyn_del(tmr->priv); diff --git a/platform/mcu/moc108/hal/i2c.c b/platform/mcu/moc108/hal/i2c.c new file mode 100644 index 0000000000..57e46de44f --- /dev/null +++ b/platform/mcu/moc108/hal/i2c.c @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#include +#include "hal/soc/soc.h" + +int32_t hal_i2c_init(i2c_dev_t *i2c) +{ + int32_t ret = 0; + + return ret; +} + +int32_t hal_i2c_master_send(i2c_dev_t *i2c, uint16_t dev_addr, const uint8_t *data, + uint16_t size, uint32_t timeout) +{ + int32_t ret = 0; + + return ret; +} + +int32_t hal_i2c_master_recv(i2c_dev_t *i2c, uint16_t dev_addr, uint8_t *data, + uint16_t size, uint32_t timeout) +{ + int32_t ret = 0; + + return ret; +} + +int32_t hal_i2c_slave_send(i2c_dev_t *i2c, const uint8_t *data, uint16_t size, uint32_t timeout) +{ + int32_t ret = 0; + + return ret; +} + +int32_t hal_i2c_slave_recv(i2c_dev_t *i2c, uint8_t *data, uint16_t size, uint32_t timeout) +{ + int32_t ret = 0; + + return ret; +} + +int32_t hal_i2c_mem_write(i2c_dev_t *i2c, uint16_t dev_addr, uint16_t mem_addr, + uint16_t mem_addr_size, const uint8_t *data, uint16_t size, + uint32_t timeout) +{ + int32_t ret = 0; + + return ret; +}; + +int32_t hal_i2c_mem_read(i2c_dev_t *i2c, uint16_t dev_addr, uint16_t mem_addr, + uint16_t mem_addr_size, uint8_t *data, uint16_t size, + uint32_t timeout) +{ + int32_t ret = 0; + + return ret; +}; + +int32_t hal_i2c_finalize(i2c_dev_t *i2c) +{ + int32_t ret = 0; + + return ret; +} diff --git a/platform/mcu/moc108/hal/mesh_wifi_hal.c b/platform/mcu/moc108/hal/mesh_wifi_hal.c index 3254468e92..00e4b32ab8 100644 --- a/platform/mcu/moc108/hal/mesh_wifi_hal.c +++ b/platform/mcu/moc108/hal/mesh_wifi_hal.c @@ -83,7 +83,6 @@ typedef struct { void *context; umesh_hal_module_t *module; - mesh_key_t keys[2]; unsigned char bssid[WIFI_MAC_ADDR_SIZE]; unsigned char macaddr[WIFI_MAC_ADDR_SIZE]; @@ -116,8 +115,8 @@ enum { }; static mac_entry_t entries[ENT_NUM]; - static mesh_hal_priv_t *g_hal_priv; +static bool g_radio_wakeup = true; extern int bk_wlan_monitor_enabled(void); static void pass_to_umesh(const void* arg) @@ -210,6 +209,10 @@ static int send_frame(umesh_hal_module_t *module, frame_t *frame, umesh_handle_sent_ucast_t sent; int result = 0; + if (g_radio_wakeup == false) { + return -2; + } + pkt = aos_malloc(len); if (pkt == NULL) { result = 1; @@ -373,6 +376,27 @@ void beken_wifi_mesh_get_extnetid(umesh_hal_module_t *module, memcpy(extnetid->netid, priv->bssid, extnetid->len); } +int beken_wifi_mesh_radio_wakeup(struct umesh_hal_module_s *module) +{ +#ifdef CONFIG_AOS_MESH_LOWPOWER + g_radio_wakeup = true; + if (bk_wlan_is_ap() == 0 && bk_wlan_is_sta() == 0 && bk_wlan_monitor_enabled() == 0) { + bk_wlan_start_monitor(); + hal_machw_exit_monitor_mode(); + } +#endif + return 0; +} + +int beken_wifi_mesh_radio_sleep(struct umesh_hal_module_s *module) +{ +#ifdef CONFIG_AOS_MESH_LOWPOWER + g_radio_wakeup = false; + bk_wlan_suspend(); +#endif + return 0; +} + static const frame_stats_t *beken_wifi_mesh_get_stats( umesh_hal_module_t *module) { @@ -411,6 +435,8 @@ static umesh_hal_module_t beken_wifi_mesh_module = { .umesh_hal_get_extnetid = beken_wifi_mesh_get_extnetid, .umesh_hal_get_stats = beken_wifi_mesh_get_stats, .umesh_hal_get_chnlist = beken_wifi_mesh_get_channel_list, + .umesh_hal_radio_wakeup = beken_wifi_mesh_radio_wakeup, + .umesh_hal_radio_sleep = beken_wifi_mesh_radio_sleep, }; #endif diff --git a/platform/mcu/moc108/hal/ringbuf.c b/platform/mcu/moc108/hal/ringbuf.c index 74470d31da..fcf1ad179f 100644 --- a/platform/mcu/moc108/hal/ringbuf.c +++ b/platform/mcu/moc108/hal/ringbuf.c @@ -1,33 +1,3 @@ -/** - ****************************************************************************** - * @file RingBufferUtils.c - * @author William Xu - * @version V1.0.0 - * @date 05-May-2014 - * @brief This file contains function called by ring buffer operation - ****************************************************************************** - * - * The MIT License - * Copyright (c) 2014 MXCHIP Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR - * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ****************************************************************************** - */ #include "ringbuf.h" diff --git a/platform/mcu/moc108/hal/ringbuf.h b/platform/mcu/moc108/hal/ringbuf.h index 7ccf49f11d..dc8507e9a8 100644 --- a/platform/mcu/moc108/hal/ringbuf.h +++ b/platform/mcu/moc108/hal/ringbuf.h @@ -1,34 +1,3 @@ -/** - ****************************************************************************** - * @file RingBufferUtils.h - * @author William Xu - * @version V1.0.0 - * @date 05-May-2014 - * @brief This header contains function prototypes called by ring buffer - * operation - ****************************************************************************** - * - * The MIT License - * Copyright (c) 2014 MXCHIP Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR - * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ****************************************************************************** - */ #ifndef __RingBufferUtils_h__ #define __RingBufferUtils_h__ diff --git a/platform/mcu/moc108/libmoc108.a b/platform/mcu/moc108/libmoc108.a index 39efb95d9e..5290e658a0 100644 Binary files a/platform/mcu/moc108/libmoc108.a and b/platform/mcu/moc108/libmoc108.a differ diff --git a/platform/mcu/moc108/linkinfo/mx108_framework.ld.S b/platform/mcu/moc108/linkinfo/mx108_framework.ld.S index 799e9852b2..ad6890b8a8 100644 --- a/platform/mcu/moc108/linkinfo/mx108_framework.ld.S +++ b/platform/mcu/moc108/linkinfo/mx108_framework.ld.S @@ -11,7 +11,6 @@ INCLUDE memory_framework.ld OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") OUTPUT_ARCH(arm) -ENTRY(aos_framework_init) SECTIONS { diff --git a/platform/mcu/moc108/moc108.mk b/platform/mcu/moc108/moc108.mk index 96c89e0313..ed231af807 100644 --- a/platform/mcu/moc108/moc108.mk +++ b/platform/mcu/moc108/moc108.mk @@ -1,11 +1,3 @@ -# -# UNPUBLISHED PROPRIETARY SOURCE CODE -# Copyright (c) 2016 MXCHIP Inc. -# -# The contents of this file may not be disclosed to third parties, copied or -# duplicated in any form, in whole or in part, without the prior written -# permission of MXCHIP Corporation. -# NAME := moc108 HOST_OPENOCD := moc108 @@ -16,12 +8,13 @@ endif $(NAME)_TYPE := kernel -$(NAME)_COMPONENTS += platform/arch/arm/armv5 -$(NAME)_COMPONENTS += libc rhino hal netmgr framework.common alicrypto cjson cli digest_algorithm +$(NAME)_COMPONENTS := platform/arch/arm/armv5 +$(NAME)_COMPONENTS += libc rhino yloop modules.fs.kv alicrypto digest_algorithm $(NAME)_COMPONENTS += protocols.net protocols.mesh $(NAME)_COMPONENTS += platform/mcu/moc108/aos/framework_runtime $(NAME)_COMPONENTS += platform/mcu/moc108/aos/app_runtime $(NAME)_COMPONENTS += prov +$(NAME)_COMPONENTS += hal GLOBAL_DEFINES += CONFIG_MX108 GLOBAL_DEFINES += CONFIG_AOS_KV_MULTIPTN_MODE @@ -81,7 +74,7 @@ endif endif $(NAME)_INCLUDES += aos -$(NAME)_SOURCES := aos/aos_main.c aos/qc_test.c +$(NAME)_SOURCES := aos/aos_main.c $(NAME)_SOURCES += aos/soc_impl.c \ aos/trace_impl.c \ hal/mesh_wifi_hal.c diff --git a/platform/mcu/mx1101/hal/i2c.c b/platform/mcu/mx1101/hal/i2c.c new file mode 100644 index 0000000000..57e46de44f --- /dev/null +++ b/platform/mcu/mx1101/hal/i2c.c @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#include +#include "hal/soc/soc.h" + +int32_t hal_i2c_init(i2c_dev_t *i2c) +{ + int32_t ret = 0; + + return ret; +} + +int32_t hal_i2c_master_send(i2c_dev_t *i2c, uint16_t dev_addr, const uint8_t *data, + uint16_t size, uint32_t timeout) +{ + int32_t ret = 0; + + return ret; +} + +int32_t hal_i2c_master_recv(i2c_dev_t *i2c, uint16_t dev_addr, uint8_t *data, + uint16_t size, uint32_t timeout) +{ + int32_t ret = 0; + + return ret; +} + +int32_t hal_i2c_slave_send(i2c_dev_t *i2c, const uint8_t *data, uint16_t size, uint32_t timeout) +{ + int32_t ret = 0; + + return ret; +} + +int32_t hal_i2c_slave_recv(i2c_dev_t *i2c, uint8_t *data, uint16_t size, uint32_t timeout) +{ + int32_t ret = 0; + + return ret; +} + +int32_t hal_i2c_mem_write(i2c_dev_t *i2c, uint16_t dev_addr, uint16_t mem_addr, + uint16_t mem_addr_size, const uint8_t *data, uint16_t size, + uint32_t timeout) +{ + int32_t ret = 0; + + return ret; +}; + +int32_t hal_i2c_mem_read(i2c_dev_t *i2c, uint16_t dev_addr, uint16_t mem_addr, + uint16_t mem_addr_size, uint8_t *data, uint16_t size, + uint32_t timeout) +{ + int32_t ret = 0; + + return ret; +}; + +int32_t hal_i2c_finalize(i2c_dev_t *i2c) +{ + int32_t ret = 0; + + return ret; +} diff --git a/platform/mcu/mx1101/mx1101.mk b/platform/mcu/mx1101/mx1101.mk index 8869f17090..3f6c95efd6 100644 --- a/platform/mcu/mx1101/mx1101.mk +++ b/platform/mcu/mx1101/mx1101.mk @@ -1,11 +1,3 @@ -# -# UNPUBLISHED PROPRIETARY SOURCE CODE -# Copyright (c) 2016 MXCHIP Inc. -# -# The contents of this file may not be disclosed to third parties, copied or -# duplicated in any form, in whole or in part, without the prior written -# permission of MXCHIP Corporation. -# NAME := MX1101 @@ -47,5 +39,6 @@ $(NAME)_CFLAGS += -Wno-return-type -Wno-unused-function -Wno-unused-but-set-var $(NAME)_CFLAGS += -Wno-unused-value -Wno-strict-aliasing $(NAME)_SOURCES := aos/soc_impl.c +$(NAME)_SOURCES := hal/i2c.c -$(NAME)_COMPONENTS += platform/mcu/mx1101/sdk \ No newline at end of file +$(NAME)_COMPONENTS += platform/mcu/mx1101/sdk diff --git a/platform/mcu/mx1101/sdk/main.c b/platform/mcu/mx1101/sdk/main.c index 8803131693..2f319cc530 100644 --- a/platform/mcu/mx1101/sdk/main.c +++ b/platform/mcu/mx1101/sdk/main.c @@ -1,33 +1,3 @@ -/** -****************************************************************************** -* @file crt0_IAR.h -* @author William Xu -* @version V1.0.0 -* @date 16-Sep-2014 -* @brief __low_level_init called by IAR before main. -****************************************************************************** -* -* The MIT License -* Copyright (c) 2014 MXCHIP Inc. -* -* Permission is hereby granted, free of charge, to any person obtaining a copy -* of this software and associated documentation files (the "Software"), to deal -* in the Software without restriction, including without limitation the rights -* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -* copies of the Software, and to permit persons to whom the Software is furnished -* to do so, subject to the following conditions: -* -* The above copyright notice and this permission notice shall be included in -* all copies or substantial portions of the Software. -* -* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -* IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -****************************************************************************** -*/ #include "gpio.h" #include "uart.h" diff --git a/platform/mcu/stm32f4xx/GCC/app_ram.ld b/platform/mcu/stm32f4xx/GCC/app_ram.ld index 0a16008239..8b163b3423 100644 --- a/platform/mcu/stm32f4xx/GCC/app_ram.ld +++ b/platform/mcu/stm32f4xx/GCC/app_ram.ld @@ -1,12 +1,3 @@ -/** - * UNPUBLISHED PROPRIETARY SOURCE CODE - * Copyright (c) 2016 MXCHIP Inc. - * - * The contents of this file may not be disclosed to third parties, copied or - * duplicated in any form, in whole or in part, without the prior written - * permission of MXCHIP Corporation. - * - */ Reset_Handler = _start; diff --git a/platform/mcu/stm32f4xx/GCC/bootloader.ld b/platform/mcu/stm32f4xx/GCC/bootloader.ld index 150d94a859..32c36253e5 100644 --- a/platform/mcu/stm32f4xx/GCC/bootloader.ld +++ b/platform/mcu/stm32f4xx/GCC/bootloader.ld @@ -1,13 +1,3 @@ -/** - * UNPUBLISHED PROPRIETARY SOURCE CODE - * Copyright (c) 2016 MXCHIP Inc. - * - * The contents of this file may not be disclosed to third parties, copied or - * duplicated in any form, in whole or in part, without the prior written - * permission of MXCHIP Corporation. - * - */ - Reset_Handler = _start; diff --git a/platform/mcu/stm32f4xx/GCC/platform_unhandled_isr.c b/platform/mcu/stm32f4xx/GCC/platform_unhandled_isr.c index 7302cf0cb0..c7cc8010ba 100644 --- a/platform/mcu/stm32f4xx/GCC/platform_unhandled_isr.c +++ b/platform/mcu/stm32f4xx/GCC/platform_unhandled_isr.c @@ -1,12 +1,3 @@ -/** - * UNPUBLISHED PROPRIETARY SOURCE CODE - * Copyright (c) 2016 MXCHIP Inc. - * - * The contents of this file may not be disclosed to third parties, copied or - * duplicated in any form, in whole or in part, without the prior written - * permission of MXCHIP Corporation. - * - */ /** @file * Defines STM32F4xx default unhandled ISR and default mappings to unhandled ISR diff --git a/platform/mcu/stm32f4xx/hal/hw.c b/platform/mcu/stm32f4xx/hal/hw.c index 8d07502342..163ba433f7 100644 --- a/platform/mcu/stm32f4xx/hal/hw.c +++ b/platform/mcu/stm32f4xx/hal/hw.c @@ -29,33 +29,29 @@ void hal_reboot(void) static void _timer_cb(void *timer, void *arg) { - hal_timer_t *tmr = arg; - tmr->cb(tmr->arg); + timer_dev_t *tmr = arg; + tmr->config.cb(tmr->config.arg); } -void hal_timer_init(hal_timer_t *tmr, unsigned int period, unsigned char auto_reload, unsigned char ch, hal_timer_cb_t cb, void *arg) +int32_t hal_timer_init(timer_dev_t *tim) { - (void)ch; - memset(tmr, 0, sizeof(*tmr)); - tmr->cb = cb; - tmr->arg = arg; - if (auto_reload > 0u) { - krhino_timer_dyn_create((ktimer_t **)&tmr->priv, "hwtmr", _timer_cb, - us2tick(period), us2tick(period), tmr, 0); + if (tim->config.reload_mode == TIMER_RELOAD_AUTO) { + krhino_timer_dyn_create((ktimer_t **)&tim->priv, "hwtmr", _timer_cb, + us2tick(tim->config.period), us2tick(tim->config.period), tim, 0); } else { - krhino_timer_dyn_create((ktimer_t **)&tmr->priv, "hwtmr", _timer_cb, - us2tick(period), 0, tmr, 0); + krhino_timer_dyn_create((ktimer_t **)&tim->priv, "hwtmr", _timer_cb, + us2tick(tim->config.period), 0, tim, 0); } } -int32_t hal_timer_start(hal_timer_t *tmr) +int32_t hal_timer_start(timer_dev_t *tmr) { return krhino_timer_start(tmr->priv); } -void hal_timer_stop(hal_timer_t *tmr) +void hal_timer_stop(timer_dev_t *tmr) { krhino_timer_stop(tmr->priv); krhino_timer_dyn_del(tmr->priv); diff --git a/platform/mcu/stm32f4xx/hal/i2c.c b/platform/mcu/stm32f4xx/hal/i2c.c new file mode 100644 index 0000000000..57e46de44f --- /dev/null +++ b/platform/mcu/stm32f4xx/hal/i2c.c @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#include +#include "hal/soc/soc.h" + +int32_t hal_i2c_init(i2c_dev_t *i2c) +{ + int32_t ret = 0; + + return ret; +} + +int32_t hal_i2c_master_send(i2c_dev_t *i2c, uint16_t dev_addr, const uint8_t *data, + uint16_t size, uint32_t timeout) +{ + int32_t ret = 0; + + return ret; +} + +int32_t hal_i2c_master_recv(i2c_dev_t *i2c, uint16_t dev_addr, uint8_t *data, + uint16_t size, uint32_t timeout) +{ + int32_t ret = 0; + + return ret; +} + +int32_t hal_i2c_slave_send(i2c_dev_t *i2c, const uint8_t *data, uint16_t size, uint32_t timeout) +{ + int32_t ret = 0; + + return ret; +} + +int32_t hal_i2c_slave_recv(i2c_dev_t *i2c, uint8_t *data, uint16_t size, uint32_t timeout) +{ + int32_t ret = 0; + + return ret; +} + +int32_t hal_i2c_mem_write(i2c_dev_t *i2c, uint16_t dev_addr, uint16_t mem_addr, + uint16_t mem_addr_size, const uint8_t *data, uint16_t size, + uint32_t timeout) +{ + int32_t ret = 0; + + return ret; +}; + +int32_t hal_i2c_mem_read(i2c_dev_t *i2c, uint16_t dev_addr, uint16_t mem_addr, + uint16_t mem_addr_size, uint8_t *data, uint16_t size, + uint32_t timeout) +{ + int32_t ret = 0; + + return ret; +}; + +int32_t hal_i2c_finalize(i2c_dev_t *i2c) +{ + int32_t ret = 0; + + return ret; +} diff --git a/platform/mcu/stm32f4xx/hardfault_handler.c b/platform/mcu/stm32f4xx/hardfault_handler.c index 5329d4862a..240905bcb2 100644 --- a/platform/mcu/stm32f4xx/hardfault_handler.c +++ b/platform/mcu/stm32f4xx/hardfault_handler.c @@ -1,12 +1,3 @@ -/** - * UNPUBLISHED PROPRIETARY SOURCE CODE - * Copyright (c) 2016 MXCHIP Inc. - * - * The contents of this file may not be disclosed to third parties, copied or - * duplicated in any form, in whole or in part, without the prior written - * permission of MXCHIP Corporation. - * - */ #include #include "platform_cmsis.h" diff --git a/platform/mcu/stm32f4xx/include/platform_assert.h b/platform/mcu/stm32f4xx/include/platform_assert.h index 5c63a6cd11..c723202402 100644 --- a/platform/mcu/stm32f4xx/include/platform_assert.h +++ b/platform/mcu/stm32f4xx/include/platform_assert.h @@ -1,18 +1,3 @@ -/** - ****************************************************************************** - * @file platform_assert.h - * @author William Xu - * @version V1.0.0 - * @date 05-May-2014 - ****************************************************************************** - * UNPUBLISHED PROPRIETARY SOURCE CODE - * Copyright (c) 2016 MXCHIP Inc. - * - * The contents of this file may not be disclosed to third parties, copied or - * duplicated in any form, in whole or in part, without the prior written - * permission of MXCHIP Corporation. - ****************************************************************************** - */ #pragma once diff --git a/platform/mcu/stm32f4xx/include/platform_block_device.h b/platform/mcu/stm32f4xx/include/platform_block_device.h index ed714a7ed7..e88e9bcd7f 100644 --- a/platform/mcu/stm32f4xx/include/platform_block_device.h +++ b/platform/mcu/stm32f4xx/include/platform_block_device.h @@ -1,12 +1,3 @@ -/** - * UNPUBLISHED PROPRIETARY SOURCE CODE - * Copyright (c) 2016 MXCHIP Inc. - * - * The contents of this file may not be disclosed to third parties, copied or - * duplicated in any form, in whole or in part, without the prior written - * permission of MXCHIP Corporation. - * - */ /** @file * Block device driver declarations for MICO diff --git a/platform/mcu/stm32f4xx/include/platform_bluetooth.h b/platform/mcu/stm32f4xx/include/platform_bluetooth.h index 7dbf2a21c2..67301c4020 100644 --- a/platform/mcu/stm32f4xx/include/platform_bluetooth.h +++ b/platform/mcu/stm32f4xx/include/platform_bluetooth.h @@ -1,12 +1,3 @@ -/** - * UNPUBLISHED PROPRIETARY SOURCE CODE - * Copyright (c) 2016 MXCHIP Inc. - * - * The contents of this file may not be disclosed to third parties, copied or - * duplicated in any form, in whole or in part, without the prior written - * permission of MXCHIP Corporation. - * - */ #pragma once diff --git a/platform/mcu/stm32f4xx/include/platform_cmsis.h b/platform/mcu/stm32f4xx/include/platform_cmsis.h index fa53d3a990..03e71aff76 100644 --- a/platform/mcu/stm32f4xx/include/platform_cmsis.h +++ b/platform/mcu/stm32f4xx/include/platform_cmsis.h @@ -1,12 +1,3 @@ -/** - * UNPUBLISHED PROPRIETARY SOURCE CODE - * Copyright (c) 2016 MXCHIP Inc. - * - * The contents of this file may not be disclosed to third parties, copied or - * duplicated in any form, in whole or in part, without the prior written - * permission of MXCHIP Corporation. - * - */ /** @file * Includes CMSIS implementation for STM32F2xx MCU family diff --git a/platform/mcu/stm32f4xx/include/platform_core.h b/platform/mcu/stm32f4xx/include/platform_core.h index e52d700787..78f6d57908 100644 --- a/platform/mcu/stm32f4xx/include/platform_core.h +++ b/platform/mcu/stm32f4xx/include/platform_core.h @@ -1,13 +1,3 @@ -/** - * UNPUBLISHED PROPRIETARY SOURCE CODE - * Copyright (c) 2016 MXCHIP Inc. - * - * The contents of this file may not be disclosed to third parties, copied or - * duplicated in any form, in whole or in part, without the prior written - * permission of MXCHIP Corporation. - * - */ - #ifndef __PLATFORM_CORE_h__ #define __PLATFORM_CORE_h__ diff --git a/platform/mcu/stm32f4xx/include/platform_init.h b/platform/mcu/stm32f4xx/include/platform_init.h index 9092c5dda6..1744a9dab8 100644 --- a/platform/mcu/stm32f4xx/include/platform_init.h +++ b/platform/mcu/stm32f4xx/include/platform_init.h @@ -1,12 +1,3 @@ -/** - * UNPUBLISHED PROPRIETARY SOURCE CODE - * Copyright (c) 2016 MXCHIP Inc. - * - * The contents of this file may not be disclosed to third parties, copied or - * duplicated in any form, in whole or in part, without the prior written - * permission of MXCHIP Corporation. - * - */ #pragma once #include diff --git a/platform/mcu/stm32f4xx/include/platform_internal.h b/platform/mcu/stm32f4xx/include/platform_internal.h index 7b669ec49e..fe462cb61c 100644 --- a/platform/mcu/stm32f4xx/include/platform_internal.h +++ b/platform/mcu/stm32f4xx/include/platform_internal.h @@ -1,12 +1,3 @@ -/** - * UNPUBLISHED PROPRIETARY SOURCE CODE - * Copyright (c) 2016 MXCHIP Inc. - * - * The contents of this file may not be disclosed to third parties, copied or - * duplicated in any form, in whole or in part, without the prior written - * permission of MXCHIP Corporation. - * - */ #ifndef __PlatformInternal_h__ #define __PlatformInternal_h__ diff --git a/platform/mcu/stm32f4xx/include/platform_isr.h b/platform/mcu/stm32f4xx/include/platform_isr.h index 2d6302eea2..ef16d635e0 100644 --- a/platform/mcu/stm32f4xx/include/platform_isr.h +++ b/platform/mcu/stm32f4xx/include/platform_isr.h @@ -1,13 +1,3 @@ -/** - * UNPUBLISHED PROPRIETARY SOURCE CODE - * Copyright (c) 2016 MXCHIP Inc. - * - * The contents of this file may not be disclosed to third parties, copied or - * duplicated in any form, in whole or in part, without the prior written - * permission of MXCHIP Corporation. - * - */ - /** @file * Defines macros for defining and mapping interrupt handlers to the vector table of ARM-Cortex-M3 CPU diff --git a/platform/mcu/stm32f4xx/include/platform_logging.h b/platform/mcu/stm32f4xx/include/platform_logging.h index 71aeccb975..08797459a2 100644 --- a/platform/mcu/stm32f4xx/include/platform_logging.h +++ b/platform/mcu/stm32f4xx/include/platform_logging.h @@ -1,12 +1,3 @@ -/** - * UNPUBLISHED PROPRIETARY SOURCE CODE - * Copyright (c) 2016 MXCHIP Inc. - * - * The contents of this file may not be disclosed to third parties, copied or - * duplicated in any form, in whole or in part, without the prior written - * permission of MXCHIP Corporation. - * - */ #ifndef __PlatformLogging_h__ diff --git a/platform/mcu/stm32f4xx/include/platform_peripheral.h b/platform/mcu/stm32f4xx/include/platform_peripheral.h index 7c841f7fdc..041f476865 100644 --- a/platform/mcu/stm32f4xx/include/platform_peripheral.h +++ b/platform/mcu/stm32f4xx/include/platform_peripheral.h @@ -1,12 +1,3 @@ -/** - * UNPUBLISHED PROPRIETARY SOURCE CODE - * Copyright (c) 2016 MXCHIP Inc. - * - * The contents of this file may not be disclosed to third parties, copied or - * duplicated in any form, in whole or in part, without the prior written - * permission of MXCHIP Corporation. - * - */ /** @file diff --git a/platform/mcu/stm32f4xx/include/wlan_platform_common.h b/platform/mcu/stm32f4xx/include/wlan_platform_common.h index b4a76c847f..92cd1ad6fc 100644 --- a/platform/mcu/stm32f4xx/include/wlan_platform_common.h +++ b/platform/mcu/stm32f4xx/include/wlan_platform_common.h @@ -1,12 +1,3 @@ -/** - * UNPUBLISHED PROPRIETARY SOURCE CODE - * Copyright (c) 2016 MXCHIP Inc. - * - * The contents of this file may not be disclosed to third parties, copied or - * duplicated in any form, in whole or in part, without the prior written - * permission of MXCHIP Corporation. - * - */ /** @file * This file provide wlan IO pin define diff --git a/platform/mcu/stm32f4xx/peripherals/RingBufferUtils.c b/platform/mcu/stm32f4xx/peripherals/RingBufferUtils.c index 88666ea9e1..592af7a123 100644 --- a/platform/mcu/stm32f4xx/peripherals/RingBufferUtils.c +++ b/platform/mcu/stm32f4xx/peripherals/RingBufferUtils.c @@ -1,33 +1,3 @@ -/** - ****************************************************************************** - * @file RingBufferUtils.c - * @author William Xu - * @version V1.0.0 - * @date 05-May-2014 - * @brief This file contains function called by ring buffer operation - ****************************************************************************** - * - * The MIT License - * Copyright (c) 2014 MXCHIP Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR - * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ****************************************************************************** - */ #include "RingBufferUtils.h" #include "debug.h" @@ -143,4 +113,4 @@ uint8_t ring_buffer_is_full(ring_buffer_t *ring_buffer) return 1; else return 0; -} \ No newline at end of file +} diff --git a/platform/mcu/stm32f4xx/peripherals/RingBufferUtils.h b/platform/mcu/stm32f4xx/peripherals/RingBufferUtils.h index fbc7673a84..ac596a858a 100644 --- a/platform/mcu/stm32f4xx/peripherals/RingBufferUtils.h +++ b/platform/mcu/stm32f4xx/peripherals/RingBufferUtils.h @@ -1,34 +1,3 @@ -/** - ****************************************************************************** - * @file RingBufferUtils.h - * @author William Xu - * @version V1.0.0 - * @date 05-May-2014 - * @brief This header contains function prototypes called by ring buffer - * operation - ****************************************************************************** - * - * The MIT License - * Copyright (c) 2014 MXCHIP Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR - * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ****************************************************************************** - */ #ifndef __RingBufferUtils_h__ #define __RingBufferUtils_h__ diff --git a/platform/mcu/stm32f4xx/peripherals/libraries/libraries.mk b/platform/mcu/stm32f4xx/peripherals/libraries/libraries.mk index 2b6a096679..b44058f77b 100644 --- a/platform/mcu/stm32f4xx/peripherals/libraries/libraries.mk +++ b/platform/mcu/stm32f4xx/peripherals/libraries/libraries.mk @@ -1,12 +1,3 @@ -# -# UNPUBLISHED PROPRIETARY SOURCE CODE -# Copyright (c) 2016 MXCHIP Inc. -# -# The contents of this file may not be disclosed to third parties, copied or -# duplicated in any form, in whole or in part, without the prior written -# permission of MXCHIP Corporation. -# - NAME = STM32F4xx_Peripheral_Libraries GLOBAL_INCLUDES := . \ diff --git a/platform/mcu/stm32f4xx/peripherals/peripherals.mk b/platform/mcu/stm32f4xx/peripherals/peripherals.mk index 35d770b7e7..4767254051 100644 --- a/platform/mcu/stm32f4xx/peripherals/peripherals.mk +++ b/platform/mcu/stm32f4xx/peripherals/peripherals.mk @@ -1,12 +1,3 @@ -# -# UNPUBLISHED PROPRIETARY SOURCE CODE -# Copyright (c) 2016 MXCHIP Inc. -# -# The contents of this file may not be disclosed to third parties, copied or -# duplicated in any form, in whole or in part, without the prior written -# permission of MXCHIP Corporation. -# - NAME = STM32F4xx_Peripheral_Drivers GLOBAL_INCLUDES := . diff --git a/platform/mcu/stm32f4xx/peripherals/platform_adc.c b/platform/mcu/stm32f4xx/peripherals/platform_adc.c index ad8f55078c..6ab9950826 100644 --- a/platform/mcu/stm32f4xx/peripherals/platform_adc.c +++ b/platform/mcu/stm32f4xx/peripherals/platform_adc.c @@ -1,19 +1,3 @@ -/** - ****************************************************************************** - * @file platform_adc.c - * @author William Xu - * @version V1.0.0 - * @date 05-May-2014 - * @brief This file provide ADC driver functions. - ****************************************************************************** - * UNPUBLISHED PROPRIETARY SOURCE CODE - * Copyright (c) 2016 MXCHIP Inc. - * - * The contents of this file may not be disclosed to third parties, copied or - * duplicated in any form, in whole or in part, without the prior written - * permission of MXCHIP Corporation. - ****************************************************************************** - */ #include "platform.h" #include "platform_peripheral.h" diff --git a/platform/mcu/stm32f4xx/peripherals/platform_flash.c b/platform/mcu/stm32f4xx/peripherals/platform_flash.c index 8c1ae4241c..39ae47cf2d 100644 --- a/platform/mcu/stm32f4xx/peripherals/platform_flash.c +++ b/platform/mcu/stm32f4xx/peripherals/platform_flash.c @@ -1,19 +1,3 @@ -/** - ****************************************************************************** - * @file platform_flash.c - * @author William Xu - * @version V1.0.0 - * @date 05-May-2014 - * @brief This file provides flash operation functions. - ****************************************************************************** - * UNPUBLISHED PROPRIETARY SOURCE CODE - * Copyright (c) 2016 MXCHIP Inc. - * - * The contents of this file may not be disclosed to third parties, copied or - * duplicated in any form, in whole or in part, without the prior written - * permission of MXCHIP Corporation. - ****************************************************************************** - */ /* Includes ------------------------------------------------------------------*/ #include "platform_logging.h" diff --git a/platform/mcu/stm32f4xx/peripherals/platform_gpio.c b/platform/mcu/stm32f4xx/peripherals/platform_gpio.c index 8d8e59300b..6f7679af73 100644 --- a/platform/mcu/stm32f4xx/peripherals/platform_gpio.c +++ b/platform/mcu/stm32f4xx/peripherals/platform_gpio.c @@ -1,19 +1,3 @@ -/** - ****************************************************************************** - * @file platform_gpio.c - * @author William Xu - * @version V1.0.0 - * @date 05-May-2014 - * @brief This file provide GPIO driver functions. - ****************************************************************************** - * UNPUBLISHED PROPRIETARY SOURCE CODE - * Copyright (c) 2016 MXCHIP Inc. - * - * The contents of this file may not be disclosed to third parties, copied or - * duplicated in any form, in whole or in part, without the prior written - * permission of MXCHIP Corporation. - ****************************************************************************** - */ #include "platform.h" #include "platform_peripheral.h" diff --git a/platform/mcu/stm32f4xx/peripherals/platform_i2c.c b/platform/mcu/stm32f4xx/peripherals/platform_i2c.c index 124cab22da..efd7beaf52 100644 --- a/platform/mcu/stm32f4xx/peripherals/platform_i2c.c +++ b/platform/mcu/stm32f4xx/peripherals/platform_i2c.c @@ -1,19 +1,3 @@ -/** - ****************************************************************************** - * @file platform_i2c.c - * @author William Xu - * @version V1.0.0 - * @date 05-May-2014 - * @brief This file provide I2C driver functions. - ****************************************************************************** - * UNPUBLISHED PROPRIETARY SOURCE CODE - * Copyright (c) 2016 MXCHIP Inc. - * - * The contents of this file may not be disclosed to third parties, copied or - * duplicated in any form, in whole or in part, without the prior written - * permission of MXCHIP Corporation. - ****************************************************************************** - */ #include "platform.h" #include "platform_peripheral.h" diff --git a/platform/mcu/stm32f4xx/peripherals/platform_mcu_peripheral.h b/platform/mcu/stm32f4xx/peripherals/platform_mcu_peripheral.h index 5b9344e8eb..e19d2c8d6f 100644 --- a/platform/mcu/stm32f4xx/peripherals/platform_mcu_peripheral.h +++ b/platform/mcu/stm32f4xx/peripherals/platform_mcu_peripheral.h @@ -1,19 +1,3 @@ -/** - ****************************************************************************** - * @file platform_mcu_peripheral.h - * @author William Xu - * @version V1.0.0 - * @date 05-May-2014 - * @brief This file provide all the headers of functions for stm32f2xx platform - ****************************************************************************** - * UNPUBLISHED PROPRIETARY SOURCE CODE - * Copyright (c) 2016 MXCHIP Inc. - * - * The contents of this file may not be disclosed to third parties, copied or - * duplicated in any form, in whole or in part, without the prior written - * permission of MXCHIP Corporation. - ****************************************************************************** - */ #pragma once diff --git a/platform/mcu/stm32f4xx/peripherals/platform_mcu_powersave.c b/platform/mcu/stm32f4xx/peripherals/platform_mcu_powersave.c index fde0b1f89a..8316105f0c 100644 --- a/platform/mcu/stm32f4xx/peripherals/platform_mcu_powersave.c +++ b/platform/mcu/stm32f4xx/peripherals/platform_mcu_powersave.c @@ -1,21 +1,3 @@ -/** - ****************************************************************************** - * @file platform_mcu_powersave.c - * @author William Xu - * @version V1.0.0 - * @date 05-May-2014 - * @brief This file provide functions called by MICO to drive stm32f2xx - * platform: - e.g. power save, reboot, platform initialize - ****************************************************************************** - * UNPUBLISHED PROPRIETARY SOURCE CODE - * Copyright (c) 2016 MXCHIP Inc. - * - * The contents of this file may not be disclosed to third parties, copied or - * duplicated in any form, in whole or in part, without the prior written - * permission of MXCHIP Corporation. - ****************************************************************************** - */ - #include "platform_peripheral.h" #include "platform.h" diff --git a/platform/mcu/stm32f4xx/peripherals/platform_pwm.c b/platform/mcu/stm32f4xx/peripherals/platform_pwm.c index a0df12f82d..204e3b6c0f 100644 --- a/platform/mcu/stm32f4xx/peripherals/platform_pwm.c +++ b/platform/mcu/stm32f4xx/peripherals/platform_pwm.c @@ -1,19 +1,3 @@ -/** - ****************************************************************************** - * @file platform_pwm.c - * @author William Xu - * @version V1.0.0 - * @date 05-May-2014 - * @brief This file provide PWM driver functions. - ****************************************************************************** - * UNPUBLISHED PROPRIETARY SOURCE CODE - * Copyright (c) 2016 MXCHIP Inc. - * - * The contents of this file may not be disclosed to third parties, copied or - * duplicated in any form, in whole or in part, without the prior written - * permission of MXCHIP Corporation. - ****************************************************************************** - */ #include "platform.h" #include "platform_peripheral.h" diff --git a/platform/mcu/stm32f4xx/peripherals/platform_rng.c b/platform/mcu/stm32f4xx/peripherals/platform_rng.c index d8915758a0..928f172abd 100644 --- a/platform/mcu/stm32f4xx/peripherals/platform_rng.c +++ b/platform/mcu/stm32f4xx/peripherals/platform_rng.c @@ -1,19 +1,3 @@ -/** - ****************************************************************************** - * @file platform_rng.c - * @author William Xu - * @version V1.0.0 - * @date 05-May-2014 - * @brief This file provide RNG driver functions. - ****************************************************************************** - * UNPUBLISHED PROPRIETARY SOURCE CODE - * Copyright (c) 2016 MXCHIP Inc. - * - * The contents of this file may not be disclosed to third parties, copied or - * duplicated in any form, in whole or in part, without the prior written - * permission of MXCHIP Corporation. - ****************************************************************************** - */ #include "platform_peripheral.h" #include "platform.h" diff --git a/platform/mcu/stm32f4xx/peripherals/platform_rtc.c b/platform/mcu/stm32f4xx/peripherals/platform_rtc.c index b604bb7afe..fafcf280ab 100644 --- a/platform/mcu/stm32f4xx/peripherals/platform_rtc.c +++ b/platform/mcu/stm32f4xx/peripherals/platform_rtc.c @@ -1,19 +1,3 @@ -/** - ****************************************************************************** - * @file platform_rtc.c - * @author William Xu - * @version V1.0.0 - * @date 05-May-2014 - * @brief This file provide RTC driver functions. - ****************************************************************************** - * UNPUBLISHED PROPRIETARY SOURCE CODE - * Copyright (c) 2016 MXCHIP Inc. - * - * The contents of this file may not be disclosed to third parties, copied or - * duplicated in any form, in whole or in part, without the prior written - * permission of MXCHIP Corporation. - ****************************************************************************** - */ #include "platform.h" diff --git a/platform/mcu/stm32f4xx/peripherals/platform_spi.c b/platform/mcu/stm32f4xx/peripherals/platform_spi.c index 2e23e47122..377d9f3696 100644 --- a/platform/mcu/stm32f4xx/peripherals/platform_spi.c +++ b/platform/mcu/stm32f4xx/peripherals/platform_spi.c @@ -1,19 +1,3 @@ -/** - ****************************************************************************** - * @file platform_spi.c - * @author William Xu - * @version V1.0.0 - * @date 05-May-2014 - * @brief This file provide SPI driver functions. - ****************************************************************************** - * UNPUBLISHED PROPRIETARY SOURCE CODE - * Copyright (c) 2016 MXCHIP Inc. - * - * The contents of this file may not be disclosed to third parties, copied or - * duplicated in any form, in whole or in part, without the prior written - * permission of MXCHIP Corporation. - ****************************************************************************** - */ #include "platform.h" #include "platform_config.h" diff --git a/platform/mcu/stm32f4xx/peripherals/platform_uart.c b/platform/mcu/stm32f4xx/peripherals/platform_uart.c index 05454a0684..2f8d704855 100644 --- a/platform/mcu/stm32f4xx/peripherals/platform_uart.c +++ b/platform/mcu/stm32f4xx/peripherals/platform_uart.c @@ -1,19 +1,3 @@ -/** - ****************************************************************************** - * @file platform_uart.c - * @author William Xu - * @version V1.0.0 - * @date 05-May-2014 - * @brief This file provide UART driver functions. - ****************************************************************************** - * UNPUBLISHED PROPRIETARY SOURCE CODE - * Copyright (c) 2016 MXCHIP Inc. - * - * The contents of this file may not be disclosed to third parties, copied or - * duplicated in any form, in whole or in part, without the prior written - * permission of MXCHIP Corporation. - ****************************************************************************** - */ #include "platform.h" #include "platform_peripheral.h" diff --git a/platform/mcu/stm32f4xx/peripherals/platform_watchdog.c b/platform/mcu/stm32f4xx/peripherals/platform_watchdog.c index cbc45a493b..a89b1445f2 100644 --- a/platform/mcu/stm32f4xx/peripherals/platform_watchdog.c +++ b/platform/mcu/stm32f4xx/peripherals/platform_watchdog.c @@ -1,19 +1,3 @@ -/** - ****************************************************************************** - * @file platform_watchdog.c - * @author William Xu - * @version V1.0.0 - * @date 05-May-2014 - * @brief This file provide WDG driver functions. - ****************************************************************************** - * UNPUBLISHED PROPRIETARY SOURCE CODE - * Copyright (c) 2016 MXCHIP Inc. - * - * The contents of this file may not be disclosed to third parties, copied or - * duplicated in any form, in whole or in part, without the prior written - * permission of MXCHIP Corporation. - ****************************************************************************** - */ #include "platform.h" #include "platform_config.h" diff --git a/platform/mcu/stm32f4xx/platform_cmsis.h b/platform/mcu/stm32f4xx/platform_cmsis.h index fa53d3a990..03e71aff76 100644 --- a/platform/mcu/stm32f4xx/platform_cmsis.h +++ b/platform/mcu/stm32f4xx/platform_cmsis.h @@ -1,12 +1,3 @@ -/** - * UNPUBLISHED PROPRIETARY SOURCE CODE - * Copyright (c) 2016 MXCHIP Inc. - * - * The contents of this file may not be disclosed to third parties, copied or - * duplicated in any form, in whole or in part, without the prior written - * permission of MXCHIP Corporation. - * - */ /** @file * Includes CMSIS implementation for STM32F2xx MCU family diff --git a/platform/mcu/stm32f4xx/platform_init.c b/platform/mcu/stm32f4xx/platform_init.c index 97a818b9da..dde597e811 100644 --- a/platform/mcu/stm32f4xx/platform_init.c +++ b/platform/mcu/stm32f4xx/platform_init.c @@ -1,21 +1,3 @@ -/** - ****************************************************************************** - * @file platform_init.c - * @author William Xu - * @version V1.0.0 - * @date 05-May-2014 - * @brief This file provide functions called by MICO to drive stm32f2xx - * platform: - e.g. power save, reboot, platform initialize - ****************************************************************************** - * UNPUBLISHED PROPRIETARY SOURCE CODE - * Copyright (c) 2016 MXCHIP Inc. - * - * The contents of this file may not be disclosed to third parties, copied or - * duplicated in any form, in whole or in part, without the prior written - * permission of MXCHIP Corporation. - ****************************************************************************** - */ - #include "platform_peripheral.h" #include "platform.h" diff --git a/platform/mcu/stm32f4xx/platform_vector_table.c b/platform/mcu/stm32f4xx/platform_vector_table.c index 93a35d6411..d5e394542f 100644 --- a/platform/mcu/stm32f4xx/platform_vector_table.c +++ b/platform/mcu/stm32f4xx/platform_vector_table.c @@ -1,12 +1,3 @@ -/** - * UNPUBLISHED PROPRIETARY SOURCE CODE - * Copyright (c) 2016 MXCHIP Inc. - * - * The contents of this file may not be disclosed to third parties, copied or - * duplicated in any form, in whole or in part, without the prior written - * permission of MXCHIP Corporation. - * - */ /** @file * STM32F4xx vector table */ diff --git a/platform/mcu/stm32f4xx/spi_flash/spi_flash.c b/platform/mcu/stm32f4xx/spi_flash/spi_flash.c index ca645bab43..17b8863ee0 100644 --- a/platform/mcu/stm32f4xx/spi_flash/spi_flash.c +++ b/platform/mcu/stm32f4xx/spi_flash/spi_flash.c @@ -1,19 +1,3 @@ -/** - ****************************************************************************** - * @file spi_flash.c - * @author William Xu - * @version V1.0.0 - * @date 16-Sep-2014 - * @brief This file provides all the headers of flash operation functions. - ****************************************************************************** - * UNPUBLISHED PROPRIETARY SOURCE CODE - * Copyright (c) 2016 MXCHIP Inc. - * - * The contents of this file may not be disclosed to third parties, copied or - * duplicated in any form, in whole or in part, without the prior written - * permission of MXCHIP Corporation. - ****************************************************************************** - */ #include "platform_logging.h" #include "platform.h" diff --git a/platform/mcu/stm32f4xx/spi_flash/spi_flash.h b/platform/mcu/stm32f4xx/spi_flash/spi_flash.h index c9eb326dc0..73902eac41 100644 --- a/platform/mcu/stm32f4xx/spi_flash/spi_flash.h +++ b/platform/mcu/stm32f4xx/spi_flash/spi_flash.h @@ -1,19 +1,3 @@ -/** - ****************************************************************************** - * @file spi_flash.h - * @author William Xu - * @version V1.0.0 - * @date 16-Sep-2014 - * @brief This file provides all the headers of flash operation functions. - ****************************************************************************** - * UNPUBLISHED PROPRIETARY SOURCE CODE - * Copyright (c) 2016 MXCHIP Inc. - * - * The contents of this file may not be disclosed to third parties, copied or - * duplicated in any form, in whole or in part, without the prior written - * permission of MXCHIP Corporation. - ****************************************************************************** - */ #ifndef INCLUDED_SPI_FLASH_API_H #define INCLUDED_SPI_FLASH_API_H diff --git a/platform/mcu/stm32f4xx/spi_flash/spi_flash.mk b/platform/mcu/stm32f4xx/spi_flash/spi_flash.mk index 0c3848c541..76a1072d95 100644 --- a/platform/mcu/stm32f4xx/spi_flash/spi_flash.mk +++ b/platform/mcu/stm32f4xx/spi_flash/spi_flash.mk @@ -1,18 +1,9 @@ -# -# UNPUBLISHED PROPRIETARY SOURCE CODE -# Copyright (c) 2016 MXCHIP Inc. -# -# The contents of this file may not be disclosed to third parties, copied or -# duplicated in any form, in whole or in part, without the prior written -# permission of MXCHIP Corporation. -# - -NAME := Lib_SPI_Flash_Library_$(PLATFORM) +NAME := Lib_SPI_Flash_Library $(NAME)_SOURCES := spi_flash.c spi_flash_platform.c GLOBAL_INCLUDES := . #(info $(COMPILER_SPECIFIC_PEDANTIC_CFLAGS)) -# $(NAME)_CFLAGS = $(COMPILER_SPECIFIC_PEDANTIC_CFLAGS) \ No newline at end of file +# $(NAME)_CFLAGS = $(COMPILER_SPECIFIC_PEDANTIC_CFLAGS) diff --git a/platform/mcu/stm32f4xx/spi_flash/spi_flash_internal.h b/platform/mcu/stm32f4xx/spi_flash/spi_flash_internal.h index 13a41108cc..a0c5b3b068 100644 --- a/platform/mcu/stm32f4xx/spi_flash/spi_flash_internal.h +++ b/platform/mcu/stm32f4xx/spi_flash/spi_flash_internal.h @@ -1,20 +1,3 @@ -/** - ****************************************************************************** - * @file spi_flash_internal.c - * @author William Xu - * @version V1.0.0 - * @date 16-Sep-2014 - * @brief This file provides all the headers of flash operation functions. - ****************************************************************************** - * - * UNPUBLISHED PROPRIETARY SOURCE CODE - * Copyright (c) 2016 MXCHIP Inc. - * - * The contents of this file may not be disclosed to third parties, copied or - * duplicated in any form, in whole or in part, without the prior written - * permission of MXCHIP Corporation. - ****************************************************************************** - */ #ifndef INCLUDED_SPI_FLASH_INTERNAL_H #define INCLUDED_SPI_FLASH_INTERNAL_H diff --git a/platform/mcu/stm32f4xx/spi_flash/spi_flash_platform.c b/platform/mcu/stm32f4xx/spi_flash/spi_flash_platform.c index 1ee621201e..b27910c25a 100644 --- a/platform/mcu/stm32f4xx/spi_flash/spi_flash_platform.c +++ b/platform/mcu/stm32f4xx/spi_flash/spi_flash_platform.c @@ -1,19 +1,3 @@ -/** - ****************************************************************************** - * @file spi_flash_platform.c - * @author William Xu - * @version V1.0.0 - * @date 16-Sep-2014 - * @brief This file provides all the headers of flash operation functions. - ****************************************************************************** - * UNPUBLISHED PROPRIETARY SOURCE CODE - * Copyright (c) 2016 MXCHIP Inc. - * - * The contents of this file may not be disclosed to third parties, copied or - * duplicated in any form, in whole or in part, without the prior written - * permission of MXCHIP Corporation. - ****************************************************************************** - */ #include "spi_flash_platform_interface.h" #include "mico_platform.h" diff --git a/platform/mcu/stm32f4xx/spi_flash/spi_flash_platform_interface.h b/platform/mcu/stm32f4xx/spi_flash/spi_flash_platform_interface.h index 354bdcced7..83c50778a3 100644 --- a/platform/mcu/stm32f4xx/spi_flash/spi_flash_platform_interface.h +++ b/platform/mcu/stm32f4xx/spi_flash/spi_flash_platform_interface.h @@ -1,20 +1,3 @@ -/** - ****************************************************************************** - * @file spi_flash_platform_interface.h - * @author William Xu - * @version V1.0.0 - * @date 05-May-2014 - * @brief This file provide all the headers of platform functions for spi - * flash driver - ****************************************************************************** - * UNPUBLISHED PROPRIETARY SOURCE CODE - * Copyright (c) 2016 MXCHIP Inc. - * - * The contents of this file may not be disclosed to third parties, copied or - * duplicated in any form, in whole or in part, without the prior written - * permission of MXCHIP Corporation. - ****************************************************************************** - */ #ifndef INCLUDED_SPI_FLASH_PLATFORM_INTERFACE_H #define INCLUDED_SPI_FLASH_PLATFORM_INTERFACE_H diff --git a/platform/mcu/stm32f4xx/stm32f4xx.mk b/platform/mcu/stm32f4xx/stm32f4xx.mk index 49ff8813e5..51b3277355 100644 --- a/platform/mcu/stm32f4xx/stm32f4xx.mk +++ b/platform/mcu/stm32f4xx/stm32f4xx.mk @@ -1,12 +1,3 @@ -# -# UNPUBLISHED PROPRIETARY SOURCE CODE -# Copyright (c) 2016 MXCHIP Inc. -# -# The contents of this file may not be disclosed to third parties, copied or -# duplicated in any form, in whole or in part, without the prior written -# permission of MXCHIP Corporation. -# - NAME = stm32f4xx # Host architecture is ARM Cortex M4 @@ -72,6 +63,22 @@ GLOBAL_CFLAGS += -mcpu=cortex-m4 \ GLOBAL_CFLAGS += -w + +ifeq ($(COMPILER),armcc) +GLOBAL_ASMFLAGS += --cpu=7E-M -g --apcs=interwork --pd "__MICROLIB SETA 1" --pd "STM32F4xx SETA 1" +else ifeq ($(COMPILER),iar) +GLOBAL_ASMFLAGS += --cpu Cortex-M4 \ + --cpu_mode thumb \ + --endian little +else +GLOBAL_ASMFLAGS += -mcpu=cortex-m4 \ + -march=armv7-m \ + -mlittle-endian \ + -mthumb -mthumb-interwork \ + -w +endif + + GLOBAL_LDFLAGS += -mcpu=cortex-m4 \ -mthumb -mthumb-interwork \ -mlittle-endian \ @@ -94,6 +101,7 @@ $(NAME)_SOURCES := platform_init.c \ aos/soc_impl.c \ aos/trace_impl.c \ aos/aos.c \ + hal/i2c.c \ hal/hw.c hal/uart.c hal/flash.c diff --git a/platform/mcu/stm32f4xx/wifi/mico_wlan.h b/platform/mcu/stm32f4xx/wifi/mico_wlan.h index 83ae36ebf1..1aa1ca4273 100644 --- a/platform/mcu/stm32f4xx/wifi/mico_wlan.h +++ b/platform/mcu/stm32f4xx/wifi/mico_wlan.h @@ -1,33 +1,3 @@ -/** - ****************************************************************************** - * @file mico_wlan.h - * @author William Xu - * @version V1.0.0 - * @date 16-Sep-2014 - * @brief This file provides all the headers of wlan connectivity functions. - ****************************************************************************** - * - * The MIT License - * Copyright (c) 2014 MXCHIP Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is furnished - * to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR - * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - ****************************************************************************** - */ #ifndef __MICOWLAN_H__ #define __MICOWLAN_H__ diff --git a/platform/mcu/stm32f4xx/wlan_bus_driver/wlan_bus_SDIO.c b/platform/mcu/stm32f4xx/wlan_bus_driver/wlan_bus_SDIO.c index 6f29573626..3b7d584331 100644 --- a/platform/mcu/stm32f4xx/wlan_bus_driver/wlan_bus_SDIO.c +++ b/platform/mcu/stm32f4xx/wlan_bus_driver/wlan_bus_SDIO.c @@ -1,19 +1,3 @@ -/** - ****************************************************************************** - * @file wlan_bus_sdio.h - * @author William Xu - * @version V1.0.0 - * @date 16-Sep-2014 - * @brief This file provides SDIO bus communication functions with Wi-Fi RF chip. - ****************************************************************************** - * UNPUBLISHED PROPRIETARY SOURCE CODE - * Copyright (c) 2016 MXCHIP Inc. - * - * The contents of this file may not be disclosed to third parties, copied or - * duplicated in any form, in whole or in part, without the prior written - * permission of MXCHIP Corporation. - ****************************************************************************** - */ #include "misc.h" #include "string.h" /* For memcpy */ diff --git a/platform/mcu/stm32f4xx/wlan_bus_driver/wlan_bus_SPI.c b/platform/mcu/stm32f4xx/wlan_bus_driver/wlan_bus_SPI.c index 80010151b2..ca72ed2daf 100644 --- a/platform/mcu/stm32f4xx/wlan_bus_driver/wlan_bus_SPI.c +++ b/platform/mcu/stm32f4xx/wlan_bus_driver/wlan_bus_SPI.c @@ -1,19 +1,3 @@ -/** - ****************************************************************************** - * @file wlan_bus_spi.h - * @author William Xu - * @version V1.0.0 - * @date 16-Sep-2014 - * @brief This file provides api bus communication functions with Wi-Fi RF chip. - ****************************************************************************** - * UNPUBLISHED PROPRIETARY SOURCE CODE - * Copyright (c) 2016 MXCHIP Inc. - * - * The contents of this file may not be disclosed to third parties, copied or - * duplicated in any form, in whole or in part, without the prior written - * permission of MXCHIP Corporation. - ****************************************************************************** - */ #include "mico.h" #include "misc.h" diff --git a/platform/mcu/stm32f4xx/wlan_bus_driver/wlan_platform.c b/platform/mcu/stm32f4xx/wlan_bus_driver/wlan_platform.c index de1ee634df..6a332975a2 100644 --- a/platform/mcu/stm32f4xx/wlan_bus_driver/wlan_platform.c +++ b/platform/mcu/stm32f4xx/wlan_bus_driver/wlan_platform.c @@ -1,19 +1,3 @@ -/** - ****************************************************************************** - * @file wlan_platform.c - * @author William Xu - * @version V1.0.0 - * @date 05-May-2014 - * @brief This file provide functions called by MICO to wlan RF module - ****************************************************************************** - * UNPUBLISHED PROPRIETARY SOURCE CODE - * Copyright (c) 2016 MXCHIP Inc. - * - * The contents of this file may not be disclosed to third parties, copied or - * duplicated in any form, in whole or in part, without the prior written - * permission of MXCHIP Corporation. - ****************************************************************************** - */ #include "platform_config.h" #include "platform_peripheral.h" diff --git a/platform/mcu/stm32f4xx/wlan_bus_driver/wlan_platform_common.c b/platform/mcu/stm32f4xx/wlan_bus_driver/wlan_platform_common.c index ad6e30371b..0b26567726 100644 --- a/platform/mcu/stm32f4xx/wlan_bus_driver/wlan_platform_common.c +++ b/platform/mcu/stm32f4xx/wlan_bus_driver/wlan_platform_common.c @@ -1,19 +1,3 @@ -/** - ****************************************************************************** - * @file wlan_platform_common.c - * @author William Xu - * @version V1.0.0 - * @date 05-May-2014 - * @brief This file provide functions called by MICO to wlan RF module - ****************************************************************************** - * UNPUBLISHED PROPRIETARY SOURCE CODE - * Copyright (c) 2016 MXCHIP Inc. - * - * The contents of this file may not be disclosed to third parties, copied or - * duplicated in any form, in whole or in part, without the prior written - * permission of MXCHIP Corporation. - ****************************************************************************** - */ #include #include "platform.h" diff --git a/platform/mcu/stm32l0xx/src/STM32L073RZ-Nucleo/aos_rhino/soc_init.c b/platform/mcu/stm32l0xx/src/STM32L073RZ-Nucleo/aos_rhino/soc_init.c index 6685400592..c615dd0bf9 100644 --- a/platform/mcu/stm32l0xx/src/STM32L073RZ-Nucleo/aos_rhino/soc_init.c +++ b/platform/mcu/stm32l0xx/src/STM32L073RZ-Nucleo/aos_rhino/soc_init.c @@ -38,7 +38,7 @@ /* Includes ------------------------------------------------------------------*/ #include "soc_init.h" -#include "k_config.h" +#include "k_api.h" #include "stm32l0xx_hal.h" #if defined (__CC_ARM) && defined(__MICROLIB) diff --git a/platform/mcu/stm32l0xx/src/STM32L073RZ-Nucleo/hal/i2c.c b/platform/mcu/stm32l0xx/src/STM32L073RZ-Nucleo/hal/i2c.c new file mode 100644 index 0000000000..fb56d56765 --- /dev/null +++ b/platform/mcu/stm32l0xx/src/STM32L073RZ-Nucleo/hal/i2c.c @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#include +#include + +int32_t hal_i2c_init(i2c_dev_t *i2c) +{ + int32_t ret = 0; + + return ret; +} + +int32_t hal_i2c_master_send(i2c_dev_t *i2c, uint16_t dev_addr, const uint8_t *data, + uint16_t size, uint32_t timeout) +{ + int32_t ret = 0; + + return ret; +} + +int32_t hal_i2c_master_recv(i2c_dev_t *i2c, uint16_t dev_addr, uint8_t *data, + uint16_t size, uint32_t timeout) +{ + int32_t ret = 0; + + return ret; +} + +int32_t hal_i2c_slave_send(i2c_dev_t *i2c, const uint8_t *data, uint16_t size, uint32_t timeout) +{ + int32_t ret = 0; + + return ret; +} + +int32_t hal_i2c_slave_recv(i2c_dev_t *i2c, uint8_t *data, uint16_t size, uint32_t timeout) +{ + int32_t ret = 0; + + return ret; +} + +int32_t hal_i2c_mem_write(i2c_dev_t *i2c, uint16_t dev_addr, uint16_t mem_addr, + uint16_t mem_addr_size, const uint8_t *data, uint16_t size, + uint32_t timeout) +{ + int32_t ret = 0; + + return ret; +}; + +int32_t hal_i2c_mem_read(i2c_dev_t *i2c, uint16_t dev_addr, uint16_t mem_addr, + uint16_t mem_addr_size, uint8_t *data, uint16_t size, + uint32_t timeout) +{ + int32_t ret = 0; + + return ret; +}; + +int32_t hal_i2c_finalize(i2c_dev_t *i2c) +{ + int32_t ret = 0; + + return ret; +} diff --git a/platform/mcu/stm32l0xx/src/STM32L073RZ-Nucleo/helloworld/soc_init.c b/platform/mcu/stm32l0xx/src/STM32L073RZ-Nucleo/helloworld/soc_init.c index ef76199f18..897d60ddcf 100644 --- a/platform/mcu/stm32l0xx/src/STM32L073RZ-Nucleo/helloworld/soc_init.c +++ b/platform/mcu/stm32l0xx/src/STM32L073RZ-Nucleo/helloworld/soc_init.c @@ -38,7 +38,7 @@ /* Includes ------------------------------------------------------------------*/ #include "soc_init.h" -#include "k_config.h" +#include "k_api.h" #include "stm32l0xx_hal.h" #if defined (__CC_ARM) && defined(__MICROLIB) diff --git a/platform/mcu/stm32l475/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart.h b/platform/mcu/stm32l475/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart.h index a50c0eb7d0..d5c39858e7 100644 --- a/platform/mcu/stm32l475/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart.h +++ b/platform/mcu/stm32l475/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart.h @@ -45,6 +45,7 @@ /* Includes ------------------------------------------------------------------*/ #include "stm32l4xx_hal_def.h" +#include /** @addtogroup STM32L4xx_HAL_Driver * @{ @@ -268,6 +269,8 @@ typedef struct This parameter can be a value of @ref HAL_UART_StateTypeDef */ __IO uint32_t ErrorCode; /*!< UART Error code */ + + kbuf_queue_t* buffer_queue; /*!< buffer queue */ }UART_HandleTypeDef; @@ -1345,6 +1348,7 @@ HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, u HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout); HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_UART_Receive_IT_Buf_Queue_1byte(UART_HandleTypeDef *huart, uint8_t *pData, uint32_t timeout); HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart); @@ -1359,6 +1363,7 @@ HAL_StatusTypeDef HAL_UART_AbortTransmit_IT(UART_HandleTypeDef *huart); HAL_StatusTypeDef HAL_UART_AbortReceive_IT(UART_HandleTypeDef *huart); void HAL_UART_IRQHandler(UART_HandleTypeDef *huart); +void HAL_UART_IRQHandler_Buf_Queue(UART_HandleTypeDef *huart); void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart); void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart); void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart); diff --git a/platform/mcu/stm32l475/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.c b/platform/mcu/stm32l475/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.c index 103dbb41d4..6f80a3dadd 100644 --- a/platform/mcu/stm32l475/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.c +++ b/platform/mcu/stm32l475/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.c @@ -148,6 +148,7 @@ static void UART_DMARxOnlyAbortCallback(DMA_HandleTypeDef *hdma); static HAL_StatusTypeDef UART_Transmit_IT(UART_HandleTypeDef *huart); static HAL_StatusTypeDef UART_EndTransmit_IT(UART_HandleTypeDef *huart); static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart); +static HAL_StatusTypeDef UART_Receive_IT_Buf_Queue(UART_HandleTypeDef *huart); /** * @} */ @@ -834,44 +835,103 @@ HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData * @param Size: amount of data to be received. * @retval HAL status */ -HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) +#define MSEC_TO_TICK(msec) \ + ((uint32_t)(msec) * (uint32_t)RHINO_CONFIG_TICKS_PER_SECOND / 1000uL) + +HAL_StatusTypeDef HAL_UART_Receive_IT_Buf_Queue_1byte(UART_HandleTypeDef *huart, uint8_t *pData, uint32_t timeout) { - /* Check that a Rx process is not already ongoing */ - if(huart->RxState == HAL_UART_STATE_READY) - { - if((pData == NULL ) || (Size == 0)) + int ret = 0; + size_t rev_size = 0; + + /* Check that a Rx process is not already ongoing */ + if(huart->RxState == HAL_UART_STATE_READY) { - return HAL_ERROR; + if(pData == NULL) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(huart); + + huart->pRxBuffPtr = pData; + huart->RxXferSize = 1; + huart->RxXferCount = 0xFFFF; + + /* Computation of UART mask to apply to RDR register */ + UART_MASK_COMPUTATION(huart); + + huart->ErrorCode = HAL_UART_ERROR_NONE; + huart->RxState = HAL_UART_STATE_BUSY_RX; + + /* Process Unlocked */ + __HAL_UNLOCK(huart); + + /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */ + SET_BIT(huart->Instance->CR3, USART_CR3_EIE); + + /* Enable the UART Parity Error and Data Register not empty Interrupts */ + SET_BIT(huart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE); + } + + if (huart->buffer_queue != NULL) + { + ret = krhino_buf_queue_recv(huart->buffer_queue, 0xffffffff, pData, &rev_size); + if((ret == 0) && (rev_size == 1)) + { + ret = HAL_OK; + } + else + { + ret = HAL_BUSY; + } + } + else + { + ret = HAL_BUSY; } - /* Process Locked */ - __HAL_LOCK(huart); + return (HAL_StatusTypeDef)ret; +} - huart->pRxBuffPtr = pData; - huart->RxXferSize = Size; - huart->RxXferCount = Size; +HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size) +{ + /* Check that a Rx process is not already ongoing */ + if(huart->RxState == HAL_UART_STATE_READY) + { + if((pData == NULL ) || (Size == 0)) + { + return HAL_ERROR; + } - /* Computation of UART mask to apply to RDR register */ - UART_MASK_COMPUTATION(huart); + /* Process Locked */ + __HAL_LOCK(huart); - huart->ErrorCode = HAL_UART_ERROR_NONE; - huart->RxState = HAL_UART_STATE_BUSY_RX; + huart->pRxBuffPtr = pData; + huart->RxXferSize = Size; + huart->RxXferCount = Size; - /* Process Unlocked */ - __HAL_UNLOCK(huart); + /* Computation of UART mask to apply to RDR register */ + UART_MASK_COMPUTATION(huart); - /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */ - SET_BIT(huart->Instance->CR3, USART_CR3_EIE); + huart->ErrorCode = HAL_UART_ERROR_NONE; + huart->RxState = HAL_UART_STATE_BUSY_RX; - /* Enable the UART Parity Error and Data Register not empty Interrupts */ - SET_BIT(huart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE); + /* Process Unlocked */ + __HAL_UNLOCK(huart); - return HAL_OK; - } - else - { - return HAL_BUSY; - } + /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */ + SET_BIT(huart->Instance->CR3, USART_CR3_EIE); + + /* Enable the UART Parity Error and Data Register not empty Interrupts */ + SET_BIT(huart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE); + + return HAL_OK; + } + else + { + return HAL_BUSY; + } } /** @@ -1682,6 +1742,159 @@ void HAL_UART_IRQHandler(UART_HandleTypeDef *huart) } +/** + * @brief Handle UART interrupt request. + * @param huart: UART handle. + * @retval None + */ +void HAL_UART_IRQHandler_Buf_Queue(UART_HandleTypeDef *huart) +{ + uint32_t isrflags = READ_REG(huart->Instance->ISR); + uint32_t cr1its = READ_REG(huart->Instance->CR1); + uint32_t cr3its; + uint32_t errorflags; + + /* If no error occurs */ + errorflags = (isrflags & (uint32_t)(USART_ISR_PE | USART_ISR_FE | USART_ISR_ORE | USART_ISR_NE)); + if (errorflags == RESET) + { + /* UART in mode Receiver ---------------------------------------------------*/ + if(((isrflags & USART_ISR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET)) + { + UART_Receive_IT_Buf_Queue(huart); + return; + } + } + + /* If some errors occur */ + cr3its = READ_REG(huart->Instance->CR3); + if( (errorflags != RESET) + && ( ((cr3its & USART_CR3_EIE) != RESET) + || ((cr1its & (USART_CR1_RXNEIE | USART_CR1_PEIE)) != RESET)) ) + { + /* UART parity error interrupt occurred -------------------------------------*/ + if(((isrflags & USART_ISR_PE) != RESET) && ((cr1its & USART_CR1_PEIE) != RESET)) + { + __HAL_UART_CLEAR_IT(huart, UART_CLEAR_PEF); + + huart->ErrorCode |= HAL_UART_ERROR_PE; + } + + /* UART frame error interrupt occurred --------------------------------------*/ + if(((isrflags & USART_ISR_FE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET)) + { + __HAL_UART_CLEAR_IT(huart, UART_CLEAR_FEF); + + huart->ErrorCode |= HAL_UART_ERROR_FE; + } + + /* UART noise error interrupt occurred --------------------------------------*/ + if(((isrflags & USART_ISR_NE) != RESET) && ((cr3its & USART_CR3_EIE) != RESET)) + { + __HAL_UART_CLEAR_IT(huart, UART_CLEAR_NEF); + + huart->ErrorCode |= HAL_UART_ERROR_NE; + } + + /* UART Over-Run interrupt occurred -----------------------------------------*/ + if(((isrflags & USART_ISR_ORE) != RESET) && + (((cr1its & USART_CR1_RXNEIE) != RESET) || ((cr3its & USART_CR3_EIE) != RESET))) + { + __HAL_UART_CLEAR_IT(huart, UART_CLEAR_OREF); + + huart->ErrorCode |= HAL_UART_ERROR_ORE; + } + + /* Call UART Error Call back function if need be --------------------------*/ + if(huart->ErrorCode != HAL_UART_ERROR_NONE) + { + /* UART in mode Receiver ---------------------------------------------------*/ + if(((isrflags & USART_ISR_RXNE) != RESET) && ((cr1its & USART_CR1_RXNEIE) != RESET)) + { + UART_Receive_IT_Buf_Queue(huart); + } + + /* If Overrun error occurs, or if any error occurs in DMA mode reception, + consider error as blocking */ + if (((huart->ErrorCode & HAL_UART_ERROR_ORE) != RESET) || + (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR))) + { + /* Blocking error : transfer is aborted + Set the UART state ready to be able to start again the process, + Disable Rx Interrupts, and disable Rx DMA request, if ongoing */ + UART_EndRxTransfer(huart); + + /* Disable the UART DMA Rx request if enabled */ + if (HAL_IS_BIT_SET(huart->Instance->CR3, USART_CR3_DMAR)) + { + CLEAR_BIT(huart->Instance->CR3, USART_CR3_DMAR); + + /* Abort the UART DMA Rx channel */ + if(huart->hdmarx != NULL) + { + /* Set the UART DMA Abort callback : + will lead to call HAL_UART_ErrorCallback() at end of DMA abort procedure */ + huart->hdmarx->XferAbortCallback = UART_DMAAbortOnError; + + /* Abort DMA RX */ + if(HAL_DMA_Abort_IT(huart->hdmarx) != HAL_OK) + { + /* Call Directly huart->hdmarx->XferAbortCallback function in case of error */ + huart->hdmarx->XferAbortCallback(huart->hdmarx); + } + } + else + { + /* Call user error callback */ + HAL_UART_ErrorCallback(huart); + } + } + else + { + /* Call user error callback */ + HAL_UART_ErrorCallback(huart); + } + } + else + { + /* Non Blocking error : transfer could go on. + Error is notified to user through user error callback */ + HAL_UART_ErrorCallback(huart); + huart->ErrorCode = HAL_UART_ERROR_NONE; + } + } + return; + + } /* End if some error occurs */ + + /* UART wakeup from Stop mode interrupt occurred ---------------------------*/ + cr3its = READ_REG(huart->Instance->CR3); + if(((isrflags & USART_ISR_WUF) != RESET) && ((cr3its & USART_CR3_WUFIE) != RESET)) + { + __HAL_UART_CLEAR_IT(huart, UART_CLEAR_WUF); + /* Set the UART state ready to be able to start again the process */ + huart->gState = HAL_UART_STATE_READY; + huart->RxState = HAL_UART_STATE_READY; + HAL_UARTEx_WakeupCallback(huart); + return; + } + + /* UART in mode Transmitter ------------------------------------------------*/ + if(((isrflags & USART_ISR_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET)) + { + UART_Transmit_IT(huart); + return; + } + + /* UART in mode Transmitter (transmission end) -----------------------------*/ + if(((isrflags & USART_ISR_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET)) + { + UART_EndTransmit_IT(huart); + return; + } + +} + #if 0 /** * @brief Tx Transfer completed callback. @@ -2773,6 +2986,63 @@ static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart) } } + +static HAL_StatusTypeDef UART_Receive_IT_Buf_Queue(UART_HandleTypeDef *huart) +{ + uint16_t* tmp; + uint16_t uhMask = huart->Mask; + uint16_t uhdata; + uint8_t ucdata; + + /* Check that a Rx process is ongoing */ + if(huart->RxState == HAL_UART_STATE_BUSY_RX) + { + uhdata = (uint16_t) READ_REG(huart->Instance->RDR); + if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) + { + if (huart->buffer_queue != NULL){ + krhino_buf_queue_send(huart->buffer_queue, &uhdata, 2); + }else if (huart->pRxBuffPtr != NULL){ + tmp = (uint16_t*) huart->pRxBuffPtr ; + *tmp = (uint16_t)(uhdata & uhMask); + huart->pRxBuffPtr +=2; + } + }else{ + ucdata = (uint8_t)(uhdata & (uint8_t)uhMask); + if (huart->buffer_queue != NULL){ + krhino_buf_queue_send(huart->buffer_queue, &ucdata, 1); + }else if (huart->pRxBuffPtr != NULL){ + *huart->pRxBuffPtr++ = ucdata; + } + } + + if(--huart->RxXferCount == 0) + { + /* Disable the UART Parity Error Interrupt and RXNE interrupt*/ + CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE)); + + /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */ + CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); + + /* Rx process is completed, restore huart->RxState to Ready */ + huart->RxState = HAL_UART_STATE_READY; + + HAL_UART_RxCpltCallback(huart); + + return HAL_OK; + } + + return HAL_OK; + } + else + { + /* Clear RXNE interrupt flag */ + __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST); + + return HAL_BUSY; + } +} + /** * @} */ diff --git a/platform/mcu/stm32l475/Middlewares/USB_Device/Class/AUDIO/Inc/usbd_audio.h b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/AUDIO/Inc/usbd_audio.h new file mode 100644 index 0000000000..1a124caa20 --- /dev/null +++ b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/AUDIO/Inc/usbd_audio.h @@ -0,0 +1,230 @@ +/** + ****************************************************************************** + * @file usbd_audio.h + * @author MCD Application Team + * @version V2.4.2 + * @date 11-December-2015 + * @brief header file for the usbd_audio.c file. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USB_AUDIO_H +#define __USB_AUDIO_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_ioreq.h" + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USBD_AUDIO + * @brief This file is the Header file for usbd_audio.c + * @{ + */ + + +/** @defgroup USBD_AUDIO_Exported_Defines + * @{ + */ +#define AUDIO_OUT_EP 0x01 +#define USB_AUDIO_CONFIG_DESC_SIZ 109 +#define AUDIO_INTERFACE_DESC_SIZE 9 +#define USB_AUDIO_DESC_SIZ 0x09 +#define AUDIO_STANDARD_ENDPOINT_DESC_SIZE 0x09 +#define AUDIO_STREAMING_ENDPOINT_DESC_SIZE 0x07 + +#define AUDIO_DESCRIPTOR_TYPE 0x21 +#define USB_DEVICE_CLASS_AUDIO 0x01 +#define AUDIO_SUBCLASS_AUDIOCONTROL 0x01 +#define AUDIO_SUBCLASS_AUDIOSTREAMING 0x02 +#define AUDIO_PROTOCOL_UNDEFINED 0x00 +#define AUDIO_STREAMING_GENERAL 0x01 +#define AUDIO_STREAMING_FORMAT_TYPE 0x02 + +/* Audio Descriptor Types */ +#define AUDIO_INTERFACE_DESCRIPTOR_TYPE 0x24 +#define AUDIO_ENDPOINT_DESCRIPTOR_TYPE 0x25 + +/* Audio Control Interface Descriptor Subtypes */ +#define AUDIO_CONTROL_HEADER 0x01 +#define AUDIO_CONTROL_INPUT_TERMINAL 0x02 +#define AUDIO_CONTROL_OUTPUT_TERMINAL 0x03 +#define AUDIO_CONTROL_FEATURE_UNIT 0x06 + +#define AUDIO_INPUT_TERMINAL_DESC_SIZE 0x0C +#define AUDIO_OUTPUT_TERMINAL_DESC_SIZE 0x09 +#define AUDIO_STREAMING_INTERFACE_DESC_SIZE 0x07 + +#define AUDIO_CONTROL_MUTE 0x0001 + +#define AUDIO_FORMAT_TYPE_I 0x01 +#define AUDIO_FORMAT_TYPE_III 0x03 + +#define AUDIO_ENDPOINT_GENERAL 0x01 + +#define AUDIO_REQ_GET_CUR 0x81 +#define AUDIO_REQ_SET_CUR 0x01 + +#define AUDIO_OUT_STREAMING_CTRL 0x02 + + +#define AUDIO_OUT_PACKET (uint32_t)(((USBD_AUDIO_FREQ * 2 * 2) /1000)) +#define AUDIO_DEFAULT_VOLUME 70 + +/* Number of sub-packets in the audio transfer buffer. You can modify this value but always make sure + that it is an even number and higher than 3 */ +#define AUDIO_OUT_PACKET_NUM 80 +/* Total size of the audio transfer buffer */ +#define AUDIO_TOTAL_BUF_SIZE ((uint32_t)(AUDIO_OUT_PACKET * AUDIO_OUT_PACKET_NUM)) + + /* Audio Commands enumeration */ +typedef enum +{ + AUDIO_CMD_START = 1, + AUDIO_CMD_PLAY, + AUDIO_CMD_STOP, +}AUDIO_CMD_TypeDef; + + +typedef enum +{ + AUDIO_OFFSET_NONE = 0, + AUDIO_OFFSET_HALF, + AUDIO_OFFSET_FULL, + AUDIO_OFFSET_UNKNOWN, +} +AUDIO_OffsetTypeDef; +/** + * @} + */ + + +/** @defgroup USBD_CORE_Exported_TypesDefinitions + * @{ + */ + typedef struct +{ + uint8_t cmd; + uint8_t data[USB_MAX_EP0_SIZE]; + uint8_t len; + uint8_t unit; +} +USBD_AUDIO_ControlTypeDef; + + + +typedef struct +{ + __IO uint32_t alt_setting; + uint8_t buffer[AUDIO_TOTAL_BUF_SIZE]; + AUDIO_OffsetTypeDef offset; + uint8_t rd_enable; + uint16_t rd_ptr; + uint16_t wr_ptr; + USBD_AUDIO_ControlTypeDef control; +} +USBD_AUDIO_HandleTypeDef; + + +typedef struct +{ + int8_t (*Init) (uint32_t AudioFreq, uint32_t Volume, uint32_t options); + int8_t (*DeInit) (uint32_t options); + int8_t (*AudioCmd) (uint8_t* pbuf, uint32_t size, uint8_t cmd); + int8_t (*VolumeCtl) (uint8_t vol); + int8_t (*MuteCtl) (uint8_t cmd); + int8_t (*PeriodicTC) (uint8_t cmd); + int8_t (*GetState) (void); +}USBD_AUDIO_ItfTypeDef; +/** + * @} + */ + + + +/** @defgroup USBD_CORE_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_CORE_Exported_Variables + * @{ + */ + +extern USBD_ClassTypeDef USBD_AUDIO; +#define USBD_AUDIO_CLASS &USBD_AUDIO +/** + * @} + */ + +/** @defgroup USB_CORE_Exported_Functions + * @{ + */ +uint8_t USBD_AUDIO_RegisterInterface (USBD_HandleTypeDef *pdev, + USBD_AUDIO_ItfTypeDef *fops); + +void USBD_AUDIO_Sync (USBD_HandleTypeDef *pdev, AUDIO_OffsetTypeDef offset); +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_AUDIO_H */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/platform/mcu/stm32l475/Middlewares/USB_Device/Class/AUDIO/Inc/usbd_audio_if_template.h b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/AUDIO/Inc/usbd_audio_if_template.h new file mode 100644 index 0000000000..b83af152f9 --- /dev/null +++ b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/AUDIO/Inc/usbd_audio_if_template.h @@ -0,0 +1,73 @@ +/** + ****************************************************************************** + * @file usbd_audio_if_template.h + * @author MCD Application Team + * @version V2.4.2 + * @date 11-December-2015 + * @brief Header for usbd_audio_if_template.c file. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBD_AUDIO_IF_TEMPLATE_H +#define __USBD_AUDIO_IF_TEMPLATE_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_audio.h" + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +extern USBD_AUDIO_ItfTypeDef USBD_AUDIO_Template_fops; + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USBD_AUDIO_IF_TEMPLATE_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/platform/mcu/stm32l475/Middlewares/USB_Device/Class/AUDIO/Src/usbd_audio.c b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/AUDIO/Src/usbd_audio.c new file mode 100644 index 0000000000..d059d3ab8a --- /dev/null +++ b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/AUDIO/Src/usbd_audio.c @@ -0,0 +1,811 @@ +/** + ****************************************************************************** + * @file usbd_audio.c + * @author MCD Application Team + * @version V2.4.2 + * @date 11-December-2015 + * @brief This file provides the Audio core functions. + * + * @verbatim + * + * =================================================================== + * AUDIO Class Description + * =================================================================== + * This driver manages the Audio Class 1.0 following the "USB Device Class Definition for + * Audio Devices V1.0 Mar 18, 98". + * This driver implements the following aspects of the specification: + * - Device descriptor management + * - Configuration descriptor management + * - Standard AC Interface Descriptor management + * - 1 Audio Streaming Interface (with single channel, PCM, Stereo mode) + * - 1 Audio Streaming Endpoint + * - 1 Audio Terminal Input (1 channel) + * - Audio Class-Specific AC Interfaces + * - Audio Class-Specific AS Interfaces + * - AudioControl Requests: only SET_CUR and GET_CUR requests are supported (for Mute) + * - Audio Feature Unit (limited to Mute control) + * - Audio Synchronization type: Asynchronous + * - Single fixed audio sampling rate (configurable in usbd_conf.h file) + * The current audio class version supports the following audio features: + * - Pulse Coded Modulation (PCM) format + * - sampling rate: 48KHz. + * - Bit resolution: 16 + * - Number of channels: 2 + * - No volume control + * - Mute/Unmute capability + * - Asynchronous Endpoints + * + * @note In HS mode and when the DMA is used, all variables and data structures + * dealing with the DMA during the transaction process should be 32-bit aligned. + * + * + * @endverbatim + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_audio.h" +#include "usbd_desc.h" +#include "usbd_ctlreq.h" + + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup USBD_AUDIO + * @brief usbd core module + * @{ + */ + +/** @defgroup USBD_AUDIO_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_AUDIO_Private_Defines + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_AUDIO_Private_Macros + * @{ + */ +#define AUDIO_SAMPLE_FREQ(frq) (uint8_t)(frq), (uint8_t)((frq >> 8)), (uint8_t)((frq >> 16)) + +#define AUDIO_PACKET_SZE(frq) (uint8_t)(((frq * 2 * 2)/1000) & 0xFF), \ + (uint8_t)((((frq * 2 * 2)/1000) >> 8) & 0xFF) + +/** + * @} + */ + + + + +/** @defgroup USBD_AUDIO_Private_FunctionPrototypes + * @{ + */ + + +static uint8_t USBD_AUDIO_Init (USBD_HandleTypeDef *pdev, + uint8_t cfgidx); + +static uint8_t USBD_AUDIO_DeInit (USBD_HandleTypeDef *pdev, + uint8_t cfgidx); + +static uint8_t USBD_AUDIO_Setup (USBD_HandleTypeDef *pdev, + USBD_SetupReqTypedef *req); + +static uint8_t *USBD_AUDIO_GetCfgDesc (uint16_t *length); + +static uint8_t *USBD_AUDIO_GetDeviceQualifierDesc (uint16_t *length); + +static uint8_t USBD_AUDIO_DataIn (USBD_HandleTypeDef *pdev, uint8_t epnum); + +static uint8_t USBD_AUDIO_DataOut (USBD_HandleTypeDef *pdev, uint8_t epnum); + +static uint8_t USBD_AUDIO_EP0_RxReady (USBD_HandleTypeDef *pdev); + +static uint8_t USBD_AUDIO_EP0_TxReady (USBD_HandleTypeDef *pdev); + +static uint8_t USBD_AUDIO_SOF (USBD_HandleTypeDef *pdev); + +static uint8_t USBD_AUDIO_IsoINIncomplete (USBD_HandleTypeDef *pdev, uint8_t epnum); + +static uint8_t USBD_AUDIO_IsoOutIncomplete (USBD_HandleTypeDef *pdev, uint8_t epnum); + +static void AUDIO_REQ_GetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); + +static void AUDIO_REQ_SetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); + +/** + * @} + */ + +/** @defgroup USBD_AUDIO_Private_Variables + * @{ + */ + +USBD_ClassTypeDef USBD_AUDIO = +{ + USBD_AUDIO_Init, + USBD_AUDIO_DeInit, + USBD_AUDIO_Setup, + USBD_AUDIO_EP0_TxReady, + USBD_AUDIO_EP0_RxReady, + USBD_AUDIO_DataIn, + USBD_AUDIO_DataOut, + USBD_AUDIO_SOF, + USBD_AUDIO_IsoINIncomplete, + USBD_AUDIO_IsoOutIncomplete, + USBD_AUDIO_GetCfgDesc, + USBD_AUDIO_GetCfgDesc, + USBD_AUDIO_GetCfgDesc, + USBD_AUDIO_GetDeviceQualifierDesc, +}; + +/* USB AUDIO device Configuration Descriptor */ +__ALIGN_BEGIN static uint8_t USBD_AUDIO_CfgDesc[USB_AUDIO_CONFIG_DESC_SIZ] __ALIGN_END = +{ + /* Configuration 1 */ + 0x09, /* bLength */ + USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType */ + LOBYTE(USB_AUDIO_CONFIG_DESC_SIZ), /* wTotalLength 109 bytes*/ + HIBYTE(USB_AUDIO_CONFIG_DESC_SIZ), + 0x02, /* bNumInterfaces */ + 0x01, /* bConfigurationValue */ + 0x00, /* iConfiguration */ + 0xC0, /* bmAttributes BUS Powred*/ + 0x32, /* bMaxPower = 100 mA*/ + /* 09 byte*/ + + /* USB Speaker Standard interface descriptor */ + AUDIO_INTERFACE_DESC_SIZE, /* bLength */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType */ + 0x00, /* bInterfaceNumber */ + 0x00, /* bAlternateSetting */ + 0x00, /* bNumEndpoints */ + USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ + AUDIO_SUBCLASS_AUDIOCONTROL, /* bInterfaceSubClass */ + AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */ + 0x00, /* iInterface */ + /* 09 byte*/ + + /* USB Speaker Class-specific AC Interface Descriptor */ + AUDIO_INTERFACE_DESC_SIZE, /* bLength */ + AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ + AUDIO_CONTROL_HEADER, /* bDescriptorSubtype */ + 0x00, /* 1.00 */ /* bcdADC */ + 0x01, + 0x27, /* wTotalLength = 39*/ + 0x00, + 0x01, /* bInCollection */ + 0x01, /* baInterfaceNr */ + /* 09 byte*/ + + /* USB Speaker Input Terminal Descriptor */ + AUDIO_INPUT_TERMINAL_DESC_SIZE, /* bLength */ + AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ + AUDIO_CONTROL_INPUT_TERMINAL, /* bDescriptorSubtype */ + 0x01, /* bTerminalID */ + 0x01, /* wTerminalType AUDIO_TERMINAL_USB_STREAMING 0x0101 */ + 0x01, + 0x00, /* bAssocTerminal */ + 0x01, /* bNrChannels */ + 0x00, /* wChannelConfig 0x0000 Mono */ + 0x00, + 0x00, /* iChannelNames */ + 0x00, /* iTerminal */ + /* 12 byte*/ + + /* USB Speaker Audio Feature Unit Descriptor */ + 0x09, /* bLength */ + AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ + AUDIO_CONTROL_FEATURE_UNIT, /* bDescriptorSubtype */ + AUDIO_OUT_STREAMING_CTRL, /* bUnitID */ + 0x01, /* bSourceID */ + 0x01, /* bControlSize */ + AUDIO_CONTROL_MUTE,// |AUDIO_CONTROL_VOLUME, /* bmaControls(0) */ + 0, /* bmaControls(1) */ + 0x00, /* iTerminal */ + /* 09 byte*/ + + /*USB Speaker Output Terminal Descriptor */ + 0x09, /* bLength */ + AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ + AUDIO_CONTROL_OUTPUT_TERMINAL, /* bDescriptorSubtype */ + 0x03, /* bTerminalID */ + 0x01, /* wTerminalType 0x0301*/ + 0x03, + 0x00, /* bAssocTerminal */ + 0x02, /* bSourceID */ + 0x00, /* iTerminal */ + /* 09 byte*/ + + /* USB Speaker Standard AS Interface Descriptor - Audio Streaming Zero Bandwith */ + /* Interface 1, Alternate Setting 0 */ + AUDIO_INTERFACE_DESC_SIZE, /* bLength */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType */ + 0x01, /* bInterfaceNumber */ + 0x00, /* bAlternateSetting */ + 0x00, /* bNumEndpoints */ + USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ + AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */ + AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */ + 0x00, /* iInterface */ + /* 09 byte*/ + + /* USB Speaker Standard AS Interface Descriptor - Audio Streaming Operational */ + /* Interface 1, Alternate Setting 1 */ + AUDIO_INTERFACE_DESC_SIZE, /* bLength */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType */ + 0x01, /* bInterfaceNumber */ + 0x01, /* bAlternateSetting */ + 0x01, /* bNumEndpoints */ + USB_DEVICE_CLASS_AUDIO, /* bInterfaceClass */ + AUDIO_SUBCLASS_AUDIOSTREAMING, /* bInterfaceSubClass */ + AUDIO_PROTOCOL_UNDEFINED, /* bInterfaceProtocol */ + 0x00, /* iInterface */ + /* 09 byte*/ + + /* USB Speaker Audio Streaming Interface Descriptor */ + AUDIO_STREAMING_INTERFACE_DESC_SIZE, /* bLength */ + AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ + AUDIO_STREAMING_GENERAL, /* bDescriptorSubtype */ + 0x01, /* bTerminalLink */ + 0x01, /* bDelay */ + 0x01, /* wFormatTag AUDIO_FORMAT_PCM 0x0001*/ + 0x00, + /* 07 byte*/ + + /* USB Speaker Audio Type III Format Interface Descriptor */ + 0x0B, /* bLength */ + AUDIO_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ + AUDIO_STREAMING_FORMAT_TYPE, /* bDescriptorSubtype */ + AUDIO_FORMAT_TYPE_III, /* bFormatType */ + 0x02, /* bNrChannels */ + 0x02, /* bSubFrameSize : 2 Bytes per frame (16bits) */ + 16, /* bBitResolution (16-bits per sample) */ + 0x01, /* bSamFreqType only one frequency supported */ + AUDIO_SAMPLE_FREQ(USBD_AUDIO_FREQ), /* Audio sampling frequency coded on 3 bytes */ + /* 11 byte*/ + + /* Endpoint 1 - Standard Descriptor */ + AUDIO_STANDARD_ENDPOINT_DESC_SIZE, /* bLength */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType */ + AUDIO_OUT_EP, /* bEndpointAddress 1 out endpoint*/ + USBD_EP_TYPE_ISOC, /* bmAttributes */ + AUDIO_PACKET_SZE(USBD_AUDIO_FREQ), /* wMaxPacketSize in Bytes (Freq(Samples)*2(Stereo)*2(HalfWord)) */ + 0x01, /* bInterval */ + 0x00, /* bRefresh */ + 0x00, /* bSynchAddress */ + /* 09 byte*/ + + /* Endpoint - Audio Streaming Descriptor*/ + AUDIO_STREAMING_ENDPOINT_DESC_SIZE, /* bLength */ + AUDIO_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ + AUDIO_ENDPOINT_GENERAL, /* bDescriptor */ + 0x00, /* bmAttributes */ + 0x00, /* bLockDelayUnits */ + 0x00, /* wLockDelay */ + 0x00, + /* 07 byte*/ +} ; + +/* USB Standard Device Descriptor */ +__ALIGN_BEGIN static uint8_t USBD_AUDIO_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END= +{ + USB_LEN_DEV_QUALIFIER_DESC, + USB_DESC_TYPE_DEVICE_QUALIFIER, + 0x00, + 0x02, + 0x00, + 0x00, + 0x00, + 0x40, + 0x01, + 0x00, +}; + +/** + * @} + */ + +/** @defgroup USBD_AUDIO_Private_Functions + * @{ + */ + +/** + * @brief USBD_AUDIO_Init + * Initialize the AUDIO interface + * @param pdev: device instance + * @param cfgidx: Configuration index + * @retval status + */ +static uint8_t USBD_AUDIO_Init (USBD_HandleTypeDef *pdev, + uint8_t cfgidx) +{ + USBD_AUDIO_HandleTypeDef *haudio; + + /* Open EP OUT */ + USBD_LL_OpenEP(pdev, + AUDIO_OUT_EP, + USBD_EP_TYPE_ISOC, + AUDIO_OUT_PACKET); + + /* Allocate Audio structure */ + pdev->pClassData = USBD_malloc(sizeof (USBD_AUDIO_HandleTypeDef)); + + if(pdev->pClassData == NULL) + { + return USBD_FAIL; + } + else + { + haudio = (USBD_AUDIO_HandleTypeDef*) pdev->pClassData; + haudio->alt_setting = 0; + haudio->offset = AUDIO_OFFSET_UNKNOWN; + haudio->wr_ptr = 0; + haudio->rd_ptr = 0; + haudio->rd_enable = 0; + + /* Initialize the Audio output Hardware layer */ + if (((USBD_AUDIO_ItfTypeDef *)pdev->pUserData)->Init(USBD_AUDIO_FREQ, AUDIO_DEFAULT_VOLUME, 0) != USBD_OK) + { + return USBD_FAIL; + } + + /* Prepare Out endpoint to receive 1st packet */ + USBD_LL_PrepareReceive(pdev, + AUDIO_OUT_EP, + haudio->buffer, + AUDIO_OUT_PACKET); + } + return USBD_OK; +} + +/** + * @brief USBD_AUDIO_Init + * DeInitialize the AUDIO layer + * @param pdev: device instance + * @param cfgidx: Configuration index + * @retval status + */ +static uint8_t USBD_AUDIO_DeInit (USBD_HandleTypeDef *pdev, + uint8_t cfgidx) +{ + + /* Open EP OUT */ + USBD_LL_CloseEP(pdev, + AUDIO_OUT_EP); + + /* DeInit physical Interface components */ + if(pdev->pClassData != NULL) + { + ((USBD_AUDIO_ItfTypeDef *)pdev->pUserData)->DeInit(0); + USBD_free(pdev->pClassData); + pdev->pClassData = NULL; + } + + return USBD_OK; +} + +/** + * @brief USBD_AUDIO_Setup + * Handle the AUDIO specific requests + * @param pdev: instance + * @param req: usb requests + * @retval status + */ +static uint8_t USBD_AUDIO_Setup (USBD_HandleTypeDef *pdev, + USBD_SetupReqTypedef *req) +{ + USBD_AUDIO_HandleTypeDef *haudio; + uint16_t len; + uint8_t *pbuf; + uint8_t ret = USBD_OK; + haudio = (USBD_AUDIO_HandleTypeDef*) pdev->pClassData; + + switch (req->bmRequest & USB_REQ_TYPE_MASK) + { + case USB_REQ_TYPE_CLASS : + switch (req->bRequest) + { + case AUDIO_REQ_GET_CUR: + AUDIO_REQ_GetCurrent(pdev, req); + break; + + case AUDIO_REQ_SET_CUR: + AUDIO_REQ_SetCurrent(pdev, req); + break; + + default: + USBD_CtlError (pdev, req); + ret = USBD_FAIL; + } + break; + + case USB_REQ_TYPE_STANDARD: + switch (req->bRequest) + { + case USB_REQ_GET_DESCRIPTOR: + if( (req->wValue >> 8) == AUDIO_DESCRIPTOR_TYPE) + { + pbuf = USBD_AUDIO_CfgDesc + 18; + len = MIN(USB_AUDIO_DESC_SIZ , req->wLength); + + + USBD_CtlSendData (pdev, + pbuf, + len); + } + break; + + case USB_REQ_GET_INTERFACE : + USBD_CtlSendData (pdev, + (uint8_t *)&(haudio->alt_setting), + 1); + break; + + case USB_REQ_SET_INTERFACE : + if ((uint8_t)(req->wValue) <= USBD_MAX_NUM_INTERFACES) + { + haudio->alt_setting = (uint8_t)(req->wValue); + } + else + { + /* Call the error management function (command will be nacked */ + USBD_CtlError (pdev, req); + } + break; + + default: + USBD_CtlError (pdev, req); + ret = USBD_FAIL; + } + } + return ret; +} + + +/** + * @brief USBD_AUDIO_GetCfgDesc + * return configuration descriptor + * @param speed : current device speed + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +static uint8_t *USBD_AUDIO_GetCfgDesc (uint16_t *length) +{ + *length = sizeof (USBD_AUDIO_CfgDesc); + return USBD_AUDIO_CfgDesc; +} + +/** + * @brief USBD_AUDIO_DataIn + * handle data IN Stage + * @param pdev: device instance + * @param epnum: endpoint index + * @retval status + */ +static uint8_t USBD_AUDIO_DataIn (USBD_HandleTypeDef *pdev, + uint8_t epnum) +{ + + /* Only OUT data are processed */ + return USBD_OK; +} + +/** + * @brief USBD_AUDIO_EP0_RxReady + * handle EP0 Rx Ready event + * @param pdev: device instance + * @retval status + */ +static uint8_t USBD_AUDIO_EP0_RxReady (USBD_HandleTypeDef *pdev) +{ + USBD_AUDIO_HandleTypeDef *haudio; + haudio = (USBD_AUDIO_HandleTypeDef*) pdev->pClassData; + + if (haudio->control.cmd == AUDIO_REQ_SET_CUR) + {/* In this driver, to simplify code, only SET_CUR request is managed */ + + if (haudio->control.unit == AUDIO_OUT_STREAMING_CTRL) + { + ((USBD_AUDIO_ItfTypeDef *)pdev->pUserData)->MuteCtl(haudio->control.data[0]); + haudio->control.cmd = 0; + haudio->control.len = 0; + } + } + + return USBD_OK; +} +/** + * @brief USBD_AUDIO_EP0_TxReady + * handle EP0 TRx Ready event + * @param pdev: device instance + * @retval status + */ +static uint8_t USBD_AUDIO_EP0_TxReady (USBD_HandleTypeDef *pdev) +{ + /* Only OUT control data are processed */ + return USBD_OK; +} +/** + * @brief USBD_AUDIO_SOF + * handle SOF event + * @param pdev: device instance + * @retval status + */ +static uint8_t USBD_AUDIO_SOF (USBD_HandleTypeDef *pdev) +{ + return USBD_OK; +} + +/** + * @brief USBD_AUDIO_SOF + * handle SOF event + * @param pdev: device instance + * @retval status + */ +void USBD_AUDIO_Sync (USBD_HandleTypeDef *pdev, AUDIO_OffsetTypeDef offset) +{ + int8_t shift = 0; + USBD_AUDIO_HandleTypeDef *haudio; + haudio = (USBD_AUDIO_HandleTypeDef*) pdev->pClassData; + + haudio->offset = offset; + + + if(haudio->rd_enable == 1) + { + haudio->rd_ptr += AUDIO_TOTAL_BUF_SIZE/2; + + if (haudio->rd_ptr == AUDIO_TOTAL_BUF_SIZE) + { + /* roll back */ + haudio->rd_ptr = 0; + } + } + + if(haudio->rd_ptr > haudio->wr_ptr) + { + if((haudio->rd_ptr - haudio->wr_ptr) < AUDIO_OUT_PACKET) + { + shift = -4; + } + else if((haudio->rd_ptr - haudio->wr_ptr) > (AUDIO_TOTAL_BUF_SIZE - AUDIO_OUT_PACKET)) + { + shift = 4; + } + + } + else + { + if((haudio->wr_ptr - haudio->rd_ptr) < AUDIO_OUT_PACKET) + { + shift = 4; + } + else if((haudio->wr_ptr - haudio->rd_ptr) > (AUDIO_TOTAL_BUF_SIZE - AUDIO_OUT_PACKET)) + { + shift = -4; + } + } + + if(haudio->offset == AUDIO_OFFSET_FULL) + { + ((USBD_AUDIO_ItfTypeDef *)pdev->pUserData)->AudioCmd(&haudio->buffer[0], + AUDIO_TOTAL_BUF_SIZE/2 - shift, + AUDIO_CMD_PLAY); + haudio->offset = AUDIO_OFFSET_NONE; + } +} + +/** + * @brief USBD_AUDIO_IsoINIncomplete + * handle data ISO IN Incomplete event + * @param pdev: device instance + * @param epnum: endpoint index + * @retval status + */ +static uint8_t USBD_AUDIO_IsoINIncomplete (USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + + return USBD_OK; +} +/** + * @brief USBD_AUDIO_IsoOutIncomplete + * handle data ISO OUT Incomplete event + * @param pdev: device instance + * @param epnum: endpoint index + * @retval status + */ +static uint8_t USBD_AUDIO_IsoOutIncomplete (USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + + return USBD_OK; +} +/** + * @brief USBD_AUDIO_DataOut + * handle data OUT Stage + * @param pdev: device instance + * @param epnum: endpoint index + * @retval status + */ +static uint8_t USBD_AUDIO_DataOut (USBD_HandleTypeDef *pdev, + uint8_t epnum) +{ + USBD_AUDIO_HandleTypeDef *haudio; + haudio = (USBD_AUDIO_HandleTypeDef*) pdev->pClassData; + + if (epnum == AUDIO_OUT_EP) + { + /* Increment the Buffer pointer or roll it back when all buffers are full */ + + haudio->wr_ptr += AUDIO_OUT_PACKET; + + if (haudio->wr_ptr == AUDIO_TOTAL_BUF_SIZE) + {/* All buffers are full: roll back */ + haudio->wr_ptr = 0; + + if(haudio->offset == AUDIO_OFFSET_UNKNOWN) + { + ((USBD_AUDIO_ItfTypeDef *)pdev->pUserData)->AudioCmd(&haudio->buffer[0], + AUDIO_TOTAL_BUF_SIZE/2, + AUDIO_CMD_START); + haudio->offset = AUDIO_OFFSET_NONE; + } + } + + if(haudio->rd_enable == 0) + { + if (haudio->wr_ptr == (AUDIO_TOTAL_BUF_SIZE / 2)) + { + haudio->rd_enable = 1; + } + } + + /* Prepare Out endpoint to receive next audio packet */ + USBD_LL_PrepareReceive(pdev, + AUDIO_OUT_EP, + &haudio->buffer[haudio->wr_ptr], + AUDIO_OUT_PACKET); + + } + + return USBD_OK; +} + +/** + * @brief AUDIO_Req_GetCurrent + * Handles the GET_CUR Audio control request. + * @param pdev: instance + * @param req: setup class request + * @retval status + */ +static void AUDIO_REQ_GetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + USBD_AUDIO_HandleTypeDef *haudio; + haudio = (USBD_AUDIO_HandleTypeDef*) pdev->pClassData; + + memset(haudio->control.data, 0, 64); + /* Send the current mute state */ + USBD_CtlSendData (pdev, + haudio->control.data, + req->wLength); +} + +/** + * @brief AUDIO_Req_SetCurrent + * Handles the SET_CUR Audio control request. + * @param pdev: instance + * @param req: setup class request + * @retval status + */ +static void AUDIO_REQ_SetCurrent(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + USBD_AUDIO_HandleTypeDef *haudio; + haudio = (USBD_AUDIO_HandleTypeDef*) pdev->pClassData; + + if (req->wLength) + { + /* Prepare the reception of the buffer over EP0 */ + USBD_CtlPrepareRx (pdev, + haudio->control.data, + req->wLength); + + haudio->control.cmd = AUDIO_REQ_SET_CUR; /* Set the request value */ + haudio->control.len = req->wLength; /* Set the request data length */ + haudio->control.unit = HIBYTE(req->wIndex); /* Set the request target unit */ + } +} + + +/** +* @brief DeviceQualifierDescriptor +* return Device Qualifier descriptor +* @param length : pointer data length +* @retval pointer to descriptor buffer +*/ +static uint8_t *USBD_AUDIO_GetDeviceQualifierDesc (uint16_t *length) +{ + *length = sizeof (USBD_AUDIO_DeviceQualifierDesc); + return USBD_AUDIO_DeviceQualifierDesc; +} + +/** +* @brief USBD_AUDIO_RegisterInterface +* @param fops: Audio interface callback +* @retval status +*/ +uint8_t USBD_AUDIO_RegisterInterface (USBD_HandleTypeDef *pdev, + USBD_AUDIO_ItfTypeDef *fops) +{ + if(fops != NULL) + { + pdev->pUserData= fops; + } + return 0; +} +/** + * @} + */ + + +/** + * @} + */ + + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/platform/mcu/stm32l475/Middlewares/USB_Device/Class/AUDIO/Src/usbd_audio_if_template.c b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/AUDIO/Src/usbd_audio_if_template.c new file mode 100644 index 0000000000..efc6e40268 --- /dev/null +++ b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/AUDIO/Src/usbd_audio_if_template.c @@ -0,0 +1,210 @@ +/** + ****************************************************************************** + * @file usbd_cdc_if_template.c + * @author MCD Application Team + * @version V2.4.2 + * @date 11-December-2015 + * @brief Generic media access Layer. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_audio_if_template.h" + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup USBD_AUDIO + * @brief usbd core module + * @{ + */ + +/** @defgroup USBD_AUDIO_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_AUDIO_Private_Defines + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_AUDIO_Private_Macros + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_AUDIO_Private_FunctionPrototypes + * @{ + */ + +static int8_t TEMPLATE_Init (uint32_t AudioFreq, uint32_t Volume, uint32_t options); +static int8_t TEMPLATE_DeInit (uint32_t options); +static int8_t TEMPLATE_AudioCmd (uint8_t* pbuf, uint32_t size, uint8_t cmd); +static int8_t TEMPLATE_VolumeCtl (uint8_t vol); +static int8_t TEMPLATE_MuteCtl (uint8_t cmd); +static int8_t TEMPLATE_PeriodicTC (uint8_t cmd); +static int8_t TEMPLATE_GetState (void); + +USBD_AUDIO_ItfTypeDef USBD_AUDIO_Template_fops = +{ + TEMPLATE_Init, + TEMPLATE_DeInit, + TEMPLATE_AudioCmd, + TEMPLATE_VolumeCtl, + TEMPLATE_MuteCtl, + TEMPLATE_PeriodicTC, + TEMPLATE_GetState, +}; + +/* Private functions ---------------------------------------------------------*/ + +/** + * @brief TEMPLATE_Init + * Initializes the AUDIO media low layer + * @param None + * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t TEMPLATE_Init(uint32_t AudioFreq, uint32_t Volume, uint32_t options) +{ + /* + Add your initialization code here + */ + return (0); +} + +/** + * @brief TEMPLATE_DeInit + * DeInitializes the AUDIO media low layer + * @param None + * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t TEMPLATE_DeInit(uint32_t options) +{ + /* + Add your deinitialization code here + */ + return (0); +} + + +/** + * @brief TEMPLATE_AudioCmd + * AUDIO command handler + * @param Buf: Buffer of data to be sent + * @param size: Number of data to be sent (in bytes) + * @param cmd: command opcode + * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t TEMPLATE_AudioCmd (uint8_t* pbuf, uint32_t size, uint8_t cmd) +{ + + return (0); +} + +/** + * @brief TEMPLATE_VolumeCtl + * @param vol: volume level (0..100) + * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t TEMPLATE_VolumeCtl (uint8_t vol) +{ + + return (0); +} + +/** + * @brief TEMPLATE_MuteCtl + * @param cmd: vmute command + * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t TEMPLATE_MuteCtl (uint8_t cmd) +{ + + return (0); +} + +/** + * @brief TEMPLATE_PeriodicTC + * @param cmd + * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t TEMPLATE_PeriodicTC (uint8_t cmd) +{ + + return (0); +} + +/** + * @brief TEMPLATE_GetState + * @param None + * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t TEMPLATE_GetState (void) +{ + + return (0); +} +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/platform/mcu/stm32l475/Middlewares/USB_Device/Class/CDC/Inc/usbd_cdc.h b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/CDC/Inc/usbd_cdc.h new file mode 100644 index 0000000000..a75ea9da9c --- /dev/null +++ b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/CDC/Inc/usbd_cdc.h @@ -0,0 +1,199 @@ +/** + ****************************************************************************** + * @file usbd_cdc.h + * @author MCD Application Team + * @version V2.4.2 + * @date 11-December-2015 + * @brief header file for the usbd_cdc.c file. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USB_CDC_H +#define __USB_CDC_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_ioreq.h" + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup usbd_cdc + * @brief This file is the Header file for usbd_cdc.c + * @{ + */ + + +/** @defgroup usbd_cdc_Exported_Defines + * @{ + */ +#define CDC_IN_EP 0x81 /* EP1 for data IN */ +#define CDC_OUT_EP 0x01 /* EP1 for data OUT */ +#define CDC_CMD_EP 0x82 /* EP2 for CDC commands */ + +/* CDC Endpoints parameters: you can fine tune these values depending on the needed baudrates and performance. */ +#define CDC_DATA_HS_MAX_PACKET_SIZE 512 /* Endpoint IN & OUT Packet size */ +#define CDC_DATA_FS_MAX_PACKET_SIZE 64 /* Endpoint IN & OUT Packet size */ +#define CDC_CMD_PACKET_SIZE 8 /* Control Endpoint Packet size */ + +#define USB_CDC_CONFIG_DESC_SIZ 67 +#define CDC_DATA_HS_IN_PACKET_SIZE CDC_DATA_HS_MAX_PACKET_SIZE +#define CDC_DATA_HS_OUT_PACKET_SIZE CDC_DATA_HS_MAX_PACKET_SIZE + +#define CDC_DATA_FS_IN_PACKET_SIZE CDC_DATA_FS_MAX_PACKET_SIZE +#define CDC_DATA_FS_OUT_PACKET_SIZE CDC_DATA_FS_MAX_PACKET_SIZE + +/*---------------------------------------------------------------------*/ +/* CDC definitions */ +/*---------------------------------------------------------------------*/ +#define CDC_SEND_ENCAPSULATED_COMMAND 0x00 +#define CDC_GET_ENCAPSULATED_RESPONSE 0x01 +#define CDC_SET_COMM_FEATURE 0x02 +#define CDC_GET_COMM_FEATURE 0x03 +#define CDC_CLEAR_COMM_FEATURE 0x04 +#define CDC_SET_LINE_CODING 0x20 +#define CDC_GET_LINE_CODING 0x21 +#define CDC_SET_CONTROL_LINE_STATE 0x22 +#define CDC_SEND_BREAK 0x23 + +/** + * @} + */ + + +/** @defgroup USBD_CORE_Exported_TypesDefinitions + * @{ + */ + +/** + * @} + */ +typedef struct +{ + uint32_t bitrate; + uint8_t format; + uint8_t paritytype; + uint8_t datatype; +}USBD_CDC_LineCodingTypeDef; + +typedef struct _USBD_CDC_Itf +{ + int8_t (* Init) (void); + int8_t (* DeInit) (void); + int8_t (* Control) (uint8_t, uint8_t * , uint16_t); + int8_t (* Receive) (uint8_t *, uint32_t *); + +}USBD_CDC_ItfTypeDef; + + +typedef struct +{ + uint32_t data[CDC_DATA_HS_MAX_PACKET_SIZE/4]; /* Force 32bits alignment */ + uint8_t CmdOpCode; + uint8_t CmdLength; + uint8_t *RxBuffer; + uint8_t *TxBuffer; + uint32_t RxLength; + uint32_t TxLength; + + __IO uint32_t TxState; + __IO uint32_t RxState; +} +USBD_CDC_HandleTypeDef; + + + +/** @defgroup USBD_CORE_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_CORE_Exported_Variables + * @{ + */ + +extern USBD_ClassTypeDef USBD_CDC; +#define USBD_CDC_CLASS &USBD_CDC +/** + * @} + */ + +/** @defgroup USB_CORE_Exported_Functions + * @{ + */ +uint8_t USBD_CDC_RegisterInterface (USBD_HandleTypeDef *pdev, + USBD_CDC_ItfTypeDef *fops); + +uint8_t USBD_CDC_SetTxBuffer (USBD_HandleTypeDef *pdev, + uint8_t *pbuff, + uint16_t length); + +uint8_t USBD_CDC_SetRxBuffer (USBD_HandleTypeDef *pdev, + uint8_t *pbuff); + +uint8_t USBD_CDC_ReceivePacket (USBD_HandleTypeDef *pdev); + +uint8_t USBD_CDC_TransmitPacket (USBD_HandleTypeDef *pdev); +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_CDC_H */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/platform/mcu/stm32l475/Middlewares/USB_Device/Class/CDC/Inc/usbd_cdc_if_template.h b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/CDC/Inc/usbd_cdc_if_template.h new file mode 100644 index 0000000000..aad43f76c6 --- /dev/null +++ b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/CDC/Inc/usbd_cdc_if_template.h @@ -0,0 +1,73 @@ +/** + ****************************************************************************** + * @file usbd_cdc_if_template.h + * @author MCD Application Team + * @version V2.4.2 + * @date 11-December-2015 + * @brief Header for usbd_cdc_if_template.c file. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBD_CDC_IF_TEMPLATE_H +#define __USBD_CDC_IF_TEMPLATE_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_cdc.h" + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +extern USBD_CDC_ItfTypeDef USBD_CDC_Template_fops; + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USBD_CDC_IF_TEMPLATE_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/platform/mcu/stm32l475/Middlewares/USB_Device/Class/CDC/Src/usbd_cdc.c b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/CDC/Src/usbd_cdc.c new file mode 100644 index 0000000000..15c524d229 --- /dev/null +++ b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/CDC/Src/usbd_cdc.c @@ -0,0 +1,945 @@ +/** + ****************************************************************************** + * @file usbd_cdc.c + * @author MCD Application Team + * @version V2.4.2 + * @date 11-December-2015 + * @brief This file provides the high layer firmware functions to manage the + * following functionalities of the USB CDC Class: + * - Initialization and Configuration of high and low layer + * - Enumeration as CDC Device (and enumeration for each implemented memory interface) + * - OUT/IN data transfer + * - Command IN transfer (class requests management) + * - Error management + * + * @verbatim + * + * =================================================================== + * CDC Class Driver Description + * =================================================================== + * This driver manages the "Universal Serial Bus Class Definitions for Communications Devices + * Revision 1.2 November 16, 2007" and the sub-protocol specification of "Universal Serial Bus + * Communications Class Subclass Specification for PSTN Devices Revision 1.2 February 9, 2007" + * This driver implements the following aspects of the specification: + * - Device descriptor management + * - Configuration descriptor management + * - Enumeration as CDC device with 2 data endpoints (IN and OUT) and 1 command endpoint (IN) + * - Requests management (as described in section 6.2 in specification) + * - Abstract Control Model compliant + * - Union Functional collection (using 1 IN endpoint for control) + * - Data interface class + * + * These aspects may be enriched or modified for a specific user application. + * + * This driver doesn't implement the following aspects of the specification + * (but it is possible to manage these features with some modifications on this driver): + * - Any class-specific aspect relative to communication classes should be managed by user application. + * - All communication classes other than PSTN are not managed + * + * @endverbatim + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_cdc.h" +#include "usbd_desc.h" +#include "usbd_ctlreq.h" + + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup USBD_CDC + * @brief usbd core module + * @{ + */ + +/** @defgroup USBD_CDC_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_CDC_Private_Defines + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_CDC_Private_Macros + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_CDC_Private_FunctionPrototypes + * @{ + */ + + +static uint8_t USBD_CDC_Init (USBD_HandleTypeDef *pdev, + uint8_t cfgidx); + +static uint8_t USBD_CDC_DeInit (USBD_HandleTypeDef *pdev, + uint8_t cfgidx); + +static uint8_t USBD_CDC_Setup (USBD_HandleTypeDef *pdev, + USBD_SetupReqTypedef *req); + +static uint8_t USBD_CDC_DataIn (USBD_HandleTypeDef *pdev, + uint8_t epnum); + +static uint8_t USBD_CDC_DataOut (USBD_HandleTypeDef *pdev, + uint8_t epnum); + +static uint8_t USBD_CDC_EP0_RxReady (USBD_HandleTypeDef *pdev); + +static uint8_t *USBD_CDC_GetFSCfgDesc (uint16_t *length); + +static uint8_t *USBD_CDC_GetHSCfgDesc (uint16_t *length); + +static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc (uint16_t *length); + +static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc (uint16_t *length); + +uint8_t *USBD_CDC_GetDeviceQualifierDescriptor (uint16_t *length); + +/* USB Standard Device Descriptor */ +__ALIGN_BEGIN static uint8_t USBD_CDC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = +{ + USB_LEN_DEV_QUALIFIER_DESC, + USB_DESC_TYPE_DEVICE_QUALIFIER, + 0x00, + 0x02, + 0x00, + 0x00, + 0x00, + 0x40, + 0x01, + 0x00, +}; + +/** + * @} + */ + +/** @defgroup USBD_CDC_Private_Variables + * @{ + */ + + +/* CDC interface class callbacks structure */ +USBD_ClassTypeDef USBD_CDC = +{ + USBD_CDC_Init, + USBD_CDC_DeInit, + USBD_CDC_Setup, + NULL, /* EP0_TxSent, */ + USBD_CDC_EP0_RxReady, + USBD_CDC_DataIn, + USBD_CDC_DataOut, + NULL, + NULL, + NULL, + USBD_CDC_GetHSCfgDesc, + USBD_CDC_GetFSCfgDesc, + USBD_CDC_GetOtherSpeedCfgDesc, + USBD_CDC_GetDeviceQualifierDescriptor, +}; + +/* USB CDC device Configuration Descriptor */ +__ALIGN_BEGIN uint8_t USBD_CDC_CfgHSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = +{ + /*Configuration Descriptor*/ + 0x09, /* bLength: Configuration Descriptor size */ + USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ + USB_CDC_CONFIG_DESC_SIZ, /* wTotalLength:no of returned bytes */ + 0x00, + 0x02, /* bNumInterfaces: 2 interface */ + 0x01, /* bConfigurationValue: Configuration value */ + 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ + 0xC0, /* bmAttributes: self powered */ + 0x32, /* MaxPower 0 mA */ + + /*---------------------------------------------------------------------------*/ + + /*Interface Descriptor */ + 0x09, /* bLength: Interface Descriptor size */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */ + /* Interface descriptor type */ + 0x00, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x01, /* bNumEndpoints: One endpoints used */ + 0x02, /* bInterfaceClass: Communication Interface Class */ + 0x02, /* bInterfaceSubClass: Abstract Control Model */ + 0x01, /* bInterfaceProtocol: Common AT commands */ + 0x00, /* iInterface: */ + + /*Header Functional Descriptor*/ + 0x05, /* bLength: Endpoint Descriptor size */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x00, /* bDescriptorSubtype: Header Func Desc */ + 0x10, /* bcdCDC: spec release number */ + 0x01, + + /*Call Management Functional Descriptor*/ + 0x05, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x01, /* bDescriptorSubtype: Call Management Func Desc */ + 0x00, /* bmCapabilities: D0+D1 */ + 0x01, /* bDataInterface: 1 */ + + /*ACM Functional Descriptor*/ + 0x04, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x02, /* bDescriptorSubtype: Abstract Control Management desc */ + 0x02, /* bmCapabilities */ + + /*Union Functional Descriptor*/ + 0x05, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x06, /* bDescriptorSubtype: Union func desc */ + 0x00, /* bMasterInterface: Communication class interface */ + 0x01, /* bSlaveInterface0: Data Class Interface */ + + /*Endpoint 2 Descriptor*/ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + CDC_CMD_EP, /* bEndpointAddress */ + 0x03, /* bmAttributes: Interrupt */ + LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */ + HIBYTE(CDC_CMD_PACKET_SIZE), + 0x10, /* bInterval: */ + /*---------------------------------------------------------------------------*/ + + /*Data class interface descriptor*/ + 0x09, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */ + 0x01, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x02, /* bNumEndpoints: Two endpoints used */ + 0x0A, /* bInterfaceClass: CDC */ + 0x00, /* bInterfaceSubClass: */ + 0x00, /* bInterfaceProtocol: */ + 0x00, /* iInterface: */ + + /*Endpoint OUT Descriptor*/ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + CDC_OUT_EP, /* bEndpointAddress */ + 0x02, /* bmAttributes: Bulk */ + LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ + HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), + 0x00, /* bInterval: ignore for Bulk transfer */ + + /*Endpoint IN Descriptor*/ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + CDC_IN_EP, /* bEndpointAddress */ + 0x02, /* bmAttributes: Bulk */ + LOBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ + HIBYTE(CDC_DATA_HS_MAX_PACKET_SIZE), + 0x00 /* bInterval: ignore for Bulk transfer */ +} ; + + +/* USB CDC device Configuration Descriptor */ +__ALIGN_BEGIN uint8_t USBD_CDC_CfgFSDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = +{ + /*Configuration Descriptor*/ + 0x09, /* bLength: Configuration Descriptor size */ + USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ + USB_CDC_CONFIG_DESC_SIZ, /* wTotalLength:no of returned bytes */ + 0x00, + 0x02, /* bNumInterfaces: 2 interface */ + 0x01, /* bConfigurationValue: Configuration value */ + 0x00, /* iConfiguration: Index of string descriptor describing the configuration */ + 0xC0, /* bmAttributes: self powered */ + 0x32, /* MaxPower 0 mA */ + + /*---------------------------------------------------------------------------*/ + + /*Interface Descriptor */ + 0x09, /* bLength: Interface Descriptor size */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */ + /* Interface descriptor type */ + 0x00, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x01, /* bNumEndpoints: One endpoints used */ + 0x02, /* bInterfaceClass: Communication Interface Class */ + 0x02, /* bInterfaceSubClass: Abstract Control Model */ + 0x01, /* bInterfaceProtocol: Common AT commands */ + 0x00, /* iInterface: */ + + /*Header Functional Descriptor*/ + 0x05, /* bLength: Endpoint Descriptor size */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x00, /* bDescriptorSubtype: Header Func Desc */ + 0x10, /* bcdCDC: spec release number */ + 0x01, + + /*Call Management Functional Descriptor*/ + 0x05, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x01, /* bDescriptorSubtype: Call Management Func Desc */ + 0x00, /* bmCapabilities: D0+D1 */ + 0x01, /* bDataInterface: 1 */ + + /*ACM Functional Descriptor*/ + 0x04, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x02, /* bDescriptorSubtype: Abstract Control Management desc */ + 0x02, /* bmCapabilities */ + + /*Union Functional Descriptor*/ + 0x05, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x06, /* bDescriptorSubtype: Union func desc */ + 0x00, /* bMasterInterface: Communication class interface */ + 0x01, /* bSlaveInterface0: Data Class Interface */ + + /*Endpoint 2 Descriptor*/ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + CDC_CMD_EP, /* bEndpointAddress */ + 0x03, /* bmAttributes: Interrupt */ + LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */ + HIBYTE(CDC_CMD_PACKET_SIZE), + 0x10, /* bInterval: */ + /*---------------------------------------------------------------------------*/ + + /*Data class interface descriptor*/ + 0x09, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */ + 0x01, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x02, /* bNumEndpoints: Two endpoints used */ + 0x0A, /* bInterfaceClass: CDC */ + 0x00, /* bInterfaceSubClass: */ + 0x00, /* bInterfaceProtocol: */ + 0x00, /* iInterface: */ + + /*Endpoint OUT Descriptor*/ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + CDC_OUT_EP, /* bEndpointAddress */ + 0x02, /* bmAttributes: Bulk */ + LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ + HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), + 0x00, /* bInterval: ignore for Bulk transfer */ + + /*Endpoint IN Descriptor*/ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + CDC_IN_EP, /* bEndpointAddress */ + 0x02, /* bmAttributes: Bulk */ + LOBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), /* wMaxPacketSize: */ + HIBYTE(CDC_DATA_FS_MAX_PACKET_SIZE), + 0x00 /* bInterval: ignore for Bulk transfer */ +} ; + +__ALIGN_BEGIN uint8_t USBD_CDC_OtherSpeedCfgDesc[USB_CDC_CONFIG_DESC_SIZ] __ALIGN_END = +{ + 0x09, /* bLength: Configuation Descriptor size */ + USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION, + USB_CDC_CONFIG_DESC_SIZ, + 0x00, + 0x02, /* bNumInterfaces: 2 interfaces */ + 0x01, /* bConfigurationValue: */ + 0x04, /* iConfiguration: */ + 0xC0, /* bmAttributes: */ + 0x32, /* MaxPower 100 mA */ + + /*Interface Descriptor */ + 0x09, /* bLength: Interface Descriptor size */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType: Interface */ + /* Interface descriptor type */ + 0x00, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x01, /* bNumEndpoints: One endpoints used */ + 0x02, /* bInterfaceClass: Communication Interface Class */ + 0x02, /* bInterfaceSubClass: Abstract Control Model */ + 0x01, /* bInterfaceProtocol: Common AT commands */ + 0x00, /* iInterface: */ + + /*Header Functional Descriptor*/ + 0x05, /* bLength: Endpoint Descriptor size */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x00, /* bDescriptorSubtype: Header Func Desc */ + 0x10, /* bcdCDC: spec release number */ + 0x01, + + /*Call Management Functional Descriptor*/ + 0x05, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x01, /* bDescriptorSubtype: Call Management Func Desc */ + 0x00, /* bmCapabilities: D0+D1 */ + 0x01, /* bDataInterface: 1 */ + + /*ACM Functional Descriptor*/ + 0x04, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x02, /* bDescriptorSubtype: Abstract Control Management desc */ + 0x02, /* bmCapabilities */ + + /*Union Functional Descriptor*/ + 0x05, /* bFunctionLength */ + 0x24, /* bDescriptorType: CS_INTERFACE */ + 0x06, /* bDescriptorSubtype: Union func desc */ + 0x00, /* bMasterInterface: Communication class interface */ + 0x01, /* bSlaveInterface0: Data Class Interface */ + + /*Endpoint 2 Descriptor*/ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT , /* bDescriptorType: Endpoint */ + CDC_CMD_EP, /* bEndpointAddress */ + 0x03, /* bmAttributes: Interrupt */ + LOBYTE(CDC_CMD_PACKET_SIZE), /* wMaxPacketSize: */ + HIBYTE(CDC_CMD_PACKET_SIZE), + 0xFF, /* bInterval: */ + + /*---------------------------------------------------------------------------*/ + + /*Data class interface descriptor*/ + 0x09, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType: */ + 0x01, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x02, /* bNumEndpoints: Two endpoints used */ + 0x0A, /* bInterfaceClass: CDC */ + 0x00, /* bInterfaceSubClass: */ + 0x00, /* bInterfaceProtocol: */ + 0x00, /* iInterface: */ + + /*Endpoint OUT Descriptor*/ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + CDC_OUT_EP, /* bEndpointAddress */ + 0x02, /* bmAttributes: Bulk */ + 0x40, /* wMaxPacketSize: */ + 0x00, + 0x00, /* bInterval: ignore for Bulk transfer */ + + /*Endpoint IN Descriptor*/ + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: Endpoint */ + CDC_IN_EP, /* bEndpointAddress */ + 0x02, /* bmAttributes: Bulk */ + 0x40, /* wMaxPacketSize: */ + 0x00, + 0x00 /* bInterval */ +}; + +/** + * @} + */ + +/** @defgroup USBD_CDC_Private_Functions + * @{ + */ + +/** + * @brief USBD_CDC_Init + * Initialize the CDC interface + * @param pdev: device instance + * @param cfgidx: Configuration index + * @retval status + */ +static uint8_t USBD_CDC_Init (USBD_HandleTypeDef *pdev, + uint8_t cfgidx) +{ + uint8_t ret = 0; + USBD_CDC_HandleTypeDef *hcdc; + + if(pdev->dev_speed == USBD_SPEED_HIGH ) + { + /* Open EP IN */ + USBD_LL_OpenEP(pdev, + CDC_IN_EP, + USBD_EP_TYPE_BULK, + CDC_DATA_HS_IN_PACKET_SIZE); + + /* Open EP OUT */ + USBD_LL_OpenEP(pdev, + CDC_OUT_EP, + USBD_EP_TYPE_BULK, + CDC_DATA_HS_OUT_PACKET_SIZE); + + } + else + { + /* Open EP IN */ + USBD_LL_OpenEP(pdev, + CDC_IN_EP, + USBD_EP_TYPE_BULK, + CDC_DATA_FS_IN_PACKET_SIZE); + + /* Open EP OUT */ + USBD_LL_OpenEP(pdev, + CDC_OUT_EP, + USBD_EP_TYPE_BULK, + CDC_DATA_FS_OUT_PACKET_SIZE); + } + /* Open Command IN EP */ + USBD_LL_OpenEP(pdev, + CDC_CMD_EP, + USBD_EP_TYPE_INTR, + CDC_CMD_PACKET_SIZE); + + + pdev->pClassData = USBD_malloc(sizeof (USBD_CDC_HandleTypeDef)); + + if(pdev->pClassData == NULL) + { + ret = 1; + } + else + { + hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData; + + /* Init physical Interface components */ + ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Init(); + + /* Init Xfer states */ + hcdc->TxState =0; + hcdc->RxState =0; + + if(pdev->dev_speed == USBD_SPEED_HIGH ) + { + /* Prepare Out endpoint to receive next packet */ + USBD_LL_PrepareReceive(pdev, + CDC_OUT_EP, + hcdc->RxBuffer, + CDC_DATA_HS_OUT_PACKET_SIZE); + } + else + { + /* Prepare Out endpoint to receive next packet */ + USBD_LL_PrepareReceive(pdev, + CDC_OUT_EP, + hcdc->RxBuffer, + CDC_DATA_FS_OUT_PACKET_SIZE); + } + + + } + return ret; +} + +/** + * @brief USBD_CDC_Init + * DeInitialize the CDC layer + * @param pdev: device instance + * @param cfgidx: Configuration index + * @retval status + */ +static uint8_t USBD_CDC_DeInit (USBD_HandleTypeDef *pdev, + uint8_t cfgidx) +{ + uint8_t ret = 0; + + /* Open EP IN */ + USBD_LL_CloseEP(pdev, + CDC_IN_EP); + + /* Open EP OUT */ + USBD_LL_CloseEP(pdev, + CDC_OUT_EP); + + /* Open Command IN EP */ + USBD_LL_CloseEP(pdev, + CDC_CMD_EP); + + + /* DeInit physical Interface components */ + if(pdev->pClassData != NULL) + { + ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->DeInit(); + USBD_free(pdev->pClassData); + pdev->pClassData = NULL; + } + + return ret; +} + +/** + * @brief USBD_CDC_Setup + * Handle the CDC specific requests + * @param pdev: instance + * @param req: usb requests + * @retval status + */ +static uint8_t USBD_CDC_Setup (USBD_HandleTypeDef *pdev, + USBD_SetupReqTypedef *req) +{ + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData; + static uint8_t ifalt = 0; + + switch (req->bmRequest & USB_REQ_TYPE_MASK) + { + case USB_REQ_TYPE_CLASS : + if (req->wLength) + { + if (req->bmRequest & 0x80) + { + ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest, + (uint8_t *)hcdc->data, + req->wLength); + USBD_CtlSendData (pdev, + (uint8_t *)hcdc->data, + req->wLength); + } + else + { + hcdc->CmdOpCode = req->bRequest; + hcdc->CmdLength = req->wLength; + + USBD_CtlPrepareRx (pdev, + (uint8_t *)hcdc->data, + req->wLength); + } + + } + else + { + ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(req->bRequest, + (uint8_t*)req, + 0); + } + break; + + case USB_REQ_TYPE_STANDARD: + switch (req->bRequest) + { + case USB_REQ_GET_INTERFACE : + USBD_CtlSendData (pdev, + &ifalt, + 1); + break; + + case USB_REQ_SET_INTERFACE : + break; + } + + default: + break; + } + return USBD_OK; +} + +/** + * @brief USBD_CDC_DataIn + * Data sent on non-control IN endpoint + * @param pdev: device instance + * @param epnum: endpoint number + * @retval status + */ +static uint8_t USBD_CDC_DataIn (USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData; + + if(pdev->pClassData != NULL) + { + + hcdc->TxState = 0; + + return USBD_OK; + } + else + { + return USBD_FAIL; + } +} + +/** + * @brief USBD_CDC_DataOut + * Data received on non-control Out endpoint + * @param pdev: device instance + * @param epnum: endpoint number + * @retval status + */ +static uint8_t USBD_CDC_DataOut (USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData; + + /* Get the received data length */ + hcdc->RxLength = USBD_LL_GetRxDataSize (pdev, epnum); + + /* USB data will be immediately processed, this allow next USB traffic being + NAKed till the end of the application Xfer */ + if(pdev->pClassData != NULL) + { + ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Receive(hcdc->RxBuffer, &hcdc->RxLength); + + return USBD_OK; + } + else + { + return USBD_FAIL; + } +} + + + +/** + * @brief USBD_CDC_DataOut + * Data received on non-control Out endpoint + * @param pdev: device instance + * @param epnum: endpoint number + * @retval status + */ +static uint8_t USBD_CDC_EP0_RxReady (USBD_HandleTypeDef *pdev) +{ + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData; + + if((pdev->pUserData != NULL) && (hcdc->CmdOpCode != 0xFF)) + { + ((USBD_CDC_ItfTypeDef *)pdev->pUserData)->Control(hcdc->CmdOpCode, + (uint8_t *)hcdc->data, + hcdc->CmdLength); + hcdc->CmdOpCode = 0xFF; + + } + return USBD_OK; +} + +/** + * @brief USBD_CDC_GetFSCfgDesc + * Return configuration descriptor + * @param speed : current device speed + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +static uint8_t *USBD_CDC_GetFSCfgDesc (uint16_t *length) +{ + *length = sizeof (USBD_CDC_CfgFSDesc); + return USBD_CDC_CfgFSDesc; +} + +/** + * @brief USBD_CDC_GetHSCfgDesc + * Return configuration descriptor + * @param speed : current device speed + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +static uint8_t *USBD_CDC_GetHSCfgDesc (uint16_t *length) +{ + *length = sizeof (USBD_CDC_CfgHSDesc); + return USBD_CDC_CfgHSDesc; +} + +/** + * @brief USBD_CDC_GetCfgDesc + * Return configuration descriptor + * @param speed : current device speed + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +static uint8_t *USBD_CDC_GetOtherSpeedCfgDesc (uint16_t *length) +{ + *length = sizeof (USBD_CDC_OtherSpeedCfgDesc); + return USBD_CDC_OtherSpeedCfgDesc; +} + +/** +* @brief DeviceQualifierDescriptor +* return Device Qualifier descriptor +* @param length : pointer data length +* @retval pointer to descriptor buffer +*/ +uint8_t *USBD_CDC_GetDeviceQualifierDescriptor (uint16_t *length) +{ + *length = sizeof (USBD_CDC_DeviceQualifierDesc); + return USBD_CDC_DeviceQualifierDesc; +} + +/** +* @brief USBD_CDC_RegisterInterface + * @param pdev: device instance + * @param fops: CD Interface callback + * @retval status + */ +uint8_t USBD_CDC_RegisterInterface (USBD_HandleTypeDef *pdev, + USBD_CDC_ItfTypeDef *fops) +{ + uint8_t ret = USBD_FAIL; + + if(fops != NULL) + { + pdev->pUserData= fops; + ret = USBD_OK; + } + + return ret; +} + +/** + * @brief USBD_CDC_SetTxBuffer + * @param pdev: device instance + * @param pbuff: Tx Buffer + * @retval status + */ +uint8_t USBD_CDC_SetTxBuffer (USBD_HandleTypeDef *pdev, + uint8_t *pbuff, + uint16_t length) +{ + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData; + + hcdc->TxBuffer = pbuff; + hcdc->TxLength = length; + + return USBD_OK; +} + + +/** + * @brief USBD_CDC_SetRxBuffer + * @param pdev: device instance + * @param pbuff: Rx Buffer + * @retval status + */ +uint8_t USBD_CDC_SetRxBuffer (USBD_HandleTypeDef *pdev, + uint8_t *pbuff) +{ + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData; + + hcdc->RxBuffer = pbuff; + + return USBD_OK; +} + +/** + * @brief USBD_CDC_DataOut + * Data received on non-control Out endpoint + * @param pdev: device instance + * @param epnum: endpoint number + * @retval status + */ +uint8_t USBD_CDC_TransmitPacket(USBD_HandleTypeDef *pdev) +{ + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData; + + if(pdev->pClassData != NULL) + { + if(hcdc->TxState == 0) + { + /* Tx Transfer in progress */ + hcdc->TxState = 1; + + /* Transmit next packet */ + USBD_LL_Transmit(pdev, + CDC_IN_EP, + hcdc->TxBuffer, + hcdc->TxLength); + + return USBD_OK; + } + else + { + return USBD_BUSY; + } + } + else + { + return USBD_FAIL; + } +} + + +/** + * @brief USBD_CDC_ReceivePacket + * prepare OUT Endpoint for reception + * @param pdev: device instance + * @retval status + */ +uint8_t USBD_CDC_ReceivePacket(USBD_HandleTypeDef *pdev) +{ + USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*) pdev->pClassData; + + /* Suspend or Resume USB Out process */ + if(pdev->pClassData != NULL) + { + if(pdev->dev_speed == USBD_SPEED_HIGH ) + { + /* Prepare Out endpoint to receive next packet */ + USBD_LL_PrepareReceive(pdev, + CDC_OUT_EP, + hcdc->RxBuffer, + CDC_DATA_HS_OUT_PACKET_SIZE); + } + else + { + /* Prepare Out endpoint to receive next packet */ + USBD_LL_PrepareReceive(pdev, + CDC_OUT_EP, + hcdc->RxBuffer, + CDC_DATA_FS_OUT_PACKET_SIZE); + } + return USBD_OK; + } + else + { + return USBD_FAIL; + } +} +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/platform/mcu/stm32l475/Middlewares/USB_Device/Class/CDC/Src/usbd_cdc_if_template.c b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/CDC/Src/usbd_cdc_if_template.c new file mode 100644 index 0000000000..22374142a7 --- /dev/null +++ b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/CDC/Src/usbd_cdc_if_template.c @@ -0,0 +1,246 @@ +/** + ****************************************************************************** + * @file usbd_cdc_if_template.c + * @author MCD Application Team + * @version V2.4.2 + * @date 11-December-2015 + * @brief Generic media access Layer. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_cdc_if_template.h" + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup USBD_CDC + * @brief usbd core module + * @{ + */ + +/** @defgroup USBD_CDC_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_CDC_Private_Defines + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_CDC_Private_Macros + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_CDC_Private_FunctionPrototypes + * @{ + */ + +static int8_t TEMPLATE_Init (void); +static int8_t TEMPLATE_DeInit (void); +static int8_t TEMPLATE_Control (uint8_t cmd, uint8_t* pbuf, uint16_t length); +static int8_t TEMPLATE_Receive (uint8_t* pbuf, uint32_t *Len); + +USBD_CDC_ItfTypeDef USBD_CDC_Template_fops = +{ + TEMPLATE_Init, + TEMPLATE_DeInit, + TEMPLATE_Control, + TEMPLATE_Receive +}; + +USBD_CDC_LineCodingTypeDef linecoding = + { + 115200, /* baud rate*/ + 0x00, /* stop bits-1*/ + 0x00, /* parity - none*/ + 0x08 /* nb. of bits 8*/ + }; + +/* Private functions ---------------------------------------------------------*/ + +/** + * @brief TEMPLATE_Init + * Initializes the CDC media low layer + * @param None + * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t TEMPLATE_Init(void) +{ + /* + Add your initialization code here + */ + return (0); +} + +/** + * @brief TEMPLATE_DeInit + * DeInitializes the CDC media low layer + * @param None + * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t TEMPLATE_DeInit(void) +{ + /* + Add your deinitialization code here + */ + return (0); +} + + +/** + * @brief TEMPLATE_Control + * Manage the CDC class requests + * @param Cmd: Command code + * @param Buf: Buffer containing command data (request parameters) + * @param Len: Number of data to be sent (in bytes) + * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t TEMPLATE_Control (uint8_t cmd, uint8_t* pbuf, uint16_t length) +{ + switch (cmd) + { + case CDC_SEND_ENCAPSULATED_COMMAND: + /* Add your code here */ + break; + + case CDC_GET_ENCAPSULATED_RESPONSE: + /* Add your code here */ + break; + + case CDC_SET_COMM_FEATURE: + /* Add your code here */ + break; + + case CDC_GET_COMM_FEATURE: + /* Add your code here */ + break; + + case CDC_CLEAR_COMM_FEATURE: + /* Add your code here */ + break; + + case CDC_SET_LINE_CODING: + linecoding.bitrate = (uint32_t)(pbuf[0] | (pbuf[1] << 8) |\ + (pbuf[2] << 16) | (pbuf[3] << 24)); + linecoding.format = pbuf[4]; + linecoding.paritytype = pbuf[5]; + linecoding.datatype = pbuf[6]; + + /* Add your code here */ + break; + + case CDC_GET_LINE_CODING: + pbuf[0] = (uint8_t)(linecoding.bitrate); + pbuf[1] = (uint8_t)(linecoding.bitrate >> 8); + pbuf[2] = (uint8_t)(linecoding.bitrate >> 16); + pbuf[3] = (uint8_t)(linecoding.bitrate >> 24); + pbuf[4] = linecoding.format; + pbuf[5] = linecoding.paritytype; + pbuf[6] = linecoding.datatype; + + /* Add your code here */ + break; + + case CDC_SET_CONTROL_LINE_STATE: + /* Add your code here */ + break; + + case CDC_SEND_BREAK: + /* Add your code here */ + break; + + default: + break; + } + + return (0); +} + +/** + * @brief TEMPLATE_Receive + * Data received over USB OUT endpoint are sent over CDC interface + * through this function. + * + * @note + * This function will issue a NAK packet on any OUT packet received on + * USB endpoint untill exiting this function. If you exit this function + * before transfer is complete on CDC interface (ie. using DMA controller) + * it will result in receiving more data while previous ones are still + * not sent. + * + * @param Buf: Buffer of data to be received + * @param Len: Number of data received (in bytes) + * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t TEMPLATE_Receive (uint8_t* Buf, uint32_t *Len) +{ + + return (0); +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/platform/mcu/stm32l475/Middlewares/USB_Device/Class/CustomHID/Inc/usbd_customhid.h b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/CustomHID/Inc/usbd_customhid.h new file mode 100644 index 0000000000..1c42e1a104 --- /dev/null +++ b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/CustomHID/Inc/usbd_customhid.h @@ -0,0 +1,180 @@ +/** + ****************************************************************************** + * @file usbd_customhid.h + * @author MCD Application Team + * @version V2.4.2 + * @date 11-December-2015 + * @brief header file for the usbd_customhid.c file. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USB_CUSTOMHID_H +#define __USB_CUSTOMHID_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_ioreq.h" + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USBD_CUSTOM_HID + * @brief This file is the Header file for USBD_customhid.c + * @{ + */ + + +/** @defgroup USBD_CUSTOM_HID_Exported_Defines + * @{ + */ +#define CUSTOM_HID_EPIN_ADDR 0x81 +#define CUSTOM_HID_EPIN_SIZE 0x02 + +#define CUSTOM_HID_EPOUT_ADDR 0x01 +#define CUSTOM_HID_EPOUT_SIZE 0x02 + +#define USB_CUSTOM_HID_CONFIG_DESC_SIZ 41 +#define USB_CUSTOM_HID_DESC_SIZ 9 + +#define CUSTOM_HID_DESCRIPTOR_TYPE 0x21 +#define CUSTOM_HID_REPORT_DESC 0x22 + + +#define CUSTOM_HID_REQ_SET_PROTOCOL 0x0B +#define CUSTOM_HID_REQ_GET_PROTOCOL 0x03 + +#define CUSTOM_HID_REQ_SET_IDLE 0x0A +#define CUSTOM_HID_REQ_GET_IDLE 0x02 + +#define CUSTOM_HID_REQ_SET_REPORT 0x09 +#define CUSTOM_HID_REQ_GET_REPORT 0x01 +/** + * @} + */ + + +/** @defgroup USBD_CORE_Exported_TypesDefinitions + * @{ + */ +typedef enum +{ + CUSTOM_HID_IDLE = 0, + CUSTOM_HID_BUSY, +} +CUSTOM_HID_StateTypeDef; + +typedef struct _USBD_CUSTOM_HID_Itf +{ + uint8_t *pReport; + int8_t (* Init) (void); + int8_t (* DeInit) (void); + int8_t (* OutEvent) (uint8_t, uint8_t ); + +}USBD_CUSTOM_HID_ItfTypeDef; + +typedef struct +{ + uint8_t Report_buf[USBD_CUSTOMHID_OUTREPORT_BUF_SIZE]; + uint32_t Protocol; + uint32_t IdleState; + uint32_t AltSetting; + uint32_t IsReportAvailable; + CUSTOM_HID_StateTypeDef state; +} +USBD_CUSTOM_HID_HandleTypeDef; +/** + * @} + */ + + + +/** @defgroup USBD_CORE_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_CORE_Exported_Variables + * @{ + */ + +extern USBD_ClassTypeDef USBD_CUSTOM_HID; +#define USBD_CUSTOM_HID_CLASS &USBD_CUSTOM_HID +/** + * @} + */ + +/** @defgroup USB_CORE_Exported_Functions + * @{ + */ +uint8_t USBD_CUSTOM_HID_SendReport (USBD_HandleTypeDef *pdev, + uint8_t *report, + uint16_t len); + + + +uint8_t USBD_CUSTOM_HID_RegisterInterface (USBD_HandleTypeDef *pdev, + USBD_CUSTOM_HID_ItfTypeDef *fops); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_CUSTOMHID_H */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/platform/mcu/stm32l475/Middlewares/USB_Device/Class/CustomHID/Inc/usbd_customhid_if_template.h b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/CustomHID/Inc/usbd_customhid_if_template.h new file mode 100644 index 0000000000..c49803f7d0 --- /dev/null +++ b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/CustomHID/Inc/usbd_customhid_if_template.h @@ -0,0 +1,71 @@ +/** + ****************************************************************************** + * @file usbd_customhid_if_template.h + * @author MCD Application Team + * @version V2.4.2 + * @date 11-December-2015 + * @brief Header for usbd_customhid_if_template.c file. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBD_CUSTOMHID_IF_TEMPLATE_H +#define __USBD_CUSTOMHID_IF_TEMPLATE_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_customhid.h" + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ +extern USBD_CUSTOM_HID_ItfTypeDef USBD_CustomHID_template_fops; + +#ifdef __cplusplus +} +#endif + +#endif /* __USBD_CUSTOMHID_IF_TEMPLATE_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/platform/mcu/stm32l475/Middlewares/USB_Device/Class/CustomHID/Src/usbd_customhid.c b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/CustomHID/Src/usbd_customhid.c new file mode 100644 index 0000000000..9c71fc55a9 --- /dev/null +++ b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/CustomHID/Src/usbd_customhid.c @@ -0,0 +1,556 @@ +/** + ****************************************************************************** + * @file usbd_customhid.c + * @author MCD Application Team + * @version V2.4.2 + * @date 11-December-2015 + * @brief This file provides the CUSTOM_HID core functions. + * + * @verbatim + * + * =================================================================== + * CUSTOM_HID Class Description + * =================================================================== + * This module manages the CUSTOM_HID class V1.11 following the "Device Class Definition + * for Human Interface Devices (CUSTOM_HID) Version 1.11 Jun 27, 2001". + * This driver implements the following aspects of the specification: + * - The Boot Interface Subclass + * - Usage Page : Generic Desktop + * - Usage : Vendor + * - Collection : Application + * + * @note In HS mode and when the DMA is used, all variables and data structures + * dealing with the DMA during the transaction process should be 32-bit aligned. + * + * + * @endverbatim + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_customhid.h" +#include "usbd_desc.h" +#include "usbd_ctlreq.h" + + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup USBD_CUSTOM_HID + * @brief usbd core module + * @{ + */ + +/** @defgroup USBD_CUSTOM_HID_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_CUSTOM_HID_Private_Defines + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_CUSTOM_HID_Private_Macros + * @{ + */ +/** + * @} + */ +/** @defgroup USBD_CUSTOM_HID_Private_FunctionPrototypes + * @{ + */ + + +static uint8_t USBD_CUSTOM_HID_Init (USBD_HandleTypeDef *pdev, + uint8_t cfgidx); + +static uint8_t USBD_CUSTOM_HID_DeInit (USBD_HandleTypeDef *pdev, + uint8_t cfgidx); + +static uint8_t USBD_CUSTOM_HID_Setup (USBD_HandleTypeDef *pdev, + USBD_SetupReqTypedef *req); + +static uint8_t *USBD_CUSTOM_HID_GetCfgDesc (uint16_t *length); + +static uint8_t *USBD_CUSTOM_HID_GetDeviceQualifierDesc (uint16_t *length); + +static uint8_t USBD_CUSTOM_HID_DataIn (USBD_HandleTypeDef *pdev, uint8_t epnum); + +static uint8_t USBD_CUSTOM_HID_DataOut (USBD_HandleTypeDef *pdev, uint8_t epnum); +static uint8_t USBD_CUSTOM_HID_EP0_RxReady (USBD_HandleTypeDef *pdev); +/** + * @} + */ + +/** @defgroup USBD_CUSTOM_HID_Private_Variables + * @{ + */ + +USBD_ClassTypeDef USBD_CUSTOM_HID = +{ + USBD_CUSTOM_HID_Init, + USBD_CUSTOM_HID_DeInit, + USBD_CUSTOM_HID_Setup, + NULL, /*EP0_TxSent*/ + USBD_CUSTOM_HID_EP0_RxReady, /*EP0_RxReady*/ /* STATUS STAGE IN */ + USBD_CUSTOM_HID_DataIn, /*DataIn*/ + USBD_CUSTOM_HID_DataOut, + NULL, /*SOF */ + NULL, + NULL, + USBD_CUSTOM_HID_GetCfgDesc, + USBD_CUSTOM_HID_GetCfgDesc, + USBD_CUSTOM_HID_GetCfgDesc, + USBD_CUSTOM_HID_GetDeviceQualifierDesc, +}; + +/* USB CUSTOM_HID device Configuration Descriptor */ +__ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_CfgDesc[USB_CUSTOM_HID_CONFIG_DESC_SIZ] __ALIGN_END = +{ + 0x09, /* bLength: Configuration Descriptor size */ + USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ + USB_CUSTOM_HID_CONFIG_DESC_SIZ, + /* wTotalLength: Bytes returned */ + 0x00, + 0x01, /*bNumInterfaces: 1 interface*/ + 0x01, /*bConfigurationValue: Configuration value*/ + 0x00, /*iConfiguration: Index of string descriptor describing + the configuration*/ + 0xC0, /*bmAttributes: bus powered */ + 0x32, /*MaxPower 100 mA: this current is used for detecting Vbus*/ + + /************** Descriptor of CUSTOM HID interface ****************/ + /* 09 */ + 0x09, /*bLength: Interface Descriptor size*/ + USB_DESC_TYPE_INTERFACE,/*bDescriptorType: Interface descriptor type*/ + 0x00, /*bInterfaceNumber: Number of Interface*/ + 0x00, /*bAlternateSetting: Alternate setting*/ + 0x02, /*bNumEndpoints*/ + 0x03, /*bInterfaceClass: CUSTOM_HID*/ + 0x00, /*bInterfaceSubClass : 1=BOOT, 0=no boot*/ + 0x00, /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/ + 0, /*iInterface: Index of string descriptor*/ + /******************** Descriptor of CUSTOM_HID *************************/ + /* 18 */ + 0x09, /*bLength: CUSTOM_HID Descriptor size*/ + CUSTOM_HID_DESCRIPTOR_TYPE, /*bDescriptorType: CUSTOM_HID*/ + 0x11, /*bCUSTOM_HIDUSTOM_HID: CUSTOM_HID Class Spec release number*/ + 0x01, + 0x00, /*bCountryCode: Hardware target country*/ + 0x01, /*bNumDescriptors: Number of CUSTOM_HID class descriptors to follow*/ + 0x22, /*bDescriptorType*/ + USBD_CUSTOM_HID_REPORT_DESC_SIZE,/*wItemLength: Total length of Report descriptor*/ + 0x00, + /******************** Descriptor of Custom HID endpoints ********************/ + /* 27 */ + 0x07, /*bLength: Endpoint Descriptor size*/ + USB_DESC_TYPE_ENDPOINT, /*bDescriptorType:*/ + + CUSTOM_HID_EPIN_ADDR, /*bEndpointAddress: Endpoint Address (IN)*/ + 0x03, /*bmAttributes: Interrupt endpoint*/ + CUSTOM_HID_EPIN_SIZE, /*wMaxPacketSize: 2 Byte max */ + 0x00, + 0x20, /*bInterval: Polling Interval (20 ms)*/ + /* 34 */ + + 0x07, /* bLength: Endpoint Descriptor size */ + USB_DESC_TYPE_ENDPOINT, /* bDescriptorType: */ + CUSTOM_HID_EPOUT_ADDR, /*bEndpointAddress: Endpoint Address (OUT)*/ + 0x03, /* bmAttributes: Interrupt endpoint */ + CUSTOM_HID_EPOUT_SIZE, /* wMaxPacketSize: 2 Bytes max */ + 0x00, + 0x20, /* bInterval: Polling Interval (20 ms) */ + /* 41 */ +} ; + +/* USB CUSTOM_HID device Configuration Descriptor */ +__ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_Desc[USB_CUSTOM_HID_DESC_SIZ] __ALIGN_END = +{ + /* 18 */ + 0x09, /*bLength: CUSTOM_HID Descriptor size*/ + CUSTOM_HID_DESCRIPTOR_TYPE, /*bDescriptorType: CUSTOM_HID*/ + 0x11, /*bCUSTOM_HIDUSTOM_HID: CUSTOM_HID Class Spec release number*/ + 0x01, + 0x00, /*bCountryCode: Hardware target country*/ + 0x01, /*bNumDescriptors: Number of CUSTOM_HID class descriptors to follow*/ + 0x22, /*bDescriptorType*/ + USBD_CUSTOM_HID_REPORT_DESC_SIZE,/*wItemLength: Total length of Report descriptor*/ + 0x00, +}; + +/* USB Standard Device Descriptor */ +__ALIGN_BEGIN static uint8_t USBD_CUSTOM_HID_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = +{ + USB_LEN_DEV_QUALIFIER_DESC, + USB_DESC_TYPE_DEVICE_QUALIFIER, + 0x00, + 0x02, + 0x00, + 0x00, + 0x00, + 0x40, + 0x01, + 0x00, +}; + +/** + * @} + */ + +/** @defgroup USBD_CUSTOM_HID_Private_Functions + * @{ + */ + +/** + * @brief USBD_CUSTOM_HID_Init + * Initialize the CUSTOM_HID interface + * @param pdev: device instance + * @param cfgidx: Configuration index + * @retval status + */ +static uint8_t USBD_CUSTOM_HID_Init (USBD_HandleTypeDef *pdev, + uint8_t cfgidx) +{ + uint8_t ret = 0; + USBD_CUSTOM_HID_HandleTypeDef *hhid; + /* Open EP IN */ + USBD_LL_OpenEP(pdev, + CUSTOM_HID_EPIN_ADDR, + USBD_EP_TYPE_INTR, + CUSTOM_HID_EPIN_SIZE); + + /* Open EP OUT */ + USBD_LL_OpenEP(pdev, + CUSTOM_HID_EPOUT_ADDR, + USBD_EP_TYPE_INTR, + CUSTOM_HID_EPOUT_SIZE); + + pdev->pClassData = USBD_malloc(sizeof (USBD_CUSTOM_HID_HandleTypeDef)); + + if(pdev->pClassData == NULL) + { + ret = 1; + } + else + { + hhid = (USBD_CUSTOM_HID_HandleTypeDef*) pdev->pClassData; + + hhid->state = CUSTOM_HID_IDLE; + ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData)->Init(); + /* Prepare Out endpoint to receive 1st packet */ + USBD_LL_PrepareReceive(pdev, CUSTOM_HID_EPOUT_ADDR, hhid->Report_buf, + USBD_CUSTOMHID_OUTREPORT_BUF_SIZE); + } + + return ret; +} + +/** + * @brief USBD_CUSTOM_HID_Init + * DeInitialize the CUSTOM_HID layer + * @param pdev: device instance + * @param cfgidx: Configuration index + * @retval status + */ +static uint8_t USBD_CUSTOM_HID_DeInit (USBD_HandleTypeDef *pdev, + uint8_t cfgidx) +{ + /* Close CUSTOM_HID EP IN */ + USBD_LL_CloseEP(pdev, + CUSTOM_HID_EPIN_ADDR); + + /* Close CUSTOM_HID EP OUT */ + USBD_LL_CloseEP(pdev, + CUSTOM_HID_EPOUT_ADDR); + + /* FRee allocated memory */ + if(pdev->pClassData != NULL) + { + ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData)->DeInit(); + USBD_free(pdev->pClassData); + pdev->pClassData = NULL; + } + return USBD_OK; +} + +/** + * @brief USBD_CUSTOM_HID_Setup + * Handle the CUSTOM_HID specific requests + * @param pdev: instance + * @param req: usb requests + * @retval status + */ +static uint8_t USBD_CUSTOM_HID_Setup (USBD_HandleTypeDef *pdev, + USBD_SetupReqTypedef *req) +{ + uint16_t len = 0; + uint8_t *pbuf = NULL; + USBD_CUSTOM_HID_HandleTypeDef *hhid = (USBD_CUSTOM_HID_HandleTypeDef*)pdev->pClassData; + + switch (req->bmRequest & USB_REQ_TYPE_MASK) + { + case USB_REQ_TYPE_CLASS : + switch (req->bRequest) + { + + + case CUSTOM_HID_REQ_SET_PROTOCOL: + hhid->Protocol = (uint8_t)(req->wValue); + break; + + case CUSTOM_HID_REQ_GET_PROTOCOL: + USBD_CtlSendData (pdev, + (uint8_t *)&hhid->Protocol, + 1); + break; + + case CUSTOM_HID_REQ_SET_IDLE: + hhid->IdleState = (uint8_t)(req->wValue >> 8); + break; + + case CUSTOM_HID_REQ_GET_IDLE: + USBD_CtlSendData (pdev, + (uint8_t *)&hhid->IdleState, + 1); + break; + + case CUSTOM_HID_REQ_SET_REPORT: + hhid->IsReportAvailable = 1; + USBD_CtlPrepareRx (pdev, hhid->Report_buf, (uint8_t)(req->wLength)); + + break; + default: + USBD_CtlError (pdev, req); + return USBD_FAIL; + } + break; + + case USB_REQ_TYPE_STANDARD: + switch (req->bRequest) + { + case USB_REQ_GET_DESCRIPTOR: + if( req->wValue >> 8 == CUSTOM_HID_REPORT_DESC) + { + len = MIN(USBD_CUSTOM_HID_REPORT_DESC_SIZE , req->wLength); + pbuf = ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData)->pReport; + } + else if( req->wValue >> 8 == CUSTOM_HID_DESCRIPTOR_TYPE) + { + pbuf = USBD_CUSTOM_HID_Desc; + len = MIN(USB_CUSTOM_HID_DESC_SIZ , req->wLength); + } + + USBD_CtlSendData (pdev, + pbuf, + len); + + break; + + case USB_REQ_GET_INTERFACE : + USBD_CtlSendData (pdev, + (uint8_t *)&hhid->AltSetting, + 1); + break; + + case USB_REQ_SET_INTERFACE : + hhid->AltSetting = (uint8_t)(req->wValue); + break; + } + } + return USBD_OK; +} + +/** + * @brief USBD_CUSTOM_HID_SendReport + * Send CUSTOM_HID Report + * @param pdev: device instance + * @param buff: pointer to report + * @retval status + */ +uint8_t USBD_CUSTOM_HID_SendReport (USBD_HandleTypeDef *pdev, + uint8_t *report, + uint16_t len) +{ + USBD_CUSTOM_HID_HandleTypeDef *hhid = (USBD_CUSTOM_HID_HandleTypeDef*)pdev->pClassData; + + if (pdev->dev_state == USBD_STATE_CONFIGURED ) + { + if(hhid->state == CUSTOM_HID_IDLE) + { + hhid->state = CUSTOM_HID_BUSY; + USBD_LL_Transmit (pdev, + CUSTOM_HID_EPIN_ADDR, + report, + len); + } + } + return USBD_OK; +} + +/** + * @brief USBD_CUSTOM_HID_GetCfgDesc + * return configuration descriptor + * @param speed : current device speed + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +static uint8_t *USBD_CUSTOM_HID_GetCfgDesc (uint16_t *length) +{ + *length = sizeof (USBD_CUSTOM_HID_CfgDesc); + return USBD_CUSTOM_HID_CfgDesc; +} + +/** + * @brief USBD_CUSTOM_HID_DataIn + * handle data IN Stage + * @param pdev: device instance + * @param epnum: endpoint index + * @retval status + */ +static uint8_t USBD_CUSTOM_HID_DataIn (USBD_HandleTypeDef *pdev, + uint8_t epnum) +{ + + /* Ensure that the FIFO is empty before a new transfer, this condition could + be caused by a new transfer before the end of the previous transfer */ + ((USBD_CUSTOM_HID_HandleTypeDef *)pdev->pClassData)->state = CUSTOM_HID_IDLE; + + return USBD_OK; +} + +/** + * @brief USBD_CUSTOM_HID_DataOut + * handle data OUT Stage + * @param pdev: device instance + * @param epnum: endpoint index + * @retval status + */ +static uint8_t USBD_CUSTOM_HID_DataOut (USBD_HandleTypeDef *pdev, + uint8_t epnum) +{ + + USBD_CUSTOM_HID_HandleTypeDef *hhid = (USBD_CUSTOM_HID_HandleTypeDef*)pdev->pClassData; + + ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData)->OutEvent(hhid->Report_buf[0], + hhid->Report_buf[1]); + + USBD_LL_PrepareReceive(pdev, CUSTOM_HID_EPOUT_ADDR , hhid->Report_buf, + USBD_CUSTOMHID_OUTREPORT_BUF_SIZE); + + return USBD_OK; +} + +/** + * @brief USBD_CUSTOM_HID_EP0_RxReady + * Handles control request data. + * @param pdev: device instance + * @retval status + */ +uint8_t USBD_CUSTOM_HID_EP0_RxReady(USBD_HandleTypeDef *pdev) +{ + USBD_CUSTOM_HID_HandleTypeDef *hhid = (USBD_CUSTOM_HID_HandleTypeDef*)pdev->pClassData; + + if (hhid->IsReportAvailable == 1) + { + ((USBD_CUSTOM_HID_ItfTypeDef *)pdev->pUserData)->OutEvent(hhid->Report_buf[0], + hhid->Report_buf[1]); + hhid->IsReportAvailable = 0; + } + + return USBD_OK; +} + +/** +* @brief DeviceQualifierDescriptor +* return Device Qualifier descriptor +* @param length : pointer data length +* @retval pointer to descriptor buffer +*/ +static uint8_t *USBD_CUSTOM_HID_GetDeviceQualifierDesc (uint16_t *length) +{ + *length = sizeof (USBD_CUSTOM_HID_DeviceQualifierDesc); + return USBD_CUSTOM_HID_DeviceQualifierDesc; +} + +/** +* @brief USBD_CUSTOM_HID_RegisterInterface + * @param pdev: device instance + * @param fops: CUSTOMHID Interface callback + * @retval status + */ +uint8_t USBD_CUSTOM_HID_RegisterInterface (USBD_HandleTypeDef *pdev, + USBD_CUSTOM_HID_ItfTypeDef *fops) +{ + uint8_t ret = USBD_FAIL; + + if(fops != NULL) + { + pdev->pUserData= fops; + ret = USBD_OK; + } + + return ret; +} +/** + * @} + */ + + +/** + * @} + */ + + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/platform/mcu/stm32l475/Middlewares/USB_Device/Class/CustomHID/Src/usbd_customhid_if_template.c b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/CustomHID/Src/usbd_customhid_if_template.c new file mode 100644 index 0000000000..34faaca847 --- /dev/null +++ b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/CustomHID/Src/usbd_customhid_if_template.c @@ -0,0 +1,110 @@ +/** + ****************************************************************************** + * @file usbd_customhid_if_template.c + * @author MCD Application Team + * @version V2.4.2 + * @date 11-December-2015 + * @brief USB Device Custom HID interface file. + * This template should be copied to the user folder, renamed and customized + * following user needs. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_customhid_if_template.h" +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ + +static int8_t TEMPLATE_CUSTOM_HID_Init (void); +static int8_t TEMPLATE_CUSTOM_HID_DeInit (void); +static int8_t TEMPLATE_CUSTOM_HID_OutEvent (uint8_t event_idx, uint8_t state); +/* Private variables ---------------------------------------------------------*/ +USBD_CUSTOM_HID_ItfTypeDef USBD_CustomHID_template_fops = +{ + TEMPLATE_CUSTOM_HID_ReportDesc, + TEMPLATE_CUSTOM_HID_Init, + TEMPLATE_CUSTOM_HID_DeInit, + TEMPLATE_CUSTOM_HID_OutEvent, +}; + +/* Private functions ---------------------------------------------------------*/ + +/** + * @brief TEMPLATE_CUSTOM_HID_Init + * Initializes the CUSTOM HID media low layer + * @param None + * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t TEMPLATE_CUSTOM_HID_Init(void) +{ + + return (0); +} + +/** + * @brief TEMPLATE_CUSTOM_HID_DeInit + * DeInitializes the CUSTOM HID media low layer + * @param None + * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t TEMPLATE_CUSTOM_HID_DeInit(void) +{ + /* + Add your deinitialization code here + */ + return (0); +} + + +/** + * @brief TEMPLATE_CUSTOM_HID_Control + * Manage the CUSTOM HID class events + * @param event_idx: event index + * @param state: event state + * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL + */ +static int8_t TEMPLATE_CUSTOM_HID_OutEvent (uint8_t event_idx, uint8_t state) +{ + + return (0); +} +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/platform/mcu/stm32l475/Middlewares/USB_Device/Class/DFU/Inc/usbd_dfu.h b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/DFU/Inc/usbd_dfu.h new file mode 100644 index 0000000000..9074baf723 --- /dev/null +++ b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/DFU/Inc/usbd_dfu.h @@ -0,0 +1,255 @@ +/** + ****************************************************************************** + * @file usbd_dfu.h + * @author MCD Application Team + * @version V2.4.2 + * @date 11-December-2015 + * @brief Header file for the usbd_dfu.c file. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USB_DFU_H +#define __USB_DFU_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_ioreq.h" + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USBD_DFU + * @brief This file is the Header file for usbd_dfu.c + * @{ + */ + + +/** @defgroup USBD_DFU_Exported_Defines + * @{ + */ + +#define USB_DFU_CONFIG_DESC_SIZ (18 + (9 * USBD_DFU_MAX_ITF_NUM)) +#define USB_DFU_DESC_SIZ 9 + +#define DFU_DESCRIPTOR_TYPE 0x21 + + +/**************************************************/ +/* DFU Requests DFU states */ +/**************************************************/ +#define APP_STATE_IDLE 0 +#define APP_STATE_DETACH 1 +#define DFU_STATE_IDLE 2 +#define DFU_STATE_DNLOAD_SYNC 3 +#define DFU_STATE_DNLOAD_BUSY 4 +#define DFU_STATE_DNLOAD_IDLE 5 +#define DFU_STATE_MANIFEST_SYNC 6 +#define DFU_STATE_MANIFEST 7 +#define DFU_STATE_MANIFEST_WAIT_RESET 8 +#define DFU_STATE_UPLOAD_IDLE 9 +#define DFU_STATE_ERROR 10 + +/**************************************************/ +/* DFU errors */ +/**************************************************/ +#define DFU_ERROR_NONE 0x00 +#define DFU_ERROR_TARGET 0x01 +#define DFU_ERROR_FILE 0x02 +#define DFU_ERROR_WRITE 0x03 +#define DFU_ERROR_ERASE 0x04 +#define DFU_ERROR_CHECK_ERASED 0x05 +#define DFU_ERROR_PROG 0x06 +#define DFU_ERROR_VERIFY 0x07 +#define DFU_ERROR_ADDRESS 0x08 +#define DFU_ERROR_NOTDONE 0x09 +#define DFU_ERROR_FIRMWARE 0x0A +#define DFU_ERROR_VENDOR 0x0B +#define DFU_ERROR_USB 0x0C +#define DFU_ERROR_POR 0x0D +#define DFU_ERROR_UNKNOWN 0x0E +#define DFU_ERROR_STALLEDPKT 0x0F + +/**************************************************/ +/* DFU Manifestation State */ +/**************************************************/ +#define DFU_MANIFEST_COMPLETE 0x00 +#define DFU_MANIFEST_IN_PROGRESS 0x01 + + +/**************************************************/ +/* Special Commands with Download Request */ +/**************************************************/ +#define DFU_CMD_GETCOMMANDS 0x00 +#define DFU_CMD_SETADDRESSPOINTER 0x21 +#define DFU_CMD_ERASE 0x41 + +#define DFU_MEDIA_ERASE 0x00 +#define DFU_MEDIA_PROGRAM 0x01 + +/**************************************************/ +/* Other defines */ +/**************************************************/ +/* Bit Detach capable = bit 3 in bmAttributes field */ +#define DFU_DETACH_MASK (uint8_t)(1 << 4) +#define DFU_STATUS_DEPTH (6) + +typedef enum +{ + DFU_DETACH = 0, + DFU_DNLOAD , + DFU_UPLOAD, + DFU_GETSTATUS, + DFU_CLRSTATUS, + DFU_GETSTATE, + DFU_ABORT +} DFU_RequestTypeDef; + +typedef void (*pFunction)(void); + + +/********** Descriptor of DFU interface 0 Alternate setting n ****************/ +#define USBD_DFU_IF_DESC(n) 0x09, /* bLength: Interface Descriptor size */ \ + USB_DESC_TYPE_INTERFACE, /* bDescriptorType */ \ + 0x00, /* bInterfaceNumber: Number of Interface */ \ + (n), /* bAlternateSetting: Alternate setting */ \ + 0x00, /* bNumEndpoints*/ \ + 0xFE, /* bInterfaceClass: Application Specific Class Code */ \ + 0x01, /* bInterfaceSubClass : Device Firmware Upgrade Code */ \ + 0x02, /* nInterfaceProtocol: DFU mode protocol */ \ + USBD_IDX_INTERFACE_STR + (n) + 1 /* iInterface: Index of string descriptor */ \ + +#define TRANSFER_SIZE_BYTES(size) ((uint8_t)(size)), /* XFERSIZEB0 */\ + ((uint8_t)(size >> 8)) /* XFERSIZEB1 */ + +#define IS_PROTECTED_AREA(add) (uint8_t)(((add >= 0x08000000) && (add < (APP_DEFAULT_ADD)))? 1:0) + +/** + * @} + */ + + +/** @defgroup USBD_CORE_Exported_TypesDefinitions + * @{ + */ + +typedef struct +{ + union + { + uint32_t d32[USBD_DFU_XFER_SIZE/4]; + uint8_t d8[USBD_DFU_XFER_SIZE]; + }buffer; + + uint8_t dev_state; + uint8_t dev_status[DFU_STATUS_DEPTH]; + uint8_t manif_state; + + uint32_t wblock_num; + uint32_t wlength; + uint32_t data_ptr; + __IO uint32_t alt_setting; + +} +USBD_DFU_HandleTypeDef; + + +typedef struct +{ + const uint8_t* pStrDesc; + uint16_t (* Init) (void); + uint16_t (* DeInit) (void); + uint16_t (* Erase) (uint32_t Add); + uint16_t (* Write) (uint8_t *src, uint8_t *dest, uint32_t Len); + uint8_t* (* Read) (uint8_t *src, uint8_t *dest, uint32_t Len); + uint16_t (* GetStatus)(uint32_t Add, uint8_t cmd, uint8_t *buff); +} +USBD_DFU_MediaTypeDef; +/** + * @} + */ + + + +/** @defgroup USBD_CORE_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_CORE_Exported_Variables + * @{ + */ + +extern USBD_ClassTypeDef USBD_DFU; +#define USBD_DFU_CLASS &USBD_DFU +/** + * @} + */ + +/** @defgroup USB_CORE_Exported_Functions + * @{ + */ +uint8_t USBD_DFU_RegisterMedia (USBD_HandleTypeDef *pdev, + USBD_DFU_MediaTypeDef *fops); +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_DFU_H */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/platform/mcu/stm32l475/Middlewares/USB_Device/Class/DFU/Inc/usbd_dfu_media_template.h b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/DFU/Inc/usbd_dfu_media_template.h new file mode 100644 index 0000000000..e503c40100 --- /dev/null +++ b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/DFU/Inc/usbd_dfu_media_template.h @@ -0,0 +1,125 @@ +/** + ****************************************************************************** + * @file usbd_dfu_media_template.h + * @author MCD Application Team + * @version V2.4.2 + * @date 11-December-2015 + * @brief header file for the usbd_dfu_media_template.c file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBD_DFU_MEDIA_TEMPLATE_H +#define __USBD_DFU_MEDIA_TEMPLATE_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_dfu.h" + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USBD_MEDIA + * @brief header file for the usbd_dfu_media_template.c file + * @{ + */ + +/** @defgroup USBD_MEDIA_Exported_Defines + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_MEDIA_Exported_Types + * @{ + */ + + +/** + * @} + */ + + + +/** @defgroup USBD_MEDIA_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_MEDIA_Exported_Variables + * @{ + */ +extern USBD_DFU_MediaTypeDef USBD_DFU_MEDIA_Template_fops; +/** + * @} + */ + +/** @defgroup USBD_MEDIA_Exported_FunctionsPrototype + * @{ + */ + + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USBD_DFU_MEDIA_TEMPLATE_H */ + +/** + * @} + */ + +/** +* @} +*/ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/platform/mcu/stm32l475/Middlewares/USB_Device/Class/DFU/Src/usbd_dfu.c b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/DFU/Src/usbd_dfu.c new file mode 100644 index 0000000000..4d65896c1b --- /dev/null +++ b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/DFU/Src/usbd_dfu.c @@ -0,0 +1,1127 @@ +/** + ****************************************************************************** + * @file usbd_dfu.c + * @author MCD Application Team + * @version V2.4.2 + * @date 11-December-2015 + * @brief This file provides the DFU core functions. + * + * @verbatim + * + * =================================================================== + * DFU Class Driver Description + * =================================================================== + * This driver manages the DFU class V1.1 following the "Device Class Specification for + * Device Firmware Upgrade Version 1.1 Aug 5, 2004". + * This driver implements the following aspects of the specification: + * - Device descriptor management + * - Configuration descriptor management + * - Enumeration as DFU device (in DFU mode only) + * - Requests management (supporting ST DFU sub-protocol) + * - Memory operations management (Download/Upload/Erase/Detach/GetState/GetStatus) + * - DFU state machine implementation. + * + * @note + * ST DFU sub-protocol is compliant with DFU protocol and use sub-requests to manage + * memory addressing, commands processing, specific memories operations (ie. Erase) ... + * As required by the DFU specification, only endpoint 0 is used in this application. + * Other endpoints and functions may be added to the application (ie. DFU ...) + * + * These aspects may be enriched or modified for a specific user application. + * + * This driver doesn't implement the following aspects of the specification + * (but it is possible to manage these features with some modifications on this driver): + * - Manifestation Tolerant mode + * + * @endverbatim + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_dfu.h" +#include "usbd_desc.h" +#include "usbd_ctlreq.h" + + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup USBD_DFU + * @brief usbd core module + * @{ + */ + +/** @defgroup USBD_DFU_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_DFU_Private_Defines + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_DFU_Private_Macros + * @{ + */ +#define DFU_SAMPLE_FREQ(frq) (uint8_t)(frq), (uint8_t)((frq >> 8)), (uint8_t)((frq >> 16)) + +#define DFU_PACKET_SZE(frq) (uint8_t)(((frq * 2 * 2)/1000) & 0xFF), \ + (uint8_t)((((frq * 2 * 2)/1000) >> 8) & 0xFF) + +/** + * @} + */ + + + + +/** @defgroup USBD_DFU_Private_FunctionPrototypes + * @{ + */ + + +static uint8_t USBD_DFU_Init (USBD_HandleTypeDef *pdev, + uint8_t cfgidx); + +static uint8_t USBD_DFU_DeInit (USBD_HandleTypeDef *pdev, + uint8_t cfgidx); + +static uint8_t USBD_DFU_Setup (USBD_HandleTypeDef *pdev, + USBD_SetupReqTypedef *req); + +static uint8_t *USBD_DFU_GetCfgDesc (uint16_t *length); + +static uint8_t *USBD_DFU_GetDeviceQualifierDesc (uint16_t *length); + +static uint8_t USBD_DFU_DataIn (USBD_HandleTypeDef *pdev, uint8_t epnum); + +static uint8_t USBD_DFU_DataOut (USBD_HandleTypeDef *pdev, uint8_t epnum); + +static uint8_t USBD_DFU_EP0_RxReady (USBD_HandleTypeDef *pdev); + +static uint8_t USBD_DFU_EP0_TxReady (USBD_HandleTypeDef *pdev); + +static uint8_t USBD_DFU_SOF (USBD_HandleTypeDef *pdev); + +static uint8_t USBD_DFU_IsoINIncomplete (USBD_HandleTypeDef *pdev, uint8_t epnum); + +static uint8_t USBD_DFU_IsoOutIncomplete (USBD_HandleTypeDef *pdev, uint8_t epnum); + +#if (USBD_SUPPORT_USER_STRING == 1) +static uint8_t* USBD_DFU_GetUsrStringDesc ( USBD_HandleTypeDef *pdev, uint8_t index , uint16_t *length); +#endif + +static void DFU_Detach (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); + +static void DFU_Download (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); + +static void DFU_Upload (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); + +static void DFU_GetStatus (USBD_HandleTypeDef *pdev); + +static void DFU_ClearStatus (USBD_HandleTypeDef *pdev); + +static void DFU_GetState (USBD_HandleTypeDef *pdev); + +static void DFU_Abort (USBD_HandleTypeDef *pdev); + +static void DFU_Leave (USBD_HandleTypeDef *pdev); + + +/** + * @} + */ + +/** @defgroup USBD_DFU_Private_Variables + * @{ + */ + +USBD_ClassTypeDef USBD_DFU = +{ + USBD_DFU_Init, + USBD_DFU_DeInit, + USBD_DFU_Setup, + USBD_DFU_EP0_TxReady, + USBD_DFU_EP0_RxReady, + USBD_DFU_DataIn, + USBD_DFU_DataOut, + USBD_DFU_SOF, + USBD_DFU_IsoINIncomplete, + USBD_DFU_IsoOutIncomplete, + USBD_DFU_GetCfgDesc, + USBD_DFU_GetCfgDesc, + USBD_DFU_GetCfgDesc, + USBD_DFU_GetDeviceQualifierDesc, +#if (USBD_SUPPORT_USER_STRING == 1) + USBD_DFU_GetUsrStringDesc +#endif +}; + +/* USB DFU device Configuration Descriptor */ +__ALIGN_BEGIN static uint8_t USBD_DFU_CfgDesc[USB_DFU_CONFIG_DESC_SIZ] __ALIGN_END = +{ + 0x09, /* bLength: Configuation Descriptor size */ + USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ + USB_DFU_CONFIG_DESC_SIZ, + /* wTotalLength: Bytes returned */ + 0x00, + 0x01, /*bNumInterfaces: 1 interface*/ + 0x01, /*bConfigurationValue: Configuration value*/ + 0x02, /*iConfiguration: Index of string descriptor describing the configuration*/ + 0xC0, /*bmAttributes: bus powered and Supprts Remote Wakeup */ + 0x32, /*MaxPower 100 mA: this current is used for detecting Vbus*/ + /* 09 */ + + /********** Descriptor of DFU interface 0 Alternate setting 0 **************/ + USBD_DFU_IF_DESC(0), /* This interface is mandatory for all devices */ + +#if (USBD_DFU_MAX_ITF_NUM > 1) + /********** Descriptor of DFU interface 0 Alternate setting 1 **************/ + USBD_DFU_IF_DESC(1), +#endif /* (USBD_DFU_MAX_ITF_NUM > 1) */ + +#if (USBD_DFU_MAX_ITF_NUM > 2) + /********** Descriptor of DFU interface 0 Alternate setting 2 **************/ + USBD_DFU_IF_DESC(2), +#endif /* (USBD_DFU_MAX_ITF_NUM > 2) */ + +#if (USBD_DFU_MAX_ITF_NUM > 3) + /********** Descriptor of DFU interface 0 Alternate setting 3 **************/ + USBD_DFU_IF_DESC(3), +#endif /* (USBD_DFU_MAX_ITF_NUM > 3) */ + +#if (USBD_DFU_MAX_ITF_NUM > 4) + /********** Descriptor of DFU interface 0 Alternate setting 4 **************/ + USBD_DFU_IF_DESC(4), +#endif /* (USBD_DFU_MAX_ITF_NUM > 4) */ + +#if (USBD_DFU_MAX_ITF_NUM > 5) + /********** Descriptor of DFU interface 0 Alternate setting 5 **************/ + USBD_DFU_IF_DESC(5), +#endif /* (USBD_DFU_MAX_ITF_NUM > 5) */ + +#if (USBD_DFU_MAX_ITF_NUM > 6) +#error "ERROR: usbd_dfu_core.c: Modify the file to support more descriptors!" +#endif /* (USBD_DFU_MAX_ITF_NUM > 6) */ + + /******************** DFU Functional Descriptor********************/ + 0x09, /*blength = 9 Bytes*/ + DFU_DESCRIPTOR_TYPE, /* DFU Functional Descriptor*/ + 0x0B, /*bmAttribute + bitCanDnload = 1 (bit 0) + bitCanUpload = 1 (bit 1) + bitManifestationTolerant = 0 (bit 2) + bitWillDetach = 1 (bit 3) + Reserved (bit4-6) + bitAcceleratedST = 0 (bit 7)*/ + 0xFF, /*DetachTimeOut= 255 ms*/ + 0x00, + /*WARNING: In DMA mode the multiple MPS packets feature is still not supported + ==> In this case, when using DMA USBD_DFU_XFER_SIZE should be set to 64 in usbd_conf.h */ + TRANSFER_SIZE_BYTES(USBD_DFU_XFER_SIZE), /* TransferSize = 1024 Byte*/ + 0x1A, /* bcdDFUVersion*/ + 0x01 + /***********************************************************/ + /* 9*/ +}; + +/* USB Standard Device Descriptor */ +__ALIGN_BEGIN static uint8_t USBD_DFU_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = +{ + USB_LEN_DEV_QUALIFIER_DESC, + USB_DESC_TYPE_DEVICE_QUALIFIER, + 0x00, + 0x02, + 0x00, + 0x00, + 0x00, + 0x40, + 0x01, + 0x00, +}; + +/** + * @} + */ + +/** @defgroup USBD_DFU_Private_Functions + * @{ + */ + +/** + * @brief USBD_DFU_Init + * Initialize the DFU interface + * @param pdev: device instance + * @param cfgidx: Configuration index + * @retval status + */ +static uint8_t USBD_DFU_Init (USBD_HandleTypeDef *pdev, + uint8_t cfgidx) +{ + USBD_DFU_HandleTypeDef *hdfu; + + /* Allocate Audio structure */ + pdev->pClassData = USBD_malloc(sizeof (USBD_DFU_HandleTypeDef)); + + if(pdev->pClassData == NULL) + { + return USBD_FAIL; + } + else + { + hdfu = (USBD_DFU_HandleTypeDef*) pdev->pClassData; + + hdfu->alt_setting = 0; + hdfu->data_ptr = USBD_DFU_APP_DEFAULT_ADD; + hdfu->wblock_num = 0; + hdfu->wlength = 0; + + hdfu->manif_state = DFU_MANIFEST_COMPLETE; + hdfu->dev_state = DFU_STATE_IDLE; + + hdfu->dev_status[0] = DFU_ERROR_NONE; + hdfu->dev_status[1] = 0; + hdfu->dev_status[2] = 0; + hdfu->dev_status[3] = 0; + hdfu->dev_status[4] = DFU_STATE_IDLE; + hdfu->dev_status[5] = 0; + + /* Initialize Hardware layer */ + if (((USBD_DFU_MediaTypeDef *)pdev->pUserData)->Init() != USBD_OK) + { + return USBD_FAIL; + } + } + return USBD_OK; +} + +/** + * @brief USBD_DFU_Init + * De-Initialize the DFU layer + * @param pdev: device instance + * @param cfgidx: Configuration index + * @retval status + */ +static uint8_t USBD_DFU_DeInit (USBD_HandleTypeDef *pdev, + uint8_t cfgidx) +{ + USBD_DFU_HandleTypeDef *hdfu; + hdfu = (USBD_DFU_HandleTypeDef*) pdev->pClassData; + + hdfu->wblock_num = 0; + hdfu->wlength = 0; + + hdfu->dev_state = DFU_STATE_IDLE; + hdfu->dev_status[0] = DFU_ERROR_NONE; + hdfu->dev_status[4] = DFU_STATE_IDLE; + + /* DeInit physical Interface components */ + if(pdev->pClassData != NULL) + { + /* De-Initialize Hardware layer */ + ((USBD_DFU_MediaTypeDef *)pdev->pUserData)->DeInit(); + USBD_free(pdev->pClassData); + pdev->pClassData = NULL; + } + + return USBD_OK; +} + +/** + * @brief USBD_DFU_Setup + * Handle the DFU specific requests + * @param pdev: instance + * @param req: usb requests + * @retval status + */ +static uint8_t USBD_DFU_Setup (USBD_HandleTypeDef *pdev, + USBD_SetupReqTypedef *req) +{ + uint8_t *pbuf = 0; + uint16_t len = 0; + uint8_t ret = USBD_OK; + USBD_DFU_HandleTypeDef *hdfu; + + hdfu = (USBD_DFU_HandleTypeDef*) pdev->pClassData; + + switch (req->bmRequest & USB_REQ_TYPE_MASK) + { + case USB_REQ_TYPE_CLASS : + switch (req->bRequest) + { + case DFU_DNLOAD: + DFU_Download(pdev, req); + break; + + case DFU_UPLOAD: + DFU_Upload(pdev, req); + break; + + case DFU_GETSTATUS: + DFU_GetStatus(pdev); + break; + + case DFU_CLRSTATUS: + DFU_ClearStatus(pdev); + break; + + case DFU_GETSTATE: + DFU_GetState(pdev); + break; + + case DFU_ABORT: + DFU_Abort(pdev); + break; + + case DFU_DETACH: + DFU_Detach(pdev, req); + break; + + + default: + USBD_CtlError (pdev, req); + ret = USBD_FAIL; + } + break; + + case USB_REQ_TYPE_STANDARD: + switch (req->bRequest) + { + case USB_REQ_GET_DESCRIPTOR: + if( (req->wValue >> 8) == DFU_DESCRIPTOR_TYPE) + { + pbuf = USBD_DFU_CfgDesc + (9 * (USBD_DFU_MAX_ITF_NUM + 1)); + len = MIN(USB_DFU_DESC_SIZ , req->wLength); + } + + USBD_CtlSendData (pdev, + pbuf, + len); + break; + + case USB_REQ_GET_INTERFACE : + USBD_CtlSendData (pdev, + (uint8_t *)&hdfu->alt_setting, + 1); + break; + + case USB_REQ_SET_INTERFACE : + if ((uint8_t)(req->wValue) < USBD_DFU_MAX_ITF_NUM) + { + hdfu->alt_setting = (uint8_t)(req->wValue); + } + else + { + /* Call the error management function (command will be nacked */ + USBD_CtlError (pdev, req); + ret = USBD_FAIL; + } + break; + + default: + USBD_CtlError (pdev, req); + ret = USBD_FAIL; + } + } + return ret; +} + + +/** + * @brief USBD_DFU_GetCfgDesc + * return configuration descriptor + * @param speed : current device speed + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +static uint8_t *USBD_DFU_GetCfgDesc (uint16_t *length) +{ + *length = sizeof (USBD_DFU_CfgDesc); + return USBD_DFU_CfgDesc; +} + +/** + * @brief USBD_DFU_DataIn + * handle data IN Stage + * @param pdev: device instance + * @param epnum: endpoint index + * @retval status + */ +static uint8_t USBD_DFU_DataIn (USBD_HandleTypeDef *pdev, + uint8_t epnum) +{ + + return USBD_OK; +} + +/** + * @brief USBD_DFU_EP0_RxReady + * handle EP0 Rx Ready event + * @param pdev: device instance + * @retval status + */ +static uint8_t USBD_DFU_EP0_RxReady (USBD_HandleTypeDef *pdev) +{ + + return USBD_OK; +} +/** + * @brief USBD_DFU_EP0_TxReady + * handle EP0 TRx Ready event + * @param pdev: device instance + * @retval status + */ +static uint8_t USBD_DFU_EP0_TxReady (USBD_HandleTypeDef *pdev) +{ + uint32_t addr; + USBD_SetupReqTypedef req; + USBD_DFU_HandleTypeDef *hdfu; + + hdfu = (USBD_DFU_HandleTypeDef*) pdev->pClassData; + + if (hdfu->dev_state == DFU_STATE_DNLOAD_BUSY) + { + /* Decode the Special Command*/ + if (hdfu->wblock_num == 0) + { + if ((hdfu->buffer.d8[0] == DFU_CMD_GETCOMMANDS) && (hdfu->wlength == 1)) + { + + } + else if (( hdfu->buffer.d8[0] == DFU_CMD_SETADDRESSPOINTER ) && (hdfu->wlength == 5)) + { + hdfu->data_ptr = hdfu->buffer.d8[1]; + hdfu->data_ptr += hdfu->buffer.d8[2] << 8; + hdfu->data_ptr += hdfu->buffer.d8[3] << 16; + hdfu->data_ptr += hdfu->buffer.d8[4] << 24; + } + else if (( hdfu->buffer.d8[0] == DFU_CMD_ERASE ) && (hdfu->wlength == 5)) + { + hdfu->data_ptr = hdfu->buffer.d8[1]; + hdfu->data_ptr += hdfu->buffer.d8[2] << 8; + hdfu->data_ptr += hdfu->buffer.d8[3] << 16; + hdfu->data_ptr += hdfu->buffer.d8[4] << 24; + + if (((USBD_DFU_MediaTypeDef *)pdev->pUserData)->Erase(hdfu->data_ptr) != USBD_OK) + { + return USBD_FAIL; + } + } + else + { + /* Reset the global length and block number */ + hdfu->wlength = 0; + hdfu->wblock_num = 0; + /* Call the error management function (command will be nacked) */ + req.bmRequest = 0; + req.wLength = 1; + USBD_CtlError (pdev, &req); + } + } + /* Regular Download Command */ + else if (hdfu->wblock_num > 1) + { + /* Decode the required address */ + addr = ((hdfu->wblock_num - 2) * USBD_DFU_XFER_SIZE) + hdfu->data_ptr; + + /* Preform the write operation */ + if (((USBD_DFU_MediaTypeDef *)pdev->pUserData)->Write(hdfu->buffer.d8, (uint8_t *)addr, hdfu->wlength) != USBD_OK) + { + return USBD_FAIL; + } + } + /* Reset the global length and block number */ + hdfu->wlength = 0; + hdfu->wblock_num = 0; + + /* Update the state machine */ + hdfu->dev_state = DFU_STATE_DNLOAD_SYNC; + + hdfu->dev_status[1] = 0; + hdfu->dev_status[2] = 0; + hdfu->dev_status[3] = 0; + hdfu->dev_status[4] = hdfu->dev_state; + return USBD_OK; + } + else if (hdfu->dev_state == DFU_STATE_MANIFEST)/* Manifestation in progress*/ + { + /* Start leaving DFU mode */ + DFU_Leave(pdev); + } + + return USBD_OK; +} +/** + * @brief USBD_DFU_SOF + * handle SOF event + * @param pdev: device instance + * @retval status + */ +static uint8_t USBD_DFU_SOF (USBD_HandleTypeDef *pdev) +{ + + return USBD_OK; +} +/** + * @brief USBD_DFU_IsoINIncomplete + * handle data ISO IN Incomplete event + * @param pdev: device instance + * @param epnum: endpoint index + * @retval status + */ +static uint8_t USBD_DFU_IsoINIncomplete (USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + + return USBD_OK; +} +/** + * @brief USBD_DFU_IsoOutIncomplete + * handle data ISO OUT Incomplete event + * @param pdev: device instance + * @param epnum: endpoint index + * @retval status + */ +static uint8_t USBD_DFU_IsoOutIncomplete (USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + + return USBD_OK; +} +/** + * @brief USBD_DFU_DataOut + * handle data OUT Stage + * @param pdev: device instance + * @param epnum: endpoint index + * @retval status + */ +static uint8_t USBD_DFU_DataOut (USBD_HandleTypeDef *pdev, + uint8_t epnum) +{ + + return USBD_OK; +} + +/** +* @brief DeviceQualifierDescriptor +* return Device Qualifier descriptor +* @param length : pointer data length +* @retval pointer to descriptor buffer +*/ +static uint8_t *USBD_DFU_GetDeviceQualifierDesc (uint16_t *length) +{ + *length = sizeof (USBD_DFU_DeviceQualifierDesc); + return USBD_DFU_DeviceQualifierDesc; +} + +/** + * @brief USBD_DFU_GetUsrStringDesc + * Manages the transfer of memory interfaces string descriptors. + * @param speed : current device speed + * @param index: desciptor index + * @param length : pointer data length + * @retval pointer to the descriptor table or NULL if the descriptor is not supported. + */ +#if (USBD_SUPPORT_USER_STRING == 1) +static uint8_t* USBD_DFU_GetUsrStringDesc (USBD_HandleTypeDef *pdev, uint8_t index , uint16_t *length) +{ + static uint8_t USBD_StrDesc[255]; + /* Check if the requested string interface is supported */ + if (index <= (USBD_IDX_INTERFACE_STR + USBD_DFU_MAX_ITF_NUM)) + { + USBD_GetString ((uint8_t *)((USBD_DFU_MediaTypeDef *)pdev->pUserData)->pStrDesc, USBD_StrDesc, length); + return USBD_StrDesc; + } + /* Not supported Interface Descriptor index */ + else + { + return NULL; + } +} +#endif + +/** +* @brief USBD_MSC_RegisterStorage +* @param fops: storage callback +* @retval status +*/ +uint8_t USBD_DFU_RegisterMedia (USBD_HandleTypeDef *pdev, + USBD_DFU_MediaTypeDef *fops) +{ + if(fops != NULL) + { + pdev->pUserData= fops; + } + return 0; +} + +/****************************************************************************** + DFU Class requests management +******************************************************************************/ +/** + * @brief DFU_Detach + * Handles the DFU DETACH request. + * @param pdev: device instance + * @param req: pointer to the request structure. + * @retval None. + */ +static void DFU_Detach(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + USBD_DFU_HandleTypeDef *hdfu; + + hdfu = (USBD_DFU_HandleTypeDef*) pdev->pClassData; + + if (hdfu->dev_state == DFU_STATE_IDLE || hdfu->dev_state == DFU_STATE_DNLOAD_SYNC + || hdfu->dev_state == DFU_STATE_DNLOAD_IDLE || hdfu->dev_state == DFU_STATE_MANIFEST_SYNC + || hdfu->dev_state == DFU_STATE_UPLOAD_IDLE ) + { + /* Update the state machine */ + hdfu->dev_state = DFU_STATE_IDLE; + hdfu->dev_status[0] = DFU_ERROR_NONE; + hdfu->dev_status[1] = 0; + hdfu->dev_status[2] = 0; + hdfu->dev_status[3] = 0; /*bwPollTimeout=0ms*/ + hdfu->dev_status[4] = hdfu->dev_state; + hdfu->dev_status[5] = 0; /*iString*/ + hdfu->wblock_num = 0; + hdfu->wlength = 0; + } + + /* Check the detach capability in the DFU functional descriptor */ + if ((USBD_DFU_CfgDesc[12 + (9 * USBD_DFU_MAX_ITF_NUM)]) & DFU_DETACH_MASK) + { + /* Perform an Attach-Detach operation on USB bus */ + USBD_Stop (pdev); + USBD_Start (pdev); + } + else + { + /* Wait for the period of time specified in Detach request */ + USBD_Delay (req->wValue); + } +} + +/** + * @brief DFU_Download + * Handles the DFU DNLOAD request. + * @param pdev: device instance + * @param req: pointer to the request structure + * @retval None + */ +static void DFU_Download(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + USBD_DFU_HandleTypeDef *hdfu; + + hdfu = (USBD_DFU_HandleTypeDef*) pdev->pClassData; + + /* Data setup request */ + if (req->wLength > 0) + { + if ((hdfu->dev_state == DFU_STATE_IDLE) || (hdfu->dev_state == DFU_STATE_DNLOAD_IDLE)) + { + /* Update the global length and block number */ + hdfu->wblock_num = req->wValue; + hdfu->wlength = req->wLength; + + /* Update the state machine */ + hdfu->dev_state = DFU_STATE_DNLOAD_SYNC; + hdfu->dev_status[4] = hdfu->dev_state; + + /* Prepare the reception of the buffer over EP0 */ + USBD_CtlPrepareRx (pdev, + (uint8_t*)hdfu->buffer.d8, + hdfu->wlength); + } + /* Unsupported state */ + else + { + /* Call the error management function (command will be nacked */ + USBD_CtlError (pdev, req); + } + } + /* 0 Data DNLOAD request */ + else + { + /* End of DNLOAD operation*/ + if (hdfu->dev_state == DFU_STATE_DNLOAD_IDLE || hdfu->dev_state == DFU_STATE_IDLE ) + { + hdfu->manif_state = DFU_MANIFEST_IN_PROGRESS; + hdfu->dev_state = DFU_STATE_MANIFEST_SYNC; + hdfu->dev_status[1] = 0; + hdfu->dev_status[2] = 0; + hdfu->dev_status[3] = 0; + hdfu->dev_status[4] = hdfu->dev_state; + } + else + { + /* Call the error management function (command will be nacked */ + USBD_CtlError (pdev, req); + } + } +} + +/** + * @brief DFU_Upload + * Handles the DFU UPLOAD request. + * @param pdev: instance + * @param req: pointer to the request structure + * @retval status + */ +static void DFU_Upload(USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + USBD_DFU_HandleTypeDef *hdfu; + + hdfu = (USBD_DFU_HandleTypeDef*) pdev->pClassData; + + uint8_t *phaddr = NULL; + uint32_t addr = 0; + + /* Data setup request */ + if (req->wLength > 0) + { + if ((hdfu->dev_state == DFU_STATE_IDLE) || (hdfu->dev_state == DFU_STATE_UPLOAD_IDLE)) + { + /* Update the global length and block number */ + hdfu->wblock_num = req->wValue; + hdfu->wlength = req->wLength; + + /* DFU Get Command */ + if (hdfu->wblock_num == 0) + { + /* Update the state machine */ + hdfu->dev_state = (hdfu->wlength > 3)? DFU_STATE_IDLE:DFU_STATE_UPLOAD_IDLE; + + hdfu->dev_status[1] = 0; + hdfu->dev_status[2] = 0; + hdfu->dev_status[3] = 0; + hdfu->dev_status[4] = hdfu->dev_state; + + /* Store the values of all supported commands */ + hdfu->buffer.d8[0] = DFU_CMD_GETCOMMANDS; + hdfu->buffer.d8[1] = DFU_CMD_SETADDRESSPOINTER; + hdfu->buffer.d8[2] = DFU_CMD_ERASE; + + /* Send the status data over EP0 */ + USBD_CtlSendData (pdev, + (uint8_t *)(&(hdfu->buffer.d8[0])), + 3); + } + else if (hdfu->wblock_num > 1) + { + hdfu->dev_state = DFU_STATE_UPLOAD_IDLE ; + + hdfu->dev_status[1] = 0; + hdfu->dev_status[2] = 0; + hdfu->dev_status[3] = 0; + hdfu->dev_status[4] = hdfu->dev_state; + + addr = ((hdfu->wblock_num - 2) * USBD_DFU_XFER_SIZE) + hdfu->data_ptr; /* Change is Accelerated*/ + + /* Return the physical address where data are stored */ + phaddr = ((USBD_DFU_MediaTypeDef *)pdev->pUserData)->Read((uint8_t *)addr, hdfu->buffer.d8, hdfu->wlength); + + /* Send the status data over EP0 */ + USBD_CtlSendData (pdev, + phaddr, + hdfu->wlength); + } + else /* unsupported hdfu->wblock_num */ + { + hdfu->dev_state = DFU_ERROR_STALLEDPKT; + + hdfu->dev_status[1] = 0; + hdfu->dev_status[2] = 0; + hdfu->dev_status[3] = 0; + hdfu->dev_status[4] = hdfu->dev_state; + + /* Call the error management function (command will be nacked */ + USBD_CtlError (pdev, req); + } + } + /* Unsupported state */ + else + { + hdfu->wlength = 0; + hdfu->wblock_num = 0; + /* Call the error management function (command will be nacked */ + USBD_CtlError (pdev, req); + } + } + /* No Data setup request */ + else + { + hdfu->dev_state = DFU_STATE_IDLE; + + hdfu->dev_status[1] = 0; + hdfu->dev_status[2] = 0; + hdfu->dev_status[3] = 0; + hdfu->dev_status[4] = hdfu->dev_state; + } +} + +/** + * @brief DFU_GetStatus + * Handles the DFU GETSTATUS request. + * @param pdev: instance + * @retval status + */ +static void DFU_GetStatus(USBD_HandleTypeDef *pdev) +{ + USBD_DFU_HandleTypeDef *hdfu; + + hdfu = (USBD_DFU_HandleTypeDef*) pdev->pClassData; + + switch (hdfu->dev_state) + { + case DFU_STATE_DNLOAD_SYNC: + if (hdfu->wlength != 0) + { + hdfu->dev_state = DFU_STATE_DNLOAD_BUSY; + + hdfu->dev_status[1] = 0; + hdfu->dev_status[2] = 0; + hdfu->dev_status[3] = 0; + hdfu->dev_status[4] = hdfu->dev_state; + + if ((hdfu->wblock_num == 0) && (hdfu->buffer.d8[0] == DFU_CMD_ERASE)) + { + ((USBD_DFU_MediaTypeDef *)pdev->pUserData)->GetStatus(hdfu->data_ptr, DFU_MEDIA_ERASE, hdfu->dev_status); + } + else + { + ((USBD_DFU_MediaTypeDef *)pdev->pUserData)->GetStatus(hdfu->data_ptr, DFU_MEDIA_PROGRAM, hdfu->dev_status); + } + } + else /* (hdfu->wlength==0)*/ + { + hdfu->dev_state = DFU_STATE_DNLOAD_IDLE; + + hdfu->dev_status[1] = 0; + hdfu->dev_status[2] = 0; + hdfu->dev_status[3] = 0; + hdfu->dev_status[4] = hdfu->dev_state; + } + break; + + case DFU_STATE_MANIFEST_SYNC : + if (hdfu->manif_state == DFU_MANIFEST_IN_PROGRESS) + { + hdfu->dev_state = DFU_STATE_MANIFEST; + + hdfu->dev_status[1] = 1; /*bwPollTimeout = 1ms*/ + hdfu->dev_status[2] = 0; + hdfu->dev_status[3] = 0; + hdfu->dev_status[4] = hdfu->dev_state; + } + else if ((hdfu->manif_state == DFU_MANIFEST_COMPLETE) && \ + ((USBD_DFU_CfgDesc[(11 + (9 * USBD_DFU_MAX_ITF_NUM))]) & 0x04)) + { + hdfu->dev_state = DFU_STATE_IDLE; + + hdfu->dev_status[1] = 0; + hdfu->dev_status[2] = 0; + hdfu->dev_status[3] = 0; + hdfu->dev_status[4] = hdfu->dev_state; + } + break; + + default : + break; + } + + /* Send the status data over EP0 */ + USBD_CtlSendData (pdev, + (uint8_t *)(&(hdfu->dev_status[0])), + 6); +} + +/** + * @brief DFU_ClearStatus + * Handles the DFU CLRSTATUS request. + * @param pdev: device instance + * @retval status + */ +static void DFU_ClearStatus(USBD_HandleTypeDef *pdev) +{ + USBD_DFU_HandleTypeDef *hdfu; + + hdfu = (USBD_DFU_HandleTypeDef*) pdev->pClassData; + + if (hdfu->dev_state == DFU_STATE_ERROR) + { + hdfu->dev_state = DFU_STATE_IDLE; + hdfu->dev_status[0] = DFU_ERROR_NONE;/*bStatus*/ + hdfu->dev_status[1] = 0; + hdfu->dev_status[2] = 0; + hdfu->dev_status[3] = 0; /*bwPollTimeout=0ms*/ + hdfu->dev_status[4] = hdfu->dev_state;/*bState*/ + hdfu->dev_status[5] = 0;/*iString*/ + } + else + { /*State Error*/ + hdfu->dev_state = DFU_STATE_ERROR; + hdfu->dev_status[0] = DFU_ERROR_UNKNOWN;/*bStatus*/ + hdfu->dev_status[1] = 0; + hdfu->dev_status[2] = 0; + hdfu->dev_status[3] = 0; /*bwPollTimeout=0ms*/ + hdfu->dev_status[4] = hdfu->dev_state;/*bState*/ + hdfu->dev_status[5] = 0;/*iString*/ + } +} + +/** + * @brief DFU_GetState + * Handles the DFU GETSTATE request. + * @param pdev: device instance + * @retval None + */ +static void DFU_GetState(USBD_HandleTypeDef *pdev) +{ + USBD_DFU_HandleTypeDef *hdfu; + + hdfu = (USBD_DFU_HandleTypeDef*) pdev->pClassData; + + /* Return the current state of the DFU interface */ + USBD_CtlSendData (pdev, + &hdfu->dev_state, + 1); +} + +/** + * @brief DFU_Abort + * Handles the DFU ABORT request. + * @param pdev: device instance + * @retval None + */ +static void DFU_Abort(USBD_HandleTypeDef *pdev) +{ + USBD_DFU_HandleTypeDef *hdfu; + + hdfu = (USBD_DFU_HandleTypeDef*) pdev->pClassData; + + if (hdfu->dev_state == DFU_STATE_IDLE || hdfu->dev_state == DFU_STATE_DNLOAD_SYNC + || hdfu->dev_state == DFU_STATE_DNLOAD_IDLE || hdfu->dev_state == DFU_STATE_MANIFEST_SYNC + || hdfu->dev_state == DFU_STATE_UPLOAD_IDLE ) + { + hdfu->dev_state = DFU_STATE_IDLE; + hdfu->dev_status[0] = DFU_ERROR_NONE; + hdfu->dev_status[1] = 0; + hdfu->dev_status[2] = 0; + hdfu->dev_status[3] = 0; /*bwPollTimeout=0ms*/ + hdfu->dev_status[4] = hdfu->dev_state; + hdfu->dev_status[5] = 0; /*iString*/ + hdfu->wblock_num = 0; + hdfu->wlength = 0; + } +} + +/** + * @brief DFU_Leave + * Handles the sub-protocol DFU leave DFU mode request (leaves DFU mode + * and resets device to jump to user loaded code). + * @param pdev: device instance + * @retval None + */ +void DFU_Leave(USBD_HandleTypeDef *pdev) +{ + USBD_DFU_HandleTypeDef *hdfu; + + hdfu = (USBD_DFU_HandleTypeDef*) pdev->pClassData; + + hdfu->manif_state = DFU_MANIFEST_COMPLETE; + + if ((USBD_DFU_CfgDesc[(11 + (9 * USBD_DFU_MAX_ITF_NUM))]) & 0x04) + { + hdfu->dev_state = DFU_STATE_MANIFEST_SYNC; + + hdfu->dev_status[1] = 0; + hdfu->dev_status[2] = 0; + hdfu->dev_status[3] = 0; + hdfu->dev_status[4] = hdfu->dev_state; + return; + } + else + { + + hdfu->dev_state = DFU_STATE_MANIFEST_WAIT_RESET; + + hdfu->dev_status[1] = 0; + hdfu->dev_status[2] = 0; + hdfu->dev_status[3] = 0; + hdfu->dev_status[4] = hdfu->dev_state; + + /* Disconnect the USB device */ + USBD_Stop (pdev); + + /* DeInitilialize the MAL(Media Access Layer) */ + ((USBD_DFU_MediaTypeDef *)pdev->pUserData)->DeInit(); + + /* Generate system reset to allow jumping to the user code */ + NVIC_SystemReset(); + + /* This instruction will not be reached (system reset) */ + for(;;); + } +} + +/** + * @} + */ + + +/** + * @} + */ + + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/platform/mcu/stm32l475/Middlewares/USB_Device/Class/DFU/Src/usbd_dfu_media_template.c b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/DFU/Src/usbd_dfu_media_template.c new file mode 100644 index 0000000000..c78a6c2bb6 --- /dev/null +++ b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/DFU/Src/usbd_dfu_media_template.c @@ -0,0 +1,159 @@ +/** + ****************************************************************************** + * @file usbd_dfu_media_template.c + * @author MCD Application Team + * @version V2.4.2 + * @date 11-December-2015 + * @brief Memory management layer + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_dfu_media_template.h" + + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Extern function prototypes ------------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +uint16_t MEM_If_Init(void); +uint16_t MEM_If_Erase (uint32_t Add); +uint16_t MEM_If_Write (uint8_t *src, uint8_t *dest, uint32_t Len); +uint8_t *MEM_If_Read (uint8_t *src, uint8_t *dest, uint32_t Len); +uint16_t MEM_If_DeInit(void); +uint16_t MEM_If_GetStatus (uint32_t Add, uint8_t Cmd, uint8_t *buffer); + +USBD_DFU_MediaTypeDef USBD_DFU_MEDIA_Template_fops = +{ + (uint8_t *)"DFU MEDIA", + MEM_If_Init, + MEM_If_DeInit, + MEM_If_Erase, + MEM_If_Write, + MEM_If_Read, + MEM_If_GetStatus, + +}; +/** + * @brief MEM_If_Init + * Memory initialization routine. + * @param None + * @retval 0 if operation is successful, MAL_FAIL else. + */ +uint16_t MEM_If_Init(void) +{ + return 0; +} + +/** + * @brief MEM_If_DeInit + * Memory deinitialization routine. + * @param None + * @retval 0 if operation is successful, MAL_FAIL else. + */ +uint16_t MEM_If_DeInit(void) +{ + return 0; +} + +/** + * @brief MEM_If_Erase + * Erase sector. + * @param Add: Address of sector to be erased. + * @retval 0 if operation is successful, MAL_FAIL else. + */ +uint16_t MEM_If_Erase(uint32_t Add) +{ + return 0; +} + +/** + * @brief MEM_If_Write + * Memory write routine. + * @param Add: Address to be written to. + * @param Len: Number of data to be written (in bytes). + * @retval 0 if operation is successful, MAL_FAIL else. + */ +uint16_t MEM_If_Write(uint8_t *src, uint8_t *dest, uint32_t Len) +{ + return 0; +} + +/** + * @brief MEM_If_Read + * Memory read routine. + * @param Add: Address to be read from. + * @param Len: Number of data to be read (in bytes). + * @retval Pointer to the physical address where data should be read. + */ +uint8_t *MEM_If_Read (uint8_t *src, uint8_t *dest, uint32_t Len) +{ + /* Return a valid address to avoid HardFault */ + return (uint8_t*)(0); +} + +/** + * @brief Flash_If_GetStatus + * Memory read routine. + * @param Add: Address to be read from. + * @param cmd: Number of data to be read (in bytes). + * @retval Pointer to the physical address where data should be read. + */ +uint16_t MEM_If_GetStatus (uint32_t Add, uint8_t Cmd, uint8_t *buffer) +{ + switch (Cmd) + { + case DFU_MEDIA_PROGRAM: + + break; + + case DFU_MEDIA_ERASE: + default: + + break; + } + return (0); +} +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/platform/mcu/stm32l475/Middlewares/USB_Device/Class/HID/Inc/usbd_hid.h b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/HID/Inc/usbd_hid.h new file mode 100644 index 0000000000..68fbac1d78 --- /dev/null +++ b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/HID/Inc/usbd_hid.h @@ -0,0 +1,168 @@ +/** + ****************************************************************************** + * @file usbd_hid.h + * @author MCD Application Team + * @version V2.4.2 + * @date 11-December-2015 + * @brief Header file for the usbd_hid_core.c file. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USB_HID_H +#define __USB_HID_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_ioreq.h" + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USBD_HID + * @brief This file is the Header file for usbd_hid.c + * @{ + */ + + +/** @defgroup USBD_HID_Exported_Defines + * @{ + */ +#define HID_EPIN_ADDR 0x81 +#define HID_EPIN_SIZE 0x04 + +#define USB_HID_CONFIG_DESC_SIZ 34 +#define USB_HID_DESC_SIZ 9 +#define HID_MOUSE_REPORT_DESC_SIZE 74 + +#define HID_DESCRIPTOR_TYPE 0x21 +#define HID_REPORT_DESC 0x22 + +#define HID_HS_BINTERVAL 0x07 +#define HID_FS_BINTERVAL 0x0A +#define HID_POLLING_INTERVAL 0x0A + +#define HID_REQ_SET_PROTOCOL 0x0B +#define HID_REQ_GET_PROTOCOL 0x03 + +#define HID_REQ_SET_IDLE 0x0A +#define HID_REQ_GET_IDLE 0x02 + +#define HID_REQ_SET_REPORT 0x09 +#define HID_REQ_GET_REPORT 0x01 +/** + * @} + */ + + +/** @defgroup USBD_CORE_Exported_TypesDefinitions + * @{ + */ +typedef enum +{ + HID_IDLE = 0, + HID_BUSY, +} +HID_StateTypeDef; + + +typedef struct +{ + uint32_t Protocol; + uint32_t IdleState; + uint32_t AltSetting; + HID_StateTypeDef state; +} +USBD_HID_HandleTypeDef; +/** + * @} + */ + + + +/** @defgroup USBD_CORE_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_CORE_Exported_Variables + * @{ + */ + +extern USBD_ClassTypeDef USBD_HID; +#define USBD_HID_CLASS &USBD_HID +/** + * @} + */ + +/** @defgroup USB_CORE_Exported_Functions + * @{ + */ +uint8_t USBD_HID_SendReport (USBD_HandleTypeDef *pdev, + uint8_t *report, + uint16_t len); + +uint32_t USBD_HID_GetPollingInterval (USBD_HandleTypeDef *pdev); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_HID_H */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/platform/mcu/stm32l475/Middlewares/USB_Device/Class/HID/Src/usbd_hid.c b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/HID/Src/usbd_hid.c new file mode 100644 index 0000000000..e009b3b180 --- /dev/null +++ b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/HID/Src/usbd_hid.c @@ -0,0 +1,545 @@ +/** + ****************************************************************************** + * @file usbd_hid.c + * @author MCD Application Team + * @version V2.4.2 + * @date 11-December-2015 + * @brief This file provides the HID core functions. + * + * @verbatim + * + * =================================================================== + * HID Class Description + * =================================================================== + * This module manages the HID class V1.11 following the "Device Class Definition + * for Human Interface Devices (HID) Version 1.11 Jun 27, 2001". + * This driver implements the following aspects of the specification: + * - The Boot Interface Subclass + * - The Mouse protocol + * - Usage Page : Generic Desktop + * - Usage : Joystick + * - Collection : Application + * + * @note In HS mode and when the DMA is used, all variables and data structures + * dealing with the DMA during the transaction process should be 32-bit aligned. + * + * + * @endverbatim + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_hid.h" +#include "usbd_desc.h" +#include "usbd_ctlreq.h" + + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup USBD_HID + * @brief usbd core module + * @{ + */ + +/** @defgroup USBD_HID_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_HID_Private_Defines + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_HID_Private_Macros + * @{ + */ +/** + * @} + */ + + + + +/** @defgroup USBD_HID_Private_FunctionPrototypes + * @{ + */ + + +static uint8_t USBD_HID_Init (USBD_HandleTypeDef *pdev, + uint8_t cfgidx); + +static uint8_t USBD_HID_DeInit (USBD_HandleTypeDef *pdev, + uint8_t cfgidx); + +static uint8_t USBD_HID_Setup (USBD_HandleTypeDef *pdev, + USBD_SetupReqTypedef *req); + +static uint8_t *USBD_HID_GetCfgDesc (uint16_t *length); + +static uint8_t *USBD_HID_GetDeviceQualifierDesc (uint16_t *length); + +static uint8_t USBD_HID_DataIn (USBD_HandleTypeDef *pdev, uint8_t epnum); +/** + * @} + */ + +/** @defgroup USBD_HID_Private_Variables + * @{ + */ + +USBD_ClassTypeDef USBD_HID = +{ + USBD_HID_Init, + USBD_HID_DeInit, + USBD_HID_Setup, + NULL, /*EP0_TxSent*/ + NULL, /*EP0_RxReady*/ + USBD_HID_DataIn, /*DataIn*/ + NULL, /*DataOut*/ + NULL, /*SOF */ + NULL, + NULL, + USBD_HID_GetCfgDesc, + USBD_HID_GetCfgDesc, + USBD_HID_GetCfgDesc, + USBD_HID_GetDeviceQualifierDesc, +}; + +/* USB HID device Configuration Descriptor */ +__ALIGN_BEGIN static uint8_t USBD_HID_CfgDesc[USB_HID_CONFIG_DESC_SIZ] __ALIGN_END = +{ + 0x09, /* bLength: Configuration Descriptor size */ + USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ + USB_HID_CONFIG_DESC_SIZ, + /* wTotalLength: Bytes returned */ + 0x00, + 0x01, /*bNumInterfaces: 1 interface*/ + 0x01, /*bConfigurationValue: Configuration value*/ + 0x00, /*iConfiguration: Index of string descriptor describing + the configuration*/ + 0xE0, /*bmAttributes: bus powered and Support Remote Wake-up */ + 0x32, /*MaxPower 100 mA: this current is used for detecting Vbus*/ + + /************** Descriptor of Joystick Mouse interface ****************/ + /* 09 */ + 0x09, /*bLength: Interface Descriptor size*/ + USB_DESC_TYPE_INTERFACE,/*bDescriptorType: Interface descriptor type*/ + 0x00, /*bInterfaceNumber: Number of Interface*/ + 0x00, /*bAlternateSetting: Alternate setting*/ + 0x01, /*bNumEndpoints*/ + 0x03, /*bInterfaceClass: HID*/ + 0x01, /*bInterfaceSubClass : 1=BOOT, 0=no boot*/ + 0x02, /*nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse*/ + 0, /*iInterface: Index of string descriptor*/ + /******************** Descriptor of Joystick Mouse HID ********************/ + /* 18 */ + 0x09, /*bLength: HID Descriptor size*/ + HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/ + 0x11, /*bcdHID: HID Class Spec release number*/ + 0x01, + 0x00, /*bCountryCode: Hardware target country*/ + 0x01, /*bNumDescriptors: Number of HID class descriptors to follow*/ + 0x22, /*bDescriptorType*/ + HID_MOUSE_REPORT_DESC_SIZE,/*wItemLength: Total length of Report descriptor*/ + 0x00, + /******************** Descriptor of Mouse endpoint ********************/ + /* 27 */ + 0x07, /*bLength: Endpoint Descriptor size*/ + USB_DESC_TYPE_ENDPOINT, /*bDescriptorType:*/ + + HID_EPIN_ADDR, /*bEndpointAddress: Endpoint Address (IN)*/ + 0x03, /*bmAttributes: Interrupt endpoint*/ + HID_EPIN_SIZE, /*wMaxPacketSize: 4 Byte max */ + 0x00, + HID_FS_BINTERVAL, /*bInterval: Polling Interval (10 ms)*/ + /* 34 */ +} ; + +/* USB HID device Configuration Descriptor */ +__ALIGN_BEGIN static uint8_t USBD_HID_Desc[USB_HID_DESC_SIZ] __ALIGN_END = +{ + /* 18 */ + 0x09, /*bLength: HID Descriptor size*/ + HID_DESCRIPTOR_TYPE, /*bDescriptorType: HID*/ + 0x11, /*bcdHID: HID Class Spec release number*/ + 0x01, + 0x00, /*bCountryCode: Hardware target country*/ + 0x01, /*bNumDescriptors: Number of HID class descriptors to follow*/ + 0x22, /*bDescriptorType*/ + HID_MOUSE_REPORT_DESC_SIZE,/*wItemLength: Total length of Report descriptor*/ + 0x00, +}; + +/* USB Standard Device Descriptor */ +__ALIGN_BEGIN static uint8_t USBD_HID_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = +{ + USB_LEN_DEV_QUALIFIER_DESC, + USB_DESC_TYPE_DEVICE_QUALIFIER, + 0x00, + 0x02, + 0x00, + 0x00, + 0x00, + 0x40, + 0x01, + 0x00, +}; + +__ALIGN_BEGIN static uint8_t HID_MOUSE_ReportDesc[HID_MOUSE_REPORT_DESC_SIZE] __ALIGN_END = +{ + 0x05, 0x01, + 0x09, 0x02, + 0xA1, 0x01, + 0x09, 0x01, + + 0xA1, 0x00, + 0x05, 0x09, + 0x19, 0x01, + 0x29, 0x03, + + 0x15, 0x00, + 0x25, 0x01, + 0x95, 0x03, + 0x75, 0x01, + + 0x81, 0x02, + 0x95, 0x01, + 0x75, 0x05, + 0x81, 0x01, + + 0x05, 0x01, + 0x09, 0x30, + 0x09, 0x31, + 0x09, 0x38, + + 0x15, 0x81, + 0x25, 0x7F, + 0x75, 0x08, + 0x95, 0x03, + + 0x81, 0x06, + 0xC0, 0x09, + 0x3c, 0x05, + 0xff, 0x09, + + 0x01, 0x15, + 0x00, 0x25, + 0x01, 0x75, + 0x01, 0x95, + + 0x02, 0xb1, + 0x22, 0x75, + 0x06, 0x95, + 0x01, 0xb1, + + 0x01, 0xc0 +}; + +/** + * @} + */ + +/** @defgroup USBD_HID_Private_Functions + * @{ + */ + +/** + * @brief USBD_HID_Init + * Initialize the HID interface + * @param pdev: device instance + * @param cfgidx: Configuration index + * @retval status + */ +static uint8_t USBD_HID_Init (USBD_HandleTypeDef *pdev, + uint8_t cfgidx) +{ + uint8_t ret = 0; + + /* Open EP IN */ + USBD_LL_OpenEP(pdev, + HID_EPIN_ADDR, + USBD_EP_TYPE_INTR, + HID_EPIN_SIZE); + + pdev->pClassData = USBD_malloc(sizeof (USBD_HID_HandleTypeDef)); + + if(pdev->pClassData == NULL) + { + ret = 1; + } + else + { + ((USBD_HID_HandleTypeDef *)pdev->pClassData)->state = HID_IDLE; + } + return ret; +} + +/** + * @brief USBD_HID_Init + * DeInitialize the HID layer + * @param pdev: device instance + * @param cfgidx: Configuration index + * @retval status + */ +static uint8_t USBD_HID_DeInit (USBD_HandleTypeDef *pdev, + uint8_t cfgidx) +{ + /* Close HID EPs */ + USBD_LL_CloseEP(pdev, + HID_EPIN_ADDR); + + /* FRee allocated memory */ + if(pdev->pClassData != NULL) + { + USBD_free(pdev->pClassData); + pdev->pClassData = NULL; + } + + return USBD_OK; +} + +/** + * @brief USBD_HID_Setup + * Handle the HID specific requests + * @param pdev: instance + * @param req: usb requests + * @retval status + */ +static uint8_t USBD_HID_Setup (USBD_HandleTypeDef *pdev, + USBD_SetupReqTypedef *req) +{ + uint16_t len = 0; + uint8_t *pbuf = NULL; + USBD_HID_HandleTypeDef *hhid = (USBD_HID_HandleTypeDef*) pdev->pClassData; + + switch (req->bmRequest & USB_REQ_TYPE_MASK) + { + case USB_REQ_TYPE_CLASS : + switch (req->bRequest) + { + + + case HID_REQ_SET_PROTOCOL: + hhid->Protocol = (uint8_t)(req->wValue); + break; + + case HID_REQ_GET_PROTOCOL: + USBD_CtlSendData (pdev, + (uint8_t *)&hhid->Protocol, + 1); + break; + + case HID_REQ_SET_IDLE: + hhid->IdleState = (uint8_t)(req->wValue >> 8); + break; + + case HID_REQ_GET_IDLE: + USBD_CtlSendData (pdev, + (uint8_t *)&hhid->IdleState, + 1); + break; + + default: + USBD_CtlError (pdev, req); + return USBD_FAIL; + } + break; + + case USB_REQ_TYPE_STANDARD: + switch (req->bRequest) + { + case USB_REQ_GET_DESCRIPTOR: + if( req->wValue >> 8 == HID_REPORT_DESC) + { + len = MIN(HID_MOUSE_REPORT_DESC_SIZE , req->wLength); + pbuf = HID_MOUSE_ReportDesc; + } + else if( req->wValue >> 8 == HID_DESCRIPTOR_TYPE) + { + pbuf = USBD_HID_Desc; + len = MIN(USB_HID_DESC_SIZ , req->wLength); + } + + USBD_CtlSendData (pdev, + pbuf, + len); + + break; + + case USB_REQ_GET_INTERFACE : + USBD_CtlSendData (pdev, + (uint8_t *)&hhid->AltSetting, + 1); + break; + + case USB_REQ_SET_INTERFACE : + hhid->AltSetting = (uint8_t)(req->wValue); + break; + } + } + return USBD_OK; +} + +/** + * @brief USBD_HID_SendReport + * Send HID Report + * @param pdev: device instance + * @param buff: pointer to report + * @retval status + */ +uint8_t USBD_HID_SendReport (USBD_HandleTypeDef *pdev, + uint8_t *report, + uint16_t len) +{ + USBD_HID_HandleTypeDef *hhid = (USBD_HID_HandleTypeDef*)pdev->pClassData; + + if (pdev->dev_state == USBD_STATE_CONFIGURED ) + { + if(hhid->state == HID_IDLE) + { + hhid->state = HID_BUSY; + USBD_LL_Transmit (pdev, + HID_EPIN_ADDR, + report, + len); + } + } + return USBD_OK; +} + +/** + * @brief USBD_HID_GetPollingInterval + * return polling interval from endpoint descriptor + * @param pdev: device instance + * @retval polling interval + */ +uint32_t USBD_HID_GetPollingInterval (USBD_HandleTypeDef *pdev) +{ + uint32_t polling_interval = 0; + + /* HIGH-speed endpoints */ + if(pdev->dev_speed == USBD_SPEED_HIGH) + { + /* Sets the data transfer polling interval for high speed transfers. + Values between 1..16 are allowed. Values correspond to interval + of 2 ^ (bInterval-1). This option (8 ms, corresponds to HID_HS_BINTERVAL */ + polling_interval = (((1 <<(HID_HS_BINTERVAL - 1)))/8); + } + else /* LOW and FULL-speed endpoints */ + { + /* Sets the data transfer polling interval for low and full + speed transfers */ + polling_interval = HID_FS_BINTERVAL; + } + + return ((uint32_t)(polling_interval)); +} + +/** + * @brief USBD_HID_GetCfgDesc + * return configuration descriptor + * @param speed : current device speed + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +static uint8_t *USBD_HID_GetCfgDesc (uint16_t *length) +{ + *length = sizeof (USBD_HID_CfgDesc); + return USBD_HID_CfgDesc; +} + + +/** + * @brief USBD_HID_DataIn + * handle data IN Stage + * @param pdev: device instance + * @param epnum: endpoint index + * @retval status + */ +static uint8_t USBD_HID_DataIn (USBD_HandleTypeDef *pdev, + uint8_t epnum) +{ + + /* Ensure that the FIFO is empty before a new transfer, this condition could + be caused by a new transfer before the end of the previous transfer */ + ((USBD_HID_HandleTypeDef *)pdev->pClassData)->state = HID_IDLE; + return USBD_OK; +} + + +/** +* @brief DeviceQualifierDescriptor +* return Device Qualifier descriptor +* @param length : pointer data length +* @retval pointer to descriptor buffer +*/ +static uint8_t *USBD_HID_GetDeviceQualifierDesc (uint16_t *length) +{ + *length = sizeof (USBD_HID_DeviceQualifierDesc); + return USBD_HID_DeviceQualifierDesc; +} + +/** + * @} + */ + + +/** + * @} + */ + + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/platform/mcu/stm32l475/Middlewares/USB_Device/Class/MSC/Inc/usbd_msc.h b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/MSC/Inc/usbd_msc.h new file mode 100644 index 0000000000..4ac68481a2 --- /dev/null +++ b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/MSC/Inc/usbd_msc.h @@ -0,0 +1,152 @@ +/** + ****************************************************************************** + * @file usbd_msc.h + * @author MCD Application Team + * @version V2.4.2 + * @date 11-December-2015 + * @brief Header for the usbd_msc.c file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBD_MSC_H +#define __USBD_MSC_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_msc_bot.h" +#include "usbd_msc_scsi.h" +#include "usbd_ioreq.h" + +/** @addtogroup USBD_MSC_BOT + * @{ + */ + +/** @defgroup USBD_MSC + * @brief This file is the Header file for usbd_msc.c + * @{ + */ + + +/** @defgroup USBD_BOT_Exported_Defines + * @{ + */ +#define MSC_MAX_FS_PACKET 0x40 +#define MSC_MAX_HS_PACKET 0x200 + +#define BOT_GET_MAX_LUN 0xFE +#define BOT_RESET 0xFF +#define USB_MSC_CONFIG_DESC_SIZ 32 + + +#define MSC_EPIN_ADDR 0x81 +#define MSC_EPOUT_ADDR 0x01 + +/** + * @} + */ + +/** @defgroup USB_CORE_Exported_Types + * @{ + */ +typedef struct _USBD_STORAGE +{ + int8_t (* Init) (uint8_t lun); + int8_t (* GetCapacity) (uint8_t lun, uint32_t *block_num, uint16_t *block_size); + int8_t (* IsReady) (uint8_t lun); + int8_t (* IsWriteProtected) (uint8_t lun); + int8_t (* Read) (uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len); + int8_t (* Write)(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len); + int8_t (* GetMaxLun)(void); + int8_t *pInquiry; + +}USBD_StorageTypeDef; + + +typedef struct +{ + uint32_t max_lun; + uint32_t interface; + uint8_t bot_state; + uint8_t bot_status; + uint16_t bot_data_length; + uint8_t bot_data[MSC_MEDIA_PACKET]; + USBD_MSC_BOT_CBWTypeDef cbw; + USBD_MSC_BOT_CSWTypeDef csw; + + USBD_SCSI_SenseTypeDef scsi_sense [SENSE_LIST_DEEPTH]; + uint8_t scsi_sense_head; + uint8_t scsi_sense_tail; + + uint16_t scsi_blk_size; + uint32_t scsi_blk_nbr; + + uint32_t scsi_blk_addr; + uint32_t scsi_blk_len; +} +USBD_MSC_BOT_HandleTypeDef; + +/* Structure for MSC process */ +extern USBD_ClassTypeDef USBD_MSC; +#define USBD_MSC_CLASS &USBD_MSC + +uint8_t USBD_MSC_RegisterStorage (USBD_HandleTypeDef *pdev, + USBD_StorageTypeDef *fops); +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USBD_MSC_H */ +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/platform/mcu/stm32l475/Middlewares/USB_Device/Class/MSC/Inc/usbd_msc_bot.h b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/MSC/Inc/usbd_msc_bot.h new file mode 100644 index 0000000000..5b55eb60e5 --- /dev/null +++ b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/MSC/Inc/usbd_msc_bot.h @@ -0,0 +1,178 @@ +/** + ****************************************************************************** + * @file usbd_msc_bot.h + * @author MCD Application Team + * @version V2.4.2 + * @date 11-December-2015 + * @brief Header for the usbd_msc_bot.c file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBD_MSC_BOT_H +#define __USBD_MSC_BOT_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_core.h" + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup MSC_BOT + * @brief This file is the Header file for usbd_msc_bot.c + * @{ + */ + + +/** @defgroup USBD_CORE_Exported_Defines + * @{ + */ +#define USBD_BOT_IDLE 0 /* Idle state */ +#define USBD_BOT_DATA_OUT 1 /* Data Out state */ +#define USBD_BOT_DATA_IN 2 /* Data In state */ +#define USBD_BOT_LAST_DATA_IN 3 /* Last Data In Last */ +#define USBD_BOT_SEND_DATA 4 /* Send Immediate data */ +#define USBD_BOT_NO_DATA 5 /* No data Stage */ + +#define USBD_BOT_CBW_SIGNATURE 0x43425355 +#define USBD_BOT_CSW_SIGNATURE 0x53425355 +#define USBD_BOT_CBW_LENGTH 31 +#define USBD_BOT_CSW_LENGTH 13 +#define USBD_BOT_MAX_DATA 256 + +/* CSW Status Definitions */ +#define USBD_CSW_CMD_PASSED 0x00 +#define USBD_CSW_CMD_FAILED 0x01 +#define USBD_CSW_PHASE_ERROR 0x02 + +/* BOT Status */ +#define USBD_BOT_STATUS_NORMAL 0 +#define USBD_BOT_STATUS_RECOVERY 1 +#define USBD_BOT_STATUS_ERROR 2 + + +#define USBD_DIR_IN 0 +#define USBD_DIR_OUT 1 +#define USBD_BOTH_DIR 2 + +/** + * @} + */ + +/** @defgroup MSC_CORE_Private_TypesDefinitions + * @{ + */ + +typedef struct +{ + uint32_t dSignature; + uint32_t dTag; + uint32_t dDataLength; + uint8_t bmFlags; + uint8_t bLUN; + uint8_t bCBLength; + uint8_t CB[16]; + uint8_t ReservedForAlign; +} +USBD_MSC_BOT_CBWTypeDef; + + +typedef struct +{ + uint32_t dSignature; + uint32_t dTag; + uint32_t dDataResidue; + uint8_t bStatus; + uint8_t ReservedForAlign[3]; +} +USBD_MSC_BOT_CSWTypeDef; + +/** + * @} + */ + + +/** @defgroup USBD_CORE_Exported_Types + * @{ + */ + +/** + * @} + */ +/** @defgroup USBD_CORE_Exported_FunctionsPrototypes + * @{ + */ +void MSC_BOT_Init (USBD_HandleTypeDef *pdev); +void MSC_BOT_Reset (USBD_HandleTypeDef *pdev); +void MSC_BOT_DeInit (USBD_HandleTypeDef *pdev); +void MSC_BOT_DataIn (USBD_HandleTypeDef *pdev, + uint8_t epnum); + +void MSC_BOT_DataOut (USBD_HandleTypeDef *pdev, + uint8_t epnum); + +void MSC_BOT_SendCSW (USBD_HandleTypeDef *pdev, + uint8_t CSW_Status); + +void MSC_BOT_CplClrFeature (USBD_HandleTypeDef *pdev, + uint8_t epnum); +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USBD_MSC_BOT_H */ +/** + * @} + */ + +/** +* @} +*/ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/platform/mcu/stm32l475/Middlewares/USB_Device/Class/MSC/Inc/usbd_msc_data.h b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/MSC/Inc/usbd_msc_data.h new file mode 100644 index 0000000000..6521d4a437 --- /dev/null +++ b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/MSC/Inc/usbd_msc_data.h @@ -0,0 +1,131 @@ +/** + ****************************************************************************** + * @file usbd_msc_data.h + * @author MCD Application Team + * @version V2.4.2 + * @date 11-December-2015 + * @brief Header for the usbd_msc_data.c file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBD_MSC_DATA_H +#define __USBD_MSC_DATA_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_conf.h" + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USB_INFO + * @brief general defines for the usb device library file + * @{ + */ + +/** @defgroup USB_INFO_Exported_Defines + * @{ + */ +#define MODE_SENSE6_LEN 8 +#define MODE_SENSE10_LEN 8 +#define LENGTH_INQUIRY_PAGE00 7 +#define LENGTH_FORMAT_CAPACITIES 20 + +/** + * @} + */ + + +/** @defgroup USBD_INFO_Exported_TypesDefinitions + * @{ + */ +/** + * @} + */ + + + +/** @defgroup USBD_INFO_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_INFO_Exported_Variables + * @{ + */ +extern const uint8_t MSC_Page00_Inquiry_Data[]; +extern const uint8_t MSC_Mode_Sense6_data[]; +extern const uint8_t MSC_Mode_Sense10_data[] ; + +/** + * @} + */ + +/** @defgroup USBD_INFO_Exported_FunctionsPrototype + * @{ + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USBD_MSC_DATA_H */ + +/** + * @} + */ + +/** +* @} +*/ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/platform/mcu/stm32l475/Middlewares/USB_Device/Class/MSC/Inc/usbd_msc_scsi.h b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/MSC/Inc/usbd_msc_scsi.h new file mode 100644 index 0000000000..0b274a48c1 --- /dev/null +++ b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/MSC/Inc/usbd_msc_scsi.h @@ -0,0 +1,221 @@ +/** + ****************************************************************************** + * @file usbd_msc_scsi.h + * @author MCD Application Team + * @version V2.4.2 + * @date 11-December-2015 + * @brief Header for the usbd_msc_scsi.c file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBD_MSC_SCSI_H +#define __USBD_MSC_SCSI_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_def.h" + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USBD_SCSI + * @brief header file for the storage disk file + * @{ + */ + +/** @defgroup USBD_SCSI_Exported_Defines + * @{ + */ + +#define SENSE_LIST_DEEPTH 4 + +/* SCSI Commands */ +#define SCSI_FORMAT_UNIT 0x04 +#define SCSI_INQUIRY 0x12 +#define SCSI_MODE_SELECT6 0x15 +#define SCSI_MODE_SELECT10 0x55 +#define SCSI_MODE_SENSE6 0x1A +#define SCSI_MODE_SENSE10 0x5A +#define SCSI_ALLOW_MEDIUM_REMOVAL 0x1E +#define SCSI_READ6 0x08 +#define SCSI_READ10 0x28 +#define SCSI_READ12 0xA8 +#define SCSI_READ16 0x88 + +#define SCSI_READ_CAPACITY10 0x25 +#define SCSI_READ_CAPACITY16 0x9E + +#define SCSI_REQUEST_SENSE 0x03 +#define SCSI_START_STOP_UNIT 0x1B +#define SCSI_TEST_UNIT_READY 0x00 +#define SCSI_WRITE6 0x0A +#define SCSI_WRITE10 0x2A +#define SCSI_WRITE12 0xAA +#define SCSI_WRITE16 0x8A + +#define SCSI_VERIFY10 0x2F +#define SCSI_VERIFY12 0xAF +#define SCSI_VERIFY16 0x8F + +#define SCSI_SEND_DIAGNOSTIC 0x1D +#define SCSI_READ_FORMAT_CAPACITIES 0x23 + +#define NO_SENSE 0 +#define RECOVERED_ERROR 1 +#define NOT_READY 2 +#define MEDIUM_ERROR 3 +#define HARDWARE_ERROR 4 +#define ILLEGAL_REQUEST 5 +#define UNIT_ATTENTION 6 +#define DATA_PROTECT 7 +#define BLANK_CHECK 8 +#define VENDOR_SPECIFIC 9 +#define COPY_ABORTED 10 +#define ABORTED_COMMAND 11 +#define VOLUME_OVERFLOW 13 +#define MISCOMPARE 14 + + +#define INVALID_CDB 0x20 +#define INVALID_FIELED_IN_COMMAND 0x24 +#define PARAMETER_LIST_LENGTH_ERROR 0x1A +#define INVALID_FIELD_IN_PARAMETER_LIST 0x26 +#define ADDRESS_OUT_OF_RANGE 0x21 +#define MEDIUM_NOT_PRESENT 0x3A +#define MEDIUM_HAVE_CHANGED 0x28 +#define WRITE_PROTECTED 0x27 +#define UNRECOVERED_READ_ERROR 0x11 +#define WRITE_FAULT 0x03 + +#define READ_FORMAT_CAPACITY_DATA_LEN 0x0C +#define READ_CAPACITY10_DATA_LEN 0x08 +#define MODE_SENSE10_DATA_LEN 0x08 +#define MODE_SENSE6_DATA_LEN 0x04 +#define REQUEST_SENSE_DATA_LEN 0x12 +#define STANDARD_INQUIRY_DATA_LEN 0x24 +#define BLKVFY 0x04 + +extern uint8_t Page00_Inquiry_Data[]; +extern uint8_t Standard_Inquiry_Data[]; +extern uint8_t Standard_Inquiry_Data2[]; +extern uint8_t Mode_Sense6_data[]; +extern uint8_t Mode_Sense10_data[]; +extern uint8_t Scsi_Sense_Data[]; +extern uint8_t ReadCapacity10_Data[]; +extern uint8_t ReadFormatCapacity_Data []; +/** + * @} + */ + + +/** @defgroup USBD_SCSI_Exported_TypesDefinitions + * @{ + */ + +typedef struct _SENSE_ITEM { + char Skey; + union { + struct _ASCs { + char ASC; + char ASCQ; + }b; + unsigned int ASC; + char *pData; + } w; +} USBD_SCSI_SenseTypeDef; +/** + * @} + */ + +/** @defgroup USBD_SCSI_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_SCSI_Exported_Variables + * @{ + */ + +/** + * @} + */ +/** @defgroup USBD_SCSI_Exported_FunctionsPrototype + * @{ + */ +int8_t SCSI_ProcessCmd(USBD_HandleTypeDef *pdev, + uint8_t lun, + uint8_t *cmd); + +void SCSI_SenseCode(USBD_HandleTypeDef *pdev, + uint8_t lun, + uint8_t sKey, + uint8_t ASC); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USBD_MSC_SCSI_H */ +/** + * @} + */ + +/** + * @} + */ + +/** +* @} +*/ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/platform/mcu/stm32l475/Middlewares/USB_Device/Class/MSC/Inc/usbd_msc_storage_template.h b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/MSC/Inc/usbd_msc_storage_template.h new file mode 100644 index 0000000000..02594380cf --- /dev/null +++ b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/MSC/Inc/usbd_msc_storage_template.h @@ -0,0 +1,125 @@ +/** + ****************************************************************************** + * @file usbd_msc_storage.h + * @author MCD Application Team + * @version V2.4.2 + * @date 11-December-2015 + * @brief Header file for the usbd_msc_storage.c file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBD_MSC_STORAGE_H +#define __USBD_MSC_STORAGE_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_msc.h" + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USBD_STORAGE + * @brief header file for the usbd_msc_storage.c file + * @{ + */ + +/** @defgroup USBD_STORAGE_Exported_Defines + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_STORAGE_Exported_Types + * @{ + */ + + +/** + * @} + */ + + + +/** @defgroup USBD_STORAGE_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_STORAGE_Exported_Variables + * @{ + */ +extern USBD_StorageTypeDef USBD_MSC_Template_fops; +/** + * @} + */ + +/** @defgroup USBD_STORAGE_Exported_FunctionsPrototype + * @{ + */ + + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USBD_MSC_STORAGE_H */ + +/** + * @} + */ + +/** +* @} +*/ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/platform/mcu/stm32l475/Middlewares/USB_Device/Class/MSC/Src/usbd_msc.c b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/MSC/Src/usbd_msc.c new file mode 100644 index 0000000000..f482ce6177 --- /dev/null +++ b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/MSC/Src/usbd_msc.c @@ -0,0 +1,629 @@ +/** + ****************************************************************************** + * @file usbd_msc.c + * @author MCD Application Team + * @version V2.4.2 + * @date 11-December-2015 + * @brief This file provides all the MSC core functions. + * + * @verbatim + * + * =================================================================== + * MSC Class Description + * =================================================================== + * This module manages the MSC class V1.0 following the "Universal + * Serial Bus Mass Storage Class (MSC) Bulk-Only Transport (BOT) Version 1.0 + * Sep. 31, 1999". + * This driver implements the following aspects of the specification: + * - Bulk-Only Transport protocol + * - Subclass : SCSI transparent command set (ref. SCSI Primary Commands - 3 (SPC-3)) + * + * @endverbatim + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_msc.h" + + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup MSC_CORE + * @brief Mass storage core module + * @{ + */ + +/** @defgroup MSC_CORE_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup MSC_CORE_Private_Defines + * @{ + */ + +/** + * @} + */ + + +/** @defgroup MSC_CORE_Private_Macros + * @{ + */ +/** + * @} + */ + + +/** @defgroup MSC_CORE_Private_FunctionPrototypes + * @{ + */ +uint8_t USBD_MSC_Init (USBD_HandleTypeDef *pdev, + uint8_t cfgidx); + +uint8_t USBD_MSC_DeInit (USBD_HandleTypeDef *pdev, + uint8_t cfgidx); + +uint8_t USBD_MSC_Setup (USBD_HandleTypeDef *pdev, + USBD_SetupReqTypedef *req); + +uint8_t USBD_MSC_DataIn (USBD_HandleTypeDef *pdev, + uint8_t epnum); + + +uint8_t USBD_MSC_DataOut (USBD_HandleTypeDef *pdev, + uint8_t epnum); + +uint8_t *USBD_MSC_GetHSCfgDesc (uint16_t *length); + +uint8_t *USBD_MSC_GetFSCfgDesc (uint16_t *length); + +uint8_t *USBD_MSC_GetOtherSpeedCfgDesc (uint16_t *length); + +uint8_t *USBD_MSC_GetDeviceQualifierDescriptor (uint16_t *length); + + +/** + * @} + */ + + +/** @defgroup MSC_CORE_Private_Variables + * @{ + */ + + +USBD_ClassTypeDef USBD_MSC = +{ + USBD_MSC_Init, + USBD_MSC_DeInit, + USBD_MSC_Setup, + NULL, /*EP0_TxSent*/ + NULL, /*EP0_RxReady*/ + USBD_MSC_DataIn, + USBD_MSC_DataOut, + NULL, /*SOF */ + NULL, + NULL, + USBD_MSC_GetHSCfgDesc, + USBD_MSC_GetFSCfgDesc, + USBD_MSC_GetOtherSpeedCfgDesc, + USBD_MSC_GetDeviceQualifierDescriptor, +}; + +/* USB Mass storage device Configuration Descriptor */ +/* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */ +__ALIGN_BEGIN uint8_t USBD_MSC_CfgHSDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIGN_END = +{ + + 0x09, /* bLength: Configuation Descriptor size */ + USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ + USB_MSC_CONFIG_DESC_SIZ, + + 0x00, + 0x01, /* bNumInterfaces: 1 interface */ + 0x01, /* bConfigurationValue: */ + 0x04, /* iConfiguration: */ + 0xC0, /* bmAttributes: */ + 0x32, /* MaxPower 100 mA */ + + /******************** Mass Storage interface ********************/ + 0x09, /* bLength: Interface Descriptor size */ + 0x04, /* bDescriptorType: */ + 0x00, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x02, /* bNumEndpoints*/ + 0x08, /* bInterfaceClass: MSC Class */ + 0x06, /* bInterfaceSubClass : SCSI transparent*/ + 0x50, /* nInterfaceProtocol */ + 0x05, /* iInterface: */ + /******************** Mass Storage Endpoints ********************/ + 0x07, /*Endpoint descriptor length = 7*/ + 0x05, /*Endpoint descriptor type */ + MSC_EPIN_ADDR, /*Endpoint address (IN, address 1) */ + 0x02, /*Bulk endpoint type */ + LOBYTE(MSC_MAX_HS_PACKET), + HIBYTE(MSC_MAX_HS_PACKET), + 0x00, /*Polling interval in milliseconds */ + + 0x07, /*Endpoint descriptor length = 7 */ + 0x05, /*Endpoint descriptor type */ + MSC_EPOUT_ADDR, /*Endpoint address (OUT, address 1) */ + 0x02, /*Bulk endpoint type */ + LOBYTE(MSC_MAX_HS_PACKET), + HIBYTE(MSC_MAX_HS_PACKET), + 0x00 /*Polling interval in milliseconds*/ +}; + +/* USB Mass storage device Configuration Descriptor */ +/* All Descriptors (Configuration, Interface, Endpoint, Class, Vendor */ +uint8_t USBD_MSC_CfgFSDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIGN_END = +{ + + 0x09, /* bLength: Configuation Descriptor size */ + USB_DESC_TYPE_CONFIGURATION, /* bDescriptorType: Configuration */ + USB_MSC_CONFIG_DESC_SIZ, + + 0x00, + 0x01, /* bNumInterfaces: 1 interface */ + 0x01, /* bConfigurationValue: */ + 0x04, /* iConfiguration: */ + 0xC0, /* bmAttributes: */ + 0x32, /* MaxPower 100 mA */ + + /******************** Mass Storage interface ********************/ + 0x09, /* bLength: Interface Descriptor size */ + 0x04, /* bDescriptorType: */ + 0x00, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x02, /* bNumEndpoints*/ + 0x08, /* bInterfaceClass: MSC Class */ + 0x06, /* bInterfaceSubClass : SCSI transparent*/ + 0x50, /* nInterfaceProtocol */ + 0x05, /* iInterface: */ + /******************** Mass Storage Endpoints ********************/ + 0x07, /*Endpoint descriptor length = 7*/ + 0x05, /*Endpoint descriptor type */ + MSC_EPIN_ADDR, /*Endpoint address (IN, address 1) */ + 0x02, /*Bulk endpoint type */ + LOBYTE(MSC_MAX_FS_PACKET), + HIBYTE(MSC_MAX_FS_PACKET), + 0x00, /*Polling interval in milliseconds */ + + 0x07, /*Endpoint descriptor length = 7 */ + 0x05, /*Endpoint descriptor type */ + MSC_EPOUT_ADDR, /*Endpoint address (OUT, address 1) */ + 0x02, /*Bulk endpoint type */ + LOBYTE(MSC_MAX_FS_PACKET), + HIBYTE(MSC_MAX_FS_PACKET), + 0x00 /*Polling interval in milliseconds*/ +}; + +__ALIGN_BEGIN uint8_t USBD_MSC_OtherSpeedCfgDesc[USB_MSC_CONFIG_DESC_SIZ] __ALIGN_END = +{ + + 0x09, /* bLength: Configuation Descriptor size */ + USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION, + USB_MSC_CONFIG_DESC_SIZ, + + 0x00, + 0x01, /* bNumInterfaces: 1 interface */ + 0x01, /* bConfigurationValue: */ + 0x04, /* iConfiguration: */ + 0xC0, /* bmAttributes: */ + 0x32, /* MaxPower 100 mA */ + + /******************** Mass Storage interface ********************/ + 0x09, /* bLength: Interface Descriptor size */ + 0x04, /* bDescriptorType: */ + 0x00, /* bInterfaceNumber: Number of Interface */ + 0x00, /* bAlternateSetting: Alternate setting */ + 0x02, /* bNumEndpoints*/ + 0x08, /* bInterfaceClass: MSC Class */ + 0x06, /* bInterfaceSubClass : SCSI transparent command set*/ + 0x50, /* nInterfaceProtocol */ + 0x05, /* iInterface: */ + /******************** Mass Storage Endpoints ********************/ + 0x07, /*Endpoint descriptor length = 7*/ + 0x05, /*Endpoint descriptor type */ + MSC_EPIN_ADDR, /*Endpoint address (IN, address 1) */ + 0x02, /*Bulk endpoint type */ + 0x40, + 0x00, + 0x00, /*Polling interval in milliseconds */ + + 0x07, /*Endpoint descriptor length = 7 */ + 0x05, /*Endpoint descriptor type */ + MSC_EPOUT_ADDR, /*Endpoint address (OUT, address 1) */ + 0x02, /*Bulk endpoint type */ + 0x40, + 0x00, + 0x00 /*Polling interval in milliseconds*/ +}; + +/* USB Standard Device Descriptor */ +__ALIGN_BEGIN uint8_t USBD_MSC_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] __ALIGN_END = +{ + USB_LEN_DEV_QUALIFIER_DESC, + USB_DESC_TYPE_DEVICE_QUALIFIER, + 0x00, + 0x02, + 0x00, + 0x00, + 0x00, + MSC_MAX_FS_PACKET, + 0x01, + 0x00, +}; +/** + * @} + */ + + +/** @defgroup MSC_CORE_Private_Functions + * @{ + */ + +/** + * @brief USBD_MSC_Init + * Initialize the mass storage configuration + * @param pdev: device instance + * @param cfgidx: configuration index + * @retval status + */ +uint8_t USBD_MSC_Init (USBD_HandleTypeDef *pdev, + uint8_t cfgidx) +{ + int16_t ret = 0; + + if(pdev->dev_speed == USBD_SPEED_HIGH ) + { + /* Open EP OUT */ + USBD_LL_OpenEP(pdev, + MSC_EPOUT_ADDR, + USBD_EP_TYPE_BULK, + MSC_MAX_HS_PACKET); + + /* Open EP IN */ + USBD_LL_OpenEP(pdev, + MSC_EPIN_ADDR, + USBD_EP_TYPE_BULK, + MSC_MAX_HS_PACKET); + } + else + { + /* Open EP OUT */ + USBD_LL_OpenEP(pdev, + MSC_EPOUT_ADDR, + USBD_EP_TYPE_BULK, + MSC_MAX_FS_PACKET); + + /* Open EP IN */ + USBD_LL_OpenEP(pdev, + MSC_EPIN_ADDR, + USBD_EP_TYPE_BULK, + MSC_MAX_FS_PACKET); + } + pdev->pClassData = USBD_malloc(sizeof (USBD_MSC_BOT_HandleTypeDef)); + + if(pdev->pClassData == NULL) + { + ret = 1; + } + else + { + /* Init the BOT layer */ + MSC_BOT_Init(pdev); + ret = 0; + } + + return ret; +} + +/** + * @brief USBD_MSC_DeInit + * DeInitilaize the mass storage configuration + * @param pdev: device instance + * @param cfgidx: configuration index + * @retval status + */ +uint8_t USBD_MSC_DeInit (USBD_HandleTypeDef *pdev, + uint8_t cfgidx) +{ + /* Close MSC EPs */ + USBD_LL_CloseEP(pdev, + MSC_EPOUT_ADDR); + + /* Open EP IN */ + USBD_LL_CloseEP(pdev, + MSC_EPIN_ADDR); + + + /* De-Init the BOT layer */ + MSC_BOT_DeInit(pdev); + + /* Free MSC Class Resources */ + if(pdev->pClassData != NULL) + { + USBD_free(pdev->pClassData); + pdev->pClassData = NULL; + } + return 0; +} +/** +* @brief USBD_MSC_Setup +* Handle the MSC specific requests +* @param pdev: device instance +* @param req: USB request +* @retval status +*/ +uint8_t USBD_MSC_Setup (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req) +{ + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef*) pdev->pClassData; + + switch (req->bmRequest & USB_REQ_TYPE_MASK) + { + + /* Class request */ + case USB_REQ_TYPE_CLASS : + switch (req->bRequest) + { + case BOT_GET_MAX_LUN : + + if((req->wValue == 0) && + (req->wLength == 1) && + ((req->bmRequest & 0x80) == 0x80)) + { + hmsc->max_lun = ((USBD_StorageTypeDef *)pdev->pUserData)->GetMaxLun(); + USBD_CtlSendData (pdev, + (uint8_t *)&hmsc->max_lun, + 1); + } + else + { + USBD_CtlError(pdev , req); + return USBD_FAIL; + } + break; + + case BOT_RESET : + if((req->wValue == 0) && + (req->wLength == 0) && + ((req->bmRequest & 0x80) != 0x80)) + { + MSC_BOT_Reset(pdev); + } + else + { + USBD_CtlError(pdev , req); + return USBD_FAIL; + } + break; + + default: + USBD_CtlError(pdev , req); + return USBD_FAIL; + } + break; + /* Interface & Endpoint request */ + case USB_REQ_TYPE_STANDARD: + switch (req->bRequest) + { + case USB_REQ_GET_INTERFACE : + USBD_CtlSendData (pdev, + (uint8_t *)&hmsc->interface, + 1); + break; + + case USB_REQ_SET_INTERFACE : + hmsc->interface = (uint8_t)(req->wValue); + break; + + case USB_REQ_CLEAR_FEATURE: + + /* Flush the FIFO and Clear the stall status */ + USBD_LL_FlushEP(pdev, (uint8_t)req->wIndex); + + /* Reactivate the EP */ + USBD_LL_CloseEP (pdev , (uint8_t)req->wIndex); + if((((uint8_t)req->wIndex) & 0x80) == 0x80) + { + if(pdev->dev_speed == USBD_SPEED_HIGH ) + { + /* Open EP IN */ + USBD_LL_OpenEP(pdev, + MSC_EPIN_ADDR, + USBD_EP_TYPE_BULK, + MSC_MAX_HS_PACKET); + } + else + { + /* Open EP IN */ + USBD_LL_OpenEP(pdev, + MSC_EPIN_ADDR, + USBD_EP_TYPE_BULK, + MSC_MAX_FS_PACKET); + } + } + else + { + if(pdev->dev_speed == USBD_SPEED_HIGH ) + { + /* Open EP IN */ + USBD_LL_OpenEP(pdev, + MSC_EPOUT_ADDR, + USBD_EP_TYPE_BULK, + MSC_MAX_HS_PACKET); + } + else + { + /* Open EP IN */ + USBD_LL_OpenEP(pdev, + MSC_EPOUT_ADDR, + USBD_EP_TYPE_BULK, + MSC_MAX_FS_PACKET); + } + } + + /* Handle BOT error */ + MSC_BOT_CplClrFeature(pdev, (uint8_t)req->wIndex); + break; + + } + break; + + default: + break; + } + return 0; +} + +/** +* @brief USBD_MSC_DataIn +* handle data IN Stage +* @param pdev: device instance +* @param epnum: endpoint index +* @retval status +*/ +uint8_t USBD_MSC_DataIn (USBD_HandleTypeDef *pdev, + uint8_t epnum) +{ + MSC_BOT_DataIn(pdev , epnum); + return 0; +} + +/** +* @brief USBD_MSC_DataOut +* handle data OUT Stage +* @param pdev: device instance +* @param epnum: endpoint index +* @retval status +*/ +uint8_t USBD_MSC_DataOut (USBD_HandleTypeDef *pdev, + uint8_t epnum) +{ + MSC_BOT_DataOut(pdev , epnum); + return 0; +} + +/** +* @brief USBD_MSC_GetHSCfgDesc +* return configuration descriptor +* @param length : pointer data length +* @retval pointer to descriptor buffer +*/ +uint8_t *USBD_MSC_GetHSCfgDesc (uint16_t *length) +{ + *length = sizeof (USBD_MSC_CfgHSDesc); + return USBD_MSC_CfgHSDesc; +} + +/** +* @brief USBD_MSC_GetFSCfgDesc +* return configuration descriptor +* @param length : pointer data length +* @retval pointer to descriptor buffer +*/ +uint8_t *USBD_MSC_GetFSCfgDesc (uint16_t *length) +{ + *length = sizeof (USBD_MSC_CfgFSDesc); + return USBD_MSC_CfgFSDesc; +} + +/** +* @brief USBD_MSC_GetOtherSpeedCfgDesc +* return other speed configuration descriptor +* @param length : pointer data length +* @retval pointer to descriptor buffer +*/ +uint8_t *USBD_MSC_GetOtherSpeedCfgDesc (uint16_t *length) +{ + *length = sizeof (USBD_MSC_OtherSpeedCfgDesc); + return USBD_MSC_OtherSpeedCfgDesc; +} +/** +* @brief DeviceQualifierDescriptor +* return Device Qualifier descriptor +* @param length : pointer data length +* @retval pointer to descriptor buffer +*/ +uint8_t *USBD_MSC_GetDeviceQualifierDescriptor (uint16_t *length) +{ + *length = sizeof (USBD_MSC_DeviceQualifierDesc); + return USBD_MSC_DeviceQualifierDesc; +} + +/** +* @brief USBD_MSC_RegisterStorage +* @param fops: storage callback +* @retval status +*/ +uint8_t USBD_MSC_RegisterStorage (USBD_HandleTypeDef *pdev, + USBD_StorageTypeDef *fops) +{ + if(fops != NULL) + { + pdev->pUserData= fops; + } + return 0; +} + +/** + * @} + */ + + +/** + * @} + */ + + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/platform/mcu/stm32l475/Middlewares/USB_Device/Class/MSC/Src/usbd_msc_bot.c b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/MSC/Src/usbd_msc_bot.c new file mode 100644 index 0000000000..9164be95b5 --- /dev/null +++ b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/MSC/Src/usbd_msc_bot.c @@ -0,0 +1,427 @@ +/** + ****************************************************************************** + * @file usbd_msc_bot.c + * @author MCD Application Team + * @version V2.4.2 + * @date 11-December-2015 + * @brief This file provides all the BOT protocol core functions. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_msc_bot.h" +#include "usbd_msc.h" +#include "usbd_msc_scsi.h" +#include "usbd_ioreq.h" + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup MSC_BOT + * @brief BOT protocol module + * @{ + */ + +/** @defgroup MSC_BOT_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup MSC_BOT_Private_Defines + * @{ + */ + +/** + * @} + */ + + +/** @defgroup MSC_BOT_Private_Macros + * @{ + */ +/** + * @} + */ + + +/** @defgroup MSC_BOT_Private_Variables + * @{ + */ + +/** + * @} + */ + + +/** @defgroup MSC_BOT_Private_FunctionPrototypes + * @{ + */ +static void MSC_BOT_CBW_Decode (USBD_HandleTypeDef *pdev); + +static void MSC_BOT_SendData (USBD_HandleTypeDef *pdev, + uint8_t* pbuf, + uint16_t len); + +static void MSC_BOT_Abort(USBD_HandleTypeDef *pdev); +/** + * @} + */ + + +/** @defgroup MSC_BOT_Private_Functions + * @{ + */ + + + +/** +* @brief MSC_BOT_Init +* Initialize the BOT Process +* @param pdev: device instance +* @retval None +*/ +void MSC_BOT_Init (USBD_HandleTypeDef *pdev) +{ + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef*)pdev->pClassData; + + hmsc->bot_state = USBD_BOT_IDLE; + hmsc->bot_status = USBD_BOT_STATUS_NORMAL; + + hmsc->scsi_sense_tail = 0; + hmsc->scsi_sense_head = 0; + + ((USBD_StorageTypeDef *)pdev->pUserData)->Init(0); + + USBD_LL_FlushEP(pdev, MSC_EPOUT_ADDR); + USBD_LL_FlushEP(pdev, MSC_EPIN_ADDR); + + /* Prapare EP to Receive First BOT Cmd */ + USBD_LL_PrepareReceive (pdev, + MSC_EPOUT_ADDR, + (uint8_t *)&hmsc->cbw, + USBD_BOT_CBW_LENGTH); +} + +/** +* @brief MSC_BOT_Reset +* Reset the BOT Machine +* @param pdev: device instance +* @retval None +*/ +void MSC_BOT_Reset (USBD_HandleTypeDef *pdev) +{ + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef*)pdev->pClassData; + + hmsc->bot_state = USBD_BOT_IDLE; + hmsc->bot_status = USBD_BOT_STATUS_RECOVERY; + + /* Prapare EP to Receive First BOT Cmd */ + USBD_LL_PrepareReceive (pdev, + MSC_EPOUT_ADDR, + (uint8_t *)&hmsc->cbw, + USBD_BOT_CBW_LENGTH); +} + +/** +* @brief MSC_BOT_DeInit +* Deinitialize the BOT Machine +* @param pdev: device instance +* @retval None +*/ +void MSC_BOT_DeInit (USBD_HandleTypeDef *pdev) +{ + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef*)pdev->pClassData; + hmsc->bot_state = USBD_BOT_IDLE; +} + +/** +* @brief MSC_BOT_DataIn +* Handle BOT IN data stage +* @param pdev: device instance +* @param epnum: endpoint index +* @retval None +*/ +void MSC_BOT_DataIn (USBD_HandleTypeDef *pdev, + uint8_t epnum) +{ + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef*)pdev->pClassData; + + switch (hmsc->bot_state) + { + case USBD_BOT_DATA_IN: + if(SCSI_ProcessCmd(pdev, + hmsc->cbw.bLUN, + &hmsc->cbw.CB[0]) < 0) + { + MSC_BOT_SendCSW (pdev, USBD_CSW_CMD_FAILED); + } + break; + + case USBD_BOT_SEND_DATA: + case USBD_BOT_LAST_DATA_IN: + MSC_BOT_SendCSW (pdev, USBD_CSW_CMD_PASSED); + + break; + + default: + break; + } +} +/** +* @brief MSC_BOT_DataOut +* Process MSC OUT data +* @param pdev: device instance +* @param epnum: endpoint index +* @retval None +*/ +void MSC_BOT_DataOut (USBD_HandleTypeDef *pdev, + uint8_t epnum) +{ + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef*)pdev->pClassData; + + switch (hmsc->bot_state) + { + case USBD_BOT_IDLE: + MSC_BOT_CBW_Decode(pdev); + break; + + case USBD_BOT_DATA_OUT: + + if(SCSI_ProcessCmd(pdev, + hmsc->cbw.bLUN, + &hmsc->cbw.CB[0]) < 0) + { + MSC_BOT_SendCSW (pdev, USBD_CSW_CMD_FAILED); + } + + break; + + default: + break; + } +} + +/** +* @brief MSC_BOT_CBW_Decode +* Decode the CBW command and set the BOT state machine accordingly +* @param pdev: device instance +* @retval None +*/ +static void MSC_BOT_CBW_Decode (USBD_HandleTypeDef *pdev) +{ + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef*)pdev->pClassData; + + hmsc->csw.dTag = hmsc->cbw.dTag; + hmsc->csw.dDataResidue = hmsc->cbw.dDataLength; + + if ((USBD_LL_GetRxDataSize (pdev ,MSC_EPOUT_ADDR) != USBD_BOT_CBW_LENGTH) || + (hmsc->cbw.dSignature != USBD_BOT_CBW_SIGNATURE)|| + (hmsc->cbw.bLUN > 1) || + (hmsc->cbw.bCBLength < 1) || + (hmsc->cbw.bCBLength > 16)) + { + + SCSI_SenseCode(pdev, + hmsc->cbw.bLUN, + ILLEGAL_REQUEST, + INVALID_CDB); + + hmsc->bot_status = USBD_BOT_STATUS_ERROR; + MSC_BOT_Abort(pdev); + + } + else + { + if(SCSI_ProcessCmd(pdev, + hmsc->cbw.bLUN, + &hmsc->cbw.CB[0]) < 0) + { + if(hmsc->bot_state == USBD_BOT_NO_DATA) + { + MSC_BOT_SendCSW (pdev, + USBD_CSW_CMD_FAILED); + } + else + { + MSC_BOT_Abort(pdev); + } + } + /*Burst xfer handled internally*/ + else if ((hmsc->bot_state != USBD_BOT_DATA_IN) && + (hmsc->bot_state != USBD_BOT_DATA_OUT) && + (hmsc->bot_state != USBD_BOT_LAST_DATA_IN)) + { + if (hmsc->bot_data_length > 0) + { + MSC_BOT_SendData(pdev, + hmsc->bot_data, + hmsc->bot_data_length); + } + else if (hmsc->bot_data_length == 0) + { + MSC_BOT_SendCSW (pdev, + USBD_CSW_CMD_PASSED); + } + } + } +} + +/** +* @brief MSC_BOT_SendData +* Send the requested data +* @param pdev: device instance +* @param buf: pointer to data buffer +* @param len: Data Length +* @retval None +*/ +static void MSC_BOT_SendData(USBD_HandleTypeDef *pdev, + uint8_t* buf, + uint16_t len) +{ + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef*)pdev->pClassData; + + len = MIN (hmsc->cbw.dDataLength, len); + hmsc->csw.dDataResidue -= len; + hmsc->csw.bStatus = USBD_CSW_CMD_PASSED; + hmsc->bot_state = USBD_BOT_SEND_DATA; + + USBD_LL_Transmit (pdev, MSC_EPIN_ADDR, buf, len); +} + +/** +* @brief MSC_BOT_SendCSW +* Send the Command Status Wrapper +* @param pdev: device instance +* @param status : CSW status +* @retval None +*/ +void MSC_BOT_SendCSW (USBD_HandleTypeDef *pdev, + uint8_t CSW_Status) +{ + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef*)pdev->pClassData; + + hmsc->csw.dSignature = USBD_BOT_CSW_SIGNATURE; + hmsc->csw.bStatus = CSW_Status; + hmsc->bot_state = USBD_BOT_IDLE; + + USBD_LL_Transmit (pdev, + MSC_EPIN_ADDR, + (uint8_t *)&hmsc->csw, + USBD_BOT_CSW_LENGTH); + + /* Prepare EP to Receive next Cmd */ + USBD_LL_PrepareReceive (pdev, + MSC_EPOUT_ADDR, + (uint8_t *)&hmsc->cbw, + USBD_BOT_CBW_LENGTH); + +} + +/** +* @brief MSC_BOT_Abort +* Abort the current transfer +* @param pdev: device instance +* @retval status +*/ + +static void MSC_BOT_Abort (USBD_HandleTypeDef *pdev) +{ + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef*)pdev->pClassData; + + if ((hmsc->cbw.bmFlags == 0) && + (hmsc->cbw.dDataLength != 0) && + (hmsc->bot_status == USBD_BOT_STATUS_NORMAL) ) + { + USBD_LL_StallEP(pdev, MSC_EPOUT_ADDR ); + } + USBD_LL_StallEP(pdev, MSC_EPIN_ADDR); + + if(hmsc->bot_status == USBD_BOT_STATUS_ERROR) + { + USBD_LL_PrepareReceive (pdev, + MSC_EPOUT_ADDR, + (uint8_t *)&hmsc->cbw, + USBD_BOT_CBW_LENGTH); + } +} + +/** +* @brief MSC_BOT_CplClrFeature +* Complete the clear feature request +* @param pdev: device instance +* @param epnum: endpoint index +* @retval None +*/ + +void MSC_BOT_CplClrFeature (USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef*)pdev->pClassData; + + if(hmsc->bot_status == USBD_BOT_STATUS_ERROR )/* Bad CBW Signature */ + { + USBD_LL_StallEP(pdev, MSC_EPIN_ADDR); + hmsc->bot_status = USBD_BOT_STATUS_NORMAL; + } + else if(((epnum & 0x80) == 0x80) && ( hmsc->bot_status != USBD_BOT_STATUS_RECOVERY)) + { + MSC_BOT_SendCSW (pdev, USBD_CSW_CMD_FAILED); + } + +} +/** + * @} + */ + + +/** + * @} + */ + + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/platform/mcu/stm32l475/Middlewares/USB_Device/Class/MSC/Src/usbd_msc_data.c b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/MSC/Src/usbd_msc_data.c new file mode 100644 index 0000000000..48fb1d2f47 --- /dev/null +++ b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/MSC/Src/usbd_msc_data.c @@ -0,0 +1,154 @@ +/** + ****************************************************************************** + * @file usbd_msc_data.c + * @author MCD Application Team + * @version V2.4.2 + * @date 11-December-2015 + * @brief This file provides all the vital inquiry pages and sense data. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_msc_data.h" + + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup MSC_DATA + * @brief Mass storage info/data module + * @{ + */ + +/** @defgroup MSC_DATA_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup MSC_DATA_Private_Defines + * @{ + */ +/** + * @} + */ + + +/** @defgroup MSC_DATA_Private_Macros + * @{ + */ +/** + * @} + */ + + +/** @defgroup MSC_DATA_Private_Variables + * @{ + */ + + +/* USB Mass storage Page 0 Inquiry Data */ +const uint8_t MSC_Page00_Inquiry_Data[] = {//7 + 0x00, + 0x00, + 0x00, + (LENGTH_INQUIRY_PAGE00 - 4), + 0x00, + 0x80, + 0x83 +}; +/* USB Mass storage sense 6 Data */ +const uint8_t MSC_Mode_Sense6_data[] = { + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00 +}; +/* USB Mass storage sense 10 Data */ +const uint8_t MSC_Mode_Sense10_data[] = { + 0x00, + 0x06, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00 +}; +/** + * @} + */ + + +/** @defgroup MSC_DATA_Private_FunctionPrototypes + * @{ + */ +/** + * @} + */ + + +/** @defgroup MSC_DATA_Private_Functions + * @{ + */ + +/** + * @} + */ + + +/** + * @} + */ + + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/platform/mcu/stm32l475/Middlewares/USB_Device/Class/MSC/Src/usbd_msc_scsi.c b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/MSC/Src/usbd_msc_scsi.c new file mode 100644 index 0000000000..2318668cb1 --- /dev/null +++ b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/MSC/Src/usbd_msc_scsi.c @@ -0,0 +1,790 @@ +/** + ****************************************************************************** + * @file usbd_msc_scsi.c + * @author MCD Application Team + * @version V2.4.2 + * @date 11-December-2015 + * @brief This file provides all the USBD SCSI layer functions. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_msc_bot.h" +#include "usbd_msc_scsi.h" +#include "usbd_msc.h" +#include "usbd_msc_data.h" + + + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup MSC_SCSI + * @brief Mass storage SCSI layer module + * @{ + */ + +/** @defgroup MSC_SCSI_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup MSC_SCSI_Private_Defines + * @{ + */ + +/** + * @} + */ + + +/** @defgroup MSC_SCSI_Private_Macros + * @{ + */ +/** + * @} + */ + + +/** @defgroup MSC_SCSI_Private_Variables + * @{ + */ + +/** + * @} + */ + + +/** @defgroup MSC_SCSI_Private_FunctionPrototypes + * @{ + */ +static int8_t SCSI_TestUnitReady(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); +static int8_t SCSI_Inquiry(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); +static int8_t SCSI_ReadFormatCapacity(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); +static int8_t SCSI_ReadCapacity10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); +static int8_t SCSI_RequestSense (USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); +static int8_t SCSI_StartStopUnit(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); +static int8_t SCSI_ModeSense6 (USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); +static int8_t SCSI_ModeSense10 (USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); +static int8_t SCSI_Write10(USBD_HandleTypeDef *pdev, uint8_t lun , uint8_t *params); +static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun , uint8_t *params); +static int8_t SCSI_Verify10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params); +static int8_t SCSI_CheckAddressRange (USBD_HandleTypeDef *pdev, + uint8_t lun , + uint32_t blk_offset , + uint16_t blk_nbr); +static int8_t SCSI_ProcessRead (USBD_HandleTypeDef *pdev, + uint8_t lun); + +static int8_t SCSI_ProcessWrite (USBD_HandleTypeDef *pdev, + uint8_t lun); +/** + * @} + */ + + +/** @defgroup MSC_SCSI_Private_Functions + * @{ + */ + + +/** +* @brief SCSI_ProcessCmd +* Process SCSI commands +* @param pdev: device instance +* @param lun: Logical unit number +* @param params: Command parameters +* @retval status +*/ +int8_t SCSI_ProcessCmd(USBD_HandleTypeDef *pdev, + uint8_t lun, + uint8_t *params) +{ + + switch (params[0]) + { + case SCSI_TEST_UNIT_READY: + return SCSI_TestUnitReady(pdev, lun, params); + + case SCSI_REQUEST_SENSE: + return SCSI_RequestSense (pdev, lun, params); + case SCSI_INQUIRY: + return SCSI_Inquiry(pdev, lun, params); + + case SCSI_START_STOP_UNIT: + return SCSI_StartStopUnit(pdev, lun, params); + + case SCSI_ALLOW_MEDIUM_REMOVAL: + return SCSI_StartStopUnit(pdev, lun, params); + + case SCSI_MODE_SENSE6: + return SCSI_ModeSense6 (pdev, lun, params); + + case SCSI_MODE_SENSE10: + return SCSI_ModeSense10 (pdev, lun, params); + + case SCSI_READ_FORMAT_CAPACITIES: + return SCSI_ReadFormatCapacity(pdev, lun, params); + + case SCSI_READ_CAPACITY10: + return SCSI_ReadCapacity10(pdev, lun, params); + + case SCSI_READ10: + return SCSI_Read10(pdev, lun, params); + + case SCSI_WRITE10: + return SCSI_Write10(pdev, lun, params); + + case SCSI_VERIFY10: + return SCSI_Verify10(pdev, lun, params); + + default: + SCSI_SenseCode(pdev, + lun, + ILLEGAL_REQUEST, + INVALID_CDB); + return -1; + } +} + + +/** +* @brief SCSI_TestUnitReady +* Process SCSI Test Unit Ready Command +* @param lun: Logical unit number +* @param params: Command parameters +* @retval status +*/ +static int8_t SCSI_TestUnitReady(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) +{ + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef*)pdev->pClassData; + + /* case 9 : Hi > D0 */ + if (hmsc->cbw.dDataLength != 0) + { + SCSI_SenseCode(pdev, + hmsc->cbw.bLUN, + ILLEGAL_REQUEST, + INVALID_CDB); + return -1; + } + + if(((USBD_StorageTypeDef *)pdev->pUserData)->IsReady(lun) !=0 ) + { + SCSI_SenseCode(pdev, + lun, + NOT_READY, + MEDIUM_NOT_PRESENT); + + hmsc->bot_state = USBD_BOT_NO_DATA; + return -1; + } + hmsc->bot_data_length = 0; + return 0; +} + +/** +* @brief SCSI_Inquiry +* Process Inquiry command +* @param lun: Logical unit number +* @param params: Command parameters +* @retval status +*/ +static int8_t SCSI_Inquiry(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) +{ + uint8_t* pPage; + uint16_t len; + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef*)pdev->pClassData; + + if (params[1] & 0x01)/*Evpd is set*/ + { + pPage = (uint8_t *)MSC_Page00_Inquiry_Data; + len = LENGTH_INQUIRY_PAGE00; + } + else + { + + pPage = (uint8_t *)&((USBD_StorageTypeDef *)pdev->pUserData)->pInquiry[lun * STANDARD_INQUIRY_DATA_LEN]; + len = pPage[4] + 5; + + if (params[4] <= len) + { + len = params[4]; + } + } + hmsc->bot_data_length = len; + + while (len) + { + len--; + hmsc->bot_data[len] = pPage[len]; + } + return 0; +} + +/** +* @brief SCSI_ReadCapacity10 +* Process Read Capacity 10 command +* @param lun: Logical unit number +* @param params: Command parameters +* @retval status +*/ +static int8_t SCSI_ReadCapacity10(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) +{ + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef*)pdev->pClassData; + + if(((USBD_StorageTypeDef *)pdev->pUserData)->GetCapacity(lun, &hmsc->scsi_blk_nbr, &hmsc->scsi_blk_size) != 0) + { + SCSI_SenseCode(pdev, + lun, + NOT_READY, + MEDIUM_NOT_PRESENT); + return -1; + } + else + { + + hmsc->bot_data[0] = (uint8_t)((hmsc->scsi_blk_nbr - 1) >> 24); + hmsc->bot_data[1] = (uint8_t)((hmsc->scsi_blk_nbr - 1) >> 16); + hmsc->bot_data[2] = (uint8_t)((hmsc->scsi_blk_nbr - 1) >> 8); + hmsc->bot_data[3] = (uint8_t)(hmsc->scsi_blk_nbr - 1); + + hmsc->bot_data[4] = (uint8_t)(hmsc->scsi_blk_size >> 24); + hmsc->bot_data[5] = (uint8_t)(hmsc->scsi_blk_size >> 16); + hmsc->bot_data[6] = (uint8_t)(hmsc->scsi_blk_size >> 8); + hmsc->bot_data[7] = (uint8_t)(hmsc->scsi_blk_size); + + hmsc->bot_data_length = 8; + return 0; + } +} +/** +* @brief SCSI_ReadFormatCapacity +* Process Read Format Capacity command +* @param lun: Logical unit number +* @param params: Command parameters +* @retval status +*/ +static int8_t SCSI_ReadFormatCapacity(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) +{ + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef*)pdev->pClassData; + + uint16_t blk_size; + uint32_t blk_nbr; + uint16_t i; + + for(i=0 ; i < 12 ; i++) + { + hmsc->bot_data[i] = 0; + } + + if(((USBD_StorageTypeDef *)pdev->pUserData)->GetCapacity(lun, &blk_nbr, &blk_size) != 0) + { + SCSI_SenseCode(pdev, + lun, + NOT_READY, + MEDIUM_NOT_PRESENT); + return -1; + } + else + { + hmsc->bot_data[3] = 0x08; + hmsc->bot_data[4] = (uint8_t)((blk_nbr - 1) >> 24); + hmsc->bot_data[5] = (uint8_t)((blk_nbr - 1) >> 16); + hmsc->bot_data[6] = (uint8_t)((blk_nbr - 1) >> 8); + hmsc->bot_data[7] = (uint8_t)(blk_nbr - 1); + + hmsc->bot_data[8] = 0x02; + hmsc->bot_data[9] = (uint8_t)(blk_size >> 16); + hmsc->bot_data[10] = (uint8_t)(blk_size >> 8); + hmsc->bot_data[11] = (uint8_t)(blk_size); + + hmsc->bot_data_length = 12; + return 0; + } +} +/** +* @brief SCSI_ModeSense6 +* Process Mode Sense6 command +* @param lun: Logical unit number +* @param params: Command parameters +* @retval status +*/ +static int8_t SCSI_ModeSense6 (USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) +{ + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef*)pdev->pClassData; + uint16_t len = 8 ; + hmsc->bot_data_length = len; + + while (len) + { + len--; + hmsc->bot_data[len] = MSC_Mode_Sense6_data[len]; + } + return 0; +} + +/** +* @brief SCSI_ModeSense10 +* Process Mode Sense10 command +* @param lun: Logical unit number +* @param params: Command parameters +* @retval status +*/ +static int8_t SCSI_ModeSense10 (USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) +{ + uint16_t len = 8; + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef*)pdev->pClassData; + + hmsc->bot_data_length = len; + + while (len) + { + len--; + hmsc->bot_data[len] = MSC_Mode_Sense10_data[len]; + } + return 0; +} + +/** +* @brief SCSI_RequestSense +* Process Request Sense command +* @param lun: Logical unit number +* @param params: Command parameters +* @retval status +*/ + +static int8_t SCSI_RequestSense (USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) +{ + uint8_t i; + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef*)pdev->pClassData; + + for(i=0 ; i < REQUEST_SENSE_DATA_LEN ; i++) + { + hmsc->bot_data[i] = 0; + } + + hmsc->bot_data[0] = 0x70; + hmsc->bot_data[7] = REQUEST_SENSE_DATA_LEN - 6; + + if((hmsc->scsi_sense_head != hmsc->scsi_sense_tail)) { + + hmsc->bot_data[2] = hmsc->scsi_sense[hmsc->scsi_sense_head].Skey; + hmsc->bot_data[12] = hmsc->scsi_sense[hmsc->scsi_sense_head].w.b.ASCQ; + hmsc->bot_data[13] = hmsc->scsi_sense[hmsc->scsi_sense_head].w.b.ASC; + hmsc->scsi_sense_head++; + + if (hmsc->scsi_sense_head == SENSE_LIST_DEEPTH) + { + hmsc->scsi_sense_head = 0; + } + } + hmsc->bot_data_length = REQUEST_SENSE_DATA_LEN; + + if (params[4] <= REQUEST_SENSE_DATA_LEN) + { + hmsc->bot_data_length = params[4]; + } + return 0; +} + +/** +* @brief SCSI_SenseCode +* Load the last error code in the error list +* @param lun: Logical unit number +* @param sKey: Sense Key +* @param ASC: Additional Sense Key +* @retval none + +*/ +void SCSI_SenseCode(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t sKey, uint8_t ASC) +{ + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef*)pdev->pClassData; + + hmsc->scsi_sense[hmsc->scsi_sense_tail].Skey = sKey; + hmsc->scsi_sense[hmsc->scsi_sense_tail].w.ASC = ASC << 8; + hmsc->scsi_sense_tail++; + if (hmsc->scsi_sense_tail == SENSE_LIST_DEEPTH) + { + hmsc->scsi_sense_tail = 0; + } +} +/** +* @brief SCSI_StartStopUnit +* Process Start Stop Unit command +* @param lun: Logical unit number +* @param params: Command parameters +* @retval status +*/ +static int8_t SCSI_StartStopUnit(USBD_HandleTypeDef *pdev, uint8_t lun, uint8_t *params) +{ + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef*) pdev->pClassData; + hmsc->bot_data_length = 0; + return 0; +} + +/** +* @brief SCSI_Read10 +* Process Read10 command +* @param lun: Logical unit number +* @param params: Command parameters +* @retval status +*/ +static int8_t SCSI_Read10(USBD_HandleTypeDef *pdev, uint8_t lun , uint8_t *params) +{ + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef*) pdev->pClassData; + + if(hmsc->bot_state == USBD_BOT_IDLE) /* Idle */ + { + + /* case 10 : Ho <> Di */ + + if ((hmsc->cbw.bmFlags & 0x80) != 0x80) + { + SCSI_SenseCode(pdev, + hmsc->cbw.bLUN, + ILLEGAL_REQUEST, + INVALID_CDB); + return -1; + } + + if(((USBD_StorageTypeDef *)pdev->pUserData)->IsReady(lun) !=0 ) + { + SCSI_SenseCode(pdev, + lun, + NOT_READY, + MEDIUM_NOT_PRESENT); + return -1; + } + + hmsc->scsi_blk_addr = (params[2] << 24) | \ + (params[3] << 16) | \ + (params[4] << 8) | \ + params[5]; + + hmsc->scsi_blk_len = (params[7] << 8) | \ + params[8]; + + + + if( SCSI_CheckAddressRange(pdev, lun, hmsc->scsi_blk_addr, hmsc->scsi_blk_len) < 0) + { + return -1; /* error */ + } + + hmsc->bot_state = USBD_BOT_DATA_IN; + hmsc->scsi_blk_addr *= hmsc->scsi_blk_size; + hmsc->scsi_blk_len *= hmsc->scsi_blk_size; + + /* cases 4,5 : Hi <> Dn */ + if (hmsc->cbw.dDataLength != hmsc->scsi_blk_len) + { + SCSI_SenseCode(pdev, + hmsc->cbw.bLUN, + ILLEGAL_REQUEST, + INVALID_CDB); + return -1; + } + } + hmsc->bot_data_length = MSC_MEDIA_PACKET; + + return SCSI_ProcessRead(pdev, lun); +} + +/** +* @brief SCSI_Write10 +* Process Write10 command +* @param lun: Logical unit number +* @param params: Command parameters +* @retval status +*/ + +static int8_t SCSI_Write10 (USBD_HandleTypeDef *pdev, uint8_t lun , uint8_t *params) +{ + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef*) pdev->pClassData; + + if (hmsc->bot_state == USBD_BOT_IDLE) /* Idle */ + { + + /* case 8 : Hi <> Do */ + + if ((hmsc->cbw.bmFlags & 0x80) == 0x80) + { + SCSI_SenseCode(pdev, + hmsc->cbw.bLUN, + ILLEGAL_REQUEST, + INVALID_CDB); + return -1; + } + + /* Check whether Media is ready */ + if(((USBD_StorageTypeDef *)pdev->pUserData)->IsReady(lun) !=0 ) + { + SCSI_SenseCode(pdev, + lun, + NOT_READY, + MEDIUM_NOT_PRESENT); + return -1; + } + + /* Check If media is write-protected */ + if(((USBD_StorageTypeDef *)pdev->pUserData)->IsWriteProtected(lun) !=0 ) + { + SCSI_SenseCode(pdev, + lun, + NOT_READY, + WRITE_PROTECTED); + return -1; + } + + + hmsc->scsi_blk_addr = (params[2] << 24) | \ + (params[3] << 16) | \ + (params[4] << 8) | \ + params[5]; + hmsc->scsi_blk_len = (params[7] << 8) | \ + params[8]; + + /* check if LBA address is in the right range */ + if(SCSI_CheckAddressRange(pdev, + lun, + hmsc->scsi_blk_addr, + hmsc->scsi_blk_len) < 0) + { + return -1; /* error */ + } + + hmsc->scsi_blk_addr *= hmsc->scsi_blk_size; + hmsc->scsi_blk_len *= hmsc->scsi_blk_size; + + /* cases 3,11,13 : Hn,Ho <> D0 */ + if (hmsc->cbw.dDataLength != hmsc->scsi_blk_len) + { + SCSI_SenseCode(pdev, + hmsc->cbw.bLUN, + ILLEGAL_REQUEST, + INVALID_CDB); + return -1; + } + + /* Prepare EP to receive first data packet */ + hmsc->bot_state = USBD_BOT_DATA_OUT; + USBD_LL_PrepareReceive (pdev, + MSC_EPOUT_ADDR, + hmsc->bot_data, + MIN (hmsc->scsi_blk_len, MSC_MEDIA_PACKET)); + } + else /* Write Process ongoing */ + { + return SCSI_ProcessWrite(pdev, lun); + } + return 0; +} + + +/** +* @brief SCSI_Verify10 +* Process Verify10 command +* @param lun: Logical unit number +* @param params: Command parameters +* @retval status +*/ + +static int8_t SCSI_Verify10(USBD_HandleTypeDef *pdev, uint8_t lun , uint8_t *params) +{ + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef*) pdev->pClassData; + + if ((params[1]& 0x02) == 0x02) + { + SCSI_SenseCode (pdev, + lun, + ILLEGAL_REQUEST, + INVALID_FIELED_IN_COMMAND); + return -1; /* Error, Verify Mode Not supported*/ + } + + if(SCSI_CheckAddressRange(pdev, + lun, + hmsc->scsi_blk_addr, + hmsc->scsi_blk_len) < 0) + { + return -1; /* error */ + } + hmsc->bot_data_length = 0; + return 0; +} + +/** +* @brief SCSI_CheckAddressRange +* Check address range +* @param lun: Logical unit number +* @param blk_offset: first block address +* @param blk_nbr: number of block to be processed +* @retval status +*/ +static int8_t SCSI_CheckAddressRange (USBD_HandleTypeDef *pdev, uint8_t lun , uint32_t blk_offset , uint16_t blk_nbr) +{ + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef*) pdev->pClassData; + + if ((blk_offset + blk_nbr) > hmsc->scsi_blk_nbr ) + { + SCSI_SenseCode(pdev, + lun, + ILLEGAL_REQUEST, + ADDRESS_OUT_OF_RANGE); + return -1; + } + return 0; +} + +/** +* @brief SCSI_ProcessRead +* Handle Read Process +* @param lun: Logical unit number +* @retval status +*/ +static int8_t SCSI_ProcessRead (USBD_HandleTypeDef *pdev, uint8_t lun) +{ + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef*)pdev->pClassData; + uint32_t len; + + len = MIN(hmsc->scsi_blk_len , MSC_MEDIA_PACKET); + + if( ((USBD_StorageTypeDef *)pdev->pUserData)->Read(lun , + hmsc->bot_data, + hmsc->scsi_blk_addr / hmsc->scsi_blk_size, + len / hmsc->scsi_blk_size) < 0) + { + + SCSI_SenseCode(pdev, + lun, + HARDWARE_ERROR, + UNRECOVERED_READ_ERROR); + return -1; + } + + + USBD_LL_Transmit (pdev, + MSC_EPIN_ADDR, + hmsc->bot_data, + len); + + + hmsc->scsi_blk_addr += len; + hmsc->scsi_blk_len -= len; + + /* case 6 : Hi = Di */ + hmsc->csw.dDataResidue -= len; + + if (hmsc->scsi_blk_len == 0) + { + hmsc->bot_state = USBD_BOT_LAST_DATA_IN; + } + return 0; +} + +/** +* @brief SCSI_ProcessWrite +* Handle Write Process +* @param lun: Logical unit number +* @retval status +*/ + +static int8_t SCSI_ProcessWrite (USBD_HandleTypeDef *pdev, uint8_t lun) +{ + uint32_t len; + USBD_MSC_BOT_HandleTypeDef *hmsc = (USBD_MSC_BOT_HandleTypeDef*) pdev->pClassData; + + len = MIN(hmsc->scsi_blk_len , MSC_MEDIA_PACKET); + + if(((USBD_StorageTypeDef *)pdev->pUserData)->Write(lun , + hmsc->bot_data, + hmsc->scsi_blk_addr / hmsc->scsi_blk_size, + len / hmsc->scsi_blk_size) < 0) + { + SCSI_SenseCode(pdev, + lun, + HARDWARE_ERROR, + WRITE_FAULT); + return -1; + } + + + hmsc->scsi_blk_addr += len; + hmsc->scsi_blk_len -= len; + + /* case 12 : Ho = Do */ + hmsc->csw.dDataResidue -= len; + + if (hmsc->scsi_blk_len == 0) + { + MSC_BOT_SendCSW (pdev, USBD_CSW_CMD_PASSED); + } + else + { + /* Prepare EP to Receive next packet */ + USBD_LL_PrepareReceive (pdev, + MSC_EPOUT_ADDR, + hmsc->bot_data, + MIN (hmsc->scsi_blk_len, MSC_MEDIA_PACKET)); + } + + return 0; +} +/** + * @} + */ + + +/** + * @} + */ + + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/platform/mcu/stm32l475/Middlewares/USB_Device/Class/MSC/Src/usbd_msc_storage_template.c b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/MSC/Src/usbd_msc_storage_template.c new file mode 100644 index 0000000000..f6ab790ef5 --- /dev/null +++ b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/MSC/Src/usbd_msc_storage_template.c @@ -0,0 +1,208 @@ +/** + ****************************************************************************** + * @file usbd_msc_storage_template.c + * @author MCD Application Team + * @version V2.4.2 + * @date 11-December-2015 + * @brief Memory management layer + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_msc_storage_template.h" + + +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Extern function prototypes ------------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ + +#define STORAGE_LUN_NBR 1 +#define STORAGE_BLK_NBR 0x10000 +#define STORAGE_BLK_SIZ 0x200 + +int8_t STORAGE_Init (uint8_t lun); + +int8_t STORAGE_GetCapacity (uint8_t lun, + uint32_t *block_num, + uint16_t *block_size); + +int8_t STORAGE_IsReady (uint8_t lun); + +int8_t STORAGE_IsWriteProtected (uint8_t lun); + +int8_t STORAGE_Read (uint8_t lun, + uint8_t *buf, + uint32_t blk_addr, + uint16_t blk_len); + +int8_t STORAGE_Write (uint8_t lun, + uint8_t *buf, + uint32_t blk_addr, + uint16_t blk_len); + +int8_t STORAGE_GetMaxLun (void); + +/* USB Mass storage Standard Inquiry Data */ +int8_t STORAGE_Inquirydata[] = {//36 + + /* LUN 0 */ + 0x00, + 0x80, + 0x02, + 0x02, + (STANDARD_INQUIRY_DATA_LEN - 5), + 0x00, + 0x00, + 0x00, + 'S', 'T', 'M', ' ', ' ', ' ', ' ', ' ', /* Manufacturer : 8 bytes */ + 'P', 'r', 'o', 'd', 'u', 'c', 't', ' ', /* Product : 16 Bytes */ + ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', + '0', '.', '0' ,'1', /* Version : 4 Bytes */ +}; + +USBD_StorageTypeDef USBD_MSC_Template_fops = +{ + STORAGE_Init, + STORAGE_GetCapacity, + STORAGE_IsReady, + STORAGE_IsWriteProtected, + STORAGE_Read, + STORAGE_Write, + STORAGE_GetMaxLun, + STORAGE_Inquirydata, + +}; +/******************************************************************************* +* Function Name : Read_Memory +* Description : Handle the Read operation from the microSD card. +* Input : None. +* Output : None. +* Return : None. +*******************************************************************************/ +int8_t STORAGE_Init (uint8_t lun) +{ + return (0); +} + +/******************************************************************************* +* Function Name : Read_Memory +* Description : Handle the Read operation from the STORAGE card. +* Input : None. +* Output : None. +* Return : None. +*******************************************************************************/ +int8_t STORAGE_GetCapacity (uint8_t lun, uint32_t *block_num, uint16_t *block_size) +{ + *block_num = STORAGE_BLK_NBR; + *block_size = STORAGE_BLK_SIZ; + return (0); +} + +/******************************************************************************* +* Function Name : Read_Memory +* Description : Handle the Read operation from the STORAGE card. +* Input : None. +* Output : None. +* Return : None. +*******************************************************************************/ +int8_t STORAGE_IsReady (uint8_t lun) +{ + return (0); +} + +/******************************************************************************* +* Function Name : Read_Memory +* Description : Handle the Read operation from the STORAGE card. +* Input : None. +* Output : None. +* Return : None. +*******************************************************************************/ +int8_t STORAGE_IsWriteProtected (uint8_t lun) +{ + return 0; +} + +/******************************************************************************* +* Function Name : Read_Memory +* Description : Handle the Read operation from the STORAGE card. +* Input : None. +* Output : None. +* Return : None. +*******************************************************************************/ +int8_t STORAGE_Read (uint8_t lun, + uint8_t *buf, + uint32_t blk_addr, + uint16_t blk_len) +{ + return 0; +} +/******************************************************************************* +* Function Name : Write_Memory +* Description : Handle the Write operation to the STORAGE card. +* Input : None. +* Output : None. +* Return : None. +*******************************************************************************/ +int8_t STORAGE_Write (uint8_t lun, + uint8_t *buf, + uint32_t blk_addr, + uint16_t blk_len) +{ + return (0); +} +/******************************************************************************* +* Function Name : Write_Memory +* Description : Handle the Write operation to the STORAGE card. +* Input : None. +* Output : None. +* Return : None. +*******************************************************************************/ +int8_t STORAGE_GetMaxLun (void) +{ + return (STORAGE_LUN_NBR - 1); +} + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/platform/mcu/stm32l475/Middlewares/USB_Device/Class/Template/Inc/usbd_template.h b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/Template/Inc/usbd_template.h new file mode 100644 index 0000000000..298673e4ae --- /dev/null +++ b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/Template/Inc/usbd_template.h @@ -0,0 +1,129 @@ +/** + ****************************************************************************** + * @file usbd_template_core.h + * @author MCD Application Team + * @version V2.4.2 + * @date 11-December-2015 + * @brief Header file for the usbd_template_core.c file. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USB_TEMPLATE_CORE_H +#define __USB_TEMPLATE_CORE_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_ioreq.h" + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USBD_TEMPLATE + * @brief This file is the header file for usbd_template_core.c + * @{ + */ + + +/** @defgroup USBD_TEMPLATE_Exported_Defines + * @{ + */ +#define TEMPLATE_EPIN_ADDR 0x81 +#define TEMPLATE_EPIN_SIZE 0x10 + +#define USB_TEMPLATE_CONFIG_DESC_SIZ 64 + +/** + * @} + */ + + +/** @defgroup USBD_CORE_Exported_TypesDefinitions + * @{ + */ + +/** + * @} + */ + + + +/** @defgroup USBD_CORE_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_CORE_Exported_Variables + * @{ + */ + +extern USBD_ClassTypeDef USBD_TEMPLATE_ClassDriver; +/** + * @} + */ + +/** @defgroup USB_CORE_Exported_Functions + * @{ + */ +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_TEMPLATE_CORE_H */ +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/platform/mcu/stm32l475/Middlewares/USB_Device/Class/Template/Src/usbd_template.c b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/Template/Src/usbd_template.c new file mode 100644 index 0000000000..acfacbb81a --- /dev/null +++ b/platform/mcu/stm32l475/Middlewares/USB_Device/Class/Template/Src/usbd_template.c @@ -0,0 +1,418 @@ +/** + ****************************************************************************** + * @file usbd_template.c + * @author MCD Application Team + * @version V2.4.2 + * @date 11-December-2015 + * @brief This file provides the HID core functions. + * + * @verbatim + * + * =================================================================== + * TEMPLATE Class Description + * =================================================================== + * + * + * + * + * + * + * @note In HS mode and when the DMA is used, all variables and data structures + * dealing with the DMA during the transaction process should be 32-bit aligned. + * + * + * @endverbatim + * + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_template.h" +#include "usbd_desc.h" +#include "usbd_ctlreq.h" + + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup USBD_TEMPLATE + * @brief usbd core module + * @{ + */ + +/** @defgroup USBD_TEMPLATE_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_TEMPLATE_Private_Defines + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_TEMPLATE_Private_Macros + * @{ + */ + +/** + * @} + */ + + + + +/** @defgroup USBD_TEMPLATE_Private_FunctionPrototypes + * @{ + */ + + +static uint8_t USBD_TEMPLATE_Init (USBD_HandleTypeDef *pdev, + uint8_t cfgidx); + +static uint8_t USBD_TEMPLATE_DeInit (USBD_HandleTypeDef *pdev, + uint8_t cfgidx); + +static uint8_t USBD_TEMPLATE_Setup (USBD_HandleTypeDef *pdev, + USBD_SetupReqTypedef *req); + +static uint8_t *USBD_TEMPLATE_GetCfgDesc (uint16_t *length); + +static uint8_t *USBD_TEMPLATE_GetDeviceQualifierDesc (uint16_t *length); + +static uint8_t USBD_TEMPLATE_DataIn (USBD_HandleTypeDef *pdev, uint8_t epnum); + +static uint8_t USBD_TEMPLATE_DataOut (USBD_HandleTypeDef *pdev, uint8_t epnum); + +static uint8_t USBD_TEMPLATE_EP0_RxReady (USBD_HandleTypeDef *pdev); + +static uint8_t USBD_TEMPLATE_EP0_TxReady (USBD_HandleTypeDef *pdev); + +static uint8_t USBD_TEMPLATE_SOF (USBD_HandleTypeDef *pdev); + +static uint8_t USBD_TEMPLATE_IsoINIncomplete (USBD_HandleTypeDef *pdev, uint8_t epnum); + +static uint8_t USBD_TEMPLATE_IsoOutIncomplete (USBD_HandleTypeDef *pdev, uint8_t epnum); + +/** + * @} + */ + +/** @defgroup USBD_TEMPLATE_Private_Variables + * @{ + */ + +USBD_ClassTypeDef USBD_TEMPLATE_ClassDriver = +{ + USBD_TEMPLATE_Init, + USBD_TEMPLATE_DeInit, + USBD_TEMPLATE_Setup, + USBD_TEMPLATE_EP0_TxReady, + USBD_TEMPLATE_EP0_RxReady, + USBD_TEMPLATE_DataIn, + USBD_TEMPLATE_DataOut, + USBD_TEMPLATE_SOF, + USBD_TEMPLATE_IsoINIncomplete, + USBD_TEMPLATE_IsoOutIncomplete, + USBD_TEMPLATE_GetCfgDesc, + USBD_TEMPLATE_GetCfgDesc, + USBD_TEMPLATE_GetCfgDesc, + USBD_TEMPLATE_GetDeviceQualifierDesc, +}; + +#if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 +#endif +/* USB TEMPLATE device Configuration Descriptor */ +static uint8_t USBD_TEMPLATE_CfgDesc[USB_TEMPLATE_CONFIG_DESC_SIZ] = +{ + 0x09, /* bLength: Configuation Descriptor size */ + USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION, /* bDescriptorType: Configuration */ + USB_TEMPLATE_CONFIG_DESC_SIZ, + /* wTotalLength: Bytes returned */ + 0x00, + 0x01, /*bNumInterfaces: 1 interface*/ + 0x01, /*bConfigurationValue: Configuration value*/ + 0x02, /*iConfiguration: Index of string descriptor describing the configuration*/ + 0xC0, /*bmAttributes: bus powered and Supports Remote Wakeup */ + 0x32, /*MaxPower 100 mA: this current is used for detecting Vbus*/ + /* 09 */ + + /********** Descriptor of TEMPLATE interface 0 Alternate setting 0 **************/ + +}; + +#if defined ( __ICCARM__ ) /*!< IAR Compiler */ + #pragma data_alignment=4 +#endif +/* USB Standard Device Descriptor */ +static uint8_t USBD_TEMPLATE_DeviceQualifierDesc[USB_LEN_DEV_QUALIFIER_DESC] = +{ + USB_LEN_DEV_QUALIFIER_DESC, + USB_DESC_TYPE_DEVICE_QUALIFIER, + 0x00, + 0x02, + 0x00, + 0x00, + 0x00, + 0x40, + 0x01, + 0x00, +}; + +/** + * @} + */ + +/** @defgroup USBD_TEMPLATE_Private_Functions + * @{ + */ + +/** + * @brief USBD_TEMPLATE_Init + * Initialize the TEMPLATE interface + * @param pdev: device instance + * @param cfgidx: Configuration index + * @retval status + */ +static uint8_t USBD_TEMPLATE_Init (USBD_HandleTypeDef *pdev, + uint8_t cfgidx) +{ + uint8_t ret = 0; + + + return ret; +} + +/** + * @brief USBD_TEMPLATE_Init + * DeInitialize the TEMPLATE layer + * @param pdev: device instance + * @param cfgidx: Configuration index + * @retval status + */ +static uint8_t USBD_TEMPLATE_DeInit (USBD_HandleTypeDef *pdev, + uint8_t cfgidx) +{ + + return USBD_OK; +} + +/** + * @brief USBD_TEMPLATE_Setup + * Handle the TEMPLATE specific requests + * @param pdev: instance + * @param req: usb requests + * @retval status + */ +static uint8_t USBD_TEMPLATE_Setup (USBD_HandleTypeDef *pdev, + USBD_SetupReqTypedef *req) +{ + + switch (req->bmRequest & USB_REQ_TYPE_MASK) + { + case USB_REQ_TYPE_CLASS : + switch (req->bRequest) + { + + default: + USBD_CtlError (pdev, req); + return USBD_FAIL; + } + break; + + case USB_REQ_TYPE_STANDARD: + switch (req->bRequest) + { + + default: + USBD_CtlError (pdev, req); + return USBD_FAIL; + } + } + return USBD_OK; +} + + +/** + * @brief USBD_TEMPLATE_GetCfgDesc + * return configuration descriptor + * @param length : pointer data length + * @retval pointer to descriptor buffer + */ +static uint8_t *USBD_TEMPLATE_GetCfgDesc (uint16_t *length) +{ + *length = sizeof (USBD_TEMPLATE_CfgDesc); + return USBD_TEMPLATE_CfgDesc; +} + +/** +* @brief DeviceQualifierDescriptor +* return Device Qualifier descriptor +* @param length : pointer data length +* @retval pointer to descriptor buffer +*/ +uint8_t *USBD_TEMPLATE_DeviceQualifierDescriptor (uint16_t *length) +{ + *length = sizeof (USBD_TEMPLATE_DeviceQualifierDesc); + return USBD_TEMPLATE_DeviceQualifierDesc; +} + + +/** + * @brief USBD_TEMPLATE_DataIn + * handle data IN Stage + * @param pdev: device instance + * @param epnum: endpoint index + * @retval status + */ +static uint8_t USBD_TEMPLATE_DataIn (USBD_HandleTypeDef *pdev, + uint8_t epnum) +{ + + return USBD_OK; +} + +/** + * @brief USBD_TEMPLATE_EP0_RxReady + * handle EP0 Rx Ready event + * @param pdev: device instance + * @retval status + */ +static uint8_t USBD_TEMPLATE_EP0_RxReady (USBD_HandleTypeDef *pdev) +{ + + return USBD_OK; +} +/** + * @brief USBD_TEMPLATE_EP0_TxReady + * handle EP0 TRx Ready event + * @param pdev: device instance + * @retval status + */ +static uint8_t USBD_TEMPLATE_EP0_TxReady (USBD_HandleTypeDef *pdev) +{ + + return USBD_OK; +} +/** + * @brief USBD_TEMPLATE_SOF + * handle SOF event + * @param pdev: device instance + * @retval status + */ +static uint8_t USBD_TEMPLATE_SOF (USBD_HandleTypeDef *pdev) +{ + + return USBD_OK; +} +/** + * @brief USBD_TEMPLATE_IsoINIncomplete + * handle data ISO IN Incomplete event + * @param pdev: device instance + * @param epnum: endpoint index + * @retval status + */ +static uint8_t USBD_TEMPLATE_IsoINIncomplete (USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + + return USBD_OK; +} +/** + * @brief USBD_TEMPLATE_IsoOutIncomplete + * handle data ISO OUT Incomplete event + * @param pdev: device instance + * @param epnum: endpoint index + * @retval status + */ +static uint8_t USBD_TEMPLATE_IsoOutIncomplete (USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + + return USBD_OK; +} +/** + * @brief USBD_TEMPLATE_DataOut + * handle data OUT Stage + * @param pdev: device instance + * @param epnum: endpoint index + * @retval status + */ +static uint8_t USBD_TEMPLATE_DataOut (USBD_HandleTypeDef *pdev, + uint8_t epnum) +{ + + return USBD_OK; +} + +/** +* @brief DeviceQualifierDescriptor +* return Device Qualifier descriptor +* @param length : pointer data length +* @retval pointer to descriptor buffer +*/ +uint8_t *USBD_TEMPLATE_GetDeviceQualifierDesc (uint16_t *length) +{ + *length = sizeof (USBD_TEMPLATE_DeviceQualifierDesc); + return USBD_TEMPLATE_DeviceQualifierDesc; +} + +/** + * @} + */ + + +/** + * @} + */ + + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/platform/mcu/stm32l475/Middlewares/USB_Device/Core/Inc/usbd_conf_template.h b/platform/mcu/stm32l475/Middlewares/USB_Device/Core/Inc/usbd_conf_template.h new file mode 100644 index 0000000000..40133bbb31 --- /dev/null +++ b/platform/mcu/stm32l475/Middlewares/USB_Device/Core/Inc/usbd_conf_template.h @@ -0,0 +1,189 @@ +/** + ****************************************************************************** + * @file usbd_conf_template.h + * @author MCD Application Team + * @version V2.4.2 + * @date 11-December-2015 + * @brief Header file for the usbd_conf_template.c file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBD_CONF_TEMPLATE_H +#define __USBD_CONF_TEMPLATE_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32fxxx.h" /* replace 'stm32xxx' with your HAL driver header filename, ex: stm32f4xx.h */ +#include +#include +#include + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USBD_CONF + * @brief USB device low level driver configuration file + * @{ + */ + +/** @defgroup USBD_CONF_Exported_Defines + * @{ + */ + +#define USBD_MAX_NUM_INTERFACES 1 +#define USBD_MAX_NUM_CONFIGURATION 1 +#define USBD_MAX_STR_DESC_SIZ 0x100 +#define USBD_SUPPORT_USER_STRING 0 +#define USBD_SELF_POWERED 1 +#define USBD_DEBUG_LEVEL 2 + +/* MSC Class Config */ +#define MSC_MEDIA_PACKET 8192 + +/* CDC Class Config */ +#define USBD_CDC_INTERVAL 2000 + + /* DFU Class Config */ +#define USBD_DFU_MAX_ITF_NUM 1 +#define USBD_DFU_XFERS_IZE 1024 + + /* AUDIO Class Config */ +#define USBD_AUDIO_FREQ 22100 + +/** @defgroup USBD_Exported_Macros + * @{ + */ + + /* Memory management macros */ +#define USBD_malloc malloc +#define USBD_free free +#define USBD_memset memset +#define USBD_memcpy memcpy + + /* DEBUG macros */ + + +#if (USBD_DEBUG_LEVEL > 0) +#define USBD_UsrLog(...) printf(__VA_ARGS__);\ + printf("\n"); +#else +#define USBD_UsrLog(...) +#endif + + +#if (USBD_DEBUG_LEVEL > 1) + +#define USBD_ErrLog(...) printf("ERROR: ") ;\ + printf(__VA_ARGS__);\ + printf("\n"); +#else +#define USBD_ErrLog(...) +#endif + + +#if (USBD_DEBUG_LEVEL > 2) +#define USBD_DbgLog(...) printf("DEBUG : ") ;\ + printf(__VA_ARGS__);\ + printf("\n"); +#else +#define USBD_DbgLog(...) +#endif + +/** + * @} + */ + + + +/** + * @} + */ + + +/** @defgroup USBD_CONF_Exported_Types + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_CONF_Exported_Macros + * @{ + */ +/** + * @} + */ + +/** @defgroup USBD_CONF_Exported_Variables + * @{ + */ +/** + * @} + */ + +/** @defgroup USBD_CONF_Exported_FunctionsPrototype + * @{ + */ +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USBD_CONF_TEMPLATE_H */ + + +/** + * @} + */ + +/** + * @} + */ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/platform/mcu/stm32l475/Middlewares/USB_Device/Core/Inc/usbd_core.h b/platform/mcu/stm32l475/Middlewares/USB_Device/Core/Inc/usbd_core.h new file mode 100644 index 0000000000..521de6a091 --- /dev/null +++ b/platform/mcu/stm32l475/Middlewares/USB_Device/Core/Inc/usbd_core.h @@ -0,0 +1,187 @@ +/** + ****************************************************************************** + * @file usbd_core.h + * @author MCD Application Team + * @version V2.4.2 + * @date 11-December-2015 + * @brief Header file for usbd_core.c file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBD_CORE_H +#define __USBD_CORE_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_conf.h" +#include "usbd_def.h" +#include "usbd_ioreq.h" +#include "usbd_ctlreq.h" + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USBD_CORE + * @brief This file is the Header file for usbd_core.c file + * @{ + */ + + +/** @defgroup USBD_CORE_Exported_Defines + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_CORE_Exported_TypesDefinitions + * @{ + */ + + +/** + * @} + */ + + + +/** @defgroup USBD_CORE_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_CORE_Exported_Variables + * @{ + */ +#define USBD_SOF USBD_LL_SOF +/** + * @} + */ + +/** @defgroup USBD_CORE_Exported_FunctionsPrototype + * @{ + */ +USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev, USBD_DescriptorsTypeDef *pdesc, uint8_t id); +USBD_StatusTypeDef USBD_DeInit(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_Start (USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_Stop (USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_RegisterClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass); + +USBD_StatusTypeDef USBD_RunTestMode (USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_SetClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx); +USBD_StatusTypeDef USBD_ClrClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx); + +USBD_StatusTypeDef USBD_LL_SetupStage(USBD_HandleTypeDef *pdev, uint8_t *psetup); +USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev , uint8_t epnum, uint8_t *pdata); +USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev , uint8_t epnum, uint8_t *pdata); + +USBD_StatusTypeDef USBD_LL_Reset(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_LL_SetSpeed(USBD_HandleTypeDef *pdev, USBD_SpeedTypeDef speed); +USBD_StatusTypeDef USBD_LL_Suspend(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_LL_Resume(USBD_HandleTypeDef *pdev); + +USBD_StatusTypeDef USBD_LL_SOF(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_LL_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum); +USBD_StatusTypeDef USBD_LL_IsoOUTIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum); + +USBD_StatusTypeDef USBD_LL_DevConnected(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_LL_DevDisconnected(USBD_HandleTypeDef *pdev); + +/* USBD Low Level Driver */ +USBD_StatusTypeDef USBD_LL_Init (USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_LL_DeInit (USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_LL_Stop (USBD_HandleTypeDef *pdev); +USBD_StatusTypeDef USBD_LL_OpenEP (USBD_HandleTypeDef *pdev, + uint8_t ep_addr, + uint8_t ep_type, + uint16_t ep_mps); + +USBD_StatusTypeDef USBD_LL_CloseEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr); +USBD_StatusTypeDef USBD_LL_FlushEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr); +USBD_StatusTypeDef USBD_LL_StallEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr); +USBD_StatusTypeDef USBD_LL_ClearStallEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr); +uint8_t USBD_LL_IsStallEP (USBD_HandleTypeDef *pdev, uint8_t ep_addr); +USBD_StatusTypeDef USBD_LL_SetUSBAddress (USBD_HandleTypeDef *pdev, uint8_t dev_addr); +USBD_StatusTypeDef USBD_LL_Transmit (USBD_HandleTypeDef *pdev, + uint8_t ep_addr, + uint8_t *pbuf, + uint16_t size); + +USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev, + uint8_t ep_addr, + uint8_t *pbuf, + uint16_t size); + +uint32_t USBD_LL_GetRxDataSize (USBD_HandleTypeDef *pdev, uint8_t ep_addr); +void USBD_LL_Delay (uint32_t Delay); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USBD_CORE_H */ + +/** + * @} + */ + +/** +* @} +*/ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + + + diff --git a/platform/mcu/stm32l475/Middlewares/USB_Device/Core/Inc/usbd_ctlreq.h b/platform/mcu/stm32l475/Middlewares/USB_Device/Core/Inc/usbd_ctlreq.h new file mode 100644 index 0000000000..ad2fcfd70c --- /dev/null +++ b/platform/mcu/stm32l475/Middlewares/USB_Device/Core/Inc/usbd_ctlreq.h @@ -0,0 +1,133 @@ +/** + ****************************************************************************** + * @file usbd_req.h + * @author MCD Application Team + * @version V2.4.2 + * @date 11-December-2015 + * @brief Header file for the usbd_req.c file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USB_REQUEST_H +#define __USB_REQUEST_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_def.h" + + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USBD_REQ + * @brief header file for the usbd_req.c file + * @{ + */ + +/** @defgroup USBD_REQ_Exported_Defines + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_REQ_Exported_Types + * @{ + */ +/** + * @} + */ + + + +/** @defgroup USBD_REQ_Exported_Macros + * @{ + */ +/** + * @} + */ + +/** @defgroup USBD_REQ_Exported_Variables + * @{ + */ +/** + * @} + */ + +/** @defgroup USBD_REQ_Exported_FunctionsPrototype + * @{ + */ + +USBD_StatusTypeDef USBD_StdDevReq (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +USBD_StatusTypeDef USBD_StdItfReq (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); +USBD_StatusTypeDef USBD_StdEPReq (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); + + +void USBD_CtlError (USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef *req); + +void USBD_ParseSetupRequest (USBD_SetupReqTypedef *req, uint8_t *pdata); + +void USBD_GetString (uint8_t *desc, uint8_t *unicode, uint16_t *len); +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USB_REQUEST_H */ + +/** + * @} + */ + +/** +* @} +*/ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/platform/mcu/stm32l475/Middlewares/USB_Device/Core/Inc/usbd_def.h b/platform/mcu/stm32l475/Middlewares/USB_Device/Core/Inc/usbd_def.h new file mode 100644 index 0000000000..d5735a441b --- /dev/null +++ b/platform/mcu/stm32l475/Middlewares/USB_Device/Core/Inc/usbd_def.h @@ -0,0 +1,350 @@ +/** + ****************************************************************************** + * @file usbd_def.h + * @author MCD Application Team + * @version V2.4.2 + * @date 11-December-2015 + * @brief General defines for the usb device library + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBD_DEF_H +#define __USBD_DEF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_conf.h" + +/** @addtogroup STM32_USBD_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USB_DEF + * @brief general defines for the usb device library file + * @{ + */ + +/** @defgroup USB_DEF_Exported_Defines + * @{ + */ + +#ifndef NULL +#define NULL 0 +#endif + + +#define USB_LEN_DEV_QUALIFIER_DESC 0x0A +#define USB_LEN_DEV_DESC 0x12 +#define USB_LEN_CFG_DESC 0x09 +#define USB_LEN_IF_DESC 0x09 +#define USB_LEN_EP_DESC 0x07 +#define USB_LEN_OTG_DESC 0x03 +#define USB_LEN_LANGID_STR_DESC 0x04 +#define USB_LEN_OTHER_SPEED_DESC_SIZ 0x09 + +#define USBD_IDX_LANGID_STR 0x00 +#define USBD_IDX_MFC_STR 0x01 +#define USBD_IDX_PRODUCT_STR 0x02 +#define USBD_IDX_SERIAL_STR 0x03 +#define USBD_IDX_CONFIG_STR 0x04 +#define USBD_IDX_INTERFACE_STR 0x05 + +#define USB_REQ_TYPE_STANDARD 0x00 +#define USB_REQ_TYPE_CLASS 0x20 +#define USB_REQ_TYPE_VENDOR 0x40 +#define USB_REQ_TYPE_MASK 0x60 + +#define USB_REQ_RECIPIENT_DEVICE 0x00 +#define USB_REQ_RECIPIENT_INTERFACE 0x01 +#define USB_REQ_RECIPIENT_ENDPOINT 0x02 +#define USB_REQ_RECIPIENT_MASK 0x03 + +#define USB_REQ_GET_STATUS 0x00 +#define USB_REQ_CLEAR_FEATURE 0x01 +#define USB_REQ_SET_FEATURE 0x03 +#define USB_REQ_SET_ADDRESS 0x05 +#define USB_REQ_GET_DESCRIPTOR 0x06 +#define USB_REQ_SET_DESCRIPTOR 0x07 +#define USB_REQ_GET_CONFIGURATION 0x08 +#define USB_REQ_SET_CONFIGURATION 0x09 +#define USB_REQ_GET_INTERFACE 0x0A +#define USB_REQ_SET_INTERFACE 0x0B +#define USB_REQ_SYNCH_FRAME 0x0C + +#define USB_DESC_TYPE_DEVICE 1 +#define USB_DESC_TYPE_CONFIGURATION 2 +#define USB_DESC_TYPE_STRING 3 +#define USB_DESC_TYPE_INTERFACE 4 +#define USB_DESC_TYPE_ENDPOINT 5 +#define USB_DESC_TYPE_DEVICE_QUALIFIER 6 +#define USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION 7 +#define USB_DESC_TYPE_BOS 0x0F + +#define USB_CONFIG_REMOTE_WAKEUP 2 +#define USB_CONFIG_SELF_POWERED 1 + +#define USB_FEATURE_EP_HALT 0 +#define USB_FEATURE_REMOTE_WAKEUP 1 +#define USB_FEATURE_TEST_MODE 2 + +#define USB_DEVICE_CAPABITY_TYPE 0x10 + +#define USB_HS_MAX_PACKET_SIZE 512 +#define USB_FS_MAX_PACKET_SIZE 64 +#define USB_MAX_EP0_SIZE 64 + +/* Device Status */ +#define USBD_STATE_DEFAULT 1 +#define USBD_STATE_ADDRESSED 2 +#define USBD_STATE_CONFIGURED 3 +#define USBD_STATE_SUSPENDED 4 + + +/* EP0 State */ +#define USBD_EP0_IDLE 0 +#define USBD_EP0_SETUP 1 +#define USBD_EP0_DATA_IN 2 +#define USBD_EP0_DATA_OUT 3 +#define USBD_EP0_STATUS_IN 4 +#define USBD_EP0_STATUS_OUT 5 +#define USBD_EP0_STALL 6 + +#define USBD_EP_TYPE_CTRL 0 +#define USBD_EP_TYPE_ISOC 1 +#define USBD_EP_TYPE_BULK 2 +#define USBD_EP_TYPE_INTR 3 + + +/** + * @} + */ + + +/** @defgroup USBD_DEF_Exported_TypesDefinitions + * @{ + */ + +typedef struct usb_setup_req +{ + + uint8_t bmRequest; + uint8_t bRequest; + uint16_t wValue; + uint16_t wIndex; + uint16_t wLength; +}USBD_SetupReqTypedef; + +struct _USBD_HandleTypeDef; + +typedef struct _Device_cb +{ + uint8_t (*Init) (struct _USBD_HandleTypeDef *pdev , uint8_t cfgidx); + uint8_t (*DeInit) (struct _USBD_HandleTypeDef *pdev , uint8_t cfgidx); + /* Control Endpoints*/ + uint8_t (*Setup) (struct _USBD_HandleTypeDef *pdev , USBD_SetupReqTypedef *req); + uint8_t (*EP0_TxSent) (struct _USBD_HandleTypeDef *pdev ); + uint8_t (*EP0_RxReady) (struct _USBD_HandleTypeDef *pdev ); + /* Class Specific Endpoints*/ + uint8_t (*DataIn) (struct _USBD_HandleTypeDef *pdev , uint8_t epnum); + uint8_t (*DataOut) (struct _USBD_HandleTypeDef *pdev , uint8_t epnum); + uint8_t (*SOF) (struct _USBD_HandleTypeDef *pdev); + uint8_t (*IsoINIncomplete) (struct _USBD_HandleTypeDef *pdev , uint8_t epnum); + uint8_t (*IsoOUTIncomplete) (struct _USBD_HandleTypeDef *pdev , uint8_t epnum); + + uint8_t *(*GetHSConfigDescriptor)(uint16_t *length); + uint8_t *(*GetFSConfigDescriptor)(uint16_t *length); + uint8_t *(*GetOtherSpeedConfigDescriptor)(uint16_t *length); + uint8_t *(*GetDeviceQualifierDescriptor)(uint16_t *length); +#if (USBD_SUPPORT_USER_STRING == 1) + uint8_t *(*GetUsrStrDescriptor)(struct _USBD_HandleTypeDef *pdev ,uint8_t index, uint16_t *length); +#endif + +} USBD_ClassTypeDef; + +/* Following USB Device Speed */ +typedef enum +{ + USBD_SPEED_HIGH = 0, + USBD_SPEED_FULL = 1, + USBD_SPEED_LOW = 2, +}USBD_SpeedTypeDef; + +/* Following USB Device status */ +typedef enum { + USBD_OK = 0, + USBD_BUSY, + USBD_FAIL, +}USBD_StatusTypeDef; + +/* USB Device descriptors structure */ +typedef struct +{ + uint8_t *(*GetDeviceDescriptor)( USBD_SpeedTypeDef speed , uint16_t *length); + uint8_t *(*GetLangIDStrDescriptor)( USBD_SpeedTypeDef speed , uint16_t *length); + uint8_t *(*GetManufacturerStrDescriptor)( USBD_SpeedTypeDef speed , uint16_t *length); + uint8_t *(*GetProductStrDescriptor)( USBD_SpeedTypeDef speed , uint16_t *length); + uint8_t *(*GetSerialStrDescriptor)( USBD_SpeedTypeDef speed , uint16_t *length); + uint8_t *(*GetConfigurationStrDescriptor)( USBD_SpeedTypeDef speed , uint16_t *length); + uint8_t *(*GetInterfaceStrDescriptor)( USBD_SpeedTypeDef speed , uint16_t *length); +#if (USBD_LPM_ENABLED == 1) + uint8_t *(*GetBOSDescriptor)( USBD_SpeedTypeDef speed , uint16_t *length); +#endif +} USBD_DescriptorsTypeDef; + +/* USB Device handle structure */ +typedef struct +{ + uint32_t status; + uint32_t total_length; + uint32_t rem_length; + uint32_t maxpacket; +} USBD_EndpointTypeDef; + +/* USB Device handle structure */ +typedef struct _USBD_HandleTypeDef +{ + uint8_t id; + uint32_t dev_config; + uint32_t dev_default_config; + uint32_t dev_config_status; + USBD_SpeedTypeDef dev_speed; + USBD_EndpointTypeDef ep_in[15]; + USBD_EndpointTypeDef ep_out[15]; + uint32_t ep0_state; + uint32_t ep0_data_len; + uint8_t dev_state; + uint8_t dev_old_state; + uint8_t dev_address; + uint8_t dev_connection_status; + uint8_t dev_test_mode; + uint32_t dev_remote_wakeup; + + USBD_SetupReqTypedef request; + USBD_DescriptorsTypeDef *pDesc; + USBD_ClassTypeDef *pClass; + void *pClassData; + void *pUserData; + void *pData; +} USBD_HandleTypeDef; + +/** + * @} + */ + + + +/** @defgroup USBD_DEF_Exported_Macros + * @{ + */ +#define SWAPBYTE(addr) (((uint16_t)(*((uint8_t *)(addr)))) + \ + (((uint16_t)(*(((uint8_t *)(addr)) + 1))) << 8)) + +#define LOBYTE(x) ((uint8_t)(x & 0x00FF)) +#define HIBYTE(x) ((uint8_t)((x & 0xFF00) >>8)) +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) + + +#if defined ( __GNUC__ ) + #ifndef __weak + #define __weak __attribute__((weak)) + #endif /* __weak */ + #ifndef __packed + #define __packed __attribute__((__packed__)) + #endif /* __packed */ +#endif /* __GNUC__ */ + + +/* In HS mode and when the DMA is used, all variables and data structures dealing + with the DMA during the transaction process should be 4-bytes aligned */ + +#if defined (__GNUC__) /* GNU Compiler */ + #define __ALIGN_END __attribute__ ((aligned (4))) + #define __ALIGN_BEGIN +#else + #define __ALIGN_END + #if defined (__CC_ARM) /* ARM Compiler */ + #define __ALIGN_BEGIN __align(4) + #elif defined (__ICCARM__) /* IAR Compiler */ + #define __ALIGN_BEGIN + #elif defined (__TASKING__) /* TASKING Compiler */ + #define __ALIGN_BEGIN __align(4) + #endif /* __CC_ARM */ +#endif /* __GNUC__ */ + + +/** + * @} + */ + +/** @defgroup USBD_DEF_Exported_Variables + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_DEF_Exported_FunctionsPrototype + * @{ + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USBD_DEF_H */ + +/** + * @} + */ + +/** +* @} +*/ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/platform/mcu/stm32l475/Middlewares/USB_Device/Core/Inc/usbd_ioreq.h b/platform/mcu/stm32l475/Middlewares/USB_Device/Core/Inc/usbd_ioreq.h new file mode 100644 index 0000000000..0ad31d35b2 --- /dev/null +++ b/platform/mcu/stm32l475/Middlewares/USB_Device/Core/Inc/usbd_ioreq.h @@ -0,0 +1,148 @@ +/** + ****************************************************************************** + * @file usbd_ioreq.h + * @author MCD Application Team + * @version V2.4.2 + * @date 11-December-2015 + * @brief Header file for the usbd_ioreq.c file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBD_IOREQ_H +#define __USBD_IOREQ_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_def.h" +#include "usbd_core.h" + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + +/** @defgroup USBD_IOREQ + * @brief header file for the usbd_ioreq.c file + * @{ + */ + +/** @defgroup USBD_IOREQ_Exported_Defines + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_IOREQ_Exported_Types + * @{ + */ + + +/** + * @} + */ + + + +/** @defgroup USBD_IOREQ_Exported_Macros + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_IOREQ_Exported_Variables + * @{ + */ + +/** + * @} + */ + +/** @defgroup USBD_IOREQ_Exported_FunctionsPrototype + * @{ + */ + +USBD_StatusTypeDef USBD_CtlSendData (USBD_HandleTypeDef *pdev, + uint8_t *buf, + uint16_t len); + +USBD_StatusTypeDef USBD_CtlContinueSendData (USBD_HandleTypeDef *pdev, + uint8_t *pbuf, + uint16_t len); + +USBD_StatusTypeDef USBD_CtlPrepareRx (USBD_HandleTypeDef *pdev, + uint8_t *pbuf, + uint16_t len); + +USBD_StatusTypeDef USBD_CtlContinueRx (USBD_HandleTypeDef *pdev, + uint8_t *pbuf, + uint16_t len); + +USBD_StatusTypeDef USBD_CtlSendStatus (USBD_HandleTypeDef *pdev); + +USBD_StatusTypeDef USBD_CtlReceiveStatus (USBD_HandleTypeDef *pdev); + +uint16_t USBD_GetRxCount (USBD_HandleTypeDef *pdev , + uint8_t epnum); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __USBD_IOREQ_H */ + +/** + * @} + */ + +/** +* @} +*/ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/platform/mcu/stm32l475/Middlewares/USB_Device/Core/Src/usbd_conf_template.c b/platform/mcu/stm32l475/Middlewares/USB_Device/Core/Src/usbd_conf_template.c new file mode 100644 index 0000000000..72b3c80913 --- /dev/null +++ b/platform/mcu/stm32l475/Middlewares/USB_Device/Core/Src/usbd_conf_template.c @@ -0,0 +1,232 @@ +/** + ****************************************************************************** + * @file usbd_conf_template.c + * @author MCD Application Team + * @version V2.4.2 + * @date 11-December-2015 + * @brief USB Device configuration and interface file + * This template should be copied to the user folder, renamed and customized + * following user needs. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_core.h" +/* Private typedef -----------------------------------------------------------*/ +/* Private define ------------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ +/* Private function prototypes -----------------------------------------------*/ +/* Private functions ---------------------------------------------------------*/ +/** + * @brief Initializes the Low Level portion of the Device driver. + * @param pdev: Device handle + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev) +{ + return USBD_OK; +} + +/** + * @brief De-Initializes the Low Level portion of the Device driver. + * @param pdev: Device handle + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_DeInit(USBD_HandleTypeDef *pdev) +{ + return USBD_OK; +} + +/** + * @brief Starts the Low Level portion of the Device driver. + * @param pdev: Device handle + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev) +{ + return USBD_OK; +} + +/** + * @brief Stops the Low Level portion of the Device driver. + * @param pdev: Device handle + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_Stop(USBD_HandleTypeDef *pdev) +{ + return USBD_OK; +} + +/** + * @brief Opens an endpoint of the Low Level Driver. + * @param pdev: Device handle + * @param ep_addr: Endpoint Number + * @param ep_type: Endpoint Type + * @param ep_mps: Endpoint Max Packet Size + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_OpenEP(USBD_HandleTypeDef *pdev, + uint8_t ep_addr, + uint8_t ep_type, + uint16_t ep_mps) +{ + return USBD_OK; +} + +/** + * @brief Closes an endpoint of the Low Level Driver. + * @param pdev: Device handle + * @param ep_addr: Endpoint Number + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_CloseEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + return USBD_OK; +} + +/** + * @brief Flushes an endpoint of the Low Level Driver. + * @param pdev: Device handle + * @param ep_addr: Endpoint Number + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_FlushEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + return USBD_OK; +} + +/** + * @brief Sets a Stall condition on an endpoint of the Low Level Driver. + * @param pdev: Device handle + * @param ep_addr: Endpoint Number + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_StallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + return USBD_OK; +} + +/** + * @brief Clears a Stall condition on an endpoint of the Low Level Driver. + * @param pdev: Device handle + * @param ep_addr: Endpoint Number + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_ClearStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + return USBD_OK; +} + +/** + * @brief Returns Stall condition. + * @param pdev: Device handle + * @param ep_addr: Endpoint Number + * @retval Stall (1: Yes, 0: No) + */ +uint8_t USBD_LL_IsStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + return 0; +} + +/** + * @brief Assigns a USB address to the device. + * @param pdev: Device handle + * @param ep_addr: Endpoint Number + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_SetUSBAddress(USBD_HandleTypeDef *pdev, uint8_t dev_addr) +{ + return USBD_OK; +} + +/** + * @brief Transmits data over an endpoint. + * @param pdev: Device handle + * @param ep_addr: Endpoint Number + * @param pbuf: Pointer to data to be sent + * @param size: Data size + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_Transmit(USBD_HandleTypeDef *pdev, + uint8_t ep_addr, + uint8_t *pbuf, + uint16_t size) +{ + return USBD_OK; +} + +/** + * @brief Prepares an endpoint for reception. + * @param pdev: Device handle + * @param ep_addr: Endpoint Number + * @param pbuf: Pointer to data to be received + * @param size: Data size + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev, + uint8_t ep_addr, + uint8_t *pbuf, + uint16_t size) +{ + return USBD_OK; +} + +/** + * @brief Returns the last transferred packet size. + * @param pdev: Device handle + * @param ep_addr: Endpoint Number + * @retval Recived Data Size + */ +uint32_t USBD_LL_GetRxDataSize(USBD_HandleTypeDef *pdev, uint8_t ep_addr) +{ + return 0; +} + +/** + * @brief Delays routine for the USB Device Library. + * @param Delay: Delay in ms + * @retval None + */ +void USBD_LL_Delay(uint32_t Delay) +{ +} +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/platform/mcu/stm32l475/Middlewares/USB_Device/Core/Src/usbd_core.c b/platform/mcu/stm32l475/Middlewares/USB_Device/Core/Src/usbd_core.c new file mode 100644 index 0000000000..066d135b0a --- /dev/null +++ b/platform/mcu/stm32l475/Middlewares/USB_Device/Core/Src/usbd_core.c @@ -0,0 +1,585 @@ +/** + ****************************************************************************** + * @file usbd_core.c + * @author MCD Application Team + * @version V2.4.2 + * @date 11-December-2015 + * @brief This file provides all the USBD core functions. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_core.h" + +/** @addtogroup STM32_USBD_DEVICE_LIBRARY +* @{ +*/ + + +/** @defgroup USBD_CORE +* @brief usbd core module +* @{ +*/ + +/** @defgroup USBD_CORE_Private_TypesDefinitions +* @{ +*/ +/** +* @} +*/ + + +/** @defgroup USBD_CORE_Private_Defines +* @{ +*/ + +/** +* @} +*/ + + +/** @defgroup USBD_CORE_Private_Macros +* @{ +*/ +/** +* @} +*/ + + + + +/** @defgroup USBD_CORE_Private_FunctionPrototypes +* @{ +*/ + +/** +* @} +*/ + +/** @defgroup USBD_CORE_Private_Variables +* @{ +*/ + +/** +* @} +*/ + +/** @defgroup USBD_CORE_Private_Functions +* @{ +*/ + +/** +* @brief USBD_Init +* Initializes the device stack and load the class driver +* @param pdev: device instance +* @param pdesc: Descriptor structure address +* @param id: Low level core index +* @retval None +*/ +USBD_StatusTypeDef USBD_Init(USBD_HandleTypeDef *pdev, USBD_DescriptorsTypeDef *pdesc, uint8_t id) +{ + /* Check whether the USB Host handle is valid */ + if(pdev == NULL) + { + USBD_ErrLog("Invalid Device handle"); + return USBD_FAIL; + } + + /* Unlink previous class*/ + if(pdev->pClass != NULL) + { + pdev->pClass = NULL; + } + + /* Assign USBD Descriptors */ + if(pdesc != NULL) + { + pdev->pDesc = pdesc; + } + + /* Set Device initial State */ + pdev->dev_state = USBD_STATE_DEFAULT; + pdev->id = id; + /* Initialize low level driver */ + USBD_LL_Init(pdev); + + return USBD_OK; +} + +/** +* @brief USBD_DeInit +* Re-Initialize th device library +* @param pdev: device instance +* @retval status: status +*/ +USBD_StatusTypeDef USBD_DeInit(USBD_HandleTypeDef *pdev) +{ + /* Set Default State */ + pdev->dev_state = USBD_STATE_DEFAULT; + + /* Free Class Resources */ + pdev->pClass->DeInit(pdev, pdev->dev_config); + + /* Stop the low level driver */ + USBD_LL_Stop(pdev); + + /* Initialize low level driver */ + USBD_LL_DeInit(pdev); + + return USBD_OK; +} + + +/** + * @brief USBD_RegisterClass + * Link class driver to Device Core. + * @param pDevice : Device Handle + * @param pclass: Class handle + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_RegisterClass(USBD_HandleTypeDef *pdev, USBD_ClassTypeDef *pclass) +{ + USBD_StatusTypeDef status = USBD_OK; + if(pclass != 0) + { + /* link the class to the USB Device handle */ + pdev->pClass = pclass; + status = USBD_OK; + } + else + { + USBD_ErrLog("Invalid Class handle"); + status = USBD_FAIL; + } + + return status; +} + +/** + * @brief USBD_Start + * Start the USB Device Core. + * @param pdev: Device Handle + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_Start (USBD_HandleTypeDef *pdev) +{ + + /* Start the low level driver */ + USBD_LL_Start(pdev); + + return USBD_OK; +} + +/** + * @brief USBD_Stop + * Stop the USB Device Core. + * @param pdev: Device Handle + * @retval USBD Status + */ +USBD_StatusTypeDef USBD_Stop (USBD_HandleTypeDef *pdev) +{ + /* Free Class Resources */ + pdev->pClass->DeInit(pdev, pdev->dev_config); + + /* Stop the low level driver */ + USBD_LL_Stop(pdev); + + return USBD_OK; +} + +/** +* @brief USBD_RunTestMode +* Launch test mode process +* @param pdev: device instance +* @retval status +*/ +USBD_StatusTypeDef USBD_RunTestMode (USBD_HandleTypeDef *pdev) +{ + return USBD_OK; +} + + +/** +* @brief USBD_SetClassConfig +* Configure device and start the interface +* @param pdev: device instance +* @param cfgidx: configuration index +* @retval status +*/ + +USBD_StatusTypeDef USBD_SetClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx) +{ + USBD_StatusTypeDef ret = USBD_FAIL; + + if(pdev->pClass != NULL) + { + /* Set configuration and Start the Class*/ + if(pdev->pClass->Init(pdev, cfgidx) == 0) + { + ret = USBD_OK; + } + } + return ret; +} + +/** +* @brief USBD_ClrClassConfig +* Clear current configuration +* @param pdev: device instance +* @param cfgidx: configuration index +* @retval status: USBD_StatusTypeDef +*/ +USBD_StatusTypeDef USBD_ClrClassConfig(USBD_HandleTypeDef *pdev, uint8_t cfgidx) +{ + /* Clear configuration and De-initialize the Class process*/ + pdev->pClass->DeInit(pdev, cfgidx); + return USBD_OK; +} + + +/** +* @brief USBD_SetupStage +* Handle the setup stage +* @param pdev: device instance +* @retval status +*/ +USBD_StatusTypeDef USBD_LL_SetupStage(USBD_HandleTypeDef *pdev, uint8_t *psetup) +{ + + USBD_ParseSetupRequest(&pdev->request, psetup); + + pdev->ep0_state = USBD_EP0_SETUP; + pdev->ep0_data_len = pdev->request.wLength; + + switch (pdev->request.bmRequest & 0x1F) + { + case USB_REQ_RECIPIENT_DEVICE: + USBD_StdDevReq (pdev, &pdev->request); + break; + + case USB_REQ_RECIPIENT_INTERFACE: + USBD_StdItfReq(pdev, &pdev->request); + break; + + case USB_REQ_RECIPIENT_ENDPOINT: + USBD_StdEPReq(pdev, &pdev->request); + break; + + default: + USBD_LL_StallEP(pdev , pdev->request.bmRequest & 0x80); + break; + } + return USBD_OK; +} + +/** +* @brief USBD_DataOutStage +* Handle data OUT stage +* @param pdev: device instance +* @param epnum: endpoint index +* @retval status +*/ +USBD_StatusTypeDef USBD_LL_DataOutStage(USBD_HandleTypeDef *pdev , uint8_t epnum, uint8_t *pdata) +{ + USBD_EndpointTypeDef *pep; + + if(epnum == 0) + { + pep = &pdev->ep_out[0]; + + if ( pdev->ep0_state == USBD_EP0_DATA_OUT) + { + if(pep->rem_length > pep->maxpacket) + { + pep->rem_length -= pep->maxpacket; + + USBD_CtlContinueRx (pdev, + pdata, + MIN(pep->rem_length ,pep->maxpacket)); + } + else + { + if((pdev->pClass->EP0_RxReady != NULL)&& + (pdev->dev_state == USBD_STATE_CONFIGURED)) + { + pdev->pClass->EP0_RxReady(pdev); + } + USBD_CtlSendStatus(pdev); + } + } + } + else if((pdev->pClass->DataOut != NULL)&& + (pdev->dev_state == USBD_STATE_CONFIGURED)) + { + pdev->pClass->DataOut(pdev, epnum); + } + return USBD_OK; +} + +/** +* @brief USBD_DataInStage +* Handle data in stage +* @param pdev: device instance +* @param epnum: endpoint index +* @retval status +*/ +USBD_StatusTypeDef USBD_LL_DataInStage(USBD_HandleTypeDef *pdev ,uint8_t epnum, uint8_t *pdata) +{ + USBD_EndpointTypeDef *pep; + + if(epnum == 0) + { + pep = &pdev->ep_in[0]; + + if ( pdev->ep0_state == USBD_EP0_DATA_IN) + { + if(pep->rem_length > pep->maxpacket) + { + pep->rem_length -= pep->maxpacket; + + USBD_CtlContinueSendData (pdev, + pdata, + pep->rem_length); + + /* Prepare endpoint for premature end of transfer */ + USBD_LL_PrepareReceive (pdev, + 0, + NULL, + 0); + } + else + { /* last packet is MPS multiple, so send ZLP packet */ + if((pep->total_length % pep->maxpacket == 0) && + (pep->total_length >= pep->maxpacket) && + (pep->total_length < pdev->ep0_data_len )) + { + + USBD_CtlContinueSendData(pdev , NULL, 0); + pdev->ep0_data_len = 0; + + /* Prepare endpoint for premature end of transfer */ + USBD_LL_PrepareReceive (pdev, + 0, + NULL, + 0); + } + else + { + if((pdev->pClass->EP0_TxSent != NULL)&& + (pdev->dev_state == USBD_STATE_CONFIGURED)) + { + pdev->pClass->EP0_TxSent(pdev); + } + USBD_CtlReceiveStatus(pdev); + } + } + } + if (pdev->dev_test_mode == 1) + { + USBD_RunTestMode(pdev); + pdev->dev_test_mode = 0; + } + } + else if((pdev->pClass->DataIn != NULL)&& + (pdev->dev_state == USBD_STATE_CONFIGURED)) + { + pdev->pClass->DataIn(pdev, epnum); + } + return USBD_OK; +} + +/** +* @brief USBD_LL_Reset +* Handle Reset event +* @param pdev: device instance +* @retval status +*/ + +USBD_StatusTypeDef USBD_LL_Reset(USBD_HandleTypeDef *pdev) +{ + /* Open EP0 OUT */ + USBD_LL_OpenEP(pdev, + 0x00, + USBD_EP_TYPE_CTRL, + USB_MAX_EP0_SIZE); + + pdev->ep_out[0].maxpacket = USB_MAX_EP0_SIZE; + + /* Open EP0 IN */ + USBD_LL_OpenEP(pdev, + 0x80, + USBD_EP_TYPE_CTRL, + USB_MAX_EP0_SIZE); + + pdev->ep_in[0].maxpacket = USB_MAX_EP0_SIZE; + /* Upon Reset call user call back */ + pdev->dev_state = USBD_STATE_DEFAULT; + + if (pdev->pClassData) + pdev->pClass->DeInit(pdev, pdev->dev_config); + + + return USBD_OK; +} + + + + +/** +* @brief USBD_LL_Reset +* Handle Reset event +* @param pdev: device instance +* @retval status +*/ +USBD_StatusTypeDef USBD_LL_SetSpeed(USBD_HandleTypeDef *pdev, USBD_SpeedTypeDef speed) +{ + pdev->dev_speed = speed; + return USBD_OK; +} + +/** +* @brief USBD_Suspend +* Handle Suspend event +* @param pdev: device instance +* @retval status +*/ + +USBD_StatusTypeDef USBD_LL_Suspend(USBD_HandleTypeDef *pdev) +{ + pdev->dev_old_state = pdev->dev_state; + pdev->dev_state = USBD_STATE_SUSPENDED; + return USBD_OK; +} + +/** +* @brief USBD_Resume +* Handle Resume event +* @param pdev: device instance +* @retval status +*/ + +USBD_StatusTypeDef USBD_LL_Resume(USBD_HandleTypeDef *pdev) +{ + pdev->dev_state = pdev->dev_old_state; + return USBD_OK; +} + +/** +* @brief USBD_SOF +* Handle SOF event +* @param pdev: device instance +* @retval status +*/ + +USBD_StatusTypeDef USBD_LL_SOF(USBD_HandleTypeDef *pdev) +{ + if(pdev->dev_state == USBD_STATE_CONFIGURED) + { + if(pdev->pClass->SOF != NULL) + { + pdev->pClass->SOF(pdev); + } + } + return USBD_OK; +} + +/** +* @brief USBD_IsoINIncomplete +* Handle iso in incomplete event +* @param pdev: device instance +* @retval status +*/ +USBD_StatusTypeDef USBD_LL_IsoINIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + return USBD_OK; +} + +/** +* @brief USBD_IsoOUTIncomplete +* Handle iso out incomplete event +* @param pdev: device instance +* @retval status +*/ +USBD_StatusTypeDef USBD_LL_IsoOUTIncomplete(USBD_HandleTypeDef *pdev, uint8_t epnum) +{ + return USBD_OK; +} + +/** +* @brief USBD_DevConnected +* Handle device connection event +* @param pdev: device instance +* @retval status +*/ +USBD_StatusTypeDef USBD_LL_DevConnected(USBD_HandleTypeDef *pdev) +{ + return USBD_OK; +} + +/** +* @brief USBD_DevDisconnected +* Handle device disconnection event +* @param pdev: device instance +* @retval status +*/ +USBD_StatusTypeDef USBD_LL_DevDisconnected(USBD_HandleTypeDef *pdev) +{ + /* Free Class Resources */ + pdev->dev_state = USBD_STATE_DEFAULT; + pdev->pClass->DeInit(pdev, pdev->dev_config); + + return USBD_OK; +} +/** +* @} +*/ + + +/** +* @} +*/ + + +/** +* @} +*/ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ + diff --git a/platform/mcu/stm32l475/Middlewares/USB_Device/Core/Src/usbd_ctlreq.c b/platform/mcu/stm32l475/Middlewares/USB_Device/Core/Src/usbd_ctlreq.c new file mode 100644 index 0000000000..19b19d93ec --- /dev/null +++ b/platform/mcu/stm32l475/Middlewares/USB_Device/Core/Src/usbd_ctlreq.c @@ -0,0 +1,802 @@ +/** + ****************************************************************************** + * @file usbd_req.c + * @author MCD Application Team + * @version V2.4.2 + * @date 11-December-2015 + * @brief This file provides the standard USB requests following chapter 9. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_ctlreq.h" +#include "usbd_ioreq.h" + + +/** @addtogroup STM32_USBD_STATE_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup USBD_REQ + * @brief USB standard requests module + * @{ + */ + +/** @defgroup USBD_REQ_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_REQ_Private_Defines + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_REQ_Private_Macros + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_REQ_Private_Variables + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_REQ_Private_FunctionPrototypes + * @{ + */ +static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev , + USBD_SetupReqTypedef *req); + +static void USBD_SetAddress(USBD_HandleTypeDef *pdev , + USBD_SetupReqTypedef *req); + +static void USBD_SetConfig(USBD_HandleTypeDef *pdev , + USBD_SetupReqTypedef *req); + +static void USBD_GetConfig(USBD_HandleTypeDef *pdev , + USBD_SetupReqTypedef *req); + +static void USBD_GetStatus(USBD_HandleTypeDef *pdev , + USBD_SetupReqTypedef *req); + +static void USBD_SetFeature(USBD_HandleTypeDef *pdev , + USBD_SetupReqTypedef *req); + +static void USBD_ClrFeature(USBD_HandleTypeDef *pdev , + USBD_SetupReqTypedef *req); + +static uint8_t USBD_GetLen(uint8_t *buf); + +/** + * @} + */ + + +/** @defgroup USBD_REQ_Private_Functions + * @{ + */ + + +/** +* @brief USBD_StdDevReq +* Handle standard usb device requests +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +USBD_StatusTypeDef USBD_StdDevReq (USBD_HandleTypeDef *pdev , USBD_SetupReqTypedef *req) +{ + USBD_StatusTypeDef ret = USBD_OK; + + switch (req->bRequest) + { + case USB_REQ_GET_DESCRIPTOR: + + USBD_GetDescriptor (pdev, req) ; + break; + + case USB_REQ_SET_ADDRESS: + USBD_SetAddress(pdev, req); + break; + + case USB_REQ_SET_CONFIGURATION: + USBD_SetConfig (pdev , req); + break; + + case USB_REQ_GET_CONFIGURATION: + USBD_GetConfig (pdev , req); + break; + + case USB_REQ_GET_STATUS: + USBD_GetStatus (pdev , req); + break; + + + case USB_REQ_SET_FEATURE: + USBD_SetFeature (pdev , req); + break; + + case USB_REQ_CLEAR_FEATURE: + USBD_ClrFeature (pdev , req); + break; + + default: + USBD_CtlError(pdev , req); + break; + } + + return ret; +} + +/** +* @brief USBD_StdItfReq +* Handle standard usb interface requests +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +USBD_StatusTypeDef USBD_StdItfReq (USBD_HandleTypeDef *pdev , USBD_SetupReqTypedef *req) +{ + USBD_StatusTypeDef ret = USBD_OK; + + switch (pdev->dev_state) + { + case USBD_STATE_CONFIGURED: + + if (LOBYTE(req->wIndex) <= USBD_MAX_NUM_INTERFACES) + { + pdev->pClass->Setup (pdev, req); + + if((req->wLength == 0)&& (ret == USBD_OK)) + { + USBD_CtlSendStatus(pdev); + } + } + else + { + USBD_CtlError(pdev , req); + } + break; + + default: + USBD_CtlError(pdev , req); + break; + } + return USBD_OK; +} + +/** +* @brief USBD_StdEPReq +* Handle standard usb endpoint requests +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +USBD_StatusTypeDef USBD_StdEPReq (USBD_HandleTypeDef *pdev , USBD_SetupReqTypedef *req) +{ + + uint8_t ep_addr; + USBD_StatusTypeDef ret = USBD_OK; + USBD_EndpointTypeDef *pep; + ep_addr = LOBYTE(req->wIndex); + + /* Check if it is a class request */ + if ((req->bmRequest & 0x60) == 0x20) + { + pdev->pClass->Setup (pdev, req); + + return USBD_OK; + } + + switch (req->bRequest) + { + + case USB_REQ_SET_FEATURE : + + switch (pdev->dev_state) + { + case USBD_STATE_ADDRESSED: + if ((ep_addr != 0x00) && (ep_addr != 0x80)) + { + USBD_LL_StallEP(pdev , ep_addr); + } + break; + + case USBD_STATE_CONFIGURED: + if (req->wValue == USB_FEATURE_EP_HALT) + { + if ((ep_addr != 0x00) && (ep_addr != 0x80)) + { + USBD_LL_StallEP(pdev , ep_addr); + + } + } + pdev->pClass->Setup (pdev, req); + USBD_CtlSendStatus(pdev); + + break; + + default: + USBD_CtlError(pdev , req); + break; + } + break; + + case USB_REQ_CLEAR_FEATURE : + + switch (pdev->dev_state) + { + case USBD_STATE_ADDRESSED: + if ((ep_addr != 0x00) && (ep_addr != 0x80)) + { + USBD_LL_StallEP(pdev , ep_addr); + } + break; + + case USBD_STATE_CONFIGURED: + if (req->wValue == USB_FEATURE_EP_HALT) + { + if ((ep_addr & 0x7F) != 0x00) + { + USBD_LL_ClearStallEP(pdev , ep_addr); + pdev->pClass->Setup (pdev, req); + } + USBD_CtlSendStatus(pdev); + } + break; + + default: + USBD_CtlError(pdev , req); + break; + } + break; + + case USB_REQ_GET_STATUS: + switch (pdev->dev_state) + { + case USBD_STATE_ADDRESSED: + if ((ep_addr & 0x7F) != 0x00) + { + USBD_LL_StallEP(pdev , ep_addr); + } + break; + + case USBD_STATE_CONFIGURED: + pep = ((ep_addr & 0x80) == 0x80) ? &pdev->ep_in[ep_addr & 0x7F]:\ + &pdev->ep_out[ep_addr & 0x7F]; + if(USBD_LL_IsStallEP(pdev, ep_addr)) + { + pep->status = 0x0001; + } + else + { + pep->status = 0x0000; + } + + USBD_CtlSendData (pdev, + (uint8_t *)&pep->status, + 2); + break; + + default: + USBD_CtlError(pdev , req); + break; + } + break; + + default: + break; + } + return ret; +} +/** +* @brief USBD_GetDescriptor +* Handle Get Descriptor requests +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +static void USBD_GetDescriptor(USBD_HandleTypeDef *pdev , + USBD_SetupReqTypedef *req) +{ + uint16_t len; + uint8_t *pbuf; + + + switch (req->wValue >> 8) + { +#if (USBD_LPM_ENABLED == 1) + case USB_DESC_TYPE_BOS: + pbuf = pdev->pDesc->GetBOSDescriptor(pdev->dev_speed, &len); + break; +#endif + case USB_DESC_TYPE_DEVICE: + pbuf = pdev->pDesc->GetDeviceDescriptor(pdev->dev_speed, &len); + break; + + case USB_DESC_TYPE_CONFIGURATION: + if(pdev->dev_speed == USBD_SPEED_HIGH ) + { + pbuf = (uint8_t *)pdev->pClass->GetHSConfigDescriptor(&len); + pbuf[1] = USB_DESC_TYPE_CONFIGURATION; + } + else + { + pbuf = (uint8_t *)pdev->pClass->GetFSConfigDescriptor(&len); + pbuf[1] = USB_DESC_TYPE_CONFIGURATION; + } + break; + + case USB_DESC_TYPE_STRING: + switch ((uint8_t)(req->wValue)) + { + case USBD_IDX_LANGID_STR: + pbuf = pdev->pDesc->GetLangIDStrDescriptor(pdev->dev_speed, &len); + break; + + case USBD_IDX_MFC_STR: + pbuf = pdev->pDesc->GetManufacturerStrDescriptor(pdev->dev_speed, &len); + break; + + case USBD_IDX_PRODUCT_STR: + pbuf = pdev->pDesc->GetProductStrDescriptor(pdev->dev_speed, &len); + break; + + case USBD_IDX_SERIAL_STR: + pbuf = pdev->pDesc->GetSerialStrDescriptor(pdev->dev_speed, &len); + break; + + case USBD_IDX_CONFIG_STR: + pbuf = pdev->pDesc->GetConfigurationStrDescriptor(pdev->dev_speed, &len); + break; + + case USBD_IDX_INTERFACE_STR: + pbuf = pdev->pDesc->GetInterfaceStrDescriptor(pdev->dev_speed, &len); + break; + + default: +#if (USBD_SUPPORT_USER_STRING == 1) + pbuf = pdev->pClass->GetUsrStrDescriptor(pdev, (req->wValue) , &len); + break; +#else + USBD_CtlError(pdev , req); + return; +#endif + } + break; + case USB_DESC_TYPE_DEVICE_QUALIFIER: + + if(pdev->dev_speed == USBD_SPEED_HIGH ) + { + pbuf = (uint8_t *)pdev->pClass->GetDeviceQualifierDescriptor(&len); + break; + } + else + { + USBD_CtlError(pdev , req); + return; + } + + case USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION: + if(pdev->dev_speed == USBD_SPEED_HIGH ) + { + pbuf = (uint8_t *)pdev->pClass->GetOtherSpeedConfigDescriptor(&len); + pbuf[1] = USB_DESC_TYPE_OTHER_SPEED_CONFIGURATION; + break; + } + else + { + USBD_CtlError(pdev , req); + return; + } + + default: + USBD_CtlError(pdev , req); + return; + } + + if((len != 0)&& (req->wLength != 0)) + { + + len = MIN(len , req->wLength); + + USBD_CtlSendData (pdev, + pbuf, + len); + } + +} + +/** +* @brief USBD_SetAddress +* Set device address +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +static void USBD_SetAddress(USBD_HandleTypeDef *pdev , + USBD_SetupReqTypedef *req) +{ + uint8_t dev_addr; + + if ((req->wIndex == 0) && (req->wLength == 0)) + { + dev_addr = (uint8_t)(req->wValue) & 0x7F; + + if (pdev->dev_state == USBD_STATE_CONFIGURED) + { + USBD_CtlError(pdev , req); + } + else + { + pdev->dev_address = dev_addr; + USBD_LL_SetUSBAddress(pdev, dev_addr); + USBD_CtlSendStatus(pdev); + + if (dev_addr != 0) + { + pdev->dev_state = USBD_STATE_ADDRESSED; + } + else + { + pdev->dev_state = USBD_STATE_DEFAULT; + } + } + } + else + { + USBD_CtlError(pdev , req); + } +} + +/** +* @brief USBD_SetConfig +* Handle Set device configuration request +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +static void USBD_SetConfig(USBD_HandleTypeDef *pdev , + USBD_SetupReqTypedef *req) +{ + + static uint8_t cfgidx; + + cfgidx = (uint8_t)(req->wValue); + + if (cfgidx > USBD_MAX_NUM_CONFIGURATION ) + { + USBD_CtlError(pdev , req); + } + else + { + switch (pdev->dev_state) + { + case USBD_STATE_ADDRESSED: + if (cfgidx) + { + pdev->dev_config = cfgidx; + pdev->dev_state = USBD_STATE_CONFIGURED; + if(USBD_SetClassConfig(pdev , cfgidx) == USBD_FAIL) + { + USBD_CtlError(pdev , req); + return; + } + USBD_CtlSendStatus(pdev); + } + else + { + USBD_CtlSendStatus(pdev); + } + break; + + case USBD_STATE_CONFIGURED: + if (cfgidx == 0) + { + pdev->dev_state = USBD_STATE_ADDRESSED; + pdev->dev_config = cfgidx; + USBD_ClrClassConfig(pdev , cfgidx); + USBD_CtlSendStatus(pdev); + + } + else if (cfgidx != pdev->dev_config) + { + /* Clear old configuration */ + USBD_ClrClassConfig(pdev , pdev->dev_config); + + /* set new configuration */ + pdev->dev_config = cfgidx; + if(USBD_SetClassConfig(pdev , cfgidx) == USBD_FAIL) + { + USBD_CtlError(pdev , req); + return; + } + USBD_CtlSendStatus(pdev); + } + else + { + USBD_CtlSendStatus(pdev); + } + break; + + default: + USBD_CtlError(pdev , req); + break; + } + } +} + +/** +* @brief USBD_GetConfig +* Handle Get device configuration request +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +static void USBD_GetConfig(USBD_HandleTypeDef *pdev , + USBD_SetupReqTypedef *req) +{ + + if (req->wLength != 1) + { + USBD_CtlError(pdev , req); + } + else + { + switch (pdev->dev_state ) + { + case USBD_STATE_ADDRESSED: + pdev->dev_default_config = 0; + USBD_CtlSendData (pdev, + (uint8_t *)&pdev->dev_default_config, + 1); + break; + + case USBD_STATE_CONFIGURED: + + USBD_CtlSendData (pdev, + (uint8_t *)&pdev->dev_config, + 1); + break; + + default: + USBD_CtlError(pdev , req); + break; + } + } +} + +/** +* @brief USBD_GetStatus +* Handle Get Status request +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +static void USBD_GetStatus(USBD_HandleTypeDef *pdev , + USBD_SetupReqTypedef *req) +{ + + + switch (pdev->dev_state) + { + case USBD_STATE_ADDRESSED: + case USBD_STATE_CONFIGURED: + +#if ( USBD_SELF_POWERED == 1) + pdev->dev_config_status = USB_CONFIG_SELF_POWERED; +#else + pdev->dev_config_status = 0; +#endif + + if (pdev->dev_remote_wakeup) + { + pdev->dev_config_status |= USB_CONFIG_REMOTE_WAKEUP; + } + + USBD_CtlSendData (pdev, + (uint8_t *)& pdev->dev_config_status, + 2); + break; + + default : + USBD_CtlError(pdev , req); + break; + } +} + + +/** +* @brief USBD_SetFeature +* Handle Set device feature request +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +static void USBD_SetFeature(USBD_HandleTypeDef *pdev , + USBD_SetupReqTypedef *req) +{ + + if (req->wValue == USB_FEATURE_REMOTE_WAKEUP) + { + pdev->dev_remote_wakeup = 1; + pdev->pClass->Setup (pdev, req); + USBD_CtlSendStatus(pdev); + } + +} + + +/** +* @brief USBD_ClrFeature +* Handle clear device feature request +* @param pdev: device instance +* @param req: usb request +* @retval status +*/ +static void USBD_ClrFeature(USBD_HandleTypeDef *pdev , + USBD_SetupReqTypedef *req) +{ + switch (pdev->dev_state) + { + case USBD_STATE_ADDRESSED: + case USBD_STATE_CONFIGURED: + if (req->wValue == USB_FEATURE_REMOTE_WAKEUP) + { + pdev->dev_remote_wakeup = 0; + pdev->pClass->Setup (pdev, req); + USBD_CtlSendStatus(pdev); + } + break; + + default : + USBD_CtlError(pdev , req); + break; + } +} + +/** +* @brief USBD_ParseSetupRequest +* Copy buffer into setup structure +* @param pdev: device instance +* @param req: usb request +* @retval None +*/ + +void USBD_ParseSetupRequest(USBD_SetupReqTypedef *req, uint8_t *pdata) +{ + req->bmRequest = *(uint8_t *) (pdata); + req->bRequest = *(uint8_t *) (pdata + 1); + req->wValue = SWAPBYTE (pdata + 2); + req->wIndex = SWAPBYTE (pdata + 4); + req->wLength = SWAPBYTE (pdata + 6); + +} + +/** +* @brief USBD_CtlError +* Handle USB low level Error +* @param pdev: device instance +* @param req: usb request +* @retval None +*/ + +void USBD_CtlError( USBD_HandleTypeDef *pdev , + USBD_SetupReqTypedef *req) +{ + USBD_LL_StallEP(pdev , 0x80); + USBD_LL_StallEP(pdev , 0); +} + + +/** + * @brief USBD_GetString + * Convert Ascii string into unicode one + * @param desc : descriptor buffer + * @param unicode : Formatted string buffer (unicode) + * @param len : descriptor length + * @retval None + */ +void USBD_GetString(uint8_t *desc, uint8_t *unicode, uint16_t *len) +{ + uint8_t idx = 0; + + if (desc != NULL) + { + *len = USBD_GetLen(desc) * 2 + 2; + unicode[idx++] = *len; + unicode[idx++] = USB_DESC_TYPE_STRING; + + while (*desc != '\0') + { + unicode[idx++] = *desc++; + unicode[idx++] = 0x00; + } + } +} + +/** + * @brief USBD_GetLen + * return the string length + * @param buf : pointer to the ascii string buffer + * @retval string length + */ +static uint8_t USBD_GetLen(uint8_t *buf) +{ + uint8_t len = 0; + + while (*buf != '\0') + { + len++; + buf++; + } + + return len; +} +/** + * @} + */ + + +/** + * @} + */ + + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/platform/mcu/stm32l475/Middlewares/USB_Device/Core/Src/usbd_ioreq.c b/platform/mcu/stm32l475/Middlewares/USB_Device/Core/Src/usbd_ioreq.c new file mode 100644 index 0000000000..d74a525850 --- /dev/null +++ b/platform/mcu/stm32l475/Middlewares/USB_Device/Core/Src/usbd_ioreq.c @@ -0,0 +1,256 @@ +/** + ****************************************************************************** + * @file usbd_ioreq.c + * @author MCD Application Team + * @version V2.4.2 + * @date 11-December-2015 + * @brief This file provides the IO requests APIs for control endpoints. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "usbd_ioreq.h" + +/** @addtogroup STM32_USB_DEVICE_LIBRARY + * @{ + */ + + +/** @defgroup USBD_IOREQ + * @brief control I/O requests module + * @{ + */ + +/** @defgroup USBD_IOREQ_Private_TypesDefinitions + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_IOREQ_Private_Defines + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_IOREQ_Private_Macros + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_IOREQ_Private_Variables + * @{ + */ + +/** + * @} + */ + + +/** @defgroup USBD_IOREQ_Private_FunctionPrototypes + * @{ + */ +/** + * @} + */ + + +/** @defgroup USBD_IOREQ_Private_Functions + * @{ + */ + +/** +* @brief USBD_CtlSendData +* send data on the ctl pipe +* @param pdev: device instance +* @param buff: pointer to data buffer +* @param len: length of data to be sent +* @retval status +*/ +USBD_StatusTypeDef USBD_CtlSendData (USBD_HandleTypeDef *pdev, + uint8_t *pbuf, + uint16_t len) +{ + /* Set EP0 State */ + pdev->ep0_state = USBD_EP0_DATA_IN; + pdev->ep_in[0].total_length = len; + pdev->ep_in[0].rem_length = len; + /* Start the transfer */ + USBD_LL_Transmit (pdev, 0x00, pbuf, len); + + return USBD_OK; +} + +/** +* @brief USBD_CtlContinueSendData +* continue sending data on the ctl pipe +* @param pdev: device instance +* @param buff: pointer to data buffer +* @param len: length of data to be sent +* @retval status +*/ +USBD_StatusTypeDef USBD_CtlContinueSendData (USBD_HandleTypeDef *pdev, + uint8_t *pbuf, + uint16_t len) +{ + /* Start the next transfer */ + USBD_LL_Transmit (pdev, 0x00, pbuf, len); + + return USBD_OK; +} + +/** +* @brief USBD_CtlPrepareRx +* receive data on the ctl pipe +* @param pdev: device instance +* @param buff: pointer to data buffer +* @param len: length of data to be received +* @retval status +*/ +USBD_StatusTypeDef USBD_CtlPrepareRx (USBD_HandleTypeDef *pdev, + uint8_t *pbuf, + uint16_t len) +{ + /* Set EP0 State */ + pdev->ep0_state = USBD_EP0_DATA_OUT; + pdev->ep_out[0].total_length = len; + pdev->ep_out[0].rem_length = len; + /* Start the transfer */ + USBD_LL_PrepareReceive (pdev, + 0, + pbuf, + len); + + return USBD_OK; +} + +/** +* @brief USBD_CtlContinueRx +* continue receive data on the ctl pipe +* @param pdev: device instance +* @param buff: pointer to data buffer +* @param len: length of data to be received +* @retval status +*/ +USBD_StatusTypeDef USBD_CtlContinueRx (USBD_HandleTypeDef *pdev, + uint8_t *pbuf, + uint16_t len) +{ + + USBD_LL_PrepareReceive (pdev, + 0, + pbuf, + len); + return USBD_OK; +} +/** +* @brief USBD_CtlSendStatus +* send zero lzngth packet on the ctl pipe +* @param pdev: device instance +* @retval status +*/ +USBD_StatusTypeDef USBD_CtlSendStatus (USBD_HandleTypeDef *pdev) +{ + + /* Set EP0 State */ + pdev->ep0_state = USBD_EP0_STATUS_IN; + + /* Start the transfer */ + USBD_LL_Transmit (pdev, 0x00, NULL, 0); + + return USBD_OK; +} + +/** +* @brief USBD_CtlReceiveStatus +* receive zero lzngth packet on the ctl pipe +* @param pdev: device instance +* @retval status +*/ +USBD_StatusTypeDef USBD_CtlReceiveStatus (USBD_HandleTypeDef *pdev) +{ + /* Set EP0 State */ + pdev->ep0_state = USBD_EP0_STATUS_OUT; + + /* Start the transfer */ + USBD_LL_PrepareReceive ( pdev, + 0, + NULL, + 0); + + return USBD_OK; +} + + +/** +* @brief USBD_GetRxCount +* returns the received data length +* @param pdev: device instance +* @param ep_addr: endpoint address +* @retval Rx Data blength +*/ +uint16_t USBD_GetRxCount (USBD_HandleTypeDef *pdev , uint8_t ep_addr) +{ + return USBD_LL_GetRxDataSize(pdev, ep_addr); +} + +/** + * @} + */ + + +/** + * @} + */ + + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/platform/mcu/stm32l475/STM32L475.icf b/platform/mcu/stm32l475/STM32L475.icf new file mode 100644 index 0000000000..32cb683e0d --- /dev/null +++ b/platform/mcu/stm32l475/STM32L475.icf @@ -0,0 +1,77 @@ +/*###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__ = 0x08000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x08000000; +define symbol __ICFEDIT_region_ROM_end__ = 0x080fffff; +define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; +define symbol __ICFEDIT_region_RAM_end__ = 0x20017FFF; +define symbol __ICFEDIT_region_SRAM2_start__ = 0x10000000; +define symbol __ICFEDIT_region_SRAM2_end__ = 0x10007FFF; + +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x2000; +define symbol __ICFEDIT_size_heap__ = 0x10C00; +/**** End of ICF editor section. ###ICF###*/ +define symbol heap_end=__ICFEDIT_region_RAM_end__; +export symbol heap_end; +define symbol heap2_end=__ICFEDIT_region_SRAM2_end__; +export symbol heap2_end; + +define symbol heap_len=__ICFEDIT_size_heap__; +export symbol heap_len; +define symbol heap_start=heap_end - heap_len+1 ; +export symbol heap_start; + +define symbol heap2_start=__ICFEDIT_region_SRAM2_start__; +export symbol heap2_start; +define symbol heap2_len=heap2_end-heap2_start+1; +export symbol heap2_len; + +/*need to check project map to know this value*/ +define symbol __bss_start__= 0x20000830; +export symbol __bss_start__; +define symbol __bss_end__=__ICFEDIT_region_RAM_end__; +export symbol __bss_end__; +define symbol _sdata=__ICFEDIT_region_RAM_start__; +export symbol _sdata; +define symbol _edata= __bss_start__ ; +export symbol _edata; +/* need more HEAP to run with mosquitto and RSA keys 0x7000 (exactly 0x6B6C )instead of 0x5800 with firewall ! */ + +define memory mem with size = 4G; + +/* Definition of the static memory section for TLS certificates, keys, and wifi configuration data at the end of the first bank: + * Provision of 9K , 0x2400 bytes + */ +define symbol __ICFEDIT_region_FIXED_LOC_start__ = 0x08064000; +define region inited_fixed_loc = mem:[from __ICFEDIT_region_FIXED_LOC_start__ size 2K]; +define region uninit_fixed_loc = mem:[from __ICFEDIT_region_FIXED_LOC_start__ + 2K size 8K]; + +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__] - uninit_fixed_loc; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; +define region SRAM2_region = mem:[from __ICFEDIT_region_SRAM2_start__ to __ICFEDIT_region_SRAM2_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 }; + +define exported symbol __firewall_ROM_start = 0x08066D00; +place at address mem:__firewall_ROM_start { readonly section firewall_section }; + + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; + +place in ROM_region { readonly }; +place in RAM_region { block CSTACK, + readwrite, + block HEAP }; + + +place in uninit_fixed_loc { readonly section UNINIT_FIXED_LOC }; +place in inited_fixed_loc { readonly section INITED_FIXED_LOC }; diff --git a/platform/mcu/stm32l475/src/B-L475E-IOT01/hal/flash_l4.c b/platform/mcu/stm32l475/src/B-L475E-IOT01/hal/flash_l4.c index 8297db2a8f..920972bb1e 100644 --- a/platform/mcu/stm32l475/src/B-L475E-IOT01/hal/flash_l4.c +++ b/platform/mcu/stm32l475/src/B-L475E-IOT01/hal/flash_l4.c @@ -52,8 +52,7 @@ #include #include "stm32l4xx.h" #include "stm32l4xx_hal_flash.h" - - +#include /* Private typedef -----------------------------------------------------------*/ /* Private defines -----------------------------------------------------------*/ #define ROUND_DOWN(a,b) (((a) / (b)) * (b)) @@ -209,6 +208,7 @@ int FLASH_get_pageInBank(uint32_t addr) return page; } + /** * @brief Update a chunk of the FLASH memory. * @note The FLASH chunk must no cross a FLASH bank boundary. @@ -224,8 +224,13 @@ int FLASH_update(uint32_t dst_addr, const void *data, uint32_t size) int ret = 0; int remaining = size; uint8_t * src_addr = (uint8_t *) data; - uint64_t page_cache[FLASH_PAGE_SIZE/sizeof(uint64_t)]; - + + uint64_t * page_cache = NULL; + page_cache = (uint64_t *)aos_malloc(FLASH_PAGE_SIZE); + if (page_cache == NULL) + return -1; + memset(page_cache, 0, FLASH_PAGE_SIZE); + __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS); do { @@ -259,6 +264,7 @@ int FLASH_update(uint32_t dst_addr, const void *data, uint32_t size) } } while ((ret == 0) && (remaining > 0)); + aos_free(page_cache); return ret; } diff --git a/platform/mcu/stm32l475/src/B-L475E-IOT01/hal/hal_i2c_stm32l4.c b/platform/mcu/stm32l475/src/B-L475E-IOT01/hal/hal_i2c_stm32l4.c index 6ab19fd6ff..4d98592054 100644 --- a/platform/mcu/stm32l475/src/B-L475E-IOT01/hal/hal_i2c_stm32l4.c +++ b/platform/mcu/stm32l475/src/B-L475E-IOT01/hal/hal_i2c_stm32l4.c @@ -33,10 +33,12 @@ int32_t hal_i2c_init(i2c_dev_t *i2c) I2C1_Init(); i2c->priv = &I2c1Handle; ret = 0; + break; case AOS_PORT_I2C2: I2C2_Init(); i2c->priv = &I2c2Handle; ret = 0; + break; default: break; } @@ -44,12 +46,61 @@ int32_t hal_i2c_init(i2c_dev_t *i2c) return ret; } +int32_t hal_i2c_master_send(i2c_dev_t *i2c, uint16_t dev_addr, const uint8_t *data, + uint16_t size, uint32_t timeout) +{ + int ret = -1; + + if ((i2c != NULL) && (data != NULL)) { + ret = HAL_I2C_Master_Transmit((I2C_HandleTypeDef*)(i2c->priv), dev_addr, + (uint8_t *)data, size, timeout); + } + + return ret; +} + +int32_t hal_i2c_master_recv(i2c_dev_t *i2c, uint16_t dev_addr, uint8_t *data, + uint16_t size, uint32_t timeout) +{ + int ret = -1; + + if ((i2c != NULL) && (data != NULL)) { + ret = HAL_I2C_Master_Receive((I2C_HandleTypeDef*)(i2c->priv), dev_addr, + data, size, timeout); + } + + return ret; +} + +int32_t hal_i2c_slave_send(i2c_dev_t *i2c, const uint8_t *data, uint16_t size, uint32_t timeout) +{ + int ret = -1; + + if ((i2c != NULL) && (data != NULL)) { + ret = HAL_I2C_Slave_Transmit((I2C_HandleTypeDef*)(i2c->priv), (uint8_t *)data, + size, timeout); + } + + return ret; +} + +int32_t hal_i2c_slave_recv(i2c_dev_t *i2c, uint8_t *data, uint16_t size, uint32_t timeout) +{ + int ret = -1; + + if ((i2c != NULL) && (data != NULL)) { + ret = HAL_I2C_Slave_Receive((I2C_HandleTypeDef*)(i2c->priv), data, size, timeout); + } + + return ret; +} + int32_t hal_i2c_mem_write(i2c_dev_t *i2c, uint16_t dev_addr, uint16_t mem_addr, uint16_t mem_addr_size, const uint8_t *data, uint16_t size, uint32_t timeout) { int ret = -1; - + if ((i2c != NULL) && (data != NULL)) { ret = HAL_I2C_Mem_Write((I2C_HandleTypeDef*)(i2c->priv), dev_addr, mem_addr, (uint16_t)mem_addr_size, (uint8_t *)data, size, timeout); @@ -64,7 +115,7 @@ int32_t hal_i2c_mem_read(i2c_dev_t *i2c, uint16_t dev_addr, uint16_t mem_addr, uint32_t timeout) { int ret = -1; - + if ((i2c != NULL) && (data != NULL)) { ret = HAL_I2C_Mem_Read((I2C_HandleTypeDef*)(i2c->priv), dev_addr, mem_addr, (uint16_t)mem_addr_size, data, size, timeout); @@ -85,9 +136,11 @@ int32_t hal_i2c_finalize(i2c_dev_t *i2c) case AOS_PORT_I2C1: I2C1_DeInit(); ret = 0; + break; case AOS_PORT_I2C2: I2C2_DeInit(); ret = 0; + break; default: break; } diff --git a/platform/mcu/stm32l475/src/B-L475E-IOT01/hal/hw.c b/platform/mcu/stm32l475/src/B-L475E-IOT01/hal/hw.c index 70d90e77cf..0d3509b6a4 100644 --- a/platform/mcu/stm32l475/src/B-L475E-IOT01/hal/hw.c +++ b/platform/mcu/stm32l475/src/B-L475E-IOT01/hal/hw.c @@ -13,14 +13,15 @@ #include #include #include +#include "stm32_wifi.h" #include "stm32l4xx_hal_cortex.h" #define TAG "hw" +#define WIFI_PRODUCT_INFO_SIZE ES_WIFI_MAX_SSID_NAME_SIZE #define us2tick(us) \ ((us * RHINO_CONFIG_TICKS_PER_SECOND + 999999) / 1000000) -uart_dev_t uart_0; void hal_reboot(void) { @@ -29,44 +30,50 @@ void hal_reboot(void) static void _timer_cb(void *timer, void *arg) { - hal_timer_t *tmr = arg; - tmr->cb(tmr->arg); + timer_dev_t *tmr = arg; + tmr->config.cb(tmr->config.arg); } -void hal_timer_init(hal_timer_t *tmr, unsigned int period, unsigned char auto_reload, unsigned char ch, hal_timer_cb_t cb, void *arg) +int32_t hal_timer_init(timer_dev_t *tim) { - (void)ch; - memset(tmr, 0, sizeof(*tmr)); - tmr->cb = cb; - tmr->arg = arg; - if (auto_reload > 0u) { - krhino_timer_dyn_create((ktimer_t **)&tmr->priv, "hwtmr", _timer_cb, - us2tick(period), us2tick(period), tmr, 0); + if (tim->config.reload_mode == TIMER_RELOAD_AUTO) { + krhino_timer_dyn_create((ktimer_t **)&tim->priv, "hwtmr", _timer_cb, + us2tick(tim->config.period), us2tick(tim->config.period), tim, 0); } else { - krhino_timer_dyn_create((ktimer_t **)&tmr->priv, "hwtmr", _timer_cb, - us2tick(period), 0, tmr, 0); + krhino_timer_dyn_create((ktimer_t **)&tim->priv, "hwtmr", _timer_cb, + us2tick(tim->config.period), 0, tim, 0); } } -int32_t hal_timer_start(hal_timer_t *tmr) +int32_t hal_timer_start(timer_dev_t *tmr) { return krhino_timer_start(tmr->priv); } -void hal_timer_stop(hal_timer_t *tmr) +void hal_timer_stop(timer_dev_t *tmr) { krhino_timer_stop(tmr->priv); krhino_timer_dyn_del(tmr->priv); tmr->priv = NULL; } -extern hal_wifi_module_t sim_aos_wifi_stm23l475; +#if defined(DEV_SAL_MK3060) + extern hal_wifi_module_t aos_wifi_module_mk3060; +#else + extern hal_wifi_module_t sim_aos_wifi_stm32l475; +#endif + extern struct hal_ota_module_s stm32l475_ota_module; void hw_start_hal(void) { printf("start-----------hal\n"); - hal_wifi_register_module(&sim_aos_wifi_stm23l475); +#if defined(DEV_SAL_MK3060) + hal_wifi_register_module(&aos_wifi_module_mk3060); +#else + hal_wifi_register_module(&sim_aos_wifi_stm32l475); +#endif hal_ota_register_module(&stm32l475_ota_module); + hal_wifi_init(); } diff --git a/platform/mcu/stm32l475/src/B-L475E-IOT01/hal/wifi_port.c b/platform/mcu/stm32l475/src/B-L475E-IOT01/hal/wifi_port.c old mode 100644 new mode 100755 index 1352c99d77..216229facb --- a/platform/mcu/stm32l475/src/B-L475E-IOT01/hal/wifi_port.c +++ b/platform/mcu/stm32l475/src/B-L475E-IOT01/hal/wifi_port.c @@ -9,19 +9,53 @@ #include #include "stm32_wifi.h" +#define WIFI_PRODUCT_INFO_SIZE ES_WIFI_MAX_SSID_NAME_SIZE #define WIFI_CONNECT_MAX_ATTEMPT_COUNT 3 -hal_wifi_module_t sim_aos_wifi_stm23l475; +hal_wifi_module_t sim_aos_wifi_stm32l475; void NetCallback(hal_wifi_ip_stat_t *pnet); void WifiStatusHandler(int status); static int wifi_init(hal_wifi_module_t *m) { + /* init wifi*/ + char moduleinfo[WIFI_PRODUCT_INFO_SIZE]; + uint8_t mac[6]; + WIFI_Status_t wifi_res = WIFI_Init(); + if (WIFI_STATUS_OK != wifi_res ) + { + printf("Failed to initialize WIFI module\n"); + return -1; + } + /* Retrieve the WiFi module mac address to confirm that it is detected and communicating. */ + WIFI_GetModuleName(moduleinfo); + printf("Module initialized successfully: %s",moduleinfo); + + WIFI_GetModuleID(moduleinfo); + printf(" %s",moduleinfo); + + WIFI_GetModuleFwRevision(moduleinfo); + printf(" %s\n",moduleinfo); + + printf("Retrieving the WiFi module MAC address:"); + wifi_res = WIFI_GetMAC_Address( (uint8_t*)mac); + if ( WIFI_STATUS_OK == wifi_res) + { + printf(" %02x:%02x:%02x:%02x:%02x:%02x\n", + mac[0], mac[1], mac[2], + mac[3], mac[4], mac[5]); + } + else + { + printf("Failed to get MAC address\n"); + } + printf("wifi init success!!\n"); return 0; }; + static void wifi_get_mac_addr(hal_wifi_module_t *m, uint8_t *mac) { WIFI_Status_t wifi_res = WIFI_GetMAC_Address(mac); @@ -165,32 +199,32 @@ static int wlan_send_80211_raw_frame(hal_wifi_module_t *m, uint8_t *buf, int len void NetCallback(hal_wifi_ip_stat_t *pnet) { - if (sim_aos_wifi_stm23l475.ev_cb == NULL) + if (sim_aos_wifi_stm32l475.ev_cb == NULL) return; - if (sim_aos_wifi_stm23l475.ev_cb->ip_got == NULL) + if (sim_aos_wifi_stm32l475.ev_cb->ip_got == NULL) return; - sim_aos_wifi_stm23l475.ev_cb->ip_got(&sim_aos_wifi_stm23l475, pnet, NULL); + sim_aos_wifi_stm32l475.ev_cb->ip_got(&sim_aos_wifi_stm32l475, pnet, NULL); } void connected_ap_info(hal_wifi_ap_info_adv_t *ap_info, char *key, int key_len) { - if (sim_aos_wifi_stm23l475.ev_cb == NULL) + if (sim_aos_wifi_stm32l475.ev_cb == NULL) return; - if (sim_aos_wifi_stm23l475.ev_cb->para_chg == NULL) + if (sim_aos_wifi_stm32l475.ev_cb->para_chg == NULL) return; - sim_aos_wifi_stm23l475.ev_cb->para_chg(&sim_aos_wifi_stm23l475, ap_info, key, key_len, NULL); + sim_aos_wifi_stm32l475.ev_cb->para_chg(&sim_aos_wifi_stm32l475, ap_info, key, key_len, NULL); } void WifiStatusHandler(int status) { - if (sim_aos_wifi_stm23l475.ev_cb == NULL) + if (sim_aos_wifi_stm32l475.ev_cb == NULL) return; - if (sim_aos_wifi_stm23l475.ev_cb->stat_chg == NULL) + if (sim_aos_wifi_stm32l475.ev_cb->stat_chg == NULL) return; - sim_aos_wifi_stm23l475.ev_cb->stat_chg(&sim_aos_wifi_stm23l475, (hal_wifi_event_t)status, NULL); + sim_aos_wifi_stm32l475.ev_cb->stat_chg(&sim_aos_wifi_stm32l475, (hal_wifi_event_t)status, NULL); } void ApListCallback(hal_wifi_scan_result_t *pApList) @@ -201,28 +235,28 @@ void ApListCallback(hal_wifi_scan_result_t *pApList) for(i=0; iap_num; i++) { printf("\t %s rssi %d\r\n", pApList->ap_list[i].ssid, pApList->ap_list[i].ap_power); } - if (sim_aos_wifi_stm23l475.ev_cb == NULL) + if (sim_aos_wifi_stm32l475.ev_cb == NULL) return; - if (sim_aos_wifi_stm23l475.ev_cb->scan_compeleted == NULL) + if (sim_aos_wifi_stm32l475.ev_cb->scan_compeleted == NULL) return; - sim_aos_wifi_stm23l475.ev_cb->scan_compeleted(&sim_aos_wifi_stm23l475, + sim_aos_wifi_stm32l475.ev_cb->scan_compeleted(&sim_aos_wifi_stm32l475, (hal_wifi_scan_result_t*)pApList, NULL); } void ApListAdvCallback(hal_wifi_scan_result_adv_t *pApAdvList) { - if (sim_aos_wifi_stm23l475.ev_cb == NULL) + if (sim_aos_wifi_stm32l475.ev_cb == NULL) return; - if (sim_aos_wifi_stm23l475.ev_cb->scan_adv_compeleted == NULL) + if (sim_aos_wifi_stm32l475.ev_cb->scan_adv_compeleted == NULL) return; - sim_aos_wifi_stm23l475.ev_cb->scan_adv_compeleted(&sim_aos_wifi_stm23l475, + sim_aos_wifi_stm32l475.ev_cb->scan_adv_compeleted(&sim_aos_wifi_stm32l475, pApAdvList, NULL); } -hal_wifi_module_t sim_aos_wifi_stm23l475 = { - .base.name = "sim_aos_wifi_stm23l475", +hal_wifi_module_t sim_aos_wifi_stm32l475 = { + .base.name = "sim_aos_wifi_stm32l475", .init = wifi_init, .get_mac_addr = wifi_get_mac_addr, .start = wifi_start, diff --git a/platform/mcu/stm32l475/src/B-L475E-IOT01/runapp/aos.c b/platform/mcu/stm32l475/src/B-L475E-IOT01/runapp/aos.c index c59ee8ad10..fe2d540b14 100644 --- a/platform/mcu/stm32l475/src/B-L475E-IOT01/runapp/aos.c +++ b/platform/mcu/stm32l475/src/B-L475E-IOT01/runapp/aos.c @@ -21,47 +21,6 @@ extern int application_start(int argc, char **argv); extern int aos_framework_init(void); extern void board_init(void); -static int init_wifi() -{ - /* init wifi*/ - char moduleinfo[WIFI_PRODUCT_INFO_SIZE]; - uint8_t mac[6]; - WIFI_Status_t wifi_res = WIFI_Init(); - if (WIFI_STATUS_OK != wifi_res ) - { - printf("Failed to initialize WIFI module\n"); - return -1; - } - /* Retrieve the WiFi module mac address to confirm that it is detected and communicating. */ - WIFI_GetModuleName(moduleinfo); - printf("Module initialized successfully: %s",moduleinfo); - - WIFI_GetModuleID(moduleinfo); - printf(" %s",moduleinfo); - - WIFI_GetModuleFwRevision(moduleinfo); - printf(" %s\n",moduleinfo); - - printf("Retrieving the WiFi module MAC address:"); - wifi_res = WIFI_GetMAC_Address( (uint8_t*)mac); - if ( WIFI_STATUS_OK == wifi_res) - { - printf(" %02x:%02x:%02x:%02x:%02x:%02x\n", - mac[0], mac[1], mac[2], - mac[3], mac[4], mac[5]); - } - else - { - printf("Failed to get MAC address\n"); - } - return 0; -} - -static void hal_init() -{ - init_wifi(); -} - static void var_init() { kinit.argc = 0; @@ -79,7 +38,6 @@ static void sys_init(void) #ifdef BOOTLOADER main(); #else - hal_init(); hw_start_hal(); board_init(); var_init(); diff --git a/platform/mcu/stm32l475/src/B-L475E-IOT01/runapp/soc_init.c b/platform/mcu/stm32l475/src/B-L475E-IOT01/runapp/soc_init.c index 69fd4cbb97..d00eff92a2 100644 --- a/platform/mcu/stm32l475/src/B-L475E-IOT01/runapp/soc_init.c +++ b/platform/mcu/stm32l475/src/B-L475E-IOT01/runapp/soc_init.c @@ -46,10 +46,11 @@ */ /* Includes ------------------------------------------------------------------*/ +#include "board.h" #include "soc_init.h" #include "hal/soc/uart.h" #include "aos/kernel.h" -#include "k_types.h" +#include "k_api.h" #include "errno.h" #if defined(__ICCARM__) @@ -68,15 +69,18 @@ static volatile uint8_t button_flags = 0; stm32_uart_t stm32_uart[COMn]; +uart_dev_t uart_0; + static uart_dev_t console_uart={ - .port=COM1, + .port=STDIO_UART, }; /* Private function prototypes -----------------------------------------------*/ static void SystemClock_Config(void); //static void Console_UART_Init(void); -static int UART_Init(COM_TypeDef com); +static int UART_Init(uart_dev_t *uart); static void RTC_Init(void); static void Button_ISR(void); +static int default_UART_Init(); /* Private functions ---------------------------------------------------------*/ @@ -107,9 +111,8 @@ void stm32_soc_init(void) /* RTC init */ RTC_Init(); /* UART console init */ - //Console_UART_Init(); - UART_Init(COM1); - UART_Init(COM4); + default_UART_Init(); + } /** @@ -239,37 +242,106 @@ uint8_t Button_WaitForPush(uint32_t delay) return BP_NOT_PUSHED; } +/* bufferQueue for uart */ +#define MAX_BUF_UART_BYTES 1000 -static int UART_Init(COM_TypeDef com) +kbuf_queue_t g_buf_queue_uart[COMn]; +char g_buf_uart[COMn][MAX_BUF_UART_BYTES]; +const char *g_pc_buf_queue_name[COMn] = {"buf_queue_uart0", "buf_queue_uart4"}; + +static int UART_Init(uart_dev_t *uart) { - switch(com){ - case COM1: - stm32_uart[com].handle.Instance = USART1; - break; - case COM4: - stm32_uart[com].handle.Instance = UART4; - break; - default: - return -1; - } - stm32_uart[com].handle.Init.BaudRate = 115200; - stm32_uart[com].handle.Init.WordLength = UART_WORDLENGTH_8B; - stm32_uart[com].handle.Init.StopBits = UART_STOPBITS_1; - stm32_uart[com].handle.Init.Parity = UART_PARITY_NONE; - stm32_uart[com].handle.Init.Mode = UART_MODE_TX_RX; - stm32_uart[com].handle.Init.HwFlowCtl = UART_HWCONTROL_NONE; - stm32_uart[com].handle.Init.OverSampling = UART_OVERSAMPLING_16; - stm32_uart[com].handle.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; - stm32_uart[com].handle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; - BSP_COM_Init(com,&stm32_uart[com].handle); - aos_mutex_new(&stm32_uart[com].uart_tx_mutex); - aos_mutex_new(&stm32_uart[com].uart_rx_mutex); - aos_sem_new(&stm32_uart[com].uart_tx_sem, 0); - aos_sem_new(&stm32_uart[com].uart_rx_sem, 0); - return 0; + + switch(uart->port){ + case COM1: + stm32_uart[uart->port].handle.Instance = USART1; + break; + case COM4: + stm32_uart[uart->port].handle.Instance = UART4; + break; + default: + return -1; + } + + switch(uart->config.data_width){ + case DATA_WIDTH_7BIT: + stm32_uart[uart->port].handle.Init.WordLength = UART_WORDLENGTH_7B; + break; + case DATA_WIDTH_8BIT: + stm32_uart[uart->port].handle.Init.WordLength = UART_WORDLENGTH_8B; + break; + case DATA_WIDTH_9BIT: + stm32_uart[uart->port].handle.Init.WordLength = UART_WORDLENGTH_9B; + break; + case DATA_WIDTH_5BIT: + case DATA_WIDTH_6BIT: + default: + return -1; + } + + switch(uart->config.stop_bits){ + case STOP_BITS_1: + stm32_uart[uart->port].handle.Init.StopBits = UART_STOPBITS_1; + break; + case STOP_BITS_2: + stm32_uart[uart->port].handle.Init.StopBits = UART_STOPBITS_2; + break; + default: + return -1; + } + + switch(uart->config.parity){ + case NO_PARITY: + stm32_uart[uart->port].handle.Init.Parity = UART_PARITY_NONE; + break; + case ODD_PARITY: + stm32_uart[uart->port].handle.Init.Parity = UART_PARITY_ODD; + break; + case EVEN_PARITY: + stm32_uart[uart->port].handle.Init.Parity = UART_PARITY_EVEN; + break; + default: + return -1; + } + + switch(uart->config.flow_control){ + case FLOW_CONTROL_DISABLED: + stm32_uart[uart->port].handle.Init.HwFlowCtl = UART_HWCONTROL_NONE; + break; + case FLOW_CONTROL_CTS: + stm32_uart[uart->port].handle.Init.HwFlowCtl = UART_HWCONTROL_CTS; + break; + case FLOW_CONTROL_RTS: + stm32_uart[uart->port].handle.Init.HwFlowCtl = UART_HWCONTROL_RTS; + break; + case FLOW_CONTROL_CTS_RTS: + stm32_uart[uart->port].handle.Init.HwFlowCtl = UART_HWCONTROL_RTS_CTS; + break; + default: + return -1; + } + + stm32_uart[uart->port].handle.Init.BaudRate = uart->config.baud_rate; + stm32_uart[uart->port].handle.Init.Mode = UART_MODE_TX_RX; + stm32_uart[uart->port].handle.Init.OverSampling = UART_OVERSAMPLING_16; + stm32_uart[uart->port].handle.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; + stm32_uart[uart->port].handle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; + + if(krhino_buf_queue_create(&g_buf_queue_uart[uart->port], g_pc_buf_queue_name[uart->port], g_buf_uart[uart->port], MAX_BUF_UART_BYTES, 1) != 0){ + return -2; + } + + stm32_uart[uart->port].handle.buffer_queue = &g_buf_queue_uart[uart->port]; + BSP_COM_Init(uart->port,&stm32_uart[uart->port].handle); + aos_mutex_new(&stm32_uart[uart->port].uart_tx_mutex); + aos_mutex_new(&stm32_uart[uart->port].uart_rx_mutex); + aos_sem_new(&stm32_uart[uart->port].uart_tx_sem, 0); + aos_sem_new(&stm32_uart[uart->port].uart_rx_sem, 0); + return 0; } + #if defined (__CC_ARM) && defined(__MICROLIB) #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) #define GETCHAR_PROTOTYPE int fgetc(FILE *f) @@ -314,7 +386,6 @@ GETCHAR_PROTOTYPE int32_t hal_uart_send(uart_dev_t *uart, const void *data, uint32_t size, uint32_t timeout) { HAL_UART_StateTypeDef state = HAL_UART_STATE_BUSY_TX; - int ret; if(uart==NULL||data==NULL) { return -EINVAL; } @@ -338,39 +409,42 @@ int32_t hal_uart_send(uart_dev_t *uart, const void *data, uint32_t size, uint32_ aos_mutex_unlock(&stm32_uart[uart->port].uart_tx_mutex); - return size; + return 0; } -int32_t hal_uart_recv(uart_dev_t *uart, void *data, uint32_t expect_size, uint32_t *recv_size, uint32_t timeout) { - HAL_UART_StateTypeDef state = HAL_UART_STATE_BUSY_RX; - int ret; - if(uart==NULL||data==NULL) { - return -EINVAL; - } - if(uart->port>COMn-1) { - return -EINVAL; - } - aos_mutex_lock(&stm32_uart[uart->port].uart_rx_mutex, RHINO_WAIT_FOREVER); +int32_t hal_uart_recv(uart_dev_t *uart, void *data, uint32_t expect_size, uint32_t *recv_size, uint32_t timeout) +{ + uint8_t *pdata = (uint8_t *)data; + int i = 0; + uint32_t rx_count = 0; + int32_t ret = -1; - if (recv_size != NULL) { - *recv_size = expect_size; + if ((uart == NULL) || (data == NULL)) { + return -1; } - if (stm32_uart[uart->port].handle.RxState != HAL_UART_STATE_READY) { - aos_sem_wait(&stm32_uart[uart->port].uart_rx_sem, timeout); - } else { - state = HAL_UART_STATE_READY; + aos_mutex_lock(&stm32_uart[uart->port].uart_rx_mutex, RHINO_WAIT_FOREVER); + + for (i = 0; i < expect_size; i++) + { + ret = HAL_UART_Receive_IT_Buf_Queue_1byte(&stm32_uart[uart->port].handle, &pdata[i], timeout); + if (ret == 0) { + rx_count++; + } else { + break; + } } - ret = HAL_UART_Receive_IT(&stm32_uart[uart->port].handle, (uint8_t *)data, expect_size); - // if (HAL_UART_Receive_IT(&stm32_uart[uart->port].handle, (uint8_t *)data, expect_size) != HAL_OK) { - // Error_Handler(); - // } + *recv_size = rx_count; - if (HAL_UART_STATE_READY == state) { - aos_sem_wait(&stm32_uart[uart->port].uart_rx_sem, timeout); + if(rx_count != 0) + { + ret = 0; + } + else + { + ret = -1; } - aos_mutex_unlock(&stm32_uart[uart->port].uart_rx_mutex); return ret; @@ -480,24 +554,43 @@ void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) */ void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { + return; +#if 0 for(int i=0;iport==COM1||uart->port==COM4){ - return 0; + + if(uart->port != COM1 && uart->port != COM4){ + return -EINVAL; } - return -EINVAL; + + return UART_Init(uart); } int32_t hal_uart_finalize(uart_dev_t *uart) diff --git a/platform/mcu/stm32l475/src/B-L475E-IOT01/runapp/stm32l4xx_hal_conf.h b/platform/mcu/stm32l475/src/B-L475E-IOT01/runapp/stm32l4xx_hal_conf.h index 4d3cee3720..4e531f9a3f 100644 --- a/platform/mcu/stm32l475/src/B-L475E-IOT01/runapp/stm32l4xx_hal_conf.h +++ b/platform/mcu/stm32l475/src/B-L475E-IOT01/runapp/stm32l4xx_hal_conf.h @@ -81,7 +81,7 @@ /*#define HAL_NAND_MODULE_ENABLED */ /*#define HAL_NOR_MODULE_ENABLED */ /*#define HAL_OPAMP_MODULE_ENABLED */ -/*#define HAL_PCD_MODULE_ENABLED */ +#define HAL_PCD_MODULE_ENABLED /*#define HAL_QSPI_MODULE_ENABLED */ #define HAL_QSPI_MODULE_ENABLED #define HAL_RNG_MODULE_ENABLED diff --git a/platform/mcu/stm32l475/src/B-L475E-IOT01/runapp/stm32l4xx_it.c b/platform/mcu/stm32l475/src/B-L475E-IOT01/runapp/stm32l4xx_it.c index 5a125d828c..f075e2bd47 100644 --- a/platform/mcu/stm32l475/src/B-L475E-IOT01/runapp/stm32l4xx_it.c +++ b/platform/mcu/stm32l475/src/B-L475E-IOT01/runapp/stm32l4xx_it.c @@ -177,7 +177,7 @@ void SPI3_IRQHandler(void) void USART1_IRQHandler(void) { krhino_intrpt_enter(); - HAL_UART_IRQHandler(&stm32_uart[COM1].handle); + HAL_UART_IRQHandler_Buf_Queue(&stm32_uart[COM1].handle); krhino_intrpt_exit(); } @@ -189,7 +189,7 @@ void USART1_IRQHandler(void) void UART4_IRQHandler(void) { krhino_intrpt_enter(); - HAL_UART_IRQHandler(&stm32_uart[COM4].handle); + HAL_UART_IRQHandler_Buf_Queue(&stm32_uart[COM4].handle); krhino_intrpt_exit(); } /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/platform/mcu/stm32l475/src/B-L475E-IOT01/runapp/usbd_conf.h b/platform/mcu/stm32l475/src/B-L475E-IOT01/runapp/usbd_conf.h new file mode 100644 index 0000000000..81db225545 --- /dev/null +++ b/platform/mcu/stm32l475/src/B-L475E-IOT01/runapp/usbd_conf.h @@ -0,0 +1,102 @@ +/** + ****************************************************************************** + * @file USB_Device/HID_Standalone/Inc/usbd_conf.h + * @author MCD Application Team + * @brief General low level driver configuration + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics International N.V. + * All rights reserved.

+ * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted, provided that the following conditions are met: + * + * 1. Redistribution 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 STMicroelectronics nor the names of other + * contributors to this software may be used to endorse or promote products + * derived from this software without specific written permission. + * 4. This software, including modifications and/or derivative works of this + * software, must execute solely and exclusively on microcontroller or + * microprocessor devices manufactured by or for STMicroelectronics. + * 5. Redistribution and use of this software other than as permitted under + * this license is void and will automatically terminate your rights under + * this license. + * + * THIS SOFTWARE IS PROVIDED BY STMICROELECTRONICS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS, IMPLIED OR STATUTORY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A + * PARTICULAR PURPOSE AND NON-INFRINGEMENT OF THIRD PARTY INTELLECTUAL PROPERTY + * RIGHTS ARE DISCLAIMED TO THE FULLEST EXTENT PERMITTED BY LAW. IN NO EVENT + * SHALL STMICROELECTRONICS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __USBD_CONF_H +#define __USBD_CONF_H + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l4xx_hal.h" +#include +#include +#include + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Common Config */ +#define USBD_MAX_NUM_INTERFACES 1 +#define USBD_MAX_NUM_CONFIGURATION 1 +#define USBD_MAX_STR_DESC_SIZ 0x100 +#define USBD_SUPPORT_USER_STRING 0 +#define USBD_SELF_POWERED 1 +#define USBD_DEBUG_LEVEL 3 + +/* Exported macro ------------------------------------------------------------*/ +/* Memory management macros */ +#define USBD_malloc malloc +#define USBD_free free +#define USBD_memset memset +#define USBD_memcpy memcpy + +/* DEBUG macros */ +#if (USBD_DEBUG_LEVEL > 0) +#define USBD_UsrLog(...) printf(__VA_ARGS__);\ + printf("\n"); +#else +#define USBD_UsrLog(...) +#endif + +#if (USBD_DEBUG_LEVEL > 1) + +#define USBD_ErrLog(...) printf("ERROR: ") ;\ + printf(__VA_ARGS__);\ + printf("\n"); +#else +#define USBD_ErrLog(...) +#endif + +#if (USBD_DEBUG_LEVEL > 2) +#define USBD_DbgLog(...) printf("DEBUG : ") ;\ + printf(__VA_ARGS__);\ + printf("\n"); +#else +#define USBD_DbgLog(...) +#endif + +/* Exported functions ------------------------------------------------------- */ + +#endif /* __USBD_CONF_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/platform/mcu/stm32l475/src/common/csp/wifi/src/es_wifi_io.c b/platform/mcu/stm32l475/src/common/csp/wifi/src/es_wifi_io.c index 6884cf6745..c6a0fce47d 100644 --- a/platform/mcu/stm32l475/src/common/csp/wifi/src/es_wifi_io.c +++ b/platform/mcu/stm32l475/src/common/csp/wifi/src/es_wifi_io.c @@ -51,7 +51,7 @@ #include "es_wifi_io.h" #include #include "aos/kernel.h" -#include "k_types.h" +#include "k_api.h" #include "es_wifi_conf.h" /* Private define ------------------------------------------------------------*/ diff --git a/platform/mcu/stm32l475/stm32l475.mk b/platform/mcu/stm32l475/stm32l475.mk index de6433f2c2..7aa642c9eb 100644 --- a/platform/mcu/stm32l475/stm32l475.mk +++ b/platform/mcu/stm32l475/stm32l475.mk @@ -1,24 +1,17 @@ -# -# UNPUBLISHED PROPRIETARY SOURCE CODE -# Copyright (c) 2016 MXCHIP Inc. -# -# The contents of this file may not be disclosed to third parties, copied or -# duplicated in any form, in whole or in part, without the prior written -# permission of MXCHIP Corporation. -# NAME := stm32l475 HOST_OPENOCD := stm32l475 +ifeq (, $(findstring sal, $(BUILD_STRING))) STM32_NONSTD_SOCKET := true +GLOBAL_DEFINES += STM32_USE_SPI_WIFI +endif $(NAME)_TYPE := kernel $(NAME)_COMPONENTS += platform/arch/arm/armv7m -$(NAME)_COMPONENTS += libc rhino hal netmgr framework.common mbedtls cjson cli digest_algorithm - -GLOBAL_DEFINES += STM32_USE_SPI_WIFI +$(NAME)_COMPONENTS += libc rhino hal modules.fs.kv vfs digest_algorithm GLOBAL_DEFINES += CONFIG_AOS_KV_MULTIPTN_MODE GLOBAL_DEFINES += CONFIG_AOS_KV_PTN=6 @@ -29,11 +22,12 @@ GLOBAL_DEFINES += CONFIG_AOS_KV_BUFFER_SIZE=8192 GLOBAL_INCLUDES += ../../arch/arm/armv7m/gcc/m4 GLOBAL_INCLUDES += \ + src/common/csp/lwip/include \ src/common/csp/wifi/inc \ - src/B-L475E-IOT01/include \ + src/B-L475E-IOT01/include \ src/B-L475E-IOT01/runapp \ Drivers/STM32L4xx_HAL_Driver/Inc \ - Drivers/STM32L4xx_HAL_Driver/Inc/Legacy \ + Drivers/STM32L4xx_HAL_Driver/Inc/Legacy \ Drivers/BSP/B-L475E-IOT01 \ Drivers/BSP/Components/es_wifi \ Drivers/BSP/Components/hts221 \ @@ -42,13 +36,17 @@ GLOBAL_INCLUDES += \ Drivers/BSP/Components/lsm6dsl \ Drivers/BSP/Components/vl53l0x \ Drivers/CMSIS/Include \ - ../../../include/hal - + ../../../include/hal \ + Middlewares/USB_Device/Core/Inc GLOBAL_CFLAGS += -DSTM32L475xx ifeq ($(COMPILER),armcc) -GLOBAL_CFLAGS += --c99 -c --cpu Cortex-M4.fp -D__MICROLIB -g --apcs=interwork --split_sections +GLOBAL_CFLAGS += --c99 --cpu=7E-M -D__MICROLIB -g --apcs=interwork --split_sections +else ifeq ($(COMPILER),iar) +GLOBAL_CFLAGS += --cpu=Cortex-M4 \ + --cpu_mode=thumb \ + --endian=little else GLOBAL_CFLAGS += -mcpu=cortex-m4 \ -march=armv7-m \ @@ -58,16 +56,27 @@ GLOBAL_CFLAGS += -mcpu=cortex-m4 \ endif ifeq ($(COMPILER),armcc) -GLOBAL_LDFLAGS += --cpu Cortex-M4.fp \ - --littleend \ - --branchpatch=sdcomp-29491-629360 \ - *.o \ - --library_type=microlib \ - --strict \ - --scatter "platform\mcu\stm32l4xx\B-L475E-IOT01.sct" \ - --summary_stderr \ - --info summarysizes --xref --callgraph --symbols \ - --info sizes --info totals --info unused --info veneers +GLOBAL_ASMFLAGS += --cpu=7E-M -g --apcs=interwork --pd "__MICROLIB SETA 1" --pd "STM32L475xx SETA 1" +else ifeq ($(COMPILER),iar) +GLOBAL_ASMFLAGS += --cpu Cortex-M4 \ + --cpu_mode thumb \ + --endian little +else +GLOBAL_ASMFLAGS += -mcpu=cortex-m4 \ + -march=armv7-m \ + -mlittle-endian \ + -mthumb -mthumb-interwork \ + -w +endif + +ifeq ($(COMPILER),armcc) +GLOBAL_LDFLAGS += -L --cpu=7E-M \ + -L --strict \ + -L --xref -L --callgraph -L --symbols \ + -L --info=sizes -L --info=totals -L --info=unused -L --info=veneers -L --info=summarysizes +else ifeq ($(COMPILER),iar) +GLOBAL_LDFLAGS += --silent --cpu=Cortex-M4.vfp + else GLOBAL_LDFLAGS += -mcpu=cortex-m4 \ -mlittle-endian \ @@ -77,8 +86,13 @@ GLOBAL_LDFLAGS += -mcpu=cortex-m4 \ $(CLIB_LDFLAGS_NANO_FLOAT) endif - +ifeq ($(COMPILER),armcc) +GLOBAL_LDFLAGS += -L --scatter=platform/mcu/stm32l475/B-L475E-IOT01.sct +else ifeq ($(COMPILER),iar) +GLOBAL_LDFLAGS += --config platform/mcu/stm32l475/STM32L475.icf +else GLOBAL_LDFLAGS += -T platform/mcu/stm32l475/STM32L475VGTx_FLASH.ld +endif $(NAME)_SOURCES := src/B-L475E-IOT01/runapp/stm32l4xx_hal_msp.c \ src/B-L475E-IOT01/runapp/stm32l4xx_it.c \ @@ -130,7 +144,6 @@ $(NAME)_SOURCES := src/B-L475E-IOT01/runapp/stm32l4xx_hal_msp.c \ src/common/csp/wifi/src/es_wifi_io.c \ src/common/csp/wifi/src/wifi.c \ src/B-L475E-IOT01/hal/hw.c \ - src/B-L475E-IOT01/hal/wifi_port.c \ src/B-L475E-IOT01/hal/flash_port.c \ src/B-L475E-IOT01/hal/ota_port.c \ src/B-L475E-IOT01/hal/hal_i2c_stm32l4.c \ @@ -138,12 +151,18 @@ $(NAME)_SOURCES := src/B-L475E-IOT01/runapp/stm32l4xx_hal_msp.c \ src/B-L475E-IOT01/sensor/vl53l0x_proximity.c \ src/B-L475E-IOT01/sensor/sensors_data.c \ src/B-L475E-IOT01/sensor/sensors.c \ - src/B-L475E-IOT01/sensor/qspi.c + src/B-L475E-IOT01/sensor/qspi.c \ + src/B-L475E-IOT01/hal/wifi_port.c \ + Middlewares/USB_Device/Core/Src/usbd_core.c \ + Middlewares/USB_Device/Core/Src/usbd_ctlreq.c \ + Middlewares/USB_Device/Core/Src/usbd_ioreq.c ifeq ($(COMPILER),armcc) $(NAME)_SOURCES += src/B-L475E-IOT01/runapp/startup_stm32l475xx_armcc.s +$(NAME)_LINK_FILES += src/B-L475E-IOT01/runapp/startup_stm32l475xx_armcc.o else ifeq ($(COMPILER),iar) $(NAME)_SOURCES += src/B-L475E-IOT01/runapp/startup_stm32l475xx_icc.s else $(NAME)_SOURCES += src/B-L475E-IOT01/runapp/startup_stm32l475xx_gcc.s endif + diff --git a/platform/mcu/stm32l4xx/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart.h b/platform/mcu/stm32l4xx/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart.h old mode 100644 new mode 100755 index 0c66b9384c..2ef7f3b467 --- a/platform/mcu/stm32l4xx/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart.h +++ b/platform/mcu/stm32l4xx/Drivers/STM32L4xx_HAL_Driver/Inc/stm32l4xx_hal_uart.h @@ -43,6 +43,7 @@ /* Includes ------------------------------------------------------------------*/ #include "stm32l4xx_hal_def.h" +#include /** @addtogroup STM32L4xx_HAL_Driver * @{ @@ -297,6 +298,7 @@ typedef struct __UART_HandleTypeDef __IO uint32_t ErrorCode; /*!< UART Error code */ + kbuf_queue_t* buffer_queue; /*!< buffer queue */ }UART_HandleTypeDef; /** @@ -1548,6 +1550,7 @@ HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, u HAL_StatusTypeDef HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout); HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); HAL_StatusTypeDef HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); +HAL_StatusTypeDef HAL_UART_Receive_IT_Buf_Queue_1byte(UART_HandleTypeDef *huart, uint8_t *pData); HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); HAL_StatusTypeDef HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size); HAL_StatusTypeDef HAL_UART_DMAPause(UART_HandleTypeDef *huart); diff --git a/platform/mcu/stm32l4xx/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.c b/platform/mcu/stm32l4xx/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.c old mode 100644 new mode 100755 index 00e01ee163..db00d0e42c --- a/platform/mcu/stm32l4xx/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.c +++ b/platform/mcu/stm32l4xx/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.c @@ -169,6 +169,7 @@ static void UART_TxISR_16BIT_FIFOEN(UART_HandleTypeDef *huart); #endif static void UART_EndTransmit_IT(UART_HandleTypeDef *huart); static void UART_RxISR_8BIT(UART_HandleTypeDef *huart); +static void UART_RxISR_8BIT_Buf_Queue(UART_HandleTypeDef *huart); static void UART_RxISR_16BIT(UART_HandleTypeDef *huart); #if defined(USART_CR1_FIFOEN) static void UART_RxISR_8BIT_FIFOEN(UART_HandleTypeDef *huart); @@ -903,6 +904,109 @@ HAL_StatusTypeDef HAL_UART_Transmit_IT(UART_HandleTypeDef *huart, uint8_t *pData } } +/** + * @brief Receive an amount of data in interrupt mode with buffer queue. + * @param huart UART handle. + * @param pData Pointer to data buffer. + * @param Size Amount of data to be received. + * @retval HAL status + */ +HAL_StatusTypeDef HAL_UART_Receive_IT_Buf_Queue_1byte(UART_HandleTypeDef *huart, uint8_t *pData) +{ + size_t rev_size = 0; + int ret = 0; + + /* Check that a Rx process is not already ongoing */ + if(huart->RxState == HAL_UART_STATE_READY) + { + if(pData == NULL) + { + return HAL_ERROR; + } + + /* Process Locked */ + __HAL_LOCK(huart); + + huart->pRxBuffPtr = pData; + huart->RxXferSize = 1; + huart->RxXferCount = 0xFFFF; + huart->RxISR = NULL; + + /* Computation of UART mask to apply to RDR register */ + UART_MASK_COMPUTATION(huart); + + huart->ErrorCode = HAL_UART_ERROR_NONE; + huart->RxState = HAL_UART_STATE_BUSY_RX; + + /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */ + SET_BIT(huart->Instance->CR3, USART_CR3_EIE); + +#if defined(USART_CR1_FIFOEN) + /* Configure Rx interrupt processing*/ + if ((huart->FifoMode == UART_FIFOMODE_ENABLE) && (Size >= huart->NbRxDataToProcess)) + { + /* Set the Rx ISR function pointer according to the data word length */ + if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) + { + huart->RxISR = UART_RxISR_16BIT_FIFOEN; + } + else + { + huart->RxISR = UART_RxISR_8BIT_FIFOEN; + } + + /* Process Unlocked */ + __HAL_UNLOCK(huart); + + /* Enable the UART Parity Error interrupt and RX FIFO Threshold interrupt */ + SET_BIT(huart->Instance->CR1, USART_CR1_PEIE); + SET_BIT(huart->Instance->CR3, USART_CR3_RXFTIE); + } + else +#endif + { + /* Set the Rx ISR function pointer according to the data word length */ + if ((huart->Init.WordLength == UART_WORDLENGTH_9B) && (huart->Init.Parity == UART_PARITY_NONE)) + { + huart->RxISR = UART_RxISR_16BIT; + } + else + { + huart->RxISR = UART_RxISR_8BIT_Buf_Queue; + } + + /* Process Unlocked */ + __HAL_UNLOCK(huart); + + /* Enable the UART Parity Error interrupt and Data Register Not Empty interrupt */ +#if defined(USART_CR1_FIFOEN) + SET_BIT(huart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE_RXFNEIE); +#else + SET_BIT(huart->Instance->CR1, USART_CR1_PEIE | USART_CR1_RXNEIE); +#endif + } + } + + if (huart->buffer_queue != NULL) + { + ret = krhino_buf_queue_recv(huart->buffer_queue, 0, pData, &rev_size); + if((ret == 0) && (rev_size == 1)) + { + ret = HAL_OK; + } + else + { + ret = HAL_BUSY; + } + } + else + { + ret = HAL_BUSY; + } + + return (HAL_StatusTypeDef)ret; +} + /** * @brief Receive an amount of data in interrupt mode. * @param huart UART handle. @@ -3252,6 +3356,56 @@ static void UART_RxISR_8BIT(UART_HandleTypeDef *huart) } } +/** + * @brief RX interrrupt handler for 7 or 8 bits data word length with buffer queue . + * @param huart UART handle. + * @retval None + */ +static void UART_RxISR_8BIT_Buf_Queue(UART_HandleTypeDef *huart) +{ + uint16_t uhMask = huart->Mask; + uint16_t uhdata; + uint8_t data; + + /* Check that a Rx process is ongoing */ + if(huart->RxState == HAL_UART_STATE_BUSY_RX) + { + uhdata = (uint16_t) READ_REG(huart->Instance->RDR); + data = (uint8_t)(uhdata & (uint8_t)uhMask); + + if (huart->buffer_queue != NULL) + { + krhino_buf_queue_send(huart->buffer_queue, &data, 1); + } + + if(--huart->RxXferCount == 0) + { + /* Disable the UART Parity Error Interrupt and RXNE interrupt*/ +#if defined(USART_CR1_FIFOEN) + CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE_RXFNEIE | USART_CR1_PEIE)); +#else + CLEAR_BIT(huart->Instance->CR1, (USART_CR1_RXNEIE | USART_CR1_PEIE)); +#endif + + /* Disable the UART Error Interrupt: (Frame error, noise error, overrun error) */ + CLEAR_BIT(huart->Instance->CR3, USART_CR3_EIE); + + /* Rx process is completed, restore huart->RxState to Ready */ + huart->RxState = HAL_UART_STATE_READY; + + /* Clear RxISR function pointer */ + huart->RxISR = NULL; + + HAL_UART_RxCpltCallback(huart); + } + } + else + { + /* Clear RXNE interrupt flag */ + __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST); + } +} + /** * @brief RX interrrupt handler for 9 bits data word length . * @note Function is called under interruption only, once diff --git a/platform/mcu/stm32l4xx/src/STM32L433RC-Nucleo/.DS_Store b/platform/mcu/stm32l4xx/src/STM32L433RC-Nucleo/.DS_Store new file mode 100644 index 0000000000..0e69b6f202 Binary files /dev/null and b/platform/mcu/stm32l4xx/src/STM32L433RC-Nucleo/.DS_Store differ diff --git a/platform/mcu/stm32l4xx/src/STM32L433RC-Nucleo/gui_demo/k_config.h b/platform/mcu/stm32l4xx/src/STM32L433RC-Nucleo/gui_demo/k_config.h new file mode 100755 index 0000000000..2de3f969c3 --- /dev/null +++ b/platform/mcu/stm32l4xx/src/STM32L433RC-Nucleo/gui_demo/k_config.h @@ -0,0 +1,226 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#ifndef CONFIG_H +#define CONFIG_H + +/* chip level conf */ +#ifndef RHINO_CONFIG_LITTLE_ENDIAN +#define RHINO_CONFIG_LITTLE_ENDIAN 1 +#endif +#ifndef RHINO_CONFIG_CPU_STACK_DOWN +#define RHINO_CONFIG_CPU_STACK_DOWN 1 +#endif + +/* kernel feature conf */ +#ifndef RHINO_CONFIG_SEM +#define RHINO_CONFIG_SEM 1 +#endif +#ifndef RHINO_CONFIG_QUEUE +#define RHINO_CONFIG_QUEUE 1 +#endif +#ifndef RHINO_CONFIG_TASK_SEM +#define RHINO_CONFIG_TASK_SEM 0 +#endif +#ifndef RHINO_CONFIG_EVENT_FLAG +#define RHINO_CONFIG_EVENT_FLAG 0 +#endif +#ifndef RHINO_CONFIG_TIMER +#define RHINO_CONFIG_TIMER 0 +#endif +#ifndef RHINO_CONFIG_BUF_QUEUE +#define RHINO_CONFIG_BUF_QUEUE 1 +#endif +#ifndef RHINO_CONFIG_MM_BLK +#define RHINO_CONFIG_MM_BLK 0 +#endif +#ifndef RHINO_CONFIG_MM_DEBUG +#define RHINO_CONFIG_MM_DEBUG 0 +#endif + +#ifndef RHINO_CONFIG_MM_TLF +#define RHINO_CONFIG_MM_TLF 0 +#endif +#ifndef RHINO_CONFIG_MM_TLF_BLK_SIZE +#define RHINO_CONFIG_MM_TLF_BLK_SIZE 8192 +#endif +#define K_MM_STATISTIC 0 +#ifndef RHINO_CONFIG_MM_MAXMSIZEBIT +#define RHINO_CONFIG_MM_MAXMSIZEBIT 19 +#endif +#ifndef RHINO_CONFIG_GCC_RETADDR +#define RHINO_CONFIG_GCC_RETADDR 0 +#endif +#ifndef RHINO_CONFIG_MM_LEAKCHECK +#define RHINO_CONFIG_MM_LEAKCHECK 0 +#endif +#ifndef RHINO_CONFIG_RINGBUF_VENDOR +#define RHINO_CONFIG_RINGBUF_VENDOR 0 +#endif + +#ifndef RHINO_CONFIG_KOBJ_SET +#define RHINO_CONFIG_KOBJ_SET 0 +#endif + +/* kernel task conf */ +#ifndef RHINO_CONFIG_TASK_SUSPEND +#define RHINO_CONFIG_TASK_SUSPEND 1 +#endif +#ifndef RHINO_CONFIG_TASK_INFO +#define RHINO_CONFIG_TASK_INFO 0 +#endif +#ifndef RHINO_CONFIG_TASK_DEL +#define RHINO_CONFIG_TASK_DEL 1 +#endif + +#ifndef RHINO_CONFIG_TASK_STACK_CUR_CHECK +#define RHINO_CONFIG_TASK_STACK_CUR_CHECK 0 +#endif + +#ifndef RHINO_CONFIG_TASK_WAIT_ABORT +#define RHINO_CONFIG_TASK_WAIT_ABORT 0 +#endif +#ifndef RHINO_CONFIG_TASK_STACK_OVF_CHECK +#define RHINO_CONFIG_TASK_STACK_OVF_CHECK 1 +#endif +#ifndef RHINO_CONFIG_SCHED_RR +#define RHINO_CONFIG_SCHED_RR 0 +#endif +#ifndef RHINO_CONFIG_TIME_SLICE_DEFAULT +#define RHINO_CONFIG_TIME_SLICE_DEFAULT 50 +#endif +#ifndef RHINO_CONFIG_PRI_MAX +#define RHINO_CONFIG_PRI_MAX 62 +#endif +#ifndef RHINO_CONFIG_USER_PRI_MAX +#define RHINO_CONFIG_USER_PRI_MAX (RHINO_CONFIG_PRI_MAX - 2) +#endif + +/* kernel workqueue conf */ +#ifndef RHINO_CONFIG_WORKQUEUE +#define RHINO_CONFIG_WORKQUEUE 0 +#endif +#ifndef RHINO_CONFIG_WORKQUEUE_STACK_SIZE +#define RHINO_CONFIG_WORKQUEUE_STACK_SIZE 768 +#endif + +/* kernel mm_region conf */ +#ifndef RHINO_CONFIG_MM_REGION_MUTEX +#define RHINO_CONFIG_MM_REGION_MUTEX 0 +#endif + +/* kernel timer&tick conf */ +#ifndef RHINO_CONFIG_HW_COUNT +#define RHINO_CONFIG_HW_COUNT 0 +#endif +#ifndef RHINO_CONFIG_TICK_TASK +#define RHINO_CONFIG_TICK_TASK 0 +#endif + +#if (RHINO_CONFIG_TICK_TASK > 0) +#ifndef RHINO_CONFIG_TICK_TASK_STACK_SIZE +#define RHINO_CONFIG_TICK_TASK_STACK_SIZE 256 +#endif +#ifndef RHINO_CONFIG_TICK_TASK_PRI +#define RHINO_CONFIG_TICK_TASK_PRI 1 +#endif +#endif + +#ifndef RHINO_CONFIG_TICKLESS +#define RHINO_CONFIG_TICKLESS 0 +#endif +#ifndef RHINO_CONFIG_TICKS_PER_SECOND +#define RHINO_CONFIG_TICKS_PER_SECOND 100 +#endif +/* must be 2^n size!, such as 1, 2, 4, 8, 16,32, etc....... */ +#ifndef RHINO_CONFIG_TICK_HEAD_ARRAY +#define RHINO_CONFIG_TICK_HEAD_ARRAY 8 +#endif + +/*must reserve enough stack size for timer cb will consume*/ +#ifndef RHINO_CONFIG_TIMER_TASK_STACK_SIZE +#define RHINO_CONFIG_TIMER_TASK_STACK_SIZE 300 +#endif +#ifndef RHINO_CONFIG_TIMER_RATE +#define RHINO_CONFIG_TIMER_RATE 1 +#endif +#ifndef RHINO_CONFIG_TIMER_TASK_PRI +#define RHINO_CONFIG_TIMER_TASK_PRI 5 +#endif + +/* kernel intrpt conf */ +#ifndef RHINO_CONFIG_INTRPT_STACK_REMAIN_GET +#define RHINO_CONFIG_INTRPT_STACK_REMAIN_GET 0 +#endif +#ifndef RHINO_CONFIG_INTRPT_STACK_OVF_CHECK +#define RHINO_CONFIG_INTRPT_STACK_OVF_CHECK 0 +#endif +#ifndef RHINO_CONFIG_INTRPT_MAX_NESTED_LEVEL +#define RHINO_CONFIG_INTRPT_MAX_NESTED_LEVEL 188u +#endif +#ifndef RHINO_CONFIG_INTRPT_GUARD +#define RHINO_CONFIG_INTRPT_GUARD 0 +#endif + +/* kernel dyn alloc conf */ +#ifndef RHINO_CONFIG_KOBJ_DYN_ALLOC +#define RHINO_CONFIG_KOBJ_DYN_ALLOC 0 +#endif + +#if (RHINO_CONFIG_KOBJ_DYN_ALLOC > 0) +#ifndef RHINO_CONFIG_K_DYN_QUEUE_MSG +#define RHINO_CONFIG_K_DYN_QUEUE_MSG 30 +#endif +#ifndef RHINO_CONFIG_K_DYN_TASK_STACK +#define RHINO_CONFIG_K_DYN_TASK_STACK 256 +#endif +#ifndef RHINO_CONFIG_K_DYN_MEM_TASK_PRI +#define RHINO_CONFIG_K_DYN_MEM_TASK_PRI 6 +#endif +#endif + +/* kernel idle conf */ +#ifndef RHINO_CONFIG_IDLE_TASK_STACK_SIZE +#define RHINO_CONFIG_IDLE_TASK_STACK_SIZE 200 +#endif + +/* kernel hook conf */ +#ifndef RHINO_CONFIG_USER_HOOK +#define RHINO_CONFIG_USER_HOOK 0 +#endif + +/* kernel stats conf */ +#ifndef RHINO_CONFIG_SYSTEM_STATS +#define RHINO_CONFIG_SYSTEM_STATS 1 +#endif +#ifndef RHINO_CONFIG_DISABLE_SCHED_STATS +#define RHINO_CONFIG_DISABLE_SCHED_STATS 0 +#endif +#ifndef RHINO_CONFIG_DISABLE_INTRPT_STATS +#define RHINO_CONFIG_DISABLE_INTRPT_STATS 0 +#endif +#ifndef RHINO_CONFIG_CPU_USAGE_STATS +#define RHINO_CONFIG_CPU_USAGE_STATS 0 +#endif +#ifndef RHINO_CONFIG_CPU_USAGE_TASK_PRI +#define RHINO_CONFIG_CPU_USAGE_TASK_PRI (RHINO_CONFIG_PRI_MAX - 2) +#endif +#ifndef RHINO_CONFIG_TASK_SCHED_STATS +#define RHINO_CONFIG_TASK_SCHED_STATS 0 +#endif +#ifndef RHINO_CONFIG_CPU_USAGE_TASK_STACK +#define RHINO_CONFIG_CPU_USAGE_TASK_STACK 256 +#endif + +#ifndef RHINO_CONFIG_CPU_NUM +#define RHINO_CONFIG_CPU_NUM 1 +#endif + +/* kernel trace conf */ +#ifndef RHINO_CONFIG_TRACE +#define RHINO_CONFIG_TRACE 0 +#endif + +#endif /* CONFIG_H */ + diff --git a/platform/mcu/stm32l4xx/src/STM32L433RC-Nucleo/gui_demo/soc_init.c b/platform/mcu/stm32l4xx/src/STM32L433RC-Nucleo/gui_demo/soc_init.c new file mode 100755 index 0000000000..c7138bb538 --- /dev/null +++ b/platform/mcu/stm32l4xx/src/STM32L433RC-Nucleo/gui_demo/soc_init.c @@ -0,0 +1,350 @@ +/** + ****************************************************************************** + * File Name : main.c + * Description : Main program body + ****************************************************************************** + ** This notice applies to any and all portions of this file + * that are not between comment pairs USER CODE BEGIN and + * USER CODE END. Other portions of this file, whether + * inserted by the user or by software development tools + * are owned by their respective copyright owners. + * + * COPYRIGHT(c) 2017 STMicroelectronics + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 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 STMicroelectronics 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. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "soc_init.h" +#include "k_api.h" +#include "stm32l4xx_hal.h" +#include "GUI_init.h" + +#if defined (__CC_ARM) && defined(__MICROLIB) +void __aeabi_assert(const char *expr, const char *file, int line) +{ + while (1); +} +#endif + +#if defined (__CC_ARM) && defined(__MICROLIB) +#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) +#define GETCHAR_PROTOTYPE int fgetc(FILE *f) +#elif defined(__ICCARM__) +#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) +#define GETCHAR_PROTOTYPE int fgetc(FILE *f) +#else +/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf + set to 'Yes') calls __io_putchar() */ +#define PUTCHAR_PROTOTYPE int __io_putchar(int ch) +#define GETCHAR_PROTOTYPE int __io_getchar(void) +#endif /* defined (__CC_ARM) && defined(__MICROLIB) */ + + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Private variables ---------------------------------------------------------*/ +UART_HandleTypeDef huart2; + +/* USER CODE BEGIN PV */ +/* Private variables ---------------------------------------------------------*/ + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +void SystemClock_Config(void); +static void MX_GPIO_Init(void); +static void MX_USART2_UART_Init(void); + +/* USER CODE BEGIN PFP */ +/* Private function prototypes -----------------------------------------------*/ + +/* USER CODE END PFP */ + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +void stm32_soc_init(void) +{ + + /* USER CODE BEGIN 1 */ + + /* USER CODE END 1 */ + + /* MCU Configuration----------------------------------------------------------*/ + + /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ + HAL_Init(); + + /* USER CODE BEGIN Init */ + + /* USER CODE END Init */ + + /* Configure the system clock */ + SystemClock_Config(); + + /* USER CODE BEGIN SysInit */ + + /* USER CODE END SysInit */ + + /* Initialize all configured peripherals */ + MX_GPIO_Init(); + MX_USART2_UART_Init(); + /* Initialize LCD and LEDs */ + BSP_GUI_init(); +} + +/** System Clock Configuration +*/ +void SystemClock_Config(void) +{ + + RCC_OscInitTypeDef RCC_OscInitStruct; + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_PeriphCLKInitTypeDef PeriphClkInit; + + /**Initializes the CPU, AHB and APB busses clocks + */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; + RCC_OscInitStruct.HSIState = RCC_HSI_ON; + RCC_OscInitStruct.HSICalibrationValue = 16; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; + RCC_OscInitStruct.PLL.PLLM = 1; + RCC_OscInitStruct.PLL.PLLN = 10; + RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7; + RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2; + RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2; + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) + { + _Error_Handler(__FILE__, __LINE__); + } + + /**Initializes the CPU, AHB and APB busses clocks + */ + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK + |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK) + { + _Error_Handler(__FILE__, __LINE__); + } + + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2; + PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) + { + _Error_Handler(__FILE__, __LINE__); + } + + /**Configure the main internal regulator output voltage + */ + if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK) + { + _Error_Handler(__FILE__, __LINE__); + } + + /**Configure the Systick interrupt time + */ + HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/RHINO_CONFIG_TICKS_PER_SECOND); + + /**Configure the Systick + */ + HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK); + + /* SysTick_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0); +} + +/* USART2 init function */ +static void MX_USART2_UART_Init(void) +{ + + huart2.Instance = USART2; + huart2.Init.BaudRate = 115200; + huart2.Init.WordLength = UART_WORDLENGTH_8B; + huart2.Init.StopBits = UART_STOPBITS_1; + huart2.Init.Parity = UART_PARITY_NONE; + huart2.Init.Mode = UART_MODE_TX_RX; + huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; + huart2.Init.OverSampling = UART_OVERSAMPLING_16; + huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; + huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; + if (HAL_UART_Init(&huart2) != HAL_OK) + { + _Error_Handler(__FILE__, __LINE__); + } + +} + +/** Configure pins as + * Analog + * Input + * Output + * EVENT_OUT + * EXTI +*/ +static void MX_GPIO_Init(void) +{ + + GPIO_InitTypeDef GPIO_InitStruct; + + /* GPIO Ports Clock Enable */ + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOH_CLK_ENABLE(); + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + + /*Configure GPIO pin Output Level */ + HAL_GPIO_WritePin(LD4_GPIO_Port, LD4_Pin, GPIO_PIN_RESET); + + /*Configure GPIO pin Output Level */ + HAL_GPIO_WritePin(GPIOB, SMPS_EN_Pin|SMPS_V1_Pin|SPMS_SW_Pin, GPIO_PIN_RESET); + + /*Configure GPIO pin : B1_Pin */ + GPIO_InitStruct.Pin = B1_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(B1_GPIO_Port, &GPIO_InitStruct); + + /*Configure GPIO pin : LD4_Pin */ + GPIO_InitStruct.Pin = LD4_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(LD4_GPIO_Port, &GPIO_InitStruct); + + /*Configure GPIO pins : SMPS_EN_Pin SMPS_V1_Pin SPMS_SW_Pin */ + GPIO_InitStruct.Pin = SMPS_EN_Pin|SMPS_V1_Pin|SPMS_SW_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /*Configure GPIO pin : SMPS_PG_Pin */ + GPIO_InitStruct.Pin = SMPS_PG_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(SMPS_PG_GPIO_Port, &GPIO_InitStruct); + +} + +/* USER CODE BEGIN 4 */ + +/* USER CODE END 4 */ + +/** + * @brief This function is executed in case of error occurrence. + * @param None + * @retval None + */ +void _Error_Handler(char * file, int line) +{ + /* USER CODE BEGIN Error_Handler_Debug */ + /* User can add his own implementation to report the HAL error return state */ + while(1) + { + } + /* USER CODE END Error_Handler_Debug */ +} + +#ifdef USE_FULL_ASSERT + +/** + * @brief Reports the name of the source file and the source line number + * where the assert_param error has occurred. + * @param file: pointer to the source file name + * @param line: assert_param error line source number + * @retval None + */ +void assert_failed(uint8_t* file, uint32_t line) +{ + /* USER CODE BEGIN 6 */ + /* User can add his own implementation to report the file name and line number, + ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ + /* USER CODE END 6 */ + +} + +#endif + +HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) +{ + /*Configure the SysTick to have interrupt in 1ms time basis*/ + HAL_SYSTICK_Config(SystemCoreClock/RHINO_CONFIG_TICKS_PER_SECOND); + + /*Configure the SysTick IRQ priority */ + HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority ,0U); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Retargets the C library printf function to the USART. + * @param None + * @retval None + */ +PUTCHAR_PROTOTYPE +{ + if (ch == '\n') { + //hal_uart_send(&console_uart, (void *)"\r", 1, 30000); + HAL_UART_Transmit(&huart2, (void *)"\r", 1,30000); + } + HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, 0xFFFF); + return ch; +} + +/** + * @brief Retargets the C library scanf function to the USART. + * @param None + * @retval None + */ +GETCHAR_PROTOTYPE +{ + /* Place your implementation of fgetc here */ + /* e.g. readwrite a character to the USART2 and Loop until the end of transmission */ + uint8_t ch = 0; + //uint32_t recv_size; + HAL_UART_Receive(&huart2, &ch, 1,30000); + return ch; +} + +/** + * @} + */ + +/** + * @} +*/ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/platform/mcu/stm32l4xx/src/STM32L433RC-Nucleo/gui_demo/soc_init.h b/platform/mcu/stm32l4xx/src/STM32L433RC-Nucleo/gui_demo/soc_init.h new file mode 100755 index 0000000000..936449b58b --- /dev/null +++ b/platform/mcu/stm32l4xx/src/STM32L433RC-Nucleo/gui_demo/soc_init.h @@ -0,0 +1,103 @@ +/** + ****************************************************************************** + * File Name : main.hpp + * Description : This file contains the common defines of the application + ****************************************************************************** + ** This notice applies to any and all portions of this file + * that are not between comment pairs USER CODE BEGIN and + * USER CODE END. Other portions of this file, whether + * inserted by the user or by software development tools + * are owned by their respective copyright owners. + * + * COPYRIGHT(c) 2017 STMicroelectronics + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 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 STMicroelectronics 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. + * + ****************************************************************************** + */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __SOC_INIT_H +#define __SOC_INIT_H + /* Includes ------------------------------------------------------------------*/ + +/* Includes ------------------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Private define ------------------------------------------------------------*/ + +#define B1_Pin GPIO_PIN_13 +#define B1_GPIO_Port GPIOC +#define MCO_Pin GPIO_PIN_0 +#define MCO_GPIO_Port GPIOH +#define USART_RX_Pin GPIO_PIN_3 +#define USART_RX_GPIO_Port GPIOA +#define LD4_Pin GPIO_PIN_5 +#define LD4_GPIO_Port GPIOA +#define SMPS_EN_Pin GPIO_PIN_12 +#define SMPS_EN_GPIO_Port GPIOB +#define SMPS_V1_Pin GPIO_PIN_13 +#define SMPS_V1_GPIO_Port GPIOB +#define SMPS_PG_Pin GPIO_PIN_14 +#define SMPS_PG_GPIO_Port GPIOB +#define SPMS_SW_Pin GPIO_PIN_15 +#define SPMS_SW_GPIO_Port GPIOB +#define TMS_Pin GPIO_PIN_13 +#define TMS_GPIO_Port GPIOA +#define TCK_Pin GPIO_PIN_14 +#define TCK_GPIO_Port GPIOA +#define SWO_Pin GPIO_PIN_3 +#define SWO_GPIO_Port GPIOB + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1U */ + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +#ifdef __cplusplus + extern "C" { +#endif +void _Error_Handler(char *, int); + +#define Error_Handler() _Error_Handler(__FILE__, __LINE__) +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +/** + * @} +*/ + +#endif /* __SOC_INIT_H */ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/platform/mcu/stm32l4xx/src/STM32L433RC-Nucleo/gui_demo/stm32l4xx_hal_conf.h b/platform/mcu/stm32l4xx/src/STM32L433RC-Nucleo/gui_demo/stm32l4xx_hal_conf.h new file mode 100755 index 0000000000..4d191a9bca --- /dev/null +++ b/platform/mcu/stm32l4xx/src/STM32L433RC-Nucleo/gui_demo/stm32l4xx_hal_conf.h @@ -0,0 +1,430 @@ +/** + ****************************************************************************** + * @file stm32l4xx_hal_conf.h + * @brief HAL configuration file. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2017 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 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 STMicroelectronics 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. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32L4xx_HAL_CONF_H +#define __STM32L4xx_HAL_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +#include "soc_init.h" +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ + +#define HAL_MODULE_ENABLED +/*#define HAL_ADC_MODULE_ENABLED */ +/*#define HAL_CRYP_MODULE_ENABLED */ +/*#define HAL_CAN_MODULE_ENABLED */ +/*#define HAL_COMP_MODULE_ENABLED */ +/*#define HAL_CRC_MODULE_ENABLED */ +/*#define HAL_CRYP_MODULE_ENABLED */ +/*#define HAL_DAC_MODULE_ENABLED */ +/*#define HAL_DCMI_MODULE_ENABLED */ +/*#define HAL_DMA2D_MODULE_ENABLED */ +/*#define HAL_DFSDM_MODULE_ENABLED */ +/*#define HAL_DSI_MODULE_ENABLED */ +/*#define HAL_FIREWALL_MODULE_ENABLED */ +/*#define HAL_GFXMMU_MODULE_ENABLED */ +/*#define HAL_HCD_MODULE_ENABLED */ +/*#define HAL_HASH_MODULE_ENABLED */ +/*#define HAL_I2S_MODULE_ENABLED */ +/*#define HAL_IRDA_MODULE_ENABLED */ +/*#define HAL_IWDG_MODULE_ENABLED */ +/*#define HAL_LTDC_MODULE_ENABLED */ +/*#define HAL_LCD_MODULE_ENABLED */ +/*#define HAL_LPTIM_MODULE_ENABLED */ +/*#define HAL_NAND_MODULE_ENABLED */ +/*#define HAL_NOR_MODULE_ENABLED */ +/*#define HAL_OPAMP_MODULE_ENABLED */ +/*#define HAL_OSPI_MODULE_ENABLED */ +/*#define HAL_OSPI_MODULE_ENABLED */ +/*#define HAL_PCD_MODULE_ENABLED */ +/*#define HAL_QSPI_MODULE_ENABLED */ +/*#define HAL_QSPI_MODULE_ENABLED */ +/*#define HAL_RNG_MODULE_ENABLED */ +/*#define HAL_RTC_MODULE_ENABLED */ +/*#define HAL_SAI_MODULE_ENABLED */ +/*#define HAL_SD_MODULE_ENABLED */ +/*#define HAL_SMBUS_MODULE_ENABLED */ +/*#define HAL_SMARTCARD_MODULE_ENABLED */ +/*#define HAL_SPI_MODULE_ENABLED */ +/*#define HAL_SRAM_MODULE_ENABLED */ +/*#define HAL_SWPMI_MODULE_ENABLED */ +/*#define HAL_TIM_MODULE_ENABLED */ +/*#define HAL_TSC_MODULE_ENABLED */ +#define HAL_UART_MODULE_ENABLED +/*#define HAL_USART_MODULE_ENABLED */ +/*#define HAL_WWDG_MODULE_ENABLED */ +#define HAL_GPIO_MODULE_ENABLED +#define HAL_I2C_MODULE_ENABLED +#define HAL_DMA_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED +#define HAL_FLASH_MODULE_ENABLED +#define HAL_PWR_MODULE_ENABLED +#define HAL_CORTEX_MODULE_ENABLED + +/* ########################## Oscillator Values adaptation ####################*/ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined (HSE_VALUE) + #define HSE_VALUE ((uint32_t)8000000U) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSE_STARTUP_TIMEOUT) + #define HSE_STARTUP_TIMEOUT ((uint32_t)100U) /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal Multiple Speed oscillator (MSI) default value. + * This value is the default MSI range value after Reset. + */ +#if !defined (MSI_VALUE) + #define MSI_VALUE ((uint32_t)4000000U) /*!< Value of the Internal oscillator in Hz*/ +#endif /* MSI_VALUE */ +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) + #define HSI_VALUE ((uint32_t)16000000U) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief Internal High Speed oscillator (HSI48) value for USB FS, SDMMC and RNG. + * This internal oscillator is mainly dedicated to provide a high precision clock to + * the USB peripheral by means of a special Clock Recovery System (CRS) circuitry. + * When the CRS is not used, the HSI48 RC oscillator runs on it default frequency + * which is subject to manufacturing process variations. + */ +#if !defined (HSI48_VALUE) + #define HSI48_VALUE ((uint32_t)48000000U) /*!< Value of the Internal High Speed oscillator for USB FS/SDMMC/RNG in Hz. + The real value my vary depending on manufacturing process variations.*/ +#endif /* HSI48_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined (LSI_VALUE) + #define LSI_VALUE ((uint32_t)32000U) /*!< LSI Typical Value in Hz*/ +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations + in voltage and temperature.*/ + +/** + * @brief External Low Speed oscillator (LSE) value. + * This value is used by the UART, RTC HAL module to compute the system frequency + */ +#if !defined (LSE_VALUE) + #define LSE_VALUE ((uint32_t)32768U) /*!< Value of the External oscillator in Hz*/ +#endif /* LSE_VALUE */ + +#if !defined (LSE_STARTUP_TIMEOUT) + #define LSE_STARTUP_TIMEOUT ((uint32_t)5000U) /*!< Time out for LSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief External clock source for SAI1 peripheral + * This value is used by the RCC HAL module to compute the SAI1 & SAI2 clock source + * frequency. + */ +#if !defined (EXTERNAL_SAI1_CLOCK_VALUE) + #define EXTERNAL_SAI1_CLOCK_VALUE ((uint32_t)2097000U) /*!< Value of the SAI1 External clock source in Hz*/ +#endif /* EXTERNAL_SAI1_CLOCK_VALUE */ + +/** + * @brief External clock source for SAI2 peripheral + * This value is used by the RCC HAL module to compute the SAI1 & SAI2 clock source + * frequency. + */ +#if !defined (EXTERNAL_SAI2_CLOCK_VALUE) + #define EXTERNAL_SAI2_CLOCK_VALUE ((uint32_t)48000U) /*!< Value of the SAI2 External clock source in Hz*/ +#endif /* EXTERNAL_SAI2_CLOCK_VALUE */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ + +#define VDD_VALUE ((uint32_t)3300U) /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY ((uint32_t)0U) /*!< tick interrupt priority */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 1U +#define INSTRUCTION_CACHE_ENABLE 1U +#define DATA_CACHE_ENABLE 1U + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1U */ + +/* ################## SPI peripheral configuration ########################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver + * Activated: CRC code is present inside driver + * Deactivated: CRC code cleaned from driver + */ + +#define USE_SPI_CRC 0U + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED + #include "stm32l4xx_hal_rcc.h" + #include "stm32l4xx_hal_rcc_ex.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED + #include "stm32l4xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED + #include "stm32l4xx_hal_dma.h" + #include "stm32l4xx_hal_dma_ex.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_DFSDM_MODULE_ENABLED + #include "stm32l4xx_hal_dfsdm.h" +#endif /* HAL_DFSDM_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + #include "stm32l4xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED + #include "stm32l4xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_CAN_MODULE_ENABLED + #include "stm32l4xx_hal_can.h" +#endif /* HAL_CAN_MODULE_ENABLED */ + +#ifdef HAL_COMP_MODULE_ENABLED + #include "stm32l4xx_hal_comp.h" +#endif /* HAL_COMP_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED + #include "stm32l4xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED + #include "stm32l4xx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED + #include "stm32l4xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_DCMI_MODULE_ENABLED + #include "stm32l4xx_hal_dcmi.h" +#endif /* HAL_DCMI_MODULE_ENABLED */ + +#ifdef HAL_DMA2D_MODULE_ENABLED + #include "stm32l4xx_hal_dma2d.h" +#endif /* HAL_DMA2D_MODULE_ENABLED */ + +#ifdef HAL_DSI_MODULE_ENABLED + #include "stm32l4xx_hal_dsi.h" +#endif /* HAL_DSI_MODULE_ENABLED */ + +#ifdef HAL_FIREWALL_MODULE_ENABLED + #include "stm32l4xx_hal_firewall.h" +#endif /* HAL_FIREWALL_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED + #include "stm32l4xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_HASH_MODULE_ENABLED + #include "stm32l4xx_hal_hash.h" +#endif /* HAL_HASH_MODULE_ENABLED */ + +#ifdef HAL_SRAM_MODULE_ENABLED + #include "stm32l4xx_hal_sram.h" +#endif /* HAL_SRAM_MODULE_ENABLED */ + +#ifdef HAL_NOR_MODULE_ENABLED + #include "stm32l4xx_hal_nor.h" +#endif /* HAL_NOR_MODULE_ENABLED */ + +#ifdef HAL_NAND_MODULE_ENABLED + #include "stm32l4xx_hal_nand.h" +#endif /* HAL_NAND_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED + #include "stm32l4xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED + #include "stm32l4xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_LCD_MODULE_ENABLED + #include "stm32l4xx_hal_lcd.h" +#endif /* HAL_LCD_MODULE_ENABLED */ + +#ifdef HAL_LPTIM_MODULE_ENABLED + #include "stm32l4xx_hal_lptim.h" +#endif /* HAL_LPTIM_MODULE_ENABLED */ + +#ifdef HAL_LTDC_MODULE_ENABLED + #include "stm32l4xx_hal_ltdc.h" +#endif /* HAL_LTDC_MODULE_ENABLED */ + +#ifdef HAL_OPAMP_MODULE_ENABLED + #include "stm32l4xx_hal_opamp.h" +#endif /* HAL_OPAMP_MODULE_ENABLED */ + +#ifdef HAL_OSPI_MODULE_ENABLED + #include "stm32l4xx_hal_ospi.h" +#endif /* HAL_OSPI_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED + #include "stm32l4xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_QSPI_MODULE_ENABLED + #include "stm32l4xx_hal_qspi.h" +#endif /* HAL_QSPI_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED + #include "stm32l4xx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED + #include "stm32l4xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SAI_MODULE_ENABLED + #include "stm32l4xx_hal_sai.h" +#endif /* HAL_SAI_MODULE_ENABLED */ + +#ifdef HAL_SD_MODULE_ENABLED + #include "stm32l4xx_hal_sd.h" +#endif /* HAL_SD_MODULE_ENABLED */ + +#ifdef HAL_SMBUS_MODULE_ENABLED + #include "stm32l4xx_hal_smbus.h" +#endif /* HAL_SMBUS_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED + #include "stm32l4xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_SWPMI_MODULE_ENABLED + #include "stm32l4xx_hal_swpmi.h" +#endif /* HAL_SWPMI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED + #include "stm32l4xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_TSC_MODULE_ENABLED + #include "stm32l4xx_hal_tsc.h" +#endif /* HAL_TSC_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED + #include "stm32l4xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED + #include "stm32l4xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED + #include "stm32l4xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED + #include "stm32l4xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED + #include "stm32l4xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED + #include "stm32l4xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_HCD_MODULE_ENABLED + #include "stm32l4xx_hal_hcd.h" +#endif /* HAL_HCD_MODULE_ENABLED */ + +#ifdef HAL_GFXMMU_MODULE_ENABLED + #include "stm32l4xx_hal_gfxmmu.h" +#endif /* HAL_GFXMMU_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr: If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ + #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ + void assert_failed(uint8_t* file, uint32_t line); +#else + #define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32L4xx_HAL_CONF_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/platform/mcu/stm32l4xx/src/STM32L433RC-Nucleo/gui_demo/stm32l4xx_hal_msp.c b/platform/mcu/stm32l4xx/src/STM32L433RC-Nucleo/gui_demo/stm32l4xx_hal_msp.c new file mode 100755 index 0000000000..381e07adb6 --- /dev/null +++ b/platform/mcu/stm32l4xx/src/STM32L433RC-Nucleo/gui_demo/stm32l4xx_hal_msp.c @@ -0,0 +1,154 @@ +/** + ****************************************************************************** + * File Name : stm32l4xx_hal_msp.c + * Description : This file provides code for the MSP Initialization + * and de-Initialization codes. + ****************************************************************************** + ** This notice applies to any and all portions of this file + * that are not between comment pairs USER CODE BEGIN and + * USER CODE END. Other portions of this file, whether + * inserted by the user or by software development tools + * are owned by their respective copyright owners. + * + * COPYRIGHT(c) 2017 STMicroelectronics + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 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 STMicroelectronics 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. + * + ****************************************************************************** + */ +/* Includes ------------------------------------------------------------------*/ +#include "stm32l4xx_hal.h" + +extern void _Error_Handler(char *, int); +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ +/** + * Initializes the Global MSP. + */ +void HAL_MspInit(void) +{ + /* USER CODE BEGIN MspInit 0 */ + + /* USER CODE END MspInit 0 */ + + __HAL_RCC_SYSCFG_CLK_ENABLE(); + __HAL_RCC_PWR_CLK_ENABLE(); + + HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4); + + /* System interrupt init*/ + /* MemoryManagement_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(MemoryManagement_IRQn, 0, 0); + /* BusFault_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(BusFault_IRQn, 0, 0); + /* UsageFault_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(UsageFault_IRQn, 0, 0); + /* SVCall_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(SVCall_IRQn, 0, 0); + /* DebugMonitor_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(DebugMonitor_IRQn, 0, 0); + /* PendSV_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(PendSV_IRQn, 0, 0); + /* SysTick_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0); + + /* USER CODE BEGIN MspInit 1 */ + + /* USER CODE END MspInit 1 */ +} + +void HAL_UART_MspInit(UART_HandleTypeDef* huart) +{ + + GPIO_InitTypeDef GPIO_InitStruct; + if(huart->Instance==USART2) + { + /* USER CODE BEGIN USART2_MspInit 0 */ + + /* USER CODE END USART2_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_USART2_CLK_ENABLE(); + + /**USART2 GPIO Configuration + PA2 ------> USART2_TX + PA3 ------> USART2_RX + */ + GPIO_InitStruct.Pin = GPIO_PIN_2; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF7_USART2; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = USART_RX_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF7_USART2; + HAL_GPIO_Init(USART_RX_GPIO_Port, &GPIO_InitStruct); + + /* USER CODE BEGIN USART2_MspInit 1 */ + + /* USER CODE END USART2_MspInit 1 */ + } + +} + +void HAL_UART_MspDeInit(UART_HandleTypeDef* huart) +{ + + if(huart->Instance==USART2) + { + /* USER CODE BEGIN USART2_MspDeInit 0 */ + + /* USER CODE END USART2_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_USART2_CLK_DISABLE(); + + /**USART2 GPIO Configuration + PA2 ------> USART2_TX + PA3 ------> USART2_RX + */ + HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|USART_RX_Pin); + + /* USER CODE BEGIN USART2_MspDeInit 1 */ + + /* USER CODE END USART2_MspDeInit 1 */ + } + +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/platform/mcu/stm32l4xx/src/STM32L433RC-Nucleo/gui_demo/stm32l4xx_it.c b/platform/mcu/stm32l4xx/src/STM32L433RC-Nucleo/gui_demo/stm32l4xx_it.c new file mode 100755 index 0000000000..246be40cba --- /dev/null +++ b/platform/mcu/stm32l4xx/src/STM32L433RC-Nucleo/gui_demo/stm32l4xx_it.c @@ -0,0 +1,134 @@ +/** + ****************************************************************************** + * @file stm32l4xx_it.c + * @brief Interrupt Service Routines. + ****************************************************************************** + * + * COPYRIGHT(c) 2017 STMicroelectronics + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 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 STMicroelectronics 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. + * + ****************************************************************************** + */ +/* Includes ------------------------------------------------------------------*/ +#include "stm32l4xx_hal.h" +#include "stm32l4xx.h" +#include "stm32l4xx_it.h" +#include "k_api.h" +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/* External variables --------------------------------------------------------*/ + +/******************************************************************************/ +/* Cortex-M4 Processor Interruption and Exception Handlers */ +/******************************************************************************/ + +/** +* @brief This function handles Non maskable Interrupt. +*/ +void NMI_Handler(void) +{ + +} + +/** +* @brief This function handles Hard fault interrupt. +*/ +void HardFault_Handler(void) +{ + while (1) + { + } +} + +/** +* @brief This function handles Memory management fault. +*/ +void MemManage_Handler(void) +{ + while (1) + { + } +} + +/** +* @brief This function handles Prefetch fault, memory access fault. +*/ +void BusFault_Handler(void) +{ + while (1) + { + } +} + +/** +* @brief This function handles Undefined instruction or illegal state. +*/ +void UsageFault_Handler(void) +{ + while (1) + { + } +} + +/** +* @brief This function handles System service call via SWI instruction. +*/ +void SVC_Handler(void) +{ + +} + +/** +* @brief This function handles Debug monitor. +*/ +void DebugMon_Handler(void) +{ + +} + +/** +* @brief This function handles System tick timer. +*/ +void SysTick_Handler(void) +{ + HAL_IncTick(); + krhino_intrpt_enter(); + krhino_tick_proc(); + krhino_intrpt_exit(); + //HAL_SYSTICK_IRQHandler(); +} + +/******************************************************************************/ +/* STM32L4xx Peripheral Interrupt Handlers */ +/* Add here the Interrupt Handlers for the used peripherals. */ +/* For the available peripheral interrupt handler names, */ +/* please refer to the startup file (startup_stm32l4xx.s). */ +/******************************************************************************/ + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/platform/mcu/stm32l4xx/src/STM32L433RC-Nucleo/gui_demo/stm32l4xx_it.h b/platform/mcu/stm32l4xx/src/STM32L433RC-Nucleo/gui_demo/stm32l4xx_it.h new file mode 100755 index 0000000000..8c697f299c --- /dev/null +++ b/platform/mcu/stm32l4xx/src/STM32L433RC-Nucleo/gui_demo/stm32l4xx_it.h @@ -0,0 +1,66 @@ +/** + ****************************************************************************** + * @file stm32l4xx_it.h + * @brief This file contains the headers of the interrupt handlers. + ****************************************************************************** + * + * COPYRIGHT(c) 2017 STMicroelectronics + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 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 STMicroelectronics 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. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32L4xx_IT_H +#define __STM32L4xx_IT_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l4xx_hal.h" +#include "soc_init.h" +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +void NMI_Handler(void); +void HardFault_Handler(void); +void MemManage_Handler(void); +void BusFault_Handler(void); +void UsageFault_Handler(void); +void SVC_Handler(void); +void DebugMon_Handler(void); +void PendSV_Handler(void); +void SysTick_Handler(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32L4xx_IT_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/platform/mcu/stm32l4xx/src/STM32L433RC-Nucleo/gui_demo/system_stm32l4xx.c b/platform/mcu/stm32l4xx/src/STM32L433RC-Nucleo/gui_demo/system_stm32l4xx.c new file mode 100755 index 0000000000..077d2e9dac --- /dev/null +++ b/platform/mcu/stm32l4xx/src/STM32L433RC-Nucleo/gui_demo/system_stm32l4xx.c @@ -0,0 +1,353 @@ +/** + ****************************************************************************** + * @file system_stm32l4xx.c + * @author MCD Application Team + * @brief CMSIS Cortex-M4 Device Peripheral Access Layer System Source File + * + * This file provides two functions and one global variable to be called from + * user application: + * - SystemInit(): This function is called at startup just after reset and + * before branch to main program. This call is made inside + * the "startup_stm32l4xx.s" file. + * + * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used + * by the user application to setup the SysTick + * timer or configure other parameters. + * + * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must + * be called whenever the core clock is changed + * during program execution. + * + * After each device reset the MSI (4 MHz) is used as system clock source. + * Then SystemInit() function is called, in "startup_stm32l4xx.s" file, to + * configure the system clock before to branch to main program. + * + * This file configures the system clock as follows: + *============================================================================= + *----------------------------------------------------------------------------- + * System Clock source | MSI + *----------------------------------------------------------------------------- + * SYSCLK(Hz) | 4000000 + *----------------------------------------------------------------------------- + * HCLK(Hz) | 4000000 + *----------------------------------------------------------------------------- + * AHB Prescaler | 1 + *----------------------------------------------------------------------------- + * APB1 Prescaler | 1 + *----------------------------------------------------------------------------- + * APB2 Prescaler | 1 + *----------------------------------------------------------------------------- + * PLL_M | 1 + *----------------------------------------------------------------------------- + * PLL_N | 8 + *----------------------------------------------------------------------------- + * PLL_P | 7 + *----------------------------------------------------------------------------- + * PLL_Q | 2 + *----------------------------------------------------------------------------- + * PLL_R | 2 + *----------------------------------------------------------------------------- + * PLLSAI1_P | NA + *----------------------------------------------------------------------------- + * PLLSAI1_Q | NA + *----------------------------------------------------------------------------- + * PLLSAI1_R | NA + *----------------------------------------------------------------------------- + * PLLSAI2_P | NA + *----------------------------------------------------------------------------- + * PLLSAI2_Q | NA + *----------------------------------------------------------------------------- + * PLLSAI2_R | NA + *----------------------------------------------------------------------------- + * Require 48MHz for USB OTG FS, | Disabled + * SDIO and RNG clock | + *----------------------------------------------------------------------------- + *============================================================================= + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2017 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 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 STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup stm32l4xx_system + * @{ + */ + +/** @addtogroup STM32L4xx_System_Private_Includes + * @{ + */ + +#include "stm32l4xx.h" + +#if !defined (HSE_VALUE) + #define HSE_VALUE 8000000U /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (MSI_VALUE) + #define MSI_VALUE 4000000U /*!< Value of the Internal oscillator in Hz*/ +#endif /* MSI_VALUE */ + +#if !defined (HSI_VALUE) + #define HSI_VALUE 16000000U /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @} + */ + +/** @addtogroup STM32L4xx_System_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32L4xx_System_Private_Defines + * @{ + */ + +/************************* Miscellaneous Configuration ************************/ +/*!< Uncomment the following line if you need to relocate your vector Table in + Internal SRAM. */ +/* #define VECT_TAB_SRAM */ +#define VECT_TAB_OFFSET 0x00 /*!< Vector Table base offset field. + This value must be a multiple of 0x200. */ +/******************************************************************************/ +/** + * @} + */ + +/** @addtogroup STM32L4xx_System_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32L4xx_System_Private_Variables + * @{ + */ + /* The SystemCoreClock variable is updated in three ways: + 1) by calling CMSIS function SystemCoreClockUpdate() + 2) by calling HAL API function HAL_RCC_GetHCLKFreq() + 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency + Note: If you use this function to configure the system clock; then there + is no need to call the 2 first functions listed above, since SystemCoreClock + variable is updated automatically. + */ + uint32_t SystemCoreClock = 4000000U; + + const uint8_t AHBPrescTable[16] = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U, 6U, 7U, 8U, 9U}; + const uint8_t APBPrescTable[8] = {0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U}; + const uint32_t MSIRangeTable[12] = {100000U, 200000U, 400000U, 800000U, 1000000U, 2000000U, \ + 4000000U, 8000000U, 16000000U, 24000000U, 32000000U, 48000000U}; +/** + * @} + */ + +/** @addtogroup STM32L4xx_System_Private_FunctionPrototypes + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32L4xx_System_Private_Functions + * @{ + */ + +/** + * @brief Setup the microcontroller system. + * @param None + * @retval None + */ + +void SystemInit(void) +{ + /* FPU settings ------------------------------------------------------------*/ + #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */ + #endif + + /* Reset the RCC clock configuration to the default reset state ------------*/ + /* Set MSION bit */ + RCC->CR |= RCC_CR_MSION; + + /* Reset CFGR register */ + RCC->CFGR = 0x00000000U; + + /* Reset HSEON, CSSON , HSION, and PLLON bits */ + RCC->CR &= 0xEAF6FFFFU; + + /* Reset PLLCFGR register */ + RCC->PLLCFGR = 0x00001000U; + + /* Reset HSEBYP bit */ + RCC->CR &= 0xFFFBFFFFU; + + /* Disable all interrupts */ + RCC->CIER = 0x00000000U; + + /* Configure the Vector Table location add offset address ------------------*/ +#ifdef VECT_TAB_SRAM + SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */ +#else + SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */ +#endif +} + +/** + * @brief Update SystemCoreClock variable according to Clock Register Values. + * The SystemCoreClock variable contains the core clock (HCLK), it can + * be used by the user application to setup the SysTick timer or configure + * other parameters. + * + * @note Each time the core clock (HCLK) changes, this function must be called + * to update SystemCoreClock variable value. Otherwise, any configuration + * based on this variable will be incorrect. + * + * @note - The system frequency computed by this function is not the real + * frequency in the chip. It is calculated based on the predefined + * constant and the selected clock source: + * + * - If SYSCLK source is MSI, SystemCoreClock will contain the MSI_VALUE(*) + * + * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(**) + * + * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***) + * + * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(***) + * or HSI_VALUE(*) or MSI_VALUE(*) multiplied/divided by the PLL factors. + * + * (*) MSI_VALUE is a constant defined in stm32l4xx_hal.h file (default value + * 4 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * + * (**) HSI_VALUE is a constant defined in stm32l4xx_hal.h file (default value + * 16 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * + * (***) HSE_VALUE is a constant defined in stm32l4xx_hal.h file (default value + * 8 MHz), user has to ensure that HSE_VALUE is same as the real + * frequency of the crystal used. Otherwise, this function may + * have wrong result. + * + * - The result of this function could be not correct when using fractional + * value for HSE crystal. + * + * @param None + * @retval None + */ +void SystemCoreClockUpdate(void) +{ + uint32_t tmp = 0U, msirange = 0U, pllvco = 0U, pllr = 2U, pllsource = 0U, pllm = 2U; + + /* Get MSI Range frequency--------------------------------------------------*/ + if((RCC->CR & RCC_CR_MSIRGSEL) == RESET) + { /* MSISRANGE from RCC_CSR applies */ + msirange = (RCC->CSR & RCC_CSR_MSISRANGE) >> 8U; + } + else + { /* MSIRANGE from RCC_CR applies */ + msirange = (RCC->CR & RCC_CR_MSIRANGE) >> 4U; + } + /*MSI frequency range in HZ*/ + msirange = MSIRangeTable[msirange]; + + /* Get SYSCLK source -------------------------------------------------------*/ + switch (RCC->CFGR & RCC_CFGR_SWS) + { + case 0x00: /* MSI used as system clock source */ + SystemCoreClock = msirange; + break; + + case 0x04: /* HSI used as system clock source */ + SystemCoreClock = HSI_VALUE; + break; + + case 0x08: /* HSE used as system clock source */ + SystemCoreClock = HSE_VALUE; + break; + + case 0x0C: /* PLL used as system clock source */ + /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLM) * PLLN + SYSCLK = PLL_VCO / PLLR + */ + pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC); + pllm = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLM) >> 4U) + 1U ; + + switch (pllsource) + { + case 0x02: /* HSI used as PLL clock source */ + pllvco = (HSI_VALUE / pllm); + break; + + case 0x03: /* HSE used as PLL clock source */ + pllvco = (HSE_VALUE / pllm); + break; + + default: /* MSI used as PLL clock source */ + pllvco = (msirange / pllm); + break; + } + pllvco = pllvco * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 8U); + pllr = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 25U) + 1U) * 2U; + SystemCoreClock = pllvco/pllr; + break; + + default: + SystemCoreClock = msirange; + break; + } + /* Compute HCLK clock frequency --------------------------------------------*/ + /* Get HCLK prescaler */ + tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4U)]; + /* HCLK clock frequency */ + SystemCoreClock >>= tmp; +} + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/platform/mcu/stm32l4xx/src/STM32L433RC-Nucleo/helloword/k_config.h b/platform/mcu/stm32l4xx/src/STM32L433RC-Nucleo/helloword/k_config.h index 5bc3d2748a..2de3f969c3 100644 --- a/platform/mcu/stm32l4xx/src/STM32L433RC-Nucleo/helloword/k_config.h +++ b/platform/mcu/stm32l4xx/src/STM32L433RC-Nucleo/helloword/k_config.h @@ -30,7 +30,7 @@ #define RHINO_CONFIG_TIMER 0 #endif #ifndef RHINO_CONFIG_BUF_QUEUE -#define RHINO_CONFIG_BUF_QUEUE 0 +#define RHINO_CONFIG_BUF_QUEUE 1 #endif #ifndef RHINO_CONFIG_MM_BLK #define RHINO_CONFIG_MM_BLK 0 diff --git a/platform/mcu/stm32l4xx/src/STM32L433RC-Nucleo/helloword/soc_init.c b/platform/mcu/stm32l4xx/src/STM32L433RC-Nucleo/helloword/soc_init.c index 643cc896b4..ed74343492 100644 --- a/platform/mcu/stm32l4xx/src/STM32L433RC-Nucleo/helloword/soc_init.c +++ b/platform/mcu/stm32l4xx/src/STM32L433RC-Nucleo/helloword/soc_init.c @@ -38,7 +38,7 @@ /* Includes ------------------------------------------------------------------*/ #include "soc_init.h" -#include "k_config.h" +#include "k_api.h" #include "stm32l4xx_hal.h" #if defined (__CC_ARM) && defined(__MICROLIB) diff --git a/platform/mcu/stm32l4xx/src/STM32L476RG-Nucleo/helloworld/k_config.h b/platform/mcu/stm32l4xx/src/STM32L476RG-Nucleo/helloworld/k_config.h index 5bc3d2748a..2de3f969c3 100644 --- a/platform/mcu/stm32l4xx/src/STM32L476RG-Nucleo/helloworld/k_config.h +++ b/platform/mcu/stm32l4xx/src/STM32L476RG-Nucleo/helloworld/k_config.h @@ -30,7 +30,7 @@ #define RHINO_CONFIG_TIMER 0 #endif #ifndef RHINO_CONFIG_BUF_QUEUE -#define RHINO_CONFIG_BUF_QUEUE 0 +#define RHINO_CONFIG_BUF_QUEUE 1 #endif #ifndef RHINO_CONFIG_MM_BLK #define RHINO_CONFIG_MM_BLK 0 diff --git a/platform/mcu/stm32l4xx/src/STM32L476RG-Nucleo/helloworld/soc_init.c b/platform/mcu/stm32l4xx/src/STM32L476RG-Nucleo/helloworld/soc_init.c index 8341828719..7ae2a2e2a2 100644 --- a/platform/mcu/stm32l4xx/src/STM32L476RG-Nucleo/helloworld/soc_init.c +++ b/platform/mcu/stm32l4xx/src/STM32L476RG-Nucleo/helloworld/soc_init.c @@ -38,7 +38,7 @@ /* Includes ------------------------------------------------------------------*/ #include "soc_init.h" -#include "k_config.h" +#include "k_api.h" #include "stm32l4xx_hal.h" #if defined (__CC_ARM) && defined(__MICROLIB) diff --git a/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/aos_rhino/k_config.h b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/aos_rhino/k_config.h index 2161d87a6e..9d596db26e 100644 --- a/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/aos_rhino/k_config.h +++ b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/aos_rhino/k_config.h @@ -30,7 +30,7 @@ #define RHINO_CONFIG_TIMER 0 #endif #ifndef RHINO_CONFIG_BUF_QUEUE -#define RHINO_CONFIG_BUF_QUEUE 0 +#define RHINO_CONFIG_BUF_QUEUE 1 #endif #ifndef RHINO_CONFIG_MM_BLK #define RHINO_CONFIG_MM_BLK 1 diff --git a/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/aos_rhino/soc_init.c b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/aos_rhino/soc_init.c index 85008f11f6..164b746c91 100644 --- a/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/aos_rhino/soc_init.c +++ b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/aos_rhino/soc_init.c @@ -38,7 +38,7 @@ /* Includes ------------------------------------------------------------------*/ #include "soc_init.h" -#include "k_config.h" +#include "k_api.h" #include "stm32l4xx_hal.h" #if defined (__CC_ARM) && defined(__MICROLIB) diff --git a/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/deviceIO/k_config.h b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/deviceIO/k_config.h new file mode 100755 index 0000000000..2de3f969c3 --- /dev/null +++ b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/deviceIO/k_config.h @@ -0,0 +1,226 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#ifndef CONFIG_H +#define CONFIG_H + +/* chip level conf */ +#ifndef RHINO_CONFIG_LITTLE_ENDIAN +#define RHINO_CONFIG_LITTLE_ENDIAN 1 +#endif +#ifndef RHINO_CONFIG_CPU_STACK_DOWN +#define RHINO_CONFIG_CPU_STACK_DOWN 1 +#endif + +/* kernel feature conf */ +#ifndef RHINO_CONFIG_SEM +#define RHINO_CONFIG_SEM 1 +#endif +#ifndef RHINO_CONFIG_QUEUE +#define RHINO_CONFIG_QUEUE 1 +#endif +#ifndef RHINO_CONFIG_TASK_SEM +#define RHINO_CONFIG_TASK_SEM 0 +#endif +#ifndef RHINO_CONFIG_EVENT_FLAG +#define RHINO_CONFIG_EVENT_FLAG 0 +#endif +#ifndef RHINO_CONFIG_TIMER +#define RHINO_CONFIG_TIMER 0 +#endif +#ifndef RHINO_CONFIG_BUF_QUEUE +#define RHINO_CONFIG_BUF_QUEUE 1 +#endif +#ifndef RHINO_CONFIG_MM_BLK +#define RHINO_CONFIG_MM_BLK 0 +#endif +#ifndef RHINO_CONFIG_MM_DEBUG +#define RHINO_CONFIG_MM_DEBUG 0 +#endif + +#ifndef RHINO_CONFIG_MM_TLF +#define RHINO_CONFIG_MM_TLF 0 +#endif +#ifndef RHINO_CONFIG_MM_TLF_BLK_SIZE +#define RHINO_CONFIG_MM_TLF_BLK_SIZE 8192 +#endif +#define K_MM_STATISTIC 0 +#ifndef RHINO_CONFIG_MM_MAXMSIZEBIT +#define RHINO_CONFIG_MM_MAXMSIZEBIT 19 +#endif +#ifndef RHINO_CONFIG_GCC_RETADDR +#define RHINO_CONFIG_GCC_RETADDR 0 +#endif +#ifndef RHINO_CONFIG_MM_LEAKCHECK +#define RHINO_CONFIG_MM_LEAKCHECK 0 +#endif +#ifndef RHINO_CONFIG_RINGBUF_VENDOR +#define RHINO_CONFIG_RINGBUF_VENDOR 0 +#endif + +#ifndef RHINO_CONFIG_KOBJ_SET +#define RHINO_CONFIG_KOBJ_SET 0 +#endif + +/* kernel task conf */ +#ifndef RHINO_CONFIG_TASK_SUSPEND +#define RHINO_CONFIG_TASK_SUSPEND 1 +#endif +#ifndef RHINO_CONFIG_TASK_INFO +#define RHINO_CONFIG_TASK_INFO 0 +#endif +#ifndef RHINO_CONFIG_TASK_DEL +#define RHINO_CONFIG_TASK_DEL 1 +#endif + +#ifndef RHINO_CONFIG_TASK_STACK_CUR_CHECK +#define RHINO_CONFIG_TASK_STACK_CUR_CHECK 0 +#endif + +#ifndef RHINO_CONFIG_TASK_WAIT_ABORT +#define RHINO_CONFIG_TASK_WAIT_ABORT 0 +#endif +#ifndef RHINO_CONFIG_TASK_STACK_OVF_CHECK +#define RHINO_CONFIG_TASK_STACK_OVF_CHECK 1 +#endif +#ifndef RHINO_CONFIG_SCHED_RR +#define RHINO_CONFIG_SCHED_RR 0 +#endif +#ifndef RHINO_CONFIG_TIME_SLICE_DEFAULT +#define RHINO_CONFIG_TIME_SLICE_DEFAULT 50 +#endif +#ifndef RHINO_CONFIG_PRI_MAX +#define RHINO_CONFIG_PRI_MAX 62 +#endif +#ifndef RHINO_CONFIG_USER_PRI_MAX +#define RHINO_CONFIG_USER_PRI_MAX (RHINO_CONFIG_PRI_MAX - 2) +#endif + +/* kernel workqueue conf */ +#ifndef RHINO_CONFIG_WORKQUEUE +#define RHINO_CONFIG_WORKQUEUE 0 +#endif +#ifndef RHINO_CONFIG_WORKQUEUE_STACK_SIZE +#define RHINO_CONFIG_WORKQUEUE_STACK_SIZE 768 +#endif + +/* kernel mm_region conf */ +#ifndef RHINO_CONFIG_MM_REGION_MUTEX +#define RHINO_CONFIG_MM_REGION_MUTEX 0 +#endif + +/* kernel timer&tick conf */ +#ifndef RHINO_CONFIG_HW_COUNT +#define RHINO_CONFIG_HW_COUNT 0 +#endif +#ifndef RHINO_CONFIG_TICK_TASK +#define RHINO_CONFIG_TICK_TASK 0 +#endif + +#if (RHINO_CONFIG_TICK_TASK > 0) +#ifndef RHINO_CONFIG_TICK_TASK_STACK_SIZE +#define RHINO_CONFIG_TICK_TASK_STACK_SIZE 256 +#endif +#ifndef RHINO_CONFIG_TICK_TASK_PRI +#define RHINO_CONFIG_TICK_TASK_PRI 1 +#endif +#endif + +#ifndef RHINO_CONFIG_TICKLESS +#define RHINO_CONFIG_TICKLESS 0 +#endif +#ifndef RHINO_CONFIG_TICKS_PER_SECOND +#define RHINO_CONFIG_TICKS_PER_SECOND 100 +#endif +/* must be 2^n size!, such as 1, 2, 4, 8, 16,32, etc....... */ +#ifndef RHINO_CONFIG_TICK_HEAD_ARRAY +#define RHINO_CONFIG_TICK_HEAD_ARRAY 8 +#endif + +/*must reserve enough stack size for timer cb will consume*/ +#ifndef RHINO_CONFIG_TIMER_TASK_STACK_SIZE +#define RHINO_CONFIG_TIMER_TASK_STACK_SIZE 300 +#endif +#ifndef RHINO_CONFIG_TIMER_RATE +#define RHINO_CONFIG_TIMER_RATE 1 +#endif +#ifndef RHINO_CONFIG_TIMER_TASK_PRI +#define RHINO_CONFIG_TIMER_TASK_PRI 5 +#endif + +/* kernel intrpt conf */ +#ifndef RHINO_CONFIG_INTRPT_STACK_REMAIN_GET +#define RHINO_CONFIG_INTRPT_STACK_REMAIN_GET 0 +#endif +#ifndef RHINO_CONFIG_INTRPT_STACK_OVF_CHECK +#define RHINO_CONFIG_INTRPT_STACK_OVF_CHECK 0 +#endif +#ifndef RHINO_CONFIG_INTRPT_MAX_NESTED_LEVEL +#define RHINO_CONFIG_INTRPT_MAX_NESTED_LEVEL 188u +#endif +#ifndef RHINO_CONFIG_INTRPT_GUARD +#define RHINO_CONFIG_INTRPT_GUARD 0 +#endif + +/* kernel dyn alloc conf */ +#ifndef RHINO_CONFIG_KOBJ_DYN_ALLOC +#define RHINO_CONFIG_KOBJ_DYN_ALLOC 0 +#endif + +#if (RHINO_CONFIG_KOBJ_DYN_ALLOC > 0) +#ifndef RHINO_CONFIG_K_DYN_QUEUE_MSG +#define RHINO_CONFIG_K_DYN_QUEUE_MSG 30 +#endif +#ifndef RHINO_CONFIG_K_DYN_TASK_STACK +#define RHINO_CONFIG_K_DYN_TASK_STACK 256 +#endif +#ifndef RHINO_CONFIG_K_DYN_MEM_TASK_PRI +#define RHINO_CONFIG_K_DYN_MEM_TASK_PRI 6 +#endif +#endif + +/* kernel idle conf */ +#ifndef RHINO_CONFIG_IDLE_TASK_STACK_SIZE +#define RHINO_CONFIG_IDLE_TASK_STACK_SIZE 200 +#endif + +/* kernel hook conf */ +#ifndef RHINO_CONFIG_USER_HOOK +#define RHINO_CONFIG_USER_HOOK 0 +#endif + +/* kernel stats conf */ +#ifndef RHINO_CONFIG_SYSTEM_STATS +#define RHINO_CONFIG_SYSTEM_STATS 1 +#endif +#ifndef RHINO_CONFIG_DISABLE_SCHED_STATS +#define RHINO_CONFIG_DISABLE_SCHED_STATS 0 +#endif +#ifndef RHINO_CONFIG_DISABLE_INTRPT_STATS +#define RHINO_CONFIG_DISABLE_INTRPT_STATS 0 +#endif +#ifndef RHINO_CONFIG_CPU_USAGE_STATS +#define RHINO_CONFIG_CPU_USAGE_STATS 0 +#endif +#ifndef RHINO_CONFIG_CPU_USAGE_TASK_PRI +#define RHINO_CONFIG_CPU_USAGE_TASK_PRI (RHINO_CONFIG_PRI_MAX - 2) +#endif +#ifndef RHINO_CONFIG_TASK_SCHED_STATS +#define RHINO_CONFIG_TASK_SCHED_STATS 0 +#endif +#ifndef RHINO_CONFIG_CPU_USAGE_TASK_STACK +#define RHINO_CONFIG_CPU_USAGE_TASK_STACK 256 +#endif + +#ifndef RHINO_CONFIG_CPU_NUM +#define RHINO_CONFIG_CPU_NUM 1 +#endif + +/* kernel trace conf */ +#ifndef RHINO_CONFIG_TRACE +#define RHINO_CONFIG_TRACE 0 +#endif + +#endif /* CONFIG_H */ + diff --git a/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/deviceIO/soc_init.c b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/deviceIO/soc_init.c new file mode 100755 index 0000000000..409d39e9a4 --- /dev/null +++ b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/deviceIO/soc_init.c @@ -0,0 +1,809 @@ +/** + ****************************************************************************** + * File Name : main.c + * Description : Main program body + ****************************************************************************** + ** This notice applies to any and all portions of this file + * that are not between comment pairs USER CODE BEGIN and + * USER CODE END. Other portions of this file, whether + * inserted by the user or by software development tools + * are owned by their respective copyright owners. + * + * COPYRIGHT(c) 2017 STMicroelectronics + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 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 STMicroelectronics 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. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "soc_init.h" +#include "k_config.h" +#include "stm32l4xx_hal.h" +#include "hal.h" +#include "hal_gpio_stm32l4.h" +#include "hal_uart_stm32l4.h" +#include "hal_timer_stm32l4.h" + +#if defined (__CC_ARM) && defined(__MICROLIB) +void __aeabi_assert(const char *expr, const char *file, int line) +{ + while (1); +} +#endif + +#if defined (__CC_ARM) && defined(__MICROLIB) +#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) +#define GETCHAR_PROTOTYPE int fgetc(FILE *f) +#elif defined(__ICCARM__) +#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) +#define GETCHAR_PROTOTYPE int fgetc(FILE *f) +#else +/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf + set to 'Yes') calls __io_putchar() */ +#define PUTCHAR_PROTOTYPE int __io_putchar(int ch) +#define GETCHAR_PROTOTYPE int __io_getchar(void) +#endif /* defined (__CC_ARM) && defined(__MICROLIB) */ + + +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Private variables ---------------------------------------------------------*/ +extern UART_HandleTypeDef uart1_handle; +uart_dev_t uart_dev_com1; +gpio_dev_t gpio_dev_GPIOB_PIN13; +timer_dev_t dev_timer3; +/* USER CODE BEGIN PV */ +/* Private variables ---------------------------------------------------------*/ + +/* USER CODE END PV */ + +/* Private function prototypes -----------------------------------------------*/ +void SystemClock_Config(void); +static void uart_init(void); +static void gpio_init(void); +static void timer3_init(void); +void MX_GPIO_Init(void); +void MX_USART2_UART_Init(void); +/* USER CODE BEGIN PFP */ +/* Private function prototypes -----------------------------------------------*/ +void test_timer3(void *arg); +/* USER CODE END PFP */ + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +void stm32_soc_init(void) +{ + + /* USER CODE BEGIN 1 */ + + /* USER CODE END 1 */ + + /* MCU Configuration----------------------------------------------------------*/ + + /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ + HAL_Init(); + + /* USER CODE BEGIN Init */ + + /* USER CODE END Init */ + + /* Configure the system clock */ + SystemClock_Config(); + + /* USER CODE BEGIN SysInit */ + uart_init(); + gpio_init(); + timer3_init(); + /* USER CODE END SysInit */ +} + +/** System Clock Configuration +*/ +void SystemClock_Config(void) +{ + + RCC_OscInitTypeDef RCC_OscInitStruct; + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_PeriphCLKInitTypeDef PeriphClkInit; + + /**Initializes the CPU, AHB and APB busses clocks + */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI; + RCC_OscInitStruct.MSIState = RCC_MSI_ON; + RCC_OscInitStruct.MSICalibrationValue = 0; + RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_9; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI; + RCC_OscInitStruct.PLL.PLLM = 5; + RCC_OscInitStruct.PLL.PLLN = 71; + RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; + RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2; + RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV6; + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) + { + _Error_Handler(__FILE__, __LINE__); + } + + /**Initializes the CPU, AHB and APB busses clocks + */ + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK + |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV4; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) + { + _Error_Handler(__FILE__, __LINE__); + } + + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2; + PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) + { + _Error_Handler(__FILE__, __LINE__); + } + + /**Configure the main internal regulator output voltage + */ + if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK) + { + _Error_Handler(__FILE__, __LINE__); + } + + /**Configure the Systick interrupt time + */ + HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/RHINO_CONFIG_TICKS_PER_SECOND); + + /**Configure the Systick + */ + HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK); + + /* SysTick_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0); +} + +static void uart_init(void) +{ + uart_dev_com1.port = 1; + uart_dev_com1.config.baud_rate = 115200; + uart_dev_com1.config.data_width = DATA_WIDTH_8BIT; + uart_dev_com1.config.parity = NO_PARITY; + uart_dev_com1.config.stop_bits = STOP_BITS_1; + uart_dev_com1.config.flow_control = FLOW_CONTROL_DISABLED; + uart_dev_com1.config.mode = MODE_TX_RX; + + hal_uart_init(&uart_dev_com1); +} + +static void gpio_init(void) +{ + __HAL_RCC_GPIOB_CLK_ENABLE(); + + gpio_dev_GPIOB_PIN13.port = HAL_GPIO_29; + gpio_dev_GPIOB_PIN13.config = OUTPUT_PUSH_PULL; + + hal_gpio_init(&gpio_dev_GPIOB_PIN13); +} + +static void timer3_init(void) +{ + dev_timer3.config.reload_mode = TIMER_RELOAD_AUTO; + dev_timer3.config.period = 1000000; + dev_timer3.config.cb = &test_timer3; + dev_timer3.port = PORT_TIMER3; + + hal_timer_init(&dev_timer3); +} + +void test_timer3(void *arg) +{ + printf("timer3 is running !"); +} + +/** Configure pins as + * Analog + * Input + * Output + * EVENT_OUT + * EXTI + PE0 ------> FMC_NBL0 + PB4 (NJTRST) ------> SPI1_MISO + PA15 (JTDI) ------> SPI1_NSS + PH14 ------> DCMI_D4 + PI7 ------> DCMI_D7 + PE1 ------> FMC_NBL1 + PB5 ------> SPI1_MOSI + PG9 ------> FMC_NE2 + PD0 ------> FMC_D2_DA2 + PI6 ------> S_TIM8_CH2 + PI2 ------> SPI2_MISO + PI1 ------> SPI2_SCK + PH15 ------> TIM8_CH3N + PH12 ------> DCMI_D3 + PB8 ------> I2C1_SCL + PB6 ------> USART1_TX + PD4 ------> FMC_NOE + PD1 ------> FMC_D3_DA3 + PH13 ------> TIM8_CH1N + PE4 ------> SAI1_FS_A + PE3 ------> SAI1_SD_B + PE2 ------> SAI1_MCLK_A + PB9 ------> S_TIM4_CH4 + PB7 ------> I2C1_SDA + PG10 ------> USART1_RX + PD5 ------> FMC_NWE + PD2 ------> SDMMC1_CMD + PC10 ------> SDMMC1_D2 + PI4 ------> DCMI_D5 + PH9 ------> DCMI_D0 + PA12 ------> USB_OTG_FS_DP + PE6 ------> SAI1_SD_A + PE5 ------> DCMI_D6 + PG11 ------> USART1_CTS + PC11 ------> SDMMC1_D3 + PI5 ------> DCMI_VSYNC + PA11 ------> USB_OTG_FS_DM + PF2 ------> FMC_A2 + PF1 ------> FMC_A1 + PF0 ------> FMC_A0 + PG12 ------> USART1_RTS + PD7 ------> FMC_NE1 + PC12 ------> SDMMC1_CK + PA10 ------> USB_OTG_FS_ID + PF3 ------> FMC_A3 + PF4 ------> FMC_A4 + PF5 ------> FMC_A5 + PA8 ------> LPTIM2_OUT + PC9 ------> SDMMC1_D1 + PC8 ------> SDMMC1_D0 + PC7 ------> S_DATAIN3DFSDM1 + PF10 ------> ADC3_IN13 + PC4 ------> ADCx_IN13 + PG1 ------> FMC_A11 + PE10 ------> FMC_D7_DA7 + PB11 ------> QUADSPI_BK1_NCS + PG8 ------> LPUART1_RX + PG7 ------> LPUART1_TX + PD15 ------> FMC_D1_DA1 + PC0 ------> ADCx_IN1 + PC1 ------> ADCx_IN2 + PC2 ------> S_CKOUTDFSDM1 + PG0 ------> FMC_A10 + PE9 ------> FMC_D6_DA6 + PE15 ------> FMC_D12_DA12 + PG5 ------> FMC_A15 + PG4 ------> FMC_A14 + PG3 ------> FMC_A13 + PG2 ------> FMC_A12 + PD10 ------> FMC_D15_DA15 + PC3 ------> ADCx_IN4 + PA5 ------> SPI1_SCK + PB0 ------> QUADSPI_BK1_IO1 + PF15 ------> FMC_A9 + PE8 ------> FMC_D5_DA5 + PE14 ------> FMC_D11_DA11 + PH4 ------> I2C2_SCL + PD14 ------> FMC_D0_DA0 + PD12 ------> FMC_A17_ALE + PD11 ------> FMC_A16_CLE + PD13 ------> FMC_A18 + PA4 ------> ADCx_IN9 + PA7 ------> QUADSPI_BK1_IO2 + PB1 ------> QUADSPI_BK1_IO0 + PF14 ------> FMC_A8 + PE7 ------> FMC_D4_DA4 + PE13 ------> FMC_D10_DA10 + PH5 ------> DCMI_PIXCLK + PD9 ------> FMC_D14_DA14 + PD8 ------> FMC_D13_DA13 + PA3 ------> QUADSPI_CLK + PA6 ------> QUADSPI_BK1_IO3 + PF13 ------> FMC_A7 + PE12 ------> FMC_D9_DA9 + PH10 ------> DCMI_D1 + PH11 ------> DCMI_D2 + PB15 ------> SPI2_MOSI + PB14 ------> I2C2_SDA + PA1 ------> ADCx_IN6 + PF12 ------> FMC_A6 + PE11 ------> FMC_D8_DA8 + PB10 ------> SAI1_SCK_A + PH8 ------> DCMI_HSYNC + PB12 ------> S_DATAIN1DFSDM1 +*/ +static void MX_GPIO_Init(void) +{ + + GPIO_InitTypeDef GPIO_InitStruct; + + /* GPIO Ports Clock Enable */ + __HAL_RCC_GPIOI_CLK_ENABLE(); + __HAL_RCC_GPIOH_CLK_ENABLE(); + __HAL_RCC_GPIOE_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOG_CLK_ENABLE(); + HAL_PWREx_EnableVddIO2(); + __HAL_RCC_GPIOD_CLK_ENABLE(); + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOF_CLK_ENABLE(); + + /*Configure GPIO pin Output Level */ + HAL_GPIO_WritePin(LCD_BL_GPIO_Port, LCD_BL_Pin, GPIO_PIN_RESET); + + /*Configure GPIO pin Output Level */ + HAL_GPIO_WritePin(GPIOH, MFX_WAKEUP_Pin|LCD_PWR_ON_Pin|MIC_VDD_Pin, GPIO_PIN_RESET); + + /*Configure GPIO pin Output Level */ + HAL_GPIO_WritePin(Audio_RST_GPIO_Port, Audio_RST_Pin, GPIO_PIN_RESET); + + /*Configure GPIO pin Output Level */ + HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET); + + /*Configure GPIO pins : JOY_DOWN_Pin JOY_LEFT_Pin JOY_UP_Pin */ + GPIO_InitStruct.Pin = JOY_DOWN_Pin|JOY_LEFT_Pin|JOY_UP_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_PULLDOWN; + HAL_GPIO_Init(GPIOI, &GPIO_InitStruct); + + /*Configure GPIO pin : STMOD_INT_Pin */ + GPIO_InitStruct.Pin = STMOD_INT_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(STMOD_INT_GPIO_Port, &GPIO_InitStruct); + + /*Configure GPIO pins : PSRAM_NBL0_Pin PSRAM_NBL1_Pin D7_Pin D6_Pin + D12_Pin D5_Pin D11_Pin D4_Pin + D10_Pin D9_Pin D8_Pin */ + GPIO_InitStruct.Pin = PSRAM_NBL0_Pin|PSRAM_NBL1_Pin|D7_Pin|D6_Pin + |D12_Pin|D5_Pin|D11_Pin|D4_Pin + |D10_Pin|D9_Pin|D8_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF12_FMC; + HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); + + /*Configure GPIO pins : ARD_D12_Pin ARD_D11_Pin */ + GPIO_InitStruct.Pin = ARD_D12_Pin|ARD_D11_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF5_SPI1; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /*Configure GPIO pins : ARD_D10_Pin ARD_D13_Pin */ + GPIO_InitStruct.Pin = ARD_D10_Pin|ARD_D13_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF5_SPI1; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /*Configure GPIO pin : LCD_BL_Pin */ + GPIO_InitStruct.Pin = LCD_BL_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(LCD_BL_GPIO_Port, &GPIO_InitStruct); + + /*Configure GPIO pins : DCMI_D4_Pin DCMI_D3_Pin DCMI_D0_Pin DCMI_PIXCK_Pin + DCMI_D1_Pin DCMI_D2_Pin DCMI_HSYNC_Pin */ + GPIO_InitStruct.Pin = DCMI_D4_Pin|DCMI_D3_Pin|DCMI_D0_Pin|DCMI_PIXCK_Pin + |DCMI_D1_Pin|DCMI_D2_Pin|DCMI_HSYNC_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF10_DCMI; + HAL_GPIO_Init(GPIOH, &GPIO_InitStruct); + + /*Configure GPIO pins : DCMI_D7_Pin DCMI_D5_Pin DCMI_VSYNC_Pin */ + GPIO_InitStruct.Pin = DCMI_D7_Pin|DCMI_D5_Pin|DCMI_VSYNC_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF10_DCMI; + HAL_GPIO_Init(GPIOI, &GPIO_InitStruct); + + /*Configure GPIO pins : PSRAM_NE_Pin PSRAM_A11_Pin PSRAM_A10_Pin PSRAM_A15_Pin + PSRAM_A14_Pin PSRAM_A13_Pin PSRAM_A12_Pin */ + GPIO_InitStruct.Pin = PSRAM_NE_Pin|PSRAM_A11_Pin|PSRAM_A10_Pin|PSRAM_A15_Pin + |PSRAM_A14_Pin|PSRAM_A13_Pin|PSRAM_A12_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF12_FMC; + HAL_GPIO_Init(GPIOG, &GPIO_InitStruct); + + /*Configure GPIO pins : D2_Pin OE_Pin D3_Pin WE_Pin + LCD_NE_Pin D1_Pin D15_Pin D0_Pin + PSRAM_A17_Pin PSRAM_A16_Pin PSRAM_A18_LCD_RS_Pin D14_Pin + D13_Pin */ + GPIO_InitStruct.Pin = D2_Pin|OE_Pin|D3_Pin|WE_Pin + |LCD_NE_Pin|D1_Pin|D15_Pin|D0_Pin + |PSRAM_A17_Pin|PSRAM_A16_Pin|PSRAM_A18_LCD_RS_Pin|D14_Pin + |D13_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF12_FMC; + HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); + + /*Configure GPIO pin : ARD_D6_Pin */ + GPIO_InitStruct.Pin = ARD_D6_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF3_TIM8; + HAL_GPIO_Init(ARD_D6_GPIO_Port, &GPIO_InitStruct); + + /*Configure GPIO pins : SPI2_MISO_Pin SPI2_CLK_Pin */ + GPIO_InitStruct.Pin = SPI2_MISO_Pin|SPI2_CLK_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF5_SPI2; + HAL_GPIO_Init(GPIOI, &GPIO_InitStruct); + + /*Configure GPIO pins : ARD_D3_Pin ARD_D9_Pin */ + GPIO_InitStruct.Pin = ARD_D3_Pin|ARD_D9_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF3_TIM8; + HAL_GPIO_Init(GPIOH, &GPIO_InitStruct); + + /*Configure GPIO pins : I2C1_SCL_Pin I2C1_SDA_Pin */ + GPIO_InitStruct.Pin = I2C1_SCL_Pin|I2C1_SDA_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF4_I2C1; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /*Configure GPIO pin : USART1_TX_Pin */ + GPIO_InitStruct.Pin = USART1_TX_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF7_USART1; + HAL_GPIO_Init(USART1_TX_GPIO_Port, &GPIO_InitStruct); + + /*Configure GPIO pins : SAI1_FSA_Pin SAI1_SDB_Pin SAI1_MCKA_Pin SAI1_SDA_Pin */ + GPIO_InitStruct.Pin = SAI1_FSA_Pin|SAI1_SDB_Pin|SAI1_MCKA_Pin|SAI1_SDA_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF13_SAI1; + HAL_GPIO_Init(GPIOE, &GPIO_InitStruct); + + /*Configure GPIO pin : ARD_D5_Pin */ + GPIO_InitStruct.Pin = ARD_D5_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF2_TIM4; + HAL_GPIO_Init(ARD_D5_GPIO_Port, &GPIO_InitStruct); + + /*Configure GPIO pins : UART1_RX_Pin UART1_CTS_Pin UART1_RTS_Pin */ + GPIO_InitStruct.Pin = UART1_RX_Pin|UART1_CTS_Pin|UART1_RTS_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF7_USART1; + HAL_GPIO_Init(GPIOG, &GPIO_InitStruct); + + /*Configure GPIO pin : uSD_CMD_Pin */ + GPIO_InitStruct.Pin = uSD_CMD_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF12_SDMMC1; + HAL_GPIO_Init(uSD_CMD_GPIO_Port, &GPIO_InitStruct); + + /*Configure GPIO pins : uSD_D2_Pin uSD_D3_Pin uSD_CLK_Pin uSD_D1_Pin + uSD_D0_Pin */ + GPIO_InitStruct.Pin = uSD_D2_Pin|uSD_D3_Pin|uSD_CLK_Pin|uSD_D1_Pin + |uSD_D0_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF12_SDMMC1; + HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + /*Configure GPIO pin : LCD_TE_Pin */ + GPIO_InitStruct.Pin = LCD_TE_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(LCD_TE_GPIO_Port, &GPIO_InitStruct); + + /*Configure GPIO pins : USB_OTGFS_DP_Pin USB_OTGFS_DM_Pin USB_OTGFS_ID_Pin */ + GPIO_InitStruct.Pin = USB_OTGFS_DP_Pin|USB_OTGFS_DM_Pin|USB_OTGFS_ID_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /*Configure GPIO pin : DCMI_D6_Pin */ + GPIO_InitStruct.Pin = DCMI_D6_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF10_DCMI; + HAL_GPIO_Init(DCMI_D6_GPIO_Port, &GPIO_InitStruct); + + /*Configure GPIO pins : MFX_WAKEUP_Pin LCD_PWR_ON_Pin MIC_VDD_Pin */ + GPIO_InitStruct.Pin = MFX_WAKEUP_Pin|LCD_PWR_ON_Pin|MIC_VDD_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(GPIOH, &GPIO_InitStruct); + + /*Configure GPIO pins : PSRAM_A2_Pin PSRAM_A1_Pin PSRAM_A0_Pin PSRAM_A3_Pin + PSRAM_A4_Pin PSRAM_A5_Pin PSRAM_A9_Pin PSRAM_A8_Pin + PSRAM_A7_Pin PSRAM_A6_Pin */ + GPIO_InitStruct.Pin = PSRAM_A2_Pin|PSRAM_A1_Pin|PSRAM_A0_Pin|PSRAM_A3_Pin + |PSRAM_A4_Pin|PSRAM_A5_Pin|PSRAM_A9_Pin|PSRAM_A8_Pin + |PSRAM_A7_Pin|PSRAM_A6_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF12_FMC; + HAL_GPIO_Init(GPIOF, &GPIO_InitStruct); + + /*Configure GPIO pin : Audio_RST_Pin */ + GPIO_InitStruct.Pin = Audio_RST_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(Audio_RST_GPIO_Port, &GPIO_InitStruct); + + /*Configure GPIO pin : CTP_INT_Pin */ + GPIO_InitStruct.Pin = CTP_INT_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(CTP_INT_GPIO_Port, &GPIO_InitStruct); + + /*Configure GPIO pin : DCMI_CLK_Pin */ + GPIO_InitStruct.Pin = DCMI_CLK_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF14_LPTIM2; + HAL_GPIO_Init(DCMI_CLK_GPIO_Port, &GPIO_InitStruct); + + /*Configure GPIO pins : DATIN3_Pin DF_CKOUT_Pin */ + GPIO_InitStruct.Pin = DATIN3_Pin|DF_CKOUT_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF6_DFSDM1; + HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + /*Configure GPIO pin : ARD_A3_Pin */ + GPIO_InitStruct.Pin = ARD_A3_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_ANALOG_ADC_CONTROL; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(ARD_A3_GPIO_Port, &GPIO_InitStruct); + + /*Configure GPIO pins : ARD_A0_Pin ARD_A5_Pin PC1 ARD_A2_Pin */ + GPIO_InitStruct.Pin = ARD_A0_Pin|ARD_A5_Pin|GPIO_PIN_1|ARD_A2_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_ANALOG_ADC_CONTROL; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); + + /*Configure GPIO pins : QSPI_BK1_NCS_Pin QSPI_BK1_IO1_Pin QSPI_BK1_IO0_Pin */ + GPIO_InitStruct.Pin = QSPI_BK1_NCS_Pin|QSPI_BK1_IO1_Pin|QSPI_BK1_IO0_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF10_QUADSPI; + HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); + + /*Configure GPIO pins : ARD_D0_Pin ARD_D1_Pin */ + GPIO_InitStruct.Pin = ARD_D0_Pin|ARD_D1_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF8_LPUART1; + HAL_GPIO_Init(GPIOG, &GPIO_InitStruct); + + /*Configure GPIO pin : MFX_IRQ_OUT_Pin */ + GPIO_InitStruct.Pin = MFX_IRQ_OUT_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(MFX_IRQ_OUT_GPIO_Port, &GPIO_InitStruct); + + /*Configure GPIO pin : I2C2_SCL_Pin */ + GPIO_InitStruct.Pin = I2C2_SCL_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF4_I2C2; + HAL_GPIO_Init(I2C2_SCL_GPIO_Port, &GPIO_InitStruct); + + /*Configure GPIO pins : STMOD_ADC_Pin ARD_A4_Pin */ + GPIO_InitStruct.Pin = STMOD_ADC_Pin|ARD_A4_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_ANALOG_ADC_CONTROL; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /*Configure GPIO pins : QSPI_BK1_IO2_Pin QSPI_CLK_Pin QSPI_BK1_IO3_Pin */ + GPIO_InitStruct.Pin = QSPI_BK1_IO2_Pin|QSPI_CLK_Pin|QSPI_BK1_IO3_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF10_QUADSPI; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + /*Configure GPIO pin : JOY_RIGHT_Pin */ + GPIO_InitStruct.Pin = JOY_RIGHT_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_PULLDOWN; + HAL_GPIO_Init(JOY_RIGHT_GPIO_Port, &GPIO_InitStruct); + + /*Configure GPIO pin : SPI2_MOSI_Pin */ + GPIO_InitStruct.Pin = SPI2_MOSI_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF5_SPI2; + HAL_GPIO_Init(SPI2_MOSI_GPIO_Port, &GPIO_InitStruct); + + /*Configure GPIO pin : I2C2_SDA_Pin */ + GPIO_InitStruct.Pin = I2C2_SDA_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF4_I2C2; + HAL_GPIO_Init(I2C2_SDA_GPIO_Port, &GPIO_InitStruct); + + /*Configure GPIO pin : STMOD_RESET_Pin */ + GPIO_InitStruct.Pin = STMOD_RESET_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_NOPULL; + HAL_GPIO_Init(STMOD_RESET_GPIO_Port, &GPIO_InitStruct); + + /*Configure GPIO pin : SAI1_CKA_Pin */ + GPIO_InitStruct.Pin = SAI1_CKA_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF13_SAI1; + HAL_GPIO_Init(SAI1_CKA_GPIO_Port, &GPIO_InitStruct); + + /*Configure GPIO pin : DFDATIN1_Pin */ + GPIO_InitStruct.Pin = DFDATIN1_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStruct.Alternate = GPIO_AF6_DFSDM1; + HAL_GPIO_Init(DFDATIN1_GPIO_Port, &GPIO_InitStruct); + + /*Configure GPIO pin : LED1_Pin */ + GPIO_InitStruct.Pin = LED1_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; + HAL_GPIO_Init(LED1_GPIO_Port, &GPIO_InitStruct); + +} + +/* USER CODE BEGIN 4 */ + +/* USER CODE END 4 */ + +/** + * @brief This function is executed in case of error occurrence. + * @param None + * @retval None + */ +void _Error_Handler(char * file, int line) +{ + /* USER CODE BEGIN Error_Handler_Debug */ + /* User can add his own implementation to report the HAL error return state */ + while(1) + { + } + /* USER CODE END Error_Handler_Debug */ +} + +#ifdef USE_FULL_ASSERT + +/** + * @brief Reports the name of the source file and the source line number + * where the assert_param error has occurred. + * @param file: pointer to the source file name + * @param line: assert_param error line source number + * @retval None + */ +void assert_failed(uint8_t* file, uint32_t line) +{ + /* USER CODE BEGIN 6 */ + /* User can add his own implementation to report the file name and line number, + ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ + /* USER CODE END 6 */ + +} + +#endif + +HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority) +{ + /*Configure the SysTick to have interrupt in 1ms time basis*/ + HAL_SYSTICK_Config(SystemCoreClock/RHINO_CONFIG_TICKS_PER_SECOND); + + /*Configure the SysTick IRQ priority */ + HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority ,0U); + + /* Return function status */ + return HAL_OK; +} + +/** + * @brief Retargets the C library printf function to the USART. + * @param None + * @retval None + */ +PUTCHAR_PROTOTYPE +{ + if (ch == '\n') { + //hal_uart_send(&console_uart, (void *)"\r", 1, 30000); + HAL_UART_Transmit(&uart1_handle, (void *)"\r", 1,30000); + } + HAL_UART_Transmit(&uart1_handle, (uint8_t *)&ch, 1, 0xFFFF); + return ch; +} + +/** + * @brief Retargets the C library scanf function to the USART. + * @param None + * @retval None + */ +GETCHAR_PROTOTYPE +{ + /* Place your implementation of fgetc here */ + /* e.g. readwrite a character to the USART2 and Loop until the end of transmission */ + uint8_t ch = 0; + //uint32_t recv_size; + HAL_UART_Receive(&uart1_handle, &ch, 1,30000); + return ch; +} + +/** + * @} + */ + +/** + * @} +*/ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/deviceIO/soc_init.h b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/deviceIO/soc_init.h new file mode 100755 index 0000000000..a53c6bf2cc --- /dev/null +++ b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/deviceIO/soc_init.h @@ -0,0 +1,333 @@ +/** + ****************************************************************************** + * File Name : main.hpp + * Description : This file contains the common defines of the application + ****************************************************************************** + ** This notice applies to any and all portions of this file + * that are not between comment pairs USER CODE BEGIN and + * USER CODE END. Other portions of this file, whether + * inserted by the user or by software development tools + * are owned by their respective copyright owners. + * + * COPYRIGHT(c) 2017 STMicroelectronics + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 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 STMicroelectronics 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. + * + ****************************************************************************** + */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __SOC_INIT_H +#define __SOC_INIT_H + /* Includes ------------------------------------------------------------------*/ + +/* Includes ------------------------------------------------------------------*/ +/* USER CODE BEGIN Includes */ + +/* USER CODE END Includes */ + +/* Private define ------------------------------------------------------------*/ + +#define JOY_DOWN_Pin GPIO_PIN_10 +#define JOY_DOWN_GPIO_Port GPIOI +#define STMOD_INT_Pin GPIO_PIN_2 +#define STMOD_INT_GPIO_Port GPIOH +#define PSRAM_NBL0_Pin GPIO_PIN_0 +#define PSRAM_NBL0_GPIO_Port GPIOE +#define ARD_D12_Pin GPIO_PIN_4 +#define ARD_D12_GPIO_Port GPIOB +#define SWO_Pin GPIO_PIN_3 +#define SWO_GPIO_Port GPIOB +#define ARD_D10_Pin GPIO_PIN_15 +#define ARD_D10_GPIO_Port GPIOA +#define SWCLK_Pin GPIO_PIN_14 +#define SWCLK_GPIO_Port GPIOA +#define SWDIO_Pin GPIO_PIN_13 +#define SWDIO_GPIO_Port GPIOA +#define LCD_BL_Pin GPIO_PIN_0 +#define LCD_BL_GPIO_Port GPIOI +#define DCMI_D4_Pin GPIO_PIN_14 +#define DCMI_D4_GPIO_Port GPIOH +#define JOY_LEFT_Pin GPIO_PIN_9 +#define JOY_LEFT_GPIO_Port GPIOI +#define DCMI_D7_Pin GPIO_PIN_7 +#define DCMI_D7_GPIO_Port GPIOI +#define PSRAM_NBL1_Pin GPIO_PIN_1 +#define PSRAM_NBL1_GPIO_Port GPIOE +#define ARD_D11_Pin GPIO_PIN_5 +#define ARD_D11_GPIO_Port GPIOB +#define PSRAM_NE_Pin GPIO_PIN_9 +#define PSRAM_NE_GPIO_Port GPIOG +#define D2_Pin GPIO_PIN_0 +#define D2_GPIO_Port GPIOD +#define ARD_D6_Pin GPIO_PIN_6 +#define ARD_D6_GPIO_Port GPIOI +#define SPI2_MISO_Pin GPIO_PIN_2 +#define SPI2_MISO_GPIO_Port GPIOI +#define SPI2_CLK_Pin GPIO_PIN_1 +#define SPI2_CLK_GPIO_Port GPIOI +#define ARD_D3_Pin GPIO_PIN_15 +#define ARD_D3_GPIO_Port GPIOH +#define DCMI_D3_Pin GPIO_PIN_12 +#define DCMI_D3_GPIO_Port GPIOH +#define I2C1_SCL_Pin GPIO_PIN_8 +#define I2C1_SCL_GPIO_Port GPIOB +#define USART1_TX_Pin GPIO_PIN_6 +#define USART1_TX_GPIO_Port GPIOB +#define OE_Pin GPIO_PIN_4 +#define OE_GPIO_Port GPIOD +#define D3_Pin GPIO_PIN_1 +#define D3_GPIO_Port GPIOD +#define ARD_D9_Pin GPIO_PIN_13 +#define ARD_D9_GPIO_Port GPIOH +#define JOY_UP_Pin GPIO_PIN_8 +#define JOY_UP_GPIO_Port GPIOI +#define SAI1_FSA_Pin GPIO_PIN_4 +#define SAI1_FSA_GPIO_Port GPIOE +#define SAI1_SDB_Pin GPIO_PIN_3 +#define SAI1_SDB_GPIO_Port GPIOE +#define SAI1_MCKA_Pin GPIO_PIN_2 +#define SAI1_MCKA_GPIO_Port GPIOE +#define ARD_D5_Pin GPIO_PIN_9 +#define ARD_D5_GPIO_Port GPIOB +#define I2C1_SDA_Pin GPIO_PIN_7 +#define I2C1_SDA_GPIO_Port GPIOB +#define UART1_RX_Pin GPIO_PIN_10 +#define UART1_RX_GPIO_Port GPIOG +#define WE_Pin GPIO_PIN_5 +#define WE_GPIO_Port GPIOD +#define uSD_CMD_Pin GPIO_PIN_2 +#define uSD_CMD_GPIO_Port GPIOD +#define uSD_D2_Pin GPIO_PIN_10 +#define uSD_D2_GPIO_Port GPIOC +#define DCMI_D5_Pin GPIO_PIN_4 +#define DCMI_D5_GPIO_Port GPIOI +#define DCMI_D0_Pin GPIO_PIN_9 +#define DCMI_D0_GPIO_Port GPIOH +#define LCD_TE_Pin GPIO_PIN_7 +#define LCD_TE_GPIO_Port GPIOH +#define USB_OTGFS_DP_Pin GPIO_PIN_12 +#define USB_OTGFS_DP_GPIO_Port GPIOA +#define JOY_SEL_Pin GPIO_PIN_13 +#define JOY_SEL_GPIO_Port GPIOC +#define SAI1_SDA_Pin GPIO_PIN_6 +#define SAI1_SDA_GPIO_Port GPIOE +#define DCMI_D6_Pin GPIO_PIN_5 +#define DCMI_D6_GPIO_Port GPIOE +#define UART1_CTS_Pin GPIO_PIN_11 +#define UART1_CTS_GPIO_Port GPIOG +#define USART2_RX_Pin GPIO_PIN_6 +#define USART2_RX_GPIO_Port GPIOD +#define uSD_D3_Pin GPIO_PIN_11 +#define uSD_D3_GPIO_Port GPIOC +#define DCMI_VSYNC_Pin GPIO_PIN_5 +#define DCMI_VSYNC_GPIO_Port GPIOI +#define MFX_WAKEUP_Pin GPIO_PIN_6 +#define MFX_WAKEUP_GPIO_Port GPIOH +#define USB_OTGFS_DM_Pin GPIO_PIN_11 +#define USB_OTGFS_DM_GPIO_Port GPIOA +#define PSRAM_A2_Pin GPIO_PIN_2 +#define PSRAM_A2_GPIO_Port GPIOF +#define PSRAM_A1_Pin GPIO_PIN_1 +#define PSRAM_A1_GPIO_Port GPIOF +#define PSRAM_A0_Pin GPIO_PIN_0 +#define PSRAM_A0_GPIO_Port GPIOF +#define UART1_RTS_Pin GPIO_PIN_12 +#define UART1_RTS_GPIO_Port GPIOG +#define LCD_NE_Pin GPIO_PIN_7 +#define LCD_NE_GPIO_Port GPIOD +#define uSD_CLK_Pin GPIO_PIN_12 +#define uSD_CLK_GPIO_Port GPIOC +#define USB_OTGFS_ID_Pin GPIO_PIN_10 +#define USB_OTGFS_ID_GPIO_Port GPIOA +#define USB_OTGFS_VBUS_Pin GPIO_PIN_9 +#define USB_OTGFS_VBUS_GPIO_Port GPIOA +#define Audio_RST_Pin GPIO_PIN_6 +#define Audio_RST_GPIO_Port GPIOC +#define PSRAM_A3_Pin GPIO_PIN_3 +#define PSRAM_A3_GPIO_Port GPIOF +#define PSRAM_A4_Pin GPIO_PIN_4 +#define PSRAM_A4_GPIO_Port GPIOF +#define PSRAM_A5_Pin GPIO_PIN_5 +#define PSRAM_A5_GPIO_Port GPIOF +#define CTP_INT_Pin GPIO_PIN_14 +#define CTP_INT_GPIO_Port GPIOG +#define DCMI_CLK_Pin GPIO_PIN_8 +#define DCMI_CLK_GPIO_Port GPIOA +#define uSD_D1_Pin GPIO_PIN_9 +#define uSD_D1_GPIO_Port GPIOC +#define uSD_D0_Pin GPIO_PIN_8 +#define uSD_D0_GPIO_Port GPIOC +#define DATIN3_Pin GPIO_PIN_7 +#define DATIN3_GPIO_Port GPIOC +#define LCD_PWR_ON_Pin GPIO_PIN_0 +#define LCD_PWR_ON_GPIO_Port GPIOH +#define ARD_A3_Pin GPIO_PIN_10 +#define ARD_A3_GPIO_Port GPIOF +#define ARD_A0_Pin GPIO_PIN_4 +#define ARD_A0_GPIO_Port GPIOC +#define PSRAM_A11_Pin GPIO_PIN_1 +#define PSRAM_A11_GPIO_Port GPIOG +#define D7_Pin GPIO_PIN_10 +#define D7_GPIO_Port GPIOE +#define QSPI_BK1_NCS_Pin GPIO_PIN_11 +#define QSPI_BK1_NCS_GPIO_Port GPIOB +#define ARD_D0_Pin GPIO_PIN_8 +#define ARD_D0_GPIO_Port GPIOG +#define ARD_D1_Pin GPIO_PIN_7 +#define ARD_D1_GPIO_Port GPIOG +#define D1_Pin GPIO_PIN_15 +#define D1_GPIO_Port GPIOD +#define MIC_VDD_Pin GPIO_PIN_1 +#define MIC_VDD_GPIO_Port GPIOH +#define ARD_A5_Pin GPIO_PIN_0 +#define ARD_A5_GPIO_Port GPIOC +#define DF_CKOUT_Pin GPIO_PIN_2 +#define DF_CKOUT_GPIO_Port GPIOC +#define MFX_IRQ_OUT_Pin GPIO_PIN_5 +#define MFX_IRQ_OUT_GPIO_Port GPIOC +#define PSRAM_A10_Pin GPIO_PIN_0 +#define PSRAM_A10_GPIO_Port GPIOG +#define D6_Pin GPIO_PIN_9 +#define D6_GPIO_Port GPIOE +#define D12_Pin GPIO_PIN_15 +#define D12_GPIO_Port GPIOE +#define PSRAM_A15_Pin GPIO_PIN_5 +#define PSRAM_A15_GPIO_Port GPIOG +#define PSRAM_A14_Pin GPIO_PIN_4 +#define PSRAM_A14_GPIO_Port GPIOG +#define PSRAM_A13_Pin GPIO_PIN_3 +#define PSRAM_A13_GPIO_Port GPIOG +#define PSRAM_A12_Pin GPIO_PIN_2 +#define PSRAM_A12_GPIO_Port GPIOG +#define D15_Pin GPIO_PIN_10 +#define D15_GPIO_Port GPIOD +#define ARD_A2_Pin GPIO_PIN_3 +#define ARD_A2_GPIO_Port GPIOC +#define STMOD_PWM_Pin GPIO_PIN_0 +#define STMOD_PWM_GPIO_Port GPIOA +#define ARD_D13_Pin GPIO_PIN_5 +#define ARD_D13_GPIO_Port GPIOA +#define QSPI_BK1_IO1_Pin GPIO_PIN_0 +#define QSPI_BK1_IO1_GPIO_Port GPIOB +#define PSRAM_A9_Pin GPIO_PIN_15 +#define PSRAM_A9_GPIO_Port GPIOF +#define D5_Pin GPIO_PIN_8 +#define D5_GPIO_Port GPIOE +#define D11_Pin GPIO_PIN_14 +#define D11_GPIO_Port GPIOE +#define I2C2_SCL_Pin GPIO_PIN_4 +#define I2C2_SCL_GPIO_Port GPIOH +#define D0_Pin GPIO_PIN_14 +#define D0_GPIO_Port GPIOD +#define PSRAM_A17_Pin GPIO_PIN_12 +#define PSRAM_A17_GPIO_Port GPIOD +#define PSRAM_A16_Pin GPIO_PIN_11 +#define PSRAM_A16_GPIO_Port GPIOD +#define PSRAM_A18_LCD_RS_Pin GPIO_PIN_13 +#define PSRAM_A18_LCD_RS_GPIO_Port GPIOD +#define STMOD_ADC_Pin GPIO_PIN_4 +#define STMOD_ADC_GPIO_Port GPIOA +#define QSPI_BK1_IO2_Pin GPIO_PIN_7 +#define QSPI_BK1_IO2_GPIO_Port GPIOA +#define QSPI_BK1_IO0_Pin GPIO_PIN_1 +#define QSPI_BK1_IO0_GPIO_Port GPIOB +#define PSRAM_A8_Pin GPIO_PIN_14 +#define PSRAM_A8_GPIO_Port GPIOF +#define D4_Pin GPIO_PIN_7 +#define D4_GPIO_Port GPIOE +#define D10_Pin GPIO_PIN_13 +#define D10_GPIO_Port GPIOE +#define DCMI_PIXCK_Pin GPIO_PIN_5 +#define DCMI_PIXCK_GPIO_Port GPIOH +#define D14_Pin GPIO_PIN_9 +#define D14_GPIO_Port GPIOD +#define D13_Pin GPIO_PIN_8 +#define D13_GPIO_Port GPIOD +#define QSPI_CLK_Pin GPIO_PIN_3 +#define QSPI_CLK_GPIO_Port GPIOA +#define QSPI_BK1_IO3_Pin GPIO_PIN_6 +#define QSPI_BK1_IO3_GPIO_Port GPIOA +#define JOY_RIGHT_Pin GPIO_PIN_11 +#define JOY_RIGHT_GPIO_Port GPIOF +#define PSRAM_A7_Pin GPIO_PIN_13 +#define PSRAM_A7_GPIO_Port GPIOF +#define D9_Pin GPIO_PIN_12 +#define D9_GPIO_Port GPIOE +#define DCMI_D1_Pin GPIO_PIN_10 +#define DCMI_D1_GPIO_Port GPIOH +#define DCMI_D2_Pin GPIO_PIN_11 +#define DCMI_D2_GPIO_Port GPIOH +#define SPI2_MOSI_Pin GPIO_PIN_15 +#define SPI2_MOSI_GPIO_Port GPIOB +#define I2C2_SDA_Pin GPIO_PIN_14 +#define I2C2_SDA_GPIO_Port GPIOB +#define USART2_TX_Pin GPIO_PIN_2 +#define USART2_TX_GPIO_Port GPIOA +#define ARD_A4_Pin GPIO_PIN_1 +#define ARD_A4_GPIO_Port GPIOA +#define STMOD_RESET_Pin GPIO_PIN_2 +#define STMOD_RESET_GPIO_Port GPIOB +#define PSRAM_A6_Pin GPIO_PIN_12 +#define PSRAM_A6_GPIO_Port GPIOF +#define D8_Pin GPIO_PIN_11 +#define D8_GPIO_Port GPIOE +#define SAI1_CKA_Pin GPIO_PIN_10 +#define SAI1_CKA_GPIO_Port GPIOB +#define DCMI_HSYNC_Pin GPIO_PIN_8 +#define DCMI_HSYNC_GPIO_Port GPIOH +#define DFDATIN1_Pin GPIO_PIN_12 +#define DFDATIN1_GPIO_Port GPIOB +#define LED1_Pin GPIO_PIN_13 +#define LED1_GPIO_Port GPIOB + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1U */ + +/* USER CODE BEGIN Private defines */ + +/* USER CODE END Private defines */ + +#ifdef __cplusplus + extern "C" { +#endif +void _Error_Handler(char *, int); + +#define Error_Handler() _Error_Handler(__FILE__, __LINE__) +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +/** + * @} +*/ + +#endif /* __SOC_INIT_H */ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/deviceIO/stm32l4xx_hal_conf.h b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/deviceIO/stm32l4xx_hal_conf.h new file mode 100755 index 0000000000..f6d0eeb057 --- /dev/null +++ b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/deviceIO/stm32l4xx_hal_conf.h @@ -0,0 +1,430 @@ +/** + ****************************************************************************** + * @file stm32l4xx_hal_conf.h + * @brief HAL configuration file. + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2017 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 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 STMicroelectronics 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. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32L4xx_HAL_CONF_H +#define __STM32L4xx_HAL_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +#include "soc_init.h" +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ + +#define HAL_MODULE_ENABLED +#define HAL_ADC_MODULE_ENABLED +/*#define HAL_CRYP_MODULE_ENABLED */ +/*#define HAL_CAN_MODULE_ENABLED */ +/*#define HAL_COMP_MODULE_ENABLED */ +/*#define HAL_CRC_MODULE_ENABLED */ +/*#define HAL_CRYP_MODULE_ENABLED */ +/*#define HAL_DAC_MODULE_ENABLED */ +/*#define HAL_DCMI_MODULE_ENABLED */ +/*#define HAL_DMA2D_MODULE_ENABLED */ +/*#define HAL_DFSDM_MODULE_ENABLED */ +/*#define HAL_DSI_MODULE_ENABLED */ +/*#define HAL_FIREWALL_MODULE_ENABLED */ +/*#define HAL_GFXMMU_MODULE_ENABLED */ +/*#define HAL_HCD_MODULE_ENABLED */ +/*#define HAL_HASH_MODULE_ENABLED */ +/*#define HAL_I2S_MODULE_ENABLED */ +/*#define HAL_IRDA_MODULE_ENABLED */ +/*#define HAL_IWDG_MODULE_ENABLED */ +/*#define HAL_LTDC_MODULE_ENABLED */ +/*#define HAL_LCD_MODULE_ENABLED */ +/*#define HAL_LPTIM_MODULE_ENABLED */ +/*#define HAL_NAND_MODULE_ENABLED */ +/*#define HAL_NOR_MODULE_ENABLED */ +/*#define HAL_OPAMP_MODULE_ENABLED */ +/*#define HAL_OSPI_MODULE_ENABLED */ +/*#define HAL_OSPI_MODULE_ENABLED */ +/*#define HAL_PCD_MODULE_ENABLED */ +/*#define HAL_QSPI_MODULE_ENABLED */ +/*#define HAL_QSPI_MODULE_ENABLED */ +/*#define HAL_RNG_MODULE_ENABLED */ +#define HAL_RTC_MODULE_ENABLED +/*#define HAL_SAI_MODULE_ENABLED */ +/*#define HAL_SD_MODULE_ENABLED */ +/*#define HAL_SMBUS_MODULE_ENABLED */ +/*#define HAL_SMARTCARD_MODULE_ENABLED */ +#define HAL_SPI_MODULE_ENABLED +/*#define HAL_SRAM_MODULE_ENABLED */ +/*#define HAL_SWPMI_MODULE_ENABLED */ +#define HAL_TIM_MODULE_ENABLED +/*#define HAL_TSC_MODULE_ENABLED */ +#define HAL_UART_MODULE_ENABLED +/*#define HAL_USART_MODULE_ENABLED */ +/*#define HAL_WWDG_MODULE_ENABLED */ +#define HAL_GPIO_MODULE_ENABLED +#define HAL_I2C_MODULE_ENABLED +#define HAL_DMA_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED +#define HAL_FLASH_MODULE_ENABLED +#define HAL_PWR_MODULE_ENABLED +#define HAL_CORTEX_MODULE_ENABLED + +/* ########################## Oscillator Values adaptation ####################*/ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined (HSE_VALUE) + #define HSE_VALUE ((uint32_t)8000000U) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSE_STARTUP_TIMEOUT) + #define HSE_STARTUP_TIMEOUT ((uint32_t)100U) /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal Multiple Speed oscillator (MSI) default value. + * This value is the default MSI range value after Reset. + */ +#if !defined (MSI_VALUE) + #define MSI_VALUE ((uint32_t)24000000U) /*!< Value of the Internal oscillator in Hz*/ +#endif /* MSI_VALUE */ +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) + #define HSI_VALUE ((uint32_t)16000000U) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief Internal High Speed oscillator (HSI48) value for USB FS, SDMMC and RNG. + * This internal oscillator is mainly dedicated to provide a high precision clock to + * the USB peripheral by means of a special Clock Recovery System (CRS) circuitry. + * When the CRS is not used, the HSI48 RC oscillator runs on it default frequency + * which is subject to manufacturing process variations. + */ +#if !defined (HSI48_VALUE) + #define HSI48_VALUE ((uint32_t)48000000U) /*!< Value of the Internal High Speed oscillator for USB FS/SDMMC/RNG in Hz. + The real value my vary depending on manufacturing process variations.*/ +#endif /* HSI48_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined (LSI_VALUE) + #define LSI_VALUE ((uint32_t)32000U) /*!< LSI Typical Value in Hz*/ +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations + in voltage and temperature.*/ + +/** + * @brief External Low Speed oscillator (LSE) value. + * This value is used by the UART, RTC HAL module to compute the system frequency + */ +#if !defined (LSE_VALUE) + #define LSE_VALUE ((uint32_t)32768U) /*!< Value of the External oscillator in Hz*/ +#endif /* LSE_VALUE */ + +#if !defined (LSE_STARTUP_TIMEOUT) + #define LSE_STARTUP_TIMEOUT ((uint32_t)5000U) /*!< Time out for LSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief External clock source for SAI1 peripheral + * This value is used by the RCC HAL module to compute the SAI1 & SAI2 clock source + * frequency. + */ +#if !defined (EXTERNAL_SAI1_CLOCK_VALUE) + #define EXTERNAL_SAI1_CLOCK_VALUE ((uint32_t)2097000U) /*!< Value of the SAI1 External clock source in Hz*/ +#endif /* EXTERNAL_SAI1_CLOCK_VALUE */ + +/** + * @brief External clock source for SAI2 peripheral + * This value is used by the RCC HAL module to compute the SAI1 & SAI2 clock source + * frequency. + */ +#if !defined (EXTERNAL_SAI2_CLOCK_VALUE) + #define EXTERNAL_SAI2_CLOCK_VALUE ((uint32_t)2097000U) /*!< Value of the SAI2 External clock source in Hz*/ +#endif /* EXTERNAL_SAI2_CLOCK_VALUE */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ + +#define VDD_VALUE ((uint32_t)3300U) /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY ((uint32_t)0U) /*!< tick interrupt priority */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 0U +#define INSTRUCTION_CACHE_ENABLE 1U +#define DATA_CACHE_ENABLE 1U + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1U */ + +/* ################## SPI peripheral configuration ########################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver + * Activated: CRC code is present inside driver + * Deactivated: CRC code cleaned from driver + */ + +#define USE_SPI_CRC 0U + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED + #include "stm32l4xx_hal_rcc.h" + #include "stm32l4xx_hal_rcc_ex.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED + #include "stm32l4xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED + #include "stm32l4xx_hal_dma.h" + #include "stm32l4xx_hal_dma_ex.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_DFSDM_MODULE_ENABLED + #include "stm32l4xx_hal_dfsdm.h" +#endif /* HAL_DFSDM_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + #include "stm32l4xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED + #include "stm32l4xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_CAN_MODULE_ENABLED + #include "stm32l4xx_hal_can.h" +#endif /* HAL_CAN_MODULE_ENABLED */ + +#ifdef HAL_COMP_MODULE_ENABLED + #include "stm32l4xx_hal_comp.h" +#endif /* HAL_COMP_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED + #include "stm32l4xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED + #include "stm32l4xx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED + #include "stm32l4xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_DCMI_MODULE_ENABLED + #include "stm32l4xx_hal_dcmi.h" +#endif /* HAL_DCMI_MODULE_ENABLED */ + +#ifdef HAL_DMA2D_MODULE_ENABLED + #include "stm32l4xx_hal_dma2d.h" +#endif /* HAL_DMA2D_MODULE_ENABLED */ + +#ifdef HAL_DSI_MODULE_ENABLED + #include "stm32l4xx_hal_dsi.h" +#endif /* HAL_DSI_MODULE_ENABLED */ + +#ifdef HAL_FIREWALL_MODULE_ENABLED + #include "stm32l4xx_hal_firewall.h" +#endif /* HAL_FIREWALL_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED + #include "stm32l4xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_HASH_MODULE_ENABLED + #include "stm32l4xx_hal_hash.h" +#endif /* HAL_HASH_MODULE_ENABLED */ + +#ifdef HAL_SRAM_MODULE_ENABLED + #include "stm32l4xx_hal_sram.h" +#endif /* HAL_SRAM_MODULE_ENABLED */ + +#ifdef HAL_NOR_MODULE_ENABLED + #include "stm32l4xx_hal_nor.h" +#endif /* HAL_NOR_MODULE_ENABLED */ + +#ifdef HAL_NAND_MODULE_ENABLED + #include "stm32l4xx_hal_nand.h" +#endif /* HAL_NAND_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED + #include "stm32l4xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED + #include "stm32l4xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_LCD_MODULE_ENABLED + #include "stm32l4xx_hal_lcd.h" +#endif /* HAL_LCD_MODULE_ENABLED */ + +#ifdef HAL_LPTIM_MODULE_ENABLED + #include "stm32l4xx_hal_lptim.h" +#endif /* HAL_LPTIM_MODULE_ENABLED */ + +#ifdef HAL_LTDC_MODULE_ENABLED + #include "stm32l4xx_hal_ltdc.h" +#endif /* HAL_LTDC_MODULE_ENABLED */ + +#ifdef HAL_OPAMP_MODULE_ENABLED + #include "stm32l4xx_hal_opamp.h" +#endif /* HAL_OPAMP_MODULE_ENABLED */ + +#ifdef HAL_OSPI_MODULE_ENABLED + #include "stm32l4xx_hal_ospi.h" +#endif /* HAL_OSPI_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED + #include "stm32l4xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_QSPI_MODULE_ENABLED + #include "stm32l4xx_hal_qspi.h" +#endif /* HAL_QSPI_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED + #include "stm32l4xx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED + #include "stm32l4xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SAI_MODULE_ENABLED + #include "stm32l4xx_hal_sai.h" +#endif /* HAL_SAI_MODULE_ENABLED */ + +#ifdef HAL_SD_MODULE_ENABLED + #include "stm32l4xx_hal_sd.h" +#endif /* HAL_SD_MODULE_ENABLED */ + +#ifdef HAL_SMBUS_MODULE_ENABLED + #include "stm32l4xx_hal_smbus.h" +#endif /* HAL_SMBUS_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED + #include "stm32l4xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_SWPMI_MODULE_ENABLED + #include "stm32l4xx_hal_swpmi.h" +#endif /* HAL_SWPMI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED + #include "stm32l4xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_TSC_MODULE_ENABLED + #include "stm32l4xx_hal_tsc.h" +#endif /* HAL_TSC_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED + #include "stm32l4xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED + #include "stm32l4xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED + #include "stm32l4xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED + #include "stm32l4xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED + #include "stm32l4xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED + #include "stm32l4xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_HCD_MODULE_ENABLED + #include "stm32l4xx_hal_hcd.h" +#endif /* HAL_HCD_MODULE_ENABLED */ + +#ifdef HAL_GFXMMU_MODULE_ENABLED + #include "stm32l4xx_hal_gfxmmu.h" +#endif /* HAL_GFXMMU_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr: If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ + #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ + void assert_failed(uint8_t* file, uint32_t line); +#else + #define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32L4xx_HAL_CONF_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/deviceIO/stm32l4xx_hal_msp.c b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/deviceIO/stm32l4xx_hal_msp.c new file mode 100755 index 0000000000..a51c47eaad --- /dev/null +++ b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/deviceIO/stm32l4xx_hal_msp.c @@ -0,0 +1,180 @@ +/** + ****************************************************************************** + * File Name : stm32l4xx_hal_msp.c + * Description : This file provides code for the MSP Initialization + * and de-Initialization codes. + ****************************************************************************** + ** This notice applies to any and all portions of this file + * that are not between comment pairs USER CODE BEGIN and + * USER CODE END. Other portions of this file, whether + * inserted by the user or by software development tools + * are owned by their respective copyright owners. + * + * COPYRIGHT(c) 2017 STMicroelectronics + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 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 STMicroelectronics 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. + * + ****************************************************************************** + */ +/* Includes ------------------------------------------------------------------*/ +#include "stm32l4xx_hal.h" + +extern void _Error_Handler(char *, int); +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ +/** + * Initializes the Global MSP. + */ +void HAL_MspInit(void) +{ + /* USER CODE BEGIN MspInit 0 */ + + /* USER CODE END MspInit 0 */ + + __HAL_RCC_SYSCFG_CLK_ENABLE(); + __HAL_RCC_PWR_CLK_ENABLE(); + + HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4); + + /* System interrupt init*/ + /* MemoryManagement_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(MemoryManagement_IRQn, 0, 0); + /* BusFault_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(BusFault_IRQn, 0, 0); + /* UsageFault_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(UsageFault_IRQn, 0, 0); + /* SVCall_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(SVCall_IRQn, 0, 0); + /* DebugMonitor_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(DebugMonitor_IRQn, 0, 0); + /* PendSV_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(PendSV_IRQn, 0, 0); + /* SysTick_IRQn interrupt configuration */ + HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0); + + /* USER CODE BEGIN MspInit 1 */ + + /* USER CODE END MspInit 1 */ +} + +void HAL_UART_MspInit(UART_HandleTypeDef* huart) +{ + + GPIO_InitTypeDef GPIO_InitStruct; + if(huart->Instance==USART2) + { + /* USER CODE BEGIN USART2_MspInit 0 */ + + /* USER CODE END USART2_MspInit 0 */ + /* Peripheral clock enable */ + __HAL_RCC_USART2_CLK_ENABLE(); + + /**USART2 GPIO Configuration + PD6 ------> USART2_RX + PA2 ------> USART2_TX + */ + GPIO_InitStruct.Pin = USART2_RX_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF7_USART2; + HAL_GPIO_Init(USART2_RX_GPIO_Port, &GPIO_InitStruct); + + GPIO_InitStruct.Pin = USART2_TX_Pin; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_PULLUP; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF7_USART2; + HAL_GPIO_Init(USART2_TX_GPIO_Port, &GPIO_InitStruct); + + /* USER CODE BEGIN USART2_MspInit 1 */ + + /* USER CODE END USART2_MspInit 1 */ + } + +} + +void HAL_UART_MspDeInit(UART_HandleTypeDef* huart) +{ + + if(huart->Instance==USART2) + { + /* USER CODE BEGIN USART2_MspDeInit 0 */ + + /* USER CODE END USART2_MspDeInit 0 */ + /* Peripheral clock disable */ + __HAL_RCC_USART2_CLK_DISABLE(); + + /**USART2 GPIO Configuration + PD6 ------> USART2_RX + PA2 ------> USART2_TX + */ + HAL_GPIO_DeInit(USART2_RX_GPIO_Port, USART2_RX_Pin); + + HAL_GPIO_DeInit(USART2_TX_GPIO_Port, USART2_TX_Pin); + + /* USER CODE BEGIN USART2_MspDeInit 1 */ + + /* USER CODE END USART2_MspDeInit 1 */ + } + +} + +/** + * @brief TIM MSP Initialization + * This function configures the hardware resources used in this example: + * - Peripheral's clock enable + * @param htim: TIM handle pointer + * @retval None + */ +void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim) +{ + if (htim->Instance == TIM3) + { + /*##-1- Enable peripheral clock #################################*/ + /* TIMx Peripheral clock enable */ + __HAL_RCC_TIM3_CLK_ENABLE(); + + /*##-2- Configure the NVIC for TIMx ########################################*/ + /* Set the TIMx priority */ + HAL_NVIC_SetPriority(TIM3_IRQn, 3, 0); + + /* Enable the TIMx global Interrupt */ + HAL_NVIC_EnableIRQ(TIM3_IRQn); + } +} + +/* USER CODE BEGIN 1 */ + +/* USER CODE END 1 */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/deviceIO/stm32l4xx_it.c b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/deviceIO/stm32l4xx_it.c new file mode 100755 index 0000000000..de1532434d --- /dev/null +++ b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/deviceIO/stm32l4xx_it.c @@ -0,0 +1,143 @@ +/** + ****************************************************************************** + * @file stm32l4xx_it.c + * @brief Interrupt Service Routines. + ****************************************************************************** + * + * COPYRIGHT(c) 2017 STMicroelectronics + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 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 STMicroelectronics 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. + * + ****************************************************************************** + */ +/* Includes ------------------------------------------------------------------*/ +#include "stm32l4xx_hal.h" +#include "stm32l4xx.h" +#include "stm32l4xx_it.h" +#include "hal.h" +#include "k_api.h" + +/* USER CODE BEGIN 0 */ + +/* USER CODE END 0 */ + +/* External variables --------------------------------------------------------*/ + +/******************************************************************************/ +/* Cortex-M4 Processor Interruption and Exception Handlers */ +/******************************************************************************/ + +/** +* @brief This function handles Non maskable Interrupt. +*/ +void NMI_Handler(void) +{ + +} + +/** +* @brief This function handles Hard fault interrupt. +*/ +void HardFault_Handler(void) +{ + while (1) + { + } +} + +/** +* @brief This function handles Memory management fault. +*/ +void MemManage_Handler(void) +{ + while (1) + { + } +} + +/** +* @brief This function handles Prefetch fault, memory access fault. +*/ +void BusFault_Handler(void) +{ + while (1) + { + } +} + +/** +* @brief This function handles Undefined instruction or illegal state. +*/ +void UsageFault_Handler(void) +{ + while (1) + { + } +} + +/** +* @brief This function handles System service call via SWI instruction. +*/ +void SVC_Handler(void) +{ + +} + +/** +* @brief This function handles Debug monitor. +*/ +void DebugMon_Handler(void) +{ + +} + +extern UART_HandleTypeDef uart1_handle; + +/** +* @brief This function handles System tick timer. +*/ +void SysTick_Handler(void) +{ + HAL_IncTick(); + krhino_intrpt_enter(); + krhino_tick_proc(); + krhino_intrpt_exit(); +} + +/******************************************************************************/ +/* STM32L4xx Peripheral Interrupt Handlers */ +/* Add here the Interrupt Handlers for the used peripherals. */ +/* For the available peripheral interrupt handler names, */ +/* please refer to the startup file (startup_stm32l4xx.s). */ +/******************************************************************************/ + +/* USER CODE BEGIN 1 */ +void USART2_IRQHandler(void) +{ + krhino_intrpt_enter(); + HAL_UART_IRQHandler(&uart1_handle); + krhino_intrpt_exit(); +} + +/* USER CODE END 1 */ +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/deviceIO/stm32l4xx_it.h b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/deviceIO/stm32l4xx_it.h new file mode 100755 index 0000000000..807c58408f --- /dev/null +++ b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/deviceIO/stm32l4xx_it.h @@ -0,0 +1,66 @@ +/** + ****************************************************************************** + * @file stm32l4xx_it.h + * @brief This file contains the headers of the interrupt handlers. + ****************************************************************************** + * + * COPYRIGHT(c) 2017 STMicroelectronics + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 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 STMicroelectronics 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. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32L4xx_IT_H +#define __STM32L4xx_IT_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32l4xx_hal.h" +#include "soc_init.h" +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +void NMI_Handler(void); +void HardFault_Handler(void); +void MemManage_Handler(void); +void BusFault_Handler(void); +void UsageFault_Handler(void); +void SVC_Handler(void); +void DebugMon_Handler(void); +void PendSV_Handler(void); +void SysTick_Handler(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32L4xx_IT_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/deviceIO/system_stm32l4xx.c b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/deviceIO/system_stm32l4xx.c new file mode 100755 index 0000000000..c76fe45ee1 --- /dev/null +++ b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/deviceIO/system_stm32l4xx.c @@ -0,0 +1,353 @@ +/** + ****************************************************************************** + * @file system_stm32l4xx.c + * @author MCD Application Team + * @brief CMSIS Cortex-M4 Device Peripheral Access Layer System Source File + * + * This file provides two functions and one global variable to be called from + * user application: + * - SystemInit(): This function is called at startup just after reset and + * before branch to main program. This call is made inside + * the "startup_stm32l4xx.s" file. + * + * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used + * by the user application to setup the SysTick + * timer or configure other parameters. + * + * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must + * be called whenever the core clock is changed + * during program execution. + * + * After each device reset the MSI (4 MHz) is used as system clock source. + * Then SystemInit() function is called, in "startup_stm32l4xx.s" file, to + * configure the system clock before to branch to main program. + * + * This file configures the system clock as follows: + *============================================================================= + *----------------------------------------------------------------------------- + * System Clock source | MSI + *----------------------------------------------------------------------------- + * SYSCLK(Hz) | 4000000 + *----------------------------------------------------------------------------- + * HCLK(Hz) | 4000000 + *----------------------------------------------------------------------------- + * AHB Prescaler | 1 + *----------------------------------------------------------------------------- + * APB1 Prescaler | 1 + *----------------------------------------------------------------------------- + * APB2 Prescaler | 1 + *----------------------------------------------------------------------------- + * PLL_M | 1 + *----------------------------------------------------------------------------- + * PLL_N | 8 + *----------------------------------------------------------------------------- + * PLL_P | 7 + *----------------------------------------------------------------------------- + * PLL_Q | 2 + *----------------------------------------------------------------------------- + * PLL_R | 2 + *----------------------------------------------------------------------------- + * PLLSAI1_P | NA + *----------------------------------------------------------------------------- + * PLLSAI1_Q | NA + *----------------------------------------------------------------------------- + * PLLSAI1_R | NA + *----------------------------------------------------------------------------- + * PLLSAI2_P | NA + *----------------------------------------------------------------------------- + * PLLSAI2_Q | NA + *----------------------------------------------------------------------------- + * PLLSAI2_R | NA + *----------------------------------------------------------------------------- + * Require 48MHz for USB OTG FS, | Disabled + * SDIO and RNG clock | + *----------------------------------------------------------------------------- + *============================================================================= + ****************************************************************************** + * @attention + * + *

© COPYRIGHT(c) 2017 STMicroelectronics

+ * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * 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 STMicroelectronics nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************** + */ + +/** @addtogroup CMSIS + * @{ + */ + +/** @addtogroup stm32l4xx_system + * @{ + */ + +/** @addtogroup STM32L4xx_System_Private_Includes + * @{ + */ + +#include "stm32l4xx.h" + +#if !defined (HSE_VALUE) + #define HSE_VALUE 8000000U /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (MSI_VALUE) + #define MSI_VALUE 4000000U /*!< Value of the Internal oscillator in Hz*/ +#endif /* MSI_VALUE */ + +#if !defined (HSI_VALUE) + #define HSI_VALUE 16000000U /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @} + */ + +/** @addtogroup STM32L4xx_System_Private_TypesDefinitions + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32L4xx_System_Private_Defines + * @{ + */ + +/************************* Miscellaneous Configuration ************************/ +/*!< Uncomment the following line if you need to relocate your vector Table in + Internal SRAM. */ +/* #define VECT_TAB_SRAM */ +#define VECT_TAB_OFFSET 0x00 /*!< Vector Table base offset field. + This value must be a multiple of 0x200. */ +/******************************************************************************/ +/** + * @} + */ + +/** @addtogroup STM32L4xx_System_Private_Macros + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32L4xx_System_Private_Variables + * @{ + */ + /* The SystemCoreClock variable is updated in three ways: + 1) by calling CMSIS function SystemCoreClockUpdate() + 2) by calling HAL API function HAL_RCC_GetHCLKFreq() + 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency + Note: If you use this function to configure the system clock; then there + is no need to call the 2 first functions listed above, since SystemCoreClock + variable is updated automatically. + */ + uint32_t SystemCoreClock = 4000000U; + + const uint8_t AHBPrescTable[16] = {0U, 0U, 0U, 0U, 0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U, 6U, 7U, 8U, 9U}; + const uint8_t APBPrescTable[8] = {0U, 0U, 0U, 0U, 1U, 2U, 3U, 4U}; + const uint32_t MSIRangeTable[12] = {100000U, 200000U, 400000U, 800000U, 1000000U, 2000000U, \ + 4000000U, 8000000U, 16000000U, 24000000U, 32000000U, 48000000U}; +/** + * @} + */ + +/** @addtogroup STM32L4xx_System_Private_FunctionPrototypes + * @{ + */ + +/** + * @} + */ + +/** @addtogroup STM32L4xx_System_Private_Functions + * @{ + */ + +/** + * @brief Setup the microcontroller system. + * @param None + * @retval None + */ + +void SystemInit(void) +{ + /* FPU settings ------------------------------------------------------------*/ + #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */ + #endif + + /* Reset the RCC clock configuration to the default reset state ------------*/ + /* Set MSION bit */ + RCC->CR |= RCC_CR_MSION; + + /* Reset CFGR register */ + RCC->CFGR = 0x00000000U; + + /* Reset HSEON, CSSON , HSION, and PLLON bits */ + RCC->CR &= 0xEAF6FFFFU; + + /* Reset PLLCFGR register */ + RCC->PLLCFGR = 0x00001000U; + + /* Reset HSEBYP bit */ + RCC->CR &= 0xFFFBFFFFU; + + /* Disable all interrupts */ + RCC->CIER = 0x00000000U; + + /* Configure the Vector Table location add offset address ------------------*/ +#ifdef VECT_TAB_SRAM + SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */ +#else + SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */ +#endif +} + +/** + * @brief Update SystemCoreClock variable according to Clock Register Values. + * The SystemCoreClock variable contains the core clock (HCLK), it can + * be used by the user application to setup the SysTick timer or configure + * other parameters. + * + * @note Each time the core clock (HCLK) changes, this function must be called + * to update SystemCoreClock variable value. Otherwise, any configuration + * based on this variable will be incorrect. + * + * @note - The system frequency computed by this function is not the real + * frequency in the chip. It is calculated based on the predefined + * constant and the selected clock source: + * + * - If SYSCLK source is MSI, SystemCoreClock will contain the MSI_VALUE(*) + * + * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(**) + * + * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***) + * + * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(***) + * or HSI_VALUE(*) or MSI_VALUE(*) multiplied/divided by the PLL factors. + * + * (*) MSI_VALUE is a constant defined in stm32l4xx_hal.h file (default value + * 4 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * + * (**) HSI_VALUE is a constant defined in stm32l4xx_hal.h file (default value + * 16 MHz) but the real value may vary depending on the variations + * in voltage and temperature. + * + * (***) HSE_VALUE is a constant defined in stm32l4xx_hal.h file (default value + * 8 MHz), user has to ensure that HSE_VALUE is same as the real + * frequency of the crystal used. Otherwise, this function may + * have wrong result. + * + * - The result of this function could be not correct when using fractional + * value for HSE crystal. + * + * @param None + * @retval None + */ +void SystemCoreClockUpdate(void) +{ + uint32_t tmp = 0U, msirange = 0U, pllvco = 0U, pllr = 2U, pllsource = 0U, pllm = 2U; + + /* Get MSI Range frequency--------------------------------------------------*/ + if((RCC->CR & RCC_CR_MSIRGSEL) == RESET) + { /* MSISRANGE from RCC_CSR applies */ + msirange = (RCC->CSR & RCC_CSR_MSISRANGE) >> 8U; + } + else + { /* MSIRANGE from RCC_CR applies */ + msirange = (RCC->CR & RCC_CR_MSIRANGE) >> 4U; + } + /*MSI frequency range in HZ*/ + msirange = MSIRangeTable[msirange]; + + /* Get SYSCLK source -------------------------------------------------------*/ + switch (RCC->CFGR & RCC_CFGR_SWS) + { + case 0x00: /* MSI used as system clock source */ + SystemCoreClock = msirange; + break; + + case 0x04: /* HSI used as system clock source */ + SystemCoreClock = HSI_VALUE; + break; + + case 0x08: /* HSE used as system clock source */ + SystemCoreClock = HSE_VALUE; + break; + + case 0x0C: /* PLL used as system clock source */ + /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLM) * PLLN + SYSCLK = PLL_VCO / PLLR + */ + pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC); + pllm = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLM) >> 4U) + 1U ; + + switch (pllsource) + { + case 0x02: /* HSI used as PLL clock source */ + pllvco = (HSI_VALUE / pllm); + break; + + case 0x03: /* HSE used as PLL clock source */ + pllvco = (HSE_VALUE / pllm); + break; + + default: /* MSI used as PLL clock source */ + pllvco = (msirange / pllm); + break; + } + pllvco = pllvco * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 8U); + pllr = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 25U) + 1U) * 2U; + SystemCoreClock = pllvco/pllr; + break; + + default: + SystemCoreClock = msirange; + break; + } + /* Compute HCLK clock frequency --------------------------------------------*/ + /* Get HCLK prescaler */ + tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4U)]; + /* HCLK clock frequency */ + SystemCoreClock >>= tmp; +} + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/hal/hal_adc_stm32l4.c b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/hal/hal_adc_stm32l4.c new file mode 100755 index 0000000000..76c716875c --- /dev/null +++ b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/hal/hal_adc_stm32l4.c @@ -0,0 +1,150 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#include +#include +#include +#include "stm32l4xx_hal.h" +#include "soc_init.h" +#include "hal.h" +#include "stm32l4xx_hal.h" +#include "hal_adc_stm32l4.h" +#include "stm32l4xx_hal_adc.h" + +/* Init and deInit function for adc1 */ +static int32_t adc1_init(adc_dev_t *uart); +static int32_t adc1_DeInit(void); +static void adc1_MspInit(void); +static void adc1_DeMspInit(void); + +/* function used to transform hal para to stm32l4 para */ +int32_t get_adc_Instance(adc_dev_t *adc, ADC_TypeDef **ADCx); +uint16_t get_adc_channel(uint8_t port); + +/* handle for adc */ +ADC_HandleTypeDef adc1_handle; +ADC_ChannelConfTypeDef adc1_sConfig; + +int32_t hal_adc_init(adc_dev_t *adc) +{ + int32_t ret = -1; + + if (adc == NULL) { + return -1; + } + + /*init adc handle*/ + memset(&adc1_handle, 0, sizeof(adc1_handle)); + memset(&adc1_sConfig, 0, sizeof(adc1_sConfig)); + + switch (adc->port) { + case PORT_ADC1: + adc->priv = &adc1_handle; + ret = adc1_init(adc); + break; + + /* if ohter adc exist add init code here */ + + default: + break; + } + + return ret; +} + +int32_t hal_adc_value_get(adc_dev_t *adc, void *output, uint32_t timeout) +{ + int32_t ret = -1; + uint16_t *value = (uint16_t *)output; + + ret = HAL_ADC_PollForConversion((ADC_HandleTypeDef*)adc->priv, timeout); + if (ret == 0) { + *value = HAL_ADC_GetValue((ADC_HandleTypeDef*)adc->priv); + } + + return ret; +} + +int32_t hal_adc_finalize(adc_dev_t *adc) +{ + int32_t ret = -1; + + if (adc == NULL) { + return -1; + } + + switch (adc->port) { + case PORT_ADC1: + ret = adc1_DeInit(); + break; + /* if other adc exist add Deinit code here */ + + default: + break; + } + + return ret; +} + +int32_t adc1_init(adc_dev_t *adc) +{ + ADC_TypeDef *adc_instance = NULL; + int32_t ret = 0; + + ret = get_adc_Instance(adc, &adc_instance); + adc1_handle.Instance = adc_instance; + + /* Initialize other parameters in struction ADC_InitTypeDef */ + + ret = HAL_ADC_Init(&adc1_handle); + if (ret != 0) { + return -1; + } + + adc1_MspInit(); + + adc1_sConfig.Channel = get_adc_channel(adc->port); + /* Initialize other parameters in struction ADC_ChannelConfTypeDef */ + + ret = HAL_ADC_ConfigChannel(&adc1_handle, &adc1_sConfig); + + return ret; +} + +int32_t adc1_DeInit(void) +{ + int32_t ret = -1; + + /* adc1 deinitialization */ + ret = HAL_ADC_DeInit(&adc1_handle); + adc1_DeMspInit(); + + return ret; +} + +void adc1_MspInit(void) +{ + /* Initialize adc-related pins */ + + /* Initialize interrupts if necessary */ +} + +void adc1_DeMspInit(void) +{ + /* Disable adc-related pins */ + + /* Disable interrupts if necessary */ +} + +int32_t get_adc_Instance(adc_dev_t *adc, ADC_TypeDef **ADCx) +{ + /* Get adc instance according to adc->port */ + return 0; +} + +uint16_t get_adc_channel(uint8_t port) +{ + /* Get adc channel according to adc->port */ + return 0; +} diff --git a/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/hal/hal_adc_stm32l4.h b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/hal/hal_adc_stm32l4.h new file mode 100755 index 0000000000..703cf7da09 --- /dev/null +++ b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/hal/hal_adc_stm32l4.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#ifndef __HAL_ADC_STM32L4_H +#define __HAL_ADC_STM32L4_H + +#ifdef __cplusplus + extern "C" { +#endif + +#include "stm32l4xx_hal.h" +#include +#include +#include +#include +#include "aos/kernel.h" + +#define PORT_ADC1 1 +#define PORT_ADC2 2 +#define PORT_ADC3 3 +#define PORT_ADC4 4 +#define PORT_ADC5 5 +#define PORT_ADC6 6 +#define PORT_ADC7 7 +#define PORT_ADC8 8 + +#ifdef __cplusplus +} +#endif + +#endif /* __HAL_UART_STM32L4_H */ diff --git a/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/hal/hal_gpio_stm32l4.c b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/hal/hal_gpio_stm32l4.c new file mode 100755 index 0000000000..a467e12edf --- /dev/null +++ b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/hal/hal_gpio_stm32l4.c @@ -0,0 +1,202 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#include +#include +#include +#include "stm32l4xx_hal.h" +#include "soc_init.h" +#include "hal.h" +#include "stm32l4xx_hal.h" +#include "hal_gpio_stm32l4.h" + +static int32_t gpio_para_transform(gpio_dev_t *gpio, GPIO_InitTypeDef * init_str); +static int32_t get_gpio_group(gpio_dev_t *gpio, GPIO_TypeDef **GPIOx); +static uint16_t get_gpio_pin(uint8_t pin); +static GPIO_InitTypeDef GPIO_InitStruct; + +int32_t hal_gpio_init(gpio_dev_t *gpio) +{ + int32_t ret = -1; + GPIO_TypeDef *GPIOx = NULL; + + if (gpio == NULL) { + return -1; + } + + ret = get_gpio_group(gpio, &GPIOx); + if (ret == 0) { + ret = gpio_para_transform(gpio, &GPIO_InitStruct); + if (ret == 0) { + GPIO_InitStruct.Pin = get_gpio_pin(gpio->port); + HAL_GPIO_Init(GPIOx, &GPIO_InitStruct); + } + } + + return ret; +} + +int32_t hal_gpio_output_high(gpio_dev_t *gpio) +{ + uint16_t pin = 0; + GPIO_TypeDef* GPIOx = NULL; + int32_t ret = 0; + + if (gpio == NULL) { + return -1; + } + + ret = get_gpio_group(gpio, &GPIOx); + if (ret == 0) { + pin = get_gpio_pin(gpio->port); + HAL_GPIO_WritePin(GPIOx, pin, GPIO_PIN_SET); + }; + + return ret; +} + +int32_t hal_gpio_output_low(gpio_dev_t *gpio) +{ + uint16_t pin = 0; + GPIO_TypeDef* GPIOx = NULL; + int32_t ret = 0; + + if (gpio == NULL) { + return -1; + } + + ret = get_gpio_group(gpio, &GPIOx); + if (ret == 0) { + pin = get_gpio_pin(gpio->port); + HAL_GPIO_WritePin(GPIOx, pin, GPIO_PIN_RESET); + }; + + return ret; +} + +int32_t hal_gpio_output_toggle(gpio_dev_t *gpio) +{ + uint16_t pin = 0; + GPIO_TypeDef* GPIOx = NULL; + int32_t ret = 0; + + if (gpio == NULL) { + return -1; + } + + ret = get_gpio_group(gpio, &GPIOx); + if (ret == 0) { + pin = get_gpio_pin(gpio->port); + HAL_GPIO_TogglePin(GPIOx, pin); + }; + + return ret; +} + +int32_t hal_gpio_input_get(gpio_dev_t *gpio, uint32_t *value) +{ + uint16_t pin = 0; + GPIO_TypeDef* GPIOx = NULL; + int32_t ret = 0; + + if (gpio == NULL) { + return -1; + } + + ret = get_gpio_group(gpio, &GPIOx); + if (ret == 0) { + pin = gpio->port % PINS_IN_GROUP; + *value = HAL_GPIO_ReadPin(GPIOx, pin); + }; + + return ret; +} + +int32_t gpio_para_transform(gpio_dev_t *gpio, GPIO_InitTypeDef * init_str) +{ + int32_t ret = 0; + + switch (gpio->config) { + case ANALOG_MODE: + init_str->Mode = GPIO_MODE_ANALOG; + break; + case INPUT_PULL_UP: + init_str->Mode = GPIO_MODE_INPUT; + init_str->Pull = GPIO_PULLUP; + break; + case INPUT_PULL_DOWN: + init_str->Mode = GPIO_MODE_INPUT; + init_str->Pull = GPIO_PULLDOWN; + break; + case INPUT_HIGH_IMPEDANCE: + init_str->Mode = GPIO_MODE_INPUT; + init_str->Pull = GPIO_NOPULL; + break; + case OUTPUT_PUSH_PULL: + init_str->Mode = GPIO_MODE_OUTPUT_PP; + init_str->Pull = GPIO_PULLUP; + break; + case OUTPUT_OPEN_DRAIN_NO_PULL: + init_str->Mode = GPIO_MODE_OUTPUT_OD; + init_str->Pull = GPIO_NOPULL; + break; + case OUTPUT_OPEN_DRAIN_PULL_UP: + init_str->Mode = GPIO_MODE_OUTPUT_OD; + init_str->Pull = GPIO_PULLUP; + break; + default: + ret = -1; + break; + } + + return ret; +} + +int32_t get_gpio_group(gpio_dev_t *gpio, GPIO_TypeDef **GPIOx) +{ + uint16_t group = 0; + int32_t ret = 0; + + if (gpio == NULL) { + return -1; + } + + group = gpio->port / PINS_IN_GROUP; + + switch (group) { + case GROUP_GPIOA: + *GPIOx = GPIOA; + break; + case GROUP_GPIOB: + *GPIOx = GPIOB; + break; + case GROUP_GPIOC: + *GPIOx = GPIOC; + break; + case GROUP_GPIOD: + *GPIOx = GPIOD; + break; + case GROUP_GPIOE: + *GPIOx = GPIOE; + break; + default: + ret = -1; + break; + } + + return ret; +} + +uint16_t get_gpio_pin(uint8_t pin) +{ + uint16_t i = 0; + uint16_t result = 1; + uint8_t pin_t = pin % PINS_IN_GROUP; + + for (i = 0; i < pin_t; i++) { + result *= 2; + } + + return result; +} diff --git a/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/hal/hal_gpio_stm32l4.h b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/hal/hal_gpio_stm32l4.h new file mode 100755 index 0000000000..bb625c2acf --- /dev/null +++ b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/hal/hal_gpio_stm32l4.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#ifndef __HAL_GPIO_STM32L4_H +#define __HAL_GPIO_STM32L4_H + +#ifdef __cplusplus + extern "C" { +#endif + +#include "stm32l4xx_hal.h" +#include +#include +#include +#include +#include "aos/kernel.h" + +#define PINS_IN_GROUP 16 +#define GROUP_GPIOA 0 +#define GROUP_GPIOB 1 +#define GROUP_GPIOC 2 +#define GROUP_GPIOD 3 +#define GROUP_GPIOE 4 + +#define HAL_GPIO_0 ((uint8_t)0) /* represent GPIOA pin 0 */ +#define HAL_GPIO_1 ((uint8_t)1) /* represent GPIOA pin 1 */ +#define HAL_GPIO_2 ((uint8_t)2) /* represent GPIOA pin 2 */ +#define HAL_GPIO_3 ((uint8_t)3) /* represent GPIOA pin 3 */ +#define HAL_GPIO_4 ((uint8_t)4) /* represent GPIOA pin 4 */ +#define HAL_GPIO_5 ((uint8_t)5) /* represent GPIOA pin 5 */ +#define HAL_GPIO_6 ((uint8_t)6) /* represent GPIOA pin 6 */ +#define HAL_GPIO_7 ((uint8_t)7) /* represent GPIOA pin 7 */ +#define HAL_GPIO_8 ((uint8_t)8) /* represent GPIOA pin 8 */ +#define HAL_GPIO_9 ((uint8_t)9) /* represent GPIOA pin 9 */ +#define HAL_GPIO_10 ((uint8_t)10) /* represent GPIOA pin 10 */ +#define HAL_GPIO_11 ((uint8_t)11) /* represent GPIOA pin 11 */ +#define HAL_GPIO_12 ((uint8_t)12) /* represent GPIOA pin 12 */ +#define HAL_GPIO_13 ((uint8_t)13) /* represent GPIOA pin 13 */ +#define HAL_GPIO_14 ((uint8_t)14) /* represent GPIOA pin 14 */ +#define HAL_GPIO_15 ((uint8_t)15) /* represent GPIOA pin 15 */ + +#define HAL_GPIO_16 ((uint8_t)16) /* represent GPIOB pin 0 */ +#define HAL_GPIO_17 ((uint8_t)17) /* represent GPIOB pin 1 */ +#define HAL_GPIO_18 ((uint8_t)18) /* represent GPIOB pin 2 */ +#define HAL_GPIO_19 ((uint8_t)19) /* represent GPIOB pin 3 */ +#define HAL_GPIO_20 ((uint8_t)20) /* represent GPIOB pin 4 */ +#define HAL_GPIO_21 ((uint8_t)21) /* represent GPIOB pin 5 */ +#define HAL_GPIO_22 ((uint8_t)22) /* represent GPIOB pin 6 */ +#define HAL_GPIO_23 ((uint8_t)23) /* represent GPIOB pin 7 */ +#define HAL_GPIO_24 ((uint8_t)24) /* represent GPIOB pin 8 */ +#define HAL_GPIO_25 ((uint8_t)25) /* represent GPIOB pin 9 */ +#define HAL_GPIO_26 ((uint8_t)26) /* represent GPIOB pin 10 */ +#define HAL_GPIO_27 ((uint8_t)27) /* represent GPIOB pin 11 */ +#define HAL_GPIO_28 ((uint8_t)28) /* represent GPIOB pin 12 */ +#define HAL_GPIO_29 ((uint8_t)29) /* represent GPIOB pin 13 */ +#define HAL_GPIO_30 ((uint8_t)30) /* represent GPIOB pin 14 */ +#define HAL_GPIO_31 ((uint8_t)31) /* represent GPIOB pin 15 */ + +#define GPIOA_SPEED GPIO_SPEED_FREQ_VERY_HIGH + +#ifdef __cplusplus +} +#endif + +#endif /* __HAL_GPIO_STM32L4_H */ diff --git a/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/hal/hal_i2c_stm32l4.c b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/hal/hal_i2c_stm32l4.c new file mode 100755 index 0000000000..f8bf81df82 --- /dev/null +++ b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/hal/hal_i2c_stm32l4.c @@ -0,0 +1,346 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#include "hal.h" +#include "soc_init.h" +#include "k_types.h" +#include "errno.h" +#include "hal_i2c_stm32l4.h" + +/* Init and deInit function for i2c1 */ +static void I2C1_Init(void); +static void I2C1_DeInit(void); +static void I2C1_MspInit(I2C_HandleTypeDef *hi2c); +static void I2C1_MspDeInit(I2C_HandleTypeDef *hi2c); + +/* Init and deInit function for i2c2 */ +static void I2C2_Init(void); +static void I2C2_DeInit(void); +static void I2C2_MspInit(I2C_HandleTypeDef *hi2c); +static void I2C2_MspDeInit(I2C_HandleTypeDef *hi2c); + +/* handle for i2c */ +static I2C_HandleTypeDef I2c1Handle = {0}; +static I2C_HandleTypeDef I2c2Handle = {0}; + +int32_t hal_i2c_init(i2c_dev_t *i2c) +{ + int32_t ret = -1; + + if (i2c == NULL) { + return -1; + } + + switch (i2c->port) { + case AOS_PORT_I2C1: + I2C1_Init(); + i2c->priv = &I2c1Handle; + ret = 0; + break; + case AOS_PORT_I2C2: + I2C2_Init(); + i2c->priv = &I2c2Handle; + ret = 0; + break; + default: + break; + } + + return ret; +} + +int32_t hal_i2c_master_send(i2c_dev_t *i2c, uint16_t dev_addr, const uint8_t *data, + uint16_t size, uint32_t timeout) +{ + int ret = -1; + + if ((i2c != NULL) && (data != NULL)) { + ret = HAL_I2C_Master_Transmit((I2C_HandleTypeDef*)(i2c->priv), dev_addr, + (uint8_t *)data, size, timeout); + } + + return ret; +} + +int32_t hal_i2c_master_recv(i2c_dev_t *i2c, uint16_t dev_addr, uint8_t *data, + uint16_t size, uint32_t timeout) +{ + int ret = -1; + + if ((i2c != NULL) && (data != NULL)) { + ret = HAL_I2C_Master_Receive((I2C_HandleTypeDef*)(i2c->priv), dev_addr, + data, size, timeout); + } + + return ret; +} + +int32_t hal_i2c_slave_send(i2c_dev_t *i2c, const uint8_t *data, uint16_t size, uint32_t timeout) +{ + int ret = -1; + + if ((i2c != NULL) && (data != NULL)) { + ret = HAL_I2C_Slave_Transmit((I2C_HandleTypeDef*)(i2c->priv), (uint8_t *)data, + size, timeout); + } + + return ret; +} + +int32_t hal_i2c_slave_recv(i2c_dev_t *i2c, uint8_t *data, uint16_t size, uint32_t timeout) +{ + int ret = -1; + + if ((i2c != NULL) && (data != NULL)) { + ret = HAL_I2C_Slave_Receive((I2C_HandleTypeDef*)(i2c->priv), data, size, timeout); + } + + return ret; +} + +int32_t hal_i2c_mem_write(i2c_dev_t *i2c, uint16_t dev_addr, uint16_t mem_addr, + uint16_t mem_addr_size, const uint8_t *data, uint16_t size, + uint32_t timeout) +{ + int ret = -1; + + if ((i2c != NULL) && (data != NULL)) { + ret = HAL_I2C_Mem_Write((I2C_HandleTypeDef*)(i2c->priv), dev_addr, mem_addr, + (uint16_t)mem_addr_size, (uint8_t *)data, size, timeout); + } + + return ret; +}; + +int32_t hal_i2c_mem_read(i2c_dev_t *i2c, uint16_t dev_addr, uint16_t mem_addr, + uint16_t mem_addr_size, uint8_t *data, uint16_t size, + uint32_t timeout) +{ + int ret = -1; + + if ((i2c != NULL) && (data != NULL)) { + ret = HAL_I2C_Mem_Read((I2C_HandleTypeDef*)(i2c->priv), dev_addr, mem_addr, + (uint16_t)mem_addr_size, data, size, timeout); + } + + return ret; +}; + +int32_t hal_i2c_finalize(i2c_dev_t *i2c) +{ + int32_t ret = -1; + + if (i2c == NULL) { + return -1; + } + + switch (i2c->port) { + case AOS_PORT_I2C1: + I2C1_DeInit(); + ret = 0; + break; + case AOS_PORT_I2C2: + I2C2_DeInit(); + ret = 0; + break; + default: + break; + } + + return ret; +} + +void I2C1_Init(void) +{ + if (HAL_I2C_GetState(&I2c1Handle) == HAL_I2C_STATE_RESET) { + I2c1Handle.Instance = I2C1_INSTANCE; + I2c1Handle.Init.Timing = I2C1_TIMING; + I2c1Handle.Init.OwnAddress1 = I2C1_OWN_ADDRESS1; + I2c1Handle.Init.AddressingMode = I2C1_ADDRESSING_MODE; + I2c1Handle.Init.DualAddressMode = I2C1_DUAL_ADDRESS_MODE; + I2c1Handle.Init.OwnAddress2 = I2C1_OWNADDRESS2; + I2c1Handle.Init.GeneralCallMode = I2C1_GENERAL_CALL_MODE; + I2c1Handle.Init.NoStretchMode = I2C1_NO_STRETCH_MODE; + + /* Init the I2C */ + I2C1_MspInit(&I2c1Handle); + HAL_I2C_Init(&I2c1Handle); + } +} + +void I2C1_DeInit(void) +{ + if (HAL_I2C_GetState(&I2c1Handle) != HAL_I2C_STATE_RESET) { + /* DeInit the I2C */ + HAL_I2C_DeInit(&I2c1Handle); + I2C1_MspDeInit(&I2c1Handle); + } +} + +static void I2C1_MspInit(I2C_HandleTypeDef *hi2c) +{ + GPIO_InitTypeDef GPIO_InitStructure; + RCC_PeriphCLKInitTypeDef RCC_PeriphCLKInitStruct; + + if (hi2c->Instance == I2C1_INSTANCE) { + /*##-1- Configure the Discovery I2C1 clock source. The clock is derived from the SYSCLK #*/ + RCC_PeriphCLKInitStruct.PeriphClockSelection = I2C1_RCC_PERIPH_CLOCK_SELECTION; + RCC_PeriphCLKInitStruct.I2c2ClockSelection = I2C1_RCC_CLOCK_SELECTION; + HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphCLKInitStruct); + + /* -2- Configure the GPIOs */ + /* Enable GPIO clock */ + I2C1_SDA_GPIO_CLK_ENABLE(); + I2C1_SCL_GPIO_CLK_ENABLE(); + + /* Configure I2C Rx/Tx as alternate function */ + GPIO_InitStructure.Pin = I2C1_GPIO_SCL_PIN; + GPIO_InitStructure.Mode = GPIO_MODE_AF_OD; + GPIO_InitStructure.Pull = GPIO_PULLUP; + GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStructure.Alternate = I2C1_GPIO_ALTERNATE; + HAL_GPIO_Init(I2C1_GPIO_SCL_PORT, &GPIO_InitStructure); + GPIO_InitStructure.Pin = I2C1_GPIO_SDA_PIN; + HAL_GPIO_Init(I2C1_GPIO_SDA_PORT, &GPIO_InitStructure); + + /* -3- Configure the Discovery I2C1 peripheral */ + /* Enable Discovery_I2C1 clock */ + I2C1_CLK_ENABLE(); + + /* Force and release the I2C Peripheral Clock Reset */ + I2C1_FORCE_RESET(); + I2C1_RELEASE_RESET(); + + /* Enable and set Discovery I2C1 Interrupt to the highest priority */ + HAL_NVIC_SetPriority(I2C1_EV_IRQn, 0x00, 0); + HAL_NVIC_EnableIRQ(I2C1_EV_IRQn); + + /* Enable and set Discovery I2C1 Interrupt to the highest priority */ + HAL_NVIC_SetPriority(I2C1_ER_IRQn, 0x00, 0); + HAL_NVIC_EnableIRQ(I2C1_ER_IRQn); + } +} + +static void I2C1_MspDeInit(I2C_HandleTypeDef *hi2c) +{ + if (hi2c->Instance == I2C1_INSTANCE) { + /* -1- Unconfigure the GPIOs */ + /* Enable GPIO clock */ + I2C1_SDA_GPIO_CLK_ENABLE(); + I2C1_SCL_GPIO_CLK_ENABLE(); + + /* Configure I2C Rx/Tx as alternate function */ + HAL_GPIO_DeInit(I2C1_GPIO_SCL_PORT, I2C1_GPIO_SCL_PIN); + HAL_GPIO_DeInit(I2C1_GPIO_SDA_PORT, I2C1_GPIO_SDA_PIN); + + /* -2- Unconfigure the Discovery I2C1 peripheral */ + /* Force and release I2C Peripheral */ + I2C1_FORCE_RESET(); + I2C1_RELEASE_RESET(); + + /* Disable Discovery I2C1 clock */ + I2C1_CLK_DISABLE(); + + /* Disable Discovery I2C1 interrupts */ + HAL_NVIC_DisableIRQ(I2C1_EV_IRQn); + HAL_NVIC_DisableIRQ(I2C1_ER_IRQn); + } +} + +void I2C2_Init(void) +{ + if (HAL_I2C_GetState(&I2c2Handle) == HAL_I2C_STATE_RESET) { + I2c2Handle.Instance = I2C2_INSTANCE; + I2c2Handle.Init.Timing = I2C2_TIMING; + I2c2Handle.Init.OwnAddress1 = I2C2_OWN_ADDRESS1; + I2c2Handle.Init.AddressingMode = I2C2_ADDRESSING_MODE; + I2c2Handle.Init.DualAddressMode = I2C2_DUAL_ADDRESS_MODE; + I2c2Handle.Init.OwnAddress2 = I2C2_OWNADDRESS2; + I2c2Handle.Init.GeneralCallMode = I2C2_GENERAL_CALL_MODE; + I2c2Handle.Init.NoStretchMode = I2C2_NO_STRETCH_MODE; + + /* Init the I2C */ + I2C2_MspInit(&I2c2Handle); + HAL_I2C_Init(&I2c2Handle); + } +} + +void I2C2_DeInit(void) +{ + if (HAL_I2C_GetState(&I2c2Handle) != HAL_I2C_STATE_RESET) { + /* DeInit the I2C */ + HAL_I2C_DeInit(&I2c2Handle); + I2C2_MspDeInit(&I2c2Handle); + } +} + +static void I2C2_MspInit(I2C_HandleTypeDef *hi2c) +{ + GPIO_InitTypeDef GPIO_InitStructure; + RCC_PeriphCLKInitTypeDef RCC_PeriphCLKInitStruct; + + if (hi2c->Instance == I2C2_INSTANCE) { + /*##-1- Configure the Discovery I2C2 clock source. The clock is derived from the SYSCLK #*/ + RCC_PeriphCLKInitStruct.PeriphClockSelection = I2C2_RCC_PERIPH_CLOCK_SELECTION; + RCC_PeriphCLKInitStruct.I2c2ClockSelection = I2C2_RCC_CLOCK_SELECTION; + HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphCLKInitStruct); + + /* -2- Configure the GPIOs */ + /* Enable GPIO clock */ + I2C2_SDA_GPIO_CLK_ENABLE(); + I2C2_SCL_GPIO_CLK_ENABLE(); + + /* Configure I2C Rx/Tx as alternate function */ + GPIO_InitStructure.Pin = I2C2_GPIO_SCL_PIN; + GPIO_InitStructure.Mode = GPIO_MODE_AF_OD; + GPIO_InitStructure.Pull = GPIO_PULLUP; + GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStructure.Alternate = I2C2_GPIO_ALTERNATE; + HAL_GPIO_Init(I2C2_GPIO_SCL_PORT, &GPIO_InitStructure); + GPIO_InitStructure.Pin = I2C2_GPIO_SDA_PIN; + HAL_GPIO_Init(I2C2_GPIO_SDA_PORT, &GPIO_InitStructure); + + /* -3- Configure the Discovery I2C2 peripheral */ + /* Enable Discovery_I2C2 clock */ + I2C2_CLK_ENABLE(); + + /* Force and release the I2C Peripheral Clock Reset */ + I2C2_FORCE_RESET(); + I2C2_RELEASE_RESET(); + + /* Enable and set Discovery I2C2 Interrupt to the highest priority */ + HAL_NVIC_SetPriority(I2C2_EV_IRQn, 0x00, 0); + HAL_NVIC_EnableIRQ(I2C2_EV_IRQn); + + /* Enable and set Discovery I2C2 Interrupt to the highest priority */ + HAL_NVIC_SetPriority(I2C2_ER_IRQn, 0x00, 0); + HAL_NVIC_EnableIRQ(I2C2_ER_IRQn); + } +} + +static void I2C2_MspDeInit(I2C_HandleTypeDef *hi2c) +{ + if (hi2c->Instance == I2C2_INSTANCE) { + /* -1- Unconfigure the GPIOs */ + /* Enable GPIO clock */ + I2C2_SDA_GPIO_CLK_ENABLE(); + I2C2_SCL_GPIO_CLK_ENABLE(); + + /* Configure I2C Rx/Tx as alternate function */ + HAL_GPIO_DeInit(I2C2_GPIO_SCL_PORT, I2C2_GPIO_SCL_PIN); + HAL_GPIO_DeInit(I2C2_GPIO_SDA_PORT, I2C2_GPIO_SDA_PIN); + + /* -2- Unconfigure the Discovery I2C2 peripheral */ + /* Force and release I2C Peripheral */ + I2C2_FORCE_RESET(); + I2C2_RELEASE_RESET(); + + /* Disable Discovery I2C2 clock */ + I2C2_CLK_DISABLE(); + + /* Disable Discovery I2C2 interrupts */ + HAL_NVIC_DisableIRQ(I2C2_EV_IRQn); + HAL_NVIC_DisableIRQ(I2C2_ER_IRQn); + } +} diff --git a/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/hal/hal_i2c_stm32l4.h b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/hal/hal_i2c_stm32l4.h new file mode 100755 index 0000000000..1af6129fce --- /dev/null +++ b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/hal/hal_i2c_stm32l4.h @@ -0,0 +1,101 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#ifndef __HAL_I2C_STM32L4_H +#define __HAL_I2C_STM32L4_H + +#ifdef __cplusplus + extern "C" { +#endif + +#include "stm32l4xx_hal.h" +#include +#include +#include +#include + +/******************************** I2C1 configure *****************************/ +#define AOS_PORT_I2C1 1 +#define I2C1_INSTANCE I2C1 +#define I2C1_TIMING 0x40403E5D +#define I2C1_OWN_ADDRESS1 0x70 +#define I2C1_ADDRESSING_MODE I2C_ADDRESSINGMODE_7BIT +#define I2C1_DUAL_ADDRESS_MODE I2C_DUALADDRESS_DISABLE +#define I2C1_OWNADDRESS2 0xFF +#define I2C1_OWN_ADDRESS2_MASK I2C_OA2_NOMASK +#define I2C1_GENERAL_CALL_MODE I2C_GENERALCALL_DISABLE +#define I2C1_NO_STRETCH_MODE I2C_NOSTRETCH_DISABLE + +/* Definition for I2C1 clock resources */ +#define I2C1_RCC_PERIPH_CLOCK_SELECTION RCC_PERIPHCLK_I2C1 +#define I2C1_RCC_CLOCK_SELECTION RCC_I2C1CLKSOURCE_SYSCLK + +#define I2C1_CLK_ENABLE() __HAL_RCC_I2C1_CLK_ENABLE() +#define I2C1_CLK_DISABLE() __HAL_RCC_I2C1_CLK_DISABLE() +#define I2C1_SDA_GPIO_CLK_ENABLE() __HAL_RCC_GPIOG_CLK_ENABLE() +#define I2C1_SCL_GPIO_CLK_ENABLE() __HAL_RCC_GPIOG_CLK_ENABLE() +#define I2C1_SDA_GPIO_CLK_DISABLE() __HAL_RCC_GPIOG_CLK_DISABLE() +#define I2C1_SCL_GPIO_CLK_DISABLE() __HAL_RCC_GPIOG_CLK_DISABLE() +#define I2C1_FORCE_RESET() __HAL_RCC_I2C1_FORCE_RESET() +#define I2C1_RELEASE_RESET() __HAL_RCC_I2C1_RELEASE_RESET() + +/* Definition for I2C1 Pins */ +#define I2C1_GPIO_SCL_PIN GPIO_PIN_14 +#define I2C1_GPIO_SDA_PIN GPIO_PIN_13 +#define I2C1_GPIO_SCL_PORT GPIOG +#define I2C1_GPIO_SDA_PORT GPIOG +#define I2C1_GPIO_MODE GPIO_MODE_AF_OD +#define I2C1_GPIO_PULL GPIO_PULLUP +#define I2C1_GPIO_SPEED GPIO_SPEED_FREQ_VERY_HIGH +#define I2C1_GPIO_ALTERNATE GPIO_AF4_I2C1 + +/* Definition for I2C1's NVIC */ +#define I2C1_EV_IRQn I2C1_EV_IRQn +#define I2C1_ER_IRQn I2C1_ER_IRQn + +/******************************** I2C2 configure *****************************/ +#define AOS_PORT_I2C2 2 +#define I2C2_INSTANCE I2C2 +#define I2C2_TIMING 0x40403E5D +#define I2C2_OWN_ADDRESS1 0x70 +#define I2C2_ADDRESSING_MODE I2C_ADDRESSINGMODE_7BIT +#define I2C2_DUAL_ADDRESS_MODE I2C_DUALADDRESS_DISABLE +#define I2C2_OWNADDRESS2 0xFF +#define I2C2_OWN_ADDRESS2_MASK I2C_OA2_NOMASK +#define I2C2_GENERAL_CALL_MODE I2C_GENERALCALL_DISABLE +#define I2C2_NO_STRETCH_MODE I2C_NOSTRETCH_DISABLE + +/* Definition for I2C2 clock resources */ +#define I2C2_RCC_PERIPH_CLOCK_SELECTION RCC_PERIPHCLK_I2C2 +#define I2C2_RCC_CLOCK_SELECTION RCC_I2C2CLKSOURCE_SYSCLK + +#define I2C2_CLK_ENABLE() __HAL_RCC_I2C2_CLK_ENABLE() +#define I2C2_CLK_DISABLE() __HAL_RCC_I2C2_CLK_DISABLE() +#define I2C2_SDA_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE() +#define I2C2_SCL_GPIO_CLK_ENABLE() __HAL_RCC_GPIOH_CLK_ENABLE() +#define I2C2_SDA_GPIO_CLK_DISABLE() __HAL_RCC_GPIOB_CLK_DISABLE() +#define I2C2_SCL_GPIO_CLK_DISABLE() __HAL_RCC_GPIOH_CLK_DISABLE() +#define I2C2_FORCE_RESET() __HAL_RCC_I2C2_FORCE_RESET() +#define I2C2_RELEASE_RESET() __HAL_RCC_I2C2_RELEASE_RESET() + +/* Definition for I2C2 Pins */ +#define I2C2_GPIO_SCL_PIN GPIO_PIN_4 +#define I2C2_GPIO_SDA_PIN GPIO_PIN_14 +#define I2C2_GPIO_SCL_PORT GPIOH +#define I2C2_GPIO_SDA_PORT GPIOB +#define I2C2_GPIO_MODE GPIO_MODE_AF_OD +#define I2C2_GPIO_PULL GPIO_PULLUP +#define I2C2_GPIO_SPEED GPIO_SPEED_FREQ_VERY_HIGH +#define I2C2_GPIO_ALTERNATE GPIO_AF4_I2C2 + +/* Definition for I2C2's NVIC */ +#define I2C2_EV_IRQn I2C2_EV_IRQn +#define I2C2_ER_IRQn I2C2_ER_IRQn + + +#ifdef __cplusplus +} +#endif + +#endif /* __HAL_I2C_STM32L4_H */ diff --git a/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/hal/hal_spi_stm32l4.c b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/hal/hal_spi_stm32l4.c new file mode 100755 index 0000000000..12278a54e4 --- /dev/null +++ b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/hal/hal_spi_stm32l4.c @@ -0,0 +1,191 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#include +#include +#include +#include "stm32l4xx_hal.h" +#include "soc_init.h" +#include "hal.h" +#include "stm32l4xx_hal.h" +#include "hal_spi_stm32l4.h" +#include "stm32l4xx_hal_spi.h" + +/* Init and deInit function for spi1 */ +static int32_t spi1_init(spi_dev_t *uart); +static int32_t spi1_DeInit(void); +static void spi1_MspInit(void); +static void spi1_DeMspInit(void); + +/* function used to transform hal para to stm32l4 para */ +static int32_t spi_mode_transform(uint32_t mode_hal, uint32_t *mode_stm32l4); +static int32_t spi_freq_transform(uint32_t freq_hal, uint32_t *BaudRatePrescaler_stm32l4_stm32l4); + +/* handle for spi */ +SPI_HandleTypeDef spi1_handle; + +int32_t hal_spi_init(spi_dev_t *spi) +{ + int32_t ret = -1; + + if (spi == NULL) { + return -1; + } + + /*init spi handle*/ + memset(&spi1_handle, 0, sizeof(spi1_handle)); + + switch (spi->port) { + case PORT_SPI1: + spi->priv = &spi1_handle; + ret = spi1_init(spi); + break; + + /* if ohter spi exist add init code here */ + + default: + break; + } + + return ret; +} + +int32_t hal_spi_send(spi_dev_t *spi, const uint8_t *data, uint16_t size, uint32_t timeout) +{ + int32_t ret = -1; + + if((spi != NULL) && (data != NULL)) { + ret = HAL_SPI_Transmit((SPI_HandleTypeDef *)spi->priv, + (uint8_t *)data, size, timeout); + } + + return ret; +} + +int32_t hal_spi_recv(spi_dev_t *spi, uint8_t *data, uint16_t size, uint32_t timeout) +{ + int32_t ret = -1; + + if((spi != NULL) && (data != NULL)) { + ret = HAL_SPI_Receive((SPI_HandleTypeDef *)spi->priv, + (uint8_t *)data, size, timeout); + } + + return ret; +} + +int32_t hal_spi_send_recv(spi_dev_t *spi, uint8_t *tx_data, uint16_t tx_size, + uint8_t *rx_data, uint16_t rx_size, uint32_t timeout) +{ + int32_t ret = -1; + + if((spi != NULL) && (tx_data != NULL) && (rx_data != NULL) && (rx_size == tx_size)) { + ret = HAL_SPI_TransmitReceive((SPI_HandleTypeDef *)spi->priv, + (uint8_t *)tx_data, (uint8_t *)rx_data, rx_size, timeout); + } + + return ret; +} + +int32_t hal_spi_finalize(spi_dev_t *spi) +{ + int32_t ret = -1; + + if (spi == NULL) { + return -1; + } + + switch (spi->port) { + case PORT_SPI1: + ret = spi1_DeInit(); + break; + /* if other spi exist add Deinit code here */ + + default: + break; + } + + return ret; +} + +int32_t spi1_init(spi_dev_t *spi) +{ + int32_t ret = 0; + + spi1_handle.Instance = SPI1; + + ret = spi_mode_transform(spi->config.mode, &spi1_handle.Init.Mode); + ret = spi_freq_transform(spi->config.freq, &spi1_handle.Init.BaudRatePrescaler); + if (ret != 0) { + return -1; + } + + /* Initialize other parameters in struction SPI_InitTypeDef */ + + /* init spi */ + spi1_MspInit(); + ret = HAL_SPI_Init(&spi1_handle); + + return ret; +} + +int32_t spi1_DeInit(void) +{ + int32_t ret = -1; + + /* spi1 deinitialization */ + ret = HAL_SPI_DeInit(&spi1_handle); + spi1_DeMspInit(); + + return ret; +} + +void spi1_MspInit(void) +{ + /* Initialize spi-related pins */ + + /* Initialize interrupts if necessary */ +} + +void spi1_DeMspInit(void) +{ + /* Disable spi-related pins */ + + /* Disable interrupts if necessary */ +} + +static int32_t spi_mode_transform(uint32_t mode_hal, uint32_t *mode_stm32l4) +{ + uint32_t mode = 0; + int32_t ret = 0; + + if(mode_hal == HAL_SPI_MODE_MASTER) + { + mode = SPI_MODE_MASTER; + } + else if(mode_hal == HAL_SPI_MODE_MASTER) + { + mode = SPI_MODE_MASTER; + } + else + { + ret = -1; + } + + if(ret == 0) + { + *mode_stm32l4 = mode; + } + + return ret; +} + +static int32_t spi_freq_transform(uint32_t freq_hal, uint32_t *BaudRatePrescaler_stm32l4) +{ + int32_t ret = 0; + + /* calc BaudRatePrescaler according to freq_hal */ + + return ret; +} diff --git a/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/hal/hal_spi_stm32l4.h b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/hal/hal_spi_stm32l4.h new file mode 100755 index 0000000000..26db4079a9 --- /dev/null +++ b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/hal/hal_spi_stm32l4.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#ifndef __HAL_SPI_STM32L4_H +#define __HAL_SPI_STM32L4_H + +#ifdef __cplusplus + extern "C" { +#endif + +#include "stm32l4xx_hal.h" +#include +#include +#include +#include +#include "aos/kernel.h" + +#define PORT_SPI1 1 +#define PORT_SPI2 2 +#define PORT_SPI3 3 +#define PORT_SPI4 4 + +#ifdef __cplusplus +} +#endif + +#endif /* __HAL_SPI_STM32L4_H */ diff --git a/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/hal/hal_timer_stm32l4.c b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/hal/hal_timer_stm32l4.c new file mode 100755 index 0000000000..691f9ff6ad --- /dev/null +++ b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/hal/hal_timer_stm32l4.c @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#include +#include +#include +#include "stm32l4xx_hal.h" +#include "soc_init.h" +#include "hal.h" +#include "stm32l4xx_hal.h" +#include "hal_timer_stm32l4.h" +#include "stm32l4xx_hal_adc.h" + +/* Init and deInit function for adc1 */ +static int32_t timer3_init(timer_dev_t *tim); +static int32_t adc1_DeInit(void); +static void adc1_MspInit(void); +static void adc1_DeMspInit(void); + +/* function used to transform hal para to stm32l4 para */ +int32_t timer_reload_mode_transform(uint8_t reload_mode_hal, uint8_t *reload_mode_stm32l4); + +/* handle for adc */ +TIM_HandleTypeDef timer3_handle; +uint32_t uwPrescalerValue = 0; +hal_timer_cb_t pFun_timer3 = NULL; +void * arg_timer3 = NULL; + +void TIM3_IRQHandler(void) +{ + krhino_intrpt_enter(); + HAL_TIM_IRQHandler(&timer3_handle); + krhino_intrpt_exit(); +} + +int32_t hal_timer_init(timer_dev_t *tim) +{ + int32_t ret = -1; + + if (tim == NULL) { + return -1; + } + + /*init adc handle*/ + memset(&timer3_handle, 0, sizeof(timer3_handle)); + + switch (tim->port) { + case PORT_TIMER3: + tim->priv = &timer3_handle; + ret = timer3_init(tim); + break; + + /* if other timer exist add init code here */ + + default: + break; + } + + return ret; + +} + +int32_t timer3_init(timer_dev_t *tim) +{ + int32_t ret = -1; + + pFun_timer3 = tim->config.cb; + arg_timer3 = tim->config.arg; + + /* Set TIMx instance */ + timer3_handle.Instance = TIM3; + + /* Compute the prescaler value to have TIMx counter clock equal to 10000 Hz */ + uwPrescalerValue = (uint32_t)(SystemCoreClock / 10000) - 1; + timer3_handle.Init.Period = ((tim->config.period / 1000000) * 10000) - 1; + timer3_handle.Init.Prescaler = uwPrescalerValue; + timer3_handle.Init.ClockDivision = 0; + timer3_handle.Init.CounterMode = TIM_COUNTERMODE_UP; + timer3_handle.Init.RepetitionCounter = 0; + ret = timer_reload_mode_transform(tim->config.reload_mode, + (uint8_t *)&timer3_handle.Init.AutoReloadPreload); + + if (ret == 0) { + ret = HAL_TIM_Base_Init(&timer3_handle); + } + + return ret; +} + +int32_t hal_timer_start(timer_dev_t *tim) +{ + int32_t ret = -1; + + if (tim != NULL) + { + ret = HAL_TIM_Base_Start_IT((TIM_HandleTypeDef *)tim->priv); + } + + return ret; +} + +void hal_timer_stop(timer_dev_t *tim) +{ + if (tim != NULL) + { + HAL_TIM_Base_Stop_IT((TIM_HandleTypeDef *)tim->priv); + } +} + +int32_t hal_timer_finalize(timer_dev_t *tim) +{ + if (tim != NULL) + { + HAL_TIM_Base_DeInit((TIM_HandleTypeDef *)tim->priv); + } +} + +int32_t timer_reload_mode_transform(uint8_t reload_mode_hal, + uint8_t *reload_mode_stm32l4) +{ + uint32_t reload_mode = 0; + int32_t ret = 0; + + if(reload_mode_hal == TIMER_RELOAD_AUTO) + { + reload_mode = TIM_AUTORELOAD_PRELOAD_ENABLE; + } + else if(reload_mode_hal == TIMER_RELOAD_MANU) + { + reload_mode = TIM_AUTORELOAD_PRELOAD_DISABLE; + } + else + { + ret = -1; + } + + if(ret == 0) + { + *reload_mode_stm32l4 = reload_mode; + } + + return ret; +} + +void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) +{ + if (htim->Instance == TIM3) { + pFun_timer3(arg_timer3); + } +} diff --git a/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/hal/hal_timer_stm32l4.h b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/hal/hal_timer_stm32l4.h new file mode 100755 index 0000000000..4dce0b2900 --- /dev/null +++ b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/hal/hal_timer_stm32l4.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#ifndef __HAL_TIMER_STM32L4_H +#define __HAL_TIMER_STM32L4_H + +#ifdef __cplusplus + extern "C" { +#endif + +#include "stm32l4xx_hal.h" +#include +#include +#include +#include +#include "aos/kernel.h" + +#define PORT_TIMER1 1 +#define PORT_TIMER2 2 +#define PORT_TIMER3 3 +#define PORT_TIMER4 4 + + +#ifdef __cplusplus +} +#endif + +#endif /* __HAL_TIMER_STM32L4_H */ diff --git a/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/hal/hal_uart_stm32l4.c b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/hal/hal_uart_stm32l4.c new file mode 100755 index 0000000000..653c43e92e --- /dev/null +++ b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/hal/hal_uart_stm32l4.c @@ -0,0 +1,360 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#include +#include +#include +#include "stm32l4xx_hal.h" +#include "soc_init.h" +#include "hal.h" +#include "stm32l4xx_hal.h" +#include "hal_uart_stm32l4.h" + +/* Init and deInit function for uart1 */ +static int32_t uart1_init(uart_dev_t *uart); +static int32_t uart1_DeInit(void); +static void uart1_MspInit(void); +static void uart1_DeMspInit(void); + +/* function used to transform hal para to stm32l4 para */ +static int32_t uart_dataWidth_transform(hal_uart_data_width_t data_width_hal, uint32_t *data_width_stm32l4); +static int32_t uart_parity_transform(hal_uart_parity_t parity_hal, uint32_t *parity_stm32l4); +static int32_t uart_stop_bits_transform(hal_uart_stop_bits_t stop_bits_hal, uint32_t *stop_bits_stm32l4); +static int32_t uart_flow_control_transform(hal_uart_flow_control_t flow_control_hal, uint32_t *flow_control_stm32l4); +static int32_t uart_mode_transform(hal_uart_mode_t mode_hal, uint32_t *mode_stm32l4); + +/* handle for uart */ +UART_HandleTypeDef uart1_handle; + +/* bufferQueue for uart */ +kbuf_queue_t g_buf_queue_uart; +char g_buf_uart[MAX_BUF_UART_BYTES]; + +int32_t hal_uart_init(uart_dev_t *uart) +{ + int32_t ret = -1; + + if (uart == NULL) { + return -1; + } + + switch (uart->port) { + case PORT_UART1: + uart->priv = &uart1_handle; + ret = uart1_init(uart); + break; + + /* if ohter uart exist add init code here */ + + default: + break; + } + + return ret; +} + +int32_t hal_uart_send(uart_dev_t *uart, const void *data, uint32_t size, uint32_t timeout) +{ + int32_t ret = -1; + + if((uart != NULL) && (data != NULL)) { + ret = HAL_UART_Transmit_IT((UART_HandleTypeDef *)uart->priv, + (uint8_t *)data, size); + } + + return ret; +} + +int32_t hal_uart_recv(uart_dev_t *uart, void *data, uint32_t expect_size, + uint32_t *recv_size, uint32_t timeout) +{ + uint8_t *pdata = (uint8_t *)data; + int i = 0; + uint32_t rx_count = 0; + int32_t ret = -1; + + if ((uart == NULL) || (data == NULL)) { + return -1; + } + + for (i = 0; i < expect_size; i++) + { + ret = HAL_UART_Receive_IT_Buf_Queue_1byte((UART_HandleTypeDef *)uart->priv, &pdata[i]); + if (ret == 0) { + rx_count++; + } else { + break; + } + } + + *recv_size = rx_count; + + if(rx_count != 0) + { + ret = 0; + } + else + { + ret = -1; + } + + return ret; +} + +int32_t hal_uart_finalize(uart_dev_t *uart) +{ + int32_t ret = -1; + + if (uart == NULL) { + return -1; + } + + switch (uart->port) { + case PORT_UART1: + ret = uart1_DeInit(); + break; + /* if other uart exist add Deinit code here */ + + default: + break; + } + + return ret; +} + +int32_t uart1_init(uart_dev_t *uart) +{ + int32_t ret = 0; + + uart1_handle.Instance = UART1; + uart1_handle.Init.BaudRate = uart->config.baud_rate; + + ret = uart_dataWidth_transform(uart->config.data_width, &uart1_handle.Init.WordLength); + ret |= uart_parity_transform(uart->config.parity, &uart1_handle.Init.Parity); + ret |= uart_stop_bits_transform(uart->config.stop_bits, &uart1_handle.Init.StopBits); + ret |= uart_flow_control_transform(uart->config.flow_control, &uart1_handle.Init.HwFlowCtl); + ret |= uart_mode_transform(uart->config.mode, &uart1_handle.Init.Mode); + + if (ret != 0) { + return -1; + } + + uart1_handle.Init.OverSampling = UART_OVERSAMPLING_16; + uart1_handle.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE; + uart1_handle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; + uart1_handle.buffer_queue = &g_buf_queue_uart; + + /* init uart */ + uart1_MspInit(); + HAL_UART_Init(&uart1_handle); + + ret = krhino_buf_queue_create(&g_buf_queue_uart, "buf_queue_uart", + g_buf_uart, MAX_BUF_UART_BYTES, 1); + + return ret; +} + +int32_t uart1_DeInit(void) +{ + int32_t ret = -1; + + /* uart deinitialization */ + ret = HAL_UART_DeInit(&uart1_handle); + uart1_DeMspInit(); + + return ret; +} + +void uart1_MspInit(void) +{ + GPIO_InitTypeDef gpio_init_structure; + + /* Enable GPIO clock */ + UART1_TX_GPIO_CLK_ENABLE(); + UART1_RX_GPIO_CLK_ENABLE(); + + /* Enable USART clock */ + UART1_CLK_ENABLE(); + + /* Configure USART Tx as alternate function */ + gpio_init_structure.Pin = UART1_TX_PIN; + gpio_init_structure.Mode = UART1_TX_MODE; + gpio_init_structure.Speed = UART1_TX_SPEED; + gpio_init_structure.Pull = UART1_TX_PULL; + gpio_init_structure.Alternate = UART1_TX_ALTERNATE; + HAL_GPIO_Init(UART1_TX_GPIO_PORT, &gpio_init_structure); + + /* Configure USART Rx as alternate function */ + gpio_init_structure.Pin = UART1_RX_PIN; + gpio_init_structure.Mode = UART1_RX_MODE; + gpio_init_structure.Alternate = UART1_RX_ALTERNATE; + HAL_GPIO_Init(UART1_RX_GPIO_PORT, &gpio_init_structure); + + HAL_NVIC_SetPriority(USART2_IRQn, 0,1); + HAL_NVIC_EnableIRQ(USART2_IRQn); +} + +void uart1_DeMspInit(void) +{ + /* Disable USART clock */ + UART1_CLK_DISABLE(); + + /* USART TX/RX pins deinitializations */ + UART1_TX_GPIO_CLK_DISABLE(); + UART1_RX_GPIO_CLK_DISABLE(); +} + +int32_t uart_dataWidth_transform(hal_uart_data_width_t data_width_hal, + uint32_t *data_width_stm32l4) +{ + uint32_t data_width = 0; + int32_t ret = 0; + + if(data_width_hal == DATA_WIDTH_7BIT) + { + data_width = UART_WORDLENGTH_7B; + } + else if(data_width_hal == DATA_WIDTH_8BIT) + { + data_width = UART_WORDLENGTH_8B; + } + else if(data_width_hal == DATA_WIDTH_9BIT) + { + data_width = UART_WORDLENGTH_9B; + } + else + { + ret = -1; + } + + if(ret == 0) + { + *data_width_stm32l4 = data_width; + } + + return ret; +} + +int32_t uart_parity_transform(hal_uart_parity_t parity_hal, + uint32_t *parity_stm32l4) +{ + uint32_t parity = 0; + int32_t ret = 0; + + if(parity_hal == NO_PARITY) + { + parity = UART_PARITY_NONE; + } + else if(parity_hal == ODD_PARITY) + { + parity = UART_PARITY_EVEN; + } + else if(parity_hal == EVEN_PARITY) + { + parity = UART_PARITY_ODD; + } + else + { + ret = -1; + } + + if(ret == 0) + { + *parity_stm32l4 = parity; + } + + return ret; +} + +int32_t uart_stop_bits_transform(hal_uart_stop_bits_t stop_bits_hal, + uint32_t *stop_bits_stm32l4) +{ + uint32_t stop_bits = 0; + int32_t ret = 0; + + if(stop_bits_hal == STOP_BITS_1) + { + stop_bits = UART_STOPBITS_1; + } + else if(stop_bits_hal == STOP_BITS_2) + { + stop_bits = UART_STOPBITS_2; + } + else + { + ret = -1; + } + + if(ret == 0) + { + *stop_bits_stm32l4 = stop_bits; + } + + return ret; +} + +int32_t uart_flow_control_transform(hal_uart_flow_control_t flow_control_hal, + uint32_t *flow_control_stm32l4) +{ + uint32_t flow_control = 0; + int32_t ret = 0; + + if(flow_control_hal == FLOW_CONTROL_DISABLED) + { + flow_control = UART_HWCONTROL_NONE; + } + else if(flow_control_hal == FLOW_CONTROL_CTS) + { + flow_control = UART_HWCONTROL_CTS; + } + else if(flow_control_hal == FLOW_CONTROL_RTS) + { + flow_control = UART_HWCONTROL_RTS; + } + else if(flow_control_hal == FLOW_CONTROL_RTS) + { + flow_control = UART_HWCONTROL_RTS_CTS; + } + else + { + ret = -1; + } + + if(ret == 0) + { + *flow_control_stm32l4 = flow_control; + } + + return ret; +} + +int32_t uart_mode_transform(hal_uart_mode_t mode_hal, uint32_t *mode_stm32l4) +{ + uint32_t mode = 0; + int32_t ret = 0; + + if(mode_hal == MODE_TX) + { + mode = UART_MODE_TX; + } + else if(mode_hal == MODE_RX) + { + mode = UART_MODE_RX; + } + else if(mode_hal == MODE_TX_RX) + { + mode = UART_MODE_TX_RX; + } + else + { + ret = -1; + } + + if(ret == 0) + { + *mode_stm32l4 = mode; + } + + return ret; +} diff --git a/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/hal/hal_uart_stm32l4.h b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/hal/hal_uart_stm32l4.h new file mode 100755 index 0000000000..581734a414 --- /dev/null +++ b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/hal/hal_uart_stm32l4.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#ifndef __HAL_UART_STM32L4_H +#define __HAL_UART_STM32L4_H + +#ifdef __cplusplus + extern "C" { +#endif + +#include "stm32l4xx_hal.h" +#include +#include +#include +#include +#include "aos/kernel.h" + +#define PORT_UART1 1 +#define PORT_UART2 2 +#define PORT_UART3 3 +#define PORT_UART4 4 + +/***************************** uart1 configure *******************************/ +#define UART1 USART2 + +#define UART1_BANDRATE 115200 +#define UART1_WORD_LENGTH UART_WORDLENGTH_8B +#define UART1_STOP_BITS UART_STOPBITS_1 +#define UART1_PARITY UART_PARITY_NONE +#define UART1_MODE UART_MODE_TX_RX +#define UART1_HW_FLOW_CTL UART_HWCONTROL_NONE +#define UART1_OVER_SAMPLING UART_OVERSAMPLING_16 +#define UART1_ONE_BIT_SAMPLING UART_ONE_BIT_SAMPLE_DISABLE +#define UART1_ADV_FEATURE_INIT UART_ADVFEATURE_NO_INIT + +#define UART1_CLK_ENABLE() __HAL_RCC_USART2_CLK_ENABLE() +#define UART1_CLK_DISABLE() __HAL_RCC_USART2_CLK_DISABLE() +#define UART1_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE() +#define UART1_TX_GPIO_CLK_DISABLE() __HAL_RCC_GPIOA_CLK_DISABLE() +#define UART1_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE() +#define UART1_RX_GPIO_CLK_DISABLE() __HAL_RCC_GPIOD_CLK_DISABLE() + +#define UART1_TX_PIN GPIO_PIN_2 +#define UART1_TX_MODE GPIO_MODE_AF_PP +#define UART1_TX_SPEED GPIO_SPEED_FREQ_HIGH +#define UART1_TX_PULL GPIO_NOPULL +#define UART1_TX_ALTERNATE GPIO_AF7_USART2 +#define UART1_TX_GPIO_PORT GPIOA + +#define UART1_RX_PIN GPIO_PIN_6 +#define UART1_RX_MODE GPIO_MODE_AF_PP +#define UART1_RX_ALTERNATE GPIO_AF7_USART2 +#define UART1_RX_GPIO_PORT GPIOD + + +#define MAX_BUF_UART_BYTES 1000 + +#ifdef __cplusplus +} +#endif + +#endif /* __HAL_UART_STM32L4_H */ diff --git a/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/hal/hw.c b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/hal/hw.c index aa6e603319..45829cde83 100644 --- a/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/hal/hw.c +++ b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/hal/hw.c @@ -29,33 +29,29 @@ void hal_reboot(void) static void _timer_cb(void *timer, void *arg) { - hal_timer_t *tmr = arg; - tmr->cb(tmr->arg); + timer_dev_t *tmr = arg; + tmr->config.cb(tmr->config.arg); } -void hal_timer_init(hal_timer_t *tmr, unsigned int period, unsigned char auto_reload, unsigned char ch, hal_timer_cb_t cb, void *arg) +int32_t hal_timer_init(timer_dev_t *tim) { - (void)ch; - memset(tmr, 0, sizeof(*tmr)); - tmr->cb = cb; - tmr->arg = arg; - if (auto_reload > 0u) { - krhino_timer_dyn_create((ktimer_t **)&tmr->priv, "hwtmr", _timer_cb, - us2tick(period), us2tick(period), tmr, 0); + if (tim->config.reload_mode == TIMER_RELOAD_AUTO) { + krhino_timer_dyn_create((ktimer_t **)&tim->priv, "hwtmr", _timer_cb, + us2tick(tim->config.period), us2tick(tim->config.period), tim, 0); } else { - krhino_timer_dyn_create((ktimer_t **)&tmr->priv, "hwtmr", _timer_cb, - us2tick(period), 0, tmr, 0); + krhino_timer_dyn_create((ktimer_t **)&tim->priv, "hwtmr", _timer_cb, + us2tick(tim->config.period), 0, tim, 0); } } -int32_t hal_timer_start(hal_timer_t *tmr) +int32_t hal_timer_start(timer_dev_t *tmr) { return krhino_timer_start(tmr->priv); } -void hal_timer_stop(hal_timer_t *tmr) +void hal_timer_stop(timer_dev_t *tmr) { krhino_timer_stop(tmr->priv); krhino_timer_dyn_del(tmr->priv); diff --git a/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/helloworld/k_config.h b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/helloworld/k_config.h index 5bc3d2748a..2de3f969c3 100644 --- a/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/helloworld/k_config.h +++ b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/helloworld/k_config.h @@ -30,7 +30,7 @@ #define RHINO_CONFIG_TIMER 0 #endif #ifndef RHINO_CONFIG_BUF_QUEUE -#define RHINO_CONFIG_BUF_QUEUE 0 +#define RHINO_CONFIG_BUF_QUEUE 1 #endif #ifndef RHINO_CONFIG_MM_BLK #define RHINO_CONFIG_MM_BLK 0 diff --git a/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/helloworld/soc_init.c b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/helloworld/soc_init.c index 0e09156873..fa190d6507 100644 --- a/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/helloworld/soc_init.c +++ b/platform/mcu/stm32l4xx/src/STM32L496G-Discovery/helloworld/soc_init.c @@ -38,7 +38,7 @@ /* Includes ------------------------------------------------------------------*/ #include "soc_init.h" -#include "k_config.h" +#include "k_api.h" #include "stm32l4xx_hal.h" #if defined (__CC_ARM) && defined(__MICROLIB) diff --git a/projects/IAR/mqttapp/alios.ewp b/projects/IAR/mqttapp/alios.ewp index feda73900b..2e1b833e18 100644 --- a/projects/IAR/mqttapp/alios.ewp +++ b/projects/IAR/mqttapp/alios.ewp @@ -237,10 +237,10 @@ ALIOT_DEBUG IOTX_DEBUG STM32L475xx - SYSINFO_OS_VERSION="AOS-R-1.1.2-" + SYSINFO_OS_VERSION="AOS-R-1.2.0-" SYSINFO_PRODUCT_MODEL="ALI_AOS_B-L475E" SYSINFO_DEVICE_NAME="B-L475E" - SYSINFO_KERNEL_VERSION="AOS-R-1.1.2" + SYSINFO_KERNEL_VERSION="AOS-R-1.2.0" SYSINFO_APP_VERSION="APP-1.0.0-20171128.1211" __arm__ __thumb__ @@ -371,14 +371,14 @@ CCIncludePath2 $PROJ_DIR$\..\..\..\framework\fota\socket\stm32wifi $PROJ_DIR$\..\..\..\framework\fota\platform\mqtt - $PROJ_DIR$\..\..\..\utility\iotx-utils\device + $PROJ_DIR$\..\..\..\utility\iotx-utils\iotx-system $PROJ_DIR$\..\..\..\security\alicrypto\inc $PROJ_DIR$\..\..\..\security\alicrypto\test $PROJ_DIR$\..\..\..\kernel\modules\fs\kv\include $PROJ_DIR$\..\..\..\framework\fota\socket\ $PROJ_DIR$\..\..\..\framework\fota\platform\ $PROJ_DIR$\..\..\..\utility\iotx-utils\guider - $PROJ_DIR$\..\..\..\utility\iotx-utils\device + $PROJ_DIR$\..\..\..\utility\iotx-utils\iotx-system $PROJ_DIR$\..\..\..\utility\iotx-utils\LITE-utils $PROJ_DIR$\..\..\..\utility\iotx-utils\LITE-log $PROJ_DIR$\..\..\..\utility\iotx-utils\misc @@ -2187,10 +2187,10 @@ ALIOT_DEBUG IOTX_DEBUG STM32L475xx - SYSINFO_OS_VERSION="AOS-R-1.1.2-" + SYSINFO_OS_VERSION="AOS-R-1.2.0-" SYSINFO_PRODUCT_MODEL="ALI_AOS_B-L475E" SYSINFO_DEVICE_NAME="B-L475E" - SYSINFO_KERNEL_VERSION="AOS-R-1.1.2" + SYSINFO_KERNEL_VERSION="AOS-R-1.2.0" SYSINFO_APP_VERSION="APP-1.0.0-" __arm__ __thumb__ @@ -2322,14 +2322,14 @@ CCIncludePath2 $PROJ_DIR$\..\..\..\framework\fota\socket\stm32wifi $PROJ_DIR$\..\..\..\framework\fota\platform\mqtt - $PROJ_DIR$\..\..\..\utility\iotx-utils\device + $PROJ_DIR$\..\..\..\utility\iotx-utils\iotx-system $PROJ_DIR$\..\..\..\security\alicrypto\inc $PROJ_DIR$\..\..\..\security\alicrypto\test $PROJ_DIR$\..\..\..\kernel\modules\fs\kv\include $PROJ_DIR$\..\..\..\framework\fota\socket\ $PROJ_DIR$\..\..\..\framework\fota\platform\ $PROJ_DIR$\..\..\..\utility\iotx-utils\guider - $PROJ_DIR$\..\..\..\utility\iotx-utils\device + $PROJ_DIR$\..\..\..\utility\iotx-utils\iotx-system $PROJ_DIR$\..\..\..\utility\iotx-utils\LITE-utils $PROJ_DIR$\..\..\..\utility\iotx-utils\LITE-log $PROJ_DIR$\..\..\..\utility\iotx-utils\misc @@ -2629,7 +2629,7 @@ $PROJ_DIR$\..\..\..\kernel\rhino\core\k_event.c - $PROJ_DIR$\..\..\..\kernel\rhino\core\k_fifo.c + $PROJ_DIR$\..\..\..\kernel\rhino\common\k_fifo.c $PROJ_DIR$\..\..\..\kernel\rhino\core\k_idle.c @@ -2689,7 +2689,7 @@ $PROJ_DIR$\..\..\..\kernel\rhino\core\k_timer.c - $PROJ_DIR$\..\..\..\kernel\rhino\core\k_trace.c + $PROJ_DIR$\..\..\..\kernel\rhino\common\k_trace.c $PROJ_DIR$\..\..\..\kernel\rhino\core\k_workqueue.c @@ -2932,10 +2932,10 @@ mbedtls - $PROJ_DIR$\..\..\..\security\mbedtls\mbedtls_net.c + $PROJ_DIR$\..\..\..\security\mbedtls\src\mbedtls_net.c - $PROJ_DIR$\..\..\..\security\mbedtls\mbedtls_ssl.c + $PROJ_DIR$\..\..\..\security\mbedtls\src\mbedtls_ssl.c Debug @@ -2973,10 +2973,10 @@ ALIOT_DEBUG IOTX_DEBUG STM32L475xx - SYSINFO_OS_VERSION="AOS-R-1.1.2-" + SYSINFO_OS_VERSION="AOS-R-1.2.0-" SYSINFO_PRODUCT_MODEL="ALI_AOS_B-L475E" SYSINFO_DEVICE_NAME="B-L475E" - SYSINFO_KERNEL_VERSION="AOS-R-1.1.2" + SYSINFO_KERNEL_VERSION="AOS-R-1.2.0" SYSINFO_APP_VERSION="APP-1.0.0-" __arm__ __thumb__ @@ -3108,14 +3108,14 @@ CCIncludePath2 $PROJ_DIR$\..\..\..\framework\fota\socket\stm32wifi $PROJ_DIR$\..\..\..\framework\fota\platform\mqtt - $PROJ_DIR$\..\..\..\utility\iotx-utils\device + $PROJ_DIR$\..\..\..\utility\iotx-utils\iotx-system $PROJ_DIR$\..\..\..\security\alicrypto\inc $PROJ_DIR$\..\..\..\security\alicrypto\test $PROJ_DIR$\..\..\..\kernel\modules\fs\kv\include $PROJ_DIR$\..\..\..\framework\fota\socket\ $PROJ_DIR$\..\..\..\framework\fota\platform\ $PROJ_DIR$\..\..\..\utility\iotx-utils\guider - $PROJ_DIR$\..\..\..\utility\iotx-utils\device + $PROJ_DIR$\..\..\..\utility\iotx-utils\iotx-system $PROJ_DIR$\..\..\..\utility\iotx-utils\LITE-utils $PROJ_DIR$\..\..\..\utility\iotx-utils\LITE-log $PROJ_DIR$\..\..\..\utility\iotx-utils\misc @@ -3333,10 +3333,10 @@ ALIOT_DEBUG IOTX_DEBUG STM32L475xx - SYSINFO_OS_VERSION="AOS-R-1.1.2-" + SYSINFO_OS_VERSION="AOS-R-1.2.0-" SYSINFO_PRODUCT_MODEL="ALI_AOS_B-L475E" SYSINFO_DEVICE_NAME="B-L475E" - SYSINFO_KERNEL_VERSION="AOS-R-1.1.2" + SYSINFO_KERNEL_VERSION="AOS-R-1.2.0" SYSINFO_APP_VERSION="APP-1.0.0-" __arm__ __thumb__ @@ -3468,14 +3468,14 @@ CCIncludePath2 $PROJ_DIR$\..\..\..\framework\fota\socket\stm32wifi\ $PROJ_DIR$\..\..\..\framework\fota\platform\mqtt\ - $PROJ_DIR$\..\..\..\utility\iotx-utils\device\ + $PROJ_DIR$\..\..\..\utility\iotx-utils\iotx-system\ $PROJ_DIR$\..\..\..\security\alicrypto\inc $PROJ_DIR$\..\..\..\security\alicrypto\test $PROJ_DIR$\..\..\..\kernel\modules\fs\kv\include $PROJ_DIR$\..\..\..\framework\fota\socket\ $PROJ_DIR$\..\..\..\framework\fota\platform\ $PROJ_DIR$\..\..\..\utility\iotx-utils\guider\ - $PROJ_DIR$\..\..\..\utility\iotx-utils\device + $PROJ_DIR$\..\..\..\utility\iotx-utils\iotx-system $PROJ_DIR$\..\..\..\utility\iotx-utils\LITE-utils $PROJ_DIR$\..\..\..\utility\iotx-utils\LITE-log $PROJ_DIR$\..\..\..\utility\iotx-utils\misc @@ -3632,10 +3632,10 @@ device - $PROJ_DIR$\..\..\..\utility\iotx-utils\device\ca.c + $PROJ_DIR$\..\..\..\utility\iotx-utils\iotx-system\ca.c - $PROJ_DIR$\..\..\..\utility\iotx-utils\device\device_iar.c + $PROJ_DIR$\..\..\..\utility\iotx-utils\iotx-system\device_iar.c @@ -3700,10 +3700,10 @@ ALIOT_DEBUG IOTX_DEBUG STM32L475xx - SYSINFO_OS_VERSION="AOS-R-1.1.2-" + SYSINFO_OS_VERSION="AOS-R-1.2.0-" SYSINFO_PRODUCT_MODEL="ALI_AOS_B-L475E" SYSINFO_DEVICE_NAME="B-L475E" - SYSINFO_KERNEL_VERSION="AOS-R-1.1.2" + SYSINFO_KERNEL_VERSION="AOS-R-1.2.0" SYSINFO_APP_VERSION="APP-1.0.0-" __arm__ __thumb__ @@ -3834,14 +3834,14 @@ CCIncludePath2 $PROJ_DIR$\..\..\..\framework\fota\socket\stm32wifi\ $PROJ_DIR$\..\..\..\framework\fota\platform\mqtt\ - $PROJ_DIR$\..\..\..\utility\iotx-utils\device\ + $PROJ_DIR$\..\..\..\utility\iotx-utils\iotx-system\ $PROJ_DIR$\..\..\..\security\alicrypto\inc $PROJ_DIR$\..\..\..\security\alicrypto\test $PROJ_DIR$\..\..\..\kernel\modules\fs\kv\include $PROJ_DIR$\..\..\..\framework\fota\socket\ $PROJ_DIR$\..\..\..\framework\fota\platform\ $PROJ_DIR$\..\..\..\utility\iotx-utils\guider\ - $PROJ_DIR$\..\..\..\utility\iotx-utils\device + $PROJ_DIR$\..\..\..\utility\iotx-utils\iotx-system $PROJ_DIR$\..\..\..\utility\iotx-utils\LITE-utils $PROJ_DIR$\..\..\..\utility\iotx-utils\LITE-log $PROJ_DIR$\..\..\..\utility\iotx-utils\misc @@ -4043,10 +4043,10 @@ ALIOT_DEBUG IOTX_DEBUG STM32L475xx - SYSINFO_OS_VERSION="AOS-R-1.1.2-" + SYSINFO_OS_VERSION="AOS-R-1.2.0-" SYSINFO_PRODUCT_MODEL="ALI_AOS_B-L475E" SYSINFO_DEVICE_NAME="B-L475E" - SYSINFO_KERNEL_VERSION="AOS-R-1.1.2" + SYSINFO_KERNEL_VERSION="AOS-R-1.2.0" SYSINFO_APP_VERSION="APP-1.0.0-" __arm__ __thumb__ @@ -4177,14 +4177,14 @@ CCIncludePath2 $PROJ_DIR$\..\..\..\framework\fota\socket\stm32wifi\ $PROJ_DIR$\..\..\..\framework\fota\platform\mqtt\ - $PROJ_DIR$\..\..\..\utility\iotx-utils\device\ + $PROJ_DIR$\..\..\..\utility\iotx-utils\iotx-system\ $PROJ_DIR$\..\..\..\security\alicrypto\inc $PROJ_DIR$\..\..\..\security\alicrypto\test $PROJ_DIR$\..\..\..\kernel\modules\fs\kv\include $PROJ_DIR$\..\..\..\framework\fota\socket\ $PROJ_DIR$\..\..\..\framework\fota\platform\ $PROJ_DIR$\..\..\..\utility\iotx-utils\guider\ - $PROJ_DIR$\..\..\..\utility\iotx-utils\device + $PROJ_DIR$\..\..\..\utility\iotx-utils\iotx-system $PROJ_DIR$\..\..\..\utility\iotx-utils\LITE-utils $PROJ_DIR$\..\..\..\utility\iotx-utils\LITE-log $PROJ_DIR$\..\..\..\utility\iotx-utils\misc diff --git a/projects/IAR/mqttapp/alios.ewt b/projects/IAR/mqttapp/alios.ewt index 722b6e20d9..e7cc855423 100644 --- a/projects/IAR/mqttapp/alios.ewt +++ b/projects/IAR/mqttapp/alios.ewt @@ -2539,7 +2539,7 @@ $PROJ_DIR$\..\..\..\kernel\rhino\core\k_event.c - $PROJ_DIR$\..\..\..\kernel\rhino\core\k_fifo.c + $PROJ_DIR$\..\..\..\kernel\rhino\common\k_fifo.c $PROJ_DIR$\..\..\..\kernel\rhino\core\k_idle.c @@ -2599,7 +2599,7 @@ $PROJ_DIR$\..\..\..\kernel\rhino\core\k_timer.c - $PROJ_DIR$\..\..\..\kernel\rhino\core\k_trace.c + $PROJ_DIR$\..\..\..\kernel\rhino\common\k_trace.c $PROJ_DIR$\..\..\..\kernel\rhino\core\k_workqueue.c @@ -2842,10 +2842,10 @@ mbedtls - $PROJ_DIR$\..\..\..\security\mbedtls\mbedtls_net.c + $PROJ_DIR$\..\..\..\security\mbedtls\src\mbedtls_net.c - $PROJ_DIR$\..\..\..\security\mbedtls\mbedtls_ssl.c + $PROJ_DIR$\..\..\..\security\mbedtls\src\mbedtls_ssl.c Debug @@ -2889,10 +2889,10 @@ device - $PROJ_DIR$\..\..\..\utility\iotx-utils\device\ca.c + $PROJ_DIR$\..\..\..\utility\iotx-utils\iotx-system\ca.c - $PROJ_DIR$\..\..\..\utility\iotx-utils\device\device_iar.c + $PROJ_DIR$\..\..\..\utility\iotx-utils\iotx-system\device_iar.c diff --git a/projects/IAR/sensorapp/sensorapp.ewp b/projects/IAR/sensorapp/sensorapp.ewp index 7bde1d2a56..5640b82654 100644 --- a/projects/IAR/sensorapp/sensorapp.ewp +++ b/projects/IAR/sensorapp/sensorapp.ewp @@ -236,10 +236,10 @@ ALIOT_DEBUG IOTX_DEBUG STM32L475xx - SYSINFO_OS_VERSION="AOS-R-1.1.2-" + SYSINFO_OS_VERSION="AOS-R-1.2.0-" SYSINFO_PRODUCT_MODEL="ALI_AOS_B-L475E" SYSINFO_DEVICE_NAME="B-L475E" - SYSINFO_KERNEL_VERSION="AOS-R-1.1.2" + SYSINFO_KERNEL_VERSION="AOS-R-1.2.0" SYSINFO_APP_VERSION="APP-1.0.0-20171128.1211" __arm__ __thumb__ @@ -370,14 +370,14 @@ CCIncludePath2 $PROJ_DIR$\..\..\..\framework\fota\socket\stm32wifi $PROJ_DIR$\..\..\..\framework\fota\platform\mqtt - $PROJ_DIR$\..\..\..\utility\iotx-utils\device + $PROJ_DIR$\..\..\..\utility\iotx-utils\iotx-system $PROJ_DIR$\..\..\..\security\alicrypto\inc $PROJ_DIR$\..\..\..\security\alicrypto\test $PROJ_DIR$\..\..\..\kernel\modules\fs\kv\include $PROJ_DIR$\..\..\..\framework\fota\socket\ $PROJ_DIR$\..\..\..\framework\fota\platform\ $PROJ_DIR$\..\..\..\utility\iotx-utils\guider - $PROJ_DIR$\..\..\..\utility\iotx-utils\device + $PROJ_DIR$\..\..\..\utility\iotx-utils\iotx-system $PROJ_DIR$\..\..\..\utility\iotx-utils\LITE-utils $PROJ_DIR$\..\..\..\utility\iotx-utils\LITE-log $PROJ_DIR$\..\..\..\utility\iotx-utils\misc @@ -2298,7 +2298,7 @@ $PROJ_DIR$\..\..\..\kernel\rhino\core\k_event.c - $PROJ_DIR$\..\..\..\kernel\rhino\core\k_fifo.c + $PROJ_DIR$\..\..\..\kernel\rhino\common\k_fifo.c $PROJ_DIR$\..\..\..\kernel\rhino\core\k_idle.c @@ -2358,7 +2358,7 @@ $PROJ_DIR$\..\..\..\kernel\rhino\core\k_timer.c - $PROJ_DIR$\..\..\..\kernel\rhino\core\k_trace.c + $PROJ_DIR$\..\..\..\kernel\rhino\common\k_trace.c $PROJ_DIR$\..\..\..\kernel\rhino\core\k_workqueue.c @@ -2607,10 +2607,10 @@ mbedtls - $PROJ_DIR$\..\..\..\security\mbedtls\mbedtls_net.c + $PROJ_DIR$\..\..\..\security\mbedtls\src\mbedtls_net.c - $PROJ_DIR$\..\..\..\security\mbedtls\mbedtls_ssl.c + $PROJ_DIR$\..\..\..\security\mbedtls\src\mbedtls_ssl.c Debug @@ -2648,10 +2648,10 @@ ALIOT_DEBUG IOTX_DEBUG STM32L475xx - SYSINFO_OS_VERSION="AOS-R-1.1.2-" + SYSINFO_OS_VERSION="AOS-R-1.2.0-" SYSINFO_PRODUCT_MODEL="ALI_AOS_B-L475E" SYSINFO_DEVICE_NAME="B-L475E" - SYSINFO_KERNEL_VERSION="AOS-R-1.1.2" + SYSINFO_KERNEL_VERSION="AOS-R-1.2.0" SYSINFO_APP_VERSION="APP-1.0.0-" __arm__ __thumb__ @@ -2783,14 +2783,14 @@ CCIncludePath2 $PROJ_DIR$\..\..\..\framework\fota\socket\stm32wifi $PROJ_DIR$\..\..\..\framework\fota\platform\mqtt - $PROJ_DIR$\..\..\..\utility\iotx-utils\device + $PROJ_DIR$\..\..\..\utility\iotx-utils\iotx-system $PROJ_DIR$\..\..\..\security\alicrypto\inc $PROJ_DIR$\..\..\..\security\alicrypto\test $PROJ_DIR$\..\..\..\kernel\modules\fs\kv\include $PROJ_DIR$\..\..\..\framework\fota\socket\ $PROJ_DIR$\..\..\..\framework\fota\platform\ $PROJ_DIR$\..\..\..\utility\iotx-utils\guider - $PROJ_DIR$\..\..\..\utility\iotx-utils\device + $PROJ_DIR$\..\..\..\utility\iotx-utils\iotx-system $PROJ_DIR$\..\..\..\utility\iotx-utils\LITE-utils $PROJ_DIR$\..\..\..\utility\iotx-utils\LITE-log $PROJ_DIR$\..\..\..\utility\iotx-utils\misc @@ -2996,10 +2996,10 @@ ALIOT_DEBUG IOTX_DEBUG STM32L475xx - SYSINFO_OS_VERSION="AOS-R-1.1.2-" + SYSINFO_OS_VERSION="AOS-R-1.2.0-" SYSINFO_PRODUCT_MODEL="ALI_AOS_B-L475E" SYSINFO_DEVICE_NAME="B-L475E" - SYSINFO_KERNEL_VERSION="AOS-R-1.1.2" + SYSINFO_KERNEL_VERSION="AOS-R-1.2.0" SYSINFO_APP_VERSION="APP-1.0.0-" __arm__ __thumb__ @@ -3131,14 +3131,14 @@ CCIncludePath2 $PROJ_DIR$\..\..\..\framework\fota\socket\stm32wifi $PROJ_DIR$\..\..\..\framework\fota\platform\mqtt - $PROJ_DIR$\..\..\..\utility\iotx-utils\device + $PROJ_DIR$\..\..\..\utility\iotx-utils\iotx-system $PROJ_DIR$\..\..\..\security\alicrypto\inc $PROJ_DIR$\..\..\..\security\alicrypto\test $PROJ_DIR$\..\..\..\kernel\modules\fs\kv\include $PROJ_DIR$\..\..\..\framework\fota\socket\ $PROJ_DIR$\..\..\..\framework\fota\platform\ $PROJ_DIR$\..\..\..\utility\iotx-utils\guider - $PROJ_DIR$\..\..\..\utility\iotx-utils\device + $PROJ_DIR$\..\..\..\utility\iotx-utils\iotx-system $PROJ_DIR$\..\..\..\utility\iotx-utils\LITE-utils $PROJ_DIR$\..\..\..\utility\iotx-utils\LITE-log $PROJ_DIR$\..\..\..\utility\iotx-utils\misc @@ -3296,10 +3296,10 @@ device - $PROJ_DIR$\..\..\..\utility\iotx-utils\device\ca.c + $PROJ_DIR$\..\..\..\utility\iotx-utils\iotx-system\ca.c - $PROJ_DIR$\..\..\..\utility\iotx-utils\device\device_iar.c + $PROJ_DIR$\..\..\..\utility\iotx-utils\iotx-system\device_iar.c @@ -3364,10 +3364,10 @@ ALIOT_DEBUG IOTX_DEBUG STM32L475xx - SYSINFO_OS_VERSION="AOS-R-1.1.2-" + SYSINFO_OS_VERSION="AOS-R-1.2.0-" SYSINFO_PRODUCT_MODEL="ALI_AOS_B-L475E" SYSINFO_DEVICE_NAME="B-L475E" - SYSINFO_KERNEL_VERSION="AOS-R-1.1.2" + SYSINFO_KERNEL_VERSION="AOS-R-1.2.0" SYSINFO_APP_VERSION="APP-1.0.0-" __arm__ __thumb__ @@ -3498,14 +3498,14 @@ CCIncludePath2 $PROJ_DIR$\..\..\..\framework\fota\socket\stm32wifi\ $PROJ_DIR$\..\..\..\framework\fota\platform\mqtt\ - $PROJ_DIR$\..\..\..\utility\iotx-utils\device\ + $PROJ_DIR$\..\..\..\utility\iotx-utils\iotx-system\ $PROJ_DIR$\..\..\..\security\alicrypto\inc $PROJ_DIR$\..\..\..\security\alicrypto\test $PROJ_DIR$\..\..\..\kernel\modules\fs\kv\include $PROJ_DIR$\..\..\..\framework\fota\socket\ $PROJ_DIR$\..\..\..\framework\fota\platform\ $PROJ_DIR$\..\..\..\utility\iotx-utils\guider\ - $PROJ_DIR$\..\..\..\utility\iotx-utils\device + $PROJ_DIR$\..\..\..\utility\iotx-utils\iotx-system $PROJ_DIR$\..\..\..\utility\iotx-utils\LITE-utils $PROJ_DIR$\..\..\..\utility\iotx-utils\LITE-log $PROJ_DIR$\..\..\..\utility\iotx-utils\misc @@ -3707,10 +3707,10 @@ ALIOT_DEBUG IOTX_DEBUG STM32L475xx - SYSINFO_OS_VERSION="AOS-R-1.1.2-" + SYSINFO_OS_VERSION="AOS-R-1.2.0-" SYSINFO_PRODUCT_MODEL="ALI_AOS_B-L475E" SYSINFO_DEVICE_NAME="B-L475E" - SYSINFO_KERNEL_VERSION="AOS-R-1.1.2" + SYSINFO_KERNEL_VERSION="AOS-R-1.2.0" SYSINFO_APP_VERSION="APP-1.0.0-" __arm__ __thumb__ @@ -3841,14 +3841,14 @@ CCIncludePath2 $PROJ_DIR$\..\..\..\framework\fota\socket\stm32wifi\ $PROJ_DIR$\..\..\..\framework\fota\platform\mqtt\ - $PROJ_DIR$\..\..\..\utility\iotx-utils\device\ + $PROJ_DIR$\..\..\..\utility\iotx-utils\iotx-system\ $PROJ_DIR$\..\..\..\security\alicrypto\inc $PROJ_DIR$\..\..\..\security\alicrypto\test $PROJ_DIR$\..\..\..\kernel\modules\fs\kv\include $PROJ_DIR$\..\..\..\framework\fota\socket\ $PROJ_DIR$\..\..\..\framework\fota\platform\ $PROJ_DIR$\..\..\..\utility\iotx-utils\guider\ - $PROJ_DIR$\..\..\..\utility\iotx-utils\device + $PROJ_DIR$\..\..\..\utility\iotx-utils\iotx-system $PROJ_DIR$\..\..\..\utility\iotx-utils\LITE-utils $PROJ_DIR$\..\..\..\utility\iotx-utils\LITE-log $PROJ_DIR$\..\..\..\utility\iotx-utils\misc diff --git a/projects/IAR/sensorapp/sensorapp.ewt b/projects/IAR/sensorapp/sensorapp.ewt index 2ca51f5372..5449e304c3 100644 --- a/projects/IAR/sensorapp/sensorapp.ewt +++ b/projects/IAR/sensorapp/sensorapp.ewt @@ -2536,7 +2536,7 @@ $PROJ_DIR$\..\..\..\kernel\rhino\core\k_event.c - $PROJ_DIR$\..\..\..\kernel\rhino\core\k_fifo.c + $PROJ_DIR$\..\..\..\kernel\rhino\common\k_fifo.c $PROJ_DIR$\..\..\..\kernel\rhino\core\k_idle.c @@ -2596,7 +2596,7 @@ $PROJ_DIR$\..\..\..\kernel\rhino\core\k_timer.c - $PROJ_DIR$\..\..\..\kernel\rhino\core\k_trace.c + $PROJ_DIR$\..\..\..\kernel\rhino\common\k_trace.c $PROJ_DIR$\..\..\..\kernel\rhino\core\k_workqueue.c @@ -2845,10 +2845,10 @@ mbedtls - $PROJ_DIR$\..\..\..\security\mbedtls\mbedtls_net.c + $PROJ_DIR$\..\..\..\security\mbedtls\src\mbedtls_net.c - $PROJ_DIR$\..\..\..\security\mbedtls\mbedtls_ssl.c + $PROJ_DIR$\..\..\..\security\mbedtls\src\mbedtls_ssl.c Debug @@ -2880,10 +2880,10 @@ device - $PROJ_DIR$\..\..\..\utility\iotx-utils\device\ca.c + $PROJ_DIR$\..\..\..\utility\iotx-utils\iotx-system\ca.c - $PROJ_DIR$\..\..\..\utility\iotx-utils\device\device_iar.c + $PROJ_DIR$\..\..\..\utility\iotx-utils\iotx-system\device_iar.c diff --git a/projects/Keil/B-L475E-IOT01/mqttapp/B-L475E-IOT01.uvoptx b/projects/Keil/B-L475E-IOT01/mqttapp/B-L475E-IOT01.uvoptx index 21643aec7b..76ea85209d 100644 --- a/projects/Keil/B-L475E-IOT01/mqttapp/B-L475E-IOT01.uvoptx +++ b/projects/Keil/B-L475E-IOT01/mqttapp/B-L475E-IOT01.uvoptx @@ -839,8 +839,8 @@ 0 0 0 - ..\..\..\..\platform\arch\arm\armv7m\armcc\m4\port_c.s - port_c.s + ..\..\..\..\platform\arch\arm\armv7m\armcc\m4\port_s.s + port_s.s 0 0 @@ -1115,7 +1115,7 @@ 0 0 0 - ..\..\..\..\kernel\rhino\core\k_fifo.c + ..\..\..\..\kernel\rhino\common\k_fifo.c k_fifo.c 0 0 @@ -1355,7 +1355,7 @@ 0 0 0 - ..\..\..\..\kernel\rhino\core\k_trace.c + ..\..\..\..\kernel\rhino\common\k_trace.c k_trace.c 0 0 @@ -1919,7 +1919,7 @@ - utility/iotx-utils/device + utility/iotx-utils/iotx-system 0 0 0 @@ -1931,7 +1931,7 @@ 0 0 0 - ..\..\..\..\utility\iotx-utils\device\ca.c + ..\..\..\..\utility\iotx-utils\iotx-system\ca.c ca.c 0 0 @@ -1943,7 +1943,7 @@ 0 0 0 - ..\..\..\..\utility\iotx-utils\device\device.c + ..\..\..\..\utility\iotx-utils\iotx-system\device.c device.c 0 0 @@ -2295,7 +2295,7 @@ 0 0 0 - ..\..\..\..\security\mbedtls\mbedtls_net.c + ..\..\..\..\security\mbedtls\src\mbedtls_net.c mbedtls_net.c 0 0 @@ -2307,7 +2307,7 @@ 0 0 0 - ..\..\..\..\security\mbedtls\mbedtls_ssl.c + ..\..\..\..\security\mbedtls\src\mbedtls_ssl.c mbedtls_ssl.c 0 0 diff --git a/projects/Keil/B-L475E-IOT01/mqttapp/B-L475E-IOT01.uvprojx b/projects/Keil/B-L475E-IOT01/mqttapp/B-L475E-IOT01.uvprojx index b8b662ba38..97959334d0 100644 --- a/projects/Keil/B-L475E-IOT01/mqttapp/B-L475E-IOT01.uvprojx +++ b/projects/Keil/B-L475E-IOT01/mqttapp/B-L475E-IOT01.uvprojx @@ -332,10 +332,10 @@ 0 0 - -DSYSINFO_OS_VERSION=\"APP-1.0.0-20171128.1211\" -DSYSINFO_PRODUCT_MODEL=\"ALI_AOS_STM32L475VGT6\" -DSYSINFO_DEVICE_NAME=\"STM32L475VGT6\" -DSYSINFO_KERNEL_VERSION=\"AOS-R-1.1.2\" -DSYSINFO_APP_VERSION=\"APP-1.0.0\" -DSTDIO_UART=0 -DCONFIG_NO_TCPIP -DRHINO_CONFIG_TICK_TASK=0 -DCONFIG_AOS_KV_MULTIPTN_MODE -DCONFIG_AOS_KV_PTN=6 -DCONFIG_AOS_KV_SECOND_PTN=7 -DCONFIG_AOS_KV_PTN_SIZE=4096 -DCONFIG_AOS_KV_BUFFER_SIZE=8192 -D__BSD_VISIBLE -DRHINO_CONFIG_TICK_TASK=0 + -DSYSINFO_OS_VERSION=\"APP-1.0.0-20171128.1211\" -DSYSINFO_PRODUCT_MODEL=\"ALI_AOS_STM32L475VGT6\" -DSYSINFO_DEVICE_NAME=\"STM32L475VGT6\" -DSYSINFO_KERNEL_VERSION=\"AOS-R-1.2.0\" -DSYSINFO_APP_VERSION=\"APP-1.0.0\" -DSTDIO_UART=0 -DCONFIG_NO_TCPIP -DRHINO_CONFIG_TICK_TASK=0 -DCONFIG_AOS_KV_MULTIPTN_MODE -DCONFIG_AOS_KV_PTN=6 -DCONFIG_AOS_KV_SECOND_PTN=7 -DCONFIG_AOS_KV_PTN_SIZE=4096 -DCONFIG_AOS_KV_BUFFER_SIZE=8192 -D__BSD_VISIBLE -DRHINO_CONFIG_TICK_TASK=0 USE_HAL_DRIVER,STM32L475xx,VCALL_RHINO,AOS_KV,AOS_VFS,AOS_LOOP,AOS_FRAMEWORK_COMMON,CONFIG_AOS_CLI,SENSOR,AOS_FOTA,STM32_USE_SPI_WIFI - ../../../../include;../../../../board/b_l475e;../../../../kernel/rhino/core/include;../../../../platform/arch/arm/armv7m/armcc/m4;../../../../platform/mcu/stm32l475/Drivers/STM32L4xx_HAL_Driver/Inc;../../../../platform/mcu/stm32l475/Drivers/BSP/B-L475E-IOT01;../../../../platform/mcu/stm32l475/src/B-L475E-IOT01/include;../../../../platform/mcu/stm32l475/Drivers/BSP/Components/es_wifi;../../../../platform/mcu/stm32l475/Drivers/BSP/Components/hts221;../../../../platform/mcu/stm32l475/Drivers/BSP/Components/lis3mdl;../../../../platform/mcu/stm32l475/Drivers/BSP/Components/lps22hb;../../../../platform/mcu/stm32l475/Drivers/BSP/Components/lsm6dsl;../../../../platform/mcu/stm32l475/Drivers/BSP/Components/vl53l0x;../../../../platform/mcu/stm32l475/src/B-L475E-IOT01/runapp;../../../../platform/mcu/stm32l475/Drivers/CMSIS/Include;../../../../platform/mcu/stm32l475/src/common/csp/wifi/inc;../../../../platform/mcu/stm32l475/src/B-L475E-IOT01/hal;../../../../kernel/modules/fs/kv/include;../../../../kernel/vcall/aos;../../../../kernel/vfs/include;../../../../kernel/yloop;../../../../utility/libc/compilers/armlibc;../../../../platform/mcu/stm32l4xx/hal;../../../../utility/digest_algorithm;../../../../framework/connectivity/mqtt;../../../../framework/connectivity/mqtt/MQTTPacket;../../../../utility/iotx-utils/device;../../../../utility/iotx-utils/digest;../../../../utility/iotx-utils/guider;../../../../utility/iotx-utils/LITE-log;../../../../utility/iotx-utils/LITE-utils;../../../../utility/iotx-utils/misc;../../../../utility/iotx-utils/sdk-impl;../../../../utility/iotx-utils/sdk-impl/imports;../../../../utility/iotx-utils/sdk-impl/exports;../../../../security/mbedtls/include;../../../../framework/netmgr/include;../../../../security/alicrypto/inc;../../../../framework/fota;../../../../framework/fota/platform;../../../../framework/fota/download;../../../../framework/fota/download/http/socket;../../../../utility/cjson/include + ../../../../include;../../../../board/b_l475e;../../../../kernel/rhino/core/include;../../../../platform/arch/arm/armv7m/armcc/m4;../../../../platform/mcu/stm32l475/Drivers/STM32L4xx_HAL_Driver/Inc;../../../../platform/mcu/stm32l475/Drivers/BSP/B-L475E-IOT01;../../../../platform/mcu/stm32l475/src/B-L475E-IOT01/include;../../../../platform/mcu/stm32l475/Drivers/BSP/Components/es_wifi;../../../../platform/mcu/stm32l475/Drivers/BSP/Components/hts221;../../../../platform/mcu/stm32l475/Drivers/BSP/Components/lis3mdl;../../../../platform/mcu/stm32l475/Drivers/BSP/Components/lps22hb;../../../../platform/mcu/stm32l475/Drivers/BSP/Components/lsm6dsl;../../../../platform/mcu/stm32l475/Drivers/BSP/Components/vl53l0x;../../../../platform/mcu/stm32l475/src/B-L475E-IOT01/runapp;../../../../platform/mcu/stm32l475/Drivers/CMSIS/Include;../../../../platform/mcu/stm32l475/src/common/csp/wifi/inc;../../../../platform/mcu/stm32l475/src/B-L475E-IOT01/hal;../../../../kernel/modules/fs/kv/include;../../../../kernel/vcall/aos;../../../../kernel/vfs/include;../../../../kernel/yloop;../../../../utility/libc/compilers/armlibc;../../../../platform/mcu/stm32l4xx/hal;../../../../utility/digest_algorithm;../../../../framework/connectivity/mqtt;../../../../framework/connectivity/mqtt/MQTTPacket;../../../../utility/iotx-utils/iotx-system;../../../../utility/iotx-utils/digest;../../../../utility/iotx-utils/guider;../../../../utility/iotx-utils/LITE-log;../../../../utility/iotx-utils/LITE-utils;../../../../utility/iotx-utils/misc;../../../../utility/iotx-utils/sdk-impl;../../../../utility/iotx-utils/sdk-impl/imports;../../../../utility/iotx-utils/sdk-impl/exports;../../../../security/mbedtls/include;../../../../framework/netmgr/include;../../../../security/alicrypto/inc;../../../../framework/fota;../../../../framework/fota/platform;../../../../framework/fota/download;../../../../framework/fota/download/http/socket;../../../../utility/cjson/include;..\..\..\..\utility\iotx-utils\iotx-system @@ -655,9 +655,9 @@ ..\..\..\..\platform\arch\arm\armv7m\armcc\m4\port_c.c - port_c.s + port_s.s 2 - ..\..\..\..\platform\arch\arm\armv7m\armcc\m4\port_c.s + ..\..\..\..\platform\arch\arm\armv7m\armcc\m4\port_s.s @@ -782,7 +782,7 @@ k_fifo.c 1 - ..\..\..\..\kernel\rhino\core\k_fifo.c + ..\..\..\..\kernel\rhino\common\k_fifo.c k_idle.c @@ -882,7 +882,7 @@ k_trace.c 1 - ..\..\..\..\kernel\rhino\core\k_trace.c + ..\..\..\..\kernel\rhino\common\k_trace.c k_workqueue.c @@ -1142,17 +1142,17 @@ - utility/iotx-utils/device + utility/iotx-utils/iotx-system ca.c 1 - ..\..\..\..\utility\iotx-utils\device\ca.c + ..\..\..\..\utility\iotx-utils\iotx-system\ca.c device.c 1 - ..\..\..\..\utility\iotx-utils\device\device.c + ..\..\..\..\utility\iotx-utils\iotx-system\device.c @@ -1317,12 +1317,12 @@ mbedtls_net.c 1 - ..\..\..\..\security\mbedtls\mbedtls_net.c + ..\..\..\..\security\mbedtls\src\mbedtls_net.c mbedtls_ssl.c 1 - ..\..\..\..\security\mbedtls\mbedtls_ssl.c + ..\..\..\..\security\mbedtls\src\mbedtls_ssl.c diff --git a/projects/Keil/STM32L073RZ-Nucleo/aos_rhino/STM32L073RZTx.uvoptx b/projects/Keil/STM32L073RZ-Nucleo/aos_rhino/STM32L073RZTx.uvoptx index e0e6a96b08..df6f302f7d 100644 --- a/projects/Keil/STM32L073RZ-Nucleo/aos_rhino/STM32L073RZTx.uvoptx +++ b/projects/Keil/STM32L073RZ-Nucleo/aos_rhino/STM32L073RZTx.uvoptx @@ -549,7 +549,7 @@ 0 0 0 - ..\..\..\..\kernel\rhino\core\k_fifo.c + ..\..\..\..\kernel\rhino\common\k_fifo.c k_fifo.c 0 0 @@ -789,7 +789,7 @@ 0 0 0 - ..\..\..\..\kernel\rhino\core\k_trace.c + ..\..\..\..\kernel\rhino\common\k_trace.c k_trace.c 0 0 diff --git a/projects/Keil/STM32L073RZ-Nucleo/aos_rhino/STM32L073RZTx.uvprojx b/projects/Keil/STM32L073RZ-Nucleo/aos_rhino/STM32L073RZTx.uvprojx index 7189b195e9..0c3b599a6d 100644 --- a/projects/Keil/STM32L073RZ-Nucleo/aos_rhino/STM32L073RZTx.uvprojx +++ b/projects/Keil/STM32L073RZ-Nucleo/aos_rhino/STM32L073RZTx.uvprojx @@ -332,10 +332,10 @@ 0 0 - --C99 -DSYSINFO_OS_VERSION=\"APP-1.0.0\" -DSYSINFO_PRODUCT_MODEL=\"ALI_AOS_STM32L073RZTx\" -DSYSINFO_DEVICE_NAME=\"STM32L073RZTx\" -DSYSINFO_KERNEL_VERSION=\"AOS-R-1.1.2\" -DSYSINFO_APP_VERSION=\"APP-1.0.0\" -DSTDIO_UART=0 -DCONFIG_NO_TCPIP -DRHINO_CONFIG_TICK_TASK=0 -DCONFIG_AOS_KV_MULTIPTN_MODE -DCONFIG_AOS_KV_PTN=6 -DCONFIG_AOS_KV_SECOND_PTN=7 -DCONFIG_AOS_KV_PTN_SIZE=4096 -DCONFIG_AOS_KV_BUFFER_SIZE=8192 -D__BSD_VISIBLE -DRHINO_CONFIG_TICK_TASK=0 + --C99 -DSYSINFO_OS_VERSION=\"APP-1.0.0\" -DSYSINFO_PRODUCT_MODEL=\"ALI_AOS_STM32L073RZTx\" -DSYSINFO_DEVICE_NAME=\"STM32L073RZTx\" -DSYSINFO_KERNEL_VERSION=\"AOS-R-1.2.0\" -DSYSINFO_APP_VERSION=\"APP-1.0.0\" -DSTDIO_UART=0 -DCONFIG_NO_TCPIP -DRHINO_CONFIG_TICK_TASK=0 -DCONFIG_AOS_KV_MULTIPTN_MODE -DCONFIG_AOS_KV_PTN=6 -DCONFIG_AOS_KV_SECOND_PTN=7 -DCONFIG_AOS_KV_PTN_SIZE=4096 -DCONFIG_AOS_KV_BUFFER_SIZE=8192 -D__BSD_VISIBLE -DRHINO_CONFIG_TICK_TASK=0 USE_HAL_DRIVER,STM32L073xx,AOS_KV - ..\..\..\..\include;..\..\..\..\kernel\rhino\core\include;..\..\..\..\platform\arch\arm\armv6m\armcc\m0plus;..\..\..\..\platform\mcu\stm32l0xx\Drivers\STM32L0xx_HAL_Driver\Inc;..\..\..\..\platform\mcu\stm32l0xx\Drivers\STM32L0xx_HAL_Driver\Inc\Legacy;..\..\..\..\platform\mcu\stm32l0xx\Drivers\CMSIS\Device\ST\STM32L0xx\Include;..\..\..\..\platform\mcu\stm32l0xx\Drivers\CMSIS\Include;..\..\..\..\platform\mcu\stm32l0xx\src\STM32L073RZ-Nucleo\aos_rhino;..\..\..\..\include\hal;..\..\..\..\kernel\modules\fs\kv\include;..\..\..\..\kernel\vcall\aos;..\..\..\..\utility\libc\compilers\armlibc + ..\..\..\..\include;..\..\..\..\kernel\rhino\core\include;..\..\..\..\platform\arch\arm\armv6m\armcc\m0plus;..\..\..\..\platform\mcu\stm32l0xx\Drivers\STM32L0xx_HAL_Driver\Inc;..\..\..\..\platform\mcu\stm32l0xx\Drivers\STM32L0xx_HAL_Driver\Inc\Legacy;..\..\..\..\platform\mcu\stm32l0xx\Drivers\CMSIS\Device\ST\STM32L0xx\Include;..\..\..\..\platform\mcu\stm32l0xx\Drivers\CMSIS\Include;..\..\..\..\platform\mcu\stm32l0xx\src\STM32L073RZ-Nucleo\aos_rhino;..\..\..\..\include\hal;..\..\..\..\kernel\modules\fs\kv\include;..\..\..\..\kernel\vcall\aos;..\..\..\..\utility\libc\compilers\armlibc;..\..\..\..\kernel\vfs\include @@ -532,7 +532,7 @@ k_fifo.c 1 - ..\..\..\..\kernel\rhino\core\k_fifo.c + ..\..\..\..\kernel\rhino\common\k_fifo.c k_idle.c @@ -632,7 +632,7 @@ k_trace.c 1 - ..\..\..\..\kernel\rhino\core\k_trace.c + ..\..\..\..\kernel\rhino\common\k_trace.c k_workqueue.c diff --git a/projects/Keil/STM32L073RZ-Nucleo/helloworld/STM32L073RZTx.uvoptx b/projects/Keil/STM32L073RZ-Nucleo/helloworld/STM32L073RZTx.uvoptx index fabcf2e45b..11bc2bcede 100644 --- a/projects/Keil/STM32L073RZ-Nucleo/helloworld/STM32L073RZTx.uvoptx +++ b/projects/Keil/STM32L073RZ-Nucleo/helloworld/STM32L073RZTx.uvoptx @@ -509,7 +509,7 @@ 0 0 0 - ..\..\..\..\kernel\rhino\core\k_fifo.c + ..\..\..\..\kernel\rhino\common\k_fifo.c k_fifo.c 0 0 @@ -749,7 +749,7 @@ 0 0 0 - ..\..\..\..\kernel\rhino\core\k_trace.c + ..\..\..\..\kernel\rhino\common\k_trace.c k_trace.c 0 0 diff --git a/projects/Keil/STM32L073RZ-Nucleo/helloworld/STM32L073RZTx.uvprojx b/projects/Keil/STM32L073RZ-Nucleo/helloworld/STM32L073RZTx.uvprojx index 77dc8823b6..706fa89def 100644 --- a/projects/Keil/STM32L073RZ-Nucleo/helloworld/STM32L073RZTx.uvprojx +++ b/projects/Keil/STM32L073RZ-Nucleo/helloworld/STM32L073RZTx.uvprojx @@ -332,7 +332,7 @@ 0 0 - --C99 -DSYSINFO_OS_VERSION=\"APP-1.0.0\" -DSYSINFO_PRODUCT_MODEL=\"ALI_AOS_STM32L073RZTx\" -DSYSINFO_DEVICE_NAME=\"STM32L073RZTx\" -DSYSINFO_KERNEL_VERSION=\"AOS-R-1.1.2\" -DSYSINFO_APP_VERSION=\"APP-1.0.0\" -DSTDIO_UART=0 -DCONFIG_NO_TCPIP -DRHINO_CONFIG_TICK_TASK=0 -DCONFIG_AOS_KV_MULTIPTN_MODE -DCONFIG_AOS_KV_PTN=6 -DCONFIG_AOS_KV_SECOND_PTN=7 -DCONFIG_AOS_KV_PTN_SIZE=4096 -DCONFIG_AOS_KV_BUFFER_SIZE=8192 -D__BSD_VISIBLE -DRHINO_CONFIG_TICK_TASK=0 + --C99 -DSYSINFO_OS_VERSION=\"APP-1.0.0\" -DSYSINFO_PRODUCT_MODEL=\"ALI_AOS_STM32L073RZTx\" -DSYSINFO_DEVICE_NAME=\"STM32L073RZTx\" -DSYSINFO_KERNEL_VERSION=\"AOS-R-1.2.0\" -DSYSINFO_APP_VERSION=\"APP-1.0.0\" -DSTDIO_UART=0 -DCONFIG_NO_TCPIP -DRHINO_CONFIG_TICK_TASK=0 -DCONFIG_AOS_KV_MULTIPTN_MODE -DCONFIG_AOS_KV_PTN=6 -DCONFIG_AOS_KV_SECOND_PTN=7 -DCONFIG_AOS_KV_PTN_SIZE=4096 -DCONFIG_AOS_KV_BUFFER_SIZE=8192 -D__BSD_VISIBLE -DRHINO_CONFIG_TICK_TASK=0 USE_HAL_DRIVER,STM32L073xx ..\..\..\..\include;..\..\..\..\kernel\rhino\core\include;..\..\..\..\platform\arch\arm\armv6m\armcc\m0plus;..\..\..\..\platform\mcu\stm32l0xx\Drivers\STM32L0xx_HAL_Driver\Inc;..\..\..\..\platform\mcu\stm32l0xx\Drivers\STM32L0xx_HAL_Driver\Inc\Legacy;..\..\..\..\platform\mcu\stm32l0xx\Drivers\CMSIS\Device\ST\STM32L0xx\Include;..\..\..\..\platform\mcu\stm32l0xx\Drivers\CMSIS\Include;..\..\..\..\platform\mcu\stm32l0xx\src\STM32L073RZ-Nucleo\helloworld;..\..\..\..\include\hal;..\..\..\..\kernel\vcall\aos;..\..\..\..\utility\libc\compilers\armlibc @@ -522,7 +522,7 @@ k_fifo.c 1 - ..\..\..\..\kernel\rhino\core\k_fifo.c + ..\..\..\..\kernel\rhino\common\k_fifo.c k_idle.c @@ -622,7 +622,7 @@ k_trace.c 1 - ..\..\..\..\kernel\rhino\core\k_trace.c + ..\..\..\..\kernel\rhino\common\k_trace.c k_workqueue.c diff --git a/projects/Keil/STM32L433RC-Nucleo/gui_demo/STM32L433RCTxP.uvoptx b/projects/Keil/STM32L433RC-Nucleo/gui_demo/STM32L433RCTxP.uvoptx new file mode 100755 index 0000000000..22e9e93e89 --- /dev/null +++ b/projects/Keil/STM32L433RC-Nucleo/gui_demo/STM32L433RCTxP.uvoptx @@ -0,0 +1,1109 @@ + + + + 1.0 + +
### uVision Project, (C) Keil Software
+ + + *.c + *.s*; *.src; *.a* + *.obj; *.o + *.lib + *.txt; *.h; *.inc + *.plm + *.cpp + 0 + + + + 0 + 0 + + + + STM32L433RCTxP + 0x4 + ARM-ADS + + 12000000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 18 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + 1 + 5 + + + + + + + + + + + STLink\ST-LINKIII-KEIL_SWO.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 + DLGUARM + (105=-1,-1,-1,-1,0) + + + 0 + UL2CM3 + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32L4xx_256 -FS08000000 -FL040000 -FP0($$Device:STM32L433RCTx$CMSIS\Flash\STM32L4xx_256.FLM)) + + + 0 + ST-LINKIII-KEIL_SWO + -U066EFF333036434B43053913 -O2254 -S1 -C0 -A0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8004 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC1000 -FN1 -FF0STM32L4xx_256.FLM -FS08000000 -FL040000 -FP0($$Device:STM32L433RCTx$CMSIS\Flash\STM32L4xx_256.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 + 0 + 0 + + + + + + 1 + 0 + 2 + 10000000 + + + + + + platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src + 0 + 0 + 0 + 0 + + 1 + 1 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_dma.c + stm32l4xx_hal_dma.c + 0 + 0 + + + 1 + 2 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_pwr.c + stm32l4xx_hal_pwr.c + 0 + 0 + + + 1 + 3 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_uart_ex.c + stm32l4xx_hal_uart_ex.c + 0 + 0 + + + 1 + 4 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_pwr_ex.c + stm32l4xx_hal_pwr_ex.c + 0 + 0 + + + 1 + 5 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_rcc_ex.c + stm32l4xx_hal_rcc_ex.c + 0 + 0 + + + 1 + 6 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_tim_ex.c + stm32l4xx_hal_tim_ex.c + 0 + 0 + + + 1 + 7 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_i2c.c + stm32l4xx_hal_i2c.c + 0 + 0 + + + 1 + 8 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash_ex.c + stm32l4xx_hal_flash_ex.c + 0 + 0 + + + 1 + 9 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_gpio.c + stm32l4xx_hal_gpio.c + 0 + 0 + + + 1 + 10 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal.c + stm32l4xx_hal.c + 0 + 0 + + + 1 + 11 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash.c + stm32l4xx_hal_flash.c + 0 + 0 + + + 1 + 12 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash_ramfunc.c + stm32l4xx_hal_flash_ramfunc.c + 0 + 0 + + + 1 + 13 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_tim.c + stm32l4xx_hal_tim.c + 0 + 0 + + + 1 + 14 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_rcc.c + stm32l4xx_hal_rcc.c + 0 + 0 + + + 1 + 15 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_uart.c + stm32l4xx_hal_uart.c + 0 + 0 + + + 1 + 16 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_dma_ex.c + stm32l4xx_hal_dma_ex.c + 0 + 0 + + + 1 + 17 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_cortex.c + stm32l4xx_hal_cortex.c + 0 + 0 + + + 1 + 18 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_i2c_ex.c + stm32l4xx_hal_i2c_ex.c + 0 + 0 + + + + + platform\mcu\stm32l4xx\src\STM32L433RC-Nucleo + 0 + 0 + 0 + 0 + + 2 + 19 + 2 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\src\STM32L433RC-Nucleo\startup_stm32l433xx_keil.s + startup_stm32l433xx_keil.s + 0 + 0 + + + 2 + 20 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\src\STM32L433RC-Nucleo\gui_demo\soc_init.c + soc_init.c + 0 + 0 + + + 2 + 21 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\src\STM32L433RC-Nucleo\gui_demo\stm32l4xx_hal_msp.c + stm32l4xx_hal_msp.c + 0 + 0 + + + 2 + 22 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\src\STM32L433RC-Nucleo\gui_demo\stm32l4xx_it.c + stm32l4xx_it.c + 0 + 0 + + + 2 + 23 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\src\STM32L433RC-Nucleo\gui_demo\system_stm32l4xx.c + system_stm32l4xx.c + 0 + 0 + + + + + kernel\rhino\core + 0 + 0 + 0 + 0 + + 3 + 24 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\core\k_buf_queue.c + k_buf_queue.c + 0 + 0 + + + 3 + 25 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\core\k_dyn_mem_proc.c + k_dyn_mem_proc.c + 0 + 0 + + + 3 + 26 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\core\k_err.c + k_err.c + 0 + 0 + + + 3 + 27 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\core\k_event.c + k_event.c + 0 + 0 + + + 3 + 28 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\common\k_fifo.c + k_fifo.c + 0 + 0 + + + 3 + 29 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\core\k_idle.c + k_idle.c + 0 + 0 + + + 3 + 30 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\core\k_mm.c + k_mm.c + 0 + 0 + + + 3 + 31 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\core\k_mm_blk.c + k_mm_blk.c + 0 + 0 + + + 3 + 32 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\core\k_mm_debug.c + k_mm_debug.c + 0 + 0 + + + 3 + 33 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\core\k_mutex.c + k_mutex.c + 0 + 0 + + + 3 + 34 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\core\k_obj.c + k_obj.c + 0 + 0 + + + 3 + 35 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\core\k_obj_set.c + k_obj_set.c + 0 + 0 + + + 3 + 36 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\core\k_pend.c + k_pend.c + 0 + 0 + + + 3 + 37 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\core\k_queue.c + k_queue.c + 0 + 0 + + + 3 + 38 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\core\k_ringbuf.c + k_ringbuf.c + 0 + 0 + + + 3 + 39 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\core\k_sched.c + k_sched.c + 0 + 0 + + + 3 + 40 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\core\k_sem.c + k_sem.c + 0 + 0 + + + 3 + 41 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\core\k_stats.c + k_stats.c + 0 + 0 + + + 3 + 42 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\core\k_sys.c + k_sys.c + 0 + 0 + + + 3 + 43 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\core\k_task.c + k_task.c + 0 + 0 + + + 3 + 44 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\core\k_task_sem.c + k_task_sem.c + 0 + 0 + + + 3 + 45 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\core\k_tick.c + k_tick.c + 0 + 0 + + + 3 + 46 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\core\k_time.c + k_time.c + 0 + 0 + + + 3 + 47 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\core\k_timer.c + k_timer.c + 0 + 0 + + + 3 + 48 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\common\k_trace.c + k_trace.c + 0 + 0 + + + 3 + 49 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\core\k_workqueue.c + k_workqueue.c + 0 + 0 + + + + + platform\mcu\stm32l4xx\aos + 0 + 0 + 0 + 0 + + 4 + 50 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\aos\soc_impl.c + soc_impl.c + 0 + 0 + + + 4 + 51 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\aos\trace_impl.c + trace_impl.c + 0 + 0 + + + + + platform\arch\arm\armv7m\armcc\m4 + 0 + 0 + 0 + 0 + + 5 + 52 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\arch\arm\armv7m\armcc\m4\port_c.c + port_c.c + 0 + 0 + + + 5 + 53 + 2 + 0 + 0 + 0 + ..\..\..\..\platform\arch\arm\armv7m\armcc\m4\port_s.s + port_s.s + 0 + 0 + + + + + main + 1 + 0 + 0 + 0 + + 6 + 54 + 1 + 0 + 0 + 0 + ..\..\..\..\example\GUI\main.c + main.c + 0 + 0 + + + + + GUI\STemWin\Conf + 1 + 0 + 0 + 0 + + 7 + 55 + 1 + 0 + 0 + 0 + ..\..\..\..\example\GUI\STemWin\Config\GUIConf.c + GUIConf.c + 0 + 0 + + + 7 + 56 + 1 + 0 + 0 + 0 + ..\..\..\..\example\GUI\STemWin\Config\LCDConf_FlexColor_Template.c + LCDConf_FlexColor_Template.c + 0 + 0 + + + + + GUI\STemWin\OS + 1 + 0 + 0 + 0 + + 8 + 57 + 1 + 0 + 0 + 0 + ..\..\..\..\example\GUI\STemWin\OS\GUI_X_rhino.c + GUI_X_rhino.c + 0 + 0 + + + + + GUI\STemWin\Lib + 1 + 0 + 0 + 0 + + 9 + 58 + 4 + 0 + 0 + 0 + ..\..\..\..\example\GUI\STemWin\Lib\STemWin540_CM4_OS_Keil_ot.lib + STemWin540_CM4_OS_Keil_ot.lib + 0 + 0 + + + + + GUI\core + 1 + 0 + 0 + 0 + + 10 + 59 + 1 + 0 + 0 + 0 + ..\..\..\..\example\GUI\core\GUI_init.c + GUI_init.c + 0 + 0 + + + + + GUI\app + 0 + 0 + 0 + 0 + + 11 + 60 + 1 + 0 + 0 + 0 + ..\..\..\..\example\GUI\app\GUIDEMO.c + GUIDEMO.c + 0 + 0 + + + 11 + 61 + 1 + 0 + 0 + 0 + ..\..\..\..\example\GUI\app\GUIDEMO_BarGraph.c + GUIDEMO_BarGraph.c + 0 + 0 + + + 11 + 62 + 1 + 0 + 0 + 0 + ..\..\..\..\example\GUI\app\GUIDEMO_ColorBar.c + GUIDEMO_ColorBar.c + 0 + 0 + + + 11 + 63 + 1 + 0 + 0 + 0 + ..\..\..\..\example\GUI\app\GUIDEMO_Conf.c + GUIDEMO_Conf.c + 0 + 0 + + + 11 + 64 + 1 + 0 + 0 + 0 + ..\..\..\..\example\GUI\app\GUIDEMO_Graph.c + GUIDEMO_Graph.c + 0 + 0 + + + 11 + 65 + 1 + 0 + 0 + 0 + ..\..\..\..\example\GUI\app\GUIDEMO_Intro.c + GUIDEMO_Intro.c + 0 + 0 + + + 11 + 66 + 1 + 0 + 0 + 0 + ..\..\..\..\example\GUI\app\GUIDEMO_Resource.c + GUIDEMO_Resource.c + 0 + 0 + + + 11 + 67 + 1 + 0 + 0 + 0 + ..\..\..\..\example\GUI\app\GUIDEMO_Start.c + GUIDEMO_Start.c + 0 + 0 + + + 11 + 68 + 1 + 0 + 0 + 0 + ..\..\..\..\example\GUI\app\GUIDEMO_TransparentDialog.c + GUIDEMO_TransparentDialog.c + 0 + 0 + + + + + ::CMSIS + 0 + 0 + 0 + 1 + + +
diff --git a/projects/Keil/STM32L433RC-Nucleo/gui_demo/STM32L433RCTxP.uvprojx b/projects/Keil/STM32L433RC-Nucleo/gui_demo/STM32L433RCTxP.uvprojx new file mode 100755 index 0000000000..1ea1b0e0b5 --- /dev/null +++ b/projects/Keil/STM32L433RC-Nucleo/gui_demo/STM32L433RCTxP.uvprojx @@ -0,0 +1,794 @@ + + + + 2.1 + +
### uVision Project, (C) Keil Software
+ + + + STM32L433RCTxP + 0x4 + ARM-ADS + 5060422::V5.06 update 4 (build 422)::ARMCC + + + STM32L433RCTx + STMicroelectronics + Keil.STM32L4xx_DFP.2.0.0 + http://www.keil.com/pack + IRAM(0x20000000,0x0000C000) IRAM2(0x10000000,0x00004000) IROM(0x08000000,0x00040000) CPUTYPE("Cortex-M4") FPU2 CLOCK(12000000) ELITTLE + + + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32L4xx_256 -FS08000000 -FL040000 -FP0($$Device:STM32L433RCTx$CMSIS\Flash\STM32L4xx_256.FLM)) + 0 + $$Device:STM32L433RCTx$Drivers\CMSIS\Device\ST\STM32L4xx\Include\stm32l4xx.h + + + + + + + + + + $$Device:STM32L433RCTx$CMSIS\SVD\STM32L4x3.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + STM32L433RCTxP\ + STM32L433RCTxP + 1 + 0 + 0 + 1 + 1 + + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 0 + + + SARMCM3.DLL + -REMAP -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 + 1 + 0 + 8 + 1 + 0 + 0 + 0 + 3 + 4 + 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 + 0xc000 + + + 1 + 0x8000000 + 0x40000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x40000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0xc000 + + + 0 + 0x10000000 + 0x4000 + + + + + + 1 + 1 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 2 + 0 + 0 + 1 + 0 + 1 + 1 + 1 + 1 + 0 + 0 + 0 + + --C99 -DSYSINFO_OS_VERSION=\"APP-1.0.0\" -DSYSINFO_PRODUCT_MODEL=\"ALI_AOS_STM32L433RCTxP\" -DSYSINFO_DEVICE_NAME=\"STM32L433RCTxP\" -DSYSINFO_KERNEL_VERSION=\"AOS-R-1.2.0\" -DSYSINFO_APP_VERSION=\"APP-1.0.0\" -DSTDIO_UART=0 -DCONFIG_NO_TCPIP -DRHINO_CONFIG_TICK_TASK=0 -DCONFIG_AOS_KV_MULTIPTN_MODE -DCONFIG_AOS_KV_PTN=6 -DCONFIG_AOS_KV_SECOND_PTN=7 -DCONFIG_AOS_KV_PTN_SIZE=4096 -DCONFIG_AOS_KV_BUFFER_SIZE=8192 -D__BSD_VISIBLE -DRHINO_CONFIG_TICK_TASK=0 + USE_HAL_DRIVER,STM32L433xx + + ..\..\..\..\include;..\..\..\..\kernel\rhino\core\include;..\..\..\..\platform\arch\arm\armv7m\armcc\m4;..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Inc;..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Inc\Legacy;..\..\..\..\platform\mcu\stm32l4xx\Drivers\CMSIS\Device\ST\STM32L4xx\Include;..\..\..\..\platform\mcu\stm32l4xx\Drivers\CMSIS\Include;..\..\..\..\platform\mcu\stm32l4xx\src\STM32L433RC-Nucleo\helloword;..\..\..\..\include\hal;..\..\..\..\kernel\vcall\aos;..\..\..\..\utility\libc\compilers\armlibc;..\..\..\..\example\GUI\core\include;..\..\..\..\example\GUI\STemWin\Config;..\..\..\..\example\GUI\STemWin\inc + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + + + + 1 + 0 + 0 + 0 + 1 + 0 + 0x08000000 + 0x20000000 + + + + + --diag_suppress=L6329 + + + + + + + + platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src + + + stm32l4xx_hal_dma.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_dma.c + + + stm32l4xx_hal_pwr.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_pwr.c + + + stm32l4xx_hal_uart_ex.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_uart_ex.c + + + stm32l4xx_hal_pwr_ex.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_pwr_ex.c + + + stm32l4xx_hal_rcc_ex.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_rcc_ex.c + + + stm32l4xx_hal_tim_ex.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_tim_ex.c + + + stm32l4xx_hal_i2c.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_i2c.c + + + stm32l4xx_hal_flash_ex.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash_ex.c + + + stm32l4xx_hal_gpio.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_gpio.c + + + stm32l4xx_hal.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal.c + + + stm32l4xx_hal_flash.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash.c + + + stm32l4xx_hal_flash_ramfunc.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash_ramfunc.c + + + stm32l4xx_hal_tim.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_tim.c + + + stm32l4xx_hal_rcc.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_rcc.c + + + stm32l4xx_hal_uart.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_uart.c + + + stm32l4xx_hal_dma_ex.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_dma_ex.c + + + stm32l4xx_hal_cortex.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_cortex.c + + + stm32l4xx_hal_i2c_ex.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_i2c_ex.c + + + + + platform\mcu\stm32l4xx\src\STM32L433RC-Nucleo + + + startup_stm32l433xx_keil.s + 2 + ..\..\..\..\platform\mcu\stm32l4xx\src\STM32L433RC-Nucleo\startup_stm32l433xx_keil.s + + + soc_init.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\src\STM32L433RC-Nucleo\gui_demo\soc_init.c + + + stm32l4xx_hal_msp.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\src\STM32L433RC-Nucleo\gui_demo\stm32l4xx_hal_msp.c + + + stm32l4xx_it.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\src\STM32L433RC-Nucleo\gui_demo\stm32l4xx_it.c + + + system_stm32l4xx.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\src\STM32L433RC-Nucleo\gui_demo\system_stm32l4xx.c + + + + + kernel\rhino\core + + + k_buf_queue.c + 1 + ..\..\..\..\kernel\rhino\core\k_buf_queue.c + + + k_dyn_mem_proc.c + 1 + ..\..\..\..\kernel\rhino\core\k_dyn_mem_proc.c + + + k_err.c + 1 + ..\..\..\..\kernel\rhino\core\k_err.c + + + k_event.c + 1 + ..\..\..\..\kernel\rhino\core\k_event.c + + + k_fifo.c + 1 + ..\..\..\..\kernel\rhino\common\k_fifo.c + + + k_idle.c + 1 + ..\..\..\..\kernel\rhino\core\k_idle.c + + + k_mm.c + 1 + ..\..\..\..\kernel\rhino\core\k_mm.c + + + k_mm_blk.c + 1 + ..\..\..\..\kernel\rhino\core\k_mm_blk.c + + + k_mm_debug.c + 1 + ..\..\..\..\kernel\rhino\core\k_mm_debug.c + + + k_mutex.c + 1 + ..\..\..\..\kernel\rhino\core\k_mutex.c + + + k_obj.c + 1 + ..\..\..\..\kernel\rhino\core\k_obj.c + + + k_obj_set.c + 1 + ..\..\..\..\kernel\rhino\core\k_obj_set.c + + + k_pend.c + 1 + ..\..\..\..\kernel\rhino\core\k_pend.c + + + k_queue.c + 1 + ..\..\..\..\kernel\rhino\core\k_queue.c + + + k_ringbuf.c + 1 + ..\..\..\..\kernel\rhino\core\k_ringbuf.c + + + k_sched.c + 1 + ..\..\..\..\kernel\rhino\core\k_sched.c + + + k_sem.c + 1 + ..\..\..\..\kernel\rhino\core\k_sem.c + + + k_stats.c + 1 + ..\..\..\..\kernel\rhino\core\k_stats.c + + + k_sys.c + 1 + ..\..\..\..\kernel\rhino\core\k_sys.c + + + k_task.c + 1 + ..\..\..\..\kernel\rhino\core\k_task.c + + + k_task_sem.c + 1 + ..\..\..\..\kernel\rhino\core\k_task_sem.c + + + k_tick.c + 1 + ..\..\..\..\kernel\rhino\core\k_tick.c + + + k_time.c + 1 + ..\..\..\..\kernel\rhino\core\k_time.c + + + k_timer.c + 1 + ..\..\..\..\kernel\rhino\core\k_timer.c + + + k_trace.c + 1 + ..\..\..\..\kernel\rhino\common\k_trace.c + + + k_workqueue.c + 1 + ..\..\..\..\kernel\rhino\core\k_workqueue.c + + + + + platform\mcu\stm32l4xx\aos + + + soc_impl.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\aos\soc_impl.c + + + trace_impl.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\aos\trace_impl.c + + + + + platform\arch\arm\armv7m\armcc\m4 + + + port_c.c + 1 + ..\..\..\..\platform\arch\arm\armv7m\armcc\m4\port_c.c + + + port_s.s + 2 + ..\..\..\..\platform\arch\arm\armv7m\armcc\m4\port_s.s + + + + + main + + + main.c + 1 + ..\..\..\..\example\GUI\main.c + + + + + GUI\STemWin\Conf + + + GUIConf.c + 1 + ..\..\..\..\example\GUI\STemWin\Config\GUIConf.c + + + LCDConf_FlexColor_Template.c + 1 + ..\..\..\..\example\GUI\STemWin\Config\LCDConf_FlexColor_Template.c + + + + + GUI\STemWin\OS + + + GUI_X_rhino.c + 1 + ..\..\..\..\example\GUI\STemWin\OS\GUI_X_rhino.c + + + + + GUI\STemWin\Lib + + + STemWin540_CM4_OS_Keil_ot.lib + 4 + ..\..\..\..\example\GUI\STemWin\Lib\STemWin540_CM4_OS_Keil_ot.lib + + + + + GUI\core + + + GUI_init.c + 1 + ..\..\..\..\example\GUI\core\GUI_init.c + + + + + GUI\app + + + GUIDEMO.c + 1 + ..\..\..\..\example\GUI\app\GUIDEMO.c + + + GUIDEMO_BarGraph.c + 1 + ..\..\..\..\example\GUI\app\GUIDEMO_BarGraph.c + + + GUIDEMO_ColorBar.c + 1 + ..\..\..\..\example\GUI\app\GUIDEMO_ColorBar.c + + + GUIDEMO_Conf.c + 1 + ..\..\..\..\example\GUI\app\GUIDEMO_Conf.c + + + GUIDEMO_Graph.c + 1 + ..\..\..\..\example\GUI\app\GUIDEMO_Graph.c + + + GUIDEMO_Intro.c + 1 + ..\..\..\..\example\GUI\app\GUIDEMO_Intro.c + + + GUIDEMO_Resource.c + 1 + ..\..\..\..\example\GUI\app\GUIDEMO_Resource.c + + + GUIDEMO_Start.c + 1 + ..\..\..\..\example\GUI\app\GUIDEMO_Start.c + + + GUIDEMO_TransparentDialog.c + 1 + ..\..\..\..\example\GUI\app\GUIDEMO_TransparentDialog.c + + + + + ::CMSIS + + + + + + + + + + + + + + + + + + +
diff --git a/projects/Keil/STM32L433RC-Nucleo/helloworld/STM32L433RCTxP.uvoptx b/projects/Keil/STM32L433RC-Nucleo/helloworld/STM32L433RCTxP.uvoptx index fdd37c5af8..a376fbb1fb 100644 --- a/projects/Keil/STM32L433RC-Nucleo/helloworld/STM32L433RCTxP.uvoptx +++ b/projects/Keil/STM32L433RC-Nucleo/helloworld/STM32L433RCTxP.uvoptx @@ -547,7 +547,7 @@ 0 0 0 - ..\..\..\..\kernel\rhino\core\k_fifo.c + ..\..\..\..\kernel\rhino\common\k_fifo.c k_fifo.c 0 0 @@ -787,7 +787,7 @@ 0 0 0 - ..\..\..\..\kernel\rhino\core\k_trace.c + ..\..\..\..\kernel\rhino\common\k_trace.c k_trace.c 0 0 @@ -863,8 +863,8 @@ 0 0 0 - ..\..\..\..\platform\arch\arm\armv7m\armcc\m4\port_c.s - port_c.s + ..\..\..\..\platform\arch\arm\armv7m\armcc\m4\port_s.s + port_s.s 0 0
diff --git a/projects/Keil/STM32L433RC-Nucleo/helloworld/STM32L433RCTxP.uvprojx b/projects/Keil/STM32L433RC-Nucleo/helloworld/STM32L433RCTxP.uvprojx index 57b3c1c862..81ab224f04 100644 --- a/projects/Keil/STM32L433RC-Nucleo/helloworld/STM32L433RCTxP.uvprojx +++ b/projects/Keil/STM32L433RC-Nucleo/helloworld/STM32L433RCTxP.uvprojx @@ -332,7 +332,7 @@ 0 0 - --C99 -DSYSINFO_OS_VERSION=\"APP-1.0.0\" -DSYSINFO_PRODUCT_MODEL=\"ALI_AOS_STM32L433RCTxP\" -DSYSINFO_DEVICE_NAME=\"STM32L433RCTxP\" -DSYSINFO_KERNEL_VERSION=\"AOS-R-1.1.2\" -DSYSINFO_APP_VERSION=\"APP-1.0.0\" -DSTDIO_UART=0 -DCONFIG_NO_TCPIP -DRHINO_CONFIG_TICK_TASK=0 -DCONFIG_AOS_KV_MULTIPTN_MODE -DCONFIG_AOS_KV_PTN=6 -DCONFIG_AOS_KV_SECOND_PTN=7 -DCONFIG_AOS_KV_PTN_SIZE=4096 -DCONFIG_AOS_KV_BUFFER_SIZE=8192 -D__BSD_VISIBLE -DRHINO_CONFIG_TICK_TASK=0 + --C99 -DSYSINFO_OS_VERSION=\"APP-1.0.0\" -DSYSINFO_PRODUCT_MODEL=\"ALI_AOS_STM32L433RCTxP\" -DSYSINFO_DEVICE_NAME=\"STM32L433RCTxP\" -DSYSINFO_KERNEL_VERSION=\"AOS-R-1.2.0\" -DSYSINFO_APP_VERSION=\"APP-1.0.0\" -DSTDIO_UART=0 -DCONFIG_NO_TCPIP -DRHINO_CONFIG_TICK_TASK=0 -DCONFIG_AOS_KV_MULTIPTN_MODE -DCONFIG_AOS_KV_PTN=6 -DCONFIG_AOS_KV_SECOND_PTN=7 -DCONFIG_AOS_KV_PTN_SIZE=4096 -DCONFIG_AOS_KV_BUFFER_SIZE=8192 -D__BSD_VISIBLE -DRHINO_CONFIG_TICK_TASK=0 USE_HAL_DRIVER,STM32L433xx ..\..\..\..\include;..\..\..\..\kernel\rhino\core\include;..\..\..\..\platform\arch\arm\armv7m\armcc\m4;..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Inc;..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Inc\Legacy;..\..\..\..\platform\mcu\stm32l4xx\Drivers\CMSIS\Device\ST\STM32L4xx\Include;..\..\..\..\platform\mcu\stm32l4xx\Drivers\CMSIS\Include;..\..\..\..\platform\mcu\stm32l4xx\src\STM32L433RC-Nucleo\helloword;..\..\..\..\include\hal;..\..\..\..\kernel\vcall\aos;..\..\..\..\utility\libc\compilers\armlibc @@ -527,7 +527,7 @@ k_fifo.c 1 - ..\..\..\..\kernel\rhino\core\k_fifo.c + ..\..\..\..\kernel\rhino\common\k_fifo.c k_idle.c @@ -627,7 +627,7 @@ k_trace.c 1 - ..\..\..\..\kernel\rhino\core\k_trace.c + ..\..\..\..\kernel\rhino\common\k_trace.c k_workqueue.c @@ -660,9 +660,9 @@ ..\..\..\..\platform\arch\arm\armv7m\armcc\m4\port_c.c - port_c.s + port_s.s 2 - ..\..\..\..\platform\arch\arm\armv7m\armcc\m4\port_c.s + ..\..\..\..\platform\arch\arm\armv7m\armcc\m4\port_s.s diff --git a/projects/Keil/STM32L476RG-Nucleo/helloworld/STM32L476RGTx.uvoptx b/projects/Keil/STM32L476RG-Nucleo/helloworld/STM32L476RGTx.uvoptx index ad83137a67..c5b0c0b342 100644 --- a/projects/Keil/STM32L476RG-Nucleo/helloworld/STM32L476RGTx.uvoptx +++ b/projects/Keil/STM32L476RG-Nucleo/helloworld/STM32L476RGTx.uvoptx @@ -547,7 +547,7 @@ 0 0 0 - ..\..\..\..\kernel\rhino\core\k_fifo.c + ..\..\..\..\kernel\rhino\common\k_fifo.c k_fifo.c 0 0 @@ -787,7 +787,7 @@ 0 0 0 - ..\..\..\..\kernel\rhino\core\k_trace.c + ..\..\..\..\kernel\rhino\common\k_trace.c k_trace.c 0 0 @@ -863,8 +863,8 @@ 0 0 0 - ..\..\..\..\platform\arch\arm\armv7m\armcc\m4\port_c.s - port_c.s + ..\..\..\..\platform\arch\arm\armv7m\armcc\m4\port_s.s + port_s.s 0 0 diff --git a/projects/Keil/STM32L476RG-Nucleo/helloworld/STM32L476RGTx.uvprojx b/projects/Keil/STM32L476RG-Nucleo/helloworld/STM32L476RGTx.uvprojx index c1202f529a..3c4a0489ca 100644 --- a/projects/Keil/STM32L476RG-Nucleo/helloworld/STM32L476RGTx.uvprojx +++ b/projects/Keil/STM32L476RG-Nucleo/helloworld/STM32L476RGTx.uvprojx @@ -332,7 +332,7 @@ 0 0 - --C99 -DSYSINFO_OS_VERSION=\"APP-1.0.0\" -DSYSINFO_PRODUCT_MODEL=\"ALI_AOS_STM32L476RGTx\" -DSYSINFO_DEVICE_NAME=\"STM32L476RGTx\" -DSYSINFO_KERNEL_VERSION=\"AOS-R-1.1.2\" -DSYSINFO_APP_VERSION=\"APP-1.0.0\" -DSTDIO_UART=0 -DCONFIG_NO_TCPIP -DRHINO_CONFIG_TICK_TASK=0 -DCONFIG_AOS_KV_MULTIPTN_MODE -DCONFIG_AOS_KV_PTN=6 -DCONFIG_AOS_KV_SECOND_PTN=7 -DCONFIG_AOS_KV_PTN_SIZE=4096 -DCONFIG_AOS_KV_BUFFER_SIZE=8192 -D__BSD_VISIBLE -DRHINO_CONFIG_TICK_TASK=0 + --C99 -DSYSINFO_OS_VERSION=\"APP-1.0.0\" -DSYSINFO_PRODUCT_MODEL=\"ALI_AOS_STM32L476RGTx\" -DSYSINFO_DEVICE_NAME=\"STM32L476RGTx\" -DSYSINFO_KERNEL_VERSION=\"AOS-R-1.2.0\" -DSYSINFO_APP_VERSION=\"APP-1.0.0\" -DSTDIO_UART=0 -DCONFIG_NO_TCPIP -DRHINO_CONFIG_TICK_TASK=0 -DCONFIG_AOS_KV_MULTIPTN_MODE -DCONFIG_AOS_KV_PTN=6 -DCONFIG_AOS_KV_SECOND_PTN=7 -DCONFIG_AOS_KV_PTN_SIZE=4096 -DCONFIG_AOS_KV_BUFFER_SIZE=8192 -D__BSD_VISIBLE -DRHINO_CONFIG_TICK_TASK=0 USE_HAL_DRIVER,STM32L476xx ..\..\..\..\include;..\..\..\..\kernel\rhino\core\include;..\..\..\..\platform\arch\arm\armv7m\armcc\m4;..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Inc;..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Inc\Legacy;..\..\..\..\platform\mcu\stm32l4xx\Drivers\CMSIS\Device\ST\STM32L4xx\Include;..\..\..\..\platform\mcu\stm32l4xx\Drivers\CMSIS\Include;..\..\..\..\platform\mcu\stm32l4xx\src\STM32L476RG-Nucleo\helloworld;..\..\..\..\include\hal;..\..\..\..\kernel\vcall\aos;..\..\..\..\utility\libc\compilers\armlibc @@ -527,7 +527,7 @@ k_fifo.c 1 - ..\..\..\..\kernel\rhino\core\k_fifo.c + ..\..\..\..\kernel\rhino\common\k_fifo.c k_idle.c @@ -627,7 +627,7 @@ k_trace.c 1 - ..\..\..\..\kernel\rhino\core\k_trace.c + ..\..\..\..\kernel\rhino\common\k_trace.c k_workqueue.c @@ -660,9 +660,9 @@ ..\..\..\..\platform\arch\arm\armv7m\armcc\m4\port_c.c - port_c.s + port_s.s 2 - ..\..\..\..\platform\arch\arm\armv7m\armcc\m4\port_c.s + ..\..\..\..\platform\arch\arm\armv7m\armcc\m4\port_s.s diff --git a/projects/Keil/STM32L496G-Discovery/aos_rhino/STM32L496AGIx.uvoptx b/projects/Keil/STM32L496G-Discovery/aos_rhino/STM32L496AGIx.uvoptx index 1d85bb8b92..89290ba044 100644 --- a/projects/Keil/STM32L496G-Discovery/aos_rhino/STM32L496AGIx.uvoptx +++ b/projects/Keil/STM32L496G-Discovery/aos_rhino/STM32L496AGIx.uvoptx @@ -599,7 +599,7 @@ 0 0 0 - ..\..\..\..\kernel\rhino\core\k_fifo.c + ..\..\..\..\kernel\rhino\common\k_fifo.c k_fifo.c 0 0 @@ -839,7 +839,7 @@ 0 0 0 - ..\..\..\..\kernel\rhino\core\k_trace.c + ..\..\..\..\kernel\rhino\common\k_trace.c k_trace.c 0 0 @@ -915,8 +915,8 @@ 0 0 0 - ..\..\..\..\platform\arch\arm\armv7m\armcc\m4\port_c.s - port_c.s + ..\..\..\..\platform\arch\arm\armv7m\armcc\m4\port_s.s + port_s.s 0 0 diff --git a/projects/Keil/STM32L496G-Discovery/aos_rhino/STM32L496AGIx.uvprojx b/projects/Keil/STM32L496G-Discovery/aos_rhino/STM32L496AGIx.uvprojx index 64894d1ebf..8f071ab181 100644 --- a/projects/Keil/STM32L496G-Discovery/aos_rhino/STM32L496AGIx.uvprojx +++ b/projects/Keil/STM32L496G-Discovery/aos_rhino/STM32L496AGIx.uvprojx @@ -332,10 +332,10 @@ 0 0 - --C99 -DSYSINFO_OS_VERSION=\"APP-1.0.0\" -DSYSINFO_PRODUCT_MODEL=\"ALI_AOS_STM32L496AGIx\" -DSYSINFO_DEVICE_NAME=\"STM32LL496AGIx\" -DSYSINFO_KERNEL_VERSION=\"AOS-R-1.1.2\" -DSYSINFO_APP_VERSION=\"APP-1.0.0\" -DSTDIO_UART=0 -DCONFIG_NO_TCPIP -DRHINO_CONFIG_TICK_TASK=0 -DCONFIG_AOS_KV_MULTIPTN_MODE -DCONFIG_AOS_KV_PTN=6 -DCONFIG_AOS_KV_SECOND_PTN=7 -DCONFIG_AOS_KV_PTN_SIZE=4096 -DCONFIG_AOS_KV_BUFFER_SIZE=8192 -D__BSD_VISIBLE -DRHINO_CONFIG_TICK_TASK=0 + --C99 -DSYSINFO_OS_VERSION=\"APP-1.0.0\" -DSYSINFO_PRODUCT_MODEL=\"ALI_AOS_STM32L496AGIx\" -DSYSINFO_DEVICE_NAME=\"STM32LL496AGIx\" -DSYSINFO_KERNEL_VERSION=\"AOS-R-1.2.0\" -DSYSINFO_APP_VERSION=\"APP-1.0.0\" -DSTDIO_UART=0 -DCONFIG_NO_TCPIP -DRHINO_CONFIG_TICK_TASK=0 -DCONFIG_AOS_KV_MULTIPTN_MODE -DCONFIG_AOS_KV_PTN=6 -DCONFIG_AOS_KV_SECOND_PTN=7 -DCONFIG_AOS_KV_PTN_SIZE=4096 -DCONFIG_AOS_KV_BUFFER_SIZE=8192 -D__BSD_VISIBLE -DRHINO_CONFIG_TICK_TASK=0 STM32L496xx,USE_HAL_DRIVER,AOS_KV - ..\..\..\..\include;..\..\..\..\kernel\rhino\core\include;..\..\..\..\platform\arch\arm\armv7m\armcc\m4;..\..\..\..\platform\mcu\stm32l4xx\Drivers\BSP\STM32L496G-Discovery;..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Inc;..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Inc\Legacy;..\..\..\..\platform\mcu\stm32l4xx\Drivers\CMSIS\Device\ST\STM32L4xx\Include;..\..\..\..\platform\mcu\stm32l4xx\Drivers\CMSIS\Include;..\..\..\..\board\stm32l496g-discovery;..\..\..\..\include\hal;..\..\..\..\kernel\vcall\aos;..\..\..\..\utility\libc\compilers\armlibc;..\..\..\..\platform\mcu\stm32l4xx\src\STM32L496G-Discovery\aos_rhino;..\..\..\..\platform\mcu\stm32l4xx\Drivers\BSP\Components\mfxstm32l152;..\..\..\..\kernel\modules\fs\kv\include;..\..\..\..\include\hal\soc;..\..\..\..\platform\mcu\stm32l4xx\src\common + ..\..\..\..\include;..\..\..\..\kernel\rhino\core\include;..\..\..\..\platform\arch\arm\armv7m\armcc\m4;..\..\..\..\platform\mcu\stm32l4xx\Drivers\BSP\STM32L496G-Discovery;..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Inc;..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Inc\Legacy;..\..\..\..\platform\mcu\stm32l4xx\Drivers\CMSIS\Device\ST\STM32L4xx\Include;..\..\..\..\platform\mcu\stm32l4xx\Drivers\CMSIS\Include;..\..\..\..\board\stm32l496g-discovery;..\..\..\..\include\hal;..\..\..\..\kernel\vcall\aos;..\..\..\..\utility\libc\compilers\armlibc;..\..\..\..\platform\mcu\stm32l4xx\src\STM32L496G-Discovery\aos_rhino;..\..\..\..\platform\mcu\stm32l4xx\Drivers\BSP\Components\mfxstm32l152;..\..\..\..\kernel\modules\fs\kv\include;..\..\..\..\include\hal\soc;..\..\..\..\platform\mcu\stm32l4xx\src\common;..\..\..\..\kernel\vfs\include @@ -547,7 +547,7 @@ k_fifo.c 1 - ..\..\..\..\kernel\rhino\core\k_fifo.c + ..\..\..\..\kernel\rhino\common\k_fifo.c k_idle.c @@ -647,7 +647,7 @@ k_trace.c 1 - ..\..\..\..\kernel\rhino\core\k_trace.c + ..\..\..\..\kernel\rhino\common\k_trace.c k_workqueue.c @@ -680,9 +680,9 @@ ..\..\..\..\platform\arch\arm\armv7m\armcc\m4\port_c.c - port_c.s + port_s.s 2 - ..\..\..\..\platform\arch\arm\armv7m\armcc\m4\port_c.s + ..\..\..\..\platform\arch\arm\armv7m\armcc\m4\port_s.s diff --git a/projects/Keil/STM32L496G-Discovery/device_io/STM32L496AGIx.uvoptx b/projects/Keil/STM32L496G-Discovery/device_io/STM32L496AGIx.uvoptx new file mode 100755 index 0000000000..24972c8094 --- /dev/null +++ b/projects/Keil/STM32L496G-Discovery/device_io/STM32L496AGIx.uvoptx @@ -0,0 +1,1119 @@ + + + + 1.0 + +
### uVision Project, (C) Keil Software
+ + + *.c + *.s*; *.src; *.a* + *.obj; *.o + *.lib + *.txt; *.h; *.inc + *.plm + *.cpp + 0 + + + + 0 + 0 + + + + STM32L496AGIx + 0x4 + ARM-ADS + + 14200000 + + 1 + 1 + 0 + 1 + 0 + + + 1 + 65535 + 0 + 0 + 0 + + + 79 + 66 + 8 + + + + 1 + 1 + 1 + 0 + 1 + 1 + 0 + 1 + 0 + 0 + 0 + 0 + + + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + + + 1 + 0 + 1 + + 18 + + 0 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 0 + 0 + 1 + 5 + + + + + + + + + + + STLink\ST-LINKIII-KEIL_SWO.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 + DLGUARM + (105=-1,-1,-1,-1,0) + + + 0 + UL2CM3 + UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32L4xx_1024 -FS08000000 -FL0100000 -FP0($$Device:STM32L496AGIx$CMSIS\Flash\STM32L4xx_1024.FLM)) + + + 0 + ST-LINKIII-KEIL_SWO + -U066EFF555352845187103212 -O2254 -S0 -C0 -A0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8004 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC1000 -FN1 -FF0STM32L4xx_1024.FLM -FS08000000 -FL0100000 -FP0($$Device:STM32L496AGIx$CMSIS\Flash\STM32L4xx_1024.FLM) + + + + + 0 + 0 + 192 + 0 +
134236604
+ 0 + 0 + 0 + 0 + 0 + 1 + ..\..\..\..\platform\mcu\stm32l4xx\src\STM32L496G-Discovery\deviceIO\soc_init.c + + \\STM32L496AGIx\../../../../platform/mcu/stm32l4xx/src/STM32L496G-Discovery/deviceIO/soc_init.c\192 +
+ + 1 + 0 + 33 + 1 +
134226642
+ 0 + 0 + 0 + 0 + 0 + 1 + ..\..\..\..\platform\mcu\stm32l4xx\src\STM32L496G-Discovery\hal\hal_timer_stm32l4.c + + \\STM32L496AGIx\../../../../platform/mcu/stm32l4xx/src/STM32L496G-Discovery/hal/hal_timer_stm32l4.c\33 +
+ + 2 + 0 + 138 + 1 +
134228954
+ 0 + 0 + 0 + 0 + 0 + 1 + ..\..\..\..\platform\mcu\stm32l4xx\src\STM32L496G-Discovery\deviceIO\stm32l4xx_it.c + + \\STM32L496AGIx\../../../../platform/mcu/stm32l4xx/src/STM32L496G-Discovery/deviceIO/stm32l4xx_it.c\138 +
+ + 3 + 0 + 191 + 0 +
0
+ 0 + 0 + 0 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\src\STM32L496G-Discovery\deviceIO\soc_init.c + + +
+ + 4 + 0 + 193 + 0 +
0
+ 0 + 0 + 0 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\src\STM32L496G-Discovery\deviceIO\soc_init.c + + +
+ + 5 + 0 + 211 + 0 +
0
+ 0 + 0 + 0 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\src\STM32L496G-Discovery\deviceIO\soc_init.c + + +
+
+ + + 0 + 1 + GPIO_InitStruct + + + 1 + 1 + tim->config.period + + + 2 + 1 + ((tim->config.period / 1000000) * 10000) + + + + + 0 + 2 + test + + + 1 + 2 + val + + + + + 1 + 0 + val + 0 + + + + 0 + + + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + 0 + 0 + + + + + + 1 + 0 + 2 + 10000000 + +
+
+ + + platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src + 0 + 0 + 0 + 0 + + 1 + 1 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_dma.c + stm32l4xx_hal_dma.c + 0 + 0 + + + 1 + 2 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_pwr.c + stm32l4xx_hal_pwr.c + 0 + 0 + + + 1 + 3 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_uart_ex.c + stm32l4xx_hal_uart_ex.c + 0 + 0 + + + 1 + 4 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_pwr_ex.c + stm32l4xx_hal_pwr_ex.c + 0 + 0 + + + 1 + 5 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_rcc_ex.c + stm32l4xx_hal_rcc_ex.c + 0 + 0 + + + 1 + 6 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_tim_ex.c + stm32l4xx_hal_tim_ex.c + 0 + 0 + + + 1 + 7 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_i2c.c + stm32l4xx_hal_i2c.c + 0 + 0 + + + 1 + 8 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash_ex.c + stm32l4xx_hal_flash_ex.c + 0 + 0 + + + 1 + 9 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_gpio.c + stm32l4xx_hal_gpio.c + 0 + 0 + + + 1 + 10 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal.c + stm32l4xx_hal.c + 0 + 0 + + + 1 + 11 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash.c + stm32l4xx_hal_flash.c + 0 + 0 + + + 1 + 12 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash_ramfunc.c + stm32l4xx_hal_flash_ramfunc.c + 0 + 0 + + + 1 + 13 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_tim.c + stm32l4xx_hal_tim.c + 0 + 0 + + + 1 + 14 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_rcc.c + stm32l4xx_hal_rcc.c + 0 + 0 + + + 1 + 15 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_uart.c + stm32l4xx_hal_uart.c + 0 + 0 + + + 1 + 16 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_dma_ex.c + stm32l4xx_hal_dma_ex.c + 0 + 0 + + + 1 + 17 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_cortex.c + stm32l4xx_hal_cortex.c + 0 + 0 + + + 1 + 18 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_i2c_ex.c + stm32l4xx_hal_i2c_ex.c + 0 + 0 + + + 1 + 19 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_spi.c + stm32l4xx_hal_spi.c + 0 + 0 + + + 1 + 20 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_adc.c + stm32l4xx_hal_adc.c + 0 + 0 + + + 1 + 21 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_adc_ex.c + stm32l4xx_hal_adc_ex.c + 0 + 0 + + + + + platform\mcu\stm32l4xx\src\STM32L496G-Discovery + 1 + 0 + 0 + 0 + + 2 + 22 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\src\STM32L496G-Discovery\deviceIO\soc_init.c + soc_init.c + 0 + 0 + + + 2 + 23 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\src\STM32L496G-Discovery\deviceIO\stm32l4xx_hal_msp.c + stm32l4xx_hal_msp.c + 0 + 0 + + + 2 + 24 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\src\STM32L496G-Discovery\deviceIO\stm32l4xx_it.c + stm32l4xx_it.c + 0 + 0 + + + 2 + 25 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\src\STM32L496G-Discovery\deviceIO\system_stm32l4xx.c + system_stm32l4xx.c + 0 + 0 + + + 2 + 26 + 2 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\src\STM32L496G-Discovery\startup_stm32l496xx_keil.s + startup_stm32l496xx_keil.s + 0 + 0 + + + 2 + 27 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\src\STM32L496G-Discovery\hal\hal_uart_stm32l4.c + hal_uart_stm32l4.c + 0 + 0 + + + 2 + 28 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\src\STM32L496G-Discovery\hal\hal_i2c_stm32l4.c + hal_i2c_stm32l4.c + 0 + 0 + + + 2 + 29 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\src\STM32L496G-Discovery\hal\hal_gpio_stm32l4.c + hal_gpio_stm32l4.c + 0 + 0 + + + 2 + 30 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\src\STM32L496G-Discovery\hal\hal_spi_stm32l4.c + hal_spi_stm32l4.c + 0 + 0 + + + 2 + 31 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\src\STM32L496G-Discovery\hal\hal_adc_stm32l4.c + hal_adc_stm32l4.c + 0 + 0 + + + 2 + 32 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\src\STM32L496G-Discovery\hal\hal_timer_stm32l4.c + hal_timer_stm32l4.c + 0 + 0 + + + + + kernel\rhino\core + 0 + 0 + 0 + 0 + + 3 + 33 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\core\k_buf_queue.c + k_buf_queue.c + 0 + 0 + + + 3 + 34 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\core\k_dyn_mem_proc.c + k_dyn_mem_proc.c + 0 + 0 + + + 3 + 35 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\core\k_err.c + k_err.c + 0 + 0 + + + 3 + 36 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\core\k_event.c + k_event.c + 0 + 0 + + + 3 + 37 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\core\k_idle.c + k_idle.c + 0 + 0 + + + 3 + 38 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\core\k_mm.c + k_mm.c + 0 + 0 + + + 3 + 39 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\core\k_mm_blk.c + k_mm_blk.c + 0 + 0 + + + 3 + 40 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\core\k_mm_debug.c + k_mm_debug.c + 0 + 0 + + + 3 + 41 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\core\k_mutex.c + k_mutex.c + 0 + 0 + + + 3 + 42 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\core\k_obj.c + k_obj.c + 0 + 0 + + + 3 + 43 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\core\k_obj_set.c + k_obj_set.c + 0 + 0 + + + 3 + 44 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\core\k_pend.c + k_pend.c + 0 + 0 + + + 3 + 45 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\core\k_queue.c + k_queue.c + 0 + 0 + + + 3 + 46 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\core\k_ringbuf.c + k_ringbuf.c + 0 + 0 + + + 3 + 47 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\core\k_sched.c + k_sched.c + 0 + 0 + + + 3 + 48 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\core\k_sem.c + k_sem.c + 0 + 0 + + + 3 + 49 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\core\k_stats.c + k_stats.c + 0 + 0 + + + 3 + 50 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\core\k_sys.c + k_sys.c + 0 + 0 + + + 3 + 51 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\core\k_task.c + k_task.c + 0 + 0 + + + 3 + 52 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\core\k_task_sem.c + k_task_sem.c + 0 + 0 + + + 3 + 53 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\core\k_tick.c + k_tick.c + 0 + 0 + + + 3 + 54 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\core\k_time.c + k_time.c + 0 + 0 + + + 3 + 55 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\core\k_timer.c + k_timer.c + 0 + 0 + + + 3 + 56 + 1 + 0 + 0 + 0 + ..\..\..\..\kernel\rhino\core\k_workqueue.c + k_workqueue.c + 0 + 0 + + + + + platform\mcu\stm32l4xx\aos + 1 + 0 + 0 + 0 + + 4 + 57 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\aos\soc_impl.c + soc_impl.c + 0 + 0 + + + 4 + 58 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\mcu\stm32l4xx\aos\trace_impl.c + trace_impl.c + 0 + 0 + + + + + platform\arch\arm\armv7m\armcc\m4 + 0 + 0 + 0 + 0 + + 5 + 59 + 1 + 0 + 0 + 0 + ..\..\..\..\platform\arch\arm\armv7m\armcc\m4\port_c.c + port_c.c + 0 + 0 + + + 5 + 60 + 2 + 0 + 0 + 0 + ..\..\..\..\platform\arch\arm\armv7m\armcc\m4\port_s.s + port_s.s + 0 + 0 + + + + + example + 1 + 0 + 0 + 0 + + 6 + 61 + 1 + 0 + 0 + 0 + ..\..\..\..\example\deviceIO\deviceIO.c + deviceIO.c + 0 + 0 + + + + + ::CMSIS + 0 + 0 + 0 + 1 + + +
diff --git a/projects/Keil/STM32L496G-Discovery/device_io/STM32L496AGIx.uvprojx b/projects/Keil/STM32L496G-Discovery/device_io/STM32L496AGIx.uvprojx new file mode 100755 index 0000000000..6fde0fee63 --- /dev/null +++ b/projects/Keil/STM32L496G-Discovery/device_io/STM32L496AGIx.uvprojx @@ -0,0 +1,734 @@ + + + + 2.1 + +
### uVision Project, (C) Keil Software
+ + + + STM32L496AGIx + 0x4 + ARM-ADS + 5060422::V5.06 update 4 (build 422)::ARMCC + + + STM32L496AGIx + STMicroelectronics + Keil.STM32L4xx_DFP.2.0.0 + http://www.keil.com/pack + IRAM(0x20000000-0x2004FFFF) IROM(0x8000000-0x80FFFFF) CLOCK(8000000) FPU2 CPUTYPE("Cortex-M4") + + + + + + + + + + + + + + + $$Device:STM32L496AGIx$CMSIS\SVD\STM32L4x6.svd + 0 + 0 + + + + + + + 0 + 0 + 0 + 0 + 1 + + STM32L496AGIx\ + STM32L496AGIx + 1 + 0 + 0 + 1 + 1 + + 1 + 0 + 0 + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + + 0 + 0 + + + 0 + 0 + 0 + 0 + + 0 + + + + 0 + 0 + 0 + 0 + 0 + 1 + 0 + 0 + 0 + 0 + 3 + + + 0 + + + SARMCM3.DLL + -REMAP -MPU + DCM.DLL + -pCM4 + SARMCM3.DLL + -MPU + TCM.DLL + -pCM4 + + + + 1 + 0 + 0 + 0 + 16 + + + + + 1 + 0 + 0 + 1 + 1 + 4100 + + 1 + STLink\ST-LINKIII-KEIL_SWO.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 + 0x50000 + + + 1 + 0x8000000 + 0x100000 + + + 0 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x0 + 0x0 + + + 1 + 0x8000000 + 0x100000 + + + 1 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x0 + 0x0 + + + 0 + 0x20000000 + 0x50000 + + + 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 + + --C99 -DSYSINFO_OS_VERSION=\"APP-1.0.0\" -DSYSINFO_PRODUCT_MODEL=\"ALI_AOS_STM32L496AGIx\" -DSYSINFO_DEVICE_NAME=\"STM32LL496AGIx\" -DSYSINFO_KERNEL_VERSION=\"AOS-R-1.0.1\" -DSYSINFO_APP_VERSION=\"APP-1.0.0\" -DSTDIO_UART=0 -DCONFIG_NO_TCPIP -DRHINO_CONFIG_TICK_TASK=0 -DCONFIG_AOS_KV_MULTIPTN_MODE -DCONFIG_AOS_KV_PTN=6 -DCONFIG_AOS_KV_SECOND_PTN=7 -DCONFIG_AOS_KV_PTN_SIZE=4096 -DCONFIG_AOS_KV_BUFFER_SIZE=8192 -D__BSD_VISIBLE -DRHINO_CONFIG_TICK_TASK=0 + USE_HAL_DRIVER,STM32L496xx + + ..\..\..\..\include;..\..\..\..\kernel\rhino\core\include;..\..\..\..\platform\arch\arm\armv7m\armcc\m4;..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Inc;..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Inc\Legacy;..\..\..\..\platform\mcu\stm32l4xx\Drivers\CMSIS\Device\ST\STM32L4xx\Include;..\..\..\..\platform\mcu\stm32l4xx\Drivers\CMSIS\Include;..\..\..\..\platform\mcu\stm32l4xx\src\STM32L496G-Discovery\deviceIO;..\..\..\..\include\hal;..\..\..\..\kernel\vcall\aos;..\..\..\..\utility\libc\compilers\armlibc;..\..\..\..\platform\mcu\stm32l4xx\src\STM32L496G-Discovery\hal;..\..\..\..\kernel\vfs\include + + + + 1 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + 0 + + + + + + + + + 1 + 0 + 0 + 0 + 1 + 0 + 0x08000000 + 0x20000000 + + + + + --diag_suppress=L6329 + + + + + + + + platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src + + + stm32l4xx_hal_dma.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_dma.c + + + stm32l4xx_hal_pwr.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_pwr.c + + + stm32l4xx_hal_uart_ex.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_uart_ex.c + + + stm32l4xx_hal_pwr_ex.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_pwr_ex.c + + + stm32l4xx_hal_rcc_ex.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_rcc_ex.c + + + stm32l4xx_hal_tim_ex.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_tim_ex.c + + + stm32l4xx_hal_i2c.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_i2c.c + + + stm32l4xx_hal_flash_ex.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash_ex.c + + + stm32l4xx_hal_gpio.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_gpio.c + + + stm32l4xx_hal.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal.c + + + stm32l4xx_hal_flash.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash.c + + + stm32l4xx_hal_flash_ramfunc.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_flash_ramfunc.c + + + stm32l4xx_hal_tim.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_tim.c + + + stm32l4xx_hal_rcc.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_rcc.c + + + stm32l4xx_hal_uart.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_uart.c + + + stm32l4xx_hal_dma_ex.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_dma_ex.c + + + stm32l4xx_hal_cortex.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_cortex.c + + + stm32l4xx_hal_i2c_ex.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_i2c_ex.c + + + stm32l4xx_hal_spi.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_spi.c + + + stm32l4xx_hal_adc.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_adc.c + + + stm32l4xx_hal_adc_ex.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal_adc_ex.c + + + + + platform\mcu\stm32l4xx\src\STM32L496G-Discovery + + + soc_init.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\src\STM32L496G-Discovery\deviceIO\soc_init.c + + + stm32l4xx_hal_msp.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\src\STM32L496G-Discovery\deviceIO\stm32l4xx_hal_msp.c + + + stm32l4xx_it.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\src\STM32L496G-Discovery\deviceIO\stm32l4xx_it.c + + + system_stm32l4xx.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\src\STM32L496G-Discovery\deviceIO\system_stm32l4xx.c + + + startup_stm32l496xx_keil.s + 2 + ..\..\..\..\platform\mcu\stm32l4xx\src\STM32L496G-Discovery\startup_stm32l496xx_keil.s + + + hal_uart_stm32l4.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\src\STM32L496G-Discovery\hal\hal_uart_stm32l4.c + + + hal_i2c_stm32l4.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\src\STM32L496G-Discovery\hal\hal_i2c_stm32l4.c + + + hal_gpio_stm32l4.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\src\STM32L496G-Discovery\hal\hal_gpio_stm32l4.c + + + hal_spi_stm32l4.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\src\STM32L496G-Discovery\hal\hal_spi_stm32l4.c + + + hal_adc_stm32l4.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\src\STM32L496G-Discovery\hal\hal_adc_stm32l4.c + + + hal_timer_stm32l4.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\src\STM32L496G-Discovery\hal\hal_timer_stm32l4.c + + + + + kernel\rhino\core + + + k_buf_queue.c + 1 + ..\..\..\..\kernel\rhino\core\k_buf_queue.c + + + k_dyn_mem_proc.c + 1 + ..\..\..\..\kernel\rhino\core\k_dyn_mem_proc.c + + + k_err.c + 1 + ..\..\..\..\kernel\rhino\core\k_err.c + + + k_event.c + 1 + ..\..\..\..\kernel\rhino\core\k_event.c + + + k_idle.c + 1 + ..\..\..\..\kernel\rhino\core\k_idle.c + + + k_mm.c + 1 + ..\..\..\..\kernel\rhino\core\k_mm.c + + + k_mm_blk.c + 1 + ..\..\..\..\kernel\rhino\core\k_mm_blk.c + + + k_mm_debug.c + 1 + ..\..\..\..\kernel\rhino\core\k_mm_debug.c + + + k_mutex.c + 1 + ..\..\..\..\kernel\rhino\core\k_mutex.c + + + k_obj.c + 1 + ..\..\..\..\kernel\rhino\core\k_obj.c + + + k_obj_set.c + 1 + ..\..\..\..\kernel\rhino\core\k_obj_set.c + + + k_pend.c + 1 + ..\..\..\..\kernel\rhino\core\k_pend.c + + + k_queue.c + 1 + ..\..\..\..\kernel\rhino\core\k_queue.c + + + k_ringbuf.c + 1 + ..\..\..\..\kernel\rhino\core\k_ringbuf.c + + + k_sched.c + 1 + ..\..\..\..\kernel\rhino\core\k_sched.c + + + k_sem.c + 1 + ..\..\..\..\kernel\rhino\core\k_sem.c + + + k_stats.c + 1 + ..\..\..\..\kernel\rhino\core\k_stats.c + + + k_sys.c + 1 + ..\..\..\..\kernel\rhino\core\k_sys.c + + + k_task.c + 1 + ..\..\..\..\kernel\rhino\core\k_task.c + + + k_task_sem.c + 1 + ..\..\..\..\kernel\rhino\core\k_task_sem.c + + + k_tick.c + 1 + ..\..\..\..\kernel\rhino\core\k_tick.c + + + k_time.c + 1 + ..\..\..\..\kernel\rhino\core\k_time.c + + + k_timer.c + 1 + ..\..\..\..\kernel\rhino\core\k_timer.c + + + k_workqueue.c + 1 + ..\..\..\..\kernel\rhino\core\k_workqueue.c + + + + + platform\mcu\stm32l4xx\aos + + + soc_impl.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\aos\soc_impl.c + + + trace_impl.c + 1 + ..\..\..\..\platform\mcu\stm32l4xx\aos\trace_impl.c + + + + + platform\arch\arm\armv7m\armcc\m4 + + + port_c.c + 1 + ..\..\..\..\platform\arch\arm\armv7m\armcc\m4\port_c.c + + + port_s.s + 2 + ..\..\..\..\platform\arch\arm\armv7m\armcc\m4\port_s.s + + + + + example + + + deviceIO.c + 1 + ..\..\..\..\example\deviceIO\deviceIO.c + + + + + ::CMSIS + + + + + + + + + + + + + + + + + + +
diff --git a/projects/Keil/STM32L496G-Discovery/helloworld/STM32L496AGIx.uvoptx b/projects/Keil/STM32L496G-Discovery/helloworld/STM32L496AGIx.uvoptx index 3b155f9c15..84dae582ac 100644 --- a/projects/Keil/STM32L496G-Discovery/helloworld/STM32L496AGIx.uvoptx +++ b/projects/Keil/STM32L496G-Discovery/helloworld/STM32L496AGIx.uvoptx @@ -547,7 +547,7 @@ 0 0 0 - ..\..\..\..\kernel\rhino\core\k_fifo.c + ..\..\..\..\kernel\rhino\common\k_fifo.c k_fifo.c 0 0 @@ -787,7 +787,7 @@ 0 0 0 - ..\..\..\..\kernel\rhino\core\k_trace.c + ..\..\..\..\kernel\rhino\common\k_trace.c k_trace.c 0 0 @@ -863,8 +863,8 @@ 0 0 0 - ..\..\..\..\platform\arch\arm\armv7m\armcc\m4\port_c.s - port_c.s + ..\..\..\..\platform\arch\arm\armv7m\armcc\m4\port_s.s + port_s.s 0 0
diff --git a/projects/Keil/STM32L496G-Discovery/helloworld/STM32L496AGIx.uvprojx b/projects/Keil/STM32L496G-Discovery/helloworld/STM32L496AGIx.uvprojx index d74b14470e..5ed03e0b85 100644 --- a/projects/Keil/STM32L496G-Discovery/helloworld/STM32L496AGIx.uvprojx +++ b/projects/Keil/STM32L496G-Discovery/helloworld/STM32L496AGIx.uvprojx @@ -332,7 +332,7 @@ 0 0 - --C99 -DSYSINFO_OS_VERSION=\"APP-1.0.0\" -DSYSINFO_PRODUCT_MODEL=\"ALI_AOS_STM32L496AGIx\" -DSYSINFO_DEVICE_NAME=\"STM32LL496AGIx\" -DSYSINFO_KERNEL_VERSION=\"AOS-R-1.1.2\" -DSYSINFO_APP_VERSION=\"APP-1.0.0\" -DSTDIO_UART=0 -DCONFIG_NO_TCPIP -DRHINO_CONFIG_TICK_TASK=0 -DCONFIG_AOS_KV_MULTIPTN_MODE -DCONFIG_AOS_KV_PTN=6 -DCONFIG_AOS_KV_SECOND_PTN=7 -DCONFIG_AOS_KV_PTN_SIZE=4096 -DCONFIG_AOS_KV_BUFFER_SIZE=8192 -D__BSD_VISIBLE -DRHINO_CONFIG_TICK_TASK=0 + --C99 -DSYSINFO_OS_VERSION=\"APP-1.0.0\" -DSYSINFO_PRODUCT_MODEL=\"ALI_AOS_STM32L496AGIx\" -DSYSINFO_DEVICE_NAME=\"STM32LL496AGIx\" -DSYSINFO_KERNEL_VERSION=\"AOS-R-1.2.0\" -DSYSINFO_APP_VERSION=\"APP-1.0.0\" -DSTDIO_UART=0 -DCONFIG_NO_TCPIP -DRHINO_CONFIG_TICK_TASK=0 -DCONFIG_AOS_KV_MULTIPTN_MODE -DCONFIG_AOS_KV_PTN=6 -DCONFIG_AOS_KV_SECOND_PTN=7 -DCONFIG_AOS_KV_PTN_SIZE=4096 -DCONFIG_AOS_KV_BUFFER_SIZE=8192 -D__BSD_VISIBLE -DRHINO_CONFIG_TICK_TASK=0 USE_HAL_DRIVER,STM32L496xx ..\..\..\..\include;..\..\..\..\kernel\rhino\core\include;..\..\..\..\platform\arch\arm\armv7m\armcc\m4;..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Inc;..\..\..\..\platform\mcu\stm32l4xx\Drivers\STM32L4xx_HAL_Driver\Inc\Legacy;..\..\..\..\platform\mcu\stm32l4xx\Drivers\CMSIS\Device\ST\STM32L4xx\Include;..\..\..\..\platform\mcu\stm32l4xx\Drivers\CMSIS\Include;..\..\..\..\platform\mcu\stm32l4xx\src\STM32L496G-Discovery\helloworld;..\..\..\..\include\hal;..\..\..\..\kernel\vcall\aos;..\..\..\..\utility\libc\compilers\armlibc @@ -527,7 +527,7 @@ k_fifo.c 1 - ..\..\..\..\kernel\rhino\core\k_fifo.c + ..\..\..\..\kernel\rhino\common\k_fifo.c k_idle.c @@ -627,7 +627,7 @@ k_trace.c 1 - ..\..\..\..\kernel\rhino\core\k_trace.c + ..\..\..\..\kernel\rhino\common\k_trace.c k_workqueue.c @@ -660,9 +660,9 @@ ..\..\..\..\platform\arch\arm\armv7m\armcc\m4\port_c.c - port_c.s + port_s.s 2 - ..\..\..\..\platform\arch\arm\armv7m\armcc\m4\port_c.s + ..\..\..\..\platform\arch\arm\armv7m\armcc\m4\port_s.s diff --git a/security/alicrypto/alicrypto.mk b/security/alicrypto/alicrypto.mk index 85dbb3ed20..2f91c0b054 100644 --- a/security/alicrypto/alicrypto.mk +++ b/security/alicrypto/alicrypto.mk @@ -18,8 +18,16 @@ GLOBAL_LDFLAGS += GLOBAL_DEFINES += CONFIG_ALICRYPTO GLOBAL_CFLAGS += +ifeq ($(COMPILER),armcc) +$(NAME)_PREBUILT_LIBRARY := lib/$(HOST_ARCH)/KEIL/libmbedcrypto.lib \ + lib/$(HOST_ARCH)/KEIL/libalicrypto.lib +else ifeq ($(COMPILER),iar) +$(NAME)_PREBUILT_LIBRARY := lib/$(HOST_ARCH)/IAR/libmbedcrytpo.a \ + lib/$(HOST_ARCH)/IAR/libalicrypto.a +else $(NAME)_PREBUILT_LIBRARY := lib/$(HOST_ARCH)/libmbedcrypto.a \ - lib/$(HOST_ARCH)/libalicrypto.a + lib/$(HOST_ARCH)/libalicrypto.a +endif ifeq ($(ALICRYPTO_TEST), yes) GLOBAL_INCLUDES += test diff --git a/security/alicrypto/test/ali_crypto_test_hash.c b/security/alicrypto/test/ali_crypto_test_hash.c index 6613a15cf0..666553b583 100644 --- a/security/alicrypto/test/ali_crypto_test_hash.c +++ b/security/alicrypto/test/ali_crypto_test_hash.c @@ -135,6 +135,10 @@ int ali_crypto_hash_test(void) } for (type = SHA1; type <= MD5; type++) { + if (type == SHA512 || type == SHA384) { + CRYPT_INF("hash not support hash 384 512\n"); + continue; + } result = ali_hash_get_ctx_size(type, &hash_ctx_size); if (result != ALI_CRYPTO_SUCCESS) { GO_RET(result, "get ctx size fail(%08x)\n", result); diff --git a/security/alicrypto/test/ali_crypto_test_rsa.c b/security/alicrypto/test/ali_crypto_test_rsa.c index 7576360a6b..bba13ba598 100644 --- a/security/alicrypto/test/ali_crypto_test_rsa.c +++ b/security/alicrypto/test/ali_crypto_test_rsa.c @@ -620,9 +620,11 @@ static int _ali_crypto_sign_verify_v1_5( CRYPT_INF("mbedtls rsa V1.5 not support hash 384 512\n"); continue; } +#if 0 if (HASH_SIZE(hash_type) + 11 > RSA_KEY_LEN) { continue; } +#endif src_size = HASH_SIZE(hash_type); CRYPT_MEMSET(src_data, 0xa, src_size); @@ -681,9 +683,11 @@ static int _ali_crypto_sign_verify_pss( CRYPT_INF("mbedtls rsa pss not support hash 512\n"); continue; } +#if 0 if (HASH_SIZE(hash_type) + 28 + 2 > RSA_KEY_LEN) { continue; } +#endif src_size = HASH_SIZE(hash_type); diff --git a/security/libid2/lib/ARM968E-S/libid2.a b/security/libid2/lib/ARM968E-S/libid2.a index 04dc582635..0ffb3dff38 100644 Binary files a/security/libid2/lib/ARM968E-S/libid2.a and b/security/libid2/lib/ARM968E-S/libid2.a differ diff --git a/security/libid2/lib/Cortex-M4/libid2.a b/security/libid2/lib/Cortex-M4/libid2.a index bd3a68ce4d..fcd0bcbb11 100644 Binary files a/security/libid2/lib/Cortex-M4/libid2.a and b/security/libid2/lib/Cortex-M4/libid2.a differ diff --git a/security/libid2/lib/linux/libid2.a b/security/libid2/lib/linux/libid2.a index 2d80315da1..66ac06be31 100644 Binary files a/security/libid2/lib/linux/libid2.a and b/security/libid2/lib/linux/libid2.a differ diff --git a/security/libid2/lib/xtensa/libid2.a b/security/libid2/lib/xtensa/libid2.a index ca5d8a7787..a70d8e516e 100644 Binary files a/security/libid2/lib/xtensa/libid2.a and b/security/libid2/lib/xtensa/libid2.a differ diff --git a/security/libid2/libid2.mk b/security/libid2/libid2.mk index 6f6aa30478..bf785e27e8 100644 --- a/security/libid2/libid2.mk +++ b/security/libid2/libid2.mk @@ -12,9 +12,7 @@ $(NAME)_PREBUILT_LIBRARY := lib/$(HOST_ARCH)/libid2.a ifeq ($(ID2_TEST), yes) ifeq ($(HOST_ARCH), linux) $(NAME)_DEFINES += CONFIG_GENERIC_LINUX=1 -else ifeq ($(HOST_ARCH), ARM968E-S) -$(NAME)_DEFINES += CONFIG_AOS_SUPPORT=1 -else ifeq ($(HOST_ARCH), xtensa) +else $(NAME)_DEFINES += CONFIG_AOS_SUPPORT=1 endif diff --git a/security/libkm/include/ks.h b/security/libkm/include/ks.h index 255cfe6cf0..16acc56f68 100644 --- a/security/libkm/include/ks.h +++ b/security/libkm/include/ks.h @@ -10,6 +10,18 @@ //the max key name len this KM can support #define MAX_NAME_LEN 16 +#define KM_SUCCESS 0x00000000 +#define KM_ERR_GENERIC 0xffff0000 +#define KM_ERR_AUTHENTICATION 0xffff0001 +#define KM_ERR_BAD_PARAMS 0xffff0002 +#define KM_ERR_NOT_SUPPORT 0xffff0003 +#define KM_ERR_BAD_FORMAT 0xffff0004 +#define KM_ERR_SHORT_BUFFER 0xffff0005 +#define KM_ERR_OUT_OF_MEMORY 0xffff0006 +#define KM_ERR_ACCESS_CONFLICT 0xffff0007 +#define KM_ERR_ITEM_NOT_FOUND 0xffff0008 +#define KM_ERR_CORRUPT_KEY 0xffff0009 + typedef void * km_op_handle_t; typedef enum { @@ -24,6 +36,7 @@ typedef enum { KM_ECC, KM_AES, KM_DES, + KM_DES3, KM_HMAC, } km_key_type; @@ -81,6 +94,10 @@ typedef struct _km_cipher_param { km_padding_type padding_type; } km_cipher_param; +typedef struct _km_hmac_param { + km_digest_type hash_type; +} km_hmac_param; + //for import raw format typedef struct _rsa_key_t { uint32_t n_len; @@ -101,49 +118,50 @@ typedef struct _rsa_key_t { uint8_t *iq; } rsa_key_t; -typedef struct _aes_key_t { +typedef struct _sym_key_t { uint32_t key_bit; uint8_t *key; -} aes_key_t; +} sym_key_t; typedef struct _km_key_data_t { km_key_type type; union { rsa_key_t rsa_data; - aes_key_t aes_key; + sym_key_t aes_key; }; } km_key_data_t; -//0 succrss -1 failed -int32_t generate_key(const char *name, const uint32_t name_len, +uint32_t generate_key(const char *name, const uint32_t name_len, uint32_t key_type, void *arg); -int32_t import_key(const char *name, const uint32_t name_len, km_format_t format, +uint32_t import_key(const char *name, const uint32_t name_len, km_format_t format, const uint8_t *key_data, const uint32_t key_data_len); -int32_t export_key(const char *name, const uint32_t name_len, km_format_t format, +uint32_t export_key(const char *name, const uint32_t name_len, km_format_t format, uint8_t **export_data, uint32_t *export_data_size); -int32_t sign(const char *name, const uint32_t name_len, void *sign_params, - const uint8_t *data, const uint32_t data_len, - uint8_t **out, uint32_t *out_len); -int32_t verify(const char *name, const uint32_t name_len, void *sign_params, - const uint8_t *data, const uint32_t data_len, - const uint8_t *signature, const uint32_t signature_len); -int32_t encrypt(const char *name, const uint32_t name_len, void *enc_params, - const uint8_t *src, const uint32_t src_len, - uint8_t **dest, uint32_t *dest_len); -int32_t decrypt(const char *name, const uint32_t name_len, void *enc_params, - const uint8_t *src, const uint32_t src_len, - uint8_t **dest, uint32_t *dest_len); -int32_t begin(const char *name, const uint32_t name_len, void *cipher_params, +uint32_t sign(const char *name, const uint32_t name_len, void *sign_params, + const uint8_t *data, const size_t data_len, + uint8_t **out, size_t *out_len); +uint32_t verify(const char *name, const uint32_t name_len, void *sign_params, + const uint8_t *data, const size_t data_len, + const uint8_t *signature, const size_t signature_len); +uint32_t encrypt(const char *name, const uint32_t name_len, void *enc_params, + const uint8_t *src, const size_t src_len, + uint8_t **dest, size_t *dest_len); +uint32_t decrypt(const char *name, const uint32_t name_len, void *enc_params, + const uint8_t *src, const size_t src_len, + uint8_t **dest, size_t *dest_len); +uint32_t begin(const char *name, const uint32_t name_len, void *cipher_params, const uint8_t *iv, const uint32_t iv_len, km_op_handle_t *operation_handle); -int32_t update(km_op_handle_t operation_handle, - const uint8_t *src, const uint32_t src_len, - uint8_t *dest, uint32_t *dest_len); -int32_t finish(km_op_handle_t operation_handle, - const uint8_t *src, const uint32_t src_len, - uint8_t *dest, uint32_t *dest_len); -int32_t delete_key(const char *name, const uint32_t name_len); -int32_t delete_all(); +uint32_t update(km_op_handle_t operation_handle, + const uint8_t *src, const size_t src_len, + uint8_t *dest, size_t *dest_len); +uint32_t finish(km_op_handle_t operation_handle, + const uint8_t *src, const size_t src_len, + uint8_t *dest, size_t *dest_len); +uint32_t delete_key(const char *name, const uint32_t name_len); +uint32_t delete_all(); + +uint32_t ks_init(); #endif /* _KS_H_ */ diff --git a/security/libkm/lib/ARM968E-S/libkm.a b/security/libkm/lib/ARM968E-S/libkm.a index 40dc635248..54819dd8ce 100644 Binary files a/security/libkm/lib/ARM968E-S/libkm.a and b/security/libkm/lib/ARM968E-S/libkm.a differ diff --git a/security/libkm/lib/Cortex-M4/libkm.a b/security/libkm/lib/Cortex-M4/libkm.a index 39e240f7bc..da03bb7107 100644 Binary files a/security/libkm/lib/Cortex-M4/libkm.a and b/security/libkm/lib/Cortex-M4/libkm.a differ diff --git a/security/libkm/lib/linux/libkm.a b/security/libkm/lib/linux/libkm.a index dbcc4104a7..ff35c37778 100644 Binary files a/security/libkm/lib/linux/libkm.a and b/security/libkm/lib/linux/libkm.a differ diff --git a/security/libkm/lib/xtensa/libkm.a b/security/libkm/lib/xtensa/libkm.a index c0e8f6b5cc..f1a6dfad1f 100644 Binary files a/security/libkm/lib/xtensa/libkm.a and b/security/libkm/lib/xtensa/libkm.a differ diff --git a/security/mbedtls/include/mbedtls/config.h b/security/mbedtls/include/mbedtls/config.h index 7afbd829a3..5ad5b4ad3b 100644 --- a/security/mbedtls/include/mbedtls/config.h +++ b/security/mbedtls/include/mbedtls/config.h @@ -76,8 +76,6 @@ #define MBEDTLS_PK_ALT #define MBEDTLS_AES_ALT -#define MBEDTLS_SSL_MAX_CONTENT_LEN (4 * 1024) /* Size of the input / output buffer */ - #include "mbedtls/check_config.h" #endif /* MBEDTLS_CONFIG_H */ diff --git a/security/mbedtls/include/mbedtls/des.h b/security/mbedtls/include/mbedtls/des.h new file mode 100644 index 0000000000..5ca2ecf2e0 --- /dev/null +++ b/security/mbedtls/include/mbedtls/des.h @@ -0,0 +1,306 @@ +/** + * \file des.h + * + * \brief DES block cipher + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +#ifndef MBEDTLS_DES_H +#define MBEDTLS_DES_H + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include +#include + +#define MBEDTLS_DES_ENCRYPT 1 +#define MBEDTLS_DES_DECRYPT 0 + +#define MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH -0x0032 /**< The data input has an invalid length. */ + +#define MBEDTLS_DES_KEY_SIZE 8 + +#if !defined(MBEDTLS_DES_ALT) +// Regular implementation +// + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief DES context structure + */ +typedef struct +{ + uint32_t sk[32]; /*!< DES subkeys */ +} +mbedtls_des_context; + +/** + * \brief Triple-DES context structure + */ +typedef struct +{ + uint32_t sk[96]; /*!< 3DES subkeys */ +} +mbedtls_des3_context; + +/** + * \brief Initialize DES context + * + * \param ctx DES context to be initialized + */ +void mbedtls_des_init( mbedtls_des_context *ctx ); + +/** + * \brief Clear DES context + * + * \param ctx DES context to be cleared + */ +void mbedtls_des_free( mbedtls_des_context *ctx ); + +/** + * \brief Initialize Triple-DES context + * + * \param ctx DES3 context to be initialized + */ +void mbedtls_des3_init( mbedtls_des3_context *ctx ); + +/** + * \brief Clear Triple-DES context + * + * \param ctx DES3 context to be cleared + */ +void mbedtls_des3_free( mbedtls_des3_context *ctx ); + +/** + * \brief Set key parity on the given key to odd. + * + * DES keys are 56 bits long, but each byte is padded with + * a parity bit to allow verification. + * + * \param key 8-byte secret key + */ +void mbedtls_des_key_set_parity( unsigned char key[MBEDTLS_DES_KEY_SIZE] ); + +/** + * \brief Check that key parity on the given key is odd. + * + * DES keys are 56 bits long, but each byte is padded with + * a parity bit to allow verification. + * + * \param key 8-byte secret key + * + * \return 0 is parity was ok, 1 if parity was not correct. + */ +int mbedtls_des_key_check_key_parity( const unsigned char key[MBEDTLS_DES_KEY_SIZE] ); + +/** + * \brief Check that key is not a weak or semi-weak DES key + * + * \param key 8-byte secret key + * + * \return 0 if no weak key was found, 1 if a weak key was identified. + */ +int mbedtls_des_key_check_weak( const unsigned char key[MBEDTLS_DES_KEY_SIZE] ); + +/** + * \brief DES key schedule (56-bit, encryption) + * + * \param ctx DES context to be initialized + * \param key 8-byte secret key + * + * \return 0 + */ +int mbedtls_des_setkey_enc( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] ); + +/** + * \brief DES key schedule (56-bit, decryption) + * + * \param ctx DES context to be initialized + * \param key 8-byte secret key + * + * \return 0 + */ +int mbedtls_des_setkey_dec( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] ); + +/** + * \brief Triple-DES key schedule (112-bit, encryption) + * + * \param ctx 3DES context to be initialized + * \param key 16-byte secret key + * + * \return 0 + */ +int mbedtls_des3_set2key_enc( mbedtls_des3_context *ctx, + const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] ); + +/** + * \brief Triple-DES key schedule (112-bit, decryption) + * + * \param ctx 3DES context to be initialized + * \param key 16-byte secret key + * + * \return 0 + */ +int mbedtls_des3_set2key_dec( mbedtls_des3_context *ctx, + const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] ); + +/** + * \brief Triple-DES key schedule (168-bit, encryption) + * + * \param ctx 3DES context to be initialized + * \param key 24-byte secret key + * + * \return 0 + */ +int mbedtls_des3_set3key_enc( mbedtls_des3_context *ctx, + const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] ); + +/** + * \brief Triple-DES key schedule (168-bit, decryption) + * + * \param ctx 3DES context to be initialized + * \param key 24-byte secret key + * + * \return 0 + */ +int mbedtls_des3_set3key_dec( mbedtls_des3_context *ctx, + const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] ); + +/** + * \brief DES-ECB block encryption/decryption + * + * \param ctx DES context + * \param input 64-bit input block + * \param output 64-bit output block + * + * \return 0 if successful + */ +int mbedtls_des_crypt_ecb( mbedtls_des_context *ctx, + const unsigned char input[8], + unsigned char output[8] ); + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +/** + * \brief DES-CBC buffer encryption/decryption + * + * \note Upon exit, the content of the IV is updated so that you can + * call the function same function again on the following + * block(s) of data and get the same result as if it was + * encrypted in one call. This allows a "streaming" usage. + * If on the other hand you need to retain the contents of the + * IV, you should either save it manually or use the cipher + * module instead. + * + * \param ctx DES context + * \param mode MBEDTLS_DES_ENCRYPT or MBEDTLS_DES_DECRYPT + * \param length length of the input data + * \param iv initialization vector (updated after use) + * \param input buffer holding the input data + * \param output buffer holding the output data + */ +int mbedtls_des_crypt_cbc( mbedtls_des_context *ctx, + int mode, + size_t length, + unsigned char iv[8], + const unsigned char *input, + unsigned char *output ); +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +/** + * \brief 3DES-ECB block encryption/decryption + * + * \param ctx 3DES context + * \param input 64-bit input block + * \param output 64-bit output block + * + * \return 0 if successful + */ +int mbedtls_des3_crypt_ecb( mbedtls_des3_context *ctx, + const unsigned char input[8], + unsigned char output[8] ); + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +/** + * \brief 3DES-CBC buffer encryption/decryption + * + * \note Upon exit, the content of the IV is updated so that you can + * call the function same function again on the following + * block(s) of data and get the same result as if it was + * encrypted in one call. This allows a "streaming" usage. + * If on the other hand you need to retain the contents of the + * IV, you should either save it manually or use the cipher + * module instead. + * + * \param ctx 3DES context + * \param mode MBEDTLS_DES_ENCRYPT or MBEDTLS_DES_DECRYPT + * \param length length of the input data + * \param iv initialization vector (updated after use) + * \param input buffer holding the input data + * \param output buffer holding the output data + * + * \return 0 if successful, or MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH + */ +int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx, + int mode, + size_t length, + unsigned char iv[8], + const unsigned char *input, + unsigned char *output ); +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +/** + * \brief Internal function for key expansion. + * (Only exposed to allow overriding it, + * see MBEDTLS_DES_SETKEY_ALT) + * + * \param SK Round keys + * \param key Base key + */ +void mbedtls_des_setkey( uint32_t SK[32], + const unsigned char key[MBEDTLS_DES_KEY_SIZE] ); +#ifdef __cplusplus +} +#endif + +#else /* MBEDTLS_DES_ALT */ +#include "des_alt.h" +#endif /* MBEDTLS_DES_ALT */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \brief Checkup routine + * + * \return 0 if successful, or 1 if the test failed + */ +int mbedtls_des_self_test( int verbose ); + +#ifdef __cplusplus +} +#endif + +#endif /* des.h */ diff --git a/security/mbedtls/include/mbedtls/ssl.h b/security/mbedtls/include/mbedtls/ssl.h index 495e02cb0e..d0456701f9 100644 --- a/security/mbedtls/include/mbedtls/ssl.h +++ b/security/mbedtls/include/mbedtls/ssl.h @@ -216,7 +216,7 @@ * peers are using it too! */ #if !defined(MBEDTLS_SSL_MAX_CONTENT_LEN) -#define MBEDTLS_SSL_MAX_CONTENT_LEN 16384 /**< Size of the input / output buffer */ +#define MBEDTLS_SSL_MAX_CONTENT_LEN (4*1024) /**< ali default value. Size of the input / output buffer */ #endif /* \} name SECTION: Module settings */ diff --git a/security/mbedtls/include/mbedtls/ssl_internal.h b/security/mbedtls/include/mbedtls/ssl_internal.h new file mode 100644 index 0000000000..668c0f567c --- /dev/null +++ b/security/mbedtls/include/mbedtls/ssl_internal.h @@ -0,0 +1,500 @@ +/** + * \file ssl_ticket.h + * + * \brief Internal functions shared by the SSL modules + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +#ifndef MBEDTLS_SSL_INTERNAL_H +#define MBEDTLS_SSL_INTERNAL_H + +#include "ssl.h" + +#if defined(MBEDTLS_MD5_C) +#include "md5.h" +#endif + +#if defined(MBEDTLS_SHA1_C) +#include "sha1.h" +#endif + +#if defined(MBEDTLS_SHA256_C) +#include "sha256.h" +#endif + +#if defined(MBEDTLS_SHA512_C) +#include "sha512.h" +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) +#include "ecjpake.h" +#endif + +#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ + !defined(inline) && !defined(__cplusplus) +#define inline __inline +#endif + +/* Determine minimum supported version */ +#define MBEDTLS_SSL_MIN_MAJOR_VERSION MBEDTLS_SSL_MAJOR_VERSION_3 + +#if defined(MBEDTLS_SSL_PROTO_SSL3) +#define MBEDTLS_SSL_MIN_MINOR_VERSION MBEDTLS_SSL_MINOR_VERSION_0 +#else +#if defined(MBEDTLS_SSL_PROTO_TLS1) +#define MBEDTLS_SSL_MIN_MINOR_VERSION MBEDTLS_SSL_MINOR_VERSION_1 +#else +#if defined(MBEDTLS_SSL_PROTO_TLS1_1) +#define MBEDTLS_SSL_MIN_MINOR_VERSION MBEDTLS_SSL_MINOR_VERSION_2 +#else +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) +#define MBEDTLS_SSL_MIN_MINOR_VERSION MBEDTLS_SSL_MINOR_VERSION_3 +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ +#endif /* MBEDTLS_SSL_PROTO_TLS1_1 */ +#endif /* MBEDTLS_SSL_PROTO_TLS1 */ +#endif /* MBEDTLS_SSL_PROTO_SSL3 */ + +/* Determine maximum supported version */ +#define MBEDTLS_SSL_MAX_MAJOR_VERSION MBEDTLS_SSL_MAJOR_VERSION_3 + +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) +#define MBEDTLS_SSL_MAX_MINOR_VERSION MBEDTLS_SSL_MINOR_VERSION_3 +#else +#if defined(MBEDTLS_SSL_PROTO_TLS1_1) +#define MBEDTLS_SSL_MAX_MINOR_VERSION MBEDTLS_SSL_MINOR_VERSION_2 +#else +#if defined(MBEDTLS_SSL_PROTO_TLS1) +#define MBEDTLS_SSL_MAX_MINOR_VERSION MBEDTLS_SSL_MINOR_VERSION_1 +#else +#if defined(MBEDTLS_SSL_PROTO_SSL3) +#define MBEDTLS_SSL_MAX_MINOR_VERSION MBEDTLS_SSL_MINOR_VERSION_0 +#endif /* MBEDTLS_SSL_PROTO_SSL3 */ +#endif /* MBEDTLS_SSL_PROTO_TLS1 */ +#endif /* MBEDTLS_SSL_PROTO_TLS1_1 */ +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ + +#define MBEDTLS_SSL_INITIAL_HANDSHAKE 0 +#define MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS 1 /* In progress */ +#define MBEDTLS_SSL_RENEGOTIATION_DONE 2 /* Done or aborted */ +#define MBEDTLS_SSL_RENEGOTIATION_PENDING 3 /* Requested (server only) */ + +/* + * DTLS retransmission states, see RFC 6347 4.2.4 + * + * The SENDING state is merged in PREPARING for initial sends, + * but is distinct for resends. + * + * Note: initial state is wrong for server, but is not used anyway. + */ +#define MBEDTLS_SSL_RETRANS_PREPARING 0 +#define MBEDTLS_SSL_RETRANS_SENDING 1 +#define MBEDTLS_SSL_RETRANS_WAITING 2 +#define MBEDTLS_SSL_RETRANS_FINISHED 3 + +/* + * Allow extra bytes for record, authentication and encryption overhead: + * counter (8) + header (5) + IV(16) + MAC (16-48) + padding (0-256) + * and allow for a maximum of 1024 of compression expansion if + * enabled. + */ +#if defined(MBEDTLS_ZLIB_SUPPORT) +#define MBEDTLS_SSL_COMPRESSION_ADD 1024 +#else +#define MBEDTLS_SSL_COMPRESSION_ADD 0 +#endif + +#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_MODE_CBC) +/* Ciphersuites using HMAC */ +#if defined(MBEDTLS_SHA512_C) +#define MBEDTLS_SSL_MAC_ADD 48 /* SHA-384 used for HMAC */ +#elif defined(MBEDTLS_SHA256_C) +#define MBEDTLS_SSL_MAC_ADD 32 /* SHA-256 used for HMAC */ +#else +#define MBEDTLS_SSL_MAC_ADD 20 /* SHA-1 used for HMAC */ +#endif +#else +/* AEAD ciphersuites: GCM and CCM use a 128 bits tag */ +#define MBEDTLS_SSL_MAC_ADD 16 +#endif + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#define MBEDTLS_SSL_PADDING_ADD 256 +#else +#define MBEDTLS_SSL_PADDING_ADD 0 +#endif + +#define MBEDTLS_SSL_BUFFER_LEN ( MBEDTLS_SSL_MAX_CONTENT_LEN \ + + MBEDTLS_SSL_COMPRESSION_ADD \ + + 29 /* counter + header + IV */ \ + + MBEDTLS_SSL_MAC_ADD \ + + MBEDTLS_SSL_PADDING_ADD \ + ) + +/* + * TLS extension flags (for extensions with outgoing ServerHello content + * that need it (e.g. for RENEGOTIATION_INFO the server already knows because + * of state of the renegotiation flag, so no indicator is required) + */ +#define MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT (1 << 0) +#define MBEDTLS_TLS_EXT_ECJPAKE_KKPP_OK (1 << 1) + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * This structure contains the parameters only needed during handshake. + */ +struct mbedtls_ssl_handshake_params +{ + /* + * Handshake specific crypto variables + */ + int sig_alg; /*!< Hash algorithm for signature */ + int verify_sig_alg; /*!< Signature algorithm for verify */ +#if defined(MBEDTLS_DHM_C) + mbedtls_dhm_context dhm_ctx; /*!< DHM key exchange */ +#endif +#if defined(MBEDTLS_ECDH_C) + mbedtls_ecdh_context ecdh_ctx; /*!< ECDH key exchange */ +#endif +#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) + mbedtls_ecjpake_context ecjpake_ctx; /*!< EC J-PAKE key exchange */ +#if defined(MBEDTLS_SSL_CLI_C) + unsigned char *ecjpake_cache; /*!< Cache for ClientHello ext */ + size_t ecjpake_cache_len; /*!< Length of cached data */ +#endif +#endif +#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) + const mbedtls_ecp_curve_info **curves; /*!< Supported elliptic curves */ +#endif +#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) + unsigned char *psk; /*!< PSK from the callback */ + size_t psk_len; /*!< Length of PSK from callback */ +#endif +#if defined(MBEDTLS_X509_CRT_PARSE_C) + mbedtls_ssl_key_cert *key_cert; /*!< chosen key/cert pair (server) */ +#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) + int sni_authmode; /*!< authmode from SNI callback */ + mbedtls_ssl_key_cert *sni_key_cert; /*!< key/cert list from SNI */ + mbedtls_x509_crt *sni_ca_chain; /*!< trusted CAs from SNI callback */ + mbedtls_x509_crl *sni_ca_crl; /*!< trusted CAs CRLs from SNI */ +#endif +#endif /* MBEDTLS_X509_CRT_PARSE_C */ +#if defined(MBEDTLS_SSL_PROTO_DTLS) + unsigned int out_msg_seq; /*!< Outgoing handshake sequence number */ + unsigned int in_msg_seq; /*!< Incoming handshake sequence number */ + + unsigned char *verify_cookie; /*!< Cli: HelloVerifyRequest cookie + Srv: unused */ + unsigned char verify_cookie_len; /*!< Cli: cookie length + Srv: flag for sending a cookie */ + + unsigned char *hs_msg; /*!< Reassembled handshake message */ + + uint32_t retransmit_timeout; /*!< Current value of timeout */ + unsigned char retransmit_state; /*!< Retransmission state */ + mbedtls_ssl_flight_item *flight; /*!< Current outgoing flight */ + mbedtls_ssl_flight_item *cur_msg; /*!< Current message in flight */ + unsigned int in_flight_start_seq; /*!< Minimum message sequence in the + flight being received */ + mbedtls_ssl_transform *alt_transform_out; /*!< Alternative transform for + resending messages */ + unsigned char alt_out_ctr[8]; /*!< Alternative record epoch/counter + for resending messages */ +#endif + + /* + * Checksum contexts + */ +#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ + defined(MBEDTLS_SSL_PROTO_TLS1_1) + mbedtls_md5_context fin_md5; + mbedtls_sha1_context fin_sha1; +#endif +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) +#if defined(MBEDTLS_SHA256_C) + mbedtls_sha256_context fin_sha256; +#endif +#if defined(MBEDTLS_SHA512_C) + mbedtls_sha512_context fin_sha512; +#endif +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ + + void (*update_checksum)(mbedtls_ssl_context *, const unsigned char *, size_t); + void (*calc_verify)(mbedtls_ssl_context *, unsigned char *); + void (*calc_finished)(mbedtls_ssl_context *, unsigned char *, int); + int (*tls_prf)(const unsigned char *, size_t, const char *, + const unsigned char *, size_t, + unsigned char *, size_t); + + size_t pmslen; /*!< premaster length */ + + unsigned char randbytes[64]; /*!< random bytes */ + unsigned char premaster[MBEDTLS_PREMASTER_SIZE]; + /*!< premaster secret */ + + int resume; /*!< session resume indicator*/ + int max_major_ver; /*!< max. major version client*/ + int max_minor_ver; /*!< max. minor version client*/ + int cli_exts; /*!< client extension presence*/ + +#if defined(MBEDTLS_SSL_SESSION_TICKETS) + int new_session_ticket; /*!< use NewSessionTicket? */ +#endif /* MBEDTLS_SSL_SESSION_TICKETS */ +#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) + int extended_ms; /*!< use Extended Master Secret? */ +#endif +}; + +/* + * This structure contains a full set of runtime transform parameters + * either in negotiation or active. + */ +struct mbedtls_ssl_transform +{ + /* + * Session specific crypto layer + */ + const mbedtls_ssl_ciphersuite_t *ciphersuite_info; + /*!< Chosen cipersuite_info */ + unsigned int keylen; /*!< symmetric key length (bytes) */ + size_t minlen; /*!< min. ciphertext length */ + size_t ivlen; /*!< IV length */ + size_t fixed_ivlen; /*!< Fixed part of IV (AEAD) */ + size_t maclen; /*!< MAC length */ + + unsigned char iv_enc[16]; /*!< IV (encryption) */ + unsigned char iv_dec[16]; /*!< IV (decryption) */ + +#if defined(MBEDTLS_SSL_PROTO_SSL3) + /* Needed only for SSL v3.0 secret */ + unsigned char mac_enc[20]; /*!< SSL v3.0 secret (enc) */ + unsigned char mac_dec[20]; /*!< SSL v3.0 secret (dec) */ +#endif /* MBEDTLS_SSL_PROTO_SSL3 */ + + mbedtls_md_context_t md_ctx_enc; /*!< MAC (encryption) */ + mbedtls_md_context_t md_ctx_dec; /*!< MAC (decryption) */ + + mbedtls_cipher_context_t cipher_ctx_enc; /*!< encryption context */ + mbedtls_cipher_context_t cipher_ctx_dec; /*!< decryption context */ + + /* + * Session specific compression layer + */ +#if defined(MBEDTLS_ZLIB_SUPPORT) + z_stream ctx_deflate; /*!< compression context */ + z_stream ctx_inflate; /*!< decompression context */ +#endif +}; + +#if defined(MBEDTLS_X509_CRT_PARSE_C) +/* + * List of certificate + private key pairs + */ +struct mbedtls_ssl_key_cert +{ + mbedtls_x509_crt *cert; /*!< cert */ + mbedtls_pk_context *key; /*!< private key */ + mbedtls_ssl_key_cert *next; /*!< next key/cert pair */ +}; +#endif /* MBEDTLS_X509_CRT_PARSE_C */ + +#if defined(MBEDTLS_SSL_PROTO_DTLS) +/* + * List of handshake messages kept around for resending + */ +struct mbedtls_ssl_flight_item +{ + unsigned char *p; /*!< message, including handshake headers */ + size_t len; /*!< length of p */ + unsigned char type; /*!< type of the message: handshake or CCS */ + mbedtls_ssl_flight_item *next; /*!< next handshake message(s) */ +}; +#endif /* MBEDTLS_SSL_PROTO_DTLS */ + + +/** + * \brief Free referenced items in an SSL transform context and clear + * memory + * + * \param transform SSL transform context + */ +void mbedtls_ssl_transform_free( mbedtls_ssl_transform *transform ); + +/** + * \brief Free referenced items in an SSL handshake context and clear + * memory + * + * \param handshake SSL handshake context + */ +void mbedtls_ssl_handshake_free( mbedtls_ssl_handshake_params *handshake ); + +int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl ); +int mbedtls_ssl_handshake_server_step( mbedtls_ssl_context *ssl ); +void mbedtls_ssl_handshake_wrapup( mbedtls_ssl_context *ssl ); + +int mbedtls_ssl_send_fatal_handshake_failure( mbedtls_ssl_context *ssl ); + +void mbedtls_ssl_reset_checksum( mbedtls_ssl_context *ssl ); +int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl ); + +int mbedtls_ssl_read_record_layer( mbedtls_ssl_context *ssl ); +int mbedtls_ssl_handle_message_type( mbedtls_ssl_context *ssl ); +int mbedtls_ssl_prepare_handshake_record( mbedtls_ssl_context *ssl ); +void mbedtls_ssl_update_handshake_status( mbedtls_ssl_context *ssl ); + +int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl ); +int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want ); + +int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl ); +int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl ); + +int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl ); +int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl ); + +int mbedtls_ssl_parse_change_cipher_spec( mbedtls_ssl_context *ssl ); +int mbedtls_ssl_write_change_cipher_spec( mbedtls_ssl_context *ssl ); + +int mbedtls_ssl_parse_finished( mbedtls_ssl_context *ssl ); +int mbedtls_ssl_write_finished( mbedtls_ssl_context *ssl ); + +void mbedtls_ssl_optimize_checksum( mbedtls_ssl_context *ssl, + const mbedtls_ssl_ciphersuite_t *ciphersuite_info ); + +#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) +int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exchange_type_t key_ex ); +#endif + +#if defined(MBEDTLS_PK_C) +unsigned char mbedtls_ssl_sig_from_pk( mbedtls_pk_context *pk ); +mbedtls_pk_type_t mbedtls_ssl_pk_alg_from_sig( unsigned char sig ); +#endif + +mbedtls_md_type_t mbedtls_ssl_md_alg_from_hash( unsigned char hash ); +unsigned char mbedtls_ssl_hash_from_md_alg( int md ); +int mbedtls_ssl_set_calc_verify_md( mbedtls_ssl_context *ssl, int md ); + +#if defined(MBEDTLS_ECP_C) +int mbedtls_ssl_check_curve( const mbedtls_ssl_context *ssl, mbedtls_ecp_group_id grp_id ); +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) +int mbedtls_ssl_check_sig_hash( const mbedtls_ssl_context *ssl, + mbedtls_md_type_t md ); +#endif + +#if defined(MBEDTLS_X509_CRT_PARSE_C) +static inline mbedtls_pk_context *mbedtls_ssl_own_key( mbedtls_ssl_context *ssl ) +{ + mbedtls_ssl_key_cert *key_cert; + + if( ssl->handshake != NULL && ssl->handshake->key_cert != NULL ) + key_cert = ssl->handshake->key_cert; + else + key_cert = ssl->conf->key_cert; + + return( key_cert == NULL ? NULL : key_cert->key ); +} + +static inline mbedtls_x509_crt *mbedtls_ssl_own_cert( mbedtls_ssl_context *ssl ) +{ + mbedtls_ssl_key_cert *key_cert; + + if( ssl->handshake != NULL && ssl->handshake->key_cert != NULL ) + key_cert = ssl->handshake->key_cert; + else + key_cert = ssl->conf->key_cert; + + return( key_cert == NULL ? NULL : key_cert->cert ); +} + +/* + * Check usage of a certificate wrt extensions: + * keyUsage, extendedKeyUsage (later), and nSCertType (later). + * + * Warning: cert_endpoint is the endpoint of the cert (ie, of our peer when we + * check a cert we received from them)! + * + * Return 0 if everything is OK, -1 if not. + */ +int mbedtls_ssl_check_cert_usage( const mbedtls_x509_crt *cert, + const mbedtls_ssl_ciphersuite_t *ciphersuite, + int cert_endpoint, + uint32_t *flags ); +#endif /* MBEDTLS_X509_CRT_PARSE_C */ + +void mbedtls_ssl_write_version( int major, int minor, int transport, + unsigned char ver[2] ); +void mbedtls_ssl_read_version( int *major, int *minor, int transport, + const unsigned char ver[2] ); + +static inline size_t mbedtls_ssl_hdr_len( const mbedtls_ssl_context *ssl ) +{ +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + return( 13 ); +#else + ((void) ssl); +#endif + return( 5 ); +} + +static inline size_t mbedtls_ssl_hs_hdr_len( const mbedtls_ssl_context *ssl ) +{ +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + return( 12 ); +#else + ((void) ssl); +#endif + return( 4 ); +} + +#if defined(MBEDTLS_SSL_PROTO_DTLS) +void mbedtls_ssl_send_flight_completed( mbedtls_ssl_context *ssl ); +void mbedtls_ssl_recv_flight_completed( mbedtls_ssl_context *ssl ); +int mbedtls_ssl_resend( mbedtls_ssl_context *ssl ); +#endif + +/* Visible for testing purposes only */ +#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) +int mbedtls_ssl_dtls_replay_check( mbedtls_ssl_context *ssl ); +void mbedtls_ssl_dtls_replay_update( mbedtls_ssl_context *ssl ); +#endif + +/* constant-time buffer comparison */ +static inline int mbedtls_ssl_safer_memcmp( const void *a, const void *b, size_t n ) +{ + size_t i; + const unsigned char *A = (const unsigned char *) a; + const unsigned char *B = (const unsigned char *) b; + unsigned char diff = 0; + + for( i = 0; i < n; i++ ) + diff |= A[i] ^ B[i]; + + return( diff ); +} + +#ifdef __cplusplus +} +#endif + +#endif /* ssl_internal.h */ diff --git a/security/mbedtls/mbedtls.mk b/security/mbedtls/mbedtls.mk index 0e6cf0af2e..1d913e2820 100644 --- a/security/mbedtls/mbedtls.mk +++ b/security/mbedtls/mbedtls.mk @@ -25,8 +25,6 @@ ifeq ($(DEBUG), yes) $(NAME)_DEFINES += CONFIG_SSL_DEBUG endif -$(NAME)_COMPONENTS := alicrypto - ifeq ($(HOST_ARCH), linux) ifeq ($(LWIP), 1) $(NAME)_DEFINES += LWIP_ENABLED @@ -35,26 +33,79 @@ else $(NAME)_DEFINES += LWIP_ENABLED endif -ifeq ($(HOST_ARCH), linux) -$(NAME)_PREBUILT_LIBRARY := lib/$(HOST_ARCH)/libmbedtls.a -ifeq (1,$(with_lwip)) -$(info using lwip version mbedtls) -$(NAME)_PREBUILT_LIBRARY := lib/$(HOST_ARCH)/libmbedtls.a.lwip -endif -else ifeq ($(HOST_ARCH), xtensa) -$(NAME)_PREBUILT_LIBRARY := lib/$(HOST_ARCH)/libmbedtls.a -ifeq ($(DEBUG), yes) -$(info using libmbedtls debug version) -$(NAME)_PREBUILT_LIBRARY := lib/$(HOST_ARCH)/libmbedtls.a.dbg -endif -else -$(NAME)_PREBUILT_LIBRARY := lib/$(HOST_ARCH)/libmbedtls.a -ifeq ($(DEBUG), yes) -$(info using libmbedtls debug version) -$(NAME)_PREBUILT_LIBRARY := lib/$(HOST_ARCH)/libmbedtls.a.dbg -endif +ifeq ($(COMPILER),armcc) +$(NAME)_PREBUILT_LIBRARY := lib/$(HOST_ARCH)/KEIL/libmbedtls.lib +else ifeq ($(COMPILER),iar) +$(NAME)_PREBUILT_LIBRARY := lib/$(HOST_ARCH)/IAR/libmbedtls.a endif -$(NAME)_SOURCES := mbedtls_net.c -$(NAME)_SOURCES += mbedtls_ssl.c +$(NAME)_COMPONENTS := alicrypto + +$(NAME)_SOURCES := src/mbedtls_net.c +$(NAME)_SOURCES += src/mbedtls_ssl.c + +$(NAME)_SOURCES += src/aes.c +$(NAME)_SOURCES += src/aesni.c +$(NAME)_SOURCES += src/arc4.c +$(NAME)_SOURCES += src/asn1write.c +$(NAME)_SOURCES += src/base64.c +$(NAME)_SOURCES += src/bignum.c +$(NAME)_SOURCES += src/blowfish.c +$(NAME)_SOURCES += src/camellia.c +$(NAME)_SOURCES += src/ccm.c +$(NAME)_SOURCES += src/cipher.c +$(NAME)_SOURCES += src/cipher_wrap.c +$(NAME)_SOURCES += src/cmac.c +$(NAME)_SOURCES += src/ctr_drbg.c +$(NAME)_SOURCES += src/debug.c +$(NAME)_SOURCES += src/des.c +$(NAME)_SOURCES += src/dhm.c +$(NAME)_SOURCES += src/ecdh.c +$(NAME)_SOURCES += src/ecdsa.c +$(NAME)_SOURCES += src/ecjpake.c +$(NAME)_SOURCES += src/ecp.c +$(NAME)_SOURCES += src/ecp_curves.c +$(NAME)_SOURCES += src/entropy.c +$(NAME)_SOURCES += src/entropy_poll.c +$(NAME)_SOURCES += src/error.c +$(NAME)_SOURCES += src/gcm.c +$(NAME)_SOURCES += src/havege.c +$(NAME)_SOURCES += src/hmac_drbg.c +$(NAME)_SOURCES += src/md2.c +$(NAME)_SOURCES += src/md4.c +$(NAME)_SOURCES += src/memory_buffer_alloc.c +$(NAME)_SOURCES += src/net_sockets.c +$(NAME)_SOURCES += src/oid.c +$(NAME)_SOURCES += src/padlock.c +$(NAME)_SOURCES += src/pem.c +$(NAME)_SOURCES += src/pk.c +$(NAME)_SOURCES += src/pkcs11.c +$(NAME)_SOURCES += src/pkcs12.c +$(NAME)_SOURCES += src/pkcs5.c +$(NAME)_SOURCES += src/pkparse.c +$(NAME)_SOURCES += src/pk_wrap.c +$(NAME)_SOURCES += src/pkwrite.c +$(NAME)_SOURCES += src/platform.c +$(NAME)_SOURCES += src/ripemd160.c +$(NAME)_SOURCES += src/rsa.c +$(NAME)_SOURCES += src/sha512.c +$(NAME)_SOURCES += src/ssl_cache.c +$(NAME)_SOURCES += src/ssl_ciphersuites.c +$(NAME)_SOURCES += src/ssl_cli.c +$(NAME)_SOURCES += src/ssl_cookie.c +$(NAME)_SOURCES += src/ssl_srv.c +$(NAME)_SOURCES += src/ssl_ticket.c +$(NAME)_SOURCES += src/ssl_tls.c +$(NAME)_SOURCES += src/timing.c +$(NAME)_SOURCES += src/version.c +$(NAME)_SOURCES += src/version_features.c +$(NAME)_SOURCES += src/x509.c +$(NAME)_SOURCES += src/x509_create.c +$(NAME)_SOURCES += src/x509_crl.c +$(NAME)_SOURCES += src/x509_crt.c +$(NAME)_SOURCES += src/x509_csr.c +$(NAME)_SOURCES += src/x509write_crt.c +$(NAME)_SOURCES += src/x509write_csr.c +$(NAME)_SOURCES += src/xtea.c +$(NAME)_SOURCES += src/mbedtls_alt.c diff --git a/security/mbedtls/src/aes.c b/security/mbedtls/src/aes.c new file mode 100644 index 0000000000..8823a54ab5 --- /dev/null +++ b/security/mbedtls/src/aes.c @@ -0,0 +1,1494 @@ +/* + * FIPS-197 compliant AES implementation + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +/* + * The AES block cipher was designed by Vincent Rijmen and Joan Daemen. + * + * http://csrc.nist.gov/encryption/aes/rijndael/Rijndael.pdf + * http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_AES_C) + +#include + +#include "mbedtls/aes.h" +#if defined(MBEDTLS_PADLOCK_C) +#include "mbedtls/padlock.h" +#endif +#if defined(MBEDTLS_AESNI_C) +#include "mbedtls/aesni.h" +#endif + +#if defined(MBEDTLS_SELF_TEST) +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_printf printf +#endif /* MBEDTLS_PLATFORM_C */ +#endif /* MBEDTLS_SELF_TEST */ + +#if !defined(MBEDTLS_AES_ALT) + +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0; +} + +/* + * 32-bit integer manipulation macros (little endian) + */ +#ifndef GET_UINT32_LE +#define GET_UINT32_LE(n,b,i) \ +{ \ + (n) = ( (uint32_t) (b)[(i) ] ) \ + | ( (uint32_t) (b)[(i) + 1] << 8 ) \ + | ( (uint32_t) (b)[(i) + 2] << 16 ) \ + | ( (uint32_t) (b)[(i) + 3] << 24 ); \ +} +#endif + +#ifndef PUT_UINT32_LE +#define PUT_UINT32_LE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \ + (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \ + (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \ + (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \ +} +#endif + +#if defined(MBEDTLS_PADLOCK_C) && \ + ( defined(MBEDTLS_HAVE_X86) || defined(MBEDTLS_PADLOCK_ALIGN16) ) +static int aes_padlock_ace = -1; +#endif + +#if defined(MBEDTLS_AES_ROM_TABLES) +/* + * Forward S-box + */ +static const unsigned char FSb[256] = +{ + 0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, + 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76, + 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, + 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, + 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, + 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15, + 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, + 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75, + 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, + 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, + 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, + 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF, + 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, + 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8, + 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, + 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, + 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, + 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73, + 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, + 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB, + 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, + 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, + 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, + 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08, + 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, + 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A, + 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, + 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, + 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, + 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF, + 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, + 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16 +}; + +/* + * Forward tables + */ +#define FT \ +\ + V(A5,63,63,C6), V(84,7C,7C,F8), V(99,77,77,EE), V(8D,7B,7B,F6), \ + V(0D,F2,F2,FF), V(BD,6B,6B,D6), V(B1,6F,6F,DE), V(54,C5,C5,91), \ + V(50,30,30,60), V(03,01,01,02), V(A9,67,67,CE), V(7D,2B,2B,56), \ + V(19,FE,FE,E7), V(62,D7,D7,B5), V(E6,AB,AB,4D), V(9A,76,76,EC), \ + V(45,CA,CA,8F), V(9D,82,82,1F), V(40,C9,C9,89), V(87,7D,7D,FA), \ + V(15,FA,FA,EF), V(EB,59,59,B2), V(C9,47,47,8E), V(0B,F0,F0,FB), \ + V(EC,AD,AD,41), V(67,D4,D4,B3), V(FD,A2,A2,5F), V(EA,AF,AF,45), \ + V(BF,9C,9C,23), V(F7,A4,A4,53), V(96,72,72,E4), V(5B,C0,C0,9B), \ + V(C2,B7,B7,75), V(1C,FD,FD,E1), V(AE,93,93,3D), V(6A,26,26,4C), \ + V(5A,36,36,6C), V(41,3F,3F,7E), V(02,F7,F7,F5), V(4F,CC,CC,83), \ + V(5C,34,34,68), V(F4,A5,A5,51), V(34,E5,E5,D1), V(08,F1,F1,F9), \ + V(93,71,71,E2), V(73,D8,D8,AB), V(53,31,31,62), V(3F,15,15,2A), \ + V(0C,04,04,08), V(52,C7,C7,95), V(65,23,23,46), V(5E,C3,C3,9D), \ + V(28,18,18,30), V(A1,96,96,37), V(0F,05,05,0A), V(B5,9A,9A,2F), \ + V(09,07,07,0E), V(36,12,12,24), V(9B,80,80,1B), V(3D,E2,E2,DF), \ + V(26,EB,EB,CD), V(69,27,27,4E), V(CD,B2,B2,7F), V(9F,75,75,EA), \ + V(1B,09,09,12), V(9E,83,83,1D), V(74,2C,2C,58), V(2E,1A,1A,34), \ + V(2D,1B,1B,36), V(B2,6E,6E,DC), V(EE,5A,5A,B4), V(FB,A0,A0,5B), \ + V(F6,52,52,A4), V(4D,3B,3B,76), V(61,D6,D6,B7), V(CE,B3,B3,7D), \ + V(7B,29,29,52), V(3E,E3,E3,DD), V(71,2F,2F,5E), V(97,84,84,13), \ + V(F5,53,53,A6), V(68,D1,D1,B9), V(00,00,00,00), V(2C,ED,ED,C1), \ + V(60,20,20,40), V(1F,FC,FC,E3), V(C8,B1,B1,79), V(ED,5B,5B,B6), \ + V(BE,6A,6A,D4), V(46,CB,CB,8D), V(D9,BE,BE,67), V(4B,39,39,72), \ + V(DE,4A,4A,94), V(D4,4C,4C,98), V(E8,58,58,B0), V(4A,CF,CF,85), \ + V(6B,D0,D0,BB), V(2A,EF,EF,C5), V(E5,AA,AA,4F), V(16,FB,FB,ED), \ + V(C5,43,43,86), V(D7,4D,4D,9A), V(55,33,33,66), V(94,85,85,11), \ + V(CF,45,45,8A), V(10,F9,F9,E9), V(06,02,02,04), V(81,7F,7F,FE), \ + V(F0,50,50,A0), V(44,3C,3C,78), V(BA,9F,9F,25), V(E3,A8,A8,4B), \ + V(F3,51,51,A2), V(FE,A3,A3,5D), V(C0,40,40,80), V(8A,8F,8F,05), \ + V(AD,92,92,3F), V(BC,9D,9D,21), V(48,38,38,70), V(04,F5,F5,F1), \ + V(DF,BC,BC,63), V(C1,B6,B6,77), V(75,DA,DA,AF), V(63,21,21,42), \ + V(30,10,10,20), V(1A,FF,FF,E5), V(0E,F3,F3,FD), V(6D,D2,D2,BF), \ + V(4C,CD,CD,81), V(14,0C,0C,18), V(35,13,13,26), V(2F,EC,EC,C3), \ + V(E1,5F,5F,BE), V(A2,97,97,35), V(CC,44,44,88), V(39,17,17,2E), \ + V(57,C4,C4,93), V(F2,A7,A7,55), V(82,7E,7E,FC), V(47,3D,3D,7A), \ + V(AC,64,64,C8), V(E7,5D,5D,BA), V(2B,19,19,32), V(95,73,73,E6), \ + V(A0,60,60,C0), V(98,81,81,19), V(D1,4F,4F,9E), V(7F,DC,DC,A3), \ + V(66,22,22,44), V(7E,2A,2A,54), V(AB,90,90,3B), V(83,88,88,0B), \ + V(CA,46,46,8C), V(29,EE,EE,C7), V(D3,B8,B8,6B), V(3C,14,14,28), \ + V(79,DE,DE,A7), V(E2,5E,5E,BC), V(1D,0B,0B,16), V(76,DB,DB,AD), \ + V(3B,E0,E0,DB), V(56,32,32,64), V(4E,3A,3A,74), V(1E,0A,0A,14), \ + V(DB,49,49,92), V(0A,06,06,0C), V(6C,24,24,48), V(E4,5C,5C,B8), \ + V(5D,C2,C2,9F), V(6E,D3,D3,BD), V(EF,AC,AC,43), V(A6,62,62,C4), \ + V(A8,91,91,39), V(A4,95,95,31), V(37,E4,E4,D3), V(8B,79,79,F2), \ + V(32,E7,E7,D5), V(43,C8,C8,8B), V(59,37,37,6E), V(B7,6D,6D,DA), \ + V(8C,8D,8D,01), V(64,D5,D5,B1), V(D2,4E,4E,9C), V(E0,A9,A9,49), \ + V(B4,6C,6C,D8), V(FA,56,56,AC), V(07,F4,F4,F3), V(25,EA,EA,CF), \ + V(AF,65,65,CA), V(8E,7A,7A,F4), V(E9,AE,AE,47), V(18,08,08,10), \ + V(D5,BA,BA,6F), V(88,78,78,F0), V(6F,25,25,4A), V(72,2E,2E,5C), \ + V(24,1C,1C,38), V(F1,A6,A6,57), V(C7,B4,B4,73), V(51,C6,C6,97), \ + V(23,E8,E8,CB), V(7C,DD,DD,A1), V(9C,74,74,E8), V(21,1F,1F,3E), \ + V(DD,4B,4B,96), V(DC,BD,BD,61), V(86,8B,8B,0D), V(85,8A,8A,0F), \ + V(90,70,70,E0), V(42,3E,3E,7C), V(C4,B5,B5,71), V(AA,66,66,CC), \ + V(D8,48,48,90), V(05,03,03,06), V(01,F6,F6,F7), V(12,0E,0E,1C), \ + V(A3,61,61,C2), V(5F,35,35,6A), V(F9,57,57,AE), V(D0,B9,B9,69), \ + V(91,86,86,17), V(58,C1,C1,99), V(27,1D,1D,3A), V(B9,9E,9E,27), \ + V(38,E1,E1,D9), V(13,F8,F8,EB), V(B3,98,98,2B), V(33,11,11,22), \ + V(BB,69,69,D2), V(70,D9,D9,A9), V(89,8E,8E,07), V(A7,94,94,33), \ + V(B6,9B,9B,2D), V(22,1E,1E,3C), V(92,87,87,15), V(20,E9,E9,C9), \ + V(49,CE,CE,87), V(FF,55,55,AA), V(78,28,28,50), V(7A,DF,DF,A5), \ + V(8F,8C,8C,03), V(F8,A1,A1,59), V(80,89,89,09), V(17,0D,0D,1A), \ + V(DA,BF,BF,65), V(31,E6,E6,D7), V(C6,42,42,84), V(B8,68,68,D0), \ + V(C3,41,41,82), V(B0,99,99,29), V(77,2D,2D,5A), V(11,0F,0F,1E), \ + V(CB,B0,B0,7B), V(FC,54,54,A8), V(D6,BB,BB,6D), V(3A,16,16,2C) + +#define V(a,b,c,d) 0x##a##b##c##d +static const uint32_t FT0[256] = { FT }; +#undef V + +#define V(a,b,c,d) 0x##b##c##d##a +static const uint32_t FT1[256] = { FT }; +#undef V + +#define V(a,b,c,d) 0x##c##d##a##b +static const uint32_t FT2[256] = { FT }; +#undef V + +#define V(a,b,c,d) 0x##d##a##b##c +static const uint32_t FT3[256] = { FT }; +#undef V + +#undef FT + +/* + * Reverse S-box + */ +static const unsigned char RSb[256] = +{ + 0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, + 0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB, + 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87, + 0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, + 0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D, + 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E, + 0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, + 0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25, + 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16, + 0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, + 0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA, + 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84, + 0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, + 0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06, + 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02, + 0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, + 0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA, + 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73, + 0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, + 0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E, + 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89, + 0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, + 0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20, + 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4, + 0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, + 0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F, + 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D, + 0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, + 0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0, + 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61, + 0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, + 0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D +}; + +/* + * Reverse tables + */ +#define RT \ +\ + V(50,A7,F4,51), V(53,65,41,7E), V(C3,A4,17,1A), V(96,5E,27,3A), \ + V(CB,6B,AB,3B), V(F1,45,9D,1F), V(AB,58,FA,AC), V(93,03,E3,4B), \ + V(55,FA,30,20), V(F6,6D,76,AD), V(91,76,CC,88), V(25,4C,02,F5), \ + V(FC,D7,E5,4F), V(D7,CB,2A,C5), V(80,44,35,26), V(8F,A3,62,B5), \ + V(49,5A,B1,DE), V(67,1B,BA,25), V(98,0E,EA,45), V(E1,C0,FE,5D), \ + V(02,75,2F,C3), V(12,F0,4C,81), V(A3,97,46,8D), V(C6,F9,D3,6B), \ + V(E7,5F,8F,03), V(95,9C,92,15), V(EB,7A,6D,BF), V(DA,59,52,95), \ + V(2D,83,BE,D4), V(D3,21,74,58), V(29,69,E0,49), V(44,C8,C9,8E), \ + V(6A,89,C2,75), V(78,79,8E,F4), V(6B,3E,58,99), V(DD,71,B9,27), \ + V(B6,4F,E1,BE), V(17,AD,88,F0), V(66,AC,20,C9), V(B4,3A,CE,7D), \ + V(18,4A,DF,63), V(82,31,1A,E5), V(60,33,51,97), V(45,7F,53,62), \ + V(E0,77,64,B1), V(84,AE,6B,BB), V(1C,A0,81,FE), V(94,2B,08,F9), \ + V(58,68,48,70), V(19,FD,45,8F), V(87,6C,DE,94), V(B7,F8,7B,52), \ + V(23,D3,73,AB), V(E2,02,4B,72), V(57,8F,1F,E3), V(2A,AB,55,66), \ + V(07,28,EB,B2), V(03,C2,B5,2F), V(9A,7B,C5,86), V(A5,08,37,D3), \ + V(F2,87,28,30), V(B2,A5,BF,23), V(BA,6A,03,02), V(5C,82,16,ED), \ + V(2B,1C,CF,8A), V(92,B4,79,A7), V(F0,F2,07,F3), V(A1,E2,69,4E), \ + V(CD,F4,DA,65), V(D5,BE,05,06), V(1F,62,34,D1), V(8A,FE,A6,C4), \ + V(9D,53,2E,34), V(A0,55,F3,A2), V(32,E1,8A,05), V(75,EB,F6,A4), \ + V(39,EC,83,0B), V(AA,EF,60,40), V(06,9F,71,5E), V(51,10,6E,BD), \ + V(F9,8A,21,3E), V(3D,06,DD,96), V(AE,05,3E,DD), V(46,BD,E6,4D), \ + V(B5,8D,54,91), V(05,5D,C4,71), V(6F,D4,06,04), V(FF,15,50,60), \ + V(24,FB,98,19), V(97,E9,BD,D6), V(CC,43,40,89), V(77,9E,D9,67), \ + V(BD,42,E8,B0), V(88,8B,89,07), V(38,5B,19,E7), V(DB,EE,C8,79), \ + V(47,0A,7C,A1), V(E9,0F,42,7C), V(C9,1E,84,F8), V(00,00,00,00), \ + V(83,86,80,09), V(48,ED,2B,32), V(AC,70,11,1E), V(4E,72,5A,6C), \ + V(FB,FF,0E,FD), V(56,38,85,0F), V(1E,D5,AE,3D), V(27,39,2D,36), \ + V(64,D9,0F,0A), V(21,A6,5C,68), V(D1,54,5B,9B), V(3A,2E,36,24), \ + V(B1,67,0A,0C), V(0F,E7,57,93), V(D2,96,EE,B4), V(9E,91,9B,1B), \ + V(4F,C5,C0,80), V(A2,20,DC,61), V(69,4B,77,5A), V(16,1A,12,1C), \ + V(0A,BA,93,E2), V(E5,2A,A0,C0), V(43,E0,22,3C), V(1D,17,1B,12), \ + V(0B,0D,09,0E), V(AD,C7,8B,F2), V(B9,A8,B6,2D), V(C8,A9,1E,14), \ + V(85,19,F1,57), V(4C,07,75,AF), V(BB,DD,99,EE), V(FD,60,7F,A3), \ + V(9F,26,01,F7), V(BC,F5,72,5C), V(C5,3B,66,44), V(34,7E,FB,5B), \ + V(76,29,43,8B), V(DC,C6,23,CB), V(68,FC,ED,B6), V(63,F1,E4,B8), \ + V(CA,DC,31,D7), V(10,85,63,42), V(40,22,97,13), V(20,11,C6,84), \ + V(7D,24,4A,85), V(F8,3D,BB,D2), V(11,32,F9,AE), V(6D,A1,29,C7), \ + V(4B,2F,9E,1D), V(F3,30,B2,DC), V(EC,52,86,0D), V(D0,E3,C1,77), \ + V(6C,16,B3,2B), V(99,B9,70,A9), V(FA,48,94,11), V(22,64,E9,47), \ + V(C4,8C,FC,A8), V(1A,3F,F0,A0), V(D8,2C,7D,56), V(EF,90,33,22), \ + V(C7,4E,49,87), V(C1,D1,38,D9), V(FE,A2,CA,8C), V(36,0B,D4,98), \ + V(CF,81,F5,A6), V(28,DE,7A,A5), V(26,8E,B7,DA), V(A4,BF,AD,3F), \ + V(E4,9D,3A,2C), V(0D,92,78,50), V(9B,CC,5F,6A), V(62,46,7E,54), \ + V(C2,13,8D,F6), V(E8,B8,D8,90), V(5E,F7,39,2E), V(F5,AF,C3,82), \ + V(BE,80,5D,9F), V(7C,93,D0,69), V(A9,2D,D5,6F), V(B3,12,25,CF), \ + V(3B,99,AC,C8), V(A7,7D,18,10), V(6E,63,9C,E8), V(7B,BB,3B,DB), \ + V(09,78,26,CD), V(F4,18,59,6E), V(01,B7,9A,EC), V(A8,9A,4F,83), \ + V(65,6E,95,E6), V(7E,E6,FF,AA), V(08,CF,BC,21), V(E6,E8,15,EF), \ + V(D9,9B,E7,BA), V(CE,36,6F,4A), V(D4,09,9F,EA), V(D6,7C,B0,29), \ + V(AF,B2,A4,31), V(31,23,3F,2A), V(30,94,A5,C6), V(C0,66,A2,35), \ + V(37,BC,4E,74), V(A6,CA,82,FC), V(B0,D0,90,E0), V(15,D8,A7,33), \ + V(4A,98,04,F1), V(F7,DA,EC,41), V(0E,50,CD,7F), V(2F,F6,91,17), \ + V(8D,D6,4D,76), V(4D,B0,EF,43), V(54,4D,AA,CC), V(DF,04,96,E4), \ + V(E3,B5,D1,9E), V(1B,88,6A,4C), V(B8,1F,2C,C1), V(7F,51,65,46), \ + V(04,EA,5E,9D), V(5D,35,8C,01), V(73,74,87,FA), V(2E,41,0B,FB), \ + V(5A,1D,67,B3), V(52,D2,DB,92), V(33,56,10,E9), V(13,47,D6,6D), \ + V(8C,61,D7,9A), V(7A,0C,A1,37), V(8E,14,F8,59), V(89,3C,13,EB), \ + V(EE,27,A9,CE), V(35,C9,61,B7), V(ED,E5,1C,E1), V(3C,B1,47,7A), \ + V(59,DF,D2,9C), V(3F,73,F2,55), V(79,CE,14,18), V(BF,37,C7,73), \ + V(EA,CD,F7,53), V(5B,AA,FD,5F), V(14,6F,3D,DF), V(86,DB,44,78), \ + V(81,F3,AF,CA), V(3E,C4,68,B9), V(2C,34,24,38), V(5F,40,A3,C2), \ + V(72,C3,1D,16), V(0C,25,E2,BC), V(8B,49,3C,28), V(41,95,0D,FF), \ + V(71,01,A8,39), V(DE,B3,0C,08), V(9C,E4,B4,D8), V(90,C1,56,64), \ + V(61,84,CB,7B), V(70,B6,32,D5), V(74,5C,6C,48), V(42,57,B8,D0) + +#define V(a,b,c,d) 0x##a##b##c##d +static const uint32_t RT0[256] = { RT }; +#undef V + +#define V(a,b,c,d) 0x##b##c##d##a +static const uint32_t RT1[256] = { RT }; +#undef V + +#define V(a,b,c,d) 0x##c##d##a##b +static const uint32_t RT2[256] = { RT }; +#undef V + +#define V(a,b,c,d) 0x##d##a##b##c +static const uint32_t RT3[256] = { RT }; +#undef V + +#undef RT + +/* + * Round constants + */ +static const uint32_t RCON[10] = +{ + 0x00000001, 0x00000002, 0x00000004, 0x00000008, + 0x00000010, 0x00000020, 0x00000040, 0x00000080, + 0x0000001B, 0x00000036 +}; + +#else /* MBEDTLS_AES_ROM_TABLES */ + +/* + * Forward S-box & tables + */ +static unsigned char FSb[256]; +static uint32_t FT0[256]; +static uint32_t FT1[256]; +static uint32_t FT2[256]; +static uint32_t FT3[256]; + +/* + * Reverse S-box & tables + */ +static unsigned char RSb[256]; +static uint32_t RT0[256]; +static uint32_t RT1[256]; +static uint32_t RT2[256]; +static uint32_t RT3[256]; + +/* + * Round constants + */ +static uint32_t RCON[10]; + +/* + * Tables generation code + */ +#define ROTL8(x) ( ( x << 8 ) & 0xFFFFFFFF ) | ( x >> 24 ) +#define XTIME(x) ( ( x << 1 ) ^ ( ( x & 0x80 ) ? 0x1B : 0x00 ) ) +#define MUL(x,y) ( ( x && y ) ? pow[(log[x]+log[y]) % 255] : 0 ) + +static int aes_init_done = 0; + +static void aes_gen_tables( void ) +{ + int i, x, y, z; + int pow[256]; + int log[256]; + + /* + * compute pow and log tables over GF(2^8) + */ + for( i = 0, x = 1; i < 256; i++ ) + { + pow[i] = x; + log[x] = i; + x = ( x ^ XTIME( x ) ) & 0xFF; + } + + /* + * calculate the round constants + */ + for( i = 0, x = 1; i < 10; i++ ) + { + RCON[i] = (uint32_t) x; + x = XTIME( x ) & 0xFF; + } + + /* + * generate the forward and reverse S-boxes + */ + FSb[0x00] = 0x63; + RSb[0x63] = 0x00; + + for( i = 1; i < 256; i++ ) + { + x = pow[255 - log[i]]; + + y = x; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF; + x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF; + x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF; + x ^= y; y = ( ( y << 1 ) | ( y >> 7 ) ) & 0xFF; + x ^= y ^ 0x63; + + FSb[i] = (unsigned char) x; + RSb[x] = (unsigned char) i; + } + + /* + * generate the forward and reverse tables + */ + for( i = 0; i < 256; i++ ) + { + x = FSb[i]; + y = XTIME( x ) & 0xFF; + z = ( y ^ x ) & 0xFF; + + FT0[i] = ( (uint32_t) y ) ^ + ( (uint32_t) x << 8 ) ^ + ( (uint32_t) x << 16 ) ^ + ( (uint32_t) z << 24 ); + + FT1[i] = ROTL8( FT0[i] ); + FT2[i] = ROTL8( FT1[i] ); + FT3[i] = ROTL8( FT2[i] ); + + x = RSb[i]; + + RT0[i] = ( (uint32_t) MUL( 0x0E, x ) ) ^ + ( (uint32_t) MUL( 0x09, x ) << 8 ) ^ + ( (uint32_t) MUL( 0x0D, x ) << 16 ) ^ + ( (uint32_t) MUL( 0x0B, x ) << 24 ); + + RT1[i] = ROTL8( RT0[i] ); + RT2[i] = ROTL8( RT1[i] ); + RT3[i] = ROTL8( RT2[i] ); + } +} + +#endif /* MBEDTLS_AES_ROM_TABLES */ + +void mbedtls_aes_init( mbedtls_aes_context *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_aes_context ) ); +} + +void mbedtls_aes_free( mbedtls_aes_context *ctx ) +{ + if( ctx == NULL ) + return; + + mbedtls_zeroize( ctx, sizeof( mbedtls_aes_context ) ); +} + +/* + * AES key schedule (encryption) + */ +#if !defined(MBEDTLS_AES_SETKEY_ENC_ALT) +int mbedtls_aes_setkey_enc( mbedtls_aes_context *ctx, const unsigned char *key, + unsigned int keybits ) +{ + unsigned int i; + uint32_t *RK; + +#if !defined(MBEDTLS_AES_ROM_TABLES) + if( aes_init_done == 0 ) + { + aes_gen_tables(); + aes_init_done = 1; + + } +#endif + + switch( keybits ) + { + case 128: ctx->nr = 10; break; + case 192: ctx->nr = 12; break; + case 256: ctx->nr = 14; break; + default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH ); + } + +#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16) + if( aes_padlock_ace == -1 ) + aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE ); + + if( aes_padlock_ace ) + ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16( ctx->buf ); + else +#endif + ctx->rk = RK = ctx->buf; + +#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64) + if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) ) + return( mbedtls_aesni_setkey_enc( (unsigned char *) ctx->rk, key, keybits ) ); +#endif + + for( i = 0; i < ( keybits >> 5 ); i++ ) + { + GET_UINT32_LE( RK[i], key, i << 2 ); + } + + switch( ctx->nr ) + { + case 10: + + for( i = 0; i < 10; i++, RK += 4 ) + { + RK[4] = RK[0] ^ RCON[i] ^ + ( (uint32_t) FSb[ ( RK[3] >> 8 ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( RK[3] >> 16 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( RK[3] >> 24 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( RK[3] ) & 0xFF ] << 24 ); + + RK[5] = RK[1] ^ RK[4]; + RK[6] = RK[2] ^ RK[5]; + RK[7] = RK[3] ^ RK[6]; + } + break; + + case 12: + + for( i = 0; i < 8; i++, RK += 6 ) + { + RK[6] = RK[0] ^ RCON[i] ^ + ( (uint32_t) FSb[ ( RK[5] >> 8 ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( RK[5] >> 16 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( RK[5] >> 24 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( RK[5] ) & 0xFF ] << 24 ); + + RK[7] = RK[1] ^ RK[6]; + RK[8] = RK[2] ^ RK[7]; + RK[9] = RK[3] ^ RK[8]; + RK[10] = RK[4] ^ RK[9]; + RK[11] = RK[5] ^ RK[10]; + } + break; + + case 14: + + for( i = 0; i < 7; i++, RK += 8 ) + { + RK[8] = RK[0] ^ RCON[i] ^ + ( (uint32_t) FSb[ ( RK[7] >> 8 ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( RK[7] >> 16 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( RK[7] >> 24 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( RK[7] ) & 0xFF ] << 24 ); + + RK[9] = RK[1] ^ RK[8]; + RK[10] = RK[2] ^ RK[9]; + RK[11] = RK[3] ^ RK[10]; + + RK[12] = RK[4] ^ + ( (uint32_t) FSb[ ( RK[11] ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( RK[11] >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( RK[11] >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( RK[11] >> 24 ) & 0xFF ] << 24 ); + + RK[13] = RK[5] ^ RK[12]; + RK[14] = RK[6] ^ RK[13]; + RK[15] = RK[7] ^ RK[14]; + } + break; + } + + return( 0 ); +} +#endif /* !MBEDTLS_AES_SETKEY_ENC_ALT */ + +/* + * AES key schedule (decryption) + */ +#if !defined(MBEDTLS_AES_SETKEY_DEC_ALT) +int mbedtls_aes_setkey_dec( mbedtls_aes_context *ctx, const unsigned char *key, + unsigned int keybits ) +{ + int i, j, ret; + mbedtls_aes_context cty; + uint32_t *RK; + uint32_t *SK; + + mbedtls_aes_init( &cty ); + +#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_PADLOCK_ALIGN16) + if( aes_padlock_ace == -1 ) + aes_padlock_ace = mbedtls_padlock_has_support( MBEDTLS_PADLOCK_ACE ); + + if( aes_padlock_ace ) + ctx->rk = RK = MBEDTLS_PADLOCK_ALIGN16( ctx->buf ); + else +#endif + ctx->rk = RK = ctx->buf; + + /* Also checks keybits */ + if( ( ret = mbedtls_aes_setkey_enc( &cty, key, keybits ) ) != 0 ) + goto exit; + + ctx->nr = cty.nr; + +#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64) + if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) ) + { + mbedtls_aesni_inverse_key( (unsigned char *) ctx->rk, + (const unsigned char *) cty.rk, ctx->nr ); + goto exit; + } +#endif + + SK = cty.rk + cty.nr * 4; + + *RK++ = *SK++; + *RK++ = *SK++; + *RK++ = *SK++; + *RK++ = *SK++; + + for( i = ctx->nr - 1, SK -= 8; i > 0; i--, SK -= 8 ) + { + for( j = 0; j < 4; j++, SK++ ) + { + *RK++ = RT0[ FSb[ ( *SK ) & 0xFF ] ] ^ + RT1[ FSb[ ( *SK >> 8 ) & 0xFF ] ] ^ + RT2[ FSb[ ( *SK >> 16 ) & 0xFF ] ] ^ + RT3[ FSb[ ( *SK >> 24 ) & 0xFF ] ]; + } + } + + *RK++ = *SK++; + *RK++ = *SK++; + *RK++ = *SK++; + *RK++ = *SK++; + +exit: + mbedtls_aes_free( &cty ); + + return( ret ); +} +#endif /* !MBEDTLS_AES_SETKEY_DEC_ALT */ + +#define AES_FROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ +{ \ + X0 = *RK++ ^ FT0[ ( Y0 ) & 0xFF ] ^ \ + FT1[ ( Y1 >> 8 ) & 0xFF ] ^ \ + FT2[ ( Y2 >> 16 ) & 0xFF ] ^ \ + FT3[ ( Y3 >> 24 ) & 0xFF ]; \ + \ + X1 = *RK++ ^ FT0[ ( Y1 ) & 0xFF ] ^ \ + FT1[ ( Y2 >> 8 ) & 0xFF ] ^ \ + FT2[ ( Y3 >> 16 ) & 0xFF ] ^ \ + FT3[ ( Y0 >> 24 ) & 0xFF ]; \ + \ + X2 = *RK++ ^ FT0[ ( Y2 ) & 0xFF ] ^ \ + FT1[ ( Y3 >> 8 ) & 0xFF ] ^ \ + FT2[ ( Y0 >> 16 ) & 0xFF ] ^ \ + FT3[ ( Y1 >> 24 ) & 0xFF ]; \ + \ + X3 = *RK++ ^ FT0[ ( Y3 ) & 0xFF ] ^ \ + FT1[ ( Y0 >> 8 ) & 0xFF ] ^ \ + FT2[ ( Y1 >> 16 ) & 0xFF ] ^ \ + FT3[ ( Y2 >> 24 ) & 0xFF ]; \ +} + +#define AES_RROUND(X0,X1,X2,X3,Y0,Y1,Y2,Y3) \ +{ \ + X0 = *RK++ ^ RT0[ ( Y0 ) & 0xFF ] ^ \ + RT1[ ( Y3 >> 8 ) & 0xFF ] ^ \ + RT2[ ( Y2 >> 16 ) & 0xFF ] ^ \ + RT3[ ( Y1 >> 24 ) & 0xFF ]; \ + \ + X1 = *RK++ ^ RT0[ ( Y1 ) & 0xFF ] ^ \ + RT1[ ( Y0 >> 8 ) & 0xFF ] ^ \ + RT2[ ( Y3 >> 16 ) & 0xFF ] ^ \ + RT3[ ( Y2 >> 24 ) & 0xFF ]; \ + \ + X2 = *RK++ ^ RT0[ ( Y2 ) & 0xFF ] ^ \ + RT1[ ( Y1 >> 8 ) & 0xFF ] ^ \ + RT2[ ( Y0 >> 16 ) & 0xFF ] ^ \ + RT3[ ( Y3 >> 24 ) & 0xFF ]; \ + \ + X3 = *RK++ ^ RT0[ ( Y3 ) & 0xFF ] ^ \ + RT1[ ( Y2 >> 8 ) & 0xFF ] ^ \ + RT2[ ( Y1 >> 16 ) & 0xFF ] ^ \ + RT3[ ( Y0 >> 24 ) & 0xFF ]; \ +} + +/* + * AES-ECB block encryption + */ +#if !defined(MBEDTLS_AES_ENCRYPT_ALT) +void mbedtls_aes_encrypt( mbedtls_aes_context *ctx, + const unsigned char input[16], + unsigned char output[16] ) +{ + int i; + uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; + + RK = ctx->rk; + + GET_UINT32_LE( X0, input, 0 ); X0 ^= *RK++; + GET_UINT32_LE( X1, input, 4 ); X1 ^= *RK++; + GET_UINT32_LE( X2, input, 8 ); X2 ^= *RK++; + GET_UINT32_LE( X3, input, 12 ); X3 ^= *RK++; + + for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- ) + { + AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); + AES_FROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); + } + + AES_FROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); + + X0 = *RK++ ^ \ + ( (uint32_t) FSb[ ( Y0 ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( Y3 >> 24 ) & 0xFF ] << 24 ); + + X1 = *RK++ ^ \ + ( (uint32_t) FSb[ ( Y1 ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( Y0 >> 24 ) & 0xFF ] << 24 ); + + X2 = *RK++ ^ \ + ( (uint32_t) FSb[ ( Y2 ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( Y1 >> 24 ) & 0xFF ] << 24 ); + + X3 = *RK++ ^ \ + ( (uint32_t) FSb[ ( Y3 ) & 0xFF ] ) ^ + ( (uint32_t) FSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) FSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) FSb[ ( Y2 >> 24 ) & 0xFF ] << 24 ); + + PUT_UINT32_LE( X0, output, 0 ); + PUT_UINT32_LE( X1, output, 4 ); + PUT_UINT32_LE( X2, output, 8 ); + PUT_UINT32_LE( X3, output, 12 ); +} +#endif /* !MBEDTLS_AES_ENCRYPT_ALT */ + +/* + * AES-ECB block decryption + */ +#if !defined(MBEDTLS_AES_DECRYPT_ALT) +void mbedtls_aes_decrypt( mbedtls_aes_context *ctx, + const unsigned char input[16], + unsigned char output[16] ) +{ + int i; + uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; + + RK = ctx->rk; + + GET_UINT32_LE( X0, input, 0 ); X0 ^= *RK++; + GET_UINT32_LE( X1, input, 4 ); X1 ^= *RK++; + GET_UINT32_LE( X2, input, 8 ); X2 ^= *RK++; + GET_UINT32_LE( X3, input, 12 ); X3 ^= *RK++; + + for( i = ( ctx->nr >> 1 ) - 1; i > 0; i-- ) + { + AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); + AES_RROUND( X0, X1, X2, X3, Y0, Y1, Y2, Y3 ); + } + + AES_RROUND( Y0, Y1, Y2, Y3, X0, X1, X2, X3 ); + + X0 = *RK++ ^ \ + ( (uint32_t) RSb[ ( Y0 ) & 0xFF ] ) ^ + ( (uint32_t) RSb[ ( Y3 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) RSb[ ( Y2 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) RSb[ ( Y1 >> 24 ) & 0xFF ] << 24 ); + + X1 = *RK++ ^ \ + ( (uint32_t) RSb[ ( Y1 ) & 0xFF ] ) ^ + ( (uint32_t) RSb[ ( Y0 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) RSb[ ( Y3 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) RSb[ ( Y2 >> 24 ) & 0xFF ] << 24 ); + + X2 = *RK++ ^ \ + ( (uint32_t) RSb[ ( Y2 ) & 0xFF ] ) ^ + ( (uint32_t) RSb[ ( Y1 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) RSb[ ( Y0 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) RSb[ ( Y3 >> 24 ) & 0xFF ] << 24 ); + + X3 = *RK++ ^ \ + ( (uint32_t) RSb[ ( Y3 ) & 0xFF ] ) ^ + ( (uint32_t) RSb[ ( Y2 >> 8 ) & 0xFF ] << 8 ) ^ + ( (uint32_t) RSb[ ( Y1 >> 16 ) & 0xFF ] << 16 ) ^ + ( (uint32_t) RSb[ ( Y0 >> 24 ) & 0xFF ] << 24 ); + + PUT_UINT32_LE( X0, output, 0 ); + PUT_UINT32_LE( X1, output, 4 ); + PUT_UINT32_LE( X2, output, 8 ); + PUT_UINT32_LE( X3, output, 12 ); +} +#endif /* !MBEDTLS_AES_DECRYPT_ALT */ + +#if !defined(MBEDTLS_AES_ALT) +/* + * AES-ECB block encryption/decryption + */ +int mbedtls_aes_crypt_ecb( mbedtls_aes_context *ctx, + int mode, + const unsigned char input[16], + unsigned char output[16] ) +{ +#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64) + if( mbedtls_aesni_has_support( MBEDTLS_AESNI_AES ) ) + return( mbedtls_aesni_crypt_ecb( ctx, mode, input, output ) ); +#endif + +#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86) + if( aes_padlock_ace ) + { + if( mbedtls_padlock_xcryptecb( ctx, mode, input, output ) == 0 ) + return( 0 ); + + // If padlock data misaligned, we just fall back to + // unaccelerated mode + // + } +#endif + + if( mode == MBEDTLS_AES_ENCRYPT ) + mbedtls_aes_encrypt( ctx, input, output ); + else + mbedtls_aes_decrypt( ctx, input, output ); + + return( 0 ); +} +#endif /* !MBEDTLS_AES_ALT */ + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +/* + * AES-CBC buffer encryption/decryption + */ +int mbedtls_aes_crypt_cbc( mbedtls_aes_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ) +{ + int i; + unsigned char temp[16]; + + if( length % 16 ) + return( MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH ); + +#if defined(MBEDTLS_PADLOCK_C) && defined(MBEDTLS_HAVE_X86) + if( aes_padlock_ace ) + { + if( mbedtls_padlock_xcryptcbc( ctx, mode, length, iv, input, output ) == 0 ) + return( 0 ); + + // If padlock data misaligned, we just fall back to + // unaccelerated mode + // + } +#endif + + if( mode == MBEDTLS_AES_DECRYPT ) + { + while( length > 0 ) + { + memcpy( temp, input, 16 ); + mbedtls_aes_crypt_ecb( ctx, mode, input, output ); + + for( i = 0; i < 16; i++ ) + output[i] = (unsigned char)( output[i] ^ iv[i] ); + + memcpy( iv, temp, 16 ); + + input += 16; + output += 16; + length -= 16; + } + } + else + { + while( length > 0 ) + { + for( i = 0; i < 16; i++ ) + output[i] = (unsigned char)( input[i] ^ iv[i] ); + + mbedtls_aes_crypt_ecb( ctx, mode, output, output ); + memcpy( iv, output, 16 ); + + input += 16; + output += 16; + length -= 16; + } + } + + return( 0 ); +} +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +/* + * AES-CFB128 buffer encryption/decryption + */ +int mbedtls_aes_crypt_cfb128( mbedtls_aes_context *ctx, + int mode, + size_t length, + size_t *iv_off, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ) +{ + int c; + size_t n = *iv_off; + + if( mode == MBEDTLS_AES_DECRYPT ) + { + while( length-- ) + { + if( n == 0 ) + mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv ); + + c = *input++; + *output++ = (unsigned char)( c ^ iv[n] ); + iv[n] = (unsigned char) c; + + n = ( n + 1 ) & 0x0F; + } + } + else + { + while( length-- ) + { + if( n == 0 ) + mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv ); + + iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ ); + + n = ( n + 1 ) & 0x0F; + } + } + + *iv_off = n; + + return( 0 ); +} + +/* + * AES-CFB8 buffer encryption/decryption + */ +int mbedtls_aes_crypt_cfb8( mbedtls_aes_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ) +{ + unsigned char c; + unsigned char ov[17]; + + while( length-- ) + { + memcpy( ov, iv, 16 ); + mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, iv, iv ); + + if( mode == MBEDTLS_AES_DECRYPT ) + ov[16] = *input; + + c = *output++ = (unsigned char)( iv[0] ^ *input++ ); + + if( mode == MBEDTLS_AES_ENCRYPT ) + ov[16] = c; + + memcpy( iv, ov + 1, 16 ); + } + + return( 0 ); +} +#endif /*MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +/* + * AES-CTR buffer encryption/decryption + */ +int mbedtls_aes_crypt_ctr( mbedtls_aes_context *ctx, + size_t length, + size_t *nc_off, + unsigned char nonce_counter[16], + unsigned char stream_block[16], + const unsigned char *input, + unsigned char *output ) +{ + int c, i; + size_t n = *nc_off; + + while( length-- ) + { + if( n == 0 ) { + mbedtls_aes_crypt_ecb( ctx, MBEDTLS_AES_ENCRYPT, nonce_counter, stream_block ); + + for( i = 16; i > 0; i-- ) + if( ++nonce_counter[i - 1] != 0 ) + break; + } + c = *input++; + *output++ = (unsigned char)( c ^ stream_block[n] ); + + n = ( n + 1 ) & 0x0F; + } + + *nc_off = n; + + return( 0 ); +} +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +#endif /* !MBEDTLS_AES_ALT */ + +#if defined(MBEDTLS_SELF_TEST) +/* + * AES test vectors from: + * + * http://csrc.nist.gov/archive/aes/rijndael/rijndael-vals.zip + */ +static const unsigned char aes_test_ecb_dec[3][16] = +{ + { 0x44, 0x41, 0x6A, 0xC2, 0xD1, 0xF5, 0x3C, 0x58, + 0x33, 0x03, 0x91, 0x7E, 0x6B, 0xE9, 0xEB, 0xE0 }, + { 0x48, 0xE3, 0x1E, 0x9E, 0x25, 0x67, 0x18, 0xF2, + 0x92, 0x29, 0x31, 0x9C, 0x19, 0xF1, 0x5B, 0xA4 }, + { 0x05, 0x8C, 0xCF, 0xFD, 0xBB, 0xCB, 0x38, 0x2D, + 0x1F, 0x6F, 0x56, 0x58, 0x5D, 0x8A, 0x4A, 0xDE } +}; + +static const unsigned char aes_test_ecb_enc[3][16] = +{ + { 0xC3, 0x4C, 0x05, 0x2C, 0xC0, 0xDA, 0x8D, 0x73, + 0x45, 0x1A, 0xFE, 0x5F, 0x03, 0xBE, 0x29, 0x7F }, + { 0xF3, 0xF6, 0x75, 0x2A, 0xE8, 0xD7, 0x83, 0x11, + 0x38, 0xF0, 0x41, 0x56, 0x06, 0x31, 0xB1, 0x14 }, + { 0x8B, 0x79, 0xEE, 0xCC, 0x93, 0xA0, 0xEE, 0x5D, + 0xFF, 0x30, 0xB4, 0xEA, 0x21, 0x63, 0x6D, 0xA4 } +}; + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static const unsigned char aes_test_cbc_dec[3][16] = +{ + { 0xFA, 0xCA, 0x37, 0xE0, 0xB0, 0xC8, 0x53, 0x73, + 0xDF, 0x70, 0x6E, 0x73, 0xF7, 0xC9, 0xAF, 0x86 }, + { 0x5D, 0xF6, 0x78, 0xDD, 0x17, 0xBA, 0x4E, 0x75, + 0xB6, 0x17, 0x68, 0xC6, 0xAD, 0xEF, 0x7C, 0x7B }, + { 0x48, 0x04, 0xE1, 0x81, 0x8F, 0xE6, 0x29, 0x75, + 0x19, 0xA3, 0xE8, 0x8C, 0x57, 0x31, 0x04, 0x13 } +}; + +static const unsigned char aes_test_cbc_enc[3][16] = +{ + { 0x8A, 0x05, 0xFC, 0x5E, 0x09, 0x5A, 0xF4, 0x84, + 0x8A, 0x08, 0xD3, 0x28, 0xD3, 0x68, 0x8E, 0x3D }, + { 0x7B, 0xD9, 0x66, 0xD5, 0x3A, 0xD8, 0xC1, 0xBB, + 0x85, 0xD2, 0xAD, 0xFA, 0xE8, 0x7B, 0xB1, 0x04 }, + { 0xFE, 0x3C, 0x53, 0x65, 0x3E, 0x2F, 0x45, 0xB5, + 0x6F, 0xCD, 0x88, 0xB2, 0xCC, 0x89, 0x8F, 0xF0 } +}; +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +/* + * AES-CFB128 test vectors from: + * + * http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf + */ +static const unsigned char aes_test_cfb128_key[3][32] = +{ + { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, + 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }, + { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52, + 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5, + 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B }, + { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, + 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, + 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, + 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 } +}; + +static const unsigned char aes_test_cfb128_iv[16] = +{ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F +}; + +static const unsigned char aes_test_cfb128_pt[64] = +{ + 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, + 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A, + 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, + 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51, + 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, + 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF, + 0xF6, 0x9F, 0x24, 0x45, 0xDF, 0x4F, 0x9B, 0x17, + 0xAD, 0x2B, 0x41, 0x7B, 0xE6, 0x6C, 0x37, 0x10 +}; + +static const unsigned char aes_test_cfb128_ct[3][64] = +{ + { 0x3B, 0x3F, 0xD9, 0x2E, 0xB7, 0x2D, 0xAD, 0x20, + 0x33, 0x34, 0x49, 0xF8, 0xE8, 0x3C, 0xFB, 0x4A, + 0xC8, 0xA6, 0x45, 0x37, 0xA0, 0xB3, 0xA9, 0x3F, + 0xCD, 0xE3, 0xCD, 0xAD, 0x9F, 0x1C, 0xE5, 0x8B, + 0x26, 0x75, 0x1F, 0x67, 0xA3, 0xCB, 0xB1, 0x40, + 0xB1, 0x80, 0x8C, 0xF1, 0x87, 0xA4, 0xF4, 0xDF, + 0xC0, 0x4B, 0x05, 0x35, 0x7C, 0x5D, 0x1C, 0x0E, + 0xEA, 0xC4, 0xC6, 0x6F, 0x9F, 0xF7, 0xF2, 0xE6 }, + { 0xCD, 0xC8, 0x0D, 0x6F, 0xDD, 0xF1, 0x8C, 0xAB, + 0x34, 0xC2, 0x59, 0x09, 0xC9, 0x9A, 0x41, 0x74, + 0x67, 0xCE, 0x7F, 0x7F, 0x81, 0x17, 0x36, 0x21, + 0x96, 0x1A, 0x2B, 0x70, 0x17, 0x1D, 0x3D, 0x7A, + 0x2E, 0x1E, 0x8A, 0x1D, 0xD5, 0x9B, 0x88, 0xB1, + 0xC8, 0xE6, 0x0F, 0xED, 0x1E, 0xFA, 0xC4, 0xC9, + 0xC0, 0x5F, 0x9F, 0x9C, 0xA9, 0x83, 0x4F, 0xA0, + 0x42, 0xAE, 0x8F, 0xBA, 0x58, 0x4B, 0x09, 0xFF }, + { 0xDC, 0x7E, 0x84, 0xBF, 0xDA, 0x79, 0x16, 0x4B, + 0x7E, 0xCD, 0x84, 0x86, 0x98, 0x5D, 0x38, 0x60, + 0x39, 0xFF, 0xED, 0x14, 0x3B, 0x28, 0xB1, 0xC8, + 0x32, 0x11, 0x3C, 0x63, 0x31, 0xE5, 0x40, 0x7B, + 0xDF, 0x10, 0x13, 0x24, 0x15, 0xE5, 0x4B, 0x92, + 0xA1, 0x3E, 0xD0, 0xA8, 0x26, 0x7A, 0xE2, 0xF9, + 0x75, 0xA3, 0x85, 0x74, 0x1A, 0xB9, 0xCE, 0xF8, + 0x20, 0x31, 0x62, 0x3D, 0x55, 0xB1, 0xE4, 0x71 } +}; +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +/* + * AES-CTR test vectors from: + * + * http://www.faqs.org/rfcs/rfc3686.html + */ + +static const unsigned char aes_test_ctr_key[3][16] = +{ + { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC, + 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E }, + { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7, + 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 }, + { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8, + 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC } +}; + +static const unsigned char aes_test_ctr_nonce_counter[3][16] = +{ + { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, + { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59, + 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 }, + { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F, + 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 } +}; + +static const unsigned char aes_test_ctr_pt[3][48] = +{ + { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62, + 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 }, + + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F }, + + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, + 0x20, 0x21, 0x22, 0x23 } +}; + +static const unsigned char aes_test_ctr_ct[3][48] = +{ + { 0xE4, 0x09, 0x5D, 0x4F, 0xB7, 0xA7, 0xB3, 0x79, + 0x2D, 0x61, 0x75, 0xA3, 0x26, 0x13, 0x11, 0xB8 }, + { 0x51, 0x04, 0xA1, 0x06, 0x16, 0x8A, 0x72, 0xD9, + 0x79, 0x0D, 0x41, 0xEE, 0x8E, 0xDA, 0xD3, 0x88, + 0xEB, 0x2E, 0x1E, 0xFC, 0x46, 0xDA, 0x57, 0xC8, + 0xFC, 0xE6, 0x30, 0xDF, 0x91, 0x41, 0xBE, 0x28 }, + { 0xC1, 0xCF, 0x48, 0xA8, 0x9F, 0x2F, 0xFD, 0xD9, + 0xCF, 0x46, 0x52, 0xE9, 0xEF, 0xDB, 0x72, 0xD7, + 0x45, 0x40, 0xA4, 0x2B, 0xDE, 0x6D, 0x78, 0x36, + 0xD5, 0x9A, 0x5C, 0xEA, 0xAE, 0xF3, 0x10, 0x53, + 0x25, 0xB2, 0x07, 0x2F } +}; + +static const int aes_test_ctr_len[3] = + { 16, 32, 36 }; +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +/* + * Checkup routine + */ +int mbedtls_aes_self_test( int verbose ) +{ + int ret = 0, i, j, u, v; + unsigned char key[32]; + unsigned char buf[64]; +#if defined(MBEDTLS_CIPHER_MODE_CBC) || defined(MBEDTLS_CIPHER_MODE_CFB) + unsigned char iv[16]; +#endif +#if defined(MBEDTLS_CIPHER_MODE_CBC) + unsigned char prv[16]; +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) || defined(MBEDTLS_CIPHER_MODE_CFB) + size_t offset; +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + int len; + unsigned char nonce_counter[16]; + unsigned char stream_block[16]; +#endif + mbedtls_aes_context ctx; + + memset( key, 0, 32 ); + mbedtls_aes_init( &ctx ); + + /* + * ECB mode + */ + for( i = 0; i < 6; i++ ) + { + u = i >> 1; + v = i & 1; + + if( verbose != 0 ) + mbedtls_printf( " AES-ECB-%3d (%s): ", 128 + u * 64, + ( v == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); + + memset( buf, 0, 16 ); + + if( v == MBEDTLS_AES_DECRYPT ) + { + mbedtls_aes_setkey_dec( &ctx, key, 128 + u * 64 ); + + for( j = 0; j < 10000; j++ ) + mbedtls_aes_crypt_ecb( &ctx, v, buf, buf ); + + if( memcmp( buf, aes_test_ecb_dec[u], 16 ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + ret = 1; + goto exit; + } + } + else + { + mbedtls_aes_setkey_enc( &ctx, key, 128 + u * 64 ); + + for( j = 0; j < 10000; j++ ) + mbedtls_aes_crypt_ecb( &ctx, v, buf, buf ); + + if( memcmp( buf, aes_test_ecb_enc[u], 16 ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + ret = 1; + goto exit; + } + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + +#if defined(MBEDTLS_CIPHER_MODE_CBC) + /* + * CBC mode + */ + for( i = 0; i < 6; i++ ) + { + u = i >> 1; + v = i & 1; + + if( verbose != 0 ) + mbedtls_printf( " AES-CBC-%3d (%s): ", 128 + u * 64, + ( v == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); + + memset( iv , 0, 16 ); + memset( prv, 0, 16 ); + memset( buf, 0, 16 ); + + if( v == MBEDTLS_AES_DECRYPT ) + { + mbedtls_aes_setkey_dec( &ctx, key, 128 + u * 64 ); + + for( j = 0; j < 10000; j++ ) + mbedtls_aes_crypt_cbc( &ctx, v, 16, iv, buf, buf ); + + if( memcmp( buf, aes_test_cbc_dec[u], 16 ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + ret = 1; + goto exit; + } + } + else + { + mbedtls_aes_setkey_enc( &ctx, key, 128 + u * 64 ); + + for( j = 0; j < 10000; j++ ) + { + unsigned char tmp[16]; + + mbedtls_aes_crypt_cbc( &ctx, v, 16, iv, buf, buf ); + + memcpy( tmp, prv, 16 ); + memcpy( prv, buf, 16 ); + memcpy( buf, tmp, 16 ); + } + + if( memcmp( prv, aes_test_cbc_enc[u], 16 ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + ret = 1; + goto exit; + } + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) + /* + * CFB128 mode + */ + for( i = 0; i < 6; i++ ) + { + u = i >> 1; + v = i & 1; + + if( verbose != 0 ) + mbedtls_printf( " AES-CFB128-%3d (%s): ", 128 + u * 64, + ( v == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); + + memcpy( iv, aes_test_cfb128_iv, 16 ); + memcpy( key, aes_test_cfb128_key[u], 16 + u * 8 ); + + offset = 0; + mbedtls_aes_setkey_enc( &ctx, key, 128 + u * 64 ); + + if( v == MBEDTLS_AES_DECRYPT ) + { + memcpy( buf, aes_test_cfb128_ct[u], 64 ); + mbedtls_aes_crypt_cfb128( &ctx, v, 64, &offset, iv, buf, buf ); + + if( memcmp( buf, aes_test_cfb128_pt, 64 ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + ret = 1; + goto exit; + } + } + else + { + memcpy( buf, aes_test_cfb128_pt, 64 ); + mbedtls_aes_crypt_cfb128( &ctx, v, 64, &offset, iv, buf, buf ); + + if( memcmp( buf, aes_test_cfb128_ct[u], 64 ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + ret = 1; + goto exit; + } + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) + /* + * CTR mode + */ + for( i = 0; i < 6; i++ ) + { + u = i >> 1; + v = i & 1; + + if( verbose != 0 ) + mbedtls_printf( " AES-CTR-128 (%s): ", + ( v == MBEDTLS_AES_DECRYPT ) ? "dec" : "enc" ); + + memcpy( nonce_counter, aes_test_ctr_nonce_counter[u], 16 ); + memcpy( key, aes_test_ctr_key[u], 16 ); + + offset = 0; + mbedtls_aes_setkey_enc( &ctx, key, 128 ); + + if( v == MBEDTLS_AES_DECRYPT ) + { + len = aes_test_ctr_len[u]; + memcpy( buf, aes_test_ctr_ct[u], len ); + + mbedtls_aes_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block, + buf, buf ); + + if( memcmp( buf, aes_test_ctr_pt[u], len ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + ret = 1; + goto exit; + } + } + else + { + len = aes_test_ctr_len[u]; + memcpy( buf, aes_test_ctr_pt[u], len ); + + mbedtls_aes_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block, + buf, buf ); + + if( memcmp( buf, aes_test_ctr_ct[u], len ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + ret = 1; + goto exit; + } + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + + ret = 0; + +exit: + mbedtls_aes_free( &ctx ); + + return( ret ); +} + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_AES_C */ diff --git a/security/mbedtls/src/aesni.c b/security/mbedtls/src/aesni.c new file mode 100644 index 0000000000..1ca3c3ef5b --- /dev/null +++ b/security/mbedtls/src/aesni.c @@ -0,0 +1,464 @@ +/* + * AES-NI support functions + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +/* + * [AES-WP] http://software.intel.com/en-us/articles/intel-advanced-encryption-standard-aes-instructions-set + * [CLMUL-WP] http://software.intel.com/en-us/articles/intel-carry-less-multiplication-instruction-and-its-usage-for-computing-the-gcm-mode/ + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_AESNI_C) + +#include "mbedtls/aesni.h" + +#include + +#ifndef asm +#define asm __asm +#endif + +#if defined(MBEDTLS_HAVE_X86_64) + +/* + * AES-NI support detection routine + */ +int mbedtls_aesni_has_support( unsigned int what ) +{ + static int done = 0; + static unsigned int c = 0; + + if( ! done ) + { + asm( "movl $1, %%eax \n\t" + "cpuid \n\t" + : "=c" (c) + : + : "eax", "ebx", "edx" ); + done = 1; + } + + return( ( c & what ) != 0 ); +} + +/* + * Binutils needs to be at least 2.19 to support AES-NI instructions. + * Unfortunately, a lot of users have a lower version now (2014-04). + * Emit bytecode directly in order to support "old" version of gas. + * + * Opcodes from the Intel architecture reference manual, vol. 3. + * We always use registers, so we don't need prefixes for memory operands. + * Operand macros are in gas order (src, dst) as opposed to Intel order + * (dst, src) in order to blend better into the surrounding assembly code. + */ +#define AESDEC ".byte 0x66,0x0F,0x38,0xDE," +#define AESDECLAST ".byte 0x66,0x0F,0x38,0xDF," +#define AESENC ".byte 0x66,0x0F,0x38,0xDC," +#define AESENCLAST ".byte 0x66,0x0F,0x38,0xDD," +#define AESIMC ".byte 0x66,0x0F,0x38,0xDB," +#define AESKEYGENA ".byte 0x66,0x0F,0x3A,0xDF," +#define PCLMULQDQ ".byte 0x66,0x0F,0x3A,0x44," + +#define xmm0_xmm0 "0xC0" +#define xmm0_xmm1 "0xC8" +#define xmm0_xmm2 "0xD0" +#define xmm0_xmm3 "0xD8" +#define xmm0_xmm4 "0xE0" +#define xmm1_xmm0 "0xC1" +#define xmm1_xmm2 "0xD1" + +/* + * AES-NI AES-ECB block en(de)cryption + */ +int mbedtls_aesni_crypt_ecb( mbedtls_aes_context *ctx, + int mode, + const unsigned char input[16], + unsigned char output[16] ) +{ + asm( "movdqu (%3), %%xmm0 \n\t" // load input + "movdqu (%1), %%xmm1 \n\t" // load round key 0 + "pxor %%xmm1, %%xmm0 \n\t" // round 0 + "add $16, %1 \n\t" // point to next round key + "subl $1, %0 \n\t" // normal rounds = nr - 1 + "test %2, %2 \n\t" // mode? + "jz 2f \n\t" // 0 = decrypt + + "1: \n\t" // encryption loop + "movdqu (%1), %%xmm1 \n\t" // load round key + AESENC xmm1_xmm0 "\n\t" // do round + "add $16, %1 \n\t" // point to next round key + "subl $1, %0 \n\t" // loop + "jnz 1b \n\t" + "movdqu (%1), %%xmm1 \n\t" // load round key + AESENCLAST xmm1_xmm0 "\n\t" // last round + "jmp 3f \n\t" + + "2: \n\t" // decryption loop + "movdqu (%1), %%xmm1 \n\t" + AESDEC xmm1_xmm0 "\n\t" // do round + "add $16, %1 \n\t" + "subl $1, %0 \n\t" + "jnz 2b \n\t" + "movdqu (%1), %%xmm1 \n\t" // load round key + AESDECLAST xmm1_xmm0 "\n\t" // last round + + "3: \n\t" + "movdqu %%xmm0, (%4) \n\t" // export output + : + : "r" (ctx->nr), "r" (ctx->rk), "r" (mode), "r" (input), "r" (output) + : "memory", "cc", "xmm0", "xmm1" ); + + + return( 0 ); +} + +/* + * GCM multiplication: c = a times b in GF(2^128) + * Based on [CLMUL-WP] algorithms 1 (with equation 27) and 5. + */ +void mbedtls_aesni_gcm_mult( unsigned char c[16], + const unsigned char a[16], + const unsigned char b[16] ) +{ + unsigned char aa[16], bb[16], cc[16]; + size_t i; + + /* The inputs are in big-endian order, so byte-reverse them */ + for( i = 0; i < 16; i++ ) + { + aa[i] = a[15 - i]; + bb[i] = b[15 - i]; + } + + asm( "movdqu (%0), %%xmm0 \n\t" // a1:a0 + "movdqu (%1), %%xmm1 \n\t" // b1:b0 + + /* + * Caryless multiplication xmm2:xmm1 = xmm0 * xmm1 + * using [CLMUL-WP] algorithm 1 (p. 13). + */ + "movdqa %%xmm1, %%xmm2 \n\t" // copy of b1:b0 + "movdqa %%xmm1, %%xmm3 \n\t" // same + "movdqa %%xmm1, %%xmm4 \n\t" // same + PCLMULQDQ xmm0_xmm1 ",0x00 \n\t" // a0*b0 = c1:c0 + PCLMULQDQ xmm0_xmm2 ",0x11 \n\t" // a1*b1 = d1:d0 + PCLMULQDQ xmm0_xmm3 ",0x10 \n\t" // a0*b1 = e1:e0 + PCLMULQDQ xmm0_xmm4 ",0x01 \n\t" // a1*b0 = f1:f0 + "pxor %%xmm3, %%xmm4 \n\t" // e1+f1:e0+f0 + "movdqa %%xmm4, %%xmm3 \n\t" // same + "psrldq $8, %%xmm4 \n\t" // 0:e1+f1 + "pslldq $8, %%xmm3 \n\t" // e0+f0:0 + "pxor %%xmm4, %%xmm2 \n\t" // d1:d0+e1+f1 + "pxor %%xmm3, %%xmm1 \n\t" // c1+e0+f1:c0 + + /* + * Now shift the result one bit to the left, + * taking advantage of [CLMUL-WP] eq 27 (p. 20) + */ + "movdqa %%xmm1, %%xmm3 \n\t" // r1:r0 + "movdqa %%xmm2, %%xmm4 \n\t" // r3:r2 + "psllq $1, %%xmm1 \n\t" // r1<<1:r0<<1 + "psllq $1, %%xmm2 \n\t" // r3<<1:r2<<1 + "psrlq $63, %%xmm3 \n\t" // r1>>63:r0>>63 + "psrlq $63, %%xmm4 \n\t" // r3>>63:r2>>63 + "movdqa %%xmm3, %%xmm5 \n\t" // r1>>63:r0>>63 + "pslldq $8, %%xmm3 \n\t" // r0>>63:0 + "pslldq $8, %%xmm4 \n\t" // r2>>63:0 + "psrldq $8, %%xmm5 \n\t" // 0:r1>>63 + "por %%xmm3, %%xmm1 \n\t" // r1<<1|r0>>63:r0<<1 + "por %%xmm4, %%xmm2 \n\t" // r3<<1|r2>>62:r2<<1 + "por %%xmm5, %%xmm2 \n\t" // r3<<1|r2>>62:r2<<1|r1>>63 + + /* + * Now reduce modulo the GCM polynomial x^128 + x^7 + x^2 + x + 1 + * using [CLMUL-WP] algorithm 5 (p. 20). + * Currently xmm2:xmm1 holds x3:x2:x1:x0 (already shifted). + */ + /* Step 2 (1) */ + "movdqa %%xmm1, %%xmm3 \n\t" // x1:x0 + "movdqa %%xmm1, %%xmm4 \n\t" // same + "movdqa %%xmm1, %%xmm5 \n\t" // same + "psllq $63, %%xmm3 \n\t" // x1<<63:x0<<63 = stuff:a + "psllq $62, %%xmm4 \n\t" // x1<<62:x0<<62 = stuff:b + "psllq $57, %%xmm5 \n\t" // x1<<57:x0<<57 = stuff:c + + /* Step 2 (2) */ + "pxor %%xmm4, %%xmm3 \n\t" // stuff:a+b + "pxor %%xmm5, %%xmm3 \n\t" // stuff:a+b+c + "pslldq $8, %%xmm3 \n\t" // a+b+c:0 + "pxor %%xmm3, %%xmm1 \n\t" // x1+a+b+c:x0 = d:x0 + + /* Steps 3 and 4 */ + "movdqa %%xmm1,%%xmm0 \n\t" // d:x0 + "movdqa %%xmm1,%%xmm4 \n\t" // same + "movdqa %%xmm1,%%xmm5 \n\t" // same + "psrlq $1, %%xmm0 \n\t" // e1:x0>>1 = e1:e0' + "psrlq $2, %%xmm4 \n\t" // f1:x0>>2 = f1:f0' + "psrlq $7, %%xmm5 \n\t" // g1:x0>>7 = g1:g0' + "pxor %%xmm4, %%xmm0 \n\t" // e1+f1:e0'+f0' + "pxor %%xmm5, %%xmm0 \n\t" // e1+f1+g1:e0'+f0'+g0' + // e0'+f0'+g0' is almost e0+f0+g0, ex\tcept for some missing + // bits carried from d. Now get those\t bits back in. + "movdqa %%xmm1,%%xmm3 \n\t" // d:x0 + "movdqa %%xmm1,%%xmm4 \n\t" // same + "movdqa %%xmm1,%%xmm5 \n\t" // same + "psllq $63, %%xmm3 \n\t" // d<<63:stuff + "psllq $62, %%xmm4 \n\t" // d<<62:stuff + "psllq $57, %%xmm5 \n\t" // d<<57:stuff + "pxor %%xmm4, %%xmm3 \n\t" // d<<63+d<<62:stuff + "pxor %%xmm5, %%xmm3 \n\t" // missing bits of d:stuff + "psrldq $8, %%xmm3 \n\t" // 0:missing bits of d + "pxor %%xmm3, %%xmm0 \n\t" // e1+f1+g1:e0+f0+g0 + "pxor %%xmm1, %%xmm0 \n\t" // h1:h0 + "pxor %%xmm2, %%xmm0 \n\t" // x3+h1:x2+h0 + + "movdqu %%xmm0, (%2) \n\t" // done + : + : "r" (aa), "r" (bb), "r" (cc) + : "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5" ); + + /* Now byte-reverse the outputs */ + for( i = 0; i < 16; i++ ) + c[i] = cc[15 - i]; + + return; +} + +/* + * Compute decryption round keys from encryption round keys + */ +void mbedtls_aesni_inverse_key( unsigned char *invkey, + const unsigned char *fwdkey, int nr ) +{ + unsigned char *ik = invkey; + const unsigned char *fk = fwdkey + 16 * nr; + + memcpy( ik, fk, 16 ); + + for( fk -= 16, ik += 16; fk > fwdkey; fk -= 16, ik += 16 ) + asm( "movdqu (%0), %%xmm0 \n\t" + AESIMC xmm0_xmm0 "\n\t" + "movdqu %%xmm0, (%1) \n\t" + : + : "r" (fk), "r" (ik) + : "memory", "xmm0" ); + + memcpy( ik, fk, 16 ); +} + +/* + * Key expansion, 128-bit case + */ +static void aesni_setkey_enc_128( unsigned char *rk, + const unsigned char *key ) +{ + asm( "movdqu (%1), %%xmm0 \n\t" // copy the original key + "movdqu %%xmm0, (%0) \n\t" // as round key 0 + "jmp 2f \n\t" // skip auxiliary routine + + /* + * Finish generating the next round key. + * + * On entry xmm0 is r3:r2:r1:r0 and xmm1 is X:stuff:stuff:stuff + * with X = rot( sub( r3 ) ) ^ RCON. + * + * On exit, xmm0 is r7:r6:r5:r4 + * with r4 = X + r0, r5 = r4 + r1, r6 = r5 + r2, r7 = r6 + r3 + * and those are written to the round key buffer. + */ + "1: \n\t" + "pshufd $0xff, %%xmm1, %%xmm1 \n\t" // X:X:X:X + "pxor %%xmm0, %%xmm1 \n\t" // X+r3:X+r2:X+r1:r4 + "pslldq $4, %%xmm0 \n\t" // r2:r1:r0:0 + "pxor %%xmm0, %%xmm1 \n\t" // X+r3+r2:X+r2+r1:r5:r4 + "pslldq $4, %%xmm0 \n\t" // etc + "pxor %%xmm0, %%xmm1 \n\t" + "pslldq $4, %%xmm0 \n\t" + "pxor %%xmm1, %%xmm0 \n\t" // update xmm0 for next time! + "add $16, %0 \n\t" // point to next round key + "movdqu %%xmm0, (%0) \n\t" // write it + "ret \n\t" + + /* Main "loop" */ + "2: \n\t" + AESKEYGENA xmm0_xmm1 ",0x01 \n\tcall 1b \n\t" + AESKEYGENA xmm0_xmm1 ",0x02 \n\tcall 1b \n\t" + AESKEYGENA xmm0_xmm1 ",0x04 \n\tcall 1b \n\t" + AESKEYGENA xmm0_xmm1 ",0x08 \n\tcall 1b \n\t" + AESKEYGENA xmm0_xmm1 ",0x10 \n\tcall 1b \n\t" + AESKEYGENA xmm0_xmm1 ",0x20 \n\tcall 1b \n\t" + AESKEYGENA xmm0_xmm1 ",0x40 \n\tcall 1b \n\t" + AESKEYGENA xmm0_xmm1 ",0x80 \n\tcall 1b \n\t" + AESKEYGENA xmm0_xmm1 ",0x1B \n\tcall 1b \n\t" + AESKEYGENA xmm0_xmm1 ",0x36 \n\tcall 1b \n\t" + : + : "r" (rk), "r" (key) + : "memory", "cc", "0" ); +} + +/* + * Key expansion, 192-bit case + */ +static void aesni_setkey_enc_192( unsigned char *rk, + const unsigned char *key ) +{ + asm( "movdqu (%1), %%xmm0 \n\t" // copy original round key + "movdqu %%xmm0, (%0) \n\t" + "add $16, %0 \n\t" + "movq 16(%1), %%xmm1 \n\t" + "movq %%xmm1, (%0) \n\t" + "add $8, %0 \n\t" + "jmp 2f \n\t" // skip auxiliary routine + + /* + * Finish generating the next 6 quarter-keys. + * + * On entry xmm0 is r3:r2:r1:r0, xmm1 is stuff:stuff:r5:r4 + * and xmm2 is stuff:stuff:X:stuff with X = rot( sub( r3 ) ) ^ RCON. + * + * On exit, xmm0 is r9:r8:r7:r6 and xmm1 is stuff:stuff:r11:r10 + * and those are written to the round key buffer. + */ + "1: \n\t" + "pshufd $0x55, %%xmm2, %%xmm2 \n\t" // X:X:X:X + "pxor %%xmm0, %%xmm2 \n\t" // X+r3:X+r2:X+r1:r4 + "pslldq $4, %%xmm0 \n\t" // etc + "pxor %%xmm0, %%xmm2 \n\t" + "pslldq $4, %%xmm0 \n\t" + "pxor %%xmm0, %%xmm2 \n\t" + "pslldq $4, %%xmm0 \n\t" + "pxor %%xmm2, %%xmm0 \n\t" // update xmm0 = r9:r8:r7:r6 + "movdqu %%xmm0, (%0) \n\t" + "add $16, %0 \n\t" + "pshufd $0xff, %%xmm0, %%xmm2 \n\t" // r9:r9:r9:r9 + "pxor %%xmm1, %%xmm2 \n\t" // stuff:stuff:r9+r5:r10 + "pslldq $4, %%xmm1 \n\t" // r2:r1:r0:0 + "pxor %%xmm2, %%xmm1 \n\t" // xmm1 = stuff:stuff:r11:r10 + "movq %%xmm1, (%0) \n\t" + "add $8, %0 \n\t" + "ret \n\t" + + "2: \n\t" + AESKEYGENA xmm1_xmm2 ",0x01 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x02 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x04 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x08 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x10 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x20 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x40 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x80 \n\tcall 1b \n\t" + + : + : "r" (rk), "r" (key) + : "memory", "cc", "0" ); +} + +/* + * Key expansion, 256-bit case + */ +static void aesni_setkey_enc_256( unsigned char *rk, + const unsigned char *key ) +{ + asm( "movdqu (%1), %%xmm0 \n\t" + "movdqu %%xmm0, (%0) \n\t" + "add $16, %0 \n\t" + "movdqu 16(%1), %%xmm1 \n\t" + "movdqu %%xmm1, (%0) \n\t" + "jmp 2f \n\t" // skip auxiliary routine + + /* + * Finish generating the next two round keys. + * + * On entry xmm0 is r3:r2:r1:r0, xmm1 is r7:r6:r5:r4 and + * xmm2 is X:stuff:stuff:stuff with X = rot( sub( r7 )) ^ RCON + * + * On exit, xmm0 is r11:r10:r9:r8 and xmm1 is r15:r14:r13:r12 + * and those have been written to the output buffer. + */ + "1: \n\t" + "pshufd $0xff, %%xmm2, %%xmm2 \n\t" + "pxor %%xmm0, %%xmm2 \n\t" + "pslldq $4, %%xmm0 \n\t" + "pxor %%xmm0, %%xmm2 \n\t" + "pslldq $4, %%xmm0 \n\t" + "pxor %%xmm0, %%xmm2 \n\t" + "pslldq $4, %%xmm0 \n\t" + "pxor %%xmm2, %%xmm0 \n\t" + "add $16, %0 \n\t" + "movdqu %%xmm0, (%0) \n\t" + + /* Set xmm2 to stuff:Y:stuff:stuff with Y = subword( r11 ) + * and proceed to generate next round key from there */ + AESKEYGENA xmm0_xmm2 ",0x00 \n\t" + "pshufd $0xaa, %%xmm2, %%xmm2 \n\t" + "pxor %%xmm1, %%xmm2 \n\t" + "pslldq $4, %%xmm1 \n\t" + "pxor %%xmm1, %%xmm2 \n\t" + "pslldq $4, %%xmm1 \n\t" + "pxor %%xmm1, %%xmm2 \n\t" + "pslldq $4, %%xmm1 \n\t" + "pxor %%xmm2, %%xmm1 \n\t" + "add $16, %0 \n\t" + "movdqu %%xmm1, (%0) \n\t" + "ret \n\t" + + /* + * Main "loop" - Generating one more key than necessary, + * see definition of mbedtls_aes_context.buf + */ + "2: \n\t" + AESKEYGENA xmm1_xmm2 ",0x01 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x02 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x04 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x08 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x10 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x20 \n\tcall 1b \n\t" + AESKEYGENA xmm1_xmm2 ",0x40 \n\tcall 1b \n\t" + : + : "r" (rk), "r" (key) + : "memory", "cc", "0" ); +} + +/* + * Key expansion, wrapper + */ +int mbedtls_aesni_setkey_enc( unsigned char *rk, + const unsigned char *key, + size_t bits ) +{ + switch( bits ) + { + case 128: aesni_setkey_enc_128( rk, key ); break; + case 192: aesni_setkey_enc_192( rk, key ); break; + case 256: aesni_setkey_enc_256( rk, key ); break; + default : return( MBEDTLS_ERR_AES_INVALID_KEY_LENGTH ); + } + + return( 0 ); +} + +#endif /* MBEDTLS_HAVE_X86_64 */ + +#endif /* MBEDTLS_AESNI_C */ diff --git a/security/mbedtls/src/arc4.c b/security/mbedtls/src/arc4.c new file mode 100644 index 0000000000..05b33d3fdb --- /dev/null +++ b/security/mbedtls/src/arc4.c @@ -0,0 +1,205 @@ +/* + * An implementation of the ARCFOUR algorithm + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +/* + * The ARCFOUR algorithm was publicly disclosed on 94/09. + * + * http://groups.google.com/group/sci.crypt/msg/10a300c9d21afca0 + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_ARC4_C) + +#include "mbedtls/arc4.h" + +#include + +#if defined(MBEDTLS_SELF_TEST) +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_printf printf +#endif /* MBEDTLS_PLATFORM_C */ +#endif /* MBEDTLS_SELF_TEST */ + +#if !defined(MBEDTLS_ARC4_ALT) + +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0; +} + +void mbedtls_arc4_init( mbedtls_arc4_context *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_arc4_context ) ); +} + +void mbedtls_arc4_free( mbedtls_arc4_context *ctx ) +{ + if( ctx == NULL ) + return; + + mbedtls_zeroize( ctx, sizeof( mbedtls_arc4_context ) ); +} + +/* + * ARC4 key schedule + */ +void mbedtls_arc4_setup( mbedtls_arc4_context *ctx, const unsigned char *key, + unsigned int keylen ) +{ + int i, j, a; + unsigned int k; + unsigned char *m; + + ctx->x = 0; + ctx->y = 0; + m = ctx->m; + + for( i = 0; i < 256; i++ ) + m[i] = (unsigned char) i; + + j = k = 0; + + for( i = 0; i < 256; i++, k++ ) + { + if( k >= keylen ) k = 0; + + a = m[i]; + j = ( j + a + key[k] ) & 0xFF; + m[i] = m[j]; + m[j] = (unsigned char) a; + } +} + +/* + * ARC4 cipher function + */ +int mbedtls_arc4_crypt( mbedtls_arc4_context *ctx, size_t length, const unsigned char *input, + unsigned char *output ) +{ + int x, y, a, b; + size_t i; + unsigned char *m; + + x = ctx->x; + y = ctx->y; + m = ctx->m; + + for( i = 0; i < length; i++ ) + { + x = ( x + 1 ) & 0xFF; a = m[x]; + y = ( y + a ) & 0xFF; b = m[y]; + + m[x] = (unsigned char) b; + m[y] = (unsigned char) a; + + output[i] = (unsigned char) + ( input[i] ^ m[(unsigned char)( a + b )] ); + } + + ctx->x = x; + ctx->y = y; + + return( 0 ); +} + +#endif /* !MBEDTLS_ARC4_ALT */ + +#if defined(MBEDTLS_SELF_TEST) +/* + * ARC4 tests vectors as posted by Eric Rescorla in sep. 1994: + * + * http://groups.google.com/group/comp.security.misc/msg/10a300c9d21afca0 + */ +static const unsigned char arc4_test_key[3][8] = +{ + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }, + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } +}; + +static const unsigned char arc4_test_pt[3][8] = +{ + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } +}; + +static const unsigned char arc4_test_ct[3][8] = +{ + { 0x75, 0xB7, 0x87, 0x80, 0x99, 0xE0, 0xC5, 0x96 }, + { 0x74, 0x94, 0xC2, 0xE7, 0x10, 0x4B, 0x08, 0x79 }, + { 0xDE, 0x18, 0x89, 0x41, 0xA3, 0x37, 0x5D, 0x3A } +}; + +/* + * Checkup routine + */ +int mbedtls_arc4_self_test( int verbose ) +{ + int i, ret = 0; + unsigned char ibuf[8]; + unsigned char obuf[8]; + mbedtls_arc4_context ctx; + + mbedtls_arc4_init( &ctx ); + + for( i = 0; i < 3; i++ ) + { + if( verbose != 0 ) + mbedtls_printf( " ARC4 test #%d: ", i + 1 ); + + memcpy( ibuf, arc4_test_pt[i], 8 ); + + mbedtls_arc4_setup( &ctx, arc4_test_key[i], 8 ); + mbedtls_arc4_crypt( &ctx, 8, ibuf, obuf ); + + if( memcmp( obuf, arc4_test_ct[i], 8 ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + ret = 1; + goto exit; + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + +exit: + mbedtls_arc4_free( &ctx ); + + return( ret ); +} + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_ARC4_C */ diff --git a/security/mbedtls/src/asn1parse.c b/security/mbedtls/src/asn1parse.c new file mode 100644 index 0000000000..4dd65c03c0 --- /dev/null +++ b/security/mbedtls/src/asn1parse.c @@ -0,0 +1,393 @@ +/* + * Generic ASN.1 parsing + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_ASN1_PARSE_C) + +#include "mbedtls/asn1.h" + +#include + +#if defined(MBEDTLS_BIGNUM_C) +#include "mbedtls/bignum.h" +#endif + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_calloc calloc +#define mbedtls_free free +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0; +} + +/* + * ASN.1 DER decoding routines + */ +int mbedtls_asn1_get_len( unsigned char **p, + const unsigned char *end, + size_t *len ) +{ + if( ( end - *p ) < 1 ) + return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); + + if( ( **p & 0x80 ) == 0 ) + *len = *(*p)++; + else + { + switch( **p & 0x7F ) + { + case 1: + if( ( end - *p ) < 2 ) + return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); + + *len = (*p)[1]; + (*p) += 2; + break; + + case 2: + if( ( end - *p ) < 3 ) + return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); + + *len = ( (size_t)(*p)[1] << 8 ) | (*p)[2]; + (*p) += 3; + break; + + case 3: + if( ( end - *p ) < 4 ) + return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); + + *len = ( (size_t)(*p)[1] << 16 ) | + ( (size_t)(*p)[2] << 8 ) | (*p)[3]; + (*p) += 4; + break; + + case 4: + if( ( end - *p ) < 5 ) + return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); + + *len = ( (size_t)(*p)[1] << 24 ) | ( (size_t)(*p)[2] << 16 ) | + ( (size_t)(*p)[3] << 8 ) | (*p)[4]; + (*p) += 5; + break; + + default: + return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); + } + } + + if( *len > (size_t) ( end - *p ) ) + return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); + + return( 0 ); +} + +int mbedtls_asn1_get_tag( unsigned char **p, + const unsigned char *end, + size_t *len, int tag ) +{ + if( ( end - *p ) < 1 ) + return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); + + if( **p != tag ) + return( MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); + + (*p)++; + + return( mbedtls_asn1_get_len( p, end, len ) ); +} + +int mbedtls_asn1_get_bool( unsigned char **p, + const unsigned char *end, + int *val ) +{ + int ret; + size_t len; + + if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_BOOLEAN ) ) != 0 ) + return( ret ); + + if( len != 1 ) + return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); + + *val = ( **p != 0 ) ? 1 : 0; + (*p)++; + + return( 0 ); +} + +int mbedtls_asn1_get_int( unsigned char **p, + const unsigned char *end, + int *val ) +{ + int ret; + size_t len; + + if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 ) + return( ret ); + + if( len == 0 || len > sizeof( int ) || ( **p & 0x80 ) != 0 ) + return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); + + *val = 0; + + while( len-- > 0 ) + { + *val = ( *val << 8 ) | **p; + (*p)++; + } + + return( 0 ); +} + +#if defined(MBEDTLS_BIGNUM_C) +int mbedtls_asn1_get_mpi( unsigned char **p, + const unsigned char *end, + mbedtls_mpi *X ) +{ + int ret; + size_t len; + + if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 ) + return( ret ); + + ret = mbedtls_mpi_read_binary( X, *p, len ); + + *p += len; + + return( ret ); +} +#endif /* MBEDTLS_BIGNUM_C */ + +int mbedtls_asn1_get_bitstring( unsigned char **p, const unsigned char *end, + mbedtls_asn1_bitstring *bs) +{ + int ret; + + /* Certificate type is a single byte bitstring */ + if( ( ret = mbedtls_asn1_get_tag( p, end, &bs->len, MBEDTLS_ASN1_BIT_STRING ) ) != 0 ) + return( ret ); + + /* Check length, subtract one for actual bit string length */ + if( bs->len < 1 ) + return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); + bs->len -= 1; + + /* Get number of unused bits, ensure unused bits <= 7 */ + bs->unused_bits = **p; + if( bs->unused_bits > 7 ) + return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); + (*p)++; + + /* Get actual bitstring */ + bs->p = *p; + *p += bs->len; + + if( *p != end ) + return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + + return( 0 ); +} + +/* + * Get a bit string without unused bits + */ +int mbedtls_asn1_get_bitstring_null( unsigned char **p, const unsigned char *end, + size_t *len ) +{ + int ret; + + if( ( ret = mbedtls_asn1_get_tag( p, end, len, MBEDTLS_ASN1_BIT_STRING ) ) != 0 ) + return( ret ); + + if( (*len)-- < 2 || *(*p)++ != 0 ) + return( MBEDTLS_ERR_ASN1_INVALID_DATA ); + + return( 0 ); +} + + + +/* + * Parses and splits an ASN.1 "SEQUENCE OF " + */ +int mbedtls_asn1_get_sequence_of( unsigned char **p, + const unsigned char *end, + mbedtls_asn1_sequence *cur, + int tag) +{ + int ret; + size_t len; + mbedtls_asn1_buf *buf; + + /* Get main sequence tag */ + if( ( ret = mbedtls_asn1_get_tag( p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) + return( ret ); + + if( *p + len != end ) + return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + + while( *p < end ) + { + buf = &(cur->buf); + buf->tag = **p; + + if( ( ret = mbedtls_asn1_get_tag( p, end, &buf->len, tag ) ) != 0 ) + return( ret ); + + buf->p = *p; + *p += buf->len; + + /* Allocate and assign next pointer */ + if( *p < end ) + { + cur->next = (mbedtls_asn1_sequence*)mbedtls_calloc( 1, + sizeof( mbedtls_asn1_sequence ) ); + + if( cur->next == NULL ) + return( MBEDTLS_ERR_ASN1_ALLOC_FAILED ); + + cur = cur->next; + } + } + + /* Set final sequence entry's next pointer to NULL */ + cur->next = NULL; + + if( *p != end ) + return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + + return( 0 ); +} + +int mbedtls_asn1_get_alg( unsigned char **p, + const unsigned char *end, + mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params ) +{ + int ret; + size_t len; + + if( ( ret = mbedtls_asn1_get_tag( p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) + return( ret ); + + if( ( end - *p ) < 1 ) + return( MBEDTLS_ERR_ASN1_OUT_OF_DATA ); + + alg->tag = **p; + end = *p + len; + + if( ( ret = mbedtls_asn1_get_tag( p, end, &alg->len, MBEDTLS_ASN1_OID ) ) != 0 ) + return( ret ); + + alg->p = *p; + *p += alg->len; + + if( *p == end ) + { + mbedtls_zeroize( params, sizeof(mbedtls_asn1_buf) ); + return( 0 ); + } + + params->tag = **p; + (*p)++; + + if( ( ret = mbedtls_asn1_get_len( p, end, ¶ms->len ) ) != 0 ) + return( ret ); + + params->p = *p; + *p += params->len; + + if( *p != end ) + return( MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + + return( 0 ); +} + +int mbedtls_asn1_get_alg_null( unsigned char **p, + const unsigned char *end, + mbedtls_asn1_buf *alg ) +{ + int ret; + mbedtls_asn1_buf params; + + memset( ¶ms, 0, sizeof(mbedtls_asn1_buf) ); + + if( ( ret = mbedtls_asn1_get_alg( p, end, alg, ¶ms ) ) != 0 ) + return( ret ); + + if( ( params.tag != MBEDTLS_ASN1_NULL && params.tag != 0 ) || params.len != 0 ) + return( MBEDTLS_ERR_ASN1_INVALID_DATA ); + + return( 0 ); +} + +void mbedtls_asn1_free_named_data( mbedtls_asn1_named_data *cur ) +{ + if( cur == NULL ) + return; + + mbedtls_free( cur->oid.p ); + mbedtls_free( cur->val.p ); + + mbedtls_zeroize( cur, sizeof( mbedtls_asn1_named_data ) ); +} + +void mbedtls_asn1_free_named_data_list( mbedtls_asn1_named_data **head ) +{ + mbedtls_asn1_named_data *cur; + + while( ( cur = *head ) != NULL ) + { + *head = cur->next; + mbedtls_asn1_free_named_data( cur ); + mbedtls_free( cur ); + } +} + +mbedtls_asn1_named_data *mbedtls_asn1_find_named_data( mbedtls_asn1_named_data *list, + const char *oid, size_t len ) +{ + while( list != NULL ) + { + if( list->oid.len == len && + memcmp( list->oid.p, oid, len ) == 0 ) + { + break; + } + + list = list->next; + } + + return( list ); +} + +#endif /* MBEDTLS_ASN1_PARSE_C */ diff --git a/security/mbedtls/src/asn1write.c b/security/mbedtls/src/asn1write.c new file mode 100644 index 0000000000..69b61b205f --- /dev/null +++ b/security/mbedtls/src/asn1write.c @@ -0,0 +1,390 @@ +/* + * ASN.1 buffer writing functionality + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_ASN1_WRITE_C) + +#include "mbedtls/asn1write.h" + +#include + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_calloc calloc +#define mbedtls_free free +#endif + +int mbedtls_asn1_write_len( unsigned char **p, unsigned char *start, size_t len ) +{ + if( len < 0x80 ) + { + if( *p - start < 1 ) + return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); + + *--(*p) = (unsigned char) len; + return( 1 ); + } + + if( len <= 0xFF ) + { + if( *p - start < 2 ) + return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); + + *--(*p) = (unsigned char) len; + *--(*p) = 0x81; + return( 2 ); + } + + if( len <= 0xFFFF ) + { + if( *p - start < 3 ) + return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); + + *--(*p) = ( len ) & 0xFF; + *--(*p) = ( len >> 8 ) & 0xFF; + *--(*p) = 0x82; + return( 3 ); + } + + if( len <= 0xFFFFFF ) + { + if( *p - start < 4 ) + return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); + + *--(*p) = ( len ) & 0xFF; + *--(*p) = ( len >> 8 ) & 0xFF; + *--(*p) = ( len >> 16 ) & 0xFF; + *--(*p) = 0x83; + return( 4 ); + } + + if( len <= 0xFFFFFFFF ) + { + if( *p - start < 5 ) + return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); + + *--(*p) = ( len ) & 0xFF; + *--(*p) = ( len >> 8 ) & 0xFF; + *--(*p) = ( len >> 16 ) & 0xFF; + *--(*p) = ( len >> 24 ) & 0xFF; + *--(*p) = 0x84; + return( 5 ); + } + + return( MBEDTLS_ERR_ASN1_INVALID_LENGTH ); +} + +int mbedtls_asn1_write_tag( unsigned char **p, unsigned char *start, unsigned char tag ) +{ + if( *p - start < 1 ) + return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); + + *--(*p) = tag; + + return( 1 ); +} + +int mbedtls_asn1_write_raw_buffer( unsigned char **p, unsigned char *start, + const unsigned char *buf, size_t size ) +{ + size_t len = 0; + + if( *p < start || (size_t)( *p - start ) < size ) + return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); + + len = size; + (*p) -= len; + memcpy( *p, buf, len ); + + return( (int) len ); +} + +#if defined(MBEDTLS_BIGNUM_C) +int mbedtls_asn1_write_mpi( unsigned char **p, unsigned char *start, const mbedtls_mpi *X ) +{ + int ret; + size_t len = 0; + + // Write the MPI + // + len = mbedtls_mpi_size( X ); + + if( *p < start || (size_t)( *p - start ) < len ) + return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); + + (*p) -= len; + MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( X, *p, len ) ); + + // DER format assumes 2s complement for numbers, so the leftmost bit + // should be 0 for positive numbers and 1 for negative numbers. + // + if( X->s ==1 && **p & 0x80 ) + { + if( *p - start < 1 ) + return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); + + *--(*p) = 0x00; + len += 1; + } + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_INTEGER ) ); + + ret = (int) len; + +cleanup: + return( ret ); +} +#endif /* MBEDTLS_BIGNUM_C */ + +int mbedtls_asn1_write_null( unsigned char **p, unsigned char *start ) +{ + int ret; + size_t len = 0; + + // Write NULL + // + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, 0) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_NULL ) ); + + return( (int) len ); +} + +int mbedtls_asn1_write_oid( unsigned char **p, unsigned char *start, + const char *oid, size_t oid_len ) +{ + int ret; + size_t len = 0; + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, + (const unsigned char *) oid, oid_len ) ); + MBEDTLS_ASN1_CHK_ADD( len , mbedtls_asn1_write_len( p, start, len ) ); + MBEDTLS_ASN1_CHK_ADD( len , mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_OID ) ); + + return( (int) len ); +} + +int mbedtls_asn1_write_algorithm_identifier( unsigned char **p, unsigned char *start, + const char *oid, size_t oid_len, + size_t par_len ) +{ + int ret; + size_t len = 0; + + if( par_len == 0 ) + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_null( p, start ) ); + else + len += par_len; + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( p, start, oid, oid_len ) ); + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ); + + return( (int) len ); +} + +int mbedtls_asn1_write_bool( unsigned char **p, unsigned char *start, int boolean ) +{ + int ret; + size_t len = 0; + + if( *p - start < 1 ) + return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); + + *--(*p) = (boolean) ? 255 : 0; + len++; + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_BOOLEAN ) ); + + return( (int) len ); +} + +int mbedtls_asn1_write_int( unsigned char **p, unsigned char *start, int val ) +{ + int ret; + size_t len = 0; + + // TODO negative values and values larger than 128 + // DER format assumes 2s complement for numbers, so the leftmost bit + // should be 0 for positive numbers and 1 for negative numbers. + // + if( *p - start < 1 ) + return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); + + len += 1; + *--(*p) = val; + + if( val > 0 && **p & 0x80 ) + { + if( *p - start < 1 ) + return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); + + *--(*p) = 0x00; + len += 1; + } + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_INTEGER ) ); + + return( (int) len ); +} + +int mbedtls_asn1_write_printable_string( unsigned char **p, unsigned char *start, + const char *text, size_t text_len ) +{ + int ret; + size_t len = 0; + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, + (const unsigned char *) text, text_len ) ); + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_PRINTABLE_STRING ) ); + + return( (int) len ); +} + +int mbedtls_asn1_write_ia5_string( unsigned char **p, unsigned char *start, + const char *text, size_t text_len ) +{ + int ret; + size_t len = 0; + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, + (const unsigned char *) text, text_len ) ); + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_IA5_STRING ) ); + + return( (int) len ); +} + +int mbedtls_asn1_write_bitstring( unsigned char **p, unsigned char *start, + const unsigned char *buf, size_t bits ) +{ + int ret; + size_t len = 0, size; + + size = ( bits / 8 ) + ( ( bits % 8 ) ? 1 : 0 ); + + // Calculate byte length + // + if( *p < start || (size_t)( *p - start ) < size + 1 ) + return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); + + len = size + 1; + (*p) -= size; + memcpy( *p, buf, size ); + + // Write unused bits + // + *--(*p) = (unsigned char) (size * 8 - bits); + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_BIT_STRING ) ); + + return( (int) len ); +} + +int mbedtls_asn1_write_octet_string( unsigned char **p, unsigned char *start, + const unsigned char *buf, size_t size ) +{ + int ret; + size_t len = 0; + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, buf, size ) ); + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_OCTET_STRING ) ); + + return( (int) len ); +} + +mbedtls_asn1_named_data *mbedtls_asn1_store_named_data( mbedtls_asn1_named_data **head, + const char *oid, size_t oid_len, + const unsigned char *val, + size_t val_len ) +{ + mbedtls_asn1_named_data *cur; + + if( ( cur = mbedtls_asn1_find_named_data( *head, oid, oid_len ) ) == NULL ) + { + // Add new entry if not present yet based on OID + // + cur = (mbedtls_asn1_named_data*)mbedtls_calloc( 1, + sizeof(mbedtls_asn1_named_data) ); + if( cur == NULL ) + return( NULL ); + + cur->oid.len = oid_len; + cur->oid.p = mbedtls_calloc( 1, oid_len ); + if( cur->oid.p == NULL ) + { + mbedtls_free( cur ); + return( NULL ); + } + + memcpy( cur->oid.p, oid, oid_len ); + + cur->val.len = val_len; + cur->val.p = mbedtls_calloc( 1, val_len ); + if( cur->val.p == NULL ) + { + mbedtls_free( cur->oid.p ); + mbedtls_free( cur ); + return( NULL ); + } + + cur->next = *head; + *head = cur; + } + else if( cur->val.len < val_len ) + { + /* + * Enlarge existing value buffer if needed + * Preserve old data until the allocation succeeded, to leave list in + * a consistent state in case allocation fails. + */ + void *p = mbedtls_calloc( 1, val_len ); + if( p == NULL ) + return( NULL ); + + mbedtls_free( cur->val.p ); + cur->val.p = p; + cur->val.len = val_len; + } + + if( val != NULL ) + memcpy( cur->val.p, val, val_len ); + + return( cur ); +} +#endif /* MBEDTLS_ASN1_WRITE_C */ diff --git a/security/mbedtls/src/base64.c b/security/mbedtls/src/base64.c new file mode 100644 index 0000000000..f06b57b31f --- /dev/null +++ b/security/mbedtls/src/base64.c @@ -0,0 +1,293 @@ +/* + * RFC 1521 base64 encoding/decoding + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_BASE64_C) + +#include "mbedtls/base64.h" + +#include + +#if defined(MBEDTLS_SELF_TEST) +#include +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_printf printf +#endif /* MBEDTLS_PLATFORM_C */ +#endif /* MBEDTLS_SELF_TEST */ + +static const unsigned char base64_enc_map[64] = +{ + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', + 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', + 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', + 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', + 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', + 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', '+', '/' +}; + +static const unsigned char base64_dec_map[128] = +{ + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, + 127, 127, 127, 62, 127, 127, 127, 63, 52, 53, + 54, 55, 56, 57, 58, 59, 60, 61, 127, 127, + 127, 64, 127, 127, 127, 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, 127, 127, 127, 127, 127, 127, 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, 127, 127, 127, 127, 127 +}; + +#define BASE64_SIZE_T_MAX ( (size_t) -1 ) /* SIZE_T_MAX is not standard */ + +/* + * Encode a buffer into base64 format + */ +int mbedtls_base64_encode( unsigned char *dst, size_t dlen, size_t *olen, + const unsigned char *src, size_t slen ) +{ + size_t i, n; + int C1, C2, C3; + unsigned char *p; + + if( slen == 0 ) + { + *olen = 0; + return( 0 ); + } + + n = slen / 3 + ( slen % 3 != 0 ); + + if( n > ( BASE64_SIZE_T_MAX - 1 ) / 4 ) + { + *olen = BASE64_SIZE_T_MAX; + return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL ); + } + + n *= 4; + + if( ( dlen < n + 1 ) || ( NULL == dst ) ) + { + *olen = n + 1; + return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL ); + } + + n = ( slen / 3 ) * 3; + + for( i = 0, p = dst; i < n; i += 3 ) + { + C1 = *src++; + C2 = *src++; + C3 = *src++; + + *p++ = base64_enc_map[(C1 >> 2) & 0x3F]; + *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F]; + *p++ = base64_enc_map[(((C2 & 15) << 2) + (C3 >> 6)) & 0x3F]; + *p++ = base64_enc_map[C3 & 0x3F]; + } + + if( i < slen ) + { + C1 = *src++; + C2 = ( ( i + 1 ) < slen ) ? *src++ : 0; + + *p++ = base64_enc_map[(C1 >> 2) & 0x3F]; + *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F]; + + if( ( i + 1 ) < slen ) + *p++ = base64_enc_map[((C2 & 15) << 2) & 0x3F]; + else *p++ = '='; + + *p++ = '='; + } + + *olen = p - dst; + *p = 0; + + return( 0 ); +} + +/* + * Decode a base64-formatted buffer + */ +int mbedtls_base64_decode( unsigned char *dst, size_t dlen, size_t *olen, + const unsigned char *src, size_t slen ) +{ + size_t i, n; + uint32_t j, x; + unsigned char *p; + + /* First pass: check for validity and get output length */ + for( i = n = j = 0; i < slen; i++ ) + { + /* Skip spaces before checking for EOL */ + x = 0; + while( i < slen && src[i] == ' ' ) + { + ++i; + ++x; + } + + /* Spaces at end of buffer are OK */ + if( i == slen ) + break; + + if( ( slen - i ) >= 2 && + src[i] == '\r' && src[i + 1] == '\n' ) + continue; + + if( src[i] == '\n' ) + continue; + + /* Space inside a line is an error */ + if( x != 0 ) + return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER ); + + if( src[i] == '=' && ++j > 2 ) + return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER ); + + if( src[i] > 127 || base64_dec_map[src[i]] == 127 ) + return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER ); + + if( base64_dec_map[src[i]] < 64 && j != 0 ) + return( MBEDTLS_ERR_BASE64_INVALID_CHARACTER ); + + n++; + } + + if( n == 0 ) + { + *olen = 0; + return( 0 ); + } + + /* The following expression is to calculate the following formula without + * risk of integer overflow in n: + * n = ( ( n * 6 ) + 7 ) >> 3; + */ + n = ( 6 * ( n >> 3 ) ) + ( ( 6 * ( n & 0x7 ) + 7 ) >> 3 ); + n -= j; + + if( dst == NULL || dlen < n ) + { + *olen = n; + return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL ); + } + + for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ ) + { + if( *src == '\r' || *src == '\n' || *src == ' ' ) + continue; + + j -= ( base64_dec_map[*src] == 64 ); + x = ( x << 6 ) | ( base64_dec_map[*src] & 0x3F ); + + if( ++n == 4 ) + { + n = 0; + if( j > 0 ) *p++ = (unsigned char)( x >> 16 ); + if( j > 1 ) *p++ = (unsigned char)( x >> 8 ); + if( j > 2 ) *p++ = (unsigned char)( x ); + } + } + + *olen = p - dst; + + return( 0 ); +} + +#if defined(MBEDTLS_SELF_TEST) + +static const unsigned char base64_test_dec[64] = +{ + 0x24, 0x48, 0x6E, 0x56, 0x87, 0x62, 0x5A, 0xBD, + 0xBF, 0x17, 0xD9, 0xA2, 0xC4, 0x17, 0x1A, 0x01, + 0x94, 0xED, 0x8F, 0x1E, 0x11, 0xB3, 0xD7, 0x09, + 0x0C, 0xB6, 0xE9, 0x10, 0x6F, 0x22, 0xEE, 0x13, + 0xCA, 0xB3, 0x07, 0x05, 0x76, 0xC9, 0xFA, 0x31, + 0x6C, 0x08, 0x34, 0xFF, 0x8D, 0xC2, 0x6C, 0x38, + 0x00, 0x43, 0xE9, 0x54, 0x97, 0xAF, 0x50, 0x4B, + 0xD1, 0x41, 0xBA, 0x95, 0x31, 0x5A, 0x0B, 0x97 +}; + +static const unsigned char base64_test_enc[] = + "JEhuVodiWr2/F9mixBcaAZTtjx4Rs9cJDLbpEG8i7hPK" + "swcFdsn6MWwINP+Nwmw4AEPpVJevUEvRQbqVMVoLlw=="; + +/* + * Checkup routine + */ +int mbedtls_base64_self_test( int verbose ) +{ + size_t len; + const unsigned char *src; + unsigned char buffer[128]; + + if( verbose != 0 ) + mbedtls_printf( " Base64 encoding test: " ); + + src = base64_test_dec; + + if( mbedtls_base64_encode( buffer, sizeof( buffer ), &len, src, 64 ) != 0 || + memcmp( base64_test_enc, buffer, 88 ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n Base64 decoding test: " ); + + src = base64_test_enc; + + if( mbedtls_base64_decode( buffer, sizeof( buffer ), &len, src, 88 ) != 0 || + memcmp( base64_test_dec, buffer, 64 ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n\n" ); + + return( 0 ); +} + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_BASE64_C */ diff --git a/security/mbedtls/src/bignum.c b/security/mbedtls/src/bignum.c new file mode 100644 index 0000000000..193f4806e8 --- /dev/null +++ b/security/mbedtls/src/bignum.c @@ -0,0 +1,2448 @@ +/* + * Multi-precision integer library + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +/* + * The following sources were referenced in the design of this Multi-precision + * Integer library: + * + * [1] Handbook of Applied Cryptography - 1997 + * Menezes, van Oorschot and Vanstone + * + * [2] Multi-Precision Math + * Tom St Denis + * https://github.com/libtom/libtommath/blob/develop/tommath.pdf + * + * [3] GNU Multi-Precision Arithmetic Library + * https://gmplib.org/manual/index.html + * + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_BIGNUM_C) + +#include "mbedtls/bignum.h" +#include "mbedtls/bn_mul.h" + +#include + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#include +#define mbedtls_printf printf +#define mbedtls_calloc calloc +#define mbedtls_free free +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_mpi_zeroize( mbedtls_mpi_uint *v, size_t n ) { + volatile mbedtls_mpi_uint *p = v; while( n-- ) *p++ = 0; +} + +#define ciL (sizeof(mbedtls_mpi_uint)) /* chars in limb */ +#define biL (ciL << 3) /* bits in limb */ +#define biH (ciL << 2) /* half limb size */ + +#define MPI_SIZE_T_MAX ( (size_t) -1 ) /* SIZE_T_MAX is not standard */ + +/* + * Convert between bits/chars and number of limbs + * Divide first in order to avoid potential overflows + */ +#define BITS_TO_LIMBS(i) ( (i) / biL + ( (i) % biL != 0 ) ) +#define CHARS_TO_LIMBS(i) ( (i) / ciL + ( (i) % ciL != 0 ) ) + +/* + * Initialize one MPI + */ +void mbedtls_mpi_init( mbedtls_mpi *X ) +{ + if( X == NULL ) + return; + + X->s = 1; + X->n = 0; + X->p = NULL; +} + +/* + * Unallocate one MPI + */ +void mbedtls_mpi_free( mbedtls_mpi *X ) +{ + if( X == NULL ) + return; + + if( X->p != NULL ) + { + mbedtls_mpi_zeroize( X->p, X->n ); + mbedtls_free( X->p ); + } + + X->s = 1; + X->n = 0; + X->p = NULL; +} + +/* + * Enlarge to the specified number of limbs + */ +int mbedtls_mpi_grow( mbedtls_mpi *X, size_t nblimbs ) +{ + mbedtls_mpi_uint *p; + + if( nblimbs > MBEDTLS_MPI_MAX_LIMBS ) + return( MBEDTLS_ERR_MPI_ALLOC_FAILED ); + + if( X->n < nblimbs ) + { + if( ( p = (mbedtls_mpi_uint*)mbedtls_calloc( nblimbs, ciL ) ) == NULL ) + return( MBEDTLS_ERR_MPI_ALLOC_FAILED ); + + if( X->p != NULL ) + { + memcpy( p, X->p, X->n * ciL ); + mbedtls_mpi_zeroize( X->p, X->n ); + mbedtls_free( X->p ); + } + + X->n = nblimbs; + X->p = p; + } + + return( 0 ); +} + +/* + * Resize down as much as possible, + * while keeping at least the specified number of limbs + */ +int mbedtls_mpi_shrink( mbedtls_mpi *X, size_t nblimbs ) +{ + mbedtls_mpi_uint *p; + size_t i; + + /* Actually resize up in this case */ + if( X->n <= nblimbs ) + return( mbedtls_mpi_grow( X, nblimbs ) ); + + for( i = X->n - 1; i > 0; i-- ) + if( X->p[i] != 0 ) + break; + i++; + + if( i < nblimbs ) + i = nblimbs; + + if( ( p = (mbedtls_mpi_uint*)mbedtls_calloc( i, ciL ) ) == NULL ) + return( MBEDTLS_ERR_MPI_ALLOC_FAILED ); + + if( X->p != NULL ) + { + memcpy( p, X->p, i * ciL ); + mbedtls_mpi_zeroize( X->p, X->n ); + mbedtls_free( X->p ); + } + + X->n = i; + X->p = p; + + return( 0 ); +} + +/* + * Copy the contents of Y into X + */ +int mbedtls_mpi_copy( mbedtls_mpi *X, const mbedtls_mpi *Y ) +{ + int ret; + size_t i; + + if( X == Y ) + return( 0 ); + + if( Y->p == NULL ) + { + mbedtls_mpi_free( X ); + return( 0 ); + } + + for( i = Y->n - 1; i > 0; i-- ) + if( Y->p[i] != 0 ) + break; + i++; + + X->s = Y->s; + + MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i ) ); + + memset( X->p, 0, X->n * ciL ); + memcpy( X->p, Y->p, i * ciL ); + +cleanup: + + return( ret ); +} + +/* + * Swap the contents of X and Y + */ +void mbedtls_mpi_swap( mbedtls_mpi *X, mbedtls_mpi *Y ) +{ + mbedtls_mpi T; + + memcpy( &T, X, sizeof( mbedtls_mpi ) ); + memcpy( X, Y, sizeof( mbedtls_mpi ) ); + memcpy( Y, &T, sizeof( mbedtls_mpi ) ); +} + +/* + * Conditionally assign X = Y, without leaking information + * about whether the assignment was made or not. + * (Leaking information about the respective sizes of X and Y is ok however.) + */ +int mbedtls_mpi_safe_cond_assign( mbedtls_mpi *X, const mbedtls_mpi *Y, unsigned char assign ) +{ + int ret = 0; + size_t i; + + /* make sure assign is 0 or 1 in a time-constant manner */ + assign = (assign | (unsigned char)-assign) >> 7; + + MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, Y->n ) ); + + X->s = X->s * ( 1 - assign ) + Y->s * assign; + + for( i = 0; i < Y->n; i++ ) + X->p[i] = X->p[i] * ( 1 - assign ) + Y->p[i] * assign; + + for( ; i < X->n; i++ ) + X->p[i] *= ( 1 - assign ); + +cleanup: + return( ret ); +} + +/* + * Conditionally swap X and Y, without leaking information + * about whether the swap was made or not. + * Here it is not ok to simply swap the pointers, which whould lead to + * different memory access patterns when X and Y are used afterwards. + */ +int mbedtls_mpi_safe_cond_swap( mbedtls_mpi *X, mbedtls_mpi *Y, unsigned char swap ) +{ + int ret, s; + size_t i; + mbedtls_mpi_uint tmp; + + if( X == Y ) + return( 0 ); + + /* make sure swap is 0 or 1 in a time-constant manner */ + swap = (swap | (unsigned char)-swap) >> 7; + + MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, Y->n ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_grow( Y, X->n ) ); + + s = X->s; + X->s = X->s * ( 1 - swap ) + Y->s * swap; + Y->s = Y->s * ( 1 - swap ) + s * swap; + + + for( i = 0; i < X->n; i++ ) + { + tmp = X->p[i]; + X->p[i] = X->p[i] * ( 1 - swap ) + Y->p[i] * swap; + Y->p[i] = Y->p[i] * ( 1 - swap ) + tmp * swap; + } + +cleanup: + return( ret ); +} + +/* + * Set value from integer + */ +int mbedtls_mpi_lset( mbedtls_mpi *X, mbedtls_mpi_sint z ) +{ + int ret; + + MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, 1 ) ); + memset( X->p, 0, X->n * ciL ); + + X->p[0] = ( z < 0 ) ? -z : z; + X->s = ( z < 0 ) ? -1 : 1; + +cleanup: + + return( ret ); +} + +/* + * Get a specific bit + */ +int mbedtls_mpi_get_bit( const mbedtls_mpi *X, size_t pos ) +{ + if( X->n * biL <= pos ) + return( 0 ); + + return( ( X->p[pos / biL] >> ( pos % biL ) ) & 0x01 ); +} + +/* + * Set a bit to a specific value of 0 or 1 + */ +int mbedtls_mpi_set_bit( mbedtls_mpi *X, size_t pos, unsigned char val ) +{ + int ret = 0; + size_t off = pos / biL; + size_t idx = pos % biL; + + if( val != 0 && val != 1 ) + return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); + + if( X->n * biL <= pos ) + { + if( val == 0 ) + return( 0 ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, off + 1 ) ); + } + + X->p[off] &= ~( (mbedtls_mpi_uint) 0x01 << idx ); + X->p[off] |= (mbedtls_mpi_uint) val << idx; + +cleanup: + + return( ret ); +} + +/* + * Return the number of less significant zero-bits + */ +size_t mbedtls_mpi_lsb( const mbedtls_mpi *X ) +{ + size_t i, j, count = 0; + + for( i = 0; i < X->n; i++ ) + for( j = 0; j < biL; j++, count++ ) + if( ( ( X->p[i] >> j ) & 1 ) != 0 ) + return( count ); + + return( 0 ); +} + +/* + * Count leading zero bits in a given integer + */ +static size_t mbedtls_clz( const mbedtls_mpi_uint x ) +{ + size_t j; + mbedtls_mpi_uint mask = (mbedtls_mpi_uint) 1 << (biL - 1); + + for( j = 0; j < biL; j++ ) + { + if( x & mask ) break; + + mask >>= 1; + } + + return j; +} + +/* + * Return the number of bits + */ +size_t mbedtls_mpi_bitlen( const mbedtls_mpi *X ) +{ + size_t i, j; + + if( X->n == 0 ) + return( 0 ); + + for( i = X->n - 1; i > 0; i-- ) + if( X->p[i] != 0 ) + break; + + j = biL - mbedtls_clz( X->p[i] ); + + return( ( i * biL ) + j ); +} + +/* + * Return the total size in bytes + */ +size_t mbedtls_mpi_size( const mbedtls_mpi *X ) +{ + return( ( mbedtls_mpi_bitlen( X ) + 7 ) >> 3 ); +} + +/* + * Convert an ASCII character to digit value + */ +static int mpi_get_digit( mbedtls_mpi_uint *d, int radix, char c ) +{ + *d = 255; + + if( c >= 0x30 && c <= 0x39 ) *d = c - 0x30; + if( c >= 0x41 && c <= 0x46 ) *d = c - 0x37; + if( c >= 0x61 && c <= 0x66 ) *d = c - 0x57; + + if( *d >= (mbedtls_mpi_uint) radix ) + return( MBEDTLS_ERR_MPI_INVALID_CHARACTER ); + + return( 0 ); +} + +/* + * Import from an ASCII string + */ +int mbedtls_mpi_read_string( mbedtls_mpi *X, int radix, const char *s ) +{ + int ret; + size_t i, j, slen, n; + mbedtls_mpi_uint d; + mbedtls_mpi T; + + if( radix < 2 || radix > 16 ) + return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); + + mbedtls_mpi_init( &T ); + + slen = strlen( s ); + + if( radix == 16 ) + { + if( slen > MPI_SIZE_T_MAX >> 2 ) + return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); + + n = BITS_TO_LIMBS( slen << 2 ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, n ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) ); + + for( i = slen, j = 0; i > 0; i--, j++ ) + { + if( i == 1 && s[i - 1] == '-' ) + { + X->s = -1; + break; + } + + MBEDTLS_MPI_CHK( mpi_get_digit( &d, radix, s[i - 1] ) ); + X->p[j / ( 2 * ciL )] |= d << ( ( j % ( 2 * ciL ) ) << 2 ); + } + } + else + { + MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) ); + + for( i = 0; i < slen; i++ ) + { + if( i == 0 && s[i] == '-' ) + { + X->s = -1; + continue; + } + + MBEDTLS_MPI_CHK( mpi_get_digit( &d, radix, s[i] ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T, X, radix ) ); + + if( X->s == 1 ) + { + MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, &T, d ) ); + } + else + { + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( X, &T, d ) ); + } + } + } + +cleanup: + + mbedtls_mpi_free( &T ); + + return( ret ); +} + +/* + * Helper to write the digits high-order first + */ +static int mpi_write_hlp( mbedtls_mpi *X, int radix, char **p ) +{ + int ret; + mbedtls_mpi_uint r; + + if( radix < 2 || radix > 16 ) + return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, radix ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_div_int( X, NULL, X, radix ) ); + + if( mbedtls_mpi_cmp_int( X, 0 ) != 0 ) + MBEDTLS_MPI_CHK( mpi_write_hlp( X, radix, p ) ); + + if( r < 10 ) + *(*p)++ = (char)( r + 0x30 ); + else + *(*p)++ = (char)( r + 0x37 ); + +cleanup: + + return( ret ); +} + +/* + * Export into an ASCII string + */ +int mbedtls_mpi_write_string( const mbedtls_mpi *X, int radix, + char *buf, size_t buflen, size_t *olen ) +{ + int ret = 0; + size_t n; + char *p; + mbedtls_mpi T; + + if( radix < 2 || radix > 16 ) + return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); + + n = mbedtls_mpi_bitlen( X ); + if( radix >= 4 ) n >>= 1; + if( radix >= 16 ) n >>= 1; + /* + * Round up the buffer length to an even value to ensure that there is + * enough room for hexadecimal values that can be represented in an odd + * number of digits. + */ + n += 3 + ( ( n + 1 ) & 1 ); + + if( buflen < n ) + { + *olen = n; + return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL ); + } + + p = buf; + mbedtls_mpi_init( &T ); + + if( X->s == -1 ) + *p++ = '-'; + + if( radix == 16 ) + { + int c; + size_t i, j, k; + + for( i = X->n, k = 0; i > 0; i-- ) + { + for( j = ciL; j > 0; j-- ) + { + c = ( X->p[i - 1] >> ( ( j - 1 ) << 3) ) & 0xFF; + + if( c == 0 && k == 0 && ( i + j ) != 2 ) + continue; + + *(p++) = "0123456789ABCDEF" [c / 16]; + *(p++) = "0123456789ABCDEF" [c % 16]; + k = 1; + } + } + } + else + { + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &T, X ) ); + + if( T.s == -1 ) + T.s = 1; + + MBEDTLS_MPI_CHK( mpi_write_hlp( &T, radix, &p ) ); + } + + *p++ = '\0'; + *olen = p - buf; + +cleanup: + + mbedtls_mpi_free( &T ); + + return( ret ); +} + +#if defined(MBEDTLS_FS_IO) +/* + * Read X from an opened file + */ +int mbedtls_mpi_read_file( mbedtls_mpi *X, int radix, FILE *fin ) +{ + mbedtls_mpi_uint d; + size_t slen; + char *p; + /* + * Buffer should have space for (short) label and decimal formatted MPI, + * newline characters and '\0' + */ + char s[ MBEDTLS_MPI_RW_BUFFER_SIZE ]; + + memset( s, 0, sizeof( s ) ); + if( fgets( s, sizeof( s ) - 1, fin ) == NULL ) + return( MBEDTLS_ERR_MPI_FILE_IO_ERROR ); + + slen = strlen( s ); + if( slen == sizeof( s ) - 2 ) + return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL ); + + if( s[slen - 1] == '\n' ) { slen--; s[slen] = '\0'; } + if( s[slen - 1] == '\r' ) { slen--; s[slen] = '\0'; } + + p = s + slen; + while( --p >= s ) + if( mpi_get_digit( &d, radix, *p ) != 0 ) + break; + + return( mbedtls_mpi_read_string( X, radix, p + 1 ) ); +} + +/* + * Write X into an opened file (or stdout if fout == NULL) + */ +int mbedtls_mpi_write_file( const char *p, const mbedtls_mpi *X, int radix, FILE *fout ) +{ + int ret; + size_t n, slen, plen; + /* + * Buffer should have space for (short) label and decimal formatted MPI, + * newline characters and '\0' + */ + char s[ MBEDTLS_MPI_RW_BUFFER_SIZE ]; + + memset( s, 0, sizeof( s ) ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_write_string( X, radix, s, sizeof( s ) - 2, &n ) ); + + if( p == NULL ) p = ""; + + plen = strlen( p ); + slen = strlen( s ); + s[slen++] = '\r'; + s[slen++] = '\n'; + + if( fout != NULL ) + { + if( fwrite( p, 1, plen, fout ) != plen || + fwrite( s, 1, slen, fout ) != slen ) + return( MBEDTLS_ERR_MPI_FILE_IO_ERROR ); + } + else + mbedtls_printf( "%s%s", p, s ); + +cleanup: + + return( ret ); +} +#endif /* MBEDTLS_FS_IO */ + +/* + * Import X from unsigned binary data, big endian + */ +int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf, size_t buflen ) +{ + int ret; + size_t i, j, n; + + for( n = 0; n < buflen; n++ ) + if( buf[n] != 0 ) + break; + + MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, CHARS_TO_LIMBS( buflen - n ) ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) ); + + for( i = buflen, j = 0; i > n; i--, j++ ) + X->p[j / ciL] |= ((mbedtls_mpi_uint) buf[i - 1]) << ((j % ciL) << 3); + +cleanup: + + return( ret ); +} + +/* + * Export X into unsigned binary data, big endian + */ +int mbedtls_mpi_write_binary( const mbedtls_mpi *X, unsigned char *buf, size_t buflen ) +{ + size_t i, j, n; + + n = mbedtls_mpi_size( X ); + + if( buflen < n ) + return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL ); + + memset( buf, 0, buflen ); + + for( i = buflen - 1, j = 0; n > 0; i--, j++, n-- ) + buf[i] = (unsigned char)( X->p[j / ciL] >> ((j % ciL) << 3) ); + + return( 0 ); +} + +/* + * Left-shift: X <<= count + */ +int mbedtls_mpi_shift_l( mbedtls_mpi *X, size_t count ) +{ + int ret; + size_t i, v0, t1; + mbedtls_mpi_uint r0 = 0, r1; + + v0 = count / (biL ); + t1 = count & (biL - 1); + + i = mbedtls_mpi_bitlen( X ) + count; + + if( X->n * biL < i ) + MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, BITS_TO_LIMBS( i ) ) ); + + ret = 0; + + /* + * shift by count / limb_size + */ + if( v0 > 0 ) + { + for( i = X->n; i > v0; i-- ) + X->p[i - 1] = X->p[i - v0 - 1]; + + for( ; i > 0; i-- ) + X->p[i - 1] = 0; + } + + /* + * shift by count % limb_size + */ + if( t1 > 0 ) + { + for( i = v0; i < X->n; i++ ) + { + r1 = X->p[i] >> (biL - t1); + X->p[i] <<= t1; + X->p[i] |= r0; + r0 = r1; + } + } + +cleanup: + + return( ret ); +} + +/* + * Right-shift: X >>= count + */ +int mbedtls_mpi_shift_r( mbedtls_mpi *X, size_t count ) +{ + size_t i, v0, v1; + mbedtls_mpi_uint r0 = 0, r1; + + v0 = count / biL; + v1 = count & (biL - 1); + + if( v0 > X->n || ( v0 == X->n && v1 > 0 ) ) + return mbedtls_mpi_lset( X, 0 ); + + /* + * shift by count / limb_size + */ + if( v0 > 0 ) + { + for( i = 0; i < X->n - v0; i++ ) + X->p[i] = X->p[i + v0]; + + for( ; i < X->n; i++ ) + X->p[i] = 0; + } + + /* + * shift by count % limb_size + */ + if( v1 > 0 ) + { + for( i = X->n; i > 0; i-- ) + { + r1 = X->p[i - 1] << (biL - v1); + X->p[i - 1] >>= v1; + X->p[i - 1] |= r0; + r0 = r1; + } + } + + return( 0 ); +} + +/* + * Compare unsigned values + */ +int mbedtls_mpi_cmp_abs( const mbedtls_mpi *X, const mbedtls_mpi *Y ) +{ + size_t i, j; + + for( i = X->n; i > 0; i-- ) + if( X->p[i - 1] != 0 ) + break; + + for( j = Y->n; j > 0; j-- ) + if( Y->p[j - 1] != 0 ) + break; + + if( i == 0 && j == 0 ) + return( 0 ); + + if( i > j ) return( 1 ); + if( j > i ) return( -1 ); + + for( ; i > 0; i-- ) + { + if( X->p[i - 1] > Y->p[i - 1] ) return( 1 ); + if( X->p[i - 1] < Y->p[i - 1] ) return( -1 ); + } + + return( 0 ); +} + +/* + * Compare signed values + */ +int mbedtls_mpi_cmp_mpi( const mbedtls_mpi *X, const mbedtls_mpi *Y ) +{ + size_t i, j; + + for( i = X->n; i > 0; i-- ) + if( X->p[i - 1] != 0 ) + break; + + for( j = Y->n; j > 0; j-- ) + if( Y->p[j - 1] != 0 ) + break; + + if( i == 0 && j == 0 ) + return( 0 ); + + if( i > j ) return( X->s ); + if( j > i ) return( -Y->s ); + + if( X->s > 0 && Y->s < 0 ) return( 1 ); + if( Y->s > 0 && X->s < 0 ) return( -1 ); + + for( ; i > 0; i-- ) + { + if( X->p[i - 1] > Y->p[i - 1] ) return( X->s ); + if( X->p[i - 1] < Y->p[i - 1] ) return( -X->s ); + } + + return( 0 ); +} + +/* + * Compare signed values + */ +int mbedtls_mpi_cmp_int( const mbedtls_mpi *X, mbedtls_mpi_sint z ) +{ + mbedtls_mpi Y; + mbedtls_mpi_uint p[1]; + + *p = ( z < 0 ) ? -z : z; + Y.s = ( z < 0 ) ? -1 : 1; + Y.n = 1; + Y.p = p; + + return( mbedtls_mpi_cmp_mpi( X, &Y ) ); +} + +/* + * Unsigned addition: X = |A| + |B| (HAC 14.7) + */ +int mbedtls_mpi_add_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B ) +{ + int ret; + size_t i, j; + mbedtls_mpi_uint *o, *p, c, tmp; + + if( X == B ) + { + const mbedtls_mpi *T = A; A = X; B = T; + } + + if( X != A ) + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, A ) ); + + /* + * X should always be positive as a result of unsigned additions. + */ + X->s = 1; + + for( j = B->n; j > 0; j-- ) + if( B->p[j - 1] != 0 ) + break; + + MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, j ) ); + + o = B->p; p = X->p; c = 0; + + /* + * tmp is used because it might happen that p == o + */ + for( i = 0; i < j; i++, o++, p++ ) + { + tmp= *o; + *p += c; c = ( *p < c ); + *p += tmp; c += ( *p < tmp ); + } + + while( c != 0 ) + { + if( i >= X->n ) + { + MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i + 1 ) ); + p = X->p + i; + } + + *p += c; c = ( *p < c ); i++; p++; + } + +cleanup: + + return( ret ); +} + +/* + * Helper for mbedtls_mpi subtraction + */ +static void mpi_sub_hlp( size_t n, mbedtls_mpi_uint *s, mbedtls_mpi_uint *d ) +{ + size_t i; + mbedtls_mpi_uint c, z; + + for( i = c = 0; i < n; i++, s++, d++ ) + { + z = ( *d < c ); *d -= c; + c = ( *d < *s ) + z; *d -= *s; + } + + while( c != 0 ) + { + z = ( *d < c ); *d -= c; + c = z; i++; d++; + } +} + +/* + * Unsigned subtraction: X = |A| - |B| (HAC 14.9) + */ +int mbedtls_mpi_sub_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B ) +{ + mbedtls_mpi TB; + int ret; + size_t n; + + if( mbedtls_mpi_cmp_abs( A, B ) < 0 ) + return( MBEDTLS_ERR_MPI_NEGATIVE_VALUE ); + + mbedtls_mpi_init( &TB ); + + if( X == B ) + { + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, B ) ); + B = &TB; + } + + if( X != A ) + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, A ) ); + + /* + * X should always be positive as a result of unsigned subtractions. + */ + X->s = 1; + + ret = 0; + + for( n = B->n; n > 0; n-- ) + if( B->p[n - 1] != 0 ) + break; + + mpi_sub_hlp( n, B->p, X->p ); + +cleanup: + + mbedtls_mpi_free( &TB ); + + return( ret ); +} + +/* + * Signed addition: X = A + B + */ +int mbedtls_mpi_add_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B ) +{ + int ret, s = A->s; + + if( A->s * B->s < 0 ) + { + if( mbedtls_mpi_cmp_abs( A, B ) >= 0 ) + { + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, A, B ) ); + X->s = s; + } + else + { + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, B, A ) ); + X->s = -s; + } + } + else + { + MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( X, A, B ) ); + X->s = s; + } + +cleanup: + + return( ret ); +} + +/* + * Signed subtraction: X = A - B + */ +int mbedtls_mpi_sub_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B ) +{ + int ret, s = A->s; + + if( A->s * B->s > 0 ) + { + if( mbedtls_mpi_cmp_abs( A, B ) >= 0 ) + { + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, A, B ) ); + X->s = s; + } + else + { + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, B, A ) ); + X->s = -s; + } + } + else + { + MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( X, A, B ) ); + X->s = s; + } + +cleanup: + + return( ret ); +} + +/* + * Signed addition: X = A + b + */ +int mbedtls_mpi_add_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b ) +{ + mbedtls_mpi _B; + mbedtls_mpi_uint p[1]; + + p[0] = ( b < 0 ) ? -b : b; + _B.s = ( b < 0 ) ? -1 : 1; + _B.n = 1; + _B.p = p; + + return( mbedtls_mpi_add_mpi( X, A, &_B ) ); +} + +/* + * Signed subtraction: X = A - b + */ +int mbedtls_mpi_sub_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b ) +{ + mbedtls_mpi _B; + mbedtls_mpi_uint p[1]; + + p[0] = ( b < 0 ) ? -b : b; + _B.s = ( b < 0 ) ? -1 : 1; + _B.n = 1; + _B.p = p; + + return( mbedtls_mpi_sub_mpi( X, A, &_B ) ); +} + +/* + * Helper for mbedtls_mpi multiplication + */ +static +#if defined(__APPLE__) && defined(__arm__) +/* + * Apple LLVM version 4.2 (clang-425.0.24) (based on LLVM 3.2svn) + * appears to need this to prevent bad ARM code generation at -O3. + */ +__attribute__ ((noinline)) +#endif +void mpi_mul_hlp( size_t i, mbedtls_mpi_uint *s, mbedtls_mpi_uint *d, mbedtls_mpi_uint b ) +{ + mbedtls_mpi_uint c = 0, t = 0; + +#if defined(MULADDC_HUIT) + for( ; i >= 8; i -= 8 ) + { + MULADDC_INIT + MULADDC_HUIT + MULADDC_STOP + } + + for( ; i > 0; i-- ) + { + MULADDC_INIT + MULADDC_CORE + MULADDC_STOP + } +#else /* MULADDC_HUIT */ + for( ; i >= 16; i -= 16 ) + { + MULADDC_INIT + MULADDC_CORE MULADDC_CORE + MULADDC_CORE MULADDC_CORE + MULADDC_CORE MULADDC_CORE + MULADDC_CORE MULADDC_CORE + + MULADDC_CORE MULADDC_CORE + MULADDC_CORE MULADDC_CORE + MULADDC_CORE MULADDC_CORE + MULADDC_CORE MULADDC_CORE + MULADDC_STOP + } + + for( ; i >= 8; i -= 8 ) + { + MULADDC_INIT + MULADDC_CORE MULADDC_CORE + MULADDC_CORE MULADDC_CORE + + MULADDC_CORE MULADDC_CORE + MULADDC_CORE MULADDC_CORE + MULADDC_STOP + } + + for( ; i > 0; i-- ) + { + MULADDC_INIT + MULADDC_CORE + MULADDC_STOP + } +#endif /* MULADDC_HUIT */ + + t++; + + do { + *d += c; c = ( *d < c ); d++; + } + while( c != 0 ); +} + +/* + * Baseline multiplication: X = A * B (HAC 14.12) + */ +int mbedtls_mpi_mul_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B ) +{ + int ret; + size_t i, j; + mbedtls_mpi TA, TB; + + mbedtls_mpi_init( &TA ); mbedtls_mpi_init( &TB ); + + if( X == A ) { MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TA, A ) ); A = &TA; } + if( X == B ) { MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, B ) ); B = &TB; } + + for( i = A->n; i > 0; i-- ) + if( A->p[i - 1] != 0 ) + break; + + for( j = B->n; j > 0; j-- ) + if( B->p[j - 1] != 0 ) + break; + + MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i + j ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) ); + + for( i++; j > 0; j-- ) + mpi_mul_hlp( i - 1, A->p, X->p + j - 1, B->p[j - 1] ); + + X->s = A->s * B->s; + +cleanup: + + mbedtls_mpi_free( &TB ); mbedtls_mpi_free( &TA ); + + return( ret ); +} + +/* + * Baseline multiplication: X = A * b + */ +int mbedtls_mpi_mul_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_uint b ) +{ + mbedtls_mpi _B; + mbedtls_mpi_uint p[1]; + + _B.s = 1; + _B.n = 1; + _B.p = p; + p[0] = b; + + return( mbedtls_mpi_mul_mpi( X, A, &_B ) ); +} + +/* + * Unsigned integer divide - double mbedtls_mpi_uint dividend, u1/u0, and + * mbedtls_mpi_uint divisor, d + */ +static mbedtls_mpi_uint mbedtls_int_div_int( mbedtls_mpi_uint u1, + mbedtls_mpi_uint u0, mbedtls_mpi_uint d, mbedtls_mpi_uint *r ) +{ +#if defined(MBEDTLS_HAVE_UDBL) + mbedtls_t_udbl dividend, quotient; +#else + const mbedtls_mpi_uint radix = (mbedtls_mpi_uint) 1 << biH; + const mbedtls_mpi_uint uint_halfword_mask = ( (mbedtls_mpi_uint) 1 << biH ) - 1; + mbedtls_mpi_uint d0, d1, q0, q1, rAX, r0, quotient; + mbedtls_mpi_uint u0_msw, u0_lsw; + size_t s; +#endif + + /* + * Check for overflow + */ + if( 0 == d || u1 >= d ) + { + if (r != NULL) *r = ~0; + + return ( ~0 ); + } + +#if defined(MBEDTLS_HAVE_UDBL) + dividend = (mbedtls_t_udbl) u1 << biL; + dividend |= (mbedtls_t_udbl) u0; + quotient = dividend / d; + if( quotient > ( (mbedtls_t_udbl) 1 << biL ) - 1 ) + quotient = ( (mbedtls_t_udbl) 1 << biL ) - 1; + + if( r != NULL ) + *r = (mbedtls_mpi_uint)( dividend - (quotient * d ) ); + + return (mbedtls_mpi_uint) quotient; +#else + + /* + * Algorithm D, Section 4.3.1 - The Art of Computer Programming + * Vol. 2 - Seminumerical Algorithms, Knuth + */ + + /* + * Normalize the divisor, d, and dividend, u0, u1 + */ + s = mbedtls_clz( d ); + d = d << s; + + u1 = u1 << s; + u1 |= ( u0 >> ( biL - s ) ) & ( -(mbedtls_mpi_sint)s >> ( biL - 1 ) ); + u0 = u0 << s; + + d1 = d >> biH; + d0 = d & uint_halfword_mask; + + u0_msw = u0 >> biH; + u0_lsw = u0 & uint_halfword_mask; + + /* + * Find the first quotient and remainder + */ + q1 = u1 / d1; + r0 = u1 - d1 * q1; + + while( q1 >= radix || ( q1 * d0 > radix * r0 + u0_msw ) ) + { + q1 -= 1; + r0 += d1; + + if ( r0 >= radix ) break; + } + + rAX = ( u1 * radix ) + ( u0_msw - q1 * d ); + q0 = rAX / d1; + r0 = rAX - q0 * d1; + + while( q0 >= radix || ( q0 * d0 > radix * r0 + u0_lsw ) ) + { + q0 -= 1; + r0 += d1; + + if ( r0 >= radix ) break; + } + + if (r != NULL) + *r = ( rAX * radix + u0_lsw - q0 * d ) >> s; + + quotient = q1 * radix + q0; + + return quotient; +#endif +} + +/* + * Division by mbedtls_mpi: A = Q * B + R (HAC 14.20) + */ +int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B ) +{ + int ret; + size_t i, n, t, k; + mbedtls_mpi X, Y, Z, T1, T2; + + if( mbedtls_mpi_cmp_int( B, 0 ) == 0 ) + return( MBEDTLS_ERR_MPI_DIVISION_BY_ZERO ); + + mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); + mbedtls_mpi_init( &T1 ); mbedtls_mpi_init( &T2 ); + + if( mbedtls_mpi_cmp_abs( A, B ) < 0 ) + { + if( Q != NULL ) MBEDTLS_MPI_CHK( mbedtls_mpi_lset( Q, 0 ) ); + if( R != NULL ) MBEDTLS_MPI_CHK( mbedtls_mpi_copy( R, A ) ); + return( 0 ); + } + + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &X, A ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Y, B ) ); + X.s = Y.s = 1; + + MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &Z, A->n + 2 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &Z, 0 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T1, 2 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T2, 3 ) ); + + k = mbedtls_mpi_bitlen( &Y ) % biL; + if( k < biL - 1 ) + { + k = biL - 1 - k; + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &X, k ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &Y, k ) ); + } + else k = 0; + + n = X.n - 1; + t = Y.n - 1; + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &Y, biL * ( n - t ) ) ); + + while( mbedtls_mpi_cmp_mpi( &X, &Y ) >= 0 ) + { + Z.p[n - t]++; + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &X, &X, &Y ) ); + } + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &Y, biL * ( n - t ) ) ); + + for( i = n; i > t ; i-- ) + { + if( X.p[i] >= Y.p[t] ) + Z.p[i - t - 1] = ~0; + else + { + Z.p[i - t - 1] = mbedtls_int_div_int( X.p[i], X.p[i - 1], + Y.p[t], NULL); + } + + Z.p[i - t - 1]++; + do + { + Z.p[i - t - 1]--; + + MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &T1, 0 ) ); + T1.p[0] = ( t < 1 ) ? 0 : Y.p[t - 1]; + T1.p[1] = Y.p[t]; + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T1, &T1, Z.p[i - t - 1] ) ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &T2, 0 ) ); + T2.p[0] = ( i < 2 ) ? 0 : X.p[i - 2]; + T2.p[1] = ( i < 1 ) ? 0 : X.p[i - 1]; + T2.p[2] = X.p[i]; + } + while( mbedtls_mpi_cmp_mpi( &T1, &T2 ) > 0 ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T1, &Y, Z.p[i - t - 1] ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &T1, biL * ( i - t - 1 ) ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &X, &X, &T1 ) ); + + if( mbedtls_mpi_cmp_int( &X, 0 ) < 0 ) + { + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &T1, &Y ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &T1, biL * ( i - t - 1 ) ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &X, &X, &T1 ) ); + Z.p[i - t - 1]--; + } + } + + if( Q != NULL ) + { + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( Q, &Z ) ); + Q->s = A->s * B->s; + } + + if( R != NULL ) + { + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &X, k ) ); + X.s = A->s; + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( R, &X ) ); + + if( mbedtls_mpi_cmp_int( R, 0 ) == 0 ) + R->s = 1; + } + +cleanup: + + mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); + mbedtls_mpi_free( &T1 ); mbedtls_mpi_free( &T2 ); + + return( ret ); +} + +/* + * Division by int: A = Q * b + R + */ +int mbedtls_mpi_div_int( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, mbedtls_mpi_sint b ) +{ + mbedtls_mpi _B; + mbedtls_mpi_uint p[1]; + + p[0] = ( b < 0 ) ? -b : b; + _B.s = ( b < 0 ) ? -1 : 1; + _B.n = 1; + _B.p = p; + + return( mbedtls_mpi_div_mpi( Q, R, A, &_B ) ); +} + +/* + * Modulo: R = A mod B + */ +int mbedtls_mpi_mod_mpi( mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B ) +{ + int ret; + + if( mbedtls_mpi_cmp_int( B, 0 ) < 0 ) + return( MBEDTLS_ERR_MPI_NEGATIVE_VALUE ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( NULL, R, A, B ) ); + + while( mbedtls_mpi_cmp_int( R, 0 ) < 0 ) + MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( R, R, B ) ); + + while( mbedtls_mpi_cmp_mpi( R, B ) >= 0 ) + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( R, R, B ) ); + +cleanup: + + return( ret ); +} + +/* + * Modulo: r = A mod b + */ +int mbedtls_mpi_mod_int( mbedtls_mpi_uint *r, const mbedtls_mpi *A, mbedtls_mpi_sint b ) +{ + size_t i; + mbedtls_mpi_uint x, y, z; + + if( b == 0 ) + return( MBEDTLS_ERR_MPI_DIVISION_BY_ZERO ); + + if( b < 0 ) + return( MBEDTLS_ERR_MPI_NEGATIVE_VALUE ); + + /* + * handle trivial cases + */ + if( b == 1 ) + { + *r = 0; + return( 0 ); + } + + if( b == 2 ) + { + *r = A->p[0] & 1; + return( 0 ); + } + + /* + * general case + */ + for( i = A->n, y = 0; i > 0; i-- ) + { + x = A->p[i - 1]; + y = ( y << biH ) | ( x >> biH ); + z = y / b; + y -= z * b; + + x <<= biH; + y = ( y << biH ) | ( x >> biH ); + z = y / b; + y -= z * b; + } + + /* + * If A is negative, then the current y represents a negative value. + * Flipping it to the positive side. + */ + if( A->s < 0 && y != 0 ) + y = b - y; + + *r = y; + + return( 0 ); +} + +/* + * Fast Montgomery initialization (thanks to Tom St Denis) + */ +static void mpi_montg_init( mbedtls_mpi_uint *mm, const mbedtls_mpi *N ) +{ + mbedtls_mpi_uint x, m0 = N->p[0]; + unsigned int i; + + x = m0; + x += ( ( m0 + 2 ) & 4 ) << 1; + + for( i = biL; i >= 8; i /= 2 ) + x *= ( 2 - ( m0 * x ) ); + + *mm = ~x + 1; +} + +/* + * Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36) + */ +static int mpi_montmul( mbedtls_mpi *A, const mbedtls_mpi *B, const mbedtls_mpi *N, mbedtls_mpi_uint mm, + const mbedtls_mpi *T ) +{ + size_t i, n, m; + mbedtls_mpi_uint u0, u1, *d; + + if( T->n < N->n + 1 || T->p == NULL ) + return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); + + memset( T->p, 0, T->n * ciL ); + + d = T->p; + n = N->n; + m = ( B->n < n ) ? B->n : n; + + for( i = 0; i < n; i++ ) + { + /* + * T = (T + u0*B + u1*N) / 2^biL + */ + u0 = A->p[i]; + u1 = ( d[0] + u0 * B->p[0] ) * mm; + + mpi_mul_hlp( m, B->p, d, u0 ); + mpi_mul_hlp( n, N->p, d, u1 ); + + *d++ = u0; d[n + 1] = 0; + } + + memcpy( A->p, d, ( n + 1 ) * ciL ); + + if( mbedtls_mpi_cmp_abs( A, N ) >= 0 ) + mpi_sub_hlp( n, N->p, A->p ); + else + /* prevent timing attacks */ + mpi_sub_hlp( n, A->p, T->p ); + + return( 0 ); +} + +/* + * Montgomery reduction: A = A * R^-1 mod N + */ +static int mpi_montred( mbedtls_mpi *A, const mbedtls_mpi *N, mbedtls_mpi_uint mm, const mbedtls_mpi *T ) +{ + mbedtls_mpi_uint z = 1; + mbedtls_mpi U; + + U.n = U.s = (int) z; + U.p = &z; + + return( mpi_montmul( A, &U, N, mm, T ) ); +} + +/* + * Sliding-window exponentiation: X = A^E mod N (HAC 14.85) + */ +int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *E, const mbedtls_mpi *N, mbedtls_mpi *_RR ) +{ + int ret; + size_t wbits, wsize, one = 1; + size_t i, j, nblimbs; + size_t bufsize, nbits; + mbedtls_mpi_uint ei, mm, state; + mbedtls_mpi RR, T, W[ 2 << MBEDTLS_MPI_WINDOW_SIZE ], Apos; + int neg; + + if( mbedtls_mpi_cmp_int( N, 0 ) < 0 || ( N->p[0] & 1 ) == 0 ) + return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); + + if( mbedtls_mpi_cmp_int( E, 0 ) < 0 ) + return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); + + /* + * Init temps and window size + */ + mpi_montg_init( &mm, N ); + mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &T ); + mbedtls_mpi_init( &Apos ); + memset( W, 0, sizeof( W ) ); + + i = mbedtls_mpi_bitlen( E ); + + wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 : + ( i > 79 ) ? 4 : ( i > 23 ) ? 3 : 1; + + if( wsize > MBEDTLS_MPI_WINDOW_SIZE ) + wsize = MBEDTLS_MPI_WINDOW_SIZE; + + j = N->n + 1; + MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, j ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[1], j ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T, j * 2 ) ); + + /* + * Compensate for negative A (and correct at the end) + */ + neg = ( A->s == -1 ); + if( neg ) + { + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Apos, A ) ); + Apos.s = 1; + A = &Apos; + } + + /* + * If 1st call, pre-compute R^2 mod N + */ + if( _RR == NULL || _RR->p == NULL ) + { + MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &RR, 1 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &RR, N->n * 2 * biL ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &RR, &RR, N ) ); + + if( _RR != NULL ) + memcpy( _RR, &RR, sizeof( mbedtls_mpi ) ); + } + else + memcpy( &RR, _RR, sizeof( mbedtls_mpi ) ); + + /* + * W[1] = A * R^2 * R^-1 mod N = A * R mod N + */ + if( mbedtls_mpi_cmp_mpi( A, N ) >= 0 ) + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &W[1], A, N ) ); + else + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[1], A ) ); + + MBEDTLS_MPI_CHK( mpi_montmul( &W[1], &RR, N, mm, &T ) ); + + /* + * X = R^2 * R^-1 mod N = R mod N + */ + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, &RR ) ); + MBEDTLS_MPI_CHK( mpi_montred( X, N, mm, &T ) ); + + if( wsize > 1 ) + { + /* + * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1) + */ + j = one << ( wsize - 1 ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[j], N->n + 1 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[j], &W[1] ) ); + + for( i = 0; i < wsize - 1; i++ ) + MBEDTLS_MPI_CHK( mpi_montmul( &W[j], &W[j], N, mm, &T ) ); + + /* + * W[i] = W[i - 1] * W[1] + */ + for( i = j + 1; i < ( one << wsize ); i++ ) + { + MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[i], N->n + 1 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[i], &W[i - 1] ) ); + + MBEDTLS_MPI_CHK( mpi_montmul( &W[i], &W[1], N, mm, &T ) ); + } + } + + nblimbs = E->n; + bufsize = 0; + nbits = 0; + wbits = 0; + state = 0; + + while( 1 ) + { + if( bufsize == 0 ) + { + if( nblimbs == 0 ) + break; + + nblimbs--; + + bufsize = sizeof( mbedtls_mpi_uint ) << 3; + } + + bufsize--; + + ei = (E->p[nblimbs] >> bufsize) & 1; + + /* + * skip leading 0s + */ + if( ei == 0 && state == 0 ) + continue; + + if( ei == 0 && state == 1 ) + { + /* + * out of window, square X + */ + MBEDTLS_MPI_CHK( mpi_montmul( X, X, N, mm, &T ) ); + continue; + } + + /* + * add ei to current window + */ + state = 2; + + nbits++; + wbits |= ( ei << ( wsize - nbits ) ); + + if( nbits == wsize ) + { + /* + * X = X^wsize R^-1 mod N + */ + for( i = 0; i < wsize; i++ ) + MBEDTLS_MPI_CHK( mpi_montmul( X, X, N, mm, &T ) ); + + /* + * X = X * W[wbits] R^-1 mod N + */ + MBEDTLS_MPI_CHK( mpi_montmul( X, &W[wbits], N, mm, &T ) ); + + state--; + nbits = 0; + wbits = 0; + } + } + + /* + * process the remaining bits + */ + for( i = 0; i < nbits; i++ ) + { + MBEDTLS_MPI_CHK( mpi_montmul( X, X, N, mm, &T ) ); + + wbits <<= 1; + + if( ( wbits & ( one << wsize ) ) != 0 ) + MBEDTLS_MPI_CHK( mpi_montmul( X, &W[1], N, mm, &T ) ); + } + + /* + * X = A^E * R * R^-1 mod N = A^E mod N + */ + MBEDTLS_MPI_CHK( mpi_montred( X, N, mm, &T ) ); + + if( neg ) + { + X->s = -1; + MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( X, N, X ) ); + } + +cleanup: + + for( i = ( one << ( wsize - 1 ) ); i < ( one << wsize ); i++ ) + mbedtls_mpi_free( &W[i] ); + + mbedtls_mpi_free( &W[1] ); mbedtls_mpi_free( &T ); mbedtls_mpi_free( &Apos ); + + if( _RR == NULL || _RR->p == NULL ) + mbedtls_mpi_free( &RR ); + + return( ret ); +} + +/* + * Greatest common divisor: G = gcd(A, B) (HAC 14.54) + */ +int mbedtls_mpi_gcd( mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B ) +{ + int ret; + size_t lz, lzt; + mbedtls_mpi TG, TA, TB; + + mbedtls_mpi_init( &TG ); mbedtls_mpi_init( &TA ); mbedtls_mpi_init( &TB ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TA, A ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, B ) ); + + lz = mbedtls_mpi_lsb( &TA ); + lzt = mbedtls_mpi_lsb( &TB ); + + if( lzt < lz ) + lz = lzt; + + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TA, lz ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TB, lz ) ); + + TA.s = TB.s = 1; + + while( mbedtls_mpi_cmp_int( &TA, 0 ) != 0 ) + { + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TA, mbedtls_mpi_lsb( &TA ) ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TB, mbedtls_mpi_lsb( &TB ) ) ); + + if( mbedtls_mpi_cmp_mpi( &TA, &TB ) >= 0 ) + { + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( &TA, &TA, &TB ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TA, 1 ) ); + } + else + { + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( &TB, &TB, &TA ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TB, 1 ) ); + } + } + + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &TB, lz ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( G, &TB ) ); + +cleanup: + + mbedtls_mpi_free( &TG ); mbedtls_mpi_free( &TA ); mbedtls_mpi_free( &TB ); + + return( ret ); +} + +/* + * Fill X with size bytes of random. + * + * Use a temporary bytes representation to make sure the result is the same + * regardless of the platform endianness (useful when f_rng is actually + * deterministic, eg for tests). + */ +int mbedtls_mpi_fill_random( mbedtls_mpi *X, size_t size, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + unsigned char buf[MBEDTLS_MPI_MAX_SIZE]; + + if( size > MBEDTLS_MPI_MAX_SIZE ) + return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); + + MBEDTLS_MPI_CHK( f_rng( p_rng, buf, size ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( X, buf, size ) ); + +cleanup: + return( ret ); +} + +/* + * Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64) + */ +int mbedtls_mpi_inv_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *N ) +{ + int ret; + mbedtls_mpi G, TA, TU, U1, U2, TB, TV, V1, V2; + + if( mbedtls_mpi_cmp_int( N, 0 ) <= 0 ) + return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); + + mbedtls_mpi_init( &TA ); mbedtls_mpi_init( &TU ); mbedtls_mpi_init( &U1 ); mbedtls_mpi_init( &U2 ); + mbedtls_mpi_init( &G ); mbedtls_mpi_init( &TB ); mbedtls_mpi_init( &TV ); + mbedtls_mpi_init( &V1 ); mbedtls_mpi_init( &V2 ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, A, N ) ); + + if( mbedtls_mpi_cmp_int( &G, 1 ) != 0 ) + { + ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE; + goto cleanup; + } + + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &TA, A, N ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TU, &TA ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, N ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TV, N ) ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &U1, 1 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &U2, 0 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &V1, 0 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &V2, 1 ) ); + + do + { + while( ( TU.p[0] & 1 ) == 0 ) + { + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TU, 1 ) ); + + if( ( U1.p[0] & 1 ) != 0 || ( U2.p[0] & 1 ) != 0 ) + { + MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &U1, &U1, &TB ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &U2, &U2, &TA ) ); + } + + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &U1, 1 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &U2, 1 ) ); + } + + while( ( TV.p[0] & 1 ) == 0 ) + { + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TV, 1 ) ); + + if( ( V1.p[0] & 1 ) != 0 || ( V2.p[0] & 1 ) != 0 ) + { + MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &V1, &V1, &TB ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &V2, &V2, &TA ) ); + } + + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &V1, 1 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &V2, 1 ) ); + } + + if( mbedtls_mpi_cmp_mpi( &TU, &TV ) >= 0 ) + { + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &TU, &TU, &TV ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &U1, &U1, &V1 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &U2, &U2, &V2 ) ); + } + else + { + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &TV, &TV, &TU ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &V1, &V1, &U1 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &V2, &V2, &U2 ) ); + } + } + while( mbedtls_mpi_cmp_int( &TU, 0 ) != 0 ); + + while( mbedtls_mpi_cmp_int( &V1, 0 ) < 0 ) + MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &V1, &V1, N ) ); + + while( mbedtls_mpi_cmp_mpi( &V1, N ) >= 0 ) + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &V1, &V1, N ) ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, &V1 ) ); + +cleanup: + + mbedtls_mpi_free( &TA ); mbedtls_mpi_free( &TU ); mbedtls_mpi_free( &U1 ); mbedtls_mpi_free( &U2 ); + mbedtls_mpi_free( &G ); mbedtls_mpi_free( &TB ); mbedtls_mpi_free( &TV ); + mbedtls_mpi_free( &V1 ); mbedtls_mpi_free( &V2 ); + + return( ret ); +} + +#if defined(MBEDTLS_GENPRIME) + +static const int small_prime[] = +{ + 3, 5, 7, 11, 13, 17, 19, 23, + 29, 31, 37, 41, 43, 47, 53, 59, + 61, 67, 71, 73, 79, 83, 89, 97, + 101, 103, 107, 109, 113, 127, 131, 137, + 139, 149, 151, 157, 163, 167, 173, 179, + 181, 191, 193, 197, 199, 211, 223, 227, + 229, 233, 239, 241, 251, 257, 263, 269, + 271, 277, 281, 283, 293, 307, 311, 313, + 317, 331, 337, 347, 349, 353, 359, 367, + 373, 379, 383, 389, 397, 401, 409, 419, + 421, 431, 433, 439, 443, 449, 457, 461, + 463, 467, 479, 487, 491, 499, 503, 509, + 521, 523, 541, 547, 557, 563, 569, 571, + 577, 587, 593, 599, 601, 607, 613, 617, + 619, 631, 641, 643, 647, 653, 659, 661, + 673, 677, 683, 691, 701, 709, 719, 727, + 733, 739, 743, 751, 757, 761, 769, 773, + 787, 797, 809, 811, 821, 823, 827, 829, + 839, 853, 857, 859, 863, 877, 881, 883, + 887, 907, 911, 919, 929, 937, 941, 947, + 953, 967, 971, 977, 983, 991, 997, -103 +}; + +/* + * Small divisors test (X must be positive) + * + * Return values: + * 0: no small factor (possible prime, more tests needed) + * 1: certain prime + * MBEDTLS_ERR_MPI_NOT_ACCEPTABLE: certain non-prime + * other negative: error + */ +static int mpi_check_small_factors( const mbedtls_mpi *X ) +{ + int ret = 0; + size_t i; + mbedtls_mpi_uint r; + + if( ( X->p[0] & 1 ) == 0 ) + return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE ); + + for( i = 0; small_prime[i] > 0; i++ ) + { + if( mbedtls_mpi_cmp_int( X, small_prime[i] ) <= 0 ) + return( 1 ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, small_prime[i] ) ); + + if( r == 0 ) + return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE ); + } + +cleanup: + return( ret ); +} + +/* + * Miller-Rabin pseudo-primality test (HAC 4.24) + */ +static int mpi_miller_rabin( const mbedtls_mpi *X, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret, count; + size_t i, j, k, n, s; + mbedtls_mpi W, R, T, A, RR; + + mbedtls_mpi_init( &W ); mbedtls_mpi_init( &R ); mbedtls_mpi_init( &T ); mbedtls_mpi_init( &A ); + mbedtls_mpi_init( &RR ); + + /* + * W = |X| - 1 + * R = W >> lsb( W ) + */ + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &W, X, 1 ) ); + s = mbedtls_mpi_lsb( &W ); + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R, &W ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &R, s ) ); + + i = mbedtls_mpi_bitlen( X ); + /* + * HAC, table 4.4 + */ + n = ( ( i >= 1300 ) ? 2 : ( i >= 850 ) ? 3 : + ( i >= 650 ) ? 4 : ( i >= 350 ) ? 8 : + ( i >= 250 ) ? 12 : ( i >= 150 ) ? 18 : 27 ); + + for( i = 0; i < n; i++ ) + { + /* + * pick a random A, 1 < A < |X| - 1 + */ + MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &A, X->n * ciL, f_rng, p_rng ) ); + + if( mbedtls_mpi_cmp_mpi( &A, &W ) >= 0 ) + { + j = mbedtls_mpi_bitlen( &A ) - mbedtls_mpi_bitlen( &W ); + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &A, j + 1 ) ); + } + A.p[0] |= 3; + + count = 0; + do { + MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &A, X->n * ciL, f_rng, p_rng ) ); + + j = mbedtls_mpi_bitlen( &A ); + k = mbedtls_mpi_bitlen( &W ); + if (j > k) { + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &A, j - k ) ); + } + + if (count++ > 30) { + return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE; + } + + } while ( mbedtls_mpi_cmp_mpi( &A, &W ) >= 0 || + mbedtls_mpi_cmp_int( &A, 1 ) <= 0 ); + + /* + * A = A^R mod |X| + */ + MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &A, &A, &R, X, &RR ) ); + + if( mbedtls_mpi_cmp_mpi( &A, &W ) == 0 || + mbedtls_mpi_cmp_int( &A, 1 ) == 0 ) + continue; + + j = 1; + while( j < s && mbedtls_mpi_cmp_mpi( &A, &W ) != 0 ) + { + /* + * A = A * A mod |X| + */ + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &A, &A ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &A, &T, X ) ); + + if( mbedtls_mpi_cmp_int( &A, 1 ) == 0 ) + break; + + j++; + } + + /* + * not prime if A != |X| - 1 or A == 1 + */ + if( mbedtls_mpi_cmp_mpi( &A, &W ) != 0 || + mbedtls_mpi_cmp_int( &A, 1 ) == 0 ) + { + ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE; + break; + } + } + +cleanup: + mbedtls_mpi_free( &W ); mbedtls_mpi_free( &R ); mbedtls_mpi_free( &T ); mbedtls_mpi_free( &A ); + mbedtls_mpi_free( &RR ); + + return( ret ); +} + +/* + * Pseudo-primality test: small factors, then Miller-Rabin + */ +int mbedtls_mpi_is_prime( const mbedtls_mpi *X, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + mbedtls_mpi XX; + + XX.s = 1; + XX.n = X->n; + XX.p = X->p; + + if( mbedtls_mpi_cmp_int( &XX, 0 ) == 0 || + mbedtls_mpi_cmp_int( &XX, 1 ) == 0 ) + return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE ); + + if( mbedtls_mpi_cmp_int( &XX, 2 ) == 0 ) + return( 0 ); + + if( ( ret = mpi_check_small_factors( &XX ) ) != 0 ) + { + if( ret == 1 ) + return( 0 ); + + return( ret ); + } + + return( mpi_miller_rabin( &XX, f_rng, p_rng ) ); +} + +/* + * Prime number generation + */ +int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int dh_flag, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + size_t k, n; + mbedtls_mpi_uint r; + mbedtls_mpi Y; + + if( nbits < 3 || nbits > MBEDTLS_MPI_MAX_BITS ) + return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA ); + + mbedtls_mpi_init( &Y ); + + n = BITS_TO_LIMBS( nbits ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( X, n * ciL, f_rng, p_rng ) ); + + k = mbedtls_mpi_bitlen( X ); + if( k > nbits ) MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( X, k - nbits + 1 ) ); + + mbedtls_mpi_set_bit( X, nbits-1, 1 ); + + X->p[0] |= 1; + + if( dh_flag == 0 ) + { + while( ( ret = mbedtls_mpi_is_prime( X, f_rng, p_rng ) ) != 0 ) + { + if( ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE ) + goto cleanup; + + MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 2 ) ); + } + } + else + { + /* + * An necessary condition for Y and X = 2Y + 1 to be prime + * is X = 2 mod 3 (which is equivalent to Y = 2 mod 3). + * Make sure it is satisfied, while keeping X = 3 mod 4 + */ + + X->p[0] |= 2; + + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, 3 ) ); + if( r == 0 ) + MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 8 ) ); + else if( r == 1 ) + MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 4 ) ); + + /* Set Y = (X-1) / 2, which is X / 2 because X is odd */ + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Y, X ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &Y, 1 ) ); + + while( 1 ) + { + /* + * First, check small factors for X and Y + * before doing Miller-Rabin on any of them + */ + if( ( ret = mpi_check_small_factors( X ) ) == 0 && + ( ret = mpi_check_small_factors( &Y ) ) == 0 && + ( ret = mpi_miller_rabin( X, f_rng, p_rng ) ) == 0 && + ( ret = mpi_miller_rabin( &Y, f_rng, p_rng ) ) == 0 ) + { + break; + } + + if( ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE ) + goto cleanup; + + /* + * Next candidates. We want to preserve Y = (X-1) / 2 and + * Y = 1 mod 2 and Y = 2 mod 3 (eq X = 3 mod 4 and X = 2 mod 3) + * so up Y by 6 and X by 12. + */ + MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 12 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &Y, &Y, 6 ) ); + } + } + +cleanup: + + mbedtls_mpi_free( &Y ); + + return( ret ); +} + +#endif /* MBEDTLS_GENPRIME */ + +#if defined(MBEDTLS_SELF_TEST) + +#define GCD_PAIR_COUNT 3 + +static const int gcd_pairs[GCD_PAIR_COUNT][3] = +{ + { 693, 609, 21 }, + { 1764, 868, 28 }, + { 768454923, 542167814, 1 } +}; + +/* + * Checkup routine + */ +int mbedtls_mpi_self_test( int verbose ) +{ + int ret, i; + mbedtls_mpi A, E, N, X, Y, U, V; + + mbedtls_mpi_init( &A ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &N ); mbedtls_mpi_init( &X ); + mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &U ); mbedtls_mpi_init( &V ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &A, 16, + "EFE021C2645FD1DC586E69184AF4A31E" \ + "D5F53E93B5F123FA41680867BA110131" \ + "944FE7952E2517337780CB0DB80E61AA" \ + "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &E, 16, + "B2E7EFD37075B9F03FF989C7C5051C20" \ + "34D2A323810251127E7BF8625A4F49A5" \ + "F3E27F4DA8BD59C47D6DAABA4C8127BD" \ + "5B5C25763222FEFCCFC38B832366C29E" ) ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &N, 16, + "0066A198186C18C10B2F5ED9B522752A" \ + "9830B69916E535C8F047518A889A43A5" \ + "94B6BED27A168D31D4A52F88925AA8F5" ) ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &X, &A, &N ) ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &U, 16, + "602AB7ECA597A3D6B56FF9829A5E8B85" \ + "9E857EA95A03512E2BAE7391688D264A" \ + "A5663B0341DB9CCFD2C4C5F421FEC814" \ + "8001B72E848A38CAE1C65F78E56ABDEF" \ + "E12D3C039B8A02D6BE593F0BBBDA56F1" \ + "ECF677152EF804370C1A305CAF3B5BF1" \ + "30879B56C61DE584A0F53A2447A51E" ) ); + + if( verbose != 0 ) + mbedtls_printf( " MPI test #1 (mul_mpi): " ); + + if( mbedtls_mpi_cmp_mpi( &X, &U ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + ret = 1; + goto cleanup; + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( &X, &Y, &A, &N ) ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &U, 16, + "256567336059E52CAE22925474705F39A94" ) ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &V, 16, + "6613F26162223DF488E9CD48CC132C7A" \ + "0AC93C701B001B092E4E5B9F73BCD27B" \ + "9EE50D0657C77F374E903CDFA4C642" ) ); + + if( verbose != 0 ) + mbedtls_printf( " MPI test #2 (div_mpi): " ); + + if( mbedtls_mpi_cmp_mpi( &X, &U ) != 0 || + mbedtls_mpi_cmp_mpi( &Y, &V ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + ret = 1; + goto cleanup; + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &X, &A, &E, &N, NULL ) ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &U, 16, + "36E139AEA55215609D2816998ED020BB" \ + "BD96C37890F65171D948E9BC7CBAA4D9" \ + "325D24D6A3C12710F10A09FA08AB87" ) ); + + if( verbose != 0 ) + mbedtls_printf( " MPI test #3 (exp_mod): " ); + + if( mbedtls_mpi_cmp_mpi( &X, &U ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + ret = 1; + goto cleanup; + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &X, &A, &N ) ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &U, 16, + "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \ + "C3DBA76456363A10869622EAC2DD84EC" \ + "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) ); + + if( verbose != 0 ) + mbedtls_printf( " MPI test #4 (inv_mod): " ); + + if( mbedtls_mpi_cmp_mpi( &X, &U ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + ret = 1; + goto cleanup; + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + + if( verbose != 0 ) + mbedtls_printf( " MPI test #5 (simple gcd): " ); + + for( i = 0; i < GCD_PAIR_COUNT; i++ ) + { + MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &X, gcd_pairs[i][0] ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &Y, gcd_pairs[i][1] ) ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &A, &X, &Y ) ); + + if( mbedtls_mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed at %d\n", i ); + + ret = 1; + goto cleanup; + } + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + +cleanup: + + if( ret != 0 && verbose != 0 ) + mbedtls_printf( "Unexpected error, return code = %08X\n", ret ); + + mbedtls_mpi_free( &A ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &N ); mbedtls_mpi_free( &X ); + mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &U ); mbedtls_mpi_free( &V ); + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + + return( ret ); +} + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_BIGNUM_C */ + diff --git a/security/mbedtls/src/blowfish.c b/security/mbedtls/src/blowfish.c new file mode 100644 index 0000000000..9003f0dfeb --- /dev/null +++ b/security/mbedtls/src/blowfish.c @@ -0,0 +1,656 @@ +/* + * Blowfish implementation + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +/* + * The Blowfish block cipher was designed by Bruce Schneier in 1993. + * http://www.schneier.com/blowfish.html + * http://en.wikipedia.org/wiki/Blowfish_%28cipher%29 + * + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_BLOWFISH_C) + +#include "mbedtls/blowfish.h" + +#include + +#if !defined(MBEDTLS_BLOWFISH_ALT) + +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0; +} + +/* + * 32-bit integer manipulation macros (big endian) + */ +#ifndef GET_UINT32_BE +#define GET_UINT32_BE(n,b,i) \ +{ \ + (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ + | ( (uint32_t) (b)[(i) + 1] << 16 ) \ + | ( (uint32_t) (b)[(i) + 2] << 8 ) \ + | ( (uint32_t) (b)[(i) + 3] ); \ +} +#endif + +#ifndef PUT_UINT32_BE +#define PUT_UINT32_BE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) ); \ +} +#endif + +static const uint32_t P[MBEDTLS_BLOWFISH_ROUNDS + 2] = { + 0x243F6A88L, 0x85A308D3L, 0x13198A2EL, 0x03707344L, + 0xA4093822L, 0x299F31D0L, 0x082EFA98L, 0xEC4E6C89L, + 0x452821E6L, 0x38D01377L, 0xBE5466CFL, 0x34E90C6CL, + 0xC0AC29B7L, 0xC97C50DDL, 0x3F84D5B5L, 0xB5470917L, + 0x9216D5D9L, 0x8979FB1BL +}; + +/* declarations of data at the end of this file */ +static const uint32_t S[4][256]; + +static uint32_t F( mbedtls_blowfish_context *ctx, uint32_t x ) +{ + unsigned short a, b, c, d; + uint32_t y; + + d = (unsigned short)(x & 0xFF); + x >>= 8; + c = (unsigned short)(x & 0xFF); + x >>= 8; + b = (unsigned short)(x & 0xFF); + x >>= 8; + a = (unsigned short)(x & 0xFF); + y = ctx->S[0][a] + ctx->S[1][b]; + y = y ^ ctx->S[2][c]; + y = y + ctx->S[3][d]; + + return( y ); +} + +static void blowfish_enc( mbedtls_blowfish_context *ctx, uint32_t *xl, uint32_t *xr ) +{ + uint32_t Xl, Xr, temp; + short i; + + Xl = *xl; + Xr = *xr; + + for( i = 0; i < MBEDTLS_BLOWFISH_ROUNDS; ++i ) + { + Xl = Xl ^ ctx->P[i]; + Xr = F( ctx, Xl ) ^ Xr; + + temp = Xl; + Xl = Xr; + Xr = temp; + } + + temp = Xl; + Xl = Xr; + Xr = temp; + + Xr = Xr ^ ctx->P[MBEDTLS_BLOWFISH_ROUNDS]; + Xl = Xl ^ ctx->P[MBEDTLS_BLOWFISH_ROUNDS + 1]; + + *xl = Xl; + *xr = Xr; +} + +static void blowfish_dec( mbedtls_blowfish_context *ctx, uint32_t *xl, uint32_t *xr ) +{ + uint32_t Xl, Xr, temp; + short i; + + Xl = *xl; + Xr = *xr; + + for( i = MBEDTLS_BLOWFISH_ROUNDS + 1; i > 1; --i ) + { + Xl = Xl ^ ctx->P[i]; + Xr = F( ctx, Xl ) ^ Xr; + + temp = Xl; + Xl = Xr; + Xr = temp; + } + + temp = Xl; + Xl = Xr; + Xr = temp; + + Xr = Xr ^ ctx->P[1]; + Xl = Xl ^ ctx->P[0]; + + *xl = Xl; + *xr = Xr; +} + +void mbedtls_blowfish_init( mbedtls_blowfish_context *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_blowfish_context ) ); +} + +void mbedtls_blowfish_free( mbedtls_blowfish_context *ctx ) +{ + if( ctx == NULL ) + return; + + mbedtls_zeroize( ctx, sizeof( mbedtls_blowfish_context ) ); +} + +/* + * Blowfish key schedule + */ +int mbedtls_blowfish_setkey( mbedtls_blowfish_context *ctx, const unsigned char *key, + unsigned int keybits ) +{ + unsigned int i, j, k; + uint32_t data, datal, datar; + + if( keybits < MBEDTLS_BLOWFISH_MIN_KEY_BITS || keybits > MBEDTLS_BLOWFISH_MAX_KEY_BITS || + ( keybits % 8 ) ) + { + return( MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH ); + } + + keybits >>= 3; + + for( i = 0; i < 4; i++ ) + { + for( j = 0; j < 256; j++ ) + ctx->S[i][j] = S[i][j]; + } + + j = 0; + for( i = 0; i < MBEDTLS_BLOWFISH_ROUNDS + 2; ++i ) + { + data = 0x00000000; + for( k = 0; k < 4; ++k ) + { + data = ( data << 8 ) | key[j++]; + if( j >= keybits ) + j = 0; + } + ctx->P[i] = P[i] ^ data; + } + + datal = 0x00000000; + datar = 0x00000000; + + for( i = 0; i < MBEDTLS_BLOWFISH_ROUNDS + 2; i += 2 ) + { + blowfish_enc( ctx, &datal, &datar ); + ctx->P[i] = datal; + ctx->P[i + 1] = datar; + } + + for( i = 0; i < 4; i++ ) + { + for( j = 0; j < 256; j += 2 ) + { + blowfish_enc( ctx, &datal, &datar ); + ctx->S[i][j] = datal; + ctx->S[i][j + 1] = datar; + } + } + return( 0 ); +} + +/* + * Blowfish-ECB block encryption/decryption + */ +int mbedtls_blowfish_crypt_ecb( mbedtls_blowfish_context *ctx, + int mode, + const unsigned char input[MBEDTLS_BLOWFISH_BLOCKSIZE], + unsigned char output[MBEDTLS_BLOWFISH_BLOCKSIZE] ) +{ + uint32_t X0, X1; + + GET_UINT32_BE( X0, input, 0 ); + GET_UINT32_BE( X1, input, 4 ); + + if( mode == MBEDTLS_BLOWFISH_DECRYPT ) + { + blowfish_dec( ctx, &X0, &X1 ); + } + else /* MBEDTLS_BLOWFISH_ENCRYPT */ + { + blowfish_enc( ctx, &X0, &X1 ); + } + + PUT_UINT32_BE( X0, output, 0 ); + PUT_UINT32_BE( X1, output, 4 ); + + return( 0 ); +} + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +/* + * Blowfish-CBC buffer encryption/decryption + */ +int mbedtls_blowfish_crypt_cbc( mbedtls_blowfish_context *ctx, + int mode, + size_t length, + unsigned char iv[MBEDTLS_BLOWFISH_BLOCKSIZE], + const unsigned char *input, + unsigned char *output ) +{ + int i; + unsigned char temp[MBEDTLS_BLOWFISH_BLOCKSIZE]; + + if( length % MBEDTLS_BLOWFISH_BLOCKSIZE ) + return( MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH ); + + if( mode == MBEDTLS_BLOWFISH_DECRYPT ) + { + while( length > 0 ) + { + memcpy( temp, input, MBEDTLS_BLOWFISH_BLOCKSIZE ); + mbedtls_blowfish_crypt_ecb( ctx, mode, input, output ); + + for( i = 0; i < MBEDTLS_BLOWFISH_BLOCKSIZE;i++ ) + output[i] = (unsigned char)( output[i] ^ iv[i] ); + + memcpy( iv, temp, MBEDTLS_BLOWFISH_BLOCKSIZE ); + + input += MBEDTLS_BLOWFISH_BLOCKSIZE; + output += MBEDTLS_BLOWFISH_BLOCKSIZE; + length -= MBEDTLS_BLOWFISH_BLOCKSIZE; + } + } + else + { + while( length > 0 ) + { + for( i = 0; i < MBEDTLS_BLOWFISH_BLOCKSIZE; i++ ) + output[i] = (unsigned char)( input[i] ^ iv[i] ); + + mbedtls_blowfish_crypt_ecb( ctx, mode, output, output ); + memcpy( iv, output, MBEDTLS_BLOWFISH_BLOCKSIZE ); + + input += MBEDTLS_BLOWFISH_BLOCKSIZE; + output += MBEDTLS_BLOWFISH_BLOCKSIZE; + length -= MBEDTLS_BLOWFISH_BLOCKSIZE; + } + } + + return( 0 ); +} +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +/* + * Blowfish CFB buffer encryption/decryption + */ +int mbedtls_blowfish_crypt_cfb64( mbedtls_blowfish_context *ctx, + int mode, + size_t length, + size_t *iv_off, + unsigned char iv[MBEDTLS_BLOWFISH_BLOCKSIZE], + const unsigned char *input, + unsigned char *output ) +{ + int c; + size_t n = *iv_off; + + if( mode == MBEDTLS_BLOWFISH_DECRYPT ) + { + while( length-- ) + { + if( n == 0 ) + mbedtls_blowfish_crypt_ecb( ctx, MBEDTLS_BLOWFISH_ENCRYPT, iv, iv ); + + c = *input++; + *output++ = (unsigned char)( c ^ iv[n] ); + iv[n] = (unsigned char) c; + + n = ( n + 1 ) % MBEDTLS_BLOWFISH_BLOCKSIZE; + } + } + else + { + while( length-- ) + { + if( n == 0 ) + mbedtls_blowfish_crypt_ecb( ctx, MBEDTLS_BLOWFISH_ENCRYPT, iv, iv ); + + iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ ); + + n = ( n + 1 ) % MBEDTLS_BLOWFISH_BLOCKSIZE; + } + } + + *iv_off = n; + + return( 0 ); +} +#endif /*MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +/* + * Blowfish CTR buffer encryption/decryption + */ +int mbedtls_blowfish_crypt_ctr( mbedtls_blowfish_context *ctx, + size_t length, + size_t *nc_off, + unsigned char nonce_counter[MBEDTLS_BLOWFISH_BLOCKSIZE], + unsigned char stream_block[MBEDTLS_BLOWFISH_BLOCKSIZE], + const unsigned char *input, + unsigned char *output ) +{ + int c, i; + size_t n = *nc_off; + + while( length-- ) + { + if( n == 0 ) { + mbedtls_blowfish_crypt_ecb( ctx, MBEDTLS_BLOWFISH_ENCRYPT, nonce_counter, + stream_block ); + + for( i = MBEDTLS_BLOWFISH_BLOCKSIZE; i > 0; i-- ) + if( ++nonce_counter[i - 1] != 0 ) + break; + } + c = *input++; + *output++ = (unsigned char)( c ^ stream_block[n] ); + + n = ( n + 1 ) % MBEDTLS_BLOWFISH_BLOCKSIZE; + } + + *nc_off = n; + + return( 0 ); +} +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +static const uint32_t S[4][256] = { + { 0xD1310BA6L, 0x98DFB5ACL, 0x2FFD72DBL, 0xD01ADFB7L, + 0xB8E1AFEDL, 0x6A267E96L, 0xBA7C9045L, 0xF12C7F99L, + 0x24A19947L, 0xB3916CF7L, 0x0801F2E2L, 0x858EFC16L, + 0x636920D8L, 0x71574E69L, 0xA458FEA3L, 0xF4933D7EL, + 0x0D95748FL, 0x728EB658L, 0x718BCD58L, 0x82154AEEL, + 0x7B54A41DL, 0xC25A59B5L, 0x9C30D539L, 0x2AF26013L, + 0xC5D1B023L, 0x286085F0L, 0xCA417918L, 0xB8DB38EFL, + 0x8E79DCB0L, 0x603A180EL, 0x6C9E0E8BL, 0xB01E8A3EL, + 0xD71577C1L, 0xBD314B27L, 0x78AF2FDAL, 0x55605C60L, + 0xE65525F3L, 0xAA55AB94L, 0x57489862L, 0x63E81440L, + 0x55CA396AL, 0x2AAB10B6L, 0xB4CC5C34L, 0x1141E8CEL, + 0xA15486AFL, 0x7C72E993L, 0xB3EE1411L, 0x636FBC2AL, + 0x2BA9C55DL, 0x741831F6L, 0xCE5C3E16L, 0x9B87931EL, + 0xAFD6BA33L, 0x6C24CF5CL, 0x7A325381L, 0x28958677L, + 0x3B8F4898L, 0x6B4BB9AFL, 0xC4BFE81BL, 0x66282193L, + 0x61D809CCL, 0xFB21A991L, 0x487CAC60L, 0x5DEC8032L, + 0xEF845D5DL, 0xE98575B1L, 0xDC262302L, 0xEB651B88L, + 0x23893E81L, 0xD396ACC5L, 0x0F6D6FF3L, 0x83F44239L, + 0x2E0B4482L, 0xA4842004L, 0x69C8F04AL, 0x9E1F9B5EL, + 0x21C66842L, 0xF6E96C9AL, 0x670C9C61L, 0xABD388F0L, + 0x6A51A0D2L, 0xD8542F68L, 0x960FA728L, 0xAB5133A3L, + 0x6EEF0B6CL, 0x137A3BE4L, 0xBA3BF050L, 0x7EFB2A98L, + 0xA1F1651DL, 0x39AF0176L, 0x66CA593EL, 0x82430E88L, + 0x8CEE8619L, 0x456F9FB4L, 0x7D84A5C3L, 0x3B8B5EBEL, + 0xE06F75D8L, 0x85C12073L, 0x401A449FL, 0x56C16AA6L, + 0x4ED3AA62L, 0x363F7706L, 0x1BFEDF72L, 0x429B023DL, + 0x37D0D724L, 0xD00A1248L, 0xDB0FEAD3L, 0x49F1C09BL, + 0x075372C9L, 0x80991B7BL, 0x25D479D8L, 0xF6E8DEF7L, + 0xE3FE501AL, 0xB6794C3BL, 0x976CE0BDL, 0x04C006BAL, + 0xC1A94FB6L, 0x409F60C4L, 0x5E5C9EC2L, 0x196A2463L, + 0x68FB6FAFL, 0x3E6C53B5L, 0x1339B2EBL, 0x3B52EC6FL, + 0x6DFC511FL, 0x9B30952CL, 0xCC814544L, 0xAF5EBD09L, + 0xBEE3D004L, 0xDE334AFDL, 0x660F2807L, 0x192E4BB3L, + 0xC0CBA857L, 0x45C8740FL, 0xD20B5F39L, 0xB9D3FBDBL, + 0x5579C0BDL, 0x1A60320AL, 0xD6A100C6L, 0x402C7279L, + 0x679F25FEL, 0xFB1FA3CCL, 0x8EA5E9F8L, 0xDB3222F8L, + 0x3C7516DFL, 0xFD616B15L, 0x2F501EC8L, 0xAD0552ABL, + 0x323DB5FAL, 0xFD238760L, 0x53317B48L, 0x3E00DF82L, + 0x9E5C57BBL, 0xCA6F8CA0L, 0x1A87562EL, 0xDF1769DBL, + 0xD542A8F6L, 0x287EFFC3L, 0xAC6732C6L, 0x8C4F5573L, + 0x695B27B0L, 0xBBCA58C8L, 0xE1FFA35DL, 0xB8F011A0L, + 0x10FA3D98L, 0xFD2183B8L, 0x4AFCB56CL, 0x2DD1D35BL, + 0x9A53E479L, 0xB6F84565L, 0xD28E49BCL, 0x4BFB9790L, + 0xE1DDF2DAL, 0xA4CB7E33L, 0x62FB1341L, 0xCEE4C6E8L, + 0xEF20CADAL, 0x36774C01L, 0xD07E9EFEL, 0x2BF11FB4L, + 0x95DBDA4DL, 0xAE909198L, 0xEAAD8E71L, 0x6B93D5A0L, + 0xD08ED1D0L, 0xAFC725E0L, 0x8E3C5B2FL, 0x8E7594B7L, + 0x8FF6E2FBL, 0xF2122B64L, 0x8888B812L, 0x900DF01CL, + 0x4FAD5EA0L, 0x688FC31CL, 0xD1CFF191L, 0xB3A8C1ADL, + 0x2F2F2218L, 0xBE0E1777L, 0xEA752DFEL, 0x8B021FA1L, + 0xE5A0CC0FL, 0xB56F74E8L, 0x18ACF3D6L, 0xCE89E299L, + 0xB4A84FE0L, 0xFD13E0B7L, 0x7CC43B81L, 0xD2ADA8D9L, + 0x165FA266L, 0x80957705L, 0x93CC7314L, 0x211A1477L, + 0xE6AD2065L, 0x77B5FA86L, 0xC75442F5L, 0xFB9D35CFL, + 0xEBCDAF0CL, 0x7B3E89A0L, 0xD6411BD3L, 0xAE1E7E49L, + 0x00250E2DL, 0x2071B35EL, 0x226800BBL, 0x57B8E0AFL, + 0x2464369BL, 0xF009B91EL, 0x5563911DL, 0x59DFA6AAL, + 0x78C14389L, 0xD95A537FL, 0x207D5BA2L, 0x02E5B9C5L, + 0x83260376L, 0x6295CFA9L, 0x11C81968L, 0x4E734A41L, + 0xB3472DCAL, 0x7B14A94AL, 0x1B510052L, 0x9A532915L, + 0xD60F573FL, 0xBC9BC6E4L, 0x2B60A476L, 0x81E67400L, + 0x08BA6FB5L, 0x571BE91FL, 0xF296EC6BL, 0x2A0DD915L, + 0xB6636521L, 0xE7B9F9B6L, 0xFF34052EL, 0xC5855664L, + 0x53B02D5DL, 0xA99F8FA1L, 0x08BA4799L, 0x6E85076AL }, + { 0x4B7A70E9L, 0xB5B32944L, 0xDB75092EL, 0xC4192623L, + 0xAD6EA6B0L, 0x49A7DF7DL, 0x9CEE60B8L, 0x8FEDB266L, + 0xECAA8C71L, 0x699A17FFL, 0x5664526CL, 0xC2B19EE1L, + 0x193602A5L, 0x75094C29L, 0xA0591340L, 0xE4183A3EL, + 0x3F54989AL, 0x5B429D65L, 0x6B8FE4D6L, 0x99F73FD6L, + 0xA1D29C07L, 0xEFE830F5L, 0x4D2D38E6L, 0xF0255DC1L, + 0x4CDD2086L, 0x8470EB26L, 0x6382E9C6L, 0x021ECC5EL, + 0x09686B3FL, 0x3EBAEFC9L, 0x3C971814L, 0x6B6A70A1L, + 0x687F3584L, 0x52A0E286L, 0xB79C5305L, 0xAA500737L, + 0x3E07841CL, 0x7FDEAE5CL, 0x8E7D44ECL, 0x5716F2B8L, + 0xB03ADA37L, 0xF0500C0DL, 0xF01C1F04L, 0x0200B3FFL, + 0xAE0CF51AL, 0x3CB574B2L, 0x25837A58L, 0xDC0921BDL, + 0xD19113F9L, 0x7CA92FF6L, 0x94324773L, 0x22F54701L, + 0x3AE5E581L, 0x37C2DADCL, 0xC8B57634L, 0x9AF3DDA7L, + 0xA9446146L, 0x0FD0030EL, 0xECC8C73EL, 0xA4751E41L, + 0xE238CD99L, 0x3BEA0E2FL, 0x3280BBA1L, 0x183EB331L, + 0x4E548B38L, 0x4F6DB908L, 0x6F420D03L, 0xF60A04BFL, + 0x2CB81290L, 0x24977C79L, 0x5679B072L, 0xBCAF89AFL, + 0xDE9A771FL, 0xD9930810L, 0xB38BAE12L, 0xDCCF3F2EL, + 0x5512721FL, 0x2E6B7124L, 0x501ADDE6L, 0x9F84CD87L, + 0x7A584718L, 0x7408DA17L, 0xBC9F9ABCL, 0xE94B7D8CL, + 0xEC7AEC3AL, 0xDB851DFAL, 0x63094366L, 0xC464C3D2L, + 0xEF1C1847L, 0x3215D908L, 0xDD433B37L, 0x24C2BA16L, + 0x12A14D43L, 0x2A65C451L, 0x50940002L, 0x133AE4DDL, + 0x71DFF89EL, 0x10314E55L, 0x81AC77D6L, 0x5F11199BL, + 0x043556F1L, 0xD7A3C76BL, 0x3C11183BL, 0x5924A509L, + 0xF28FE6EDL, 0x97F1FBFAL, 0x9EBABF2CL, 0x1E153C6EL, + 0x86E34570L, 0xEAE96FB1L, 0x860E5E0AL, 0x5A3E2AB3L, + 0x771FE71CL, 0x4E3D06FAL, 0x2965DCB9L, 0x99E71D0FL, + 0x803E89D6L, 0x5266C825L, 0x2E4CC978L, 0x9C10B36AL, + 0xC6150EBAL, 0x94E2EA78L, 0xA5FC3C53L, 0x1E0A2DF4L, + 0xF2F74EA7L, 0x361D2B3DL, 0x1939260FL, 0x19C27960L, + 0x5223A708L, 0xF71312B6L, 0xEBADFE6EL, 0xEAC31F66L, + 0xE3BC4595L, 0xA67BC883L, 0xB17F37D1L, 0x018CFF28L, + 0xC332DDEFL, 0xBE6C5AA5L, 0x65582185L, 0x68AB9802L, + 0xEECEA50FL, 0xDB2F953BL, 0x2AEF7DADL, 0x5B6E2F84L, + 0x1521B628L, 0x29076170L, 0xECDD4775L, 0x619F1510L, + 0x13CCA830L, 0xEB61BD96L, 0x0334FE1EL, 0xAA0363CFL, + 0xB5735C90L, 0x4C70A239L, 0xD59E9E0BL, 0xCBAADE14L, + 0xEECC86BCL, 0x60622CA7L, 0x9CAB5CABL, 0xB2F3846EL, + 0x648B1EAFL, 0x19BDF0CAL, 0xA02369B9L, 0x655ABB50L, + 0x40685A32L, 0x3C2AB4B3L, 0x319EE9D5L, 0xC021B8F7L, + 0x9B540B19L, 0x875FA099L, 0x95F7997EL, 0x623D7DA8L, + 0xF837889AL, 0x97E32D77L, 0x11ED935FL, 0x16681281L, + 0x0E358829L, 0xC7E61FD6L, 0x96DEDFA1L, 0x7858BA99L, + 0x57F584A5L, 0x1B227263L, 0x9B83C3FFL, 0x1AC24696L, + 0xCDB30AEBL, 0x532E3054L, 0x8FD948E4L, 0x6DBC3128L, + 0x58EBF2EFL, 0x34C6FFEAL, 0xFE28ED61L, 0xEE7C3C73L, + 0x5D4A14D9L, 0xE864B7E3L, 0x42105D14L, 0x203E13E0L, + 0x45EEE2B6L, 0xA3AAABEAL, 0xDB6C4F15L, 0xFACB4FD0L, + 0xC742F442L, 0xEF6ABBB5L, 0x654F3B1DL, 0x41CD2105L, + 0xD81E799EL, 0x86854DC7L, 0xE44B476AL, 0x3D816250L, + 0xCF62A1F2L, 0x5B8D2646L, 0xFC8883A0L, 0xC1C7B6A3L, + 0x7F1524C3L, 0x69CB7492L, 0x47848A0BL, 0x5692B285L, + 0x095BBF00L, 0xAD19489DL, 0x1462B174L, 0x23820E00L, + 0x58428D2AL, 0x0C55F5EAL, 0x1DADF43EL, 0x233F7061L, + 0x3372F092L, 0x8D937E41L, 0xD65FECF1L, 0x6C223BDBL, + 0x7CDE3759L, 0xCBEE7460L, 0x4085F2A7L, 0xCE77326EL, + 0xA6078084L, 0x19F8509EL, 0xE8EFD855L, 0x61D99735L, + 0xA969A7AAL, 0xC50C06C2L, 0x5A04ABFCL, 0x800BCADCL, + 0x9E447A2EL, 0xC3453484L, 0xFDD56705L, 0x0E1E9EC9L, + 0xDB73DBD3L, 0x105588CDL, 0x675FDA79L, 0xE3674340L, + 0xC5C43465L, 0x713E38D8L, 0x3D28F89EL, 0xF16DFF20L, + 0x153E21E7L, 0x8FB03D4AL, 0xE6E39F2BL, 0xDB83ADF7L }, + { 0xE93D5A68L, 0x948140F7L, 0xF64C261CL, 0x94692934L, + 0x411520F7L, 0x7602D4F7L, 0xBCF46B2EL, 0xD4A20068L, + 0xD4082471L, 0x3320F46AL, 0x43B7D4B7L, 0x500061AFL, + 0x1E39F62EL, 0x97244546L, 0x14214F74L, 0xBF8B8840L, + 0x4D95FC1DL, 0x96B591AFL, 0x70F4DDD3L, 0x66A02F45L, + 0xBFBC09ECL, 0x03BD9785L, 0x7FAC6DD0L, 0x31CB8504L, + 0x96EB27B3L, 0x55FD3941L, 0xDA2547E6L, 0xABCA0A9AL, + 0x28507825L, 0x530429F4L, 0x0A2C86DAL, 0xE9B66DFBL, + 0x68DC1462L, 0xD7486900L, 0x680EC0A4L, 0x27A18DEEL, + 0x4F3FFEA2L, 0xE887AD8CL, 0xB58CE006L, 0x7AF4D6B6L, + 0xAACE1E7CL, 0xD3375FECL, 0xCE78A399L, 0x406B2A42L, + 0x20FE9E35L, 0xD9F385B9L, 0xEE39D7ABL, 0x3B124E8BL, + 0x1DC9FAF7L, 0x4B6D1856L, 0x26A36631L, 0xEAE397B2L, + 0x3A6EFA74L, 0xDD5B4332L, 0x6841E7F7L, 0xCA7820FBL, + 0xFB0AF54EL, 0xD8FEB397L, 0x454056ACL, 0xBA489527L, + 0x55533A3AL, 0x20838D87L, 0xFE6BA9B7L, 0xD096954BL, + 0x55A867BCL, 0xA1159A58L, 0xCCA92963L, 0x99E1DB33L, + 0xA62A4A56L, 0x3F3125F9L, 0x5EF47E1CL, 0x9029317CL, + 0xFDF8E802L, 0x04272F70L, 0x80BB155CL, 0x05282CE3L, + 0x95C11548L, 0xE4C66D22L, 0x48C1133FL, 0xC70F86DCL, + 0x07F9C9EEL, 0x41041F0FL, 0x404779A4L, 0x5D886E17L, + 0x325F51EBL, 0xD59BC0D1L, 0xF2BCC18FL, 0x41113564L, + 0x257B7834L, 0x602A9C60L, 0xDFF8E8A3L, 0x1F636C1BL, + 0x0E12B4C2L, 0x02E1329EL, 0xAF664FD1L, 0xCAD18115L, + 0x6B2395E0L, 0x333E92E1L, 0x3B240B62L, 0xEEBEB922L, + 0x85B2A20EL, 0xE6BA0D99L, 0xDE720C8CL, 0x2DA2F728L, + 0xD0127845L, 0x95B794FDL, 0x647D0862L, 0xE7CCF5F0L, + 0x5449A36FL, 0x877D48FAL, 0xC39DFD27L, 0xF33E8D1EL, + 0x0A476341L, 0x992EFF74L, 0x3A6F6EABL, 0xF4F8FD37L, + 0xA812DC60L, 0xA1EBDDF8L, 0x991BE14CL, 0xDB6E6B0DL, + 0xC67B5510L, 0x6D672C37L, 0x2765D43BL, 0xDCD0E804L, + 0xF1290DC7L, 0xCC00FFA3L, 0xB5390F92L, 0x690FED0BL, + 0x667B9FFBL, 0xCEDB7D9CL, 0xA091CF0BL, 0xD9155EA3L, + 0xBB132F88L, 0x515BAD24L, 0x7B9479BFL, 0x763BD6EBL, + 0x37392EB3L, 0xCC115979L, 0x8026E297L, 0xF42E312DL, + 0x6842ADA7L, 0xC66A2B3BL, 0x12754CCCL, 0x782EF11CL, + 0x6A124237L, 0xB79251E7L, 0x06A1BBE6L, 0x4BFB6350L, + 0x1A6B1018L, 0x11CAEDFAL, 0x3D25BDD8L, 0xE2E1C3C9L, + 0x44421659L, 0x0A121386L, 0xD90CEC6EL, 0xD5ABEA2AL, + 0x64AF674EL, 0xDA86A85FL, 0xBEBFE988L, 0x64E4C3FEL, + 0x9DBC8057L, 0xF0F7C086L, 0x60787BF8L, 0x6003604DL, + 0xD1FD8346L, 0xF6381FB0L, 0x7745AE04L, 0xD736FCCCL, + 0x83426B33L, 0xF01EAB71L, 0xB0804187L, 0x3C005E5FL, + 0x77A057BEL, 0xBDE8AE24L, 0x55464299L, 0xBF582E61L, + 0x4E58F48FL, 0xF2DDFDA2L, 0xF474EF38L, 0x8789BDC2L, + 0x5366F9C3L, 0xC8B38E74L, 0xB475F255L, 0x46FCD9B9L, + 0x7AEB2661L, 0x8B1DDF84L, 0x846A0E79L, 0x915F95E2L, + 0x466E598EL, 0x20B45770L, 0x8CD55591L, 0xC902DE4CL, + 0xB90BACE1L, 0xBB8205D0L, 0x11A86248L, 0x7574A99EL, + 0xB77F19B6L, 0xE0A9DC09L, 0x662D09A1L, 0xC4324633L, + 0xE85A1F02L, 0x09F0BE8CL, 0x4A99A025L, 0x1D6EFE10L, + 0x1AB93D1DL, 0x0BA5A4DFL, 0xA186F20FL, 0x2868F169L, + 0xDCB7DA83L, 0x573906FEL, 0xA1E2CE9BL, 0x4FCD7F52L, + 0x50115E01L, 0xA70683FAL, 0xA002B5C4L, 0x0DE6D027L, + 0x9AF88C27L, 0x773F8641L, 0xC3604C06L, 0x61A806B5L, + 0xF0177A28L, 0xC0F586E0L, 0x006058AAL, 0x30DC7D62L, + 0x11E69ED7L, 0x2338EA63L, 0x53C2DD94L, 0xC2C21634L, + 0xBBCBEE56L, 0x90BCB6DEL, 0xEBFC7DA1L, 0xCE591D76L, + 0x6F05E409L, 0x4B7C0188L, 0x39720A3DL, 0x7C927C24L, + 0x86E3725FL, 0x724D9DB9L, 0x1AC15BB4L, 0xD39EB8FCL, + 0xED545578L, 0x08FCA5B5L, 0xD83D7CD3L, 0x4DAD0FC4L, + 0x1E50EF5EL, 0xB161E6F8L, 0xA28514D9L, 0x6C51133CL, + 0x6FD5C7E7L, 0x56E14EC4L, 0x362ABFCEL, 0xDDC6C837L, + 0xD79A3234L, 0x92638212L, 0x670EFA8EL, 0x406000E0L }, + { 0x3A39CE37L, 0xD3FAF5CFL, 0xABC27737L, 0x5AC52D1BL, + 0x5CB0679EL, 0x4FA33742L, 0xD3822740L, 0x99BC9BBEL, + 0xD5118E9DL, 0xBF0F7315L, 0xD62D1C7EL, 0xC700C47BL, + 0xB78C1B6BL, 0x21A19045L, 0xB26EB1BEL, 0x6A366EB4L, + 0x5748AB2FL, 0xBC946E79L, 0xC6A376D2L, 0x6549C2C8L, + 0x530FF8EEL, 0x468DDE7DL, 0xD5730A1DL, 0x4CD04DC6L, + 0x2939BBDBL, 0xA9BA4650L, 0xAC9526E8L, 0xBE5EE304L, + 0xA1FAD5F0L, 0x6A2D519AL, 0x63EF8CE2L, 0x9A86EE22L, + 0xC089C2B8L, 0x43242EF6L, 0xA51E03AAL, 0x9CF2D0A4L, + 0x83C061BAL, 0x9BE96A4DL, 0x8FE51550L, 0xBA645BD6L, + 0x2826A2F9L, 0xA73A3AE1L, 0x4BA99586L, 0xEF5562E9L, + 0xC72FEFD3L, 0xF752F7DAL, 0x3F046F69L, 0x77FA0A59L, + 0x80E4A915L, 0x87B08601L, 0x9B09E6ADL, 0x3B3EE593L, + 0xE990FD5AL, 0x9E34D797L, 0x2CF0B7D9L, 0x022B8B51L, + 0x96D5AC3AL, 0x017DA67DL, 0xD1CF3ED6L, 0x7C7D2D28L, + 0x1F9F25CFL, 0xADF2B89BL, 0x5AD6B472L, 0x5A88F54CL, + 0xE029AC71L, 0xE019A5E6L, 0x47B0ACFDL, 0xED93FA9BL, + 0xE8D3C48DL, 0x283B57CCL, 0xF8D56629L, 0x79132E28L, + 0x785F0191L, 0xED756055L, 0xF7960E44L, 0xE3D35E8CL, + 0x15056DD4L, 0x88F46DBAL, 0x03A16125L, 0x0564F0BDL, + 0xC3EB9E15L, 0x3C9057A2L, 0x97271AECL, 0xA93A072AL, + 0x1B3F6D9BL, 0x1E6321F5L, 0xF59C66FBL, 0x26DCF319L, + 0x7533D928L, 0xB155FDF5L, 0x03563482L, 0x8ABA3CBBL, + 0x28517711L, 0xC20AD9F8L, 0xABCC5167L, 0xCCAD925FL, + 0x4DE81751L, 0x3830DC8EL, 0x379D5862L, 0x9320F991L, + 0xEA7A90C2L, 0xFB3E7BCEL, 0x5121CE64L, 0x774FBE32L, + 0xA8B6E37EL, 0xC3293D46L, 0x48DE5369L, 0x6413E680L, + 0xA2AE0810L, 0xDD6DB224L, 0x69852DFDL, 0x09072166L, + 0xB39A460AL, 0x6445C0DDL, 0x586CDECFL, 0x1C20C8AEL, + 0x5BBEF7DDL, 0x1B588D40L, 0xCCD2017FL, 0x6BB4E3BBL, + 0xDDA26A7EL, 0x3A59FF45L, 0x3E350A44L, 0xBCB4CDD5L, + 0x72EACEA8L, 0xFA6484BBL, 0x8D6612AEL, 0xBF3C6F47L, + 0xD29BE463L, 0x542F5D9EL, 0xAEC2771BL, 0xF64E6370L, + 0x740E0D8DL, 0xE75B1357L, 0xF8721671L, 0xAF537D5DL, + 0x4040CB08L, 0x4EB4E2CCL, 0x34D2466AL, 0x0115AF84L, + 0xE1B00428L, 0x95983A1DL, 0x06B89FB4L, 0xCE6EA048L, + 0x6F3F3B82L, 0x3520AB82L, 0x011A1D4BL, 0x277227F8L, + 0x611560B1L, 0xE7933FDCL, 0xBB3A792BL, 0x344525BDL, + 0xA08839E1L, 0x51CE794BL, 0x2F32C9B7L, 0xA01FBAC9L, + 0xE01CC87EL, 0xBCC7D1F6L, 0xCF0111C3L, 0xA1E8AAC7L, + 0x1A908749L, 0xD44FBD9AL, 0xD0DADECBL, 0xD50ADA38L, + 0x0339C32AL, 0xC6913667L, 0x8DF9317CL, 0xE0B12B4FL, + 0xF79E59B7L, 0x43F5BB3AL, 0xF2D519FFL, 0x27D9459CL, + 0xBF97222CL, 0x15E6FC2AL, 0x0F91FC71L, 0x9B941525L, + 0xFAE59361L, 0xCEB69CEBL, 0xC2A86459L, 0x12BAA8D1L, + 0xB6C1075EL, 0xE3056A0CL, 0x10D25065L, 0xCB03A442L, + 0xE0EC6E0EL, 0x1698DB3BL, 0x4C98A0BEL, 0x3278E964L, + 0x9F1F9532L, 0xE0D392DFL, 0xD3A0342BL, 0x8971F21EL, + 0x1B0A7441L, 0x4BA3348CL, 0xC5BE7120L, 0xC37632D8L, + 0xDF359F8DL, 0x9B992F2EL, 0xE60B6F47L, 0x0FE3F11DL, + 0xE54CDA54L, 0x1EDAD891L, 0xCE6279CFL, 0xCD3E7E6FL, + 0x1618B166L, 0xFD2C1D05L, 0x848FD2C5L, 0xF6FB2299L, + 0xF523F357L, 0xA6327623L, 0x93A83531L, 0x56CCCD02L, + 0xACF08162L, 0x5A75EBB5L, 0x6E163697L, 0x88D273CCL, + 0xDE966292L, 0x81B949D0L, 0x4C50901BL, 0x71C65614L, + 0xE6C6C7BDL, 0x327A140AL, 0x45E1D006L, 0xC3F27B9AL, + 0xC9AA53FDL, 0x62A80F00L, 0xBB25BFE2L, 0x35BDD2F6L, + 0x71126905L, 0xB2040222L, 0xB6CBCF7CL, 0xCD769C2BL, + 0x53113EC0L, 0x1640E3D3L, 0x38ABBD60L, 0x2547ADF0L, + 0xBA38209CL, 0xF746CE76L, 0x77AFA1C5L, 0x20756060L, + 0x85CBFE4EL, 0x8AE88DD8L, 0x7AAAF9B0L, 0x4CF9AA7EL, + 0x1948C25CL, 0x02FB8A8CL, 0x01C36AE4L, 0xD6EBE1F9L, + 0x90D4F869L, 0xA65CDEA0L, 0x3F09252DL, 0xC208E69FL, + 0xB74E6132L, 0xCE77E25BL, 0x578FDFE3L, 0x3AC372E6L } +}; + +#endif /* !MBEDTLS_BLOWFISH_ALT */ +#endif /* MBEDTLS_BLOWFISH_C */ diff --git a/security/mbedtls/src/camellia.c b/security/mbedtls/src/camellia.c new file mode 100644 index 0000000000..ac6f96a83a --- /dev/null +++ b/security/mbedtls/src/camellia.c @@ -0,0 +1,1072 @@ +/* + * Camellia implementation + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +/* + * The Camellia block cipher was designed by NTT and Mitsubishi Electric + * Corporation. + * + * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/01espec.pdf + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_CAMELLIA_C) + +#include "mbedtls/camellia.h" + +#include + +#if defined(MBEDTLS_SELF_TEST) +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_printf printf +#endif /* MBEDTLS_PLATFORM_C */ +#endif /* MBEDTLS_SELF_TEST */ + +#if !defined(MBEDTLS_CAMELLIA_ALT) + +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0; +} + +/* + * 32-bit integer manipulation macros (big endian) + */ +#ifndef GET_UINT32_BE +#define GET_UINT32_BE(n,b,i) \ +{ \ + (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ + | ( (uint32_t) (b)[(i) + 1] << 16 ) \ + | ( (uint32_t) (b)[(i) + 2] << 8 ) \ + | ( (uint32_t) (b)[(i) + 3] ); \ +} +#endif + +#ifndef PUT_UINT32_BE +#define PUT_UINT32_BE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) ); \ +} +#endif + +static const unsigned char SIGMA_CHARS[6][8] = +{ + { 0xa0, 0x9e, 0x66, 0x7f, 0x3b, 0xcc, 0x90, 0x8b }, + { 0xb6, 0x7a, 0xe8, 0x58, 0x4c, 0xaa, 0x73, 0xb2 }, + { 0xc6, 0xef, 0x37, 0x2f, 0xe9, 0x4f, 0x82, 0xbe }, + { 0x54, 0xff, 0x53, 0xa5, 0xf1, 0xd3, 0x6f, 0x1c }, + { 0x10, 0xe5, 0x27, 0xfa, 0xde, 0x68, 0x2d, 0x1d }, + { 0xb0, 0x56, 0x88, 0xc2, 0xb3, 0xe6, 0xc1, 0xfd } +}; + +#if defined(MBEDTLS_CAMELLIA_SMALL_MEMORY) + +static const unsigned char FSb[256] = +{ + 112,130, 44,236,179, 39,192,229,228,133, 87, 53,234, 12,174, 65, + 35,239,107,147, 69, 25,165, 33,237, 14, 79, 78, 29,101,146,189, + 134,184,175,143,124,235, 31,206, 62, 48,220, 95, 94,197, 11, 26, + 166,225, 57,202,213, 71, 93, 61,217, 1, 90,214, 81, 86,108, 77, + 139, 13,154,102,251,204,176, 45,116, 18, 43, 32,240,177,132,153, + 223, 76,203,194, 52,126,118, 5,109,183,169, 49,209, 23, 4,215, + 20, 88, 58, 97,222, 27, 17, 28, 50, 15,156, 22, 83, 24,242, 34, + 254, 68,207,178,195,181,122,145, 36, 8,232,168, 96,252,105, 80, + 170,208,160,125,161,137, 98,151, 84, 91, 30,149,224,255,100,210, + 16,196, 0, 72,163,247,117,219,138, 3,230,218, 9, 63,221,148, + 135, 92,131, 2,205, 74,144, 51,115,103,246,243,157,127,191,226, + 82,155,216, 38,200, 55,198, 59,129,150,111, 75, 19,190, 99, 46, + 233,121,167,140,159,110,188,142, 41,245,249,182, 47,253,180, 89, + 120,152, 6,106,231, 70,113,186,212, 37,171, 66,136,162,141,250, + 114, 7,185, 85,248,238,172, 10, 54, 73, 42,104, 60, 56,241,164, + 64, 40,211,123,187,201, 67,193, 21,227,173,244,119,199,128,158 +}; + +#define SBOX1(n) FSb[(n)] +#define SBOX2(n) (unsigned char)((FSb[(n)] >> 7 ^ FSb[(n)] << 1) & 0xff) +#define SBOX3(n) (unsigned char)((FSb[(n)] >> 1 ^ FSb[(n)] << 7) & 0xff) +#define SBOX4(n) FSb[((n) << 1 ^ (n) >> 7) &0xff] + +#else /* MBEDTLS_CAMELLIA_SMALL_MEMORY */ + +static const unsigned char FSb[256] = +{ + 112, 130, 44, 236, 179, 39, 192, 229, 228, 133, 87, 53, 234, 12, 174, 65, + 35, 239, 107, 147, 69, 25, 165, 33, 237, 14, 79, 78, 29, 101, 146, 189, + 134, 184, 175, 143, 124, 235, 31, 206, 62, 48, 220, 95, 94, 197, 11, 26, + 166, 225, 57, 202, 213, 71, 93, 61, 217, 1, 90, 214, 81, 86, 108, 77, + 139, 13, 154, 102, 251, 204, 176, 45, 116, 18, 43, 32, 240, 177, 132, 153, + 223, 76, 203, 194, 52, 126, 118, 5, 109, 183, 169, 49, 209, 23, 4, 215, + 20, 88, 58, 97, 222, 27, 17, 28, 50, 15, 156, 22, 83, 24, 242, 34, + 254, 68, 207, 178, 195, 181, 122, 145, 36, 8, 232, 168, 96, 252, 105, 80, + 170, 208, 160, 125, 161, 137, 98, 151, 84, 91, 30, 149, 224, 255, 100, 210, + 16, 196, 0, 72, 163, 247, 117, 219, 138, 3, 230, 218, 9, 63, 221, 148, + 135, 92, 131, 2, 205, 74, 144, 51, 115, 103, 246, 243, 157, 127, 191, 226, + 82, 155, 216, 38, 200, 55, 198, 59, 129, 150, 111, 75, 19, 190, 99, 46, + 233, 121, 167, 140, 159, 110, 188, 142, 41, 245, 249, 182, 47, 253, 180, 89, + 120, 152, 6, 106, 231, 70, 113, 186, 212, 37, 171, 66, 136, 162, 141, 250, + 114, 7, 185, 85, 248, 238, 172, 10, 54, 73, 42, 104, 60, 56, 241, 164, + 64, 40, 211, 123, 187, 201, 67, 193, 21, 227, 173, 244, 119, 199, 128, 158 +}; + +static const unsigned char FSb2[256] = +{ + 224, 5, 88, 217, 103, 78, 129, 203, 201, 11, 174, 106, 213, 24, 93, 130, + 70, 223, 214, 39, 138, 50, 75, 66, 219, 28, 158, 156, 58, 202, 37, 123, + 13, 113, 95, 31, 248, 215, 62, 157, 124, 96, 185, 190, 188, 139, 22, 52, + 77, 195, 114, 149, 171, 142, 186, 122, 179, 2, 180, 173, 162, 172, 216, 154, + 23, 26, 53, 204, 247, 153, 97, 90, 232, 36, 86, 64, 225, 99, 9, 51, + 191, 152, 151, 133, 104, 252, 236, 10, 218, 111, 83, 98, 163, 46, 8, 175, + 40, 176, 116, 194, 189, 54, 34, 56, 100, 30, 57, 44, 166, 48, 229, 68, + 253, 136, 159, 101, 135, 107, 244, 35, 72, 16, 209, 81, 192, 249, 210, 160, + 85, 161, 65, 250, 67, 19, 196, 47, 168, 182, 60, 43, 193, 255, 200, 165, + 32, 137, 0, 144, 71, 239, 234, 183, 21, 6, 205, 181, 18, 126, 187, 41, + 15, 184, 7, 4, 155, 148, 33, 102, 230, 206, 237, 231, 59, 254, 127, 197, + 164, 55, 177, 76, 145, 110, 141, 118, 3, 45, 222, 150, 38, 125, 198, 92, + 211, 242, 79, 25, 63, 220, 121, 29, 82, 235, 243, 109, 94, 251, 105, 178, + 240, 49, 12, 212, 207, 140, 226, 117, 169, 74, 87, 132, 17, 69, 27, 245, + 228, 14, 115, 170, 241, 221, 89, 20, 108, 146, 84, 208, 120, 112, 227, 73, + 128, 80, 167, 246, 119, 147, 134, 131, 42, 199, 91, 233, 238, 143, 1, 61 +}; + +static const unsigned char FSb3[256] = +{ + 56, 65, 22, 118, 217, 147, 96, 242, 114, 194, 171, 154, 117, 6, 87, 160, + 145, 247, 181, 201, 162, 140, 210, 144, 246, 7, 167, 39, 142, 178, 73, 222, + 67, 92, 215, 199, 62, 245, 143, 103, 31, 24, 110, 175, 47, 226, 133, 13, + 83, 240, 156, 101, 234, 163, 174, 158, 236, 128, 45, 107, 168, 43, 54, 166, + 197, 134, 77, 51, 253, 102, 88, 150, 58, 9, 149, 16, 120, 216, 66, 204, + 239, 38, 229, 97, 26, 63, 59, 130, 182, 219, 212, 152, 232, 139, 2, 235, + 10, 44, 29, 176, 111, 141, 136, 14, 25, 135, 78, 11, 169, 12, 121, 17, + 127, 34, 231, 89, 225, 218, 61, 200, 18, 4, 116, 84, 48, 126, 180, 40, + 85, 104, 80, 190, 208, 196, 49, 203, 42, 173, 15, 202, 112, 255, 50, 105, + 8, 98, 0, 36, 209, 251, 186, 237, 69, 129, 115, 109, 132, 159, 238, 74, + 195, 46, 193, 1, 230, 37, 72, 153, 185, 179, 123, 249, 206, 191, 223, 113, + 41, 205, 108, 19, 100, 155, 99, 157, 192, 75, 183, 165, 137, 95, 177, 23, + 244, 188, 211, 70, 207, 55, 94, 71, 148, 250, 252, 91, 151, 254, 90, 172, + 60, 76, 3, 53, 243, 35, 184, 93, 106, 146, 213, 33, 68, 81, 198, 125, + 57, 131, 220, 170, 124, 119, 86, 5, 27, 164, 21, 52, 30, 28, 248, 82, + 32, 20, 233, 189, 221, 228, 161, 224, 138, 241, 214, 122, 187, 227, 64, 79 +}; + +static const unsigned char FSb4[256] = +{ + 112, 44, 179, 192, 228, 87, 234, 174, 35, 107, 69, 165, 237, 79, 29, 146, + 134, 175, 124, 31, 62, 220, 94, 11, 166, 57, 213, 93, 217, 90, 81, 108, + 139, 154, 251, 176, 116, 43, 240, 132, 223, 203, 52, 118, 109, 169, 209, 4, + 20, 58, 222, 17, 50, 156, 83, 242, 254, 207, 195, 122, 36, 232, 96, 105, + 170, 160, 161, 98, 84, 30, 224, 100, 16, 0, 163, 117, 138, 230, 9, 221, + 135, 131, 205, 144, 115, 246, 157, 191, 82, 216, 200, 198, 129, 111, 19, 99, + 233, 167, 159, 188, 41, 249, 47, 180, 120, 6, 231, 113, 212, 171, 136, 141, + 114, 185, 248, 172, 54, 42, 60, 241, 64, 211, 187, 67, 21, 173, 119, 128, + 130, 236, 39, 229, 133, 53, 12, 65, 239, 147, 25, 33, 14, 78, 101, 189, + 184, 143, 235, 206, 48, 95, 197, 26, 225, 202, 71, 61, 1, 214, 86, 77, + 13, 102, 204, 45, 18, 32, 177, 153, 76, 194, 126, 5, 183, 49, 23, 215, + 88, 97, 27, 28, 15, 22, 24, 34, 68, 178, 181, 145, 8, 168, 252, 80, + 208, 125, 137, 151, 91, 149, 255, 210, 196, 72, 247, 219, 3, 218, 63, 148, + 92, 2, 74, 51, 103, 243, 127, 226, 155, 38, 55, 59, 150, 75, 190, 46, + 121, 140, 110, 142, 245, 182, 253, 89, 152, 106, 70, 186, 37, 66, 162, 250, + 7, 85, 238, 10, 73, 104, 56, 164, 40, 123, 201, 193, 227, 244, 199, 158 +}; + +#define SBOX1(n) FSb[(n)] +#define SBOX2(n) FSb2[(n)] +#define SBOX3(n) FSb3[(n)] +#define SBOX4(n) FSb4[(n)] + +#endif /* MBEDTLS_CAMELLIA_SMALL_MEMORY */ + +static const unsigned char shifts[2][4][4] = +{ + { + { 1, 1, 1, 1 }, /* KL */ + { 0, 0, 0, 0 }, /* KR */ + { 1, 1, 1, 1 }, /* KA */ + { 0, 0, 0, 0 } /* KB */ + }, + { + { 1, 0, 1, 1 }, /* KL */ + { 1, 1, 0, 1 }, /* KR */ + { 1, 1, 1, 0 }, /* KA */ + { 1, 1, 0, 1 } /* KB */ + } +}; + +static const signed char indexes[2][4][20] = +{ + { + { 0, 1, 2, 3, 8, 9, 10, 11, 38, 39, + 36, 37, 23, 20, 21, 22, 27, -1, -1, 26 }, /* KL -> RK */ + { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, /* KR -> RK */ + { 4, 5, 6, 7, 12, 13, 14, 15, 16, 17, + 18, 19, -1, 24, 25, -1, 31, 28, 29, 30 }, /* KA -> RK */ + { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 } /* KB -> RK */ + }, + { + { 0, 1, 2, 3, 61, 62, 63, 60, -1, -1, + -1, -1, 27, 24, 25, 26, 35, 32, 33, 34 }, /* KL -> RK */ + { -1, -1, -1, -1, 8, 9, 10, 11, 16, 17, + 18, 19, -1, -1, -1, -1, 39, 36, 37, 38 }, /* KR -> RK */ + { -1, -1, -1, -1, 12, 13, 14, 15, 58, 59, + 56, 57, 31, 28, 29, 30, -1, -1, -1, -1 }, /* KA -> RK */ + { 4, 5, 6, 7, 65, 66, 67, 64, 20, 21, + 22, 23, -1, -1, -1, -1, 43, 40, 41, 42 } /* KB -> RK */ + } +}; + +static const signed char transposes[2][20] = +{ + { + 21, 22, 23, 20, + -1, -1, -1, -1, + 18, 19, 16, 17, + 11, 8, 9, 10, + 15, 12, 13, 14 + }, + { + 25, 26, 27, 24, + 29, 30, 31, 28, + 18, 19, 16, 17, + -1, -1, -1, -1, + -1, -1, -1, -1 + } +}; + +/* Shift macro for 128 bit strings with rotation smaller than 32 bits (!) */ +#define ROTL(DEST, SRC, SHIFT) \ +{ \ + (DEST)[0] = (SRC)[0] << (SHIFT) ^ (SRC)[1] >> (32 - (SHIFT)); \ + (DEST)[1] = (SRC)[1] << (SHIFT) ^ (SRC)[2] >> (32 - (SHIFT)); \ + (DEST)[2] = (SRC)[2] << (SHIFT) ^ (SRC)[3] >> (32 - (SHIFT)); \ + (DEST)[3] = (SRC)[3] << (SHIFT) ^ (SRC)[0] >> (32 - (SHIFT)); \ +} + +#define FL(XL, XR, KL, KR) \ +{ \ + (XR) = ((((XL) & (KL)) << 1) | (((XL) & (KL)) >> 31)) ^ (XR); \ + (XL) = ((XR) | (KR)) ^ (XL); \ +} + +#define FLInv(YL, YR, KL, KR) \ +{ \ + (YL) = ((YR) | (KR)) ^ (YL); \ + (YR) = ((((YL) & (KL)) << 1) | (((YL) & (KL)) >> 31)) ^ (YR); \ +} + +#define SHIFT_AND_PLACE(INDEX, OFFSET) \ +{ \ + TK[0] = KC[(OFFSET) * 4 + 0]; \ + TK[1] = KC[(OFFSET) * 4 + 1]; \ + TK[2] = KC[(OFFSET) * 4 + 2]; \ + TK[3] = KC[(OFFSET) * 4 + 3]; \ + \ + for( i = 1; i <= 4; i++ ) \ + if( shifts[(INDEX)][(OFFSET)][i -1] ) \ + ROTL(TK + i * 4, TK, ( 15 * i ) % 32); \ + \ + for( i = 0; i < 20; i++ ) \ + if( indexes[(INDEX)][(OFFSET)][i] != -1 ) { \ + RK[indexes[(INDEX)][(OFFSET)][i]] = TK[ i ]; \ + } \ +} + +static void camellia_feistel( const uint32_t x[2], const uint32_t k[2], + uint32_t z[2]) +{ + uint32_t I0, I1; + I0 = x[0] ^ k[0]; + I1 = x[1] ^ k[1]; + + I0 = ((uint32_t) SBOX1((I0 >> 24) & 0xFF) << 24) | + ((uint32_t) SBOX2((I0 >> 16) & 0xFF) << 16) | + ((uint32_t) SBOX3((I0 >> 8) & 0xFF) << 8) | + ((uint32_t) SBOX4((I0 ) & 0xFF) ); + I1 = ((uint32_t) SBOX2((I1 >> 24) & 0xFF) << 24) | + ((uint32_t) SBOX3((I1 >> 16) & 0xFF) << 16) | + ((uint32_t) SBOX4((I1 >> 8) & 0xFF) << 8) | + ((uint32_t) SBOX1((I1 ) & 0xFF) ); + + I0 ^= (I1 << 8) | (I1 >> 24); + I1 ^= (I0 << 16) | (I0 >> 16); + I0 ^= (I1 >> 8) | (I1 << 24); + I1 ^= (I0 >> 8) | (I0 << 24); + + z[0] ^= I1; + z[1] ^= I0; +} + +void mbedtls_camellia_init( mbedtls_camellia_context *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_camellia_context ) ); +} + +void mbedtls_camellia_free( mbedtls_camellia_context *ctx ) +{ + if( ctx == NULL ) + return; + + mbedtls_zeroize( ctx, sizeof( mbedtls_camellia_context ) ); +} + +/* + * Camellia key schedule (encryption) + */ +int mbedtls_camellia_setkey_enc( mbedtls_camellia_context *ctx, const unsigned char *key, + unsigned int keybits ) +{ + int idx; + size_t i; + uint32_t *RK; + unsigned char t[64]; + uint32_t SIGMA[6][2]; + uint32_t KC[16]; + uint32_t TK[20]; + + RK = ctx->rk; + + memset( t, 0, 64 ); + memset( RK, 0, sizeof(ctx->rk) ); + + switch( keybits ) + { + case 128: ctx->nr = 3; idx = 0; break; + case 192: + case 256: ctx->nr = 4; idx = 1; break; + default : return( MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH ); + } + + for( i = 0; i < keybits / 8; ++i ) + t[i] = key[i]; + + if( keybits == 192 ) { + for( i = 0; i < 8; i++ ) + t[24 + i] = ~t[16 + i]; + } + + /* + * Prepare SIGMA values + */ + for( i = 0; i < 6; i++ ) { + GET_UINT32_BE( SIGMA[i][0], SIGMA_CHARS[i], 0 ); + GET_UINT32_BE( SIGMA[i][1], SIGMA_CHARS[i], 4 ); + } + + /* + * Key storage in KC + * Order: KL, KR, KA, KB + */ + memset( KC, 0, sizeof(KC) ); + + /* Store KL, KR */ + for( i = 0; i < 8; i++ ) + GET_UINT32_BE( KC[i], t, i * 4 ); + + /* Generate KA */ + for( i = 0; i < 4; ++i ) + KC[8 + i] = KC[i] ^ KC[4 + i]; + + camellia_feistel( KC + 8, SIGMA[0], KC + 10 ); + camellia_feistel( KC + 10, SIGMA[1], KC + 8 ); + + for( i = 0; i < 4; ++i ) + KC[8 + i] ^= KC[i]; + + camellia_feistel( KC + 8, SIGMA[2], KC + 10 ); + camellia_feistel( KC + 10, SIGMA[3], KC + 8 ); + + if( keybits > 128 ) { + /* Generate KB */ + for( i = 0; i < 4; ++i ) + KC[12 + i] = KC[4 + i] ^ KC[8 + i]; + + camellia_feistel( KC + 12, SIGMA[4], KC + 14 ); + camellia_feistel( KC + 14, SIGMA[5], KC + 12 ); + } + + /* + * Generating subkeys + */ + + /* Manipulating KL */ + SHIFT_AND_PLACE( idx, 0 ); + + /* Manipulating KR */ + if( keybits > 128 ) { + SHIFT_AND_PLACE( idx, 1 ); + } + + /* Manipulating KA */ + SHIFT_AND_PLACE( idx, 2 ); + + /* Manipulating KB */ + if( keybits > 128 ) { + SHIFT_AND_PLACE( idx, 3 ); + } + + /* Do transpositions */ + for( i = 0; i < 20; i++ ) { + if( transposes[idx][i] != -1 ) { + RK[32 + 12 * idx + i] = RK[transposes[idx][i]]; + } + } + + return( 0 ); +} + +/* + * Camellia key schedule (decryption) + */ +int mbedtls_camellia_setkey_dec( mbedtls_camellia_context *ctx, const unsigned char *key, + unsigned int keybits ) +{ + int idx, ret; + size_t i; + mbedtls_camellia_context cty; + uint32_t *RK; + uint32_t *SK; + + mbedtls_camellia_init( &cty ); + + /* Also checks keybits */ + if( ( ret = mbedtls_camellia_setkey_enc( &cty, key, keybits ) ) != 0 ) + goto exit; + + ctx->nr = cty.nr; + idx = ( ctx->nr == 4 ); + + RK = ctx->rk; + SK = cty.rk + 24 * 2 + 8 * idx * 2; + + *RK++ = *SK++; + *RK++ = *SK++; + *RK++ = *SK++; + *RK++ = *SK++; + + for( i = 22 + 8 * idx, SK -= 6; i > 0; i--, SK -= 4 ) + { + *RK++ = *SK++; + *RK++ = *SK++; + } + + SK -= 2; + + *RK++ = *SK++; + *RK++ = *SK++; + *RK++ = *SK++; + *RK++ = *SK++; + +exit: + mbedtls_camellia_free( &cty ); + + return( ret ); +} + +/* + * Camellia-ECB block encryption/decryption + */ +int mbedtls_camellia_crypt_ecb( mbedtls_camellia_context *ctx, + int mode, + const unsigned char input[16], + unsigned char output[16] ) +{ + int NR; + uint32_t *RK, X[4]; + + ( (void) mode ); + + NR = ctx->nr; + RK = ctx->rk; + + GET_UINT32_BE( X[0], input, 0 ); + GET_UINT32_BE( X[1], input, 4 ); + GET_UINT32_BE( X[2], input, 8 ); + GET_UINT32_BE( X[3], input, 12 ); + + X[0] ^= *RK++; + X[1] ^= *RK++; + X[2] ^= *RK++; + X[3] ^= *RK++; + + while( NR ) { + --NR; + camellia_feistel( X, RK, X + 2 ); + RK += 2; + camellia_feistel( X + 2, RK, X ); + RK += 2; + camellia_feistel( X, RK, X + 2 ); + RK += 2; + camellia_feistel( X + 2, RK, X ); + RK += 2; + camellia_feistel( X, RK, X + 2 ); + RK += 2; + camellia_feistel( X + 2, RK, X ); + RK += 2; + + if( NR ) { + FL(X[0], X[1], RK[0], RK[1]); + RK += 2; + FLInv(X[2], X[3], RK[0], RK[1]); + RK += 2; + } + } + + X[2] ^= *RK++; + X[3] ^= *RK++; + X[0] ^= *RK++; + X[1] ^= *RK++; + + PUT_UINT32_BE( X[2], output, 0 ); + PUT_UINT32_BE( X[3], output, 4 ); + PUT_UINT32_BE( X[0], output, 8 ); + PUT_UINT32_BE( X[1], output, 12 ); + + return( 0 ); +} + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +/* + * Camellia-CBC buffer encryption/decryption + */ +int mbedtls_camellia_crypt_cbc( mbedtls_camellia_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ) +{ + int i; + unsigned char temp[16]; + + if( length % 16 ) + return( MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH ); + + if( mode == MBEDTLS_CAMELLIA_DECRYPT ) + { + while( length > 0 ) + { + memcpy( temp, input, 16 ); + mbedtls_camellia_crypt_ecb( ctx, mode, input, output ); + + for( i = 0; i < 16; i++ ) + output[i] = (unsigned char)( output[i] ^ iv[i] ); + + memcpy( iv, temp, 16 ); + + input += 16; + output += 16; + length -= 16; + } + } + else + { + while( length > 0 ) + { + for( i = 0; i < 16; i++ ) + output[i] = (unsigned char)( input[i] ^ iv[i] ); + + mbedtls_camellia_crypt_ecb( ctx, mode, output, output ); + memcpy( iv, output, 16 ); + + input += 16; + output += 16; + length -= 16; + } + } + + return( 0 ); +} +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +/* + * Camellia-CFB128 buffer encryption/decryption + */ +int mbedtls_camellia_crypt_cfb128( mbedtls_camellia_context *ctx, + int mode, + size_t length, + size_t *iv_off, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ) +{ + int c; + size_t n = *iv_off; + + if( mode == MBEDTLS_CAMELLIA_DECRYPT ) + { + while( length-- ) + { + if( n == 0 ) + mbedtls_camellia_crypt_ecb( ctx, MBEDTLS_CAMELLIA_ENCRYPT, iv, iv ); + + c = *input++; + *output++ = (unsigned char)( c ^ iv[n] ); + iv[n] = (unsigned char) c; + + n = ( n + 1 ) & 0x0F; + } + } + else + { + while( length-- ) + { + if( n == 0 ) + mbedtls_camellia_crypt_ecb( ctx, MBEDTLS_CAMELLIA_ENCRYPT, iv, iv ); + + iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ ); + + n = ( n + 1 ) & 0x0F; + } + } + + *iv_off = n; + + return( 0 ); +} +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +/* + * Camellia-CTR buffer encryption/decryption + */ +int mbedtls_camellia_crypt_ctr( mbedtls_camellia_context *ctx, + size_t length, + size_t *nc_off, + unsigned char nonce_counter[16], + unsigned char stream_block[16], + const unsigned char *input, + unsigned char *output ) +{ + int c, i; + size_t n = *nc_off; + + while( length-- ) + { + if( n == 0 ) { + mbedtls_camellia_crypt_ecb( ctx, MBEDTLS_CAMELLIA_ENCRYPT, nonce_counter, + stream_block ); + + for( i = 16; i > 0; i-- ) + if( ++nonce_counter[i - 1] != 0 ) + break; + } + c = *input++; + *output++ = (unsigned char)( c ^ stream_block[n] ); + + n = ( n + 1 ) & 0x0F; + } + + *nc_off = n; + + return( 0 ); +} +#endif /* MBEDTLS_CIPHER_MODE_CTR */ +#endif /* !MBEDTLS_CAMELLIA_ALT */ + +#if defined(MBEDTLS_SELF_TEST) + +/* + * Camellia test vectors from: + * + * http://info.isl.ntt.co.jp/crypt/eng/camellia/technology.html: + * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/cryptrec/intermediate.txt + * http://info.isl.ntt.co.jp/crypt/eng/camellia/dl/cryptrec/t_camellia.txt + * (For each bitlength: Key 0, Nr 39) + */ +#define CAMELLIA_TESTS_ECB 2 + +static const unsigned char camellia_test_ecb_key[3][CAMELLIA_TESTS_ECB][32] = +{ + { + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } + }, + { + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } + }, + { + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } + }, +}; + +static const unsigned char camellia_test_ecb_plain[CAMELLIA_TESTS_ECB][16] = +{ + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }, + { 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } +}; + +static const unsigned char camellia_test_ecb_cipher[3][CAMELLIA_TESTS_ECB][16] = +{ + { + { 0x67, 0x67, 0x31, 0x38, 0x54, 0x96, 0x69, 0x73, + 0x08, 0x57, 0x06, 0x56, 0x48, 0xea, 0xbe, 0x43 }, + { 0x38, 0x3C, 0x6C, 0x2A, 0xAB, 0xEF, 0x7F, 0xDE, + 0x25, 0xCD, 0x47, 0x0B, 0xF7, 0x74, 0xA3, 0x31 } + }, + { + { 0xb4, 0x99, 0x34, 0x01, 0xb3, 0xe9, 0x96, 0xf8, + 0x4e, 0xe5, 0xce, 0xe7, 0xd7, 0x9b, 0x09, 0xb9 }, + { 0xD1, 0x76, 0x3F, 0xC0, 0x19, 0xD7, 0x7C, 0xC9, + 0x30, 0xBF, 0xF2, 0xA5, 0x6F, 0x7C, 0x93, 0x64 } + }, + { + { 0x9a, 0xcc, 0x23, 0x7d, 0xff, 0x16, 0xd7, 0x6c, + 0x20, 0xef, 0x7c, 0x91, 0x9e, 0x3a, 0x75, 0x09 }, + { 0x05, 0x03, 0xFB, 0x10, 0xAB, 0x24, 0x1E, 0x7C, + 0xF4, 0x5D, 0x8C, 0xDE, 0xEE, 0x47, 0x43, 0x35 } + } +}; + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#define CAMELLIA_TESTS_CBC 3 + +static const unsigned char camellia_test_cbc_key[3][32] = +{ + { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, + 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C } + , + { 0x8E, 0x73, 0xB0, 0xF7, 0xDA, 0x0E, 0x64, 0x52, + 0xC8, 0x10, 0xF3, 0x2B, 0x80, 0x90, 0x79, 0xE5, + 0x62, 0xF8, 0xEA, 0xD2, 0x52, 0x2C, 0x6B, 0x7B } + , + { 0x60, 0x3D, 0xEB, 0x10, 0x15, 0xCA, 0x71, 0xBE, + 0x2B, 0x73, 0xAE, 0xF0, 0x85, 0x7D, 0x77, 0x81, + 0x1F, 0x35, 0x2C, 0x07, 0x3B, 0x61, 0x08, 0xD7, + 0x2D, 0x98, 0x10, 0xA3, 0x09, 0x14, 0xDF, 0xF4 } +}; + +static const unsigned char camellia_test_cbc_iv[16] = + + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F } +; + +static const unsigned char camellia_test_cbc_plain[CAMELLIA_TESTS_CBC][16] = +{ + { 0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96, + 0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A }, + { 0xAE, 0x2D, 0x8A, 0x57, 0x1E, 0x03, 0xAC, 0x9C, + 0x9E, 0xB7, 0x6F, 0xAC, 0x45, 0xAF, 0x8E, 0x51 }, + { 0x30, 0xC8, 0x1C, 0x46, 0xA3, 0x5C, 0xE4, 0x11, + 0xE5, 0xFB, 0xC1, 0x19, 0x1A, 0x0A, 0x52, 0xEF } + +}; + +static const unsigned char camellia_test_cbc_cipher[3][CAMELLIA_TESTS_CBC][16] = +{ + { + { 0x16, 0x07, 0xCF, 0x49, 0x4B, 0x36, 0xBB, 0xF0, + 0x0D, 0xAE, 0xB0, 0xB5, 0x03, 0xC8, 0x31, 0xAB }, + { 0xA2, 0xF2, 0xCF, 0x67, 0x16, 0x29, 0xEF, 0x78, + 0x40, 0xC5, 0xA5, 0xDF, 0xB5, 0x07, 0x48, 0x87 }, + { 0x0F, 0x06, 0x16, 0x50, 0x08, 0xCF, 0x8B, 0x8B, + 0x5A, 0x63, 0x58, 0x63, 0x62, 0x54, 0x3E, 0x54 } + }, + { + { 0x2A, 0x48, 0x30, 0xAB, 0x5A, 0xC4, 0xA1, 0xA2, + 0x40, 0x59, 0x55, 0xFD, 0x21, 0x95, 0xCF, 0x93 }, + { 0x5D, 0x5A, 0x86, 0x9B, 0xD1, 0x4C, 0xE5, 0x42, + 0x64, 0xF8, 0x92, 0xA6, 0xDD, 0x2E, 0xC3, 0xD5 }, + { 0x37, 0xD3, 0x59, 0xC3, 0x34, 0x98, 0x36, 0xD8, + 0x84, 0xE3, 0x10, 0xAD, 0xDF, 0x68, 0xC4, 0x49 } + }, + { + { 0xE6, 0xCF, 0xA3, 0x5F, 0xC0, 0x2B, 0x13, 0x4A, + 0x4D, 0x2C, 0x0B, 0x67, 0x37, 0xAC, 0x3E, 0xDA }, + { 0x36, 0xCB, 0xEB, 0x73, 0xBD, 0x50, 0x4B, 0x40, + 0x70, 0xB1, 0xB7, 0xDE, 0x2B, 0x21, 0xEB, 0x50 }, + { 0xE3, 0x1A, 0x60, 0x55, 0x29, 0x7D, 0x96, 0xCA, + 0x33, 0x30, 0xCD, 0xF1, 0xB1, 0x86, 0x0A, 0x83 } + } +}; +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +/* + * Camellia-CTR test vectors from: + * + * http://www.faqs.org/rfcs/rfc5528.html + */ + +static const unsigned char camellia_test_ctr_key[3][16] = +{ + { 0xAE, 0x68, 0x52, 0xF8, 0x12, 0x10, 0x67, 0xCC, + 0x4B, 0xF7, 0xA5, 0x76, 0x55, 0x77, 0xF3, 0x9E }, + { 0x7E, 0x24, 0x06, 0x78, 0x17, 0xFA, 0xE0, 0xD7, + 0x43, 0xD6, 0xCE, 0x1F, 0x32, 0x53, 0x91, 0x63 }, + { 0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8, + 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC } +}; + +static const unsigned char camellia_test_ctr_nonce_counter[3][16] = +{ + { 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }, + { 0x00, 0x6C, 0xB6, 0xDB, 0xC0, 0x54, 0x3B, 0x59, + 0xDA, 0x48, 0xD9, 0x0B, 0x00, 0x00, 0x00, 0x01 }, + { 0x00, 0xE0, 0x01, 0x7B, 0x27, 0x77, 0x7F, 0x3F, + 0x4A, 0x17, 0x86, 0xF0, 0x00, 0x00, 0x00, 0x01 } +}; + +static const unsigned char camellia_test_ctr_pt[3][48] = +{ + { 0x53, 0x69, 0x6E, 0x67, 0x6C, 0x65, 0x20, 0x62, + 0x6C, 0x6F, 0x63, 0x6B, 0x20, 0x6D, 0x73, 0x67 }, + + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F }, + + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, + 0x20, 0x21, 0x22, 0x23 } +}; + +static const unsigned char camellia_test_ctr_ct[3][48] = +{ + { 0xD0, 0x9D, 0xC2, 0x9A, 0x82, 0x14, 0x61, 0x9A, + 0x20, 0x87, 0x7C, 0x76, 0xDB, 0x1F, 0x0B, 0x3F }, + { 0xDB, 0xF3, 0xC7, 0x8D, 0xC0, 0x83, 0x96, 0xD4, + 0xDA, 0x7C, 0x90, 0x77, 0x65, 0xBB, 0xCB, 0x44, + 0x2B, 0x8E, 0x8E, 0x0F, 0x31, 0xF0, 0xDC, 0xA7, + 0x2C, 0x74, 0x17, 0xE3, 0x53, 0x60, 0xE0, 0x48 }, + { 0xB1, 0x9D, 0x1F, 0xCD, 0xCB, 0x75, 0xEB, 0x88, + 0x2F, 0x84, 0x9C, 0xE2, 0x4D, 0x85, 0xCF, 0x73, + 0x9C, 0xE6, 0x4B, 0x2B, 0x5C, 0x9D, 0x73, 0xF1, + 0x4F, 0x2D, 0x5D, 0x9D, 0xCE, 0x98, 0x89, 0xCD, + 0xDF, 0x50, 0x86, 0x96 } +}; + +static const int camellia_test_ctr_len[3] = + { 16, 32, 36 }; +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +/* + * Checkup routine + */ +int mbedtls_camellia_self_test( int verbose ) +{ + int i, j, u, v; + unsigned char key[32]; + unsigned char buf[64]; + unsigned char src[16]; + unsigned char dst[16]; +#if defined(MBEDTLS_CIPHER_MODE_CBC) + unsigned char iv[16]; +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + size_t offset, len; + unsigned char nonce_counter[16]; + unsigned char stream_block[16]; +#endif + + mbedtls_camellia_context ctx; + + memset( key, 0, 32 ); + + for( j = 0; j < 6; j++ ) { + u = j >> 1; + v = j & 1; + + if( verbose != 0 ) + mbedtls_printf( " CAMELLIA-ECB-%3d (%s): ", 128 + u * 64, + (v == MBEDTLS_CAMELLIA_DECRYPT) ? "dec" : "enc"); + + for( i = 0; i < CAMELLIA_TESTS_ECB; i++ ) { + memcpy( key, camellia_test_ecb_key[u][i], 16 + 8 * u ); + + if( v == MBEDTLS_CAMELLIA_DECRYPT ) { + mbedtls_camellia_setkey_dec( &ctx, key, 128 + u * 64 ); + memcpy( src, camellia_test_ecb_cipher[u][i], 16 ); + memcpy( dst, camellia_test_ecb_plain[i], 16 ); + } else { /* MBEDTLS_CAMELLIA_ENCRYPT */ + mbedtls_camellia_setkey_enc( &ctx, key, 128 + u * 64 ); + memcpy( src, camellia_test_ecb_plain[i], 16 ); + memcpy( dst, camellia_test_ecb_cipher[u][i], 16 ); + } + + mbedtls_camellia_crypt_ecb( &ctx, v, src, buf ); + + if( memcmp( buf, dst, 16 ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( 1 ); + } + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + +#if defined(MBEDTLS_CIPHER_MODE_CBC) + /* + * CBC mode + */ + for( j = 0; j < 6; j++ ) + { + u = j >> 1; + v = j & 1; + + if( verbose != 0 ) + mbedtls_printf( " CAMELLIA-CBC-%3d (%s): ", 128 + u * 64, + ( v == MBEDTLS_CAMELLIA_DECRYPT ) ? "dec" : "enc" ); + + memcpy( src, camellia_test_cbc_iv, 16 ); + memcpy( dst, camellia_test_cbc_iv, 16 ); + memcpy( key, camellia_test_cbc_key[u], 16 + 8 * u ); + + if( v == MBEDTLS_CAMELLIA_DECRYPT ) { + mbedtls_camellia_setkey_dec( &ctx, key, 128 + u * 64 ); + } else { + mbedtls_camellia_setkey_enc( &ctx, key, 128 + u * 64 ); + } + + for( i = 0; i < CAMELLIA_TESTS_CBC; i++ ) { + + if( v == MBEDTLS_CAMELLIA_DECRYPT ) { + memcpy( iv , src, 16 ); + memcpy( src, camellia_test_cbc_cipher[u][i], 16 ); + memcpy( dst, camellia_test_cbc_plain[i], 16 ); + } else { /* MBEDTLS_CAMELLIA_ENCRYPT */ + memcpy( iv , dst, 16 ); + memcpy( src, camellia_test_cbc_plain[i], 16 ); + memcpy( dst, camellia_test_cbc_cipher[u][i], 16 ); + } + + mbedtls_camellia_crypt_cbc( &ctx, v, 16, iv, src, buf ); + + if( memcmp( buf, dst, 16 ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( 1 ); + } + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + +#if defined(MBEDTLS_CIPHER_MODE_CTR) + /* + * CTR mode + */ + for( i = 0; i < 6; i++ ) + { + u = i >> 1; + v = i & 1; + + if( verbose != 0 ) + mbedtls_printf( " CAMELLIA-CTR-128 (%s): ", + ( v == MBEDTLS_CAMELLIA_DECRYPT ) ? "dec" : "enc" ); + + memcpy( nonce_counter, camellia_test_ctr_nonce_counter[u], 16 ); + memcpy( key, camellia_test_ctr_key[u], 16 ); + + offset = 0; + mbedtls_camellia_setkey_enc( &ctx, key, 128 ); + + if( v == MBEDTLS_CAMELLIA_DECRYPT ) + { + len = camellia_test_ctr_len[u]; + memcpy( buf, camellia_test_ctr_ct[u], len ); + + mbedtls_camellia_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block, + buf, buf ); + + if( memcmp( buf, camellia_test_ctr_pt[u], len ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( 1 ); + } + } + else + { + len = camellia_test_ctr_len[u]; + memcpy( buf, camellia_test_ctr_pt[u], len ); + + mbedtls_camellia_crypt_ctr( &ctx, len, &offset, nonce_counter, stream_block, + buf, buf ); + + if( memcmp( buf, camellia_test_ctr_ct[u], len ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( 1 ); + } + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + + return( 0 ); +} + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_CAMELLIA_C */ diff --git a/security/mbedtls/src/ccm.c b/security/mbedtls/src/ccm.c new file mode 100644 index 0000000000..13a8fd1a24 --- /dev/null +++ b/security/mbedtls/src/ccm.c @@ -0,0 +1,464 @@ +/* + * NIST SP800-38C compliant CCM implementation + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +/* + * Definition of CCM: + * http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C_updated-July20_2007.pdf + * RFC 3610 "Counter with CBC-MAC (CCM)" + * + * Related: + * RFC 5116 "An Interface and Algorithms for Authenticated Encryption" + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_CCM_C) + +#include "mbedtls/ccm.h" + +#include + +#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_printf printf +#endif /* MBEDTLS_PLATFORM_C */ +#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ + +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0; +} + +#define CCM_ENCRYPT 0 +#define CCM_DECRYPT 1 + +/* + * Initialize context + */ +void mbedtls_ccm_init( mbedtls_ccm_context *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_ccm_context ) ); +} + +int mbedtls_ccm_setkey( mbedtls_ccm_context *ctx, + mbedtls_cipher_id_t cipher, + const unsigned char *key, + unsigned int keybits ) +{ + int ret; + const mbedtls_cipher_info_t *cipher_info; + + cipher_info = mbedtls_cipher_info_from_values( cipher, keybits, MBEDTLS_MODE_ECB ); + if( cipher_info == NULL ) + return( MBEDTLS_ERR_CCM_BAD_INPUT ); + + if( cipher_info->block_size != 16 ) + return( MBEDTLS_ERR_CCM_BAD_INPUT ); + + mbedtls_cipher_free( &ctx->cipher_ctx ); + + if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 ) + return( ret ); + + if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits, + MBEDTLS_ENCRYPT ) ) != 0 ) + { + return( ret ); + } + + return( 0 ); +} + +/* + * Free context + */ +void mbedtls_ccm_free( mbedtls_ccm_context *ctx ) +{ + mbedtls_cipher_free( &ctx->cipher_ctx ); + mbedtls_zeroize( ctx, sizeof( mbedtls_ccm_context ) ); +} + +/* + * Macros for common operations. + * Results in smaller compiled code than static inline functions. + */ + +/* + * Update the CBC-MAC state in y using a block in b + * (Always using b as the source helps the compiler optimise a bit better.) + */ +#define UPDATE_CBC_MAC \ + for( i = 0; i < 16; i++ ) \ + y[i] ^= b[i]; \ + \ + if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, y, 16, y, &olen ) ) != 0 ) \ + return( ret ); + +/* + * Encrypt or decrypt a partial block with CTR + * Warning: using b for temporary storage! src and dst must not be b! + * This avoids allocating one more 16 bytes buffer while allowing src == dst. + */ +#define CTR_CRYPT( dst, src, len ) \ + if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctr, 16, b, &olen ) ) != 0 ) \ + return( ret ); \ + \ + for( i = 0; i < len; i++ ) \ + dst[i] = src[i] ^ b[i]; + +/* + * Authenticated encryption or decryption + */ +static int ccm_auth_crypt( mbedtls_ccm_context *ctx, int mode, size_t length, + const unsigned char *iv, size_t iv_len, + const unsigned char *add, size_t add_len, + const unsigned char *input, unsigned char *output, + unsigned char *tag, size_t tag_len ) +{ + int ret; + unsigned char i; + unsigned char q; + size_t len_left, olen; + unsigned char b[16]; + unsigned char y[16]; + unsigned char ctr[16]; + const unsigned char *src; + unsigned char *dst; + + /* + * Check length requirements: SP800-38C A.1 + * Additional requirement: a < 2^16 - 2^8 to simplify the code. + * 'length' checked later (when writing it to the first block) + */ + if( tag_len < 4 || tag_len > 16 || tag_len % 2 != 0 ) + return( MBEDTLS_ERR_CCM_BAD_INPUT ); + + /* Also implies q is within bounds */ + if( iv_len < 7 || iv_len > 13 ) + return( MBEDTLS_ERR_CCM_BAD_INPUT ); + + if( add_len > 0xFF00 ) + return( MBEDTLS_ERR_CCM_BAD_INPUT ); + + q = 16 - 1 - (unsigned char) iv_len; + + /* + * First block B_0: + * 0 .. 0 flags + * 1 .. iv_len nonce (aka iv) + * iv_len+1 .. 15 length + * + * With flags as (bits): + * 7 0 + * 6 add present? + * 5 .. 3 (t - 2) / 2 + * 2 .. 0 q - 1 + */ + b[0] = 0; + b[0] |= ( add_len > 0 ) << 6; + b[0] |= ( ( tag_len - 2 ) / 2 ) << 3; + b[0] |= q - 1; + + memcpy( b + 1, iv, iv_len ); + + for( i = 0, len_left = length; i < q; i++, len_left >>= 8 ) + b[15-i] = (unsigned char)( len_left & 0xFF ); + + if( len_left > 0 ) + return( MBEDTLS_ERR_CCM_BAD_INPUT ); + + + /* Start CBC-MAC with first block */ + memset( y, 0, 16 ); + UPDATE_CBC_MAC; + + /* + * If there is additional data, update CBC-MAC with + * add_len, add, 0 (padding to a block boundary) + */ + if( add_len > 0 ) + { + size_t use_len; + len_left = add_len; + src = add; + + memset( b, 0, 16 ); + b[0] = (unsigned char)( ( add_len >> 8 ) & 0xFF ); + b[1] = (unsigned char)( ( add_len ) & 0xFF ); + + use_len = len_left < 16 - 2 ? len_left : 16 - 2; + memcpy( b + 2, src, use_len ); + len_left -= use_len; + src += use_len; + + UPDATE_CBC_MAC; + + while( len_left > 0 ) + { + use_len = len_left > 16 ? 16 : len_left; + + memset( b, 0, 16 ); + memcpy( b, src, use_len ); + UPDATE_CBC_MAC; + + len_left -= use_len; + src += use_len; + } + } + + /* + * Prepare counter block for encryption: + * 0 .. 0 flags + * 1 .. iv_len nonce (aka iv) + * iv_len+1 .. 15 counter (initially 1) + * + * With flags as (bits): + * 7 .. 3 0 + * 2 .. 0 q - 1 + */ + ctr[0] = q - 1; + memcpy( ctr + 1, iv, iv_len ); + memset( ctr + 1 + iv_len, 0, q ); + ctr[15] = 1; + + /* + * Authenticate and {en,de}crypt the message. + * + * The only difference between encryption and decryption is + * the respective order of authentication and {en,de}cryption. + */ + len_left = length; + src = input; + dst = output; + + while( len_left > 0 ) + { + size_t use_len = len_left > 16 ? 16 : len_left; + + if( mode == CCM_ENCRYPT ) + { + memset( b, 0, 16 ); + memcpy( b, src, use_len ); + UPDATE_CBC_MAC; + } + + CTR_CRYPT( dst, src, use_len ); + + if( mode == CCM_DECRYPT ) + { + memset( b, 0, 16 ); + memcpy( b, dst, use_len ); + UPDATE_CBC_MAC; + } + + dst += use_len; + src += use_len; + len_left -= use_len; + + /* + * Increment counter. + * No need to check for overflow thanks to the length check above. + */ + for( i = 0; i < q; i++ ) + if( ++ctr[15-i] != 0 ) + break; + } + + /* + * Authentication: reset counter and crypt/mask internal tag + */ + for( i = 0; i < q; i++ ) + ctr[15-i] = 0; + + CTR_CRYPT( y, y, 16 ); + memcpy( tag, y, tag_len ); + + return( 0 ); +} + +/* + * Authenticated encryption + */ +int mbedtls_ccm_encrypt_and_tag( mbedtls_ccm_context *ctx, size_t length, + const unsigned char *iv, size_t iv_len, + const unsigned char *add, size_t add_len, + const unsigned char *input, unsigned char *output, + unsigned char *tag, size_t tag_len ) +{ + return( ccm_auth_crypt( ctx, CCM_ENCRYPT, length, iv, iv_len, + add, add_len, input, output, tag, tag_len ) ); +} + +/* + * Authenticated decryption + */ +int mbedtls_ccm_auth_decrypt( mbedtls_ccm_context *ctx, size_t length, + const unsigned char *iv, size_t iv_len, + const unsigned char *add, size_t add_len, + const unsigned char *input, unsigned char *output, + const unsigned char *tag, size_t tag_len ) +{ + int ret; + unsigned char check_tag[16]; + unsigned char i; + int diff; + + if( ( ret = ccm_auth_crypt( ctx, CCM_DECRYPT, length, + iv, iv_len, add, add_len, + input, output, check_tag, tag_len ) ) != 0 ) + { + return( ret ); + } + + /* Check tag in "constant-time" */ + for( diff = 0, i = 0; i < tag_len; i++ ) + diff |= tag[i] ^ check_tag[i]; + + if( diff != 0 ) + { + mbedtls_zeroize( output, length ); + return( MBEDTLS_ERR_CCM_AUTH_FAILED ); + } + + return( 0 ); +} + + +#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) +/* + * Examples 1 to 3 from SP800-38C Appendix C + */ + +#define NB_TESTS 3 + +/* + * The data is the same for all tests, only the used length changes + */ +static const unsigned char key[] = { + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f +}; + +static const unsigned char iv[] = { + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b +}; + +static const unsigned char ad[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13 +}; + +static const unsigned char msg[] = { + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, +}; + +static const size_t iv_len [NB_TESTS] = { 7, 8, 12 }; +static const size_t add_len[NB_TESTS] = { 8, 16, 20 }; +static const size_t msg_len[NB_TESTS] = { 4, 16, 24 }; +static const size_t tag_len[NB_TESTS] = { 4, 6, 8 }; + +static const unsigned char res[NB_TESTS][32] = { + { 0x71, 0x62, 0x01, 0x5b, 0x4d, 0xac, 0x25, 0x5d }, + { 0xd2, 0xa1, 0xf0, 0xe0, 0x51, 0xea, 0x5f, 0x62, + 0x08, 0x1a, 0x77, 0x92, 0x07, 0x3d, 0x59, 0x3d, + 0x1f, 0xc6, 0x4f, 0xbf, 0xac, 0xcd }, + { 0xe3, 0xb2, 0x01, 0xa9, 0xf5, 0xb7, 0x1a, 0x7a, + 0x9b, 0x1c, 0xea, 0xec, 0xcd, 0x97, 0xe7, 0x0b, + 0x61, 0x76, 0xaa, 0xd9, 0xa4, 0x42, 0x8a, 0xa5, + 0x48, 0x43, 0x92, 0xfb, 0xc1, 0xb0, 0x99, 0x51 } +}; + +int mbedtls_ccm_self_test( int verbose ) +{ + mbedtls_ccm_context ctx; + unsigned char out[32]; + size_t i; + int ret; + + mbedtls_ccm_init( &ctx ); + + if( mbedtls_ccm_setkey( &ctx, MBEDTLS_CIPHER_ID_AES, key, 8 * sizeof key ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( " CCM: setup failed" ); + + return( 1 ); + } + + for( i = 0; i < NB_TESTS; i++ ) + { + if( verbose != 0 ) + mbedtls_printf( " CCM-AES #%u: ", (unsigned int) i + 1 ); + + ret = mbedtls_ccm_encrypt_and_tag( &ctx, msg_len[i], + iv, iv_len[i], ad, add_len[i], + msg, out, + out + msg_len[i], tag_len[i] ); + + if( ret != 0 || + memcmp( out, res[i], msg_len[i] + tag_len[i] ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( 1 ); + } + + ret = mbedtls_ccm_auth_decrypt( &ctx, msg_len[i], + iv, iv_len[i], ad, add_len[i], + res[i], out, + res[i] + msg_len[i], tag_len[i] ); + + if( ret != 0 || + memcmp( out, msg, msg_len[i] ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + + mbedtls_ccm_free( &ctx ); + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + + return( 0 ); +} + +#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ + +#endif /* MBEDTLS_CCM_C */ diff --git a/security/mbedtls/src/certs.c b/security/mbedtls/src/certs.c new file mode 100644 index 0000000000..ffe6bc981c --- /dev/null +++ b/security/mbedtls/src/certs.c @@ -0,0 +1,351 @@ +/* + * X.509 test certificates + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include "mbedtls/certs.h" + +#if defined(MBEDTLS_CERTS_C) + +#if defined(MBEDTLS_ECDSA_C) +#define TEST_CA_CRT_EC \ +"-----BEGIN CERTIFICATE-----\r\n" \ +"MIICUjCCAdegAwIBAgIJAMFD4n5iQ8zoMAoGCCqGSM49BAMCMD4xCzAJBgNVBAYT\r\n" \ +"Ak5MMREwDwYDVQQKEwhQb2xhclNTTDEcMBoGA1UEAxMTUG9sYXJzc2wgVGVzdCBF\r\n" \ +"QyBDQTAeFw0xMzA5MjQxNTQ5NDhaFw0yMzA5MjIxNTQ5NDhaMD4xCzAJBgNVBAYT\r\n" \ +"Ak5MMREwDwYDVQQKEwhQb2xhclNTTDEcMBoGA1UEAxMTUG9sYXJzc2wgVGVzdCBF\r\n" \ +"QyBDQTB2MBAGByqGSM49AgEGBSuBBAAiA2IABMPaKzRBN1gvh1b+/Im6KUNLTuBu\r\n" \ +"ww5XUzM5WNRStJGVOQsj318XJGJI/BqVKc4sLYfCiFKAr9ZqqyHduNMcbli4yuiy\r\n" \ +"aY7zQa0pw7RfdadHb9UZKVVpmlM7ILRmFmAzHqOBoDCBnTAdBgNVHQ4EFgQUnW0g\r\n" \ +"JEkBPyvLeLUZvH4kydv7NnwwbgYDVR0jBGcwZYAUnW0gJEkBPyvLeLUZvH4kydv7\r\n" \ +"NnyhQqRAMD4xCzAJBgNVBAYTAk5MMREwDwYDVQQKEwhQb2xhclNTTDEcMBoGA1UE\r\n" \ +"AxMTUG9sYXJzc2wgVGVzdCBFQyBDQYIJAMFD4n5iQ8zoMAwGA1UdEwQFMAMBAf8w\r\n" \ +"CgYIKoZIzj0EAwIDaQAwZgIxAMO0YnNWKJUAfXgSJtJxexn4ipg+kv4znuR50v56\r\n" \ +"t4d0PCu412mUC6Nnd7izvtE2MgIxAP1nnJQjZ8BWukszFQDG48wxCCyci9qpdSMv\r\n" \ +"uCjn8pwUOkABXK8Mss90fzCfCEOtIA==\r\n" \ +"-----END CERTIFICATE-----\r\n" +const char mbedtls_test_ca_crt_ec[] = TEST_CA_CRT_EC; + +const char mbedtls_test_ca_key_ec[] = +"-----BEGIN EC PRIVATE KEY-----\r\n" +"Proc-Type: 4,ENCRYPTED\r\n" +"DEK-Info: DES-EDE3-CBC,307EAB469933D64E\r\n" +"\r\n" +"IxbrRmKcAzctJqPdTQLA4SWyBYYGYJVkYEna+F7Pa5t5Yg/gKADrFKcm6B72e7DG\r\n" +"ihExtZI648s0zdYw6qSJ74vrPSuWDe5qm93BqsfVH9svtCzWHW0pm1p0KTBCFfUq\r\n" +"UsuWTITwJImcnlAs1gaRZ3sAWm7cOUidL0fo2G0fYUFNcYoCSLffCFTEHBuPnagb\r\n" +"a77x/sY1Bvii8S9/XhDTb6pTMx06wzrm\r\n" +"-----END EC PRIVATE KEY-----\r\n"; + +const char mbedtls_test_ca_pwd_ec[] = "PolarSSLTest"; + +const char mbedtls_test_srv_crt_ec[] = +"-----BEGIN CERTIFICATE-----\r\n" +"MIICHzCCAaWgAwIBAgIBCTAKBggqhkjOPQQDAjA+MQswCQYDVQQGEwJOTDERMA8G\r\n" +"A1UEChMIUG9sYXJTU0wxHDAaBgNVBAMTE1BvbGFyc3NsIFRlc3QgRUMgQ0EwHhcN\r\n" +"MTMwOTI0MTU1MjA0WhcNMjMwOTIyMTU1MjA0WjA0MQswCQYDVQQGEwJOTDERMA8G\r\n" +"A1UEChMIUG9sYXJTU0wxEjAQBgNVBAMTCWxvY2FsaG9zdDBZMBMGByqGSM49AgEG\r\n" +"CCqGSM49AwEHA0IABDfMVtl2CR5acj7HWS3/IG7ufPkGkXTQrRS192giWWKSTuUA\r\n" +"2CMR/+ov0jRdXRa9iojCa3cNVc2KKg76Aci07f+jgZ0wgZowCQYDVR0TBAIwADAd\r\n" +"BgNVHQ4EFgQUUGGlj9QH2deCAQzlZX+MY0anE74wbgYDVR0jBGcwZYAUnW0gJEkB\r\n" +"PyvLeLUZvH4kydv7NnyhQqRAMD4xCzAJBgNVBAYTAk5MMREwDwYDVQQKEwhQb2xh\r\n" +"clNTTDEcMBoGA1UEAxMTUG9sYXJzc2wgVGVzdCBFQyBDQYIJAMFD4n5iQ8zoMAoG\r\n" +"CCqGSM49BAMCA2gAMGUCMQCaLFzXptui5WQN8LlO3ddh1hMxx6tzgLvT03MTVK2S\r\n" +"C12r0Lz3ri/moSEpNZWqPjkCMCE2f53GXcYLqyfyJR078c/xNSUU5+Xxl7VZ414V\r\n" +"fGa5kHvHARBPc8YAIVIqDvHH1Q==\r\n" +"-----END CERTIFICATE-----\r\n"; + +const char mbedtls_test_srv_key_ec[] = +"-----BEGIN EC PRIVATE KEY-----\r\n" +"MHcCAQEEIPEqEyB2AnCoPL/9U/YDHvdqXYbIogTywwyp6/UfDw6noAoGCCqGSM49\r\n" +"AwEHoUQDQgAEN8xW2XYJHlpyPsdZLf8gbu58+QaRdNCtFLX3aCJZYpJO5QDYIxH/\r\n" +"6i/SNF1dFr2KiMJrdw1VzYoqDvoByLTt/w==\r\n" +"-----END EC PRIVATE KEY-----\r\n"; + +const char mbedtls_test_cli_crt_ec[] = +"-----BEGIN CERTIFICATE-----\r\n" +"MIICLDCCAbKgAwIBAgIBDTAKBggqhkjOPQQDAjA+MQswCQYDVQQGEwJOTDERMA8G\r\n" +"A1UEChMIUG9sYXJTU0wxHDAaBgNVBAMTE1BvbGFyc3NsIFRlc3QgRUMgQ0EwHhcN\r\n" +"MTMwOTI0MTU1MjA0WhcNMjMwOTIyMTU1MjA0WjBBMQswCQYDVQQGEwJOTDERMA8G\r\n" +"A1UEChMIUG9sYXJTU0wxHzAdBgNVBAMTFlBvbGFyU1NMIFRlc3QgQ2xpZW50IDIw\r\n" +"WTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARX5a6xc9/TrLuTuIH/Eq7u5lOszlVT\r\n" +"9jQOzC7jYyUL35ji81xgNpbA1RgUcOV/n9VLRRjlsGzVXPiWj4dwo+THo4GdMIGa\r\n" +"MAkGA1UdEwQCMAAwHQYDVR0OBBYEFHoAX4Zk/OBd5REQO7LmO8QmP8/iMG4GA1Ud\r\n" +"IwRnMGWAFJ1tICRJAT8ry3i1Gbx+JMnb+zZ8oUKkQDA+MQswCQYDVQQGEwJOTDER\r\n" +"MA8GA1UEChMIUG9sYXJTU0wxHDAaBgNVBAMTE1BvbGFyc3NsIFRlc3QgRUMgQ0GC\r\n" +"CQDBQ+J+YkPM6DAKBggqhkjOPQQDAgNoADBlAjBKZQ17IIOimbmoD/yN7o89u3BM\r\n" +"lgOsjnhw3fIOoLIWy2WOGsk/LGF++DzvrRzuNiACMQCd8iem1XS4JK7haj8xocpU\r\n" +"LwjQje5PDGHfd3h9tP38Qknu5bJqws0md2KOKHyeV0U=\r\n" +"-----END CERTIFICATE-----\r\n"; + +const char mbedtls_test_cli_key_ec[] = +"-----BEGIN EC PRIVATE KEY-----\r\n" +"MHcCAQEEIPb3hmTxZ3/mZI3vyk7p3U3wBf+WIop6hDhkFzJhmLcqoAoGCCqGSM49\r\n" +"AwEHoUQDQgAEV+WusXPf06y7k7iB/xKu7uZTrM5VU/Y0Dswu42MlC9+Y4vNcYDaW\r\n" +"wNUYFHDlf5/VS0UY5bBs1Vz4lo+HcKPkxw==\r\n" +"-----END EC PRIVATE KEY-----\r\n"; + +const size_t mbedtls_test_ca_crt_ec_len = sizeof( mbedtls_test_ca_crt_ec ); +const size_t mbedtls_test_ca_key_ec_len = sizeof( mbedtls_test_ca_key_ec ); +const size_t mbedtls_test_ca_pwd_ec_len = sizeof( mbedtls_test_ca_pwd_ec ) - 1; +const size_t mbedtls_test_srv_crt_ec_len = sizeof( mbedtls_test_srv_crt_ec ); +const size_t mbedtls_test_srv_key_ec_len = sizeof( mbedtls_test_srv_key_ec ); +const size_t mbedtls_test_cli_crt_ec_len = sizeof( mbedtls_test_cli_crt_ec ); +const size_t mbedtls_test_cli_key_ec_len = sizeof( mbedtls_test_cli_key_ec ); +#else +#define TEST_CA_CRT_EC +#endif /* MBEDTLS_ECDSA_C */ + +#if defined(MBEDTLS_RSA_C) +#define TEST_CA_CRT_RSA \ +"-----BEGIN CERTIFICATE-----\r\n" \ +"MIIDhzCCAm+gAwIBAgIBADANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n" \ +"MA8GA1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" \ +"MTEwMjEyMTQ0NDAwWhcNMjEwMjEyMTQ0NDAwWjA7MQswCQYDVQQGEwJOTDERMA8G\r\n" \ +"A1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwggEiMA0G\r\n" \ +"CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDA3zf8F7vglp0/ht6WMn1EpRagzSHx\r\n" \ +"mdTs6st8GFgIlKXsm8WL3xoemTiZhx57wI053zhdcHgH057Zk+i5clHFzqMwUqny\r\n" \ +"50BwFMtEonILwuVA+T7lpg6z+exKY8C4KQB0nFc7qKUEkHHxvYPZP9al4jwqj+8n\r\n" \ +"YMPGn8u67GB9t+aEMr5P+1gmIgNb1LTV+/Xjli5wwOQuvfwu7uJBVcA0Ln0kcmnL\r\n" \ +"R7EUQIN9Z/SG9jGr8XmksrUuEvmEF/Bibyc+E1ixVA0hmnM3oTDPb5Lc9un8rNsu\r\n" \ +"KNF+AksjoBXyOGVkCeoMbo4bF6BxyLObyavpw/LPh5aPgAIynplYb6LVAgMBAAGj\r\n" \ +"gZUwgZIwDAYDVR0TBAUwAwEB/zAdBgNVHQ4EFgQUtFrkpbPe0lL2udWmlQ/rPrzH\r\n" \ +"/f8wYwYDVR0jBFwwWoAUtFrkpbPe0lL2udWmlQ/rPrzH/f+hP6Q9MDsxCzAJBgNV\r\n" \ +"BAYTAk5MMREwDwYDVQQKEwhQb2xhclNTTDEZMBcGA1UEAxMQUG9sYXJTU0wgVGVz\r\n" \ +"dCBDQYIBADANBgkqhkiG9w0BAQUFAAOCAQEAuP1U2ABUkIslsCfdlc2i94QHHYeJ\r\n" \ +"SsR4EdgHtdciUI5I62J6Mom+Y0dT/7a+8S6MVMCZP6C5NyNyXw1GWY/YR82XTJ8H\r\n" \ +"DBJiCTok5DbZ6SzaONBzdWHXwWwmi5vg1dxn7YxrM9d0IjxM27WNKs4sDQhZBQkF\r\n" \ +"pjmfs2cb4oPl4Y9T9meTx/lvdkRYEug61Jfn6cA+qHpyPYdTH+UshITnmp5/Ztkf\r\n" \ +"m/UTSLBNFNHesiTZeH31NcxYGdHSme9Nc/gfidRa0FLOCfWxRlFqAI47zG9jAQCZ\r\n" \ +"7Z2mCGDNMhjQc+BYcdnl0lPXjdDK6V0qCg1dVewhUBcW5gZKzV7e9+DpVA==\r\n" \ +"-----END CERTIFICATE-----\r\n" +const char mbedtls_test_ca_crt_rsa[] = TEST_CA_CRT_RSA; + +const char mbedtls_test_ca_key_rsa[] = +"-----BEGIN RSA PRIVATE KEY-----\r\n" +"Proc-Type: 4,ENCRYPTED\r\n" +"DEK-Info: DES-EDE3-CBC,A8A95B05D5B7206B\r\n" +"\r\n" +"9Qd9GeArejl1GDVh2lLV1bHt0cPtfbh5h/5zVpAVaFpqtSPMrElp50Rntn9et+JA\r\n" +"7VOyboR+Iy2t/HU4WvA687k3Bppe9GwKHjHhtl//8xFKwZr3Xb5yO5JUP8AUctQq\r\n" +"Nb8CLlZyuUC+52REAAthdWgsX+7dJO4yabzUcQ22Tp9JSD0hiL43BlkWYUNK3dAo\r\n" +"PZlmiptjnzVTjg1MxsBSydZinWOLBV8/JQgxSPo2yD4uEfig28qbvQ2wNIn0pnAb\r\n" +"GxnSAOazkongEGfvcjIIs+LZN9gXFhxcOh6kc4Q/c99B7QWETwLLkYgZ+z1a9VY9\r\n" +"gEU7CwCxYCD+h9hY6FPmsK0/lC4O7aeRKpYq00rPPxs6i7phiexg6ax6yTMmArQq\r\n" +"QmK3TAsJm8V/J5AWpLEV6jAFgRGymGGHnof0DXzVWZidrcZJWTNuGEX90nB3ee2w\r\n" +"PXJEFWKoD3K3aFcSLdHYr3mLGxP7H9ThQai9VsycxZKS5kwvBKQ//YMrmFfwPk8x\r\n" +"vTeY4KZMaUrveEel5tWZC94RSMKgxR6cyE1nBXyTQnDOGbfpNNgBKxyKbINWoOJU\r\n" +"WJZAwlsQn+QzCDwpri7+sV1mS3gBE6UY7aQmnmiiaC2V3Hbphxct/en5QsfDOt1X\r\n" +"JczSfpRWLlbPznZg8OQh/VgCMA58N5DjOzTIK7sJJ5r+94ZBTCpgAMbF588f0NTR\r\n" +"KCe4yrxGJR7X02M4nvD4IwOlpsQ8xQxZtOSgXv4LkxvdU9XJJKWZ/XNKJeWztxSe\r\n" +"Z1vdTc2YfsDBA2SEv33vxHx2g1vqtw8SjDRT2RaQSS0QuSaMJimdOX6mTOCBKk1J\r\n" +"9Q5mXTrER+/LnK0jEmXsBXWA5bqqVZIyahXSx4VYZ7l7w/PHiUDtDgyRhMMKi4n2\r\n" +"iQvQcWSQTjrpnlJbca1/DkpRt3YwrvJwdqb8asZU2VrNETh5x0QVefDRLFiVpif/\r\n" +"tUaeAe/P1F8OkS7OIZDs1SUbv/sD2vMbhNkUoCms3/PvNtdnvgL4F0zhaDpKCmlT\r\n" +"P8vx49E7v5CyRNmED9zZg4o3wmMqrQO93PtTug3Eu9oVx1zPQM1NVMyBa2+f29DL\r\n" +"1nuTCeXdo9+ni45xx+jAI4DCwrRdhJ9uzZyC6962H37H6D+5naNvClFR1s6li1Gb\r\n" +"nqPoiy/OBsEx9CaDGcqQBp5Wme/3XW+6z1ISOx+igwNTVCT14mHdBMbya0eIKft5\r\n" +"X+GnwtgEMyCYyyWuUct8g4RzErcY9+yW9Om5Hzpx4zOuW4NPZgPDTgK+t2RSL/Yq\r\n" +"rE1njrgeGYcVeG3f+OftH4s6fPbq7t1A5ZgUscbLMBqr9tK+OqygR4EgKBPsH6Cz\r\n" +"L6zlv/2RV0qAHvVuDJcIDIgwY5rJtINEm32rhOeFNJwZS5MNIC1czXZx5//ugX7l\r\n" +"I4sy5nbVhwSjtAk8Xg5dZbdTZ6mIrb7xqH+fdakZor1khG7bC2uIwibD3cSl2XkR\r\n" +"wN48lslbHnqqagr6Xm1nNOSVl8C/6kbJEsMpLhAezfRtGwvOucoaE+WbeUNolGde\r\n" +"P/eQiddSf0brnpiLJRh7qZrl9XuqYdpUqnoEdMAfotDOID8OtV7gt8a48ad8VPW2\r\n" +"-----END RSA PRIVATE KEY-----\r\n"; + +const char mbedtls_test_ca_pwd_rsa[] = "PolarSSLTest"; + +const char mbedtls_test_srv_crt_rsa[] = +"-----BEGIN CERTIFICATE-----\r\n" +"MIIDNzCCAh+gAwIBAgIBAjANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n" +"MA8GA1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" +"MTEwMjEyMTQ0NDA2WhcNMjEwMjEyMTQ0NDA2WjA0MQswCQYDVQQGEwJOTDERMA8G\r\n" +"A1UEChMIUG9sYXJTU0wxEjAQBgNVBAMTCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcN\r\n" +"AQEBBQADggEPADCCAQoCggEBAMFNo93nzR3RBNdJcriZrA545Do8Ss86ExbQWuTN\r\n" +"owCIp+4ea5anUrSQ7y1yej4kmvy2NKwk9XfgJmSMnLAofaHa6ozmyRyWvP7BBFKz\r\n" +"NtSj+uGxdtiQwWG0ZlI2oiZTqqt0Xgd9GYLbKtgfoNkNHC1JZvdbJXNG6AuKT2kM\r\n" +"tQCQ4dqCEGZ9rlQri2V5kaHiYcPNQEkI7mgM8YuG0ka/0LiqEQMef1aoGh5EGA8P\r\n" +"hYvai0Re4hjGYi/HZo36Xdh98yeJKQHFkA4/J/EwyEoO79bex8cna8cFPXrEAjya\r\n" +"HT4P6DSYW8tzS1KW2BGiLICIaTla0w+w3lkvEcf36hIBMJcCAwEAAaNNMEswCQYD\r\n" +"VR0TBAIwADAdBgNVHQ4EFgQUpQXoZLjc32APUBJNYKhkr02LQ5MwHwYDVR0jBBgw\r\n" +"FoAUtFrkpbPe0lL2udWmlQ/rPrzH/f8wDQYJKoZIhvcNAQEFBQADggEBAJxnXClY\r\n" +"oHkbp70cqBrsGXLybA74czbO5RdLEgFs7rHVS9r+c293luS/KdliLScZqAzYVylw\r\n" +"UfRWvKMoWhHYKp3dEIS4xTXk6/5zXxhv9Rw8SGc8qn6vITHk1S1mPevtekgasY5Y\r\n" +"iWQuM3h4YVlRH3HHEMAD1TnAexfXHHDFQGe+Bd1iAbz1/sH9H8l4StwX6egvTK3M\r\n" +"wXRwkKkvjKaEDA9ATbZx0mI8LGsxSuCqe9r9dyjmttd47J1p1Rulz3CLzaRcVIuS\r\n" +"RRQfaD8neM9c1S/iJ/amTVqJxA1KOdOS5780WhPfSArA+g4qAmSjelc3p4wWpha8\r\n" +"zhuYwjVuX6JHG0c=\r\n" +"-----END CERTIFICATE-----\r\n"; + +const char mbedtls_test_srv_key_rsa[] = +"-----BEGIN RSA PRIVATE KEY-----\r\n" +"MIIEpAIBAAKCAQEAwU2j3efNHdEE10lyuJmsDnjkOjxKzzoTFtBa5M2jAIin7h5r\r\n" +"lqdStJDvLXJ6PiSa/LY0rCT1d+AmZIycsCh9odrqjObJHJa8/sEEUrM21KP64bF2\r\n" +"2JDBYbRmUjaiJlOqq3ReB30Zgtsq2B+g2Q0cLUlm91slc0boC4pPaQy1AJDh2oIQ\r\n" +"Zn2uVCuLZXmRoeJhw81ASQjuaAzxi4bSRr/QuKoRAx5/VqgaHkQYDw+Fi9qLRF7i\r\n" +"GMZiL8dmjfpd2H3zJ4kpAcWQDj8n8TDISg7v1t7HxydrxwU9esQCPJodPg/oNJhb\r\n" +"y3NLUpbYEaIsgIhpOVrTD7DeWS8Rx/fqEgEwlwIDAQABAoIBAQCXR0S8EIHFGORZ\r\n" +"++AtOg6eENxD+xVs0f1IeGz57Tjo3QnXX7VBZNdj+p1ECvhCE/G7XnkgU5hLZX+G\r\n" +"Z0jkz/tqJOI0vRSdLBbipHnWouyBQ4e/A1yIJdlBtqXxJ1KE/ituHRbNc4j4kL8Z\r\n" +"/r6pvwnTI0PSx2Eqs048YdS92LT6qAv4flbNDxMn2uY7s4ycS4Q8w1JXnCeaAnYm\r\n" +"WYI5wxO+bvRELR2Mcz5DmVnL8jRyml6l6582bSv5oufReFIbyPZbQWlXgYnpu6He\r\n" +"GTc7E1zKYQGG/9+DQUl/1vQuCPqQwny0tQoX2w5tdYpdMdVm+zkLtbajzdTviJJa\r\n" +"TWzL6lt5AoGBAN86+SVeJDcmQJcv4Eq6UhtRr4QGMiQMz0Sod6ettYxYzMgxtw28\r\n" +"CIrgpozCc+UaZJLo7UxvC6an85r1b2nKPCLQFaggJ0H4Q0J/sZOhBIXaoBzWxveK\r\n" +"nupceKdVxGsFi8CDy86DBfiyFivfBj+47BbaQzPBj7C4rK7UlLjab2rDAoGBAN2u\r\n" +"AM2gchoFiu4v1HFL8D7lweEpi6ZnMJjnEu/dEgGQJFjwdpLnPbsj4c75odQ4Gz8g\r\n" +"sw9lao9VVzbusoRE/JGI4aTdO0pATXyG7eG1Qu+5Yc1YGXcCrliA2xM9xx+d7f+s\r\n" +"mPzN+WIEg5GJDYZDjAzHG5BNvi/FfM1C9dOtjv2dAoGAF0t5KmwbjWHBhcVqO4Ic\r\n" +"BVvN3BIlc1ue2YRXEDlxY5b0r8N4XceMgKmW18OHApZxfl8uPDauWZLXOgl4uepv\r\n" +"whZC3EuWrSyyICNhLY21Ah7hbIEBPF3L3ZsOwC+UErL+dXWLdB56Jgy3gZaBeW7b\r\n" +"vDrEnocJbqCm7IukhXHOBK8CgYEAwqdHB0hqyNSzIOGY7v9abzB6pUdA3BZiQvEs\r\n" +"3LjHVd4HPJ2x0N8CgrBIWOE0q8+0hSMmeE96WW/7jD3fPWwCR5zlXknxBQsfv0gP\r\n" +"3BC5PR0Qdypz+d+9zfMf625kyit4T/hzwhDveZUzHnk1Cf+IG7Q+TOEnLnWAWBED\r\n" +"ISOWmrUCgYAFEmRxgwAc/u+D6t0syCwAYh6POtscq9Y0i9GyWk89NzgC4NdwwbBH\r\n" +"4AgahOxIxXx2gxJnq3yfkJfIjwf0s2DyP0kY2y6Ua1OeomPeY9mrIS4tCuDQ6LrE\r\n" +"TB6l9VGoxJL4fyHnZb8L5gGvnB1bbD8cL6YPaDiOhcRseC9vBiEuVg==\r\n" +"-----END RSA PRIVATE KEY-----\r\n"; + +const char mbedtls_test_cli_crt_rsa[] = +"-----BEGIN CERTIFICATE-----\r\n" +"MIIDPzCCAiegAwIBAgIBBDANBgkqhkiG9w0BAQUFADA7MQswCQYDVQQGEwJOTDER\r\n" +"MA8GA1UEChMIUG9sYXJTU0wxGTAXBgNVBAMTEFBvbGFyU1NMIFRlc3QgQ0EwHhcN\r\n" +"MTEwMjEyMTQ0NDA3WhcNMjEwMjEyMTQ0NDA3WjA8MQswCQYDVQQGEwJOTDERMA8G\r\n" +"A1UEChMIUG9sYXJTU0wxGjAYBgNVBAMTEVBvbGFyU1NMIENsaWVudCAyMIIBIjAN\r\n" +"BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyHTEzLn5tXnpRdkUYLB9u5Pyax6f\r\n" +"M60Nj4o8VmXl3ETZzGaFB9X4J7BKNdBjngpuG7fa8H6r7gwQk4ZJGDTzqCrSV/Uu\r\n" +"1C93KYRhTYJQj6eVSHD1bk2y1RPD0hrt5kPqQhTrdOrA7R/UV06p86jt0uDBMHEw\r\n" +"MjDV0/YI0FZPRo7yX/k9Z5GIMC5Cst99++UMd//sMcB4j7/Cf8qtbCHWjdmLao5v\r\n" +"4Jv4EFbMs44TFeY0BGbH7vk2DmqV9gmaBmf0ZXH4yqSxJeD+PIs1BGe64E92hfx/\r\n" +"/DZrtenNLQNiTrM9AM+vdqBpVoNq0qjU51Bx5rU2BXcFbXvI5MT9TNUhXwIDAQAB\r\n" +"o00wSzAJBgNVHRMEAjAAMB0GA1UdDgQWBBRxoQBzckAvVHZeM/xSj7zx3WtGITAf\r\n" +"BgNVHSMEGDAWgBS0WuSls97SUva51aaVD+s+vMf9/zANBgkqhkiG9w0BAQUFAAOC\r\n" +"AQEAAn86isAM8X+mVwJqeItt6E9slhEQbAofyk+diH1Lh8Y9iLlWQSKbw/UXYjx5\r\n" +"LLPZcniovxIcARC/BjyZR9g3UwTHNGNm+rwrqa15viuNOFBchykX/Orsk02EH7NR\r\n" +"Alw5WLPorYjED6cdVQgBl9ot93HdJogRiXCxErM7NC8/eP511mjq+uLDjLKH8ZPQ\r\n" +"8I4ekHJnroLsDkIwXKGIsvIBHQy2ac/NwHLCQOK6mfum1pRx52V4Utu5dLLjD5bM\r\n" +"xOBC7KU4xZKuMXXZM6/93Yb51K/J4ahf1TxJlTWXtnzDr9saEYdNy2SKY/6ZiDNH\r\n" +"D+stpAKiQLAWaAusIWKYEyw9MQ==\r\n" +"-----END CERTIFICATE-----\r\n"; + +const char mbedtls_test_cli_key_rsa[] = +"-----BEGIN RSA PRIVATE KEY-----\r\n" +"MIIEpAIBAAKCAQEAyHTEzLn5tXnpRdkUYLB9u5Pyax6fM60Nj4o8VmXl3ETZzGaF\r\n" +"B9X4J7BKNdBjngpuG7fa8H6r7gwQk4ZJGDTzqCrSV/Uu1C93KYRhTYJQj6eVSHD1\r\n" +"bk2y1RPD0hrt5kPqQhTrdOrA7R/UV06p86jt0uDBMHEwMjDV0/YI0FZPRo7yX/k9\r\n" +"Z5GIMC5Cst99++UMd//sMcB4j7/Cf8qtbCHWjdmLao5v4Jv4EFbMs44TFeY0BGbH\r\n" +"7vk2DmqV9gmaBmf0ZXH4yqSxJeD+PIs1BGe64E92hfx//DZrtenNLQNiTrM9AM+v\r\n" +"dqBpVoNq0qjU51Bx5rU2BXcFbXvI5MT9TNUhXwIDAQABAoIBAGdNtfYDiap6bzst\r\n" +"yhCiI8m9TtrhZw4MisaEaN/ll3XSjaOG2dvV6xMZCMV+5TeXDHOAZnY18Yi18vzz\r\n" +"4Ut2TnNFzizCECYNaA2fST3WgInnxUkV3YXAyP6CNxJaCmv2aA0yFr2kFVSeaKGt\r\n" +"ymvljNp2NVkvm7Th8fBQBO7I7AXhz43k0mR7XmPgewe8ApZOG3hstkOaMvbWAvWA\r\n" +"zCZupdDjZYjOJqlA4eEA4H8/w7F83r5CugeBE8LgEREjLPiyejrU5H1fubEY+h0d\r\n" +"l5HZBJ68ybTXfQ5U9o/QKA3dd0toBEhhdRUDGzWtjvwkEQfqF1reGWj/tod/gCpf\r\n" +"DFi6X0ECgYEA4wOv/pjSC3ty6TuOvKX2rOUiBrLXXv2JSxZnMoMiWI5ipLQt+RYT\r\n" +"VPafL/m7Dn6MbwjayOkcZhBwk5CNz5A6Q4lJ64Mq/lqHznRCQQ2Mc1G8eyDF/fYL\r\n" +"Ze2pLvwP9VD5jTc2miDfw+MnvJhywRRLcemDFP8k4hQVtm8PMp3ZmNECgYEA4gz7\r\n" +"wzObR4gn8ibe617uQPZjWzUj9dUHYd+in1gwBCIrtNnaRn9I9U/Q6tegRYpii4ys\r\n" +"c176NmU+umy6XmuSKV5qD9bSpZWG2nLFnslrN15Lm3fhZxoeMNhBaEDTnLT26yoi\r\n" +"33gp0mSSWy94ZEqipms+ULF6sY1ZtFW6tpGFoy8CgYAQHhnnvJflIs2ky4q10B60\r\n" +"ZcxFp3rtDpkp0JxhFLhiizFrujMtZSjYNm5U7KkgPVHhLELEUvCmOnKTt4ap/vZ0\r\n" +"BxJNe1GZH3pW6SAvGDQpl9sG7uu/vTFP+lCxukmzxB0DrrDcvorEkKMom7ZCCRvW\r\n" +"KZsZ6YeH2Z81BauRj218kQKBgQCUV/DgKP2985xDTT79N08jUo3hTP5MVYCCuj/+\r\n" +"UeEw1TvZcx3LJby7P6Xad6a1/BqveaGyFKIfEFIaBUBItk801sDDpDaYc4gL00Xc\r\n" +"7lFuBHOZkxJYlss5QrGpuOEl9ZwUt5IrFLBdYaKqNHzNVC1pCPfb/JyH6Dr2HUxq\r\n" +"gxUwAQKBgQCcU6G2L8AG9d9c0UpOyL1tMvFe5Ttw0KjlQVdsh1MP6yigYo9DYuwu\r\n" +"bHFVW2r0dBTqegP2/KTOxKzaHfC1qf0RGDsUoJCNJrd1cwoCLG8P2EF4w3OBrKqv\r\n" +"8u4ytY0F+Vlanj5lm3TaoHSVF1+NWPyOTiwevIECGKwSxvlki4fDAA==\r\n" +"-----END RSA PRIVATE KEY-----\r\n"; + +const size_t mbedtls_test_ca_crt_rsa_len = sizeof( mbedtls_test_ca_crt_rsa ); +const size_t mbedtls_test_ca_key_rsa_len = sizeof( mbedtls_test_ca_key_rsa ); +const size_t mbedtls_test_ca_pwd_rsa_len = sizeof( mbedtls_test_ca_pwd_rsa ) - 1; +const size_t mbedtls_test_srv_crt_rsa_len = sizeof( mbedtls_test_srv_crt_rsa ); +const size_t mbedtls_test_srv_key_rsa_len = sizeof( mbedtls_test_srv_key_rsa ); +const size_t mbedtls_test_cli_crt_rsa_len = sizeof( mbedtls_test_cli_crt_rsa ); +const size_t mbedtls_test_cli_key_rsa_len = sizeof( mbedtls_test_cli_key_rsa ); +#else +#define TEST_CA_CRT_RSA +#endif /* MBEDTLS_RSA_C */ + +#if defined(MBEDTLS_PEM_PARSE_C) +/* Concatenation of all available CA certificates */ +const char mbedtls_test_cas_pem[] = TEST_CA_CRT_RSA TEST_CA_CRT_EC; +const size_t mbedtls_test_cas_pem_len = sizeof( mbedtls_test_cas_pem ); +#endif + +/* List of all available CA certificates */ +const char * mbedtls_test_cas[] = { +#if defined(MBEDTLS_RSA_C) + mbedtls_test_ca_crt_rsa, +#endif +#if defined(MBEDTLS_ECDSA_C) + mbedtls_test_ca_crt_ec, +#endif + NULL +}; +const size_t mbedtls_test_cas_len[] = { +#if defined(MBEDTLS_RSA_C) + sizeof( mbedtls_test_ca_crt_rsa ), +#endif +#if defined(MBEDTLS_ECDSA_C) + sizeof( mbedtls_test_ca_crt_ec ), +#endif + 0 +}; + +#if defined(MBEDTLS_RSA_C) +const char *mbedtls_test_ca_crt = mbedtls_test_ca_crt_rsa; +const char *mbedtls_test_ca_key = mbedtls_test_ca_key_rsa; +const char *mbedtls_test_ca_pwd = mbedtls_test_ca_pwd_rsa; +const char *mbedtls_test_srv_crt = mbedtls_test_srv_crt_rsa; +const char *mbedtls_test_srv_key = mbedtls_test_srv_key_rsa; +const char *mbedtls_test_cli_crt = mbedtls_test_cli_crt_rsa; +const char *mbedtls_test_cli_key = mbedtls_test_cli_key_rsa; +const size_t mbedtls_test_ca_crt_len = sizeof( mbedtls_test_ca_crt_rsa ); +const size_t mbedtls_test_ca_key_len = sizeof( mbedtls_test_ca_key_rsa ); +const size_t mbedtls_test_ca_pwd_len = sizeof( mbedtls_test_ca_pwd_rsa ) - 1; +const size_t mbedtls_test_srv_crt_len = sizeof( mbedtls_test_srv_crt_rsa ); +const size_t mbedtls_test_srv_key_len = sizeof( mbedtls_test_srv_key_rsa ); +const size_t mbedtls_test_cli_crt_len = sizeof( mbedtls_test_cli_crt_rsa ); +const size_t mbedtls_test_cli_key_len = sizeof( mbedtls_test_cli_key_rsa ); +#else /* ! MBEDTLS_RSA_C, so MBEDTLS_ECDSA_C */ +const char *mbedtls_test_ca_crt = mbedtls_test_ca_crt_ec; +const char *mbedtls_test_ca_key = mbedtls_test_ca_key_ec; +const char *mbedtls_test_ca_pwd = mbedtls_test_ca_pwd_ec; +const char *mbedtls_test_srv_crt = mbedtls_test_srv_crt_ec; +const char *mbedtls_test_srv_key = mbedtls_test_srv_key_ec; +const char *mbedtls_test_cli_crt = mbedtls_test_cli_crt_ec; +const char *mbedtls_test_cli_key = mbedtls_test_cli_key_ec; +const size_t mbedtls_test_ca_crt_len = sizeof( mbedtls_test_ca_crt_ec ); +const size_t mbedtls_test_ca_key_len = sizeof( mbedtls_test_ca_key_ec ); +const size_t mbedtls_test_ca_pwd_len = sizeof( mbedtls_test_ca_pwd_ec ) - 1; +const size_t mbedtls_test_srv_crt_len = sizeof( mbedtls_test_srv_crt_ec ); +const size_t mbedtls_test_srv_key_len = sizeof( mbedtls_test_srv_key_ec ); +const size_t mbedtls_test_cli_crt_len = sizeof( mbedtls_test_cli_crt_ec ); +const size_t mbedtls_test_cli_key_len = sizeof( mbedtls_test_cli_key_ec ); +#endif /* MBEDTLS_RSA_C */ + +#endif /* MBEDTLS_CERTS_C */ diff --git a/security/mbedtls/src/cipher.c b/security/mbedtls/src/cipher.c new file mode 100644 index 0000000000..68baa0a5f3 --- /dev/null +++ b/security/mbedtls/src/cipher.c @@ -0,0 +1,925 @@ +/** + * \file cipher.c + * + * \brief Generic cipher wrapper for mbed TLS + * + * \author Adriaan de Jong + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_CIPHER_C) + +#include "mbedtls/cipher.h" +#include "mbedtls/cipher_internal.h" + +#include +#include + +#if defined(MBEDTLS_AES_ALT) +#include "mbedtls/aes.h" +#endif + +#if defined(MBEDTLS_GCM_C) +#include "mbedtls/gcm.h" +#endif + +#if defined(MBEDTLS_CCM_C) +#include "mbedtls/ccm.h" +#endif + +#if defined(MBEDTLS_CMAC_C) +#include "mbedtls/cmac.h" +#endif + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#define mbedtls_calloc calloc +#define mbedtls_free free +#endif + +#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) +#define MBEDTLS_CIPHER_MODE_STREAM +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0; +} + +static int supported_init = 0; + +const int *mbedtls_cipher_list( void ) +{ + const mbedtls_cipher_definition_t *def; + int *type; + + if( ! supported_init ) + { + def = mbedtls_cipher_definitions; + type = mbedtls_cipher_supported; + + while( def->type != 0 ) + *type++ = (*def++).type; + + *type = 0; + + supported_init = 1; + } + + return( mbedtls_cipher_supported ); +} + +const mbedtls_cipher_info_t *mbedtls_cipher_info_from_type( const mbedtls_cipher_type_t cipher_type ) +{ + const mbedtls_cipher_definition_t *def; + + for( def = mbedtls_cipher_definitions; def->info != NULL; def++ ) + if( def->type == cipher_type ) + return( def->info ); + + return( NULL ); +} + +const mbedtls_cipher_info_t *mbedtls_cipher_info_from_string( const char *cipher_name ) +{ + const mbedtls_cipher_definition_t *def; + + if( NULL == cipher_name ) + return( NULL ); + + for( def = mbedtls_cipher_definitions; def->info != NULL; def++ ) + if( ! strcmp( def->info->name, cipher_name ) ) + return( def->info ); + + return( NULL ); +} + +const mbedtls_cipher_info_t *mbedtls_cipher_info_from_values( const mbedtls_cipher_id_t cipher_id, + int key_bitlen, + const mbedtls_cipher_mode_t mode ) +{ + const mbedtls_cipher_definition_t *def; + + for( def = mbedtls_cipher_definitions; def->info != NULL; def++ ) + if( def->info->base->cipher == cipher_id && + def->info->key_bitlen == (unsigned) key_bitlen && + def->info->mode == mode ) + return( def->info ); + + return( NULL ); +} + +void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) ); +} + +void mbedtls_cipher_free( mbedtls_cipher_context_t *ctx ) +{ + if( ctx == NULL ) + return; + +#if defined(MBEDTLS_CMAC_C) + if( ctx->cmac_ctx ) + { + mbedtls_zeroize( ctx->cmac_ctx, sizeof( mbedtls_cmac_context_t ) ); + mbedtls_free( ctx->cmac_ctx ); + } +#endif + + if( ctx->cipher_ctx ) + ctx->cipher_info->base->ctx_free_func( ctx->cipher_ctx ); + + mbedtls_zeroize( ctx, sizeof(mbedtls_cipher_context_t) ); +} + +int mbedtls_cipher_setup( mbedtls_cipher_context_t *ctx, const mbedtls_cipher_info_t *cipher_info ) +{ + if( NULL == cipher_info || NULL == ctx ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + memset( ctx, 0, sizeof( mbedtls_cipher_context_t ) ); + + if( NULL == ( ctx->cipher_ctx = cipher_info->base->ctx_alloc_func() ) ) + return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED ); + + ctx->cipher_info = cipher_info; + +#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) + /* + * Ignore possible errors caused by a cipher mode that doesn't use padding + */ +#if defined(MBEDTLS_CIPHER_PADDING_PKCS7) + (void) mbedtls_cipher_set_padding_mode( ctx, MBEDTLS_PADDING_PKCS7 ); +#else + (void) mbedtls_cipher_set_padding_mode( ctx, MBEDTLS_PADDING_NONE ); +#endif +#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ + + return( 0 ); +} + +int mbedtls_cipher_setkey( mbedtls_cipher_context_t *ctx, const unsigned char *key, + int key_bitlen, const mbedtls_operation_t operation ) +{ + if( NULL == ctx || NULL == ctx->cipher_info ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_KEY_LEN ) == 0 && + (int) ctx->cipher_info->key_bitlen != key_bitlen ) + { + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + } + + ctx->key_bitlen = key_bitlen; + ctx->operation = operation; + + /* + * For CFB and CTR mode always use the encryption key schedule + */ + if( MBEDTLS_ENCRYPT == operation || + MBEDTLS_MODE_CFB == ctx->cipher_info->mode || + MBEDTLS_MODE_CTR == ctx->cipher_info->mode ) + { + return ctx->cipher_info->base->setkey_enc_func( ctx->cipher_ctx, key, + ctx->key_bitlen ); + } + + if( MBEDTLS_DECRYPT == operation ) + return ctx->cipher_info->base->setkey_dec_func( ctx->cipher_ctx, key, + ctx->key_bitlen ); + + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); +} + +int mbedtls_cipher_set_iv( mbedtls_cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len ) +{ + size_t actual_iv_size; + + if( NULL == ctx || NULL == ctx->cipher_info || NULL == iv ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + /* avoid buffer overflow in ctx->iv */ + if( iv_len > MBEDTLS_MAX_IV_LENGTH ) + return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); + + if( ( ctx->cipher_info->flags & MBEDTLS_CIPHER_VARIABLE_IV_LEN ) != 0 ) + actual_iv_size = iv_len; + else + { + actual_iv_size = ctx->cipher_info->iv_size; + + /* avoid reading past the end of input buffer */ + if( actual_iv_size > iv_len ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + } + + memcpy( ctx->iv, iv, actual_iv_size ); + ctx->iv_size = actual_iv_size; + + return( 0 ); +} + +int mbedtls_cipher_reset( mbedtls_cipher_context_t *ctx ) +{ + if( NULL == ctx || NULL == ctx->cipher_info ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + ctx->unprocessed_len = 0; + +#if defined(MBEDTLS_AES_ALT) + ((mbedtls_aes_context *)(ctx->cipher_ctx))->status = AES_STATUS_INIT; +#endif + + return( 0 ); +} + +#if defined(MBEDTLS_GCM_C) +int mbedtls_cipher_update_ad( mbedtls_cipher_context_t *ctx, + const unsigned char *ad, size_t ad_len ) +{ + if( NULL == ctx || NULL == ctx->cipher_info ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) + { + return mbedtls_gcm_starts( (mbedtls_gcm_context *) ctx->cipher_ctx, ctx->operation, + ctx->iv, ctx->iv_size, ad, ad_len ); + } + + return( 0 ); +} +#endif /* MBEDTLS_GCM_C */ + +int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *input, + size_t ilen, unsigned char *output, size_t *olen ) +{ + int ret; + size_t block_size = 0; + + if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen ) + { + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + } + + *olen = 0; + block_size = mbedtls_cipher_get_block_size( ctx ); + + if( ctx->cipher_info->mode == MBEDTLS_MODE_ECB ) + { + if( ilen != block_size ) + return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); + + *olen = ilen; + + if( 0 != ( ret = ctx->cipher_info->base->ecb_func( ctx->cipher_ctx, + ctx->operation, input, output ) ) ) + { + return( ret ); + } + + return( 0 ); + } + +#if defined(MBEDTLS_GCM_C) + if( ctx->cipher_info->mode == MBEDTLS_MODE_GCM ) + { + *olen = ilen; + return mbedtls_gcm_update( (mbedtls_gcm_context *) ctx->cipher_ctx, ilen, input, + output ); + } +#endif + + if ( 0 == block_size ) + { + return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT; + } + + if( input == output && + ( ctx->unprocessed_len != 0 || ilen % block_size ) ) + { + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + } + +#if defined(MBEDTLS_CIPHER_MODE_CBC) + if( ctx->cipher_info->mode == MBEDTLS_MODE_CBC ) + { + size_t copy_len = 0; + + /* + * If there is not enough data for a full block, cache it. + */ + if( ( ctx->operation == MBEDTLS_DECRYPT && + ilen <= block_size - ctx->unprocessed_len ) || + ( ctx->operation == MBEDTLS_ENCRYPT && + ilen < block_size - ctx->unprocessed_len ) ) + { + memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input, + ilen ); + + ctx->unprocessed_len += ilen; + return( 0 ); + } + + /* + * Process cached data first + */ + if( 0 != ctx->unprocessed_len ) + { + copy_len = block_size - ctx->unprocessed_len; + + memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input, + copy_len ); + + if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, + ctx->operation, block_size, ctx->iv, + ctx->unprocessed_data, output ) ) ) + { + return( ret ); + } + + *olen += block_size; + output += block_size; + ctx->unprocessed_len = 0; + + input += copy_len; + ilen -= copy_len; + } + + /* + * Cache final, incomplete block + */ + if( 0 != ilen ) + { + if( 0 == block_size ) + { + return MBEDTLS_ERR_CIPHER_INVALID_CONTEXT; + } + + copy_len = ilen % block_size; + if( copy_len == 0 && ctx->operation == MBEDTLS_DECRYPT ) + copy_len = block_size; + + memcpy( ctx->unprocessed_data, &( input[ilen - copy_len] ), + copy_len ); + + ctx->unprocessed_len += copy_len; + ilen -= copy_len; + } + + /* + * Process remaining full blocks + */ + if( ilen ) + { + if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, + ctx->operation, ilen, ctx->iv, input, output ) ) ) + { + return( ret ); + } + + *olen += ilen; + } + + return( 0 ); + } +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) + if( ctx->cipher_info->mode == MBEDTLS_MODE_CFB ) + { + if( 0 != ( ret = ctx->cipher_info->base->cfb_func( ctx->cipher_ctx, + ctx->operation, ilen, &ctx->unprocessed_len, ctx->iv, + input, output ) ) ) + { + return( ret ); + } + + *olen = ilen; + + return( 0 ); + } +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) + if( ctx->cipher_info->mode == MBEDTLS_MODE_CTR ) + { + if( 0 != ( ret = ctx->cipher_info->base->ctr_func( ctx->cipher_ctx, + ilen, &ctx->unprocessed_len, ctx->iv, + ctx->unprocessed_data, input, output ) ) ) + { + return( ret ); + } + + *olen = ilen; + + return( 0 ); + } +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + if( ctx->cipher_info->mode == MBEDTLS_MODE_STREAM ) + { + if( 0 != ( ret = ctx->cipher_info->base->stream_func( ctx->cipher_ctx, + ilen, input, output ) ) ) + { + return( ret ); + } + + *olen = ilen; + + return( 0 ); + } +#endif /* MBEDTLS_CIPHER_MODE_STREAM */ + + return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); +} + +#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) +#if defined(MBEDTLS_CIPHER_PADDING_PKCS7) +/* + * PKCS7 (and PKCS5) padding: fill with ll bytes, with ll = padding_len + */ +static void add_pkcs_padding( unsigned char *output, size_t output_len, + size_t data_len ) +{ + size_t padding_len = output_len - data_len; + unsigned char i; + + for( i = 0; i < padding_len; i++ ) + output[data_len + i] = (unsigned char) padding_len; +} + +static int get_pkcs_padding( unsigned char *input, size_t input_len, + size_t *data_len ) +{ + size_t i, pad_idx; + unsigned char padding_len, bad = 0; + + if( NULL == input || NULL == data_len ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + padding_len = input[input_len - 1]; + *data_len = input_len - padding_len; + + /* Avoid logical || since it results in a branch */ + bad |= padding_len > input_len; + bad |= padding_len == 0; + + /* The number of bytes checked must be independent of padding_len, + * so pick input_len, which is usually 8 or 16 (one block) */ + pad_idx = input_len - padding_len; + for( i = 0; i < input_len; i++ ) + bad |= ( input[i] ^ padding_len ) * ( i >= pad_idx ); + + return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) ); +} +#endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */ + +#if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS) +/* + * One and zeros padding: fill with 80 00 ... 00 + */ +static void add_one_and_zeros_padding( unsigned char *output, + size_t output_len, size_t data_len ) +{ + size_t padding_len = output_len - data_len; + unsigned char i = 0; + + output[data_len] = 0x80; + for( i = 1; i < padding_len; i++ ) + output[data_len + i] = 0x00; +} + +static int get_one_and_zeros_padding( unsigned char *input, size_t input_len, + size_t *data_len ) +{ + size_t i; + unsigned char done = 0, prev_done, bad; + + if( NULL == input || NULL == data_len ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + bad = 0xFF; + *data_len = 0; + for( i = input_len; i > 0; i-- ) + { + prev_done = done; + done |= ( input[i-1] != 0 ); + *data_len |= ( i - 1 ) * ( done != prev_done ); + bad &= ( input[i-1] ^ 0x80 ) | ( done == prev_done ); + } + + return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) ); + +} +#endif /* MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS */ + +#if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN) +/* + * Zeros and len padding: fill with 00 ... 00 ll, where ll is padding length + */ +static void add_zeros_and_len_padding( unsigned char *output, + size_t output_len, size_t data_len ) +{ + size_t padding_len = output_len - data_len; + unsigned char i = 0; + + for( i = 1; i < padding_len; i++ ) + output[data_len + i - 1] = 0x00; + output[output_len - 1] = (unsigned char) padding_len; +} + +static int get_zeros_and_len_padding( unsigned char *input, size_t input_len, + size_t *data_len ) +{ + size_t i, pad_idx; + unsigned char padding_len, bad = 0; + + if( NULL == input || NULL == data_len ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + padding_len = input[input_len - 1]; + *data_len = input_len - padding_len; + + /* Avoid logical || since it results in a branch */ + bad |= padding_len > input_len; + bad |= padding_len == 0; + + /* The number of bytes checked must be independent of padding_len */ + pad_idx = input_len - padding_len; + for( i = 0; i < input_len - 1; i++ ) + bad |= input[i] * ( i >= pad_idx ); + + return( MBEDTLS_ERR_CIPHER_INVALID_PADDING * ( bad != 0 ) ); +} +#endif /* MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN */ + +#if defined(MBEDTLS_CIPHER_PADDING_ZEROS) +/* + * Zero padding: fill with 00 ... 00 + */ +static void add_zeros_padding( unsigned char *output, + size_t output_len, size_t data_len ) +{ + size_t i; + + for( i = data_len; i < output_len; i++ ) + output[i] = 0x00; +} + +static int get_zeros_padding( unsigned char *input, size_t input_len, + size_t *data_len ) +{ + size_t i; + unsigned char done = 0, prev_done; + + if( NULL == input || NULL == data_len ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + *data_len = 0; + for( i = input_len; i > 0; i-- ) + { + prev_done = done; + done |= ( input[i-1] != 0 ); + *data_len |= i * ( done != prev_done ); + } + + return( 0 ); +} +#endif /* MBEDTLS_CIPHER_PADDING_ZEROS */ + +/* + * No padding: don't pad :) + * + * There is no add_padding function (check for NULL in mbedtls_cipher_finish) + * but a trivial get_padding function + */ +static int get_no_padding( unsigned char *input, size_t input_len, + size_t *data_len ) +{ + if( NULL == input || NULL == data_len ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + *data_len = input_len; + + return( 0 ); +} +#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ + +int mbedtls_cipher_finish( mbedtls_cipher_context_t *ctx, + unsigned char *output, size_t *olen ) +{ + if( NULL == ctx || NULL == ctx->cipher_info || NULL == olen ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + *olen = 0; + + if( MBEDTLS_MODE_CFB == ctx->cipher_info->mode || + MBEDTLS_MODE_CTR == ctx->cipher_info->mode || + MBEDTLS_MODE_GCM == ctx->cipher_info->mode || + MBEDTLS_MODE_STREAM == ctx->cipher_info->mode ) + { + return( 0 ); + } + + if( MBEDTLS_MODE_ECB == ctx->cipher_info->mode ) + { + if( ctx->unprocessed_len != 0 ) + return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); + + return( 0 ); + } + +#if defined(MBEDTLS_CIPHER_MODE_CBC) + if( MBEDTLS_MODE_CBC == ctx->cipher_info->mode ) + { + int ret = 0; + + if( MBEDTLS_ENCRYPT == ctx->operation ) + { + /* check for 'no padding' mode */ + if( NULL == ctx->add_padding ) + { + if( 0 != ctx->unprocessed_len ) + return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); + + return( 0 ); + } + + ctx->add_padding( ctx->unprocessed_data, mbedtls_cipher_get_iv_size( ctx ), + ctx->unprocessed_len ); + } + else if( mbedtls_cipher_get_block_size( ctx ) != ctx->unprocessed_len ) + { + /* + * For decrypt operations, expect a full block, + * or an empty block if no padding + */ + if( NULL == ctx->add_padding && 0 == ctx->unprocessed_len ) + return( 0 ); + + return( MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED ); + } + + /* cipher block */ + if( 0 != ( ret = ctx->cipher_info->base->cbc_func( ctx->cipher_ctx, + ctx->operation, mbedtls_cipher_get_block_size( ctx ), ctx->iv, + ctx->unprocessed_data, output ) ) ) + { + return( ret ); + } + + /* Set output size for decryption */ + if( MBEDTLS_DECRYPT == ctx->operation ) + return ctx->get_padding( output, mbedtls_cipher_get_block_size( ctx ), + olen ); + + /* Set output size for encryption */ + *olen = mbedtls_cipher_get_block_size( ctx ); + return( 0 ); + } +#else + ((void) output); +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + + return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); +} + +#if defined(MBEDTLS_CIPHER_MODE_WITH_PADDING) +int mbedtls_cipher_set_padding_mode( mbedtls_cipher_context_t *ctx, mbedtls_cipher_padding_t mode ) +{ + if( NULL == ctx || + MBEDTLS_MODE_CBC != ctx->cipher_info->mode ) + { + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + } + + switch( mode ) + { +#if defined(MBEDTLS_CIPHER_PADDING_PKCS7) + case MBEDTLS_PADDING_PKCS7: + ctx->add_padding = add_pkcs_padding; + ctx->get_padding = get_pkcs_padding; + break; +#endif +#if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS) + case MBEDTLS_PADDING_ONE_AND_ZEROS: + ctx->add_padding = add_one_and_zeros_padding; + ctx->get_padding = get_one_and_zeros_padding; + break; +#endif +#if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN) + case MBEDTLS_PADDING_ZEROS_AND_LEN: + ctx->add_padding = add_zeros_and_len_padding; + ctx->get_padding = get_zeros_and_len_padding; + break; +#endif +#if defined(MBEDTLS_CIPHER_PADDING_ZEROS) + case MBEDTLS_PADDING_ZEROS: + ctx->add_padding = add_zeros_padding; + ctx->get_padding = get_zeros_padding; + break; +#endif + case MBEDTLS_PADDING_NONE: + ctx->add_padding = NULL; + ctx->get_padding = get_no_padding; + break; + + default: + return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); + } + + return( 0 ); +} +#endif /* MBEDTLS_CIPHER_MODE_WITH_PADDING */ + +#if defined(MBEDTLS_GCM_C) +int mbedtls_cipher_write_tag( mbedtls_cipher_context_t *ctx, + unsigned char *tag, size_t tag_len ) +{ + if( NULL == ctx || NULL == ctx->cipher_info || NULL == tag ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + if( MBEDTLS_ENCRYPT != ctx->operation ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) + return mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx, tag, tag_len ); + + return( 0 ); +} + +int mbedtls_cipher_check_tag( mbedtls_cipher_context_t *ctx, + const unsigned char *tag, size_t tag_len ) +{ + int ret; + + if( NULL == ctx || NULL == ctx->cipher_info || + MBEDTLS_DECRYPT != ctx->operation ) + { + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + } + + if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) + { + unsigned char check_tag[16]; + size_t i; + int diff; + + if( tag_len > sizeof( check_tag ) ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + if( 0 != ( ret = mbedtls_gcm_finish( (mbedtls_gcm_context *) ctx->cipher_ctx, + check_tag, tag_len ) ) ) + { + return( ret ); + } + + /* Check the tag in "constant-time" */ + for( diff = 0, i = 0; i < tag_len; i++ ) + diff |= tag[i] ^ check_tag[i]; + + if( diff != 0 ) + return( MBEDTLS_ERR_CIPHER_AUTH_FAILED ); + + return( 0 ); + } + + return( 0 ); +} +#endif /* MBEDTLS_GCM_C */ + +/* + * Packet-oriented wrapper for non-AEAD modes + */ +int mbedtls_cipher_crypt( mbedtls_cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen ) +{ + int ret; + size_t finish_olen; + + if( ( ret = mbedtls_cipher_set_iv( ctx, iv, iv_len ) ) != 0 ) + return( ret ); + + if( ( ret = mbedtls_cipher_reset( ctx ) ) != 0 ) + return( ret ); + + if( ( ret = mbedtls_cipher_update( ctx, input, ilen, output, olen ) ) != 0 ) + return( ret ); + + if( ( ret = mbedtls_cipher_finish( ctx, output + *olen, &finish_olen ) ) != 0 ) + return( ret ); + + *olen += finish_olen; + + return( 0 ); +} + +#if defined(MBEDTLS_CIPHER_MODE_AEAD) +/* + * Packet-oriented encryption for AEAD modes + */ +int mbedtls_cipher_auth_encrypt( mbedtls_cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *ad, size_t ad_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, + unsigned char *tag, size_t tag_len ) +{ +#if defined(MBEDTLS_GCM_C) + if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) + { + *olen = ilen; + return( mbedtls_gcm_crypt_and_tag( ctx->cipher_ctx, MBEDTLS_GCM_ENCRYPT, ilen, + iv, iv_len, ad, ad_len, input, output, + tag_len, tag ) ); + } +#endif /* MBEDTLS_GCM_C */ +#if defined(MBEDTLS_CCM_C) + if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode ) + { + *olen = ilen; + return( mbedtls_ccm_encrypt_and_tag( ctx->cipher_ctx, ilen, + iv, iv_len, ad, ad_len, input, output, + tag, tag_len ) ); + } +#endif /* MBEDTLS_CCM_C */ + + return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); +} + +/* + * Packet-oriented decryption for AEAD modes + */ +int mbedtls_cipher_auth_decrypt( mbedtls_cipher_context_t *ctx, + const unsigned char *iv, size_t iv_len, + const unsigned char *ad, size_t ad_len, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, + const unsigned char *tag, size_t tag_len ) +{ +#if defined(MBEDTLS_GCM_C) + if( MBEDTLS_MODE_GCM == ctx->cipher_info->mode ) + { + int ret; + + *olen = ilen; + ret = mbedtls_gcm_auth_decrypt( ctx->cipher_ctx, ilen, + iv, iv_len, ad, ad_len, + tag, tag_len, input, output ); + + if( ret == MBEDTLS_ERR_GCM_AUTH_FAILED ) + ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; + + return( ret ); + } +#endif /* MBEDTLS_GCM_C */ +#if defined(MBEDTLS_CCM_C) + if( MBEDTLS_MODE_CCM == ctx->cipher_info->mode ) + { + int ret; + + *olen = ilen; + ret = mbedtls_ccm_auth_decrypt( ctx->cipher_ctx, ilen, + iv, iv_len, ad, ad_len, + input, output, tag, tag_len ); + + if( ret == MBEDTLS_ERR_CCM_AUTH_FAILED ) + ret = MBEDTLS_ERR_CIPHER_AUTH_FAILED; + + return( ret ); + } +#endif /* MBEDTLS_CCM_C */ + + return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); +} +#endif /* MBEDTLS_CIPHER_MODE_AEAD */ + +#endif /* MBEDTLS_CIPHER_C */ diff --git a/security/mbedtls/src/cipher_wrap.c b/security/mbedtls/src/cipher_wrap.c new file mode 100644 index 0000000000..0315f20bc2 --- /dev/null +++ b/security/mbedtls/src/cipher_wrap.c @@ -0,0 +1,1500 @@ +/** + * \file cipher_wrap.c + * + * \brief Generic cipher wrapper for mbed TLS + * + * \author Adriaan de Jong + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_CIPHER_C) + +#include "mbedtls/cipher_internal.h" + +#if defined(MBEDTLS_AES_C) +#include "mbedtls/aes.h" +#endif + +#if defined(MBEDTLS_ARC4_C) +#include "mbedtls/arc4.h" +#endif + +#if defined(MBEDTLS_CAMELLIA_C) +#include "mbedtls/camellia.h" +#endif + +#if defined(MBEDTLS_DES_C) +#include "mbedtls/des.h" +#endif + +#if defined(MBEDTLS_BLOWFISH_C) +#include "mbedtls/blowfish.h" +#endif + +#if defined(MBEDTLS_GCM_C) +#include "mbedtls/gcm.h" +#endif + +#if defined(MBEDTLS_CCM_C) +#include "mbedtls/ccm.h" +#endif + +#if defined(MBEDTLS_CIPHER_NULL_CIPHER) +#include +#endif + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_calloc calloc +#define mbedtls_free free +#endif + +#if defined(MBEDTLS_GCM_C) +/* shared by all GCM ciphers */ +static void *gcm_ctx_alloc( void ) +{ + void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_gcm_context ) ); + + if( ctx != NULL ) + mbedtls_gcm_init( (mbedtls_gcm_context *) ctx ); + + return( ctx ); +} + +static void gcm_ctx_free( void *ctx ) +{ + mbedtls_gcm_free( ctx ); + mbedtls_free( ctx ); +} +#endif /* MBEDTLS_GCM_C */ + +#if defined(MBEDTLS_CCM_C) +/* shared by all CCM ciphers */ +static void *ccm_ctx_alloc( void ) +{ + void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ccm_context ) ); + + if( ctx != NULL ) + mbedtls_ccm_init( (mbedtls_ccm_context *) ctx ); + + return( ctx ); +} + +static void ccm_ctx_free( void *ctx ) +{ + mbedtls_ccm_free( ctx ); + mbedtls_free( ctx ); +} +#endif /* MBEDTLS_CCM_C */ + +#if defined(MBEDTLS_AES_C) + +#if !defined(MBEDTLS_AES_ALT) +static int aes_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_aes_crypt_ecb( (mbedtls_aes_context *) ctx, operation, input, output ); +} + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static int aes_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, size_t length, + unsigned char *iv, const unsigned char *input, unsigned char *output ) +{ + return mbedtls_aes_crypt_cbc( (mbedtls_aes_context *) ctx, operation, length, iv, input, + output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +static int aes_crypt_cfb128_wrap( void *ctx, mbedtls_operation_t operation, + size_t length, size_t *iv_off, unsigned char *iv, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_aes_crypt_cfb128( (mbedtls_aes_context *) ctx, operation, length, iv_off, iv, + input, output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +static int aes_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off, + unsigned char *nonce_counter, unsigned char *stream_block, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_aes_crypt_ctr( (mbedtls_aes_context *) ctx, length, nc_off, nonce_counter, + stream_block, input, output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +static int aes_setkey_dec_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_aes_setkey_dec( (mbedtls_aes_context *) ctx, key, key_bitlen ); +} + +static int aes_setkey_enc_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_aes_setkey_enc( (mbedtls_aes_context *) ctx, key, key_bitlen ); +} + +static void * aes_ctx_alloc( void ) +{ + mbedtls_aes_context *aes = mbedtls_calloc( 1, sizeof( mbedtls_aes_context ) ); + + if( aes == NULL ) + return( NULL ); + + mbedtls_aes_init( aes ); + + return( aes ); +} + +static void aes_ctx_free( void *ctx ) +{ + mbedtls_aes_free( (mbedtls_aes_context *) ctx ); + mbedtls_free( ctx ); +} + +#else /* MBEDTLS_AES_ALT */ + +static int aes_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_aes_crypt_ecb_alt( (mbedtls_aes_context *) ctx, operation, input, output ); +} + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static int aes_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, size_t length, + unsigned char *iv, const unsigned char *input, unsigned char *output ) +{ + return mbedtls_aes_crypt_cbc_alt( (mbedtls_aes_context *) ctx, operation, length, iv, input, + output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +static int aes_setkey_dec_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_aes_setkey_dec_alt( (mbedtls_aes_context *) ctx, key, key_bitlen ); +} + +static int aes_setkey_enc_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_aes_setkey_enc_alt( (mbedtls_aes_context *) ctx, key, key_bitlen ); +} + +static void* aes_ctx_alloc( void ) +{ + mbedtls_aes_context *aes = mbedtls_calloc( 1, sizeof( mbedtls_aes_context ) ); + + if( aes == NULL ) + return( NULL ); + + mbedtls_aes_init_alt( aes ); + + return( aes ); +} + +static void aes_ctx_free( void *ctx ) +{ + mbedtls_aes_free_alt( (mbedtls_aes_context *) ctx ); + mbedtls_free( ctx ); +} +#endif /* MBEDTLS_AES_ALT */ + +static const mbedtls_cipher_base_t aes_info = { + MBEDTLS_CIPHER_ID_AES, + aes_crypt_ecb_wrap, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + aes_crypt_cbc_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + aes_crypt_cfb128_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + aes_crypt_ctr_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + aes_setkey_enc_wrap, + aes_setkey_dec_wrap, + aes_ctx_alloc, + aes_ctx_free +}; + +static const mbedtls_cipher_info_t aes_128_ecb_info = { + MBEDTLS_CIPHER_AES_128_ECB, + MBEDTLS_MODE_ECB, + 128, + "AES-128-ECB", + 16, + 0, + 16, + &aes_info +}; + +static const mbedtls_cipher_info_t aes_192_ecb_info = { + MBEDTLS_CIPHER_AES_192_ECB, + MBEDTLS_MODE_ECB, + 192, + "AES-192-ECB", + 16, + 0, + 16, + &aes_info +}; + +static const mbedtls_cipher_info_t aes_256_ecb_info = { + MBEDTLS_CIPHER_AES_256_ECB, + MBEDTLS_MODE_ECB, + 256, + "AES-256-ECB", + 16, + 0, + 16, + &aes_info +}; + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static const mbedtls_cipher_info_t aes_128_cbc_info = { + MBEDTLS_CIPHER_AES_128_CBC, + MBEDTLS_MODE_CBC, + 128, + "AES-128-CBC", + 16, + 0, + 16, + &aes_info +}; + +static const mbedtls_cipher_info_t aes_192_cbc_info = { + MBEDTLS_CIPHER_AES_192_CBC, + MBEDTLS_MODE_CBC, + 192, + "AES-192-CBC", + 16, + 0, + 16, + &aes_info +}; + +static const mbedtls_cipher_info_t aes_256_cbc_info = { + MBEDTLS_CIPHER_AES_256_CBC, + MBEDTLS_MODE_CBC, + 256, + "AES-256-CBC", + 16, + 0, + 16, + &aes_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +static const mbedtls_cipher_info_t aes_128_cfb128_info = { + MBEDTLS_CIPHER_AES_128_CFB128, + MBEDTLS_MODE_CFB, + 128, + "AES-128-CFB128", + 16, + 0, + 16, + &aes_info +}; + +static const mbedtls_cipher_info_t aes_192_cfb128_info = { + MBEDTLS_CIPHER_AES_192_CFB128, + MBEDTLS_MODE_CFB, + 192, + "AES-192-CFB128", + 16, + 0, + 16, + &aes_info +}; + +static const mbedtls_cipher_info_t aes_256_cfb128_info = { + MBEDTLS_CIPHER_AES_256_CFB128, + MBEDTLS_MODE_CFB, + 256, + "AES-256-CFB128", + 16, + 0, + 16, + &aes_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +static const mbedtls_cipher_info_t aes_128_ctr_info = { + MBEDTLS_CIPHER_AES_128_CTR, + MBEDTLS_MODE_CTR, + 128, + "AES-128-CTR", + 16, + 0, + 16, + &aes_info +}; + +static const mbedtls_cipher_info_t aes_192_ctr_info = { + MBEDTLS_CIPHER_AES_192_CTR, + MBEDTLS_MODE_CTR, + 192, + "AES-192-CTR", + 16, + 0, + 16, + &aes_info +}; + +static const mbedtls_cipher_info_t aes_256_ctr_info = { + MBEDTLS_CIPHER_AES_256_CTR, + MBEDTLS_MODE_CTR, + 256, + "AES-256-CTR", + 16, + 0, + 16, + &aes_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +#if defined(MBEDTLS_GCM_C) +static int gcm_aes_setkey_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_gcm_setkey( (mbedtls_gcm_context *) ctx, MBEDTLS_CIPHER_ID_AES, + key, key_bitlen ); +} + +static const mbedtls_cipher_base_t gcm_aes_info = { + MBEDTLS_CIPHER_ID_AES, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + gcm_aes_setkey_wrap, + gcm_aes_setkey_wrap, + gcm_ctx_alloc, + gcm_ctx_free, +}; + +static const mbedtls_cipher_info_t aes_128_gcm_info = { + MBEDTLS_CIPHER_AES_128_GCM, + MBEDTLS_MODE_GCM, + 128, + "AES-128-GCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &gcm_aes_info +}; + +static const mbedtls_cipher_info_t aes_192_gcm_info = { + MBEDTLS_CIPHER_AES_192_GCM, + MBEDTLS_MODE_GCM, + 192, + "AES-192-GCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &gcm_aes_info +}; + +static const mbedtls_cipher_info_t aes_256_gcm_info = { + MBEDTLS_CIPHER_AES_256_GCM, + MBEDTLS_MODE_GCM, + 256, + "AES-256-GCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &gcm_aes_info +}; +#endif /* MBEDTLS_GCM_C */ + +#if defined(MBEDTLS_CCM_C) +static int ccm_aes_setkey_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_ccm_setkey( (mbedtls_ccm_context *) ctx, MBEDTLS_CIPHER_ID_AES, + key, key_bitlen ); +} + +static const mbedtls_cipher_base_t ccm_aes_info = { + MBEDTLS_CIPHER_ID_AES, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + ccm_aes_setkey_wrap, + ccm_aes_setkey_wrap, + ccm_ctx_alloc, + ccm_ctx_free, +}; + +static const mbedtls_cipher_info_t aes_128_ccm_info = { + MBEDTLS_CIPHER_AES_128_CCM, + MBEDTLS_MODE_CCM, + 128, + "AES-128-CCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &ccm_aes_info +}; + +static const mbedtls_cipher_info_t aes_192_ccm_info = { + MBEDTLS_CIPHER_AES_192_CCM, + MBEDTLS_MODE_CCM, + 192, + "AES-192-CCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &ccm_aes_info +}; + +static const mbedtls_cipher_info_t aes_256_ccm_info = { + MBEDTLS_CIPHER_AES_256_CCM, + MBEDTLS_MODE_CCM, + 256, + "AES-256-CCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &ccm_aes_info +}; +#endif /* MBEDTLS_CCM_C */ + +#endif /* MBEDTLS_AES_C */ + +#if defined(MBEDTLS_CAMELLIA_C) + +static int camellia_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_camellia_crypt_ecb( (mbedtls_camellia_context *) ctx, operation, input, + output ); +} + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static int camellia_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, + size_t length, unsigned char *iv, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_camellia_crypt_cbc( (mbedtls_camellia_context *) ctx, operation, length, iv, + input, output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +static int camellia_crypt_cfb128_wrap( void *ctx, mbedtls_operation_t operation, + size_t length, size_t *iv_off, unsigned char *iv, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_camellia_crypt_cfb128( (mbedtls_camellia_context *) ctx, operation, length, + iv_off, iv, input, output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +static int camellia_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off, + unsigned char *nonce_counter, unsigned char *stream_block, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_camellia_crypt_ctr( (mbedtls_camellia_context *) ctx, length, nc_off, + nonce_counter, stream_block, input, output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +static int camellia_setkey_dec_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_camellia_setkey_dec( (mbedtls_camellia_context *) ctx, key, key_bitlen ); +} + +static int camellia_setkey_enc_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_camellia_setkey_enc( (mbedtls_camellia_context *) ctx, key, key_bitlen ); +} + +static void * camellia_ctx_alloc( void ) +{ + mbedtls_camellia_context *ctx; + ctx = mbedtls_calloc( 1, sizeof( mbedtls_camellia_context ) ); + + if( ctx == NULL ) + return( NULL ); + + mbedtls_camellia_init( ctx ); + + return( ctx ); +} + +static void camellia_ctx_free( void *ctx ) +{ + mbedtls_camellia_free( (mbedtls_camellia_context *) ctx ); + mbedtls_free( ctx ); +} + +static const mbedtls_cipher_base_t camellia_info = { + MBEDTLS_CIPHER_ID_CAMELLIA, + camellia_crypt_ecb_wrap, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + camellia_crypt_cbc_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + camellia_crypt_cfb128_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + camellia_crypt_ctr_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + camellia_setkey_enc_wrap, + camellia_setkey_dec_wrap, + camellia_ctx_alloc, + camellia_ctx_free +}; + +static const mbedtls_cipher_info_t camellia_128_ecb_info = { + MBEDTLS_CIPHER_CAMELLIA_128_ECB, + MBEDTLS_MODE_ECB, + 128, + "CAMELLIA-128-ECB", + 16, + 0, + 16, + &camellia_info +}; + +static const mbedtls_cipher_info_t camellia_192_ecb_info = { + MBEDTLS_CIPHER_CAMELLIA_192_ECB, + MBEDTLS_MODE_ECB, + 192, + "CAMELLIA-192-ECB", + 16, + 0, + 16, + &camellia_info +}; + +static const mbedtls_cipher_info_t camellia_256_ecb_info = { + MBEDTLS_CIPHER_CAMELLIA_256_ECB, + MBEDTLS_MODE_ECB, + 256, + "CAMELLIA-256-ECB", + 16, + 0, + 16, + &camellia_info +}; + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static const mbedtls_cipher_info_t camellia_128_cbc_info = { + MBEDTLS_CIPHER_CAMELLIA_128_CBC, + MBEDTLS_MODE_CBC, + 128, + "CAMELLIA-128-CBC", + 16, + 0, + 16, + &camellia_info +}; + +static const mbedtls_cipher_info_t camellia_192_cbc_info = { + MBEDTLS_CIPHER_CAMELLIA_192_CBC, + MBEDTLS_MODE_CBC, + 192, + "CAMELLIA-192-CBC", + 16, + 0, + 16, + &camellia_info +}; + +static const mbedtls_cipher_info_t camellia_256_cbc_info = { + MBEDTLS_CIPHER_CAMELLIA_256_CBC, + MBEDTLS_MODE_CBC, + 256, + "CAMELLIA-256-CBC", + 16, + 0, + 16, + &camellia_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +static const mbedtls_cipher_info_t camellia_128_cfb128_info = { + MBEDTLS_CIPHER_CAMELLIA_128_CFB128, + MBEDTLS_MODE_CFB, + 128, + "CAMELLIA-128-CFB128", + 16, + 0, + 16, + &camellia_info +}; + +static const mbedtls_cipher_info_t camellia_192_cfb128_info = { + MBEDTLS_CIPHER_CAMELLIA_192_CFB128, + MBEDTLS_MODE_CFB, + 192, + "CAMELLIA-192-CFB128", + 16, + 0, + 16, + &camellia_info +}; + +static const mbedtls_cipher_info_t camellia_256_cfb128_info = { + MBEDTLS_CIPHER_CAMELLIA_256_CFB128, + MBEDTLS_MODE_CFB, + 256, + "CAMELLIA-256-CFB128", + 16, + 0, + 16, + &camellia_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +static const mbedtls_cipher_info_t camellia_128_ctr_info = { + MBEDTLS_CIPHER_CAMELLIA_128_CTR, + MBEDTLS_MODE_CTR, + 128, + "CAMELLIA-128-CTR", + 16, + 0, + 16, + &camellia_info +}; + +static const mbedtls_cipher_info_t camellia_192_ctr_info = { + MBEDTLS_CIPHER_CAMELLIA_192_CTR, + MBEDTLS_MODE_CTR, + 192, + "CAMELLIA-192-CTR", + 16, + 0, + 16, + &camellia_info +}; + +static const mbedtls_cipher_info_t camellia_256_ctr_info = { + MBEDTLS_CIPHER_CAMELLIA_256_CTR, + MBEDTLS_MODE_CTR, + 256, + "CAMELLIA-256-CTR", + 16, + 0, + 16, + &camellia_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +#if defined(MBEDTLS_GCM_C) +static int gcm_camellia_setkey_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_gcm_setkey( (mbedtls_gcm_context *) ctx, MBEDTLS_CIPHER_ID_CAMELLIA, + key, key_bitlen ); +} + +static const mbedtls_cipher_base_t gcm_camellia_info = { + MBEDTLS_CIPHER_ID_CAMELLIA, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + gcm_camellia_setkey_wrap, + gcm_camellia_setkey_wrap, + gcm_ctx_alloc, + gcm_ctx_free, +}; + +static const mbedtls_cipher_info_t camellia_128_gcm_info = { + MBEDTLS_CIPHER_CAMELLIA_128_GCM, + MBEDTLS_MODE_GCM, + 128, + "CAMELLIA-128-GCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &gcm_camellia_info +}; + +static const mbedtls_cipher_info_t camellia_192_gcm_info = { + MBEDTLS_CIPHER_CAMELLIA_192_GCM, + MBEDTLS_MODE_GCM, + 192, + "CAMELLIA-192-GCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &gcm_camellia_info +}; + +static const mbedtls_cipher_info_t camellia_256_gcm_info = { + MBEDTLS_CIPHER_CAMELLIA_256_GCM, + MBEDTLS_MODE_GCM, + 256, + "CAMELLIA-256-GCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &gcm_camellia_info +}; +#endif /* MBEDTLS_GCM_C */ + +#if defined(MBEDTLS_CCM_C) +static int ccm_camellia_setkey_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_ccm_setkey( (mbedtls_ccm_context *) ctx, MBEDTLS_CIPHER_ID_CAMELLIA, + key, key_bitlen ); +} + +static const mbedtls_cipher_base_t ccm_camellia_info = { + MBEDTLS_CIPHER_ID_CAMELLIA, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + ccm_camellia_setkey_wrap, + ccm_camellia_setkey_wrap, + ccm_ctx_alloc, + ccm_ctx_free, +}; + +static const mbedtls_cipher_info_t camellia_128_ccm_info = { + MBEDTLS_CIPHER_CAMELLIA_128_CCM, + MBEDTLS_MODE_CCM, + 128, + "CAMELLIA-128-CCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &ccm_camellia_info +}; + +static const mbedtls_cipher_info_t camellia_192_ccm_info = { + MBEDTLS_CIPHER_CAMELLIA_192_CCM, + MBEDTLS_MODE_CCM, + 192, + "CAMELLIA-192-CCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &ccm_camellia_info +}; + +static const mbedtls_cipher_info_t camellia_256_ccm_info = { + MBEDTLS_CIPHER_CAMELLIA_256_CCM, + MBEDTLS_MODE_CCM, + 256, + "CAMELLIA-256-CCM", + 12, + MBEDTLS_CIPHER_VARIABLE_IV_LEN, + 16, + &ccm_camellia_info +}; +#endif /* MBEDTLS_CCM_C */ + +#endif /* MBEDTLS_CAMELLIA_C */ + +#if defined(MBEDTLS_DES_C) + +static int des_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, + const unsigned char *input, unsigned char *output ) +{ + ((void) operation); + return mbedtls_des_crypt_ecb( (mbedtls_des_context *) ctx, input, output ); +} + +static int des3_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, + const unsigned char *input, unsigned char *output ) +{ + ((void) operation); + return mbedtls_des3_crypt_ecb( (mbedtls_des3_context *) ctx, input, output ); +} + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static int des_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, size_t length, + unsigned char *iv, const unsigned char *input, unsigned char *output ) +{ + return mbedtls_des_crypt_cbc( (mbedtls_des_context *) ctx, operation, length, iv, input, + output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static int des3_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, size_t length, + unsigned char *iv, const unsigned char *input, unsigned char *output ) +{ + return mbedtls_des3_crypt_cbc( (mbedtls_des3_context *) ctx, operation, length, iv, input, + output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +static int des_setkey_dec_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + ((void) key_bitlen); + + return mbedtls_des_setkey_dec( (mbedtls_des_context *) ctx, key ); +} + +static int des_setkey_enc_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + ((void) key_bitlen); + + return mbedtls_des_setkey_enc( (mbedtls_des_context *) ctx, key ); +} + +static int des3_set2key_dec_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + ((void) key_bitlen); + + return mbedtls_des3_set2key_dec( (mbedtls_des3_context *) ctx, key ); +} + +static int des3_set2key_enc_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + ((void) key_bitlen); + + return mbedtls_des3_set2key_enc( (mbedtls_des3_context *) ctx, key ); +} + +static int des3_set3key_dec_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + ((void) key_bitlen); + + return mbedtls_des3_set3key_dec( (mbedtls_des3_context *) ctx, key ); +} + +static int des3_set3key_enc_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + ((void) key_bitlen); + + return mbedtls_des3_set3key_enc( (mbedtls_des3_context *) ctx, key ); +} + +static void * des_ctx_alloc( void ) +{ + mbedtls_des_context *des = mbedtls_calloc( 1, sizeof( mbedtls_des_context ) ); + + if( des == NULL ) + return( NULL ); + + mbedtls_des_init( des ); + + return( des ); +} + +static void des_ctx_free( void *ctx ) +{ + mbedtls_des_free( (mbedtls_des_context *) ctx ); + mbedtls_free( ctx ); +} + +static void * des3_ctx_alloc( void ) +{ + mbedtls_des3_context *des3; + des3 = mbedtls_calloc( 1, sizeof( mbedtls_des3_context ) ); + + if( des3 == NULL ) + return( NULL ); + + mbedtls_des3_init( des3 ); + + return( des3 ); +} + +static void des3_ctx_free( void *ctx ) +{ + mbedtls_des3_free( (mbedtls_des3_context *) ctx ); + mbedtls_free( ctx ); +} + +static const mbedtls_cipher_base_t des_info = { + MBEDTLS_CIPHER_ID_DES, + des_crypt_ecb_wrap, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + des_crypt_cbc_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + des_setkey_enc_wrap, + des_setkey_dec_wrap, + des_ctx_alloc, + des_ctx_free +}; + +static const mbedtls_cipher_info_t des_ecb_info = { + MBEDTLS_CIPHER_DES_ECB, + MBEDTLS_MODE_ECB, + MBEDTLS_KEY_LENGTH_DES, + "DES-ECB", + 8, + 0, + 8, + &des_info +}; + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static const mbedtls_cipher_info_t des_cbc_info = { + MBEDTLS_CIPHER_DES_CBC, + MBEDTLS_MODE_CBC, + MBEDTLS_KEY_LENGTH_DES, + "DES-CBC", + 8, + 0, + 8, + &des_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +static const mbedtls_cipher_base_t des_ede_info = { + MBEDTLS_CIPHER_ID_DES, + des3_crypt_ecb_wrap, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + des3_crypt_cbc_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + des3_set2key_enc_wrap, + des3_set2key_dec_wrap, + des3_ctx_alloc, + des3_ctx_free +}; + +static const mbedtls_cipher_info_t des_ede_ecb_info = { + MBEDTLS_CIPHER_DES_EDE_ECB, + MBEDTLS_MODE_ECB, + MBEDTLS_KEY_LENGTH_DES_EDE, + "DES-EDE-ECB", + 8, + 0, + 8, + &des_ede_info +}; + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static const mbedtls_cipher_info_t des_ede_cbc_info = { + MBEDTLS_CIPHER_DES_EDE_CBC, + MBEDTLS_MODE_CBC, + MBEDTLS_KEY_LENGTH_DES_EDE, + "DES-EDE-CBC", + 8, + 0, + 8, + &des_ede_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +static const mbedtls_cipher_base_t des_ede3_info = { + MBEDTLS_CIPHER_ID_3DES, + des3_crypt_ecb_wrap, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + des3_crypt_cbc_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + des3_set3key_enc_wrap, + des3_set3key_dec_wrap, + des3_ctx_alloc, + des3_ctx_free +}; + +static const mbedtls_cipher_info_t des_ede3_ecb_info = { + MBEDTLS_CIPHER_DES_EDE3_ECB, + MBEDTLS_MODE_ECB, + MBEDTLS_KEY_LENGTH_DES_EDE3, + "DES-EDE3-ECB", + 8, + 0, + 8, + &des_ede3_info +}; +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static const mbedtls_cipher_info_t des_ede3_cbc_info = { + MBEDTLS_CIPHER_DES_EDE3_CBC, + MBEDTLS_MODE_CBC, + MBEDTLS_KEY_LENGTH_DES_EDE3, + "DES-EDE3-CBC", + 8, + 0, + 8, + &des_ede3_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* MBEDTLS_DES_C */ + +#if defined(MBEDTLS_BLOWFISH_C) + +static int blowfish_crypt_ecb_wrap( void *ctx, mbedtls_operation_t operation, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_blowfish_crypt_ecb( (mbedtls_blowfish_context *) ctx, operation, input, + output ); +} + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static int blowfish_crypt_cbc_wrap( void *ctx, mbedtls_operation_t operation, + size_t length, unsigned char *iv, const unsigned char *input, + unsigned char *output ) +{ + return mbedtls_blowfish_crypt_cbc( (mbedtls_blowfish_context *) ctx, operation, length, iv, + input, output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +static int blowfish_crypt_cfb64_wrap( void *ctx, mbedtls_operation_t operation, + size_t length, size_t *iv_off, unsigned char *iv, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_blowfish_crypt_cfb64( (mbedtls_blowfish_context *) ctx, operation, length, + iv_off, iv, input, output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +static int blowfish_crypt_ctr_wrap( void *ctx, size_t length, size_t *nc_off, + unsigned char *nonce_counter, unsigned char *stream_block, + const unsigned char *input, unsigned char *output ) +{ + return mbedtls_blowfish_crypt_ctr( (mbedtls_blowfish_context *) ctx, length, nc_off, + nonce_counter, stream_block, input, output ); +} +#endif /* MBEDTLS_CIPHER_MODE_CTR */ + +static int blowfish_setkey_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + return mbedtls_blowfish_setkey( (mbedtls_blowfish_context *) ctx, key, key_bitlen ); +} + +static void * blowfish_ctx_alloc( void ) +{ + mbedtls_blowfish_context *ctx; + ctx = mbedtls_calloc( 1, sizeof( mbedtls_blowfish_context ) ); + + if( ctx == NULL ) + return( NULL ); + + mbedtls_blowfish_init( ctx ); + + return( ctx ); +} + +static void blowfish_ctx_free( void *ctx ) +{ + mbedtls_blowfish_free( (mbedtls_blowfish_context *) ctx ); + mbedtls_free( ctx ); +} + +static const mbedtls_cipher_base_t blowfish_info = { + MBEDTLS_CIPHER_ID_BLOWFISH, + blowfish_crypt_ecb_wrap, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + blowfish_crypt_cbc_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + blowfish_crypt_cfb64_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + blowfish_crypt_ctr_wrap, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + NULL, +#endif + blowfish_setkey_wrap, + blowfish_setkey_wrap, + blowfish_ctx_alloc, + blowfish_ctx_free +}; + +static const mbedtls_cipher_info_t blowfish_ecb_info = { + MBEDTLS_CIPHER_BLOWFISH_ECB, + MBEDTLS_MODE_ECB, + 128, + "BLOWFISH-ECB", + 8, + MBEDTLS_CIPHER_VARIABLE_KEY_LEN, + 8, + &blowfish_info +}; + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static const mbedtls_cipher_info_t blowfish_cbc_info = { + MBEDTLS_CIPHER_BLOWFISH_CBC, + MBEDTLS_MODE_CBC, + 128, + "BLOWFISH-CBC", + 8, + MBEDTLS_CIPHER_VARIABLE_KEY_LEN, + 8, + &blowfish_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_CIPHER_MODE_CFB) +static const mbedtls_cipher_info_t blowfish_cfb64_info = { + MBEDTLS_CIPHER_BLOWFISH_CFB64, + MBEDTLS_MODE_CFB, + 128, + "BLOWFISH-CFB64", + 8, + MBEDTLS_CIPHER_VARIABLE_KEY_LEN, + 8, + &blowfish_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CFB */ + +#if defined(MBEDTLS_CIPHER_MODE_CTR) +static const mbedtls_cipher_info_t blowfish_ctr_info = { + MBEDTLS_CIPHER_BLOWFISH_CTR, + MBEDTLS_MODE_CTR, + 128, + "BLOWFISH-CTR", + 8, + MBEDTLS_CIPHER_VARIABLE_KEY_LEN, + 8, + &blowfish_info +}; +#endif /* MBEDTLS_CIPHER_MODE_CTR */ +#endif /* MBEDTLS_BLOWFISH_C */ + +#if defined(MBEDTLS_ARC4_C) +static int arc4_crypt_stream_wrap( void *ctx, size_t length, + const unsigned char *input, + unsigned char *output ) +{ + return( mbedtls_arc4_crypt( (mbedtls_arc4_context *) ctx, length, input, output ) ); +} + +static int arc4_setkey_wrap( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + /* we get key_bitlen in bits, arc4 expects it in bytes */ + if( key_bitlen % 8 != 0 ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + mbedtls_arc4_setup( (mbedtls_arc4_context *) ctx, key, key_bitlen / 8 ); + return( 0 ); +} + +static void * arc4_ctx_alloc( void ) +{ + mbedtls_arc4_context *ctx; + ctx = mbedtls_calloc( 1, sizeof( mbedtls_arc4_context ) ); + + if( ctx == NULL ) + return( NULL ); + + mbedtls_arc4_init( ctx ); + + return( ctx ); +} + +static void arc4_ctx_free( void *ctx ) +{ + mbedtls_arc4_free( (mbedtls_arc4_context *) ctx ); + mbedtls_free( ctx ); +} + +static const mbedtls_cipher_base_t arc4_base_info = { + MBEDTLS_CIPHER_ID_ARC4, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + arc4_crypt_stream_wrap, +#endif + arc4_setkey_wrap, + arc4_setkey_wrap, + arc4_ctx_alloc, + arc4_ctx_free +}; + +static const mbedtls_cipher_info_t arc4_128_info = { + MBEDTLS_CIPHER_ARC4_128, + MBEDTLS_MODE_STREAM, + 128, + "ARC4-128", + 0, + 0, + 1, + &arc4_base_info +}; +#endif /* MBEDTLS_ARC4_C */ + +#if defined(MBEDTLS_CIPHER_NULL_CIPHER) +static int null_crypt_stream( void *ctx, size_t length, + const unsigned char *input, + unsigned char *output ) +{ + ((void) ctx); + memmove( output, input, length ); + return( 0 ); +} + +static int null_setkey( void *ctx, const unsigned char *key, + unsigned int key_bitlen ) +{ + ((void) ctx); + ((void) key); + ((void) key_bitlen); + + return( 0 ); +} + +static void * null_ctx_alloc( void ) +{ + return( (void *) 1 ); +} + +static void null_ctx_free( void *ctx ) +{ + ((void) ctx); +} + +static const mbedtls_cipher_base_t null_base_info = { + MBEDTLS_CIPHER_ID_NULL, + NULL, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + NULL, +#endif +#if defined(MBEDTLS_CIPHER_MODE_STREAM) + null_crypt_stream, +#endif + null_setkey, + null_setkey, + null_ctx_alloc, + null_ctx_free +}; + +static const mbedtls_cipher_info_t null_cipher_info = { + MBEDTLS_CIPHER_NULL, + MBEDTLS_MODE_STREAM, + 0, + "NULL", + 0, + 0, + 1, + &null_base_info +}; +#endif /* defined(MBEDTLS_CIPHER_NULL_CIPHER) */ + +const mbedtls_cipher_definition_t mbedtls_cipher_definitions[] = +{ +#if defined(MBEDTLS_AES_C) + { MBEDTLS_CIPHER_AES_128_ECB, &aes_128_ecb_info }, + { MBEDTLS_CIPHER_AES_192_ECB, &aes_192_ecb_info }, + { MBEDTLS_CIPHER_AES_256_ECB, &aes_256_ecb_info }, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_CIPHER_AES_128_CBC, &aes_128_cbc_info }, + { MBEDTLS_CIPHER_AES_192_CBC, &aes_192_cbc_info }, + { MBEDTLS_CIPHER_AES_256_CBC, &aes_256_cbc_info }, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + { MBEDTLS_CIPHER_AES_128_CFB128, &aes_128_cfb128_info }, + { MBEDTLS_CIPHER_AES_192_CFB128, &aes_192_cfb128_info }, + { MBEDTLS_CIPHER_AES_256_CFB128, &aes_256_cfb128_info }, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + { MBEDTLS_CIPHER_AES_128_CTR, &aes_128_ctr_info }, + { MBEDTLS_CIPHER_AES_192_CTR, &aes_192_ctr_info }, + { MBEDTLS_CIPHER_AES_256_CTR, &aes_256_ctr_info }, +#endif +#if defined(MBEDTLS_GCM_C) + { MBEDTLS_CIPHER_AES_128_GCM, &aes_128_gcm_info }, + { MBEDTLS_CIPHER_AES_192_GCM, &aes_192_gcm_info }, + { MBEDTLS_CIPHER_AES_256_GCM, &aes_256_gcm_info }, +#endif +#if defined(MBEDTLS_CCM_C) + { MBEDTLS_CIPHER_AES_128_CCM, &aes_128_ccm_info }, + { MBEDTLS_CIPHER_AES_192_CCM, &aes_192_ccm_info }, + { MBEDTLS_CIPHER_AES_256_CCM, &aes_256_ccm_info }, +#endif +#endif /* MBEDTLS_AES_C */ + +#if defined(MBEDTLS_ARC4_C) + { MBEDTLS_CIPHER_ARC4_128, &arc4_128_info }, +#endif + +#if defined(MBEDTLS_BLOWFISH_C) + { MBEDTLS_CIPHER_BLOWFISH_ECB, &blowfish_ecb_info }, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_CIPHER_BLOWFISH_CBC, &blowfish_cbc_info }, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + { MBEDTLS_CIPHER_BLOWFISH_CFB64, &blowfish_cfb64_info }, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + { MBEDTLS_CIPHER_BLOWFISH_CTR, &blowfish_ctr_info }, +#endif +#endif /* MBEDTLS_BLOWFISH_C */ + +#if defined(MBEDTLS_CAMELLIA_C) + { MBEDTLS_CIPHER_CAMELLIA_128_ECB, &camellia_128_ecb_info }, + { MBEDTLS_CIPHER_CAMELLIA_192_ECB, &camellia_192_ecb_info }, + { MBEDTLS_CIPHER_CAMELLIA_256_ECB, &camellia_256_ecb_info }, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_CIPHER_CAMELLIA_128_CBC, &camellia_128_cbc_info }, + { MBEDTLS_CIPHER_CAMELLIA_192_CBC, &camellia_192_cbc_info }, + { MBEDTLS_CIPHER_CAMELLIA_256_CBC, &camellia_256_cbc_info }, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CFB) + { MBEDTLS_CIPHER_CAMELLIA_128_CFB128, &camellia_128_cfb128_info }, + { MBEDTLS_CIPHER_CAMELLIA_192_CFB128, &camellia_192_cfb128_info }, + { MBEDTLS_CIPHER_CAMELLIA_256_CFB128, &camellia_256_cfb128_info }, +#endif +#if defined(MBEDTLS_CIPHER_MODE_CTR) + { MBEDTLS_CIPHER_CAMELLIA_128_CTR, &camellia_128_ctr_info }, + { MBEDTLS_CIPHER_CAMELLIA_192_CTR, &camellia_192_ctr_info }, + { MBEDTLS_CIPHER_CAMELLIA_256_CTR, &camellia_256_ctr_info }, +#endif +#if defined(MBEDTLS_GCM_C) + { MBEDTLS_CIPHER_CAMELLIA_128_GCM, &camellia_128_gcm_info }, + { MBEDTLS_CIPHER_CAMELLIA_192_GCM, &camellia_192_gcm_info }, + { MBEDTLS_CIPHER_CAMELLIA_256_GCM, &camellia_256_gcm_info }, +#endif +#if defined(MBEDTLS_CCM_C) + { MBEDTLS_CIPHER_CAMELLIA_128_CCM, &camellia_128_ccm_info }, + { MBEDTLS_CIPHER_CAMELLIA_192_CCM, &camellia_192_ccm_info }, + { MBEDTLS_CIPHER_CAMELLIA_256_CCM, &camellia_256_ccm_info }, +#endif +#endif /* MBEDTLS_CAMELLIA_C */ + +#if defined(MBEDTLS_DES_C) + { MBEDTLS_CIPHER_DES_ECB, &des_ecb_info }, + { MBEDTLS_CIPHER_DES_EDE_ECB, &des_ede_ecb_info }, + { MBEDTLS_CIPHER_DES_EDE3_ECB, &des_ede3_ecb_info }, +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_CIPHER_DES_CBC, &des_cbc_info }, + { MBEDTLS_CIPHER_DES_EDE_CBC, &des_ede_cbc_info }, + { MBEDTLS_CIPHER_DES_EDE3_CBC, &des_ede3_cbc_info }, +#endif +#endif /* MBEDTLS_DES_C */ + +#if defined(MBEDTLS_CIPHER_NULL_CIPHER) + { MBEDTLS_CIPHER_NULL, &null_cipher_info }, +#endif /* MBEDTLS_CIPHER_NULL_CIPHER */ + + { MBEDTLS_CIPHER_NONE, NULL } +}; + +#define NUM_CIPHERS sizeof mbedtls_cipher_definitions / sizeof mbedtls_cipher_definitions[0] +int mbedtls_cipher_supported[NUM_CIPHERS]; + +#endif /* MBEDTLS_CIPHER_C */ diff --git a/security/mbedtls/src/cmac.c b/security/mbedtls/src/cmac.c new file mode 100644 index 0000000000..035ad071d4 --- /dev/null +++ b/security/mbedtls/src/cmac.c @@ -0,0 +1,1074 @@ +/** + * \file cmac.c + * + * \brief NIST SP800-38B compliant CMAC implementation for AES and 3DES + * + * Copyright (C) 2006-2016, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +/* + * References: + * + * - NIST SP 800-38B Recommendation for Block Cipher Modes of Operation: The + * CMAC Mode for Authentication + * http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-38b.pdf + * + * - RFC 4493 - The AES-CMAC Algorithm + * https://tools.ietf.org/html/rfc4493 + * + * - RFC 4615 - The Advanced Encryption Standard-Cipher-based Message + * Authentication Code-Pseudo-Random Function-128 (AES-CMAC-PRF-128) + * Algorithm for the Internet Key Exchange Protocol (IKE) + * https://tools.ietf.org/html/rfc4615 + * + * Additional test vectors: ISO/IEC 9797-1 + * + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_CMAC_C) + +#include "mbedtls/cmac.h" + +#include + + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_calloc calloc +#define mbedtls_free free +#if defined(MBEDTLS_SELF_TEST) +#include +#define mbedtls_printf printf +#endif /* MBEDTLS_SELF_TEST */ +#endif /* MBEDTLS_PLATFORM_C */ + +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0; +} + +/* + * Multiplication by u in the Galois field of GF(2^n) + * + * As explained in NIST SP 800-38B, this can be computed: + * + * If MSB(p) = 0, then p = (p << 1) + * If MSB(p) = 1, then p = (p << 1) ^ R_n + * with R_64 = 0x1B and R_128 = 0x87 + * + * Input and output MUST NOT point to the same buffer + * Block size must be 8 bytes or 16 bytes - the block sizes for DES and AES. + */ +static int cmac_multiply_by_u( unsigned char *output, + const unsigned char *input, + size_t blocksize ) +{ + const unsigned char R_128 = 0x87; + const unsigned char R_64 = 0x1B; + unsigned char R_n, mask; + unsigned char overflow = 0x00; + int i; + + if( blocksize == MBEDTLS_AES_BLOCK_SIZE ) + { + R_n = R_128; + } + else if( blocksize == MBEDTLS_DES3_BLOCK_SIZE ) + { + R_n = R_64; + } + else + { + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + } + + for( i = (int)blocksize - 1; i >= 0; i-- ) + { + output[i] = input[i] << 1 | overflow; + overflow = input[i] >> 7; + } + + /* mask = ( input[0] >> 7 ) ? 0xff : 0x00 + * using bit operations to avoid branches */ + + /* MSVC has a warning about unary minus on unsigned, but this is + * well-defined and precisely what we want to do here */ +#if defined(_MSC_VER) +#pragma warning( push ) +#pragma warning( disable : 4146 ) +#endif + mask = - ( input[0] >> 7 ); +#if defined(_MSC_VER) +#pragma warning( pop ) +#endif + + output[ blocksize - 1 ] ^= R_n & mask; + + return( 0 ); +} + +/* + * Generate subkeys + * + * - as specified by RFC 4493, section 2.3 Subkey Generation Algorithm + */ +static int cmac_generate_subkeys( mbedtls_cipher_context_t *ctx, + unsigned char* K1, unsigned char* K2 ) +{ + int ret; + unsigned char L[MBEDTLS_CIPHER_BLKSIZE_MAX]; + size_t olen, block_size; + + mbedtls_zeroize( L, sizeof( L ) ); + + block_size = ctx->cipher_info->block_size; + + /* Calculate Ek(0) */ + if( ( ret = mbedtls_cipher_update( ctx, L, block_size, L, &olen ) ) != 0 ) + goto exit; + + /* + * Generate K1 and K2 + */ + if( ( ret = cmac_multiply_by_u( K1, L , block_size ) ) != 0 ) + goto exit; + + if( ( ret = cmac_multiply_by_u( K2, K1 , block_size ) ) != 0 ) + goto exit; + +exit: + mbedtls_zeroize( L, sizeof( L ) ); + + return( ret ); +} + +static void cmac_xor_block( unsigned char *output, const unsigned char *input1, + const unsigned char *input2, + const size_t block_size ) +{ + size_t index; + + for( index = 0; index < block_size; index++ ) + output[ index ] = input1[ index ] ^ input2[ index ]; +} + +/* + * Create padded last block from (partial) last block. + * + * We can't use the padding option from the cipher layer, as it only works for + * CBC and we use ECB mode, and anyway we need to XOR K1 or K2 in addition. + */ +static void cmac_pad( unsigned char padded_block[MBEDTLS_CIPHER_BLKSIZE_MAX], + size_t padded_block_len, + const unsigned char *last_block, + size_t last_block_len ) +{ + size_t j; + + for( j = 0; j < padded_block_len; j++ ) + { + if( j < last_block_len ) + padded_block[j] = last_block[j]; + else if( j == last_block_len ) + padded_block[j] = 0x80; + else + padded_block[j] = 0x00; + } +} + +int mbedtls_cipher_cmac_starts( mbedtls_cipher_context_t *ctx, + const unsigned char *key, size_t keybits ) +{ + mbedtls_cipher_type_t type; + mbedtls_cmac_context_t *cmac_ctx; + int retval; + + if( ctx == NULL || ctx->cipher_info == NULL || key == NULL ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + if( ( retval = mbedtls_cipher_setkey( ctx, key, (int)keybits, + MBEDTLS_ENCRYPT ) ) != 0 ) + return( retval ); + + type = ctx->cipher_info->type; + + switch( type ) + { + case MBEDTLS_CIPHER_AES_128_ECB: + case MBEDTLS_CIPHER_AES_192_ECB: + case MBEDTLS_CIPHER_AES_256_ECB: + case MBEDTLS_CIPHER_DES_EDE3_ECB: + break; + default: + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + } + + /* Allocated and initialise in the cipher context memory for the CMAC + * context */ + cmac_ctx = mbedtls_calloc( 1, sizeof( mbedtls_cmac_context_t ) ); + if( cmac_ctx == NULL ) + return( MBEDTLS_ERR_CIPHER_ALLOC_FAILED ); + + ctx->cmac_ctx = cmac_ctx; + + mbedtls_zeroize( cmac_ctx->state, sizeof( cmac_ctx->state ) ); + + return 0; +} + +int mbedtls_cipher_cmac_update( mbedtls_cipher_context_t *ctx, + const unsigned char *input, size_t ilen ) +{ + mbedtls_cmac_context_t* cmac_ctx; + unsigned char *state; + int ret = 0; + size_t n, j, olen, block_size; + + if( ctx == NULL || ctx->cipher_info == NULL || input == NULL || + ctx->cmac_ctx == NULL ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + cmac_ctx = ctx->cmac_ctx; + block_size = ctx->cipher_info->block_size; + state = ctx->cmac_ctx->state; + + /* Is there data still to process from the last call, that's greater in + * size than a block? */ + if( cmac_ctx->unprocessed_len > 0 && + ilen > block_size - cmac_ctx->unprocessed_len ) + { + memcpy( &cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len], + input, + block_size - cmac_ctx->unprocessed_len ); + + cmac_xor_block( state, cmac_ctx->unprocessed_block, state, block_size ); + + if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state, + &olen ) ) != 0 ) + { + goto exit; + } + + input += block_size - cmac_ctx->unprocessed_len; + ilen -= block_size - cmac_ctx->unprocessed_len; + cmac_ctx->unprocessed_len = 0; + } + + /* n is the number of blocks including any final partial block */ + n = ( ilen + block_size - 1 ) / block_size; + + /* Iterate across the input data in block sized chunks, excluding any + * final partial or complete block */ + for( j = 1; j < n; j++ ) + { + cmac_xor_block( state, input, state, block_size ); + + if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state, + &olen ) ) != 0 ) + goto exit; + + ilen -= block_size; + input += block_size; + } + + /* If there is data left over that wasn't aligned to a block */ + if( ilen > 0 ) + { + memcpy( &cmac_ctx->unprocessed_block[cmac_ctx->unprocessed_len], + input, + ilen ); + cmac_ctx->unprocessed_len += ilen; + } + +exit: + return( ret ); +} + +int mbedtls_cipher_cmac_finish( mbedtls_cipher_context_t *ctx, + unsigned char *output ) +{ + mbedtls_cmac_context_t* cmac_ctx; + unsigned char *state, *last_block; + unsigned char K1[MBEDTLS_CIPHER_BLKSIZE_MAX]; + unsigned char K2[MBEDTLS_CIPHER_BLKSIZE_MAX]; + unsigned char M_last[MBEDTLS_CIPHER_BLKSIZE_MAX]; + int ret; + size_t olen, block_size; + + if( ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL || + output == NULL ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + cmac_ctx = ctx->cmac_ctx; + block_size = ctx->cipher_info->block_size; + state = cmac_ctx->state; + + mbedtls_zeroize( K1, sizeof( K1 ) ); + mbedtls_zeroize( K2, sizeof( K2 ) ); + cmac_generate_subkeys( ctx, K1, K2 ); + + last_block = cmac_ctx->unprocessed_block; + + /* Calculate last block */ + if( cmac_ctx->unprocessed_len < block_size ) + { + cmac_pad( M_last, block_size, last_block, cmac_ctx->unprocessed_len ); + cmac_xor_block( M_last, M_last, K2, block_size ); + } + else + { + /* Last block is complete block */ + cmac_xor_block( M_last, last_block, K1, block_size ); + } + + + cmac_xor_block( state, M_last, state, block_size ); + if( ( ret = mbedtls_cipher_update( ctx, state, block_size, state, + &olen ) ) != 0 ) + { + goto exit; + } + + memcpy( output, state, block_size ); + +exit: + /* Wipe the generated keys on the stack, and any other transients to avoid + * side channel leakage */ + mbedtls_zeroize( K1, sizeof( K1 ) ); + mbedtls_zeroize( K2, sizeof( K2 ) ); + + cmac_ctx->unprocessed_len = 0; + mbedtls_zeroize( cmac_ctx->unprocessed_block, + sizeof( cmac_ctx->unprocessed_block ) ); + + mbedtls_zeroize( state, MBEDTLS_CIPHER_BLKSIZE_MAX ); + return( ret ); +} + +int mbedtls_cipher_cmac_reset( mbedtls_cipher_context_t *ctx ) +{ + mbedtls_cmac_context_t* cmac_ctx; + + if( ctx == NULL || ctx->cipher_info == NULL || ctx->cmac_ctx == NULL ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + cmac_ctx = ctx->cmac_ctx; + + /* Reset the internal state */ + cmac_ctx->unprocessed_len = 0; + mbedtls_zeroize( cmac_ctx->unprocessed_block, + sizeof( cmac_ctx->unprocessed_block ) ); + mbedtls_zeroize( cmac_ctx->state, + sizeof( cmac_ctx->state ) ); + + return( 0 ); +} + +int mbedtls_cipher_cmac( const mbedtls_cipher_info_t *cipher_info, + const unsigned char *key, size_t keylen, + const unsigned char *input, size_t ilen, + unsigned char *output ) +{ + mbedtls_cipher_context_t ctx; + int ret; + + if( cipher_info == NULL || key == NULL || input == NULL || output == NULL ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + mbedtls_cipher_init( &ctx ); + + if( ( ret = mbedtls_cipher_setup( &ctx, cipher_info ) ) != 0 ) + goto exit; + + ret = mbedtls_cipher_cmac_starts( &ctx, key, keylen ); + if( ret != 0 ) + goto exit; + + ret = mbedtls_cipher_cmac_update( &ctx, input, ilen ); + if( ret != 0 ) + goto exit; + + ret = mbedtls_cipher_cmac_finish( &ctx, output ); + +exit: + mbedtls_cipher_free( &ctx ); + + return( ret ); +} + +#if defined(MBEDTLS_AES_C) +/* + * Implementation of AES-CMAC-PRF-128 defined in RFC 4615 + */ +int mbedtls_aes_cmac_prf_128( const unsigned char *key, size_t key_length, + const unsigned char *input, size_t in_len, + unsigned char *output ) +{ + int ret; + const mbedtls_cipher_info_t *cipher_info; + unsigned char zero_key[MBEDTLS_AES_BLOCK_SIZE]; + unsigned char int_key[MBEDTLS_AES_BLOCK_SIZE]; + + if( key == NULL || input == NULL || output == NULL ) + return( MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA ); + + cipher_info = mbedtls_cipher_info_from_type( MBEDTLS_CIPHER_AES_128_ECB ); + if( cipher_info == NULL ) + { + /* Failing at this point must be due to a build issue */ + ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; + goto exit; + } + + if( key_length == MBEDTLS_AES_BLOCK_SIZE ) + { + /* Use key as is */ + memcpy( int_key, key, MBEDTLS_AES_BLOCK_SIZE ); + } + else + { + memset( zero_key, 0, MBEDTLS_AES_BLOCK_SIZE ); + + ret = mbedtls_cipher_cmac( cipher_info, zero_key, 128, key, + key_length, int_key ); + if( ret != 0 ) + goto exit; + } + + ret = mbedtls_cipher_cmac( cipher_info, int_key, 128, input, in_len, + output ); + +exit: + mbedtls_zeroize( int_key, sizeof( int_key ) ); + + return( ret ); +} +#endif /* MBEDTLS_AES_C */ + +#if defined(MBEDTLS_SELF_TEST) +/* + * CMAC test data for SP800-38B + * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/AES_CMAC.pdf + * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/TDES_CMAC.pdf + * + * AES-CMAC-PRF-128 test data from RFC 4615 + * https://tools.ietf.org/html/rfc4615#page-4 + */ + +#define NB_CMAC_TESTS_PER_KEY 4 +#define NB_PRF_TESTS 3 + +#if defined(MBEDTLS_AES_C) || defined(MBEDTLS_DES_C) +/* All CMAC test inputs are truncated from the same 64 byte buffer. */ +static const unsigned char test_message[] = { + /* PT */ + 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, + 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a, + 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, + 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51, + 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, + 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef, + 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, + 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 +}; +#endif /* MBEDTLS_AES_C || MBEDTLS_DES_C */ + +#if defined(MBEDTLS_AES_C) +/* Truncation point of message for AES CMAC tests */ +static const unsigned int aes_message_lengths[NB_CMAC_TESTS_PER_KEY] = { + /* Mlen */ + 0, + 16, + 20, + 64 +}; + +/* CMAC-AES128 Test Data */ +static const unsigned char aes_128_key[16] = { + 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c +}; +static const unsigned char aes_128_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = { + { + /* K1 */ + 0xfb, 0xee, 0xd6, 0x18, 0x35, 0x71, 0x33, 0x66, + 0x7c, 0x85, 0xe0, 0x8f, 0x72, 0x36, 0xa8, 0xde + }, + { + /* K2 */ + 0xf7, 0xdd, 0xac, 0x30, 0x6a, 0xe2, 0x66, 0xcc, + 0xf9, 0x0b, 0xc1, 0x1e, 0xe4, 0x6d, 0x51, 0x3b + } +}; +static const unsigned char aes_128_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = { + { + /* Example #1 */ + 0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28, + 0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46 + }, + { + /* Example #2 */ + 0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44, + 0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c + }, + { + /* Example #3 */ + 0x7d, 0x85, 0x44, 0x9e, 0xa6, 0xea, 0x19, 0xc8, + 0x23, 0xa7, 0xbf, 0x78, 0x83, 0x7d, 0xfa, 0xde + }, + { + /* Example #4 */ + 0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92, + 0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe + } +}; + +/* CMAC-AES192 Test Data */ +static const unsigned char aes_192_key[24] = { + 0x8e, 0x73, 0xb0, 0xf7, 0xda, 0x0e, 0x64, 0x52, + 0xc8, 0x10, 0xf3, 0x2b, 0x80, 0x90, 0x79, 0xe5, + 0x62, 0xf8, 0xea, 0xd2, 0x52, 0x2c, 0x6b, 0x7b +}; +static const unsigned char aes_192_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = { + { + /* K1 */ + 0x44, 0x8a, 0x5b, 0x1c, 0x93, 0x51, 0x4b, 0x27, + 0x3e, 0xe6, 0x43, 0x9d, 0xd4, 0xda, 0xa2, 0x96 + }, + { + /* K2 */ + 0x89, 0x14, 0xb6, 0x39, 0x26, 0xa2, 0x96, 0x4e, + 0x7d, 0xcc, 0x87, 0x3b, 0xa9, 0xb5, 0x45, 0x2c + } +}; +static const unsigned char aes_192_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = { + { + /* Example #1 */ + 0xd1, 0x7d, 0xdf, 0x46, 0xad, 0xaa, 0xcd, 0xe5, + 0x31, 0xca, 0xc4, 0x83, 0xde, 0x7a, 0x93, 0x67 + }, + { + /* Example #2 */ + 0x9e, 0x99, 0xa7, 0xbf, 0x31, 0xe7, 0x10, 0x90, + 0x06, 0x62, 0xf6, 0x5e, 0x61, 0x7c, 0x51, 0x84 + }, + { + /* Example #3 */ + 0x3d, 0x75, 0xc1, 0x94, 0xed, 0x96, 0x07, 0x04, + 0x44, 0xa9, 0xfa, 0x7e, 0xc7, 0x40, 0xec, 0xf8 + }, + { + /* Example #4 */ + 0xa1, 0xd5, 0xdf, 0x0e, 0xed, 0x79, 0x0f, 0x79, + 0x4d, 0x77, 0x58, 0x96, 0x59, 0xf3, 0x9a, 0x11 + } +}; + +/* CMAC-AES256 Test Data */ +static const unsigned char aes_256_key[32] = { + 0x60, 0x3d, 0xeb, 0x10, 0x15, 0xca, 0x71, 0xbe, + 0x2b, 0x73, 0xae, 0xf0, 0x85, 0x7d, 0x77, 0x81, + 0x1f, 0x35, 0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, + 0x2d, 0x98, 0x10, 0xa3, 0x09, 0x14, 0xdf, 0xf4 +}; +static const unsigned char aes_256_subkeys[2][MBEDTLS_AES_BLOCK_SIZE] = { + { + /* K1 */ + 0xca, 0xd1, 0xed, 0x03, 0x29, 0x9e, 0xed, 0xac, + 0x2e, 0x9a, 0x99, 0x80, 0x86, 0x21, 0x50, 0x2f + }, + { + /* K2 */ + 0x95, 0xa3, 0xda, 0x06, 0x53, 0x3d, 0xdb, 0x58, + 0x5d, 0x35, 0x33, 0x01, 0x0c, 0x42, 0xa0, 0xd9 + } +}; +static const unsigned char aes_256_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_AES_BLOCK_SIZE] = { + { + /* Example #1 */ + 0x02, 0x89, 0x62, 0xf6, 0x1b, 0x7b, 0xf8, 0x9e, + 0xfc, 0x6b, 0x55, 0x1f, 0x46, 0x67, 0xd9, 0x83 + }, + { + /* Example #2 */ + 0x28, 0xa7, 0x02, 0x3f, 0x45, 0x2e, 0x8f, 0x82, + 0xbd, 0x4b, 0xf2, 0x8d, 0x8c, 0x37, 0xc3, 0x5c + }, + { + /* Example #3 */ + 0x15, 0x67, 0x27, 0xdc, 0x08, 0x78, 0x94, 0x4a, + 0x02, 0x3c, 0x1f, 0xe0, 0x3b, 0xad, 0x6d, 0x93 + }, + { + /* Example #4 */ + 0xe1, 0x99, 0x21, 0x90, 0x54, 0x9f, 0x6e, 0xd5, + 0x69, 0x6a, 0x2c, 0x05, 0x6c, 0x31, 0x54, 0x10 + } +}; +#endif /* MBEDTLS_AES_C */ + +#if defined(MBEDTLS_DES_C) +/* Truncation point of message for 3DES CMAC tests */ +static const unsigned int des3_message_lengths[NB_CMAC_TESTS_PER_KEY] = { + 0, + 16, + 20, + 32 +}; + +/* CMAC-TDES (Generation) - 2 Key Test Data */ +static const unsigned char des3_2key_key[24] = { + /* Key1 */ + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + /* Key2 */ + 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xEF, 0x01, + /* Key3 */ + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef +}; +static const unsigned char des3_2key_subkeys[2][8] = { + { + /* K1 */ + 0x0d, 0xd2, 0xcb, 0x7a, 0x3d, 0x88, 0x88, 0xd9 + }, + { + /* K2 */ + 0x1b, 0xa5, 0x96, 0xf4, 0x7b, 0x11, 0x11, 0xb2 + } +}; +static const unsigned char des3_2key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE] = { + { + /* Sample #1 */ + 0x79, 0xce, 0x52, 0xa7, 0xf7, 0x86, 0xa9, 0x60 + }, + { + /* Sample #2 */ + 0xcc, 0x18, 0xa0, 0xb7, 0x9a, 0xf2, 0x41, 0x3b + }, + { + /* Sample #3 */ + 0xc0, 0x6d, 0x37, 0x7e, 0xcd, 0x10, 0x19, 0x69 + }, + { + /* Sample #4 */ + 0x9c, 0xd3, 0x35, 0x80, 0xf9, 0xb6, 0x4d, 0xfb + } +}; + +/* CMAC-TDES (Generation) - 3 Key Test Data */ +static const unsigned char des3_3key_key[24] = { + /* Key1 */ + 0x01, 0x23, 0x45, 0x67, 0x89, 0xaa, 0xcd, 0xef, + /* Key2 */ + 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, + /* Key3 */ + 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23 +}; +static const unsigned char des3_3key_subkeys[2][8] = { + { + /* K1 */ + 0x9d, 0x74, 0xe7, 0x39, 0x33, 0x17, 0x96, 0xc0 + }, + { + /* K2 */ + 0x3a, 0xe9, 0xce, 0x72, 0x66, 0x2f, 0x2d, 0x9b + } +}; +static const unsigned char des3_3key_expected_result[NB_CMAC_TESTS_PER_KEY][MBEDTLS_DES3_BLOCK_SIZE] = { + { + /* Sample #1 */ + 0x7d, 0xb0, 0xd3, 0x7d, 0xf9, 0x36, 0xc5, 0x50 + }, + { + /* Sample #2 */ + 0x30, 0x23, 0x9c, 0xf1, 0xf5, 0x2e, 0x66, 0x09 + }, + { + /* Sample #3 */ + 0x6c, 0x9f, 0x3e, 0xe4, 0x92, 0x3f, 0x6b, 0xe2 + }, + { + /* Sample #4 */ + 0x99, 0x42, 0x9b, 0xd0, 0xbF, 0x79, 0x04, 0xe5 + } +}; + +#endif /* MBEDTLS_DES_C */ + +#if defined(MBEDTLS_AES_C) +/* AES AES-CMAC-PRF-128 Test Data */ +static const unsigned char PRFK[] = { + /* Key */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0xed, 0xcb +}; + +/* Sizes in bytes */ +static const size_t PRFKlen[NB_PRF_TESTS] = { + 18, + 16, + 10 +}; + +/* Message */ +static const unsigned char PRFM[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13 +}; + +static const unsigned char PRFT[NB_PRF_TESTS][16] = { + { + 0x84, 0xa3, 0x48, 0xa4, 0xa4, 0x5d, 0x23, 0x5b, + 0xab, 0xff, 0xfc, 0x0d, 0x2b, 0x4d, 0xa0, 0x9a + }, + { + 0x98, 0x0a, 0xe8, 0x7b, 0x5f, 0x4c, 0x9c, 0x52, + 0x14, 0xf5, 0xb6, 0xa8, 0x45, 0x5e, 0x4c, 0x2d + }, + { + 0x29, 0x0d, 0x9e, 0x11, 0x2e, 0xdb, 0x09, 0xee, + 0x14, 0x1f, 0xcf, 0x64, 0xc0, 0xb7, 0x2f, 0x3d + } +}; +#endif /* MBEDTLS_AES_C */ + +static int cmac_test_subkeys( int verbose, + const char* testname, + const unsigned char* key, + int keybits, + const unsigned char* subkeys, + mbedtls_cipher_type_t cipher_type, + int block_size, + int num_tests ) +{ + int i, ret; + mbedtls_cipher_context_t ctx; + const mbedtls_cipher_info_t *cipher_info; + unsigned char K1[MBEDTLS_CIPHER_BLKSIZE_MAX]; + unsigned char K2[MBEDTLS_CIPHER_BLKSIZE_MAX]; + + cipher_info = mbedtls_cipher_info_from_type( cipher_type ); + if( cipher_info == NULL ) + { + /* Failing at this point must be due to a build issue */ + return( MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE ); + } + + for( i = 0; i < num_tests; i++ ) + { + if( verbose != 0 ) + mbedtls_printf( " %s CMAC subkey #%u: ", testname, i + 1 ); + + mbedtls_cipher_init( &ctx ); + + if( ( ret = mbedtls_cipher_setup( &ctx, cipher_info ) ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "test execution failed\n" ); + + goto cleanup; + } + + if( ( ret = mbedtls_cipher_setkey( &ctx, key, keybits, + MBEDTLS_ENCRYPT ) ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "test execution failed\n" ); + + goto cleanup; + } + + ret = cmac_generate_subkeys( &ctx, K1, K2 ); + if( ret != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + goto cleanup; + } + + if( ( ret = memcmp( K1, subkeys, block_size ) ) != 0 || + ( ret = memcmp( K2, &subkeys[block_size], block_size ) ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + goto cleanup; + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + + mbedtls_cipher_free( &ctx ); + } + + goto exit; + +cleanup: + mbedtls_cipher_free( &ctx ); + +exit: + return( ret ); +} + +static int cmac_test_wth_cipher( int verbose, + const char* testname, + const unsigned char* key, + int keybits, + const unsigned char* messages, + const unsigned int message_lengths[4], + const unsigned char* expected_result, + mbedtls_cipher_type_t cipher_type, + int block_size, + int num_tests ) +{ + const mbedtls_cipher_info_t *cipher_info; + int i, ret; + unsigned char output[MBEDTLS_CIPHER_BLKSIZE_MAX]; + + cipher_info = mbedtls_cipher_info_from_type( cipher_type ); + if( cipher_info == NULL ) + { + /* Failing at this point must be due to a build issue */ + ret = MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE; + goto exit; + } + + for( i = 0; i < num_tests; i++ ) + { + if( verbose != 0 ) + mbedtls_printf( " %s CMAC #%u: ", testname, i + 1 ); + + if( ( ret = mbedtls_cipher_cmac( cipher_info, key, keybits, messages, + message_lengths[i], output ) ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + goto exit; + } + + if( ( ret = memcmp( output, &expected_result[i * block_size], block_size ) ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + goto exit; + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + +exit: + return( ret ); +} + +#if defined(MBEDTLS_AES_C) +static int test_aes128_cmac_prf( int verbose ) +{ + int i; + int ret; + unsigned char output[MBEDTLS_AES_BLOCK_SIZE]; + + for( i = 0; i < NB_PRF_TESTS; i++ ) + { + mbedtls_printf( " AES CMAC 128 PRF #%u: ", i ); + ret = mbedtls_aes_cmac_prf_128( PRFK, PRFKlen[i], PRFM, 20, output ); + if( ret != 0 || + memcmp( output, PRFT[i], MBEDTLS_AES_BLOCK_SIZE ) != 0 ) + { + + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( ret ); + } + else if( verbose != 0 ) + { + mbedtls_printf( "passed\n" ); + } + } + return( ret ); +} +#endif /* MBEDTLS_AES_C */ + +int mbedtls_cmac_self_test( int verbose ) +{ + int ret; + +#if defined(MBEDTLS_AES_C) + /* AES-128 */ + if( ( ret = cmac_test_subkeys( verbose, + "AES 128", + aes_128_key, + 128, + (const unsigned char*)aes_128_subkeys, + MBEDTLS_CIPHER_AES_128_ECB, + MBEDTLS_AES_BLOCK_SIZE, + NB_CMAC_TESTS_PER_KEY ) ) != 0 ) + { + return( ret ); + } + + if( ( ret = cmac_test_wth_cipher( verbose, + "AES 128", + aes_128_key, + 128, + test_message, + aes_message_lengths, + (const unsigned char*)aes_128_expected_result, + MBEDTLS_CIPHER_AES_128_ECB, + MBEDTLS_AES_BLOCK_SIZE, + NB_CMAC_TESTS_PER_KEY ) ) != 0 ) + { + return( ret ); + } + + /* AES-192 */ + if( ( ret = cmac_test_subkeys( verbose, + "AES 192", + aes_192_key, + 192, + (const unsigned char*)aes_192_subkeys, + MBEDTLS_CIPHER_AES_192_ECB, + MBEDTLS_AES_BLOCK_SIZE, + NB_CMAC_TESTS_PER_KEY ) ) != 0 ) + { + return( ret ); + } + + if( ( ret = cmac_test_wth_cipher( verbose, + "AES 192", + aes_192_key, + 192, + test_message, + aes_message_lengths, + (const unsigned char*)aes_192_expected_result, + MBEDTLS_CIPHER_AES_192_ECB, + MBEDTLS_AES_BLOCK_SIZE, + NB_CMAC_TESTS_PER_KEY ) ) != 0 ) + { + return( ret ); + } + + /* AES-256 */ + if( ( ret = cmac_test_subkeys( verbose, + "AES 256", + aes_256_key, + 256, + (const unsigned char*)aes_256_subkeys, + MBEDTLS_CIPHER_AES_256_ECB, + MBEDTLS_AES_BLOCK_SIZE, + NB_CMAC_TESTS_PER_KEY ) ) != 0 ) + { + return( ret ); + } + + if( ( ret = cmac_test_wth_cipher ( verbose, + "AES 256", + aes_256_key, + 256, + test_message, + aes_message_lengths, + (const unsigned char*)aes_256_expected_result, + MBEDTLS_CIPHER_AES_256_ECB, + MBEDTLS_AES_BLOCK_SIZE, + NB_CMAC_TESTS_PER_KEY ) ) != 0 ) + { + return( ret ); + } +#endif /* MBEDTLS_AES_C */ + +#if defined(MBEDTLS_DES_C) + /* 3DES 2 key */ + if( ( ret = cmac_test_subkeys( verbose, + "3DES 2 key", + des3_2key_key, + 192, + (const unsigned char*)des3_2key_subkeys, + MBEDTLS_CIPHER_DES_EDE3_ECB, + MBEDTLS_DES3_BLOCK_SIZE, + NB_CMAC_TESTS_PER_KEY ) ) != 0 ) + { + return( ret ); + } + + if( ( ret = cmac_test_wth_cipher( verbose, + "3DES 2 key", + des3_2key_key, + 192, + test_message, + des3_message_lengths, + (const unsigned char*)des3_2key_expected_result, + MBEDTLS_CIPHER_DES_EDE3_ECB, + MBEDTLS_DES3_BLOCK_SIZE, + NB_CMAC_TESTS_PER_KEY ) ) != 0 ) + { + return( ret ); + } + + /* 3DES 3 key */ + if( ( ret = cmac_test_subkeys( verbose, + "3DES 3 key", + des3_3key_key, + 192, + (const unsigned char*)des3_3key_subkeys, + MBEDTLS_CIPHER_DES_EDE3_ECB, + MBEDTLS_DES3_BLOCK_SIZE, + NB_CMAC_TESTS_PER_KEY ) ) != 0 ) + { + return( ret ); + } + + if( ( ret = cmac_test_wth_cipher( verbose, + "3DES 3 key", + des3_3key_key, + 192, + test_message, + des3_message_lengths, + (const unsigned char*)des3_3key_expected_result, + MBEDTLS_CIPHER_DES_EDE3_ECB, + MBEDTLS_DES3_BLOCK_SIZE, + NB_CMAC_TESTS_PER_KEY ) ) != 0 ) + { + return( ret ); + } +#endif /* MBEDTLS_DES_C */ + +#if defined(MBEDTLS_AES_C) + if( ( ret = test_aes128_cmac_prf( verbose ) ) != 0 ) + return( ret ); +#endif /* MBEDTLS_AES_C */ + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + + return( 0 ); +} + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_CMAC_C */ diff --git a/security/mbedtls/src/ctr_drbg.c b/security/mbedtls/src/ctr_drbg.c new file mode 100644 index 0000000000..55612c7fc9 --- /dev/null +++ b/security/mbedtls/src/ctr_drbg.c @@ -0,0 +1,594 @@ +/* + * CTR_DRBG implementation based on AES-256 (NIST SP 800-90) + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +/* + * The NIST SP 800-90 DRBGs are described in the following publucation. + * + * http://csrc.nist.gov/publications/nistpubs/800-90/SP800-90revised_March2007.pdf + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_CTR_DRBG_C) + +#include "mbedtls/ctr_drbg.h" + +#include + +#if defined(MBEDTLS_FS_IO) +#include +#endif + +#if defined(MBEDTLS_SELF_TEST) +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_printf printf +#endif /* MBEDTLS_PLATFORM_C */ +#endif /* MBEDTLS_SELF_TEST */ + +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +/* + * CTR_DRBG context initialization + */ +void mbedtls_ctr_drbg_init( mbedtls_ctr_drbg_context *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_ctr_drbg_context ) ); + +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_init( &ctx->mutex ); +#endif +} + +/* + * Non-public function wrapped by mbedtls_ctr_drbg_seed(). Necessary to allow + * NIST tests to succeed (which require known length fixed entropy) + */ +int mbedtls_ctr_drbg_seed_entropy_len( + mbedtls_ctr_drbg_context *ctx, + int (*f_entropy)(void *, unsigned char *, size_t), + void *p_entropy, + const unsigned char *custom, + size_t len, + size_t entropy_len ) +{ + int ret; + unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE]; + + memset( key, 0, MBEDTLS_CTR_DRBG_KEYSIZE ); + + mbedtls_aes_init( &ctx->aes_ctx ); + + ctx->f_entropy = f_entropy; + ctx->p_entropy = p_entropy; + + ctx->entropy_len = entropy_len; + ctx->reseed_interval = MBEDTLS_CTR_DRBG_RESEED_INTERVAL; + + /* + * Initialize with an empty key + */ + mbedtls_aes_setkey_enc( &ctx->aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS ); + + if( ( ret = mbedtls_ctr_drbg_reseed( ctx, custom, len ) ) != 0 ) + return( ret ); + + return( 0 ); +} + +int mbedtls_ctr_drbg_seed( mbedtls_ctr_drbg_context *ctx, + int (*f_entropy)(void *, unsigned char *, size_t), + void *p_entropy, + const unsigned char *custom, + size_t len ) +{ + return( mbedtls_ctr_drbg_seed_entropy_len( ctx, f_entropy, p_entropy, custom, len, + MBEDTLS_CTR_DRBG_ENTROPY_LEN ) ); +} + +void mbedtls_ctr_drbg_free( mbedtls_ctr_drbg_context *ctx ) +{ + if( ctx == NULL ) + return; + +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_free( &ctx->mutex ); +#endif + mbedtls_aes_free( &ctx->aes_ctx ); + mbedtls_zeroize( ctx, sizeof( mbedtls_ctr_drbg_context ) ); +} + +void mbedtls_ctr_drbg_set_prediction_resistance( mbedtls_ctr_drbg_context *ctx, int resistance ) +{ + ctx->prediction_resistance = resistance; +} + +void mbedtls_ctr_drbg_set_entropy_len( mbedtls_ctr_drbg_context *ctx, size_t len ) +{ + ctx->entropy_len = len; +} + +void mbedtls_ctr_drbg_set_reseed_interval( mbedtls_ctr_drbg_context *ctx, int interval ) +{ + ctx->reseed_interval = interval; +} + +static int block_cipher_df( unsigned char *output, + const unsigned char *data, size_t data_len ) +{ + unsigned char buf[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + MBEDTLS_CTR_DRBG_BLOCKSIZE + 16]; + unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN]; + unsigned char key[MBEDTLS_CTR_DRBG_KEYSIZE]; + unsigned char chain[MBEDTLS_CTR_DRBG_BLOCKSIZE]; + unsigned char *p, *iv; + mbedtls_aes_context aes_ctx; + + int i, j; + size_t buf_len, use_len; + + if( data_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ) + return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG ); + + memset( buf, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + MBEDTLS_CTR_DRBG_BLOCKSIZE + 16 ); + mbedtls_aes_init( &aes_ctx ); + + /* + * Construct IV (16 bytes) and S in buffer + * IV = Counter (in 32-bits) padded to 16 with zeroes + * S = Length input string (in 32-bits) || Length of output (in 32-bits) || + * data || 0x80 + * (Total is padded to a multiple of 16-bytes with zeroes) + */ + p = buf + MBEDTLS_CTR_DRBG_BLOCKSIZE; + *p++ = ( data_len >> 24 ) & 0xff; + *p++ = ( data_len >> 16 ) & 0xff; + *p++ = ( data_len >> 8 ) & 0xff; + *p++ = ( data_len ) & 0xff; + p += 3; + *p++ = MBEDTLS_CTR_DRBG_SEEDLEN; + memcpy( p, data, data_len ); + p[data_len] = 0x80; + + buf_len = MBEDTLS_CTR_DRBG_BLOCKSIZE + 8 + data_len + 1; + + for( i = 0; i < MBEDTLS_CTR_DRBG_KEYSIZE; i++ ) + key[i] = i; + + mbedtls_aes_setkey_enc( &aes_ctx, key, MBEDTLS_CTR_DRBG_KEYBITS ); + + /* + * Reduce data to MBEDTLS_CTR_DRBG_SEEDLEN bytes of data + */ + for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE ) + { + p = buf; + memset( chain, 0, MBEDTLS_CTR_DRBG_BLOCKSIZE ); + use_len = buf_len; + + while( use_len > 0 ) + { + for( i = 0; i < MBEDTLS_CTR_DRBG_BLOCKSIZE; i++ ) + chain[i] ^= p[i]; + p += MBEDTLS_CTR_DRBG_BLOCKSIZE; + use_len -= ( use_len >= MBEDTLS_CTR_DRBG_BLOCKSIZE ) ? + MBEDTLS_CTR_DRBG_BLOCKSIZE : use_len; + + mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT, chain, chain ); + } + + memcpy( tmp + j, chain, MBEDTLS_CTR_DRBG_BLOCKSIZE ); + + /* + * Update IV + */ + buf[3]++; + } + + /* + * Do final encryption with reduced data + */ + mbedtls_aes_setkey_enc( &aes_ctx, tmp, MBEDTLS_CTR_DRBG_KEYBITS ); + iv = tmp + MBEDTLS_CTR_DRBG_KEYSIZE; + p = output; + + for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE ) + { + mbedtls_aes_crypt_ecb( &aes_ctx, MBEDTLS_AES_ENCRYPT, iv, iv ); + memcpy( p, iv, MBEDTLS_CTR_DRBG_BLOCKSIZE ); + p += MBEDTLS_CTR_DRBG_BLOCKSIZE; + } + + mbedtls_aes_free( &aes_ctx ); + + return( 0 ); +} + +static int ctr_drbg_update_internal( mbedtls_ctr_drbg_context *ctx, + const unsigned char data[MBEDTLS_CTR_DRBG_SEEDLEN] ) +{ + unsigned char tmp[MBEDTLS_CTR_DRBG_SEEDLEN]; + unsigned char *p = tmp; + int i, j; + + memset( tmp, 0, MBEDTLS_CTR_DRBG_SEEDLEN ); + + for( j = 0; j < MBEDTLS_CTR_DRBG_SEEDLEN; j += MBEDTLS_CTR_DRBG_BLOCKSIZE ) + { + /* + * Increase counter + */ + for( i = MBEDTLS_CTR_DRBG_BLOCKSIZE; i > 0; i-- ) + if( ++ctx->counter[i - 1] != 0 ) + break; + + /* + * Crypt counter block + */ + mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, ctx->counter, p ); + + p += MBEDTLS_CTR_DRBG_BLOCKSIZE; + } + + for( i = 0; i < MBEDTLS_CTR_DRBG_SEEDLEN; i++ ) + tmp[i] ^= data[i]; + + /* + * Update key and counter + */ + mbedtls_aes_setkey_enc( &ctx->aes_ctx, tmp, MBEDTLS_CTR_DRBG_KEYBITS ); + memcpy( ctx->counter, tmp + MBEDTLS_CTR_DRBG_KEYSIZE, MBEDTLS_CTR_DRBG_BLOCKSIZE ); + + return( 0 ); +} + +void mbedtls_ctr_drbg_update( mbedtls_ctr_drbg_context *ctx, + const unsigned char *additional, size_t add_len ) +{ + unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN]; + + if( add_len > 0 ) + { + /* MAX_INPUT would be more logical here, but we have to match + * block_cipher_df()'s limits since we can't propagate errors */ + if( add_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ) + add_len = MBEDTLS_CTR_DRBG_MAX_SEED_INPUT; + + block_cipher_df( add_input, additional, add_len ); + ctr_drbg_update_internal( ctx, add_input ); + } +} + +int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx, + const unsigned char *additional, size_t len ) +{ + unsigned char seed[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT]; + size_t seedlen = 0; + + if( ctx->entropy_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT || + len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len ) + return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG ); + + memset( seed, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ); + + /* + * Gather entropy_len bytes of entropy to seed state + */ + if( 0 != ctx->f_entropy( ctx->p_entropy, seed, + ctx->entropy_len ) ) + { + return( MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED ); + } + + seedlen += ctx->entropy_len; + + /* + * Add additional data + */ + if( additional && len ) + { + memcpy( seed + seedlen, additional, len ); + seedlen += len; + } + + /* + * Reduce to 384 bits + */ + block_cipher_df( seed, seed, seedlen ); + + /* + * Update state + */ + ctr_drbg_update_internal( ctx, seed ); + ctx->reseed_counter = 1; + + return( 0 ); +} + +int mbedtls_ctr_drbg_random_with_add( void *p_rng, + unsigned char *output, size_t output_len, + const unsigned char *additional, size_t add_len ) +{ + int ret = 0; + mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng; + unsigned char add_input[MBEDTLS_CTR_DRBG_SEEDLEN]; + unsigned char *p = output; + unsigned char tmp[MBEDTLS_CTR_DRBG_BLOCKSIZE]; + int i; + size_t use_len; + + if( output_len > MBEDTLS_CTR_DRBG_MAX_REQUEST ) + return( MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG ); + + if( add_len > MBEDTLS_CTR_DRBG_MAX_INPUT ) + return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG ); + + memset( add_input, 0, MBEDTLS_CTR_DRBG_SEEDLEN ); + + if( ctx->reseed_counter > ctx->reseed_interval || + ctx->prediction_resistance ) + { + if( ( ret = mbedtls_ctr_drbg_reseed( ctx, additional, add_len ) ) != 0 ) + return( ret ); + + add_len = 0; + } + + if( add_len > 0 ) + { + block_cipher_df( add_input, additional, add_len ); + ctr_drbg_update_internal( ctx, add_input ); + } + + while( output_len > 0 ) + { + /* + * Increase counter + */ + for( i = MBEDTLS_CTR_DRBG_BLOCKSIZE; i > 0; i-- ) + if( ++ctx->counter[i - 1] != 0 ) + break; + + /* + * Crypt counter block + */ + mbedtls_aes_crypt_ecb( &ctx->aes_ctx, MBEDTLS_AES_ENCRYPT, ctx->counter, tmp ); + + use_len = ( output_len > MBEDTLS_CTR_DRBG_BLOCKSIZE ) ? MBEDTLS_CTR_DRBG_BLOCKSIZE : + output_len; + /* + * Copy random block to destination + */ + memcpy( p, tmp, use_len ); + p += use_len; + output_len -= use_len; + } + + ctr_drbg_update_internal( ctx, add_input ); + + ctx->reseed_counter++; + + return( 0 ); +} + +int mbedtls_ctr_drbg_random( void *p_rng, unsigned char *output, size_t output_len ) +{ + int ret; + mbedtls_ctr_drbg_context *ctx = (mbedtls_ctr_drbg_context *) p_rng; + +#if defined(MBEDTLS_THREADING_C) + if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) + return( ret ); +#endif + + ret = mbedtls_ctr_drbg_random_with_add( ctx, output, output_len, NULL, 0 ); + +#if defined(MBEDTLS_THREADING_C) + if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) + return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); +#endif + + return( ret ); +} + +#if defined(MBEDTLS_FS_IO) +int mbedtls_ctr_drbg_write_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path ) +{ + int ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR; + FILE *f; + unsigned char buf[ MBEDTLS_CTR_DRBG_MAX_INPUT ]; + + if( ( f = fopen( path, "wb" ) ) == NULL ) + return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR ); + + if( ( ret = mbedtls_ctr_drbg_random( ctx, buf, MBEDTLS_CTR_DRBG_MAX_INPUT ) ) != 0 ) + goto exit; + + if( fwrite( buf, 1, MBEDTLS_CTR_DRBG_MAX_INPUT, f ) != MBEDTLS_CTR_DRBG_MAX_INPUT ) + { + ret = MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR; + goto exit; + } + + ret = 0; + +exit: + fclose( f ); + return( ret ); +} + +int mbedtls_ctr_drbg_update_seed_file( mbedtls_ctr_drbg_context *ctx, const char *path ) +{ + FILE *f; + size_t n; + unsigned char buf[ MBEDTLS_CTR_DRBG_MAX_INPUT ]; + + if( ( f = fopen( path, "rb" ) ) == NULL ) + return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR ); + + fseek( f, 0, SEEK_END ); + n = (size_t) ftell( f ); + fseek( f, 0, SEEK_SET ); + + if( n > MBEDTLS_CTR_DRBG_MAX_INPUT ) + { + fclose( f ); + return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG ); + } + + if( fread( buf, 1, n, f ) != n ) + { + fclose( f ); + return( MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR ); + } + + fclose( f ); + + mbedtls_ctr_drbg_update( ctx, buf, n ); + + return( mbedtls_ctr_drbg_write_seed_file( ctx, path ) ); +} +#endif /* MBEDTLS_FS_IO */ + +#if defined(MBEDTLS_SELF_TEST) + +static const unsigned char entropy_source_pr[96] = + { 0xc1, 0x80, 0x81, 0xa6, 0x5d, 0x44, 0x02, 0x16, + 0x19, 0xb3, 0xf1, 0x80, 0xb1, 0xc9, 0x20, 0x02, + 0x6a, 0x54, 0x6f, 0x0c, 0x70, 0x81, 0x49, 0x8b, + 0x6e, 0xa6, 0x62, 0x52, 0x6d, 0x51, 0xb1, 0xcb, + 0x58, 0x3b, 0xfa, 0xd5, 0x37, 0x5f, 0xfb, 0xc9, + 0xff, 0x46, 0xd2, 0x19, 0xc7, 0x22, 0x3e, 0x95, + 0x45, 0x9d, 0x82, 0xe1, 0xe7, 0x22, 0x9f, 0x63, + 0x31, 0x69, 0xd2, 0x6b, 0x57, 0x47, 0x4f, 0xa3, + 0x37, 0xc9, 0x98, 0x1c, 0x0b, 0xfb, 0x91, 0x31, + 0x4d, 0x55, 0xb9, 0xe9, 0x1c, 0x5a, 0x5e, 0xe4, + 0x93, 0x92, 0xcf, 0xc5, 0x23, 0x12, 0xd5, 0x56, + 0x2c, 0x4a, 0x6e, 0xff, 0xdc, 0x10, 0xd0, 0x68 }; + +static const unsigned char entropy_source_nopr[64] = + { 0x5a, 0x19, 0x4d, 0x5e, 0x2b, 0x31, 0x58, 0x14, + 0x54, 0xde, 0xf6, 0x75, 0xfb, 0x79, 0x58, 0xfe, + 0xc7, 0xdb, 0x87, 0x3e, 0x56, 0x89, 0xfc, 0x9d, + 0x03, 0x21, 0x7c, 0x68, 0xd8, 0x03, 0x38, 0x20, + 0xf9, 0xe6, 0x5e, 0x04, 0xd8, 0x56, 0xf3, 0xa9, + 0xc4, 0x4a, 0x4c, 0xbd, 0xc1, 0xd0, 0x08, 0x46, + 0xf5, 0x98, 0x3d, 0x77, 0x1c, 0x1b, 0x13, 0x7e, + 0x4e, 0x0f, 0x9d, 0x8e, 0xf4, 0x09, 0xf9, 0x2e }; + +static const unsigned char nonce_pers_pr[16] = + { 0xd2, 0x54, 0xfc, 0xff, 0x02, 0x1e, 0x69, 0xd2, + 0x29, 0xc9, 0xcf, 0xad, 0x85, 0xfa, 0x48, 0x6c }; + +static const unsigned char nonce_pers_nopr[16] = + { 0x1b, 0x54, 0xb8, 0xff, 0x06, 0x42, 0xbf, 0xf5, + 0x21, 0xf1, 0x5c, 0x1c, 0x0b, 0x66, 0x5f, 0x3f }; + +static const unsigned char result_pr[16] = + { 0x34, 0x01, 0x16, 0x56, 0xb4, 0x29, 0x00, 0x8f, + 0x35, 0x63, 0xec, 0xb5, 0xf2, 0x59, 0x07, 0x23 }; + +static const unsigned char result_nopr[16] = + { 0xa0, 0x54, 0x30, 0x3d, 0x8a, 0x7e, 0xa9, 0x88, + 0x9d, 0x90, 0x3e, 0x07, 0x7c, 0x6f, 0x21, 0x8f }; + +static size_t test_offset; +static int ctr_drbg_self_test_entropy( void *data, unsigned char *buf, + size_t len ) +{ + const unsigned char *p = data; + memcpy( buf, p + test_offset, len ); + test_offset += len; + return( 0 ); +} + +#define CHK( c ) if( (c) != 0 ) \ + { \ + if( verbose != 0 ) \ + mbedtls_printf( "failed\n" ); \ + return( 1 ); \ + } + +/* + * Checkup routine + */ +int mbedtls_ctr_drbg_self_test( int verbose ) +{ + mbedtls_ctr_drbg_context ctx; + unsigned char buf[16]; + + mbedtls_ctr_drbg_init( &ctx ); + + /* + * Based on a NIST CTR_DRBG test vector (PR = True) + */ + if( verbose != 0 ) + mbedtls_printf( " CTR_DRBG (PR = TRUE) : " ); + + test_offset = 0; + CHK( mbedtls_ctr_drbg_seed_entropy_len( &ctx, ctr_drbg_self_test_entropy, + (void *) entropy_source_pr, nonce_pers_pr, 16, 32 ) ); + mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON ); + CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) ); + CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) ); + CHK( memcmp( buf, result_pr, MBEDTLS_CTR_DRBG_BLOCKSIZE ) ); + + mbedtls_ctr_drbg_free( &ctx ); + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + + /* + * Based on a NIST CTR_DRBG test vector (PR = FALSE) + */ + if( verbose != 0 ) + mbedtls_printf( " CTR_DRBG (PR = FALSE): " ); + + mbedtls_ctr_drbg_init( &ctx ); + + test_offset = 0; + CHK( mbedtls_ctr_drbg_seed_entropy_len( &ctx, ctr_drbg_self_test_entropy, + (void *) entropy_source_nopr, nonce_pers_nopr, 16, 32 ) ); + CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) ); + CHK( mbedtls_ctr_drbg_reseed( &ctx, NULL, 0 ) ); + CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) ); + CHK( memcmp( buf, result_nopr, 16 ) ); + + mbedtls_ctr_drbg_free( &ctx ); + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + + return( 0 ); +} +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_CTR_DRBG_C */ diff --git a/security/mbedtls/src/debug.c b/security/mbedtls/src/debug.c new file mode 100644 index 0000000000..5fe72588a8 --- /dev/null +++ b/security/mbedtls/src/debug.c @@ -0,0 +1,396 @@ +/* + * Debugging routines + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_calloc calloc +#define mbedtls_free free +#define mbedtls_time_t time_t +#define mbedtls_snprintf snprintf +#endif + +#include "mbedtls/debug.h" + +#include +#include +#include + +#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ + !defined(inline) && !defined(__cplusplus) +#define inline __inline +#endif + +#define DEBUG_BUF_SIZE 512 + +static int debug_threshold = 0; + +void mbedtls_debug_set_threshold( int threshold ) +{ + debug_threshold = threshold; +} + +#if defined(MBEDTLS_DEBUG_C) + +/* + * All calls to f_dbg must be made via this function + */ +static inline void debug_send_line( const mbedtls_ssl_context *ssl, int level, + const char *file, int line, + const char *str ) +{ + /* + * If in a threaded environment, we need a thread identifier. + * Since there is no portable way to get one, use the address of the ssl + * context instead, as it shouldn't be shared between threads. + */ +#if defined(MBEDTLS_THREADING_C) + char idstr[20 + DEBUG_BUF_SIZE]; /* 0x + 16 nibbles + ': ' */ + mbedtls_snprintf( idstr, sizeof( idstr ), "%p: %s", (void*)ssl, str ); + ssl->conf->f_dbg( ssl->conf->p_dbg, level, file, line, idstr ); +#else + ssl->conf->f_dbg( ssl->conf->p_dbg, level, file, line, str ); +#endif +} + +void mbedtls_debug_print_msg( const mbedtls_ssl_context *ssl, int level, + const char *file, int line, + const char *format, ... ) +{ + va_list argp; + char str[DEBUG_BUF_SIZE]; + int ret; + + if( NULL == ssl || NULL == ssl->conf || NULL == ssl->conf->f_dbg || level > debug_threshold ) + return; + + va_start( argp, format ); +#if defined(_WIN32) +#if defined(_TRUNCATE) + ret = _vsnprintf_s( str, DEBUG_BUF_SIZE, _TRUNCATE, format, argp ); +#else + ret = _vsnprintf( str, DEBUG_BUF_SIZE, format, argp ); + if( ret < 0 || (size_t) ret == DEBUG_BUF_SIZE ) + { + str[DEBUG_BUF_SIZE-1] = '\0'; + ret = -1; + } +#endif +#else + ret = vsnprintf( str, DEBUG_BUF_SIZE, format, argp ); +#endif + va_end( argp ); + + if( ret >= 0 && ret < DEBUG_BUF_SIZE - 1 ) + { + str[ret] = '\n'; + str[ret + 1] = '\0'; + } + + debug_send_line( ssl, level, file, line, str ); +} + +void mbedtls_debug_print_ret( const mbedtls_ssl_context *ssl, int level, + const char *file, int line, + const char *text, int ret ) +{ + char str[DEBUG_BUF_SIZE]; + + if( ssl->conf == NULL || ssl->conf->f_dbg == NULL || level > debug_threshold ) + return; + + /* + * With non-blocking I/O and examples that just retry immediately, + * the logs would be quickly flooded with WANT_READ, so ignore that. + * Don't ignore WANT_WRITE however, since is is usually rare. + */ + if( ret == MBEDTLS_ERR_SSL_WANT_READ ) + return; + + mbedtls_snprintf( str, sizeof( str ), "%s() returned %d (-0x%04x)\n", + text, ret, -ret ); + + debug_send_line( ssl, level, file, line, str ); +} + +void mbedtls_debug_print_buf( const mbedtls_ssl_context *ssl, int level, + const char *file, int line, const char *text, + const unsigned char *buf, size_t len ) +{ + char str[DEBUG_BUF_SIZE]; + char txt[17]; + size_t i, idx = 0; + + if( ssl->conf == NULL || ssl->conf->f_dbg == NULL || level > debug_threshold ) + return; + + mbedtls_snprintf( str + idx, sizeof( str ) - idx, "dumping '%s' (%u bytes)\n", + text, (unsigned int) len ); + + debug_send_line( ssl, level, file, line, str ); + + idx = 0; + memset( txt, 0, sizeof( txt ) ); + for( i = 0; i < len; i++ ) + { + if( i >= 4096 ) + break; + + if( i % 16 == 0 ) + { + if( i > 0 ) + { + mbedtls_snprintf( str + idx, sizeof( str ) - idx, " %s\n", txt ); + debug_send_line( ssl, level, file, line, str ); + + idx = 0; + memset( txt, 0, sizeof( txt ) ); + } + + idx += mbedtls_snprintf( str + idx, sizeof( str ) - idx, "%04x: ", + (unsigned int) i ); + + } + + idx += mbedtls_snprintf( str + idx, sizeof( str ) - idx, " %02x", + (unsigned int) buf[i] ); + txt[i % 16] = ( buf[i] > 31 && buf[i] < 127 ) ? buf[i] : '.' ; + } + + if( len > 0 ) + { + for( /* i = i */; i % 16 != 0; i++ ) + idx += mbedtls_snprintf( str + idx, sizeof( str ) - idx, " " ); + + mbedtls_snprintf( str + idx, sizeof( str ) - idx, " %s\n", txt ); + debug_send_line( ssl, level, file, line, str ); + } +} + +#if defined(MBEDTLS_ECP_C) +void mbedtls_debug_print_ecp( const mbedtls_ssl_context *ssl, int level, + const char *file, int line, + const char *text, const mbedtls_ecp_point *X ) +{ + char str[DEBUG_BUF_SIZE]; + + if( ssl->conf == NULL || ssl->conf->f_dbg == NULL || level > debug_threshold ) + return; + + mbedtls_snprintf( str, sizeof( str ), "%s(X)", text ); + mbedtls_debug_print_mpi( ssl, level, file, line, str, &X->X ); + + mbedtls_snprintf( str, sizeof( str ), "%s(Y)", text ); + mbedtls_debug_print_mpi( ssl, level, file, line, str, &X->Y ); +} +#endif /* MBEDTLS_ECP_C */ + +#if !defined(MBEDTLS_PK_ALT) +#if defined(MBEDTLS_BIGNUM_C) +void mbedtls_debug_print_mpi( const mbedtls_ssl_context *ssl, int level, + const char *file, int line, + const char *text, const mbedtls_mpi *X ) +{ + char str[DEBUG_BUF_SIZE]; + int j, k, zeros = 1; + size_t i, n, idx = 0; + + if( ssl->conf == NULL || ssl->conf->f_dbg == NULL || X == NULL || level > debug_threshold ) + return; + + for( n = X->n - 1; n > 0; n-- ) + if( X->p[n] != 0 ) + break; + + for( j = ( sizeof(mbedtls_mpi_uint) << 3 ) - 1; j >= 0; j-- ) + if( ( ( X->p[n] >> j ) & 1 ) != 0 ) + break; + + mbedtls_snprintf( str + idx, sizeof( str ) - idx, "value of '%s' (%d bits) is:\n", + text, (int) ( ( n * ( sizeof(mbedtls_mpi_uint) << 3 ) ) + j + 1 ) ); + + debug_send_line( ssl, level, file, line, str ); + + idx = 0; + for( i = n + 1, j = 0; i > 0; i-- ) + { + if( zeros && X->p[i - 1] == 0 ) + continue; + + for( k = sizeof( mbedtls_mpi_uint ) - 1; k >= 0; k-- ) + { + if( zeros && ( ( X->p[i - 1] >> ( k << 3 ) ) & 0xFF ) == 0 ) + continue; + else + zeros = 0; + + if( j % 16 == 0 ) + { + if( j > 0 ) + { + mbedtls_snprintf( str + idx, sizeof( str ) - idx, "\n" ); + debug_send_line( ssl, level, file, line, str ); + idx = 0; + } + } + + idx += mbedtls_snprintf( str + idx, sizeof( str ) - idx, " %02x", (unsigned int) + ( X->p[i - 1] >> ( k << 3 ) ) & 0xFF ); + + j++; + } + + } + + if( zeros == 1 ) + idx += mbedtls_snprintf( str + idx, sizeof( str ) - idx, " 00" ); + + mbedtls_snprintf( str + idx, sizeof( str ) - idx, "\n" ); + debug_send_line( ssl, level, file, line, str ); +} +#endif /* MBEDTLS_BIGNUM_C */ +#endif /* MBEDTLS_PK_ALT */ + +#if defined(MBEDTLS_X509_CRT_PARSE_C) +static void debug_print_pk( const mbedtls_ssl_context *ssl, int level, + const char *file, int line, + const char *text, const mbedtls_pk_context *pk ) +{ + size_t i; + mbedtls_pk_debug_item items[MBEDTLS_PK_DEBUG_MAX_ITEMS]; + char name[16]; + + memset( items, 0, sizeof( items ) ); + + if( mbedtls_pk_debug( pk, items ) != 0 ) + { + debug_send_line( ssl, level, file, line, + "invalid PK context\n" ); + return; + } + + for( i = 0; i < MBEDTLS_PK_DEBUG_MAX_ITEMS; i++ ) + { + if( items[i].type == MBEDTLS_PK_DEBUG_NONE ) + return; + + mbedtls_snprintf( name, sizeof( name ), "%s%s", text, items[i].name ); + name[sizeof( name ) - 1] = '\0'; + +#if !defined(MBEDTLS_PK_ALT) + if( items[i].type == MBEDTLS_PK_DEBUG_MPI ) + mbedtls_debug_print_mpi( ssl, level, file, line, name, items[i].value ); + else +#if defined(MBEDTLS_ECP_C) + if( items[i].type == MBEDTLS_PK_DEBUG_ECP ) + mbedtls_debug_print_ecp( ssl, level, file, line, name, items[i].value ); + else +#endif +#endif + debug_send_line( ssl, level, file, line, + "should not happen\n" ); + } +} + +static void debug_print_line_by_line( const mbedtls_ssl_context *ssl, int level, + const char *file, int line, const char *text ) +{ + char str[DEBUG_BUF_SIZE]; + const char *start, *cur; + + start = text; + for( cur = text; *cur != '\0'; cur++ ) + { + if( *cur == '\n' ) + { + size_t len = cur - start + 1; + if( len > DEBUG_BUF_SIZE - 1 ) + len = DEBUG_BUF_SIZE - 1; + + memcpy( str, start, len ); + str[len] = '\0'; + + debug_send_line( ssl, level, file, line, str ); + + start = cur + 1; + } + } +} + +void mbedtls_debug_print_crt( const mbedtls_ssl_context *ssl, int level, + const char *file, int line, + const char *text, const mbedtls_x509_crt *crt ) +{ + char str[DEBUG_BUF_SIZE]; + int i = 0; + + if( ssl->conf == NULL || ssl->conf->f_dbg == NULL || crt == NULL || level > debug_threshold ) + return; + + while( crt != NULL ) + { + char buf[1024]; + + mbedtls_snprintf( str, sizeof( str ), "%s #%d:\n", text, ++i ); + debug_send_line( ssl, level, file, line, str ); + + mbedtls_x509_crt_info( buf, sizeof( buf ) - 1, "", crt ); + debug_print_line_by_line( ssl, level, file, line, buf ); + + debug_print_pk( ssl, level, file, line, "crt->", &crt->pk ); + + crt = crt->next; + } +} +#endif /* MBEDTLS_X509_CRT_PARSE_C */ + +void mbedtls_debug_print_data(int level, + const char *file, int line, + const char *name, const unsigned char *data, int len) +{ + int i; + + if (data == NULL || len == 0 || level > debug_threshold) { + return; + } + + printf("%s line: %d %s - len: %d\n", file, line, name , len); + + for (i = 0; i < len - len % 8; i += 8) { + printf("%s: %d - %s: %02x %02x %02x %02x %02x %02x %02x %02x\n", + file, line, name, + data[i+0], data[i+1], data[i+2], data[i+3], + data[i+4], data[i+5], data[i+6], data[i+7]); + } + while(i < len) { + printf("%s line: %d %s %02x\n", file, line, name, data[i++]); + } + +} + +#endif /* MBEDTLS_DEBUG_C */ diff --git a/security/mbedtls/src/des.c b/security/mbedtls/src/des.c new file mode 100644 index 0000000000..09f95cfc3b --- /dev/null +++ b/security/mbedtls/src/des.c @@ -0,0 +1,1061 @@ +/* + * FIPS-46-3 compliant Triple-DES implementation + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +/* + * DES, on which TDES is based, was originally designed by Horst Feistel + * at IBM in 1974, and was adopted as a standard by NIST (formerly NBS). + * + * http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_DES_C) + +#include "mbedtls/des.h" + +#include + +#if defined(MBEDTLS_SELF_TEST) +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_printf printf +#endif /* MBEDTLS_PLATFORM_C */ +#endif /* MBEDTLS_SELF_TEST */ + +#if !defined(MBEDTLS_DES_ALT) + +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0; +} + +/* + * 32-bit integer manipulation macros (big endian) + */ +#ifndef GET_UINT32_BE +#define GET_UINT32_BE(n,b,i) \ +{ \ + (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ + | ( (uint32_t) (b)[(i) + 1] << 16 ) \ + | ( (uint32_t) (b)[(i) + 2] << 8 ) \ + | ( (uint32_t) (b)[(i) + 3] ); \ +} +#endif + +#ifndef PUT_UINT32_BE +#define PUT_UINT32_BE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) ); \ +} +#endif + +/* + * Expanded DES S-boxes + */ +static const uint32_t SB1[64] = +{ + 0x01010400, 0x00000000, 0x00010000, 0x01010404, + 0x01010004, 0x00010404, 0x00000004, 0x00010000, + 0x00000400, 0x01010400, 0x01010404, 0x00000400, + 0x01000404, 0x01010004, 0x01000000, 0x00000004, + 0x00000404, 0x01000400, 0x01000400, 0x00010400, + 0x00010400, 0x01010000, 0x01010000, 0x01000404, + 0x00010004, 0x01000004, 0x01000004, 0x00010004, + 0x00000000, 0x00000404, 0x00010404, 0x01000000, + 0x00010000, 0x01010404, 0x00000004, 0x01010000, + 0x01010400, 0x01000000, 0x01000000, 0x00000400, + 0x01010004, 0x00010000, 0x00010400, 0x01000004, + 0x00000400, 0x00000004, 0x01000404, 0x00010404, + 0x01010404, 0x00010004, 0x01010000, 0x01000404, + 0x01000004, 0x00000404, 0x00010404, 0x01010400, + 0x00000404, 0x01000400, 0x01000400, 0x00000000, + 0x00010004, 0x00010400, 0x00000000, 0x01010004 +}; + +static const uint32_t SB2[64] = +{ + 0x80108020, 0x80008000, 0x00008000, 0x00108020, + 0x00100000, 0x00000020, 0x80100020, 0x80008020, + 0x80000020, 0x80108020, 0x80108000, 0x80000000, + 0x80008000, 0x00100000, 0x00000020, 0x80100020, + 0x00108000, 0x00100020, 0x80008020, 0x00000000, + 0x80000000, 0x00008000, 0x00108020, 0x80100000, + 0x00100020, 0x80000020, 0x00000000, 0x00108000, + 0x00008020, 0x80108000, 0x80100000, 0x00008020, + 0x00000000, 0x00108020, 0x80100020, 0x00100000, + 0x80008020, 0x80100000, 0x80108000, 0x00008000, + 0x80100000, 0x80008000, 0x00000020, 0x80108020, + 0x00108020, 0x00000020, 0x00008000, 0x80000000, + 0x00008020, 0x80108000, 0x00100000, 0x80000020, + 0x00100020, 0x80008020, 0x80000020, 0x00100020, + 0x00108000, 0x00000000, 0x80008000, 0x00008020, + 0x80000000, 0x80100020, 0x80108020, 0x00108000 +}; + +static const uint32_t SB3[64] = +{ + 0x00000208, 0x08020200, 0x00000000, 0x08020008, + 0x08000200, 0x00000000, 0x00020208, 0x08000200, + 0x00020008, 0x08000008, 0x08000008, 0x00020000, + 0x08020208, 0x00020008, 0x08020000, 0x00000208, + 0x08000000, 0x00000008, 0x08020200, 0x00000200, + 0x00020200, 0x08020000, 0x08020008, 0x00020208, + 0x08000208, 0x00020200, 0x00020000, 0x08000208, + 0x00000008, 0x08020208, 0x00000200, 0x08000000, + 0x08020200, 0x08000000, 0x00020008, 0x00000208, + 0x00020000, 0x08020200, 0x08000200, 0x00000000, + 0x00000200, 0x00020008, 0x08020208, 0x08000200, + 0x08000008, 0x00000200, 0x00000000, 0x08020008, + 0x08000208, 0x00020000, 0x08000000, 0x08020208, + 0x00000008, 0x00020208, 0x00020200, 0x08000008, + 0x08020000, 0x08000208, 0x00000208, 0x08020000, + 0x00020208, 0x00000008, 0x08020008, 0x00020200 +}; + +static const uint32_t SB4[64] = +{ + 0x00802001, 0x00002081, 0x00002081, 0x00000080, + 0x00802080, 0x00800081, 0x00800001, 0x00002001, + 0x00000000, 0x00802000, 0x00802000, 0x00802081, + 0x00000081, 0x00000000, 0x00800080, 0x00800001, + 0x00000001, 0x00002000, 0x00800000, 0x00802001, + 0x00000080, 0x00800000, 0x00002001, 0x00002080, + 0x00800081, 0x00000001, 0x00002080, 0x00800080, + 0x00002000, 0x00802080, 0x00802081, 0x00000081, + 0x00800080, 0x00800001, 0x00802000, 0x00802081, + 0x00000081, 0x00000000, 0x00000000, 0x00802000, + 0x00002080, 0x00800080, 0x00800081, 0x00000001, + 0x00802001, 0x00002081, 0x00002081, 0x00000080, + 0x00802081, 0x00000081, 0x00000001, 0x00002000, + 0x00800001, 0x00002001, 0x00802080, 0x00800081, + 0x00002001, 0x00002080, 0x00800000, 0x00802001, + 0x00000080, 0x00800000, 0x00002000, 0x00802080 +}; + +static const uint32_t SB5[64] = +{ + 0x00000100, 0x02080100, 0x02080000, 0x42000100, + 0x00080000, 0x00000100, 0x40000000, 0x02080000, + 0x40080100, 0x00080000, 0x02000100, 0x40080100, + 0x42000100, 0x42080000, 0x00080100, 0x40000000, + 0x02000000, 0x40080000, 0x40080000, 0x00000000, + 0x40000100, 0x42080100, 0x42080100, 0x02000100, + 0x42080000, 0x40000100, 0x00000000, 0x42000000, + 0x02080100, 0x02000000, 0x42000000, 0x00080100, + 0x00080000, 0x42000100, 0x00000100, 0x02000000, + 0x40000000, 0x02080000, 0x42000100, 0x40080100, + 0x02000100, 0x40000000, 0x42080000, 0x02080100, + 0x40080100, 0x00000100, 0x02000000, 0x42080000, + 0x42080100, 0x00080100, 0x42000000, 0x42080100, + 0x02080000, 0x00000000, 0x40080000, 0x42000000, + 0x00080100, 0x02000100, 0x40000100, 0x00080000, + 0x00000000, 0x40080000, 0x02080100, 0x40000100 +}; + +static const uint32_t SB6[64] = +{ + 0x20000010, 0x20400000, 0x00004000, 0x20404010, + 0x20400000, 0x00000010, 0x20404010, 0x00400000, + 0x20004000, 0x00404010, 0x00400000, 0x20000010, + 0x00400010, 0x20004000, 0x20000000, 0x00004010, + 0x00000000, 0x00400010, 0x20004010, 0x00004000, + 0x00404000, 0x20004010, 0x00000010, 0x20400010, + 0x20400010, 0x00000000, 0x00404010, 0x20404000, + 0x00004010, 0x00404000, 0x20404000, 0x20000000, + 0x20004000, 0x00000010, 0x20400010, 0x00404000, + 0x20404010, 0x00400000, 0x00004010, 0x20000010, + 0x00400000, 0x20004000, 0x20000000, 0x00004010, + 0x20000010, 0x20404010, 0x00404000, 0x20400000, + 0x00404010, 0x20404000, 0x00000000, 0x20400010, + 0x00000010, 0x00004000, 0x20400000, 0x00404010, + 0x00004000, 0x00400010, 0x20004010, 0x00000000, + 0x20404000, 0x20000000, 0x00400010, 0x20004010 +}; + +static const uint32_t SB7[64] = +{ + 0x00200000, 0x04200002, 0x04000802, 0x00000000, + 0x00000800, 0x04000802, 0x00200802, 0x04200800, + 0x04200802, 0x00200000, 0x00000000, 0x04000002, + 0x00000002, 0x04000000, 0x04200002, 0x00000802, + 0x04000800, 0x00200802, 0x00200002, 0x04000800, + 0x04000002, 0x04200000, 0x04200800, 0x00200002, + 0x04200000, 0x00000800, 0x00000802, 0x04200802, + 0x00200800, 0x00000002, 0x04000000, 0x00200800, + 0x04000000, 0x00200800, 0x00200000, 0x04000802, + 0x04000802, 0x04200002, 0x04200002, 0x00000002, + 0x00200002, 0x04000000, 0x04000800, 0x00200000, + 0x04200800, 0x00000802, 0x00200802, 0x04200800, + 0x00000802, 0x04000002, 0x04200802, 0x04200000, + 0x00200800, 0x00000000, 0x00000002, 0x04200802, + 0x00000000, 0x00200802, 0x04200000, 0x00000800, + 0x04000002, 0x04000800, 0x00000800, 0x00200002 +}; + +static const uint32_t SB8[64] = +{ + 0x10001040, 0x00001000, 0x00040000, 0x10041040, + 0x10000000, 0x10001040, 0x00000040, 0x10000000, + 0x00040040, 0x10040000, 0x10041040, 0x00041000, + 0x10041000, 0x00041040, 0x00001000, 0x00000040, + 0x10040000, 0x10000040, 0x10001000, 0x00001040, + 0x00041000, 0x00040040, 0x10040040, 0x10041000, + 0x00001040, 0x00000000, 0x00000000, 0x10040040, + 0x10000040, 0x10001000, 0x00041040, 0x00040000, + 0x00041040, 0x00040000, 0x10041000, 0x00001000, + 0x00000040, 0x10040040, 0x00001000, 0x00041040, + 0x10001000, 0x00000040, 0x10000040, 0x10040000, + 0x10040040, 0x10000000, 0x00040000, 0x10001040, + 0x00000000, 0x10041040, 0x00040040, 0x10000040, + 0x10040000, 0x10001000, 0x10001040, 0x00000000, + 0x10041040, 0x00041000, 0x00041000, 0x00001040, + 0x00001040, 0x00040040, 0x10000000, 0x10041000 +}; + +/* + * PC1: left and right halves bit-swap + */ +static const uint32_t LHs[16] = +{ + 0x00000000, 0x00000001, 0x00000100, 0x00000101, + 0x00010000, 0x00010001, 0x00010100, 0x00010101, + 0x01000000, 0x01000001, 0x01000100, 0x01000101, + 0x01010000, 0x01010001, 0x01010100, 0x01010101 +}; + +static const uint32_t RHs[16] = +{ + 0x00000000, 0x01000000, 0x00010000, 0x01010000, + 0x00000100, 0x01000100, 0x00010100, 0x01010100, + 0x00000001, 0x01000001, 0x00010001, 0x01010001, + 0x00000101, 0x01000101, 0x00010101, 0x01010101, +}; + +/* + * Initial Permutation macro + */ +#define DES_IP(X,Y) \ +{ \ + T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \ + T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \ + T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \ + T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \ + Y = ((Y << 1) | (Y >> 31)) & 0xFFFFFFFF; \ + T = (X ^ Y) & 0xAAAAAAAA; Y ^= T; X ^= T; \ + X = ((X << 1) | (X >> 31)) & 0xFFFFFFFF; \ +} + +/* + * Final Permutation macro + */ +#define DES_FP(X,Y) \ +{ \ + X = ((X << 31) | (X >> 1)) & 0xFFFFFFFF; \ + T = (X ^ Y) & 0xAAAAAAAA; X ^= T; Y ^= T; \ + Y = ((Y << 31) | (Y >> 1)) & 0xFFFFFFFF; \ + T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \ + T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \ + T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \ + T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \ +} + +/* + * DES round macro + */ +#define DES_ROUND(X,Y) \ +{ \ + T = *SK++ ^ X; \ + Y ^= SB8[ (T ) & 0x3F ] ^ \ + SB6[ (T >> 8) & 0x3F ] ^ \ + SB4[ (T >> 16) & 0x3F ] ^ \ + SB2[ (T >> 24) & 0x3F ]; \ + \ + T = *SK++ ^ ((X << 28) | (X >> 4)); \ + Y ^= SB7[ (T ) & 0x3F ] ^ \ + SB5[ (T >> 8) & 0x3F ] ^ \ + SB3[ (T >> 16) & 0x3F ] ^ \ + SB1[ (T >> 24) & 0x3F ]; \ +} + +#define SWAP(a,b) { uint32_t t = a; a = b; b = t; t = 0; } + +void mbedtls_des_init( mbedtls_des_context *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_des_context ) ); +} + +void mbedtls_des_free( mbedtls_des_context *ctx ) +{ + if( ctx == NULL ) + return; + + mbedtls_zeroize( ctx, sizeof( mbedtls_des_context ) ); +} + +void mbedtls_des3_init( mbedtls_des3_context *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_des3_context ) ); +} + +void mbedtls_des3_free( mbedtls_des3_context *ctx ) +{ + if( ctx == NULL ) + return; + + mbedtls_zeroize( ctx, sizeof( mbedtls_des3_context ) ); +} + +static const unsigned char odd_parity_table[128] = { 1, 2, 4, 7, 8, + 11, 13, 14, 16, 19, 21, 22, 25, 26, 28, 31, 32, 35, 37, 38, 41, 42, 44, + 47, 49, 50, 52, 55, 56, 59, 61, 62, 64, 67, 69, 70, 73, 74, 76, 79, 81, + 82, 84, 87, 88, 91, 93, 94, 97, 98, 100, 103, 104, 107, 109, 110, 112, + 115, 117, 118, 121, 122, 124, 127, 128, 131, 133, 134, 137, 138, 140, + 143, 145, 146, 148, 151, 152, 155, 157, 158, 161, 162, 164, 167, 168, + 171, 173, 174, 176, 179, 181, 182, 185, 186, 188, 191, 193, 194, 196, + 199, 200, 203, 205, 206, 208, 211, 213, 214, 217, 218, 220, 223, 224, + 227, 229, 230, 233, 234, 236, 239, 241, 242, 244, 247, 248, 251, 253, + 254 }; + +void mbedtls_des_key_set_parity( unsigned char key[MBEDTLS_DES_KEY_SIZE] ) +{ + int i; + + for( i = 0; i < MBEDTLS_DES_KEY_SIZE; i++ ) + key[i] = odd_parity_table[key[i] / 2]; +} + +/* + * Check the given key's parity, returns 1 on failure, 0 on SUCCESS + */ +int mbedtls_des_key_check_key_parity( const unsigned char key[MBEDTLS_DES_KEY_SIZE] ) +{ + int i; + + for( i = 0; i < MBEDTLS_DES_KEY_SIZE; i++ ) + if( key[i] != odd_parity_table[key[i] / 2] ) + return( 1 ); + + return( 0 ); +} + +/* + * Table of weak and semi-weak keys + * + * Source: http://en.wikipedia.org/wiki/Weak_key + * + * Weak: + * Alternating ones + zeros (0x0101010101010101) + * Alternating 'F' + 'E' (0xFEFEFEFEFEFEFEFE) + * '0xE0E0E0E0F1F1F1F1' + * '0x1F1F1F1F0E0E0E0E' + * + * Semi-weak: + * 0x011F011F010E010E and 0x1F011F010E010E01 + * 0x01E001E001F101F1 and 0xE001E001F101F101 + * 0x01FE01FE01FE01FE and 0xFE01FE01FE01FE01 + * 0x1FE01FE00EF10EF1 and 0xE01FE01FF10EF10E + * 0x1FFE1FFE0EFE0EFE and 0xFE1FFE1FFE0EFE0E + * 0xE0FEE0FEF1FEF1FE and 0xFEE0FEE0FEF1FEF1 + * + */ + +#define WEAK_KEY_COUNT 16 + +static const unsigned char weak_key_table[WEAK_KEY_COUNT][MBEDTLS_DES_KEY_SIZE] = +{ + { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 }, + { 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE }, + { 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E }, + { 0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1 }, + + { 0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E }, + { 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01 }, + { 0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1 }, + { 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01 }, + { 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE }, + { 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01 }, + { 0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1 }, + { 0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E }, + { 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE }, + { 0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E }, + { 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE }, + { 0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1 } +}; + +int mbedtls_des_key_check_weak( const unsigned char key[MBEDTLS_DES_KEY_SIZE] ) +{ + int i; + + for( i = 0; i < WEAK_KEY_COUNT; i++ ) + if( memcmp( weak_key_table[i], key, MBEDTLS_DES_KEY_SIZE) == 0 ) + return( 1 ); + + return( 0 ); +} + +#if !defined(MBEDTLS_DES_SETKEY_ALT) +void mbedtls_des_setkey( uint32_t SK[32], const unsigned char key[MBEDTLS_DES_KEY_SIZE] ) +{ + int i; + uint32_t X, Y, T; + + GET_UINT32_BE( X, key, 0 ); + GET_UINT32_BE( Y, key, 4 ); + + /* + * Permuted Choice 1 + */ + T = ((Y >> 4) ^ X) & 0x0F0F0F0F; X ^= T; Y ^= (T << 4); + T = ((Y ) ^ X) & 0x10101010; X ^= T; Y ^= (T ); + + X = (LHs[ (X ) & 0xF] << 3) | (LHs[ (X >> 8) & 0xF ] << 2) + | (LHs[ (X >> 16) & 0xF] << 1) | (LHs[ (X >> 24) & 0xF ] ) + | (LHs[ (X >> 5) & 0xF] << 7) | (LHs[ (X >> 13) & 0xF ] << 6) + | (LHs[ (X >> 21) & 0xF] << 5) | (LHs[ (X >> 29) & 0xF ] << 4); + + Y = (RHs[ (Y >> 1) & 0xF] << 3) | (RHs[ (Y >> 9) & 0xF ] << 2) + | (RHs[ (Y >> 17) & 0xF] << 1) | (RHs[ (Y >> 25) & 0xF ] ) + | (RHs[ (Y >> 4) & 0xF] << 7) | (RHs[ (Y >> 12) & 0xF ] << 6) + | (RHs[ (Y >> 20) & 0xF] << 5) | (RHs[ (Y >> 28) & 0xF ] << 4); + + X &= 0x0FFFFFFF; + Y &= 0x0FFFFFFF; + + /* + * calculate subkeys + */ + for( i = 0; i < 16; i++ ) + { + if( i < 2 || i == 8 || i == 15 ) + { + X = ((X << 1) | (X >> 27)) & 0x0FFFFFFF; + Y = ((Y << 1) | (Y >> 27)) & 0x0FFFFFFF; + } + else + { + X = ((X << 2) | (X >> 26)) & 0x0FFFFFFF; + Y = ((Y << 2) | (Y >> 26)) & 0x0FFFFFFF; + } + + *SK++ = ((X << 4) & 0x24000000) | ((X << 28) & 0x10000000) + | ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000) + | ((X << 6) & 0x01000000) | ((X << 9) & 0x00200000) + | ((X >> 1) & 0x00100000) | ((X << 10) & 0x00040000) + | ((X << 2) & 0x00020000) | ((X >> 10) & 0x00010000) + | ((Y >> 13) & 0x00002000) | ((Y >> 4) & 0x00001000) + | ((Y << 6) & 0x00000800) | ((Y >> 1) & 0x00000400) + | ((Y >> 14) & 0x00000200) | ((Y ) & 0x00000100) + | ((Y >> 5) & 0x00000020) | ((Y >> 10) & 0x00000010) + | ((Y >> 3) & 0x00000008) | ((Y >> 18) & 0x00000004) + | ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001); + + *SK++ = ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000) + | ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000) + | ((X >> 2) & 0x02000000) | ((X << 1) & 0x01000000) + | ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000) + | ((X << 3) & 0x00080000) | ((X >> 6) & 0x00040000) + | ((X << 15) & 0x00020000) | ((X >> 4) & 0x00010000) + | ((Y >> 2) & 0x00002000) | ((Y << 8) & 0x00001000) + | ((Y >> 14) & 0x00000808) | ((Y >> 9) & 0x00000400) + | ((Y ) & 0x00000200) | ((Y << 7) & 0x00000100) + | ((Y >> 7) & 0x00000020) | ((Y >> 3) & 0x00000011) + | ((Y << 2) & 0x00000004) | ((Y >> 21) & 0x00000002); + } +} +#endif /* !MBEDTLS_DES_SETKEY_ALT */ + +/* + * DES key schedule (56-bit, encryption) + */ +int mbedtls_des_setkey_enc( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] ) +{ + mbedtls_des_setkey( ctx->sk, key ); + + return( 0 ); +} + +/* + * DES key schedule (56-bit, decryption) + */ +int mbedtls_des_setkey_dec( mbedtls_des_context *ctx, const unsigned char key[MBEDTLS_DES_KEY_SIZE] ) +{ + int i; + + mbedtls_des_setkey( ctx->sk, key ); + + for( i = 0; i < 16; i += 2 ) + { + SWAP( ctx->sk[i ], ctx->sk[30 - i] ); + SWAP( ctx->sk[i + 1], ctx->sk[31 - i] ); + } + + return( 0 ); +} + +static void des3_set2key( uint32_t esk[96], + uint32_t dsk[96], + const unsigned char key[MBEDTLS_DES_KEY_SIZE*2] ) +{ + int i; + + mbedtls_des_setkey( esk, key ); + mbedtls_des_setkey( dsk + 32, key + 8 ); + + for( i = 0; i < 32; i += 2 ) + { + dsk[i ] = esk[30 - i]; + dsk[i + 1] = esk[31 - i]; + + esk[i + 32] = dsk[62 - i]; + esk[i + 33] = dsk[63 - i]; + + esk[i + 64] = esk[i ]; + esk[i + 65] = esk[i + 1]; + + dsk[i + 64] = dsk[i ]; + dsk[i + 65] = dsk[i + 1]; + } +} + +/* + * Triple-DES key schedule (112-bit, encryption) + */ +int mbedtls_des3_set2key_enc( mbedtls_des3_context *ctx, + const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] ) +{ + uint32_t sk[96]; + + des3_set2key( ctx->sk, sk, key ); + mbedtls_zeroize( sk, sizeof( sk ) ); + + return( 0 ); +} + +/* + * Triple-DES key schedule (112-bit, decryption) + */ +int mbedtls_des3_set2key_dec( mbedtls_des3_context *ctx, + const unsigned char key[MBEDTLS_DES_KEY_SIZE * 2] ) +{ + uint32_t sk[96]; + + des3_set2key( sk, ctx->sk, key ); + mbedtls_zeroize( sk, sizeof( sk ) ); + + return( 0 ); +} + +static void des3_set3key( uint32_t esk[96], + uint32_t dsk[96], + const unsigned char key[24] ) +{ + int i; + + mbedtls_des_setkey( esk, key ); + mbedtls_des_setkey( dsk + 32, key + 8 ); + mbedtls_des_setkey( esk + 64, key + 16 ); + + for( i = 0; i < 32; i += 2 ) + { + dsk[i ] = esk[94 - i]; + dsk[i + 1] = esk[95 - i]; + + esk[i + 32] = dsk[62 - i]; + esk[i + 33] = dsk[63 - i]; + + dsk[i + 64] = esk[30 - i]; + dsk[i + 65] = esk[31 - i]; + } +} + +/* + * Triple-DES key schedule (168-bit, encryption) + */ +int mbedtls_des3_set3key_enc( mbedtls_des3_context *ctx, + const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] ) +{ + uint32_t sk[96]; + + des3_set3key( ctx->sk, sk, key ); + mbedtls_zeroize( sk, sizeof( sk ) ); + + return( 0 ); +} + +/* + * Triple-DES key schedule (168-bit, decryption) + */ +int mbedtls_des3_set3key_dec( mbedtls_des3_context *ctx, + const unsigned char key[MBEDTLS_DES_KEY_SIZE * 3] ) +{ + uint32_t sk[96]; + + des3_set3key( sk, ctx->sk, key ); + mbedtls_zeroize( sk, sizeof( sk ) ); + + return( 0 ); +} + +/* + * DES-ECB block encryption/decryption + */ +#if !defined(MBEDTLS_DES_CRYPT_ECB_ALT) +int mbedtls_des_crypt_ecb( mbedtls_des_context *ctx, + const unsigned char input[8], + unsigned char output[8] ) +{ + int i; + uint32_t X, Y, T, *SK; + + SK = ctx->sk; + + GET_UINT32_BE( X, input, 0 ); + GET_UINT32_BE( Y, input, 4 ); + + DES_IP( X, Y ); + + for( i = 0; i < 8; i++ ) + { + DES_ROUND( Y, X ); + DES_ROUND( X, Y ); + } + + DES_FP( Y, X ); + + PUT_UINT32_BE( Y, output, 0 ); + PUT_UINT32_BE( X, output, 4 ); + + return( 0 ); +} +#endif /* !MBEDTLS_DES_CRYPT_ECB_ALT */ + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +/* + * DES-CBC buffer encryption/decryption + */ +int mbedtls_des_crypt_cbc( mbedtls_des_context *ctx, + int mode, + size_t length, + unsigned char iv[8], + const unsigned char *input, + unsigned char *output ) +{ + int i; + unsigned char temp[8]; + + if( length % 8 ) + return( MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH ); + + if( mode == MBEDTLS_DES_ENCRYPT ) + { + while( length > 0 ) + { + for( i = 0; i < 8; i++ ) + output[i] = (unsigned char)( input[i] ^ iv[i] ); + + mbedtls_des_crypt_ecb( ctx, output, output ); + memcpy( iv, output, 8 ); + + input += 8; + output += 8; + length -= 8; + } + } + else /* MBEDTLS_DES_DECRYPT */ + { + while( length > 0 ) + { + memcpy( temp, input, 8 ); + mbedtls_des_crypt_ecb( ctx, input, output ); + + for( i = 0; i < 8; i++ ) + output[i] = (unsigned char)( output[i] ^ iv[i] ); + + memcpy( iv, temp, 8 ); + + input += 8; + output += 8; + length -= 8; + } + } + + return( 0 ); +} +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +/* + * 3DES-ECB block encryption/decryption + */ +#if !defined(MBEDTLS_DES3_CRYPT_ECB_ALT) +int mbedtls_des3_crypt_ecb( mbedtls_des3_context *ctx, + const unsigned char input[8], + unsigned char output[8] ) +{ + int i; + uint32_t X, Y, T, *SK; + + SK = ctx->sk; + + GET_UINT32_BE( X, input, 0 ); + GET_UINT32_BE( Y, input, 4 ); + + DES_IP( X, Y ); + + for( i = 0; i < 8; i++ ) + { + DES_ROUND( Y, X ); + DES_ROUND( X, Y ); + } + + for( i = 0; i < 8; i++ ) + { + DES_ROUND( X, Y ); + DES_ROUND( Y, X ); + } + + for( i = 0; i < 8; i++ ) + { + DES_ROUND( Y, X ); + DES_ROUND( X, Y ); + } + + DES_FP( Y, X ); + + PUT_UINT32_BE( Y, output, 0 ); + PUT_UINT32_BE( X, output, 4 ); + + return( 0 ); +} +#endif /* !MBEDTLS_DES3_CRYPT_ECB_ALT */ + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +/* + * 3DES-CBC buffer encryption/decryption + */ +int mbedtls_des3_crypt_cbc( mbedtls_des3_context *ctx, + int mode, + size_t length, + unsigned char iv[8], + const unsigned char *input, + unsigned char *output ) +{ + int i; + unsigned char temp[8]; + + if( length % 8 ) + return( MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH ); + + if( mode == MBEDTLS_DES_ENCRYPT ) + { + while( length > 0 ) + { + for( i = 0; i < 8; i++ ) + output[i] = (unsigned char)( input[i] ^ iv[i] ); + + mbedtls_des3_crypt_ecb( ctx, output, output ); + memcpy( iv, output, 8 ); + + input += 8; + output += 8; + length -= 8; + } + } + else /* MBEDTLS_DES_DECRYPT */ + { + while( length > 0 ) + { + memcpy( temp, input, 8 ); + mbedtls_des3_crypt_ecb( ctx, input, output ); + + for( i = 0; i < 8; i++ ) + output[i] = (unsigned char)( output[i] ^ iv[i] ); + + memcpy( iv, temp, 8 ); + + input += 8; + output += 8; + length -= 8; + } + } + + return( 0 ); +} +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#endif /* !MBEDTLS_DES_ALT */ + +#if defined(MBEDTLS_SELF_TEST) +/* + * DES and 3DES test vectors from: + * + * http://csrc.nist.gov/groups/STM/cavp/documents/des/tripledes-vectors.zip + */ +static const unsigned char des3_test_keys[24] = +{ + 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, + 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, + 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23 +}; + +static const unsigned char des3_test_buf[8] = +{ + 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74 +}; + +static const unsigned char des3_test_ecb_dec[3][8] = +{ + { 0xCD, 0xD6, 0x4F, 0x2F, 0x94, 0x27, 0xC1, 0x5D }, + { 0x69, 0x96, 0xC8, 0xFA, 0x47, 0xA2, 0xAB, 0xEB }, + { 0x83, 0x25, 0x39, 0x76, 0x44, 0x09, 0x1A, 0x0A } +}; + +static const unsigned char des3_test_ecb_enc[3][8] = +{ + { 0x6A, 0x2A, 0x19, 0xF4, 0x1E, 0xCA, 0x85, 0x4B }, + { 0x03, 0xE6, 0x9F, 0x5B, 0xFA, 0x58, 0xEB, 0x42 }, + { 0xDD, 0x17, 0xE8, 0xB8, 0xB4, 0x37, 0xD2, 0x32 } +}; + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +static const unsigned char des3_test_iv[8] = +{ + 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, +}; + +static const unsigned char des3_test_cbc_dec[3][8] = +{ + { 0x12, 0x9F, 0x40, 0xB9, 0xD2, 0x00, 0x56, 0xB3 }, + { 0x47, 0x0E, 0xFC, 0x9A, 0x6B, 0x8E, 0xE3, 0x93 }, + { 0xC5, 0xCE, 0xCF, 0x63, 0xEC, 0xEC, 0x51, 0x4C } +}; + +static const unsigned char des3_test_cbc_enc[3][8] = +{ + { 0x54, 0xF1, 0x5A, 0xF6, 0xEB, 0xE3, 0xA4, 0xB4 }, + { 0x35, 0x76, 0x11, 0x56, 0x5F, 0xA1, 0x8E, 0x4D }, + { 0xCB, 0x19, 0x1F, 0x85, 0xD1, 0xED, 0x84, 0x39 } +}; +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +/* + * Checkup routine + */ +int mbedtls_des_self_test( int verbose ) +{ + int i, j, u, v, ret = 0; + mbedtls_des_context ctx; + mbedtls_des3_context ctx3; + unsigned char buf[8]; +#if defined(MBEDTLS_CIPHER_MODE_CBC) + unsigned char prv[8]; + unsigned char iv[8]; +#endif + + mbedtls_des_init( &ctx ); + mbedtls_des3_init( &ctx3 ); + /* + * ECB mode + */ + for( i = 0; i < 6; i++ ) + { + u = i >> 1; + v = i & 1; + + if( verbose != 0 ) + mbedtls_printf( " DES%c-ECB-%3d (%s): ", + ( u == 0 ) ? ' ' : '3', 56 + u * 56, + ( v == MBEDTLS_DES_DECRYPT ) ? "dec" : "enc" ); + + memcpy( buf, des3_test_buf, 8 ); + + switch( i ) + { + case 0: + mbedtls_des_setkey_dec( &ctx, des3_test_keys ); + break; + + case 1: + mbedtls_des_setkey_enc( &ctx, des3_test_keys ); + break; + + case 2: + mbedtls_des3_set2key_dec( &ctx3, des3_test_keys ); + break; + + case 3: + mbedtls_des3_set2key_enc( &ctx3, des3_test_keys ); + break; + + case 4: + mbedtls_des3_set3key_dec( &ctx3, des3_test_keys ); + break; + + case 5: + mbedtls_des3_set3key_enc( &ctx3, des3_test_keys ); + break; + + default: + return( 1 ); + } + + for( j = 0; j < 10000; j++ ) + { + if( u == 0 ) + mbedtls_des_crypt_ecb( &ctx, buf, buf ); + else + mbedtls_des3_crypt_ecb( &ctx3, buf, buf ); + } + + if( ( v == MBEDTLS_DES_DECRYPT && + memcmp( buf, des3_test_ecb_dec[u], 8 ) != 0 ) || + ( v != MBEDTLS_DES_DECRYPT && + memcmp( buf, des3_test_ecb_enc[u], 8 ) != 0 ) ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + ret = 1; + goto exit; + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + +#if defined(MBEDTLS_CIPHER_MODE_CBC) + /* + * CBC mode + */ + for( i = 0; i < 6; i++ ) + { + u = i >> 1; + v = i & 1; + + if( verbose != 0 ) + mbedtls_printf( " DES%c-CBC-%3d (%s): ", + ( u == 0 ) ? ' ' : '3', 56 + u * 56, + ( v == MBEDTLS_DES_DECRYPT ) ? "dec" : "enc" ); + + memcpy( iv, des3_test_iv, 8 ); + memcpy( prv, des3_test_iv, 8 ); + memcpy( buf, des3_test_buf, 8 ); + + switch( i ) + { + case 0: + mbedtls_des_setkey_dec( &ctx, des3_test_keys ); + break; + + case 1: + mbedtls_des_setkey_enc( &ctx, des3_test_keys ); + break; + + case 2: + mbedtls_des3_set2key_dec( &ctx3, des3_test_keys ); + break; + + case 3: + mbedtls_des3_set2key_enc( &ctx3, des3_test_keys ); + break; + + case 4: + mbedtls_des3_set3key_dec( &ctx3, des3_test_keys ); + break; + + case 5: + mbedtls_des3_set3key_enc( &ctx3, des3_test_keys ); + break; + + default: + return( 1 ); + } + + if( v == MBEDTLS_DES_DECRYPT ) + { + for( j = 0; j < 10000; j++ ) + { + if( u == 0 ) + mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf ); + else + mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf ); + } + } + else + { + for( j = 0; j < 10000; j++ ) + { + unsigned char tmp[8]; + + if( u == 0 ) + mbedtls_des_crypt_cbc( &ctx, v, 8, iv, buf, buf ); + else + mbedtls_des3_crypt_cbc( &ctx3, v, 8, iv, buf, buf ); + + memcpy( tmp, prv, 8 ); + memcpy( prv, buf, 8 ); + memcpy( buf, tmp, 8 ); + } + + memcpy( buf, prv, 8 ); + } + + if( ( v == MBEDTLS_DES_DECRYPT && + memcmp( buf, des3_test_cbc_dec[u], 8 ) != 0 ) || + ( v != MBEDTLS_DES_DECRYPT && + memcmp( buf, des3_test_cbc_enc[u], 8 ) != 0 ) ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + ret = 1; + goto exit; + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + +exit: + mbedtls_des_free( &ctx ); + mbedtls_des3_free( &ctx3 ); + + return( ret ); +} + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_DES_C */ diff --git a/security/mbedtls/src/dhm.c b/security/mbedtls/src/dhm.c new file mode 100644 index 0000000000..a4715d1703 --- /dev/null +++ b/security/mbedtls/src/dhm.c @@ -0,0 +1,627 @@ +/* + * Diffie-Hellman-Merkle key exchange + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +/* + * The following sources were referenced in the design of this implementation + * of the Diffie-Hellman-Merkle algorithm: + * + * [1] Handbook of Applied Cryptography - 1997, Chapter 12 + * Menezes, van Oorschot and Vanstone + * + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_DHM_C) + +#include "mbedtls/dhm.h" + +#include + +#if defined(MBEDTLS_PEM_PARSE_C) +#include "mbedtls/pem.h" +#endif + +#if defined(MBEDTLS_ASN1_PARSE_C) +#include "mbedtls/asn1.h" +#endif + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#include +#define mbedtls_printf printf +#define mbedtls_calloc calloc +#define mbedtls_free free +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +/* + * helper to validate the mbedtls_mpi size and import it + */ +static int dhm_read_bignum( mbedtls_mpi *X, + unsigned char **p, + const unsigned char *end ) +{ + int ret, n; + + if( end - *p < 2 ) + return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA ); + + n = ( (*p)[0] << 8 ) | (*p)[1]; + (*p) += 2; + + if( (int)( end - *p ) < n ) + return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA ); + + if( ( ret = mbedtls_mpi_read_binary( X, *p, n ) ) != 0 ) + return( MBEDTLS_ERR_DHM_READ_PARAMS_FAILED + ret ); + + (*p) += n; + + return( 0 ); +} + +/* + * Verify sanity of parameter with regards to P + * + * Parameter should be: 2 <= public_param <= P - 2 + * + * For more information on the attack, see: + * http://www.cl.cam.ac.uk/~rja14/Papers/psandqs.pdf + * http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2005-2643 + */ +static int dhm_check_range( const mbedtls_mpi *param, const mbedtls_mpi *P ) +{ + mbedtls_mpi L, U; + int ret = MBEDTLS_ERR_DHM_BAD_INPUT_DATA; + + mbedtls_mpi_init( &L ); mbedtls_mpi_init( &U ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &L, 2 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &U, P, 2 ) ); + + if( mbedtls_mpi_cmp_mpi( param, &L ) >= 0 && + mbedtls_mpi_cmp_mpi( param, &U ) <= 0 ) + { + ret = 0; + } + +cleanup: + mbedtls_mpi_free( &L ); mbedtls_mpi_free( &U ); + return( ret ); +} + +void mbedtls_dhm_init( mbedtls_dhm_context *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_dhm_context ) ); +} + +/* + * Parse the ServerKeyExchange parameters + */ +int mbedtls_dhm_read_params( mbedtls_dhm_context *ctx, + unsigned char **p, + const unsigned char *end ) +{ + int ret; + + if( ( ret = dhm_read_bignum( &ctx->P, p, end ) ) != 0 || + ( ret = dhm_read_bignum( &ctx->G, p, end ) ) != 0 || + ( ret = dhm_read_bignum( &ctx->GY, p, end ) ) != 0 ) + return( ret ); + + if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 ) + return( ret ); + + ctx->len = mbedtls_mpi_size( &ctx->P ); + + return( 0 ); +} + +/* + * Setup and write the ServerKeyExchange parameters + */ +int mbedtls_dhm_make_params( mbedtls_dhm_context *ctx, int x_size, + unsigned char *output, size_t *olen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret, count = 0; + size_t n1, n2, n3; + unsigned char *p; + + if( mbedtls_mpi_cmp_int( &ctx->P, 0 ) == 0 ) + return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA ); + + /* + * Generate X as large as possible ( < P ) + */ + do + { + mbedtls_mpi_fill_random( &ctx->X, x_size, f_rng, p_rng ); + + while( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 ) + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &ctx->X, 1 ) ); + + if( count++ > 10 ) + return( MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED ); + } + while( dhm_check_range( &ctx->X, &ctx->P ) != 0 ); + + /* + * Calculate GX = G^X mod P + */ + MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->GX, &ctx->G, &ctx->X, + &ctx->P , &ctx->RP ) ); + + if( ( ret = dhm_check_range( &ctx->GX, &ctx->P ) ) != 0 ) + return( ret ); + + /* + * export P, G, GX + */ +#define DHM_MPI_EXPORT(X,n) \ + MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( X, p + 2, n ) ); \ + *p++ = (unsigned char)( n >> 8 ); \ + *p++ = (unsigned char)( n ); p += n; + + n1 = mbedtls_mpi_size( &ctx->P ); + n2 = mbedtls_mpi_size( &ctx->G ); + n3 = mbedtls_mpi_size( &ctx->GX ); + + p = output; + DHM_MPI_EXPORT( &ctx->P , n1 ); + DHM_MPI_EXPORT( &ctx->G , n2 ); + DHM_MPI_EXPORT( &ctx->GX, n3 ); + + *olen = p - output; + + ctx->len = n1; + +cleanup: + + if( ret != 0 ) + return( MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED + ret ); + + return( 0 ); +} + +/* + * Import the peer's public value G^Y + */ +int mbedtls_dhm_read_public( mbedtls_dhm_context *ctx, + const unsigned char *input, size_t ilen ) +{ + int ret; + + if( ctx == NULL || ilen < 1 || ilen > ctx->len ) + return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA ); + + if( ( ret = mbedtls_mpi_read_binary( &ctx->GY, input, ilen ) ) != 0 ) + return( MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED + ret ); + + return( 0 ); +} + +/* + * Create own private value X and export G^X + */ +int mbedtls_dhm_make_public( mbedtls_dhm_context *ctx, int x_size, + unsigned char *output, size_t olen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret, count = 0; + + if( ctx == NULL || olen < 1 || olen > ctx->len ) + return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA ); + + if( mbedtls_mpi_cmp_int( &ctx->P, 0 ) == 0 ) + return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA ); + + /* + * generate X and calculate GX = G^X mod P + */ + do + { + mbedtls_mpi_fill_random( &ctx->X, x_size, f_rng, p_rng ); + + while( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 ) + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &ctx->X, 1 ) ); + + if( count++ > 10 ) + return( MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED ); + } + while( dhm_check_range( &ctx->X, &ctx->P ) != 0 ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->GX, &ctx->G, &ctx->X, + &ctx->P , &ctx->RP ) ); + + if( ( ret = dhm_check_range( &ctx->GX, &ctx->P ) ) != 0 ) + return( ret ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->GX, output, olen ) ); + +cleanup: + + if( ret != 0 ) + return( MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED + ret ); + + return( 0 ); +} + +/* + * Use the blinding method and optimisation suggested in section 10 of: + * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA, + * DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer + * Berlin Heidelberg, 1996. p. 104-113. + */ +static int dhm_update_blinding( mbedtls_dhm_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + int ret, count; + + /* + * Don't use any blinding the first time a particular X is used, + * but remember it to use blinding next time. + */ + if( mbedtls_mpi_cmp_mpi( &ctx->X, &ctx->pX ) != 0 ) + { + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &ctx->pX, &ctx->X ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->Vi, 1 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->Vf, 1 ) ); + + return( 0 ); + } + + /* + * Ok, we need blinding. Can we re-use existing values? + * If yes, just update them by squaring them. + */ + if( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) != 0 ) + { + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->P ) ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->P ) ); + + return( 0 ); + } + + /* + * We need to generate blinding values from scratch + */ + + /* Vi = random( 2, P-1 ) */ + count = 0; + do + { + mbedtls_mpi_fill_random( &ctx->Vi, mbedtls_mpi_size( &ctx->P ), f_rng, p_rng ); + + while( mbedtls_mpi_cmp_mpi( &ctx->Vi, &ctx->P ) >= 0 ) + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &ctx->Vi, 1 ) ); + + if( count++ > 10 ) + return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE ); + } + while( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) <= 0 ); + + /* Vf = Vi^-X mod P */ + MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->Vf, &ctx->Vi, &ctx->P ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->Vf, &ctx->Vf, &ctx->X, &ctx->P, &ctx->RP ) ); + +cleanup: + return( ret ); +} + +/* + * Derive and export the shared secret (G^Y)^X mod P + */ +int mbedtls_dhm_calc_secret( mbedtls_dhm_context *ctx, + unsigned char *output, size_t output_size, size_t *olen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + mbedtls_mpi GYb; + + if( ctx == NULL || output_size < ctx->len ) + return( MBEDTLS_ERR_DHM_BAD_INPUT_DATA ); + + if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 ) + return( ret ); + + mbedtls_mpi_init( &GYb ); + + /* Blind peer's value */ + if( f_rng != NULL ) + { + MBEDTLS_MPI_CHK( dhm_update_blinding( ctx, f_rng, p_rng ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &GYb, &ctx->GY, &ctx->Vi ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &GYb, &GYb, &ctx->P ) ); + } + else + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &GYb, &ctx->GY ) ); + + /* Do modular exponentiation */ + MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->K, &GYb, &ctx->X, + &ctx->P, &ctx->RP ) ); + + /* Unblind secret value */ + if( f_rng != NULL ) + { + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->K, &ctx->K, &ctx->Vf ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->K, &ctx->K, &ctx->P ) ); + } + + *olen = mbedtls_mpi_size( &ctx->K ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &ctx->K, output, *olen ) ); + +cleanup: + mbedtls_mpi_free( &GYb ); + + if( ret != 0 ) + return( MBEDTLS_ERR_DHM_CALC_SECRET_FAILED + ret ); + + return( 0 ); +} + +/* + * Free the components of a DHM key + */ +void mbedtls_dhm_free( mbedtls_dhm_context *ctx ) +{ + mbedtls_mpi_free( &ctx->pX); mbedtls_mpi_free( &ctx->Vf ); mbedtls_mpi_free( &ctx->Vi ); + mbedtls_mpi_free( &ctx->RP ); mbedtls_mpi_free( &ctx->K ); mbedtls_mpi_free( &ctx->GY ); + mbedtls_mpi_free( &ctx->GX ); mbedtls_mpi_free( &ctx->X ); mbedtls_mpi_free( &ctx->G ); + mbedtls_mpi_free( &ctx->P ); + + mbedtls_zeroize( ctx, sizeof( mbedtls_dhm_context ) ); +} + +#if defined(MBEDTLS_ASN1_PARSE_C) +/* + * Parse DHM parameters + */ +int mbedtls_dhm_parse_dhm( mbedtls_dhm_context *dhm, const unsigned char *dhmin, + size_t dhminlen ) +{ + int ret; + size_t len; + unsigned char *p, *end; +#if defined(MBEDTLS_PEM_PARSE_C) + mbedtls_pem_context pem; + + mbedtls_pem_init( &pem ); + + /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ + if( dhminlen == 0 || dhmin[dhminlen - 1] != '\0' ) + ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; + else + ret = mbedtls_pem_read_buffer( &pem, + "-----BEGIN DH PARAMETERS-----", + "-----END DH PARAMETERS-----", + dhmin, NULL, 0, &dhminlen ); + + if( ret == 0 ) + { + /* + * Was PEM encoded + */ + dhminlen = pem.buflen; + } + else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) + goto exit; + + p = ( ret == 0 ) ? pem.buf : (unsigned char *) dhmin; +#else + p = (unsigned char *) dhmin; +#endif /* MBEDTLS_PEM_PARSE_C */ + end = p + dhminlen; + + /* + * DHParams ::= SEQUENCE { + * prime INTEGER, -- P + * generator INTEGER, -- g + * privateValueLength INTEGER OPTIONAL + * } + */ + if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) + { + ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + ret; + goto exit; + } + + end = p + len; + + if( ( ret = mbedtls_asn1_get_mpi( &p, end, &dhm->P ) ) != 0 || + ( ret = mbedtls_asn1_get_mpi( &p, end, &dhm->G ) ) != 0 ) + { + ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + ret; + goto exit; + } + + if( p != end ) + { + /* This might be the optional privateValueLength. + * If so, we can cleanly discard it */ + mbedtls_mpi rec; + mbedtls_mpi_init( &rec ); + ret = mbedtls_asn1_get_mpi( &p, end, &rec ); + mbedtls_mpi_free( &rec ); + if ( ret != 0 ) + { + ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + ret; + goto exit; + } + if ( p != end ) + { + ret = MBEDTLS_ERR_DHM_INVALID_FORMAT + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH; + goto exit; + } + } + + ret = 0; + + dhm->len = mbedtls_mpi_size( &dhm->P ); + +exit: +#if defined(MBEDTLS_PEM_PARSE_C) + mbedtls_pem_free( &pem ); +#endif + if( ret != 0 ) + mbedtls_dhm_free( dhm ); + + return( ret ); +} + +#if defined(MBEDTLS_FS_IO) +/* + * Load all data from a file into a given buffer. + * + * The file is expected to contain either PEM or DER encoded data. + * A terminating null byte is always appended. It is included in the announced + * length only if the data looks like it is PEM encoded. + */ +static int load_file( const char *path, unsigned char **buf, size_t *n ) +{ + FILE *f; + long size; + + if( ( f = fopen( path, "rb" ) ) == NULL ) + return( MBEDTLS_ERR_DHM_FILE_IO_ERROR ); + + fseek( f, 0, SEEK_END ); + if( ( size = ftell( f ) ) == -1 ) + { + fclose( f ); + return( MBEDTLS_ERR_DHM_FILE_IO_ERROR ); + } + fseek( f, 0, SEEK_SET ); + + *n = (size_t) size; + + if( *n + 1 == 0 || + ( *buf = mbedtls_calloc( 1, *n + 1 ) ) == NULL ) + { + fclose( f ); + return( MBEDTLS_ERR_DHM_ALLOC_FAILED ); + } + + if( fread( *buf, 1, *n, f ) != *n ) + { + fclose( f ); + mbedtls_free( *buf ); + return( MBEDTLS_ERR_DHM_FILE_IO_ERROR ); + } + + fclose( f ); + + (*buf)[*n] = '\0'; + + if( strstr( (const char *) *buf, "-----BEGIN " ) != NULL ) + ++*n; + + return( 0 ); +} + +/* + * Load and parse DHM parameters + */ +int mbedtls_dhm_parse_dhmfile( mbedtls_dhm_context *dhm, const char *path ) +{ + int ret; + size_t n; + unsigned char *buf; + + if( ( ret = load_file( path, &buf, &n ) ) != 0 ) + return( ret ); + + ret = mbedtls_dhm_parse_dhm( dhm, buf, n ); + + mbedtls_zeroize( buf, n ); + mbedtls_free( buf ); + + return( ret ); +} +#endif /* MBEDTLS_FS_IO */ +#endif /* MBEDTLS_ASN1_PARSE_C */ + +#if defined(MBEDTLS_SELF_TEST) + +static const char mbedtls_test_dhm_params[] = +"-----BEGIN DH PARAMETERS-----\r\n" +"MIGHAoGBAJ419DBEOgmQTzo5qXl5fQcN9TN455wkOL7052HzxxRVMyhYmwQcgJvh\r\n" +"1sa18fyfR9OiVEMYglOpkqVoGLN7qd5aQNNi5W7/C+VBdHTBJcGZJyyP5B3qcz32\r\n" +"9mLJKudlVudV0Qxk5qUJaPZ/xupz0NyoVpviuiBOI1gNi8ovSXWzAgEC\r\n" +"-----END DH PARAMETERS-----\r\n"; + +static const size_t mbedtls_test_dhm_params_len = sizeof( mbedtls_test_dhm_params ); + +/* + * Checkup routine + */ +int mbedtls_dhm_self_test( int verbose ) +{ + int ret; + mbedtls_dhm_context dhm; + + mbedtls_dhm_init( &dhm ); + + if( verbose != 0 ) + mbedtls_printf( " DHM parameter load: " ); + + if( ( ret = mbedtls_dhm_parse_dhm( &dhm, + (const unsigned char *) mbedtls_test_dhm_params, + mbedtls_test_dhm_params_len ) ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + ret = 1; + goto exit; + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n\n" ); + +exit: + mbedtls_dhm_free( &dhm ); + + return( ret ); +} + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_DHM_C */ diff --git a/security/mbedtls/src/ecdh.c b/security/mbedtls/src/ecdh.c new file mode 100644 index 0000000000..c0a8147312 --- /dev/null +++ b/security/mbedtls/src/ecdh.c @@ -0,0 +1,264 @@ +/* + * Elliptic curve Diffie-Hellman + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +/* + * References: + * + * SEC1 http://www.secg.org/index.php?action=secg,docs_secg + * RFC 4492 + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_ECDH_C) + +#include "mbedtls/ecdh.h" + +#include + +/* + * Generate public key: simple wrapper around mbedtls_ecp_gen_keypair + */ +int mbedtls_ecdh_gen_public( mbedtls_ecp_group *grp, mbedtls_mpi *d, mbedtls_ecp_point *Q, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + return mbedtls_ecp_gen_keypair( grp, d, Q, f_rng, p_rng ); +} + +/* + * Compute shared secret (SEC1 3.3.1) + */ +int mbedtls_ecdh_compute_shared( mbedtls_ecp_group *grp, mbedtls_mpi *z, + const mbedtls_ecp_point *Q, const mbedtls_mpi *d, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + mbedtls_ecp_point P; + + mbedtls_ecp_point_init( &P ); + + /* + * Make sure Q is a valid pubkey before using it + */ + MBEDTLS_MPI_CHK( mbedtls_ecp_check_pubkey( grp, Q ) ); + + MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, &P, d, Q, f_rng, p_rng ) ); + + if( mbedtls_ecp_is_zero( &P ) ) + { + ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + goto cleanup; + } + + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( z, &P.X ) ); + +cleanup: + mbedtls_ecp_point_free( &P ); + + return( ret ); +} + +/* + * Initialize context + */ +void mbedtls_ecdh_init( mbedtls_ecdh_context *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_ecdh_context ) ); +} + +/* + * Free context + */ +void mbedtls_ecdh_free( mbedtls_ecdh_context *ctx ) +{ + if( ctx == NULL ) + return; + + mbedtls_ecp_group_free( &ctx->grp ); + mbedtls_ecp_point_free( &ctx->Q ); + mbedtls_ecp_point_free( &ctx->Qp ); + mbedtls_ecp_point_free( &ctx->Vi ); + mbedtls_ecp_point_free( &ctx->Vf ); + mbedtls_mpi_free( &ctx->d ); + mbedtls_mpi_free( &ctx->z ); + mbedtls_mpi_free( &ctx->_d ); +} + +/* + * Setup and write the ServerKeyExhange parameters (RFC 4492) + * struct { + * ECParameters curve_params; + * ECPoint public; + * } ServerECDHParams; + */ +int mbedtls_ecdh_make_params( mbedtls_ecdh_context *ctx, size_t *olen, + unsigned char *buf, size_t blen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + size_t grp_len, pt_len; + + if( ctx == NULL || ctx->grp.pbits == 0 ) + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + + if( ( ret = mbedtls_ecdh_gen_public( &ctx->grp, &ctx->d, &ctx->Q, f_rng, p_rng ) ) + != 0 ) + return( ret ); + + if( ( ret = mbedtls_ecp_tls_write_group( &ctx->grp, &grp_len, buf, blen ) ) + != 0 ) + return( ret ); + + buf += grp_len; + blen -= grp_len; + + if( ( ret = mbedtls_ecp_tls_write_point( &ctx->grp, &ctx->Q, ctx->point_format, + &pt_len, buf, blen ) ) != 0 ) + return( ret ); + + *olen = grp_len + pt_len; + return( 0 ); +} + +/* + * Read the ServerKeyExhange parameters (RFC 4492) + * struct { + * ECParameters curve_params; + * ECPoint public; + * } ServerECDHParams; + */ +int mbedtls_ecdh_read_params( mbedtls_ecdh_context *ctx, + const unsigned char **buf, const unsigned char *end ) +{ + int ret; + + if( ( ret = mbedtls_ecp_tls_read_group( &ctx->grp, buf, end - *buf ) ) != 0 ) + return( ret ); + + if( ( ret = mbedtls_ecp_tls_read_point( &ctx->grp, &ctx->Qp, buf, end - *buf ) ) + != 0 ) + return( ret ); + + return( 0 ); +} + +/* + * Get parameters from a keypair + */ +int mbedtls_ecdh_get_params( mbedtls_ecdh_context *ctx, const mbedtls_ecp_keypair *key, + mbedtls_ecdh_side side ) +{ + int ret; + + if( ( ret = mbedtls_ecp_group_copy( &ctx->grp, &key->grp ) ) != 0 ) + return( ret ); + + /* If it's not our key, just import the public part as Qp */ + if( side == MBEDTLS_ECDH_THEIRS ) + return( mbedtls_ecp_copy( &ctx->Qp, &key->Q ) ); + + /* Our key: import public (as Q) and private parts */ + if( side != MBEDTLS_ECDH_OURS ) + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + + if( ( ret = mbedtls_ecp_copy( &ctx->Q, &key->Q ) ) != 0 || + ( ret = mbedtls_mpi_copy( &ctx->d, &key->d ) ) != 0 ) + return( ret ); + + return( 0 ); +} + +/* + * Setup and export the client public value + */ +int mbedtls_ecdh_make_public( mbedtls_ecdh_context *ctx, size_t *olen, + unsigned char *buf, size_t blen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + + if( ctx == NULL || ctx->grp.pbits == 0 ) + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + + if( ( ret = mbedtls_ecdh_gen_public( &ctx->grp, &ctx->d, &ctx->Q, f_rng, p_rng ) ) + != 0 ) + return( ret ); + + return mbedtls_ecp_tls_write_point( &ctx->grp, &ctx->Q, ctx->point_format, + olen, buf, blen ); +} + +/* + * Parse and import the client's public value + */ +int mbedtls_ecdh_read_public( mbedtls_ecdh_context *ctx, + const unsigned char *buf, size_t blen ) +{ + int ret; + const unsigned char *p = buf; + + if( ctx == NULL ) + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + + if( ( ret = mbedtls_ecp_tls_read_point( &ctx->grp, &ctx->Qp, &p, blen ) ) != 0 ) + return( ret ); + + if( (size_t)( p - buf ) != blen ) + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + + return( 0 ); +} + +/* + * Derive and export the shared secret + */ +int mbedtls_ecdh_calc_secret( mbedtls_ecdh_context *ctx, size_t *olen, + unsigned char *buf, size_t blen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + + if( ctx == NULL ) + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + + if( ( ret = mbedtls_ecdh_compute_shared( &ctx->grp, &ctx->z, &ctx->Qp, &ctx->d, + f_rng, p_rng ) ) != 0 ) + { + return( ret ); + } + + if( mbedtls_mpi_size( &ctx->z ) > blen ) + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + + *olen = ctx->grp.pbits / 8 + ( ( ctx->grp.pbits % 8 ) != 0 ); + return mbedtls_mpi_write_binary( &ctx->z, buf, *olen ); +} + +#endif /* MBEDTLS_ECDH_C */ diff --git a/security/mbedtls/src/ecdsa.c b/security/mbedtls/src/ecdsa.c new file mode 100644 index 0000000000..4156f3c3c4 --- /dev/null +++ b/security/mbedtls/src/ecdsa.c @@ -0,0 +1,448 @@ +/* + * Elliptic curve DSA + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +/* + * References: + * + * SEC1 http://www.secg.org/index.php?action=secg,docs_secg + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_ECDSA_C) + +#include "mbedtls/ecdsa.h" +#include "mbedtls/asn1write.h" + +#include + +#if defined(MBEDTLS_ECDSA_DETERMINISTIC) +#include "mbedtls/hmac_drbg.h" +#endif + +/* + * Derive a suitable integer for group grp from a buffer of length len + * SEC1 4.1.3 step 5 aka SEC1 4.1.4 step 3 + */ +static int derive_mpi( const mbedtls_ecp_group *grp, mbedtls_mpi *x, + const unsigned char *buf, size_t blen ) +{ + int ret; + size_t n_size = ( grp->nbits + 7 ) / 8; + size_t use_size = blen > n_size ? n_size : blen; + + MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( x, buf, use_size ) ); + if( use_size * 8 > grp->nbits ) + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( x, use_size * 8 - grp->nbits ) ); + + /* While at it, reduce modulo N */ + if( mbedtls_mpi_cmp_mpi( x, &grp->N ) >= 0 ) + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( x, x, &grp->N ) ); + +cleanup: + return( ret ); +} + +/* + * Compute ECDSA signature of a hashed message (SEC1 4.1.3) + * Obviously, compared to SEC1 4.1.3, we skip step 4 (hash message) + */ +int mbedtls_ecdsa_sign( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s, + const mbedtls_mpi *d, const unsigned char *buf, size_t blen, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + int ret, key_tries, sign_tries, blind_tries; + mbedtls_ecp_point R; + mbedtls_mpi k, e, t; + + /* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */ + if( grp->N.p == NULL ) + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + + mbedtls_ecp_point_init( &R ); + mbedtls_mpi_init( &k ); mbedtls_mpi_init( &e ); mbedtls_mpi_init( &t ); + + sign_tries = 0; + do + { + /* + * Steps 1-3: generate a suitable ephemeral keypair + * and set r = xR mod n + */ + key_tries = 0; + do + { + MBEDTLS_MPI_CHK( mbedtls_ecp_gen_keypair( grp, &k, &R, f_rng, p_rng ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( r, &R.X, &grp->N ) ); + + if( key_tries++ > 10 ) + { + ret = MBEDTLS_ERR_ECP_RANDOM_FAILED; + goto cleanup; + } + } + while( mbedtls_mpi_cmp_int( r, 0 ) == 0 ); + + /* + * Step 5: derive MPI from hashed message + */ + MBEDTLS_MPI_CHK( derive_mpi( grp, &e, buf, blen ) ); + + /* + * Generate a random value to blind inv_mod in next step, + * avoiding a potential timing leak. + */ + blind_tries = 0; + do + { + size_t n_size = ( grp->nbits + 7 ) / 8; + MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &t, n_size, f_rng, p_rng ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &t, 8 * n_size - grp->nbits ) ); + + /* See mbedtls_ecp_gen_keypair() */ + if( ++blind_tries > 30 ) + return( MBEDTLS_ERR_ECP_RANDOM_FAILED ); + } + while( mbedtls_mpi_cmp_int( &t, 1 ) < 0 || + mbedtls_mpi_cmp_mpi( &t, &grp->N ) >= 0 ); + + /* + * Step 6: compute s = (e + r * d) / k = t (e + rd) / (kt) mod n + */ + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( s, r, d ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &e, &e, s ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &e, &e, &t ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &k, &k, &t ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( s, &k, &grp->N ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( s, s, &e ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( s, s, &grp->N ) ); + + if( sign_tries++ > 10 ) + { + ret = MBEDTLS_ERR_ECP_RANDOM_FAILED; + goto cleanup; + } + } + while( mbedtls_mpi_cmp_int( s, 0 ) == 0 ); + +cleanup: + mbedtls_ecp_point_free( &R ); + mbedtls_mpi_free( &k ); mbedtls_mpi_free( &e ); mbedtls_mpi_free( &t ); + + return( ret ); +} + +#if defined(MBEDTLS_ECDSA_DETERMINISTIC) +/* + * Deterministic signature wrapper + */ +int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s, + const mbedtls_mpi *d, const unsigned char *buf, size_t blen, + mbedtls_md_type_t md_alg ) +{ + int ret; + mbedtls_hmac_drbg_context rng_ctx; + unsigned char data[2 * MBEDTLS_ECP_MAX_BYTES]; + size_t grp_len = ( grp->nbits + 7 ) / 8; + const mbedtls_md_info_t *md_info; + mbedtls_mpi h; + + if( ( md_info = mbedtls_md_info_from_type( md_alg ) ) == NULL ) + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + + mbedtls_mpi_init( &h ); + mbedtls_hmac_drbg_init( &rng_ctx ); + + /* Use private key and message hash (reduced) to initialize HMAC_DRBG */ + MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( d, data, grp_len ) ); + MBEDTLS_MPI_CHK( derive_mpi( grp, &h, buf, blen ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &h, data + grp_len, grp_len ) ); + mbedtls_hmac_drbg_seed_buf( &rng_ctx, md_info, data, 2 * grp_len ); + + ret = mbedtls_ecdsa_sign( grp, r, s, d, buf, blen, + mbedtls_hmac_drbg_random, &rng_ctx ); + +cleanup: + mbedtls_hmac_drbg_free( &rng_ctx ); + mbedtls_mpi_free( &h ); + + return( ret ); +} +#endif /* MBEDTLS_ECDSA_DETERMINISTIC */ + +/* + * Verify ECDSA signature of hashed message (SEC1 4.1.4) + * Obviously, compared to SEC1 4.1.3, we skip step 2 (hash message) + */ +int mbedtls_ecdsa_verify( mbedtls_ecp_group *grp, + const unsigned char *buf, size_t blen, + const mbedtls_ecp_point *Q, const mbedtls_mpi *r, const mbedtls_mpi *s) +{ + int ret; + mbedtls_mpi e, s_inv, u1, u2; + mbedtls_ecp_point R; + + mbedtls_ecp_point_init( &R ); + mbedtls_mpi_init( &e ); mbedtls_mpi_init( &s_inv ); mbedtls_mpi_init( &u1 ); mbedtls_mpi_init( &u2 ); + + /* Fail cleanly on curves such as Curve25519 that can't be used for ECDSA */ + if( grp->N.p == NULL ) + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + + /* + * Step 1: make sure r and s are in range 1..n-1 + */ + if( mbedtls_mpi_cmp_int( r, 1 ) < 0 || mbedtls_mpi_cmp_mpi( r, &grp->N ) >= 0 || + mbedtls_mpi_cmp_int( s, 1 ) < 0 || mbedtls_mpi_cmp_mpi( s, &grp->N ) >= 0 ) + { + ret = MBEDTLS_ERR_ECP_VERIFY_FAILED; + goto cleanup; + } + + /* + * Additional precaution: make sure Q is valid + */ + MBEDTLS_MPI_CHK( mbedtls_ecp_check_pubkey( grp, Q ) ); + + /* + * Step 3: derive MPI from hashed message + */ + MBEDTLS_MPI_CHK( derive_mpi( grp, &e, buf, blen ) ); + + /* + * Step 4: u1 = e / s mod n, u2 = r / s mod n + */ + MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &s_inv, s, &grp->N ) ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &u1, &e, &s_inv ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &u1, &u1, &grp->N ) ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &u2, r, &s_inv ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &u2, &u2, &grp->N ) ); + + /* + * Step 5: R = u1 G + u2 Q + * + * Since we're not using any secret data, no need to pass a RNG to + * mbedtls_ecp_mul() for countermesures. + */ + MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( grp, &R, &u1, &grp->G, &u2, Q ) ); + + if( mbedtls_ecp_is_zero( &R ) ) + { + ret = MBEDTLS_ERR_ECP_VERIFY_FAILED; + goto cleanup; + } + + /* + * Step 6: convert xR to an integer (no-op) + * Step 7: reduce xR mod n (gives v) + */ + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &R.X, &R.X, &grp->N ) ); + + /* + * Step 8: check if v (that is, R.X) is equal to r + */ + if( mbedtls_mpi_cmp_mpi( &R.X, r ) != 0 ) + { + ret = MBEDTLS_ERR_ECP_VERIFY_FAILED; + goto cleanup; + } + +cleanup: + mbedtls_ecp_point_free( &R ); + mbedtls_mpi_free( &e ); mbedtls_mpi_free( &s_inv ); mbedtls_mpi_free( &u1 ); mbedtls_mpi_free( &u2 ); + + return( ret ); +} + +/* + * Convert a signature (given by context) to ASN.1 + */ +static int ecdsa_signature_to_asn1( const mbedtls_mpi *r, const mbedtls_mpi *s, + unsigned char *sig, size_t *slen ) +{ + int ret; + unsigned char buf[MBEDTLS_ECDSA_MAX_LEN]; + unsigned char *p = buf + sizeof( buf ); + size_t len = 0; + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &p, buf, s ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &p, buf, r ) ); + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &p, buf, len ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &p, buf, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ); + + memcpy( sig, p, len ); + *slen = len; + + return( 0 ); +} + +/* + * Compute and write signature + */ +int mbedtls_ecdsa_write_signature( mbedtls_ecdsa_context *ctx, mbedtls_md_type_t md_alg, + const unsigned char *hash, size_t hlen, + unsigned char *sig, size_t *slen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + mbedtls_mpi r, s; + + mbedtls_mpi_init( &r ); + mbedtls_mpi_init( &s ); + +#if defined(MBEDTLS_ECDSA_DETERMINISTIC) + (void) f_rng; + (void) p_rng; + + MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign_det( &ctx->grp, &r, &s, &ctx->d, + hash, hlen, md_alg ) ); +#else + (void) md_alg; + + MBEDTLS_MPI_CHK( mbedtls_ecdsa_sign( &ctx->grp, &r, &s, &ctx->d, + hash, hlen, f_rng, p_rng ) ); +#endif + + MBEDTLS_MPI_CHK( ecdsa_signature_to_asn1( &r, &s, sig, slen ) ); + +cleanup: + mbedtls_mpi_free( &r ); + mbedtls_mpi_free( &s ); + + return( ret ); +} + +#if ! defined(MBEDTLS_DEPRECATED_REMOVED) && \ + defined(MBEDTLS_ECDSA_DETERMINISTIC) +int mbedtls_ecdsa_write_signature_det( mbedtls_ecdsa_context *ctx, + const unsigned char *hash, size_t hlen, + unsigned char *sig, size_t *slen, + mbedtls_md_type_t md_alg ) +{ + return( mbedtls_ecdsa_write_signature( ctx, md_alg, hash, hlen, sig, slen, + NULL, NULL ) ); +} +#endif + +/* + * Read and check signature + */ +int mbedtls_ecdsa_read_signature( mbedtls_ecdsa_context *ctx, + const unsigned char *hash, size_t hlen, + const unsigned char *sig, size_t slen ) +{ + int ret; + unsigned char *p = (unsigned char *) sig; + const unsigned char *end = sig + slen; + size_t len; + mbedtls_mpi r, s; + + mbedtls_mpi_init( &r ); + mbedtls_mpi_init( &s ); + + if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) + { + ret += MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + goto cleanup; + } + + if( p + len != end ) + { + ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH; + goto cleanup; + } + + if( ( ret = mbedtls_asn1_get_mpi( &p, end, &r ) ) != 0 || + ( ret = mbedtls_asn1_get_mpi( &p, end, &s ) ) != 0 ) + { + ret += MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + goto cleanup; + } + + if( ( ret = mbedtls_ecdsa_verify( &ctx->grp, hash, hlen, + &ctx->Q, &r, &s ) ) != 0 ) + goto cleanup; + + if( p != end ) + ret = MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH; + +cleanup: + mbedtls_mpi_free( &r ); + mbedtls_mpi_free( &s ); + + return( ret ); +} + +/* + * Generate key pair + */ +int mbedtls_ecdsa_genkey( mbedtls_ecdsa_context *ctx, mbedtls_ecp_group_id gid, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + return( mbedtls_ecp_group_load( &ctx->grp, gid ) || + mbedtls_ecp_gen_keypair( &ctx->grp, &ctx->d, &ctx->Q, f_rng, p_rng ) ); +} + +/* + * Set context from an mbedtls_ecp_keypair + */ +int mbedtls_ecdsa_from_keypair( mbedtls_ecdsa_context *ctx, const mbedtls_ecp_keypair *key ) +{ + int ret; + + if( ( ret = mbedtls_ecp_group_copy( &ctx->grp, &key->grp ) ) != 0 || + ( ret = mbedtls_mpi_copy( &ctx->d, &key->d ) ) != 0 || + ( ret = mbedtls_ecp_copy( &ctx->Q, &key->Q ) ) != 0 ) + { + mbedtls_ecdsa_free( ctx ); + } + + return( ret ); +} + +/* + * Initialize context + */ +void mbedtls_ecdsa_init( mbedtls_ecdsa_context *ctx ) +{ + mbedtls_ecp_keypair_init( ctx ); +} + +/* + * Free context + */ +void mbedtls_ecdsa_free( mbedtls_ecdsa_context *ctx ) +{ + mbedtls_ecp_keypair_free( ctx ); +} + +#endif /* MBEDTLS_ECDSA_C */ diff --git a/security/mbedtls/src/ecjpake.c b/security/mbedtls/src/ecjpake.c new file mode 100644 index 0000000000..1fa1c2d801 --- /dev/null +++ b/security/mbedtls/src/ecjpake.c @@ -0,0 +1,1103 @@ +/* + * Elliptic curve J-PAKE + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +/* + * References in the code are to the Thread v1.0 Specification, + * available to members of the Thread Group http://threadgroup.org/ + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_ECJPAKE_C) + +#include "mbedtls/ecjpake.h" + +#include + +/* + * Convert a mbedtls_ecjpake_role to identifier string + */ +static const char * const ecjpake_id[] = { + "client", + "server" +}; + +#define ID_MINE ( ecjpake_id[ ctx->role ] ) +#define ID_PEER ( ecjpake_id[ 1 - ctx->role ] ) + +/* + * Initialize context + */ +void mbedtls_ecjpake_init( mbedtls_ecjpake_context *ctx ) +{ + if( ctx == NULL ) + return; + + ctx->md_info = NULL; + mbedtls_ecp_group_init( &ctx->grp ); + ctx->point_format = MBEDTLS_ECP_PF_UNCOMPRESSED; + + mbedtls_ecp_point_init( &ctx->Xm1 ); + mbedtls_ecp_point_init( &ctx->Xm2 ); + mbedtls_ecp_point_init( &ctx->Xp1 ); + mbedtls_ecp_point_init( &ctx->Xp2 ); + mbedtls_ecp_point_init( &ctx->Xp ); + + mbedtls_mpi_init( &ctx->xm1 ); + mbedtls_mpi_init( &ctx->xm2 ); + mbedtls_mpi_init( &ctx->s ); +} + +/* + * Free context + */ +void mbedtls_ecjpake_free( mbedtls_ecjpake_context *ctx ) +{ + if( ctx == NULL ) + return; + + ctx->md_info = NULL; + mbedtls_ecp_group_free( &ctx->grp ); + + mbedtls_ecp_point_free( &ctx->Xm1 ); + mbedtls_ecp_point_free( &ctx->Xm2 ); + mbedtls_ecp_point_free( &ctx->Xp1 ); + mbedtls_ecp_point_free( &ctx->Xp2 ); + mbedtls_ecp_point_free( &ctx->Xp ); + + mbedtls_mpi_free( &ctx->xm1 ); + mbedtls_mpi_free( &ctx->xm2 ); + mbedtls_mpi_free( &ctx->s ); +} + +/* + * Setup context + */ +int mbedtls_ecjpake_setup( mbedtls_ecjpake_context *ctx, + mbedtls_ecjpake_role role, + mbedtls_md_type_t hash, + mbedtls_ecp_group_id curve, + const unsigned char *secret, + size_t len ) +{ + int ret; + + ctx->role = role; + + if( ( ctx->md_info = mbedtls_md_info_from_type( hash ) ) == NULL ) + return( MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE ); + + MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &ctx->grp, curve ) ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->s, secret, len ) ); + +cleanup: + if( ret != 0 ) + mbedtls_ecjpake_free( ctx ); + + return( ret ); +} + +/* + * Check if context is ready for use + */ +int mbedtls_ecjpake_check( const mbedtls_ecjpake_context *ctx ) +{ + if( ctx->md_info == NULL || + ctx->grp.id == MBEDTLS_ECP_DP_NONE || + ctx->s.p == NULL ) + { + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + } + + return( 0 ); +} + +/* + * Write a point plus its length to a buffer + */ +static int ecjpake_write_len_point( unsigned char **p, + const unsigned char *end, + const mbedtls_ecp_group *grp, + const int pf, + const mbedtls_ecp_point *P ) +{ + int ret; + size_t len; + + /* Need at least 4 for length plus 1 for point */ + if( end < *p || end - *p < 5 ) + return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); + + ret = mbedtls_ecp_point_write_binary( grp, P, pf, + &len, *p + 4, end - ( *p + 4 ) ); + if( ret != 0 ) + return( ret ); + + (*p)[0] = (unsigned char)( ( len >> 24 ) & 0xFF ); + (*p)[1] = (unsigned char)( ( len >> 16 ) & 0xFF ); + (*p)[2] = (unsigned char)( ( len >> 8 ) & 0xFF ); + (*p)[3] = (unsigned char)( ( len ) & 0xFF ); + + *p += 4 + len; + + return( 0 ); +} + +/* + * Size of the temporary buffer for ecjpake_hash: + * 3 EC points plus their length, plus ID and its length (4 + 6 bytes) + */ +#define ECJPAKE_HASH_BUF_LEN ( 3 * ( 4 + MBEDTLS_ECP_MAX_PT_LEN ) + 4 + 6 ) + +/* + * Compute hash for ZKP (7.4.2.2.2.1) + */ +static int ecjpake_hash( const mbedtls_md_info_t *md_info, + const mbedtls_ecp_group *grp, + const int pf, + const mbedtls_ecp_point *G, + const mbedtls_ecp_point *V, + const mbedtls_ecp_point *X, + const char *id, + mbedtls_mpi *h ) +{ + int ret; + unsigned char buf[ECJPAKE_HASH_BUF_LEN]; + unsigned char *p = buf; + const unsigned char *end = buf + sizeof( buf ); + const size_t id_len = strlen( id ); + unsigned char hash[MBEDTLS_MD_MAX_SIZE]; + + /* Write things to temporary buffer */ + MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p, end, grp, pf, G ) ); + MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p, end, grp, pf, V ) ); + MBEDTLS_MPI_CHK( ecjpake_write_len_point( &p, end, grp, pf, X ) ); + + if( end - p < 4 ) + return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); + + *p++ = (unsigned char)( ( id_len >> 24 ) & 0xFF ); + *p++ = (unsigned char)( ( id_len >> 16 ) & 0xFF ); + *p++ = (unsigned char)( ( id_len >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( id_len ) & 0xFF ); + + if( end < p || (size_t)( end - p ) < id_len ) + return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); + + memcpy( p, id, id_len ); + p += id_len; + + /* Compute hash */ + mbedtls_md( md_info, buf, p - buf, hash ); + + /* Turn it into an integer mod n */ + MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( h, hash, + mbedtls_md_get_size( md_info ) ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( h, h, &grp->N ) ); + +cleanup: + return( ret ); +} + +/* + * Parse a ECShnorrZKP (7.4.2.2.2) and verify it (7.4.2.3.3) + */ +static int ecjpake_zkp_read( const mbedtls_md_info_t *md_info, + const mbedtls_ecp_group *grp, + const int pf, + const mbedtls_ecp_point *G, + const mbedtls_ecp_point *X, + const char *id, + const unsigned char **p, + const unsigned char *end ) +{ + int ret; + mbedtls_ecp_point V, VV; + mbedtls_mpi r, h; + size_t r_len; + + mbedtls_ecp_point_init( &V ); + mbedtls_ecp_point_init( &VV ); + mbedtls_mpi_init( &r ); + mbedtls_mpi_init( &h ); + + /* + * struct { + * ECPoint V; + * opaque r<1..2^8-1>; + * } ECSchnorrZKP; + */ + if( end < *p ) + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + + MBEDTLS_MPI_CHK( mbedtls_ecp_tls_read_point( grp, &V, p, end - *p ) ); + + if( end < *p || (size_t)( end - *p ) < 1 ) + { + ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + goto cleanup; + } + + r_len = *(*p)++; + + if( end < *p || (size_t)( end - *p ) < r_len ) + { + ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + goto cleanup; + } + + MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &r, *p, r_len ) ); + *p += r_len; + + /* + * Verification + */ + MBEDTLS_MPI_CHK( ecjpake_hash( md_info, grp, pf, G, &V, X, id, &h ) ); + MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( (mbedtls_ecp_group *) grp, + &VV, &h, X, &r, G ) ); + + if( mbedtls_ecp_point_cmp( &VV, &V ) != 0 ) + { + ret = MBEDTLS_ERR_ECP_VERIFY_FAILED; + goto cleanup; + } + +cleanup: + mbedtls_ecp_point_free( &V ); + mbedtls_ecp_point_free( &VV ); + mbedtls_mpi_free( &r ); + mbedtls_mpi_free( &h ); + + return( ret ); +} + +/* + * Generate ZKP (7.4.2.3.2) and write it as ECSchnorrZKP (7.4.2.2.2) + */ +static int ecjpake_zkp_write( const mbedtls_md_info_t *md_info, + const mbedtls_ecp_group *grp, + const int pf, + const mbedtls_ecp_point *G, + const mbedtls_mpi *x, + const mbedtls_ecp_point *X, + const char *id, + unsigned char **p, + const unsigned char *end, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + mbedtls_ecp_point V; + mbedtls_mpi v; + mbedtls_mpi h; /* later recycled to hold r */ + size_t len; + + if( end < *p ) + return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); + + mbedtls_ecp_point_init( &V ); + mbedtls_mpi_init( &v ); + mbedtls_mpi_init( &h ); + + /* Compute signature */ + MBEDTLS_MPI_CHK( mbedtls_ecp_gen_keypair_base( (mbedtls_ecp_group *) grp, + G, &v, &V, f_rng, p_rng ) ); + MBEDTLS_MPI_CHK( ecjpake_hash( md_info, grp, pf, G, &V, X, id, &h ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &h, &h, x ) ); /* x*h */ + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &h, &v, &h ) ); /* v - x*h */ + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &h, &h, &grp->N ) ); /* r */ + + /* Write it out */ + MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_point( grp, &V, + pf, &len, *p, end - *p ) ); + *p += len; + + len = mbedtls_mpi_size( &h ); /* actually r */ + if( end < *p || (size_t)( end - *p ) < 1 + len || len > 255 ) + { + ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; + goto cleanup; + } + + *(*p)++ = (unsigned char)( len & 0xFF ); + MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &h, *p, len ) ); /* r */ + *p += len; + +cleanup: + mbedtls_ecp_point_free( &V ); + mbedtls_mpi_free( &v ); + mbedtls_mpi_free( &h ); + + return( ret ); +} + +/* + * Parse a ECJPAKEKeyKP (7.4.2.2.1) and check proof + * Output: verified public key X + */ +static int ecjpake_kkp_read( const mbedtls_md_info_t *md_info, + const mbedtls_ecp_group *grp, + const int pf, + const mbedtls_ecp_point *G, + mbedtls_ecp_point *X, + const char *id, + const unsigned char **p, + const unsigned char *end ) +{ + int ret; + + if( end < *p ) + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + + /* + * struct { + * ECPoint X; + * ECSchnorrZKP zkp; + * } ECJPAKEKeyKP; + */ + MBEDTLS_MPI_CHK( mbedtls_ecp_tls_read_point( grp, X, p, end - *p ) ); + if( mbedtls_ecp_is_zero( X ) ) + { + ret = MBEDTLS_ERR_ECP_INVALID_KEY; + goto cleanup; + } + + MBEDTLS_MPI_CHK( ecjpake_zkp_read( md_info, grp, pf, G, X, id, p, end ) ); + +cleanup: + return( ret ); +} + +/* + * Generate an ECJPAKEKeyKP + * Output: the serialized structure, plus private/public key pair + */ +static int ecjpake_kkp_write( const mbedtls_md_info_t *md_info, + const mbedtls_ecp_group *grp, + const int pf, + const mbedtls_ecp_point *G, + mbedtls_mpi *x, + mbedtls_ecp_point *X, + const char *id, + unsigned char **p, + const unsigned char *end, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + size_t len; + + if( end < *p ) + return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); + + /* Generate key (7.4.2.3.1) and write it out */ + MBEDTLS_MPI_CHK( mbedtls_ecp_gen_keypair_base( (mbedtls_ecp_group *) grp, G, x, X, + f_rng, p_rng ) ); + MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_point( grp, X, + pf, &len, *p, end - *p ) ); + *p += len; + + /* Generate and write proof */ + MBEDTLS_MPI_CHK( ecjpake_zkp_write( md_info, grp, pf, G, x, X, id, + p, end, f_rng, p_rng ) ); + +cleanup: + return( ret ); +} + +/* + * Read a ECJPAKEKeyKPPairList (7.4.2.3) and check proofs + * Ouputs: verified peer public keys Xa, Xb + */ +static int ecjpake_kkpp_read( const mbedtls_md_info_t *md_info, + const mbedtls_ecp_group *grp, + const int pf, + const mbedtls_ecp_point *G, + mbedtls_ecp_point *Xa, + mbedtls_ecp_point *Xb, + const char *id, + const unsigned char *buf, + size_t len ) +{ + int ret; + const unsigned char *p = buf; + const unsigned char *end = buf + len; + + /* + * struct { + * ECJPAKEKeyKP ecjpake_key_kp_pair_list[2]; + * } ECJPAKEKeyKPPairList; + */ + MBEDTLS_MPI_CHK( ecjpake_kkp_read( md_info, grp, pf, G, Xa, id, &p, end ) ); + MBEDTLS_MPI_CHK( ecjpake_kkp_read( md_info, grp, pf, G, Xb, id, &p, end ) ); + + if( p != end ) + ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + +cleanup: + return( ret ); +} + +/* + * Generate a ECJPAKEKeyKPPairList + * Outputs: the serialized structure, plus two private/public key pairs + */ +static int ecjpake_kkpp_write( const mbedtls_md_info_t *md_info, + const mbedtls_ecp_group *grp, + const int pf, + const mbedtls_ecp_point *G, + mbedtls_mpi *xm1, + mbedtls_ecp_point *Xa, + mbedtls_mpi *xm2, + mbedtls_ecp_point *Xb, + const char *id, + unsigned char *buf, + size_t len, + size_t *olen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + unsigned char *p = buf; + const unsigned char *end = buf + len; + + MBEDTLS_MPI_CHK( ecjpake_kkp_write( md_info, grp, pf, G, xm1, Xa, id, + &p, end, f_rng, p_rng ) ); + MBEDTLS_MPI_CHK( ecjpake_kkp_write( md_info, grp, pf, G, xm2, Xb, id, + &p, end, f_rng, p_rng ) ); + + *olen = p - buf; + +cleanup: + return( ret ); +} + +/* + * Read and process the first round message + */ +int mbedtls_ecjpake_read_round_one( mbedtls_ecjpake_context *ctx, + const unsigned char *buf, + size_t len ) +{ + return( ecjpake_kkpp_read( ctx->md_info, &ctx->grp, ctx->point_format, + &ctx->grp.G, + &ctx->Xp1, &ctx->Xp2, ID_PEER, + buf, len ) ); +} + +/* + * Generate and write the first round message + */ +int mbedtls_ecjpake_write_round_one( mbedtls_ecjpake_context *ctx, + unsigned char *buf, size_t len, size_t *olen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + return( ecjpake_kkpp_write( ctx->md_info, &ctx->grp, ctx->point_format, + &ctx->grp.G, + &ctx->xm1, &ctx->Xm1, &ctx->xm2, &ctx->Xm2, + ID_MINE, buf, len, olen, f_rng, p_rng ) ); +} + +/* + * Compute the sum of three points R = A + B + C + */ +static int ecjpake_ecp_add3( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, + const mbedtls_ecp_point *A, + const mbedtls_ecp_point *B, + const mbedtls_ecp_point *C ) +{ + int ret; + mbedtls_mpi one; + + mbedtls_mpi_init( &one ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &one, 1 ) ); + MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( grp, R, &one, A, &one, B ) ); + MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( grp, R, &one, R, &one, C ) ); + +cleanup: + mbedtls_mpi_free( &one ); + + return( ret ); +} + +/* + * Read and process second round message (C: 7.4.2.5, S: 7.4.2.6) + */ +int mbedtls_ecjpake_read_round_two( mbedtls_ecjpake_context *ctx, + const unsigned char *buf, + size_t len ) +{ + int ret; + const unsigned char *p = buf; + const unsigned char *end = buf + len; + mbedtls_ecp_group grp; + mbedtls_ecp_point G; /* C: GB, S: GA */ + + mbedtls_ecp_group_init( &grp ); + mbedtls_ecp_point_init( &G ); + + /* + * Server: GA = X3 + X4 + X1 (7.4.2.6.1) + * Client: GB = X1 + X2 + X3 (7.4.2.5.1) + * Unified: G = Xm1 + Xm2 + Xp1 + * We need that before parsing in order to check Xp as we read it + */ + MBEDTLS_MPI_CHK( ecjpake_ecp_add3( &ctx->grp, &G, + &ctx->Xm1, &ctx->Xm2, &ctx->Xp1 ) ); + + /* + * struct { + * ECParameters curve_params; // only client reading server msg + * ECJPAKEKeyKP ecjpake_key_kp; + * } Client/ServerECJPAKEParams; + */ + if( ctx->role == MBEDTLS_ECJPAKE_CLIENT ) + { + MBEDTLS_MPI_CHK( mbedtls_ecp_tls_read_group( &grp, &p, len ) ); + if( grp.id != ctx->grp.id ) + { + ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; + goto cleanup; + } + } + + MBEDTLS_MPI_CHK( ecjpake_kkp_read( ctx->md_info, &ctx->grp, + ctx->point_format, + &G, &ctx->Xp, ID_PEER, &p, end ) ); + + if( p != end ) + { + ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + goto cleanup; + } + +cleanup: + mbedtls_ecp_group_free( &grp ); + mbedtls_ecp_point_free( &G ); + + return( ret ); +} + +/* + * Compute R = +/- X * S mod N, taking care not to leak S + */ +static int ecjpake_mul_secret( mbedtls_mpi *R, int sign, + const mbedtls_mpi *X, + const mbedtls_mpi *S, + const mbedtls_mpi *N, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + mbedtls_mpi b; /* Blinding value, then s + N * blinding */ + + mbedtls_mpi_init( &b ); + + /* b = s + rnd-128-bit * N */ + MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &b, 16, f_rng, p_rng ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &b, &b, N ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &b, &b, S ) ); + + /* R = sign * X * b mod N */ + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( R, X, &b ) ); + R->s *= sign; + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( R, R, N ) ); + +cleanup: + mbedtls_mpi_free( &b ); + + return( ret ); +} + +/* + * Generate and write the second round message (S: 7.4.2.5, C: 7.4.2.6) + */ +int mbedtls_ecjpake_write_round_two( mbedtls_ecjpake_context *ctx, + unsigned char *buf, size_t len, size_t *olen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + mbedtls_ecp_point G; /* C: GA, S: GB */ + mbedtls_ecp_point Xm; /* C: Xc, S: Xs */ + mbedtls_mpi xm; /* C: xc, S: xs */ + unsigned char *p = buf; + const unsigned char *end = buf + len; + size_t ec_len; + + mbedtls_ecp_point_init( &G ); + mbedtls_ecp_point_init( &Xm ); + mbedtls_mpi_init( &xm ); + + /* + * First generate private/public key pair (S: 7.4.2.5.1, C: 7.4.2.6.1) + * + * Client: GA = X1 + X3 + X4 | xs = x2 * s | Xc = xc * GA + * Server: GB = X3 + X1 + X2 | xs = x4 * s | Xs = xs * GB + * Unified: G = Xm1 + Xp1 + Xp2 | xm = xm2 * s | Xm = xm * G + */ + MBEDTLS_MPI_CHK( ecjpake_ecp_add3( &ctx->grp, &G, + &ctx->Xp1, &ctx->Xp2, &ctx->Xm1 ) ); + MBEDTLS_MPI_CHK( ecjpake_mul_secret( &xm, 1, &ctx->xm2, &ctx->s, + &ctx->grp.N, f_rng, p_rng ) ); + MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &Xm, &xm, &G, f_rng, p_rng ) ); + + /* + * Now write things out + * + * struct { + * ECParameters curve_params; // only server writing its message + * ECJPAKEKeyKP ecjpake_key_kp; + * } Client/ServerECJPAKEParams; + */ + if( ctx->role == MBEDTLS_ECJPAKE_SERVER ) + { + if( end < p ) + { + ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; + goto cleanup; + } + MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_group( &ctx->grp, &ec_len, + p, end - p ) ); + p += ec_len; + } + + if( end < p ) + { + ret = MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL; + goto cleanup; + } + MBEDTLS_MPI_CHK( mbedtls_ecp_tls_write_point( &ctx->grp, &Xm, + ctx->point_format, &ec_len, p, end - p ) ); + p += ec_len; + + MBEDTLS_MPI_CHK( ecjpake_zkp_write( ctx->md_info, &ctx->grp, + ctx->point_format, + &G, &xm, &Xm, ID_MINE, + &p, end, f_rng, p_rng ) ); + + *olen = p - buf; + +cleanup: + mbedtls_ecp_point_free( &G ); + mbedtls_ecp_point_free( &Xm ); + mbedtls_mpi_free( &xm ); + + return( ret ); +} + +/* + * Derive PMS (7.4.2.7 / 7.4.2.8) + */ +int mbedtls_ecjpake_derive_secret( mbedtls_ecjpake_context *ctx, + unsigned char *buf, size_t len, size_t *olen, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + mbedtls_ecp_point K; + mbedtls_mpi m_xm2_s, one; + unsigned char kx[MBEDTLS_ECP_MAX_BYTES]; + size_t x_bytes; + + *olen = mbedtls_md_get_size( ctx->md_info ); + if( len < *olen ) + return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); + + mbedtls_ecp_point_init( &K ); + mbedtls_mpi_init( &m_xm2_s ); + mbedtls_mpi_init( &one ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &one, 1 ) ); + + /* + * Client: K = ( Xs - X4 * x2 * s ) * x2 + * Server: K = ( Xc - X2 * x4 * s ) * x4 + * Unified: K = ( Xp - Xp2 * xm2 * s ) * xm2 + */ + MBEDTLS_MPI_CHK( ecjpake_mul_secret( &m_xm2_s, -1, &ctx->xm2, &ctx->s, + &ctx->grp.N, f_rng, p_rng ) ); + MBEDTLS_MPI_CHK( mbedtls_ecp_muladd( &ctx->grp, &K, + &one, &ctx->Xp, + &m_xm2_s, &ctx->Xp2 ) ); + MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &K, &ctx->xm2, &K, + f_rng, p_rng ) ); + + /* PMS = SHA-256( K.X ) */ + x_bytes = ( ctx->grp.pbits + 7 ) / 8; + MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &K.X, kx, x_bytes ) ); + MBEDTLS_MPI_CHK( mbedtls_md( ctx->md_info, kx, x_bytes, buf ) ); + +cleanup: + mbedtls_ecp_point_free( &K ); + mbedtls_mpi_free( &m_xm2_s ); + mbedtls_mpi_free( &one ); + + return( ret ); +} + +#undef ID_MINE +#undef ID_PEER + + +#if defined(MBEDTLS_SELF_TEST) + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_printf printf +#endif + +#if !defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \ + !defined(MBEDTLS_SHA256_C) +int mbedtls_ecjpake_self_test( int verbose ) +{ + (void) verbose; + return( 0 ); +} +#else + +static const unsigned char ecjpake_test_password[] = { + 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x6a, 0x70, 0x61, 0x6b, 0x65, 0x74, + 0x65, 0x73, 0x74 +}; + +static const unsigned char ecjpake_test_x1[] = { + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, + 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x21 +}; + +static const unsigned char ecjpake_test_x2[] = { + 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, + 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, + 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x81 +}; + +static const unsigned char ecjpake_test_x3[] = { + 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, + 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, + 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x81 +}; + +static const unsigned char ecjpake_test_x4[] = { + 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, + 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, + 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe1 +}; + +static const unsigned char ecjpake_test_cli_one[] = { + 0x41, 0x04, 0xac, 0xcf, 0x01, 0x06, 0xef, 0x85, 0x8f, 0xa2, 0xd9, 0x19, + 0x33, 0x13, 0x46, 0x80, 0x5a, 0x78, 0xb5, 0x8b, 0xba, 0xd0, 0xb8, 0x44, + 0xe5, 0xc7, 0x89, 0x28, 0x79, 0x14, 0x61, 0x87, 0xdd, 0x26, 0x66, 0xad, + 0xa7, 0x81, 0xbb, 0x7f, 0x11, 0x13, 0x72, 0x25, 0x1a, 0x89, 0x10, 0x62, + 0x1f, 0x63, 0x4d, 0xf1, 0x28, 0xac, 0x48, 0xe3, 0x81, 0xfd, 0x6e, 0xf9, + 0x06, 0x07, 0x31, 0xf6, 0x94, 0xa4, 0x41, 0x04, 0x1d, 0xd0, 0xbd, 0x5d, + 0x45, 0x66, 0xc9, 0xbe, 0xd9, 0xce, 0x7d, 0xe7, 0x01, 0xb5, 0xe8, 0x2e, + 0x08, 0xe8, 0x4b, 0x73, 0x04, 0x66, 0x01, 0x8a, 0xb9, 0x03, 0xc7, 0x9e, + 0xb9, 0x82, 0x17, 0x22, 0x36, 0xc0, 0xc1, 0x72, 0x8a, 0xe4, 0xbf, 0x73, + 0x61, 0x0d, 0x34, 0xde, 0x44, 0x24, 0x6e, 0xf3, 0xd9, 0xc0, 0x5a, 0x22, + 0x36, 0xfb, 0x66, 0xa6, 0x58, 0x3d, 0x74, 0x49, 0x30, 0x8b, 0xab, 0xce, + 0x20, 0x72, 0xfe, 0x16, 0x66, 0x29, 0x92, 0xe9, 0x23, 0x5c, 0x25, 0x00, + 0x2f, 0x11, 0xb1, 0x50, 0x87, 0xb8, 0x27, 0x38, 0xe0, 0x3c, 0x94, 0x5b, + 0xf7, 0xa2, 0x99, 0x5d, 0xda, 0x1e, 0x98, 0x34, 0x58, 0x41, 0x04, 0x7e, + 0xa6, 0xe3, 0xa4, 0x48, 0x70, 0x37, 0xa9, 0xe0, 0xdb, 0xd7, 0x92, 0x62, + 0xb2, 0xcc, 0x27, 0x3e, 0x77, 0x99, 0x30, 0xfc, 0x18, 0x40, 0x9a, 0xc5, + 0x36, 0x1c, 0x5f, 0xe6, 0x69, 0xd7, 0x02, 0xe1, 0x47, 0x79, 0x0a, 0xeb, + 0x4c, 0xe7, 0xfd, 0x65, 0x75, 0xab, 0x0f, 0x6c, 0x7f, 0xd1, 0xc3, 0x35, + 0x93, 0x9a, 0xa8, 0x63, 0xba, 0x37, 0xec, 0x91, 0xb7, 0xe3, 0x2b, 0xb0, + 0x13, 0xbb, 0x2b, 0x41, 0x04, 0xa4, 0x95, 0x58, 0xd3, 0x2e, 0xd1, 0xeb, + 0xfc, 0x18, 0x16, 0xaf, 0x4f, 0xf0, 0x9b, 0x55, 0xfc, 0xb4, 0xca, 0x47, + 0xb2, 0xa0, 0x2d, 0x1e, 0x7c, 0xaf, 0x11, 0x79, 0xea, 0x3f, 0xe1, 0x39, + 0x5b, 0x22, 0xb8, 0x61, 0x96, 0x40, 0x16, 0xfa, 0xba, 0xf7, 0x2c, 0x97, + 0x56, 0x95, 0xd9, 0x3d, 0x4d, 0xf0, 0xe5, 0x19, 0x7f, 0xe9, 0xf0, 0x40, + 0x63, 0x4e, 0xd5, 0x97, 0x64, 0x93, 0x77, 0x87, 0xbe, 0x20, 0xbc, 0x4d, + 0xee, 0xbb, 0xf9, 0xb8, 0xd6, 0x0a, 0x33, 0x5f, 0x04, 0x6c, 0xa3, 0xaa, + 0x94, 0x1e, 0x45, 0x86, 0x4c, 0x7c, 0xad, 0xef, 0x9c, 0xf7, 0x5b, 0x3d, + 0x8b, 0x01, 0x0e, 0x44, 0x3e, 0xf0 +}; + +static const unsigned char ecjpake_test_srv_one[] = { + 0x41, 0x04, 0x7e, 0xa6, 0xe3, 0xa4, 0x48, 0x70, 0x37, 0xa9, 0xe0, 0xdb, + 0xd7, 0x92, 0x62, 0xb2, 0xcc, 0x27, 0x3e, 0x77, 0x99, 0x30, 0xfc, 0x18, + 0x40, 0x9a, 0xc5, 0x36, 0x1c, 0x5f, 0xe6, 0x69, 0xd7, 0x02, 0xe1, 0x47, + 0x79, 0x0a, 0xeb, 0x4c, 0xe7, 0xfd, 0x65, 0x75, 0xab, 0x0f, 0x6c, 0x7f, + 0xd1, 0xc3, 0x35, 0x93, 0x9a, 0xa8, 0x63, 0xba, 0x37, 0xec, 0x91, 0xb7, + 0xe3, 0x2b, 0xb0, 0x13, 0xbb, 0x2b, 0x41, 0x04, 0x09, 0xf8, 0x5b, 0x3d, + 0x20, 0xeb, 0xd7, 0x88, 0x5c, 0xe4, 0x64, 0xc0, 0x8d, 0x05, 0x6d, 0x64, + 0x28, 0xfe, 0x4d, 0xd9, 0x28, 0x7a, 0xa3, 0x65, 0xf1, 0x31, 0xf4, 0x36, + 0x0f, 0xf3, 0x86, 0xd8, 0x46, 0x89, 0x8b, 0xc4, 0xb4, 0x15, 0x83, 0xc2, + 0xa5, 0x19, 0x7f, 0x65, 0xd7, 0x87, 0x42, 0x74, 0x6c, 0x12, 0xa5, 0xec, + 0x0a, 0x4f, 0xfe, 0x2f, 0x27, 0x0a, 0x75, 0x0a, 0x1d, 0x8f, 0xb5, 0x16, + 0x20, 0x93, 0x4d, 0x74, 0xeb, 0x43, 0xe5, 0x4d, 0xf4, 0x24, 0xfd, 0x96, + 0x30, 0x6c, 0x01, 0x17, 0xbf, 0x13, 0x1a, 0xfa, 0xbf, 0x90, 0xa9, 0xd3, + 0x3d, 0x11, 0x98, 0xd9, 0x05, 0x19, 0x37, 0x35, 0x14, 0x41, 0x04, 0x19, + 0x0a, 0x07, 0x70, 0x0f, 0xfa, 0x4b, 0xe6, 0xae, 0x1d, 0x79, 0xee, 0x0f, + 0x06, 0xae, 0xb5, 0x44, 0xcd, 0x5a, 0xdd, 0xaa, 0xbe, 0xdf, 0x70, 0xf8, + 0x62, 0x33, 0x21, 0x33, 0x2c, 0x54, 0xf3, 0x55, 0xf0, 0xfb, 0xfe, 0xc7, + 0x83, 0xed, 0x35, 0x9e, 0x5d, 0x0b, 0xf7, 0x37, 0x7a, 0x0f, 0xc4, 0xea, + 0x7a, 0xce, 0x47, 0x3c, 0x9c, 0x11, 0x2b, 0x41, 0xcc, 0xd4, 0x1a, 0xc5, + 0x6a, 0x56, 0x12, 0x41, 0x04, 0x36, 0x0a, 0x1c, 0xea, 0x33, 0xfc, 0xe6, + 0x41, 0x15, 0x64, 0x58, 0xe0, 0xa4, 0xea, 0xc2, 0x19, 0xe9, 0x68, 0x31, + 0xe6, 0xae, 0xbc, 0x88, 0xb3, 0xf3, 0x75, 0x2f, 0x93, 0xa0, 0x28, 0x1d, + 0x1b, 0xf1, 0xfb, 0x10, 0x60, 0x51, 0xdb, 0x96, 0x94, 0xa8, 0xd6, 0xe8, + 0x62, 0xa5, 0xef, 0x13, 0x24, 0xa3, 0xd9, 0xe2, 0x78, 0x94, 0xf1, 0xee, + 0x4f, 0x7c, 0x59, 0x19, 0x99, 0x65, 0xa8, 0xdd, 0x4a, 0x20, 0x91, 0x84, + 0x7d, 0x2d, 0x22, 0xdf, 0x3e, 0xe5, 0x5f, 0xaa, 0x2a, 0x3f, 0xb3, 0x3f, + 0xd2, 0xd1, 0xe0, 0x55, 0xa0, 0x7a, 0x7c, 0x61, 0xec, 0xfb, 0x8d, 0x80, + 0xec, 0x00, 0xc2, 0xc9, 0xeb, 0x12 +}; + +static const unsigned char ecjpake_test_srv_two[] = { + 0x03, 0x00, 0x17, 0x41, 0x04, 0x0f, 0xb2, 0x2b, 0x1d, 0x5d, 0x11, 0x23, + 0xe0, 0xef, 0x9f, 0xeb, 0x9d, 0x8a, 0x2e, 0x59, 0x0a, 0x1f, 0x4d, 0x7c, + 0xed, 0x2c, 0x2b, 0x06, 0x58, 0x6e, 0x8f, 0x2a, 0x16, 0xd4, 0xeb, 0x2f, + 0xda, 0x43, 0x28, 0xa2, 0x0b, 0x07, 0xd8, 0xfd, 0x66, 0x76, 0x54, 0xca, + 0x18, 0xc5, 0x4e, 0x32, 0xa3, 0x33, 0xa0, 0x84, 0x54, 0x51, 0xe9, 0x26, + 0xee, 0x88, 0x04, 0xfd, 0x7a, 0xf0, 0xaa, 0xa7, 0xa6, 0x41, 0x04, 0x55, + 0x16, 0xea, 0x3e, 0x54, 0xa0, 0xd5, 0xd8, 0xb2, 0xce, 0x78, 0x6b, 0x38, + 0xd3, 0x83, 0x37, 0x00, 0x29, 0xa5, 0xdb, 0xe4, 0x45, 0x9c, 0x9d, 0xd6, + 0x01, 0xb4, 0x08, 0xa2, 0x4a, 0xe6, 0x46, 0x5c, 0x8a, 0xc9, 0x05, 0xb9, + 0xeb, 0x03, 0xb5, 0xd3, 0x69, 0x1c, 0x13, 0x9e, 0xf8, 0x3f, 0x1c, 0xd4, + 0x20, 0x0f, 0x6c, 0x9c, 0xd4, 0xec, 0x39, 0x22, 0x18, 0xa5, 0x9e, 0xd2, + 0x43, 0xd3, 0xc8, 0x20, 0xff, 0x72, 0x4a, 0x9a, 0x70, 0xb8, 0x8c, 0xb8, + 0x6f, 0x20, 0xb4, 0x34, 0xc6, 0x86, 0x5a, 0xa1, 0xcd, 0x79, 0x06, 0xdd, + 0x7c, 0x9b, 0xce, 0x35, 0x25, 0xf5, 0x08, 0x27, 0x6f, 0x26, 0x83, 0x6c +}; + +static const unsigned char ecjpake_test_cli_two[] = { + 0x41, 0x04, 0x69, 0xd5, 0x4e, 0xe8, 0x5e, 0x90, 0xce, 0x3f, 0x12, 0x46, + 0x74, 0x2d, 0xe5, 0x07, 0xe9, 0x39, 0xe8, 0x1d, 0x1d, 0xc1, 0xc5, 0xcb, + 0x98, 0x8b, 0x58, 0xc3, 0x10, 0xc9, 0xfd, 0xd9, 0x52, 0x4d, 0x93, 0x72, + 0x0b, 0x45, 0x54, 0x1c, 0x83, 0xee, 0x88, 0x41, 0x19, 0x1d, 0xa7, 0xce, + 0xd8, 0x6e, 0x33, 0x12, 0xd4, 0x36, 0x23, 0xc1, 0xd6, 0x3e, 0x74, 0x98, + 0x9a, 0xba, 0x4a, 0xff, 0xd1, 0xee, 0x41, 0x04, 0x07, 0x7e, 0x8c, 0x31, + 0xe2, 0x0e, 0x6b, 0xed, 0xb7, 0x60, 0xc1, 0x35, 0x93, 0xe6, 0x9f, 0x15, + 0xbe, 0x85, 0xc2, 0x7d, 0x68, 0xcd, 0x09, 0xcc, 0xb8, 0xc4, 0x18, 0x36, + 0x08, 0x91, 0x7c, 0x5c, 0x3d, 0x40, 0x9f, 0xac, 0x39, 0xfe, 0xfe, 0xe8, + 0x2f, 0x72, 0x92, 0xd3, 0x6f, 0x0d, 0x23, 0xe0, 0x55, 0x91, 0x3f, 0x45, + 0xa5, 0x2b, 0x85, 0xdd, 0x8a, 0x20, 0x52, 0xe9, 0xe1, 0x29, 0xbb, 0x4d, + 0x20, 0x0f, 0x01, 0x1f, 0x19, 0x48, 0x35, 0x35, 0xa6, 0xe8, 0x9a, 0x58, + 0x0c, 0x9b, 0x00, 0x03, 0xba, 0xf2, 0x14, 0x62, 0xec, 0xe9, 0x1a, 0x82, + 0xcc, 0x38, 0xdb, 0xdc, 0xae, 0x60, 0xd9, 0xc5, 0x4c +}; + +static const unsigned char ecjpake_test_pms[] = { + 0xf3, 0xd4, 0x7f, 0x59, 0x98, 0x44, 0xdb, 0x92, 0xa5, 0x69, 0xbb, 0xe7, + 0x98, 0x1e, 0x39, 0xd9, 0x31, 0xfd, 0x74, 0x3b, 0xf2, 0x2e, 0x98, 0xf9, + 0xb4, 0x38, 0xf7, 0x19, 0xd3, 0xc4, 0xf3, 0x51 +}; + +/* Load my private keys and generate the correponding public keys */ +static int ecjpake_test_load( mbedtls_ecjpake_context *ctx, + const unsigned char *xm1, size_t len1, + const unsigned char *xm2, size_t len2 ) +{ + int ret; + + MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->xm1, xm1, len1 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &ctx->xm2, xm2, len2 ) ); + MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &ctx->Xm1, &ctx->xm1, + &ctx->grp.G, NULL, NULL ) ); + MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &ctx->grp, &ctx->Xm2, &ctx->xm2, + &ctx->grp.G, NULL, NULL ) ); + +cleanup: + return( ret ); +} + +/* For tests we don't need a secure RNG; + * use the LGC from Numerical Recipes for simplicity */ +static int ecjpake_lgc( void *p, unsigned char *out, size_t len ) +{ + static uint32_t x = 42; + (void) p; + + while( len > 0 ) + { + size_t use_len = len > 4 ? 4 : len; + x = 1664525 * x + 1013904223; + memcpy( out, &x, use_len ); + out += use_len; + len -= use_len; + } + + return( 0 ); +} + +#define TEST_ASSERT( x ) \ + do { \ + if( x ) \ + ret = 0; \ + else \ + { \ + ret = 1; \ + goto cleanup; \ + } \ + } while( 0 ) + +/* + * Checkup routine + */ +int mbedtls_ecjpake_self_test( int verbose ) +{ + int ret; + mbedtls_ecjpake_context cli; + mbedtls_ecjpake_context srv; + unsigned char buf[512], pms[32]; + size_t len, pmslen; + + mbedtls_ecjpake_init( &cli ); + mbedtls_ecjpake_init( &srv ); + + if( verbose != 0 ) + mbedtls_printf( " ECJPAKE test #0 (setup): " ); + + TEST_ASSERT( mbedtls_ecjpake_setup( &cli, MBEDTLS_ECJPAKE_CLIENT, + MBEDTLS_MD_SHA256, MBEDTLS_ECP_DP_SECP256R1, + ecjpake_test_password, + sizeof( ecjpake_test_password ) ) == 0 ); + + TEST_ASSERT( mbedtls_ecjpake_setup( &srv, MBEDTLS_ECJPAKE_SERVER, + MBEDTLS_MD_SHA256, MBEDTLS_ECP_DP_SECP256R1, + ecjpake_test_password, + sizeof( ecjpake_test_password ) ) == 0 ); + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + + if( verbose != 0 ) + mbedtls_printf( " ECJPAKE test #1 (random handshake): " ); + + TEST_ASSERT( mbedtls_ecjpake_write_round_one( &cli, + buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 ); + + TEST_ASSERT( mbedtls_ecjpake_read_round_one( &srv, buf, len ) == 0 ); + + TEST_ASSERT( mbedtls_ecjpake_write_round_one( &srv, + buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 ); + + TEST_ASSERT( mbedtls_ecjpake_read_round_one( &cli, buf, len ) == 0 ); + + TEST_ASSERT( mbedtls_ecjpake_write_round_two( &srv, + buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 ); + + TEST_ASSERT( mbedtls_ecjpake_read_round_two( &cli, buf, len ) == 0 ); + + TEST_ASSERT( mbedtls_ecjpake_derive_secret( &cli, + pms, sizeof( pms ), &pmslen, ecjpake_lgc, NULL ) == 0 ); + + TEST_ASSERT( mbedtls_ecjpake_write_round_two( &cli, + buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 ); + + TEST_ASSERT( mbedtls_ecjpake_read_round_two( &srv, buf, len ) == 0 ); + + TEST_ASSERT( mbedtls_ecjpake_derive_secret( &srv, + buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 ); + + TEST_ASSERT( len == pmslen ); + TEST_ASSERT( memcmp( buf, pms, len ) == 0 ); + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + + if( verbose != 0 ) + mbedtls_printf( " ECJPAKE test #2 (reference handshake): " ); + + /* Simulate generation of round one */ + MBEDTLS_MPI_CHK( ecjpake_test_load( &cli, + ecjpake_test_x1, sizeof( ecjpake_test_x1 ), + ecjpake_test_x2, sizeof( ecjpake_test_x2 ) ) ); + + MBEDTLS_MPI_CHK( ecjpake_test_load( &srv, + ecjpake_test_x3, sizeof( ecjpake_test_x3 ), + ecjpake_test_x4, sizeof( ecjpake_test_x4 ) ) ); + + /* Read round one */ + TEST_ASSERT( mbedtls_ecjpake_read_round_one( &srv, + ecjpake_test_cli_one, + sizeof( ecjpake_test_cli_one ) ) == 0 ); + + TEST_ASSERT( mbedtls_ecjpake_read_round_one( &cli, + ecjpake_test_srv_one, + sizeof( ecjpake_test_srv_one ) ) == 0 ); + + /* Skip generation of round two, read round two */ + TEST_ASSERT( mbedtls_ecjpake_read_round_two( &cli, + ecjpake_test_srv_two, + sizeof( ecjpake_test_srv_two ) ) == 0 ); + + TEST_ASSERT( mbedtls_ecjpake_read_round_two( &srv, + ecjpake_test_cli_two, + sizeof( ecjpake_test_cli_two ) ) == 0 ); + + /* Server derives PMS */ + TEST_ASSERT( mbedtls_ecjpake_derive_secret( &srv, + buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 ); + + TEST_ASSERT( len == sizeof( ecjpake_test_pms ) ); + TEST_ASSERT( memcmp( buf, ecjpake_test_pms, len ) == 0 ); + + memset( buf, 0, len ); /* Avoid interferences with next step */ + + /* Client derives PMS */ + TEST_ASSERT( mbedtls_ecjpake_derive_secret( &cli, + buf, sizeof( buf ), &len, ecjpake_lgc, NULL ) == 0 ); + + TEST_ASSERT( len == sizeof( ecjpake_test_pms ) ); + TEST_ASSERT( memcmp( buf, ecjpake_test_pms, len ) == 0 ); + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + +cleanup: + mbedtls_ecjpake_free( &cli ); + mbedtls_ecjpake_free( &srv ); + + if( ret != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + ret = 1; + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + + return( ret ); +} + +#undef TEST_ASSERT + +#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED && MBEDTLS_SHA256_C */ + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_ECJPAKE_C */ diff --git a/security/mbedtls/src/ecp.c b/security/mbedtls/src/ecp.c new file mode 100644 index 0000000000..56f22c2726 --- /dev/null +++ b/security/mbedtls/src/ecp.c @@ -0,0 +1,2217 @@ +/* + * Elliptic curves over GF(p): generic functions + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +/* + * References: + * + * SEC1 http://www.secg.org/index.php?action=secg,docs_secg + * GECC = Guide to Elliptic Curve Cryptography - Hankerson, Menezes, Vanstone + * FIPS 186-3 http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf + * RFC 4492 for the related TLS structures and constants + * + * [Curve25519] http://cr.yp.to/ecdh/curve25519-20060209.pdf + * + * [2] CORON, Jean-S'ebastien. Resistance against differential power analysis + * for elliptic curve cryptosystems. In : Cryptographic Hardware and + * Embedded Systems. Springer Berlin Heidelberg, 1999. p. 292-302. + * + * + * [3] HEDABOU, Mustapha, PINEL, Pierre, et B'EN'ETEAU, Lucien. A comb method to + * render ECC resistant against Side Channel Attacks. IACR Cryptology + * ePrint Archive, 2004, vol. 2004, p. 342. + * + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_ECP_C) + +#include "mbedtls/ecp.h" +#include "mbedtls/threading.h" + +#include + +#if !defined(MBEDTLS_ECP_ALT) + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#include +#define mbedtls_printf printf +#define mbedtls_calloc calloc +#define mbedtls_free free +#endif + +#include "mbedtls/ecp_internal.h" + +#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ + !defined(inline) && !defined(__cplusplus) +#define inline __inline +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +#if defined(MBEDTLS_SELF_TEST) +/* + * Counts of point addition and doubling, and field multiplications. + * Used to test resistance of point multiplication to simple timing attacks. + */ +static unsigned long add_count, dbl_count, mul_count; +#endif + +#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) +#define ECP_SHORTWEIERSTRASS +#endif + +#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) +#define ECP_MONTGOMERY +#endif + +/* + * Curve types: internal for now, might be exposed later + */ +typedef enum +{ + ECP_TYPE_NONE = 0, + ECP_TYPE_SHORT_WEIERSTRASS, /* y^2 = x^3 + a x + b */ + ECP_TYPE_MONTGOMERY, /* y^2 = x^3 + a x^2 + x */ +} ecp_curve_type; + +/* + * List of supported curves: + * - internal ID + * - TLS NamedCurve ID (RFC 4492 sec. 5.1.1, RFC 7071 sec. 2) + * - size in bits + * - readable name + * + * Curves are listed in order: largest curves first, and for a given size, + * fastest curves first. This provides the default order for the SSL module. + * + * Reminder: update profiles in x509_crt.c when adding a new curves! + */ +static const mbedtls_ecp_curve_info ecp_supported_curves[] = +{ +#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) + { MBEDTLS_ECP_DP_SECP521R1, 25, 521, "secp521r1" }, +#endif +#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) + { MBEDTLS_ECP_DP_BP512R1, 28, 512, "brainpoolP512r1" }, +#endif +#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) + { MBEDTLS_ECP_DP_SECP384R1, 24, 384, "secp384r1" }, +#endif +#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) + { MBEDTLS_ECP_DP_BP384R1, 27, 384, "brainpoolP384r1" }, +#endif +#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) + { MBEDTLS_ECP_DP_SECP256R1, 23, 256, "secp256r1" }, +#endif +#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) + { MBEDTLS_ECP_DP_SECP256K1, 22, 256, "secp256k1" }, +#endif +#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) + { MBEDTLS_ECP_DP_BP256R1, 26, 256, "brainpoolP256r1" }, +#endif +#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) + { MBEDTLS_ECP_DP_SECP224R1, 21, 224, "secp224r1" }, +#endif +#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) + { MBEDTLS_ECP_DP_SECP224K1, 20, 224, "secp224k1" }, +#endif +#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) + { MBEDTLS_ECP_DP_SECP192R1, 19, 192, "secp192r1" }, +#endif +#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) + { MBEDTLS_ECP_DP_SECP192K1, 18, 192, "secp192k1" }, +#endif + { MBEDTLS_ECP_DP_NONE, 0, 0, NULL }, +}; + +#define ECP_NB_CURVES sizeof( ecp_supported_curves ) / \ + sizeof( ecp_supported_curves[0] ) + +static mbedtls_ecp_group_id ecp_supported_grp_id[ECP_NB_CURVES]; + +/* + * List of supported curves and associated info + */ +const mbedtls_ecp_curve_info *mbedtls_ecp_curve_list( void ) +{ + return( ecp_supported_curves ); +} + +/* + * List of supported curves, group ID only + */ +const mbedtls_ecp_group_id *mbedtls_ecp_grp_id_list( void ) +{ + static int init_done = 0; + + if( ! init_done ) + { + size_t i = 0; + const mbedtls_ecp_curve_info *curve_info; + + for( curve_info = mbedtls_ecp_curve_list(); + curve_info->grp_id != MBEDTLS_ECP_DP_NONE; + curve_info++ ) + { + ecp_supported_grp_id[i++] = curve_info->grp_id; + } + ecp_supported_grp_id[i] = MBEDTLS_ECP_DP_NONE; + + init_done = 1; + } + + return( ecp_supported_grp_id ); +} + +/* + * Get the curve info for the internal identifier + */ +const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_grp_id( mbedtls_ecp_group_id grp_id ) +{ + const mbedtls_ecp_curve_info *curve_info; + + for( curve_info = mbedtls_ecp_curve_list(); + curve_info->grp_id != MBEDTLS_ECP_DP_NONE; + curve_info++ ) + { + if( curve_info->grp_id == grp_id ) + return( curve_info ); + } + + return( NULL ); +} + +/* + * Get the curve info from the TLS identifier + */ +const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_tls_id( uint16_t tls_id ) +{ + const mbedtls_ecp_curve_info *curve_info; + + for( curve_info = mbedtls_ecp_curve_list(); + curve_info->grp_id != MBEDTLS_ECP_DP_NONE; + curve_info++ ) + { + if( curve_info->tls_id == tls_id ) + return( curve_info ); + } + + return( NULL ); +} + +/* + * Get the curve info from the name + */ +const mbedtls_ecp_curve_info *mbedtls_ecp_curve_info_from_name( const char *name ) +{ + const mbedtls_ecp_curve_info *curve_info; + + for( curve_info = mbedtls_ecp_curve_list(); + curve_info->grp_id != MBEDTLS_ECP_DP_NONE; + curve_info++ ) + { + if( strcmp( curve_info->name, name ) == 0 ) + return( curve_info ); + } + + return( NULL ); +} + +/* + * Get the type of a curve + */ +static inline ecp_curve_type ecp_get_type( const mbedtls_ecp_group *grp ) +{ + if( grp->G.X.p == NULL ) + return( ECP_TYPE_NONE ); + + if( grp->G.Y.p == NULL ) + return( ECP_TYPE_MONTGOMERY ); + else + return( ECP_TYPE_SHORT_WEIERSTRASS ); +} + +/* + * Initialize (the components of) a point + */ +void mbedtls_ecp_point_init( mbedtls_ecp_point *pt ) +{ + if( pt == NULL ) + return; + + mbedtls_mpi_init( &pt->X ); + mbedtls_mpi_init( &pt->Y ); + mbedtls_mpi_init( &pt->Z ); +} + +/* + * Initialize (the components of) a group + */ +void mbedtls_ecp_group_init( mbedtls_ecp_group *grp ) +{ + if( grp == NULL ) + return; + + memset( grp, 0, sizeof( mbedtls_ecp_group ) ); +} + +/* + * Initialize (the components of) a key pair + */ +void mbedtls_ecp_keypair_init( mbedtls_ecp_keypair *key ) +{ + if( key == NULL ) + return; + + mbedtls_ecp_group_init( &key->grp ); + mbedtls_mpi_init( &key->d ); + mbedtls_ecp_point_init( &key->Q ); +} + +/* + * Unallocate (the components of) a point + */ +void mbedtls_ecp_point_free( mbedtls_ecp_point *pt ) +{ + if( pt == NULL ) + return; + + mbedtls_mpi_free( &( pt->X ) ); + mbedtls_mpi_free( &( pt->Y ) ); + mbedtls_mpi_free( &( pt->Z ) ); +} + +/* + * Unallocate (the components of) a group + */ +void mbedtls_ecp_group_free( mbedtls_ecp_group *grp ) +{ + size_t i; + + if( grp == NULL ) + return; + + if( grp->h != 1 ) + { + mbedtls_mpi_free( &grp->P ); + mbedtls_mpi_free( &grp->A ); + mbedtls_mpi_free( &grp->B ); + mbedtls_ecp_point_free( &grp->G ); + mbedtls_mpi_free( &grp->N ); + } + + if( grp->T != NULL ) + { + for( i = 0; i < grp->T_size; i++ ) + mbedtls_ecp_point_free( &grp->T[i] ); + mbedtls_free( grp->T ); + } + + mbedtls_zeroize( grp, sizeof( mbedtls_ecp_group ) ); +} + +/* + * Unallocate (the components of) a key pair + */ +void mbedtls_ecp_keypair_free( mbedtls_ecp_keypair *key ) +{ + if( key == NULL ) + return; + + mbedtls_ecp_group_free( &key->grp ); + mbedtls_mpi_free( &key->d ); + mbedtls_ecp_point_free( &key->Q ); +} + +/* + * Copy the contents of a point + */ +int mbedtls_ecp_copy( mbedtls_ecp_point *P, const mbedtls_ecp_point *Q ) +{ + int ret; + + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &P->X, &Q->X ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &P->Y, &Q->Y ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &P->Z, &Q->Z ) ); + +cleanup: + return( ret ); +} + +/* + * Copy the contents of a group object + */ +int mbedtls_ecp_group_copy( mbedtls_ecp_group *dst, const mbedtls_ecp_group *src ) +{ + return mbedtls_ecp_group_load( dst, src->id ); +} + +/* + * Set point to zero + */ +int mbedtls_ecp_set_zero( mbedtls_ecp_point *pt ) +{ + int ret; + + MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->X , 1 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Y , 1 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Z , 0 ) ); + +cleanup: + return( ret ); +} + +/* + * Tell if a point is zero + */ +int mbedtls_ecp_is_zero( mbedtls_ecp_point *pt ) +{ + return( mbedtls_mpi_cmp_int( &pt->Z, 0 ) == 0 ); +} + +/* + * Compare two points lazyly + */ +int mbedtls_ecp_point_cmp( const mbedtls_ecp_point *P, + const mbedtls_ecp_point *Q ) +{ + if( mbedtls_mpi_cmp_mpi( &P->X, &Q->X ) == 0 && + mbedtls_mpi_cmp_mpi( &P->Y, &Q->Y ) == 0 && + mbedtls_mpi_cmp_mpi( &P->Z, &Q->Z ) == 0 ) + { + return( 0 ); + } + + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); +} + +/* + * Import a non-zero point from ASCII strings + */ +int mbedtls_ecp_point_read_string( mbedtls_ecp_point *P, int radix, + const char *x, const char *y ) +{ + int ret; + + MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &P->X, radix, x ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &P->Y, radix, y ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &P->Z, 1 ) ); + +cleanup: + return( ret ); +} + +/* + * Export a point into unsigned binary data (SEC1 2.3.3) + */ +int mbedtls_ecp_point_write_binary( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *P, + int format, size_t *olen, + unsigned char *buf, size_t buflen ) +{ + int ret = 0; + size_t plen; + + if( format != MBEDTLS_ECP_PF_UNCOMPRESSED && + format != MBEDTLS_ECP_PF_COMPRESSED ) + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + + /* + * Common case: P == 0 + */ + if( mbedtls_mpi_cmp_int( &P->Z, 0 ) == 0 ) + { + if( buflen < 1 ) + return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); + + buf[0] = 0x00; + *olen = 1; + + return( 0 ); + } + + plen = mbedtls_mpi_size( &grp->P ); + + if( format == MBEDTLS_ECP_PF_UNCOMPRESSED ) + { + *olen = 2 * plen + 1; + + if( buflen < *olen ) + return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); + + buf[0] = 0x04; + MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->X, buf + 1, plen ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->Y, buf + 1 + plen, plen ) ); + } + else if( format == MBEDTLS_ECP_PF_COMPRESSED ) + { + *olen = plen + 1; + + if( buflen < *olen ) + return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); + + buf[0] = 0x02 + mbedtls_mpi_get_bit( &P->Y, 0 ); + MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &P->X, buf + 1, plen ) ); + } + +cleanup: + return( ret ); +} + +/* + * Import a point from unsigned binary data (SEC1 2.3.4) + */ +int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt, + const unsigned char *buf, size_t ilen ) +{ + int ret; + size_t plen; + + if( ilen < 1 ) + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + + if( buf[0] == 0x00 ) + { + if( ilen == 1 ) + return( mbedtls_ecp_set_zero( pt ) ); + else + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + } + + plen = mbedtls_mpi_size( &grp->P ); + + if( buf[0] != 0x04 ) + return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ); + + if( ilen != 2 * plen + 1 ) + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &pt->X, buf + 1, plen ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &pt->Y, buf + 1 + plen, plen ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Z, 1 ) ); + +cleanup: + return( ret ); +} + +/* + * Import a point from a TLS ECPoint record (RFC 4492) + * struct { + * opaque point <1..2^8-1>; + * } ECPoint; + */ +int mbedtls_ecp_tls_read_point( const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt, + const unsigned char **buf, size_t buf_len ) +{ + unsigned char data_len; + const unsigned char *buf_start; + + /* + * We must have at least two bytes (1 for length, at least one for data) + */ + if( buf_len < 2 ) + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + + data_len = *(*buf)++; + if( data_len < 1 || data_len > buf_len - 1 ) + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + + /* + * Save buffer start for read_binary and update buf + */ + buf_start = *buf; + *buf += data_len; + + return mbedtls_ecp_point_read_binary( grp, pt, buf_start, data_len ); +} + +/* + * Export a point as a TLS ECPoint record (RFC 4492) + * struct { + * opaque point <1..2^8-1>; + * } ECPoint; + */ +int mbedtls_ecp_tls_write_point( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt, + int format, size_t *olen, + unsigned char *buf, size_t blen ) +{ + int ret; + + /* + * buffer length must be at least one, for our length byte + */ + if( blen < 1 ) + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + + if( ( ret = mbedtls_ecp_point_write_binary( grp, pt, format, + olen, buf + 1, blen - 1) ) != 0 ) + return( ret ); + + /* + * write length to the first byte and update total length + */ + buf[0] = (unsigned char) *olen; + ++*olen; + + return( 0 ); +} + +/* + * Set a group from an ECParameters record (RFC 4492) + */ +int mbedtls_ecp_tls_read_group( mbedtls_ecp_group *grp, const unsigned char **buf, size_t len ) +{ + uint16_t tls_id; + const mbedtls_ecp_curve_info *curve_info; + + /* + * We expect at least three bytes (see below) + */ + if( len < 3 ) + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + + /* + * First byte is curve_type; only named_curve is handled + */ + if( *(*buf)++ != MBEDTLS_ECP_TLS_NAMED_CURVE ) + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + + /* + * Next two bytes are the namedcurve value + */ + tls_id = *(*buf)++; + tls_id <<= 8; + tls_id |= *(*buf)++; + + if( ( curve_info = mbedtls_ecp_curve_info_from_tls_id( tls_id ) ) == NULL ) + return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ); + + return mbedtls_ecp_group_load( grp, curve_info->grp_id ); +} + +/* + * Write the ECParameters record corresponding to a group (RFC 4492) + */ +int mbedtls_ecp_tls_write_group( const mbedtls_ecp_group *grp, size_t *olen, + unsigned char *buf, size_t blen ) +{ + const mbedtls_ecp_curve_info *curve_info; + + if( ( curve_info = mbedtls_ecp_curve_info_from_grp_id( grp->id ) ) == NULL ) + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + + /* + * We are going to write 3 bytes (see below) + */ + *olen = 3; + if( blen < *olen ) + return( MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL ); + + /* + * First byte is curve_type, always named_curve + */ + *buf++ = MBEDTLS_ECP_TLS_NAMED_CURVE; + + /* + * Next two bytes are the namedcurve value + */ + buf[0] = curve_info->tls_id >> 8; + buf[1] = curve_info->tls_id & 0xFF; + + return( 0 ); +} + +/* + * Wrapper around fast quasi-modp functions, with fall-back to mbedtls_mpi_mod_mpi. + * See the documentation of struct mbedtls_ecp_group. + * + * This function is in the critial loop for mbedtls_ecp_mul, so pay attention to perf. + */ +static int ecp_modp( mbedtls_mpi *N, const mbedtls_ecp_group *grp ) +{ + int ret; + + if( grp->modp == NULL ) + return( mbedtls_mpi_mod_mpi( N, N, &grp->P ) ); + + /* N->s < 0 is a much faster test, which fails only if N is 0 */ + if( ( N->s < 0 && mbedtls_mpi_cmp_int( N, 0 ) != 0 ) || + mbedtls_mpi_bitlen( N ) > 2 * grp->pbits ) + { + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + } + + MBEDTLS_MPI_CHK( grp->modp( N ) ); + + /* N->s < 0 is a much faster test, which fails only if N is 0 */ + while( N->s < 0 && mbedtls_mpi_cmp_int( N, 0 ) != 0 ) + MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( N, N, &grp->P ) ); + + while( mbedtls_mpi_cmp_mpi( N, &grp->P ) >= 0 ) + /* we known P, N and the result are positive */ + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( N, N, &grp->P ) ); + +cleanup: + return( ret ); +} + +/* + * Fast mod-p functions expect their argument to be in the 0..p^2 range. + * + * In order to guarantee that, we need to ensure that operands of + * mbedtls_mpi_mul_mpi are in the 0..p range. So, after each operation we will + * bring the result back to this range. + * + * The following macros are shortcuts for doing that. + */ + +/* + * Reduce a mbedtls_mpi mod p in-place, general case, to use after mbedtls_mpi_mul_mpi + */ +#if defined(MBEDTLS_SELF_TEST) +#define INC_MUL_COUNT mul_count++; +#else +#define INC_MUL_COUNT +#endif + +#define MOD_MUL( N ) do { MBEDTLS_MPI_CHK( ecp_modp( &N, grp ) ); INC_MUL_COUNT } \ + while( 0 ) + +/* + * Reduce a mbedtls_mpi mod p in-place, to use after mbedtls_mpi_sub_mpi + * N->s < 0 is a very fast test, which fails only if N is 0 + */ +#define MOD_SUB( N ) \ + while( N.s < 0 && mbedtls_mpi_cmp_int( &N, 0 ) != 0 ) \ + MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &N, &N, &grp->P ) ) + +/* + * Reduce a mbedtls_mpi mod p in-place, to use after mbedtls_mpi_add_mpi and mbedtls_mpi_mul_int. + * We known P, N and the result are positive, so sub_abs is correct, and + * a bit faster. + */ +#define MOD_ADD( N ) \ + while( mbedtls_mpi_cmp_mpi( &N, &grp->P ) >= 0 ) \ + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( &N, &N, &grp->P ) ) + +#if defined(ECP_SHORTWEIERSTRASS) +/* + * For curves in short Weierstrass form, we do all the internal operations in + * Jacobian coordinates. + * + * For multiplication, we'll use a comb method with coutermeasueres against + * SPA, hence timing attacks. + */ + +/* + * Normalize jacobian coordinates so that Z == 0 || Z == 1 (GECC 3.2.1) + * Cost: 1N := 1I + 3M + 1S + */ +static int ecp_normalize_jac( const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt ) +{ + int ret; + mbedtls_mpi Zi, ZZi; + + if( mbedtls_mpi_cmp_int( &pt->Z, 0 ) == 0 ) + return( 0 ); + +#if defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT) + if ( mbedtls_internal_ecp_grp_capable( grp ) ) + { + return mbedtls_internal_ecp_normalize_jac( grp, pt ); + } +#endif /* MBEDTLS_ECP_NORMALIZE_JAC_ALT */ + mbedtls_mpi_init( &Zi ); mbedtls_mpi_init( &ZZi ); + + /* + * X = X / Z^2 mod p + */ + MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &Zi, &pt->Z, &grp->P ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ZZi, &Zi, &Zi ) ); MOD_MUL( ZZi ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->X, &pt->X, &ZZi ) ); MOD_MUL( pt->X ); + + /* + * Y = Y / Z^3 mod p + */ + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->Y, &pt->Y, &ZZi ) ); MOD_MUL( pt->Y ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->Y, &pt->Y, &Zi ) ); MOD_MUL( pt->Y ); + + /* + * Z = 1 + */ + MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &pt->Z, 1 ) ); + +cleanup: + + mbedtls_mpi_free( &Zi ); mbedtls_mpi_free( &ZZi ); + + return( ret ); +} + +/* + * Normalize jacobian coordinates of an array of (pointers to) points, + * using Montgomery's trick to perform only one inversion mod P. + * (See for example Cohen's "A Course in Computational Algebraic Number + * Theory", Algorithm 10.3.4.) + * + * Warning: fails (returning an error) if one of the points is zero! + * This should never happen, see choice of w in ecp_mul_comb(). + * + * Cost: 1N(t) := 1I + (6t - 3)M + 1S + */ +static int ecp_normalize_jac_many( const mbedtls_ecp_group *grp, + mbedtls_ecp_point *T[], size_t t_len ) +{ + int ret; + size_t i; + mbedtls_mpi *c, u, Zi, ZZi; + + if( t_len < 2 ) + return( ecp_normalize_jac( grp, *T ) ); + +#if defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT) + if ( mbedtls_internal_ecp_grp_capable( grp ) ) + { + return mbedtls_internal_ecp_normalize_jac_many(grp, T, t_len); + } +#endif + + if( ( c = mbedtls_calloc( t_len, sizeof( mbedtls_mpi ) ) ) == NULL ) + return( MBEDTLS_ERR_ECP_ALLOC_FAILED ); + + mbedtls_mpi_init( &u ); mbedtls_mpi_init( &Zi ); mbedtls_mpi_init( &ZZi ); + + /* + * c[i] = Z_0 * ... * Z_i + */ + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &c[0], &T[0]->Z ) ); + for( i = 1; i < t_len; i++ ) + { + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &c[i], &c[i-1], &T[i]->Z ) ); + MOD_MUL( c[i] ); + } + + /* + * u = 1 / (Z_0 * ... * Z_n) mod P + */ + MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &u, &c[t_len-1], &grp->P ) ); + + for( i = t_len - 1; ; i-- ) + { + /* + * Zi = 1 / Z_i mod p + * u = 1 / (Z_0 * ... * Z_i) mod P + */ + if( i == 0 ) { + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Zi, &u ) ); + } + else + { + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &Zi, &u, &c[i-1] ) ); MOD_MUL( Zi ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &u, &u, &T[i]->Z ) ); MOD_MUL( u ); + } + + /* + * proceed as in normalize() + */ + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ZZi, &Zi, &Zi ) ); MOD_MUL( ZZi ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T[i]->X, &T[i]->X, &ZZi ) ); MOD_MUL( T[i]->X ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T[i]->Y, &T[i]->Y, &ZZi ) ); MOD_MUL( T[i]->Y ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T[i]->Y, &T[i]->Y, &Zi ) ); MOD_MUL( T[i]->Y ); + + /* + * Post-precessing: reclaim some memory by shrinking coordinates + * - not storing Z (always 1) + * - shrinking other coordinates, but still keeping the same number of + * limbs as P, as otherwise it will too likely be regrown too fast. + */ + MBEDTLS_MPI_CHK( mbedtls_mpi_shrink( &T[i]->X, grp->P.n ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_shrink( &T[i]->Y, grp->P.n ) ); + mbedtls_mpi_free( &T[i]->Z ); + + if( i == 0 ) + break; + } + +cleanup: + + mbedtls_mpi_free( &u ); mbedtls_mpi_free( &Zi ); mbedtls_mpi_free( &ZZi ); + for( i = 0; i < t_len; i++ ) + mbedtls_mpi_free( &c[i] ); + mbedtls_free( c ); + + return( ret ); +} + +/* + * Conditional point inversion: Q -> -Q = (Q.X, -Q.Y, Q.Z) without leak. + * "inv" must be 0 (don't invert) or 1 (invert) or the result will be invalid + */ +static int ecp_safe_invert_jac( const mbedtls_ecp_group *grp, + mbedtls_ecp_point *Q, + unsigned char inv ) +{ + int ret; + unsigned char nonzero; + mbedtls_mpi mQY; + + mbedtls_mpi_init( &mQY ); + + /* Use the fact that -Q.Y mod P = P - Q.Y unless Q.Y == 0 */ + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &mQY, &grp->P, &Q->Y ) ); + nonzero = mbedtls_mpi_cmp_int( &Q->Y, 0 ) != 0; + MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( &Q->Y, &mQY, inv & nonzero ) ); + +cleanup: + mbedtls_mpi_free( &mQY ); + + return( ret ); +} + +/* + * Point doubling R = 2 P, Jacobian coordinates + * + * Based on http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#doubling-dbl-1998-cmo-2 . + * + * We follow the variable naming fairly closely. The formula variations that trade a MUL for a SQR + * (plus a few ADDs) aren't useful as our bignum implementation doesn't distinguish squaring. + * + * Standard optimizations are applied when curve parameter A is one of { 0, -3 }. + * + * Cost: 1D := 3M + 4S (A == 0) + * 4M + 4S (A == -3) + * 3M + 6S + 1a otherwise + */ +static int ecp_double_jac( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, + const mbedtls_ecp_point *P ) +{ + int ret; + mbedtls_mpi M, S, T, U; + +#if defined(MBEDTLS_SELF_TEST) + dbl_count++; +#endif + +#if defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) + if ( mbedtls_internal_ecp_grp_capable( grp ) ) + { + return mbedtls_internal_ecp_double_jac( grp, R, P ); + } +#endif /* MBEDTLS_ECP_DOUBLE_JAC_ALT */ + + mbedtls_mpi_init( &M ); mbedtls_mpi_init( &S ); mbedtls_mpi_init( &T ); mbedtls_mpi_init( &U ); + + /* Special case for A = -3 */ + if( grp->A.p == NULL ) + { + /* M = 3(X + Z^2)(X - Z^2) */ + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &P->Z, &P->Z ) ); MOD_MUL( S ); + MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &T, &P->X, &S ) ); MOD_ADD( T ); + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &U, &P->X, &S ) ); MOD_SUB( U ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &T, &U ) ); MOD_MUL( S ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &M, &S, 3 ) ); MOD_ADD( M ); + } + else + { + /* M = 3.X^2 */ + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &P->X, &P->X ) ); MOD_MUL( S ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &M, &S, 3 ) ); MOD_ADD( M ); + + /* Optimize away for "koblitz" curves with A = 0 */ + if( mbedtls_mpi_cmp_int( &grp->A, 0 ) != 0 ) + { + /* M += A.Z^4 */ + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &P->Z, &P->Z ) ); MOD_MUL( S ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &S, &S ) ); MOD_MUL( T ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &T, &grp->A ) ); MOD_MUL( S ); + MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &M, &M, &S ) ); MOD_ADD( M ); + } + } + + /* S = 4.X.Y^2 */ + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &P->Y, &P->Y ) ); MOD_MUL( T ); + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &T, 1 ) ); MOD_ADD( T ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &P->X, &T ) ); MOD_MUL( S ); + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &S, 1 ) ); MOD_ADD( S ); + + /* U = 8.Y^4 */ + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &U, &T, &T ) ); MOD_MUL( U ); + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &U, 1 ) ); MOD_ADD( U ); + + /* T = M^2 - 2.S */ + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &M, &M ) ); MOD_MUL( T ); + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T, &T, &S ) ); MOD_SUB( T ); + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T, &T, &S ) ); MOD_SUB( T ); + + /* S = M(S - T) - U */ + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &S, &S, &T ) ); MOD_SUB( S ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S, &S, &M ) ); MOD_MUL( S ); + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &S, &S, &U ) ); MOD_SUB( S ); + + /* U = 2.Y.Z */ + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &U, &P->Y, &P->Z ) ); MOD_MUL( U ); + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &U, 1 ) ); MOD_ADD( U ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->X, &T ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->Y, &S ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->Z, &U ) ); + +cleanup: + mbedtls_mpi_free( &M ); mbedtls_mpi_free( &S ); mbedtls_mpi_free( &T ); mbedtls_mpi_free( &U ); + + return( ret ); +} + +/* + * Addition: R = P + Q, mixed affine-Jacobian coordinates (GECC 3.22) + * + * The coordinates of Q must be normalized (= affine), + * but those of P don't need to. R is not normalized. + * + * Special cases: (1) P or Q is zero, (2) R is zero, (3) P == Q. + * None of these cases can happen as intermediate step in ecp_mul_comb(): + * - at each step, P, Q and R are multiples of the base point, the factor + * being less than its order, so none of them is zero; + * - Q is an odd multiple of the base point, P an even multiple, + * due to the choice of precomputed points in the modified comb method. + * So branches for these cases do not leak secret information. + * + * We accept Q->Z being unset (saving memory in tables) as meaning 1. + * + * Cost: 1A := 8M + 3S + */ +static int ecp_add_mixed( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, + const mbedtls_ecp_point *P, const mbedtls_ecp_point *Q ) +{ + int ret; + mbedtls_mpi T1, T2, T3, T4, X, Y, Z; + +#if defined(MBEDTLS_SELF_TEST) + add_count++; +#endif + +#if defined(MBEDTLS_ECP_ADD_MIXED_ALT) + if ( mbedtls_internal_ecp_grp_capable( grp ) ) + { + return mbedtls_internal_ecp_add_mixed( grp, R, P, Q ); + } +#endif /* MBEDTLS_ECP_ADD_MIXED_ALT */ + + /* + * Trivial cases: P == 0 or Q == 0 (case 1) + */ + if( mbedtls_mpi_cmp_int( &P->Z, 0 ) == 0 ) + return( mbedtls_ecp_copy( R, Q ) ); + + if( Q->Z.p != NULL && mbedtls_mpi_cmp_int( &Q->Z, 0 ) == 0 ) + return( mbedtls_ecp_copy( R, P ) ); + + /* + * Make sure Q coordinates are normalized + */ + if( Q->Z.p != NULL && mbedtls_mpi_cmp_int( &Q->Z, 1 ) != 0 ) + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + + mbedtls_mpi_init( &T1 ); mbedtls_mpi_init( &T2 ); mbedtls_mpi_init( &T3 ); mbedtls_mpi_init( &T4 ); + mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T1, &P->Z, &P->Z ) ); MOD_MUL( T1 ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T2, &T1, &P->Z ) ); MOD_MUL( T2 ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T1, &T1, &Q->X ) ); MOD_MUL( T1 ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T2, &T2, &Q->Y ) ); MOD_MUL( T2 ); + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T1, &T1, &P->X ) ); MOD_SUB( T1 ); + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T2, &T2, &P->Y ) ); MOD_SUB( T2 ); + + /* Special cases (2) and (3) */ + if( mbedtls_mpi_cmp_int( &T1, 0 ) == 0 ) + { + if( mbedtls_mpi_cmp_int( &T2, 0 ) == 0 ) + { + ret = ecp_double_jac( grp, R, P ); + goto cleanup; + } + else + { + ret = mbedtls_ecp_set_zero( R ); + goto cleanup; + } + } + + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &Z, &P->Z, &T1 ) ); MOD_MUL( Z ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T3, &T1, &T1 ) ); MOD_MUL( T3 ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T4, &T3, &T1 ) ); MOD_MUL( T4 ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T3, &T3, &P->X ) ); MOD_MUL( T3 ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T1, &T3, 2 ) ); MOD_ADD( T1 ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &X, &T2, &T2 ) ); MOD_MUL( X ); + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &X, &X, &T1 ) ); MOD_SUB( X ); + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &X, &X, &T4 ) ); MOD_SUB( X ); + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T3, &T3, &X ) ); MOD_SUB( T3 ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T3, &T3, &T2 ) ); MOD_MUL( T3 ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T4, &T4, &P->Y ) ); MOD_MUL( T4 ); + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &Y, &T3, &T4 ) ); MOD_SUB( Y ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->X, &X ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->Y, &Y ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R->Z, &Z ) ); + +cleanup: + + mbedtls_mpi_free( &T1 ); mbedtls_mpi_free( &T2 ); mbedtls_mpi_free( &T3 ); mbedtls_mpi_free( &T4 ); + mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z ); + + return( ret ); +} + +/* + * Randomize jacobian coordinates: + * (X, Y, Z) -> (l^2 X, l^3 Y, l Z) for random l + * This is sort of the reverse operation of ecp_normalize_jac(). + * + * This countermeasure was first suggested in [2]. + */ +static int ecp_randomize_jac( const mbedtls_ecp_group *grp, mbedtls_ecp_point *pt, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + int ret; + mbedtls_mpi l, ll; + size_t p_size; + int count = 0; + +#if defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT) + if ( mbedtls_internal_ecp_grp_capable( grp ) ) + { + return mbedtls_internal_ecp_randomize_jac( grp, pt, f_rng, p_rng ); + } +#endif /* MBEDTLS_ECP_RANDOMIZE_JAC_ALT */ + + p_size = ( grp->pbits + 7 ) / 8; + mbedtls_mpi_init( &l ); mbedtls_mpi_init( &ll ); + + /* Generate l such that 1 < l < p */ + do + { + mbedtls_mpi_fill_random( &l, p_size, f_rng, p_rng ); + + while( mbedtls_mpi_cmp_mpi( &l, &grp->P ) >= 0 ) + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &l, 1 ) ); + + if( count++ > 10 ) + return( MBEDTLS_ERR_ECP_RANDOM_FAILED ); + } + while( mbedtls_mpi_cmp_int( &l, 1 ) <= 0 ); + + /* Z = l * Z */ + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->Z, &pt->Z, &l ) ); MOD_MUL( pt->Z ); + + /* X = l^2 * X */ + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ll, &l, &l ) ); MOD_MUL( ll ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->X, &pt->X, &ll ) ); MOD_MUL( pt->X ); + + /* Y = l^3 * Y */ + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ll, &ll, &l ) ); MOD_MUL( ll ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &pt->Y, &pt->Y, &ll ) ); MOD_MUL( pt->Y ); + +cleanup: + mbedtls_mpi_free( &l ); mbedtls_mpi_free( &ll ); + + return( ret ); +} + +/* + * Check and define parameters used by the comb method (see below for details) + */ +#if MBEDTLS_ECP_WINDOW_SIZE < 2 || MBEDTLS_ECP_WINDOW_SIZE > 7 +#error "MBEDTLS_ECP_WINDOW_SIZE out of bounds" +#endif + +/* d = ceil( n / w ) */ +#define COMB_MAX_D ( MBEDTLS_ECP_MAX_BITS + 1 ) / 2 + +/* number of precomputed points */ +#define COMB_MAX_PRE ( 1 << ( MBEDTLS_ECP_WINDOW_SIZE - 1 ) ) + +/* + * Compute the representation of m that will be used with our comb method. + * + * The basic comb method is described in GECC 3.44 for example. We use a + * modified version that provides resistance to SPA by avoiding zero + * digits in the representation as in [3]. We modify the method further by + * requiring that all K_i be odd, which has the small cost that our + * representation uses one more K_i, due to carries. + * + * Also, for the sake of compactness, only the seven low-order bits of x[i] + * are used to represent K_i, and the msb of x[i] encodes the the sign (s_i in + * the paper): it is set if and only if if s_i == -1; + * + * Calling conventions: + * - x is an array of size d + 1 + * - w is the size, ie number of teeth, of the comb, and must be between + * 2 and 7 (in practice, between 2 and MBEDTLS_ECP_WINDOW_SIZE) + * - m is the MPI, expected to be odd and such that bitlength(m) <= w * d + * (the result will be incorrect if these assumptions are not satisfied) + */ +static void ecp_comb_fixed( unsigned char x[], size_t d, + unsigned char w, const mbedtls_mpi *m ) +{ + size_t i, j; + unsigned char c, cc, adjust; + + memset( x, 0, d+1 ); + + /* First get the classical comb values (except for x_d = 0) */ + for( i = 0; i < d; i++ ) + for( j = 0; j < w; j++ ) + x[i] |= mbedtls_mpi_get_bit( m, i + d * j ) << j; + + /* Now make sure x_1 .. x_d are odd */ + c = 0; + for( i = 1; i <= d; i++ ) + { + /* Add carry and update it */ + cc = x[i] & c; + x[i] = x[i] ^ c; + c = cc; + + /* Adjust if needed, avoiding branches */ + adjust = 1 - ( x[i] & 0x01 ); + c |= x[i] & ( x[i-1] * adjust ); + x[i] = x[i] ^ ( x[i-1] * adjust ); + x[i-1] |= adjust << 7; + } +} + +/* + * Precompute points for the comb method + * + * If i = i_{w-1} ... i_1 is the binary representation of i, then + * T[i] = i_{w-1} 2^{(w-1)d} P + ... + i_1 2^d P + P + * + * T must be able to hold 2^{w - 1} elements + * + * Cost: d(w-1) D + (2^{w-1} - 1) A + 1 N(w-1) + 1 N(2^{w-1} - 1) + */ +static int ecp_precompute_comb( const mbedtls_ecp_group *grp, + mbedtls_ecp_point T[], const mbedtls_ecp_point *P, + unsigned char w, size_t d ) +{ + int ret; + unsigned char i, k; + size_t j; + mbedtls_ecp_point *cur, *TT[COMB_MAX_PRE - 1]; + + /* + * Set T[0] = P and + * T[2^{l-1}] = 2^{dl} P for l = 1 .. w-1 (this is not the final value) + */ + MBEDTLS_MPI_CHK( mbedtls_ecp_copy( &T[0], P ) ); + + k = 0; + for( i = 1; i < ( 1U << ( w - 1 ) ); i <<= 1 ) + { + cur = T + i; + MBEDTLS_MPI_CHK( mbedtls_ecp_copy( cur, T + ( i >> 1 ) ) ); + for( j = 0; j < d; j++ ) + MBEDTLS_MPI_CHK( ecp_double_jac( grp, cur, cur ) ); + + TT[k++] = cur; + } + + MBEDTLS_MPI_CHK( ecp_normalize_jac_many( grp, TT, k ) ); + + /* + * Compute the remaining ones using the minimal number of additions + * Be careful to update T[2^l] only after using it! + */ + k = 0; + for( i = 1; i < ( 1U << ( w - 1 ) ); i <<= 1 ) + { + j = i; + while( j-- ) + { + MBEDTLS_MPI_CHK( ecp_add_mixed( grp, &T[i + j], &T[j], &T[i] ) ); + TT[k++] = &T[i + j]; + } + } + + MBEDTLS_MPI_CHK( ecp_normalize_jac_many( grp, TT, k ) ); + +cleanup: + + return( ret ); +} + +/* + * Select precomputed point: R = sign(i) * T[ abs(i) / 2 ] + */ +static int ecp_select_comb( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, + const mbedtls_ecp_point T[], unsigned char t_len, + unsigned char i ) +{ + int ret; + unsigned char ii, j; + + /* Ignore the "sign" bit and scale down */ + ii = ( i & 0x7Fu ) >> 1; + + /* Read the whole table to thwart cache-based timing attacks */ + for( j = 0; j < t_len; j++ ) + { + MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( &R->X, &T[j].X, j == ii ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( &R->Y, &T[j].Y, j == ii ) ); + } + + /* Safely invert result if i is "negative" */ + MBEDTLS_MPI_CHK( ecp_safe_invert_jac( grp, R, i >> 7 ) ); + +cleanup: + return( ret ); +} + +/* + * Core multiplication algorithm for the (modified) comb method. + * This part is actually common with the basic comb method (GECC 3.44) + * + * Cost: d A + d D + 1 R + */ +static int ecp_mul_comb_core( const mbedtls_ecp_group *grp, mbedtls_ecp_point *R, + const mbedtls_ecp_point T[], unsigned char t_len, + const unsigned char x[], size_t d, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + mbedtls_ecp_point Txi; + size_t i; + + mbedtls_ecp_point_init( &Txi ); + + /* Start with a non-zero point and randomize its coordinates */ + i = d; + MBEDTLS_MPI_CHK( ecp_select_comb( grp, R, T, t_len, x[i] ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &R->Z, 1 ) ); + if( f_rng != 0 ) + MBEDTLS_MPI_CHK( ecp_randomize_jac( grp, R, f_rng, p_rng ) ); + + while( i-- != 0 ) + { + MBEDTLS_MPI_CHK( ecp_double_jac( grp, R, R ) ); + MBEDTLS_MPI_CHK( ecp_select_comb( grp, &Txi, T, t_len, x[i] ) ); + MBEDTLS_MPI_CHK( ecp_add_mixed( grp, R, R, &Txi ) ); + } + +cleanup: + + mbedtls_ecp_point_free( &Txi ); + + return( ret ); +} + +/* + * Multiplication using the comb method, + * for curves in short Weierstrass form + */ +static int ecp_mul_comb( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, + const mbedtls_mpi *m, const mbedtls_ecp_point *P, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + unsigned char w, m_is_odd, p_eq_g, pre_len, i; + size_t d; + unsigned char k[COMB_MAX_D + 1]; + mbedtls_ecp_point *T; + mbedtls_mpi M, mm; + + mbedtls_mpi_init( &M ); + mbedtls_mpi_init( &mm ); + + /* we need N to be odd to trnaform m in an odd number, check now */ + if( mbedtls_mpi_get_bit( &grp->N, 0 ) != 1 ) + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + + /* + * Minimize the number of multiplications, that is minimize + * 10 * d * w + 18 * 2^(w-1) + 11 * d + 7 * w, with d = ceil( nbits / w ) + * (see costs of the various parts, with 1S = 1M) + */ + w = grp->nbits >= 384 ? 5 : 4; + + /* + * If P == G, pre-compute a bit more, since this may be re-used later. + * Just adding one avoids upping the cost of the first mul too much, + * and the memory cost too. + */ +#if MBEDTLS_ECP_FIXED_POINT_OPTIM == 1 + p_eq_g = ( mbedtls_mpi_cmp_mpi( &P->Y, &grp->G.Y ) == 0 && + mbedtls_mpi_cmp_mpi( &P->X, &grp->G.X ) == 0 ); + if( p_eq_g ) + w++; +#else + p_eq_g = 0; +#endif + + /* + * Make sure w is within bounds. + * (The last test is useful only for very small curves in the test suite.) + */ + if( w > MBEDTLS_ECP_WINDOW_SIZE ) + w = MBEDTLS_ECP_WINDOW_SIZE; + if( w >= grp->nbits ) + w = 2; + + /* Other sizes that depend on w */ + pre_len = 1U << ( w - 1 ); + d = ( grp->nbits + w - 1 ) / w; + + /* + * Prepare precomputed points: if P == G we want to + * use grp->T if already initialized, or initialize it. + */ + T = p_eq_g ? grp->T : NULL; + + if( T == NULL ) + { + T = mbedtls_calloc( pre_len, sizeof( mbedtls_ecp_point ) ); + if( T == NULL ) + { + ret = MBEDTLS_ERR_ECP_ALLOC_FAILED; + goto cleanup; + } + + MBEDTLS_MPI_CHK( ecp_precompute_comb( grp, T, P, w, d ) ); + + if( p_eq_g ) + { + grp->T = T; + grp->T_size = pre_len; + } + } + + /* + * Make sure M is odd (M = m or M = N - m, since N is odd) + * using the fact that m * P = - (N - m) * P + */ + m_is_odd = ( mbedtls_mpi_get_bit( m, 0 ) == 1 ); + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &M, m ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &mm, &grp->N, m ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( &M, &mm, ! m_is_odd ) ); + + /* + * Go for comb multiplication, R = M * P + */ + ecp_comb_fixed( k, d, w, &M ); + MBEDTLS_MPI_CHK( ecp_mul_comb_core( grp, R, T, pre_len, k, d, f_rng, p_rng ) ); + + /* + * Now get m * P from M * P and normalize it + */ + MBEDTLS_MPI_CHK( ecp_safe_invert_jac( grp, R, ! m_is_odd ) ); + MBEDTLS_MPI_CHK( ecp_normalize_jac( grp, R ) ); + +cleanup: + + if( T != NULL && ! p_eq_g ) + { + for( i = 0; i < pre_len; i++ ) + mbedtls_ecp_point_free( &T[i] ); + mbedtls_free( T ); + } + + mbedtls_mpi_free( &M ); + mbedtls_mpi_free( &mm ); + + if( ret != 0 ) + mbedtls_ecp_point_free( R ); + + return( ret ); +} + +#endif /* ECP_SHORTWEIERSTRASS */ + +#if defined(ECP_MONTGOMERY) +/* + * For Montgomery curves, we do all the internal arithmetic in projective + * coordinates. Import/export of points uses only the x coordinates, which is + * internaly represented as X / Z. + * + * For scalar multiplication, we'll use a Montgomery ladder. + */ + +/* + * Normalize Montgomery x/z coordinates: X = X/Z, Z = 1 + * Cost: 1M + 1I + */ +static int ecp_normalize_mxz( const mbedtls_ecp_group *grp, mbedtls_ecp_point *P ) +{ + int ret; + +#if defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT) + if ( mbedtls_internal_ecp_grp_capable( grp ) ) + { + return mbedtls_internal_ecp_normalize_mxz( grp, P ); + } +#endif /* MBEDTLS_ECP_NORMALIZE_MXZ_ALT */ + + MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &P->Z, &P->Z, &grp->P ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &P->X, &P->X, &P->Z ) ); MOD_MUL( P->X ); + MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &P->Z, 1 ) ); + +cleanup: + return( ret ); +} + +/* + * Randomize projective x/z coordinates: + * (X, Z) -> (l X, l Z) for random l + * This is sort of the reverse operation of ecp_normalize_mxz(). + * + * This countermeasure was first suggested in [2]. + * Cost: 2M + */ +static int ecp_randomize_mxz( const mbedtls_ecp_group *grp, mbedtls_ecp_point *P, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + int ret; + mbedtls_mpi l; + size_t p_size; + int count = 0; + +#if defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT) + if ( mbedtls_internal_ecp_grp_capable( grp ) ) + { + return mbedtls_internal_ecp_randomize_mxz( grp, P, f_rng, p_rng ); + } +#endif /* MBEDTLS_ECP_RANDOMIZE_MXZ_ALT */ + + p_size = ( grp->pbits + 7 ) / 8; + mbedtls_mpi_init( &l ); + + /* Generate l such that 1 < l < p */ + do + { + mbedtls_mpi_fill_random( &l, p_size, f_rng, p_rng ); + + while( mbedtls_mpi_cmp_mpi( &l, &grp->P ) >= 0 ) + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &l, 1 ) ); + + if( count++ > 10 ) + return( MBEDTLS_ERR_ECP_RANDOM_FAILED ); + } + while( mbedtls_mpi_cmp_int( &l, 1 ) <= 0 ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &P->X, &P->X, &l ) ); MOD_MUL( P->X ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &P->Z, &P->Z, &l ) ); MOD_MUL( P->Z ); + +cleanup: + mbedtls_mpi_free( &l ); + + return( ret ); +} + +/* + * Double-and-add: R = 2P, S = P + Q, with d = X(P - Q), + * for Montgomery curves in x/z coordinates. + * + * http://www.hyperelliptic.org/EFD/g1p/auto-code/montgom/xz/ladder/mladd-1987-m.op3 + * with + * d = X1 + * P = (X2, Z2) + * Q = (X3, Z3) + * R = (X4, Z4) + * S = (X5, Z5) + * and eliminating temporary variables tO, ..., t4. + * + * Cost: 5M + 4S + */ +static int ecp_double_add_mxz( const mbedtls_ecp_group *grp, + mbedtls_ecp_point *R, mbedtls_ecp_point *S, + const mbedtls_ecp_point *P, const mbedtls_ecp_point *Q, + const mbedtls_mpi *d ) +{ + int ret; + mbedtls_mpi A, AA, B, BB, E, C, D, DA, CB; + +#if defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT) + if ( mbedtls_internal_ecp_grp_capable( grp ) ) + { + return mbedtls_internal_ecp_double_add_mxz( grp, R, S, P, Q, d ); + } +#endif /* MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT */ + + mbedtls_mpi_init( &A ); mbedtls_mpi_init( &AA ); mbedtls_mpi_init( &B ); + mbedtls_mpi_init( &BB ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &C ); + mbedtls_mpi_init( &D ); mbedtls_mpi_init( &DA ); mbedtls_mpi_init( &CB ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &A, &P->X, &P->Z ) ); MOD_ADD( A ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &AA, &A, &A ) ); MOD_MUL( AA ); + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &B, &P->X, &P->Z ) ); MOD_SUB( B ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &BB, &B, &B ) ); MOD_MUL( BB ); + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &E, &AA, &BB ) ); MOD_SUB( E ); + MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &C, &Q->X, &Q->Z ) ); MOD_ADD( C ); + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &D, &Q->X, &Q->Z ) ); MOD_SUB( D ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DA, &D, &A ) ); MOD_MUL( DA ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &CB, &C, &B ) ); MOD_MUL( CB ); + MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &S->X, &DA, &CB ) ); MOD_MUL( S->X ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S->X, &S->X, &S->X ) ); MOD_MUL( S->X ); + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &S->Z, &DA, &CB ) ); MOD_SUB( S->Z ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S->Z, &S->Z, &S->Z ) ); MOD_MUL( S->Z ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &S->Z, d, &S->Z ) ); MOD_MUL( S->Z ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &R->X, &AA, &BB ) ); MOD_MUL( R->X ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &R->Z, &grp->A, &E ) ); MOD_MUL( R->Z ); + MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &R->Z, &BB, &R->Z ) ); MOD_ADD( R->Z ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &R->Z, &E, &R->Z ) ); MOD_MUL( R->Z ); + +cleanup: + mbedtls_mpi_free( &A ); mbedtls_mpi_free( &AA ); mbedtls_mpi_free( &B ); + mbedtls_mpi_free( &BB ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &C ); + mbedtls_mpi_free( &D ); mbedtls_mpi_free( &DA ); mbedtls_mpi_free( &CB ); + + return( ret ); +} + +/* + * Multiplication with Montgomery ladder in x/z coordinates, + * for curves in Montgomery form + */ +static int ecp_mul_mxz( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, + const mbedtls_mpi *m, const mbedtls_ecp_point *P, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + size_t i; + unsigned char b; + mbedtls_ecp_point RP; + mbedtls_mpi PX; + + mbedtls_ecp_point_init( &RP ); mbedtls_mpi_init( &PX ); + + /* Save PX and read from P before writing to R, in case P == R */ + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &PX, &P->X ) ); + MBEDTLS_MPI_CHK( mbedtls_ecp_copy( &RP, P ) ); + + /* Set R to zero in modified x/z coordinates */ + MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &R->X, 1 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &R->Z, 0 ) ); + mbedtls_mpi_free( &R->Y ); + + /* RP.X might be sligtly larger than P, so reduce it */ + MOD_ADD( RP.X ); + + /* Randomize coordinates of the starting point */ + if( f_rng != NULL ) + MBEDTLS_MPI_CHK( ecp_randomize_mxz( grp, &RP, f_rng, p_rng ) ); + + /* Loop invariant: R = result so far, RP = R + P */ + i = mbedtls_mpi_bitlen( m ); /* one past the (zero-based) most significant bit */ + while( i-- > 0 ) + { + b = mbedtls_mpi_get_bit( m, i ); + /* + * if (b) R = 2R + P else R = 2R, + * which is: + * if (b) double_add( RP, R, RP, R ) + * else double_add( R, RP, R, RP ) + * but using safe conditional swaps to avoid leaks + */ + MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_swap( &R->X, &RP.X, b ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_swap( &R->Z, &RP.Z, b ) ); + MBEDTLS_MPI_CHK( ecp_double_add_mxz( grp, R, &RP, R, &RP, &PX ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_swap( &R->X, &RP.X, b ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_swap( &R->Z, &RP.Z, b ) ); + } + + MBEDTLS_MPI_CHK( ecp_normalize_mxz( grp, R ) ); + +cleanup: + mbedtls_ecp_point_free( &RP ); mbedtls_mpi_free( &PX ); + + return( ret ); +} + +#endif /* ECP_MONTGOMERY */ + +/* + * Multiplication R = m * P + */ +int mbedtls_ecp_mul( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, + const mbedtls_mpi *m, const mbedtls_ecp_point *P, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + int ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; +#if defined(MBEDTLS_ECP_INTERNAL_ALT) + char is_grp_capable = 0; +#endif + + /* Common sanity checks */ + if( mbedtls_mpi_cmp_int( &P->Z, 1 ) != 0 ) + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + + if( ( ret = mbedtls_ecp_check_privkey( grp, m ) ) != 0 || + ( ret = mbedtls_ecp_check_pubkey( grp, P ) ) != 0 ) + return( ret ); + +#if defined(MBEDTLS_ECP_INTERNAL_ALT) +#if defined(MBEDTLS_THREADING_C) + if( mbedtls_mutex_lock( &mbedtls_threading_ecp_mutex ) != 0 ) + return ( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); + +#endif + if ( is_grp_capable = mbedtls_internal_ecp_grp_capable( grp ) ) + { + MBEDTLS_MPI_CHK( mbedtls_internal_ecp_init( grp ) ); + } + +#endif /* MBEDTLS_ECP_INTERNAL_ALT */ +#if defined(ECP_MONTGOMERY) + if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY ) + ret = ecp_mul_mxz( grp, R, m, P, f_rng, p_rng ); + +#endif +#if defined(ECP_SHORTWEIERSTRASS) + if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS ) + ret = ecp_mul_comb( grp, R, m, P, f_rng, p_rng ); + +#endif +#if defined(MBEDTLS_ECP_INTERNAL_ALT) +cleanup: + + if ( is_grp_capable ) + { + mbedtls_internal_ecp_free( grp ); + } + +#if defined(MBEDTLS_THREADING_C) + if( mbedtls_mutex_unlock( &mbedtls_threading_ecp_mutex ) != 0 ) + return ( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); + +#endif +#endif /* MBEDTLS_ECP_INTERNAL_ALT */ + return( ret ); +} + +#if defined(ECP_SHORTWEIERSTRASS) +/* + * Check that an affine point is valid as a public key, + * short weierstrass curves (SEC1 3.2.3.1) + */ +static int ecp_check_pubkey_sw( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt ) +{ + int ret; + mbedtls_mpi YY, RHS; + + /* pt coordinates must be normalized for our checks */ + if( mbedtls_mpi_cmp_int( &pt->X, 0 ) < 0 || + mbedtls_mpi_cmp_int( &pt->Y, 0 ) < 0 || + mbedtls_mpi_cmp_mpi( &pt->X, &grp->P ) >= 0 || + mbedtls_mpi_cmp_mpi( &pt->Y, &grp->P ) >= 0 ) + return( MBEDTLS_ERR_ECP_INVALID_KEY ); + + mbedtls_mpi_init( &YY ); mbedtls_mpi_init( &RHS ); + + /* + * YY = Y^2 + * RHS = X (X^2 + A) + B = X^3 + A X + B + */ + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &YY, &pt->Y, &pt->Y ) ); MOD_MUL( YY ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &RHS, &pt->X, &pt->X ) ); MOD_MUL( RHS ); + + /* Special case for A = -3 */ + if( grp->A.p == NULL ) + { + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &RHS, &RHS, 3 ) ); MOD_SUB( RHS ); + } + else + { + MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &RHS, &RHS, &grp->A ) ); MOD_ADD( RHS ); + } + + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &RHS, &RHS, &pt->X ) ); MOD_MUL( RHS ); + MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &RHS, &RHS, &grp->B ) ); MOD_ADD( RHS ); + + if( mbedtls_mpi_cmp_mpi( &YY, &RHS ) != 0 ) + ret = MBEDTLS_ERR_ECP_INVALID_KEY; + +cleanup: + + mbedtls_mpi_free( &YY ); mbedtls_mpi_free( &RHS ); + + return( ret ); +} +#endif /* ECP_SHORTWEIERSTRASS */ + +/* + * R = m * P with shortcuts for m == 1 and m == -1 + * NOT constant-time - ONLY for short Weierstrass! + */ +static int mbedtls_ecp_mul_shortcuts( mbedtls_ecp_group *grp, + mbedtls_ecp_point *R, + const mbedtls_mpi *m, + const mbedtls_ecp_point *P ) +{ + int ret; + + if( mbedtls_mpi_cmp_int( m, 1 ) == 0 ) + { + MBEDTLS_MPI_CHK( mbedtls_ecp_copy( R, P ) ); + } + else if( mbedtls_mpi_cmp_int( m, -1 ) == 0 ) + { + MBEDTLS_MPI_CHK( mbedtls_ecp_copy( R, P ) ); + if( mbedtls_mpi_cmp_int( &R->Y, 0 ) != 0 ) + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &R->Y, &grp->P, &R->Y ) ); + } + else + { + MBEDTLS_MPI_CHK( mbedtls_ecp_mul( grp, R, m, P, NULL, NULL ) ); + } + +cleanup: + return( ret ); +} + +/* + * Linear combination + * NOT constant-time + */ +int mbedtls_ecp_muladd( mbedtls_ecp_group *grp, mbedtls_ecp_point *R, + const mbedtls_mpi *m, const mbedtls_ecp_point *P, + const mbedtls_mpi *n, const mbedtls_ecp_point *Q ) +{ + int ret; + mbedtls_ecp_point mP; +#if defined(MBEDTLS_ECP_INTERNAL_ALT) + char is_grp_capable = 0; +#endif + + if( ecp_get_type( grp ) != ECP_TYPE_SHORT_WEIERSTRASS ) + return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ); + + mbedtls_ecp_point_init( &mP ); + + MBEDTLS_MPI_CHK( mbedtls_ecp_mul_shortcuts( grp, &mP, m, P ) ); + MBEDTLS_MPI_CHK( mbedtls_ecp_mul_shortcuts( grp, R, n, Q ) ); + +#if defined(MBEDTLS_ECP_INTERNAL_ALT) +#if defined(MBEDTLS_THREADING_C) + if( mbedtls_mutex_lock( &mbedtls_threading_ecp_mutex ) != 0 ) + return ( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); + +#endif + if ( is_grp_capable = mbedtls_internal_ecp_grp_capable( grp ) ) + { + MBEDTLS_MPI_CHK( mbedtls_internal_ecp_init( grp ) ); + } + +#endif /* MBEDTLS_ECP_INTERNAL_ALT */ + MBEDTLS_MPI_CHK( ecp_add_mixed( grp, R, &mP, R ) ); + MBEDTLS_MPI_CHK( ecp_normalize_jac( grp, R ) ); + +cleanup: + +#if defined(MBEDTLS_ECP_INTERNAL_ALT) + if ( is_grp_capable ) + { + mbedtls_internal_ecp_free( grp ); + } + +#if defined(MBEDTLS_THREADING_C) + if( mbedtls_mutex_unlock( &mbedtls_threading_ecp_mutex ) != 0 ) + return ( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); + +#endif +#endif /* MBEDTLS_ECP_INTERNAL_ALT */ + mbedtls_ecp_point_free( &mP ); + + return( ret ); +} + + +#if defined(ECP_MONTGOMERY) +/* + * Check validity of a public key for Montgomery curves with x-only schemes + */ +static int ecp_check_pubkey_mx( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt ) +{ + /* [Curve25519 p. 5] Just check X is the correct number of bytes */ + if( mbedtls_mpi_size( &pt->X ) > ( grp->nbits + 7 ) / 8 ) + return( MBEDTLS_ERR_ECP_INVALID_KEY ); + + return( 0 ); +} +#endif /* ECP_MONTGOMERY */ + +/* + * Check that a point is valid as a public key + */ +int mbedtls_ecp_check_pubkey( const mbedtls_ecp_group *grp, const mbedtls_ecp_point *pt ) +{ + /* Must use affine coordinates */ + if( mbedtls_mpi_cmp_int( &pt->Z, 1 ) != 0 ) + return( MBEDTLS_ERR_ECP_INVALID_KEY ); + +#if defined(ECP_MONTGOMERY) + if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY ) + return( ecp_check_pubkey_mx( grp, pt ) ); +#endif +#if defined(ECP_SHORTWEIERSTRASS) + if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS ) + return( ecp_check_pubkey_sw( grp, pt ) ); +#endif + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); +} + +/* + * Check that an mbedtls_mpi is valid as a private key + */ +int mbedtls_ecp_check_privkey( const mbedtls_ecp_group *grp, const mbedtls_mpi *d ) +{ +#if defined(ECP_MONTGOMERY) + if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY ) + { + /* see [Curve25519] page 5 */ + if( mbedtls_mpi_get_bit( d, 0 ) != 0 || + mbedtls_mpi_get_bit( d, 1 ) != 0 || + mbedtls_mpi_get_bit( d, 2 ) != 0 || + mbedtls_mpi_bitlen( d ) - 1 != grp->nbits ) /* mbedtls_mpi_bitlen is one-based! */ + return( MBEDTLS_ERR_ECP_INVALID_KEY ); + else + return( 0 ); + } +#endif /* ECP_MONTGOMERY */ +#if defined(ECP_SHORTWEIERSTRASS) + if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS ) + { + /* see SEC1 3.2 */ + if( mbedtls_mpi_cmp_int( d, 1 ) < 0 || + mbedtls_mpi_cmp_mpi( d, &grp->N ) >= 0 ) + return( MBEDTLS_ERR_ECP_INVALID_KEY ); + else + return( 0 ); + } +#endif /* ECP_SHORTWEIERSTRASS */ + + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); +} + +/* + * Generate a keypair with configurable base point + */ +int mbedtls_ecp_gen_keypair_base( mbedtls_ecp_group *grp, + const mbedtls_ecp_point *G, + mbedtls_mpi *d, mbedtls_ecp_point *Q, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + size_t n_size = ( grp->nbits + 7 ) / 8; + +#if defined(ECP_MONTGOMERY) + if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY ) + { + /* [M225] page 5 */ + size_t b; + + do { + MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( d, n_size, f_rng, p_rng ) ); + } while( mbedtls_mpi_bitlen( d ) == 0); + + /* Make sure the most significant bit is nbits */ + b = mbedtls_mpi_bitlen( d ) - 1; /* mbedtls_mpi_bitlen is one-based */ + if( b > grp->nbits ) + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( d, b - grp->nbits ) ); + else + MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, grp->nbits, 1 ) ); + + /* Make sure the last three bits are unset */ + MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 0, 0 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 1, 0 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 2, 0 ) ); + } + else +#endif /* ECP_MONTGOMERY */ +#if defined(ECP_SHORTWEIERSTRASS) + if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS ) + { + /* SEC1 3.2.1: Generate d such that 1 <= n < N */ + int count = 0; + unsigned char rnd[MBEDTLS_ECP_MAX_BYTES]; + + /* + * Match the procedure given in RFC 6979 (deterministic ECDSA): + * - use the same byte ordering; + * - keep the leftmost nbits bits of the generated octet string; + * - try until result is in the desired range. + * This also avoids any biais, which is especially important for ECDSA. + */ + do + { + MBEDTLS_MPI_CHK( f_rng( p_rng, rnd, n_size ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( d, rnd, n_size ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( d, 8 * n_size - grp->nbits ) ); + + /* + * Each try has at worst a probability 1/2 of failing (the msb has + * a probability 1/2 of being 0, and then the result will be < N), + * so after 30 tries failure probability is a most 2**(-30). + * + * For most curves, 1 try is enough with overwhelming probability, + * since N starts with a lot of 1s in binary, but some curves + * such as secp224k1 are actually very close to the worst case. + */ + if( ++count > 30 ) + return( MBEDTLS_ERR_ECP_RANDOM_FAILED ); + } + while( mbedtls_mpi_cmp_int( d, 1 ) < 0 || + mbedtls_mpi_cmp_mpi( d, &grp->N ) >= 0 ); + } + else +#endif /* ECP_SHORTWEIERSTRASS */ + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + +cleanup: + if( ret != 0 ) + return( ret ); + + return( mbedtls_ecp_mul( grp, Q, d, G, f_rng, p_rng ) ); +} + +/* + * Generate key pair, wrapper for conventional base point + */ +int mbedtls_ecp_gen_keypair( mbedtls_ecp_group *grp, + mbedtls_mpi *d, mbedtls_ecp_point *Q, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + return( mbedtls_ecp_gen_keypair_base( grp, &grp->G, d, Q, f_rng, p_rng ) ); +} + +/* + * Generate a keypair, prettier wrapper + */ +int mbedtls_ecp_gen_key( mbedtls_ecp_group_id grp_id, mbedtls_ecp_keypair *key, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + int ret; + + if( ( ret = mbedtls_ecp_group_load( &key->grp, grp_id ) ) != 0 ) + return( ret ); + + return( mbedtls_ecp_gen_keypair( &key->grp, &key->d, &key->Q, f_rng, p_rng ) ); +} + +/* + * Check a public-private key pair + */ +int mbedtls_ecp_check_pub_priv( const mbedtls_ecp_keypair *pub, const mbedtls_ecp_keypair *prv ) +{ + int ret; + mbedtls_ecp_point Q; + mbedtls_ecp_group grp; + + if( pub->grp.id == MBEDTLS_ECP_DP_NONE || + pub->grp.id != prv->grp.id || + mbedtls_mpi_cmp_mpi( &pub->Q.X, &prv->Q.X ) || + mbedtls_mpi_cmp_mpi( &pub->Q.Y, &prv->Q.Y ) || + mbedtls_mpi_cmp_mpi( &pub->Q.Z, &prv->Q.Z ) ) + { + return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); + } + + mbedtls_ecp_point_init( &Q ); + mbedtls_ecp_group_init( &grp ); + + /* mbedtls_ecp_mul() needs a non-const group... */ + mbedtls_ecp_group_copy( &grp, &prv->grp ); + + /* Also checks d is valid */ + MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &Q, &prv->d, &prv->grp.G, NULL, NULL ) ); + + if( mbedtls_mpi_cmp_mpi( &Q.X, &prv->Q.X ) || + mbedtls_mpi_cmp_mpi( &Q.Y, &prv->Q.Y ) || + mbedtls_mpi_cmp_mpi( &Q.Z, &prv->Q.Z ) ) + { + ret = MBEDTLS_ERR_ECP_BAD_INPUT_DATA; + goto cleanup; + } + +cleanup: + mbedtls_ecp_point_free( &Q ); + mbedtls_ecp_group_free( &grp ); + + return( ret ); +} + +#if defined(MBEDTLS_SELF_TEST) + +/* + * Checkup routine + */ +int mbedtls_ecp_self_test( int verbose ) +{ + int ret; + size_t i; + mbedtls_ecp_group grp; + mbedtls_ecp_point R, P; + mbedtls_mpi m; + unsigned long add_c_prev, dbl_c_prev, mul_c_prev; + /* exponents especially adapted for secp192r1 */ + const char *exponents[] = + { + "000000000000000000000000000000000000000000000001", /* one */ + "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22830", /* N - 1 */ + "5EA6F389A38B8BC81E767753B15AA5569E1782E30ABE7D25", /* random */ + "400000000000000000000000000000000000000000000000", /* one and zeros */ + "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", /* all ones */ + "555555555555555555555555555555555555555555555555", /* 101010... */ + }; + + mbedtls_ecp_group_init( &grp ); + mbedtls_ecp_point_init( &R ); + mbedtls_ecp_point_init( &P ); + mbedtls_mpi_init( &m ); + + /* Use secp192r1 if available, or any available curve */ +#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) + MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &grp, MBEDTLS_ECP_DP_SECP192R1 ) ); +#else + MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &grp, mbedtls_ecp_curve_list()->grp_id ) ); +#endif + + if( verbose != 0 ) + mbedtls_printf( " ECP test #1 (constant op_count, base point G): " ); + + /* Do a dummy multiplication first to trigger precomputation */ + MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &m, 2 ) ); + MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &P, &m, &grp.G, NULL, NULL ) ); + + add_count = 0; + dbl_count = 0; + mul_count = 0; + MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &m, 16, exponents[0] ) ); + MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &R, &m, &grp.G, NULL, NULL ) ); + + for( i = 1; i < sizeof( exponents ) / sizeof( exponents[0] ); i++ ) + { + add_c_prev = add_count; + dbl_c_prev = dbl_count; + mul_c_prev = mul_count; + add_count = 0; + dbl_count = 0; + mul_count = 0; + + MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &m, 16, exponents[i] ) ); + MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &R, &m, &grp.G, NULL, NULL ) ); + + if( add_count != add_c_prev || + dbl_count != dbl_c_prev || + mul_count != mul_c_prev ) + { + if( verbose != 0 ) + mbedtls_printf( "failed (%u)\n", (unsigned int) i ); + + ret = 1; + goto cleanup; + } + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + + if( verbose != 0 ) + mbedtls_printf( " ECP test #2 (constant op_count, other point): " ); + /* We computed P = 2G last time, use it */ + + add_count = 0; + dbl_count = 0; + mul_count = 0; + MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &m, 16, exponents[0] ) ); + MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &R, &m, &P, NULL, NULL ) ); + + for( i = 1; i < sizeof( exponents ) / sizeof( exponents[0] ); i++ ) + { + add_c_prev = add_count; + dbl_c_prev = dbl_count; + mul_c_prev = mul_count; + add_count = 0; + dbl_count = 0; + mul_count = 0; + + MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &m, 16, exponents[i] ) ); + MBEDTLS_MPI_CHK( mbedtls_ecp_mul( &grp, &R, &m, &P, NULL, NULL ) ); + + if( add_count != add_c_prev || + dbl_count != dbl_c_prev || + mul_count != mul_c_prev ) + { + if( verbose != 0 ) + mbedtls_printf( "failed (%u)\n", (unsigned int) i ); + + ret = 1; + goto cleanup; + } + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + +cleanup: + + if( ret < 0 && verbose != 0 ) + mbedtls_printf( "Unexpected error, return code = %08X\n", ret ); + + mbedtls_ecp_group_free( &grp ); + mbedtls_ecp_point_free( &R ); + mbedtls_ecp_point_free( &P ); + mbedtls_mpi_free( &m ); + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + + return( ret ); +} + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* !MBEDTLS_ECP_ALT */ + +#endif /* MBEDTLS_ECP_C */ diff --git a/security/mbedtls/src/ecp_curves.c b/security/mbedtls/src/ecp_curves.c new file mode 100644 index 0000000000..df5ac3eea5 --- /dev/null +++ b/security/mbedtls/src/ecp_curves.c @@ -0,0 +1,1329 @@ +/* + * Elliptic curves over GF(p): curve-specific data and functions + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_ECP_C) + +#include "mbedtls/ecp.h" + +#include + +#if !defined(MBEDTLS_ECP_ALT) + +#if ( defined(__ARMCC_VERSION) || defined(_MSC_VER) ) && \ + !defined(inline) && !defined(__cplusplus) +#define inline __inline +#endif + +/* + * Conversion macros for embedded constants: + * build lists of mbedtls_mpi_uint's from lists of unsigned char's grouped by 8, 4 or 2 + */ +#if defined(MBEDTLS_HAVE_INT32) + +#define BYTES_TO_T_UINT_4( a, b, c, d ) \ + ( (mbedtls_mpi_uint) a << 0 ) | \ + ( (mbedtls_mpi_uint) b << 8 ) | \ + ( (mbedtls_mpi_uint) c << 16 ) | \ + ( (mbedtls_mpi_uint) d << 24 ) + +#define BYTES_TO_T_UINT_2( a, b ) \ + BYTES_TO_T_UINT_4( a, b, 0, 0 ) + +#define BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h ) \ + BYTES_TO_T_UINT_4( a, b, c, d ), \ + BYTES_TO_T_UINT_4( e, f, g, h ) + +#else /* 64-bits */ + +#define BYTES_TO_T_UINT_8( a, b, c, d, e, f, g, h ) \ + ( (mbedtls_mpi_uint) a << 0 ) | \ + ( (mbedtls_mpi_uint) b << 8 ) | \ + ( (mbedtls_mpi_uint) c << 16 ) | \ + ( (mbedtls_mpi_uint) d << 24 ) | \ + ( (mbedtls_mpi_uint) e << 32 ) | \ + ( (mbedtls_mpi_uint) f << 40 ) | \ + ( (mbedtls_mpi_uint) g << 48 ) | \ + ( (mbedtls_mpi_uint) h << 56 ) + +#define BYTES_TO_T_UINT_4( a, b, c, d ) \ + BYTES_TO_T_UINT_8( a, b, c, d, 0, 0, 0, 0 ) + +#define BYTES_TO_T_UINT_2( a, b ) \ + BYTES_TO_T_UINT_8( a, b, 0, 0, 0, 0, 0, 0 ) + +#endif /* bits in mbedtls_mpi_uint */ + +/* + * Note: the constants are in little-endian order + * to be directly usable in MPIs + */ + +/* + * Domain parameters for secp192r1 + */ +#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) +static const mbedtls_mpi_uint secp192r1_p[] = { + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +static const mbedtls_mpi_uint secp192r1_b[] = { + BYTES_TO_T_UINT_8( 0xB1, 0xB9, 0x46, 0xC1, 0xEC, 0xDE, 0xB8, 0xFE ), + BYTES_TO_T_UINT_8( 0x49, 0x30, 0x24, 0x72, 0xAB, 0xE9, 0xA7, 0x0F ), + BYTES_TO_T_UINT_8( 0xE7, 0x80, 0x9C, 0xE5, 0x19, 0x05, 0x21, 0x64 ), +}; +static const mbedtls_mpi_uint secp192r1_gx[] = { + BYTES_TO_T_UINT_8( 0x12, 0x10, 0xFF, 0x82, 0xFD, 0x0A, 0xFF, 0xF4 ), + BYTES_TO_T_UINT_8( 0x00, 0x88, 0xA1, 0x43, 0xEB, 0x20, 0xBF, 0x7C ), + BYTES_TO_T_UINT_8( 0xF6, 0x90, 0x30, 0xB0, 0x0E, 0xA8, 0x8D, 0x18 ), +}; +static const mbedtls_mpi_uint secp192r1_gy[] = { + BYTES_TO_T_UINT_8( 0x11, 0x48, 0x79, 0x1E, 0xA1, 0x77, 0xF9, 0x73 ), + BYTES_TO_T_UINT_8( 0xD5, 0xCD, 0x24, 0x6B, 0xED, 0x11, 0x10, 0x63 ), + BYTES_TO_T_UINT_8( 0x78, 0xDA, 0xC8, 0xFF, 0x95, 0x2B, 0x19, 0x07 ), +}; +static const mbedtls_mpi_uint secp192r1_n[] = { + BYTES_TO_T_UINT_8( 0x31, 0x28, 0xD2, 0xB4, 0xB1, 0xC9, 0x6B, 0x14 ), + BYTES_TO_T_UINT_8( 0x36, 0xF8, 0xDE, 0x99, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */ + +/* + * Domain parameters for secp224r1 + */ +#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) +static const mbedtls_mpi_uint secp224r1_p[] = { + BYTES_TO_T_UINT_8( 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ), + BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ), +}; +static const mbedtls_mpi_uint secp224r1_b[] = { + BYTES_TO_T_UINT_8( 0xB4, 0xFF, 0x55, 0x23, 0x43, 0x39, 0x0B, 0x27 ), + BYTES_TO_T_UINT_8( 0xBA, 0xD8, 0xBF, 0xD7, 0xB7, 0xB0, 0x44, 0x50 ), + BYTES_TO_T_UINT_8( 0x56, 0x32, 0x41, 0xF5, 0xAB, 0xB3, 0x04, 0x0C ), + BYTES_TO_T_UINT_4( 0x85, 0x0A, 0x05, 0xB4 ), +}; +static const mbedtls_mpi_uint secp224r1_gx[] = { + BYTES_TO_T_UINT_8( 0x21, 0x1D, 0x5C, 0x11, 0xD6, 0x80, 0x32, 0x34 ), + BYTES_TO_T_UINT_8( 0x22, 0x11, 0xC2, 0x56, 0xD3, 0xC1, 0x03, 0x4A ), + BYTES_TO_T_UINT_8( 0xB9, 0x90, 0x13, 0x32, 0x7F, 0xBF, 0xB4, 0x6B ), + BYTES_TO_T_UINT_4( 0xBD, 0x0C, 0x0E, 0xB7 ), +}; +static const mbedtls_mpi_uint secp224r1_gy[] = { + BYTES_TO_T_UINT_8( 0x34, 0x7E, 0x00, 0x85, 0x99, 0x81, 0xD5, 0x44 ), + BYTES_TO_T_UINT_8( 0x64, 0x47, 0x07, 0x5A, 0xA0, 0x75, 0x43, 0xCD ), + BYTES_TO_T_UINT_8( 0xE6, 0xDF, 0x22, 0x4C, 0xFB, 0x23, 0xF7, 0xB5 ), + BYTES_TO_T_UINT_4( 0x88, 0x63, 0x37, 0xBD ), +}; +static const mbedtls_mpi_uint secp224r1_n[] = { + BYTES_TO_T_UINT_8( 0x3D, 0x2A, 0x5C, 0x5C, 0x45, 0x29, 0xDD, 0x13 ), + BYTES_TO_T_UINT_8( 0x3E, 0xF0, 0xB8, 0xE0, 0xA2, 0x16, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_4( 0xFF, 0xFF, 0xFF, 0xFF ), +}; +#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */ + +/* + * Domain parameters for secp256r1 + */ +#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) +static const mbedtls_mpi_uint secp256r1_p[] = { + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ), + BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ), + BYTES_TO_T_UINT_8( 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +static const mbedtls_mpi_uint secp256r1_b[] = { + BYTES_TO_T_UINT_8( 0x4B, 0x60, 0xD2, 0x27, 0x3E, 0x3C, 0xCE, 0x3B ), + BYTES_TO_T_UINT_8( 0xF6, 0xB0, 0x53, 0xCC, 0xB0, 0x06, 0x1D, 0x65 ), + BYTES_TO_T_UINT_8( 0xBC, 0x86, 0x98, 0x76, 0x55, 0xBD, 0xEB, 0xB3 ), + BYTES_TO_T_UINT_8( 0xE7, 0x93, 0x3A, 0xAA, 0xD8, 0x35, 0xC6, 0x5A ), +}; +static const mbedtls_mpi_uint secp256r1_gx[] = { + BYTES_TO_T_UINT_8( 0x96, 0xC2, 0x98, 0xD8, 0x45, 0x39, 0xA1, 0xF4 ), + BYTES_TO_T_UINT_8( 0xA0, 0x33, 0xEB, 0x2D, 0x81, 0x7D, 0x03, 0x77 ), + BYTES_TO_T_UINT_8( 0xF2, 0x40, 0xA4, 0x63, 0xE5, 0xE6, 0xBC, 0xF8 ), + BYTES_TO_T_UINT_8( 0x47, 0x42, 0x2C, 0xE1, 0xF2, 0xD1, 0x17, 0x6B ), +}; +static const mbedtls_mpi_uint secp256r1_gy[] = { + BYTES_TO_T_UINT_8( 0xF5, 0x51, 0xBF, 0x37, 0x68, 0x40, 0xB6, 0xCB ), + BYTES_TO_T_UINT_8( 0xCE, 0x5E, 0x31, 0x6B, 0x57, 0x33, 0xCE, 0x2B ), + BYTES_TO_T_UINT_8( 0x16, 0x9E, 0x0F, 0x7C, 0x4A, 0xEB, 0xE7, 0x8E ), + BYTES_TO_T_UINT_8( 0x9B, 0x7F, 0x1A, 0xFE, 0xE2, 0x42, 0xE3, 0x4F ), +}; +static const mbedtls_mpi_uint secp256r1_n[] = { + BYTES_TO_T_UINT_8( 0x51, 0x25, 0x63, 0xFC, 0xC2, 0xCA, 0xB9, 0xF3 ), + BYTES_TO_T_UINT_8( 0x84, 0x9E, 0x17, 0xA7, 0xAD, 0xFA, 0xE6, 0xBC ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */ + +/* + * Domain parameters for secp384r1 + */ +#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) +static const mbedtls_mpi_uint secp384r1_p[] = { + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 ), + BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +static const mbedtls_mpi_uint secp384r1_b[] = { + BYTES_TO_T_UINT_8( 0xEF, 0x2A, 0xEC, 0xD3, 0xED, 0xC8, 0x85, 0x2A ), + BYTES_TO_T_UINT_8( 0x9D, 0xD1, 0x2E, 0x8A, 0x8D, 0x39, 0x56, 0xC6 ), + BYTES_TO_T_UINT_8( 0x5A, 0x87, 0x13, 0x50, 0x8F, 0x08, 0x14, 0x03 ), + BYTES_TO_T_UINT_8( 0x12, 0x41, 0x81, 0xFE, 0x6E, 0x9C, 0x1D, 0x18 ), + BYTES_TO_T_UINT_8( 0x19, 0x2D, 0xF8, 0xE3, 0x6B, 0x05, 0x8E, 0x98 ), + BYTES_TO_T_UINT_8( 0xE4, 0xE7, 0x3E, 0xE2, 0xA7, 0x2F, 0x31, 0xB3 ), +}; +static const mbedtls_mpi_uint secp384r1_gx[] = { + BYTES_TO_T_UINT_8( 0xB7, 0x0A, 0x76, 0x72, 0x38, 0x5E, 0x54, 0x3A ), + BYTES_TO_T_UINT_8( 0x6C, 0x29, 0x55, 0xBF, 0x5D, 0xF2, 0x02, 0x55 ), + BYTES_TO_T_UINT_8( 0x38, 0x2A, 0x54, 0x82, 0xE0, 0x41, 0xF7, 0x59 ), + BYTES_TO_T_UINT_8( 0x98, 0x9B, 0xA7, 0x8B, 0x62, 0x3B, 0x1D, 0x6E ), + BYTES_TO_T_UINT_8( 0x74, 0xAD, 0x20, 0xF3, 0x1E, 0xC7, 0xB1, 0x8E ), + BYTES_TO_T_UINT_8( 0x37, 0x05, 0x8B, 0xBE, 0x22, 0xCA, 0x87, 0xAA ), +}; +static const mbedtls_mpi_uint secp384r1_gy[] = { + BYTES_TO_T_UINT_8( 0x5F, 0x0E, 0xEA, 0x90, 0x7C, 0x1D, 0x43, 0x7A ), + BYTES_TO_T_UINT_8( 0x9D, 0x81, 0x7E, 0x1D, 0xCE, 0xB1, 0x60, 0x0A ), + BYTES_TO_T_UINT_8( 0xC0, 0xB8, 0xF0, 0xB5, 0x13, 0x31, 0xDA, 0xE9 ), + BYTES_TO_T_UINT_8( 0x7C, 0x14, 0x9A, 0x28, 0xBD, 0x1D, 0xF4, 0xF8 ), + BYTES_TO_T_UINT_8( 0x29, 0xDC, 0x92, 0x92, 0xBF, 0x98, 0x9E, 0x5D ), + BYTES_TO_T_UINT_8( 0x6F, 0x2C, 0x26, 0x96, 0x4A, 0xDE, 0x17, 0x36 ), +}; +static const mbedtls_mpi_uint secp384r1_n[] = { + BYTES_TO_T_UINT_8( 0x73, 0x29, 0xC5, 0xCC, 0x6A, 0x19, 0xEC, 0xEC ), + BYTES_TO_T_UINT_8( 0x7A, 0xA7, 0xB0, 0x48, 0xB2, 0x0D, 0x1A, 0x58 ), + BYTES_TO_T_UINT_8( 0xDF, 0x2D, 0x37, 0xF4, 0x81, 0x4D, 0x63, 0xC7 ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ + +/* + * Domain parameters for secp521r1 + */ +#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) +static const mbedtls_mpi_uint secp521r1_p[] = { + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_2( 0xFF, 0x01 ), +}; +static const mbedtls_mpi_uint secp521r1_b[] = { + BYTES_TO_T_UINT_8( 0x00, 0x3F, 0x50, 0x6B, 0xD4, 0x1F, 0x45, 0xEF ), + BYTES_TO_T_UINT_8( 0xF1, 0x34, 0x2C, 0x3D, 0x88, 0xDF, 0x73, 0x35 ), + BYTES_TO_T_UINT_8( 0x07, 0xBF, 0xB1, 0x3B, 0xBD, 0xC0, 0x52, 0x16 ), + BYTES_TO_T_UINT_8( 0x7B, 0x93, 0x7E, 0xEC, 0x51, 0x39, 0x19, 0x56 ), + BYTES_TO_T_UINT_8( 0xE1, 0x09, 0xF1, 0x8E, 0x91, 0x89, 0xB4, 0xB8 ), + BYTES_TO_T_UINT_8( 0xF3, 0x15, 0xB3, 0x99, 0x5B, 0x72, 0xDA, 0xA2 ), + BYTES_TO_T_UINT_8( 0xEE, 0x40, 0x85, 0xB6, 0xA0, 0x21, 0x9A, 0x92 ), + BYTES_TO_T_UINT_8( 0x1F, 0x9A, 0x1C, 0x8E, 0x61, 0xB9, 0x3E, 0x95 ), + BYTES_TO_T_UINT_2( 0x51, 0x00 ), +}; +static const mbedtls_mpi_uint secp521r1_gx[] = { + BYTES_TO_T_UINT_8( 0x66, 0xBD, 0xE5, 0xC2, 0x31, 0x7E, 0x7E, 0xF9 ), + BYTES_TO_T_UINT_8( 0x9B, 0x42, 0x6A, 0x85, 0xC1, 0xB3, 0x48, 0x33 ), + BYTES_TO_T_UINT_8( 0xDE, 0xA8, 0xFF, 0xA2, 0x27, 0xC1, 0x1D, 0xFE ), + BYTES_TO_T_UINT_8( 0x28, 0x59, 0xE7, 0xEF, 0x77, 0x5E, 0x4B, 0xA1 ), + BYTES_TO_T_UINT_8( 0xBA, 0x3D, 0x4D, 0x6B, 0x60, 0xAF, 0x28, 0xF8 ), + BYTES_TO_T_UINT_8( 0x21, 0xB5, 0x3F, 0x05, 0x39, 0x81, 0x64, 0x9C ), + BYTES_TO_T_UINT_8( 0x42, 0xB4, 0x95, 0x23, 0x66, 0xCB, 0x3E, 0x9E ), + BYTES_TO_T_UINT_8( 0xCD, 0xE9, 0x04, 0x04, 0xB7, 0x06, 0x8E, 0x85 ), + BYTES_TO_T_UINT_2( 0xC6, 0x00 ), +}; +static const mbedtls_mpi_uint secp521r1_gy[] = { + BYTES_TO_T_UINT_8( 0x50, 0x66, 0xD1, 0x9F, 0x76, 0x94, 0xBE, 0x88 ), + BYTES_TO_T_UINT_8( 0x40, 0xC2, 0x72, 0xA2, 0x86, 0x70, 0x3C, 0x35 ), + BYTES_TO_T_UINT_8( 0x61, 0x07, 0xAD, 0x3F, 0x01, 0xB9, 0x50, 0xC5 ), + BYTES_TO_T_UINT_8( 0x40, 0x26, 0xF4, 0x5E, 0x99, 0x72, 0xEE, 0x97 ), + BYTES_TO_T_UINT_8( 0x2C, 0x66, 0x3E, 0x27, 0x17, 0xBD, 0xAF, 0x17 ), + BYTES_TO_T_UINT_8( 0x68, 0x44, 0x9B, 0x57, 0x49, 0x44, 0xF5, 0x98 ), + BYTES_TO_T_UINT_8( 0xD9, 0x1B, 0x7D, 0x2C, 0xB4, 0x5F, 0x8A, 0x5C ), + BYTES_TO_T_UINT_8( 0x04, 0xC0, 0x3B, 0x9A, 0x78, 0x6A, 0x29, 0x39 ), + BYTES_TO_T_UINT_2( 0x18, 0x01 ), +}; +static const mbedtls_mpi_uint secp521r1_n[] = { + BYTES_TO_T_UINT_8( 0x09, 0x64, 0x38, 0x91, 0x1E, 0xB7, 0x6F, 0xBB ), + BYTES_TO_T_UINT_8( 0xAE, 0x47, 0x9C, 0x89, 0xB8, 0xC9, 0xB5, 0x3B ), + BYTES_TO_T_UINT_8( 0xD0, 0xA5, 0x09, 0xF7, 0x48, 0x01, 0xCC, 0x7F ), + BYTES_TO_T_UINT_8( 0x6B, 0x96, 0x2F, 0xBF, 0x83, 0x87, 0x86, 0x51 ), + BYTES_TO_T_UINT_8( 0xFA, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_2( 0xFF, 0x01 ), +}; +#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) +static const mbedtls_mpi_uint secp192k1_p[] = { + BYTES_TO_T_UINT_8( 0x37, 0xEE, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +static const mbedtls_mpi_uint secp192k1_a[] = { + BYTES_TO_T_UINT_2( 0x00, 0x00 ), +}; +static const mbedtls_mpi_uint secp192k1_b[] = { + BYTES_TO_T_UINT_2( 0x03, 0x00 ), +}; +static const mbedtls_mpi_uint secp192k1_gx[] = { + BYTES_TO_T_UINT_8( 0x7D, 0x6C, 0xE0, 0xEA, 0xB1, 0xD1, 0xA5, 0x1D ), + BYTES_TO_T_UINT_8( 0x34, 0xF4, 0xB7, 0x80, 0x02, 0x7D, 0xB0, 0x26 ), + BYTES_TO_T_UINT_8( 0xAE, 0xE9, 0x57, 0xC0, 0x0E, 0xF1, 0x4F, 0xDB ), +}; +static const mbedtls_mpi_uint secp192k1_gy[] = { + BYTES_TO_T_UINT_8( 0x9D, 0x2F, 0x5E, 0xD9, 0x88, 0xAA, 0x82, 0x40 ), + BYTES_TO_T_UINT_8( 0x34, 0x86, 0xBE, 0x15, 0xD0, 0x63, 0x41, 0x84 ), + BYTES_TO_T_UINT_8( 0xA7, 0x28, 0x56, 0x9C, 0x6D, 0x2F, 0x2F, 0x9B ), +}; +static const mbedtls_mpi_uint secp192k1_n[] = { + BYTES_TO_T_UINT_8( 0x8D, 0xFD, 0xDE, 0x74, 0x6A, 0x46, 0x69, 0x0F ), + BYTES_TO_T_UINT_8( 0x17, 0xFC, 0xF2, 0x26, 0xFE, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) +static const mbedtls_mpi_uint secp224k1_p[] = { + BYTES_TO_T_UINT_8( 0x6D, 0xE5, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_4( 0xFF, 0xFF, 0xFF, 0xFF ), +}; +static const mbedtls_mpi_uint secp224k1_a[] = { + BYTES_TO_T_UINT_2( 0x00, 0x00 ), +}; +static const mbedtls_mpi_uint secp224k1_b[] = { + BYTES_TO_T_UINT_2( 0x05, 0x00 ), +}; +static const mbedtls_mpi_uint secp224k1_gx[] = { + BYTES_TO_T_UINT_8( 0x5C, 0xA4, 0xB7, 0xB6, 0x0E, 0x65, 0x7E, 0x0F ), + BYTES_TO_T_UINT_8( 0xA9, 0x75, 0x70, 0xE4, 0xE9, 0x67, 0xA4, 0x69 ), + BYTES_TO_T_UINT_8( 0xA1, 0x28, 0xFC, 0x30, 0xDF, 0x99, 0xF0, 0x4D ), + BYTES_TO_T_UINT_4( 0x33, 0x5B, 0x45, 0xA1 ), +}; +static const mbedtls_mpi_uint secp224k1_gy[] = { + BYTES_TO_T_UINT_8( 0xA5, 0x61, 0x6D, 0x55, 0xDB, 0x4B, 0xCA, 0xE2 ), + BYTES_TO_T_UINT_8( 0x59, 0xBD, 0xB0, 0xC0, 0xF7, 0x19, 0xE3, 0xF7 ), + BYTES_TO_T_UINT_8( 0xD6, 0xFB, 0xCA, 0x82, 0x42, 0x34, 0xBA, 0x7F ), + BYTES_TO_T_UINT_4( 0xED, 0x9F, 0x08, 0x7E ), +}; +static const mbedtls_mpi_uint secp224k1_n[] = { + BYTES_TO_T_UINT_8( 0xF7, 0xB1, 0x9F, 0x76, 0x71, 0xA9, 0xF0, 0xCA ), + BYTES_TO_T_UINT_8( 0x84, 0x61, 0xEC, 0xD2, 0xE8, 0xDC, 0x01, 0x00 ), + BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ), + BYTES_TO_T_UINT_8( 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ), +}; +#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) +static const mbedtls_mpi_uint secp256k1_p[] = { + BYTES_TO_T_UINT_8( 0x2F, 0xFC, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +static const mbedtls_mpi_uint secp256k1_a[] = { + BYTES_TO_T_UINT_2( 0x00, 0x00 ), +}; +static const mbedtls_mpi_uint secp256k1_b[] = { + BYTES_TO_T_UINT_2( 0x07, 0x00 ), +}; +static const mbedtls_mpi_uint secp256k1_gx[] = { + BYTES_TO_T_UINT_8( 0x98, 0x17, 0xF8, 0x16, 0x5B, 0x81, 0xF2, 0x59 ), + BYTES_TO_T_UINT_8( 0xD9, 0x28, 0xCE, 0x2D, 0xDB, 0xFC, 0x9B, 0x02 ), + BYTES_TO_T_UINT_8( 0x07, 0x0B, 0x87, 0xCE, 0x95, 0x62, 0xA0, 0x55 ), + BYTES_TO_T_UINT_8( 0xAC, 0xBB, 0xDC, 0xF9, 0x7E, 0x66, 0xBE, 0x79 ), +}; +static const mbedtls_mpi_uint secp256k1_gy[] = { + BYTES_TO_T_UINT_8( 0xB8, 0xD4, 0x10, 0xFB, 0x8F, 0xD0, 0x47, 0x9C ), + BYTES_TO_T_UINT_8( 0x19, 0x54, 0x85, 0xA6, 0x48, 0xB4, 0x17, 0xFD ), + BYTES_TO_T_UINT_8( 0xA8, 0x08, 0x11, 0x0E, 0xFC, 0xFB, 0xA4, 0x5D ), + BYTES_TO_T_UINT_8( 0x65, 0xC4, 0xA3, 0x26, 0x77, 0xDA, 0x3A, 0x48 ), +}; +static const mbedtls_mpi_uint secp256k1_n[] = { + BYTES_TO_T_UINT_8( 0x41, 0x41, 0x36, 0xD0, 0x8C, 0x5E, 0xD2, 0xBF ), + BYTES_TO_T_UINT_8( 0x3B, 0xA0, 0x48, 0xAF, 0xE6, 0xDC, 0xAE, 0xBA ), + BYTES_TO_T_UINT_8( 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), + BYTES_TO_T_UINT_8( 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF ), +}; +#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */ + +/* + * Domain parameters for brainpoolP256r1 (RFC 5639 3.4) + */ +#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) +static const mbedtls_mpi_uint brainpoolP256r1_p[] = { + BYTES_TO_T_UINT_8( 0x77, 0x53, 0x6E, 0x1F, 0x1D, 0x48, 0x13, 0x20 ), + BYTES_TO_T_UINT_8( 0x28, 0x20, 0x26, 0xD5, 0x23, 0xF6, 0x3B, 0x6E ), + BYTES_TO_T_UINT_8( 0x72, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E ), + BYTES_TO_T_UINT_8( 0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9 ), +}; +static const mbedtls_mpi_uint brainpoolP256r1_a[] = { + BYTES_TO_T_UINT_8( 0xD9, 0xB5, 0x30, 0xF3, 0x44, 0x4B, 0x4A, 0xE9 ), + BYTES_TO_T_UINT_8( 0x6C, 0x5C, 0xDC, 0x26, 0xC1, 0x55, 0x80, 0xFB ), + BYTES_TO_T_UINT_8( 0xE7, 0xFF, 0x7A, 0x41, 0x30, 0x75, 0xF6, 0xEE ), + BYTES_TO_T_UINT_8( 0x57, 0x30, 0x2C, 0xFC, 0x75, 0x09, 0x5A, 0x7D ), +}; +static const mbedtls_mpi_uint brainpoolP256r1_b[] = { + BYTES_TO_T_UINT_8( 0xB6, 0x07, 0x8C, 0xFF, 0x18, 0xDC, 0xCC, 0x6B ), + BYTES_TO_T_UINT_8( 0xCE, 0xE1, 0xF7, 0x5C, 0x29, 0x16, 0x84, 0x95 ), + BYTES_TO_T_UINT_8( 0xBF, 0x7C, 0xD7, 0xBB, 0xD9, 0xB5, 0x30, 0xF3 ), + BYTES_TO_T_UINT_8( 0x44, 0x4B, 0x4A, 0xE9, 0x6C, 0x5C, 0xDC, 0x26 ), +}; +static const mbedtls_mpi_uint brainpoolP256r1_gx[] = { + BYTES_TO_T_UINT_8( 0x62, 0x32, 0xCE, 0x9A, 0xBD, 0x53, 0x44, 0x3A ), + BYTES_TO_T_UINT_8( 0xC2, 0x23, 0xBD, 0xE3, 0xE1, 0x27, 0xDE, 0xB9 ), + BYTES_TO_T_UINT_8( 0xAF, 0xB7, 0x81, 0xFC, 0x2F, 0x48, 0x4B, 0x2C ), + BYTES_TO_T_UINT_8( 0xCB, 0x57, 0x7E, 0xCB, 0xB9, 0xAE, 0xD2, 0x8B ), +}; +static const mbedtls_mpi_uint brainpoolP256r1_gy[] = { + BYTES_TO_T_UINT_8( 0x97, 0x69, 0x04, 0x2F, 0xC7, 0x54, 0x1D, 0x5C ), + BYTES_TO_T_UINT_8( 0x54, 0x8E, 0xED, 0x2D, 0x13, 0x45, 0x77, 0xC2 ), + BYTES_TO_T_UINT_8( 0xC9, 0x1D, 0x61, 0x14, 0x1A, 0x46, 0xF8, 0x97 ), + BYTES_TO_T_UINT_8( 0xFD, 0xC4, 0xDA, 0xC3, 0x35, 0xF8, 0x7E, 0x54 ), +}; +static const mbedtls_mpi_uint brainpoolP256r1_n[] = { + BYTES_TO_T_UINT_8( 0xA7, 0x56, 0x48, 0x97, 0x82, 0x0E, 0x1E, 0x90 ), + BYTES_TO_T_UINT_8( 0xF7, 0xA6, 0x61, 0xB5, 0xA3, 0x7A, 0x39, 0x8C ), + BYTES_TO_T_UINT_8( 0x71, 0x8D, 0x83, 0x9D, 0x90, 0x0A, 0x66, 0x3E ), + BYTES_TO_T_UINT_8( 0xBC, 0xA9, 0xEE, 0xA1, 0xDB, 0x57, 0xFB, 0xA9 ), +}; +#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */ + +/* + * Domain parameters for brainpoolP384r1 (RFC 5639 3.6) + */ +#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) +static const mbedtls_mpi_uint brainpoolP384r1_p[] = { + BYTES_TO_T_UINT_8( 0x53, 0xEC, 0x07, 0x31, 0x13, 0x00, 0x47, 0x87 ), + BYTES_TO_T_UINT_8( 0x71, 0x1A, 0x1D, 0x90, 0x29, 0xA7, 0xD3, 0xAC ), + BYTES_TO_T_UINT_8( 0x23, 0x11, 0xB7, 0x7F, 0x19, 0xDA, 0xB1, 0x12 ), + BYTES_TO_T_UINT_8( 0xB4, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15 ), + BYTES_TO_T_UINT_8( 0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F ), + BYTES_TO_T_UINT_8( 0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C ), +}; +static const mbedtls_mpi_uint brainpoolP384r1_a[] = { + BYTES_TO_T_UINT_8( 0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04 ), + BYTES_TO_T_UINT_8( 0xEB, 0xD4, 0x3A, 0x50, 0x4A, 0x81, 0xA5, 0x8A ), + BYTES_TO_T_UINT_8( 0x0F, 0xF9, 0x91, 0xBA, 0xEF, 0x65, 0x91, 0x13 ), + BYTES_TO_T_UINT_8( 0x87, 0x27, 0xB2, 0x4F, 0x8E, 0xA2, 0xBE, 0xC2 ), + BYTES_TO_T_UINT_8( 0xA0, 0xAF, 0x05, 0xCE, 0x0A, 0x08, 0x72, 0x3C ), + BYTES_TO_T_UINT_8( 0x0C, 0x15, 0x8C, 0x3D, 0xC6, 0x82, 0xC3, 0x7B ), +}; +static const mbedtls_mpi_uint brainpoolP384r1_b[] = { + BYTES_TO_T_UINT_8( 0x11, 0x4C, 0x50, 0xFA, 0x96, 0x86, 0xB7, 0x3A ), + BYTES_TO_T_UINT_8( 0x94, 0xC9, 0xDB, 0x95, 0x02, 0x39, 0xB4, 0x7C ), + BYTES_TO_T_UINT_8( 0xD5, 0x62, 0xEB, 0x3E, 0xA5, 0x0E, 0x88, 0x2E ), + BYTES_TO_T_UINT_8( 0xA6, 0xD2, 0xDC, 0x07, 0xE1, 0x7D, 0xB7, 0x2F ), + BYTES_TO_T_UINT_8( 0x7C, 0x44, 0xF0, 0x16, 0x54, 0xB5, 0x39, 0x8B ), + BYTES_TO_T_UINT_8( 0x26, 0x28, 0xCE, 0x22, 0xDD, 0xC7, 0xA8, 0x04 ), +}; +static const mbedtls_mpi_uint brainpoolP384r1_gx[] = { + BYTES_TO_T_UINT_8( 0x1E, 0xAF, 0xD4, 0x47, 0xE2, 0xB2, 0x87, 0xEF ), + BYTES_TO_T_UINT_8( 0xAA, 0x46, 0xD6, 0x36, 0x34, 0xE0, 0x26, 0xE8 ), + BYTES_TO_T_UINT_8( 0xE8, 0x10, 0xBD, 0x0C, 0xFE, 0xCA, 0x7F, 0xDB ), + BYTES_TO_T_UINT_8( 0xE3, 0x4F, 0xF1, 0x7E, 0xE7, 0xA3, 0x47, 0x88 ), + BYTES_TO_T_UINT_8( 0x6B, 0x3F, 0xC1, 0xB7, 0x81, 0x3A, 0xA6, 0xA2 ), + BYTES_TO_T_UINT_8( 0xFF, 0x45, 0xCF, 0x68, 0xF0, 0x64, 0x1C, 0x1D ), +}; +static const mbedtls_mpi_uint brainpoolP384r1_gy[] = { + BYTES_TO_T_UINT_8( 0x15, 0x53, 0x3C, 0x26, 0x41, 0x03, 0x82, 0x42 ), + BYTES_TO_T_UINT_8( 0x11, 0x81, 0x91, 0x77, 0x21, 0x46, 0x46, 0x0E ), + BYTES_TO_T_UINT_8( 0x28, 0x29, 0x91, 0xF9, 0x4F, 0x05, 0x9C, 0xE1 ), + BYTES_TO_T_UINT_8( 0x64, 0x58, 0xEC, 0xFE, 0x29, 0x0B, 0xB7, 0x62 ), + BYTES_TO_T_UINT_8( 0x52, 0xD5, 0xCF, 0x95, 0x8E, 0xEB, 0xB1, 0x5C ), + BYTES_TO_T_UINT_8( 0xA4, 0xC2, 0xF9, 0x20, 0x75, 0x1D, 0xBE, 0x8A ), +}; +static const mbedtls_mpi_uint brainpoolP384r1_n[] = { + BYTES_TO_T_UINT_8( 0x65, 0x65, 0x04, 0xE9, 0x02, 0x32, 0x88, 0x3B ), + BYTES_TO_T_UINT_8( 0x10, 0xC3, 0x7F, 0x6B, 0xAF, 0xB6, 0x3A, 0xCF ), + BYTES_TO_T_UINT_8( 0xA7, 0x25, 0x04, 0xAC, 0x6C, 0x6E, 0x16, 0x1F ), + BYTES_TO_T_UINT_8( 0xB3, 0x56, 0x54, 0xED, 0x09, 0x71, 0x2F, 0x15 ), + BYTES_TO_T_UINT_8( 0xDF, 0x41, 0xE6, 0x50, 0x7E, 0x6F, 0x5D, 0x0F ), + BYTES_TO_T_UINT_8( 0x28, 0x6D, 0x38, 0xA3, 0x82, 0x1E, 0xB9, 0x8C ), +}; +#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */ + +/* + * Domain parameters for brainpoolP512r1 (RFC 5639 3.7) + */ +#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) +static const mbedtls_mpi_uint brainpoolP512r1_p[] = { + BYTES_TO_T_UINT_8( 0xF3, 0x48, 0x3A, 0x58, 0x56, 0x60, 0xAA, 0x28 ), + BYTES_TO_T_UINT_8( 0x85, 0xC6, 0x82, 0x2D, 0x2F, 0xFF, 0x81, 0x28 ), + BYTES_TO_T_UINT_8( 0xE6, 0x80, 0xA3, 0xE6, 0x2A, 0xA1, 0xCD, 0xAE ), + BYTES_TO_T_UINT_8( 0x42, 0x68, 0xC6, 0x9B, 0x00, 0x9B, 0x4D, 0x7D ), + BYTES_TO_T_UINT_8( 0x71, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6 ), + BYTES_TO_T_UINT_8( 0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB ), + BYTES_TO_T_UINT_8( 0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F ), + BYTES_TO_T_UINT_8( 0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA ), +}; +static const mbedtls_mpi_uint brainpoolP512r1_a[] = { + BYTES_TO_T_UINT_8( 0xCA, 0x94, 0xFC, 0x77, 0x4D, 0xAC, 0xC1, 0xE7 ), + BYTES_TO_T_UINT_8( 0xB9, 0xC7, 0xF2, 0x2B, 0xA7, 0x17, 0x11, 0x7F ), + BYTES_TO_T_UINT_8( 0xB5, 0xC8, 0x9A, 0x8B, 0xC9, 0xF1, 0x2E, 0x0A ), + BYTES_TO_T_UINT_8( 0xA1, 0x3A, 0x25, 0xA8, 0x5A, 0x5D, 0xED, 0x2D ), + BYTES_TO_T_UINT_8( 0xBC, 0x63, 0x98, 0xEA, 0xCA, 0x41, 0x34, 0xA8 ), + BYTES_TO_T_UINT_8( 0x10, 0x16, 0xF9, 0x3D, 0x8D, 0xDD, 0xCB, 0x94 ), + BYTES_TO_T_UINT_8( 0xC5, 0x4C, 0x23, 0xAC, 0x45, 0x71, 0x32, 0xE2 ), + BYTES_TO_T_UINT_8( 0x89, 0x3B, 0x60, 0x8B, 0x31, 0xA3, 0x30, 0x78 ), +}; +static const mbedtls_mpi_uint brainpoolP512r1_b[] = { + BYTES_TO_T_UINT_8( 0x23, 0xF7, 0x16, 0x80, 0x63, 0xBD, 0x09, 0x28 ), + BYTES_TO_T_UINT_8( 0xDD, 0xE5, 0xBA, 0x5E, 0xB7, 0x50, 0x40, 0x98 ), + BYTES_TO_T_UINT_8( 0x67, 0x3E, 0x08, 0xDC, 0xCA, 0x94, 0xFC, 0x77 ), + BYTES_TO_T_UINT_8( 0x4D, 0xAC, 0xC1, 0xE7, 0xB9, 0xC7, 0xF2, 0x2B ), + BYTES_TO_T_UINT_8( 0xA7, 0x17, 0x11, 0x7F, 0xB5, 0xC8, 0x9A, 0x8B ), + BYTES_TO_T_UINT_8( 0xC9, 0xF1, 0x2E, 0x0A, 0xA1, 0x3A, 0x25, 0xA8 ), + BYTES_TO_T_UINT_8( 0x5A, 0x5D, 0xED, 0x2D, 0xBC, 0x63, 0x98, 0xEA ), + BYTES_TO_T_UINT_8( 0xCA, 0x41, 0x34, 0xA8, 0x10, 0x16, 0xF9, 0x3D ), +}; +static const mbedtls_mpi_uint brainpoolP512r1_gx[] = { + BYTES_TO_T_UINT_8( 0x22, 0xF8, 0xB9, 0xBC, 0x09, 0x22, 0x35, 0x8B ), + BYTES_TO_T_UINT_8( 0x68, 0x5E, 0x6A, 0x40, 0x47, 0x50, 0x6D, 0x7C ), + BYTES_TO_T_UINT_8( 0x5F, 0x7D, 0xB9, 0x93, 0x7B, 0x68, 0xD1, 0x50 ), + BYTES_TO_T_UINT_8( 0x8D, 0xD4, 0xD0, 0xE2, 0x78, 0x1F, 0x3B, 0xFF ), + BYTES_TO_T_UINT_8( 0x8E, 0x09, 0xD0, 0xF4, 0xEE, 0x62, 0x3B, 0xB4 ), + BYTES_TO_T_UINT_8( 0xC1, 0x16, 0xD9, 0xB5, 0x70, 0x9F, 0xED, 0x85 ), + BYTES_TO_T_UINT_8( 0x93, 0x6A, 0x4C, 0x9C, 0x2E, 0x32, 0x21, 0x5A ), + BYTES_TO_T_UINT_8( 0x64, 0xD9, 0x2E, 0xD8, 0xBD, 0xE4, 0xAE, 0x81 ), +}; +static const mbedtls_mpi_uint brainpoolP512r1_gy[] = { + BYTES_TO_T_UINT_8( 0x92, 0x08, 0xD8, 0x3A, 0x0F, 0x1E, 0xCD, 0x78 ), + BYTES_TO_T_UINT_8( 0x06, 0x54, 0xF0, 0xA8, 0x2F, 0x2B, 0xCA, 0xD1 ), + BYTES_TO_T_UINT_8( 0xAE, 0x63, 0x27, 0x8A, 0xD8, 0x4B, 0xCA, 0x5B ), + BYTES_TO_T_UINT_8( 0x5E, 0x48, 0x5F, 0x4A, 0x49, 0xDE, 0xDC, 0xB2 ), + BYTES_TO_T_UINT_8( 0x11, 0x81, 0x1F, 0x88, 0x5B, 0xC5, 0x00, 0xA0 ), + BYTES_TO_T_UINT_8( 0x1A, 0x7B, 0xA5, 0x24, 0x00, 0xF7, 0x09, 0xF2 ), + BYTES_TO_T_UINT_8( 0xFD, 0x22, 0x78, 0xCF, 0xA9, 0xBF, 0xEA, 0xC0 ), + BYTES_TO_T_UINT_8( 0xEC, 0x32, 0x63, 0x56, 0x5D, 0x38, 0xDE, 0x7D ), +}; +static const mbedtls_mpi_uint brainpoolP512r1_n[] = { + BYTES_TO_T_UINT_8( 0x69, 0x00, 0xA9, 0x9C, 0x82, 0x96, 0x87, 0xB5 ), + BYTES_TO_T_UINT_8( 0xDD, 0xDA, 0x5D, 0x08, 0x81, 0xD3, 0xB1, 0x1D ), + BYTES_TO_T_UINT_8( 0x47, 0x10, 0xAC, 0x7F, 0x19, 0x61, 0x86, 0x41 ), + BYTES_TO_T_UINT_8( 0x19, 0x26, 0xA9, 0x4C, 0x41, 0x5C, 0x3E, 0x55 ), + BYTES_TO_T_UINT_8( 0x70, 0x08, 0x33, 0x70, 0xCA, 0x9C, 0x63, 0xD6 ), + BYTES_TO_T_UINT_8( 0x0E, 0xD2, 0xC9, 0xB3, 0xB3, 0x8D, 0x30, 0xCB ), + BYTES_TO_T_UINT_8( 0x07, 0xFC, 0xC9, 0x33, 0xAE, 0xE6, 0xD4, 0x3F ), + BYTES_TO_T_UINT_8( 0x8B, 0xC4, 0xE9, 0xDB, 0xB8, 0x9D, 0xDD, 0xAA ), +}; +#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */ + +/* + * Create an MPI from embedded constants + * (assumes len is an exact multiple of sizeof mbedtls_mpi_uint) + */ +static inline void ecp_mpi_load( mbedtls_mpi *X, const mbedtls_mpi_uint *p, size_t len ) +{ + X->s = 1; + X->n = len / sizeof( mbedtls_mpi_uint ); + X->p = (mbedtls_mpi_uint *) p; +} + +/* + * Set an MPI to static value 1 + */ +static inline void ecp_mpi_set1( mbedtls_mpi *X ) +{ + static mbedtls_mpi_uint one[] = { 1 }; + X->s = 1; + X->n = 1; + X->p = one; +} + +/* + * Make group available from embedded constants + */ +static int ecp_group_load( mbedtls_ecp_group *grp, + const mbedtls_mpi_uint *p, size_t plen, + const mbedtls_mpi_uint *a, size_t alen, + const mbedtls_mpi_uint *b, size_t blen, + const mbedtls_mpi_uint *gx, size_t gxlen, + const mbedtls_mpi_uint *gy, size_t gylen, + const mbedtls_mpi_uint *n, size_t nlen) +{ + ecp_mpi_load( &grp->P, p, plen ); + if( a != NULL ) + ecp_mpi_load( &grp->A, a, alen ); + ecp_mpi_load( &grp->B, b, blen ); + ecp_mpi_load( &grp->N, n, nlen ); + + ecp_mpi_load( &grp->G.X, gx, gxlen ); + ecp_mpi_load( &grp->G.Y, gy, gylen ); + ecp_mpi_set1( &grp->G.Z ); + + grp->pbits = mbedtls_mpi_bitlen( &grp->P ); + grp->nbits = mbedtls_mpi_bitlen( &grp->N ); + + grp->h = 1; + + return( 0 ); +} + +#if defined(MBEDTLS_ECP_NIST_OPTIM) +/* Forward declarations */ +#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) +static int ecp_mod_p192( mbedtls_mpi * ); +#endif +#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) +static int ecp_mod_p224( mbedtls_mpi * ); +#endif +#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) +static int ecp_mod_p256( mbedtls_mpi * ); +#endif +#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) +static int ecp_mod_p384( mbedtls_mpi * ); +#endif +#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) +static int ecp_mod_p521( mbedtls_mpi * ); +#endif + +#define NIST_MODP( P ) grp->modp = ecp_mod_ ## P; +#else +#define NIST_MODP( P ) +#endif /* MBEDTLS_ECP_NIST_OPTIM */ + +/* Additional forward declarations */ +#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) +static int ecp_mod_p255( mbedtls_mpi * ); +#endif +#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) +static int ecp_mod_p192k1( mbedtls_mpi * ); +#endif +#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) +static int ecp_mod_p224k1( mbedtls_mpi * ); +#endif +#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) +static int ecp_mod_p256k1( mbedtls_mpi * ); +#endif + +#define LOAD_GROUP_A( G ) ecp_group_load( grp, \ + G ## _p, sizeof( G ## _p ), \ + G ## _a, sizeof( G ## _a ), \ + G ## _b, sizeof( G ## _b ), \ + G ## _gx, sizeof( G ## _gx ), \ + G ## _gy, sizeof( G ## _gy ), \ + G ## _n, sizeof( G ## _n ) ) + +#define LOAD_GROUP( G ) ecp_group_load( grp, \ + G ## _p, sizeof( G ## _p ), \ + NULL, 0, \ + G ## _b, sizeof( G ## _b ), \ + G ## _gx, sizeof( G ## _gx ), \ + G ## _gy, sizeof( G ## _gy ), \ + G ## _n, sizeof( G ## _n ) ) + +#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) +/* + * Specialized function for creating the Curve25519 group + */ +static int ecp_use_curve25519( mbedtls_ecp_group *grp ) +{ + int ret; + + /* Actually ( A + 2 ) / 4 */ + MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &grp->A, 16, "01DB42" ) ); + + /* P = 2^255 - 19 */ + MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->P, 1 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &grp->P, 255 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &grp->P, &grp->P, 19 ) ); + grp->pbits = mbedtls_mpi_bitlen( &grp->P ); + + /* Y intentionaly not set, since we use x/z coordinates. + * This is used as a marker to identify Montgomery curves! */ + MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.X, 9 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &grp->G.Z, 1 ) ); + mbedtls_mpi_free( &grp->G.Y ); + + /* Actually, the required msb for private keys */ + grp->nbits = 254; + +cleanup: + if( ret != 0 ) + mbedtls_ecp_group_free( grp ); + + return( ret ); +} +#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */ + +/* + * Set a group using well-known domain parameters + */ +int mbedtls_ecp_group_load( mbedtls_ecp_group *grp, mbedtls_ecp_group_id id ) +{ + mbedtls_ecp_group_free( grp ); + + grp->id = id; + + switch( id ) + { +#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) + case MBEDTLS_ECP_DP_SECP192R1: + NIST_MODP( p192 ); + return( LOAD_GROUP( secp192r1 ) ); +#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) + case MBEDTLS_ECP_DP_SECP224R1: + NIST_MODP( p224 ); + return( LOAD_GROUP( secp224r1 ) ); +#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) + case MBEDTLS_ECP_DP_SECP256R1: + NIST_MODP( p256 ); + return( LOAD_GROUP( secp256r1 ) ); +#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) + case MBEDTLS_ECP_DP_SECP384R1: + NIST_MODP( p384 ); + return( LOAD_GROUP( secp384r1 ) ); +#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) + case MBEDTLS_ECP_DP_SECP521R1: + NIST_MODP( p521 ); + return( LOAD_GROUP( secp521r1 ) ); +#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) + case MBEDTLS_ECP_DP_SECP192K1: + grp->modp = ecp_mod_p192k1; + return( LOAD_GROUP_A( secp192k1 ) ); +#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) + case MBEDTLS_ECP_DP_SECP224K1: + grp->modp = ecp_mod_p224k1; + return( LOAD_GROUP_A( secp224k1 ) ); +#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) + case MBEDTLS_ECP_DP_SECP256K1: + grp->modp = ecp_mod_p256k1; + return( LOAD_GROUP_A( secp256k1 ) ); +#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) + case MBEDTLS_ECP_DP_BP256R1: + return( LOAD_GROUP_A( brainpoolP256r1 ) ); +#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) + case MBEDTLS_ECP_DP_BP384R1: + return( LOAD_GROUP_A( brainpoolP384r1 ) ); +#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) + case MBEDTLS_ECP_DP_BP512R1: + return( LOAD_GROUP_A( brainpoolP512r1 ) ); +#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) + case MBEDTLS_ECP_DP_CURVE25519: + grp->modp = ecp_mod_p255; + return( ecp_use_curve25519( grp ) ); +#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */ + + default: + mbedtls_ecp_group_free( grp ); + return( MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ); + } +} + +#if defined(MBEDTLS_ECP_NIST_OPTIM) +/* + * Fast reduction modulo the primes used by the NIST curves. + * + * These functions are critical for speed, but not needed for correct + * operations. So, we make the choice to heavily rely on the internals of our + * bignum library, which creates a tight coupling between these functions and + * our MPI implementation. However, the coupling between the ECP module and + * MPI remains loose, since these functions can be deactivated at will. + */ + +#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) +/* + * Compared to the way things are presented in FIPS 186-3 D.2, + * we proceed in columns, from right (least significant chunk) to left, + * adding chunks to N in place, and keeping a carry for the next chunk. + * This avoids moving things around in memory, and uselessly adding zeros, + * compared to the more straightforward, line-oriented approach. + * + * For this prime we need to handle data in chunks of 64 bits. + * Since this is always a multiple of our basic mbedtls_mpi_uint, we can + * use a mbedtls_mpi_uint * to designate such a chunk, and small loops to handle it. + */ + +/* Add 64-bit chunks (dst += src) and update carry */ +static inline void add64( mbedtls_mpi_uint *dst, mbedtls_mpi_uint *src, mbedtls_mpi_uint *carry ) +{ + unsigned char i; + mbedtls_mpi_uint c = 0; + for( i = 0; i < 8 / sizeof( mbedtls_mpi_uint ); i++, dst++, src++ ) + { + *dst += c; c = ( *dst < c ); + *dst += *src; c += ( *dst < *src ); + } + *carry += c; +} + +/* Add carry to a 64-bit chunk and update carry */ +static inline void carry64( mbedtls_mpi_uint *dst, mbedtls_mpi_uint *carry ) +{ + unsigned char i; + for( i = 0; i < 8 / sizeof( mbedtls_mpi_uint ); i++, dst++ ) + { + *dst += *carry; + *carry = ( *dst < *carry ); + } +} + +#define WIDTH 8 / sizeof( mbedtls_mpi_uint ) +#define A( i ) N->p + i * WIDTH +#define ADD( i ) add64( p, A( i ), &c ) +#define NEXT p += WIDTH; carry64( p, &c ) +#define LAST p += WIDTH; *p = c; while( ++p < end ) *p = 0 + +/* + * Fast quasi-reduction modulo p192 (FIPS 186-3 D.2.1) + */ +static int ecp_mod_p192( mbedtls_mpi *N ) +{ + int ret; + mbedtls_mpi_uint c = 0; + mbedtls_mpi_uint *p, *end; + + /* Make sure we have enough blocks so that A(5) is legal */ + MBEDTLS_MPI_CHK( mbedtls_mpi_grow( N, 6 * WIDTH ) ); + + p = N->p; + end = p + N->n; + + ADD( 3 ); ADD( 5 ); NEXT; // A0 += A3 + A5 + ADD( 3 ); ADD( 4 ); ADD( 5 ); NEXT; // A1 += A3 + A4 + A5 + ADD( 4 ); ADD( 5 ); LAST; // A2 += A4 + A5 + +cleanup: + return( ret ); +} + +#undef WIDTH +#undef A +#undef ADD +#undef NEXT +#undef LAST +#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) +/* + * The reader is advised to first understand ecp_mod_p192() since the same + * general structure is used here, but with additional complications: + * (1) chunks of 32 bits, and (2) subtractions. + */ + +/* + * For these primes, we need to handle data in chunks of 32 bits. + * This makes it more complicated if we use 64 bits limbs in MPI, + * which prevents us from using a uniform access method as for p192. + * + * So, we define a mini abstraction layer to access 32 bit chunks, + * load them in 'cur' for work, and store them back from 'cur' when done. + * + * While at it, also define the size of N in terms of 32-bit chunks. + */ +#define LOAD32 cur = A( i ); + +#if defined(MBEDTLS_HAVE_INT32) /* 32 bit */ + +#define MAX32 N->n +#define A( j ) N->p[j] +#define STORE32 N->p[i] = cur; + +#else /* 64-bit */ + +#define MAX32 N->n * 2 +#define A( j ) j % 2 ? (uint32_t)( N->p[j/2] >> 32 ) : (uint32_t)( N->p[j/2] ) +#define STORE32 \ + if( i % 2 ) { \ + N->p[i/2] &= 0x00000000FFFFFFFF; \ + N->p[i/2] |= ((mbedtls_mpi_uint) cur) << 32; \ + } else { \ + N->p[i/2] &= 0xFFFFFFFF00000000; \ + N->p[i/2] |= (mbedtls_mpi_uint) cur; \ + } + +#endif /* sizeof( mbedtls_mpi_uint ) */ + +/* + * Helpers for addition and subtraction of chunks, with signed carry. + */ +static inline void add32( uint32_t *dst, uint32_t src, signed char *carry ) +{ + *dst += src; + *carry += ( *dst < src ); +} + +static inline void sub32( uint32_t *dst, uint32_t src, signed char *carry ) +{ + *carry -= ( *dst < src ); + *dst -= src; +} + +#define ADD( j ) add32( &cur, A( j ), &c ); +#define SUB( j ) sub32( &cur, A( j ), &c ); + +/* + * Helpers for the main 'loop' + * (see fix_negative for the motivation of C) + */ +#define INIT( b ) \ + int ret; \ + signed char c = 0, cc; \ + uint32_t cur; \ + size_t i = 0, bits = b; \ + mbedtls_mpi C; \ + mbedtls_mpi_uint Cp[ b / 8 / sizeof( mbedtls_mpi_uint) + 1 ]; \ + \ + C.s = 1; \ + C.n = b / 8 / sizeof( mbedtls_mpi_uint) + 1; \ + C.p = Cp; \ + memset( Cp, 0, C.n * sizeof( mbedtls_mpi_uint ) ); \ + \ + MBEDTLS_MPI_CHK( mbedtls_mpi_grow( N, b * 2 / 8 / sizeof( mbedtls_mpi_uint ) ) ); \ + LOAD32; + +#define NEXT \ + STORE32; i++; LOAD32; \ + cc = c; c = 0; \ + if( cc < 0 ) \ + sub32( &cur, -cc, &c ); \ + else \ + add32( &cur, cc, &c ); \ + +#define LAST \ + STORE32; i++; \ + cur = c > 0 ? c : 0; STORE32; \ + cur = 0; while( ++i < MAX32 ) { STORE32; } \ + if( c < 0 ) fix_negative( N, c, &C, bits ); + +/* + * If the result is negative, we get it in the form + * c * 2^(bits + 32) + N, with c negative and N positive shorter than 'bits' + */ +static inline int fix_negative( mbedtls_mpi *N, signed char c, mbedtls_mpi *C, size_t bits ) +{ + int ret; + + /* C = - c * 2^(bits + 32) */ +#if !defined(MBEDTLS_HAVE_INT64) + ((void) bits); +#else + if( bits == 224 ) + C->p[ C->n - 1 ] = ((mbedtls_mpi_uint) -c) << 32; + else +#endif + C->p[ C->n - 1 ] = (mbedtls_mpi_uint) -c; + + /* N = - ( C - N ) */ + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( N, C, N ) ); + N->s = -1; + +cleanup: + + return( ret ); +} + +#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) +/* + * Fast quasi-reduction modulo p224 (FIPS 186-3 D.2.2) + */ +static int ecp_mod_p224( mbedtls_mpi *N ) +{ + INIT( 224 ); + + SUB( 7 ); SUB( 11 ); NEXT; // A0 += -A7 - A11 + SUB( 8 ); SUB( 12 ); NEXT; // A1 += -A8 - A12 + SUB( 9 ); SUB( 13 ); NEXT; // A2 += -A9 - A13 + SUB( 10 ); ADD( 7 ); ADD( 11 ); NEXT; // A3 += -A10 + A7 + A11 + SUB( 11 ); ADD( 8 ); ADD( 12 ); NEXT; // A4 += -A11 + A8 + A12 + SUB( 12 ); ADD( 9 ); ADD( 13 ); NEXT; // A5 += -A12 + A9 + A13 + SUB( 13 ); ADD( 10 ); LAST; // A6 += -A13 + A10 + +cleanup: + return( ret ); +} +#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) +/* + * Fast quasi-reduction modulo p256 (FIPS 186-3 D.2.3) + */ +static int ecp_mod_p256( mbedtls_mpi *N ) +{ + INIT( 256 ); + + ADD( 8 ); ADD( 9 ); + SUB( 11 ); SUB( 12 ); SUB( 13 ); SUB( 14 ); NEXT; // A0 + + ADD( 9 ); ADD( 10 ); + SUB( 12 ); SUB( 13 ); SUB( 14 ); SUB( 15 ); NEXT; // A1 + + ADD( 10 ); ADD( 11 ); + SUB( 13 ); SUB( 14 ); SUB( 15 ); NEXT; // A2 + + ADD( 11 ); ADD( 11 ); ADD( 12 ); ADD( 12 ); ADD( 13 ); + SUB( 15 ); SUB( 8 ); SUB( 9 ); NEXT; // A3 + + ADD( 12 ); ADD( 12 ); ADD( 13 ); ADD( 13 ); ADD( 14 ); + SUB( 9 ); SUB( 10 ); NEXT; // A4 + + ADD( 13 ); ADD( 13 ); ADD( 14 ); ADD( 14 ); ADD( 15 ); + SUB( 10 ); SUB( 11 ); NEXT; // A5 + + ADD( 14 ); ADD( 14 ); ADD( 15 ); ADD( 15 ); ADD( 14 ); ADD( 13 ); + SUB( 8 ); SUB( 9 ); NEXT; // A6 + + ADD( 15 ); ADD( 15 ); ADD( 15 ); ADD( 8 ); + SUB( 10 ); SUB( 11 ); SUB( 12 ); SUB( 13 ); LAST; // A7 + +cleanup: + return( ret ); +} +#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) +/* + * Fast quasi-reduction modulo p384 (FIPS 186-3 D.2.4) + */ +static int ecp_mod_p384( mbedtls_mpi *N ) +{ + INIT( 384 ); + + ADD( 12 ); ADD( 21 ); ADD( 20 ); + SUB( 23 ); NEXT; // A0 + + ADD( 13 ); ADD( 22 ); ADD( 23 ); + SUB( 12 ); SUB( 20 ); NEXT; // A2 + + ADD( 14 ); ADD( 23 ); + SUB( 13 ); SUB( 21 ); NEXT; // A2 + + ADD( 15 ); ADD( 12 ); ADD( 20 ); ADD( 21 ); + SUB( 14 ); SUB( 22 ); SUB( 23 ); NEXT; // A3 + + ADD( 21 ); ADD( 21 ); ADD( 16 ); ADD( 13 ); ADD( 12 ); ADD( 20 ); ADD( 22 ); + SUB( 15 ); SUB( 23 ); SUB( 23 ); NEXT; // A4 + + ADD( 22 ); ADD( 22 ); ADD( 17 ); ADD( 14 ); ADD( 13 ); ADD( 21 ); ADD( 23 ); + SUB( 16 ); NEXT; // A5 + + ADD( 23 ); ADD( 23 ); ADD( 18 ); ADD( 15 ); ADD( 14 ); ADD( 22 ); + SUB( 17 ); NEXT; // A6 + + ADD( 19 ); ADD( 16 ); ADD( 15 ); ADD( 23 ); + SUB( 18 ); NEXT; // A7 + + ADD( 20 ); ADD( 17 ); ADD( 16 ); + SUB( 19 ); NEXT; // A8 + + ADD( 21 ); ADD( 18 ); ADD( 17 ); + SUB( 20 ); NEXT; // A9 + + ADD( 22 ); ADD( 19 ); ADD( 18 ); + SUB( 21 ); NEXT; // A10 + + ADD( 23 ); ADD( 20 ); ADD( 19 ); + SUB( 22 ); LAST; // A11 + +cleanup: + return( ret ); +} +#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ + +#undef A +#undef LOAD32 +#undef STORE32 +#undef MAX32 +#undef INIT +#undef NEXT +#undef LAST + +#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED || + MBEDTLS_ECP_DP_SECP256R1_ENABLED || + MBEDTLS_ECP_DP_SECP384R1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) +/* + * Here we have an actual Mersenne prime, so things are more straightforward. + * However, chunks are aligned on a 'weird' boundary (521 bits). + */ + +/* Size of p521 in terms of mbedtls_mpi_uint */ +#define P521_WIDTH ( 521 / 8 / sizeof( mbedtls_mpi_uint ) + 1 ) + +/* Bits to keep in the most significant mbedtls_mpi_uint */ +#define P521_MASK 0x01FF + +/* + * Fast quasi-reduction modulo p521 (FIPS 186-3 D.2.5) + * Write N as A1 + 2^521 A0, return A0 + A1 + */ +static int ecp_mod_p521( mbedtls_mpi *N ) +{ + int ret; + size_t i; + mbedtls_mpi M; + mbedtls_mpi_uint Mp[P521_WIDTH + 1]; + /* Worst case for the size of M is when mbedtls_mpi_uint is 16 bits: + * we need to hold bits 513 to 1056, which is 34 limbs, that is + * P521_WIDTH + 1. Otherwise P521_WIDTH is enough. */ + + if( N->n < P521_WIDTH ) + return( 0 ); + + /* M = A1 */ + M.s = 1; + M.n = N->n - ( P521_WIDTH - 1 ); + if( M.n > P521_WIDTH + 1 ) + M.n = P521_WIDTH + 1; + M.p = Mp; + memcpy( Mp, N->p + P521_WIDTH - 1, M.n * sizeof( mbedtls_mpi_uint ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, 521 % ( 8 * sizeof( mbedtls_mpi_uint ) ) ) ); + + /* N = A0 */ + N->p[P521_WIDTH - 1] &= P521_MASK; + for( i = P521_WIDTH; i < N->n; i++ ) + N->p[i] = 0; + + /* N = A0 + A1 */ + MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) ); + +cleanup: + return( ret ); +} + +#undef P521_WIDTH +#undef P521_MASK +#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ + +#endif /* MBEDTLS_ECP_NIST_OPTIM */ + +#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) + +/* Size of p255 in terms of mbedtls_mpi_uint */ +#define P255_WIDTH ( 255 / 8 / sizeof( mbedtls_mpi_uint ) + 1 ) + +/* + * Fast quasi-reduction modulo p255 = 2^255 - 19 + * Write N as A0 + 2^255 A1, return A0 + 19 * A1 + */ +static int ecp_mod_p255( mbedtls_mpi *N ) +{ + int ret; + size_t i; + mbedtls_mpi M; + mbedtls_mpi_uint Mp[P255_WIDTH + 2]; + + if( N->n < P255_WIDTH ) + return( 0 ); + + /* M = A1 */ + M.s = 1; + M.n = N->n - ( P255_WIDTH - 1 ); + if( M.n > P255_WIDTH + 1 ) + M.n = P255_WIDTH + 1; + M.p = Mp; + memset( Mp, 0, sizeof Mp ); + memcpy( Mp, N->p + P255_WIDTH - 1, M.n * sizeof( mbedtls_mpi_uint ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, 255 % ( 8 * sizeof( mbedtls_mpi_uint ) ) ) ); + M.n++; /* Make room for multiplication by 19 */ + + /* N = A0 */ + MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( N, 255, 0 ) ); + for( i = P255_WIDTH; i < N->n; i++ ) + N->p[i] = 0; + + /* N = A0 + 19 * A1 */ + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &M, &M, 19 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) ); + +cleanup: + return( ret ); +} +#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) || \ + defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) +/* + * Fast quasi-reduction modulo P = 2^s - R, + * with R about 33 bits, used by the Koblitz curves. + * + * Write N as A0 + 2^224 A1, return A0 + R * A1. + * Actually do two passes, since R is big. + */ +#define P_KOBLITZ_MAX ( 256 / 8 / sizeof( mbedtls_mpi_uint ) ) // Max limbs in P +#define P_KOBLITZ_R ( 8 / sizeof( mbedtls_mpi_uint ) ) // Limbs in R +static inline int ecp_mod_koblitz( mbedtls_mpi *N, mbedtls_mpi_uint *Rp, size_t p_limbs, + size_t adjust, size_t shift, mbedtls_mpi_uint mask ) +{ + int ret; + size_t i; + mbedtls_mpi M, R; + mbedtls_mpi_uint Mp[P_KOBLITZ_MAX + P_KOBLITZ_R + 1]; + + if( N->n < p_limbs ) + return( 0 ); + + /* Init R */ + R.s = 1; + R.p = Rp; + R.n = P_KOBLITZ_R; + + /* Common setup for M */ + M.s = 1; + M.p = Mp; + + /* M = A1 */ + M.n = N->n - ( p_limbs - adjust ); + if( M.n > p_limbs + adjust ) + M.n = p_limbs + adjust; + memset( Mp, 0, sizeof Mp ); + memcpy( Mp, N->p + p_limbs - adjust, M.n * sizeof( mbedtls_mpi_uint ) ); + if( shift != 0 ) + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, shift ) ); + M.n += R.n; /* Make room for multiplication by R */ + + /* N = A0 */ + if( mask != 0 ) + N->p[p_limbs - 1] &= mask; + for( i = p_limbs; i < N->n; i++ ) + N->p[i] = 0; + + /* N = A0 + R * A1 */ + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &M, &M, &R ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) ); + + /* Second pass */ + + /* M = A1 */ + M.n = N->n - ( p_limbs - adjust ); + if( M.n > p_limbs + adjust ) + M.n = p_limbs + adjust; + memset( Mp, 0, sizeof Mp ); + memcpy( Mp, N->p + p_limbs - adjust, M.n * sizeof( mbedtls_mpi_uint ) ); + if( shift != 0 ) + MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &M, shift ) ); + M.n += R.n; /* Make room for multiplication by R */ + + /* N = A0 */ + if( mask != 0 ) + N->p[p_limbs - 1] &= mask; + for( i = p_limbs; i < N->n; i++ ) + N->p[i] = 0; + + /* N = A0 + R * A1 */ + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &M, &M, &R ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( N, N, &M ) ); + +cleanup: + return( ret ); +} +#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED) || + MBEDTLS_ECP_DP_SECP224K1_ENABLED) || + MBEDTLS_ECP_DP_SECP256K1_ENABLED) */ + +#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) +/* + * Fast quasi-reduction modulo p192k1 = 2^192 - R, + * with R = 2^32 + 2^12 + 2^8 + 2^7 + 2^6 + 2^3 + 1 = 0x0100001119 + */ +static int ecp_mod_p192k1( mbedtls_mpi *N ) +{ + static mbedtls_mpi_uint Rp[] = { + BYTES_TO_T_UINT_8( 0xC9, 0x11, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) }; + + return( ecp_mod_koblitz( N, Rp, 192 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0, 0 ) ); +} +#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) +/* + * Fast quasi-reduction modulo p224k1 = 2^224 - R, + * with R = 2^32 + 2^12 + 2^11 + 2^9 + 2^7 + 2^4 + 2 + 1 = 0x0100001A93 + */ +static int ecp_mod_p224k1( mbedtls_mpi *N ) +{ + static mbedtls_mpi_uint Rp[] = { + BYTES_TO_T_UINT_8( 0x93, 0x1A, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) }; + +#if defined(MBEDTLS_HAVE_INT64) + return( ecp_mod_koblitz( N, Rp, 4, 1, 32, 0xFFFFFFFF ) ); +#else + return( ecp_mod_koblitz( N, Rp, 224 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0, 0 ) ); +#endif +} + +#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */ + +#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) +/* + * Fast quasi-reduction modulo p256k1 = 2^256 - R, + * with R = 2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1 = 0x01000003D1 + */ +static int ecp_mod_p256k1( mbedtls_mpi *N ) +{ + static mbedtls_mpi_uint Rp[] = { + BYTES_TO_T_UINT_8( 0xD1, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00 ) }; + return( ecp_mod_koblitz( N, Rp, 256 / 8 / sizeof( mbedtls_mpi_uint ), 0, 0, 0 ) ); +} +#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */ + +#endif /* !MBEDTLS_ECP_ALT */ + +#endif /* MBEDTLS_ECP_C */ diff --git a/security/mbedtls/src/entropy.c b/security/mbedtls/src/entropy.c new file mode 100644 index 0000000000..d4d1b27b7f --- /dev/null +++ b/security/mbedtls/src/entropy.c @@ -0,0 +1,655 @@ +/* + * Entropy accumulator implementation + * + * Copyright (C) 2006-2016, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_ENTROPY_C) + +#if defined(MBEDTLS_TEST_NULL_ENTROPY) +#warning "**** WARNING! MBEDTLS_TEST_NULL_ENTROPY defined! " +#warning "**** THIS BUILD HAS NO DEFINED ENTROPY SOURCES " +#warning "**** THIS BUILD IS *NOT* SUITABLE FOR PRODUCTION USE " +#endif + +#include "mbedtls/entropy.h" +#include "mbedtls/entropy_poll.h" + +#include + +#if defined(MBEDTLS_FS_IO) +#include +#endif + +#if defined(MBEDTLS_ENTROPY_NV_SEED) +#include "mbedtls/platform.h" +#endif + +#if defined(MBEDTLS_SELF_TEST) +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_printf printf +#endif /* MBEDTLS_PLATFORM_C */ +#endif /* MBEDTLS_SELF_TEST */ + +#if defined(MBEDTLS_HAVEGE_C) +#include "mbedtls/havege.h" +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +#define ENTROPY_MAX_LOOP 256 /**< Maximum amount to loop before error */ + +void mbedtls_entropy_init( mbedtls_entropy_context *ctx ) +{ + memset( ctx, 0, sizeof(mbedtls_entropy_context) ); + +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_init( &ctx->mutex ); +#endif + +#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR) + mbedtls_sha512_starts( &ctx->accumulator, 0 ); +#else + mbedtls_sha256_starts( &ctx->accumulator, 0 ); +#endif +#if defined(MBEDTLS_HAVEGE_C) + mbedtls_havege_init( &ctx->havege_data ); +#endif + +#if defined(MBEDTLS_TEST_NULL_ENTROPY) + mbedtls_entropy_add_source( ctx, mbedtls_null_entropy_poll, NULL, + 1, MBEDTLS_ENTROPY_SOURCE_STRONG ); +#endif + +#if !defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) +#if !defined(MBEDTLS_NO_PLATFORM_ENTROPY) + mbedtls_entropy_add_source( ctx, mbedtls_platform_entropy_poll, NULL, + MBEDTLS_ENTROPY_MIN_PLATFORM, + MBEDTLS_ENTROPY_SOURCE_STRONG ); +#endif +#if defined(MBEDTLS_TIMING_C) + mbedtls_entropy_add_source( ctx, mbedtls_hardclock_poll, NULL, + MBEDTLS_ENTROPY_MIN_HARDCLOCK, + MBEDTLS_ENTROPY_SOURCE_WEAK ); +#endif +#if defined(MBEDTLS_HAVEGE_C) + mbedtls_entropy_add_source( ctx, mbedtls_havege_poll, &ctx->havege_data, + MBEDTLS_ENTROPY_MIN_HAVEGE, + MBEDTLS_ENTROPY_SOURCE_STRONG ); +#endif +#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) + mbedtls_entropy_add_source( ctx, mbedtls_hardware_poll, NULL, + MBEDTLS_ENTROPY_MIN_HARDWARE, + MBEDTLS_ENTROPY_SOURCE_STRONG ); +#endif +#if defined(MBEDTLS_ENTROPY_NV_SEED) + mbedtls_entropy_add_source( ctx, mbedtls_nv_seed_poll, NULL, + MBEDTLS_ENTROPY_BLOCK_SIZE, + MBEDTLS_ENTROPY_SOURCE_STRONG ); +#endif +#endif /* MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES */ +} + +void mbedtls_entropy_free( mbedtls_entropy_context *ctx ) +{ +#if defined(MBEDTLS_HAVEGE_C) + mbedtls_havege_free( &ctx->havege_data ); +#endif +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_free( &ctx->mutex ); +#endif + mbedtls_zeroize( ctx, sizeof( mbedtls_entropy_context ) ); +} + +int mbedtls_entropy_add_source( mbedtls_entropy_context *ctx, + mbedtls_entropy_f_source_ptr f_source, void *p_source, + size_t threshold, int strong ) +{ + int index, ret = 0; + +#if defined(MBEDTLS_THREADING_C) + if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) + return( ret ); +#endif + + index = ctx->source_count; + if( index >= MBEDTLS_ENTROPY_MAX_SOURCES ) + { + ret = MBEDTLS_ERR_ENTROPY_MAX_SOURCES; + goto exit; + } + + ctx->source[index].f_source = f_source; + ctx->source[index].p_source = p_source; + ctx->source[index].threshold = threshold; + ctx->source[index].strong = strong; + + ctx->source_count++; + +exit: +#if defined(MBEDTLS_THREADING_C) + if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) + return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); +#endif + + return( ret ); +} + +/* + * Entropy accumulator update + */ +static int entropy_update( mbedtls_entropy_context *ctx, unsigned char source_id, + const unsigned char *data, size_t len ) +{ + unsigned char header[2]; + unsigned char tmp[MBEDTLS_ENTROPY_BLOCK_SIZE]; + size_t use_len = len; + const unsigned char *p = data; + + if( use_len > MBEDTLS_ENTROPY_BLOCK_SIZE ) + { +#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR) + mbedtls_sha512( data, len, tmp, 0 ); +#else + mbedtls_sha256( data, len, tmp, 0 ); +#endif + p = tmp; + use_len = MBEDTLS_ENTROPY_BLOCK_SIZE; + } + + header[0] = source_id; + header[1] = use_len & 0xFF; + +#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR) + mbedtls_sha512_update( &ctx->accumulator, header, 2 ); + mbedtls_sha512_update( &ctx->accumulator, p, use_len ); +#else + mbedtls_sha256_update( &ctx->accumulator, header, 2 ); + mbedtls_sha256_update( &ctx->accumulator, p, use_len ); +#endif + + return( 0 ); +} + +int mbedtls_entropy_update_manual( mbedtls_entropy_context *ctx, + const unsigned char *data, size_t len ) +{ + int ret; + +#if defined(MBEDTLS_THREADING_C) + if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) + return( ret ); +#endif + + ret = entropy_update( ctx, MBEDTLS_ENTROPY_SOURCE_MANUAL, data, len ); + +#if defined(MBEDTLS_THREADING_C) + if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) + return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); +#endif + + return( ret ); +} + +/* + * Run through the different sources to add entropy to our accumulator + */ +static int entropy_gather_internal( mbedtls_entropy_context *ctx ) +{ + int ret, i, have_one_strong = 0; + unsigned char buf[MBEDTLS_ENTROPY_MAX_GATHER]; + size_t olen; + + if( ctx->source_count == 0 ) + return( MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED ); + + /* + * Run through our entropy sources + */ + for( i = 0; i < ctx->source_count; i++ ) + { + if( ctx->source[i].strong == MBEDTLS_ENTROPY_SOURCE_STRONG ) + have_one_strong = 1; + + olen = 0; + if( ( ret = ctx->source[i].f_source( ctx->source[i].p_source, + buf, MBEDTLS_ENTROPY_MAX_GATHER, &olen ) ) != 0 ) + { + return( ret ); + } + + /* + * Add if we actually gathered something + */ + if( olen > 0 ) + { + entropy_update( ctx, (unsigned char) i, buf, olen ); + ctx->source[i].size += olen; + } + } + + if( have_one_strong == 0 ) + return( MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE ); + + return( 0 ); +} + +/* + * Thread-safe wrapper for entropy_gather_internal() + */ +int mbedtls_entropy_gather( mbedtls_entropy_context *ctx ) +{ + int ret; + +#if defined(MBEDTLS_THREADING_C) + if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) + return( ret ); +#endif + + ret = entropy_gather_internal( ctx ); + +#if defined(MBEDTLS_THREADING_C) + if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) + return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); +#endif + + return( ret ); +} + +int mbedtls_entropy_func( void *data, unsigned char *output, size_t len ) +{ + int ret, count = 0, i, done; + mbedtls_entropy_context *ctx = (mbedtls_entropy_context *) data; + unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE]; + + if( len > MBEDTLS_ENTROPY_BLOCK_SIZE ) + return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); + +#if defined(MBEDTLS_ENTROPY_NV_SEED) + /* Update the NV entropy seed before generating any entropy for outside + * use. + */ + if( ctx->initial_entropy_run == 0 ) + { + ctx->initial_entropy_run = 1; + if( ( ret = mbedtls_entropy_update_nv_seed( ctx ) ) != 0 ) + return( ret ); + } +#endif + +#if defined(MBEDTLS_THREADING_C) + if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) + return( ret ); +#endif + + /* + * Always gather extra entropy before a call + */ + do + { + if( count++ > ENTROPY_MAX_LOOP ) + { + ret = MBEDTLS_ERR_ENTROPY_SOURCE_FAILED; + goto exit; + } + + if( ( ret = entropy_gather_internal( ctx ) ) != 0 ) + goto exit; + + done = 1; + for( i = 0; i < ctx->source_count; i++ ) + if( ctx->source[i].size < ctx->source[i].threshold ) + done = 0; + } + while( ! done ); + + memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE ); + +#if defined(MBEDTLS_ENTROPY_SHA512_ACCUMULATOR) + mbedtls_sha512_finish( &ctx->accumulator, buf ); + + /* + * Reset accumulator and counters and recycle existing entropy + */ + memset( &ctx->accumulator, 0, sizeof( mbedtls_sha512_context ) ); + mbedtls_sha512_starts( &ctx->accumulator, 0 ); + mbedtls_sha512_update( &ctx->accumulator, buf, MBEDTLS_ENTROPY_BLOCK_SIZE ); + + /* + * Perform second SHA-512 on entropy + */ + mbedtls_sha512( buf, MBEDTLS_ENTROPY_BLOCK_SIZE, buf, 0 ); +#else /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */ + mbedtls_sha256_finish( &ctx->accumulator, buf ); + + /* + * Reset accumulator and counters and recycle existing entropy + */ + memset( &ctx->accumulator, 0, sizeof( mbedtls_sha256_context ) ); + mbedtls_sha256_starts( &ctx->accumulator, 0 ); + mbedtls_sha256_update( &ctx->accumulator, buf, MBEDTLS_ENTROPY_BLOCK_SIZE ); + + /* + * Perform second SHA-256 on entropy + */ + mbedtls_sha256( buf, MBEDTLS_ENTROPY_BLOCK_SIZE, buf, 0 ); +#endif /* MBEDTLS_ENTROPY_SHA512_ACCUMULATOR */ + + for( i = 0; i < ctx->source_count; i++ ) + ctx->source[i].size = 0; + + memcpy( output, buf, len ); + + ret = 0; + +exit: +#if defined(MBEDTLS_THREADING_C) + if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) + return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); +#endif + + return( ret ); +} + +#if defined(MBEDTLS_ENTROPY_NV_SEED) +int mbedtls_entropy_update_nv_seed( mbedtls_entropy_context *ctx ) +{ + int ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR; + unsigned char buf[ MBEDTLS_ENTROPY_MAX_SEED_SIZE ]; + + /* Read new seed and write it to NV */ + if( ( ret = mbedtls_entropy_func( ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 ) + return( ret ); + + if( mbedtls_nv_seed_write( buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) < 0 ) + return( MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR ); + + /* Manually update the remaining stream with a separator value to diverge */ + memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE ); + mbedtls_entropy_update_manual( ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE ); + + return( 0 ); +} +#endif /* MBEDTLS_ENTROPY_NV_SEED */ + +#if defined(MBEDTLS_FS_IO) +int mbedtls_entropy_write_seed_file( mbedtls_entropy_context *ctx, const char *path ) +{ + int ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR; + FILE *f; + unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE]; + + if( ( f = fopen( path, "wb" ) ) == NULL ) + return( MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR ); + + if( ( ret = mbedtls_entropy_func( ctx, buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) ) != 0 ) + goto exit; + + if( fwrite( buf, 1, MBEDTLS_ENTROPY_BLOCK_SIZE, f ) != MBEDTLS_ENTROPY_BLOCK_SIZE ) + { + ret = MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR; + goto exit; + } + + ret = 0; + +exit: + fclose( f ); + return( ret ); +} + +int mbedtls_entropy_update_seed_file( mbedtls_entropy_context *ctx, const char *path ) +{ + FILE *f; + size_t n; + unsigned char buf[ MBEDTLS_ENTROPY_MAX_SEED_SIZE ]; + + if( ( f = fopen( path, "rb" ) ) == NULL ) + return( MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR ); + + fseek( f, 0, SEEK_END ); + n = (size_t) ftell( f ); + fseek( f, 0, SEEK_SET ); + + if( n > MBEDTLS_ENTROPY_MAX_SEED_SIZE ) + n = MBEDTLS_ENTROPY_MAX_SEED_SIZE; + + if( fread( buf, 1, n, f ) != n ) + { + fclose( f ); + return( MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR ); + } + + fclose( f ); + + mbedtls_entropy_update_manual( ctx, buf, n ); + + return( mbedtls_entropy_write_seed_file( ctx, path ) ); +} +#endif /* MBEDTLS_FS_IO */ + +#if defined(MBEDTLS_SELF_TEST) +#if !defined(MBEDTLS_TEST_NULL_ENTROPY) +/* + * Dummy source function + */ +static int entropy_dummy_source( void *data, unsigned char *output, + size_t len, size_t *olen ) +{ + ((void) data); + + memset( output, 0x2a, len ); + *olen = len; + + return( 0 ); +} +#endif /* !MBEDTLS_TEST_NULL_ENTROPY */ + +#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) + +static int mbedtls_entropy_source_self_test_gather( unsigned char *buf, size_t buf_len ) +{ + int ret = 0; + size_t entropy_len = 0; + size_t olen = 0; + size_t attempts = buf_len; + + while( attempts > 0 && entropy_len < buf_len ) + { + if( ( ret = mbedtls_hardware_poll( NULL, buf + entropy_len, + buf_len - entropy_len, &olen ) ) != 0 ) + return( ret ); + + entropy_len += olen; + attempts--; + } + + if( entropy_len < buf_len ) + { + ret = 1; + } + + return( ret ); +} + + +static int mbedtls_entropy_source_self_test_check_bits( const unsigned char *buf, + size_t buf_len ) +{ + unsigned char set= 0xFF; + unsigned char unset = 0x00; + size_t i; + + for( i = 0; i < buf_len; i++ ) + { + set &= buf[i]; + unset |= buf[i]; + } + + return( set == 0xFF || unset == 0x00 ); +} + +/* + * A test to ensure hat the entropy sources are functioning correctly + * and there is no obvious failure. The test performs the following checks: + * - The entropy source is not providing only 0s (all bits unset) or 1s (all + * bits set). + * - The entropy source is not providing values in a pattern. Because the + * hardware could be providing data in an arbitrary length, this check polls + * the hardware entropy source twice and compares the result to ensure they + * are not equal. + * - The error code returned by the entropy source is not an error. + */ +int mbedtls_entropy_source_self_test( int verbose ) +{ + int ret = 0; + unsigned char buf0[2 * sizeof( unsigned long long int )]; + unsigned char buf1[2 * sizeof( unsigned long long int )]; + + if( verbose != 0 ) + mbedtls_printf( " ENTROPY_BIAS test: " ); + + memset( buf0, 0x00, sizeof( buf0 ) ); + memset( buf1, 0x00, sizeof( buf1 ) ); + + if( ( ret = mbedtls_entropy_source_self_test_gather( buf0, sizeof( buf0 ) ) ) != 0 ) + goto cleanup; + if( ( ret = mbedtls_entropy_source_self_test_gather( buf1, sizeof( buf1 ) ) ) != 0 ) + goto cleanup; + + /* Make sure that the returned values are not all 0 or 1 */ + if( ( ret = mbedtls_entropy_source_self_test_check_bits( buf0, sizeof( buf0 ) ) ) != 0 ) + goto cleanup; + if( ( ret = mbedtls_entropy_source_self_test_check_bits( buf1, sizeof( buf1 ) ) ) != 0 ) + goto cleanup; + + /* Make sure that the entropy source is not returning values in a + * pattern */ + ret = memcmp( buf0, buf1, sizeof( buf0 ) ) == 0; + +cleanup: + if( verbose != 0 ) + { + if( ret != 0 ) + mbedtls_printf( "failed\n" ); + else + mbedtls_printf( "passed\n" ); + + mbedtls_printf( "\n" ); + } + + return( ret != 0 ); +} + +#endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */ + +/* + * The actual entropy quality is hard to test, but we can at least + * test that the functions don't cause errors and write the correct + * amount of data to buffers. + */ +int mbedtls_entropy_self_test( int verbose ) +{ + int ret = 1; +#if !defined(MBEDTLS_TEST_NULL_ENTROPY) + mbedtls_entropy_context ctx; + unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE] = { 0 }; + unsigned char acc[MBEDTLS_ENTROPY_BLOCK_SIZE] = { 0 }; + size_t i, j; +#endif /* !MBEDTLS_TEST_NULL_ENTROPY */ + + if( verbose != 0 ) + mbedtls_printf( " ENTROPY test: " ); + +#if !defined(MBEDTLS_TEST_NULL_ENTROPY) + mbedtls_entropy_init( &ctx ); + + /* First do a gather to make sure we have default sources */ + if( ( ret = mbedtls_entropy_gather( &ctx ) ) != 0 ) + goto cleanup; + + ret = mbedtls_entropy_add_source( &ctx, entropy_dummy_source, NULL, 16, + MBEDTLS_ENTROPY_SOURCE_WEAK ); + if( ret != 0 ) + goto cleanup; + + if( ( ret = mbedtls_entropy_update_manual( &ctx, buf, sizeof buf ) ) != 0 ) + goto cleanup; + + /* + * To test that mbedtls_entropy_func writes correct number of bytes: + * - use the whole buffer and rely on ASan to detect overruns + * - collect entropy 8 times and OR the result in an accumulator: + * any byte should then be 0 with probably 2^(-64), so requiring + * each of the 32 or 64 bytes to be non-zero has a false failure rate + * of at most 2^(-58) which is acceptable. + */ + for( i = 0; i < 8; i++ ) + { + if( ( ret = mbedtls_entropy_func( &ctx, buf, sizeof( buf ) ) ) != 0 ) + goto cleanup; + + for( j = 0; j < sizeof( buf ); j++ ) + acc[j] |= buf[j]; + } + + for( j = 0; j < sizeof( buf ); j++ ) + { + if( acc[j] == 0 ) + { + ret = 1; + goto cleanup; + } + } + +#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) + if( ( ret = mbedtls_entropy_source_self_test( 0 ) ) != 0 ) + goto cleanup; +#endif + +cleanup: + mbedtls_entropy_free( &ctx ); +#endif /* !MBEDTLS_TEST_NULL_ENTROPY */ + + if( verbose != 0 ) + { + if( ret != 0 ) + mbedtls_printf( "failed\n" ); + else + mbedtls_printf( "passed\n" ); + + mbedtls_printf( "\n" ); + } + + return( ret != 0 ); +} +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_ENTROPY_C */ diff --git a/security/mbedtls/src/entropy_poll.c b/security/mbedtls/src/entropy_poll.c new file mode 100644 index 0000000000..a116e605d2 --- /dev/null +++ b/security/mbedtls/src/entropy_poll.c @@ -0,0 +1,268 @@ +/* + * Platform-specific and custom entropy polling functions + * + * Copyright (C) 2006-2016, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_ENTROPY_C) + +#include "mbedtls/entropy.h" +#include "mbedtls/entropy_poll.h" + +#if defined(MBEDTLS_TIMING_C) +#include +#include "mbedtls/timing.h" +#endif +#if defined(MBEDTLS_HAVEGE_C) +#include "mbedtls/havege.h" +#endif +#if defined(MBEDTLS_ENTROPY_NV_SEED) +#include "mbedtls/platform.h" +#endif + +#if !defined(MBEDTLS_NO_PLATFORM_ENTROPY) + +#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \ + !defined(__APPLE__) && !defined(_WIN32) +#error "Platform entropy sources only work on Unix and Windows, see MBEDTLS_NO_PLATFORM_ENTROPY in config.h" +#endif + +#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) + +#if !defined(_WIN32_WINNT) +#define _WIN32_WINNT 0x0400 +#endif +#include +#include + +int mbedtls_platform_entropy_poll( void *data, unsigned char *output, size_t len, + size_t *olen ) +{ + HCRYPTPROV provider; + ((void) data); + *olen = 0; + + if( CryptAcquireContext( &provider, NULL, NULL, + PROV_RSA_FULL, CRYPT_VERIFYCONTEXT ) == FALSE ) + { + return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); + } + + if( CryptGenRandom( provider, (DWORD) len, output ) == FALSE ) + { + CryptReleaseContext( provider, 0 ); + return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); + } + + CryptReleaseContext( provider, 0 ); + *olen = len; + + return( 0 ); +} +#else /* _WIN32 && !EFIX64 && !EFI32 */ + +/* + * Test for Linux getrandom() support. + * Since there is no wrapper in the libc yet, use the generic syscall wrapper + * available in GNU libc and compatible libc's (eg uClibc). + */ +#if defined(__linux__) && defined(__GLIBC__) +#include +#include +#if defined(SYS_getrandom) +#define HAVE_GETRANDOM + +static int getrandom_wrapper( void *buf, size_t buflen, unsigned int flags ) +{ + /* MemSan cannot understand that the syscall writes to the buffer */ +#if defined(__has_feature) +#if __has_feature(memory_sanitizer) + memset( buf, 0, buflen ); +#endif +#endif + + return( syscall( SYS_getrandom, buf, buflen, flags ) ); +} + +#include +/* Check if version is at least 3.17.0 */ +static int check_version_3_17_plus( void ) +{ + int minor; + struct utsname un; + const char *ver; + + /* Get version information */ + uname(&un); + ver = un.release; + + /* Check major version; assume a single digit */ + if( ver[0] < '3' || ver[0] > '9' || ver [1] != '.' ) + return( -1 ); + + if( ver[0] - '0' > 3 ) + return( 0 ); + + /* Ok, so now we know major == 3, check minor. + * Assume 1 or 2 digits. */ + if( ver[2] < '0' || ver[2] > '9' ) + return( -1 ); + + minor = ver[2] - '0'; + + if( ver[3] >= '0' && ver[3] <= '9' ) + minor = 10 * minor + ver[3] - '0'; + else if( ver [3] != '.' ) + return( -1 ); + + if( minor < 17 ) + return( -1 ); + + return( 0 ); +} +static int has_getrandom = -1; +#endif /* SYS_getrandom */ +#endif /* __linux__ */ + +#include + +int mbedtls_platform_entropy_poll( void *data, + unsigned char *output, size_t len, size_t *olen ) +{ + FILE *file; + size_t read_len; + ((void) data); + +#if defined(HAVE_GETRANDOM) + if( has_getrandom == -1 ) + has_getrandom = ( check_version_3_17_plus() == 0 ); + + if( has_getrandom ) + { + int ret; + + if( ( ret = getrandom_wrapper( output, len, 0 ) ) < 0 ) + return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); + + *olen = ret; + return( 0 ); + } +#endif /* HAVE_GETRANDOM */ + + *olen = 0; + + file = fopen( "/dev/urandom", "rb" ); + if( file == NULL ) + return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); + + read_len = fread( output, 1, len, file ); + if( read_len != len ) + { + fclose( file ); + return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); + } + + fclose( file ); + *olen = len; + + return( 0 ); +} +#endif /* _WIN32 && !EFIX64 && !EFI32 */ +#endif /* !MBEDTLS_NO_PLATFORM_ENTROPY */ + +#if defined(MBEDTLS_TEST_NULL_ENTROPY) +int mbedtls_null_entropy_poll( void *data, + unsigned char *output, size_t len, size_t *olen ) +{ + ((void) data); + ((void) output); + *olen = 0; + + if( len < sizeof(unsigned char) ) + return( 0 ); + + *olen = sizeof(unsigned char); + + return( 0 ); +} +#endif + +#if defined(MBEDTLS_TIMING_C) +int mbedtls_hardclock_poll( void *data, + unsigned char *output, size_t len, size_t *olen ) +{ + unsigned long timer = mbedtls_timing_hardclock(); + ((void) data); + *olen = 0; + + if( len < sizeof(unsigned long) ) + return( 0 ); + + memcpy( output, &timer, sizeof(unsigned long) ); + *olen = sizeof(unsigned long); + + return( 0 ); +} +#endif /* MBEDTLS_TIMING_C */ + +#if defined(MBEDTLS_HAVEGE_C) +int mbedtls_havege_poll( void *data, + unsigned char *output, size_t len, size_t *olen ) +{ + mbedtls_havege_state *hs = (mbedtls_havege_state *) data; + *olen = 0; + + if( mbedtls_havege_random( hs, output, len ) != 0 ) + return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); + + *olen = len; + + return( 0 ); +} +#endif /* MBEDTLS_HAVEGE_C */ + +#if defined(MBEDTLS_ENTROPY_NV_SEED) +int mbedtls_nv_seed_poll( void *data, + unsigned char *output, size_t len, size_t *olen ) +{ + unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE]; + size_t use_len = MBEDTLS_ENTROPY_BLOCK_SIZE; + ((void) data); + + memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE ); + + if( mbedtls_nv_seed_read( buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) < 0 ) + return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED ); + + if( len < use_len ) + use_len = len; + + memcpy( output, buf, use_len ); + *olen = use_len; + + return( 0 ); +} +#endif /* MBEDTLS_ENTROPY_NV_SEED */ + +#endif /* MBEDTLS_ENTROPY_C */ diff --git a/security/mbedtls/src/error.c b/security/mbedtls/src/error.c new file mode 100644 index 0000000000..dd2db0c45c --- /dev/null +++ b/security/mbedtls/src/error.c @@ -0,0 +1,707 @@ +/* + * Error message information + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_ERROR_C) || defined(MBEDTLS_ERROR_STRERROR_DUMMY) +#include "mbedtls/error.h" +#include +#endif + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#define mbedtls_snprintf snprintf +#define mbedtls_time_t time_t +#endif + +#if defined(MBEDTLS_ERROR_C) + +#include + +#if defined(MBEDTLS_AES_C) +#include "mbedtls/aes.h" +#endif + +#if defined(MBEDTLS_BASE64_C) +#include "mbedtls/base64.h" +#endif + +#if defined(MBEDTLS_BIGNUM_C) +#include "mbedtls/bignum.h" +#endif + +#if defined(MBEDTLS_BLOWFISH_C) +#include "mbedtls/blowfish.h" +#endif + +#if defined(MBEDTLS_CAMELLIA_C) +#include "mbedtls/camellia.h" +#endif + +#if defined(MBEDTLS_CCM_C) +#include "mbedtls/ccm.h" +#endif + +#if defined(MBEDTLS_CIPHER_C) +#include "mbedtls/cipher.h" +#endif + +#if defined(MBEDTLS_CTR_DRBG_C) +#include "mbedtls/ctr_drbg.h" +#endif + +#if defined(MBEDTLS_DES_C) +#include "mbedtls/des.h" +#endif + +#if defined(MBEDTLS_DHM_C) +#include "mbedtls/dhm.h" +#endif + +#if defined(MBEDTLS_ECP_C) +#include "mbedtls/ecp.h" +#endif + +#if defined(MBEDTLS_ENTROPY_C) +#include "mbedtls/entropy.h" +#endif + +#if defined(MBEDTLS_GCM_C) +#include "mbedtls/gcm.h" +#endif + +#if defined(MBEDTLS_HMAC_DRBG_C) +#include "mbedtls/hmac_drbg.h" +#endif + +#if defined(MBEDTLS_MD_C) +#include "mbedtls/md.h" +#endif + +#if defined(MBEDTLS_NET_C) +#include "mbedtls/net_sockets.h" +#endif + +#if defined(MBEDTLS_OID_C) +#include "mbedtls/oid.h" +#endif + +#if defined(MBEDTLS_PADLOCK_C) +#include "mbedtls/padlock.h" +#endif + +#if defined(MBEDTLS_PEM_PARSE_C) || defined(MBEDTLS_PEM_WRITE_C) +#include "mbedtls/pem.h" +#endif + +#if defined(MBEDTLS_PK_C) +#include "mbedtls/pk.h" +#endif + +#if defined(MBEDTLS_PKCS12_C) +#include "mbedtls/pkcs12.h" +#endif + +#if defined(MBEDTLS_PKCS5_C) +#include "mbedtls/pkcs5.h" +#endif + +#if defined(MBEDTLS_RSA_C) +#include "mbedtls/rsa.h" +#endif + +#if defined(MBEDTLS_SSL_TLS_C) +#include "mbedtls/ssl.h" +#endif + +#if defined(MBEDTLS_THREADING_C) +#include "mbedtls/threading.h" +#endif + +#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C) +#include "mbedtls/x509.h" +#endif + +#if defined(MBEDTLS_XTEA_C) +#include "mbedtls/xtea.h" +#endif + + +void mbedtls_strerror( int ret, char *buf, size_t buflen ) +{ + size_t len; + int use_ret; + + if( buflen == 0 ) + return; + + memset( buf, 0x00, buflen ); + + if( ret < 0 ) + ret = -ret; + + if( ret & 0xFF80 ) + { + use_ret = ret & 0xFF80; + + // High level error codes + // + // BEGIN generated code +#if defined(MBEDTLS_CIPHER_C) + if( use_ret == -(MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE) ) + mbedtls_snprintf( buf, buflen, "CIPHER - The selected feature is not available" ); + if( use_ret == -(MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA) ) + mbedtls_snprintf( buf, buflen, "CIPHER - Bad input parameters to function" ); + if( use_ret == -(MBEDTLS_ERR_CIPHER_ALLOC_FAILED) ) + mbedtls_snprintf( buf, buflen, "CIPHER - Failed to allocate memory" ); + if( use_ret == -(MBEDTLS_ERR_CIPHER_INVALID_PADDING) ) + mbedtls_snprintf( buf, buflen, "CIPHER - Input data contains invalid padding and is rejected" ); + if( use_ret == -(MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED) ) + mbedtls_snprintf( buf, buflen, "CIPHER - Decryption of block requires a full block" ); + if( use_ret == -(MBEDTLS_ERR_CIPHER_AUTH_FAILED) ) + mbedtls_snprintf( buf, buflen, "CIPHER - Authentication failed (for AEAD modes)" ); + if( use_ret == -(MBEDTLS_ERR_CIPHER_INVALID_CONTEXT) ) + mbedtls_snprintf( buf, buflen, "CIPHER - The context is invalid, eg because it was free()ed" ); +#endif /* MBEDTLS_CIPHER_C */ + +#if defined(MBEDTLS_DHM_C) + if( use_ret == -(MBEDTLS_ERR_DHM_BAD_INPUT_DATA) ) + mbedtls_snprintf( buf, buflen, "DHM - Bad input parameters to function" ); + if( use_ret == -(MBEDTLS_ERR_DHM_READ_PARAMS_FAILED) ) + mbedtls_snprintf( buf, buflen, "DHM - Reading of the DHM parameters failed" ); + if( use_ret == -(MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED) ) + mbedtls_snprintf( buf, buflen, "DHM - Making of the DHM parameters failed" ); + if( use_ret == -(MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED) ) + mbedtls_snprintf( buf, buflen, "DHM - Reading of the public values failed" ); + if( use_ret == -(MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED) ) + mbedtls_snprintf( buf, buflen, "DHM - Making of the public value failed" ); + if( use_ret == -(MBEDTLS_ERR_DHM_CALC_SECRET_FAILED) ) + mbedtls_snprintf( buf, buflen, "DHM - Calculation of the DHM secret failed" ); + if( use_ret == -(MBEDTLS_ERR_DHM_INVALID_FORMAT) ) + mbedtls_snprintf( buf, buflen, "DHM - The ASN.1 data is not formatted correctly" ); + if( use_ret == -(MBEDTLS_ERR_DHM_ALLOC_FAILED) ) + mbedtls_snprintf( buf, buflen, "DHM - Allocation of memory failed" ); + if( use_ret == -(MBEDTLS_ERR_DHM_FILE_IO_ERROR) ) + mbedtls_snprintf( buf, buflen, "DHM - Read/write of file failed" ); +#endif /* MBEDTLS_DHM_C */ + +#if defined(MBEDTLS_ECP_C) + if( use_ret == -(MBEDTLS_ERR_ECP_BAD_INPUT_DATA) ) + mbedtls_snprintf( buf, buflen, "ECP - Bad input parameters to function" ); + if( use_ret == -(MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL) ) + mbedtls_snprintf( buf, buflen, "ECP - The buffer is too small to write to" ); + if( use_ret == -(MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE) ) + mbedtls_snprintf( buf, buflen, "ECP - Requested curve not available" ); + if( use_ret == -(MBEDTLS_ERR_ECP_VERIFY_FAILED) ) + mbedtls_snprintf( buf, buflen, "ECP - The signature is not valid" ); + if( use_ret == -(MBEDTLS_ERR_ECP_ALLOC_FAILED) ) + mbedtls_snprintf( buf, buflen, "ECP - Memory allocation failed" ); + if( use_ret == -(MBEDTLS_ERR_ECP_RANDOM_FAILED) ) + mbedtls_snprintf( buf, buflen, "ECP - Generation of random value, such as (ephemeral) key, failed" ); + if( use_ret == -(MBEDTLS_ERR_ECP_INVALID_KEY) ) + mbedtls_snprintf( buf, buflen, "ECP - Invalid private or public key" ); + if( use_ret == -(MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH) ) + mbedtls_snprintf( buf, buflen, "ECP - Signature is valid but shorter than the user-supplied length" ); +#endif /* MBEDTLS_ECP_C */ + +#if defined(MBEDTLS_MD_C) + if( use_ret == -(MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE) ) + mbedtls_snprintf( buf, buflen, "MD - The selected feature is not available" ); + if( use_ret == -(MBEDTLS_ERR_MD_BAD_INPUT_DATA) ) + mbedtls_snprintf( buf, buflen, "MD - Bad input parameters to function" ); + if( use_ret == -(MBEDTLS_ERR_MD_ALLOC_FAILED) ) + mbedtls_snprintf( buf, buflen, "MD - Failed to allocate memory" ); + if( use_ret == -(MBEDTLS_ERR_MD_FILE_IO_ERROR) ) + mbedtls_snprintf( buf, buflen, "MD - Opening or reading of file failed" ); +#endif /* MBEDTLS_MD_C */ + +#if defined(MBEDTLS_PEM_PARSE_C) || defined(MBEDTLS_PEM_WRITE_C) + if( use_ret == -(MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) ) + mbedtls_snprintf( buf, buflen, "PEM - No PEM header or footer found" ); + if( use_ret == -(MBEDTLS_ERR_PEM_INVALID_DATA) ) + mbedtls_snprintf( buf, buflen, "PEM - PEM string is not as expected" ); + if( use_ret == -(MBEDTLS_ERR_PEM_ALLOC_FAILED) ) + mbedtls_snprintf( buf, buflen, "PEM - Failed to allocate memory" ); + if( use_ret == -(MBEDTLS_ERR_PEM_INVALID_ENC_IV) ) + mbedtls_snprintf( buf, buflen, "PEM - RSA IV is not in hex-format" ); + if( use_ret == -(MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG) ) + mbedtls_snprintf( buf, buflen, "PEM - Unsupported key encryption algorithm" ); + if( use_ret == -(MBEDTLS_ERR_PEM_PASSWORD_REQUIRED) ) + mbedtls_snprintf( buf, buflen, "PEM - Private key password can't be empty" ); + if( use_ret == -(MBEDTLS_ERR_PEM_PASSWORD_MISMATCH) ) + mbedtls_snprintf( buf, buflen, "PEM - Given private key password does not allow for correct decryption" ); + if( use_ret == -(MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE) ) + mbedtls_snprintf( buf, buflen, "PEM - Unavailable feature, e.g. hashing/encryption combination" ); + if( use_ret == -(MBEDTLS_ERR_PEM_BAD_INPUT_DATA) ) + mbedtls_snprintf( buf, buflen, "PEM - Bad input parameters to function" ); +#endif /* MBEDTLS_PEM_PARSE_C || MBEDTLS_PEM_WRITE_C */ + +#if defined(MBEDTLS_PK_C) + if( use_ret == -(MBEDTLS_ERR_PK_ALLOC_FAILED) ) + mbedtls_snprintf( buf, buflen, "PK - Memory allocation failed" ); + if( use_ret == -(MBEDTLS_ERR_PK_TYPE_MISMATCH) ) + mbedtls_snprintf( buf, buflen, "PK - Type mismatch, eg attempt to encrypt with an ECDSA key" ); + if( use_ret == -(MBEDTLS_ERR_PK_BAD_INPUT_DATA) ) + mbedtls_snprintf( buf, buflen, "PK - Bad input parameters to function" ); + if( use_ret == -(MBEDTLS_ERR_PK_FILE_IO_ERROR) ) + mbedtls_snprintf( buf, buflen, "PK - Read/write of file failed" ); + if( use_ret == -(MBEDTLS_ERR_PK_KEY_INVALID_VERSION) ) + mbedtls_snprintf( buf, buflen, "PK - Unsupported key version" ); + if( use_ret == -(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT) ) + mbedtls_snprintf( buf, buflen, "PK - Invalid key tag or value" ); + if( use_ret == -(MBEDTLS_ERR_PK_UNKNOWN_PK_ALG) ) + mbedtls_snprintf( buf, buflen, "PK - Key algorithm is unsupported (only RSA and EC are supported)" ); + if( use_ret == -(MBEDTLS_ERR_PK_PASSWORD_REQUIRED) ) + mbedtls_snprintf( buf, buflen, "PK - Private key password can't be empty" ); + if( use_ret == -(MBEDTLS_ERR_PK_PASSWORD_MISMATCH) ) + mbedtls_snprintf( buf, buflen, "PK - Given private key password does not allow for correct decryption" ); + if( use_ret == -(MBEDTLS_ERR_PK_INVALID_PUBKEY) ) + mbedtls_snprintf( buf, buflen, "PK - The pubkey tag or value is invalid (only RSA and EC are supported)" ); + if( use_ret == -(MBEDTLS_ERR_PK_INVALID_ALG) ) + mbedtls_snprintf( buf, buflen, "PK - The algorithm tag or value is invalid" ); + if( use_ret == -(MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE) ) + mbedtls_snprintf( buf, buflen, "PK - Elliptic curve is unsupported (only NIST curves are supported)" ); + if( use_ret == -(MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE) ) + mbedtls_snprintf( buf, buflen, "PK - Unavailable feature, e.g. RSA disabled for RSA key" ); + if( use_ret == -(MBEDTLS_ERR_PK_SIG_LEN_MISMATCH) ) + mbedtls_snprintf( buf, buflen, "PK - The signature is valid but its length is less than expected" ); +#endif /* MBEDTLS_PK_C */ + +#if defined(MBEDTLS_PKCS12_C) + if( use_ret == -(MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA) ) + mbedtls_snprintf( buf, buflen, "PKCS12 - Bad input parameters to function" ); + if( use_ret == -(MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE) ) + mbedtls_snprintf( buf, buflen, "PKCS12 - Feature not available, e.g. unsupported encryption scheme" ); + if( use_ret == -(MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT) ) + mbedtls_snprintf( buf, buflen, "PKCS12 - PBE ASN.1 data not as expected" ); + if( use_ret == -(MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH) ) + mbedtls_snprintf( buf, buflen, "PKCS12 - Given private key password does not allow for correct decryption" ); +#endif /* MBEDTLS_PKCS12_C */ + +#if defined(MBEDTLS_PKCS5_C) + if( use_ret == -(MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA) ) + mbedtls_snprintf( buf, buflen, "PKCS5 - Bad input parameters to function" ); + if( use_ret == -(MBEDTLS_ERR_PKCS5_INVALID_FORMAT) ) + mbedtls_snprintf( buf, buflen, "PKCS5 - Unexpected ASN.1 data" ); + if( use_ret == -(MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE) ) + mbedtls_snprintf( buf, buflen, "PKCS5 - Requested encryption or digest alg not available" ); + if( use_ret == -(MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH) ) + mbedtls_snprintf( buf, buflen, "PKCS5 - Given private key password does not allow for correct decryption" ); +#endif /* MBEDTLS_PKCS5_C */ + +#if defined(MBEDTLS_RSA_C) + if( use_ret == -(MBEDTLS_ERR_RSA_BAD_INPUT_DATA) ) + mbedtls_snprintf( buf, buflen, "RSA - Bad input parameters to function" ); + if( use_ret == -(MBEDTLS_ERR_RSA_INVALID_PADDING) ) + mbedtls_snprintf( buf, buflen, "RSA - Input data contains invalid padding and is rejected" ); + if( use_ret == -(MBEDTLS_ERR_RSA_KEY_GEN_FAILED) ) + mbedtls_snprintf( buf, buflen, "RSA - Something failed during generation of a key" ); + if( use_ret == -(MBEDTLS_ERR_RSA_KEY_CHECK_FAILED) ) + mbedtls_snprintf( buf, buflen, "RSA - Key failed to pass the library's validity check" ); + if( use_ret == -(MBEDTLS_ERR_RSA_PUBLIC_FAILED) ) + mbedtls_snprintf( buf, buflen, "RSA - The public key operation failed" ); + if( use_ret == -(MBEDTLS_ERR_RSA_PRIVATE_FAILED) ) + mbedtls_snprintf( buf, buflen, "RSA - The private key operation failed" ); + if( use_ret == -(MBEDTLS_ERR_RSA_VERIFY_FAILED) ) + mbedtls_snprintf( buf, buflen, "RSA - The PKCS#1 verification failed" ); + if( use_ret == -(MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE) ) + mbedtls_snprintf( buf, buflen, "RSA - The output buffer for decryption is not large enough" ); + if( use_ret == -(MBEDTLS_ERR_RSA_RNG_FAILED) ) + mbedtls_snprintf( buf, buflen, "RSA - The random generator failed to generate non-zeros" ); +#endif /* MBEDTLS_RSA_C */ + +#if defined(MBEDTLS_SSL_TLS_C) + if( use_ret == -(MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE) ) + mbedtls_snprintf( buf, buflen, "SSL - The requested feature is not available" ); + if( use_ret == -(MBEDTLS_ERR_SSL_BAD_INPUT_DATA) ) + mbedtls_snprintf( buf, buflen, "SSL - Bad input parameters to function" ); + if( use_ret == -(MBEDTLS_ERR_SSL_INVALID_MAC) ) + mbedtls_snprintf( buf, buflen, "SSL - Verification of the message MAC failed" ); + if( use_ret == -(MBEDTLS_ERR_SSL_INVALID_RECORD) ) + mbedtls_snprintf( buf, buflen, "SSL - An invalid SSL record was received" ); + if( use_ret == -(MBEDTLS_ERR_SSL_CONN_EOF) ) + mbedtls_snprintf( buf, buflen, "SSL - The connection indicated an EOF" ); + if( use_ret == -(MBEDTLS_ERR_SSL_UNKNOWN_CIPHER) ) + mbedtls_snprintf( buf, buflen, "SSL - An unknown cipher was received" ); + if( use_ret == -(MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN) ) + mbedtls_snprintf( buf, buflen, "SSL - The server has no ciphersuites in common with the client" ); + if( use_ret == -(MBEDTLS_ERR_SSL_NO_RNG) ) + mbedtls_snprintf( buf, buflen, "SSL - No RNG was provided to the SSL module" ); + if( use_ret == -(MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE) ) + mbedtls_snprintf( buf, buflen, "SSL - No client certification received from the client, but required by the authentication mode" ); + if( use_ret == -(MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE) ) + mbedtls_snprintf( buf, buflen, "SSL - Our own certificate(s) is/are too large to send in an SSL message" ); + if( use_ret == -(MBEDTLS_ERR_SSL_CERTIFICATE_REQUIRED) ) + mbedtls_snprintf( buf, buflen, "SSL - The own certificate is not set, but needed by the server" ); + if( use_ret == -(MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED) ) + mbedtls_snprintf( buf, buflen, "SSL - The own private key or pre-shared key is not set, but needed" ); + if( use_ret == -(MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED) ) + mbedtls_snprintf( buf, buflen, "SSL - No CA Chain is set, but required to operate" ); + if( use_ret == -(MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE) ) + mbedtls_snprintf( buf, buflen, "SSL - An unexpected message was received from our peer" ); + if( use_ret == -(MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE) ) + { + mbedtls_snprintf( buf, buflen, "SSL - A fatal alert message was received from our peer" ); + return; + } + if( use_ret == -(MBEDTLS_ERR_SSL_PEER_VERIFY_FAILED) ) + mbedtls_snprintf( buf, buflen, "SSL - Verification of our peer failed" ); + if( use_ret == -(MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) ) + mbedtls_snprintf( buf, buflen, "SSL - The peer notified us that the connection is going to be closed" ); + if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO) ) + mbedtls_snprintf( buf, buflen, "SSL - Processing of the ClientHello handshake message failed" ); + if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO) ) + mbedtls_snprintf( buf, buflen, "SSL - Processing of the ServerHello handshake message failed" ); + if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE) ) + mbedtls_snprintf( buf, buflen, "SSL - Processing of the Certificate handshake message failed" ); + if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST) ) + mbedtls_snprintf( buf, buflen, "SSL - Processing of the CertificateRequest handshake message failed" ); + if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE) ) + mbedtls_snprintf( buf, buflen, "SSL - Processing of the ServerKeyExchange handshake message failed" ); + if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE) ) + mbedtls_snprintf( buf, buflen, "SSL - Processing of the ServerHelloDone handshake message failed" ); + if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE) ) + mbedtls_snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed" ); + if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP) ) + mbedtls_snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Read Public" ); + if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS) ) + mbedtls_snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Calculate Secret" ); + if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY) ) + mbedtls_snprintf( buf, buflen, "SSL - Processing of the CertificateVerify handshake message failed" ); + if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC) ) + mbedtls_snprintf( buf, buflen, "SSL - Processing of the ChangeCipherSpec handshake message failed" ); + if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_FINISHED) ) + mbedtls_snprintf( buf, buflen, "SSL - Processing of the Finished handshake message failed" ); + if( use_ret == -(MBEDTLS_ERR_SSL_ALLOC_FAILED) ) + mbedtls_snprintf( buf, buflen, "SSL - Memory allocation failed" ); + if( use_ret == -(MBEDTLS_ERR_SSL_HW_ACCEL_FAILED) ) + mbedtls_snprintf( buf, buflen, "SSL - Hardware acceleration function returned with error" ); + if( use_ret == -(MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH) ) + mbedtls_snprintf( buf, buflen, "SSL - Hardware acceleration function skipped / left alone data" ); + if( use_ret == -(MBEDTLS_ERR_SSL_COMPRESSION_FAILED) ) + mbedtls_snprintf( buf, buflen, "SSL - Processing of the compression / decompression failed" ); + if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION) ) + mbedtls_snprintf( buf, buflen, "SSL - Handshake protocol not within min/max boundaries" ); + if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET) ) + mbedtls_snprintf( buf, buflen, "SSL - Processing of the NewSessionTicket handshake message failed" ); + if( use_ret == -(MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED) ) + mbedtls_snprintf( buf, buflen, "SSL - Session ticket has expired" ); + if( use_ret == -(MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH) ) + mbedtls_snprintf( buf, buflen, "SSL - Public key type mismatch (eg, asked for RSA key exchange and presented EC key)" ); + if( use_ret == -(MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY) ) + mbedtls_snprintf( buf, buflen, "SSL - Unknown identity received (eg, PSK identity)" ); + if( use_ret == -(MBEDTLS_ERR_SSL_INTERNAL_ERROR) ) + mbedtls_snprintf( buf, buflen, "SSL - Internal error (eg, unexpected failure in lower-level module)" ); + if( use_ret == -(MBEDTLS_ERR_SSL_COUNTER_WRAPPING) ) + mbedtls_snprintf( buf, buflen, "SSL - A counter would wrap (eg, too many messages exchanged)" ); + if( use_ret == -(MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO) ) + mbedtls_snprintf( buf, buflen, "SSL - Unexpected message at ServerHello in renegotiation" ); + if( use_ret == -(MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED) ) + mbedtls_snprintf( buf, buflen, "SSL - DTLS client must retry for hello verification" ); + if( use_ret == -(MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL) ) + mbedtls_snprintf( buf, buflen, "SSL - A buffer is too small to receive or write a message" ); + if( use_ret == -(MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE) ) + mbedtls_snprintf( buf, buflen, "SSL - None of the common ciphersuites is usable (eg, no suitable certificate, see debug messages)" ); + if( use_ret == -(MBEDTLS_ERR_SSL_WANT_READ) ) + mbedtls_snprintf( buf, buflen, "SSL - Connection requires a read call" ); + if( use_ret == -(MBEDTLS_ERR_SSL_WANT_WRITE) ) + mbedtls_snprintf( buf, buflen, "SSL - Connection requires a write call" ); + if( use_ret == -(MBEDTLS_ERR_SSL_TIMEOUT) ) + mbedtls_snprintf( buf, buflen, "SSL - The operation timed out" ); + if( use_ret == -(MBEDTLS_ERR_SSL_CLIENT_RECONNECT) ) + mbedtls_snprintf( buf, buflen, "SSL - The client initiated a reconnect from the same port" ); + if( use_ret == -(MBEDTLS_ERR_SSL_UNEXPECTED_RECORD) ) + mbedtls_snprintf( buf, buflen, "SSL - Record header looks valid but is not expected" ); + if( use_ret == -(MBEDTLS_ERR_SSL_NON_FATAL) ) + mbedtls_snprintf( buf, buflen, "SSL - The alert message received indicates a non-fatal error" ); + if( use_ret == -(MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH) ) + mbedtls_snprintf( buf, buflen, "SSL - Couldn't set the hash for verifying CertificateVerify" ); +#endif /* MBEDTLS_SSL_TLS_C */ + +#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C) + if( use_ret == -(MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE) ) + mbedtls_snprintf( buf, buflen, "X509 - Unavailable feature, e.g. RSA hashing/encryption combination" ); + if( use_ret == -(MBEDTLS_ERR_X509_UNKNOWN_OID) ) + mbedtls_snprintf( buf, buflen, "X509 - Requested OID is unknown" ); + if( use_ret == -(MBEDTLS_ERR_X509_INVALID_FORMAT) ) + mbedtls_snprintf( buf, buflen, "X509 - The CRT/CRL/CSR format is invalid, e.g. different type expected" ); + if( use_ret == -(MBEDTLS_ERR_X509_INVALID_VERSION) ) + mbedtls_snprintf( buf, buflen, "X509 - The CRT/CRL/CSR version element is invalid" ); + if( use_ret == -(MBEDTLS_ERR_X509_INVALID_SERIAL) ) + mbedtls_snprintf( buf, buflen, "X509 - The serial tag or value is invalid" ); + if( use_ret == -(MBEDTLS_ERR_X509_INVALID_ALG) ) + mbedtls_snprintf( buf, buflen, "X509 - The algorithm tag or value is invalid" ); + if( use_ret == -(MBEDTLS_ERR_X509_INVALID_NAME) ) + mbedtls_snprintf( buf, buflen, "X509 - The name tag or value is invalid" ); + if( use_ret == -(MBEDTLS_ERR_X509_INVALID_DATE) ) + mbedtls_snprintf( buf, buflen, "X509 - The date tag or value is invalid" ); + if( use_ret == -(MBEDTLS_ERR_X509_INVALID_SIGNATURE) ) + mbedtls_snprintf( buf, buflen, "X509 - The signature tag or value invalid" ); + if( use_ret == -(MBEDTLS_ERR_X509_INVALID_EXTENSIONS) ) + mbedtls_snprintf( buf, buflen, "X509 - The extension tag or value is invalid" ); + if( use_ret == -(MBEDTLS_ERR_X509_UNKNOWN_VERSION) ) + mbedtls_snprintf( buf, buflen, "X509 - CRT/CRL/CSR has an unsupported version number" ); + if( use_ret == -(MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG) ) + mbedtls_snprintf( buf, buflen, "X509 - Signature algorithm (oid) is unsupported" ); + if( use_ret == -(MBEDTLS_ERR_X509_SIG_MISMATCH) ) + mbedtls_snprintf( buf, buflen, "X509 - Signature algorithms do not match. (see \\c ::mbedtls_x509_crt sig_oid)" ); + if( use_ret == -(MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) ) + mbedtls_snprintf( buf, buflen, "X509 - Certificate verification failed, e.g. CRL, CA or signature check failed" ); + if( use_ret == -(MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT) ) + mbedtls_snprintf( buf, buflen, "X509 - Format not recognized as DER or PEM" ); + if( use_ret == -(MBEDTLS_ERR_X509_BAD_INPUT_DATA) ) + mbedtls_snprintf( buf, buflen, "X509 - Input invalid" ); + if( use_ret == -(MBEDTLS_ERR_X509_ALLOC_FAILED) ) + mbedtls_snprintf( buf, buflen, "X509 - Allocation of memory failed" ); + if( use_ret == -(MBEDTLS_ERR_X509_FILE_IO_ERROR) ) + mbedtls_snprintf( buf, buflen, "X509 - Read/write of file failed" ); + if( use_ret == -(MBEDTLS_ERR_X509_BUFFER_TOO_SMALL) ) + mbedtls_snprintf( buf, buflen, "X509 - Destination buffer is too small" ); +#endif /* MBEDTLS_X509_USE_C || MBEDTLS_X509_CREATE_C */ + // END generated code + + if( strlen( buf ) == 0 ) + mbedtls_snprintf( buf, buflen, "UNKNOWN ERROR CODE (%04X)", use_ret ); + } + + use_ret = ret & ~0xFF80; + + if( use_ret == 0 ) + return; + + // If high level code is present, make a concatenation between both + // error strings. + // + len = strlen( buf ); + + if( len > 0 ) + { + if( buflen - len < 5 ) + return; + + mbedtls_snprintf( buf + len, buflen - len, " : " ); + + buf += len + 3; + buflen -= len + 3; + } + + // Low level error codes + // + // BEGIN generated code +#if defined(MBEDTLS_AES_C) + if( use_ret == -(MBEDTLS_ERR_AES_INVALID_KEY_LENGTH) ) + mbedtls_snprintf( buf, buflen, "AES - Invalid key length" ); + if( use_ret == -(MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH) ) + mbedtls_snprintf( buf, buflen, "AES - Invalid data input length" ); +#endif /* MBEDTLS_AES_C */ + +#if defined(MBEDTLS_ASN1_PARSE_C) + if( use_ret == -(MBEDTLS_ERR_ASN1_OUT_OF_DATA) ) + mbedtls_snprintf( buf, buflen, "ASN1 - Out of data when parsing an ASN1 data structure" ); + if( use_ret == -(MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) ) + mbedtls_snprintf( buf, buflen, "ASN1 - ASN1 tag was of an unexpected value" ); + if( use_ret == -(MBEDTLS_ERR_ASN1_INVALID_LENGTH) ) + mbedtls_snprintf( buf, buflen, "ASN1 - Error when trying to determine the length or invalid length" ); + if( use_ret == -(MBEDTLS_ERR_ASN1_LENGTH_MISMATCH) ) + mbedtls_snprintf( buf, buflen, "ASN1 - Actual length differs from expected length" ); + if( use_ret == -(MBEDTLS_ERR_ASN1_INVALID_DATA) ) + mbedtls_snprintf( buf, buflen, "ASN1 - Data is invalid. (not used)" ); + if( use_ret == -(MBEDTLS_ERR_ASN1_ALLOC_FAILED) ) + mbedtls_snprintf( buf, buflen, "ASN1 - Memory allocation failed" ); + if( use_ret == -(MBEDTLS_ERR_ASN1_BUF_TOO_SMALL) ) + mbedtls_snprintf( buf, buflen, "ASN1 - Buffer too small when writing ASN.1 data structure" ); +#endif /* MBEDTLS_ASN1_PARSE_C */ + +#if defined(MBEDTLS_BASE64_C) + if( use_ret == -(MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL) ) + mbedtls_snprintf( buf, buflen, "BASE64 - Output buffer too small" ); + if( use_ret == -(MBEDTLS_ERR_BASE64_INVALID_CHARACTER) ) + mbedtls_snprintf( buf, buflen, "BASE64 - Invalid character in input" ); +#endif /* MBEDTLS_BASE64_C */ + +#if defined(MBEDTLS_BIGNUM_C) + if( use_ret == -(MBEDTLS_ERR_MPI_FILE_IO_ERROR) ) + mbedtls_snprintf( buf, buflen, "BIGNUM - An error occurred while reading from or writing to a file" ); + if( use_ret == -(MBEDTLS_ERR_MPI_BAD_INPUT_DATA) ) + mbedtls_snprintf( buf, buflen, "BIGNUM - Bad input parameters to function" ); + if( use_ret == -(MBEDTLS_ERR_MPI_INVALID_CHARACTER) ) + mbedtls_snprintf( buf, buflen, "BIGNUM - There is an invalid character in the digit string" ); + if( use_ret == -(MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL) ) + mbedtls_snprintf( buf, buflen, "BIGNUM - The buffer is too small to write to" ); + if( use_ret == -(MBEDTLS_ERR_MPI_NEGATIVE_VALUE) ) + mbedtls_snprintf( buf, buflen, "BIGNUM - The input arguments are negative or result in illegal output" ); + if( use_ret == -(MBEDTLS_ERR_MPI_DIVISION_BY_ZERO) ) + mbedtls_snprintf( buf, buflen, "BIGNUM - The input argument for division is zero, which is not allowed" ); + if( use_ret == -(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE) ) + mbedtls_snprintf( buf, buflen, "BIGNUM - The input arguments are not acceptable" ); + if( use_ret == -(MBEDTLS_ERR_MPI_ALLOC_FAILED) ) + mbedtls_snprintf( buf, buflen, "BIGNUM - Memory allocation failed" ); +#endif /* MBEDTLS_BIGNUM_C */ + +#if defined(MBEDTLS_BLOWFISH_C) + if( use_ret == -(MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH) ) + mbedtls_snprintf( buf, buflen, "BLOWFISH - Invalid key length" ); + if( use_ret == -(MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH) ) + mbedtls_snprintf( buf, buflen, "BLOWFISH - Invalid data input length" ); +#endif /* MBEDTLS_BLOWFISH_C */ + +#if defined(MBEDTLS_CAMELLIA_C) + if( use_ret == -(MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH) ) + mbedtls_snprintf( buf, buflen, "CAMELLIA - Invalid key length" ); + if( use_ret == -(MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH) ) + mbedtls_snprintf( buf, buflen, "CAMELLIA - Invalid data input length" ); +#endif /* MBEDTLS_CAMELLIA_C */ + +#if defined(MBEDTLS_CCM_C) + if( use_ret == -(MBEDTLS_ERR_CCM_BAD_INPUT) ) + mbedtls_snprintf( buf, buflen, "CCM - Bad input parameters to function" ); + if( use_ret == -(MBEDTLS_ERR_CCM_AUTH_FAILED) ) + mbedtls_snprintf( buf, buflen, "CCM - Authenticated decryption failed" ); +#endif /* MBEDTLS_CCM_C */ + +#if defined(MBEDTLS_CTR_DRBG_C) + if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED) ) + mbedtls_snprintf( buf, buflen, "CTR_DRBG - The entropy source failed" ); + if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG) ) + mbedtls_snprintf( buf, buflen, "CTR_DRBG - Too many random requested in single call" ); + if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG) ) + mbedtls_snprintf( buf, buflen, "CTR_DRBG - Input too large (Entropy + additional)" ); + if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR) ) + mbedtls_snprintf( buf, buflen, "CTR_DRBG - Read/write error in file" ); +#endif /* MBEDTLS_CTR_DRBG_C */ + +#if defined(MBEDTLS_DES_C) + if( use_ret == -(MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH) ) + mbedtls_snprintf( buf, buflen, "DES - The data input has an invalid length" ); +#endif /* MBEDTLS_DES_C */ + +#if defined(MBEDTLS_ENTROPY_C) + if( use_ret == -(MBEDTLS_ERR_ENTROPY_SOURCE_FAILED) ) + mbedtls_snprintf( buf, buflen, "ENTROPY - Critical entropy source failure" ); + if( use_ret == -(MBEDTLS_ERR_ENTROPY_MAX_SOURCES) ) + mbedtls_snprintf( buf, buflen, "ENTROPY - No more sources can be added" ); + if( use_ret == -(MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED) ) + mbedtls_snprintf( buf, buflen, "ENTROPY - No sources have been added to poll" ); + if( use_ret == -(MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE) ) + mbedtls_snprintf( buf, buflen, "ENTROPY - No strong sources have been added to poll" ); + if( use_ret == -(MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR) ) + mbedtls_snprintf( buf, buflen, "ENTROPY - Read/write error in file" ); +#endif /* MBEDTLS_ENTROPY_C */ + +#if defined(MBEDTLS_GCM_C) + if( use_ret == -(MBEDTLS_ERR_GCM_AUTH_FAILED) ) + mbedtls_snprintf( buf, buflen, "GCM - Authenticated decryption failed" ); + if( use_ret == -(MBEDTLS_ERR_GCM_BAD_INPUT) ) + mbedtls_snprintf( buf, buflen, "GCM - Bad input parameters to function" ); +#endif /* MBEDTLS_GCM_C */ + +#if defined(MBEDTLS_HMAC_DRBG_C) + if( use_ret == -(MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG) ) + mbedtls_snprintf( buf, buflen, "HMAC_DRBG - Too many random requested in single call" ); + if( use_ret == -(MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG) ) + mbedtls_snprintf( buf, buflen, "HMAC_DRBG - Input too large (Entropy + additional)" ); + if( use_ret == -(MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR) ) + mbedtls_snprintf( buf, buflen, "HMAC_DRBG - Read/write error in file" ); + if( use_ret == -(MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED) ) + mbedtls_snprintf( buf, buflen, "HMAC_DRBG - The entropy source failed" ); +#endif /* MBEDTLS_HMAC_DRBG_C */ + +#if defined(MBEDTLS_NET_C) + if( use_ret == -(MBEDTLS_ERR_NET_SOCKET_FAILED) ) + mbedtls_snprintf( buf, buflen, "NET - Failed to open a socket" ); + if( use_ret == -(MBEDTLS_ERR_NET_CONNECT_FAILED) ) + mbedtls_snprintf( buf, buflen, "NET - The connection to the given server / port failed" ); + if( use_ret == -(MBEDTLS_ERR_NET_BIND_FAILED) ) + mbedtls_snprintf( buf, buflen, "NET - Binding of the socket failed" ); + if( use_ret == -(MBEDTLS_ERR_NET_LISTEN_FAILED) ) + mbedtls_snprintf( buf, buflen, "NET - Could not listen on the socket" ); + if( use_ret == -(MBEDTLS_ERR_NET_ACCEPT_FAILED) ) + mbedtls_snprintf( buf, buflen, "NET - Could not accept the incoming connection" ); + if( use_ret == -(MBEDTLS_ERR_NET_RECV_FAILED) ) + mbedtls_snprintf( buf, buflen, "NET - Reading information from the socket failed" ); + if( use_ret == -(MBEDTLS_ERR_NET_SEND_FAILED) ) + mbedtls_snprintf( buf, buflen, "NET - Sending information through the socket failed" ); + if( use_ret == -(MBEDTLS_ERR_NET_CONN_RESET) ) + mbedtls_snprintf( buf, buflen, "NET - Connection was reset by peer" ); + if( use_ret == -(MBEDTLS_ERR_NET_UNKNOWN_HOST) ) + mbedtls_snprintf( buf, buflen, "NET - Failed to get an IP address for the given hostname" ); + if( use_ret == -(MBEDTLS_ERR_NET_BUFFER_TOO_SMALL) ) + mbedtls_snprintf( buf, buflen, "NET - Buffer is too small to hold the data" ); + if( use_ret == -(MBEDTLS_ERR_NET_INVALID_CONTEXT) ) + mbedtls_snprintf( buf, buflen, "NET - The context is invalid, eg because it was free()ed" ); +#endif /* MBEDTLS_NET_C */ + +#if defined(MBEDTLS_OID_C) + if( use_ret == -(MBEDTLS_ERR_OID_NOT_FOUND) ) + mbedtls_snprintf( buf, buflen, "OID - OID is not found" ); + if( use_ret == -(MBEDTLS_ERR_OID_BUF_TOO_SMALL) ) + mbedtls_snprintf( buf, buflen, "OID - output buffer is too small" ); +#endif /* MBEDTLS_OID_C */ + +#if defined(MBEDTLS_PADLOCK_C) + if( use_ret == -(MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED) ) + mbedtls_snprintf( buf, buflen, "PADLOCK - Input data should be aligned" ); +#endif /* MBEDTLS_PADLOCK_C */ + +#if defined(MBEDTLS_THREADING_C) + if( use_ret == -(MBEDTLS_ERR_THREADING_FEATURE_UNAVAILABLE) ) + mbedtls_snprintf( buf, buflen, "THREADING - The selected feature is not available" ); + if( use_ret == -(MBEDTLS_ERR_THREADING_BAD_INPUT_DATA) ) + mbedtls_snprintf( buf, buflen, "THREADING - Bad input parameters to function" ); + if( use_ret == -(MBEDTLS_ERR_THREADING_MUTEX_ERROR) ) + mbedtls_snprintf( buf, buflen, "THREADING - Locking / unlocking / free failed with error code" ); +#endif /* MBEDTLS_THREADING_C */ + +#if defined(MBEDTLS_XTEA_C) + if( use_ret == -(MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH) ) + mbedtls_snprintf( buf, buflen, "XTEA - The data input has an invalid length" ); +#endif /* MBEDTLS_XTEA_C */ + // END generated code + + if( strlen( buf ) != 0 ) + return; + + mbedtls_snprintf( buf, buflen, "UNKNOWN ERROR CODE (%04X)", use_ret ); +} + +#else /* MBEDTLS_ERROR_C */ + +#if defined(MBEDTLS_ERROR_STRERROR_DUMMY) + +/* + * Provide an non-function in case MBEDTLS_ERROR_C is not defined + */ +void mbedtls_strerror( int ret, char *buf, size_t buflen ) +{ + ((void) ret); + + if( buflen > 0 ) + buf[0] = '\0'; +} + +#endif /* MBEDTLS_ERROR_STRERROR_DUMMY */ + +#endif /* MBEDTLS_ERROR_C */ diff --git a/security/mbedtls/src/gcm.c b/security/mbedtls/src/gcm.c new file mode 100644 index 0000000000..f1210c52c3 --- /dev/null +++ b/security/mbedtls/src/gcm.c @@ -0,0 +1,952 @@ +/* + * NIST SP800-38D compliant GCM implementation + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +/* + * http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf + * + * See also: + * [MGV] http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf + * + * We use the algorithm described as Shoup's method with 4-bit tables in + * [MGV] 4.1, pp. 12-13, to enhance speed without using too much memory. + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_GCM_C) + +#include "mbedtls/gcm.h" + +#include + +#if defined(MBEDTLS_AESNI_C) +#include "mbedtls/aesni.h" +#endif + +#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_printf printf +#endif /* MBEDTLS_PLATFORM_C */ +#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ + +/* + * 32-bit integer manipulation macros (big endian) + */ +#ifndef GET_UINT32_BE +#define GET_UINT32_BE(n,b,i) \ +{ \ + (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ + | ( (uint32_t) (b)[(i) + 1] << 16 ) \ + | ( (uint32_t) (b)[(i) + 2] << 8 ) \ + | ( (uint32_t) (b)[(i) + 3] ); \ +} +#endif + +#ifndef PUT_UINT32_BE +#define PUT_UINT32_BE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) ); \ +} +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +/* + * Initialize a context + */ +void mbedtls_gcm_init( mbedtls_gcm_context *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_gcm_context ) ); +} + +/* + * Precompute small multiples of H, that is set + * HH[i] || HL[i] = H times i, + * where i is seen as a field element as in [MGV], ie high-order bits + * correspond to low powers of P. The result is stored in the same way, that + * is the high-order bit of HH corresponds to P^0 and the low-order bit of HL + * corresponds to P^127. + */ +static int gcm_gen_table( mbedtls_gcm_context *ctx ) +{ + int ret, i, j; + uint64_t hi, lo; + uint64_t vl, vh; + unsigned char h[16]; + size_t olen = 0; + + memset( h, 0, 16 ); + if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, h, 16, h, &olen ) ) != 0 ) + return( ret ); + + /* pack h as two 64-bits ints, big-endian */ + GET_UINT32_BE( hi, h, 0 ); + GET_UINT32_BE( lo, h, 4 ); + vh = (uint64_t) hi << 32 | lo; + + GET_UINT32_BE( hi, h, 8 ); + GET_UINT32_BE( lo, h, 12 ); + vl = (uint64_t) hi << 32 | lo; + + /* 8 = 1000 corresponds to 1 in GF(2^128) */ + ctx->HL[8] = vl; + ctx->HH[8] = vh; + +#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64) + /* With CLMUL support, we need only h, not the rest of the table */ + if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) + return( 0 ); +#endif + + /* 0 corresponds to 0 in GF(2^128) */ + ctx->HH[0] = 0; + ctx->HL[0] = 0; + + for( i = 4; i > 0; i >>= 1 ) + { + uint32_t T = ( vl & 1 ) * 0xe1000000U; + vl = ( vh << 63 ) | ( vl >> 1 ); + vh = ( vh >> 1 ) ^ ( (uint64_t) T << 32); + + ctx->HL[i] = vl; + ctx->HH[i] = vh; + } + + for( i = 2; i <= 8; i *= 2 ) + { + uint64_t *HiL = ctx->HL + i, *HiH = ctx->HH + i; + vh = *HiH; + vl = *HiL; + for( j = 1; j < i; j++ ) + { + HiH[j] = vh ^ ctx->HH[j]; + HiL[j] = vl ^ ctx->HL[j]; + } + } + + return( 0 ); +} + +int mbedtls_gcm_setkey( mbedtls_gcm_context *ctx, + mbedtls_cipher_id_t cipher, + const unsigned char *key, + unsigned int keybits ) +{ + int ret; + const mbedtls_cipher_info_t *cipher_info; + + cipher_info = mbedtls_cipher_info_from_values( cipher, keybits, MBEDTLS_MODE_ECB ); + if( cipher_info == NULL ) + return( MBEDTLS_ERR_GCM_BAD_INPUT ); + + if( cipher_info->block_size != 16 ) + return( MBEDTLS_ERR_GCM_BAD_INPUT ); + + mbedtls_cipher_free( &ctx->cipher_ctx ); + + if( ( ret = mbedtls_cipher_setup( &ctx->cipher_ctx, cipher_info ) ) != 0 ) + return( ret ); + + if( ( ret = mbedtls_cipher_setkey( &ctx->cipher_ctx, key, keybits, + MBEDTLS_ENCRYPT ) ) != 0 ) + { + return( ret ); + } + + if( ( ret = gcm_gen_table( ctx ) ) != 0 ) + return( ret ); + + return( 0 ); +} + +/* + * Shoup's method for multiplication use this table with + * last4[x] = x times P^128 + * where x and last4[x] are seen as elements of GF(2^128) as in [MGV] + */ +static const uint64_t last4[16] = +{ + 0x0000, 0x1c20, 0x3840, 0x2460, + 0x7080, 0x6ca0, 0x48c0, 0x54e0, + 0xe100, 0xfd20, 0xd940, 0xc560, + 0x9180, 0x8da0, 0xa9c0, 0xb5e0 +}; + +/* + * Sets output to x times H using the precomputed tables. + * x and output are seen as elements of GF(2^128) as in [MGV]. + */ +static void gcm_mult( mbedtls_gcm_context *ctx, const unsigned char x[16], + unsigned char output[16] ) +{ + int i = 0; + unsigned char lo, hi, rem; + uint64_t zh, zl; + +#if defined(MBEDTLS_AESNI_C) && defined(MBEDTLS_HAVE_X86_64) + if( mbedtls_aesni_has_support( MBEDTLS_AESNI_CLMUL ) ) { + unsigned char h[16]; + + PUT_UINT32_BE( ctx->HH[8] >> 32, h, 0 ); + PUT_UINT32_BE( ctx->HH[8], h, 4 ); + PUT_UINT32_BE( ctx->HL[8] >> 32, h, 8 ); + PUT_UINT32_BE( ctx->HL[8], h, 12 ); + + mbedtls_aesni_gcm_mult( output, x, h ); + return; + } +#endif /* MBEDTLS_AESNI_C && MBEDTLS_HAVE_X86_64 */ + + lo = x[15] & 0xf; + + zh = ctx->HH[lo]; + zl = ctx->HL[lo]; + + for( i = 15; i >= 0; i-- ) + { + lo = x[i] & 0xf; + hi = x[i] >> 4; + + if( i != 15 ) + { + rem = (unsigned char) zl & 0xf; + zl = ( zh << 60 ) | ( zl >> 4 ); + zh = ( zh >> 4 ); + zh ^= (uint64_t) last4[rem] << 48; + zh ^= ctx->HH[lo]; + zl ^= ctx->HL[lo]; + + } + + rem = (unsigned char) zl & 0xf; + zl = ( zh << 60 ) | ( zl >> 4 ); + zh = ( zh >> 4 ); + zh ^= (uint64_t) last4[rem] << 48; + zh ^= ctx->HH[hi]; + zl ^= ctx->HL[hi]; + } + + PUT_UINT32_BE( zh >> 32, output, 0 ); + PUT_UINT32_BE( zh, output, 4 ); + PUT_UINT32_BE( zl >> 32, output, 8 ); + PUT_UINT32_BE( zl, output, 12 ); +} + +int mbedtls_gcm_starts( mbedtls_gcm_context *ctx, + int mode, + const unsigned char *iv, + size_t iv_len, + const unsigned char *add, + size_t add_len ) +{ + int ret; + unsigned char work_buf[16]; + size_t i; + const unsigned char *p; + size_t use_len, olen = 0; + + /* IV and AD are limited to 2^64 bits, so 2^61 bytes */ + if( ( (uint64_t) iv_len ) >> 61 != 0 || + ( (uint64_t) add_len ) >> 61 != 0 ) + { + return( MBEDTLS_ERR_GCM_BAD_INPUT ); + } + + memset( ctx->y, 0x00, sizeof(ctx->y) ); + memset( ctx->buf, 0x00, sizeof(ctx->buf) ); + + ctx->mode = mode; + ctx->len = 0; + ctx->add_len = 0; + + if( iv_len == 12 ) + { + memcpy( ctx->y, iv, iv_len ); + ctx->y[15] = 1; + } + else + { + memset( work_buf, 0x00, 16 ); + PUT_UINT32_BE( iv_len * 8, work_buf, 12 ); + + p = iv; + while( iv_len > 0 ) + { + use_len = ( iv_len < 16 ) ? iv_len : 16; + + for( i = 0; i < use_len; i++ ) + ctx->y[i] ^= p[i]; + + gcm_mult( ctx, ctx->y, ctx->y ); + + iv_len -= use_len; + p += use_len; + } + + for( i = 0; i < 16; i++ ) + ctx->y[i] ^= work_buf[i]; + + gcm_mult( ctx, ctx->y, ctx->y ); + } + + if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ctx->base_ectr, + &olen ) ) != 0 ) + { + return( ret ); + } + + ctx->add_len = add_len; + p = add; + while( add_len > 0 ) + { + use_len = ( add_len < 16 ) ? add_len : 16; + + for( i = 0; i < use_len; i++ ) + ctx->buf[i] ^= p[i]; + + gcm_mult( ctx, ctx->buf, ctx->buf ); + + add_len -= use_len; + p += use_len; + } + + return( 0 ); +} + +int mbedtls_gcm_update( mbedtls_gcm_context *ctx, + size_t length, + const unsigned char *input, + unsigned char *output ) +{ + int ret; + unsigned char ectr[16]; + size_t i; + const unsigned char *p; + unsigned char *out_p = output; + size_t use_len, olen = 0; + + if( output > input && (size_t) ( output - input ) < length ) + return( MBEDTLS_ERR_GCM_BAD_INPUT ); + + /* Total length is restricted to 2^39 - 256 bits, ie 2^36 - 2^5 bytes + * Also check for possible overflow */ + if( ctx->len + length < ctx->len || + (uint64_t) ctx->len + length > 0xFFFFFFFE0ull ) + { + return( MBEDTLS_ERR_GCM_BAD_INPUT ); + } + + ctx->len += length; + + p = input; + while( length > 0 ) + { + use_len = ( length < 16 ) ? length : 16; + + for( i = 16; i > 12; i-- ) + if( ++ctx->y[i - 1] != 0 ) + break; + + if( ( ret = mbedtls_cipher_update( &ctx->cipher_ctx, ctx->y, 16, ectr, + &olen ) ) != 0 ) + { + return( ret ); + } + + for( i = 0; i < use_len; i++ ) + { + if( ctx->mode == MBEDTLS_GCM_DECRYPT ) + ctx->buf[i] ^= p[i]; + out_p[i] = ectr[i] ^ p[i]; + if( ctx->mode == MBEDTLS_GCM_ENCRYPT ) + ctx->buf[i] ^= out_p[i]; + } + + gcm_mult( ctx, ctx->buf, ctx->buf ); + + length -= use_len; + p += use_len; + out_p += use_len; + } + + return( 0 ); +} + +int mbedtls_gcm_finish( mbedtls_gcm_context *ctx, + unsigned char *tag, + size_t tag_len ) +{ + unsigned char work_buf[16]; + size_t i; + uint64_t orig_len = ctx->len * 8; + uint64_t orig_add_len = ctx->add_len * 8; + + if( tag_len > 16 || tag_len < 4 ) + return( MBEDTLS_ERR_GCM_BAD_INPUT ); + + memcpy( tag, ctx->base_ectr, tag_len ); + + if( orig_len || orig_add_len ) + { + memset( work_buf, 0x00, 16 ); + + PUT_UINT32_BE( ( orig_add_len >> 32 ), work_buf, 0 ); + PUT_UINT32_BE( ( orig_add_len ), work_buf, 4 ); + PUT_UINT32_BE( ( orig_len >> 32 ), work_buf, 8 ); + PUT_UINT32_BE( ( orig_len ), work_buf, 12 ); + + for( i = 0; i < 16; i++ ) + ctx->buf[i] ^= work_buf[i]; + + gcm_mult( ctx, ctx->buf, ctx->buf ); + + for( i = 0; i < tag_len; i++ ) + tag[i] ^= ctx->buf[i]; + } + + return( 0 ); +} + +int mbedtls_gcm_crypt_and_tag( mbedtls_gcm_context *ctx, + int mode, + size_t length, + const unsigned char *iv, + size_t iv_len, + const unsigned char *add, + size_t add_len, + const unsigned char *input, + unsigned char *output, + size_t tag_len, + unsigned char *tag ) +{ + int ret; + + if( ( ret = mbedtls_gcm_starts( ctx, mode, iv, iv_len, add, add_len ) ) != 0 ) + return( ret ); + + if( ( ret = mbedtls_gcm_update( ctx, length, input, output ) ) != 0 ) + return( ret ); + + if( ( ret = mbedtls_gcm_finish( ctx, tag, tag_len ) ) != 0 ) + return( ret ); + + return( 0 ); +} + +int mbedtls_gcm_auth_decrypt( mbedtls_gcm_context *ctx, + size_t length, + const unsigned char *iv, + size_t iv_len, + const unsigned char *add, + size_t add_len, + const unsigned char *tag, + size_t tag_len, + const unsigned char *input, + unsigned char *output ) +{ + int ret; + unsigned char check_tag[16]; + size_t i; + int diff; + + if( ( ret = mbedtls_gcm_crypt_and_tag( ctx, MBEDTLS_GCM_DECRYPT, length, + iv, iv_len, add, add_len, + input, output, tag_len, check_tag ) ) != 0 ) + { + return( ret ); + } + + /* Check tag in "constant-time" */ + for( diff = 0, i = 0; i < tag_len; i++ ) + diff |= tag[i] ^ check_tag[i]; + + if( diff != 0 ) + { + mbedtls_zeroize( output, length ); + return( MBEDTLS_ERR_GCM_AUTH_FAILED ); + } + + return( 0 ); +} + +void mbedtls_gcm_free( mbedtls_gcm_context *ctx ) +{ + mbedtls_cipher_free( &ctx->cipher_ctx ); + mbedtls_zeroize( ctx, sizeof( mbedtls_gcm_context ) ); +} + +#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_AES_C) +/* + * AES-GCM test vectors from: + * + * http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip + */ +#define MAX_TESTS 6 + +static const int key_index[MAX_TESTS] = + { 0, 0, 1, 1, 1, 1 }; + +static const unsigned char key[MAX_TESTS][32] = +{ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 }, +}; + +static const size_t iv_len[MAX_TESTS] = + { 12, 12, 12, 12, 8, 60 }; + +static const int iv_index[MAX_TESTS] = + { 0, 0, 1, 1, 1, 2 }; + +static const unsigned char iv[MAX_TESTS][64] = +{ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 }, + { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88 }, + { 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5, + 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa, + 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1, + 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28, + 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39, + 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54, + 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57, + 0xa6, 0x37, 0xb3, 0x9b }, +}; + +static const size_t add_len[MAX_TESTS] = + { 0, 0, 0, 20, 20, 20 }; + +static const int add_index[MAX_TESTS] = + { 0, 0, 0, 1, 1, 1 }; + +static const unsigned char additional[MAX_TESTS][64] = +{ + { 0x00 }, + { 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xab, 0xad, 0xda, 0xd2 }, +}; + +static const size_t pt_len[MAX_TESTS] = + { 0, 16, 64, 60, 60, 60 }; + +static const int pt_index[MAX_TESTS] = + { 0, 0, 1, 1, 1, 1 }; + +static const unsigned char pt[MAX_TESTS][64] = +{ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 }, +}; + +static const unsigned char ct[MAX_TESTS * 3][64] = +{ + { 0x00 }, + { 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92, + 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 }, + { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, + 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, + 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, + 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, + 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, + 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, + 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, + 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 }, + { 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, + 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, + 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, + 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, + 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, + 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, + 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, + 0x3d, 0x58, 0xe0, 0x91 }, + { 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a, + 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55, + 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8, + 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23, + 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2, + 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42, + 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07, + 0xc2, 0x3f, 0x45, 0x98 }, + { 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6, + 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94, + 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8, + 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7, + 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90, + 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f, + 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03, + 0x4c, 0x34, 0xae, 0xe5 }, + { 0x00 }, + { 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41, + 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 }, + { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41, + 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57, + 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84, + 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c, + 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25, + 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47, + 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9, + 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 }, + { 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41, + 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57, + 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84, + 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c, + 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25, + 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47, + 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9, + 0xcc, 0xda, 0x27, 0x10 }, + { 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54, + 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8, + 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f, + 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57, + 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75, + 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9, + 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f, + 0xa0, 0xf0, 0x62, 0xf7 }, + { 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c, + 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff, + 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef, + 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45, + 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9, + 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3, + 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7, + 0xe9, 0xb7, 0x37, 0x3b }, + { 0x00 }, + { 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e, + 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 }, + { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, + 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, + 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, + 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, + 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, + 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, + 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, + 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad }, + { 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, + 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, + 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, + 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, + 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, + 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, + 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, + 0xbc, 0xc9, 0xf6, 0x62 }, + { 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32, + 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb, + 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa, + 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0, + 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0, + 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78, + 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99, + 0xf4, 0x7c, 0x9b, 0x1f }, + { 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1, + 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20, + 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19, + 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4, + 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45, + 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde, + 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e, + 0x44, 0xae, 0x7e, 0x3f }, +}; + +static const unsigned char tag[MAX_TESTS * 3][16] = +{ + { 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61, + 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a }, + { 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd, + 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf }, + { 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6, + 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 }, + { 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb, + 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 }, + { 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85, + 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb }, + { 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa, + 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 }, + { 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b, + 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 }, + { 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab, + 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb }, + { 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf, + 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 }, + { 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f, + 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c }, + { 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24, + 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 }, + { 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb, + 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 }, + { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9, + 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b }, + { 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0, + 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 }, + { 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd, + 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c }, + { 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68, + 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b }, + { 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4, + 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 }, + { 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0, + 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a }, +}; + +int mbedtls_gcm_self_test( int verbose ) +{ + mbedtls_gcm_context ctx; + unsigned char buf[64]; + unsigned char tag_buf[16]; + int i, j, ret; + mbedtls_cipher_id_t cipher = MBEDTLS_CIPHER_ID_AES; + + mbedtls_gcm_init( &ctx ); + + for( j = 0; j < 3; j++ ) + { + int key_len = 128 + 64 * j; + + for( i = 0; i < MAX_TESTS; i++ ) + { + if( verbose != 0 ) + mbedtls_printf( " AES-GCM-%3d #%d (%s): ", + key_len, i, "enc" ); + + mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]], key_len ); + + ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_ENCRYPT, + pt_len[i], + iv[iv_index[i]], iv_len[i], + additional[add_index[i]], add_len[i], + pt[pt_index[i]], buf, 16, tag_buf ); + + if( ret != 0 || + memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 || + memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( 1 ); + } + + mbedtls_gcm_free( &ctx ); + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + + if( verbose != 0 ) + mbedtls_printf( " AES-GCM-%3d #%d (%s): ", + key_len, i, "dec" ); + + mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]], key_len ); + + ret = mbedtls_gcm_crypt_and_tag( &ctx, MBEDTLS_GCM_DECRYPT, + pt_len[i], + iv[iv_index[i]], iv_len[i], + additional[add_index[i]], add_len[i], + ct[j * 6 + i], buf, 16, tag_buf ); + + if( ret != 0 || + memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 || + memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( 1 ); + } + + mbedtls_gcm_free( &ctx ); + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + + if( verbose != 0 ) + mbedtls_printf( " AES-GCM-%3d #%d split (%s): ", + key_len, i, "enc" ); + + mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]], key_len ); + + ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_ENCRYPT, + iv[iv_index[i]], iv_len[i], + additional[add_index[i]], add_len[i] ); + if( ret != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( 1 ); + } + + if( pt_len[i] > 32 ) + { + size_t rest_len = pt_len[i] - 32; + ret = mbedtls_gcm_update( &ctx, 32, pt[pt_index[i]], buf ); + if( ret != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( 1 ); + } + + ret = mbedtls_gcm_update( &ctx, rest_len, pt[pt_index[i]] + 32, + buf + 32 ); + if( ret != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( 1 ); + } + } + else + { + ret = mbedtls_gcm_update( &ctx, pt_len[i], pt[pt_index[i]], buf ); + if( ret != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( 1 ); + } + } + + ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 ); + if( ret != 0 || + memcmp( buf, ct[j * 6 + i], pt_len[i] ) != 0 || + memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( 1 ); + } + + mbedtls_gcm_free( &ctx ); + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + + if( verbose != 0 ) + mbedtls_printf( " AES-GCM-%3d #%d split (%s): ", + key_len, i, "dec" ); + + mbedtls_gcm_setkey( &ctx, cipher, key[key_index[i]], key_len ); + + ret = mbedtls_gcm_starts( &ctx, MBEDTLS_GCM_DECRYPT, + iv[iv_index[i]], iv_len[i], + additional[add_index[i]], add_len[i] ); + if( ret != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( 1 ); + } + + if( pt_len[i] > 32 ) + { + size_t rest_len = pt_len[i] - 32; + ret = mbedtls_gcm_update( &ctx, 32, ct[j * 6 + i], buf ); + if( ret != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( 1 ); + } + + ret = mbedtls_gcm_update( &ctx, rest_len, ct[j * 6 + i] + 32, + buf + 32 ); + if( ret != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( 1 ); + } + } + else + { + ret = mbedtls_gcm_update( &ctx, pt_len[i], ct[j * 6 + i], buf ); + if( ret != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( 1 ); + } + } + + ret = mbedtls_gcm_finish( &ctx, tag_buf, 16 ); + if( ret != 0 || + memcmp( buf, pt[pt_index[i]], pt_len[i] ) != 0 || + memcmp( tag_buf, tag[j * 6 + i], 16 ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( 1 ); + } + + mbedtls_gcm_free( &ctx ); + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + + } + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + + return( 0 ); +} + +#endif /* MBEDTLS_SELF_TEST && MBEDTLS_AES_C */ + +#endif /* MBEDTLS_GCM_C */ diff --git a/security/mbedtls/src/havege.c b/security/mbedtls/src/havege.c new file mode 100644 index 0000000000..2b75ef7bd8 --- /dev/null +++ b/security/mbedtls/src/havege.c @@ -0,0 +1,245 @@ +/** + * \brief HAVEGE: HArdware Volatile Entropy Gathering and Expansion + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +/* + * The HAVEGE RNG was designed by Andre Seznec in 2002. + * + * http://www.irisa.fr/caps/projects/hipsor/publi.php + * + * Contact: seznec(at)irisa_dot_fr - orocheco(at)irisa_dot_fr + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_HAVEGE_C) + +#include "mbedtls/havege.h" +#include "mbedtls/timing.h" + +#include + +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +/* ------------------------------------------------------------------------ + * On average, one iteration accesses two 8-word blocks in the havege WALK + * table, and generates 16 words in the RES array. + * + * The data read in the WALK table is updated and permuted after each use. + * The result of the hardware clock counter read is used for this update. + * + * 25 conditional tests are present. The conditional tests are grouped in + * two nested groups of 12 conditional tests and 1 test that controls the + * permutation; on average, there should be 6 tests executed and 3 of them + * should be mispredicted. + * ------------------------------------------------------------------------ + */ + +#define SWAP(X,Y) { int *T = X; X = Y; Y = T; } + +#define TST1_ENTER if( PTEST & 1 ) { PTEST ^= 3; PTEST >>= 1; +#define TST2_ENTER if( PTEST & 1 ) { PTEST ^= 3; PTEST >>= 1; + +#define TST1_LEAVE U1++; } +#define TST2_LEAVE U2++; } + +#define ONE_ITERATION \ + \ + PTEST = PT1 >> 20; \ + \ + TST1_ENTER TST1_ENTER TST1_ENTER TST1_ENTER \ + TST1_ENTER TST1_ENTER TST1_ENTER TST1_ENTER \ + TST1_ENTER TST1_ENTER TST1_ENTER TST1_ENTER \ + \ + TST1_LEAVE TST1_LEAVE TST1_LEAVE TST1_LEAVE \ + TST1_LEAVE TST1_LEAVE TST1_LEAVE TST1_LEAVE \ + TST1_LEAVE TST1_LEAVE TST1_LEAVE TST1_LEAVE \ + \ + PTX = (PT1 >> 18) & 7; \ + PT1 &= 0x1FFF; \ + PT2 &= 0x1FFF; \ + CLK = (int) mbedtls_timing_hardclock(); \ + \ + i = 0; \ + A = &WALK[PT1 ]; RES[i++] ^= *A; \ + B = &WALK[PT2 ]; RES[i++] ^= *B; \ + C = &WALK[PT1 ^ 1]; RES[i++] ^= *C; \ + D = &WALK[PT2 ^ 4]; RES[i++] ^= *D; \ + \ + IN = (*A >> (1)) ^ (*A << (31)) ^ CLK; \ + *A = (*B >> (2)) ^ (*B << (30)) ^ CLK; \ + *B = IN ^ U1; \ + *C = (*C >> (3)) ^ (*C << (29)) ^ CLK; \ + *D = (*D >> (4)) ^ (*D << (28)) ^ CLK; \ + \ + A = &WALK[PT1 ^ 2]; RES[i++] ^= *A; \ + B = &WALK[PT2 ^ 2]; RES[i++] ^= *B; \ + C = &WALK[PT1 ^ 3]; RES[i++] ^= *C; \ + D = &WALK[PT2 ^ 6]; RES[i++] ^= *D; \ + \ + if( PTEST & 1 ) SWAP( A, C ); \ + \ + IN = (*A >> (5)) ^ (*A << (27)) ^ CLK; \ + *A = (*B >> (6)) ^ (*B << (26)) ^ CLK; \ + *B = IN; CLK = (int) mbedtls_timing_hardclock(); \ + *C = (*C >> (7)) ^ (*C << (25)) ^ CLK; \ + *D = (*D >> (8)) ^ (*D << (24)) ^ CLK; \ + \ + A = &WALK[PT1 ^ 4]; \ + B = &WALK[PT2 ^ 1]; \ + \ + PTEST = PT2 >> 1; \ + \ + PT2 = (RES[(i - 8) ^ PTY] ^ WALK[PT2 ^ PTY ^ 7]); \ + PT2 = ((PT2 & 0x1FFF) & (~8)) ^ ((PT1 ^ 8) & 0x8); \ + PTY = (PT2 >> 10) & 7; \ + \ + TST2_ENTER TST2_ENTER TST2_ENTER TST2_ENTER \ + TST2_ENTER TST2_ENTER TST2_ENTER TST2_ENTER \ + TST2_ENTER TST2_ENTER TST2_ENTER TST2_ENTER \ + \ + TST2_LEAVE TST2_LEAVE TST2_LEAVE TST2_LEAVE \ + TST2_LEAVE TST2_LEAVE TST2_LEAVE TST2_LEAVE \ + TST2_LEAVE TST2_LEAVE TST2_LEAVE TST2_LEAVE \ + \ + C = &WALK[PT1 ^ 5]; \ + D = &WALK[PT2 ^ 5]; \ + \ + RES[i++] ^= *A; \ + RES[i++] ^= *B; \ + RES[i++] ^= *C; \ + RES[i++] ^= *D; \ + \ + IN = (*A >> ( 9)) ^ (*A << (23)) ^ CLK; \ + *A = (*B >> (10)) ^ (*B << (22)) ^ CLK; \ + *B = IN ^ U2; \ + *C = (*C >> (11)) ^ (*C << (21)) ^ CLK; \ + *D = (*D >> (12)) ^ (*D << (20)) ^ CLK; \ + \ + A = &WALK[PT1 ^ 6]; RES[i++] ^= *A; \ + B = &WALK[PT2 ^ 3]; RES[i++] ^= *B; \ + C = &WALK[PT1 ^ 7]; RES[i++] ^= *C; \ + D = &WALK[PT2 ^ 7]; RES[i++] ^= *D; \ + \ + IN = (*A >> (13)) ^ (*A << (19)) ^ CLK; \ + *A = (*B >> (14)) ^ (*B << (18)) ^ CLK; \ + *B = IN; \ + *C = (*C >> (15)) ^ (*C << (17)) ^ CLK; \ + *D = (*D >> (16)) ^ (*D << (16)) ^ CLK; \ + \ + PT1 = ( RES[( i - 8 ) ^ PTX] ^ \ + WALK[PT1 ^ PTX ^ 7] ) & (~1); \ + PT1 ^= (PT2 ^ 0x10) & 0x10; \ + \ + for( n++, i = 0; i < 16; i++ ) \ + hs->pool[n % MBEDTLS_HAVEGE_COLLECT_SIZE] ^= RES[i]; + +/* + * Entropy gathering function + */ +static void havege_fill( mbedtls_havege_state *hs ) +{ + int i, n = 0; + int U1, U2, *A, *B, *C, *D; + int PT1, PT2, *WALK, RES[16]; + int PTX, PTY, CLK, PTEST, IN; + + WALK = hs->WALK; + PT1 = hs->PT1; + PT2 = hs->PT2; + + PTX = U1 = 0; + PTY = U2 = 0; + + (void)PTX; + + memset( RES, 0, sizeof( RES ) ); + + while( n < MBEDTLS_HAVEGE_COLLECT_SIZE * 4 ) + { + ONE_ITERATION + ONE_ITERATION + ONE_ITERATION + ONE_ITERATION + } + + hs->PT1 = PT1; + hs->PT2 = PT2; + + hs->offset[0] = 0; + hs->offset[1] = MBEDTLS_HAVEGE_COLLECT_SIZE / 2; +} + +/* + * HAVEGE initialization + */ +void mbedtls_havege_init( mbedtls_havege_state *hs ) +{ + memset( hs, 0, sizeof( mbedtls_havege_state ) ); + + havege_fill( hs ); +} + +void mbedtls_havege_free( mbedtls_havege_state *hs ) +{ + if( hs == NULL ) + return; + + mbedtls_zeroize( hs, sizeof( mbedtls_havege_state ) ); +} + +/* + * HAVEGE rand function + */ +int mbedtls_havege_random( void *p_rng, unsigned char *buf, size_t len ) +{ + int val; + size_t use_len; + mbedtls_havege_state *hs = (mbedtls_havege_state *) p_rng; + unsigned char *p = buf; + + while( len > 0 ) + { + use_len = len; + if( use_len > sizeof(int) ) + use_len = sizeof(int); + + if( hs->offset[1] >= MBEDTLS_HAVEGE_COLLECT_SIZE ) + havege_fill( hs ); + + val = hs->pool[hs->offset[0]++]; + val ^= hs->pool[hs->offset[1]++]; + + memcpy( p, &val, use_len ); + + len -= use_len; + p += use_len; + } + + return( 0 ); +} + +#endif /* MBEDTLS_HAVEGE_C */ diff --git a/security/mbedtls/src/hmac_drbg.c b/security/mbedtls/src/hmac_drbg.c new file mode 100644 index 0000000000..bf5f9b5bd3 --- /dev/null +++ b/security/mbedtls/src/hmac_drbg.c @@ -0,0 +1,529 @@ +/* + * HMAC_DRBG implementation (NIST SP 800-90) + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +/* + * The NIST SP 800-90A DRBGs are described in the following publication. + * http://csrc.nist.gov/publications/nistpubs/800-90A/SP800-90A.pdf + * References below are based on rev. 1 (January 2012). + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_HMAC_DRBG_C) + +#include "mbedtls/hmac_drbg.h" + +#include + +#if defined(MBEDTLS_FS_IO) +#include +#endif + +#if defined(MBEDTLS_SELF_TEST) +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_printf printf +#endif /* MBEDTLS_SELF_TEST */ +#endif /* MBEDTLS_PLATFORM_C */ + +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +/* + * HMAC_DRBG context initialization + */ +void mbedtls_hmac_drbg_init( mbedtls_hmac_drbg_context *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_hmac_drbg_context ) ); + +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_init( &ctx->mutex ); +#endif +} + +/* + * HMAC_DRBG update, using optional additional data (10.1.2.2) + */ +void mbedtls_hmac_drbg_update( mbedtls_hmac_drbg_context *ctx, + const unsigned char *additional, size_t add_len ) +{ + size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info ); + unsigned char rounds = ( additional != NULL && add_len != 0 ) ? 2 : 1; + unsigned char sep[1]; + unsigned char K[MBEDTLS_MD_MAX_SIZE]; + + for( sep[0] = 0; sep[0] < rounds; sep[0]++ ) + { + /* Step 1 or 4 */ + mbedtls_md_hmac_reset( &ctx->md_ctx ); + mbedtls_md_hmac_update( &ctx->md_ctx, ctx->V, md_len ); + mbedtls_md_hmac_update( &ctx->md_ctx, sep, 1 ); + if( rounds == 2 ) + mbedtls_md_hmac_update( &ctx->md_ctx, additional, add_len ); + mbedtls_md_hmac_finish( &ctx->md_ctx, K ); + + /* Step 2 or 5 */ + mbedtls_md_hmac_starts( &ctx->md_ctx, K, md_len ); + mbedtls_md_hmac_update( &ctx->md_ctx, ctx->V, md_len ); + mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ); + } +} + +/* + * Simplified HMAC_DRBG initialisation (for use with deterministic ECDSA) + */ +int mbedtls_hmac_drbg_seed_buf( mbedtls_hmac_drbg_context *ctx, + const mbedtls_md_info_t * md_info, + const unsigned char *data, size_t data_len ) +{ + int ret; + + if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 ) + return( ret ); + + /* + * Set initial working state. + * Use the V memory location, which is currently all 0, to initialize the + * MD context with an all-zero key. Then set V to its initial value. + */ + mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, mbedtls_md_get_size( md_info ) ); + memset( ctx->V, 0x01, mbedtls_md_get_size( md_info ) ); + + mbedtls_hmac_drbg_update( ctx, data, data_len ); + + return( 0 ); +} + +/* + * HMAC_DRBG reseeding: 10.1.2.4 (arabic) + 9.2 (Roman) + */ +int mbedtls_hmac_drbg_reseed( mbedtls_hmac_drbg_context *ctx, + const unsigned char *additional, size_t len ) +{ + unsigned char seed[MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT]; + size_t seedlen; + + /* III. Check input length */ + if( len > MBEDTLS_HMAC_DRBG_MAX_INPUT || + ctx->entropy_len + len > MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT ) + { + return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG ); + } + + memset( seed, 0, MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT ); + + /* IV. Gather entropy_len bytes of entropy for the seed */ + if( ctx->f_entropy( ctx->p_entropy, seed, ctx->entropy_len ) != 0 ) + return( MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED ); + + seedlen = ctx->entropy_len; + + /* 1. Concatenate entropy and additional data if any */ + if( additional != NULL && len != 0 ) + { + memcpy( seed + seedlen, additional, len ); + seedlen += len; + } + + /* 2. Update state */ + mbedtls_hmac_drbg_update( ctx, seed, seedlen ); + + /* 3. Reset reseed_counter */ + ctx->reseed_counter = 1; + + /* 4. Done */ + return( 0 ); +} + +/* + * HMAC_DRBG initialisation (10.1.2.3 + 9.1) + */ +int mbedtls_hmac_drbg_seed( mbedtls_hmac_drbg_context *ctx, + const mbedtls_md_info_t * md_info, + int (*f_entropy)(void *, unsigned char *, size_t), + void *p_entropy, + const unsigned char *custom, + size_t len ) +{ + int ret; + size_t entropy_len, md_size; + + if( ( ret = mbedtls_md_setup( &ctx->md_ctx, md_info, 1 ) ) != 0 ) + return( ret ); + + md_size = mbedtls_md_get_size( md_info ); + + /* + * Set initial working state. + * Use the V memory location, which is currently all 0, to initialize the + * MD context with an all-zero key. Then set V to its initial value. + */ + mbedtls_md_hmac_starts( &ctx->md_ctx, ctx->V, md_size ); + memset( ctx->V, 0x01, md_size ); + + ctx->f_entropy = f_entropy; + ctx->p_entropy = p_entropy; + + ctx->reseed_interval = MBEDTLS_HMAC_DRBG_RESEED_INTERVAL; + + /* + * See SP800-57 5.6.1 (p. 65-66) for the security strength provided by + * each hash function, then according to SP800-90A rev1 10.1 table 2, + * min_entropy_len (in bits) is security_strength. + * + * (This also matches the sizes used in the NIST test vectors.) + */ + entropy_len = md_size <= 20 ? 16 : /* 160-bits hash -> 128 bits */ + md_size <= 28 ? 24 : /* 224-bits hash -> 192 bits */ + 32; /* better (256+) -> 256 bits */ + + /* + * For initialisation, use more entropy to emulate a nonce + * (Again, matches test vectors.) + */ + ctx->entropy_len = entropy_len * 3 / 2; + + if( ( ret = mbedtls_hmac_drbg_reseed( ctx, custom, len ) ) != 0 ) + return( ret ); + + ctx->entropy_len = entropy_len; + + return( 0 ); +} + +/* + * Set prediction resistance + */ +void mbedtls_hmac_drbg_set_prediction_resistance( mbedtls_hmac_drbg_context *ctx, + int resistance ) +{ + ctx->prediction_resistance = resistance; +} + +/* + * Set entropy length grabbed for reseeds + */ +void mbedtls_hmac_drbg_set_entropy_len( mbedtls_hmac_drbg_context *ctx, size_t len ) +{ + ctx->entropy_len = len; +} + +/* + * Set reseed interval + */ +void mbedtls_hmac_drbg_set_reseed_interval( mbedtls_hmac_drbg_context *ctx, int interval ) +{ + ctx->reseed_interval = interval; +} + +/* + * HMAC_DRBG random function with optional additional data: + * 10.1.2.5 (arabic) + 9.3 (Roman) + */ +int mbedtls_hmac_drbg_random_with_add( void *p_rng, + unsigned char *output, size_t out_len, + const unsigned char *additional, size_t add_len ) +{ + int ret; + mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng; + size_t md_len = mbedtls_md_get_size( ctx->md_ctx.md_info ); + size_t left = out_len; + unsigned char *out = output; + + /* II. Check request length */ + if( out_len > MBEDTLS_HMAC_DRBG_MAX_REQUEST ) + return( MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG ); + + /* III. Check input length */ + if( add_len > MBEDTLS_HMAC_DRBG_MAX_INPUT ) + return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG ); + + /* 1. (aka VII and IX) Check reseed counter and PR */ + if( ctx->f_entropy != NULL && /* For no-reseeding instances */ + ( ctx->prediction_resistance == MBEDTLS_HMAC_DRBG_PR_ON || + ctx->reseed_counter > ctx->reseed_interval ) ) + { + if( ( ret = mbedtls_hmac_drbg_reseed( ctx, additional, add_len ) ) != 0 ) + return( ret ); + + add_len = 0; /* VII.4 */ + } + + /* 2. Use additional data if any */ + if( additional != NULL && add_len != 0 ) + mbedtls_hmac_drbg_update( ctx, additional, add_len ); + + /* 3, 4, 5. Generate bytes */ + while( left != 0 ) + { + size_t use_len = left > md_len ? md_len : left; + + mbedtls_md_hmac_reset( &ctx->md_ctx ); + mbedtls_md_hmac_update( &ctx->md_ctx, ctx->V, md_len ); + mbedtls_md_hmac_finish( &ctx->md_ctx, ctx->V ); + + memcpy( out, ctx->V, use_len ); + out += use_len; + left -= use_len; + } + + /* 6. Update */ + mbedtls_hmac_drbg_update( ctx, additional, add_len ); + + /* 7. Update reseed counter */ + ctx->reseed_counter++; + + /* 8. Done */ + return( 0 ); +} + +/* + * HMAC_DRBG random function + */ +int mbedtls_hmac_drbg_random( void *p_rng, unsigned char *output, size_t out_len ) +{ + int ret; + mbedtls_hmac_drbg_context *ctx = (mbedtls_hmac_drbg_context *) p_rng; + +#if defined(MBEDTLS_THREADING_C) + if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) + return( ret ); +#endif + + ret = mbedtls_hmac_drbg_random_with_add( ctx, output, out_len, NULL, 0 ); + +#if defined(MBEDTLS_THREADING_C) + if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) + return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); +#endif + + return( ret ); +} + +/* + * Free an HMAC_DRBG context + */ +void mbedtls_hmac_drbg_free( mbedtls_hmac_drbg_context *ctx ) +{ + if( ctx == NULL ) + return; + +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_free( &ctx->mutex ); +#endif + mbedtls_md_free( &ctx->md_ctx ); + mbedtls_zeroize( ctx, sizeof( mbedtls_hmac_drbg_context ) ); +} + +#if defined(MBEDTLS_FS_IO) +int mbedtls_hmac_drbg_write_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path ) +{ + int ret; + FILE *f; + unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ]; + + if( ( f = fopen( path, "wb" ) ) == NULL ) + return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR ); + + if( ( ret = mbedtls_hmac_drbg_random( ctx, buf, sizeof( buf ) ) ) != 0 ) + goto exit; + + if( fwrite( buf, 1, sizeof( buf ), f ) != sizeof( buf ) ) + { + ret = MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR; + goto exit; + } + + ret = 0; + +exit: + fclose( f ); + return( ret ); +} + +int mbedtls_hmac_drbg_update_seed_file( mbedtls_hmac_drbg_context *ctx, const char *path ) +{ + FILE *f; + size_t n; + unsigned char buf[ MBEDTLS_HMAC_DRBG_MAX_INPUT ]; + + if( ( f = fopen( path, "rb" ) ) == NULL ) + return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR ); + + fseek( f, 0, SEEK_END ); + n = (size_t) ftell( f ); + fseek( f, 0, SEEK_SET ); + + if( n > MBEDTLS_HMAC_DRBG_MAX_INPUT ) + { + fclose( f ); + return( MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG ); + } + + if( fread( buf, 1, n, f ) != n ) + { + fclose( f ); + return( MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR ); + } + + fclose( f ); + + mbedtls_hmac_drbg_update( ctx, buf, n ); + + return( mbedtls_hmac_drbg_write_seed_file( ctx, path ) ); +} +#endif /* MBEDTLS_FS_IO */ + + +#if defined(MBEDTLS_SELF_TEST) + +#if !defined(MBEDTLS_SHA1_C) +/* Dummy checkup routine */ +int mbedtls_hmac_drbg_self_test( int verbose ) +{ + (void) verbose; + return( 0 ); +} +#else + +#define OUTPUT_LEN 80 + +/* From a NIST PR=true test vector */ +static const unsigned char entropy_pr[] = { + 0xa0, 0xc9, 0xab, 0x58, 0xf1, 0xe2, 0xe5, 0xa4, 0xde, 0x3e, 0xbd, 0x4f, + 0xf7, 0x3e, 0x9c, 0x5b, 0x64, 0xef, 0xd8, 0xca, 0x02, 0x8c, 0xf8, 0x11, + 0x48, 0xa5, 0x84, 0xfe, 0x69, 0xab, 0x5a, 0xee, 0x42, 0xaa, 0x4d, 0x42, + 0x17, 0x60, 0x99, 0xd4, 0x5e, 0x13, 0x97, 0xdc, 0x40, 0x4d, 0x86, 0xa3, + 0x7b, 0xf5, 0x59, 0x54, 0x75, 0x69, 0x51, 0xe4 }; +static const unsigned char result_pr[OUTPUT_LEN] = { + 0x9a, 0x00, 0xa2, 0xd0, 0x0e, 0xd5, 0x9b, 0xfe, 0x31, 0xec, 0xb1, 0x39, + 0x9b, 0x60, 0x81, 0x48, 0xd1, 0x96, 0x9d, 0x25, 0x0d, 0x3c, 0x1e, 0x94, + 0x10, 0x10, 0x98, 0x12, 0x93, 0x25, 0xca, 0xb8, 0xfc, 0xcc, 0x2d, 0x54, + 0x73, 0x19, 0x70, 0xc0, 0x10, 0x7a, 0xa4, 0x89, 0x25, 0x19, 0x95, 0x5e, + 0x4b, 0xc6, 0x00, 0x1d, 0x7f, 0x4e, 0x6a, 0x2b, 0xf8, 0xa3, 0x01, 0xab, + 0x46, 0x05, 0x5c, 0x09, 0xa6, 0x71, 0x88, 0xf1, 0xa7, 0x40, 0xee, 0xf3, + 0xe1, 0x5c, 0x02, 0x9b, 0x44, 0xaf, 0x03, 0x44 }; + +/* From a NIST PR=false test vector */ +static const unsigned char entropy_nopr[] = { + 0x79, 0x34, 0x9b, 0xbf, 0x7c, 0xdd, 0xa5, 0x79, 0x95, 0x57, 0x86, 0x66, + 0x21, 0xc9, 0x13, 0x83, 0x11, 0x46, 0x73, 0x3a, 0xbf, 0x8c, 0x35, 0xc8, + 0xc7, 0x21, 0x5b, 0x5b, 0x96, 0xc4, 0x8e, 0x9b, 0x33, 0x8c, 0x74, 0xe3, + 0xe9, 0x9d, 0xfe, 0xdf }; +static const unsigned char result_nopr[OUTPUT_LEN] = { + 0xc6, 0xa1, 0x6a, 0xb8, 0xd4, 0x20, 0x70, 0x6f, 0x0f, 0x34, 0xab, 0x7f, + 0xec, 0x5a, 0xdc, 0xa9, 0xd8, 0xca, 0x3a, 0x13, 0x3e, 0x15, 0x9c, 0xa6, + 0xac, 0x43, 0xc6, 0xf8, 0xa2, 0xbe, 0x22, 0x83, 0x4a, 0x4c, 0x0a, 0x0a, + 0xff, 0xb1, 0x0d, 0x71, 0x94, 0xf1, 0xc1, 0xa5, 0xcf, 0x73, 0x22, 0xec, + 0x1a, 0xe0, 0x96, 0x4e, 0xd4, 0xbf, 0x12, 0x27, 0x46, 0xe0, 0x87, 0xfd, + 0xb5, 0xb3, 0xe9, 0x1b, 0x34, 0x93, 0xd5, 0xbb, 0x98, 0xfa, 0xed, 0x49, + 0xe8, 0x5f, 0x13, 0x0f, 0xc8, 0xa4, 0x59, 0xb7 }; + +/* "Entropy" from buffer */ +static size_t test_offset; +static int hmac_drbg_self_test_entropy( void *data, + unsigned char *buf, size_t len ) +{ + const unsigned char *p = data; + memcpy( buf, p + test_offset, len ); + test_offset += len; + return( 0 ); +} + +#define CHK( c ) if( (c) != 0 ) \ + { \ + if( verbose != 0 ) \ + mbedtls_printf( "failed\n" ); \ + return( 1 ); \ + } + +/* + * Checkup routine for HMAC_DRBG with SHA-1 + */ +int mbedtls_hmac_drbg_self_test( int verbose ) +{ + mbedtls_hmac_drbg_context ctx; + unsigned char buf[OUTPUT_LEN]; + const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 ); + + mbedtls_hmac_drbg_init( &ctx ); + + /* + * PR = True + */ + if( verbose != 0 ) + mbedtls_printf( " HMAC_DRBG (PR = True) : " ); + + test_offset = 0; + CHK( mbedtls_hmac_drbg_seed( &ctx, md_info, + hmac_drbg_self_test_entropy, (void *) entropy_pr, + NULL, 0 ) ); + mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON ); + CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); + CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); + CHK( memcmp( buf, result_pr, OUTPUT_LEN ) ); + mbedtls_hmac_drbg_free( &ctx ); + + mbedtls_hmac_drbg_free( &ctx ); + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + + /* + * PR = False + */ + if( verbose != 0 ) + mbedtls_printf( " HMAC_DRBG (PR = False) : " ); + + mbedtls_hmac_drbg_init( &ctx ); + + test_offset = 0; + CHK( mbedtls_hmac_drbg_seed( &ctx, md_info, + hmac_drbg_self_test_entropy, (void *) entropy_nopr, + NULL, 0 ) ); + CHK( mbedtls_hmac_drbg_reseed( &ctx, NULL, 0 ) ); + CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); + CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); + CHK( memcmp( buf, result_nopr, OUTPUT_LEN ) ); + mbedtls_hmac_drbg_free( &ctx ); + + mbedtls_hmac_drbg_free( &ctx ); + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + + return( 0 ); +} +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_HMAC_DRBG_C */ diff --git a/security/mbedtls/src/mbedtls_alt.c b/security/mbedtls/src/mbedtls_alt.c new file mode 100644 index 0000000000..0a36c36bc6 --- /dev/null +++ b/security/mbedtls/src/mbedtls_alt.c @@ -0,0 +1,460 @@ +/** + * Copyright (C) 2017 The YunOS IoT Project. All rights reserved. + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include +#include +#include + +#include "mbedtls/md.h" + +#if defined(MBEDTLS_DEBUG_C) +#include "mbedtls/debug.h" +#endif + +#if defined(MBEDTLS_THREADING_ALT) +#include "mbedtls/threading.h" +#endif + +#if defined(MBEDTLS_AES_ALT) +#include "mbedtls/aes.h" +#include "mbedtls/cipher.h" +#endif + +#if defined(MBEDTLS_PK_ALT) +#include "mbedtls/rsa.h" +#include "ali_crypto.h" +#else +#include "ali_crypto.h" +#endif + +#define MBEDTLS_ALT_PRINT(_f, _a ...) \ + printf("%s %d: "_f, __FUNCTION__, __LINE__, ##_a) + +#if defined(MBEDTLS_AES_ALT) +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} +#endif + +#if defined(MBEDTLS_THREADING_ALT) +void threading_mutex_init(mbedtls_threading_mutex_t *mutex) +{ + if (mutex == NULL || mutex->is_valid) + return; + + mutex->is_valid = aos_mutex_new(&mutex->mutex) == 0; +} + +void threading_mutex_free(mbedtls_threading_mutex_t *mutex) +{ + if (mutex == NULL || !mutex->is_valid) + return; + + aos_mutex_free(&mutex->mutex); + mutex->is_valid = 0; +} + +int threading_mutex_lock(mbedtls_threading_mutex_t *mutex) +{ + if (mutex == NULL || !mutex->is_valid) + return( MBEDTLS_ERR_THREADING_BAD_INPUT_DATA ); + + if (aos_mutex_lock( &mutex->mutex, AOS_WAIT_FOREVER) != 0 ) + return(MBEDTLS_ERR_THREADING_MUTEX_ERROR); + + return 0; +} + +int threading_mutex_unlock( mbedtls_threading_mutex_t *mutex ) +{ + if( mutex == NULL || ! mutex->is_valid ) + return( MBEDTLS_ERR_THREADING_BAD_INPUT_DATA ); + + if( aos_mutex_unlock( &mutex->mutex ) != 0 ) + return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); + + return( 0 ); +} + +#endif /* MBEDTLS_THREADING_ALT */ + +#if defined(MBEDTLS_AES_ALT) +void mbedtls_aes_init_alt( mbedtls_aes_context *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_aes_context ) ); +} + +void mbedtls_aes_free_alt( mbedtls_aes_context *ctx ) +{ + if (ctx == NULL) { + return; + } + + if (ctx->ali_ctx) { + free(ctx->ali_ctx); + } + + mbedtls_zeroize(ctx, sizeof(mbedtls_aes_context)); +} + +int mbedtls_aes_setkey_enc_alt( mbedtls_aes_context *ctx, const unsigned char *key, + unsigned int keybits ) +{ + if (ctx == NULL || key == NULL || keybits == 0) { + MBEDTLS_ALT_PRINT("invalid input args\n"); + return -1; + } + + if ((keybits >> 3) > 32) { + MBEDTLS_ALT_PRINT("invalid key length - %d\n", keybits >> 3); + return -1; + } else { + ctx->key_len = keybits >> 3; + memcpy(ctx->key, key, ctx->key_len); + } + + return 0; +} + +int mbedtls_aes_setkey_dec_alt( mbedtls_aes_context *ctx, const unsigned char *key, + unsigned int keybits ) +{ + if (ctx == NULL || key == NULL || keybits == 0) { + MBEDTLS_ALT_PRINT("invalid input args\n"); + return -1; + } + + if ((keybits >> 3) > 32) { + MBEDTLS_ALT_PRINT("invalid key length - %d\n", keybits >> 3); + return -1; + } else { + ctx->key_len = keybits >> 3; + memcpy(ctx->key, key, ctx->key_len); + } + + return 0; +} + +int mbedtls_aes_crypt_ecb_alt( mbedtls_aes_context *ctx, + int mode, + const unsigned char input[16], + unsigned char output[16] ) +{ + (void)ctx; + (void)mode; + (void)input; + (void)output; + + MBEDTLS_ALT_PRINT("not support!\n"); + + return -1; +} + +int mbedtls_aes_crypt_cbc_alt( mbedtls_aes_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ) +{ + bool is_enc; + size_t ctx_size; + ali_crypto_result result; + + if (ctx == NULL || + length == 0 || input == NULL || output == NULL) { + MBEDTLS_ALT_PRINT("invalid input args\n"); + return -1; + } + + if (length % 16) { + MBEDTLS_ALT_PRINT("invalid input length - %d\n", length); + return -1; + } + + if (ctx->ali_ctx == NULL) { + result = ali_aes_get_ctx_size(AES_CBC, &ctx_size); + if (result != ALI_CRYPTO_SUCCESS) { + MBEDTLS_ALT_PRINT("get ctx size fail - 0x%x\n", result); + return -1; + } + + ctx->ali_ctx = malloc(ctx_size); + if (ctx->ali_ctx == NULL) { + MBEDTLS_ALT_PRINT("malloc(%d) fail\n", ctx_size); + return -1; + } else { + memset(ctx->ali_ctx, 0, ctx_size); + } + } + + if (ctx->status == AES_STATUS_INIT) { + if (mode == MBEDTLS_AES_ENCRYPT) { + is_enc = true; + } else { + is_enc = false; + } + + if (ctx->reset) { + result = ali_aes_reset(ctx->ali_ctx); + if (result != ALI_CRYPTO_SUCCESS) { + MBEDTLS_ALT_PRINT("aes reset fail - 0x%x\n", result); + return -1; + } + } + + result = ali_aes_init(AES_CBC, is_enc, + ctx->key, NULL, ctx->key_len, iv, ctx->ali_ctx); + if (result != ALI_CRYPTO_SUCCESS) { + MBEDTLS_ALT_PRINT("aes init fail - 0x%x\n", result); + return -1; + } else { + ctx->reset = 1; + ctx->status = AES_STATUS_PROCESS; + } + } + + result = ali_aes_process(input, + output, length, ctx->ali_ctx); + if (result != ALI_CRYPTO_SUCCESS) { + MBEDTLS_ALT_PRINT("aes process fail - 0x%x\n", result); + return -1; + } + + return 0; +} + +#endif /* MBEDTLS_AES_ALT */ + +#if defined(MBEDTLS_PK_ALT) +int rsa_verify_alt(void *ctx, size_t hash_id, + const unsigned char *hash, size_t hash_len, + const unsigned char *sig, size_t sig_len) +{ + int ret = 0; + bool result1 = false; + ali_crypto_result result; + mbedtls_rsa_context *rsa_ctx; + hash_type_t hash_type; + rsa_padding_t rsa_padding; + size_t pub_key_len; + uint8_t *pub_key = NULL; + + if (ctx == NULL || hash == NULL || sig == NULL) { + MBEDTLS_ALT_PRINT("invalid input args\n"); + return -1; + } + + rsa_ctx = (mbedtls_rsa_context *)ctx; + if (sig_len != rsa_ctx->n_len) { + MBEDTLS_ALT_PRINT("invalid sig len - %d\n", sig_len); + return -1; + } + + if (rsa_ctx->padding != MBEDTLS_RSA_ALT_PKCS_V15) { + MBEDTLS_ALT_PRINT("invalid rsa padding - %d\n", rsa_ctx->padding); + return -1; + } + + switch(hash_id) { + case MBEDTLS_MD_MD5: { + if (hash_len != MD5_HASH_SIZE) { + MBEDTLS_ALT_PRINT("invalid hash len - %d\n", hash_len); + return -1; + } else { + hash_type = MD5; + } + + break; + } + case MBEDTLS_MD_SHA1: { + if (hash_len != SHA1_HASH_SIZE) { + MBEDTLS_ALT_PRINT("invalid hash len - %d\n", hash_len); + return -1; + } else { + hash_type = SHA1; + } + + break; + } + case MBEDTLS_MD_SHA256: { + if (hash_len != SHA256_HASH_SIZE) { + MBEDTLS_ALT_PRINT("invalid hash len - %d\n", hash_len); + return -1; + } else { + hash_type = SHA256; + } + + break; + } + + default: + MBEDTLS_ALT_PRINT("not support hash_id - %d\n", hash_id); + return -1; + } + + result = ali_rsa_get_pubkey_size((size_t)rsa_ctx->n_len, &pub_key_len); + if (result != ALI_CRYPTO_SUCCESS) { + MBEDTLS_ALT_PRINT("get pubkey size fail - 0x%x\n", result); + return -1; + } + + pub_key = malloc(pub_key_len); + if (pub_key == NULL) { + MBEDTLS_ALT_PRINT("malloc(%d) fail\n", pub_key_len); + ret = -1; + goto _out; + } else { + memset(pub_key, 0, pub_key_len); + } + + result = ali_rsa_init_pubkey(rsa_ctx->n_len << 3, + rsa_ctx->rsa_n, rsa_ctx->n_len, + rsa_ctx->rsa_e, rsa_ctx->e_len, (rsa_pubkey_t *)pub_key); + if (result != ALI_CRYPTO_SUCCESS) { + MBEDTLS_ALT_PRINT("init pub_key fail - 0x%x\n", result); + ret = -1; + goto _out; + } + + rsa_padding.type = RSASSA_PKCS1_V1_5; + rsa_padding.pad.rsassa_v1_5.type = hash_type; + result = ali_rsa_verify((rsa_pubkey_t *)pub_key, + hash, hash_len, + sig, sig_len, rsa_padding, &result1); + if (result != ALI_CRYPTO_SUCCESS || result1 == false) { + MBEDTLS_ALT_PRINT("rsa verify fail - 0x%x\n", result); + ret = -1; + goto _out; + } + +_out: + if (pub_key) { + free(pub_key); + } + + return ret; +} + +int rsa_sign_alt(void *ctx, size_t hash_id, + const unsigned char *hash, size_t hash_len, + unsigned char *sig, size_t *sig_len) +{ + (void)ctx; + (void)hash_id; + + (void)hash; + (void)hash_len; + (void)sig; + (void)sig_len; + + MBEDTLS_ALT_PRINT("not support!\n"); + + return -1; +} + +int rsa_decrypt_alt(void *ctx, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen) +{ + (void)ctx; + (void)input; + (void)ilen; + + (void)output; + (void)olen; + + MBEDTLS_ALT_PRINT("not support!\n"); + + return -1; +} + +int rsa_encrypt_alt(void *ctx, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen) +{ + int ret = 0; + ali_crypto_result result; + mbedtls_rsa_context *rsa_ctx; + rsa_padding_t rsa_padding; + size_t pub_key_len; + uint8_t *pub_key = NULL; + + if (ctx == NULL || input == NULL || ilen == 0 || + output == NULL || olen == NULL) { + MBEDTLS_ALT_PRINT("invalid input args\n"); + return -1; + } + + rsa_ctx = (mbedtls_rsa_context *)ctx; + if (rsa_ctx->padding != MBEDTLS_RSA_ALT_PKCS_V15) { + MBEDTLS_ALT_PRINT("invalid rsa padding - %d\n", rsa_ctx->padding); + return -1; + } + + result = ali_rsa_get_pubkey_size((size_t)rsa_ctx->n_len, &pub_key_len); + if (result != ALI_CRYPTO_SUCCESS) { + MBEDTLS_ALT_PRINT("get pubkey size fail - 0x%x\n", result); + return -1; + } + + pub_key = malloc(pub_key_len); + if (pub_key == NULL) { + MBEDTLS_ALT_PRINT("malloc(%d) fail\n", pub_key_len); + ret = -1; + goto _out; + } else { + memset(pub_key, 0, pub_key_len); + } + + result = ali_rsa_init_pubkey(rsa_ctx->n_len << 3, + rsa_ctx->rsa_n, rsa_ctx->n_len, + rsa_ctx->rsa_e, rsa_ctx->e_len, (rsa_pubkey_t *)pub_key); + if (result != ALI_CRYPTO_SUCCESS) { + MBEDTLS_ALT_PRINT("init pub_key fail - 0x%x\n", result); + ret = -1; + goto _out; + } + + rsa_padding.type = RSAES_PKCS1_V1_5; + result = ali_rsa_public_encrypt((rsa_pubkey_t *)pub_key, + input, ilen, output, olen, rsa_padding); + if (result != ALI_CRYPTO_SUCCESS) { + MBEDTLS_ALT_PRINT("rsa encrypt fail - 0x%x\n", result); + ret = -1; + goto _out; + } + +_out: + if (pub_key) { + free(pub_key); + } + + return ret; +} + +void mbedtls_rsa_init_alt(mbedtls_rsa_context *ctx, + int padding, int hash_id) +{ + memset( ctx, 0, sizeof(mbedtls_rsa_context)); + + ctx->padding = padding; + ctx->hash_id = hash_id; +} + + +void mbedtls_rsa_free_alt(mbedtls_rsa_context *ctx) +{ + memset(ctx, 0, sizeof(mbedtls_rsa_context)); +} + +#endif /* MBEDTLS_PK_ALT */ + diff --git a/security/mbedtls/mbedtls_net.c b/security/mbedtls/src/mbedtls_net.c similarity index 83% rename from security/mbedtls/mbedtls_net.c rename to security/mbedtls/src/mbedtls_net.c index a8be150e67..d046f552a5 100644 --- a/security/mbedtls/mbedtls_net.c +++ b/security/mbedtls/src/mbedtls_net.c @@ -102,13 +102,27 @@ int mbedtls_net_recv(void *ctx, unsigned char *buf, size_t len) if (len > WIFI_PAYLOAD_SIZE) { len = WIFI_PAYLOAD_SIZE; } - ret = WIFI_ReceiveData((uint8_t)fd, - buf, (uint16_t)len, - &recv_size, WIFI_READ_TIMEOUT); - if (ret != WIFI_STATUS_OK) { - MBEDTLS_NET_PRINT("net_recv: receive data fail - %d\n", ret); - return MBEDTLS_ERR_NET_RECV_FAILED; - } + int err_count = 0; + do { + ret = WIFI_ReceiveData((uint8_t)fd, + buf, (uint16_t)len, + &recv_size, WIFI_READ_TIMEOUT); + if (ret != WIFI_STATUS_OK) { + MBEDTLS_NET_PRINT("net_recv: receive data fail - %d\n", ret); + return MBEDTLS_ERR_NET_RECV_FAILED; + } + + //TODO, how to identify the connection is shutdown? + if (recv_size == 0) { + if (err_count == WIFI_READ_RETRY_TIME) { + MBEDTLS_NET_PRINT("retry WIFI_ReceiveData %d times failed\n", err_count); + return MBEDTLS_ERR_SSL_WANT_READ; + } else { + err_count++; + MBEDTLS_NET_PRINT("retry WIFI_ReceiveData time %d\n", err_count); + } + } + } while (ret == WIFI_STATUS_OK && recv_size == 0); return recv_size; } @@ -130,13 +144,27 @@ int mbedtls_net_recv_timeout(void *ctx, unsigned char *buf, size_t len, } // TODO: STM32 WiFi module can't set mqtt default timeout 60000, will return error, need to check with WiFi module, ignore param "timeout" - ret = WIFI_ReceiveData((uint8_t)fd, - buf, (uint16_t)len, - &recv_size, WIFI_READ_TIMEOUT); - if (ret != WIFI_STATUS_OK) { - MBEDTLS_NET_PRINT("net_recv_timeout: receive data fail - %d\n", ret); - return MBEDTLS_ERR_NET_RECV_FAILED; - } + int err_count = 0; + do { + ret = WIFI_ReceiveData((uint8_t)fd, + buf, (uint16_t)len, + &recv_size, WIFI_READ_TIMEOUT); + if (ret != WIFI_STATUS_OK) { + MBEDTLS_NET_PRINT("net_recv_timeout: receive data fail - %d\n", ret); + return MBEDTLS_ERR_NET_RECV_FAILED; + } + + //TODO, how to identify the connection is shutdown? + if (recv_size == 0) { + if (err_count == WIFI_READ_RETRY_TIME) { + MBEDTLS_NET_PRINT("retry WIFI_ReceiveData %d times failed\n", err_count); + return MBEDTLS_ERR_SSL_WANT_READ; + } else { + err_count++; + MBEDTLS_NET_PRINT("retry WIFI_ReceiveData time %d\n", err_count); + } + } + } while (ret == WIFI_STATUS_OK && recv_size == 0); return recv_size; } diff --git a/security/mbedtls/mbedtls_ssl.c b/security/mbedtls/src/mbedtls_ssl.c similarity index 100% rename from security/mbedtls/mbedtls_ssl.c rename to security/mbedtls/src/mbedtls_ssl.c diff --git a/security/mbedtls/src/md.c b/security/mbedtls/src/md.c new file mode 100644 index 0000000000..eda98f6361 --- /dev/null +++ b/security/mbedtls/src/md.c @@ -0,0 +1,471 @@ +/** + * \file mbedtls_md.c + * + * \brief Generic message digest wrapper for mbed TLS + * + * \author Adriaan de Jong + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_MD_C) + +#include "mbedtls/md.h" +#include "mbedtls/md_internal.h" + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_calloc calloc +#define mbedtls_free free +#endif + +#include + +#if defined(MBEDTLS_FS_IO) +#include +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +/* + * Reminder: update profiles in x509_crt.c when adding a new hash! + */ +static const int supported_digests[] = { + +#if defined(MBEDTLS_SHA512_C) + MBEDTLS_MD_SHA512, + MBEDTLS_MD_SHA384, +#endif + +#if defined(MBEDTLS_SHA256_C) + MBEDTLS_MD_SHA256, + MBEDTLS_MD_SHA224, +#endif + +#if defined(MBEDTLS_SHA1_C) + MBEDTLS_MD_SHA1, +#endif + +#if defined(MBEDTLS_RIPEMD160_C) + MBEDTLS_MD_RIPEMD160, +#endif + +#if defined(MBEDTLS_MD5_C) + MBEDTLS_MD_MD5, +#endif + +#if defined(MBEDTLS_MD4_C) + MBEDTLS_MD_MD4, +#endif + +#if defined(MBEDTLS_MD2_C) + MBEDTLS_MD_MD2, +#endif + + MBEDTLS_MD_NONE +}; + +const int *mbedtls_md_list( void ) +{ + return( supported_digests ); +} + +const mbedtls_md_info_t *mbedtls_md_info_from_string( const char *md_name ) +{ + if( NULL == md_name ) + return( NULL ); + + /* Get the appropriate digest information */ +#if defined(MBEDTLS_MD2_C) + if( !strcmp( "MD2", md_name ) ) + return mbedtls_md_info_from_type( MBEDTLS_MD_MD2 ); +#endif +#if defined(MBEDTLS_MD4_C) + if( !strcmp( "MD4", md_name ) ) + return mbedtls_md_info_from_type( MBEDTLS_MD_MD4 ); +#endif +#if defined(MBEDTLS_MD5_C) + if( !strcmp( "MD5", md_name ) ) + return mbedtls_md_info_from_type( MBEDTLS_MD_MD5 ); +#endif +#if defined(MBEDTLS_RIPEMD160_C) + if( !strcmp( "RIPEMD160", md_name ) ) + return mbedtls_md_info_from_type( MBEDTLS_MD_RIPEMD160 ); +#endif +#if defined(MBEDTLS_SHA1_C) + if( !strcmp( "SHA1", md_name ) || !strcmp( "SHA", md_name ) ) + return mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 ); +#endif +#if defined(MBEDTLS_SHA256_C) + if( !strcmp( "SHA224", md_name ) ) + return mbedtls_md_info_from_type( MBEDTLS_MD_SHA224 ); + if( !strcmp( "SHA256", md_name ) ) + return mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 ); +#endif +#if defined(MBEDTLS_SHA512_C) + if( !strcmp( "SHA384", md_name ) ) + return mbedtls_md_info_from_type( MBEDTLS_MD_SHA384 ); + if( !strcmp( "SHA512", md_name ) ) + return mbedtls_md_info_from_type( MBEDTLS_MD_SHA512 ); +#endif + return( NULL ); +} + +const mbedtls_md_info_t *mbedtls_md_info_from_type( mbedtls_md_type_t md_type ) +{ + switch( md_type ) + { +#if defined(MBEDTLS_MD2_C) + case MBEDTLS_MD_MD2: + return( &mbedtls_md2_info ); +#endif +#if defined(MBEDTLS_MD4_C) + case MBEDTLS_MD_MD4: + return( &mbedtls_md4_info ); +#endif +#if defined(MBEDTLS_MD5_C) + case MBEDTLS_MD_MD5: + return( &mbedtls_md5_info ); +#endif +#if defined(MBEDTLS_RIPEMD160_C) + case MBEDTLS_MD_RIPEMD160: + return( &mbedtls_ripemd160_info ); +#endif +#if defined(MBEDTLS_SHA1_C) + case MBEDTLS_MD_SHA1: + return( &mbedtls_sha1_info ); +#endif +#if defined(MBEDTLS_SHA256_C) + case MBEDTLS_MD_SHA224: + return( &mbedtls_sha224_info ); + case MBEDTLS_MD_SHA256: + return( &mbedtls_sha256_info ); +#endif +#if defined(MBEDTLS_SHA512_C) + case MBEDTLS_MD_SHA384: + return( &mbedtls_sha384_info ); + case MBEDTLS_MD_SHA512: + return( &mbedtls_sha512_info ); +#endif + default: + return( NULL ); + } +} + +void mbedtls_md_init( mbedtls_md_context_t *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_md_context_t ) ); +} + +void mbedtls_md_free( mbedtls_md_context_t *ctx ) +{ + if( ctx == NULL || ctx->md_info == NULL ) + return; + + if( ctx->md_ctx != NULL ) + ctx->md_info->ctx_free_func( ctx->md_ctx ); + + if( ctx->hmac_ctx != NULL ) + { + mbedtls_zeroize( ctx->hmac_ctx, 2 * ctx->md_info->block_size ); + mbedtls_free( ctx->hmac_ctx ); + } + + mbedtls_zeroize( ctx, sizeof( mbedtls_md_context_t ) ); +} + +int mbedtls_md_clone( mbedtls_md_context_t *dst, + const mbedtls_md_context_t *src ) +{ + if( dst == NULL || dst->md_info == NULL || + src == NULL || src->md_info == NULL || + dst->md_info != src->md_info ) + { + return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); + } + + dst->md_info->clone_func( dst->md_ctx, src->md_ctx ); + + return( 0 ); +} + +#if ! defined(MBEDTLS_DEPRECATED_REMOVED) +int mbedtls_md_init_ctx( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info ) +{ + return mbedtls_md_setup( ctx, md_info, 1 ); +} +#endif + +int mbedtls_md_setup( mbedtls_md_context_t *ctx, const mbedtls_md_info_t *md_info, int hmac ) +{ + if( md_info == NULL || ctx == NULL ) + return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); + + if( ( ctx->md_ctx = md_info->ctx_alloc_func() ) == NULL ) + return( MBEDTLS_ERR_MD_ALLOC_FAILED ); + + if( hmac != 0 ) + { + ctx->hmac_ctx = mbedtls_calloc( 2, md_info->block_size ); + if( ctx->hmac_ctx == NULL ) + { + md_info->ctx_free_func( ctx->md_ctx ); + return( MBEDTLS_ERR_MD_ALLOC_FAILED ); + } + } + + ctx->md_info = md_info; + + return( 0 ); +} + +int mbedtls_md_starts( mbedtls_md_context_t *ctx ) +{ + if( ctx == NULL || ctx->md_info == NULL ) + return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); + + ctx->md_info->starts_func( ctx->md_ctx ); + + return( 0 ); +} + +int mbedtls_md_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen ) +{ + if( ctx == NULL || ctx->md_info == NULL ) + return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); + + ctx->md_info->update_func( ctx->md_ctx, input, ilen ); + + return( 0 ); +} + +int mbedtls_md_finish( mbedtls_md_context_t *ctx, unsigned char *output ) +{ + if( ctx == NULL || ctx->md_info == NULL ) + return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); + + ctx->md_info->finish_func( ctx->md_ctx, output ); + + return( 0 ); +} + +int mbedtls_md( const mbedtls_md_info_t *md_info, const unsigned char *input, size_t ilen, + unsigned char *output ) +{ + if( md_info == NULL ) + return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); + + md_info->digest_func( input, ilen, output ); + + return( 0 ); +} + +#if defined(MBEDTLS_FS_IO) +int mbedtls_md_file( const mbedtls_md_info_t *md_info, const char *path, unsigned char *output ) +{ + int ret; + FILE *f; + size_t n; + mbedtls_md_context_t ctx; + unsigned char buf[1024]; + + if( md_info == NULL ) + return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); + + if( ( f = fopen( path, "rb" ) ) == NULL ) + return( MBEDTLS_ERR_MD_FILE_IO_ERROR ); + + mbedtls_md_init( &ctx ); + + if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 ) + goto cleanup; + + md_info->starts_func( ctx.md_ctx ); + + while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) + md_info->update_func( ctx.md_ctx, buf, n ); + + if( ferror( f ) != 0 ) + { + ret = MBEDTLS_ERR_MD_FILE_IO_ERROR; + goto cleanup; + } + + md_info->finish_func( ctx.md_ctx, output ); + +cleanup: + fclose( f ); + mbedtls_md_free( &ctx ); + + return( ret ); +} +#endif /* MBEDTLS_FS_IO */ + +int mbedtls_md_hmac_starts( mbedtls_md_context_t *ctx, const unsigned char *key, size_t keylen ) +{ + unsigned char sum[MBEDTLS_MD_MAX_SIZE]; + unsigned char *ipad, *opad; + size_t i; + + if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) + return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); + + if( keylen > (size_t) ctx->md_info->block_size ) + { + ctx->md_info->starts_func( ctx->md_ctx ); + ctx->md_info->update_func( ctx->md_ctx, key, keylen ); + ctx->md_info->finish_func( ctx->md_ctx, sum ); + + keylen = ctx->md_info->size; + key = sum; + } + + ipad = (unsigned char *) ctx->hmac_ctx; + opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size; + + memset( ipad, 0x36, ctx->md_info->block_size ); + memset( opad, 0x5C, ctx->md_info->block_size ); + + for( i = 0; i < keylen; i++ ) + { + ipad[i] = (unsigned char)( ipad[i] ^ key[i] ); + opad[i] = (unsigned char)( opad[i] ^ key[i] ); + } + + mbedtls_zeroize( sum, sizeof( sum ) ); + + ctx->md_info->starts_func( ctx->md_ctx ); + ctx->md_info->update_func( ctx->md_ctx, ipad, ctx->md_info->block_size ); + + return( 0 ); +} + +int mbedtls_md_hmac_update( mbedtls_md_context_t *ctx, const unsigned char *input, size_t ilen ) +{ + if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) + return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); + + ctx->md_info->update_func( ctx->md_ctx, input, ilen ); + + return( 0 ); +} + +int mbedtls_md_hmac_finish( mbedtls_md_context_t *ctx, unsigned char *output ) +{ + unsigned char tmp[MBEDTLS_MD_MAX_SIZE]; + unsigned char *opad; + + if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) + return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); + + opad = (unsigned char *) ctx->hmac_ctx + ctx->md_info->block_size; + + ctx->md_info->finish_func( ctx->md_ctx, tmp ); + ctx->md_info->starts_func( ctx->md_ctx ); + ctx->md_info->update_func( ctx->md_ctx, opad, ctx->md_info->block_size ); + ctx->md_info->update_func( ctx->md_ctx, tmp, ctx->md_info->size ); + ctx->md_info->finish_func( ctx->md_ctx, output ); + + return( 0 ); +} + +int mbedtls_md_hmac_reset( mbedtls_md_context_t *ctx ) +{ + unsigned char *ipad; + + if( ctx == NULL || ctx->md_info == NULL || ctx->hmac_ctx == NULL ) + return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); + + ipad = (unsigned char *) ctx->hmac_ctx; + + ctx->md_info->starts_func( ctx->md_ctx ); + ctx->md_info->update_func( ctx->md_ctx, ipad, ctx->md_info->block_size ); + + return( 0 ); +} + +int mbedtls_md_hmac( const mbedtls_md_info_t *md_info, const unsigned char *key, size_t keylen, + const unsigned char *input, size_t ilen, + unsigned char *output ) +{ + mbedtls_md_context_t ctx; + int ret; + + if( md_info == NULL ) + return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); + + mbedtls_md_init( &ctx ); + + if( ( ret = mbedtls_md_setup( &ctx, md_info, 1 ) ) != 0 ) + return( ret ); + + mbedtls_md_hmac_starts( &ctx, key, keylen ); + mbedtls_md_hmac_update( &ctx, input, ilen ); + mbedtls_md_hmac_finish( &ctx, output ); + + mbedtls_md_free( &ctx ); + + return( 0 ); +} + +int mbedtls_md_process( mbedtls_md_context_t *ctx, const unsigned char *data ) +{ + if( ctx == NULL || ctx->md_info == NULL ) + return( MBEDTLS_ERR_MD_BAD_INPUT_DATA ); + + ctx->md_info->process_func( ctx->md_ctx, data ); + + return( 0 ); +} + +unsigned char mbedtls_md_get_size( const mbedtls_md_info_t *md_info ) +{ + if( md_info == NULL ) + return( 0 ); + + return md_info->size; +} + +mbedtls_md_type_t mbedtls_md_get_type( const mbedtls_md_info_t *md_info ) +{ + if( md_info == NULL ) + return( MBEDTLS_MD_NONE ); + + return md_info->type; +} + +const char *mbedtls_md_get_name( const mbedtls_md_info_t *md_info ) +{ + if( md_info == NULL ) + return( NULL ); + + return md_info->name; +} + +#endif /* MBEDTLS_MD_C */ diff --git a/security/mbedtls/src/md2.c b/security/mbedtls/src/md2.c new file mode 100644 index 0000000000..95cbcce658 --- /dev/null +++ b/security/mbedtls/src/md2.c @@ -0,0 +1,288 @@ +/* + * RFC 1115/1319 compliant MD2 implementation + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +/* + * The MD2 algorithm was designed by Ron Rivest in 1989. + * + * http://www.ietf.org/rfc/rfc1115.txt + * http://www.ietf.org/rfc/rfc1319.txt + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_MD2_C) + +#include "mbedtls/md2.h" + +#include + +#if defined(MBEDTLS_SELF_TEST) +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_printf printf +#endif /* MBEDTLS_PLATFORM_C */ +#endif /* MBEDTLS_SELF_TEST */ + +#if !defined(MBEDTLS_MD2_ALT) + +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +static const unsigned char PI_SUBST[256] = +{ + 0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01, 0x3D, 0x36, + 0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13, 0x62, 0xA7, 0x05, 0xF3, + 0xC0, 0xC7, 0x73, 0x8C, 0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C, + 0x82, 0xCA, 0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16, + 0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12, 0xBE, 0x4E, + 0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49, 0xA0, 0xFB, 0xF5, 0x8E, + 0xBB, 0x2F, 0xEE, 0x7A, 0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2, + 0x07, 0x3F, 0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21, + 0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27, 0x35, 0x3E, + 0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03, 0xFF, 0x19, 0x30, 0xB3, + 0x48, 0xA5, 0xB5, 0xD1, 0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56, + 0xAA, 0xC6, 0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6, + 0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1, 0x45, 0x9D, + 0x70, 0x59, 0x64, 0x71, 0x87, 0x20, 0x86, 0x5B, 0xCF, 0x65, + 0xE6, 0x2D, 0xA8, 0x02, 0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0, + 0xB9, 0xF6, 0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F, + 0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A, 0xC3, 0x5C, + 0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26, 0x2C, 0x53, 0x0D, 0x6E, + 0x85, 0x28, 0x84, 0x09, 0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81, + 0x4D, 0x52, 0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA, + 0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A, 0x78, 0x88, + 0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D, 0xE9, 0xCB, 0xD5, 0xFE, + 0x3B, 0x00, 0x1D, 0x39, 0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58, + 0xD0, 0xE4, 0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A, + 0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A, 0xDB, 0x99, + 0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14 +}; + +void mbedtls_md2_init( mbedtls_md2_context *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_md2_context ) ); +} + +void mbedtls_md2_free( mbedtls_md2_context *ctx ) +{ + if( ctx == NULL ) + return; + + mbedtls_zeroize( ctx, sizeof( mbedtls_md2_context ) ); +} + +void mbedtls_md2_clone( mbedtls_md2_context *dst, + const mbedtls_md2_context *src ) +{ + *dst = *src; +} + +/* + * MD2 context setup + */ +void mbedtls_md2_starts( mbedtls_md2_context *ctx ) +{ + memset( ctx->cksum, 0, 16 ); + memset( ctx->state, 0, 46 ); + memset( ctx->buffer, 0, 16 ); + ctx->left = 0; +} + +#if !defined(MBEDTLS_MD2_PROCESS_ALT) +void mbedtls_md2_process( mbedtls_md2_context *ctx ) +{ + int i, j; + unsigned char t = 0; + + for( i = 0; i < 16; i++ ) + { + ctx->state[i + 16] = ctx->buffer[i]; + ctx->state[i + 32] = + (unsigned char)( ctx->buffer[i] ^ ctx->state[i]); + } + + for( i = 0; i < 18; i++ ) + { + for( j = 0; j < 48; j++ ) + { + ctx->state[j] = (unsigned char) + ( ctx->state[j] ^ PI_SUBST[t] ); + t = ctx->state[j]; + } + + t = (unsigned char)( t + i ); + } + + t = ctx->cksum[15]; + + for( i = 0; i < 16; i++ ) + { + ctx->cksum[i] = (unsigned char) + ( ctx->cksum[i] ^ PI_SUBST[ctx->buffer[i] ^ t] ); + t = ctx->cksum[i]; + } +} +#endif /* !MBEDTLS_MD2_PROCESS_ALT */ + +/* + * MD2 process buffer + */ +void mbedtls_md2_update( mbedtls_md2_context *ctx, const unsigned char *input, size_t ilen ) +{ + size_t fill; + + while( ilen > 0 ) + { + if( ilen > 16 - ctx->left ) + fill = 16 - ctx->left; + else + fill = ilen; + + memcpy( ctx->buffer + ctx->left, input, fill ); + + ctx->left += fill; + input += fill; + ilen -= fill; + + if( ctx->left == 16 ) + { + ctx->left = 0; + mbedtls_md2_process( ctx ); + } + } +} + +/* + * MD2 final digest + */ +void mbedtls_md2_finish( mbedtls_md2_context *ctx, unsigned char output[16] ) +{ + size_t i; + unsigned char x; + + x = (unsigned char)( 16 - ctx->left ); + + for( i = ctx->left; i < 16; i++ ) + ctx->buffer[i] = x; + + mbedtls_md2_process( ctx ); + + memcpy( ctx->buffer, ctx->cksum, 16 ); + mbedtls_md2_process( ctx ); + + memcpy( output, ctx->state, 16 ); +} + +#endif /* !MBEDTLS_MD2_ALT */ + +/* + * output = MD2( input buffer ) + */ +void mbedtls_md2( const unsigned char *input, size_t ilen, unsigned char output[16] ) +{ + mbedtls_md2_context ctx; + + mbedtls_md2_init( &ctx ); + mbedtls_md2_starts( &ctx ); + mbedtls_md2_update( &ctx, input, ilen ); + mbedtls_md2_finish( &ctx, output ); + mbedtls_md2_free( &ctx ); +} + +#if defined(MBEDTLS_SELF_TEST) + +/* + * RFC 1319 test vectors + */ +static const char md2_test_str[7][81] = +{ + { "" }, + { "a" }, + { "abc" }, + { "message digest" }, + { "abcdefghijklmnopqrstuvwxyz" }, + { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, + { "12345678901234567890123456789012345678901234567890123456789012" \ + "345678901234567890" } +}; + +static const unsigned char md2_test_sum[7][16] = +{ + { 0x83, 0x50, 0xE5, 0xA3, 0xE2, 0x4C, 0x15, 0x3D, + 0xF2, 0x27, 0x5C, 0x9F, 0x80, 0x69, 0x27, 0x73 }, + { 0x32, 0xEC, 0x01, 0xEC, 0x4A, 0x6D, 0xAC, 0x72, + 0xC0, 0xAB, 0x96, 0xFB, 0x34, 0xC0, 0xB5, 0xD1 }, + { 0xDA, 0x85, 0x3B, 0x0D, 0x3F, 0x88, 0xD9, 0x9B, + 0x30, 0x28, 0x3A, 0x69, 0xE6, 0xDE, 0xD6, 0xBB }, + { 0xAB, 0x4F, 0x49, 0x6B, 0xFB, 0x2A, 0x53, 0x0B, + 0x21, 0x9F, 0xF3, 0x30, 0x31, 0xFE, 0x06, 0xB0 }, + { 0x4E, 0x8D, 0xDF, 0xF3, 0x65, 0x02, 0x92, 0xAB, + 0x5A, 0x41, 0x08, 0xC3, 0xAA, 0x47, 0x94, 0x0B }, + { 0xDA, 0x33, 0xDE, 0xF2, 0xA4, 0x2D, 0xF1, 0x39, + 0x75, 0x35, 0x28, 0x46, 0xC3, 0x03, 0x38, 0xCD }, + { 0xD5, 0x97, 0x6F, 0x79, 0xD8, 0x3D, 0x3A, 0x0D, + 0xC9, 0x80, 0x6C, 0x3C, 0x66, 0xF3, 0xEF, 0xD8 } +}; + +/* + * Checkup routine + */ +int mbedtls_md2_self_test( int verbose ) +{ + int i; + unsigned char md2sum[16]; + + for( i = 0; i < 7; i++ ) + { + if( verbose != 0 ) + mbedtls_printf( " MD2 test #%d: ", i + 1 ); + + mbedtls_md2( (unsigned char *) md2_test_str[i], + strlen( md2_test_str[i] ), md2sum ); + + if( memcmp( md2sum, md2_test_sum[i], 16 ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + + return( 0 ); +} + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_MD2_C */ diff --git a/security/mbedtls/src/md4.c b/security/mbedtls/src/md4.c new file mode 100644 index 0000000000..11a77e3ae4 --- /dev/null +++ b/security/mbedtls/src/md4.c @@ -0,0 +1,384 @@ +/* + * RFC 1186/1320 compliant MD4 implementation + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +/* + * The MD4 algorithm was designed by Ron Rivest in 1990. + * + * http://www.ietf.org/rfc/rfc1186.txt + * http://www.ietf.org/rfc/rfc1320.txt + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_MD4_C) + +#include "mbedtls/md4.h" + +#include + +#if defined(MBEDTLS_SELF_TEST) +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_printf printf +#endif /* MBEDTLS_PLATFORM_C */ +#endif /* MBEDTLS_SELF_TEST */ + +#if !defined(MBEDTLS_MD4_ALT) + +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +/* + * 32-bit integer manipulation macros (little endian) + */ +#ifndef GET_UINT32_LE +#define GET_UINT32_LE(n,b,i) \ +{ \ + (n) = ( (uint32_t) (b)[(i) ] ) \ + | ( (uint32_t) (b)[(i) + 1] << 8 ) \ + | ( (uint32_t) (b)[(i) + 2] << 16 ) \ + | ( (uint32_t) (b)[(i) + 3] << 24 ); \ +} +#endif + +#ifndef PUT_UINT32_LE +#define PUT_UINT32_LE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \ + (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \ + (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \ + (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \ +} +#endif + +void mbedtls_md4_init( mbedtls_md4_context *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_md4_context ) ); +} + +void mbedtls_md4_free( mbedtls_md4_context *ctx ) +{ + if( ctx == NULL ) + return; + + mbedtls_zeroize( ctx, sizeof( mbedtls_md4_context ) ); +} + +void mbedtls_md4_clone( mbedtls_md4_context *dst, + const mbedtls_md4_context *src ) +{ + *dst = *src; +} + +/* + * MD4 context setup + */ +void mbedtls_md4_starts( mbedtls_md4_context *ctx ) +{ + ctx->total[0] = 0; + ctx->total[1] = 0; + + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + ctx->state[3] = 0x10325476; +} + +#if !defined(MBEDTLS_MD4_PROCESS_ALT) +void mbedtls_md4_process( mbedtls_md4_context *ctx, const unsigned char data[64] ) +{ + uint32_t X[16], A, B, C, D; + + GET_UINT32_LE( X[ 0], data, 0 ); + GET_UINT32_LE( X[ 1], data, 4 ); + GET_UINT32_LE( X[ 2], data, 8 ); + GET_UINT32_LE( X[ 3], data, 12 ); + GET_UINT32_LE( X[ 4], data, 16 ); + GET_UINT32_LE( X[ 5], data, 20 ); + GET_UINT32_LE( X[ 6], data, 24 ); + GET_UINT32_LE( X[ 7], data, 28 ); + GET_UINT32_LE( X[ 8], data, 32 ); + GET_UINT32_LE( X[ 9], data, 36 ); + GET_UINT32_LE( X[10], data, 40 ); + GET_UINT32_LE( X[11], data, 44 ); + GET_UINT32_LE( X[12], data, 48 ); + GET_UINT32_LE( X[13], data, 52 ); + GET_UINT32_LE( X[14], data, 56 ); + GET_UINT32_LE( X[15], data, 60 ); + +#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) + + A = ctx->state[0]; + B = ctx->state[1]; + C = ctx->state[2]; + D = ctx->state[3]; + +#define F(x, y, z) ((x & y) | ((~x) & z)) +#define P(a,b,c,d,x,s) { a += F(b,c,d) + x; a = S(a,s); } + + P( A, B, C, D, X[ 0], 3 ); + P( D, A, B, C, X[ 1], 7 ); + P( C, D, A, B, X[ 2], 11 ); + P( B, C, D, A, X[ 3], 19 ); + P( A, B, C, D, X[ 4], 3 ); + P( D, A, B, C, X[ 5], 7 ); + P( C, D, A, B, X[ 6], 11 ); + P( B, C, D, A, X[ 7], 19 ); + P( A, B, C, D, X[ 8], 3 ); + P( D, A, B, C, X[ 9], 7 ); + P( C, D, A, B, X[10], 11 ); + P( B, C, D, A, X[11], 19 ); + P( A, B, C, D, X[12], 3 ); + P( D, A, B, C, X[13], 7 ); + P( C, D, A, B, X[14], 11 ); + P( B, C, D, A, X[15], 19 ); + +#undef P +#undef F + +#define F(x,y,z) ((x & y) | (x & z) | (y & z)) +#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x5A827999; a = S(a,s); } + + P( A, B, C, D, X[ 0], 3 ); + P( D, A, B, C, X[ 4], 5 ); + P( C, D, A, B, X[ 8], 9 ); + P( B, C, D, A, X[12], 13 ); + P( A, B, C, D, X[ 1], 3 ); + P( D, A, B, C, X[ 5], 5 ); + P( C, D, A, B, X[ 9], 9 ); + P( B, C, D, A, X[13], 13 ); + P( A, B, C, D, X[ 2], 3 ); + P( D, A, B, C, X[ 6], 5 ); + P( C, D, A, B, X[10], 9 ); + P( B, C, D, A, X[14], 13 ); + P( A, B, C, D, X[ 3], 3 ); + P( D, A, B, C, X[ 7], 5 ); + P( C, D, A, B, X[11], 9 ); + P( B, C, D, A, X[15], 13 ); + +#undef P +#undef F + +#define F(x,y,z) (x ^ y ^ z) +#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x6ED9EBA1; a = S(a,s); } + + P( A, B, C, D, X[ 0], 3 ); + P( D, A, B, C, X[ 8], 9 ); + P( C, D, A, B, X[ 4], 11 ); + P( B, C, D, A, X[12], 15 ); + P( A, B, C, D, X[ 2], 3 ); + P( D, A, B, C, X[10], 9 ); + P( C, D, A, B, X[ 6], 11 ); + P( B, C, D, A, X[14], 15 ); + P( A, B, C, D, X[ 1], 3 ); + P( D, A, B, C, X[ 9], 9 ); + P( C, D, A, B, X[ 5], 11 ); + P( B, C, D, A, X[13], 15 ); + P( A, B, C, D, X[ 3], 3 ); + P( D, A, B, C, X[11], 9 ); + P( C, D, A, B, X[ 7], 11 ); + P( B, C, D, A, X[15], 15 ); + +#undef F +#undef P + + ctx->state[0] += A; + ctx->state[1] += B; + ctx->state[2] += C; + ctx->state[3] += D; +} +#endif /* !MBEDTLS_MD4_PROCESS_ALT */ + +/* + * MD4 process buffer + */ +void mbedtls_md4_update( mbedtls_md4_context *ctx, const unsigned char *input, size_t ilen ) +{ + size_t fill; + uint32_t left; + + if( ilen == 0 ) + return; + + left = ctx->total[0] & 0x3F; + fill = 64 - left; + + ctx->total[0] += (uint32_t) ilen; + ctx->total[0] &= 0xFFFFFFFF; + + if( ctx->total[0] < (uint32_t) ilen ) + ctx->total[1]++; + + if( left && ilen >= fill ) + { + memcpy( (void *) (ctx->buffer + left), + (void *) input, fill ); + mbedtls_md4_process( ctx, ctx->buffer ); + input += fill; + ilen -= fill; + left = 0; + } + + while( ilen >= 64 ) + { + mbedtls_md4_process( ctx, input ); + input += 64; + ilen -= 64; + } + + if( ilen > 0 ) + { + memcpy( (void *) (ctx->buffer + left), + (void *) input, ilen ); + } +} + +static const unsigned char md4_padding[64] = +{ + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* + * MD4 final digest + */ +void mbedtls_md4_finish( mbedtls_md4_context *ctx, unsigned char output[16] ) +{ + uint32_t last, padn; + uint32_t high, low; + unsigned char msglen[8]; + + high = ( ctx->total[0] >> 29 ) + | ( ctx->total[1] << 3 ); + low = ( ctx->total[0] << 3 ); + + PUT_UINT32_LE( low, msglen, 0 ); + PUT_UINT32_LE( high, msglen, 4 ); + + last = ctx->total[0] & 0x3F; + padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); + + mbedtls_md4_update( ctx, (unsigned char *) md4_padding, padn ); + mbedtls_md4_update( ctx, msglen, 8 ); + + PUT_UINT32_LE( ctx->state[0], output, 0 ); + PUT_UINT32_LE( ctx->state[1], output, 4 ); + PUT_UINT32_LE( ctx->state[2], output, 8 ); + PUT_UINT32_LE( ctx->state[3], output, 12 ); +} + +#endif /* !MBEDTLS_MD4_ALT */ + +/* + * output = MD4( input buffer ) + */ +void mbedtls_md4( const unsigned char *input, size_t ilen, unsigned char output[16] ) +{ + mbedtls_md4_context ctx; + + mbedtls_md4_init( &ctx ); + mbedtls_md4_starts( &ctx ); + mbedtls_md4_update( &ctx, input, ilen ); + mbedtls_md4_finish( &ctx, output ); + mbedtls_md4_free( &ctx ); +} + +#if defined(MBEDTLS_SELF_TEST) + +/* + * RFC 1320 test vectors + */ +static const char md4_test_str[7][81] = +{ + { "" }, + { "a" }, + { "abc" }, + { "message digest" }, + { "abcdefghijklmnopqrstuvwxyz" }, + { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, + { "12345678901234567890123456789012345678901234567890123456789012" \ + "345678901234567890" } +}; + +static const unsigned char md4_test_sum[7][16] = +{ + { 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31, + 0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 }, + { 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46, + 0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 }, + { 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52, + 0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D }, + { 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8, + 0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B }, + { 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD, + 0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 }, + { 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35, + 0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 }, + { 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19, + 0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 } +}; + +/* + * Checkup routine + */ +int mbedtls_md4_self_test( int verbose ) +{ + int i; + unsigned char md4sum[16]; + + for( i = 0; i < 7; i++ ) + { + if( verbose != 0 ) + mbedtls_printf( " MD4 test #%d: ", i + 1 ); + + mbedtls_md4( (unsigned char *) md4_test_str[i], + strlen( md4_test_str[i] ), md4sum ); + + if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + + return( 0 ); +} + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_MD4_C */ diff --git a/security/mbedtls/src/md5.c b/security/mbedtls/src/md5.c new file mode 100644 index 0000000000..5d972dc9dd --- /dev/null +++ b/security/mbedtls/src/md5.c @@ -0,0 +1,404 @@ +/* + * RFC 1321 compliant MD5 implementation + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +/* + * The MD5 algorithm was designed by Ron Rivest in 1991. + * + * http://www.ietf.org/rfc/rfc1321.txt + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_MD5_C) + +#include "mbedtls/md5.h" + +#include + +#if defined(MBEDTLS_SELF_TEST) +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_printf printf +#endif /* MBEDTLS_PLATFORM_C */ +#endif /* MBEDTLS_SELF_TEST */ + +#if !defined(MBEDTLS_MD5_ALT) + +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +/* + * 32-bit integer manipulation macros (little endian) + */ +#ifndef GET_UINT32_LE +#define GET_UINT32_LE(n,b,i) \ +{ \ + (n) = ( (uint32_t) (b)[(i) ] ) \ + | ( (uint32_t) (b)[(i) + 1] << 8 ) \ + | ( (uint32_t) (b)[(i) + 2] << 16 ) \ + | ( (uint32_t) (b)[(i) + 3] << 24 ); \ +} +#endif + +#ifndef PUT_UINT32_LE +#define PUT_UINT32_LE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \ + (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \ + (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \ + (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \ +} +#endif + +void mbedtls_md5_init( mbedtls_md5_context *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_md5_context ) ); +} + +void mbedtls_md5_free( mbedtls_md5_context *ctx ) +{ + if( ctx == NULL ) + return; + + mbedtls_zeroize( ctx, sizeof( mbedtls_md5_context ) ); +} + +void mbedtls_md5_clone( mbedtls_md5_context *dst, + const mbedtls_md5_context *src ) +{ + *dst = *src; +} + +/* + * MD5 context setup + */ +void mbedtls_md5_starts( mbedtls_md5_context *ctx ) +{ + ctx->total[0] = 0; + ctx->total[1] = 0; + + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + ctx->state[3] = 0x10325476; +} + +#if !defined(MBEDTLS_MD5_PROCESS_ALT) +void mbedtls_md5_process( mbedtls_md5_context *ctx, const unsigned char data[64] ) +{ + uint32_t X[16], A, B, C, D; + + GET_UINT32_LE( X[ 0], data, 0 ); + GET_UINT32_LE( X[ 1], data, 4 ); + GET_UINT32_LE( X[ 2], data, 8 ); + GET_UINT32_LE( X[ 3], data, 12 ); + GET_UINT32_LE( X[ 4], data, 16 ); + GET_UINT32_LE( X[ 5], data, 20 ); + GET_UINT32_LE( X[ 6], data, 24 ); + GET_UINT32_LE( X[ 7], data, 28 ); + GET_UINT32_LE( X[ 8], data, 32 ); + GET_UINT32_LE( X[ 9], data, 36 ); + GET_UINT32_LE( X[10], data, 40 ); + GET_UINT32_LE( X[11], data, 44 ); + GET_UINT32_LE( X[12], data, 48 ); + GET_UINT32_LE( X[13], data, 52 ); + GET_UINT32_LE( X[14], data, 56 ); + GET_UINT32_LE( X[15], data, 60 ); + +#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) + +#define P(a,b,c,d,k,s,t) \ +{ \ + a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \ +} + + A = ctx->state[0]; + B = ctx->state[1]; + C = ctx->state[2]; + D = ctx->state[3]; + +#define F(x,y,z) (z ^ (x & (y ^ z))) + + P( A, B, C, D, 0, 7, 0xD76AA478 ); + P( D, A, B, C, 1, 12, 0xE8C7B756 ); + P( C, D, A, B, 2, 17, 0x242070DB ); + P( B, C, D, A, 3, 22, 0xC1BDCEEE ); + P( A, B, C, D, 4, 7, 0xF57C0FAF ); + P( D, A, B, C, 5, 12, 0x4787C62A ); + P( C, D, A, B, 6, 17, 0xA8304613 ); + P( B, C, D, A, 7, 22, 0xFD469501 ); + P( A, B, C, D, 8, 7, 0x698098D8 ); + P( D, A, B, C, 9, 12, 0x8B44F7AF ); + P( C, D, A, B, 10, 17, 0xFFFF5BB1 ); + P( B, C, D, A, 11, 22, 0x895CD7BE ); + P( A, B, C, D, 12, 7, 0x6B901122 ); + P( D, A, B, C, 13, 12, 0xFD987193 ); + P( C, D, A, B, 14, 17, 0xA679438E ); + P( B, C, D, A, 15, 22, 0x49B40821 ); + +#undef F + +#define F(x,y,z) (y ^ (z & (x ^ y))) + + P( A, B, C, D, 1, 5, 0xF61E2562 ); + P( D, A, B, C, 6, 9, 0xC040B340 ); + P( C, D, A, B, 11, 14, 0x265E5A51 ); + P( B, C, D, A, 0, 20, 0xE9B6C7AA ); + P( A, B, C, D, 5, 5, 0xD62F105D ); + P( D, A, B, C, 10, 9, 0x02441453 ); + P( C, D, A, B, 15, 14, 0xD8A1E681 ); + P( B, C, D, A, 4, 20, 0xE7D3FBC8 ); + P( A, B, C, D, 9, 5, 0x21E1CDE6 ); + P( D, A, B, C, 14, 9, 0xC33707D6 ); + P( C, D, A, B, 3, 14, 0xF4D50D87 ); + P( B, C, D, A, 8, 20, 0x455A14ED ); + P( A, B, C, D, 13, 5, 0xA9E3E905 ); + P( D, A, B, C, 2, 9, 0xFCEFA3F8 ); + P( C, D, A, B, 7, 14, 0x676F02D9 ); + P( B, C, D, A, 12, 20, 0x8D2A4C8A ); + +#undef F + +#define F(x,y,z) (x ^ y ^ z) + + P( A, B, C, D, 5, 4, 0xFFFA3942 ); + P( D, A, B, C, 8, 11, 0x8771F681 ); + P( C, D, A, B, 11, 16, 0x6D9D6122 ); + P( B, C, D, A, 14, 23, 0xFDE5380C ); + P( A, B, C, D, 1, 4, 0xA4BEEA44 ); + P( D, A, B, C, 4, 11, 0x4BDECFA9 ); + P( C, D, A, B, 7, 16, 0xF6BB4B60 ); + P( B, C, D, A, 10, 23, 0xBEBFBC70 ); + P( A, B, C, D, 13, 4, 0x289B7EC6 ); + P( D, A, B, C, 0, 11, 0xEAA127FA ); + P( C, D, A, B, 3, 16, 0xD4EF3085 ); + P( B, C, D, A, 6, 23, 0x04881D05 ); + P( A, B, C, D, 9, 4, 0xD9D4D039 ); + P( D, A, B, C, 12, 11, 0xE6DB99E5 ); + P( C, D, A, B, 15, 16, 0x1FA27CF8 ); + P( B, C, D, A, 2, 23, 0xC4AC5665 ); + +#undef F + +#define F(x,y,z) (y ^ (x | ~z)) + + P( A, B, C, D, 0, 6, 0xF4292244 ); + P( D, A, B, C, 7, 10, 0x432AFF97 ); + P( C, D, A, B, 14, 15, 0xAB9423A7 ); + P( B, C, D, A, 5, 21, 0xFC93A039 ); + P( A, B, C, D, 12, 6, 0x655B59C3 ); + P( D, A, B, C, 3, 10, 0x8F0CCC92 ); + P( C, D, A, B, 10, 15, 0xFFEFF47D ); + P( B, C, D, A, 1, 21, 0x85845DD1 ); + P( A, B, C, D, 8, 6, 0x6FA87E4F ); + P( D, A, B, C, 15, 10, 0xFE2CE6E0 ); + P( C, D, A, B, 6, 15, 0xA3014314 ); + P( B, C, D, A, 13, 21, 0x4E0811A1 ); + P( A, B, C, D, 4, 6, 0xF7537E82 ); + P( D, A, B, C, 11, 10, 0xBD3AF235 ); + P( C, D, A, B, 2, 15, 0x2AD7D2BB ); + P( B, C, D, A, 9, 21, 0xEB86D391 ); + +#undef F + + ctx->state[0] += A; + ctx->state[1] += B; + ctx->state[2] += C; + ctx->state[3] += D; +} +#endif /* !MBEDTLS_MD5_PROCESS_ALT */ + +/* + * MD5 process buffer + */ +void mbedtls_md5_update( mbedtls_md5_context *ctx, const unsigned char *input, size_t ilen ) +{ + size_t fill; + uint32_t left; + + if( ilen == 0 ) + return; + + left = ctx->total[0] & 0x3F; + fill = 64 - left; + + ctx->total[0] += (uint32_t) ilen; + ctx->total[0] &= 0xFFFFFFFF; + + if( ctx->total[0] < (uint32_t) ilen ) + ctx->total[1]++; + + if( left && ilen >= fill ) + { + memcpy( (void *) (ctx->buffer + left), input, fill ); + mbedtls_md5_process( ctx, ctx->buffer ); + input += fill; + ilen -= fill; + left = 0; + } + + while( ilen >= 64 ) + { + mbedtls_md5_process( ctx, input ); + input += 64; + ilen -= 64; + } + + if( ilen > 0 ) + { + memcpy( (void *) (ctx->buffer + left), input, ilen ); + } +} + +static const unsigned char md5_padding[64] = +{ + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* + * MD5 final digest + */ +void mbedtls_md5_finish( mbedtls_md5_context *ctx, unsigned char output[16] ) +{ + uint32_t last, padn; + uint32_t high, low; + unsigned char msglen[8]; + + high = ( ctx->total[0] >> 29 ) + | ( ctx->total[1] << 3 ); + low = ( ctx->total[0] << 3 ); + + PUT_UINT32_LE( low, msglen, 0 ); + PUT_UINT32_LE( high, msglen, 4 ); + + last = ctx->total[0] & 0x3F; + padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); + + mbedtls_md5_update( ctx, md5_padding, padn ); + mbedtls_md5_update( ctx, msglen, 8 ); + + PUT_UINT32_LE( ctx->state[0], output, 0 ); + PUT_UINT32_LE( ctx->state[1], output, 4 ); + PUT_UINT32_LE( ctx->state[2], output, 8 ); + PUT_UINT32_LE( ctx->state[3], output, 12 ); +} + +#endif /* !MBEDTLS_MD5_ALT */ + +/* + * output = MD5( input buffer ) + */ +void mbedtls_md5( const unsigned char *input, size_t ilen, unsigned char output[16] ) +{ + mbedtls_md5_context ctx; + + mbedtls_md5_init( &ctx ); + mbedtls_md5_starts( &ctx ); + mbedtls_md5_update( &ctx, input, ilen ); + mbedtls_md5_finish( &ctx, output ); + mbedtls_md5_free( &ctx ); +} + +#if defined(MBEDTLS_SELF_TEST) +/* + * RFC 1321 test vectors + */ +static const unsigned char md5_test_buf[7][81] = +{ + { "" }, + { "a" }, + { "abc" }, + { "message digest" }, + { "abcdefghijklmnopqrstuvwxyz" }, + { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, + { "12345678901234567890123456789012345678901234567890123456789012" \ + "345678901234567890" } +}; + +static const int md5_test_buflen[7] = +{ + 0, 1, 3, 14, 26, 62, 80 +}; + +static const unsigned char md5_test_sum[7][16] = +{ + { 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04, + 0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E }, + { 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8, + 0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 }, + { 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0, + 0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 }, + { 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D, + 0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 }, + { 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00, + 0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B }, + { 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5, + 0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F }, + { 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55, + 0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A } +}; + +/* + * Checkup routine + */ +int mbedtls_md5_self_test( int verbose ) +{ + int i; + unsigned char md5sum[16]; + + for( i = 0; i < 7; i++ ) + { + if( verbose != 0 ) + mbedtls_printf( " MD5 test #%d: ", i + 1 ); + + mbedtls_md5( md5_test_buf[i], md5_test_buflen[i], md5sum ); + + if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + + return( 0 ); +} + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_MD5_C */ diff --git a/security/mbedtls/src/md_wrap.c b/security/mbedtls/src/md_wrap.c new file mode 100644 index 0000000000..2cfcae200e --- /dev/null +++ b/security/mbedtls/src/md_wrap.c @@ -0,0 +1,575 @@ +/** + * \file md_wrap.c + * + * \brief Generic message digest wrapper for mbed TLS + * + * \author Adriaan de Jong + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_MD_C) + +#include "mbedtls/md_internal.h" + +#if defined(MBEDTLS_MD2_C) +#include "mbedtls/md2.h" +#endif + +#if defined(MBEDTLS_MD4_C) +#include "mbedtls/md4.h" +#endif + +#if defined(MBEDTLS_MD5_C) +#include "mbedtls/md5.h" +#endif + +#if defined(MBEDTLS_RIPEMD160_C) +#include "mbedtls/ripemd160.h" +#endif + +#if defined(MBEDTLS_SHA1_C) +#include "mbedtls/sha1.h" +#endif + +#if defined(MBEDTLS_SHA256_C) +#include "mbedtls/sha256.h" +#endif + +#if defined(MBEDTLS_SHA512_C) +#include "mbedtls/sha512.h" +#endif + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_calloc calloc +#define mbedtls_free free +#endif + +#if defined(MBEDTLS_MD2_C) + +static void md2_starts_wrap( void *ctx ) +{ + mbedtls_md2_starts( (mbedtls_md2_context *) ctx ); +} + +static void md2_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + mbedtls_md2_update( (mbedtls_md2_context *) ctx, input, ilen ); +} + +static void md2_finish_wrap( void *ctx, unsigned char *output ) +{ + mbedtls_md2_finish( (mbedtls_md2_context *) ctx, output ); +} + +static void *md2_ctx_alloc( void ) +{ + void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_md2_context ) ); + + if( ctx != NULL ) + mbedtls_md2_init( (mbedtls_md2_context *) ctx ); + + return( ctx ); +} + +static void md2_ctx_free( void *ctx ) +{ + mbedtls_md2_free( (mbedtls_md2_context *) ctx ); + mbedtls_free( ctx ); +} + +static void md2_clone_wrap( void *dst, const void *src ) +{ + mbedtls_md2_clone( (mbedtls_md2_context *) dst, + (const mbedtls_md2_context *) src ); +} + +static void md2_process_wrap( void *ctx, const unsigned char *data ) +{ + ((void) data); + + mbedtls_md2_process( (mbedtls_md2_context *) ctx ); +} + +const mbedtls_md_info_t mbedtls_md2_info = { + MBEDTLS_MD_MD2, + "MD2", + 16, + 16, + md2_starts_wrap, + md2_update_wrap, + md2_finish_wrap, + mbedtls_md2, + md2_ctx_alloc, + md2_ctx_free, + md2_clone_wrap, + md2_process_wrap, +}; + +#endif /* MBEDTLS_MD2_C */ + +#if defined(MBEDTLS_MD4_C) + +static void md4_starts_wrap( void *ctx ) +{ + mbedtls_md4_starts( (mbedtls_md4_context *) ctx ); +} + +static void md4_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + mbedtls_md4_update( (mbedtls_md4_context *) ctx, input, ilen ); +} + +static void md4_finish_wrap( void *ctx, unsigned char *output ) +{ + mbedtls_md4_finish( (mbedtls_md4_context *) ctx, output ); +} + +static void *md4_ctx_alloc( void ) +{ + void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_md4_context ) ); + + if( ctx != NULL ) + mbedtls_md4_init( (mbedtls_md4_context *) ctx ); + + return( ctx ); +} + +static void md4_ctx_free( void *ctx ) +{ + mbedtls_md4_free( (mbedtls_md4_context *) ctx ); + mbedtls_free( ctx ); +} + +static void md4_clone_wrap( void *dst, const void *src ) +{ + mbedtls_md4_clone( (mbedtls_md4_context *) dst, + (const mbedtls_md4_context *) src ); +} + +static void md4_process_wrap( void *ctx, const unsigned char *data ) +{ + mbedtls_md4_process( (mbedtls_md4_context *) ctx, data ); +} + +const mbedtls_md_info_t mbedtls_md4_info = { + MBEDTLS_MD_MD4, + "MD4", + 16, + 64, + md4_starts_wrap, + md4_update_wrap, + md4_finish_wrap, + mbedtls_md4, + md4_ctx_alloc, + md4_ctx_free, + md4_clone_wrap, + md4_process_wrap, +}; + +#endif /* MBEDTLS_MD4_C */ + +#if defined(MBEDTLS_MD5_C) + +static void md5_starts_wrap( void *ctx ) +{ + mbedtls_md5_starts( (mbedtls_md5_context *) ctx ); +} + +static void md5_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + mbedtls_md5_update( (mbedtls_md5_context *) ctx, input, ilen ); +} + +static void md5_finish_wrap( void *ctx, unsigned char *output ) +{ + mbedtls_md5_finish( (mbedtls_md5_context *) ctx, output ); +} + +static void *md5_ctx_alloc( void ) +{ + void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_md5_context ) ); + + if( ctx != NULL ) + mbedtls_md5_init( (mbedtls_md5_context *) ctx ); + + return( ctx ); +} + +static void md5_ctx_free( void *ctx ) +{ + mbedtls_md5_free( (mbedtls_md5_context *) ctx ); + mbedtls_free( ctx ); +} + +static void md5_clone_wrap( void *dst, const void *src ) +{ + mbedtls_md5_clone( (mbedtls_md5_context *) dst, + (const mbedtls_md5_context *) src ); +} + +static void md5_process_wrap( void *ctx, const unsigned char *data ) +{ + mbedtls_md5_process( (mbedtls_md5_context *) ctx, data ); +} + +const mbedtls_md_info_t mbedtls_md5_info = { + MBEDTLS_MD_MD5, + "MD5", + 16, + 64, + md5_starts_wrap, + md5_update_wrap, + md5_finish_wrap, + mbedtls_md5, + md5_ctx_alloc, + md5_ctx_free, + md5_clone_wrap, + md5_process_wrap, +}; + +#endif /* MBEDTLS_MD5_C */ + +#if defined(MBEDTLS_RIPEMD160_C) + +static void ripemd160_starts_wrap( void *ctx ) +{ + mbedtls_ripemd160_starts( (mbedtls_ripemd160_context *) ctx ); +} + +static void ripemd160_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + mbedtls_ripemd160_update( (mbedtls_ripemd160_context *) ctx, input, ilen ); +} + +static void ripemd160_finish_wrap( void *ctx, unsigned char *output ) +{ + mbedtls_ripemd160_finish( (mbedtls_ripemd160_context *) ctx, output ); +} + +static void *ripemd160_ctx_alloc( void ) +{ + void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ripemd160_context ) ); + + if( ctx != NULL ) + mbedtls_ripemd160_init( (mbedtls_ripemd160_context *) ctx ); + + return( ctx ); +} + +static void ripemd160_ctx_free( void *ctx ) +{ + mbedtls_ripemd160_free( (mbedtls_ripemd160_context *) ctx ); + mbedtls_free( ctx ); +} + +static void ripemd160_clone_wrap( void *dst, const void *src ) +{ + mbedtls_ripemd160_clone( (mbedtls_ripemd160_context *) dst, + (const mbedtls_ripemd160_context *) src ); +} + +static void ripemd160_process_wrap( void *ctx, const unsigned char *data ) +{ + mbedtls_ripemd160_process( (mbedtls_ripemd160_context *) ctx, data ); +} + +const mbedtls_md_info_t mbedtls_ripemd160_info = { + MBEDTLS_MD_RIPEMD160, + "RIPEMD160", + 20, + 64, + ripemd160_starts_wrap, + ripemd160_update_wrap, + ripemd160_finish_wrap, + mbedtls_ripemd160, + ripemd160_ctx_alloc, + ripemd160_ctx_free, + ripemd160_clone_wrap, + ripemd160_process_wrap, +}; + +#endif /* MBEDTLS_RIPEMD160_C */ + +#if defined(MBEDTLS_SHA1_C) + +static void sha1_starts_wrap( void *ctx ) +{ + mbedtls_sha1_starts( (mbedtls_sha1_context *) ctx ); +} + +static void sha1_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + mbedtls_sha1_update( (mbedtls_sha1_context *) ctx, input, ilen ); +} + +static void sha1_finish_wrap( void *ctx, unsigned char *output ) +{ + mbedtls_sha1_finish( (mbedtls_sha1_context *) ctx, output ); +} + +static void *sha1_ctx_alloc( void ) +{ + void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_sha1_context ) ); + + if( ctx != NULL ) + mbedtls_sha1_init( (mbedtls_sha1_context *) ctx ); + + return( ctx ); +} + +static void sha1_clone_wrap( void *dst, const void *src ) +{ + mbedtls_sha1_clone( (mbedtls_sha1_context *) dst, + (const mbedtls_sha1_context *) src ); +} + +static void sha1_ctx_free( void *ctx ) +{ + mbedtls_sha1_free( (mbedtls_sha1_context *) ctx ); + mbedtls_free( ctx ); +} + +static void sha1_process_wrap( void *ctx, const unsigned char *data ) +{ + mbedtls_sha1_process( (mbedtls_sha1_context *) ctx, data ); +} + +const mbedtls_md_info_t mbedtls_sha1_info = { + MBEDTLS_MD_SHA1, + "SHA1", + 20, + 64, + sha1_starts_wrap, + sha1_update_wrap, + sha1_finish_wrap, + mbedtls_sha1, + sha1_ctx_alloc, + sha1_ctx_free, + sha1_clone_wrap, + sha1_process_wrap, +}; + +#endif /* MBEDTLS_SHA1_C */ + +/* + * Wrappers for generic message digests + */ +#if defined(MBEDTLS_SHA256_C) + +static void sha224_starts_wrap( void *ctx ) +{ + mbedtls_sha256_starts( (mbedtls_sha256_context *) ctx, 1 ); +} + +static void sha224_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + mbedtls_sha256_update( (mbedtls_sha256_context *) ctx, input, ilen ); +} + +static void sha224_finish_wrap( void *ctx, unsigned char *output ) +{ + mbedtls_sha256_finish( (mbedtls_sha256_context *) ctx, output ); +} + +static void sha224_wrap( const unsigned char *input, size_t ilen, + unsigned char *output ) +{ + mbedtls_sha256( input, ilen, output, 1 ); +} + +static void *sha224_ctx_alloc( void ) +{ + void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_sha256_context ) ); + + if( ctx != NULL ) + mbedtls_sha256_init( (mbedtls_sha256_context *) ctx ); + + return( ctx ); +} + +static void sha224_ctx_free( void *ctx ) +{ + mbedtls_sha256_free( (mbedtls_sha256_context *) ctx ); + mbedtls_free( ctx ); +} + +static void sha224_clone_wrap( void *dst, const void *src ) +{ + mbedtls_sha256_clone( (mbedtls_sha256_context *) dst, + (const mbedtls_sha256_context *) src ); +} + +static void sha224_process_wrap( void *ctx, const unsigned char *data ) +{ + mbedtls_sha256_process( (mbedtls_sha256_context *) ctx, data ); +} + +const mbedtls_md_info_t mbedtls_sha224_info = { + MBEDTLS_MD_SHA224, + "SHA224", + 28, + 64, + sha224_starts_wrap, + sha224_update_wrap, + sha224_finish_wrap, + sha224_wrap, + sha224_ctx_alloc, + sha224_ctx_free, + sha224_clone_wrap, + sha224_process_wrap, +}; + +static void sha256_starts_wrap( void *ctx ) +{ + mbedtls_sha256_starts( (mbedtls_sha256_context *) ctx, 0 ); +} + +static void sha256_wrap( const unsigned char *input, size_t ilen, + unsigned char *output ) +{ + mbedtls_sha256( input, ilen, output, 0 ); +} + +const mbedtls_md_info_t mbedtls_sha256_info = { + MBEDTLS_MD_SHA256, + "SHA256", + 32, + 64, + sha256_starts_wrap, + sha224_update_wrap, + sha224_finish_wrap, + sha256_wrap, + sha224_ctx_alloc, + sha224_ctx_free, + sha224_clone_wrap, + sha224_process_wrap, +}; + +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_SHA512_C) + +static void sha384_starts_wrap( void *ctx ) +{ + mbedtls_sha512_starts( (mbedtls_sha512_context *) ctx, 1 ); +} + +static void sha384_update_wrap( void *ctx, const unsigned char *input, + size_t ilen ) +{ + mbedtls_sha512_update( (mbedtls_sha512_context *) ctx, input, ilen ); +} + +static void sha384_finish_wrap( void *ctx, unsigned char *output ) +{ + mbedtls_sha512_finish( (mbedtls_sha512_context *) ctx, output ); +} + +static void sha384_wrap( const unsigned char *input, size_t ilen, + unsigned char *output ) +{ + mbedtls_sha512( input, ilen, output, 1 ); +} + +static void *sha384_ctx_alloc( void ) +{ + void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_sha512_context ) ); + + if( ctx != NULL ) + mbedtls_sha512_init( (mbedtls_sha512_context *) ctx ); + + return( ctx ); +} + +static void sha384_ctx_free( void *ctx ) +{ + mbedtls_sha512_free( (mbedtls_sha512_context *) ctx ); + mbedtls_free( ctx ); +} + +static void sha384_clone_wrap( void *dst, const void *src ) +{ + mbedtls_sha512_clone( (mbedtls_sha512_context *) dst, + (const mbedtls_sha512_context *) src ); +} + +static void sha384_process_wrap( void *ctx, const unsigned char *data ) +{ + mbedtls_sha512_process( (mbedtls_sha512_context *) ctx, data ); +} + +const mbedtls_md_info_t mbedtls_sha384_info = { + MBEDTLS_MD_SHA384, + "SHA384", + 48, + 128, + sha384_starts_wrap, + sha384_update_wrap, + sha384_finish_wrap, + sha384_wrap, + sha384_ctx_alloc, + sha384_ctx_free, + sha384_clone_wrap, + sha384_process_wrap, +}; + +static void sha512_starts_wrap( void *ctx ) +{ + mbedtls_sha512_starts( (mbedtls_sha512_context *) ctx, 0 ); +} + +static void sha512_wrap( const unsigned char *input, size_t ilen, + unsigned char *output ) +{ + mbedtls_sha512( input, ilen, output, 0 ); +} + +const mbedtls_md_info_t mbedtls_sha512_info = { + MBEDTLS_MD_SHA512, + "SHA512", + 64, + 128, + sha512_starts_wrap, + sha384_update_wrap, + sha384_finish_wrap, + sha512_wrap, + sha384_ctx_alloc, + sha384_ctx_free, + sha384_clone_wrap, + sha384_process_wrap, +}; + +#endif /* MBEDTLS_SHA512_C */ + +#endif /* MBEDTLS_MD_C */ diff --git a/security/mbedtls/src/memory_buffer_alloc.c b/security/mbedtls/src/memory_buffer_alloc.c new file mode 100644 index 0000000000..545d5a2c32 --- /dev/null +++ b/security/mbedtls/src/memory_buffer_alloc.c @@ -0,0 +1,745 @@ +/* + * Buffer-based memory allocator + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) +#include "mbedtls/memory_buffer_alloc.h" + +/* No need for the header guard as MBEDTLS_MEMORY_BUFFER_ALLOC_C + is dependent upon MBEDTLS_PLATFORM_C */ +#include "mbedtls/platform.h" + +#include + +#if defined(MBEDTLS_MEMORY_BACKTRACE) +#include +#endif + +#if defined(MBEDTLS_THREADING_C) +#include "mbedtls/threading.h" +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +#define MAGIC1 0xFF00AA55 +#define MAGIC2 0xEE119966 +#define MAX_BT 20 + +typedef struct _memory_header memory_header; +struct _memory_header +{ + size_t magic1; + size_t size; + size_t alloc; + memory_header *prev; + memory_header *next; + memory_header *prev_free; + memory_header *next_free; +#if defined(MBEDTLS_MEMORY_BACKTRACE) + char **trace; + size_t trace_count; +#endif + size_t magic2; +}; + +typedef struct +{ + unsigned char *buf; + size_t len; + memory_header *first; + memory_header *first_free; + int verify; +#if defined(MBEDTLS_MEMORY_DEBUG) + size_t alloc_count; + size_t free_count; + size_t total_used; + size_t maximum_used; + size_t header_count; + size_t maximum_header_count; +#endif +#if defined(MBEDTLS_THREADING_C) + mbedtls_threading_mutex_t mutex; +#endif +} +buffer_alloc_ctx; + +static buffer_alloc_ctx heap; + +#if defined(MBEDTLS_MEMORY_DEBUG) +static void debug_header( memory_header *hdr ) +{ +#if defined(MBEDTLS_MEMORY_BACKTRACE) + size_t i; +#endif + + mbedtls_fprintf( stderr, "HDR: PTR(%10zu), PREV(%10zu), NEXT(%10zu), " + "ALLOC(%zu), SIZE(%10zu)\n", + (size_t) hdr, (size_t) hdr->prev, (size_t) hdr->next, + hdr->alloc, hdr->size ); + mbedtls_fprintf( stderr, " FPREV(%10zu), FNEXT(%10zu)\n", + (size_t) hdr->prev_free, (size_t) hdr->next_free ); + +#if defined(MBEDTLS_MEMORY_BACKTRACE) + mbedtls_fprintf( stderr, "TRACE: \n" ); + for( i = 0; i < hdr->trace_count; i++ ) + mbedtls_fprintf( stderr, "%s\n", hdr->trace[i] ); + mbedtls_fprintf( stderr, "\n" ); +#endif +} + +static void debug_chain() +{ + memory_header *cur = heap.first; + + mbedtls_fprintf( stderr, "\nBlock list\n" ); + while( cur != NULL ) + { + debug_header( cur ); + cur = cur->next; + } + + mbedtls_fprintf( stderr, "Free list\n" ); + cur = heap.first_free; + + while( cur != NULL ) + { + debug_header( cur ); + cur = cur->next_free; + } +} +#endif /* MBEDTLS_MEMORY_DEBUG */ + +static int verify_header( memory_header *hdr ) +{ + if( hdr->magic1 != MAGIC1 ) + { +#if defined(MBEDTLS_MEMORY_DEBUG) + mbedtls_fprintf( stderr, "FATAL: MAGIC1 mismatch\n" ); +#endif + return( 1 ); + } + + if( hdr->magic2 != MAGIC2 ) + { +#if defined(MBEDTLS_MEMORY_DEBUG) + mbedtls_fprintf( stderr, "FATAL: MAGIC2 mismatch\n" ); +#endif + return( 1 ); + } + + if( hdr->alloc > 1 ) + { +#if defined(MBEDTLS_MEMORY_DEBUG) + mbedtls_fprintf( stderr, "FATAL: alloc has illegal value\n" ); +#endif + return( 1 ); + } + + if( hdr->prev != NULL && hdr->prev == hdr->next ) + { +#if defined(MBEDTLS_MEMORY_DEBUG) + mbedtls_fprintf( stderr, "FATAL: prev == next\n" ); +#endif + return( 1 ); + } + + if( hdr->prev_free != NULL && hdr->prev_free == hdr->next_free ) + { +#if defined(MBEDTLS_MEMORY_DEBUG) + mbedtls_fprintf( stderr, "FATAL: prev_free == next_free\n" ); +#endif + return( 1 ); + } + + return( 0 ); +} + +static int verify_chain() +{ + memory_header *prv = heap.first, *cur = heap.first->next; + + if( verify_header( heap.first ) != 0 ) + { +#if defined(MBEDTLS_MEMORY_DEBUG) + mbedtls_fprintf( stderr, "FATAL: verification of first header " + "failed\n" ); +#endif + return( 1 ); + } + + if( heap.first->prev != NULL ) + { +#if defined(MBEDTLS_MEMORY_DEBUG) + mbedtls_fprintf( stderr, "FATAL: verification failed: " + "first->prev != NULL\n" ); +#endif + return( 1 ); + } + + while( cur != NULL ) + { + if( verify_header( cur ) != 0 ) + { +#if defined(MBEDTLS_MEMORY_DEBUG) + mbedtls_fprintf( stderr, "FATAL: verification of header " + "failed\n" ); +#endif + return( 1 ); + } + + if( cur->prev != prv ) + { +#if defined(MBEDTLS_MEMORY_DEBUG) + mbedtls_fprintf( stderr, "FATAL: verification failed: " + "cur->prev != prv\n" ); +#endif + return( 1 ); + } + + prv = cur; + cur = cur->next; + } + + return( 0 ); +} + +static void *buffer_alloc_calloc( size_t n, size_t size ) +{ + memory_header *new, *cur = heap.first_free; + unsigned char *p; + void *ret; + size_t original_len, len; +#if defined(MBEDTLS_MEMORY_BACKTRACE) + void *trace_buffer[MAX_BT]; + size_t trace_cnt; +#endif + + if( heap.buf == NULL || heap.first == NULL ) + return( NULL ); + + original_len = len = n * size; + + if( n != 0 && len / n != size ) + return( NULL ); + + if( len % MBEDTLS_MEMORY_ALIGN_MULTIPLE ) + { + len -= len % MBEDTLS_MEMORY_ALIGN_MULTIPLE; + len += MBEDTLS_MEMORY_ALIGN_MULTIPLE; + } + + // Find block that fits + // + while( cur != NULL ) + { + if( cur->size >= len ) + break; + + cur = cur->next_free; + } + + if( cur == NULL ) + return( NULL ); + + if( cur->alloc != 0 ) + { +#if defined(MBEDTLS_MEMORY_DEBUG) + mbedtls_fprintf( stderr, "FATAL: block in free_list but allocated " + "data\n" ); +#endif + mbedtls_exit( 1 ); + } + +#if defined(MBEDTLS_MEMORY_DEBUG) + heap.alloc_count++; +#endif + + // Found location, split block if > memory_header + 4 room left + // + if( cur->size - len < sizeof(memory_header) + + MBEDTLS_MEMORY_ALIGN_MULTIPLE ) + { + cur->alloc = 1; + + // Remove from free_list + // + if( cur->prev_free != NULL ) + cur->prev_free->next_free = cur->next_free; + else + heap.first_free = cur->next_free; + + if( cur->next_free != NULL ) + cur->next_free->prev_free = cur->prev_free; + + cur->prev_free = NULL; + cur->next_free = NULL; + +#if defined(MBEDTLS_MEMORY_DEBUG) + heap.total_used += cur->size; + if( heap.total_used > heap.maximum_used ) + heap.maximum_used = heap.total_used; +#endif +#if defined(MBEDTLS_MEMORY_BACKTRACE) + trace_cnt = backtrace( trace_buffer, MAX_BT ); + cur->trace = backtrace_symbols( trace_buffer, trace_cnt ); + cur->trace_count = trace_cnt; +#endif + + if( ( heap.verify & MBEDTLS_MEMORY_VERIFY_ALLOC ) && verify_chain() != 0 ) + mbedtls_exit( 1 ); + + ret = (unsigned char *) cur + sizeof( memory_header ); + memset( ret, 0, original_len ); + + return( ret ); + } + + p = ( (unsigned char *) cur ) + sizeof(memory_header) + len; + new = (memory_header *) p; + + new->size = cur->size - len - sizeof(memory_header); + new->alloc = 0; + new->prev = cur; + new->next = cur->next; +#if defined(MBEDTLS_MEMORY_BACKTRACE) + new->trace = NULL; + new->trace_count = 0; +#endif + new->magic1 = MAGIC1; + new->magic2 = MAGIC2; + + if( new->next != NULL ) + new->next->prev = new; + + // Replace cur with new in free_list + // + new->prev_free = cur->prev_free; + new->next_free = cur->next_free; + if( new->prev_free != NULL ) + new->prev_free->next_free = new; + else + heap.first_free = new; + + if( new->next_free != NULL ) + new->next_free->prev_free = new; + + cur->alloc = 1; + cur->size = len; + cur->next = new; + cur->prev_free = NULL; + cur->next_free = NULL; + +#if defined(MBEDTLS_MEMORY_DEBUG) + heap.header_count++; + if( heap.header_count > heap.maximum_header_count ) + heap.maximum_header_count = heap.header_count; + heap.total_used += cur->size; + if( heap.total_used > heap.maximum_used ) + heap.maximum_used = heap.total_used; +#endif +#if defined(MBEDTLS_MEMORY_BACKTRACE) + trace_cnt = backtrace( trace_buffer, MAX_BT ); + cur->trace = backtrace_symbols( trace_buffer, trace_cnt ); + cur->trace_count = trace_cnt; +#endif + + if( ( heap.verify & MBEDTLS_MEMORY_VERIFY_ALLOC ) && verify_chain() != 0 ) + mbedtls_exit( 1 ); + + ret = (unsigned char *) cur + sizeof( memory_header ); + memset( ret, 0, original_len ); + + return( ret ); +} + +static void buffer_alloc_free( void *ptr ) +{ + memory_header *hdr, *old = NULL; + unsigned char *p = (unsigned char *) ptr; + + if( ptr == NULL || heap.buf == NULL || heap.first == NULL ) + return; + + if( p < heap.buf || p > heap.buf + heap.len ) + { +#if defined(MBEDTLS_MEMORY_DEBUG) + mbedtls_fprintf( stderr, "FATAL: mbedtls_free() outside of managed " + "space\n" ); +#endif + mbedtls_exit( 1 ); + } + + p -= sizeof(memory_header); + hdr = (memory_header *) p; + + if( verify_header( hdr ) != 0 ) + mbedtls_exit( 1 ); + + if( hdr->alloc != 1 ) + { +#if defined(MBEDTLS_MEMORY_DEBUG) + mbedtls_fprintf( stderr, "FATAL: mbedtls_free() on unallocated " + "data\n" ); +#endif + mbedtls_exit( 1 ); + } + + hdr->alloc = 0; + +#if defined(MBEDTLS_MEMORY_DEBUG) + heap.free_count++; + heap.total_used -= hdr->size; +#endif + +#if defined(MBEDTLS_MEMORY_BACKTRACE) + free( hdr->trace ); + hdr->trace = NULL; + hdr->trace_count = 0; +#endif + + // Regroup with block before + // + if( hdr->prev != NULL && hdr->prev->alloc == 0 ) + { +#if defined(MBEDTLS_MEMORY_DEBUG) + heap.header_count--; +#endif + hdr->prev->size += sizeof(memory_header) + hdr->size; + hdr->prev->next = hdr->next; + old = hdr; + hdr = hdr->prev; + + if( hdr->next != NULL ) + hdr->next->prev = hdr; + + memset( old, 0, sizeof(memory_header) ); + } + + // Regroup with block after + // + if( hdr->next != NULL && hdr->next->alloc == 0 ) + { +#if defined(MBEDTLS_MEMORY_DEBUG) + heap.header_count--; +#endif + hdr->size += sizeof(memory_header) + hdr->next->size; + old = hdr->next; + hdr->next = hdr->next->next; + + if( hdr->prev_free != NULL || hdr->next_free != NULL ) + { + if( hdr->prev_free != NULL ) + hdr->prev_free->next_free = hdr->next_free; + else + heap.first_free = hdr->next_free; + + if( hdr->next_free != NULL ) + hdr->next_free->prev_free = hdr->prev_free; + } + + hdr->prev_free = old->prev_free; + hdr->next_free = old->next_free; + + if( hdr->prev_free != NULL ) + hdr->prev_free->next_free = hdr; + else + heap.first_free = hdr; + + if( hdr->next_free != NULL ) + hdr->next_free->prev_free = hdr; + + if( hdr->next != NULL ) + hdr->next->prev = hdr; + + memset( old, 0, sizeof(memory_header) ); + } + + // Prepend to free_list if we have not merged + // (Does not have to stay in same order as prev / next list) + // + if( old == NULL ) + { + hdr->next_free = heap.first_free; + if( heap.first_free != NULL ) + heap.first_free->prev_free = hdr; + heap.first_free = hdr; + } + + if( ( heap.verify & MBEDTLS_MEMORY_VERIFY_FREE ) && verify_chain() != 0 ) + mbedtls_exit( 1 ); +} + +void mbedtls_memory_buffer_set_verify( int verify ) +{ + heap.verify = verify; +} + +int mbedtls_memory_buffer_alloc_verify() +{ + return verify_chain(); +} + +#if defined(MBEDTLS_MEMORY_DEBUG) +void mbedtls_memory_buffer_alloc_status() +{ + mbedtls_fprintf( stderr, + "Current use: %zu blocks / %zu bytes, max: %zu blocks / " + "%zu bytes (total %zu bytes), alloc / free: %zu / %zu\n", + heap.header_count, heap.total_used, + heap.maximum_header_count, heap.maximum_used, + heap.maximum_header_count * sizeof( memory_header ) + + heap.maximum_used, + heap.alloc_count, heap.free_count ); + + if( heap.first->next == NULL ) + mbedtls_fprintf( stderr, "All memory de-allocated in stack buffer\n" ); + else + { + mbedtls_fprintf( stderr, "Memory currently allocated:\n" ); + debug_chain(); + } +} + +void mbedtls_memory_buffer_alloc_max_get( size_t *max_used, size_t *max_blocks ) +{ + *max_used = heap.maximum_used; + *max_blocks = heap.maximum_header_count; +} + +void mbedtls_memory_buffer_alloc_max_reset( void ) +{ + heap.maximum_used = 0; + heap.maximum_header_count = 0; +} + +void mbedtls_memory_buffer_alloc_cur_get( size_t *cur_used, size_t *cur_blocks ) +{ + *cur_used = heap.total_used; + *cur_blocks = heap.header_count; +} +#endif /* MBEDTLS_MEMORY_DEBUG */ + +#if defined(MBEDTLS_THREADING_C) +static void *buffer_alloc_calloc_mutexed( size_t n, size_t size ) +{ + void *buf; + if( mbedtls_mutex_lock( &heap.mutex ) != 0 ) + return( NULL ); + buf = buffer_alloc_calloc( n, size ); + if( mbedtls_mutex_unlock( &heap.mutex ) ) + return( NULL ); + return( buf ); +} + +static void buffer_alloc_free_mutexed( void *ptr ) +{ + /* We have to good option here, but corrupting the heap seems + * worse than loosing memory. */ + if( mbedtls_mutex_lock( &heap.mutex ) ) + return; + buffer_alloc_free( ptr ); + (void) mbedtls_mutex_unlock( &heap.mutex ); +} +#endif /* MBEDTLS_THREADING_C */ + +void mbedtls_memory_buffer_alloc_init( unsigned char *buf, size_t len ) +{ + memset( &heap, 0, sizeof(buffer_alloc_ctx) ); + memset( buf, 0, len ); + +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_init( &heap.mutex ); + mbedtls_platform_set_calloc_free( buffer_alloc_calloc_mutexed, + buffer_alloc_free_mutexed ); +#else + mbedtls_platform_set_calloc_free( buffer_alloc_calloc, buffer_alloc_free ); +#endif + + if( (size_t) buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE ) + { + /* Adjust len first since buf is used in the computation */ + len -= MBEDTLS_MEMORY_ALIGN_MULTIPLE + - (size_t) buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE; + buf += MBEDTLS_MEMORY_ALIGN_MULTIPLE + - (size_t) buf % MBEDTLS_MEMORY_ALIGN_MULTIPLE; + } + + heap.buf = buf; + heap.len = len; + + heap.first = (memory_header *) buf; + heap.first->size = len - sizeof(memory_header); + heap.first->magic1 = MAGIC1; + heap.first->magic2 = MAGIC2; + heap.first_free = heap.first; +} + +void mbedtls_memory_buffer_alloc_free() +{ +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_free( &heap.mutex ); +#endif + mbedtls_zeroize( &heap, sizeof(buffer_alloc_ctx) ); +} + +#if defined(MBEDTLS_SELF_TEST) +static int check_pointer( void *p ) +{ + if( p == NULL ) + return( -1 ); + + if( (size_t) p % MBEDTLS_MEMORY_ALIGN_MULTIPLE != 0 ) + return( -1 ); + + return( 0 ); +} + +static int check_all_free( ) +{ + if( +#if defined(MBEDTLS_MEMORY_DEBUG) + heap.total_used != 0 || +#endif + heap.first != heap.first_free || + (void *) heap.first != (void *) heap.buf ) + { + return( -1 ); + } + + return( 0 ); +} + +#define TEST_ASSERT( condition ) \ + if( ! (condition) ) \ + { \ + if( verbose != 0 ) \ + mbedtls_printf( "failed\n" ); \ + \ + ret = 1; \ + goto cleanup; \ + } + +int mbedtls_memory_buffer_alloc_self_test( int verbose ) +{ + unsigned char buf[1024]; + unsigned char *p, *q, *r, *end; + int ret = 0; + + if( verbose != 0 ) + mbedtls_printf( " MBA test #1 (basic alloc-free cycle): " ); + + mbedtls_memory_buffer_alloc_init( buf, sizeof( buf ) ); + + p = mbedtls_calloc( 1, 1 ); + q = mbedtls_calloc( 1, 128 ); + r = mbedtls_calloc( 1, 16 ); + + TEST_ASSERT( check_pointer( p ) == 0 && + check_pointer( q ) == 0 && + check_pointer( r ) == 0 ); + + mbedtls_free( r ); + mbedtls_free( q ); + mbedtls_free( p ); + + TEST_ASSERT( check_all_free( ) == 0 ); + + /* Memorize end to compare with the next test */ + end = heap.buf + heap.len; + + mbedtls_memory_buffer_alloc_free( ); + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + + if( verbose != 0 ) + mbedtls_printf( " MBA test #2 (buf not aligned): " ); + + mbedtls_memory_buffer_alloc_init( buf + 1, sizeof( buf ) - 1 ); + + TEST_ASSERT( heap.buf + heap.len == end ); + + p = mbedtls_calloc( 1, 1 ); + q = mbedtls_calloc( 1, 128 ); + r = mbedtls_calloc( 1, 16 ); + + TEST_ASSERT( check_pointer( p ) == 0 && + check_pointer( q ) == 0 && + check_pointer( r ) == 0 ); + + mbedtls_free( r ); + mbedtls_free( q ); + mbedtls_free( p ); + + TEST_ASSERT( check_all_free( ) == 0 ); + + mbedtls_memory_buffer_alloc_free( ); + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + + if( verbose != 0 ) + mbedtls_printf( " MBA test #3 (full): " ); + + mbedtls_memory_buffer_alloc_init( buf, sizeof( buf ) ); + + p = mbedtls_calloc( 1, sizeof( buf ) - sizeof( memory_header ) ); + + TEST_ASSERT( check_pointer( p ) == 0 ); + TEST_ASSERT( mbedtls_calloc( 1, 1 ) == NULL ); + + mbedtls_free( p ); + + p = mbedtls_calloc( 1, sizeof( buf ) - 2 * sizeof( memory_header ) - 16 ); + q = mbedtls_calloc( 1, 16 ); + + TEST_ASSERT( check_pointer( p ) == 0 && check_pointer( q ) == 0 ); + TEST_ASSERT( mbedtls_calloc( 1, 1 ) == NULL ); + + mbedtls_free( q ); + + TEST_ASSERT( mbedtls_calloc( 1, 17 ) == NULL ); + + mbedtls_free( p ); + + TEST_ASSERT( check_all_free( ) == 0 ); + + mbedtls_memory_buffer_alloc_free( ); + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + +cleanup: + mbedtls_memory_buffer_alloc_free( ); + + return( ret ); +} +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_MEMORY_BUFFER_ALLOC_C */ diff --git a/security/mbedtls/src/net_sockets.c b/security/mbedtls/src/net_sockets.c new file mode 100644 index 0000000000..076f196090 --- /dev/null +++ b/security/mbedtls/src/net_sockets.c @@ -0,0 +1,593 @@ +/* + * TCP/IP or UDP/IP networking functions + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if !defined(MBEDTLS_NET_ALT) + +#if defined(MBEDTLS_NET_C) + +#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \ + !defined(__APPLE__) && !defined(_WIN32) +#error "This module only works on Unix and Windows, see MBEDTLS_NET_C in config.h" +#endif + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#endif + +#include "mbedtls/net_sockets.h" + +#include + +#if (defined(_WIN32) || defined(_WIN32_WCE)) && !defined(EFIX64) && \ + !defined(EFI32) + +#ifdef _WIN32_WINNT +#undef _WIN32_WINNT +#endif +/* Enables getaddrinfo() & Co */ +#define _WIN32_WINNT 0x0501 +#include + +#include +#include + +#if defined(_MSC_VER) +#if defined(_WIN32_WCE) +#pragma comment( lib, "ws2.lib" ) +#else +#pragma comment( lib, "ws2_32.lib" ) +#endif +#endif /* _MSC_VER */ + +#define read(fd,buf,len) recv(fd,(char*)buf,(int) len,0) +#define write(fd,buf,len) send(fd,(char*)buf,(int) len,0) +#define close(fd) closesocket(fd) + +static int wsa_init_done = 0; + +#else /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */ + +/* Some MS functions want int and MSVC warns if we pass size_t, + * but the standard fucntions use socklen_t, so cast only for MSVC */ +#if defined(_MSC_VER) +#define MSVC_INT_CAST (int) +#else +#define MSVC_INT_CAST +#endif + +#include + +#include + +#include + +/* + * Prepare for using the sockets interface + */ +static int net_prepare( void ) +{ +#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ + !defined(EFI32) + WSADATA wsaData; + + if( wsa_init_done == 0 ) + { + if( WSAStartup( MAKEWORD(2,0), &wsaData ) != 0 ) + return( MBEDTLS_ERR_NET_SOCKET_FAILED ); + + wsa_init_done = 1; + } +#else +#if !defined(EFIX64) && !defined(EFI32) + signal( SIGPIPE, SIG_IGN ); +#endif +#endif + return( 0 ); +} + +/* + * Initialize a context + */ +void mbedtls_net_init( mbedtls_net_context *ctx ) +{ + ctx->fd = -1; +} + +/* + * Initiate a TCP connection with host:port and the given protocol + */ +int mbedtls_net_connect( mbedtls_net_context *ctx, const char *host, + const char *port, int proto ) +{ + int ret; + struct addrinfo hints, *addr_list, *cur; + + if( ( ret = net_prepare() ) != 0 ) + return( ret ); + + /* Do name resolution with both IPv6 and IPv4 */ + memset( &hints, 0, sizeof( hints ) ); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = proto == MBEDTLS_NET_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM; + hints.ai_protocol = proto == MBEDTLS_NET_PROTO_UDP ? IPPROTO_UDP : IPPROTO_TCP; + + if( getaddrinfo( host, port, &hints, &addr_list ) != 0 ) + return( MBEDTLS_ERR_NET_UNKNOWN_HOST ); + + /* Try the sockaddrs until a connection succeeds */ + ret = MBEDTLS_ERR_NET_UNKNOWN_HOST; + for( cur = addr_list; cur != NULL; cur = cur->ai_next ) + { + ctx->fd = (int) socket( cur->ai_family, cur->ai_socktype, + cur->ai_protocol ); + if( ctx->fd < 0 ) + { + ret = MBEDTLS_ERR_NET_SOCKET_FAILED; + continue; + } + + if( connect( ctx->fd, cur->ai_addr, MSVC_INT_CAST cur->ai_addrlen ) == 0 ) + { + ret = 0; + break; + } + + close( ctx->fd ); + ret = MBEDTLS_ERR_NET_CONNECT_FAILED; + } + + freeaddrinfo( addr_list ); + + return( ret ); +} + +/* + * Create a listening socket on bind_ip:port + */ +int mbedtls_net_bind( mbedtls_net_context *ctx, const char *bind_ip, const char *port, int proto ) +{ + int n, ret; + struct addrinfo hints, *addr_list, *cur; + + if( ( ret = net_prepare() ) != 0 ) + return( ret ); + + /* Bind to IPv6 and/or IPv4, but only in the desired protocol */ + memset( &hints, 0, sizeof( hints ) ); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = proto == MBEDTLS_NET_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM; + hints.ai_protocol = proto == MBEDTLS_NET_PROTO_UDP ? IPPROTO_UDP : IPPROTO_TCP; + if( bind_ip == NULL ) + hints.ai_flags = AI_PASSIVE; + + if( getaddrinfo( bind_ip, port, &hints, &addr_list ) != 0 ) + return( MBEDTLS_ERR_NET_UNKNOWN_HOST ); + + /* Try the sockaddrs until a binding succeeds */ + ret = MBEDTLS_ERR_NET_UNKNOWN_HOST; + for( cur = addr_list; cur != NULL; cur = cur->ai_next ) + { + ctx->fd = (int) socket( cur->ai_family, cur->ai_socktype, + cur->ai_protocol ); + if( ctx->fd < 0 ) + { + ret = MBEDTLS_ERR_NET_SOCKET_FAILED; + continue; + } + + n = 1; + if( setsockopt( ctx->fd, SOL_SOCKET, SO_REUSEADDR, + (const char *) &n, sizeof( n ) ) != 0 ) + { + close( ctx->fd ); + ret = MBEDTLS_ERR_NET_SOCKET_FAILED; + continue; + } + + if( bind( ctx->fd, cur->ai_addr, MSVC_INT_CAST cur->ai_addrlen ) != 0 ) + { + close( ctx->fd ); + ret = MBEDTLS_ERR_NET_BIND_FAILED; + continue; + } + + /* Listen only makes sense for TCP */ + if( proto == MBEDTLS_NET_PROTO_TCP ) + { + if( listen( ctx->fd, MBEDTLS_NET_LISTEN_BACKLOG ) != 0 ) + { + close( ctx->fd ); + ret = MBEDTLS_ERR_NET_LISTEN_FAILED; + continue; + } + } + + /* Bind was successful */ + ret = 0; + break; + } + + freeaddrinfo( addr_list ); + + return( ret ); + +} + +#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ + !defined(EFI32) +/* + * Check if the requested operation would be blocking on a non-blocking socket + * and thus 'failed' with a negative return value. + */ +static int net_would_block( const mbedtls_net_context *ctx ) +{ + ((void) ctx); + return( WSAGetLastError() == WSAEWOULDBLOCK ); +} +#else +/* + * Check if the requested operation would be blocking on a non-blocking socket + * and thus 'failed' with a negative return value. + * + * Note: on a blocking socket this function always returns 0! + */ +static int net_would_block( const mbedtls_net_context *ctx ) +{ + /* + * Never return 'WOULD BLOCK' on a non-blocking socket + */ + if( ( fcntl( ctx->fd, F_GETFL ) & O_NONBLOCK ) != O_NONBLOCK ) + return( 0 ); + + switch( errno ) + { +#if defined EAGAIN + case EAGAIN: +#endif +#if defined EWOULDBLOCK && EWOULDBLOCK != EAGAIN + case EWOULDBLOCK: +#endif + return( 1 ); + } + return( 0 ); +} +#endif /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */ + +/* + * Accept a connection from a remote client + */ +int mbedtls_net_accept( mbedtls_net_context *bind_ctx, + mbedtls_net_context *client_ctx, + void *client_ip, size_t buf_size, size_t *ip_len ) +{ + int ret; + int type; + + struct sockaddr_storage client_addr; + +#if defined(__socklen_t_defined) || defined(_SOCKLEN_T) || \ + defined(_SOCKLEN_T_DECLARED) || defined(__DEFINED_socklen_t) + socklen_t n = (socklen_t) sizeof( client_addr ); + socklen_t type_len = (socklen_t) sizeof( type ); +#else + int n = (int) sizeof( client_addr ); + int type_len = (int) sizeof( type ); +#endif + + /* Is this a TCP or UDP socket? */ + if( getsockopt( bind_ctx->fd, SOL_SOCKET, SO_TYPE, + (void *) &type, &type_len ) != 0 || + ( type != SOCK_STREAM && type != SOCK_DGRAM ) ) + { + return( MBEDTLS_ERR_NET_ACCEPT_FAILED ); + } + + if( type == SOCK_STREAM ) + { + /* TCP: actual accept() */ + ret = client_ctx->fd = (int) accept( bind_ctx->fd, + (struct sockaddr *) &client_addr, &n ); + } + else + { + /* UDP: wait for a message, but keep it in the queue */ + char buf[1] = { 0 }; + + ret = (int) recvfrom( bind_ctx->fd, buf, sizeof( buf ), MSG_PEEK, + (struct sockaddr *) &client_addr, &n ); + +#if defined(_WIN32) + if( ret == SOCKET_ERROR && + WSAGetLastError() == WSAEMSGSIZE ) + { + /* We know buf is too small, thanks, just peeking here */ + ret = 0; + } +#endif + } + + if( ret < 0 ) + { + if( net_would_block( bind_ctx ) != 0 ) + return( MBEDTLS_ERR_SSL_WANT_READ ); + + return( MBEDTLS_ERR_NET_ACCEPT_FAILED ); + } + + /* UDP: hijack the listening socket to communicate with the client, + * then bind a new socket to accept new connections */ + if( type != SOCK_STREAM ) + { + struct sockaddr_storage local_addr; + int one = 1; + + if( connect( bind_ctx->fd, (struct sockaddr *) &client_addr, n ) != 0 ) + return( MBEDTLS_ERR_NET_ACCEPT_FAILED ); + + client_ctx->fd = bind_ctx->fd; + bind_ctx->fd = -1; /* In case we exit early */ + + n = sizeof( struct sockaddr_storage ); + if( getsockname( client_ctx->fd, + (struct sockaddr *) &local_addr, &n ) != 0 || + ( bind_ctx->fd = (int) socket( local_addr.ss_family, + SOCK_DGRAM, IPPROTO_UDP ) ) < 0 || + setsockopt( bind_ctx->fd, SOL_SOCKET, SO_REUSEADDR, + (const char *) &one, sizeof( one ) ) != 0 ) + { + return( MBEDTLS_ERR_NET_SOCKET_FAILED ); + } + + if( bind( bind_ctx->fd, (struct sockaddr *) &local_addr, n ) != 0 ) + { + return( MBEDTLS_ERR_NET_BIND_FAILED ); + } + } + + if( client_ip != NULL ) + { + if( client_addr.ss_family == AF_INET ) + { + struct sockaddr_in *addr4 = (struct sockaddr_in *) &client_addr; + *ip_len = sizeof( addr4->sin_addr.s_addr ); + + if( buf_size < *ip_len ) + return( MBEDTLS_ERR_NET_BUFFER_TOO_SMALL ); + + memcpy( client_ip, &addr4->sin_addr.s_addr, *ip_len ); + } + else + { + struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) &client_addr; + *ip_len = sizeof( addr6->sin6_addr.s6_addr ); + + if( buf_size < *ip_len ) + return( MBEDTLS_ERR_NET_BUFFER_TOO_SMALL ); + + memcpy( client_ip, &addr6->sin6_addr.s6_addr, *ip_len); + } + } + + return( 0 ); +} + +/* + * Set the socket blocking or non-blocking + */ +int mbedtls_net_set_block( mbedtls_net_context *ctx ) +{ +#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ + !defined(EFI32) + u_long n = 0; + return( ioctlsocket( ctx->fd, FIONBIO, &n ) ); +#else + return( fcntl( ctx->fd, F_SETFL, fcntl( ctx->fd, F_GETFL ) & ~O_NONBLOCK ) ); +#endif +} + +int mbedtls_net_set_nonblock( mbedtls_net_context *ctx ) +{ +#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ + !defined(EFI32) + u_long n = 1; + return( ioctlsocket( ctx->fd, FIONBIO, &n ) ); +#else + return( fcntl( ctx->fd, F_SETFL, fcntl( ctx->fd, F_GETFL ) | O_NONBLOCK ) ); +#endif +} + +/* + * Portable usleep helper + */ +void mbedtls_net_usleep( unsigned long usec ) +{ +#if defined(_WIN32) + Sleep( ( usec + 999 ) / 1000 ); +#else + struct timeval tv; + tv.tv_sec = usec / 1000000; +#if defined(__unix__) || defined(__unix) || \ + ( defined(__APPLE__) && defined(__MACH__) ) + tv.tv_usec = (suseconds_t) usec % 1000000; +#else + tv.tv_usec = usec % 1000000; +#endif + select( 0, NULL, NULL, NULL, &tv ); +#endif +} + +/* + * Read at most 'len' characters + */ +int mbedtls_net_recv( void *ctx, unsigned char *buf, size_t len ) +{ + int ret; + int fd = ((mbedtls_net_context *) ctx)->fd; + + if( fd < 0 ) + return( MBEDTLS_ERR_NET_INVALID_CONTEXT ); + + errno = 0; + ret = (int) read( fd, buf, len ); + + if( ret < 0 ) + { + if( net_would_block( ctx ) != 0 ) + return( MBEDTLS_ERR_SSL_WANT_READ ); + +#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ + !defined(EFI32) + if( WSAGetLastError() == WSAECONNRESET ) + return( MBEDTLS_ERR_NET_CONN_RESET ); +#else + if( errno == EPIPE || errno == ECONNRESET ) + return( MBEDTLS_ERR_NET_CONN_RESET ); + + if( errno == EINTR ) + return( MBEDTLS_ERR_SSL_WANT_READ ); +#endif + + printf("net recv failed - errno: %d\n", errno); + return( MBEDTLS_ERR_NET_RECV_FAILED ); + } + + return( ret ); +} + +/* + * Read at most 'len' characters, blocking for at most 'timeout' ms + */ +int mbedtls_net_recv_timeout( void *ctx, unsigned char *buf, size_t len, + uint32_t timeout ) +{ + int ret; + struct timeval tv; + fd_set read_fds; + int fd = ((mbedtls_net_context *) ctx)->fd; + + if( fd < 0 ) + return( MBEDTLS_ERR_NET_INVALID_CONTEXT ); + + FD_ZERO( &read_fds ); + FD_SET( fd, &read_fds ); + + tv.tv_sec = timeout / 1000; + tv.tv_usec = ( timeout % 1000 ) * 1000; + + ret = select( fd + 1, &read_fds, NULL, NULL, timeout == 0 ? NULL : &tv ); + + /* Zero fds ready means we timed out */ + if( ret == 0 ) + return( MBEDTLS_ERR_SSL_TIMEOUT ); + + if( ret < 0 ) + { +#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ + !defined(EFI32) + if( WSAGetLastError() == WSAEINTR ) + return( MBEDTLS_ERR_SSL_WANT_READ ); +#else + if( errno == EINTR ) + return( MBEDTLS_ERR_SSL_WANT_READ ); +#endif + + return( MBEDTLS_ERR_NET_RECV_FAILED ); + } + + /* This call will not block */ + return( mbedtls_net_recv( ctx, buf, len ) ); +} + +/* + * Write at most 'len' characters + */ +int mbedtls_net_send( void *ctx, const unsigned char *buf, size_t len ) +{ + int ret; + int fd = ((mbedtls_net_context *) ctx)->fd; + + if( fd < 0 ) + return( MBEDTLS_ERR_NET_INVALID_CONTEXT ); + + errno = 0; + ret = (int) write( fd, buf, len ); + + if( ret < 0 ) + { + if( net_would_block( ctx ) != 0 ) + return( MBEDTLS_ERR_SSL_WANT_WRITE ); + +#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \ + !defined(EFI32) + if( WSAGetLastError() == WSAECONNRESET ) + return( MBEDTLS_ERR_NET_CONN_RESET ); +#else + if( errno == EPIPE || errno == ECONNRESET ) + return( MBEDTLS_ERR_NET_CONN_RESET ); + + if( errno == EINTR ) + return( MBEDTLS_ERR_SSL_WANT_WRITE ); +#endif + + return( MBEDTLS_ERR_NET_SEND_FAILED ); + } + + return( ret ); +} + +/* + * Gracefully close the connection + */ +void mbedtls_net_free( mbedtls_net_context *ctx ) +{ + if( ctx->fd == -1 ) + return; + + shutdown( ctx->fd, 2 ); + close( ctx->fd ); + + ctx->fd = -1; +} + +#endif /* MBEDTLS_NET_C */ + +#endif /* MBEDTLS_NET_ALT */ diff --git a/security/mbedtls/src/oid.c b/security/mbedtls/src/oid.c new file mode 100644 index 0000000000..f13826ed74 --- /dev/null +++ b/security/mbedtls/src/oid.c @@ -0,0 +1,710 @@ +/** + * \file oid.c + * + * \brief Object Identifier (OID) database + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_OID_C) + +#include "mbedtls/oid.h" +#include "mbedtls/rsa.h" + +#include +#include + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#define mbedtls_snprintf snprintf +#endif + +#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C) +#include "mbedtls/x509.h" +#endif + +/* + * Macro to automatically add the size of #define'd OIDs + */ +#define ADD_LEN(s) s, MBEDTLS_OID_SIZE(s) + +/* + * Macro to generate an internal function for oid_XXX_from_asn1() (used by + * the other functions) + */ +#define FN_OID_TYPED_FROM_ASN1( TYPE_T, NAME, LIST ) \ +static const TYPE_T * oid_ ## NAME ## _from_asn1( const mbedtls_asn1_buf *oid ) \ +{ \ + const TYPE_T *p = LIST; \ + const mbedtls_oid_descriptor_t *cur = (const mbedtls_oid_descriptor_t *) p; \ + if( p == NULL || oid == NULL ) return( NULL ); \ + while( cur->asn1 != NULL ) { \ + if( cur->asn1_len == oid->len && \ + memcmp( cur->asn1, oid->p, oid->len ) == 0 ) { \ + return( p ); \ + } \ + p++; \ + cur = (const mbedtls_oid_descriptor_t *) p; \ + } \ + return( NULL ); \ +} + +/* + * Macro to generate a function for retrieving a single attribute from the + * descriptor of an mbedtls_oid_descriptor_t wrapper. + */ +#define FN_OID_GET_DESCRIPTOR_ATTR1(FN_NAME, TYPE_T, TYPE_NAME, ATTR1_TYPE, ATTR1) \ +int FN_NAME( const mbedtls_asn1_buf *oid, ATTR1_TYPE * ATTR1 ) \ +{ \ + const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1( oid ); \ + if( data == NULL ) return( MBEDTLS_ERR_OID_NOT_FOUND ); \ + *ATTR1 = data->descriptor.ATTR1; \ + return( 0 ); \ +} + +/* + * Macro to generate a function for retrieving a single attribute from an + * mbedtls_oid_descriptor_t wrapper. + */ +#define FN_OID_GET_ATTR1(FN_NAME, TYPE_T, TYPE_NAME, ATTR1_TYPE, ATTR1) \ +int FN_NAME( const mbedtls_asn1_buf *oid, ATTR1_TYPE * ATTR1 ) \ +{ \ + const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1( oid ); \ + if( data == NULL ) return( MBEDTLS_ERR_OID_NOT_FOUND ); \ + *ATTR1 = data->ATTR1; \ + return( 0 ); \ +} + +/* + * Macro to generate a function for retrieving two attributes from an + * mbedtls_oid_descriptor_t wrapper. + */ +#define FN_OID_GET_ATTR2(FN_NAME, TYPE_T, TYPE_NAME, ATTR1_TYPE, ATTR1, \ + ATTR2_TYPE, ATTR2) \ +int FN_NAME( const mbedtls_asn1_buf *oid, ATTR1_TYPE * ATTR1, ATTR2_TYPE * ATTR2 ) \ +{ \ + const TYPE_T *data = oid_ ## TYPE_NAME ## _from_asn1( oid ); \ + if( data == NULL ) return( MBEDTLS_ERR_OID_NOT_FOUND ); \ + *ATTR1 = data->ATTR1; \ + *ATTR2 = data->ATTR2; \ + return( 0 ); \ +} + +/* + * Macro to generate a function for retrieving the OID based on a single + * attribute from a mbedtls_oid_descriptor_t wrapper. + */ +#define FN_OID_GET_OID_BY_ATTR1(FN_NAME, TYPE_T, LIST, ATTR1_TYPE, ATTR1) \ +int FN_NAME( ATTR1_TYPE ATTR1, const char **oid, size_t *olen ) \ +{ \ + const TYPE_T *cur = LIST; \ + while( cur->descriptor.asn1 != NULL ) { \ + if( cur->ATTR1 == ATTR1 ) { \ + *oid = cur->descriptor.asn1; \ + *olen = cur->descriptor.asn1_len; \ + return( 0 ); \ + } \ + cur++; \ + } \ + return( MBEDTLS_ERR_OID_NOT_FOUND ); \ +} + +/* + * Macro to generate a function for retrieving the OID based on two + * attributes from a mbedtls_oid_descriptor_t wrapper. + */ +#define FN_OID_GET_OID_BY_ATTR2(FN_NAME, TYPE_T, LIST, ATTR1_TYPE, ATTR1, \ + ATTR2_TYPE, ATTR2) \ +int FN_NAME( ATTR1_TYPE ATTR1, ATTR2_TYPE ATTR2, const char **oid , \ + size_t *olen ) \ +{ \ + const TYPE_T *cur = LIST; \ + while( cur->descriptor.asn1 != NULL ) { \ + if( cur->ATTR1 == ATTR1 && cur->ATTR2 == ATTR2 ) { \ + *oid = cur->descriptor.asn1; \ + *olen = cur->descriptor.asn1_len; \ + return( 0 ); \ + } \ + cur++; \ + } \ + return( MBEDTLS_ERR_OID_NOT_FOUND ); \ +} + +#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C) +/* + * For X520 attribute types + */ +typedef struct { + mbedtls_oid_descriptor_t descriptor; + const char *short_name; +} oid_x520_attr_t; + +static const oid_x520_attr_t oid_x520_attr_type[] = +{ + { + { ADD_LEN( MBEDTLS_OID_AT_CN ), "id-at-commonName", "Common Name" }, + "CN", + }, + { + { ADD_LEN( MBEDTLS_OID_AT_COUNTRY ), "id-at-countryName", "Country" }, + "C", + }, + { + { ADD_LEN( MBEDTLS_OID_AT_LOCALITY ), "id-at-locality", "Locality" }, + "L", + }, + { + { ADD_LEN( MBEDTLS_OID_AT_STATE ), "id-at-state", "State" }, + "ST", + }, + { + { ADD_LEN( MBEDTLS_OID_AT_ORGANIZATION ),"id-at-organizationName", "Organization" }, + "O", + }, + { + { ADD_LEN( MBEDTLS_OID_AT_ORG_UNIT ), "id-at-organizationalUnitName", "Org Unit" }, + "OU", + }, + { + { ADD_LEN( MBEDTLS_OID_PKCS9_EMAIL ), "emailAddress", "E-mail address" }, + "emailAddress", + }, + { + { ADD_LEN( MBEDTLS_OID_AT_SERIAL_NUMBER ),"id-at-serialNumber", "Serial number" }, + "serialNumber", + }, + { + { ADD_LEN( MBEDTLS_OID_AT_POSTAL_ADDRESS ),"id-at-postalAddress", "Postal address" }, + "postalAddress", + }, + { + { ADD_LEN( MBEDTLS_OID_AT_POSTAL_CODE ), "id-at-postalCode", "Postal code" }, + "postalCode", + }, + { + { ADD_LEN( MBEDTLS_OID_AT_SUR_NAME ), "id-at-surName", "Surname" }, + "SN", + }, + { + { ADD_LEN( MBEDTLS_OID_AT_GIVEN_NAME ), "id-at-givenName", "Given name" }, + "GN", + }, + { + { ADD_LEN( MBEDTLS_OID_AT_INITIALS ), "id-at-initials", "Initials" }, + "initials", + }, + { + { ADD_LEN( MBEDTLS_OID_AT_GENERATION_QUALIFIER ), "id-at-generationQualifier", "Generation qualifier" }, + "generationQualifier", + }, + { + { ADD_LEN( MBEDTLS_OID_AT_TITLE ), "id-at-title", "Title" }, + "title", + }, + { + { ADD_LEN( MBEDTLS_OID_AT_DN_QUALIFIER ),"id-at-dnQualifier", "Distinguished Name qualifier" }, + "dnQualifier", + }, + { + { ADD_LEN( MBEDTLS_OID_AT_PSEUDONYM ), "id-at-pseudonym", "Pseudonym" }, + "pseudonym", + }, + { + { ADD_LEN( MBEDTLS_OID_DOMAIN_COMPONENT ), "id-domainComponent", "Domain component" }, + "DC", + }, + { + { ADD_LEN( MBEDTLS_OID_AT_UNIQUE_IDENTIFIER ), "id-at-uniqueIdentifier", "Unique Identifier" }, + "uniqueIdentifier", + }, + { + { NULL, 0, NULL, NULL }, + NULL, + } +}; + +FN_OID_TYPED_FROM_ASN1(oid_x520_attr_t, x520_attr, oid_x520_attr_type) +FN_OID_GET_ATTR1(mbedtls_oid_get_attr_short_name, oid_x520_attr_t, x520_attr, const char *, short_name) + +/* + * For X509 extensions + */ +typedef struct { + mbedtls_oid_descriptor_t descriptor; + int ext_type; +} oid_x509_ext_t; + +static const oid_x509_ext_t oid_x509_ext[] = +{ + { + { ADD_LEN( MBEDTLS_OID_BASIC_CONSTRAINTS ), "id-ce-basicConstraints", "Basic Constraints" }, + MBEDTLS_X509_EXT_BASIC_CONSTRAINTS, + }, + { + { ADD_LEN( MBEDTLS_OID_KEY_USAGE ), "id-ce-keyUsage", "Key Usage" }, + MBEDTLS_X509_EXT_KEY_USAGE, + }, + { + { ADD_LEN( MBEDTLS_OID_EXTENDED_KEY_USAGE ), "id-ce-extKeyUsage", "Extended Key Usage" }, + MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE, + }, + { + { ADD_LEN( MBEDTLS_OID_SUBJECT_ALT_NAME ), "id-ce-subjectAltName", "Subject Alt Name" }, + MBEDTLS_X509_EXT_SUBJECT_ALT_NAME, + }, + { + { ADD_LEN( MBEDTLS_OID_NS_CERT_TYPE ), "id-netscape-certtype", "Netscape Certificate Type" }, + MBEDTLS_X509_EXT_NS_CERT_TYPE, + }, + { + { NULL, 0, NULL, NULL }, + 0, + }, +}; + +FN_OID_TYPED_FROM_ASN1(oid_x509_ext_t, x509_ext, oid_x509_ext) +FN_OID_GET_ATTR1(mbedtls_oid_get_x509_ext_type, oid_x509_ext_t, x509_ext, int, ext_type) + +static const mbedtls_oid_descriptor_t oid_ext_key_usage[] = +{ + { ADD_LEN( MBEDTLS_OID_SERVER_AUTH ), "id-kp-serverAuth", "TLS Web Server Authentication" }, + { ADD_LEN( MBEDTLS_OID_CLIENT_AUTH ), "id-kp-clientAuth", "TLS Web Client Authentication" }, + { ADD_LEN( MBEDTLS_OID_CODE_SIGNING ), "id-kp-codeSigning", "Code Signing" }, + { ADD_LEN( MBEDTLS_OID_EMAIL_PROTECTION ), "id-kp-emailProtection", "E-mail Protection" }, + { ADD_LEN( MBEDTLS_OID_TIME_STAMPING ), "id-kp-timeStamping", "Time Stamping" }, + { ADD_LEN( MBEDTLS_OID_OCSP_SIGNING ), "id-kp-OCSPSigning", "OCSP Signing" }, + { NULL, 0, NULL, NULL }, +}; + +FN_OID_TYPED_FROM_ASN1(mbedtls_oid_descriptor_t, ext_key_usage, oid_ext_key_usage) +FN_OID_GET_ATTR1(mbedtls_oid_get_extended_key_usage, mbedtls_oid_descriptor_t, ext_key_usage, const char *, description) +#endif /* MBEDTLS_X509_USE_C || MBEDTLS_X509_CREATE_C */ + +#if defined(MBEDTLS_MD_C) +/* + * For SignatureAlgorithmIdentifier + */ +typedef struct { + mbedtls_oid_descriptor_t descriptor; + mbedtls_md_type_t md_alg; + mbedtls_pk_type_t pk_alg; +} oid_sig_alg_t; + +static const oid_sig_alg_t oid_sig_alg[] = +{ +#if defined(MBEDTLS_RSA_C) +#if defined(MBEDTLS_MD2_C) + { + { ADD_LEN( MBEDTLS_OID_PKCS1_MD2 ), "md2WithRSAEncryption", "RSA with MD2" }, + MBEDTLS_MD_MD2, MBEDTLS_PK_RSA, + }, +#endif /* MBEDTLS_MD2_C */ +#if defined(MBEDTLS_MD4_C) + { + { ADD_LEN( MBEDTLS_OID_PKCS1_MD4 ), "md4WithRSAEncryption", "RSA with MD4" }, + MBEDTLS_MD_MD4, MBEDTLS_PK_RSA, + }, +#endif /* MBEDTLS_MD4_C */ +#if defined(MBEDTLS_MD5_C) + { + { ADD_LEN( MBEDTLS_OID_PKCS1_MD5 ), "md5WithRSAEncryption", "RSA with MD5" }, + MBEDTLS_MD_MD5, MBEDTLS_PK_RSA, + }, +#endif /* MBEDTLS_MD5_C */ +#if defined(MBEDTLS_SHA1_C) + { + { ADD_LEN( MBEDTLS_OID_PKCS1_SHA1 ), "sha-1WithRSAEncryption", "RSA with SHA1" }, + MBEDTLS_MD_SHA1, MBEDTLS_PK_RSA, + }, +#endif /* MBEDTLS_SHA1_C */ +#if defined(MBEDTLS_SHA256_C) + { + { ADD_LEN( MBEDTLS_OID_PKCS1_SHA224 ), "sha224WithRSAEncryption", "RSA with SHA-224" }, + MBEDTLS_MD_SHA224, MBEDTLS_PK_RSA, + }, + { + { ADD_LEN( MBEDTLS_OID_PKCS1_SHA256 ), "sha256WithRSAEncryption", "RSA with SHA-256" }, + MBEDTLS_MD_SHA256, MBEDTLS_PK_RSA, + }, +#endif /* MBEDTLS_SHA256_C */ +#if defined(MBEDTLS_SHA512_C) + { + { ADD_LEN( MBEDTLS_OID_PKCS1_SHA384 ), "sha384WithRSAEncryption", "RSA with SHA-384" }, + MBEDTLS_MD_SHA384, MBEDTLS_PK_RSA, + }, + { + { ADD_LEN( MBEDTLS_OID_PKCS1_SHA512 ), "sha512WithRSAEncryption", "RSA with SHA-512" }, + MBEDTLS_MD_SHA512, MBEDTLS_PK_RSA, + }, +#endif /* MBEDTLS_SHA512_C */ +#if defined(MBEDTLS_SHA1_C) + { + { ADD_LEN( MBEDTLS_OID_RSA_SHA_OBS ), "sha-1WithRSAEncryption", "RSA with SHA1" }, + MBEDTLS_MD_SHA1, MBEDTLS_PK_RSA, + }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_RSA_C */ +#if defined(MBEDTLS_ECDSA_C) +#if defined(MBEDTLS_SHA1_C) + { + { ADD_LEN( MBEDTLS_OID_ECDSA_SHA1 ), "ecdsa-with-SHA1", "ECDSA with SHA1" }, + MBEDTLS_MD_SHA1, MBEDTLS_PK_ECDSA, + }, +#endif /* MBEDTLS_SHA1_C */ +#if defined(MBEDTLS_SHA256_C) + { + { ADD_LEN( MBEDTLS_OID_ECDSA_SHA224 ), "ecdsa-with-SHA224", "ECDSA with SHA224" }, + MBEDTLS_MD_SHA224, MBEDTLS_PK_ECDSA, + }, + { + { ADD_LEN( MBEDTLS_OID_ECDSA_SHA256 ), "ecdsa-with-SHA256", "ECDSA with SHA256" }, + MBEDTLS_MD_SHA256, MBEDTLS_PK_ECDSA, + }, +#endif /* MBEDTLS_SHA256_C */ +#if defined(MBEDTLS_SHA512_C) + { + { ADD_LEN( MBEDTLS_OID_ECDSA_SHA384 ), "ecdsa-with-SHA384", "ECDSA with SHA384" }, + MBEDTLS_MD_SHA384, MBEDTLS_PK_ECDSA, + }, + { + { ADD_LEN( MBEDTLS_OID_ECDSA_SHA512 ), "ecdsa-with-SHA512", "ECDSA with SHA512" }, + MBEDTLS_MD_SHA512, MBEDTLS_PK_ECDSA, + }, +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_ECDSA_C */ +#if defined(MBEDTLS_RSA_C) + { + { ADD_LEN( MBEDTLS_OID_RSASSA_PSS ), "RSASSA-PSS", "RSASSA-PSS" }, + MBEDTLS_MD_NONE, MBEDTLS_PK_RSASSA_PSS, + }, +#endif /* MBEDTLS_RSA_C */ + { + { NULL, 0, NULL, NULL }, + MBEDTLS_MD_NONE, MBEDTLS_PK_NONE, + }, +}; + +FN_OID_TYPED_FROM_ASN1(oid_sig_alg_t, sig_alg, oid_sig_alg) +FN_OID_GET_DESCRIPTOR_ATTR1(mbedtls_oid_get_sig_alg_desc, oid_sig_alg_t, sig_alg, const char *, description) +FN_OID_GET_ATTR2(mbedtls_oid_get_sig_alg, oid_sig_alg_t, sig_alg, mbedtls_md_type_t, md_alg, mbedtls_pk_type_t, pk_alg) +FN_OID_GET_OID_BY_ATTR2(mbedtls_oid_get_oid_by_sig_alg, oid_sig_alg_t, oid_sig_alg, mbedtls_pk_type_t, pk_alg, mbedtls_md_type_t, md_alg) +#endif /* MBEDTLS_MD_C */ + +/* + * For PublicKeyInfo (PKCS1, RFC 5480) + */ +typedef struct { + mbedtls_oid_descriptor_t descriptor; + mbedtls_pk_type_t pk_alg; +} oid_pk_alg_t; + +static const oid_pk_alg_t oid_pk_alg[] = +{ + { + { ADD_LEN( MBEDTLS_OID_PKCS1_RSA ), "rsaEncryption", "RSA" }, + MBEDTLS_PK_RSA, + }, + { + { ADD_LEN( MBEDTLS_OID_EC_ALG_UNRESTRICTED ), "id-ecPublicKey", "Generic EC key" }, + MBEDTLS_PK_ECKEY, + }, + { + { ADD_LEN( MBEDTLS_OID_EC_ALG_ECDH ), "id-ecDH", "EC key for ECDH" }, + MBEDTLS_PK_ECKEY_DH, + }, + { + { NULL, 0, NULL, NULL }, + MBEDTLS_PK_NONE, + }, +}; + +FN_OID_TYPED_FROM_ASN1(oid_pk_alg_t, pk_alg, oid_pk_alg) +FN_OID_GET_ATTR1(mbedtls_oid_get_pk_alg, oid_pk_alg_t, pk_alg, mbedtls_pk_type_t, pk_alg) +FN_OID_GET_OID_BY_ATTR1(mbedtls_oid_get_oid_by_pk_alg, oid_pk_alg_t, oid_pk_alg, mbedtls_pk_type_t, pk_alg) + +#if defined(MBEDTLS_ECP_C) +/* + * For namedCurve (RFC 5480) + */ +typedef struct { + mbedtls_oid_descriptor_t descriptor; + mbedtls_ecp_group_id grp_id; +} oid_ecp_grp_t; + +static const oid_ecp_grp_t oid_ecp_grp[] = +{ +#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) + { + { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP192R1 ), "secp192r1", "secp192r1" }, + MBEDTLS_ECP_DP_SECP192R1, + }, +#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) + { + { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP224R1 ), "secp224r1", "secp224r1" }, + MBEDTLS_ECP_DP_SECP224R1, + }, +#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) + { + { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP256R1 ), "secp256r1", "secp256r1" }, + MBEDTLS_ECP_DP_SECP256R1, + }, +#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) + { + { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP384R1 ), "secp384r1", "secp384r1" }, + MBEDTLS_ECP_DP_SECP384R1, + }, +#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) + { + { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP521R1 ), "secp521r1", "secp521r1" }, + MBEDTLS_ECP_DP_SECP521R1, + }, +#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) + { + { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP192K1 ), "secp192k1", "secp192k1" }, + MBEDTLS_ECP_DP_SECP192K1, + }, +#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) + { + { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP224K1 ), "secp224k1", "secp224k1" }, + MBEDTLS_ECP_DP_SECP224K1, + }, +#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) + { + { ADD_LEN( MBEDTLS_OID_EC_GRP_SECP256K1 ), "secp256k1", "secp256k1" }, + MBEDTLS_ECP_DP_SECP256K1, + }, +#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) + { + { ADD_LEN( MBEDTLS_OID_EC_GRP_BP256R1 ), "brainpoolP256r1","brainpool256r1" }, + MBEDTLS_ECP_DP_BP256R1, + }, +#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) + { + { ADD_LEN( MBEDTLS_OID_EC_GRP_BP384R1 ), "brainpoolP384r1","brainpool384r1" }, + MBEDTLS_ECP_DP_BP384R1, + }, +#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) + { + { ADD_LEN( MBEDTLS_OID_EC_GRP_BP512R1 ), "brainpoolP512r1","brainpool512r1" }, + MBEDTLS_ECP_DP_BP512R1, + }, +#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */ + { + { NULL, 0, NULL, NULL }, + MBEDTLS_ECP_DP_NONE, + }, +}; + +FN_OID_TYPED_FROM_ASN1(oid_ecp_grp_t, grp_id, oid_ecp_grp) +FN_OID_GET_ATTR1(mbedtls_oid_get_ec_grp, oid_ecp_grp_t, grp_id, mbedtls_ecp_group_id, grp_id) +FN_OID_GET_OID_BY_ATTR1(mbedtls_oid_get_oid_by_ec_grp, oid_ecp_grp_t, oid_ecp_grp, mbedtls_ecp_group_id, grp_id) +#endif /* MBEDTLS_ECP_C */ + +#if defined(MBEDTLS_CIPHER_C) +/* + * For PKCS#5 PBES2 encryption algorithm + */ +typedef struct { + mbedtls_oid_descriptor_t descriptor; + mbedtls_cipher_type_t cipher_alg; +} oid_cipher_alg_t; + +static const oid_cipher_alg_t oid_cipher_alg[] = +{ + { + { ADD_LEN( MBEDTLS_OID_DES_CBC ), "desCBC", "DES-CBC" }, + MBEDTLS_CIPHER_DES_CBC, + }, + { + { ADD_LEN( MBEDTLS_OID_DES_EDE3_CBC ), "des-ede3-cbc", "DES-EDE3-CBC" }, + MBEDTLS_CIPHER_DES_EDE3_CBC, + }, + { + { NULL, 0, NULL, NULL }, + MBEDTLS_CIPHER_NONE, + }, +}; + +FN_OID_TYPED_FROM_ASN1(oid_cipher_alg_t, cipher_alg, oid_cipher_alg) +FN_OID_GET_ATTR1(mbedtls_oid_get_cipher_alg, oid_cipher_alg_t, cipher_alg, mbedtls_cipher_type_t, cipher_alg) +#endif /* MBEDTLS_CIPHER_C */ + +#if defined(MBEDTLS_MD_C) +/* + * For digestAlgorithm + */ +typedef struct { + mbedtls_oid_descriptor_t descriptor; + mbedtls_md_type_t md_alg; +} oid_md_alg_t; + +static const oid_md_alg_t oid_md_alg[] = +{ +#if defined(MBEDTLS_MD2_C) + { + { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_MD2 ), "id-md2", "MD2" }, + MBEDTLS_MD_MD2, + }, +#endif /* MBEDTLS_MD2_C */ +#if defined(MBEDTLS_MD4_C) + { + { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_MD4 ), "id-md4", "MD4" }, + MBEDTLS_MD_MD4, + }, +#endif /* MBEDTLS_MD4_C */ +#if defined(MBEDTLS_MD5_C) + { + { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_MD5 ), "id-md5", "MD5" }, + MBEDTLS_MD_MD5, + }, +#endif /* MBEDTLS_MD5_C */ +#if defined(MBEDTLS_SHA1_C) + { + { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA1 ), "id-sha1", "SHA-1" }, + MBEDTLS_MD_SHA1, + }, +#endif /* MBEDTLS_SHA1_C */ +#if defined(MBEDTLS_SHA256_C) + { + { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA224 ), "id-sha224", "SHA-224" }, + MBEDTLS_MD_SHA224, + }, + { + { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA256 ), "id-sha256", "SHA-256" }, + MBEDTLS_MD_SHA256, + }, +#endif /* MBEDTLS_SHA256_C */ +#if defined(MBEDTLS_SHA512_C) + { + { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA384 ), "id-sha384", "SHA-384" }, + MBEDTLS_MD_SHA384, + }, + { + { ADD_LEN( MBEDTLS_OID_DIGEST_ALG_SHA512 ), "id-sha512", "SHA-512" }, + MBEDTLS_MD_SHA512, + }, +#endif /* MBEDTLS_SHA512_C */ + { + { NULL, 0, NULL, NULL }, + MBEDTLS_MD_NONE, + }, +}; + +FN_OID_TYPED_FROM_ASN1(oid_md_alg_t, md_alg, oid_md_alg) +FN_OID_GET_ATTR1(mbedtls_oid_get_md_alg, oid_md_alg_t, md_alg, mbedtls_md_type_t, md_alg) +FN_OID_GET_OID_BY_ATTR1(mbedtls_oid_get_oid_by_md, oid_md_alg_t, oid_md_alg, mbedtls_md_type_t, md_alg) +#endif /* MBEDTLS_MD_C */ + +#if defined(MBEDTLS_PKCS12_C) +/* + * For PKCS#12 PBEs + */ +typedef struct { + mbedtls_oid_descriptor_t descriptor; + mbedtls_md_type_t md_alg; + mbedtls_cipher_type_t cipher_alg; +} oid_pkcs12_pbe_alg_t; + +static const oid_pkcs12_pbe_alg_t oid_pkcs12_pbe_alg[] = +{ + { + { ADD_LEN( MBEDTLS_OID_PKCS12_PBE_SHA1_DES3_EDE_CBC ), "pbeWithSHAAnd3-KeyTripleDES-CBC", "PBE with SHA1 and 3-Key 3DES" }, + MBEDTLS_MD_SHA1, MBEDTLS_CIPHER_DES_EDE3_CBC, + }, + { + { ADD_LEN( MBEDTLS_OID_PKCS12_PBE_SHA1_DES2_EDE_CBC ), "pbeWithSHAAnd2-KeyTripleDES-CBC", "PBE with SHA1 and 2-Key 3DES" }, + MBEDTLS_MD_SHA1, MBEDTLS_CIPHER_DES_EDE_CBC, + }, + { + { NULL, 0, NULL, NULL }, + MBEDTLS_MD_NONE, MBEDTLS_CIPHER_NONE, + }, +}; + +FN_OID_TYPED_FROM_ASN1(oid_pkcs12_pbe_alg_t, pkcs12_pbe_alg, oid_pkcs12_pbe_alg) +FN_OID_GET_ATTR2(mbedtls_oid_get_pkcs12_pbe_alg, oid_pkcs12_pbe_alg_t, pkcs12_pbe_alg, mbedtls_md_type_t, md_alg, mbedtls_cipher_type_t, cipher_alg) +#endif /* MBEDTLS_PKCS12_C */ + +#define OID_SAFE_SNPRINTF \ + do { \ + if( ret < 0 || (size_t) ret >= n ) \ + return( MBEDTLS_ERR_OID_BUF_TOO_SMALL ); \ + \ + n -= (size_t) ret; \ + p += (size_t) ret; \ + } while( 0 ) + +/* Return the x.y.z.... style numeric string for the given OID */ +int mbedtls_oid_get_numeric_string( char *buf, size_t size, + const mbedtls_asn1_buf *oid ) +{ + int ret; + size_t i, n; + unsigned int value; + char *p; + + p = buf; + n = size; + + /* First byte contains first two dots */ + if( oid->len > 0 ) + { + ret = mbedtls_snprintf( p, n, "%d.%d", oid->p[0] / 40, oid->p[0] % 40 ); + OID_SAFE_SNPRINTF; + } + + value = 0; + for( i = 1; i < oid->len; i++ ) + { + /* Prevent overflow in value. */ + if( ( ( value << 7 ) >> 7 ) != value ) + return( MBEDTLS_ERR_OID_BUF_TOO_SMALL ); + + value <<= 7; + value += oid->p[i] & 0x7F; + + if( !( oid->p[i] & 0x80 ) ) + { + /* Last byte */ + ret = mbedtls_snprintf( p, n, ".%d", value ); + OID_SAFE_SNPRINTF; + value = 0; + } + } + + return( (int) ( size - n ) ); +} + +#endif /* MBEDTLS_OID_C */ diff --git a/security/mbedtls/src/padlock.c b/security/mbedtls/src/padlock.c new file mode 100644 index 0000000000..b85ff9cd2c --- /dev/null +++ b/security/mbedtls/src/padlock.c @@ -0,0 +1,170 @@ +/* + * VIA PadLock support functions + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +/* + * This implementation is based on the VIA PadLock Programming Guide: + * + * http://www.via.com.tw/en/downloads/whitepapers/initiatives/padlock/ + * programming_guide.pdf + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_PADLOCK_C) + +#include "mbedtls/padlock.h" + +#include + +#ifndef asm +#define asm __asm +#endif + +#if defined(MBEDTLS_HAVE_X86) + +/* + * PadLock detection routine + */ +int mbedtls_padlock_has_support( int feature ) +{ + static int flags = -1; + int ebx = 0, edx = 0; + + if( flags == -1 ) + { + asm( "movl %%ebx, %0 \n\t" + "movl $0xC0000000, %%eax \n\t" + "cpuid \n\t" + "cmpl $0xC0000001, %%eax \n\t" + "movl $0, %%edx \n\t" + "jb unsupported \n\t" + "movl $0xC0000001, %%eax \n\t" + "cpuid \n\t" + "unsupported: \n\t" + "movl %%edx, %1 \n\t" + "movl %2, %%ebx \n\t" + : "=m" (ebx), "=m" (edx) + : "m" (ebx) + : "eax", "ecx", "edx" ); + + flags = edx; + } + + return( flags & feature ); +} + +/* + * PadLock AES-ECB block en(de)cryption + */ +int mbedtls_padlock_xcryptecb( mbedtls_aes_context *ctx, + int mode, + const unsigned char input[16], + unsigned char output[16] ) +{ + int ebx = 0; + uint32_t *rk; + uint32_t *blk; + uint32_t *ctrl; + unsigned char buf[256]; + + rk = ctx->rk; + blk = MBEDTLS_PADLOCK_ALIGN16( buf ); + memcpy( blk, input, 16 ); + + ctrl = blk + 4; + *ctrl = 0x80 | ctx->nr | ( ( ctx->nr + ( mode^1 ) - 10 ) << 9 ); + + asm( "pushfl \n\t" + "popfl \n\t" + "movl %%ebx, %0 \n\t" + "movl $1, %%ecx \n\t" + "movl %2, %%edx \n\t" + "movl %3, %%ebx \n\t" + "movl %4, %%esi \n\t" + "movl %4, %%edi \n\t" + ".byte 0xf3,0x0f,0xa7,0xc8 \n\t" + "movl %1, %%ebx \n\t" + : "=m" (ebx) + : "m" (ebx), "m" (ctrl), "m" (rk), "m" (blk) + : "memory", "ecx", "edx", "esi", "edi" ); + + memcpy( output, blk, 16 ); + + return( 0 ); +} + +/* + * PadLock AES-CBC buffer en(de)cryption + */ +int mbedtls_padlock_xcryptcbc( mbedtls_aes_context *ctx, + int mode, + size_t length, + unsigned char iv[16], + const unsigned char *input, + unsigned char *output ) +{ + int ebx = 0; + size_t count; + uint32_t *rk; + uint32_t *iw; + uint32_t *ctrl; + unsigned char buf[256]; + + if( ( (long) input & 15 ) != 0 || + ( (long) output & 15 ) != 0 ) + return( MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED ); + + rk = ctx->rk; + iw = MBEDTLS_PADLOCK_ALIGN16( buf ); + memcpy( iw, iv, 16 ); + + ctrl = iw + 4; + *ctrl = 0x80 | ctx->nr | ( ( ctx->nr + ( mode ^ 1 ) - 10 ) << 9 ); + + count = ( length + 15 ) >> 4; + + asm( "pushfl \n\t" + "popfl \n\t" + "movl %%ebx, %0 \n\t" + "movl %2, %%ecx \n\t" + "movl %3, %%edx \n\t" + "movl %4, %%ebx \n\t" + "movl %5, %%esi \n\t" + "movl %6, %%edi \n\t" + "movl %7, %%eax \n\t" + ".byte 0xf3,0x0f,0xa7,0xd0 \n\t" + "movl %1, %%ebx \n\t" + : "=m" (ebx) + : "m" (ebx), "m" (count), "m" (ctrl), + "m" (rk), "m" (input), "m" (output), "m" (iw) + : "memory", "eax", "ecx", "edx", "esi", "edi" ); + + memcpy( iv, iw, 16 ); + + return( 0 ); +} + +#endif /* MBEDTLS_HAVE_X86 */ + +#endif /* MBEDTLS_PADLOCK_C */ diff --git a/security/mbedtls/src/pem.c b/security/mbedtls/src/pem.c new file mode 100644 index 0000000000..19e02c6b22 --- /dev/null +++ b/security/mbedtls/src/pem.c @@ -0,0 +1,462 @@ +/* + * Privacy Enhanced Mail (PEM) decoding + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_PEM_PARSE_C) || defined(MBEDTLS_PEM_WRITE_C) + +#include "mbedtls/pem.h" +#include "mbedtls/base64.h" +#include "mbedtls/des.h" +#include "mbedtls/aes.h" +#include "mbedtls/md5.h" +#include "mbedtls/cipher.h" + +#include + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_calloc calloc +#define mbedtls_free free +#endif + +#if defined(MBEDTLS_PEM_PARSE_C) +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +void mbedtls_pem_init( mbedtls_pem_context *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_pem_context ) ); +} + +#if defined(MBEDTLS_MD5_C) && defined(MBEDTLS_CIPHER_MODE_CBC) && \ + ( defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C) ) +/* + * Read a 16-byte hex string and convert it to binary + */ +static int pem_get_iv( const unsigned char *s, unsigned char *iv, + size_t iv_len ) +{ + size_t i, j, k; + + memset( iv, 0, iv_len ); + + for( i = 0; i < iv_len * 2; i++, s++ ) + { + if( *s >= '0' && *s <= '9' ) j = *s - '0'; else + if( *s >= 'A' && *s <= 'F' ) j = *s - '7'; else + if( *s >= 'a' && *s <= 'f' ) j = *s - 'W'; else + return( MBEDTLS_ERR_PEM_INVALID_ENC_IV ); + + k = ( ( i & 1 ) != 0 ) ? j : j << 4; + + iv[i >> 1] = (unsigned char)( iv[i >> 1] | k ); + } + + return( 0 ); +} + +static void pem_pbkdf1( unsigned char *key, size_t keylen, + unsigned char *iv, + const unsigned char *pwd, size_t pwdlen ) +{ + mbedtls_md5_context md5_ctx; + unsigned char md5sum[16]; + size_t use_len; + + mbedtls_md5_init( &md5_ctx ); + + /* + * key[ 0..15] = MD5(pwd || IV) + */ + mbedtls_md5_starts( &md5_ctx ); + mbedtls_md5_update( &md5_ctx, pwd, pwdlen ); + mbedtls_md5_update( &md5_ctx, iv, 8 ); + mbedtls_md5_finish( &md5_ctx, md5sum ); + + if( keylen <= 16 ) + { + memcpy( key, md5sum, keylen ); + + mbedtls_md5_free( &md5_ctx ); + mbedtls_zeroize( md5sum, 16 ); + return; + } + + memcpy( key, md5sum, 16 ); + + /* + * key[16..23] = MD5(key[ 0..15] || pwd || IV]) + */ + mbedtls_md5_starts( &md5_ctx ); + mbedtls_md5_update( &md5_ctx, md5sum, 16 ); + mbedtls_md5_update( &md5_ctx, pwd, pwdlen ); + mbedtls_md5_update( &md5_ctx, iv, 8 ); + mbedtls_md5_finish( &md5_ctx, md5sum ); + + use_len = 16; + if( keylen < 32 ) + use_len = keylen - 16; + + memcpy( key + 16, md5sum, use_len ); + + mbedtls_md5_free( &md5_ctx ); + mbedtls_zeroize( md5sum, 16 ); +} + +#if defined(MBEDTLS_DES_C) +/* + * Decrypt with DES-CBC, using PBKDF1 for key derivation + */ +static void pem_des_decrypt( unsigned char des_iv[8], + unsigned char *buf, size_t buflen, + const unsigned char *pwd, size_t pwdlen ) +{ + mbedtls_des_context des_ctx; + unsigned char des_key[8]; + + mbedtls_des_init( &des_ctx ); + + pem_pbkdf1( des_key, 8, des_iv, pwd, pwdlen ); + + mbedtls_des_setkey_dec( &des_ctx, des_key ); + mbedtls_des_crypt_cbc( &des_ctx, MBEDTLS_DES_DECRYPT, buflen, + des_iv, buf, buf ); + + mbedtls_des_free( &des_ctx ); + mbedtls_zeroize( des_key, 8 ); +} + +/* + * Decrypt with 3DES-CBC, using PBKDF1 for key derivation + */ +static void pem_des3_decrypt( unsigned char des3_iv[8], + unsigned char *buf, size_t buflen, + const unsigned char *pwd, size_t pwdlen ) +{ + mbedtls_des3_context des3_ctx; + unsigned char des3_key[24]; + + mbedtls_des3_init( &des3_ctx ); + + pem_pbkdf1( des3_key, 24, des3_iv, pwd, pwdlen ); + + mbedtls_des3_set3key_dec( &des3_ctx, des3_key ); + mbedtls_des3_crypt_cbc( &des3_ctx, MBEDTLS_DES_DECRYPT, buflen, + des3_iv, buf, buf ); + + mbedtls_des3_free( &des3_ctx ); + mbedtls_zeroize( des3_key, 24 ); +} +#endif /* MBEDTLS_DES_C */ + +#if defined(MBEDTLS_AES_C) +/* + * Decrypt with AES-XXX-CBC, using PBKDF1 for key derivation + */ +static void pem_aes_decrypt( unsigned char aes_iv[16], unsigned int keylen, + unsigned char *buf, size_t buflen, + const unsigned char *pwd, size_t pwdlen ) +{ + mbedtls_aes_context aes_ctx; + unsigned char aes_key[32]; + +#if !defined(MBEDTLS_AES_ALT) + mbedtls_aes_init( &aes_ctx ); + + pem_pbkdf1( aes_key, keylen, aes_iv, pwd, pwdlen ); + + mbedtls_aes_setkey_dec( &aes_ctx, aes_key, keylen * 8 ); + mbedtls_aes_crypt_cbc( &aes_ctx, MBEDTLS_AES_DECRYPT, buflen, + aes_iv, buf, buf ); + + mbedtls_aes_free( &aes_ctx ); + mbedtls_zeroize( aes_key, keylen ); +#else + mbedtls_aes_init_alt( &aes_ctx ); + + pem_pbkdf1( aes_key, keylen, aes_iv, pwd, pwdlen ); + + mbedtls_aes_setkey_dec_alt( &aes_ctx, aes_key, keylen * 8 ); + mbedtls_aes_crypt_cbc_alt( &aes_ctx, MBEDTLS_AES_DECRYPT, buflen, + aes_iv, buf, buf ); + + mbedtls_aes_free_alt( &aes_ctx ); + mbedtls_zeroize( aes_key, keylen ); +#endif +} +#endif /* MBEDTLS_AES_C */ + +#endif /* MBEDTLS_MD5_C && MBEDTLS_CIPHER_MODE_CBC && + ( MBEDTLS_AES_C || MBEDTLS_DES_C ) */ + +int mbedtls_pem_read_buffer( mbedtls_pem_context *ctx, const char *header, const char *footer, + const unsigned char *data, const unsigned char *pwd, + size_t pwdlen, size_t *use_len ) +{ + int ret, enc; + size_t len; + unsigned char *buf; + const unsigned char *s1, *s2, *end; +#if defined(MBEDTLS_MD5_C) && defined(MBEDTLS_CIPHER_MODE_CBC) && \ + ( defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C) ) + unsigned char pem_iv[16]; + mbedtls_cipher_type_t enc_alg = MBEDTLS_CIPHER_NONE; +#else + ((void) pwd); + ((void) pwdlen); +#endif /* MBEDTLS_MD5_C && MBEDTLS_CIPHER_MODE_CBC && + ( MBEDTLS_AES_C || MBEDTLS_DES_C ) */ + + if( ctx == NULL ) + return( MBEDTLS_ERR_PEM_BAD_INPUT_DATA ); + + s1 = (unsigned char *) strstr( (const char *) data, header ); + + if( s1 == NULL ) + return( MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ); + + s2 = (unsigned char *) strstr( (const char *) data, footer ); + + if( s2 == NULL || s2 <= s1 ) + return( MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ); + + s1 += strlen( header ); + if( *s1 == ' ' ) s1++; + if( *s1 == '\r' ) s1++; + if( *s1 == '\n' ) s1++; + else return( MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ); + + end = s2; + end += strlen( footer ); + if( *end == ' ' ) end++; + if( *end == '\r' ) end++; + if( *end == '\n' ) end++; + *use_len = end - data; + + enc = 0; + + if( s2 - s1 >= 22 && memcmp( s1, "Proc-Type: 4,ENCRYPTED", 22 ) == 0 ) + { +#if defined(MBEDTLS_MD5_C) && defined(MBEDTLS_CIPHER_MODE_CBC) && \ + ( defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C) ) + enc++; + + s1 += 22; + if( *s1 == '\r' ) s1++; + if( *s1 == '\n' ) s1++; + else return( MBEDTLS_ERR_PEM_INVALID_DATA ); + + +#if defined(MBEDTLS_DES_C) + if( s2 - s1 >= 23 && memcmp( s1, "DEK-Info: DES-EDE3-CBC,", 23 ) == 0 ) + { + enc_alg = MBEDTLS_CIPHER_DES_EDE3_CBC; + + s1 += 23; + if( s2 - s1 < 16 || pem_get_iv( s1, pem_iv, 8 ) != 0 ) + return( MBEDTLS_ERR_PEM_INVALID_ENC_IV ); + + s1 += 16; + } + else if( s2 - s1 >= 18 && memcmp( s1, "DEK-Info: DES-CBC,", 18 ) == 0 ) + { + enc_alg = MBEDTLS_CIPHER_DES_CBC; + + s1 += 18; + if( s2 - s1 < 16 || pem_get_iv( s1, pem_iv, 8) != 0 ) + return( MBEDTLS_ERR_PEM_INVALID_ENC_IV ); + + s1 += 16; + } +#endif /* MBEDTLS_DES_C */ + +#if defined(MBEDTLS_AES_C) + if( s2 - s1 >= 14 && memcmp( s1, "DEK-Info: AES-", 14 ) == 0 ) + { + if( s2 - s1 < 22 ) + return( MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG ); + else if( memcmp( s1, "DEK-Info: AES-128-CBC,", 22 ) == 0 ) + enc_alg = MBEDTLS_CIPHER_AES_128_CBC; + else if( memcmp( s1, "DEK-Info: AES-192-CBC,", 22 ) == 0 ) + enc_alg = MBEDTLS_CIPHER_AES_192_CBC; + else if( memcmp( s1, "DEK-Info: AES-256-CBC,", 22 ) == 0 ) + enc_alg = MBEDTLS_CIPHER_AES_256_CBC; + else + return( MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG ); + + s1 += 22; + if( s2 - s1 < 32 || pem_get_iv( s1, pem_iv, 16 ) != 0 ) + return( MBEDTLS_ERR_PEM_INVALID_ENC_IV ); + + s1 += 32; + } +#endif /* MBEDTLS_AES_C */ + + if( enc_alg == MBEDTLS_CIPHER_NONE ) + return( MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG ); + + if( *s1 == '\r' ) s1++; + if( *s1 == '\n' ) s1++; + else return( MBEDTLS_ERR_PEM_INVALID_DATA ); +#else + return( MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE ); +#endif /* MBEDTLS_MD5_C && MBEDTLS_CIPHER_MODE_CBC && + ( MBEDTLS_AES_C || MBEDTLS_DES_C ) */ + } + + if( s1 >= s2 ) + return( MBEDTLS_ERR_PEM_INVALID_DATA ); + + ret = mbedtls_base64_decode( NULL, 0, &len, s1, s2 - s1 ); + + if( ret == MBEDTLS_ERR_BASE64_INVALID_CHARACTER ) + return( MBEDTLS_ERR_PEM_INVALID_DATA + ret ); + + if( ( buf = mbedtls_calloc( 1, len ) ) == NULL ) + return( MBEDTLS_ERR_PEM_ALLOC_FAILED ); + + if( ( ret = mbedtls_base64_decode( buf, len, &len, s1, s2 - s1 ) ) != 0 ) + { + mbedtls_free( buf ); + return( MBEDTLS_ERR_PEM_INVALID_DATA + ret ); + } + + if( enc != 0 ) + { +#if defined(MBEDTLS_MD5_C) && defined(MBEDTLS_CIPHER_MODE_CBC) && \ + ( defined(MBEDTLS_DES_C) || defined(MBEDTLS_AES_C) ) + if( pwd == NULL ) + { + mbedtls_free( buf ); + return( MBEDTLS_ERR_PEM_PASSWORD_REQUIRED ); + } + +#if defined(MBEDTLS_DES_C) + if( enc_alg == MBEDTLS_CIPHER_DES_EDE3_CBC ) + pem_des3_decrypt( pem_iv, buf, len, pwd, pwdlen ); + else if( enc_alg == MBEDTLS_CIPHER_DES_CBC ) + pem_des_decrypt( pem_iv, buf, len, pwd, pwdlen ); +#endif /* MBEDTLS_DES_C */ + +#if defined(MBEDTLS_AES_C) + if( enc_alg == MBEDTLS_CIPHER_AES_128_CBC ) + pem_aes_decrypt( pem_iv, 16, buf, len, pwd, pwdlen ); + else if( enc_alg == MBEDTLS_CIPHER_AES_192_CBC ) + pem_aes_decrypt( pem_iv, 24, buf, len, pwd, pwdlen ); + else if( enc_alg == MBEDTLS_CIPHER_AES_256_CBC ) + pem_aes_decrypt( pem_iv, 32, buf, len, pwd, pwdlen ); +#endif /* MBEDTLS_AES_C */ + + /* + * The result will be ASN.1 starting with a SEQUENCE tag, with 1 to 3 + * length bytes (allow 4 to be sure) in all known use cases. + * + * Use that as heurisitic to try detecting password mismatchs. + */ + if( len <= 2 || buf[0] != 0x30 || buf[1] > 0x83 ) + { + mbedtls_free( buf ); + return( MBEDTLS_ERR_PEM_PASSWORD_MISMATCH ); + } +#else + mbedtls_free( buf ); + return( MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE ); +#endif /* MBEDTLS_MD5_C && MBEDTLS_CIPHER_MODE_CBC && + ( MBEDTLS_AES_C || MBEDTLS_DES_C ) */ + } + + ctx->buf = buf; + ctx->buflen = len; + + return( 0 ); +} + +void mbedtls_pem_free( mbedtls_pem_context *ctx ) +{ + mbedtls_free( ctx->buf ); + mbedtls_free( ctx->info ); + + mbedtls_zeroize( ctx, sizeof( mbedtls_pem_context ) ); +} +#endif /* MBEDTLS_PEM_PARSE_C */ + +#if defined(MBEDTLS_PEM_WRITE_C) +int mbedtls_pem_write_buffer( const char *header, const char *footer, + const unsigned char *der_data, size_t der_len, + unsigned char *buf, size_t buf_len, size_t *olen ) +{ + int ret; + unsigned char *encode_buf, *c, *p = buf; + size_t len = 0, use_len, add_len = 0; + + mbedtls_base64_encode( NULL, 0, &use_len, der_data, der_len ); + add_len = strlen( header ) + strlen( footer ) + ( use_len / 64 ) + 1; + + if( use_len + add_len > buf_len ) + { + *olen = use_len + add_len; + return( MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL ); + } + + if( ( encode_buf = mbedtls_calloc( 1, use_len ) ) == NULL ) + return( MBEDTLS_ERR_PEM_ALLOC_FAILED ); + + if( ( ret = mbedtls_base64_encode( encode_buf, use_len, &use_len, der_data, + der_len ) ) != 0 ) + { + mbedtls_free( encode_buf ); + return( ret ); + } + + memcpy( p, header, strlen( header ) ); + p += strlen( header ); + c = encode_buf; + + while( use_len ) + { + len = ( use_len > 64 ) ? 64 : use_len; + memcpy( p, c, len ); + use_len -= len; + p += len; + c += len; + *p++ = '\n'; + } + + memcpy( p, footer, strlen( footer ) ); + p += strlen( footer ); + + *p++ = '\0'; + *olen = p - buf; + + mbedtls_free( encode_buf ); + return( 0 ); +} +#endif /* MBEDTLS_PEM_WRITE_C */ +#endif /* MBEDTLS_PEM_PARSE_C || MBEDTLS_PEM_WRITE_C */ diff --git a/security/mbedtls/src/pk.c b/security/mbedtls/src/pk.c new file mode 100644 index 0000000000..8d13bc5ce3 --- /dev/null +++ b/security/mbedtls/src/pk.c @@ -0,0 +1,383 @@ +/* + * Public Key abstraction layer + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_PK_C) +#include "mbedtls/pk.h" +#include "mbedtls/pk_internal.h" + +#include "mbedtls/bignum.h" + +#if defined(MBEDTLS_RSA_C) +#include "mbedtls/rsa.h" +#endif +#if defined(MBEDTLS_ECP_C) +#include "mbedtls/ecp.h" +#endif +#if defined(MBEDTLS_ECDSA_C) +#include "mbedtls/ecdsa.h" +#endif + +#include + +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +/* + * Initialise a mbedtls_pk_context + */ +void mbedtls_pk_init( mbedtls_pk_context *ctx ) +{ + if( ctx == NULL ) + return; + + ctx->pk_info = NULL; + ctx->pk_ctx = NULL; +} + +/* + * Free (the components of) a mbedtls_pk_context + */ +void mbedtls_pk_free( mbedtls_pk_context *ctx ) +{ + if( ctx == NULL || ctx->pk_info == NULL ) + return; + + ctx->pk_info->ctx_free_func( ctx->pk_ctx ); + + mbedtls_zeroize( ctx, sizeof( mbedtls_pk_context ) ); +} + +/* + * Get pk_info structure from type + */ +const mbedtls_pk_info_t * mbedtls_pk_info_from_type( mbedtls_pk_type_t pk_type ) +{ + switch( pk_type ) { +#if defined(MBEDTLS_RSA_C) + case MBEDTLS_PK_RSA: + return( &mbedtls_rsa_info ); +#endif +#if defined(MBEDTLS_ECP_C) + case MBEDTLS_PK_ECKEY: + return( &mbedtls_eckey_info ); + case MBEDTLS_PK_ECKEY_DH: + return( &mbedtls_eckeydh_info ); +#endif +#if defined(MBEDTLS_ECDSA_C) + case MBEDTLS_PK_ECDSA: + return( &mbedtls_ecdsa_info ); +#endif + /* MBEDTLS_PK_RSA_ALT omitted on purpose */ + default: + return( NULL ); + } +} + +/* + * Initialise context + */ +int mbedtls_pk_setup( mbedtls_pk_context *ctx, const mbedtls_pk_info_t *info ) +{ + if( ctx == NULL || info == NULL || ctx->pk_info != NULL ) + return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); + + if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL ) + return( MBEDTLS_ERR_PK_ALLOC_FAILED ); + + ctx->pk_info = info; + + return( 0 ); +} + +#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) +/* + * Initialize an RSA-alt context + */ +int mbedtls_pk_setup_rsa_alt( mbedtls_pk_context *ctx, void * key, + mbedtls_pk_rsa_alt_decrypt_func decrypt_func, + mbedtls_pk_rsa_alt_sign_func sign_func, + mbedtls_pk_rsa_alt_key_len_func key_len_func ) +{ + mbedtls_rsa_alt_context *rsa_alt; + const mbedtls_pk_info_t *info = &mbedtls_rsa_alt_info; + + if( ctx == NULL || ctx->pk_info != NULL ) + return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); + + if( ( ctx->pk_ctx = info->ctx_alloc_func() ) == NULL ) + return( MBEDTLS_ERR_PK_ALLOC_FAILED ); + + ctx->pk_info = info; + + rsa_alt = (mbedtls_rsa_alt_context *) ctx->pk_ctx; + + rsa_alt->key = key; + rsa_alt->decrypt_func = decrypt_func; + rsa_alt->sign_func = sign_func; + rsa_alt->key_len_func = key_len_func; + + return( 0 ); +} +#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */ + +/* + * Tell if a PK can do the operations of the given type + */ +int mbedtls_pk_can_do( const mbedtls_pk_context *ctx, mbedtls_pk_type_t type ) +{ + /* null or NONE context can't do anything */ + if( ctx == NULL || ctx->pk_info == NULL ) + return( 0 ); + + return( ctx->pk_info->can_do( type ) ); +} + +/* + * Helper for mbedtls_pk_sign and mbedtls_pk_verify + */ +static inline int pk_hashlen_helper( mbedtls_md_type_t md_alg, size_t *hash_len ) +{ + const mbedtls_md_info_t *md_info; + + if( *hash_len != 0 ) + return( 0 ); + + if( ( md_info = mbedtls_md_info_from_type( md_alg ) ) == NULL ) + return( -1 ); + + *hash_len = mbedtls_md_get_size( md_info ); + return( 0 ); +} + +/* + * Verify a signature + */ +int mbedtls_pk_verify( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + const unsigned char *sig, size_t sig_len ) +{ + if( ctx == NULL || ctx->pk_info == NULL || + pk_hashlen_helper( md_alg, &hash_len ) != 0 ) + return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); + + if( ctx->pk_info->verify_func == NULL ) + return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); + + return( ctx->pk_info->verify_func( ctx->pk_ctx, md_alg, hash, hash_len, + sig, sig_len ) ); +} + +/* + * Verify a signature with options + */ +int mbedtls_pk_verify_ext( mbedtls_pk_type_t type, const void *options, + mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + const unsigned char *sig, size_t sig_len ) +{ + if( ctx == NULL || ctx->pk_info == NULL ) + return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); + + if( ! mbedtls_pk_can_do( ctx, type ) ) + return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); + + if( type == MBEDTLS_PK_RSASSA_PSS ) + { +#if defined(MBEDTLS_RSA_C) && defined(MBEDTLS_PKCS1_V21) + int ret; + const mbedtls_pk_rsassa_pss_options *pss_opts; + +#if defined(MBEDTLS_HAVE_INT64) + if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len ) + return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); +#endif /* MBEDTLS_HAVE_INT64 */ + + if( options == NULL ) + return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); + + pss_opts = (const mbedtls_pk_rsassa_pss_options *) options; + + if( sig_len < mbedtls_pk_get_len( ctx ) ) + return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); + + ret = mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_pk_rsa( *ctx ), + NULL, NULL, MBEDTLS_RSA_PUBLIC, + md_alg, (unsigned int) hash_len, hash, + pss_opts->mgf1_hash_id, + pss_opts->expected_salt_len, + sig ); + if( ret != 0 ) + return( ret ); + + if( sig_len > mbedtls_pk_get_len( ctx ) ) + return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH ); + + return( 0 ); +#else + return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); +#endif /* MBEDTLS_RSA_C && MBEDTLS_PKCS1_V21 */ + } + + /* General case: no options */ + if( options != NULL ) + return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); + + return( mbedtls_pk_verify( ctx, md_alg, hash, hash_len, sig, sig_len ) ); +} + +/* + * Make a signature + */ +int mbedtls_pk_sign( mbedtls_pk_context *ctx, mbedtls_md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + unsigned char *sig, size_t *sig_len, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + if( ctx == NULL || ctx->pk_info == NULL || + pk_hashlen_helper( md_alg, &hash_len ) != 0 ) + return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); + + if( ctx->pk_info->sign_func == NULL ) + return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); + + return( ctx->pk_info->sign_func( ctx->pk_ctx, md_alg, hash, hash_len, + sig, sig_len, f_rng, p_rng ) ); +} + +/* + * Decrypt message + */ +int mbedtls_pk_decrypt( mbedtls_pk_context *ctx, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, size_t osize, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + if( ctx == NULL || ctx->pk_info == NULL ) + return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); + + if( ctx->pk_info->decrypt_func == NULL ) + return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); + + return( ctx->pk_info->decrypt_func( ctx->pk_ctx, input, ilen, + output, olen, osize, f_rng, p_rng ) ); +} + +/* + * Encrypt message + */ +int mbedtls_pk_encrypt( mbedtls_pk_context *ctx, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, size_t osize, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + if( ctx == NULL || ctx->pk_info == NULL ) + return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); + + if( ctx->pk_info->encrypt_func == NULL ) + return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); + + return( ctx->pk_info->encrypt_func( ctx->pk_ctx, input, ilen, + output, olen, osize, f_rng, p_rng ) ); +} + +/* + * Check public-private key pair + */ +int mbedtls_pk_check_pair( const mbedtls_pk_context *pub, const mbedtls_pk_context *prv ) +{ + if( pub == NULL || pub->pk_info == NULL || + prv == NULL || prv->pk_info == NULL || + prv->pk_info->check_pair_func == NULL ) + { + return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); + } + + if( prv->pk_info->type == MBEDTLS_PK_RSA_ALT ) + { + if( pub->pk_info->type != MBEDTLS_PK_RSA ) + return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); + } + else + { + if( pub->pk_info != prv->pk_info ) + return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); + } + + return( prv->pk_info->check_pair_func( pub->pk_ctx, prv->pk_ctx ) ); +} + +/* + * Get key size in bits + */ +size_t mbedtls_pk_get_bitlen( const mbedtls_pk_context *ctx ) +{ + if( ctx == NULL || ctx->pk_info == NULL ) + return( 0 ); + + return( ctx->pk_info->get_bitlen( ctx->pk_ctx ) ); +} + +/* + * Export debug information + */ +int mbedtls_pk_debug( const mbedtls_pk_context *ctx, mbedtls_pk_debug_item *items ) +{ + if( ctx == NULL || ctx->pk_info == NULL ) + return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); + + if( ctx->pk_info->debug_func == NULL ) + return( MBEDTLS_ERR_PK_TYPE_MISMATCH ); + + ctx->pk_info->debug_func( ctx->pk_ctx, items ); + return( 0 ); +} + +/* + * Access the PK type name + */ +const char *mbedtls_pk_get_name( const mbedtls_pk_context *ctx ) +{ + if( ctx == NULL || ctx->pk_info == NULL ) + return( "invalid PK" ); + + return( ctx->pk_info->name ); +} + +/* + * Access the PK type + */ +mbedtls_pk_type_t mbedtls_pk_get_type( const mbedtls_pk_context *ctx ) +{ + if( ctx == NULL || ctx->pk_info == NULL ) + return( MBEDTLS_PK_NONE ); + + return( ctx->pk_info->type ); +} + +#endif /* MBEDTLS_PK_C */ diff --git a/security/mbedtls/src/pk_wrap.c b/security/mbedtls/src/pk_wrap.c new file mode 100644 index 0000000000..c11f30afcc --- /dev/null +++ b/security/mbedtls/src/pk_wrap.c @@ -0,0 +1,636 @@ +/* + * Public Key abstraction layer: wrapper functions + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_PK_C) +#include "mbedtls/pk_internal.h" + +/* Even if RSA not activated, for the sake of RSA-alt */ +#include "mbedtls/rsa.h" +#include "mbedtls/bignum.h" + +#include + +#if defined(MBEDTLS_ECP_C) +#include "mbedtls/ecp.h" +#endif + +#if defined(MBEDTLS_ECDSA_C) +#include "mbedtls/ecdsa.h" +#endif + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_calloc calloc +#define mbedtls_free free +#endif + +#include + +#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} +#endif + +#if !defined(MBEDTLS_PK_ALT) +#if defined(MBEDTLS_RSA_C) +static int rsa_can_do( mbedtls_pk_type_t type ) +{ + return( type == MBEDTLS_PK_RSA || + type == MBEDTLS_PK_RSASSA_PSS ); +} + +static size_t rsa_get_bitlen( const void *ctx ) +{ + return( 8 * ((const mbedtls_rsa_context *) ctx)->len ); +} + +static int rsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + const unsigned char *sig, size_t sig_len ) +{ + int ret; + +#if defined(MBEDTLS_HAVE_INT64) + if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len ) + return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); +#endif /* MBEDTLS_HAVE_INT64 */ + + if( sig_len < ((mbedtls_rsa_context *) ctx)->len ) + return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); + + if( ( ret = mbedtls_rsa_pkcs1_verify( (mbedtls_rsa_context *) ctx, NULL, NULL, + MBEDTLS_RSA_PUBLIC, md_alg, + (unsigned int) hash_len, hash, sig ) ) != 0 ) + return( ret ); + + if( sig_len > ((mbedtls_rsa_context *) ctx)->len ) + return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH ); + + return( 0 ); +} + +#if defined(MBEDTLS_RSA_PRIV_ENABLED) +static int rsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + unsigned char *sig, size_t *sig_len, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ +#if defined(MBEDTLS_HAVE_INT64) + if( md_alg == MBEDTLS_MD_NONE && UINT_MAX < hash_len ) + return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); +#endif /* MBEDTLS_HAVE_INT64 */ + + *sig_len = ((mbedtls_rsa_context *) ctx)->len; + + return( mbedtls_rsa_pkcs1_sign( (mbedtls_rsa_context *) ctx, f_rng, p_rng, MBEDTLS_RSA_PRIVATE, + md_alg, (unsigned int) hash_len, hash, sig ) ); +} + +static int rsa_decrypt_wrap( void *ctx, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, size_t osize, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + if( ilen != ((mbedtls_rsa_context *) ctx)->len ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + + return( mbedtls_rsa_pkcs1_decrypt( (mbedtls_rsa_context *) ctx, f_rng, p_rng, + MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) ); +} + +#endif /* MBEDTLS_RSA_PRIV_ENABLED */ + +static int rsa_encrypt_wrap( void *ctx, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, size_t osize, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + *olen = ((mbedtls_rsa_context *) ctx)->len; + + if( *olen > osize ) + return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE ); + + return( mbedtls_rsa_pkcs1_encrypt( (mbedtls_rsa_context *) ctx, + f_rng, p_rng, MBEDTLS_RSA_PUBLIC, ilen, input, output ) ); +} + +#if defined(MBEDTLS_RSA_PRIV_ENABLED) +static int rsa_check_pair_wrap( const void *pub, const void *prv ) +{ + return( mbedtls_rsa_check_pub_priv( (const mbedtls_rsa_context *) pub, + (const mbedtls_rsa_context *) prv ) ); +} +#endif /* MBEDTLS_RSA_PRIV_ENABLED */ + +static void *rsa_alloc_wrap( void ) +{ + void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_context ) ); + + if( ctx != NULL ) + mbedtls_rsa_init( (mbedtls_rsa_context *) ctx, 0, 0 ); + + return( ctx ); +} + +static void rsa_free_wrap( void *ctx ) +{ + mbedtls_rsa_free( (mbedtls_rsa_context *) ctx ); + mbedtls_free( ctx ); +} + +static void rsa_debug( const void *ctx, mbedtls_pk_debug_item *items ) +{ + items->type = MBEDTLS_PK_DEBUG_MPI; + items->name = "rsa.N"; + items->value = &( ((mbedtls_rsa_context *) ctx)->N ); + + items++; + + items->type = MBEDTLS_PK_DEBUG_MPI; + items->name = "rsa.E"; + items->value = &( ((mbedtls_rsa_context *) ctx)->E ); +} + +const mbedtls_pk_info_t mbedtls_rsa_info = { + MBEDTLS_PK_RSA, + "RSA", + rsa_get_bitlen, + rsa_can_do, + rsa_verify_wrap, +#if defined(MBEDTLS_RSA_PRIV_ENABLED) + rsa_sign_wrap, + rsa_decrypt_wrap, +#else + NULL, + NULL, +#endif + rsa_encrypt_wrap, +#if defined(MBEDTLS_RSA_PRIV_ENABLED) + rsa_check_pair_wrap, +#else + NULL, +#endif + rsa_alloc_wrap, + rsa_free_wrap, + rsa_debug, +}; +#endif /* MBEDTLS_RSA_C */ + +#else /* MBEDTLS_PK_ALT */ + +static int rsa_can_do( mbedtls_pk_type_t type ) +{ + return( type == MBEDTLS_PK_RSA ); +} + +static size_t rsa_get_bitlen( const void *ctx ) +{ + return( 8 * ((const mbedtls_rsa_context *) ctx)->n_len ); +} + +static int rsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + const unsigned char *sig, size_t sig_len ) +{ + return rsa_verify_alt(ctx, (size_t)md_alg, + hash, hash_len, sig, sig_len); +} + +static int rsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + unsigned char *sig, size_t *sig_len, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + (void)f_rng; + (void)p_rng; + + return rsa_sign_alt(ctx, (size_t)md_alg, + hash, hash_len, sig, sig_len); +} + +static int rsa_decrypt_wrap( void *ctx, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, size_t osize, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + (void)osize; + (void)f_rng; + (void)p_rng; + + if( ilen != ((mbedtls_rsa_context *) ctx)->n_len ) + return -1; + + return rsa_decrypt_alt(ctx, input, ilen, output, olen ); +} + +static int rsa_encrypt_wrap( void *ctx, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, size_t osize, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + (void)f_rng; + (void)p_rng; + + *olen = ((mbedtls_rsa_context *) ctx)->n_len; + + if( *olen > osize ) + return -1; + + return rsa_encrypt_alt(ctx, input, ilen, output, olen ); +} + +static void *rsa_alloc_wrap( void ) +{ + void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_context ) ); + + if( ctx != NULL ) + mbedtls_rsa_init_alt( (mbedtls_rsa_context *) ctx, 0, 0 ); + + return( ctx ); +} + +static void rsa_free_wrap( void *ctx ) +{ + mbedtls_rsa_free_alt( (mbedtls_rsa_context *) ctx ); + mbedtls_free( ctx ); +} + +static void rsa_debug_wrap( const void *ctx, mbedtls_pk_debug_item *items ) +{ + items->type = MBEDTLS_PK_DEBUG_MPI; + items->name = "rsa.N"; + items->value = ((mbedtls_rsa_context *) ctx)->rsa_n; + + items++; + + items->type = MBEDTLS_PK_DEBUG_MPI; + items->name = "rsa.E"; + items->value = ((mbedtls_rsa_context *) ctx)->rsa_e; +} + +const mbedtls_pk_info_t mbedtls_rsa_info = { + MBEDTLS_PK_RSA, + "RSA", + rsa_get_bitlen, + rsa_can_do, + rsa_verify_wrap, + rsa_sign_wrap, + rsa_decrypt_wrap, + rsa_encrypt_wrap, + NULL, + rsa_alloc_wrap, + rsa_free_wrap, + rsa_debug_wrap, +}; +#endif /* MBEDTLS_PK_ALT */ + +#if defined(MBEDTLS_ECP_C) +/* + * Generic EC key + */ +static int eckey_can_do( mbedtls_pk_type_t type ) +{ + return( type == MBEDTLS_PK_ECKEY || + type == MBEDTLS_PK_ECKEY_DH || + type == MBEDTLS_PK_ECDSA ); +} + +static size_t eckey_get_bitlen( const void *ctx ) +{ + return( ((mbedtls_ecp_keypair *) ctx)->grp.pbits ); +} + +#if defined(MBEDTLS_ECDSA_C) +/* Forward declarations */ +static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + const unsigned char *sig, size_t sig_len ); + +static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + unsigned char *sig, size_t *sig_len, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ); + +static int eckey_verify_wrap( void *ctx, mbedtls_md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + const unsigned char *sig, size_t sig_len ) +{ + int ret; + mbedtls_ecdsa_context ecdsa; + + mbedtls_ecdsa_init( &ecdsa ); + + if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 ) + ret = ecdsa_verify_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len ); + + mbedtls_ecdsa_free( &ecdsa ); + + return( ret ); +} + +static int eckey_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + unsigned char *sig, size_t *sig_len, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + int ret; + mbedtls_ecdsa_context ecdsa; + + mbedtls_ecdsa_init( &ecdsa ); + + if( ( ret = mbedtls_ecdsa_from_keypair( &ecdsa, ctx ) ) == 0 ) + ret = ecdsa_sign_wrap( &ecdsa, md_alg, hash, hash_len, sig, sig_len, + f_rng, p_rng ); + + mbedtls_ecdsa_free( &ecdsa ); + + return( ret ); +} + +#endif /* MBEDTLS_ECDSA_C */ + +static int eckey_check_pair( const void *pub, const void *prv ) +{ + return( mbedtls_ecp_check_pub_priv( (const mbedtls_ecp_keypair *) pub, + (const mbedtls_ecp_keypair *) prv ) ); +} + +static void *eckey_alloc_wrap( void ) +{ + void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecp_keypair ) ); + + if( ctx != NULL ) + mbedtls_ecp_keypair_init( ctx ); + + return( ctx ); +} + +static void eckey_free_wrap( void *ctx ) +{ + mbedtls_ecp_keypair_free( (mbedtls_ecp_keypair *) ctx ); + mbedtls_free( ctx ); +} + +static void eckey_debug( const void *ctx, mbedtls_pk_debug_item *items ) +{ + items->type = MBEDTLS_PK_DEBUG_ECP; + items->name = "eckey.Q"; + items->value = &( ((mbedtls_ecp_keypair *) ctx)->Q ); +} + +const mbedtls_pk_info_t mbedtls_eckey_info = { + MBEDTLS_PK_ECKEY, + "EC", + eckey_get_bitlen, + eckey_can_do, +#if defined(MBEDTLS_ECDSA_C) + eckey_verify_wrap, + eckey_sign_wrap, +#else + NULL, + NULL, +#endif + NULL, + NULL, + eckey_check_pair, + eckey_alloc_wrap, + eckey_free_wrap, + eckey_debug, +}; + +/* + * EC key restricted to ECDH + */ +static int eckeydh_can_do( mbedtls_pk_type_t type ) +{ + return( type == MBEDTLS_PK_ECKEY || + type == MBEDTLS_PK_ECKEY_DH ); +} + +const mbedtls_pk_info_t mbedtls_eckeydh_info = { + MBEDTLS_PK_ECKEY_DH, + "EC_DH", + eckey_get_bitlen, /* Same underlying key structure */ + eckeydh_can_do, + NULL, + NULL, + NULL, + NULL, + eckey_check_pair, + eckey_alloc_wrap, /* Same underlying key structure */ + eckey_free_wrap, /* Same underlying key structure */ + eckey_debug, /* Same underlying key structure */ +}; +#endif /* MBEDTLS_ECP_C */ + +#if defined(MBEDTLS_ECDSA_C) +static int ecdsa_can_do( mbedtls_pk_type_t type ) +{ + return( type == MBEDTLS_PK_ECDSA ); +} + +static int ecdsa_verify_wrap( void *ctx, mbedtls_md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + const unsigned char *sig, size_t sig_len ) +{ + int ret; + ((void) md_alg); + + ret = mbedtls_ecdsa_read_signature( (mbedtls_ecdsa_context *) ctx, + hash, hash_len, sig, sig_len ); + + if( ret == MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH ) + return( MBEDTLS_ERR_PK_SIG_LEN_MISMATCH ); + + return( ret ); +} + +static int ecdsa_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + unsigned char *sig, size_t *sig_len, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + return( mbedtls_ecdsa_write_signature( (mbedtls_ecdsa_context *) ctx, + md_alg, hash, hash_len, sig, sig_len, f_rng, p_rng ) ); +} + +static void *ecdsa_alloc_wrap( void ) +{ + void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_ecdsa_context ) ); + + if( ctx != NULL ) + mbedtls_ecdsa_init( (mbedtls_ecdsa_context *) ctx ); + + return( ctx ); +} + +static void ecdsa_free_wrap( void *ctx ) +{ + mbedtls_ecdsa_free( (mbedtls_ecdsa_context *) ctx ); + mbedtls_free( ctx ); +} + +const mbedtls_pk_info_t mbedtls_ecdsa_info = { + MBEDTLS_PK_ECDSA, + "ECDSA", + eckey_get_bitlen, /* Compatible key structures */ + ecdsa_can_do, + ecdsa_verify_wrap, + ecdsa_sign_wrap, + NULL, + NULL, + eckey_check_pair, /* Compatible key structures */ + ecdsa_alloc_wrap, + ecdsa_free_wrap, + eckey_debug, /* Compatible key structures */ +}; +#endif /* MBEDTLS_ECDSA_C */ + +#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) +/* + * Support for alternative RSA-private implementations + */ + +static int rsa_alt_can_do( mbedtls_pk_type_t type ) +{ + return( type == MBEDTLS_PK_RSA ); +} + +static size_t rsa_alt_get_bitlen( const void *ctx ) +{ + const mbedtls_rsa_alt_context *rsa_alt = (const mbedtls_rsa_alt_context *) ctx; + + return( 8 * rsa_alt->key_len_func( rsa_alt->key ) ); +} + +static int rsa_alt_sign_wrap( void *ctx, mbedtls_md_type_t md_alg, + const unsigned char *hash, size_t hash_len, + unsigned char *sig, size_t *sig_len, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx; + +#if defined(MBEDTLS_HAVE_INT64) + if( UINT_MAX < hash_len ) + return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); +#endif /* MBEDTLS_HAVE_INT64 */ + + *sig_len = rsa_alt->key_len_func( rsa_alt->key ); + + return( rsa_alt->sign_func( rsa_alt->key, f_rng, p_rng, MBEDTLS_RSA_PRIVATE, + md_alg, (unsigned int) hash_len, hash, sig ) ); +} + +static int rsa_alt_decrypt_wrap( void *ctx, + const unsigned char *input, size_t ilen, + unsigned char *output, size_t *olen, size_t osize, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + mbedtls_rsa_alt_context *rsa_alt = (mbedtls_rsa_alt_context *) ctx; + + ((void) f_rng); + ((void) p_rng); + + if( ilen != rsa_alt->key_len_func( rsa_alt->key ) ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + + return( rsa_alt->decrypt_func( rsa_alt->key, + MBEDTLS_RSA_PRIVATE, olen, input, output, osize ) ); +} + +#if defined(MBEDTLS_RSA_C) +static int rsa_alt_check_pair( const void *pub, const void *prv ) +{ + unsigned char sig[MBEDTLS_MPI_MAX_SIZE]; + unsigned char hash[32]; + size_t sig_len = 0; + int ret; + + if( rsa_alt_get_bitlen( prv ) != rsa_get_bitlen( pub ) ) + return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); + + memset( hash, 0x2a, sizeof( hash ) ); + + if( ( ret = rsa_alt_sign_wrap( (void *) prv, MBEDTLS_MD_NONE, + hash, sizeof( hash ), + sig, &sig_len, NULL, NULL ) ) != 0 ) + { + return( ret ); + } + + if( rsa_verify_wrap( (void *) pub, MBEDTLS_MD_NONE, + hash, sizeof( hash ), sig, sig_len ) != 0 ) + { + return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); + } + + return( 0 ); +} +#endif /* MBEDTLS_RSA_C */ + +static void *rsa_alt_alloc_wrap( void ) +{ + void *ctx = mbedtls_calloc( 1, sizeof( mbedtls_rsa_alt_context ) ); + + if( ctx != NULL ) + memset( ctx, 0, sizeof( mbedtls_rsa_alt_context ) ); + + return( ctx ); +} + +static void rsa_alt_free_wrap( void *ctx ) +{ + mbedtls_zeroize( ctx, sizeof( mbedtls_rsa_alt_context ) ); + mbedtls_free( ctx ); +} + +const mbedtls_pk_info_t mbedtls_rsa_alt_info = { + MBEDTLS_PK_RSA_ALT, + "RSA-alt", + rsa_alt_get_bitlen, + rsa_alt_can_do, + NULL, + rsa_alt_sign_wrap, + rsa_alt_decrypt_wrap, + NULL, +#if defined(MBEDTLS_RSA_C) + rsa_alt_check_pair, +#else + NULL, +#endif + rsa_alt_alloc_wrap, + rsa_alt_free_wrap, + NULL, +}; + +#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */ + +#endif /* MBEDTLS_PK_C */ diff --git a/security/mbedtls/src/pkcs11.c b/security/mbedtls/src/pkcs11.c new file mode 100644 index 0000000000..0ea64252ee --- /dev/null +++ b/security/mbedtls/src/pkcs11.c @@ -0,0 +1,240 @@ +/** + * \file pkcs11.c + * + * \brief Wrapper for PKCS#11 library libpkcs11-helper + * + * \author Adriaan de Jong + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#include "mbedtls/pkcs11.h" + +#if defined(MBEDTLS_PKCS11_C) + +#include "mbedtls/md.h" +#include "mbedtls/oid.h" +#include "mbedtls/x509_crt.h" + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_calloc calloc +#define mbedtls_free free +#endif + +#include + +void mbedtls_pkcs11_init( mbedtls_pkcs11_context *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_pkcs11_context ) ); +} + +int mbedtls_pkcs11_x509_cert_bind( mbedtls_x509_crt *cert, pkcs11h_certificate_t pkcs11_cert ) +{ + int ret = 1; + unsigned char *cert_blob = NULL; + size_t cert_blob_size = 0; + + if( cert == NULL ) + { + ret = 2; + goto cleanup; + } + + if( pkcs11h_certificate_getCertificateBlob( pkcs11_cert, NULL, + &cert_blob_size ) != CKR_OK ) + { + ret = 3; + goto cleanup; + } + + cert_blob = mbedtls_calloc( 1, cert_blob_size ); + if( NULL == cert_blob ) + { + ret = 4; + goto cleanup; + } + + if( pkcs11h_certificate_getCertificateBlob( pkcs11_cert, cert_blob, + &cert_blob_size ) != CKR_OK ) + { + ret = 5; + goto cleanup; + } + + if( 0 != mbedtls_x509_crt_parse( cert, cert_blob, cert_blob_size ) ) + { + ret = 6; + goto cleanup; + } + + ret = 0; + +cleanup: + if( NULL != cert_blob ) + mbedtls_free( cert_blob ); + + return( ret ); +} + + +int mbedtls_pkcs11_priv_key_bind( mbedtls_pkcs11_context *priv_key, + pkcs11h_certificate_t pkcs11_cert ) +{ + int ret = 1; + mbedtls_x509_crt cert; + + mbedtls_x509_crt_init( &cert ); + + if( priv_key == NULL ) + goto cleanup; + + if( 0 != mbedtls_pkcs11_x509_cert_bind( &cert, pkcs11_cert ) ) + goto cleanup; + + priv_key->len = mbedtls_pk_get_len( &cert.pk ); + priv_key->pkcs11h_cert = pkcs11_cert; + + ret = 0; + +cleanup: + mbedtls_x509_crt_free( &cert ); + + return( ret ); +} + +void mbedtls_pkcs11_priv_key_free( mbedtls_pkcs11_context *priv_key ) +{ + if( NULL != priv_key ) + pkcs11h_certificate_freeCertificate( priv_key->pkcs11h_cert ); +} + +int mbedtls_pkcs11_decrypt( mbedtls_pkcs11_context *ctx, + int mode, size_t *olen, + const unsigned char *input, + unsigned char *output, + size_t output_max_len ) +{ + size_t input_len, output_len; + + if( NULL == ctx ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + + if( MBEDTLS_RSA_PRIVATE != mode ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + + output_len = input_len = ctx->len; + + if( input_len < 16 || input_len > output_max_len ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + + /* Determine size of output buffer */ + if( pkcs11h_certificate_decryptAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, input, + input_len, NULL, &output_len ) != CKR_OK ) + { + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + } + + if( output_len > output_max_len ) + return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE ); + + if( pkcs11h_certificate_decryptAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, input, + input_len, output, &output_len ) != CKR_OK ) + { + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + } + *olen = output_len; + return( 0 ); +} + +int mbedtls_pkcs11_sign( mbedtls_pkcs11_context *ctx, + int mode, + mbedtls_md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + unsigned char *sig ) +{ + size_t sig_len = 0, asn_len = 0, oid_size = 0; + unsigned char *p = sig; + const char *oid; + + if( NULL == ctx ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + + if( MBEDTLS_RSA_PRIVATE != mode ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + + if( md_alg != MBEDTLS_MD_NONE ) + { + const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg ); + if( md_info == NULL ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + + if( mbedtls_oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + + hashlen = mbedtls_md_get_size( md_info ); + asn_len = 10 + oid_size; + } + + sig_len = ctx->len; + if( hashlen > sig_len || asn_len > sig_len || + hashlen + asn_len > sig_len ) + { + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + } + + if( md_alg != MBEDTLS_MD_NONE ) + { + /* + * DigestInfo ::= SEQUENCE { + * digestAlgorithm DigestAlgorithmIdentifier, + * digest Digest } + * + * DigestAlgorithmIdentifier ::= AlgorithmIdentifier + * + * Digest ::= OCTET STRING + */ + *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED; + *p++ = (unsigned char) ( 0x08 + oid_size + hashlen ); + *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED; + *p++ = (unsigned char) ( 0x04 + oid_size ); + *p++ = MBEDTLS_ASN1_OID; + *p++ = oid_size & 0xFF; + memcpy( p, oid, oid_size ); + p += oid_size; + *p++ = MBEDTLS_ASN1_NULL; + *p++ = 0x00; + *p++ = MBEDTLS_ASN1_OCTET_STRING; + *p++ = hashlen; + } + + memcpy( p, hash, hashlen ); + + if( pkcs11h_certificate_signAny( ctx->pkcs11h_cert, CKM_RSA_PKCS, sig, + asn_len + hashlen, sig, &sig_len ) != CKR_OK ) + { + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + } + + return( 0 ); +} + +#endif /* defined(MBEDTLS_PKCS11_C) */ diff --git a/security/mbedtls/src/pkcs12.c b/security/mbedtls/src/pkcs12.c new file mode 100644 index 0000000000..c603a13577 --- /dev/null +++ b/security/mbedtls/src/pkcs12.c @@ -0,0 +1,365 @@ +/* + * PKCS#12 Personal Information Exchange Syntax + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +/* + * The PKCS #12 Personal Information Exchange Syntax Standard v1.1 + * + * http://www.rsa.com/rsalabs/pkcs/files/h11301-wp-pkcs-12v1-1-personal-information-exchange-syntax.pdf + * ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-12/pkcs-12v1-1.asn + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_PKCS12_C) + +#include "mbedtls/pkcs12.h" +#include "mbedtls/asn1.h" +#include "mbedtls/cipher.h" + +#include + +#if defined(MBEDTLS_ARC4_C) +#include "mbedtls/arc4.h" +#endif + +#if defined(MBEDTLS_DES_C) +#include "mbedtls/des.h" +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +static int pkcs12_parse_pbe_params( mbedtls_asn1_buf *params, + mbedtls_asn1_buf *salt, int *iterations ) +{ + int ret; + unsigned char **p = ¶ms->p; + const unsigned char *end = params->p + params->len; + + /* + * pkcs-12PbeParams ::= SEQUENCE { + * salt OCTET STRING, + * iterations INTEGER + * } + * + */ + if( params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) + return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT + + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); + + if( ( ret = mbedtls_asn1_get_tag( p, end, &salt->len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ) + return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT + ret ); + + salt->p = *p; + *p += salt->len; + + if( ( ret = mbedtls_asn1_get_int( p, end, iterations ) ) != 0 ) + return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT + ret ); + + if( *p != end ) + return( MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + + return( 0 ); +} + +#define PKCS12_MAX_PWDLEN 128 + +static int pkcs12_pbe_derive_key_iv( mbedtls_asn1_buf *pbe_params, mbedtls_md_type_t md_type, + const unsigned char *pwd, size_t pwdlen, + unsigned char *key, size_t keylen, + unsigned char *iv, size_t ivlen ) +{ + int ret, iterations = 0; + mbedtls_asn1_buf salt; + size_t i; + unsigned char unipwd[PKCS12_MAX_PWDLEN * 2 + 2]; + + if( pwdlen > PKCS12_MAX_PWDLEN ) + return( MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA ); + + memset( &salt, 0, sizeof(mbedtls_asn1_buf) ); + memset( &unipwd, 0, sizeof(unipwd) ); + + if( ( ret = pkcs12_parse_pbe_params( pbe_params, &salt, + &iterations ) ) != 0 ) + return( ret ); + + for( i = 0; i < pwdlen; i++ ) + unipwd[i * 2 + 1] = pwd[i]; + + if( ( ret = mbedtls_pkcs12_derivation( key, keylen, unipwd, pwdlen * 2 + 2, + salt.p, salt.len, md_type, + MBEDTLS_PKCS12_DERIVE_KEY, iterations ) ) != 0 ) + { + return( ret ); + } + + if( iv == NULL || ivlen == 0 ) + return( 0 ); + + if( ( ret = mbedtls_pkcs12_derivation( iv, ivlen, unipwd, pwdlen * 2 + 2, + salt.p, salt.len, md_type, + MBEDTLS_PKCS12_DERIVE_IV, iterations ) ) != 0 ) + { + return( ret ); + } + return( 0 ); +} + +#undef PKCS12_MAX_PWDLEN + +int mbedtls_pkcs12_pbe_sha1_rc4_128( mbedtls_asn1_buf *pbe_params, int mode, + const unsigned char *pwd, size_t pwdlen, + const unsigned char *data, size_t len, + unsigned char *output ) +{ +#if !defined(MBEDTLS_ARC4_C) + ((void) pbe_params); + ((void) mode); + ((void) pwd); + ((void) pwdlen); + ((void) data); + ((void) len); + ((void) output); + return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE ); +#else + int ret; + unsigned char key[16]; + mbedtls_arc4_context ctx; + ((void) mode); + + mbedtls_arc4_init( &ctx ); + + if( ( ret = pkcs12_pbe_derive_key_iv( pbe_params, MBEDTLS_MD_SHA1, + pwd, pwdlen, + key, 16, NULL, 0 ) ) != 0 ) + { + return( ret ); + } + + mbedtls_arc4_setup( &ctx, key, 16 ); + if( ( ret = mbedtls_arc4_crypt( &ctx, len, data, output ) ) != 0 ) + goto exit; + +exit: + mbedtls_zeroize( key, sizeof( key ) ); + mbedtls_arc4_free( &ctx ); + + return( ret ); +#endif /* MBEDTLS_ARC4_C */ +} + +int mbedtls_pkcs12_pbe( mbedtls_asn1_buf *pbe_params, int mode, + mbedtls_cipher_type_t cipher_type, mbedtls_md_type_t md_type, + const unsigned char *pwd, size_t pwdlen, + const unsigned char *data, size_t len, + unsigned char *output ) +{ + int ret, keylen = 0; + unsigned char key[32]; + unsigned char iv[16]; + const mbedtls_cipher_info_t *cipher_info; + mbedtls_cipher_context_t cipher_ctx; + size_t olen = 0; + + cipher_info = mbedtls_cipher_info_from_type( cipher_type ); + if( cipher_info == NULL ) + return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE ); + + keylen = cipher_info->key_bitlen / 8; + + if( ( ret = pkcs12_pbe_derive_key_iv( pbe_params, md_type, pwd, pwdlen, + key, keylen, + iv, cipher_info->iv_size ) ) != 0 ) + { + return( ret ); + } + + mbedtls_cipher_init( &cipher_ctx ); + + if( ( ret = mbedtls_cipher_setup( &cipher_ctx, cipher_info ) ) != 0 ) + goto exit; + + if( ( ret = mbedtls_cipher_setkey( &cipher_ctx, key, 8 * keylen, (mbedtls_operation_t) mode ) ) != 0 ) + goto exit; + + if( ( ret = mbedtls_cipher_set_iv( &cipher_ctx, iv, cipher_info->iv_size ) ) != 0 ) + goto exit; + + if( ( ret = mbedtls_cipher_reset( &cipher_ctx ) ) != 0 ) + goto exit; + + if( ( ret = mbedtls_cipher_update( &cipher_ctx, data, len, + output, &olen ) ) != 0 ) + { + goto exit; + } + + if( ( ret = mbedtls_cipher_finish( &cipher_ctx, output + olen, &olen ) ) != 0 ) + ret = MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH; + +exit: + mbedtls_zeroize( key, sizeof( key ) ); + mbedtls_zeroize( iv, sizeof( iv ) ); + mbedtls_cipher_free( &cipher_ctx ); + + return( ret ); +} + +static void pkcs12_fill_buffer( unsigned char *data, size_t data_len, + const unsigned char *filler, size_t fill_len ) +{ + unsigned char *p = data; + size_t use_len; + + while( data_len > 0 ) + { + use_len = ( data_len > fill_len ) ? fill_len : data_len; + memcpy( p, filler, use_len ); + p += use_len; + data_len -= use_len; + } +} + +int mbedtls_pkcs12_derivation( unsigned char *data, size_t datalen, + const unsigned char *pwd, size_t pwdlen, + const unsigned char *salt, size_t saltlen, + mbedtls_md_type_t md_type, int id, int iterations ) +{ + int ret; + unsigned int j; + + unsigned char diversifier[128]; + unsigned char salt_block[128], pwd_block[128], hash_block[128]; + unsigned char hash_output[MBEDTLS_MD_MAX_SIZE]; + unsigned char *p; + unsigned char c; + + size_t hlen, use_len, v, i; + + const mbedtls_md_info_t *md_info; + mbedtls_md_context_t md_ctx; + + // This version only allows max of 64 bytes of password or salt + if( datalen > 128 || pwdlen > 64 || saltlen > 64 ) + return( MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA ); + + md_info = mbedtls_md_info_from_type( md_type ); + if( md_info == NULL ) + return( MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE ); + + mbedtls_md_init( &md_ctx ); + + if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 ) + return( ret ); + hlen = mbedtls_md_get_size( md_info ); + + if( hlen <= 32 ) + v = 64; + else + v = 128; + + memset( diversifier, (unsigned char) id, v ); + + pkcs12_fill_buffer( salt_block, v, salt, saltlen ); + pkcs12_fill_buffer( pwd_block, v, pwd, pwdlen ); + + p = data; + while( datalen > 0 ) + { + // Calculate hash( diversifier || salt_block || pwd_block ) + if( ( ret = mbedtls_md_starts( &md_ctx ) ) != 0 ) + goto exit; + + if( ( ret = mbedtls_md_update( &md_ctx, diversifier, v ) ) != 0 ) + goto exit; + + if( ( ret = mbedtls_md_update( &md_ctx, salt_block, v ) ) != 0 ) + goto exit; + + if( ( ret = mbedtls_md_update( &md_ctx, pwd_block, v ) ) != 0 ) + goto exit; + + if( ( ret = mbedtls_md_finish( &md_ctx, hash_output ) ) != 0 ) + goto exit; + + // Perform remaining ( iterations - 1 ) recursive hash calculations + for( i = 1; i < (size_t) iterations; i++ ) + { + if( ( ret = mbedtls_md( md_info, hash_output, hlen, hash_output ) ) != 0 ) + goto exit; + } + + use_len = ( datalen > hlen ) ? hlen : datalen; + memcpy( p, hash_output, use_len ); + datalen -= use_len; + p += use_len; + + if( datalen == 0 ) + break; + + // Concatenating copies of hash_output into hash_block (B) + pkcs12_fill_buffer( hash_block, v, hash_output, hlen ); + + // B += 1 + for( i = v; i > 0; i-- ) + if( ++hash_block[i - 1] != 0 ) + break; + + // salt_block += B + c = 0; + for( i = v; i > 0; i-- ) + { + j = salt_block[i - 1] + hash_block[i - 1] + c; + c = (unsigned char) (j >> 8); + salt_block[i - 1] = j & 0xFF; + } + + // pwd_block += B + c = 0; + for( i = v; i > 0; i-- ) + { + j = pwd_block[i - 1] + hash_block[i - 1] + c; + c = (unsigned char) (j >> 8); + pwd_block[i - 1] = j & 0xFF; + } + } + + ret = 0; + +exit: + mbedtls_zeroize( salt_block, sizeof( salt_block ) ); + mbedtls_zeroize( pwd_block, sizeof( pwd_block ) ); + mbedtls_zeroize( hash_block, sizeof( hash_block ) ); + mbedtls_zeroize( hash_output, sizeof( hash_output ) ); + + mbedtls_md_free( &md_ctx ); + + return( ret ); +} + +#endif /* MBEDTLS_PKCS12_C */ diff --git a/security/mbedtls/src/pkcs5.c b/security/mbedtls/src/pkcs5.c new file mode 100644 index 0000000000..e28d5a8473 --- /dev/null +++ b/security/mbedtls/src/pkcs5.c @@ -0,0 +1,406 @@ +/** + * \file pkcs5.c + * + * \brief PKCS#5 functions + * + * \author Mathias Olsson + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +/* + * PKCS#5 includes PBKDF2 and more + * + * http://tools.ietf.org/html/rfc2898 (Specification) + * http://tools.ietf.org/html/rfc6070 (Test vectors) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_PKCS5_C) + +#include "mbedtls/pkcs5.h" +#include "mbedtls/asn1.h" +#include "mbedtls/cipher.h" +#include "mbedtls/oid.h" + +#include + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_printf printf +#endif + +static int pkcs5_parse_pbkdf2_params( const mbedtls_asn1_buf *params, + mbedtls_asn1_buf *salt, int *iterations, + int *keylen, mbedtls_md_type_t *md_type ) +{ + int ret; + mbedtls_asn1_buf prf_alg_oid; + unsigned char *p = params->p; + const unsigned char *end = params->p + params->len; + + if( params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) + return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); + /* + * PBKDF2-params ::= SEQUENCE { + * salt OCTET STRING, + * iterationCount INTEGER, + * keyLength INTEGER OPTIONAL + * prf AlgorithmIdentifier DEFAULT algid-hmacWithSHA1 + * } + * + */ + if( ( ret = mbedtls_asn1_get_tag( &p, end, &salt->len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ) + return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret ); + + salt->p = p; + p += salt->len; + + if( ( ret = mbedtls_asn1_get_int( &p, end, iterations ) ) != 0 ) + return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret ); + + if( p == end ) + return( 0 ); + + if( ( ret = mbedtls_asn1_get_int( &p, end, keylen ) ) != 0 ) + { + if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) + return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret ); + } + + if( p == end ) + return( 0 ); + + if( ( ret = mbedtls_asn1_get_alg_null( &p, end, &prf_alg_oid ) ) != 0 ) + return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret ); + + if( MBEDTLS_OID_CMP( MBEDTLS_OID_HMAC_SHA1, &prf_alg_oid ) != 0 ) + return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE ); + + *md_type = MBEDTLS_MD_SHA1; + + if( p != end ) + return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + + return( 0 ); +} + +int mbedtls_pkcs5_pbes2( const mbedtls_asn1_buf *pbe_params, int mode, + const unsigned char *pwd, size_t pwdlen, + const unsigned char *data, size_t datalen, + unsigned char *output ) +{ + int ret, iterations = 0, keylen = 0; + unsigned char *p, *end; + mbedtls_asn1_buf kdf_alg_oid, enc_scheme_oid, kdf_alg_params, enc_scheme_params; + mbedtls_asn1_buf salt; + mbedtls_md_type_t md_type = MBEDTLS_MD_SHA1; + unsigned char key[32], iv[32]; + size_t olen = 0; + const mbedtls_md_info_t *md_info; + const mbedtls_cipher_info_t *cipher_info; + mbedtls_md_context_t md_ctx; + mbedtls_cipher_type_t cipher_alg; + mbedtls_cipher_context_t cipher_ctx; + + p = pbe_params->p; + end = p + pbe_params->len; + + /* + * PBES2-params ::= SEQUENCE { + * keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}}, + * encryptionScheme AlgorithmIdentifier {{PBES2-Encs}} + * } + */ + if( pbe_params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) + return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); + + if( ( ret = mbedtls_asn1_get_alg( &p, end, &kdf_alg_oid, &kdf_alg_params ) ) != 0 ) + return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret ); + + // Only PBKDF2 supported at the moment + // + if( MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS5_PBKDF2, &kdf_alg_oid ) != 0 ) + return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE ); + + if( ( ret = pkcs5_parse_pbkdf2_params( &kdf_alg_params, + &salt, &iterations, &keylen, + &md_type ) ) != 0 ) + { + return( ret ); + } + + md_info = mbedtls_md_info_from_type( md_type ); + if( md_info == NULL ) + return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE ); + + if( ( ret = mbedtls_asn1_get_alg( &p, end, &enc_scheme_oid, + &enc_scheme_params ) ) != 0 ) + { + return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT + ret ); + } + + if( mbedtls_oid_get_cipher_alg( &enc_scheme_oid, &cipher_alg ) != 0 ) + return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE ); + + cipher_info = mbedtls_cipher_info_from_type( cipher_alg ); + if( cipher_info == NULL ) + return( MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE ); + + /* + * The value of keylen from pkcs5_parse_pbkdf2_params() is ignored + * since it is optional and we don't know if it was set or not + */ + keylen = cipher_info->key_bitlen / 8; + + if( enc_scheme_params.tag != MBEDTLS_ASN1_OCTET_STRING || + enc_scheme_params.len != cipher_info->iv_size ) + { + return( MBEDTLS_ERR_PKCS5_INVALID_FORMAT ); + } + + mbedtls_md_init( &md_ctx ); + mbedtls_cipher_init( &cipher_ctx ); + + memcpy( iv, enc_scheme_params.p, enc_scheme_params.len ); + + if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 ) + goto exit; + + if( ( ret = mbedtls_pkcs5_pbkdf2_hmac( &md_ctx, pwd, pwdlen, salt.p, salt.len, + iterations, keylen, key ) ) != 0 ) + { + goto exit; + } + + if( ( ret = mbedtls_cipher_setup( &cipher_ctx, cipher_info ) ) != 0 ) + goto exit; + + if( ( ret = mbedtls_cipher_setkey( &cipher_ctx, key, 8 * keylen, (mbedtls_operation_t) mode ) ) != 0 ) + goto exit; + + if( ( ret = mbedtls_cipher_crypt( &cipher_ctx, iv, enc_scheme_params.len, + data, datalen, output, &olen ) ) != 0 ) + ret = MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH; + +exit: + mbedtls_md_free( &md_ctx ); + mbedtls_cipher_free( &cipher_ctx ); + + return( ret ); +} + +int mbedtls_pkcs5_pbkdf2_hmac( mbedtls_md_context_t *ctx, const unsigned char *password, + size_t plen, const unsigned char *salt, size_t slen, + unsigned int iteration_count, + uint32_t key_length, unsigned char *output ) +{ + int ret, j; + unsigned int i; + unsigned char md1[MBEDTLS_MD_MAX_SIZE]; + unsigned char work[MBEDTLS_MD_MAX_SIZE]; + unsigned char md_size = mbedtls_md_get_size( ctx->md_info ); + size_t use_len; + unsigned char *out_p = output; + unsigned char counter[4]; + + memset( counter, 0, 4 ); + counter[3] = 1; + + if( iteration_count > 0xFFFFFFFF ) + return( MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA ); + + while( key_length ) + { + // U1 ends up in work + // + if( ( ret = mbedtls_md_hmac_starts( ctx, password, plen ) ) != 0 ) + return( ret ); + + if( ( ret = mbedtls_md_hmac_update( ctx, salt, slen ) ) != 0 ) + return( ret ); + + if( ( ret = mbedtls_md_hmac_update( ctx, counter, 4 ) ) != 0 ) + return( ret ); + + if( ( ret = mbedtls_md_hmac_finish( ctx, work ) ) != 0 ) + return( ret ); + + memcpy( md1, work, md_size ); + + for( i = 1; i < iteration_count; i++ ) + { + // U2 ends up in md1 + // + if( ( ret = mbedtls_md_hmac_starts( ctx, password, plen ) ) != 0 ) + return( ret ); + + if( ( ret = mbedtls_md_hmac_update( ctx, md1, md_size ) ) != 0 ) + return( ret ); + + if( ( ret = mbedtls_md_hmac_finish( ctx, md1 ) ) != 0 ) + return( ret ); + + // U1 xor U2 + // + for( j = 0; j < md_size; j++ ) + work[j] ^= md1[j]; + } + + use_len = ( key_length < md_size ) ? key_length : md_size; + memcpy( out_p, work, use_len ); + + key_length -= (uint32_t) use_len; + out_p += use_len; + + for( i = 4; i > 0; i-- ) + if( ++counter[i - 1] != 0 ) + break; + } + + return( 0 ); +} + +#if defined(MBEDTLS_SELF_TEST) + +#if !defined(MBEDTLS_SHA1_C) +int mbedtls_pkcs5_self_test( int verbose ) +{ + if( verbose != 0 ) + mbedtls_printf( " PBKDF2 (SHA1): skipped\n\n" ); + + return( 0 ); +} +#else + +#define MAX_TESTS 6 + +static const size_t plen[MAX_TESTS] = + { 8, 8, 8, 24, 9 }; + +static const unsigned char password[MAX_TESTS][32] = +{ + "password", + "password", + "password", + "passwordPASSWORDpassword", + "pass\0word", +}; + +static const size_t slen[MAX_TESTS] = + { 4, 4, 4, 36, 5 }; + +static const unsigned char salt[MAX_TESTS][40] = +{ + "salt", + "salt", + "salt", + "saltSALTsaltSALTsaltSALTsaltSALTsalt", + "sa\0lt", +}; + +static const uint32_t it_cnt[MAX_TESTS] = + { 1, 2, 4096, 4096, 4096 }; + +static const uint32_t key_len[MAX_TESTS] = + { 20, 20, 20, 25, 16 }; + +static const unsigned char result_key[MAX_TESTS][32] = +{ + { 0x0c, 0x60, 0xc8, 0x0f, 0x96, 0x1f, 0x0e, 0x71, + 0xf3, 0xa9, 0xb5, 0x24, 0xaf, 0x60, 0x12, 0x06, + 0x2f, 0xe0, 0x37, 0xa6 }, + { 0xea, 0x6c, 0x01, 0x4d, 0xc7, 0x2d, 0x6f, 0x8c, + 0xcd, 0x1e, 0xd9, 0x2a, 0xce, 0x1d, 0x41, 0xf0, + 0xd8, 0xde, 0x89, 0x57 }, + { 0x4b, 0x00, 0x79, 0x01, 0xb7, 0x65, 0x48, 0x9a, + 0xbe, 0xad, 0x49, 0xd9, 0x26, 0xf7, 0x21, 0xd0, + 0x65, 0xa4, 0x29, 0xc1 }, + { 0x3d, 0x2e, 0xec, 0x4f, 0xe4, 0x1c, 0x84, 0x9b, + 0x80, 0xc8, 0xd8, 0x36, 0x62, 0xc0, 0xe4, 0x4a, + 0x8b, 0x29, 0x1a, 0x96, 0x4c, 0xf2, 0xf0, 0x70, + 0x38 }, + { 0x56, 0xfa, 0x6a, 0xa7, 0x55, 0x48, 0x09, 0x9d, + 0xcc, 0x37, 0xd7, 0xf0, 0x34, 0x25, 0xe0, 0xc3 }, +}; + +int mbedtls_pkcs5_self_test( int verbose ) +{ + mbedtls_md_context_t sha1_ctx; + const mbedtls_md_info_t *info_sha1; + int ret, i; + unsigned char key[64]; + + mbedtls_md_init( &sha1_ctx ); + + info_sha1 = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 ); + if( info_sha1 == NULL ) + { + ret = 1; + goto exit; + } + + if( ( ret = mbedtls_md_setup( &sha1_ctx, info_sha1, 1 ) ) != 0 ) + { + ret = 1; + goto exit; + } + + for( i = 0; i < MAX_TESTS; i++ ) + { + if( verbose != 0 ) + mbedtls_printf( " PBKDF2 (SHA1) #%d: ", i ); + + ret = mbedtls_pkcs5_pbkdf2_hmac( &sha1_ctx, password[i], plen[i], salt[i], + slen[i], it_cnt[i], key_len[i], key ); + if( ret != 0 || + memcmp( result_key[i], key, key_len[i] ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + ret = 1; + goto exit; + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + +exit: + mbedtls_md_free( &sha1_ctx ); + + return( ret ); +} +#endif /* MBEDTLS_SHA1_C */ + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_PKCS5_C */ diff --git a/security/mbedtls/src/pkparse.c b/security/mbedtls/src/pkparse.c new file mode 100644 index 0000000000..50d5a73709 --- /dev/null +++ b/security/mbedtls/src/pkparse.c @@ -0,0 +1,1360 @@ +/* + * Public Key layer for parsing key files and structures + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_PK_PARSE_C) + +#include "mbedtls/pk.h" +#include "mbedtls/asn1.h" +#include "mbedtls/oid.h" +#include "mbedtls/debug.h" + +#include + +#if defined(MBEDTLS_RSA_C) +#include "mbedtls/rsa.h" +#endif +#if defined(MBEDTLS_ECP_C) +#include "mbedtls/ecp.h" +#endif +#if defined(MBEDTLS_ECDSA_C) +#include "mbedtls/ecdsa.h" +#endif +#if defined(MBEDTLS_PEM_PARSE_C) +#include "mbedtls/pem.h" +#endif +#if defined(MBEDTLS_PKCS5_C) +#include "mbedtls/pkcs5.h" +#endif +#if defined(MBEDTLS_PKCS12_C) +#include "mbedtls/pkcs12.h" +#endif + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_calloc calloc +#define mbedtls_free free +#endif + +#if defined(MBEDTLS_IOT_SPECIFIC) +static unsigned char CRT_OID_PKCS1_RSA[] = { + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01 +}; +#endif + +#if defined(MBEDTLS_FS_IO) +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +/* + * Load all data from a file into a given buffer. + * + * The file is expected to contain either PEM or DER encoded data. + * A terminating null byte is always appended. It is included in the announced + * length only if the data looks like it is PEM encoded. + */ +int mbedtls_pk_load_file( const char *path, unsigned char **buf, size_t *n ) +{ + FILE *f; + long size; + + if( ( f = fopen( path, "rb" ) ) == NULL ) + return( MBEDTLS_ERR_PK_FILE_IO_ERROR ); + + fseek( f, 0, SEEK_END ); + if( ( size = ftell( f ) ) == -1 ) + { + fclose( f ); + return( MBEDTLS_ERR_PK_FILE_IO_ERROR ); + } + fseek( f, 0, SEEK_SET ); + + *n = (size_t) size; + + if( *n + 1 == 0 || + ( *buf = mbedtls_calloc( 1, *n + 1 ) ) == NULL ) + { + fclose( f ); + return( MBEDTLS_ERR_PK_ALLOC_FAILED ); + } + + if( fread( *buf, 1, *n, f ) != *n ) + { + fclose( f ); + mbedtls_free( *buf ); + return( MBEDTLS_ERR_PK_FILE_IO_ERROR ); + } + + fclose( f ); + + (*buf)[*n] = '\0'; + + if( strstr( (const char *) *buf, "-----BEGIN " ) != NULL ) + ++*n; + + return( 0 ); +} + +/* + * Load and parse a private key + */ +int mbedtls_pk_parse_keyfile( mbedtls_pk_context *ctx, + const char *path, const char *pwd ) +{ + int ret; + size_t n; + unsigned char *buf; + + if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 ) + return( ret ); + + if( pwd == NULL ) + ret = mbedtls_pk_parse_key( ctx, buf, n, NULL, 0 ); + else + ret = mbedtls_pk_parse_key( ctx, buf, n, + (const unsigned char *) pwd, strlen( pwd ) ); + + mbedtls_zeroize( buf, n ); + mbedtls_free( buf ); + + return( ret ); +} + +/* + * Load and parse a public key + */ +int mbedtls_pk_parse_public_keyfile( mbedtls_pk_context *ctx, const char *path ) +{ + int ret; + size_t n; + unsigned char *buf; + + if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 ) + return( ret ); + + ret = mbedtls_pk_parse_public_key( ctx, buf, n ); + + mbedtls_zeroize( buf, n ); + mbedtls_free( buf ); + + return( ret ); +} +#endif /* MBEDTLS_FS_IO */ + +#if defined(MBEDTLS_ECP_C) +/* Minimally parse an ECParameters buffer to and mbedtls_asn1_buf + * + * ECParameters ::= CHOICE { + * namedCurve OBJECT IDENTIFIER + * specifiedCurve SpecifiedECDomain -- = SEQUENCE { ... } + * -- implicitCurve NULL + * } + */ +static int pk_get_ecparams( unsigned char **p, const unsigned char *end, + mbedtls_asn1_buf *params ) +{ + int ret; + + /* Tag may be either OID or SEQUENCE */ + params->tag = **p; + if( params->tag != MBEDTLS_ASN1_OID +#if defined(MBEDTLS_PK_PARSE_EC_EXTENDED) + && params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) +#endif + ) + { + return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); + } + + if( ( ret = mbedtls_asn1_get_tag( p, end, ¶ms->len, params->tag ) ) != 0 ) + { + return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); + } + + params->p = *p; + *p += params->len; + + if( *p != end ) + return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + + return( 0 ); +} + +#if defined(MBEDTLS_PK_PARSE_EC_EXTENDED) +/* + * Parse a SpecifiedECDomain (SEC 1 C.2) and (mostly) fill the group with it. + * WARNING: the resulting group should only be used with + * pk_group_id_from_specified(), since its base point may not be set correctly + * if it was encoded compressed. + * + * SpecifiedECDomain ::= SEQUENCE { + * version SpecifiedECDomainVersion(ecdpVer1 | ecdpVer2 | ecdpVer3, ...), + * fieldID FieldID {{FieldTypes}}, + * curve Curve, + * base ECPoint, + * order INTEGER, + * cofactor INTEGER OPTIONAL, + * hash HashAlgorithm OPTIONAL, + * ... + * } + * + * We only support prime-field as field type, and ignore hash and cofactor. + */ +static int pk_group_from_specified( const mbedtls_asn1_buf *params, mbedtls_ecp_group *grp ) +{ + int ret; + unsigned char *p = params->p; + const unsigned char * const end = params->p + params->len; + const unsigned char *end_field, *end_curve; + size_t len; + int ver; + + /* SpecifiedECDomainVersion ::= INTEGER { 1, 2, 3 } */ + if( ( ret = mbedtls_asn1_get_int( &p, end, &ver ) ) != 0 ) + return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); + + if( ver < 1 || ver > 3 ) + return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); + + /* + * FieldID { FIELD-ID:IOSet } ::= SEQUENCE { -- Finite field + * fieldType FIELD-ID.&id({IOSet}), + * parameters FIELD-ID.&Type({IOSet}{@fieldType}) + * } + */ + if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) + return( ret ); + + end_field = p + len; + + /* + * FIELD-ID ::= TYPE-IDENTIFIER + * FieldTypes FIELD-ID ::= { + * { Prime-p IDENTIFIED BY prime-field } | + * { Characteristic-two IDENTIFIED BY characteristic-two-field } + * } + * prime-field OBJECT IDENTIFIER ::= { id-fieldType 1 } + */ + if( ( ret = mbedtls_asn1_get_tag( &p, end_field, &len, MBEDTLS_ASN1_OID ) ) != 0 ) + return( ret ); + + if( len != MBEDTLS_OID_SIZE( MBEDTLS_OID_ANSI_X9_62_PRIME_FIELD ) || + memcmp( p, MBEDTLS_OID_ANSI_X9_62_PRIME_FIELD, len ) != 0 ) + { + return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); + } + + p += len; + + /* Prime-p ::= INTEGER -- Field of size p. */ + if( ( ret = mbedtls_asn1_get_mpi( &p, end_field, &grp->P ) ) != 0 ) + return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); + + grp->pbits = mbedtls_mpi_bitlen( &grp->P ); + + if( p != end_field ) + return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + + /* + * Curve ::= SEQUENCE { + * a FieldElement, + * b FieldElement, + * seed BIT STRING OPTIONAL + * -- Shall be present if used in SpecifiedECDomain + * -- with version equal to ecdpVer2 or ecdpVer3 + * } + */ + if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) + return( ret ); + + end_curve = p + len; + + /* + * FieldElement ::= OCTET STRING + * containing an integer in the case of a prime field + */ + if( ( ret = mbedtls_asn1_get_tag( &p, end_curve, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 || + ( ret = mbedtls_mpi_read_binary( &grp->A, p, len ) ) != 0 ) + { + return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); + } + + p += len; + + if( ( ret = mbedtls_asn1_get_tag( &p, end_curve, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 || + ( ret = mbedtls_mpi_read_binary( &grp->B, p, len ) ) != 0 ) + { + return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); + } + + p += len; + + /* Ignore seed BIT STRING OPTIONAL */ + if( ( ret = mbedtls_asn1_get_tag( &p, end_curve, &len, MBEDTLS_ASN1_BIT_STRING ) ) == 0 ) + p += len; + + if( p != end_curve ) + return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + + /* + * ECPoint ::= OCTET STRING + */ + if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ) + return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); + + if( ( ret = mbedtls_ecp_point_read_binary( grp, &grp->G, + ( const unsigned char *) p, len ) ) != 0 ) + { + /* + * If we can't read the point because it's compressed, cheat by + * reading only the X coordinate and the parity bit of Y. + */ + if( ret != MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE || + ( p[0] != 0x02 && p[0] != 0x03 ) || + len != mbedtls_mpi_size( &grp->P ) + 1 || + mbedtls_mpi_read_binary( &grp->G.X, p + 1, len - 1 ) != 0 || + mbedtls_mpi_lset( &grp->G.Y, p[0] - 2 ) != 0 || + mbedtls_mpi_lset( &grp->G.Z, 1 ) != 0 ) + { + return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); + } + } + + p += len; + + /* + * order INTEGER + */ + if( ( ret = mbedtls_asn1_get_mpi( &p, end, &grp->N ) ) != 0 ) + return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); + + grp->nbits = mbedtls_mpi_bitlen( &grp->N ); + + /* + * Allow optional elements by purposefully not enforcing p == end here. + */ + + return( 0 ); +} + +/* + * Find the group id associated with an (almost filled) group as generated by + * pk_group_from_specified(), or return an error if unknown. + */ +static int pk_group_id_from_group( const mbedtls_ecp_group *grp, mbedtls_ecp_group_id *grp_id ) +{ + int ret = 0; + mbedtls_ecp_group ref; + const mbedtls_ecp_group_id *id; + + mbedtls_ecp_group_init( &ref ); + + for( id = mbedtls_ecp_grp_id_list(); *id != MBEDTLS_ECP_DP_NONE; id++ ) + { + /* Load the group associated to that id */ + mbedtls_ecp_group_free( &ref ); + MBEDTLS_MPI_CHK( mbedtls_ecp_group_load( &ref, *id ) ); + + /* Compare to the group we were given, starting with easy tests */ + if( grp->pbits == ref.pbits && grp->nbits == ref.nbits && + mbedtls_mpi_cmp_mpi( &grp->P, &ref.P ) == 0 && + mbedtls_mpi_cmp_mpi( &grp->A, &ref.A ) == 0 && + mbedtls_mpi_cmp_mpi( &grp->B, &ref.B ) == 0 && + mbedtls_mpi_cmp_mpi( &grp->N, &ref.N ) == 0 && + mbedtls_mpi_cmp_mpi( &grp->G.X, &ref.G.X ) == 0 && + mbedtls_mpi_cmp_mpi( &grp->G.Z, &ref.G.Z ) == 0 && + /* For Y we may only know the parity bit, so compare only that */ + mbedtls_mpi_get_bit( &grp->G.Y, 0 ) == mbedtls_mpi_get_bit( &ref.G.Y, 0 ) ) + { + break; + } + + } + +cleanup: + mbedtls_ecp_group_free( &ref ); + + *grp_id = *id; + + if( ret == 0 && *id == MBEDTLS_ECP_DP_NONE ) + ret = MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE; + + return( ret ); +} + +/* + * Parse a SpecifiedECDomain (SEC 1 C.2) and find the associated group ID + */ +static int pk_group_id_from_specified( const mbedtls_asn1_buf *params, + mbedtls_ecp_group_id *grp_id ) +{ + int ret; + mbedtls_ecp_group grp; + + mbedtls_ecp_group_init( &grp ); + + if( ( ret = pk_group_from_specified( params, &grp ) ) != 0 ) + goto cleanup; + + ret = pk_group_id_from_group( &grp, grp_id ); + +cleanup: + mbedtls_ecp_group_free( &grp ); + + return( ret ); +} +#endif /* MBEDTLS_PK_PARSE_EC_EXTENDED */ + +/* + * Use EC parameters to initialise an EC group + * + * ECParameters ::= CHOICE { + * namedCurve OBJECT IDENTIFIER + * specifiedCurve SpecifiedECDomain -- = SEQUENCE { ... } + * -- implicitCurve NULL + */ +static int pk_use_ecparams( const mbedtls_asn1_buf *params, mbedtls_ecp_group *grp ) +{ + int ret; + mbedtls_ecp_group_id grp_id; + + if( params->tag == MBEDTLS_ASN1_OID ) + { + if( mbedtls_oid_get_ec_grp( params, &grp_id ) != 0 ) + return( MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE ); + } + else + { +#if defined(MBEDTLS_PK_PARSE_EC_EXTENDED) + if( ( ret = pk_group_id_from_specified( params, &grp_id ) ) != 0 ) + return( ret ); +#else + return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); +#endif + } + + /* + * grp may already be initilialized; if so, make sure IDs match + */ + if( grp->id != MBEDTLS_ECP_DP_NONE && grp->id != grp_id ) + return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); + + if( ( ret = mbedtls_ecp_group_load( grp, grp_id ) ) != 0 ) + return( ret ); + + return( 0 ); +} + +/* + * EC public key is an EC point + * + * The caller is responsible for clearing the structure upon failure if + * desired. Take care to pass along the possible ECP_FEATURE_UNAVAILABLE + * return code of mbedtls_ecp_point_read_binary() and leave p in a usable state. + */ +static int pk_get_ecpubkey( unsigned char **p, const unsigned char *end, + mbedtls_ecp_keypair *key ) +{ + int ret; + + if( ( ret = mbedtls_ecp_point_read_binary( &key->grp, &key->Q, + (const unsigned char *) *p, end - *p ) ) == 0 ) + { + ret = mbedtls_ecp_check_pubkey( &key->grp, &key->Q ); + } + + /* + * We know mbedtls_ecp_point_read_binary consumed all bytes or failed + */ + *p = (unsigned char *) end; + + return( ret ); +} +#endif /* MBEDTLS_ECP_C */ + +#if defined(MBEDTLS_RSA_C) +/* + * RSAPublicKey ::= SEQUENCE { + * modulus INTEGER, -- n + * publicExponent INTEGER -- e + * } + */ +static int pk_get_rsapubkey( unsigned char **p, + const unsigned char *end, + mbedtls_rsa_context *rsa ) +{ + int ret; + size_t len; +#if defined(MBEDTLS_PK_ALT) + int n_len; + int e_len; + unsigned char *rsa_n; + unsigned char *rsa_e; +#endif + + if( ( ret = mbedtls_asn1_get_tag( p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) + return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret ); + + if( *p + len != end ) + return( MBEDTLS_ERR_PK_INVALID_PUBKEY + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + +#if defined(MBEDTLS_PK_ALT) + if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 ) + return( ret ); + + rsa_n = *p; + n_len = len; + *p += len; + + while(*rsa_n == 0x00) { + rsa_n++; + n_len--; + } + + if( ( ret = mbedtls_asn1_get_tag( p, end, &len, MBEDTLS_ASN1_INTEGER ) ) != 0 ) + return( ret ); + + rsa_e = *p; + e_len = len; + *p += len; + + rsa->n_len = n_len; + rsa->e_len = e_len; + rsa->rsa_n = rsa_n; + rsa->rsa_e = rsa_e; + + MBEDTLS_ALT_DEBUG_BUF(3, "rsa_n", rsa->rsa_n, rsa->n_len); + MBEDTLS_ALT_DEBUG_BUF(3, "rsa_e", rsa->rsa_e, rsa->e_len); + +#else /* MBEDTLS_PK_ALT */ + + if( ( ret = mbedtls_asn1_get_mpi( p, end, &rsa->N ) ) != 0 || + ( ret = mbedtls_asn1_get_mpi( p, end, &rsa->E ) ) != 0 ) + return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret ); + + if( *p != end ) + return( MBEDTLS_ERR_PK_INVALID_PUBKEY + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + + if( ( ret = mbedtls_rsa_check_pubkey( rsa ) ) != 0 ) + return( MBEDTLS_ERR_PK_INVALID_PUBKEY ); + + rsa->len = mbedtls_mpi_size( &rsa->N ); +#endif /* MBEDTLS_PK_ALT */ + + return( 0 ); +} +#endif /* MBEDTLS_RSA_C */ + +/* Get a PK algorithm identifier + * + * AlgorithmIdentifier ::= SEQUENCE { + * algorithm OBJECT IDENTIFIER, + * parameters ANY DEFINED BY algorithm OPTIONAL } + */ +static int pk_get_pk_alg( unsigned char **p, + const unsigned char *end, + mbedtls_pk_type_t *pk_alg, mbedtls_asn1_buf *params ) +{ + int ret; + mbedtls_asn1_buf alg_oid; + + memset( params, 0, sizeof(mbedtls_asn1_buf) ); + + if( ( ret = mbedtls_asn1_get_alg( p, end, &alg_oid, params ) ) != 0 ) + return( MBEDTLS_ERR_PK_INVALID_ALG + ret ); + + +#if defined(MBEDTLS_IOT_SPECIFIC) + if( alg_oid.len != CRT_OID_IDENT_LEN || + memcmp(alg_oid.p, CRT_OID_PKCS1_RSA, CRT_OID_IDENT_LEN ) ) { + MBEDTLS_ALT_DEBUG_BUF(1, "pk_alg_oid", alg_oid.p, alg_oid.len); + return( MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG ); + } else { + *pk_alg = MBEDTLS_PK_RSA; + } +#else + if( mbedtls_oid_get_pk_alg( &alg_oid, pk_alg ) != 0 ) + return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); +#endif /* MBEDTLS_IOT_SPECIFIC */ + + /* + * No parameters with RSA (only for EC) + */ + if( *pk_alg == MBEDTLS_PK_RSA && + ( ( params->tag != MBEDTLS_ASN1_NULL && params->tag != 0 ) || + params->len != 0 ) ) + { + return( MBEDTLS_ERR_PK_INVALID_ALG ); + } + + return( 0 ); +} + +/* + * SubjectPublicKeyInfo ::= SEQUENCE { + * algorithm AlgorithmIdentifier, + * subjectPublicKey BIT STRING } + */ +int mbedtls_pk_parse_subpubkey( unsigned char **p, const unsigned char *end, + mbedtls_pk_context *pk ) +{ + int ret; + size_t len; + mbedtls_asn1_buf alg_params; + mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE; + const mbedtls_pk_info_t *pk_info; + + if( ( ret = mbedtls_asn1_get_tag( p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) + { + return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); + } + + end = *p + len; + + if( ( ret = pk_get_pk_alg( p, end, &pk_alg, &alg_params ) ) != 0 ) + return( ret ); + + if( ( ret = mbedtls_asn1_get_bitstring_null( p, end, &len ) ) != 0 ) + return( MBEDTLS_ERR_PK_INVALID_PUBKEY + ret ); + + if( *p + len != end ) + return( MBEDTLS_ERR_PK_INVALID_PUBKEY + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + + if( ( pk_info = mbedtls_pk_info_from_type( pk_alg ) ) == NULL ) + return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); + + if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 ) + return( ret ); + +#if defined(MBEDTLS_RSA_C) + if( pk_alg == MBEDTLS_PK_RSA ) + { + ret = pk_get_rsapubkey( p, end, mbedtls_pk_rsa( *pk ) ); + } else +#endif /* MBEDTLS_RSA_C */ +#if defined(MBEDTLS_ECP_C) + if( pk_alg == MBEDTLS_PK_ECKEY_DH || pk_alg == MBEDTLS_PK_ECKEY ) + { + ret = pk_use_ecparams( &alg_params, &mbedtls_pk_ec( *pk )->grp ); + if( ret == 0 ) + ret = pk_get_ecpubkey( p, end, mbedtls_pk_ec( *pk ) ); + } else +#endif /* MBEDTLS_ECP_C */ + ret = MBEDTLS_ERR_PK_UNKNOWN_PK_ALG; + + if( ret == 0 && *p != end ) + ret = MBEDTLS_ERR_PK_INVALID_PUBKEY + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH; + + if( ret != 0 ) + mbedtls_pk_free( pk ); + + return( ret ); +} + +#if defined(MBEDTLS_RSA_C) +#if defined(MBEDTLS_RSA_PRIV_ENABLED) +/* + * Parse a PKCS#1 encoded private RSA key + */ +static int pk_parse_key_pkcs1_der( mbedtls_rsa_context *rsa, + const unsigned char *key, + size_t keylen ) +{ + int ret; + size_t len; + unsigned char *p, *end; + + p = (unsigned char *) key; + end = p + keylen; + + /* + * This function parses the RSAPrivateKey (PKCS#1) + * + * RSAPrivateKey ::= SEQUENCE { + * version Version, + * modulus INTEGER, -- n + * publicExponent INTEGER, -- e + * privateExponent INTEGER, -- d + * prime1 INTEGER, -- p + * prime2 INTEGER, -- q + * exponent1 INTEGER, -- d mod (p-1) + * exponent2 INTEGER, -- d mod (q-1) + * coefficient INTEGER, -- (inverse of q) mod p + * otherPrimeInfos OtherPrimeInfos OPTIONAL + * } + */ + if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) + { + return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); + } + + end = p + len; + + if( ( ret = mbedtls_asn1_get_int( &p, end, &rsa->ver ) ) != 0 ) + { + return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); + } + + if( rsa->ver != 0 ) + { + return( MBEDTLS_ERR_PK_KEY_INVALID_VERSION ); + } + + if( ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->N ) ) != 0 || + ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->E ) ) != 0 || + ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->D ) ) != 0 || + ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->P ) ) != 0 || + ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 || + ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 || + ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 || + ( ret = mbedtls_asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 ) + { + mbedtls_rsa_free( rsa ); + return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); + } + + rsa->len = mbedtls_mpi_size( &rsa->N ); + + if( p != end ) + { + mbedtls_rsa_free( rsa ); + return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + } + + if( ( ret = mbedtls_rsa_check_privkey( rsa ) ) != 0 ) + { + mbedtls_rsa_free( rsa ); + return( ret ); + } + + return( 0 ); +} +#endif /* MBEDTLS_RSA_PRIV_ENABLED */ +#endif /* MBEDTLS_RSA_C */ + +#if defined(MBEDTLS_ECP_C) +/* + * Parse a SEC1 encoded private EC key + */ +static int pk_parse_key_sec1_der( mbedtls_ecp_keypair *eck, + const unsigned char *key, + size_t keylen ) +{ + int ret; + int version, pubkey_done; + size_t len; + mbedtls_asn1_buf params; + unsigned char *p = (unsigned char *) key; + unsigned char *end = p + keylen; + unsigned char *end2; + + /* + * RFC 5915, or SEC1 Appendix C.4 + * + * ECPrivateKey ::= SEQUENCE { + * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), + * privateKey OCTET STRING, + * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, + * publicKey [1] BIT STRING OPTIONAL + * } + */ + if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) + { + return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); + } + + end = p + len; + + if( ( ret = mbedtls_asn1_get_int( &p, end, &version ) ) != 0 ) + return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); + + if( version != 1 ) + return( MBEDTLS_ERR_PK_KEY_INVALID_VERSION ); + + if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ) + return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); + + if( ( ret = mbedtls_mpi_read_binary( &eck->d, p, len ) ) != 0 ) + { + mbedtls_ecp_keypair_free( eck ); + return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); + } + + p += len; + + pubkey_done = 0; + if( p != end ) + { + /* + * Is 'parameters' present? + */ + if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, + MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) ) == 0 ) + { + if( ( ret = pk_get_ecparams( &p, p + len, ¶ms) ) != 0 || + ( ret = pk_use_ecparams( ¶ms, &eck->grp ) ) != 0 ) + { + mbedtls_ecp_keypair_free( eck ); + return( ret ); + } + } + else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) + { + mbedtls_ecp_keypair_free( eck ); + return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); + } + + /* + * Is 'publickey' present? If not, or if we can't read it (eg because it + * is compressed), create it from the private key. + */ + if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, + MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 1 ) ) == 0 ) + { + end2 = p + len; + + if( ( ret = mbedtls_asn1_get_bitstring_null( &p, end2, &len ) ) != 0 ) + return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); + + if( p + len != end2 ) + return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + + if( ( ret = pk_get_ecpubkey( &p, end2, eck ) ) == 0 ) + pubkey_done = 1; + else + { + /* + * The only acceptable failure mode of pk_get_ecpubkey() above + * is if the point format is not recognized. + */ + if( ret != MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE ) + return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); + } + } + else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) + { + mbedtls_ecp_keypair_free( eck ); + return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); + } + } + + if( ! pubkey_done && + ( ret = mbedtls_ecp_mul( &eck->grp, &eck->Q, &eck->d, &eck->grp.G, + NULL, NULL ) ) != 0 ) + { + mbedtls_ecp_keypair_free( eck ); + return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); + } + + if( ( ret = mbedtls_ecp_check_privkey( &eck->grp, &eck->d ) ) != 0 ) + { + mbedtls_ecp_keypair_free( eck ); + return( ret ); + } + + return( 0 ); +} +#endif /* MBEDTLS_ECP_C */ + +/* + * Parse an unencrypted PKCS#8 encoded private key + */ +static int pk_parse_key_pkcs8_unencrypted_der( + mbedtls_pk_context *pk, + const unsigned char* key, + size_t keylen ) +{ + int ret, version; + size_t len; + mbedtls_asn1_buf params; + unsigned char *p = (unsigned char *) key; + unsigned char *end = p + keylen; + mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE; + const mbedtls_pk_info_t *pk_info; + + /* + * This function parses the PrivatKeyInfo object (PKCS#8 v1.2 = RFC 5208) + * + * PrivateKeyInfo ::= SEQUENCE { + * version Version, + * privateKeyAlgorithm PrivateKeyAlgorithmIdentifier, + * privateKey PrivateKey, + * attributes [0] IMPLICIT Attributes OPTIONAL } + * + * Version ::= INTEGER + * PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier + * PrivateKey ::= OCTET STRING + * + * The PrivateKey OCTET STRING is a SEC1 ECPrivateKey + */ + + if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) + { + return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); + } + + end = p + len; + + if( ( ret = mbedtls_asn1_get_int( &p, end, &version ) ) != 0 ) + return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); + + if( version != 0 ) + return( MBEDTLS_ERR_PK_KEY_INVALID_VERSION + ret ); + + if( ( ret = pk_get_pk_alg( &p, end, &pk_alg, ¶ms ) ) != 0 ) + return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); + + if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ) + return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); + + if( len < 1 ) + return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + + MBEDTLS_ERR_ASN1_OUT_OF_DATA ); + + if( ( pk_info = mbedtls_pk_info_from_type( pk_alg ) ) == NULL ) + return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); + + if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 ) + return( ret ); + +#if defined(MBEDTLS_RSA_C) +#if defined(MBEDTLS_RSA_PRIV_ENABLED) + if( pk_alg == MBEDTLS_PK_RSA ) + { + if( ( ret = pk_parse_key_pkcs1_der( mbedtls_pk_rsa( *pk ), p, len ) ) != 0 ) + { + mbedtls_pk_free( pk ); + return( ret ); + } + } else +#endif /* MBEDTLS_RSA_PRIV_ENABLED */ +#endif /* MBEDTLS_RSA_C */ +#if defined(MBEDTLS_ECP_C) + if( pk_alg == MBEDTLS_PK_ECKEY || pk_alg == MBEDTLS_PK_ECKEY_DH ) + { + if( ( ret = pk_use_ecparams( ¶ms, &mbedtls_pk_ec( *pk )->grp ) ) != 0 || + ( ret = pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ), p, len ) ) != 0 ) + { + mbedtls_pk_free( pk ); + return( ret ); + } + } else +#endif /* MBEDTLS_ECP_C */ + return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); + + return( 0 ); +} + +/* + * Parse an encrypted PKCS#8 encoded private key + */ +#if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C) +static int pk_parse_key_pkcs8_encrypted_der( + mbedtls_pk_context *pk, + const unsigned char *key, size_t keylen, + const unsigned char *pwd, size_t pwdlen ) +{ + int ret, decrypted = 0; + size_t len; + unsigned char buf[2048]; + unsigned char *p, *end; + mbedtls_asn1_buf pbe_alg_oid, pbe_params; +#if defined(MBEDTLS_PKCS12_C) + mbedtls_cipher_type_t cipher_alg; + mbedtls_md_type_t md_alg; +#endif + + memset( buf, 0, sizeof( buf ) ); + + p = (unsigned char *) key; + end = p + keylen; + + if( pwdlen == 0 ) + return( MBEDTLS_ERR_PK_PASSWORD_REQUIRED ); + + /* + * This function parses the EncryptedPrivatKeyInfo object (PKCS#8) + * + * EncryptedPrivateKeyInfo ::= SEQUENCE { + * encryptionAlgorithm EncryptionAlgorithmIdentifier, + * encryptedData EncryptedData + * } + * + * EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier + * + * EncryptedData ::= OCTET STRING + * + * The EncryptedData OCTET STRING is a PKCS#8 PrivateKeyInfo + */ + if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) + { + return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); + } + + end = p + len; + + if( ( ret = mbedtls_asn1_get_alg( &p, end, &pbe_alg_oid, &pbe_params ) ) != 0 ) + return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); + + if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ) + return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT + ret ); + + if( len > sizeof( buf ) ) + return( MBEDTLS_ERR_PK_BAD_INPUT_DATA ); + + /* + * Decrypt EncryptedData with appropriate PDE + */ +#if defined(MBEDTLS_PKCS12_C) + if( mbedtls_oid_get_pkcs12_pbe_alg( &pbe_alg_oid, &md_alg, &cipher_alg ) == 0 ) + { + if( ( ret = mbedtls_pkcs12_pbe( &pbe_params, MBEDTLS_PKCS12_PBE_DECRYPT, + cipher_alg, md_alg, + pwd, pwdlen, p, len, buf ) ) != 0 ) + { + if( ret == MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH ) + return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH ); + + return( ret ); + } + + decrypted = 1; + } + else if( MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS12_PBE_SHA1_RC4_128, &pbe_alg_oid ) == 0 ) + { + if( ( ret = mbedtls_pkcs12_pbe_sha1_rc4_128( &pbe_params, + MBEDTLS_PKCS12_PBE_DECRYPT, + pwd, pwdlen, + p, len, buf ) ) != 0 ) + { + return( ret ); + } + + // Best guess for password mismatch when using RC4. If first tag is + // not MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE + // + if( *buf != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) + return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH ); + + decrypted = 1; + } + else +#endif /* MBEDTLS_PKCS12_C */ +#if defined(MBEDTLS_PKCS5_C) + if( MBEDTLS_OID_CMP( MBEDTLS_OID_PKCS5_PBES2, &pbe_alg_oid ) == 0 ) + { + if( ( ret = mbedtls_pkcs5_pbes2( &pbe_params, MBEDTLS_PKCS5_DECRYPT, pwd, pwdlen, + p, len, buf ) ) != 0 ) + { + if( ret == MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH ) + return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH ); + + return( ret ); + } + + decrypted = 1; + } + else +#endif /* MBEDTLS_PKCS5_C */ + { + ((void) pwd); + } + + if( decrypted == 0 ) + return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); + + return( pk_parse_key_pkcs8_unencrypted_der( pk, buf, len ) ); +} +#endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */ + +/* + * Parse a private key + */ +int mbedtls_pk_parse_key( mbedtls_pk_context *pk, + const unsigned char *key, size_t keylen, + const unsigned char *pwd, size_t pwdlen ) +{ + int ret; + const mbedtls_pk_info_t *pk_info; + +#if defined(MBEDTLS_PEM_PARSE_C) + size_t len; + mbedtls_pem_context pem; + + mbedtls_pem_init( &pem ); + +#if defined(MBEDTLS_RSA_C) +#if defined(MBEDTLS_RSA_PRIV_ENABLED) + /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ + if( keylen == 0 || key[keylen - 1] != '\0' ) + ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; + else + ret = mbedtls_pem_read_buffer( &pem, + "-----BEGIN RSA PRIVATE KEY-----", + "-----END RSA PRIVATE KEY-----", + key, pwd, pwdlen, &len ); + + if( ret == 0 ) + { + if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == NULL ) + return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); + + if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 || + ( ret = pk_parse_key_pkcs1_der( mbedtls_pk_rsa( *pk ), + pem.buf, pem.buflen ) ) != 0 ) + { + mbedtls_pk_free( pk ); + } + + mbedtls_pem_free( &pem ); + return( ret ); + } + else if( ret == MBEDTLS_ERR_PEM_PASSWORD_MISMATCH ) + return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH ); + else if( ret == MBEDTLS_ERR_PEM_PASSWORD_REQUIRED ) + return( MBEDTLS_ERR_PK_PASSWORD_REQUIRED ); + else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) + return( ret ); +#else + (void)pwd; + (void)pwdlen; + (void)pk_info; +#endif /* MBEDTLS_RSA_PRIV_ENABLED */ +#endif /* MBEDTLS_RSA_C */ + +#if defined(MBEDTLS_ECP_C) + /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ + if( keylen == 0 || key[keylen - 1] != '\0' ) + ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; + else + ret = mbedtls_pem_read_buffer( &pem, + "-----BEGIN EC PRIVATE KEY-----", + "-----END EC PRIVATE KEY-----", + key, pwd, pwdlen, &len ); + if( ret == 0 ) + { + if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_ECKEY ) ) == NULL ) + return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); + + if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 || + ( ret = pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ), + pem.buf, pem.buflen ) ) != 0 ) + { + mbedtls_pk_free( pk ); + } + + mbedtls_pem_free( &pem ); + return( ret ); + } + else if( ret == MBEDTLS_ERR_PEM_PASSWORD_MISMATCH ) + return( MBEDTLS_ERR_PK_PASSWORD_MISMATCH ); + else if( ret == MBEDTLS_ERR_PEM_PASSWORD_REQUIRED ) + return( MBEDTLS_ERR_PK_PASSWORD_REQUIRED ); + else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) + return( ret ); +#endif /* MBEDTLS_ECP_C */ + + /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ + if( keylen == 0 || key[keylen - 1] != '\0' ) + ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; + else + ret = mbedtls_pem_read_buffer( &pem, + "-----BEGIN PRIVATE KEY-----", + "-----END PRIVATE KEY-----", + key, NULL, 0, &len ); + if( ret == 0 ) + { + if( ( ret = pk_parse_key_pkcs8_unencrypted_der( pk, + pem.buf, pem.buflen ) ) != 0 ) + { + mbedtls_pk_free( pk ); + } + + mbedtls_pem_free( &pem ); + return( ret ); + } + else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) + return( ret ); + +#if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C) + /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ + if( keylen == 0 || key[keylen - 1] != '\0' ) + ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; + else + ret = mbedtls_pem_read_buffer( &pem, + "-----BEGIN ENCRYPTED PRIVATE KEY-----", + "-----END ENCRYPTED PRIVATE KEY-----", + key, NULL, 0, &len ); + if( ret == 0 ) + { + if( ( ret = pk_parse_key_pkcs8_encrypted_der( pk, + pem.buf, pem.buflen, + pwd, pwdlen ) ) != 0 ) + { + mbedtls_pk_free( pk ); + } + + mbedtls_pem_free( &pem ); + return( ret ); + } + else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) + return( ret ); +#endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */ +#else + ((void) ret); + ((void) pwd); + ((void) pwdlen); +#endif /* MBEDTLS_PEM_PARSE_C */ + + /* + * At this point we only know it's not a PEM formatted key. Could be any + * of the known DER encoded private key formats + * + * We try the different DER format parsers to see if one passes without + * error + */ +#if defined(MBEDTLS_PKCS12_C) || defined(MBEDTLS_PKCS5_C) + if( ( ret = pk_parse_key_pkcs8_encrypted_der( pk, key, keylen, + pwd, pwdlen ) ) == 0 ) + { + return( 0 ); + } + + mbedtls_pk_free( pk ); + + if( ret == MBEDTLS_ERR_PK_PASSWORD_MISMATCH ) + { + return( ret ); + } +#endif /* MBEDTLS_PKCS12_C || MBEDTLS_PKCS5_C */ + + if( ( ret = pk_parse_key_pkcs8_unencrypted_der( pk, key, keylen ) ) == 0 ) + return( 0 ); + + mbedtls_pk_free( pk ); + +#if defined(MBEDTLS_RSA_C) +#if defined(MBEDTLS_RSA_PRIV_ENABLED) + if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_RSA ) ) == NULL ) + return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); + + if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 || + ( ret = pk_parse_key_pkcs1_der( mbedtls_pk_rsa( *pk ), key, keylen ) ) == 0 ) + { + return( 0 ); + } + + mbedtls_pk_free( pk ); +#endif /* MBEDTLS_RSA_PRIV_ENABLED */ +#endif /* MBEDTLS_RSA_C */ + +#if defined(MBEDTLS_ECP_C) + if( ( pk_info = mbedtls_pk_info_from_type( MBEDTLS_PK_ECKEY ) ) == NULL ) + return( MBEDTLS_ERR_PK_UNKNOWN_PK_ALG ); + + if( ( ret = mbedtls_pk_setup( pk, pk_info ) ) != 0 || + ( ret = pk_parse_key_sec1_der( mbedtls_pk_ec( *pk ), key, keylen ) ) == 0 ) + { + return( 0 ); + } + + mbedtls_pk_free( pk ); +#endif /* MBEDTLS_ECP_C */ + + return( MBEDTLS_ERR_PK_KEY_INVALID_FORMAT ); +} + +/* + * Parse a public key + */ +int mbedtls_pk_parse_public_key( mbedtls_pk_context *ctx, + const unsigned char *key, size_t keylen ) +{ + int ret; + unsigned char *p; +#if defined(MBEDTLS_PEM_PARSE_C) + size_t len; + mbedtls_pem_context pem; + + mbedtls_pem_init( &pem ); + + /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ + if( keylen == 0 || key[keylen - 1] != '\0' ) + ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; + else + ret = mbedtls_pem_read_buffer( &pem, + "-----BEGIN PUBLIC KEY-----", + "-----END PUBLIC KEY-----", + key, NULL, 0, &len ); + + if( ret == 0 ) + { + /* + * Was PEM encoded + */ + key = pem.buf; + keylen = pem.buflen; + } + else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) + { + mbedtls_pem_free( &pem ); + return( ret ); + } +#endif /* MBEDTLS_PEM_PARSE_C */ + p = (unsigned char *) key; + + ret = mbedtls_pk_parse_subpubkey( &p, p + keylen, ctx ); + +#if defined(MBEDTLS_PEM_PARSE_C) + mbedtls_pem_free( &pem ); +#endif + + return( ret ); +} + +#endif /* MBEDTLS_PK_PARSE_C */ diff --git a/security/mbedtls/src/pkwrite.c b/security/mbedtls/src/pkwrite.c new file mode 100644 index 0000000000..83b798c119 --- /dev/null +++ b/security/mbedtls/src/pkwrite.c @@ -0,0 +1,439 @@ +/* + * Public Key layer for writing key files and structures + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_PK_WRITE_C) + +#include "mbedtls/pk.h" +#include "mbedtls/asn1write.h" +#include "mbedtls/oid.h" + +#include + +#if defined(MBEDTLS_RSA_C) +#include "mbedtls/rsa.h" +#endif +#if defined(MBEDTLS_ECP_C) +#include "mbedtls/ecp.h" +#endif +#if defined(MBEDTLS_ECDSA_C) +#include "mbedtls/ecdsa.h" +#endif +#if defined(MBEDTLS_PEM_WRITE_C) +#include "mbedtls/pem.h" +#endif + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_calloc calloc +#define mbedtls_free free +#endif + +#if defined(MBEDTLS_RSA_C) +/* + * RSAPublicKey ::= SEQUENCE { + * modulus INTEGER, -- n + * publicExponent INTEGER -- e + * } + */ +static int pk_write_rsa_pubkey( unsigned char **p, unsigned char *start, + mbedtls_rsa_context *rsa ) +{ + int ret; + size_t len = 0; + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( p, start, &rsa->E ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( p, start, &rsa->N ) ); + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_CONSTRUCTED | + MBEDTLS_ASN1_SEQUENCE ) ); + + return( (int) len ); +} +#endif /* MBEDTLS_RSA_C */ + +#if defined(MBEDTLS_ECP_C) +/* + * EC public key is an EC point + */ +static int pk_write_ec_pubkey( unsigned char **p, unsigned char *start, + mbedtls_ecp_keypair *ec ) +{ + int ret; + size_t len = 0; + unsigned char buf[MBEDTLS_ECP_MAX_PT_LEN]; + + if( ( ret = mbedtls_ecp_point_write_binary( &ec->grp, &ec->Q, + MBEDTLS_ECP_PF_UNCOMPRESSED, + &len, buf, sizeof( buf ) ) ) != 0 ) + { + return( ret ); + } + + if( *p < start || (size_t)( *p - start ) < len ) + return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); + + *p -= len; + memcpy( *p, buf, len ); + + return( (int) len ); +} + +/* + * ECParameters ::= CHOICE { + * namedCurve OBJECT IDENTIFIER + * } + */ +static int pk_write_ec_param( unsigned char **p, unsigned char *start, + mbedtls_ecp_keypair *ec ) +{ + int ret; + size_t len = 0; + const char *oid; + size_t oid_len; + + if( ( ret = mbedtls_oid_get_oid_by_ec_grp( ec->grp.id, &oid, &oid_len ) ) != 0 ) + return( ret ); + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( p, start, oid, oid_len ) ); + + return( (int) len ); +} +#endif /* MBEDTLS_ECP_C */ + +int mbedtls_pk_write_pubkey( unsigned char **p, unsigned char *start, + const mbedtls_pk_context *key ) +{ + int ret; + size_t len = 0; + +#if defined(MBEDTLS_RSA_C) + if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA ) + MBEDTLS_ASN1_CHK_ADD( len, pk_write_rsa_pubkey( p, start, mbedtls_pk_rsa( *key ) ) ); + else +#endif +#if defined(MBEDTLS_ECP_C) + if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY ) + MBEDTLS_ASN1_CHK_ADD( len, pk_write_ec_pubkey( p, start, mbedtls_pk_ec( *key ) ) ); + else +#endif + return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); + + return( (int) len ); +} + +int mbedtls_pk_write_pubkey_der( mbedtls_pk_context *key, unsigned char *buf, size_t size ) +{ + int ret; + unsigned char *c; + size_t len = 0, par_len = 0, oid_len; + const char *oid; + + c = buf + size; + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, key ) ); + + if( c - buf < 1 ) + return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); + + /* + * SubjectPublicKeyInfo ::= SEQUENCE { + * algorithm AlgorithmIdentifier, + * subjectPublicKey BIT STRING } + */ + *--c = 0; + len += 1; + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_BIT_STRING ) ); + + if( ( ret = mbedtls_oid_get_oid_by_pk_alg( mbedtls_pk_get_type( key ), + &oid, &oid_len ) ) != 0 ) + { + return( ret ); + } + +#if defined(MBEDTLS_ECP_C) + if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY ) + { + MBEDTLS_ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, mbedtls_pk_ec( *key ) ) ); + } +#endif + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_algorithm_identifier( &c, buf, oid, oid_len, + par_len ) ); + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED | + MBEDTLS_ASN1_SEQUENCE ) ); + + return( (int) len ); +} + +int mbedtls_pk_write_key_der( mbedtls_pk_context *key, unsigned char *buf, size_t size ) +{ + int ret; + unsigned char *c = buf + size; + size_t len = 0; + +#if defined(MBEDTLS_RSA_C) + if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA ) + { + mbedtls_rsa_context *rsa = mbedtls_pk_rsa( *key ); + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->QP ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->DQ ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->DP ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->Q ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->P ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->D ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->E ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->N ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, 0 ) ); + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED | + MBEDTLS_ASN1_SEQUENCE ) ); + } + else +#endif /* MBEDTLS_RSA_C */ +#if defined(MBEDTLS_ECP_C) + if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY ) + { + mbedtls_ecp_keypair *ec = mbedtls_pk_ec( *key ); + size_t pub_len = 0, par_len = 0; + + /* + * RFC 5915, or SEC1 Appendix C.4 + * + * ECPrivateKey ::= SEQUENCE { + * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), + * privateKey OCTET STRING, + * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, + * publicKey [1] BIT STRING OPTIONAL + * } + */ + + /* publicKey */ + MBEDTLS_ASN1_CHK_ADD( pub_len, pk_write_ec_pubkey( &c, buf, ec ) ); + + if( c - buf < 1 ) + return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); + *--c = 0; + pub_len += 1; + + MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_len( &c, buf, pub_len ) ); + MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_BIT_STRING ) ); + + MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_len( &c, buf, pub_len ) ); + MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_tag( &c, buf, + MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 1 ) ); + len += pub_len; + + /* parameters */ + MBEDTLS_ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, ec ) ); + + MBEDTLS_ASN1_CHK_ADD( par_len, mbedtls_asn1_write_len( &c, buf, par_len ) ); + MBEDTLS_ASN1_CHK_ADD( par_len, mbedtls_asn1_write_tag( &c, buf, + MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) ); + len += par_len; + + /* privateKey: write as MPI then fix tag */ + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &ec->d ) ); + *c = MBEDTLS_ASN1_OCTET_STRING; + + /* version */ + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, 1 ) ); + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED | + MBEDTLS_ASN1_SEQUENCE ) ); + } + else +#endif /* MBEDTLS_ECP_C */ + return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); + + return( (int) len ); +} + +#if defined(MBEDTLS_PEM_WRITE_C) + +#define PEM_BEGIN_PUBLIC_KEY "-----BEGIN PUBLIC KEY-----\n" +#define PEM_END_PUBLIC_KEY "-----END PUBLIC KEY-----\n" + +#define PEM_BEGIN_PRIVATE_KEY_RSA "-----BEGIN RSA PRIVATE KEY-----\n" +#define PEM_END_PRIVATE_KEY_RSA "-----END RSA PRIVATE KEY-----\n" +#define PEM_BEGIN_PRIVATE_KEY_EC "-----BEGIN EC PRIVATE KEY-----\n" +#define PEM_END_PRIVATE_KEY_EC "-----END EC PRIVATE KEY-----\n" + +/* + * Max sizes of key per types. Shown as tag + len (+ content). + */ + +#if defined(MBEDTLS_RSA_C) +/* + * RSA public keys: + * SubjectPublicKeyInfo ::= SEQUENCE { 1 + 3 + * algorithm AlgorithmIdentifier, 1 + 1 (sequence) + * + 1 + 1 + 9 (rsa oid) + * + 1 + 1 (params null) + * subjectPublicKey BIT STRING } 1 + 3 + (1 + below) + * RSAPublicKey ::= SEQUENCE { 1 + 3 + * modulus INTEGER, -- n 1 + 3 + MPI_MAX + 1 + * publicExponent INTEGER -- e 1 + 3 + MPI_MAX + 1 + * } + */ +#define RSA_PUB_DER_MAX_BYTES 38 + 2 * MBEDTLS_MPI_MAX_SIZE + +/* + * RSA private keys: + * RSAPrivateKey ::= SEQUENCE { 1 + 3 + * version Version, 1 + 1 + 1 + * modulus INTEGER, 1 + 3 + MPI_MAX + 1 + * publicExponent INTEGER, 1 + 3 + MPI_MAX + 1 + * privateExponent INTEGER, 1 + 3 + MPI_MAX + 1 + * prime1 INTEGER, 1 + 3 + MPI_MAX / 2 + 1 + * prime2 INTEGER, 1 + 3 + MPI_MAX / 2 + 1 + * exponent1 INTEGER, 1 + 3 + MPI_MAX / 2 + 1 + * exponent2 INTEGER, 1 + 3 + MPI_MAX / 2 + 1 + * coefficient INTEGER, 1 + 3 + MPI_MAX / 2 + 1 + * otherPrimeInfos OtherPrimeInfos OPTIONAL 0 (not supported) + * } + */ +#define MPI_MAX_SIZE_2 MBEDTLS_MPI_MAX_SIZE / 2 + \ + MBEDTLS_MPI_MAX_SIZE % 2 +#define RSA_PRV_DER_MAX_BYTES 47 + 3 * MBEDTLS_MPI_MAX_SIZE \ + + 5 * MPI_MAX_SIZE_2 + +#else /* MBEDTLS_RSA_C */ + +#define RSA_PUB_DER_MAX_BYTES 0 +#define RSA_PRV_DER_MAX_BYTES 0 + +#endif /* MBEDTLS_RSA_C */ + +#if defined(MBEDTLS_ECP_C) +/* + * EC public keys: + * SubjectPublicKeyInfo ::= SEQUENCE { 1 + 2 + * algorithm AlgorithmIdentifier, 1 + 1 (sequence) + * + 1 + 1 + 7 (ec oid) + * + 1 + 1 + 9 (namedCurve oid) + * subjectPublicKey BIT STRING 1 + 2 + 1 [1] + * + 1 (point format) [1] + * + 2 * ECP_MAX (coords) [1] + * } + */ +#define ECP_PUB_DER_MAX_BYTES 30 + 2 * MBEDTLS_ECP_MAX_BYTES + +/* + * EC private keys: + * ECPrivateKey ::= SEQUENCE { 1 + 2 + * version INTEGER , 1 + 1 + 1 + * privateKey OCTET STRING, 1 + 1 + ECP_MAX + * parameters [0] ECParameters OPTIONAL, 1 + 1 + (1 + 1 + 9) + * publicKey [1] BIT STRING OPTIONAL 1 + 2 + [1] above + * } + */ +#define ECP_PRV_DER_MAX_BYTES 29 + 3 * MBEDTLS_ECP_MAX_BYTES + +#else /* MBEDTLS_ECP_C */ + +#define ECP_PUB_DER_MAX_BYTES 0 +#define ECP_PRV_DER_MAX_BYTES 0 + +#endif /* MBEDTLS_ECP_C */ + +#define PUB_DER_MAX_BYTES RSA_PUB_DER_MAX_BYTES > ECP_PUB_DER_MAX_BYTES ? \ + RSA_PUB_DER_MAX_BYTES : ECP_PUB_DER_MAX_BYTES +#define PRV_DER_MAX_BYTES RSA_PRV_DER_MAX_BYTES > ECP_PRV_DER_MAX_BYTES ? \ + RSA_PRV_DER_MAX_BYTES : ECP_PRV_DER_MAX_BYTES + +int mbedtls_pk_write_pubkey_pem( mbedtls_pk_context *key, unsigned char *buf, size_t size ) +{ + int ret; + unsigned char output_buf[PUB_DER_MAX_BYTES]; + size_t olen = 0; + + if( ( ret = mbedtls_pk_write_pubkey_der( key, output_buf, + sizeof(output_buf) ) ) < 0 ) + { + return( ret ); + } + + if( ( ret = mbedtls_pem_write_buffer( PEM_BEGIN_PUBLIC_KEY, PEM_END_PUBLIC_KEY, + output_buf + sizeof(output_buf) - ret, + ret, buf, size, &olen ) ) != 0 ) + { + return( ret ); + } + + return( 0 ); +} + +int mbedtls_pk_write_key_pem( mbedtls_pk_context *key, unsigned char *buf, size_t size ) +{ + int ret; + unsigned char output_buf[PRV_DER_MAX_BYTES]; + const char *begin, *end; + size_t olen = 0; + + if( ( ret = mbedtls_pk_write_key_der( key, output_buf, sizeof(output_buf) ) ) < 0 ) + return( ret ); + +#if defined(MBEDTLS_RSA_C) + if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA ) + { + begin = PEM_BEGIN_PRIVATE_KEY_RSA; + end = PEM_END_PRIVATE_KEY_RSA; + } + else +#endif +#if defined(MBEDTLS_ECP_C) + if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY ) + { + begin = PEM_BEGIN_PRIVATE_KEY_EC; + end = PEM_END_PRIVATE_KEY_EC; + } + else +#endif + return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); + + if( ( ret = mbedtls_pem_write_buffer( begin, end, + output_buf + sizeof(output_buf) - ret, + ret, buf, size, &olen ) ) != 0 ) + { + return( ret ); + } + + return( 0 ); +} +#endif /* MBEDTLS_PEM_WRITE_C */ + +#endif /* MBEDTLS_PK_WRITE_C */ diff --git a/security/mbedtls/src/platform.c b/security/mbedtls/src/platform.c new file mode 100644 index 0000000000..8b336c38ec --- /dev/null +++ b/security/mbedtls/src/platform.c @@ -0,0 +1,307 @@ +/* + * Platform abstraction layer + * + * Copyright (C) 2006-2016, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_PLATFORM_C) + +#include "mbedtls/platform.h" + +#if defined(MBEDTLS_PLATFORM_MEMORY) +#if !defined(MBEDTLS_PLATFORM_STD_CALLOC) +static void *platform_calloc_uninit( size_t n, size_t size ) +{ + ((void) n); + ((void) size); + return( NULL ); +} + +#define MBEDTLS_PLATFORM_STD_CALLOC platform_calloc_uninit +#endif /* !MBEDTLS_PLATFORM_STD_CALLOC */ + +#if !defined(MBEDTLS_PLATFORM_STD_FREE) +static void platform_free_uninit( void *ptr ) +{ + ((void) ptr); +} + +#define MBEDTLS_PLATFORM_STD_FREE platform_free_uninit +#endif /* !MBEDTLS_PLATFORM_STD_FREE */ + +void * (*mbedtls_calloc)( size_t, size_t ) = MBEDTLS_PLATFORM_STD_CALLOC; +void (*mbedtls_free)( void * ) = MBEDTLS_PLATFORM_STD_FREE; + +int mbedtls_platform_set_calloc_free( void * (*calloc_func)( size_t, size_t ), + void (*free_func)( void * ) ) +{ + mbedtls_calloc = calloc_func; + mbedtls_free = free_func; + return( 0 ); +} +#endif /* MBEDTLS_PLATFORM_MEMORY */ + +#if defined(_WIN32) +#include +int mbedtls_platform_win32_snprintf( char *s, size_t n, const char *fmt, ... ) +{ + int ret; + va_list argp; + + /* Avoid calling the invalid parameter handler by checking ourselves */ + if( s == NULL || n == 0 || fmt == NULL ) + return( -1 ); + + va_start( argp, fmt ); +#if defined(_TRUNCATE) + ret = _vsnprintf_s( s, n, _TRUNCATE, fmt, argp ); +#else + ret = _vsnprintf( s, n, fmt, argp ); + if( ret < 0 || (size_t) ret == n ) + { + s[n-1] = '\0'; + ret = -1; + } +#endif + va_end( argp ); + + return( ret ); +} +#endif + +#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) +#if !defined(MBEDTLS_PLATFORM_STD_SNPRINTF) +/* + * Make dummy function to prevent NULL pointer dereferences + */ +static int platform_snprintf_uninit( char * s, size_t n, + const char * format, ... ) +{ + ((void) s); + ((void) n); + ((void) format); + return( 0 ); +} + +#define MBEDTLS_PLATFORM_STD_SNPRINTF platform_snprintf_uninit +#endif /* !MBEDTLS_PLATFORM_STD_SNPRINTF */ + +int (*mbedtls_snprintf)( char * s, size_t n, + const char * format, + ... ) = MBEDTLS_PLATFORM_STD_SNPRINTF; + +int mbedtls_platform_set_snprintf( int (*snprintf_func)( char * s, size_t n, + const char * format, + ... ) ) +{ + mbedtls_snprintf = snprintf_func; + return( 0 ); +} +#endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */ + +#if defined(MBEDTLS_PLATFORM_PRINTF_ALT) +#if !defined(MBEDTLS_PLATFORM_STD_PRINTF) +/* + * Make dummy function to prevent NULL pointer dereferences + */ +static int platform_printf_uninit( const char *format, ... ) +{ + ((void) format); + return( 0 ); +} + +#define MBEDTLS_PLATFORM_STD_PRINTF platform_printf_uninit +#endif /* !MBEDTLS_PLATFORM_STD_PRINTF */ + +int (*mbedtls_printf)( const char *, ... ) = MBEDTLS_PLATFORM_STD_PRINTF; + +int mbedtls_platform_set_printf( int (*printf_func)( const char *, ... ) ) +{ + mbedtls_printf = printf_func; + return( 0 ); +} +#endif /* MBEDTLS_PLATFORM_PRINTF_ALT */ + +#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT) +#if !defined(MBEDTLS_PLATFORM_STD_FPRINTF) +/* + * Make dummy function to prevent NULL pointer dereferences + */ +static int platform_fprintf_uninit( FILE *stream, const char *format, ... ) +{ + ((void) stream); + ((void) format); + return( 0 ); +} + +#define MBEDTLS_PLATFORM_STD_FPRINTF platform_fprintf_uninit +#endif /* !MBEDTLS_PLATFORM_STD_FPRINTF */ + +int (*mbedtls_fprintf)( FILE *, const char *, ... ) = + MBEDTLS_PLATFORM_STD_FPRINTF; + +int mbedtls_platform_set_fprintf( int (*fprintf_func)( FILE *, const char *, ... ) ) +{ + mbedtls_fprintf = fprintf_func; + return( 0 ); +} +#endif /* MBEDTLS_PLATFORM_FPRINTF_ALT */ + +#if defined(MBEDTLS_PLATFORM_EXIT_ALT) +#if !defined(MBEDTLS_PLATFORM_STD_EXIT) +/* + * Make dummy function to prevent NULL pointer dereferences + */ +static void platform_exit_uninit( int status ) +{ + ((void) status); +} + +#define MBEDTLS_PLATFORM_STD_EXIT platform_exit_uninit +#endif /* !MBEDTLS_PLATFORM_STD_EXIT */ + +void (*mbedtls_exit)( int status ) = MBEDTLS_PLATFORM_STD_EXIT; + +int mbedtls_platform_set_exit( void (*exit_func)( int status ) ) +{ + mbedtls_exit = exit_func; + return( 0 ); +} +#endif /* MBEDTLS_PLATFORM_EXIT_ALT */ + +#if defined(MBEDTLS_HAVE_TIME) + +#if defined(MBEDTLS_PLATFORM_TIME_ALT) +#if !defined(MBEDTLS_PLATFORM_STD_TIME) +/* + * Make dummy function to prevent NULL pointer dereferences + */ +static mbedtls_time_t platform_time_uninit( mbedtls_time_t* timer ) +{ + ((void) timer); + return( 0 ); +} + +#define MBEDTLS_PLATFORM_STD_TIME platform_time_uninit +#endif /* !MBEDTLS_PLATFORM_STD_TIME */ + +mbedtls_time_t (*mbedtls_time)( mbedtls_time_t* timer ) = MBEDTLS_PLATFORM_STD_TIME; + +int mbedtls_platform_set_time( mbedtls_time_t (*time_func)( mbedtls_time_t* timer ) ) +{ + mbedtls_time = time_func; + return( 0 ); +} +#endif /* MBEDTLS_PLATFORM_TIME_ALT */ + +#endif /* MBEDTLS_HAVE_TIME */ + +#if defined(MBEDTLS_ENTROPY_NV_SEED) +#if !defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) && defined(MBEDTLS_FS_IO) +/* Default implementations for the platform independent seed functions use + * standard libc file functions to read from and write to a pre-defined filename + */ +int mbedtls_platform_std_nv_seed_read( unsigned char *buf, size_t buf_len ) +{ + FILE *file; + size_t n; + + if( ( file = fopen( MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "rb" ) ) == NULL ) + return -1; + + if( ( n = fread( buf, 1, buf_len, file ) ) != buf_len ) + { + fclose( file ); + return -1; + } + + fclose( file ); + return( (int)n ); +} + +int mbedtls_platform_std_nv_seed_write( unsigned char *buf, size_t buf_len ) +{ + FILE *file; + size_t n; + + if( ( file = fopen( MBEDTLS_PLATFORM_STD_NV_SEED_FILE, "w" ) ) == NULL ) + return -1; + + if( ( n = fwrite( buf, 1, buf_len, file ) ) != buf_len ) + { + fclose( file ); + return -1; + } + + fclose( file ); + return( (int)n ); +} +#endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */ + +#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT) +#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_READ) +/* + * Make dummy function to prevent NULL pointer dereferences + */ +static int platform_nv_seed_read_uninit( unsigned char *buf, size_t buf_len ) +{ + ((void) buf); + ((void) buf_len); + return( -1 ); +} + +#define MBEDTLS_PLATFORM_STD_NV_SEED_READ platform_nv_seed_read_uninit +#endif /* !MBEDTLS_PLATFORM_STD_NV_SEED_READ */ + +#if !defined(MBEDTLS_PLATFORM_STD_NV_SEED_WRITE) +/* + * Make dummy function to prevent NULL pointer dereferences + */ +static int platform_nv_seed_write_uninit( unsigned char *buf, size_t buf_len ) +{ + ((void) buf); + ((void) buf_len); + return( -1 ); +} + +#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE platform_nv_seed_write_uninit +#endif /* !MBEDTLS_PLATFORM_STD_NV_SEED_WRITE */ + +int (*mbedtls_nv_seed_read)( unsigned char *buf, size_t buf_len ) = + MBEDTLS_PLATFORM_STD_NV_SEED_READ; +int (*mbedtls_nv_seed_write)( unsigned char *buf, size_t buf_len ) = + MBEDTLS_PLATFORM_STD_NV_SEED_WRITE; + +int mbedtls_platform_set_nv_seed( + int (*nv_seed_read_func)( unsigned char *buf, size_t buf_len ), + int (*nv_seed_write_func)( unsigned char *buf, size_t buf_len ) ) +{ + mbedtls_nv_seed_read = nv_seed_read_func; + mbedtls_nv_seed_write = nv_seed_write_func; + return( 0 ); +} +#endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */ +#endif /* MBEDTLS_ENTROPY_NV_SEED */ + +#endif /* MBEDTLS_PLATFORM_C */ diff --git a/security/mbedtls/src/ripemd160.c b/security/mbedtls/src/ripemd160.c new file mode 100644 index 0000000000..cdb0a63c0f --- /dev/null +++ b/security/mbedtls/src/ripemd160.c @@ -0,0 +1,467 @@ +/* + * RIPE MD-160 implementation + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +/* + * The RIPEMD-160 algorithm was designed by RIPE in 1996 + * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html + * http://ehash.iaik.tugraz.at/wiki/RIPEMD-160 + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_RIPEMD160_C) + +#include "mbedtls/ripemd160.h" + +#include + +#if defined(MBEDTLS_SELF_TEST) +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_printf printf +#endif /* MBEDTLS_PLATFORM_C */ +#endif /* MBEDTLS_SELF_TEST */ + +/* + * 32-bit integer manipulation macros (little endian) + */ +#ifndef GET_UINT32_LE +#define GET_UINT32_LE(n,b,i) \ +{ \ + (n) = ( (uint32_t) (b)[(i) ] ) \ + | ( (uint32_t) (b)[(i) + 1] << 8 ) \ + | ( (uint32_t) (b)[(i) + 2] << 16 ) \ + | ( (uint32_t) (b)[(i) + 3] << 24 ); \ +} +#endif + +#ifndef PUT_UINT32_LE +#define PUT_UINT32_LE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \ + (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \ + (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \ + (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \ +} +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +void mbedtls_ripemd160_init( mbedtls_ripemd160_context *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_ripemd160_context ) ); +} + +void mbedtls_ripemd160_free( mbedtls_ripemd160_context *ctx ) +{ + if( ctx == NULL ) + return; + + mbedtls_zeroize( ctx, sizeof( mbedtls_ripemd160_context ) ); +} + +void mbedtls_ripemd160_clone( mbedtls_ripemd160_context *dst, + const mbedtls_ripemd160_context *src ) +{ + *dst = *src; +} + +/* + * RIPEMD-160 context setup + */ +void mbedtls_ripemd160_starts( mbedtls_ripemd160_context *ctx ) +{ + ctx->total[0] = 0; + ctx->total[1] = 0; + + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + ctx->state[3] = 0x10325476; + ctx->state[4] = 0xC3D2E1F0; +} + +#if !defined(MBEDTLS_RIPEMD160_PROCESS_ALT) +/* + * Process one block + */ +void mbedtls_ripemd160_process( mbedtls_ripemd160_context *ctx, const unsigned char data[64] ) +{ + uint32_t A, B, C, D, E, Ap, Bp, Cp, Dp, Ep, X[16]; + + GET_UINT32_LE( X[ 0], data, 0 ); + GET_UINT32_LE( X[ 1], data, 4 ); + GET_UINT32_LE( X[ 2], data, 8 ); + GET_UINT32_LE( X[ 3], data, 12 ); + GET_UINT32_LE( X[ 4], data, 16 ); + GET_UINT32_LE( X[ 5], data, 20 ); + GET_UINT32_LE( X[ 6], data, 24 ); + GET_UINT32_LE( X[ 7], data, 28 ); + GET_UINT32_LE( X[ 8], data, 32 ); + GET_UINT32_LE( X[ 9], data, 36 ); + GET_UINT32_LE( X[10], data, 40 ); + GET_UINT32_LE( X[11], data, 44 ); + GET_UINT32_LE( X[12], data, 48 ); + GET_UINT32_LE( X[13], data, 52 ); + GET_UINT32_LE( X[14], data, 56 ); + GET_UINT32_LE( X[15], data, 60 ); + + A = Ap = ctx->state[0]; + B = Bp = ctx->state[1]; + C = Cp = ctx->state[2]; + D = Dp = ctx->state[3]; + E = Ep = ctx->state[4]; + +#define F1( x, y, z ) ( x ^ y ^ z ) +#define F2( x, y, z ) ( ( x & y ) | ( ~x & z ) ) +#define F3( x, y, z ) ( ( x | ~y ) ^ z ) +#define F4( x, y, z ) ( ( x & z ) | ( y & ~z ) ) +#define F5( x, y, z ) ( x ^ ( y | ~z ) ) + +#define S( x, n ) ( ( x << n ) | ( x >> (32 - n) ) ) + +#define P( a, b, c, d, e, r, s, f, k ) \ + a += f( b, c, d ) + X[r] + k; \ + a = S( a, s ) + e; \ + c = S( c, 10 ); + +#define P2( a, b, c, d, e, r, s, rp, sp ) \ + P( a, b, c, d, e, r, s, F, K ); \ + P( a ## p, b ## p, c ## p, d ## p, e ## p, rp, sp, Fp, Kp ); + +#define F F1 +#define K 0x00000000 +#define Fp F5 +#define Kp 0x50A28BE6 + P2( A, B, C, D, E, 0, 11, 5, 8 ); + P2( E, A, B, C, D, 1, 14, 14, 9 ); + P2( D, E, A, B, C, 2, 15, 7, 9 ); + P2( C, D, E, A, B, 3, 12, 0, 11 ); + P2( B, C, D, E, A, 4, 5, 9, 13 ); + P2( A, B, C, D, E, 5, 8, 2, 15 ); + P2( E, A, B, C, D, 6, 7, 11, 15 ); + P2( D, E, A, B, C, 7, 9, 4, 5 ); + P2( C, D, E, A, B, 8, 11, 13, 7 ); + P2( B, C, D, E, A, 9, 13, 6, 7 ); + P2( A, B, C, D, E, 10, 14, 15, 8 ); + P2( E, A, B, C, D, 11, 15, 8, 11 ); + P2( D, E, A, B, C, 12, 6, 1, 14 ); + P2( C, D, E, A, B, 13, 7, 10, 14 ); + P2( B, C, D, E, A, 14, 9, 3, 12 ); + P2( A, B, C, D, E, 15, 8, 12, 6 ); +#undef F +#undef K +#undef Fp +#undef Kp + +#define F F2 +#define K 0x5A827999 +#define Fp F4 +#define Kp 0x5C4DD124 + P2( E, A, B, C, D, 7, 7, 6, 9 ); + P2( D, E, A, B, C, 4, 6, 11, 13 ); + P2( C, D, E, A, B, 13, 8, 3, 15 ); + P2( B, C, D, E, A, 1, 13, 7, 7 ); + P2( A, B, C, D, E, 10, 11, 0, 12 ); + P2( E, A, B, C, D, 6, 9, 13, 8 ); + P2( D, E, A, B, C, 15, 7, 5, 9 ); + P2( C, D, E, A, B, 3, 15, 10, 11 ); + P2( B, C, D, E, A, 12, 7, 14, 7 ); + P2( A, B, C, D, E, 0, 12, 15, 7 ); + P2( E, A, B, C, D, 9, 15, 8, 12 ); + P2( D, E, A, B, C, 5, 9, 12, 7 ); + P2( C, D, E, A, B, 2, 11, 4, 6 ); + P2( B, C, D, E, A, 14, 7, 9, 15 ); + P2( A, B, C, D, E, 11, 13, 1, 13 ); + P2( E, A, B, C, D, 8, 12, 2, 11 ); +#undef F +#undef K +#undef Fp +#undef Kp + +#define F F3 +#define K 0x6ED9EBA1 +#define Fp F3 +#define Kp 0x6D703EF3 + P2( D, E, A, B, C, 3, 11, 15, 9 ); + P2( C, D, E, A, B, 10, 13, 5, 7 ); + P2( B, C, D, E, A, 14, 6, 1, 15 ); + P2( A, B, C, D, E, 4, 7, 3, 11 ); + P2( E, A, B, C, D, 9, 14, 7, 8 ); + P2( D, E, A, B, C, 15, 9, 14, 6 ); + P2( C, D, E, A, B, 8, 13, 6, 6 ); + P2( B, C, D, E, A, 1, 15, 9, 14 ); + P2( A, B, C, D, E, 2, 14, 11, 12 ); + P2( E, A, B, C, D, 7, 8, 8, 13 ); + P2( D, E, A, B, C, 0, 13, 12, 5 ); + P2( C, D, E, A, B, 6, 6, 2, 14 ); + P2( B, C, D, E, A, 13, 5, 10, 13 ); + P2( A, B, C, D, E, 11, 12, 0, 13 ); + P2( E, A, B, C, D, 5, 7, 4, 7 ); + P2( D, E, A, B, C, 12, 5, 13, 5 ); +#undef F +#undef K +#undef Fp +#undef Kp + +#define F F4 +#define K 0x8F1BBCDC +#define Fp F2 +#define Kp 0x7A6D76E9 + P2( C, D, E, A, B, 1, 11, 8, 15 ); + P2( B, C, D, E, A, 9, 12, 6, 5 ); + P2( A, B, C, D, E, 11, 14, 4, 8 ); + P2( E, A, B, C, D, 10, 15, 1, 11 ); + P2( D, E, A, B, C, 0, 14, 3, 14 ); + P2( C, D, E, A, B, 8, 15, 11, 14 ); + P2( B, C, D, E, A, 12, 9, 15, 6 ); + P2( A, B, C, D, E, 4, 8, 0, 14 ); + P2( E, A, B, C, D, 13, 9, 5, 6 ); + P2( D, E, A, B, C, 3, 14, 12, 9 ); + P2( C, D, E, A, B, 7, 5, 2, 12 ); + P2( B, C, D, E, A, 15, 6, 13, 9 ); + P2( A, B, C, D, E, 14, 8, 9, 12 ); + P2( E, A, B, C, D, 5, 6, 7, 5 ); + P2( D, E, A, B, C, 6, 5, 10, 15 ); + P2( C, D, E, A, B, 2, 12, 14, 8 ); +#undef F +#undef K +#undef Fp +#undef Kp + +#define F F5 +#define K 0xA953FD4E +#define Fp F1 +#define Kp 0x00000000 + P2( B, C, D, E, A, 4, 9, 12, 8 ); + P2( A, B, C, D, E, 0, 15, 15, 5 ); + P2( E, A, B, C, D, 5, 5, 10, 12 ); + P2( D, E, A, B, C, 9, 11, 4, 9 ); + P2( C, D, E, A, B, 7, 6, 1, 12 ); + P2( B, C, D, E, A, 12, 8, 5, 5 ); + P2( A, B, C, D, E, 2, 13, 8, 14 ); + P2( E, A, B, C, D, 10, 12, 7, 6 ); + P2( D, E, A, B, C, 14, 5, 6, 8 ); + P2( C, D, E, A, B, 1, 12, 2, 13 ); + P2( B, C, D, E, A, 3, 13, 13, 6 ); + P2( A, B, C, D, E, 8, 14, 14, 5 ); + P2( E, A, B, C, D, 11, 11, 0, 15 ); + P2( D, E, A, B, C, 6, 8, 3, 13 ); + P2( C, D, E, A, B, 15, 5, 9, 11 ); + P2( B, C, D, E, A, 13, 6, 11, 11 ); +#undef F +#undef K +#undef Fp +#undef Kp + + C = ctx->state[1] + C + Dp; + ctx->state[1] = ctx->state[2] + D + Ep; + ctx->state[2] = ctx->state[3] + E + Ap; + ctx->state[3] = ctx->state[4] + A + Bp; + ctx->state[4] = ctx->state[0] + B + Cp; + ctx->state[0] = C; +} +#endif /* !MBEDTLS_RIPEMD160_PROCESS_ALT */ + +/* + * RIPEMD-160 process buffer + */ +void mbedtls_ripemd160_update( mbedtls_ripemd160_context *ctx, + const unsigned char *input, size_t ilen ) +{ + size_t fill; + uint32_t left; + + if( ilen == 0 ) + return; + + left = ctx->total[0] & 0x3F; + fill = 64 - left; + + ctx->total[0] += (uint32_t) ilen; + ctx->total[0] &= 0xFFFFFFFF; + + if( ctx->total[0] < (uint32_t) ilen ) + ctx->total[1]++; + + if( left && ilen >= fill ) + { + memcpy( (void *) (ctx->buffer + left), input, fill ); + mbedtls_ripemd160_process( ctx, ctx->buffer ); + input += fill; + ilen -= fill; + left = 0; + } + + while( ilen >= 64 ) + { + mbedtls_ripemd160_process( ctx, input ); + input += 64; + ilen -= 64; + } + + if( ilen > 0 ) + { + memcpy( (void *) (ctx->buffer + left), input, ilen ); + } +} + +static const unsigned char ripemd160_padding[64] = +{ + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* + * RIPEMD-160 final digest + */ +void mbedtls_ripemd160_finish( mbedtls_ripemd160_context *ctx, unsigned char output[20] ) +{ + uint32_t last, padn; + uint32_t high, low; + unsigned char msglen[8]; + + high = ( ctx->total[0] >> 29 ) + | ( ctx->total[1] << 3 ); + low = ( ctx->total[0] << 3 ); + + PUT_UINT32_LE( low, msglen, 0 ); + PUT_UINT32_LE( high, msglen, 4 ); + + last = ctx->total[0] & 0x3F; + padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); + + mbedtls_ripemd160_update( ctx, ripemd160_padding, padn ); + mbedtls_ripemd160_update( ctx, msglen, 8 ); + + PUT_UINT32_LE( ctx->state[0], output, 0 ); + PUT_UINT32_LE( ctx->state[1], output, 4 ); + PUT_UINT32_LE( ctx->state[2], output, 8 ); + PUT_UINT32_LE( ctx->state[3], output, 12 ); + PUT_UINT32_LE( ctx->state[4], output, 16 ); +} + +/* + * output = RIPEMD-160( input buffer ) + */ +void mbedtls_ripemd160( const unsigned char *input, size_t ilen, + unsigned char output[20] ) +{ + mbedtls_ripemd160_context ctx; + + mbedtls_ripemd160_init( &ctx ); + mbedtls_ripemd160_starts( &ctx ); + mbedtls_ripemd160_update( &ctx, input, ilen ); + mbedtls_ripemd160_finish( &ctx, output ); + mbedtls_ripemd160_free( &ctx ); +} + +#if defined(MBEDTLS_SELF_TEST) +/* + * Test vectors from the RIPEMD-160 paper and + * http://homes.esat.kuleuven.be/~bosselae/mbedtls_ripemd160.html#HMAC + */ +#define TESTS 8 +#define KEYS 2 +static const char *ripemd160_test_input[TESTS] = +{ + "", + "a", + "abc", + "message digest", + "abcdefghijklmnopqrstuvwxyz", + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + "1234567890123456789012345678901234567890" + "1234567890123456789012345678901234567890", +}; + +static const unsigned char ripemd160_test_md[TESTS][20] = +{ + { 0x9c, 0x11, 0x85, 0xa5, 0xc5, 0xe9, 0xfc, 0x54, 0x61, 0x28, + 0x08, 0x97, 0x7e, 0xe8, 0xf5, 0x48, 0xb2, 0x25, 0x8d, 0x31 }, + { 0x0b, 0xdc, 0x9d, 0x2d, 0x25, 0x6b, 0x3e, 0xe9, 0xda, 0xae, + 0x34, 0x7b, 0xe6, 0xf4, 0xdc, 0x83, 0x5a, 0x46, 0x7f, 0xfe }, + { 0x8e, 0xb2, 0x08, 0xf7, 0xe0, 0x5d, 0x98, 0x7a, 0x9b, 0x04, + 0x4a, 0x8e, 0x98, 0xc6, 0xb0, 0x87, 0xf1, 0x5a, 0x0b, 0xfc }, + { 0x5d, 0x06, 0x89, 0xef, 0x49, 0xd2, 0xfa, 0xe5, 0x72, 0xb8, + 0x81, 0xb1, 0x23, 0xa8, 0x5f, 0xfa, 0x21, 0x59, 0x5f, 0x36 }, + { 0xf7, 0x1c, 0x27, 0x10, 0x9c, 0x69, 0x2c, 0x1b, 0x56, 0xbb, + 0xdc, 0xeb, 0x5b, 0x9d, 0x28, 0x65, 0xb3, 0x70, 0x8d, 0xbc }, + { 0x12, 0xa0, 0x53, 0x38, 0x4a, 0x9c, 0x0c, 0x88, 0xe4, 0x05, + 0xa0, 0x6c, 0x27, 0xdc, 0xf4, 0x9a, 0xda, 0x62, 0xeb, 0x2b }, + { 0xb0, 0xe2, 0x0b, 0x6e, 0x31, 0x16, 0x64, 0x02, 0x86, 0xed, + 0x3a, 0x87, 0xa5, 0x71, 0x30, 0x79, 0xb2, 0x1f, 0x51, 0x89 }, + { 0x9b, 0x75, 0x2e, 0x45, 0x57, 0x3d, 0x4b, 0x39, 0xf4, 0xdb, + 0xd3, 0x32, 0x3c, 0xab, 0x82, 0xbf, 0x63, 0x32, 0x6b, 0xfb }, +}; + +/* + * Checkup routine + */ +int mbedtls_ripemd160_self_test( int verbose ) +{ + int i; + unsigned char output[20]; + + memset( output, 0, sizeof output ); + + for( i = 0; i < TESTS; i++ ) + { + if( verbose != 0 ) + mbedtls_printf( " RIPEMD-160 test #%d: ", i + 1 ); + + mbedtls_ripemd160( (const unsigned char *) ripemd160_test_input[i], + strlen( ripemd160_test_input[i] ), + output ); + + if( memcmp( output, ripemd160_test_md[i], 20 ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + + return( 0 ); +} + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_RIPEMD160_C */ diff --git a/security/mbedtls/src/rsa.c b/security/mbedtls/src/rsa.c new file mode 100644 index 0000000000..17471eff91 --- /dev/null +++ b/security/mbedtls/src/rsa.c @@ -0,0 +1,1784 @@ +/* + * The RSA public-key cryptosystem + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +/* + * The following sources were referenced in the design of this implementation + * of the RSA algorithm: + * + * [1] A method for obtaining digital signatures and public-key cryptosystems + * R Rivest, A Shamir, and L Adleman + * http://people.csail.mit.edu/rivest/pubs.html#RSA78 + * + * [2] Handbook of Applied Cryptography - 1997, Chapter 8 + * Menezes, van Oorschot and Vanstone + * + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if !defined(MBEDTLS_PK_ALT) + +#if defined(MBEDTLS_RSA_C) + +#include "mbedtls/rsa.h" +#include "mbedtls/oid.h" + +#include + +#if defined(MBEDTLS_PKCS1_V21) +#include "mbedtls/md.h" +#endif + +#if defined(MBEDTLS_PKCS1_V15) && !defined(__OpenBSD__) +#include +#endif + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_printf printf +#define mbedtls_calloc calloc +#define mbedtls_free free +#endif + +/* + * Initialize an RSA context + */ +void mbedtls_rsa_init( mbedtls_rsa_context *ctx, + int padding, + int hash_id ) +{ + memset( ctx, 0, sizeof( mbedtls_rsa_context ) ); + + mbedtls_rsa_set_padding( ctx, padding, hash_id ); + +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_init( &ctx->mutex ); +#endif +} + +/* + * Set padding for an existing RSA context + */ +void mbedtls_rsa_set_padding( mbedtls_rsa_context *ctx, int padding, int hash_id ) +{ + ctx->padding = padding; + ctx->hash_id = hash_id; +} + +#if defined(MBEDTLS_GENPRIME) + +/* + * Generate an RSA keypair + */ +int mbedtls_rsa_gen_key( mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + unsigned int nbits, int exponent ) +{ + int ret; + mbedtls_mpi P1, Q1, H, G; + + if( f_rng == NULL || nbits < 128 || exponent < 3 ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + + if( nbits % 2 ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + + mbedtls_mpi_init( &P1 ); mbedtls_mpi_init( &Q1 ); + mbedtls_mpi_init( &H ); mbedtls_mpi_init( &G ); + + /* + * find primes P and Q with Q < P so that: + * GCD( E, (P-1)*(Q-1) ) == 1 + */ + MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &ctx->E, exponent ) ); + + do + { + MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->P, nbits >> 1, 0, + f_rng, p_rng ) ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_gen_prime( &ctx->Q, nbits >> 1, 0, + f_rng, p_rng ) ); + + if( mbedtls_mpi_cmp_mpi( &ctx->P, &ctx->Q ) == 0 ) + continue; + + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->N, &ctx->P, &ctx->Q ) ); + if( mbedtls_mpi_bitlen( &ctx->N ) != nbits ) + continue; + + if( mbedtls_mpi_cmp_mpi( &ctx->P, &ctx->Q ) < 0 ) + mbedtls_mpi_swap( &ctx->P, &ctx->Q ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &P1, &ctx->P, 1 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &Q1, &ctx->Q, 1 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &H, &P1, &Q1 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, &ctx->E, &H ) ); + } + while( mbedtls_mpi_cmp_int( &G, 1 ) != 0 ); + + /* + * D = E^-1 mod ((P-1)*(Q-1)) + * DP = D mod (P - 1) + * DQ = D mod (Q - 1) + * QP = Q^-1 mod P + */ + MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->D , &ctx->E, &H ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->DP, &ctx->D, &P1 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->DQ, &ctx->D, &Q1 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->QP, &ctx->Q, &ctx->P ) ); + + ctx->len = ( mbedtls_mpi_bitlen( &ctx->N ) + 7 ) >> 3; + +cleanup: + + mbedtls_mpi_free( &P1 ); mbedtls_mpi_free( &Q1 ); mbedtls_mpi_free( &H ); mbedtls_mpi_free( &G ); + + if( ret != 0 ) + { + mbedtls_rsa_free( ctx ); + return( MBEDTLS_ERR_RSA_KEY_GEN_FAILED + ret ); + } + + return( 0 ); +} + +#endif /* MBEDTLS_GENPRIME */ + +/* + * Check a public RSA key + */ +int mbedtls_rsa_check_pubkey( const mbedtls_rsa_context *ctx ) +{ + if( !ctx->N.p || !ctx->E.p ) + return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); + + if( ( ctx->N.p[0] & 1 ) == 0 || + ( ctx->E.p[0] & 1 ) == 0 ) + return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); + + if( mbedtls_mpi_bitlen( &ctx->N ) < 128 || + mbedtls_mpi_bitlen( &ctx->N ) > MBEDTLS_MPI_MAX_BITS ) + return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); + + if( mbedtls_mpi_bitlen( &ctx->E ) < 2 || + mbedtls_mpi_cmp_mpi( &ctx->E, &ctx->N ) >= 0 ) + return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); + + return( 0 ); +} + +#if defined(MBEDTLS_RSA_PRIV_ENABLED) +/* + * Check a private RSA key + */ +int mbedtls_rsa_check_privkey( const mbedtls_rsa_context *ctx ) +{ + int ret; + mbedtls_mpi PQ, DE, P1, Q1, H, I, G, G2, L1, L2, DP, DQ, QP; + + if( ( ret = mbedtls_rsa_check_pubkey( ctx ) ) != 0 ) + return( ret ); + + if( !ctx->P.p || !ctx->Q.p || !ctx->D.p ) + return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); + + mbedtls_mpi_init( &PQ ); mbedtls_mpi_init( &DE ); mbedtls_mpi_init( &P1 ); mbedtls_mpi_init( &Q1 ); + mbedtls_mpi_init( &H ); mbedtls_mpi_init( &I ); mbedtls_mpi_init( &G ); mbedtls_mpi_init( &G2 ); + mbedtls_mpi_init( &L1 ); mbedtls_mpi_init( &L2 ); mbedtls_mpi_init( &DP ); mbedtls_mpi_init( &DQ ); + mbedtls_mpi_init( &QP ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &PQ, &ctx->P, &ctx->Q ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &DE, &ctx->D, &ctx->E ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &P1, &ctx->P, 1 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &Q1, &ctx->Q, 1 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &H, &P1, &Q1 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, &ctx->E, &H ) ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G2, &P1, &Q1 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( &L1, &L2, &H, &G2 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &I, &DE, &L1 ) ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &DP, &ctx->D, &P1 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &DQ, &ctx->D, &Q1 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &QP, &ctx->Q, &ctx->P ) ); + /* + * Check for a valid PKCS1v2 private key + */ + if( mbedtls_mpi_cmp_mpi( &PQ, &ctx->N ) != 0 || + mbedtls_mpi_cmp_mpi( &DP, &ctx->DP ) != 0 || + mbedtls_mpi_cmp_mpi( &DQ, &ctx->DQ ) != 0 || + mbedtls_mpi_cmp_mpi( &QP, &ctx->QP ) != 0 || + mbedtls_mpi_cmp_int( &L2, 0 ) != 0 || + mbedtls_mpi_cmp_int( &I, 1 ) != 0 || + mbedtls_mpi_cmp_int( &G, 1 ) != 0 ) + { + ret = MBEDTLS_ERR_RSA_KEY_CHECK_FAILED; + } + +cleanup: + mbedtls_mpi_free( &PQ ); mbedtls_mpi_free( &DE ); mbedtls_mpi_free( &P1 ); mbedtls_mpi_free( &Q1 ); + mbedtls_mpi_free( &H ); mbedtls_mpi_free( &I ); mbedtls_mpi_free( &G ); mbedtls_mpi_free( &G2 ); + mbedtls_mpi_free( &L1 ); mbedtls_mpi_free( &L2 ); mbedtls_mpi_free( &DP ); mbedtls_mpi_free( &DQ ); + mbedtls_mpi_free( &QP ); + + if( ret == MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ) + return( ret ); + + if( ret != 0 ) + return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED + ret ); + + return( 0 ); +} + +/* + * Check if contexts holding a public and private key match + */ +int mbedtls_rsa_check_pub_priv( const mbedtls_rsa_context *pub, const mbedtls_rsa_context *prv ) +{ + if( mbedtls_rsa_check_pubkey( pub ) != 0 || + mbedtls_rsa_check_privkey( prv ) != 0 ) + { + return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); + } + + if( mbedtls_mpi_cmp_mpi( &pub->N, &prv->N ) != 0 || + mbedtls_mpi_cmp_mpi( &pub->E, &prv->E ) != 0 ) + { + return( MBEDTLS_ERR_RSA_KEY_CHECK_FAILED ); + } + + return( 0 ); +} +#endif /* MBEDTLS_RSA_PRIV_ENABLED */ + +/* + * Do an RSA public key operation + */ +int mbedtls_rsa_public( mbedtls_rsa_context *ctx, + const unsigned char *input, + unsigned char *output ) +{ + int ret; + size_t olen; + mbedtls_mpi T; + + mbedtls_mpi_init( &T ); + +#if defined(MBEDTLS_THREADING_C) + if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) + return( ret ); +#endif + + MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &T, input, ctx->len ) ); + + if( mbedtls_mpi_cmp_mpi( &T, &ctx->N ) >= 0 ) + { + ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA; + goto cleanup; + } + + olen = ctx->len; + MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, &T, &ctx->E, &ctx->N, &ctx->RN ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &T, output, olen ) ); + +cleanup: +#if defined(MBEDTLS_THREADING_C) + if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) + return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); +#endif + + mbedtls_mpi_free( &T ); + + if( ret != 0 ) + return( MBEDTLS_ERR_RSA_PUBLIC_FAILED + ret ); + + return( 0 ); +} + +#if defined(MBEDTLS_RSA_PRIV_ENABLED) +/* + * Generate or update blinding values, see section 10 of: + * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA, + * DSS, and other systems. In : Advances in Cryptology-CRYPTO'96. Springer + * Berlin Heidelberg, 1996. p. 104-113. + */ +static int rsa_prepare_blinding( mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) +{ + int ret, count = 0; + + if( ctx->Vf.p != NULL ) + { + /* We already have blinding values, just update them by squaring */ + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->N ) ); + + goto cleanup; + } + + /* Unblinding value: Vf = random number, invertible mod N */ + do { + if( count++ > 10 ) + return( MBEDTLS_ERR_RSA_RNG_FAILED ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &ctx->Vf, ctx->len - 1, f_rng, p_rng ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &ctx->Vi, &ctx->Vf, &ctx->N ) ); + } while( mbedtls_mpi_cmp_int( &ctx->Vi, 1 ) != 0 ); + + /* Blinding value: Vi = Vf^(-e) mod N */ + MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &ctx->Vi, &ctx->Vf, &ctx->N ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &ctx->Vi, &ctx->Vi, &ctx->E, &ctx->N, &ctx->RN ) ); + + +cleanup: + return( ret ); +} + +/* + * Do an RSA private key operation + */ +int mbedtls_rsa_private( mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + const unsigned char *input, + unsigned char *output ) +{ + int ret; + size_t olen; + mbedtls_mpi T, T1, T2; + + /* Make sure we have private key info, prevent possible misuse */ + if( ctx->P.p == NULL || ctx->Q.p == NULL || ctx->D.p == NULL ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + + mbedtls_mpi_init( &T ); mbedtls_mpi_init( &T1 ); mbedtls_mpi_init( &T2 ); + +#if defined(MBEDTLS_THREADING_C) + if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) + return( ret ); +#endif + + MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( &T, input, ctx->len ) ); + if( mbedtls_mpi_cmp_mpi( &T, &ctx->N ) >= 0 ) + { + ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA; + goto cleanup; + } + + if( f_rng != NULL ) + { + /* + * Blinding + * T = T * Vi mod N + */ + MBEDTLS_MPI_CHK( rsa_prepare_blinding( ctx, f_rng, p_rng ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vi ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) ); + } + +#if defined(MBEDTLS_RSA_NO_CRT) + MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T, &T, &ctx->D, &ctx->N, &ctx->RN ) ); +#else + /* + * faster decryption using the CRT + * + * T1 = input ^ dP mod P + * T2 = input ^ dQ mod Q + */ + MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T1, &T, &ctx->DP, &ctx->P, &ctx->RP ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &T2, &T, &ctx->DQ, &ctx->Q, &ctx->RQ ) ); + + /* + * T = (T1 - T2) * (Q^-1 mod P) mod P + */ + MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &T, &T1, &T2 ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T1, &T, &ctx->QP ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T1, &ctx->P ) ); + + /* + * T = T2 + T * Q + */ + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T1, &T, &ctx->Q ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &T, &T2, &T1 ) ); +#endif /* MBEDTLS_RSA_NO_CRT */ + + if( f_rng != NULL ) + { + /* + * Unblind + * T = T * Vf mod N + */ + MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &T, &ctx->Vf ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &T, &T, &ctx->N ) ); + } + + olen = ctx->len; + MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &T, output, olen ) ); + +cleanup: +#if defined(MBEDTLS_THREADING_C) + if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) + return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); +#endif + + mbedtls_mpi_free( &T ); mbedtls_mpi_free( &T1 ); mbedtls_mpi_free( &T2 ); + + if( ret != 0 ) + return( MBEDTLS_ERR_RSA_PRIVATE_FAILED + ret ); + + return( 0 ); +} +#endif /* MBEDTLS_RSA_PRIV_ENABLED */ + +#if defined(MBEDTLS_PKCS1_V21) +/** + * Generate and apply the MGF1 operation (from PKCS#1 v2.1) to a buffer. + * + * \param dst buffer to mask + * \param dlen length of destination buffer + * \param src source of the mask generation + * \param slen length of the source buffer + * \param md_ctx message digest context to use + */ +static void mgf_mask( unsigned char *dst, size_t dlen, unsigned char *src, + size_t slen, mbedtls_md_context_t *md_ctx ) +{ + unsigned char mask[MBEDTLS_MD_MAX_SIZE]; + unsigned char counter[4]; + unsigned char *p; + unsigned int hlen; + size_t i, use_len; + + memset( mask, 0, MBEDTLS_MD_MAX_SIZE ); + memset( counter, 0, 4 ); + + hlen = mbedtls_md_get_size( md_ctx->md_info ); + + /* Generate and apply dbMask */ + p = dst; + + while( dlen > 0 ) + { + use_len = hlen; + if( dlen < hlen ) + use_len = dlen; + + mbedtls_md_starts( md_ctx ); + mbedtls_md_update( md_ctx, src, slen ); + mbedtls_md_update( md_ctx, counter, 4 ); + mbedtls_md_finish( md_ctx, mask ); + + for( i = 0; i < use_len; ++i ) + *p++ ^= mask[i]; + + counter[3]++; + + dlen -= use_len; + } +} +#endif /* MBEDTLS_PKCS1_V21 */ + +#if defined(MBEDTLS_PKCS1_V21) +/* + * Implementation of the PKCS#1 v2.1 RSAES-OAEP-ENCRYPT function + */ +int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + const unsigned char *label, size_t label_len, + size_t ilen, + const unsigned char *input, + unsigned char *output ) +{ + size_t olen; + int ret; + unsigned char *p = output; + unsigned int hlen; + const mbedtls_md_info_t *md_info; + mbedtls_md_context_t md_ctx; + +#if defined(MBEDTLS_RSA_PRIV_ENABLED) + if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); +#else + if( mode != MBEDTLS_RSA_PUBLIC ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); +#endif /* MBEDTLS_RSA_PRIV_ENABLED */ + + if( f_rng == NULL ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + + md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id ); + if( md_info == NULL ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + + olen = ctx->len; + hlen = mbedtls_md_get_size( md_info ); + + /* first comparison checks for overflow */ + if( ilen + 2 * hlen + 2 < ilen || olen < ilen + 2 * hlen + 2 ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + + memset( output, 0, olen ); + + *p++ = 0; + + /* Generate a random octet string seed */ + if( ( ret = f_rng( p_rng, p, hlen ) ) != 0 ) + return( MBEDTLS_ERR_RSA_RNG_FAILED + ret ); + + p += hlen; + + /* Construct DB */ + mbedtls_md( md_info, label, label_len, p ); + p += hlen; + p += olen - 2 * hlen - 2 - ilen; + *p++ = 1; + memcpy( p, input, ilen ); + + mbedtls_md_init( &md_ctx ); + if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 ) + { + mbedtls_md_free( &md_ctx ); + return( ret ); + } + + /* maskedDB: Apply dbMask to DB */ + mgf_mask( output + hlen + 1, olen - hlen - 1, output + 1, hlen, + &md_ctx ); + + /* maskedSeed: Apply seedMask to seed */ + mgf_mask( output + 1, hlen, output + hlen + 1, olen - hlen - 1, + &md_ctx ); + + mbedtls_md_free( &md_ctx ); + +#if defined(MBEDTLS_RSA_PRIV_ENABLED) + return( ( mode == MBEDTLS_RSA_PUBLIC ) + ? mbedtls_rsa_public( ctx, output, output ) + : mbedtls_rsa_private( ctx, f_rng, p_rng, output, output ) ); +#else + return ( mbedtls_rsa_public( ctx, output, output ); +#endif +} +#endif /* MBEDTLS_PKCS1_V21 */ + +#if defined(MBEDTLS_PKCS1_V15) +/* + * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-ENCRYPT function + */ +int mbedtls_rsa_rsaes_pkcs1_v15_encrypt( mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, size_t ilen, + const unsigned char *input, + unsigned char *output ) +{ + size_t nb_pad, olen; + int ret; + unsigned char *p = output; + +#if defined(MBEDTLS_RSA_PRIV_ENABLED) + if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); +#else + if( mode != MBEDTLS_RSA_PUBLIC ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); +#endif /* MBEDTLS_RSA_PRIV_ENABLED */ + + // We don't check p_rng because it won't be dereferenced here + if( f_rng == NULL || input == NULL || output == NULL ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + + olen = ctx->len; + + /* first comparison checks for overflow */ + if( ilen + 11 < ilen || olen < ilen + 11 ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + + nb_pad = olen - 3 - ilen; + + *p++ = 0; + if( mode == MBEDTLS_RSA_PUBLIC ) + { + *p++ = MBEDTLS_RSA_CRYPT; + + while( nb_pad-- > 0 ) + { + int rng_dl = 100; + + do { + ret = f_rng( p_rng, p, 1 ); + } while( *p == 0 && --rng_dl && ret == 0 ); + + /* Check if RNG failed to generate data */ + if( rng_dl == 0 || ret != 0 ) + return( MBEDTLS_ERR_RSA_RNG_FAILED + ret ); + + p++; + } + } + else + { + *p++ = MBEDTLS_RSA_SIGN; + + while( nb_pad-- > 0 ) + *p++ = 0xFF; + } + + *p++ = 0; + memcpy( p, input, ilen ); + +#if defined(MBEDTLS_RSA_PRIV_ENABLED) + return( ( mode == MBEDTLS_RSA_PUBLIC ) + ? mbedtls_rsa_public( ctx, output, output ) + : mbedtls_rsa_private( ctx, f_rng, p_rng, output, output ) ); +#else + return (mbedtls_rsa_public( ctx, output, output ) ); +#endif +} +#endif /* MBEDTLS_PKCS1_V15 */ + +/* + * Add the message padding, then do an RSA operation + */ +int mbedtls_rsa_pkcs1_encrypt( mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, size_t ilen, + const unsigned char *input, + unsigned char *output ) +{ + switch( ctx->padding ) + { +#if defined(MBEDTLS_PKCS1_V15) + case MBEDTLS_RSA_PKCS_V15: + return mbedtls_rsa_rsaes_pkcs1_v15_encrypt( ctx, f_rng, p_rng, mode, ilen, + input, output ); +#endif + +#if defined(MBEDTLS_PKCS1_V21) + case MBEDTLS_RSA_PKCS_V21: + return mbedtls_rsa_rsaes_oaep_encrypt( ctx, f_rng, p_rng, mode, NULL, 0, + ilen, input, output ); +#endif + + default: + return( MBEDTLS_ERR_RSA_INVALID_PADDING ); + } +} + +#if defined(MBEDTLS_RSA_PRIV_ENABLED) +#if defined(MBEDTLS_PKCS1_V21) +/* + * Implementation of the PKCS#1 v2.1 RSAES-OAEP-DECRYPT function + */ +int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + const unsigned char *label, size_t label_len, + size_t *olen, + const unsigned char *input, + unsigned char *output, + size_t output_max_len ) +{ + int ret; + size_t ilen, i, pad_len; + unsigned char *p, bad, pad_done; + unsigned char buf[MBEDTLS_MPI_MAX_SIZE]; + unsigned char lhash[MBEDTLS_MD_MAX_SIZE]; + unsigned int hlen; + const mbedtls_md_info_t *md_info; + mbedtls_md_context_t md_ctx; + + /* + * Parameters sanity checks + */ + if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + + ilen = ctx->len; + + if( ilen < 16 || ilen > sizeof( buf ) ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + + md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id ); + if( md_info == NULL ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + + hlen = mbedtls_md_get_size( md_info ); + + // checking for integer underflow + if( 2 * hlen + 2 > ilen ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + + /* + * RSA operation + */ + ret = ( mode == MBEDTLS_RSA_PUBLIC ) + ? mbedtls_rsa_public( ctx, input, buf ) + : mbedtls_rsa_private( ctx, f_rng, p_rng, input, buf ); + + if( ret != 0 ) + return( ret ); + + /* + * Unmask data and generate lHash + */ + mbedtls_md_init( &md_ctx ); + if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 ) + { + mbedtls_md_free( &md_ctx ); + return( ret ); + } + + + /* Generate lHash */ + mbedtls_md( md_info, label, label_len, lhash ); + + /* seed: Apply seedMask to maskedSeed */ + mgf_mask( buf + 1, hlen, buf + hlen + 1, ilen - hlen - 1, + &md_ctx ); + + /* DB: Apply dbMask to maskedDB */ + mgf_mask( buf + hlen + 1, ilen - hlen - 1, buf + 1, hlen, + &md_ctx ); + + mbedtls_md_free( &md_ctx ); + + /* + * Check contents, in "constant-time" + */ + p = buf; + bad = 0; + + bad |= *p++; /* First byte must be 0 */ + + p += hlen; /* Skip seed */ + + /* Check lHash */ + for( i = 0; i < hlen; i++ ) + bad |= lhash[i] ^ *p++; + + /* Get zero-padding len, but always read till end of buffer + * (minus one, for the 01 byte) */ + pad_len = 0; + pad_done = 0; + for( i = 0; i < ilen - 2 * hlen - 2; i++ ) + { + pad_done |= p[i]; + pad_len += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1; + } + + p += pad_len; + bad |= *p++ ^ 0x01; + + /* + * The only information "leaked" is whether the padding was correct or not + * (eg, no data is copied if it was not correct). This meets the + * recommendations in PKCS#1 v2.2: an opponent cannot distinguish between + * the different error conditions. + */ + if( bad != 0 ) + return( MBEDTLS_ERR_RSA_INVALID_PADDING ); + + if( ilen - ( p - buf ) > output_max_len ) + return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE ); + + *olen = ilen - (p - buf); + memcpy( output, p, *olen ); + + return( 0 ); +} +#endif /* MBEDTLS_PKCS1_V21 */ + +#if defined(MBEDTLS_PKCS1_V15) +/* + * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-DECRYPT function + */ +int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, size_t *olen, + const unsigned char *input, + unsigned char *output, + size_t output_max_len) +{ + int ret; + size_t ilen, pad_count = 0, i; + unsigned char *p, bad, pad_done = 0; + unsigned char buf[MBEDTLS_MPI_MAX_SIZE]; + + if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + + ilen = ctx->len; + + if( ilen < 16 || ilen > sizeof( buf ) ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + + ret = ( mode == MBEDTLS_RSA_PUBLIC ) + ? mbedtls_rsa_public( ctx, input, buf ) + : mbedtls_rsa_private( ctx, f_rng, p_rng, input, buf ); + + if( ret != 0 ) + return( ret ); + + p = buf; + bad = 0; + + /* + * Check and get padding len in "constant-time" + */ + bad |= *p++; /* First byte must be 0 */ + + /* This test does not depend on secret data */ + if( mode == MBEDTLS_RSA_PRIVATE ) + { + bad |= *p++ ^ MBEDTLS_RSA_CRYPT; + + /* Get padding len, but always read till end of buffer + * (minus one, for the 00 byte) */ + for( i = 0; i < ilen - 3; i++ ) + { + pad_done |= ((p[i] | (unsigned char)-p[i]) >> 7) ^ 1; + pad_count += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1; + } + + p += pad_count; + bad |= *p++; /* Must be zero */ + } + else + { + bad |= *p++ ^ MBEDTLS_RSA_SIGN; + + /* Get padding len, but always read till end of buffer + * (minus one, for the 00 byte) */ + for( i = 0; i < ilen - 3; i++ ) + { + pad_done |= ( p[i] != 0xFF ); + pad_count += ( pad_done == 0 ); + } + + p += pad_count; + bad |= *p++; /* Must be zero */ + } + + bad |= ( pad_count < 8 ); + + if( bad ) + return( MBEDTLS_ERR_RSA_INVALID_PADDING ); + + if( ilen - ( p - buf ) > output_max_len ) + return( MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE ); + + *olen = ilen - (p - buf); + memcpy( output, p, *olen ); + + return( 0 ); +} +#endif /* MBEDTLS_PKCS1_V15 */ + +/* + * Do an RSA operation, then remove the message padding + */ +int mbedtls_rsa_pkcs1_decrypt( mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, size_t *olen, + const unsigned char *input, + unsigned char *output, + size_t output_max_len) +{ + switch( ctx->padding ) + { +#if defined(MBEDTLS_PKCS1_V15) + case MBEDTLS_RSA_PKCS_V15: + return mbedtls_rsa_rsaes_pkcs1_v15_decrypt( ctx, f_rng, p_rng, mode, olen, + input, output, output_max_len ); +#endif + +#if defined(MBEDTLS_PKCS1_V21) + case MBEDTLS_RSA_PKCS_V21: + return mbedtls_rsa_rsaes_oaep_decrypt( ctx, f_rng, p_rng, mode, NULL, 0, + olen, input, output, + output_max_len ); +#endif + + default: + return( MBEDTLS_ERR_RSA_INVALID_PADDING ); + } +} + +#if defined(MBEDTLS_PKCS1_V21) +/* + * Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function + */ +int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + mbedtls_md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + unsigned char *sig ) +{ + size_t olen; + unsigned char *p = sig; + unsigned char salt[MBEDTLS_MD_MAX_SIZE]; + unsigned int slen, hlen, offset = 0; + int ret; + size_t msb; + const mbedtls_md_info_t *md_info; + mbedtls_md_context_t md_ctx; + + if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + + if( f_rng == NULL ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + + olen = ctx->len; + + if( md_alg != MBEDTLS_MD_NONE ) + { + /* Gather length of hash to sign */ + md_info = mbedtls_md_info_from_type( md_alg ); + if( md_info == NULL ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + + hashlen = mbedtls_md_get_size( md_info ); + } + + md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id ); + if( md_info == NULL ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + + hlen = mbedtls_md_get_size( md_info ); + slen = hlen; + + if( olen < hlen + slen + 2 ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + + memset( sig, 0, olen ); + + /* Generate salt of length slen */ + if( ( ret = f_rng( p_rng, salt, slen ) ) != 0 ) + return( MBEDTLS_ERR_RSA_RNG_FAILED + ret ); + + /* Note: EMSA-PSS encoding is over the length of N - 1 bits */ + msb = mbedtls_mpi_bitlen( &ctx->N ) - 1; + p += olen - hlen * 2 - 2; + *p++ = 0x01; + memcpy( p, salt, slen ); + p += slen; + + mbedtls_md_init( &md_ctx ); + if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 ) + { + mbedtls_md_free( &md_ctx ); + return( ret ); + } + + /* Generate H = Hash( M' ) */ + mbedtls_md_starts( &md_ctx ); + mbedtls_md_update( &md_ctx, p, 8 ); + mbedtls_md_update( &md_ctx, hash, hashlen ); + mbedtls_md_update( &md_ctx, salt, slen ); + mbedtls_md_finish( &md_ctx, p ); + + /* Compensate for boundary condition when applying mask */ + if( msb % 8 == 0 ) + offset = 1; + + /* maskedDB: Apply dbMask to DB */ + mgf_mask( sig + offset, olen - hlen - 1 - offset, p, hlen, &md_ctx ); + + mbedtls_md_free( &md_ctx ); + + msb = mbedtls_mpi_bitlen( &ctx->N ) - 1; + sig[0] &= 0xFF >> ( olen * 8 - msb ); + + p += hlen; + *p++ = 0xBC; + + return( ( mode == MBEDTLS_RSA_PUBLIC ) + ? mbedtls_rsa_public( ctx, sig, sig ) + : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig ) ); +} +#endif /* MBEDTLS_PKCS1_V21 */ + +#if defined(MBEDTLS_PKCS1_V15) +/* + * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-V1_5-SIGN function + */ +/* + * Do an RSA operation to sign the message digest + */ +int mbedtls_rsa_rsassa_pkcs1_v15_sign( mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + mbedtls_md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + unsigned char *sig ) +{ + size_t nb_pad, olen, oid_size = 0; + unsigned char *p = sig; + const char *oid = NULL; + unsigned char *sig_try = NULL, *verif = NULL; + size_t i; + unsigned char diff; + volatile unsigned char diff_no_optimize; + int ret; + + if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + + olen = ctx->len; + nb_pad = olen - 3; + + if( md_alg != MBEDTLS_MD_NONE ) + { + const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg ); + if( md_info == NULL ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + + if( mbedtls_oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + + nb_pad -= 10 + oid_size; + + hashlen = mbedtls_md_get_size( md_info ); + } + + nb_pad -= hashlen; + + if( ( nb_pad < 8 ) || ( nb_pad > olen ) ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + + *p++ = 0; + *p++ = MBEDTLS_RSA_SIGN; + memset( p, 0xFF, nb_pad ); + p += nb_pad; + *p++ = 0; + + if( md_alg == MBEDTLS_MD_NONE ) + { + memcpy( p, hash, hashlen ); + } + else + { + /* + * DigestInfo ::= SEQUENCE { + * digestAlgorithm DigestAlgorithmIdentifier, + * digest Digest } + * + * DigestAlgorithmIdentifier ::= AlgorithmIdentifier + * + * Digest ::= OCTET STRING + */ + *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED; + *p++ = (unsigned char) ( 0x08 + oid_size + hashlen ); + *p++ = MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED; + *p++ = (unsigned char) ( 0x04 + oid_size ); + *p++ = MBEDTLS_ASN1_OID; + *p++ = oid_size & 0xFF; + memcpy( p, oid, oid_size ); + p += oid_size; + *p++ = MBEDTLS_ASN1_NULL; + *p++ = 0x00; + *p++ = MBEDTLS_ASN1_OCTET_STRING; + *p++ = hashlen; + memcpy( p, hash, hashlen ); + } + + if( mode == MBEDTLS_RSA_PUBLIC ) + return( mbedtls_rsa_public( ctx, sig, sig ) ); + + /* + * In order to prevent Lenstra's attack, make the signature in a + * temporary buffer and check it before returning it. + */ + sig_try = mbedtls_calloc( 1, ctx->len ); + if( sig_try == NULL ) + return( MBEDTLS_ERR_MPI_ALLOC_FAILED ); + + verif = mbedtls_calloc( 1, ctx->len ); + if( verif == NULL ) + { + mbedtls_free( sig_try ); + return( MBEDTLS_ERR_MPI_ALLOC_FAILED ); + } + + MBEDTLS_MPI_CHK( mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig_try ) ); + MBEDTLS_MPI_CHK( mbedtls_rsa_public( ctx, sig_try, verif ) ); + + /* Compare in constant time just in case */ + for( diff = 0, i = 0; i < ctx->len; i++ ) + diff |= verif[i] ^ sig[i]; + diff_no_optimize = diff; + + if( diff_no_optimize != 0 ) + { + ret = MBEDTLS_ERR_RSA_PRIVATE_FAILED; + goto cleanup; + } + + memcpy( sig, sig_try, ctx->len ); + +cleanup: + mbedtls_free( sig_try ); + mbedtls_free( verif ); + + return( ret ); +} +#endif /* MBEDTLS_PKCS1_V15 */ + +/* + * Do an RSA operation to sign the message digest + */ +int mbedtls_rsa_pkcs1_sign( mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + mbedtls_md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + unsigned char *sig ) +{ + switch( ctx->padding ) + { +#if defined(MBEDTLS_PKCS1_V15) + case MBEDTLS_RSA_PKCS_V15: + return mbedtls_rsa_rsassa_pkcs1_v15_sign( ctx, f_rng, p_rng, mode, md_alg, + hashlen, hash, sig ); +#endif + +#if defined(MBEDTLS_PKCS1_V21) + case MBEDTLS_RSA_PKCS_V21: + return mbedtls_rsa_rsassa_pss_sign( ctx, f_rng, p_rng, mode, md_alg, + hashlen, hash, sig ); +#endif + + default: + return( MBEDTLS_ERR_RSA_INVALID_PADDING ); + } +} +#endif /* MBEDTLS_RSA_PRIV_ENABLED */ + +#if defined(MBEDTLS_PKCS1_V21) +/* + * Implementation of the PKCS#1 v2.1 RSASSA-PSS-VERIFY function + */ +int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + mbedtls_md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + mbedtls_md_type_t mgf1_hash_id, + int expected_salt_len, + const unsigned char *sig ) +{ + int ret; + size_t siglen; + unsigned char *p; + unsigned char result[MBEDTLS_MD_MAX_SIZE]; + unsigned char zeros[8]; + unsigned int hlen; + size_t slen, msb; + const mbedtls_md_info_t *md_info; + mbedtls_md_context_t md_ctx; + unsigned char buf[MBEDTLS_MPI_MAX_SIZE]; + +#if defined(MBEDTLS_RSA_PRIV_ENABLED) + if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); +#else + if( mode != MBEDTLS_RSA_PUBLIC ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); +#endif /* MBEDTLS_RSA_PRIV_ENABLED */ + + siglen = ctx->len; + + if( siglen < 16 || siglen > sizeof( buf ) ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + +#if defined(MBEDTLS_RSA_PRIV_ENABLED) + ret = ( mode == MBEDTLS_RSA_PUBLIC ) + ? mbedtls_rsa_public( ctx, sig, buf ) + : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, buf ); +#else + ret = mbedtls_rsa_public( ctx, sig, buf ); +#endif + + if( ret != 0 ) + return( ret ); + + p = buf; + + if( buf[siglen - 1] != 0xBC ) + return( MBEDTLS_ERR_RSA_INVALID_PADDING ); + + if( md_alg != MBEDTLS_MD_NONE ) + { + /* Gather length of hash to sign */ + md_info = mbedtls_md_info_from_type( md_alg ); + if( md_info == NULL ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + + hashlen = mbedtls_md_get_size( md_info ); + } + + md_info = mbedtls_md_info_from_type( mgf1_hash_id ); + if( md_info == NULL ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + + hlen = mbedtls_md_get_size( md_info ); + slen = siglen - hlen - 1; /* Currently length of salt + padding */ + + memset( zeros, 0, 8 ); + + /* + * Note: EMSA-PSS verification is over the length of N - 1 bits + */ + msb = mbedtls_mpi_bitlen( &ctx->N ) - 1; + + /* Compensate for boundary condition when applying mask */ + if( msb % 8 == 0 ) + { + p++; + siglen -= 1; + } + if( buf[0] >> ( 8 - siglen * 8 + msb ) ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + + mbedtls_md_init( &md_ctx ); + if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) ) != 0 ) + { + mbedtls_md_free( &md_ctx ); + return( ret ); + } + + mgf_mask( p, siglen - hlen - 1, p + siglen - hlen - 1, hlen, &md_ctx ); + + buf[0] &= 0xFF >> ( siglen * 8 - msb ); + + while( p < buf + siglen && *p == 0 ) + p++; + + if( p == buf + siglen || + *p++ != 0x01 ) + { + mbedtls_md_free( &md_ctx ); + return( MBEDTLS_ERR_RSA_INVALID_PADDING ); + } + + /* Actual salt len */ + slen -= p - buf; + + if( expected_salt_len != MBEDTLS_RSA_SALT_LEN_ANY && + slen != (size_t) expected_salt_len ) + { + mbedtls_md_free( &md_ctx ); + return( MBEDTLS_ERR_RSA_INVALID_PADDING ); + } + + /* + * Generate H = Hash( M' ) + */ + mbedtls_md_starts( &md_ctx ); + mbedtls_md_update( &md_ctx, zeros, 8 ); + mbedtls_md_update( &md_ctx, hash, hashlen ); + mbedtls_md_update( &md_ctx, p, slen ); + mbedtls_md_finish( &md_ctx, result ); + + mbedtls_md_free( &md_ctx ); + + if( memcmp( p + slen, result, hlen ) == 0 ) + return( 0 ); + else + return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); +} + +/* + * Simplified PKCS#1 v2.1 RSASSA-PSS-VERIFY function + */ +int mbedtls_rsa_rsassa_pss_verify( mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + mbedtls_md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + const unsigned char *sig ) +{ + mbedtls_md_type_t mgf1_hash_id = ( ctx->hash_id != MBEDTLS_MD_NONE ) + ? (mbedtls_md_type_t) ctx->hash_id + : md_alg; + + return( mbedtls_rsa_rsassa_pss_verify_ext( ctx, f_rng, p_rng, mode, + md_alg, hashlen, hash, + mgf1_hash_id, MBEDTLS_RSA_SALT_LEN_ANY, + sig ) ); + +} +#endif /* MBEDTLS_PKCS1_V21 */ + +#if defined(MBEDTLS_PKCS1_V15) +/* + * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-v1_5-VERIFY function + */ +int mbedtls_rsa_rsassa_pkcs1_v15_verify( mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + mbedtls_md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + const unsigned char *sig ) +{ + int ret; + size_t len, siglen, asn1_len; + unsigned char *p, *end; +#if !defined(MBEDTLS_IOT_SPECIFIC) + mbedtls_md_type_t msg_md_alg; +#endif + const mbedtls_md_info_t *md_info; + mbedtls_asn1_buf oid; + unsigned char buf[MBEDTLS_MPI_MAX_SIZE]; + +#if defined(MBEDTLS_RSA_PRIV_ENABLED) + if( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V15 ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); +#else + if( mode != MBEDTLS_RSA_PUBLIC ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); +#endif /* MBEDTLS_RSA_PRIV_ENABLED */ + + siglen = ctx->len; + + if( siglen < 16 || siglen > sizeof( buf ) ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + +#if defined(MBEDTLS_RSA_PRIV_ENABLED) + ret = ( mode == MBEDTLS_RSA_PUBLIC ) + ? mbedtls_rsa_public( ctx, sig, buf ) + : mbedtls_rsa_private( ctx, f_rng, p_rng, sig, buf ); +#else + (void)f_rng; + (void)p_rng; + ret = mbedtls_rsa_public( ctx, sig, buf ); +#endif /* MBEDTLS_RSA_PRIV_ENABLED */ + + if( ret != 0 ) + return( ret ); + + p = buf; + + if( *p++ != 0 || *p++ != MBEDTLS_RSA_SIGN ) + return( MBEDTLS_ERR_RSA_INVALID_PADDING ); + + while( *p != 0 ) + { + if( p >= buf + siglen - 1 || *p != 0xFF ) + return( MBEDTLS_ERR_RSA_INVALID_PADDING ); + p++; + } + p++; + + len = siglen - ( p - buf ); + + if( len == hashlen && md_alg == MBEDTLS_MD_NONE ) + { + if( memcmp( p, hash, hashlen ) == 0 ) + return( 0 ); + else + return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); + } + + md_info = mbedtls_md_info_from_type( md_alg ); + if( md_info == NULL ) + return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA ); + hashlen = mbedtls_md_get_size( md_info ); + + end = p + len; + + /* + * Parse the ASN.1 structure inside the PKCS#1 v1.5 structure + */ + if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) + return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); + + if( asn1_len + 2 != len ) + return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); + + if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) + return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); + + if( asn1_len + 6 + hashlen != len ) + return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); + + if( ( ret = mbedtls_asn1_get_tag( &p, end, &oid.len, MBEDTLS_ASN1_OID ) ) != 0 ) + return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); + + oid.p = p; + p += oid.len; + +#if !defined(MBEDTLS_IOT_SPECIFIC) + if( mbedtls_oid_get_md_alg( &oid, &msg_md_alg ) != 0 ) + return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); + + if( md_alg != msg_md_alg ) + return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); +#endif + + /* + * assume the algorithm parameters must be NULL + */ + if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len, MBEDTLS_ASN1_NULL ) ) != 0 ) + return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); + + if( ( ret = mbedtls_asn1_get_tag( &p, end, &asn1_len, MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ) + return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); + + if( asn1_len != hashlen ) + return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); + + if( memcmp( p, hash, hashlen ) != 0 ) + return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); + + p += hashlen; + + if( p != end ) + return( MBEDTLS_ERR_RSA_VERIFY_FAILED ); + + return( 0 ); +} +#endif /* MBEDTLS_PKCS1_V15 */ + +/* + * Do an RSA operation and check the message digest + */ +int mbedtls_rsa_pkcs1_verify( mbedtls_rsa_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng, + int mode, + mbedtls_md_type_t md_alg, + unsigned int hashlen, + const unsigned char *hash, + const unsigned char *sig ) +{ + switch( ctx->padding ) + { +#if defined(MBEDTLS_PKCS1_V15) + case MBEDTLS_RSA_PKCS_V15: + return mbedtls_rsa_rsassa_pkcs1_v15_verify( ctx, f_rng, p_rng, mode, md_alg, + hashlen, hash, sig ); +#endif + +#if defined(MBEDTLS_PKCS1_V21) + case MBEDTLS_RSA_PKCS_V21: + return mbedtls_rsa_rsassa_pss_verify( ctx, f_rng, p_rng, mode, md_alg, + hashlen, hash, sig ); +#endif + + default: + return( MBEDTLS_ERR_RSA_INVALID_PADDING ); + } +} + +/* + * Copy the components of an RSA key + */ +int mbedtls_rsa_copy( mbedtls_rsa_context *dst, const mbedtls_rsa_context *src ) +{ + int ret; + + dst->ver = src->ver; + dst->len = src->len; + + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->N, &src->N ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->E, &src->E ) ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->D, &src->D ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->P, &src->P ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Q, &src->Q ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->DP, &src->DP ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->DQ, &src->DQ ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->QP, &src->QP ) ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RN, &src->RN ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RP, &src->RP ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->RQ, &src->RQ ) ); + + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Vi, &src->Vi ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &dst->Vf, &src->Vf ) ); + + dst->padding = src->padding; + dst->hash_id = src->hash_id; + +cleanup: + if( ret != 0 ) + mbedtls_rsa_free( dst ); + + return( ret ); +} + +/* + * Free the components of an RSA key + */ +void mbedtls_rsa_free( mbedtls_rsa_context *ctx ) +{ + mbedtls_mpi_free( &ctx->Vi ); mbedtls_mpi_free( &ctx->Vf ); + mbedtls_mpi_free( &ctx->RQ ); mbedtls_mpi_free( &ctx->RP ); mbedtls_mpi_free( &ctx->RN ); + mbedtls_mpi_free( &ctx->QP ); mbedtls_mpi_free( &ctx->DQ ); mbedtls_mpi_free( &ctx->DP ); + mbedtls_mpi_free( &ctx->Q ); mbedtls_mpi_free( &ctx->P ); mbedtls_mpi_free( &ctx->D ); + mbedtls_mpi_free( &ctx->E ); mbedtls_mpi_free( &ctx->N ); + +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_free( &ctx->mutex ); +#endif +} + +#if defined(MBEDTLS_SELF_TEST) + +#include "mbedtls/sha1.h" + +/* + * Example RSA-1024 keypair, for test purposes + */ +#define KEY_LEN 128 + +#define RSA_N "9292758453063D803DD603D5E777D788" \ + "8ED1D5BF35786190FA2F23EBC0848AEA" \ + "DDA92CA6C3D80B32C4D109BE0F36D6AE" \ + "7130B9CED7ACDF54CFC7555AC14EEBAB" \ + "93A89813FBF3C4F8066D2D800F7C38A8" \ + "1AE31942917403FF4946B0A83D3D3E05" \ + "EE57C6F5F5606FB5D4BC6CD34EE0801A" \ + "5E94BB77B07507233A0BC7BAC8F90F79" + +#define RSA_E "10001" + +#define RSA_D "24BF6185468786FDD303083D25E64EFC" \ + "66CA472BC44D253102F8B4A9D3BFA750" \ + "91386C0077937FE33FA3252D28855837" \ + "AE1B484A8A9A45F7EE8C0C634F99E8CD" \ + "DF79C5CE07EE72C7F123142198164234" \ + "CABB724CF78B8173B9F880FC86322407" \ + "AF1FEDFDDE2BEB674CA15F3E81A1521E" \ + "071513A1E85B5DFA031F21ECAE91A34D" + +#define RSA_P "C36D0EB7FCD285223CFB5AABA5BDA3D8" \ + "2C01CAD19EA484A87EA4377637E75500" \ + "FCB2005C5C7DD6EC4AC023CDA285D796" \ + "C3D9E75E1EFC42488BB4F1D13AC30A57" + +#define RSA_Q "C000DF51A7C77AE8D7C7370C1FF55B69" \ + "E211C2B9E5DB1ED0BF61D0D9899620F4" \ + "910E4168387E3C30AA1E00C339A79508" \ + "8452DD96A9A5EA5D9DCA68DA636032AF" + +#define RSA_DP "C1ACF567564274FB07A0BBAD5D26E298" \ + "3C94D22288ACD763FD8E5600ED4A702D" \ + "F84198A5F06C2E72236AE490C93F07F8" \ + "3CC559CD27BC2D1CA488811730BB5725" + +#define RSA_DQ "4959CBF6F8FEF750AEE6977C155579C7" \ + "D8AAEA56749EA28623272E4F7D0592AF" \ + "7C1F1313CAC9471B5C523BFE592F517B" \ + "407A1BD76C164B93DA2D32A383E58357" + +#define RSA_QP "9AE7FBC99546432DF71896FC239EADAE" \ + "F38D18D2B2F0E2DD275AA977E2BF4411" \ + "F5A3B2A5D33605AEBBCCBA7FEB9F2D2F" \ + "A74206CEC169D74BF5A8C50D6F48EA08" + +#define PT_LEN 24 +#define RSA_PT "\xAA\xBB\xCC\x03\x02\x01\x00\xFF\xFF\xFF\xFF\xFF" \ + "\x11\x22\x33\x0A\x0B\x0C\xCC\xDD\xDD\xDD\xDD\xDD" + +#if defined(MBEDTLS_PKCS1_V15) +static int myrand( void *rng_state, unsigned char *output, size_t len ) +{ +#if !defined(__OpenBSD__) + size_t i; + + if( rng_state != NULL ) + rng_state = NULL; + + for( i = 0; i < len; ++i ) + output[i] = rand(); +#else + if( rng_state != NULL ) + rng_state = NULL; + + arc4random_buf( output, len ); +#endif /* !OpenBSD */ + + return( 0 ); +} +#endif /* MBEDTLS_PKCS1_V15 */ + +#if defined(MBEDTLS_RSA_PRIV_ENABLED) +/* + * Checkup routine + */ +int mbedtls_rsa_self_test( int verbose ) +{ + int ret = 0; +#if defined(MBEDTLS_PKCS1_V15) + size_t len; + mbedtls_rsa_context rsa; + unsigned char rsa_plaintext[PT_LEN]; + unsigned char rsa_decrypted[PT_LEN]; + unsigned char rsa_ciphertext[KEY_LEN]; +#if defined(MBEDTLS_SHA1_C) + unsigned char sha1sum[20]; +#endif + + mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, 0 ); + + rsa.len = KEY_LEN; + MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &rsa.N , 16, RSA_N ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &rsa.E , 16, RSA_E ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &rsa.D , 16, RSA_D ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &rsa.P , 16, RSA_P ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &rsa.Q , 16, RSA_Q ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &rsa.DP, 16, RSA_DP ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &rsa.DQ, 16, RSA_DQ ) ); + MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &rsa.QP, 16, RSA_QP ) ); + + if( verbose != 0 ) + mbedtls_printf( " RSA key validation: " ); + + if( mbedtls_rsa_check_pubkey( &rsa ) != 0 || + mbedtls_rsa_check_privkey( &rsa ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n PKCS#1 encryption : " ); + + memcpy( rsa_plaintext, RSA_PT, PT_LEN ); + + if( mbedtls_rsa_pkcs1_encrypt( &rsa, myrand, NULL, MBEDTLS_RSA_PUBLIC, PT_LEN, + rsa_plaintext, rsa_ciphertext ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n PKCS#1 decryption : " ); + + if( mbedtls_rsa_pkcs1_decrypt( &rsa, myrand, NULL, MBEDTLS_RSA_PRIVATE, &len, + rsa_ciphertext, rsa_decrypted, + sizeof(rsa_decrypted) ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( 1 ); + } + + if( memcmp( rsa_decrypted, rsa_plaintext, len ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + +#if defined(MBEDTLS_SHA1_C) + if( verbose != 0 ) + mbedtls_printf( " PKCS#1 data sign : " ); + + mbedtls_sha1( rsa_plaintext, PT_LEN, sha1sum ); + + if( mbedtls_rsa_pkcs1_sign( &rsa, myrand, NULL, MBEDTLS_RSA_PRIVATE, MBEDTLS_MD_SHA1, 0, + sha1sum, rsa_ciphertext ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n PKCS#1 sig. verify: " ); + + if( mbedtls_rsa_pkcs1_verify( &rsa, NULL, NULL, MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_SHA1, 0, + sha1sum, rsa_ciphertext ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( 1 ); + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); +#endif /* MBEDTLS_SHA1_C */ + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + +cleanup: + mbedtls_rsa_free( &rsa ); +#else /* MBEDTLS_PKCS1_V15 */ + ((void) verbose); +#endif /* MBEDTLS_PKCS1_V15 */ + return( ret ); +} +#endif /* MBEDTLS_RSA_PRIV_ENABLED */ + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_RSA_C */ + +#endif /* MBEDTLS_PK_ALT */ diff --git a/security/mbedtls/src/sha1.c b/security/mbedtls/src/sha1.c new file mode 100644 index 0000000000..2ccf2a2f52 --- /dev/null +++ b/security/mbedtls/src/sha1.c @@ -0,0 +1,448 @@ +/* + * FIPS-180-1 compliant SHA-1 implementation + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +/* + * The SHA-1 standard was published by NIST in 1993. + * + * http://www.itl.nist.gov/fipspubs/fip180-1.htm + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_SHA1_C) + +#include "mbedtls/sha1.h" + +#include + +#if defined(MBEDTLS_SELF_TEST) +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_printf printf +#endif /* MBEDTLS_PLATFORM_C */ +#endif /* MBEDTLS_SELF_TEST */ + +#if !defined(MBEDTLS_SHA1_ALT) + +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0; +} + +/* + * 32-bit integer manipulation macros (big endian) + */ +#ifndef GET_UINT32_BE +#define GET_UINT32_BE(n,b,i) \ +{ \ + (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ + | ( (uint32_t) (b)[(i) + 1] << 16 ) \ + | ( (uint32_t) (b)[(i) + 2] << 8 ) \ + | ( (uint32_t) (b)[(i) + 3] ); \ +} +#endif + +#ifndef PUT_UINT32_BE +#define PUT_UINT32_BE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) ); \ +} +#endif + +void mbedtls_sha1_init( mbedtls_sha1_context *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_sha1_context ) ); +} + +void mbedtls_sha1_free( mbedtls_sha1_context *ctx ) +{ + if( ctx == NULL ) + return; + + mbedtls_zeroize( ctx, sizeof( mbedtls_sha1_context ) ); +} + +void mbedtls_sha1_clone( mbedtls_sha1_context *dst, + const mbedtls_sha1_context *src ) +{ + *dst = *src; +} + +/* + * SHA-1 context setup + */ +void mbedtls_sha1_starts( mbedtls_sha1_context *ctx ) +{ + ctx->total[0] = 0; + ctx->total[1] = 0; + + ctx->state[0] = 0x67452301; + ctx->state[1] = 0xEFCDAB89; + ctx->state[2] = 0x98BADCFE; + ctx->state[3] = 0x10325476; + ctx->state[4] = 0xC3D2E1F0; +} + +#if !defined(MBEDTLS_SHA1_PROCESS_ALT) +void mbedtls_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[64] ) +{ + uint32_t temp, W[16], A, B, C, D, E; + + GET_UINT32_BE( W[ 0], data, 0 ); + GET_UINT32_BE( W[ 1], data, 4 ); + GET_UINT32_BE( W[ 2], data, 8 ); + GET_UINT32_BE( W[ 3], data, 12 ); + GET_UINT32_BE( W[ 4], data, 16 ); + GET_UINT32_BE( W[ 5], data, 20 ); + GET_UINT32_BE( W[ 6], data, 24 ); + GET_UINT32_BE( W[ 7], data, 28 ); + GET_UINT32_BE( W[ 8], data, 32 ); + GET_UINT32_BE( W[ 9], data, 36 ); + GET_UINT32_BE( W[10], data, 40 ); + GET_UINT32_BE( W[11], data, 44 ); + GET_UINT32_BE( W[12], data, 48 ); + GET_UINT32_BE( W[13], data, 52 ); + GET_UINT32_BE( W[14], data, 56 ); + GET_UINT32_BE( W[15], data, 60 ); + +#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) + +#define R(t) \ +( \ + temp = W[( t - 3 ) & 0x0F] ^ W[( t - 8 ) & 0x0F] ^ \ + W[( t - 14 ) & 0x0F] ^ W[ t & 0x0F], \ + ( W[t & 0x0F] = S(temp,1) ) \ +) + +#define P(a,b,c,d,e,x) \ +{ \ + e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \ +} + + A = ctx->state[0]; + B = ctx->state[1]; + C = ctx->state[2]; + D = ctx->state[3]; + E = ctx->state[4]; + +#define F(x,y,z) (z ^ (x & (y ^ z))) +#define K 0x5A827999 + + P( A, B, C, D, E, W[0] ); + P( E, A, B, C, D, W[1] ); + P( D, E, A, B, C, W[2] ); + P( C, D, E, A, B, W[3] ); + P( B, C, D, E, A, W[4] ); + P( A, B, C, D, E, W[5] ); + P( E, A, B, C, D, W[6] ); + P( D, E, A, B, C, W[7] ); + P( C, D, E, A, B, W[8] ); + P( B, C, D, E, A, W[9] ); + P( A, B, C, D, E, W[10] ); + P( E, A, B, C, D, W[11] ); + P( D, E, A, B, C, W[12] ); + P( C, D, E, A, B, W[13] ); + P( B, C, D, E, A, W[14] ); + P( A, B, C, D, E, W[15] ); + P( E, A, B, C, D, R(16) ); + P( D, E, A, B, C, R(17) ); + P( C, D, E, A, B, R(18) ); + P( B, C, D, E, A, R(19) ); + +#undef K +#undef F + +#define F(x,y,z) (x ^ y ^ z) +#define K 0x6ED9EBA1 + + P( A, B, C, D, E, R(20) ); + P( E, A, B, C, D, R(21) ); + P( D, E, A, B, C, R(22) ); + P( C, D, E, A, B, R(23) ); + P( B, C, D, E, A, R(24) ); + P( A, B, C, D, E, R(25) ); + P( E, A, B, C, D, R(26) ); + P( D, E, A, B, C, R(27) ); + P( C, D, E, A, B, R(28) ); + P( B, C, D, E, A, R(29) ); + P( A, B, C, D, E, R(30) ); + P( E, A, B, C, D, R(31) ); + P( D, E, A, B, C, R(32) ); + P( C, D, E, A, B, R(33) ); + P( B, C, D, E, A, R(34) ); + P( A, B, C, D, E, R(35) ); + P( E, A, B, C, D, R(36) ); + P( D, E, A, B, C, R(37) ); + P( C, D, E, A, B, R(38) ); + P( B, C, D, E, A, R(39) ); + +#undef K +#undef F + +#define F(x,y,z) ((x & y) | (z & (x | y))) +#define K 0x8F1BBCDC + + P( A, B, C, D, E, R(40) ); + P( E, A, B, C, D, R(41) ); + P( D, E, A, B, C, R(42) ); + P( C, D, E, A, B, R(43) ); + P( B, C, D, E, A, R(44) ); + P( A, B, C, D, E, R(45) ); + P( E, A, B, C, D, R(46) ); + P( D, E, A, B, C, R(47) ); + P( C, D, E, A, B, R(48) ); + P( B, C, D, E, A, R(49) ); + P( A, B, C, D, E, R(50) ); + P( E, A, B, C, D, R(51) ); + P( D, E, A, B, C, R(52) ); + P( C, D, E, A, B, R(53) ); + P( B, C, D, E, A, R(54) ); + P( A, B, C, D, E, R(55) ); + P( E, A, B, C, D, R(56) ); + P( D, E, A, B, C, R(57) ); + P( C, D, E, A, B, R(58) ); + P( B, C, D, E, A, R(59) ); + +#undef K +#undef F + +#define F(x,y,z) (x ^ y ^ z) +#define K 0xCA62C1D6 + + P( A, B, C, D, E, R(60) ); + P( E, A, B, C, D, R(61) ); + P( D, E, A, B, C, R(62) ); + P( C, D, E, A, B, R(63) ); + P( B, C, D, E, A, R(64) ); + P( A, B, C, D, E, R(65) ); + P( E, A, B, C, D, R(66) ); + P( D, E, A, B, C, R(67) ); + P( C, D, E, A, B, R(68) ); + P( B, C, D, E, A, R(69) ); + P( A, B, C, D, E, R(70) ); + P( E, A, B, C, D, R(71) ); + P( D, E, A, B, C, R(72) ); + P( C, D, E, A, B, R(73) ); + P( B, C, D, E, A, R(74) ); + P( A, B, C, D, E, R(75) ); + P( E, A, B, C, D, R(76) ); + P( D, E, A, B, C, R(77) ); + P( C, D, E, A, B, R(78) ); + P( B, C, D, E, A, R(79) ); + +#undef K +#undef F + + ctx->state[0] += A; + ctx->state[1] += B; + ctx->state[2] += C; + ctx->state[3] += D; + ctx->state[4] += E; +} +#endif /* !MBEDTLS_SHA1_PROCESS_ALT */ + +/* + * SHA-1 process buffer + */ +void mbedtls_sha1_update( mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen ) +{ + size_t fill; + uint32_t left; + + if( ilen == 0 ) + return; + + left = ctx->total[0] & 0x3F; + fill = 64 - left; + + ctx->total[0] += (uint32_t) ilen; + ctx->total[0] &= 0xFFFFFFFF; + + if( ctx->total[0] < (uint32_t) ilen ) + ctx->total[1]++; + + if( left && ilen >= fill ) + { + memcpy( (void *) (ctx->buffer + left), input, fill ); + mbedtls_sha1_process( ctx, ctx->buffer ); + input += fill; + ilen -= fill; + left = 0; + } + + while( ilen >= 64 ) + { + mbedtls_sha1_process( ctx, input ); + input += 64; + ilen -= 64; + } + + if( ilen > 0 ) + memcpy( (void *) (ctx->buffer + left), input, ilen ); +} + +static const unsigned char sha1_padding[64] = +{ + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* + * SHA-1 final digest + */ +void mbedtls_sha1_finish( mbedtls_sha1_context *ctx, unsigned char output[20] ) +{ + uint32_t last, padn; + uint32_t high, low; + unsigned char msglen[8]; + + high = ( ctx->total[0] >> 29 ) + | ( ctx->total[1] << 3 ); + low = ( ctx->total[0] << 3 ); + + PUT_UINT32_BE( high, msglen, 0 ); + PUT_UINT32_BE( low, msglen, 4 ); + + last = ctx->total[0] & 0x3F; + padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); + + mbedtls_sha1_update( ctx, sha1_padding, padn ); + mbedtls_sha1_update( ctx, msglen, 8 ); + + PUT_UINT32_BE( ctx->state[0], output, 0 ); + PUT_UINT32_BE( ctx->state[1], output, 4 ); + PUT_UINT32_BE( ctx->state[2], output, 8 ); + PUT_UINT32_BE( ctx->state[3], output, 12 ); + PUT_UINT32_BE( ctx->state[4], output, 16 ); +} + +#endif /* !MBEDTLS_SHA1_ALT */ + +/* + * output = SHA-1( input buffer ) + */ +void mbedtls_sha1( const unsigned char *input, size_t ilen, unsigned char output[20] ) +{ + mbedtls_sha1_context ctx; + + mbedtls_sha1_init( &ctx ); + mbedtls_sha1_starts( &ctx ); + mbedtls_sha1_update( &ctx, input, ilen ); + mbedtls_sha1_finish( &ctx, output ); + mbedtls_sha1_free( &ctx ); +} + +#if defined(MBEDTLS_SELF_TEST) +/* + * FIPS-180-1 test vectors + */ +static const unsigned char sha1_test_buf[3][57] = +{ + { "abc" }, + { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }, + { "" } +}; + +static const int sha1_test_buflen[3] = +{ + 3, 56, 1000 +}; + +static const unsigned char sha1_test_sum[3][20] = +{ + { 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E, + 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D }, + { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE, + 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 }, + { 0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E, + 0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F } +}; + +/* + * Checkup routine + */ +int mbedtls_sha1_self_test( int verbose ) +{ + int i, j, buflen, ret = 0; + unsigned char buf[1024]; + unsigned char sha1sum[20]; + mbedtls_sha1_context ctx; + + mbedtls_sha1_init( &ctx ); + + /* + * SHA-1 + */ + for( i = 0; i < 3; i++ ) + { + if( verbose != 0 ) + mbedtls_printf( " SHA-1 test #%d: ", i + 1 ); + + mbedtls_sha1_starts( &ctx ); + + if( i == 2 ) + { + memset( buf, 'a', buflen = 1000 ); + + for( j = 0; j < 1000; j++ ) + mbedtls_sha1_update( &ctx, buf, buflen ); + } + else + mbedtls_sha1_update( &ctx, sha1_test_buf[i], + sha1_test_buflen[i] ); + + mbedtls_sha1_finish( &ctx, sha1sum ); + + if( memcmp( sha1sum, sha1_test_sum[i], 20 ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + ret = 1; + goto exit; + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + +exit: + mbedtls_sha1_free( &ctx ); + + return( ret ); +} + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_SHA1_C */ diff --git a/security/mbedtls/src/sha256.c b/security/mbedtls/src/sha256.c new file mode 100644 index 0000000000..ad25d38333 --- /dev/null +++ b/security/mbedtls/src/sha256.c @@ -0,0 +1,458 @@ +/* + * FIPS-180-2 compliant SHA-256 implementation + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +/* + * The SHA-256 Secure Hash Standard was published by NIST in 2002. + * + * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_SHA256_C) + +#include "mbedtls/sha256.h" + +#include + +#if defined(MBEDTLS_SELF_TEST) +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#include +#define mbedtls_printf printf +#define mbedtls_calloc calloc +#define mbedtls_free free +#endif /* MBEDTLS_PLATFORM_C */ +#endif /* MBEDTLS_SELF_TEST */ + +#if !defined(MBEDTLS_SHA256_ALT) + +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +/* + * 32-bit integer manipulation macros (big endian) + */ +#ifndef GET_UINT32_BE +#define GET_UINT32_BE(n,b,i) \ +do { \ + (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ + | ( (uint32_t) (b)[(i) + 1] << 16 ) \ + | ( (uint32_t) (b)[(i) + 2] << 8 ) \ + | ( (uint32_t) (b)[(i) + 3] ); \ +} while( 0 ) +#endif + +#ifndef PUT_UINT32_BE +#define PUT_UINT32_BE(n,b,i) \ +do { \ + (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) ); \ +} while( 0 ) +#endif + +void mbedtls_sha256_init( mbedtls_sha256_context *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_sha256_context ) ); +} + +void mbedtls_sha256_free( mbedtls_sha256_context *ctx ) +{ + if( ctx == NULL ) + return; + + mbedtls_zeroize( ctx, sizeof( mbedtls_sha256_context ) ); +} + +void mbedtls_sha256_clone( mbedtls_sha256_context *dst, + const mbedtls_sha256_context *src ) +{ + *dst = *src; +} + +/* + * SHA-256 context setup + */ +void mbedtls_sha256_starts( mbedtls_sha256_context *ctx, int is224 ) +{ + ctx->total[0] = 0; + ctx->total[1] = 0; + + if( is224 == 0 ) + { + /* SHA-256 */ + 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; + } + else + { + /* SHA-224 */ + ctx->state[0] = 0xC1059ED8; + ctx->state[1] = 0x367CD507; + ctx->state[2] = 0x3070DD17; + ctx->state[3] = 0xF70E5939; + ctx->state[4] = 0xFFC00B31; + ctx->state[5] = 0x68581511; + ctx->state[6] = 0x64F98FA7; + ctx->state[7] = 0xBEFA4FA4; + } + + ctx->is224 = is224; +} + +#if !defined(MBEDTLS_SHA256_PROCESS_ALT) +static const uint32_t K[] = +{ + 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, +}; + +#define SHR(x,n) ((x & 0xFFFFFFFF) >> n) +#define ROTR(x,n) (SHR(x,n) | (x << (32 - n))) + +#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3)) +#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10)) + +#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22)) +#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25)) + +#define F0(x,y,z) ((x & y) | (z & (x | y))) +#define F1(x,y,z) (z ^ (x & (y ^ z))) + +#define R(t) \ +( \ + W[t] = S1(W[t - 2]) + W[t - 7] + \ + S0(W[t - 15]) + W[t - 16] \ +) + +#define P(a,b,c,d,e,f,g,h,x,K) \ +{ \ + temp1 = h + S3(e) + F1(e,f,g) + K + x; \ + temp2 = S2(a) + F0(a,b,c); \ + d += temp1; h = temp1 + temp2; \ +} + +void mbedtls_sha256_process( mbedtls_sha256_context *ctx, const unsigned char data[64] ) +{ + uint32_t temp1, temp2, W[64]; + uint32_t A[8]; + unsigned int i; + + for( i = 0; i < 8; i++ ) + A[i] = ctx->state[i]; + +#if defined(MBEDTLS_SHA256_SMALLER) + for( i = 0; i < 64; i++ ) + { + if( i < 16 ) + GET_UINT32_BE( W[i], data, 4 * i ); + else + R( i ); + + P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] ); + + temp1 = A[7]; A[7] = A[6]; A[6] = A[5]; A[5] = A[4]; A[4] = A[3]; + A[3] = A[2]; A[2] = A[1]; A[1] = A[0]; A[0] = temp1; + } +#else /* MBEDTLS_SHA256_SMALLER */ + for( i = 0; i < 16; i++ ) + GET_UINT32_BE( W[i], data, 4 * i ); + + for( i = 0; i < 16; i += 8 ) + { + P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i+0], K[i+0] ); + P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[i+1], K[i+1] ); + P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[i+2], K[i+2] ); + P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[i+3], K[i+3] ); + P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[i+4], K[i+4] ); + P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[i+5], K[i+5] ); + P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[i+6], K[i+6] ); + P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[i+7], K[i+7] ); + } + + for( i = 16; i < 64; i += 8 ) + { + P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(i+0), K[i+0] ); + P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(i+1), K[i+1] ); + P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(i+2), K[i+2] ); + P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(i+3), K[i+3] ); + P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(i+4), K[i+4] ); + P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(i+5), K[i+5] ); + P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(i+6), K[i+6] ); + P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(i+7), K[i+7] ); + } +#endif /* MBEDTLS_SHA256_SMALLER */ + + for( i = 0; i < 8; i++ ) + ctx->state[i] += A[i]; +} +#endif /* !MBEDTLS_SHA256_PROCESS_ALT */ + +/* + * SHA-256 process buffer + */ +void mbedtls_sha256_update( mbedtls_sha256_context *ctx, const unsigned char *input, + size_t ilen ) +{ + size_t fill; + uint32_t left; + + if( ilen == 0 ) + return; + + left = ctx->total[0] & 0x3F; + fill = 64 - left; + + ctx->total[0] += (uint32_t) ilen; + ctx->total[0] &= 0xFFFFFFFF; + + if( ctx->total[0] < (uint32_t) ilen ) + ctx->total[1]++; + + if( left && ilen >= fill ) + { + memcpy( (void *) (ctx->buffer + left), input, fill ); + mbedtls_sha256_process( ctx, ctx->buffer ); + input += fill; + ilen -= fill; + left = 0; + } + + while( ilen >= 64 ) + { + mbedtls_sha256_process( ctx, input ); + input += 64; + ilen -= 64; + } + + if( ilen > 0 ) + memcpy( (void *) (ctx->buffer + left), input, ilen ); +} + +static const unsigned char sha256_padding[64] = +{ + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* + * SHA-256 final digest + */ +void mbedtls_sha256_finish( mbedtls_sha256_context *ctx, unsigned char output[32] ) +{ + uint32_t last, padn; + uint32_t high, low; + unsigned char msglen[8]; + + high = ( ctx->total[0] >> 29 ) + | ( ctx->total[1] << 3 ); + low = ( ctx->total[0] << 3 ); + + PUT_UINT32_BE( high, msglen, 0 ); + PUT_UINT32_BE( low, msglen, 4 ); + + last = ctx->total[0] & 0x3F; + padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); + + mbedtls_sha256_update( ctx, sha256_padding, padn ); + mbedtls_sha256_update( ctx, msglen, 8 ); + + PUT_UINT32_BE( ctx->state[0], output, 0 ); + PUT_UINT32_BE( ctx->state[1], output, 4 ); + PUT_UINT32_BE( ctx->state[2], output, 8 ); + PUT_UINT32_BE( ctx->state[3], output, 12 ); + PUT_UINT32_BE( ctx->state[4], output, 16 ); + PUT_UINT32_BE( ctx->state[5], output, 20 ); + PUT_UINT32_BE( ctx->state[6], output, 24 ); + + if( ctx->is224 == 0 ) + PUT_UINT32_BE( ctx->state[7], output, 28 ); +} + +#endif /* !MBEDTLS_SHA256_ALT */ + +/* + * output = SHA-256( input buffer ) + */ +void mbedtls_sha256( const unsigned char *input, size_t ilen, + unsigned char output[32], int is224 ) +{ + mbedtls_sha256_context ctx; + + mbedtls_sha256_init( &ctx ); + mbedtls_sha256_starts( &ctx, is224 ); + mbedtls_sha256_update( &ctx, input, ilen ); + mbedtls_sha256_finish( &ctx, output ); + mbedtls_sha256_free( &ctx ); +} + +#if defined(MBEDTLS_SELF_TEST) +/* + * FIPS-180-2 test vectors + */ +static const unsigned char sha256_test_buf[3][57] = +{ + { "abc" }, + { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }, + { "" } +}; + +static const int sha256_test_buflen[3] = +{ + 3, 56, 1000 +}; + +static const unsigned char sha256_test_sum[6][32] = +{ + /* + * SHA-224 test vectors + */ + { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22, + 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3, + 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7, + 0xE3, 0x6C, 0x9D, 0xA7 }, + { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC, + 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50, + 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19, + 0x52, 0x52, 0x25, 0x25 }, + { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8, + 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B, + 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE, + 0x4E, 0xE7, 0xAD, 0x67 }, + + /* + * SHA-256 test vectors + */ + { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA, + 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23, + 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C, + 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD }, + { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8, + 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39, + 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67, + 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 }, + { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92, + 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67, + 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E, + 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 } +}; + +/* + * Checkup routine + */ +int mbedtls_sha256_self_test( int verbose ) +{ + int i, j, k, buflen, ret = 0; + unsigned char *buf; + unsigned char sha256sum[32]; + mbedtls_sha256_context ctx; + + buf = mbedtls_calloc( 1024, sizeof(unsigned char) ); + if( NULL == buf ) + { + if( verbose != 0 ) + mbedtls_printf( "Buffer allocation failed\n" ); + + return( 1 ); + } + + mbedtls_sha256_init( &ctx ); + + for( i = 0; i < 6; i++ ) + { + j = i % 3; + k = i < 3; + + if( verbose != 0 ) + mbedtls_printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 ); + + mbedtls_sha256_starts( &ctx, k ); + + if( j == 2 ) + { + memset( buf, 'a', buflen = 1000 ); + + for( j = 0; j < 1000; j++ ) + mbedtls_sha256_update( &ctx, buf, buflen ); + } + else + mbedtls_sha256_update( &ctx, sha256_test_buf[j], + sha256_test_buflen[j] ); + + mbedtls_sha256_finish( &ctx, sha256sum ); + + if( memcmp( sha256sum, sha256_test_sum[i], 32 - k * 4 ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + ret = 1; + goto exit; + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + +exit: + mbedtls_sha256_free( &ctx ); + mbedtls_free( buf ); + + return( ret ); +} + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_SHA256_C */ diff --git a/security/mbedtls/src/sha512.c b/security/mbedtls/src/sha512.c new file mode 100644 index 0000000000..724522ac68 --- /dev/null +++ b/security/mbedtls/src/sha512.c @@ -0,0 +1,514 @@ +/* + * FIPS-180-2 compliant SHA-384/512 implementation + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +/* + * The SHA-512 Secure Hash Standard was published by NIST in 2002. + * + * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_SHA512_C) + +#include "mbedtls/sha512.h" + +#if defined(_MSC_VER) || defined(__WATCOMC__) + #define UL64(x) x##ui64 +#else + #define UL64(x) x##ULL +#endif + +#include + +#if defined(MBEDTLS_SELF_TEST) +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#include +#define mbedtls_printf printf +#define mbedtls_calloc calloc +#define mbedtls_free free +#endif /* MBEDTLS_PLATFORM_C */ +#endif /* MBEDTLS_SELF_TEST */ + +#if !defined(MBEDTLS_SHA512_ALT) + +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +/* + * 64-bit integer manipulation macros (big endian) + */ +#ifndef GET_UINT64_BE +#define GET_UINT64_BE(n,b,i) \ +{ \ + (n) = ( (uint64_t) (b)[(i) ] << 56 ) \ + | ( (uint64_t) (b)[(i) + 1] << 48 ) \ + | ( (uint64_t) (b)[(i) + 2] << 40 ) \ + | ( (uint64_t) (b)[(i) + 3] << 32 ) \ + | ( (uint64_t) (b)[(i) + 4] << 24 ) \ + | ( (uint64_t) (b)[(i) + 5] << 16 ) \ + | ( (uint64_t) (b)[(i) + 6] << 8 ) \ + | ( (uint64_t) (b)[(i) + 7] ); \ +} +#endif /* GET_UINT64_BE */ + +#ifndef PUT_UINT64_BE +#define PUT_UINT64_BE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) >> 56 ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 48 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 40 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) >> 32 ); \ + (b)[(i) + 4] = (unsigned char) ( (n) >> 24 ); \ + (b)[(i) + 5] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 6] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 7] = (unsigned char) ( (n) ); \ +} +#endif /* PUT_UINT64_BE */ + +void mbedtls_sha512_init( mbedtls_sha512_context *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_sha512_context ) ); +} + +void mbedtls_sha512_free( mbedtls_sha512_context *ctx ) +{ + if( ctx == NULL ) + return; + + mbedtls_zeroize( ctx, sizeof( mbedtls_sha512_context ) ); +} + +void mbedtls_sha512_clone( mbedtls_sha512_context *dst, + const mbedtls_sha512_context *src ) +{ + *dst = *src; +} + +/* + * SHA-512 context setup + */ +void mbedtls_sha512_starts( mbedtls_sha512_context *ctx, int is384 ) +{ + ctx->total[0] = 0; + ctx->total[1] = 0; + + if( is384 == 0 ) + { + /* SHA-512 */ + ctx->state[0] = UL64(0x6A09E667F3BCC908); + ctx->state[1] = UL64(0xBB67AE8584CAA73B); + ctx->state[2] = UL64(0x3C6EF372FE94F82B); + ctx->state[3] = UL64(0xA54FF53A5F1D36F1); + ctx->state[4] = UL64(0x510E527FADE682D1); + ctx->state[5] = UL64(0x9B05688C2B3E6C1F); + ctx->state[6] = UL64(0x1F83D9ABFB41BD6B); + ctx->state[7] = UL64(0x5BE0CD19137E2179); + } + else + { + /* SHA-384 */ + ctx->state[0] = UL64(0xCBBB9D5DC1059ED8); + ctx->state[1] = UL64(0x629A292A367CD507); + ctx->state[2] = UL64(0x9159015A3070DD17); + ctx->state[3] = UL64(0x152FECD8F70E5939); + ctx->state[4] = UL64(0x67332667FFC00B31); + ctx->state[5] = UL64(0x8EB44A8768581511); + ctx->state[6] = UL64(0xDB0C2E0D64F98FA7); + ctx->state[7] = UL64(0x47B5481DBEFA4FA4); + } + + ctx->is384 = is384; +} + +#if !defined(MBEDTLS_SHA512_PROCESS_ALT) + +/* + * Round constants + */ +static const uint64_t K[80] = +{ + UL64(0x428A2F98D728AE22), UL64(0x7137449123EF65CD), + UL64(0xB5C0FBCFEC4D3B2F), UL64(0xE9B5DBA58189DBBC), + UL64(0x3956C25BF348B538), UL64(0x59F111F1B605D019), + UL64(0x923F82A4AF194F9B), UL64(0xAB1C5ED5DA6D8118), + UL64(0xD807AA98A3030242), UL64(0x12835B0145706FBE), + UL64(0x243185BE4EE4B28C), UL64(0x550C7DC3D5FFB4E2), + UL64(0x72BE5D74F27B896F), UL64(0x80DEB1FE3B1696B1), + UL64(0x9BDC06A725C71235), UL64(0xC19BF174CF692694), + UL64(0xE49B69C19EF14AD2), UL64(0xEFBE4786384F25E3), + UL64(0x0FC19DC68B8CD5B5), UL64(0x240CA1CC77AC9C65), + UL64(0x2DE92C6F592B0275), UL64(0x4A7484AA6EA6E483), + UL64(0x5CB0A9DCBD41FBD4), UL64(0x76F988DA831153B5), + UL64(0x983E5152EE66DFAB), UL64(0xA831C66D2DB43210), + UL64(0xB00327C898FB213F), UL64(0xBF597FC7BEEF0EE4), + UL64(0xC6E00BF33DA88FC2), UL64(0xD5A79147930AA725), + UL64(0x06CA6351E003826F), UL64(0x142929670A0E6E70), + UL64(0x27B70A8546D22FFC), UL64(0x2E1B21385C26C926), + UL64(0x4D2C6DFC5AC42AED), UL64(0x53380D139D95B3DF), + UL64(0x650A73548BAF63DE), UL64(0x766A0ABB3C77B2A8), + UL64(0x81C2C92E47EDAEE6), UL64(0x92722C851482353B), + UL64(0xA2BFE8A14CF10364), UL64(0xA81A664BBC423001), + UL64(0xC24B8B70D0F89791), UL64(0xC76C51A30654BE30), + UL64(0xD192E819D6EF5218), UL64(0xD69906245565A910), + UL64(0xF40E35855771202A), UL64(0x106AA07032BBD1B8), + UL64(0x19A4C116B8D2D0C8), UL64(0x1E376C085141AB53), + UL64(0x2748774CDF8EEB99), UL64(0x34B0BCB5E19B48A8), + UL64(0x391C0CB3C5C95A63), UL64(0x4ED8AA4AE3418ACB), + UL64(0x5B9CCA4F7763E373), UL64(0x682E6FF3D6B2B8A3), + UL64(0x748F82EE5DEFB2FC), UL64(0x78A5636F43172F60), + UL64(0x84C87814A1F0AB72), UL64(0x8CC702081A6439EC), + UL64(0x90BEFFFA23631E28), UL64(0xA4506CEBDE82BDE9), + UL64(0xBEF9A3F7B2C67915), UL64(0xC67178F2E372532B), + UL64(0xCA273ECEEA26619C), UL64(0xD186B8C721C0C207), + UL64(0xEADA7DD6CDE0EB1E), UL64(0xF57D4F7FEE6ED178), + UL64(0x06F067AA72176FBA), UL64(0x0A637DC5A2C898A6), + UL64(0x113F9804BEF90DAE), UL64(0x1B710B35131C471B), + UL64(0x28DB77F523047D84), UL64(0x32CAAB7B40C72493), + UL64(0x3C9EBE0A15C9BEBC), UL64(0x431D67C49C100D4C), + UL64(0x4CC5D4BECB3E42B6), UL64(0x597F299CFC657E2A), + UL64(0x5FCB6FAB3AD6FAEC), UL64(0x6C44198C4A475817) +}; + +void mbedtls_sha512_process( mbedtls_sha512_context *ctx, const unsigned char data[128] ) +{ + int i; + uint64_t temp1, temp2, W[80]; + uint64_t A, B, C, D, E, F, G, H; + +#define SHR(x,n) (x >> n) +#define ROTR(x,n) (SHR(x,n) | (x << (64 - n))) + +#define S0(x) (ROTR(x, 1) ^ ROTR(x, 8) ^ SHR(x, 7)) +#define S1(x) (ROTR(x,19) ^ ROTR(x,61) ^ SHR(x, 6)) + +#define S2(x) (ROTR(x,28) ^ ROTR(x,34) ^ ROTR(x,39)) +#define S3(x) (ROTR(x,14) ^ ROTR(x,18) ^ ROTR(x,41)) + +#define F0(x,y,z) ((x & y) | (z & (x | y))) +#define F1(x,y,z) (z ^ (x & (y ^ z))) + +#define P(a,b,c,d,e,f,g,h,x,K) \ +{ \ + temp1 = h + S3(e) + F1(e,f,g) + K + x; \ + temp2 = S2(a) + F0(a,b,c); \ + d += temp1; h = temp1 + temp2; \ +} + + for( i = 0; i < 16; i++ ) + { + GET_UINT64_BE( W[i], data, i << 3 ); + } + + for( ; i < 80; i++ ) + { + W[i] = S1(W[i - 2]) + W[i - 7] + + S0(W[i - 15]) + W[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]; + i = 0; + + do + { + P( A, B, C, D, E, F, G, H, W[i], K[i] ); i++; + P( H, A, B, C, D, E, F, G, W[i], K[i] ); i++; + P( G, H, A, B, C, D, E, F, W[i], K[i] ); i++; + P( F, G, H, A, B, C, D, E, W[i], K[i] ); i++; + P( E, F, G, H, A, B, C, D, W[i], K[i] ); i++; + P( D, E, F, G, H, A, B, C, W[i], K[i] ); i++; + P( C, D, E, F, G, H, A, B, W[i], K[i] ); i++; + P( B, C, D, E, F, G, H, A, W[i], K[i] ); i++; + } + while( i < 80 ); + + 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; +} +#endif /* !MBEDTLS_SHA512_PROCESS_ALT */ + +/* + * SHA-512 process buffer + */ +void mbedtls_sha512_update( mbedtls_sha512_context *ctx, const unsigned char *input, + size_t ilen ) +{ + size_t fill; + unsigned int left; + + if( ilen == 0 ) + return; + + left = (unsigned int) (ctx->total[0] & 0x7F); + fill = 128 - left; + + ctx->total[0] += (uint64_t) ilen; + + if( ctx->total[0] < (uint64_t) ilen ) + ctx->total[1]++; + + if( left && ilen >= fill ) + { + memcpy( (void *) (ctx->buffer + left), input, fill ); + mbedtls_sha512_process( ctx, ctx->buffer ); + input += fill; + ilen -= fill; + left = 0; + } + + while( ilen >= 128 ) + { + mbedtls_sha512_process( ctx, input ); + input += 128; + ilen -= 128; + } + + if( ilen > 0 ) + memcpy( (void *) (ctx->buffer + left), input, ilen ); +} + +static const unsigned char sha512_padding[128] = +{ + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* + * SHA-512 final digest + */ +void mbedtls_sha512_finish( mbedtls_sha512_context *ctx, unsigned char output[64] ) +{ + size_t last, padn; + uint64_t high, low; + unsigned char msglen[16]; + + high = ( ctx->total[0] >> 61 ) + | ( ctx->total[1] << 3 ); + low = ( ctx->total[0] << 3 ); + + PUT_UINT64_BE( high, msglen, 0 ); + PUT_UINT64_BE( low, msglen, 8 ); + + last = (size_t)( ctx->total[0] & 0x7F ); + padn = ( last < 112 ) ? ( 112 - last ) : ( 240 - last ); + + mbedtls_sha512_update( ctx, sha512_padding, padn ); + mbedtls_sha512_update( ctx, msglen, 16 ); + + PUT_UINT64_BE( ctx->state[0], output, 0 ); + PUT_UINT64_BE( ctx->state[1], output, 8 ); + PUT_UINT64_BE( ctx->state[2], output, 16 ); + PUT_UINT64_BE( ctx->state[3], output, 24 ); + PUT_UINT64_BE( ctx->state[4], output, 32 ); + PUT_UINT64_BE( ctx->state[5], output, 40 ); + + if( ctx->is384 == 0 ) + { + PUT_UINT64_BE( ctx->state[6], output, 48 ); + PUT_UINT64_BE( ctx->state[7], output, 56 ); + } +} + +#endif /* !MBEDTLS_SHA512_ALT */ + +/* + * output = SHA-512( input buffer ) + */ +void mbedtls_sha512( const unsigned char *input, size_t ilen, + unsigned char output[64], int is384 ) +{ + mbedtls_sha512_context ctx; + + mbedtls_sha512_init( &ctx ); + mbedtls_sha512_starts( &ctx, is384 ); + mbedtls_sha512_update( &ctx, input, ilen ); + mbedtls_sha512_finish( &ctx, output ); + mbedtls_sha512_free( &ctx ); +} + +#if defined(MBEDTLS_SELF_TEST) + +/* + * FIPS-180-2 test vectors + */ +static const unsigned char sha512_test_buf[3][113] = +{ + { "abc" }, + { "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn" + "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu" }, + { "" } +}; + +static const int sha512_test_buflen[3] = +{ + 3, 112, 1000 +}; + +static const unsigned char sha512_test_sum[6][64] = +{ + /* + * SHA-384 test vectors + */ + { 0xCB, 0x00, 0x75, 0x3F, 0x45, 0xA3, 0x5E, 0x8B, + 0xB5, 0xA0, 0x3D, 0x69, 0x9A, 0xC6, 0x50, 0x07, + 0x27, 0x2C, 0x32, 0xAB, 0x0E, 0xDE, 0xD1, 0x63, + 0x1A, 0x8B, 0x60, 0x5A, 0x43, 0xFF, 0x5B, 0xED, + 0x80, 0x86, 0x07, 0x2B, 0xA1, 0xE7, 0xCC, 0x23, + 0x58, 0xBA, 0xEC, 0xA1, 0x34, 0xC8, 0x25, 0xA7 }, + { 0x09, 0x33, 0x0C, 0x33, 0xF7, 0x11, 0x47, 0xE8, + 0x3D, 0x19, 0x2F, 0xC7, 0x82, 0xCD, 0x1B, 0x47, + 0x53, 0x11, 0x1B, 0x17, 0x3B, 0x3B, 0x05, 0xD2, + 0x2F, 0xA0, 0x80, 0x86, 0xE3, 0xB0, 0xF7, 0x12, + 0xFC, 0xC7, 0xC7, 0x1A, 0x55, 0x7E, 0x2D, 0xB9, + 0x66, 0xC3, 0xE9, 0xFA, 0x91, 0x74, 0x60, 0x39 }, + { 0x9D, 0x0E, 0x18, 0x09, 0x71, 0x64, 0x74, 0xCB, + 0x08, 0x6E, 0x83, 0x4E, 0x31, 0x0A, 0x4A, 0x1C, + 0xED, 0x14, 0x9E, 0x9C, 0x00, 0xF2, 0x48, 0x52, + 0x79, 0x72, 0xCE, 0xC5, 0x70, 0x4C, 0x2A, 0x5B, + 0x07, 0xB8, 0xB3, 0xDC, 0x38, 0xEC, 0xC4, 0xEB, + 0xAE, 0x97, 0xDD, 0xD8, 0x7F, 0x3D, 0x89, 0x85 }, + + /* + * SHA-512 test vectors + */ + { 0xDD, 0xAF, 0x35, 0xA1, 0x93, 0x61, 0x7A, 0xBA, + 0xCC, 0x41, 0x73, 0x49, 0xAE, 0x20, 0x41, 0x31, + 0x12, 0xE6, 0xFA, 0x4E, 0x89, 0xA9, 0x7E, 0xA2, + 0x0A, 0x9E, 0xEE, 0xE6, 0x4B, 0x55, 0xD3, 0x9A, + 0x21, 0x92, 0x99, 0x2A, 0x27, 0x4F, 0xC1, 0xA8, + 0x36, 0xBA, 0x3C, 0x23, 0xA3, 0xFE, 0xEB, 0xBD, + 0x45, 0x4D, 0x44, 0x23, 0x64, 0x3C, 0xE8, 0x0E, + 0x2A, 0x9A, 0xC9, 0x4F, 0xA5, 0x4C, 0xA4, 0x9F }, + { 0x8E, 0x95, 0x9B, 0x75, 0xDA, 0xE3, 0x13, 0xDA, + 0x8C, 0xF4, 0xF7, 0x28, 0x14, 0xFC, 0x14, 0x3F, + 0x8F, 0x77, 0x79, 0xC6, 0xEB, 0x9F, 0x7F, 0xA1, + 0x72, 0x99, 0xAE, 0xAD, 0xB6, 0x88, 0x90, 0x18, + 0x50, 0x1D, 0x28, 0x9E, 0x49, 0x00, 0xF7, 0xE4, + 0x33, 0x1B, 0x99, 0xDE, 0xC4, 0xB5, 0x43, 0x3A, + 0xC7, 0xD3, 0x29, 0xEE, 0xB6, 0xDD, 0x26, 0x54, + 0x5E, 0x96, 0xE5, 0x5B, 0x87, 0x4B, 0xE9, 0x09 }, + { 0xE7, 0x18, 0x48, 0x3D, 0x0C, 0xE7, 0x69, 0x64, + 0x4E, 0x2E, 0x42, 0xC7, 0xBC, 0x15, 0xB4, 0x63, + 0x8E, 0x1F, 0x98, 0xB1, 0x3B, 0x20, 0x44, 0x28, + 0x56, 0x32, 0xA8, 0x03, 0xAF, 0xA9, 0x73, 0xEB, + 0xDE, 0x0F, 0xF2, 0x44, 0x87, 0x7E, 0xA6, 0x0A, + 0x4C, 0xB0, 0x43, 0x2C, 0xE5, 0x77, 0xC3, 0x1B, + 0xEB, 0x00, 0x9C, 0x5C, 0x2C, 0x49, 0xAA, 0x2E, + 0x4E, 0xAD, 0xB2, 0x17, 0xAD, 0x8C, 0xC0, 0x9B } +}; + +/* + * Checkup routine + */ +int mbedtls_sha512_self_test( int verbose ) +{ + int i, j, k, buflen, ret = 0; + unsigned char *buf; + unsigned char sha512sum[64]; + mbedtls_sha512_context ctx; + + buf = mbedtls_calloc( 1024, sizeof(unsigned char) ); + if( NULL == buf ) + { + if( verbose != 0 ) + mbedtls_printf( "Buffer allocation failed\n" ); + + return( 1 ); + } + + mbedtls_sha512_init( &ctx ); + + for( i = 0; i < 6; i++ ) + { + j = i % 3; + k = i < 3; + + if( verbose != 0 ) + mbedtls_printf( " SHA-%d test #%d: ", 512 - k * 128, j + 1 ); + + mbedtls_sha512_starts( &ctx, k ); + + if( j == 2 ) + { + memset( buf, 'a', buflen = 1000 ); + + for( j = 0; j < 1000; j++ ) + mbedtls_sha512_update( &ctx, buf, buflen ); + } + else + mbedtls_sha512_update( &ctx, sha512_test_buf[j], + sha512_test_buflen[j] ); + + mbedtls_sha512_finish( &ctx, sha512sum ); + + if( memcmp( sha512sum, sha512_test_sum[i], 64 - k * 16 ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + ret = 1; + goto exit; + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + +exit: + mbedtls_sha512_free( &ctx ); + mbedtls_free( buf ); + + return( ret ); +} + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_SHA512_C */ diff --git a/security/mbedtls/src/ssl_cache.c b/security/mbedtls/src/ssl_cache.c new file mode 100644 index 0000000000..9b62de2dcc --- /dev/null +++ b/security/mbedtls/src/ssl_cache.c @@ -0,0 +1,326 @@ +/* + * SSL session cache implementation + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +/* + * These session callbacks use a simple chained list + * to store and retrieve the session information. + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_SSL_CACHE_C) + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_calloc calloc +#define mbedtls_free free +#endif + +#include "mbedtls/ssl_cache.h" + +#include + +void mbedtls_ssl_cache_init( mbedtls_ssl_cache_context *cache ) +{ + memset( cache, 0, sizeof( mbedtls_ssl_cache_context ) ); + + cache->timeout = MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT; + cache->max_entries = MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES; + +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_init( &cache->mutex ); +#endif +} + +int mbedtls_ssl_cache_get( void *data, mbedtls_ssl_session *session ) +{ + int ret = 1; +#if defined(MBEDTLS_HAVE_TIME) + mbedtls_time_t t = mbedtls_time( NULL ); +#endif + mbedtls_ssl_cache_context *cache = (mbedtls_ssl_cache_context *) data; + mbedtls_ssl_cache_entry *cur, *entry; + +#if defined(MBEDTLS_THREADING_C) + if( mbedtls_mutex_lock( &cache->mutex ) != 0 ) + return( 1 ); +#endif + + cur = cache->chain; + entry = NULL; + + while( cur != NULL ) + { + entry = cur; + cur = cur->next; + +#if defined(MBEDTLS_HAVE_TIME) + if( cache->timeout != 0 && + (int) ( t - entry->timestamp ) > cache->timeout ) + continue; +#endif + + if( session->ciphersuite != entry->session.ciphersuite || + session->compression != entry->session.compression || + session->id_len != entry->session.id_len ) + continue; + + if( memcmp( session->id, entry->session.id, + entry->session.id_len ) != 0 ) + continue; + + memcpy( session->master, entry->session.master, 48 ); + + session->verify_result = entry->session.verify_result; + +#if defined(MBEDTLS_X509_CRT_PARSE_C) + /* + * Restore peer certificate (without rest of the original chain) + */ + if( entry->peer_cert.p != NULL ) + { + if( ( session->peer_cert = mbedtls_calloc( 1, + sizeof(mbedtls_x509_crt) ) ) == NULL ) + { + ret = 1; + goto exit; + } + + mbedtls_x509_crt_init( session->peer_cert ); + if( mbedtls_x509_crt_parse( session->peer_cert, entry->peer_cert.p, + entry->peer_cert.len ) != 0 ) + { + mbedtls_free( session->peer_cert ); + session->peer_cert = NULL; + ret = 1; + goto exit; + } + } +#endif /* MBEDTLS_X509_CRT_PARSE_C */ + + ret = 0; + goto exit; + } + +exit: +#if defined(MBEDTLS_THREADING_C) + if( mbedtls_mutex_unlock( &cache->mutex ) != 0 ) + ret = 1; +#endif + + return( ret ); +} + +int mbedtls_ssl_cache_set( void *data, const mbedtls_ssl_session *session ) +{ + int ret = 1; +#if defined(MBEDTLS_HAVE_TIME) + mbedtls_time_t t = time( NULL ), oldest = 0; + mbedtls_ssl_cache_entry *old = NULL; +#endif + mbedtls_ssl_cache_context *cache = (mbedtls_ssl_cache_context *) data; + mbedtls_ssl_cache_entry *cur, *prv; + int count = 0; + +#if defined(MBEDTLS_THREADING_C) + if( ( ret = mbedtls_mutex_lock( &cache->mutex ) ) != 0 ) + return( ret ); +#endif + + cur = cache->chain; + prv = NULL; + + while( cur != NULL ) + { + count++; + +#if defined(MBEDTLS_HAVE_TIME) + if( cache->timeout != 0 && + (int) ( t - cur->timestamp ) > cache->timeout ) + { + cur->timestamp = t; + break; /* expired, reuse this slot, update timestamp */ + } +#endif + + if( memcmp( session->id, cur->session.id, cur->session.id_len ) == 0 ) + break; /* client reconnected, keep timestamp for session id */ + +#if defined(MBEDTLS_HAVE_TIME) + if( oldest == 0 || cur->timestamp < oldest ) + { + oldest = cur->timestamp; + old = cur; + } +#endif + + prv = cur; + cur = cur->next; + } + + if( cur == NULL ) + { +#if defined(MBEDTLS_HAVE_TIME) + /* + * Reuse oldest entry if max_entries reached + */ + if( count >= cache->max_entries ) + { + if( old == NULL ) + { + ret = 1; + goto exit; + } + + cur = old; + } +#else /* MBEDTLS_HAVE_TIME */ + /* + * Reuse first entry in chain if max_entries reached, + * but move to last place + */ + if( count >= cache->max_entries ) + { + if( cache->chain == NULL ) + { + ret = 1; + goto exit; + } + + cur = cache->chain; + cache->chain = cur->next; + cur->next = NULL; + prv->next = cur; + } +#endif /* MBEDTLS_HAVE_TIME */ + else + { + /* + * max_entries not reached, create new entry + */ + cur = mbedtls_calloc( 1, sizeof(mbedtls_ssl_cache_entry) ); + if( cur == NULL ) + { + ret = 1; + goto exit; + } + + if( prv == NULL ) + cache->chain = cur; + else + prv->next = cur; + } + +#if defined(MBEDTLS_HAVE_TIME) + cur->timestamp = t; +#endif + } + + memcpy( &cur->session, session, sizeof( mbedtls_ssl_session ) ); + +#if defined(MBEDTLS_X509_CRT_PARSE_C) + /* + * If we're reusing an entry, free its certificate first + */ + if( cur->peer_cert.p != NULL ) + { + mbedtls_free( cur->peer_cert.p ); + memset( &cur->peer_cert, 0, sizeof(mbedtls_x509_buf) ); + } + + /* + * Store peer certificate + */ + if( session->peer_cert != NULL ) + { + cur->peer_cert.p = mbedtls_calloc( 1, session->peer_cert->raw.len ); + if( cur->peer_cert.p == NULL ) + { + ret = 1; + goto exit; + } + + memcpy( cur->peer_cert.p, session->peer_cert->raw.p, + session->peer_cert->raw.len ); + cur->peer_cert.len = session->peer_cert->raw.len; + + cur->session.peer_cert = NULL; + } +#endif /* MBEDTLS_X509_CRT_PARSE_C */ + + ret = 0; + +exit: +#if defined(MBEDTLS_THREADING_C) + if( mbedtls_mutex_unlock( &cache->mutex ) != 0 ) + ret = 1; +#endif + + return( ret ); +} + +#if defined(MBEDTLS_HAVE_TIME) +void mbedtls_ssl_cache_set_timeout( mbedtls_ssl_cache_context *cache, int timeout ) +{ + if( timeout < 0 ) timeout = 0; + + cache->timeout = timeout; +} +#endif /* MBEDTLS_HAVE_TIME */ + +void mbedtls_ssl_cache_set_max_entries( mbedtls_ssl_cache_context *cache, int max ) +{ + if( max < 0 ) max = 0; + + cache->max_entries = max; +} + +void mbedtls_ssl_cache_free( mbedtls_ssl_cache_context *cache ) +{ + mbedtls_ssl_cache_entry *cur, *prv; + + cur = cache->chain; + + while( cur != NULL ) + { + prv = cur; + cur = cur->next; + + mbedtls_ssl_session_free( &prv->session ); + +#if defined(MBEDTLS_X509_CRT_PARSE_C) + mbedtls_free( prv->peer_cert.p ); +#endif /* MBEDTLS_X509_CRT_PARSE_C */ + + mbedtls_free( prv ); + } + +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_free( &cache->mutex ); +#endif +} + +#endif /* MBEDTLS_SSL_CACHE_C */ diff --git a/security/mbedtls/src/ssl_ciphersuites.c b/security/mbedtls/src/ssl_ciphersuites.c new file mode 100644 index 0000000000..516e647b17 --- /dev/null +++ b/security/mbedtls/src/ssl_ciphersuites.c @@ -0,0 +1,1872 @@ +/** + * \file ssl_ciphersuites.c + * + * \brief SSL ciphersuites for mbed TLS + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_SSL_TLS_C) + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#endif + +#include "mbedtls/ssl_ciphersuites.h" +#include "mbedtls/ssl.h" + +#include + +/* + * Ordered from most preferred to least preferred in terms of security. + * + * Current rule (except rc4, weak and null which come last): + * 1. By key exchange: + * Forward-secure non-PSK > forward-secure PSK > ECJPAKE > other non-PSK > other PSK + * 2. By key length and cipher: + * AES-256 > Camellia-256 > AES-128 > Camellia-128 > 3DES + * 3. By cipher mode when relevant GCM > CCM > CBC > CCM_8 + * 4. By hash function used when relevant + * 5. By key exchange/auth again: EC > non-EC + */ +static const int ciphersuite_preference[] = +{ +#if defined(MBEDTLS_SSL_CIPHERSUITES) + MBEDTLS_SSL_CIPHERSUITES, +#else + +#if !defined(MBEDTLS_IOT_SPECIFIC) + /* All AES-256 ephemeral suites */ + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM, + MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM, + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, + MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, + MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA, + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, + MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM_8, + + /* All CAMELLIA-256 ephemeral suites */ + MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384, + MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384, + MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384, + MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, + MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384, + MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256, + MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, + + /* All AES-128 ephemeral suites */ + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM, + MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM, + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, + MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, + MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, + MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA, + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, + MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8, + + /* All CAMELLIA-128 ephemeral suites */ + MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256, + MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256, + MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256, + MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, + MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, + MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, + MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, + + /* All remaining >= 128-bit ephemeral suites */ + MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, + MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, + MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, + + /* The PSK ephemeral suites */ + MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384, + MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM, + MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384, + MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384, + MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, + MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA, + MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384, + MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, + MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, + MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM_8, + + MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256, + MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM, + MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, + MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256, + MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, + MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA, + MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256, + MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, + MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, + MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM_8, + + MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA, + MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA, + + /* The ECJPAKE suite */ + MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8, +#endif /* !MBEDTLS_IOT_SPECIFIC */ + + /* All AES-256 suites */ +#if !defined(MBEDTLS_IOT_SPECIFIC) + MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384, + MBEDTLS_TLS_RSA_WITH_AES_256_CCM, +#endif /* !MBEDTLS_IOT_SPECIFIC */ + MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256, + MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA, +#if !defined(MBEDTLS_IOT_SPECIFIC) + MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, + MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, + MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, + MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, + MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, + MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, + MBEDTLS_TLS_RSA_WITH_AES_256_CCM_8, +#endif /* !MBEDTLS_IOT_SPECIFIC */ + +#if !defined(MBEDTLS_IOT_SPECIFIC) + /* All CAMELLIA-256 suites */ + MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384, + MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256, + MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, + MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384, + MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384, + MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384, + MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, +#endif /* !MBEDTLS_IOT_SPECIFIC */ + + /* All AES-128 suites */ +#if !defined(MBEDTLS_IOT_SPECIFIC) + MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256, + MBEDTLS_TLS_RSA_WITH_AES_128_CCM, +#endif /* !MBEDTLS_IOT_SPECIFIC */ + MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256, + MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA, +#if !defined(MBEDTLS_IOT_SPECIFIC) + MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, + MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, + MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, + MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, + MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, + MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, + MBEDTLS_TLS_RSA_WITH_AES_128_CCM_8, +#endif /* !MBEDTLS_IOT_SPECIFIC */ + +#if !defined(MBEDTLS_IOT_SPECIFIC) + /* All CAMELLIA-128 suites */ + MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256, + MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256, + MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, + MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256, + MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256, + MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256, + MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, + + /* All remaining >= 128-bit suites */ + MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA, + MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, + MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, + + /* The RSA PSK suites */ + MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384, + MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384, + MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA, + MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384, + MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384, + + MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256, + MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256, + MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA, + MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256, + MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256, + + MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA, + + /* The PSK suites */ + MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384, + MBEDTLS_TLS_PSK_WITH_AES_256_CCM, + MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384, + MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA, + MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384, + MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384, + MBEDTLS_TLS_PSK_WITH_AES_256_CCM_8, + + MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256, + MBEDTLS_TLS_PSK_WITH_AES_128_CCM, + MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256, + MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA, + MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256, + MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256, + MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8, + + MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA, + + /* RC4 suites */ + MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, + MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA, + MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA, + MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA, + MBEDTLS_TLS_RSA_WITH_RC4_128_SHA, + MBEDTLS_TLS_RSA_WITH_RC4_128_MD5, + MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA, + MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA, + MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA, + MBEDTLS_TLS_PSK_WITH_RC4_128_SHA, + + /* Weak suites */ + MBEDTLS_TLS_DHE_RSA_WITH_DES_CBC_SHA, + MBEDTLS_TLS_RSA_WITH_DES_CBC_SHA, + + /* NULL suites */ + MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA, + MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA, + MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384, + MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256, + MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA, + MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA384, + MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA256, + MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA, + + MBEDTLS_TLS_RSA_WITH_NULL_SHA256, + MBEDTLS_TLS_RSA_WITH_NULL_SHA, + MBEDTLS_TLS_RSA_WITH_NULL_MD5, + MBEDTLS_TLS_ECDH_RSA_WITH_NULL_SHA, + MBEDTLS_TLS_ECDH_ECDSA_WITH_NULL_SHA, + MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384, + MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA256, + MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA, + MBEDTLS_TLS_PSK_WITH_NULL_SHA384, + MBEDTLS_TLS_PSK_WITH_NULL_SHA256, + MBEDTLS_TLS_PSK_WITH_NULL_SHA, +#endif /* !MBEDTLS_IOT_SPECIFIC */ + +#endif /* MBEDTLS_SSL_CIPHERSUITES */ + 0 +}; + +static const mbedtls_ssl_ciphersuite_t ciphersuite_definitions[] = +{ +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) +#if defined(MBEDTLS_AES_C) +#if defined(MBEDTLS_SHA1_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, "TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA", + MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, "TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA", + MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* MBEDTLS_SHA1_C */ +#if defined(MBEDTLS_SHA256_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, "TLS-ECDHE-ECDSA-WITH-AES-128-CBC-SHA256", + MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#if defined(MBEDTLS_GCM_C) + { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, "TLS-ECDHE-ECDSA-WITH-AES-128-GCM-SHA256", + MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_GCM_C */ +#endif /* MBEDTLS_SHA256_C */ +#if defined(MBEDTLS_SHA512_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, "TLS-ECDHE-ECDSA-WITH-AES-256-CBC-SHA384", + MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#if defined(MBEDTLS_GCM_C) + { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, "TLS-ECDHE-ECDSA-WITH-AES-256-GCM-SHA384", + MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_GCM_C */ +#endif /* MBEDTLS_SHA512_C */ +#if defined(MBEDTLS_CCM_C) + { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM, "TLS-ECDHE-ECDSA-WITH-AES-256-CCM", + MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, "TLS-ECDHE-ECDSA-WITH-AES-256-CCM-8", + MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_SHORT_TAG }, + { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM, "TLS-ECDHE-ECDSA-WITH-AES-128-CCM", + MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + { MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, "TLS-ECDHE-ECDSA-WITH-AES-128-CCM-8", + MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_SHORT_TAG }, +#endif /* MBEDTLS_CCM_C */ +#endif /* MBEDTLS_AES_C */ + +#if defined(MBEDTLS_CAMELLIA_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-CBC-SHA256", + MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-CBC-SHA384", + MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_GCM_C) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-ECDHE-ECDSA-WITH-CAMELLIA-128-GCM-SHA256", + MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-ECDHE-ECDSA-WITH-CAMELLIA-256-GCM-SHA384", + MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_GCM_C */ +#endif /* MBEDTLS_CAMELLIA_C */ + +#if defined(MBEDTLS_DES_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, "TLS-ECDHE-ECDSA-WITH-3DES-EDE-CBC-SHA", + MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* MBEDTLS_DES_C */ + +#if defined(MBEDTLS_ARC4_C) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, "TLS-ECDHE-ECDSA-WITH-RC4-128-SHA", + MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_NODTLS }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_ARC4_C */ + +#if defined(MBEDTLS_CIPHER_NULL_CIPHER) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA, "TLS-ECDHE-ECDSA-WITH-NULL-SHA", + MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_WEAK }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_CIPHER_NULL_CIPHER */ +#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) +#if defined(MBEDTLS_AES_C) +#if defined(MBEDTLS_SHA1_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, "TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA", + MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + { MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, "TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA", + MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* MBEDTLS_SHA1_C */ +#if defined(MBEDTLS_SHA256_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, "TLS-ECDHE-RSA-WITH-AES-128-CBC-SHA256", + MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#if defined(MBEDTLS_GCM_C) + { MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, "TLS-ECDHE-RSA-WITH-AES-128-GCM-SHA256", + MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_GCM_C */ +#endif /* MBEDTLS_SHA256_C */ +#if defined(MBEDTLS_SHA512_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, "TLS-ECDHE-RSA-WITH-AES-256-CBC-SHA384", + MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#if defined(MBEDTLS_GCM_C) + { MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, "TLS-ECDHE-RSA-WITH-AES-256-GCM-SHA384", + MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_GCM_C */ +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_AES_C */ + +#if defined(MBEDTLS_CAMELLIA_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-ECDHE-RSA-WITH-CAMELLIA-128-CBC-SHA256", + MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDHE-RSA-WITH-CAMELLIA-256-CBC-SHA384", + MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_GCM_C) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-ECDHE-RSA-WITH-CAMELLIA-128-GCM-SHA256", + MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-ECDHE-RSA-WITH-CAMELLIA-256-GCM-SHA384", + MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_GCM_C */ +#endif /* MBEDTLS_CAMELLIA_C */ + +#if defined(MBEDTLS_DES_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, "TLS-ECDHE-RSA-WITH-3DES-EDE-CBC-SHA", + MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* MBEDTLS_DES_C */ + +#if defined(MBEDTLS_ARC4_C) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_ECDHE_RSA_WITH_RC4_128_SHA, "TLS-ECDHE-RSA-WITH-RC4-128-SHA", + MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_NODTLS }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_ARC4_C */ + +#if defined(MBEDTLS_CIPHER_NULL_CIPHER) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA, "TLS-ECDHE-RSA-WITH-NULL-SHA", + MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_WEAK }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_CIPHER_NULL_CIPHER */ +#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) +#if defined(MBEDTLS_AES_C) +#if defined(MBEDTLS_SHA512_C) && defined(MBEDTLS_GCM_C) + { MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, "TLS-DHE-RSA-WITH-AES-256-GCM-SHA384", + MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C && MBEDTLS_GCM_C */ + +#if defined(MBEDTLS_SHA256_C) +#if defined(MBEDTLS_GCM_C) + { MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, "TLS-DHE-RSA-WITH-AES-128-GCM-SHA256", + MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_GCM_C */ + +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, "TLS-DHE-RSA-WITH-AES-128-CBC-SHA256", + MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + + { MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, "TLS-DHE-RSA-WITH-AES-256-CBC-SHA256", + MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA, "TLS-DHE-RSA-WITH-AES-128-CBC-SHA", + MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + + { MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA, "TLS-DHE-RSA-WITH-AES-256-CBC-SHA", + MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#if defined(MBEDTLS_CCM_C) + { MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM, "TLS-DHE-RSA-WITH-AES-256-CCM", + MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + { MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CCM_8, "TLS-DHE-RSA-WITH-AES-256-CCM-8", + MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_SHORT_TAG }, + { MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM, "TLS-DHE-RSA-WITH-AES-128-CCM", + MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + { MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CCM_8, "TLS-DHE-RSA-WITH-AES-128-CCM-8", + MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_SHORT_TAG }, +#endif /* MBEDTLS_CCM_C */ +#endif /* MBEDTLS_AES_C */ + +#if defined(MBEDTLS_CAMELLIA_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA256", + MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + + { MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256, "TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA256", + MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, "TLS-DHE-RSA-WITH-CAMELLIA-128-CBC-SHA", + MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + + { MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, "TLS-DHE-RSA-WITH-CAMELLIA-256-CBC-SHA", + MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#if defined(MBEDTLS_GCM_C) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-DHE-RSA-WITH-CAMELLIA-128-GCM-SHA256", + MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-DHE-RSA-WITH-CAMELLIA-256-GCM-SHA384", + MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_GCM_C */ +#endif /* MBEDTLS_CAMELLIA_C */ + +#if defined(MBEDTLS_DES_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, "TLS-DHE-RSA-WITH-3DES-EDE-CBC-SHA", + MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* MBEDTLS_DES_C */ +#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) +#if defined(MBEDTLS_AES_C) +#if defined(MBEDTLS_SHA512_C) && defined(MBEDTLS_GCM_C) + { MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384, "TLS-RSA-WITH-AES-256-GCM-SHA384", + MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C && MBEDTLS_GCM_C */ + +#if defined(MBEDTLS_SHA256_C) +#if defined(MBEDTLS_GCM_C) + { MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256, "TLS-RSA-WITH-AES-128-GCM-SHA256", + MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_GCM_C */ + +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256, "TLS-RSA-WITH-AES-128-CBC-SHA256", + MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + + { MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256, "TLS-RSA-WITH-AES-256-CBC-SHA256", + MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_SHA1_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA, "TLS-RSA-WITH-AES-128-CBC-SHA", + MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + + { MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA, "TLS-RSA-WITH-AES-256-CBC-SHA", + MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* MBEDTLS_SHA1_C */ +#if defined(MBEDTLS_CCM_C) + { MBEDTLS_TLS_RSA_WITH_AES_256_CCM, "TLS-RSA-WITH-AES-256-CCM", + MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + { MBEDTLS_TLS_RSA_WITH_AES_256_CCM_8, "TLS-RSA-WITH-AES-256-CCM-8", + MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_SHORT_TAG }, + { MBEDTLS_TLS_RSA_WITH_AES_128_CCM, "TLS-RSA-WITH-AES-128-CCM", + MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + { MBEDTLS_TLS_RSA_WITH_AES_128_CCM_8, "TLS-RSA-WITH-AES-128-CCM-8", + MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_SHORT_TAG }, +#endif /* MBEDTLS_CCM_C */ +#endif /* MBEDTLS_AES_C */ + +#if defined(MBEDTLS_CAMELLIA_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-RSA-WITH-CAMELLIA-128-CBC-SHA256", + MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + + { MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256, "TLS-RSA-WITH-CAMELLIA-256-CBC-SHA256", + MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, "TLS-RSA-WITH-CAMELLIA-128-CBC-SHA", + MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + + { MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, "TLS-RSA-WITH-CAMELLIA-256-CBC-SHA", + MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_GCM_C) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-RSA-WITH-CAMELLIA-128-GCM-SHA256", + MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-RSA-WITH-CAMELLIA-256-GCM-SHA384", + MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_GCM_C */ +#endif /* MBEDTLS_CAMELLIA_C */ + +#if defined(MBEDTLS_DES_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_RSA_WITH_3DES_EDE_CBC_SHA, "TLS-RSA-WITH-3DES-EDE-CBC-SHA", + MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* MBEDTLS_DES_C */ + +#if defined(MBEDTLS_ARC4_C) +#if defined(MBEDTLS_MD5_C) + { MBEDTLS_TLS_RSA_WITH_RC4_128_MD5, "TLS-RSA-WITH-RC4-128-MD5", + MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_MD5, MBEDTLS_KEY_EXCHANGE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_NODTLS }, +#endif + +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_RSA_WITH_RC4_128_SHA, "TLS-RSA-WITH-RC4-128-SHA", + MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_NODTLS }, +#endif +#endif /* MBEDTLS_ARC4_C */ +#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) +#if defined(MBEDTLS_AES_C) +#if defined(MBEDTLS_SHA1_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, "TLS-ECDH-RSA-WITH-AES-128-CBC-SHA", + MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + { MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, "TLS-ECDH-RSA-WITH-AES-256-CBC-SHA", + MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* MBEDTLS_SHA1_C */ +#if defined(MBEDTLS_SHA256_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, "TLS-ECDH-RSA-WITH-AES-128-CBC-SHA256", + MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#if defined(MBEDTLS_GCM_C) + { MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, "TLS-ECDH-RSA-WITH-AES-128-GCM-SHA256", + MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_GCM_C */ +#endif /* MBEDTLS_SHA256_C */ +#if defined(MBEDTLS_SHA512_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, "TLS-ECDH-RSA-WITH-AES-256-CBC-SHA384", + MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#if defined(MBEDTLS_GCM_C) + { MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, "TLS-ECDH-RSA-WITH-AES-256-GCM-SHA384", + MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_GCM_C */ +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_AES_C */ + +#if defined(MBEDTLS_CAMELLIA_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-ECDH-RSA-WITH-CAMELLIA-128-CBC-SHA256", + MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDH-RSA-WITH-CAMELLIA-256-CBC-SHA384", + MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_GCM_C) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-ECDH-RSA-WITH-CAMELLIA-128-GCM-SHA256", + MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-ECDH-RSA-WITH-CAMELLIA-256-GCM-SHA384", + MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_GCM_C */ +#endif /* MBEDTLS_CAMELLIA_C */ + +#if defined(MBEDTLS_DES_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, "TLS-ECDH-RSA-WITH-3DES-EDE-CBC-SHA", + MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* MBEDTLS_DES_C */ + +#if defined(MBEDTLS_ARC4_C) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_ECDH_RSA_WITH_RC4_128_SHA, "TLS-ECDH-RSA-WITH-RC4-128-SHA", + MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_NODTLS }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_ARC4_C */ + +#if defined(MBEDTLS_CIPHER_NULL_CIPHER) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_ECDH_RSA_WITH_NULL_SHA, "TLS-ECDH-RSA-WITH-NULL-SHA", + MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_WEAK }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_CIPHER_NULL_CIPHER */ +#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) +#if defined(MBEDTLS_AES_C) +#if defined(MBEDTLS_SHA1_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, "TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA", + MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + { MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, "TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA", + MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* MBEDTLS_SHA1_C */ +#if defined(MBEDTLS_SHA256_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, "TLS-ECDH-ECDSA-WITH-AES-128-CBC-SHA256", + MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#if defined(MBEDTLS_GCM_C) + { MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, "TLS-ECDH-ECDSA-WITH-AES-128-GCM-SHA256", + MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_GCM_C */ +#endif /* MBEDTLS_SHA256_C */ +#if defined(MBEDTLS_SHA512_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) + { MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, "TLS-ECDH-ECDSA-WITH-AES-256-CBC-SHA384", + MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#if defined(MBEDTLS_GCM_C) + { MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, "TLS-ECDH-ECDSA-WITH-AES-256-GCM-SHA384", + MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_GCM_C */ +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_AES_C */ + +#if defined(MBEDTLS_CAMELLIA_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256, "TLS-ECDH-ECDSA-WITH-CAMELLIA-128-CBC-SHA256", + MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDH-ECDSA-WITH-CAMELLIA-256-CBC-SHA384", + MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_GCM_C) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256, "TLS-ECDH-ECDSA-WITH-CAMELLIA-128-GCM-SHA256", + MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384, "TLS-ECDH-ECDSA-WITH-CAMELLIA-256-GCM-SHA384", + MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_GCM_C */ +#endif /* MBEDTLS_CAMELLIA_C */ + +#if defined(MBEDTLS_DES_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, "TLS-ECDH-ECDSA-WITH-3DES-EDE-CBC-SHA", + MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* MBEDTLS_DES_C */ + +#if defined(MBEDTLS_ARC4_C) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_ECDH_ECDSA_WITH_RC4_128_SHA, "TLS-ECDH-ECDSA-WITH-RC4-128-SHA", + MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_NODTLS }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_ARC4_C */ + +#if defined(MBEDTLS_CIPHER_NULL_CIPHER) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_ECDH_ECDSA_WITH_NULL_SHA, "TLS-ECDH-ECDSA-WITH-NULL-SHA", + MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_WEAK }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_CIPHER_NULL_CIPHER */ +#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) +#if defined(MBEDTLS_AES_C) +#if defined(MBEDTLS_GCM_C) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256, "TLS-PSK-WITH-AES-128-GCM-SHA256", + MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384, "TLS-PSK-WITH-AES-256-GCM-SHA384", + MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_GCM_C */ + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256, "TLS-PSK-WITH-AES-128-CBC-SHA256", + MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384, "TLS-PSK-WITH-AES-256-CBC-SHA384", + MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C */ + +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA, "TLS-PSK-WITH-AES-128-CBC-SHA", + MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + + { MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA, "TLS-PSK-WITH-AES-256-CBC-SHA", + MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#if defined(MBEDTLS_CCM_C) + { MBEDTLS_TLS_PSK_WITH_AES_256_CCM, "TLS-PSK-WITH-AES-256-CCM", + MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + { MBEDTLS_TLS_PSK_WITH_AES_256_CCM_8, "TLS-PSK-WITH-AES-256-CCM-8", + MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_SHORT_TAG }, + { MBEDTLS_TLS_PSK_WITH_AES_128_CCM, "TLS-PSK-WITH-AES-128-CCM", + MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + { MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8, "TLS-PSK-WITH-AES-128-CCM-8", + MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_SHORT_TAG }, +#endif /* MBEDTLS_CCM_C */ +#endif /* MBEDTLS_AES_C */ + +#if defined(MBEDTLS_CAMELLIA_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256, "TLS-PSK-WITH-CAMELLIA-128-CBC-SHA256", + MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-PSK-WITH-CAMELLIA-256-CBC-SHA384", + MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_GCM_C) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256, "TLS-PSK-WITH-CAMELLIA-128-GCM-SHA256", + MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384, "TLS-PSK-WITH-CAMELLIA-256-GCM-SHA384", + MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_GCM_C */ +#endif /* MBEDTLS_CAMELLIA_C */ + +#if defined(MBEDTLS_DES_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_PSK_WITH_3DES_EDE_CBC_SHA, "TLS-PSK-WITH-3DES-EDE-CBC-SHA", + MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* MBEDTLS_DES_C */ + +#if defined(MBEDTLS_ARC4_C) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_PSK_WITH_RC4_128_SHA, "TLS-PSK-WITH-RC4-128-SHA", + MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_NODTLS }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_ARC4_C */ +#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) +#if defined(MBEDTLS_AES_C) +#if defined(MBEDTLS_GCM_C) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256, "TLS-DHE-PSK-WITH-AES-128-GCM-SHA256", + MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384, "TLS-DHE-PSK-WITH-AES-256-GCM-SHA384", + MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_GCM_C */ + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256, "TLS-DHE-PSK-WITH-AES-128-CBC-SHA256", + MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384, "TLS-DHE-PSK-WITH-AES-256-CBC-SHA384", + MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C */ + +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA, "TLS-DHE-PSK-WITH-AES-128-CBC-SHA", + MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + + { MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA, "TLS-DHE-PSK-WITH-AES-256-CBC-SHA", + MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#if defined(MBEDTLS_CCM_C) + { MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM, "TLS-DHE-PSK-WITH-AES-256-CCM", + MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + { MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CCM_8, "TLS-DHE-PSK-WITH-AES-256-CCM-8", + MBEDTLS_CIPHER_AES_256_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_SHORT_TAG }, + { MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM, "TLS-DHE-PSK-WITH-AES-128-CCM", + MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + { MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CCM_8, "TLS-DHE-PSK-WITH-AES-128-CCM-8", + MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_SHORT_TAG }, +#endif /* MBEDTLS_CCM_C */ +#endif /* MBEDTLS_AES_C */ + +#if defined(MBEDTLS_CAMELLIA_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, "TLS-DHE-PSK-WITH-CAMELLIA-128-CBC-SHA256", + MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-DHE-PSK-WITH-CAMELLIA-256-CBC-SHA384", + MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_GCM_C) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256, "TLS-DHE-PSK-WITH-CAMELLIA-128-GCM-SHA256", + MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384, "TLS-DHE-PSK-WITH-CAMELLIA-256-GCM-SHA384", + MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_GCM_C */ +#endif /* MBEDTLS_CAMELLIA_C */ + +#if defined(MBEDTLS_DES_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA, "TLS-DHE-PSK-WITH-3DES-EDE-CBC-SHA", + MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* MBEDTLS_DES_C */ + +#if defined(MBEDTLS_ARC4_C) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_DHE_PSK_WITH_RC4_128_SHA, "TLS-DHE-PSK-WITH-RC4-128-SHA", + MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_NODTLS }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_ARC4_C */ +#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) +#if defined(MBEDTLS_AES_C) + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256, "TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA256", + MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384, "TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA384", + MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C */ + +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, "TLS-ECDHE-PSK-WITH-AES-128-CBC-SHA", + MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + + { MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, "TLS-ECDHE-PSK-WITH-AES-256-CBC-SHA", + MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* MBEDTLS_AES_C */ + +#if defined(MBEDTLS_CAMELLIA_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256, "TLS-ECDHE-PSK-WITH-CAMELLIA-128-CBC-SHA256", + MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-ECDHE-PSK-WITH-CAMELLIA-256-CBC-SHA384", + MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* MBEDTLS_CAMELLIA_C */ + +#if defined(MBEDTLS_DES_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA, "TLS-ECDHE-PSK-WITH-3DES-EDE-CBC-SHA", + MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* MBEDTLS_DES_C */ + +#if defined(MBEDTLS_ARC4_C) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_ECDHE_PSK_WITH_RC4_128_SHA, "TLS-ECDHE-PSK-WITH-RC4-128-SHA", + MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_NODTLS }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_ARC4_C */ +#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) +#if defined(MBEDTLS_AES_C) +#if defined(MBEDTLS_GCM_C) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256, "TLS-RSA-PSK-WITH-AES-128-GCM-SHA256", + MBEDTLS_CIPHER_AES_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384, "TLS-RSA-PSK-WITH-AES-256-GCM-SHA384", + MBEDTLS_CIPHER_AES_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_GCM_C */ + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256, "TLS-RSA-PSK-WITH-AES-128-CBC-SHA256", + MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384, "TLS-RSA-PSK-WITH-AES-256-CBC-SHA384", + MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C */ + +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA, "TLS-RSA-PSK-WITH-AES-128-CBC-SHA", + MBEDTLS_CIPHER_AES_128_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, + + { MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA, "TLS-RSA-PSK-WITH-AES-256-CBC-SHA", + MBEDTLS_CIPHER_AES_256_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* MBEDTLS_AES_C */ + +#if defined(MBEDTLS_CAMELLIA_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256, "TLS-RSA-PSK-WITH-CAMELLIA-128-CBC-SHA256", + MBEDTLS_CIPHER_CAMELLIA_128_CBC, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384, "TLS-RSA-PSK-WITH-CAMELLIA-256-CBC-SHA384", + MBEDTLS_CIPHER_CAMELLIA_256_CBC, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + +#if defined(MBEDTLS_GCM_C) +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256, "TLS-RSA-PSK-WITH-CAMELLIA-128-GCM-SHA256", + MBEDTLS_CIPHER_CAMELLIA_128_GCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384, "TLS-RSA-PSK-WITH-CAMELLIA-256-GCM-SHA384", + MBEDTLS_CIPHER_CAMELLIA_256_GCM, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_GCM_C */ +#endif /* MBEDTLS_CAMELLIA_C */ + +#if defined(MBEDTLS_DES_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA, "TLS-RSA-PSK-WITH-3DES-EDE-CBC-SHA", + MBEDTLS_CIPHER_DES_EDE3_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + 0 }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* MBEDTLS_DES_C */ + +#if defined(MBEDTLS_ARC4_C) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_RSA_PSK_WITH_RC4_128_SHA, "TLS-RSA-PSK-WITH-RC4-128-SHA", + MBEDTLS_CIPHER_ARC4_128, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_NODTLS }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_ARC4_C */ +#endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) +#if defined(MBEDTLS_AES_C) +#if defined(MBEDTLS_CCM_C) + { MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8, "TLS-ECJPAKE-WITH-AES-128-CCM-8", + MBEDTLS_CIPHER_AES_128_CCM, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECJPAKE, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_SHORT_TAG }, +#endif /* MBEDTLS_CCM_C */ +#endif /* MBEDTLS_AES_C */ +#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ + +#if defined(MBEDTLS_ENABLE_WEAK_CIPHERSUITES) +#if defined(MBEDTLS_CIPHER_NULL_CIPHER) +#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) +#if defined(MBEDTLS_MD5_C) + { MBEDTLS_TLS_RSA_WITH_NULL_MD5, "TLS-RSA-WITH-NULL-MD5", + MBEDTLS_CIPHER_NULL, MBEDTLS_MD_MD5, MBEDTLS_KEY_EXCHANGE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_WEAK }, +#endif + +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_RSA_WITH_NULL_SHA, "TLS-RSA-WITH-NULL-SHA", + MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_WEAK }, +#endif + +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_RSA_WITH_NULL_SHA256, "TLS-RSA-WITH-NULL-SHA256", + MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_WEAK }, +#endif +#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_PSK_WITH_NULL_SHA, "TLS-PSK-WITH-NULL-SHA", + MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_WEAK }, +#endif /* MBEDTLS_SHA1_C */ + +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_PSK_WITH_NULL_SHA256, "TLS-PSK-WITH-NULL-SHA256", + MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_WEAK }, +#endif + +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_PSK_WITH_NULL_SHA384, "TLS-PSK-WITH-NULL-SHA384", + MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_WEAK }, +#endif +#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA, "TLS-DHE-PSK-WITH-NULL-SHA", + MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_WEAK }, +#endif /* MBEDTLS_SHA1_C */ + +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA256, "TLS-DHE-PSK-WITH-NULL-SHA256", + MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_DHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_WEAK }, +#endif + +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA384, "TLS-DHE-PSK-WITH-NULL-SHA384", + MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_DHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_WEAK }, +#endif +#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA, "TLS-ECDHE-PSK-WITH-NULL-SHA", + MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_WEAK }, +#endif /* MBEDTLS_SHA1_C */ + +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256, "TLS-ECDHE-PSK-WITH-NULL-SHA256", + MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_WEAK }, +#endif + +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384, "TLS-ECDHE-PSK-WITH-NULL-SHA384", + MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_ECDHE_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_WEAK }, +#endif +#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA, "TLS-RSA-PSK-WITH-NULL-SHA", + MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_WEAK }, +#endif /* MBEDTLS_SHA1_C */ + +#if defined(MBEDTLS_SHA256_C) + { MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA256, "TLS-RSA-PSK-WITH-NULL-SHA256", + MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA256, MBEDTLS_KEY_EXCHANGE_RSA_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_WEAK }, +#endif + +#if defined(MBEDTLS_SHA512_C) + { MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384, "TLS-RSA-PSK-WITH-NULL-SHA384", + MBEDTLS_CIPHER_NULL, MBEDTLS_MD_SHA384, MBEDTLS_KEY_EXCHANGE_RSA_PSK, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_WEAK }, +#endif +#endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ +#endif /* MBEDTLS_CIPHER_NULL_CIPHER */ + +#if defined(MBEDTLS_DES_C) +#if defined(MBEDTLS_CIPHER_MODE_CBC) +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_DHE_RSA_WITH_DES_CBC_SHA, "TLS-DHE-RSA-WITH-DES-CBC-SHA", + MBEDTLS_CIPHER_DES_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_DHE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_WEAK }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) +#if defined(MBEDTLS_SHA1_C) + { MBEDTLS_TLS_RSA_WITH_DES_CBC_SHA, "TLS-RSA-WITH-DES-CBC-SHA", + MBEDTLS_CIPHER_DES_CBC, MBEDTLS_MD_SHA1, MBEDTLS_KEY_EXCHANGE_RSA, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_0, + MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3, + MBEDTLS_CIPHERSUITE_WEAK }, +#endif /* MBEDTLS_SHA1_C */ +#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* MBEDTLS_DES_C */ +#endif /* MBEDTLS_ENABLE_WEAK_CIPHERSUITES */ + + { 0, "", + MBEDTLS_CIPHER_NONE, MBEDTLS_MD_NONE, MBEDTLS_KEY_EXCHANGE_NONE, + 0, 0, 0, 0, 0 } +}; + +#if defined(MBEDTLS_SSL_CIPHERSUITES) +const int *mbedtls_ssl_list_ciphersuites( void ) +{ + return( ciphersuite_preference ); +} +#else +#define MAX_CIPHERSUITES sizeof( ciphersuite_definitions ) / \ + sizeof( ciphersuite_definitions[0] ) +static int supported_ciphersuites[MAX_CIPHERSUITES]; +static int supported_init = 0; + +const int *mbedtls_ssl_list_ciphersuites( void ) +{ + /* + * On initial call filter out all ciphersuites not supported by current + * build based on presence in the ciphersuite_definitions. + */ + if( supported_init == 0 ) + { + const int *p; + int *q; + + for( p = ciphersuite_preference, q = supported_ciphersuites; + *p != 0 && q < supported_ciphersuites + MAX_CIPHERSUITES - 1; + p++ ) + { +#if defined(MBEDTLS_REMOVE_ARC4_CIPHERSUITES) + const mbedtls_ssl_ciphersuite_t *cs_info; + if( ( cs_info = mbedtls_ssl_ciphersuite_from_id( *p ) ) != NULL && + cs_info->cipher != MBEDTLS_CIPHER_ARC4_128 ) +#else + if( mbedtls_ssl_ciphersuite_from_id( *p ) != NULL ) +#endif + *(q++) = *p; + } + *q = 0; + + supported_init = 1; + } + + return( supported_ciphersuites ); +} +#endif /* MBEDTLS_SSL_CIPHERSUITES */ + +const mbedtls_ssl_ciphersuite_t *mbedtls_ssl_ciphersuite_from_string( + const char *ciphersuite_name ) +{ + const mbedtls_ssl_ciphersuite_t *cur = ciphersuite_definitions; + + if( NULL == ciphersuite_name ) + return( NULL ); + + while( cur->id != 0 ) + { + if( 0 == strcmp( cur->name, ciphersuite_name ) ) + return( cur ); + + cur++; + } + + return( NULL ); +} + +const mbedtls_ssl_ciphersuite_t *mbedtls_ssl_ciphersuite_from_id( int ciphersuite ) +{ + const mbedtls_ssl_ciphersuite_t *cur = ciphersuite_definitions; + + while( cur->id != 0 ) + { + if( cur->id == ciphersuite ) + return( cur ); + + cur++; + } + + return( NULL ); +} + +const char *mbedtls_ssl_get_ciphersuite_name( const int ciphersuite_id ) +{ + const mbedtls_ssl_ciphersuite_t *cur; + + cur = mbedtls_ssl_ciphersuite_from_id( ciphersuite_id ); + + if( cur == NULL ) + return( "unknown" ); + + return( cur->name ); +} + +int mbedtls_ssl_get_ciphersuite_id( const char *ciphersuite_name ) +{ + const mbedtls_ssl_ciphersuite_t *cur; + + cur = mbedtls_ssl_ciphersuite_from_string( ciphersuite_name ); + + if( cur == NULL ) + return( 0 ); + + return( cur->id ); +} + +#if defined(MBEDTLS_PK_C) +mbedtls_pk_type_t mbedtls_ssl_get_ciphersuite_sig_pk_alg( const mbedtls_ssl_ciphersuite_t *info ) +{ + switch( info->key_exchange ) + { + case MBEDTLS_KEY_EXCHANGE_RSA: + case MBEDTLS_KEY_EXCHANGE_DHE_RSA: + case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: + case MBEDTLS_KEY_EXCHANGE_RSA_PSK: + return( MBEDTLS_PK_RSA ); + + case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: + return( MBEDTLS_PK_ECDSA ); + + case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: + case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: + return( MBEDTLS_PK_ECKEY ); + + default: + return( MBEDTLS_PK_NONE ); + } +} +#endif /* MBEDTLS_PK_C */ + +#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) +int mbedtls_ssl_ciphersuite_uses_ec( const mbedtls_ssl_ciphersuite_t *info ) +{ + switch( info->key_exchange ) + { + case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: + case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: + case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK: + case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: + case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: + return( 1 ); + + default: + return( 0 ); + } +} +#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */ + +#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) +int mbedtls_ssl_ciphersuite_uses_psk( const mbedtls_ssl_ciphersuite_t *info ) +{ + switch( info->key_exchange ) + { + case MBEDTLS_KEY_EXCHANGE_PSK: + case MBEDTLS_KEY_EXCHANGE_RSA_PSK: + case MBEDTLS_KEY_EXCHANGE_DHE_PSK: + case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK: + return( 1 ); + + default: + return( 0 ); + } +} +#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ + +#endif /* MBEDTLS_SSL_TLS_C */ diff --git a/security/mbedtls/src/ssl_cli.c b/security/mbedtls/src/ssl_cli.c new file mode 100644 index 0000000000..223823b3cd --- /dev/null +++ b/security/mbedtls/src/ssl_cli.c @@ -0,0 +1,3405 @@ +/* + * SSLv3/TLSv1 client-side functions + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_SSL_CLI_C) + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_calloc calloc +#define mbedtls_free free +#endif + +#include "mbedtls/debug.h" +#include "mbedtls/ssl.h" +#include "mbedtls/ssl_internal.h" + +#include + +#include + +#if defined(MBEDTLS_HAVE_TIME) +#include "mbedtls/platform_time.h" +#endif + +#if defined(MBEDTLS_SSL_SESSION_TICKETS) +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} +#endif + +#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) +static void ssl_write_hostname_ext( mbedtls_ssl_context *ssl, + unsigned char *buf, + size_t *olen ) +{ + unsigned char *p = buf; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; + size_t hostname_len; + + *olen = 0; + + if( ssl->hostname == NULL ) + return; + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding server name extension: %s", + ssl->hostname ) ); + + hostname_len = strlen( ssl->hostname ); + + if( end < p || (size_t)( end - p ) < hostname_len + 9 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); + return; + } + + /* + * struct { + * NameType name_type; + * select (name_type) { + * case host_name: HostName; + * } name; + * } ServerName; + * + * enum { + * host_name(0), (255) + * } NameType; + * + * opaque HostName<1..2^16-1>; + * + * struct { + * ServerName server_name_list<1..2^16-1> + * } ServerNameList; + */ + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME ) & 0xFF ); + + *p++ = (unsigned char)( ( (hostname_len + 5) >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( (hostname_len + 5) ) & 0xFF ); + + *p++ = (unsigned char)( ( (hostname_len + 3) >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( (hostname_len + 3) ) & 0xFF ); + + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SERVERNAME_HOSTNAME ) & 0xFF ); + *p++ = (unsigned char)( ( hostname_len >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( hostname_len ) & 0xFF ); + + memcpy( p, ssl->hostname, hostname_len ); + + *olen = hostname_len + 9; +} +#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ + +#if defined(MBEDTLS_SSL_RENEGOTIATION) +static void ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl, + unsigned char *buf, + size_t *olen ) +{ + unsigned char *p = buf; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; + + *olen = 0; + + if( ssl->renego_status != MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS ) + return; + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding renegotiation extension" ) ); + + if( end < p || (size_t)( end - p ) < 5 + ssl->verify_data_len ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); + return; + } + + /* + * Secure renegotiation + */ + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO ) & 0xFF ); + + *p++ = 0x00; + *p++ = ( ssl->verify_data_len + 1 ) & 0xFF; + *p++ = ssl->verify_data_len & 0xFF; + + memcpy( p, ssl->own_verify_data, ssl->verify_data_len ); + + *olen = 5 + ssl->verify_data_len; +} +#endif /* MBEDTLS_SSL_RENEGOTIATION */ + +/* + * Only if we handle at least one key exchange that needs signatures. + */ +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ + defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) +static void ssl_write_signature_algorithms_ext( mbedtls_ssl_context *ssl, + unsigned char *buf, + size_t *olen ) +{ + unsigned char *p = buf; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; + size_t sig_alg_len = 0; + const int *md; +#if defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECDSA_C) + unsigned char *sig_alg_list = buf + 6; +#endif + + *olen = 0; + + if( ssl->conf->max_minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 ) + return; + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding signature_algorithms extension" ) ); + + for( md = ssl->conf->sig_hashes; *md != MBEDTLS_MD_NONE; md++ ) + { +#if defined(MBEDTLS_ECDSA_C) + sig_alg_len += 2; +#endif +#if defined(MBEDTLS_RSA_C) + sig_alg_len += 2; +#endif + } + + if( end < p || (size_t)( end - p ) < sig_alg_len + 6 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); + return; + } + + /* + * Prepare signature_algorithms extension (TLS 1.2) + */ + sig_alg_len = 0; + + for( md = ssl->conf->sig_hashes; *md != MBEDTLS_MD_NONE; md++ ) + { +#if defined(MBEDTLS_ECDSA_C) + sig_alg_list[sig_alg_len++] = mbedtls_ssl_hash_from_md_alg( *md ); + sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_ECDSA; +#endif +#if defined(MBEDTLS_RSA_C) + sig_alg_list[sig_alg_len++] = mbedtls_ssl_hash_from_md_alg( *md ); + sig_alg_list[sig_alg_len++] = MBEDTLS_SSL_SIG_RSA; +#endif + } + + /* + * enum { + * none(0), md5(1), sha1(2), sha224(3), sha256(4), sha384(5), + * sha512(6), (255) + * } HashAlgorithm; + * + * enum { anonymous(0), rsa(1), dsa(2), ecdsa(3), (255) } + * SignatureAlgorithm; + * + * struct { + * HashAlgorithm hash; + * SignatureAlgorithm signature; + * } SignatureAndHashAlgorithm; + * + * SignatureAndHashAlgorithm + * supported_signature_algorithms<2..2^16-2>; + */ + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SIG_ALG >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SIG_ALG ) & 0xFF ); + + *p++ = (unsigned char)( ( ( sig_alg_len + 2 ) >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( ( sig_alg_len + 2 ) ) & 0xFF ); + + *p++ = (unsigned char)( ( sig_alg_len >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( sig_alg_len ) & 0xFF ); + + *olen = 6 + sig_alg_len; +} +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && + MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ + +#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) +static void ssl_write_supported_elliptic_curves_ext( mbedtls_ssl_context *ssl, + unsigned char *buf, + size_t *olen ) +{ + unsigned char *p = buf; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; + unsigned char *elliptic_curve_list = p + 6; + size_t elliptic_curve_len = 0; + const mbedtls_ecp_curve_info *info; +#if defined(MBEDTLS_ECP_C) + const mbedtls_ecp_group_id *grp_id; +#else + ((void) ssl); +#endif + + *olen = 0; + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding supported_elliptic_curves extension" ) ); + +#if defined(MBEDTLS_ECP_C) + for( grp_id = ssl->conf->curve_list; *grp_id != MBEDTLS_ECP_DP_NONE; grp_id++ ) + { + info = mbedtls_ecp_curve_info_from_grp_id( *grp_id ); +#else + for( info = mbedtls_ecp_curve_list(); info->grp_id != MBEDTLS_ECP_DP_NONE; info++ ) + { +#endif + if( info == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid curve in ssl configuration" ) ); + return; + } + + elliptic_curve_len += 2; + } + + if( end < p || (size_t)( end - p ) < 6 + elliptic_curve_len ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); + return; + } + + elliptic_curve_len = 0; + +#if defined(MBEDTLS_ECP_C) + for( grp_id = ssl->conf->curve_list; *grp_id != MBEDTLS_ECP_DP_NONE; grp_id++ ) + { + info = mbedtls_ecp_curve_info_from_grp_id( *grp_id ); +#else + for( info = mbedtls_ecp_curve_list(); info->grp_id != MBEDTLS_ECP_DP_NONE; info++ ) + { +#endif + elliptic_curve_list[elliptic_curve_len++] = info->tls_id >> 8; + elliptic_curve_list[elliptic_curve_len++] = info->tls_id & 0xFF; + } + + if( elliptic_curve_len == 0 ) + return; + + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES ) & 0xFF ); + + *p++ = (unsigned char)( ( ( elliptic_curve_len + 2 ) >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( ( elliptic_curve_len + 2 ) ) & 0xFF ); + + *p++ = (unsigned char)( ( ( elliptic_curve_len ) >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( ( elliptic_curve_len ) ) & 0xFF ); + + *olen = 6 + elliptic_curve_len; +} + +static void ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl, + unsigned char *buf, + size_t *olen ) +{ + unsigned char *p = buf; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; + + *olen = 0; + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding supported_point_formats extension" ) ); + + if( end < p || (size_t)( end - p ) < 6 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); + return; + } + + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS ) & 0xFF ); + + *p++ = 0x00; + *p++ = 2; + + *p++ = 1; + *p++ = MBEDTLS_ECP_PF_UNCOMPRESSED; + + *olen = 6; +} +#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || + MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) +static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl, + unsigned char *buf, + size_t *olen ) +{ + int ret; + unsigned char *p = buf; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; + size_t kkpp_len; + + *olen = 0; + + /* Skip costly extension if we can't use EC J-PAKE anyway */ + if( mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 ) + return; + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding ecjpake_kkpp extension" ) ); + + if( end - p < 4 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); + return; + } + + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP ) & 0xFF ); + + /* + * We may need to send ClientHello multiple times for Hello verification. + * We don't want to compute fresh values every time (both for performance + * and consistency reasons), so cache the extension content. + */ + if( ssl->handshake->ecjpake_cache == NULL || + ssl->handshake->ecjpake_cache_len == 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "generating new ecjpake parameters" ) ); + + ret = mbedtls_ecjpake_write_round_one( &ssl->handshake->ecjpake_ctx, + p + 2, end - p - 2, &kkpp_len, + ssl->conf->f_rng, ssl->conf->p_rng ); + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1 , "mbedtls_ecjpake_write_round_one", ret ); + return; + } + + ssl->handshake->ecjpake_cache = mbedtls_calloc( 1, kkpp_len ); + if( ssl->handshake->ecjpake_cache == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "allocation failed" ) ); + return; + } + + memcpy( ssl->handshake->ecjpake_cache, p + 2, kkpp_len ); + ssl->handshake->ecjpake_cache_len = kkpp_len; + } + else + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "re-using cached ecjpake parameters" ) ); + + kkpp_len = ssl->handshake->ecjpake_cache_len; + + if( (size_t)( end - p - 2 ) < kkpp_len ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); + return; + } + + memcpy( p + 2, ssl->handshake->ecjpake_cache, kkpp_len ); + } + + *p++ = (unsigned char)( ( kkpp_len >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( kkpp_len ) & 0xFF ); + + *olen = kkpp_len + 4; +} +#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ + +#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) +static void ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl, + unsigned char *buf, + size_t *olen ) +{ + unsigned char *p = buf; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; + + *olen = 0; + + if( ssl->conf->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE ) { + return; + } + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding max_fragment_length extension" ) ); + + if( end < p || (size_t)( end - p ) < 5 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); + return; + } + + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH ) & 0xFF ); + + *p++ = 0x00; + *p++ = 1; + + *p++ = ssl->conf->mfl_code; + + *olen = 5; +} +#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ + +#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) +static void ssl_write_truncated_hmac_ext( mbedtls_ssl_context *ssl, + unsigned char *buf, size_t *olen ) +{ + unsigned char *p = buf; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; + + *olen = 0; + + if( ssl->conf->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_DISABLED ) + { + return; + } + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding truncated_hmac extension" ) ); + + if( end < p || (size_t)( end - p ) < 4 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); + return; + } + + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC ) & 0xFF ); + + *p++ = 0x00; + *p++ = 0x00; + + *olen = 4; +} +#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ + +#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) +static void ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl, + unsigned char *buf, size_t *olen ) +{ + unsigned char *p = buf; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; + + *olen = 0; + + if( ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED || + ssl->conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) + { + return; + } + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding encrypt_then_mac " + "extension" ) ); + + if( end < p || (size_t)( end - p ) < 4 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); + return; + } + + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC ) & 0xFF ); + + *p++ = 0x00; + *p++ = 0x00; + + *olen = 4; +} +#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ + +#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) +static void ssl_write_extended_ms_ext( mbedtls_ssl_context *ssl, + unsigned char *buf, size_t *olen ) +{ + unsigned char *p = buf; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; + + *olen = 0; + + if( ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED || + ssl->conf->max_minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) + { + return; + } + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding extended_master_secret " + "extension" ) ); + + if( end < p || (size_t)( end - p ) < 4 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); + return; + } + + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET ) & 0xFF ); + + *p++ = 0x00; + *p++ = 0x00; + + *olen = 4; +} +#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ + +#if defined(MBEDTLS_SSL_SESSION_TICKETS) +static void ssl_write_session_ticket_ext( mbedtls_ssl_context *ssl, + unsigned char *buf, size_t *olen ) +{ + unsigned char *p = buf; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; + size_t tlen = ssl->session_negotiate->ticket_len; + + *olen = 0; + + if( ssl->conf->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED ) + { + return; + } + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding session ticket extension" ) ); + + if( end < p || (size_t)( end - p ) < 4 + tlen ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); + return; + } + + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET ) & 0xFF ); + + *p++ = (unsigned char)( ( tlen >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( tlen ) & 0xFF ); + + *olen = 4; + + if( ssl->session_negotiate->ticket == NULL || tlen == 0 ) + { + return; + } + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "sending session ticket of length %d", tlen ) ); + + memcpy( p, ssl->session_negotiate->ticket, tlen ); + + *olen += tlen; +} +#endif /* MBEDTLS_SSL_SESSION_TICKETS */ + +#if defined(MBEDTLS_SSL_ALPN) +static void ssl_write_alpn_ext( mbedtls_ssl_context *ssl, + unsigned char *buf, size_t *olen ) +{ + unsigned char *p = buf; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; + size_t alpnlen = 0; + const char **cur; + + *olen = 0; + + if( ssl->conf->alpn_list == NULL ) + { + return; + } + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, adding alpn extension" ) ); + + for( cur = ssl->conf->alpn_list; *cur != NULL; cur++ ) + alpnlen += (unsigned char)( strlen( *cur ) & 0xFF ) + 1; + + if( end < p || (size_t)( end - p ) < 6 + alpnlen ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); + return; + } + + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN ) & 0xFF ); + + /* + * opaque ProtocolName<1..2^8-1>; + * + * struct { + * ProtocolName protocol_name_list<2..2^16-1> + * } ProtocolNameList; + */ + + /* Skip writing extension and list length for now */ + p += 4; + + for( cur = ssl->conf->alpn_list; *cur != NULL; cur++ ) + { + *p = (unsigned char)( strlen( *cur ) & 0xFF ); + memcpy( p + 1, *cur, *p ); + p += 1 + *p; + } + + *olen = p - buf; + + /* List length = olen - 2 (ext_type) - 2 (ext_len) - 2 (list_len) */ + buf[4] = (unsigned char)( ( ( *olen - 6 ) >> 8 ) & 0xFF ); + buf[5] = (unsigned char)( ( ( *olen - 6 ) ) & 0xFF ); + + /* Extension length = olen - 2 (ext_type) - 2 (ext_len) */ + buf[2] = (unsigned char)( ( ( *olen - 4 ) >> 8 ) & 0xFF ); + buf[3] = (unsigned char)( ( ( *olen - 4 ) ) & 0xFF ); +} +#endif /* MBEDTLS_SSL_ALPN */ + +/* + * Generate random bytes for ClientHello + */ +static int ssl_generate_random( mbedtls_ssl_context *ssl ) +{ + int ret; + unsigned char *p = ssl->handshake->randbytes; +#if defined(MBEDTLS_HAVE_TIME) + mbedtls_time_t t; +#endif + + /* + * When responding to a verify request, MUST reuse random (RFC 6347 4.2.1) + */ +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && + ssl->handshake->verify_cookie != NULL ) + { + return( 0 ); + } +#endif + +#if defined(MBEDTLS_HAVE_TIME) + t = mbedtls_time( NULL ); + *p++ = (unsigned char)( t >> 24 ); + *p++ = (unsigned char)( t >> 16 ); + *p++ = (unsigned char)( t >> 8 ); + *p++ = (unsigned char)( t ); + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, current time: %lu", t ) ); +#else + if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 4 ) ) != 0 ) + return( ret ); + + p += 4; +#endif /* MBEDTLS_HAVE_TIME */ + + if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 28 ) ) != 0 ) + return( ret ); + + return( 0 ); +} + +static int ssl_write_client_hello( mbedtls_ssl_context *ssl ) +{ + int ret; + size_t i, n, olen, ext_len = 0; + unsigned char *buf; + unsigned char *p, *q; + unsigned char offer_compress; + const int *ciphersuites; + const mbedtls_ssl_ciphersuite_t *ciphersuite_info; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write client hello" ) ); + + if( ssl->conf->f_rng == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "no RNG provided") ); + return( MBEDTLS_ERR_SSL_NO_RNG ); + } + +#if defined(MBEDTLS_SSL_RENEGOTIATION) + if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE ) +#endif + { + ssl->major_ver = ssl->conf->min_major_ver; + ssl->minor_ver = ssl->conf->min_minor_ver; + } + + if( ssl->conf->max_major_ver == 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "configured max major version is invalid, " + "consider using mbedtls_ssl_config_defaults()" ) ); + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + } + + /* + * 0 . 0 handshake type + * 1 . 3 handshake length + * 4 . 5 highest version supported + * 6 . 9 current UNIX time + * 10 . 37 random bytes + */ + buf = ssl->out_msg; + p = buf + 4; + + mbedtls_ssl_write_version( ssl->conf->max_major_ver, ssl->conf->max_minor_ver, + ssl->conf->transport, p ); + p += 2; + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, max version: [%d:%d]", + buf[4], buf[5] ) ); + + if( ( ret = ssl_generate_random( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "ssl_generate_random", ret ); + return( ret ); + } + + memcpy( p, ssl->handshake->randbytes, 32 ); + MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, random bytes", p, 32 ); + p += 32; + + /* + * 38 . 38 session id length + * 39 . 39+n session id + * 39+n . 39+n DTLS only: cookie length (1 byte) + * 40+n . .. DTSL only: cookie + * .. . .. ciphersuitelist length (2 bytes) + * .. . .. ciphersuitelist + * .. . .. compression methods length (1 byte) + * .. . .. compression methods + * .. . .. extensions length (2 bytes) + * .. . .. extensions + */ + n = ssl->session_negotiate->id_len; + + if( n < 16 || n > 32 || +#if defined(MBEDTLS_SSL_RENEGOTIATION) + ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE || +#endif + ssl->handshake->resume == 0 ) + { + n = 0; + } + +#if defined(MBEDTLS_SSL_SESSION_TICKETS) + /* + * RFC 5077 section 3.4: "When presenting a ticket, the client MAY + * generate and include a Session ID in the TLS ClientHello." + */ +#if defined(MBEDTLS_SSL_RENEGOTIATION) + if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE ) +#endif + { + if( ssl->session_negotiate->ticket != NULL && + ssl->session_negotiate->ticket_len != 0 ) + { + ret = ssl->conf->f_rng( ssl->conf->p_rng, ssl->session_negotiate->id, 32 ); + + if( ret != 0 ) + return( ret ); + + ssl->session_negotiate->id_len = n = 32; + } + } +#endif /* MBEDTLS_SSL_SESSION_TICKETS */ + + *p++ = (unsigned char) n; + + for( i = 0; i < n; i++ ) + *p++ = ssl->session_negotiate->id[i]; + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, session id len.: %d", n ) ); + MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, session id", buf + 39, n ); + + /* + * DTLS cookie + */ +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + { + if( ssl->handshake->verify_cookie == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "no verify cookie to send" ) ); + *p++ = 0; + } + else + { + MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, cookie", + ssl->handshake->verify_cookie, + ssl->handshake->verify_cookie_len ); + + *p++ = ssl->handshake->verify_cookie_len; + memcpy( p, ssl->handshake->verify_cookie, + ssl->handshake->verify_cookie_len ); + p += ssl->handshake->verify_cookie_len; + } + } +#endif + + /* + * Ciphersuite list + */ + ciphersuites = ssl->conf->ciphersuite_list[ssl->minor_ver]; + + /* Skip writing ciphersuite length for now */ + n = 0; + q = p; + p += 2; + + for( i = 0; ciphersuites[i] != 0; i++ ) + { + ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( ciphersuites[i] ); + + if( ciphersuite_info == NULL ) + continue; + + if( ciphersuite_info->min_minor_ver > ssl->conf->max_minor_ver || + ciphersuite_info->max_minor_ver < ssl->conf->min_minor_ver ) + continue; + +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && + ( ciphersuite_info->flags & MBEDTLS_CIPHERSUITE_NODTLS ) ) + continue; +#endif + +#if defined(MBEDTLS_ARC4_C) + if( ssl->conf->arc4_disabled == MBEDTLS_SSL_ARC4_DISABLED && + ciphersuite_info->cipher == MBEDTLS_CIPHER_ARC4_128 ) + continue; +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE && + mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 ) + continue; +#endif + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, add ciphersuite: %04x", + ciphersuites[i] ) ); + + n++; + *p++ = (unsigned char)( ciphersuites[i] >> 8 ); + *p++ = (unsigned char)( ciphersuites[i] ); + } + + /* + * Add TLS_EMPTY_RENEGOTIATION_INFO_SCSV + */ +#if defined(MBEDTLS_SSL_RENEGOTIATION) + if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE ) +#endif + { + *p++ = (unsigned char)( MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO >> 8 ); + *p++ = (unsigned char)( MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO ); + n++; + } + + /* Some versions of OpenSSL don't handle it correctly if not at end */ +#if defined(MBEDTLS_SSL_FALLBACK_SCSV) + if( ssl->conf->fallback == MBEDTLS_SSL_IS_FALLBACK ) + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "adding FALLBACK_SCSV" ) ); + *p++ = (unsigned char)( MBEDTLS_SSL_FALLBACK_SCSV_VALUE >> 8 ); + *p++ = (unsigned char)( MBEDTLS_SSL_FALLBACK_SCSV_VALUE ); + n++; + } +#endif + + *q++ = (unsigned char)( n >> 7 ); + *q++ = (unsigned char)( n << 1 ); + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, got %d ciphersuites", n ) ); + +#if defined(MBEDTLS_ZLIB_SUPPORT) + offer_compress = 1; +#else + offer_compress = 0; +#endif + + /* + * We don't support compression with DTLS right now: is many records come + * in the same datagram, uncompressing one could overwrite the next one. + * We don't want to add complexity for handling that case unless there is + * an actual need for it. + */ +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + offer_compress = 0; +#endif + + if( offer_compress ) + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress len.: %d", 2 ) ); + MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress alg.: %d %d", + MBEDTLS_SSL_COMPRESS_DEFLATE, MBEDTLS_SSL_COMPRESS_NULL ) ); + + *p++ = 2; + *p++ = MBEDTLS_SSL_COMPRESS_DEFLATE; + *p++ = MBEDTLS_SSL_COMPRESS_NULL; + } + else + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress len.: %d", 1 ) ); + MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, compress alg.: %d", + MBEDTLS_SSL_COMPRESS_NULL ) ); + + *p++ = 1; + *p++ = MBEDTLS_SSL_COMPRESS_NULL; + } + + // First write extensions, then the total length + // +#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) + ssl_write_hostname_ext( ssl, p + 2 + ext_len, &olen ); + ext_len += olen; +#endif + +#if defined(MBEDTLS_SSL_RENEGOTIATION) + ssl_write_renegotiation_ext( ssl, p + 2 + ext_len, &olen ); + ext_len += olen; +#endif + +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ + defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) + ssl_write_signature_algorithms_ext( ssl, p + 2 + ext_len, &olen ); + ext_len += olen; +#endif + +#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) + ssl_write_supported_elliptic_curves_ext( ssl, p + 2 + ext_len, &olen ); + ext_len += olen; + + ssl_write_supported_point_formats_ext( ssl, p + 2 + ext_len, &olen ); + ext_len += olen; +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) + ssl_write_ecjpake_kkpp_ext( ssl, p + 2 + ext_len, &olen ); + ext_len += olen; +#endif + +#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) + ssl_write_max_fragment_length_ext( ssl, p + 2 + ext_len, &olen ); + ext_len += olen; +#endif + +#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) + ssl_write_truncated_hmac_ext( ssl, p + 2 + ext_len, &olen ); + ext_len += olen; +#endif + +#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) + ssl_write_encrypt_then_mac_ext( ssl, p + 2 + ext_len, &olen ); + ext_len += olen; +#endif + +#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) + ssl_write_extended_ms_ext( ssl, p + 2 + ext_len, &olen ); + ext_len += olen; +#endif + +#if defined(MBEDTLS_SSL_ALPN) + ssl_write_alpn_ext( ssl, p + 2 + ext_len, &olen ); + ext_len += olen; +#endif + +#if defined(MBEDTLS_SSL_SESSION_TICKETS) + ssl_write_session_ticket_ext( ssl, p + 2 + ext_len, &olen ); + ext_len += olen; +#endif + + /* olen unused if all extensions are disabled */ + ((void) olen); + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello, total extension length: %d", + ext_len ) ); + + if( ext_len > 0 ) + { + *p++ = (unsigned char)( ( ext_len >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( ext_len ) & 0xFF ); + p += ext_len; + } + + ssl->out_msglen = p - buf; + ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; + ssl->out_msg[0] = MBEDTLS_SSL_HS_CLIENT_HELLO; + + ssl->state++; + +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + mbedtls_ssl_send_flight_completed( ssl ); +#endif + + if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); + return( ret ); + } + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write client hello" ) ); + + return( 0 ); +} + +static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl, + const unsigned char *buf, + size_t len ) +{ + int ret; + +#if defined(MBEDTLS_SSL_RENEGOTIATION) + if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ) + { + /* Check verify-data in constant-time. The length OTOH is no secret */ + if( len != 1 + ssl->verify_data_len * 2 || + buf[0] != ssl->verify_data_len * 2 || + mbedtls_ssl_safer_memcmp( buf + 1, + ssl->own_verify_data, ssl->verify_data_len ) != 0 || + mbedtls_ssl_safer_memcmp( buf + 1 + ssl->verify_data_len, + ssl->peer_verify_data, ssl->verify_data_len ) != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching renegotiation info" ) ); + + if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 ) + return( ret ); + + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); + } + } + else +#endif /* MBEDTLS_SSL_RENEGOTIATION */ + { + if( len != 1 || buf[0] != 0x00 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-zero length renegotiation info" ) ); + + if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 ) + return( ret ); + + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); + } + + ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION; + } + + return( 0 ); +} + +#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) +static int ssl_parse_max_fragment_length_ext( mbedtls_ssl_context *ssl, + const unsigned char *buf, + size_t len ) +{ + /* + * server should use the extension only if we did, + * and if so the server's value should match ours (and len is always 1) + */ + if( ssl->conf->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE || + len != 1 || + buf[0] != ssl->conf->mfl_code ) + { + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); + } + + return( 0 ); +} +#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ + +#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) +static int ssl_parse_truncated_hmac_ext( mbedtls_ssl_context *ssl, + const unsigned char *buf, + size_t len ) +{ + if( ssl->conf->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_DISABLED || + len != 0 ) + { + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); + } + + ((void) buf); + + ssl->session_negotiate->trunc_hmac = MBEDTLS_SSL_TRUNC_HMAC_ENABLED; + + return( 0 ); +} +#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ + +#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) +static int ssl_parse_encrypt_then_mac_ext( mbedtls_ssl_context *ssl, + const unsigned char *buf, + size_t len ) +{ + if( ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED || + ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 || + len != 0 ) + { + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); + } + + ((void) buf); + + ssl->session_negotiate->encrypt_then_mac = MBEDTLS_SSL_ETM_ENABLED; + + return( 0 ); +} +#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ + +#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) +static int ssl_parse_extended_ms_ext( mbedtls_ssl_context *ssl, + const unsigned char *buf, + size_t len ) +{ + if( ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED || + ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 || + len != 0 ) + { + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); + } + + ((void) buf); + + ssl->handshake->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED; + + return( 0 ); +} +#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ + +#if defined(MBEDTLS_SSL_SESSION_TICKETS) +static int ssl_parse_session_ticket_ext( mbedtls_ssl_context *ssl, + const unsigned char *buf, + size_t len ) +{ + if( ssl->conf->session_tickets == MBEDTLS_SSL_SESSION_TICKETS_DISABLED || + len != 0 ) + { + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); + } + + ((void) buf); + + ssl->handshake->new_session_ticket = 1; + + return( 0 ); +} +#endif /* MBEDTLS_SSL_SESSION_TICKETS */ + +#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) +static int ssl_parse_supported_point_formats_ext( mbedtls_ssl_context *ssl, + const unsigned char *buf, + size_t len ) +{ + size_t list_size; + const unsigned char *p; + + list_size = buf[0]; + if( list_size + 1 != len ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); + } + + p = buf + 1; + while( list_size > 0 ) + { + if( p[0] == MBEDTLS_ECP_PF_UNCOMPRESSED || + p[0] == MBEDTLS_ECP_PF_COMPRESSED ) + { +#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) + ssl->handshake->ecdh_ctx.point_format = p[0]; +#endif +#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) + ssl->handshake->ecjpake_ctx.point_format = p[0]; +#endif + MBEDTLS_SSL_DEBUG_MSG( 4, ( "point format selected: %d", p[0] ) ); + return( 0 ); + } + + list_size--; + p++; + } + + MBEDTLS_SSL_DEBUG_MSG( 1, ( "no point format in common" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); +} +#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || + MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) +static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl, + const unsigned char *buf, + size_t len ) +{ + int ret; + + if( ssl->transform_negotiate->ciphersuite_info->key_exchange != + MBEDTLS_KEY_EXCHANGE_ECJPAKE ) + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip ecjpake kkpp extension" ) ); + return( 0 ); + } + + /* If we got here, we no longer need our cached extension */ + mbedtls_free( ssl->handshake->ecjpake_cache ); + ssl->handshake->ecjpake_cache = NULL; + ssl->handshake->ecjpake_cache_len = 0; + + if( ( ret = mbedtls_ecjpake_read_round_one( &ssl->handshake->ecjpake_ctx, + buf, len ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_one", ret ); + return( ret ); + } + + return( 0 ); +} +#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ + +#if defined(MBEDTLS_SSL_ALPN) +static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl, + const unsigned char *buf, size_t len ) +{ + size_t list_len, name_len; + const char **p; + + /* If we didn't send it, the server shouldn't send it */ + if( ssl->conf->alpn_list == NULL ) + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); + + /* + * opaque ProtocolName<1..2^8-1>; + * + * struct { + * ProtocolName protocol_name_list<2..2^16-1> + * } ProtocolNameList; + * + * the "ProtocolNameList" MUST contain exactly one "ProtocolName" + */ + + /* Min length is 2 (list_len) + 1 (name_len) + 1 (name) */ + if( len < 4 ) + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); + + list_len = ( buf[0] << 8 ) | buf[1]; + if( list_len != len - 2 ) + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); + + name_len = buf[2]; + if( name_len != list_len - 1 ) + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); + + /* Check that the server chosen protocol was in our list and save it */ + for( p = ssl->conf->alpn_list; *p != NULL; p++ ) + { + if( name_len == strlen( *p ) && + memcmp( buf + 3, *p, name_len ) == 0 ) + { + ssl->alpn_chosen = *p; + return( 0 ); + } + } + + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); +} +#endif /* MBEDTLS_SSL_ALPN */ + +/* + * Parse HelloVerifyRequest. Only called after verifying the HS type. + */ +#if defined(MBEDTLS_SSL_PROTO_DTLS) +static int ssl_parse_hello_verify_request( mbedtls_ssl_context *ssl ) +{ + const unsigned char *p = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ); + int major_ver, minor_ver; + unsigned char cookie_len; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse hello verify request" ) ); + + /* + * struct { + * ProtocolVersion server_version; + * opaque cookie<0..2^8-1>; + * } HelloVerifyRequest; + */ + MBEDTLS_SSL_DEBUG_BUF( 3, "server version", p, 2 ); + mbedtls_ssl_read_version( &major_ver, &minor_ver, ssl->conf->transport, p ); + p += 2; + + /* + * Since the RFC is not clear on this point, accept DTLS 1.0 (TLS 1.1) + * even is lower than our min version. + */ + if( major_ver < MBEDTLS_SSL_MAJOR_VERSION_3 || + minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 || + major_ver > ssl->conf->max_major_ver || + minor_ver > ssl->conf->max_minor_ver ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server version" ) ); + + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION ); + + return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION ); + } + + cookie_len = *p++; + MBEDTLS_SSL_DEBUG_BUF( 3, "cookie", p, cookie_len ); + + if( ( ssl->in_msg + ssl->in_msglen ) - p < cookie_len ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, + ( "cookie length does not match incoming message size" ) ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR ); + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); + } + + mbedtls_free( ssl->handshake->verify_cookie ); + + ssl->handshake->verify_cookie = mbedtls_calloc( 1, cookie_len ); + if( ssl->handshake->verify_cookie == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc failed (%d bytes)", cookie_len ) ); + return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); + } + + memcpy( ssl->handshake->verify_cookie, p, cookie_len ); + ssl->handshake->verify_cookie_len = cookie_len; + + /* Start over at ClientHello */ + ssl->state = MBEDTLS_SSL_CLIENT_HELLO; + mbedtls_ssl_reset_checksum( ssl ); + + mbedtls_ssl_recv_flight_completed( ssl ); + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse hello verify request" ) ); + + return( 0 ); +} +#endif /* MBEDTLS_SSL_PROTO_DTLS */ + +static int ssl_parse_server_hello( mbedtls_ssl_context *ssl ) +{ + int ret, i; + size_t n; + size_t ext_len; + unsigned char *buf, *ext; + unsigned char comp; +#if defined(MBEDTLS_ZLIB_SUPPORT) + int accept_comp; +#endif +#if defined(MBEDTLS_SSL_RENEGOTIATION) + int renegotiation_info_seen = 0; +#endif + int handshake_failure = 0; + const mbedtls_ssl_ciphersuite_t *suite_info; +#if defined(MBEDTLS_DEBUG_C) + uint32_t t; +#endif + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server hello" ) ); + + buf = ssl->in_msg; + + if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); + return( ret ); + } + + if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) + { +#if defined(MBEDTLS_SSL_RENEGOTIATION) + if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS ) + { + ssl->renego_records_seen++; + + if( ssl->conf->renego_max_records >= 0 && + ssl->renego_records_seen > ssl->conf->renego_max_records ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation requested, " + "but not honored by server" ) ); + return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); + } + + MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-handshake message during renego" ) ); + return( MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO ); + } +#endif /* MBEDTLS_SSL_RENEGOTIATION */ + + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); + return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); + } + +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + { + if( buf[0] == MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "received hello verify request" ) ); + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server hello" ) ); + return( ssl_parse_hello_verify_request( ssl ) ); + } + else + { + /* We made it through the verification process */ + mbedtls_free( ssl->handshake->verify_cookie ); + ssl->handshake->verify_cookie = NULL; + ssl->handshake->verify_cookie_len = 0; + } + } +#endif /* MBEDTLS_SSL_PROTO_DTLS */ + + if( ssl->in_hslen < 38 + mbedtls_ssl_hs_hdr_len( ssl ) || + buf[0] != MBEDTLS_SSL_HS_SERVER_HELLO ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); + } + + /* + * 0 . 1 server_version + * 2 . 33 random (maybe including 4 bytes of Unix time) + * 34 . 34 session_id length = n + * 35 . 34+n session_id + * 35+n . 36+n cipher_suite + * 37+n . 37+n compression_method + * + * 38+n . 39+n extensions length (optional) + * 40+n . .. extensions + */ + buf += mbedtls_ssl_hs_hdr_len( ssl ); + + MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, version", buf + 0, 2 ); + mbedtls_ssl_read_version( &ssl->major_ver, &ssl->minor_ver, + ssl->conf->transport, buf + 0 ); + + if( ssl->major_ver < ssl->conf->min_major_ver || + ssl->minor_ver < ssl->conf->min_minor_ver || + ssl->major_ver > ssl->conf->max_major_ver || + ssl->minor_ver > ssl->conf->max_minor_ver ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "server version out of bounds - " + " min: [%d:%d], server: [%d:%d], max: [%d:%d]", + ssl->conf->min_major_ver, ssl->conf->min_minor_ver, + ssl->major_ver, ssl->minor_ver, + ssl->conf->max_major_ver, ssl->conf->max_minor_ver ) ); + + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION ); + + return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION ); + } + +#if defined(MBEDTLS_DEBUG_C) + t = ( (uint32_t) buf[2] << 24 ) + | ( (uint32_t) buf[3] << 16 ) + | ( (uint32_t) buf[4] << 8 ) + | ( (uint32_t) buf[5] ); + MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, current time: %lu", t ) ); +#endif + + memcpy( ssl->handshake->randbytes + 32, buf + 2, 32 ); + + n = buf[34]; + + MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, random bytes", buf + 2, 32 ); + + if( n > 32 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); + } + + if( ssl->in_hslen > mbedtls_ssl_hs_hdr_len( ssl ) + 39 + n ) + { + ext_len = ( ( buf[38 + n] << 8 ) + | ( buf[39 + n] ) ); + + if( ( ext_len > 0 && ext_len < 4 ) || + ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + 40 + n + ext_len ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); + } + } + else if( ssl->in_hslen == mbedtls_ssl_hs_hdr_len( ssl ) + 38 + n ) + { + ext_len = 0; + } + else + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); + } + + /* ciphersuite (used later) */ + i = ( buf[35 + n] << 8 ) | buf[36 + n]; + + /* + * Read and check compression + */ + comp = buf[37 + n]; + +#if defined(MBEDTLS_ZLIB_SUPPORT) + /* See comments in ssl_write_client_hello() */ +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + accept_comp = 0; + else +#endif + accept_comp = 1; + + if( comp != MBEDTLS_SSL_COMPRESS_NULL && + ( comp != MBEDTLS_SSL_COMPRESS_DEFLATE || accept_comp == 0 ) ) +#else /* MBEDTLS_ZLIB_SUPPORT */ + if( comp != MBEDTLS_SSL_COMPRESS_NULL ) +#endif/* MBEDTLS_ZLIB_SUPPORT */ + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "server hello, bad compression: %d", comp ) ); + return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); + } + + /* + * Initialize update checksum functions + */ + ssl->transform_negotiate->ciphersuite_info = mbedtls_ssl_ciphersuite_from_id( i ); + + if( ssl->transform_negotiate->ciphersuite_info == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "ciphersuite info for %04x not found", i ) ); + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + } + + mbedtls_ssl_optimize_checksum( ssl, ssl->transform_negotiate->ciphersuite_info ); + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, session id len.: %d", n ) ); + MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, session id", buf + 35, n ); + + /* + * Check if the session can be resumed + */ + if( ssl->handshake->resume == 0 || n == 0 || +#if defined(MBEDTLS_SSL_RENEGOTIATION) + ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE || +#endif + ssl->session_negotiate->ciphersuite != i || + ssl->session_negotiate->compression != comp || + ssl->session_negotiate->id_len != n || + memcmp( ssl->session_negotiate->id, buf + 35, n ) != 0 ) + { + ssl->state++; + ssl->handshake->resume = 0; +#if defined(MBEDTLS_HAVE_TIME) + ssl->session_negotiate->start = mbedtls_time( NULL ); +#endif + ssl->session_negotiate->ciphersuite = i; + ssl->session_negotiate->compression = comp; + ssl->session_negotiate->id_len = n; + memcpy( ssl->session_negotiate->id, buf + 35, n ); + } + else + { + ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC; + + if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret ); + return( ret ); + } + } + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "%s session has been resumed", + ssl->handshake->resume ? "a" : "no" ) ); + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %04x", i ) ); + MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: %d", buf[37 + n] ) ); + + suite_info = mbedtls_ssl_ciphersuite_from_id( ssl->session_negotiate->ciphersuite ); + if( suite_info == NULL +#if defined(MBEDTLS_ARC4_C) + || ( ssl->conf->arc4_disabled && + suite_info->cipher == MBEDTLS_CIPHER_ARC4_128 ) +#endif + ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); + } + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %s", suite_info->name ) ); + + i = 0; + while( 1 ) + { + if( ssl->conf->ciphersuite_list[ssl->minor_ver][i] == 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); + } + + if( ssl->conf->ciphersuite_list[ssl->minor_ver][i++] == + ssl->session_negotiate->ciphersuite ) + { + break; + } + } + + if( comp != MBEDTLS_SSL_COMPRESS_NULL +#if defined(MBEDTLS_ZLIB_SUPPORT) + && comp != MBEDTLS_SSL_COMPRESS_DEFLATE +#endif + ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); + } + ssl->session_negotiate->compression = comp; + + ext = buf + 40 + n; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "server hello, total extension length: %d", ext_len ) ); + + while( ext_len ) + { + unsigned int ext_id = ( ( ext[0] << 8 ) + | ( ext[1] ) ); + unsigned int ext_size = ( ( ext[2] << 8 ) + | ( ext[3] ) ); + + if( ext_size + 4 > ext_len ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); + } + + switch( ext_id ) + { + case MBEDTLS_TLS_EXT_RENEGOTIATION_INFO: + MBEDTLS_SSL_DEBUG_MSG( 3, ( "found renegotiation extension" ) ); +#if defined(MBEDTLS_SSL_RENEGOTIATION) + renegotiation_info_seen = 1; +#endif + + if( ( ret = ssl_parse_renegotiation_info( ssl, ext + 4, + ext_size ) ) != 0 ) + return( ret ); + + break; + +#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) + case MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH: + MBEDTLS_SSL_DEBUG_MSG( 3, ( "found max_fragment_length extension" ) ); + + if( ( ret = ssl_parse_max_fragment_length_ext( ssl, + ext + 4, ext_size ) ) != 0 ) + { + return( ret ); + } + + break; +#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ + +#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) + case MBEDTLS_TLS_EXT_TRUNCATED_HMAC: + MBEDTLS_SSL_DEBUG_MSG( 3, ( "found truncated_hmac extension" ) ); + + if( ( ret = ssl_parse_truncated_hmac_ext( ssl, + ext + 4, ext_size ) ) != 0 ) + { + return( ret ); + } + + break; +#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ + +#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) + case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC: + MBEDTLS_SSL_DEBUG_MSG( 3, ( "found encrypt_then_mac extension" ) ); + + if( ( ret = ssl_parse_encrypt_then_mac_ext( ssl, + ext + 4, ext_size ) ) != 0 ) + { + return( ret ); + } + + break; +#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ + +#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) + case MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET: + MBEDTLS_SSL_DEBUG_MSG( 3, ( "found extended_master_secret extension" ) ); + + if( ( ret = ssl_parse_extended_ms_ext( ssl, + ext + 4, ext_size ) ) != 0 ) + { + return( ret ); + } + + break; +#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ + +#if defined(MBEDTLS_SSL_SESSION_TICKETS) + case MBEDTLS_TLS_EXT_SESSION_TICKET: + MBEDTLS_SSL_DEBUG_MSG( 3, ( "found session_ticket extension" ) ); + + if( ( ret = ssl_parse_session_ticket_ext( ssl, + ext + 4, ext_size ) ) != 0 ) + { + return( ret ); + } + + break; +#endif /* MBEDTLS_SSL_SESSION_TICKETS */ + +#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) + case MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS: + MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported_point_formats extension" ) ); + + if( ( ret = ssl_parse_supported_point_formats_ext( ssl, + ext + 4, ext_size ) ) != 0 ) + { + return( ret ); + } + + break; +#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || + MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) + case MBEDTLS_TLS_EXT_ECJPAKE_KKPP: + MBEDTLS_SSL_DEBUG_MSG( 3, ( "found ecjpake_kkpp extension" ) ); + + if( ( ret = ssl_parse_ecjpake_kkpp( ssl, + ext + 4, ext_size ) ) != 0 ) + { + return( ret ); + } + + break; +#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ + +#if defined(MBEDTLS_SSL_ALPN) + case MBEDTLS_TLS_EXT_ALPN: + MBEDTLS_SSL_DEBUG_MSG( 3, ( "found alpn extension" ) ); + + if( ( ret = ssl_parse_alpn_ext( ssl, ext + 4, ext_size ) ) != 0 ) + return( ret ); + + break; +#endif /* MBEDTLS_SSL_ALPN */ + + default: + MBEDTLS_SSL_DEBUG_MSG( 3, ( "unknown extension found: %d (ignoring)", + ext_id ) ); + } + + ext_len -= 4 + ext_size; + ext += 4 + ext_size; + + if( ext_len > 0 && ext_len < 4 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); + } + } + + /* + * Renegotiation security checks + */ + if( ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && + ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) ); + handshake_failure = 1; + } +#if defined(MBEDTLS_SSL_RENEGOTIATION) + else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && + ssl->secure_renegotiation == MBEDTLS_SSL_SECURE_RENEGOTIATION && + renegotiation_info_seen == 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation_info extension missing (secure)" ) ); + handshake_failure = 1; + } + else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && + ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && + ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation not allowed" ) ); + handshake_failure = 1; + } + else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && + ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && + renegotiation_info_seen == 1 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation_info extension present (legacy)" ) ); + handshake_failure = 1; + } +#endif /* MBEDTLS_SSL_RENEGOTIATION */ + + if( handshake_failure == 1 ) + { + if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 ) + return( ret ); + + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); + } + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server hello" ) ); + + return( 0 ); +} + +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) +static int ssl_parse_server_dh_params( mbedtls_ssl_context *ssl, unsigned char **p, + unsigned char *end ) +{ + int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; + + /* + * Ephemeral DH parameters: + * + * struct { + * opaque dh_p<1..2^16-1>; + * opaque dh_g<1..2^16-1>; + * opaque dh_Ys<1..2^16-1>; + * } ServerDHParams; + */ + if( ( ret = mbedtls_dhm_read_params( &ssl->handshake->dhm_ctx, p, end ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 2, ( "mbedtls_dhm_read_params" ), ret ); + return( ret ); + } + + if( ssl->handshake->dhm_ctx.len * 8 < ssl->conf->dhm_min_bitlen ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "DHM prime too short: %d < %d", + ssl->handshake->dhm_ctx.len * 8, + ssl->conf->dhm_min_bitlen ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); + } + + MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: P ", &ssl->handshake->dhm_ctx.P ); + MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: G ", &ssl->handshake->dhm_ctx.G ); + MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: GY", &ssl->handshake->dhm_ctx.GY ); + + return( ret ); +} +#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED || + MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) +static int ssl_check_server_ecdh_params( const mbedtls_ssl_context *ssl ) +{ + const mbedtls_ecp_curve_info *curve_info; + + curve_info = mbedtls_ecp_curve_info_from_grp_id( ssl->handshake->ecdh_ctx.grp.id ); + if( curve_info == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "ECDH curve: %s", curve_info->name ) ); + +#if defined(MBEDTLS_ECP_C) + if( mbedtls_ssl_check_curve( ssl, ssl->handshake->ecdh_ctx.grp.id ) != 0 ) +#else + if( ssl->handshake->ecdh_ctx.grp.nbits < 163 || + ssl->handshake->ecdh_ctx.grp.nbits > 521 ) +#endif + return( -1 ); + + MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Qp", &ssl->handshake->ecdh_ctx.Qp ); + + return( 0 ); +} +#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || + MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED || + MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED || + MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED || + MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) +static int ssl_parse_server_ecdh_params( mbedtls_ssl_context *ssl, + unsigned char **p, + unsigned char *end ) +{ + int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; + + /* + * Ephemeral ECDH parameters: + * + * struct { + * ECParameters curve_params; + * ECPoint public; + * } ServerECDHParams; + */ + if( ( ret = mbedtls_ecdh_read_params( &ssl->handshake->ecdh_ctx, + (const unsigned char **) p, end ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ecdh_read_params" ), ret ); + return( ret ); + } + + if( ssl_check_server_ecdh_params( ssl ) != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message (ECDHE curve)" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); + } + + return( ret ); +} +#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || + MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED || + MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) +static int ssl_parse_server_psk_hint( mbedtls_ssl_context *ssl, + unsigned char **p, + unsigned char *end ) +{ + int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; + size_t len; + ((void) ssl); + + /* + * PSK parameters: + * + * opaque psk_identity_hint<0..2^16-1>; + */ + len = (*p)[0] << 8 | (*p)[1]; + *p += 2; + + if( (*p) + len > end ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message (psk_identity_hint length)" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); + } + + /* + * Note: we currently ignore the PKS identity hint, as we only allow one + * PSK to be provisionned on the client. This could be changed later if + * someone needs that feature. + */ + *p += len; + ret = 0; + + return( ret ); +} +#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) +/* + * Generate a pre-master secret and encrypt it with the server's RSA key + */ +static int ssl_write_encrypted_pms( mbedtls_ssl_context *ssl, + size_t offset, size_t *olen, + size_t pms_offset ) +{ + int ret; + size_t len_bytes = ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ? 0 : 2; + unsigned char *p = ssl->handshake->premaster + pms_offset; + + if( offset + len_bytes > MBEDTLS_SSL_MAX_CONTENT_LEN ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small for encrypted pms" ) ); + return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); + } + + /* + * Generate (part of) the pre-master as + * struct { + * ProtocolVersion client_version; + * opaque random[46]; + * } PreMasterSecret; + */ + mbedtls_ssl_write_version( ssl->conf->max_major_ver, ssl->conf->max_minor_ver, + ssl->conf->transport, p ); + + if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p + 2, 46 ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "f_rng", ret ); + return( ret ); + } + + ssl->handshake->pmslen = 48; + + if( ssl->session_negotiate->peer_cert == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "certificate required" ) ); + return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); + } + + /* + * Now write it out, encrypted + */ + if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk, + MBEDTLS_PK_RSA ) ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "certificate key type mismatch" ) ); + return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH ); + } + + if( ( ret = mbedtls_pk_encrypt( &ssl->session_negotiate->peer_cert->pk, + p, ssl->handshake->pmslen, + ssl->out_msg + offset + len_bytes, olen, + MBEDTLS_SSL_MAX_CONTENT_LEN - offset - len_bytes, + ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_rsa_pkcs1_encrypt", ret ); + return( ret ); + } + +#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ + defined(MBEDTLS_SSL_PROTO_TLS1_2) + if( len_bytes == 2 ) + { + ssl->out_msg[offset+0] = (unsigned char)( *olen >> 8 ); + ssl->out_msg[offset+1] = (unsigned char)( *olen ); + *olen += 2; + } +#endif + + return( 0 ); +} +#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED || + MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ + +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) +static int ssl_parse_signature_algorithm( mbedtls_ssl_context *ssl, + unsigned char **p, + unsigned char *end, + mbedtls_md_type_t *md_alg, + mbedtls_pk_type_t *pk_alg ) +{ + ((void) ssl); + *md_alg = MBEDTLS_MD_NONE; + *pk_alg = MBEDTLS_PK_NONE; + + /* Only in TLS 1.2 */ + if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 ) + { + return( 0 ); + } + + if( (*p) + 2 > end ) + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); + + /* + * Get hash algorithm + */ + if( ( *md_alg = mbedtls_ssl_md_alg_from_hash( (*p)[0] ) ) == MBEDTLS_MD_NONE ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "Server used unsupported " + "HashAlgorithm %d", *(p)[0] ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); + } + + /* + * Get signature algorithm + */ + if( ( *pk_alg = mbedtls_ssl_pk_alg_from_sig( (*p)[1] ) ) == MBEDTLS_PK_NONE ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "server used unsupported " + "SignatureAlgorithm %d", (*p)[1] ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); + } + + /* + * Check if the hash is acceptable + */ + if( mbedtls_ssl_check_sig_hash( ssl, *md_alg ) != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "server used HashAlgorithm " + "that was not offered" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); + } + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "Server used SignatureAlgorithm %d", (*p)[1] ) ); + MBEDTLS_SSL_DEBUG_MSG( 2, ( "Server used HashAlgorithm %d", (*p)[0] ) ); + *p += 2; + + return( 0 ); +} +#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED || + MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || + MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ + +#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) +static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl ) +{ + int ret; + const mbedtls_ecp_keypair *peer_key; + + if( ssl->session_negotiate->peer_cert == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "certificate required" ) ); + return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); + } + + if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk, + MBEDTLS_PK_ECKEY ) ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "server key not ECDH capable" ) ); + return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH ); + } + + peer_key = mbedtls_pk_ec( ssl->session_negotiate->peer_cert->pk ); + + if( ( ret = mbedtls_ecdh_get_params( &ssl->handshake->ecdh_ctx, peer_key, + MBEDTLS_ECDH_THEIRS ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ecdh_get_params" ), ret ); + return( ret ); + } + + if( ssl_check_server_ecdh_params( ssl ) != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server certificate (ECDH curve)" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ); + } + + return( ret ); +} +#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || + MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ + +static int ssl_parse_server_key_exchange( mbedtls_ssl_context *ssl ) +{ + int ret; + const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; + unsigned char *p, *end; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server key exchange" ) ); + +#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) ); + ssl->state++; + return( 0 ); + } + ((void) p); + ((void) end); +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA ) + { + if( ( ret = ssl_get_ecdh_params_from_cert( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "ssl_get_ecdh_params_from_cert", ret ); + return( ret ); + } + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse server key exchange" ) ); + ssl->state++; + return( 0 ); + } + ((void) p); + ((void) end); +#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED || + MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ + + if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); + return( ret ); + } + + if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); + return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); + } + + /* + * ServerKeyExchange may be skipped with PSK and RSA-PSK when the server + * doesn't use a psk_identity_hint + */ + if( ssl->in_msg[0] != MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE ) + { + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ) + { + ssl->record_read = 1; + goto exit; + } + + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); + return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); + } + + p = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ); + end = ssl->in_msg + ssl->in_hslen; + MBEDTLS_SSL_DEBUG_BUF( 3, "server key exchange", p, end - p ); + +#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ) + { + if( ssl_parse_server_psk_hint( ssl, &p, end ) != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); + } + } /* FALLTROUGH */ +#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ) + ; /* nothing more to do */ + else +#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED || + MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ) + { + if( ssl_parse_server_dh_params( ssl, &p, end ) != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); + } + } + else +#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED || + MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ) + { + if( ssl_parse_server_ecdh_params( ssl, &p, end ) != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); + } + } + else +#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || + MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED || + MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ +#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) + { + ret = mbedtls_ecjpake_read_round_two( &ssl->handshake->ecjpake_ctx, + p, end - p ); + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_two", ret ); + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); + } + } + else +#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ) + { + size_t sig_len, hashlen; + unsigned char hash[64]; + mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE; + mbedtls_pk_type_t pk_alg = MBEDTLS_PK_NONE; + unsigned char *params = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ); + size_t params_len = p - params; + + /* + * Handle the digitally-signed structure + */ +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) + if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) + { + if( ssl_parse_signature_algorithm( ssl, &p, end, + &md_alg, &pk_alg ) != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); + } + + if( pk_alg != mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info ) ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); + } + } + else +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ +#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ + defined(MBEDTLS_SSL_PROTO_TLS1_1) + if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 ) + { + pk_alg = mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info ); + + /* Default hash for ECDSA is SHA-1 */ + if( pk_alg == MBEDTLS_PK_ECDSA && md_alg == MBEDTLS_MD_NONE ) + md_alg = MBEDTLS_MD_SHA1; + } + else +#endif + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + + /* + * Read signature + */ + sig_len = ( p[0] << 8 ) | p[1]; + p += 2; + + if( end != p + sig_len ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); + } + + MBEDTLS_SSL_DEBUG_BUF( 3, "signature", p, sig_len ); + + /* + * Compute the hash that has been signed + */ +#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ + defined(MBEDTLS_SSL_PROTO_TLS1_1) + if( md_alg == MBEDTLS_MD_NONE ) + { + mbedtls_md5_context mbedtls_md5; + mbedtls_sha1_context mbedtls_sha1; + + mbedtls_md5_init( &mbedtls_md5 ); + mbedtls_sha1_init( &mbedtls_sha1 ); + + hashlen = 36; + + /* + * digitally-signed struct { + * opaque md5_hash[16]; + * opaque sha_hash[20]; + * }; + * + * md5_hash + * MD5(ClientHello.random + ServerHello.random + * + ServerParams); + * sha_hash + * SHA(ClientHello.random + ServerHello.random + * + ServerParams); + */ + mbedtls_md5_starts( &mbedtls_md5 ); + mbedtls_md5_update( &mbedtls_md5, ssl->handshake->randbytes, 64 ); + mbedtls_md5_update( &mbedtls_md5, params, params_len ); + mbedtls_md5_finish( &mbedtls_md5, hash ); + + mbedtls_sha1_starts( &mbedtls_sha1 ); + mbedtls_sha1_update( &mbedtls_sha1, ssl->handshake->randbytes, 64 ); + mbedtls_sha1_update( &mbedtls_sha1, params, params_len ); + mbedtls_sha1_finish( &mbedtls_sha1, hash + 16 ); + + mbedtls_md5_free( &mbedtls_md5 ); + mbedtls_sha1_free( &mbedtls_sha1 ); + } + else +#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \ + MBEDTLS_SSL_PROTO_TLS1_1 */ +#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ + defined(MBEDTLS_SSL_PROTO_TLS1_2) + if( md_alg != MBEDTLS_MD_NONE ) + { + mbedtls_md_context_t ctx; + + mbedtls_md_init( &ctx ); + + /* Info from md_alg will be used instead */ + hashlen = 0; + + /* + * digitally-signed struct { + * opaque client_random[32]; + * opaque server_random[32]; + * ServerDHParams params; + * }; + */ + if( ( ret = mbedtls_md_setup( &ctx, + mbedtls_md_info_from_type( md_alg ), 0 ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_setup", ret ); + return( ret ); + } + + mbedtls_md_starts( &ctx ); + mbedtls_md_update( &ctx, ssl->handshake->randbytes, 64 ); + mbedtls_md_update( &ctx, params, params_len ); + mbedtls_md_finish( &ctx, hash ); + mbedtls_md_free( &ctx ); + } + else +#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \ + MBEDTLS_SSL_PROTO_TLS1_2 */ + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + + MBEDTLS_SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen != 0 ? hashlen : + (unsigned int) ( mbedtls_md_get_size( mbedtls_md_info_from_type( md_alg ) ) ) ); + + if( ssl->session_negotiate->peer_cert == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "certificate required" ) ); + return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); + } + + /* + * Verify signature + */ + if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk, pk_alg ) ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server key exchange message" ) ); + return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH ); + } + + if( ( ret = mbedtls_pk_verify( &ssl->session_negotiate->peer_cert->pk, + md_alg, hash, hashlen, p, sig_len ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_verify", ret ); + return( ret ); + } + } +#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED || + MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || + MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ + +exit: + ssl->state++; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server key exchange" ) ); + + return( 0 ); +} + +#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)&& \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) +static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl ) +{ + const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) ); + + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) ); + ssl->state++; + return( 0 ); + } + + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); +} +#else +static int ssl_parse_certificate_request( mbedtls_ssl_context *ssl ) +{ + int ret; + unsigned char *buf; + size_t n = 0; + size_t cert_type_len = 0, dn_len = 0; + const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate request" ) ); + + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate request" ) ); + ssl->state++; + return( 0 ); + } + + if( ssl->record_read == 0 ) + { + if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); + return( ret ); + } + + if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) ); + return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); + } + + ssl->record_read = 1; + } + + ssl->client_auth = 0; + ssl->state++; + + if( ssl->in_msg[0] == MBEDTLS_SSL_HS_CERTIFICATE_REQUEST ) + ssl->client_auth++; + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "got %s certificate request", + ssl->client_auth ? "a" : "no" ) ); + + if( ssl->client_auth == 0 ) + goto exit; + + ssl->record_read = 0; + + /* + * struct { + * ClientCertificateType certificate_types<1..2^8-1>; + * SignatureAndHashAlgorithm + * supported_signature_algorithms<2^16-1>; -- TLS 1.2 only + * DistinguishedName certificate_authorities<0..2^16-1>; + * } CertificateRequest; + * + * Since we only support a single certificate on clients, let's just + * ignore all the information that's supposed to help us pick a + * certificate. + * + * We could check that our certificate matches the request, and bail out + * if it doesn't, but it's simpler to just send the certificate anyway, + * and give the server the opportunity to decide if it should terminate + * the connection when it doesn't like our certificate. + * + * Same goes for the hash in TLS 1.2's signature_algorithms: at this + * point we only have one hash available (see comments in + * write_certificate_verify), so let's just use what we have. + * + * However, we still minimally parse the message to check it is at least + * superficially sane. + */ + buf = ssl->in_msg; + + /* certificate_types */ + cert_type_len = buf[mbedtls_ssl_hs_hdr_len( ssl )]; + n = cert_type_len; + + if( ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST ); + } + + /* supported_signature_algorithms */ +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) + if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) + { + size_t sig_alg_len = ( ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 1 + n] << 8 ) + | ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n] ) ); +#if defined(MBEDTLS_DEBUG_C) + unsigned char* sig_alg = buf + mbedtls_ssl_hs_hdr_len( ssl ) + 3 + n; + size_t i; + + for( i = 0; i < sig_alg_len; i += 2 ) + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "Supported Signature Algorithm found: %d,%d", sig_alg[i], sig_alg[i + 1] ) ); + } +#endif + + n += 2 + sig_alg_len; + + if( ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST ); + } + } +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ + + /* certificate_authorities */ + dn_len = ( ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 1 + n] << 8 ) + | ( buf[mbedtls_ssl_hs_hdr_len( ssl ) + 2 + n] ) ); + + n += dn_len; + if( ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + 3 + n ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate request message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST ); + } + +exit: + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate request" ) ); + + return( 0 ); +} +#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ + +static int ssl_parse_server_hello_done( mbedtls_ssl_context *ssl ) +{ + int ret; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse server hello done" ) ); + + if( ssl->record_read == 0 ) + { + if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); + return( ret ); + } + + if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) ); + return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); + } + } + ssl->record_read = 0; + + if( ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) || + ssl->in_msg[0] != MBEDTLS_SSL_HS_SERVER_HELLO_DONE ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad server hello done message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE ); + } + + ssl->state++; + +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + mbedtls_ssl_recv_flight_completed( ssl ); +#endif + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse server hello done" ) ); + + return( 0 ); +} + +static int ssl_write_client_key_exchange( mbedtls_ssl_context *ssl ) +{ + int ret; + size_t i, n; + const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write client key exchange" ) ); + +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA ) + { + /* + * DHM key exchange -- send G^X mod P + */ + n = ssl->handshake->dhm_ctx.len; + + ssl->out_msg[4] = (unsigned char)( n >> 8 ); + ssl->out_msg[5] = (unsigned char)( n ); + i = 6; + + ret = mbedtls_dhm_make_public( &ssl->handshake->dhm_ctx, + (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ), + &ssl->out_msg[i], n, + ssl->conf->f_rng, ssl->conf->p_rng ); + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_make_public", ret ); + return( ret ); + } + + MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: X ", &ssl->handshake->dhm_ctx.X ); + MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: GX", &ssl->handshake->dhm_ctx.GX ); + + if( ( ret = mbedtls_dhm_calc_secret( &ssl->handshake->dhm_ctx, + ssl->handshake->premaster, + MBEDTLS_PREMASTER_SIZE, + &ssl->handshake->pmslen, + ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret ); + return( ret ); + } + + MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K ); + } + else +#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */ +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA ) + { + /* + * ECDH key exchange -- send client public value + */ + i = 4; + + ret = mbedtls_ecdh_make_public( &ssl->handshake->ecdh_ctx, + &n, + &ssl->out_msg[i], 1000, + ssl->conf->f_rng, ssl->conf->p_rng ); + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_public", ret ); + return( ret ); + } + + MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Q", &ssl->handshake->ecdh_ctx.Q ); + + if( ( ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx, + &ssl->handshake->pmslen, + ssl->handshake->premaster, + MBEDTLS_MPI_MAX_SIZE, + ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret ); + return( ret ); + } + + MBEDTLS_SSL_DEBUG_MPI( 3, "ECDH: z", &ssl->handshake->ecdh_ctx.z ); + } + else +#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || + MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED || + MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED || + MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ +#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ) + { + /* + * opaque psk_identity<0..2^16-1>; + */ + if( ssl->conf->psk == NULL || ssl->conf->psk_identity == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no private key for PSK" ) ); + return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED ); + } + + i = 4; + n = ssl->conf->psk_identity_len; + + if( i + 2 + n > MBEDTLS_SSL_MAX_CONTENT_LEN ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "psk identity too long or " + "SSL buffer too short" ) ); + return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); + } + + ssl->out_msg[i++] = (unsigned char)( n >> 8 ); + ssl->out_msg[i++] = (unsigned char)( n ); + + memcpy( ssl->out_msg + i, ssl->conf->psk_identity, ssl->conf->psk_identity_len ); + i += ssl->conf->psk_identity_len; + +#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ) + { + n = 0; + } + else +#endif +#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ) + { + if( ( ret = ssl_write_encrypted_pms( ssl, i, &n, 2 ) ) != 0 ) + return( ret ); + } + else +#endif +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ) + { + /* + * ClientDiffieHellmanPublic public (DHM send G^X mod P) + */ + n = ssl->handshake->dhm_ctx.len; + + if( i + 2 + n > MBEDTLS_SSL_MAX_CONTENT_LEN ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "psk identity or DHM size too long" + " or SSL buffer too short" ) ); + return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); + } + + ssl->out_msg[i++] = (unsigned char)( n >> 8 ); + ssl->out_msg[i++] = (unsigned char)( n ); + + ret = mbedtls_dhm_make_public( &ssl->handshake->dhm_ctx, + (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ), + &ssl->out_msg[i], n, + ssl->conf->f_rng, ssl->conf->p_rng ); + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_make_public", ret ); + return( ret ); + } + } + else +#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ) + { + /* + * ClientECDiffieHellmanPublic public; + */ + ret = mbedtls_ecdh_make_public( &ssl->handshake->ecdh_ctx, &n, + &ssl->out_msg[i], MBEDTLS_SSL_MAX_CONTENT_LEN - i, + ssl->conf->f_rng, ssl->conf->p_rng ); + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_public", ret ); + return( ret ); + } + + MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Q", &ssl->handshake->ecdh_ctx.Q ); + } + else +#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + + if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl, + ciphersuite_info->key_exchange ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret ); + return( ret ); + } + } + else +#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ +#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA ) + { + i = 4; + if( ( ret = ssl_write_encrypted_pms( ssl, i, &n, 0 ) ) != 0 ) + return( ret ); + } + else +#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ +#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) + { + i = 4; + + ret = mbedtls_ecjpake_write_round_two( &ssl->handshake->ecjpake_ctx, + ssl->out_msg + i, MBEDTLS_SSL_MAX_CONTENT_LEN - i, &n, + ssl->conf->f_rng, ssl->conf->p_rng ); + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_write_round_two", ret ); + return( ret ); + } + + ret = mbedtls_ecjpake_derive_secret( &ssl->handshake->ecjpake_ctx, + ssl->handshake->premaster, 32, &ssl->handshake->pmslen, + ssl->conf->f_rng, ssl->conf->p_rng ); + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_derive_secret", ret ); + return( ret ); + } + } + else +#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ + { + ((void) ciphersuite_info); + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + + ssl->out_msglen = i + n; + ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; + ssl->out_msg[0] = MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE; + + ssl->state++; + + if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); + return( ret ); + } + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write client key exchange" ) ); + + return( 0 ); +} + +#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)&& \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) +static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl ) +{ + const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; + int ret; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) ); + + if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret ); + return( ret ); + } + + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) ); + ssl->state++; + return( 0 ); + } + + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); +} +#else +static int ssl_write_certificate_verify( mbedtls_ssl_context *ssl ) +{ + int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; + const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; + size_t n = 0, offset = 0; + unsigned char hash[48]; + unsigned char *hash_start = hash; + mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE; + unsigned int hashlen; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate verify" ) ); + + if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret ); + return( ret ); + } + + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) ); + ssl->state++; + return( 0 ); + } + + if( ssl->client_auth == 0 || mbedtls_ssl_own_cert( ssl ) == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate verify" ) ); + ssl->state++; + return( 0 ); + } + + if( mbedtls_ssl_own_key( ssl ) == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no private key for certificate" ) ); + return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED ); + } + + /* + * Make an RSA signature of the handshake digests + */ + ssl->handshake->calc_verify( ssl, hash ); + +#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ + defined(MBEDTLS_SSL_PROTO_TLS1_1) + if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 ) + { + /* + * digitally-signed struct { + * opaque md5_hash[16]; + * opaque sha_hash[20]; + * }; + * + * md5_hash + * MD5(handshake_messages); + * + * sha_hash + * SHA(handshake_messages); + */ + hashlen = 36; + md_alg = MBEDTLS_MD_NONE; + + /* + * For ECDSA, default hash is SHA-1 only + */ + if( mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_ECDSA ) ) + { + hash_start += 16; + hashlen -= 16; + md_alg = MBEDTLS_MD_SHA1; + } + } + else +#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \ + MBEDTLS_SSL_PROTO_TLS1_1 */ +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) + if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) + { + /* + * digitally-signed struct { + * opaque handshake_messages[handshake_messages_length]; + * }; + * + * Taking shortcut here. We assume that the server always allows the + * PRF Hash function and has sent it in the allowed signature + * algorithms list received in the Certificate Request message. + * + * Until we encounter a server that does not, we will take this + * shortcut. + * + * Reason: Otherwise we should have running hashes for SHA512 and SHA224 + * in order to satisfy 'weird' needs from the server side. + */ + if( ssl->transform_negotiate->ciphersuite_info->mac == + MBEDTLS_MD_SHA384 ) + { + md_alg = MBEDTLS_MD_SHA384; + ssl->out_msg[4] = MBEDTLS_SSL_HASH_SHA384; + } + else + { + md_alg = MBEDTLS_MD_SHA256; + ssl->out_msg[4] = MBEDTLS_SSL_HASH_SHA256; + } + ssl->out_msg[5] = mbedtls_ssl_sig_from_pk( mbedtls_ssl_own_key( ssl ) ); + + /* Info from md_alg will be used instead */ + hashlen = 0; + offset = 2; + } + else +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + + if( ( ret = mbedtls_pk_sign( mbedtls_ssl_own_key( ssl ), md_alg, hash_start, hashlen, + ssl->out_msg + 6 + offset, &n, + ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_sign", ret ); + return( ret ); + } + + ssl->out_msg[4 + offset] = (unsigned char)( n >> 8 ); + ssl->out_msg[5 + offset] = (unsigned char)( n ); + + ssl->out_msglen = 6 + n + offset; + ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; + ssl->out_msg[0] = MBEDTLS_SSL_HS_CERTIFICATE_VERIFY; + + ssl->state++; + + if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); + return( ret ); + } + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write certificate verify" ) ); + + return( ret ); +} +#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ + +#if defined(MBEDTLS_SSL_SESSION_TICKETS) +static int ssl_parse_new_session_ticket( mbedtls_ssl_context *ssl ) +{ + int ret; + uint32_t lifetime; + size_t ticket_len; + unsigned char *ticket; + const unsigned char *msg; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse new session ticket" ) ); + + if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); + return( ret ); + } + + if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) ); + return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); + } + + /* + * struct { + * uint32 ticket_lifetime_hint; + * opaque ticket<0..2^16-1>; + * } NewSessionTicket; + * + * 0 . 3 ticket_lifetime_hint + * 4 . 5 ticket_len (n) + * 6 . 5+n ticket content + */ + if( ssl->in_msg[0] != MBEDTLS_SSL_HS_NEW_SESSION_TICKET || + ssl->in_hslen < 6 + mbedtls_ssl_hs_hdr_len( ssl ) ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET ); + } + + msg = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ); + + lifetime = ( msg[0] << 24 ) | ( msg[1] << 16 ) | + ( msg[2] << 8 ) | ( msg[3] ); + + ticket_len = ( msg[4] << 8 ) | ( msg[5] ); + + if( ticket_len + 6 + mbedtls_ssl_hs_hdr_len( ssl ) != ssl->in_hslen ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad new session ticket message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET ); + } + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket length: %d", ticket_len ) ); + + /* We're not waiting for a NewSessionTicket message any more */ + ssl->handshake->new_session_ticket = 0; + ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC; + + /* + * Zero-length ticket means the server changed his mind and doesn't want + * to send a ticket after all, so just forget it + */ + if( ticket_len == 0 ) + return( 0 ); + + mbedtls_zeroize( ssl->session_negotiate->ticket, + ssl->session_negotiate->ticket_len ); + mbedtls_free( ssl->session_negotiate->ticket ); + ssl->session_negotiate->ticket = NULL; + ssl->session_negotiate->ticket_len = 0; + + if( ( ticket = mbedtls_calloc( 1, ticket_len ) ) == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "ticket alloc failed" ) ); + return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); + } + + memcpy( ticket, msg + 6, ticket_len ); + + ssl->session_negotiate->ticket = ticket; + ssl->session_negotiate->ticket_len = ticket_len; + ssl->session_negotiate->ticket_lifetime = lifetime; + + /* + * RFC 5077 section 3.4: + * "If the client receives a session ticket from the server, then it + * discards any Session ID that was sent in the ServerHello." + */ + MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket in use, discarding session id" ) ); + ssl->session_negotiate->id_len = 0; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse new session ticket" ) ); + + return( 0 ); +} +#endif /* MBEDTLS_SSL_SESSION_TICKETS */ + +/* + * SSL handshake -- client side -- single step + */ +int mbedtls_ssl_handshake_client_step( mbedtls_ssl_context *ssl ) +{ + int ret = 0; + + if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER || ssl->handshake == NULL ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "client state: %d", ssl->state ) ); + + if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) + return( ret ); + +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && + ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING ) + { + if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 ) + return( ret ); + } +#endif + + /* Change state now, so that it is right in mbedtls_ssl_read_record(), used + * by DTLS for dropping out-of-sequence ChangeCipherSpec records */ +#if defined(MBEDTLS_SSL_SESSION_TICKETS) + if( ssl->state == MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC && + ssl->handshake->new_session_ticket != 0 ) + { + ssl->state = MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET; + } +#endif + + switch( ssl->state ) + { + case MBEDTLS_SSL_HELLO_REQUEST: + ssl->state = MBEDTLS_SSL_CLIENT_HELLO; + break; + + /* + * ==> ClientHello + */ + case MBEDTLS_SSL_CLIENT_HELLO: + ret = ssl_write_client_hello( ssl ); + break; + + /* + * <== ServerHello + * Certificate + * ( ServerKeyExchange ) + * ( CertificateRequest ) + * ServerHelloDone + */ + case MBEDTLS_SSL_SERVER_HELLO: + ret = ssl_parse_server_hello( ssl ); + break; + + case MBEDTLS_SSL_SERVER_CERTIFICATE: + ret = mbedtls_ssl_parse_certificate( ssl ); + break; + + case MBEDTLS_SSL_SERVER_KEY_EXCHANGE: + ret = ssl_parse_server_key_exchange( ssl ); + break; + + case MBEDTLS_SSL_CERTIFICATE_REQUEST: + ret = ssl_parse_certificate_request( ssl ); + break; + + case MBEDTLS_SSL_SERVER_HELLO_DONE: + ret = ssl_parse_server_hello_done( ssl ); + break; + + /* + * ==> ( Certificate/Alert ) + * ClientKeyExchange + * ( CertificateVerify ) + * ChangeCipherSpec + * Finished + */ + case MBEDTLS_SSL_CLIENT_CERTIFICATE: + ret = mbedtls_ssl_write_certificate( ssl ); + break; + + case MBEDTLS_SSL_CLIENT_KEY_EXCHANGE: + ret = ssl_write_client_key_exchange( ssl ); + break; + + case MBEDTLS_SSL_CERTIFICATE_VERIFY: + ret = ssl_write_certificate_verify( ssl ); + break; + + case MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC: + ret = mbedtls_ssl_write_change_cipher_spec( ssl ); + break; + + case MBEDTLS_SSL_CLIENT_FINISHED: + ret = mbedtls_ssl_write_finished( ssl ); + break; + + /* + * <== ( NewSessionTicket ) + * ChangeCipherSpec + * Finished + */ +#if defined(MBEDTLS_SSL_SESSION_TICKETS) + case MBEDTLS_SSL_SERVER_NEW_SESSION_TICKET: + ret = ssl_parse_new_session_ticket( ssl ); + break; +#endif + + case MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC: + ret = mbedtls_ssl_parse_change_cipher_spec( ssl ); + break; + + case MBEDTLS_SSL_SERVER_FINISHED: + ret = mbedtls_ssl_parse_finished( ssl ); + break; + + case MBEDTLS_SSL_FLUSH_BUFFERS: + MBEDTLS_SSL_DEBUG_MSG( 2, ( "handshake: done" ) ); + ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP; + break; + + case MBEDTLS_SSL_HANDSHAKE_WRAPUP: + mbedtls_ssl_handshake_wrapup( ssl ); + break; + + default: + MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid state %d", ssl->state ) ); + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + } + + return( ret ); +} +#endif /* MBEDTLS_SSL_CLI_C */ diff --git a/security/mbedtls/src/ssl_cookie.c b/security/mbedtls/src/ssl_cookie.c new file mode 100644 index 0000000000..caf119990d --- /dev/null +++ b/security/mbedtls/src/ssl_cookie.c @@ -0,0 +1,260 @@ +/* + * DTLS cookie callbacks implementation + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +/* + * These session callbacks use a simple chained list + * to store and retrieve the session information. + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_SSL_COOKIE_C) + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#define mbedtls_calloc calloc +#define mbedtls_free free +#endif + +#include "mbedtls/ssl_cookie.h" +#include "mbedtls/ssl_internal.h" + +#include + +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +/* + * If DTLS is in use, then at least one of SHA-1, SHA-256, SHA-512 is + * available. Try SHA-256 first, 512 wastes resources since we need to stay + * with max 32 bytes of cookie for DTLS 1.0 + */ +#if defined(MBEDTLS_SHA256_C) +#define COOKIE_MD MBEDTLS_MD_SHA224 +#define COOKIE_MD_OUTLEN 32 +#define COOKIE_HMAC_LEN 28 +#elif defined(MBEDTLS_SHA512_C) +#define COOKIE_MD MBEDTLS_MD_SHA384 +#define COOKIE_MD_OUTLEN 48 +#define COOKIE_HMAC_LEN 28 +#elif defined(MBEDTLS_SHA1_C) +#define COOKIE_MD MBEDTLS_MD_SHA1 +#define COOKIE_MD_OUTLEN 20 +#define COOKIE_HMAC_LEN 20 +#else +#error "DTLS hello verify needs SHA-1 or SHA-2" +#endif + +/* + * Cookies are formed of a 4-bytes timestamp (or serial number) and + * an HMAC of timestemp and client ID. + */ +#define COOKIE_LEN ( 4 + COOKIE_HMAC_LEN ) + +void mbedtls_ssl_cookie_init( mbedtls_ssl_cookie_ctx *ctx ) +{ + mbedtls_md_init( &ctx->hmac_ctx ); +#if !defined(MBEDTLS_HAVE_TIME) + ctx->serial = 0; +#endif + ctx->timeout = MBEDTLS_SSL_COOKIE_TIMEOUT; + +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_init( &ctx->mutex ); +#endif +} + +void mbedtls_ssl_cookie_set_timeout( mbedtls_ssl_cookie_ctx *ctx, unsigned long delay ) +{ + ctx->timeout = delay; +} + +void mbedtls_ssl_cookie_free( mbedtls_ssl_cookie_ctx *ctx ) +{ + mbedtls_md_free( &ctx->hmac_ctx ); + +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_free( &ctx->mutex ); +#endif + + mbedtls_zeroize( ctx, sizeof( mbedtls_ssl_cookie_ctx ) ); +} + +int mbedtls_ssl_cookie_setup( mbedtls_ssl_cookie_ctx *ctx, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + unsigned char key[COOKIE_MD_OUTLEN]; + + if( ( ret = f_rng( p_rng, key, sizeof( key ) ) ) != 0 ) + return( ret ); + + ret = mbedtls_md_setup( &ctx->hmac_ctx, mbedtls_md_info_from_type( COOKIE_MD ), 1 ); + if( ret != 0 ) + return( ret ); + + ret = mbedtls_md_hmac_starts( &ctx->hmac_ctx, key, sizeof( key ) ); + if( ret != 0 ) + return( ret ); + + mbedtls_zeroize( key, sizeof( key ) ); + + return( 0 ); +} + +/* + * Generate the HMAC part of a cookie + */ +static int ssl_cookie_hmac( mbedtls_md_context_t *hmac_ctx, + const unsigned char time[4], + unsigned char **p, unsigned char *end, + const unsigned char *cli_id, size_t cli_id_len ) +{ + unsigned char hmac_out[COOKIE_MD_OUTLEN]; + + if( (size_t)( end - *p ) < COOKIE_HMAC_LEN ) + return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); + + if( mbedtls_md_hmac_reset( hmac_ctx ) != 0 || + mbedtls_md_hmac_update( hmac_ctx, time, 4 ) != 0 || + mbedtls_md_hmac_update( hmac_ctx, cli_id, cli_id_len ) != 0 || + mbedtls_md_hmac_finish( hmac_ctx, hmac_out ) != 0 ) + { + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + + memcpy( *p, hmac_out, COOKIE_HMAC_LEN ); + *p += COOKIE_HMAC_LEN; + + return( 0 ); +} + +/* + * Generate cookie for DTLS ClientHello verification + */ +int mbedtls_ssl_cookie_write( void *p_ctx, + unsigned char **p, unsigned char *end, + const unsigned char *cli_id, size_t cli_id_len ) +{ + int ret; + mbedtls_ssl_cookie_ctx *ctx = (mbedtls_ssl_cookie_ctx *) p_ctx; + unsigned long t; + + if( ctx == NULL || cli_id == NULL ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + if( (size_t)( end - *p ) < COOKIE_LEN ) + return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); + +#if defined(MBEDTLS_HAVE_TIME) + t = (unsigned long) mbedtls_time( NULL ); +#else + t = ctx->serial++; +#endif + + (*p)[0] = (unsigned char)( t >> 24 ); + (*p)[1] = (unsigned char)( t >> 16 ); + (*p)[2] = (unsigned char)( t >> 8 ); + (*p)[3] = (unsigned char)( t ); + *p += 4; + +#if defined(MBEDTLS_THREADING_C) + if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR + ret ); +#endif + + ret = ssl_cookie_hmac( &ctx->hmac_ctx, *p - 4, + p, end, cli_id, cli_id_len ); + +#if defined(MBEDTLS_THREADING_C) + if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR + + MBEDTLS_ERR_THREADING_MUTEX_ERROR ); +#endif + + return( ret ); +} + +/* + * Check a cookie + */ +int mbedtls_ssl_cookie_check( void *p_ctx, + const unsigned char *cookie, size_t cookie_len, + const unsigned char *cli_id, size_t cli_id_len ) +{ + unsigned char ref_hmac[COOKIE_HMAC_LEN]; + int ret = 0; + unsigned char *p = ref_hmac; + mbedtls_ssl_cookie_ctx *ctx = (mbedtls_ssl_cookie_ctx *) p_ctx; + unsigned long cur_time, cookie_time; + + if( ctx == NULL || cli_id == NULL ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + if( cookie_len != COOKIE_LEN ) + return( -1 ); + +#if defined(MBEDTLS_THREADING_C) + if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR + ret ); +#endif + + if( ssl_cookie_hmac( &ctx->hmac_ctx, cookie, + &p, p + sizeof( ref_hmac ), + cli_id, cli_id_len ) != 0 ) + ret = -1; + +#if defined(MBEDTLS_THREADING_C) + if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR + + MBEDTLS_ERR_THREADING_MUTEX_ERROR ); +#endif + + if( ret != 0 ) + return( ret ); + + if( mbedtls_ssl_safer_memcmp( cookie + 4, ref_hmac, sizeof( ref_hmac ) ) != 0 ) + return( -1 ); + +#if defined(MBEDTLS_HAVE_TIME) + cur_time = (unsigned long) mbedtls_time( NULL ); +#else + cur_time = ctx->serial; +#endif + + cookie_time = ( (unsigned long) cookie[0] << 24 ) | + ( (unsigned long) cookie[1] << 16 ) | + ( (unsigned long) cookie[2] << 8 ) | + ( (unsigned long) cookie[3] ); + + if( ctx->timeout != 0 && cur_time - cookie_time > ctx->timeout ) + return( -1 ); + + return( 0 ); +} +#endif /* MBEDTLS_SSL_COOKIE_C */ diff --git a/security/mbedtls/src/ssl_srv.c b/security/mbedtls/src/ssl_srv.c new file mode 100644 index 0000000000..fc0d2d7b42 --- /dev/null +++ b/security/mbedtls/src/ssl_srv.c @@ -0,0 +1,3926 @@ +/* + * SSLv3/TLSv1 server-side functions + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_SSL_SRV_C) + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_calloc calloc +#define mbedtls_free free +#endif + +#include "mbedtls/debug.h" +#include "mbedtls/ssl.h" +#include "mbedtls/ssl_internal.h" + +#include + +#if defined(MBEDTLS_ECP_C) +#include "mbedtls/ecp.h" +#endif + +#if defined(MBEDTLS_HAVE_TIME) +#include "mbedtls/platform_time.h" +#endif + +#if defined(MBEDTLS_SSL_SESSION_TICKETS) +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} +#endif + +#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) +int mbedtls_ssl_set_client_transport_id( mbedtls_ssl_context *ssl, + const unsigned char *info, + size_t ilen ) +{ + if( ssl->conf->endpoint != MBEDTLS_SSL_IS_SERVER ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + mbedtls_free( ssl->cli_id ); + + if( ( ssl->cli_id = mbedtls_calloc( 1, ilen ) ) == NULL ) + return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); + + memcpy( ssl->cli_id, info, ilen ); + ssl->cli_id_len = ilen; + + return( 0 ); +} + +void mbedtls_ssl_conf_dtls_cookies( mbedtls_ssl_config *conf, + mbedtls_ssl_cookie_write_t *f_cookie_write, + mbedtls_ssl_cookie_check_t *f_cookie_check, + void *p_cookie ) +{ + conf->f_cookie_write = f_cookie_write; + conf->f_cookie_check = f_cookie_check; + conf->p_cookie = p_cookie; +} +#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */ + +#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) +static int ssl_parse_servername_ext( mbedtls_ssl_context *ssl, + const unsigned char *buf, + size_t len ) +{ + int ret; + size_t servername_list_size, hostname_len; + const unsigned char *p; + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "parse ServerName extension" ) ); + + servername_list_size = ( ( buf[0] << 8 ) | ( buf[1] ) ); + if( servername_list_size + 2 != len ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + p = buf + 2; + while( servername_list_size > 0 ) + { + hostname_len = ( ( p[1] << 8 ) | p[2] ); + if( hostname_len + 3 > servername_list_size ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + if( p[0] == MBEDTLS_TLS_EXT_SERVERNAME_HOSTNAME ) + { + ret = ssl->conf->f_sni( ssl->conf->p_sni, + ssl, p + 3, hostname_len ); + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "ssl_sni_wrapper", ret ); + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_UNRECOGNIZED_NAME ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + return( 0 ); + } + + servername_list_size -= hostname_len + 3; + p += hostname_len + 3; + } + + if( servername_list_size != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + return( 0 ); +} +#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ + +static int ssl_parse_renegotiation_info( mbedtls_ssl_context *ssl, + const unsigned char *buf, + size_t len ) +{ + int ret; + +#if defined(MBEDTLS_SSL_RENEGOTIATION) + if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ) + { + /* Check verify-data in constant-time. The length OTOH is no secret */ + if( len != 1 + ssl->verify_data_len || + buf[0] != ssl->verify_data_len || + mbedtls_ssl_safer_memcmp( buf + 1, ssl->peer_verify_data, + ssl->verify_data_len ) != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-matching renegotiation info" ) ); + + if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 ) + return( ret ); + + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + } + else +#endif /* MBEDTLS_SSL_RENEGOTIATION */ + { + if( len != 1 || buf[0] != 0x0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "non-zero length renegotiation info" ) ); + + if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 ) + return( ret ); + + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION; + } + + return( 0 ); +} + +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ + defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) +static int ssl_parse_signature_algorithms_ext( mbedtls_ssl_context *ssl, + const unsigned char *buf, + size_t len ) +{ + size_t sig_alg_list_size; + const unsigned char *p; + const unsigned char *end = buf + len; + const int *md_cur; + + + sig_alg_list_size = ( ( buf[0] << 8 ) | ( buf[1] ) ); + if( sig_alg_list_size + 2 != len || + sig_alg_list_size % 2 != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + /* + * For now, ignore the SignatureAlgorithm part and rely on offered + * ciphersuites only for that part. To be fixed later. + * + * So, just look at the HashAlgorithm part. + */ + for( md_cur = ssl->conf->sig_hashes; *md_cur != MBEDTLS_MD_NONE; md_cur++ ) { + for( p = buf + 2; p < end; p += 2 ) { + if( *md_cur == (int) mbedtls_ssl_md_alg_from_hash( p[0] ) ) { + ssl->handshake->sig_alg = p[0]; + goto have_sig_alg; + } + } + } + + /* Some key echanges do not need signatures at all */ + MBEDTLS_SSL_DEBUG_MSG( 3, ( "no signature_algorithm in common" ) ); + return( 0 ); + +have_sig_alg: + MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, signature_algorithm ext: %d", + ssl->handshake->sig_alg ) ); + + return( 0 ); +} +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && + MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ + +#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) +static int ssl_parse_supported_elliptic_curves( mbedtls_ssl_context *ssl, + const unsigned char *buf, + size_t len ) +{ + size_t list_size, our_size; + const unsigned char *p; + const mbedtls_ecp_curve_info *curve_info, **curves; + + list_size = ( ( buf[0] << 8 ) | ( buf[1] ) ); + if( list_size + 2 != len || + list_size % 2 != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + /* Should never happen unless client duplicates the extension */ + if( ssl->handshake->curves != NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + /* Don't allow our peer to make us allocate too much memory, + * and leave room for a final 0 */ + our_size = list_size / 2 + 1; + if( our_size > MBEDTLS_ECP_DP_MAX ) + our_size = MBEDTLS_ECP_DP_MAX; + + if( ( curves = mbedtls_calloc( our_size, sizeof( *curves ) ) ) == NULL ) + return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); + + ssl->handshake->curves = curves; + + p = buf + 2; + while( list_size > 0 && our_size > 1 ) + { + curve_info = mbedtls_ecp_curve_info_from_tls_id( ( p[0] << 8 ) | p[1] ); + + if( curve_info != NULL ) + { + *curves++ = curve_info; + our_size--; + } + + list_size -= 2; + p += 2; + } + + return( 0 ); +} + +static int ssl_parse_supported_point_formats( mbedtls_ssl_context *ssl, + const unsigned char *buf, + size_t len ) +{ + size_t list_size; + const unsigned char *p; + + list_size = buf[0]; + if( list_size + 1 != len ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + p = buf + 1; + while( list_size > 0 ) + { + if( p[0] == MBEDTLS_ECP_PF_UNCOMPRESSED || + p[0] == MBEDTLS_ECP_PF_COMPRESSED ) + { +#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) + ssl->handshake->ecdh_ctx.point_format = p[0]; +#endif +#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) + ssl->handshake->ecjpake_ctx.point_format = p[0]; +#endif + MBEDTLS_SSL_DEBUG_MSG( 4, ( "point format selected: %d", p[0] ) ); + return( 0 ); + } + + list_size--; + p++; + } + + return( 0 ); +} +#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || + MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) +static int ssl_parse_ecjpake_kkpp( mbedtls_ssl_context *ssl, + const unsigned char *buf, + size_t len ) +{ + int ret; + + if( mbedtls_ecjpake_check( &ssl->handshake->ecjpake_ctx ) != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip ecjpake kkpp extension" ) ); + return( 0 ); + } + + if( ( ret = mbedtls_ecjpake_read_round_one( &ssl->handshake->ecjpake_ctx, + buf, len ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_one", ret ); + return( ret ); + } + + /* Only mark the extension as OK when we're sure it is */ + ssl->handshake->cli_exts |= MBEDTLS_TLS_EXT_ECJPAKE_KKPP_OK; + + return( 0 ); +} +#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ + +#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) +static int ssl_parse_max_fragment_length_ext( mbedtls_ssl_context *ssl, + const unsigned char *buf, + size_t len ) +{ + if( len != 1 || buf[0] >= MBEDTLS_SSL_MAX_FRAG_LEN_INVALID ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + ssl->session_negotiate->mfl_code = buf[0]; + + return( 0 ); +} +#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ + +#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) +static int ssl_parse_truncated_hmac_ext( mbedtls_ssl_context *ssl, + const unsigned char *buf, + size_t len ) +{ + if( len != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + ((void) buf); + + if( ssl->conf->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_ENABLED ) + ssl->session_negotiate->trunc_hmac = MBEDTLS_SSL_TRUNC_HMAC_ENABLED; + + return( 0 ); +} +#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ + +#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) +static int ssl_parse_encrypt_then_mac_ext( mbedtls_ssl_context *ssl, + const unsigned char *buf, + size_t len ) +{ + if( len != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + ((void) buf); + + if( ssl->conf->encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED && + ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_0 ) + { + ssl->session_negotiate->encrypt_then_mac = MBEDTLS_SSL_ETM_ENABLED; + } + + return( 0 ); +} +#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ + +#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) +static int ssl_parse_extended_ms_ext( mbedtls_ssl_context *ssl, + const unsigned char *buf, + size_t len ) +{ + if( len != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + ((void) buf); + + if( ssl->conf->extended_ms == MBEDTLS_SSL_EXTENDED_MS_ENABLED && + ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_0 ) + { + ssl->handshake->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED; + } + + return( 0 ); +} +#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ + +#if defined(MBEDTLS_SSL_SESSION_TICKETS) +static int ssl_parse_session_ticket_ext( mbedtls_ssl_context *ssl, + unsigned char *buf, + size_t len ) +{ + int ret; + mbedtls_ssl_session session; + + mbedtls_ssl_session_init( &session ); + + if( ssl->conf->f_ticket_parse == NULL || + ssl->conf->f_ticket_write == NULL ) + { + return( 0 ); + } + + /* Remember the client asked us to send a new ticket */ + ssl->handshake->new_session_ticket = 1; + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket length: %d", len ) ); + + if( len == 0 ) + return( 0 ); + +#if defined(MBEDTLS_SSL_RENEGOTIATION) + if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ) + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket rejected: renegotiating" ) ); + return( 0 ); + } +#endif /* MBEDTLS_SSL_RENEGOTIATION */ + + /* + * Failures are ok: just ignore the ticket and proceed. + */ + if( ( ret = ssl->conf->f_ticket_parse( ssl->conf->p_ticket, &session, + buf, len ) ) != 0 ) + { + mbedtls_ssl_session_free( &session ); + + if( ret == MBEDTLS_ERR_SSL_INVALID_MAC ) + MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket is not authentic" ) ); + else if( ret == MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED ) + MBEDTLS_SSL_DEBUG_MSG( 3, ( "ticket is expired" ) ); + else + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_ticket_parse", ret ); + + return( 0 ); + } + + /* + * Keep the session ID sent by the client, since we MUST send it back to + * inform them we're accepting the ticket (RFC 5077 section 3.4) + */ + session.id_len = ssl->session_negotiate->id_len; + memcpy( &session.id, ssl->session_negotiate->id, session.id_len ); + + mbedtls_ssl_session_free( ssl->session_negotiate ); + memcpy( ssl->session_negotiate, &session, sizeof( mbedtls_ssl_session ) ); + + /* Zeroize instead of free as we copied the content */ + mbedtls_zeroize( &session, sizeof( mbedtls_ssl_session ) ); + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "session successfully restored from ticket" ) ); + + ssl->handshake->resume = 1; + + /* Don't send a new ticket after all, this one is OK */ + ssl->handshake->new_session_ticket = 0; + + return( 0 ); +} +#endif /* MBEDTLS_SSL_SESSION_TICKETS */ + +#if defined(MBEDTLS_SSL_ALPN) +static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl, + const unsigned char *buf, size_t len ) +{ + size_t list_len, cur_len, ours_len; + const unsigned char *theirs, *start, *end; + const char **ours; + + /* If ALPN not configured, just ignore the extension */ + if( ssl->conf->alpn_list == NULL ) + return( 0 ); + + /* + * opaque ProtocolName<1..2^8-1>; + * + * struct { + * ProtocolName protocol_name_list<2..2^16-1> + * } ProtocolNameList; + */ + + /* Min length is 2 (list_len) + 1 (name_len) + 1 (name) */ + if( len < 4 ) + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + + list_len = ( buf[0] << 8 ) | buf[1]; + if( list_len != len - 2 ) + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + + /* + * Use our order of preference + */ + start = buf + 2; + end = buf + len; + for( ours = ssl->conf->alpn_list; *ours != NULL; ours++ ) + { + ours_len = strlen( *ours ); + for( theirs = start; theirs != end; theirs += cur_len ) + { + /* If the list is well formed, we should get equality first */ + if( theirs > end ) + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + + cur_len = *theirs++; + + /* Empty strings MUST NOT be included */ + if( cur_len == 0 ) + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + + if( cur_len == ours_len && + memcmp( theirs, *ours, cur_len ) == 0 ) + { + ssl->alpn_chosen = *ours; + return( 0 ); + } + } + } + + /* If we get there, no match was found */ + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_NO_APPLICATION_PROTOCOL ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); +} +#endif /* MBEDTLS_SSL_ALPN */ + +/* + * Auxiliary functions for ServerHello parsing and related actions + */ + +#if defined(MBEDTLS_X509_CRT_PARSE_C) +/* + * Return 0 if the given key uses one of the acceptable curves, -1 otherwise + */ +#if defined(MBEDTLS_ECDSA_C) +static int ssl_check_key_curve( mbedtls_pk_context *pk, + const mbedtls_ecp_curve_info **curves ) +{ + const mbedtls_ecp_curve_info **crv = curves; + mbedtls_ecp_group_id grp_id = mbedtls_pk_ec( *pk )->grp.id; + + while( *crv != NULL ) + { + if( (*crv)->grp_id == grp_id ) + return( 0 ); + crv++; + } + + return( -1 ); +} +#endif /* MBEDTLS_ECDSA_C */ + +/* + * Try picking a certificate for this ciphersuite, + * return 0 on success and -1 on failure. + */ +static int ssl_pick_cert( mbedtls_ssl_context *ssl, + const mbedtls_ssl_ciphersuite_t * ciphersuite_info ) +{ + mbedtls_ssl_key_cert *cur, *list, *fallback = NULL; + mbedtls_pk_type_t pk_alg = mbedtls_ssl_get_ciphersuite_sig_pk_alg( ciphersuite_info ); + uint32_t flags; + +#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) + if( ssl->handshake->sni_key_cert != NULL ) + list = ssl->handshake->sni_key_cert; + else +#endif + list = ssl->conf->key_cert; + + if( pk_alg == MBEDTLS_PK_NONE ) + return( 0 ); + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite requires certificate" ) ); + + if( list == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "server has no certificate" ) ); + return( -1 ); + } + + for( cur = list; cur != NULL; cur = cur->next ) + { + MBEDTLS_SSL_DEBUG_CRT( 3, "candidate certificate chain, certificate", + cur->cert ); + + if( ! mbedtls_pk_can_do( cur->key, pk_alg ) ) + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: key type" ) ); + continue; + } + + /* + * This avoids sending the client a cert it'll reject based on + * keyUsage or other extensions. + * + * It also allows the user to provision different certificates for + * different uses based on keyUsage, eg if they want to avoid signing + * and decrypting with the same RSA key. + */ + if( mbedtls_ssl_check_cert_usage( cur->cert, ciphersuite_info, + MBEDTLS_SSL_IS_SERVER, &flags ) != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: " + "(extended) key usage extension" ) ); + continue; + } + +#if defined(MBEDTLS_ECDSA_C) + if( pk_alg == MBEDTLS_PK_ECDSA && + ssl_check_key_curve( cur->key, ssl->handshake->curves ) != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate mismatch: elliptic curve" ) ); + continue; + } +#endif + + /* + * Try to select a SHA-1 certificate for pre-1.2 clients, but still + * present them a SHA-higher cert rather than failing if it's the only + * one we got that satisfies the other conditions. + */ + if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 && + cur->cert->sig_md != MBEDTLS_MD_SHA1 ) + { + if( fallback == NULL ) + fallback = cur; + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "certificate not preferred: " + "sha-2 with pre-TLS 1.2 client" ) ); + continue; + } + } + + /* If we get there, we got a winner */ + break; + } + + if( cur == NULL ) + cur = fallback; + + /* Do not update ssl->handshake->key_cert unless there is a match */ + if( cur != NULL ) + { + ssl->handshake->key_cert = cur; + MBEDTLS_SSL_DEBUG_CRT( 3, "selected certificate chain, certificate", + ssl->handshake->key_cert->cert ); + return( 0 ); + } + + return( -1 ); +} +#endif /* MBEDTLS_X509_CRT_PARSE_C */ + +/* + * Check if a given ciphersuite is suitable for use with our config/keys/etc + * Sets ciphersuite_info only if the suite matches. + */ +static int ssl_ciphersuite_match( mbedtls_ssl_context *ssl, int suite_id, + const mbedtls_ssl_ciphersuite_t **ciphersuite_info ) +{ + const mbedtls_ssl_ciphersuite_t *suite_info; + + suite_info = mbedtls_ssl_ciphersuite_from_id( suite_id ); + if( suite_info == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "trying ciphersuite: %s", suite_info->name ) ); + + if( suite_info->min_minor_ver > ssl->minor_ver || + suite_info->max_minor_ver < ssl->minor_ver ) + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: version" ) ); + return( 0 ); + } + +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && + ( suite_info->flags & MBEDTLS_CIPHERSUITE_NODTLS ) ) + return( 0 ); +#endif + +#if defined(MBEDTLS_ARC4_C) + if( ssl->conf->arc4_disabled == MBEDTLS_SSL_ARC4_DISABLED && + suite_info->cipher == MBEDTLS_CIPHER_ARC4_128 ) + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: rc4" ) ); + return( 0 ); + } +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) + if( suite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE && + ( ssl->handshake->cli_exts & MBEDTLS_TLS_EXT_ECJPAKE_KKPP_OK ) == 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: ecjpake " + "not configured or ext missing" ) ); + return( 0 ); + } +#endif + + +#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) + if( mbedtls_ssl_ciphersuite_uses_ec( suite_info ) && + ( ssl->handshake->curves == NULL || + ssl->handshake->curves[0] == NULL ) ) + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: " + "no common elliptic curve" ) ); + return( 0 ); + } +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) + /* If the ciphersuite requires a pre-shared key and we don't + * have one, skip it now rather than failing later */ + if( mbedtls_ssl_ciphersuite_uses_psk( suite_info ) && + ssl->conf->f_psk == NULL && + ( ssl->conf->psk == NULL || ssl->conf->psk_identity == NULL || + ssl->conf->psk_identity_len == 0 || ssl->conf->psk_len == 0 ) ) + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: no pre-shared key" ) ); + return( 0 ); + } +#endif + +#if defined(MBEDTLS_X509_CRT_PARSE_C) + /* + * Final check: if ciphersuite requires us to have a + * certificate/key of a particular type: + * - select the appropriate certificate if we have one, or + * - try the next ciphersuite if we don't + * This must be done last since we modify the key_cert list. + */ + if( ssl_pick_cert( ssl, suite_info ) != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite mismatch: " + "no suitable certificate" ) ); + return( 0 ); + } +#endif + + *ciphersuite_info = suite_info; + return( 0 ); +} + +#if defined(MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO) +static int ssl_parse_client_hello_v2( mbedtls_ssl_context *ssl ) +{ + int ret, got_common_suite; + unsigned int i, j; + size_t n; + unsigned int ciph_len, sess_len, chal_len; + unsigned char *buf, *p; + const int *ciphersuites; + const mbedtls_ssl_ciphersuite_t *ciphersuite_info; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse client hello v2" ) ); + +#if defined(MBEDTLS_SSL_RENEGOTIATION) + if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "client hello v2 illegal for renegotiation" ) ); + + if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 ) + return( ret ); + + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } +#endif /* MBEDTLS_SSL_RENEGOTIATION */ + + buf = ssl->in_hdr; + + MBEDTLS_SSL_DEBUG_BUF( 4, "record header", buf, 5 ); + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v2, message type: %d", + buf[2] ) ); + MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v2, message len.: %d", + ( ( buf[0] & 0x7F ) << 8 ) | buf[1] ) ); + MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v2, max. version: [%d:%d]", + buf[3], buf[4] ) ); + + /* + * SSLv2 Client Hello + * + * Record layer: + * 0 . 1 message length + * + * SSL layer: + * 2 . 2 message type + * 3 . 4 protocol version + */ + if( buf[2] != MBEDTLS_SSL_HS_CLIENT_HELLO || + buf[3] != MBEDTLS_SSL_MAJOR_VERSION_3 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + n = ( ( buf[0] << 8 ) | buf[1] ) & 0x7FFF; + + if( n < 17 || n > 512 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + ssl->major_ver = MBEDTLS_SSL_MAJOR_VERSION_3; + ssl->minor_ver = ( buf[4] <= ssl->conf->max_minor_ver ) + ? buf[4] : ssl->conf->max_minor_ver; + + if( ssl->minor_ver < ssl->conf->min_minor_ver ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "client only supports ssl smaller than minimum" + " [%d:%d] < [%d:%d]", + ssl->major_ver, ssl->minor_ver, + ssl->conf->min_major_ver, ssl->conf->min_minor_ver ) ); + + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION ); + return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION ); + } + + ssl->handshake->max_major_ver = buf[3]; + ssl->handshake->max_minor_ver = buf[4]; + + if( ( ret = mbedtls_ssl_fetch_input( ssl, 2 + n ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret ); + return( ret ); + } + + ssl->handshake->update_checksum( ssl, buf + 2, n ); + + buf = ssl->in_msg; + n = ssl->in_left - 5; + + /* + * 0 . 1 ciphersuitelist length + * 2 . 3 session id length + * 4 . 5 challenge length + * 6 . .. ciphersuitelist + * .. . .. session id + * .. . .. challenge + */ + MBEDTLS_SSL_DEBUG_BUF( 4, "record contents", buf, n ); + + ciph_len = ( buf[0] << 8 ) | buf[1]; + sess_len = ( buf[2] << 8 ) | buf[3]; + chal_len = ( buf[4] << 8 ) | buf[5]; + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciph_len: %d, sess_len: %d, chal_len: %d", + ciph_len, sess_len, chal_len ) ); + + /* + * Make sure each parameter length is valid + */ + if( ciph_len < 3 || ( ciph_len % 3 ) != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + if( sess_len > 32 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + if( chal_len < 8 || chal_len > 32 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + if( n != 6 + ciph_len + sess_len + chal_len ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, ciphersuitelist", + buf + 6, ciph_len ); + MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, session id", + buf + 6 + ciph_len, sess_len ); + MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, challenge", + buf + 6 + ciph_len + sess_len, chal_len ); + + p = buf + 6 + ciph_len; + ssl->session_negotiate->id_len = sess_len; + memset( ssl->session_negotiate->id, 0, + sizeof( ssl->session_negotiate->id ) ); + memcpy( ssl->session_negotiate->id, p, ssl->session_negotiate->id_len ); + + p += sess_len; + memset( ssl->handshake->randbytes, 0, 64 ); + memcpy( ssl->handshake->randbytes + 32 - chal_len, p, chal_len ); + + /* + * Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV + */ + for( i = 0, p = buf + 6; i < ciph_len; i += 3, p += 3 ) + { + if( p[0] == 0 && p[1] == 0 && p[2] == MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO ) + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "received TLS_EMPTY_RENEGOTIATION_INFO " ) ); +#if defined(MBEDTLS_SSL_RENEGOTIATION) + if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "received RENEGOTIATION SCSV " + "during renegotiation" ) ); + + if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 ) + return( ret ); + + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } +#endif /* MBEDTLS_SSL_RENEGOTIATION */ + ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION; + break; + } + } + +#if defined(MBEDTLS_SSL_FALLBACK_SCSV) + for( i = 0, p = buf + 6; i < ciph_len; i += 3, p += 3 ) + { + if( p[0] == 0 && + p[1] == (unsigned char)( ( MBEDTLS_SSL_FALLBACK_SCSV_VALUE >> 8 ) & 0xff ) && + p[2] == (unsigned char)( ( MBEDTLS_SSL_FALLBACK_SCSV_VALUE ) & 0xff ) ) + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "received FALLBACK_SCSV" ) ); + + if( ssl->minor_ver < ssl->conf->max_minor_ver ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "inapropriate fallback" ) ); + + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_INAPROPRIATE_FALLBACK ); + + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + break; + } + } +#endif /* MBEDTLS_SSL_FALLBACK_SCSV */ + + got_common_suite = 0; + ciphersuites = ssl->conf->ciphersuite_list[ssl->minor_ver]; + ciphersuite_info = NULL; +#if defined(MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE) + for( j = 0, p = buf + 6; j < ciph_len; j += 3, p += 3 ) + { + for( i = 0; ciphersuites[i] != 0; i++ ) +#else + for( i = 0; ciphersuites[i] != 0; i++ ) + { + for( j = 0, p = buf + 6; j < ciph_len; j += 3, p += 3 ) +#endif + { + if( p[0] != 0 || + p[1] != ( ( ciphersuites[i] >> 8 ) & 0xFF ) || + p[2] != ( ( ciphersuites[i] ) & 0xFF ) ) + continue; + + got_common_suite = 1; + + if( ( ret = ssl_ciphersuite_match( ssl, ciphersuites[i], + &ciphersuite_info ) ) != 0 ) + return( ret ); + + if( ciphersuite_info != NULL ) + goto have_ciphersuite_v2; + } + } + + if( got_common_suite ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "got ciphersuites in common, " + "but none of them usable" ) ); + return( MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE ); + } + else + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no ciphersuites in common" ) ); + return( MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN ); + } + +have_ciphersuite_v2: + MBEDTLS_SSL_DEBUG_MSG( 2, ( "selected ciphersuite: %s", ciphersuite_info->name ) ); + + ssl->session_negotiate->ciphersuite = ciphersuites[i]; + ssl->transform_negotiate->ciphersuite_info = ciphersuite_info; + + /* + * SSLv2 Client Hello relevant renegotiation security checks + */ + if( ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && + ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) ); + + if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 ) + return( ret ); + + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + ssl->in_left = 0; + ssl->state++; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse client hello v2" ) ); + + return( 0 ); +} +#endif /* MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO */ + +static int ssl_parse_client_hello( mbedtls_ssl_context *ssl ) +{ + int ret, got_common_suite; + size_t i, j; + size_t ciph_offset, comp_offset, ext_offset; + size_t msg_len, ciph_len, sess_len, comp_len, ext_len; +#if defined(MBEDTLS_SSL_PROTO_DTLS) + size_t cookie_offset, cookie_len; +#endif + unsigned char *buf, *p, *ext; +#if defined(MBEDTLS_SSL_RENEGOTIATION) + int renegotiation_info_seen = 0; +#endif + int handshake_failure = 0; + const int *ciphersuites; + const mbedtls_ssl_ciphersuite_t *ciphersuite_info; + int major, minor; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse client hello" ) ); + +#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) +read_record_header: +#endif + /* + * If renegotiating, then the input was read with mbedtls_ssl_read_record(), + * otherwise read it ourselves manually in order to support SSLv2 + * ClientHello, which doesn't use the same record layer format. + */ +#if defined(MBEDTLS_SSL_RENEGOTIATION) + if( ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE ) +#endif + { + if( ( ret = mbedtls_ssl_fetch_input( ssl, 5 ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret ); + return( ret ); + } + } + + buf = ssl->in_hdr; + +#if defined(MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO) +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_STREAM ) +#endif + if( ( buf[0] & 0x80 ) != 0 ) + return ssl_parse_client_hello_v2( ssl ); +#endif + + MBEDTLS_SSL_DEBUG_BUF( 4, "record header", buf, mbedtls_ssl_hdr_len( ssl ) ); + + /* + * SSLv3/TLS Client Hello + * + * Record layer: + * 0 . 0 message type + * 1 . 2 protocol version + * 3 . 11 DTLS: epoch + record sequence number + * 3 . 4 message length + */ + MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, message type: %d", + buf[0] ) ); + + if( buf[0] != MBEDTLS_SSL_MSG_HANDSHAKE ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, message len.: %d", + ( ssl->in_len[0] << 8 ) | ssl->in_len[1] ) ); + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, protocol version: [%d:%d]", + buf[1], buf[2] ) ); + + mbedtls_ssl_read_version( &major, &minor, ssl->conf->transport, buf + 1 ); + + /* According to RFC 5246 Appendix E.1, the version here is typically + * "{03,00}, the lowest version number supported by the client, [or] the + * value of ClientHello.client_version", so the only meaningful check here + * is the major version shouldn't be less than 3 */ + if( major < MBEDTLS_SSL_MAJOR_VERSION_3 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + /* For DTLS if this is the initial handshake, remember the client sequence + * number to use it in our next message (RFC 6347 4.2.1) */ +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM +#if defined(MBEDTLS_SSL_RENEGOTIATION) + && ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE +#endif + ) + { + /* Epoch should be 0 for initial handshakes */ + if( ssl->in_ctr[0] != 0 || ssl->in_ctr[1] != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + memcpy( ssl->out_ctr + 2, ssl->in_ctr + 2, 6 ); + +#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) + if( mbedtls_ssl_dtls_replay_check( ssl ) != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "replayed record, discarding" ) ); + ssl->next_record_offset = 0; + ssl->in_left = 0; + goto read_record_header; + } + + /* No MAC to check yet, so we can update right now */ + mbedtls_ssl_dtls_replay_update( ssl ); +#endif + } +#endif /* MBEDTLS_SSL_PROTO_DTLS */ + + msg_len = ( ssl->in_len[0] << 8 ) | ssl->in_len[1]; + +#if defined(MBEDTLS_SSL_RENEGOTIATION) + if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ) + { + /* Set by mbedtls_ssl_read_record() */ + msg_len = ssl->in_hslen; + } + else +#endif + { + if( msg_len > MBEDTLS_SSL_MAX_CONTENT_LEN ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + if( ( ret = mbedtls_ssl_fetch_input( ssl, mbedtls_ssl_hdr_len( ssl ) + msg_len ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret ); + return( ret ); + } + + /* Done reading this record, get ready for the next one */ +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + ssl->next_record_offset = msg_len + mbedtls_ssl_hdr_len( ssl ); + else +#endif + ssl->in_left = 0; + } + + buf = ssl->in_msg; + + MBEDTLS_SSL_DEBUG_BUF( 4, "record contents", buf, msg_len ); + + ssl->handshake->update_checksum( ssl, buf, msg_len ); + + /* + * Handshake layer: + * 0 . 0 handshake type + * 1 . 3 handshake length + * 4 . 5 DTLS only: message seqence number + * 6 . 8 DTLS only: fragment offset + * 9 . 11 DTLS only: fragment length + */ + if( msg_len < mbedtls_ssl_hs_hdr_len( ssl ) ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, handshake type: %d", buf[0] ) ); + + if( buf[0] != MBEDTLS_SSL_HS_CLIENT_HELLO ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "client hello v3, handshake len.: %d", + ( buf[1] << 16 ) | ( buf[2] << 8 ) | buf[3] ) ); + + /* We don't support fragmentation of ClientHello (yet?) */ + if( buf[1] != 0 || + msg_len != mbedtls_ssl_hs_hdr_len( ssl ) + ( ( buf[2] << 8 ) | buf[3] ) ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + { + /* + * Copy the client's handshake message_seq on initial handshakes, + * check sequence number on renego. + */ +#if defined(MBEDTLS_SSL_RENEGOTIATION) + if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS ) + { + /* This couldn't be done in ssl_prepare_handshake_record() */ + unsigned int cli_msg_seq = ( ssl->in_msg[4] << 8 ) | + ssl->in_msg[5]; + + if( cli_msg_seq != ssl->handshake->in_msg_seq ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message_seq: " + "%d (expected %d)", cli_msg_seq, + ssl->handshake->in_msg_seq ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + ssl->handshake->in_msg_seq++; + } + else +#endif + { + unsigned int cli_msg_seq = ( ssl->in_msg[4] << 8 ) | + ssl->in_msg[5]; + ssl->handshake->out_msg_seq = cli_msg_seq; + ssl->handshake->in_msg_seq = cli_msg_seq + 1; + } + + /* + * For now we don't support fragmentation, so make sure + * fragment_offset == 0 and fragment_length == length + */ + if( ssl->in_msg[6] != 0 || ssl->in_msg[7] != 0 || ssl->in_msg[8] != 0 || + memcmp( ssl->in_msg + 1, ssl->in_msg + 9, 3 ) != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "ClientHello fragmentation not supported" ) ); + return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); + } + } +#endif /* MBEDTLS_SSL_PROTO_DTLS */ + + buf += mbedtls_ssl_hs_hdr_len( ssl ); + msg_len -= mbedtls_ssl_hs_hdr_len( ssl ); + + /* + * ClientHello layer: + * 0 . 1 protocol version + * 2 . 33 random bytes (starting with 4 bytes of Unix time) + * 34 . 35 session id length (1 byte) + * 35 . 34+x session id + * 35+x . 35+x DTLS only: cookie length (1 byte) + * 36+x . .. DTLS only: cookie + * .. . .. ciphersuite list length (2 bytes) + * .. . .. ciphersuite list + * .. . .. compression alg. list length (1 byte) + * .. . .. compression alg. list + * .. . .. extensions length (2 bytes, optional) + * .. . .. extensions (optional) + */ + + /* + * Minimal length (with everything empty and extensions ommitted) is + * 2 + 32 + 1 + 2 + 1 = 38 bytes. Check that first, so that we can + * read at least up to session id length without worrying. + */ + if( msg_len < 38 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + /* + * Check and save the protocol version + */ + MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, version", buf, 2 ); + + mbedtls_ssl_read_version( &ssl->major_ver, &ssl->minor_ver, + ssl->conf->transport, buf ); + + ssl->handshake->max_major_ver = ssl->major_ver; + ssl->handshake->max_minor_ver = ssl->minor_ver; + + if( ssl->major_ver < ssl->conf->min_major_ver || + ssl->minor_ver < ssl->conf->min_minor_ver ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "client only supports ssl smaller than minimum" + " [%d:%d] < [%d:%d]", + ssl->major_ver, ssl->minor_ver, + ssl->conf->min_major_ver, ssl->conf->min_minor_ver ) ); + + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_PROTOCOL_VERSION ); + + return( MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION ); + } + + if( ssl->major_ver > ssl->conf->max_major_ver ) + { + ssl->major_ver = ssl->conf->max_major_ver; + ssl->minor_ver = ssl->conf->max_minor_ver; + } + else if( ssl->minor_ver > ssl->conf->max_minor_ver ) + ssl->minor_ver = ssl->conf->max_minor_ver; + + /* + * Save client random (inc. Unix time) + */ + MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, random bytes", buf + 2, 32 ); + + memcpy( ssl->handshake->randbytes, buf + 2, 32 ); + + /* + * Check the session ID length and save session ID + */ + sess_len = buf[34]; + + if( sess_len > sizeof( ssl->session_negotiate->id ) || + sess_len + 34 + 2 > msg_len ) /* 2 for cipherlist length field */ + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, session id", buf + 35, sess_len ); + + ssl->session_negotiate->id_len = sess_len; + memset( ssl->session_negotiate->id, 0, + sizeof( ssl->session_negotiate->id ) ); + memcpy( ssl->session_negotiate->id, buf + 35, + ssl->session_negotiate->id_len ); + + /* + * Check the cookie length and content + */ +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + { + cookie_offset = 35 + sess_len; + cookie_len = buf[cookie_offset]; + + if( cookie_offset + 1 + cookie_len + 2 > msg_len ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, cookie", + buf + cookie_offset + 1, cookie_len ); + +#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) + if( ssl->conf->f_cookie_check != NULL +#if defined(MBEDTLS_SSL_RENEGOTIATION) + && ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE +#endif + ) + { + if( ssl->conf->f_cookie_check( ssl->conf->p_cookie, + buf + cookie_offset + 1, cookie_len, + ssl->cli_id, ssl->cli_id_len ) != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "cookie verification failed" ) ); + ssl->handshake->verify_cookie_len = 1; + } + else + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "cookie verification passed" ) ); + ssl->handshake->verify_cookie_len = 0; + } + } + else +#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */ + { + /* We know we didn't send a cookie, so it should be empty */ + if( cookie_len != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "cookie verification skipped" ) ); + } + + /* + * Check the ciphersuitelist length (will be parsed later) + */ + ciph_offset = cookie_offset + 1 + cookie_len; + } + else +#endif /* MBEDTLS_SSL_PROTO_DTLS */ + ciph_offset = 35 + sess_len; + + ciph_len = ( buf[ciph_offset + 0] << 8 ) + | ( buf[ciph_offset + 1] ); + + if( ciph_len < 2 || + ciph_len + 2 + ciph_offset + 1 > msg_len || /* 1 for comp. alg. len */ + ( ciph_len % 2 ) != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, ciphersuitelist", + buf + ciph_offset + 2, ciph_len ); + + /* + * Check the compression algorithms length and pick one + */ + comp_offset = ciph_offset + 2 + ciph_len; + + comp_len = buf[comp_offset]; + + if( comp_len < 1 || + comp_len > 16 || + comp_len + comp_offset + 1 > msg_len ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + MBEDTLS_SSL_DEBUG_BUF( 3, "client hello, compression", + buf + comp_offset + 1, comp_len ); + + ssl->session_negotiate->compression = MBEDTLS_SSL_COMPRESS_NULL; +#if defined(MBEDTLS_ZLIB_SUPPORT) + for( i = 0; i < comp_len; ++i ) + { + if( buf[comp_offset + 1 + i] == MBEDTLS_SSL_COMPRESS_DEFLATE ) + { + ssl->session_negotiate->compression = MBEDTLS_SSL_COMPRESS_DEFLATE; + break; + } + } +#endif + + /* See comments in ssl_write_client_hello() */ +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + ssl->session_negotiate->compression = MBEDTLS_SSL_COMPRESS_NULL; +#endif + + /* Do not parse the extensions if the protocol is SSLv3 */ +#if defined(MBEDTLS_SSL_PROTO_SSL3) + if( ( ssl->major_ver != 3 ) || ( ssl->minor_ver != 0 ) ) + { +#endif + /* + * Check the extension length + */ + ext_offset = comp_offset + 1 + comp_len; + if( msg_len > ext_offset ) + { + if( msg_len < ext_offset + 2 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + ext_len = ( buf[ext_offset + 0] << 8 ) + | ( buf[ext_offset + 1] ); + + if( ( ext_len > 0 && ext_len < 4 ) || + msg_len != ext_offset + 2 + ext_len ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + } + else + ext_len = 0; + + ext = buf + ext_offset + 2; + MBEDTLS_SSL_DEBUG_BUF( 3, "client hello extensions", ext, ext_len ); + + while( ext_len != 0 ) + { + unsigned int ext_id = ( ( ext[0] << 8 ) + | ( ext[1] ) ); + unsigned int ext_size = ( ( ext[2] << 8 ) + | ( ext[3] ) ); + + if( ext_size + 4 > ext_len ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + switch( ext_id ) + { +#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) + case MBEDTLS_TLS_EXT_SERVERNAME: + MBEDTLS_SSL_DEBUG_MSG( 3, ( "found ServerName extension" ) ); + if( ssl->conf->f_sni == NULL ) + break; + + ret = ssl_parse_servername_ext( ssl, ext + 4, ext_size ); + if( ret != 0 ) + return( ret ); + break; +#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ + + case MBEDTLS_TLS_EXT_RENEGOTIATION_INFO: + MBEDTLS_SSL_DEBUG_MSG( 3, ( "found renegotiation extension" ) ); +#if defined(MBEDTLS_SSL_RENEGOTIATION) + renegotiation_info_seen = 1; +#endif + + ret = ssl_parse_renegotiation_info( ssl, ext + 4, ext_size ); + if( ret != 0 ) + return( ret ); + break; + +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ + defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) + case MBEDTLS_TLS_EXT_SIG_ALG: + MBEDTLS_SSL_DEBUG_MSG( 3, ( "found signature_algorithms extension" ) ); +#if defined(MBEDTLS_SSL_RENEGOTIATION) + if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS ) + break; +#endif + + ret = ssl_parse_signature_algorithms_ext( ssl, ext + 4, ext_size ); + if( ret != 0 ) + return( ret ); + break; +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 && + MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ + +#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) + case MBEDTLS_TLS_EXT_SUPPORTED_ELLIPTIC_CURVES: + MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported elliptic curves extension" ) ); + + ret = ssl_parse_supported_elliptic_curves( ssl, ext + 4, ext_size ); + if( ret != 0 ) + return( ret ); + break; + + case MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS: + MBEDTLS_SSL_DEBUG_MSG( 3, ( "found supported point formats extension" ) ); + ssl->handshake->cli_exts |= MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT; + + ret = ssl_parse_supported_point_formats( ssl, ext + 4, ext_size ); + if( ret != 0 ) + return( ret ); + break; +#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || + MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) + case MBEDTLS_TLS_EXT_ECJPAKE_KKPP: + MBEDTLS_SSL_DEBUG_MSG( 3, ( "found ecjpake kkpp extension" ) ); + + ret = ssl_parse_ecjpake_kkpp( ssl, ext + 4, ext_size ); + if( ret != 0 ) + return( ret ); + break; +#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ + +#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) + case MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH: + MBEDTLS_SSL_DEBUG_MSG( 3, ( "found max fragment length extension" ) ); + + ret = ssl_parse_max_fragment_length_ext( ssl, ext + 4, ext_size ); + if( ret != 0 ) + return( ret ); + break; +#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ + +#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) + case MBEDTLS_TLS_EXT_TRUNCATED_HMAC: + MBEDTLS_SSL_DEBUG_MSG( 3, ( "found truncated hmac extension" ) ); + + ret = ssl_parse_truncated_hmac_ext( ssl, ext + 4, ext_size ); + if( ret != 0 ) + return( ret ); + break; +#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ + +#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) + case MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC: + MBEDTLS_SSL_DEBUG_MSG( 3, ( "found encrypt then mac extension" ) ); + + ret = ssl_parse_encrypt_then_mac_ext( ssl, ext + 4, ext_size ); + if( ret != 0 ) + return( ret ); + break; +#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ + +#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) + case MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET: + MBEDTLS_SSL_DEBUG_MSG( 3, ( "found extended master secret extension" ) ); + + ret = ssl_parse_extended_ms_ext( ssl, ext + 4, ext_size ); + if( ret != 0 ) + return( ret ); + break; +#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ + +#if defined(MBEDTLS_SSL_SESSION_TICKETS) + case MBEDTLS_TLS_EXT_SESSION_TICKET: + MBEDTLS_SSL_DEBUG_MSG( 3, ( "found session ticket extension" ) ); + + ret = ssl_parse_session_ticket_ext( ssl, ext + 4, ext_size ); + if( ret != 0 ) + return( ret ); + break; +#endif /* MBEDTLS_SSL_SESSION_TICKETS */ + +#if defined(MBEDTLS_SSL_ALPN) + case MBEDTLS_TLS_EXT_ALPN: + MBEDTLS_SSL_DEBUG_MSG( 3, ( "found alpn extension" ) ); + + ret = ssl_parse_alpn_ext( ssl, ext + 4, ext_size ); + if( ret != 0 ) + return( ret ); + break; +#endif /* MBEDTLS_SSL_SESSION_TICKETS */ + + default: + MBEDTLS_SSL_DEBUG_MSG( 3, ( "unknown extension found: %d (ignoring)", + ext_id ) ); + } + + ext_len -= 4 + ext_size; + ext += 4 + ext_size; + + if( ext_len > 0 && ext_len < 4 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client hello message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + } +#if defined(MBEDTLS_SSL_PROTO_SSL3) + } +#endif + +#if defined(MBEDTLS_SSL_FALLBACK_SCSV) + for( i = 0, p = buf + 41 + sess_len; i < ciph_len; i += 2, p += 2 ) + { + if( p[0] == (unsigned char)( ( MBEDTLS_SSL_FALLBACK_SCSV_VALUE >> 8 ) & 0xff ) && + p[1] == (unsigned char)( ( MBEDTLS_SSL_FALLBACK_SCSV_VALUE ) & 0xff ) ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "received FALLBACK_SCSV" ) ); + + if( ssl->minor_ver < ssl->conf->max_minor_ver ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "inapropriate fallback" ) ); + + mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_INAPROPRIATE_FALLBACK ); + + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + break; + } + } +#endif /* MBEDTLS_SSL_FALLBACK_SCSV */ + + /* + * Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV + */ + for( i = 0, p = buf + ciph_offset + 2; i < ciph_len; i += 2, p += 2 ) + { + if( p[0] == 0 && p[1] == MBEDTLS_SSL_EMPTY_RENEGOTIATION_INFO ) + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "received TLS_EMPTY_RENEGOTIATION_INFO " ) ); +#if defined(MBEDTLS_SSL_RENEGOTIATION) + if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "received RENEGOTIATION SCSV during renegotiation" ) ); + + if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 ) + return( ret ); + + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } +#endif + ssl->secure_renegotiation = MBEDTLS_SSL_SECURE_RENEGOTIATION; + break; + } + } + + /* + * Renegotiation security checks + */ + if( ssl->secure_renegotiation != MBEDTLS_SSL_SECURE_RENEGOTIATION && + ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_BREAK_HANDSHAKE ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation, breaking off handshake" ) ); + handshake_failure = 1; + } +#if defined(MBEDTLS_SSL_RENEGOTIATION) + else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && + ssl->secure_renegotiation == MBEDTLS_SSL_SECURE_RENEGOTIATION && + renegotiation_info_seen == 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation_info extension missing (secure)" ) ); + handshake_failure = 1; + } + else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && + ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && + ssl->conf->allow_legacy_renegotiation == MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "legacy renegotiation not allowed" ) ); + handshake_failure = 1; + } + else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && + ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && + renegotiation_info_seen == 1 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation_info extension present (legacy)" ) ); + handshake_failure = 1; + } +#endif /* MBEDTLS_SSL_RENEGOTIATION */ + + if( handshake_failure == 1 ) + { + if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 ) + return( ret ); + + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + /* + * Search for a matching ciphersuite + * (At the end because we need information from the EC-based extensions + * and certificate from the SNI callback triggered by the SNI extension.) + */ + got_common_suite = 0; + ciphersuites = ssl->conf->ciphersuite_list[ssl->minor_ver]; + ciphersuite_info = NULL; +#if defined(MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE) + for( j = 0, p = buf + ciph_offset + 2; j < ciph_len; j += 2, p += 2 ) + { + for( i = 0; ciphersuites[i] != 0; i++ ) +#else + for( i = 0; ciphersuites[i] != 0; i++ ) + { + for( j = 0, p = buf + ciph_offset + 2; j < ciph_len; j += 2, p += 2 ) +#endif + { + if( p[0] != ( ( ciphersuites[i] >> 8 ) & 0xFF ) || + p[1] != ( ( ciphersuites[i] ) & 0xFF ) ) + continue; + + got_common_suite = 1; + + if( ( ret = ssl_ciphersuite_match( ssl, ciphersuites[i], + &ciphersuite_info ) ) != 0 ) + return( ret ); + + if( ciphersuite_info != NULL ) + goto have_ciphersuite; + } + } + + if( got_common_suite ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "got ciphersuites in common, " + "but none of them usable" ) ); + mbedtls_ssl_send_fatal_handshake_failure( ssl ); + return( MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE ); + } + else + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no ciphersuites in common" ) ); + mbedtls_ssl_send_fatal_handshake_failure( ssl ); + return( MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN ); + } + +have_ciphersuite: + MBEDTLS_SSL_DEBUG_MSG( 2, ( "selected ciphersuite: %s", ciphersuite_info->name ) ); + + ssl->session_negotiate->ciphersuite = ciphersuites[i]; + ssl->transform_negotiate->ciphersuite_info = ciphersuite_info; + + ssl->state++; + +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + mbedtls_ssl_recv_flight_completed( ssl ); +#endif + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse client hello" ) ); + + return( 0 ); +} + +#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) +static void ssl_write_truncated_hmac_ext( mbedtls_ssl_context *ssl, + unsigned char *buf, + size_t *olen ) +{ + unsigned char *p = buf; + + if( ssl->session_negotiate->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_DISABLED ) + { + *olen = 0; + return; + } + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding truncated hmac extension" ) ); + + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_TRUNCATED_HMAC ) & 0xFF ); + + *p++ = 0x00; + *p++ = 0x00; + + *olen = 4; +} +#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ + +#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) +static void ssl_write_encrypt_then_mac_ext( mbedtls_ssl_context *ssl, + unsigned char *buf, + size_t *olen ) +{ + unsigned char *p = buf; + const mbedtls_ssl_ciphersuite_t *suite = NULL; + const mbedtls_cipher_info_t *cipher = NULL; + + if( ssl->session_negotiate->encrypt_then_mac == MBEDTLS_SSL_EXTENDED_MS_DISABLED || + ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) + { + *olen = 0; + return; + } + + /* + * RFC 7366: "If a server receives an encrypt-then-MAC request extension + * from a client and then selects a stream or Authenticated Encryption + * with Associated Data (AEAD) ciphersuite, it MUST NOT send an + * encrypt-then-MAC response extension back to the client." + */ + if( ( suite = mbedtls_ssl_ciphersuite_from_id( + ssl->session_negotiate->ciphersuite ) ) == NULL || + ( cipher = mbedtls_cipher_info_from_type( suite->cipher ) ) == NULL || + cipher->mode != MBEDTLS_MODE_CBC ) + { + *olen = 0; + return; + } + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding encrypt then mac extension" ) ); + + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ENCRYPT_THEN_MAC ) & 0xFF ); + + *p++ = 0x00; + *p++ = 0x00; + + *olen = 4; +} +#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ + +#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) +static void ssl_write_extended_ms_ext( mbedtls_ssl_context *ssl, + unsigned char *buf, + size_t *olen ) +{ + unsigned char *p = buf; + + if( ssl->handshake->extended_ms == MBEDTLS_SSL_EXTENDED_MS_DISABLED || + ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) + { + *olen = 0; + return; + } + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding extended master secret " + "extension" ) ); + + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_EXTENDED_MASTER_SECRET ) & 0xFF ); + + *p++ = 0x00; + *p++ = 0x00; + + *olen = 4; +} +#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ + +#if defined(MBEDTLS_SSL_SESSION_TICKETS) +static void ssl_write_session_ticket_ext( mbedtls_ssl_context *ssl, + unsigned char *buf, + size_t *olen ) +{ + unsigned char *p = buf; + + if( ssl->handshake->new_session_ticket == 0 ) + { + *olen = 0; + return; + } + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding session ticket extension" ) ); + + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SESSION_TICKET ) & 0xFF ); + + *p++ = 0x00; + *p++ = 0x00; + + *olen = 4; +} +#endif /* MBEDTLS_SSL_SESSION_TICKETS */ + +static void ssl_write_renegotiation_ext( mbedtls_ssl_context *ssl, + unsigned char *buf, + size_t *olen ) +{ + unsigned char *p = buf; + + if( ssl->secure_renegotiation != MBEDTLS_SSL_SECURE_RENEGOTIATION ) + { + *olen = 0; + return; + } + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, secure renegotiation extension" ) ); + + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_RENEGOTIATION_INFO ) & 0xFF ); + +#if defined(MBEDTLS_SSL_RENEGOTIATION) + if( ssl->renego_status != MBEDTLS_SSL_INITIAL_HANDSHAKE ) + { + *p++ = 0x00; + *p++ = ( ssl->verify_data_len * 2 + 1 ) & 0xFF; + *p++ = ssl->verify_data_len * 2 & 0xFF; + + memcpy( p, ssl->peer_verify_data, ssl->verify_data_len ); + p += ssl->verify_data_len; + memcpy( p, ssl->own_verify_data, ssl->verify_data_len ); + p += ssl->verify_data_len; + } + else +#endif /* MBEDTLS_SSL_RENEGOTIATION */ + { + *p++ = 0x00; + *p++ = 0x01; + *p++ = 0x00; + } + + *olen = p - buf; +} + +#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) +static void ssl_write_max_fragment_length_ext( mbedtls_ssl_context *ssl, + unsigned char *buf, + size_t *olen ) +{ + unsigned char *p = buf; + + if( ssl->session_negotiate->mfl_code == MBEDTLS_SSL_MAX_FRAG_LEN_NONE ) + { + *olen = 0; + return; + } + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, max_fragment_length extension" ) ); + + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_MAX_FRAGMENT_LENGTH ) & 0xFF ); + + *p++ = 0x00; + *p++ = 1; + + *p++ = ssl->session_negotiate->mfl_code; + + *olen = 5; +} +#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ + +#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) +static void ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl, + unsigned char *buf, + size_t *olen ) +{ + unsigned char *p = buf; + ((void) ssl); + + if( ( ssl->handshake->cli_exts & + MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS_PRESENT ) == 0 ) + { + *olen = 0; + return; + } + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, supported_point_formats extension" ) ); + + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_SUPPORTED_POINT_FORMATS ) & 0xFF ); + + *p++ = 0x00; + *p++ = 2; + + *p++ = 1; + *p++ = MBEDTLS_ECP_PF_UNCOMPRESSED; + + *olen = 6; +} +#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) +static void ssl_write_ecjpake_kkpp_ext( mbedtls_ssl_context *ssl, + unsigned char *buf, + size_t *olen ) +{ + int ret; + unsigned char *p = buf; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; + size_t kkpp_len; + + *olen = 0; + + /* Skip costly computation if not needed */ + if( ssl->transform_negotiate->ciphersuite_info->key_exchange != + MBEDTLS_KEY_EXCHANGE_ECJPAKE ) + return; + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, ecjpake kkpp extension" ) ); + + if( end - p < 4 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); + return; + } + + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( MBEDTLS_TLS_EXT_ECJPAKE_KKPP ) & 0xFF ); + + ret = mbedtls_ecjpake_write_round_one( &ssl->handshake->ecjpake_ctx, + p + 2, end - p - 2, &kkpp_len, + ssl->conf->f_rng, ssl->conf->p_rng ); + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1 , "mbedtls_ecjpake_write_round_one", ret ); + return; + } + + *p++ = (unsigned char)( ( kkpp_len >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( kkpp_len ) & 0xFF ); + + *olen = kkpp_len + 4; +} +#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ + +#if defined(MBEDTLS_SSL_ALPN ) +static void ssl_write_alpn_ext( mbedtls_ssl_context *ssl, + unsigned char *buf, size_t *olen ) +{ + if( ssl->alpn_chosen == NULL ) + { + *olen = 0; + return; + } + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, adding alpn extension" ) ); + + /* + * 0 . 1 ext identifier + * 2 . 3 ext length + * 4 . 5 protocol list length + * 6 . 6 protocol name length + * 7 . 7+n protocol name + */ + buf[0] = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN >> 8 ) & 0xFF ); + buf[1] = (unsigned char)( ( MBEDTLS_TLS_EXT_ALPN ) & 0xFF ); + + *olen = 7 + strlen( ssl->alpn_chosen ); + + buf[2] = (unsigned char)( ( ( *olen - 4 ) >> 8 ) & 0xFF ); + buf[3] = (unsigned char)( ( ( *olen - 4 ) ) & 0xFF ); + + buf[4] = (unsigned char)( ( ( *olen - 6 ) >> 8 ) & 0xFF ); + buf[5] = (unsigned char)( ( ( *olen - 6 ) ) & 0xFF ); + + buf[6] = (unsigned char)( ( ( *olen - 7 ) ) & 0xFF ); + + memcpy( buf + 7, ssl->alpn_chosen, *olen - 7 ); +} +#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C */ + +#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) +static int ssl_write_hello_verify_request( mbedtls_ssl_context *ssl ) +{ + int ret; + unsigned char *p = ssl->out_msg + 4; + unsigned char *cookie_len_byte; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write hello verify request" ) ); + + /* + * struct { + * ProtocolVersion server_version; + * opaque cookie<0..2^8-1>; + * } HelloVerifyRequest; + */ + + /* The RFC is not clear on this point, but sending the actual negotiated + * version looks like the most interoperable thing to do. */ + mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver, + ssl->conf->transport, p ); + MBEDTLS_SSL_DEBUG_BUF( 3, "server version", p, 2 ); + p += 2; + + /* If we get here, f_cookie_check is not null */ + if( ssl->conf->f_cookie_write == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "inconsistent cookie callbacks" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + + /* Skip length byte until we know the length */ + cookie_len_byte = p++; + + if( ( ret = ssl->conf->f_cookie_write( ssl->conf->p_cookie, + &p, ssl->out_buf + MBEDTLS_SSL_BUFFER_LEN, + ssl->cli_id, ssl->cli_id_len ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "f_cookie_write", ret ); + return( ret ); + } + + *cookie_len_byte = (unsigned char)( p - ( cookie_len_byte + 1 ) ); + + MBEDTLS_SSL_DEBUG_BUF( 3, "cookie sent", cookie_len_byte + 1, *cookie_len_byte ); + + ssl->out_msglen = p - ssl->out_msg; + ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; + ssl->out_msg[0] = MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST; + + ssl->state = MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT; + + if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); + return( ret ); + } + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write hello verify request" ) ); + + return( 0 ); +} +#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */ + +static int ssl_write_server_hello( mbedtls_ssl_context *ssl ) +{ +#if defined(MBEDTLS_HAVE_TIME) + mbedtls_time_t t; +#endif + int ret; + size_t olen, ext_len = 0, n; + unsigned char *buf, *p; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server hello" ) ); + +#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && + ssl->handshake->verify_cookie_len != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "client hello was not authenticated" ) ); + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server hello" ) ); + + return( ssl_write_hello_verify_request( ssl ) ); + } +#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */ + + if( ssl->conf->f_rng == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "no RNG provided") ); + return( MBEDTLS_ERR_SSL_NO_RNG ); + } + + /* + * 0 . 0 handshake type + * 1 . 3 handshake length + * 4 . 5 protocol version + * 6 . 9 UNIX time() + * 10 . 37 random bytes + */ + buf = ssl->out_msg; + p = buf + 4; + + mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver, + ssl->conf->transport, p ); + p += 2; + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen version: [%d:%d]", + buf[4], buf[5] ) ); + +#if defined(MBEDTLS_HAVE_TIME) + t = mbedtls_time( NULL ); + *p++ = (unsigned char)( t >> 24 ); + *p++ = (unsigned char)( t >> 16 ); + *p++ = (unsigned char)( t >> 8 ); + *p++ = (unsigned char)( t ); + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, current time: %lu", t ) ); +#else + if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 4 ) ) != 0 ) + return( ret ); + + p += 4; +#endif /* MBEDTLS_HAVE_TIME */ + + if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, p, 28 ) ) != 0 ) + return( ret ); + + p += 28; + + memcpy( ssl->handshake->randbytes + 32, buf + 6, 32 ); + + MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, random bytes", buf + 6, 32 ); + + /* + * Resume is 0 by default, see ssl_handshake_init(). + * It may be already set to 1 by ssl_parse_session_ticket_ext(). + * If not, try looking up session ID in our cache. + */ + if( ssl->handshake->resume == 0 && +#if defined(MBEDTLS_SSL_RENEGOTIATION) + ssl->renego_status == MBEDTLS_SSL_INITIAL_HANDSHAKE && +#endif + ssl->session_negotiate->id_len != 0 && + ssl->conf->f_get_cache != NULL && + ssl->conf->f_get_cache( ssl->conf->p_cache, ssl->session_negotiate ) == 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "session successfully restored from cache" ) ); + ssl->handshake->resume = 1; + } + + if( ssl->handshake->resume == 0 ) + { + /* + * New session, create a new session id, + * unless we're about to issue a session ticket + */ + ssl->state++; + +#if defined(MBEDTLS_HAVE_TIME) + ssl->session_negotiate->start = mbedtls_time( NULL ); +#endif + +#if defined(MBEDTLS_SSL_SESSION_TICKETS) + if( ssl->handshake->new_session_ticket != 0 ) + { + ssl->session_negotiate->id_len = n = 0; + memset( ssl->session_negotiate->id, 0, 32 ); + } + else +#endif /* MBEDTLS_SSL_SESSION_TICKETS */ + { + ssl->session_negotiate->id_len = n = 32; + if( ( ret = ssl->conf->f_rng( ssl->conf->p_rng, ssl->session_negotiate->id, + n ) ) != 0 ) + return( ret ); + } + } + else + { + /* + * Resuming a session + */ + n = ssl->session_negotiate->id_len; + ssl->state = MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC; + + if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret ); + return( ret ); + } + } + + /* + * 38 . 38 session id length + * 39 . 38+n session id + * 39+n . 40+n chosen ciphersuite + * 41+n . 41+n chosen compression alg. + * 42+n . 43+n extensions length + * 44+n . 43+n+m extensions + */ + *p++ = (unsigned char) ssl->session_negotiate->id_len; + memcpy( p, ssl->session_negotiate->id, ssl->session_negotiate->id_len ); + p += ssl->session_negotiate->id_len; + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, session id len.: %d", n ) ); + MBEDTLS_SSL_DEBUG_BUF( 3, "server hello, session id", buf + 39, n ); + MBEDTLS_SSL_DEBUG_MSG( 3, ( "%s session has been resumed", + ssl->handshake->resume ? "a" : "no" ) ); + + *p++ = (unsigned char)( ssl->session_negotiate->ciphersuite >> 8 ); + *p++ = (unsigned char)( ssl->session_negotiate->ciphersuite ); + *p++ = (unsigned char)( ssl->session_negotiate->compression ); + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, chosen ciphersuite: %s", + mbedtls_ssl_get_ciphersuite_name( ssl->session_negotiate->ciphersuite ) ) ); + MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, compress alg.: 0x%02X", + ssl->session_negotiate->compression ) ); + + /* Do not write the extensions if the protocol is SSLv3 */ +#if defined(MBEDTLS_SSL_PROTO_SSL3) + if( ( ssl->major_ver != 3 ) || ( ssl->minor_ver != 0 ) ) + { +#endif + + /* + * First write extensions, then the total length + */ + ssl_write_renegotiation_ext( ssl, p + 2 + ext_len, &olen ); + ext_len += olen; + +#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) + ssl_write_max_fragment_length_ext( ssl, p + 2 + ext_len, &olen ); + ext_len += olen; +#endif + +#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) + ssl_write_truncated_hmac_ext( ssl, p + 2 + ext_len, &olen ); + ext_len += olen; +#endif + +#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) + ssl_write_encrypt_then_mac_ext( ssl, p + 2 + ext_len, &olen ); + ext_len += olen; +#endif + +#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) + ssl_write_extended_ms_ext( ssl, p + 2 + ext_len, &olen ); + ext_len += olen; +#endif + +#if defined(MBEDTLS_SSL_SESSION_TICKETS) + ssl_write_session_ticket_ext( ssl, p + 2 + ext_len, &olen ); + ext_len += olen; +#endif + +#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) + ssl_write_supported_point_formats_ext( ssl, p + 2 + ext_len, &olen ); + ext_len += olen; +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) + ssl_write_ecjpake_kkpp_ext( ssl, p + 2 + ext_len, &olen ); + ext_len += olen; +#endif + +#if defined(MBEDTLS_SSL_ALPN) + ssl_write_alpn_ext( ssl, p + 2 + ext_len, &olen ); + ext_len += olen; +#endif + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "server hello, total extension length: %d", ext_len ) ); + + if( ext_len > 0 ) + { + *p++ = (unsigned char)( ( ext_len >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( ext_len ) & 0xFF ); + p += ext_len; + } + +#if defined(MBEDTLS_SSL_PROTO_SSL3) + } +#endif + + ssl->out_msglen = p - buf; + ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; + ssl->out_msg[0] = MBEDTLS_SSL_HS_SERVER_HELLO; + + ret = mbedtls_ssl_write_record( ssl ); + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server hello" ) ); + + return( ret ); +} + +#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)&& \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) +static int ssl_write_certificate_request( mbedtls_ssl_context *ssl ) +{ + const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate request" ) ); + + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate request" ) ); + ssl->state++; + return( 0 ); + } + + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); +} +#else +static int ssl_write_certificate_request( mbedtls_ssl_context *ssl ) +{ + int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; + const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; + size_t dn_size, total_dn_size; /* excluding length bytes */ + size_t ct_len, sa_len; /* including length bytes */ + unsigned char *buf, *p; + const unsigned char * const end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; + const mbedtls_x509_crt *crt; + int authmode; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate request" ) ); + + ssl->state++; + +#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) + if( ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET ) + authmode = ssl->handshake->sni_authmode; + else +#endif + authmode = ssl->conf->authmode; + + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE || + authmode == MBEDTLS_SSL_VERIFY_NONE ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate request" ) ); + return( 0 ); + } + + /* + * 0 . 0 handshake type + * 1 . 3 handshake length + * 4 . 4 cert type count + * 5 .. m-1 cert types + * m .. m+1 sig alg length (TLS 1.2 only) + * m+1 .. n-1 SignatureAndHashAlgorithms (TLS 1.2 only) + * n .. n+1 length of all DNs + * n+2 .. n+3 length of DN 1 + * n+4 .. ... Distinguished Name #1 + * ... .. ... length of DN 2, etc. + */ + buf = ssl->out_msg; + p = buf + 4; + + /* + * Supported certificate types + * + * ClientCertificateType certificate_types<1..2^8-1>; + * enum { (255) } ClientCertificateType; + */ + ct_len = 0; + +#if defined(MBEDTLS_RSA_C) + p[1 + ct_len++] = MBEDTLS_SSL_CERT_TYPE_RSA_SIGN; +#endif +#if defined(MBEDTLS_ECDSA_C) + p[1 + ct_len++] = MBEDTLS_SSL_CERT_TYPE_ECDSA_SIGN; +#endif + + p[0] = (unsigned char) ct_len++; + p += ct_len; + + sa_len = 0; +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) + /* + * Add signature_algorithms for verify (TLS 1.2) + * + * SignatureAndHashAlgorithm supported_signature_algorithms<2..2^16-2>; + * + * struct { + * HashAlgorithm hash; + * SignatureAlgorithm signature; + * } SignatureAndHashAlgorithm; + * + * enum { (255) } HashAlgorithm; + * enum { (255) } SignatureAlgorithm; + */ + if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) + { + const int *cur; + + /* + * Supported signature algorithms + */ + for( cur = ssl->conf->sig_hashes; *cur != MBEDTLS_MD_NONE; cur++ ) + { + unsigned char hash = mbedtls_ssl_hash_from_md_alg( *cur ); + + if( MBEDTLS_SSL_HASH_NONE == hash || mbedtls_ssl_set_calc_verify_md( ssl, hash ) ) + continue; + +#if defined(MBEDTLS_RSA_C) + p[2 + sa_len++] = hash; + p[2 + sa_len++] = MBEDTLS_SSL_SIG_RSA; +#endif +#if defined(MBEDTLS_ECDSA_C) + p[2 + sa_len++] = hash; + p[2 + sa_len++] = MBEDTLS_SSL_SIG_ECDSA; +#endif + } + + p[0] = (unsigned char)( sa_len >> 8 ); + p[1] = (unsigned char)( sa_len ); + sa_len += 2; + p += sa_len; + } +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ + + /* + * DistinguishedName certificate_authorities<0..2^16-1>; + * opaque DistinguishedName<1..2^16-1>; + */ + p += 2; +#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) + if( ssl->handshake->sni_ca_chain != NULL ) + crt = ssl->handshake->sni_ca_chain; + else +#endif + crt = ssl->conf->ca_chain; + + total_dn_size = 0; + while( crt != NULL && crt->version != 0 ) + { + dn_size = crt->subject_raw.len; + + if( end < p || + (size_t)( end - p ) < dn_size || + (size_t)( end - p ) < 2 + dn_size ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "skipping CAs: buffer too short" ) ); + break; + } + + *p++ = (unsigned char)( dn_size >> 8 ); + *p++ = (unsigned char)( dn_size ); + memcpy( p, crt->subject_raw.p, dn_size ); + p += dn_size; + + MBEDTLS_SSL_DEBUG_BUF( 3, "requested DN", p - dn_size, dn_size ); + + total_dn_size += 2 + dn_size; + crt = crt->next; + } + + ssl->out_msglen = p - buf; + ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; + ssl->out_msg[0] = MBEDTLS_SSL_HS_CERTIFICATE_REQUEST; + ssl->out_msg[4 + ct_len + sa_len] = (unsigned char)( total_dn_size >> 8 ); + ssl->out_msg[5 + ct_len + sa_len] = (unsigned char)( total_dn_size ); + + ret = mbedtls_ssl_write_record( ssl ); + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write certificate request" ) ); + + return( ret ); +} +#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) +static int ssl_get_ecdh_params_from_cert( mbedtls_ssl_context *ssl ) +{ + int ret; + + if( ! mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_ECKEY ) ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "server key not ECDH capable" ) ); + return( MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH ); + } + + if( ( ret = mbedtls_ecdh_get_params( &ssl->handshake->ecdh_ctx, + mbedtls_pk_ec( *mbedtls_ssl_own_key( ssl ) ), + MBEDTLS_ECDH_OURS ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ecdh_get_params" ), ret ); + return( ret ); + } + + return( 0 ); +} +#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || + MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ + +static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl ) +{ + int ret; + size_t n = 0; + const mbedtls_ssl_ciphersuite_t *ciphersuite_info = + ssl->transform_negotiate->ciphersuite_info; + +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) + unsigned char *p = ssl->out_msg + 4; + unsigned char *dig_signed = p; + size_t dig_signed_len = 0, len; + ((void) dig_signed); + ((void) dig_signed_len); + ((void) len); +#endif + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server key exchange" ) ); + +#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write server key exchange" ) ); + ssl->state++; + return( 0 ); + } +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA ) + { + ssl_get_ecdh_params_from_cert( ssl ); + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write server key exchange" ) ); + ssl->state++; + return( 0 ); + } +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) + { + size_t jlen; + const unsigned char *end = ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN; + + ret = mbedtls_ecjpake_write_round_two( &ssl->handshake->ecjpake_ctx, + p, end - p, &jlen, ssl->conf->f_rng, ssl->conf->p_rng ); + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_write_round_two", ret ); + return( ret ); + } + + p += jlen; + n += jlen; + } +#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ) + { + /* Note: we don't support identity hints, until someone asks + * for them. */ + *(p++) = 0x00; + *(p++) = 0x00; + + n += 2; + } +#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED || + MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ) + { + if( ssl->conf->dhm_P.p == NULL || ssl->conf->dhm_G.p == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "no DH parameters set" ) ); + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + } + + /* + * Ephemeral DH parameters: + * + * struct { + * opaque dh_p<1..2^16-1>; + * opaque dh_g<1..2^16-1>; + * opaque dh_Ys<1..2^16-1>; + * } ServerDHParams; + */ + if( ( ret = mbedtls_mpi_copy( &ssl->handshake->dhm_ctx.P, &ssl->conf->dhm_P ) ) != 0 || + ( ret = mbedtls_mpi_copy( &ssl->handshake->dhm_ctx.G, &ssl->conf->dhm_G ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_mpi_copy", ret ); + return( ret ); + } + + if( ( ret = mbedtls_dhm_make_params( &ssl->handshake->dhm_ctx, + (int) mbedtls_mpi_size( &ssl->handshake->dhm_ctx.P ), + p, &len, ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_make_params", ret ); + return( ret ); + } + + dig_signed = p; + dig_signed_len = len; + + p += len; + n += len; + + MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: X ", &ssl->handshake->dhm_ctx.X ); + MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: P ", &ssl->handshake->dhm_ctx.P ); + MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: G ", &ssl->handshake->dhm_ctx.G ); + MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: GX", &ssl->handshake->dhm_ctx.GX ); + } +#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED || + MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ) + { + /* + * Ephemeral ECDH parameters: + * + * struct { + * ECParameters curve_params; + * ECPoint public; + * } ServerECDHParams; + */ + const mbedtls_ecp_curve_info **curve = NULL; + const mbedtls_ecp_group_id *gid; + + /* Match our preference list against the offered curves */ + for( gid = ssl->conf->curve_list; *gid != MBEDTLS_ECP_DP_NONE; gid++ ) + for( curve = ssl->handshake->curves; *curve != NULL; curve++ ) + if( (*curve)->grp_id == *gid ) + goto curve_matching_done; + +curve_matching_done: + if( curve == NULL || *curve == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "no matching curve for ECDHE" ) ); + return( MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN ); + } + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "ECDHE curve: %s", (*curve)->name ) ); + + if( ( ret = mbedtls_ecp_group_load( &ssl->handshake->ecdh_ctx.grp, + (*curve)->grp_id ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecp_group_load", ret ); + return( ret ); + } + + if( ( ret = mbedtls_ecdh_make_params( &ssl->handshake->ecdh_ctx, &len, + p, MBEDTLS_SSL_MAX_CONTENT_LEN - n, + ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_make_params", ret ); + return( ret ); + } + + dig_signed = p; + dig_signed_len = len; + + p += len; + n += len; + + MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Q ", &ssl->handshake->ecdh_ctx.Q ); + } +#endif /* MBEDTLS_KEY_EXCHANGE__SOME__ECDHE_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ) + { + size_t signature_len = 0; + unsigned int hashlen = 0; + unsigned char hash[64]; + mbedtls_md_type_t md_alg = MBEDTLS_MD_NONE; + + /* + * Choose hash algorithm. NONE means MD5 + SHA1 here. + */ +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) + if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) + { + md_alg = mbedtls_ssl_md_alg_from_hash( ssl->handshake->sig_alg ); + + if( md_alg == MBEDTLS_MD_NONE ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + } + else +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ +#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ + defined(MBEDTLS_SSL_PROTO_TLS1_1) + if( ciphersuite_info->key_exchange == + MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA ) + { + md_alg = MBEDTLS_MD_SHA1; + } + else +#endif + { + md_alg = MBEDTLS_MD_NONE; + } + + /* + * Compute the hash to be signed + */ +#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ + defined(MBEDTLS_SSL_PROTO_TLS1_1) + if( md_alg == MBEDTLS_MD_NONE ) + { + mbedtls_md5_context mbedtls_md5; + mbedtls_sha1_context mbedtls_sha1; + + mbedtls_md5_init( &mbedtls_md5 ); + mbedtls_sha1_init( &mbedtls_sha1 ); + + /* + * digitally-signed struct { + * opaque md5_hash[16]; + * opaque sha_hash[20]; + * }; + * + * md5_hash + * MD5(ClientHello.random + ServerHello.random + * + ServerParams); + * sha_hash + * SHA(ClientHello.random + ServerHello.random + * + ServerParams); + */ + mbedtls_md5_starts( &mbedtls_md5 ); + mbedtls_md5_update( &mbedtls_md5, ssl->handshake->randbytes, 64 ); + mbedtls_md5_update( &mbedtls_md5, dig_signed, dig_signed_len ); + mbedtls_md5_finish( &mbedtls_md5, hash ); + + mbedtls_sha1_starts( &mbedtls_sha1 ); + mbedtls_sha1_update( &mbedtls_sha1, ssl->handshake->randbytes, 64 ); + mbedtls_sha1_update( &mbedtls_sha1, dig_signed, dig_signed_len ); + mbedtls_sha1_finish( &mbedtls_sha1, hash + 16 ); + + hashlen = 36; + + mbedtls_md5_free( &mbedtls_md5 ); + mbedtls_sha1_free( &mbedtls_sha1 ); + } + else +#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || \ + MBEDTLS_SSL_PROTO_TLS1_1 */ +#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ + defined(MBEDTLS_SSL_PROTO_TLS1_2) + if( md_alg != MBEDTLS_MD_NONE ) + { + mbedtls_md_context_t ctx; + const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( md_alg ); + + mbedtls_md_init( &ctx ); + + /* Info from md_alg will be used instead */ + hashlen = 0; + + /* + * digitally-signed struct { + * opaque client_random[32]; + * opaque server_random[32]; + * ServerDHParams params; + * }; + */ + if( ( ret = mbedtls_md_setup( &ctx, md_info, 0 ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_setup", ret ); + return( ret ); + } + + mbedtls_md_starts( &ctx ); + mbedtls_md_update( &ctx, ssl->handshake->randbytes, 64 ); + mbedtls_md_update( &ctx, dig_signed, dig_signed_len ); + mbedtls_md_finish( &ctx, hash ); + mbedtls_md_free( &ctx ); + } + else +#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \ + MBEDTLS_SSL_PROTO_TLS1_2 */ + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + + MBEDTLS_SSL_DEBUG_BUF( 3, "parameters hash", hash, hashlen != 0 ? hashlen : + (unsigned int) ( mbedtls_md_get_size( mbedtls_md_info_from_type( md_alg ) ) ) ); + + /* + * Make the signature + */ + if( mbedtls_ssl_own_key( ssl ) == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no private key" ) ); + return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED ); + } + +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) + if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) + { + *(p++) = ssl->handshake->sig_alg; + *(p++) = mbedtls_ssl_sig_from_pk( mbedtls_ssl_own_key( ssl ) ); + + n += 2; + } +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ + + if( ( ret = mbedtls_pk_sign( mbedtls_ssl_own_key( ssl ), md_alg, hash, hashlen, + p + 2 , &signature_len, + ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_sign", ret ); + return( ret ); + } + + *(p++) = (unsigned char)( signature_len >> 8 ); + *(p++) = (unsigned char)( signature_len ); + n += 2; + + MBEDTLS_SSL_DEBUG_BUF( 3, "my signature", p, signature_len ); + + n += signature_len; + } +#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || + MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || + MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ + + ssl->out_msglen = 4 + n; + ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; + ssl->out_msg[0] = MBEDTLS_SSL_HS_SERVER_KEY_EXCHANGE; + + ssl->state++; + + if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); + return( ret ); + } + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server key exchange" ) ); + + return( 0 ); +} + +static int ssl_write_server_hello_done( mbedtls_ssl_context *ssl ) +{ + int ret; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write server hello done" ) ); + + ssl->out_msglen = 4; + ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; + ssl->out_msg[0] = MBEDTLS_SSL_HS_SERVER_HELLO_DONE; + + ssl->state++; + +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + mbedtls_ssl_send_flight_completed( ssl ); +#endif + + if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); + return( ret ); + } + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write server hello done" ) ); + + return( 0 ); +} + +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) +static int ssl_parse_client_dh_public( mbedtls_ssl_context *ssl, unsigned char **p, + const unsigned char *end ) +{ + int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; + size_t n; + + /* + * Receive G^Y mod P, premaster = (G^Y)^X mod P + */ + if( *p + 2 > end ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); + } + + n = ( (*p)[0] << 8 ) | (*p)[1]; + *p += 2; + + if( *p + n > end ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); + } + + if( ( ret = mbedtls_dhm_read_public( &ssl->handshake->dhm_ctx, *p, n ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_read_public", ret ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP ); + } + + *p += n; + + MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: GY", &ssl->handshake->dhm_ctx.GY ); + + return( ret ); +} +#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED || + MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) +static int ssl_parse_encrypted_pms( mbedtls_ssl_context *ssl, + const unsigned char *p, + const unsigned char *end, + size_t pms_offset ) +{ + int ret; + size_t len = mbedtls_pk_get_len( mbedtls_ssl_own_key( ssl ) ); + unsigned char *pms = ssl->handshake->premaster + pms_offset; + unsigned char ver[2]; + unsigned char fake_pms[48], peer_pms[48]; + unsigned char mask; + size_t i, peer_pmslen; + unsigned int diff; + + if( ! mbedtls_pk_can_do( mbedtls_ssl_own_key( ssl ), MBEDTLS_PK_RSA ) ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no RSA private key" ) ); + return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED ); + } + + /* + * Decrypt the premaster using own private RSA key + */ +#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ + defined(MBEDTLS_SSL_PROTO_TLS1_2) + if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_0 ) + { + if( *p++ != ( ( len >> 8 ) & 0xFF ) || + *p++ != ( ( len ) & 0xFF ) ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); + } + } +#endif + + if( p + len != end ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); + } + + mbedtls_ssl_write_version( ssl->handshake->max_major_ver, + ssl->handshake->max_minor_ver, + ssl->conf->transport, ver ); + + /* + * Protection against Bleichenbacher's attack: invalid PKCS#1 v1.5 padding + * must not cause the connection to end immediately; instead, send a + * bad_record_mac later in the handshake. + * Also, avoid data-dependant branches here to protect against + * timing-based variants. + */ + ret = ssl->conf->f_rng( ssl->conf->p_rng, fake_pms, sizeof( fake_pms ) ); + if( ret != 0 ) + return( ret ); + + ret = mbedtls_pk_decrypt( mbedtls_ssl_own_key( ssl ), p, len, + peer_pms, &peer_pmslen, + sizeof( peer_pms ), + ssl->conf->f_rng, ssl->conf->p_rng ); + + diff = (unsigned int) ret; + diff |= peer_pmslen ^ 48; + diff |= peer_pms[0] ^ ver[0]; + diff |= peer_pms[1] ^ ver[1]; + +#if defined(MBEDTLS_SSL_DEBUG_ALL) + if( diff != 0 ) + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); +#endif + + if( sizeof( ssl->handshake->premaster ) < pms_offset || + sizeof( ssl->handshake->premaster ) - pms_offset < 48 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + ssl->handshake->pmslen = 48; + + /* mask = diff ? 0xff : 0x00 using bit operations to avoid branches */ + /* MSVC has a warning about unary minus on unsigned, but this is + * well-defined and precisely what we want to do here */ +#if defined(_MSC_VER) +#pragma warning( push ) +#pragma warning( disable : 4146 ) +#endif + mask = - ( ( diff | - diff ) >> ( sizeof( unsigned int ) * 8 - 1 ) ); +#if defined(_MSC_VER) +#pragma warning( pop ) +#endif + + for( i = 0; i < ssl->handshake->pmslen; i++ ) + pms[i] = ( mask & fake_pms[i] ) | ( (~mask) & peer_pms[i] ); + + return( 0 ); +} +#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED || + MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) +static int ssl_parse_client_psk_identity( mbedtls_ssl_context *ssl, unsigned char **p, + const unsigned char *end ) +{ + int ret = 0; + size_t n; + + if( ssl->conf->f_psk == NULL && + ( ssl->conf->psk == NULL || ssl->conf->psk_identity == NULL || + ssl->conf->psk_identity_len == 0 || ssl->conf->psk_len == 0 ) ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no pre-shared key" ) ); + return( MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED ); + } + + /* + * Receive client pre-shared key identity name + */ + if( *p + 2 > end ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); + } + + n = ( (*p)[0] << 8 ) | (*p)[1]; + *p += 2; + + if( n < 1 || n > 65535 || *p + n > end ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); + } + + if( ssl->conf->f_psk != NULL ) + { + if( ssl->conf->f_psk( ssl->conf->p_psk, ssl, *p, n ) != 0 ) + ret = MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY; + } + else + { + /* Identity is not a big secret since clients send it in the clear, + * but treat it carefully anyway, just in case */ + if( n != ssl->conf->psk_identity_len || + mbedtls_ssl_safer_memcmp( ssl->conf->psk_identity, *p, n ) != 0 ) + { + ret = MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY; + } + } + + if( ret == MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY ) + { + MBEDTLS_SSL_DEBUG_BUF( 3, "Unknown PSK identity", *p, n ); + if( ( ret = mbedtls_ssl_send_alert_message( ssl, + MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_UNKNOWN_PSK_IDENTITY ) ) != 0 ) + { + return( ret ); + } + + return( MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY ); + } + + *p += n; + + return( 0 ); +} +#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ + +static int ssl_parse_client_key_exchange( mbedtls_ssl_context *ssl ) +{ + int ret; + const mbedtls_ssl_ciphersuite_t *ciphersuite_info; + unsigned char *p, *end; + + ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse client key exchange" ) ); + + if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); + return( ret ); + } + + p = ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ); + end = ssl->in_msg + ssl->in_hslen; + + if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); + } + + if( ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_KEY_EXCHANGE ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); + } + +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_RSA ) + { + if( ( ret = ssl_parse_client_dh_public( ssl, &p, end ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_client_dh_public" ), ret ); + return( ret ); + } + + if( p != end ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); + } + + if( ( ret = mbedtls_dhm_calc_secret( &ssl->handshake->dhm_ctx, + ssl->handshake->premaster, + MBEDTLS_PREMASTER_SIZE, + &ssl->handshake->pmslen, + ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS ); + } + + MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K ); + } + else +#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */ +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_RSA || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_RSA || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA ) + { + if( ( ret = mbedtls_ecdh_read_public( &ssl->handshake->ecdh_ctx, + p, end - p) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_read_public", ret ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP ); + } + + MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Qp ", &ssl->handshake->ecdh_ctx.Qp ); + + if( ( ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx, + &ssl->handshake->pmslen, + ssl->handshake->premaster, + MBEDTLS_MPI_MAX_SIZE, + ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS ); + } + + MBEDTLS_SSL_DEBUG_MPI( 3, "ECDH: z ", &ssl->handshake->ecdh_ctx.z ); + } + else +#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED || + MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED || + MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED || + MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ +#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK ) + { + if( ( ret = ssl_parse_client_psk_identity( ssl, &p, end ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_client_psk_identity" ), ret ); + return( ret ); + } + + if( p != end ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); + } + + if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl, + ciphersuite_info->key_exchange ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret ); + return( ret ); + } + } + else +#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */ +#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ) + { + if( ( ret = ssl_parse_client_psk_identity( ssl, &p, end ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_client_psk_identity" ), ret ); + return( ret ); + } + + if( ( ret = ssl_parse_encrypted_pms( ssl, p, end, 2 ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_encrypted_pms" ), ret ); + return( ret ); + } + + if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl, + ciphersuite_info->key_exchange ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret ); + return( ret ); + } + } + else +#endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK ) + { + if( ( ret = ssl_parse_client_psk_identity( ssl, &p, end ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_client_psk_identity" ), ret ); + return( ret ); + } + if( ( ret = ssl_parse_client_dh_public( ssl, &p, end ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_client_dh_public" ), ret ); + return( ret ); + } + + if( p != end ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad client key exchange" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE ); + } + + if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl, + ciphersuite_info->key_exchange ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret ); + return( ret ); + } + } + else +#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ) + { + if( ( ret = ssl_parse_client_psk_identity( ssl, &p, end ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_client_psk_identity" ), ret ); + return( ret ); + } + + if( ( ret = mbedtls_ecdh_read_public( &ssl->handshake->ecdh_ctx, + p, end - p ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_read_public", ret ); + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP ); + } + + MBEDTLS_SSL_DEBUG_ECP( 3, "ECDH: Qp ", &ssl->handshake->ecdh_ctx.Qp ); + + if( ( ret = mbedtls_ssl_psk_derive_premaster( ssl, + ciphersuite_info->key_exchange ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_psk_derive_premaster", ret ); + return( ret ); + } + } + else +#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ +#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA ) + { + if( ( ret = ssl_parse_encrypted_pms( ssl, p, end, 0 ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, ( "ssl_parse_parse_encrypted_pms_secret" ), ret ); + return( ret ); + } + } + else +#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ +#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) + { + ret = mbedtls_ecjpake_read_round_two( &ssl->handshake->ecjpake_ctx, + p, end - p ); + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_read_round_two", ret ); + return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE ); + } + + ret = mbedtls_ecjpake_derive_secret( &ssl->handshake->ecjpake_ctx, + ssl->handshake->premaster, 32, &ssl->handshake->pmslen, + ssl->conf->f_rng, ssl->conf->p_rng ); + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecjpake_derive_secret", ret ); + return( ret ); + } + } + else +#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + + if( ( ret = mbedtls_ssl_derive_keys( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_derive_keys", ret ); + return( ret ); + } + + ssl->state++; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse client key exchange" ) ); + + return( 0 ); +} + +#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED)&& \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) +static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) +{ + const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate verify" ) ); + + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) ); + ssl->state++; + return( 0 ); + } + + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); +} +#else +static int ssl_parse_certificate_verify( mbedtls_ssl_context *ssl ) +{ + int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; + size_t i, sig_len; + unsigned char hash[48]; + unsigned char *hash_start = hash; + size_t hashlen; +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) + mbedtls_pk_type_t pk_alg; +#endif + mbedtls_md_type_t md_alg; + const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate verify" ) ); + + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE || + ssl->session_negotiate->peer_cert == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate verify" ) ); + ssl->state++; + return( 0 ); + } + + /* Read the message without adding it to the checksum */ + do { + + if( ( ret = mbedtls_ssl_read_record_layer( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ssl_read_record_layer" ), ret ); + return( ret ); + } + + ret = mbedtls_ssl_handle_message_type( ssl ); + + } while( MBEDTLS_ERR_SSL_NON_FATAL == ret ); + + if( 0 != ret ) + { + MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ssl_handle_message_type" ), ret ); + return( ret ); + } + + ssl->state++; + + /* Process the message contents */ + if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE || + ssl->in_msg[0] != MBEDTLS_SSL_HS_CERTIFICATE_VERIFY ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); + } + + i = mbedtls_ssl_hs_hdr_len( ssl ); + + /* + * struct { + * SignatureAndHashAlgorithm algorithm; -- TLS 1.2 only + * opaque signature<0..2^16-1>; + * } DigitallySigned; + */ +#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ + defined(MBEDTLS_SSL_PROTO_TLS1_1) + if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 ) + { + md_alg = MBEDTLS_MD_NONE; + hashlen = 36; + + /* For ECDSA, use SHA-1, not MD-5 + SHA-1 */ + if( mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk, + MBEDTLS_PK_ECDSA ) ) + { + hash_start += 16; + hashlen -= 16; + md_alg = MBEDTLS_MD_SHA1; + } + } + else +#endif /* MBEDTLS_SSL_PROTO_SSL3 || MBEDTLS_SSL_PROTO_TLS1 || + MBEDTLS_SSL_PROTO_TLS1_1 */ +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) + if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) + { + if( i + 2 > ssl->in_hslen ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); + } + + /* + * Hash + */ + md_alg = mbedtls_ssl_md_alg_from_hash( ssl->in_msg[i] ); + + if( md_alg == MBEDTLS_MD_NONE || mbedtls_ssl_set_calc_verify_md( ssl, ssl->in_msg[i] ) ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "peer not adhering to requested sig_alg" + " for verify message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); + } + +#if !defined(MBEDTLS_MD_SHA1) + if( MBEDTLS_MD_SHA1 == md_alg ) + hash_start += 16; +#endif + + /* Info from md_alg will be used instead */ + hashlen = 0; + + i++; + + /* + * Signature + */ + if( ( pk_alg = mbedtls_ssl_pk_alg_from_sig( ssl->in_msg[i] ) ) + == MBEDTLS_PK_NONE ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "peer not adhering to requested sig_alg" + " for verify message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); + } + + /* + * Check the certificate's key type matches the signature alg + */ + if( ! mbedtls_pk_can_do( &ssl->session_negotiate->peer_cert->pk, pk_alg ) ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "sig_alg doesn't match cert key" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); + } + + i++; + } + else +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + + if( i + 2 > ssl->in_hslen ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); + } + + sig_len = ( ssl->in_msg[i] << 8 ) | ssl->in_msg[i+1]; + i += 2; + + if( i + sig_len != ssl->in_hslen ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate verify message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY ); + } + + /* Calculate hash and verify signature */ + ssl->handshake->calc_verify( ssl, hash ); + + if( ( ret = mbedtls_pk_verify( &ssl->session_negotiate->peer_cert->pk, + md_alg, hash_start, hashlen, + ssl->in_msg + i, sig_len ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_pk_verify", ret ); + return( ret ); + } + + mbedtls_ssl_update_handshake_status( ssl ); + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate verify" ) ); + + return( ret ); +} +#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED && + !MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ + +#if defined(MBEDTLS_SSL_SESSION_TICKETS) +static int ssl_write_new_session_ticket( mbedtls_ssl_context *ssl ) +{ + int ret; + size_t tlen; + uint32_t lifetime; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write new session ticket" ) ); + + ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; + ssl->out_msg[0] = MBEDTLS_SSL_HS_NEW_SESSION_TICKET; + + /* + * struct { + * uint32 ticket_lifetime_hint; + * opaque ticket<0..2^16-1>; + * } NewSessionTicket; + * + * 4 . 7 ticket_lifetime_hint (0 = unspecified) + * 8 . 9 ticket_len (n) + * 10 . 9+n ticket content + */ + + if( ( ret = ssl->conf->f_ticket_write( ssl->conf->p_ticket, + ssl->session_negotiate, + ssl->out_msg + 10, + ssl->out_msg + MBEDTLS_SSL_MAX_CONTENT_LEN, + &tlen, &lifetime ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_ticket_write", ret ); + tlen = 0; + } + + ssl->out_msg[4] = ( lifetime >> 24 ) & 0xFF; + ssl->out_msg[5] = ( lifetime >> 16 ) & 0xFF; + ssl->out_msg[6] = ( lifetime >> 8 ) & 0xFF; + ssl->out_msg[7] = ( lifetime ) & 0xFF; + + ssl->out_msg[8] = (unsigned char)( ( tlen >> 8 ) & 0xFF ); + ssl->out_msg[9] = (unsigned char)( ( tlen ) & 0xFF ); + + ssl->out_msglen = 10 + tlen; + + /* + * Morally equivalent to updating ssl->state, but NewSessionTicket and + * ChangeCipherSpec share the same state. + */ + ssl->handshake->new_session_ticket = 0; + + if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); + return( ret ); + } + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write new session ticket" ) ); + + return( 0 ); +} +#endif /* MBEDTLS_SSL_SESSION_TICKETS */ + +/* + * SSL handshake -- server side -- single step + */ +int mbedtls_ssl_handshake_server_step( mbedtls_ssl_context *ssl ) +{ + int ret = 0; + + if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER || ssl->handshake == NULL ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "server state: %d", ssl->state ) ); + + if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) + return( ret ); + +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && + ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING ) + { + if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 ) + return( ret ); + } +#endif + + switch( ssl->state ) + { + case MBEDTLS_SSL_HELLO_REQUEST: + ssl->state = MBEDTLS_SSL_CLIENT_HELLO; + break; + + /* + * <== ClientHello + */ + case MBEDTLS_SSL_CLIENT_HELLO: + ret = ssl_parse_client_hello( ssl ); + break; + +#if defined(MBEDTLS_SSL_PROTO_DTLS) + case MBEDTLS_SSL_SERVER_HELLO_VERIFY_REQUEST_SENT: + return( MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED ); +#endif + + /* + * ==> ServerHello + * Certificate + * ( ServerKeyExchange ) + * ( CertificateRequest ) + * ServerHelloDone + */ + case MBEDTLS_SSL_SERVER_HELLO: + ret = ssl_write_server_hello( ssl ); + break; + + case MBEDTLS_SSL_SERVER_CERTIFICATE: + ret = mbedtls_ssl_write_certificate( ssl ); + break; + + case MBEDTLS_SSL_SERVER_KEY_EXCHANGE: + ret = ssl_write_server_key_exchange( ssl ); + break; + + case MBEDTLS_SSL_CERTIFICATE_REQUEST: + ret = ssl_write_certificate_request( ssl ); + break; + + case MBEDTLS_SSL_SERVER_HELLO_DONE: + ret = ssl_write_server_hello_done( ssl ); + break; + + /* + * <== ( Certificate/Alert ) + * ClientKeyExchange + * ( CertificateVerify ) + * ChangeCipherSpec + * Finished + */ + case MBEDTLS_SSL_CLIENT_CERTIFICATE: + ret = mbedtls_ssl_parse_certificate( ssl ); + break; + + case MBEDTLS_SSL_CLIENT_KEY_EXCHANGE: + ret = ssl_parse_client_key_exchange( ssl ); + break; + + case MBEDTLS_SSL_CERTIFICATE_VERIFY: + ret = ssl_parse_certificate_verify( ssl ); + break; + + case MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC: + ret = mbedtls_ssl_parse_change_cipher_spec( ssl ); + break; + + case MBEDTLS_SSL_CLIENT_FINISHED: + ret = mbedtls_ssl_parse_finished( ssl ); + break; + + /* + * ==> ( NewSessionTicket ) + * ChangeCipherSpec + * Finished + */ + case MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC: +#if defined(MBEDTLS_SSL_SESSION_TICKETS) + if( ssl->handshake->new_session_ticket != 0 ) + ret = ssl_write_new_session_ticket( ssl ); + else +#endif + ret = mbedtls_ssl_write_change_cipher_spec( ssl ); + break; + + case MBEDTLS_SSL_SERVER_FINISHED: + ret = mbedtls_ssl_write_finished( ssl ); + break; + + case MBEDTLS_SSL_FLUSH_BUFFERS: + MBEDTLS_SSL_DEBUG_MSG( 2, ( "handshake: done" ) ); + ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP; + break; + + case MBEDTLS_SSL_HANDSHAKE_WRAPUP: + mbedtls_ssl_handshake_wrapup( ssl ); + break; + + default: + MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid state %d", ssl->state ) ); + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + } + + return( ret ); +} +#endif /* MBEDTLS_SSL_SRV_C */ diff --git a/security/mbedtls/src/ssl_ticket.c b/security/mbedtls/src/ssl_ticket.c new file mode 100644 index 0000000000..4d9116d214 --- /dev/null +++ b/security/mbedtls/src/ssl_ticket.c @@ -0,0 +1,489 @@ +/* + * TLS server tickets callbacks implementation + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_SSL_TICKET_C) + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_calloc calloc +#define mbedtls_free free +#endif + +#include "mbedtls/ssl_ticket.h" + +#include + +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +/* + * Initialze context + */ +void mbedtls_ssl_ticket_init( mbedtls_ssl_ticket_context *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_ssl_ticket_context ) ); + +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_init( &ctx->mutex ); +#endif +} + +#define MAX_KEY_BYTES 32 /* 256 bits */ + +/* + * Generate/update a key + */ +static int ssl_ticket_gen_key( mbedtls_ssl_ticket_context *ctx, + unsigned char index ) +{ + int ret; + unsigned char buf[MAX_KEY_BYTES]; + mbedtls_ssl_ticket_key *key = ctx->keys + index; + +#if defined(MBEDTLS_HAVE_TIME) + key->generation_time = (uint32_t) mbedtls_time( NULL ); +#endif + + if( ( ret = ctx->f_rng( ctx->p_rng, key->name, sizeof( key->name ) ) ) != 0 ) + return( ret ); + + if( ( ret = ctx->f_rng( ctx->p_rng, buf, sizeof( buf ) ) ) != 0 ) + return( ret ); + + /* With GCM and CCM, same context can encrypt & decrypt */ + ret = mbedtls_cipher_setkey( &key->ctx, buf, + mbedtls_cipher_get_key_bitlen( &key->ctx ), + MBEDTLS_ENCRYPT ); + + mbedtls_zeroize( buf, sizeof( buf ) ); + + return( ret ); +} + +/* + * Rotate/generate keys if necessary + */ +static int ssl_ticket_update_keys( mbedtls_ssl_ticket_context *ctx ) +{ +#if !defined(MBEDTLS_HAVE_TIME) + ((void) ctx); +#else + if( ctx->ticket_lifetime != 0 ) + { + uint32_t current_time = (uint32_t) mbedtls_time( NULL ); + uint32_t key_time = ctx->keys[ctx->active].generation_time; + + if( current_time > key_time && + current_time - key_time < ctx->ticket_lifetime ) + { + return( 0 ); + } + + ctx->active = 1 - ctx->active; + + return( ssl_ticket_gen_key( ctx, ctx->active ) ); + } + else +#endif /* MBEDTLS_HAVE_TIME */ + return( 0 ); +} + +/* + * Setup context for actual use + */ +int mbedtls_ssl_ticket_setup( mbedtls_ssl_ticket_context *ctx, + int (*f_rng)(void *, unsigned char *, size_t), void *p_rng, + mbedtls_cipher_type_t cipher, + uint32_t lifetime ) +{ + int ret; + const mbedtls_cipher_info_t *cipher_info; + + ctx->f_rng = f_rng; + ctx->p_rng = p_rng; + + ctx->ticket_lifetime = lifetime; + + cipher_info = mbedtls_cipher_info_from_type( cipher); + if( cipher_info == NULL ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + if( cipher_info->mode != MBEDTLS_MODE_GCM && + cipher_info->mode != MBEDTLS_MODE_CCM ) + { + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + } + + if( cipher_info->key_bitlen > 8 * MAX_KEY_BYTES ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + if( ( ret = mbedtls_cipher_setup( &ctx->keys[0].ctx, cipher_info ) ) != 0 || + ( ret = mbedtls_cipher_setup( &ctx->keys[1].ctx, cipher_info ) ) != 0 ) + { + return( ret ); + } + + if( ( ret = ssl_ticket_gen_key( ctx, 0 ) ) != 0 || + ( ret = ssl_ticket_gen_key( ctx, 1 ) ) != 0 ) + { + return( ret ); + } + + return( 0 ); +} + +/* + * Serialize a session in the following format: + * 0 . n-1 session structure, n = sizeof(mbedtls_ssl_session) + * n . n+2 peer_cert length = m (0 if no certificate) + * n+3 . n+2+m peer cert ASN.1 + */ +static int ssl_save_session( const mbedtls_ssl_session *session, + unsigned char *buf, size_t buf_len, + size_t *olen ) +{ + unsigned char *p = buf; + size_t left = buf_len; +#if defined(MBEDTLS_X509_CRT_PARSE_C) + size_t cert_len; +#endif /* MBEDTLS_X509_CRT_PARSE_C */ + + if( left < sizeof( mbedtls_ssl_session ) ) + return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); + + memcpy( p, session, sizeof( mbedtls_ssl_session ) ); + p += sizeof( mbedtls_ssl_session ); + left -= sizeof( mbedtls_ssl_session ); + +#if defined(MBEDTLS_X509_CRT_PARSE_C) + if( session->peer_cert == NULL ) + cert_len = 0; + else + cert_len = session->peer_cert->raw.len; + + if( left < 3 + cert_len ) + return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); + + *p++ = (unsigned char)( cert_len >> 16 & 0xFF ); + *p++ = (unsigned char)( cert_len >> 8 & 0xFF ); + *p++ = (unsigned char)( cert_len & 0xFF ); + + if( session->peer_cert != NULL ) + memcpy( p, session->peer_cert->raw.p, cert_len ); + + p += cert_len; +#endif /* MBEDTLS_X509_CRT_PARSE_C */ + + *olen = p - buf; + + return( 0 ); +} + +/* + * Unserialise session, see ssl_save_session() + */ +static int ssl_load_session( mbedtls_ssl_session *session, + const unsigned char *buf, size_t len ) +{ + const unsigned char *p = buf; + const unsigned char * const end = buf + len; +#if defined(MBEDTLS_X509_CRT_PARSE_C) + size_t cert_len; +#endif /* MBEDTLS_X509_CRT_PARSE_C */ + + if( p + sizeof( mbedtls_ssl_session ) > end ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + memcpy( session, p, sizeof( mbedtls_ssl_session ) ); + p += sizeof( mbedtls_ssl_session ); + +#if defined(MBEDTLS_X509_CRT_PARSE_C) + if( p + 3 > end ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + cert_len = ( p[0] << 16 ) | ( p[1] << 8 ) | p[2]; + p += 3; + + if( cert_len == 0 ) + { + session->peer_cert = NULL; + } + else + { + int ret; + + if( p + cert_len > end ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + session->peer_cert = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) ); + + if( session->peer_cert == NULL ) + return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); + + mbedtls_x509_crt_init( session->peer_cert ); + + if( ( ret = mbedtls_x509_crt_parse_der( session->peer_cert, + p, cert_len ) ) != 0 ) + { + mbedtls_x509_crt_free( session->peer_cert ); + mbedtls_free( session->peer_cert ); + session->peer_cert = NULL; + return( ret ); + } + + p += cert_len; + } +#endif /* MBEDTLS_X509_CRT_PARSE_C */ + + if( p != end ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + return( 0 ); +} + +/* + * Create session ticket, with the following structure: + * + * struct { + * opaque key_name[4]; + * opaque iv[12]; + * opaque encrypted_state<0..2^16-1>; + * opaque tag[16]; + * } ticket; + * + * The key_name, iv, and length of encrypted_state are the additional + * authenticated data. + */ +int mbedtls_ssl_ticket_write( void *p_ticket, + const mbedtls_ssl_session *session, + unsigned char *start, + const unsigned char *end, + size_t *tlen, + uint32_t *ticket_lifetime ) +{ + int ret; + mbedtls_ssl_ticket_context *ctx = p_ticket; + mbedtls_ssl_ticket_key *key; + unsigned char *key_name = start; + unsigned char *iv = start + 4; + unsigned char *state_len_bytes = iv + 12; + unsigned char *state = state_len_bytes + 2; + unsigned char *tag; + size_t clear_len, ciph_len; + + *tlen = 0; + + if( ctx == NULL || ctx->f_rng == NULL ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + /* We need at least 4 bytes for key_name, 12 for IV, 2 for len 16 for tag, + * in addition to session itself, that will be checked when writing it. */ + if( end - start < 4 + 12 + 2 + 16 ) + return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); + +#if defined(MBEDTLS_THREADING_C) + if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) + return( ret ); +#endif + + if( ( ret = ssl_ticket_update_keys( ctx ) ) != 0 ) + goto cleanup; + + key = &ctx->keys[ctx->active]; + + *ticket_lifetime = ctx->ticket_lifetime; + + memcpy( key_name, key->name, 4 ); + + if( ( ret = ctx->f_rng( ctx->p_rng, iv, 12 ) ) != 0 ) + goto cleanup; + + /* Dump session state */ + if( ( ret = ssl_save_session( session, + state, end - state, &clear_len ) ) != 0 || + (unsigned long) clear_len > 65535 ) + { + goto cleanup; + } + state_len_bytes[0] = ( clear_len >> 8 ) & 0xff; + state_len_bytes[1] = ( clear_len ) & 0xff; + + /* Encrypt and authenticate */ + tag = state + clear_len; + if( ( ret = mbedtls_cipher_auth_encrypt( &key->ctx, + iv, 12, key_name, 4 + 12 + 2, + state, clear_len, state, &ciph_len, tag, 16 ) ) != 0 ) + { + goto cleanup; + } + if( ciph_len != clear_len ) + { + ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR; + goto cleanup; + } + + *tlen = 4 + 12 + 2 + 16 + ciph_len; + +cleanup: +#if defined(MBEDTLS_THREADING_C) + if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) + return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); +#endif + + return( ret ); +} + +/* + * Select key based on name + */ +static mbedtls_ssl_ticket_key *ssl_ticket_select_key( + mbedtls_ssl_ticket_context *ctx, + const unsigned char name[4] ) +{ + unsigned char i; + + for( i = 0; i < sizeof( ctx->keys ) / sizeof( *ctx->keys ); i++ ) + if( memcmp( name, ctx->keys[i].name, 4 ) == 0 ) + return( &ctx->keys[i] ); + + return( NULL ); +} + +/* + * Load session ticket (see mbedtls_ssl_ticket_write for structure) + */ +int mbedtls_ssl_ticket_parse( void *p_ticket, + mbedtls_ssl_session *session, + unsigned char *buf, + size_t len ) +{ + int ret; + mbedtls_ssl_ticket_context *ctx = p_ticket; + mbedtls_ssl_ticket_key *key; + unsigned char *key_name = buf; + unsigned char *iv = buf + 4; + unsigned char *enc_len_p = iv + 12; + unsigned char *ticket = enc_len_p + 2; + unsigned char *tag; + size_t enc_len, clear_len; + + if( ctx == NULL || ctx->f_rng == NULL ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + /* See mbedtls_ssl_ticket_write() */ + if( len < 4 + 12 + 2 + 16 ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + +#if defined(MBEDTLS_THREADING_C) + if( ( ret = mbedtls_mutex_lock( &ctx->mutex ) ) != 0 ) + return( ret ); +#endif + + if( ( ret = ssl_ticket_update_keys( ctx ) ) != 0 ) + goto cleanup; + + enc_len = ( enc_len_p[0] << 8 ) | enc_len_p[1]; + tag = ticket + enc_len; + + if( len != 4 + 12 + 2 + enc_len + 16 ) + { + ret = MBEDTLS_ERR_SSL_BAD_INPUT_DATA; + goto cleanup; + } + + /* Select key */ + if( ( key = ssl_ticket_select_key( ctx, key_name ) ) == NULL ) + { + /* We can't know for sure but this is a likely option unless we're + * under attack - this is only informative anyway */ + ret = MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED; + goto cleanup; + } + + /* Decrypt and authenticate */ + if( ( ret = mbedtls_cipher_auth_decrypt( &key->ctx, iv, 12, + key_name, 4 + 12 + 2, ticket, enc_len, + ticket, &clear_len, tag, 16 ) ) != 0 ) + { + if( ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED ) + ret = MBEDTLS_ERR_SSL_INVALID_MAC; + + goto cleanup; + } + if( clear_len != enc_len ) + { + ret = MBEDTLS_ERR_SSL_INTERNAL_ERROR; + goto cleanup; + } + + /* Actually load session */ + if( ( ret = ssl_load_session( session, ticket, clear_len ) ) != 0 ) + goto cleanup; + +#if defined(MBEDTLS_HAVE_TIME) + { + /* Check for expiration */ + mbedtls_time_t current_time = mbedtls_time( NULL ); + + if( current_time < session->start || + (uint32_t)( current_time - session->start ) > ctx->ticket_lifetime ) + { + ret = MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED; + goto cleanup; + } + } +#endif + +cleanup: +#if defined(MBEDTLS_THREADING_C) + if( mbedtls_mutex_unlock( &ctx->mutex ) != 0 ) + return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); +#endif + + return( ret ); +} + +/* + * Free context + */ +void mbedtls_ssl_ticket_free( mbedtls_ssl_ticket_context *ctx ) +{ + mbedtls_cipher_free( &ctx->keys[0].ctx ); + mbedtls_cipher_free( &ctx->keys[1].ctx ); + +#if defined(MBEDTLS_THREADING_C) + mbedtls_mutex_free( &ctx->mutex ); +#endif + + mbedtls_zeroize( ctx, sizeof( mbedtls_ssl_ticket_context ) ); +} + +#endif /* MBEDTLS_SSL_TICKET_C */ diff --git a/security/mbedtls/src/ssl_tls.c b/security/mbedtls/src/ssl_tls.c new file mode 100644 index 0000000000..b661ec6d3d --- /dev/null +++ b/security/mbedtls/src/ssl_tls.c @@ -0,0 +1,7701 @@ +/* + * SSLv3/TLSv1 shared functions + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +/* + * The SSL 3.0 specification was drafted by Netscape in 1996, + * and became an IETF standard in 1999. + * + * http://wp.netscape.com/eng/ssl3/ + * http://www.ietf.org/rfc/rfc2246.txt + * http://www.ietf.org/rfc/rfc4346.txt + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_SSL_TLS_C) + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_calloc calloc +#define mbedtls_free free +#endif + +#include "mbedtls/debug.h" +#include "mbedtls/ssl.h" +#include "mbedtls/ssl_internal.h" + +#include + +#if defined(MBEDTLS_X509_CRT_PARSE_C) +#include "mbedtls/oid.h" +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +/* Length of the "epoch" field in the record header */ +static inline size_t ssl_ep_len( const mbedtls_ssl_context *ssl ) +{ +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + return( 2 ); +#else + ((void) ssl); +#endif + return( 0 ); +} + +/* + * Start a timer. + * Passing millisecs = 0 cancels a running timer. + */ +static void ssl_set_timer( mbedtls_ssl_context *ssl, uint32_t millisecs ) +{ + if( ssl->f_set_timer == NULL ) + return; + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "set_timer to %d ms", (int) millisecs ) ); + ssl->f_set_timer( ssl->p_timer, millisecs / 4, millisecs ); +} + +/* + * Return -1 is timer is expired, 0 if it isn't. + */ +static int ssl_check_timer( mbedtls_ssl_context *ssl ) +{ + if( ssl->f_get_timer == NULL ) + return( 0 ); + + if( ssl->f_get_timer( ssl->p_timer ) == 2 ) + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "timer expired" ) ); + return( -1 ); + } + + return( 0 ); +} + +#if defined(MBEDTLS_SSL_PROTO_DTLS) +/* + * Double the retransmit timeout value, within the allowed range, + * returning -1 if the maximum value has already been reached. + */ +static int ssl_double_retransmit_timeout( mbedtls_ssl_context *ssl ) +{ + uint32_t new_timeout; + + if( ssl->handshake->retransmit_timeout >= ssl->conf->hs_timeout_max ) + return( -1 ); + + new_timeout = 2 * ssl->handshake->retransmit_timeout; + + /* Avoid arithmetic overflow and range overflow */ + if( new_timeout < ssl->handshake->retransmit_timeout || + new_timeout > ssl->conf->hs_timeout_max ) + { + new_timeout = ssl->conf->hs_timeout_max; + } + + ssl->handshake->retransmit_timeout = new_timeout; + MBEDTLS_SSL_DEBUG_MSG( 3, ( "update timeout value to %d millisecs", + ssl->handshake->retransmit_timeout ) ); + + return( 0 ); +} + +static void ssl_reset_retransmit_timeout( mbedtls_ssl_context *ssl ) +{ + ssl->handshake->retransmit_timeout = ssl->conf->hs_timeout_min; + MBEDTLS_SSL_DEBUG_MSG( 3, ( "update timeout value to %d millisecs", + ssl->handshake->retransmit_timeout ) ); +} +#endif /* MBEDTLS_SSL_PROTO_DTLS */ + +#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) +/* + * Convert max_fragment_length codes to length. + * RFC 6066 says: + * enum{ + * 2^9(1), 2^10(2), 2^11(3), 2^12(4), (255) + * } MaxFragmentLength; + * and we add 0 -> extension unused + */ +static unsigned int mfl_code_to_length[MBEDTLS_SSL_MAX_FRAG_LEN_INVALID] = +{ + MBEDTLS_SSL_MAX_CONTENT_LEN, /* MBEDTLS_SSL_MAX_FRAG_LEN_NONE */ + 512, /* MBEDTLS_SSL_MAX_FRAG_LEN_512 */ + 1024, /* MBEDTLS_SSL_MAX_FRAG_LEN_1024 */ + 2048, /* MBEDTLS_SSL_MAX_FRAG_LEN_2048 */ + 4096, /* MBEDTLS_SSL_MAX_FRAG_LEN_4096 */ +}; +#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ + +#if defined(MBEDTLS_SSL_CLI_C) +static int ssl_session_copy( mbedtls_ssl_session *dst, const mbedtls_ssl_session *src ) +{ + mbedtls_ssl_session_free( dst ); + memcpy( dst, src, sizeof( mbedtls_ssl_session ) ); + +#if defined(MBEDTLS_X509_CRT_PARSE_C) + if( src->peer_cert != NULL ) + { + int ret; + + dst->peer_cert = mbedtls_calloc( 1, sizeof(mbedtls_x509_crt) ); + if( dst->peer_cert == NULL ) + return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); + + mbedtls_x509_crt_init( dst->peer_cert ); + + if( ( ret = mbedtls_x509_crt_parse_der( dst->peer_cert, src->peer_cert->raw.p, + src->peer_cert->raw.len ) ) != 0 ) + { + mbedtls_free( dst->peer_cert ); + dst->peer_cert = NULL; + return( ret ); + } + } +#endif /* MBEDTLS_X509_CRT_PARSE_C */ + +#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C) + if( src->ticket != NULL ) + { + dst->ticket = mbedtls_calloc( 1, src->ticket_len ); + if( dst->ticket == NULL ) + return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); + + memcpy( dst->ticket, src->ticket, src->ticket_len ); + } +#endif /* MBEDTLS_SSL_SESSION_TICKETS && MBEDTLS_SSL_CLI_C */ + + return( 0 ); +} +#endif /* MBEDTLS_SSL_CLI_C */ + +#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) +int (*mbedtls_ssl_hw_record_init)( mbedtls_ssl_context *ssl, + const unsigned char *key_enc, const unsigned char *key_dec, + size_t keylen, + const unsigned char *iv_enc, const unsigned char *iv_dec, + size_t ivlen, + const unsigned char *mac_enc, const unsigned char *mac_dec, + size_t maclen ) = NULL; +int (*mbedtls_ssl_hw_record_activate)( mbedtls_ssl_context *ssl, int direction) = NULL; +int (*mbedtls_ssl_hw_record_reset)( mbedtls_ssl_context *ssl ) = NULL; +int (*mbedtls_ssl_hw_record_write)( mbedtls_ssl_context *ssl ) = NULL; +int (*mbedtls_ssl_hw_record_read)( mbedtls_ssl_context *ssl ) = NULL; +int (*mbedtls_ssl_hw_record_finish)( mbedtls_ssl_context *ssl ) = NULL; +#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ + +/* + * Key material generation + */ +#if defined(MBEDTLS_SSL_PROTO_SSL3) +static int ssl3_prf( const unsigned char *secret, size_t slen, + const char *label, + const unsigned char *random, size_t rlen, + unsigned char *dstbuf, size_t dlen ) +{ + size_t i; + mbedtls_md5_context md5; + mbedtls_sha1_context sha1; + unsigned char padding[16]; + unsigned char sha1sum[20]; + ((void)label); + + mbedtls_md5_init( &md5 ); + mbedtls_sha1_init( &sha1 ); + + /* + * SSLv3: + * block = + * MD5( secret + SHA1( 'A' + secret + random ) ) + + * MD5( secret + SHA1( 'BB' + secret + random ) ) + + * MD5( secret + SHA1( 'CCC' + secret + random ) ) + + * ... + */ + for( i = 0; i < dlen / 16; i++ ) + { + memset( padding, (unsigned char) ('A' + i), 1 + i ); + + mbedtls_sha1_starts( &sha1 ); + mbedtls_sha1_update( &sha1, padding, 1 + i ); + mbedtls_sha1_update( &sha1, secret, slen ); + mbedtls_sha1_update( &sha1, random, rlen ); + mbedtls_sha1_finish( &sha1, sha1sum ); + + mbedtls_md5_starts( &md5 ); + mbedtls_md5_update( &md5, secret, slen ); + mbedtls_md5_update( &md5, sha1sum, 20 ); + mbedtls_md5_finish( &md5, dstbuf + i * 16 ); + } + + mbedtls_md5_free( &md5 ); + mbedtls_sha1_free( &sha1 ); + + mbedtls_zeroize( padding, sizeof( padding ) ); + mbedtls_zeroize( sha1sum, sizeof( sha1sum ) ); + + return( 0 ); +} +#endif /* MBEDTLS_SSL_PROTO_SSL3 */ + +#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) +static int tls1_prf( const unsigned char *secret, size_t slen, + const char *label, + const unsigned char *random, size_t rlen, + unsigned char *dstbuf, size_t dlen ) +{ + size_t nb, hs; + size_t i, j, k; + const unsigned char *S1, *S2; + unsigned char tmp[128]; + unsigned char h_i[20]; + const mbedtls_md_info_t *md_info; + mbedtls_md_context_t md_ctx; + int ret; + + mbedtls_md_init( &md_ctx ); + + if( sizeof( tmp ) < 20 + strlen( label ) + rlen ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + hs = ( slen + 1 ) / 2; + S1 = secret; + S2 = secret + slen - hs; + + nb = strlen( label ); + memcpy( tmp + 20, label, nb ); + memcpy( tmp + 20 + nb, random, rlen ); + nb += rlen; + + /* + * First compute P_md5(secret,label+random)[0..dlen] + */ + if( ( md_info = mbedtls_md_info_from_type( MBEDTLS_MD_MD5 ) ) == NULL ) + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + + if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 ) + return( ret ); + + mbedtls_md_hmac_starts( &md_ctx, S1, hs ); + mbedtls_md_hmac_update( &md_ctx, tmp + 20, nb ); + mbedtls_md_hmac_finish( &md_ctx, 4 + tmp ); + + for( i = 0; i < dlen; i += 16 ) + { + mbedtls_md_hmac_reset ( &md_ctx ); + mbedtls_md_hmac_update( &md_ctx, 4 + tmp, 16 + nb ); + mbedtls_md_hmac_finish( &md_ctx, h_i ); + + mbedtls_md_hmac_reset ( &md_ctx ); + mbedtls_md_hmac_update( &md_ctx, 4 + tmp, 16 ); + mbedtls_md_hmac_finish( &md_ctx, 4 + tmp ); + + k = ( i + 16 > dlen ) ? dlen % 16 : 16; + + for( j = 0; j < k; j++ ) + dstbuf[i + j] = h_i[j]; + } + + mbedtls_md_free( &md_ctx ); + + /* + * XOR out with P_sha1(secret,label+random)[0..dlen] + */ + if( ( md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 ) ) == NULL ) + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + + if( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 ) + return( ret ); + + mbedtls_md_hmac_starts( &md_ctx, S2, hs ); + mbedtls_md_hmac_update( &md_ctx, tmp + 20, nb ); + mbedtls_md_hmac_finish( &md_ctx, tmp ); + + for( i = 0; i < dlen; i += 20 ) + { + mbedtls_md_hmac_reset ( &md_ctx ); + mbedtls_md_hmac_update( &md_ctx, tmp, 20 + nb ); + mbedtls_md_hmac_finish( &md_ctx, h_i ); + + mbedtls_md_hmac_reset ( &md_ctx ); + mbedtls_md_hmac_update( &md_ctx, tmp, 20 ); + mbedtls_md_hmac_finish( &md_ctx, tmp ); + + k = ( i + 20 > dlen ) ? dlen % 20 : 20; + + for( j = 0; j < k; j++ ) + dstbuf[i + j] = (unsigned char)( dstbuf[i + j] ^ h_i[j] ); + } + + mbedtls_md_free( &md_ctx ); + + mbedtls_zeroize( tmp, sizeof( tmp ) ); + mbedtls_zeroize( h_i, sizeof( h_i ) ); + + return( 0 ); +} +#endif /* MBEDTLS_SSL_PROTO_TLS1) || MBEDTLS_SSL_PROTO_TLS1_1 */ + +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) +static int tls_prf_generic( mbedtls_md_type_t md_type, + const unsigned char *secret, size_t slen, + const char *label, + const unsigned char *random, size_t rlen, + unsigned char *dstbuf, size_t dlen ) +{ + size_t nb; + size_t i, j, k, md_len; + unsigned char tmp[128]; + unsigned char h_i[MBEDTLS_MD_MAX_SIZE]; + const mbedtls_md_info_t *md_info; + mbedtls_md_context_t md_ctx; + int ret; + + mbedtls_md_init( &md_ctx ); + + if( ( md_info = mbedtls_md_info_from_type( md_type ) ) == NULL ) + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + + md_len = mbedtls_md_get_size( md_info ); + + if( sizeof( tmp ) < md_len + strlen( label ) + rlen ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + nb = strlen( label ); + memcpy( tmp + md_len, label, nb ); + memcpy( tmp + md_len + nb, random, rlen ); + nb += rlen; + + /* + * Compute P_(secret, label + random)[0..dlen] + */ + if ( ( ret = mbedtls_md_setup( &md_ctx, md_info, 1 ) ) != 0 ) + return( ret ); + + mbedtls_md_hmac_starts( &md_ctx, secret, slen ); + mbedtls_md_hmac_update( &md_ctx, tmp + md_len, nb ); + mbedtls_md_hmac_finish( &md_ctx, tmp ); + + for( i = 0; i < dlen; i += md_len ) + { + mbedtls_md_hmac_reset ( &md_ctx ); + mbedtls_md_hmac_update( &md_ctx, tmp, md_len + nb ); + mbedtls_md_hmac_finish( &md_ctx, h_i ); + + mbedtls_md_hmac_reset ( &md_ctx ); + mbedtls_md_hmac_update( &md_ctx, tmp, md_len ); + mbedtls_md_hmac_finish( &md_ctx, tmp ); + + k = ( i + md_len > dlen ) ? dlen % md_len : md_len; + + for( j = 0; j < k; j++ ) + dstbuf[i + j] = h_i[j]; + } + + mbedtls_md_free( &md_ctx ); + + mbedtls_zeroize( tmp, sizeof( tmp ) ); + mbedtls_zeroize( h_i, sizeof( h_i ) ); + + return( 0 ); +} + +#if defined(MBEDTLS_SHA256_C) +static int tls_prf_sha256( const unsigned char *secret, size_t slen, + const char *label, + const unsigned char *random, size_t rlen, + unsigned char *dstbuf, size_t dlen ) +{ + return( tls_prf_generic( MBEDTLS_MD_SHA256, secret, slen, + label, random, rlen, dstbuf, dlen ) ); +} +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_SHA512_C) +static int tls_prf_sha384( const unsigned char *secret, size_t slen, + const char *label, + const unsigned char *random, size_t rlen, + unsigned char *dstbuf, size_t dlen ) +{ + return( tls_prf_generic( MBEDTLS_MD_SHA384, secret, slen, + label, random, rlen, dstbuf, dlen ) ); +} +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ + +static void ssl_update_checksum_start( mbedtls_ssl_context *, const unsigned char *, size_t ); + +#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ + defined(MBEDTLS_SSL_PROTO_TLS1_1) +static void ssl_update_checksum_md5sha1( mbedtls_ssl_context *, const unsigned char *, size_t ); +#endif + +#if defined(MBEDTLS_SSL_PROTO_SSL3) +static void ssl_calc_verify_ssl( mbedtls_ssl_context *, unsigned char * ); +static void ssl_calc_finished_ssl( mbedtls_ssl_context *, unsigned char *, int ); +#endif + +#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) +static void ssl_calc_verify_tls( mbedtls_ssl_context *, unsigned char * ); +static void ssl_calc_finished_tls( mbedtls_ssl_context *, unsigned char *, int ); +#endif + +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) +#if defined(MBEDTLS_SHA256_C) +static void ssl_update_checksum_sha256( mbedtls_ssl_context *, const unsigned char *, size_t ); +static void ssl_calc_verify_tls_sha256( mbedtls_ssl_context *,unsigned char * ); +static void ssl_calc_finished_tls_sha256( mbedtls_ssl_context *,unsigned char *, int ); +#endif + +#if defined(MBEDTLS_SHA512_C) +static void ssl_update_checksum_sha384( mbedtls_ssl_context *, const unsigned char *, size_t ); +static void ssl_calc_verify_tls_sha384( mbedtls_ssl_context *, unsigned char * ); +static void ssl_calc_finished_tls_sha384( mbedtls_ssl_context *, unsigned char *, int ); +#endif +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ + +int mbedtls_ssl_derive_keys( mbedtls_ssl_context *ssl ) +{ + int ret = 0; + unsigned char tmp[64]; + unsigned char keyblk[256]; + unsigned char *key1; + unsigned char *key2; + unsigned char *mac_enc; + unsigned char *mac_dec; + size_t iv_copy_len; + const mbedtls_cipher_info_t *cipher_info; + const mbedtls_md_info_t *md_info; + + mbedtls_ssl_session *session = ssl->session_negotiate; + mbedtls_ssl_transform *transform = ssl->transform_negotiate; + mbedtls_ssl_handshake_params *handshake = ssl->handshake; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> derive keys" ) ); + + cipher_info = mbedtls_cipher_info_from_type( transform->ciphersuite_info->cipher ); + if( cipher_info == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "cipher info for %d not found", + transform->ciphersuite_info->cipher ) ); + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + } + + md_info = mbedtls_md_info_from_type( transform->ciphersuite_info->mac ); + if( md_info == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "mbedtls_md info for %d not found", + transform->ciphersuite_info->mac ) ); + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + } + + /* + * Set appropriate PRF function and other SSL / TLS / TLS1.2 functions + */ +#if defined(MBEDTLS_SSL_PROTO_SSL3) + if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) + { + handshake->tls_prf = ssl3_prf; + handshake->calc_verify = ssl_calc_verify_ssl; + handshake->calc_finished = ssl_calc_finished_ssl; + } + else +#endif +#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) + if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 ) + { + handshake->tls_prf = tls1_prf; + handshake->calc_verify = ssl_calc_verify_tls; + handshake->calc_finished = ssl_calc_finished_tls; + } + else +#endif +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) +#if defined(MBEDTLS_SHA512_C) + if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 && + transform->ciphersuite_info->mac == MBEDTLS_MD_SHA384 ) + { + handshake->tls_prf = tls_prf_sha384; + handshake->calc_verify = ssl_calc_verify_tls_sha384; + handshake->calc_finished = ssl_calc_finished_tls_sha384; + } + else +#endif +#if defined(MBEDTLS_SHA256_C) + if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) + { + handshake->tls_prf = tls_prf_sha256; + handshake->calc_verify = ssl_calc_verify_tls_sha256; + handshake->calc_finished = ssl_calc_finished_tls_sha256; + } + else +#endif +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + + /* + * SSLv3: + * master = + * MD5( premaster + SHA1( 'A' + premaster + randbytes ) ) + + * MD5( premaster + SHA1( 'BB' + premaster + randbytes ) ) + + * MD5( premaster + SHA1( 'CCC' + premaster + randbytes ) ) + * + * TLSv1+: + * master = PRF( premaster, "master secret", randbytes )[0..47] + */ + if( handshake->resume == 0 ) + { + MBEDTLS_SSL_DEBUG_BUF( 3, "premaster secret", handshake->premaster, + handshake->pmslen ); + +#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) + if( ssl->handshake->extended_ms == MBEDTLS_SSL_EXTENDED_MS_ENABLED ) + { + unsigned char session_hash[48]; + size_t hash_len; + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "using extended master secret" ) ); + + ssl->handshake->calc_verify( ssl, session_hash ); + +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) + if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) + { +#if defined(MBEDTLS_SHA512_C) + if( ssl->transform_negotiate->ciphersuite_info->mac == + MBEDTLS_MD_SHA384 ) + { + hash_len = 48; + } + else +#endif + hash_len = 32; + } + else +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ + hash_len = 36; + + MBEDTLS_SSL_DEBUG_BUF( 3, "session hash", session_hash, hash_len ); + + ret = handshake->tls_prf( handshake->premaster, handshake->pmslen, + "extended master secret", + session_hash, hash_len, + session->master, 48 ); + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "prf", ret ); + return( ret ); + } + + } + else +#endif + ret = handshake->tls_prf( handshake->premaster, handshake->pmslen, + "master secret", + handshake->randbytes, 64, + session->master, 48 ); + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "prf", ret ); + return( ret ); + } + + mbedtls_zeroize( handshake->premaster, sizeof(handshake->premaster) ); + } + else + MBEDTLS_SSL_DEBUG_MSG( 3, ( "no premaster (session resumed)" ) ); + + /* + * Swap the client and server random values. + */ + memcpy( tmp, handshake->randbytes, 64 ); + memcpy( handshake->randbytes, tmp + 32, 32 ); + memcpy( handshake->randbytes + 32, tmp, 32 ); + mbedtls_zeroize( tmp, sizeof( tmp ) ); + + /* + * SSLv3: + * key block = + * MD5( master + SHA1( 'A' + master + randbytes ) ) + + * MD5( master + SHA1( 'BB' + master + randbytes ) ) + + * MD5( master + SHA1( 'CCC' + master + randbytes ) ) + + * MD5( master + SHA1( 'DDDD' + master + randbytes ) ) + + * ... + * + * TLSv1: + * key block = PRF( master, "key expansion", randbytes ) + */ + ret = handshake->tls_prf( session->master, 48, "key expansion", + handshake->randbytes, 64, keyblk, 256 ); + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "prf", ret ); + return( ret ); + } + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "ciphersuite = %s", + mbedtls_ssl_get_ciphersuite_name( session->ciphersuite ) ) ); + MBEDTLS_SSL_DEBUG_BUF( 3, "master secret", session->master, 48 ); + MBEDTLS_SSL_DEBUG_BUF( 4, "random bytes", handshake->randbytes, 64 ); + MBEDTLS_SSL_DEBUG_BUF( 4, "key block", keyblk, 256 ); + + mbedtls_zeroize( handshake->randbytes, sizeof( handshake->randbytes ) ); + + /* + * Determine the appropriate key, IV and MAC length. + */ + + transform->keylen = cipher_info->key_bitlen / 8; + + if( cipher_info->mode == MBEDTLS_MODE_GCM || + cipher_info->mode == MBEDTLS_MODE_CCM ) + { + transform->maclen = 0; + + transform->ivlen = 12; + transform->fixed_ivlen = 4; + + /* Minimum length is expicit IV + tag */ + transform->minlen = transform->ivlen - transform->fixed_ivlen + + ( transform->ciphersuite_info->flags & + MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16 ); + } + else + { + /* Initialize HMAC contexts */ + if( ( ret = mbedtls_md_setup( &transform->md_ctx_enc, md_info, 1 ) ) != 0 || + ( ret = mbedtls_md_setup( &transform->md_ctx_dec, md_info, 1 ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_md_setup", ret ); + return( ret ); + } + + /* Get MAC length */ + transform->maclen = mbedtls_md_get_size( md_info ); + +#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) + /* + * If HMAC is to be truncated, we shall keep the leftmost bytes, + * (rfc 6066 page 13 or rfc 2104 section 4), + * so we only need to adjust the length here. + */ + if( session->trunc_hmac == MBEDTLS_SSL_TRUNC_HMAC_ENABLED ) + transform->maclen = MBEDTLS_SSL_TRUNCATED_HMAC_LEN; +#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ + + /* IV length */ + transform->ivlen = cipher_info->iv_size; + + /* Minimum length */ + if( cipher_info->mode == MBEDTLS_MODE_STREAM ) + transform->minlen = transform->maclen; + else + { + /* + * GenericBlockCipher: + * 1. if EtM is in use: one block plus MAC + * otherwise: * first multiple of blocklen greater than maclen + * 2. IV except for SSL3 and TLS 1.0 + */ +#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) + if( session->encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED ) + { + transform->minlen = transform->maclen + + cipher_info->block_size; + } + else +#endif + { + transform->minlen = transform->maclen + + cipher_info->block_size + - transform->maclen % cipher_info->block_size; + } + +#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) + if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 || + ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_1 ) + ; /* No need to adjust minlen */ + else +#endif +#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2) + if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_2 || + ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_3 ) + { + transform->minlen += transform->ivlen; + } + else +#endif + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + } + } + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "keylen: %d, minlen: %d, ivlen: %d, maclen: %d", + transform->keylen, transform->minlen, transform->ivlen, + transform->maclen ) ); + + /* + * Finally setup the cipher contexts, IVs and MAC secrets. + */ +#if defined(MBEDTLS_SSL_CLI_C) + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) + { + key1 = keyblk + transform->maclen * 2; + key2 = keyblk + transform->maclen * 2 + transform->keylen; + + mac_enc = keyblk; + mac_dec = keyblk + transform->maclen; + + /* + * This is not used in TLS v1.1. + */ + iv_copy_len = ( transform->fixed_ivlen ) ? + transform->fixed_ivlen : transform->ivlen; + memcpy( transform->iv_enc, key2 + transform->keylen, iv_copy_len ); + memcpy( transform->iv_dec, key2 + transform->keylen + iv_copy_len, + iv_copy_len ); + } + else +#endif /* MBEDTLS_SSL_CLI_C */ +#if defined(MBEDTLS_SSL_SRV_C) + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) + { + key1 = keyblk + transform->maclen * 2 + transform->keylen; + key2 = keyblk + transform->maclen * 2; + + mac_enc = keyblk + transform->maclen; + mac_dec = keyblk; + + /* + * This is not used in TLS v1.1. + */ + iv_copy_len = ( transform->fixed_ivlen ) ? + transform->fixed_ivlen : transform->ivlen; + memcpy( transform->iv_dec, key1 + transform->keylen, iv_copy_len ); + memcpy( transform->iv_enc, key1 + transform->keylen + iv_copy_len, + iv_copy_len ); + } + else +#endif /* MBEDTLS_SSL_SRV_C */ + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + +#if defined(MBEDTLS_SSL_PROTO_SSL3) + if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) + { + if( transform->maclen > sizeof transform->mac_enc ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + + memcpy( transform->mac_enc, mac_enc, transform->maclen ); + memcpy( transform->mac_dec, mac_dec, transform->maclen ); + } + else +#endif /* MBEDTLS_SSL_PROTO_SSL3 */ +#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ + defined(MBEDTLS_SSL_PROTO_TLS1_2) + if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 ) + { + mbedtls_md_hmac_starts( &transform->md_ctx_enc, mac_enc, transform->maclen ); + mbedtls_md_hmac_starts( &transform->md_ctx_dec, mac_dec, transform->maclen ); + } + else +#endif + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + +#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) + if( mbedtls_ssl_hw_record_init != NULL ) + { + int ret = 0; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_init()" ) ); + + if( ( ret = mbedtls_ssl_hw_record_init( ssl, key1, key2, transform->keylen, + transform->iv_enc, transform->iv_dec, + iv_copy_len, + mac_enc, mac_dec, + transform->maclen ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_init", ret ); + return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); + } + } +#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ + +#if defined(MBEDTLS_SSL_EXPORT_KEYS) + if( ssl->conf->f_export_keys != NULL ) + { + ssl->conf->f_export_keys( ssl->conf->p_export_keys, + session->master, keyblk, + transform->maclen, transform->keylen, + iv_copy_len ); + } +#endif + + if( ( ret = mbedtls_cipher_setup( &transform->cipher_ctx_enc, + cipher_info ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup", ret ); + return( ret ); + } + + if( ( ret = mbedtls_cipher_setup( &transform->cipher_ctx_dec, + cipher_info ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setup", ret ); + return( ret ); + } + + if( ( ret = mbedtls_cipher_setkey( &transform->cipher_ctx_enc, key1, + cipher_info->key_bitlen, + MBEDTLS_ENCRYPT ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setkey", ret ); + return( ret ); + } + + if( ( ret = mbedtls_cipher_setkey( &transform->cipher_ctx_dec, key2, + cipher_info->key_bitlen, + MBEDTLS_DECRYPT ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_setkey", ret ); + return( ret ); + } + +#if defined(MBEDTLS_CIPHER_MODE_CBC) + if( cipher_info->mode == MBEDTLS_MODE_CBC ) + { + if( ( ret = mbedtls_cipher_set_padding_mode( &transform->cipher_ctx_enc, + MBEDTLS_PADDING_NONE ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_set_padding_mode", ret ); + return( ret ); + } + + if( ( ret = mbedtls_cipher_set_padding_mode( &transform->cipher_ctx_dec, + MBEDTLS_PADDING_NONE ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_set_padding_mode", ret ); + return( ret ); + } + } +#endif /* MBEDTLS_CIPHER_MODE_CBC */ + + mbedtls_zeroize( keyblk, sizeof( keyblk ) ); + +#if defined(MBEDTLS_ZLIB_SUPPORT) + // Initialize compression + // + if( session->compression == MBEDTLS_SSL_COMPRESS_DEFLATE ) + { + if( ssl->compress_buf == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "Allocating compression buffer" ) ); + ssl->compress_buf = mbedtls_calloc( 1, MBEDTLS_SSL_BUFFER_LEN ); + if( ssl->compress_buf == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", + MBEDTLS_SSL_BUFFER_LEN ) ); + return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); + } + } + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "Initializing zlib states" ) ); + + memset( &transform->ctx_deflate, 0, sizeof( transform->ctx_deflate ) ); + memset( &transform->ctx_inflate, 0, sizeof( transform->ctx_inflate ) ); + + if( deflateInit( &transform->ctx_deflate, + Z_DEFAULT_COMPRESSION ) != Z_OK || + inflateInit( &transform->ctx_inflate ) != Z_OK ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "Failed to initialize compression" ) ); + return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED ); + } + } +#endif /* MBEDTLS_ZLIB_SUPPORT */ + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= derive keys" ) ); + + return( 0 ); +} + +#if defined(MBEDTLS_SSL_PROTO_SSL3) +void ssl_calc_verify_ssl( mbedtls_ssl_context *ssl, unsigned char hash[36] ) +{ + mbedtls_md5_context md5; + mbedtls_sha1_context sha1; + unsigned char pad_1[48]; + unsigned char pad_2[48]; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify ssl" ) ); + + mbedtls_md5_init( &md5 ); + mbedtls_sha1_init( &sha1 ); + + mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 ); + mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 ); + + memset( pad_1, 0x36, 48 ); + memset( pad_2, 0x5C, 48 ); + + mbedtls_md5_update( &md5, ssl->session_negotiate->master, 48 ); + mbedtls_md5_update( &md5, pad_1, 48 ); + mbedtls_md5_finish( &md5, hash ); + + mbedtls_md5_starts( &md5 ); + mbedtls_md5_update( &md5, ssl->session_negotiate->master, 48 ); + mbedtls_md5_update( &md5, pad_2, 48 ); + mbedtls_md5_update( &md5, hash, 16 ); + mbedtls_md5_finish( &md5, hash ); + + mbedtls_sha1_update( &sha1, ssl->session_negotiate->master, 48 ); + mbedtls_sha1_update( &sha1, pad_1, 40 ); + mbedtls_sha1_finish( &sha1, hash + 16 ); + + mbedtls_sha1_starts( &sha1 ); + mbedtls_sha1_update( &sha1, ssl->session_negotiate->master, 48 ); + mbedtls_sha1_update( &sha1, pad_2, 40 ); + mbedtls_sha1_update( &sha1, hash + 16, 20 ); + mbedtls_sha1_finish( &sha1, hash + 16 ); + + MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 36 ); + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) ); + + mbedtls_md5_free( &md5 ); + mbedtls_sha1_free( &sha1 ); + + return; +} +#endif /* MBEDTLS_SSL_PROTO_SSL3 */ + +#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) +void ssl_calc_verify_tls( mbedtls_ssl_context *ssl, unsigned char hash[36] ) +{ + mbedtls_md5_context md5; + mbedtls_sha1_context sha1; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify tls" ) ); + + mbedtls_md5_init( &md5 ); + mbedtls_sha1_init( &sha1 ); + + mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 ); + mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 ); + + mbedtls_md5_finish( &md5, hash ); + mbedtls_sha1_finish( &sha1, hash + 16 ); + + MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 36 ); + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) ); + + mbedtls_md5_free( &md5 ); + mbedtls_sha1_free( &sha1 ); + + return; +} +#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */ + +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) +#if defined(MBEDTLS_SHA256_C) +void ssl_calc_verify_tls_sha256( mbedtls_ssl_context *ssl, unsigned char hash[32] ) +{ + mbedtls_sha256_context sha256; + + mbedtls_sha256_init( &sha256 ); + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify sha256" ) ); + + mbedtls_sha256_clone( &sha256, &ssl->handshake->fin_sha256 ); + mbedtls_sha256_finish( &sha256, hash ); + + MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 32 ); + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) ); + + mbedtls_sha256_free( &sha256 ); + + return; +} +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_SHA512_C) +void ssl_calc_verify_tls_sha384( mbedtls_ssl_context *ssl, unsigned char hash[48] ) +{ + mbedtls_sha512_context sha512; + + mbedtls_sha512_init( &sha512 ); + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc verify sha384" ) ); + + mbedtls_sha512_clone( &sha512, &ssl->handshake->fin_sha512 ); + mbedtls_sha512_finish( &sha512, hash ); + + MBEDTLS_SSL_DEBUG_BUF( 3, "calculated verify result", hash, 48 ); + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc verify" ) ); + + mbedtls_sha512_free( &sha512 ); + + return; +} +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ + +#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) +int mbedtls_ssl_psk_derive_premaster( mbedtls_ssl_context *ssl, mbedtls_key_exchange_type_t key_ex ) +{ + unsigned char *p = ssl->handshake->premaster; + unsigned char *end = p + sizeof( ssl->handshake->premaster ); + const unsigned char *psk = ssl->conf->psk; + size_t psk_len = ssl->conf->psk_len; + + /* If the psk callback was called, use its result */ + if( ssl->handshake->psk != NULL ) + { + psk = ssl->handshake->psk; + psk_len = ssl->handshake->psk_len; + } + + /* + * PMS = struct { + * opaque other_secret<0..2^16-1>; + * opaque psk<0..2^16-1>; + * }; + * with "other_secret" depending on the particular key exchange + */ +#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) + if( key_ex == MBEDTLS_KEY_EXCHANGE_PSK ) + { + if( end - p < 2 ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + *(p++) = (unsigned char)( psk_len >> 8 ); + *(p++) = (unsigned char)( psk_len ); + + if( end < p || (size_t)( end - p ) < psk_len ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + memset( p, 0, psk_len ); + p += psk_len; + } + else +#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */ +#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) + if( key_ex == MBEDTLS_KEY_EXCHANGE_RSA_PSK ) + { + /* + * other_secret already set by the ClientKeyExchange message, + * and is 48 bytes long + */ + *p++ = 0; + *p++ = 48; + p += 48; + } + else +#endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) + if( key_ex == MBEDTLS_KEY_EXCHANGE_DHE_PSK ) + { + int ret; + size_t len; + + /* Write length only when we know the actual value */ + if( ( ret = mbedtls_dhm_calc_secret( &ssl->handshake->dhm_ctx, + p + 2, end - ( p + 2 ), &len, + ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_dhm_calc_secret", ret ); + return( ret ); + } + *(p++) = (unsigned char)( len >> 8 ); + *(p++) = (unsigned char)( len ); + p += len; + + MBEDTLS_SSL_DEBUG_MPI( 3, "DHM: K ", &ssl->handshake->dhm_ctx.K ); + } + else +#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) + if( key_ex == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK ) + { + int ret; + size_t zlen; + + if( ( ret = mbedtls_ecdh_calc_secret( &ssl->handshake->ecdh_ctx, &zlen, + p + 2, end - ( p + 2 ), + ssl->conf->f_rng, ssl->conf->p_rng ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ecdh_calc_secret", ret ); + return( ret ); + } + + *(p++) = (unsigned char)( zlen >> 8 ); + *(p++) = (unsigned char)( zlen ); + p += zlen; + + MBEDTLS_SSL_DEBUG_MPI( 3, "ECDH: z", &ssl->handshake->ecdh_ctx.z ); + } + else +#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + + /* opaque psk<0..2^16-1>; */ + if( end - p < 2 ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + *(p++) = (unsigned char)( psk_len >> 8 ); + *(p++) = (unsigned char)( psk_len ); + + if( end < p || (size_t)( end - p ) < psk_len ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + memcpy( p, psk, psk_len ); + p += psk_len; + + ssl->handshake->pmslen = p - ssl->handshake->premaster; + + return( 0 ); +} +#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ + +#if defined(MBEDTLS_SSL_PROTO_SSL3) +/* + * SSLv3.0 MAC functions + */ +static void ssl_mac( mbedtls_md_context_t *md_ctx, unsigned char *secret, + unsigned char *buf, size_t len, + unsigned char *ctr, int type ) +{ + unsigned char header[11]; + unsigned char padding[48]; + int padlen; + int md_size = mbedtls_md_get_size( md_ctx->md_info ); + int md_type = mbedtls_md_get_type( md_ctx->md_info ); + + /* Only MD5 and SHA-1 supported */ + if( md_type == MBEDTLS_MD_MD5 ) + padlen = 48; + else + padlen = 40; + + memcpy( header, ctr, 8 ); + header[ 8] = (unsigned char) type; + header[ 9] = (unsigned char)( len >> 8 ); + header[10] = (unsigned char)( len ); + + memset( padding, 0x36, padlen ); + mbedtls_md_starts( md_ctx ); + mbedtls_md_update( md_ctx, secret, md_size ); + mbedtls_md_update( md_ctx, padding, padlen ); + mbedtls_md_update( md_ctx, header, 11 ); + mbedtls_md_update( md_ctx, buf, len ); + mbedtls_md_finish( md_ctx, buf + len ); + + memset( padding, 0x5C, padlen ); + mbedtls_md_starts( md_ctx ); + mbedtls_md_update( md_ctx, secret, md_size ); + mbedtls_md_update( md_ctx, padding, padlen ); + mbedtls_md_update( md_ctx, buf + len, md_size ); + mbedtls_md_finish( md_ctx, buf + len ); +} +#endif /* MBEDTLS_SSL_PROTO_SSL3 */ + +#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) || \ + ( defined(MBEDTLS_CIPHER_MODE_CBC) && \ + ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_CAMELLIA_C) ) ) +#define SSL_SOME_MODES_USE_MAC +#endif + +/* + * Encryption/decryption functions + */ +static int ssl_encrypt_buf( mbedtls_ssl_context *ssl ) +{ + mbedtls_cipher_mode_t mode; + int auth_done = 0; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> encrypt buf" ) ); + + if( ssl->session_out == NULL || ssl->transform_out == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + + mode = mbedtls_cipher_get_cipher_mode( &ssl->transform_out->cipher_ctx_enc ); + + MBEDTLS_SSL_DEBUG_BUF( 4, "before encrypt: output payload", + ssl->out_msg, ssl->out_msglen ); + + /* + * Add MAC before if needed + */ +#if defined(SSL_SOME_MODES_USE_MAC) + if( mode == MBEDTLS_MODE_STREAM || + ( mode == MBEDTLS_MODE_CBC +#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) + && ssl->session_out->encrypt_then_mac == MBEDTLS_SSL_ETM_DISABLED +#endif + ) ) + { +#if defined(MBEDTLS_SSL_PROTO_SSL3) + if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) + { + ssl_mac( &ssl->transform_out->md_ctx_enc, + ssl->transform_out->mac_enc, + ssl->out_msg, ssl->out_msglen, + ssl->out_ctr, ssl->out_msgtype ); + } + else +#endif +#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ + defined(MBEDTLS_SSL_PROTO_TLS1_2) + if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 ) + { + mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, ssl->out_ctr, 8 ); + mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, ssl->out_hdr, 3 ); + mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, ssl->out_len, 2 ); + mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, + ssl->out_msg, ssl->out_msglen ); + mbedtls_md_hmac_finish( &ssl->transform_out->md_ctx_enc, + ssl->out_msg + ssl->out_msglen ); + mbedtls_md_hmac_reset( &ssl->transform_out->md_ctx_enc ); + } + else +#endif + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + + MBEDTLS_SSL_DEBUG_BUF( 4, "computed mac", + ssl->out_msg + ssl->out_msglen, + ssl->transform_out->maclen ); + + ssl->out_msglen += ssl->transform_out->maclen; + auth_done++; + } +#endif /* AEAD not the only option */ + + /* + * Encrypt + */ +#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) + if( mode == MBEDTLS_MODE_STREAM ) + { + int ret; + size_t olen = 0; + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, " + "including %d bytes of padding", + ssl->out_msglen, 0 ) ); + + if( ( ret = mbedtls_cipher_crypt( &ssl->transform_out->cipher_ctx_enc, + ssl->transform_out->iv_enc, + ssl->transform_out->ivlen, + ssl->out_msg, ssl->out_msglen, + ssl->out_msg, &olen ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret ); + return( ret ); + } + + if( ssl->out_msglen != olen ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + } + else +#endif /* MBEDTLS_ARC4_C || MBEDTLS_CIPHER_NULL_CIPHER */ +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C) + if( mode == MBEDTLS_MODE_GCM || + mode == MBEDTLS_MODE_CCM ) + { + int ret; + size_t enc_msglen, olen; + unsigned char *enc_msg; + unsigned char add_data[13]; + unsigned char taglen = ssl->transform_out->ciphersuite_info->flags & + MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16; + + memcpy( add_data, ssl->out_ctr, 8 ); + add_data[8] = ssl->out_msgtype; + mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver, + ssl->conf->transport, add_data + 9 ); + add_data[11] = ( ssl->out_msglen >> 8 ) & 0xFF; + add_data[12] = ssl->out_msglen & 0xFF; + + MBEDTLS_SSL_DEBUG_BUF( 4, "additional data used for AEAD", + add_data, 13 ); + + /* + * Generate IV + */ + if( ssl->transform_out->ivlen - ssl->transform_out->fixed_ivlen != 8 ) + { + /* Reminder if we ever add an AEAD mode with a different size */ + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + + memcpy( ssl->transform_out->iv_enc + ssl->transform_out->fixed_ivlen, + ssl->out_ctr, 8 ); + memcpy( ssl->out_iv, ssl->out_ctr, 8 ); + + MBEDTLS_SSL_DEBUG_BUF( 4, "IV used", ssl->out_iv, + ssl->transform_out->ivlen - ssl->transform_out->fixed_ivlen ); + + /* + * Fix pointer positions and message length with added IV + */ + enc_msg = ssl->out_msg; + enc_msglen = ssl->out_msglen; + ssl->out_msglen += ssl->transform_out->ivlen - + ssl->transform_out->fixed_ivlen; + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, " + "including %d bytes of padding", + ssl->out_msglen, 0 ) ); + + /* + * Encrypt and authenticate + */ + if( ( ret = mbedtls_cipher_auth_encrypt( &ssl->transform_out->cipher_ctx_enc, + ssl->transform_out->iv_enc, + ssl->transform_out->ivlen, + add_data, 13, + enc_msg, enc_msglen, + enc_msg, &olen, + enc_msg + enc_msglen, taglen ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_auth_encrypt", ret ); + return( ret ); + } + + if( olen != enc_msglen ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + + ssl->out_msglen += taglen; + auth_done++; + + MBEDTLS_SSL_DEBUG_BUF( 4, "after encrypt: tag", enc_msg + enc_msglen, taglen ); + } + else +#endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C */ +#if defined(MBEDTLS_CIPHER_MODE_CBC) && \ + ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_CAMELLIA_C) ) + if( mode == MBEDTLS_MODE_CBC ) + { + int ret; + unsigned char *enc_msg; + size_t enc_msglen, padlen, olen = 0, i; + + padlen = ssl->transform_out->ivlen - ( ssl->out_msglen + 1 ) % + ssl->transform_out->ivlen; + if( padlen == ssl->transform_out->ivlen ) + padlen = 0; + + for( i = 0; i <= padlen; i++ ) + ssl->out_msg[ssl->out_msglen + i] = (unsigned char) padlen; + + ssl->out_msglen += padlen + 1; + + enc_msglen = ssl->out_msglen; + enc_msg = ssl->out_msg; + +#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2) + /* + * Prepend per-record IV for block cipher in TLS v1.1 and up as per + * Method 1 (6.2.3.2. in RFC4346 and RFC5246) + */ + if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 ) + { + /* + * Generate IV + */ + ret = ssl->conf->f_rng( ssl->conf->p_rng, ssl->transform_out->iv_enc, + ssl->transform_out->ivlen ); + if( ret != 0 ) + return( ret ); + + memcpy( ssl->out_iv, ssl->transform_out->iv_enc, + ssl->transform_out->ivlen ); + + /* + * Fix pointer positions and message length with added IV + */ + enc_msg = ssl->out_msg; + enc_msglen = ssl->out_msglen; + ssl->out_msglen += ssl->transform_out->ivlen; + } +#endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */ + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "before encrypt: msglen = %d, " + "including %d bytes of IV and %d bytes of padding", + ssl->out_msglen, ssl->transform_out->ivlen, + padlen + 1 ) ); + + if( ( ret = mbedtls_cipher_crypt( &ssl->transform_out->cipher_ctx_enc, + ssl->transform_out->iv_enc, + ssl->transform_out->ivlen, + enc_msg, enc_msglen, + enc_msg, &olen ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret ); + return( ret ); + } + + if( enc_msglen != olen ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + +#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) + if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 ) + { + /* + * Save IV in SSL3 and TLS1 + */ + memcpy( ssl->transform_out->iv_enc, + ssl->transform_out->cipher_ctx_enc.iv, + ssl->transform_out->ivlen ); + } +#endif + +#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) + if( auth_done == 0 ) + { + /* + * MAC(MAC_write_key, seq_num + + * TLSCipherText.type + + * TLSCipherText.version + + * length_of( (IV +) ENC(...) ) + + * IV + // except for TLS 1.0 + * ENC(content + padding + padding_length)); + */ + unsigned char pseudo_hdr[13]; + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "using encrypt then mac" ) ); + + memcpy( pseudo_hdr + 0, ssl->out_ctr, 8 ); + memcpy( pseudo_hdr + 8, ssl->out_hdr, 3 ); + pseudo_hdr[11] = (unsigned char)( ( ssl->out_msglen >> 8 ) & 0xFF ); + pseudo_hdr[12] = (unsigned char)( ( ssl->out_msglen ) & 0xFF ); + + MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", pseudo_hdr, 13 ); + + mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, pseudo_hdr, 13 ); + mbedtls_md_hmac_update( &ssl->transform_out->md_ctx_enc, + ssl->out_iv, ssl->out_msglen ); + mbedtls_md_hmac_finish( &ssl->transform_out->md_ctx_enc, + ssl->out_iv + ssl->out_msglen ); + mbedtls_md_hmac_reset( &ssl->transform_out->md_ctx_enc ); + + ssl->out_msglen += ssl->transform_out->maclen; + auth_done++; + } +#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ + } + else +#endif /* MBEDTLS_CIPHER_MODE_CBC && + ( MBEDTLS_AES_C || MBEDTLS_CAMELLIA_C ) */ + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + + /* Make extra sure authentication was performed, exactly once */ + if( auth_done != 1 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= encrypt buf" ) ); + + return( 0 ); +} + +#define SSL_MAX_MAC_SIZE 48 + +static int ssl_decrypt_buf( mbedtls_ssl_context *ssl ) +{ + size_t i; + mbedtls_cipher_mode_t mode; + int auth_done = 0; +#if defined(SSL_SOME_MODES_USE_MAC) + size_t padlen = 0, correct = 1; +#endif + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> decrypt buf" ) ); + + if( ssl->session_in == NULL || ssl->transform_in == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + + mode = mbedtls_cipher_get_cipher_mode( &ssl->transform_in->cipher_ctx_dec ); + + if( ssl->in_msglen < ssl->transform_in->minlen ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "in_msglen (%d) < minlen (%d)", + ssl->in_msglen, ssl->transform_in->minlen ) ); + return( MBEDTLS_ERR_SSL_INVALID_MAC ); + } + +#if defined(MBEDTLS_ARC4_C) || defined(MBEDTLS_CIPHER_NULL_CIPHER) + if( mode == MBEDTLS_MODE_STREAM ) + { + int ret; + size_t olen = 0; + + padlen = 0; + + if( ( ret = mbedtls_cipher_crypt( &ssl->transform_in->cipher_ctx_dec, + ssl->transform_in->iv_dec, + ssl->transform_in->ivlen, + ssl->in_msg, ssl->in_msglen, + ssl->in_msg, &olen ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret ); + return( ret ); + } + + if( ssl->in_msglen != olen ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + } + else +#endif /* MBEDTLS_ARC4_C || MBEDTLS_CIPHER_NULL_CIPHER */ +#if defined(MBEDTLS_GCM_C) || defined(MBEDTLS_CCM_C) + if( mode == MBEDTLS_MODE_GCM || + mode == MBEDTLS_MODE_CCM ) + { + int ret; + size_t dec_msglen, olen; + unsigned char *dec_msg; + unsigned char *dec_msg_result; + unsigned char add_data[13]; + unsigned char taglen = ssl->transform_in->ciphersuite_info->flags & + MBEDTLS_CIPHERSUITE_SHORT_TAG ? 8 : 16; + size_t explicit_iv_len = ssl->transform_in->ivlen - + ssl->transform_in->fixed_ivlen; + + if( ssl->in_msglen < explicit_iv_len + taglen ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) < explicit_iv_len (%d) " + "+ taglen (%d)", ssl->in_msglen, + explicit_iv_len, taglen ) ); + return( MBEDTLS_ERR_SSL_INVALID_MAC ); + } + dec_msglen = ssl->in_msglen - explicit_iv_len - taglen; + + dec_msg = ssl->in_msg; + dec_msg_result = ssl->in_msg; + ssl->in_msglen = dec_msglen; + + memcpy( add_data, ssl->in_ctr, 8 ); + add_data[8] = ssl->in_msgtype; + mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver, + ssl->conf->transport, add_data + 9 ); + add_data[11] = ( ssl->in_msglen >> 8 ) & 0xFF; + add_data[12] = ssl->in_msglen & 0xFF; + + MBEDTLS_SSL_DEBUG_BUF( 4, "additional data used for AEAD", + add_data, 13 ); + + memcpy( ssl->transform_in->iv_dec + ssl->transform_in->fixed_ivlen, + ssl->in_iv, + ssl->transform_in->ivlen - ssl->transform_in->fixed_ivlen ); + + MBEDTLS_SSL_DEBUG_BUF( 4, "IV used", ssl->transform_in->iv_dec, + ssl->transform_in->ivlen ); + MBEDTLS_SSL_DEBUG_BUF( 4, "TAG used", dec_msg + dec_msglen, taglen ); + + /* + * Decrypt and authenticate + */ + if( ( ret = mbedtls_cipher_auth_decrypt( &ssl->transform_in->cipher_ctx_dec, + ssl->transform_in->iv_dec, + ssl->transform_in->ivlen, + add_data, 13, + dec_msg, dec_msglen, + dec_msg_result, &olen, + dec_msg + dec_msglen, taglen ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_auth_decrypt", ret ); + + if( ret == MBEDTLS_ERR_CIPHER_AUTH_FAILED ) + return( MBEDTLS_ERR_SSL_INVALID_MAC ); + + return( ret ); + } + auth_done++; + + if( olen != dec_msglen ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + } + else +#endif /* MBEDTLS_GCM_C || MBEDTLS_CCM_C */ +#if defined(MBEDTLS_CIPHER_MODE_CBC) && \ + ( defined(MBEDTLS_AES_C) || defined(MBEDTLS_CAMELLIA_C) ) + if( mode == MBEDTLS_MODE_CBC ) + { + /* + * Decrypt and check the padding + */ + int ret; + unsigned char *dec_msg; + unsigned char *dec_msg_result; + size_t dec_msglen; + size_t minlen = 0; + size_t olen = 0; + + /* + * Check immediate ciphertext sanity + */ +#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2) + if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 ) + minlen += ssl->transform_in->ivlen; +#endif + + if( ssl->in_msglen < minlen + ssl->transform_in->ivlen || + ssl->in_msglen < minlen + ssl->transform_in->maclen + 1 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) < max( ivlen(%d), maclen (%d) " + "+ 1 ) ( + expl IV )", ssl->in_msglen, + ssl->transform_in->ivlen, + ssl->transform_in->maclen ) ); + return( MBEDTLS_ERR_SSL_INVALID_MAC ); + } + + dec_msglen = ssl->in_msglen; + dec_msg = ssl->in_msg; + dec_msg_result = ssl->in_msg; + + /* + * Authenticate before decrypt if enabled + */ +#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) + if( ssl->session_in->encrypt_then_mac == MBEDTLS_SSL_ETM_ENABLED ) + { + unsigned char computed_mac[SSL_MAX_MAC_SIZE]; + unsigned char pseudo_hdr[13]; + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "using encrypt then mac" ) ); + + dec_msglen -= ssl->transform_in->maclen; + ssl->in_msglen -= ssl->transform_in->maclen; + + memcpy( pseudo_hdr + 0, ssl->in_ctr, 8 ); + memcpy( pseudo_hdr + 8, ssl->in_hdr, 3 ); + pseudo_hdr[11] = (unsigned char)( ( ssl->in_msglen >> 8 ) & 0xFF ); + pseudo_hdr[12] = (unsigned char)( ( ssl->in_msglen ) & 0xFF ); + + MBEDTLS_SSL_DEBUG_BUF( 4, "MAC'd meta-data", pseudo_hdr, 13 ); + + mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, pseudo_hdr, 13 ); + mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, + ssl->in_iv, ssl->in_msglen ); + mbedtls_md_hmac_finish( &ssl->transform_in->md_ctx_dec, computed_mac ); + mbedtls_md_hmac_reset( &ssl->transform_in->md_ctx_dec ); + + MBEDTLS_SSL_DEBUG_BUF( 4, "message mac", ssl->in_iv + ssl->in_msglen, + ssl->transform_in->maclen ); + MBEDTLS_SSL_DEBUG_BUF( 4, "computed mac", computed_mac, + ssl->transform_in->maclen ); + + if( mbedtls_ssl_safer_memcmp( ssl->in_iv + ssl->in_msglen, computed_mac, + ssl->transform_in->maclen ) != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "message mac does not match" ) ); + + return( MBEDTLS_ERR_SSL_INVALID_MAC ); + } + auth_done++; + } +#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ + + /* + * Check length sanity + */ + if( ssl->in_msglen % ssl->transform_in->ivlen != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) %% ivlen (%d) != 0", + ssl->in_msglen, ssl->transform_in->ivlen ) ); + return( MBEDTLS_ERR_SSL_INVALID_MAC ); + } + +#if defined(MBEDTLS_SSL_PROTO_TLS1_1) || defined(MBEDTLS_SSL_PROTO_TLS1_2) + /* + * Initialize for prepended IV for block cipher in TLS v1.1 and up + */ + if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 ) + { + dec_msglen -= ssl->transform_in->ivlen; + ssl->in_msglen -= ssl->transform_in->ivlen; + + for( i = 0; i < ssl->transform_in->ivlen; i++ ) + ssl->transform_in->iv_dec[i] = ssl->in_iv[i]; + } +#endif /* MBEDTLS_SSL_PROTO_TLS1_1 || MBEDTLS_SSL_PROTO_TLS1_2 */ + + if( ( ret = mbedtls_cipher_crypt( &ssl->transform_in->cipher_ctx_dec, + ssl->transform_in->iv_dec, + ssl->transform_in->ivlen, + dec_msg, dec_msglen, + dec_msg_result, &olen ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_cipher_crypt", ret ); + return( ret ); + } + + if( dec_msglen != olen ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + +#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) + if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_2 ) + { + /* + * Save IV in SSL3 and TLS1 + */ + memcpy( ssl->transform_in->iv_dec, + ssl->transform_in->cipher_ctx_dec.iv, + ssl->transform_in->ivlen ); + } +#endif + + padlen = 1 + ssl->in_msg[ssl->in_msglen - 1]; + + if( ssl->in_msglen < ssl->transform_in->maclen + padlen && + auth_done == 0 ) + { +#if defined(MBEDTLS_SSL_DEBUG_ALL) + MBEDTLS_SSL_DEBUG_MSG( 1, ( "msglen (%d) < maclen (%d) + padlen (%d)", + ssl->in_msglen, ssl->transform_in->maclen, padlen ) ); +#endif + padlen = 0; + correct = 0; + } + +#if defined(MBEDTLS_SSL_PROTO_SSL3) + if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) + { + if( padlen > ssl->transform_in->ivlen ) + { +#if defined(MBEDTLS_SSL_DEBUG_ALL) + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad padding length: is %d, " + "should be no more than %d", + padlen, ssl->transform_in->ivlen ) ); +#endif + correct = 0; + } + } + else +#endif /* MBEDTLS_SSL_PROTO_SSL3 */ +#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ + defined(MBEDTLS_SSL_PROTO_TLS1_2) + if( ssl->minor_ver > MBEDTLS_SSL_MINOR_VERSION_0 ) + { + /* + * TLSv1+: always check the padding up to the first failure + * and fake check up to 256 bytes of padding + */ + size_t pad_count = 0, real_count = 1; + size_t padding_idx = ssl->in_msglen - padlen - 1; + + /* + * Padding is guaranteed to be incorrect if: + * 1. padlen >= ssl->in_msglen + * + * 2. padding_idx >= MBEDTLS_SSL_MAX_CONTENT_LEN + + * ssl->transform_in->maclen + * + * In both cases we reset padding_idx to a safe value (0) to + * prevent out-of-buffer reads. + */ + correct &= ( ssl->in_msglen >= padlen + 1 ); + correct &= ( padding_idx < MBEDTLS_SSL_MAX_CONTENT_LEN + + ssl->transform_in->maclen ); + + padding_idx *= correct; + + for( i = 1; i <= 256; i++ ) + { + real_count &= ( i <= padlen ); + pad_count += real_count * + ( ssl->in_msg[padding_idx + i] == padlen - 1 ); + } + + correct &= ( pad_count == padlen ); /* Only 1 on correct padding */ + +#if defined(MBEDTLS_SSL_DEBUG_ALL) + if( padlen > 0 && correct == 0 ) + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad padding byte detected" ) ); +#endif + padlen &= correct * 0x1FF; + } + else +#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \ + MBEDTLS_SSL_PROTO_TLS1_2 */ + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + + ssl->in_msglen -= padlen; + } + else +#endif /* MBEDTLS_CIPHER_MODE_CBC && + ( MBEDTLS_AES_C || MBEDTLS_CAMELLIA_C ) */ + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + + MBEDTLS_SSL_DEBUG_BUF( 4, "raw buffer after decryption", + ssl->in_msg, ssl->in_msglen ); + + /* + * Authenticate if not done yet. + * Compute the MAC regardless of the padding result (RFC4346, CBCTIME). + */ +#if defined(SSL_SOME_MODES_USE_MAC) + if( auth_done == 0 ) + { + unsigned char tmp[SSL_MAX_MAC_SIZE]; + + ssl->in_msglen -= ssl->transform_in->maclen; + + ssl->in_len[0] = (unsigned char)( ssl->in_msglen >> 8 ); + ssl->in_len[1] = (unsigned char)( ssl->in_msglen ); + + memcpy( tmp, ssl->in_msg + ssl->in_msglen, ssl->transform_in->maclen ); + +#if defined(MBEDTLS_SSL_PROTO_SSL3) + if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) + { + ssl_mac( &ssl->transform_in->md_ctx_dec, + ssl->transform_in->mac_dec, + ssl->in_msg, ssl->in_msglen, + ssl->in_ctr, ssl->in_msgtype ); + } + else +#endif /* MBEDTLS_SSL_PROTO_SSL3 */ +#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ + defined(MBEDTLS_SSL_PROTO_TLS1_2) + if( ssl->minor_ver > MBEDTLS_SSL_MINOR_VERSION_0 ) + { + /* + * Process MAC and always update for padlen afterwards to make + * total time independent of padlen + * + * extra_run compensates MAC check for padlen + * + * Known timing attacks: + * - Lucky Thirteen (http://www.isg.rhul.ac.uk/tls/TLStiming.pdf) + * + * We use ( ( Lx + 8 ) / 64 ) to handle 'negative Lx' values + * correctly. (We round down instead of up, so -56 is the correct + * value for our calculations instead of -55) + */ + size_t j, extra_run = 0; + extra_run = ( 13 + ssl->in_msglen + padlen + 8 ) / 64 - + ( 13 + ssl->in_msglen + 8 ) / 64; + + extra_run &= correct * 0xFF; + + mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_ctr, 8 ); + mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_hdr, 3 ); + mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_len, 2 ); + mbedtls_md_hmac_update( &ssl->transform_in->md_ctx_dec, ssl->in_msg, + ssl->in_msglen ); + mbedtls_md_hmac_finish( &ssl->transform_in->md_ctx_dec, + ssl->in_msg + ssl->in_msglen ); + /* Call mbedtls_md_process at least once due to cache attacks */ + for( j = 0; j < extra_run + 1; j++ ) + mbedtls_md_process( &ssl->transform_in->md_ctx_dec, ssl->in_msg ); + + mbedtls_md_hmac_reset( &ssl->transform_in->md_ctx_dec ); + } + else +#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \ + MBEDTLS_SSL_PROTO_TLS1_2 */ + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + + MBEDTLS_SSL_DEBUG_BUF( 4, "message mac", tmp, ssl->transform_in->maclen ); + MBEDTLS_SSL_DEBUG_BUF( 4, "computed mac", ssl->in_msg + ssl->in_msglen, + ssl->transform_in->maclen ); + + if( mbedtls_ssl_safer_memcmp( tmp, ssl->in_msg + ssl->in_msglen, + ssl->transform_in->maclen ) != 0 ) + { +#if defined(MBEDTLS_SSL_DEBUG_ALL) + MBEDTLS_SSL_DEBUG_MSG( 1, ( "message mac does not match" ) ); +#endif + correct = 0; + } + auth_done++; + + /* + * Finally check the correct flag + */ + if( correct == 0 ) + return( MBEDTLS_ERR_SSL_INVALID_MAC ); + } +#endif /* SSL_SOME_MODES_USE_MAC */ + + /* Make extra sure authentication was performed, exactly once */ + if( auth_done != 1 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + + if( ssl->in_msglen == 0 ) + { + ssl->nb_zero++; + + /* + * Three or more empty messages may be a DoS attack + * (excessive CPU consumption). + */ + if( ssl->nb_zero > 3 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "received four consecutive empty " + "messages, possible DoS attack" ) ); + return( MBEDTLS_ERR_SSL_INVALID_MAC ); + } + } + else + ssl->nb_zero = 0; + +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + { + ; /* in_ctr read from peer, not maintained internally */ + } + else +#endif + { + for( i = 8; i > ssl_ep_len( ssl ); i-- ) + if( ++ssl->in_ctr[i - 1] != 0 ) + break; + + /* The loop goes to its end iff the counter is wrapping */ + if( i == ssl_ep_len( ssl ) ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "incoming message counter would wrap" ) ); + return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING ); + } + } + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= decrypt buf" ) ); + + return( 0 ); +} + +#undef MAC_NONE +#undef MAC_PLAINTEXT +#undef MAC_CIPHERTEXT + +#if defined(MBEDTLS_ZLIB_SUPPORT) +/* + * Compression/decompression functions + */ +static int ssl_compress_buf( mbedtls_ssl_context *ssl ) +{ + int ret; + unsigned char *msg_post = ssl->out_msg; + size_t len_pre = ssl->out_msglen; + unsigned char *msg_pre = ssl->compress_buf; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> compress buf" ) ); + + if( len_pre == 0 ) + return( 0 ); + + memcpy( msg_pre, ssl->out_msg, len_pre ); + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "before compression: msglen = %d, ", + ssl->out_msglen ) ); + + MBEDTLS_SSL_DEBUG_BUF( 4, "before compression: output payload", + ssl->out_msg, ssl->out_msglen ); + + ssl->transform_out->ctx_deflate.next_in = msg_pre; + ssl->transform_out->ctx_deflate.avail_in = len_pre; + ssl->transform_out->ctx_deflate.next_out = msg_post; + ssl->transform_out->ctx_deflate.avail_out = MBEDTLS_SSL_BUFFER_LEN; + + ret = deflate( &ssl->transform_out->ctx_deflate, Z_SYNC_FLUSH ); + if( ret != Z_OK ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "failed to perform compression (%d)", ret ) ); + return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED ); + } + + ssl->out_msglen = MBEDTLS_SSL_BUFFER_LEN - + ssl->transform_out->ctx_deflate.avail_out; + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "after compression: msglen = %d, ", + ssl->out_msglen ) ); + + MBEDTLS_SSL_DEBUG_BUF( 4, "after compression: output payload", + ssl->out_msg, ssl->out_msglen ); + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= compress buf" ) ); + + return( 0 ); +} + +static int ssl_decompress_buf( mbedtls_ssl_context *ssl ) +{ + int ret; + unsigned char *msg_post = ssl->in_msg; + size_t len_pre = ssl->in_msglen; + unsigned char *msg_pre = ssl->compress_buf; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> decompress buf" ) ); + + if( len_pre == 0 ) + return( 0 ); + + memcpy( msg_pre, ssl->in_msg, len_pre ); + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "before decompression: msglen = %d, ", + ssl->in_msglen ) ); + + MBEDTLS_SSL_DEBUG_BUF( 4, "before decompression: input payload", + ssl->in_msg, ssl->in_msglen ); + + ssl->transform_in->ctx_inflate.next_in = msg_pre; + ssl->transform_in->ctx_inflate.avail_in = len_pre; + ssl->transform_in->ctx_inflate.next_out = msg_post; + ssl->transform_in->ctx_inflate.avail_out = MBEDTLS_SSL_MAX_CONTENT_LEN; + + ret = inflate( &ssl->transform_in->ctx_inflate, Z_SYNC_FLUSH ); + if( ret != Z_OK ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "failed to perform decompression (%d)", ret ) ); + return( MBEDTLS_ERR_SSL_COMPRESSION_FAILED ); + } + + ssl->in_msglen = MBEDTLS_SSL_MAX_CONTENT_LEN - + ssl->transform_in->ctx_inflate.avail_out; + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "after decompression: msglen = %d, ", + ssl->in_msglen ) ); + + MBEDTLS_SSL_DEBUG_BUF( 4, "after decompression: input payload", + ssl->in_msg, ssl->in_msglen ); + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= decompress buf" ) ); + + return( 0 ); +} +#endif /* MBEDTLS_ZLIB_SUPPORT */ + +#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION) +static int ssl_write_hello_request( mbedtls_ssl_context *ssl ); + +#if defined(MBEDTLS_SSL_PROTO_DTLS) +static int ssl_resend_hello_request( mbedtls_ssl_context *ssl ) +{ + /* If renegotiation is not enforced, retransmit until we would reach max + * timeout if we were using the usual handshake doubling scheme */ + if( ssl->conf->renego_max_records < 0 ) + { + uint32_t ratio = ssl->conf->hs_timeout_max / ssl->conf->hs_timeout_min + 1; + unsigned char doublings = 1; + + while( ratio != 0 ) + { + ++doublings; + ratio >>= 1; + } + + if( ++ssl->renego_records_seen > doublings ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "no longer retransmitting hello request" ) ); + return( 0 ); + } + } + + return( ssl_write_hello_request( ssl ) ); +} +#endif +#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */ + +/* + * Fill the input message buffer by appending data to it. + * The amount of data already fetched is in ssl->in_left. + * + * If we return 0, is it guaranteed that (at least) nb_want bytes are + * available (from this read and/or a previous one). Otherwise, an error code + * is returned (possibly EOF or WANT_READ). + * + * With stream transport (TLS) on success ssl->in_left == nb_want, but + * with datagram transport (DTLS) on success ssl->in_left >= nb_want, + * since we always read a whole datagram at once. + * + * For DTLS, it is up to the caller to set ssl->next_record_offset when + * they're done reading a record. + */ +int mbedtls_ssl_fetch_input( mbedtls_ssl_context *ssl, size_t nb_want ) +{ + int ret; + size_t len; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> fetch input" ) ); + + if( ssl->f_recv == NULL && ssl->f_recv_timeout == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() " + "or mbedtls_ssl_set_bio()" ) ); + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + } + + if( nb_want > MBEDTLS_SSL_BUFFER_LEN - (size_t)( ssl->in_hdr - ssl->in_buf ) ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "requesting more data than fits" ) ); + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + } + +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + { + uint32_t timeout; + + /* Just to be sure */ + if( ssl->f_set_timer == NULL || ssl->f_get_timer == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "You must use " + "mbedtls_ssl_set_timer_cb() for DTLS" ) ); + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + } + + /* + * The point is, we need to always read a full datagram at once, so we + * sometimes read more then requested, and handle the additional data. + * It could be the rest of the current record (while fetching the + * header) and/or some other records in the same datagram. + */ + + /* + * Move to the next record in the already read datagram if applicable + */ + if( ssl->next_record_offset != 0 ) + { + if( ssl->in_left < ssl->next_record_offset ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + + ssl->in_left -= ssl->next_record_offset; + + if( ssl->in_left != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "next record in same datagram, offset: %d", + ssl->next_record_offset ) ); + memmove( ssl->in_hdr, + ssl->in_hdr + ssl->next_record_offset, + ssl->in_left ); + } + + ssl->next_record_offset = 0; + } + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %d, nb_want: %d", + ssl->in_left, nb_want ) ); + + /* + * Done if we already have enough data. + */ + if( nb_want <= ssl->in_left) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= fetch input" ) ); + return( 0 ); + } + + /* + * A record can't be split accross datagrams. If we need to read but + * are not at the beginning of a new record, the caller did something + * wrong. + */ + if( ssl->in_left != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + + /* + * Don't even try to read if time's out already. + * This avoids by-passing the timer when repeatedly receiving messages + * that will end up being dropped. + */ + if( ssl_check_timer( ssl ) != 0 ) + ret = MBEDTLS_ERR_SSL_TIMEOUT; + else + { + len = MBEDTLS_SSL_BUFFER_LEN - ( ssl->in_hdr - ssl->in_buf ); + + if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) + timeout = ssl->handshake->retransmit_timeout; + else + timeout = ssl->conf->read_timeout; + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "f_recv_timeout: %u ms", timeout ) ); + + if( ssl->f_recv_timeout != NULL ) + ret = ssl->f_recv_timeout( ssl->p_bio, ssl->in_hdr, len, + timeout ); + else + ret = ssl->f_recv( ssl->p_bio, ssl->in_hdr, len ); + + MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_recv(_timeout)", ret ); + + if( ret == 0 ) + return( MBEDTLS_ERR_SSL_CONN_EOF ); + } + + if( ret == MBEDTLS_ERR_SSL_TIMEOUT ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "timeout" ) ); + ssl_set_timer( ssl, 0 ); + + if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) + { + if( ssl_double_retransmit_timeout( ssl ) != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake timeout" ) ); + return( MBEDTLS_ERR_SSL_TIMEOUT ); + } + + if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_resend", ret ); + return( ret ); + } + + return( MBEDTLS_ERR_SSL_WANT_READ ); + } +#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION) + else if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && + ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING ) + { + if( ( ret = ssl_resend_hello_request( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "ssl_resend_hello_request", ret ); + return( ret ); + } + + return( MBEDTLS_ERR_SSL_WANT_READ ); + } +#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */ + } + + if( ret < 0 ) + return( ret ); + + ssl->in_left = ret; + } + else +#endif + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %d, nb_want: %d", + ssl->in_left, nb_want ) ); + + while( ssl->in_left < nb_want ) + { + len = nb_want - ssl->in_left; + + if( ssl_check_timer( ssl ) != 0 ) + ret = MBEDTLS_ERR_SSL_TIMEOUT; + else + { + if( ssl->f_recv_timeout != NULL ) + { + ret = ssl->f_recv_timeout( ssl->p_bio, + ssl->in_hdr + ssl->in_left, len, + ssl->conf->read_timeout ); + } + else + { + ret = ssl->f_recv( ssl->p_bio, + ssl->in_hdr + ssl->in_left, len ); + } + } + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "in_left: %d, nb_want: %d", + ssl->in_left, nb_want ) ); + MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_recv(_timeout)", ret ); + + if( ret == 0 ) + return( MBEDTLS_ERR_SSL_CONN_EOF ); + + if( ret < 0 ) + return( ret ); + + ssl->in_left += ret; + } + } + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= fetch input" ) ); + + return( 0 ); +} + +/* + * Flush any data not yet written + */ +int mbedtls_ssl_flush_output( mbedtls_ssl_context *ssl ) +{ + int ret; + unsigned char *buf, i; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> flush output" ) ); + + if( ssl->f_send == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "Bad usage of mbedtls_ssl_set_bio() " + "or mbedtls_ssl_set_bio()" ) ); + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + } + + /* Avoid incrementing counter if data is flushed */ + if( ssl->out_left == 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= flush output" ) ); + return( 0 ); + } + + while( ssl->out_left > 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "message length: %d, out_left: %d", + mbedtls_ssl_hdr_len( ssl ) + ssl->out_msglen, ssl->out_left ) ); + + buf = ssl->out_hdr + mbedtls_ssl_hdr_len( ssl ) + + ssl->out_msglen - ssl->out_left; + ret = ssl->f_send( ssl->p_bio, buf, ssl->out_left ); + + MBEDTLS_SSL_DEBUG_RET( 2, "ssl->f_send", ret ); + + if( ret <= 0 ) + return( ret ); + + ssl->out_left -= ret; + } + + for( i = 8; i > ssl_ep_len( ssl ); i-- ) + if( ++ssl->out_ctr[i - 1] != 0 ) + break; + + /* The loop goes to its end iff the counter is wrapping */ + if( i == ssl_ep_len( ssl ) ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "outgoing message counter would wrap" ) ); + return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING ); + } + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= flush output" ) ); + + return( 0 ); +} + +/* + * Functions to handle the DTLS retransmission state machine + */ +#if defined(MBEDTLS_SSL_PROTO_DTLS) +/* + * Append current handshake message to current outgoing flight + */ +static int ssl_flight_append( mbedtls_ssl_context *ssl ) +{ + mbedtls_ssl_flight_item *msg; + + /* Allocate space for current message */ + if( ( msg = mbedtls_calloc( 1, sizeof( mbedtls_ssl_flight_item ) ) ) == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc %d bytes failed", + sizeof( mbedtls_ssl_flight_item ) ) ); + return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); + } + + if( ( msg->p = mbedtls_calloc( 1, ssl->out_msglen ) ) == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc %d bytes failed", ssl->out_msglen ) ); + mbedtls_free( msg ); + return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); + } + + /* Copy current handshake message with headers */ + memcpy( msg->p, ssl->out_msg, ssl->out_msglen ); + msg->len = ssl->out_msglen; + msg->type = ssl->out_msgtype; + msg->next = NULL; + + /* Append to the current flight */ + if( ssl->handshake->flight == NULL ) + ssl->handshake->flight = msg; + else + { + mbedtls_ssl_flight_item *cur = ssl->handshake->flight; + while( cur->next != NULL ) + cur = cur->next; + cur->next = msg; + } + + return( 0 ); +} + +/* + * Free the current flight of handshake messages + */ +static void ssl_flight_free( mbedtls_ssl_flight_item *flight ) +{ + mbedtls_ssl_flight_item *cur = flight; + mbedtls_ssl_flight_item *next; + + while( cur != NULL ) + { + next = cur->next; + + mbedtls_free( cur->p ); + mbedtls_free( cur ); + + cur = next; + } +} + +#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) +static void ssl_dtls_replay_reset( mbedtls_ssl_context *ssl ); +#endif + +/* + * Swap transform_out and out_ctr with the alternative ones + */ +static void ssl_swap_epochs( mbedtls_ssl_context *ssl ) +{ + mbedtls_ssl_transform *tmp_transform; + unsigned char tmp_out_ctr[8]; + + if( ssl->transform_out == ssl->handshake->alt_transform_out ) + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip swap epochs" ) ); + return; + } + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "swap epochs" ) ); + + /* Swap transforms */ + tmp_transform = ssl->transform_out; + ssl->transform_out = ssl->handshake->alt_transform_out; + ssl->handshake->alt_transform_out = tmp_transform; + + /* Swap epoch + sequence_number */ + memcpy( tmp_out_ctr, ssl->out_ctr, 8 ); + memcpy( ssl->out_ctr, ssl->handshake->alt_out_ctr, 8 ); + memcpy( ssl->handshake->alt_out_ctr, tmp_out_ctr, 8 ); + + /* Adjust to the newly activated transform */ + if( ssl->transform_out != NULL && + ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 ) + { + ssl->out_msg = ssl->out_iv + ssl->transform_out->ivlen - + ssl->transform_out->fixed_ivlen; + } + else + ssl->out_msg = ssl->out_iv; + +#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) + if( mbedtls_ssl_hw_record_activate != NULL ) + { + if( ( ret = mbedtls_ssl_hw_record_activate( ssl, MBEDTLS_SSL_CHANNEL_OUTBOUND ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_activate", ret ); + return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); + } + } +#endif +} + +/* + * Retransmit the current flight of messages. + * + * Need to remember the current message in case flush_output returns + * WANT_WRITE, causing us to exit this function and come back later. + * This function must be called until state is no longer SENDING. + */ +int mbedtls_ssl_resend( mbedtls_ssl_context *ssl ) +{ + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> mbedtls_ssl_resend" ) ); + + if( ssl->handshake->retransmit_state != MBEDTLS_SSL_RETRANS_SENDING ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "initialise resending" ) ); + + ssl->handshake->cur_msg = ssl->handshake->flight; + ssl_swap_epochs( ssl ); + + ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_SENDING; + } + + while( ssl->handshake->cur_msg != NULL ) + { + int ret; + mbedtls_ssl_flight_item *cur = ssl->handshake->cur_msg; + + /* Swap epochs before sending Finished: we can't do it after + * sending ChangeCipherSpec, in case write returns WANT_READ. + * Must be done before copying, may change out_msg pointer */ + if( cur->type == MBEDTLS_SSL_MSG_HANDSHAKE && + cur->p[0] == MBEDTLS_SSL_HS_FINISHED ) + { + ssl_swap_epochs( ssl ); + } + + memcpy( ssl->out_msg, cur->p, cur->len ); + ssl->out_msglen = cur->len; + ssl->out_msgtype = cur->type; + + ssl->handshake->cur_msg = cur->next; + + MBEDTLS_SSL_DEBUG_BUF( 3, "resent handshake message header", ssl->out_msg, 12 ); + + if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); + return( ret ); + } + } + + if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER ) + ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED; + else + { + ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING; + ssl_set_timer( ssl, ssl->handshake->retransmit_timeout ); + } + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= mbedtls_ssl_resend" ) ); + + return( 0 ); +} + +/* + * To be called when the last message of an incoming flight is received. + */ +void mbedtls_ssl_recv_flight_completed( mbedtls_ssl_context *ssl ) +{ + /* We won't need to resend that one any more */ + ssl_flight_free( ssl->handshake->flight ); + ssl->handshake->flight = NULL; + ssl->handshake->cur_msg = NULL; + + /* The next incoming flight will start with this msg_seq */ + ssl->handshake->in_flight_start_seq = ssl->handshake->in_msg_seq; + + /* Cancel timer */ + ssl_set_timer( ssl, 0 ); + + if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && + ssl->in_msg[0] == MBEDTLS_SSL_HS_FINISHED ) + { + ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED; + } + else + ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_PREPARING; +} + +/* + * To be called when the last message of an outgoing flight is send. + */ +void mbedtls_ssl_send_flight_completed( mbedtls_ssl_context *ssl ) +{ + ssl_reset_retransmit_timeout( ssl ); + ssl_set_timer( ssl, ssl->handshake->retransmit_timeout ); + + if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && + ssl->in_msg[0] == MBEDTLS_SSL_HS_FINISHED ) + { + ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_FINISHED; + } + else + ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING; +} +#endif /* MBEDTLS_SSL_PROTO_DTLS */ + +/* + * Record layer functions + */ + +/* + * Write current record. + * Uses ssl->out_msgtype, ssl->out_msglen and bytes at ssl->out_msg. + */ +int mbedtls_ssl_write_record( mbedtls_ssl_context *ssl ) +{ + int ret, done = 0, out_msg_type; + size_t len = ssl->out_msglen; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write record" ) ); + +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && + ssl->handshake != NULL && + ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING ) + { + ; /* Skip special handshake treatment when resending */ + } + else +#endif + if( ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE ) + { + out_msg_type = ssl->out_msg[0]; + + if( out_msg_type != MBEDTLS_SSL_HS_HELLO_REQUEST && + ssl->handshake == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + + ssl->out_msg[1] = (unsigned char)( ( len - 4 ) >> 16 ); + ssl->out_msg[2] = (unsigned char)( ( len - 4 ) >> 8 ); + ssl->out_msg[3] = (unsigned char)( ( len - 4 ) ); + + /* + * DTLS has additional fields in the Handshake layer, + * between the length field and the actual payload: + * uint16 message_seq; + * uint24 fragment_offset; + * uint24 fragment_length; + */ +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + { + /* Make room for the additional DTLS fields */ + memmove( ssl->out_msg + 12, ssl->out_msg + 4, len - 4 ); + ssl->out_msglen += 8; + len += 8; + + /* Write message_seq and update it, except for HelloRequest */ + if( out_msg_type != MBEDTLS_SSL_HS_HELLO_REQUEST ) + { + ssl->out_msg[4] = ( ssl->handshake->out_msg_seq >> 8 ) & 0xFF; + ssl->out_msg[5] = ( ssl->handshake->out_msg_seq ) & 0xFF; + ++( ssl->handshake->out_msg_seq ); + } + else + { + ssl->out_msg[4] = 0; + ssl->out_msg[5] = 0; + } + + /* We don't fragment, so frag_offset = 0 and frag_len = len */ + memset( ssl->out_msg + 6, 0x00, 3 ); + memcpy( ssl->out_msg + 9, ssl->out_msg + 1, 3 ); + } +#endif /* MBEDTLS_SSL_PROTO_DTLS */ + + if( out_msg_type != MBEDTLS_SSL_HS_HELLO_REQUEST ) + ssl->handshake->update_checksum( ssl, ssl->out_msg, len ); + } + + /* Save handshake and CCS messages for resending */ +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && + ssl->handshake != NULL && + ssl->handshake->retransmit_state != MBEDTLS_SSL_RETRANS_SENDING && + ( ssl->out_msgtype == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC || + ssl->out_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE ) ) + { + if( ( ret = ssl_flight_append( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "ssl_flight_append", ret ); + return( ret ); + } + } +#endif + +#if defined(MBEDTLS_ZLIB_SUPPORT) + if( ssl->transform_out != NULL && + ssl->session_out->compression == MBEDTLS_SSL_COMPRESS_DEFLATE ) + { + if( ( ret = ssl_compress_buf( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "ssl_compress_buf", ret ); + return( ret ); + } + + len = ssl->out_msglen; + } +#endif /*MBEDTLS_ZLIB_SUPPORT */ + +#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) + if( mbedtls_ssl_hw_record_write != NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_write()" ) ); + + ret = mbedtls_ssl_hw_record_write( ssl ); + if( ret != 0 && ret != MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_write", ret ); + return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); + } + + if( ret == 0 ) + done = 1; + } +#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ + if( !done ) + { + ssl->out_hdr[0] = (unsigned char) ssl->out_msgtype; + mbedtls_ssl_write_version( ssl->major_ver, ssl->minor_ver, + ssl->conf->transport, ssl->out_hdr + 1 ); + + ssl->out_len[0] = (unsigned char)( len >> 8 ); + ssl->out_len[1] = (unsigned char)( len ); + + if( ssl->transform_out != NULL ) + { + if( ( ret = ssl_encrypt_buf( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "ssl_encrypt_buf", ret ); + return( ret ); + } + + len = ssl->out_msglen; + ssl->out_len[0] = (unsigned char)( len >> 8 ); + ssl->out_len[1] = (unsigned char)( len ); + } + + ssl->out_left = mbedtls_ssl_hdr_len( ssl ) + ssl->out_msglen; + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "output record: msgtype = %d, " + "version = [%d:%d], msglen = %d", + ssl->out_hdr[0], ssl->out_hdr[1], ssl->out_hdr[2], + ( ssl->out_len[0] << 8 ) | ssl->out_len[1] ) ); + + MBEDTLS_SSL_DEBUG_BUF( 4, "output record sent to network", + ssl->out_hdr, mbedtls_ssl_hdr_len( ssl ) + ssl->out_msglen ); + } + + if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flush_output", ret ); + return( ret ); + } + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write record" ) ); + + return( 0 ); +} + +#if defined(MBEDTLS_SSL_PROTO_DTLS) +/* + * Mark bits in bitmask (used for DTLS HS reassembly) + */ +static void ssl_bitmask_set( unsigned char *mask, size_t offset, size_t len ) +{ + unsigned int start_bits, end_bits; + + start_bits = 8 - ( offset % 8 ); + if( start_bits != 8 ) + { + size_t first_byte_idx = offset / 8; + + /* Special case */ + if( len <= start_bits ) + { + for( ; len != 0; len-- ) + mask[first_byte_idx] |= 1 << ( start_bits - len ); + + /* Avoid potential issues with offset or len becoming invalid */ + return; + } + + offset += start_bits; /* Now offset % 8 == 0 */ + len -= start_bits; + + for( ; start_bits != 0; start_bits-- ) + mask[first_byte_idx] |= 1 << ( start_bits - 1 ); + } + + end_bits = len % 8; + if( end_bits != 0 ) + { + size_t last_byte_idx = ( offset + len ) / 8; + + len -= end_bits; /* Now len % 8 == 0 */ + + for( ; end_bits != 0; end_bits-- ) + mask[last_byte_idx] |= 1 << ( 8 - end_bits ); + } + + memset( mask + offset / 8, 0xFF, len / 8 ); +} + +/* + * Check that bitmask is full + */ +static int ssl_bitmask_check( unsigned char *mask, size_t len ) +{ + size_t i; + + for( i = 0; i < len / 8; i++ ) + if( mask[i] != 0xFF ) + return( -1 ); + + for( i = 0; i < len % 8; i++ ) + if( ( mask[len / 8] & ( 1 << ( 7 - i ) ) ) == 0 ) + return( -1 ); + + return( 0 ); +} + +/* + * Reassemble fragmented DTLS handshake messages. + * + * Use a temporary buffer for reassembly, divided in two parts: + * - the first holds the reassembled message (including handshake header), + * - the second holds a bitmask indicating which parts of the message + * (excluding headers) have been received so far. + */ +static int ssl_reassemble_dtls_handshake( mbedtls_ssl_context *ssl ) +{ + unsigned char *msg, *bitmask; + size_t frag_len, frag_off; + size_t msg_len = ssl->in_hslen - 12; /* Without headers */ + + if( ssl->handshake == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "not supported outside handshake (for now)" ) ); + return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); + } + + /* + * For first fragment, check size and allocate buffer + */ + if( ssl->handshake->hs_msg == NULL ) + { + size_t alloc_len; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "initialize reassembly, total length = %d", + msg_len ) ); + + if( ssl->in_hslen > MBEDTLS_SSL_MAX_CONTENT_LEN ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake message too large" ) ); + return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); + } + + /* The bitmask needs one bit per byte of message excluding header */ + alloc_len = 12 + msg_len + msg_len / 8 + ( msg_len % 8 != 0 ); + + ssl->handshake->hs_msg = mbedtls_calloc( 1, alloc_len ); + if( ssl->handshake->hs_msg == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc failed (%d bytes)", alloc_len ) ); + return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); + } + + /* Prepare final header: copy msg_type, length and message_seq, + * then add standardised fragment_offset and fragment_length */ + memcpy( ssl->handshake->hs_msg, ssl->in_msg, 6 ); + memset( ssl->handshake->hs_msg + 6, 0, 3 ); + memcpy( ssl->handshake->hs_msg + 9, + ssl->handshake->hs_msg + 1, 3 ); + } + else + { + /* Make sure msg_type and length are consistent */ + if( memcmp( ssl->handshake->hs_msg, ssl->in_msg, 4 ) != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "fragment header mismatch" ) ); + return( MBEDTLS_ERR_SSL_INVALID_RECORD ); + } + } + + msg = ssl->handshake->hs_msg + 12; + bitmask = msg + msg_len; + + /* + * Check and copy current fragment + */ + frag_off = ( ssl->in_msg[6] << 16 ) | + ( ssl->in_msg[7] << 8 ) | + ssl->in_msg[8]; + frag_len = ( ssl->in_msg[9] << 16 ) | + ( ssl->in_msg[10] << 8 ) | + ssl->in_msg[11]; + + if( frag_off + frag_len > msg_len ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid fragment offset/len: %d + %d > %d", + frag_off, frag_len, msg_len ) ); + return( MBEDTLS_ERR_SSL_INVALID_RECORD ); + } + + if( frag_len + 12 > ssl->in_msglen ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "invalid fragment length: %d + 12 > %d", + frag_len, ssl->in_msglen ) ); + return( MBEDTLS_ERR_SSL_INVALID_RECORD ); + } + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "adding fragment, offset = %d, length = %d", + frag_off, frag_len ) ); + + memcpy( msg + frag_off, ssl->in_msg + 12, frag_len ); + ssl_bitmask_set( bitmask, frag_off, frag_len ); + + /* + * Do we have the complete message by now? + * If yes, finalize it, else ask to read the next record. + */ + if( ssl_bitmask_check( bitmask, msg_len ) != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "message is not complete yet" ) ); + return( MBEDTLS_ERR_SSL_WANT_READ ); + } + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "handshake message completed" ) ); + + if( frag_len + 12 < ssl->in_msglen ) + { + /* + * We'got more handshake messages in the same record. + * This case is not handled now because no know implementation does + * that and it's hard to test, so we prefer to fail cleanly for now. + */ + MBEDTLS_SSL_DEBUG_MSG( 1, ( "last fragment not alone in its record" ) ); + return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); + } + + if( ssl->in_left > ssl->next_record_offset ) + { + /* + * We've got more data in the buffer after the current record, + * that we don't want to overwrite. Move it before writing the + * reassembled message, and adjust in_left and next_record_offset. + */ + unsigned char *cur_remain = ssl->in_hdr + ssl->next_record_offset; + unsigned char *new_remain = ssl->in_msg + ssl->in_hslen; + size_t remain_len = ssl->in_left - ssl->next_record_offset; + + /* First compute and check new lengths */ + ssl->next_record_offset = new_remain - ssl->in_hdr; + ssl->in_left = ssl->next_record_offset + remain_len; + + if( ssl->in_left > MBEDTLS_SSL_BUFFER_LEN - + (size_t)( ssl->in_hdr - ssl->in_buf ) ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "reassembled message too large for buffer" ) ); + return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); + } + + memmove( new_remain, cur_remain, remain_len ); + } + + memcpy( ssl->in_msg, ssl->handshake->hs_msg, ssl->in_hslen ); + + mbedtls_free( ssl->handshake->hs_msg ); + ssl->handshake->hs_msg = NULL; + + MBEDTLS_SSL_DEBUG_BUF( 3, "reassembled handshake message", + ssl->in_msg, ssl->in_hslen ); + + return( 0 ); +} +#endif /* MBEDTLS_SSL_PROTO_DTLS */ + +int mbedtls_ssl_prepare_handshake_record( mbedtls_ssl_context *ssl ) +{ + if( ssl->in_msglen < mbedtls_ssl_hs_hdr_len( ssl ) ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake message too short: %d", + ssl->in_msglen ) ); + return( MBEDTLS_ERR_SSL_INVALID_RECORD ); + } + + ssl->in_hslen = mbedtls_ssl_hs_hdr_len( ssl ) + ( + ( ssl->in_msg[1] << 16 ) | + ( ssl->in_msg[2] << 8 ) | + ssl->in_msg[3] ); + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "handshake message: msglen =" + " %d, type = %d, hslen = %d", + ssl->in_msglen, ssl->in_msg[0], ssl->in_hslen ) ); + +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + { + int ret; + unsigned int recv_msg_seq = ( ssl->in_msg[4] << 8 ) | ssl->in_msg[5]; + + /* ssl->handshake is NULL when receiving ClientHello for renego */ + if( ssl->handshake != NULL && + recv_msg_seq != ssl->handshake->in_msg_seq ) + { + /* Retransmit only on last message from previous flight, to avoid + * too many retransmissions. + * Besides, No sane server ever retransmits HelloVerifyRequest */ + if( recv_msg_seq == ssl->handshake->in_flight_start_seq - 1 && + ssl->in_msg[0] != MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "received message from last flight, " + "message_seq = %d, start_of_flight = %d", + recv_msg_seq, + ssl->handshake->in_flight_start_seq ) ); + + if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_resend", ret ); + return( ret ); + } + } + else + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "dropping out-of-sequence message: " + "message_seq = %d, expected = %d", + recv_msg_seq, + ssl->handshake->in_msg_seq ) ); + } + + return( MBEDTLS_ERR_SSL_WANT_READ ); + } + /* Wait until message completion to increment in_msg_seq */ + + /* Reassemble if current message is fragmented or reassembly is + * already in progress */ + if( ssl->in_msglen < ssl->in_hslen || + memcmp( ssl->in_msg + 6, "\0\0\0", 3 ) != 0 || + memcmp( ssl->in_msg + 9, ssl->in_msg + 1, 3 ) != 0 || + ( ssl->handshake != NULL && ssl->handshake->hs_msg != NULL ) ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "found fragmented DTLS handshake message" ) ); + + if( ( ret = ssl_reassemble_dtls_handshake( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "ssl_reassemble_dtls_handshake", ret ); + return( ret ); + } + } + } + else +#endif /* MBEDTLS_SSL_PROTO_DTLS */ + /* With TLS we don't handle fragmentation (for now) */ + if( ssl->in_msglen < ssl->in_hslen ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "TLS handshake fragmentation not supported" ) ); + return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); + } + + return( 0 ); +} + +void mbedtls_ssl_update_handshake_status( mbedtls_ssl_context *ssl ) +{ + + if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER && + ssl->handshake != NULL ) + { + ssl->handshake->update_checksum( ssl, ssl->in_msg, ssl->in_hslen ); + } + + /* Handshake message is complete, increment counter */ +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && + ssl->handshake != NULL ) + { + ssl->handshake->in_msg_seq++; + } +#endif +} + +/* + * DTLS anti-replay: RFC 6347 4.1.2.6 + * + * in_window is a field of bits numbered from 0 (lsb) to 63 (msb). + * Bit n is set iff record number in_window_top - n has been seen. + * + * Usually, in_window_top is the last record number seen and the lsb of + * in_window is set. The only exception is the initial state (record number 0 + * not seen yet). + */ +#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) +static void ssl_dtls_replay_reset( mbedtls_ssl_context *ssl ) +{ + ssl->in_window_top = 0; + ssl->in_window = 0; +} + +static inline uint64_t ssl_load_six_bytes( unsigned char *buf ) +{ + return( ( (uint64_t) buf[0] << 40 ) | + ( (uint64_t) buf[1] << 32 ) | + ( (uint64_t) buf[2] << 24 ) | + ( (uint64_t) buf[3] << 16 ) | + ( (uint64_t) buf[4] << 8 ) | + ( (uint64_t) buf[5] ) ); +} + +/* + * Return 0 if sequence number is acceptable, -1 otherwise + */ +int mbedtls_ssl_dtls_replay_check( mbedtls_ssl_context *ssl ) +{ + uint64_t rec_seqnum = ssl_load_six_bytes( ssl->in_ctr + 2 ); + uint64_t bit; + + if( ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED ) + return( 0 ); + + if( rec_seqnum > ssl->in_window_top ) + return( 0 ); + + bit = ssl->in_window_top - rec_seqnum; + + if( bit >= 64 ) + return( -1 ); + + if( ( ssl->in_window & ( (uint64_t) 1 << bit ) ) != 0 ) + return( -1 ); + + return( 0 ); +} + +/* + * Update replay window on new validated record + */ +void mbedtls_ssl_dtls_replay_update( mbedtls_ssl_context *ssl ) +{ + uint64_t rec_seqnum = ssl_load_six_bytes( ssl->in_ctr + 2 ); + + if( ssl->conf->anti_replay == MBEDTLS_SSL_ANTI_REPLAY_DISABLED ) + return; + + if( rec_seqnum > ssl->in_window_top ) + { + /* Update window_top and the contents of the window */ + uint64_t shift = rec_seqnum - ssl->in_window_top; + + if( shift >= 64 ) + ssl->in_window = 1; + else + { + ssl->in_window <<= shift; + ssl->in_window |= 1; + } + + ssl->in_window_top = rec_seqnum; + } + else + { + /* Mark that number as seen in the current window */ + uint64_t bit = ssl->in_window_top - rec_seqnum; + + if( bit < 64 ) /* Always true, but be extra sure */ + ssl->in_window |= (uint64_t) 1 << bit; + } +} +#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */ + +#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C) +/* Forward declaration */ +static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial ); + +/* + * Without any SSL context, check if a datagram looks like a ClientHello with + * a valid cookie, and if it doesn't, generate a HelloVerifyRequest message. + * Both input and output include full DTLS headers. + * + * - if cookie is valid, return 0 + * - if ClientHello looks superficially valid but cookie is not, + * fill obuf and set olen, then + * return MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED + * - otherwise return a specific error code + */ +static int ssl_check_dtls_clihlo_cookie( + mbedtls_ssl_cookie_write_t *f_cookie_write, + mbedtls_ssl_cookie_check_t *f_cookie_check, + void *p_cookie, + const unsigned char *cli_id, size_t cli_id_len, + const unsigned char *in, size_t in_len, + unsigned char *obuf, size_t buf_len, size_t *olen ) +{ + size_t sid_len, cookie_len; + unsigned char *p; + + if( f_cookie_write == NULL || f_cookie_check == NULL ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + /* + * Structure of ClientHello with record and handshake headers, + * and expected values. We don't need to check a lot, more checks will be + * done when actually parsing the ClientHello - skipping those checks + * avoids code duplication and does not make cookie forging any easier. + * + * 0-0 ContentType type; copied, must be handshake + * 1-2 ProtocolVersion version; copied + * 3-4 uint16 epoch; copied, must be 0 + * 5-10 uint48 sequence_number; copied + * 11-12 uint16 length; (ignored) + * + * 13-13 HandshakeType msg_type; (ignored) + * 14-16 uint24 length; (ignored) + * 17-18 uint16 message_seq; copied + * 19-21 uint24 fragment_offset; copied, must be 0 + * 22-24 uint24 fragment_length; (ignored) + * + * 25-26 ProtocolVersion client_version; (ignored) + * 27-58 Random random; (ignored) + * 59-xx SessionID session_id; 1 byte len + sid_len content + * 60+ opaque cookie<0..2^8-1>; 1 byte len + content + * ... + * + * Minimum length is 61 bytes. + */ + if( in_len < 61 || + in[0] != MBEDTLS_SSL_MSG_HANDSHAKE || + in[3] != 0 || in[4] != 0 || + in[19] != 0 || in[20] != 0 || in[21] != 0 ) + { + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + } + + sid_len = in[59]; + if( sid_len > in_len - 61 ) + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + + cookie_len = in[60 + sid_len]; + if( cookie_len > in_len - 60 ) + return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO ); + + if( f_cookie_check( p_cookie, in + sid_len + 61, cookie_len, + cli_id, cli_id_len ) == 0 ) + { + /* Valid cookie */ + return( 0 ); + } + + /* + * If we get here, we've got an invalid cookie, let's prepare HVR. + * + * 0-0 ContentType type; copied + * 1-2 ProtocolVersion version; copied + * 3-4 uint16 epoch; copied + * 5-10 uint48 sequence_number; copied + * 11-12 uint16 length; olen - 13 + * + * 13-13 HandshakeType msg_type; hello_verify_request + * 14-16 uint24 length; olen - 25 + * 17-18 uint16 message_seq; copied + * 19-21 uint24 fragment_offset; copied + * 22-24 uint24 fragment_length; olen - 25 + * + * 25-26 ProtocolVersion server_version; 0xfe 0xff + * 27-27 opaque cookie<0..2^8-1>; cookie_len = olen - 27, cookie + * + * Minimum length is 28. + */ + if( buf_len < 28 ) + return( MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL ); + + /* Copy most fields and adapt others */ + memcpy( obuf, in, 25 ); + obuf[13] = MBEDTLS_SSL_HS_HELLO_VERIFY_REQUEST; + obuf[25] = 0xfe; + obuf[26] = 0xff; + + /* Generate and write actual cookie */ + p = obuf + 28; + if( f_cookie_write( p_cookie, + &p, obuf + buf_len, cli_id, cli_id_len ) != 0 ) + { + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + + *olen = p - obuf; + + /* Go back and fill length fields */ + obuf[27] = (unsigned char)( *olen - 28 ); + + obuf[14] = obuf[22] = (unsigned char)( ( *olen - 25 ) >> 16 ); + obuf[15] = obuf[23] = (unsigned char)( ( *olen - 25 ) >> 8 ); + obuf[16] = obuf[24] = (unsigned char)( ( *olen - 25 ) ); + + obuf[11] = (unsigned char)( ( *olen - 13 ) >> 8 ); + obuf[12] = (unsigned char)( ( *olen - 13 ) ); + + return( MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED ); +} + +/* + * Handle possible client reconnect with the same UDP quadruplet + * (RFC 6347 Section 4.2.8). + * + * Called by ssl_parse_record_header() in case we receive an epoch 0 record + * that looks like a ClientHello. + * + * - if the input looks like a ClientHello without cookies, + * send back HelloVerifyRequest, then + * return MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED + * - if the input looks like a ClientHello with a valid cookie, + * reset the session of the current context, and + * return MBEDTLS_ERR_SSL_CLIENT_RECONNECT + * - if anything goes wrong, return a specific error code + * + * mbedtls_ssl_read_record() will ignore the record if anything else than + * MBEDTLS_ERR_SSL_CLIENT_RECONNECT or 0 is returned, although this function + * cannot not return 0. + */ +static int ssl_handle_possible_reconnect( mbedtls_ssl_context *ssl ) +{ + int ret; + size_t len; + + ret = ssl_check_dtls_clihlo_cookie( + ssl->conf->f_cookie_write, + ssl->conf->f_cookie_check, + ssl->conf->p_cookie, + ssl->cli_id, ssl->cli_id_len, + ssl->in_buf, ssl->in_left, + ssl->out_buf, MBEDTLS_SSL_MAX_CONTENT_LEN, &len ); + + MBEDTLS_SSL_DEBUG_RET( 2, "ssl_check_dtls_clihlo_cookie", ret ); + + if( ret == MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED ) + { + /* Don't check write errors as we can't do anything here. + * If the error is permanent we'll catch it later, + * if it's not, then hopefully it'll work next time. */ + (void) ssl->f_send( ssl->p_bio, ssl->out_buf, len ); + + return( MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED ); + } + + if( ret == 0 ) + { + /* Got a valid cookie, partially reset context */ + if( ( ret = ssl_session_reset_int( ssl, 1 ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "reset", ret ); + return( ret ); + } + + return( MBEDTLS_ERR_SSL_CLIENT_RECONNECT ); + } + + return( ret ); +} +#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */ + +/* + * ContentType type; + * ProtocolVersion version; + * uint16 epoch; // DTLS only + * uint48 sequence_number; // DTLS only + * uint16 length; + * + * Return 0 if header looks sane (and, for DTLS, the record is expected) + * MBEDTLS_ERR_SSL_INVALID_RECORD if the header looks bad, + * MBEDTLS_ERR_SSL_UNEXPECTED_RECORD (DTLS only) if sane but unexpected. + * + * With DTLS, mbedtls_ssl_read_record() will: + * 1. proceed with the record if this function returns 0 + * 2. drop only the current record if this function returns UNEXPECTED_RECORD + * 3. return CLIENT_RECONNECT if this function return that value + * 4. drop the whole datagram if this function returns anything else. + * Point 2 is needed when the peer is resending, and we have already received + * the first record from a datagram but are still waiting for the others. + */ +static int ssl_parse_record_header( mbedtls_ssl_context *ssl ) +{ + int ret; + int major_ver, minor_ver; + + MBEDTLS_SSL_DEBUG_BUF( 4, "input record header", ssl->in_hdr, mbedtls_ssl_hdr_len( ssl ) ); + + ssl->in_msgtype = ssl->in_hdr[0]; + ssl->in_msglen = ( ssl->in_len[0] << 8 ) | ssl->in_len[1]; + mbedtls_ssl_read_version( &major_ver, &minor_ver, ssl->conf->transport, ssl->in_hdr + 1 ); + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "input record: msgtype = %d, " + "version = [%d:%d], msglen = %d", + ssl->in_msgtype, + major_ver, minor_ver, ssl->in_msglen ) ); + + /* Check record type */ + if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE && + ssl->in_msgtype != MBEDTLS_SSL_MSG_ALERT && + ssl->in_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC && + ssl->in_msgtype != MBEDTLS_SSL_MSG_APPLICATION_DATA ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "unknown record type" ) ); + + if( ( ret = mbedtls_ssl_send_alert_message( ssl, + MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_UNEXPECTED_MESSAGE ) ) != 0 ) + { + return( ret ); + } + + return( MBEDTLS_ERR_SSL_INVALID_RECORD ); + } + + /* Check version */ + if( major_ver != ssl->major_ver ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "major version mismatch" ) ); + return( MBEDTLS_ERR_SSL_INVALID_RECORD ); + } + + if( minor_ver > ssl->conf->max_minor_ver ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "minor version mismatch" ) ); + return( MBEDTLS_ERR_SSL_INVALID_RECORD ); + } + + /* Check length against the size of our buffer */ + if( ssl->in_msglen > MBEDTLS_SSL_BUFFER_LEN + - (size_t)( ssl->in_msg - ssl->in_buf ) ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) ); + return( MBEDTLS_ERR_SSL_INVALID_RECORD ); + } + + /* Check length against bounds of the current transform and version */ + if( ssl->transform_in == NULL ) + { + if( ssl->in_msglen < 1 || + ssl->in_msglen > MBEDTLS_SSL_MAX_CONTENT_LEN ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) ); + return( MBEDTLS_ERR_SSL_INVALID_RECORD ); + } + } + else + { + if( ssl->in_msglen < ssl->transform_in->minlen ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) ); + return( MBEDTLS_ERR_SSL_INVALID_RECORD ); + } + +#if defined(MBEDTLS_SSL_PROTO_SSL3) + if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 && + ssl->in_msglen > ssl->transform_in->minlen + MBEDTLS_SSL_MAX_CONTENT_LEN ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) ); + return( MBEDTLS_ERR_SSL_INVALID_RECORD ); + } +#endif +#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ + defined(MBEDTLS_SSL_PROTO_TLS1_2) + /* + * TLS encrypted messages can have up to 256 bytes of padding + */ + if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 && + ssl->in_msglen > ssl->transform_in->minlen + + MBEDTLS_SSL_MAX_CONTENT_LEN + 256 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) ); + return( MBEDTLS_ERR_SSL_INVALID_RECORD ); + } +#endif + } + + /* + * DTLS-related tests done last, because most of them may result in + * silently dropping the record (but not the whole datagram), and we only + * want to consider that after ensuring that the "basic" fields (type, + * version, length) are sane. + */ +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + { + unsigned int rec_epoch = ( ssl->in_ctr[0] << 8 ) | ssl->in_ctr[1]; + + /* Drop unexpected ChangeCipherSpec messages */ + if( ssl->in_msgtype == MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC && + ssl->state != MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC && + ssl->state != MBEDTLS_SSL_SERVER_CHANGE_CIPHER_SPEC ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping unexpected ChangeCipherSpec" ) ); + return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD ); + } + + /* Drop unexpected ApplicationData records, + * except at the beginning of renegotiations */ + if( ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA && + ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER +#if defined(MBEDTLS_SSL_RENEGOTIATION) + && ! ( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS && + ssl->state == MBEDTLS_SSL_SERVER_HELLO ) +#endif + ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "dropping unexpected ApplicationData" ) ); + return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD ); + } + + /* Check epoch (and sequence number) with DTLS */ + if( rec_epoch != ssl->in_epoch ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "record from another epoch: " + "expected %d, received %d", + ssl->in_epoch, rec_epoch ) ); + +#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) && defined(MBEDTLS_SSL_SRV_C) + /* + * Check for an epoch 0 ClientHello. We can't use in_msg here to + * access the first byte of record content (handshake type), as we + * have an active transform (possibly iv_len != 0), so use the + * fact that the record header len is 13 instead. + */ + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && + ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER && + rec_epoch == 0 && + ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && + ssl->in_left > 13 && + ssl->in_buf[13] == MBEDTLS_SSL_HS_CLIENT_HELLO ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "possible client reconnect " + "from the same port" ) ); + return( ssl_handle_possible_reconnect( ssl ) ); + } + else +#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE && MBEDTLS_SSL_SRV_C */ + return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD ); + } + +#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) + /* Replay detection only works for the current epoch */ + if( rec_epoch == ssl->in_epoch && + mbedtls_ssl_dtls_replay_check( ssl ) != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "replayed record" ) ); + return( MBEDTLS_ERR_SSL_UNEXPECTED_RECORD ); + } +#endif + } +#endif /* MBEDTLS_SSL_PROTO_DTLS */ + + return( 0 ); +} + +/* + * If applicable, decrypt (and decompress) record content + */ +static int ssl_prepare_record_content( mbedtls_ssl_context *ssl ) +{ + int ret, done = 0; + + MBEDTLS_SSL_DEBUG_BUF( 4, "input record from network", + ssl->in_hdr, mbedtls_ssl_hdr_len( ssl ) + ssl->in_msglen ); + +#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) + if( mbedtls_ssl_hw_record_read != NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_read()" ) ); + + ret = mbedtls_ssl_hw_record_read( ssl ); + if( ret != 0 && ret != MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_read", ret ); + return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); + } + + if( ret == 0 ) + done = 1; + } +#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ + if( !done && ssl->transform_in != NULL ) + { + if( ( ret = ssl_decrypt_buf( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "ssl_decrypt_buf", ret ); + return( ret ); + } + + MBEDTLS_SSL_DEBUG_BUF( 4, "input payload after decrypt", + ssl->in_msg, ssl->in_msglen ); + + if( ssl->in_msglen > MBEDTLS_SSL_MAX_CONTENT_LEN ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad message length" ) ); + return( MBEDTLS_ERR_SSL_INVALID_RECORD ); + } + } + +#if defined(MBEDTLS_ZLIB_SUPPORT) + if( ssl->transform_in != NULL && + ssl->session_in->compression == MBEDTLS_SSL_COMPRESS_DEFLATE ) + { + if( ( ret = ssl_decompress_buf( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "ssl_decompress_buf", ret ); + return( ret ); + } + } +#endif /* MBEDTLS_ZLIB_SUPPORT */ + +#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + { + mbedtls_ssl_dtls_replay_update( ssl ); + } +#endif + + return( 0 ); +} + +static void ssl_handshake_wrapup_free_hs_transform( mbedtls_ssl_context *ssl ); + +/* + * Read a record. + * + * Silently ignore non-fatal alert (and for DTLS, invalid records as well, + * RFC 6347 4.1.2.7) and continue reading until a valid record is found. + * + */ +int mbedtls_ssl_read_record( mbedtls_ssl_context *ssl ) +{ + int ret; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> read record" ) ); + + do { + + if( ( ret = mbedtls_ssl_read_record_layer( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ssl_read_record_layer" ), ret ); + return( ret ); + } + + ret = mbedtls_ssl_handle_message_type( ssl ); + + } while( MBEDTLS_ERR_SSL_NON_FATAL == ret ); + + if( 0 != ret ) + { + MBEDTLS_SSL_DEBUG_RET( 1, ( "mbedtls_ssl_handle_message_type" ), ret ); + return( ret ); + } + + if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE ) + { + mbedtls_ssl_update_handshake_status( ssl ); + } + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= read record" ) ); + + return( 0 ); +} + +int mbedtls_ssl_read_record_layer( mbedtls_ssl_context *ssl ) +{ + int ret; + + if( ssl->in_hslen != 0 && ssl->in_hslen < ssl->in_msglen ) + { + /* + * Get next Handshake message in the current record + */ + ssl->in_msglen -= ssl->in_hslen; + + memmove( ssl->in_msg, ssl->in_msg + ssl->in_hslen, + ssl->in_msglen ); + + MBEDTLS_SSL_DEBUG_BUF( 4, "remaining content in record", + ssl->in_msg, ssl->in_msglen ); + + return( 0 ); + } + + ssl->in_hslen = 0; + + /* + * Read the record header and parse it + */ +#if defined(MBEDTLS_SSL_PROTO_DTLS) +read_record_header: +#endif + + if( ( ret = mbedtls_ssl_fetch_input( ssl, mbedtls_ssl_hdr_len( ssl ) ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret ); + return( ret ); + } + + if( ( ret = ssl_parse_record_header( ssl ) ) != 0 ) + { +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && + ret != MBEDTLS_ERR_SSL_CLIENT_RECONNECT ) + { + if( ret == MBEDTLS_ERR_SSL_UNEXPECTED_RECORD ) + { + /* Skip unexpected record (but not whole datagram) */ + ssl->next_record_offset = ssl->in_msglen + + mbedtls_ssl_hdr_len( ssl ); + + MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding unexpected record " + "(header)" ) ); + } + else + { + /* Skip invalid record and the rest of the datagram */ + ssl->next_record_offset = 0; + ssl->in_left = 0; + + MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding invalid record " + "(header)" ) ); + } + + /* Get next record */ + goto read_record_header; + } +#endif + return( ret ); + } + + /* + * Read and optionally decrypt the message contents + */ + if( ( ret = mbedtls_ssl_fetch_input( ssl, + mbedtls_ssl_hdr_len( ssl ) + ssl->in_msglen ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_fetch_input", ret ); + return( ret ); + } + + /* Done reading this record, get ready for the next one */ +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + ssl->next_record_offset = ssl->in_msglen + mbedtls_ssl_hdr_len( ssl ); + else +#endif + ssl->in_left = 0; + + if( ( ret = ssl_prepare_record_content( ssl ) ) != 0 ) + { +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + { + /* Silently discard invalid records */ + if( ret == MBEDTLS_ERR_SSL_INVALID_RECORD || + ret == MBEDTLS_ERR_SSL_INVALID_MAC ) + { + /* Except when waiting for Finished as a bad mac here + * probably means something went wrong in the handshake + * (eg wrong psk used, mitm downgrade attempt, etc.) */ + if( ssl->state == MBEDTLS_SSL_CLIENT_FINISHED || + ssl->state == MBEDTLS_SSL_SERVER_FINISHED ) + { +#if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES) + if( ret == MBEDTLS_ERR_SSL_INVALID_MAC ) + { + mbedtls_ssl_send_alert_message( ssl, + MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC ); + } +#endif + return( ret ); + } + +#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) + if( ssl->conf->badmac_limit != 0 && + ++ssl->badmac_seen >= ssl->conf->badmac_limit ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "too many records with bad MAC" ) ); + return( MBEDTLS_ERR_SSL_INVALID_MAC ); + } +#endif + + MBEDTLS_SSL_DEBUG_MSG( 1, ( "discarding invalid record (mac)" ) ); + goto read_record_header; + } + + return( ret ); + } + else +#endif + { + /* Error out (and send alert) on invalid records */ +#if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES) + if( ret == MBEDTLS_ERR_SSL_INVALID_MAC ) + { + mbedtls_ssl_send_alert_message( ssl, + MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_BAD_RECORD_MAC ); + } +#endif + return( ret ); + } + } + + /* + * When we sent the last flight of the handshake, we MUST respond to a + * retransmit of the peer's previous flight with a retransmit. (In + * practice, only the Finished message will make it, other messages + * including CCS use the old transform so they're dropped as invalid.) + * + * If the record we received is not a handshake message, however, it + * means the peer received our last flight so we can clean up + * handshake info. + * + * This check needs to be done before prepare_handshake() due to an edge + * case: if the client immediately requests renegotiation, this + * finishes the current handshake first, avoiding the new ClientHello + * being mistaken for an ancient message in the current handshake. + */ +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && + ssl->handshake != NULL && + ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER ) + { + if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && + ssl->in_msg[0] == MBEDTLS_SSL_HS_FINISHED ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "received retransmit of last flight" ) ); + + if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_resend", ret ); + return( ret ); + } + + return( MBEDTLS_ERR_SSL_WANT_READ ); + } + else + { + ssl_handshake_wrapup_free_hs_transform( ssl ); + } + } +#endif + + return( 0 ); +} + +int mbedtls_ssl_handle_message_type( mbedtls_ssl_context *ssl ) +{ + int ret; + + /* + * Handle particular types of records + */ + if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE ) + { + if( ( ret = mbedtls_ssl_prepare_handshake_record( ssl ) ) != 0 ) + { + return( ret ); + } + } + + if( ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "got an alert message, type: [%d:%d]", + ssl->in_msg[0], ssl->in_msg[1] ) ); + + /* + * Ignore non-fatal alerts, except close_notify and no_renegotiation + */ + if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_FATAL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "is a fatal alert message (msg %d)", + ssl->in_msg[1] ) ); + return( MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE ); + } + + if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING && + ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a close notify message" ) ); + return( MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY ); + } + +#if defined(MBEDTLS_SSL_RENEGOTIATION_ENABLED) + if( ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING && + ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a SSLv3 no_cert" ) ); + /* Will be handled when trying to parse ServerHello */ + return( 0 ); + } +#endif + +#if defined(MBEDTLS_SSL_PROTO_SSL3) && defined(MBEDTLS_SSL_SRV_C) + if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 && + ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && + ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING && + ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_CERT ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "is a SSLv3 no_cert" ) ); + /* Will be handled in mbedtls_ssl_parse_certificate() */ + return( 0 ); + } +#endif /* MBEDTLS_SSL_PROTO_SSL3 && MBEDTLS_SSL_SRV_C */ + + /* Silently ignore: fetch new message */ + return MBEDTLS_ERR_SSL_NON_FATAL; + } + + return( 0 ); +} + +int mbedtls_ssl_send_fatal_handshake_failure( mbedtls_ssl_context *ssl ) +{ + int ret; + + if( ( ret = mbedtls_ssl_send_alert_message( ssl, + MBEDTLS_SSL_ALERT_LEVEL_FATAL, + MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ) ) != 0 ) + { + return( ret ); + } + + return( 0 ); +} + +int mbedtls_ssl_send_alert_message( mbedtls_ssl_context *ssl, + unsigned char level, + unsigned char message ) +{ + int ret; + + if( ssl == NULL || ssl->conf == NULL ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> send alert message" ) ); + + ssl->out_msgtype = MBEDTLS_SSL_MSG_ALERT; + ssl->out_msglen = 2; + ssl->out_msg[0] = level; + ssl->out_msg[1] = message; + + if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); + return( ret ); + } + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= send alert message" ) ); + + return( 0 ); +} + +/* + * Handshake functions + */ +#if !defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) && \ + !defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) +int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl ) +{ + const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate" ) ); + + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) ); + ssl->state++; + return( 0 ); + } + + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); +} + +int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl ) +{ + const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate" ) ); + + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) ); + ssl->state++; + return( 0 ); + } + + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); +} +#else +int mbedtls_ssl_write_certificate( mbedtls_ssl_context *ssl ) +{ + int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; + size_t i, n; + const mbedtls_x509_crt *crt; + const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write certificate" ) ); + + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) ); + ssl->state++; + return( 0 ); + } + +#if defined(MBEDTLS_SSL_CLI_C) + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) + { + if( ssl->client_auth == 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip write certificate" ) ); + ssl->state++; + return( 0 ); + } + +#if defined(MBEDTLS_SSL_PROTO_SSL3) + /* + * If using SSLv3 and got no cert, send an Alert message + * (otherwise an empty Certificate message will be sent). + */ + if( mbedtls_ssl_own_cert( ssl ) == NULL && + ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) + { + ssl->out_msglen = 2; + ssl->out_msgtype = MBEDTLS_SSL_MSG_ALERT; + ssl->out_msg[0] = MBEDTLS_SSL_ALERT_LEVEL_WARNING; + ssl->out_msg[1] = MBEDTLS_SSL_ALERT_MSG_NO_CERT; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "got no certificate to send" ) ); + goto write_msg; + } +#endif /* MBEDTLS_SSL_PROTO_SSL3 */ + } +#endif /* MBEDTLS_SSL_CLI_C */ +#if defined(MBEDTLS_SSL_SRV_C) + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) + { + if( mbedtls_ssl_own_cert( ssl ) == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no certificate to send" ) ); + return( MBEDTLS_ERR_SSL_CERTIFICATE_REQUIRED ); + } + } +#endif + + MBEDTLS_SSL_DEBUG_CRT( 3, "own certificate", mbedtls_ssl_own_cert( ssl ) ); + + /* + * 0 . 0 handshake type + * 1 . 3 handshake length + * 4 . 6 length of all certs + * 7 . 9 length of cert. 1 + * 10 . n-1 peer certificate + * n . n+2 length of cert. 2 + * n+3 . ... upper level cert, etc. + */ + i = 7; + crt = mbedtls_ssl_own_cert( ssl ); + + while( crt != NULL ) + { + n = crt->raw.len; + if( n > MBEDTLS_SSL_MAX_CONTENT_LEN - 3 - i ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "certificate too large, %d > %d", + i + 3 + n, MBEDTLS_SSL_MAX_CONTENT_LEN ) ); + return( MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE ); + } + + ssl->out_msg[i ] = (unsigned char)( n >> 16 ); + ssl->out_msg[i + 1] = (unsigned char)( n >> 8 ); + ssl->out_msg[i + 2] = (unsigned char)( n ); + + i += 3; memcpy( ssl->out_msg + i, crt->raw.p, n ); + i += n; crt = crt->next; + } + + ssl->out_msg[4] = (unsigned char)( ( i - 7 ) >> 16 ); + ssl->out_msg[5] = (unsigned char)( ( i - 7 ) >> 8 ); + ssl->out_msg[6] = (unsigned char)( ( i - 7 ) ); + + ssl->out_msglen = i; + ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; + ssl->out_msg[0] = MBEDTLS_SSL_HS_CERTIFICATE; + +#if defined(MBEDTLS_SSL_PROTO_SSL3) && defined(MBEDTLS_SSL_CLI_C) +write_msg: +#endif + + ssl->state++; + + if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); + return( ret ); + } + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write certificate" ) ); + + return( ret ); +} + +int mbedtls_ssl_parse_certificate( mbedtls_ssl_context *ssl ) +{ + int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; + size_t i, n; + const mbedtls_ssl_ciphersuite_t *ciphersuite_info = ssl->transform_negotiate->ciphersuite_info; + int authmode = ssl->conf->authmode; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse certificate" ) ); + + if( ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_DHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECDHE_PSK || + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_ECJPAKE ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) ); + ssl->state++; + return( 0 ); + } + +#if defined(MBEDTLS_SSL_SRV_C) + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && + ciphersuite_info->key_exchange == MBEDTLS_KEY_EXCHANGE_RSA_PSK ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) ); + ssl->state++; + return( 0 ); + } + +#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) + if( ssl->handshake->sni_authmode != MBEDTLS_SSL_VERIFY_UNSET ) + authmode = ssl->handshake->sni_authmode; +#endif + + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && + authmode == MBEDTLS_SSL_VERIFY_NONE ) + { + ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_SKIP_VERIFY; + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= skip parse certificate" ) ); + ssl->state++; + return( 0 ); + } +#endif + + if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); + return( ret ); + } + + ssl->state++; + +#if defined(MBEDTLS_SSL_SRV_C) +#if defined(MBEDTLS_SSL_PROTO_SSL3) + /* + * Check if the client sent an empty certificate + */ + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && + ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) + { + if( ssl->in_msglen == 2 && + ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT && + ssl->in_msg[0] == MBEDTLS_SSL_ALERT_LEVEL_WARNING && + ssl->in_msg[1] == MBEDTLS_SSL_ALERT_MSG_NO_CERT ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "SSLv3 client has no certificate" ) ); + + ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_MISSING; + if( authmode == MBEDTLS_SSL_VERIFY_OPTIONAL ) + return( 0 ); + else + return( MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE ); + } + } +#endif /* MBEDTLS_SSL_PROTO_SSL3 */ + +#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ + defined(MBEDTLS_SSL_PROTO_TLS1_2) + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && + ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_0 ) + { + if( ssl->in_hslen == 3 + mbedtls_ssl_hs_hdr_len( ssl ) && + ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE && + ssl->in_msg[0] == MBEDTLS_SSL_HS_CERTIFICATE && + memcmp( ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ), "\0\0\0", 3 ) == 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "TLSv1 client has no certificate" ) ); + + ssl->session_negotiate->verify_result = MBEDTLS_X509_BADCERT_MISSING; + if( authmode == MBEDTLS_SSL_VERIFY_OPTIONAL ) + return( 0 ); + else + return( MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE ); + } + } +#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || \ + MBEDTLS_SSL_PROTO_TLS1_2 */ +#endif /* MBEDTLS_SSL_SRV_C */ + + if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) ); + return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); + } + + if( ssl->in_msg[0] != MBEDTLS_SSL_HS_CERTIFICATE || + ssl->in_hslen < mbedtls_ssl_hs_hdr_len( ssl ) + 3 + 3 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ); + } + + i = mbedtls_ssl_hs_hdr_len( ssl ); + + /* + * Same message structure as in mbedtls_ssl_write_certificate() + */ + n = ( ssl->in_msg[i+1] << 8 ) | ssl->in_msg[i+2]; + + if( ssl->in_msg[i] != 0 || + ssl->in_hslen != n + 3 + mbedtls_ssl_hs_hdr_len( ssl ) ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ); + } + + /* In case we tried to reuse a session but it failed */ + if( ssl->session_negotiate->peer_cert != NULL ) + { + mbedtls_x509_crt_free( ssl->session_negotiate->peer_cert ); + mbedtls_free( ssl->session_negotiate->peer_cert ); + } + + if( ( ssl->session_negotiate->peer_cert = mbedtls_calloc( 1, + sizeof( mbedtls_x509_crt ) ) ) == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", + sizeof( mbedtls_x509_crt ) ) ); + return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); + } + + mbedtls_x509_crt_init( ssl->session_negotiate->peer_cert ); + + i += 3; + + while( i < ssl->in_hslen ) + { + if( ssl->in_msg[i] != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ); + } + + n = ( (unsigned int) ssl->in_msg[i + 1] << 8 ) + | (unsigned int) ssl->in_msg[i + 2]; + i += 3; + + if( n < 128 || i + n > ssl->in_hslen ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ); + } + + ret = mbedtls_x509_crt_parse_der( ssl->session_negotiate->peer_cert, + ssl->in_msg + i, n ); + if( 0 != ret && ( MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG + MBEDTLS_ERR_OID_NOT_FOUND ) != ret ) + { + MBEDTLS_SSL_DEBUG_RET( 1, " mbedtls_x509_crt_parse_der", ret ); + return( ret ); + } + + i += n; + } + + MBEDTLS_SSL_DEBUG_CRT( 3, "peer certificate", ssl->session_negotiate->peer_cert ); + + /* + * On client, make sure the server cert doesn't change during renego to + * avoid "triple handshake" attack: https://secure-resumption.com/ + */ +#if defined(MBEDTLS_SSL_RENEGOTIATION) && defined(MBEDTLS_SSL_CLI_C) + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT && + ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS ) + { + if( ssl->session->peer_cert == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "new server cert during renegotiation" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ); + } + + if( ssl->session->peer_cert->raw.len != + ssl->session_negotiate->peer_cert->raw.len || + memcmp( ssl->session->peer_cert->raw.p, + ssl->session_negotiate->peer_cert->raw.p, + ssl->session->peer_cert->raw.len ) != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "server cert changed during renegotiation" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE ); + } + } +#endif /* MBEDTLS_SSL_RENEGOTIATION && MBEDTLS_SSL_CLI_C */ + + if( authmode != MBEDTLS_SSL_VERIFY_NONE ) + { + mbedtls_x509_crt *ca_chain; + mbedtls_x509_crl *ca_crl; + +#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) + if( ssl->handshake->sni_ca_chain != NULL ) + { + ca_chain = ssl->handshake->sni_ca_chain; + ca_crl = ssl->handshake->sni_ca_crl; + } + else +#endif + { + ca_chain = ssl->conf->ca_chain; + ca_crl = ssl->conf->ca_crl; + } + + if( ca_chain == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "got no CA chain" ) ); + return( MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED ); + } + + /* + * Main check: verify certificate + */ + ret = mbedtls_x509_crt_verify_with_profile( + ssl->session_negotiate->peer_cert, + ca_chain, ca_crl, + ssl->conf->cert_profile, + ssl->hostname, + &ssl->session_negotiate->verify_result, + ssl->conf->f_vrfy, ssl->conf->p_vrfy ); + + if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "x509_verify_cert", ret ); + } + + /* + * Secondary checks: always done, but change 'ret' only if it was 0 + */ + +#if defined(MBEDTLS_ECP_C) + { + const mbedtls_pk_context *pk = &ssl->session_negotiate->peer_cert->pk; + + /* If certificate uses an EC key, make sure the curve is OK */ + if( mbedtls_pk_can_do( pk, MBEDTLS_PK_ECKEY ) && + mbedtls_ssl_check_curve( ssl, mbedtls_pk_ec( *pk )->grp.id ) != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate (EC key curve)" ) ); + if( ret == 0 ) + ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE; + } + } +#endif /* MBEDTLS_ECP_C */ + + if( mbedtls_ssl_check_cert_usage( ssl->session_negotiate->peer_cert, + ciphersuite_info, + ! ssl->conf->endpoint, + &ssl->session_negotiate->verify_result ) != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad certificate (usage extensions)" ) ); + if( ret == 0 ) + ret = MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE; + } + + if( authmode == MBEDTLS_SSL_VERIFY_OPTIONAL ) + ret = 0; + } + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse certificate" ) ); + + return( ret ); +} +#endif /* !MBEDTLS_KEY_EXCHANGE_RSA_ENABLED + !MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED + !MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED + !MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED + !MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED + !MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED + !MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ + +int mbedtls_ssl_write_change_cipher_spec( mbedtls_ssl_context *ssl ) +{ + int ret; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write change cipher spec" ) ); + + ssl->out_msgtype = MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC; + ssl->out_msglen = 1; + ssl->out_msg[0] = 1; + + ssl->state++; + + if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); + return( ret ); + } + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write change cipher spec" ) ); + + return( 0 ); +} + +int mbedtls_ssl_parse_change_cipher_spec( mbedtls_ssl_context *ssl ) +{ + int ret; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse change cipher spec" ) ); + + if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); + return( ret ); + } + + if( ssl->in_msgtype != MBEDTLS_SSL_MSG_CHANGE_CIPHER_SPEC ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad change cipher spec message" ) ); + return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); + } + + if( ssl->in_msglen != 1 || ssl->in_msg[0] != 1 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad change cipher spec message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC ); + } + + /* + * Switch to our negotiated transform and session parameters for inbound + * data. + */ + MBEDTLS_SSL_DEBUG_MSG( 3, ( "switching to new transform spec for inbound data" ) ); + ssl->transform_in = ssl->transform_negotiate; + ssl->session_in = ssl->session_negotiate; + +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + { +#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) + ssl_dtls_replay_reset( ssl ); +#endif + + /* Increment epoch */ + if( ++ssl->in_epoch == 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "DTLS epoch would wrap" ) ); + return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING ); + } + } + else +#endif /* MBEDTLS_SSL_PROTO_DTLS */ + memset( ssl->in_ctr, 0, 8 ); + + /* + * Set the in_msg pointer to the correct location based on IV length + */ + if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 ) + { + ssl->in_msg = ssl->in_iv + ssl->transform_negotiate->ivlen - + ssl->transform_negotiate->fixed_ivlen; + } + else + ssl->in_msg = ssl->in_iv; + +#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) + if( mbedtls_ssl_hw_record_activate != NULL ) + { + if( ( ret = mbedtls_ssl_hw_record_activate( ssl, MBEDTLS_SSL_CHANNEL_INBOUND ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_activate", ret ); + return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); + } + } +#endif + + ssl->state++; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse change cipher spec" ) ); + + return( 0 ); +} + +void mbedtls_ssl_optimize_checksum( mbedtls_ssl_context *ssl, + const mbedtls_ssl_ciphersuite_t *ciphersuite_info ) +{ + ((void) ciphersuite_info); + +#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ + defined(MBEDTLS_SSL_PROTO_TLS1_1) + if( ssl->minor_ver < MBEDTLS_SSL_MINOR_VERSION_3 ) + ssl->handshake->update_checksum = ssl_update_checksum_md5sha1; + else +#endif +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) +#if defined(MBEDTLS_SHA512_C) + if( ciphersuite_info->mac == MBEDTLS_MD_SHA384 ) + ssl->handshake->update_checksum = ssl_update_checksum_sha384; + else +#endif +#if defined(MBEDTLS_SHA256_C) + if( ciphersuite_info->mac != MBEDTLS_MD_SHA384 ) + ssl->handshake->update_checksum = ssl_update_checksum_sha256; + else +#endif +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return; + } +} + +void mbedtls_ssl_reset_checksum( mbedtls_ssl_context *ssl ) +{ +#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ + defined(MBEDTLS_SSL_PROTO_TLS1_1) + mbedtls_md5_starts( &ssl->handshake->fin_md5 ); + mbedtls_sha1_starts( &ssl->handshake->fin_sha1 ); +#endif +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) +#if defined(MBEDTLS_SHA256_C) + mbedtls_sha256_starts( &ssl->handshake->fin_sha256, 0 ); +#endif +#if defined(MBEDTLS_SHA512_C) + mbedtls_sha512_starts( &ssl->handshake->fin_sha512, 1 ); +#endif +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ +} + +static void ssl_update_checksum_start( mbedtls_ssl_context *ssl, + const unsigned char *buf, size_t len ) +{ +#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ + defined(MBEDTLS_SSL_PROTO_TLS1_1) + mbedtls_md5_update( &ssl->handshake->fin_md5 , buf, len ); + mbedtls_sha1_update( &ssl->handshake->fin_sha1, buf, len ); +#endif +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) +#if defined(MBEDTLS_SHA256_C) + mbedtls_sha256_update( &ssl->handshake->fin_sha256, buf, len ); +#endif +#if defined(MBEDTLS_SHA512_C) + mbedtls_sha512_update( &ssl->handshake->fin_sha512, buf, len ); +#endif +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ +} + +#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ + defined(MBEDTLS_SSL_PROTO_TLS1_1) +static void ssl_update_checksum_md5sha1( mbedtls_ssl_context *ssl, + const unsigned char *buf, size_t len ) +{ + mbedtls_md5_update( &ssl->handshake->fin_md5 , buf, len ); + mbedtls_sha1_update( &ssl->handshake->fin_sha1, buf, len ); +} +#endif + +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) +#if defined(MBEDTLS_SHA256_C) +static void ssl_update_checksum_sha256( mbedtls_ssl_context *ssl, + const unsigned char *buf, size_t len ) +{ + mbedtls_sha256_update( &ssl->handshake->fin_sha256, buf, len ); +} +#endif + +#if defined(MBEDTLS_SHA512_C) +static void ssl_update_checksum_sha384( mbedtls_ssl_context *ssl, + const unsigned char *buf, size_t len ) +{ + mbedtls_sha512_update( &ssl->handshake->fin_sha512, buf, len ); +} +#endif +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ + +#if defined(MBEDTLS_SSL_PROTO_SSL3) +static void ssl_calc_finished_ssl( + mbedtls_ssl_context *ssl, unsigned char *buf, int from ) +{ + const char *sender; + mbedtls_md5_context md5; + mbedtls_sha1_context sha1; + + unsigned char padbuf[48]; + unsigned char md5sum[16]; + unsigned char sha1sum[20]; + + mbedtls_ssl_session *session = ssl->session_negotiate; + if( !session ) + session = ssl->session; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished ssl" ) ); + + mbedtls_md5_init( &md5 ); + mbedtls_sha1_init( &sha1 ); + + mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 ); + mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 ); + + /* + * SSLv3: + * hash = + * MD5( master + pad2 + + * MD5( handshake + sender + master + pad1 ) ) + * + SHA1( master + pad2 + + * SHA1( handshake + sender + master + pad1 ) ) + */ + +#if !defined(MBEDTLS_MD5_ALT) + MBEDTLS_SSL_DEBUG_BUF( 4, "finished md5 state", (unsigned char *) + md5.state, sizeof( md5.state ) ); +#endif + +#if !defined(MBEDTLS_SHA1_ALT) + MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha1 state", (unsigned char *) + sha1.state, sizeof( sha1.state ) ); +#endif + + sender = ( from == MBEDTLS_SSL_IS_CLIENT ) ? "CLNT" + : "SRVR"; + + memset( padbuf, 0x36, 48 ); + + mbedtls_md5_update( &md5, (const unsigned char *) sender, 4 ); + mbedtls_md5_update( &md5, session->master, 48 ); + mbedtls_md5_update( &md5, padbuf, 48 ); + mbedtls_md5_finish( &md5, md5sum ); + + mbedtls_sha1_update( &sha1, (const unsigned char *) sender, 4 ); + mbedtls_sha1_update( &sha1, session->master, 48 ); + mbedtls_sha1_update( &sha1, padbuf, 40 ); + mbedtls_sha1_finish( &sha1, sha1sum ); + + memset( padbuf, 0x5C, 48 ); + + mbedtls_md5_starts( &md5 ); + mbedtls_md5_update( &md5, session->master, 48 ); + mbedtls_md5_update( &md5, padbuf, 48 ); + mbedtls_md5_update( &md5, md5sum, 16 ); + mbedtls_md5_finish( &md5, buf ); + + mbedtls_sha1_starts( &sha1 ); + mbedtls_sha1_update( &sha1, session->master, 48 ); + mbedtls_sha1_update( &sha1, padbuf , 40 ); + mbedtls_sha1_update( &sha1, sha1sum, 20 ); + mbedtls_sha1_finish( &sha1, buf + 16 ); + + MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, 36 ); + + mbedtls_md5_free( &md5 ); + mbedtls_sha1_free( &sha1 ); + + mbedtls_zeroize( padbuf, sizeof( padbuf ) ); + mbedtls_zeroize( md5sum, sizeof( md5sum ) ); + mbedtls_zeroize( sha1sum, sizeof( sha1sum ) ); + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) ); +} +#endif /* MBEDTLS_SSL_PROTO_SSL3 */ + +#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) +static void ssl_calc_finished_tls( + mbedtls_ssl_context *ssl, unsigned char *buf, int from ) +{ + int len = 12; + const char *sender; + mbedtls_md5_context md5; + mbedtls_sha1_context sha1; + unsigned char padbuf[36]; + + mbedtls_ssl_session *session = ssl->session_negotiate; + if( !session ) + session = ssl->session; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished tls" ) ); + + mbedtls_md5_init( &md5 ); + mbedtls_sha1_init( &sha1 ); + + mbedtls_md5_clone( &md5, &ssl->handshake->fin_md5 ); + mbedtls_sha1_clone( &sha1, &ssl->handshake->fin_sha1 ); + + /* + * TLSv1: + * hash = PRF( master, finished_label, + * MD5( handshake ) + SHA1( handshake ) )[0..11] + */ + +#if !defined(MBEDTLS_MD5_ALT) + MBEDTLS_SSL_DEBUG_BUF( 4, "finished md5 state", (unsigned char *) + md5.state, sizeof( md5.state ) ); +#endif + +#if !defined(MBEDTLS_SHA1_ALT) + MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha1 state", (unsigned char *) + sha1.state, sizeof( sha1.state ) ); +#endif + + sender = ( from == MBEDTLS_SSL_IS_CLIENT ) + ? "client finished" + : "server finished"; + + mbedtls_md5_finish( &md5, padbuf ); + mbedtls_sha1_finish( &sha1, padbuf + 16 ); + + ssl->handshake->tls_prf( session->master, 48, sender, + padbuf, 36, buf, len ); + + MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len ); + + mbedtls_md5_free( &md5 ); + mbedtls_sha1_free( &sha1 ); + + mbedtls_zeroize( padbuf, sizeof( padbuf ) ); + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) ); +} +#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */ + +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) +#if defined(MBEDTLS_SHA256_C) +static void ssl_calc_finished_tls_sha256( + mbedtls_ssl_context *ssl, unsigned char *buf, int from ) +{ + int len = 12; + const char *sender; + mbedtls_sha256_context sha256; + unsigned char padbuf[32]; + + mbedtls_ssl_session *session = ssl->session_negotiate; + if( !session ) + session = ssl->session; + + mbedtls_sha256_init( &sha256 ); + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished tls sha256" ) ); + + mbedtls_sha256_clone( &sha256, &ssl->handshake->fin_sha256 ); + + /* + * TLSv1.2: + * hash = PRF( master, finished_label, + * Hash( handshake ) )[0.11] + */ + +#if !defined(MBEDTLS_SHA256_ALT) + MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha2 state", (unsigned char *) + sha256.state, sizeof( sha256.state ) ); +#endif + + sender = ( from == MBEDTLS_SSL_IS_CLIENT ) + ? "client finished" + : "server finished"; + + mbedtls_sha256_finish( &sha256, padbuf ); + + ssl->handshake->tls_prf( session->master, 48, sender, + padbuf, 32, buf, len ); + + MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len ); + + mbedtls_sha256_free( &sha256 ); + + mbedtls_zeroize( padbuf, sizeof( padbuf ) ); + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) ); +} +#endif /* MBEDTLS_SHA256_C */ + +#if defined(MBEDTLS_SHA512_C) +static void ssl_calc_finished_tls_sha384( + mbedtls_ssl_context *ssl, unsigned char *buf, int from ) +{ + int len = 12; + const char *sender; + mbedtls_sha512_context sha512; + unsigned char padbuf[48]; + + mbedtls_ssl_session *session = ssl->session_negotiate; + if( !session ) + session = ssl->session; + + mbedtls_sha512_init( &sha512 ); + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> calc finished tls sha384" ) ); + + mbedtls_sha512_clone( &sha512, &ssl->handshake->fin_sha512 ); + + /* + * TLSv1.2: + * hash = PRF( master, finished_label, + * Hash( handshake ) )[0.11] + */ + +#if !defined(MBEDTLS_SHA512_ALT) + MBEDTLS_SSL_DEBUG_BUF( 4, "finished sha512 state", (unsigned char *) + sha512.state, sizeof( sha512.state ) ); +#endif + + sender = ( from == MBEDTLS_SSL_IS_CLIENT ) + ? "client finished" + : "server finished"; + + mbedtls_sha512_finish( &sha512, padbuf ); + + ssl->handshake->tls_prf( session->master, 48, sender, + padbuf, 48, buf, len ); + + MBEDTLS_SSL_DEBUG_BUF( 3, "calc finished result", buf, len ); + + mbedtls_sha512_free( &sha512 ); + + mbedtls_zeroize( padbuf, sizeof( padbuf ) ); + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= calc finished" ) ); +} +#endif /* MBEDTLS_SHA512_C */ +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ + +static void ssl_handshake_wrapup_free_hs_transform( mbedtls_ssl_context *ssl ) +{ + MBEDTLS_SSL_DEBUG_MSG( 3, ( "=> handshake wrapup: final free" ) ); + + /* + * Free our handshake params + */ + mbedtls_ssl_handshake_free( ssl->handshake ); + mbedtls_free( ssl->handshake ); + ssl->handshake = NULL; + + /* + * Free the previous transform and swith in the current one + */ + if( ssl->transform ) + { + mbedtls_ssl_transform_free( ssl->transform ); + mbedtls_free( ssl->transform ); + } + ssl->transform = ssl->transform_negotiate; + ssl->transform_negotiate = NULL; + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "<= handshake wrapup: final free" ) ); +} + +void mbedtls_ssl_handshake_wrapup( mbedtls_ssl_context *ssl ) +{ + int resume = ssl->handshake->resume; + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "=> handshake wrapup" ) ); + +#if defined(MBEDTLS_SSL_RENEGOTIATION) + if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS ) + { + ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_DONE; + ssl->renego_records_seen = 0; + } +#endif + + /* + * Free the previous session and switch in the current one + */ + if( ssl->session ) + { +#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) + /* RFC 7366 3.1: keep the EtM state */ + ssl->session_negotiate->encrypt_then_mac = + ssl->session->encrypt_then_mac; +#endif + + mbedtls_ssl_session_free( ssl->session ); + mbedtls_free( ssl->session ); + } + ssl->session = ssl->session_negotiate; + ssl->session_negotiate = NULL; + + /* + * Add cache entry + */ + if( ssl->conf->f_set_cache != NULL && + ssl->session->id_len != 0 && + resume == 0 ) + { + if( ssl->conf->f_set_cache( ssl->conf->p_cache, ssl->session ) != 0 ) + MBEDTLS_SSL_DEBUG_MSG( 1, ( "cache did not store session" ) ); + } + +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && + ssl->handshake->flight != NULL ) + { + /* Cancel handshake timer */ + ssl_set_timer( ssl, 0 ); + + /* Keep last flight around in case we need to resend it: + * we need the handshake and transform structures for that */ + MBEDTLS_SSL_DEBUG_MSG( 3, ( "skip freeing handshake and transform" ) ); + } + else +#endif + ssl_handshake_wrapup_free_hs_transform( ssl ); + + ssl->state++; + + MBEDTLS_SSL_DEBUG_MSG( 3, ( "<= handshake wrapup" ) ); +} + +int mbedtls_ssl_write_finished( mbedtls_ssl_context *ssl ) +{ + int ret, hash_len; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write finished" ) ); + + /* + * Set the out_msg pointer to the correct location based on IV length + */ + if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_2 ) + { + ssl->out_msg = ssl->out_iv + ssl->transform_negotiate->ivlen - + ssl->transform_negotiate->fixed_ivlen; + } + else + ssl->out_msg = ssl->out_iv; + + ssl->handshake->calc_finished( ssl, ssl->out_msg + 4, ssl->conf->endpoint ); + + /* + * RFC 5246 7.4.9 (Page 63) says 12 is the default length and ciphersuites + * may define some other value. Currently (early 2016), no defined + * ciphersuite does this (and this is unlikely to change as activity has + * moved to TLS 1.3 now) so we can keep the hardcoded 12 here. + */ + hash_len = ( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) ? 36 : 12; + +#if defined(MBEDTLS_SSL_RENEGOTIATION) + ssl->verify_data_len = hash_len; + memcpy( ssl->own_verify_data, ssl->out_msg + 4, hash_len ); +#endif + + ssl->out_msglen = 4 + hash_len; + ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; + ssl->out_msg[0] = MBEDTLS_SSL_HS_FINISHED; + + /* + * In case of session resuming, invert the client and server + * ChangeCipherSpec messages order. + */ + if( ssl->handshake->resume != 0 ) + { +#if defined(MBEDTLS_SSL_CLI_C) + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) + ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP; +#endif +#if defined(MBEDTLS_SSL_SRV_C) + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) + ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC; +#endif + } + else + ssl->state++; + + /* + * Switch to our negotiated transform and session parameters for outbound + * data. + */ + MBEDTLS_SSL_DEBUG_MSG( 3, ( "switching to new transform spec for outbound data" ) ); + +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + { + unsigned char i; + + /* Remember current epoch settings for resending */ + ssl->handshake->alt_transform_out = ssl->transform_out; + memcpy( ssl->handshake->alt_out_ctr, ssl->out_ctr, 8 ); + + /* Set sequence_number to zero */ + memset( ssl->out_ctr + 2, 0, 6 ); + + /* Increment epoch */ + for( i = 2; i > 0; i-- ) + if( ++ssl->out_ctr[i - 1] != 0 ) + break; + + /* The loop goes to its end iff the counter is wrapping */ + if( i == 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "DTLS epoch would wrap" ) ); + return( MBEDTLS_ERR_SSL_COUNTER_WRAPPING ); + } + } + else +#endif /* MBEDTLS_SSL_PROTO_DTLS */ + memset( ssl->out_ctr, 0, 8 ); + + ssl->transform_out = ssl->transform_negotiate; + ssl->session_out = ssl->session_negotiate; + +#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) + if( mbedtls_ssl_hw_record_activate != NULL ) + { + if( ( ret = mbedtls_ssl_hw_record_activate( ssl, MBEDTLS_SSL_CHANNEL_OUTBOUND ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_activate", ret ); + return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); + } + } +#endif + +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + mbedtls_ssl_send_flight_completed( ssl ); +#endif + + if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); + return( ret ); + } + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write finished" ) ); + + return( 0 ); +} + +#if defined(MBEDTLS_SSL_PROTO_SSL3) +#define SSL_MAX_HASH_LEN 36 +#else +#define SSL_MAX_HASH_LEN 12 +#endif + +int mbedtls_ssl_parse_finished( mbedtls_ssl_context *ssl ) +{ + int ret; + unsigned int hash_len; + unsigned char buf[SSL_MAX_HASH_LEN]; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> parse finished" ) ); + + ssl->handshake->calc_finished( ssl, buf, ssl->conf->endpoint ^ 1 ); + + if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); + return( ret ); + } + + if( ssl->in_msgtype != MBEDTLS_SSL_MSG_HANDSHAKE ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) ); + return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); + } + + /* There is currently no ciphersuite using another length with TLS 1.2 */ +#if defined(MBEDTLS_SSL_PROTO_SSL3) + if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) + hash_len = 36; + else +#endif + hash_len = 12; + + if( ssl->in_msg[0] != MBEDTLS_SSL_HS_FINISHED || + ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) + hash_len ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_FINISHED ); + } + + if( mbedtls_ssl_safer_memcmp( ssl->in_msg + mbedtls_ssl_hs_hdr_len( ssl ), + buf, hash_len ) != 0 ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad finished message" ) ); + return( MBEDTLS_ERR_SSL_BAD_HS_FINISHED ); + } + +#if defined(MBEDTLS_SSL_RENEGOTIATION) + ssl->verify_data_len = hash_len; + memcpy( ssl->peer_verify_data, buf, hash_len ); +#endif + + if( ssl->handshake->resume != 0 ) + { +#if defined(MBEDTLS_SSL_CLI_C) + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) + ssl->state = MBEDTLS_SSL_CLIENT_CHANGE_CIPHER_SPEC; +#endif +#if defined(MBEDTLS_SSL_SRV_C) + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) + ssl->state = MBEDTLS_SSL_HANDSHAKE_WRAPUP; +#endif + } + else + ssl->state++; + +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + mbedtls_ssl_recv_flight_completed( ssl ); +#endif + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= parse finished" ) ); + + return( 0 ); +} + +static void ssl_handshake_params_init( mbedtls_ssl_handshake_params *handshake ) +{ + memset( handshake, 0, sizeof( mbedtls_ssl_handshake_params ) ); + +#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ + defined(MBEDTLS_SSL_PROTO_TLS1_1) + mbedtls_md5_init( &handshake->fin_md5 ); + mbedtls_sha1_init( &handshake->fin_sha1 ); + mbedtls_md5_starts( &handshake->fin_md5 ); + mbedtls_sha1_starts( &handshake->fin_sha1 ); +#endif +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) +#if defined(MBEDTLS_SHA256_C) + mbedtls_sha256_init( &handshake->fin_sha256 ); + mbedtls_sha256_starts( &handshake->fin_sha256, 0 ); +#endif +#if defined(MBEDTLS_SHA512_C) + mbedtls_sha512_init( &handshake->fin_sha512 ); + mbedtls_sha512_starts( &handshake->fin_sha512, 1 ); +#endif +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ + + handshake->update_checksum = ssl_update_checksum_start; + handshake->sig_alg = MBEDTLS_SSL_HASH_SHA1; + +#if defined(MBEDTLS_DHM_C) + mbedtls_dhm_init( &handshake->dhm_ctx ); +#endif +#if defined(MBEDTLS_ECDH_C) + mbedtls_ecdh_init( &handshake->ecdh_ctx ); +#endif +#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) + mbedtls_ecjpake_init( &handshake->ecjpake_ctx ); +#if defined(MBEDTLS_SSL_CLI_C) + handshake->ecjpake_cache = NULL; + handshake->ecjpake_cache_len = 0; +#endif +#endif + +#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) + handshake->sni_authmode = MBEDTLS_SSL_VERIFY_UNSET; +#endif +} + +static void ssl_transform_init( mbedtls_ssl_transform *transform ) +{ + memset( transform, 0, sizeof(mbedtls_ssl_transform) ); + + mbedtls_cipher_init( &transform->cipher_ctx_enc ); + mbedtls_cipher_init( &transform->cipher_ctx_dec ); + + mbedtls_md_init( &transform->md_ctx_enc ); + mbedtls_md_init( &transform->md_ctx_dec ); +} + +void mbedtls_ssl_session_init( mbedtls_ssl_session *session ) +{ + memset( session, 0, sizeof(mbedtls_ssl_session) ); +} + +static int ssl_handshake_init( mbedtls_ssl_context *ssl ) +{ + /* Clear old handshake information if present */ + if( ssl->transform_negotiate ) + mbedtls_ssl_transform_free( ssl->transform_negotiate ); + if( ssl->session_negotiate ) + mbedtls_ssl_session_free( ssl->session_negotiate ); + if( ssl->handshake ) + mbedtls_ssl_handshake_free( ssl->handshake ); + + /* + * Either the pointers are now NULL or cleared properly and can be freed. + * Now allocate missing structures. + */ + if( ssl->transform_negotiate == NULL ) + { + ssl->transform_negotiate = mbedtls_calloc( 1, sizeof(mbedtls_ssl_transform) ); + } + + if( ssl->session_negotiate == NULL ) + { + ssl->session_negotiate = mbedtls_calloc( 1, sizeof(mbedtls_ssl_session) ); + } + + if( ssl->handshake == NULL ) + { + ssl->handshake = mbedtls_calloc( 1, sizeof(mbedtls_ssl_handshake_params) ); + } + + /* All pointers should exist and can be directly freed without issue */ + if( ssl->handshake == NULL || + ssl->transform_negotiate == NULL || + ssl->session_negotiate == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc() of ssl sub-contexts failed" ) ); + + mbedtls_free( ssl->handshake ); + mbedtls_free( ssl->transform_negotiate ); + mbedtls_free( ssl->session_negotiate ); + + ssl->handshake = NULL; + ssl->transform_negotiate = NULL; + ssl->session_negotiate = NULL; + + return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); + } + + /* Initialize structures */ + mbedtls_ssl_session_init( ssl->session_negotiate ); + ssl_transform_init( ssl->transform_negotiate ); + ssl_handshake_params_init( ssl->handshake ); + +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + { + ssl->handshake->alt_transform_out = ssl->transform_out; + + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) + ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_PREPARING; + else + ssl->handshake->retransmit_state = MBEDTLS_SSL_RETRANS_WAITING; + + ssl_set_timer( ssl, 0 ); + } +#endif + + return( 0 ); +} + +#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C) +/* Dummy cookie callbacks for defaults */ +static int ssl_cookie_write_dummy( void *ctx, + unsigned char **p, unsigned char *end, + const unsigned char *cli_id, size_t cli_id_len ) +{ + ((void) ctx); + ((void) p); + ((void) end); + ((void) cli_id); + ((void) cli_id_len); + + return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); +} + +static int ssl_cookie_check_dummy( void *ctx, + const unsigned char *cookie, size_t cookie_len, + const unsigned char *cli_id, size_t cli_id_len ) +{ + ((void) ctx); + ((void) cookie); + ((void) cookie_len); + ((void) cli_id); + ((void) cli_id_len); + + return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); +} +#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY && MBEDTLS_SSL_SRV_C */ + +/* + * Initialize an SSL context + */ +void mbedtls_ssl_init( mbedtls_ssl_context *ssl ) +{ + memset( ssl, 0, sizeof( mbedtls_ssl_context ) ); +} + +/* + * Setup an SSL context + */ +int mbedtls_ssl_setup( mbedtls_ssl_context *ssl, + const mbedtls_ssl_config *conf ) +{ + int ret; + const size_t len = MBEDTLS_SSL_BUFFER_LEN; + + ssl->conf = conf; + + /* + * Prepare base structures + */ + if( ( ssl-> in_buf = mbedtls_calloc( 1, len ) ) == NULL || + ( ssl->out_buf = mbedtls_calloc( 1, len ) ) == NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "alloc(%d bytes) failed", len ) ); + mbedtls_free( ssl->in_buf ); + ssl->in_buf = NULL; + return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); + } + +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + { + ssl->out_hdr = ssl->out_buf; + ssl->out_ctr = ssl->out_buf + 3; + ssl->out_len = ssl->out_buf + 11; + ssl->out_iv = ssl->out_buf + 13; + ssl->out_msg = ssl->out_buf + 13; + + ssl->in_hdr = ssl->in_buf; + ssl->in_ctr = ssl->in_buf + 3; + ssl->in_len = ssl->in_buf + 11; + ssl->in_iv = ssl->in_buf + 13; + ssl->in_msg = ssl->in_buf + 13; + } + else +#endif + { + ssl->out_ctr = ssl->out_buf; + ssl->out_hdr = ssl->out_buf + 8; + ssl->out_len = ssl->out_buf + 11; + ssl->out_iv = ssl->out_buf + 13; + ssl->out_msg = ssl->out_buf + 13; + + ssl->in_ctr = ssl->in_buf; + ssl->in_hdr = ssl->in_buf + 8; + ssl->in_len = ssl->in_buf + 11; + ssl->in_iv = ssl->in_buf + 13; + ssl->in_msg = ssl->in_buf + 13; + } + + if( ( ret = ssl_handshake_init( ssl ) ) != 0 ) + return( ret ); + + return( 0 ); +} + +/* + * Reset an initialized and used SSL context for re-use while retaining + * all application-set variables, function pointers and data. + * + * If partial is non-zero, keep data in the input buffer and client ID. + * (Use when a DTLS client reconnects from the same port.) + */ +static int ssl_session_reset_int( mbedtls_ssl_context *ssl, int partial ) +{ + int ret; + + ssl->state = MBEDTLS_SSL_HELLO_REQUEST; + + /* Cancel any possibly running timer */ + ssl_set_timer( ssl, 0 ); + +#if defined(MBEDTLS_SSL_RENEGOTIATION) + ssl->renego_status = MBEDTLS_SSL_INITIAL_HANDSHAKE; + ssl->renego_records_seen = 0; + + ssl->verify_data_len = 0; + memset( ssl->own_verify_data, 0, MBEDTLS_SSL_VERIFY_DATA_MAX_LEN ); + memset( ssl->peer_verify_data, 0, MBEDTLS_SSL_VERIFY_DATA_MAX_LEN ); +#endif + ssl->secure_renegotiation = MBEDTLS_SSL_LEGACY_RENEGOTIATION; + + ssl->in_offt = NULL; + + ssl->in_msg = ssl->in_buf + 13; + ssl->in_msgtype = 0; + ssl->in_msglen = 0; + if( partial == 0 ) + ssl->in_left = 0; +#if defined(MBEDTLS_SSL_PROTO_DTLS) + ssl->next_record_offset = 0; + ssl->in_epoch = 0; +#endif +#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) + ssl_dtls_replay_reset( ssl ); +#endif + + ssl->in_hslen = 0; + ssl->nb_zero = 0; + ssl->record_read = 0; + + ssl->out_msg = ssl->out_buf + 13; + ssl->out_msgtype = 0; + ssl->out_msglen = 0; + ssl->out_left = 0; +#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) + if( ssl->split_done != MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED ) + ssl->split_done = 0; +#endif + + ssl->transform_in = NULL; + ssl->transform_out = NULL; + + memset( ssl->out_buf, 0, MBEDTLS_SSL_BUFFER_LEN ); + if( partial == 0 ) + memset( ssl->in_buf, 0, MBEDTLS_SSL_BUFFER_LEN ); + +#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) + if( mbedtls_ssl_hw_record_reset != NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_reset()" ) ); + if( ( ret = mbedtls_ssl_hw_record_reset( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_hw_record_reset", ret ); + return( MBEDTLS_ERR_SSL_HW_ACCEL_FAILED ); + } + } +#endif + + if( ssl->transform ) + { + mbedtls_ssl_transform_free( ssl->transform ); + mbedtls_free( ssl->transform ); + ssl->transform = NULL; + } + + if( ssl->session ) + { + mbedtls_ssl_session_free( ssl->session ); + mbedtls_free( ssl->session ); + ssl->session = NULL; + } + +#if defined(MBEDTLS_SSL_ALPN) + ssl->alpn_chosen = NULL; +#endif + +#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C) + if( partial == 0 ) + { + mbedtls_free( ssl->cli_id ); + ssl->cli_id = NULL; + ssl->cli_id_len = 0; + } +#endif + + if( ( ret = ssl_handshake_init( ssl ) ) != 0 ) + return( ret ); + + return( 0 ); +} + +/* + * Reset an initialized and used SSL context for re-use while retaining + * all application-set variables, function pointers and data. + */ +int mbedtls_ssl_session_reset( mbedtls_ssl_context *ssl ) +{ + return( ssl_session_reset_int( ssl, 0 ) ); +} + +/* + * SSL set accessors + */ +void mbedtls_ssl_conf_endpoint( mbedtls_ssl_config *conf, int endpoint ) +{ + conf->endpoint = endpoint; +} + +void mbedtls_ssl_conf_transport( mbedtls_ssl_config *conf, int transport ) +{ + conf->transport = transport; +} + +#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) +void mbedtls_ssl_conf_dtls_anti_replay( mbedtls_ssl_config *conf, char mode ) +{ + conf->anti_replay = mode; +} +#endif + +#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) +void mbedtls_ssl_conf_dtls_badmac_limit( mbedtls_ssl_config *conf, unsigned limit ) +{ + conf->badmac_limit = limit; +} +#endif + +#if defined(MBEDTLS_SSL_PROTO_DTLS) +void mbedtls_ssl_conf_handshake_timeout( mbedtls_ssl_config *conf, uint32_t min, uint32_t max ) +{ + conf->hs_timeout_min = min; + conf->hs_timeout_max = max; +} +#endif + +void mbedtls_ssl_conf_authmode( mbedtls_ssl_config *conf, int authmode ) +{ + conf->authmode = authmode; +} + +#if defined(MBEDTLS_X509_CRT_PARSE_C) +void mbedtls_ssl_conf_verify( mbedtls_ssl_config *conf, + int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), + void *p_vrfy ) +{ + conf->f_vrfy = f_vrfy; + conf->p_vrfy = p_vrfy; +} +#endif /* MBEDTLS_X509_CRT_PARSE_C */ + +void mbedtls_ssl_conf_rng( mbedtls_ssl_config *conf, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + conf->f_rng = f_rng; + conf->p_rng = p_rng; +} + +void mbedtls_ssl_conf_dbg( mbedtls_ssl_config *conf, + void (*f_dbg)(void *, int, const char *, int, const char *), + void *p_dbg ) +{ + conf->f_dbg = f_dbg; + conf->p_dbg = p_dbg; +} + +void mbedtls_ssl_set_bio( mbedtls_ssl_context *ssl, + void *p_bio, + mbedtls_ssl_send_t *f_send, + mbedtls_ssl_recv_t *f_recv, + mbedtls_ssl_recv_timeout_t *f_recv_timeout ) +{ + ssl->p_bio = p_bio; + ssl->f_send = f_send; + ssl->f_recv = f_recv; + ssl->f_recv_timeout = f_recv_timeout; +} + +void mbedtls_ssl_conf_read_timeout( mbedtls_ssl_config *conf, uint32_t timeout ) +{ + conf->read_timeout = timeout; +} + +void mbedtls_ssl_set_timer_cb( mbedtls_ssl_context *ssl, + void *p_timer, + mbedtls_ssl_set_timer_t *f_set_timer, + mbedtls_ssl_get_timer_t *f_get_timer ) +{ + ssl->p_timer = p_timer; + ssl->f_set_timer = f_set_timer; + ssl->f_get_timer = f_get_timer; + + /* Make sure we start with no timer running */ + ssl_set_timer( ssl, 0 ); +} + +#if defined(MBEDTLS_SSL_SRV_C) +void mbedtls_ssl_conf_session_cache( mbedtls_ssl_config *conf, + void *p_cache, + int (*f_get_cache)(void *, mbedtls_ssl_session *), + int (*f_set_cache)(void *, const mbedtls_ssl_session *) ) +{ + conf->p_cache = p_cache; + conf->f_get_cache = f_get_cache; + conf->f_set_cache = f_set_cache; +} +#endif /* MBEDTLS_SSL_SRV_C */ + +#if defined(MBEDTLS_SSL_CLI_C) +int mbedtls_ssl_set_session( mbedtls_ssl_context *ssl, const mbedtls_ssl_session *session ) +{ + int ret; + + if( ssl == NULL || + session == NULL || + ssl->session_negotiate == NULL || + ssl->conf->endpoint != MBEDTLS_SSL_IS_CLIENT ) + { + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + } + + if( ( ret = ssl_session_copy( ssl->session_negotiate, session ) ) != 0 ) + return( ret ); + + ssl->handshake->resume = 1; + + return( 0 ); +} +#endif /* MBEDTLS_SSL_CLI_C */ + +void mbedtls_ssl_conf_ciphersuites( mbedtls_ssl_config *conf, + const int *ciphersuites ) +{ + conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_0] = ciphersuites; + conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_1] = ciphersuites; + conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_2] = ciphersuites; + conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_3] = ciphersuites; +} + +void mbedtls_ssl_conf_ciphersuites_for_version( mbedtls_ssl_config *conf, + const int *ciphersuites, + int major, int minor ) +{ + if( major != MBEDTLS_SSL_MAJOR_VERSION_3 ) + return; + + if( minor < MBEDTLS_SSL_MINOR_VERSION_0 || minor > MBEDTLS_SSL_MINOR_VERSION_3 ) + return; + + conf->ciphersuite_list[minor] = ciphersuites; +} + +#if defined(MBEDTLS_X509_CRT_PARSE_C) +void mbedtls_ssl_conf_cert_profile( mbedtls_ssl_config *conf, + const mbedtls_x509_crt_profile *profile ) +{ + conf->cert_profile = profile; +} + +/* Append a new keycert entry to a (possibly empty) list */ +static int ssl_append_key_cert( mbedtls_ssl_key_cert **head, + mbedtls_x509_crt *cert, + mbedtls_pk_context *key ) +{ + mbedtls_ssl_key_cert *new; + + new = mbedtls_calloc( 1, sizeof( mbedtls_ssl_key_cert ) ); + if( new == NULL ) + return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); + + new->cert = cert; + new->key = key; + new->next = NULL; + + /* Update head is the list was null, else add to the end */ + if( *head == NULL ) + { + *head = new; + } + else + { + mbedtls_ssl_key_cert *cur = *head; + while( cur->next != NULL ) + cur = cur->next; + cur->next = new; + } + + return( 0 ); +} + +int mbedtls_ssl_conf_own_cert( mbedtls_ssl_config *conf, + mbedtls_x509_crt *own_cert, + mbedtls_pk_context *pk_key ) +{ + return( ssl_append_key_cert( &conf->key_cert, own_cert, pk_key ) ); +} + +void mbedtls_ssl_conf_ca_chain( mbedtls_ssl_config *conf, + mbedtls_x509_crt *ca_chain, + mbedtls_x509_crl *ca_crl ) +{ + conf->ca_chain = ca_chain; + conf->ca_crl = ca_crl; +} +#endif /* MBEDTLS_X509_CRT_PARSE_C */ + +#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) +int mbedtls_ssl_set_hs_own_cert( mbedtls_ssl_context *ssl, + mbedtls_x509_crt *own_cert, + mbedtls_pk_context *pk_key ) +{ + return( ssl_append_key_cert( &ssl->handshake->sni_key_cert, + own_cert, pk_key ) ); +} + +void mbedtls_ssl_set_hs_ca_chain( mbedtls_ssl_context *ssl, + mbedtls_x509_crt *ca_chain, + mbedtls_x509_crl *ca_crl ) +{ + ssl->handshake->sni_ca_chain = ca_chain; + ssl->handshake->sni_ca_crl = ca_crl; +} + +void mbedtls_ssl_set_hs_authmode( mbedtls_ssl_context *ssl, + int authmode ) +{ + ssl->handshake->sni_authmode = authmode; +} +#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ + +#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) +/* + * Set EC J-PAKE password for current handshake + */ +int mbedtls_ssl_set_hs_ecjpake_password( mbedtls_ssl_context *ssl, + const unsigned char *pw, + size_t pw_len ) +{ + mbedtls_ecjpake_role role; + + if( ssl->handshake == NULL || ssl->conf == NULL ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) + role = MBEDTLS_ECJPAKE_SERVER; + else + role = MBEDTLS_ECJPAKE_CLIENT; + + return( mbedtls_ecjpake_setup( &ssl->handshake->ecjpake_ctx, + role, + MBEDTLS_MD_SHA256, + MBEDTLS_ECP_DP_SECP256R1, + pw, pw_len ) ); +} +#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ + +#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) +int mbedtls_ssl_conf_psk( mbedtls_ssl_config *conf, + const unsigned char *psk, size_t psk_len, + const unsigned char *psk_identity, size_t psk_identity_len ) +{ + if( psk == NULL || psk_identity == NULL ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + if( psk_len > MBEDTLS_PSK_MAX_LEN ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + /* Identity len will be encoded on two bytes */ + if( ( psk_identity_len >> 16 ) != 0 || + psk_identity_len > MBEDTLS_SSL_MAX_CONTENT_LEN ) + { + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + } + + if( conf->psk != NULL || conf->psk_identity != NULL ) + { + mbedtls_free( conf->psk ); + mbedtls_free( conf->psk_identity ); + conf->psk = NULL; + conf->psk_identity = NULL; + } + + if( ( conf->psk = mbedtls_calloc( 1, psk_len ) ) == NULL || + ( conf->psk_identity = mbedtls_calloc( 1, psk_identity_len ) ) == NULL ) + { + mbedtls_free( conf->psk ); + mbedtls_free( conf->psk_identity ); + conf->psk = NULL; + conf->psk_identity = NULL; + return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); + } + + conf->psk_len = psk_len; + conf->psk_identity_len = psk_identity_len; + + memcpy( conf->psk, psk, conf->psk_len ); + memcpy( conf->psk_identity, psk_identity, conf->psk_identity_len ); + + return( 0 ); +} + +int mbedtls_ssl_set_hs_psk( mbedtls_ssl_context *ssl, + const unsigned char *psk, size_t psk_len ) +{ + if( psk == NULL || ssl->handshake == NULL ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + if( psk_len > MBEDTLS_PSK_MAX_LEN ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + if( ssl->handshake->psk != NULL ) + mbedtls_free( ssl->handshake->psk ); + + if( ( ssl->handshake->psk = mbedtls_calloc( 1, psk_len ) ) == NULL ) + return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); + + ssl->handshake->psk_len = psk_len; + memcpy( ssl->handshake->psk, psk, ssl->handshake->psk_len ); + + return( 0 ); +} + +void mbedtls_ssl_conf_psk_cb( mbedtls_ssl_config *conf, + int (*f_psk)(void *, mbedtls_ssl_context *, const unsigned char *, + size_t), + void *p_psk ) +{ + conf->f_psk = f_psk; + conf->p_psk = p_psk; +} +#endif /* MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED */ + +#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C) +int mbedtls_ssl_conf_dh_param( mbedtls_ssl_config *conf, const char *dhm_P, const char *dhm_G ) +{ + int ret; + + if( ( ret = mbedtls_mpi_read_string( &conf->dhm_P, 16, dhm_P ) ) != 0 || + ( ret = mbedtls_mpi_read_string( &conf->dhm_G, 16, dhm_G ) ) != 0 ) + { + mbedtls_mpi_free( &conf->dhm_P ); + mbedtls_mpi_free( &conf->dhm_G ); + return( ret ); + } + + return( 0 ); +} + +int mbedtls_ssl_conf_dh_param_ctx( mbedtls_ssl_config *conf, mbedtls_dhm_context *dhm_ctx ) +{ + int ret; + + if( ( ret = mbedtls_mpi_copy( &conf->dhm_P, &dhm_ctx->P ) ) != 0 || + ( ret = mbedtls_mpi_copy( &conf->dhm_G, &dhm_ctx->G ) ) != 0 ) + { + mbedtls_mpi_free( &conf->dhm_P ); + mbedtls_mpi_free( &conf->dhm_G ); + return( ret ); + } + + return( 0 ); +} +#endif /* MBEDTLS_DHM_C && MBEDTLS_SSL_SRV_C */ + +#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C) +/* + * Set the minimum length for Diffie-Hellman parameters + */ +void mbedtls_ssl_conf_dhm_min_bitlen( mbedtls_ssl_config *conf, + unsigned int bitlen ) +{ + conf->dhm_min_bitlen = bitlen; +} +#endif /* MBEDTLS_DHM_C && MBEDTLS_SSL_CLI_C */ + +#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) +/* + * Set allowed/preferred hashes for handshake signatures + */ +void mbedtls_ssl_conf_sig_hashes( mbedtls_ssl_config *conf, + const int *hashes ) +{ + conf->sig_hashes = hashes; +} +#endif + +#if defined(MBEDTLS_ECP_C) +/* + * Set the allowed elliptic curves + */ +void mbedtls_ssl_conf_curves( mbedtls_ssl_config *conf, + const mbedtls_ecp_group_id *curve_list ) +{ + conf->curve_list = curve_list; +} +#endif + +#if defined(MBEDTLS_X509_CRT_PARSE_C) +int mbedtls_ssl_set_hostname( mbedtls_ssl_context *ssl, const char *hostname ) +{ + size_t hostname_len; + + if( hostname == NULL ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + hostname_len = strlen( hostname ); + + if( hostname_len + 1 == 0 ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + if( hostname_len > MBEDTLS_SSL_MAX_HOST_NAME_LEN ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + ssl->hostname = mbedtls_calloc( 1, hostname_len + 1 ); + + if( ssl->hostname == NULL ) + return( MBEDTLS_ERR_SSL_ALLOC_FAILED ); + + memcpy( ssl->hostname, hostname, hostname_len ); + + ssl->hostname[hostname_len] = '\0'; + + return( 0 ); +} +#endif + +#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) +void mbedtls_ssl_conf_sni( mbedtls_ssl_config *conf, + int (*f_sni)(void *, mbedtls_ssl_context *, + const unsigned char *, size_t), + void *p_sni ) +{ + conf->f_sni = f_sni; + conf->p_sni = p_sni; +} +#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ + +#if defined(MBEDTLS_SSL_ALPN) +int mbedtls_ssl_conf_alpn_protocols( mbedtls_ssl_config *conf, const char **protos ) +{ + size_t cur_len, tot_len; + const char **p; + + /* + * RFC 7301 3.1: "Empty strings MUST NOT be included and byte strings + * MUST NOT be truncated." + * We check lengths now rather than later. + */ + tot_len = 0; + for( p = protos; *p != NULL; p++ ) + { + cur_len = strlen( *p ); + tot_len += cur_len; + + if( cur_len == 0 || cur_len > 255 || tot_len > 65535 ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + } + + conf->alpn_list = protos; + + return( 0 ); +} + +const char *mbedtls_ssl_get_alpn_protocol( const mbedtls_ssl_context *ssl ) +{ + return( ssl->alpn_chosen ); +} +#endif /* MBEDTLS_SSL_ALPN */ + +void mbedtls_ssl_conf_max_version( mbedtls_ssl_config *conf, int major, int minor ) +{ + conf->max_major_ver = major; + conf->max_minor_ver = minor; +} + +void mbedtls_ssl_conf_min_version( mbedtls_ssl_config *conf, int major, int minor ) +{ + conf->min_major_ver = major; + conf->min_minor_ver = minor; +} + +#if defined(MBEDTLS_SSL_FALLBACK_SCSV) && defined(MBEDTLS_SSL_CLI_C) +void mbedtls_ssl_conf_fallback( mbedtls_ssl_config *conf, char fallback ) +{ + conf->fallback = fallback; +} +#endif + +#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) +void mbedtls_ssl_conf_encrypt_then_mac( mbedtls_ssl_config *conf, char etm ) +{ + conf->encrypt_then_mac = etm; +} +#endif + +#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) +void mbedtls_ssl_conf_extended_master_secret( mbedtls_ssl_config *conf, char ems ) +{ + conf->extended_ms = ems; +} +#endif + +#if defined(MBEDTLS_ARC4_C) +void mbedtls_ssl_conf_arc4_support( mbedtls_ssl_config *conf, char arc4 ) +{ + conf->arc4_disabled = arc4; +} +#endif + +#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) +int mbedtls_ssl_conf_max_frag_len( mbedtls_ssl_config *conf, unsigned char mfl_code ) +{ + if( mfl_code >= MBEDTLS_SSL_MAX_FRAG_LEN_INVALID || + mfl_code_to_length[mfl_code] > MBEDTLS_SSL_MAX_CONTENT_LEN ) + { + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + } + + conf->mfl_code = mfl_code; + + return( 0 ); +} +#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ + +#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) +void mbedtls_ssl_conf_truncated_hmac( mbedtls_ssl_config *conf, int truncate ) +{ + conf->trunc_hmac = truncate; +} +#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ + +#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) +void mbedtls_ssl_conf_cbc_record_splitting( mbedtls_ssl_config *conf, char split ) +{ + conf->cbc_record_splitting = split; +} +#endif + +void mbedtls_ssl_conf_legacy_renegotiation( mbedtls_ssl_config *conf, int allow_legacy ) +{ + conf->allow_legacy_renegotiation = allow_legacy; +} + +#if defined(MBEDTLS_SSL_RENEGOTIATION) +void mbedtls_ssl_conf_renegotiation( mbedtls_ssl_config *conf, int renegotiation ) +{ + conf->disable_renegotiation = renegotiation; +} + +void mbedtls_ssl_conf_renegotiation_enforced( mbedtls_ssl_config *conf, int max_records ) +{ + conf->renego_max_records = max_records; +} + +void mbedtls_ssl_conf_renegotiation_period( mbedtls_ssl_config *conf, + const unsigned char period[8] ) +{ + memcpy( conf->renego_period, period, 8 ); +} +#endif /* MBEDTLS_SSL_RENEGOTIATION */ + +#if defined(MBEDTLS_SSL_SESSION_TICKETS) +#if defined(MBEDTLS_SSL_CLI_C) +void mbedtls_ssl_conf_session_tickets( mbedtls_ssl_config *conf, int use_tickets ) +{ + conf->session_tickets = use_tickets; +} +#endif + +#if defined(MBEDTLS_SSL_SRV_C) +void mbedtls_ssl_conf_session_tickets_cb( mbedtls_ssl_config *conf, + mbedtls_ssl_ticket_write_t *f_ticket_write, + mbedtls_ssl_ticket_parse_t *f_ticket_parse, + void *p_ticket ) +{ + conf->f_ticket_write = f_ticket_write; + conf->f_ticket_parse = f_ticket_parse; + conf->p_ticket = p_ticket; +} +#endif +#endif /* MBEDTLS_SSL_SESSION_TICKETS */ + +#if defined(MBEDTLS_SSL_EXPORT_KEYS) +void mbedtls_ssl_conf_export_keys_cb( mbedtls_ssl_config *conf, + mbedtls_ssl_export_keys_t *f_export_keys, + void *p_export_keys ) +{ + conf->f_export_keys = f_export_keys; + conf->p_export_keys = p_export_keys; +} +#endif + +/* + * SSL get accessors + */ +size_t mbedtls_ssl_get_bytes_avail( const mbedtls_ssl_context *ssl ) +{ + return( ssl->in_offt == NULL ? 0 : ssl->in_msglen ); +} + +uint32_t mbedtls_ssl_get_verify_result( const mbedtls_ssl_context *ssl ) +{ + if( ssl->session != NULL ) + return( ssl->session->verify_result ); + + if( ssl->session_negotiate != NULL ) + return( ssl->session_negotiate->verify_result ); + + return( 0xFFFFFFFF ); +} + +const char *mbedtls_ssl_get_ciphersuite( const mbedtls_ssl_context *ssl ) +{ + if( ssl == NULL || ssl->session == NULL ) + return( NULL ); + + return mbedtls_ssl_get_ciphersuite_name( ssl->session->ciphersuite ); +} + +const char *mbedtls_ssl_get_version( const mbedtls_ssl_context *ssl ) +{ +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + { + switch( ssl->minor_ver ) + { + case MBEDTLS_SSL_MINOR_VERSION_2: + return( "DTLSv1.0" ); + + case MBEDTLS_SSL_MINOR_VERSION_3: + return( "DTLSv1.2" ); + + default: + return( "unknown (DTLS)" ); + } + } +#endif + + switch( ssl->minor_ver ) + { + case MBEDTLS_SSL_MINOR_VERSION_0: + return( "SSLv3.0" ); + + case MBEDTLS_SSL_MINOR_VERSION_1: + return( "TLSv1.0" ); + + case MBEDTLS_SSL_MINOR_VERSION_2: + return( "TLSv1.1" ); + + case MBEDTLS_SSL_MINOR_VERSION_3: + return( "TLSv1.2" ); + + default: + return( "unknown" ); + } +} + +int mbedtls_ssl_get_record_expansion( const mbedtls_ssl_context *ssl ) +{ + size_t transform_expansion; + const mbedtls_ssl_transform *transform = ssl->transform_out; + +#if defined(MBEDTLS_ZLIB_SUPPORT) + if( ssl->session_out->compression != MBEDTLS_SSL_COMPRESS_NULL ) + return( MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE ); +#endif + + if( transform == NULL ) + return( (int) mbedtls_ssl_hdr_len( ssl ) ); + + switch( mbedtls_cipher_get_cipher_mode( &transform->cipher_ctx_enc ) ) + { + case MBEDTLS_MODE_GCM: + case MBEDTLS_MODE_CCM: + case MBEDTLS_MODE_STREAM: + transform_expansion = transform->minlen; + break; + + case MBEDTLS_MODE_CBC: + transform_expansion = transform->maclen + + mbedtls_cipher_get_block_size( &transform->cipher_ctx_enc ); + break; + + default: + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + + return( (int)( mbedtls_ssl_hdr_len( ssl ) + transform_expansion ) ); +} + +#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) +size_t mbedtls_ssl_get_max_frag_len( const mbedtls_ssl_context *ssl ) +{ + size_t max_len; + + /* + * Assume mfl_code is correct since it was checked when set + */ + max_len = mfl_code_to_length[ssl->conf->mfl_code]; + + /* + * Check if a smaller max length was negotiated + */ + if( ssl->session_out != NULL && + mfl_code_to_length[ssl->session_out->mfl_code] < max_len ) + { + max_len = mfl_code_to_length[ssl->session_out->mfl_code]; + } + + return max_len; +} +#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ + +#if defined(MBEDTLS_X509_CRT_PARSE_C) +const mbedtls_x509_crt *mbedtls_ssl_get_peer_cert( const mbedtls_ssl_context *ssl ) +{ + if( ssl == NULL || ssl->session == NULL ) + return( NULL ); + + return( ssl->session->peer_cert ); +} +#endif /* MBEDTLS_X509_CRT_PARSE_C */ + +#if defined(MBEDTLS_SSL_CLI_C) +int mbedtls_ssl_get_session( const mbedtls_ssl_context *ssl, mbedtls_ssl_session *dst ) +{ + if( ssl == NULL || + dst == NULL || + ssl->session == NULL || + ssl->conf->endpoint != MBEDTLS_SSL_IS_CLIENT ) + { + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + } + + return( ssl_session_copy( dst, ssl->session ) ); +} +#endif /* MBEDTLS_SSL_CLI_C */ + +/* + * Perform a single step of the SSL handshake + */ +int mbedtls_ssl_handshake_step( mbedtls_ssl_context *ssl ) +{ + int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; + + if( ssl == NULL || ssl->conf == NULL ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + +#if defined(MBEDTLS_SSL_CLI_C) + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) + ret = mbedtls_ssl_handshake_client_step( ssl ); +#endif +#if defined(MBEDTLS_SSL_SRV_C) + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) + ret = mbedtls_ssl_handshake_server_step( ssl ); +#endif + + return( ret ); +} + +/* + * Perform the SSL handshake + */ +int mbedtls_ssl_handshake( mbedtls_ssl_context *ssl ) +{ + int ret = 0; + + if( ssl == NULL || ssl->conf == NULL ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> handshake" ) ); + + while( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) + { + ret = mbedtls_ssl_handshake_step( ssl ); + + if( ret != 0 ) + break; + } + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= handshake" ) ); + + return( ret ); +} + +#if defined(MBEDTLS_SSL_RENEGOTIATION) +#if defined(MBEDTLS_SSL_SRV_C) +/* + * Write HelloRequest to request renegotiation on server + */ +static int ssl_write_hello_request( mbedtls_ssl_context *ssl ) +{ + int ret; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write hello request" ) ); + + ssl->out_msglen = 4; + ssl->out_msgtype = MBEDTLS_SSL_MSG_HANDSHAKE; + ssl->out_msg[0] = MBEDTLS_SSL_HS_HELLO_REQUEST; + + if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); + return( ret ); + } + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write hello request" ) ); + + return( 0 ); +} +#endif /* MBEDTLS_SSL_SRV_C */ + +/* + * Actually renegotiate current connection, triggered by either: + * - any side: calling mbedtls_ssl_renegotiate(), + * - client: receiving a HelloRequest during mbedtls_ssl_read(), + * - server: receiving any handshake message on server during mbedtls_ssl_read() after + * the initial handshake is completed. + * If the handshake doesn't complete due to waiting for I/O, it will continue + * during the next calls to mbedtls_ssl_renegotiate() or mbedtls_ssl_read() respectively. + */ +static int ssl_start_renegotiation( mbedtls_ssl_context *ssl ) +{ + int ret; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> renegotiate" ) ); + + if( ( ret = ssl_handshake_init( ssl ) ) != 0 ) + return( ret ); + + /* RFC 6347 4.2.2: "[...] the HelloRequest will have message_seq = 0 and + * the ServerHello will have message_seq = 1" */ +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && + ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING ) + { + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) + ssl->handshake->out_msg_seq = 1; + else + ssl->handshake->in_msg_seq = 1; + } +#endif + + ssl->state = MBEDTLS_SSL_HELLO_REQUEST; + ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS; + + if( ( ret = mbedtls_ssl_handshake( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret ); + return( ret ); + } + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= renegotiate" ) ); + + return( 0 ); +} + +/* + * Renegotiate current connection on client, + * or request renegotiation on server + */ +int mbedtls_ssl_renegotiate( mbedtls_ssl_context *ssl ) +{ + int ret = MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE; + + if( ssl == NULL || ssl->conf == NULL ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + +#if defined(MBEDTLS_SSL_SRV_C) + /* On server, just send the request */ + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER ) + { + if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_PENDING; + + /* Did we already try/start sending HelloRequest? */ + if( ssl->out_left != 0 ) + return( mbedtls_ssl_flush_output( ssl ) ); + + return( ssl_write_hello_request( ssl ) ); + } +#endif /* MBEDTLS_SSL_SRV_C */ + +#if defined(MBEDTLS_SSL_CLI_C) + /* + * On client, either start the renegotiation process or, + * if already in progress, continue the handshake + */ + if( ssl->renego_status != MBEDTLS_SSL_RENEGOTIATION_IN_PROGRESS ) + { + if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + if( ( ret = ssl_start_renegotiation( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "ssl_start_renegotiation", ret ); + return( ret ); + } + } + else + { + if( ( ret = mbedtls_ssl_handshake( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret ); + return( ret ); + } + } +#endif /* MBEDTLS_SSL_CLI_C */ + + return( ret ); +} + +/* + * Check record counters and renegotiate if they're above the limit. + */ +static int ssl_check_ctr_renegotiate( mbedtls_ssl_context *ssl ) +{ + size_t ep_len = ssl_ep_len( ssl ); + int in_ctr_cmp; + int out_ctr_cmp; + + if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER || + ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING || + ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED ) + { + return( 0 ); + } + + in_ctr_cmp = memcmp( ssl->in_ctr + ep_len, + ssl->conf->renego_period + ep_len, 8 - ep_len ); + out_ctr_cmp = memcmp( ssl->out_ctr + ep_len, + ssl->conf->renego_period + ep_len, 8 - ep_len ); + + if( in_ctr_cmp <= 0 && out_ctr_cmp <= 0 ) + { + return( 0 ); + } + + MBEDTLS_SSL_DEBUG_MSG( 1, ( "record counter limit reached: renegotiate" ) ); + return( mbedtls_ssl_renegotiate( ssl ) ); +} +#endif /* MBEDTLS_SSL_RENEGOTIATION */ + +/* + * Receive application data decrypted from the SSL layer + */ +int mbedtls_ssl_read( mbedtls_ssl_context *ssl, unsigned char *buf, size_t len ) +{ + int ret, record_read = 0; + size_t n; + + if( ssl == NULL || ssl->conf == NULL ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> read" ) ); + +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + { + if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) + return( ret ); + + if( ssl->handshake != NULL && + ssl->handshake->retransmit_state == MBEDTLS_SSL_RETRANS_SENDING ) + { + if( ( ret = mbedtls_ssl_resend( ssl ) ) != 0 ) + return( ret ); + } + } +#endif + +#if defined(MBEDTLS_SSL_RENEGOTIATION) + if( ( ret = ssl_check_ctr_renegotiate( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "ssl_check_ctr_renegotiate", ret ); + return( ret ); + } +#endif + + if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) + { + ret = mbedtls_ssl_handshake( ssl ); + if( ret == MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO ) + { + record_read = 1; + } + else if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret ); + return( ret ); + } + } + + if( ssl->in_offt == NULL ) + { + /* Start timer if not already running */ + if( ssl->f_get_timer != NULL && + ssl->f_get_timer( ssl->p_timer ) == -1 ) + { + ssl_set_timer( ssl, ssl->conf->read_timeout ); + } + + if( ! record_read ) + { + if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 ) + { + if( ret == MBEDTLS_ERR_SSL_CONN_EOF ) + return( 0 ); + + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); + return( ret ); + } + } + + if( ssl->in_msglen == 0 && + ssl->in_msgtype == MBEDTLS_SSL_MSG_APPLICATION_DATA ) + { + /* + * OpenSSL sends empty messages to randomize the IV + */ + if( ( ret = mbedtls_ssl_read_record( ssl ) ) != 0 ) + { + if( ret == MBEDTLS_ERR_SSL_CONN_EOF ) + return( 0 ); + + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_read_record", ret ); + return( ret ); + } + } + +#if defined(MBEDTLS_SSL_RENEGOTIATION) + if( ssl->in_msgtype == MBEDTLS_SSL_MSG_HANDSHAKE ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "received handshake message" ) ); + +#if defined(MBEDTLS_SSL_CLI_C) + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT && + ( ssl->in_msg[0] != MBEDTLS_SSL_HS_HELLO_REQUEST || + ssl->in_hslen != mbedtls_ssl_hs_hdr_len( ssl ) ) ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake received (not HelloRequest)" ) ); + + /* With DTLS, drop the packet (probably from last handshake) */ +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + return( MBEDTLS_ERR_SSL_WANT_READ ); +#endif + return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); + } + + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && + ssl->in_msg[0] != MBEDTLS_SSL_HS_CLIENT_HELLO ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "handshake received (not ClientHello)" ) ); + + /* With DTLS, drop the packet (probably from last handshake) */ +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + return( MBEDTLS_ERR_SSL_WANT_READ ); +#endif + return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); + } +#endif + + if( ssl->conf->disable_renegotiation == MBEDTLS_SSL_RENEGOTIATION_DISABLED || + ( ssl->secure_renegotiation == MBEDTLS_SSL_LEGACY_RENEGOTIATION && + ssl->conf->allow_legacy_renegotiation == + MBEDTLS_SSL_LEGACY_NO_RENEGOTIATION ) ) + { + MBEDTLS_SSL_DEBUG_MSG( 3, ( "refusing renegotiation, sending alert" ) ); + +#if defined(MBEDTLS_SSL_PROTO_SSL3) + if( ssl->minor_ver == MBEDTLS_SSL_MINOR_VERSION_0 ) + { + /* + * SSLv3 does not have a "no_renegotiation" alert + */ + if( ( ret = mbedtls_ssl_send_fatal_handshake_failure( ssl ) ) != 0 ) + return( ret ); + } + else +#endif /* MBEDTLS_SSL_PROTO_SSL3 */ +#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) || \ + defined(MBEDTLS_SSL_PROTO_TLS1_2) + if( ssl->minor_ver >= MBEDTLS_SSL_MINOR_VERSION_1 ) + { + if( ( ret = mbedtls_ssl_send_alert_message( ssl, + MBEDTLS_SSL_ALERT_LEVEL_WARNING, + MBEDTLS_SSL_ALERT_MSG_NO_RENEGOTIATION ) ) != 0 ) + { + return( ret ); + } + } + else +#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 || + MBEDTLS_SSL_PROTO_TLS1_2 */ + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); + return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); + } + } + else + { + /* DTLS clients need to know renego is server-initiated */ +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM && + ssl->conf->endpoint == MBEDTLS_SSL_IS_CLIENT ) + { + ssl->renego_status = MBEDTLS_SSL_RENEGOTIATION_PENDING; + } +#endif + ret = ssl_start_renegotiation( ssl ); + if( ret == MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO ) + { + record_read = 1; + } + else if( ret != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "ssl_start_renegotiation", ret ); + return( ret ); + } + } + + /* If a non-handshake record was read during renego, fallthrough, + * else tell the user they should call mbedtls_ssl_read() again */ + if( ! record_read ) + return( MBEDTLS_ERR_SSL_WANT_READ ); + } + else if( ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING ) + { + + if( ssl->conf->renego_max_records >= 0 ) + { + if( ++ssl->renego_records_seen > ssl->conf->renego_max_records ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "renegotiation requested, " + "but not honored by client" ) ); + return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); + } + } + } +#endif /* MBEDTLS_SSL_RENEGOTIATION */ + + /* Fatal and closure alerts handled by mbedtls_ssl_read_record() */ + if( ssl->in_msgtype == MBEDTLS_SSL_MSG_ALERT ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "ignoring non-fatal non-closure alert" ) ); + return( MBEDTLS_ERR_SSL_WANT_READ ); + } + + if( ssl->in_msgtype != MBEDTLS_SSL_MSG_APPLICATION_DATA ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "bad application data message" ) ); + return( MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE ); + } + + ssl->in_offt = ssl->in_msg; + + /* We're going to return something now, cancel timer, + * except if handshake (renegotiation) is in progress */ + if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER ) + ssl_set_timer( ssl, 0 ); + +#if defined(MBEDTLS_SSL_PROTO_DTLS) + /* If we requested renego but received AppData, resend HelloRequest. + * Do it now, after setting in_offt, to avoid taking this branch + * again if ssl_write_hello_request() returns WANT_WRITE */ +#if defined(MBEDTLS_SSL_SRV_C) && defined(MBEDTLS_SSL_RENEGOTIATION) + if( ssl->conf->endpoint == MBEDTLS_SSL_IS_SERVER && + ssl->renego_status == MBEDTLS_SSL_RENEGOTIATION_PENDING ) + { + if( ( ret = ssl_resend_hello_request( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "ssl_resend_hello_request", ret ); + return( ret ); + } + } +#endif /* MBEDTLS_SSL_SRV_C && MBEDTLS_SSL_RENEGOTIATION */ +#endif + } + + n = ( len < ssl->in_msglen ) + ? len : ssl->in_msglen; + + memcpy( buf, ssl->in_offt, n ); + ssl->in_msglen -= n; + + if( ssl->in_msglen == 0 ) + /* all bytes consumed */ + ssl->in_offt = NULL; + else + /* more data available */ + ssl->in_offt += n; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= read" ) ); + + return( (int) n ); +} + +/* + * Send application data to be encrypted by the SSL layer, + * taking care of max fragment length and buffer size + */ +static int ssl_write_real( mbedtls_ssl_context *ssl, + const unsigned char *buf, size_t len ) +{ + int ret; +#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) + size_t max_len = mbedtls_ssl_get_max_frag_len( ssl ); + + if( len > max_len ) + { +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( ssl->conf->transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "fragment larger than the (negotiated) " + "maximum fragment length: %d > %d", + len, max_len ) ); + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + } + else +#endif + len = max_len; + } +#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ + + if( ssl->out_left != 0 ) + { + if( ( ret = mbedtls_ssl_flush_output( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_flush_output", ret ); + return( ret ); + } + } + else + { + + if (len > MBEDTLS_SSL_BUFFER_LEN - 13) { + MBEDTLS_SSL_DEBUG_MSG( 1, ( "input larger than the out msg " + "maximum length: 0x%x > 0x%x", + len, MBEDTLS_SSL_BUFFER_LEN - 13 ) ); + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + } + + ssl->out_msglen = len; + ssl->out_msgtype = MBEDTLS_SSL_MSG_APPLICATION_DATA; + memcpy( ssl->out_msg, buf, len ); + + if( ( ret = mbedtls_ssl_write_record( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_write_record", ret ); + return( ret ); + } + } + + return( (int) len ); +} + +/* + * Write application data, doing 1/n-1 splitting if necessary. + * + * With non-blocking I/O, ssl_write_real() may return WANT_WRITE, + * then the caller will call us again with the same arguments, so + * remember wether we already did the split or not. + */ +#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) +static int ssl_write_split( mbedtls_ssl_context *ssl, + const unsigned char *buf, size_t len ) +{ + int ret; + + if( ssl->conf->cbc_record_splitting == + MBEDTLS_SSL_CBC_RECORD_SPLITTING_DISABLED || + len <= 1 || + ssl->minor_ver > MBEDTLS_SSL_MINOR_VERSION_1 || + mbedtls_cipher_get_cipher_mode( &ssl->transform_out->cipher_ctx_enc ) + != MBEDTLS_MODE_CBC ) + { + return( ssl_write_real( ssl, buf, len ) ); + } + + if( ssl->split_done == 0 ) + { + if( ( ret = ssl_write_real( ssl, buf, 1 ) ) <= 0 ) + return( ret ); + ssl->split_done = 1; + } + + if( ( ret = ssl_write_real( ssl, buf + 1, len - 1 ) ) <= 0 ) + return( ret ); + ssl->split_done = 0; + + return( ret + 1 ); +} +#endif /* MBEDTLS_SSL_CBC_RECORD_SPLITTING */ + +/* + * Write application data (public-facing wrapper) + */ +int mbedtls_ssl_write( mbedtls_ssl_context *ssl, const unsigned char *buf, size_t len ) +{ + int ret; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write" ) ); + + if( ssl == NULL || ssl->conf == NULL ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + +#if defined(MBEDTLS_SSL_RENEGOTIATION) + if( ( ret = ssl_check_ctr_renegotiate( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "ssl_check_ctr_renegotiate", ret ); + return( ret ); + } +#endif + + if( ssl->state != MBEDTLS_SSL_HANDSHAKE_OVER ) + { + if( ( ret = mbedtls_ssl_handshake( ssl ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_handshake", ret ); + return( ret ); + } + } + +#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) + ret = ssl_write_split( ssl, buf, len ); +#else + ret = ssl_write_real( ssl, buf, len ); +#endif + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write" ) ); + + return( ret ); +} + +/* + * Notify the peer that the connection is being closed + */ +int mbedtls_ssl_close_notify( mbedtls_ssl_context *ssl ) +{ + int ret; + + if( ssl == NULL || ssl->conf == NULL ) + return( MBEDTLS_ERR_SSL_BAD_INPUT_DATA ); + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> write close notify" ) ); + + if( ssl->out_left != 0 ) + return( mbedtls_ssl_flush_output( ssl ) ); + + if( ssl->state == MBEDTLS_SSL_HANDSHAKE_OVER ) + { + if( ( ret = mbedtls_ssl_send_alert_message( ssl, + MBEDTLS_SSL_ALERT_LEVEL_WARNING, + MBEDTLS_SSL_ALERT_MSG_CLOSE_NOTIFY ) ) != 0 ) + { + MBEDTLS_SSL_DEBUG_RET( 1, "mbedtls_ssl_send_alert_message", ret ); + return( ret ); + } + } + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= write close notify" ) ); + + return( 0 ); +} + +void mbedtls_ssl_transform_free( mbedtls_ssl_transform *transform ) +{ + if( transform == NULL ) + return; + +#if defined(MBEDTLS_ZLIB_SUPPORT) + deflateEnd( &transform->ctx_deflate ); + inflateEnd( &transform->ctx_inflate ); +#endif + + mbedtls_cipher_free( &transform->cipher_ctx_enc ); + mbedtls_cipher_free( &transform->cipher_ctx_dec ); + + mbedtls_md_free( &transform->md_ctx_enc ); + mbedtls_md_free( &transform->md_ctx_dec ); + + mbedtls_zeroize( transform, sizeof( mbedtls_ssl_transform ) ); +} + +#if defined(MBEDTLS_X509_CRT_PARSE_C) +static void ssl_key_cert_free( mbedtls_ssl_key_cert *key_cert ) +{ + mbedtls_ssl_key_cert *cur = key_cert, *next; + + while( cur != NULL ) + { + next = cur->next; + mbedtls_free( cur ); + cur = next; + } +} +#endif /* MBEDTLS_X509_CRT_PARSE_C */ + +void mbedtls_ssl_handshake_free( mbedtls_ssl_handshake_params *handshake ) +{ + if( handshake == NULL ) + return; + +#if defined(MBEDTLS_SSL_PROTO_SSL3) || defined(MBEDTLS_SSL_PROTO_TLS1) || \ + defined(MBEDTLS_SSL_PROTO_TLS1_1) + mbedtls_md5_free( &handshake->fin_md5 ); + mbedtls_sha1_free( &handshake->fin_sha1 ); +#endif +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) +#if defined(MBEDTLS_SHA256_C) + mbedtls_sha256_free( &handshake->fin_sha256 ); +#endif +#if defined(MBEDTLS_SHA512_C) + mbedtls_sha512_free( &handshake->fin_sha512 ); +#endif +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ + +#if defined(MBEDTLS_DHM_C) + mbedtls_dhm_free( &handshake->dhm_ctx ); +#endif +#if defined(MBEDTLS_ECDH_C) + mbedtls_ecdh_free( &handshake->ecdh_ctx ); +#endif +#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) + mbedtls_ecjpake_free( &handshake->ecjpake_ctx ); +#if defined(MBEDTLS_SSL_CLI_C) + mbedtls_free( handshake->ecjpake_cache ); + handshake->ecjpake_cache = NULL; + handshake->ecjpake_cache_len = 0; +#endif +#endif + +#if defined(MBEDTLS_ECDH_C) || defined(MBEDTLS_ECDSA_C) || \ + defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) + /* explicit void pointer cast for buggy MS compiler */ + mbedtls_free( (void *) handshake->curves ); +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) + if( handshake->psk != NULL ) + { + mbedtls_zeroize( handshake->psk, handshake->psk_len ); + mbedtls_free( handshake->psk ); + } +#endif + +#if defined(MBEDTLS_X509_CRT_PARSE_C) && \ + defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) + /* + * Free only the linked list wrapper, not the keys themselves + * since the belong to the SNI callback + */ + if( handshake->sni_key_cert != NULL ) + { + mbedtls_ssl_key_cert *cur = handshake->sni_key_cert, *next; + + while( cur != NULL ) + { + next = cur->next; + mbedtls_free( cur ); + cur = next; + } + } +#endif /* MBEDTLS_X509_CRT_PARSE_C && MBEDTLS_SSL_SERVER_NAME_INDICATION */ + +#if defined(MBEDTLS_SSL_PROTO_DTLS) + mbedtls_free( handshake->verify_cookie ); + mbedtls_free( handshake->hs_msg ); + ssl_flight_free( handshake->flight ); +#endif + + mbedtls_zeroize( handshake, sizeof( mbedtls_ssl_handshake_params ) ); +} + +void mbedtls_ssl_session_free( mbedtls_ssl_session *session ) +{ + if( session == NULL ) + return; + +#if defined(MBEDTLS_X509_CRT_PARSE_C) + if( session->peer_cert != NULL ) + { + mbedtls_x509_crt_free( session->peer_cert ); + mbedtls_free( session->peer_cert ); + } +#endif + +#if defined(MBEDTLS_SSL_SESSION_TICKETS) && defined(MBEDTLS_SSL_CLI_C) + mbedtls_free( session->ticket ); +#endif + + mbedtls_zeroize( session, sizeof( mbedtls_ssl_session ) ); +} + +/* + * Free an SSL context + */ +void mbedtls_ssl_free( mbedtls_ssl_context *ssl ) +{ + if( ssl == NULL ) + return; + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "=> free" ) ); + + if( ssl->out_buf != NULL ) + { + mbedtls_zeroize( ssl->out_buf, MBEDTLS_SSL_BUFFER_LEN ); + mbedtls_free( ssl->out_buf ); + } + + if( ssl->in_buf != NULL ) + { + mbedtls_zeroize( ssl->in_buf, MBEDTLS_SSL_BUFFER_LEN ); + mbedtls_free( ssl->in_buf ); + } + +#if defined(MBEDTLS_ZLIB_SUPPORT) + if( ssl->compress_buf != NULL ) + { + mbedtls_zeroize( ssl->compress_buf, MBEDTLS_SSL_BUFFER_LEN ); + mbedtls_free( ssl->compress_buf ); + } +#endif + + if( ssl->transform ) + { + mbedtls_ssl_transform_free( ssl->transform ); + mbedtls_free( ssl->transform ); + } + + if( ssl->handshake ) + { + mbedtls_ssl_handshake_free( ssl->handshake ); + mbedtls_ssl_transform_free( ssl->transform_negotiate ); + mbedtls_ssl_session_free( ssl->session_negotiate ); + + mbedtls_free( ssl->handshake ); + mbedtls_free( ssl->transform_negotiate ); + mbedtls_free( ssl->session_negotiate ); + } + + if( ssl->session ) + { + mbedtls_ssl_session_free( ssl->session ); + mbedtls_free( ssl->session ); + } + +#if defined(MBEDTLS_X509_CRT_PARSE_C) + if( ssl->hostname != NULL ) + { + mbedtls_zeroize( ssl->hostname, strlen( ssl->hostname ) ); + mbedtls_free( ssl->hostname ); + } +#endif + +#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) + if( mbedtls_ssl_hw_record_finish != NULL ) + { + MBEDTLS_SSL_DEBUG_MSG( 2, ( "going for mbedtls_ssl_hw_record_finish()" ) ); + mbedtls_ssl_hw_record_finish( ssl ); + } +#endif + +#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C) + mbedtls_free( ssl->cli_id ); +#endif + + MBEDTLS_SSL_DEBUG_MSG( 2, ( "<= free" ) ); + + /* Actually clear after last debug message */ + mbedtls_zeroize( ssl, sizeof( mbedtls_ssl_context ) ); +} + +/* + * Initialze mbedtls_ssl_config + */ +void mbedtls_ssl_config_init( mbedtls_ssl_config *conf ) +{ + memset( conf, 0, sizeof( mbedtls_ssl_config ) ); +} + +#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) +static int ssl_preset_default_hashes[] = { +#if defined(MBEDTLS_SHA512_C) + MBEDTLS_MD_SHA512, + MBEDTLS_MD_SHA384, +#endif +#if defined(MBEDTLS_SHA256_C) + MBEDTLS_MD_SHA256, +#endif +#if defined(MBEDTLS_SHA1_C) + MBEDTLS_MD_SHA1, +#endif +#if defined(MBEDTLS_MD5_C) + MBEDTLS_MD_MD5, +#endif + MBEDTLS_MD_NONE +}; +#endif + +#if !defined(MBEDTLS_IOT_SPECIFIC) +static int ssl_preset_suiteb_ciphersuites[] = { + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + 0 +}; + +#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) +static int ssl_preset_suiteb_hashes[] = { + MBEDTLS_MD_SHA256, + MBEDTLS_MD_SHA384, + MBEDTLS_MD_NONE +}; +#endif + +#if defined(MBEDTLS_ECP_C) +static mbedtls_ecp_group_id ssl_preset_suiteb_curves[] = { + MBEDTLS_ECP_DP_SECP256R1, + MBEDTLS_ECP_DP_SECP384R1, + MBEDTLS_ECP_DP_NONE +}; +#endif +#endif /* MBEDTLS_IOT_SPECIFIC */ + +/* + * Load default in mbedtls_ssl_config + */ +int mbedtls_ssl_config_defaults( mbedtls_ssl_config *conf, + int endpoint, int transport, int preset ) +{ +#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C) + int ret; +#endif + + /* Use the functions here so that they are covered in tests, + * but otherwise access member directly for efficiency */ + mbedtls_ssl_conf_endpoint( conf, endpoint ); + mbedtls_ssl_conf_transport( conf, transport ); + + /* + * Things that are common to all presets + */ +#if defined(MBEDTLS_SSL_CLI_C) + if( endpoint == MBEDTLS_SSL_IS_CLIENT ) + { + conf->authmode = MBEDTLS_SSL_VERIFY_REQUIRED; +#if defined(MBEDTLS_SSL_SESSION_TICKETS) + conf->session_tickets = MBEDTLS_SSL_SESSION_TICKETS_ENABLED; +#endif + } +#endif + +#if defined(MBEDTLS_ARC4_C) + conf->arc4_disabled = MBEDTLS_SSL_ARC4_DISABLED; +#endif + +#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) + conf->encrypt_then_mac = MBEDTLS_SSL_ETM_ENABLED; +#endif + +#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) + conf->extended_ms = MBEDTLS_SSL_EXTENDED_MS_ENABLED; +#endif + +#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) + conf->cbc_record_splitting = MBEDTLS_SSL_CBC_RECORD_SPLITTING_ENABLED; +#endif + +#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C) + conf->f_cookie_write = ssl_cookie_write_dummy; + conf->f_cookie_check = ssl_cookie_check_dummy; +#endif + +#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) + conf->anti_replay = MBEDTLS_SSL_ANTI_REPLAY_ENABLED; +#endif + +#if defined(MBEDTLS_SSL_PROTO_DTLS) + conf->hs_timeout_min = MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MIN; + conf->hs_timeout_max = MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MAX; +#endif + +#if defined(MBEDTLS_SSL_RENEGOTIATION) + conf->renego_max_records = MBEDTLS_SSL_RENEGO_MAX_RECORDS_DEFAULT; + memset( conf->renego_period, 0x00, 2 ); + memset( conf->renego_period + 2, 0xFF, 6 ); +#endif + +#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_SRV_C) + if( endpoint == MBEDTLS_SSL_IS_SERVER ) + { + if( ( ret = mbedtls_ssl_conf_dh_param( conf, + MBEDTLS_DHM_RFC5114_MODP_2048_P, + MBEDTLS_DHM_RFC5114_MODP_2048_G ) ) != 0 ) + { + return( ret ); + } + } +#endif + + /* + * Preset-specific defaults + */ + switch( preset ) + { +#if !defined(MBEDTLS_IOT_SPECIFIC) + /* + * NSA Suite B + */ + case MBEDTLS_SSL_PRESET_SUITEB: + conf->min_major_ver = MBEDTLS_SSL_MAJOR_VERSION_3; + conf->min_minor_ver = MBEDTLS_SSL_MINOR_VERSION_3; /* TLS 1.2 */ + conf->max_major_ver = MBEDTLS_SSL_MAX_MAJOR_VERSION; + conf->max_minor_ver = MBEDTLS_SSL_MAX_MINOR_VERSION; + + conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_0] = + conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_1] = + conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_2] = + conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_3] = + ssl_preset_suiteb_ciphersuites; + +#if defined(MBEDTLS_X509_CRT_PARSE_C) + conf->cert_profile = &mbedtls_x509_crt_profile_suiteb; +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) + conf->sig_hashes = ssl_preset_suiteb_hashes; +#endif + +#if defined(MBEDTLS_ECP_C) + conf->curve_list = ssl_preset_suiteb_curves; +#endif + break; +#endif /* MBEDTLS_IOT_SPECIFIC */ + + /* + * Default + */ + default: + conf->min_major_ver = MBEDTLS_SSL_MAJOR_VERSION_3; + conf->min_minor_ver = MBEDTLS_SSL_MINOR_VERSION_3; /* TLS 1.2 */ + conf->max_major_ver = MBEDTLS_SSL_MAX_MAJOR_VERSION; + conf->max_minor_ver = MBEDTLS_SSL_MAX_MINOR_VERSION; + +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + conf->min_minor_ver = MBEDTLS_SSL_MINOR_VERSION_2; +#endif + + conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_0] = + conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_1] = + conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_2] = + conf->ciphersuite_list[MBEDTLS_SSL_MINOR_VERSION_3] = + mbedtls_ssl_list_ciphersuites(); + +#if defined(MBEDTLS_X509_CRT_PARSE_C) + conf->cert_profile = &mbedtls_x509_crt_profile_default; +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) + conf->sig_hashes = ssl_preset_default_hashes; +#endif + +#if defined(MBEDTLS_ECP_C) + conf->curve_list = mbedtls_ecp_grp_id_list(); +#endif + +#if defined(MBEDTLS_DHM_C) && defined(MBEDTLS_SSL_CLI_C) + conf->dhm_min_bitlen = 1024; +#endif + } + + return( 0 ); +} + +/* + * Free mbedtls_ssl_config + */ +void mbedtls_ssl_config_free( mbedtls_ssl_config *conf ) +{ +#if defined(MBEDTLS_DHM_C) + mbedtls_mpi_free( &conf->dhm_P ); + mbedtls_mpi_free( &conf->dhm_G ); +#endif + +#if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED) + if( conf->psk != NULL ) + { + mbedtls_zeroize( conf->psk, conf->psk_len ); + mbedtls_zeroize( conf->psk_identity, conf->psk_identity_len ); + mbedtls_free( conf->psk ); + mbedtls_free( conf->psk_identity ); + conf->psk_len = 0; + conf->psk_identity_len = 0; + } +#endif + +#if defined(MBEDTLS_X509_CRT_PARSE_C) + ssl_key_cert_free( conf->key_cert ); +#endif + + mbedtls_zeroize( conf, sizeof( mbedtls_ssl_config ) ); +} + +#if defined(MBEDTLS_PK_C) && \ + ( defined(MBEDTLS_RSA_C) || defined(MBEDTLS_ECDSA_C) ) +/* + * Convert between MBEDTLS_PK_XXX and SSL_SIG_XXX + */ +unsigned char mbedtls_ssl_sig_from_pk( mbedtls_pk_context *pk ) +{ +#if defined(MBEDTLS_RSA_C) + if( mbedtls_pk_can_do( pk, MBEDTLS_PK_RSA ) ) + return( MBEDTLS_SSL_SIG_RSA ); +#endif +#if defined(MBEDTLS_ECDSA_C) + if( mbedtls_pk_can_do( pk, MBEDTLS_PK_ECDSA ) ) + return( MBEDTLS_SSL_SIG_ECDSA ); +#endif + return( MBEDTLS_SSL_SIG_ANON ); +} + +mbedtls_pk_type_t mbedtls_ssl_pk_alg_from_sig( unsigned char sig ) +{ + switch( sig ) + { +#if defined(MBEDTLS_RSA_C) + case MBEDTLS_SSL_SIG_RSA: + return( MBEDTLS_PK_RSA ); +#endif +#if defined(MBEDTLS_ECDSA_C) + case MBEDTLS_SSL_SIG_ECDSA: + return( MBEDTLS_PK_ECDSA ); +#endif + default: + return( MBEDTLS_PK_NONE ); + } +} +#endif /* MBEDTLS_PK_C && ( MBEDTLS_RSA_C || MBEDTLS_ECDSA_C ) */ + +/* + * Convert from MBEDTLS_SSL_HASH_XXX to MBEDTLS_MD_XXX + */ +mbedtls_md_type_t mbedtls_ssl_md_alg_from_hash( unsigned char hash ) +{ + switch( hash ) + { +#if defined(MBEDTLS_MD5_C) + case MBEDTLS_SSL_HASH_MD5: + return( MBEDTLS_MD_MD5 ); +#endif +#if defined(MBEDTLS_SHA1_C) + case MBEDTLS_SSL_HASH_SHA1: + return( MBEDTLS_MD_SHA1 ); +#endif +#if defined(MBEDTLS_SHA256_C) + case MBEDTLS_SSL_HASH_SHA224: + return( MBEDTLS_MD_SHA224 ); + case MBEDTLS_SSL_HASH_SHA256: + return( MBEDTLS_MD_SHA256 ); +#endif +#if defined(MBEDTLS_SHA512_C) + case MBEDTLS_SSL_HASH_SHA384: + return( MBEDTLS_MD_SHA384 ); + case MBEDTLS_SSL_HASH_SHA512: + return( MBEDTLS_MD_SHA512 ); +#endif + default: + return( MBEDTLS_MD_NONE ); + } +} + +/* + * Convert from MBEDTLS_MD_XXX to MBEDTLS_SSL_HASH_XXX + */ +unsigned char mbedtls_ssl_hash_from_md_alg( int md ) +{ + switch( md ) + { +#if defined(MBEDTLS_MD5_C) + case MBEDTLS_MD_MD5: + return( MBEDTLS_SSL_HASH_MD5 ); +#endif +#if defined(MBEDTLS_SHA1_C) + case MBEDTLS_MD_SHA1: + return( MBEDTLS_SSL_HASH_SHA1 ); +#endif +#if defined(MBEDTLS_SHA256_C) + case MBEDTLS_MD_SHA224: + return( MBEDTLS_SSL_HASH_SHA224 ); + case MBEDTLS_MD_SHA256: + return( MBEDTLS_SSL_HASH_SHA256 ); +#endif +#if defined(MBEDTLS_SHA512_C) + case MBEDTLS_MD_SHA384: + return( MBEDTLS_SSL_HASH_SHA384 ); + case MBEDTLS_MD_SHA512: + return( MBEDTLS_SSL_HASH_SHA512 ); +#endif + default: + return( MBEDTLS_SSL_HASH_NONE ); + } +} + +#if defined(MBEDTLS_ECP_C) +/* + * Check if a curve proposed by the peer is in our list. + * Return 0 if we're willing to use it, -1 otherwise. + */ +int mbedtls_ssl_check_curve( const mbedtls_ssl_context *ssl, mbedtls_ecp_group_id grp_id ) +{ + const mbedtls_ecp_group_id *gid; + + if( ssl->conf->curve_list == NULL ) + return( -1 ); + + for( gid = ssl->conf->curve_list; *gid != MBEDTLS_ECP_DP_NONE; gid++ ) + if( *gid == grp_id ) + return( 0 ); + + return( -1 ); +} +#endif /* MBEDTLS_ECP_C */ + +#if defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) +/* + * Check if a hash proposed by the peer is in our list. + * Return 0 if we're willing to use it, -1 otherwise. + */ +int mbedtls_ssl_check_sig_hash( const mbedtls_ssl_context *ssl, + mbedtls_md_type_t md ) +{ + const int *cur; + + if( ssl->conf->sig_hashes == NULL ) + return( -1 ); + + for( cur = ssl->conf->sig_hashes; *cur != MBEDTLS_MD_NONE; cur++ ) + if( *cur == (int) md ) + return( 0 ); + + return( -1 ); +} +#endif /* MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED */ + +#if defined(MBEDTLS_X509_CRT_PARSE_C) +int mbedtls_ssl_check_cert_usage( const mbedtls_x509_crt *cert, + const mbedtls_ssl_ciphersuite_t *ciphersuite, + int cert_endpoint, + uint32_t *flags ) +{ + int ret = 0; +#if defined(MBEDTLS_X509_CHECK_KEY_USAGE) + int usage = 0; +#endif +#if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE) + const char *ext_oid; + size_t ext_len; +#endif + +#if !defined(MBEDTLS_X509_CHECK_KEY_USAGE) && \ + !defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE) + ((void) cert); + ((void) cert_endpoint); + ((void) flags); +#endif + +#if defined(MBEDTLS_X509_CHECK_KEY_USAGE) + if( cert_endpoint == MBEDTLS_SSL_IS_SERVER ) + { + /* Server part of the key exchange */ + switch( ciphersuite->key_exchange ) + { + case MBEDTLS_KEY_EXCHANGE_RSA: + case MBEDTLS_KEY_EXCHANGE_RSA_PSK: + usage = MBEDTLS_X509_KU_KEY_ENCIPHERMENT; + break; + + case MBEDTLS_KEY_EXCHANGE_DHE_RSA: + case MBEDTLS_KEY_EXCHANGE_ECDHE_RSA: + case MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA: + usage = MBEDTLS_X509_KU_DIGITAL_SIGNATURE; + break; + + case MBEDTLS_KEY_EXCHANGE_ECDH_RSA: + case MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA: + usage = MBEDTLS_X509_KU_KEY_AGREEMENT; + break; + + /* Don't use default: we want warnings when adding new values */ + case MBEDTLS_KEY_EXCHANGE_NONE: + case MBEDTLS_KEY_EXCHANGE_PSK: + case MBEDTLS_KEY_EXCHANGE_DHE_PSK: + case MBEDTLS_KEY_EXCHANGE_ECDHE_PSK: + case MBEDTLS_KEY_EXCHANGE_ECJPAKE: + usage = 0; + } + } + else + { + /* Client auth: we only implement rsa_sign and mbedtls_ecdsa_sign for now */ + usage = MBEDTLS_X509_KU_DIGITAL_SIGNATURE; + } + + if( mbedtls_x509_crt_check_key_usage( cert, usage ) != 0 ) + { + *flags |= MBEDTLS_X509_BADCERT_KEY_USAGE; + ret = -1; + } +#else + ((void) ciphersuite); +#endif /* MBEDTLS_X509_CHECK_KEY_USAGE */ + +#if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE) + if( cert_endpoint == MBEDTLS_SSL_IS_SERVER ) + { + ext_oid = MBEDTLS_OID_SERVER_AUTH; + ext_len = MBEDTLS_OID_SIZE( MBEDTLS_OID_SERVER_AUTH ); + } + else + { + ext_oid = MBEDTLS_OID_CLIENT_AUTH; + ext_len = MBEDTLS_OID_SIZE( MBEDTLS_OID_CLIENT_AUTH ); + } + + if( mbedtls_x509_crt_check_extended_key_usage( cert, ext_oid, ext_len ) != 0 ) + { + *flags |= MBEDTLS_X509_BADCERT_EXT_KEY_USAGE; + ret = -1; + } +#endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */ + + return( ret ); +} +#endif /* MBEDTLS_X509_CRT_PARSE_C */ + +/* + * Convert version numbers to/from wire format + * and, for DTLS, to/from TLS equivalent. + * + * For TLS this is the identity. + * For DTLS, use 1's complement (v -> 255 - v, and then map as follows: + * 1.0 <-> 3.2 (DTLS 1.0 is based on TLS 1.1) + * 1.x <-> 3.x+1 for x != 0 (DTLS 1.2 based on TLS 1.2) + */ +void mbedtls_ssl_write_version( int major, int minor, int transport, + unsigned char ver[2] ) +{ +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + { + if( minor == MBEDTLS_SSL_MINOR_VERSION_2 ) + --minor; /* DTLS 1.0 stored as TLS 1.1 internally */ + + ver[0] = (unsigned char)( 255 - ( major - 2 ) ); + ver[1] = (unsigned char)( 255 - ( minor - 1 ) ); + } + else +#else + ((void) transport); +#endif + { + ver[0] = (unsigned char) major; + ver[1] = (unsigned char) minor; + } +} + +void mbedtls_ssl_read_version( int *major, int *minor, int transport, + const unsigned char ver[2] ) +{ +#if defined(MBEDTLS_SSL_PROTO_DTLS) + if( transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM ) + { + *major = 255 - ver[0] + 2; + *minor = 255 - ver[1] + 1; + + if( *minor == MBEDTLS_SSL_MINOR_VERSION_1 ) + ++*minor; /* DTLS 1.0 stored as TLS 1.1 internally */ + } + else +#else + ((void) transport); +#endif + { + *major = ver[0]; + *minor = ver[1]; + } +} + +int mbedtls_ssl_set_calc_verify_md( mbedtls_ssl_context *ssl, int md ) +{ +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) + if( ssl->minor_ver != MBEDTLS_SSL_MINOR_VERSION_3 ) + return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH; + + switch( md ) + { +#if defined(MBEDTLS_SSL_PROTO_TLS1) || defined(MBEDTLS_SSL_PROTO_TLS1_1) +#if defined(MBEDTLS_MD5_C) + case MBEDTLS_SSL_HASH_MD5: + return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH; +#endif +#if defined(MBEDTLS_SHA1_C) + case MBEDTLS_SSL_HASH_SHA1: + ssl->handshake->calc_verify = ssl_calc_verify_tls; + break; +#endif +#endif /* MBEDTLS_SSL_PROTO_TLS1 || MBEDTLS_SSL_PROTO_TLS1_1 */ +#if defined(MBEDTLS_SHA512_C) + case MBEDTLS_SSL_HASH_SHA384: + ssl->handshake->calc_verify = ssl_calc_verify_tls_sha384; + break; +#endif +#if defined(MBEDTLS_SHA256_C) + case MBEDTLS_SSL_HASH_SHA256: + ssl->handshake->calc_verify = ssl_calc_verify_tls_sha256; + break; +#endif + default: + return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH; + } + + return 0; +#else /* !MBEDTLS_SSL_PROTO_TLS1_2 */ + (void) ssl; + (void) md; + + return MBEDTLS_ERR_SSL_INVALID_VERIFY_HASH; +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ +} + +#endif /* MBEDTLS_SSL_TLS_C */ diff --git a/security/mbedtls/src/threading.c b/security/mbedtls/src/threading.c new file mode 100644 index 0000000000..81c1075446 --- /dev/null +++ b/security/mbedtls/src/threading.c @@ -0,0 +1,146 @@ +/* + * Threading abstraction layer + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_THREADING_C) + +#include "mbedtls/threading.h" + +#if defined(MBEDTLS_THREADING_PTHREAD) +static void threading_mutex_init_pthread( mbedtls_threading_mutex_t *mutex ) +{ + if( mutex == NULL || mutex->is_valid ) + return; + + mutex->is_valid = pthread_mutex_init( &mutex->mutex, NULL ) == 0; +} + +static void threading_mutex_free_pthread( mbedtls_threading_mutex_t *mutex ) +{ + if( mutex == NULL || !mutex->is_valid ) + return; + + (void) pthread_mutex_destroy( &mutex->mutex ); + mutex->is_valid = 0; +} + +static int threading_mutex_lock_pthread( mbedtls_threading_mutex_t *mutex ) +{ + if( mutex == NULL || ! mutex->is_valid ) + return( MBEDTLS_ERR_THREADING_BAD_INPUT_DATA ); + + if( pthread_mutex_lock( &mutex->mutex ) != 0 ) + return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); + + return( 0 ); +} + +static int threading_mutex_unlock_pthread( mbedtls_threading_mutex_t *mutex ) +{ + if( mutex == NULL || ! mutex->is_valid ) + return( MBEDTLS_ERR_THREADING_BAD_INPUT_DATA ); + + if( pthread_mutex_unlock( &mutex->mutex ) != 0 ) + return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); + + return( 0 ); +} + +void (*mbedtls_mutex_init)( mbedtls_threading_mutex_t * ) = threading_mutex_init_pthread; +void (*mbedtls_mutex_free)( mbedtls_threading_mutex_t * ) = threading_mutex_free_pthread; +int (*mbedtls_mutex_lock)( mbedtls_threading_mutex_t * ) = threading_mutex_lock_pthread; +int (*mbedtls_mutex_unlock)( mbedtls_threading_mutex_t * ) = threading_mutex_unlock_pthread; + +/* + * With phtreads we can statically initialize mutexes + */ +#define MUTEX_INIT = { PTHREAD_MUTEX_INITIALIZER, 1 } + +#endif /* MBEDTLS_THREADING_PTHREAD */ + +#if defined(MBEDTLS_THREADING_ALT) +static int threading_mutex_fail( mbedtls_threading_mutex_t *mutex ) +{ + ((void) mutex ); + return( MBEDTLS_ERR_THREADING_BAD_INPUT_DATA ); +} +static void threading_mutex_dummy( mbedtls_threading_mutex_t *mutex ) +{ + ((void) mutex ); + return; +} + +void (*mbedtls_mutex_init)( mbedtls_threading_mutex_t * ) = threading_mutex_dummy; +void (*mbedtls_mutex_free)( mbedtls_threading_mutex_t * ) = threading_mutex_dummy; +int (*mbedtls_mutex_lock)( mbedtls_threading_mutex_t * ) = threading_mutex_fail; +int (*mbedtls_mutex_unlock)( mbedtls_threading_mutex_t * ) = threading_mutex_fail; + +/* + * Set functions pointers and initialize global mutexes + */ +void mbedtls_threading_set_alt( void (*mutex_init)( mbedtls_threading_mutex_t * ), + void (*mutex_free)( mbedtls_threading_mutex_t * ), + int (*mutex_lock)( mbedtls_threading_mutex_t * ), + int (*mutex_unlock)( mbedtls_threading_mutex_t * ) ) +{ + mbedtls_mutex_init = mutex_init; + mbedtls_mutex_free = mutex_free; + mbedtls_mutex_lock = mutex_lock; + mbedtls_mutex_unlock = mutex_unlock; + + mbedtls_mutex_init( &mbedtls_threading_readdir_mutex ); + mbedtls_mutex_init( &mbedtls_threading_gmtime_mutex ); +#if defined(MBEDTLS_ECP_INTERNAL_ALT) + mbedtls_mutex_init( &mbedtls_threading_ecp_mutex ); +#endif +} + +/* + * Free global mutexes + */ +void mbedtls_threading_free_alt( void ) +{ + mbedtls_mutex_free( &mbedtls_threading_readdir_mutex ); + mbedtls_mutex_free( &mbedtls_threading_gmtime_mutex ); +#if defined(MBEDTLS_ECP_INTERNAL_ALT) + mbedtls_mutex_free( &mbedtls_threading_ecp_mutex ); +#endif +} +#endif /* MBEDTLS_THREADING_ALT */ + +/* + * Define global mutexes + */ +#ifndef MUTEX_INIT +#define MUTEX_INIT +#endif +mbedtls_threading_mutex_t mbedtls_threading_readdir_mutex MUTEX_INIT; +mbedtls_threading_mutex_t mbedtls_threading_gmtime_mutex MUTEX_INIT; +#if defined(MBEDTLS_ECP_INTERNAL_ALT) +mbedtls_threading_mutex_t mbedtls_threading_ecp_mutex MUTEX_INIT; +#endif + +#endif /* MBEDTLS_THREADING_C */ diff --git a/security/mbedtls/src/timing.c b/security/mbedtls/src/timing.c new file mode 100644 index 0000000000..5d8b25b997 --- /dev/null +++ b/security/mbedtls/src/timing.c @@ -0,0 +1,520 @@ +/* + * Portable interface to the CPU cycle counter + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_SELF_TEST) && defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_printf printf +#endif + +#if defined(MBEDTLS_TIMING_C) + +#include "mbedtls/timing.h" + +#if !defined(MBEDTLS_TIMING_ALT) + +#ifndef asm +#define asm __asm +#endif + +#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) + +#include +#include + +struct _hr_time +{ + LARGE_INTEGER start; +}; + +#else + +#include +#include +#include +#include +#include + +struct _hr_time +{ + struct timeval start; +}; + +#endif /* _WIN32 && !EFIX64 && !EFI32 */ + +#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ + ( defined(_MSC_VER) && defined(_M_IX86) ) || defined(__WATCOMC__) + +#define HAVE_HARDCLOCK + +unsigned long mbedtls_timing_hardclock( void ) +{ + unsigned long tsc; + __asm rdtsc + __asm mov [tsc], eax + return( tsc ); +} +#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && + ( _MSC_VER && _M_IX86 ) || __WATCOMC__ */ + +/* some versions of mingw-64 have 32-bit longs even on x84_64 */ +#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ + defined(__GNUC__) && ( defined(__i386__) || ( \ + ( defined(__amd64__) || defined( __x86_64__) ) && __SIZEOF_LONG__ == 4 ) ) + +#define HAVE_HARDCLOCK + +unsigned long mbedtls_timing_hardclock( void ) +{ + unsigned long lo, hi; + asm volatile( "rdtsc" : "=a" (lo), "=d" (hi) ); + return( lo ); +} +#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && + __GNUC__ && __i386__ */ + +#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ + defined(__GNUC__) && ( defined(__amd64__) || defined(__x86_64__) ) + +#define HAVE_HARDCLOCK + +unsigned long mbedtls_timing_hardclock( void ) +{ + unsigned long lo, hi; + asm volatile( "rdtsc" : "=a" (lo), "=d" (hi) ); + return( lo | ( hi << 32 ) ); +} +#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && + __GNUC__ && ( __amd64__ || __x86_64__ ) */ + +#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ + defined(__GNUC__) && ( defined(__powerpc__) || defined(__ppc__) ) + +#define HAVE_HARDCLOCK + +unsigned long mbedtls_timing_hardclock( void ) +{ + unsigned long tbl, tbu0, tbu1; + + do + { + asm volatile( "mftbu %0" : "=r" (tbu0) ); + asm volatile( "mftb %0" : "=r" (tbl ) ); + asm volatile( "mftbu %0" : "=r" (tbu1) ); + } + while( tbu0 != tbu1 ); + + return( tbl ); +} +#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && + __GNUC__ && ( __powerpc__ || __ppc__ ) */ + +#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ + defined(__GNUC__) && defined(__sparc64__) + +#if defined(__OpenBSD__) +#warning OpenBSD does not allow access to tick register using software version instead +#else +#define HAVE_HARDCLOCK + +unsigned long mbedtls_timing_hardclock( void ) +{ + unsigned long tick; + asm volatile( "rdpr %%tick, %0;" : "=&r" (tick) ); + return( tick ); +} +#endif /* __OpenBSD__ */ +#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && + __GNUC__ && __sparc64__ */ + +#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ + defined(__GNUC__) && defined(__sparc__) && !defined(__sparc64__) + +#define HAVE_HARDCLOCK + +unsigned long mbedtls_timing_hardclock( void ) +{ + unsigned long tick; + asm volatile( ".byte 0x83, 0x41, 0x00, 0x00" ); + asm volatile( "mov %%g1, %0" : "=r" (tick) ); + return( tick ); +} +#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && + __GNUC__ && __sparc__ && !__sparc64__ */ + +#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ + defined(__GNUC__) && defined(__alpha__) + +#define HAVE_HARDCLOCK + +unsigned long mbedtls_timing_hardclock( void ) +{ + unsigned long cc; + asm volatile( "rpcc %0" : "=r" (cc) ); + return( cc & 0xFFFFFFFF ); +} +#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && + __GNUC__ && __alpha__ */ + +#if !defined(HAVE_HARDCLOCK) && defined(MBEDTLS_HAVE_ASM) && \ + defined(__GNUC__) && defined(__ia64__) + +#define HAVE_HARDCLOCK + +unsigned long mbedtls_timing_hardclock( void ) +{ + unsigned long itc; + asm volatile( "mov %0 = ar.itc" : "=r" (itc) ); + return( itc ); +} +#endif /* !HAVE_HARDCLOCK && MBEDTLS_HAVE_ASM && + __GNUC__ && __ia64__ */ + +#if !defined(HAVE_HARDCLOCK) && defined(_MSC_VER) && \ + !defined(EFIX64) && !defined(EFI32) + +#define HAVE_HARDCLOCK + +unsigned long mbedtls_timing_hardclock( void ) +{ + LARGE_INTEGER offset; + + QueryPerformanceCounter( &offset ); + + return( (unsigned long)( offset.QuadPart ) ); +} +#endif /* !HAVE_HARDCLOCK && _MSC_VER && !EFIX64 && !EFI32 */ + +#if !defined(HAVE_HARDCLOCK) + +#define HAVE_HARDCLOCK + +static int hardclock_init = 0; +static struct timeval tv_init; + +unsigned long mbedtls_timing_hardclock( void ) +{ + struct timeval tv_cur; + + if( hardclock_init == 0 ) + { + gettimeofday( &tv_init, NULL ); + hardclock_init = 1; + } + + gettimeofday( &tv_cur, NULL ); + return( ( tv_cur.tv_sec - tv_init.tv_sec ) * 1000000 + + ( tv_cur.tv_usec - tv_init.tv_usec ) ); +} +#endif /* !HAVE_HARDCLOCK */ + +volatile int mbedtls_timing_alarmed = 0; + +#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) + +unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int reset ) +{ + unsigned long delta; + LARGE_INTEGER offset, hfreq; + struct _hr_time *t = (struct _hr_time *) val; + + QueryPerformanceCounter( &offset ); + QueryPerformanceFrequency( &hfreq ); + + delta = (unsigned long)( ( 1000 * + ( offset.QuadPart - t->start.QuadPart ) ) / + hfreq.QuadPart ); + + if( reset ) + QueryPerformanceCounter( &t->start ); + + return( delta ); +} + +/* It's OK to use a global because alarm() is supposed to be global anyway */ +static DWORD alarmMs; + +static DWORD WINAPI TimerProc( LPVOID TimerContext ) +{ + ((void) TimerContext); + Sleep( alarmMs ); + mbedtls_timing_alarmed = 1; + return( TRUE ); +} + +void mbedtls_set_alarm( int seconds ) +{ + DWORD ThreadId; + + mbedtls_timing_alarmed = 0; + alarmMs = seconds * 1000; + CloseHandle( CreateThread( NULL, 0, TimerProc, NULL, 0, &ThreadId ) ); +} + +#else /* _WIN32 && !EFIX64 && !EFI32 */ + +unsigned long mbedtls_timing_get_timer( struct mbedtls_timing_hr_time *val, int reset ) +{ + unsigned long delta; + struct timeval offset; + struct _hr_time *t = (struct _hr_time *) val; + + gettimeofday( &offset, NULL ); + + if( reset ) + { + t->start.tv_sec = offset.tv_sec; + t->start.tv_usec = offset.tv_usec; + return( 0 ); + } + + delta = ( offset.tv_sec - t->start.tv_sec ) * 1000 + + ( offset.tv_usec - t->start.tv_usec ) / 1000; + + return( delta ); +} + +static void sighandler( int signum ) +{ + mbedtls_timing_alarmed = 1; + signal( signum, sighandler ); +} + +void mbedtls_set_alarm( int seconds ) +{ + mbedtls_timing_alarmed = 0; + signal( SIGALRM, sighandler ); + alarm( seconds ); +} + +#endif /* _WIN32 && !EFIX64 && !EFI32 */ + +/* + * Set delays to watch + */ +void mbedtls_timing_set_delay( void *data, uint32_t int_ms, uint32_t fin_ms ) +{ + mbedtls_timing_delay_context *ctx = (mbedtls_timing_delay_context *) data; + + ctx->int_ms = int_ms; + ctx->fin_ms = fin_ms; + + if( fin_ms != 0 ) + (void) mbedtls_timing_get_timer( &ctx->timer, 1 ); +} + +/* + * Get number of delays expired + */ +int mbedtls_timing_get_delay( void *data ) +{ + mbedtls_timing_delay_context *ctx = (mbedtls_timing_delay_context *) data; + unsigned long elapsed_ms; + + if( ctx->fin_ms == 0 ) + return( -1 ); + + elapsed_ms = mbedtls_timing_get_timer( &ctx->timer, 0 ); + + if( elapsed_ms >= ctx->fin_ms ) + return( 2 ); + + if( elapsed_ms >= ctx->int_ms ) + return( 1 ); + + return( 0 ); +} + +#endif /* !MBEDTLS_TIMING_ALT */ + +#if defined(MBEDTLS_SELF_TEST) + +/* + * Busy-waits for the given number of milliseconds. + * Used for testing mbedtls_timing_hardclock. + */ +static void busy_msleep( unsigned long msec ) +{ + struct mbedtls_timing_hr_time hires; + unsigned long i = 0; /* for busy-waiting */ + volatile unsigned long j; /* to prevent optimisation */ + + (void) mbedtls_timing_get_timer( &hires, 1 ); + + while( mbedtls_timing_get_timer( &hires, 0 ) < msec ) + i++; + + j = i; + (void) j; +} + +#define FAIL do \ +{ \ + if( verbose != 0 ) \ + mbedtls_printf( "failed\n" ); \ + \ + return( 1 ); \ +} while( 0 ) + +/* + * Checkup routine + * + * Warning: this is work in progress, some tests may not be reliable enough + * yet! False positives may happen. + */ +int mbedtls_timing_self_test( int verbose ) +{ + unsigned long cycles, ratio; + unsigned long millisecs, secs; + int hardfail; + struct mbedtls_timing_hr_time hires; + uint32_t a, b; + mbedtls_timing_delay_context ctx; + + if( verbose != 0 ) + mbedtls_printf( " TIMING tests note: will take some time!\n" ); + + + if( verbose != 0 ) + mbedtls_printf( " TIMING test #1 (set_alarm / get_timer): " ); + + for( secs = 1; secs <= 3; secs++ ) + { + (void) mbedtls_timing_get_timer( &hires, 1 ); + + mbedtls_set_alarm( (int) secs ); + while( !mbedtls_timing_alarmed ) + ; + + millisecs = mbedtls_timing_get_timer( &hires, 0 ); + + /* For some reason on Windows it looks like alarm has an extra delay + * (maybe related to creating a new thread). Allow some room here. */ + if( millisecs < 800 * secs || millisecs > 1200 * secs + 300 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( 1 ); + } + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + + if( verbose != 0 ) + mbedtls_printf( " TIMING test #2 (set/get_delay ): " ); + + for( a = 200; a <= 400; a += 200 ) + { + for( b = 200; b <= 400; b += 200 ) + { + mbedtls_timing_set_delay( &ctx, a, a + b ); + + busy_msleep( a - a / 8 ); + if( mbedtls_timing_get_delay( &ctx ) != 0 ) + FAIL; + + busy_msleep( a / 4 ); + if( mbedtls_timing_get_delay( &ctx ) != 1 ) + FAIL; + + busy_msleep( b - a / 8 - b / 8 ); + if( mbedtls_timing_get_delay( &ctx ) != 1 ) + FAIL; + + busy_msleep( b / 4 ); + if( mbedtls_timing_get_delay( &ctx ) != 2 ) + FAIL; + } + } + + mbedtls_timing_set_delay( &ctx, 0, 0 ); + busy_msleep( 200 ); + if( mbedtls_timing_get_delay( &ctx ) != -1 ) + FAIL; + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + + if( verbose != 0 ) + mbedtls_printf( " TIMING test #3 (hardclock / get_timer): " ); + + /* + * Allow one failure for possible counter wrapping. + * On a 4Ghz 32-bit machine the cycle counter wraps about once per second; + * since the whole test is about 10ms, it shouldn't happen twice in a row. + */ + hardfail = 0; + +hard_test: + if( hardfail > 1 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed (ignored)\n" ); + + goto hard_test_done; + } + + /* Get a reference ratio cycles/ms */ + millisecs = 1; + cycles = mbedtls_timing_hardclock(); + busy_msleep( millisecs ); + cycles = mbedtls_timing_hardclock() - cycles; + ratio = cycles / millisecs; + + /* Check that the ratio is mostly constant */ + for( millisecs = 2; millisecs <= 4; millisecs++ ) + { + cycles = mbedtls_timing_hardclock(); + busy_msleep( millisecs ); + cycles = mbedtls_timing_hardclock() - cycles; + + /* Allow variation up to 20% */ + if( cycles / millisecs < ratio - ratio / 5 || + cycles / millisecs > ratio + ratio / 5 ) + { + hardfail++; + goto hard_test; + } + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + +hard_test_done: + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + + return( 0 ); +} + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_TIMING_C */ diff --git a/security/mbedtls/src/version.c b/security/mbedtls/src/version.c new file mode 100644 index 0000000000..6ca80d4695 --- /dev/null +++ b/security/mbedtls/src/version.c @@ -0,0 +1,50 @@ +/* + * Version information + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_VERSION_C) + +#include "mbedtls/version.h" +#include + +unsigned int mbedtls_version_get_number() +{ + return( MBEDTLS_VERSION_NUMBER ); +} + +void mbedtls_version_get_string( char *string ) +{ + memcpy( string, MBEDTLS_VERSION_STRING, + sizeof( MBEDTLS_VERSION_STRING ) ); +} + +void mbedtls_version_get_string_full( char *string ) +{ + memcpy( string, MBEDTLS_VERSION_STRING_FULL, + sizeof( MBEDTLS_VERSION_STRING_FULL ) ); +} + +#endif /* MBEDTLS_VERSION_C */ diff --git a/security/mbedtls/src/version_features.c b/security/mbedtls/src/version_features.c new file mode 100644 index 0000000000..9f97c7bc3e --- /dev/null +++ b/security/mbedtls/src/version_features.c @@ -0,0 +1,677 @@ +/* + * Version feature information + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_VERSION_C) + +#include "mbedtls/version.h" + +#include + +static const char *features[] = { +#if defined(MBEDTLS_VERSION_FEATURES) +#if defined(MBEDTLS_HAVE_ASM) + "MBEDTLS_HAVE_ASM", +#endif /* MBEDTLS_HAVE_ASM */ +#if defined(MBEDTLS_HAVE_SSE2) + "MBEDTLS_HAVE_SSE2", +#endif /* MBEDTLS_HAVE_SSE2 */ +#if defined(MBEDTLS_HAVE_TIME) + "MBEDTLS_HAVE_TIME", +#endif /* MBEDTLS_HAVE_TIME */ +#if defined(MBEDTLS_HAVE_TIME_DATE) + "MBEDTLS_HAVE_TIME_DATE", +#endif /* MBEDTLS_HAVE_TIME_DATE */ +#if defined(MBEDTLS_PLATFORM_MEMORY) + "MBEDTLS_PLATFORM_MEMORY", +#endif /* MBEDTLS_PLATFORM_MEMORY */ +#if defined(MBEDTLS_PLATFORM_NO_STD_FUNCTIONS) + "MBEDTLS_PLATFORM_NO_STD_FUNCTIONS", +#endif /* MBEDTLS_PLATFORM_NO_STD_FUNCTIONS */ +#if defined(MBEDTLS_PLATFORM_EXIT_ALT) + "MBEDTLS_PLATFORM_EXIT_ALT", +#endif /* MBEDTLS_PLATFORM_EXIT_ALT */ +#if defined(MBEDTLS_PLATFORM_TIME_ALT) + "MBEDTLS_PLATFORM_TIME_ALT", +#endif /* MBEDTLS_PLATFORM_TIME_ALT */ +#if defined(MBEDTLS_PLATFORM_FPRINTF_ALT) + "MBEDTLS_PLATFORM_FPRINTF_ALT", +#endif /* MBEDTLS_PLATFORM_FPRINTF_ALT */ +#if defined(MBEDTLS_PLATFORM_PRINTF_ALT) + "MBEDTLS_PLATFORM_PRINTF_ALT", +#endif /* MBEDTLS_PLATFORM_PRINTF_ALT */ +#if defined(MBEDTLS_PLATFORM_SNPRINTF_ALT) + "MBEDTLS_PLATFORM_SNPRINTF_ALT", +#endif /* MBEDTLS_PLATFORM_SNPRINTF_ALT */ +#if defined(MBEDTLS_PLATFORM_NV_SEED_ALT) + "MBEDTLS_PLATFORM_NV_SEED_ALT", +#endif /* MBEDTLS_PLATFORM_NV_SEED_ALT */ +#if defined(MBEDTLS_DEPRECATED_WARNING) + "MBEDTLS_DEPRECATED_WARNING", +#endif /* MBEDTLS_DEPRECATED_WARNING */ +#if defined(MBEDTLS_DEPRECATED_REMOVED) + "MBEDTLS_DEPRECATED_REMOVED", +#endif /* MBEDTLS_DEPRECATED_REMOVED */ +#if defined(MBEDTLS_TIMING_ALT) + "MBEDTLS_TIMING_ALT", +#endif /* MBEDTLS_TIMING_ALT */ +#if defined(MBEDTLS_AES_ALT) + "MBEDTLS_AES_ALT", +#endif /* MBEDTLS_AES_ALT */ +#if defined(MBEDTLS_ARC4_ALT) + "MBEDTLS_ARC4_ALT", +#endif /* MBEDTLS_ARC4_ALT */ +#if defined(MBEDTLS_BLOWFISH_ALT) + "MBEDTLS_BLOWFISH_ALT", +#endif /* MBEDTLS_BLOWFISH_ALT */ +#if defined(MBEDTLS_CAMELLIA_ALT) + "MBEDTLS_CAMELLIA_ALT", +#endif /* MBEDTLS_CAMELLIA_ALT */ +#if defined(MBEDTLS_DES_ALT) + "MBEDTLS_DES_ALT", +#endif /* MBEDTLS_DES_ALT */ +#if defined(MBEDTLS_XTEA_ALT) + "MBEDTLS_XTEA_ALT", +#endif /* MBEDTLS_XTEA_ALT */ +#if defined(MBEDTLS_MD2_ALT) + "MBEDTLS_MD2_ALT", +#endif /* MBEDTLS_MD2_ALT */ +#if defined(MBEDTLS_MD4_ALT) + "MBEDTLS_MD4_ALT", +#endif /* MBEDTLS_MD4_ALT */ +#if defined(MBEDTLS_MD5_ALT) + "MBEDTLS_MD5_ALT", +#endif /* MBEDTLS_MD5_ALT */ +#if defined(MBEDTLS_RIPEMD160_ALT) + "MBEDTLS_RIPEMD160_ALT", +#endif /* MBEDTLS_RIPEMD160_ALT */ +#if defined(MBEDTLS_SHA1_ALT) + "MBEDTLS_SHA1_ALT", +#endif /* MBEDTLS_SHA1_ALT */ +#if defined(MBEDTLS_SHA256_ALT) + "MBEDTLS_SHA256_ALT", +#endif /* MBEDTLS_SHA256_ALT */ +#if defined(MBEDTLS_SHA512_ALT) + "MBEDTLS_SHA512_ALT", +#endif /* MBEDTLS_SHA512_ALT */ +#if defined(MBEDTLS_ECP_ALT) + "MBEDTLS_ECP_ALT", +#endif /* MBEDTLS_ECP_ALT */ +#if defined(MBEDTLS_MD2_PROCESS_ALT) + "MBEDTLS_MD2_PROCESS_ALT", +#endif /* MBEDTLS_MD2_PROCESS_ALT */ +#if defined(MBEDTLS_MD4_PROCESS_ALT) + "MBEDTLS_MD4_PROCESS_ALT", +#endif /* MBEDTLS_MD4_PROCESS_ALT */ +#if defined(MBEDTLS_MD5_PROCESS_ALT) + "MBEDTLS_MD5_PROCESS_ALT", +#endif /* MBEDTLS_MD5_PROCESS_ALT */ +#if defined(MBEDTLS_RIPEMD160_PROCESS_ALT) + "MBEDTLS_RIPEMD160_PROCESS_ALT", +#endif /* MBEDTLS_RIPEMD160_PROCESS_ALT */ +#if defined(MBEDTLS_SHA1_PROCESS_ALT) + "MBEDTLS_SHA1_PROCESS_ALT", +#endif /* MBEDTLS_SHA1_PROCESS_ALT */ +#if defined(MBEDTLS_SHA256_PROCESS_ALT) + "MBEDTLS_SHA256_PROCESS_ALT", +#endif /* MBEDTLS_SHA256_PROCESS_ALT */ +#if defined(MBEDTLS_SHA512_PROCESS_ALT) + "MBEDTLS_SHA512_PROCESS_ALT", +#endif /* MBEDTLS_SHA512_PROCESS_ALT */ +#if defined(MBEDTLS_DES_SETKEY_ALT) + "MBEDTLS_DES_SETKEY_ALT", +#endif /* MBEDTLS_DES_SETKEY_ALT */ +#if defined(MBEDTLS_DES_CRYPT_ECB_ALT) + "MBEDTLS_DES_CRYPT_ECB_ALT", +#endif /* MBEDTLS_DES_CRYPT_ECB_ALT */ +#if defined(MBEDTLS_DES3_CRYPT_ECB_ALT) + "MBEDTLS_DES3_CRYPT_ECB_ALT", +#endif /* MBEDTLS_DES3_CRYPT_ECB_ALT */ +#if defined(MBEDTLS_AES_SETKEY_ENC_ALT) + "MBEDTLS_AES_SETKEY_ENC_ALT", +#endif /* MBEDTLS_AES_SETKEY_ENC_ALT */ +#if defined(MBEDTLS_AES_SETKEY_DEC_ALT) + "MBEDTLS_AES_SETKEY_DEC_ALT", +#endif /* MBEDTLS_AES_SETKEY_DEC_ALT */ +#if defined(MBEDTLS_AES_ENCRYPT_ALT) + "MBEDTLS_AES_ENCRYPT_ALT", +#endif /* MBEDTLS_AES_ENCRYPT_ALT */ +#if defined(MBEDTLS_AES_DECRYPT_ALT) + "MBEDTLS_AES_DECRYPT_ALT", +#endif /* MBEDTLS_AES_DECRYPT_ALT */ +#if defined(MBEDTLS_ECP_INTERNAL_ALT) + "MBEDTLS_ECP_INTERNAL_ALT", +#endif /* MBEDTLS_ECP_INTERNAL_ALT */ +#if defined(MBEDTLS_ECP_RANDOMIZE_JAC_ALT) + "MBEDTLS_ECP_RANDOMIZE_JAC_ALT", +#endif /* MBEDTLS_ECP_RANDOMIZE_JAC_ALT */ +#if defined(MBEDTLS_ECP_ADD_MIXED_ALT) + "MBEDTLS_ECP_ADD_MIXED_ALT", +#endif /* MBEDTLS_ECP_ADD_MIXED_ALT */ +#if defined(MBEDTLS_ECP_DOUBLE_JAC_ALT) + "MBEDTLS_ECP_DOUBLE_JAC_ALT", +#endif /* MBEDTLS_ECP_DOUBLE_JAC_ALT */ +#if defined(MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT) + "MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT", +#endif /* MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT */ +#if defined(MBEDTLS_ECP_NORMALIZE_JAC_ALT) + "MBEDTLS_ECP_NORMALIZE_JAC_ALT", +#endif /* MBEDTLS_ECP_NORMALIZE_JAC_ALT */ +#if defined(MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT) + "MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT", +#endif /* MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT */ +#if defined(MBEDTLS_ECP_RANDOMIZE_MXZ_ALT) + "MBEDTLS_ECP_RANDOMIZE_MXZ_ALT", +#endif /* MBEDTLS_ECP_RANDOMIZE_MXZ_ALT */ +#if defined(MBEDTLS_ECP_NORMALIZE_MXZ_ALT) + "MBEDTLS_ECP_NORMALIZE_MXZ_ALT", +#endif /* MBEDTLS_ECP_NORMALIZE_MXZ_ALT */ +#if defined(MBEDTLS_TEST_NULL_ENTROPY) + "MBEDTLS_TEST_NULL_ENTROPY", +#endif /* MBEDTLS_TEST_NULL_ENTROPY */ +#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) + "MBEDTLS_ENTROPY_HARDWARE_ALT", +#endif /* MBEDTLS_ENTROPY_HARDWARE_ALT */ +#if defined(MBEDTLS_AES_ROM_TABLES) + "MBEDTLS_AES_ROM_TABLES", +#endif /* MBEDTLS_AES_ROM_TABLES */ +#if defined(MBEDTLS_CAMELLIA_SMALL_MEMORY) + "MBEDTLS_CAMELLIA_SMALL_MEMORY", +#endif /* MBEDTLS_CAMELLIA_SMALL_MEMORY */ +#if defined(MBEDTLS_CIPHER_MODE_CBC) + "MBEDTLS_CIPHER_MODE_CBC", +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#if defined(MBEDTLS_CIPHER_MODE_CFB) + "MBEDTLS_CIPHER_MODE_CFB", +#endif /* MBEDTLS_CIPHER_MODE_CFB */ +#if defined(MBEDTLS_CIPHER_MODE_CTR) + "MBEDTLS_CIPHER_MODE_CTR", +#endif /* MBEDTLS_CIPHER_MODE_CTR */ +#if defined(MBEDTLS_CIPHER_NULL_CIPHER) + "MBEDTLS_CIPHER_NULL_CIPHER", +#endif /* MBEDTLS_CIPHER_NULL_CIPHER */ +#if defined(MBEDTLS_CIPHER_PADDING_PKCS7) + "MBEDTLS_CIPHER_PADDING_PKCS7", +#endif /* MBEDTLS_CIPHER_PADDING_PKCS7 */ +#if defined(MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS) + "MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS", +#endif /* MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS */ +#if defined(MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN) + "MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN", +#endif /* MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN */ +#if defined(MBEDTLS_CIPHER_PADDING_ZEROS) + "MBEDTLS_CIPHER_PADDING_ZEROS", +#endif /* MBEDTLS_CIPHER_PADDING_ZEROS */ +#if defined(MBEDTLS_ENABLE_WEAK_CIPHERSUITES) + "MBEDTLS_ENABLE_WEAK_CIPHERSUITES", +#endif /* MBEDTLS_ENABLE_WEAK_CIPHERSUITES */ +#if defined(MBEDTLS_REMOVE_ARC4_CIPHERSUITES) + "MBEDTLS_REMOVE_ARC4_CIPHERSUITES", +#endif /* MBEDTLS_REMOVE_ARC4_CIPHERSUITES */ +#if defined(MBEDTLS_ECP_DP_SECP192R1_ENABLED) + "MBEDTLS_ECP_DP_SECP192R1_ENABLED", +#endif /* MBEDTLS_ECP_DP_SECP192R1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_SECP224R1_ENABLED) + "MBEDTLS_ECP_DP_SECP224R1_ENABLED", +#endif /* MBEDTLS_ECP_DP_SECP224R1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_SECP256R1_ENABLED) + "MBEDTLS_ECP_DP_SECP256R1_ENABLED", +#endif /* MBEDTLS_ECP_DP_SECP256R1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_SECP384R1_ENABLED) + "MBEDTLS_ECP_DP_SECP384R1_ENABLED", +#endif /* MBEDTLS_ECP_DP_SECP384R1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_SECP521R1_ENABLED) + "MBEDTLS_ECP_DP_SECP521R1_ENABLED", +#endif /* MBEDTLS_ECP_DP_SECP521R1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_SECP192K1_ENABLED) + "MBEDTLS_ECP_DP_SECP192K1_ENABLED", +#endif /* MBEDTLS_ECP_DP_SECP192K1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_SECP224K1_ENABLED) + "MBEDTLS_ECP_DP_SECP224K1_ENABLED", +#endif /* MBEDTLS_ECP_DP_SECP224K1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_SECP256K1_ENABLED) + "MBEDTLS_ECP_DP_SECP256K1_ENABLED", +#endif /* MBEDTLS_ECP_DP_SECP256K1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_BP256R1_ENABLED) + "MBEDTLS_ECP_DP_BP256R1_ENABLED", +#endif /* MBEDTLS_ECP_DP_BP256R1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_BP384R1_ENABLED) + "MBEDTLS_ECP_DP_BP384R1_ENABLED", +#endif /* MBEDTLS_ECP_DP_BP384R1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_BP512R1_ENABLED) + "MBEDTLS_ECP_DP_BP512R1_ENABLED", +#endif /* MBEDTLS_ECP_DP_BP512R1_ENABLED */ +#if defined(MBEDTLS_ECP_DP_CURVE25519_ENABLED) + "MBEDTLS_ECP_DP_CURVE25519_ENABLED", +#endif /* MBEDTLS_ECP_DP_CURVE25519_ENABLED */ +#if defined(MBEDTLS_ECP_NIST_OPTIM) + "MBEDTLS_ECP_NIST_OPTIM", +#endif /* MBEDTLS_ECP_NIST_OPTIM */ +#if defined(MBEDTLS_ECDSA_DETERMINISTIC) + "MBEDTLS_ECDSA_DETERMINISTIC", +#endif /* MBEDTLS_ECDSA_DETERMINISTIC */ +#if defined(MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) + "MBEDTLS_KEY_EXCHANGE_PSK_ENABLED", +#endif /* MBEDTLS_KEY_EXCHANGE_PSK_ENABLED */ +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED) + "MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED", +#endif /* MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED */ +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED) + "MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED", +#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED */ +#if defined(MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED) + "MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED", +#endif /* MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED */ +#if defined(MBEDTLS_KEY_EXCHANGE_RSA_ENABLED) + "MBEDTLS_KEY_EXCHANGE_RSA_ENABLED", +#endif /* MBEDTLS_KEY_EXCHANGE_RSA_ENABLED */ +#if defined(MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED) + "MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED", +#endif /* MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED */ +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) + "MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED", +#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED */ +#if defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) + "MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED", +#endif /* MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED */ +#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) + "MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED", +#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED */ +#if defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) + "MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED", +#endif /* MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED */ +#if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) + "MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED", +#endif /* MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ +#if defined(MBEDTLS_PK_PARSE_EC_EXTENDED) + "MBEDTLS_PK_PARSE_EC_EXTENDED", +#endif /* MBEDTLS_PK_PARSE_EC_EXTENDED */ +#if defined(MBEDTLS_ERROR_STRERROR_DUMMY) + "MBEDTLS_ERROR_STRERROR_DUMMY", +#endif /* MBEDTLS_ERROR_STRERROR_DUMMY */ +#if defined(MBEDTLS_GENPRIME) + "MBEDTLS_GENPRIME", +#endif /* MBEDTLS_GENPRIME */ +#if defined(MBEDTLS_FS_IO) + "MBEDTLS_FS_IO", +#endif /* MBEDTLS_FS_IO */ +#if defined(MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES) + "MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES", +#endif /* MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES */ +#if defined(MBEDTLS_NO_PLATFORM_ENTROPY) + "MBEDTLS_NO_PLATFORM_ENTROPY", +#endif /* MBEDTLS_NO_PLATFORM_ENTROPY */ +#if defined(MBEDTLS_ENTROPY_FORCE_SHA256) + "MBEDTLS_ENTROPY_FORCE_SHA256", +#endif /* MBEDTLS_ENTROPY_FORCE_SHA256 */ +#if defined(MBEDTLS_ENTROPY_NV_SEED) + "MBEDTLS_ENTROPY_NV_SEED", +#endif /* MBEDTLS_ENTROPY_NV_SEED */ +#if defined(MBEDTLS_MEMORY_DEBUG) + "MBEDTLS_MEMORY_DEBUG", +#endif /* MBEDTLS_MEMORY_DEBUG */ +#if defined(MBEDTLS_MEMORY_BACKTRACE) + "MBEDTLS_MEMORY_BACKTRACE", +#endif /* MBEDTLS_MEMORY_BACKTRACE */ +#if defined(MBEDTLS_PK_RSA_ALT_SUPPORT) + "MBEDTLS_PK_RSA_ALT_SUPPORT", +#endif /* MBEDTLS_PK_RSA_ALT_SUPPORT */ +#if defined(MBEDTLS_PKCS1_V15) + "MBEDTLS_PKCS1_V15", +#endif /* MBEDTLS_PKCS1_V15 */ +#if defined(MBEDTLS_PKCS1_V21) + "MBEDTLS_PKCS1_V21", +#endif /* MBEDTLS_PKCS1_V21 */ +#if defined(MBEDTLS_RSA_NO_CRT) + "MBEDTLS_RSA_NO_CRT", +#endif /* MBEDTLS_RSA_NO_CRT */ +#if defined(MBEDTLS_SELF_TEST) + "MBEDTLS_SELF_TEST", +#endif /* MBEDTLS_SELF_TEST */ +#if defined(MBEDTLS_SHA256_SMALLER) + "MBEDTLS_SHA256_SMALLER", +#endif /* MBEDTLS_SHA256_SMALLER */ +#if defined(MBEDTLS_SSL_ALL_ALERT_MESSAGES) + "MBEDTLS_SSL_ALL_ALERT_MESSAGES", +#endif /* MBEDTLS_SSL_ALL_ALERT_MESSAGES */ +#if defined(MBEDTLS_SSL_DEBUG_ALL) + "MBEDTLS_SSL_DEBUG_ALL", +#endif /* MBEDTLS_SSL_DEBUG_ALL */ +#if defined(MBEDTLS_SSL_ENCRYPT_THEN_MAC) + "MBEDTLS_SSL_ENCRYPT_THEN_MAC", +#endif /* MBEDTLS_SSL_ENCRYPT_THEN_MAC */ +#if defined(MBEDTLS_SSL_EXTENDED_MASTER_SECRET) + "MBEDTLS_SSL_EXTENDED_MASTER_SECRET", +#endif /* MBEDTLS_SSL_EXTENDED_MASTER_SECRET */ +#if defined(MBEDTLS_SSL_FALLBACK_SCSV) + "MBEDTLS_SSL_FALLBACK_SCSV", +#endif /* MBEDTLS_SSL_FALLBACK_SCSV */ +#if defined(MBEDTLS_SSL_HW_RECORD_ACCEL) + "MBEDTLS_SSL_HW_RECORD_ACCEL", +#endif /* MBEDTLS_SSL_HW_RECORD_ACCEL */ +#if defined(MBEDTLS_SSL_CBC_RECORD_SPLITTING) + "MBEDTLS_SSL_CBC_RECORD_SPLITTING", +#endif /* MBEDTLS_SSL_CBC_RECORD_SPLITTING */ +#if defined(MBEDTLS_SSL_RENEGOTIATION) + "MBEDTLS_SSL_RENEGOTIATION", +#endif /* MBEDTLS_SSL_RENEGOTIATION */ +#if defined(MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO) + "MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO", +#endif /* MBEDTLS_SSL_SRV_SUPPORT_SSLV2_CLIENT_HELLO */ +#if defined(MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE) + "MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE", +#endif /* MBEDTLS_SSL_SRV_RESPECT_CLIENT_PREFERENCE */ +#if defined(MBEDTLS_SSL_MAX_FRAGMENT_LENGTH) + "MBEDTLS_SSL_MAX_FRAGMENT_LENGTH", +#endif /* MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ +#if defined(MBEDTLS_SSL_PROTO_SSL3) + "MBEDTLS_SSL_PROTO_SSL3", +#endif /* MBEDTLS_SSL_PROTO_SSL3 */ +#if defined(MBEDTLS_SSL_PROTO_TLS1) + "MBEDTLS_SSL_PROTO_TLS1", +#endif /* MBEDTLS_SSL_PROTO_TLS1 */ +#if defined(MBEDTLS_SSL_PROTO_TLS1_1) + "MBEDTLS_SSL_PROTO_TLS1_1", +#endif /* MBEDTLS_SSL_PROTO_TLS1_1 */ +#if defined(MBEDTLS_SSL_PROTO_TLS1_2) + "MBEDTLS_SSL_PROTO_TLS1_2", +#endif /* MBEDTLS_SSL_PROTO_TLS1_2 */ +#if defined(MBEDTLS_SSL_PROTO_DTLS) + "MBEDTLS_SSL_PROTO_DTLS", +#endif /* MBEDTLS_SSL_PROTO_DTLS */ +#if defined(MBEDTLS_SSL_ALPN) + "MBEDTLS_SSL_ALPN", +#endif /* MBEDTLS_SSL_ALPN */ +#if defined(MBEDTLS_SSL_DTLS_ANTI_REPLAY) + "MBEDTLS_SSL_DTLS_ANTI_REPLAY", +#endif /* MBEDTLS_SSL_DTLS_ANTI_REPLAY */ +#if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) + "MBEDTLS_SSL_DTLS_HELLO_VERIFY", +#endif /* MBEDTLS_SSL_DTLS_HELLO_VERIFY */ +#if defined(MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE) + "MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE", +#endif /* MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE */ +#if defined(MBEDTLS_SSL_DTLS_BADMAC_LIMIT) + "MBEDTLS_SSL_DTLS_BADMAC_LIMIT", +#endif /* MBEDTLS_SSL_DTLS_BADMAC_LIMIT */ +#if defined(MBEDTLS_SSL_SESSION_TICKETS) + "MBEDTLS_SSL_SESSION_TICKETS", +#endif /* MBEDTLS_SSL_SESSION_TICKETS */ +#if defined(MBEDTLS_SSL_EXPORT_KEYS) + "MBEDTLS_SSL_EXPORT_KEYS", +#endif /* MBEDTLS_SSL_EXPORT_KEYS */ +#if defined(MBEDTLS_SSL_SERVER_NAME_INDICATION) + "MBEDTLS_SSL_SERVER_NAME_INDICATION", +#endif /* MBEDTLS_SSL_SERVER_NAME_INDICATION */ +#if defined(MBEDTLS_SSL_TRUNCATED_HMAC) + "MBEDTLS_SSL_TRUNCATED_HMAC", +#endif /* MBEDTLS_SSL_TRUNCATED_HMAC */ +#if defined(MBEDTLS_THREADING_ALT) + "MBEDTLS_THREADING_ALT", +#endif /* MBEDTLS_THREADING_ALT */ +#if defined(MBEDTLS_THREADING_PTHREAD) + "MBEDTLS_THREADING_PTHREAD", +#endif /* MBEDTLS_THREADING_PTHREAD */ +#if defined(MBEDTLS_VERSION_FEATURES) + "MBEDTLS_VERSION_FEATURES", +#endif /* MBEDTLS_VERSION_FEATURES */ +#if defined(MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3) + "MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3", +#endif /* MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3 */ +#if defined(MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION) + "MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION", +#endif /* MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION */ +#if defined(MBEDTLS_X509_CHECK_KEY_USAGE) + "MBEDTLS_X509_CHECK_KEY_USAGE", +#endif /* MBEDTLS_X509_CHECK_KEY_USAGE */ +#if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE) + "MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE", +#endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */ +#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) + "MBEDTLS_X509_RSASSA_PSS_SUPPORT", +#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ +#if defined(MBEDTLS_ZLIB_SUPPORT) + "MBEDTLS_ZLIB_SUPPORT", +#endif /* MBEDTLS_ZLIB_SUPPORT */ +#if defined(MBEDTLS_AESNI_C) + "MBEDTLS_AESNI_C", +#endif /* MBEDTLS_AESNI_C */ +#if defined(MBEDTLS_AES_C) + "MBEDTLS_AES_C", +#endif /* MBEDTLS_AES_C */ +#if defined(MBEDTLS_ARC4_C) + "MBEDTLS_ARC4_C", +#endif /* MBEDTLS_ARC4_C */ +#if defined(MBEDTLS_ASN1_PARSE_C) + "MBEDTLS_ASN1_PARSE_C", +#endif /* MBEDTLS_ASN1_PARSE_C */ +#if defined(MBEDTLS_ASN1_WRITE_C) + "MBEDTLS_ASN1_WRITE_C", +#endif /* MBEDTLS_ASN1_WRITE_C */ +#if defined(MBEDTLS_BASE64_C) + "MBEDTLS_BASE64_C", +#endif /* MBEDTLS_BASE64_C */ +#if defined(MBEDTLS_BIGNUM_C) + "MBEDTLS_BIGNUM_C", +#endif /* MBEDTLS_BIGNUM_C */ +#if defined(MBEDTLS_BLOWFISH_C) + "MBEDTLS_BLOWFISH_C", +#endif /* MBEDTLS_BLOWFISH_C */ +#if defined(MBEDTLS_CAMELLIA_C) + "MBEDTLS_CAMELLIA_C", +#endif /* MBEDTLS_CAMELLIA_C */ +#if defined(MBEDTLS_CCM_C) + "MBEDTLS_CCM_C", +#endif /* MBEDTLS_CCM_C */ +#if defined(MBEDTLS_CERTS_C) + "MBEDTLS_CERTS_C", +#endif /* MBEDTLS_CERTS_C */ +#if defined(MBEDTLS_CIPHER_C) + "MBEDTLS_CIPHER_C", +#endif /* MBEDTLS_CIPHER_C */ +#if defined(MBEDTLS_CMAC_C) + "MBEDTLS_CMAC_C", +#endif /* MBEDTLS_CMAC_C */ +#if defined(MBEDTLS_CTR_DRBG_C) + "MBEDTLS_CTR_DRBG_C", +#endif /* MBEDTLS_CTR_DRBG_C */ +#if defined(MBEDTLS_DEBUG_C) + "MBEDTLS_DEBUG_C", +#endif /* MBEDTLS_DEBUG_C */ +#if defined(MBEDTLS_DES_C) + "MBEDTLS_DES_C", +#endif /* MBEDTLS_DES_C */ +#if defined(MBEDTLS_DHM_C) + "MBEDTLS_DHM_C", +#endif /* MBEDTLS_DHM_C */ +#if defined(MBEDTLS_ECDH_C) + "MBEDTLS_ECDH_C", +#endif /* MBEDTLS_ECDH_C */ +#if defined(MBEDTLS_ECDSA_C) + "MBEDTLS_ECDSA_C", +#endif /* MBEDTLS_ECDSA_C */ +#if defined(MBEDTLS_ECJPAKE_C) + "MBEDTLS_ECJPAKE_C", +#endif /* MBEDTLS_ECJPAKE_C */ +#if defined(MBEDTLS_ECP_C) + "MBEDTLS_ECP_C", +#endif /* MBEDTLS_ECP_C */ +#if defined(MBEDTLS_ENTROPY_C) + "MBEDTLS_ENTROPY_C", +#endif /* MBEDTLS_ENTROPY_C */ +#if defined(MBEDTLS_ERROR_C) + "MBEDTLS_ERROR_C", +#endif /* MBEDTLS_ERROR_C */ +#if defined(MBEDTLS_GCM_C) + "MBEDTLS_GCM_C", +#endif /* MBEDTLS_GCM_C */ +#if defined(MBEDTLS_HAVEGE_C) + "MBEDTLS_HAVEGE_C", +#endif /* MBEDTLS_HAVEGE_C */ +#if defined(MBEDTLS_HMAC_DRBG_C) + "MBEDTLS_HMAC_DRBG_C", +#endif /* MBEDTLS_HMAC_DRBG_C */ +#if defined(MBEDTLS_MD_C) + "MBEDTLS_MD_C", +#endif /* MBEDTLS_MD_C */ +#if defined(MBEDTLS_MD2_C) + "MBEDTLS_MD2_C", +#endif /* MBEDTLS_MD2_C */ +#if defined(MBEDTLS_MD4_C) + "MBEDTLS_MD4_C", +#endif /* MBEDTLS_MD4_C */ +#if defined(MBEDTLS_MD5_C) + "MBEDTLS_MD5_C", +#endif /* MBEDTLS_MD5_C */ +#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C) + "MBEDTLS_MEMORY_BUFFER_ALLOC_C", +#endif /* MBEDTLS_MEMORY_BUFFER_ALLOC_C */ +#if defined(MBEDTLS_NET_C) + "MBEDTLS_NET_C", +#endif /* MBEDTLS_NET_C */ +#if defined(MBEDTLS_OID_C) + "MBEDTLS_OID_C", +#endif /* MBEDTLS_OID_C */ +#if defined(MBEDTLS_PADLOCK_C) + "MBEDTLS_PADLOCK_C", +#endif /* MBEDTLS_PADLOCK_C */ +#if defined(MBEDTLS_PEM_PARSE_C) + "MBEDTLS_PEM_PARSE_C", +#endif /* MBEDTLS_PEM_PARSE_C */ +#if defined(MBEDTLS_PEM_WRITE_C) + "MBEDTLS_PEM_WRITE_C", +#endif /* MBEDTLS_PEM_WRITE_C */ +#if defined(MBEDTLS_PK_C) + "MBEDTLS_PK_C", +#endif /* MBEDTLS_PK_C */ +#if defined(MBEDTLS_PK_PARSE_C) + "MBEDTLS_PK_PARSE_C", +#endif /* MBEDTLS_PK_PARSE_C */ +#if defined(MBEDTLS_PK_WRITE_C) + "MBEDTLS_PK_WRITE_C", +#endif /* MBEDTLS_PK_WRITE_C */ +#if defined(MBEDTLS_PKCS5_C) + "MBEDTLS_PKCS5_C", +#endif /* MBEDTLS_PKCS5_C */ +#if defined(MBEDTLS_PKCS11_C) + "MBEDTLS_PKCS11_C", +#endif /* MBEDTLS_PKCS11_C */ +#if defined(MBEDTLS_PKCS12_C) + "MBEDTLS_PKCS12_C", +#endif /* MBEDTLS_PKCS12_C */ +#if defined(MBEDTLS_PLATFORM_C) + "MBEDTLS_PLATFORM_C", +#endif /* MBEDTLS_PLATFORM_C */ +#if defined(MBEDTLS_RIPEMD160_C) + "MBEDTLS_RIPEMD160_C", +#endif /* MBEDTLS_RIPEMD160_C */ +#if defined(MBEDTLS_RSA_C) + "MBEDTLS_RSA_C", +#endif /* MBEDTLS_RSA_C */ +#if defined(MBEDTLS_SHA1_C) + "MBEDTLS_SHA1_C", +#endif /* MBEDTLS_SHA1_C */ +#if defined(MBEDTLS_SHA256_C) + "MBEDTLS_SHA256_C", +#endif /* MBEDTLS_SHA256_C */ +#if defined(MBEDTLS_SHA512_C) + "MBEDTLS_SHA512_C", +#endif /* MBEDTLS_SHA512_C */ +#if defined(MBEDTLS_SSL_CACHE_C) + "MBEDTLS_SSL_CACHE_C", +#endif /* MBEDTLS_SSL_CACHE_C */ +#if defined(MBEDTLS_SSL_COOKIE_C) + "MBEDTLS_SSL_COOKIE_C", +#endif /* MBEDTLS_SSL_COOKIE_C */ +#if defined(MBEDTLS_SSL_TICKET_C) + "MBEDTLS_SSL_TICKET_C", +#endif /* MBEDTLS_SSL_TICKET_C */ +#if defined(MBEDTLS_SSL_CLI_C) + "MBEDTLS_SSL_CLI_C", +#endif /* MBEDTLS_SSL_CLI_C */ +#if defined(MBEDTLS_SSL_SRV_C) + "MBEDTLS_SSL_SRV_C", +#endif /* MBEDTLS_SSL_SRV_C */ +#if defined(MBEDTLS_SSL_TLS_C) + "MBEDTLS_SSL_TLS_C", +#endif /* MBEDTLS_SSL_TLS_C */ +#if defined(MBEDTLS_THREADING_C) + "MBEDTLS_THREADING_C", +#endif /* MBEDTLS_THREADING_C */ +#if defined(MBEDTLS_TIMING_C) + "MBEDTLS_TIMING_C", +#endif /* MBEDTLS_TIMING_C */ +#if defined(MBEDTLS_VERSION_C) + "MBEDTLS_VERSION_C", +#endif /* MBEDTLS_VERSION_C */ +#if defined(MBEDTLS_X509_USE_C) + "MBEDTLS_X509_USE_C", +#endif /* MBEDTLS_X509_USE_C */ +#if defined(MBEDTLS_X509_CRT_PARSE_C) + "MBEDTLS_X509_CRT_PARSE_C", +#endif /* MBEDTLS_X509_CRT_PARSE_C */ +#if defined(MBEDTLS_X509_CRL_PARSE_C) + "MBEDTLS_X509_CRL_PARSE_C", +#endif /* MBEDTLS_X509_CRL_PARSE_C */ +#if defined(MBEDTLS_X509_CSR_PARSE_C) + "MBEDTLS_X509_CSR_PARSE_C", +#endif /* MBEDTLS_X509_CSR_PARSE_C */ +#if defined(MBEDTLS_X509_CREATE_C) + "MBEDTLS_X509_CREATE_C", +#endif /* MBEDTLS_X509_CREATE_C */ +#if defined(MBEDTLS_X509_CRT_WRITE_C) + "MBEDTLS_X509_CRT_WRITE_C", +#endif /* MBEDTLS_X509_CRT_WRITE_C */ +#if defined(MBEDTLS_X509_CSR_WRITE_C) + "MBEDTLS_X509_CSR_WRITE_C", +#endif /* MBEDTLS_X509_CSR_WRITE_C */ +#if defined(MBEDTLS_XTEA_C) + "MBEDTLS_XTEA_C", +#endif /* MBEDTLS_XTEA_C */ +#endif /* MBEDTLS_VERSION_FEATURES */ + NULL +}; + +int mbedtls_version_check_feature( const char *feature ) +{ + const char **idx = features; + + if( *idx == NULL ) + return( -2 ); + + if( feature == NULL ) + return( -1 ); + + while( *idx != NULL ) + { + if( !strcmp( *idx, feature ) ) + return( 0 ); + idx++; + } + return( -1 ); +} + +#endif /* MBEDTLS_VERSION_C */ diff --git a/security/mbedtls/src/x509.c b/security/mbedtls/src/x509.c new file mode 100644 index 0000000000..ac1ee8cf31 --- /dev/null +++ b/security/mbedtls/src/x509.c @@ -0,0 +1,1155 @@ +/* + * X.509 common functions for parsing and verification + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +/* + * The ITU-T X.509 standard defines a certificate format for PKI. + * + * http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs) + * http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs) + * http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10) + * + * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf + * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_X509_USE_C) + +#include "mbedtls/x509.h" +#include "mbedtls/asn1.h" +#include "mbedtls/oid.h" +#include "mbedtls/debug.h" + +#include +#include + +#if defined(MBEDTLS_PEM_PARSE_C) +#include "mbedtls/pem.h" +#endif + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#include +#define mbedtls_free free +#define mbedtls_calloc calloc +#define mbedtls_printf printf +#define mbedtls_snprintf snprintf +#endif + +#if defined(MBEDTLS_HAVE_TIME) +#include "mbedtls/platform_time.h" +#endif + +#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) +#include +#else +#include +#endif + +#if defined(MBEDTLS_FS_IO) +#include +#if !defined(_WIN32) +#include +#include +#include +#endif +#endif + +#define CHECK(code) if( ( ret = code ) != 0 ){ return( ret ); } +#define CHECK_RANGE(min, max, val) if( val < min || val > max ){ return( ret ); } + +#if defined(MBEDTLS_IOT_SPECIFIC) +static unsigned char CRT_OID_PKCS1_MD5[] = { + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x04 +}; +static unsigned char CRT_OID_PKCS1_SHA1[] = { + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05 +}; +static unsigned char CRT_OID_PKCS1_SHA256[] = { + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b +}; +#endif + +/* + * CertificateSerialNumber ::= INTEGER + */ +int mbedtls_x509_get_serial( unsigned char **p, const unsigned char *end, + mbedtls_x509_buf *serial ) +{ + int ret; + + if( ( end - *p ) < 1 ) + return( MBEDTLS_ERR_X509_INVALID_SERIAL + + MBEDTLS_ERR_ASN1_OUT_OF_DATA ); + + if( **p != ( MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_PRIMITIVE | 2 ) && + **p != MBEDTLS_ASN1_INTEGER ) + return( MBEDTLS_ERR_X509_INVALID_SERIAL + + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); + + serial->tag = *(*p)++; + + if( ( ret = mbedtls_asn1_get_len( p, end, &serial->len ) ) != 0 ) + return( MBEDTLS_ERR_X509_INVALID_SERIAL + ret ); + + serial->p = *p; + *p += serial->len; + + return( 0 ); +} + +/* Get an algorithm identifier without parameters (eg for signatures) + * + * AlgorithmIdentifier ::= SEQUENCE { + * algorithm OBJECT IDENTIFIER, + * parameters ANY DEFINED BY algorithm OPTIONAL } + */ +int mbedtls_x509_get_alg_null( unsigned char **p, const unsigned char *end, + mbedtls_x509_buf *alg ) +{ + int ret; + + if( ( ret = mbedtls_asn1_get_alg_null( p, end, alg ) ) != 0 ) + return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); + + return( 0 ); +} + +/* + * Parse an algorithm identifier with (optional) paramaters + */ +int mbedtls_x509_get_alg( unsigned char **p, const unsigned char *end, + mbedtls_x509_buf *alg, mbedtls_x509_buf *params ) +{ + int ret; + + if( ( ret = mbedtls_asn1_get_alg( p, end, alg, params ) ) != 0 ) + return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); + + return( 0 ); +} + +#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) +/* + * HashAlgorithm ::= AlgorithmIdentifier + * + * AlgorithmIdentifier ::= SEQUENCE { + * algorithm OBJECT IDENTIFIER, + * parameters ANY DEFINED BY algorithm OPTIONAL } + * + * For HashAlgorithm, parameters MUST be NULL or absent. + */ +static int x509_get_hash_alg( const mbedtls_x509_buf *alg, mbedtls_md_type_t *md_alg ) +{ + int ret; + unsigned char *p; + const unsigned char *end; + mbedtls_x509_buf md_oid; + size_t len; + + /* Make sure we got a SEQUENCE and setup bounds */ + if( alg->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) + return( MBEDTLS_ERR_X509_INVALID_ALG + + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); + + p = (unsigned char *) alg->p; + end = p + alg->len; + + if( p >= end ) + return( MBEDTLS_ERR_X509_INVALID_ALG + + MBEDTLS_ERR_ASN1_OUT_OF_DATA ); + + /* Parse md_oid */ + md_oid.tag = *p; + + if( ( ret = mbedtls_asn1_get_tag( &p, end, &md_oid.len, MBEDTLS_ASN1_OID ) ) != 0 ) + return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); + + md_oid.p = p; + p += md_oid.len; + + /* Get md_alg from md_oid */ + if( ( ret = mbedtls_oid_get_md_alg( &md_oid, md_alg ) ) != 0 ) + return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); + + /* Make sure params is absent of NULL */ + if( p == end ) + return( 0 ); + + if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, MBEDTLS_ASN1_NULL ) ) != 0 || len != 0 ) + return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); + + if( p != end ) + return( MBEDTLS_ERR_X509_INVALID_ALG + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + + return( 0 ); +} + +/* + * RSASSA-PSS-params ::= SEQUENCE { + * hashAlgorithm [0] HashAlgorithm DEFAULT sha1Identifier, + * maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1Identifier, + * saltLength [2] INTEGER DEFAULT 20, + * trailerField [3] INTEGER DEFAULT 1 } + * -- Note that the tags in this Sequence are explicit. + * + * RFC 4055 (which defines use of RSASSA-PSS in PKIX) states that the value + * of trailerField MUST be 1, and PKCS#1 v2.2 doesn't even define any other + * option. Enfore this at parsing time. + */ +int mbedtls_x509_get_rsassa_pss_params( const mbedtls_x509_buf *params, + mbedtls_md_type_t *md_alg, mbedtls_md_type_t *mgf_md, + int *salt_len ) +{ + int ret; + unsigned char *p; + const unsigned char *end, *end2; + size_t len; + mbedtls_x509_buf alg_id, alg_params; + + /* First set everything to defaults */ + *md_alg = MBEDTLS_MD_SHA1; + *mgf_md = MBEDTLS_MD_SHA1; + *salt_len = 20; + + /* Make sure params is a SEQUENCE and setup bounds */ + if( params->tag != ( MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) + return( MBEDTLS_ERR_X509_INVALID_ALG + + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); + + p = (unsigned char *) params->p; + end = p + params->len; + + if( p == end ) + return( 0 ); + + /* + * HashAlgorithm + */ + if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, + MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) ) == 0 ) + { + end2 = p + len; + + /* HashAlgorithm ::= AlgorithmIdentifier (without parameters) */ + if( ( ret = mbedtls_x509_get_alg_null( &p, end2, &alg_id ) ) != 0 ) + return( ret ); + + if( ( ret = mbedtls_oid_get_md_alg( &alg_id, md_alg ) ) != 0 ) + return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); + + if( p != end2 ) + return( MBEDTLS_ERR_X509_INVALID_ALG + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + } + else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) + return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); + + if( p == end ) + return( 0 ); + + /* + * MaskGenAlgorithm + */ + if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, + MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 1 ) ) == 0 ) + { + end2 = p + len; + + /* MaskGenAlgorithm ::= AlgorithmIdentifier (params = HashAlgorithm) */ + if( ( ret = mbedtls_x509_get_alg( &p, end2, &alg_id, &alg_params ) ) != 0 ) + return( ret ); + + /* Only MFG1 is recognised for now */ + if( MBEDTLS_OID_CMP( MBEDTLS_OID_MGF1, &alg_id ) != 0 ) + return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE + + MBEDTLS_ERR_OID_NOT_FOUND ); + + /* Parse HashAlgorithm */ + if( ( ret = x509_get_hash_alg( &alg_params, mgf_md ) ) != 0 ) + return( ret ); + + if( p != end2 ) + return( MBEDTLS_ERR_X509_INVALID_ALG + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + } + else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) + return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); + + if( p == end ) + return( 0 ); + + /* + * salt_len + */ + if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, + MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 2 ) ) == 0 ) + { + end2 = p + len; + + if( ( ret = mbedtls_asn1_get_int( &p, end2, salt_len ) ) != 0 ) + return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); + + if( p != end2 ) + return( MBEDTLS_ERR_X509_INVALID_ALG + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + } + else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) + return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); + + if( p == end ) + return( 0 ); + + /* + * trailer_field (if present, must be 1) + */ + if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, + MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 3 ) ) == 0 ) + { + int trailer_field; + + end2 = p + len; + + if( ( ret = mbedtls_asn1_get_int( &p, end2, &trailer_field ) ) != 0 ) + return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); + + if( p != end2 ) + return( MBEDTLS_ERR_X509_INVALID_ALG + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + + if( trailer_field != 1 ) + return( MBEDTLS_ERR_X509_INVALID_ALG ); + } + else if( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) + return( MBEDTLS_ERR_X509_INVALID_ALG + ret ); + + if( p != end ) + return( MBEDTLS_ERR_X509_INVALID_ALG + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + + return( 0 ); +} +#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ + +/* + * AttributeTypeAndValue ::= SEQUENCE { + * type AttributeType, + * value AttributeValue } + * + * AttributeType ::= OBJECT IDENTIFIER + * + * AttributeValue ::= ANY DEFINED BY AttributeType + */ +static int x509_get_attr_type_value( unsigned char **p, + const unsigned char *end, + mbedtls_x509_name *cur ) +{ + int ret; + size_t len; + mbedtls_x509_buf *oid; + mbedtls_x509_buf *val; + + if( ( ret = mbedtls_asn1_get_tag( p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) + return( MBEDTLS_ERR_X509_INVALID_NAME + ret ); + + if( ( end - *p ) < 1 ) + return( MBEDTLS_ERR_X509_INVALID_NAME + + MBEDTLS_ERR_ASN1_OUT_OF_DATA ); + + oid = &cur->oid; + oid->tag = **p; + + if( ( ret = mbedtls_asn1_get_tag( p, end, &oid->len, MBEDTLS_ASN1_OID ) ) != 0 ) + return( MBEDTLS_ERR_X509_INVALID_NAME + ret ); + + oid->p = *p; + *p += oid->len; + + if( ( end - *p ) < 1 ) + return( MBEDTLS_ERR_X509_INVALID_NAME + + MBEDTLS_ERR_ASN1_OUT_OF_DATA ); + + if( **p != MBEDTLS_ASN1_BMP_STRING && **p != MBEDTLS_ASN1_UTF8_STRING && + **p != MBEDTLS_ASN1_T61_STRING && **p != MBEDTLS_ASN1_PRINTABLE_STRING && + **p != MBEDTLS_ASN1_IA5_STRING && **p != MBEDTLS_ASN1_UNIVERSAL_STRING && + **p != MBEDTLS_ASN1_BIT_STRING ) + return( MBEDTLS_ERR_X509_INVALID_NAME + + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); + + val = &cur->val; + val->tag = *(*p)++; + + if( ( ret = mbedtls_asn1_get_len( p, end, &val->len ) ) != 0 ) + return( MBEDTLS_ERR_X509_INVALID_NAME + ret ); + + val->p = *p; + *p += val->len; + + cur->next = NULL; + + return( 0 ); +} + +/* + * Name ::= CHOICE { -- only one possibility for now -- + * rdnSequence RDNSequence } + * + * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName + * + * RelativeDistinguishedName ::= + * SET OF AttributeTypeAndValue + * + * AttributeTypeAndValue ::= SEQUENCE { + * type AttributeType, + * value AttributeValue } + * + * AttributeType ::= OBJECT IDENTIFIER + * + * AttributeValue ::= ANY DEFINED BY AttributeType + * + * The data structure is optimized for the common case where each RDN has only + * one element, which is represented as a list of AttributeTypeAndValue. + * For the general case we still use a flat list, but we mark elements of the + * same set so that they are "merged" together in the functions that consume + * this list, eg mbedtls_x509_dn_gets(). + */ +int mbedtls_x509_get_name( unsigned char **p, const unsigned char *end, + mbedtls_x509_name *cur ) +{ + int ret; + size_t set_len; + const unsigned char *end_set; + + /* don't use recursion, we'd risk stack overflow if not optimized */ + while( 1 ) + { + /* + * parse SET + */ + if( ( ret = mbedtls_asn1_get_tag( p, end, &set_len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET ) ) != 0 ) + return( MBEDTLS_ERR_X509_INVALID_NAME + ret ); + + end_set = *p + set_len; + + while( 1 ) + { + if( ( ret = x509_get_attr_type_value( p, end_set, cur ) ) != 0 ) + return( ret ); + + if( *p == end_set ) + break; + + /* Mark this item as being no the only one in a set */ + cur->next_merged = 1; + + cur->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_name ) ); + + if( cur->next == NULL ) + return( MBEDTLS_ERR_X509_ALLOC_FAILED ); + + cur = cur->next; + } + + /* + * continue until end of SEQUENCE is reached + */ + if( *p == end ) + return( 0 ); + + cur->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_name ) ); + + if( cur->next == NULL ) + return( MBEDTLS_ERR_X509_ALLOC_FAILED ); + + cur = cur->next; + } +} + +static int x509_parse_int( unsigned char **p, size_t n, int *res ) +{ + *res = 0; + + for( ; n > 0; --n ) + { + if( ( **p < '0') || ( **p > '9' ) ) + return ( MBEDTLS_ERR_X509_INVALID_DATE ); + + *res *= 10; + *res += ( *(*p)++ - '0' ); + } + + return( 0 ); +} + +static int x509_date_is_valid(const mbedtls_x509_time *time) +{ + int ret = MBEDTLS_ERR_X509_INVALID_DATE; + + CHECK_RANGE( 0, 9999, time->year ); + CHECK_RANGE( 0, 23, time->hour ); + CHECK_RANGE( 0, 59, time->min ); + CHECK_RANGE( 0, 59, time->sec ); + + switch( time->mon ) + { + case 1: case 3: case 5: case 7: case 8: case 10: case 12: + CHECK_RANGE( 1, 31, time->day ); + break; + case 4: case 6: case 9: case 11: + CHECK_RANGE( 1, 30, time->day ); + break; + case 2: + CHECK_RANGE( 1, 28 + (time->year % 4 == 0), time->day ); + break; + default: + return( ret ); + } + + return( 0 ); +} + +/* + * Parse an ASN1_UTC_TIME (yearlen=2) or ASN1_GENERALIZED_TIME (yearlen=4) + * field. + */ +static int x509_parse_time( unsigned char **p, size_t len, size_t yearlen, + mbedtls_x509_time *time ) +{ + int ret; + + /* + * Minimum length is 10 or 12 depending on yearlen + */ + if ( len < yearlen + 8 ) + return ( MBEDTLS_ERR_X509_INVALID_DATE ); + len -= yearlen + 8; + + /* + * Parse year, month, day, hour, minute + */ + CHECK( x509_parse_int( p, yearlen, &time->year ) ); + if ( 2 == yearlen ) + { + if ( time->year < 50 ) + time->year += 100; + + time->year += 1900; + } + + CHECK( x509_parse_int( p, 2, &time->mon ) ); + CHECK( x509_parse_int( p, 2, &time->day ) ); + CHECK( x509_parse_int( p, 2, &time->hour ) ); + CHECK( x509_parse_int( p, 2, &time->min ) ); + + /* + * Parse seconds if present + */ + if ( len >= 2 ) + { + CHECK( x509_parse_int( p, 2, &time->sec ) ); + len -= 2; + } + else + return ( MBEDTLS_ERR_X509_INVALID_DATE ); + + /* + * Parse trailing 'Z' if present + */ + if ( 1 == len && 'Z' == **p ) + { + (*p)++; + len--; + } + + /* + * We should have parsed all characters at this point + */ + if ( 0 != len ) + return ( MBEDTLS_ERR_X509_INVALID_DATE ); + + CHECK( x509_date_is_valid( time ) ); + + return ( 0 ); +} + +/* + * Time ::= CHOICE { + * utcTime UTCTime, + * generalTime GeneralizedTime } + */ +int mbedtls_x509_get_time( unsigned char **p, const unsigned char *end, + mbedtls_x509_time *time ) +{ + int ret; + size_t len, year_len; + unsigned char tag; + + if( ( end - *p ) < 1 ) + return( MBEDTLS_ERR_X509_INVALID_DATE + + MBEDTLS_ERR_ASN1_OUT_OF_DATA ); + + tag = **p; + + if( tag == MBEDTLS_ASN1_UTC_TIME ) + year_len = 2; + else if( tag == MBEDTLS_ASN1_GENERALIZED_TIME ) + year_len = 4; + else + return( MBEDTLS_ERR_X509_INVALID_DATE + + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); + + (*p)++; + ret = mbedtls_asn1_get_len( p, end, &len ); + + if( ret != 0 ) + return( MBEDTLS_ERR_X509_INVALID_DATE + ret ); + + return x509_parse_time( p, len, year_len, time ); +} + +int mbedtls_x509_get_sig( unsigned char **p, const unsigned char *end, mbedtls_x509_buf *sig ) +{ + int ret; + size_t len; + int tag_type; + + if( ( end - *p ) < 1 ) + return( MBEDTLS_ERR_X509_INVALID_SIGNATURE + + MBEDTLS_ERR_ASN1_OUT_OF_DATA ); + + tag_type = **p; + + if( ( ret = mbedtls_asn1_get_bitstring_null( p, end, &len ) ) != 0 ) + return( MBEDTLS_ERR_X509_INVALID_SIGNATURE + ret ); + + sig->tag = tag_type; + sig->len = len; + sig->p = *p; + + *p += len; + + return( 0 ); +} + +/* + * Get signature algorithm from alg OID and optional parameters + */ +int mbedtls_x509_get_sig_alg( const mbedtls_x509_buf *sig_oid, const mbedtls_x509_buf *sig_params, + mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg, + void **sig_opts ) +{ +#if !defined(MBEDTLS_IOT_SPECIFIC) + int ret; +#endif + + if( *sig_opts != NULL ) + return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); + +#if defined(MBEDTLS_IOT_SPECIFIC) + *md_alg = MBEDTLS_MD_NONE; + *pk_alg = MBEDTLS_PK_NONE; + + if( sig_oid->len == CRT_OID_IDENT_LEN) { +#if defined(MBEDTLS_MD5_C) + if (!memcmp(sig_oid->p, CRT_OID_PKCS1_MD5, CRT_OID_IDENT_LEN)) { + *md_alg = MBEDTLS_MD_MD5; + *pk_alg = MBEDTLS_PK_RSA; + } +#endif /* MBEDTLS_MD5_C */ + +#if defined(MBEDTLS_SHA1_C) + if (!memcmp(sig_oid->p, CRT_OID_PKCS1_SHA1, CRT_OID_IDENT_LEN)) { + *md_alg = MBEDTLS_MD_SHA1; + *pk_alg = MBEDTLS_PK_RSA; + } +#endif /* MBEDTLS_SHA1_C */ + +#if defined(MBEDTLS_SHA256_C) + if (!memcmp(sig_oid->p, CRT_OID_PKCS1_SHA256, CRT_OID_IDENT_LEN)) { + *md_alg = MBEDTLS_MD_SHA256; + *pk_alg = MBEDTLS_PK_RSA; + } +#endif /* MBEDTLS_SHA256_C */ + } + + if (*md_alg == MBEDTLS_MD_NONE) { + MBEDTLS_ALT_DEBUG_BUF(2, "x509_sig_oid", sig_oid->p, sig_oid->len); + return( MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG + MBEDTLS_ERR_OID_NOT_FOUND ); + } + +#else + if( ( ret = mbedtls_oid_get_sig_alg( sig_oid, md_alg, pk_alg ) ) != 0 ) { + return( MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG + ret ); + } +#endif /* MBEDTLS_IOT_SPECIFIC */ + +#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) + if( *pk_alg == MBEDTLS_PK_RSASSA_PSS ) + { + mbedtls_pk_rsassa_pss_options *pss_opts; + + pss_opts = mbedtls_calloc( 1, sizeof( mbedtls_pk_rsassa_pss_options ) ); + if( pss_opts == NULL ) + return( MBEDTLS_ERR_X509_ALLOC_FAILED ); + + ret = mbedtls_x509_get_rsassa_pss_params( sig_params, + md_alg, + &pss_opts->mgf1_hash_id, + &pss_opts->expected_salt_len ); + if( ret != 0 ) + { + mbedtls_free( pss_opts ); + return( ret ); + } + + *sig_opts = (void *) pss_opts; + } + else +#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ + { + /* Make sure parameters are absent or NULL */ + if( ( sig_params->tag != MBEDTLS_ASN1_NULL && sig_params->tag != 0 ) || + sig_params->len != 0 ) + return( MBEDTLS_ERR_X509_INVALID_ALG ); + } + + return( 0 ); +} + +/* + * X.509 Extensions (No parsing of extensions, pointer should + * be either manually updated or extensions should be parsed!) + */ +int mbedtls_x509_get_ext( unsigned char **p, const unsigned char *end, + mbedtls_x509_buf *ext, int tag ) +{ + int ret; +#if !defined(MBEDTLS_IOT_SPECIFIC) + size_t len; +#endif + + if( *p == end ) + return( 0 ); + + ext->tag = **p; + + if( ( ret = mbedtls_asn1_get_tag( p, end, &ext->len, + MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | tag ) ) != 0 ) + return( ret ); + + ext->p = *p; + end = *p + ext->len; + +#if !defined(MBEDTLS_IOT_SPECIFIC) + /* + * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension + * + * Extension ::= SEQUENCE { + * extnID OBJECT IDENTIFIER, + * critical BOOLEAN DEFAULT FALSE, + * extnValue OCTET STRING } + */ + if( ( ret = mbedtls_asn1_get_tag( p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); + + if( end != *p + len ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); +#endif + + return( 0 ); +} + +#if !defined(MBEDTLS_IOT_SPECIFIC) +/* + * Store the name in printable form into buf; no more + * than size characters will be written + */ +int mbedtls_x509_dn_gets( char *buf, size_t size, const mbedtls_x509_name *dn ) +{ + int ret; + size_t i, n; + unsigned char c, merge = 0; + const mbedtls_x509_name *name; + const char *short_name = NULL; + char s[MBEDTLS_X509_MAX_DN_NAME_SIZE], *p; + + memset( s, 0, sizeof( s ) ); + + name = dn; + p = buf; + n = size; + + while( name != NULL ) + { + if( !name->oid.p ) + { + name = name->next; + continue; + } + + if( name != dn ) + { + ret = mbedtls_snprintf( p, n, merge ? " + " : ", " ); + MBEDTLS_X509_SAFE_SNPRINTF; + } + + ret = mbedtls_oid_get_attr_short_name( &name->oid, &short_name ); + + if( ret == 0 ) + ret = mbedtls_snprintf( p, n, "%s=", short_name ); + else + ret = mbedtls_snprintf( p, n, "\?\?=" ); + MBEDTLS_X509_SAFE_SNPRINTF; + + for( i = 0; i < name->val.len; i++ ) + { + if( i >= sizeof( s ) - 1 ) + break; + + c = name->val.p[i]; + if( c < 32 || c == 127 || ( c > 128 && c < 160 ) ) + s[i] = '?'; + else s[i] = c; + } + s[i] = '\0'; + ret = mbedtls_snprintf( p, n, "%s", s ); + MBEDTLS_X509_SAFE_SNPRINTF; + + merge = name->next_merged; + name = name->next; + } + + return( (int) ( size - n ) ); +} +#endif + +/* + * Store the serial in printable form into buf; no more + * than size characters will be written + */ +int mbedtls_x509_serial_gets( char *buf, size_t size, const mbedtls_x509_buf *serial ) +{ + int ret; + size_t i, n, nr; + char *p; + + p = buf; + n = size; + + nr = ( serial->len <= 32 ) + ? serial->len : 28; + + for( i = 0; i < nr; i++ ) + { + if( i == 0 && nr > 1 && serial->p[i] == 0x0 ) + continue; + + ret = mbedtls_snprintf( p, n, "%02X%s", + serial->p[i], ( i < nr - 1 ) ? ":" : "" ); + MBEDTLS_X509_SAFE_SNPRINTF; + } + + if( nr != serial->len ) + { + ret = mbedtls_snprintf( p, n, "...." ); + MBEDTLS_X509_SAFE_SNPRINTF; + } + + return( (int) ( size - n ) ); +} + +#if !defined(MBEDTLS_IOT_SPECIFIC) +/* + * Helper for writing signature algorithms + */ +int mbedtls_x509_sig_alg_gets( char *buf, size_t size, const mbedtls_x509_buf *sig_oid, + mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg, + const void *sig_opts ) +{ + int ret; + char *p = buf; + size_t n = size; + const char *desc = NULL; + + ret = mbedtls_oid_get_sig_alg_desc( sig_oid, &desc ); + if( ret != 0 ) + ret = mbedtls_snprintf( p, n, "???" ); + else + ret = mbedtls_snprintf( p, n, "%s", desc ); + MBEDTLS_X509_SAFE_SNPRINTF; + +#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) + if( pk_alg == MBEDTLS_PK_RSASSA_PSS ) + { + const mbedtls_pk_rsassa_pss_options *pss_opts; + const mbedtls_md_info_t *md_info, *mgf_md_info; + + pss_opts = (const mbedtls_pk_rsassa_pss_options *) sig_opts; + + md_info = mbedtls_md_info_from_type( md_alg ); + mgf_md_info = mbedtls_md_info_from_type( pss_opts->mgf1_hash_id ); + + ret = mbedtls_snprintf( p, n, " (%s, MGF1-%s, 0x%02X)", + md_info ? mbedtls_md_get_name( md_info ) : "???", + mgf_md_info ? mbedtls_md_get_name( mgf_md_info ) : "???", + pss_opts->expected_salt_len ); + MBEDTLS_X509_SAFE_SNPRINTF; + } +#else + ((void) pk_alg); + ((void) md_alg); + ((void) sig_opts); +#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */ + + return( (int)( size - n ) ); +} +#endif /* MBEDTLS_IOT_SPECIFIC */ + +/* + * Helper for writing "RSA key size", "EC key size", etc + */ +int mbedtls_x509_key_size_helper( char *buf, size_t buf_size, const char *name ) +{ + char *p = buf; + size_t n = buf_size; + int ret; + + ret = mbedtls_snprintf( p, n, "%s key size", name ); + MBEDTLS_X509_SAFE_SNPRINTF; + + return( 0 ); +} + +#if defined(MBEDTLS_HAVE_TIME_DATE) +/* + * Set the time structure to the current time. + * Return 0 on success, non-zero on failure. + */ +#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) +static int x509_get_current_time( mbedtls_x509_time *now ) +{ + SYSTEMTIME st; + + GetSystemTime( &st ); + + now->year = st.wYear; + now->mon = st.wMonth; + now->day = st.wDay; + now->hour = st.wHour; + now->min = st.wMinute; + now->sec = st.wSecond; + + return( 0 ); +} +#else +static int x509_get_current_time( mbedtls_x509_time *now ) +{ + struct tm *lt; + mbedtls_time_t tt; + int ret = 0; + +#if defined(MBEDTLS_THREADING_C) + if( mbedtls_mutex_lock( &mbedtls_threading_gmtime_mutex ) != 0 ) + return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); +#endif + + tt = mbedtls_time( NULL ); + lt = gmtime( &tt ); + + if( lt == NULL ) + ret = -1; + else + { + now->year = lt->tm_year + 1900; + now->mon = lt->tm_mon + 1; + now->day = lt->tm_mday; + now->hour = lt->tm_hour; + now->min = lt->tm_min; + now->sec = lt->tm_sec; + } + +#if defined(MBEDTLS_THREADING_C) + if( mbedtls_mutex_unlock( &mbedtls_threading_gmtime_mutex ) != 0 ) + return( MBEDTLS_ERR_THREADING_MUTEX_ERROR ); +#endif + + return( ret ); +} +#endif /* _WIN32 && !EFIX64 && !EFI32 */ + +/* + * Return 0 if before <= after, 1 otherwise + */ +static int x509_check_time( const mbedtls_x509_time *before, const mbedtls_x509_time *after ) +{ + if( before->year > after->year ) + return( 1 ); + + if( before->year == after->year && + before->mon > after->mon ) + return( 1 ); + + if( before->year == after->year && + before->mon == after->mon && + before->day > after->day ) + return( 1 ); + + if( before->year == after->year && + before->mon == after->mon && + before->day == after->day && + before->hour > after->hour ) + return( 1 ); + + if( before->year == after->year && + before->mon == after->mon && + before->day == after->day && + before->hour == after->hour && + before->min > after->min ) + return( 1 ); + + if( before->year == after->year && + before->mon == after->mon && + before->day == after->day && + before->hour == after->hour && + before->min == after->min && + before->sec > after->sec ) + return( 1 ); + + return( 0 ); +} + +int mbedtls_x509_time_is_past( const mbedtls_x509_time *to ) +{ + mbedtls_x509_time now; + + if( x509_get_current_time( &now ) != 0 ) + return( 1 ); + + return( x509_check_time( &now, to ) ); +} + +int mbedtls_x509_time_is_future( const mbedtls_x509_time *from ) +{ + mbedtls_x509_time now; + + if( x509_get_current_time( &now ) != 0 ) + return( 1 ); + + return( x509_check_time( from, &now ) ); +} + +#else /* MBEDTLS_HAVE_TIME_DATE */ + +int mbedtls_x509_time_is_past( const mbedtls_x509_time *to ) +{ + ((void) to); + return( 0 ); +} + +int mbedtls_x509_time_is_future( const mbedtls_x509_time *from ) +{ + ((void) from); + return( 0 ); +} +#endif /* MBEDTLS_HAVE_TIME_DATE */ + +#if defined(MBEDTLS_SELF_TEST) + +#include "mbedtls/x509_crt.h" +#include "mbedtls/certs.h" + +/* + * Checkup routine + */ +int mbedtls_x509_self_test( int verbose ) +{ +#if defined(MBEDTLS_CERTS_C) && defined(MBEDTLS_SHA1_C) + int ret; + uint32_t flags; + mbedtls_x509_crt cacert; + mbedtls_x509_crt clicert; + + if( verbose != 0 ) + mbedtls_printf( " X.509 certificate load: " ); + + mbedtls_x509_crt_init( &clicert ); + + ret = mbedtls_x509_crt_parse( &clicert, (const unsigned char *) mbedtls_test_cli_crt, + mbedtls_test_cli_crt_len ); + if( ret != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( ret ); + } + + mbedtls_x509_crt_init( &cacert ); + + ret = mbedtls_x509_crt_parse( &cacert, (const unsigned char *) mbedtls_test_ca_crt, + mbedtls_test_ca_crt_len ); + if( ret != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( ret ); + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n X.509 signature verify: "); + + ret = mbedtls_x509_crt_verify( &clicert, &cacert, NULL, NULL, &flags, NULL, NULL ); + if( ret != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + return( ret ); + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n\n"); + + mbedtls_x509_crt_free( &cacert ); + mbedtls_x509_crt_free( &clicert ); + + return( 0 ); +#else + ((void) verbose); + return( 0 ); +#endif /* MBEDTLS_CERTS_C && MBEDTLS_SHA1_C */ +} + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_X509_USE_C */ diff --git a/security/mbedtls/src/x509_create.c b/security/mbedtls/src/x509_create.c new file mode 100644 index 0000000000..df20ec8ebd --- /dev/null +++ b/security/mbedtls/src/x509_create.c @@ -0,0 +1,340 @@ +/* + * X.509 base functions for creating certificates / CSRs + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_X509_CREATE_C) + +#include "mbedtls/x509.h" +#include "mbedtls/asn1write.h" +#include "mbedtls/oid.h" + +#include + +typedef struct { + const char *name; + size_t name_len; + const char*oid; +} x509_attr_descriptor_t; + +#define ADD_STRLEN( s ) s, sizeof( s ) - 1 + +static const x509_attr_descriptor_t x509_attrs[] = +{ + { ADD_STRLEN( "CN" ), MBEDTLS_OID_AT_CN }, + { ADD_STRLEN( "commonName" ), MBEDTLS_OID_AT_CN }, + { ADD_STRLEN( "C" ), MBEDTLS_OID_AT_COUNTRY }, + { ADD_STRLEN( "countryName" ), MBEDTLS_OID_AT_COUNTRY }, + { ADD_STRLEN( "O" ), MBEDTLS_OID_AT_ORGANIZATION }, + { ADD_STRLEN( "organizationName" ), MBEDTLS_OID_AT_ORGANIZATION }, + { ADD_STRLEN( "L" ), MBEDTLS_OID_AT_LOCALITY }, + { ADD_STRLEN( "locality" ), MBEDTLS_OID_AT_LOCALITY }, + { ADD_STRLEN( "R" ), MBEDTLS_OID_PKCS9_EMAIL }, + { ADD_STRLEN( "OU" ), MBEDTLS_OID_AT_ORG_UNIT }, + { ADD_STRLEN( "organizationalUnitName" ), MBEDTLS_OID_AT_ORG_UNIT }, + { ADD_STRLEN( "ST" ), MBEDTLS_OID_AT_STATE }, + { ADD_STRLEN( "stateOrProvinceName" ), MBEDTLS_OID_AT_STATE }, + { ADD_STRLEN( "emailAddress" ), MBEDTLS_OID_PKCS9_EMAIL }, + { ADD_STRLEN( "serialNumber" ), MBEDTLS_OID_AT_SERIAL_NUMBER }, + { ADD_STRLEN( "postalAddress" ), MBEDTLS_OID_AT_POSTAL_ADDRESS }, + { ADD_STRLEN( "postalCode" ), MBEDTLS_OID_AT_POSTAL_CODE }, + { ADD_STRLEN( "dnQualifier" ), MBEDTLS_OID_AT_DN_QUALIFIER }, + { ADD_STRLEN( "title" ), MBEDTLS_OID_AT_TITLE }, + { ADD_STRLEN( "surName" ), MBEDTLS_OID_AT_SUR_NAME }, + { ADD_STRLEN( "SN" ), MBEDTLS_OID_AT_SUR_NAME }, + { ADD_STRLEN( "givenName" ), MBEDTLS_OID_AT_GIVEN_NAME }, + { ADD_STRLEN( "GN" ), MBEDTLS_OID_AT_GIVEN_NAME }, + { ADD_STRLEN( "initials" ), MBEDTLS_OID_AT_INITIALS }, + { ADD_STRLEN( "pseudonym" ), MBEDTLS_OID_AT_PSEUDONYM }, + { ADD_STRLEN( "generationQualifier" ), MBEDTLS_OID_AT_GENERATION_QUALIFIER }, + { ADD_STRLEN( "domainComponent" ), MBEDTLS_OID_DOMAIN_COMPONENT }, + { ADD_STRLEN( "DC" ), MBEDTLS_OID_DOMAIN_COMPONENT }, + { NULL, 0, NULL } +}; + +static const char *x509_at_oid_from_name( const char *name, size_t name_len ) +{ + const x509_attr_descriptor_t *cur; + + for( cur = x509_attrs; cur->name != NULL; cur++ ) + if( cur->name_len == name_len && + strncmp( cur->name, name, name_len ) == 0 ) + break; + + return( cur->oid ); +} + +int mbedtls_x509_string_to_names( mbedtls_asn1_named_data **head, const char *name ) +{ + int ret = 0; + const char *s = name, *c = s; + const char *end = s + strlen( s ); + const char *oid = NULL; + int in_tag = 1; + char data[MBEDTLS_X509_MAX_DN_NAME_SIZE]; + char *d = data; + + /* Clear existing chain if present */ + mbedtls_asn1_free_named_data_list( head ); + + while( c <= end ) + { + if( in_tag && *c == '=' ) + { + if( ( oid = x509_at_oid_from_name( s, c - s ) ) == NULL ) + { + ret = MBEDTLS_ERR_X509_UNKNOWN_OID; + goto exit; + } + + s = c + 1; + in_tag = 0; + d = data; + } + + if( !in_tag && *c == '\\' && c != end ) + { + c++; + + /* Check for valid escaped characters */ + if( c == end || *c != ',' ) + { + ret = MBEDTLS_ERR_X509_INVALID_NAME; + goto exit; + } + } + else if( !in_tag && ( *c == ',' || c == end ) ) + { + if( mbedtls_asn1_store_named_data( head, oid, strlen( oid ), + (unsigned char *) data, + d - data ) == NULL ) + { + return( MBEDTLS_ERR_X509_ALLOC_FAILED ); + } + + while( c < end && *(c + 1) == ' ' ) + c++; + + s = c + 1; + in_tag = 1; + } + + if( !in_tag && s != c + 1 ) + { + *(d++) = *c; + + if( d - data == MBEDTLS_X509_MAX_DN_NAME_SIZE ) + { + ret = MBEDTLS_ERR_X509_INVALID_NAME; + goto exit; + } + } + + c++; + } + +exit: + + return( ret ); +} + +/* The first byte of the value in the mbedtls_asn1_named_data structure is reserved + * to store the critical boolean for us + */ +int mbedtls_x509_set_extension( mbedtls_asn1_named_data **head, const char *oid, size_t oid_len, + int critical, const unsigned char *val, size_t val_len ) +{ + mbedtls_asn1_named_data *cur; + + if( ( cur = mbedtls_asn1_store_named_data( head, oid, oid_len, + NULL, val_len + 1 ) ) == NULL ) + { + return( MBEDTLS_ERR_X509_ALLOC_FAILED ); + } + + cur->val.p[0] = critical; + memcpy( cur->val.p + 1, val, val_len ); + + return( 0 ); +} + +/* + * RelativeDistinguishedName ::= + * SET OF AttributeTypeAndValue + * + * AttributeTypeAndValue ::= SEQUENCE { + * type AttributeType, + * value AttributeValue } + * + * AttributeType ::= OBJECT IDENTIFIER + * + * AttributeValue ::= ANY DEFINED BY AttributeType + */ +static int x509_write_name( unsigned char **p, unsigned char *start, + const char *oid, size_t oid_len, + const unsigned char *name, size_t name_len ) +{ + int ret; + size_t len = 0; + + // Write PrintableString for all except MBEDTLS_OID_PKCS9_EMAIL + // + if( MBEDTLS_OID_SIZE( MBEDTLS_OID_PKCS9_EMAIL ) == oid_len && + memcmp( oid, MBEDTLS_OID_PKCS9_EMAIL, oid_len ) == 0 ) + { + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_ia5_string( p, start, + (const char *) name, + name_len ) ); + } + else + { + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_printable_string( p, start, + (const char *) name, + name_len ) ); + } + + // Write OID + // + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( p, start, oid, oid_len ) ); + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_CONSTRUCTED | + MBEDTLS_ASN1_SEQUENCE ) ); + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_CONSTRUCTED | + MBEDTLS_ASN1_SET ) ); + + return( (int) len ); +} + +int mbedtls_x509_write_names( unsigned char **p, unsigned char *start, + mbedtls_asn1_named_data *first ) +{ + int ret; + size_t len = 0; + mbedtls_asn1_named_data *cur = first; + + while( cur != NULL ) + { + MBEDTLS_ASN1_CHK_ADD( len, x509_write_name( p, start, (char *) cur->oid.p, + cur->oid.len, + cur->val.p, cur->val.len ) ); + cur = cur->next; + } + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_CONSTRUCTED | + MBEDTLS_ASN1_SEQUENCE ) ); + + return( (int) len ); +} + +int mbedtls_x509_write_sig( unsigned char **p, unsigned char *start, + const char *oid, size_t oid_len, + unsigned char *sig, size_t size ) +{ + int ret; + size_t len = 0; + + if( *p < start || (size_t)( *p - start ) < size ) + return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); + + len = size; + (*p) -= len; + memcpy( *p, sig, len ); + + if( *p - start < 1 ) + return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); + + *--(*p) = 0; + len += 1; + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_BIT_STRING ) ); + + // Write OID + // + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_algorithm_identifier( p, start, oid, + oid_len, 0 ) ); + + return( (int) len ); +} + +static int x509_write_extension( unsigned char **p, unsigned char *start, + mbedtls_asn1_named_data *ext ) +{ + int ret; + size_t len = 0; + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, ext->val.p + 1, + ext->val.len - 1 ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, ext->val.len - 1 ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_OCTET_STRING ) ); + + if( ext->val.p[0] != 0 ) + { + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_bool( p, start, 1 ) ); + } + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, ext->oid.p, + ext->oid.len ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, ext->oid.len ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_OID ) ); + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_CONSTRUCTED | + MBEDTLS_ASN1_SEQUENCE ) ); + + return( (int) len ); +} + +/* + * Extension ::= SEQUENCE { + * extnID OBJECT IDENTIFIER, + * critical BOOLEAN DEFAULT FALSE, + * extnValue OCTET STRING + * -- contains the DER encoding of an ASN.1 value + * -- corresponding to the extension type identified + * -- by extnID + * } + */ +int mbedtls_x509_write_extensions( unsigned char **p, unsigned char *start, + mbedtls_asn1_named_data *first ) +{ + int ret; + size_t len = 0; + mbedtls_asn1_named_data *cur_ext = first; + + while( cur_ext != NULL ) + { + MBEDTLS_ASN1_CHK_ADD( len, x509_write_extension( p, start, cur_ext ) ); + cur_ext = cur_ext->next; + } + + return( (int) len ); +} + +#endif /* MBEDTLS_X509_CREATE_C */ diff --git a/security/mbedtls/src/x509_crl.c b/security/mbedtls/src/x509_crl.c new file mode 100644 index 0000000000..927f30375a --- /dev/null +++ b/security/mbedtls/src/x509_crl.c @@ -0,0 +1,725 @@ +/* + * X.509 Certidicate Revocation List (CRL) parsing + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +/* + * The ITU-T X.509 standard defines a certificate format for PKI. + * + * http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs) + * http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs) + * http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10) + * + * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf + * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_X509_CRL_PARSE_C) + +#include "mbedtls/x509_crl.h" +#include "mbedtls/oid.h" + +#include + +#if defined(MBEDTLS_PEM_PARSE_C) +#include "mbedtls/pem.h" +#endif + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#include +#define mbedtls_free free +#define mbedtls_calloc calloc +#define mbedtls_snprintf snprintf +#endif + +#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) +#include +#else +#include +#endif + +#if defined(MBEDTLS_FS_IO) || defined(EFIX64) || defined(EFI32) +#include +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +/* + * Version ::= INTEGER { v1(0), v2(1) } + */ +static int x509_crl_get_version( unsigned char **p, + const unsigned char *end, + int *ver ) +{ + int ret; + + if( ( ret = mbedtls_asn1_get_int( p, end, ver ) ) != 0 ) + { + if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) + { + *ver = 0; + return( 0 ); + } + + return( MBEDTLS_ERR_X509_INVALID_VERSION + ret ); + } + + return( 0 ); +} + +/* + * X.509 CRL v2 extensions (no extensions parsed yet.) + */ +static int x509_get_crl_ext( unsigned char **p, + const unsigned char *end, + mbedtls_x509_buf *ext ) +{ + int ret; + size_t len = 0; + + /* Get explicit tag */ + if( ( ret = mbedtls_x509_get_ext( p, end, ext, 0) ) != 0 ) + { + if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) + return( 0 ); + + return( ret ); + } + + while( *p < end ) + { + if( ( ret = mbedtls_asn1_get_tag( p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); + + *p += len; + } + + if( *p != end ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + + return( 0 ); +} + +/* + * X.509 CRL v2 entry extensions (no extensions parsed yet.) + */ +static int x509_get_crl_entry_ext( unsigned char **p, + const unsigned char *end, + mbedtls_x509_buf *ext ) +{ + int ret; + size_t len = 0; + + /* OPTIONAL */ + if( end <= *p ) + return( 0 ); + + ext->tag = **p; + ext->p = *p; + + /* + * Get CRL-entry extension sequence header + * crlEntryExtensions Extensions OPTIONAL -- if present, MUST be v2 + */ + if( ( ret = mbedtls_asn1_get_tag( p, end, &ext->len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) + { + if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) + { + ext->p = NULL; + return( 0 ); + } + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); + } + + end = *p + ext->len; + + if( end != *p + ext->len ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + + while( *p < end ) + { + if( ( ret = mbedtls_asn1_get_tag( p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); + + *p += len; + } + + if( *p != end ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + + return( 0 ); +} + +/* + * X.509 CRL Entries + */ +static int x509_get_entries( unsigned char **p, + const unsigned char *end, + mbedtls_x509_crl_entry *entry ) +{ + int ret; + size_t entry_len; + mbedtls_x509_crl_entry *cur_entry = entry; + + if( *p == end ) + return( 0 ); + + if( ( ret = mbedtls_asn1_get_tag( p, end, &entry_len, + MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED ) ) != 0 ) + { + if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) + return( 0 ); + + return( ret ); + } + + end = *p + entry_len; + + while( *p < end ) + { + size_t len2; + const unsigned char *end2; + + if( ( ret = mbedtls_asn1_get_tag( p, end, &len2, + MBEDTLS_ASN1_SEQUENCE | MBEDTLS_ASN1_CONSTRUCTED ) ) != 0 ) + { + return( ret ); + } + + cur_entry->raw.tag = **p; + cur_entry->raw.p = *p; + cur_entry->raw.len = len2; + end2 = *p + len2; + + if( ( ret = mbedtls_x509_get_serial( p, end2, &cur_entry->serial ) ) != 0 ) + return( ret ); + + if( ( ret = mbedtls_x509_get_time( p, end2, + &cur_entry->revocation_date ) ) != 0 ) + return( ret ); + + if( ( ret = x509_get_crl_entry_ext( p, end2, + &cur_entry->entry_ext ) ) != 0 ) + return( ret ); + + if( *p < end ) + { + cur_entry->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_crl_entry ) ); + + if( cur_entry->next == NULL ) + return( MBEDTLS_ERR_X509_ALLOC_FAILED ); + + cur_entry = cur_entry->next; + } + } + + return( 0 ); +} + +/* + * Parse one CRLs in DER format and append it to the chained list + */ +int mbedtls_x509_crl_parse_der( mbedtls_x509_crl *chain, + const unsigned char *buf, size_t buflen ) +{ + int ret; + size_t len; + unsigned char *p, *end; + mbedtls_x509_buf sig_params1, sig_params2, sig_oid2; + mbedtls_x509_crl *crl = chain; + + /* + * Check for valid input + */ + if( crl == NULL || buf == NULL ) + return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); + + memset( &sig_params1, 0, sizeof( mbedtls_x509_buf ) ); + memset( &sig_params2, 0, sizeof( mbedtls_x509_buf ) ); + memset( &sig_oid2, 0, sizeof( mbedtls_x509_buf ) ); + + /* + * Add new CRL on the end of the chain if needed. + */ + while( crl->version != 0 && crl->next != NULL ) + crl = crl->next; + + if( crl->version != 0 && crl->next == NULL ) + { + crl->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_crl ) ); + + if( crl->next == NULL ) + { + mbedtls_x509_crl_free( crl ); + return( MBEDTLS_ERR_X509_ALLOC_FAILED ); + } + + mbedtls_x509_crl_init( crl->next ); + crl = crl->next; + } + + /* + * Copy raw DER-encoded CRL + */ + if( ( p = mbedtls_calloc( 1, buflen ) ) == NULL ) + return( MBEDTLS_ERR_X509_ALLOC_FAILED ); + + memcpy( p, buf, buflen ); + + crl->raw.p = p; + crl->raw.len = buflen; + + end = p + buflen; + + /* + * CertificateList ::= SEQUENCE { + * tbsCertList TBSCertList, + * signatureAlgorithm AlgorithmIdentifier, + * signatureValue BIT STRING } + */ + if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) + { + mbedtls_x509_crl_free( crl ); + return( MBEDTLS_ERR_X509_INVALID_FORMAT ); + } + + if( len != (size_t) ( end - p ) ) + { + mbedtls_x509_crl_free( crl ); + return( MBEDTLS_ERR_X509_INVALID_FORMAT + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + } + + /* + * TBSCertList ::= SEQUENCE { + */ + crl->tbs.p = p; + + if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) + { + mbedtls_x509_crl_free( crl ); + return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); + } + + end = p + len; + crl->tbs.len = end - crl->tbs.p; + + /* + * Version ::= INTEGER OPTIONAL { v1(0), v2(1) } + * -- if present, MUST be v2 + * + * signature AlgorithmIdentifier + */ + if( ( ret = x509_crl_get_version( &p, end, &crl->version ) ) != 0 || + ( ret = mbedtls_x509_get_alg( &p, end, &crl->sig_oid, &sig_params1 ) ) != 0 ) + { + mbedtls_x509_crl_free( crl ); + return( ret ); + } + + crl->version++; + + if( crl->version > 2 ) + { + mbedtls_x509_crl_free( crl ); + return( MBEDTLS_ERR_X509_UNKNOWN_VERSION ); + } + + if( ( ret = mbedtls_x509_get_sig_alg( &crl->sig_oid, &sig_params1, + &crl->sig_md, &crl->sig_pk, + &crl->sig_opts ) ) != 0 ) + { + mbedtls_x509_crl_free( crl ); + return( MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG ); + } + + /* + * issuer Name + */ + crl->issuer_raw.p = p; + + if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) + { + mbedtls_x509_crl_free( crl ); + return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); + } + + if( ( ret = mbedtls_x509_get_name( &p, p + len, &crl->issuer ) ) != 0 ) + { + mbedtls_x509_crl_free( crl ); + return( ret ); + } + + crl->issuer_raw.len = p - crl->issuer_raw.p; + + /* + * thisUpdate Time + * nextUpdate Time OPTIONAL + */ + if( ( ret = mbedtls_x509_get_time( &p, end, &crl->this_update ) ) != 0 ) + { + mbedtls_x509_crl_free( crl ); + return( ret ); + } + + if( ( ret = mbedtls_x509_get_time( &p, end, &crl->next_update ) ) != 0 ) + { + if( ret != ( MBEDTLS_ERR_X509_INVALID_DATE + + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) && + ret != ( MBEDTLS_ERR_X509_INVALID_DATE + + MBEDTLS_ERR_ASN1_OUT_OF_DATA ) ) + { + mbedtls_x509_crl_free( crl ); + return( ret ); + } + } + + /* + * revokedCertificates SEQUENCE OF SEQUENCE { + * userCertificate CertificateSerialNumber, + * revocationDate Time, + * crlEntryExtensions Extensions OPTIONAL + * -- if present, MUST be v2 + * } OPTIONAL + */ + if( ( ret = x509_get_entries( &p, end, &crl->entry ) ) != 0 ) + { + mbedtls_x509_crl_free( crl ); + return( ret ); + } + + /* + * crlExtensions EXPLICIT Extensions OPTIONAL + * -- if present, MUST be v2 + */ + if( crl->version == 2 ) + { + ret = x509_get_crl_ext( &p, end, &crl->crl_ext ); + + if( ret != 0 ) + { + mbedtls_x509_crl_free( crl ); + return( ret ); + } + } + + if( p != end ) + { + mbedtls_x509_crl_free( crl ); + return( MBEDTLS_ERR_X509_INVALID_FORMAT + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + } + + end = crl->raw.p + crl->raw.len; + + /* + * signatureAlgorithm AlgorithmIdentifier, + * signatureValue BIT STRING + */ + if( ( ret = mbedtls_x509_get_alg( &p, end, &sig_oid2, &sig_params2 ) ) != 0 ) + { + mbedtls_x509_crl_free( crl ); + return( ret ); + } + + if( crl->sig_oid.len != sig_oid2.len || + memcmp( crl->sig_oid.p, sig_oid2.p, crl->sig_oid.len ) != 0 || + sig_params1.len != sig_params2.len || + ( sig_params1.len != 0 && + memcmp( sig_params1.p, sig_params2.p, sig_params1.len ) != 0 ) ) + { + mbedtls_x509_crl_free( crl ); + return( MBEDTLS_ERR_X509_SIG_MISMATCH ); + } + + if( ( ret = mbedtls_x509_get_sig( &p, end, &crl->sig ) ) != 0 ) + { + mbedtls_x509_crl_free( crl ); + return( ret ); + } + + if( p != end ) + { + mbedtls_x509_crl_free( crl ); + return( MBEDTLS_ERR_X509_INVALID_FORMAT + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + } + + return( 0 ); +} + +/* + * Parse one or more CRLs and add them to the chained list + */ +int mbedtls_x509_crl_parse( mbedtls_x509_crl *chain, const unsigned char *buf, size_t buflen ) +{ +#if defined(MBEDTLS_PEM_PARSE_C) + int ret; + size_t use_len; + mbedtls_pem_context pem; + int is_pem = 0; + + if( chain == NULL || buf == NULL ) + return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); + + do + { + mbedtls_pem_init( &pem ); + + // Avoid calling mbedtls_pem_read_buffer() on non-null-terminated + // string + if( buflen == 0 || buf[buflen - 1] != '\0' ) + ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; + else + ret = mbedtls_pem_read_buffer( &pem, + "-----BEGIN X509 CRL-----", + "-----END X509 CRL-----", + buf, NULL, 0, &use_len ); + + if( ret == 0 ) + { + /* + * Was PEM encoded + */ + is_pem = 1; + + buflen -= use_len; + buf += use_len; + + if( ( ret = mbedtls_x509_crl_parse_der( chain, + pem.buf, pem.buflen ) ) != 0 ) + { + mbedtls_pem_free( &pem ); + return( ret ); + } + } + else if( is_pem ) + { + mbedtls_pem_free( &pem ); + return( ret ); + } + + mbedtls_pem_free( &pem ); + } + /* In the PEM case, buflen is 1 at the end, for the terminated NULL byte. + * And a valid CRL cannot be less than 1 byte anyway. */ + while( is_pem && buflen > 1 ); + + if( is_pem ) + return( 0 ); + else +#endif /* MBEDTLS_PEM_PARSE_C */ + return( mbedtls_x509_crl_parse_der( chain, buf, buflen ) ); +} + +#if defined(MBEDTLS_FS_IO) +/* + * Load one or more CRLs and add them to the chained list + */ +int mbedtls_x509_crl_parse_file( mbedtls_x509_crl *chain, const char *path ) +{ + int ret; + size_t n; + unsigned char *buf; + + if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 ) + return( ret ); + + ret = mbedtls_x509_crl_parse( chain, buf, n ); + + mbedtls_zeroize( buf, n ); + mbedtls_free( buf ); + + return( ret ); +} +#endif /* MBEDTLS_FS_IO */ + +/* + * Return an informational string about the certificate. + */ +#define BEFORE_COLON 14 +#define BC "14" +/* + * Return an informational string about the CRL. + */ +int mbedtls_x509_crl_info( char *buf, size_t size, const char *prefix, + const mbedtls_x509_crl *crl ) +{ + int ret; + size_t n; + char *p; + const mbedtls_x509_crl_entry *entry; + + p = buf; + n = size; + + ret = mbedtls_snprintf( p, n, "%sCRL version : %d", + prefix, crl->version ); + MBEDTLS_X509_SAFE_SNPRINTF; + + ret = mbedtls_snprintf( p, n, "\n%sissuer name : ", prefix ); + MBEDTLS_X509_SAFE_SNPRINTF; + ret = mbedtls_x509_dn_gets( p, n, &crl->issuer ); + MBEDTLS_X509_SAFE_SNPRINTF; + + ret = mbedtls_snprintf( p, n, "\n%sthis update : " \ + "%04d-%02d-%02d %02d:%02d:%02d", prefix, + crl->this_update.year, crl->this_update.mon, + crl->this_update.day, crl->this_update.hour, + crl->this_update.min, crl->this_update.sec ); + MBEDTLS_X509_SAFE_SNPRINTF; + + ret = mbedtls_snprintf( p, n, "\n%snext update : " \ + "%04d-%02d-%02d %02d:%02d:%02d", prefix, + crl->next_update.year, crl->next_update.mon, + crl->next_update.day, crl->next_update.hour, + crl->next_update.min, crl->next_update.sec ); + MBEDTLS_X509_SAFE_SNPRINTF; + + entry = &crl->entry; + + ret = mbedtls_snprintf( p, n, "\n%sRevoked certificates:", + prefix ); + MBEDTLS_X509_SAFE_SNPRINTF; + + while( entry != NULL && entry->raw.len != 0 ) + { + ret = mbedtls_snprintf( p, n, "\n%sserial number: ", + prefix ); + MBEDTLS_X509_SAFE_SNPRINTF; + + ret = mbedtls_x509_serial_gets( p, n, &entry->serial ); + MBEDTLS_X509_SAFE_SNPRINTF; + + ret = mbedtls_snprintf( p, n, " revocation date: " \ + "%04d-%02d-%02d %02d:%02d:%02d", + entry->revocation_date.year, entry->revocation_date.mon, + entry->revocation_date.day, entry->revocation_date.hour, + entry->revocation_date.min, entry->revocation_date.sec ); + MBEDTLS_X509_SAFE_SNPRINTF; + + entry = entry->next; + } + +#if !defined(MBEDTLS_IOT_SPECIFIC) + ret = mbedtls_snprintf( p, n, "\n%ssigned using : ", prefix ); + MBEDTLS_X509_SAFE_SNPRINTF; + + ret = mbedtls_x509_sig_alg_gets( p, n, &crl->sig_oid, crl->sig_pk, crl->sig_md, + crl->sig_opts ); + MBEDTLS_X509_SAFE_SNPRINTF; + + ret = mbedtls_snprintf( p, n, "\n" ); + MBEDTLS_X509_SAFE_SNPRINTF; +#endif /* MBEDTLS_IOT_SPECIFIC */ + + return( (int) ( size - n ) ); +} + +/* + * Initialize a CRL chain + */ +void mbedtls_x509_crl_init( mbedtls_x509_crl *crl ) +{ + memset( crl, 0, sizeof(mbedtls_x509_crl) ); +} + +/* + * Unallocate all CRL data + */ +void mbedtls_x509_crl_free( mbedtls_x509_crl *crl ) +{ + mbedtls_x509_crl *crl_cur = crl; + mbedtls_x509_crl *crl_prv; + mbedtls_x509_name *name_cur; + mbedtls_x509_name *name_prv; + mbedtls_x509_crl_entry *entry_cur; + mbedtls_x509_crl_entry *entry_prv; + + if( crl == NULL ) + return; + + do + { +#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) + mbedtls_free( crl_cur->sig_opts ); +#endif + + name_cur = crl_cur->issuer.next; + while( name_cur != NULL ) + { + name_prv = name_cur; + name_cur = name_cur->next; + mbedtls_zeroize( name_prv, sizeof( mbedtls_x509_name ) ); + mbedtls_free( name_prv ); + } + + entry_cur = crl_cur->entry.next; + while( entry_cur != NULL ) + { + entry_prv = entry_cur; + entry_cur = entry_cur->next; + mbedtls_zeroize( entry_prv, sizeof( mbedtls_x509_crl_entry ) ); + mbedtls_free( entry_prv ); + } + + if( crl_cur->raw.p != NULL ) + { + mbedtls_zeroize( crl_cur->raw.p, crl_cur->raw.len ); + mbedtls_free( crl_cur->raw.p ); + } + + crl_cur = crl_cur->next; + } + while( crl_cur != NULL ); + + crl_cur = crl; + do + { + crl_prv = crl_cur; + crl_cur = crl_cur->next; + + mbedtls_zeroize( crl_prv, sizeof( mbedtls_x509_crl ) ); + if( crl_prv != crl ) + mbedtls_free( crl_prv ); + } + while( crl_cur != NULL ); +} + +#endif /* MBEDTLS_X509_CRL_PARSE_C */ diff --git a/security/mbedtls/src/x509_crt.c b/security/mbedtls/src/x509_crt.c new file mode 100644 index 0000000000..06f1ffe774 --- /dev/null +++ b/security/mbedtls/src/x509_crt.c @@ -0,0 +1,2482 @@ +/* + * X.509 certificate parsing and verification + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +/* + * The ITU-T X.509 standard defines a certificate format for PKI. + * + * http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs) + * http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs) + * http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10) + * + * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf + * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_X509_CRT_PARSE_C) + +#include "mbedtls/x509_crt.h" +#include "mbedtls/oid.h" + +#include +#include + +#if defined(MBEDTLS_PEM_PARSE_C) +#include "mbedtls/pem.h" +#endif + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_free free +#define mbedtls_calloc calloc +#define mbedtls_snprintf snprintf +#define mbedtls_printf(_f, _a ...) \ + printf("%s %d: "_f, __FUNCTION__, __LINE__, ##_a) +#endif + +#if defined(MBEDTLS_THREADING_C) +#include "mbedtls/threading.h" +#endif + +#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) +#include +#else +#include +#endif + +#if defined(MBEDTLS_FS_IO) +#include +#if !defined(_WIN32) || defined(EFIX64) || defined(EFI32) +#include +#include +#include +#endif /* !_WIN32 || EFIX64 || EFI32 */ +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +/* + * Default profile + */ +const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_default = +{ +#if defined(MBEDTLS_IOT_SPECIFIC) +#if defined(MBEDTLS_MD5_C) + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_MD5 ) | +#endif /* MBEDTLS_MD5_C */ +#if defined(MBEDTLS_SHA1_C) + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA1 ) | +#endif /* MBEDTLS_SHA1_C */ + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ), + MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_RSA ), + 0, + 2048, +#else + /* Hashes from SHA-1 and above */ + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_MD5 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA1 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA224 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ), + 0xFFFFFFF, /* Any PK alg */ + 0xFFFFFFF, /* Any curve */ + 2048, +#endif +}; + +/* + * Next-default profile + */ +const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_next = +{ + /* Hashes from SHA-256 and above */ + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA512 ), + 0xFFFFFFF, /* Any PK alg */ +#if defined(MBEDTLS_ECP_C) + /* Curves at or above 128-bit security level */ + MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256R1 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP521R1 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_BP256R1 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_BP384R1 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_BP512R1 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256K1 ), +#else + 0, +#endif + 2048, +}; + +/* + * NSA Suite B Profile + */ +const mbedtls_x509_crt_profile mbedtls_x509_crt_profile_suiteb = +{ + /* Only SHA-256 and 384 */ + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA384 ), + /* Only ECDSA */ + MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECDSA ), +#if defined(MBEDTLS_ECP_C) + /* Only NIST P-256 and P-384 */ + MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256R1 ) | + MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP384R1 ), +#else + 0, +#endif + 0, +}; + +/* + * Check md_alg against profile + * Return 0 if md_alg acceptable for this profile, -1 otherwise + */ +static int x509_profile_check_md_alg( const mbedtls_x509_crt_profile *profile, + mbedtls_md_type_t md_alg ) +{ + if( ( profile->allowed_mds & MBEDTLS_X509_ID_FLAG( md_alg ) ) != 0 ) + return( 0 ); + + return( -1 ); +} + +/* + * Check pk_alg against profile + * Return 0 if pk_alg acceptable for this profile, -1 otherwise + */ +static int x509_profile_check_pk_alg( const mbedtls_x509_crt_profile *profile, + mbedtls_pk_type_t pk_alg ) +{ + if( ( profile->allowed_pks & MBEDTLS_X509_ID_FLAG( pk_alg ) ) != 0 ) + return( 0 ); + + return( -1 ); +} + +/* + * Check key against profile + * Return 0 if pk_alg acceptable for this profile, -1 otherwise + */ +static int x509_profile_check_key( const mbedtls_x509_crt_profile *profile, + mbedtls_pk_type_t pk_alg, + const mbedtls_pk_context *pk ) +{ +#if defined(MBEDTLS_RSA_C) + if( pk_alg == MBEDTLS_PK_RSA || pk_alg == MBEDTLS_PK_RSASSA_PSS ) + { + if( mbedtls_pk_get_bitlen( pk ) >= profile->rsa_min_bitlen ) + return( 0 ); + + return( -1 ); + } +#endif + +#if defined(MBEDTLS_ECP_C) + if( pk_alg == MBEDTLS_PK_ECDSA || + pk_alg == MBEDTLS_PK_ECKEY || + pk_alg == MBEDTLS_PK_ECKEY_DH ) + { + mbedtls_ecp_group_id gid = mbedtls_pk_ec( *pk )->grp.id; + + if( ( profile->allowed_curves & MBEDTLS_X509_ID_FLAG( gid ) ) != 0 ) + return( 0 ); + + return( -1 ); + } +#endif + + return( -1 ); +} + +#if defined(MBEDTLS_IOT_SPECIFIC) +static int x509_skip_parse( unsigned char **p, + const unsigned char *end, + int tag ) +{ + int ret; + size_t len; + + if( ( ret = mbedtls_asn1_get_tag( p, end, &len, tag ) ) != 0 ) + { + if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) + { + return( 0 ); + } + + return( ret ); + } + + *p += len; + + return( 0 ); +} +#endif + +/* + * Version ::= INTEGER { v1(0), v2(1), v3(2) } + */ +static int x509_get_version( unsigned char **p, + const unsigned char *end, + int *ver ) +{ + int ret; + size_t len; + + if( ( ret = mbedtls_asn1_get_tag( p, end, &len, + MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) ) != 0 ) + { + if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) + { + *ver = 0; + return( 0 ); + } + + return( ret ); + } + + end = *p + len; + + if( ( ret = mbedtls_asn1_get_int( p, end, ver ) ) != 0 ) + return( MBEDTLS_ERR_X509_INVALID_VERSION + ret ); + + if( *p != end ) + return( MBEDTLS_ERR_X509_INVALID_VERSION + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + + return( 0 ); +} + +#if defined(MBEDTLS_HAVE_TIME_DATE) +/* + * Validity ::= SEQUENCE { + * notBefore Time, + * notAfter Time } + */ +static int x509_get_dates( unsigned char **p, + const unsigned char *end, + mbedtls_x509_time *from, + mbedtls_x509_time *to ) +{ + int ret; + size_t len; + + if( ( ret = mbedtls_asn1_get_tag( p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) + return( MBEDTLS_ERR_X509_INVALID_DATE + ret ); + + end = *p + len; + + if( ( ret = mbedtls_x509_get_time( p, end, from ) ) != 0 ) + return( ret ); + + if( ( ret = mbedtls_x509_get_time( p, end, to ) ) != 0 ) + return( ret ); + + if( *p != end ) + return( MBEDTLS_ERR_X509_INVALID_DATE + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + + return( 0 ); +} +#endif /* MBEDTLS_HAVE_TIME_DATE */ + +#if !defined(MBEDTLS_IOT_SPECIFIC) +/* + * X.509 v2/v3 unique identifier (not parsed) + */ +static int x509_get_uid( unsigned char **p, + const unsigned char *end, + mbedtls_x509_buf *uid, int n ) +{ + int ret; + + if( *p == end ) + return( 0 ); + + uid->tag = **p; + + if( ( ret = mbedtls_asn1_get_tag( p, end, &uid->len, + MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | n ) ) != 0 ) + { + if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) + return( 0 ); + + return( ret ); + } + + uid->p = *p; + *p += uid->len; + + return( 0 ); +} + +static int x509_get_basic_constraints( unsigned char **p, + const unsigned char *end, + int *ca_istrue, + int *max_pathlen ) +{ + int ret; + size_t len; + + /* + * BasicConstraints ::= SEQUENCE { + * cA BOOLEAN DEFAULT FALSE, + * pathLenConstraint INTEGER (0..MAX) OPTIONAL } + */ + *ca_istrue = 0; /* DEFAULT FALSE */ + *max_pathlen = 0; /* endless */ + + if( ( ret = mbedtls_asn1_get_tag( p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); + + if( *p == end ) + return( 0 ); + + if( ( ret = mbedtls_asn1_get_bool( p, end, ca_istrue ) ) != 0 ) + { + if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) + ret = mbedtls_asn1_get_int( p, end, ca_istrue ); + + if( ret != 0 ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); + + if( *ca_istrue != 0 ) + *ca_istrue = 1; + } + + if( *p == end ) + return( 0 ); + + if( ( ret = mbedtls_asn1_get_int( p, end, max_pathlen ) ) != 0 ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); + + if( *p != end ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + + (*max_pathlen)++; + + return( 0 ); +} + +static int x509_get_ns_cert_type( unsigned char **p, + const unsigned char *end, + unsigned char *ns_cert_type) +{ + int ret; + mbedtls_x509_bitstring bs = { 0, 0, NULL }; + + if( ( ret = mbedtls_asn1_get_bitstring( p, end, &bs ) ) != 0 ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); + + if( bs.len != 1 ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + + MBEDTLS_ERR_ASN1_INVALID_LENGTH ); + + /* Get actual bitstring */ + *ns_cert_type = *bs.p; + return( 0 ); +} + +static int x509_get_key_usage( unsigned char **p, + const unsigned char *end, + unsigned int *key_usage) +{ + int ret; + size_t i; + mbedtls_x509_bitstring bs = { 0, 0, NULL }; + + if( ( ret = mbedtls_asn1_get_bitstring( p, end, &bs ) ) != 0 ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); + + if( bs.len < 1 ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + + MBEDTLS_ERR_ASN1_INVALID_LENGTH ); + + /* Get actual bitstring */ + *key_usage = 0; + for( i = 0; i < bs.len && i < sizeof( unsigned int ); i++ ) + { + *key_usage |= (unsigned int) bs.p[i] << (8*i); + } + + return( 0 ); +} + +/* + * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId + * + * KeyPurposeId ::= OBJECT IDENTIFIER + */ +static int x509_get_ext_key_usage( unsigned char **p, + const unsigned char *end, + mbedtls_x509_sequence *ext_key_usage) +{ + int ret; + + if( ( ret = mbedtls_asn1_get_sequence_of( p, end, ext_key_usage, MBEDTLS_ASN1_OID ) ) != 0 ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); + + /* Sequence length must be >= 1 */ + if( ext_key_usage->buf.p == NULL ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + + MBEDTLS_ERR_ASN1_INVALID_LENGTH ); + + return( 0 ); +} + +/* + * SubjectAltName ::= GeneralNames + * + * GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName + * + * GeneralName ::= CHOICE { + * otherName [0] OtherName, + * rfc822Name [1] IA5String, + * dNSName [2] IA5String, + * x400Address [3] ORAddress, + * directoryName [4] Name, + * ediPartyName [5] EDIPartyName, + * uniformResourceIdentifier [6] IA5String, + * iPAddress [7] OCTET STRING, + * registeredID [8] OBJECT IDENTIFIER } + * + * OtherName ::= SEQUENCE { + * type-id OBJECT IDENTIFIER, + * value [0] EXPLICIT ANY DEFINED BY type-id } + * + * EDIPartyName ::= SEQUENCE { + * nameAssigner [0] DirectoryString OPTIONAL, + * partyName [1] DirectoryString } + * + * NOTE: we only parse and use dNSName at this point. + */ +static int x509_get_subject_alt_name( unsigned char **p, + const unsigned char *end, + mbedtls_x509_sequence *subject_alt_name ) +{ + int ret; + size_t len, tag_len; + mbedtls_asn1_buf *buf; + unsigned char tag; + mbedtls_asn1_sequence *cur = subject_alt_name; + + /* Get main sequence tag */ + if( ( ret = mbedtls_asn1_get_tag( p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); + + if( *p + len != end ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + + while( *p < end ) + { + if( ( end - *p ) < 1 ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + + MBEDTLS_ERR_ASN1_OUT_OF_DATA ); + + tag = **p; + (*p)++; + if( ( ret = mbedtls_asn1_get_len( p, end, &tag_len ) ) != 0 ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); + + if( ( tag & MBEDTLS_ASN1_CONTEXT_SPECIFIC ) != MBEDTLS_ASN1_CONTEXT_SPECIFIC ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); + + /* Skip everything but DNS name */ + if( tag != ( MBEDTLS_ASN1_CONTEXT_SPECIFIC | 2 ) ) + { + *p += tag_len; + continue; + } + + /* Allocate and assign next pointer */ + if( cur->buf.p != NULL ) + { + if( cur->next != NULL ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS ); + + cur->next = mbedtls_calloc( 1, sizeof( mbedtls_asn1_sequence ) ); + + if( cur->next == NULL ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + + MBEDTLS_ERR_ASN1_ALLOC_FAILED ); + + cur = cur->next; + } + + buf = &(cur->buf); + buf->tag = tag; + buf->p = *p; + buf->len = tag_len; + *p += buf->len; + } + + /* Set final sequence entry's next pointer to NULL */ + cur->next = NULL; + + if( *p != end ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + + return( 0 ); +} +#endif /* MBEDTLS_IOT_SPECIFIC */ + +/* + * X.509 v3 extensions + * + */ +static int x509_get_crt_ext( unsigned char **p, + const unsigned char *end, + mbedtls_x509_crt *crt ) +{ + int ret; +#if !defined(MBEDTLS_IOT_SPECIFIC) + size_t len; + unsigned char *end_ext_data, *end_ext_octet; +#endif + + if( ( ret = mbedtls_x509_get_ext( p, end, &crt->v3_ext, 3 ) ) != 0 ) + { + if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) + return( 0 ); + + return( ret ); + } + +#if defined(MBEDTLS_IOT_SPECIFIC) + *p += crt->v3_ext.len; + + crt->ca_istrue = 1; +#else + while( *p < end ) + { + /* + * Extension ::= SEQUENCE { + * extnID OBJECT IDENTIFIER, + * critical BOOLEAN DEFAULT FALSE, + * extnValue OCTET STRING } + */ + mbedtls_x509_buf extn_oid = {0, 0, NULL}; + int is_critical = 0; /* DEFAULT FALSE */ + int ext_type = 0; + + if( ( ret = mbedtls_asn1_get_tag( p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); + + end_ext_data = *p + len; + + /* Get extension ID */ + extn_oid.tag = **p; + + if( ( ret = mbedtls_asn1_get_tag( p, end, &extn_oid.len, MBEDTLS_ASN1_OID ) ) != 0 ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); + + extn_oid.p = *p; + *p += extn_oid.len; + + if( ( end - *p ) < 1 ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + + MBEDTLS_ERR_ASN1_OUT_OF_DATA ); + + /* Get optional critical */ + if( ( ret = mbedtls_asn1_get_bool( p, end_ext_data, &is_critical ) ) != 0 && + ( ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); + + /* Data should be octet string type */ + if( ( ret = mbedtls_asn1_get_tag( p, end_ext_data, &len, + MBEDTLS_ASN1_OCTET_STRING ) ) != 0 ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + ret ); + + end_ext_octet = *p + len; + + if( end_ext_octet != end_ext_data ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + + /* + * Detect supported extensions + */ + ret = mbedtls_oid_get_x509_ext_type( &extn_oid, &ext_type ); + + if( ret != 0 ) + { + /* No parser found, skip extension */ + *p = end_ext_octet; + +#if !defined(MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION) + if( is_critical ) + { + /* Data is marked as critical: fail */ + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + + MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ); + } +#endif + continue; + } + + /* Forbid repeated extensions */ + if( ( crt->ext_types & ext_type ) != 0 ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS ); + + crt->ext_types |= ext_type; + + switch( ext_type ) + { + case MBEDTLS_X509_EXT_BASIC_CONSTRAINTS: + /* Parse basic constraints */ + if( ( ret = x509_get_basic_constraints( p, end_ext_octet, + &crt->ca_istrue, &crt->max_pathlen ) ) != 0 ) + return( ret ); + break; + + case MBEDTLS_X509_EXT_KEY_USAGE: + /* Parse key usage */ + if( ( ret = x509_get_key_usage( p, end_ext_octet, + &crt->key_usage ) ) != 0 ) + return( ret ); + break; + + case MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE: + /* Parse extended key usage */ + if( ( ret = x509_get_ext_key_usage( p, end_ext_octet, + &crt->ext_key_usage ) ) != 0 ) + return( ret ); + break; + + case MBEDTLS_X509_EXT_SUBJECT_ALT_NAME: + /* Parse subject alt name */ + if( ( ret = x509_get_subject_alt_name( p, end_ext_octet, + &crt->subject_alt_names ) ) != 0 ) + return( ret ); + break; + + case MBEDTLS_X509_EXT_NS_CERT_TYPE: + /* Parse netscape certificate type */ + if( ( ret = x509_get_ns_cert_type( p, end_ext_octet, + &crt->ns_cert_type ) ) != 0 ) + return( ret ); + break; + + default: + return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE ); + } + } +#endif /* MBEDTLS_IOT_SPECIFIC */ + + if( *p != end ) + return( MBEDTLS_ERR_X509_INVALID_EXTENSIONS + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + + return( 0 ); +} + +/* + * Parse and fill a single X.509 certificate in DER format + */ +static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, const unsigned char *buf, + size_t buflen ) +{ + int ret; + size_t len; + unsigned char *p, *end, *crt_end; + mbedtls_x509_buf sig_params1, sig_params2, sig_oid2; + + memset( &sig_params1, 0, sizeof( mbedtls_x509_buf ) ); + memset( &sig_params2, 0, sizeof( mbedtls_x509_buf ) ); + memset( &sig_oid2, 0, sizeof( mbedtls_x509_buf ) ); + + /* + * Check for valid input + */ + if( crt == NULL || buf == NULL ) + return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); + + // Use the original buffer until we figure out actual length + p = (unsigned char*) buf; + len = buflen; + end = p + len; + + /* + * Certificate ::= SEQUENCE { + * tbsCertificate TBSCertificate, + * signatureAlgorithm AlgorithmIdentifier, + * signatureValue BIT STRING } + */ + if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) + { + mbedtls_x509_crt_free( crt ); + return( MBEDTLS_ERR_X509_INVALID_FORMAT ); + } + + if( len > (size_t) ( end - p ) ) + { + mbedtls_x509_crt_free( crt ); + return( MBEDTLS_ERR_X509_INVALID_FORMAT + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + } + crt_end = p + len; + + // Create and populate a new buffer for the raw field + crt->raw.len = crt_end - buf; + crt->raw.p = p = mbedtls_calloc( 1, crt->raw.len ); + if( p == NULL ) + return( MBEDTLS_ERR_X509_ALLOC_FAILED ); + + memcpy( p, buf, crt->raw.len ); + + // Direct pointers to the new buffer + p += crt->raw.len - len; + end = crt_end = p + len; + + /* + * TBSCertificate ::= SEQUENCE { + */ + crt->tbs.p = p; + + if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) + { + mbedtls_x509_crt_free( crt ); + return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); + } + + end = p + len; + crt->tbs.len = end - crt->tbs.p; + + /* + * Version ::= INTEGER { v1(0), v2(1), v3(2) } + * + * CertificateSerialNumber ::= INTEGER + * + * signature AlgorithmIdentifier + */ + if( ( ret = x509_get_version( &p, end, &crt->version ) ) != 0 || + ( ret = mbedtls_x509_get_serial( &p, end, &crt->serial ) ) != 0 || + ( ret = mbedtls_x509_get_alg( &p, end, &crt->sig_oid, + &sig_params1 ) ) != 0 ) + { + mbedtls_x509_crt_free( crt ); + return( ret ); + } + + crt->version++; + + if( crt->version > 3 ) + { + mbedtls_x509_crt_free( crt ); + return( MBEDTLS_ERR_X509_UNKNOWN_VERSION ); + } + + if( ( ret = mbedtls_x509_get_sig_alg( &crt->sig_oid, &sig_params1, + &crt->sig_md, &crt->sig_pk, + &crt->sig_opts ) ) != 0 ) + { + mbedtls_x509_crt_free( crt ); + return( ret ); + } + + /* + * issuer Name + */ + crt->issuer_raw.p = p; + + if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) + { + mbedtls_x509_crt_free( crt ); + return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); + } + + if( ( ret = mbedtls_x509_get_name( &p, p + len, &crt->issuer ) ) != 0 ) + { + mbedtls_x509_crt_free( crt ); + return( ret ); + } + + crt->issuer_raw.len = p - crt->issuer_raw.p; + + /* + * Validity ::= SEQUENCE { + * notBefore Time, + * notAfter Time } + * + */ +#if defined(MBEDTLS_HAVE_TIME_DATE) + if( ( ret = x509_get_dates( &p, end, &crt->valid_from, + &crt->valid_to ) ) != 0 ) +#else + if( ( ret = x509_skip_parse( &p, end, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) +#endif + { + mbedtls_x509_crt_free( crt ); + return( ret ); + } + + /* + * subject Name + */ + crt->subject_raw.p = p; + + if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) + { + mbedtls_x509_crt_free( crt ); + return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); + } + + if( len && ( ret = mbedtls_x509_get_name( &p, p + len, &crt->subject ) ) != 0 ) + { + mbedtls_x509_crt_free( crt ); + return( ret ); + } + + crt->subject_raw.len = p - crt->subject_raw.p; + + /* + * SubjectPublicKeyInfo + */ + if( ( ret = mbedtls_pk_parse_subpubkey( &p, end, &crt->pk ) ) != 0 ) + { + mbedtls_x509_crt_free( crt ); + return( ret ); + } + + /* + * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, + * -- If present, version shall be v2 or v3 + * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, + * -- If present, version shall be v2 or v3 + * extensions [3] EXPLICIT Extensions OPTIONAL + * -- If present, version shall be v3 + */ + if( crt->version == 2 || crt->version == 3 ) + { +#if !defined(MBEDTLS_IOT_SPECIFIC) + ret = x509_get_uid( &p, end, &crt->issuer_id, 1 ); +#else + ret = x509_skip_parse( &p, end, + MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 1 ); +#endif + if( ret != 0 ) + { + mbedtls_x509_crt_free( crt ); + return( ret ); + } + } + + if( crt->version == 2 || crt->version == 3 ) + { +#if !defined(MBEDTLS_IOT_SPECIFIC) + ret = x509_get_uid( &p, end, &crt->subject_id, 2 ); +#else + ret = x509_skip_parse( &p, end, + MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 2 ); +#endif + if( ret != 0 ) + { + mbedtls_x509_crt_free( crt ); + return( ret ); + } + } + +#if !defined(MBEDTLS_X509_ALLOW_EXTENSIONS_NON_V3) + if( crt->version == 3 ) +#endif + { + ret = x509_get_crt_ext( &p, end, crt ); + + if( ret != 0 ) + { + mbedtls_x509_crt_free( crt ); + return( ret ); + } + } + + if( p != end ) + { + mbedtls_x509_crt_free( crt ); + return( MBEDTLS_ERR_X509_INVALID_FORMAT + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + } + + end = crt_end; + + /* + * } + * -- end of TBSCertificate + * + * signatureAlgorithm AlgorithmIdentifier, + * signatureValue BIT STRING + */ + if( ( ret = mbedtls_x509_get_alg( &p, end, &sig_oid2, &sig_params2 ) ) != 0 ) + { + mbedtls_x509_crt_free( crt ); + return( ret ); + } + + if( crt->sig_oid.len != sig_oid2.len || + memcmp( crt->sig_oid.p, sig_oid2.p, crt->sig_oid.len ) != 0 || + sig_params1.len != sig_params2.len || + ( sig_params1.len != 0 && + memcmp( sig_params1.p, sig_params2.p, sig_params1.len ) != 0 ) ) + { + mbedtls_x509_crt_free( crt ); + return( MBEDTLS_ERR_X509_SIG_MISMATCH ); + } + + if( ( ret = mbedtls_x509_get_sig( &p, end, &crt->sig ) ) != 0 ) + { + mbedtls_x509_crt_free( crt ); + return( ret ); + } + + if( p != end ) + { + mbedtls_x509_crt_free( crt ); + return( MBEDTLS_ERR_X509_INVALID_FORMAT + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + } + + return( 0 ); +} + +/* + * Parse one X.509 certificate in DER format from a buffer and add them to a + * chained list + */ +int mbedtls_x509_crt_parse_der( mbedtls_x509_crt *chain, const unsigned char *buf, + size_t buflen ) +{ + int ret; + mbedtls_x509_crt *crt = chain, *prev = NULL; + + /* + * Check for valid input + */ + if( crt == NULL || buf == NULL ) + return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); + + while( crt->version != 0 && crt->next != NULL ) + { + prev = crt; + crt = crt->next; + } + + /* + * Add new certificate on the end of the chain if needed. + */ + if( crt->version != 0 && crt->next == NULL ) + { + crt->next = mbedtls_calloc( 1, sizeof( mbedtls_x509_crt ) ); + + if( crt->next == NULL ) + return( MBEDTLS_ERR_X509_ALLOC_FAILED ); + + prev = crt; + mbedtls_x509_crt_init( crt->next ); + crt = crt->next; + } + + if( ( ret = x509_crt_parse_der_core( crt, buf, buflen ) ) != 0 ) + { + if( prev ) + prev->next = NULL; + + if( crt != chain ) + mbedtls_free( crt ); + + return( ret ); + } + + return( 0 ); +} + +/* + * Parse one or more PEM certificates from a buffer and add them to the chained + * list + */ +int mbedtls_x509_crt_parse( mbedtls_x509_crt *chain, const unsigned char *buf, size_t buflen ) +{ +#if defined(MBEDTLS_PEM_PARSE_C) + int success = 0, first_error = 0, total_failed = 0; + int buf_format = MBEDTLS_X509_FORMAT_DER; +#endif + + /* + * Check for valid input + */ + if( chain == NULL || buf == NULL ) + return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); + + /* + * Determine buffer content. Buffer contains either one DER certificate or + * one or more PEM certificates. + */ +#if defined(MBEDTLS_PEM_PARSE_C) + if( buflen != 0 && buf[buflen - 1] == '\0' && + strstr( (const char *) buf, "-----BEGIN CERTIFICATE-----" ) != NULL ) + { + buf_format = MBEDTLS_X509_FORMAT_PEM; + } + + if( buf_format == MBEDTLS_X509_FORMAT_DER ) + return mbedtls_x509_crt_parse_der( chain, buf, buflen ); +#else + return mbedtls_x509_crt_parse_der( chain, buf, buflen ); +#endif + +#if defined(MBEDTLS_PEM_PARSE_C) + if( buf_format == MBEDTLS_X509_FORMAT_PEM ) + { + int ret; + mbedtls_pem_context pem; + + /* 1 rather than 0 since the terminating NULL byte is counted in */ + while( buflen > 1 ) + { + size_t use_len; + mbedtls_pem_init( &pem ); + + /* If we get there, we know the string is null-terminated */ + ret = mbedtls_pem_read_buffer( &pem, + "-----BEGIN CERTIFICATE-----", + "-----END CERTIFICATE-----", + buf, NULL, 0, &use_len ); + + if( ret == 0 ) + { + /* + * Was PEM encoded + */ + buflen -= use_len; + buf += use_len; + } + else if( ret == MBEDTLS_ERR_PEM_BAD_INPUT_DATA ) + { + return( ret ); + } + else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) + { + mbedtls_pem_free( &pem ); + + /* + * PEM header and footer were found + */ + buflen -= use_len; + buf += use_len; + + if( first_error == 0 ) + first_error = ret; + + total_failed++; + continue; + } + else + break; + + ret = mbedtls_x509_crt_parse_der( chain, pem.buf, pem.buflen ); + + mbedtls_pem_free( &pem ); + + if( ret != 0 ) + { + /* + * Quit parsing on a memory error + */ + if( ret == MBEDTLS_ERR_X509_ALLOC_FAILED ) + return( ret ); + + if( first_error == 0 ) + first_error = ret; + + total_failed++; + continue; + } + + success = 1; + } + } + + if( success ) + return( total_failed ); + else if( first_error ) + return( first_error ); + else + return( MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT ); +#endif /* MBEDTLS_PEM_PARSE_C */ +} + +#if defined(MBEDTLS_FS_IO) +/* + * Load one or more certificates and add them to the chained list + */ +int mbedtls_x509_crt_parse_file( mbedtls_x509_crt *chain, const char *path ) +{ + int ret; + size_t n; + unsigned char *buf; + + if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 ) + return( ret ); + + ret = mbedtls_x509_crt_parse( chain, buf, n ); + + mbedtls_zeroize( buf, n ); + mbedtls_free( buf ); + + return( ret ); +} + +int mbedtls_x509_crt_parse_path( mbedtls_x509_crt *chain, const char *path ) +{ + int ret = 0; +#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32) + int w_ret; + WCHAR szDir[MAX_PATH]; + char filename[MAX_PATH]; + char *p; + size_t len = strlen( path ); + + WIN32_FIND_DATAW file_data; + HANDLE hFind; + + if( len > MAX_PATH - 3 ) + return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); + + memset( szDir, 0, sizeof(szDir) ); + memset( filename, 0, MAX_PATH ); + memcpy( filename, path, len ); + filename[len++] = '\\'; + p = filename + len; + filename[len++] = '*'; + + w_ret = MultiByteToWideChar( CP_ACP, 0, filename, (int)len, szDir, + MAX_PATH - 3 ); + if( w_ret == 0 ) + return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); + + hFind = FindFirstFileW( szDir, &file_data ); + if( hFind == INVALID_HANDLE_VALUE ) + return( MBEDTLS_ERR_X509_FILE_IO_ERROR ); + + len = MAX_PATH - len; + do + { + memset( p, 0, len ); + + if( file_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) + continue; + + w_ret = WideCharToMultiByte( CP_ACP, 0, file_data.cFileName, + lstrlenW( file_data.cFileName ), + p, (int) len - 1, + NULL, NULL ); + if( w_ret == 0 ) + return( MBEDTLS_ERR_X509_FILE_IO_ERROR ); + + w_ret = mbedtls_x509_crt_parse_file( chain, filename ); + if( w_ret < 0 ) + ret++; + else + ret += w_ret; + } + while( FindNextFileW( hFind, &file_data ) != 0 ); + + if( GetLastError() != ERROR_NO_MORE_FILES ) + ret = MBEDTLS_ERR_X509_FILE_IO_ERROR; + + FindClose( hFind ); +#else /* _WIN32 */ + int t_ret; + int snp_ret; + struct stat sb; + struct dirent *entry; + char entry_name[MBEDTLS_X509_MAX_FILE_PATH_LEN]; + DIR *dir = opendir( path ); + + if( dir == NULL ) + return( MBEDTLS_ERR_X509_FILE_IO_ERROR ); + +#if defined(MBEDTLS_THREADING_PTHREAD) + if( ( ret = mbedtls_mutex_lock( &mbedtls_threading_readdir_mutex ) ) != 0 ) + { + closedir( dir ); + return( ret ); + } +#endif + + while( ( entry = readdir( dir ) ) != NULL ) + { + snp_ret = mbedtls_snprintf( entry_name, sizeof entry_name, + "%s/%s", path, entry->d_name ); + + if( snp_ret < 0 || (size_t)snp_ret >= sizeof entry_name ) + { + ret = MBEDTLS_ERR_X509_BUFFER_TOO_SMALL; + goto cleanup; + } + else if( stat( entry_name, &sb ) == -1 ) + { + ret = MBEDTLS_ERR_X509_FILE_IO_ERROR; + goto cleanup; + } + + if( !S_ISREG( sb.st_mode ) ) + continue; + + // Ignore parse errors + // + t_ret = mbedtls_x509_crt_parse_file( chain, entry_name ); + if( t_ret < 0 ) + ret++; + else + ret += t_ret; + } + +cleanup: + closedir( dir ); + +#if defined(MBEDTLS_THREADING_PTHREAD) + if( mbedtls_mutex_unlock( &mbedtls_threading_readdir_mutex ) != 0 ) + ret = MBEDTLS_ERR_THREADING_MUTEX_ERROR; +#endif + +#endif /* _WIN32 */ + + return( ret ); +} +#endif /* MBEDTLS_FS_IO */ + +#if !defined(MBEDTLS_IOT_SPECIFIC) +static int x509_info_subject_alt_name( char **buf, size_t *size, + const mbedtls_x509_sequence *subject_alt_name ) +{ + size_t i; + size_t n = *size; + char *p = *buf; + const mbedtls_x509_sequence *cur = subject_alt_name; + const char *sep = ""; + size_t sep_len = 0; + + while( cur != NULL ) + { + if( cur->buf.len + sep_len >= n ) + { + *p = '\0'; + return( MBEDTLS_ERR_X509_BUFFER_TOO_SMALL ); + } + + n -= cur->buf.len + sep_len; + for( i = 0; i < sep_len; i++ ) + *p++ = sep[i]; + for( i = 0; i < cur->buf.len; i++ ) + *p++ = cur->buf.p[i]; + + sep = ", "; + sep_len = 2; + + cur = cur->next; + } + + *p = '\0'; + + *size = n; + *buf = p; + + return( 0 ); +} + +#define PRINT_ITEM(i) \ + { \ + ret = mbedtls_snprintf( p, n, "%s" i, sep ); \ + MBEDTLS_X509_SAFE_SNPRINTF; \ + sep = ", "; \ + } + +#define CERT_TYPE(type,name) \ + if( ns_cert_type & type ) \ + PRINT_ITEM( name ); + +static int x509_info_cert_type( char **buf, size_t *size, + unsigned char ns_cert_type ) +{ + int ret; + size_t n = *size; + char *p = *buf; + const char *sep = ""; + + CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT, "SSL Client" ); + CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_SSL_SERVER, "SSL Server" ); + CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_EMAIL, "Email" ); + CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING, "Object Signing" ); + CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_RESERVED, "Reserved" ); + CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_SSL_CA, "SSL CA" ); + CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_EMAIL_CA, "Email CA" ); + CERT_TYPE( MBEDTLS_X509_NS_CERT_TYPE_OBJECT_SIGNING_CA, "Object Signing CA" ); + + *size = n; + *buf = p; + + return( 0 ); +} + +#define KEY_USAGE(code,name) \ + if( key_usage & code ) \ + PRINT_ITEM( name ); + +static int x509_info_key_usage( char **buf, size_t *size, + unsigned int key_usage ) +{ + int ret; + size_t n = *size; + char *p = *buf; + const char *sep = ""; + + KEY_USAGE( MBEDTLS_X509_KU_DIGITAL_SIGNATURE, "Digital Signature" ); + KEY_USAGE( MBEDTLS_X509_KU_NON_REPUDIATION, "Non Repudiation" ); + KEY_USAGE( MBEDTLS_X509_KU_KEY_ENCIPHERMENT, "Key Encipherment" ); + KEY_USAGE( MBEDTLS_X509_KU_DATA_ENCIPHERMENT, "Data Encipherment" ); + KEY_USAGE( MBEDTLS_X509_KU_KEY_AGREEMENT, "Key Agreement" ); + KEY_USAGE( MBEDTLS_X509_KU_KEY_CERT_SIGN, "Key Cert Sign" ); + KEY_USAGE( MBEDTLS_X509_KU_CRL_SIGN, "CRL Sign" ); + KEY_USAGE( MBEDTLS_X509_KU_ENCIPHER_ONLY, "Encipher Only" ); + KEY_USAGE( MBEDTLS_X509_KU_DECIPHER_ONLY, "Decipher Only" ); + + *size = n; + *buf = p; + + return( 0 ); +} + +static int x509_info_ext_key_usage( char **buf, size_t *size, + const mbedtls_x509_sequence *extended_key_usage ) +{ + int ret; + const char *desc; + size_t n = *size; + char *p = *buf; + const mbedtls_x509_sequence *cur = extended_key_usage; + const char *sep = ""; + + while( cur != NULL ) + { + if( mbedtls_oid_get_extended_key_usage( &cur->buf, &desc ) != 0 ) + desc = "???"; + + ret = mbedtls_snprintf( p, n, "%s%s", sep, desc ); + MBEDTLS_X509_SAFE_SNPRINTF; + + sep = ", "; + + cur = cur->next; + } + + *size = n; + *buf = p; + + return( 0 ); +} +#endif /* MBEDTLS_IOT_SPECIFIC */ + +/* + * Return an informational string about the certificate. + */ +#define BEFORE_COLON 18 +#define BC "18" +int mbedtls_x509_crt_info( char *buf, size_t size, const char *prefix, + const mbedtls_x509_crt *crt ) +{ + int ret; + size_t n; + char *p; + char key_size_str[BEFORE_COLON]; + + p = buf; + n = size; + + if( NULL == crt ) + { + ret = mbedtls_snprintf( p, n, "\nCertificate is uninitialised!\n" ); + MBEDTLS_X509_SAFE_SNPRINTF; + + return( (int) ( size - n ) ); + } + + ret = mbedtls_snprintf( p, n, "%scert. version : %d\n", + prefix, crt->version ); + MBEDTLS_X509_SAFE_SNPRINTF; + ret = mbedtls_snprintf( p, n, "%sserial number : ", + prefix ); + MBEDTLS_X509_SAFE_SNPRINTF; + + ret = mbedtls_x509_serial_gets( p, n, &crt->serial ); + MBEDTLS_X509_SAFE_SNPRINTF; + +#if !defined(MBEDTLS_IOT_SPECIFIC) + ret = mbedtls_snprintf( p, n, "\n%sissuer name : ", prefix ); + MBEDTLS_X509_SAFE_SNPRINTF; + ret = mbedtls_x509_dn_gets( p, n, &crt->issuer ); + MBEDTLS_X509_SAFE_SNPRINTF; + + ret = mbedtls_snprintf( p, n, "\n%ssubject name : ", prefix ); + MBEDTLS_X509_SAFE_SNPRINTF; + ret = mbedtls_x509_dn_gets( p, n, &crt->subject ); + MBEDTLS_X509_SAFE_SNPRINTF; +#endif + + ret = mbedtls_snprintf( p, n, "\n%sissued on : " \ + "%04d-%02d-%02d %02d:%02d:%02d", prefix, + crt->valid_from.year, crt->valid_from.mon, + crt->valid_from.day, crt->valid_from.hour, + crt->valid_from.min, crt->valid_from.sec ); + MBEDTLS_X509_SAFE_SNPRINTF; + + ret = mbedtls_snprintf( p, n, "\n%sexpires on : " \ + "%04d-%02d-%02d %02d:%02d:%02d", prefix, + crt->valid_to.year, crt->valid_to.mon, + crt->valid_to.day, crt->valid_to.hour, + crt->valid_to.min, crt->valid_to.sec ); + MBEDTLS_X509_SAFE_SNPRINTF; + +#if !defined(MBEDTLS_IOT_SPECIFIC) + ret = mbedtls_snprintf( p, n, "\n%ssigned using : ", prefix ); + MBEDTLS_X509_SAFE_SNPRINTF; + + ret = mbedtls_x509_sig_alg_gets( p, n, &crt->sig_oid, crt->sig_pk, + crt->sig_md, crt->sig_opts ); + MBEDTLS_X509_SAFE_SNPRINTF; +#endif /* MBEDTLS_IOT_SPECIFIC */ + + /* Key size */ + if( ( ret = mbedtls_x509_key_size_helper( key_size_str, BEFORE_COLON, + mbedtls_pk_get_name( &crt->pk ) ) ) != 0 ) + { + return( ret ); + } + + ret = mbedtls_snprintf( p, n, "\n%s%-" BC "s: %d bits", prefix, key_size_str, + (int) mbedtls_pk_get_bitlen( &crt->pk ) ); + MBEDTLS_X509_SAFE_SNPRINTF; + + /* + * Optional extensions + */ +#if !defined(MBEDTLS_IOT_SPECIFIC) + if( crt->ext_types & MBEDTLS_X509_EXT_BASIC_CONSTRAINTS ) + { + ret = mbedtls_snprintf( p, n, "\n%sbasic constraints : CA=%s", prefix, + crt->ca_istrue ? "true" : "false" ); + MBEDTLS_X509_SAFE_SNPRINTF; + + if( crt->max_pathlen > 0 ) + { + ret = mbedtls_snprintf( p, n, ", max_pathlen=%d", crt->max_pathlen - 1 ); + MBEDTLS_X509_SAFE_SNPRINTF; + } + } + + if( crt->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME ) + { + ret = mbedtls_snprintf( p, n, "\n%ssubject alt name : ", prefix ); + MBEDTLS_X509_SAFE_SNPRINTF; + + if( ( ret = x509_info_subject_alt_name( &p, &n, + &crt->subject_alt_names ) ) != 0 ) + return( ret ); + } + + if( crt->ext_types & MBEDTLS_X509_EXT_NS_CERT_TYPE ) + { + ret = mbedtls_snprintf( p, n, "\n%scert. type : ", prefix ); + MBEDTLS_X509_SAFE_SNPRINTF; + + if( ( ret = x509_info_cert_type( &p, &n, crt->ns_cert_type ) ) != 0 ) + return( ret ); + } + + if( crt->ext_types & MBEDTLS_X509_EXT_KEY_USAGE ) + { + ret = mbedtls_snprintf( p, n, "\n%skey usage : ", prefix ); + MBEDTLS_X509_SAFE_SNPRINTF; + + if( ( ret = x509_info_key_usage( &p, &n, crt->key_usage ) ) != 0 ) + return( ret ); + } + + if( crt->ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE ) + { + ret = mbedtls_snprintf( p, n, "\n%sext key usage : ", prefix ); + MBEDTLS_X509_SAFE_SNPRINTF; + + if( ( ret = x509_info_ext_key_usage( &p, &n, + &crt->ext_key_usage ) ) != 0 ) + return( ret ); + } +#endif + + ret = mbedtls_snprintf( p, n, "\n" ); + MBEDTLS_X509_SAFE_SNPRINTF; + + return( (int) ( size - n ) ); +} + +struct x509_crt_verify_string { + int code; + const char *string; +}; + +static const struct x509_crt_verify_string x509_crt_verify_strings[] = { + { MBEDTLS_X509_BADCERT_EXPIRED, "The certificate validity has expired" }, + { MBEDTLS_X509_BADCERT_REVOKED, "The certificate has been revoked (is on a CRL)" }, + { MBEDTLS_X509_BADCERT_CN_MISMATCH, "The certificate Common Name (CN) does not match with the expected CN" }, + { MBEDTLS_X509_BADCERT_NOT_TRUSTED, "The certificate is not correctly signed by the trusted CA" }, + { MBEDTLS_X509_BADCRL_NOT_TRUSTED, "The CRL is not correctly signed by the trusted CA" }, + { MBEDTLS_X509_BADCRL_EXPIRED, "The CRL is expired" }, + { MBEDTLS_X509_BADCERT_MISSING, "Certificate was missing" }, + { MBEDTLS_X509_BADCERT_SKIP_VERIFY, "Certificate verification was skipped" }, + { MBEDTLS_X509_BADCERT_OTHER, "Other reason (can be used by verify callback)" }, + { MBEDTLS_X509_BADCERT_FUTURE, "The certificate validity starts in the future" }, + { MBEDTLS_X509_BADCRL_FUTURE, "The CRL is from the future" }, + { MBEDTLS_X509_BADCERT_KEY_USAGE, "Usage does not match the keyUsage extension" }, + { MBEDTLS_X509_BADCERT_EXT_KEY_USAGE, "Usage does not match the extendedKeyUsage extension" }, + { MBEDTLS_X509_BADCERT_NS_CERT_TYPE, "Usage does not match the nsCertType extension" }, + { MBEDTLS_X509_BADCERT_BAD_MD, "The certificate is signed with an unacceptable hash." }, + { MBEDTLS_X509_BADCERT_BAD_PK, "The certificate is signed with an unacceptable PK alg (eg RSA vs ECDSA)." }, + { MBEDTLS_X509_BADCERT_BAD_KEY, "The certificate is signed with an unacceptable key (eg bad curve, RSA too short)." }, + { MBEDTLS_X509_BADCRL_BAD_MD, "The CRL is signed with an unacceptable hash." }, + { MBEDTLS_X509_BADCRL_BAD_PK, "The CRL is signed with an unacceptable PK alg (eg RSA vs ECDSA)." }, + { MBEDTLS_X509_BADCRL_BAD_KEY, "The CRL is signed with an unacceptable key (eg bad curve, RSA too short)." }, + { 0, NULL } +}; + +int mbedtls_x509_crt_verify_info( char *buf, size_t size, const char *prefix, + uint32_t flags ) +{ + int ret; + const struct x509_crt_verify_string *cur; + char *p = buf; + size_t n = size; + + for( cur = x509_crt_verify_strings; cur->string != NULL ; cur++ ) + { + if( ( flags & cur->code ) == 0 ) + continue; + + ret = mbedtls_snprintf( p, n, "%s%s\n", prefix, cur->string ); + MBEDTLS_X509_SAFE_SNPRINTF; + flags ^= cur->code; + } + + if( flags != 0 ) + { + ret = mbedtls_snprintf( p, n, "%sUnknown reason " + "(this should not happen)\n", prefix ); + MBEDTLS_X509_SAFE_SNPRINTF; + } + + return( (int) ( size - n ) ); +} + +#if defined(MBEDTLS_X509_CHECK_KEY_USAGE) +int mbedtls_x509_crt_check_key_usage( const mbedtls_x509_crt *crt, + unsigned int usage ) +{ + unsigned int usage_must, usage_may; + unsigned int may_mask = MBEDTLS_X509_KU_ENCIPHER_ONLY + | MBEDTLS_X509_KU_DECIPHER_ONLY; + + if( ( crt->ext_types & MBEDTLS_X509_EXT_KEY_USAGE ) == 0 ) + return( 0 ); + + usage_must = usage & ~may_mask; + + if( ( ( crt->key_usage & ~may_mask ) & usage_must ) != usage_must ) + return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); + + usage_may = usage & may_mask; + + if( ( ( crt->key_usage & may_mask ) | usage_may ) != usage_may ) + return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); + + return( 0 ); +} +#endif + +#if defined(MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE) +int mbedtls_x509_crt_check_extended_key_usage( const mbedtls_x509_crt *crt, + const char *usage_oid, + size_t usage_len ) +{ + const mbedtls_x509_sequence *cur; + + /* Extension is not mandatory, absent means no restriction */ + if( ( crt->ext_types & MBEDTLS_X509_EXT_EXTENDED_KEY_USAGE ) == 0 ) + return( 0 ); + + /* + * Look for the requested usage (or wildcard ANY) in our list + */ + for( cur = &crt->ext_key_usage; cur != NULL; cur = cur->next ) + { + const mbedtls_x509_buf *cur_oid = &cur->buf; + + if( cur_oid->len == usage_len && + memcmp( cur_oid->p, usage_oid, usage_len ) == 0 ) + { + return( 0 ); + } + + if( MBEDTLS_OID_CMP( MBEDTLS_OID_ANY_EXTENDED_KEY_USAGE, cur_oid ) == 0 ) + return( 0 ); + } + + return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); +} +#endif /* MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE */ + +#if defined(MBEDTLS_X509_CRL_PARSE_C) +/* + * Return 1 if the certificate is revoked, or 0 otherwise. + */ +int mbedtls_x509_crt_is_revoked( const mbedtls_x509_crt *crt, const mbedtls_x509_crl *crl ) +{ + const mbedtls_x509_crl_entry *cur = &crl->entry; + + while( cur != NULL && cur->serial.len != 0 ) + { + if( crt->serial.len == cur->serial.len && + memcmp( crt->serial.p, cur->serial.p, crt->serial.len ) == 0 ) + { + if( mbedtls_x509_time_is_past( &cur->revocation_date ) ) + return( 1 ); + } + + cur = cur->next; + } + + return( 0 ); +} + +/* + * Check that the given certificate is not revoked according to the CRL. + * Skip validation is no CRL for the given CA is present. + */ +static int x509_crt_verifycrl( mbedtls_x509_crt *crt, mbedtls_x509_crt *ca, + mbedtls_x509_crl *crl_list, + const mbedtls_x509_crt_profile *profile ) +{ + int flags = 0; + unsigned char hash[MBEDTLS_MD_MAX_SIZE]; + const mbedtls_md_info_t *md_info; + + if( ca == NULL ) + return( flags ); + + while( crl_list != NULL ) + { + if( crl_list->version == 0 || + crl_list->issuer_raw.len != ca->subject_raw.len || + memcmp( crl_list->issuer_raw.p, ca->subject_raw.p, + crl_list->issuer_raw.len ) != 0 ) + { + crl_list = crl_list->next; + continue; + } + + /* + * Check if the CA is configured to sign CRLs + */ +#if defined(MBEDTLS_X509_CHECK_KEY_USAGE) + if( mbedtls_x509_crt_check_key_usage( ca, MBEDTLS_X509_KU_CRL_SIGN ) != 0 ) + { + flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED; + break; + } +#endif + + /* + * Check if CRL is correctly signed by the trusted CA + */ + if( x509_profile_check_md_alg( profile, crl_list->sig_md ) != 0 ) + flags |= MBEDTLS_X509_BADCRL_BAD_MD; + + if( x509_profile_check_pk_alg( profile, crl_list->sig_pk ) != 0 ) + flags |= MBEDTLS_X509_BADCRL_BAD_PK; + + md_info = mbedtls_md_info_from_type( crl_list->sig_md ); + if( md_info == NULL ) + { + /* + * Cannot check 'unknown' hash + */ + flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED; + break; + } + + mbedtls_md( md_info, crl_list->tbs.p, crl_list->tbs.len, hash ); + + if( x509_profile_check_key( profile, crl_list->sig_pk, &ca->pk ) != 0 ) + flags |= MBEDTLS_X509_BADCERT_BAD_KEY; + + if( mbedtls_pk_verify_ext( crl_list->sig_pk, crl_list->sig_opts, &ca->pk, + crl_list->sig_md, hash, mbedtls_md_get_size( md_info ), + crl_list->sig.p, crl_list->sig.len ) != 0 ) + { + flags |= MBEDTLS_X509_BADCRL_NOT_TRUSTED; + break; + } + + /* + * Check for validity of CRL (Do not drop out) + */ + if( mbedtls_x509_time_is_past( &crl_list->next_update ) ) + flags |= MBEDTLS_X509_BADCRL_EXPIRED; + + if( mbedtls_x509_time_is_future( &crl_list->this_update ) ) + flags |= MBEDTLS_X509_BADCRL_FUTURE; + + /* + * Check if certificate is revoked + */ + if( mbedtls_x509_crt_is_revoked( crt, crl_list ) ) + { + flags |= MBEDTLS_X509_BADCERT_REVOKED; + break; + } + + crl_list = crl_list->next; + } + + return( flags ); +} +#endif /* MBEDTLS_X509_CRL_PARSE_C */ + +/* + * Like memcmp, but case-insensitive and always returns -1 if different + */ +static int x509_memcasecmp( const void *s1, const void *s2, size_t len ) +{ + size_t i; + unsigned char diff; + const unsigned char *n1 = s1, *n2 = s2; + + for( i = 0; i < len; i++ ) + { + diff = n1[i] ^ n2[i]; + + if( diff == 0 ) + continue; + + if( diff == 32 && + ( ( n1[i] >= 'a' && n1[i] <= 'z' ) || + ( n1[i] >= 'A' && n1[i] <= 'Z' ) ) ) + { + continue; + } + + return( -1 ); + } + + return( 0 ); +} + +#if !defined(MBEDTLS_IOT_SPECIFIC) +/* + * Return 0 if name matches wildcard, -1 otherwise + */ +static int x509_check_wildcard( const char *cn, mbedtls_x509_buf *name ) +{ + size_t i; + size_t cn_idx = 0, cn_len = strlen( cn ); + + if( name->len < 3 || name->p[0] != '*' || name->p[1] != '.' ) + return( 0 ); + + for( i = 0; i < cn_len; ++i ) + { + if( cn[i] == '.' ) + { + cn_idx = i; + break; + } + } + + if( cn_idx == 0 ) + return( -1 ); + + if( cn_len - cn_idx == name->len - 1 && + x509_memcasecmp( name->p + 1, cn + cn_idx, name->len - 1 ) == 0 ) + { + return( 0 ); + } + + return( -1 ); +} +#endif /* MBEDTLS_IOT_SPECIFIC */ + +/* + * Compare two X.509 strings, case-insensitive, and allowing for some encoding + * variations (but not all). + * + * Return 0 if equal, -1 otherwise. + */ +static int x509_string_cmp( const mbedtls_x509_buf *a, const mbedtls_x509_buf *b ) +{ + if( a->tag == b->tag && + a->len == b->len && + memcmp( a->p, b->p, b->len ) == 0 ) + { + return( 0 ); + } + + if( ( a->tag == MBEDTLS_ASN1_UTF8_STRING || a->tag == MBEDTLS_ASN1_PRINTABLE_STRING ) && + ( b->tag == MBEDTLS_ASN1_UTF8_STRING || b->tag == MBEDTLS_ASN1_PRINTABLE_STRING ) && + a->len == b->len && + x509_memcasecmp( a->p, b->p, b->len ) == 0 ) + { + return( 0 ); + } + + return( -1 ); +} + +/* + * Compare two X.509 Names (aka rdnSequence). + * + * See RFC 5280 section 7.1, though we don't implement the whole algorithm: + * we sometimes return unequal when the full algorithm would return equal, + * but never the other way. (In particular, we don't do Unicode normalisation + * or space folding.) + * + * Return 0 if equal, -1 otherwise. + */ +static int x509_name_cmp( const mbedtls_x509_name *a, const mbedtls_x509_name *b ) +{ + /* Avoid recursion, it might not be optimised by the compiler */ + while( a != NULL || b != NULL ) + { + if( a == NULL || b == NULL ) + return( -1 ); + + /* type */ + if( a->oid.tag != b->oid.tag || + a->oid.len != b->oid.len || + memcmp( a->oid.p, b->oid.p, b->oid.len ) != 0 ) + { + return( -1 ); + } + + /* value */ + if( x509_string_cmp( &a->val, &b->val ) != 0 ) + return( -1 ); + + /* structure of the list of sets */ + if( a->next_merged != b->next_merged ) + return( -1 ); + + a = a->next; + b = b->next; + } + + /* a == NULL == b */ + return( 0 ); +} + +/* + * Check if 'parent' is a suitable parent (signing CA) for 'child'. + * Return 0 if yes, -1 if not. + * + * top means parent is a locally-trusted certificate + * bottom means child is the end entity cert + */ +static int x509_crt_check_parent( const mbedtls_x509_crt *child, + const mbedtls_x509_crt *parent, + int top, int bottom ) +{ + int need_ca_bit; + + /* Parent must be the issuer */ + if( x509_name_cmp( &child->issuer, &parent->subject ) != 0 ) + return( -1 ); + + /* Parent must have the basicConstraints CA bit set as a general rule */ + need_ca_bit = 1; + + /* Exception: v1/v2 certificates that are locally trusted. */ + if( top && parent->version < 3 ) + need_ca_bit = 0; + + /* Exception: self-signed end-entity certs that are locally trusted. */ + if( top && bottom && + child->raw.len == parent->raw.len && + memcmp( child->raw.p, parent->raw.p, child->raw.len ) == 0 ) + { + need_ca_bit = 0; + } + + if( need_ca_bit && ! parent->ca_istrue ) + return( -1 ); + +#if defined(MBEDTLS_X509_CHECK_KEY_USAGE) + if( need_ca_bit && + mbedtls_x509_crt_check_key_usage( parent, MBEDTLS_X509_KU_KEY_CERT_SIGN ) != 0 ) + { + return( -1 ); + } +#endif + + return( 0 ); +} + +static int x509_crt_verify_top( + mbedtls_x509_crt *child, mbedtls_x509_crt *trust_ca, + mbedtls_x509_crl *ca_crl, + const mbedtls_x509_crt_profile *profile, + int path_cnt, int self_cnt, uint32_t *flags, + int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), + void *p_vrfy ) +{ + int ret; + uint32_t ca_flags = 0; + int check_path_cnt; + unsigned char hash[MBEDTLS_MD_MAX_SIZE]; + const mbedtls_md_info_t *md_info; + mbedtls_x509_crt *future_past_ca = NULL; + + if( mbedtls_x509_time_is_past( &child->valid_to ) ) + *flags |= MBEDTLS_X509_BADCERT_EXPIRED; + if( mbedtls_x509_time_is_future( &child->valid_from ) ) + *flags |= MBEDTLS_X509_BADCERT_FUTURE; + if( x509_profile_check_md_alg( profile, child->sig_md ) != 0 ) + *flags |= MBEDTLS_X509_BADCERT_BAD_MD; + if( x509_profile_check_pk_alg( profile, child->sig_pk ) != 0 ) + *flags |= MBEDTLS_X509_BADCERT_BAD_PK; + + /* + * Child is the top of the chain. Check against the trust_ca list. + */ + *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED; + + md_info = mbedtls_md_info_from_type( child->sig_md ); + if( md_info == NULL ) + { + /* + * Cannot check 'unknown', no need to try any CA + */ + trust_ca = NULL; + } + else + mbedtls_md( md_info, child->tbs.p, child->tbs.len, hash ); + + for( /* trust_ca */ ; trust_ca != NULL; trust_ca = trust_ca->next ) + { + if( x509_crt_check_parent( child, trust_ca, 1, path_cnt == 0 ) != 0 ) + continue; + + check_path_cnt = path_cnt + 1; + + /* + * Reduce check_path_cnt to check against if top of the chain is + * the same as the trusted CA + */ + if( child->subject_raw.len == trust_ca->subject_raw.len && + memcmp( child->subject_raw.p, trust_ca->subject_raw.p, + child->issuer_raw.len ) == 0 ) + { + check_path_cnt--; + } + + /* Self signed certificates do not count towards the limit */ + if( trust_ca->max_pathlen > 0 && + trust_ca->max_pathlen < check_path_cnt - self_cnt ) + { + continue; + } + + if( mbedtls_pk_verify_ext( child->sig_pk, child->sig_opts, &trust_ca->pk, + child->sig_md, hash, mbedtls_md_get_size( md_info ), + child->sig.p, child->sig.len ) != 0 ) + { + continue; + } + + if( mbedtls_x509_time_is_past( &trust_ca->valid_to ) || + mbedtls_x509_time_is_future( &trust_ca->valid_from ) ) + { + if ( future_past_ca == NULL ) + future_past_ca = trust_ca; + + continue; + } + + break; + } + + if( trust_ca != NULL || ( trust_ca = future_past_ca ) != NULL ) + { + /* + * Top of chain is signed by a trusted CA + */ + *flags &= ~MBEDTLS_X509_BADCERT_NOT_TRUSTED; + + if( x509_profile_check_key( profile, child->sig_pk, &trust_ca->pk ) != 0 ) + *flags |= MBEDTLS_X509_BADCERT_BAD_KEY; + } + + /* + * If top of chain is not the same as the trusted CA send a verify request + * to the callback for any issues with validity and CRL presence for the + * trusted CA certificate. + */ + if( trust_ca != NULL && + ( child->subject_raw.len != trust_ca->subject_raw.len || + memcmp( child->subject_raw.p, trust_ca->subject_raw.p, + child->issuer_raw.len ) != 0 ) ) + { +#if defined(MBEDTLS_X509_CRL_PARSE_C) + /* Check trusted CA's CRL for the chain's top crt */ + *flags |= x509_crt_verifycrl( child, trust_ca, ca_crl, profile ); +#else + ((void) ca_crl); +#endif + + if( mbedtls_x509_time_is_past( &trust_ca->valid_to ) ) + ca_flags |= MBEDTLS_X509_BADCERT_EXPIRED; + + if( mbedtls_x509_time_is_future( &trust_ca->valid_from ) ) + ca_flags |= MBEDTLS_X509_BADCERT_FUTURE; + + if( NULL != f_vrfy ) + { + if( ( ret = f_vrfy( p_vrfy, trust_ca, path_cnt + 1, + &ca_flags ) ) != 0 ) + { + return( ret ); + } + } + } + + /* Call callback on top cert */ + if( NULL != f_vrfy ) + { + if( ( ret = f_vrfy( p_vrfy, child, path_cnt, flags ) ) != 0 ) + return( ret ); + } + + *flags |= ca_flags; + + return( 0 ); +} + +static int x509_crt_verify_child( + mbedtls_x509_crt *child, mbedtls_x509_crt *parent, + mbedtls_x509_crt *trust_ca, mbedtls_x509_crl *ca_crl, + const mbedtls_x509_crt_profile *profile, + int path_cnt, int self_cnt, uint32_t *flags, + int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), + void *p_vrfy ) +{ + int ret; + uint32_t parent_flags = 0; + unsigned char hash[MBEDTLS_MD_MAX_SIZE]; + mbedtls_x509_crt *grandparent; + const mbedtls_md_info_t *md_info; + + /* Counting intermediate self signed certificates */ + if( ( path_cnt != 0 ) && x509_name_cmp( &child->issuer, &child->subject ) == 0 ) + self_cnt++; + + /* path_cnt is 0 for the first intermediate CA */ + if( 1 + path_cnt > MBEDTLS_X509_MAX_INTERMEDIATE_CA ) + { + *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED; + return( MBEDTLS_ERR_X509_CERT_VERIFY_FAILED ); + } + + if( mbedtls_x509_time_is_past( &child->valid_to ) ) + *flags |= MBEDTLS_X509_BADCERT_EXPIRED; + + if( mbedtls_x509_time_is_future( &child->valid_from ) ) + *flags |= MBEDTLS_X509_BADCERT_FUTURE; + + if( x509_profile_check_md_alg( profile, child->sig_md ) != 0 ) + *flags |= MBEDTLS_X509_BADCERT_BAD_MD; + + if( x509_profile_check_pk_alg( profile, child->sig_pk ) != 0 ) + *flags |= MBEDTLS_X509_BADCERT_BAD_PK; + + md_info = mbedtls_md_info_from_type( child->sig_md ); + if( md_info == NULL ) + { + /* + * Cannot check 'unknown' hash + */ + *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED; + } + else + { + mbedtls_md( md_info, child->tbs.p, child->tbs.len, hash ); + + if( x509_profile_check_key( profile, child->sig_pk, &parent->pk ) != 0 ) + *flags |= MBEDTLS_X509_BADCERT_BAD_KEY; + + if( mbedtls_pk_verify_ext( child->sig_pk, child->sig_opts, &parent->pk, + child->sig_md, hash, mbedtls_md_get_size( md_info ), + child->sig.p, child->sig.len ) != 0 ) + { + *flags |= MBEDTLS_X509_BADCERT_NOT_TRUSTED; + } + } + +#if defined(MBEDTLS_X509_CRL_PARSE_C) + /* Check trusted CA's CRL for the given crt */ + *flags |= x509_crt_verifycrl(child, parent, ca_crl, profile ); +#endif + + /* Look for a grandparent in trusted CAs */ + for( grandparent = trust_ca; + grandparent != NULL; + grandparent = grandparent->next ) + { + if( x509_crt_check_parent( parent, grandparent, + 0, path_cnt == 0 ) == 0 ) + break; + } + + if( grandparent != NULL ) + { + ret = x509_crt_verify_top( parent, grandparent, ca_crl, profile, + path_cnt + 1, self_cnt, &parent_flags, f_vrfy, p_vrfy ); + if( ret != 0 ) + return( ret ); + } + else + { + /* Look for a grandparent upwards the chain */ + for( grandparent = parent->next; + grandparent != NULL; + grandparent = grandparent->next ) + { + /* +2 because the current step is not yet accounted for + * and because max_pathlen is one higher than it should be. + * Also self signed certificates do not count to the limit. */ + if( grandparent->max_pathlen > 0 && + grandparent->max_pathlen < 2 + path_cnt - self_cnt ) + { + continue; + } + + if( x509_crt_check_parent( parent, grandparent, + 0, path_cnt == 0 ) == 0 ) + break; + } + + /* Is our parent part of the chain or at the top? */ + if( grandparent != NULL ) + { + ret = x509_crt_verify_child( parent, grandparent, trust_ca, ca_crl, + profile, path_cnt + 1, self_cnt, &parent_flags, + f_vrfy, p_vrfy ); + if( ret != 0 ) + return( ret ); + } + else + { + ret = x509_crt_verify_top( parent, trust_ca, ca_crl, profile, + path_cnt + 1, self_cnt, &parent_flags, + f_vrfy, p_vrfy ); + if( ret != 0 ) + return( ret ); + } + } + + /* child is verified to be a child of the parent, call verify callback */ + if( NULL != f_vrfy ) + if( ( ret = f_vrfy( p_vrfy, child, path_cnt, flags ) ) != 0 ) + return( ret ); + + *flags |= parent_flags; + + return( 0 ); +} + +/* + * Verify the certificate validity + */ +int mbedtls_x509_crt_verify( mbedtls_x509_crt *crt, + mbedtls_x509_crt *trust_ca, + mbedtls_x509_crl *ca_crl, + const char *cn, uint32_t *flags, + int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), + void *p_vrfy ) +{ + return( mbedtls_x509_crt_verify_with_profile( crt, trust_ca, ca_crl, + &mbedtls_x509_crt_profile_default, cn, flags, f_vrfy, p_vrfy ) ); +} + + +/* + * Verify the certificate validity, with profile + */ +int mbedtls_x509_crt_verify_with_profile( mbedtls_x509_crt *crt, + mbedtls_x509_crt *trust_ca, + mbedtls_x509_crl *ca_crl, + const mbedtls_x509_crt_profile *profile, + const char *cn, uint32_t *flags, + int (*f_vrfy)(void *, mbedtls_x509_crt *, int, uint32_t *), + void *p_vrfy ) +{ + int ret; + int pathlen = 0, selfsigned = 0; + mbedtls_x509_crt *parent; +#if !defined(MBEDTLS_IOT_SPECIFIC) + size_t cn_len; + mbedtls_x509_name *name; + mbedtls_x509_sequence *cur = NULL; +#endif + mbedtls_pk_type_t pk_type; + + if( profile == NULL ) + return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); + + *flags = 0; + +#if !defined(MBEDTLS_IOT_SPECIFIC) + if( cn != NULL ) + { + name = &crt->subject; + cn_len = strlen( cn ); + + if( crt->ext_types & MBEDTLS_X509_EXT_SUBJECT_ALT_NAME ) + { + cur = &crt->subject_alt_names; + + while( cur != NULL ) + { + if( cur->buf.len == cn_len && + x509_memcasecmp( cn, cur->buf.p, cn_len ) == 0 ) + break; + + if( cur->buf.len > 2 && + memcmp( cur->buf.p, "*.", 2 ) == 0 && + x509_check_wildcard( cn, &cur->buf ) == 0 ) + { + break; + } + + cur = cur->next; + } + + if( cur == NULL ) + *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH; + } + else + { + while( name != NULL ) + { + if( MBEDTLS_OID_CMP( MBEDTLS_OID_AT_CN, &name->oid ) == 0 ) + { + if( name->val.len == cn_len && + x509_memcasecmp( name->val.p, cn, cn_len ) == 0 ) + break; + + if( name->val.len > 2 && + memcmp( name->val.p, "*.", 2 ) == 0 && + x509_check_wildcard( cn, &name->val ) == 0 ) + break; + } + + name = name->next; + } + + if( name == NULL ) + *flags |= MBEDTLS_X509_BADCERT_CN_MISMATCH; + } + } +#else + (void)cn; +#endif /* MBEDTLS_IOT_SPECIFIC */ + + /* Check the type and size of the key */ + pk_type = mbedtls_pk_get_type( &crt->pk ); + + if( x509_profile_check_pk_alg( profile, pk_type ) != 0 ) + *flags |= MBEDTLS_X509_BADCERT_BAD_PK; + + if( x509_profile_check_key( profile, pk_type, &crt->pk ) != 0 ) + *flags |= MBEDTLS_X509_BADCERT_BAD_KEY; + + /* Look for a parent in trusted CAs */ + for( parent = trust_ca; parent != NULL; parent = parent->next ) + { + if( x509_crt_check_parent( crt, parent, 0, pathlen == 0 ) == 0 ) + break; + } + + if( parent != NULL ) + { + ret = x509_crt_verify_top( crt, parent, ca_crl, profile, + pathlen, selfsigned, flags, f_vrfy, p_vrfy ); + if( ret != 0 ) + return( ret ); + } + else + { + /* Look for a parent upwards the chain */ + for( parent = crt->next; parent != NULL; parent = parent->next ) + if( x509_crt_check_parent( crt, parent, 0, pathlen == 0 ) == 0 ) + break; + + /* Are we part of the chain or at the top? */ + if( parent != NULL ) + { + ret = x509_crt_verify_child( crt, parent, trust_ca, ca_crl, profile, + pathlen, selfsigned, flags, f_vrfy, p_vrfy ); + if( ret != 0 ) + return( ret ); + } + else + { + ret = x509_crt_verify_top( crt, trust_ca, ca_crl, profile, + pathlen, selfsigned, flags, f_vrfy, p_vrfy ); + if( ret != 0 ) + return( ret ); + } + } + + if( *flags != 0 ) + return( MBEDTLS_ERR_X509_CERT_VERIFY_FAILED ); + + return( 0 ); +} + +/* + * Initialize a certificate chain + */ +void mbedtls_x509_crt_init( mbedtls_x509_crt *crt ) +{ + memset( crt, 0, sizeof(mbedtls_x509_crt) ); +} + +/* + * Unallocate all certificate data + */ +void mbedtls_x509_crt_free( mbedtls_x509_crt *crt ) +{ + mbedtls_x509_crt *cert_cur = crt; + mbedtls_x509_crt *cert_prv; + mbedtls_x509_name *name_cur; + mbedtls_x509_name *name_prv; + mbedtls_x509_sequence *seq_cur; + mbedtls_x509_sequence *seq_prv; + + if( crt == NULL ) + return; + + do + { + mbedtls_pk_free( &cert_cur->pk ); + +#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) + mbedtls_free( cert_cur->sig_opts ); +#endif + + name_cur = cert_cur->issuer.next; + while( name_cur != NULL ) + { + name_prv = name_cur; + name_cur = name_cur->next; + mbedtls_zeroize( name_prv, sizeof( mbedtls_x509_name ) ); + mbedtls_free( name_prv ); + } + + name_cur = cert_cur->subject.next; + while( name_cur != NULL ) + { + name_prv = name_cur; + name_cur = name_cur->next; + mbedtls_zeroize( name_prv, sizeof( mbedtls_x509_name ) ); + mbedtls_free( name_prv ); + } + + seq_cur = cert_cur->ext_key_usage.next; + while( seq_cur != NULL ) + { + seq_prv = seq_cur; + seq_cur = seq_cur->next; + mbedtls_zeroize( seq_prv, sizeof( mbedtls_x509_sequence ) ); + mbedtls_free( seq_prv ); + } + + seq_cur = cert_cur->subject_alt_names.next; + while( seq_cur != NULL ) + { + seq_prv = seq_cur; + seq_cur = seq_cur->next; + mbedtls_zeroize( seq_prv, sizeof( mbedtls_x509_sequence ) ); + mbedtls_free( seq_prv ); + } + + if( cert_cur->raw.p != NULL ) + { + mbedtls_zeroize( cert_cur->raw.p, cert_cur->raw.len ); + mbedtls_free( cert_cur->raw.p ); + } + + cert_cur = cert_cur->next; + } + while( cert_cur != NULL ); + + cert_cur = crt; + do + { + cert_prv = cert_cur; + cert_cur = cert_cur->next; + + mbedtls_zeroize( cert_prv, sizeof( mbedtls_x509_crt ) ); + if( cert_prv != crt ) + mbedtls_free( cert_prv ); + } + while( cert_cur != NULL ); +} + +#endif /* MBEDTLS_X509_CRT_PARSE_C */ diff --git a/security/mbedtls/src/x509_csr.c b/security/mbedtls/src/x509_csr.c new file mode 100644 index 0000000000..a34539e37c --- /dev/null +++ b/security/mbedtls/src/x509_csr.c @@ -0,0 +1,425 @@ +/* + * X.509 Certificate Signing Request (CSR) parsing + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +/* + * The ITU-T X.509 standard defines a certificate format for PKI. + * + * http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs) + * http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs) + * http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10) + * + * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf + * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_X509_CSR_PARSE_C) + +#include "mbedtls/x509_csr.h" +#include "mbedtls/oid.h" + +#include + +#if defined(MBEDTLS_PEM_PARSE_C) +#include "mbedtls/pem.h" +#endif + +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#include +#define mbedtls_free free +#define mbedtls_calloc calloc +#define mbedtls_snprintf snprintf +#endif + +#if defined(MBEDTLS_FS_IO) || defined(EFIX64) || defined(EFI32) +#include +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +/* + * Version ::= INTEGER { v1(0) } + */ +static int x509_csr_get_version( unsigned char **p, + const unsigned char *end, + int *ver ) +{ + int ret; + + if( ( ret = mbedtls_asn1_get_int( p, end, ver ) ) != 0 ) + { + if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG ) + { + *ver = 0; + return( 0 ); + } + + return( MBEDTLS_ERR_X509_INVALID_VERSION + ret ); + } + + return( 0 ); +} + +/* + * Parse a CSR in DER format + */ +int mbedtls_x509_csr_parse_der( mbedtls_x509_csr *csr, + const unsigned char *buf, size_t buflen ) +{ + int ret; + size_t len; + unsigned char *p, *end; + mbedtls_x509_buf sig_params; + + memset( &sig_params, 0, sizeof( mbedtls_x509_buf ) ); + + /* + * Check for valid input + */ + if( csr == NULL || buf == NULL || buflen == 0 ) + return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); + + mbedtls_x509_csr_init( csr ); + + /* + * first copy the raw DER data + */ + p = mbedtls_calloc( 1, len = buflen ); + + if( p == NULL ) + return( MBEDTLS_ERR_X509_ALLOC_FAILED ); + + memcpy( p, buf, buflen ); + + csr->raw.p = p; + csr->raw.len = len; + end = p + len; + + /* + * CertificationRequest ::= SEQUENCE { + * certificationRequestInfo CertificationRequestInfo, + * signatureAlgorithm AlgorithmIdentifier, + * signature BIT STRING + * } + */ + if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) + { + mbedtls_x509_csr_free( csr ); + return( MBEDTLS_ERR_X509_INVALID_FORMAT ); + } + + if( len != (size_t) ( end - p ) ) + { + mbedtls_x509_csr_free( csr ); + return( MBEDTLS_ERR_X509_INVALID_FORMAT + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + } + + /* + * CertificationRequestInfo ::= SEQUENCE { + */ + csr->cri.p = p; + + if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) + { + mbedtls_x509_csr_free( csr ); + return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); + } + + end = p + len; + csr->cri.len = end - csr->cri.p; + + /* + * Version ::= INTEGER { v1(0) } + */ + if( ( ret = x509_csr_get_version( &p, end, &csr->version ) ) != 0 ) + { + mbedtls_x509_csr_free( csr ); + return( ret ); + } + + csr->version++; + + if( csr->version != 1 ) + { + mbedtls_x509_csr_free( csr ); + return( MBEDTLS_ERR_X509_UNKNOWN_VERSION ); + } + + /* + * subject Name + */ + csr->subject_raw.p = p; + + if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 ) + { + mbedtls_x509_csr_free( csr ); + return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); + } + + if( ( ret = mbedtls_x509_get_name( &p, p + len, &csr->subject ) ) != 0 ) + { + mbedtls_x509_csr_free( csr ); + return( ret ); + } + + csr->subject_raw.len = p - csr->subject_raw.p; + + /* + * subjectPKInfo SubjectPublicKeyInfo + */ + if( ( ret = mbedtls_pk_parse_subpubkey( &p, end, &csr->pk ) ) != 0 ) + { + mbedtls_x509_csr_free( csr ); + return( ret ); + } + + /* + * attributes [0] Attributes + * + * The list of possible attributes is open-ended, though RFC 2985 + * (PKCS#9) defines a few in section 5.4. We currently don't support any, + * so we just ignore them. This is a safe thing to do as the worst thing + * that could happen is that we issue a certificate that does not match + * the requester's expectations - this cannot cause a violation of our + * signature policies. + */ + if( ( ret = mbedtls_asn1_get_tag( &p, end, &len, + MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC ) ) != 0 ) + { + mbedtls_x509_csr_free( csr ); + return( MBEDTLS_ERR_X509_INVALID_FORMAT + ret ); + } + + p += len; + + end = csr->raw.p + csr->raw.len; + + /* + * signatureAlgorithm AlgorithmIdentifier, + * signature BIT STRING + */ + if( ( ret = mbedtls_x509_get_alg( &p, end, &csr->sig_oid, &sig_params ) ) != 0 ) + { + mbedtls_x509_csr_free( csr ); + return( ret ); + } + + if( ( ret = mbedtls_x509_get_sig_alg( &csr->sig_oid, &sig_params, + &csr->sig_md, &csr->sig_pk, + &csr->sig_opts ) ) != 0 ) + { + mbedtls_x509_csr_free( csr ); + return( MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG ); + } + + if( ( ret = mbedtls_x509_get_sig( &p, end, &csr->sig ) ) != 0 ) + { + mbedtls_x509_csr_free( csr ); + return( ret ); + } + + if( p != end ) + { + mbedtls_x509_csr_free( csr ); + return( MBEDTLS_ERR_X509_INVALID_FORMAT + + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ); + } + + return( 0 ); +} + +/* + * Parse a CSR, allowing for PEM or raw DER encoding + */ +int mbedtls_x509_csr_parse( mbedtls_x509_csr *csr, const unsigned char *buf, size_t buflen ) +{ +#if defined(MBEDTLS_PEM_PARSE_C) + int ret; + size_t use_len; + mbedtls_pem_context pem; +#endif + + /* + * Check for valid input + */ + if( csr == NULL || buf == NULL || buflen == 0 ) + return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); + +#if defined(MBEDTLS_PEM_PARSE_C) + mbedtls_pem_init( &pem ); + + /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */ + if( buf[buflen - 1] != '\0' ) + ret = MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT; + else + ret = mbedtls_pem_read_buffer( &pem, + "-----BEGIN CERTIFICATE REQUEST-----", + "-----END CERTIFICATE REQUEST-----", + buf, NULL, 0, &use_len ); + + if( ret == 0 ) + { + /* + * Was PEM encoded, parse the result + */ + if( ( ret = mbedtls_x509_csr_parse_der( csr, pem.buf, pem.buflen ) ) != 0 ) + return( ret ); + + mbedtls_pem_free( &pem ); + return( 0 ); + } + else if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT ) + { + mbedtls_pem_free( &pem ); + return( ret ); + } + else +#endif /* MBEDTLS_PEM_PARSE_C */ + return( mbedtls_x509_csr_parse_der( csr, buf, buflen ) ); +} + +#if defined(MBEDTLS_FS_IO) +/* + * Load a CSR into the structure + */ +int mbedtls_x509_csr_parse_file( mbedtls_x509_csr *csr, const char *path ) +{ + int ret; + size_t n; + unsigned char *buf; + + if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 ) + return( ret ); + + ret = mbedtls_x509_csr_parse( csr, buf, n ); + + mbedtls_zeroize( buf, n ); + mbedtls_free( buf ); + + return( ret ); +} +#endif /* MBEDTLS_FS_IO */ + +#define BEFORE_COLON 14 +#define BC "14" +/* + * Return an informational string about the CSR. + */ +int mbedtls_x509_csr_info( char *buf, size_t size, const char *prefix, + const mbedtls_x509_csr *csr ) +{ + int ret; + size_t n; + char *p; + char key_size_str[BEFORE_COLON]; + + p = buf; + n = size; + + ret = mbedtls_snprintf( p, n, "%sCSR version : %d", + prefix, csr->version ); + MBEDTLS_X509_SAFE_SNPRINTF; + + ret = mbedtls_snprintf( p, n, "\n%ssubject name : ", prefix ); + MBEDTLS_X509_SAFE_SNPRINTF; + ret = mbedtls_x509_dn_gets( p, n, &csr->subject ); + MBEDTLS_X509_SAFE_SNPRINTF; + +#if !defined(MBEDTLS_IOT_SPECIFIC) + ret = mbedtls_snprintf( p, n, "\n%ssigned using : ", prefix ); + MBEDTLS_X509_SAFE_SNPRINTF; + + ret = mbedtls_x509_sig_alg_gets( p, n, &csr->sig_oid, csr->sig_pk, csr->sig_md, + csr->sig_opts ); + MBEDTLS_X509_SAFE_SNPRINTF; +#endif /* MBEDTLS_IOT_SPECIFIC */ + + if( ( ret = mbedtls_x509_key_size_helper( key_size_str, BEFORE_COLON, + mbedtls_pk_get_name( &csr->pk ) ) ) != 0 ) + { + return( ret ); + } + + ret = mbedtls_snprintf( p, n, "\n%s%-" BC "s: %d bits\n", prefix, key_size_str, + (int) mbedtls_pk_get_bitlen( &csr->pk ) ); + MBEDTLS_X509_SAFE_SNPRINTF; + + return( (int) ( size - n ) ); +} + +/* + * Initialize a CSR + */ +void mbedtls_x509_csr_init( mbedtls_x509_csr *csr ) +{ + memset( csr, 0, sizeof(mbedtls_x509_csr) ); +} + +/* + * Unallocate all CSR data + */ +void mbedtls_x509_csr_free( mbedtls_x509_csr *csr ) +{ + mbedtls_x509_name *name_cur; + mbedtls_x509_name *name_prv; + + if( csr == NULL ) + return; + + mbedtls_pk_free( &csr->pk ); + +#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT) + mbedtls_free( csr->sig_opts ); +#endif + + name_cur = csr->subject.next; + while( name_cur != NULL ) + { + name_prv = name_cur; + name_cur = name_cur->next; + mbedtls_zeroize( name_prv, sizeof( mbedtls_x509_name ) ); + mbedtls_free( name_prv ); + } + + if( csr->raw.p != NULL ) + { + mbedtls_zeroize( csr->raw.p, csr->raw.len ); + mbedtls_free( csr->raw.p ); + } + + mbedtls_zeroize( csr, sizeof( mbedtls_x509_csr ) ); +} + +#endif /* MBEDTLS_X509_CSR_PARSE_C */ diff --git a/security/mbedtls/src/x509write_crt.c b/security/mbedtls/src/x509write_crt.c new file mode 100644 index 0000000000..d1d9a22a7e --- /dev/null +++ b/security/mbedtls/src/x509write_crt.c @@ -0,0 +1,459 @@ +/* + * X.509 certificate writing + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +/* + * References: + * - certificates: RFC 5280, updated by RFC 6818 + * - CSRs: PKCS#10 v1.7 aka RFC 2986 + * - attributes: PKCS#9 v2.0 aka RFC 2985 + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_X509_CRT_WRITE_C) + +#include "mbedtls/x509_crt.h" +#include "mbedtls/oid.h" +#include "mbedtls/asn1write.h" +#include "mbedtls/sha1.h" + +#include + +#if defined(MBEDTLS_PEM_WRITE_C) +#include "mbedtls/pem.h" +#endif /* MBEDTLS_PEM_WRITE_C */ + +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +void mbedtls_x509write_crt_init( mbedtls_x509write_cert *ctx ) +{ + memset( ctx, 0, sizeof(mbedtls_x509write_cert) ); + + mbedtls_mpi_init( &ctx->serial ); + ctx->version = MBEDTLS_X509_CRT_VERSION_3; +} + +void mbedtls_x509write_crt_free( mbedtls_x509write_cert *ctx ) +{ + mbedtls_mpi_free( &ctx->serial ); + + mbedtls_asn1_free_named_data_list( &ctx->subject ); + mbedtls_asn1_free_named_data_list( &ctx->issuer ); + mbedtls_asn1_free_named_data_list( &ctx->extensions ); + + mbedtls_zeroize( ctx, sizeof(mbedtls_x509write_cert) ); +} + +void mbedtls_x509write_crt_set_version( mbedtls_x509write_cert *ctx, int version ) +{ + ctx->version = version; +} + +void mbedtls_x509write_crt_set_md_alg( mbedtls_x509write_cert *ctx, mbedtls_md_type_t md_alg ) +{ + ctx->md_alg = md_alg; +} + +void mbedtls_x509write_crt_set_subject_key( mbedtls_x509write_cert *ctx, mbedtls_pk_context *key ) +{ + ctx->subject_key = key; +} + +void mbedtls_x509write_crt_set_issuer_key( mbedtls_x509write_cert *ctx, mbedtls_pk_context *key ) +{ + ctx->issuer_key = key; +} + +int mbedtls_x509write_crt_set_subject_name( mbedtls_x509write_cert *ctx, + const char *subject_name ) +{ + return mbedtls_x509_string_to_names( &ctx->subject, subject_name ); +} + +int mbedtls_x509write_crt_set_issuer_name( mbedtls_x509write_cert *ctx, + const char *issuer_name ) +{ + return mbedtls_x509_string_to_names( &ctx->issuer, issuer_name ); +} + +int mbedtls_x509write_crt_set_serial( mbedtls_x509write_cert *ctx, const mbedtls_mpi *serial ) +{ + int ret; + + if( ( ret = mbedtls_mpi_copy( &ctx->serial, serial ) ) != 0 ) + return( ret ); + + return( 0 ); +} + +int mbedtls_x509write_crt_set_validity( mbedtls_x509write_cert *ctx, const char *not_before, + const char *not_after ) +{ + if( strlen( not_before ) != MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1 || + strlen( not_after ) != MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1 ) + { + return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); + } + strncpy( ctx->not_before, not_before, MBEDTLS_X509_RFC5280_UTC_TIME_LEN ); + strncpy( ctx->not_after , not_after , MBEDTLS_X509_RFC5280_UTC_TIME_LEN ); + ctx->not_before[MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1] = 'Z'; + ctx->not_after[MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1] = 'Z'; + + return( 0 ); +} + +int mbedtls_x509write_crt_set_extension( mbedtls_x509write_cert *ctx, + const char *oid, size_t oid_len, + int critical, + const unsigned char *val, size_t val_len ) +{ + return mbedtls_x509_set_extension( &ctx->extensions, oid, oid_len, + critical, val, val_len ); +} + +int mbedtls_x509write_crt_set_basic_constraints( mbedtls_x509write_cert *ctx, + int is_ca, int max_pathlen ) +{ + int ret; + unsigned char buf[9]; + unsigned char *c = buf + sizeof(buf); + size_t len = 0; + + memset( buf, 0, sizeof(buf) ); + + if( is_ca && max_pathlen > 127 ) + return( MBEDTLS_ERR_X509_BAD_INPUT_DATA ); + + if( is_ca ) + { + if( max_pathlen >= 0 ) + { + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, max_pathlen ) ); + } + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_bool( &c, buf, 1 ) ); + } + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED | + MBEDTLS_ASN1_SEQUENCE ) ); + + return mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_BASIC_CONSTRAINTS, + MBEDTLS_OID_SIZE( MBEDTLS_OID_BASIC_CONSTRAINTS ), + 0, buf + sizeof(buf) - len, len ); +} + +#if defined(MBEDTLS_SHA1_C) +int mbedtls_x509write_crt_set_subject_key_identifier( mbedtls_x509write_cert *ctx ) +{ + int ret; + unsigned char buf[MBEDTLS_MPI_MAX_SIZE * 2 + 20]; /* tag, length + 2xMPI */ + unsigned char *c = buf + sizeof(buf); + size_t len = 0; + + memset( buf, 0, sizeof(buf) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, ctx->subject_key ) ); + + mbedtls_sha1( buf + sizeof(buf) - len, len, buf + sizeof(buf) - 20 ); + c = buf + sizeof(buf) - 20; + len = 20; + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_OCTET_STRING ) ); + + return mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER, + MBEDTLS_OID_SIZE( MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER ), + 0, buf + sizeof(buf) - len, len ); +} + +int mbedtls_x509write_crt_set_authority_key_identifier( mbedtls_x509write_cert *ctx ) +{ + int ret; + unsigned char buf[MBEDTLS_MPI_MAX_SIZE * 2 + 20]; /* tag, length + 2xMPI */ + unsigned char *c = buf + sizeof(buf); + size_t len = 0; + + memset( buf, 0, sizeof(buf) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, ctx->issuer_key ) ); + + mbedtls_sha1( buf + sizeof(buf) - len, len, buf + sizeof(buf) - 20 ); + c = buf + sizeof(buf) - 20; + len = 20; + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONTEXT_SPECIFIC | 0 ) ); + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED | + MBEDTLS_ASN1_SEQUENCE ) ); + + return mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER, + MBEDTLS_OID_SIZE( MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER ), + 0, buf + sizeof(buf) - len, len ); +} +#endif /* MBEDTLS_SHA1_C */ + +int mbedtls_x509write_crt_set_key_usage( mbedtls_x509write_cert *ctx, + unsigned int key_usage ) +{ + unsigned char buf[4], ku; + unsigned char *c; + int ret; + + /* We currently only support 7 bits, from 0x80 to 0x02 */ + if( ( key_usage & ~0xfe ) != 0 ) + return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE ); + + c = buf + 4; + ku = (unsigned char) key_usage; + + if( ( ret = mbedtls_asn1_write_bitstring( &c, buf, &ku, 7 ) ) != 4 ) + return( ret ); + + ret = mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_KEY_USAGE, + MBEDTLS_OID_SIZE( MBEDTLS_OID_KEY_USAGE ), + 1, buf, 4 ); + if( ret != 0 ) + return( ret ); + + return( 0 ); +} + +int mbedtls_x509write_crt_set_ns_cert_type( mbedtls_x509write_cert *ctx, + unsigned char ns_cert_type ) +{ + unsigned char buf[4]; + unsigned char *c; + int ret; + + c = buf + 4; + + if( ( ret = mbedtls_asn1_write_bitstring( &c, buf, &ns_cert_type, 8 ) ) != 4 ) + return( ret ); + + ret = mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_NS_CERT_TYPE, + MBEDTLS_OID_SIZE( MBEDTLS_OID_NS_CERT_TYPE ), + 0, buf, 4 ); + if( ret != 0 ) + return( ret ); + + return( 0 ); +} + +static int x509_write_time( unsigned char **p, unsigned char *start, + const char *time, size_t size ) +{ + int ret; + size_t len = 0; + + /* + * write MBEDTLS_ASN1_UTC_TIME if year < 2050 (2 bytes shorter) + */ + if( time[0] == '2' && time[1] == '0' && time [2] < '5' ) + { + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, + (const unsigned char *) time + 2, + size - 2 ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_UTC_TIME ) ); + } + else + { + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start, + (const unsigned char *) time, + size ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_GENERALIZED_TIME ) ); + } + + return( (int) len ); +} + +int mbedtls_x509write_crt_der( mbedtls_x509write_cert *ctx, unsigned char *buf, size_t size, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + const char *sig_oid; + size_t sig_oid_len = 0; + unsigned char *c, *c2; + unsigned char hash[64]; + unsigned char sig[MBEDTLS_MPI_MAX_SIZE]; + unsigned char tmp_buf[2048]; + size_t sub_len = 0, pub_len = 0, sig_and_oid_len = 0, sig_len; + size_t len = 0; + mbedtls_pk_type_t pk_alg; + + /* + * Prepare data to be signed in tmp_buf + */ + c = tmp_buf + sizeof( tmp_buf ); + + /* Signature algorithm needed in TBS, and later for actual signature */ + pk_alg = mbedtls_pk_get_type( ctx->issuer_key ); + if( pk_alg == MBEDTLS_PK_ECKEY ) + pk_alg = MBEDTLS_PK_ECDSA; + + if( ( ret = mbedtls_oid_get_oid_by_sig_alg( pk_alg, ctx->md_alg, + &sig_oid, &sig_oid_len ) ) != 0 ) + { + return( ret ); + } + + /* + * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension + */ + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_extensions( &c, tmp_buf, ctx->extensions ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED | + MBEDTLS_ASN1_SEQUENCE ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONTEXT_SPECIFIC | + MBEDTLS_ASN1_CONSTRUCTED | 3 ) ); + + /* + * SubjectPublicKeyInfo + */ + MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_pk_write_pubkey_der( ctx->subject_key, + tmp_buf, c - tmp_buf ) ); + c -= pub_len; + len += pub_len; + + /* + * Subject ::= Name + */ + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_names( &c, tmp_buf, ctx->subject ) ); + + /* + * Validity ::= SEQUENCE { + * notBefore Time, + * notAfter Time } + */ + sub_len = 0; + + MBEDTLS_ASN1_CHK_ADD( sub_len, x509_write_time( &c, tmp_buf, ctx->not_after, + MBEDTLS_X509_RFC5280_UTC_TIME_LEN ) ); + + MBEDTLS_ASN1_CHK_ADD( sub_len, x509_write_time( &c, tmp_buf, ctx->not_before, + MBEDTLS_X509_RFC5280_UTC_TIME_LEN ) ); + + len += sub_len; + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, sub_len ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED | + MBEDTLS_ASN1_SEQUENCE ) ); + + /* + * Issuer ::= Name + */ + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_names( &c, tmp_buf, ctx->issuer ) ); + + /* + * Signature ::= AlgorithmIdentifier + */ + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_algorithm_identifier( &c, tmp_buf, + sig_oid, strlen( sig_oid ), 0 ) ); + + /* + * Serial ::= INTEGER + */ + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, tmp_buf, &ctx->serial ) ); + + /* + * Version ::= INTEGER { v1(0), v2(1), v3(2) } + */ + sub_len = 0; + MBEDTLS_ASN1_CHK_ADD( sub_len, mbedtls_asn1_write_int( &c, tmp_buf, ctx->version ) ); + len += sub_len; + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, sub_len ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONTEXT_SPECIFIC | + MBEDTLS_ASN1_CONSTRUCTED | 0 ) ); + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED | + MBEDTLS_ASN1_SEQUENCE ) ); + + /* + * Make signature + */ + mbedtls_md( mbedtls_md_info_from_type( ctx->md_alg ), c, len, hash ); + + if( ( ret = mbedtls_pk_sign( ctx->issuer_key, ctx->md_alg, hash, 0, sig, &sig_len, + f_rng, p_rng ) ) != 0 ) + { + return( ret ); + } + + /* + * Write data to output buffer + */ + c2 = buf + size; + MBEDTLS_ASN1_CHK_ADD( sig_and_oid_len, mbedtls_x509_write_sig( &c2, buf, + sig_oid, sig_oid_len, sig, sig_len ) ); + + if( len > (size_t)( c2 - buf ) ) + return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); + + c2 -= len; + memcpy( c2, c, len ); + + len += sig_and_oid_len; + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c2, buf, len ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c2, buf, MBEDTLS_ASN1_CONSTRUCTED | + MBEDTLS_ASN1_SEQUENCE ) ); + + return( (int) len ); +} + +#define PEM_BEGIN_CRT "-----BEGIN CERTIFICATE-----\n" +#define PEM_END_CRT "-----END CERTIFICATE-----\n" + +#if defined(MBEDTLS_PEM_WRITE_C) +int mbedtls_x509write_crt_pem( mbedtls_x509write_cert *crt, unsigned char *buf, size_t size, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + unsigned char output_buf[4096]; + size_t olen = 0; + + if( ( ret = mbedtls_x509write_crt_der( crt, output_buf, sizeof(output_buf), + f_rng, p_rng ) ) < 0 ) + { + return( ret ); + } + + if( ( ret = mbedtls_pem_write_buffer( PEM_BEGIN_CRT, PEM_END_CRT, + output_buf + sizeof(output_buf) - ret, + ret, buf, size, &olen ) ) != 0 ) + { + return( ret ); + } + + return( 0 ); +} +#endif /* MBEDTLS_PEM_WRITE_C */ + +#endif /* MBEDTLS_X509_CRT_WRITE_C */ diff --git a/security/mbedtls/src/x509write_csr.c b/security/mbedtls/src/x509write_csr.c new file mode 100644 index 0000000000..8fd856b2a2 --- /dev/null +++ b/security/mbedtls/src/x509write_csr.c @@ -0,0 +1,259 @@ +/* + * X.509 Certificate Signing Request writing + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ +/* + * References: + * - CSRs: PKCS#10 v1.7 aka RFC 2986 + * - attributes: PKCS#9 v2.0 aka RFC 2985 + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_X509_CSR_WRITE_C) + +#include "mbedtls/x509_csr.h" +#include "mbedtls/oid.h" +#include "mbedtls/asn1write.h" + +#include +#include + +#if defined(MBEDTLS_PEM_WRITE_C) +#include "mbedtls/pem.h" +#endif + +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +void mbedtls_x509write_csr_init( mbedtls_x509write_csr *ctx ) +{ + memset( ctx, 0, sizeof(mbedtls_x509write_csr) ); +} + +void mbedtls_x509write_csr_free( mbedtls_x509write_csr *ctx ) +{ + mbedtls_asn1_free_named_data_list( &ctx->subject ); + mbedtls_asn1_free_named_data_list( &ctx->extensions ); + + mbedtls_zeroize( ctx, sizeof(mbedtls_x509write_csr) ); +} + +void mbedtls_x509write_csr_set_md_alg( mbedtls_x509write_csr *ctx, mbedtls_md_type_t md_alg ) +{ + ctx->md_alg = md_alg; +} + +void mbedtls_x509write_csr_set_key( mbedtls_x509write_csr *ctx, mbedtls_pk_context *key ) +{ + ctx->key = key; +} + +int mbedtls_x509write_csr_set_subject_name( mbedtls_x509write_csr *ctx, + const char *subject_name ) +{ + return mbedtls_x509_string_to_names( &ctx->subject, subject_name ); +} + +int mbedtls_x509write_csr_set_extension( mbedtls_x509write_csr *ctx, + const char *oid, size_t oid_len, + const unsigned char *val, size_t val_len ) +{ + return mbedtls_x509_set_extension( &ctx->extensions, oid, oid_len, + 0, val, val_len ); +} + +int mbedtls_x509write_csr_set_key_usage( mbedtls_x509write_csr *ctx, unsigned char key_usage ) +{ + unsigned char buf[4]; + unsigned char *c; + int ret; + + c = buf + 4; + + if( ( ret = mbedtls_asn1_write_bitstring( &c, buf, &key_usage, 7 ) ) != 4 ) + return( ret ); + + ret = mbedtls_x509write_csr_set_extension( ctx, MBEDTLS_OID_KEY_USAGE, + MBEDTLS_OID_SIZE( MBEDTLS_OID_KEY_USAGE ), + buf, 4 ); + if( ret != 0 ) + return( ret ); + + return( 0 ); +} + +int mbedtls_x509write_csr_set_ns_cert_type( mbedtls_x509write_csr *ctx, + unsigned char ns_cert_type ) +{ + unsigned char buf[4]; + unsigned char *c; + int ret; + + c = buf + 4; + + if( ( ret = mbedtls_asn1_write_bitstring( &c, buf, &ns_cert_type, 8 ) ) != 4 ) + return( ret ); + + ret = mbedtls_x509write_csr_set_extension( ctx, MBEDTLS_OID_NS_CERT_TYPE, + MBEDTLS_OID_SIZE( MBEDTLS_OID_NS_CERT_TYPE ), + buf, 4 ); + if( ret != 0 ) + return( ret ); + + return( 0 ); +} + +int mbedtls_x509write_csr_der( mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + const char *sig_oid; + size_t sig_oid_len = 0; + unsigned char *c, *c2; + unsigned char hash[64]; + unsigned char sig[MBEDTLS_MPI_MAX_SIZE]; + unsigned char tmp_buf[2048]; + size_t pub_len = 0, sig_and_oid_len = 0, sig_len; + size_t len = 0; + mbedtls_pk_type_t pk_alg; + + /* + * Prepare data to be signed in tmp_buf + */ + c = tmp_buf + sizeof( tmp_buf ); + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_extensions( &c, tmp_buf, ctx->extensions ) ); + + if( len ) + { + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED | + MBEDTLS_ASN1_SEQUENCE ) ); + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED | + MBEDTLS_ASN1_SET ) ); + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( &c, tmp_buf, MBEDTLS_OID_PKCS9_CSR_EXT_REQ, + MBEDTLS_OID_SIZE( MBEDTLS_OID_PKCS9_CSR_EXT_REQ ) ) ); + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED | + MBEDTLS_ASN1_SEQUENCE ) ); + } + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED | + MBEDTLS_ASN1_CONTEXT_SPECIFIC ) ); + + MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_pk_write_pubkey_der( ctx->key, + tmp_buf, c - tmp_buf ) ); + c -= pub_len; + len += pub_len; + + /* + * Subject ::= Name + */ + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_names( &c, tmp_buf, ctx->subject ) ); + + /* + * Version ::= INTEGER { v1(0), v2(1), v3(2) } + */ + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, tmp_buf, 0 ) ); + + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED | + MBEDTLS_ASN1_SEQUENCE ) ); + + /* + * Prepare signature + */ + mbedtls_md( mbedtls_md_info_from_type( ctx->md_alg ), c, len, hash ); + + pk_alg = mbedtls_pk_get_type( ctx->key ); + if( pk_alg == MBEDTLS_PK_ECKEY ) + pk_alg = MBEDTLS_PK_ECDSA; + + if( ( ret = mbedtls_pk_sign( ctx->key, ctx->md_alg, hash, 0, sig, &sig_len, + f_rng, p_rng ) ) != 0 || + ( ret = mbedtls_oid_get_oid_by_sig_alg( pk_alg, ctx->md_alg, + &sig_oid, &sig_oid_len ) ) != 0 ) + { + return( ret ); + } + + /* + * Write data to output buffer + */ + c2 = buf + size; + MBEDTLS_ASN1_CHK_ADD( sig_and_oid_len, mbedtls_x509_write_sig( &c2, buf, + sig_oid, sig_oid_len, sig, sig_len ) ); + + if( len > (size_t)( c2 - buf ) ) + return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); + + c2 -= len; + memcpy( c2, c, len ); + + len += sig_and_oid_len; + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c2, buf, len ) ); + MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c2, buf, MBEDTLS_ASN1_CONSTRUCTED | + MBEDTLS_ASN1_SEQUENCE ) ); + + return( (int) len ); +} + +#define PEM_BEGIN_CSR "-----BEGIN CERTIFICATE REQUEST-----\n" +#define PEM_END_CSR "-----END CERTIFICATE REQUEST-----\n" + +#if defined(MBEDTLS_PEM_WRITE_C) +int mbedtls_x509write_csr_pem( mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size, + int (*f_rng)(void *, unsigned char *, size_t), + void *p_rng ) +{ + int ret; + unsigned char output_buf[4096]; + size_t olen = 0; + + if( ( ret = mbedtls_x509write_csr_der( ctx, output_buf, sizeof(output_buf), + f_rng, p_rng ) ) < 0 ) + { + return( ret ); + } + + if( ( ret = mbedtls_pem_write_buffer( PEM_BEGIN_CSR, PEM_END_CSR, + output_buf + sizeof(output_buf) - ret, + ret, buf, size, &olen ) ) != 0 ) + { + return( ret ); + } + + return( 0 ); +} +#endif /* MBEDTLS_PEM_WRITE_C */ + +#endif /* MBEDTLS_X509_CSR_WRITE_C */ diff --git a/security/mbedtls/src/xtea.c b/security/mbedtls/src/xtea.c new file mode 100644 index 0000000000..fe0a3509f6 --- /dev/null +++ b/security/mbedtls/src/xtea.c @@ -0,0 +1,281 @@ +/* + * An 32-bit implementation of the XTEA algorithm + * + * Copyright (C) 2006-2015, 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is part of mbed TLS (https://tls.mbed.org) + */ + +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#if defined(MBEDTLS_XTEA_C) + +#include "mbedtls/xtea.h" + +#include + +#if defined(MBEDTLS_SELF_TEST) +#if defined(MBEDTLS_PLATFORM_C) +#include "mbedtls/platform.h" +#else +#include +#define mbedtls_printf printf +#endif /* MBEDTLS_PLATFORM_C */ +#endif /* MBEDTLS_SELF_TEST */ + +#if !defined(MBEDTLS_XTEA_ALT) + +/* Implementation that should never be optimized out by the compiler */ +static void mbedtls_zeroize( void *v, size_t n ) { + volatile unsigned char *p = v; while( n-- ) *p++ = 0; +} + +/* + * 32-bit integer manipulation macros (big endian) + */ +#ifndef GET_UINT32_BE +#define GET_UINT32_BE(n,b,i) \ +{ \ + (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ + | ( (uint32_t) (b)[(i) + 1] << 16 ) \ + | ( (uint32_t) (b)[(i) + 2] << 8 ) \ + | ( (uint32_t) (b)[(i) + 3] ); \ +} +#endif + +#ifndef PUT_UINT32_BE +#define PUT_UINT32_BE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) ); \ +} +#endif + +void mbedtls_xtea_init( mbedtls_xtea_context *ctx ) +{ + memset( ctx, 0, sizeof( mbedtls_xtea_context ) ); +} + +void mbedtls_xtea_free( mbedtls_xtea_context *ctx ) +{ + if( ctx == NULL ) + return; + + mbedtls_zeroize( ctx, sizeof( mbedtls_xtea_context ) ); +} + +/* + * XTEA key schedule + */ +void mbedtls_xtea_setup( mbedtls_xtea_context *ctx, const unsigned char key[16] ) +{ + int i; + + memset( ctx, 0, sizeof(mbedtls_xtea_context) ); + + for( i = 0; i < 4; i++ ) + { + GET_UINT32_BE( ctx->k[i], key, i << 2 ); + } +} + +/* + * XTEA encrypt function + */ +int mbedtls_xtea_crypt_ecb( mbedtls_xtea_context *ctx, int mode, + const unsigned char input[8], unsigned char output[8]) +{ + uint32_t *k, v0, v1, i; + + k = ctx->k; + + GET_UINT32_BE( v0, input, 0 ); + GET_UINT32_BE( v1, input, 4 ); + + if( mode == MBEDTLS_XTEA_ENCRYPT ) + { + uint32_t sum = 0, delta = 0x9E3779B9; + + for( i = 0; i < 32; i++ ) + { + v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]); + sum += delta; + v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]); + } + } + else /* MBEDTLS_XTEA_DECRYPT */ + { + uint32_t delta = 0x9E3779B9, sum = delta * 32; + + for( i = 0; i < 32; i++ ) + { + v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]); + sum -= delta; + v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]); + } + } + + PUT_UINT32_BE( v0, output, 0 ); + PUT_UINT32_BE( v1, output, 4 ); + + return( 0 ); +} + +#if defined(MBEDTLS_CIPHER_MODE_CBC) +/* + * XTEA-CBC buffer encryption/decryption + */ +int mbedtls_xtea_crypt_cbc( mbedtls_xtea_context *ctx, int mode, size_t length, + unsigned char iv[8], const unsigned char *input, + unsigned char *output) +{ + int i; + unsigned char temp[8]; + + if( length % 8 ) + return( MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH ); + + if( mode == MBEDTLS_XTEA_DECRYPT ) + { + while( length > 0 ) + { + memcpy( temp, input, 8 ); + mbedtls_xtea_crypt_ecb( ctx, mode, input, output ); + + for( i = 0; i < 8; i++ ) + output[i] = (unsigned char)( output[i] ^ iv[i] ); + + memcpy( iv, temp, 8 ); + + input += 8; + output += 8; + length -= 8; + } + } + else + { + while( length > 0 ) + { + for( i = 0; i < 8; i++ ) + output[i] = (unsigned char)( input[i] ^ iv[i] ); + + mbedtls_xtea_crypt_ecb( ctx, mode, output, output ); + memcpy( iv, output, 8 ); + + input += 8; + output += 8; + length -= 8; + } + } + + return( 0 ); +} +#endif /* MBEDTLS_CIPHER_MODE_CBC */ +#endif /* !MBEDTLS_XTEA_ALT */ + +#if defined(MBEDTLS_SELF_TEST) + +/* + * XTEA tests vectors (non-official) + */ + +static const unsigned char xtea_test_key[6][16] = +{ + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f }, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f }, + { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 } +}; + +static const unsigned char xtea_test_pt[6][8] = +{ + { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 }, + { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }, + { 0x5a, 0x5b, 0x6e, 0x27, 0x89, 0x48, 0xd7, 0x7f }, + { 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48 }, + { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }, + { 0x70, 0xe1, 0x22, 0x5d, 0x6e, 0x4e, 0x76, 0x55 } +}; + +static const unsigned char xtea_test_ct[6][8] = +{ + { 0x49, 0x7d, 0xf3, 0xd0, 0x72, 0x61, 0x2c, 0xb5 }, + { 0xe7, 0x8f, 0x2d, 0x13, 0x74, 0x43, 0x41, 0xd8 }, + { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 }, + { 0xa0, 0x39, 0x05, 0x89, 0xf8, 0xb8, 0xef, 0xa5 }, + { 0xed, 0x23, 0x37, 0x5a, 0x82, 0x1a, 0x8c, 0x2d }, + { 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41 } +}; + +/* + * Checkup routine + */ +int mbedtls_xtea_self_test( int verbose ) +{ + int i, ret = 0; + unsigned char buf[8]; + mbedtls_xtea_context ctx; + + mbedtls_xtea_init( &ctx ); + for( i = 0; i < 6; i++ ) + { + if( verbose != 0 ) + mbedtls_printf( " XTEA test #%d: ", i + 1 ); + + memcpy( buf, xtea_test_pt[i], 8 ); + + mbedtls_xtea_setup( &ctx, xtea_test_key[i] ); + mbedtls_xtea_crypt_ecb( &ctx, MBEDTLS_XTEA_ENCRYPT, buf, buf ); + + if( memcmp( buf, xtea_test_ct[i], 8 ) != 0 ) + { + if( verbose != 0 ) + mbedtls_printf( "failed\n" ); + + ret = 1; + goto exit; + } + + if( verbose != 0 ) + mbedtls_printf( "passed\n" ); + } + + if( verbose != 0 ) + mbedtls_printf( "\n" ); + +exit: + mbedtls_xtea_free( &ctx ); + + return( ret ); +} + +#endif /* MBEDTLS_SELF_TEST */ + +#endif /* MBEDTLS_XTEA_C */ diff --git a/security/plat_gen/lib/ARM968E-S/plat_gen.a b/security/plat_gen/lib/ARM968E-S/libplat_gen.a similarity index 89% rename from security/plat_gen/lib/ARM968E-S/plat_gen.a rename to security/plat_gen/lib/ARM968E-S/libplat_gen.a index acac43b22e..1d4fe5f148 100644 Binary files a/security/plat_gen/lib/ARM968E-S/plat_gen.a and b/security/plat_gen/lib/ARM968E-S/libplat_gen.a differ diff --git a/security/plat_gen/lib/Cortex-M4/libplat_gen.a b/security/plat_gen/lib/Cortex-M4/libplat_gen.a new file mode 100644 index 0000000000..60629a6cf6 Binary files /dev/null and b/security/plat_gen/lib/Cortex-M4/libplat_gen.a differ diff --git a/security/plat_gen/lib/linux/plat_gen.a b/security/plat_gen/lib/linux/libplat_gen.a similarity index 98% rename from security/plat_gen/lib/linux/plat_gen.a rename to security/plat_gen/lib/linux/libplat_gen.a index b8888fe0be..7d1b2e383e 100644 Binary files a/security/plat_gen/lib/linux/plat_gen.a and b/security/plat_gen/lib/linux/libplat_gen.a differ diff --git a/security/plat_gen/lib/xtensa/plat_gen.a b/security/plat_gen/lib/xtensa/libplat_gen.a similarity index 97% rename from security/plat_gen/lib/xtensa/plat_gen.a rename to security/plat_gen/lib/xtensa/libplat_gen.a index a418495834..94968fb9f4 100644 Binary files a/security/plat_gen/lib/xtensa/plat_gen.a and b/security/plat_gen/lib/xtensa/libplat_gen.a differ diff --git a/security/plat_gen/plat_gen.mk b/security/plat_gen/plat_gen.mk index 99f6618820..0f2156a8d6 100644 --- a/security/plat_gen/plat_gen.mk +++ b/security/plat_gen/plat_gen.mk @@ -4,5 +4,13 @@ $(NAME)_CFLAGS += -Wall -Werror -Os GLOBAL_INCLUDES += include -$(NAME)_PREBUILT_LIBRARY := lib/$(HOST_ARCH)/plat_gen.a +ifneq (,$(BINS)) +ifeq ($(MBEDTLS_SHARE),1) +$(NAME)_TYPE := framework&kernel +else +$(NAME)_TYPE := kernel +endif +endif + +$(NAME)_PREBUILT_LIBRARY := lib/$(HOST_ARCH)/libplat_gen.a diff --git a/security/prov/lib/ARM968E-S/libprov.a b/security/prov/lib/ARM968E-S/libprov.a new file mode 100644 index 0000000000..443b8c4f49 Binary files /dev/null and b/security/prov/lib/ARM968E-S/libprov.a differ diff --git a/security/prov/lib/ARM968E-S/prov.a b/security/prov/lib/ARM968E-S/prov.a deleted file mode 100644 index 13e83cffbd..0000000000 Binary files a/security/prov/lib/ARM968E-S/prov.a and /dev/null differ diff --git a/security/prov/lib/Cortex-M4/libprov.a b/security/prov/lib/Cortex-M4/libprov.a new file mode 100644 index 0000000000..92501a353d Binary files /dev/null and b/security/prov/lib/Cortex-M4/libprov.a differ diff --git a/security/prov/lib/linux/libprov.a b/security/prov/lib/linux/libprov.a new file mode 100644 index 0000000000..498165cc11 Binary files /dev/null and b/security/prov/lib/linux/libprov.a differ diff --git a/security/prov/lib/linux/prov.a b/security/prov/lib/linux/prov.a deleted file mode 100644 index a966a264fc..0000000000 Binary files a/security/prov/lib/linux/prov.a and /dev/null differ diff --git a/security/prov/lib/xtensa/libprov.a b/security/prov/lib/xtensa/libprov.a new file mode 100644 index 0000000000..957ed2aadf Binary files /dev/null and b/security/prov/lib/xtensa/libprov.a differ diff --git a/security/prov/lib/xtensa/prov.a b/security/prov/lib/xtensa/prov.a deleted file mode 100644 index 22e94190d4..0000000000 Binary files a/security/prov/lib/xtensa/prov.a and /dev/null differ diff --git a/security/prov/prov.mk b/security/prov/prov.mk index 46ff9f615e..b9a3486a0c 100644 --- a/security/prov/prov.mk +++ b/security/prov/prov.mk @@ -2,11 +2,19 @@ NAME := prov DEBUG := no +ifneq (,$(BINS)) +ifeq ($(MBEDTLS_SHARE),1) +$(NAME)_TYPE := framework&kernel +else +$(NAME)_TYPE := kernel +endif +endif + GLOBAL_INCLUDES += include $(NAME)_CFLAGS += -Wall -Werror -Os $(NAME)_COMPONENTS := plat_gen alicrypto libid2 libkm -$(NAME)_PREBUILT_LIBRARY := lib/$(HOST_ARCH)/prov.a +$(NAME)_PREBUILT_LIBRARY := lib/$(HOST_ARCH)/libprov.a diff --git a/security/tfs/lib/ARM968E-S/libtfs.a b/security/tfs/lib/ARM968E-S/libtfs.a index 34720560a0..7e17b80ab6 100644 Binary files a/security/tfs/lib/ARM968E-S/libtfs.a and b/security/tfs/lib/ARM968E-S/libtfs.a differ diff --git a/security/tfs/lib/ARM968E-S/libtfspal.a b/security/tfs/lib/ARM968E-S/libtfspal.a index 9189df69ec..f742fbc56d 100644 Binary files a/security/tfs/lib/ARM968E-S/libtfspal.a and b/security/tfs/lib/ARM968E-S/libtfspal.a differ diff --git a/security/tfs/lib/Cortex-M4/libtfs.a b/security/tfs/lib/Cortex-M4/libtfs.a index d10f9c48f0..007dae406c 100644 Binary files a/security/tfs/lib/Cortex-M4/libtfs.a and b/security/tfs/lib/Cortex-M4/libtfs.a differ diff --git a/security/tfs/lib/Cortex-M4/libtfspal.a b/security/tfs/lib/Cortex-M4/libtfspal.a new file mode 100644 index 0000000000..4f66dc9db1 Binary files /dev/null and b/security/tfs/lib/Cortex-M4/libtfspal.a differ diff --git a/security/tfs/lib/armhflinux/libtfs.a b/security/tfs/lib/armhflinux/libtfs.a index 3f1aba6cb2..c17936a6c3 100644 Binary files a/security/tfs/lib/armhflinux/libtfs.a and b/security/tfs/lib/armhflinux/libtfs.a differ diff --git a/security/tfs/lib/armhflinux/libtfspal.a b/security/tfs/lib/armhflinux/libtfspal.a new file mode 100644 index 0000000000..bcd23bd54e Binary files /dev/null and b/security/tfs/lib/armhflinux/libtfspal.a differ diff --git a/security/tfs/lib/linux/libtfs.a b/security/tfs/lib/linux/libtfs.a index fa1618beac..ac38196351 100644 Binary files a/security/tfs/lib/linux/libtfs.a and b/security/tfs/lib/linux/libtfs.a differ diff --git a/security/tfs/lib/xtensa/libtfs.a b/security/tfs/lib/xtensa/libtfs.a index 8d07e44848..4e65205bda 100644 Binary files a/security/tfs/lib/xtensa/libtfs.a and b/security/tfs/lib/xtensa/libtfs.a differ diff --git a/security/tfs/lib/xtensa/libtfspal.a b/security/tfs/lib/xtensa/libtfspal.a index 232a8be104..780a2c126b 100644 Binary files a/security/tfs/lib/xtensa/libtfspal.a and b/security/tfs/lib/xtensa/libtfspal.a differ diff --git a/test/testcase/aosapi/api_test/aos_event_test.c b/test/testcase/aosapi/api_test/aos_event_test.c new file mode 100644 index 0000000000..be5599ba7e --- /dev/null +++ b/test/testcase/aosapi/api_test/aos_event_test.c @@ -0,0 +1,271 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#include +#include + +#include +#include + +#include +#include + +#define EVENT_INIT_FLAG 0x0F0F0F0F +#define EVENT_FLAG_1 0x00000001 +#define EVENT_FLAG_2 0x01000F01 +#define EVENT_FLAG_3 0x000000F0 + +static aos_event_t event; +#ifdef MULTITASK_UNDER_SMP +static aos_task_t task1; +static aos_task_t task2; +static aos_sem_t sem; +#endif /* MULTITASK_UNDER_SMP */ + +static void CASE_aosapi_kernel_event_new_free() +{ + kstat_t ret; + + /* create event */ + + ret = aos_event_new(&event, EVENT_INIT_FLAG); + YUNIT_ASSERT_MSG(ret==(RHINO_SUCCESS), "ret=%d", ret); + + /* destory event */ + + aos_event_free(&event); + YUNIT_ASSERT_MSG(event.hdl==NULL, "ret=%d", 0); +} + +static void CASE_aosapi_kernel_event_op_and() +{ + kstat_t ret; + uint32_t actl_flags; + + /* create event */ + + ret = aos_event_new(&event, EVENT_INIT_FLAG); + YUNIT_ASSERT_MSG(ret==(RHINO_SUCCESS), "ret=%d", ret); + + /*the event now should has event flag value as EVENT_INIT_FLAG(0x0F0F0F0F) */ + + /* try to get flag EVENT_FLAG_1(0x00000001) with AND operation should success */ + ret = aos_event_get(&event, EVENT_FLAG_1, RHINO_AND, &actl_flags,AOS_NO_WAIT); + YUNIT_ASSERT_MSG(ret==(RHINO_SUCCESS), "ret=%d", ret); + + /* try to get flag EVENT_FLAG_2(0x01000F01) with AND operation should success */ + ret = aos_event_get(&event, EVENT_FLAG_2, RHINO_AND, &actl_flags, AOS_NO_WAIT); + YUNIT_ASSERT_MSG(ret==(RHINO_SUCCESS), "ret=%d", ret); + + /* try to get flag EVENT_FLAG_3(0x000000F0) with AND operation should fail */ + ret = aos_event_get(&event, EVENT_FLAG_3, RHINO_AND, &actl_flags, AOS_NO_WAIT); + YUNIT_ASSERT_MSG(ret!=(RHINO_SUCCESS), "ret=%d", ret); + + /* destory event */ + + aos_event_free(&event); + YUNIT_ASSERT_MSG(event.hdl==NULL, "ret=%d", 0); +} + +static void CASE_aosapi_kernel_event_op_andclear() +{ + kstat_t ret; + uint32_t actl_flags; + + /* create event */ + + ret = aos_event_new(&event, EVENT_INIT_FLAG); + YUNIT_ASSERT_MSG(ret==(RHINO_SUCCESS), "ret=%d", ret); + + /*the event now should has event flag value as EVENT_INIT_FLAG(0x0F0F0F0F) */ + + /* try to get flag EVENT_FLAG_1(0x00000001) with AND_CLEAR operation should success */ + ret = aos_event_get(&event, EVENT_FLAG_1, RHINO_AND_CLEAR, &actl_flags,AOS_NO_WAIT); + YUNIT_ASSERT_MSG(ret==(RHINO_SUCCESS), "ret=%d", ret); + + /* now the event should has flag 0x0F0F0F0E */ + + /* + * try to get flag EVENT_FLAG_2(0x01000F01) with AND_CLEAR operation should fail, + * because (0x0F0F0F0E & 0x01000F01) != 0x01000F01 + */ + ret = aos_event_get(&event, EVENT_FLAG_2, RHINO_AND, &actl_flags, AOS_NO_WAIT); + YUNIT_ASSERT_MSG(ret!=(RHINO_SUCCESS), "ret=%d", ret); + + /* now the event should still has flag 0x0F0F0F0E */ + + /* try to get flag EVENT_FLAG_3(0x000000F0) with AND operation should fail */ + ret = aos_event_get(&event, EVENT_FLAG_3, RHINO_AND, &actl_flags, AOS_NO_WAIT); + YUNIT_ASSERT_MSG(ret!=(RHINO_SUCCESS), "ret=%d", ret); + + /* destory event */ + + aos_event_free(&event); + YUNIT_ASSERT_MSG(event.hdl==NULL, "ret=%d", 0); +} + +static void CASE_aosapi_kernel_event_op_or() +{ + kstat_t ret; + uint32_t actl_flags; + + /* create event */ + + ret = aos_event_new(&event, EVENT_INIT_FLAG); + YUNIT_ASSERT_MSG(ret==(RHINO_SUCCESS), "ret=%d", ret); + + /*set event flag with OR operation */ + ret = aos_event_set(&event, EVENT_FLAG_1, RHINO_OR); + YUNIT_ASSERT_MSG(ret==(RHINO_SUCCESS), "ret=%d", ret); + + /*the event now should has event flag value as EVENT_INIT_FLAG|EVENT_FLAG_1 = 0x0F0F0F0F */ + + /* try to get flag EVENT_FLAG_1(0x00000001) with OR operation should success */ + ret = aos_event_get(&event, EVENT_FLAG_1, RHINO_OR, &actl_flags, AOS_NO_WAIT); + YUNIT_ASSERT_MSG(ret==(RHINO_SUCCESS), "ret=%d", ret); + + /* try to get flag EVENT_FLAG_2(0x01000F01) with OR operation should success */ + ret = aos_event_get(&event, EVENT_FLAG_2, RHINO_OR, &actl_flags, AOS_NO_WAIT); + YUNIT_ASSERT_MSG(ret==(RHINO_SUCCESS), "ret=%d", ret); + + /* try to get flag EVENT_FLAG_3(0x000000F0) with OR operation should fail */ + ret = aos_event_get(&event, EVENT_FLAG_3, RHINO_OR, &actl_flags, AOS_NO_WAIT); + YUNIT_ASSERT_MSG(ret!=(RHINO_SUCCESS), "ret=%d", ret); + + /* destory event */ + + aos_event_free(&event); + YUNIT_ASSERT_MSG(event.hdl==NULL, "ret=%d", 0); +} + +static void CASE_aosapi_kernel_event_op_orclear() +{ + kstat_t ret; + uint32_t actl_flags; + + /* create event */ + + ret = aos_event_new(&event, EVENT_INIT_FLAG); + YUNIT_ASSERT_MSG(ret==(RHINO_SUCCESS), "ret=%d", ret); + + /*the event now should has event flag value as EVENT_INIT_FLAG|EVENT_FLAG_1 = 0x0F0F0F0F */ + + /* try to get flag EVENT_FLAG_1(0x00000001) with OR_CLEAR operation should success */ + ret = aos_event_get(&event, EVENT_FLAG_1, RHINO_OR_CLEAR, &actl_flags,AOS_NO_WAIT); + YUNIT_ASSERT_MSG(ret==(RHINO_SUCCESS), "ret=%d", ret); + + /* now the event should has flag 0x0F0F0F0E*/ + + /* + * try to get flag EVENT_FLAG_2(0x01000F01) with OR_CLEAR operation should success, + * because (0x0F0F0F0E & 0x01000F01) > 0 + */ + ret = aos_event_get(&event, EVENT_FLAG_2, RHINO_OR_CLEAR, &actl_flags, AOS_NO_WAIT); + YUNIT_ASSERT_MSG(ret==(RHINO_SUCCESS), "ret=%d", ret); + + /* now the event should has flag 0x0E0F000E*/ + + /* try to get flag EVENT_FLAG_3(0x000000F0) with OR operation should fail */ + ret = aos_event_get(&event, EVENT_FLAG_3, RHINO_OR, &actl_flags, AOS_NO_WAIT); + YUNIT_ASSERT_MSG(ret!=(RHINO_SUCCESS), "ret=%d", ret); + + /* destory event */ + + aos_event_free(&event); + YUNIT_ASSERT_MSG(event.hdl==NULL, "ret=%d", 0); +} + +#ifdef MULTITASK_UNDER_SMP + +static void event_test_task1_entry(void* arg) +{ + kstat_t ret; + uint32_t actl_flags; + + /* try to get flag EVENT_FLAG_3(0x000000F0) with OR operation should fail */ + ret = aos_event_get(&event, EVENT_FLAG_3, RHINO_OR, &actl_flags, AOS_NO_WAIT); + YUNIT_ASSERT_MSG(ret!=(RHINO_SUCCESS), "ret=%d", ret); + + /* + * try to get flag EVENT_FLAG_3(0x000000F0) with OR operation should wait here, + * task2 will set the flags with 0x000000F0, and then task1 will continue + */ + ret = aos_event_get(&event, EVENT_FLAG_3, RHINO_OR, &actl_flags, AOS_WAIT_FOREVER); + YUNIT_ASSERT_MSG(ret==(RHINO_SUCCESS), "ret=%d", ret); + + /* give the samphore to let main task continue*/ + aos_sem_signal(&sem); + + /* exit self */ + aos_task_exit(0); +} + +static void event_test_task2_entry(void* arg) +{ + kstat_t ret; + + /*set event flag(0x000000F0) with OR operation, this will un-block task1 */ + + ret = aos_event_set(&event, EVENT_FLAG_3, RHINO_OR); + YUNIT_ASSERT_MSG(ret==(RHINO_SUCCESS), "ret=%d", ret); + + /* exit self */ + aos_task_exit(0); +} + +static void CASE_aosapi_kernel_event_op_multask(void) +{ + kstat_t ret; + + /* create event */ + + ret = aos_event_new(&event, EVENT_INIT_FLAG); + YUNIT_ASSERT_MSG(ret==(RHINO_SUCCESS), "ret=%d", ret); + + /*create a semphore which will be used for sync multi-task*/ + ret = aos_sem_new(&sem, 0); + YUNIT_ASSERT_MSG(ret==(RHINO_SUCCESS), "ret=%d", ret); + + /*the event now should has event flag value as EVENT_INIT_FLAG = 0x0F0F0F0F */ + + /* create task1 */ + + ret = aos_task_new_ext(&task1, "event_test_task1", event_test_task1_entry, + 0, 4096, AOS_DEFAULT_APP_PRI); + YUNIT_ASSERT_MSG(ret==(RHINO_SUCCESS), "ret=%d", ret); + + /* create task2, which has a lower pri then task1, this make sure task1 will run first */ + + ret = aos_task_new_ext(&task2, "event_test_task2", event_test_task2_entry, + 0, 4096, AOS_DEFAULT_APP_PRI+1); + YUNIT_ASSERT_MSG(ret==(RHINO_SUCCESS), "ret=%d", ret); + + /* wait for task1 to give samphore */ + ret = aos_sem_wait(&sem, AOS_WAIT_FOREVER); + YUNIT_ASSERT_MSG(ret==(RHINO_SUCCESS), "ret=%d", ret); + + /* destory samphore */ + aos_sem_free(&sem); + + /* destory event */ + + aos_event_free(&event); + YUNIT_ASSERT_MSG(event.hdl==NULL, "ret=%d", 0); +} + +#endif /* MULTITASK_UNDER_SMP */ + +void aosapi_kernel_event_test_entry(yunit_test_suite_t *suite) +{ + yunit_add_test_case(suite, "kernel.event.new_free", CASE_aosapi_kernel_event_new_free); + yunit_add_test_case(suite, "kernel.event.op_and", CASE_aosapi_kernel_event_op_and); + yunit_add_test_case(suite, "kernel.event.op_andclear", CASE_aosapi_kernel_event_op_andclear); + yunit_add_test_case(suite, "kernel.event.op_or", CASE_aosapi_kernel_event_op_or); + yunit_add_test_case(suite, "kernel.event.op_orclear", CASE_aosapi_kernel_event_op_orclear); +#ifdef MULTITASK_UNDER_SMP + yunit_add_test_case(suite, "kernel.event.op_multask", CASE_aosapi_kernel_event_op_multask); +#endif +} + + diff --git a/test/testcase/aosapi/api_test/aos_mutex_test.c b/test/testcase/aosapi/api_test/aos_mutex_test.c index 2bd61f8318..d0d01ab68a 100644 --- a/test/testcase/aosapi/api_test/aos_mutex_test.c +++ b/test/testcase/aosapi/api_test/aos_mutex_test.c @@ -31,7 +31,7 @@ static void CASE_aosapi_kernel_mutex_param() #if 0 // FIXME: null pointer:coredump - ret = aos_mutex_lock(NULL, RHINO_WAIT_FOREVER); + ret = aos_mutex_lock(NULL, AOS_WAIT_FOREVER); YUNIT_ASSERT_MSG(ret==RHINO_NULL_PTR, "ret=%d", ret); #endif @@ -53,7 +53,7 @@ void TASK_aosapi_kernel_mutex_lock1(void *arg) int ret; int *pflag = (int*)arg; for(int i=0; i + +#include "cutest/cut.h" + +#define QUEUE_BUF_SIZE (64) + +static unsigned int g_var = 0; +static aos_sem_t g_sem_taskexit_sync; +static aos_mutex_t g_mutex; +static aos_sem_t g_sem; +static aos_queue_t g_queue; +static aos_timer_t g_timer; + +static char queue_buf[QUEUE_BUF_SIZE]; +static aos_queue_t g_queue1; +static char queue1_buf[QUEUE_BUF_SIZE]; +static aos_queue_t g_queue2; +static char queue2_buf[QUEUE_BUF_SIZE]; +static aos_queue_t g_queue3; +static char queue3_buf[QUEUE_BUF_SIZE]; + + +CASE(test_mm, aos_1_001) +{ + unsigned int size = 512; + unsigned char *ptr = NULL; + + ptr = aos_malloc(size); + ASSERT_NOT_NULL(ptr); + + aos_free(ptr); +} + +CASE(test_mm, aos_1_002) +{ + unsigned int size = 512; + unsigned char *ptr = NULL; + int i = 0; + + ptr = aos_zalloc(size); + ASSERT_NOT_NULL(ptr); + + for (; i g_queue2 */ +static void task8(void *arg) +{ + int msg = -1; + unsigned int size = 0; + + while(1) { + aos_queue_recv(&g_queue1, -1, &msg, &size); + aos_queue_send(&g_queue2, &msg, size); + if(msg == TEST_CONFIG_SYNC_TIMES) { + break; + } + } + printf("%s exit!\n", aos_task_name()); + aos_task_exit(0); +} + +/* task: g_queue2 -> g_queue3 */ +static void task9(void *arg) +{ + int msg = -1; + unsigned int size = 0; + + while(1) { + aos_queue_recv(&g_queue2, -1, &msg, &size); + aos_queue_send(&g_queue3, &msg, size); + if(msg == TEST_CONFIG_SYNC_TIMES) { + break; + } + } + printf("%s exit!\n", aos_task_name()); + aos_task_exit(0); +} + +CASE(test_task, aos_1_006) +{ + unsigned int stack_size = 1024; + int ret = -1; + + aos_sem_new(&g_sem_taskexit_sync, 0); + + ret = aos_task_new("task1", task1, NULL, stack_size); + ASSERT_EQ(ret, 0); + + aos_sem_wait(&g_sem_taskexit_sync, -1); + printf("task1 exit!\n"); + + aos_sem_free(&g_sem_taskexit_sync); +} + +CASE(test_task, aos_1_007) +{ + unsigned int stack_size = 1024; + aos_task_t task; + int ret = -1; + + aos_sem_new(&g_sem_taskexit_sync, 0); + + ret = aos_task_new_ext(&task, "task1", task1, NULL, stack_size, 10); + ASSERT_EQ(ret, 0); + + aos_sem_wait(&g_sem_taskexit_sync, -1); + printf("task1 exit!\n"); + + aos_sem_free(&g_sem_taskexit_sync); +} + +CASE(test_task, aos_1_008) +{ + unsigned int stack_size = 1024; + int ret = -1; + + aos_sem_new(&g_sem_taskexit_sync, 0); + + ret = aos_task_new("task2", task2, NULL, stack_size); + ASSERT_EQ(ret, 0); + + aos_sem_wait(&g_sem_taskexit_sync, -1); + printf("task2 exit!\n"); + + aos_sem_free(&g_sem_taskexit_sync); +} + +CASE(test_task, aos_1_009) +{ + unsigned int stack_size = 1024; + int ret = -1; + + aos_sem_new(&g_sem_taskexit_sync, 0); + + ret = aos_task_new("task2", task2, NULL, stack_size); + ASSERT_EQ(ret, 0); + + aos_sem_wait(&g_sem_taskexit_sync, -1); + printf("task2 exit!\n"); + + aos_sem_free(&g_sem_taskexit_sync); +} + +CASE(test_task, aos_1_010) +{ + unsigned int stack_size = 1024; + int ret = -1; + + aos_sem_new(&g_sem_taskexit_sync, 0); + + ret = aos_task_new("task3", task3, NULL, stack_size); + ASSERT_EQ(ret, 0); + + aos_sem_wait(&g_sem_taskexit_sync, -1); + printf("task3 exit!\n"); + + aos_sem_free(&g_sem_taskexit_sync); +} + +CASE(test_task, aos_1_011) +{ + unsigned int stack_size = 512; + char task_name[10] = {0}; + int ret = -1; + int i = 0; + + aos_sem_new(&g_sem_taskexit_sync, 0); + + for(i=0; i +CASE(test_kv, aos_2_001) +{ + char *key = "test_kv_key"; + char *set_value = "test_kv_value"; + int set_len = strlen(set_value); + char get_value[32] = {0}; + int get_len = 32; + int ret = -1; + + ret = aos_kv_set(key, set_value, set_len, 1); + ASSERT_EQ(ret, 0); + + ret = aos_kv_get(key, get_value, &get_len); + ASSERT_EQ(ret, 0); + ASSERT_EQ(get_len, set_len); + ASSERT_STR_EQ(get_value, set_value); +} + +CASE(test_kv, aos_2_002) +{ + char *key = "test_kv_key"; + char *set_value = "test_kv_value"; + int set_len = strlen(set_value); + char get_value[32] = {0}; + int get_len = 32; + int ret = -1; + + aos_kv_del(key); + + ret = aos_kv_set(key, set_value, set_len, 1); + ASSERT_EQ(ret, 0); + + ret = aos_kv_del(key); + ASSERT_EQ(ret, 0); + + ret = aos_kv_get(key, get_value, &get_len); + ASSERT_NE(ret, 0); +} + +CASE(test_kv, aos_2_003) +{ + char key[64] = {0}; + char set_value[64] = {0}; + int set_len = 0; + char get_value[64] = {0}; + int get_len = 0; + int ret = -1; + int i = 0; + + + while(i++ < TEST_CONFIG_KV_TIMES) { + memset(key, 0, sizeof(key)); + memset(set_value, 0, sizeof(set_value)); + memset(get_value, 0, sizeof(get_value)); + + sprintf(key, "this_is_key_%d", i); + sprintf(set_value, "this_is_value_%d", i); + set_len = strlen(set_value); + ret = aos_kv_set(key, set_value, set_len, 1); + ASSERT_EQ(ret, 0); + + get_len = sizeof(get_value); + ret = aos_kv_get(key, get_value, &get_len); + ASSERT_EQ(ret, 0); + ASSERT_EQ(get_len, set_len); + ASSERT_TRUE(0 == memcmp(get_value, set_value, set_len)); + + ret = aos_kv_del(key); + ASSERT_EQ(ret, 0); + + if(i%100 == 0) { + printf("kv test: %d/%d\n", i, TEST_CONFIG_KV_TIMES); + } + aos_msleep(1); + } +} + +/* kv test suite */ +SUITE(test_kv) = { + ADD_CASE(test_kv, aos_2_001), + ADD_CASE(test_kv, aos_2_002), + ADD_CASE(test_kv, aos_2_003), + ADD_CASE_NULL +}; +#endif + +#ifdef TEST_CONFIG_YLOOP_ENABLED +#include +#define EV_USER_TYPE1 (EV_USER+1) +#define EV_USER_TYPE2 (EV_USER+2) + +static void ev_callback1(input_event_t *event, void *private_data) +{ + printf("ev_callback1 is called\n"); + g_var = 0x5A; + aos_loop_exit(); +} + +static void delayed_action1(void *arg) +{ + g_var++; + printf("delayed_action1 called, %d\n", g_var); + aos_post_delayed_action(1000, delayed_action1, NULL); + aos_cancel_delayed_action(1000, delayed_action1, NULL); +} + +static void delayed_action2(void *arg) +{ + g_var++; + printf("delayed_action2 called, %d\n", g_var); + aos_loop_exit(); +} + +static void delayed_action3(void *arg) +{ + g_var++; +} + +static void task_loop1(void *arg) +{ + int ret = -1; + aos_loop_t loop = NULL; + + g_var = 0; + printf("task name: %s\n", aos_task_name()); + + loop = aos_loop_init(); + if (loop == NULL) { + g_var = -1; + aos_sem_signal(&g_sem_taskexit_sync); + aos_task_exit(-1); + } + + ret = aos_post_delayed_action(200, delayed_action2, NULL); + if(ret != 0) { + g_var = -2; + aos_sem_signal(&g_sem_taskexit_sync); + aos_task_exit(-2); + } + + aos_loop_run(); + aos_loop_destroy(); + aos_sem_signal(&g_sem_taskexit_sync); + aos_task_exit(0); +} + +CASE(test_yloop, aos_2_004) +{ + int ret = -1; + g_var = 0; + + ret = aos_register_event_filter(EV_USER_TYPE1, ev_callback1, NULL); + ASSERT_EQ(ret, 0); + + ret = aos_post_event(EV_USER_TYPE1, 0, 0); + // ASSERT_EQ(ret, 0); + + aos_loop_run(); + aos_unregister_event_filter(EV_USER_TYPE1, ev_callback1, NULL); + ASSERT_EQ(g_var, 0x5A); +} + +CASE(test_yloop, aos_2_005) +{ + int ret = -1; + g_var = 0; + + ret = aos_post_delayed_action(500, delayed_action1, NULL); + ASSERT_EQ(ret, 0); + + ret = aos_post_delayed_action(3000, delayed_action2, NULL); + ASSERT_EQ(ret, 0); + + aos_loop_run(); + ASSERT_EQ(g_var, 2); +} + +CASE(test_yloop, aos_2_006) +{ + int ret = -1; + int stack_size = 1024; + + g_var = 0; + ret = aos_sem_new(&g_sem_taskexit_sync, 0); + ASSERT_EQ(ret, 0); + + ret = aos_task_new("task_loop1", task_loop1, NULL, stack_size); + ASSERT_EQ(ret, 0); + + aos_sem_wait(&g_sem_taskexit_sync, 1000); + ASSERT_EQ(g_var, 1); + + aos_sem_free(&g_sem_taskexit_sync); +} + +CASE(test_yloop, aos_2_007) +{ + int ret = -1; + g_var = 0; + + ret = aos_post_delayed_action(200, delayed_action2, NULL); + ASSERT_EQ(ret, 0); + + aos_loop_run(); + ASSERT_EQ(g_var, 1); +} + +CASE(test_yloop, aos_2_008) +{ + int ret = -1; + int i = 0; + g_var = 0; + + for(i=0; isname, argv[1]))) || + (argc==3 && (NULL==strstr(c->sname, argv[1]) || NULL==strstr(c->cname, argv[2])))) { + cut.clist[i]->skip = 1; + cut.ccnt_skip++; + } + } +} + +static void usage(const char* me) +{ + cut_printf("Usage: %s [OPTION] [SUITE] [CASE]\n\n" \ + "OPTION:\n" \ + " --help : print this help\n" \ + " --list : list cases\n" \ + " --count : print case count\n" \ + " SUITE : suite name filter, e.g. '%s all' means run all suites\n" \ + " CASE : case name filter\n", me, me); +} + +static int parse_arg(int argc, char** argv) +{ + if (argc >= 2) { + if (0 == strcmp(argv[1], "--list")) { + int i = 0; + int cnt = 0; + cut_printf("\33[1;34mCASE_LIST_BEGIN\n"); + for(i=0; isname, argv[2])) || + (argc==4 && NULL!=strstr(c->sname, argv[2]) && NULL!=strstr(c->cname, argv[3]))) + cut_printf("\33[1;34m[%02d] %s.%s\33[0m\n", ++cnt, c->sname, c->cname); + } + cut_printf("\33[1;34mCASE_LIST_END\n"); + return 0; + } + if (0 == strcmp(argv[1], "--count")) { + cut_printf("total %d case(s).\n", cut.ccnt_total); + return 0; + } + if (0 == strcmp(argv[1], "--help")) { + usage(argv[0]); + return 0; + } + } + return 1; +} + +static void cut_result_report(struct cut_runtime *cut) +{ + int i = 0; + + /* print test result locally */ + cut_printf("===========================================================================\n"); + if (cut->ccnt_fail > 0) { + cut_printf("FAIL LIST:\n"); + for (i = 0; i < cut->ccnt_fail; i++) { + cut_printf(" [%02d] %s\n", i + 1, cut->cerrmsg[i]); + cut_free(cut->cerrmsg[i]); + } + cut_printf("---------------------------------------------------------------------------\n"); + } + cut_printf("SUMMARY:\n" \ + " TOTAL: %d\n" \ + " SKIPPED: %d\n" \ + " MATCHED: %d\n" \ + " PASS: %d\n" \ + " FAILED: %d\n", cut->ccnt_total, cut->ccnt_skip, + cut->ccnt_total-cut->ccnt_skip, cut->ccnt_pass, cut->ccnt_fail); + cut_printf("===========================================================================\n"); +} + + +int cut_main(int argc, char** argv) +{ + int i = 0, cnt = 0; + char *_argv[2] = {"None", "--list"}; + + cut.ccnt_pass = 0; + cut.ccnt_fail = 0; + cut.ccnt_skip = 0; + for(i=0; iskip = 0; + cut.clist[i]->flag = 1; + } + + if (0 == parse_arg(argc, argv)) + return 0; + + parse_arg(2, _argv); + + filter(argc, argv); + + for(i=0; i < cut.ccnt_total; i++) { + cut.ccur = cut.clist[i]; + if (cut.ccur->skip) + continue; + + cut_printf("\33[1;33mTEST [%d/%d] %s.%s...\33[0m\n", + ++cnt, cut.ccnt_total-cut.ccnt_skip, cut.ccur->sname, cut.ccur->cname); + if (cut.ccur->setup) + cut.ccur->setup(cut.ccur->data); + cut.ccur->run((struct cut_case *)(cut.ccur->data)); + if (cut.ccur->teardown) + cut.ccur->teardown(cut.ccur->data); + if (cut.ccur->flag) { + cut_printf("\33[1;32m[OK]\33[0m\n\n"); + cut.ccnt_pass++; + } + else { + cut_printf("\33[1;31m[FAIL]: %s\33[0m\n\n", cut.cerrmsg[cut.ccnt_fail]); + cut.ccnt_fail++; + } + } + cut_result_report(&cut); + return cut.ccnt_fail; +} + diff --git a/test/testcase/certificate_test/cutest/cut.h b/test/testcase/certificate_test/cutest/cut.h new file mode 100644 index 0000000000..cbfaeefd3d --- /dev/null +++ b/test/testcase/certificate_test/cutest/cut.h @@ -0,0 +1,226 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#ifndef __CUT_H__ +#define __CUT_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include +#include +#include + +#define cut_printf printf +#define cut_snprintf snprintf +#define cut_malloc malloc +#define cut_free free + +#define CUT_CASE_MAX_CNT (32) +#define CUT_MSG_MAX_LEN (64) + +extern int cut_main(int argc, char** argv); +extern struct cut_runtime cut; + +struct cut_case { + const char* sname; + const char* cname; + void *data; + void (*run)(void*); + void (*setup)(void*); + void (*teardown)(void*); + int skip; + int flag; +}; + +struct cut_runtime { + int scnt_total; + int ccnt_total; + int ccnt_pass; + int ccnt_fail; + int ccnt_skip; + struct cut_case *clist[CUT_CASE_MAX_CNT]; + struct cut_case *ccur; + char *cerrmsg[CUT_CASE_MAX_CNT]; +}; + +#define CUT_CASE_RUNNER(sname, cname) cut_##sname##_##cname##_run +#define CUT_CASE_NAME(sname, cname) cut_##sname##_##cname +#define CUT_CASE_DATA(sname) cut_##sname##_data +#define CUT_CASE_SETUP(sname) cut_##sname##_setup +#define CUT_CASE_TEARDOWN(sname) cut_##sname##_teardown + +#define DATA(sname) \ +struct CUT_CASE_DATA(sname) + +#define SETUP(sname) \ +static void CUT_CASE_SETUP(sname)(struct CUT_CASE_DATA(sname) *data) + +#define TEARDOWN(sname) \ +static void CUT_CASE_TEARDOWN(sname)(struct CUT_CASE_DATA(sname) *data) + + +/* + * @brief: construct a test case structor and a test case runner + * @sname: suite name + * @cname: case name + * e.g. + CASE(mysuite, mycase1) { + // do something here + ASSERT_TRUE(1); + } + */ +#define CASE(sname, cname) \ + static void CUT_CASE_RUNNER(sname, cname)(void *null); \ + static struct cut_case CUT_CASE_NAME(sname, cname) = { \ + #sname, #cname, NULL, CUT_CASE_RUNNER(sname, cname), NULL, NULL, 0}; \ + static void CUT_CASE_RUNNER(sname, cname)(void *null) + +/* + * @brief: construct a test case structor and a test case runner + * with case_data/setup/teardown for each case. + * @sname: suite name + * @cname: case name + * e.g. + DATA(mysuite) { + int errmsg; + char *errcode; + }; + + SETUP(mysuite) { + data->errcode = 0; + data->errmsg = (char*)malloc(100); + } + + TEARDOWN(mysuite) { + if(data->errmsg) { + free(data->errmsg); + data->errmsg = NULL; + } + } + + CASE2(mysuite, mycase1) { + data->errcode = 1; + strcpy(data->errmsg, "timeout error"); + ASSERT_TRUE(1); + } + */ +#define CASE2(sname, cname) \ + static struct CUT_CASE_DATA(sname) CUT_CASE_DATA(sname); \ + static void CUT_CASE_RUNNER(sname, cname)(struct CUT_CASE_DATA(sname) * data); \ + static struct cut_case CUT_CASE_NAME(sname, cname) = { \ + #sname, #cname, &CUT_CASE_DATA(sname), (void(*)(void*))CUT_CASE_RUNNER(sname, cname), \ + (void(*)(void*))CUT_CASE_SETUP(sname), (void(*)(void*))CUT_CASE_TEARDOWN(sname), 0}; \ + static void CUT_CASE_RUNNER(sname, cname)(struct CUT_CASE_DATA(sname) * data) + +/* + * @brief: construct a test suite by adding test case(s) + * @sname: suite name + * e.g. + SUITE(mysuite) = { + ADD_CASE(mysuite, mycase1), + ADD_CASE(mysuite, mycase2), + ADD_CASE_NULL + }; + */ +#define SUITE(sname) struct cut_case *cut_suite_##sname[] + +/* + * @brief: add a test case into a test suite + * @sname: suite name + * @cname: case name + */ +#define ADD_CASE(sname, cname) &CUT_CASE_NAME(sname, cname) +#define ADD_CASE_NULL (struct cut_case*)(NULL) + +/* + * @brief: add a test suite into case list + * @sname: suite name + */ +#define ADD_SUITE(sname) \ + do { \ + int i = 0; \ + extern struct cut_case *cut_suite_##sname[]; \ + struct cut_case *c = cut_suite_##sname[i]; \ + if (cut.ccnt_total >= CUT_CASE_MAX_CNT) { \ + cut_printf("reaches maximum case count:%d\n", \ + CUT_CASE_MAX_CNT); \ + break; \ + } \ + while (c) { \ + *(cut.clist + cut.ccnt_total++) = c; \ + c = *(cut_suite_##sname + (++i)); \ + } \ + } while (0) + + +#define TRY //if(0==setjmp(cut.jmpbuf)) +#define EXCEPT //else +#define RAISE_EXCEPTION_WITH_MSG(msg) \ + do \ + { \ + int ret = 0, i = cut.ccnt_fail; \ + cut.cerrmsg[i] = (char *)cut_malloc(CUT_MSG_MAX_LEN); \ + assert(cut.cerrmsg[i] != NULL); \ + memset(cut.cerrmsg[i], 0, CUT_MSG_MAX_LEN); \ + ret = cut_snprintf(cut.cerrmsg[i], \ + CUT_MSG_MAX_LEN - 1, \ + "%s.%s in %s(%d) expected %s", \ + cut.ccur->sname, cut.ccur->cname, \ + __FILE__, __LINE__, msg); \ + if (ret >= CUT_MSG_MAX_LEN) \ + cut_snprintf(cut.cerrmsg[i] + CUT_MSG_MAX_LEN - 4, \ + 4, "..."); \ + cut.ccur->flag = 0; \ + return; \ + } while (0) + +#define ASSERT_TRUE(cond) \ + do { \ + if (!(cond)) \ + RAISE_EXCEPTION_WITH_MSG("[True]"); \ + } while (0) + +#define ASSERT_INT(expected, compare, actual) \ + do { \ + if (!((expected)compare(actual))) \ + RAISE_EXCEPTION_WITH_MSG("[" #expected " " #compare " " #actual "]"); \ + } while (0) + +#define ASSERT_STR(expected, compare, actual) \ + do { \ + if (!(strcmp((expected), (actual)) compare 0)) \ + RAISE_EXCEPTION_WITH_MSG("[" #expected " " #compare " " #actual "]"); \ + } while (0) + +#define ASSERT_IN(expected1, actual, expected2) \ + do { \ + if ((actual) < (expected1) || (actual) > (expected2)) \ + RAISE_EXCEPTION_WITH_MSG("[" #expected1 " <= " #actual " <=" #expected2); \ + } while (0) + +#define ASSERT_FAIL() RAISE_EXCEPTION_WITH_MSG("[should not be here]") +#define ASSERT_FALSE(cond) ASSERT_TRUE(!(cond)) +#define ASSERT_NULL(ptr) ASSERT_INT(ptr, ==, NULL) +#define ASSERT_NOT_NULL(ptr) ASSERT_INT(ptr, !=, NULL) +#define ASSERT_EQ(actual, expected) ASSERT_INT(actual, ==, expected) +#define ASSERT_NE(actual, expected) ASSERT_INT(actual, !=, expected) +#define ASSERT_GT(actual, expected) ASSERT_INT(actual, >, expected) +#define ASSERT_GE(actual, expected) ASSERT_INT(actual, >=, expected) +#define ASSERT_LT(actual, expected) ASSERT_INT(actual, <, expected) +#define ASSERT_LE(actual, expected) ASSERT_INT(actual, <=, expected) +#define ASSERT_STR_EQ(actual, expected) ASSERT_STR(actual, ==, expected) +#define ASSERT_STR_NE(actual, expected) ASSERT_STR(actual, !=, expected) +#define ASSERT_STR_GT(actual, expected) ASSERT_STR(actual, >, expected) +#define ASSERT_STR_LT(actual, expected) ASSERT_STR(actual, <, expected) + +#ifdef __cplusplus +} +#endif + +#endif /* __CUT_H__ */ + diff --git a/test/testcase/framework/uData_test/uData_test.c b/test/testcase/framework/uData_test/uData_test.c new file mode 100644 index 0000000000..3aa4df2dea --- /dev/null +++ b/test/testcase/framework/uData_test/uData_test.c @@ -0,0 +1,358 @@ +/* + * Copyright (C) 2015-2017 Alibaba Group Holding Limited + */ + +#include +#include + +#include +#include +#include + +#include "yunit.h" + +#include "hal/soc/soc.h" + +#define UDATA_SUCCES 0 + +static int uData_sensor_open(inode_t *node, file_t *file); +static int uData_sensor_close(file_t *file); +static ssize_t uData_sensor_read(file_t *f, void *buf, size_t len); +static ssize_t uData_sensor_write(file_t *f, const void *buf, size_t len); +static int uData_sensor_ioctl(file_t *f, int cmd, unsigned long arg); + +file_ops_t uData_sensor_fops = { + .open = uData_sensor_open, + .close = uData_sensor_close, + .read = uData_sensor_read, + .write = uData_sensor_write, + .ioctl = uData_sensor_ioctl, +}; + +static sensor_obj_t *g_sensor_obj[TAG_DEV_SENSOR_NUM_MAX]; +static uint32_t g_sensor_cnt = 0; + +static int drv_virtual_sensor_open(void) +{ + return 0; + +} + +static int drv_virtual_sensor_close(void) +{ + return 0; +} + + +static int drv_virtual_sensor_read(void *buf, size_t len) +{ + return 0; +} + +static int drv_virtual_sensor_ioctl(int cmd, unsigned long arg) +{ + return 0; +} + +int drv_virtual_sensor_init(void){ + int ret = 0; + sensor_obj_t sensor; + + /* fill the sensor obj parameters here */ + sensor.tag = TAG_DEV_BARO; + sensor.path = dev_baro_path; + sensor.io_port = I2C_PORT; + sensor.open = drv_virtual_sensor_open; + sensor.close = drv_virtual_sensor_close; + sensor.read = drv_virtual_sensor_read; + sensor.write = NULL; + sensor.ioctl = drv_virtual_sensor_ioctl; + sensor.irq_handle = NULL; + + ret = uData_sensor_create_obj(&sensor); + if(unlikely(ret)){ + return -1; + } + + LOG("%s %s successfully \n", SENSOR_STR, __func__); + return 0; +} + + +static int uData_find_selected_sensor(char* path ) +{ + int i = 0; + + if(path == NULL){ + return -1; + } + + for(i = 0; i < g_sensor_cnt; i++){ + if(strncmp(g_sensor_obj[i]->path, path, strlen(path)) == 0){ + return i; + } + } + return -1; +} +static int uData_load_sensor_config(int index ) +{ + int ret = 0; + g_sensor_obj[index] = (sensor_obj_t*)aos_malloc(sizeof(sensor_obj_t)); + if(g_sensor_obj[index] == NULL){ + return -1; + } + + return 0; +} + +static int uData_sensor_obj_register(int index ) +{ + int ret = 0; + ret = aos_register_driver(g_sensor_obj[index]->path, &uData_sensor_fops, NULL); + if (ret != 0) { + return -1; + } + + return 0; +} + +int uData_sensor_create_obj(sensor_obj_t* sensor) +{ + int ret = 0; + + g_sensor_obj[g_sensor_cnt] = (sensor_obj_t*)aos_malloc(sizeof(sensor_obj_t)); + if(g_sensor_obj[g_sensor_cnt] == NULL){ + return -1; + } + memset(g_sensor_obj[g_sensor_cnt], 0, sizeof(sensor_obj_t)); + + /* install the phy sensor info into the sensor object datebase here */ + g_sensor_obj[g_sensor_cnt]->io_port = sensor->io_port; + g_sensor_obj[g_sensor_cnt]->path = sensor->path; + g_sensor_obj[g_sensor_cnt]->tag = sensor->tag; + g_sensor_obj[g_sensor_cnt]->open = sensor->open; + g_sensor_obj[g_sensor_cnt]->close = sensor->close; + g_sensor_obj[g_sensor_cnt]->ioctl = sensor->ioctl; + g_sensor_obj[g_sensor_cnt]->read = sensor->read; + g_sensor_obj[g_sensor_cnt]->write = sensor->write; + g_sensor_obj[g_sensor_cnt]->irq_handle = sensor->irq_handle; + g_sensor_obj[g_sensor_cnt]->mode = sensor->mode; + g_sensor_obj[g_sensor_cnt]->bus = sensor->bus; + g_sensor_obj[g_sensor_cnt]->power = DEV_POWER_OFF; // will update the status later + + /* register the sensor object into the irq list and vfs */ + ret = uData_sensor_obj_register(g_sensor_cnt); + if (ret != 0) { + goto error; + } + + g_sensor_cnt++; + return 0; + +error: + free(g_sensor_obj[g_sensor_cnt]); + return -1; +} + +static int uData_sensor_hal_get_dev_list(void* buf) +{ + sensor_list_t* list = buf; + if(buf == NULL) + return -1; + + /* load the sensor count and tag list here */ + list->cnt = g_sensor_cnt; + for(int index = 0; index < g_sensor_cnt; index++){ + list->list[index] = g_sensor_obj[index]->tag; + } + + return 0; +} + +static int uData_sensor_open(inode_t *node, file_t *file) +{ + int index = 0; + + if((node == NULL)||(file == NULL)){ + return -1; + } + + + /* just open the /dev/sensor node here */ + if(strncmp(sensor_node_path, node->i_name, strlen(node->i_name)) == 0){ + return 0; + } + + index = uData_find_selected_sensor(node->i_name); + if(( g_sensor_obj[index]->open == NULL)||(index < 0)){ + return -1; + } + + g_sensor_obj[index]->open(); + return 0; +} + +static int uData_sensor_close(file_t *file) +{ + int index = 0; + + /* just close the /dev/sensor node here */ + if(strncmp(sensor_node_path, (file->node->i_name), strlen(file->node->i_name)) == 0){ + return 0; + } + + index = uData_find_selected_sensor(file->node->i_name); + if(( g_sensor_obj[index]->close == NULL)||(index < 0)){ + return -1; + } + g_sensor_obj[index]->close(); + return 0; +} + +static ssize_t uData_sensor_read(file_t *f, void *buf, size_t len) +{ + int index = 0; + int ret = 0; + + if(f == NULL){ + return -1; + } + + index = uData_find_selected_sensor(f->node->i_name); + if(( g_sensor_obj[index]->read == NULL)||(index < 0)){ + goto error; + } + + if(buf == NULL){ + goto error; + } + + ret = g_sensor_obj[index]->read(buf, len); + if(ret != 0){ + goto error; + } + + return len; + +error: + return -1; +} + +static ssize_t uData_sensor_write(file_t *f, const void *buf, size_t len) +{ + /* no need this functionality recently */ + return 0; +} + +static int uData_sensor_ioctl(file_t *f, int cmd, unsigned long arg) +{ + int ret = 0; + int index = 0; + + if(f == NULL){ + return -1; + } + + if(cmd == SENSOR_IOCTL_GET_SENSOR_LIST){ + ret = uData_sensor_hal_get_dev_list(arg); + if(ret != 0){ + return -1; + } + return 0; + } + + index = uData_find_selected_sensor(f->node->i_name); + if(( g_sensor_obj[index]->ioctl == NULL)||(index < 0)){ + return -1; + } + + ret = g_sensor_obj[index]->ioctl(cmd, arg); + if(ret != 0){ + return -1; + } + return 0; +} + +static int uData_sensor_hal_register(void) +{ + int ret = 0; + ret = aos_register_driver(sensor_node_path, &uData_sensor_fops, NULL); + if (ret != 0) { + return -1; + } + + return 0; +} + +int uData_sensor_init(void){ + int ret = 0; + int index = 0; + g_sensor_cnt = 0 ; + + drv_virtual_sensor_init(); + + ret = uData_sensor_hal_register(); + if(ret != 0){ + return -1; + } + + return 0; +} + +static void test_udata_subscribe_case(void) +{ + int ret = 0; + uData_sensor_init(); + uData_main(); + ret = uData_subscribe(UDATA_SERVICE_BARO); + YUNIT_ASSERT(ret == UDATA_SUCCES); +} + +static void test_udata_unsubscribe_case(void) +{ + int ret = 0; + ret = uData_unsubscribe(UDATA_SERVICE_BARO); + YUNIT_ASSERT(ret == UDATA_SUCCES); +} + +static yunit_test_case_t aos_udata_testcases[] = { + { "subscribe", test_udata_subscribe_case }, + { "unsubscribe", test_udata_unsubscribe_case }, + //{ "get list", test_udata_getlist_case }, + //{ "open", test_udata_open_case}, + //{ "close", test_udata_close_case}, + //{ "ioctl", test_udata_ioctl_case}, + YUNIT_TEST_CASE_NULL +}; + +static int init(void) +{ + return 0; +} + +static int cleanup(void) +{ + return 0; +} + +static void setup(void) +{ +} + +static void teardown(void) +{ +} + +static yunit_test_suite_t suites[] = { + { "uData", init, cleanup, setup, teardown, aos_udata_testcases }, + YUNIT_TEST_SUITE_NULL +}; + +void test_uData(void) +{ + yunit_add_test_suites(suites); +} + +AOS_TESTCASE(test_uData); + + diff --git a/test/testcase/framework/uData_test/uData_test.mk b/test/testcase/framework/uData_test/uData_test.mk new file mode 100644 index 0000000000..0046d3f24b --- /dev/null +++ b/test/testcase/framework/uData_test/uData_test.mk @@ -0,0 +1,8 @@ +NAME := uData_test + +$(NAME)_COMPONENTS += framework.common uData + +$(NAME)_SOURCES += uData_test.c + +$(NAME)_CFLAGS += -Wall -Werror + diff --git a/test/testcase/framework/wifi_hal_test/wifi_hal_test.c b/test/testcase/framework/wifi_hal_test/wifi_hal_test.c index 9a462e8dab..cc851674e4 100644 --- a/test/testcase/framework/wifi_hal_test/wifi_hal_test.c +++ b/test/testcase/framework/wifi_hal_test/wifi_hal_test.c @@ -25,8 +25,13 @@ static void test_timer_cb(void *arg) static void test_timer_case(void) { int counter = 0, old_counter; - hal_timer_t t; - hal_timer_init(&t, 50000, 1, 0, test_timer_cb, &counter); + timer_dev_t t; + t.config.period = 50000; + t.config.reload_mode = TIMER_RELOAD_AUTO; + t.config.cb = &test_timer_cb; + t.config.arg = &counter; + + hal_timer_init(&t); aos_msleep(1000); YUNIT_ASSERT(counter == 0); diff --git a/test/testcase/kernel/protocols/mesh_test/1hop_test.c b/test/testcase/kernel/protocols/mesh_test/1hop_test.c deleted file mode 100644 index ef03b3e2ab..0000000000 --- a/test/testcase/kernel/protocols/mesh_test/1hop_test.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#include "yunit.h" - -#include "aos/aos.h" -#include "aos/kernel.h" - -#include "umesh.h" -#include "core/link_mgmt.h" -#include "core/sid_allocator.h" -#include "core/router_mgr.h" -#include "utilities/logging.h" -#include "hal/hals.h" -#include "hal/interface_context.h" -#include "hal/interfaces.h" -#include "tools/cli.h" -#include "ip/lwip_adapter.h" - -#include "dda_util.h" - -static void me_as_leader(bool vector_router) -{ - /* start ourself(agent id 11) */ - cmd_to_agent("mode FIXED"); - if (vector_router) - cmd_to_agent("router VECTOR_ROUTER"); - else - cmd_to_agent("router SID_ROUTER"); - cmd_to_agent("start"); - check_cond_wait(umesh_get_device_state() == DEVICE_STATE_LEADER, 10); - - start_node_ext(12, -1, vector_router ? VECTOR_ROUTER : SID_ROUTER, -1); - check_cond_wait(umesh_get_meshnetsize() == 2, 10); - - check_p2p_str_wait("1000", 12, "testcmd sid", 5); - - YUNIT_ASSERT(umesh_get_device_state() == DEVICE_STATE_LEADER); - - cmd_to_agent("router SID_ROUTER"); - cmd_to_agent("stop"); - stop_node(12); - - aos_msleep(2 * 1000); -} - -static void me_as_router(bool vector_router) -{ - start_node_ext(12, MODE_RX_ON, -1, -1); - check_p2p_str_wait("leader", 12, "testcmd state", 10); - - cmd_to_agent("mode FIXED"); - cmd_to_agent("start"); - check_cond_wait(umesh_get_device_state() == DEVICE_STATE_ROUTER || - umesh_get_device_state() == DEVICE_STATE_SUPER_ROUTER, 10); - - cmd_to_agent("stop"); - stop_node(12); - aos_msleep(2 * 1000); -} - -static void me_as_router_lowpower(void) -{ - char ping_cmd[64]; - const ip6_addr_t *myaddr; - - start_node_ext(12, MODE_RX_ON, -1, -1); - check_p2p_str_wait("leader", 12, "testcmd state", 10); - - umesh_set_mode(0); - cmd_to_agent("start"); - check_cond_wait(umesh_get_device_state() == DEVICE_STATE_ROUTER, 10); - - aos_msleep(18 * 1000); - myaddr = ur_adapter_get_default_ipaddr(); - snprintf(ping_cmd, sizeof ping_cmd, "send 12 ping " IP6_ADDR_FMT, IP6_ADDR_DATA(((ur_ip6_addr_t *)myaddr))); - cmd_to_master(ping_cmd); - check_p2p_str_wait("1", 12, "testcmd icmp_acked", 30); - - snprintf(ping_cmd, sizeof ping_cmd, "send 12 ping " IP6_ADDR_FMT " 1400", IP6_ADDR_DATA(((ur_ip6_addr_t *)myaddr))); - cmd_to_master(ping_cmd); - check_p2p_str_wait("2", 12, "testcmd icmp_acked", 30); - - umesh_stop(); - umesh_set_mode(MODE_RX_ON); - stop_node(12); - aos_msleep(2 * 1000); -} - -static void me_as_leader_lowpower(void) -{ - char ping_cmd[64]; - const ip6_addr_t *myaddr; - - umesh_set_mode(MODE_RX_ON); - cmd_to_agent("start"); - check_cond_wait(umesh_get_device_state() == DEVICE_STATE_LEADER, 10); - - start_node_ext(12, 0, -1, -1); - check_p2p_str_wait("router", 12, "testcmd state", 10); - - aos_msleep(18 * 1000); - myaddr = ur_adapter_get_default_ipaddr(); - snprintf(ping_cmd, sizeof ping_cmd, "send 12 ping " IP6_ADDR_FMT " 1400", IP6_ADDR_DATA(((ur_ip6_addr_t *)myaddr))); - cmd_to_master(ping_cmd); - - aos_msleep(6 * 1000); - cmd_to_master(ping_cmd); - - check_p2p_str_wait("1", 12, "testcmd icmp_acked", 30); - - umesh_stop(); - umesh_set_mode(MODE_RX_ON); - stop_node(12); - aos_msleep(2 * 1000); -} - -void test_uradar_1hop_case(void) -{ - set_full_rssi(11, 12); - run_times(me_as_leader(false), 2); - run_times(me_as_router(false), 2); - run_times(me_as_leader(true), 2); - run_times(me_as_router(true), 2); - run_times(me_as_router_lowpower(), 1); - run_times(me_as_leader_lowpower(), 1); -} diff --git a/test/testcase/kernel/protocols/mesh_test/1mobile_test.c b/test/testcase/kernel/protocols/mesh_test/1mobile_test.c deleted file mode 100644 index 2f009a2663..0000000000 --- a/test/testcase/kernel/protocols/mesh_test/1mobile_test.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#include "yunit.h" - -#include "aos/aos.h" -#include "aos/kernel.h" - -#include "umesh.h" -#include "core/link_mgmt.h" -#include "core/sid_allocator.h" -#include "utilities/logging.h" -#include "tools/cli.h" -#include "ip/lwip_adapter.h" - -#include "dda_util.h" - -static void run_in_hop1(void) -{ - const ip6_addr_t *addr; - char ping_cmd[64]; - - set_full_rssi(11, 13); - - cmd_to_agent("stop"); - start_node_ext(12, MODE_RX_ON, -1, -1); - check_p2p_str_wait("leader", 12, "testcmd state", 10); - start_node_ext(13, MODE_RX_ON, -1, -1); - check_p2p_str_wait("router", 13, "testcmd state", 10); - - cmd_to_agent("mode MOBILE"); - cmd_to_agent("start"); - check_p2p_str_wait("leaf", 11, "testcmd state", 10); - - addr = ur_adapter_get_default_ipaddr(); - snprintf(ping_cmd, sizeof ping_cmd, "send 12 ping " IP6_ADDR_FMT, IP6_ADDR_DATA(((ur_ip6_addr_t *)addr))); - cmd_to_master(ping_cmd); - check_p2p_str_wait("1", 12, "testcmd icmp_acked", 5); - - cmd_to_agent("stop"); - cmd_to_agent("mode FIXED"); - stop_node(12); - stop_node(13); - - aos_msleep(2 * 1000); -} - -static void run_in_hop2(void) -{ - const ip6_addr_t *addr; - char ping_cmd[64]; - - set_line_rssi(11, 13); - - start_node_ext(13, MODE_RX_ON, -1, -1); - check_p2p_str_wait("leader", 13, "testcmd state", 10); - start_node_ext(12, MODE_RX_ON, -1, -1); - check_p2p_str_wait("router", 12, "testcmd state", 10); - - cmd_to_agent("mode MOBILE"); - cmd_to_agent("start"); - - check_p2p_str_wait("leaf", 11, "testcmd state", 10); - YUNIT_ASSERT(umesh_get_sid() == 0xc001); - - addr = ur_adapter_get_default_ipaddr(); - snprintf(ping_cmd, sizeof ping_cmd, "send 13 ping " IP6_ADDR_FMT, IP6_ADDR_DATA(((ur_ip6_addr_t *)addr))); - cmd_to_master(ping_cmd); - check_p2p_str_wait("1", 13, "testcmd icmp_acked", 5); - - cmd_to_agent("stop"); - cmd_to_agent("mode FIXED"); - stop_node(12); - stop_node(13); - - aos_msleep(2 * 1000); -} - - -void test_uradar_1mobile_case(void) -{ - run_times(run_in_hop1(), 2); - run_times(run_in_hop2(), 2); -} diff --git a/test/testcase/kernel/protocols/mesh_test/2mobile_test.c b/test/testcase/kernel/protocols/mesh_test/2mobile_test.c deleted file mode 100644 index 051b574da7..0000000000 --- a/test/testcase/kernel/protocols/mesh_test/2mobile_test.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#include "yunit.h" - -#include "aos/aos.h" -#include "aos/kernel.h" - -#include "umesh.h" -#include "core/link_mgmt.h" -#include "core/sid_allocator.h" -#include "tools/cli.h" - -#include "dda_util.h" - -static void run_in_hop1(void) -{ - set_full_rssi(11, 14); - - start_node(12); - start_node(13); - aos_msleep(5000); - - cmd_to_agent("mode MOBILE"); - cmd_to_agent("start"); - aos_msleep(10000); - - YUNIT_ASSERT(umesh_get_sid() == 0xc001); - - cmd_to_agent("stop"); - stop_node(12); - stop_node(13); - - aos_msleep(2 * 1000); -} - -static void run_in_hop2(void) -{ - set_line_rssi(11, 13); - - start_node(13); - aos_msleep(5000); - start_node(12); - aos_msleep(5000); - - cmd_to_agent("mode MOBILE"); - cmd_to_agent("start"); - - aos_msleep(10 * 1000); - YUNIT_ASSERT(umesh_get_sid() == 0xc001); - - cmd_to_agent("stop"); - stop_node(12); - stop_node(13); - - aos_msleep(2 * 1000); -} - - -void test_uradar_1mobile_case(void) -{ - run_times(run_in_hop1(), 2); - run_times(run_in_hop2(), 2); -} diff --git a/test/testcase/kernel/protocols/mesh_test/4super_7nodes_test.c b/test/testcase/kernel/protocols/mesh_test/4super_7nodes_test.c deleted file mode 100644 index ec2be54f36..0000000000 --- a/test/testcase/kernel/protocols/mesh_test/4super_7nodes_test.c +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#include "yunit.h" - -#include "aos/aos.h" -#include "aos/kernel.h" - -#include "umesh.h" -#include "core/link_mgmt.h" -#include "core/sid_allocator.h" -#include "core/router_mgr.h" -#include "utilities/logging.h" -#include "tools/cli.h" -#include "ip/lwip_adapter.h" - -#include "dda_util.h" - -/* topology: - * 11(super) - * ---------- - * | | | - * ____________| | |_________ - * | | | - * 2(super)---------1(leader)----- 4 (super) - * | | | - * ------ | | - * | | | | - * | | | | - * 5 8 9 10 (mobile) - * | - * | - * 6 - * | - * | - * 7 - * | - * | - * 3 - */ - -static void build_topo_wifi(void) -{ - clear_full_rssi(1, 11); - - set_rssi_ext(IF_WIFI, 11, 2, 1, 1); - set_rssi_ext(IF_WIFI, 11, 1, 1, 1); - set_rssi_ext(IF_WIFI, 11, 4, 1, 1); - set_rssi_ext(IF_WIFI, 2, 1, 1, 1); - set_rssi_ext(IF_WIFI, 1, 4, 1, 1); - set_rssi_ext(IF_WIFI, 2, 5, 1, 1); - set_rssi_ext(IF_WIFI, 2, 8, 1, 1); - set_rssi_ext(IF_WIFI, 5, 6, 1, 1); - set_rssi_ext(IF_WIFI, 6, 7, 1, 1); - set_rssi_ext(IF_WIFI, 7, 3, 1, 1); - set_rssi_ext(IF_WIFI, 1, 9, 1, 1); - set_rssi_ext(IF_WIFI, 4, 10, 1, 1); -} - -/* topology: - * 151(super) - * ---------- - * | | | - * ____________| | |_________ - * | | | - * 152(super)------153(leader)------154 (super) - * | | | - * ------ | | - * | | | | - * | | | | - * 155 156 157 158 (mobile) - * | - * | - * 159 - * | - * | - * 160 - * | - * | - * 161 - */ - -static void build_topo_wifi_ble(void) -{ - clear_full_rssi(151, 161); - - set_rssi_ext(IF_WIFI, 151, 152, 1, 1); - set_rssi_ext(IF_WIFI, 151, 153, 1, 1); - set_rssi_ext(IF_WIFI, 151, 154, 1, 1); - set_rssi_ext(IF_WIFI, 152, 153, 1, 1); - set_rssi_ext(IF_WIFI, 153, 154, 1, 1); - set_rssi_ext(IF_BLE, 152, 155, 1, 1); - set_rssi_ext(IF_BLE, 152, 156, 1, 1); - set_rssi_ext(IF_BLE, 155, 159, 1, 1); - set_rssi_ext(IF_BLE, 159, 160, 1, 1); - set_rssi_ext(IF_BLE, 160, 161, 1, 1); - set_rssi_ext(IF_BLE, 153, 157, 1, 1); - set_rssi_ext(IF_BLE, 154, 158, 1, 1); -} - -static void subnet_is_wifi_case(void) -{ - char autotest_cmd[64]; - const ip6_addr_t *addr; - uint8_t index; - - build_topo_wifi(); - umesh_stop(); - - start_node_ext(1, MODE_SUPER | MODE_RX_ON, -1, 1); - check_p2p_str_wait("leader", 1, "testcmd state", 10); - check_p2p_str_wait("VECTOR_ROUTER", 1, "testcmd router", 2); - - umesh_set_mode(MODE_SUPER | MODE_RX_ON); - cmd_to_agent("start"); - check_cond_wait((DEVICE_STATE_SUPER_ROUTER == umesh_mm_get_device_state()), 15); - YUNIT_ASSERT(ur_router_get_default_router() == VECTOR_ROUTER); - - start_node_ext(2, MODE_SUPER | MODE_RX_ON, -1, 1); - check_p2p_str_wait("super_router", 2, "testcmd state", 10); - check_p2p_str_wait("VECTOR_ROUTER", 2, "testcmd router", 2); - - start_node_ext(4, MODE_SUPER | MODE_RX_ON, -1, 1); - check_p2p_str_wait("super_router", 4, "testcmd state", 10); - check_p2p_str_wait("VECTOR_ROUTER", 4, "testcmd router", 2); - - aos_msleep(15 * 1000); - - start_node_ext(5, MODE_RX_ON, -1, 1); - check_p2p_str_wait("router", 5, "testcmd state", 10); - check_p2p_str_wait("SID_ROUTER", 5, "testcmd router", 2); - - start_node_ext(6, MODE_RX_ON, -1, 1); - check_p2p_str_wait("router", 6, "testcmd state", 10); - check_p2p_str_wait("SID_ROUTER", 6, "testcmd router", 2); - - start_node_ext(7, MODE_RX_ON, -1, 1); - check_p2p_str_wait("router", 7, "testcmd state", 10); - check_p2p_str_wait("SID_ROUTER", 7, "testcmd router", 2); - - start_node_ext(3, MODE_RX_ON, -1, 1); - check_p2p_str_wait("leaf", 3, "testcmd state", 10); - check_p2p_str_wait("SID_ROUTER", 3, "testcmd router", 2); - - start_node_ext(8, MODE_RX_ON, -1, 1); - check_p2p_str_wait("router", 8, "testcmd state", 10); - check_p2p_str_wait("SID_ROUTER", 8, "testcmd router", 2); - - start_node_ext(9, MODE_RX_ON, -1, 1); - check_p2p_str_wait("router", 9, "testcmd state", 10); - check_p2p_str_wait("SID_ROUTER", 9, "testcmd router", 2); - - start_node_ext(10, MODE_MOBILE | MODE_RX_ON, -1, 1); - check_p2p_str_wait("leaf", 10, "testcmd state", 10); - check_p2p_str_wait("SID_ROUTER", 10, "testcmd router", 2); - - addr = ur_adapter_get_mcast_ipaddr(); - for (index = 1; index < 12; index++) { - if (index != 3 || index !=10 || index != 5) { - continue; - } - snprintf(autotest_cmd, sizeof autotest_cmd, "send %d autotest " IP6_ADDR_FMT " 1 500", - index, IP6_ADDR_DATA(((ur_ip6_addr_t *)addr))); - cmd_to_master(autotest_cmd); - check_p2p_str_wait("10", index, "testcmd autotest_acked", 10); - } - - for (index = 1; index < 11; index++) { - stop_node(index); - } - cmd_to_agent("stop"); - aos_msleep(1 * 1000); -} - -static void subnet_is_ble_case(void) -{ - char autotest_cmd[64]; - uint8_t index; - uint8_t counter; - - build_topo_wifi_ble(); - - umesh_stop(); - - start_node_ext(153, MODE_SUPER | MODE_RX_ON, -1, 3); - check_p2p_str_wait("leader", 153, "testcmd state", 10); - check_p2p_str_wait("VECTOR_ROUTER", 153, "testcmd router", 2); - - start_node_ext(151, MODE_SUPER | MODE_RX_ON, -1, 3); - check_p2p_str_wait("super_router", 151, "testcmd state", 10); - check_p2p_str_wait("VECTOR_ROUTER", 151, "testcmd router", 2); - - start_node_ext(152, MODE_SUPER | MODE_RX_ON, -1, 3); - check_p2p_str_wait("super_router", 152, "testcmd state", 10); - check_p2p_str_wait("VECTOR_ROUTER", 152, "testcmd router", 2); - - start_node_ext(154, MODE_SUPER | MODE_RX_ON, -1, 3); - check_p2p_str_wait("super_router", 154, "testcmd state", 10); - check_p2p_str_wait("VECTOR_ROUTER", 154, "testcmd router", 2); - - aos_msleep(15 * 1000); - - start_node_ext(155, MODE_RX_ON, -1, 2); - check_p2p_str_wait("router", 155, "testcmd state", 10); - check_p2p_str_wait("SID_ROUTER", 155, "testcmd router", 2); - - start_node_ext(159, MODE_RX_ON, -1, 2); - check_p2p_str_wait("router", 159, "testcmd state", 10); - check_p2p_str_wait("SID_ROUTER", 159, "testcmd router", 2); - - start_node_ext(160, MODE_RX_ON, -1, 2); - check_p2p_str_wait("router", 160, "testcmd state", 10); - check_p2p_str_wait("SID_ROUTER", 160, "testcmd router", 2); - - start_node_ext(161, MODE_RX_ON, -1, 2); - check_p2p_str_wait("leaf", 161, "testcmd state", 10); - check_p2p_str_wait("SID_ROUTER", 161, "testcmd router", 2); - - start_node_ext(156, MODE_RX_ON, -1, 2); - check_p2p_str_wait("router", 156, "testcmd state", 10); - check_p2p_str_wait("SID_ROUTER", 156, "testcmd router", 2); - - start_node_ext(157, MODE_RX_ON, -1, 2); - check_p2p_str_wait("router", 157, "testcmd state", 10); - check_p2p_str_wait("SID_ROUTER", 157, "testcmd router", 2); - - start_node_ext(158, MODE_MOBILE | MODE_RX_ON, -1, 2); - check_p2p_str_wait("leaf", 158, "testcmd state", 10); - check_p2p_str_wait("SID_ROUTER", 158, "testcmd router", 2); - - char *ipaddr = dda_p2p_req_and_wait(154, "testcmd ipaddr", 5); - YUNIT_ASSERT(ipaddr != NULL); - for (index = 151; index < 161; index++) { - if (index != 153 || index != 158 || index != 159) { - continue; - } - snprintf(autotest_cmd, sizeof autotest_cmd, "send %d autotest %s", - index, ipaddr); - cmd_to_master(autotest_cmd); - check_p2p_str_wait("1", index, "testcmd autotest_acked", 10); - } - aos_free(ipaddr); - - for (index = 151; index < 162; index++) { - stop_node(index); - } - aos_msleep(1 * 1000); -} - -void test_umesh_4super_7nodes_case(void) -{ - run_times(subnet_is_wifi_case(), 1); - run_times(subnet_is_ble_case(), 1); -} diff --git a/test/testcase/kernel/protocols/mesh_test/asymmetric_test.c b/test/testcase/kernel/protocols/mesh_test/asymmetric_test.c deleted file mode 100644 index 856da33418..0000000000 --- a/test/testcase/kernel/protocols/mesh_test/asymmetric_test.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#include "yunit.h" - -#include "aos/aos.h" -#include "aos/kernel.h" - -#include "umesh.h" -#include "core/link_mgmt.h" -#include "core/sid_allocator.h" -#include "core/router_mgr.h" -#include "utilities/logging.h" -#include "tools/cli.h" -#include "ip/lwip_adapter.h" - -#include "dda_util.h" - -static void two_nodes_case(void) -{ - uint8_t index; - - /* topology: - * leader leader - * 11 <------ 12 - */ - - set_rssi_ext(IF_WIFI, 11, 12, 0, 1); - - umesh_set_mode(MODE_RX_ON); - cmd_to_agent("start"); - check_cond_wait((DEVICE_STATE_LEADER == umesh_mm_get_device_state()), 15); - YUNIT_ASSERT(ur_router_get_default_router() == SID_ROUTER); - - start_node_ext(12, MODE_RX_ON, -1, -1); - check_p2p_str_wait("leader", 12, "testcmd state", 10); - check_p2p_str_wait("SID_ROUTER", 12, "testcmd router", 2); - - for (index = 0; index < 3; index++) { - aos_msleep(5* 1000); - YUNIT_ASSERT(DEVICE_STATE_LEADER == umesh_get_device_state()); - } - - stop_node(12); - cmd_to_agent("stop"); -} - -static void three_nodes_case(void) -{ - uint8_t index; - char index_str[3]; - char ping_cmd[64]; - const ip6_addr_t *myaddr; - - /* topology: - * leader router router - * 13 <------> 12 <-----> - * | 11 - * |--------------------> - * - */ - - set_rssi_ext(IF_WIFI, 13, 12, 1, 1); - set_rssi_ext(IF_WIFI, 12, 11, 1, 1); - set_rssi_ext(IF_WIFI, 13, 11, 1, 0); - - start_node_ext(13, MODE_RX_ON, -1, -1); - check_p2p_str_wait("leader", 13, "testcmd state", 10); - check_p2p_str_wait("SID_ROUTER", 13, "testcmd router", 2); - - start_node_ext(12, MODE_RX_ON, -1, -1); - check_p2p_str_wait("router", 12, "testcmd state", 10); - check_p2p_str_wait("SID_ROUTER", 12, "testcmd router", 2); - - umesh_set_mode(MODE_RX_ON); - cmd_to_agent("start"); - check_cond_wait((DEVICE_STATE_ROUTER == umesh_mm_get_device_state()), 15); - YUNIT_ASSERT(ur_router_get_default_router() == SID_ROUTER); - - myaddr = ur_adapter_get_default_ipaddr(); - snprintf(ping_cmd, sizeof ping_cmd, "send 12 ping " IP6_ADDR_FMT, IP6_ADDR_DATA(((ur_ip6_addr_t *)myaddr))); - - for (index = 0; index < 2; index++) { - check_cond_wait(umesh_mm_get_attach_state() == ATTACH_IDLE || \ - umesh_mm_get_attach_state() == ATTACH_DONE, 10); - cmd_to_master(ping_cmd); - snprintf(index_str, sizeof(index_str), "%d", index + 1); - check_p2p_str_wait(index_str, 12, "testcmd icmp_acked", 5); - aos_msleep(5 * 1000); - } - - stop_node(12); - stop_node(13); - cmd_to_agent("stop"); -} - - -void test_uradar_asymmetric_link_case(void) -{ - run_times(two_nodes_case(), 1); - run_times(three_nodes_case(), 1); -} diff --git a/test/testcase/kernel/protocols/mesh_test/cli_test.c b/test/testcase/kernel/protocols/mesh_test/cli_test.c deleted file mode 100644 index 15de8c2d76..0000000000 --- a/test/testcase/kernel/protocols/mesh_test/cli_test.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#include -#include - -#include -#include "yunit.h" - -#include "dda_util.h" - -#include "umesh.h" -#include "utilities/logging.h" -#include "core/mesh_mgmt.h" -#include "tools/cli.h" - -void test_uradar_cli_case(void) -{ - cmd_to_agent("stop"); - cmd_to_agent("start"); - check_cond_wait(umesh_get_device_state() == DEVICE_STATE_LEADER, 10); - - cmd_to_agent("help"); - cmd_to_agent("channel"); - cmd_to_agent("loglevel"); - cmd_to_agent("ipaddr"); - cmd_to_agent("macaddr"); - cmd_to_agent("meshnetsize"); - cmd_to_agent("meshnetid"); - cmd_to_agent("autotest"); - cmd_to_agent("prefix"); - cmd_to_agent("seclevel"); - cmd_to_agent("state"); - cmd_to_agent("stats"); - cmd_to_agent("whitelist"); - cmd_to_agent("whitelist add 0100000000000000"); - cmd_to_agent("whitelist remove 0100000000000000"); - cmd_to_agent("whitelist enable"); - cmd_to_agent("whitelist disable"); - cmd_to_agent("whitelist clear"); - cmd_to_agent("networks"); - cmd_to_agent("stop"); - aos_msleep(1 * 1000); -} - diff --git a/test/testcase/kernel/protocols/mesh_test/dda_util.h b/test/testcase/kernel/protocols/mesh_test/dda_util.h deleted file mode 100644 index 2e048cd996..0000000000 --- a/test/testcase/kernel/protocols/mesh_test/dda_util.h +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#ifndef _DDM_UTIL_H_ -#define _DDM_UTIL_H_ - -#include -#include -#include "config_parser.h" -#include "yts.h" - -#ifndef DDA_DEBUG -#define DDA_DEBUG 0 -#endif - -extern void ur_ut_send_cmd_to_ddm(const char *cmd); - -static void cmd_to_master(char *cmd) -{ - ur_ut_send_cmd_to_ddm("goto master"); - ur_ut_send_cmd_to_ddm(cmd); -} - -static void cmd_to_agent(char *cmd) -{ - umesh_cli_cmd(cmd, strlen(cmd), NULL, NULL); -} - -static void set_rssi_ext(int if_idx, int i, int j, int rssi1, int rssi2) -{ - char rssi_cmd[64]; - if (if_idx >= 0) - sprintf(rssi_cmd, "if=%s rssi %d %d %d %d", - if_idx2name(if_idx), i, j, rssi1, rssi2); - else - sprintf(rssi_cmd, "rssi %d %d %d %d", i, j, rssi1, rssi2); - cmd_to_master(rssi_cmd); -} - -static void set_rssi(int i, int j, int rssi) -{ - set_rssi_ext(-1, i, j, rssi, rssi); -} - -static void set_line_rssi_ext(int if_idx, int start, int end) -{ - int i; - while (start < end) { - set_rssi(start, start+1, 1); - for (i=start+2;i<=end;i++) { - set_rssi_ext(if_idx, start, i, 0, 0); - } - - start ++; - } -} - -static void set_line_rssi(int start, int end) -{ - set_line_rssi_ext(IF_WIFI, start, end); - set_line_rssi_ext(IF_BLE, start, end); -} - -static void set_full_rssi_ext(int if_idx, int start, int end) -{ - int i,j; - for (i=start;i= 0) { - sprintf(tmp, " mode=%d", mode); - strcat(cmd, tmp); - } - if (router >= 0) { - sprintf(tmp, " router=%d", router); - strcat(cmd, tmp); - } - if (ifs >= 0) { - sprintf(tmp, " ifs=%d", ifs); - strcat(cmd, tmp); - } - cmd_to_master(cmd); -} - -static void stop_node(int id) -{ - char cmd[32]; - sprintf(cmd, "stop %d", id); - cmd_to_master(cmd); -} - -inline static void __dummy__(void) -{ - cmd_to_agent(NULL); - set_line_rssi(0, 0); - set_full_rssi(0, 0); - start_node(0); - start_node_ext(0, -1, -1, -1); - stop_node(0); - clear_full_rssi(0, 0); -} - -typedef void (*dda_p2p_cb)(const char *, int, void *); -void dda_p2p_request(int dst_id, const char *cmd, dda_p2p_cb cb, void *cb_data); -void dda_p2p_remove_request(dda_p2p_cb cb, void *cb_data); - -struct wait_cb_data { - aos_sem_t sem; - char *buf; -}; - -static void dda_p2p_wait_cb(const char *buf, int len, void *cb_data) -{ - struct wait_cb_data *pdata = cb_data; - int sz = strlen(buf) + 1; - pdata->buf = aos_malloc(sz); - memcpy(pdata->buf, buf, sz); - aos_sem_signal(&pdata->sem); -} - -inline static char *dda_p2p_req_and_wait(int dst_id, const char *cmd, int max_wait_second) -{ - struct wait_cb_data wait_data = {}; - - aos_sem_new(&wait_data.sem, 0); - dda_p2p_request(dst_id, cmd, dda_p2p_wait_cb, &wait_data); - - aos_sem_wait(&wait_data.sem, max_wait_second * 1000); - - dda_p2p_remove_request(dda_p2p_wait_cb, &wait_data); - - aos_sem_free(&wait_data.sem); - - return wait_data.buf; -} - -/** - * ret: expected return - * did: agent id - * cmd: command to agent - * sec: max waiting seconds - */ -#define check_p2p_str_wait(ret, did, cmd, sec) do { \ - int i; \ - for (i=0;i %s\n", did, cmd, str); \ - if (str && strcmp(ret, str) == 0) { aos_free(str);break;} \ - if (str) { aos_free(str);} \ - } \ - YUNIT_ASSERT(i 12 <---> 13 <---> 14 - */ - set_line_rssi(11, 14); - - umesh_set_mode(MODE_RX_ON); - cmd_to_agent("start"); - check_cond_wait((DEVICE_STATE_LEADER == umesh_mm_get_device_state()), 15); - YUNIT_ASSERT(ur_router_get_default_router() == SID_ROUTER); - - start_node_ext(12, MODE_RX_ON, -1, -1); - check_p2p_str_wait("router", 12, "testcmd state", 10); - check_p2p_str_wait("SID_ROUTER", 12, "testcmd router", 2); - - start_node_ext(13, MODE_RX_ON, -1, -1); - check_p2p_str_wait("router", 13, "testcmd state", 10); - check_p2p_str_wait("SID_ROUTER", 13, "testcmd router", 2); - - start_node_ext(14, MODE_RX_ON | MODE_MOBILE, -1, -1); - check_p2p_str_wait("leaf", 14, "testcmd state", 10); - check_p2p_str_wait("SID_ROUTER", 14, "testcmd router", 2); - - myaddr = ur_adapter_get_default_ipaddr(); - snprintf(ping_cmd, sizeof ping_cmd, "send 14 ping " IP6_ADDR_FMT, IP6_ADDR_DATA(((ur_ip6_addr_t *)myaddr))); - cmd_to_master(ping_cmd); - check_p2p_str_wait("1", 14, "testcmd icmp_acked", 5); - - /* topology: - * leader router router - * 11 <------> 12 <---> 13 - * | mobile - * | <---> 14 - */ - - set_rssi_ext(IF_WIFI, 13, 14, 0, 0); - set_rssi_ext(IF_WIFI, 12, 14, 1, 1); - - aos_msleep(WIFI_NEIGHBOR_ALIVE_TIMEOUT + WIFI_ADVERTISEMENT_TIMEOUT); - myaddr = ur_adapter_get_default_ipaddr(); - snprintf(ping_cmd, sizeof ping_cmd, "send 14 ping " IP6_ADDR_FMT, IP6_ADDR_DATA(((ur_ip6_addr_t *)myaddr))); - cmd_to_master(ping_cmd); - snprintf(ping_cmd, sizeof ping_cmd, "send 14 ping " IP6_ADDR_FMT, IP6_ADDR_DATA(((ur_ip6_addr_t *)myaddr))); - aos_msleep(WIFI_ADVERTISEMENT_TIMEOUT); - cmd_to_master(ping_cmd); - check_p2p_str_wait("2", 14, "testcmd icmp_acked", 10); - - stop_node(12); - stop_node(13); - stop_node(14); - cmd_to_agent("stop"); -} - - -void test_uradar_dest_become_unreachable_case(void) -{ - run_times(one_layer_case(), 1); -} diff --git a/test/testcase/kernel/protocols/mesh_test/diags_test.c b/test/testcase/kernel/protocols/mesh_test/diags_test.c deleted file mode 100644 index eb872fe589..0000000000 --- a/test/testcase/kernel/protocols/mesh_test/diags_test.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#include -#include -#include - -#include "umesh_utils.h" -#include "core/mesh_mgmt.h" -#include "tools/diags.h" -#include "hal/interfaces.h" - -void test_diags_case(void) -{ - network_context_t *network; - ur_addr_t dest; - message_t *message; - mm_header_t *mm_header; - mm_timestamp_tv_t *timestamp; - message_info_t *info; - uint8_t *data; - uint8_t *data_orig; - uint16_t length; - - interface_start(); - network = get_default_network_context(); - dest.netid = 0x100; - dest.addr.len = SHORT_ADDR_SIZE; - dest.addr.short_addr = 0x1000; - YUNIT_ASSERT(UR_ERROR_NONE == send_trace_route_request(network, &dest)); - - length = sizeof(mm_header_t) + sizeof(mm_timestamp_tv_t); - data = (uint8_t *)ur_mem_alloc(length); - data_orig = data; - data += sizeof(mm_header_t); - - timestamp = (mm_timestamp_tv_t *)data; - umesh_mm_init_tv_base((mm_tv_t *)timestamp, TYPE_TIMESTAMP); - timestamp->timestamp = 10; - data += sizeof(mm_timestamp_tv_t); - - message = mf_build_message(MESH_FRAME_TYPE_CMD, COMMAND_TRACE_ROUTE_RESPONSE, - data_orig, length, UT_MSG); - info = message->info; - info->network = network; - memcpy(&info->dest, &dest, sizeof(info->dest)); - - YUNIT_ASSERT(UR_ERROR_NONE == handle_diags_command(message, true)); - message_free(message); - ur_mem_free(data_orig, length); - - length = sizeof(mm_header_t) + sizeof(mm_timestamp_tv_t); - data = (uint8_t *)ur_mem_alloc(length); - data_orig = data; - data += sizeof(mm_header_t); - timestamp = (mm_timestamp_tv_t *)data; - umesh_mm_init_tv_base((mm_tv_t *)timestamp, TYPE_TIMESTAMP); - timestamp->timestamp = umesh_now_ms(); - data += sizeof(mm_timestamp_tv_t); - - message = mf_build_message(MESH_FRAME_TYPE_CMD, COMMAND_TRACE_ROUTE_REQUEST, - data_orig, length, UT_MSG); - - info = message->info; - info->network = network; - memcpy(&info->dest, &dest, sizeof(info->dest)); - - YUNIT_ASSERT(UR_ERROR_NONE == handle_diags_command(message, true)); - message_free(message); - ur_mem_free(data_orig, length); - interface_stop(); -} diff --git a/test/testcase/kernel/protocols/mesh_test/filelists.mk b/test/testcase/kernel/protocols/mesh_test/filelists.mk deleted file mode 100644 index 8793dffe80..0000000000 --- a/test/testcase/kernel/protocols/mesh_test/filelists.mk +++ /dev/null @@ -1,31 +0,0 @@ - -MESHYTSPATH = ./ - -MESHYTSFILE = $(MESHYTSPATH)/uradar_test.c \ - $(MESHYTSPATH)/lowpan6_test.c \ - $(MESHYTSPATH)/sid_router_test.c \ - $(MESHYTSPATH)/vector_router_test.c \ - $(MESHYTSPATH)/lwip_adapter_test.c \ - $(MESHYTSPATH)/urmesh_test.c \ - $(MESHYTSPATH)/sid_allocator_test.c \ - $(MESHYTSPATH)/rsid_allocator_test.c \ - $(MESHYTSPATH)/misc_test.c \ - $(MESHYTSPATH)/mesh_mgmt_test.c \ - $(MESHYTSPATH)/hal_mesh_test.c \ - $(MESHYTSPATH)/diags_test.c \ - $(MESHYTSPATH)/mcast_test.c \ - $(MESHYTSPATH)/1hop_test.c \ - $(MESHYTSPATH)/1mobile_test.c \ - $(MESHYTSPATH)/topology_line_test.c \ - $(MESHYTSPATH)/layer_routing_line_topology.c \ - $(MESHYTSPATH)/layer_routing_2mobile.c \ - $(MESHYTSPATH)/dest_unreachable.c \ - $(MESHYTSPATH)/asymmetric_test.c \ - $(MESHYTSPATH)/topo_test.c \ - $(MESHYTSPATH)/cli_test.c \ - $(MESHYTSPATH)/test_common_functions.c \ - $(MESHYTSPATH)/scales_5nodes_test.c \ - $(MESHYTSPATH)/scales_10nodes_test.c \ - $(MESHYTSPATH)/scales_20nodes_test.c \ - $(MESHYTSPATH)/scales_30nodes_test.c \ - $(MESHYTSPATH)/4super_7nodes_test.c diff --git a/test/testcase/kernel/protocols/mesh_test/hal_mesh_test.c b/test/testcase/kernel/protocols/mesh_test/hal_mesh_test.c deleted file mode 100644 index ecba876c77..0000000000 --- a/test/testcase/kernel/protocols/mesh_test/hal_mesh_test.c +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#include -#include -#include - -#include "umesh_hal.h" - -void test_hal_mesh_case(void) -{ - hal_umesh_get_bcast_mtu(NULL); - hal_umesh_get_ucast_mtu(NULL); - hal_umesh_get_channel(NULL); - hal_umesh_get_chnlist(NULL, NULL); - hal_umesh_set_txpower(NULL, 2); - hal_umesh_get_txpower(NULL); - hal_umesh_get_extnetid(NULL, NULL); - hal_umesh_get_stats(NULL); -} diff --git a/test/testcase/kernel/protocols/mesh_test/layer_routing_2mobile.c b/test/testcase/kernel/protocols/mesh_test/layer_routing_2mobile.c deleted file mode 100644 index 6f2d5a7942..0000000000 --- a/test/testcase/kernel/protocols/mesh_test/layer_routing_2mobile.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#include "yunit.h" - -#include "aos/aos.h" -#include "aos/kernel.h" - -#include "umesh.h" -#include "core/link_mgmt.h" -#include "core/sid_allocator.h" -#include "core/router_mgr.h" -#include "utilities/logging.h" -#include "tools/cli.h" -#include "ip/lwip_adapter.h" - -#include "dda_util.h" - -static void topology_line_case(void) -{ - char ping_cmd[64]; - const ip6_addr_t *myaddr; - - /* topology: - * router super super router - * 11 <------> 12 <===> 13 <---> 14 - */ - set_line_rssi(11, 14); - cmd_to_agent("stop"); - - start_node_ext(13, MODE_SUPER | MODE_RX_ON, -1, -1); - check_p2p_str_wait("leader", 13, "testcmd state", 10); - check_p2p_str_wait("VECTOR_ROUTER", 13, "testcmd router", 2); - - start_node_ext(12, MODE_SUPER | MODE_RX_ON, -1, -1); - check_p2p_str_wait("super_router", 12, "testcmd state", 10); - check_p2p_str_wait("VECTOR_ROUTER", 12, "testcmd router", 2); - - start_node_ext(14, MODE_MOBILE | MODE_RX_ON, -1, -1); - check_p2p_str_wait("leaf", 14, "testcmd state", 10); - check_p2p_str_wait("SID_ROUTER", 14, "testcmd router", 2); - - umesh_set_mode(MODE_MOBILE | MODE_RX_ON); - cmd_to_agent("start"); - check_cond_wait((DEVICE_STATE_LEAF == umesh_mm_get_device_state()), 15); - YUNIT_ASSERT(ur_router_get_default_router() == SID_ROUTER); - - myaddr = ur_adapter_get_default_ipaddr(); - snprintf(ping_cmd, sizeof ping_cmd, "send 14 ping " IP6_ADDR_FMT, IP6_ADDR_DATA(((ur_ip6_addr_t *)myaddr))); - cmd_to_master(ping_cmd); - check_p2p_str_wait("1", 14, "testcmd icmp_acked", 5); - - stop_node(12); - stop_node(13); - stop_node(14); - cmd_to_agent("stop"); -} - -static void dual_if_topology_line_case(void) -{ - char ping_cmd[64]; - - /* topology: - * ble wifi/ble wifi/ble ble - * 151 <------> 152 <===> 153 <---> 154 - */ - set_line_rssi(151, 154); - cmd_to_agent("stop"); - - start_node_ext(152, MODE_SUPER | MODE_RX_ON, -1, 3); - check_p2p_str_wait("leader", 152, "testcmd state", 10); - check_p2p_str_wait("VECTOR_ROUTER", 152, "testcmd router", 2); - - start_node_ext(153, MODE_SUPER | MODE_RX_ON, -1, 3); - check_p2p_str_wait("super_router", 153, "testcmd state", 10); - check_p2p_str_wait("VECTOR_ROUTER", 153, "testcmd router", 2); - - start_node_ext(151, MODE_MOBILE | MODE_RX_ON, -1, 2); - check_p2p_str_wait("leaf", 151, "testcmd state", 10); - check_p2p_str_wait("SID_ROUTER", 151, "testcmd router", 2); - - start_node_ext(154, MODE_MOBILE | MODE_RX_ON, -1, 2); - check_p2p_str_wait("leaf", 154, "testcmd state", 10); - check_p2p_str_wait("SID_ROUTER", 154, "testcmd router", 2); - - char *ipaddr = dda_p2p_req_and_wait(154, "testcmd ipaddr", 5); - YUNIT_ASSERT(ipaddr != NULL); - if (ipaddr) { - snprintf(ping_cmd, sizeof ping_cmd, "send 151 ping %s", ipaddr); - aos_free(ipaddr); - - cmd_to_master(ping_cmd); - check_p2p_str_wait("1", 151, "testcmd icmp_acked", 5); - } - - stop_node(151); - stop_node(152); - stop_node(153); - stop_node(154); - cmd_to_agent("stop"); -} - -void test_uradar_layer_routing_2mobile_case(void) -{ - run_times(topology_line_case(), 1); - run_times(dual_if_topology_line_case(), 1); -} diff --git a/test/testcase/kernel/protocols/mesh_test/layer_routing_line_topology.c b/test/testcase/kernel/protocols/mesh_test/layer_routing_line_topology.c deleted file mode 100644 index e262a69e65..0000000000 --- a/test/testcase/kernel/protocols/mesh_test/layer_routing_line_topology.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#include "yunit.h" - -#include "aos/aos.h" -#include "aos/kernel.h" - -#include "umesh.h" -#include "core/link_mgmt.h" -#include "core/sid_allocator.h" -#include "core/router_mgr.h" -#include "utilities/logging.h" -#include "tools/cli.h" -#include "ip/lwip_adapter.h" - -#include "dda_util.h" - -static void topology_line_case(void) -{ - char ping_cmd[64]; - const ip6_addr_t *myaddr; - - /* topology: - * router super super router - * 11 <------> 12 <===> 13 <---> 14 - */ - set_line_rssi(11, 14); - cmd_to_agent("stop"); - - start_node_ext(13, MODE_SUPER | MODE_RX_ON, -1, -1); - check_p2p_str_wait("leader", 13, "testcmd state", 10); - check_p2p_str_wait("VECTOR_ROUTER", 13, "testcmd router", 2); - - start_node_ext(12, MODE_SUPER | MODE_RX_ON, -1, -1); - check_p2p_str_wait("super_router", 12, "testcmd state", 10); - check_p2p_str_wait("VECTOR_ROUTER", 12, "testcmd router", 2); - - start_node_ext(14, MODE_RX_ON, -1, -1); - check_p2p_str_wait("router", 14, "testcmd state", 10); - check_p2p_str_wait("SID_ROUTER", 14, "testcmd router", 2); - - umesh_set_mode(MODE_RX_ON); - cmd_to_agent("start"); - check_cond_wait((DEVICE_STATE_ROUTER == umesh_mm_get_device_state()), 15); - YUNIT_ASSERT(ur_router_get_default_router() == SID_ROUTER); - - myaddr = ur_adapter_get_default_ipaddr(); - snprintf(ping_cmd, sizeof ping_cmd, "send 14 ping " IP6_ADDR_FMT, IP6_ADDR_DATA(((ur_ip6_addr_t *)myaddr))); - cmd_to_master(ping_cmd); - check_p2p_str_wait("1", 14, "testcmd icmp_acked", 5); - - stop_node(12); - stop_node(13); - stop_node(14); - cmd_to_agent("stop"); -} - -static void dual_if_topology_line_case(void) -{ - char ping_cmd[64]; - - /* topology: - * ble wifi/ble wifi/ble ble - * 151 <------> 152 <===> 153 <---> 154 - */ - set_line_rssi(151, 154); - cmd_to_agent("stop"); - - start_node_ext(152, MODE_SUPER | MODE_RX_ON, -1, 3); - check_p2p_str_wait("leader", 152, "testcmd state", 10); - check_p2p_str_wait("VECTOR_ROUTER", 152, "testcmd router", 2); - - start_node_ext(153, MODE_SUPER | MODE_RX_ON, -1, 3); - check_p2p_str_wait("super_router", 153, "testcmd state", 10); - check_p2p_str_wait("VECTOR_ROUTER", 153, "testcmd router", 2); - - start_node_ext(151, MODE_RX_ON, -1, 2); - check_p2p_str_wait("router", 151, "testcmd state", 10); - check_p2p_str_wait("SID_ROUTER", 151, "testcmd router", 2); - - start_node_ext(154, MODE_RX_ON, -1, 2); - check_p2p_str_wait("router", 154, "testcmd state", 10); - check_p2p_str_wait("SID_ROUTER", 154, "testcmd router", 2); - - char *ipaddr = dda_p2p_req_and_wait(154, "testcmd ipaddr", 5); - YUNIT_ASSERT(ipaddr != NULL); - if (ipaddr) { - snprintf(ping_cmd, sizeof ping_cmd, "send 151 ping %s", ipaddr); - aos_free(ipaddr); - - cmd_to_master(ping_cmd); - check_p2p_str_wait("1", 151, "testcmd icmp_acked", 5); - } - - stop_node(151); - stop_node(152); - stop_node(153); - stop_node(154); -} - -void test_uradar_layer_routing_line_topology_case(void) -{ - //run_times(topology_line_case(), 1); - run_times(dual_if_topology_line_case(), 1); -} diff --git a/test/testcase/kernel/protocols/mesh_test/lowpan6_test.c b/test/testcase/kernel/protocols/mesh_test/lowpan6_test.c deleted file mode 100644 index e2a9dd527e..0000000000 --- a/test/testcase/kernel/protocols/mesh_test/lowpan6_test.c +++ /dev/null @@ -1,400 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#include -#include "yunit.h" - -#include "umesh.h" -#include "umesh_types.h" -#include "core/mesh_forwarder.h" -#include "core/fragments.h" -#include "core/network_data.h" -#include "ip/ip.h" -#include "ip/compress6.h" -#include "utilities/message.h" - -static void get_addr_prefix(ur_ip6_prefix_t *prefix) -{ - uint16_t meshnetid = get_main_netid(umesh_get_meshnetid()); - - memset(prefix, 0, sizeof(*prefix)); - prefix->length = 64; - prefix->prefix.m8[0] = 0xfc; - prefix->prefix.m8[6] = (uint8_t)(meshnetid >> 8); - prefix->prefix.m8[7] = (uint8_t)meshnetid; -} - -void test_uradar_6lowpan_case(void) -{ - #define TEST_MSG_LEN 60 - uint8_t ip6_buffer[TEST_MSG_LEN]; - uint8_t lowpan_buffer[TEST_MSG_LEN]; - uint16_t ip_hdr_len, lowpan_hdr_len, pkt_len; - ur_ip6_header_t *ip6hdr; - iphc_header_t iphc_header; - ur_udp_header_t *udphdr; - nhc_header_t nhc_header; - ur_ip6_prefix_t prefix; - ur_error_t error; - ur_addr_t src; - ur_addr_t dest; - - get_addr_prefix(&prefix); - - /*********test header compress and decompress functions*********/ - memset(ip6_buffer, 0x00, sizeof(ip6_buffer)); - ip6hdr = (ur_ip6_header_t *)ip6_buffer; - udphdr = (ur_udp_header_t *)(ip6_buffer + UR_IP6_HLEN); - - ip6hdr->v_tc_fl = htonl(6 << 28); /* TC=0, Fl=0 */ - ip6hdr->len = htons(sizeof(ip6_buffer) - UR_IP6_HLEN); - ip6hdr->hop_lim = 255; - ip6hdr->next_header = UR_IPPROTO_UDP; - ip6hdr->src.m8[0] = 0xfc; /*src is local unicast address */ - ip6hdr->src.m8[6] = prefix.prefix.m8[6]; - ip6hdr->src.m8[7] = prefix.prefix.m8[7]; - ip6hdr->src.m8[15] = 0x01; - ip6hdr->dest.m8[0] = 0xfc; /*dest is local unicast address */ - ip6hdr->dest.m8[6] = prefix.prefix.m8[6]; - ip6hdr->dest.m8[7] = prefix.prefix.m8[7]; - ip6hdr->dest.m8[15] = 0x02; - udphdr->src_port = htons(0xf0b1); - udphdr->dst_port = htons(0xf0b1); - udphdr->length = htons(sizeof(ip6_buffer) - UR_IP6_HLEN); - udphdr->chksum = htons(0xffbb); - YUNIT_ASSERT(UR_ERROR_NONE == lp_header_compress(ip6_buffer, lowpan_buffer, &ip_hdr_len, &lowpan_hdr_len)); - memcpy(lowpan_buffer + lowpan_hdr_len, ip6_buffer + ip_hdr_len, sizeof(ip6_buffer) - ip_hdr_len); - *((uint16_t *)&iphc_header) = ntohs(*((uint16_t *)lowpan_buffer)); - YUNIT_ASSERT(IPHC_DISPATCH == iphc_header.DP); - YUNIT_ASSERT(TC_FL_BOTH_ELIDED == iphc_header.TF); - YUNIT_ASSERT(NEXT_HEADER_ELIDED == iphc_header.NH); - YUNIT_ASSERT(HOP_LIM_255 == iphc_header.HLIM); - YUNIT_ASSERT(STATELESS_COMPRESS == iphc_header.CID); - YUNIT_ASSERT(STATELESS_COMPRESS == iphc_header.SAC); - YUNIT_ASSERT(STATELESS_COMPRESS == iphc_header.DAC); - YUNIT_ASSERT(UCAST_ADDR_ELIDED == iphc_header.SAM); - YUNIT_ASSERT(UCAST_ADDR_ELIDED == iphc_header.DAM); - nhc_header = *((nhc_header_t *)(lowpan_buffer + sizeof(iphc_header))); - YUNIT_ASSERT(NHC_UDP_DISPATCH == nhc_header.DP); - YUNIT_ASSERT(CHKSUM_APPENDED == nhc_header.C); - YUNIT_ASSERT(BOTH_PORT_COMPRESSED == nhc_header.P); - YUNIT_ASSERT((UR_IP6_HLEN + UR_UDP_HLEN) == ip_hdr_len); - YUNIT_ASSERT(6 == lowpan_hdr_len); - - ip_hdr_len = 18; - src.addr.len = 2; - src.addr.short_addr = 0x0001; - dest.addr.len = 2; - dest.addr.short_addr = 0x0002; - error = lp_header_decompress(lowpan_buffer, &ip_hdr_len, &lowpan_hdr_len, - &src, &dest); - YUNIT_ASSERT(error == UR_ERROR_NONE); - YUNIT_ASSERT(0 == memcmp(ip6_buffer, lowpan_buffer, ip_hdr_len)); - - ip6hdr->v_tc_fl = htonl((6 << 28) | (1 << 20)); /* TC=1, Fl=0 */ - ip6hdr->hop_lim = 64; - ip6hdr->next_header = UR_IPPROTO_UDP; - ip6hdr->src.m8[0] = 0xfc; /*src is local address that can be compressed to 16bit */ - memcpy(&ip6hdr->src.m8[8], FIXED_IID, 6); - ip6hdr->dest.m8[0] = 0xff; /*dest is multicast address that can be compressed to 8bit*/ - ip6hdr->dest.m8[6] = 0x00; - ip6hdr->dest.m8[7] = 0x00; - ip6hdr->dest.m8[1] = 0x02; - udphdr->src_port = htons(0xf0b1); - udphdr->dst_port = htons(0x00b1); - YUNIT_ASSERT(UR_ERROR_NONE == lp_header_compress(ip6_buffer, lowpan_buffer, &ip_hdr_len, &lowpan_hdr_len)); - memcpy(lowpan_buffer + lowpan_hdr_len, ip6_buffer + ip_hdr_len, sizeof(ip6_buffer) - ip_hdr_len); - *((uint16_t *)&iphc_header) = ntohs(*((uint16_t *)lowpan_buffer)); - YUNIT_ASSERT(TC_APENDED_FL_ELIDED == iphc_header.TF); - YUNIT_ASSERT(HOP_LIM_64 == iphc_header.HLIM); - YUNIT_ASSERT(UCAST_ADDR_16BIT == iphc_header.SAM); - YUNIT_ASSERT(MCAST_ADDR_8BIT == iphc_header.DAM); - nhc_header = *((nhc_header_t *)(lowpan_buffer + sizeof(iphc_header) + 3)); - YUNIT_ASSERT(SRC_PORT_COMPRESSED == nhc_header.P); - YUNIT_ASSERT((UR_IP6_HLEN + UR_UDP_HLEN) == ip_hdr_len); - YUNIT_ASSERT(12 == lowpan_hdr_len); - - ip_hdr_len = 24; - src.addr.len = 2; - src.addr.short_addr = 0x0001; - dest.addr.len = 2; - dest.addr.short_addr = 0xffff; - - error = lp_header_decompress(lowpan_buffer, &ip_hdr_len, &lowpan_hdr_len, - &src, &dest); - YUNIT_ASSERT(error == UR_ERROR_NONE); - YUNIT_ASSERT(0 == memcmp(ip6_buffer, lowpan_buffer, ip_hdr_len)); - - ip6hdr->v_tc_fl = htonl((6 << 28) | (1 << 0)); /* TC=0, Fl=1 */ - ip6hdr->hop_lim = 1; - ip6hdr->next_header = UR_IPPROTO_UDP; - ip6hdr->src.m8[8] = 0xff; /*src is local address that can be compressed to 64bit */ - ip6hdr->dest.m8[13] = 0x03; /*dest is multicast address that can be compressed to 32bit*/ - udphdr->src_port = htons(0x00b1); - udphdr->dst_port = htons(0xf0b1); - YUNIT_ASSERT(UR_ERROR_NONE == lp_header_compress(ip6_buffer, lowpan_buffer, &ip_hdr_len, &lowpan_hdr_len)); - memcpy(lowpan_buffer + lowpan_hdr_len, ip6_buffer + ip_hdr_len, sizeof(ip6_buffer) - ip_hdr_len); - *((uint16_t *)&iphc_header) = ntohs(*((uint16_t *)lowpan_buffer)); - YUNIT_ASSERT(DCSP_ELEDED_ECN_FL_APPENDED == iphc_header.TF); - YUNIT_ASSERT(HOP_LIM_1 == iphc_header.HLIM); - YUNIT_ASSERT(UCAST_ADDR_64BIT == iphc_header.SAM); - YUNIT_ASSERT(MCAST_ADDR_32BIT == iphc_header.DAM); - nhc_header = *((nhc_header_t *)(lowpan_buffer + sizeof(iphc_header) + 15)); - YUNIT_ASSERT(DST_PORT_COMPRESSED == nhc_header.P); - YUNIT_ASSERT((UR_IP6_HLEN + UR_UDP_HLEN) == ip_hdr_len); - YUNIT_ASSERT(23 == lowpan_hdr_len); - - ip_hdr_len = 35; - src.addr.len = 2; - src.addr.short_addr = 0x0001; - dest.addr.len = 2; - dest.addr.short_addr = 0xffff; - error = lp_header_decompress(lowpan_buffer, &ip_hdr_len, &lowpan_hdr_len, - &src, &dest); - YUNIT_ASSERT(error == UR_ERROR_NONE); - YUNIT_ASSERT(0 == memcmp(ip6_buffer, lowpan_buffer, ip_hdr_len)); - - ip6hdr->v_tc_fl = htonl((6 << 28) | (1 << 20) | (1 << 0)); /* TC=1, Fl=1 */ - ip6hdr->hop_lim = 1; - ip6hdr->src.m8[0] = 0x0f; /*src is address that can not be compressed */ - ip6hdr->dest.m8[11] = 0x03; /*dest is multicast address that can be compressed to 48bit*/ - ip6hdr->next_header = UR_IPPROTO_UDP; - udphdr->src_port = htons(0x00b1); - udphdr->dst_port = htons(0x00b1); - YUNIT_ASSERT(UR_ERROR_NONE == lp_header_compress(ip6_buffer, lowpan_buffer, &ip_hdr_len, &lowpan_hdr_len)); - memcpy(lowpan_buffer + lowpan_hdr_len, ip6_buffer + ip_hdr_len, sizeof(ip6_buffer) - ip_hdr_len); - *((uint16_t *)&iphc_header) = ntohs(*((uint16_t *)lowpan_buffer)); - YUNIT_ASSERT(TC_FL_BOTH_APEENDED == iphc_header.TF); - YUNIT_ASSERT(HOP_LIM_1 == iphc_header.HLIM); - YUNIT_ASSERT(UCAST_ADDR_128BIT == iphc_header.SAM); - YUNIT_ASSERT(MCAST_ADDR_48BIT == iphc_header.DAM); - nhc_header = *((nhc_header_t *)(lowpan_buffer + sizeof(iphc_header) + 26)); - YUNIT_ASSERT(NO_PORT_COMPRESSED == nhc_header.P); - YUNIT_ASSERT((UR_IP6_HLEN + UR_UDP_HLEN) == ip_hdr_len); - YUNIT_ASSERT(35 == lowpan_hdr_len); - - ip_hdr_len = 47; - src.addr.len = 2; - src.addr.short_addr = 0x0001; - dest.addr.len = 2; - dest.addr.short_addr = 0x0002; - error = lp_header_decompress(lowpan_buffer, &ip_hdr_len, &lowpan_hdr_len, - &src, &dest); - YUNIT_ASSERT(error == UR_ERROR_NONE); - YUNIT_ASSERT(0 == memcmp(ip6_buffer, lowpan_buffer, ip_hdr_len)); - - ip6hdr->v_tc_fl = htonl((6 << 28) | (1 << 0)); /* TC=0, Fl=1 */ - ip6hdr->hop_lim = 20; - ip6hdr->dest.m8[9] = 0x03; /*dest is multicast address that can not be compressed */ - ip6hdr->next_header = UR_IPPROTO_ICMPV6; - ip6hdr->src.m8[0] = 0xff; - ip6hdr->dest.m8[0] = 0xff; - YUNIT_ASSERT(UR_ERROR_NONE == lp_header_compress(ip6_buffer, lowpan_buffer, &ip_hdr_len, &lowpan_hdr_len)); - memcpy(lowpan_buffer + lowpan_hdr_len, ip6_buffer + ip_hdr_len, sizeof(ip6_buffer) - ip_hdr_len); - *((uint16_t *)&iphc_header) = ntohs(*((uint16_t *)lowpan_buffer)); - YUNIT_ASSERT(DCSP_ELEDED_ECN_FL_APPENDED == iphc_header.TF); - YUNIT_ASSERT(HOP_LIM_APPENDED == iphc_header.HLIM); - YUNIT_ASSERT(NEXT_HEADER_APPENDED == iphc_header.NH); - YUNIT_ASSERT(UCAST_ADDR_128BIT == iphc_header.SAM); - YUNIT_ASSERT(MCAST_ADDR_128BIT == iphc_header.DAM); - YUNIT_ASSERT(UR_IP6_HLEN == ip_hdr_len); - YUNIT_ASSERT(39 == lowpan_hdr_len); - - ip_hdr_len = 59; - src.addr.len = 2; - src.addr.short_addr = 0x0001; - dest.addr.len = 2; - dest.addr.short_addr = 0x0002; - error = lp_header_decompress(lowpan_buffer, &ip_hdr_len, &lowpan_hdr_len, - &src, &dest); - YUNIT_ASSERT(error == UR_ERROR_NONE); - YUNIT_ASSERT(0 == memcmp(ip6_buffer, lowpan_buffer, ip_hdr_len)); - - ip6hdr->v_tc_fl = htonl((4 << 28)); /* IPv4 */ - YUNIT_ASSERT(UR_ERROR_FAIL == lp_header_compress(ip6_buffer, lowpan_buffer, &ip_hdr_len, &lowpan_hdr_len)); - - uint8_t tmp = lowpan_buffer[1]; - lowpan_buffer[1] = tmp | 0x80; /* STATEFULL compress */ - error = lp_header_decompress(lowpan_buffer, &ip_hdr_len, &lowpan_hdr_len, - &src, &dest); - YUNIT_ASSERT(error != UR_ERROR_NONE); - - lowpan_buffer[1] = tmp | 0x40; /* STATEFULL compress */ - error = lp_header_decompress(lowpan_buffer, &ip_hdr_len, &lowpan_hdr_len, - &src, &dest); - YUNIT_ASSERT(error != UR_ERROR_NONE); - - lowpan_buffer[1] = tmp | 0x04; /* STATEFULL compress */ - error = lp_header_decompress(lowpan_buffer, &ip_hdr_len, &lowpan_hdr_len, - &src, &dest); - YUNIT_ASSERT(error != UR_ERROR_NONE); - - /*************** test reassemble functions *******************/ - message_t *reass_pkt = NULL; - message_t *message = NULL; - uint8_t *data; - uint16_t size = 256, length = 96, offset = 0; - message_info_t *info; - - message = message_alloc(length + sizeof(frag_header_t) - 1, UT_MSG); - info = message->info; - data = message_get_payload(message); - data[0] = 0xC0 | ((size & 0x0700) >> 8); /* FRAG_1 packet from 0x1000 */ - data[1] = size & 0xff; - data[2] = 0x00; - data[3] = 0x01; - info->src.addr.len = SHORT_ADDR_SIZE; - info->src.addr.short_addr = 0x1000; - YUNIT_ASSERT(UR_ERROR_NONE == frags_reassemble(message, &reass_pkt)); - YUNIT_ASSERT_PTR_NULL(reass_pkt); - - YUNIT_ASSERT(UR_ERROR_FAIL == frags_reassemble(NULL, &reass_pkt)); - - message = message_alloc(length + sizeof(frag_header_t) - 1, UT_MSG); - info = message->info; - data = message_get_payload(message); - data[0] = 0xC0 | ((size & 0x0700) >> 8); /* repeated FRAG_1 packet from 0x1000 */ - data[1] = size & 0xff; - data[2] = 0x00; - data[3] = 0x01; - info->src.addr.len = SHORT_ADDR_SIZE; - info->src.addr.short_addr = 0x1000; - YUNIT_ASSERT(UR_ERROR_FAIL == frags_reassemble(message, &reass_pkt)); - message_free(message); - - message = message_alloc(length + sizeof(frag_header_t) - 1, UT_MSG); - info = message->info; - data = message_get_payload(message); - data[0] = 0xC0 | ((size & 0x0700) >> 8); /* FRAG_1 packet from 0x2000 */ - data[1] = size & 0xff; - data[2] = 0x00; - data[3] = 0x02; - info->src.addr.len = SHORT_ADDR_SIZE; - info->src.addr.short_addr = 0x2000; - YUNIT_ASSERT(UR_ERROR_NONE == frags_reassemble(message, &reass_pkt)); - YUNIT_ASSERT_PTR_NULL(reass_pkt); - - offset = length; - message = message_alloc(length + sizeof(frag_header_t), UT_MSG); - info = message->info; - data = message_get_payload(message); - data[0] = 0xE0 | ((size & 0x0700) >> 8); /* FRAG_N packet from 0x2000 */ - data[1] = size & 0xff; - data[2] = 0x00; - data[3] = 0x02; - data[4] = (offset >> 3); - info->src.addr.len = SHORT_ADDR_SIZE; - info->src.addr.short_addr = 0x2000; - YUNIT_ASSERT(UR_ERROR_NONE == frags_reassemble(message, &reass_pkt)); - YUNIT_ASSERT_PTR_NULL(reass_pkt); - - message = message_alloc(length + sizeof(frag_header_t), UT_MSG); - info = message->info; - data = message_get_payload(message); - data[0] = 0xE0 | ((size & 0x0700) >> 8); /* repeated FRAG_N packet from 0x2000 */ - data[1] = size & 0xff; - data[2] = 0x00; - data[3] = 0x02; - data[4] = (offset >> 3); - info->src.addr.len = SHORT_ADDR_SIZE; - info->src.addr.short_addr = 0x2000; - YUNIT_ASSERT(UR_ERROR_FAIL == frags_reassemble(message, &reass_pkt)); - message_free(message); - YUNIT_ASSERT_PTR_NULL(reass_pkt); - - offset += length; - message = message_alloc(size - 2 * length + sizeof(frag_header_t), UT_MSG); - info = message->info; - data = message_get_payload(message); - data[0] = 0xE0 | ((size & 0x0700) >> 8); /* FRAG_N packet from 0x2000 */ - data[1] = size & 0xff; - data[2] = 0x00; - data[3] = 0x02; - data[4] = (offset >> 3); - info->src.addr.len = SHORT_ADDR_SIZE; - info->src.addr.short_addr = 0x2000; - YUNIT_ASSERT(UR_ERROR_NONE == frags_reassemble(message, &reass_pkt)); - YUNIT_ASSERT_PTR_NOT_NULL(reass_pkt); - - offset += length; - message = message_alloc(length + sizeof(frag_header_t), UT_MSG); - info = message->info; - data = message_get_payload(message); - data[0] = 0xE0 | ((size & 0x0700) >> 8); /*rougue FRAG_N packet from 0x2000 */ - data[1] = size & 0xff; - data[2] = 0x00; - data[3] = 0x03; - data[4] = (offset >> 3); - info->src.addr.len = SHORT_ADDR_SIZE; - info->src.addr.short_addr = 0x2000; - YUNIT_ASSERT(UR_ERROR_FAIL == frags_reassemble(message, &reass_pkt)); - message_free(message); - - message = message_alloc(length + sizeof(frag_header_t) - 1, UT_MSG); - info = message->info; - data = message_get_payload(message); - data[0] = 0xC0 | ((size & 0x0700) >> 8); /* FRAG_1 packet from 0x2000 */ - data[1] = size & 0xff; - data[2] = 0x00; - data[3] = 0x04; - info->src.addr.len = SHORT_ADDR_SIZE; - info->src.addr.short_addr = 0x2000; - YUNIT_ASSERT(UR_ERROR_NONE == frags_reassemble(message, &reass_pkt)); - YUNIT_ASSERT_PTR_NULL(reass_pkt); - - offset += length; - offset += length; /* pack with unexpected offset */ - message = message_alloc(size - 2 * length + sizeof(frag_header_t), UT_MSG); - info = message->info; - data = message_get_payload(message); - data[0] = 0xE0 | ((size & 0x0700) >> 8); /* FRAG_N packet from 0x2000 */ - data[1] = size & 0xff; - data[2] = 0x00; - data[3] = 0x04; - data[4] = (offset >> 3); - info->src.addr.len = SHORT_ADDR_SIZE; - info->src.addr.short_addr = 0x2000; - YUNIT_ASSERT(UR_ERROR_FAIL == frags_reassemble(message, &reass_pkt)); - message_free(message); - - message = message_alloc(length + sizeof(frag_header_t) - 1, UT_MSG); - info = message->info; - data = message_get_payload(message); - data[0] = 0xC0 | ((size & 0x0700) >> 8); /* FRAG_1 packet from 0x3000 */ - data[1] = size & 0xff; - data[2] = 0x00; - data[3] = 0x02; - info->src.addr.len = SHORT_ADDR_SIZE; - info->src.addr.short_addr = 0x3000; - YUNIT_ASSERT(UR_ERROR_NONE == frags_reassemble(message, &reass_pkt)); - YUNIT_ASSERT_PTR_NULL(reass_pkt); - - message = message_alloc(length + sizeof(frag_header_t) - 1, UT_MSG); - info = message->info; - data = message_get_payload(message); - data[0] = 0xC0 | ((size & 0x0700) >> 8); /* FRAG_1 packet from 0x4000 */ - data[1] = size & 0xff; - data[2] = 0x00; - data[3] = 0x02; - info->src.addr.len = SHORT_ADDR_SIZE; - info->src.addr.short_addr = 0x4000; - YUNIT_ASSERT(UR_ERROR_NONE == frags_reassemble(message, &reass_pkt)); - YUNIT_ASSERT_PTR_NULL(reass_pkt); - - message = message_alloc(length + sizeof(frag_header_t), UT_MSG); - info = message->info; - data = message_get_payload(message); - data[0] = 0xA0 | ((size & 0x0700) >> 8); /* packet with wrong DISPATCH */ - data[1] = size & 0xff; - data[2] = 0x00; - data[3] = 0x02; - data[4] = (offset >> 3); - YUNIT_ASSERT(UR_ERROR_FAIL == frags_reassemble(message, &reass_pkt)); - message_free(message); - YUNIT_ASSERT_PTR_NULL(reass_pkt); - - message_free(reass_pkt); - extern void frags_cleanup(bool force); - frags_cleanup(true); -} diff --git a/test/testcase/kernel/protocols/mesh_test/lwip_adapter_test.c b/test/testcase/kernel/protocols/mesh_test/lwip_adapter_test.c deleted file mode 100644 index 0d3df2b95c..0000000000 --- a/test/testcase/kernel/protocols/mesh_test/lwip_adapter_test.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#include -#include -#include - -#include "yunit.h" - -#include "lwip/ip6_addr.h" -#include "lwip/sockets.h" - -#include "umesh_types.h" -#include "utilities/message.h" -#include "ip/ip.h" -#include "ip/lwip_adapter.h" - -#if LWIP_IPV6 -extern struct netif *ur_adapter_ip6_route(const ip6_addr_t *src, const ip6_addr_t *dest); -extern bool ur_adapter_is_mcast_subscribed(const ip6_addr_t *addr); -#endif -extern void interface_start(void); -extern void interface_stop(void); - -void test_uradar_lwip_adapter_case(void) -{ - YUNIT_ASSERT(UR_ERROR_NONE == ur_adapter_interface_update()); - interface_start(); - YUNIT_ASSERT(UR_ERROR_NONE == ur_adapter_interface_up()); - -#if LWIP_IPV6 - YUNIT_ASSERT(NULL != ur_adapter_ip6_route(NULL, NULL)); - - ip6_addr_t ip6addr; - memset(ip6addr.addr, 0x00, sizeof(ip6addr)); - ip6addr.addr[0] = 0x00110011; - YUNIT_ASSERT(false == ur_adapter_is_mcast_subscribed(&ip6addr)); -#endif - - message_t *message; - message = message_alloc(60, UT_MSG); - ur_ip6_header_t *ip6_header; - ip6_header = (ur_ip6_header_t *)message_get_payload(message); - memset(ip6_header, 0x00, UR_IP6_HLEN); - ip6_header->v_tc_fl = htonl(6<<24); - ip6_header->len = 60 - UR_IP6_HLEN; - ip6_header->next_header = 17; - ip6_header->hop_lim = 255; - YUNIT_ASSERT(UR_ERROR_NONE == ur_adapter_input(message->data)); - - int socket; - ur_udp_header_t *header; - ur_ip6_addr_t dst; - header = (ur_udp_header_t *)malloc(16); - header->src_port = htons(2016); - header->dst_port = htons(2016); - header->length = htons(16); - header->chksum = 0; - string_to_ip6_addr("F'00::0", &dst); - string_to_ip6_addr("fc00::0", &dst); - socket = lwip_socket(AF_INET6, SOCK_RAW, IPPROTO_UDP); - ip_sendto(socket, (const uint8_t *)header, 16, &dst, 0); - /* TODO: sleep to wait send actually happen */ - free(header); - - - interface_stop(); - YUNIT_ASSERT(UR_ERROR_NONE == ur_adapter_interface_down()); -} - - diff --git a/test/testcase/kernel/protocols/mesh_test/mcast_test.c b/test/testcase/kernel/protocols/mesh_test/mcast_test.c deleted file mode 100644 index b843e03661..0000000000 --- a/test/testcase/kernel/protocols/mesh_test/mcast_test.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#include "yunit.h" - -#include "umesh.h" -#include "core/link_mgmt.h" -#include "utilities/logging.h" -#include "utilities/message.h" -#include "tools/cli.h" -#include "ip/lwip_adapter.h" -#include "lwip/ip.h" - -#include "dda_util.h" - -void test_uradar_mcast_case(void) -{ - neighbor_t *attach_node; - set_line_rssi(11, 14); - - cmd_to_agent("stop"); - start_node_ext(12, MODE_RX_ON, -1, -1); - check_p2p_str_wait("leader", 12, "testcmd state", 10); - start_node_ext(13, MODE_RX_ON, -1, -1); - check_p2p_str_wait("router", 13, "testcmd state", 10); - start_node_ext(14, MODE_RX_ON | MODE_MOBILE, -1, -1); - check_p2p_str_wait("leaf", 14, "testcmd state", 10); - - cmd_to_agent("mode FIXED"); - cmd_to_agent("start"); - check_cond_wait(!!(attach_node = umesh_mm_get_attach_node()), 15); - - cmd_to_master("sendall status"); - - char ping_cmd[64]; - const ip6_addr_t *myaddr; - - myaddr = ur_adapter_get_mcast_ipaddr(); - snprintf(ping_cmd, sizeof ping_cmd, "send 12 autotest " IP6_ADDR_FMT, IP6_ADDR_DATA(((ur_ip6_addr_t *)myaddr))); - cmd_to_master(ping_cmd); - check_p2p_str_wait("3", 12, "testcmd autotest_acked", 10); - - myaddr = ur_adapter_get_default_ipaddr(); - snprintf(ping_cmd, sizeof ping_cmd, "send 12 autotest " IP6_ADDR_FMT " 1 1200", IP6_ADDR_DATA(((ur_ip6_addr_t *)myaddr))); - cmd_to_master(ping_cmd); - check_p2p_str_wait("1", 12, "testcmd autotest_acked", 10); - - cmd_to_agent("stop"); - stop_node(14); - stop_node(13); - stop_node(12); -} diff --git a/test/testcase/kernel/protocols/mesh_test/mesh_mgmt_test.c b/test/testcase/kernel/protocols/mesh_test/mesh_mgmt_test.c deleted file mode 100644 index 0a70fc745d..0000000000 --- a/test/testcase/kernel/protocols/mesh_test/mesh_mgmt_test.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#include "yunit.h" - -#include "umesh.h" -#include "core/link_mgmt.h" -#include "core/mesh_mgmt.h" -#include "core/mesh_forwarder.h" -#include "hal/interfaces.h" - -#define INVALID_UEID "\xff\xff\xff\xff\xff\xff\xff\xff" - -extern void hal_arch_time_msleep(int ms); -extern void ur_ut_send_cmd_to_ddm(const char *cmd); - -static ur_error_t dummy_interface_up(void) -{ - return UR_ERROR_NONE; -} - -static ur_error_t dummy_interface_down(void) -{ - return UR_ERROR_NONE; -} - -void test_uradar_mesh_mgmt_case(void) -{ - interface_start(); - YUNIT_ASSERT(UR_ERROR_NONE == umesh_mm_start()); - YUNIT_ASSERT(UR_ERROR_NONE == umesh_mm_stop()); - YUNIT_ASSERT(DEVICE_STATE_DISABLED == umesh_mm_get_device_state()); - YUNIT_ASSERT(BCAST_SID == umesh_mm_get_local_sid()); - uint8_t *ueid; - YUNIT_ASSERT_PTR_NOT_NULL((ueid = umesh_mm_get_local_ueid())); - YUNIT_ASSERT(0 != memcmp(ueid, INVALID_UEID, 8)); - - mac_address_t mac_addr; - mac_addr.len = sizeof(mac_addr.addr); - memset(mac_addr.addr, 0x00, sizeof(mac_addr.addr)); - mac_addr.addr[0] = 0x03; - YUNIT_ASSERT_PTR_NULL(get_neighbor_by_mac_addr((const uint8_t *)&mac_addr)); - YUNIT_ASSERT_PTR_NULL(get_neighbor_by_sid(NULL, 0x1200, umesh_mm_get_meshnetid(NULL))); - uint8_t ueid1[8] = {0}; - YUNIT_ASSERT_PTR_NULL(get_neighbor_by_mac_addr(ueid1)); - YUNIT_ASSERT(0 != umesh_mm_get_meshnetid(NULL)); - YUNIT_ASSERT_PTR_NOT_NULL(umesh_mm_get_mac_address()); - YUNIT_ASSERT(UR_ERROR_NONE == umesh_mm_set_mode(MODE_MOBILE)); - YUNIT_ASSERT(MODE_MOBILE == umesh_mm_get_mode()); - YUNIT_ASSERT(UR_ERROR_NONE == umesh_mm_set_mode(MODE_RX_ON)); - YUNIT_ASSERT(MODE_RX_ON == umesh_mm_get_mode()); - YUNIT_ASSERT_PTR_NULL(umesh_mm_get_attach_node()); - - uint8_t tlvs[10]; - uint8_t length = 10; - umesh_mm_init_tv_base((mm_tv_t *)tlvs, TYPE_VERSION); - YUNIT_ASSERT_PTR_NOT_NULL(umesh_mm_get_tv(tlvs, length, TYPE_VERSION)); - umesh_mm_init_tlv_base((mm_tlv_t *)tlvs, TYPE_FORWARD_RSSI, 1); - - if (umesh_mm_get_device_state() != DEVICE_STATE_LEADER) { - YUNIT_ASSERT(0x0000 != umesh_mm_get_meshnetid(NULL)); - } - - YUNIT_ASSERT(UR_ERROR_NONE == umesh_mm_stop()); - YUNIT_ASSERT(UR_ERROR_NONE == umesh_mm_start()); - YUNIT_ASSERT(UR_ERROR_NONE == umesh_mm_stop()); - interface_stop(); -} - - diff --git a/test/testcase/kernel/protocols/mesh_test/mesh_test.mk b/test/testcase/kernel/protocols/mesh_test/mesh_test.mk deleted file mode 100644 index e0969a63c7..0000000000 --- a/test/testcase/kernel/protocols/mesh_test/mesh_test.mk +++ /dev/null @@ -1,15 +0,0 @@ -NAME := mesh_test - -$(NAME)_COMPONENTS += protocols.mesh dda - -$(NAME)_INCLUDES += include -$(NAME)_INCLUDES += ../../../../../tools/dda - -include test/testcase/kernel/protocols/mesh_test/filelists.mk -$(NAME)_SOURCES += $(MESHYTSFILE) - -$(NAME)_CFLAGS += -Wall -Werror -Wno-unused-variable -Wno-unused-parameter -Wno-implicit-function-declaration -$(NAME)_CFLAGS += -Wno-type-limits -Wno-sign-compare -Wno-pointer-sign -Wno-uninitialized -$(NAME)_CFLAGS += -Wno-return-type -Wno-unused-function -Wno-unused-but-set-variable -$(NAME)_CFLAGS += -Wno-unused-value -Wno-strict-aliasing - diff --git a/test/testcase/kernel/protocols/mesh_test/misc_test.c b/test/testcase/kernel/protocols/mesh_test/misc_test.c deleted file mode 100644 index 81f85d9bba..0000000000 --- a/test/testcase/kernel/protocols/mesh_test/misc_test.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#include "yunit.h" - -#include "core/mesh_mgmt.h" -#include "utilities/mac_whitelist.h" -#include "utilities/message.h" - -void test_uradar_misc_case(void) -{ - message_t *message; - message = message_alloc(100, UT_MSG); - YUNIT_ASSERT(UR_ERROR_FAIL == message_set_msglen(NULL, 100)); - YUNIT_ASSERT(UR_ERROR_NONE == message_set_msglen(message, 100)); - YUNIT_ASSERT(UR_ERROR_FAIL == message_set_buflen(NULL, 100)); - YUNIT_ASSERT(UR_ERROR_NONE == message_set_buflen(message, 100)); - YUNIT_ASSERT(0 == message_get_buflen(NULL)); - YUNIT_ASSERT(100 == message_get_buflen(message)); - - message_t *message2, *message3; - message2 = message_alloc(30, UT_MSG); - message3 = message_alloc(30, UT_MSG); - YUNIT_ASSERT(UR_ERROR_FAIL == message_concatenate(NULL, message2, false)); - YUNIT_ASSERT(UR_ERROR_NONE == message_concatenate(message, message2, false)); - YUNIT_ASSERT(UR_ERROR_NONE == message_concatenate(message, message3, false)); - message_free(message); - - extern ur_error_t nd_set_stable_meshnetid(uint16_t meshnetid); - extern uint16_t nd_get_stable_meshnetid(void); - extern uint8_t nd_get_version(network_context_t *network); - if (umesh_mm_get_device_state() == DEVICE_STATE_LEADER) { - YUNIT_ASSERT(UR_ERROR_NONE == nd_set_stable_meshnetid(0x1000)); - YUNIT_ASSERT(0x1000 == nd_get_stable_meshnetid()); - YUNIT_ASSERT(0 != nd_get_version(NULL)); - } else { - YUNIT_ASSERT(UR_ERROR_FAIL == nd_set_stable_meshnetid(0x1000)); - } - - YUNIT_ASSERT_PTR_NOT_NULL(whitelist_get_entries()); - mac_address_t mac_addr; - whitelist_entry_t *entry; - int8_t rssi; - mac_addr.len = sizeof(mac_addr.addr); - memset(mac_addr.addr, 0x00, mac_addr.len); - mac_addr.addr[0] = 0x12; - YUNIT_ASSERT_PTR_NOT_NULL(whitelist_add(&mac_addr)); - entry = (whitelist_entry_t *)whitelist_get_entries(); - YUNIT_ASSERT_PTR_NOT_NULL(entry); - whitelist_clear_constant_rssi(entry); - YUNIT_ASSERT(UR_ERROR_FAIL == whitelist_get_constant_rssi(entry, &rssi)); -} - - diff --git a/test/testcase/kernel/protocols/mesh_test/rsid_allocator_test.c b/test/testcase/kernel/protocols/mesh_test/rsid_allocator_test.c deleted file mode 100644 index f8f96d6b0f..0000000000 --- a/test/testcase/kernel/protocols/mesh_test/rsid_allocator_test.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#include "yunit.h" - -#include "core/sid_allocator.h" -#include "hal/interfaces.h" -#include "hal/interface_context.h" - -void test_uradar_rsid_allocator_case(void) -{ - ur_node_id_t node_id = {.ueid = {0x00, 0x02, 0x03,0x04, 0x05, 0x06, 0x07, 0x08}, - .sid = INVALID_SID, - .attach_sid = 0x0000}; - uint16_t index; - allocator_t hdl = rsid_allocator_init(SHORT_RANDOM_SID); - - for(index = 1; index <= 11; index++) { - node_id.ueid[0] += 1; - node_id.sid = INVALID_SID; - YUNIT_ASSERT(UR_ERROR_NONE == rsid_allocate_sid(hdl, &node_id)); - YUNIT_ASSERT(index == node_id.sid); - } - YUNIT_ASSERT(11 == rsid_get_allocated_number(hdl)); - - node_id.ueid[0] += 1; - node_id.sid = 10; - YUNIT_ASSERT(UR_ERROR_NONE == rsid_allocate_sid(hdl, &node_id)); - YUNIT_ASSERT(12 == node_id.sid); - YUNIT_ASSERT(12 == rsid_get_allocated_number(hdl)); - - rsid_allocator_deinit(hdl); - - hdl = rsid_allocator_init(SHORT_RANDOM_SID); - - node_id.ueid[0] = 0; - for (index = 1; index <= 11; index++) { - node_id.ueid[0] += 1; - node_id.sid = index; - YUNIT_ASSERT(UR_ERROR_NONE == rsid_allocate_sid(hdl, &node_id)); - YUNIT_ASSERT(index == node_id.sid); - } - - node_id.ueid[0] = 10; - node_id.sid = 10; - YUNIT_ASSERT(UR_ERROR_NONE == rsid_allocate_sid(hdl, &node_id)); - YUNIT_ASSERT(10 == node_id.sid); - YUNIT_ASSERT(11 == rsid_get_allocated_number(hdl)); - - rsid_allocator_deinit(hdl); -} diff --git a/test/testcase/kernel/protocols/mesh_test/scales_10nodes_test.c b/test/testcase/kernel/protocols/mesh_test/scales_10nodes_test.c deleted file mode 100644 index 2391cf3325..0000000000 --- a/test/testcase/kernel/protocols/mesh_test/scales_10nodes_test.c +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#include "yunit.h" - -#include "aos/aos.h" -#include "aos/kernel.h" - -#include "core/mesh_mgmt.h" - -#include "dda_util.h" - -extern void topo_test_function(uint16_t first_node, uint16_t num, uint32_t timeout); -void test_uradar_scales_10nodes_case(void) -{ - topo_test_function(11, 10, 80); -} - diff --git a/test/testcase/kernel/protocols/mesh_test/scales_20nodes_test.c b/test/testcase/kernel/protocols/mesh_test/scales_20nodes_test.c deleted file mode 100644 index 677dec6d65..0000000000 --- a/test/testcase/kernel/protocols/mesh_test/scales_20nodes_test.c +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#include "yunit.h" - -#include "aos/aos.h" -#include "aos/kernel.h" - -#include "core/mesh_mgmt.h" - -#include "dda_util.h" - -extern void topo_test_function(uint16_t first_node, uint16_t num, uint32_t timeout); -void test_uradar_scales_20nodes_case(void) -{ - topo_test_function(11, 20, 150); -} - diff --git a/test/testcase/kernel/protocols/mesh_test/scales_30nodes_test.c b/test/testcase/kernel/protocols/mesh_test/scales_30nodes_test.c deleted file mode 100644 index 7e778998bf..0000000000 --- a/test/testcase/kernel/protocols/mesh_test/scales_30nodes_test.c +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#include "yunit.h" - -#include "aos/aos.h" -#include "aos/kernel.h" - -#include "core/mesh_mgmt.h" - -#include "dda_util.h" - -extern void topo_test_function(uint16_t first_node, uint16_t num, uint32_t timeout); -void test_uradar_scales_30nodes_case(void) -{ - topo_test_function(11, 30, 200); -} - diff --git a/test/testcase/kernel/protocols/mesh_test/scales_5nodes_test.c b/test/testcase/kernel/protocols/mesh_test/scales_5nodes_test.c deleted file mode 100644 index 03912c86d2..0000000000 --- a/test/testcase/kernel/protocols/mesh_test/scales_5nodes_test.c +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#include "yunit.h" - -#include "aos/aos.h" -#include "aos/kernel.h" - -#include "core/mesh_mgmt.h" - -#include "dda_util.h" - -extern void topo_test_function(uint16_t first_node, uint16_t num, uint32_t timeout); -void test_uradar_scales_5nodes_case(void) -{ - topo_test_function(11, 5, 60); -} - diff --git a/test/testcase/kernel/protocols/mesh_test/sid_allocator_test.c b/test/testcase/kernel/protocols/mesh_test/sid_allocator_test.c deleted file mode 100644 index c3de710152..0000000000 --- a/test/testcase/kernel/protocols/mesh_test/sid_allocator_test.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#include "yunit.h" - -#include "umesh_types.h" -#include "core/sid_allocator.h" -#include "hal/interface_context.h" -#include "hal/interfaces.h" - -void test_uradar_sid_allocator_case(void) -{ - ur_node_id_t node_id = {.ueid = {0x00, 0x02, 0x03,0x04, 0x05, 0x06, 0x07, 0x08}, - .sid = INVALID_SID, - .attach_sid = 0x0000}; - uint16_t index; - allocator_t hdl = allocator_init(0x0000, STRUCTURED_SID); - - for(index = 1; index <= 11; index++) { - node_id.ueid[0] += 1; - YUNIT_ASSERT(UR_ERROR_NONE == allocate_sid(hdl, &node_id)); - YUNIT_ASSERT((index << 12) == node_id.sid); - } - YUNIT_ASSERT(11 == get_allocated_number(hdl)); - allocator_deinit(hdl); - - hdl = allocator_init(0x1000, STRUCTURED_SID); - node_id.sid = 0x1000; - free_sid(hdl, node_id.sid); - node_id.mode = MODE_RX_ON; - YUNIT_ASSERT(UR_ERROR_NONE == allocate_sid(hdl, &node_id)); - YUNIT_ASSERT(0x1100 == node_id.sid); - YUNIT_ASSERT(1 == get_allocated_number(hdl)); - - node_id.ueid[0] += 1; - YUNIT_ASSERT(UR_ERROR_NONE == allocate_sid(hdl, &node_id)); - - allocator_deinit(hdl); - - hdl = allocator_init(0x0000, STRUCTURED_SID); - node_id.ueid[0] += 1; - node_id.mode = MODE_MOBILE; - YUNIT_ASSERT(UR_ERROR_NONE == allocate_sid(hdl, &node_id)); - YUNIT_ASSERT(0xc001 == node_id.sid); - YUNIT_ASSERT(true == is_partial_function_sid(node_id.sid)); - YUNIT_ASSERT(1 == get_allocated_pf_number(hdl)); - YUNIT_ASSERT(UR_ERROR_NONE == allocate_sid(hdl, &node_id)); - YUNIT_ASSERT(0xc001 == node_id.sid); - YUNIT_ASSERT(true == is_partial_function_sid(node_id.sid)); - YUNIT_ASSERT(1 == get_allocated_pf_number(hdl)); - node_id.ueid[0] += 1; - node_id.mode = MODE_MOBILE; - YUNIT_ASSERT(UR_ERROR_NONE == allocate_sid(hdl, &node_id)); - YUNIT_ASSERT(0xc002 == node_id.sid); - YUNIT_ASSERT(true == is_partial_function_sid(node_id.sid)); - YUNIT_ASSERT(2 == get_allocated_pf_number(hdl)); - - allocator_deinit(hdl); -} diff --git a/test/testcase/kernel/protocols/mesh_test/sid_router_test.c b/test/testcase/kernel/protocols/mesh_test/sid_router_test.c deleted file mode 100644 index 38f2f94071..0000000000 --- a/test/testcase/kernel/protocols/mesh_test/sid_router_test.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#include - -#include "yunit.h" - -#include "core/router_mgr.h" -#include "core/mesh_mgmt.h" -#include "hal/interfaces.h" - -void test_uradar_sid_router_case(void) -{ - network_context_t network = { - .meshnetid = 0x100, - .attach_state = ATTACH_DONE - }; - netids_t netids; - - YUNIT_ASSERT(UR_ERROR_NONE == ur_router_set_default_router(SID_ROUTER)); - network.router = ur_get_router_by_id(SID_ROUTER); - network.router->cb.start(); - netids.meshnetid = network.meshnetid; - netids.sid = 0x1000; - network.router->cb.handle_subscribe_event(EVENT_SID_UPDATED, (uint8_t *)&netids, sizeof(netids_t)); - YUNIT_ASSERT(0x1000 == ur_router_get_next_hop(&network, 0x1000)); - YUNIT_ASSERT(0x0000 == ur_router_get_next_hop(&network, 0x0000)); - YUNIT_ASSERT(0x0000 == ur_router_get_next_hop(&network, 0x2000)); - YUNIT_ASSERT(0x0000 == ur_router_get_next_hop(&network, 0x2100)); - YUNIT_ASSERT(0x1100 == ur_router_get_next_hop(&network, 0x1100)); - YUNIT_ASSERT(0x1100 == ur_router_get_next_hop(&network, 0x1110)); - YUNIT_ASSERT(0x1100 == ur_router_get_next_hop(&network, 0x1120)); -} - - diff --git a/test/testcase/kernel/protocols/mesh_test/test_common_functions.c b/test/testcase/kernel/protocols/mesh_test/test_common_functions.c deleted file mode 100644 index 8b03a9ba21..0000000000 --- a/test/testcase/kernel/protocols/mesh_test/test_common_functions.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#include "yunit.h" - -#include "umesh.h" -#include "aos/aos.h" -#include "aos/kernel.h" -#include "core/mesh_mgmt.h" -#include "ip/lwip_adapter.h" -#include "lwip/ip.h" - -#include "dda_util.h" - -extern void ur_ut_send_cmd_to_ddm(const char *cmd); -void topo_test_function(uint16_t first_node, uint16_t num, uint32_t timeout) -{ - uint16_t index; - char number[5]; - - aos_msleep(2 * 1000); - set_full_rssi(first_node, first_node + num - 1); - - for (index = 1; index < num; index++) { - start_node_ext(index + first_node, MODE_RX_ON, -1, -1); - } - umesh_stop(); - umesh_set_mode(MODE_RX_ON); - umesh_start(); - check_cond_wait(num == umesh_mm_get_meshnetsize(), timeout); - - ur_ut_send_cmd_to_ddm("sendall sids"); - aos_msleep(10 * 1000); - - check_cond_wait(num == umesh_mm_get_meshnetsize(), 2000); - - for (index = 1; index < num; index++) { - stop_node(index + first_node); - } - umesh_stop(); -} diff --git a/test/testcase/kernel/protocols/mesh_test/topo_test.c b/test/testcase/kernel/protocols/mesh_test/topo_test.c deleted file mode 100644 index 2b09cfd375..0000000000 --- a/test/testcase/kernel/protocols/mesh_test/topo_test.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#include "yunit.h" - -#include "aos/aos.h" -#include "aos/kernel.h" - -#include "umesh.h" -#include "core/link_mgmt.h" -#include "core/sid_allocator.h" -#include "core/router_mgr.h" -#include "utilities/logging.h" -#include "tools/cli.h" - -#include "dda_util.h" - -static void one_super_router_case(void) -{ - char ping_cmd[64]; - - /* topology: - * leader router - * 151 <---wifi--> 152 - * ^ - * | router - * | <---wifi--> 153 - * | - * | router - * | <---ble---> 154 - * | - * | router - * | <---ble---> 155 - * - */ - - set_full_rssi(151, 155); - cmd_to_agent("stop"); - - start_node_ext(151, MODE_SUPER | MODE_RX_ON, -1, 3); - check_p2p_str_wait("leader", 151, "testcmd state", 10); - check_p2p_str_wait("VECTOR_ROUTER", 151, "testcmd router", 2); - - start_node_ext(152, MODE_RX_ON, -1, 1); - check_p2p_str_wait("router", 152, "testcmd state", 10); - check_p2p_str_wait("SID_ROUTER", 152, "testcmd router", 2); - - start_node_ext(153, MODE_RX_ON, -1, 1); - check_p2p_str_wait("router", 153, "testcmd state", 10); - check_p2p_str_wait("SID_ROUTER", 153, "testcmd router", 2); - - start_node_ext(154, MODE_RX_ON, -1, 2); - check_p2p_str_wait("router", 154, "testcmd state", 10); - check_p2p_str_wait("SID_ROUTER", 154, "testcmd router", 2); - - start_node_ext(155, MODE_RX_ON, -1, 2); - check_p2p_str_wait("router", 155, "testcmd state", 10); - check_p2p_str_wait("SID_ROUTER", 155, "testcmd router", 2); - - char *ipaddr = dda_p2p_req_and_wait(151, "testcmd ipaddr", 5); - YUNIT_ASSERT(ipaddr != NULL); - if (ipaddr) { - snprintf(ping_cmd, sizeof ping_cmd, "send 155 ping %s", ipaddr); - aos_free(ipaddr); - - cmd_to_master(ping_cmd); - check_p2p_str_wait("1", 155, "testcmd icmp_acked", 5); - } - - stop_node(151); - stop_node(152); - stop_node(153); - stop_node(154); - stop_node(155); -} - -static void two_super_router_case(void) -{ - char ping_cmd[64]; - - /* topology: - * leader router - * 151 <----------------> 152 - * | | - * | router | - * | <-----wifi----> 153 | - * | | - * | router | - * | <-----wifi----> 154 | - * | | - * | router | - * | <-----ble-----> 155 | - * | | - * | router | - * | <-----ble-----> 156 | - * - */ - - set_full_rssi(151, 156); - cmd_to_agent("stop"); - - start_node_ext(151, MODE_SUPER | MODE_RX_ON, -1, 3); - check_p2p_str_wait("leader", 151, "testcmd state", 10); - check_p2p_str_wait("VECTOR_ROUTER", 151, "testcmd router", 2); - - start_node_ext(152, MODE_SUPER | MODE_RX_ON, -1, 3); - check_p2p_str_wait("super_router", 152, "testcmd state", 10); - check_p2p_str_wait("VECTOR_ROUTER", 152, "testcmd router", 2); - - start_node_ext(153, MODE_RX_ON, -1, 1); - check_p2p_str_wait("router", 153, "testcmd state", 10); - check_p2p_str_wait("SID_ROUTER", 153, "testcmd router", 2); - - start_node_ext(154, MODE_RX_ON, -1, 1); - check_p2p_str_wait("router", 154, "testcmd state", 10); - check_p2p_str_wait("SID_ROUTER", 154, "testcmd router", 2); - - start_node_ext(155, MODE_RX_ON, -1, 2); - check_p2p_str_wait("router", 155, "testcmd state", 10); - check_p2p_str_wait("SID_ROUTER", 155, "testcmd router", 2); - - start_node_ext(156, MODE_RX_ON, -1, 2); - check_p2p_str_wait("router", 156, "testcmd state", 10); - check_p2p_str_wait("SID_ROUTER", 156, "testcmd router", 2); - - char *ipaddr = dda_p2p_req_and_wait(151, "testcmd ipaddr", 5); - YUNIT_ASSERT(ipaddr != NULL); - if (ipaddr) { - snprintf(ping_cmd, sizeof ping_cmd, "send 156 ping %s", ipaddr); - aos_free(ipaddr); - - cmd_to_master(ping_cmd); - check_p2p_str_wait("1", 156, "testcmd icmp_acked", 5); - } - - stop_node(151); - stop_node(152); - stop_node(153); - stop_node(154); - stop_node(155); - stop_node(156); -} - -void test_uradar_topo_case(void) -{ - run_times(one_super_router_case(), 1); - run_times(two_super_router_case(), 1); -} diff --git a/test/testcase/kernel/protocols/mesh_test/topology_line_test.c b/test/testcase/kernel/protocols/mesh_test/topology_line_test.c deleted file mode 100644 index 23e01beb48..0000000000 --- a/test/testcase/kernel/protocols/mesh_test/topology_line_test.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#include "yunit.h" - -#include "aos/aos.h" -#include "aos/kernel.h" - -#include "umesh.h" -#include "core/link_mgmt.h" -#include "core/sid_allocator.h" -#include "core/router_mgr.h" -#include "utilities/logging.h" -#include "hal/hals.h" -#include "hal/interface_context.h" -#include "hal/interfaces.h" -#include "tools/cli.h" -#include "ip/lwip_adapter.h" - -#include "dda_util.h" - -static void topology_line_case(bool vector_router) -{ - int i; - neighbor_t *attach_node; - uint16_t netid; - char ping_cmd[64]; - const ip6_addr_t *myaddr; - network_context_t *network; - - /* topology: - * 11 <------> 12 <----> 13 - */ - set_line_rssi(11, 13); - - cmd_to_agent("stop"); - /* make 7 leader */ - start_node_ext(13, MODE_RX_ON, vector_router ? VECTOR_ROUTER : SID_ROUTER, -1); - check_p2p_str_wait("leader", 13, "testcmd state", 10); - - start_node_ext(12, MODE_RX_ON, vector_router ? VECTOR_ROUTER : SID_ROUTER, -1); - check_p2p_str_wait("router", 12, "testcmd state", 10); - - cmd_to_agent("mode FIXED"); - if (vector_router) - cmd_to_agent("router VECTOR_ROUTER"); - else - cmd_to_agent("router SID_ROUTER"); - cmd_to_agent("start"); - check_cond_wait(!!(attach_node = umesh_mm_get_attach_node()), 15); - - YUNIT_ASSERT(attach_node != NULL); - if (!attach_node) { - goto out; - } - - netid = umesh_get_meshnetid(); - - cmd_to_master("sendall status"); - /* check if ping work */ - aos_msleep(2 * 1000); - myaddr = ur_adapter_get_default_ipaddr(); - snprintf(ping_cmd, sizeof ping_cmd, "send 13 ping " IP6_ADDR_FMT, IP6_ADDR_DATA(((ur_ip6_addr_t *)myaddr))); - cmd_to_master(ping_cmd); - check_p2p_str_wait("1", 13, "testcmd icmp_acked", 5); - - /* kill leader */ - stop_node(13); - - /* wait network id changed, as we expect migration */ - int tmo_ms = 2 * (WIFI_NEIGHBOR_ALIVE_TIMEOUT + WIFI_ADVERTISEMENT_TIMEOUT * MIGRATE_TIMEOUT); - check_cond_wait(netid != umesh_get_meshnetid() && umesh_get_device_state() == 6, - tmo_ms / 1000); - - /* check if ping work */ - aos_msleep(2 * 1000); - myaddr = ur_adapter_get_default_ipaddr(); - snprintf(ping_cmd, sizeof ping_cmd, "send 12 ping " IP6_ADDR_FMT, IP6_ADDR_DATA(((ur_ip6_addr_t *)myaddr))); - cmd_to_master(ping_cmd); - check_p2p_str_wait("1", 12, "testcmd icmp_acked", 5); - - attach_node = umesh_mm_get_attach_node(); - if (attach_node) { - uint64_t ueid = ueid64(attach_node->mac); - YUNIT_ASSERT(ueid == 12); - YUNIT_ASSERT(umesh_get_meshnetid() == attach_node->netid); - goto out; - } - - /* we become leader, check sids */ - network = get_default_network_context(); - uint16_t num = get_allocated_number(network->sid_base); - uint32_t sids_bitmap = get_allocated_bitmap(network->sid_base); - neighbor_t *node = NULL; - int found_12 = 0; - YUNIT_ASSERT(num == 1); - for (i=0;i<16 && num > 0;i++) { - if (!(sids_bitmap & (1 << i))) - continue; - - num --; - node = get_neighbor_by_sid(NULL, i, umesh_get_meshnetid()); - if (!node) - continue; - - uint64_t ueid = ueid64(node->mac); - printf("node sid=%04x ueid=%llx\n", node->sid, ueid); - if (ueid == 12) - found_12 = 1; - } - YUNIT_ASSERT(found_12); - -out: - stop_node(12); - stop_node(13); - cmd_to_agent("stop"); -} - -void test_uradar_topology_line_case(void) -{ - run_times(topology_line_case(true), 1); - run_times(topology_line_case(false), 1); -} diff --git a/test/testcase/kernel/protocols/mesh_test/uradar_test.c b/test/testcase/kernel/protocols/mesh_test/uradar_test.c deleted file mode 100644 index 1bc437059f..0000000000 --- a/test/testcase/kernel/protocols/mesh_test/uradar_test.c +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#include -#include -#include -#include -#include -#include - -#include - -#include "yunit.h" - -#include "aos/aos.h" -#include "yts.h" -#include "umesh.h" - -extern int dda_enable(int agent_id); -extern int dda_service_init(void); -extern int dda_service_start(void); -extern void dda_service_stop(void); -extern void dda_service_deinit(void); -static int ddm_pid, ddm_fd = -1; -static int start_ddm(void) -{ - int pipefd[2]; - int pid; - int ret; - - ret = pipe(pipefd); - if (ret < 0) { - return -1; - } - - pid = fork(); - if (pid == 0) { - const char **argv; - yts_get_args(&argv); - char * const args[] = { - (char *)argv[0], - "--mesh-master", - "-l", - "/tmp/ddm_log_ut.txt", - "tools/dda/configs/mesh_topology.txt", - NULL - }; - close(pipefd[1]); - dup2(pipefd[0], fileno(stdin)); - execve(args[0], args, NULL); - } - close(pipefd[0]); - ddm_fd = pipefd[1]; - - return pid; -} - -void ur_ut_send_cmd_to_ddm(const char *cmd) -{ - int ret; - ret = write(ddm_fd, cmd, strlen(cmd)); - if (ret < 0) - perror("write ddm:"); - ret = write(ddm_fd, "\n", 1); - if (ret < 0) - perror("write ddm:"); -} - -void start_dda(void) -{ - dda_enable(11); - dda_service_init(); - dda_service_start(); -} - -static void stop_dda(void *args) -{ - dda_service_stop(); - dda_service_deinit(); -} - -static bool dda_connected; -static void input_event_executor(input_event_t *eventinfo, void* cb_para) -{ - if (eventinfo->code != CODE_DDA_ON_CONNECTED) - return; - - dda_connected = true; -} - -static int init(void) -{ - aos_register_event_filter(EV_DDA, input_event_executor, NULL); - - ddm_pid = start_ddm(); - ur_ut_send_cmd_to_ddm("log off 0"); - - start_dda(); - - int cnt = 0; - while (!dda_connected && cnt++ < 100) { - aos_msleep(100); - } - - YUNIT_ASSERT(UR_ERROR_NONE == umesh_stop()); - - aos_msleep(1000); - - return cnt < 100 ? 0 : -1; -} - -static int cleanup(void) -{ - aos_schedule_call(stop_dda, NULL); - - ur_ut_send_cmd_to_ddm("goto master"); - ur_ut_send_cmd_to_ddm("ls"); - ur_ut_send_cmd_to_ddm("q"); - - waitpid(ddm_pid, NULL, 0); - - aos_register_event_filter(EV_DDA, input_event_executor, NULL); - - return 0; -} - -static void setup(void) -{ -} - -static void teardown(void) -{ -} - -extern void test_uradar_sid_router_case(void); -extern void test_uradar_vector_router_case(void); -extern void test_uradar_6lowpan_case(void); -extern void test_uradar_sid_allocator_case(void); -extern void test_uradar_rsid_allocator_case(void); -extern void test_uradar_urmesh_case(void); -extern void test_uradar_misc_case(void); -extern void test_uradar_lwip_adapter_case(void); -extern void test_uradar_mesh_mgmt_case(void); -extern void test_uradar_cli_case(void); -extern void test_uradar_mcast_case(void); -extern void test_uradar_1hop_case(void); -extern void test_uradar_1mobile_case(void); -extern void test_uradar_topology_line_case(void); -extern void test_uradar_scales_5nodes_case(void); -extern void test_uradar_scales_10nodes_case(void); -extern void test_uradar_scales_20nodes_case(void); -extern void test_uradar_scales_30nodes_case(void); -extern void test_uradar_layer_routing_line_topology_case(void); -extern void test_uradar_layer_routing_2mobile_case(void); -extern void test_uradar_dest_become_unreachable_case(void); -extern void test_uradar_asymmetric_link_case(void); -extern void test_uradar_topo_case(void); -extern void test_hal_mesh_case(void); -extern void test_diags_case(void); -extern void test_umesh_4super_7nodes_case(void); - -/* submodule ut */ -static yunit_test_case_t krhino_uradar_sub_testcases[] = { - { "hal_mesh", test_hal_mesh_case }, - { "diags", test_diags_case }, - { "sid_router", test_uradar_sid_router_case }, - { "vector_router", test_uradar_vector_router_case }, - { "6lowpan", test_uradar_6lowpan_case }, - { "sid_allocator", test_uradar_sid_allocator_case }, - { "rsid_allocator", test_uradar_rsid_allocator_case }, - { "urmesh", test_uradar_urmesh_case }, - { "misc", test_uradar_misc_case }, - { "lwip_adapter", test_uradar_lwip_adapter_case }, - { "mesh_mgmt", test_uradar_mesh_mgmt_case }, - { "cli", test_uradar_cli_case }, - YUNIT_TEST_CASE_NULL -}; - -/* compound case */ -static yunit_test_case_t krhino_uradar_com_testcases[] = { - { "mcast", test_uradar_mcast_case }, - { "1hop", test_uradar_1hop_case }, - { "1mobile", test_uradar_1mobile_case }, - { "top_line", test_uradar_topology_line_case }, - { "layer_routing_simple", test_uradar_layer_routing_line_topology_case }, - { "layer_routing_2mobile", test_uradar_layer_routing_2mobile_case }, - { "dest_unreachable", test_uradar_dest_become_unreachable_case }, - { "asymmetric_link", test_uradar_asymmetric_link_case }, - { "topology", test_uradar_topo_case }, - { "4super_7nodes", test_umesh_4super_7nodes_case }, - YUNIT_TEST_CASE_NULL -}; - -/* stress case */ -static yunit_test_case_t krhino_uradar_stress_testcases[] = { - { "scales_5", test_uradar_scales_5nodes_case }, - { "scales_10", test_uradar_scales_10nodes_case }, - { "scales_20", test_uradar_scales_20nodes_case }, - { "scales_30", test_uradar_scales_30nodes_case }, - YUNIT_TEST_CASE_NULL -}; - -static yunit_test_case_t krhino_uradar_mini_testcases[] = { - /* submodule ut */ - { "sid_router", test_uradar_sid_router_case }, - { "6lowpan", test_uradar_6lowpan_case }, - { "sid_allocator", test_uradar_sid_allocator_case }, - { "rsid_allocator", test_uradar_rsid_allocator_case }, - { "lwip_adapter", test_uradar_lwip_adapter_case }, - { "mesh_mgmt", test_uradar_mesh_mgmt_case }, - /* compound case */ - { "mcast", test_uradar_mcast_case }, - { "1hop", test_uradar_1hop_case }, - { "top_line", test_uradar_topology_line_case }, - { "layer_routing_simple", test_uradar_layer_routing_line_topology_case }, - { "layer_routing_2mobile", test_uradar_layer_routing_2mobile_case }, - { "topology", test_uradar_topo_case }, - /* stress case */ - { "scales_5", test_uradar_scales_5nodes_case }, - YUNIT_TEST_CASE_NULL -}; - -static yunit_test_case_t krhino_uradar_testcases[] = { - /* submodule ut */ - { "hal_mesh", test_hal_mesh_case }, - { "diags", test_diags_case }, - { "sid_router", test_uradar_sid_router_case }, - { "vector_router", test_uradar_vector_router_case }, - { "6lowpan", test_uradar_6lowpan_case }, - { "sid_allocator", test_uradar_sid_allocator_case }, - { "rsid_allocator", test_uradar_rsid_allocator_case }, - { "urmesh", test_uradar_urmesh_case }, - { "misc", test_uradar_misc_case }, - { "lwip_adapter", test_uradar_lwip_adapter_case }, - { "mesh_mgmt", test_uradar_mesh_mgmt_case }, - { "cli", test_uradar_cli_case }, - /* compound case */ - { "mcast", test_uradar_mcast_case }, - { "1hop", test_uradar_1hop_case }, - { "1mobile", test_uradar_1mobile_case }, - { "top_line", test_uradar_topology_line_case }, - { "layer_routing_simple", test_uradar_layer_routing_line_topology_case }, - { "layer_routing_2mobile", test_uradar_layer_routing_2mobile_case }, - { "dest_unreachable", test_uradar_dest_become_unreachable_case }, - { "asymmetric_link", test_uradar_asymmetric_link_case }, - { "topology", test_uradar_topo_case }, - { "4super_7nodes", test_umesh_4super_7nodes_case }, - /* stress case */ - { "scales_5", test_uradar_scales_5nodes_case }, - { "scales_10", test_uradar_scales_10nodes_case }, - { "scales_20", test_uradar_scales_20nodes_case }, - { "scales_30", test_uradar_scales_30nodes_case }, - YUNIT_TEST_CASE_NULL -}; - -static yunit_test_suite_t suites[] = { - { "mesh", init, cleanup, setup, teardown, krhino_uradar_testcases }, - YUNIT_TEST_SUITE_NULL -}; - -static yunit_test_suite_t sub_suites[] = { - { "mesh_sub", init, cleanup, setup, teardown, krhino_uradar_sub_testcases }, - YUNIT_TEST_SUITE_NULL -}; - -static yunit_test_suite_t com_suites[] = { - { "mesh_com", init, cleanup, setup, teardown, krhino_uradar_com_testcases }, - YUNIT_TEST_SUITE_NULL -}; - -static yunit_test_suite_t stress_suites[] = { - { "mesh_stress", init, cleanup, setup, teardown, krhino_uradar_stress_testcases }, - YUNIT_TEST_SUITE_NULL -}; - -static yunit_test_suite_t mini_suites[] = { - { "mesh_mini", init, cleanup, setup, teardown, krhino_uradar_mini_testcases }, - YUNIT_TEST_SUITE_NULL -}; - -void test_uradar(void) -{ - int argc; - const char **argv; - - argc = yts_get_args(&argv); - if (argc > 1) { - yunit_add_test_suites(sub_suites); - yunit_add_test_suites(com_suites); - yunit_add_test_suites(stress_suites); - yunit_add_test_suites(mini_suites); - } - - yunit_add_test_suites(suites); -} -AOS_TESTCASE(test_uradar); diff --git a/test/testcase/kernel/protocols/mesh_test/urmesh_test.c b/test/testcase/kernel/protocols/mesh_test/urmesh_test.c deleted file mode 100644 index 1dbc29c36d..0000000000 --- a/test/testcase/kernel/protocols/mesh_test/urmesh_test.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#include "yunit.h" - -#include "aos/kernel.h" -#include "umesh.h" -#include "core/topology.h" -#include "core/mesh_mgmt.h" -#include "hal/interfaces.h" -#include "hal/interface_context.h" -#include "ip/lwip_adapter.h" - -#include "dda_util.h" - -void test_uradar_urmesh_case(void) -{ - ur_ip6_addr_t ip6addr; - - YUNIT_ASSERT(INVALID_SID == umesh_get_sid()); - YUNIT_ASSERT(UR_ERROR_NONE == umesh_start()); - check_cond_wait(umesh_get_device_state() == DEVICE_STATE_LEADER, 5); - - YUNIT_ASSERT(UR_ERROR_NONE == umesh_stop()); - YUNIT_ASSERT(UR_ERROR_NONE == umesh_set_mode(MODE_MOBILE)); - YUNIT_ASSERT(MODE_MOBILE == umesh_get_mode()); - YUNIT_ASSERT(NULL != umesh_get_mac_address(MEDIA_TYPE_DFL)); - umesh_set_mode(MODE_RX_ON); - YUNIT_ASSERT(MODE_RX_ON == umesh_get_mode()); - YUNIT_ASSERT(UR_ERROR_NONE == umesh_start()); - check_cond_wait(umesh_get_device_state() >= DEVICE_STATE_LEAF, 10); - - memset(ip6addr.m8, 0x00, sizeof(ip6addr.m8)); - ip6addr.m8[0] = 0xff; - ip6addr.m8[1] = 0x08; - ip6addr.m8[6] = (umesh_get_meshnetid() >> 8); - ip6addr.m8[7] = umesh_get_meshnetid(); - ip6addr.m8[15] = 0xfc; - YUNIT_ASSERT(true == umesh_is_mcast_subscribed(&ip6addr)); - - YUNIT_ASSERT(NULL != ur_adapter_get_default_ipaddr()); - YUNIT_ASSERT(NULL != ur_adapter_get_mcast_ipaddr()); - YUNIT_ASSERT(UR_ERROR_NONE == umesh_stop()); -} diff --git a/test/testcase/kernel/protocols/mesh_test/vector_router_test.c b/test/testcase/kernel/protocols/mesh_test/vector_router_test.c deleted file mode 100644 index bfa6025705..0000000000 --- a/test/testcase/kernel/protocols/mesh_test/vector_router_test.c +++ /dev/null @@ -1,274 +0,0 @@ -/* - * Copyright (C) 2015-2017 Alibaba Group Holding Limited - */ - -#include - -#include "yunit.h" - -#include "aos/kernel.h" - -#include "umesh_types.h" -#include "core/mesh_mgmt.h" -#include "core/link_mgmt.h" -#include "core/router_mgr.h" -#include "core/vector_router.h" - -extern ur_error_t vector_router_init(void); -extern ur_error_t vector_router_deinit(void); -extern ur_error_t vector_router_neighbor_updated(neighbor_t *neighbor); -extern ur_error_t vector_router_message_received(const uint8_t *data, uint16_t length); -extern ur_error_t vector_router_event_triggered(uint8_t event, uint8_t *data, uint8_t len); -extern ur_error_t vector_router_add_vertex(uint16_t sid); -extern ur_error_t vector_router_update_edge(uint16_t src_sid, uint16_t dst_sid, uint8_t cost); -extern void vector_router_print_routing_table(void); -extern void vector_router_calculate_routing_info(void); -extern uint16_t vector_router_get_next_hop_shortid(uint16_t dest); - -void test_uradar_vector_router_case(void) -{ - /* routing algorithm related test */ - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_init()); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_add_vertex(2)); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_add_vertex(3)); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_add_vertex(4)); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_add_vertex(5)); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_add_vertex(6)); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_add_vertex(7)); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_add_vertex(8)); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_add_vertex(9)); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_add_vertex(10)); - YUNIT_ASSERT(UR_ERROR_FAIL == vector_router_add_vertex(10)); - - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_update_edge(1, 2, 1)); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_update_edge(1, 3, 1)); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_update_edge(1, 4, 1)); - YUNIT_ASSERT(UR_ERROR_FAIL == vector_router_update_edge(1, 4, 1)); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_update_edge(2, 3, 1)); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_update_edge(2, 6, 1)); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_update_edge(3, 4, 1)); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_update_edge(3, 5, 1)); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_update_edge(3, 6, 1)); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_update_edge(4, 5, 1)); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_update_edge(4, 9, 1)); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_update_edge(5, 6, 1)); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_update_edge(5, 7, 1)); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_update_edge(5, 8, 1)); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_update_edge(5, 9, 1)); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_update_edge(6, 7, 1)); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_update_edge(7, 8, 1)); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_update_edge(8, 9, 1)); - - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_update_edge(2, 1, 1)); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_update_edge(3, 1, 1)); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_update_edge(4, 1, 1)); - YUNIT_ASSERT(UR_ERROR_FAIL == vector_router_update_edge(4, 1, 1)); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_update_edge(3, 2, 1)); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_update_edge(6, 2, 1)); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_update_edge(4, 3, 1)); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_update_edge(5, 3, 1)); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_update_edge(6, 3, 1)); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_update_edge(5, 4, 1)); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_update_edge(9, 4, 1)); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_update_edge(6, 5, 1)); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_update_edge(7, 5, 1)); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_update_edge(8, 5, 1)); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_update_edge(9, 5, 1)); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_update_edge(7, 6, 1)); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_update_edge(8, 7, 1)); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_update_edge(9, 8, 1)); - - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_update_edge(5, 7, 2)); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_update_edge(5, 8, 255)); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_update_edge(7, 8, 2)); - vector_router_print_routing_table(); - vector_router_calculate_routing_info(); - vector_router_print_routing_table(); - YUNIT_ASSERT(2 == vector_router_get_next_hop_shortid(2)); - YUNIT_ASSERT(3 == vector_router_get_next_hop_shortid(3)); - YUNIT_ASSERT(4 == vector_router_get_next_hop_shortid(4)); - YUNIT_ASSERT(3 == vector_router_get_next_hop_shortid(5)); - YUNIT_ASSERT(2 == vector_router_get_next_hop_shortid(6)); - YUNIT_ASSERT(2 == vector_router_get_next_hop_shortid(7)); - YUNIT_ASSERT(4 == vector_router_get_next_hop_shortid(8)); - YUNIT_ASSERT(4 == vector_router_get_next_hop_shortid(9)); - YUNIT_ASSERT(INVALID_SID == vector_router_get_next_hop_shortid(10)); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_deinit()); - - /* function level uinit test */ - netids_t netids; - uint8_t data[512]; - uint16_t sid, len; - router_command_t *cmd; - vertex_tv_t *vertex_tv; - edge_tv_t *edge_tv; - none_tv_t *none_tv; - edge_tuple_t *edge_tuple; - neighbor_t neighbor; - - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_init()); - netids.meshnetid = 0x0100; - netids.sid = LEADER_SID; - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_event_triggered(EVENT_SID_UPDATED, (uint8_t *)&netids, sizeof(netids_t))); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_event_triggered(EVENT_SID_UPDATED, (uint8_t *)&netids, sizeof(netids_t))); - sid = 0x2000; - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_event_triggered(EVENT_SID_UPDATED, (uint8_t *)&netids, sizeof(netids_t))); - sid = LEADER_SID; - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_event_triggered(EVENT_SID_UPDATED, (uint8_t *)&netids, sizeof(netids_t))); - - /* heartbeat messages */ - cmd = (router_command_t *)data; - len = sizeof(router_command_t); - vertex_tv = (vertex_tv_t *)(data + len); - len += sizeof(vertex_tv_t); - cmd->cmd = COMMAND_HEARTBEAT; - cmd->seq = 1; - cmd->sid = 0x1000; - vertex_tv->type = TYPE_VERTEX; - memset(vertex_tv->ueid, 0x00, sizeof(vertex_tv->ueid)); - vertex_tv->ueid[0] = 0x02; - vertex_tv->sid = 0x1000; - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_message_received(data, len)); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_message_received(data, len)); - edge_tuple = (edge_tuple_t *)(data + len); - len += sizeof(edge_tuple_t); - edge_tuple->dst = 0x0000; - edge_tuple->cost = 16; - cmd->seq = 2; - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_message_received(data, len)); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_message_received(data, len)); - cmd->seq = 1; - vertex_tv->ueid[0] = 0x04; - vertex_tv->sid = 0x4000; - edge_tuple->dst = 0x1000; - edge_tuple->cost = 16; - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_message_received(data, len)); - /* vertex update message */ - cmd->cmd = COMMAND_VERTEX_UPDATE; - cmd->seq = 3; - cmd->sid = 0x1000; - vertex_tv->sid = 0x1000; - vertex_tv->ueid[0] = 0x02; - len = sizeof(router_command_t) + sizeof(vertex_tv_t); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_message_received(data, len)); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_message_received(data, len)); - - cmd->cmd = COMMAND_VERTEX_DELETE; - cmd->seq = 2; - vertex_tv->ueid[0] = 0x04; - vertex_tv->sid = 0x4000; - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_message_received(data, len)); - /* edge update message */ - cmd->cmd = COMMAND_EDGE_UPDATE; - cmd->seq = 4; - edge_tv = (edge_tv_t *)(data + sizeof(router_command_t)); - edge_tv->src = 0x1000; - edge_tv->dst = 0x0000; - edge_tv->cost = 32; - len = sizeof(router_command_t) + sizeof(edge_tv_t); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_message_received(data, len)); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_message_received(data, len)); - /* unkonw message */ - cmd->cmd = 0; - YUNIT_ASSERT(UR_ERROR_FAIL == vector_router_message_received(data, len)); - /* neighbor updated */ - neighbor.sid = 0x1000; - memset(neighbor.mac, 0x00, sizeof(neighbor.mac)); - neighbor.mac[0] = 0x02; - neighbor.stats.link_cost = 256; - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_neighbor_updated(&neighbor)); - neighbor.stats.link_cost = LINK_COST_MAX; - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_neighbor_updated(&neighbor)); - neighbor.stats.link_cost = 512; - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_neighbor_updated(&neighbor)); - YUNIT_ASSERT(UR_ERROR_FAIL == vector_router_neighbor_updated(&neighbor)); - neighbor.mac[0] = 0x03; - YUNIT_ASSERT(UR_ERROR_FAIL == vector_router_neighbor_updated(&neighbor)); - - /* topology sync as server */ - cmd->cmd = COMMAND_TOPOLOGY_SYNC_SELECT; - cmd->seq = 1; - cmd->sid = 0x2000; - len = sizeof(router_command_t); - cmd->seq = 2; - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_message_received(data, len)); - aos_msleep(TOPOLOGY_SYNC_TIMEOUT + TOPOLOGY_SYNC_TIMEOUT / 2); - cmd->cmd = COMMAND_TOPOLOGY_SYNC_ACK; - cmd->seq = 1; - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_message_received(data, len)); - - aos_msleep(HEARTBEAT_TIMEOUT); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_deinit()); - - /* topology sync as client */ - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_init()); - sid = 0x1000; - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_event_triggered(EVENT_SID_UPDATED, (uint8_t *)&sid, 2)); - aos_msleep(STARTUP_TIMEOUT + TOPOLOGY_SYNC_TIMEOUT / 2); - - cmd->cmd = COMMAND_TOPOLOGY_SYNC_DATA; - cmd->seq = 1; - cmd->sid = LEADER_SID; - len = sizeof(router_command_t); - vertex_tv = (vertex_tv_t *)(data + len); - vertex_tv->type = TYPE_VERTEX; - memset(vertex_tv->ueid, 0x00, sizeof(vertex_tv->ueid)); - vertex_tv->ueid[0] = 0x11; - vertex_tv->sid = 0x0000; - len += sizeof(vertex_tv_t); - vertex_tv = (vertex_tv_t *)(data + len); - vertex_tv->type = TYPE_VERTEX; - memset(vertex_tv->ueid, 0x00, sizeof(vertex_tv->ueid)); - vertex_tv->ueid[0] = 0x12; - vertex_tv->sid = 0x2000; - len += sizeof(vertex_tv_t); - vertex_tv = (vertex_tv_t *)(data + len); - vertex_tv->type = TYPE_VERTEX; - memset(vertex_tv->ueid, 0x00, sizeof(vertex_tv->ueid)); - vertex_tv->ueid[0] = 0x13; - vertex_tv->sid = 0x3000; - len += sizeof(vertex_tv_t); - edge_tv = (edge_tv_t *)(data + len); - edge_tv->type = TYPE_EDGE; - edge_tv->src = 0x0000; - edge_tv->dst = 0x2000; - edge_tv->cost = 16; - len += sizeof(edge_tv_t); - edge_tv = (edge_tv_t *)(data + len); - edge_tv->type = TYPE_EDGE; - edge_tv->src = 0x2000; - edge_tv->dst = 0x0000; - edge_tv->cost = 16; - len += sizeof(edge_tv_t); - edge_tv = (edge_tv_t *)(data + len); - edge_tv->type = TYPE_EDGE; - edge_tv->src = 0x2000; - edge_tv->dst = 0x3000; - edge_tv->cost = 16; - len += sizeof(edge_tv_t); - edge_tv = (edge_tv_t *)(data + len); - edge_tv->type = TYPE_EDGE; - edge_tv->src = 0x3000; - edge_tv->dst = 0x2000; - edge_tv->cost = 16; - len += sizeof(edge_tv_t); - edge_tv = (edge_tv_t *)(data + len); - edge_tv->type = TYPE_EDGE; - edge_tv->src = 0x0000; - edge_tv->dst = 0x3000; - edge_tv->cost = 16; - len += sizeof(edge_tv_t); - edge_tv = (edge_tv_t *)(data + len); - edge_tv->type = TYPE_EDGE; - edge_tv->src = 0x3000; - edge_tv->dst = 0x0000; - edge_tv->cost = 16; - len += sizeof(edge_tv_t); - none_tv = (none_tv_t *)(data + len); - none_tv->type = TYPE_NONE; - len += sizeof(none_tv_t); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_message_received(data, len)); - YUNIT_ASSERT(UR_ERROR_NONE == vector_router_deinit()); -} - - diff --git a/tools/cli/cli.c b/tools/cli/cli.c index 7d3b73af42..e94a4e4fc6 100755 --- a/tools/cli/cli.c +++ b/tools/cli/cli.c @@ -78,6 +78,47 @@ static const struct cli_command *lookup_command(char *name, int len) return NULL; } + +/*proc one cli cmd and to run the according funtion +* Returns: 0 on success: + 1 fail +*/ +static int proc_onecmd(int argc,char * argv[]) +{ + int i = 0; + const char *p; + const struct cli_command *command = NULL; + + if (argc < 1) { + return 0; + } + + if (!cli->echo_disabled) { + csp_printf("\r\n"); + fflush(stdout); + } + + /* + * Some comamands can allow extensions like foo.a, foo.b and hence + * compare commands before first dot. + */ + i = ((p = strchr(argv[0], '.')) == NULL) ? 0 : (p - argv[0]); + + command = lookup_command(argv[0], i); + if (command == NULL) { + return 1; + } + + memset(cli->outbuf, 0, OUTBUF_SIZE); + + command->function(cli->outbuf, OUTBUF_SIZE, argc, argv); + cli_putstr(cli->outbuf); + return 0; +} + + + + /* Parse input line and locate arguments (if any), keeping count of the number * of arguments and their locations. Look up and call the corresponding cli * function if one is found and pass it the argv array. @@ -95,13 +136,18 @@ static int handle_input(char *inbuf) unsigned inQuote: 1; unsigned done: 1; } stat; - static char *argv[16]; - int argc = 0; + static char *argvall[CLI_MAX_ONCECMD_NUM][CLI_MAX_ARG_NUM]; + int argcall[CLI_MAX_ONCECMD_NUM] = {0}; + /* + static char *argv[CLI_MAX_ONCECMD_NUM][CLI_MAX_ARG_NUM]; + int argc = 0;*/ + int cmdnum = 0; + int * pargc = &argcall[0]; int i = 0; - const struct cli_command *command = NULL; - const char *p; + int ret = 0; - memset((void *)&argv, 0, sizeof(argv)); + memset((void *)&argvall, 0, sizeof(argvall)); + memset((void *)&argcall, 0, sizeof(argcall)); memset(&stat, 0, sizeof(stat)); do { @@ -129,8 +175,8 @@ static int handle_input(char *inbuf) if (!stat.inQuote && !stat.inArg) { stat.inArg = 1; stat.inQuote = 1; - argc++; - argv[argc - 1] = &inbuf[i + 1]; + (*pargc)++; + argvall[cmdnum][(*pargc) - 1] = &inbuf[i + 1]; } else if (stat.inQuote && stat.inArg) { stat.inArg = 0; stat.inQuote = 0; @@ -151,46 +197,49 @@ static int handle_input(char *inbuf) } break; + case ';': + if (i > 0 && inbuf[i - 1] == '\\' && stat.inArg) { + memcpy(&inbuf[i - 1], &inbuf[i], + strlen(&inbuf[i]) + 1); + --i; + break; + } + if (stat.inQuote) { + return 2; + } + if (!stat.inQuote && stat.inArg) { + stat.inArg = 0; + inbuf[i] = '\0'; + + if(*pargc) { + if(++cmdnum < CLI_MAX_ONCECMD_NUM) { + pargc = &argcall[cmdnum]; + } + } + } + + break; + default: if (!stat.inArg) { stat.inArg = 1; - argc++; - argv[argc - 1] = &inbuf[i]; + (*pargc)++; + argvall[cmdnum][(*pargc) - 1] = &inbuf[i]; } break; } - } while (!stat.done && ++i < INBUF_SIZE); + } while (!stat.done && ++i < INBUF_SIZE && cmdnum < CLI_MAX_ONCECMD_NUM && (*pargc) < CLI_MAX_ARG_NUM); if (stat.inQuote) { return 2; } - if (argc < 1) { - return 0; - } - - if (!cli->echo_disabled) { - csp_printf("\r\n"); - fflush(stdout); - } - - /* - * Some comamands can allow extensions like foo.a, foo.b and hence - * compare commands before first dot. - */ - i = ((p = strchr(argv[0], '.')) == NULL) ? 0 : (p - argv[0]); - - command = lookup_command(argv[0], i); - if (command == NULL) { - return 1; + for( i = 0; i <= cmdnum && i < CLI_MAX_ONCECMD_NUM ; i++ ) + { + ret |= proc_onecmd(argcall[i],argvall[i]); } - memset(cli->outbuf, 0, OUTBUF_SIZE); - - command->function(cli->outbuf, OUTBUF_SIZE, argc, argv); - cli_putstr(cli->outbuf); - - return 0; + return ret; } /* Perform basic tab-completion on the input buffer by string-matching the @@ -512,6 +561,8 @@ static void help_cmd(char *buf, int len, int argc, char **argv) #endif aos_cli_printf( "====Build-in Commands====\r\n" ); + aos_cli_printf( "====Support six cmds once, seperate by ; ====\r\n" ); + for (i = 0, n = 0; i < MAX_COMMANDS && n < cli->num_commands; i++) { if (cli->commands[i]->name) { aos_cli_printf("%s: %s\r\n", cli->commands[i]->name, diff --git a/tools/cli/cli.mk b/tools/cli/cli.mk index f641966a6e..eee698ca5a 100644 --- a/tools/cli/cli.mk +++ b/tools/cli/cli.mk @@ -5,7 +5,7 @@ $(NAME)_TYPE := kernel $(NAME)_SOURCES := cli.c dumpsys.c ifeq ($(COMPILER),armcc) -else ifeq ($(COMPILER),armcc) +else ifeq ($(COMPILER),iar) else $(NAME)_CFLAGS += -Wall -Werror endif diff --git a/tools/testbed/TBframe.py b/tools/testbed/TBframe.py index f60f000039..e90d96eea7 100644 --- a/tools/testbed/TBframe.py +++ b/tools/testbed/TBframe.py @@ -27,6 +27,10 @@ TYPE_NONE = 'NONE' CLIENT_UUID = 'CUID' CLIENT_TAG = 'CTAG' +REQUEST_LOGIN = 'RLGI' +CLIENT_LOGIN = 'CLGI' +SERVER_LOGIN = 'SLGI' +TERMINAL_LOGIN = 'TLGI' def is_valid_type(type): #frequently used commands @@ -79,6 +83,14 @@ def is_valid_type(type): return True if type == CLIENT_TAG: return True + if type == REQUEST_LOGIN: + return True + if type == CLIENT_LOGIN: + return True + if type == SERVER_LOGIN: + return True + if type == TERMINAL_LOGIN: + return True return False def construct(type, value): @@ -98,7 +110,7 @@ def parse(msg): length = 0 value = '' break; - # print msg + # print(msg) for i in range(len(msg)): if msg[i] != '{': continue @@ -114,8 +126,8 @@ def parse(msg): continue sync = True if DEBUG and i > 0: - print "msg:{0}".format(msg) - print "discard:{0}".format(msg[0:i]) + print("msg:{0}".format(msg)) + print("discard:{0}".format(msg[0:i])) msg = msg[i:] break if sync == False: @@ -130,8 +142,7 @@ def parse(msg): break if msg[length + 11] != '}': sync = False - if DEBUG: - print msg[0:11],"Lose sync because of FOOTER error" + if DEBUG: print(msg[0:11] + " Lose sync because of FOOTER error") msg = msg[1:] continue value = msg[11:length+11] diff --git a/tools/testbed/aos_firmware_update.py b/tools/testbed/aos_firmware_update.py deleted file mode 120000 index bab9873c2f..0000000000 --- a/tools/testbed/aos_firmware_update.py +++ /dev/null @@ -1 +0,0 @@ -../../build/aos_firmware_update.py \ No newline at end of file diff --git a/tools/testbed/autotest.py b/tools/testbed/autotest.py index 864b456f3f..4245b175eb 100644 --- a/tools/testbed/autotest.py +++ b/tools/testbed/autotest.py @@ -1,11 +1,12 @@ #!/usr/bin/python -import os, sys, time, socket, re, pdb, traceback -import subprocess, thread, threading, random +import os, sys, time, socket, ssl, traceback +import subprocess, thread, threading, random, re from operator import itemgetter import TBframe -MAX_MSG_LENTH = 2000 +MAX_MSG_LENTH = 8192 +ENCRYPT = False DEBUG = True class ConnectionLost(Exception): @@ -164,16 +165,13 @@ def server_interaction(self): self.cmd_excute_event.set() except ConnectionLost: self.connected = False - print 'connection to server lost, try reconnecting...' self.service_socket.close() - self.service_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + print 'connection to server lost, try reconnecting...' while True: - try: - self.service_socket.connect((self.server_ip, self.server_port)) - self.connected = True + result = self.connect_to_server(self.server_ip, self.server_port) + if result == 'success': break - except: - time.sleep(1) + time.sleep(1) print 'connection to server resumed' random.seed() time.sleep(1.2 + random.random()) @@ -435,14 +433,23 @@ def device_run_cmd(self, devname, args, expect_lines = 0, timeout=0.8, filters=[ def get_device_list(self): return list(self.device_list) + def connect_to_server(self, server_ip, server_port): + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + if ENCRYPT: + sock = ssl.wrap_socket(sock, cert_reqs=ssl.CERT_REQUIRED, ca_certs='server_cert.pem') + try: + sock.connect((server_ip, server_port)) + self.service_socket = sock + self.connected = True + return "success" + except: + return "fail" + def start(self, server_ip, server_port, logname=None): - #connect to server self.server_ip = server_ip self.server_port = server_port - self.service_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - try: - self.service_socket.connect((server_ip, server_port)) - except: + result = self.connect_to_server(server_ip, server_port) + if result != 'success': print "connect to server {0}:{1} failed".format(server_ip, server_port) return False diff --git a/tools/testbed/board/README b/tools/testbed/board/README new file mode 100644 index 0000000000..485dc1e9ed --- /dev/null +++ b/tools/testbed/board/README @@ -0,0 +1,12 @@ +This folder contains all board support files. + +To interface a new borad to testbed, you need to: + 1. get the board name--DEVNAME--by running AliOS Things 'devname' command in board shell, e.g.: MK3060 + 2. make a folder with its name to be devname (=lowercase(DEVNAME)), e.g.: mk3060 + 3. write a python script named devname.py (e.g.: mk3060.py), put it in ./devname folder, implement the following three functions: + def erase(port) + def program(port, address, file) + def control(port, operation) + also put the related tools in ./devname folder + +Should you have any questions, please contact lc122798@alibaba-inc.com. diff --git a/tools/testbed/board/esp32/esp32.py b/tools/testbed/board/esp32/esp32.py new file mode 100644 index 0000000000..36c8e90a8a --- /dev/null +++ b/tools/testbed/board/esp32/esp32.py @@ -0,0 +1,98 @@ +import os, sys, time, serial, subprocess, traceback, glob + +def list_devices(os): + return glob.glob('/dev/espif-*') + +def new_device(port): + try: + ser = serial.Serial(port, 115200, timeout = 0.02) + ser.setRTS(True) + ser.setDTR(False) + time.sleep(0.1) + ser.setDTR(True) + except: + ser = None + print 'esp32: open {0} error'.format(port) + return ser + +def erase(port): + retry = 3 + baudrate = 230400 + error = 'fail' + flash_tool_path = os.path.dirname(os.path.realpath(__file__)) + '/esptool.py' + while retry > 0: + script = ['python', flash_tool_path] + script += ['--chip'] + script += ['esp32'] + script += ['--port'] + script += [port] + script += ['--baud'] + script += [str(baudrate)] + script += ['erase_flash'] + ret = subprocess.call(script) + if ret == 0: + error = 'success' + break + retry -= 1 + baudrate = baudrate / 2 + return error + +def program(port, address, file): + retry = 3 + baudrate = 230400 + error = 'fail' + flash_tool_path = os.path.dirname(os.path.realpath(__file__)) + '/esptool.py' + while retry > 0: + script = ['python', flash_tool_path] + script += ['--chip'] + script += ['esp32'] + script += ['--port'] + script += [port] + script += ['--baud'] + script += [str(baudrate)] + script += ['--before'] + script += ['default_reset'] + script += ['--after'] + script += ['hard_reset'] + script += ['write_flash'] + script += ['-z'] + script += ['--flash_mode'] + script += ['dio'] + script += ['--flash_freq'] + script += ['40m'] + script += ['--flash_size'] + script += ['4MB'] + script += [address] + script += [file] + ret = subprocess.call(script) + if ret == 0: + error = 'success' + break + retry -= 1 + baudrate = baudrate / 2 + return error + +def control(port, operation): + try: + ser = serial.Serial(port, 115200) + except: + traceback.print_exc() + print 'esp32 control error: unable to open {0}'.format(port) + return 'fail' + ret = 'fail' + try: + if operation == 'reset': + ser.setDTR(False) + time.sleep(0.1) + ser.setDTR(True) + ret = 'success' + elif operation == 'stop': + ser.setDTR(False) + ret = 'success' + elif operation == 'start': + ser.setDTR(True) + ret = 'success' + except: + pass + ser.close() + return ret diff --git a/tools/testbed/board/esp32/esptool.py b/tools/testbed/board/esp32/esptool.py new file mode 120000 index 0000000000..d796feb4e4 --- /dev/null +++ b/tools/testbed/board/esp32/esptool.py @@ -0,0 +1 @@ +../../../../platform/mcu/esp32/esptool_py/esptool/esptool.py \ No newline at end of file diff --git a/tools/testbed/board/linuxhost/linuxhost.py b/tools/testbed/board/linuxhost/linuxhost.py new file mode 100644 index 0000000000..e7bf1c3694 --- /dev/null +++ b/tools/testbed/board/linuxhost/linuxhost.py @@ -0,0 +1,20 @@ +import os, sys, time, serial, subprocess, traceback, pty + +def list_devices(os): + return [] + return ['/dev/tty20', '/dev/tty21'] + +def new_device(port): + return open(port, 'rb+') + +def erase(port): + error = 'fail' + return error + +def program(port, address, file): + error = 'fail' + return error + +def control(port, operation): + ret = 'fail' + return ret diff --git a/tools/testbed/board/mk3060/mk3060.py b/tools/testbed/board/mk3060/mk3060.py new file mode 100644 index 0000000000..58c3819e3e --- /dev/null +++ b/tools/testbed/board/mk3060/mk3060.py @@ -0,0 +1,60 @@ +import os, sys, time, serial, subprocess, traceback, glob + +def list_devices(os): + return glob.glob('/dev/mxchip-*') + +def new_device(port): + try: + ser = serial.Serial(port, 921600, timeout = 0.02) + ser.setRTS(False) + except: + ser = None + print 'mk3060: open {0} error'.format(port) + return ser + +def erase(port): + error = 'fail' + return error + +def program(port, address, file): + retry = 3 + error = 'fail' + flash_tool_path = os.path.dirname(os.path.realpath(__file__)) + '/mk3060_firmware_update.py' + while retry > 0: + script = ['python', flash_tool_path] + script += [port] + script += [address] + script += [file] + script += ['--hardreset'] + ret = subprocess.call(script) + if ret == 0: + error = 'success' + break + retry -= 1 + time.sleep(4) + return error + +def control(port, operation): + try: + ser = serial.Serial(port, 921600) + except: + traceback.print_exc() + print 'mk3060 control error: unable to open {0}'.format(port) + return 'fail' + ret = 'fail' + try: + if operation == 'reset': + ser.setRTS(True) + time.sleep(0.1) + ser.setRTS(False) + ret = 'success' + elif operation == 'stop': + ser.setRTS(True) + ret = 'success' + elif operation == 'start': + ser.setRTS(False) + ret = 'success' + except: + pass + ser.close() + return ret diff --git a/tools/testbed/board/mk3060/mk3060_firmware_update.py b/tools/testbed/board/mk3060/mk3060_firmware_update.py new file mode 120000 index 0000000000..7a1ac6ae8b --- /dev/null +++ b/tools/testbed/board/mk3060/mk3060_firmware_update.py @@ -0,0 +1 @@ +../../../../build/aos_firmware_update.py \ No newline at end of file diff --git a/tools/testbed/client.py b/tools/testbed/client.py index f08cdec316..88f40b57c7 100644 --- a/tools/testbed/client.py +++ b/tools/testbed/client.py @@ -1,7 +1,9 @@ -import os, sys, time, platform, json, traceback, random -import socket, thread, threading, subprocess, signal, Queue +import os, sys, time, platform, json, traceback, random, re, glob, uuid +import socket, ssl, thread, threading, subprocess, signal, Queue, importlib import TBframe +MAX_MSG_LENTH = 8192 +ENCRYPT = False DEBUG = True LOCALLOG = False @@ -13,17 +15,16 @@ print ' sudo pip install pyserial' sys.exit(1) -if platform.system() == 'Windows': - import serial.tools.list_ports -else: - import glob - -MAX_MSG_LENTH = 2000 - def signal_handler(sig, frame): print "received SIGINT" raise KeyboardInterrupt +def queue_safeput(queue, item): + try: + queue.put(item, False) + except: + pass + class ConnectionLost(Exception): pass @@ -33,14 +34,22 @@ def __init__(self): self.devices = {} self.keep_running = True self.connected = False - self.models = ['mk3060', 'esp32'] self.poll_str = '\x1b[t' bytes = os.urandom(4) for byte in bytes: self.poll_str += '{0:02x}'.format(ord(byte)) self.poll_str += 'm' self.poll_interval = 60 - self.uuid = '' + self.uuid = '{0:012x}'.format(uuid.getnode()) + self.model_interface = {} + self.mesh_changed = [re.compile('become leader'), + re.compile('become detached'), + re.compile('allocate sid 0x[0-9a-f]{4}, become [0-9] in net [0-9a-f]{4}')] + self.neighbor_changed = [re.compile('sid [0-9a-f]{4} mac [0-9a-f]{16} is replaced'), + re.compile('[0-9a-f]{1,4} neighbor [0-9a-f]{16} become inactive')] + self.device_uuid_changed = ["ACCS: connected", + "ACCS: disconnected", + 'GATEWAY: connect to server succeed'] def send_device_list(self): device_list = [] @@ -52,18 +61,19 @@ def send_device_list(self): try: self.service_socket.send(data) except: - self.connected = False + #self.connected = False + pass def run_poll_command(self, port, command, lines_expect, timeout): filter = {} response = [] - while self.devices[port]['fqueue'].empty() == False: - self.devices[port]['fqueue'].get() + while self.devices[port]['plog_queue'].empty() == False: + self.devices[port]['plog_queue'].get() self.devices[port]['serial'].write(self.poll_str + command + '\r') start = time.time() while True: try: - log = self.devices[port]['fqueue'].get(False) + log = self.devices[port]['plog_queue'].get(False) except: log = None if time.time() - start >= timeout: @@ -88,32 +98,36 @@ def run_poll_command(self, port, command, lines_expect, timeout): def device_cmd_process(self, port, exit_condition): poll_fail_num = 0 - poll_queue = Queue.Queue(12) + pcmd_queue = self.devices[port]['pcmd_queue'] if self.devices[port]['attributes'] != {}: content = port + ':' + json.dumps(self.devices[port]['attributes'], sort_keys=True) data = TBframe.construct(TBframe.DEVICE_STATUS, content) - self.service_socket.send(data) - poll_timeout = time.time() + 5 + random.uniform(0, self.poll_interval/3) + try: + self.service_socket.send(data) + except: + #self.connected = False + pass + poll_timeout = time.time() + 3 + random.uniform(0, self.poll_interval/10) while os.path.exists(port) and exit_condition.is_set() == False: try: if time.time() >= poll_timeout: poll_timeout += self.poll_interval - poll_queue.put(['devname', 1, 0.2]) - poll_queue.put(['mac', 1, 0.2]) - poll_queue.put(['version', 2, 0.2]) - poll_queue.put(['uuid', 1, 0.2]) - poll_queue.put(['umesh status', 11, 0.2]) - poll_queue.put(['umesh extnetid', 1, 0.2]) - poll_queue.put(['umesh nbrs', 33, 0.3]) + queue_safeput(pcmd_queue, ['devname', 1, 0.2]) + queue_safeput(pcmd_queue, ['mac', 1, 0.2]) + queue_safeput(pcmd_queue, ['version', 2, 0.2]) + queue_safeput(pcmd_queue, ['uuid', 1, 0.2]) + queue_safeput(pcmd_queue, ['umesh status', 11, 0.2]) + queue_safeput(pcmd_queue, ['umesh extnetid', 1, 0.2]) + queue_safeput(pcmd_queue, ['umesh nbrs', 35, 0.3]) block=True timeout=0 try: args = None - if self.devices[port]['queue'].empty() == True and poll_queue.empty() == True: - args = self.devices[port]['queue'].get(block=True, timeout=0.1) - elif self.devices[port]['queue'].empty() == False: - args = self.devices[port]['queue'].get() + if self.devices[port]['ucmd_queue'].empty() == True and pcmd_queue.empty() == True: + args = self.devices[port]['ucmd_queue'].get(block=True, timeout=0.1) + elif self.devices[port]['ucmd_queue'].empty() == False: + args = self.devices[port]['ucmd_queue'].get() except Queue.Empty: args = None continue @@ -136,16 +150,18 @@ def device_cmd_process(self, port, exit_condition): elif type == TBframe.DEVICE_CMD: cmd = args[2] self.device_run_cmd(port, cmd, term) + if re.search('umesh extnetid [0-9A-Fa-f]{12}', cmd) != None: + queue_safeput(pcmd_queue, ['umesh extnetid', 1, 0.2]) else: print "error: unknown operation tyep {0}".format(repr(type)) args = None time.sleep(0.05) continue - if poll_queue.empty() == True: + if pcmd_queue.empty() == True: continue - [cmd, lines, timeout] = poll_queue.get() + [cmd, lines, timeout] = pcmd_queue.get() response = self.run_poll_command(port, cmd, lines, timeout) if cmd == 'devname': #poll device model @@ -243,14 +259,14 @@ def device_cmd_process(self, port, exit_condition): print "device {0} become active".format(port) self.devices[port]['attributes']['status'] = 'active' - if poll_queue.empty() == False: + if pcmd_queue.empty() == False: continue content = port + ':' + json.dumps(self.devices[port]['attributes'], sort_keys=True) data = TBframe.construct(TBframe.DEVICE_STATUS, content) try: self.service_socket.send(data) except: - self.connected = False + #self.connected = False continue except: if os.path.exists(port) == False: @@ -263,6 +279,33 @@ def device_cmd_process(self, port, exit_condition): self.devices[port]['serial'].open() print 'devie command process thread for {0} exited'.format(port) + def device_log_filter(self, port, log): + pcmd_queue = self.devices[port]['pcmd_queue'] + if pcmd_queue.full() == True: + return + for flog in self.mesh_changed: + if flog.search(log) == None: + continue + #print log + #print "device {0} mesh status changed".format(port) + queue_safeput(pcmd_queue, ['umesh status', 11, 0.2]) + queue_safeput(pcmd_queue, ['umesh nbrs', 33, 0.3]) + return + for flog in self.neighbor_changed: + if flog.search(log) == None: + continue + #print log + #print "device {0} neighbors changed".format(port) + queue_safeput(pcmd_queue, ['umesh nbrs', 33, 0.3]) + return + for flog in self.device_uuid_changed: + if flog not in log: + continue + #print log + #print "device {0} uuid changed".format(port) + queue_safeput(pcmd_queue, ['uuid', 1, 0.2]) + return + def device_log_poll(self, port, exit_condition): log_time = time.time() log = '' @@ -294,8 +337,10 @@ def device_log_poll(self, port, exit_condition): break if newline == True and log != '': - if self.poll_str in log and self.devices[port]['fqueue'].full() == False: - self.devices[port]['fqueue'].put(log, False) + if self.poll_str in log: + queue_safeput(self.devices[port]['plog_queue'], log) + else: + self.device_log_filter(port, log) if LOCALLOG: flog.write('{0:.3f}:'.format(log_time) + log) log = port + ':{0:.3f}:'.format(log_time) + log @@ -304,7 +349,7 @@ def device_log_poll(self, port, exit_condition): try: self.service_socket.send(data) except: - self.connected == False + #self.connected = False continue if LOCALLOG: flog.close() @@ -315,124 +360,110 @@ def device_log_poll(self, port, exit_condition): self.send_device_list() print 'device log poll thread for {0} exited'.format(port) + def add_new_device(self, mi, port): + ser = mi.new_device(port) + if ser == None: + return False + self.devices[port] = {'valid':True, \ + 'serial':ser, \ + 'if' : mi, \ + 'slock':threading.Lock(), \ + 'attributes':{}, \ + 'ucmd_queue':Queue.Queue(12), \ + 'pcmd_queue':Queue.Queue(64), \ + 'plog_queue':Queue.Queue(64)} + self.devices[port]['attributes']['status'] = 'inactive' + return True + + def add_old_device(self, mi, port): + ser = mi.new_device(port) + if ser == None: + return False + self.devices[port]['serial'] = ser + if self.devices[port]['slock'].locked(): + self.devices[port]['slock'].release() + while self.devices[port]['ucmd_queue'].empty() == False: + self.devices[port]['ucmd_queue'].get() + while self.devices[port]['pcmd_queue'].empty() == False: + self.devices[port]['pcmd_queue'].get() + while self.devices[port]['plog_queue'].empty() == False: + self.devices[port]['plog_queue'].get() + self.devices[port]['attributes']['status'] = 'inactive' + self.devices[port]['valid'] = True + return True + + def list_devices(self): + os = platform.system() + devices_new = [] + for model in self.model_interface: + mi = self.model_interface[model] + + devices = mi.list_devices(os) + for port in devices: + if port in self.devices and self.devices[port]['valid'] == True: + continue + if port not in self.devices: + ret = self.add_new_device(mi, port) + else: + ret = self.add_old_device(mi, port) + if ret == True: + devices_new.append(port) + + devices_new.sort() + return devices_new + def device_monitor(self): while self.keep_running: - os = platform.system() - if os == 'Windows': - coms = serial.tools.list_ports.comports() - devices_new = [] - for com in coms: - devices_new.append(com.device) - elif os == 'Linux': - devices_new = glob.glob('/dev/mxchip-*') - devices_new += glob.glob('/dev/espif-*') - if devices_new == []: - devices_new += glob.glob('/dev/ttyUSB*') - elif os == 'Darwin': - devices_new = glob.glob('/dev/tty.usbserial*') - elif 'CYGWIN' in os: - devices_new = glob.glob('/dev/ttyS*') - else: - print 'unsupported os "{0}"'.format(os) - break - - devices_new.sort() + devices_new = self.list_devices() for port in devices_new: - if port in self.devices and self.devices[port]['valid']: - continue - if port in self.devices: - try: - self.devices[port]['serial'].close() - self.devices[port]['serial'].open() - except: - print 'device_monitor, error: unable to open {0}'.format(port) - continue - if self.devices[port]['slock'].locked(): - self.devices[port]['slock'].release() - while self.devices[port]['queue'].empty() == False: - self.devices[port]['queue'].get() - while self.devices[port]['fqueue'].empty() == False: - self.devices[port]['fqueue'].get() - self.devices[port]['valid'] = True - else: - if 'mxchip' in port: - baudrate = 921600 - elif 'espif' in port: - baudrate = 115200 - else: - baudrate = 115200 - - try: - ser = serial.Serial(port, baudrate, timeout = 0.02) - except: - print 'device_monitor, error: unable to open {0}'.format(port) - continue - self.devices[port] = {'valid':True, \ - 'serial':ser, \ - 'slock':threading.Lock(), \ - 'queue':Queue.Queue(12), \ - 'attributes':{}, \ - 'fqueue':Queue.Queue(64)} - try: - if 'mxchip' in port: - self.devices[port]['attributes']['model'] = 'MK3060' - ser.setRTS(False) - if 'espif' in port: - self.devices[port]['attributes']['model'] = 'ESP32' - ser.setRTS(True) - ser.setDTR(False) - time.sleep(0.1) - ser.setDTR(True) - except: - self.devices[port]['valid'] = False - continue print 'device {0} added'.format(port) - self.devices[port]['attributes']['status'] = 'inactive' exit_condition = threading.Event() thread.start_new_thread(self.device_log_poll, (port, exit_condition,)) thread.start_new_thread(self.device_cmd_process, (port, exit_condition,)) + if devices_new != []: self.send_device_list() time.sleep(0.1) print 'device monitor thread exited' self.keep_running = False - def esp32_erase(self, port): - retry = 3 - baudrate = 230400 - error = 'fail' - while retry > 0: - script = ['python', 'esptool.py'] - script += ['--chip'] - script += ['esp32'] - script += ['--port'] - script += [port] - script += ['--baud'] - script += [str(baudrate)] - script += ['erase_flash'] - ret = subprocess.call(script) - if ret == 0: - error = 'success' - break - retry -= 1 - baudrate = baudrate / 2 - return error + def get_interface_by_model(self, model): + if model not in self.model_interface: + if os.path.exists('board/'+model) == False or \ + os.path.exists('board/{0}/{0}.py'.format(model)) == False: + return None + if 'board/'+model not in sys.path: + sys.path.append('board/'+model) + try: + self.model_interface[model] = importlib.import_module(model) + except: + if DEBUG: traceback.print_exc() + return None + return self.model_interface[model] + + def load_interfaces(self): + candidates = glob.glob("board/*/*.py") + for d in candidates: + r = re.search("board/(.*)/(.*)\.py", d) + if r == None: + continue + model = r.groups()[0] + if model != r.groups()[1]: + continue + self.get_interface_by_model(model) + print 'model loaded - ',model def device_erase(self, port, term): - model = 'unknown' - if 'model' in self.devices[port]['attributes']: - model = self.devices[port]['attributes']['model'] - model = model.lower() - - if model != 'esp32': + interface = self.devices[port]['if'] + if interface == None: print "error: erasing dose not support model '{0}'".format(model) - content = ','.join(term) + ',' + 'unknow model' + content = ','.join(term) + ',' + 'unsupported model' self.send_packet(TBframe.DEVICE_ERASE, content) return self.devices[port]['slock'].acquire() try: self.devices[port]['serial'].close() - ret = self.esp32_erase(port) + ret = interface.erase(port) except: if DEBUG: traceback.print_exc() ret = 'fail' @@ -445,58 +476,6 @@ def device_erase(self, port, term): content = ','.join(term) + ',' + ret self.send_packet(TBframe.DEVICE_ERASE, content) - def esp32_program(self, port, address, file): - retry = 3 - baudrate = 230400 - error = 'fail' - while retry > 0: - script = ['python'] - script += [os.environ['ESPTOOL_PATH'] + '/esptool.py'] - script += ['--chip'] - script += ['esp32'] - script += ['--port'] - script += [port] - script += ['--baud'] - script += [str(baudrate)] - script += ['--before'] - script += ['default_reset'] - script += ['--after'] - script += ['hard_reset'] - script += ['write_flash'] - script += ['-z'] - script += ['--flash_mode'] - script += ['dio'] - script += ['--flash_freq'] - script += ['40m'] - script += ['--flash_size'] - script += ['4MB'] - script += [address] - script += [file] - ret = subprocess.call(script) - if ret == 0: - error = 'success' - break - retry -= 1 - baudrate = baudrate / 2 - return error - - def mxchip_program(self, port, address, file): - retry = 3 - error = 'fail' - while retry > 0: - script = ['python', 'aos_firmware_update.py'] - script += [port] - script += [address] - script += [file] - script += ['--hardreset'] - ret = subprocess.call(script) - if ret == 0: - error = 'success' - break - retry -= 1 - time.sleep(4) - return error - def device_program(self, port, address, file, term): if os.path.exists(port) == False or port not in self.devices: print "error: progamming nonexist port {0}".format(port) @@ -504,24 +483,17 @@ def device_program(self, port, address, file, term): self.send_packet(TBframe.DEVICE_PROGRAM, content) return - model = 'unknown' - if 'model' in self.devices[port]['attributes']: - model = self.devices[port]['attributes']['model'] - model = model.lower() - if model not in self.models: - print "error: programing dose not support model '{0}'".format(model) - content = ','.join(term) + ',' + 'unknown model' + interface = self.devices[port]['if'] + if interface == None: + print "error: programming dose not support model '{0}'".format(model) + content = ','.join(term) + ',' + 'unsupported model' self.send_packet(TBframe.DEVICE_PROGRAM, content) return self.devices[port]['slock'].acquire() try: self.devices[port]['serial'].close() - if model == 'esp32': - ret = self.esp32_program(port, address, file) - elif model == 'mk3060': - ret = self.mxchip_program(port, address, file) - self.devices[port]['serial'].open() + ret = interface.program(port, address, file) except: if DEBUG: traceback.print_exc() ret = 'fail' @@ -534,40 +506,6 @@ def device_program(self, port, address, file, term): content = ','.join(term) + ',' + ret self.send_packet(TBframe.DEVICE_PROGRAM, content) - def esp32_control(self, port, operation): - try: - if operation == TBframe.DEVICE_RESET: - self.devices[port]['serial'].setDTR(False) - time.sleep(0.1) - self.devices[port]['serial'].setDTR(True) - return 'success' - elif operation == TBframe.DEVICE_STOP: - self.devices[port]['serial'].setDTR(False) - return 'success' - elif operation == TBframe.DEVICE_START: - self.devices[port]['serial'].setDTR(True) - return 'success' - except: - pass - return 'fail' - - def mxchip_control(self, port, operation): - try: - if operation == TBframe.DEVICE_RESET: - self.devices[port]['serial'].setRTS(True) - time.sleep(0.1) - self.devices[port]['serial'].setRTS(False) - return 'success' - elif operation == TBframe.DEVICE_STOP: - self.devices[port]['serial'].setRTS(True) - return 'success' - elif operation == TBframe.DEVICE_START: - self.devices[port]['serial'].setRTS(False) - return 'success' - except: - pass - return 'fail' - def device_control(self, port, type, term): operations= {TBframe.DEVICE_RESET:'reset', TBframe.DEVICE_STOP:'stop', TBframe.DEVICE_START:'start'} if os.path.exists(port) == False or port not in self.devices: @@ -576,21 +514,15 @@ def device_control(self, port, type, term): self.send_packet(type, content) return - model = 'unknown' - if 'model' in self.devices[port]['attributes']: - model = self.devices[port]['attributes']['model'] - model = model.lower() - if model not in self.models: - print "error: controlling unsupported model '{0}'".format(model) - content = ','.join(term) + ',' + 'unknown model' + interface = self.devices[port]['if'] + if interface == None: + print "error: controlling dose not support model '{0}'".format(model) + content = ','.join(term) + ',' + 'unsupported model' self.send_packet(type, content) return try: - if model == 'esp32': - ret = self.esp32_control(port, type) - elif model == 'mk3060': - ret = self.mxchip_control(port, type) + ret = interface.control(port, operations[type]) except: if DEBUG: traceback.print_exc() ret = 'fail' @@ -635,36 +567,31 @@ def send_packet(self, type, content): except: raise ConnectionLost - def client_func(self, server_ip, server_port): - self.service_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + def connect_to_server(self, server_ip, server_port): + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + if ENCRYPT: + sock = ssl.wrap_socket(sock, cert_reqs=ssl.CERT_REQUIRED, ca_certs='server_cert.pem') try: - self.service_socket.connect((server_ip, server_port)) + sock.connect((server_ip, server_port)) + self.service_socket = sock self.connected = True - print 'connect to server {0}:{1} succeeded'.format(server_ip, server_port) + return "success" except: + if DEBUG: traceback.print_exc() + return "fail" + + def client_func(self, server_ip, server_port): + self.load_interfaces() + + result = self.connect_to_server(server_ip, server_port) + if result == 'success': + print 'connect to server {0}:{1} succeeded'.format(server_ip, server_port) + else: print 'connect to server {0}:{1} failed'.format(server_ip, server_port) return if os.path.exists('client') == False: os.mkdir('client') - if os.path.exists('client/.uuid') == True: - try: - file = open('client/.uuid','rb') - self.uuid = json.load(file) - file.close() - except: - print "read uuid from file failed" - if not self.uuid: - bytes = os.urandom(6) - self.uuid = '' - for byte in bytes: - self.uuid += '{0:02x}'.format(ord(byte)) - try: - file = open('client/.uuid','w') - file.write(json.dumps(self.uuid)) - file.close() - except: - print "save uuid to file failed" signal.signal(signal.SIGINT, signal_handler) self.send_packet(TBframe.CLIENT_UUID, self.uuid) @@ -773,8 +700,8 @@ def client_func(self, server_ip, server_port): term = args[0:2] port = args[2] if os.path.exists(port) and port in self.devices: - if self.devices[port]['queue'].full() == False: - self.devices[port]['queue'].put([type, term]) + if self.devices[port]['ucmd_queue'].full() == False: + self.devices[port]['ucmd_queue'].put([type, term]) continue else: result = 'busy' @@ -798,8 +725,8 @@ def client_func(self, server_ip, server_port): continue filename = file_received[hash] if os.path.exists(port) and port in self.devices: - if self.devices[port]['queue'].full() == False: - self.devices[port]['queue'].put([type, term, address, filename]) + if self.devices[port]['ucmd_queue'].full() == False: + self.devices[port]['ucmd_queue'].put([type, term, address, filename]) continue else: result = 'busy' @@ -817,8 +744,8 @@ def client_func(self, server_ip, server_port): term = args[0:2] port = args[2] if os.path.exists(port) and port in self.devices: - if self.devices[port]['queue'].full() == False: - self.devices[port]['queue'].put([type, term]) + if self.devices[port]['ucmd_queue'].full() == False: + self.devices[port]['ucmd_queue'].put([type, term]) continue else: result = 'busy' @@ -838,8 +765,8 @@ def client_func(self, server_ip, server_port): cmd = ' '.join(cmd) if os.path.exists(port) and port in self.devices and \ self.devices[port]['valid'] == True: - if self.devices[port]['queue'].full() == False: - self.devices[port]['queue'].put([type, term, cmd]) + if self.devices[port]['ucmd_queue'].full() == False: + self.devices[port]['ucmd_queue'].put([type, term, cmd]) continue else: result = 'busy' @@ -856,24 +783,16 @@ def client_func(self, server_ip, server_port): self.send_device_list() except ConnectionLost: self.connected = False - print 'connection to server lost, try reconnecting...' self.service_socket.close() - self.service_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + print 'connection to server lost, try reconnecting...' while True: - try: - self.service_socket.connect((server_ip, server_port)) - time.sleep(0.1) - self.connected = True + result = self.connect_to_server(server_ip, server_port) + if result == 'success': self.send_packet(TBframe.CLIENT_UUID, self.uuid) self.send_packet(TBframe.CLIENT_TAG, self.poll_str) self.send_device_list() break - except: - try: - time.sleep(1) - except: - self.service_socket.close() - return + time.sleep(1) print 'connection to server resumed' except KeyboardInterrupt: print "client exiting ..." diff --git a/tools/testbed/controller.py b/tools/testbed/controller.py new file mode 100644 index 0000000000..d1b0077f55 --- /dev/null +++ b/tools/testbed/controller.py @@ -0,0 +1,160 @@ +import sys, time, socket, ssl, signal, select, thread +import TBframe + +CONFIG_TIMEOUT = 30 +CONFIG_MAXMSG_LENTH = 8192 +CONFIG_ENCRYPT = True + +def signal_handler(sig, frame): + print "received SIGINT" + raise KeyboardInterrupt + +class selector(): + EVENT_READ = 0 + EVENT_WRITE = 1 + EVENT_ERROR = 2 + def __init__(self): + self.read_map = {} + self.write_map = {} + self.error_map = {} + + def register(self, fd, type, callback): + types = {self.EVENT_READ:self.read_map, self.EVENT_WRITE:self.write_map, self.EVENT_ERROR: self.error_map} + if type not in types: + return + map = types[type] + map[fd] = callback + + def unregister(self, fd, type): + types = {self.EVENT_READ:self.read_map, self.EVENT_WRITE:self.write_map, self.EVENT_ERROR: self.error_map} + if type not in types: + return + map = types[type] + if fd in map: map.pop(fd) + + def select(self): + ret = [] + r, w, e = select.select(list(self.read_map), list(self.write_map), list(self.error_map)) + for fd in r: + ret.append([fd, self.read_map[fd]]) + for fd in w: + ret.append([fd, self.write_map[fd]]) + for fd in e: + ret.append([fd, self.error_map[fd]]) + return ret + + +class Controller(): + def __init__(self, host, port): + self.host = host + self.port = port + self.clients = {} + self.servers = {} + self.terminals = {} + self.timeouts = {} + self.keyfile = 'server_key.pem' + self.certfile = 'server_cert.pem' + + def accept(self, sel, sock, type): + funcs = {'client':self.client_serve, 'server':self.server_serve, 'terminal':self.terminal_serve} + clist = {'client':self.clients, 'server':self.servers, 'terminal':self.terminals} + conn, addr = sock.accept() + if type not in funcs: + print "error: unsupported type {0}".format(type) + conn.close() + return + print('{0} {1} connected'.format(type, addr)) + conn.setblocking(False) + sel.register(conn, selector.EVENT_READ, funcs[type]) + self.timeouts[sel][conn] = time.time() + CONFIG_TIMEOUT + clist[type][conn] = {} + + def client_serve(self, sel, sock, type): + data = sock.recv(CONFIG_MAXMSG_LENTH) + if not data: + print("client {0} disconnect".format(sock.getpeername())) + sel.unregister(sock, selector.EVENT_READ) + sock.close() + self.timeouts[sel].pop(sock) + self.clients.pop(sock) + return + self.timeouts[sel][sock] = time.time() + CONFIG_TIMEOUT + print type, data + + def server_serve(self, sel, sock, type): + data = sock.recv(CONFIG_MAXMSG_LENTH) + if not data: + print("server {0} disconnect".format(sock.getpeername())) + sel.unregister(sock, selector.EVENT_READ) + sock.close() + self.timeouts[sel].pop(sock) + self.servers.pop(sock) + return + self.timeouts[sel][sock] = time.time() + CONFIG_TIMEOUT + print type, data + + def terminal_serve(self, sel, sock, type): + data = sock.recv(CONFIG_MAXMSG_LENTH) + if not data: + print("terminal {0} disconnect".format(sock.getpeername())) + sel.unregister(sock, selector.EVENT_READ) + sock.close() + self.timeouts[sel].pop(sock) + self.terminals.pop(sock) + return + self.timeouts[sel][sock] = time.time() + CONFIG_TIMEOUT + print type, data + + def service_thread(self, port, type): + types = {'client':self.clients, 'server':self.servers, 'terminal':self.terminals} + if type not in types: + return + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + sock.setblocking(False) + sock.bind((self.host, port)) + if CONFIG_ENCRYPT: + sock = ssl.wrap_socket(sock, self.keyfile, self.certfile, True) + sock.listen(100) + sel = selector() + sel.register(sock, selector.EVENT_READ, self.accept) + self.timeouts[sel] = {} + while self.keep_running: + events = sel.select() + for [sock, callback] in events: + callback(sel, sock, type) + + #close timeout connections + now = time.time() + conlist = types[type] + for conn in list(self.timeouts[sel]): + if now < self.timeouts[sel][conn]: + continue + sel.unregister(conn, selector.EVENT_READ) + conn.close() + self.timeouts[sel].pop(conn) + conlist.pop(conn) + + def run(self): + signal.signal(signal.SIGINT, signal_handler) + self.keep_running = True + thread.start_new_thread(self.service_thread, (self.port, 'client',)) + thread.start_new_thread(self.service_thread, (self.port + 2, 'server',)) + thread.start_new_thread(self.service_thread, (self.port + 1, 'terminal',)) + while True: + try: + time.sleep(1) + except: + self.keep_running = False + break + +if __name__ == '__main__': + host = '' + port = '34567' + if len(sys.argv) > 1: + host = sys.argv[1] + if len(sys.argv) > 2: + port = sys.argv[2] + cntr = Controller(host, 34567) + cntr.run() + sys.exit(0) diff --git a/tools/testbed/esptool.py b/tools/testbed/esptool.py deleted file mode 120000 index a0b5896e7f..0000000000 --- a/tools/testbed/esptool.py +++ /dev/null @@ -1 +0,0 @@ -../../platform/mcu/esp32/esptool_py/esptool/esptool.py \ No newline at end of file diff --git a/tools/testbed/server.py b/tools/testbed/server.py index a2043a8ae2..22b9ab4720 100644 --- a/tools/testbed/server.py +++ b/tools/testbed/server.py @@ -1,8 +1,10 @@ -import os, sys, time, socket, signal -import thread, threading, json, traceback +import os, sys, time, socket, ssl, signal, re +import thread, threading, json, traceback, shutil import TBframe -MAX_MSG_LENTH = 2000 +MAX_MSG_LENTH = 8192 +ENCRYPT_CLIENT = False +ENCRYPT_TERMINAL = False DEBUG = True def signal_handler(sig, frame): @@ -11,24 +13,27 @@ def signal_handler(sig, frame): class Server: def __init__(self): + self.keyfile = 'server_key.pem' + self.certfile = 'server_cert.pem' self.client_socket = 0 self.terminal_socket = 0 self.client_list = [] self.terminal_list = [] - self.allocated = {'lock':threading.Lock(), 'devices':[], 'timeout':0} + self.conn_timeout = {} self.keep_running = True + self.log_preserve_period = (7 * 24 * 3600) * 3 #save log for 3 weeks + self.allocated = {'lock':threading.Lock(), 'devices':[], 'timeout':0} self.special_purpose_set = {'mk3060-alink':[], 'esp32-alink':[]} #mk3060 self.special_purpose_set['mk3060-alink'] += ['DN02QRKQ', 'DN02RDVL', 'DN02RDVT', 'DN02RDVV'] self.special_purpose_set['mk3060-alink'] += ['DN02X2ZO', 'DN02X2ZS', 'DN02X2ZX', 'DN02X2ZZ'] self.special_purpose_set['mk3060-alink'] += ['DN02X303', 'DN02X304', 'DN02X30B', 'DN02X30H'] + self.special_purpose_set['mk3060-mesh'] = self.special_purpose_set['mk3060-alink'] #esp32 - self.special_purpose_set['esp32-alink'] += ['espif-1.1', 'espif-1.3', 'espif-1.4'] - self.special_purpose_set['esp32-alink'] += ['espif-2.1', 'espif-2.3', 'espif-2.4'] - self.special_purpose_set['esp32-alink'] += ['espif-9.1', 'espif-9.3', 'espif-9.4'] - self.special_purpose_set['esp32-alink'] += ['espif-1.2.2', 'espif-1.2.3'] - self.special_purpose_set['esp32-alink'] += ['espif-2.2.1','espif-2.2.2', 'espif-2.2.3'] - self.special_purpose_set['esp32-alink'] += ['espif-9.2.1','espif-9.2.2', 'espif-9.2.3'] + self.special_purpose_set['esp32-alink'] += ['espif-3.1.1', 'espif-3.1.2', 'espif-3.1.3', 'espif-3.1.4'] + self.special_purpose_set['esp32-alink'] += ['espif-3.2.1', 'espif-3.2.2', 'espif-3.2.3', 'espif-3.2.4'] + self.special_purpose_set['esp32-alink'] += ['espif-3.3.1', 'espif-3.3.2', 'espif-3.3.3', 'espif-3.3.4'] + self.special_purpose_set['esp32-mesh'] = self.special_purpose_set['esp32-alink'] def construct_dev_list(self): l = [] @@ -59,20 +64,12 @@ def send_device_list_to_all(self): continue def client_serve_thread(self, conn, addr): - conn.settimeout(1) - heartbeat_timeout = time.time() + 30 file = {} msg = '' client = None + self.conn_timeout[conn] = {'type':'client', 'addr': addr, 'timeout': time.time() + 30} while self.keep_running: try: - if time.time() > heartbeat_timeout: - if client != None: - print "client {0} @ {1} heartbeat timeout".format(client['uuid'], addr) - else: - print "client @ {0} heartbeat timeout".format(addr) - break - new_msg = conn.recv(MAX_MSG_LENTH) if new_msg == '': break @@ -83,7 +80,7 @@ def client_serve_thread(self, conn, addr): if type == TBframe.TYPE_NONE: break - heartbeat_timeout = time.time() + 30 + self.conn_timeout[conn]['timeout'] = time.time() + 30 if client == None: if type != TBframe.CLIENT_UUID: data = TBframe.construct(TBframe.CLIENT_UUID, 'give me your uuid first') @@ -141,48 +138,57 @@ def client_serve_thread(self, conn, addr): client['devices'][port]['valid'] = False print "device {0} removed from client {1}".format(port, client['uuid']) - for port in list(client['devices']): - if port in file: - continue - try: - filename = 'server/' + client['uuid'] + '-' + port.split('/')[-1] + '.log' - file[port] = open(filename, 'a') - except: - print "error: can not open/create file ", filename - continue for port in list(file): if client['devices'][port]['valid'] == True: continue - file[port].close() + file[port]['handle'].close() file.pop(port) self.send_device_list_to_all() elif type == TBframe.DEVICE_LOG: port = value.split(':')[0] - if port not in file: + if port not in client['devices']: continue + #forwad log to subscribed devices + if client['devices'][port]['log_subscribe'] != [] and \ + ('tag' not in client or client['tag'] not in value): + log = client['uuid'] + ',' + value + data = TBframe.construct(type, log) + for s in client['devices'][port]['log_subscribe']: + try: + s.send(data) + except: + continue + #save log to files try: logtime = value.split(':')[1] logstr = value[len(port) + 1 + len(logtime):] logtime = float(logtime) - logtimestr=time.strftime("%Y-%m-%d@%H:%M:%S", time.localtime(logtime)) + logtimestr = time.strftime("%Y-%m-%d@%H:%M:%S", time.localtime(logtime)) logtimestr += ("{0:.3f}".format(logtime-int(logtime)))[1:] logstr = logtimestr + logstr - file[port].write(logstr) + logdatestr = time.strftime("%Y-%m-%d", time.localtime(logtime)) except: if DEBUG: traceback.print_exc() continue - if 'tag' in client and client['tag'] in logstr: - continue - if client['devices'][port]['log_subscribe'] != []: - log = client['uuid'] + ',' + port - log += value[len(port):] - data = TBframe.construct(type, log) - for s in client['devices'][port]['log_subscribe']: + if (port not in file) or (file[port]['date'] != logdatestr): + if port in file: + file[port]['handle'].close() + file.pop(port) + log_dir = 'server/' + logdatestr + if os.path.isdir(log_dir) == False: try: - s.send(data) + os.mkdir(log_dir) except: - continue + print "error: can not create directory {0}".format(log_dir) + filename = log_dir + '/' + client['uuid'] + '-' + port.split('/')[-1] + '.log' + try: + handle = open(filename, 'a+') + file[port] = {'handle':handle, 'date': logdatestr} + except: + print "error: can not open/create file ", filename + if port in file and file[port]['date'] == logdatestr: + file[port]['handle'].write(logstr) elif type == TBframe.DEVICE_STATUS: #print value port = value.split(':')[0] @@ -218,12 +224,11 @@ def client_serve_thread(self, conn, addr): elif type == TBframe.CLIENT_TAG: client['tag'] = value print 'client {0} tag: {1}'.format(client['uuid'],repr(value)) - except socket.timeout: - continue except: if DEBUG: traceback.print_exc() break conn.close() + self.conn_timeout.pop(conn) if client: for port in client['devices']: if client['devices'][port]['valid'] == False: @@ -373,18 +378,15 @@ def increase_device_refer(self, client, port, using_list): using_list.append([client['uuid'], port]) self.send_device_list_to_all() - def terminal_serve_thread(self, terminal): - self.send_device_list_to_terminal(terminal) + def terminal_serve_thread(self, conn, addr): + terminal = {'socket':conn, 'addr':addr} + self.terminal_list.append(terminal) using_list = [] - terminal['socket'].settimeout(1) - heartbeat_timeout = time.time() + 30 msg = '' + self.conn_timeout[conn] = {'type': 'terminal', 'addr': addr, 'timeout': time.time() + 30} + self.send_device_list_to_terminal(terminal) while self.keep_running: try: - if time.time() > heartbeat_timeout: - print "terminal {0} heartbeat timeout".format(terminal['addr']) - break - new_msg = terminal['socket'].recv(MAX_MSG_LENTH); if new_msg == '': break @@ -395,7 +397,7 @@ def terminal_serve_thread(self, terminal): if type == TBframe.TYPE_NONE: break - heartbeat_timeout = time.time() + 30 + self.conn_timeout[conn]['timeout'] = time.time() + 30 if type == TBframe.FILE_BEGIN or type == TBframe.FILE_DATA or type == TBframe.FILE_END: dev_str = value.split(':')[0] uuid = dev_str.split(',')[0] @@ -478,7 +480,8 @@ def terminal_serve_thread(self, terminal): if len(dev_str_split) != 2: continue [uuid, port] = dev_str_split - filename = 'server/' + uuid + '-' + port.split('/')[-1] + '.log' + datestr = time.strftime('%Y-%m-%d') + filename = 'server/' + datestr + '/' + uuid + '-' + port.split('/')[-1] + '.log' client = self.get_client_by_uuid(uuid) if client == None or port not in list(client['devices']) or os.path.exists(filename) == False: data = TBframe.construct(TBframe.CMD_ERROR,'fail') @@ -492,8 +495,6 @@ def terminal_serve_thread(self, terminal): terminal['socket'].send(data) print "terminal {0}:{1}".format(terminal['addr'][0], terminal['addr'][1]), print "downloading log of device {0}:{1} ... succeed".format(uuid, port) - except socket.timeout: - continue except: if DEBUG: traceback.print_exc() break @@ -517,27 +518,37 @@ def terminal_serve_thread(self, terminal): if client['devices'][port]['using'] > 0: client['devices'][port]['using'] -= 1 terminal['socket'].close() + self.conn_timeout.pop(conn) print "terminal ", terminal['addr'], "disconnected" self.terminal_list.remove(terminal) self.send_device_list_to_all() def client_listen_thread(self): self.client_socket.listen(5) + if ENCRYPT_CLIENT: + self.client_socket = ssl.wrap_socket(self.client_socket, self.keyfile, self.certfile, True) while self.keep_running: - conn, addr = self.client_socket.accept() - thread.start_new_thread(self.client_serve_thread, (conn, addr,)) + try: + (conn, addr) = self.client_socket.accept() + thread.start_new_thread(self.client_serve_thread, (conn, addr,)) + except: + traceback.print_exc() def terminal_listen_thread(self): self.terminal_socket.listen(5) + if ENCRYPT_TERMINAL: + self.terminal_socket = ssl.wrap_socket(self.terminal_socket, self.keyfile, self.certfile, True) while self.keep_running: - conn, addr = self.terminal_socket.accept() - terminal = {'socket':conn, 'addr':addr} - self.terminal_list.append(terminal) - thread.start_new_thread(self.terminal_serve_thread, (terminal,)) - print "terminal ", addr," connected" + try: + (conn, addr) = self.terminal_socket.accept() + thread.start_new_thread(self.terminal_serve_thread, (conn, addr,)) + print "terminal ", addr," connected" + except: + traceback.print_exc() def statistics_thread(self): minute = time.strftime("%Y-%m-%d@%H:%M") + datestr = time.strftime("%Y-%m-%d") statistics={ \ 'terminal_num_max':0, \ 'client_num_max':0, \ @@ -556,7 +567,35 @@ def statistics_thread(self): print "error: unable to create/open {0}".format(logname) return while self.keep_running: - time.sleep(2) + time.sleep(3) + + #remove outdated log files + if time.strftime("%Y-%m-%d") != datestr: + tbefore = time.mktime(time.strptime(time.strftime('%Y-%m-%d'), '%Y-%m-%d')) + tbefore -= self.log_preserve_period + flist = os.listdir('server') + for fname in flist: + if os.path.isdir('server/'+ fname) == False: + continue + if re.match('[0-9]{4}-[0-9]{2}-[0-9]{2}', fname) == None: + continue + ftime = time.strptime(fname, '%Y-%m-%d') + ftime = time.mktime(ftime) + if ftime >= tbefore: + continue + shutil.rmtree('server/' + fname) + datestr = time.strftime("%Y-%m-%d") + + #disconnect timeout connections + now = time.time() + for conn in list(self.conn_timeout): + if now <= self.conn_timeout[conn]['timeout']: + continue + conn.close() + print self.conn_timeout[conn]['type'], self.conn_timeout[conn]['addr'], 'timeout' + self.conn_timeout.pop(conn) + + #generate and save statistics data client_cnt = 0 device_cnt = 0 device_use = 0 @@ -584,6 +623,7 @@ def statistics_thread(self): statistics['device_num_avg'] += device_cnt statistics['device_use_avg'] += device_use statistics_cnt += 1.0 + now = time.strftime("%Y-%m-%d@%H:%M") if now == minute: continue diff --git a/tools/testbed/terminal.py b/tools/testbed/terminal.py index e450c2faff..0ee3e078ff 100644 --- a/tools/testbed/terminal.py +++ b/tools/testbed/terminal.py @@ -1,11 +1,11 @@ #!/usr/bin/python -import os, sys, time, curses, socket, random +import os, sys, time, curses, socket, ssl, random import subprocess, thread, threading, pickle from operator import itemgetter import TBframe -MAX_MSG_LENTH = 2000 +MAX_MSG_LENTH = 8192 CMD_WINDOW_HEIGHT = 2 DEV_WINDOW_WIDTH = 36 LOG_WINDOW_HEIGHT = 30 @@ -13,6 +13,7 @@ LOG_HISTORY_LENGTH = 5000 MOUSE_SCROLL_UP = 0x80000 MOUSE_SCROLL_DOWN = 0x8000000 +ENCRYPT = False DEBUG = True class ConnectionLost(Exception): @@ -27,7 +28,7 @@ def __init__(self): self.keep_running = True self.connected = False self.device_list= {} - self.service_socket = 0 + self.service_socket = None self.cmd_excute_state = 'idle' self.cmd_excute_return = '' self.cmd_excute_event = threading.Event() @@ -394,14 +395,12 @@ def server_interaction(self): self.connected = False self.cmdrun_status_display('connection to server lost, try reconnecting...') self.service_socket.close() - self.service_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.service_socket = None while True: - try: - self.service_socket.connect((self.server_ip, self.server_port)) - self.connected = True + result = self.connect_to_server(self.server_ip, self.server_port) + if result == 'success': break - except: - time.sleep(1) + time.sleep(1) self.cmdrun_status_display('connection to server resumed') random.seed() time.sleep(1.2 + random.random()) @@ -973,15 +972,24 @@ def user_interaction(self): continue self.cmdrun_command_display(cmd, p) + def connect_to_server(self, server_ip, server_port): + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + if ENCRYPT: + sock = ssl.wrap_socket(sock, cert_reqs=ssl.CERT_REQUIRED, ca_certs='server_cert.pem') + try: + sock.connect((server_ip, server_port)) + self.service_socket = sock + self.connected = True + return "success" + except: + return "fail" + def run(self, server_ip, server_port): #connect to server self.server_ip = server_ip self.server_port = server_port - self.service_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - try: - self.service_socket.connect((server_ip, server_port)) - self.connected = True - except: + result = self.connect_to_server(server_ip, server_port) + if result != 'success': print "connect to server {0}:{1} failed".format(server_ip, server_port) return thread.start_new_thread(self.server_interaction, ()) @@ -1001,7 +1009,8 @@ def deinit(self): self.cmd_window.keypad(0) curses.echo() curses.endwin() - self.service_socket.close() + if self.service_socket: + self.service_socket.close() try: if len(self.cmd_history) > 0: file = open("terminal/.cmd_history",'wb') diff --git a/tools/testbed/utilities/install.sh b/tools/testbed/utilities/install.sh index be824e0f4c..0e4284e6e1 100755 --- a/tools/testbed/utilities/install.sh +++ b/tools/testbed/utilities/install.sh @@ -48,6 +48,7 @@ if [ $? -ne 0 ];then fi cd aos/tools/testbed cp *.py ~/testbed/ +cp -rf board ~/testbed/ cd utilities support_log_to_file=`screen -V | grep "\-L \[file\]"` diff --git a/utility/cjson/cJSON.c b/utility/cjson/cJSON.c index 02260b1081..a31512a244 100644 --- a/utility/cjson/cJSON.c +++ b/utility/cjson/cJSON.c @@ -66,7 +66,7 @@ static const unsigned char firstByteMark[7] = static void *(*cJSON_malloc)(size_t sz) = aos_malloc; static void (*cJSON_free)(void *ptr) = aos_free; -#if defined (__CC_ARM) && defined(__MICROLIB) +#if defined (__CC_ARM) extern char * strdup(const char *s); #endif @@ -91,7 +91,7 @@ static char *cJSON_strdup(const char *str) char *copy; len = strlen(str) + 1; - if (!(copy = (char *)cJSON_malloc(len))) + if ((copy = (char *)cJSON_malloc(len))==0) { return 0; } @@ -523,7 +523,7 @@ static char *print_string_ptr(const char *str) } ptr = str; - while ((token = *ptr) && ++len) + while (((token = *ptr)!=0 && ++len!=0)) { if (strchr("\"\\\b\f\n\r\t", token)) { @@ -761,7 +761,7 @@ static const char *parse_array(cJSON *item, const char *value) while (*value == ',') { cJSON *new_item; - if (!(new_item = cJSON_New_Item())) + if ((new_item = cJSON_New_Item())==0) { /* header = "Accept: text/xml,text/javascript,text/html,application/json\r\n"; requ_payload = (char *)LITE_malloc(HTTP_POST_MAX_LEN); if (NULL == requ_payload) { @@ -269,7 +269,7 @@ static int _http_response(char *payload, httpc_data.response_buf = resp_payload; httpc_data.response_buf_len = HTTP_RESP_MAX_LEN; - ret = httpclient_common(&httpc, + ret = httpclient_common(phttpc, url, port_num, pkey, @@ -302,6 +302,7 @@ static int _iotId_iotToken_http( char *iot_id, char *iot_token, char *host, + httpclient_t *phttpc, uint16_t *pport) { char iotx_payload[512] = {0}; @@ -361,6 +362,7 @@ static int _iotId_iotToken_http( request_string, guider_addr, iotx_port, + phttpc, #if defined(MQTT_ID2_AUTH) && defined(TEST_ID2_DAILY) NULL #elif defined(TEST_OTA_PRE) @@ -728,6 +730,7 @@ int iotx_guider_authenticate(void) iotx_device_info_pt dev = iotx_device_info_get(); iotx_conn_info_pt usr = iotx_conn_info_get(); char *req_str = NULL; + httpclient_t httpc; assert(dev); assert(usr); @@ -795,12 +798,14 @@ int iotx_guider_authenticate(void) iotx_id, iotx_token, iotx_conn_host, + &httpc, &iotx_conn_port)) { if (req_str) { free(req_str); } log_err("_iotId_iotToken_http() failed"); + httpclient_close(&httpc); #ifdef MQTT_ID2_AUTH LITE_free(guider_id2); LITE_free(guider_device_code); diff --git a/utility/iotx-utils/guider/guider.mk b/utility/iotx-utils/guider/guider.mk index 1753f8a303..6d8b813b57 100644 --- a/utility/iotx-utils/guider/guider.mk +++ b/utility/iotx-utils/guider/guider.mk @@ -2,7 +2,7 @@ NAME := libguider GLOBAL_INCLUDES += \ ./ \ - ../device \ + ../iotx-system \ ../LITE-utils \ ../LITE-log \ ../misc \ @@ -14,4 +14,4 @@ GLOBAL_INCLUDES += \ $(NAME)_SOURCES := \ guider.c -$(NAME)_COMPONENTS += iotx-utils.device +$(NAME)_COMPONENTS += iotx-utils.iotx-system diff --git a/utility/iotx-utils/device/ca.c b/utility/iotx-utils/iotx-system/ca.c similarity index 100% rename from utility/iotx-utils/device/ca.c rename to utility/iotx-utils/iotx-system/ca.c diff --git a/utility/iotx-utils/device/ca.h b/utility/iotx-utils/iotx-system/ca.h similarity index 100% rename from utility/iotx-utils/device/ca.h rename to utility/iotx-utils/iotx-system/ca.h diff --git a/utility/iotx-utils/device/device.c b/utility/iotx-utils/iotx-system/device.c similarity index 100% rename from utility/iotx-utils/device/device.c rename to utility/iotx-utils/iotx-system/device.c diff --git a/utility/iotx-utils/device/device.h b/utility/iotx-utils/iotx-system/device.h similarity index 100% rename from utility/iotx-utils/device/device.h rename to utility/iotx-utils/iotx-system/device.h diff --git a/utility/iotx-utils/device/device_iar.c b/utility/iotx-utils/iotx-system/device_iar.c similarity index 100% rename from utility/iotx-utils/device/device_iar.c rename to utility/iotx-utils/iotx-system/device_iar.c diff --git a/utility/iotx-utils/device/device.mk b/utility/iotx-utils/iotx-system/iotx-system.mk similarity index 87% rename from utility/iotx-utils/device/device.mk rename to utility/iotx-utils/iotx-system/iotx-system.mk index dcd4d9a2e1..11fd798fde 100644 --- a/utility/iotx-utils/device/device.mk +++ b/utility/iotx-utils/iotx-system/iotx-system.mk @@ -1,4 +1,4 @@ -NAME := libdevice +NAME := libiotx-system GLOBAL_INCLUDES += \ ./ \ diff --git a/utility/iotx-utils/mbedtls-hal/HAL_TLS_mbedtls.c b/utility/iotx-utils/mbedtls-hal/HAL_TLS_mbedtls.c index bfa740c56e..476f0e0f73 100644 --- a/utility/iotx-utils/mbedtls-hal/HAL_TLS_mbedtls.c +++ b/utility/iotx-utils/mbedtls-hal/HAL_TLS_mbedtls.c @@ -449,14 +449,12 @@ int32_t HAL_SSL_Destroy(uintptr_t handle) return 0; } -#ifndef STM32L475xx int ssl_fd = -1; int get_ssl_fd() { return ssl_fd; } -#endif uintptr_t HAL_SSL_Establish(const char *host, uint16_t port, @@ -486,9 +484,7 @@ uintptr_t HAL_SSL_Establish(const char *host, free(pTlsData); return 0; } -#ifndef STM32L475xx ssl_fd = pTlsData->fd.fd; //SSL_LOG(" ssl_fd %d \n ", ssl_fd); -#endif return (uintptr_t)pTlsData; } diff --git a/utility/iotx-utils/sdk-impl/sdk-impl.mk b/utility/iotx-utils/sdk-impl/sdk-impl.mk index 379261d3a7..80acb1b200 100644 --- a/utility/iotx-utils/sdk-impl/sdk-impl.mk +++ b/utility/iotx-utils/sdk-impl/sdk-impl.mk @@ -18,6 +18,6 @@ $(NAME)_INCLUDES := \ ../LITE-utils \ ../LITE-log \ ../guider \ - ../device + ../iotx-system $(NAME)_COMPONENTS += iotx-utils.guider diff --git a/utility/libc/compilers/EWARM/iar_libc.c b/utility/libc/compilers/EWARM/iar_libc.c index 86d1cb8b0b..5aaaff355d 100644 --- a/utility/libc/compilers/EWARM/iar_libc.c +++ b/utility/libc/compilers/EWARM/iar_libc.c @@ -76,6 +76,47 @@ int *__errno _PARAMS ((void)) void __assert_func(const char * a, int b, const char * c, const char *d) { while (1); +} + +/*TO DO*/ +void __write() +{ + +} + +void bzero() +{ + +} + +void __lseek() +{ + +} + +void __close() +{ + +} + +int remove(char const *p) +{ + return 0; +} + +void gettimeofday() +{ + +} + +void getopt() +{ + +} + +void optarg() +{ + } #endif diff --git a/utility/libc/compilers/EWARM/sys/time.h b/utility/libc/compilers/EWARM/sys/time.h index 244d130e02..066579f0ef 100644 --- a/utility/libc/compilers/EWARM/sys/time.h +++ b/utility/libc/compilers/EWARM/sys/time.h @@ -24,15 +24,15 @@ struct timeval { }; #endif /* _TIMEVAL_DEFINED */ -#ifndef _TIMESPEC_DEFINED -#define _TIMESPEC_DEFINED -/* - * Structure defined by POSIX.1b to be like a timeval. - */ -struct timespec { - time_t tv_sec; /* seconds */ - long tv_nsec; /* and nanoseconds */ -}; +#ifndef _TIMESPEC_DEFINED +#define _TIMESPEC_DEFINED +/* +* Structure defined by POSIX.1b to be like a timeval. +*/ +struct timespec { + time_t tv_sec; /* seconds */ + long tv_nsec; /* and nanoseconds */ +}; #endif /* _TIMESPEC_DEFINED */ struct timezone { diff --git a/utility/libc/compilers/armlibc/armcc_libc.c b/utility/libc/compilers/armlibc/armcc_libc.c index e83406d527..93efed6a93 100644 --- a/utility/libc/compilers/armlibc/armcc_libc.c +++ b/utility/libc/compilers/armlibc/armcc_libc.c @@ -6,7 +6,7 @@ #include #include -#if defined (__CC_ARM) && defined(__MICROLIB) +#if defined (__CC_ARM) void __aeabi_assert(const char *expr, const char *file, int line) { while (1); diff --git a/utility/libc/libc.mk b/utility/libc/libc.mk index 9c29bd611a..7e6e843231 100644 --- a/utility/libc/libc.mk +++ b/utility/libc/libc.mk @@ -1,16 +1,15 @@ NAME := newlib_stub ifeq ($(COMPILER),armcc) +$(NAME)_TYPE := share +$(NAME)_SOURCES := compilers/armlibc/armcc_libc.c GLOBAL_INCLUDES += compilers/armlibc -else -ifeq ($(COMPILER),EWARM) +else ifeq ($(COMPILER),iar) +$(NAME)_TYPE := share GLOBAL_INCLUDES += compilers/EWARM -else -#default gcc -ifneq ($(HOST_MCU_FAMILY),linux) +$(NAME)_SOURCES := compilers/EWARM/iar_libc.c +else ifneq ($(HOST_MCU_FAMILY),linux) $(NAME)_TYPE := share $(NAME)_SOURCES := newlib_stub.c endif -endif -endif